commit 3ec2b41a6f86116906772e79815ac4c56b126bd2 Author: mchughalex <25671999+mchughalex@users.noreply.github.com> Date: Mon May 18 22:41:13 2026 +0100 prepare rexglue fork for Skate 3 diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..b7a3056 --- /dev/null +++ b/.clang-format @@ -0,0 +1,109 @@ +--- +Language: Cpp +BasedOnStyle: Google + +# Layout +ColumnLimit: 100 +IndentWidth: 2 +TabWidth: 2 +UseTab: Never +ContinuationIndentWidth: 4 +ConstructorInitializerIndentWidth: 4 + +# Braces +BreakBeforeBraces: Attach + +# Alignment +PointerAlignment: Left +ReferenceAlignment: Left +AccessModifierOffset: -1 +IndentAccessModifiers: false + +# Namespaces +NamespaceIndentation: None +CompactNamespaces: false +FixNamespaceComments: true + +# Includes +SortIncludes: Never +IncludeBlocks: Regroup +IncludeCategories: + # 1. Main header (e.g. foo.cpp -> foo.h) + - Regex: '^"' + Priority: 0 + SortPriority: 0 + # 2. C system headers + - Regex: '^<(assert|complex|ctype|errno|fenv|float|inttypes|iso646|limits|locale|math|setjmp|signal|stdalign|stdarg|stdatomic|stdbool|stddef|stdint|stdio|stdlib|stdnoreturn|string|tgmath|threads|time|uchar|wchar|wctype)\.h>' + Priority: 1 + SortPriority: 1 + # 3. C++ standard library + - Regex: '^<(algorithm|any|array|atomic|barrier|bit|bitset|cassert|cctype|cerrno|cfenv|cfloat|charconv|chrono|cinttypes|climits|clocale|cmath|compare|complex|concepts|condition_variable|coroutine|csetjmp|csignal|cstdarg|cstddef|cstdint|cstdio|cstdlib|cstring|ctgmath|ctime|cuchar|cwchar|cwctype|deque|exception|execution|expected|filesystem|format|forward_list|fstream|functional|future|initializer_list|iomanip|ios|iosfwd|iostream|istream|iterator|latch|limits|list|locale|map|mdspan|memory|memory_resource|mutex|new|numbers|numeric|optional|ostream|print|queue|random|ranges|ratio|regex|scoped_allocator|semaphore|set|shared_mutex|source_location|span|spanstream|sstream|stack|stacktrace|stdexcept|stop_token|streambuf|string|string_view|strstream|syncstream|system_error|thread|tuple|type_traits|typeindex|typeinfo|unordered_map|unordered_set|utility|valarray|variant|vector|version)>' + Priority: 2 + SortPriority: 2 + # 4. POSIX / platform headers + - Regex: '^<(sys/|unistd|fcntl|poll|pthread|dlfcn|netdb|netinet|arpa|windows|winnt|winbase|winsock|d3d|dxgi|vulkan|vk_)' + Priority: 3 + SortPriority: 3 + # 5. Third-party headers + - Regex: '^<(fmt|spdlog|SDL|imgui|toml|catch2|CLI|volk|glslang|spirv|renderdoc|simde|snappy|date|utfcpp|aes|mspack|xxhash|disruptorplus)/' + Priority: 4 + SortPriority: 4 + # 6. Project headers + - Regex: '^ + -*, + bugprone-*, + -bugprone-easily-swappable-parameters, + -bugprone-narrowing-conversions, + -bugprone-reserved-identifier, + -bugprone-exception-escape, + performance-*, + -performance-avoid-endl, + readability-identifier-naming, + readability-redundant-*, + readability-misleading-indentation, + readability-container-size-empty, + readability-make-member-function-const, + misc-unused-using-decls, + misc-redundant-expression, + +WarningsAsErrors: '' + +HeaderFilterRegex: 'include/rex/.*' + +CheckOptions: + # Classes and structs + - key: readability-identifier-naming.ClassCase + value: CamelCase + - key: readability-identifier-naming.StructCase + value: CamelCase + + # Functions and methods + - key: readability-identifier-naming.FunctionCase + value: CamelCase + - key: readability-identifier-naming.MethodCase + value: CamelCase + + # Variables + - key: readability-identifier-naming.VariableCase + value: lower_case + - key: readability-identifier-naming.ParameterCase + value: lower_case + - key: readability-identifier-naming.LocalVariableCase + value: lower_case + + # Member variables + - key: readability-identifier-naming.MemberCase + value: lower_case + - key: readability-identifier-naming.MemberSuffix + value: '_' + - key: readability-identifier-naming.PrivateMemberCase + value: lower_case + - key: readability-identifier-naming.PrivateMemberSuffix + value: '_' + - key: readability-identifier-naming.ProtectedMemberCase + value: lower_case + - key: readability-identifier-naming.ProtectedMemberSuffix + value: '_' + + # Constants + - key: readability-identifier-naming.ConstexprVariableCase + value: CamelCase + - key: readability-identifier-naming.ConstexprVariablePrefix + value: 'k' + - key: readability-identifier-naming.StaticConstantCase + value: CamelCase + - key: readability-identifier-naming.StaticConstantPrefix + value: 'k' + - key: readability-identifier-naming.GlobalConstantCase + value: CamelCase + - key: readability-identifier-naming.GlobalConstantPrefix + value: 'k' + + # Enum constants + - key: readability-identifier-naming.EnumConstantCase + value: CamelCase + - key: readability-identifier-naming.EnumConstantPrefix + value: 'k' + + # Enums + - key: readability-identifier-naming.EnumCase + value: CamelCase + + # Namespaces + - key: readability-identifier-naming.NamespaceCase + value: lower_case + + # Template parameters + - key: readability-identifier-naming.TemplateParameterCase + value: CamelCase + - key: readability-identifier-naming.TypeTemplateParameterCase + value: CamelCase + + # Type aliases + - key: readability-identifier-naming.TypeAliasCase + value: CamelCase + - key: readability-identifier-naming.TypedefCase + value: CamelCase + + # Macros + - key: readability-identifier-naming.MacroDefinitionCase + value: UPPER_CASE +... diff --git a/.cmake-format.yaml b/.cmake-format.yaml new file mode 100644 index 0000000..3c90387 --- /dev/null +++ b/.cmake-format.yaml @@ -0,0 +1,19 @@ +format: + line_width: 100 + tab_size: 2 + use_tabchars: false + fractional_tab_policy: use-space + max_subgroups_hwrap: 2 + max_pargs_hwrap: 6 + max_rows_cmdline: 2 + separate_ctrl_name_with_space: true + separate_fn_name_with_space: false + dangle_parens: true + dangle_align: prefix + min_prefix_chars: 4 + max_prefix_chars: 10 + command_case: lower + keyword_case: upper + +markup: + enable_markup: false diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..afcffbe --- /dev/null +++ b/.editorconfig @@ -0,0 +1,36 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{cpp,h,hpp,c}] +indent_style = space +indent_size = 2 + +[CMakeLists.txt] +indent_style = space +indent_size = 2 + +[*.cmake] +indent_style = space +indent_size = 2 + +[*.{yaml,yml}] +indent_style = space +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false + +[*.{sh,bash}] +indent_style = space +indent_size = 2 +end_of_line = lf + +[*.ps1] +indent_style = space +indent_size = 4 +end_of_line = lf diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..06ab33d --- /dev/null +++ b/.gitattributes @@ -0,0 +1,17 @@ +# Enforce LF line endings for all text files +* text=auto eol=lf + +# Explicitly mark binary files +*.png binary +*.jpg binary +*.ico binary +*.zip binary +*.exe binary +*.dll binary +*.so binary +*.dylib binary +*.a binary +*.lib binary +*.obj binary +*.o binary +*.pdb binary diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..c8bb481 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,2 @@ +# Global owners +* @tomcl7 diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml new file mode 100644 index 0000000..15745ca --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -0,0 +1,97 @@ +name: Bug Report +description: Report a bug or unexpected behavior +title: "[Bug]: " +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + Thanks for reporting a bug! Please fill out as much detail as possible. + + - type: textarea + id: description + attributes: + label: Description + description: Clear description of the bug + placeholder: When I do X, Y happens instead of Z. + validations: + required: true + + - type: textarea + id: steps-to-reproduce + attributes: + label: Steps to Reproduce + description: Minimal steps to reproduce the behavior + placeholder: | + 1. Build with '...' + 2. Run '...' + 3. Observe error in log, set breakpoint here and inspect, etc. + validations: + required: true + + - type: textarea + id: expected-behavior + attributes: + label: Expected Behavior + description: What should happen instead? + validations: + required: true + + - type: textarea + id: actual-behavior + attributes: + label: Actual Behavior + description: What actually happens? Include error messages, stack traces, or logs if available. + placeholder: | + The program crashes with: + ``` + error message here + ``` + validations: + required: true + + - type: dropdown + id: platform + attributes: + label: Platform + description: What platform are you running on? + options: + - Windows + - Linux + validations: + required: true + + - type: input + id: compiler + attributes: + label: Clang version + validations: + required: false + + - type: input + id: version + attributes: + label: Version / Commit + description: Version number or git commit hash + placeholder: v0.1.0 or abc1234 + validations: + required: false + + - type: textarea + id: environment + attributes: + label: Additional Environment Info + description: Any other relevant environment details (dev tool versions, GPU, etc.) + validations: + required: false + + - type: textarea + id: related + attributes: + label: Related + description: Links to related issues, code, or documentation + placeholder: | + - Possibly related to #69 + - Relevant code: `src/foo/bar.cpp:420` + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..3ba13e0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml new file mode 100644 index 0000000..2a10f72 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -0,0 +1,93 @@ +name: Feature Request +description: Propose a new feature or enhancement +title: "[Feature]: " +labels: ["enhancement"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to propose a feature! + + - type: textarea + id: summary + attributes: + label: Summary + description: Brief description of the feature and why it's needed + placeholder: | + Implement X to enable Y. + + The current system lacks Z, which means we can't do A, B, or C. + validations: + required: true + + - type: textarea + id: proposed-solution + attributes: + label: Proposed Solution + description: How should this be implemented? Include key features and design decisions. + placeholder: | + Build on **library X** with a custom layer for Y. + + ### Key Features + - **Feature A**: Description + - **Feature B**: Description + validations: + required: true + + - type: textarea + id: requirements + attributes: + label: Requirements + description: Checklist of requirements needed to implement this feature. Use `- [ ]` for checkboxes. + placeholder: | + ### Requirement 1 + - [ ] Function A + - [ ] Function B + + ### Requirement 2 + - [ ] Function C + - [ ] Function D + validations: + required: true + + - type: textarea + id: out-of-scope + attributes: + label: Out of Scope + description: What is explicitly NOT part of this feature request? + placeholder: | + - Feature X (separate effort) + - Support for Y (deferred) + validations: + required: false + + - type: textarea + id: dependencies + attributes: + label: Modified Dependencies + description: Any new or changed dependencies required for this feature + placeholder: | + - **new_library** - For X functionality + - **existing_lib** - Already in project + validations: + required: false + + - type: textarea + id: acceptance-criteria + attributes: + label: Acceptance Criteria + description: How do we know this feature is complete? Use `- [ ]` for checkboxes. + placeholder: | + - [ ] Feature X works as described + - [ ] All tests pass + - [ ] Documentation updated + validations: + required: true + + - type: textarea + id: related + attributes: + label: Related + description: Links to design docs, related issues, or relevant code + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/new-instruction.yml b/.github/ISSUE_TEMPLATE/new-instruction.yml new file mode 100644 index 0000000..c7de949 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/new-instruction.yml @@ -0,0 +1,128 @@ +name: New Instruction +description: Add a new instruction to the rexglue codegen +title: "instruction: " +labels: ["instruction"] +body: + - type: input + id: mnemonic + attributes: + label: Mnemonic + description: Assembly mnemonic + placeholder: "addze" + validations: + required: true + + - type: textarea + id: description + attributes: + label: Description + description: What the instruction does in plain language. + placeholder: "Add to Zero Extended - adds the contents of rA and the CA bit of the XER to rT." + validations: + required: true + + - type: dropdown + id: format + attributes: + label: Instruction Format + options: + - I (Branch - LI, AA, LK) + - B (Conditional branch - BO, BI, BD, AA, LK) + - D (Immediate - RT, RA, d/SIMM/UIMM) + - DS (Double-word - RT, RA, DS, XO) + - X (General - RT, RA, RB, XO, Rc) + - XL (Branch to LR/CTR - BO, BI, XO, LK) + - XFX (SPR access - RT, SPR, XO) + - XO (Arithmetic w/ overflow - RT, RA, RB, OE, XO, Rc) + - M (Rotate/mask - RS, RA, SH/RB, MB, ME, Rc) + - MD (Rotate double-word - RS, RA, sh, mb, XO, Rc) + - A (FP arithmetic - FRT, FRA, FRB, FRC, XO, Rc) + - VA (Vector 4-operand - VRT, VRA, VRB, VRC, XO) + - VX (Vector 3-operand - VRT, VRA, VRB, XO) + - VXR (Vector w/ record - VRT, VRA, VRB, Rc, XO) + - VMX128 (Xbox 360 extended vector) + validations: + required: true + + - type: dropdown + id: group + attributes: + label: Opcode Group + options: + - General (ALU/logical) + - Branch (control flow) + - Memory (load/store) + - Special (SPR access) + - Sync (synchronization) + - System (syscall/trap) + - Float (floating-point) + - Vector (VMX/VMX128) + validations: + required: true + + - type: input + id: primary_opcode + attributes: + label: Primary Opcode (bits 0-5) + placeholder: "31" + validations: + required: true + + - type: input + id: extended_opcode + attributes: + label: Extended Opcode + description: Leave blank if none. + placeholder: "266" + + - type: textarea + id: decoding + attributes: + label: Bit Layout & Decoding + description: Show the bit fields and how operands are extracted. Include all variants (Rc=0/1, OE=0/1). + validations: + required: true + + - type: textarea + id: simplified_mnemonics + attributes: + label: Simplified Mnemonics + description: Any simplified forms this maps to/from. + + - type: textarea + id: operation + attributes: + label: Operation (pseudocode) + description: Precise semantics including side effects (CR0, XER, etc). + value: | + ``` + rT <- rA + rB + if Rc then CR0 <- compare(rT, 0) + if OE then XER[SO,OV] <- overflow + ``` + validations: + required: true + + - type: checkboxes + id: flags + attributes: + label: Instruction Properties + options: + - label: "Record form (Rc=1 sets CR0)" + - label: "Overflow form (OE=1 sets XER[SO,OV])" + - label: "Reads memory" + - label: "Writes memory" + - label: "Reads/writes LR" + - label: "Reads/writes CTR" + - label: "Reads/writes XER (carry, overflow)" + - label: "Reads/writes FPSCR" + - label: "Needs CSR flush mode change (FPU vs VMX)" + - label: "Xbox 360 specific (not in standard PPC ISA)" + + - type: textarea + id: context + attributes: + label: Context + description: What game was this encountered in? Provide context around how it is used, including example use cases. + validations: + required: true diff --git a/.github/workflows/_build-platform.yaml b/.github/workflows/_build-platform.yaml new file mode 100644 index 0000000..fa02a97 --- /dev/null +++ b/.github/workflows/_build-platform.yaml @@ -0,0 +1,131 @@ +name: Build platform (reusable) + +on: + workflow_call: + inputs: + platform: + description: "win-amd64 | linux-amd64 | linux-arm64" + required: true + type: string + ref: + description: "Git ref (SHA or tag) to check out and build" + required: true + type: string + publish_mode: + description: "'release' to upload as a GitHub release asset, 'artifact' to upload as a workflow artifact" + required: true + type: string + artifact_name: + description: "Artifact name when publish_mode is 'artifact'" + required: false + type: string + default: "" + outputs: + version: + description: "Derived build version string (REXGLUE_VERSION_STRING)" + value: ${{ jobs.build.outputs.version }} + +jobs: + build: + runs-on: ${{ fromJSON('{"win-amd64":"windows-latest","linux-amd64":"ubuntu-latest","linux-arm64":"ubuntu-24.04-arm"}')[inputs.platform] }} + outputs: + version: ${{ steps.version.outputs.v }} + steps: + - uses: actions/checkout@v6 + with: + ref: ${{ inputs.ref }} + submodules: recursive + fetch-depth: 0 + fetch-tags: true + + - name: Install toolchain (Windows) + if: inputs.platform == 'win-amd64' + run: choco install llvm cmake ninja -y + + - name: Install clang 20 (Linux) + if: inputs.platform != 'win-amd64' + run: | + sudo apt-get update + sudo apt-get install -y wget gnupg lsb-release + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + sudo ./llvm.sh 20 + sudo apt-get install -y clang-20 lld-20 + sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-20 200 + sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-20 200 + + - name: Install build deps (linux-amd64) + if: inputs.platform == 'linux-amd64' + run: | + wget -qO- https://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo tee /etc/apt/trusted.gpg.d/lunarg.asc + sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-noble.list http://packages.lunarg.com/vulkan/lunarg-vulkan-noble.list + sudo apt update + sudo apt install -y cmake ninja-build build-essential git curl unzip autoconf python3.12-venv \ + libgtk-3-dev libx11-xcb-dev wine vulkan-sdk \ + libasound2-dev libpulse-dev libpipewire-0.3-dev + + - name: Install build deps (linux-arm64) + if: inputs.platform == 'linux-arm64' + run: | + sudo apt update + sudo apt install -y cmake ninja-build build-essential git curl unzip autoconf python3.12-venv \ + libgtk-3-dev libx11-xcb-dev libvulkan-dev glslc glslang-tools \ + libasound2-dev libpulse-dev libpipewire-0.3-dev + + - name: Set up sccache + uses: hendrikmuhs/ccache-action@v1.2.22 + with: + variant: sccache + key: ${{ inputs.platform }} + + - name: Configure + env: + CC: ${{ inputs.platform == 'win-amd64' && '' || 'clang-20' }} + CXX: ${{ inputs.platform == 'win-amd64' && '' || 'clang++-20' }} + run: cmake --preset ${{ inputs.platform }} -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache + + - name: Build and install + run: cmake --build out/build/${{ inputs.platform }} --target install --parallel + + - name: sccache stats + if: always() + shell: bash + run: sccache --show-stats || true + + - name: Read version + id: version + shell: bash + run: | + v=$(sed -nE 's/^#define REXGLUE_VERSION_STRING "([^"]+)".*/\1/p' \ + out/build/${{ inputs.platform }}/include/rex/version.h) + echo "v=${v}" >> "$GITHUB_OUTPUT" + + - name: Package (Windows) + if: inputs.platform == 'win-amd64' + shell: bash + run: | + cd out/install + 7z a "rexglue-sdk-${{ steps.version.outputs.v }}-${{ inputs.platform }}.zip" ${{ inputs.platform }} + + - name: Package (Linux) + if: inputs.platform != 'win-amd64' + run: | + cd out/install + zip -r "rexglue-sdk-${{ steps.version.outputs.v }}-${{ inputs.platform }}.zip" ${{ inputs.platform }} + + - name: Upload as release asset + if: inputs.publish_mode == 'release' + uses: softprops/action-gh-release@v2 + with: + files: out/install/rexglue-sdk-*-${{ inputs.platform }}.zip + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload as workflow artifact + if: inputs.publish_mode == 'artifact' + uses: actions/upload-artifact@v6 + with: + name: ${{ inputs.artifact_name }} + path: out/install/rexglue-sdk-*-${{ inputs.platform }}.zip + retention-days: 14 diff --git a/.github/workflows/build-linux-aarch64.yaml b/.github/workflows/build-linux-aarch64.yaml new file mode 100644 index 0000000..76676fe --- /dev/null +++ b/.github/workflows/build-linux-aarch64.yaml @@ -0,0 +1,19 @@ +name: Build rexglue-sdk linux-arm64 + +on: + push: + tags: + - "v*" + +permissions: + contents: write + actions: write + +jobs: + build: + uses: ./.github/workflows/_build-platform.yaml + with: + platform: linux-arm64 + ref: ${{ github.ref }} + publish_mode: release + secrets: inherit diff --git a/.github/workflows/build-linux-amd64.yaml b/.github/workflows/build-linux-amd64.yaml new file mode 100644 index 0000000..8d199cc --- /dev/null +++ b/.github/workflows/build-linux-amd64.yaml @@ -0,0 +1,19 @@ +name: Build rexglue-sdk linux-amd64 + +on: + push: + tags: + - "v*" + +permissions: + contents: write + actions: write + +jobs: + build: + uses: ./.github/workflows/_build-platform.yaml + with: + platform: linux-amd64 + ref: ${{ github.ref }} + publish_mode: release + secrets: inherit diff --git a/.github/workflows/build-win-amd64.yaml b/.github/workflows/build-win-amd64.yaml new file mode 100644 index 0000000..252c7c9 --- /dev/null +++ b/.github/workflows/build-win-amd64.yaml @@ -0,0 +1,19 @@ +name: Build rexglue-sdk win-amd64 + +on: + push: + tags: + - "v*" + +permissions: + contents: write + actions: write + +jobs: + build: + uses: ./.github/workflows/_build-platform.yaml + with: + platform: win-amd64 + ref: ${{ github.ref }} + publish_mode: release + secrets: inherit diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 0000000..a546877 --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,28 @@ +name: Lint & Format Check + +on: [pull_request, push] + +jobs: + format-check: + name: Format Check + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + + - name: Install clang-format + run: | + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + sudo ./llvm.sh 20 + sudo apt-get install -y clang-format-20 + + # - name: Install cmake-format + # run: pip install cmake-format + + - name: Check C/C++ formatting + run: | + find include src tests \ + -type f \( -name '*.cpp' -o -name '*.h' -o -name '*.hpp' -o -name '*.c' \) \ + | xargs clang-format-20 --dry-run --Werror + diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml new file mode 100644 index 0000000..8413d4b --- /dev/null +++ b/.github/workflows/nightly.yaml @@ -0,0 +1,152 @@ +name: Nightly rexglue-sdk + +on: + schedule: + - cron: "0 6 * * *" + workflow_dispatch: {} + +permissions: + contents: write + actions: write + +env: + DEV_BRANCH: development + NIGHTLY_TAG_PREFIX: nightly- + NIGHTLY_RETENTION: 10 + RELEASE_LIST_LIMIT: 1000 + +jobs: + check: + runs-on: ubuntu-latest + outputs: + should_build: ${{ steps.compare.outputs.should_build }} + dev_sha: ${{ steps.compare.outputs.dev_sha }} + prev_nightly_sha: ${{ steps.compare.outputs.prev_nightly_sha }} + tag_name: ${{ steps.compare.outputs.tag_name }} + steps: + - name: Checkout dev branch + uses: actions/checkout@v6 + with: + ref: ${{ env.DEV_BRANCH }} + fetch-depth: 1 + + - name: Compare dev HEAD to most recent nightly + id: compare + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + dev_sha=$(git rev-parse HEAD) + short_sha="${dev_sha:0:8}" + tag_name="${NIGHTLY_TAG_PREFIX}$(date -u +%Y%m%d)-${short_sha}" + echo "dev_sha=${dev_sha}" >> "$GITHUB_OUTPUT" + echo "tag_name=${tag_name}" >> "$GITHUB_OUTPUT" + prev_release=$(gh release list --limit "${RELEASE_LIST_LIMIT}" \ + --json tagName,isPrerelease,createdAt \ + | jq -r --arg prefix "${NIGHTLY_TAG_PREFIX}" \ + '[.[] | select(.isPrerelease) | select(.tagName | startswith($prefix))] + | sort_by(.createdAt) | last | .tagName // ""' \ + 2>/dev/null || echo "") + if [ -n "${prev_release}" ]; then + prev_sha=$(gh release view "${prev_release}" --json targetCommitish -q .targetCommitish 2>/dev/null || echo "") + else + prev_sha="" + fi + echo "prev_nightly_sha=${prev_sha}" >> "$GITHUB_OUTPUT" + if [ "${dev_sha}" = "${prev_sha}" ]; then + echo "${DEV_BRANCH} unchanged since last nightly (${dev_sha}); skipping build." + echo "should_build=false" >> "$GITHUB_OUTPUT" + else + echo "${DEV_BRANCH} advanced (${prev_sha:-} -> ${dev_sha}); building as ${tag_name}." + echo "should_build=true" >> "$GITHUB_OUTPUT" + fi + + build-win-amd64: + needs: check + if: needs.check.outputs.should_build == 'true' + uses: ./.github/workflows/_build-platform.yaml + with: + platform: win-amd64 + ref: ${{ needs.check.outputs.dev_sha }} + publish_mode: artifact + artifact_name: nightly-win-amd64 + secrets: inherit + + build-linux-amd64: + needs: check + if: needs.check.outputs.should_build == 'true' + uses: ./.github/workflows/_build-platform.yaml + with: + platform: linux-amd64 + ref: ${{ needs.check.outputs.dev_sha }} + publish_mode: artifact + artifact_name: nightly-linux-amd64 + secrets: inherit + + build-linux-arm64: + needs: check + if: needs.check.outputs.should_build == 'true' + uses: ./.github/workflows/_build-platform.yaml + with: + platform: linux-arm64 + ref: ${{ needs.check.outputs.dev_sha }} + publish_mode: artifact + artifact_name: nightly-linux-arm64 + secrets: inherit + + publish: + needs: [check, build-win-amd64, build-linux-amd64, build-linux-arm64] + if: needs.check.outputs.should_build == 'true' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + ref: ${{ needs.check.outputs.dev_sha }} + fetch-depth: 0 + + - name: Download all artifacts + uses: actions/download-artifact@v8 + with: + path: artifacts + + - name: Publish nightly release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION: ${{ needs.build-win-amd64.outputs.version }} + DEV_SHA: ${{ needs.check.outputs.dev_sha }} + PREV_SHA: ${{ needs.check.outputs.prev_nightly_sha }} + TAG_NAME: ${{ needs.check.outputs.tag_name }} + run: | + if [ -n "${PREV_SHA}" ] && git cat-file -e "${PREV_SHA}^{commit}" 2>/dev/null; then + commits=$(git log --no-merges --pretty='format:- %s (%h)' "${PREV_SHA}..${DEV_SHA}") + range_header="Changes since previous nightly (\`${PREV_SHA:0:8}\`):" + else + commits=$(git log --no-merges --pretty='format:- %s (%h)' -20 "${DEV_SHA}") + range_header="Latest commits on \`${DEV_BRANCH}\`:" + fi + if [ -z "${commits}" ]; then + commits="- (no new commits)" + fi + notes=$(printf '%s\n\n%s\n' "${range_header}" "${commits}") + gh release create "${TAG_NAME}" \ + --target "${DEV_SHA}" \ + --title "Nightly ${VERSION}" \ + --notes "${notes}" \ + --prerelease \ + artifacts/nightly-win-amd64/*.zip \ + artifacts/nightly-linux-amd64/*.zip \ + artifacts/nightly-linux-arm64/*.zip + + - name: Prune old nightlies + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release list --limit "${RELEASE_LIST_LIMIT}" \ + --json tagName,isPrerelease,createdAt \ + | jq -r --arg prefix "${NIGHTLY_TAG_PREFIX}" --argjson keep "${NIGHTLY_RETENTION}" \ + '[.[] | select(.isPrerelease) | select(.tagName | startswith($prefix))] + | sort_by(.createdAt) | reverse | .[$keep:] | .[].tagName' \ + | while IFS= read -r tag; do + [ -z "${tag}" ] && continue + echo "Pruning ${tag}" + gh release delete "${tag}" --yes --cleanup-tag + done diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..041d984 --- /dev/null +++ b/.gitignore @@ -0,0 +1,421 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates +*.env + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +[Aa][Rr][Mm]64[Ee][Cc]/ +bld/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Build results on 'Bin' directories +**/[Bb]in/* +# Uncomment if you have tasks that rely on *.refresh files to move binaries +# (https://github.com/github/gitignore/pull/3736) +#!**/[Bb]in/*.refresh + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* +*.trx + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Approval Tests result files +*.received.* + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.idb +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +# but not Directory.Build.rsp, as it configures directory-level build defaults +!Directory.Build.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +**/.paket/paket.exe +paket-files/ + +# FAKE - F# Make +**/.fake/ + +# CodeRush personal settings +**/.cr/personal + +# Python Tools for Visual Studio (PTVS) +**/__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +#tools/** +#!tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog +MSBuild_Logs/ + +# AWS SAM Build and Temporary Artifacts folder +.aws-sam + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +**/.mfractor/ + +# Local History for Visual Studio +**/.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +**/.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# CMake User Overrides +CMakeUserPresets.json diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..245c381 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,68 @@ +[submodule "thirdparty/libmspack"] + path = thirdparty/libmspack + url = https://github.com/kyz/libmspack.git +[submodule "thirdparty/glslang"] + path = thirdparty/glslang + url = https://github.com/KhronosGroup/glslang.git +[submodule "thirdparty/FFmpeg"] + path = thirdparty/FFmpeg + url = https://github.com/wmarti/FFmpeg.git + branch = xenia-ffmpeg-canary-full +[submodule "thirdparty/tomlplusplus"] + path = thirdparty/tomlplusplus + url = https://github.com/marzer/tomlplusplus.git +[submodule "thirdparty/simde"] + path = thirdparty/simde + url = https://github.com/simd-everywhere/simde.git +[submodule "thirdparty/xxHash"] + path = thirdparty/xxHash + url = https://github.com/Cyan4973/xxHash.git +[submodule "thirdparty/spdlog"] + path = thirdparty/spdlog + url = https://github.com/gabime/spdlog.git +[submodule "thirdparty/fmt"] + path = thirdparty/fmt + url = https://github.com/fmtlib/fmt.git +[submodule "thirdparty/catch2"] + path = thirdparty/catch2 + url = https://github.com/catchorg/Catch2.git +[submodule "thirdparty/snappy"] + path = thirdparty/snappy + url = https://github.com/google/snappy.git +[submodule "thirdparty/utfcpp"] + path = thirdparty/utfcpp + url = https://github.com/nemtrif/utfcpp.git +[submodule "thirdparty/volk"] + path = thirdparty/volk + url = https://github.com/zeux/volk.git +[submodule "thirdparty/vulkan-headers"] + path = thirdparty/vulkan-headers + url = https://github.com/KhronosGroup/Vulkan-Headers.git +[submodule "thirdparty/vulkan-memory-allocator"] + path = thirdparty/vulkan-memory-allocator + url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git +[submodule "thirdparty/imgui"] + path = thirdparty/imgui + url = https://github.com/ocornut/imgui.git +[submodule "thirdparty/spirv-tools"] + path = thirdparty/spirv-tools + url = https://github.com/KhronosGroup/SPIRV-Tools.git +[submodule "thirdparty/spirv-headers"] + path = thirdparty/spirv-headers + url = https://github.com/KhronosGroup/SPIRV-Headers.git +[submodule "thirdparty/cli11"] + path = thirdparty/cli11 + url = https://github.com/CLIUtils/CLI11 +[submodule "thirdparty/o1heap"] + path = thirdparty/o1heap + url = https://github.com/pavel-kirienko/o1heap.git +[submodule "thirdparty/sdl3"] + path = thirdparty/sdl3 + url = https://github.com/libsdl-org/SDL + branch = release-3.4.x +[submodule "thirdparty/inja"] + path = thirdparty/inja + url = https://github.com/pantor/inja.git +[submodule "thirdparty/tracy"] + path = thirdparty/tracy + url = https://github.com/wolfpld/tracy.git diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..448765a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,243 @@ +# ReXGlue SDK - Xbox 360 Recompilation Toolkit +# Modern C++23 cross-platform SDK for recompiling Xbox 360 executables +cmake_minimum_required(VERSION 3.25) + +project(ReXGlue + VERSION 0.8.0 + LANGUAGES C CXX + DESCRIPTION "Xbox 360 Recompilation SDK" +) +# Floor only: bump MAJOR.MINOR for API changes. Patch is derived from git tags +# in cmake/rex_version.cmake. See docs/RELEASING.md. + +#========================================================== +# Build Options +#========================================================== +option(REXGLUE_BUILD_TESTS "Build PPC instruction and unit tests" OFF) +option(REXGLUE_ENABLE_SANITIZERS "Enable UndefinedBehaviorSanitizer" OFF) +option(REXGLUE_ENABLE_FIDELITYFX "Enable optional AMD FidelityFX integration (experimental)" OFF) +option(REXGLUE_ENABLE_TRACY "Enable Tracy profiler integration" ON) +option(REXGLUE_ENABLE_PERF_COUNTERS "Enable lightweight perf counter registry and overlay" ON) +# Propagate profiling defines globally (compiled out in Release) +if(REXGLUE_ENABLE_TRACY) + add_compile_definitions($<$>:REXGLUE_ENABLE_PROFILING>) +endif() +if(REXGLUE_ENABLE_PERF_COUNTERS) + add_compile_definitions($<$>:REXGLUE_ENABLE_PERF_COUNTERS>) +endif() + +# Graphics backend selection +# D3D12: Windows only, ON by default. +# Vulkan: Cross-platform, ON by default on Linux, OFF by default on Windows. +if(WIN32) + option(REXGLUE_USE_D3D12 "Enable D3D12 graphics backend" ON) + option(REXGLUE_USE_VULKAN "Enable Vulkan graphics backend" OFF) +else() + set(REXGLUE_USE_D3D12 OFF) + option(REXGLUE_USE_VULKAN "Enable Vulkan graphics backend" ON) +endif() + +if(NOT REXGLUE_USE_D3D12 AND NOT REXGLUE_USE_VULKAN) + message(FATAL_ERROR "At least one graphics backend must be enabled (REXGLUE_USE_D3D12 or REXGLUE_USE_VULKAN)") +endif() + +if (REXGLUE_ENABLE_FIDELITYFX AND + NOT (REXGLUE_USE_VULKAN OR REXGLUE_USE_D3D12)) + message(FATAL_ERROR + "REXGLUE_ENABLE_FIDELITYFX requires at least one graphics backend") +endif() + +# Root of the SDK source tree +set(REXGLUE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}") + +# SDK install support +include(GNUInstallDirs) +include(CMakePackageConfigHelpers) + +if(UNIX AND NOT APPLE) + # Keep installed binaries self-contained by resolving shared libs relative + # to the install prefix (for example, bin -> ../lib). + set(CMAKE_BUILD_RPATH_USE_ORIGIN ON) + list(APPEND CMAKE_INSTALL_RPATH + "$ORIGIN" + "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}" + ) + set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ON) +endif() + +# Enforce Clang18 compiler +if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "ReXGlue requires Clang compiler. Please set CMAKE_CXX_COMPILER to clang++") +endif() + +if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "18.0") + message(FATAL_ERROR "ReXGlue requires Clang 18 or newer (found ${CMAKE_CXX_COMPILER_VERSION})") +endif() + +# Enforce x64 architecture +if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8) + message(FATAL_ERROR "ReXGlue only supports 64‑bit architectures (x86_64 or ARM64)") +endif() + +# Set C++23 standard +set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_DEBUG_POSTFIX d) +set(CMAKE_RELWITHDEBINFO_POSTFIX rd) + +if(NOT WIN32) + # Use appropriate code model based on architecture + if(CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64|x86_64") + # Large code model on x86_64 for linking with very large recompiled executables (35MB+) + add_compile_options(-mcmodel=large) + else() + # Small code model for other architectures (ARM64, etc.) + add_compile_options(-mcmodel=small) + endif() + # Position-independent code for all targets + set(CMAKE_POSITION_INDEPENDENT_CODE ON) +endif() + +# Global compile options +add_compile_options( + -fno-strict-aliasing + -ffp-model=strict + $<$:-g> + $<$:-O0> + $<$:-O3> + $<$:-DNDEBUG> + -fno-char8_t +) + +# Platform detection (supports AMD64 and ARM64) +if(WIN32) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64|x86_64") + set(REX_PLATFORM "win-amd64") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|ARM64") + set(REX_PLATFORM "win-arm64") + else() + message(FATAL_ERROR "Unsupported Windows architecture: ${CMAKE_SYSTEM_PROCESSOR}") + endif() + add_compile_definitions(REX_PLATFORM_WINDOWS=1) +elseif(UNIX AND NOT APPLE) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64|x86_64") + set(REX_PLATFORM "linux-amd64") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|ARM64") + set(REX_PLATFORM "linux-arm64") + else() + set(REX_PLATFORM "linux-${CMAKE_SYSTEM_PROCESSOR}") + endif() + add_compile_definitions(REX_PLATFORM_LINUX=1) +else() + message(FATAL_ERROR "Unsupported platform. ReXGlue supports Windows and Linux only.") +endif() + +# Build config as compile definition (multi-config generators don't know config at configure time) +add_compile_definitions(REXGLUE_BUILD_CONFIG="$") + +include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/rex_version.cmake) +rex_resolve_version(REXGLUE_FULL_VERSION + FLOOR_MAJOR ${PROJECT_VERSION_MAJOR} + FLOOR_MINOR ${PROJECT_VERSION_MINOR} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + +# Strip the -id trailer (if any) for the numeric-only version. +string(REGEX REPLACE "-.*$" "" REXGLUE_NUMERIC_VERSION "${REXGLUE_FULL_VERSION}") + +# Parse up to 4 numeric components for consumers that want integer access. +string(REGEX MATCH "^([0-9]+)\\.([0-9]+)(\\.([0-9]+))?(\\.([0-9]+))?" _ "${REXGLUE_NUMERIC_VERSION}") +set(REXGLUE_DERIVED_MAJOR "${CMAKE_MATCH_1}") +set(REXGLUE_DERIVED_MINOR "${CMAKE_MATCH_2}") +if(CMAKE_MATCH_4) + set(REXGLUE_DERIVED_PATCH "${CMAKE_MATCH_4}") +else() + set(REXGLUE_DERIVED_PATCH "0") +endif() +if(CMAKE_MATCH_6) + set(REXGLUE_DERIVED_TWEAK "${CMAKE_MATCH_6}") +else() + set(REXGLUE_DERIVED_TWEAK "0") +endif() + +# Generate version header -- must run after REX_PLATFORM is set +# Timestamp is set at configure time -- intentionally not updated on every rebuild +string(TIMESTAMP REXGLUE_BUILD_TIMESTAMP "%Y%m%d_%H%M") +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/include/rex/version.h.in + ${CMAKE_CURRENT_BINARY_DIR}/include/rex/version.h + @ONLY +) + +# Output directories (multi-config appends // automatically) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${REXGLUE_ROOT}/out/${REX_PLATFORM}") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${REXGLUE_ROOT}/out/${REX_PLATFORM}") +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${REXGLUE_ROOT}/out/${REX_PLATFORM}") + +# Sanitizer support for debugging memory corruption and undefined behavior +if(REXGLUE_ENABLE_SANITIZERS) + message(STATUS "Enabling UndefinedBehaviorSanitizer (UBSan only - ASan conflicts with custom memory mapping)") + # Note: ASan doesn't work well with the custom mmap at 0x100000000, so we only use UBSan + add_compile_options(-fsanitize=undefined -fno-omit-frame-pointer -g) + add_link_options(-fsanitize=undefined) +endif() + +if(REXGLUE_BUILD_TESTS) + list(APPEND CMAKE_MODULE_PATH "${REXGLUE_ROOT}/cmake") + list(APPEND CMAKE_MODULE_PATH "${REXGLUE_ROOT}/thirdparty/catch2/extras") +endif() + +# Third-party dependencies (vendored sources only) +add_subdirectory(thirdparty) + +# Enable warnings after thirdparty +add_compile_options( + -Wall + -Wextra +) + +include_directories(${REXGLUE_ROOT}/include) + +add_subdirectory(src/core) +add_subdirectory(src/filesystem) +add_subdirectory(src/ui) +add_subdirectory(src/input) +add_subdirectory(src/audio) +add_subdirectory(src/graphics) +add_subdirectory(src/system) +add_subdirectory(src/kernel) +add_subdirectory(src/codegen) +add_subdirectory(src/rexglue) + +# Add tests subdirectory if tests are enabled +if(REXGLUE_BUILD_TESTS) + enable_testing() + add_subdirectory(tests) +endif() + +# Print configuration summary +message(STATUS "===========================================") +message(STATUS "ReXGlue Configuration Summary:") +message(STATUS " Version: ${REXGLUE_FULL_VERSION}") +message(STATUS " Platform: ${REX_PLATFORM}") +message(STATUS " Compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") +message(STATUS " Configurations: ${CMAKE_CONFIGURATION_TYPES}") +message(STATUS " Output Dir: ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") +message(STATUS " C++ Standard: C++${CMAKE_CXX_STANDARD}") +message(STATUS " Graphics: D3D12=${REXGLUE_USE_D3D12} Vulkan=${REXGLUE_USE_VULKAN}") +message(STATUS " FidelityFX: ${REXGLUE_ENABLE_FIDELITYFX}") +message(STATUS " Tracy: ${REXGLUE_ENABLE_TRACY}") +message(STATUS " Perf Counters: ${REXGLUE_ENABLE_PERF_COUNTERS}") +message(STATUS "===========================================") + +# SDK install/export rules (skipped when consumed as a subdirectory) +if(PROJECT_IS_TOP_LEVEL) + include(cmake/rexglue_devenv.cmake) + include(cmake/rexglue_install.cmake) +else() + # When consumed via add_subdirectory(), provide the same interface as find_package(). + # This sets REXGLUE_SHARE_DIR and makes rexglue_configure_target() available. + set(REXGLUE_SHARE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/ui" PARENT_SCOPE) + set(REXGLUE_SHARE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/ui") + include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/rexglue_helpers.cmake) +endif() diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..dd51475 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,222 @@ +{ + "version": 6, + "cmakeMinimumRequired": { + "major": 3, + "minor": 25, + "patch": 0 + }, + "configurePresets": [ + { + "name": "windows-base", + "hidden": true, + "generator": "Ninja Multi-Config", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "cacheVariables": { + "CMAKE_C_COMPILER": "clang", + "CMAKE_CXX_COMPILER": "clang++", + "CMAKE_C_FLAGS": "-march=x86-64-v3", + "CMAKE_CXX_FLAGS": "-march=x86-64-v3", + "CMAKE_CXX_STANDARD": "23", + "CMAKE_CONFIGURATION_TYPES": "Debug;Release;RelWithDebInfo", + "CMAKE_CROSS_CONFIGS": "all", + "CMAKE_DEFAULT_BUILD_TYPE": "Debug", + "CMAKE_DEFAULT_CONFIGS": "all", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + } + }, + { + "name": "linux-base", + "hidden": true, + "generator": "Ninja Multi-Config", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "cacheVariables": { + "CMAKE_C_COMPILER": "clang", + "CMAKE_CXX_COMPILER": "clang++", + "CMAKE_C_FLAGS": "-march=x86-64-v3", + "CMAKE_CXX_FLAGS": "-march=x86-64-v3", + "CMAKE_CXX_STANDARD": "23", + "CMAKE_CONFIGURATION_TYPES": "Debug;Release;RelWithDebInfo", + "CMAKE_CROSS_CONFIGS": "all", + "CMAKE_DEFAULT_BUILD_TYPE": "Debug", + "CMAKE_DEFAULT_CONFIGS": "all", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Linux" + } + }, + { + "name": "windows-arm64-base", + "hidden": true, + "inherits": "windows-base", + "cacheVariables": { + "CMAKE_C_FLAGS": "-march=armv8-a", + "CMAKE_CXX_FLAGS": "-march=armv8-a" + } + }, + { + "name": "linux-arm64-base", + "hidden": true, + "inherits": "linux-base", + "cacheVariables": { + "CMAKE_C_FLAGS": "-march=armv8-a", + "CMAKE_CXX_FLAGS": "-march=armv8-a" + } + }, + { + "name": "win-amd64", + "displayName": "Windows AMD64", + "description": "Multi-config build for Windows AMD64 using Clang", + "inherits": "windows-base" + }, + { + "name": "win-arm64", + "displayName": "Windows ARM64", + "description": "Multi-config build for Windows ARM64 using Clang", + "inherits": "windows-arm64-base" + }, + { + "name": "linux-amd64", + "displayName": "Linux AMD64", + "description": "Multi-config build for Linux AMD64 using Clang", + "inherits": "linux-base" + }, + { + "name": "linux-arm64", + "displayName": "Linux ARM64", + "description": "Multi-config build for Linux ARM64 using Clang", + "inherits": "linux-arm64-base" + } + ], + "buildPresets": [ + { + "name": "win-amd64-debug", + "configurePreset": "win-amd64", + "configuration": "Debug" + }, + { + "name": "win-amd64-release", + "configurePreset": "win-amd64", + "configuration": "Release" + }, + { + "name": "win-amd64-relwithdebinfo", + "configurePreset": "win-amd64", + "configuration": "RelWithDebInfo" + }, + { + "name": "win-arm64-debug", + "configurePreset": "win-arm64", + "configuration": "Debug" + }, + { + "name": "win-arm64-release", + "configurePreset": "win-arm64", + "configuration": "Release" + }, + { + "name": "win-arm64-relwithdebinfo", + "configurePreset": "win-arm64", + "configuration": "RelWithDebInfo" + }, + { + "name": "linux-amd64-debug", + "configurePreset": "linux-amd64", + "configuration": "Debug" + }, + { + "name": "linux-amd64-release", + "configurePreset": "linux-amd64", + "configuration": "Release" + }, + { + "name": "linux-amd64-relwithdebinfo", + "configurePreset": "linux-amd64", + "configuration": "RelWithDebInfo" + }, + { + "name": "linux-arm64-debug", + "configurePreset": "linux-arm64", + "configuration": "Debug" + }, + { + "name": "linux-arm64-release", + "configurePreset": "linux-arm64", + "configuration": "Release" + }, + { + "name": "linux-arm64-relwithdebinfo", + "configurePreset": "linux-arm64", + "configuration": "RelWithDebInfo" + } + ], + "testPresets": [ + { + "name": "win-amd64-debug", + "configurePreset": "win-amd64", + "configuration": "Debug" + }, + { + "name": "win-amd64-release", + "configurePreset": "win-amd64", + "configuration": "Release" + }, + { + "name": "win-amd64-relwithdebinfo", + "configurePreset": "win-amd64", + "configuration": "RelWithDebInfo" + }, + { + "name": "win-arm64-debug", + "configurePreset": "win-arm64", + "configuration": "Debug" + }, + { + "name": "win-arm64-release", + "configurePreset": "win-arm64", + "configuration": "Release" + }, + { + "name": "win-arm64-relwithdebinfo", + "configurePreset": "win-arm64", + "configuration": "RelWithDebInfo" + }, + { + "name": "linux-amd64-debug", + "configurePreset": "linux-amd64", + "configuration": "Debug" + }, + { + "name": "linux-amd64-release", + "configurePreset": "linux-amd64", + "configuration": "Release" + }, + { + "name": "linux-amd64-relwithdebinfo", + "configurePreset": "linux-amd64", + "configuration": "RelWithDebInfo" + }, + { + "name": "linux-arm64-debug", + "configurePreset": "linux-arm64", + "configuration": "Debug" + }, + { + "name": "linux-arm64-release", + "configurePreset": "linux-arm64", + "configuration": "Release" + }, + { + "name": "linux-arm64-relwithdebinfo", + "configurePreset": "linux-arm64", + "configuration": "RelWithDebInfo" + } + ] +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..67ddc06 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,9 @@ +# Contributing + +See the [Contributing Guide](https://github.com/rexglue/rexglue-sdk/wiki/Development/Contributing) in the wiki for: + +- Build prerequisites and setup +- Code style conventions +- Formatting and linting instructions +- Git setup (line endings, rebasing) +- PR submission workflow diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..989af87 --- /dev/null +++ b/LICENSE @@ -0,0 +1,32 @@ +Copyright (c) 2026, Tom Clay + +Portions of this software are derived from the Xenia project: +Copyright (c) 2022, Ben Vanik and Xenia project contributors +https://xenia.jp + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..9e5b57e --- /dev/null +++ b/README.md @@ -0,0 +1,60 @@ +> [!CAUTION] +> This project is in early development. Expect things to not work quite right and there to be significant changes and breaking public API updates as development progresses. Contributions and feedback are welcome, but please be aware that the codebase is still evolving rapidly. + +

+
+ + ReXGlue banner + +
+
+ + Discord + + + rexglue-sdk stargazers + +

+ +ReXGlue converts Xbox 360 PowerPC code into portable C++ that runs natively on modern platforms. + +ReXGlue is heavily rooted on the foundations of [Xenia](https://github.com/xenia-project), the Xbox 360 emulator. Rather than interpreting or JIT-compiling PPC instructions at runtime, ReXGlue takes a different path: it generates C++ source code ahead of time, an approach inspired by [XenonRecomp](https://github.com/hedge-dev/XenonRecomp) and [rexdex's recompiler](https://github.com/rexdex/recompiler). + +Latest SDK builds and releases are published on [GitHub Releases](https://github.com/rexglue/rexglue-sdk/releases). Join the [Discord server](https://discord.gg/CNTxwSNZfT) for updates and share what you have created. + +## Builds + +| Channel | CI | Download | +| --- | --- | --- | +| Release | [![win-amd64](https://github.com/rexglue/rexglue-sdk/actions/workflows/build-win-amd64.yaml/badge.svg)](https://github.com/rexglue/rexglue-sdk/actions/workflows/build-win-amd64.yaml) [![linux-amd64](https://github.com/rexglue/rexglue-sdk/actions/workflows/build-linux-amd64.yaml/badge.svg)](https://github.com/rexglue/rexglue-sdk/actions/workflows/build-linux-amd64.yaml) [![linux-arm64](https://github.com/rexglue/rexglue-sdk/actions/workflows/build-linux-aarch64.yaml/badge.svg)](https://github.com/rexglue/rexglue-sdk/actions/workflows/build-linux-aarch64.yaml) | [Latest stable](https://github.com/rexglue/rexglue-sdk/releases/latest) | +| Nightly | [![nightly](https://github.com/rexglue/rexglue-sdk/actions/workflows/nightly.yaml/badge.svg)](https://github.com/rexglue/rexglue-sdk/actions/workflows/nightly.yaml) | [Latest pre-release](https://github.com/rexglue/rexglue-sdk/releases?q=prerelease%3Atrue) | + +## Quickstart + +For quick start guide, full CLI reference, and config file options, see the [wiki](https://github.com/rexglue/rexglue-sdk/wiki). + +# **Disclaimer** +ReXGlue is not affiliated with nor endorsed by Microsoft or Xbox. It is an independent project created for educational and development purposes. All trademarks and copyrights belong to their respective owners. + +This project is not intended to promote piracy nor unauthorized use of copyrighted material. Any misuse of this software to endorse or enable this type of activity is strictly prohibited. + + +# Credits + +## ReXGlue +- [Tom (crack)](https://github.com/tomcl7) - Project Founder +- [Loreaxe](https://github.com/Loreaxe) - Linux Contributor +- [mystixor](https://github.com/Mystixor) - Windows Contributor +- [Graine25](https://github.com/Graine25) - Project Support +- [Carlos Estrague (mrcmunir)](https://github.com/mrcmunir) - Linux / ARM64 Contributor +- [sanjay900](https://github.com/sanjay900) - Linux / SDL Contributor +- [Toby](https://github.com/TbyDtch) - Project Support +- [Roxxsen](https://github.com/Roxxsen) - CI/CD Contributor + +The list above is not exhaustive. Thanks to everyone in the ReXGlue community who contributes code, files issues, tests builds, and keeps the project moving. + +## Very Special Thank You: +- [Project Xenia](https://github.com/xenia-project/xenia/tree/master/src/xenia) - Their invaluable work on Xbox 360 emulation laid the groundwork for ReXGlue's development. This project (and numerous others) would not exist without their hard work and dedication. +- [XenonRecomp](https://github.com/hedge-dev/XenonRecomp) - For pioneering the modern static recompilation approach for Xbox 360. A lot of the codegen analysis logic and instruction translations are based on their work. Thank you! +- [rexdex's recompiler](https://github.com/rexdex/recompiler) - The OG static recompiler for Xbox 360. +- Many others in the Xbox 360 homebrew and modding communities whose work and research have contributed to the collective knowledge that makes projects like this possible. diff --git a/cmake/embed_templates.cmake b/cmake/embed_templates.cmake new file mode 100644 index 0000000..c0dd364 --- /dev/null +++ b/cmake/embed_templates.cmake @@ -0,0 +1,58 @@ +if(NOT DEFINED TEMPLATE_SOURCE_DIR OR NOT DEFINED TEMPLATE_OUTPUT_DIR) + message(FATAL_ERROR "embed_templates.cmake requires -DTEMPLATE_SOURCE_DIR and -DTEMPLATE_OUTPUT_DIR") +endif() + +file(GLOB_RECURSE INJA_TEMPLATE_FILES "${TEMPLATE_SOURCE_DIR}/*.inja") + +set(FORBIDDEN_DELIMITER ")__TMPL__\"") + +set(EMBEDDED_INCLUDES "") +set(EMBEDDED_MAP_ENTRIES "") + +foreach(TEMPLATE_FILE ${INJA_TEMPLATE_FILES}) + file(READ "${TEMPLATE_FILE}" TEMPLATE_CONTENT) + + string(FIND "${TEMPLATE_CONTENT}" "${FORBIDDEN_DELIMITER}" DELIMITER_POS) + if(NOT DELIMITER_POS EQUAL -1) + message(FATAL_ERROR + "Template file contains forbidden raw string delimiter ')__TMPL__\"':\n" + " ${TEMPLATE_FILE}\n" + "Please remove or rename this sequence in the template.") + endif() + + file(RELATIVE_PATH REL_PATH "${TEMPLATE_SOURCE_DIR}" "${TEMPLATE_FILE}") + string(REGEX REPLACE "\\.inja$" "" CANONICAL_ID "${REL_PATH}") + + string(REPLACE "/" "_" VAR_NAME "${CANONICAL_ID}") + string(REPLACE "-" "_" VAR_NAME "${VAR_NAME}") + + set(HEADER_FILE "${TEMPLATE_OUTPUT_DIR}/${VAR_NAME}.inja.h") + file(WRITE "${HEADER_FILE}" + "// Auto-generated from resources/templates/${REL_PATH} -- DO NOT EDIT\n" + "#pragma once\n" + "#include \n\n" + "namespace rex::codegen::embedded {\n" + "inline constexpr std::string_view ${VAR_NAME} = R\"__TMPL__(${TEMPLATE_CONTENT})__TMPL__\";\n" + "} // namespace rex::codegen::embedded\n" + ) + + string(APPEND EMBEDDED_INCLUDES "#include \"${VAR_NAME}.inja.h\"\n") + string(APPEND EMBEDDED_MAP_ENTRIES " {\"${CANONICAL_ID}\", embedded::${VAR_NAME}},\n") +endforeach() + +file(WRITE "${TEMPLATE_OUTPUT_DIR}/embedded_templates.h" + "// Auto-generated master template index -- DO NOT EDIT\n" + "#pragma once\n\n" + "#include \n" + "#include \n" + "#include \n\n" + "${EMBEDDED_INCLUDES}\n" + "namespace rex::codegen {\n\n" + "inline const std::unordered_map& embeddedTemplates() {\n" + " static const std::unordered_map map = {\n" + "${EMBEDDED_MAP_ENTRIES}" + " };\n" + " return map;\n" + "}\n\n" + "} // namespace rex::codegen\n" +) diff --git a/cmake/ppc_test_pipeline.cmake b/cmake/ppc_test_pipeline.cmake new file mode 100644 index 0000000..59d01ee --- /dev/null +++ b/cmake/ppc_test_pipeline.cmake @@ -0,0 +1,97 @@ +# cmake/ppc_test_pipeline.cmake +# PPC assembly test build pipeline +# Provides ppc_add_test_binary() for assembling, linking, and generating +# symbol maps from PPC assembly test files. + +# Locate PPC toolchain in tools/ directory +set(PPC_TOOLS_DIR "${PROJECT_SOURCE_DIR}/tools/binutils") + +if(WIN32) + set(PPC_ASSEMBLER "${PPC_TOOLS_DIR}/powerpc-none-elf-as.exe") + set(PPC_LINKER "${PPC_TOOLS_DIR}/powerpc-none-elf-ld.exe") + set(PPC_NM "${PPC_TOOLS_DIR}/powerpc-none-elf-nm.exe") +else() + set(PPC_ASSEMBLER "${PPC_TOOLS_DIR}/powerpc-none-elf-as") + set(PPC_LINKER "${PPC_TOOLS_DIR}/powerpc-none-elf-ld") + set(PPC_NM "${PPC_TOOLS_DIR}/powerpc-none-elf-nm") +endif() + +# Verify toolchain exists +if(NOT EXISTS "${PPC_ASSEMBLER}") + message(FATAL_ERROR "PPC assembler not found at ${PPC_ASSEMBLER}") +endif() +if(NOT EXISTS "${PPC_LINKER}") + message(FATAL_ERROR "PPC linker not found at ${PPC_LINKER}") +endif() + +message(STATUS "PowerPC assembler: ${PPC_ASSEMBLER}") +message(STATUS "PowerPC linker: ${PPC_LINKER}") + +# Convert Windows paths to Cygwin paths for binutils (Windows only) +function(_ppc_convert_to_cygwin_path WINDOWS_PATH OUTPUT_VAR) + if(WIN32 AND WINDOWS_PATH MATCHES "^([A-Za-z]):") + string(REGEX REPLACE "^([A-Za-z]):" "/cygdrive/\\1" CYGWIN_PATH "${WINDOWS_PATH}") + string(SUBSTRING "${CYGWIN_PATH}" 10 1 DRIVE_LETTER) + string(TOLOWER "${DRIVE_LETTER}" DRIVE_LOWER) + string(REGEX REPLACE "^/cygdrive/[A-Za-z]" "/cygdrive/${DRIVE_LOWER}" CYGWIN_PATH "${CYGWIN_PATH}") + string(REPLACE "\\" "/" CYGWIN_PATH "${CYGWIN_PATH}") + set(${OUTPUT_VAR} "${CYGWIN_PATH}" PARENT_SCOPE) + else() + set(${OUTPUT_VAR} "${WINDOWS_PATH}" PARENT_SCOPE) + endif() +endfunction() + +# Add a PPC test binary from an assembly file. +# Assembles .s -> .o, links .o -> .bin, generates .o -> .map. +# Appends output files to PPC_TEST_BINS, PPC_TEST_MAPS, PPC_TEST_OBJS +# global properties. +function(ppc_add_test_binary ASM_FILE OBJ_DIR BIN_DIR) + get_filename_component(BASE_NAME ${ASM_FILE} NAME_WE) + + set(OBJ_FILE ${OBJ_DIR}/${BASE_NAME}.o) + set(BIN_FILE ${BIN_DIR}/${BASE_NAME}.bin) + set(MAP_FILE ${BIN_DIR}/${BASE_NAME}.map) + + _ppc_convert_to_cygwin_path("${OBJ_FILE}" OBJ_FILE_CYGWIN) + _ppc_convert_to_cygwin_path("${BIN_FILE}" BIN_FILE_CYGWIN) + _ppc_convert_to_cygwin_path("${MAP_FILE}" MAP_FILE_CYGWIN) + _ppc_convert_to_cygwin_path("${ASM_FILE}" ASM_FILE_CYGWIN) + + # Assemble .s to .o + add_custom_command( + OUTPUT ${OBJ_FILE} + COMMAND ${PPC_ASSEMBLER} + -a32 -be -mregnames -mpower7 -maltivec -mvsx -mvmx128 -R + -o ${OBJ_FILE_CYGWIN} + ${ASM_FILE_CYGWIN} + DEPENDS ${ASM_FILE} + COMMENT "Assembling ${BASE_NAME}.s" + VERBATIM + ) + + # Link .o to .bin + add_custom_command( + OUTPUT ${BIN_FILE} + COMMAND ${PPC_LINKER} + -A powerpc:common32 -melf32ppc -EB -nostdlib + --oformat=binary -Ttext=0x82010000 -e 0x82010000 + -o ${BIN_FILE_CYGWIN} + ${OBJ_FILE_CYGWIN} + DEPENDS ${OBJ_FILE} + COMMENT "Linking ${BASE_NAME}.bin" + VERBATIM + ) + + # Generate symbol map + add_custom_command( + OUTPUT ${MAP_FILE} + COMMAND ${PPC_NM} --numeric-sort ${OBJ_FILE_CYGWIN} > ${MAP_FILE} + DEPENDS ${OBJ_FILE} + COMMENT "Generating symbol map for ${BASE_NAME}" + VERBATIM + ) + + set_property(GLOBAL APPEND PROPERTY PPC_TEST_BINS ${BIN_FILE}) + set_property(GLOBAL APPEND PROPERTY PPC_TEST_MAPS ${MAP_FILE}) + set_property(GLOBAL APPEND PROPERTY PPC_TEST_OBJS ${OBJ_FILE}) +endfunction() diff --git a/cmake/rex_version.cmake b/cmake/rex_version.cmake new file mode 100644 index 0000000..d593ee4 --- /dev/null +++ b/cmake/rex_version.cmake @@ -0,0 +1,144 @@ +#========================================================== +# rex_compute_version( +# FLOOR_MAJOR +# FLOOR_MINOR +# GIT_DESCRIBE_LONG # output of git describe --tags --long ... +# GIT_DESCRIBE_EXACT # output of git describe --tags --exact-match +# BRANCH_NAME ) # output of git symbolic-ref --short HEAD +# +# Emits a CMake-style version string: MAJOR.MINOR[.PATCH[.TWEAK]][-id]. +# See https://cmake.org/cmake/help/latest/variable/CMAKE_VERSION.html +# +# Tagged commit (vX.Y[.Z[.W]]): emits the tag verbatim (without the v). +# Untagged commit: emits MAJOR...- +# where id is "dev.gSHA" on any branch and "rc.gSHA" on a release/* branch. +#========================================================== +function(rex_compute_version out_var) + set(one_value FLOOR_MAJOR FLOOR_MINOR GIT_DESCRIBE_LONG GIT_DESCRIBE_EXACT BRANCH_NAME) + cmake_parse_arguments(ARG "" "${one_value}" "" ${ARGN}) + + if(NOT "${ARG_GIT_DESCRIBE_EXACT}" STREQUAL "") + if(ARG_GIT_DESCRIBE_EXACT MATCHES "^v([0-9]+\\.[0-9]+(\\.[0-9]+)?(\\.[0-9]+)?)$") + set(${out_var} "${CMAKE_MATCH_1}" PARENT_SCOPE) + return() + endif() + message(FATAL_ERROR "rex_compute_version: unparseable exact tag '${ARG_GIT_DESCRIBE_EXACT}'") + endif() + + if("${ARG_GIT_DESCRIBE_LONG}" STREQUAL "") + message(WARNING + "rex_compute_version: no v* tag reachable from HEAD. " + "Falling back to ${ARG_FLOOR_MAJOR}.${ARG_FLOOR_MINOR}.0.0-dev.unknown. " + "If this is a CI build, ensure tags are fetched (fetch-depth: 0 + fetch-tags: true). " + "If this is a fork, push tags with: git push --tags") + set(${out_var} "${ARG_FLOOR_MAJOR}.${ARG_FLOOR_MINOR}.0.0-dev.unknown" PARENT_SCOPE) + return() + endif() + + if(NOT ARG_GIT_DESCRIBE_LONG MATCHES "^v([0-9]+)\\.([0-9]+)(\\.([0-9]+))?(\\.([0-9]+))?-([0-9]+)-g([0-9a-f]+)$") + message(FATAL_ERROR "rex_compute_version: unparseable describe output '${ARG_GIT_DESCRIBE_LONG}'") + endif() + set(tag_minor ${CMAKE_MATCH_2}) + if(CMAKE_MATCH_4) + set(tag_patch ${CMAKE_MATCH_4}) + else() + set(tag_patch 0) + endif() + set(commit_count ${CMAKE_MATCH_7}) + set(short_sha ${CMAKE_MATCH_8}) + + # Floor minor must never go backwards. + if(ARG_FLOOR_MINOR LESS tag_minor) + message(FATAL_ERROR + "rex_compute_version: floor minor (${ARG_FLOOR_MINOR}) is behind tag minor (${tag_minor}). " + "The floor in CMakeLists.txt must not regress.") + endif() + + if(ARG_FLOOR_MINOR EQUAL tag_minor) + math(EXPR derived_patch "${tag_patch} + 1") + else() + set(derived_patch 0) + endif() + + if(ARG_BRANCH_NAME MATCHES "^release/") + set(id "rc.g${short_sha}") + else() + set(id "dev.g${short_sha}") + endif() + + set(${out_var} "${ARG_FLOOR_MAJOR}.${ARG_FLOOR_MINOR}.${derived_patch}.${commit_count}-${id}" PARENT_SCOPE) +endfunction() + +#========================================================== +# rex_resolve_version( +# FLOOR_MAJOR +# FLOOR_MINOR +# [SOURCE_DIR ]) # defaults to CMAKE_SOURCE_DIR +# +# Runs git in the working tree, then delegates to rex_compute_version. +#========================================================== +function(rex_resolve_version out_var) + set(one_value FLOOR_MAJOR FLOOR_MINOR SOURCE_DIR) + cmake_parse_arguments(ARG "" "${one_value}" "" ${ARGN}) + + if(NOT ARG_SOURCE_DIR) + set(ARG_SOURCE_DIR "${CMAKE_SOURCE_DIR}") + endif() + + find_program(GIT_EXECUTABLE git) + if(NOT GIT_EXECUTABLE) + rex_compute_version(result + FLOOR_MAJOR ${ARG_FLOOR_MAJOR} + FLOOR_MINOR ${ARG_FLOOR_MINOR} + GIT_DESCRIBE_LONG "" + GIT_DESCRIBE_EXACT "" + BRANCH_NAME "") + set(${out_var} "${result}" PARENT_SCOPE) + return() + endif() + + execute_process( + COMMAND ${GIT_EXECUTABLE} describe --tags --exact-match + --match "v[0-9]*.[0-9]*.[0-9]*" + --exclude "*-*" + WORKING_DIRECTORY "${ARG_SOURCE_DIR}" + OUTPUT_VARIABLE describe_exact + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE describe_exact_rc) + if(NOT describe_exact_rc EQUAL 0) + set(describe_exact "") + endif() + + execute_process( + COMMAND ${GIT_EXECUTABLE} describe --tags --long + --match "v[0-9]*.[0-9]*" + --exclude "*-*" + WORKING_DIRECTORY "${ARG_SOURCE_DIR}" + OUTPUT_VARIABLE describe_long + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE describe_long_rc) + if(NOT describe_long_rc EQUAL 0) + set(describe_long "") + endif() + + execute_process( + COMMAND ${GIT_EXECUTABLE} symbolic-ref --short HEAD + WORKING_DIRECTORY "${ARG_SOURCE_DIR}" + OUTPUT_VARIABLE branch_name + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE branch_rc) + if(NOT branch_rc EQUAL 0) + set(branch_name "") + endif() + + rex_compute_version(result + FLOOR_MAJOR ${ARG_FLOOR_MAJOR} + FLOOR_MINOR ${ARG_FLOOR_MINOR} + GIT_DESCRIBE_LONG "${describe_long}" + GIT_DESCRIBE_EXACT "${describe_exact}" + BRANCH_NAME "${branch_name}") + set(${out_var} "${result}" PARENT_SCOPE) +endfunction() diff --git a/cmake/rexglueConfig.cmake.in b/cmake/rexglueConfig.cmake.in new file mode 100644 index 0000000..887bb9e --- /dev/null +++ b/cmake/rexglueConfig.cmake.in @@ -0,0 +1,39 @@ +@PACKAGE_INIT@ + +set(REXGLUE_VERSION_STRING "@REXGLUE_FULL_VERSION@") + +set(REXGLUE_SHARE_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_DATADIR@/rexglue") + +include(CMakeFindDependencyMacro) + +include("${CMAKE_CURRENT_LIST_DIR}/rexglue_helpers.cmake") + +list(PREPEND CMAKE_PREFIX_PATH "${PACKAGE_PREFIX_DIR}") + +find_dependency(fmt CONFIG) +find_dependency(spdlog CONFIG) +find_dependency(Snappy CONFIG) +find_dependency(utf8cpp CONFIG) +find_dependency(SDL3 CONFIG) + +set(REXGLUE_USE_VULKAN @REXGLUE_USE_VULKAN@) +if(REXGLUE_USE_VULKAN) + find_dependency(VulkanHeaders CONFIG) + find_dependency(volk CONFIG) + find_dependency(VulkanMemoryAllocator CONFIG) +endif() + +include("${CMAKE_CURRENT_LIST_DIR}/rexglueTargets.cmake") + +if(TARGET rex::runtime AND NOT TARGET rex::system) + add_library(rex::system ALIAS rex::runtime) +endif() +if(TARGET rex::runtime AND NOT TARGET rex::kernel) + add_library(rex::kernel ALIAS rex::runtime) +endif() + +if(NOT rexglue_FIND_QUIETLY) + message(STATUS "Found ReXGlue SDK ${REXGLUE_VERSION_STRING} at (${PACKAGE_PREFIX_DIR})") +endif() + +check_required_components(rexglue) diff --git a/cmake/rexglue_devenv.cmake b/cmake/rexglue_devenv.cmake new file mode 100644 index 0000000..9f2dff2 --- /dev/null +++ b/cmake/rexglue_devenv.cmake @@ -0,0 +1,13 @@ +# ReXGlue developer environment setup target. +# Provides the `config-rexdevenv` target that installs the pre-commit hook, +# VS terminal profile, and verifies the toolchain. +# Requires PowerShell 7 (pwsh) on all platforms. + +add_custom_target(config-rexdevenv + COMMAND pwsh -NoProfile -ExecutionPolicy Bypass -Command + "Import-Module '${REXGLUE_ROOT}/scripts/PSReX' -Force; Invoke-ReXSetup -RepoRoot '${REXGLUE_ROOT}'" + WORKING_DIRECTORY "${REXGLUE_ROOT}" + COMMENT "Configuring ReXGlue developer environment..." + VERBATIM + USES_TERMINAL +) diff --git a/cmake/rexglue_fidelityfx.cmake b/cmake/rexglue_fidelityfx.cmake new file mode 100644 index 0000000..af35fa8 --- /dev/null +++ b/cmake/rexglue_fidelityfx.cmake @@ -0,0 +1,133 @@ +# rexglue_fidelityfx.cmake — Optional AMD FidelityFX integration via FetchContent +# +# Expects REXGLUE_ENABLE_FIDELITYFX to be set before inclusion. +# On success, creates amd_fidelityfx_vk and/or amd_fidelityfx_dx12 targets +# and sets REXGLUE_FIDELITYFX_SOURCE_DIR to the fetched SDK root. + +if(NOT REXGLUE_ENABLE_FIDELITYFX) + return() +endif() + +# ── Dependency validation ──────────────────────────────────────────────── +if(NOT WIN32) + find_package(Vulkan QUIET) + if(NOT Vulkan_FOUND) + message(WARNING + "REXGLUE_ENABLE_FIDELITYFX requires the Vulkan SDK but it was not found.\n" + "Install the LunarG Vulkan SDK: https://vulkan.lunarg.com/sdk/home\n" + "Disabling FidelityFX.") + set(REXGLUE_ENABLE_FIDELITYFX OFF CACHE BOOL "" FORCE) + return() + elseif(Vulkan_VERSION VERSION_LESS "1.3.250") + message(WARNING + "REXGLUE_ENABLE_FIDELITYFX requires Vulkan SDK >= 1.3.250 " + "(found ${Vulkan_VERSION}).\n" + "Update via: https://vulkan.lunarg.com/sdk/home\n" + "Disabling FidelityFX.") + set(REXGLUE_ENABLE_FIDELITYFX OFF CACHE BOOL "" FORCE) + return() + else() + find_program(_rexglue_glslc glslc) + find_program(_rexglue_glslang glslangValidator) + if(NOT _rexglue_glslc AND NOT _rexglue_glslang) + message(WARNING + "REXGLUE_ENABLE_FIDELITYFX requires Vulkan shader tools " + "(glslc or glslangValidator) but neither was found.\n" + "Install the full LunarG Vulkan SDK: https://vulkan.lunarg.com/sdk/home\n" + "Disabling FidelityFX.") + set(REXGLUE_ENABLE_FIDELITYFX OFF CACHE BOOL "" FORCE) + unset(_rexglue_glslc CACHE) + unset(_rexglue_glslang CACHE) + return() + endif() + unset(_rexglue_glslc CACHE) + unset(_rexglue_glslang CACHE) + endif() +endif() + +# ── Fetch FidelityFX SDK ───────────────────────────────────────────────── +include(FetchContent) +FetchContent_Declare( + fidelityfx + GIT_REPOSITORY https://github.com/rexglue/FidelityFX-SDK.git + GIT_TAG eee08db1688ac3d1275a70b728f4a8ba22914213 + GIT_SHALLOW OFF +) +FetchContent_GetProperties(fidelityfx) +if(NOT fidelityfx_POPULATED) + FetchContent_Populate(fidelityfx) +endif() + +set(REXGLUE_FIDELITYFX_SOURCE_DIR "${fidelityfx_SOURCE_DIR}" CACHE INTERNAL + "Root of the fetched FidelityFX SDK source tree") + +# ── Backend selection ──────────────────────────────────────────────────── +set(REXGLUE_FIDELITYFX_BACKEND "auto" CACHE STRING + "FidelityFX backend to build (auto, vk, dx12)") +set_property(CACHE REXGLUE_FIDELITYFX_BACKEND PROPERTY STRINGS auto vk dx12) +set(_rexglue_fidelityfx_backend "${REXGLUE_FIDELITYFX_BACKEND}") +string(TOLOWER "${_rexglue_fidelityfx_backend}" _rexglue_fidelityfx_backend) + +if(_rexglue_fidelityfx_backend STREQUAL "auto") + if(WIN32 AND REXGLUE_USE_D3D12) + set(_rexglue_fidelityfx_backend "dx12") + elseif(REXGLUE_USE_VULKAN) + set(_rexglue_fidelityfx_backend "vk") + elseif(REXGLUE_USE_D3D12) + set(_rexglue_fidelityfx_backend "dx12") + endif() +endif() + +if(_rexglue_fidelityfx_backend STREQUAL "vk") + if(NOT REXGLUE_USE_VULKAN) + message(FATAL_ERROR + "REXGLUE_FIDELITYFX_BACKEND=vk requires REXGLUE_USE_VULKAN=ON") + endif() + set(FFX_API_BACKEND VK_X64 CACHE STRING "" FORCE) +elseif(_rexglue_fidelityfx_backend STREQUAL "dx12") + if(NOT REXGLUE_USE_D3D12) + message(FATAL_ERROR + "REXGLUE_FIDELITYFX_BACKEND=dx12 requires REXGLUE_USE_D3D12=ON") + endif() + set(FFX_API_BACKEND DX12_X64 CACHE STRING "" FORCE) +elseif(_rexglue_fidelityfx_backend STREQUAL "") + message(FATAL_ERROR "FidelityFX requires a supported graphics backend") +else() + message(FATAL_ERROR + "Invalid REXGLUE_FIDELITYFX_BACKEND='${REXGLUE_FIDELITYFX_BACKEND}' " + "(expected auto, vk, or dx12)") +endif() + +if(REXGLUE_USE_VULKAN AND REXGLUE_USE_D3D12) + message(STATUS + "FidelityFX backend selected for this build: ${_rexglue_fidelityfx_backend}") +endif() + +# ── Build FidelityFX ───────────────────────────────────────────────────── +set(FFX_API_ENABLE_FRAMEGEN_PROVIDER OFF CACHE BOOL "" FORCE) +if(WIN32) + set(FFX_API_AUTO_COMPILE_SHADERS ON CACHE BOOL "" FORCE) +else() + set(FFX_API_AUTO_COMPILE_SHADERS OFF CACHE BOOL "" FORCE) +endif() +add_subdirectory("${fidelityfx_SOURCE_DIR}/ffx-api" "${fidelityfx_BINARY_DIR}/ffx-api" EXCLUDE_FROM_ALL) + +# The upstream FidelityFX targets expose source-tree include paths in +# INTERFACE_INCLUDE_DIRECTORIES, which breaks our install export checks. +# We only link against these targets internally, so no public includes are +# needed on the exported interface. +if(TARGET amd_fidelityfx_vk) + set_target_properties(amd_fidelityfx_vk PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "" + ) +endif() +if(TARGET amd_fidelityfx_dx12) + set_target_properties(amd_fidelityfx_dx12 PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "" + ) +endif() + +# FidelityFX's toolchain.cmake force-sets CMAKE_GENERATOR_PLATFORM (for VS generators). +# With Ninja this variable is invalid and poisons every subsequent try_compile() call. +# Clear it from the cache. +unset(CMAKE_GENERATOR_PLATFORM CACHE) diff --git a/cmake/rexglue_helpers.cmake b/cmake/rexglue_helpers.cmake new file mode 100644 index 0000000..6f88084 --- /dev/null +++ b/cmake/rexglue_helpers.cmake @@ -0,0 +1,142 @@ +#========================================================== +# rexglue_helpers.cmake +# +# Three helpers, each with a single responsibility: +# rexglue_apply_target_settings() - common compile/platform flags +# rexglue_configure_target() - host application +# rexglue_configure_module_target( ...) - guest DLL module +#========================================================== + +#========================================================== +# rexglue_apply_target_settings() - Common flags +# +# Applied to both host apps and guest DLL modules. Compile/link flags only; +# runtime DLL staging is the host's job (see rexglue_configure_target). +#========================================================== +function(rexglue_apply_target_settings target_name) + if(UNIX AND NOT APPLE) + find_package(PkgConfig REQUIRED) + pkg_check_modules(GTK3 REQUIRED gtk+-3.0) + target_include_directories(${target_name} PRIVATE ${GTK3_INCLUDE_DIRS}) + target_link_libraries(${target_name} PRIVATE ${GTK3_LIBRARIES}) + # Large executable support + if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64") + target_link_options(${target_name} PRIVATE -Wl,--no-relax) + target_compile_options(${target_name} PRIVATE -mcmodel=large) + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|ARM64") + target_compile_options(${target_name} PRIVATE -march=armv8-a) + endif() + endif() + + if(NOT MSVC) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64") + target_compile_options(${target_name} PRIVATE -msse4.1) + endif() + endif() +endfunction() + +#========================================================== +# rexglue_configure_target() - Host application +# +# Adds: +# - Platform entry point source (windowed_app_main_*.cpp) +# - ReXApp base class source (rex_app.cpp) +# - Build-config define for the version stamp +# - $ORIGIN RPATH on UNIX so the host finds librexruntime.so next to itself +# - Windows POST_BUILD copy of TARGET_RUNTIME_DLLS and the FidelityFX DLLs. +# Guest modules colocate with the host (see rexglue_configure_module_target), +# so this single copy handles them transitively. +#========================================================== +function(rexglue_configure_target target_name) + if(WIN32) + target_sources(${target_name} PRIVATE + ${REXGLUE_SHARE_DIR}/windowed_app_main_win.cpp) + else() + target_sources(${target_name} PRIVATE + ${REXGLUE_SHARE_DIR}/windowed_app_main_posix.cpp) + endif() + + target_sources(${target_name} PRIVATE + ${REXGLUE_SHARE_DIR}/rex_app.cpp) + + target_compile_definitions(${target_name} PRIVATE + REXGLUE_BUILD_CONFIG="$") + + if(TARGET imgui::imgui) + target_link_libraries(${target_name} PRIVATE imgui::imgui) + endif() + target_include_directories(${target_name} PRIVATE + ${CMAKE_CURRENT_BINARY_DIR}/rexglue-sdk/include) + + if(UNIX AND NOT APPLE) + set_target_properties(${target_name} PROPERTIES + INSTALL_RPATH "$ORIGIN" + BUILD_WITH_INSTALL_RPATH ON + ) + endif() + + rexglue_apply_target_settings(${target_name}) + + if(WIN32) + # Stage runtime DLLs (rexruntime, TracyClient, etc.) next to the host + # binary on every link. copy_if_different is a no-op when up to date. + add_custom_command(TARGET ${target_name} POST_BUILD + COMMAND "$<$>:${CMAKE_COMMAND};-E;copy_if_different;$;$>" + COMMAND_EXPAND_LISTS + VERBATIM + ) + # FidelityFX is linked PRIVATE by rexui (to avoid propagating DLL + # requirements to tool-mode targets), so copy its DLLs explicitly. + foreach(_fx amd_fidelityfx_vk amd_fidelityfx_dx12) + if(TARGET ${_fx}) + add_custom_command(TARGET ${target_name} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + $ + $ + VERBATIM + ) + endif() + endforeach() + endif() +endfunction() + +#========================================================== +# rexglue_configure_module_target( [HOST ]) +# - Guest DLL module +# +# Output is colocated with HOST (or CMAKE_RUNTIME_OUTPUT_DIRECTORY) so the +# host's LoadUserModule finds it; the host is wired to depend on the module +# so a top-level build of the host pulls in all guest DLLs. No runtime DLL +# staging here; the host's POST_BUILD copy covers shared dependencies. +#========================================================== +function(rexglue_configure_module_target target_name) + cmake_parse_arguments(ARG "" "HOST" "" ${ARGN}) + + if(ARG_HOST) + set_target_properties(${target_name} PROPERTIES + LIBRARY_OUTPUT_DIRECTORY $ + RUNTIME_OUTPUT_DIRECTORY $ + ARCHIVE_OUTPUT_DIRECTORY $ + ) + # Defer add_dependencies so the host target may be declared after + # this module call. Wrapping in EVAL CODE expands the variables now, + # which DEFER CALL otherwise treats as literal argument text. + cmake_language(EVAL CODE + "cmake_language(DEFER CALL add_dependencies ${ARG_HOST} ${target_name})") + elseif(CMAKE_RUNTIME_OUTPUT_DIRECTORY) + set_target_properties(${target_name} PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + ) + endif() + + if(UNIX AND NOT APPLE) + set_target_properties(${target_name} PROPERTIES + INSTALL_RPATH "$ORIGIN" + BUILD_WITH_INSTALL_RPATH ON + ) + endif() + + rexglue_apply_target_settings(${target_name}) +endfunction() diff --git a/cmake/rexglue_install.cmake b/cmake/rexglue_install.cmake new file mode 100644 index 0000000..e7d5135 --- /dev/null +++ b/cmake/rexglue_install.cmake @@ -0,0 +1,192 @@ +#========================================================== +# SDK Install/Export Rules +#========================================================== +set_target_properties(rexcore PROPERTIES EXPORT_NAME core) +set_target_properties(rexfilesystem PROPERTIES EXPORT_NAME filesystem) +set_target_properties(rexui PROPERTIES EXPORT_NAME ui) +set_target_properties(rexinput PROPERTIES EXPORT_NAME input) +set_target_properties(rexaudio PROPERTIES EXPORT_NAME audio) +set_target_properties(rexgraphics PROPERTIES EXPORT_NAME graphics) +set_target_properties(rexruntime PROPERTIES EXPORT_NAME runtime) +set_target_properties(rexcodegen PROPERTIES EXPORT_NAME codegen) + +set(REXGLUE_INSTALL_TARGETS + rexruntime + disruptorplus renderdoc simde tomlplusplus + aes128 mspack o1heap disasm xxhash + libavcodec libavutil + rexglue +) + +if(REXGLUE_USE_VULKAN) + list(APPEND REXGLUE_INSTALL_TARGETS + SPIRV glslang MachineIndependent GenericCodeGen OSDependent OGLCompiler # glslang + SPIRV-Tools-static + ) +endif() + +if(REXGLUE_USE_D3D12) + list(APPEND REXGLUE_INSTALL_TARGETS dxc-headers) +endif() + +if(REXGLUE_ENABLE_TRACY) + list(APPEND REXGLUE_INSTALL_TARGETS TracyClient) +endif() + +set(REXGLUE_INSTALL_FIDELITYFX_TARGETS) +if(TARGET amd_fidelityfx_vk) + list(APPEND REXGLUE_INSTALL_FIDELITYFX_TARGETS amd_fidelityfx_vk) +endif() + +if(TARGET amd_fidelityfx_dx12) + list(APPEND REXGLUE_INSTALL_FIDELITYFX_TARGETS amd_fidelityfx_dx12) +endif() + +install(TARGETS ${REXGLUE_INSTALL_TARGETS} + EXPORT rexglueTargets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) + +if(REXGLUE_INSTALL_FIDELITYFX_TARGETS) + install(TARGETS ${REXGLUE_INSTALL_FIDELITYFX_TARGETS} + EXPORT rexglueTargets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) +endif() + +# Install public headers +install(DIRECTORY include/rex + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) + +# Install generated version header +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/include/rex/version.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/rex +) + +# Install vendored header-only library headers +install(DIRECTORY thirdparty/disruptorplus/include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/disruptorplus +) +install(DIRECTORY thirdparty/renderdoc/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/renderdoc + FILES_MATCHING PATTERN "*.h" +) +install(DIRECTORY thirdparty/tomlplusplus/include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) +install(DIRECTORY thirdparty/simde/simde + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING PATTERN "*.h" +) +install(FILES + thirdparty/xxHash/xxhash.h + thirdparty/xxHash/xxh3.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) +install(FILES + thirdparty/o1heap/o1heap/o1heap.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) +install(FILES + thirdparty/imgui/imgui.h + thirdparty/imgui/imconfig.h + thirdparty/imgui/imgui_internal.h + thirdparty/imgui/imstb_rectpack.h + thirdparty/imgui/imstb_textedit.h + thirdparty/imgui/imstb_truetype.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) + +# Install SPIRV-Tools headers (only the public API, not opt/linker) +if(REXGLUE_USE_VULKAN) + install(FILES + thirdparty/spirv-tools/include/spirv-tools/libspirv.h + thirdparty/spirv-tools/include/spirv-tools/libspirv.hpp + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/spirv-tools + ) +endif() + +# Install platform entry point sources and ReXApp for SDK consumers +install(FILES + src/ui/windowed_app_main_win.cpp + src/ui/windowed_app_main_posix.cpp + src/ui/rex_app.cpp + DESTINATION ${CMAKE_INSTALL_DATADIR}/rexglue +) + +# Install DXC API headers (vendored, for D3D12 backend) +if(REXGLUE_USE_D3D12) + install(FILES + thirdparty/dxc/include/DxbcConverter.h + thirdparty/dxc/include/dxcapi.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dxc + ) +endif() + +# Generate and install package config files +configure_package_config_file( + cmake/rexglueConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/rexglueConfig.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/rexglue +) + +write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/rexglueConfigVersion.cmake + VERSION ${REXGLUE_NUMERIC_VERSION} + COMPATIBILITY SameMajorVersion +) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/rexglueConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/rexglueConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/rexglue +) + +install(FILES + ${CMAKE_SOURCE_DIR}/cmake/rexglue_helpers.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/rexglue +) + +# Export targets with rex:: namespace +install(EXPORT rexglueTargets + FILE rexglueTargets.cmake + NAMESPACE rex:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/rexglue +) + +# Register in the CMake User Package Registry after install. +# This makes find_package(rexglue) work with no REXSDK env var or CMAKE_PREFIX_PATH. +# Multiple SxS installs coexist. Each prefix gets a unique hash entry. +# +# Windows: HKCU\Software\Kitware\CMake\Packages\rexglue (REG_SZ, value name = MD5 hash) +# Unix: ~/.cmake/packages/rexglue/ (file containing prefix path) +install(CODE [[ + # Normalize path casing on Windows before hashing to avoid duplicate entries + if(CMAKE_HOST_WIN32) + string(TOLOWER "${CMAKE_INSTALL_PREFIX}" _reg_key) + else() + set(_reg_key "${CMAKE_INSTALL_PREFIX}") + endif() + string(MD5 _hash "${_reg_key}") + + if(CMAKE_HOST_WIN32) + # Windows CMake User Package Registry lives in HKCU (not the filesystem) + set(_reg_root "HKCU\\Software\\Kitware\\CMake\\Packages\\rexglue") + execute_process( + COMMAND reg add "${_reg_root}" /v "${_hash}" /t REG_SZ /d "${CMAKE_INSTALL_PREFIX}" /f + OUTPUT_QUIET ERROR_QUIET + ) + else() + set(_reg_dir "$ENV{HOME}/.cmake/packages/rexglue") + file(MAKE_DIRECTORY "${_reg_dir}") + file(WRITE "${_reg_dir}/${_hash}" "${CMAKE_INSTALL_PREFIX}") + endif() + message(STATUS "Registered rexglue in CMake user package registry") + message(STATUS " -> ${CMAKE_INSTALL_PREFIX}") +]]) diff --git a/docs/RELEASING.md b/docs/RELEASING.md new file mode 100644 index 0000000..eb09f25 --- /dev/null +++ b/docs/RELEASING.md @@ -0,0 +1,124 @@ +# Releasing ReXGlue SDK + +## Branches + +`main` always sits at the most recent stable tag. `development` is the working canary; all feature work merges here first. `release/X.Y.Z` is short-lived: branched from dev tip when a release is cut, merged into both dev and main when the release is published, then deleted. + +## Versioning + +The build version is computed automatically. Do not edit `CMakeLists.txt` to bump the version on a routine release. + +`CMakeLists.txt` carries only the API floor as `PROJECT VERSION MAJOR.MINOR.0`. The patch field there is a placeholder CMake requires; only major and minor mean anything. Edit the floor only when you are introducing a public API change. + +Version format follows [CMake's `CMAKE_VERSION`](https://cmake.org/cmake/help/latest/variable/CMAKE_VERSION.html) convention: `MAJOR.MINOR[.PATCH[.TWEAK]][-id]`. + +The full version is derived at configure time: + +- On a tagged commit: version is the tag verbatim (minus the leading `v`). Tags may be 2, 3, or 4 components (`v0.7`, `v0.7.5`, `v0.7.5.1`). Whatever you tag is what ships. +- On a `release/*` branch: version is `MAJOR...-rc.g`. +- On `development` or anywhere else: version is `MAJOR...-dev.g`. + +`` is `last-tag-patch + 1` when the floor minor matches the most recent tag's minor, or `0` when the floor is ahead. `` is the number of commits since that tag (the TWEAK slot). The `-id` trailer identifies the build channel (`dev` or `rc`) and the short commit SHA. + +Examples: + +| Scenario | Version | +| --- | --- | +| `git tag v0.7.5` pushed | `0.7.5` | +| `git tag v0.7.5.1` pushed (hotfix tweak) | `0.7.5.1` | +| `development`, 38 commits past `v0.7.4` | `0.7.5.38-dev.gb27f3f74` | +| `release/0.7.5`, 15 commits past `v0.7.4` | `0.7.5.15-rc.gdeadbee` | +| Floor bumped to `0.8`, 3 commits past `v0.7.5` | `0.8.0.3-dev.gdef5678` | + +A version with `-dev` or `-rc` is unstable. Only a version without an `-id` trailer is covered by the public API. + +## Release flow + +### Cutting the release + +Figure out the next release version. On a normal release it is `MAJOR..`. If the release introduces a public API change, bump the floor first (see "Bumping the floor" below) and the next release becomes `MAJOR..0`. + +Branch the release from dev tip and push it: + +``` +git fetch origin +git checkout -b release/X.Y.Z origin/development +git push -u origin release/X.Y.Z +``` + +Open a PR `release/X.Y.Z -> main`. + +### While the release is open + +Feature work keeps merging into `development` as normal. Review fixes for the open release land on `release/X.Y.Z` directly. Do not cherry-pick review fixes into dev; they flow back when the release is published. + +### Merging and tagging + +Merge the release branch into dev first, so review fixes flow back: + +``` +git checkout development +git pull +git merge --no-ff release/X.Y.Z -m "Merge release/X.Y.Z into development" +git push origin development +``` + +Then merge into main. Use a real merge commit; do not squash, do not rebase: + +``` +git checkout main +git pull +git merge --no-ff release/X.Y.Z -m "Release vX.Y.Z" +git push origin main +``` + +Tag the release branch tip (not `main` HEAD) and push. + +``` +git tag vX.Y.Z release/X.Y.Z +git push origin vX.Y.Z +``` + +The tag push triggers `build-win-amd64`, `build-linux-amd64`, and `build-linux-aarch64`, which publish a GitHub release with the three platform zips. + +Delete the release branch (after tagging): + +``` +git push origin --delete release/X.Y.Z +git branch -d release/X.Y.Z +``` + +## Hotfixes + +A hotfix follows the same flow as a normal release with two differences. The release branch starts from `main` (the last stable tag) instead of dev tip, so it carries the fix and nothing else. The version is the next patch off the most recent tag, same rule as a normal release. + +``` +git fetch origin +git checkout -b release/X.Y.Z origin/main +``` + +Apply the fix on the branch, open the PR into main, then merge into dev first and into main with a merge commit, exactly like a normal release. Tag and push. + +If a regular release branch is already open, close it without merging before cutting the hotfix; only one release branch may exist at a time. Re-cut the regular release from dev tip after the hotfix is released; its version will be the next patch off the hotfix tag. + +## Bumping the floor + +Only when the public API is changing. Single commit on `development`: + +1. Edit `CMakeLists.txt` line 6: change `PROJECT VERSION 0..0` to `PROJECT VERSION 0..0`. +2. Commit message: `chore: bump API floor to 0.`. +3. The next release branch is `release/0..0` and the tag is `v0..0`. + +## Nightly builds + +Scheduled workflow that builds dev tip when its SHA has advanced since the last nightly. Each run produces a prerelease tagged `YYYYMMDD-` and prunes older ones beyond `NIGHTLY_RETENTION`. + +## When something goes wrong + +CI fails on a tag push: do not delete the tag. Investigate, fix on `development`, cut the next patch release when ready. Do not retag. + +A bad release went out: cut a fix release. Do not delete the bad release. + +Conflicts merging `release/X.Y.Z` into `development`: resolve in favor of dev for feature changes, in favor of the release branch for release fixes. Do not cherry-pick. + +Two release branches accidentally open: close the older one without merging. Only one release branch at a time. diff --git a/docs/ppc/altivec_instructions.pdf b/docs/ppc/altivec_instructions.pdf new file mode 100644 index 0000000..f6da0ca Binary files /dev/null and b/docs/ppc/altivec_instructions.pdf differ diff --git a/docs/ppc/core_instructions.pdf b/docs/ppc/core_instructions.pdf new file mode 100644 index 0000000..2e978e8 Binary files /dev/null and b/docs/ppc/core_instructions.pdf differ diff --git a/docs/ppc/vmx128.txt b/docs/ppc/vmx128.txt new file mode 100644 index 0000000..e1bed1a --- /dev/null +++ b/docs/ppc/vmx128.txt @@ -0,0 +1,610 @@ + 2006/09/01 Revision 1.2 +----------------------------------------------------------------- + + + This is a description of the VMX128-type opcodes found on + the xbox360 processor. I figured this out by looking at + various disassmblies, so there might some errors and + missing instructions. Some instructions have unknown + semantics for me. + + See comments or corrections to sb#biallas.net + + +================================================================= +Conventions: + VD128, VS128: 5 lower bits of a VMX128 vector register + number + VDh: upper 2 bits of VD128 + (so register number is (VDh << 5 | VD128)) + + VA128: same as VD128 + A: bit 6 of VA128 + a: bit 5 of VA128 + (so register number is (A<<6 | a<<5 | VA128)) + + VB128: same as VD128 + VBh: same as VDh + + VC128: 3 bits of a VMX128 vector register number + (you can only use vr0-vr7 here) + + RA, RB: general purpose register number + + UIMM: unsigned immediate value + SIMM: signed immediate value + + PERMh: upper 3 bits of a permutation + PERMl: lower 5 bits of a permutation + + x, y, z: unknown immediate values + +================================================================= + lvewx128 Load Vector128 Element Word Indexed +|0 0 0 1 0 0| VD128 | RA | RB |0 0 0 1 0 0 0|VDh|1 1| + + lvewx128 vr(VD128), r(RA), r(RB) + + +================================================================= + lvlx128 Load Vector128 Left Indexed +|0 0 0 1 0 0| VD128 | RA | RB |1 0 0 0 0 0 0|VDh|1 1| + + lvlx128 vr(VD128), r(RA), r(RB) + + +================================================================= + lvrx128 Load Vector128 Right Indexed +|0 0 0 1 0 0| VD128 | RA | RB |1 0 0 0 1 0 0|VDh|1 1| + + lvrx128 vr(VD128), r(RA), r(RB) + + +================================================================= + lvlxl128 Load Vector128 Left Indexed LRU +|0 0 0 1 0 0| VD128 | RA | RB |1 1 0 0 0 0 0|VDh|1 1| + + lvlxl128 vr(VD128), r(RA), r(RB) + + +================================================================= + lvrxl128 Load Vector128 Right Indexed LRU +|0 0 0 1 0 0| VD128 | RA | RB |1 1 0 0 1 0 0|VDh|1 1| + + lvrxl128 vr(VD128), r(RA), r(RB) + + +================================================================= + lvsl128 Load Vector128 for Shift Left +|0 0 0 1 0 0| VD128 | RA | RB |0 0 0 0 0 0 0|VDh|1 1| + + lvsl128 vr(VD128), r(RA), r(RB) + + +================================================================= + lvsr128 Load Vector128 for Shift Right +|0 0 0 1 0 0| VD128 | RA | RB |0 0 0 0 1 0 0|VDh|1 1| + + lvsr128 vr(VD128), r(RA), r(RB) + + +================================================================= + lvx128 Load Vector128 Indexed +|0 0 0 1 0 0| VD128 | RA | RB |0 0 0 1 1 0 0|VDh|1 1| + + lvx128 vr(VD128), r(RA), r(RB) + + +================================================================= + lvxl128 Load Vector128 Indexed LRU +|0 0 0 1 0 0| VD128 | RA | RB |0 1 0 1 1 0 0|VDh|1 1| + + lvxl128 vr(VD128), r(RA), r(RB) + + +================================================================= + stewx128 Store Vector128 Element Word Indexed +|0 0 0 1 0 0| VS128 | RA | RB |0 1 1 0 0 0 0|VDh|1 1| + + stvewx128 vr(VS128), r(RA), r(RB) + + +================================================================= + stvlx128 Store Vector128 Left Indexed +|0 0 0 1 0 0| VS128 | RA | RB |1 0 1 0 0 0 0|VDh|1 1| + + stvlx128 vr(VS128), r(RA), r(RB) + + +================================================================= + stvlxl128 Store Vector128 Left Indexed LRU +|0 0 0 1 0 0| VS128 | RA | RB |1 1 1 0 0 0 0|VDh|1 1| + + lvlxl128 vr(VS128), r(RA), r(RB) + + +================================================================= + stvrx128 Store Vector128 Right Indexed +|0 0 0 1 0 0| VS128 | RA | RB |1 0 1 0 1 0 0|VDh|1 1| + + stvrx128 vr(VS128), r(RA), r(RB) + + +================================================================= + stvrxl128 Store Vector128 Right Indexed LRU +|0 0 0 1 0 0| VS128 | RA | RB |1 1 1 0 1 0 0|VDh|1 1| + + stvrxl128 vr(VS128), r(RA), r(RB) + + +================================================================= + stvx128 Store Vector128 Indexed +|0 0 0 1 0 0| VS128 | RA | RB |0 0 1 1 1 0 0|VDh|1 1| + + stvx128 vr(VS128), r(RA), r(RB) + + +================================================================= + stvxl128 Store Vector128 Indexed LRU +|0 0 0 1 0 0| VS128 | RA | RB |0 1 1 1 1 0 0|VDh|1 1| + + stvxl128 vr(VS128), r(RA), r(RB) + + +================================================================= + vaddfp128 Vector128 Add Floating Point +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|0 0 0 0|a|1|VDh|VBh| + + vaddfp128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vand128 Vector128 Logical AND +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 0 0 0|a|1|VDh|VBh| + + vand128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vandc128 Vector128 Logical AND + with Complement +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 0 1 0|a|1|VDh|VBh| + + vandc128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vcfpsxws128 Vector128 Convert From Floating-Point to + Signed Fixed-Point Word Saturate +|0 0 0 1 1 0| VD128 | SIMM | VB128 |0 1 0 0 0 1 1|VDh|VBh| + + vcfpsxws128 vr(VD128), vr(VB128), SIMM + + +================================================================= + vcfpuxws128 Vector128 Convert From Floating-Point to + Unsigned Fixed-Point Word Saturate +|0 0 0 1 1 0| VD128 | UIMM | VB128 |0 1 0 0 1 1 1|VDh|VBh| + + vcfpuxws128 vr(VD128), vr(VB128), UIMM + + +================================================================= + vcmpbfp128 Vector128 Compare Bounds + Floating Point +|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|0 1 1|R|a|0|VDh|VBh| + + vcmpbfp128 vr(VD128), vr(VA128), vr(VB128) (R == 0) + vcmpbfp128. vr(VD128), vr(VA128), vr(VB128) (R == 1) + + +================================================================= + vcmpeqfp128 Vector128 Compare Equal-to + Floating Point +|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|0 0 0|R|a|0|VDh|VBh| + + vcmpeqfp128 vr(VD128), vr(VA128), vr(VB128) (R == 0) + vcmpeqfp128. vr(VD128), vr(VA128), vr(VB128) (R == 1) + + +================================================================= + vcmpequw128 Vector128 Compare Equal-to + Unsigned Word +|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|1 0 0|R|a|0|VDh|VBh| + + vcmpequw128 vr(VD128), vr(VA128), vr(VB128) (R == 0) + vcmpequw128. vr(VD128), vr(VA128), vr(VB128) (R == 1) + + +================================================================= + vcmpgefp128 Vector128 Compare Greater-Than- + or-Equal-to Floating Point +|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|0 0 1|R|a|0|VDh|VBh| + + vcmpgefp128 vr(VD128), vr(VA128), vr(VB128) (R == 0) + vcmpgefp128. vr(VD128), vr(VA128), vr(VB128) (R == 1) + + +================================================================= + vcmpgtfp128 Vector128 Compare Greater-Than + Floating-Point +|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|0 1 0|R|a|0|VDh|VBh| + + vcmpgtfp128 vr(VD128), vr(VA128), vr(VB128) (R == 0) + vcmpgtfp128. vr(VD128), vr(VA128), vr(VB128) (R == 1) + + +================================================================= + vcsxwfp128 Vector128 Convert From Signed Fixed-Point + Word to Floating-Point +|0 0 0 1 1 0| VD128 | UIMM | VB128 |0 1 0 1 0 1 1|VDh|VBh| + + vcsxwfp128 vr(VD128), vr(VB128), SIMM + + +================================================================= + vcuxwfp128 Vector128 Convert From Unsigned Fixed-Point + Word to Floating-Point +|0 0 0 1 1 0| VD128 | UIMM | VB128 |0 1 0 1 1 1 1|VDh|VBh| + + vcuxwfp128 vr(VD128), vr(VB128), UIMM + + +================================================================= + vexptefp128 Vector128 2 Raised to the Exponent + Estimate Floating Point +|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |1 1 0 1 0 1 1|VDh|VBh| + + vexptefp128 vr(VD128), vr(VB128) + + +================================================================= + vlogefp128 Vector128 Log2 Estimate + Floating Point +|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |1 1 0 1 1 1 1|VDh|VBh| + + vlogefp128 vr(VD128), vr(VB128) + + +================================================================= + vmaddcfp128 Vector128 Multiply Add + Floating Point +|0 0 0 1 0 1| VDS128 | VA128 | VB128 |A|0 1 0 0|a|1|VDh|VBh| + + vmaddcfp128 vr(VDS128), vr(VA128), vr(VSD128), vr(VB128) + + +================================================================= + vmaddfp128 Vector128 Multiply Add + Floating Point +|0 0 0 1 0 1| VDS128 | VA128 | VB128 |A|0 0 1 1|a|1|VDh|VBh| + + vmaddfp128 vr(VDS128), vr(VA128), vr(VB128), vr(VDS128) + + +================================================================= + vmaxfp128 Vector128 Maximum + Floating Point +|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|1 0 1 0|a|0|VDh|VBh| + + vmaxfp128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vminfp128 Vector128 Minimum + Floating Point +|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|1 0 1 1|a|0|VDh|VBh| + + vminfp128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vmrghw128 Vector128 Merge High Word +|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|1 1 0 0|a|0|VDh|VBh| + + vmrghw128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vmrglw128 Vector128 Merge Low Word +|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|1 1 0 1|a|0|VDh|VBh| + + vmrglw128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vmsum3fp128 Vector128 Multiply Sum 3-way + Floating Point +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|0 1 1 0|a|1|VDh|VBh| + + vmsub3fp128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vmsum4fp128 Vector128 Multiply Sum 4-way + Floating-Point +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|0 1 1 1|a|1|VDh|VBh| + + vmsub4fp128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vmulfp128 Vector128 Multiply + Floating-Point +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|0 0 1 0|a|1|VDh|VBh| + + vmulfp128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vnmsubfp128 Vector128 Negative Multiply-Subtract + Floating Point +|0 0 0 1 0 1| VDS128 | VA128 | VB128 |A|0 1 0 1|a|1|VDh|VBh| + + vnmsubfp128 vr(VDS128), vr(VA128), vr(VB128), vr(VDS128) + + +================================================================= + vnor128 Vector128 Logical NOR +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 0 1 0|a|1|VDh|VBh| + + vnor128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vor128 Vector128 Logical OR +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 0 1 1|a|1|VDh|VBh| + + vor128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vperm128 Vector128 Permutation +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|0| VC |a|0|VDh|VBh| + + vperm128 vr(VD128), vr(VA128), vr(VB128), vr(VC) + + +================================================================= + vpermwi128 Vector128 Permutate Word Immediate +|0 0 0 1 1 0| VD128 | PERMl | VB128 |0|1|PERMh|0|1|VDh|VBh| + + vpermwi128 vr(VD128), vr(VB128), (PERMh << 5 | PERMl) + + +================================================================= + vpkd3d128 Vector128 Pack D3Dtype, Rotate Left + Immediate and Mask Insert +|0 0 0 1 1 0| VD128 | x | y | VB128 |1 1 0| z |0 1|VDh|VBh| + + vpkd3d128 vr(VD128), vr(VB128), x, y, z + + +================================================================= + vpkshss128 Vector128 Pack Signed Half Word + Signed Saturate +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 0 0 0|a|0|VDh|VBh| + + vpkshss128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vpkshus128 Vector128 Pack Signed Half Word + Unsigned Saturate +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 0 0 1|a|0|VDh|VBh| + + vpkshus128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vpkswss128 Vector128 Pack Signed Word + Signed Saturate +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 0 1 0|a|0|VDh|VBh| + + vpkswss128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vpkswus128 Vector128 Pack Signed Word + Unsigned Saturate +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 0 1 1|a|0|VDh|VBh| + + vpkswus128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vpkuhum128 Vector128 Pack Unsigned Half Word + Unsigned Modulo +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 1 0 0|a|0|VDh|VBh| + + vpkuhum128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vpkuhus128 Vector128 Pack Unsigned Half Word + Unsigned Saturate +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 1 0 1|a|0|VDh|VBh| + + vpkuhus128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vpkuwum128 Vector128 Pack Unsigned Word + Unsigned Modulo +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 1 1 0|a|0|VDh|VBh| + + vpkuwum128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vpkuwus128 Vector128 Pack Unsigned Word + Unsigned Saturate +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 1 1 1|a|0|VDh|VBh| + + vpkuwus128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vrefp128 Vector128 Reciprocal Estimate + Floating Point +|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |1 1 0 0 0 1 1|VDh|VBh| + + vrefp128 vr(VD128), vr(VB128) + + +================================================================= + vrfim128 Vector128 Round to Floating-Point + Integer toward -oo +|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |0 1 1 0 0 1 1|VDh|VBh| + + vrfim128 vr(VD128), vr(VB128) + + +================================================================= + vrfin128 Vector128 Round to Floating-Point + Integer toward Nearest +|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |0 1 1 0 1 1 1|VDh|VBh| + + vrfin128 vr(VD128), vr(VB128) + + +================================================================= + vrfip128 Vector128 Round to Floating-Point + Integer toward +oo +|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |0 1 1 1 0 1 1|VDh|VBh| + + vrfip128 vr(VD128), vr(VB128) + + +================================================================= + vrfiz128 Vector128 Round to Floating-Point + Integer toward Zero +|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |0 1 1 1 1 1 1|VDh|VBh| + + vrfiz128 vr(VD128), vr(VB128) + + +================================================================= + vrlimi128 Vector128 Rotate Left Immediate + and Mask Insert +|0 0 0 1 1 0| VD128 | UIMM | VB128 |1 1 1| z |0 1|VDh|VBh| + + vrlimi128 vr(VD128), vr(VB128), UIMM, z + + +================================================================= + vrlw128 Vector128 Rotate Left Word +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|0 0 0 1|a|1|VDh|VBh| + + vrlw128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vrsqrtefp128 Vector128 Reciprocal Square Root + Estimate Floating Point +|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |1 1 0 0 1 1 1|VDh|VBh| + + vrsqrtefp128 vr(VD128), vr(VB128) + + +================================================================= + vsel128 Vector128 Select +|0 0 0 1 0 1| VDS128 | VA128 | VB128 |A|1 1 0 1|a|1|VDh|VBh| + + vsel128 vr(VDS128), vr(VA128), vr(VB128), vr(VDS128) + + +================================================================= + vsldoi128 Vector128 Shift Left Double + by Octet Immediate +|0 0 0 1 0 0| VD128 | VA128 | VB128 |A| SHB |a|1|VDh|VBh| + + vsldoi128 vr(VD128), vr(VA128), vr(VB128), SHB + + +================================================================= + vslo128 Vector128 Shift Left Octet +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 1 1 0|a|1|VDh|VBh| + + vslo128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vslw128 Vector128 Shift Left Word +|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|0 0 1 1|a|1|VDh|VBh| + + vslw128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vspltisw128 Vector128 Splat Immediate + Signed Word +|0 0 0 1 1 0| VD128 | SIMM | VB128 |1 1 1 0 1 1 1|VDh|VBh| + + vspltisw128 vr(VD128), vr(VB128), SIMM + + +================================================================= + vspltw128 Vector128 Splat Word +|0 0 0 1 1 0| VD128 | UIMM | VB128 |1 1 1 0 0 1 1|VDh|VBh| + + vspltw128 vr(VD128), vr(VB128), UIMM + + +================================================================= + vsraw128 Vector128 Shift Right + Arithmetic Word +|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|0 1 0 1|a|1|VDh|VBh| + + vsraw128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vsro128 Vector128 Shift Right Octet +|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|1 1 1 1|a|1|VDh|VBh| + + vsro128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vsrw128 Vector128 Shift Right Word +|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|0 1 1 1|a|1|VDh|VBh| + + vsrw128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vsubfp128 Vector128 Subtract Floating Point +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|0 0 0 1|a|1|VDh|VBh| + + vsubfp128 vr(VD128), vr(VA128), vr(VB128) + + +================================================================= + vupkd3d128 Vector128 Unpack D3Dtype +|0 0 0 1 1 0| VD128 | UIMM | VB128 |1 1 1 1 1 1 1|VDh|VBh| + + vupkd3d128 vr(VD128), vr(VB128), UIMM + + +================================================================= + vupkhsb128 Vector128 Unpack + High Signed Byte +|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |0 1 1 1 0 0 0|VDh|VBh| + + vupkhsb128 vr(VD128), vr(VB128) + + +================================================================= + vupklsb128 Vector128 Unpack + Low Signed Byte +|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |0 1 1 1 1 0 0|VDh|VBh| + + vupkhsb128 vr(VD128), vr(VB128) + + +================================================================= + vxor128 Vector128 Logical XOR +|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 1 0 0|a|1|VDh|VBh| + + vxor128 vr(VD128), vr(VA128), vr(VB128) diff --git a/include/rex/assert.h b/include/rex/assert.h new file mode 100644 index 0000000..526c9eb --- /dev/null +++ b/include/rex/assert.h @@ -0,0 +1,130 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include +#include +#include +#include + +#include + +namespace rex { + +#define static_assert_size(type, size) \ + static_assert(sizeof(type) == size, "bad definition for " #type ": must be " #size " bytes") + +#ifdef NDEBUG +// References expr in an unevaluated short-circuit so -Wunused doesn't fire. +#define rex_assert(expr) ((void)(false && (expr))) +#else +#define rex_assert(expr) assert(expr) +#endif + +#define __REX_EXPAND(x) x +#define __REX_ARGC(...) \ + __REX_EXPAND(__REX_ARGC_IMPL(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) +#define __REX_ARGC_IMPL(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, N, ...) N +#define __REX_MACRO_DISPATCH(func, ...) __REX_MACRO_DISPATCH_(func, __REX_ARGC(__VA_ARGS__)) +#define __REX_MACRO_DISPATCH_(func, nargs) __REX_MACRO_DISPATCH__(func, nargs) +#define __REX_MACRO_DISPATCH__(func, nargs) func##nargs + +/// Assert failure handler that logs the message before aborting +/// @param file Source file (__FILE__) +/// @param line Line number (__LINE__) +/// @param expr Expression that failed (stringified) +/// @param message User-provided message explaining the failure +[[noreturn]] inline void rex_assert_fail(const char* file, int line, const char* expr, + const char* message) { + fprintf(stderr, "Assertion failed: %s\n Expression: %s\n Location: %s:%d\n", message, expr, + file, line); + fflush(stderr); + std::abort(); +} + +#define assert_always(...) rex_assert(false) + +#define assert_true(...) __REX_MACRO_DISPATCH(assert_true, __VA_ARGS__)(__VA_ARGS__) +#define assert_true1(expr) rex_assert(expr) +#define assert_true2(expr, message) \ + do { \ + if (!(expr)) { \ + rex_assert_fail(__FILE__, __LINE__, #expr, message); \ + } \ + } while (0) + +#define assert_false(...) __REX_MACRO_DISPATCH(assert_false, __VA_ARGS__)(__VA_ARGS__) +#define assert_false1(expr) rex_assert(!(expr)) +#define assert_false2(expr, message) \ + do { \ + if (!!(expr)) { \ + rex_assert_fail(__FILE__, __LINE__, "!(" #expr ")", message); \ + } \ + } while (0) + +#define assert_zero(...) __REX_MACRO_DISPATCH(assert_zero, __VA_ARGS__)(__VA_ARGS__) +#define assert_zero1(expr) rex_assert((expr) == 0) +#define assert_zero2(expr, message) \ + do { \ + if ((expr) != 0) { \ + rex_assert_fail(__FILE__, __LINE__, "(" #expr ") == 0", message); \ + } \ + } while (0) + +#define assert_not_zero(...) __REX_MACRO_DISPATCH(assert_not_zero, __VA_ARGS__)(__VA_ARGS__) +#define assert_not_zero1(expr) rex_assert((expr) != 0) +#define assert_not_zero2(expr, message) \ + do { \ + if ((expr) == 0) { \ + rex_assert_fail(__FILE__, __LINE__, "(" #expr ") != 0", message); \ + } \ + } while (0) + +#define assert_null(...) __REX_MACRO_DISPATCH(assert_null, __VA_ARGS__)(__VA_ARGS__) +#define assert_null1(expr) rex_assert((expr) == nullptr) +#define assert_null2(expr, message) \ + do { \ + if ((expr) != nullptr) { \ + rex_assert_fail(__FILE__, __LINE__, "(" #expr ") == nullptr", message); \ + } \ + } while (0) + +#define assert_not_null(...) __REX_MACRO_DISPATCH(assert_not_null, __VA_ARGS__)(__VA_ARGS__) +#define assert_not_null1(expr) rex_assert((expr) != nullptr) +#define assert_not_null2(expr, message) \ + do { \ + if ((expr) == nullptr) { \ + rex_assert_fail(__FILE__, __LINE__, "(" #expr ") != nullptr", message); \ + } \ + } while (0) + +#define assert_unhandled_case(variable) assert_always("unhandled switch(" #variable ") case") + +/// Marks code as unreachable. Invokes undefined behavior if reached. +/// Use in switch default cases and after exhaustive if-else chains. +#define rex_unreachable() std::unreachable() + +// Fatal error that terminates the program with a message +[[noreturn]] inline void FatalError(const char* message) { + // Print to stderr and terminate + fprintf(stderr, "FATAL ERROR: %s\n", message); + fflush(stderr); + std::abort(); +} + +[[noreturn]] inline void FatalError(const std::string& message) { + FatalError(message.c_str()); +} + +} // namespace rex diff --git a/include/rex/audio/audio_driver.h b/include/rex/audio/audio_driver.h new file mode 100644 index 0000000..37ccbf2 --- /dev/null +++ b/include/rex/audio/audio_driver.h @@ -0,0 +1,34 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +namespace rex::audio { + +class AudioDriver { + public: + explicit AudioDriver(memory::Memory* memory); + virtual ~AudioDriver(); + + virtual void SubmitFrame(uint32_t samples_ptr) = 0; + + protected: + inline uint8_t* TranslatePhysical(uint32_t guest_address) const { + return memory_->TranslatePhysical(guest_address); + } + + memory::Memory* memory_ = nullptr; +}; + +} // namespace rex::audio diff --git a/include/rex/audio/audio_system.h b/include/rex/audio/audio_system.h new file mode 100644 index 0000000..33fd32c --- /dev/null +++ b/include/rex/audio/audio_system.h @@ -0,0 +1,101 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace rex::stream { +class ByteStream; +} // namespace rex::stream + +namespace rex::audio { + +constexpr memory::fourcc_t kAudioSaveSignature = memory::make_fourcc("XAUD"); + +class AudioDriver; +class XmaDecoder; + +class AudioSystem : public system::IAudioSystem { + public: + virtual ~AudioSystem(); + + memory::Memory* memory() const { return memory_; } + runtime::FunctionDispatcher* function_dispatcher() const { return function_dispatcher_; } + XmaDecoder* xma_decoder() const { return xma_decoder_.get(); } + + virtual X_STATUS Setup(system::KernelState* kernel_state); + virtual void Shutdown(); + + X_STATUS RegisterClient(uint32_t callback, uint32_t callback_arg, size_t* out_index); + void UnregisterClient(size_t index); + void SubmitFrame(size_t index, uint32_t samples_ptr); + + bool Save(stream::ByteStream* stream); + bool Restore(stream::ByteStream* stream); + + bool is_paused() const { return paused_; } + void Pause(); + void Resume(); + + protected: + explicit AudioSystem(runtime::FunctionDispatcher* function_dispatcher); + + virtual void Initialize(); + + void WorkerThreadMain(); + + virtual X_STATUS CreateDriver(size_t index, rex::thread::Semaphore* semaphore, + AudioDriver** out_driver) = 0; + virtual void DestroyDriver(AudioDriver* driver) = 0; + + static constexpr size_t kMaximumQueuedFrames = 64; + + memory::Memory* memory_ = nullptr; + runtime::FunctionDispatcher* function_dispatcher_ = nullptr; + std::unique_ptr xma_decoder_; + uint32_t queued_frames_; + + std::atomic worker_running_ = {false}; + system::object_ref worker_thread_; + + rex::thread::global_critical_region global_critical_region_; + static const size_t kMaximumClientCount = 8; + struct { + AudioDriver* driver; + uint32_t callback; + uint32_t callback_arg; + uint32_t wrapped_callback_arg; + bool in_use; + } clients_[kMaximumClientCount]; + + int FindFreeClient(); + + std::unique_ptr client_semaphores_[kMaximumClientCount]; + // Event is always there in case we have no clients. + std::unique_ptr shutdown_event_; + rex::thread::WaitHandle* wait_handles_[kMaximumClientCount + 1]; + + bool paused_ = false; + rex::thread::Fence pause_fence_; + std::unique_ptr resume_event_; +}; + +} // namespace rex::audio diff --git a/include/rex/audio/conversion.h b/include/rex/audio/conversion.h new file mode 100644 index 0000000..a9fa7bd --- /dev/null +++ b/include/rex/audio/conversion.h @@ -0,0 +1,103 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include +#include + +namespace rex::audio::conversion { + +#if REX_ARCH_AMD64 +inline void sequential_6_BE_to_interleaved_6_LE(float* output, const float* input, + size_t ch_sample_count) { + const uint32_t* in = reinterpret_cast(input); + uint32_t* out = reinterpret_cast(output); + const __m128i byte_swap_shuffle = + _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3); + for (size_t sample = 0; sample < ch_sample_count; sample++) { + __m128i sample0 = + _mm_set_epi32(in[3 * ch_sample_count + sample], in[2 * ch_sample_count + sample], + in[1 * ch_sample_count + sample], in[0 * ch_sample_count + sample]); + uint32_t sample1 = in[4 * ch_sample_count + sample]; + uint32_t sample2 = in[5 * ch_sample_count + sample]; + sample0 = _mm_shuffle_epi8(sample0, byte_swap_shuffle); + _mm_storeu_si128(reinterpret_cast<__m128i*>(&out[sample * 6]), sample0); + sample1 = rex::byte_swap(sample1); + out[sample * 6 + 4] = sample1; + sample2 = rex::byte_swap(sample2); + out[sample * 6 + 5] = sample2; + } +} + +inline void sequential_6_BE_to_interleaved_2_LE(float* output, const float* input, + size_t ch_sample_count) { + assert_true(ch_sample_count % 4 == 0); + + const __m128i byte_swap_shuffle = + _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3); + const __m128 half = _mm_set1_ps(0.5f); + const __m128 two_fifths = _mm_set1_ps(1.0f / 2.5f); + + // put center on left and right, discard low frequency + for (size_t sample = 0; sample < ch_sample_count; sample += 4) { + // load 4 samples from 6 channels each + __m128 fl = _mm_loadu_ps(&input[0 * ch_sample_count + sample]); + __m128 fr = _mm_loadu_ps(&input[1 * ch_sample_count + sample]); + __m128 fc = _mm_loadu_ps(&input[2 * ch_sample_count + sample]); + __m128 bl = _mm_loadu_ps(&input[4 * ch_sample_count + sample]); + __m128 br = _mm_loadu_ps(&input[5 * ch_sample_count + sample]); + // byte swap + fl = _mm_castsi128_ps(_mm_shuffle_epi8(_mm_castps_si128(fl), byte_swap_shuffle)); + fr = _mm_castsi128_ps(_mm_shuffle_epi8(_mm_castps_si128(fr), byte_swap_shuffle)); + fc = _mm_castsi128_ps(_mm_shuffle_epi8(_mm_castps_si128(fc), byte_swap_shuffle)); + bl = _mm_castsi128_ps(_mm_shuffle_epi8(_mm_castps_si128(bl), byte_swap_shuffle)); + br = _mm_castsi128_ps(_mm_shuffle_epi8(_mm_castps_si128(br), byte_swap_shuffle)); + + __m128 center_halved = _mm_mul_ps(fc, half); + __m128 left = _mm_add_ps(_mm_add_ps(fl, bl), center_halved); + __m128 right = _mm_add_ps(_mm_add_ps(fr, br), center_halved); + left = _mm_mul_ps(left, two_fifths); + right = _mm_mul_ps(right, two_fifths); + _mm_storeu_ps(&output[sample * 2], _mm_unpacklo_ps(left, right)); + _mm_storeu_ps(&output[(sample + 2) * 2], _mm_unpackhi_ps(left, right)); + } +} +#else +inline void sequential_6_BE_to_interleaved_6_LE(float* output, const float* input, + size_t ch_sample_count) { + for (size_t sample = 0; sample < ch_sample_count; sample++) { + for (size_t channel = 0; channel < 6; channel++) { + output[sample * 6 + channel] = rex::byte_swap(input[channel * ch_sample_count + sample]); + } + } +} +inline void sequential_6_BE_to_interleaved_2_LE(float* output, const float* input, + size_t ch_sample_count) { + // Default 5.1 channel mapping is fl, fr, fc, lf, bl, br + // https://docs.microsoft.com/en-us/windows/win32/xaudio2/xaudio2-default-channel-mapping + for (size_t sample = 0; sample < ch_sample_count; sample++) { + // put center on left and right, discard low frequency + float fl = rex::byte_swap(input[0 * ch_sample_count + sample]); + float fr = rex::byte_swap(input[1 * ch_sample_count + sample]); + float fc = rex::byte_swap(input[2 * ch_sample_count + sample]); + float br = rex::byte_swap(input[4 * ch_sample_count + sample]); + float bl = rex::byte_swap(input[5 * ch_sample_count + sample]); + float center_halved = fc * 0.5f; + output[sample * 2] = (fl + bl + center_halved) * (1.0f / 2.5f); + output[sample * 2 + 1] = (fr + br + center_halved) * (1.0f / 2.5f); + } +} +#endif + +} // namespace rex::audio::conversion diff --git a/include/rex/audio/flags.h b/include/rex/audio/flags.h new file mode 100644 index 0000000..c2f70ba --- /dev/null +++ b/include/rex/audio/flags.h @@ -0,0 +1,17 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +REXCVAR_DECLARE(bool, audio_mute); +REXCVAR_DECLARE(bool, ffmpeg_verbose); diff --git a/include/rex/audio/nop/nop_audio_system.h b/include/rex/audio/nop/nop_audio_system.h new file mode 100644 index 0000000..e2a1fc2 --- /dev/null +++ b/include/rex/audio/nop/nop_audio_system.h @@ -0,0 +1,32 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +namespace rex::audio::nop { + +class NopAudioSystem : public AudioSystem { + public: + explicit NopAudioSystem(runtime::FunctionDispatcher* function_dispatcher); + ~NopAudioSystem() override; + + static bool IsAvailable() { return true; } + + static std::unique_ptr Create(runtime::FunctionDispatcher* function_dispatcher); + + X_STATUS CreateDriver(size_t index, rex::thread::Semaphore* semaphore, + AudioDriver** out_driver) override; + void DestroyDriver(AudioDriver* driver) override; +}; + +} // namespace rex::audio::nop diff --git a/include/rex/audio/sdl/sdl_audio_driver.h b/include/rex/audio/sdl/sdl_audio_driver.h new file mode 100644 index 0000000..f8949ca --- /dev/null +++ b/include/rex/audio/sdl/sdl_audio_driver.h @@ -0,0 +1,54 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include + +#include +#include + +#include + +namespace rex::audio::sdl { + +class SDLAudioDriver : public AudioDriver { + public: + SDLAudioDriver(memory::Memory* memory, rex::thread::Semaphore* semaphore); + ~SDLAudioDriver() override; + + bool Initialize(); + void SubmitFrame(uint32_t frame_ptr) override; + void Shutdown(); + + protected: + static void SDLCallback(void* userdata, SDL_AudioStream* stream, int additional_amount, + int total_amount); + + rex::thread::Semaphore* semaphore_ = nullptr; + + SDL_AudioStream* sdl_stream_ = nullptr; + bool sdl_initialized_ = false; + uint8_t sdl_device_channels_ = 0; + + static const uint32_t frame_frequency_ = 48000; + static const uint32_t frame_channels_ = 6; + static const uint32_t channel_samples_ = 256; + static const uint32_t frame_samples_ = frame_channels_ * channel_samples_; + static const uint32_t frame_size_ = sizeof(float) * frame_samples_; + std::queue frames_queued_ = {}; + std::stack frames_unused_ = {}; + std::mutex frames_mutex_ = {}; +}; + +} // namespace rex::audio::sdl diff --git a/include/rex/audio/sdl/sdl_audio_system.h b/include/rex/audio/sdl/sdl_audio_system.h new file mode 100644 index 0000000..471149c --- /dev/null +++ b/include/rex/audio/sdl/sdl_audio_system.h @@ -0,0 +1,35 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +namespace rex::audio::sdl { + +class SDLAudioSystem : public AudioSystem { + public: + explicit SDLAudioSystem(runtime::FunctionDispatcher* function_dispatcher); + ~SDLAudioSystem() override; + + static bool IsAvailable() { return true; } + + static std::unique_ptr Create(runtime::FunctionDispatcher* function_dispatcher); + + X_STATUS CreateDriver(size_t index, rex::thread::Semaphore* semaphore, + AudioDriver** out_driver) override; + void DestroyDriver(AudioDriver* driver) override; + + protected: + void Initialize() override; +}; + +} // namespace rex::audio::sdl diff --git a/include/rex/audio/xma/context.h b/include/rex/audio/xma/context.h new file mode 100644 index 0000000..5298d1e --- /dev/null +++ b/include/rex/audio/xma/context.h @@ -0,0 +1,285 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include + +#include +#include +#include + +// XMA audio format: +// From research, XMA appears to be based on WMA Pro with +// a few (very slight) modifications. +// XMA2 is fully backwards-compatible with XMA1. + +// Helpful resources: +// https://github.com/koolkdev/libertyv/blob/master/libav_wrapper/xma2dec.c +// https://hcs64.com/mboard/forum.php?showthread=14818 +// https://github.com/hrydgard/minidx9/blob/master/Include/xma2defs.h + +// Forward declarations +struct AVCodec; +struct AVCodecParserContext; +struct AVCodecContext; +struct AVFrame; +struct AVPacket; + +namespace rex::audio { + +// This is stored in guest space in big-endian order. +// We load and swap the whole thing to splat here so that we can +// use bitfields. +// This could be important: +// https://www.fmod.org/questions/question/forum-15859 +// Appears to be dumped in order (for the most part) + +struct XMA_CONTEXT_DATA { + // DWORD 0 + uint32_t input_buffer_0_packet_count : 12; // XMASetInputBuffer0, number of + // 2KB packets. Max 4095 packets. + // These packets form a block. + uint32_t loop_count : 8; // +12bit, XMASetLoopData NumLoops + uint32_t input_buffer_0_valid : 1; // +20bit, XMAIsInputBuffer0Valid + uint32_t input_buffer_1_valid : 1; // +21bit, XMAIsInputBuffer1Valid + uint32_t output_buffer_block_count : 5; // +22bit SizeWrite 256byte blocks + uint32_t output_buffer_write_offset : 5; // +27bit + // XMAGetOutputBufferWriteOffset + // AKA OffsetWrite + + // DWORD 1 + uint32_t input_buffer_1_packet_count : 12; // XMASetInputBuffer1, number of + // 2KB packets. Max 4095 packets. + // These packets form a block. + uint32_t loop_subframe_start : 2; // +12bit, XMASetLoopData + uint32_t loop_subframe_end : 3; // +14bit, XMASetLoopData + uint32_t loop_subframe_skip : 3; // +17bit, XMASetLoopData might be + // subframe_decode_count + uint32_t subframe_decode_count : 4; // +20bit + uint32_t output_buffer_padding : 3; // +24bit, extra output buffer blocks + // reserved per decoded frame + uint32_t sample_rate : 2; // +27bit enum of sample rates + uint32_t is_stereo : 1; // +29bit + uint32_t unk_dword_1_c : 1; // +30bit + uint32_t output_buffer_valid : 1; // +31bit, XMAIsOutputBufferValid + + // DWORD 2 + uint32_t input_buffer_read_offset : 26; // XMAGetInputBufferReadOffset + uint32_t error_status : 5; // ErrorStatus + uint32_t error_set : 1; // ErrorSet + + // DWORD 3 + uint32_t loop_start : 26; // XMASetLoopData LoopStartOffset + // frame offset in bits + uint32_t parser_error_status : 5; // ParserErrorStatus + uint32_t parser_error_set : 1; // ParserErrorSet + + // DWORD 4 + uint32_t loop_end : 26; // XMASetLoopData LoopEndOffset + // frame offset in bits + uint32_t packet_metadata : 5; // XMAGetPacketMetadata + uint32_t current_buffer : 1; // ? + + // DWORD 5 + uint32_t input_buffer_0_ptr; // physical address + // DWORD 6 + uint32_t input_buffer_1_ptr; // physical address + // DWORD 7 + uint32_t output_buffer_ptr; // physical address + // DWORD 8 + uint32_t work_buffer_ptr; // PtrOverlapAdd(?) + + // DWORD 9 + // +0bit, XMAGetOutputBufferReadOffset AKA WriteBufferOffsetRead + uint32_t output_buffer_read_offset : 5; + uint32_t : 25; + uint32_t stop_when_done : 1; // +30bit + uint32_t interrupt_when_done : 1; // +31bit + + // DWORD 10-15 + uint32_t unk_dwords_10_15[6]; // reserved? + + explicit XMA_CONTEXT_DATA(const void* ptr) { + memory::copy_and_swap(reinterpret_cast(this), reinterpret_cast(ptr), + sizeof(XMA_CONTEXT_DATA) / 4); + } + + void Store(void* ptr) { + memory::copy_and_swap(reinterpret_cast(ptr), reinterpret_cast(this), + sizeof(XMA_CONTEXT_DATA) / 4); + } + + bool IsInputBufferValid(uint8_t buffer_index) const { + return buffer_index == 0 ? input_buffer_0_valid : input_buffer_1_valid; + } + + bool IsCurrentInputBufferValid() const { return IsInputBufferValid(current_buffer); } + + bool IsAnyInputBufferValid() const { return input_buffer_0_valid || input_buffer_1_valid; } + + uint32_t GetInputBufferAddress(uint8_t buffer_index) const { + return buffer_index == 0 ? input_buffer_0_ptr : input_buffer_1_ptr; + } + + uint32_t GetCurrentInputBufferAddress() const { return GetInputBufferAddress(current_buffer); } + + uint32_t GetInputBufferPacketCount(uint8_t buffer_index) const { + return buffer_index == 0 ? input_buffer_0_packet_count : input_buffer_1_packet_count; + } + + uint32_t GetCurrentInputBufferPacketCount() const { + return GetInputBufferPacketCount(current_buffer); + } + + bool IsConsumeOnlyContext() const { + return (input_buffer_0_packet_count | input_buffer_1_packet_count) == 0; + } +}; +static_assert_size(XMA_CONTEXT_DATA, 64); + +#pragma pack(push, 1) +// XMA2WAVEFORMATEX +struct Xma2ExtraData { + uint8_t raw[34]; +}; +static_assert_size(Xma2ExtraData, 34); +#pragma pack(pop) + +struct kPacketInfo { + uint8_t frame_count_ = 0; + uint8_t current_frame_ = 0; + uint32_t current_frame_size_ = 0; + + bool isLastFrameInPacket() const { + return frame_count_ == 0 || current_frame_ == frame_count_ - 1; + } +}; + +static constexpr int kIdToSampleRate[4] = {24000, 32000, 44100, 48000}; + +class XmaContext { + public: + static const uint32_t kBytesPerPacket = 2048; + static const uint32_t kBitsPerPacket = kBytesPerPacket * 8; + static const uint32_t kBitsPerPacketHeader = 32; + static const uint32_t kBitsPerFrameHeader = 15; + static const uint32_t kBytesPerPacketHeader = 4; + static const uint32_t kBytesPerPacketData = kBytesPerPacket - kBytesPerPacketHeader; + + static const uint32_t kBytesPerSample = 2; + static const uint32_t kSamplesPerFrame = 512; + static const uint32_t kSamplesPerSubframe = 128; + static const uint32_t kBytesPerFrameChannel = kSamplesPerFrame * kBytesPerSample; + static const uint32_t kBytesPerSubframeChannel = kSamplesPerSubframe * kBytesPerSample; + + static const uint32_t kOutputBytesPerBlock = 256; + static const uint32_t kOutputMaxSizeBytes = 31 * kOutputBytesPerBlock; + static const uint32_t kMaxFrameSizeinBits = 0x4000 - kBitsPerPacketHeader; + + explicit XmaContext(); + ~XmaContext(); + + int Setup(uint32_t id, memory::Memory* memory, uint32_t guest_ptr); + bool Work(); + + void Enable(); + bool Block(bool poll); + void Clear(); + void Disable(); + void Release(); + + memory::Memory* memory() const { return memory_; } + + uint32_t id() { return id_; } + uint32_t guest_ptr() { return guest_ptr_; } + bool is_allocated() { return is_allocated_.load(std::memory_order_acquire); } + bool is_enabled() { return is_enabled_.load(std::memory_order_acquire); } + + void set_is_allocated(bool is_allocated) { + is_allocated_.store(is_allocated, std::memory_order_release); + } + void set_is_enabled(bool is_enabled) { is_enabled_.store(is_enabled, std::memory_order_release); } + + void SignalWorkDone() { + if (work_completion_event_) { + work_completion_event_->Set(); + } + } + void WaitForWorkDone() { + if (work_completion_event_) { + rex::thread::Wait(work_completion_event_.get(), false); + } + } + + private: + static void SwapInputBuffer(XMA_CONTEXT_DATA* data); + static int GetSampleRate(int id); + static int16_t GetPacketNumber(size_t size, size_t bit_offset); + static uint32_t GetCurrentInputBufferSize(XMA_CONTEXT_DATA* data); + + kPacketInfo GetPacketInfo(uint8_t* packet, uint32_t frame_offset); + uint32_t GetAmountOfBitsToRead(uint32_t remaining_stream_bits, uint32_t frame_size); + const uint8_t* GetNextPacket(XMA_CONTEXT_DATA* data, uint32_t next_packet_index, + uint32_t current_input_packet_count); + uint32_t GetNextPacketReadOffset(uint8_t* buffer, uint32_t next_packet_index, + uint32_t current_input_packet_count); + uint8_t* GetCurrentInputBuffer(XMA_CONTEXT_DATA* data); + + void Decode(XMA_CONTEXT_DATA* data); + void Consume(memory::RingBuffer* output_rb, const XMA_CONTEXT_DATA* data); + void UpdateLoopStatus(XMA_CONTEXT_DATA* data); + void ClearLocked(XMA_CONTEXT_DATA* data); + + memory::RingBuffer PrepareOutputRingBuffer(XMA_CONTEXT_DATA* data); + int PrepareDecoder(int sample_rate, bool is_two_channel); + void PreparePacket(uint32_t frame_size, uint32_t frame_padding); + bool DecodePacket(AVCodecContext* av_context, const AVPacket* av_packet, AVFrame* av_frame); + + void StoreContextMerged(const XMA_CONTEXT_DATA& data, const XMA_CONTEXT_DATA& initial_data, + uint8_t* context_ptr); + + static void ConvertFrame(const uint8_t** samples, bool is_two_channel, uint8_t* output_buffer); + + memory::Memory* memory_ = nullptr; + std::unique_ptr work_completion_event_; + + uint32_t id_ = 0; + uint32_t guest_ptr_ = 0; + std::mutex lock_; + std::atomic is_allocated_ = false; + std::atomic is_enabled_ = false; + + // ffmpeg structures + AVPacket* av_packet_ = nullptr; + AVCodec* av_codec_ = nullptr; + AVCodecContext* av_context_ = nullptr; + AVFrame* av_frame_ = nullptr; + + // Packet data buffer (two packets worth for split frame handling) + std::array input_buffer_; + // First byte contains bit offset information + std::array xma_frame_; + // Conversion buffer for up to 2-channel frame + std::array raw_frame_; + + // Output buffer tracking + int32_t remaining_subframe_blocks_in_output_buffer_ = 0; + uint8_t current_frame_remaining_subframes_ = 0; + + // Loop subframe precision state + uint8_t loop_frame_output_limit_ = 0; + bool loop_start_skip_pending_ = false; +}; + +} // namespace rex::audio diff --git a/include/rex/audio/xma/decoder.h b/include/rex/audio/xma/decoder.h new file mode 100644 index 0000000..df00f06 --- /dev/null +++ b/include/rex/audio/xma/decoder.h @@ -0,0 +1,92 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace rex::runtime { +class FunctionDispatcher; +} // namespace rex::runtime + +namespace rex::audio { + +struct XMA_CONTEXT_DATA; + +class XmaDecoder { + public: + explicit XmaDecoder(runtime::FunctionDispatcher* function_dispatcher); + ~XmaDecoder(); + + memory::Memory* memory() const { return memory_; } + runtime::FunctionDispatcher* function_dispatcher() const { return function_dispatcher_; } + + X_STATUS Setup(system::KernelState* kernel_state); + void Shutdown(); + + uint32_t context_array_ptr() const { return register_file_[XmaRegister::ContextArrayAddress]; } + + uint32_t AllocateContext(); + void ReleaseContext(uint32_t guest_ptr); + bool BlockOnContext(uint32_t guest_ptr, bool poll); + + uint32_t ReadRegister(uint32_t addr); + void WriteRegister(uint32_t addr, uint32_t value); + + bool is_paused() const { return paused_; } + void Pause(); + void Resume(); + + protected: + int GetContextId(uint32_t guest_ptr); + + private: + void WorkerThreadMain(); + + static uint32_t MMIOReadRegisterThunk(void* ppc_context, XmaDecoder* as, uint32_t addr) { + return as->ReadRegister(addr); + } + static void MMIOWriteRegisterThunk(void* ppc_context, XmaDecoder* as, uint32_t addr, + uint32_t value) { + as->WriteRegister(addr, value); + } + + protected: + memory::Memory* memory_ = nullptr; + runtime::FunctionDispatcher* function_dispatcher_ = nullptr; + + std::atomic worker_running_ = {false}; + system::object_ref worker_thread_; + std::unique_ptr work_event_ = nullptr; + + std::atomic paused_ = false; + rex::thread::Fence pause_fence_; // Signaled when worker paused. + rex::thread::Fence resume_fence_; // Signaled when resume requested. + + XmaRegisterFile register_file_; + + static const uint32_t kContextCount = 320; + XmaContext contexts_[kContextCount]; + bit::BitMap context_bitmap_; + + uint32_t context_data_first_ptr_ = 0; + uint32_t context_data_last_ptr_ = 0; +}; + +} // namespace rex::audio diff --git a/include/rex/audio/xma/helpers.h b/include/rex/audio/xma/helpers.h new file mode 100644 index 0000000..638e406 --- /dev/null +++ b/include/rex/audio/xma/helpers.h @@ -0,0 +1,46 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// This file contains some functions used to help parse XMA data. + +#pragma once + +#include + +namespace rex::audio::xma { + +static constexpr uint32_t kMaxFrameLength = 0x7FFF; + +// Get number of frames that /begin/ in this packet. Valid only for XMA2 packets. +inline uint8_t GetPacketFrameCount(const uint8_t* packet) { + return packet[0] >> 2; +} + +// Get the first frame offset in bits +inline uint32_t GetPacketFrameOffset(const uint8_t* packet) { + uint32_t val = + static_cast(((packet[0] & 0x3) << 13) | (packet[1] << 5) | (packet[2] >> 3)); + return val + 32; +} + +inline uint8_t GetPacketMetadata(const uint8_t* packet) { + return packet[2] & 0x7; +} + +inline bool IsPacketXma2Type(const uint8_t* packet) { + return GetPacketMetadata(packet) == 1; +} + +inline uint8_t GetPacketSkipCount(const uint8_t* packet) { + return packet[3]; +} + +} // namespace rex::audio::xma diff --git a/include/rex/audio/xma/register_file.h b/include/rex/audio/xma/register_file.h new file mode 100644 index 0000000..cd53173 --- /dev/null +++ b/include/rex/audio/xma/register_file.h @@ -0,0 +1,42 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +namespace rex::audio { + +struct XmaRegister { +#define XE_XMA_REGISTER(index, name) static const uint32_t name = index; +#include +#undef XE_XMA_REGISTER +}; + +struct XmaRegisterInfo { + const char* name; +}; + +class XmaRegisterFile { + public: + XmaRegisterFile(); + + static const XmaRegisterInfo* GetRegisterInfo(uint32_t index); + + static const size_t kRegisterCount = (0xFFFF + 1) / 4; + uint32_t values[kRegisterCount]; + + uint32_t operator[](uint32_t reg) const { return values[reg]; } + uint32_t& operator[](uint32_t reg) { return values[reg]; } +}; + +} // namespace rex::audio diff --git a/include/rex/audio/xma/register_table.inc b/include/rex/audio/xma/register_table.inc new file mode 100644 index 0000000..1703c2e --- /dev/null +++ b/include/rex/audio/xma/register_table.inc @@ -0,0 +1,81 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +// This is a partial file designed to be included by other files when +// constructing various tables. + +#ifndef XE_XMA_REGISTER +#define XE_XMA_REGISTER(index, name) +#define __XE_XMA_REGISTER_UNSET +#endif + +#ifndef XE_XMA_REGISTER_CONTEXT_GROUP +#define XE_XMA_REGISTER_CONTEXT_GROUP(index, suffix) \ + XE_XMA_REGISTER(index + 0, Context0##suffix) \ + XE_XMA_REGISTER(index + 1, Context1##suffix) \ + XE_XMA_REGISTER(index + 2, Context2##suffix) \ + XE_XMA_REGISTER(index + 3, Context3##suffix) \ + XE_XMA_REGISTER(index + 4, Context4##suffix) \ + XE_XMA_REGISTER(index + 5, Context5##suffix) \ + XE_XMA_REGISTER(index + 6, Context6##suffix) \ + XE_XMA_REGISTER(index + 7, Context7##suffix) \ + XE_XMA_REGISTER(index + 8, Context8##suffix) \ + XE_XMA_REGISTER(index + 9, Context9##suffix) +#endif + +// 0x0000..0x001F : ??? +// 0x0020..0x03FF : all 0xFFs? +// 0x0400..0x043F : ??? +// 0x0440..0x047F : all 0xFFs? +// 0x0480..0x048B : ??? +// 0x048C..0x04C0 : all 0xFFs? +// 0x04C1..0x04CB : ??? +// 0x04CC..0x04FF : all 0xFFs? +// 0x0500..0x051F : ??? +// 0x0520..0x057F : all 0xFFs? +// 0x0580..0x058F : ??? +// 0x0590..0x05FF : all 0xFFs? + +// XMA stuff is probably only 0x0600..0x06FF +//---------------------------------------------------------------------------// + +XE_XMA_REGISTER(0x0600, ContextArrayAddress) +// 0x0601..0x0605 : ??? +XE_XMA_REGISTER(0x0606, CurrentContextIndex) +XE_XMA_REGISTER(0x0607, NextContextIndex) +// 0x0608 : ??? +// 0x0609..0x060F : zero? +XE_XMA_REGISTER_CONTEXT_GROUP(0x0610, Unknown610) +// 0x061A..0x061F : zero? +XE_XMA_REGISTER_CONTEXT_GROUP(0x0620, Unknown620) +// 0x062A..0x0641 : zero? +// 0x0642..0x0644 : ??? +// 0x0645..0x064F : zero? +XE_XMA_REGISTER_CONTEXT_GROUP(0x0650, Kick) +// 0x065A..0x065F : zero? +XE_XMA_REGISTER_CONTEXT_GROUP(0x0660, Unknown660) +// 0x066A..0x0681 : zero? +// 0x0682..0x0684 : ??? +// 0x0685..0x068F : zero? +XE_XMA_REGISTER_CONTEXT_GROUP(0x0690, Lock) +// 0x069A..0x069F : zero? +XE_XMA_REGISTER_CONTEXT_GROUP(0x06A0, Clear) + +//---------------------------------------------------------------------------// + +// 0x0700..0x07FF : all 0xFFs? +// 0x0800..0x17FF : ??? +// 0x1800..0x2FFF : all 0xFFs? +// 0x3000..0x30FF : ??? +// 0x3100..0x3FFF : all 0xFFs? + +#ifdef __XE_XMA_REGISTER_UNSET +#undef __XE_XMA_REGISTER_UNSET +#undef XE_XMA_REGISTER +#endif diff --git a/include/rex/bit.h b/include/rex/bit.h new file mode 100644 index 0000000..b6759a3 --- /dev/null +++ b/include/rex/bit.h @@ -0,0 +1,145 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015-2019 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified 2026 Tom Clay + * Modified for rexglue - Xbox 360 recompilation framework + * + * @changes - Consolidated bit_map.h and bit_range.h into single header + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include + +namespace rex::bit { + +//============================================================================= +// BitMap - Efficient lookup of free/used entries +//============================================================================= + +class BitMap { + public: + BitMap(); + + // Size is the number of entries, must be a multiple of 64. + BitMap(size_t size_bits); + + // Data does not have to be aligned to a 4-byte boundary, but it is + // preferable. + // Size is the number of entries, must be a multiple of 64. + BitMap(uint64_t* data, size_t size_bits); + + // (threadsafe) Acquires an entry and returns its index. Returns -1 if there + // are no more free entries. + size_t Acquire(); + + // (threadsafe) Releases an entry by an index. + void Release(size_t index); + + // Resize the bitmap. Size is the number of entries, must be a multiple of 64. + void Resize(size_t new_size_bits); + + // Sets all entries to free. + void Reset(); + + const std::vector data() const { return data_; } + std::vector& data() { return data_; } + + private: + const static size_t kDataSize = 8; + const static size_t kDataSizeBits = kDataSize * 8; + std::vector data_; +}; + +//============================================================================= +// Bit Range Utilities +//============================================================================= + +// Provided length is in bits since the first. Returns of the +// range in bits, with length == 0 if not found. +template +std::pair GetNextRangeUnset(const Block* bits, size_t first, size_t length) { + if (!length) { + return std::make_pair(size_t(first), size_t(0)); + } + size_t last = first + length - 1; + const size_t block_bits = sizeof(Block) * CHAR_BIT; + size_t block_first = first / block_bits; + size_t block_last = last / block_bits; + size_t range_start = SIZE_MAX; + for (size_t i = block_first; i <= block_last; ++i) { + Block block = bits[i]; + // Ignore bits in the block outside the specified range by considering them + // set. + if (i == block_first) { + block |= (Block(1) << (first & (block_bits - 1))) - 1; + } + if (i == block_last && (last & (block_bits - 1)) != block_bits - 1) { + block |= ~((Block(1) << ((last & (block_bits - 1)) + 1)) - 1); + } + while (true) { + uint32_t block_bit; + if (range_start == SIZE_MAX) { + // Check if need to open a new range. + if (!rex::bit_scan_forward(~block, &block_bit)) { + break; + } + range_start = i * block_bits + block_bit; + } else { + // Check if need to close the range. + // Ignore the set bits before the beginning of the range. + Block block_bits_set_from_start = block; + if (i == range_start / block_bits) { + block_bits_set_from_start &= ~((Block(1) << (range_start & (block_bits - 1))) - 1); + } + if (!rex::bit_scan_forward(block_bits_set_from_start, &block_bit)) { + break; + } + return std::make_pair(range_start, (i * block_bits) + block_bit - range_start); + } + } + } + if (range_start != SIZE_MAX) { + return std::make_pair(range_start, last + size_t(1) - range_start); + } + return std::make_pair(first + length, size_t(0)); +} + +template +void SetRange(Block* bits, size_t first, size_t length) { + if (!length) { + return; + } + size_t last = first + length - 1; + const size_t block_bits = sizeof(Block) * CHAR_BIT; + size_t block_first = first / block_bits; + size_t block_last = last / block_bits; + Block set_first = ~((Block(1) << (first & (block_bits - 1))) - 1); + Block set_last = ~Block(0); + if ((last & (block_bits - 1)) != (block_bits - 1)) { + set_last &= (Block(1) << ((last & (block_bits - 1)) + 1)) - 1; + } + if (block_first == block_last) { + bits[block_first] |= set_first & set_last; + return; + } + bits[block_first] |= set_first; + if (block_first + 1 < block_last) { + std::memset(bits + block_first + 1, CHAR_MAX, (block_last - (block_first + 1)) * sizeof(Block)); + } + bits[block_last] |= set_last; +} + +} // namespace rex::bit diff --git a/include/rex/chrono/chrono.h b/include/rex/chrono/chrono.h new file mode 100644 index 0000000..8761cff --- /dev/null +++ b/include/rex/chrono/chrono.h @@ -0,0 +1,165 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include + +#include + +namespace rex { +using hundrednano = std::ratio<1, 10000000>; + +namespace chrono { + +using hundrednanoseconds = std::chrono::duration; + +// TODO(JoelLinn) define xstead_clock xsystem_clock etc. + +namespace detail { +// Implementation detail: NtSystemClock template for Host/Guest time domains. +// Trick to reduce code duplication and keep all the chrono template magic +// working. +enum class Domain { + // boring host clock: + Host, + // adheres to guest scaling (differrent speed, changing clock drift etc): + Guest +}; + +template +struct NtSystemClock { + using rep = int64_t; + using period = hundrednano; + using duration = hundrednanoseconds; + using time_point = std::chrono::time_point>; + // This really depends on the context the clock is used in: + // static constexpr bool is_steady = false; + + public: + // The delta between std::chrono::system_clock (Jan 1 1970) and NT file + // time (Jan 1 1601), in seconds. In the spec std::chrono::system_clock's + // epoch is undefined, but C++20 cements it as Jan 1 1970. + static constexpr std::chrono::seconds unix_epoch_delta() { + using std::chrono::steady_clock; + auto filetime_epoch = std::chrono::year{1601} / std::chrono::month{1} / std::chrono::day{1}; + auto system_clock_epoch = std::chrono::year{1970} / std::chrono::month{1} / std::chrono::day{1}; + auto fp = + static_cast(static_cast(filetime_epoch)); + auto sp = static_cast( + static_cast(system_clock_epoch)); + return fp.time_since_epoch() - sp.time_since_epoch(); + } + + public: + static constexpr uint64_t to_file_time(time_point const& tp) noexcept { + return static_cast(tp.time_since_epoch().count()); + } + + static constexpr time_point from_file_time(uint64_t const& tp) noexcept { + return time_point{duration{tp}}; + } + + // To convert XSystemClock to sys, do clock_cast(tp) first + // Only available for Host domain (Guest time must be converted via clock_cast) + static constexpr std::chrono::system_clock::time_point to_sys(const time_point& tp) + requires(domain_ == Domain::Host) + { + using sys_duration = std::chrono::system_clock::duration; + using sys_time = std::chrono::system_clock::time_point; + + auto dp = tp; + dp += unix_epoch_delta(); + auto cdp = std::chrono::time_point_cast(dp); + return sys_time{cdp.time_since_epoch()}; + } + + static constexpr time_point from_sys(const std::chrono::system_clock::time_point& tp) + requires(domain_ == Domain::Host) + { + auto ctp = std::chrono::time_point_cast(tp); + auto dp = time_point{ctp.time_since_epoch()}; + dp -= unix_epoch_delta(); + return dp; + } + + [[nodiscard]] static time_point now() noexcept { + if constexpr (domain_ == Domain::Host) { + // QueryHostSystemTime() returns windows epoch times even on POSIX + return from_file_time(Clock::QueryHostSystemTime()); + } else if constexpr (domain_ == Domain::Guest) { + return from_file_time(Clock::QueryGuestSystemTime()); + } + } +}; +} // namespace detail + +// Unscaled system clock which can be used for filetime <-> system_clock +// conversion +using WinSystemClock = detail::NtSystemClock; + +// Guest system clock, scaled +using XSystemClock = detail::NtSystemClock; + +} // namespace chrono +} // namespace rex + +namespace std::chrono { + +template <> +struct clock_time_conversion<::rex::chrono::WinSystemClock, ::rex::chrono::XSystemClock> { + using WClock_ = ::rex::chrono::WinSystemClock; + using XClock_ = ::rex::chrono::XSystemClock; + + template + typename WClock_::time_point operator()( + const std::chrono::time_point& t) const { + // Consult chrono_steady_cast.h for explanation on this: + std::atomic_thread_fence(std::memory_order_acq_rel); + auto w_now = WClock_::now(); + auto x_now = XClock_::now(); + std::atomic_thread_fence(std::memory_order_acq_rel); + + auto delta = (t - x_now); + if (!REXCVAR_GET(clock_no_scaling)) { + delta = + std::chrono::floor(delta * rex::chrono::Clock::guest_time_scalar()); + } + return w_now + delta; + } +}; + +template <> +struct clock_time_conversion<::rex::chrono::XSystemClock, ::rex::chrono::WinSystemClock> { + using WClock_ = ::rex::chrono::WinSystemClock; + using XClock_ = ::rex::chrono::XSystemClock; + + template + typename XClock_::time_point operator()( + const std::chrono::time_point& t) const { + // Consult chrono_steady_cast.h for explanation on this: + std::atomic_thread_fence(std::memory_order_acq_rel); + auto w_now = WClock_::now(); + auto x_now = XClock_::now(); + std::atomic_thread_fence(std::memory_order_acq_rel); + + rex::chrono::hundrednanoseconds delta = (t - w_now); + if (!REXCVAR_GET(clock_no_scaling)) { + delta = + std::chrono::floor(delta / rex::chrono::Clock::guest_time_scalar()); + } + return x_now + delta; + } +}; + +} // namespace std::chrono diff --git a/include/rex/chrono/chrono_steady_cast.h b/include/rex/chrono/chrono_steady_cast.h new file mode 100644 index 0000000..8401109 --- /dev/null +++ b/include/rex/chrono/chrono_steady_cast.h @@ -0,0 +1,73 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include + +// This is in a separate header because casting to and from steady time points +// usually doesn't make sense and is imprecise. However, NT uses the FileTime +// epoch as a steady clock in waits. In such cases, include this header and use +// clock_cast<>(). + +namespace std::chrono { + +// This conveniently works only for Host time domain because Guest needs +// additional scaling. Convert XSystemClock to WinSystemClock first if +// necessary. +template <> +struct clock_time_conversion<::rex::chrono::WinSystemClock, std::chrono::steady_clock> { + // using NtSystemClock_ = ::rex::chrono::internal::NtSystemClock; + using WinSystemClock_ = ::rex::chrono::WinSystemClock; + using steady_clock_ = std::chrono::steady_clock; + + template + typename WinSystemClock_::time_point operator()( + const std::chrono::time_point& t) const { + // Since there is no known epoch for steady_clock and even if, since it can + // progress differently than other common clocks (e.g. stopping when the + // computer is suspended), we need to use now() which introduces + // imprecision. + // Memory fences to keep the clock fetches close together to + // minimize drift. This pattern was benchmarked to give the lowest + // conversion error: error = sty_tpoint - + // clock_cast(clock_cast(sty_tpoint)); + std::atomic_thread_fence(std::memory_order_acq_rel); + auto steady_now = steady_clock_::now(); + auto nt_now = WinSystemClock_::now(); + std::atomic_thread_fence(std::memory_order_acq_rel); + + auto delta = std::chrono::floor(t - steady_now); + return nt_now + delta; + } +}; + +template <> +struct clock_time_conversion { + using WinSystemClock_ = ::rex::chrono::WinSystemClock; + using steady_clock_ = std::chrono::steady_clock; + + template + steady_clock_::time_point operator()( + const std::chrono::time_point& t) const { + std::atomic_thread_fence(std::memory_order_acq_rel); + auto steady_now = steady_clock_::now(); + auto nt_now = WinSystemClock_::now(); + std::atomic_thread_fence(std::memory_order_acq_rel); + + auto delta = t - nt_now; + return steady_now + delta; + } +}; + +} // namespace std::chrono diff --git a/include/rex/chrono/clock.h b/include/rex/chrono/clock.h new file mode 100644 index 0000000..c19caea --- /dev/null +++ b/include/rex/chrono/clock.h @@ -0,0 +1,90 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +#include +#include + +REXCVAR_DECLARE(bool, clock_no_scaling); +REXCVAR_DECLARE(bool, clock_source_raw); + +#if REX_ARCH_AMD64 +// Raw clock source requires platform-specific implementation +// Disable for now - use platform clock functions instead +#define REX_CLOCK_RAW_AVAILABLE 0 +#endif + +namespace rex::chrono { + +class Clock { + public: + // Host ticks-per-second. Generally QueryHostTickFrequency should be used. + // Either from platform suplied time source or from hardware directly. + static uint64_t host_tick_frequency_platform(); +#if REX_CLOCK_RAW_AVAILABLE + static uint64_t host_tick_frequency_raw(); +#endif + // Host tick count. Generally QueryHostTickCount() should be used. + static uint64_t host_tick_count_platform(); +#if REX_CLOCK_RAW_AVAILABLE + static uint64_t host_tick_count_raw(); +#endif + + // Queries the host tick frequency. + static uint64_t QueryHostTickFrequency(); + // Queries the current host tick count. + static uint64_t QueryHostTickCount(); + // Host time, in FILETIME format. + static uint64_t QueryHostSystemTime(); + // Queries the milliseconds since the host began. + static uint64_t QueryHostUptimeMillis(); + + // Guest time scalar. + static double guest_time_scalar(); + // Sets the guest time scalar, adjusting tick and wall clock speed. + // Ex: 1x=normal, 2x=double speed, 1/2x=half speed. + static void set_guest_time_scalar(double scalar); + // Get the tick ration between host and guest including time scaling if set. + static std::pair guest_tick_ratio(); + // Guest ticks-per-second. + static uint64_t guest_tick_frequency(); + // Sets the guest ticks-per-second. + static void set_guest_tick_frequency(uint64_t frequency); + // Time based used for the guest system time. + static uint64_t guest_system_time_base(); + // Sets the guest time base, used for computing the system time. + // By default this is the current system time. + static void set_guest_system_time_base(uint64_t time_base); + + // Queries the current guest tick count, accounting for frequency adjustment + // and scaling. + static uint64_t QueryGuestTickCount(); + // Queries the guest time, in FILETIME format, accounting for scaling. + static uint64_t QueryGuestSystemTime(); + // Queries the milliseconds since the guest began, accounting for scaling. + static uint32_t QueryGuestUptimeMillis(); + + // Sets the system time of the guest. + static void SetGuestSystemTime(uint64_t system_time); + + // Scales a time duration in milliseconds, from guest time. + static uint32_t ScaleGuestDurationMillis(uint32_t guest_ms); + // Scales a time duration in 100ns ticks like FILETIME, from guest time. + static int64_t ScaleGuestDurationFileTime(int64_t guest_file_time); + // Scales a time duration represented as a timeval, from guest time. + static void ScaleGuestDurationTimeval(int32_t* tv_sec, int32_t* tv_usec); +}; + +} // namespace rex::chrono diff --git a/include/rex/codegen/analysis_errors.h b/include/rex/codegen/analysis_errors.h new file mode 100644 index 0000000..8b28608 --- /dev/null +++ b/include/rex/codegen/analysis_errors.h @@ -0,0 +1,58 @@ +/** + * @file rexcodegen/analysis_errors.h + * @brief Scoped error collection for analysis + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include + +namespace rex::codegen { + +/** + * Collects errors during analysis. Replaces global g_validationState. + */ +class AnalysisErrors { + public: + enum class Category { + UnresolvedCall, + MissingJumpTable, + JumpTargetOutOfBounds, + DiscontinuousFunction, + UnimplementedInsn, + }; + + struct Entry { + Category category; + uint32_t address; + uint32_t secondaryAddress; + std::string message; + }; + + void Add(Category cat, uint32_t addr, const std::string& msg); + void Add(Category cat, uint32_t addr, uint32_t secondary, const std::string& msg); + + bool HasErrors() const { return !entries_.empty(); } + size_t Count() const { return entries_.size(); } + size_t Count(Category cat) const; + + const std::vector& Entries() const { return entries_; } + + void PrintReport() const; + void Clear() { entries_.clear(); } + + static const char* CategoryName(Category cat); + + private: + std::vector entries_; +}; + +} // namespace rex::codegen diff --git a/include/rex/codegen/analyze.h b/include/rex/codegen/analyze.h new file mode 100644 index 0000000..d80914d --- /dev/null +++ b/include/rex/codegen/analyze.h @@ -0,0 +1,37 @@ +/** + * @file rex/codegen/analyze.h + * @brief Function graph analysis (builds + validates) + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include + +namespace rex::codegen { + +/** + * Build and validate the complete FunctionGraph. + * + * This function consolidates all analysis phases: + * - Register: imports, helpers, PDATA functions, config functions + * - Scan: code regions (null boundaries), data regions + * - Discover: function blocks, calls, jump tables (iterative to fixed point) + * - VTable: discover functions via RTTI vtables + * - GapFill: claim orphaned code regions + * - Merge: resolve all jumps, seal functions + * - Validate: verify all calls resolve + * + * @param ctx CodegenContext with binary and config loaded + * @return Success if graph is valid, error otherwise + */ +Result Analyze(CodegenContext& ctx, ProgressReporter* reporter = nullptr); + +} // namespace rex::codegen diff --git a/include/rex/codegen/binary_view.h b/include/rex/codegen/binary_view.h new file mode 100644 index 0000000..3af16d2 --- /dev/null +++ b/include/rex/codegen/binary_view.h @@ -0,0 +1,115 @@ +/** + * @file rex/codegen/binary_view.h + * @brief Self-contained binary view that owns section data + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace rex::runtime { +class Module; +} + +namespace rex::codegen { + +/// Lightweight view of a binary section (points into BinaryView's owned data) +struct SectionView { + std::string_view name; + uint32_t baseAddress; + uint32_t size; + const uint8_t* data; + bool executable; + + bool contains(uint32_t addr) const { return addr >= baseAddress && addr < baseAddress + size; } + + const uint8_t* translate(uint32_t addr) const { + if (!contains(addr)) + return nullptr; + return data + (addr - baseAddress); + } + + uint32_t end() const { return baseAddress + size; } +}; + +/// Import symbol from binary (thunk address + name in "libname@ordinal" format) +struct ImportSymbol { + uint32_t address; ///< Thunk address (bl target) + std::string name; ///< "libname@ordinal" format +}; + +/// Self-contained binary view that owns all section data +class BinaryView { + public: + /// Factory - copies all data from Module + static BinaryView fromModule(const runtime::Module& module); + + // Move-only (owns large buffers) + BinaryView(BinaryView&&) noexcept = default; + BinaryView& operator=(BinaryView&&) noexcept = default; + BinaryView(const BinaryView&) = delete; + BinaryView& operator=(const BinaryView&) = delete; + + // Section access + const uint8_t* translate(uint32_t addr) const; + bool isExecutable(uint32_t addr) const; + const SectionView* findSection(uint32_t addr) const; + const SectionView* findSectionByName(std::string_view name) const; + std::span sections() const { return sections_; } + + // Metadata access + uint32_t baseAddress() const { return baseAddress_; } + uint32_t imageSize() const { return imageSize_; } + uint32_t entryPoint() const { return entryPoint_; } + uint32_t exceptionDirectoryAddr() const { return exceptionDirectoryAddr_; } + uint32_t exceptionDirectorySize() const { return exceptionDirectorySize_; } + uint32_t exportTableAddr() const { return exportTableAddr_; } + + /// Start of import thunk table (0 if not available) + /// Everything from this address to end of .text is import/export tables, not code + uint32_t importThunkTableStart() const { return importThunkTableStart_; } + + /// Check if address is in the import thunk/export table range (not real code) + /// This range is specifically within .text section, not other executable sections + bool isInImportExportRange(uint32_t addr) const { + return importThunkTableStart_ != 0 && addr >= importThunkTableStart_ && + addr < importExportRangeEnd_; + } + + /// Import symbols (thunk addresses + names) + std::span importSymbols() const { return importSymbols_; } + + public: + BinaryView() = default; + + private: + // Owned section data + std::vector sections_; + std::vector sectionNames_; + std::vector> sectionData_; + + // Metadata + uint32_t baseAddress_ = 0; + uint32_t imageSize_ = 0; + uint32_t entryPoint_ = 0; + uint32_t exceptionDirectoryAddr_ = 0; + uint32_t exceptionDirectorySize_ = 0; + uint32_t exportTableAddr_ = 0; + uint32_t importThunkTableStart_ = 0; ///< Start of import thunk table + uint32_t importExportRangeEnd_ = 0; ///< End of import/export range (end of .text) + + // Import symbols + std::vector importSymbols_; +}; + +} // namespace rex::codegen diff --git a/include/rex/codegen/code_emitter.h b/include/rex/codegen/code_emitter.h new file mode 100644 index 0000000..d1079fd --- /dev/null +++ b/include/rex/codegen/code_emitter.h @@ -0,0 +1,159 @@ +/** + * @file rex/codegen/code_emitter.h + * @brief Abstract code emission interface + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include + +#include + +namespace rex::codegen { + +// Forward declarations +struct RecompilerConfig; + +/** + * @brief CSR (Control/Status Register) state for FPU denormal handling. + * + * Tracks MXCSR configuration: + * - Unknown: Initial or after function call + * - Fpu: Denormals preserved (scalar FP) + * - Vmx: Denormals flushed (vector FP) + */ +enum class CsrState { + Unknown, // Need to check/set on next FP instruction + Fpu, // Flush mode disabled (scalar FP) + Vmx // Flush mode enabled (vector FP) +}; + +/** + * @brief Abstract interface for C++ code emission. + * + * Provides indentation management, formatted output, and CSR state tracking. + * Implementations can write to strings, files, or streams. + * + * Example: + * @code + * StringEmitter emit; + * emit.line("void foo() {{"); + * emit.indent(); + * emit.line("int x = {};", 42); + * emit.dedent(); + * emit.line("}}"); + * @endcode + */ +class CodeEmitter { + public: + virtual ~CodeEmitter() = default; + + //========================================================================= + // Indentation + //========================================================================= + + /// Increase indentation level + virtual void indent() = 0; + + /// Decrease indentation level + virtual void dedent() = 0; + + /// Get current indentation string + virtual std::string_view indentString() const = 0; + + //========================================================================= + // Output + //========================================================================= + + /// Write raw string (no indentation, no newline) + virtual void raw(std::string_view text) = 0; + + /// Write formatted line with indentation and newline + template + void line(fmt::format_string fmt, Args&&... args) { + raw(indentString()); + raw(fmt::format(fmt, std::forward(args)...)); + raw("\n"); + } + + /// Write empty line + void blankLine() { raw("\n"); } + + /// Write comment line + void comment(std::string_view text) { + raw(indentString()); + raw("// "); + raw(text); + raw("\n"); + } + + //========================================================================= + // CSR State Management + //========================================================================= + + /// Get current CSR state + CsrState csrState() const { return csrState_; } + + /// Set CSR state (called when mode is established) + void setCsrState(CsrState state) { csrState_ = state; } + + /// Ensure CSR is in required state, emitting code if needed + virtual void ensureCsrState(CsrState required); + + /// Reset CSR state to Unknown (call after function calls) + void resetCsrState() { csrState_ = CsrState::Unknown; } + + protected: + CsrState csrState_ = CsrState::Unknown; +}; + +/** + * @brief CodeEmitter that writes to a string buffer. + * + * Useful for tests and building function bodies before output. + */ +class StringEmitter : public CodeEmitter { + public: + explicit StringEmitter(int indentWidth = 4) : indentWidth_(indentWidth) {} + + void indent() override { + indentLevel_++; + updateIndentString(); + } + + void dedent() override { + if (indentLevel_ > 0) + indentLevel_--; + updateIndentString(); + } + + std::string_view indentString() const override { return indentStr_; } + + void raw(std::string_view text) override { buffer_.append(text); } + + /// Get the accumulated output + const std::string& str() const { return buffer_; } + + /// Clear the buffer + void clear() { buffer_.clear(); } + + /// Move the buffer out + std::string take() { return std::move(buffer_); } + + private: + void updateIndentString() { indentStr_ = std::string(indentLevel_ * indentWidth_, ' '); } + + std::string buffer_; + std::string indentStr_; + int indentLevel_ = 0; + int indentWidth_ = 4; +}; + +} // namespace rex::codegen diff --git a/include/rex/codegen/code_region.h b/include/rex/codegen/code_region.h new file mode 100644 index 0000000..2c9a444 --- /dev/null +++ b/include/rex/codegen/code_region.h @@ -0,0 +1,26 @@ +/** + * @file rex/codegen/code_region.h + * @brief Lightweight code region struct (no PPC dependencies) + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include + +namespace rex::codegen { + +struct CodeRegion { + uint32_t start; + uint32_t end; + + bool contains(uint32_t addr) const { return addr >= start && addr < end; } + uint32_t size() const { return end - start; } +}; + +} // namespace rex::codegen diff --git a/include/rex/codegen/codegen.h b/include/rex/codegen/codegen.h new file mode 100644 index 0000000..0eacb69 --- /dev/null +++ b/include/rex/codegen/codegen.h @@ -0,0 +1,67 @@ +/** + * @file rex/codegen/codegen.h + * @brief Codegen pipeline orchestrator + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include + +#include +#include + +namespace rex { +class Runtime; +} + +namespace rex::codegen { + +/** + * Pipeline orchestrator for code generation. + * + * Usage: + * auto pipeline = CodegenPipeline::Create(configPath); + * if (!pipeline) { handle error } + * auto result = pipeline->Run(); + */ +class CodegenPipeline { + public: + ~CodegenPipeline(); + + // Non-copyable, movable + CodegenPipeline(const CodegenPipeline&) = delete; + CodegenPipeline& operator=(const CodegenPipeline&) = delete; + CodegenPipeline(CodegenPipeline&&) noexcept; + CodegenPipeline& operator=(CodegenPipeline&&) noexcept; + + /** + * Create pipeline from config file path. + * Loads XEX, creates Runtime and CodegenContext. + * + * @param configPath Path to TOML config file + * @return Pipeline on success, error on failure + */ + static Result Create(const std::filesystem::path& configPath); + + Result Run(bool force = false); + Result RunAnalyze(); + Result RunWrite(bool force = false); + + CodegenContext& context() { return *ctx_; } + const CodegenContext& context() const { return *ctx_; } + + private: + CodegenPipeline() = default; + + std::unique_ptr runtime_; + std::unique_ptr ctx_; +}; + +} // namespace rex::codegen diff --git a/include/rex/codegen/codegen_context.h b/include/rex/codegen/codegen_context.h new file mode 100644 index 0000000..a736bcc --- /dev/null +++ b/include/rex/codegen/codegen_context.h @@ -0,0 +1,179 @@ +/** + * @file rexcodegen/codegen_context.h + * @brief Unified context for codegen pipeline + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace rex { +class Runtime; + +namespace runtime { +class ExportResolver; +} +} // namespace rex + +namespace rex::codegen { + +// Forward declarations +class DecodedBinary; +struct SectionInfo; +struct FunctionEntry; +struct FunctionConfig; + +/** + * Analysis state holding binary-derived data and analysis results. + * This data is populated during analysis and should not be mutated after. + * Separates analysis state from user-provided config. + */ +struct AnalysisState { + // Binary-derived (set once from BinaryView) + std::string format; ///< "xex" or "elf" + uint64_t loadAddress = 0; ///< Image base address + uint64_t entryPoint = 0; ///< Entry point address + uint64_t imageSize = 0; ///< Total image size + + // Analysis results + std::vector sections; ///< Sections from binary + std::vector analyzedFunctions; ///< Discovered functions + std::unordered_map> chunksByParent; ///< Chunk lookup + + // Auto-detected ABI helpers (0 = not found) + uint32_t restGpr14Address = 0; + uint32_t saveGpr14Address = 0; + uint32_t restFpr14Address = 0; + uint32_t saveFpr14Address = 0; + uint32_t restVmx14Address = 0; + uint32_t saveVmx14Address = 0; + uint32_t restVmx64Address = 0; + uint32_t saveVmx64Address = 0; + + // Merged results (user hints + analysis-detected) + std::unordered_map invalidInstructions; ///< addr -> size + std::unordered_set knownIndirectCalls; ///< bctr addresses + std::vector exceptionHandlerFuncs; ///< Handler addresses + std::vector ehDiscoveredFuncs; ///< EH-discovered function addresses +}; + +/** + * Unified context for the entire codegen pipeline. + * + * This class owns all the core data structures used throughout analysis + * and code generation. It replaces the previous scattered ownership where + * Recompiler owned some data and AnalysisContext owned other data. + * + * Single source of truth for: + * - Binary data (BinaryView) + * - Function graph (all functions including imports) + * - Configuration + * - Analysis errors + * - Scan artifacts + */ +class CodegenContext { + public: + // === FACTORY === + /** + * Create a CodegenContext from config file path and Runtime. + * + * This is the primary way to create a context. It: + * 1. Loads configuration from the TOML file + * 2. Loads the XEX via Runtime + * 3. Creates BinaryView from the loaded module + * + * @param configPath Path to the TOML config file + * @param runtime Runtime instance (must be set up with correct content_root) + * @return CodegenContext on success, error on failure + */ + static Result Create(const std::filesystem::path& configPath, Runtime& runtime); + + /** + * Create a CodegenContext from pre-loaded binary and config. + * Primarily for testing where binary is loaded differently. + * + * @param binary Pre-loaded BinaryView (moved into context) + * @param config Pre-loaded RecompilerConfig (moved into context) + */ + static CodegenContext Create(BinaryView binary, RecompilerConfig config); + + // Non-copyable, movable + CodegenContext(const CodegenContext&) = delete; + CodegenContext& operator=(const CodegenContext&) = delete; + CodegenContext(CodegenContext&&); + CodegenContext& operator=(CodegenContext&&); + ~CodegenContext(); + + // === OWNED DATA (single source of truth) === + FunctionGraph graph; ///< All functions (including imports) + AnalysisErrors errors; ///< Accumulated errors + + /// Scan phase artifacts (passed to Discover for scanner setup) + struct { + std::vector codeRegions; ///< Null-delimited code regions + std::vector> dataRegions; + std::unordered_map pdataSizes; // address -> size + } scan; + + // === ACCESSORS === + const BinaryView& binary() const { return binary_; } + BinaryView& binary() { return binary_; } + + /// Access the decoded binary (must call initDecoded() first) + DecodedBinary& decoded(); + const DecodedBinary& decoded() const; + + /// Initialize DecodedBinary after context is in final location + /// Call this once after Create() before accessing decoded() + void initDecoded(); + + bool hasDecoded() const { return decoded_ != nullptr; } + + RecompilerConfig& Config() { return config_; } + const RecompilerConfig& Config() const { return config_; } + + AnalysisState& analysisState() { return analysisState_; } + const AnalysisState& analysisState() const { return analysisState_; } + + runtime::ExportResolver* resolver() const { return resolver_; } + void setResolver(runtime::ExportResolver* r) { resolver_ = r; } + + const std::filesystem::path& configDir() const { return configDir_; } + void setConfigDir(const std::filesystem::path& dir) { configDir_ = dir; } + + void setDllModule(bool is_dll) { is_dll_module_ = is_dll; } + bool isDllModule() const { return is_dll_module_; } + + void setHasDllModules(bool has) { has_dll_modules_ = has; } + bool hasDllModules() const { return has_dll_modules_; } + + private: + CodegenContext() = default; + + BinaryView binary_; ///< Binary data + sections (owned) + RecompilerConfig config_; ///< User configuration (owned) + AnalysisState analysisState_; ///< Analysis state (populated during analysis) + std::unique_ptr decoded_; ///< Decoded instructions (created via initDecoded()) + runtime::ExportResolver* resolver_ = nullptr; ///< For runtime resolution (borrowed) + std::filesystem::path configDir_; ///< Directory containing config file (for relative paths) + bool is_dll_module_ = false; ///< True if this module is a DLL (shared library output) + bool has_dll_modules_ = false; ///< True if the project has DLL modules (multi-binary) +}; + +} // namespace rex::codegen diff --git a/include/rex/codegen/codegen_writer.h b/include/rex/codegen/codegen_writer.h new file mode 100644 index 0000000..56d0290 --- /dev/null +++ b/include/rex/codegen/codegen_writer.h @@ -0,0 +1,81 @@ +/** + * @file rex/codegen/codegen_writer.h + * @brief Consolidated codegen output writer + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include + +#include + +#include + +namespace rex { +class Runtime; +} + +namespace rex::codegen { + +class CodegenWriter { + public: + CodegenWriter(CodegenContext& ctx, Runtime* runtime = nullptr); + + /// Run the full output pipeline: validate, clean old files, generate, flush. + bool write(bool force); + + /** + * Basenames of files removed by the pre-emit cleanup sweep during write(). + * Populated only after write() completes. Empty otherwise. + */ + const std::vector& deletedFiles() const { return deletedFiles_; } + + /** + * Basenames of files written to disk during write() (via FlushPendingWrites). + * Populated only after write() completes. Empty otherwise. + */ + const std::vector& writtenFiles() const { return writtenFiles_; } + + private: + CodegenContext& ctx_; + Runtime* runtime_; + + std::string out; + size_t cppFileIndex = 0; + std::vector> pendingWrites; + std::vector deletedFiles_; + std::vector writtenFiles_; + + template + void print(fmt::format_string fmt, Args&&... args) { + fmt::vformat_to(std::back_inserter(out), fmt.get(), fmt::make_format_args(args...)); + } + + template + void println(fmt::format_string fmt, Args&&... args) { + fmt::vformat_to(std::back_inserter(out), fmt.get(), fmt::make_format_args(args...)); + out += '\n'; + } + + void SaveCurrentOutData(std::string_view name = {}); + void FlushPendingWrites(); + + // Convenience accessors + FunctionGraph& graph(); + const FunctionGraph& graph() const; + const BinaryView& binary() const; + RecompilerConfig& config(); + const RecompilerConfig& config() const; + AnalysisState& analysisState(); + const AnalysisState& analysisState() const; +}; + +} // namespace rex::codegen diff --git a/include/rex/codegen/config.h b/include/rex/codegen/config.h new file mode 100644 index 0000000..e8d3b47 --- /dev/null +++ b/include/rex/codegen/config.h @@ -0,0 +1,161 @@ +/** + * @file rexcodegen/internal/config.h + * @brief Recompiler configuration types + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include // For JumpTable + +namespace rex::codegen { + +struct MidAsmHook { + std::string name; + std::vector registers; + + bool ret = false; + bool returnOnTrue = false; + bool returnOnFalse = false; + + uint32_t jumpAddress = 0; + uint32_t jumpAddressOnTrue = 0; + uint32_t jumpAddressOnFalse = 0; + + bool afterInstruction = false; +}; + +// Unified function/chunk configuration +// A "chunk" is simply a function entry with a non-zero parent field +struct FunctionConfig { + uint32_t size = 0; // Explicit size in bytes (mutually exclusive with end) + uint32_t end = 0; // End address, exclusive (mutually exclusive with size) + std::string name; // Custom symbol name (empty = auto-generate sub_XXXXXXXX) + uint32_t parent = 0; // Parent function address (0 = standalone, non-zero = chunk) + + // Get effective size (prefers size over end) + uint32_t getSize(uint32_t address) const { + return size ? size : (end > address ? end - address : 0); + } + // Returns true if this is a discontinuous chunk belonging to a parent function + bool isChunk() const { return parent != 0; } +}; + +// Section info for analysis output +struct SectionInfo { + std::string name; + uint64_t address = 0; + uint64_t size = 0; + std::string flags; // "rx", "rw", "r" etc. +}; + +// Function entry for analysis output +struct FunctionEntry { + uint64_t address = 0; + uint64_t size = 0; + std::string name; // optional, defaults to "sub_XXXXXXXX" +}; + +struct RecompilerConfig { + // === Required user-provided fields === + std::string projectName = "rex"; ///< Project name for output files + std::string filePath; ///< Path to XEX/ELF file + std::string outDirectoryPath; ///< Output directory for generated code + std::string templateDir; ///< Optional custom template directory for overrides + + // Patch file paths (TODO: implement patching workflow) + std::string patchFilePath; + std::string patchedFilePath; + + // === Code generation options (optional) === + bool skipLr = false; + bool ctrAsLocalVariable = false; + bool xerAsLocalVariable = false; + bool reservedRegisterAsLocalVariable = false; + bool skipMsr = false; + bool crRegistersAsLocalVariables = false; + bool nonArgumentRegistersAsLocalVariables = false; + bool nonVolatileRegistersAsLocalVariables = false; + bool generateExceptionHandlers = false; ///< Generate SEH exception handler wrappers + + // === Analysis tuning (optional) === + uint32_t maxJumpExtension = 65536; ///< Max bytes to extend function for jump table targets + uint32_t dataRegionThreshold = 16; ///< Consecutive invalid instructions to mark as data region + uint32_t largeFunctionThreshold = 1048576; ///< 1MB - warn if function exceeds this size + + // Optional override for DLL module flag. If unset, the orchestrator infers + // from the module's position in the manifest (entrypoint = false, modules = true). + std::optional isDll; + + // === Manual overrides === + std::unordered_map functions; ///< Function/chunk configuration + std::unordered_map switchTables; + std::unordered_map midAsmHooks; + uint32_t longJmpAddress = 0; + uint32_t setJmpAddress = 0; + + // === rexcrt: CRT function address overrides === + // Maps function name -> guest address (e.g. "CreateFileA" -> 0x8248B780) + // Parsed from [rexcrt] TOML table. Codegen generates rexcrt_ entries. + std::unordered_map rexcrtFunctions; + + // === User hints (merged with analysis results in AnalysisState) === + std::unordered_map invalidInstructionHints; ///< addr -> size + std::unordered_set + knownIndirectCallHints; ///< bctr addresses that are vtable/computed calls + std::vector exceptionHandlerFuncHints; ///< Additional exception handler addresses + + /** + * Load configuration from a TOML file. + * + * Supports an optional `includes` array for layered config. Paths in + * `includes` resolve relative to the including file's directory. Merge + * semantics: scalars last-wins, keyed tables additive (same key = last + * wins), arrays-of-tables deduplicated by primary key, sets additive. + * + * @param configFilePath Path to the TOML config file + * @return true on success, false on error (parse failure, circular + * include, depth exceeded) + */ + bool Load(const std::string_view& configFilePath); + + /** + * Load configuration from an in-memory TOML table (e.g. an inline binary + * entry inside a manifest). Includes referenced from the table resolve + * relative to `base_dir`. Same merge semantics as Load(). + */ + bool LoadFromTable(const toml::table& tbl, const std::filesystem::path& base_dir); + + /// Validation result containing warnings and errors. + struct ValidationResult { + bool valid = true; ///< true if no errors (warnings OK) + std::vector warnings; ///< Non-fatal issues + std::vector errors; ///< Fatal issues that block codegen + + explicit operator bool() const { return valid; } + }; + + /** + * Validate the loaded configuration. + * Checks address alignment, required fields, and sanity constraints. + * @return ValidationResult with warnings and errors + */ + ValidationResult Validate() const; +}; + +} // namespace rex::codegen diff --git a/include/rex/codegen/function_graph.h b/include/rex/codegen/function_graph.h new file mode 100644 index 0000000..171eb67 --- /dev/null +++ b/include/rex/codegen/function_graph.h @@ -0,0 +1,202 @@ +/** + * @file rex/codegen/function_graph.h + * @brief Function graph - reactive model for function discovery and resolution + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include + +namespace rex::codegen { + +//============================================================================= +// Function Graph +//============================================================================= +// Container for all function nodes. Manages resolution notifications. +// Also handles vacancy checking for merge eligibility. +// +// Vacancy Rules - A region is vacant if ALL are true: +// 1. No null dword at the boundary +// 2. No chunk claims the region +// 3. Target does not fall within a protected function's range: +// - PDATA/CONFIG/HELPER: always protected (cannot merge into) +// - DISCOVERED with xrefs: CAN be merged (treated as potential internal label) + +class FunctionGraph { + public: + using MemoryReader = std::function(uint32_t addr)>; + + //========================================================================= + // Code Buffer Management + //========================================================================= + + // Add a code buffer (copies executable section data into graph) + void addCodeBuffer(uint32_t baseAddress, const uint8_t* data, size_t size); + + // Translate guest address to host pointer (searches all code buffers) + const uint8_t* translateCode(uint32_t addr) const; + + // Get all code buffers (for iteration/debugging) + const std::vector& codeBuffers() const { return codeBuffers_; } + + // Update all function code pointers (call after loading code buffers) + void updateFunctionCodePointers(); + + //========================================================================= + // Function Management + //========================================================================= + + // Add a function to the graph. + // Returns the new node, or existing node if already present (higher authority wins). + // Notifies all PENDING functions to try resolution against the new entry. + // hasXrefs: true if this is a known call target (bl target, etc.) + FunctionNode* addFunction(uint32_t base, uint32_t size, FunctionAuthority authority, + bool hasXrefs = false); + + // Add a named function to the graph (convenience overload) + FunctionNode* addFunction(uint32_t base, uint32_t size, FunctionAuthority authority, + std::string_view name, bool hasXrefs = false); + + // Add a resolved import as a callable function with __imp__ name + // Address is the thunk address that bl instructions target + FunctionNode* addImportFunction(uint32_t address, std::string_view resolvedName); + + // Get function by entry point (O(1)) + FunctionNode* getFunction(uint32_t entryPoint); + const FunctionNode* getFunction(uint32_t entryPoint) const; + + // Remove function from graph (for cleanup of absorbed GAP_FILLs) + bool removeFunction(uint32_t entryPoint); + + // Get function containing address (O(log f) via sorted base index) + FunctionNode* getFunctionContaining(uint32_t addr); + const FunctionNode* getFunctionContaining(uint32_t addr) const; + + // Check if address is a known entry point + bool isEntryPoint(uint32_t addr) const; + + // Check if address is an import (FunctionNode with IMPORT authority) + bool isImport(uint32_t addr) const; + + // Iterate all functions (includes imports with IMPORT authority) + const std::unordered_map>& functions() const { + return functions_; + } + + // Get all PENDING functions + std::vector getPendingFunctions(); + + // Get all SEALED functions + std::vector getSealedFunctions(); + + // Statistics + size_t functionCount() const { return functions_.size(); } + size_t pendingCount() const; + size_t sealedCount() const; + + //========================================================================= + // Function Setup (called during Discover phase) + //========================================================================= + + // Set function name + void setFunctionName(uint32_t entry, std::string name); + + // Set exception handler flag + void setFunctionHasExceptionHandler(uint32_t entry, bool val); + + // Set parsed exception info (SEH or C++ EH) + void setFunctionExceptionInfo(uint32_t entry, ExceptionInfo info); + + // Add a block to a function + void addBlockToFunction(uint32_t entry, Block block); + + // Add a label (internal branch target) to a function + void addLabelToFunction(uint32_t entry, uint32_t label); + + // Add a resolved call to a function + void addCallToFunction(uint32_t entry, uint32_t site, CallTarget target); + + // Add a resolved tail call to a function + void addTailCallToFunction(uint32_t entry, uint32_t site, CallTarget target); + + // Add a jump table to a function + void addJumpTableToFunction(uint32_t entry, JumpTable jt); + + // Add an unresolved jump to a function + // isCall: true for bl (call), false for b (tail call) + void addUnresolvedJumpToFunction(uint32_t entry, uint32_t site, uint32_t target, bool isCall, + bool conditional); + + //========================================================================= + // Resolution and Expansion (called during Merge phase) + //========================================================================= + + // Try to resolve all unresolved jumps for a function + // Checks against known functions, imports, and internal labels + // Returns number of jumps resolved + size_t tryResolveFunction(uint32_t entry); + + // Absorb a region into a function (for vacancy expansion) + void absorbRegionIntoFunction(uint32_t entry, uint32_t regionBase, uint32_t regionSize); + + // Seal a function if it can be sealed + // Returns true if function was sealed + bool trySealFunction(uint32_t entry); + + // Seal all functions that can be sealed + // Returns number of functions sealed + size_t sealAllReady(); + + // Seal all functions, throwing if any cannot be sealed + // Use after discovery is complete to enforce all functions are ready + void sealAll(); + + //========================================================================= + // Vacancy Checking + //========================================================================= + + // Set the memory reader for null-dword checking + void setMemoryReader(MemoryReader reader) { memoryReader_ = std::move(reader); } + + // Register a chunk (address range claimed by config, blocks vacancy) + void registerChunk(uint32_t base, uint32_t size); + + // Check if a region is vacant for absorption + // fromAddr: the address we're expanding from (to check for null boundary) + // targetAddr: the start of the region we want to absorb + bool isVacant(uint32_t fromAddr, uint32_t targetAddr) const; + + // Check if target is a mergeable entry point (DISCOVERED with xrefs) + bool isMergeableEntryPoint(uint32_t addr) const; + + //========================================================================= + // Target Classification (for code generation) + //========================================================================= + + // Classify a branch target for code generation. + // target: address being branched to + // callerAddr: address of the branch instruction + // isCallInstruction: true for bl (expects return), false for b (no return) + // Returns how the target should be treated during code generation. + TargetKind classifyTarget(uint32_t target, uint32_t callerAddr, bool isCallInstruction) const; + + private: + std::vector codeBuffers_; + std::unordered_map> functions_; + std::map + functionsByBase_; // sorted by base for O(log f) interval lookup + std::unordered_map functionHasXrefs_; // entry -> hasXrefs + std::vector> chunks_; // base, size pairs + MemoryReader memoryReader_; + + // Notify all PENDING functions that a new function was added + void notifyFunctionAdded(FunctionNode* newFunction); +}; + +} // namespace rex::codegen diff --git a/include/rex/codegen/function_node.h b/include/rex/codegen/function_node.h new file mode 100644 index 0000000..a335b37 --- /dev/null +++ b/include/rex/codegen/function_node.h @@ -0,0 +1,203 @@ +/** + * @file rex/codegen/function_node.h + * @brief FunctionNode - core object representing a function in the graph + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include + +namespace rex::codegen { + +//============================================================================= +// Function Node +//============================================================================= +// Core object representing a function in the graph. +// Manages its own state transitions and resolution. + +class FunctionNode { + friend class FunctionGraph; // Graph manages all mutations + + public: + FunctionNode(uint32_t base, uint32_t size, FunctionAuthority authority); + + //========================================================================= + // Read-only accessors - external code can inspect but not modify + //========================================================================= + + // Identity + uint32_t base() const { return base_; } + uint32_t size() const { return size_; } + uint32_t end() const { return base_ + size_; } + const std::string& name() const { return name_; } + + // Code access - cached pointer to instruction bytes + const uint8_t* code() const { return code_; } + bool hasCode() const { return code_ != nullptr; } + + // Authority and state + FunctionAuthority authority() const { return authority_; } + FunctionState state() const { return state_; } + + // State queries + bool isRegistered() const { return state_ == FunctionState::kRegistered; } + bool isDiscovered() const { return state_ == FunctionState::kDiscovered; } + bool isSealed() const { return state_ == FunctionState::kSealed; } + + // Legacy aliases (PENDING maps to kRegistered OR kDiscovered - not sealed) + bool isPending() const { return state_ != FunctionState::kSealed; } + + // Special type checks + bool isImport() const { return authority_ == FunctionAuthority::IMPORT; } + bool isHelper() const { return authority_ == FunctionAuthority::HELPER; } + + //========================================================================= + // State Machine - New 3-state model + //========================================================================= + + /// Can transition from kRegistered to kDiscovered? + bool canDiscover() const { return state_ == FunctionState::kRegistered; } + + /// Transition kRegistered -> kDiscovered with blocks and instructions + /// Precondition: canDiscover() returns true + /// For non-imports: blocks must not be empty + void discover(std::vector blocks, + std::vector instructions, + std::set labels); + + /// Transition kRegistered -> kDiscovered for import functions (no blocks) + void discoverAsImport(); + + /// Can transition from kDiscovered to kSealed? + /// Returns true if: + /// - state == kDiscovered + /// - imports: always OK (no blocks required) + /// - non-imports: blocks not empty AND no unresolved branches + bool canSeal() const; + + /// Transition kDiscovered -> kSealed + /// Computes FunctionAnalysis and sorts blocks + void seal(); + + /// Get analysis result (only valid after seal) + const FunctionAnalysis& analysis() const; + + //========================================================================= + // Code Emission (valid after seal) + //========================================================================= + + /// Emit C++ code for this function + /// Requires: state() == kSealed + /// For imports: emits REX_IMPORT macro + /// For normal functions: emits REX_FUNC with blocks and instructions + std::string emitCpp(const EmitContext& ctx) const; + + //========================================================================= + // Instruction access (valid after discover) + //========================================================================= + + /// Get owned instructions (pointers into DecodedBinary) + std::span instructions() const { return instructions_; } + + // Blocks + const std::vector& blocks() const { return blocks_; } + bool containsAddress(uint32_t addr) const; + + // Check if address is within overall function bounds (ignores blocks) + // Use this for branch target detection where address may be in a gap between blocks + bool isWithinBounds(uint32_t addr) const { return addr >= base_ && addr < base_ + size_; } + + // Labels (internal branch targets within this function) + const std::set& labels() const { return labels_; } + bool isLabel(uint32_t addr) const { return labels_.contains(addr); } + + // Resolved calls (bl instructions) + const std::vector& calls() const { return calls_; } + + // Resolved tail calls (b instructions to other functions) + const std::vector& tailCalls() const { return tailCalls_; } + + // Jump tables + const std::vector& jumpTables() const { return jumpTables_; } + + // Unresolved jumps (pending resolution) + const std::vector& unresolvedJumps() const { return unresolvedJumps_; } + + // Sealing state (legacy - use canSeal() with new semantics) + bool hasUnresolvedJumps() const { return !unresolvedJumps_.empty(); } + + // Validation + bool hasExceptionHandler() const { return hasExceptionHandler_; } + + // Exception info (SEH or C++ EH) + const std::optional& exceptionInfo() const { return exceptionInfo_; } + bool hasExceptionInfo() const { return exceptionInfo_.has_value() && exceptionInfo_->hasInfo(); } + + void setName(std::string name) { name_ = std::move(name); } + + private: + //========================================================================= + // Mutation methods - only FunctionGraph can call these + //========================================================================= + + void setCode(const uint8_t* ptr) { code_ = ptr; } + void setHasExceptionHandler(bool val) { hasExceptionHandler_ = val; } + void setExceptionInfo(ExceptionInfo info) { exceptionInfo_ = std::move(info); } + + // Block/label management + void addBlock(Block block); + void addLabel(uint32_t addr); + + // Call tracking + void addCall(uint32_t site, CallTarget target); + void addTailCall(uint32_t site, CallTarget target); + void addJumpTable(JumpTable jt); + void addUnresolvedJump(uint32_t site, uint32_t target, bool isCall, bool conditional); + + // Resolution (reactive - called by graph on events) + bool tryResolveAgainst(FunctionNode* newFunction); + bool tryResolveAgainstImport(uint32_t importAddr, const std::string& importName); + bool tryResolveAsInternalLabel(uint32_t target); + + // Expansion + void absorbRegion(uint32_t regionBase, uint32_t regionSize); + + // Internal helper + void removeUnresolvedJump(uint32_t site); + + //========================================================================= + // State + //========================================================================= + private: + uint32_t base_; + uint32_t size_; + std::string name_; + const uint8_t* code_ = nullptr; // Cached pointer to instruction bytes + FunctionAuthority authority_; + FunctionState state_ = FunctionState::kRegistered; + bool hasExceptionHandler_ = false; + + // Populated at discover() + std::vector blocks_; + std::vector instructions_; // Pointers into DecodedBinary + std::set labels_; // Branch targets within this function + + std::vector calls_; + std::vector tailCalls_; + std::vector jumpTables_; + + std::vector unresolvedJumps_; + + std::optional exceptionInfo_; + + // Computed at seal() + std::optional analysis_; +}; + +} // namespace rex::codegen diff --git a/include/rex/codegen/function_scanner.h b/include/rex/codegen/function_scanner.h new file mode 100644 index 0000000..ccd10fd --- /dev/null +++ b/include/rex/codegen/function_scanner.h @@ -0,0 +1,283 @@ +/** + * @file rex/codegen/function_scanner.h + * @brief Function scanner and block discovery + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include +#include // For FunctionAuthority, TargetKind +#include +#include + +namespace rex::codegen { + +// Forward declarations +struct CodeRegion; +class BinaryView; +class DecodedBinary; + +// FunctionAuthority is defined in function_graph.h + +//============================================================================= +// Block-Based Discovery Types +//============================================================================= + +/** + * Basic block discovered during recursive block discovery. + * Used as temporary scanner state during discovery when function extent is unknown. + * Converted to FunctionNode::Block when added to the graph. + * + * projectedSize: Size limit for conditional branch fall-through. + * When a conditional branch is taken, the fall-through block gets a projectedSize + * equal to the distance to the branch target. This prevents the fall-through from + * consuming unrelated code beyond the branch target. + */ +struct DiscoveredBlock { + rex::guest_addr_t base = 0; // Start address + rex::guest_addr_t end = 0; // End address (exclusive, points after last instruction) + bool has_terminator = false; // Ends with blr/bctr/unconditional branch + int64_t projectedSize = + -1; // Size limit (-1 = unlimited), set on conditional branch fall-through + std::vector successors; // Branch targets (for CFG building) +}; + +/** + * Result of block-based function discovery. + * Contains all blocks reachable from entry point. + */ +struct FunctionBlocks { + rex::guest_addr_t entry = 0; // Function entry point + std::vector blocks; // All discovered blocks + rex::u32 pdata_size = 0; // From pdata (0 if unknown) + std::vector jump_tables; // Detected jump tables + std::vector external_calls; // bl targets outside this function + std::vector tail_calls; // Unconditional branches to other functions +}; + +//============================================================================= +// Function Scanner +//============================================================================= + +/** + * PowerPC function scanner + * + * Implements heuristics for function boundary detection: + * - Linear sweep from entry point + * - Furthest branch target tracking + * - Return/indirect branch detection + * - Prologue/epilogue pattern matching + * + * Uses BinaryView for binary introspection. + */ +class FunctionScanner { + public: + explicit FunctionScanner(const BinaryView& binary); + + /** + * Detect jump table pattern at bctr instruction + * @param bctr_address Address of the bctr instruction + * @return JumpTable on success, nullopt if no jump table detected + */ + std::optional detect_jump_table(rex::guest_addr_t bctr_address); + + /** + * Discover all reachable blocks from entry point. + * Uses recursive block discovery with pending stack. + * @param entry_point Function entry point address + * @param pdata_size Optional size from .pdata (0 if unknown) + * @return FunctionBlocks containing all discovered blocks + */ + FunctionBlocks discover_blocks(rex::guest_addr_t entry_point, rex::u32 pdata_size = 0); + + // Address translation via Module's Memory + template + const T* translate_address(rex::guest_addr_t guest_addr) const; + + // Check if address is in an executable section + bool isExecutableSection(rex::guest_addr_t address) const; + + // Set known switch table addresses (from config) to skip auto-detection + void setKnownSwitchTables(const std::unordered_set& addresses) { + known_switch_tables_ = addresses; + } + + // Set discontinuous function chunks (chunk_addr -> FunctionConfig with parent set) + void setChunks(const std::unordered_map& chunks) { chunks_ = chunks; } + + // Set bl targets that need resolution (for Fix 4: shared helper promotion) + void setBlTargets(const std::unordered_set& targets) { bl_targets_ = targets; } + + // Get collected bl targets from discovery + const std::unordered_set& getBlTargets() const { return bl_targets_; } + + void setKnownCallables(const std::unordered_set& callables) { + known_callables_ = callables; + } + + bool isKnownCallable(uint32_t address) const { return known_callables_.contains(address); } + + void setDataRegions(const std::vector>& regions) { + data_regions_ = regions; + } + + bool isInDataRegion(uint32_t address) const { + for (const auto& [start, end] : data_regions_) { + if (address >= start && address < end) + return true; + } + return false; + } + + // Set code regions for boundary checking (prevents cross-region merges) + void setCodeRegions(const std::vector* regions) { code_regions_ = regions; } + + // Find which code region contains the given address (nullptr if not found) + const CodeRegion* findRegionContaining(uint32_t address) const; + + /** + * Check if a branch from currentAddr to targetAddr stays within the same + * code region OR targets a configured chunk of the current function. + * Used to determine if a branch is internal or a tail call. + * + * @param currentAddr Address of the branch instruction + * @param targetAddr Branch target address + * @param functionEntry Entry point of the current function being discovered + * @return true if the branch should be treated as internal + */ + bool isInternalBranch(uint32_t currentAddr, uint32_t targetAddr, uint32_t functionEntry) const; + + // Check if an address is within a chunk belonging to the given function + bool isWithinChunk(uint32_t address, uint32_t function_entry) const { + for (const auto& [chunk_start, cfg] : chunks_) { + if (cfg.parent == function_entry) { + uint32_t chunk_end = + cfg.end ? cfg.end : (cfg.size ? chunk_start + cfg.size : chunk_start + 0x1000); + if (address >= chunk_start && address < chunk_end) { + return true; + } + } + } + return false; + } + + // Find chunk parent for an address (returns 0 if not in any chunk) + uint32_t findChunkParent(uint32_t address) const { + // First check exact chunk start matches + auto it = chunks_.find(address); + if (it != chunks_.end()) { + return it->second.parent; + } + // Then check if address is within any chunk range + for (const auto& [chunk_start, cfg] : chunks_) { + uint32_t chunk_end = + cfg.end ? cfg.end : (cfg.size ? chunk_start + cfg.size : chunk_start + 0x1000); + if (address >= chunk_start && address < chunk_end) { + return cfg.parent; + } + } + return 0; + } + + private: + const BinaryView* binary_ = nullptr; + std::unordered_set known_switch_tables_; + std::unordered_map chunks_; + std::unordered_set bl_targets_; + std::unordered_set known_callables_; + std::vector> data_regions_; + const std::vector* code_regions_ = nullptr; + + // Helper methods for function boundary detection + bool is_prologue_pattern(rex::guest_addr_t address); + bool is_epilogue_pattern(rex::guest_addr_t address); + bool is_restgprlr_function(rex::guest_addr_t address); +}; + +//============================================================================= +// Block Discovery Result +//============================================================================= + +struct UnresolvedBranch { + uint32_t site; // Address of branch instruction + uint32_t target; // Target address + bool isCall; // true = bl (call), false = b (tail/jump) + bool isConditional; // true = bc/beq/etc, false = unconditional +}; + +struct BlockDiscoveryResult { + std::vector blocks; + std::vector unresolvedBranches; + std::vector jumpTables; + std::set labels; + + // Collected instruction pointers (for FunctionNode ownership) + std::vector instructions; + + // External references found during discovery + std::vector externalCalls; // bl to unknown targets + std::vector tailCalls; // b to external targets +}; + +//============================================================================= +// Block Discovery Function +//============================================================================= + +/** + * Discover all blocks belonging to a function starting at entryPoint. + * + * Algorithm: + * - Worklist-based block discovery + * - Linear sweep until terminator (blr, bctr, unconditional b) + * - Follow both paths for conditional branches + * - Detect jump tables at bctr instructions + * - Stop at code region boundaries (null padding) + * + * @param decoded The decoded binary (single-pass decoded instructions) + * @param entryPoint Starting address of the function + * @param containingRegion Code region containing the entry point + * @param knownFunctions Set of known function entry points (to detect tail calls) + * @return BlockDiscoveryResult containing blocks, branches, and jump tables + */ +BlockDiscoveryResult discoverBlocks(DecodedBinary& decoded, uint32_t entryPoint, + const CodeRegion& containingRegion, + const std::unordered_set& knownFunctions, + uint32_t pdataSize = 0); + +//============================================================================= +// Jump Table Detection +//============================================================================= + +/** + * Detect jump table at a bctr instruction. + * + * Patterns detected: + * - ABSOLUTE: lwzx loads full 32-bit addresses + * - COMPUTED: lbzx + rlwinm (byte offset with shift) + * - BYTEOFFSET: lbzx + add (byte offset direct) + * - SHORTOFFSET: lhzx + add (16-bit offset) + * + * @param decoded The decoded binary + * @param bctrAddr Address of the bctr instruction + * @param containingRegion Code region for validation + * @return JumpTable if detected, empty optional otherwise + */ +std::optional detectJumpTable(DecodedBinary& decoded, uint32_t bctrAddr, + const CodeRegion& containingRegion, uint32_t funcStart, + uint32_t funcEnd); + +} // namespace rex::codegen diff --git a/include/rex/codegen/function_types.h b/include/rex/codegen/function_types.h new file mode 100644 index 0000000..ef36b6a --- /dev/null +++ b/include/rex/codegen/function_types.h @@ -0,0 +1,295 @@ +/** + * @file rex/codegen/function_types.h + * @brief Types and structures used by FunctionNode and FunctionGraph + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace rex::codegen::ppc { +struct Instruction; +} // namespace rex::codegen::ppc + +namespace rex::runtime { +class ExportResolver; +} // namespace rex::runtime + +namespace rex::codegen { + +// Forward declarations +class FunctionGraph; +class FunctionNode; +class BinaryView; +struct RecompilerConfig; + +/// Lightweight context passed to FunctionNode::emitCpp() and BuilderContext. +/// Non-owning references -- caller must ensure lifetimes. +struct EmitContext { + const BinaryView& binary; + const RecompilerConfig& config; + const FunctionGraph& graph; + uint32_t entryPoint = 0; ///< For "xstart" naming + runtime::ExportResolver* resolver = nullptr; ///< For import ordinal resolution (nullable) +}; + +//============================================================================= +// Authority Levels +//============================================================================= +// Determines boundary mutability and merge eligibility. +// Only GAP_FILL can be absorbed during vacancy merging. +// All others represent immutable entry points. +enum class FunctionAuthority : uint8_t { + GAP_FILL = 0, // Speculative - found in unclaimed gap, CAN be absorbed + DISCOVERED = 1, // Found via bl/bcl - immutable entry point + VTABLE = 2, // Found in vtable - immutable entry point + HELPER = 3, // Save/restore helpers - fixed, overlaps allowed + PDATA = 4, // From .pdata - entry fixed, can extend + CONFIG = 5, // User config - exact boundaries, immutable + IMPORT = 6, // Import thunk - external function, immutable +}; + +//============================================================================= +// Target Classification (for code generation) +//============================================================================= +enum class TargetKind { + InternalLabel, // Target inside caller's function (PIC pattern) + Function, // Target is a function entry point + Import, // Target is an import + Unknown, // Target not recognized +}; + +const char* AuthorityName(FunctionAuthority auth); + +//============================================================================= +// Function State (3-state machine) +//============================================================================= +enum class FunctionState : uint8_t { + kRegistered, // Entry point known, blocks/instructions not yet assigned + kDiscovered, // Blocks and instructions assigned, may have unresolved branches + kSealed, // All branches resolved, ready for code generation +}; + +// Legacy aliases for compatibility during migration +constexpr FunctionState PENDING = FunctionState::kRegistered; // Will be removed +constexpr FunctionState SEALED = FunctionState::kSealed; // Will be removed + +//============================================================================= +// Exception Handling - SEH (Structured Exception Handling) +//============================================================================= + +struct SehScope { + uint32_t tryStart; // [+0] Start of __try block + uint32_t tryEnd; // [+4] End of __try block + uint32_t handler; // [+8] Handler function (__finally or __except body) + uint32_t filter; // [+C] Filter expression (0 for __finally, address for __except) +}; + +struct SehExceptionInfo { + uint32_t handlerThunk; // e.g. __C_specific_handler thunk address + uint32_t scopeTableAddr; // Pointer to scope table in .rdata + std::vector scopes; + uint32_t frameSize = 0; // Stack frame size for r12 setup during unwind + uint32_t restoreHelper = 0; // __restgprlr_N address to call on unwind +}; + +//============================================================================= +// Exception Handling - C++ EH (FuncInfo with magic 0x19930522) +//============================================================================= + +constexpr uint32_t CXX_EH_MAGIC = 0x19930522; + +struct CxxUnwindEntry { + int32_t toState; // Previous state (-1 = terminal) + uint32_t action; // Cleanup/destructor function address +}; + +struct CxxIPStateEntry { + uint32_t ip; // Code address where state changes + int32_t state; // State number at this IP +}; + +struct CxxCatchHandler { + uint32_t adjectives; // Catch type flags + uint32_t typeDescriptor; // Pointer to type descriptor (RTTI) + int32_t catchObjDisplacement; // Displacement of catch object + uint32_t handlerAddress; // Catch handler function address +}; + +struct CxxTryBlock { + int32_t tryLow; // Lowest state in try + int32_t tryHigh; // Highest state in try + int32_t catchHigh; // Highest state in catch + std::vector handlers; +}; + +struct CxxExceptionInfo { + uint32_t handlerThunk; // Frame handler function + uint32_t funcInfoAddr; // Address of FuncInfo in .rdata + uint32_t maxState; // Number of unwind states + std::vector unwindMap; + std::vector tryBlocks; + std::vector ipToStateMap; +}; + +//============================================================================= +// Combined Exception Info (variant of SEH or C++ EH) +//============================================================================= + +struct ExceptionInfo { + std::variant data; + + bool hasInfo() const { return !std::holds_alternative(data); } + bool isSeh() const { return std::holds_alternative(data); } + bool isCxx() const { return std::holds_alternative(data); } + + const SehExceptionInfo* asSeh() const { return std::get_if(&data); } + const CxxExceptionInfo* asCxx() const { return std::get_if(&data); } + + uint32_t handlerThunk() const { + if (auto* seh = asSeh()) + return seh->handlerThunk; + if (auto* cxx = asCxx()) + return cxx->handlerThunk; + return 0; + } +}; + +//============================================================================= +// Call Target - Resolved destination of a call/jump +//============================================================================= +struct CallTarget { + struct ToFunction { + FunctionNode* node; + }; + struct ToImport { + uint32_t address; + std::string name; + }; + struct Unresolved { + uint32_t address; + }; + + std::variant value; + + bool isResolved() const { return !std::holds_alternative(value); } + bool isFunction() const { return std::holds_alternative(value); } + bool isImport() const { return std::holds_alternative(value); } + + FunctionNode* asFunction() const { + if (auto* f = std::get_if(&value)) + return f->node; + return nullptr; + } + + static CallTarget function(FunctionNode* fn) { return {ToFunction{fn}}; } + static CallTarget import(uint32_t addr, std::string name) { + return {ToImport{addr, std::move(name)}}; + } + static CallTarget unresolved(uint32_t addr) { return {Unresolved{addr}}; } +}; + +//============================================================================= +// Call Edge - A call site within a function +//============================================================================= + +struct CallEdge { + uint32_t site; // Address of the bl/b instruction + CallTarget target; // Resolved or unresolved target +}; + +//============================================================================= +// Basic Block +//============================================================================= + +struct Block { + uint32_t base; + uint32_t size; + + uint32_t end() const { return base + size; } + bool contains(uint32_t addr) const { return addr >= base && addr < end(); } +}; + +//============================================================================= +// Jump Table +//============================================================================= + +struct JumpTable { + uint32_t bctrAddress; // Address of bctr instruction + uint32_t tableAddress; // Address of jump table data + uint8_t indexRegister; // Register holding switch index + std::vector targets; // Resolved case targets (internal labels) +}; + +//============================================================================= +// Function Analysis (computed at seal time) +//============================================================================= + +struct FunctionAnalysis { + // CSR requirements (denormal handling) + enum class CsrRequirement : uint8_t { None, Fpu, Vmx }; + + // Special register usage + bool usesCtr = false; + bool usesXer = false; + bool usesCr = false; + bool usesFpscr = false; + + // CSR state needed + CsrRequirement csrRequirement = CsrRequirement::None; +}; + +//============================================================================= +// Unresolved Jump - Internal jump awaiting resolution +//============================================================================= + +struct UnresolvedJump { + uint32_t site; // Address of the branch instruction + uint32_t target; // Target address + bool isCall; // true = bl (call), false = b (tail call) + bool isConditional; // true = bc/beq/bne/etc, false = b +}; + +//============================================================================= +// Code Buffer - Holds executable code for a section +//============================================================================= +// The graph owns code buffers so recompilation doesn't need module access. +// Each buffer corresponds to one executable section. + +struct CodeBuffer { + std::vector data; + uint32_t baseAddress = 0; + + uint32_t size() const { return static_cast(data.size()); } + uint32_t endAddress() const { return baseAddress + size(); } + + bool contains(uint32_t addr) const { return addr >= baseAddress && addr < endAddress(); } + + const uint8_t* translate(uint32_t addr) const { + if (!contains(addr)) + return nullptr; + return data.data() + (addr - baseAddress); + } +}; + +} // namespace rex::codegen diff --git a/include/rex/codegen/manifest.h b/include/rex/codegen/manifest.h new file mode 100644 index 0000000..395d65d --- /dev/null +++ b/include/rex/codegen/manifest.h @@ -0,0 +1,70 @@ +/** + * @file rex/codegen/manifest.h + * @brief Manifest TOML parser for multi-binary projects + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include + +namespace rex::codegen { + +/** + * Codegen settings for a single binary inside a manifest. The entrypoint + * uses an empty `guestPath`; module entries set it to the canonicalized + * guest-visible path the host runtime resolves against. + */ +struct BinaryConfig { + RecompilerConfig recompiler; + std::string guestPath; +}; + +/** + * Canonicalize a module guest path: device-stripped, slashes/case normalized, + * with `/assets/` stripped when a matching project name is given. + */ +std::string CanonicalizeModuleGuestPath(std::string_view path, std::string_view project_name = {}); + +/** + * Parsed manifest TOML. Construct via Load(); treat as read-only after. + */ +struct ManifestConfig { + std::string projectName; + std::optional sdkVersion; ///< Last SDK that ran codegen on this project + std::optional gameRoot; ///< Game asset root, relative to manifestDir. + ///< Set by `rexglue init` to anchor DLL guest paths. + std::filesystem::path manifestDir; ///< Directory containing the manifest + BinaryConfig entrypoint; ///< Entrypoint codegen settings (inline) + std::vector modules; ///< DLL module codegen settings (inline) + + /** + * Load a manifest TOML file. Returns nullopt on parse failure. + */ + static std::optional Load(const std::filesystem::path& path); + + /** + * True when `path` parses as a manifest (i.e. has a `[project]` section). + */ + static bool IsManifest(const std::filesystem::path& path); + + /** + * Insert or overwrite [project].sdk_version in the manifest file at `path`. + * Preserves the rest of the file's content. Returns false on parse or write + * failure. + */ + static bool WriteSdkVersionStamp(const std::filesystem::path& path, std::string_view version); +}; + +} // namespace rex::codegen diff --git a/include/rex/codegen/phases.h b/include/rex/codegen/phases.h new file mode 100644 index 0000000..e96f7ec --- /dev/null +++ b/include/rex/codegen/phases.h @@ -0,0 +1,40 @@ +/** + * @file rexcodegen/phases.h + * @brief Analysis phase entry points + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include + +#include +#include +#include + +namespace rex::codegen::phases { + +/// Register PDATA, CONFIG, helpers, imports into FunctionGraph +VoidResult Register(CodegenContext& ctx, ProgressReporter* reporter = nullptr); + +/// Scan binary for bl targets, thunks, bctr locations +VoidResult Scan(CodegenContext& ctx, ProgressReporter* reporter = nullptr); + +/// Discover function blocks from candidates +VoidResult Discover(CodegenContext& ctx, ProgressReporter* reporter = nullptr); + +/// Vacancy-based function expansion and sealing +VoidResult Merge(CodegenContext& ctx, ProgressReporter* reporter = nullptr); + +/// Find uncovered code regions and register them as functions +VoidResult GapFill(CodegenContext& ctx, ProgressReporter* reporter = nullptr); + +/// Validate all call targets resolve +VoidResult Validate(CodegenContext& ctx, ProgressReporter* reporter = nullptr); + +} // namespace rex::codegen::phases diff --git a/include/rex/codegen/progress_reporter.h b/include/rex/codegen/progress_reporter.h new file mode 100644 index 0000000..fdaacd3 --- /dev/null +++ b/include/rex/codegen/progress_reporter.h @@ -0,0 +1,49 @@ +/** + * @file rex/codegen/progress_reporter.h + * @brief Abstract callback interface for codegen pipeline progress + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include + +namespace rex::codegen { + +/** + * Optional progress callback invoked by the codegen pipeline at module + * and phase boundaries. CLI consumers implement this to drive a progress + * view; library-internal callers (tests, headless callers) can pass + * nullptr to opt out. + * + * All methods are called from the thread that drove the pipeline; no + * cross-thread synchronization is implied. + */ +class ProgressReporter { + public: + virtual ~ProgressReporter() = default; + + /** A new module's analysis+write cycle is starting. `index` is 0-based. */ + virtual void moduleStarted(std::string_view name, std::size_t index, std::size_t total) = 0; + + /** A named phase within the current module is starting. */ + virtual void phaseChanged(std::string_view name) = 0; + + /** The current module finished successfully. */ + virtual void moduleFinished(std::chrono::milliseconds elapsed) = 0; + + /** Project-level (non-module) emit phase started, e.g. "module_registry". */ + virtual void projectPhaseStarted(std::string_view name) = 0; + + /** Project-level emit phase finished. */ + virtual void projectPhaseFinished() = 0; +}; + +} // namespace rex::codegen diff --git a/include/rex/codegen/project_recompiler.h b/include/rex/codegen/project_recompiler.h new file mode 100644 index 0000000..ece295f --- /dev/null +++ b/include/rex/codegen/project_recompiler.h @@ -0,0 +1,53 @@ +/** + * @file rex/codegen/project_recompiler.h + * @brief Project-level recompiler driving manifest-based multi-binary codegen + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include + +#include +#include +#include + +namespace rex::codegen { + +struct ProjectRecompilerOptions { + std::vector targets; // empty = all + bool force = false; + bool enableExceptionHandlers = false; + ProgressReporter* reporter = nullptr; +}; + +class ProjectRecompiler { + public: + explicit ProjectRecompiler(ManifestConfig manifest); + Result Run(const ProjectRecompilerOptions& opts); + + /** + * Aggregated basenames of files removed across all modules during the most + * recent Run() call. Empty until Run() completes successfully. + */ + const std::vector& deletedFiles() const { return deletedFiles_; } + + /** + * Aggregated basenames of files written across all modules during the most + * recent Run() call. Empty until Run() completes successfully. + */ + const std::vector& writtenFiles() const { return writtenFiles_; } + + private: + ManifestConfig manifest_; + std::vector deletedFiles_; + std::vector writtenFiles_; +}; + +} // namespace rex::codegen diff --git a/include/rex/codegen/sig_scanner.h b/include/rex/codegen/sig_scanner.h new file mode 100644 index 0000000..3eee67f --- /dev/null +++ b/include/rex/codegen/sig_scanner.h @@ -0,0 +1,67 @@ +/** + * @file rex/codegen/sig_scanner.h + * @brief Signature scanner for pattern-based function discovery + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include + +namespace rex::codegen { + +//============================================================================= +// Signature - Pattern definition for matching +//============================================================================= +// Dword-based patterns follow PPC's per-instruction size. +// Each pattern word is matched against memory using the corresponding mask. +// A mask of 0xFFFFFFFF means exact match; partial masks allow wildcards. + +struct Signature { + std::string name; // e.g., "__savegprlr_14" + std::vector pattern; // Instruction words to match + std::vector mask; // Bits that must match (0xFFFFFFFF = exact) + size_t entryOffset = 0; // Offset from pattern start to entry point + std::optional size; // Known size, or nullopt to compute from pattern +}; + +//============================================================================= +// SigScanner - Pattern-based signature matcher +//============================================================================= + +class SigScanner { + public: + explicit SigScanner(const runtime::Module& module); + + // Scan for a single signature, return all match entry points + std::vector scan(const Signature& sig); + + // Scan for multiple signatures at once (more efficient - single pass) + std::unordered_map> scanAll( + const std::vector& sigs); + + // Built-in signature sets + static std::vector helperSignatures(); // __save/__restore helpers + static std::vector hleSignatures(); // memset, memmove, etc. (future) + + private: + const runtime::Module& module_; + + // Scan a single range for a pattern + std::vector scanRange(uint32_t start, uint32_t end, + const std::vector& pattern, + const std::vector& mask, size_t entryOffset); +}; + +} // namespace rex::codegen diff --git a/include/rex/codegen/template_registry.h b/include/rex/codegen/template_registry.h new file mode 100644 index 0000000..415c172 --- /dev/null +++ b/include/rex/codegen/template_registry.h @@ -0,0 +1,69 @@ +/** + * @file rex/codegen/template_registry.h + * @brief Template registry for inja-based code generation + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace rex::codegen { + +/// Exception thrown on template parse or render errors. +class TemplateError : public std::runtime_error { + public: + TemplateError(const std::string& templateId, const std::string& message, + const std::string& source = "embedded"); + + const std::string& templateId() const { return templateId_; } + const std::string& source() const { return source_; } + + private: + std::string templateId_; + std::string source_; +}; + +/// Resolves and renders inja templates by canonical ID. +/// Supports embedded defaults with optional filesystem overrides. +/// +/// Uses pimpl to keep inja.hpp and nlohmann/json.hpp out of this header. +/// The render() method accepts serialized JSON (const std::string&) to avoid +/// exposing nlohmann::json in the public API. +class TemplateRegistry { + public: + TemplateRegistry(); + ~TemplateRegistry(); + + TemplateRegistry(const TemplateRegistry&) = delete; + TemplateRegistry& operator=(const TemplateRegistry&) = delete; + TemplateRegistry(TemplateRegistry&&) noexcept; + TemplateRegistry& operator=(TemplateRegistry&&) noexcept; + + /// Load overrides from a directory. Files that don't match + /// a known canonical ID produce a warning log. + void loadOverrides(const std::filesystem::path& dir); + + /// Render a template by canonical ID with JSON data (as serialized string). + /// @throws TemplateError on parse or render failure + std::string render(const std::string& id, const std::string& jsonData); + + /// Render from raw template string (for testing). Not tied to a canonical ID. + std::string renderString(const std::string& templateContent, const std::string& jsonData); + + /// List all registered canonical IDs. + std::vector registeredIds() const; + + private: + struct Impl; + std::unique_ptr impl_; +}; + +} // namespace rex::codegen diff --git a/include/rex/codegen/test_support.h b/include/rex/codegen/test_support.h new file mode 100644 index 0000000..afeba30 --- /dev/null +++ b/include/rex/codegen/test_support.h @@ -0,0 +1,84 @@ +/** + * @file rex/codegen/test_support.h + * @brief Test support utilities + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include +#include + +#include + +namespace rex::codegen { + +/** + * @brief Lightweight Module for loading raw binary test data + * + * TestModule provides the Module interface needed by FunctionScanner and + * Recompiler without requiring a full Runtime/FunctionDispatcher setup. It accepts + * raw binary data by reference (caller owns the buffer). + * + * Usage: + * std::vector data = load_binary_file(...); + * TestModule module; + * module.Load(0x82010000, data.data(), data.size()); + * recompiler.module_ = &module; + */ +class TestModule : public runtime::Module { + public: + TestModule(); + ~TestModule() override = default; + + /** + * @brief Load binary data for analysis + * @param base_address Guest virtual address where code is loaded + * @param data Pointer to binary data (caller owns, must outlive TestModule usage) + * @param size Size of binary data in bytes + */ + void Load(uint32_t base_address, const uint8_t* data, size_t size); + + // Module interface overrides + const std::string& name() const override { return name_; } + void set_name(const std::string& name) { name_ = name; } + bool is_executable() const override { return true; } + uint32_t base_address() const override { return base_address_; } + uint32_t image_size() const override { return size_; } + uint32_t entry_point() const override { return base_address_; } + bool ContainsAddress(uint32_t address) override; + + private: + std::string name_{"test"}; + uint32_t base_address_ = 0; + uint32_t size_ = 0; +}; + +class CodegenContext; + +/** + * @brief Analyze a test binary using map symbols as function entry points. + * + * Filters symbols to test_ prefixed entries, adds them as functions to + * ctx.graph with single blocks, then scans for bl instructions and + * registers call edges. + * + * @param ctx Codegen context whose graph will be populated + * @param testName Stem name used for function naming (e.g. "addi") + * @param symbols Address-to-name map from parse_map_file() + * @param baseAddress Base address the binary was linked at + * @param data Pointer to raw binary data + * @param dataSize Size of binary data in bytes + */ +void AnalyzeTestBinary(CodegenContext& ctx, std::string_view testName, + const std::map& symbols, uint32_t baseAddress, + const uint8_t* data, size_t dataSize); + +} // namespace rex::codegen diff --git a/include/rex/codegen/vtable_scanner.h b/include/rex/codegen/vtable_scanner.h new file mode 100644 index 0000000..cb449e6 --- /dev/null +++ b/include/rex/codegen/vtable_scanner.h @@ -0,0 +1,90 @@ +/** + * @file rex/codegen/vtable_scanner.h + * @brief VTable scanner - RTTI-based vtable discovery + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include +#include + +#include + +namespace rex::codegen { + +//============================================================================= +// RTTI Structures (MSVC-based, Xbox 360) +//============================================================================= + +// Type descriptor - contains mangled class name +struct RTTITypeDescriptor { + uint32_t pVFTable; // Always points to type_info vtable + uint32_t spare; // Runtime use, always 0 in image + // char name[]; // Mangled name: ".?AVClassName@@" +}; + +// Complete Object Locator - links vtable to type info +struct RTTICompleteObjectLocator { + uint32_t signature; // Always 0 for 32-bit + uint32_t offset; // Offset of this vtable in complete class + uint32_t cdOffset; // Constructor displacement offset + uint32_t pTypeDescriptor; // Pointer to TypeDescriptor + uint32_t pClassHierarchy; // Pointer to class hierarchy descriptor +}; + +//============================================================================= +// VTableInfo - Result of vtable scanning +//============================================================================= + +struct VTableInfo { + uint32_t vtableAddress; // Address of vtable[0] + uint32_t colAddress; // RTTI Complete Object Locator address + std::string className; // Demangled class name (optional) + std::vector slots; // Function addresses in vtable +}; + +//============================================================================= +// VTableScanner - RTTI-based vtable discovery +//============================================================================= + +class VTableScanner { + public: + explicit VTableScanner(const BinaryView& binary); + + // Scan for all vtables via RTTI traversal + std::vector scan(); + + private: + const BinaryView& binary_; + + // Find all Complete Object Locators in .rdata + std::vector findCompleteObjectLocators(); + + // Find the vtable that references a given COL (COL is at vtable[-1]) + std::optional findVTableForCOL(uint32_t colAddr); + + // Read all function slots from a vtable (until non-executable address) + std::vector readVTableSlots(uint32_t vtableStart); + + // Extract class name from type descriptor + std::string extractClassName(uint32_t colAddr); + + // Check if an address points to executable code + bool isExecutableAddress(uint32_t addr) const; + + // Read a dword from the binary + std::optional readDword(uint32_t addr) const; + + // Read a string from the binary + std::string readString(uint32_t addr, size_t maxLen = 256) const; +}; + +} // namespace rex::codegen diff --git a/include/rex/crypto/sha256.h b/include/rex/crypto/sha256.h new file mode 100644 index 0000000..530e87a --- /dev/null +++ b/include/rex/crypto/sha256.h @@ -0,0 +1,18 @@ +/** + * SHA256 hashing utilities + * + * Provides SHA256 hashing for strings and files, used for cache invalidation. + */ + +#pragma once + +#include +#include +#include + +namespace rex::crypto { + +std::string sha256(std::string_view data); +std::string sha256_file(const std::filesystem::path& path); + +} // namespace rex::crypto diff --git a/include/rex/cvar.h b/include/rex/cvar.h new file mode 100644 index 0000000..c6abbfb --- /dev/null +++ b/include/rex/cvar.h @@ -0,0 +1,520 @@ +/** + * @file cvar.h + * @brief cvar (configuration variable) system + * + * @section cvar_defining Defining CVars + * + * Define cvars in a single .cpp file using REXCVAR_DEFINE_* macros: + * @code + * // In flags.cpp or your module's .cpp file + * REXCVAR_DEFINE_BOOL(my_flag, false, "Category", "Description"); + * REXCVAR_DEFINE_INT32(my_int, 42, "Category", "An integer setting"); + * REXCVAR_DEFINE_STRING(my_string, "default", "Category", "A string setting"); + * @endcode + * + * Available types: BOOL, INT32, INT64, UINT32, UINT64, DOUBLE, STRING, COMMAND + * + * @section cvar_declaring Declaring CVars (for use in other files) + * + * @code + * // In a header or other .cpp that needs access + * REXCVAR_DECLARE(bool, my_flag); + * REXCVAR_DECLARE(int32_t, my_int); + * REXCVAR_DECLARE(std::string, my_string); + * @endcode + * + * @section cvar_access Getting and Setting Values + * + * @code + * // Type-safe access (preferred for known cvars) + * bool value = REXCVAR_GET(my_flag); + * REXCVAR_SET(my_flag, true); + * + * // String-based access (for dynamic/runtime lookup) + * std::string str_val = rex::cvar::GetFlagByName("my_flag"); + * rex::cvar::SetFlagByName("my_flag", "true"); + * @endcode + * + * @section cvar_metadata Adding Metadata + * + * Chain metadata methods after the DEFINE macro: + * @code + * REXCVAR_DEFINE_INT32(scale, 1, "GPU", "Resolution scale") + * .range(1, 8) + * .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + * + * REXCVAR_DEFINE_STRING(backend, "d3d12", "GPU", "Render backend") + * .allowed({"d3d12", "vulkan"}) + * .lifecycle(rex::cvar::Lifecycle::kInitOnly); + * + * REXCVAR_DEFINE_BOOL(debug_overlay, false, "Debug", "Show overlay") + * .debug_only(); + * @endcode + * + * @section cvar_guidelines Metadata Guidelines + * + * - .lifecycle(kInitOnly) - Device/backend selection that cannot change after init + * - .lifecycle(kRequiresRestart) - Settings that need restart to take effect + * - .lifecycle(kHotReload) - Default; can change at runtime with immediate effect + * - .range(min, max) - Numeric bounds validation + * - .allowed({...}) - String enum validation + * - .debug_only() - Mark as debug-only (for filtering in release UIs) + * - .validator(fn) - Custom validation function + * + * @section cvar_query Querying CVars + * + * @code + * // List all cvars + * auto all = rex::cvar::ListFlags(); + * + * // Query by category or lifecycle + * auto gpu_flags = rex::cvar::ListFlagsByCategory("GPU"); + * auto init_only = rex::cvar::ListFlagsByLifecycle(rex::cvar::Lifecycle::kInitOnly); + * + * // Get metadata for a specific cvar + * const auto* info = rex::cvar::GetFlagInfo("my_flag"); + * if (info) { + * // Access info->lifecycle, info->constraints, info->description, etc. + * } + * + * // Check for modified values + * auto modified = rex::cvar::ListModifiedFlags(); + * @endcode + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::cvar { + +//============================================================================= +// Initialization API +//============================================================================= + +std::vector Init(int argc, char** argv); +void LoadConfig(const std::filesystem::path& config_path); +void ApplyEnvironment(); +void FinalizeInit(); +bool IsFinalized(); +void SaveConfig(const std::filesystem::path& config_path); + +//============================================================================= +// Flag Registry +//============================================================================= + +enum class FlagType { Boolean, Int32, Int64, Uint32, Uint64, Double, String, Command }; + +// Lifecycle: when can this flag be modified? +enum class Lifecycle { + kInitOnly, // Can only be set during initialization (before FinalizeInit) + kHotReload, // Can be changed at runtime with immediate effect + kRequiresRestart // Can be changed, but only takes effect after restart +}; + +// Validation constraints +struct Constraints { + std::optional min; + std::optional max; + std::vector allowed_values; + std::function custom_validator; + + bool HasRangeConstraint() const { return min.has_value() || max.has_value(); } + bool HasAllowedValues() const { return !allowed_values.empty(); } +}; + +struct FlagEntry { + std::string name; + FlagType type; + std::string category; + std::string description; + std::function setter; + std::function getter; + std::function command_callback; + Lifecycle lifecycle = Lifecycle::kHotReload; + Constraints constraints; + std::string default_value; + bool is_debug_only = false; +}; + +std::vector& GetRegistry(); + +/** + * Returns the registered entry's index, or nullopt if the name was already + * registered (logged at ERROR). + */ +std::optional RegisterFlag(FlagEntry entry); + +/** + * Removes a flag from the registry. Used by `FlagRegistrar`'s destructor so + * that DLL unload tears down the lambdas captured in each FlagEntry. + */ +void UnregisterFlag(std::string_view name); + +bool SetFlagByName(std::string_view name, std::string_view value); +std::string GetFlagByName(std::string_view name); + +// Typed registry query. Cross-DLL access path that does not require linking +// the DLL where the cvar is defined. Slower than REXCVAR_GET (string parse + +// hash lookup), so prefer REXCVAR_GET when the defining DLL is already on the +// link line. Returns a value-initialized T when the cvar is missing or its +// stored string fails to parse. +template +T Query(std::string_view name); + +template <> +bool Query(std::string_view name); +template <> +int32_t Query(std::string_view name); +template <> +int64_t Query(std::string_view name); +template <> +uint32_t Query(std::string_view name); +template <> +uint64_t Query(std::string_view name); +template <> +double Query(std::string_view name); +template <> +std::string Query(std::string_view name); + +std::vector ListFlags(); +std::vector ListFlagsByCategory(std::string_view category); +std::vector ListFlagsByLifecycle(Lifecycle lc); +const FlagEntry* GetFlagInfo(std::string_view name); +std::vector GetPendingRestartFlags(); +void ClearPendingRestartFlags(); +void ResetToDefault(std::string_view name); +void ResetAllToDefaults(); +bool HasNonDefaultValue(std::string_view name); +std::vector ListModifiedFlags(); +std::string SerializeToTOML(); +std::string SerializeToTOML(std::string_view category); + +/// Callback invoked when a CVAR value changes +/// @param name The CVAR name +/// @param new_value The new value as a string +using ChangeCallback = std::function; + +/// Register a callback to be invoked when a specific CVAR changes +void RegisterChangeCallback(std::string_view name, ChangeCallback callback); + +/// Unregister all callbacks for a specific CVAR +void UnregisterChangeCallbacks(std::string_view name); + +/** + * RAII handle for a registered flag. Destructor unregisters by name; on + * duplicate-name registration `owned_name_` is empty so chain methods and + * the destructor become no-ops and the original owner's entry is untouched. + */ +struct FlagRegistrar { + std::string owned_name_; // empty when registration was rejected + + explicit FlagRegistrar(FlagEntry e) { + std::string name = e.name; + if (RegisterFlag(std::move(e)).has_value()) { + owned_name_ = std::move(name); + } + } + + FlagRegistrar(FlagRegistrar&& other) noexcept : owned_name_(std::move(other.owned_name_)) { + other.owned_name_.clear(); + } + + ~FlagRegistrar() { + if (!owned_name_.empty()) { + UnregisterFlag(owned_name_); + } + } + + // Chain methods mutate the registered entry by name lookup. + FlagRegistrar&& range(double min_val, double max_val) && { + apply_([=](FlagEntry& entry) { + entry.constraints.min = min_val; + entry.constraints.max = max_val; + }); + return std::move(*this); + } + + FlagRegistrar&& allowed(std::initializer_list values) && { + std::vector vals(values); + apply_([vals = std::move(vals)](FlagEntry& entry) { entry.constraints.allowed_values = vals; }); + return std::move(*this); + } + + FlagRegistrar&& lifecycle(Lifecycle lc) && { + apply_([=](FlagEntry& entry) { entry.lifecycle = lc; }); + return std::move(*this); + } + + FlagRegistrar&& debug_only() && { + apply_([](FlagEntry& entry) { entry.is_debug_only = true; }); + return std::move(*this); + } + + FlagRegistrar&& validator(std::function fn) && { + apply_([fn = std::move(fn)](FlagEntry& entry) mutable { + entry.constraints.custom_validator = std::move(fn); + }); + return std::move(*this); + } + + // Non-copyable (prevent double registration) + FlagRegistrar(const FlagRegistrar&) = delete; + FlagRegistrar& operator=(const FlagRegistrar&) = delete; + FlagRegistrar& operator=(FlagRegistrar&&) = delete; + + private: + void apply_(std::function fn); +}; + +inline bool ParseDouble(std::string_view s, double& out) { + if (s.empty()) + return false; + char* end = nullptr; + std::string str(s); + out = std::strtod(str.c_str(), &end); + return end != str.c_str() && *end == '\0'; +} + +} // namespace rex::cvar + +//============================================================================= +// CVar Macros +//============================================================================= + +// Declare a cvar (use in headers and TUs that need to read it). +// The accessor function returns a reference to the cvar's storage. Storage +// lives as a static-local inside whichever DLL contains the matching +// REXCVAR_DEFINE_*. Cross-DLL access goes through the import lib. +#define REXCVAR_DECLARE(type, name) type& FLAGS_##name##_storage_() + +// Get a cvar value +#define REXCVAR_GET(name) (FLAGS_##name##_storage_()) + +// Set a cvar value +#define REXCVAR_SET(name, value) (FLAGS_##name##_storage_() = (value)) + +// Cross-module typed query that goes through the cvar registry by name. +// Use this when the defining DLL is not on the consumer's link line (e.g., +// across one-way subsystem dependencies where adding the reverse link would +// create a cycle). Slower than REXCVAR_GET; prefer REXCVAR_GET when possible. +#define REXCVAR_QUERY(type, name) (::rex::cvar::Query(#name)) + +// Define cvars (use in one .cpp file per cvar) +// The FlagRegistrar registers the flag in its destructor, allowing method chaining. +#define REXCVAR_DEFINE_BOOL(name, default_val, category, desc) \ + bool& FLAGS_##name##_storage_() { \ + static bool storage = (default_val); \ + return storage; \ + } \ + static auto _cvar_reg_##name = \ + ::rex::cvar::FlagRegistrar({#name, \ + ::rex::cvar::FlagType::Boolean, \ + category, \ + desc, \ + [](std::string_view v) { \ + bool val = (v == "true" || v == "1" || v == "yes"); \ + FLAGS_##name##_storage_() = val; \ + return true; \ + }, \ + []() { return FLAGS_##name##_storage_() ? "true" : "false"; }, \ + []() { return; }, \ + ::rex::cvar::Lifecycle::kHotReload, \ + {}, \ + (default_val) ? "true" : "false", \ + false}) + +#define REXCVAR_DEFINE_INT32(name, default_val, category, desc) \ + int32_t& FLAGS_##name##_storage_() { \ + static int32_t storage = (default_val); \ + return storage; \ + } \ + static auto _cvar_reg_##name = \ + ::rex::cvar::FlagRegistrar({#name, \ + ::rex::cvar::FlagType::Int32, \ + category, \ + desc, \ + [](std::string_view v) { \ + int32_t val = 0; \ + auto [ptr, ec] = \ + std::from_chars(v.data(), v.data() + v.size(), val); \ + if (ec != std::errc()) \ + return false; \ + FLAGS_##name##_storage_() = val; \ + return true; \ + }, \ + []() { return std::to_string(FLAGS_##name##_storage_()); }, \ + []() { return; }, \ + ::rex::cvar::Lifecycle::kHotReload, \ + {}, \ + std::to_string(default_val), \ + false}) + +#define REXCVAR_DEFINE_INT64(name, default_val, category, desc) \ + int64_t& FLAGS_##name##_storage_() { \ + static int64_t storage = (default_val); \ + return storage; \ + } \ + static auto _cvar_reg_##name = \ + ::rex::cvar::FlagRegistrar({#name, \ + ::rex::cvar::FlagType::Int64, \ + category, \ + desc, \ + [](std::string_view v) { \ + int64_t val = 0; \ + auto [ptr, ec] = \ + std::from_chars(v.data(), v.data() + v.size(), val); \ + if (ec != std::errc()) \ + return false; \ + FLAGS_##name##_storage_() = val; \ + return true; \ + }, \ + []() { return std::to_string(FLAGS_##name##_storage_()); }, \ + []() { return; }, \ + ::rex::cvar::Lifecycle::kHotReload, \ + {}, \ + std::to_string(default_val), \ + false}) + +#define REXCVAR_DEFINE_UINT32(name, default_val, category, desc) \ + uint32_t& FLAGS_##name##_storage_() { \ + static uint32_t storage = (default_val); \ + return storage; \ + } \ + static auto _cvar_reg_##name = \ + ::rex::cvar::FlagRegistrar({#name, \ + ::rex::cvar::FlagType::Uint32, \ + category, \ + desc, \ + [](std::string_view v) { \ + uint32_t val = 0; \ + auto [ptr, ec] = \ + std::from_chars(v.data(), v.data() + v.size(), val); \ + if (ec != std::errc()) \ + return false; \ + FLAGS_##name##_storage_() = val; \ + return true; \ + }, \ + []() { return std::to_string(FLAGS_##name##_storage_()); }, \ + []() { return; }, \ + ::rex::cvar::Lifecycle::kHotReload, \ + {}, \ + std::to_string(default_val), \ + false}) + +#define REXCVAR_DEFINE_UINT64(name, default_val, category, desc) \ + uint64_t& FLAGS_##name##_storage_() { \ + static uint64_t storage = (default_val); \ + return storage; \ + } \ + static auto _cvar_reg_##name = \ + ::rex::cvar::FlagRegistrar({#name, \ + ::rex::cvar::FlagType::Uint64, \ + category, \ + desc, \ + [](std::string_view v) { \ + uint64_t val = 0; \ + auto [ptr, ec] = \ + std::from_chars(v.data(), v.data() + v.size(), val); \ + if (ec != std::errc()) \ + return false; \ + FLAGS_##name##_storage_() = val; \ + return true; \ + }, \ + []() { return std::to_string(FLAGS_##name##_storage_()); }, \ + []() { return; }, \ + ::rex::cvar::Lifecycle::kHotReload, \ + {}, \ + std::to_string(default_val), \ + false}) + +#define REXCVAR_DEFINE_DOUBLE(name, default_val, category, desc) \ + double& FLAGS_##name##_storage_() { \ + static double storage = (default_val); \ + return storage; \ + } \ + static auto _cvar_reg_##name = \ + ::rex::cvar::FlagRegistrar({#name, \ + ::rex::cvar::FlagType::Double, \ + category, \ + desc, \ + [](std::string_view v) { \ + double val = 0; \ + if (!::rex::cvar::ParseDouble(v, val)) \ + return false; \ + FLAGS_##name##_storage_() = val; \ + return true; \ + }, \ + []() { return std::to_string(FLAGS_##name##_storage_()); }, \ + []() { return; }, \ + ::rex::cvar::Lifecycle::kHotReload, \ + {}, \ + std::to_string(default_val), \ + false}) + +#define REXCVAR_DEFINE_STRING(name, default_val, category, desc) \ + std::string& FLAGS_##name##_storage_() { \ + static std::string storage = (default_val); \ + return storage; \ + } \ + static auto _cvar_reg_##name = \ + ::rex::cvar::FlagRegistrar({#name, \ + ::rex::cvar::FlagType::String, \ + category, \ + desc, \ + [](std::string_view v) { \ + FLAGS_##name##_storage_() = std::string(v); \ + return true; \ + }, \ + []() { return FLAGS_##name##_storage_(); }, \ + []() { return; }, \ + ::rex::cvar::Lifecycle::kHotReload, \ + {}, \ + default_val, \ + false}) + +#define REXCVAR_DEFINE_COMMAND(name, callback, category, desc) \ + std::function& FLAGS_##name##_storage_() { \ + static std::function storage = (callback); \ + return storage; \ + } \ + static auto _cvar_reg_##name = \ + ::rex::cvar::FlagRegistrar({#name, \ + ::rex::cvar::FlagType::Command, \ + category, \ + desc, \ + [](std::string_view) { return false; }, \ + []() { return ""; }, \ + callback, \ + ::rex::cvar::Lifecycle::kHotReload, \ + {}, \ + "", \ + false}) + +namespace rex::cvar { +namespace testing { + +class ScopedLifecycleOverride { + public: + ScopedLifecycleOverride(); + ~ScopedLifecycleOverride(); + + ScopedLifecycleOverride(const ScopedLifecycleOverride&) = delete; + ScopedLifecycleOverride& operator=(const ScopedLifecycleOverride&) = delete; +}; + +void ResetAllForTesting(); + +} // namespace testing +} // namespace rex::cvar diff --git a/include/rex/dbg.h b/include/rex/dbg.h new file mode 100644 index 0000000..19c3453 --- /dev/null +++ b/include/rex/dbg.h @@ -0,0 +1,97 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include + +#include + +namespace rex::debug { + +// Returns true if a debugger is attached to this process. +// The state may change at any time (attach after launch, etc), so do not +// cache this value. Determining if the debugger is attached is expensive, +// though, so avoid calling it frequently. +bool IsDebuggerAttached(); + +// Breaks into the debugger if it is attached. +// If no debugger is present, a signal will be raised. +void Break(); + +namespace detail { +void DebugPrint(const char* s); +} + +// Prints a message to the attached debugger. +// This bypasses the normal logging mechanism. If no debugger is attached it's +// likely to no-op. +template +void DebugPrint(fmt::string_view format, const Args&... args) { + detail::DebugPrint(fmt::vformat(format, fmt::make_format_args(args...)).c_str()); +} + +} // namespace rex::debug + +#ifdef REXGLUE_ENABLE_PROFILING + +#include + +// CPU profiling zones +#define SCOPE_profile_cpu_f(name) ZoneNamedN(___tracy_cpu_zone, name, true) +#define SCOPE_profile_cpu_i(name, detail) \ + ZoneNamedN(___tracy_cpu_zone_i, name, true); \ + ZoneTextV(___tracy_cpu_zone_i, detail, std::strlen(detail)) + +// GPU profiling stubs -- backend code uses TracyVkZone/TracyD3D12Zone directly. +#define SCOPE_profile_gpu_f(name) +#define SCOPE_profile_gpu_i(name, detail) + +// Thread profiling +#define PROFILE_THREAD_ENTER(name) tracy::SetThreadName(name) +#define PROFILE_THREAD_EXIT() + +// Fiber profiling +#ifdef TRACY_FIBERS +#define PROFILE_FIBER_ENTER(name) TracyFiberEnter(name) +#define PROFILE_FIBER_LEAVE TracyFiberLeave +#else +#define PROFILE_FIBER_ENTER(name) +#define PROFILE_FIBER_LEAVE +#endif + +// Counter profiling -- plot to Tracy +#define COUNT_profile_set(name, value) TracyPlot(name, static_cast(value)) + +#else // !REXGLUE_ENABLE_PROFILING + +// CPU profiling stubs +#define SCOPE_profile_cpu_f(name) +#define SCOPE_profile_cpu_i(name, detail) + +// GPU profiling stubs +#define SCOPE_profile_gpu_f(name) +#define SCOPE_profile_gpu_i(name, detail) + +// Thread profiling stubs +#define PROFILE_THREAD_ENTER(name) +#define PROFILE_THREAD_EXIT() + +// Fiber profiling stubs +#define PROFILE_FIBER_ENTER(name) +#define PROFILE_FIBER_LEAVE + +// Counter profiling stubs +#define COUNT_profile_set(name, value) + +#endif // REXGLUE_ENABLE_PROFILING diff --git a/include/rex/exception_handler.h b/include/rex/exception_handler.h new file mode 100644 index 0000000..bcd00bf --- /dev/null +++ b/include/rex/exception_handler.h @@ -0,0 +1,534 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + * + * @file exception_handler.h + * @brief Unified exception handling, thread context, and register defs + * + * @remarks Flattened from arch/{arm64,amd64}/host_thread_context.h, + * arch/host_thread_context.h, arch/{arm64,amd64}/exception_handler.h, + * and arch/exception_handler.h. + * Contains VIXL-derived ARM64 load/store decoding constants. + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include + +#if REX_ARCH_AMD64 +#include +#endif + +namespace rex::arch { + +//============================================================================= +// ARM64 Register Definitions +//============================================================================= + +// NOTE: The order of the registers in the enumerations must match the order in +// the string table in host_thread_context.cc, as well as remapping tables in +// exception handler implementations. + +enum class Arm64Register { + kX0, + kX1, + kX2, + kX3, + kX4, + kX5, + kX6, + kX7, + kX8, + kX9, + kX10, + kX11, + kX12, + kX13, + kX14, + kX15, + kX16, + kX17, + kX18, + kX19, + kX20, + kX21, + kX22, + kX23, + kX24, + kX25, + kX26, + kX27, + kX28, + // FP (frame pointer). + kX29, + // LR (link register). + kX30, + kSp, + kPc, + kPstate, + kFpsr, + kFpcr, + // The whole 128 bits of a Vn register are also known as Qn (quadword). + kV0, + kV1, + kV2, + kV3, + kV4, + kV5, + kV6, + kV7, + kV8, + kV9, + kV10, + kV11, + kV12, + kV13, + kV14, + kV15, + kV16, + kV17, + kV18, + kV19, + kV20, + kV21, + kV22, + kV23, + kV24, + kV25, + kV26, + kV27, + kV28, + kV29, + kV30, + kV31, +}; + +// ARM64 thread context structure members +// Used within HostThreadContext class via #if REX_ARCH_ARM64 +struct Arm64ThreadContextMembers { + uint64_t x[31]; + uint64_t sp; + uint64_t pc; + uint64_t pstate; + uint32_t fpsr; + uint32_t fpcr; + vec128_t v[32]; +}; + +//============================================================================= +// AMD64 Register Definitions +//============================================================================= + +#if REX_ARCH_AMD64 + +// NOTE: The order of the registers in the enumerations must match the order in +// the string table in host_thread_context.cc, as well as remapping tables in +// exception handler implementations. + +enum class X64Register { + kRip, + kEflags, + + kIntRegisterFirst, + // The order matches the indices in the instruction encoding, as well as the + // Windows CONTEXT structure. + kRax = kIntRegisterFirst, + kRcx, + kRdx, + kRbx, + kRsp, + kRbp, + kRsi, + kRdi, + kR8, + kR9, + kR10, + kR11, + kR12, + kR13, + kR14, + kR15, + kIntRegisterLast = kR15, + + kXmm0, + kXmm1, + kXmm2, + kXmm3, + kXmm4, + kXmm5, + kXmm6, + kXmm7, + kXmm8, + kXmm9, + kXmm10, + kXmm11, + kXmm12, + kXmm13, + kXmm14, + kXmm15, +}; + +// x86-64 thread context structure members +// Used within HostThreadContext class via #if REX_ARCH_AMD64 +struct X64ThreadContextMembers { + uint64_t rip; + uint32_t eflags; + union { + struct { + uint64_t rax; + uint64_t rcx; + uint64_t rdx; + uint64_t rbx; + uint64_t rsp; + uint64_t rbp; + uint64_t rsi; + uint64_t rdi; + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; + }; + uint64_t int_registers[16]; + }; + union { + struct { + vec128_t xmm0; + vec128_t xmm1; + vec128_t xmm2; + vec128_t xmm3; + vec128_t xmm4; + vec128_t xmm5; + vec128_t xmm6; + vec128_t xmm7; + vec128_t xmm8; + vec128_t xmm9; + vec128_t xmm10; + vec128_t xmm11; + vec128_t xmm12; + vec128_t xmm13; + vec128_t xmm14; + vec128_t xmm15; + }; + vec128_t xmm_registers[16]; + }; +}; + +#endif // REX_ARCH_AMD64 + +//============================================================================= +// Host Register Typedef +//============================================================================= + +#if REX_ARCH_AMD64 +using HostRegister = X64Register; +#elif REX_ARCH_ARM64 +using HostRegister = Arm64Register; +#else +enum class HostRegister {}; +#endif // REX_ARCH + +//============================================================================= +// Host Thread Context +//============================================================================= + +class HostThreadContext { + public: +#if REX_ARCH_AMD64 + uint64_t rip; + uint32_t eflags; + union { + struct { + uint64_t rax; + uint64_t rcx; + uint64_t rdx; + uint64_t rbx; + uint64_t rsp; + uint64_t rbp; + uint64_t rsi; + uint64_t rdi; + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; + }; + uint64_t int_registers[16]; + }; + union { + struct { + vec128_t xmm0; + vec128_t xmm1; + vec128_t xmm2; + vec128_t xmm3; + vec128_t xmm4; + vec128_t xmm5; + vec128_t xmm6; + vec128_t xmm7; + vec128_t xmm8; + vec128_t xmm9; + vec128_t xmm10; + vec128_t xmm11; + vec128_t xmm12; + vec128_t xmm13; + vec128_t xmm14; + vec128_t xmm15; + }; + vec128_t xmm_registers[16]; + }; +#elif REX_ARCH_ARM64 + uint64_t x[31]; + uint64_t sp; + uint64_t pc; + uint64_t pstate; + uint32_t fpsr; + uint32_t fpcr; + vec128_t v[32]; +#endif // REX_ARCH + + static const char* GetRegisterName(HostRegister reg); + std::string GetStringFromValue(HostRegister reg, bool hex) const; +}; + +//============================================================================= +// ARM64 Load/Store Decoding (VIXL-derived) +//============================================================================= + +// AArch64 load and store decoding based on VIXL. +// https://github.com/Linaro/vixl/blob/ae5957cd66517b3f31dbf37e9bf39db6594abfe3/src/aarch64/constants-aarch64.h +// +// Copyright 2015, VIXL authors +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of ARM Limited nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// `Instruction address + literal offset` loads. +// This includes PRFM_lit. +constexpr uint32_t kArm64LoadLiteralFMask = UINT32_C(0x3B000000); +constexpr uint32_t kArm64LoadLiteralFixed = UINT32_C(0x18000000); + +constexpr uint32_t kArm64LoadStoreAnyFMask = UINT32_C(0x0A000000); +constexpr uint32_t kArm64LoadStoreAnyFixed = UINT32_C(0x08000000); + +constexpr uint32_t kArm64LoadStorePairAnyFMask = UINT32_C(0x3A000000); +constexpr uint32_t kArm64LoadStorePairAnyFixed = UINT32_C(0x28000000); +constexpr uint32_t kArm64LoadStorePairLoadBit = UINT32_C(1) << 22; + +constexpr uint32_t kArm64LoadStoreMask = UINT32_C(0xC4C00000); +enum class Arm64LoadStoreOp : uint32_t { + kSTRB_w = UINT32_C(0x00000000), + kSTRH_w = UINT32_C(0x40000000), + kSTR_w = UINT32_C(0x80000000), + kSTR_x = UINT32_C(0xC0000000), + kLDRB_w = UINT32_C(0x00400000), + kLDRH_w = UINT32_C(0x40400000), + kLDR_w = UINT32_C(0x80400000), + kLDR_x = UINT32_C(0xC0400000), + kLDRSB_x = UINT32_C(0x00800000), + kLDRSH_x = UINT32_C(0x40800000), + kLDRSW_x = UINT32_C(0x80800000), + kLDRSB_w = UINT32_C(0x00C00000), + kLDRSH_w = UINT32_C(0x40C00000), + kSTR_b = UINT32_C(0x04000000), + kSTR_h = UINT32_C(0x44000000), + kSTR_s = UINT32_C(0x84000000), + kSTR_d = UINT32_C(0xC4000000), + kSTR_q = UINT32_C(0x04800000), + kLDR_b = UINT32_C(0x04400000), + kLDR_h = UINT32_C(0x44400000), + kLDR_s = UINT32_C(0x84400000), + kLDR_d = UINT32_C(0xC4400000), + kLDR_q = UINT32_C(0x04C00000), + kPRFM = UINT32_C(0xC0800000), +}; + +constexpr uint32_t kArm64LoadStoreOffsetFMask = UINT32_C(0x3B200C00); +enum class Arm64LoadStoreOffsetFixed : uint32_t { + kUnscaledOffset = UINT32_C(0x38000000), + kPostIndex = UINT32_C(0x38000400), + kPreIndex = UINT32_C(0x38000C00), + kRegisterOffset = UINT32_C(0x38200800), +}; + +constexpr uint32_t kArm64LoadStoreUnsignedOffsetFMask = UINT32_C(0x3B000000); +constexpr uint32_t kArm64LoadStoreUnsignedOffsetFixed = UINT32_C(0x39000000); + +// Determines if an ARM64 instruction is a load, prefetch, or store operation. +// Returns true if the instruction is one of these, with is_store_out set to +// indicate whether it's a store operation. +bool IsArm64LoadPrefetchStore(uint32_t instruction, bool& is_store_out); + +//============================================================================= +// Exception Class +//============================================================================= + +class Exception { + public: + enum class Code { + kInvalidException = 0, + kAccessViolation, + kIllegalInstruction, + }; + + enum class AccessViolationOperation { + kUnknown, + kRead, + kWrite, + }; + + void InitializeAccessViolation(HostThreadContext* thread_context, uint64_t fault_address, + AccessViolationOperation operation) { + code_ = Code::kAccessViolation; + thread_context_ = thread_context; + fault_address_ = fault_address; + access_violation_operation_ = operation; + } + void InitializeIllegalInstruction(HostThreadContext* thread_context) { + code_ = Code::kIllegalInstruction; + thread_context_ = thread_context; + } + + Code code() const { return code_; } + + // Returns the platform-specific thread context info. + // Note that certain registers must be modified through Modify* proxy + // functions rather than directly: + // x86-64: + // - General-purpose registers (r##, r8-r15). + // - XMM registers. + // AArch64: + // - General-purpose registers (Xn), including FP and LR. + // - SIMD and floating-point registers (Vn). + HostThreadContext* thread_context() const { return thread_context_; } + + // Returns the program counter where the exception occurred. + uint64_t pc() const { +#if REX_ARCH_AMD64 + return thread_context_->rip; +#elif REX_ARCH_ARM64 + return thread_context_->pc; +#else + assert_always(); + return 0; +#endif // REX_ARCH + } + + // Sets the program counter where execution will resume. + void set_resume_pc(uint64_t pc) { +#if REX_ARCH_AMD64 + thread_context_->rip = pc; +#elif REX_ARCH_ARM64 + thread_context_->pc = pc; +#else + assert_always(); +#endif // REX_ARCH + } + +#if REX_ARCH_AMD64 + // The index is relative to X64Register::kIntRegisterFirst. + uint64_t& ModifyIntRegister(uint32_t index) { + assert_true(index <= 15); + modified_int_registers_ |= UINT16_C(1) << index; + return thread_context_->int_registers[index]; + } + uint16_t modified_int_registers() const { return modified_int_registers_; } + vec128_t& ModifyXmmRegister(uint32_t index) { + assert_true(index <= 15); + modified_xmm_registers_ |= UINT16_C(1) << index; + return thread_context_->xmm_registers[index]; + } + uint16_t modified_xmm_registers() const { return modified_xmm_registers_; } +#elif REX_ARCH_ARM64 + uint64_t& ModifyXRegister(uint32_t index) { + assert_true(index <= 30); + modified_x_registers_ |= UINT32_C(1) << index; + return thread_context_->x[index]; + } + uint32_t modified_x_registers() const { return modified_x_registers_; } + vec128_t& ModifyVRegister(uint32_t index) { + assert_true(index <= 31); + modified_v_registers_ |= UINT32_C(1) << index; + return thread_context_->v[index]; + } + uint32_t modified_v_registers() const { return modified_v_registers_; } +#endif // REX_ARCH + + // In case of AV, address that was read from/written to. + uint64_t fault_address() const { return fault_address_; } + + // In case of AV, what kind of operation caused it. + AccessViolationOperation access_violation_operation() const { + return access_violation_operation_; + } + + private: + Code code_ = Code::kInvalidException; + HostThreadContext* thread_context_ = nullptr; +#if REX_ARCH_AMD64 + uint16_t modified_int_registers_ = 0; + uint16_t modified_xmm_registers_ = 0; +#elif REX_ARCH_ARM64 + uint32_t modified_x_registers_ = 0; + uint32_t modified_v_registers_ = 0; +#endif // REX_ARCH + uint64_t fault_address_ = 0; + AccessViolationOperation access_violation_operation_ = AccessViolationOperation::kUnknown; +}; + +//============================================================================= +// Exception Handler +//============================================================================= + +class ExceptionHandler { + public: + typedef bool (*Handler)(Exception* ex, void* data); + + // Installs an exception handler. + // Handlers are called in the order they are installed. + static void Install(Handler fn, void* data); + + // Uninstalls a previously-installed exception handler. + static void Uninstall(Handler fn, void* data); +}; + +} // namespace rex::arch diff --git a/include/rex/filesystem.h b/include/rex/filesystem.h new file mode 100644 index 0000000..d4c512e --- /dev/null +++ b/include/rex/filesystem.h @@ -0,0 +1,136 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace rex { + +std::string path_to_utf8(const std::filesystem::path& path); +std::u16string path_to_utf16(const std::filesystem::path& path); +std::filesystem::path to_path(const std::string_view source); +std::filesystem::path to_path(const std::u16string_view source); + +namespace filesystem { + +// Get executable path. +std::filesystem::path GetExecutablePath(); + +// Get executable folder. +std::filesystem::path GetExecutableFolder(); + +// Get user folder. +std::filesystem::path GetUserFolder(); + +// Creates the parent folder of the specified path if needed. +// This can be used to ensure the destination path for a new file exists before +// attempting to create it. +bool CreateParentFolder(const std::filesystem::path& path); + +// Creates an empty file at the given path, overwriting if it exists. +bool CreateEmptyFile(const std::filesystem::path& path); + +// Opens the file at the given path with the specified mode. +// This behaves like fopen and the returned handle can be used with stdio. +FILE* OpenFile(const std::filesystem::path& path, const std::string_view mode); + +// Wrapper for the 64-bit version of fseek, returns true on success. +bool Seek(FILE* file, int64_t offset, int origin); + +// Wrapper for the 64-bit version of ftell, returns a positive value on success. +int64_t Tell(FILE* file); + +// Reduces the size of a stdio file opened for writing. The file pointer is +// clamped. If this returns false, the size of the file and the file pointer are +// undefined. +bool TruncateStdioFile(FILE* file, uint64_t length); + +struct FileAccess { + // Implies kFileReadData. + static const uint32_t kGenericRead = 0x80000000; + // Implies kFileWriteData. + static const uint32_t kGenericWrite = 0x40000000; + static const uint32_t kGenericExecute = 0x20000000; + static const uint32_t kGenericAll = 0x10000000; + static const uint32_t kFileReadData = 0x00000001; + static const uint32_t kFileWriteData = 0x00000002; + static const uint32_t kFileAppendData = 0x00000004; +}; + +class FileHandle { + public: + // Opens the file, failing if it doesn't exist. + // The desired_access bitmask denotes the permissions on the file. + static std::unique_ptr OpenExisting(const std::filesystem::path& path, + uint32_t desired_access); + + virtual ~FileHandle() = default; + + const std::filesystem::path& path() const { return path_; } + + // Reads the requested number of bytes from the file starting at the given + // offset. The total number of bytes read is returned only if the complete + // read succeeds. + virtual bool Read(size_t file_offset, void* buffer, size_t buffer_length, + size_t* out_bytes_read) = 0; + + // Writes the given buffer to the file starting at the given offset. + // The total number of bytes written is returned only if the complete + // write succeeds. + virtual bool Write(size_t file_offset, const void* buffer, size_t buffer_length, + size_t* out_bytes_written) = 0; + + // Set length of the file in bytes. + virtual bool SetLength(size_t length) = 0; + + // Flushes any pending write buffers to the underlying filesystem. + virtual void Flush() = 0; + + protected: + explicit FileHandle(const std::filesystem::path& path) : path_(path) {} + + std::filesystem::path path_; +}; + +struct FileInfo { + enum class Type { + kFile, + kDirectory, + }; + Type type; + std::filesystem::path name; + std::filesystem::path path; + size_t total_size; + uint64_t create_timestamp; + uint64_t access_timestamp; + uint64_t write_timestamp; +}; +bool GetInfo(const std::filesystem::path& path, FileInfo* out_info); +std::vector ListFiles(const std::filesystem::path& path); + +#if REX_PLATFORM_ANDROID +void AndroidInitialize(); +void AndroidShutdown(); +bool IsAndroidContentUri(const std::string_view source); +int OpenAndroidContentFileDescriptor(const std::string_view uri, const char* mode); +#endif // REX_PLATFORM_ANDROID + +} // namespace filesystem +} // namespace rex diff --git a/include/rex/filesystem/device.h b/include/rex/filesystem/device.h new file mode 100644 index 0000000..0d47fcd --- /dev/null +++ b/include/rex/filesystem/device.h @@ -0,0 +1,50 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +#include +#include +#include + +namespace rex::filesystem { + +class Device { + public: + explicit Device(const std::string_view mount_path); + virtual ~Device(); + + virtual bool Initialize() = 0; + + const std::string& mount_path() const { return mount_path_; } + virtual bool is_read_only() const { return true; } + + virtual void Dump(string::StringBuffer* string_buffer) = 0; + virtual Entry* ResolvePath(const std::string_view path) = 0; + + virtual const std::string& name() const = 0; + virtual uint32_t attributes() const = 0; + virtual uint32_t component_name_max_length() const = 0; + + virtual uint32_t total_allocation_units() const = 0; + virtual uint32_t available_allocation_units() const = 0; + virtual uint32_t sectors_per_allocation_unit() const = 0; + virtual uint32_t bytes_per_sector() const = 0; + + protected: + rex::thread::global_critical_region global_critical_region_; + std::string mount_path_; +}; + +} // namespace rex::filesystem diff --git a/include/rex/filesystem/devices/disc_image_device.h b/include/rex/filesystem/devices/disc_image_device.h new file mode 100644 index 0000000..2183212 --- /dev/null +++ b/include/rex/filesystem/devices/disc_image_device.h @@ -0,0 +1,89 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +#include +#include + +namespace rex::filesystem { + +class DiscImageEntry; + +class DiscImageDevice : public Device { + public: + DiscImageDevice(const std::string_view mount_path, const std::filesystem::path& host_path); + ~DiscImageDevice() override; + + bool Initialize() override; + void Dump(string::StringBuffer* string_buffer) override; + Entry* ResolvePath(const std::string_view path) override; + + struct DiscInfo { + size_t game_offset; + size_t root_sector; + size_t root_size; + size_t host_size; + }; + + const Entry* root() const { return root_entry_.get(); } + uint64_t file_count() const { return file_count_; } + uint64_t total_file_size() const { return total_file_size_; } + const DiscInfo& disc_info() const { return disc_info_; } + + const std::string& name() const override { return name_; } + uint32_t attributes() const override { return 0; } + uint32_t component_name_max_length() const override { return 255; } + + uint32_t total_allocation_units() const override { + return uint32_t(mmap_->size() / sectors_per_allocation_unit() / bytes_per_sector()); + } + uint32_t available_allocation_units() const override { return 0; } + uint32_t sectors_per_allocation_unit() const override { return 1; } + uint32_t bytes_per_sector() const override { return 0x200; } + + private: + enum class Error { + kSuccess = 0, + kErrorOutOfMemory = -1, + kErrorReadError = -10, + kErrorFileMismatch = -30, + kErrorDamagedFile = -31, + }; + + std::string name_; + std::filesystem::path host_path_; + std::unique_ptr root_entry_; + std::unique_ptr mmap_; + DiscInfo disc_info_{}; + uint64_t file_count_ = 0; + uint64_t total_file_size_ = 0; + + typedef struct { + uint8_t* ptr; + size_t size; // Size (bytes) of total image. + size_t game_offset; // Offset (bytes) of game partition. + size_t root_sector; // Offset (sector) of root. + size_t root_offset; // Offset (bytes) of root. + size_t root_size; // Size (bytes) of root. + } ParseState; + + Error Verify(ParseState* state); + bool VerifyMagic(ParseState* state, size_t offset); + Error ReadAllEntries(ParseState* state, const uint8_t* root_buffer); + bool ReadEntry(ParseState* state, const uint8_t* buffer, uint16_t entry_ordinal, + DiscImageEntry* parent); +}; + +} // namespace rex::filesystem diff --git a/include/rex/filesystem/devices/disc_image_entry.h b/include/rex/filesystem/devices/disc_image_entry.h new file mode 100644 index 0000000..01dfc4a --- /dev/null +++ b/include/rex/filesystem/devices/disc_image_entry.h @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +#include +#include + +namespace rex::filesystem { + +class DiscImageDevice; + +class DiscImageEntry : public Entry { + public: + DiscImageEntry(Device* device, Entry* parent, const std::string_view path, + memory::MappedMemory* mmap); + ~DiscImageEntry() override; + + static std::unique_ptr Create(Device* device, Entry* parent, + const std::string_view name, + memory::MappedMemory* mmap); + + memory::MappedMemory* mmap() const { return mmap_; } + size_t data_offset() const { return data_offset_; } + size_t data_size() const { return data_size_; } + + X_STATUS Open(uint32_t desired_access, File** out_file) override; + + bool can_map() const override { return true; } + std::unique_ptr OpenMapped(memory::MappedMemory::Mode mode, size_t offset, + size_t length) override; + + private: + friend class DiscImageDevice; + + memory::MappedMemory* mmap_; + size_t data_offset_; + size_t data_size_; +}; + +} // namespace rex::filesystem diff --git a/include/rex/filesystem/devices/disc_image_file.h b/include/rex/filesystem/devices/disc_image_file.h new file mode 100644 index 0000000..d20cba9 --- /dev/null +++ b/include/rex/filesystem/devices/disc_image_file.h @@ -0,0 +1,46 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include + +namespace rex::filesystem { + +class DiscImageEntry; + +class DiscImageFile : public File { + public: + DiscImageFile(uint32_t file_access, DiscImageEntry* entry); + ~DiscImageFile() override; + + void Destroy() override; + + X_STATUS ReadSync(std::span buffer, size_t byte_offset, size_t* out_bytes_read) override; + X_STATUS WriteSync(std::span buffer, size_t byte_offset, + size_t* out_bytes_written) override { + (void)buffer; + (void)byte_offset; + (void)out_bytes_written; + return X_STATUS_ACCESS_DENIED; + } + X_STATUS SetLength(size_t length) override { + (void)length; + return X_STATUS_ACCESS_DENIED; + } + + private: + DiscImageEntry* entry_; +}; + +} // namespace rex::filesystem diff --git a/include/rex/filesystem/devices/host_path_device.h b/include/rex/filesystem/devices/host_path_device.h new file mode 100644 index 0000000..4e3c49b --- /dev/null +++ b/include/rex/filesystem/devices/host_path_device.h @@ -0,0 +1,53 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include + +namespace rex::filesystem { + +class HostPathEntry; + +class HostPathDevice : public Device { + public: + HostPathDevice(const std::string_view mount_path, const std::filesystem::path& host_path, + bool read_only); + ~HostPathDevice() override; + + bool Initialize() override; + void Dump(string::StringBuffer* string_buffer) override; + Entry* ResolvePath(const std::string_view path) override; + + bool is_read_only() const override { return read_only_; } + const std::filesystem::path& host_path() const { return host_path_; } + + const std::string& name() const override { return name_; } + uint32_t attributes() const override { return 0; } + uint32_t component_name_max_length() const override { return 255; } + + uint32_t total_allocation_units() const override { return 128 * 1024; } + uint32_t available_allocation_units() const override { return 128 * 1024; } + uint32_t sectors_per_allocation_unit() const override { return 1; } + uint32_t bytes_per_sector() const override { return 0x200; } + + private: + void PopulateEntry(HostPathEntry* parent_entry); + + std::string name_; + std::filesystem::path host_path_; + std::unique_ptr root_entry_; + bool read_only_; +}; + +} // namespace rex::filesystem diff --git a/include/rex/filesystem/devices/host_path_entry.h b/include/rex/filesystem/devices/host_path_entry.h new file mode 100644 index 0000000..ceff72d --- /dev/null +++ b/include/rex/filesystem/devices/host_path_entry.h @@ -0,0 +1,58 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include +#include + +namespace rex::filesystem { + +class HostPathDevice; + +class HostPathEntry : public Entry { + public: + HostPathEntry(Device* device, Entry* parent, const std::string_view path, + const std::filesystem::path& host_path); + ~HostPathEntry() override; + + static HostPathEntry* Create(Device* device, Entry* parent, + const std::filesystem::path& full_path, + rex::filesystem::FileInfo file_info); + + const std::filesystem::path& host_path() const { return host_path_; } + + X_STATUS Open(uint32_t desired_access, File** out_file) override; + bool Truncate() override; + + bool can_map() const override { return true; } + std::unique_ptr OpenMapped(memory::MappedMemory::Mode mode, size_t offset, + size_t length) override; + void update() override; + bool SetAttributes(uint64_t attributes) override; + bool SetCreateTimestamp(uint64_t timestamp) override; + bool SetAccessTimestamp(uint64_t timestamp) override; + bool SetWriteTimestamp(uint64_t timestamp) override; + + private: + friend class HostPathDevice; + + std::unique_ptr CreateEntryInternal(const std::string_view name, + uint32_t attributes) override; + bool DeleteEntryInternal(Entry* entry) override; + void RenameEntryInternal(const std::vector& path_parts) override; + + std::filesystem::path host_path_; +}; + +} // namespace rex::filesystem diff --git a/include/rex/filesystem/devices/host_path_file.h b/include/rex/filesystem/devices/host_path_file.h new file mode 100644 index 0000000..789315c --- /dev/null +++ b/include/rex/filesystem/devices/host_path_file.h @@ -0,0 +1,41 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +#include +#include + +namespace rex::filesystem { + +class HostPathEntry; + +class HostPathFile : public File { + public: + HostPathFile(uint32_t file_access, HostPathEntry* entry, + std::unique_ptr file_handle); + ~HostPathFile() override; + + void Destroy() override; + + X_STATUS ReadSync(std::span buffer, size_t byte_offset, size_t* out_bytes_read) override; + X_STATUS WriteSync(std::span buffer, size_t byte_offset, + size_t* out_bytes_written) override; + X_STATUS SetLength(size_t length) override; + + private: + std::unique_ptr file_handle_; +}; + +} // namespace rex::filesystem diff --git a/include/rex/filesystem/devices/null_device.h b/include/rex/filesystem/devices/null_device.h new file mode 100644 index 0000000..4068d34 --- /dev/null +++ b/include/rex/filesystem/devices/null_device.h @@ -0,0 +1,53 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include + +namespace rex::filesystem { + +class NullEntry; + +class NullDevice : public Device { + public: + NullDevice(const std::string& mount_path, const std::initializer_list& null_paths); + ~NullDevice() override; + + bool Initialize() override; + void Dump(string::StringBuffer* string_buffer) override; + Entry* ResolvePath(const std::string_view path) override; + + bool is_read_only() const override { return false; } + + const std::string& name() const override { return name_; } + uint32_t attributes() const override { return 0; } + uint32_t component_name_max_length() const override { return 40; } + + uint32_t total_allocation_units() const override { return 0x10; } + uint32_t available_allocation_units() const override { return 0x10; } + + // STFC/cache code seems to require the product of the next two to equal + // 0x10000 + uint32_t sectors_per_allocation_unit() const override { return 0x80; } + + // STFC requires <= 0x1000 + uint32_t bytes_per_sector() const override { return 0x200; } + + private: + std::string name_; + std::unique_ptr root_entry_; + std::vector null_paths_; +}; + +} // namespace rex::filesystem diff --git a/include/rex/filesystem/devices/null_entry.h b/include/rex/filesystem/devices/null_entry.h new file mode 100644 index 0000000..ee16fd7 --- /dev/null +++ b/include/rex/filesystem/devices/null_entry.h @@ -0,0 +1,38 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include +#include + +namespace rex::filesystem { + +class NullDevice; + +class NullEntry : public Entry { + public: + NullEntry(Device* device, Entry* parent, std::string path); + ~NullEntry() override; + + static NullEntry* Create(Device* device, Entry* parent, const std::string& path); + + X_STATUS Open(uint32_t desired_access, File** out_file) override; + + bool can_map() const override { return false; } + + private: + friend class NullDevice; +}; + +} // namespace rex::filesystem diff --git a/include/rex/filesystem/devices/null_file.h b/include/rex/filesystem/devices/null_file.h new file mode 100644 index 0000000..786abde --- /dev/null +++ b/include/rex/filesystem/devices/null_file.h @@ -0,0 +1,37 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +#include +#include + +namespace rex::filesystem { + +class NullEntry; + +class NullFile : public File { + public: + NullFile(uint32_t file_access, NullEntry* entry); + ~NullFile() override; + + void Destroy() override; + + X_STATUS ReadSync(std::span buffer, size_t byte_offset, size_t* out_bytes_read) override; + X_STATUS WriteSync(std::span buffer, size_t byte_offset, + size_t* out_bytes_written) override; + X_STATUS SetLength(size_t length) override; +}; + +} // namespace rex::filesystem diff --git a/include/rex/filesystem/devices/stfs_container_device.h b/include/rex/filesystem/devices/stfs_container_device.h new file mode 100644 index 0000000..a30bcec --- /dev/null +++ b/include/rex/filesystem/devices/stfs_container_device.h @@ -0,0 +1,142 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include +#include +#include +#include + +#include +#include +#include + +namespace rex::filesystem { + +// https://free60project.github.io/wiki/STFS.html + +class StfsContainerEntry; + +class StfsContainerDevice : public Device { + public: + const static uint32_t kBlockSize = 0x1000; + + StfsContainerDevice(const std::string_view mount_path, const std::filesystem::path& host_path); + ~StfsContainerDevice() override; + + bool Initialize() override; + + bool is_read_only() const override { + return header_.metadata.volume_type != XContentVolumeType::kStfs || + header_.metadata.volume_descriptor.stfs.flags.bits.read_only_format; + } + + void Dump(string::StringBuffer* string_buffer) override; + Entry* ResolvePath(const std::string_view path) override; + + const std::string& name() const override { return name_; } + uint32_t attributes() const override { return 0; } + uint32_t component_name_max_length() const override { return 40; } + const StfsHeader& header() const { return header_; } + + // Reads and validates the StfsHeader from an STFS package file without + // mounting the device. Returns nullptr if the file is missing, too small, + // or has an invalid magic. + static std::unique_ptr ReadPackageHeader(const std::filesystem::path& file_path); + + uint32_t total_allocation_units() const override { + if (header_.metadata.volume_type == XContentVolumeType::kStfs) { + return header_.metadata.volume_descriptor.stfs.total_block_count; + } + + return uint32_t(data_size() / sectors_per_allocation_unit() / bytes_per_sector()); + } + uint32_t available_allocation_units() const override { + if (!is_read_only()) { + auto& descriptor = header_.metadata.volume_descriptor.stfs; + return kBlocksPerHashLevel[2] - (descriptor.total_block_count - descriptor.free_block_count); + } + return 0; + } + uint32_t sectors_per_allocation_unit() const override { return 8; } + uint32_t bytes_per_sector() const override { return 0x200; } + + size_t data_size() const { + if (header_.header.header_size) { + if (header_.metadata.volume_type == XContentVolumeType::kStfs) { + return header_.metadata.volume_descriptor.stfs.total_block_count * kBlockSize; + } + return files_total_size_ - rex::round_up(header_.header.header_size, kBlockSize); + } + return files_total_size_ - sizeof(StfsHeader); + } + + private: + const uint32_t kBlocksPerHashLevel[3] = {170, 28900, 4913000}; + const uint32_t kEndOfChain = 0xFFFFFF; + const uint32_t kEntriesPerDirectoryBlock = kBlockSize / sizeof(StfsDirectoryEntry); + + enum class Error { + kSuccess = 0, + kErrorOutOfMemory = -1, + kErrorReadError = -10, + kErrorFileMismatch = -30, + kErrorDamagedFile = -31, + kErrorTooSmall = -32, + }; + + enum class SvodLayoutType { + kUnknown = 0x0, + kEnhancedGDF = 0x1, + kXSF = 0x2, + kSingleFile = 0x4, + }; + + XContentPackageType ReadMagic(const std::filesystem::path& path); + bool ResolveFromFolder(const std::filesystem::path& path); + + Error OpenFiles(); + void CloseFiles(); + + Error ReadHeaderAndVerify(FILE* header_file); + + Error ReadSVOD(); + Error ReadEntrySVOD(uint32_t sector, uint32_t ordinal, StfsContainerEntry* parent); + void BlockToOffsetSVOD(size_t sector, size_t* address, size_t* file_index); + + Error ReadSTFS(); + size_t BlockToOffsetSTFS(uint64_t block_index) const; + uint32_t BlockToHashBlockNumberSTFS(uint32_t block_index, uint32_t hash_level) const; + size_t BlockToHashBlockOffsetSTFS(uint32_t block_index, uint32_t hash_level) const; + + const StfsHashEntry* GetBlockHash(uint32_t block_index); + + std::string name_; + std::filesystem::path host_path_; + + std::map files_; + size_t files_total_size_; + + size_t svod_base_offset_; + + std::unique_ptr root_entry_; + StfsHeader header_; + SvodLayoutType svod_layout_; + uint32_t blocks_per_hash_table_; + uint32_t block_step[2]; + + std::unordered_map cached_hash_tables_; +}; + +} // namespace rex::filesystem diff --git a/include/rex/filesystem/devices/stfs_container_entry.h b/include/rex/filesystem/devices/stfs_container_entry.h new file mode 100644 index 0000000..45d7254 --- /dev/null +++ b/include/rex/filesystem/devices/stfs_container_entry.h @@ -0,0 +1,60 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include + +#include +#include + +namespace rex::filesystem { +typedef std::map MultiFileHandles; + +class StfsContainerDevice; + +class StfsContainerEntry : public Entry { + public: + StfsContainerEntry(Device* device, Entry* parent, const std::string_view path, + MultiFileHandles* files); + ~StfsContainerEntry() override; + + static std::unique_ptr Create(Device* device, Entry* parent, + const std::string_view name, + MultiFileHandles* files); + + MultiFileHandles* files() const { return files_; } + size_t data_offset() const { return data_offset_; } + size_t data_size() const { return data_size_; } + size_t block() const { return block_; } + + X_STATUS Open(uint32_t desired_access, File** out_file) override; + + struct BlockRecord { + size_t file; + size_t offset; + size_t length; + }; + const std::vector& block_list() const { return block_list_; } + + private: + friend class StfsContainerDevice; + + MultiFileHandles* files_; + size_t data_offset_; + size_t data_size_; + size_t block_; + std::vector block_list_; +}; + +} // namespace rex::filesystem diff --git a/include/rex/filesystem/devices/stfs_container_file.h b/include/rex/filesystem/devices/stfs_container_file.h new file mode 100644 index 0000000..b0e0b51 --- /dev/null +++ b/include/rex/filesystem/devices/stfs_container_file.h @@ -0,0 +1,40 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include + +namespace rex::filesystem { + +class StfsContainerEntry; + +class StfsContainerFile : public File { + public: + StfsContainerFile(uint32_t file_access, StfsContainerEntry* entry); + ~StfsContainerFile() override; + + void Destroy() override; + + X_STATUS ReadSync(std::span buffer, size_t byte_offset, size_t* out_bytes_read) override; + X_STATUS WriteSync(std::span /*buffer*/, size_t /*byte_offset*/, + size_t* /*out_bytes_written*/) override { + return X_STATUS_ACCESS_DENIED; + } + X_STATUS SetLength(size_t /*length*/) override { return X_STATUS_ACCESS_DENIED; } + + private: + StfsContainerEntry* entry_; +}; + +} // namespace rex::filesystem diff --git a/include/rex/filesystem/devices/stfs_xbox.h b/include/rex/filesystem/devices/stfs_xbox.h new file mode 100644 index 0000000..e7166a5 --- /dev/null +++ b/include/rex/filesystem/devices/stfs_xbox.h @@ -0,0 +1,479 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace rex::filesystem { + +// Import kernel content types for STFS structures +using rex::system::XContentType; +using rex::system::XLanguage; + +// Convert FAT timestamp to 100-nanosecond intervals since January 1, 1601 (UTC) +inline uint64_t decode_fat_timestamp(const uint32_t date, const uint32_t time) { + struct tm tm = {}; + // 80 is the difference between 1980 (FAT) and 1900 (tm); + tm.tm_year = ((0xFE00 & date) >> 9) + 80; + tm.tm_mon = ((0x01E0 & date) >> 5) - 1; + tm.tm_mday = (0x001F & date) >> 0; + tm.tm_hour = (0xF800 & time) >> 11; + tm.tm_min = (0x07E0 & time) >> 5; + tm.tm_sec = (0x001F & time) << 1; // the value stored in 2-seconds intervals + tm.tm_isdst = 0; + +#if REX_PLATFORM_WIN32 + time_t timet = _mkgmtime(&tm); +#else + time_t timet = timegm(&tm); +#endif + + if (timet == -1) { + return 0; + } + // 11644473600LL is a difference between 1970 and 1601 + return (timet + 11644473600LL) * 10000000; +} + +// Structs used for interchange between Xenia and actual Xbox360 kernel/XAM + +inline uint32_t load_uint24_be(const uint8_t* p) { + return (uint32_t(p[0]) << 16) | (uint32_t(p[1]) << 8) | uint32_t(p[2]); +} +inline uint32_t load_uint24_le(const uint8_t* p) { + return (uint32_t(p[2]) << 16) | (uint32_t(p[1]) << 8) | uint32_t(p[0]); +} +inline void store_uint24_le(uint8_t* p, uint32_t value) { + p[2] = uint8_t((value >> 16) & 0xFF); + p[1] = uint8_t((value >> 8) & 0xFF); + p[0] = uint8_t(value & 0xFF); +} + +enum class XContentPackageType : uint32_t { + kCon = 0x434F4E20, + kPirs = 0x50495253, + kLive = 0x4C495645, +}; + +enum class XContentVolumeType : uint32_t { + kStfs = 0, + kSvod = 1, +}; + +/* STFS structures */ +#pragma pack(push, 1) +struct StfsVolumeDescriptor { + uint8_t descriptor_length; + uint8_t version; + union { + uint8_t as_byte; + struct { + uint8_t read_only_format : 1; // if set, only uses a single backing-block + // per hash table (no resiliency), + // otherwise uses two + uint8_t root_active_index : 1; // if set, uses secondary backing-block + // for the highest-level hash table + + uint8_t directory_overallocated : 1; + uint8_t directory_index_bounds_valid : 1; + } bits; + } flags; + uint16_t file_table_block_count; + uint8_t file_table_block_number_raw[3]; + uint8_t top_hash_table_hash[0x14]; + be total_block_count; + be free_block_count; + + uint32_t file_table_block_number() const { return load_uint24_le(file_table_block_number_raw); } + + void set_file_table_block_number(uint32_t value) { + store_uint24_le(file_table_block_number_raw, value); + } + + bool is_valid() const { return descriptor_length == sizeof(StfsVolumeDescriptor); } +}; +static_assert_size(StfsVolumeDescriptor, 0x24); +#pragma pack(pop) + +enum class StfsHashState : uint8_t { + kFree = 0, // unallocated but doesn't exist in package (needs to expand)? + kFree2 = 1, // unallocated but exists in package? + kInUse = 2, +}; + +struct StfsHashEntry { + uint8_t sha1[0x14]; + + rex::be info_raw; + + uint32_t level0_next_block() const { return info_raw & 0xFFFFFF; } + void set_level0_next_block(uint32_t value) { + info_raw = (info_raw & ~0xFFFFFF) | (value & 0xFFFFFF); + } + + StfsHashState level0_allocation_state() const { + return StfsHashState(uint8_t(((info_raw & 0xC0000000) >> 30) & 0xFF)); + } + void set_level0_allocation_state(StfsHashState value) { + info_raw = (info_raw & ~0xC0000000) | (uint32_t(value) << 30); + } + + uint32_t levelN_num_blocks_free() const { return info_raw & 0x7FFF; } + void set_levelN_num_blocks_free(uint32_t value) { + info_raw = (info_raw & ~0x7FFF) | (value & 0x7FFF); + } + + uint32_t levelN_num_blocks_unk() const { return ((info_raw & 0x3FFF8000) >> 15) & 0x7FFF; } + void set_levelN_num_blocks_unk(uint32_t value) { + info_raw = (info_raw & ~0x3FFF8000) | ((value & 0x7FFF) << 15); + } + + bool levelN_active_index() const { return (info_raw & 0x40000000) != 0; } + void set_levelN_active_index(bool value) { + info_raw = (info_raw & ~0x40000000) | (value ? 0x40000000 : 0); + } + + bool levelN_writeable() const { return (info_raw & 0x80000000) != 0; } + void set_levelN_writeable(bool value) { + info_raw = (info_raw & ~0x80000000) | (value ? 0x80000000 : 0); + } +}; +static_assert_size(StfsHashEntry, 0x18); + +struct StfsHashTable { + StfsHashEntry entries[170]; + rex::be num_blocks; // num L0 blocks covered by this table? + uint8_t padding[12]; +}; +static_assert_size(StfsHashTable, 0x1000); + +struct StfsDirectoryEntry { + char name[40]; + + struct { + uint8_t name_length : 6; + uint8_t contiguous : 1; + uint8_t directory : 1; + } flags; + + uint8_t valid_data_blocks_raw[3]; + uint8_t allocated_data_blocks_raw[3]; + uint8_t start_block_number_raw[3]; + + be directory_index; + + be length; + + be create_date; + be create_time; + be modified_date; + be modified_time; + + uint32_t valid_data_blocks() const { return load_uint24_le(valid_data_blocks_raw); } + + void set_valid_data_blocks(uint32_t value) { store_uint24_le(valid_data_blocks_raw, value); } + + uint32_t allocated_data_blocks() const { return load_uint24_le(allocated_data_blocks_raw); } + + void set_allocated_data_blocks(uint32_t value) { + store_uint24_le(allocated_data_blocks_raw, value); + } + + uint32_t start_block_number() const { return load_uint24_le(start_block_number_raw); } + + void set_start_block_number(uint32_t value) { store_uint24_le(start_block_number_raw, value); } +}; +static_assert_size(StfsDirectoryEntry, 0x40); + +struct StfsDirectoryBlock { + StfsDirectoryEntry entries[0x40]; +}; +static_assert_size(StfsDirectoryBlock, 0x1000); + +/* SVOD structures */ +struct SvodDeviceDescriptor { + uint8_t descriptor_length; + uint8_t block_cache_element_count; + uint8_t worker_thread_processor; + uint8_t worker_thread_priority; + uint8_t first_fragment_hash_entry[0x14]; + union { + uint8_t as_byte; + struct { + uint8_t must_be_zero_for_future_usage : 6; + uint8_t enhanced_gdf_layout : 1; + uint8_t zero_for_downlevel_clients : 1; + } bits; + } features; + uint8_t num_data_blocks_raw[3]; + uint8_t start_data_block_raw[3]; + uint8_t reserved[5]; + + uint32_t num_data_blocks() { return load_uint24_le(num_data_blocks_raw); } + + uint32_t start_data_block() { return load_uint24_le(start_data_block_raw); } +}; +static_assert_size(SvodDeviceDescriptor, 0x24); + +/* XContent structures */ +struct XContentLicense { + be licensee_id; + be license_bits; + be license_flags; +}; +static_assert_size(XContentLicense, 0x10); + +struct XContentMediaData { + uint8_t series_id[0x10]; + uint8_t season_id[0x10]; + be season_number; + be episode_number; +}; +static_assert_size(XContentMediaData, 0x24); + +struct XContentAvatarAssetData { + be sub_category; + be colorizable; + uint8_t asset_id[0x10]; + uint8_t skeleton_version_mask; + uint8_t reserved[0xB]; +}; +static_assert_size(XContentAvatarAssetData, 0x24); + +struct XContentAttributes { + uint8_t profile_transfer : 1; + uint8_t device_transfer : 1; + uint8_t move_only_transfer : 1; + uint8_t kinect_enabled : 1; + uint8_t disable_network_storage : 1; + uint8_t deep_link_supported : 1; + uint8_t reserved : 2; +}; +static_assert_size(XContentAttributes, 1); + +#pragma pack(push, 1) +struct XContentMetadata { + static const uint32_t kThumbLengthV1 = 0x4000; + static const uint32_t kThumbLengthV2 = 0x3D00; + + static const uint32_t kNumLanguagesV1 = 9; + // metadata_version 2 adds 3 languages inside thumbnail/title_thumbnail space + static const uint32_t kNumLanguagesV2 = 12; + + be content_type; + be metadata_version; + be content_size; + xex2_opt_execution_info execution_info; + uint8_t console_id[5]; + be profile_id; + union { + StfsVolumeDescriptor stfs; + SvodDeviceDescriptor svod; + } volume_descriptor; + be data_file_count; + be data_file_size; + be volume_type; + be online_creator; + be category; + uint8_t reserved2[0x20]; + union { + XContentMediaData media_data; + XContentAvatarAssetData avatar_asset_data; + } metadata_v2; + uint8_t device_id[0x14]; + union { + be uint[kNumLanguagesV1][128]; + char16_t chars[kNumLanguagesV1][128]; + } display_name_raw; + union { + be uint[kNumLanguagesV1][128]; + char16_t chars[kNumLanguagesV1][128]; + } description_raw; + union { + be uint[64]; + char16_t chars[64]; + } publisher_raw; + union { + be uint[64]; + char16_t chars[64]; + } title_name_raw; + union { + uint8_t as_byte; + XContentAttributes bits; + } flags; + be thumbnail_size; + be title_thumbnail_size; + uint8_t thumbnail[kThumbLengthV2]; + union { + be uint[kNumLanguagesV2 - kNumLanguagesV1][128]; + char16_t chars[kNumLanguagesV2 - kNumLanguagesV1][128]; + } display_name_ex_raw; + uint8_t title_thumbnail[kThumbLengthV2]; + union { + be uint[kNumLanguagesV2 - kNumLanguagesV1][128]; + char16_t chars[kNumLanguagesV2 - kNumLanguagesV1][128]; + } description_ex_raw; + + std::u16string display_name(XLanguage language) const { + uint32_t lang_id = uint32_t(language) - 1; + + if (lang_id >= kNumLanguagesV2) { + assert_always(); + // no room for this lang, read from english slot.. + lang_id = uint32_t(XLanguage::kEnglish) - 1; + } + + const be* str = 0; + if (lang_id >= 0 && lang_id < kNumLanguagesV1) { + str = display_name_raw.uint[lang_id]; + } else if (lang_id >= kNumLanguagesV1 && lang_id < kNumLanguagesV2 && metadata_version >= 2) { + str = display_name_ex_raw.uint[lang_id - kNumLanguagesV1]; + } + + if (!str) { + // Invalid language ID? + assert_always(); + return u""; + } + + return memory::load_and_swap(str); + } + + std::u16string description(XLanguage language) const { + uint32_t lang_id = uint32_t(language) - 1; + + if (lang_id >= kNumLanguagesV2) { + assert_always(); + // no room for this lang, read from english slot.. + lang_id = uint32_t(XLanguage::kEnglish) - 1; + } + + const be* str = 0; + if (lang_id >= 0 && lang_id < kNumLanguagesV1) { + str = description_raw.uint[lang_id]; + } else if (lang_id >= kNumLanguagesV1 && lang_id < kNumLanguagesV2 && metadata_version >= 2) { + str = description_ex_raw.uint[lang_id - kNumLanguagesV1]; + } + + if (!str) { + // Invalid language ID? + assert_always(); + return u""; + } + + return memory::load_and_swap(str); + } + + std::u16string publisher() const { + return memory::load_and_swap(publisher_raw.uint); + } + + std::u16string title_name() const { + return memory::load_and_swap(title_name_raw.uint); + } + + bool set_display_name(XLanguage language, const std::u16string_view value) { + uint32_t lang_id = uint32_t(language) - 1; + + if (lang_id >= kNumLanguagesV2) { + assert_always(); + // no room for this lang, store in english slot.. + lang_id = uint32_t(XLanguage::kEnglish) - 1; + } + + char16_t* str = 0; + if (lang_id >= 0 && lang_id < kNumLanguagesV1) { + str = display_name_raw.chars[lang_id]; + } else if (lang_id >= kNumLanguagesV1 && lang_id < kNumLanguagesV2 && metadata_version >= 2) { + str = display_name_ex_raw.chars[lang_id - kNumLanguagesV1]; + } + + if (!str) { + // Invalid language ID? + assert_always(); + return false; + } + + rex::string::util_copy_and_swap_truncating(str, value, countof(display_name_raw.chars[0])); + return true; + } + + bool set_description(XLanguage language, const std::u16string_view value) { + uint32_t lang_id = uint32_t(language) - 1; + + if (lang_id >= kNumLanguagesV2) { + assert_always(); + // no room for this lang, store in english slot.. + lang_id = uint32_t(XLanguage::kEnglish) - 1; + } + + char16_t* str = 0; + if (lang_id >= 0 && lang_id < kNumLanguagesV1) { + str = description_raw.chars[lang_id]; + } else if (lang_id >= kNumLanguagesV1 && lang_id < kNumLanguagesV2 && metadata_version >= 2) { + str = description_ex_raw.chars[lang_id - kNumLanguagesV1]; + } + + if (!str) { + // Invalid language ID? + assert_always(); + return false; + } + + rex::string::util_copy_and_swap_truncating(str, value, countof(description_raw.chars[0])); + return true; + } + + void set_publisher(const std::u16string_view value) { + rex::string::util_copy_and_swap_truncating(publisher_raw.chars, value, + countof(publisher_raw.chars)); + } + + void set_title_name(const std::u16string_view value) { + rex::string::util_copy_and_swap_truncating(title_name_raw.chars, value, + countof(title_name_raw.chars)); + } +}; +static_assert_size(XContentMetadata, 0x93D6); + +struct XContentHeader { + be magic; + uint8_t signature[0x228]; + XContentLicense licenses[0x10]; + uint8_t content_id[0x14]; + be header_size; + + bool is_magic_valid() const { + return magic == XContentPackageType::kCon || magic == XContentPackageType::kLive || + magic == XContentPackageType::kPirs; + } +}; +static_assert_size(XContentHeader, 0x344); +#pragma pack(pop) + +struct StfsHeader { + XContentHeader header; + XContentMetadata metadata; + // TODO: title/system updates contain more data after XContentMetadata, seems + // to affect header.header_size +}; +static_assert_size(StfsHeader, 0x971A); + +} // namespace rex::filesystem diff --git a/include/rex/filesystem/entry.h b/include/rex/filesystem/entry.h new file mode 100644 index 0000000..9a51a13 --- /dev/null +++ b/include/rex/filesystem/entry.h @@ -0,0 +1,166 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace rex::system { +class KernelState; +class XFile; +} // namespace rex::system + +namespace rex::filesystem { + +class Device; +class File; + +// Matches https://source.winehq.org/source/include/winternl.h#1591. +enum class FileAction { + kSuperseded = 0, + kOpened = 1, + kCreated = 2, + kOverwritten = 3, + kExists = 4, + kDoesNotExist = 5, +}; + +enum class FileDisposition { + // If exist replace, else create. + kSuperscede = 0, + // If exist open, else error. + kOpen = 1, + // If exist error, else create. + kCreate = 2, + // If exist open, else create. + kOpenIf = 3, + // If exist open and overwrite, else error. + kOverwrite = 4, + // If exist open and overwrite, else create. + kOverwriteIf = 5, +}; + +// Reuse rex::filesystem definition. +using FileAccess = rex::filesystem::FileAccess; + +enum FileAttributeFlags : uint32_t { + kFileAttributeNone = 0x0000, + kFileAttributeReadOnly = 0x0001, + kFileAttributeHidden = 0x0002, + kFileAttributeSystem = 0x0004, + kFileAttributeDirectory = 0x0010, + kFileAttributeArchive = 0x0020, + kFileAttributeDevice = 0x0040, + kFileAttributeNormal = 0x0080, + kFileAttributeTemporary = 0x0100, + kFileAttributeCompressed = 0x0800, + kFileAttributeEncrypted = 0x4000, +}; + +class Entry { + public: + virtual ~Entry(); + + void Dump(rex::string::StringBuffer* string_buffer, int indent); + + Device* device() const { return device_; } + Entry* parent() const { return parent_; } + const std::string& path() const { return path_; } + const std::string& absolute_path() const { return absolute_path_; } + const std::string& name() const { return name_; } + uint32_t attributes() const { return attributes_; } + size_t size() const { return size_; } + size_t allocation_size() const { return allocation_size_; } + uint64_t create_timestamp() const { return create_timestamp_; } + uint64_t access_timestamp() const { return access_timestamp_; } + uint64_t write_timestamp() const { return write_timestamp_; } + bool delete_on_close() const { return delete_on_close_; } + + virtual bool SetAttributes([[maybe_unused]] uint64_t attributes) { return false; } + virtual bool SetCreateTimestamp([[maybe_unused]] uint64_t timestamp) { return false; } + virtual bool SetAccessTimestamp([[maybe_unused]] uint64_t timestamp) { return false; } + virtual bool SetWriteTimestamp([[maybe_unused]] uint64_t timestamp) { return false; } + void SetForDeletion(bool delete_on_close) { delete_on_close_ = delete_on_close; } + + bool is_read_only() const; + + Entry* GetChild(const std::string_view name); + Entry* ResolvePath(const std::string_view path); + + const std::vector>& children() const { return children_; } + size_t child_count() const { return children_.size(); } + Entry* IterateChildren(const rex::filesystem::WildcardEngine& engine, size_t* current_index); + + Entry* CreateEntry(const std::string_view name, uint32_t attributes); + bool Delete(Entry* entry); + bool Delete(); + virtual bool Truncate() { return false; } + void Rename(const std::filesystem::path& file_path); + void Touch(); + + // If successful, out_file points to a new file. When finished, call + // file->Destroy() + virtual X_STATUS Open(uint32_t desired_access, File** out_file) = 0; + + virtual bool can_map() const { return false; } + virtual std::unique_ptr OpenMapped(memory::MappedMemory::Mode mode, + size_t offset = 0, size_t length = 0) { + (void)mode; + (void)offset; + (void)length; + return nullptr; + } + virtual void update() { return; } + + protected: + Entry(Device* device, Entry* parent, const std::string_view path); + + virtual std::unique_ptr CreateEntryInternal(const std::string_view name, + uint32_t attributes) { + (void)name; + (void)attributes; + return nullptr; + } + virtual bool DeleteEntryInternal(Entry* entry) { + (void)entry; + return false; + } + virtual void RenameEntryInternal(const std::vector& path_parts) { + (void)path_parts; + } + + rex::thread::global_critical_region global_critical_region_; + Device* device_; + Entry* parent_; + std::string path_; + std::string absolute_path_; + std::string name_; + uint32_t attributes_; // FileAttributeFlags + size_t size_; + size_t allocation_size_; + uint64_t create_timestamp_; + uint64_t access_timestamp_; + uint64_t write_timestamp_; + std::vector> children_; + bool delete_on_close_ = false; +}; + +} // namespace rex::filesystem diff --git a/include/rex/filesystem/file.h b/include/rex/filesystem/file.h new file mode 100644 index 0000000..1f22413 --- /dev/null +++ b/include/rex/filesystem/file.h @@ -0,0 +1,71 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +#include + +namespace rex::filesystem { + +class Entry; + +class File { + public: + File(uint32_t file_access, Entry* entry) : file_access_(file_access), entry_(entry) {} + virtual ~File() = default; + + virtual void Destroy() = 0; + + virtual X_STATUS ReadSync(std::span buffer, size_t byte_offset, + size_t* out_bytes_read) = 0; + virtual X_STATUS WriteSync(std::span buffer, size_t byte_offset, + size_t* out_bytes_written) = 0; + + // TODO: Parameters + virtual X_STATUS ReadAsync(std::span buffer, size_t byte_offset, + size_t* out_bytes_read) { + (void)buffer; + (void)byte_offset; + (void)out_bytes_read; + + return X_STATUS_NOT_IMPLEMENTED; + } + + // TODO: Parameters + virtual X_STATUS WriteAsync(std::span buffer, size_t byte_offset, + size_t* out_bytes_written) { + (void)buffer; + (void)byte_offset; + (void)out_bytes_written; + + return X_STATUS_NOT_IMPLEMENTED; + } + + virtual X_STATUS SetLength(size_t length) { + (void)length; + return X_STATUS_NOT_IMPLEMENTED; + } + + // rex::filesystem::FileAccess + uint32_t file_access() const { return file_access_; } + const Entry* entry() const { return entry_; } + Entry* entry() { return entry_; } + + protected: + // rex::filesystem::FileAccess + uint32_t file_access_ = 0; + Entry* entry_ = nullptr; +}; + +} // namespace rex::filesystem diff --git a/include/rex/filesystem/flags.h b/include/rex/filesystem/flags.h new file mode 100644 index 0000000..d1f7f95 --- /dev/null +++ b/include/rex/filesystem/flags.h @@ -0,0 +1,17 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +REXCVAR_DECLARE(std::string, dump_source); +REXCVAR_DECLARE(std::string, dump_path); diff --git a/include/rex/filesystem/vfs.h b/include/rex/filesystem/vfs.h new file mode 100644 index 0000000..96f86fe --- /dev/null +++ b/include/rex/filesystem/vfs.h @@ -0,0 +1,59 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +REXCVAR_DECLARE(bool, allow_game_relative_writes); + +namespace rex::filesystem { + +class VirtualFileSystem { + public: + VirtualFileSystem(); + ~VirtualFileSystem(); + + bool RegisterDevice(std::unique_ptr device); + bool UnregisterDevice(const std::string_view path); + + bool RegisterSymbolicLink(const std::string_view path, const std::string_view target); + bool UnregisterSymbolicLink(const std::string_view path); + bool FindSymbolicLink(const std::string_view path, std::string& target); + + Entry* ResolvePath(const std::string_view path); + + Entry* CreatePath(const std::string_view path, uint32_t attributes); + bool DeletePath(const std::string_view path); + + X_STATUS OpenFile(Entry* root_entry, const std::string_view path, + FileDisposition creation_disposition, uint32_t desired_access, + bool is_directory, bool is_non_directory, File** out_file, + FileAction* out_action); + + private: + rex::thread::global_critical_region global_critical_region_; + std::vector> devices_; + std::unordered_map symlinks_; + + bool ResolveSymbolicLink(const std::string_view path, std::string& result); +}; + +} // namespace rex::filesystem diff --git a/include/rex/filesystem/wildcard.h b/include/rex/filesystem/wildcard.h new file mode 100644 index 0000000..d4ffdcd --- /dev/null +++ b/include/rex/filesystem/wildcard.h @@ -0,0 +1,60 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include + +#include + +namespace rex { +namespace filesystem { + +class WildcardFlags { + public: + bool FromStart : 1, ToEnd : 1, ExactLength : 1; + + WildcardFlags(); + WildcardFlags(bool start, bool end, bool exact_length); + + static WildcardFlags FIRST; + static WildcardFlags LAST; + static WildcardFlags ANY; + static WildcardFlags FIRST_AND_LAST; +}; + +class WildcardRule { + public: + WildcardRule(const std::string_view match, const WildcardFlags& flags); + bool Check(const std::string_view lower, std::string_view::size_type* offset) const; + + private: + std::string match_; + WildcardFlags rules_; +}; + +class WildcardEngine { + public: + void SetRule(const std::string_view pattern); + + // Always ignoring case + bool Match(const std::string_view str) const; + + private: + std::vector rules_; + void PreparePattern(const std::string_view pattern); +}; + +} // namespace filesystem +} // namespace rex diff --git a/include/rex/graphics/command_processor.h b/include/rex/graphics/command_processor.h new file mode 100644 index 0000000..6998a45 --- /dev/null +++ b/include/rex/graphics/command_processor.h @@ -0,0 +1,312 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::stream { +class ByteStream; +} // namespace rex::stream + +namespace rex::graphics { + +class GraphicsSystem; +class Shader; + +enum class ReadbackResolveMode { + kDisabled, + kFast, + kSome, + kFull, +}; + +struct SwapState { + // Lock must be held when changing data in this structure. + std::mutex mutex; + // Dimensions of the framebuffer textures. Should match window size. + uint32_t width = 0; + uint32_t height = 0; + // Current front buffer, being drawn to the screen. + uintptr_t front_buffer_texture = 0; + // Current back buffer, being updated by the CP. + uintptr_t back_buffer_texture = 0; + // Backend data + void* backend_data = nullptr; + // Whether the back buffer is dirty and a swap is pending. + bool pending = false; +}; + +enum class SwapMode { + kNormal, + kIgnored, +}; + +enum class GammaRampType { + kUnknown = 0, + kTable, + kPWL, +}; + +class CommandProcessor { + public: + enum class SwapPostEffect { + kNone, + kFxaa, + kFxaaExtreme, + }; + + CommandProcessor(GraphicsSystem* graphics_system, system::KernelState* kernel_state); + virtual ~CommandProcessor(); + + uint32_t counter() const { return counter_; } + void increment_counter() { counter_++; } + + Shader* active_vertex_shader() const { return active_vertex_shader_; } + Shader* active_pixel_shader() const { return active_pixel_shader_; } + + virtual bool Initialize(); + virtual void Shutdown(); + + void CallInThread(std::function fn); + + virtual void ClearCaches(); + virtual void InvalidateGpuMemory(); + + // "Desired" is for the external thread managing the post-processing effect. + SwapPostEffect GetDesiredSwapPostEffect() const { return swap_post_effect_desired_; } + void SetDesiredSwapPostEffect(SwapPostEffect swap_post_effect); + // Implementations must not make assumptions that the front buffer will + // necessarily be a resolve destination - it may be a texture generated by any + // means like written to by the CPU or loaded from a file (the disclaimer + // screen right in the beginning of 4D530AA4 is not a resolved render target, + // for instance). + virtual void IssueSwap(uint32_t frontbuffer_ptr, uint32_t frontbuffer_width, + uint32_t frontbuffer_height) = 0; + + // May be called not only from the command processor thread when the command + // processor is paused, and the termination of this function may be explicitly + // awaited. + virtual void InitializeShaderStorage(const std::filesystem::path& cache_root, uint32_t title_id, + bool blocking); + + virtual void RequestFrameTrace(const std::filesystem::path& root_path); + virtual void BeginTracing(const std::filesystem::path& root_path); + virtual void EndTracing(); + + virtual void TracePlaybackWroteMemory(uint32_t base_ptr, uint32_t length) = 0; + + void RestoreRegisters(uint32_t first_register, const uint32_t* register_values, + uint32_t register_count, bool execute_callbacks); + void RestoreGammaRamp(const reg::DC_LUT_30_COLOR* new_gamma_ramp_256_entry_table, + const reg::DC_LUT_PWL_DATA* new_gamma_ramp_pwl_rgb, + uint32_t new_gamma_ramp_rw_component); + virtual void RestoreEdramSnapshot(const void* snapshot) = 0; + + void InitializeRingBuffer(uint32_t ptr, uint32_t size_log2); + void EnableReadPointerWriteBack(uint32_t ptr, uint32_t block_size_log2); + + void UpdateWritePointer(uint32_t value); + + void ExecutePacket(uint32_t ptr, uint32_t count); + + bool is_paused() const { return paused_; } + void Pause(); + void Resume(); + + bool Save(::rex::stream::ByteStream* stream); + bool Restore(::rex::stream::ByteStream* stream); + + protected: + struct IndexBufferInfo { + xenos::IndexFormat format = xenos::IndexFormat::kInt16; + xenos::Endian endianness = xenos::Endian::kNone; + uint32_t count = 0; + uint32_t guest_base = 0; + size_t length = 0; + }; + + void WorkerThreadMain(); + virtual bool SetupContext() = 0; + virtual void ShutdownContext() = 0; + + virtual void WriteRegister(uint32_t index, uint32_t value); + uint32_t ReadRegisterValue(uint32_t index) const; + virtual void WriteRegistersFromMem(uint32_t start_index, uint32_t* base, uint32_t num_registers); + virtual void WriteRegisterRangeFromRing(memory::RingBuffer* ring, uint32_t base, + uint32_t num_registers); + void WriteALURangeFromRing(memory::RingBuffer* ring, uint32_t base, uint32_t num_registers); + void WriteFetchRangeFromRing(memory::RingBuffer* ring, uint32_t base, uint32_t num_registers); + void WriteBoolRangeFromRing(memory::RingBuffer* ring, uint32_t base, uint32_t num_registers); + void WriteLoopRangeFromRing(memory::RingBuffer* ring, uint32_t base, uint32_t num_registers); + void WriteREGISTERSRangeFromRing(memory::RingBuffer* ring, uint32_t base, uint32_t num_registers); + void WriteALURangeFromMem(uint32_t start_index, uint32_t* base, uint32_t num_registers); + void WriteFetchRangeFromMem(uint32_t start_index, uint32_t* base, uint32_t num_registers); + void WriteBoolRangeFromMem(uint32_t start_index, uint32_t* base, uint32_t num_registers); + void WriteLoopRangeFromMem(uint32_t start_index, uint32_t* base, uint32_t num_registers); + void WriteREGISTERSRangeFromMem(uint32_t start_index, uint32_t* base, uint32_t num_registers); + + const reg::DC_LUT_30_COLOR* gamma_ramp_256_entry_table() const { + return gamma_ramp_256_entry_table_; + } + const reg::DC_LUT_PWL_DATA* gamma_ramp_pwl_rgb() const { return gamma_ramp_pwl_rgb_[0]; } + virtual void OnGammaRamp256EntryTableValueWritten() {} + virtual void OnGammaRampPWLValueWritten() {} + + virtual void MakeCoherent(); + virtual void PrepareForWait(); + virtual void ReturnFromWait(); + + uint32_t ExecutePrimaryBuffer(uint32_t start_index, uint32_t end_index); + virtual void OnPrimaryBufferEnd() {} + void ExecuteIndirectBuffer(uint32_t ptr, uint32_t length); + bool ExecutePacket(memory::RingBuffer* reader); + bool ExecutePacketType0(memory::RingBuffer* reader, uint32_t packet); + bool ExecutePacketType1(memory::RingBuffer* reader, uint32_t packet); + bool ExecutePacketType2(memory::RingBuffer* reader, uint32_t packet); + bool ExecutePacketType3(memory::RingBuffer* reader, uint32_t packet); + bool ExecutePacketType3_ME_INIT(memory::RingBuffer* reader, uint32_t packet, uint32_t count); + bool ExecutePacketType3_NOP(memory::RingBuffer* reader, uint32_t packet, uint32_t count); + bool ExecutePacketType3_INTERRUPT(memory::RingBuffer* reader, uint32_t packet, uint32_t count); + bool ExecutePacketType3_XE_SWAP(memory::RingBuffer* reader, uint32_t packet, uint32_t count); + bool ExecutePacketType3_INDIRECT_BUFFER(memory::RingBuffer* reader, uint32_t packet, + uint32_t count); + bool ExecutePacketType3_WAIT_REG_MEM(memory::RingBuffer* reader, uint32_t packet, uint32_t count); + bool ExecutePacketType3_REG_RMW(memory::RingBuffer* reader, uint32_t packet, uint32_t count); + bool ExecutePacketType3_REG_TO_MEM(memory::RingBuffer* reader, uint32_t packet, uint32_t count); + bool ExecutePacketType3_MEM_WRITE(memory::RingBuffer* reader, uint32_t packet, uint32_t count); + bool ExecutePacketType3_COND_WRITE(memory::RingBuffer* reader, uint32_t packet, uint32_t count); + bool ExecutePacketType3_EVENT_WRITE(memory::RingBuffer* reader, uint32_t packet, uint32_t count); + bool ExecutePacketType3_EVENT_WRITE_SHD(memory::RingBuffer* reader, uint32_t packet, + uint32_t count); + bool ExecutePacketType3_EVENT_WRITE_EXT(memory::RingBuffer* reader, uint32_t packet, + uint32_t count); + virtual bool ExecutePacketType3_EVENT_WRITE_ZPD(memory::RingBuffer* reader, uint32_t packet, + uint32_t count); + bool ExecutePacketType3Draw(memory::RingBuffer* reader, uint32_t packet, const char* opcode_name, + uint32_t viz_query_condition, uint32_t count_remaining); + bool ExecutePacketType3_DRAW_INDX(memory::RingBuffer* reader, uint32_t packet, uint32_t count); + bool ExecutePacketType3_DRAW_INDX_2(memory::RingBuffer* reader, uint32_t packet, uint32_t count); + bool ExecutePacketType3_SET_CONSTANT(memory::RingBuffer* reader, uint32_t packet, uint32_t count); + bool ExecutePacketType3_SET_CONSTANT2(memory::RingBuffer* reader, uint32_t packet, + uint32_t count); + bool ExecutePacketType3_LOAD_ALU_CONSTANT(memory::RingBuffer* reader, uint32_t packet, + uint32_t count); + bool ExecutePacketType3_SET_SHADER_CONSTANTS(memory::RingBuffer* reader, uint32_t packet, + uint32_t count); + bool ExecutePacketType3_IM_LOAD(memory::RingBuffer* reader, uint32_t packet, uint32_t count); + bool ExecutePacketType3_IM_LOAD_IMMEDIATE(memory::RingBuffer* reader, + + uint32_t packet, uint32_t count); + bool ExecutePacketType3_INVALIDATE_STATE(memory::RingBuffer* reader, uint32_t packet, + uint32_t count); + bool ExecutePacketType3_VIZ_QUERY(memory::RingBuffer* reader, uint32_t packet, uint32_t count); + + virtual Shader* LoadShader(xenos::ShaderType shader_type, uint32_t guest_address, + const uint32_t* host_address, uint32_t dword_count) = 0; + + virtual bool IssueDraw(xenos::PrimitiveType prim_type, uint32_t index_count, + IndexBufferInfo* index_buffer_info, bool major_mode_explicit) = 0; + virtual bool IssueCopy() = 0; + + // "Actual" is for the command processor thread, to be read by the + // implementations. + SwapPostEffect GetActualSwapPostEffect() const { return swap_post_effect_actual_; } + + virtual void InitializeTrace(); + + // Shared readback resolve mode with backend legacy-flag alias support. + ReadbackResolveMode GetReadbackResolveMode(bool legacy_readback_resolve_enabled) const; + // Shared memexport readback enable state with backend legacy-flag override support. + bool IsReadbackMemexportEnabled(bool legacy_backend_flag) const; + + memory::Memory* memory_ = nullptr; + system::KernelState* kernel_state_ = nullptr; + GraphicsSystem* graphics_system_ = nullptr; + RegisterFile* register_file_ = nullptr; + + TraceWriter trace_writer_; + enum class TraceState { + kDisabled, + kStreaming, + kSingleFrame, + }; + TraceState trace_state_ = TraceState::kDisabled; + std::filesystem::path trace_stream_path_; + std::filesystem::path trace_frame_path_; + + std::atomic worker_running_; + system::object_ref worker_thread_; + + std::queue> pending_fns_; + + // MicroEngine binary from PM4_ME_INIT + std::vector me_bin_; + + uint32_t counter_ = 0; + + uint32_t primary_buffer_ptr_ = 0; + uint32_t primary_buffer_size_ = 0; + + uint32_t read_ptr_index_ = 0; + uint32_t read_ptr_update_freq_ = 0; + uint32_t read_ptr_writeback_ptr_ = 0; + + std::unique_ptr write_ptr_index_event_; + std::atomic write_ptr_index_; + + // Some titles submit writes beyond the emulated register file range in PM4 + // packets. Preserve these values so dependent packet logic can still observe + // them instead of dropping the write entirely. + std::unordered_map extended_register_values_; + + uint64_t bin_select_ = 0xFFFFFFFFull; + uint64_t bin_mask_ = 0xFFFFFFFFull; + + Shader* active_vertex_shader_ = nullptr; + Shader* active_pixel_shader_ = nullptr; + + bool paused_ = false; + + // By default (such as for tools), post-processing is disabled. + // "Desired" is for the external thread managing the post-processing effect. + SwapPostEffect swap_post_effect_desired_ = SwapPostEffect::kNone; + SwapPostEffect swap_post_effect_actual_ = SwapPostEffect::kNone; + + // Set by backend command processors to their legacy memexport readback cvar + // name (for explicit-override compatibility). + const char* legacy_readback_memexport_cvar_name_ = nullptr; + + private: + reg::DC_LUT_30_COLOR gamma_ramp_256_entry_table_[256] = {}; + reg::DC_LUT_PWL_DATA gamma_ramp_pwl_rgb_[128][3] = {}; + uint32_t gamma_ramp_rw_component_ = 0; +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/d3d12/command_processor.h b/include/rex/graphics/d3d12/command_processor.h new file mode 100644 index 0000000..d977ebe --- /dev/null +++ b/include/rex/graphics/d3d12/command_processor.h @@ -0,0 +1,776 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::graphics::d3d12 { + +class D3D12CommandProcessor : public CommandProcessor { + public: + explicit D3D12CommandProcessor(D3D12GraphicsSystem* graphics_system, + system::KernelState* kernel_state); + ~D3D12CommandProcessor(); + + void ClearCaches() override; + void InvalidateGpuMemory() override; + + void InitializeShaderStorage(const std::filesystem::path& cache_root, uint32_t title_id, + bool blocking) override; + + void RequestFrameTrace(const std::filesystem::path& root_path) override; + + void TracePlaybackWroteMemory(uint32_t base_ptr, uint32_t length) override; + + void RestoreEdramSnapshot(const void* snapshot) override; + + ui::d3d12::D3D12Provider& GetD3D12Provider() const { + return *static_cast(graphics_system_->provider()); + } + + // Returns the deferred drawing command list for the currently open + // submission. + DeferredCommandList& GetDeferredCommandList() { + assert_true(submission_open_); + return deferred_command_list_; + } + + uint64_t GetCurrentSubmission() const { return submission_current_; } + uint64_t GetCompletedSubmission() const { return submission_completed_; } + + // Must be called when a subsystem does something like UpdateTileMappings so + // it can be awaited in CheckSubmissionFence(submission_current_) if it was + // done after the latest ExecuteCommandLists + Signal. + void NotifyQueueOperationsDoneDirectly() { + queue_operations_done_since_submission_signal_ = true; + } + + uint64_t GetCurrentFrame() const { return frame_current_; } + uint64_t GetCompletedFrame() const { return frame_completed_; } + + // Returns true if the barrier has been inserted (the new state is different). + bool PushTransitionBarrier(ID3D12Resource* resource, D3D12_RESOURCE_STATES old_state, + D3D12_RESOURCE_STATES new_state, + UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES); + void PushAliasingBarrier(ID3D12Resource* old_resource, ID3D12Resource* new_resource); + void PushUAVBarrier(ID3D12Resource* resource); + void SubmitBarriers(); + + // Finds or creates root signature for a pipeline. + ID3D12RootSignature* GetRootSignature(const DxbcShader* vertex_shader, + const DxbcShader* pixel_shader, bool tessellated); + + ui::d3d12::D3D12UploadBufferPool& GetConstantBufferPool() const { return *constant_buffer_pool_; } + + D3D12_CPU_DESCRIPTOR_HANDLE GetViewBindlessHeapCPUStart() const { + assert_true(bindless_resources_used_); + return view_bindless_heap_cpu_start_; + } + D3D12_GPU_DESCRIPTOR_HANDLE GetViewBindlessHeapGPUStart() const { + assert_true(bindless_resources_used_); + return view_bindless_heap_gpu_start_; + } + // Returns UINT32_MAX if no free descriptors. If the unbounded SRV range for + // bindless resources is also used in the root signature of the draw / + // dispatch referencing this descriptor, this must only be used to allocate + // SRVs, otherwise it won't work on Nvidia Fermi (root signature creation will + // fail)! + uint32_t RequestPersistentViewBindlessDescriptor(); + void ReleaseViewBindlessDescriptorImmediately(uint32_t descriptor_index); + // Request non-contiguous CBV/SRV/UAV descriptors for use only within the next + // draw or dispatch command done for internal purposes. May change the current + // descriptor heap. If the unbounded SRV range for bindless resources is also + // used in the root signature of the draw / dispatch referencing these + // descriptors, this must only be used to allocate SRVs, otherwise it won't + // work on Nvidia Fermi (root signature creation will fail)! + bool RequestOneUseSingleViewDescriptors(uint32_t count, + ui::d3d12::util::DescriptorCpuGpuHandlePair* handles_out); + // These are needed often, so they are always allocated. + enum class SystemBindlessView : uint32_t { + // Both may be bound as one root parameter. + kSharedMemoryRawSRVAndNullRawUAVStart, + kSharedMemoryRawSRV = kSharedMemoryRawSRVAndNullRawUAVStart, + kNullRawUAV, + + // Both may be bound as one root parameter. + kNullRawSRVAndSharedMemoryRawUAVStart, + kNullRawSRV = kNullRawSRVAndSharedMemoryRawUAVStart, + kSharedMemoryRawUAV, + + kSharedMemoryR32UintSRV, + kSharedMemoryR32G32UintSRV, + kSharedMemoryR32G32B32A32UintSRV, + kSharedMemoryR32UintUAV, + kSharedMemoryR32G32UintUAV, + kSharedMemoryR32G32B32A32UintUAV, + + kEdramRawSRV, + kEdramR32UintSRV, + kEdramR32G32UintSRV, + kEdramR32G32B32A32UintSRV, + kEdramRawUAV, + kEdramR32UintUAV, + kEdramR32G32UintUAV, + kEdramR32G32B32A32UintUAV, + + kGammaRampTableSRV, + kGammaRampPWLSRV, + + // Beyond this point, SRVs are accessible to shaders through an unbounded + // range - no descriptors of other types bound to shaders alongside + // unbounded ranges - must be located beyond this point. + kUnboundedSRVsStart, + kNullTexture2DArray = kUnboundedSRVsStart, + kNullTexture3D, + kNullTextureCube, + + kCount, + }; + ui::d3d12::util::DescriptorCpuGpuHandlePair GetSystemBindlessViewHandlePair( + SystemBindlessView view) const; + ui::d3d12::util::DescriptorCpuGpuHandlePair GetSharedMemoryUintPow2BindlessSRVHandlePair( + uint32_t element_size_bytes_pow2) const; + ui::d3d12::util::DescriptorCpuGpuHandlePair GetSharedMemoryUintPow2BindlessUAVHandlePair( + uint32_t element_size_bytes_pow2) const; + ui::d3d12::util::DescriptorCpuGpuHandlePair GetEdramUintPow2BindlessSRVHandlePair( + uint32_t element_size_bytes_pow2) const; + ui::d3d12::util::DescriptorCpuGpuHandlePair GetEdramUintPow2BindlessUAVHandlePair( + uint32_t element_size_bytes_pow2) const; + + // Returns a single temporary GPU-side buffer within a submission for tasks + // like texture untiling and resolving. + ID3D12Resource* RequestScratchGPUBuffer(uint32_t size, D3D12_RESOURCE_STATES state); + // This must be called when done with the scratch buffer, to notify the + // command processor about the new state in case the buffer was transitioned + // by its user. + void ReleaseScratchGPUBuffer(ID3D12Resource* buffer, D3D12_RESOURCE_STATES new_state); + + // Returns a pipeline with deferred creation by its handle. May return nullptr + // if failed to create the pipeline. + ID3D12PipelineState* GetD3D12PipelineByHandle(void* handle) const { + return pipeline_cache_->GetD3D12PipelineByHandle(handle); + } + + // Sets the current cached values to external ones. This is for cache + // invalidation primarily. A submission must be open. + void SetExternalPipeline(ID3D12PipelineState* pipeline); + void SetExternalGraphicsRootSignature(ID3D12RootSignature* root_signature); + void SetViewport(const D3D12_VIEWPORT& viewport); + void SetScissorRect(const D3D12_RECT& scissor_rect); + void SetStencilReference(uint32_t stencil_ref); + void SetPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY primitive_topology); + + // Returns the text to display in the GPU backend name in the window title. + std::string GetWindowTitleText() const; + + protected: + bool SetupContext() override; + void ShutdownContext() override; + + void WriteRegister(uint32_t index, uint32_t value) override; + void WriteRegistersFromMem(uint32_t start_index, uint32_t* base, uint32_t num_registers) override; + bool ExecutePacketType3_EVENT_WRITE_ZPD(memory::RingBuffer* reader, uint32_t packet, + uint32_t count) override; + + void OnGammaRamp256EntryTableValueWritten() override; + void OnGammaRampPWLValueWritten() override; + + void IssueSwap(uint32_t frontbuffer_ptr, uint32_t frontbuffer_width, + uint32_t frontbuffer_height) override; + + void OnPrimaryBufferEnd() override; + + Shader* LoadShader(xenos::ShaderType shader_type, uint32_t guest_address, + const uint32_t* host_address, uint32_t dword_count) override; + + bool IssueDraw(xenos::PrimitiveType primitive_type, uint32_t index_count, + IndexBufferInfo* index_buffer_info, bool major_mode_explicit) override; + bool IssueCopy() override; + + void InitializeTrace() override; + + private: + static constexpr uint32_t kQueueFrames = 3; + + enum RootParameter : UINT { + // Keep the size of the root signature at each stage 13 dwords or less + // (better 12 or less) so it fits in user data on AMD. Descriptor tables are + // 1 dword, root descriptors are 2 dwords (however, root descriptors require + // less setup on the CPU - balance needs to be maintained). + + // CBVs are set in both bindful and bindless cases via root descriptors. + + // - Bindful resources - multiple root signatures depending on extra + // parameters. + + // These are always present. + + // Very frequently changed, especially for UI draws, and for models drawn in + // multiple parts - contains vertex and texture fetch constants. + kRootParameter_Bindful_FetchConstants = 0, // +2 dwords = 2 in all. + // Quite frequently changed (for one object drawn multiple times, for + // instance - may contain projection matrices). + kRootParameter_Bindful_FloatConstantsVertex, // +2 = 4 in VS. + // Less frequently changed (per-material). + kRootParameter_Bindful_FloatConstantsPixel, // +2 = 4 in PS. + // May stay the same across many draws. + kRootParameter_Bindful_SystemConstants, // +2 = 6 in all. + // Pretty rarely used and rarely changed - flow control constants. + kRootParameter_Bindful_BoolLoopConstants, // +2 = 8 in all. + // Changed only when starting a new descriptor heap or when switching + // between shared memory as SRV and UAV - shared memory byte address buffer + // (as SRV and as UAV, either may be null if not used), and, if ROV is used + // for EDRAM, EDRAM R32_UINT UAV. + kRootParameter_Bindful_SharedMemoryAndEdram, // +1 = 9 in all. + + kRootParameter_Bindful_Count_Base, + + // Extra parameter that may or may not exist: + // - Pixel textures (+1 = 10 in PS). + // - Pixel samplers (+1 = 11 in PS). + // - Vertex textures (+1 = 10 in VS). + // - Vertex samplers (+1 = 11 in VS). + + kRootParameter_Bindful_Count_Max = kRootParameter_Bindful_Count_Base + 4, + + // - Bindless resources - two global root signatures (for non-tessellated + // and tessellated drawing), so these are always present. + + kRootParameter_Bindless_FetchConstants = 0, // +2 = 2 in all. + kRootParameter_Bindless_FloatConstantsVertex, // +2 = 4 in VS. + kRootParameter_Bindless_FloatConstantsPixel, // +2 = 4 in PS. + // Changed per-material, texture and sampler descriptor indices. + kRootParameter_Bindless_DescriptorIndicesPixel, // +2 = 6 in PS. + kRootParameter_Bindless_DescriptorIndicesVertex, // +2 = 6 in VS. + kRootParameter_Bindless_SystemConstants, // +2 = 8 in all. + kRootParameter_Bindless_BoolLoopConstants, // +2 = 10 in all. + // Changed only when switching between shared memory as SRV and UAV - shared + // memory byte address buffer (as SRV and as UAV, either may be null if not + // used). + kRootParameter_Bindless_SharedMemory, // +1 = 11 in all. + // Unbounded sampler descriptor table - changed in case of overflow. + kRootParameter_Bindless_SamplerHeap, // +1 = 12 in all. + // Unbounded SRV/UAV descriptor table - never changed. + kRootParameter_Bindless_ViewHeap, // +1 = 13 in all. + + kRootParameter_Bindless_Count, + }; + + struct RootBindfulExtraParameterIndices { + uint32_t textures_pixel; + uint32_t samplers_pixel; + uint32_t textures_vertex; + uint32_t samplers_vertex; + static constexpr uint32_t kUnavailable = UINT32_MAX; + }; + // Gets the indices of optional root parameters. Returns the total parameter + // count. + static uint32_t GetRootBindfulExtraParameterIndices( + const DxbcShader* vertex_shader, const DxbcShader* pixel_shader, + RootBindfulExtraParameterIndices& indices_out); + + // BeginSubmission and EndSubmission may be called at any time. If there's an + // open non-frame submission, BeginSubmission(true) will promote it to a + // frame. EndSubmission(true) will close the frame no matter whether the + // submission has already been closed. + // Submission (ExecuteCommandLists) boundaries are implicit full UAV and + // aliasing barriers, and also result in common resource state promotion and + // decay. + + // Rechecks submission number and reclaims per-submission resources. Pass 0 as + // the submission to await to simply check status, or pass submission_current_ + // to wait for all queue operations to be completed. + void CheckSubmissionFence(uint64_t await_submission); + // If is_guest_command is true, a new full frame - with full cleanup of + // resources and, if needed, starting capturing - is opened if pending (as + // opposed to simply resuming after mid-frame synchronization). Returns + // whether a submission is open currently and the device is not removed. + bool BeginSubmission(bool is_guest_command); + // If is_swap is true, a full frame is closed - with, if needed, cache + // clearing and stopping capturing. Returns whether the submission was done + // successfully, if it has failed, leaves it open. + bool EndSubmission(bool is_swap); + // Checks if ending a submission right now would not cause potentially more + // delay than it would reduce by making the GPU start working earlier - such + // as when there are unfinished graphics pipeline creation requests that would + // need to be fulfilled before actually submitting the command list. + bool CanEndSubmissionImmediately() const; + bool AwaitAllQueueOperationsCompletion() { + CheckSubmissionFence(submission_current_); + return submission_completed_ + 1 >= submission_current_; + } + void LogDeviceRemovalDiagnostics(ID3D12Device* device, HRESULT reason); + + void UpdateDebugMarkersEnabled(); + void PushDebugMarker(const char* format, ...); + void PopDebugMarker(); + void InsertDebugMarker(const char* format, ...); + bool debug_markers_enabled() const { return debug_markers_enabled_; } + + // Need to await submission completion before calling. + void ClearCommandAllocatorCache(); + + // Request descriptors and automatically rebind the descriptor heap on the + // draw command list. Refer to D3D12DescriptorHeapPool::Request for partial / + // full update explanation. Doesn't work when bindless descriptors are used. + uint64_t RequestViewBindfulDescriptors(uint64_t previous_heap_index, + uint32_t count_for_partial_update, + uint32_t count_for_full_update, + D3D12_CPU_DESCRIPTOR_HANDLE& cpu_handle_out, + D3D12_GPU_DESCRIPTOR_HANDLE& gpu_handle_out); + uint64_t RequestSamplerBindfulDescriptors(uint64_t previous_heap_index, + uint32_t count_for_partial_update, + uint32_t count_for_full_update, + D3D12_CPU_DESCRIPTOR_HANDLE& cpu_handle_out, + D3D12_GPU_DESCRIPTOR_HANDLE& gpu_handle_out); + + void UpdateFixedFunctionState(const draw_util::ViewportInfo& viewport_info, + const draw_util::Scissor& scissor, bool primitive_polygonal, + reg::RB_DEPTHCONTROL normalized_depth_control); + void UpdateSystemConstantValues(bool shared_memory_is_uav, bool primitive_polygonal, + uint32_t line_loop_closing_index, xenos::Endian index_endian, + const draw_util::ViewportInfo& viewport_info, + uint32_t used_texture_mask, + reg::RB_DEPTHCONTROL normalized_depth_control, + uint32_t normalized_color_mask); + bool UpdateBindings(const D3D12Shader* vertex_shader, const D3D12Shader* pixel_shader, + ID3D12RootSignature* root_signature, bool shared_memory_is_uav); + bool IssueCopy_ReadbackResolvePath(); + bool IssueDraw_MemexportReadbackFullPath(uint32_t total_size); + bool IssueDraw_MemexportReadbackFastPath(uint32_t total_size); + + // Returns a buffer for reading GPU data back to the CPU. Assuming + // synchronizing immediately after use. Always in COPY_DEST state. + ID3D12Resource* RequestReadbackBuffer(uint32_t size); + struct ReadbackBuffer { + ID3D12Resource* buffers[2] = {nullptr, nullptr}; + uint32_t sizes[2] = {0, 0}; + void* mapped_data[2] = {nullptr, nullptr}; + uint64_t submission_written[2] = {0, 0}; + uint32_t written_size[2] = {0, 0}; + uint32_t current_index = 0; + uint64_t last_used_frame = 0; + }; + void EvictOldReadbackBuffers(std::unordered_map& buffer_map); + static constexpr uint32_t kReadbackBufferSizeIncrement = 16 * 1024 * 1024; + static constexpr size_t kMaxReadbackBuffers = 256; + static constexpr uint64_t kReadbackBufferEvictionAgeFrames = 60; + static inline uint32_t AlignReadbackBufferSize(uint32_t size) { + if (size < 1 * 1024 * 1024) { + return rex::align(size, 256u * 1024u); + } + if (size < 4 * 1024 * 1024) { + return rex::align(size, 1u * 1024u * 1024u); + } + return rex::align(size, kReadbackBufferSizeIncrement); + } + static inline uint64_t MakeReadbackResolveKey(uint32_t address, uint32_t length) { + return (uint64_t(address) << 32) | uint64_t(length); + } + static inline uint64_t MakeMemexportReadbackKey(uint32_t first_base_address_dwords, + uint32_t total_size) { + return (uint64_t(first_base_address_dwords) << 32) | uint64_t(total_size); + } + + bool InitializeOcclusionQueryResources(); + void ShutdownOcclusionQueryResources(); + bool BeginGuestOcclusionQuery(uint32_t sample_count_address); + bool EndGuestOcclusionQuery(uint32_t sample_count_address, + xenos::xe_gpu_depth_sample_counts* sample_counts); + bool AcquireOcclusionQueryIndex(uint32_t& host_index_out); + void DisableHostOcclusionQueries(); + uint64_t NormalizeOcclusionSamples(uint64_t samples) const; + void WriteGuestOcclusionResult(xenos::xe_gpu_depth_sample_counts* sample_counts, + uint64_t samples); + void InvalidateAllVertexBufferResidency(); + void InvalidateVertexBufferResidency(uint32_t vfetch_index); + void InvalidateVertexBufferResidencyRange(uint32_t first_vfetch, uint32_t last_vfetch); + + void WriteGammaRampSRV(bool is_pwl, D3D12_CPU_DESCRIPTOR_HANDLE handle) const; + + bool device_removed_ = false; + + bool cache_clear_requested_ = false; + + HANDLE fence_completion_event_ = nullptr; + + bool submission_open_ = false; + // Values of submission_fence_. + uint64_t submission_current_ = 1; + uint64_t submission_completed_ = 0; + ID3D12Fence* submission_fence_ = nullptr; + + // For awaiting non-submission queue operations such as UpdateTileMappings in + // AwaitAllQueueOperationsCompletion when they're queued after the latest + // ExecuteCommandLists + Signal, thus won't be awaited by just awaiting the + // submission. + ID3D12Fence* queue_operations_since_submission_fence_ = nullptr; + uint64_t queue_operations_since_submission_fence_last_ = 0; + bool queue_operations_done_since_submission_signal_ = false; + + bool frame_open_ = false; + // Guest frame index, since some transient resources can be reused across + // submissions. Values updated in the beginning of a frame. + uint64_t frame_current_ = 1; + uint64_t frame_completed_ = 0; + // Submission indices of frames that have already been submitted. + uint64_t closed_frame_submissions_[kQueueFrames] = {}; + + struct CommandAllocator { + ID3D12CommandAllocator* command_allocator; + uint64_t last_usage_submission; + CommandAllocator* next; + }; + CommandAllocator* command_allocator_writable_first_ = nullptr; + CommandAllocator* command_allocator_writable_last_ = nullptr; + CommandAllocator* command_allocator_submitted_first_ = nullptr; + CommandAllocator* command_allocator_submitted_last_ = nullptr; + ID3D12GraphicsCommandList* command_list_ = nullptr; + ID3D12GraphicsCommandList1* command_list_1_ = nullptr; + DeferredCommandList deferred_command_list_; + + bool debug_markers_enabled_ = false; + + // Viewport info caching - avoids redundant GetHostViewportInfo recalculation + // when viewport-affecting register state hasn't changed between draws. + struct ViewportCacheKey { + uint32_t pa_cl_clip_cntl; + uint32_t pa_cl_vte_cntl; + uint32_t pa_su_sc_mode_cntl; + uint32_t pa_su_vtx_cntl; + uint32_t pa_sc_window_offset; + uint32_t normalized_depth_control; + uint32_t vport_regs[6]; // XSCALE, XOFFSET, YSCALE, YOFFSET, ZSCALE, ZOFFSET + uint32_t flags; // packed: convert_z_to_float24, full_float24, ps_writes_depth + bool operator==(const ViewportCacheKey&) const = default; + }; + ViewportCacheKey previous_viewport_key_{}; + draw_util::ViewportInfo previous_viewport_info_{}; + bool viewport_cache_valid_ = false; + + // Should bindless textures and samplers be used - many times faster + // UpdateBindings than bindful (that becomes a significant bottleneck with + // bindful - mainly because of CopyDescriptorsSimple, which takes the majority + // of UpdateBindings time, and that's outside the emulator's control even). + bool bindless_resources_used_ = false; + + std::unique_ptr shared_memory_; + + std::unique_ptr render_target_cache_; + + std::unique_ptr constant_buffer_pool_; + + static constexpr uint32_t kViewBindfulHeapSize = 32768; + static_assert(kViewBindfulHeapSize <= D3D12_MAX_SHADER_VISIBLE_DESCRIPTOR_HEAP_SIZE_TIER_1); + std::unique_ptr view_bindful_heap_pool_; + // Currently bound descriptor heap - updated by RequestViewBindfulDescriptors. + ID3D12DescriptorHeap* view_bindful_heap_current_; + // Rationale: textures have 4 KB alignment in guest memory, and there can be + // 512 MB / 4 KB in total of them at most, and multiply by 3 for different + // swizzles, signedness, and multiple host textures for one guest texture, and + // transient descriptors. Though in reality there will be a lot fewer of + // course, this is just a "safe" value. The limit is 1000000 for resource + // binding tier 2. + static constexpr uint32_t kViewBindlessHeapSize = 262144; + static_assert(kViewBindlessHeapSize <= D3D12_MAX_SHADER_VISIBLE_DESCRIPTOR_HEAP_SIZE_TIER_2); + ID3D12DescriptorHeap* view_bindless_heap_ = nullptr; + D3D12_CPU_DESCRIPTOR_HANDLE view_bindless_heap_cpu_start_; + D3D12_GPU_DESCRIPTOR_HANDLE view_bindless_heap_gpu_start_; + uint32_t view_bindless_heap_allocated_ = 0; + std::vector view_bindless_heap_free_; + // , sorted by the submission + // number. + std::deque> view_bindless_one_use_descriptors_; + + // Direct3D 12 only allows shader-visible heaps with no more than 2048 + // samplers (due to Nvidia addressing). However, there's also possibly a weird + // bug in the Nvidia driver (tested on 440.97 and earlier on Windows 10 1803) + // that caused the sampler with index 2047 not to work if a heap with 8 or + // less samplers also exists - in case of Xenia, it's the immediate drawer's + // sampler heap. + // FIXME(Triang3l): Investigate the issue with the sampler 2047 on Nvidia. + static constexpr uint32_t kSamplerHeapSize = 2000; + static_assert(kSamplerHeapSize <= D3D12_MAX_SHADER_VISIBLE_SAMPLER_HEAP_SIZE); + std::unique_ptr sampler_bindful_heap_pool_; + ID3D12DescriptorHeap* sampler_bindful_heap_current_; + ID3D12DescriptorHeap* sampler_bindless_heap_current_ = nullptr; + D3D12_CPU_DESCRIPTOR_HANDLE sampler_bindless_heap_cpu_start_; + D3D12_GPU_DESCRIPTOR_HANDLE sampler_bindless_heap_gpu_start_; + // Currently the sampler heap is used only for texture cache samplers, so + // individual samplers are never freed, and using a simple linear allocator + // inside the current heap without a free list. + uint32_t sampler_bindless_heap_allocated_ = 0; + // , if total sampler count used so far + // exceeds kSamplerHeapSize, and the heap has been switched (this is not a + // totally impossible situation considering Direct3D 9 has sampler parameter + // state instead of sampler objects, and having one "unimportant" parameter + // changed may result in doubling of sampler count). Sorted by the submission + // number (so checking if the first can be reused is enough). + std::deque> sampler_bindless_heaps_overflowed_; + // D3D12TextureCache::SamplerParameters::value -> indices within the current + // bindless sampler heap. + std::unordered_map texture_cache_bindless_sampler_map_; + + // Root signatures for different descriptor counts. + std::unordered_map root_signatures_bindful_; + ID3D12RootSignature* root_signature_bindless_vs_ = nullptr; + ID3D12RootSignature* root_signature_bindless_ds_ = nullptr; + + std::unique_ptr primitive_processor_; + + std::unique_ptr pipeline_cache_; + + std::unique_ptr texture_cache_; + + // Bytes 0x0...0x3FF - 256-entry gamma ramp table with B10G10R10X2 data (read + // as R10G10B10X2 with swizzle). + // Bytes 0x400...0x9FF - 128-entry PWL R16G16 gamma ramp (R - base, G - delta, + // low 6 bits of each are zero, 3 elements per entry). + Microsoft::WRL::ComPtr gamma_ramp_buffer_; + D3D12_RESOURCE_STATES gamma_ramp_buffer_state_; + // Upload buffer for an image that is the same as gamma_ramp_, but with + // kQueueFrames array layers. + Microsoft::WRL::ComPtr gamma_ramp_upload_buffer_; + uint8_t* gamma_ramp_upload_buffer_mapping_ = nullptr; + bool gamma_ramp_256_entry_table_up_to_date_ = false; + bool gamma_ramp_pwl_up_to_date_ = false; + + struct ApplyGammaConstants { + uint32_t size[2]; + }; + enum class ApplyGammaRootParameter : UINT { + kConstants, + kDestination, + kSource, + kRamp, + + kCount, + }; + Microsoft::WRL::ComPtr apply_gamma_root_signature_; + Microsoft::WRL::ComPtr apply_gamma_table_pipeline_; + Microsoft::WRL::ComPtr apply_gamma_table_fxaa_luma_pipeline_; + Microsoft::WRL::ComPtr apply_gamma_pwl_pipeline_; + Microsoft::WRL::ComPtr apply_gamma_pwl_fxaa_luma_pipeline_; + + struct FxaaConstants { + uint32_t size[2]; + float size_inv[2]; + }; + enum class FxaaRootParameter : UINT { + kConstants, + kDestination, + kSource, + + kCount, + }; + Microsoft::WRL::ComPtr fxaa_root_signature_; + Microsoft::WRL::ComPtr fxaa_pipeline_; + Microsoft::WRL::ComPtr fxaa_extreme_pipeline_; + + struct ResolveDownscaleConstants { + uint32_t scale_x; + uint32_t scale_y; + uint32_t pixel_size_log2; + uint32_t tile_count; + uint32_t half_pixel_offset; + }; + enum class ResolveDownscaleRootParameter : UINT { + kConstants, + kSource, + kDestination, + + kCount, + }; + Microsoft::WRL::ComPtr resolve_downscale_root_signature_; + Microsoft::WRL::ComPtr resolve_downscale_pipeline_; + Microsoft::WRL::ComPtr resolve_downscale_buffer_; + uint32_t resolve_downscale_buffer_size_ = 0; + + // PWL gamma ramp can result in values with more precision than 10bpc. Though + // those sub-10bpc bits don't have any noticeable visual effect, so normally + // R10G10B10A2_UNORM is enough. But what's the most important is that for the + // original FXAA shader, the luma needs to be written to the alpha channel. + // For simplicity (to avoid modifying the FXAA shader and adding more texture + // fetches into it), and for the highest quality (preserving all 13 bits that + // may be generated by applying the PWL gamma ramp with an increment of 2^3, + // and also leaving some space for the result of applying fractional weights + // to calculate the luma), using R16G16B16A16_UNORM instead of + // R10G10B10X2_UNORM with a separate alpha texture. + static constexpr DXGI_FORMAT kFxaaSourceTextureFormat = DXGI_FORMAT_R16G16B16A16_UNORM; + // Kept in NON_PIXEL_SHADER_RESOURCE state. + Microsoft::WRL::ComPtr fxaa_source_texture_; + uint64_t fxaa_source_texture_submission_ = 0; + + // Unsubmitted barrier batch. + std::vector barriers_; + + // , sorted by the submission number. + std::deque> resources_for_deletion_; + + static constexpr uint32_t kScratchBufferSizeIncrement = 16 * 1024 * 1024; + ID3D12Resource* scratch_buffer_ = nullptr; + uint32_t scratch_buffer_size_ = 0; + D3D12_RESOURCE_STATES scratch_buffer_state_; + bool scratch_buffer_used_ = false; + + ID3D12Resource* readback_buffer_ = nullptr; + uint32_t readback_buffer_size_ = 0; + std::unordered_map readback_buffers_; + std::unordered_map memexport_readback_buffers_; + + static constexpr uint32_t kMaxOcclusionQueries = 8192; + Microsoft::WRL::ComPtr occlusion_query_heap_; + Microsoft::WRL::ComPtr occlusion_query_readback_; + uint64_t* occlusion_query_readback_mapping_ = nullptr; + uint32_t occlusion_query_cursor_ = 0; + bool occlusion_query_resources_available_ = false; + struct ActiveOcclusionQuery { + uint32_t sample_count_address = 0; + uint32_t host_index = UINT32_MAX; + bool valid = false; + } active_occlusion_query_; + struct VertexBufferState { + uint32_t address = UINT32_MAX; + uint32_t size = UINT32_MAX; + }; + std::array vertex_buffer_states_{}; + uint64_t vertex_buffers_in_sync_[2] = {}; + + std::atomic pix_capture_requested_ = false; + bool pix_capturing_; + + // The current fixed-function drawing state. + D3D12_VIEWPORT ff_viewport_; + D3D12_RECT ff_scissor_; + float ff_blend_factor_[4]; + uint32_t ff_stencil_ref_; + bool ff_viewport_update_needed_; + bool ff_scissor_update_needed_; + bool ff_blend_factor_update_needed_; + bool ff_stencil_ref_update_needed_; + + // Currently bound pipeline, either a graphics pipeline from the pipeline + // cache (with potentially deferred creation - current_external_pipeline_ is + // nullptr in this case) or a non-Xenos graphics or compute pipeline + // (current_guest_pipeline_ is nullptr in this case). + void* current_guest_pipeline_; + ID3D12PipelineState* current_external_pipeline_; + + // Currently bound graphics root signature. + ID3D12RootSignature* current_graphics_root_signature_; + // Extra parameters which may or may not be present. + RootBindfulExtraParameterIndices current_graphics_root_bindful_extras_; + // Whether root parameters are up to date - reset if a new signature is bound. + uint32_t current_graphics_root_up_to_date_; + + // System shader constants. + DxbcShaderTranslator::SystemConstants system_constants_; + + // Float constant usage masks of the last draw call. + uint64_t current_float_constant_map_vertex_[4]; + uint64_t current_float_constant_map_pixel_[4]; + + // Constant buffer bindings. + struct ConstantBufferBinding { + D3D12_GPU_VIRTUAL_ADDRESS address; + bool up_to_date; + }; + ConstantBufferBinding cbuffer_binding_system_; + ConstantBufferBinding cbuffer_binding_float_vertex_; + ConstantBufferBinding cbuffer_binding_float_pixel_; + ConstantBufferBinding cbuffer_binding_bool_loop_; + ConstantBufferBinding cbuffer_binding_fetch_; + ConstantBufferBinding cbuffer_binding_descriptor_indices_vertex_; + ConstantBufferBinding cbuffer_binding_descriptor_indices_pixel_; + + // Whether the latest shared memory and EDRAM buffer binding contains the + // shared memory UAV rather than the SRV. + // Separate descriptor tables for the SRV and the UAV, even though only one is + // accessed dynamically in the shaders, are used to prevent a validation + // message about missing resource states in PIX. + std::optional current_shared_memory_binding_is_uav_; + + // Pages with the descriptors currently used for handling Xenos draw calls. + uint64_t draw_view_bindful_heap_index_; + uint64_t draw_sampler_bindful_heap_index_; + + // Whether the last used texture sampler bindings have been written to the + // current view descriptor heap. + bool bindful_textures_written_vertex_; + bool bindful_textures_written_pixel_; + bool bindful_samplers_written_vertex_; + bool bindful_samplers_written_pixel_; + // Layout UIDs and last texture and sampler bindings written to the current + // descriptor heaps (for bindful) or descriptor index constant buffer (for + // bindless) with the last used descriptor layout. Valid only when: + // - For bindful, when bindful_#_written_#_ is true. + // - For bindless, when cbuffer_binding_descriptor_indices_#_.up_to_date is + // true. + size_t current_texture_layout_uid_vertex_; + size_t current_texture_layout_uid_pixel_; + size_t current_sampler_layout_uid_vertex_; + size_t current_sampler_layout_uid_pixel_; + // Size of these should be ignored when checking whether these are up to date, + // layout UID should be checked first (they will be different for different + // binding counts). + std::vector current_texture_srv_keys_vertex_; + std::vector current_texture_srv_keys_pixel_; + std::vector current_samplers_vertex_; + std::vector current_samplers_pixel_; + std::vector current_sampler_bindless_indices_vertex_; + std::vector current_sampler_bindless_indices_pixel_; + + // Latest bindful descriptor handles used for handling Xenos draw calls. + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle_shared_memory_srv_and_edram_; + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle_shared_memory_uav_and_edram_; + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle_textures_vertex_; + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle_textures_pixel_; + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle_samplers_vertex_; + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle_samplers_pixel_; + + // Current primitive topology. + D3D_PRIMITIVE_TOPOLOGY primitive_topology_; + + // Temporary storage for memexport stream constants used in the draw. + std::vector memexport_ranges_; +}; + +} // namespace rex::graphics::d3d12 diff --git a/include/rex/graphics/d3d12/deferred_command_list.h b/include/rex/graphics/d3d12/deferred_command_list.h new file mode 100644 index 0000000..7f1eb7f --- /dev/null +++ b/include/rex/graphics/d3d12/deferred_command_list.h @@ -0,0 +1,649 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2019 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace rex::graphics::d3d12 { + +using namespace ::rex::literals; + +class D3D12CommandProcessor; + +class DeferredCommandList { + public: + DeferredCommandList(const D3D12CommandProcessor& command_processor, + size_t initial_size_bytes = 1_MiB); + + void Reset(); + void Execute(ID3D12GraphicsCommandList* command_list, ID3D12GraphicsCommandList1* command_list_1); + + D3D12_RECT* ClearDepthStencilViewAllocatedRects(D3D12_CPU_DESCRIPTOR_HANDLE depth_stencil_view, + D3D12_CLEAR_FLAGS clear_flags, FLOAT depth, + UINT8 stencil, UINT num_rects) { + auto args = reinterpret_cast( + WriteCommand(Command::kD3DClearDepthStencilView, + sizeof(ClearDepthStencilViewHeader) + num_rects * sizeof(D3D12_RECT))); + args->depth_stencil_view = depth_stencil_view; + args->clear_flags = clear_flags; + args->depth = depth; + args->stencil = stencil; + args->num_rects = num_rects; + return num_rects ? reinterpret_cast(args + 1) : nullptr; + } + + void D3DClearDepthStencilView(D3D12_CPU_DESCRIPTOR_HANDLE depth_stencil_view, + D3D12_CLEAR_FLAGS clear_flags, FLOAT depth, UINT8 stencil, + UINT num_rects, const D3D12_RECT* rects) { + D3D12_RECT* allocated_rects = ClearDepthStencilViewAllocatedRects( + depth_stencil_view, clear_flags, depth, stencil, num_rects); + if (num_rects) { + assert_not_null(allocated_rects); + std::memcpy(allocated_rects, rects, num_rects * sizeof(D3D12_RECT)); + } + } + + void D3DClearRenderTargetView(D3D12_CPU_DESCRIPTOR_HANDLE render_target_view, + const FLOAT color_rgba[4], UINT num_rects, + const D3D12_RECT* rects) { + auto args = reinterpret_cast( + WriteCommand(Command::kD3DClearRenderTargetView, + sizeof(ClearRenderTargetViewHeader) + num_rects * sizeof(D3D12_RECT))); + args->render_target_view = render_target_view; + std::memcpy(args->color_rgba, color_rgba, 4 * sizeof(FLOAT)); + args->num_rects = num_rects; + if (num_rects != 0) { + std::memcpy(args + 1, rects, num_rects * sizeof(D3D12_RECT)); + } + } + + void D3DClearUnorderedAccessViewUint(D3D12_GPU_DESCRIPTOR_HANDLE view_gpu_handle_in_current_heap, + D3D12_CPU_DESCRIPTOR_HANDLE view_cpu_handle, + ID3D12Resource* resource, const UINT values[4], + UINT num_rects, const D3D12_RECT* rects) { + auto args = reinterpret_cast( + WriteCommand(Command::kD3DClearUnorderedAccessViewUint, + sizeof(ClearUnorderedAccessViewHeader) + num_rects * sizeof(D3D12_RECT))); + args->view_gpu_handle_in_current_heap = view_gpu_handle_in_current_heap; + args->view_cpu_handle = view_cpu_handle; + args->resource = resource; + std::memcpy(args->values_uint, values, 4 * sizeof(UINT)); + args->num_rects = num_rects; + if (num_rects != 0) { + std::memcpy(args + 1, rects, num_rects * sizeof(D3D12_RECT)); + } + } + + void D3DCopyBufferRegion(ID3D12Resource* dst_buffer, UINT64 dst_offset, + ID3D12Resource* src_buffer, UINT64 src_offset, UINT64 num_bytes) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kD3DCopyBufferRegion, sizeof(D3DCopyBufferRegionArguments))); + args.dst_buffer = dst_buffer; + args.dst_offset = dst_offset; + args.src_buffer = src_buffer; + args.src_offset = src_offset; + args.num_bytes = num_bytes; + } + + void D3DCopyResource(ID3D12Resource* dst_resource, ID3D12Resource* src_resource) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kD3DCopyResource, sizeof(D3DCopyResourceArguments))); + args.dst_resource = dst_resource; + args.src_resource = src_resource; + } + + void CopyTexture(const D3D12_TEXTURE_COPY_LOCATION& dst, const D3D12_TEXTURE_COPY_LOCATION& src) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kCopyTexture, sizeof(CopyTextureArguments))); + std::memcpy(&args.dst, &dst, sizeof(D3D12_TEXTURE_COPY_LOCATION)); + std::memcpy(&args.src, &src, sizeof(D3D12_TEXTURE_COPY_LOCATION)); + } + + void D3DCopyTextureRegion(const D3D12_TEXTURE_COPY_LOCATION* dst, UINT dst_x, UINT dst_y, + UINT dst_z, const D3D12_TEXTURE_COPY_LOCATION* src, + const D3D12_BOX* src_box) { + assert_not_null(dst); + assert_not_null(src); + auto& args = *reinterpret_cast( + WriteCommand(Command::kD3DCopyTextureRegion, sizeof(D3DCopyTextureRegionArguments))); + std::memcpy(&args.dst, dst, sizeof(D3D12_TEXTURE_COPY_LOCATION)); + args.dst_x = dst_x; + args.dst_y = dst_y; + args.dst_z = dst_z; + std::memcpy(&args.src, src, sizeof(D3D12_TEXTURE_COPY_LOCATION)); + if (src_box) { + args.has_src_box = true; + args.src_box = *src_box; + } else { + args.has_src_box = false; + } + } + + void D3DDispatch(UINT thread_group_count_x, UINT thread_group_count_y, + UINT thread_group_count_z) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kD3DDispatch, sizeof(D3DDispatchArguments))); + args.thread_group_count_x = thread_group_count_x; + args.thread_group_count_y = thread_group_count_y; + args.thread_group_count_z = thread_group_count_z; + } + + void D3DDrawIndexedInstanced(UINT index_count_per_instance, UINT instance_count, + UINT start_index_location, INT base_vertex_location, + UINT start_instance_location) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kD3DDrawIndexedInstanced, sizeof(D3DDrawIndexedInstancedArguments))); + args.index_count_per_instance = index_count_per_instance; + args.instance_count = instance_count; + args.start_index_location = start_index_location; + args.base_vertex_location = base_vertex_location; + args.start_instance_location = start_instance_location; + } + + void D3DDrawInstanced(UINT vertex_count_per_instance, UINT instance_count, + UINT start_vertex_location, UINT start_instance_location) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kD3DDrawInstanced, sizeof(D3DDrawInstancedArguments))); + args.vertex_count_per_instance = vertex_count_per_instance; + args.instance_count = instance_count; + args.start_vertex_location = start_vertex_location; + args.start_instance_location = start_instance_location; + } + + void D3DBeginQuery(ID3D12QueryHeap* query_heap, D3D12_QUERY_TYPE type, UINT index) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kD3DBeginQuery, sizeof(D3DQueryArguments))); + args.query_heap = query_heap; + args.type = type; + args.index = index; + } + + void D3DEndQuery(ID3D12QueryHeap* query_heap, D3D12_QUERY_TYPE type, UINT index) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kD3DEndQuery, sizeof(D3DQueryArguments))); + args.query_heap = query_heap; + args.type = type; + args.index = index; + } + + void D3DResolveQueryData(ID3D12QueryHeap* query_heap, D3D12_QUERY_TYPE type, UINT start_index, + UINT num_queries, ID3D12Resource* destination_buffer, + UINT64 aligned_destination_buffer_offset) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kD3DResolveQueryData, sizeof(D3DResolveQueryDataArguments))); + args.query_heap = query_heap; + args.type = type; + args.start_index = start_index; + args.num_queries = num_queries; + args.destination_buffer = destination_buffer; + args.aligned_destination_buffer_offset = aligned_destination_buffer_offset; + } + + void D3DIASetIndexBuffer(const D3D12_INDEX_BUFFER_VIEW* view) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kD3DIASetIndexBuffer, sizeof(D3D12_INDEX_BUFFER_VIEW))); + if (view != nullptr) { + args.BufferLocation = view->BufferLocation; + args.SizeInBytes = view->SizeInBytes; + args.Format = view->Format; + } else { + args.BufferLocation = D3D12_GPU_VIRTUAL_ADDRESS(0); + args.SizeInBytes = 0; + args.Format = DXGI_FORMAT_UNKNOWN; + } + } + + void D3DIASetPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY primitive_topology) { + auto& arg = *reinterpret_cast( + WriteCommand(Command::kD3DIASetPrimitiveTopology, sizeof(D3D12_PRIMITIVE_TOPOLOGY))); + arg = primitive_topology; + } + + void D3DIASetVertexBuffers(UINT start_slot, UINT num_views, + const D3D12_VERTEX_BUFFER_VIEW* views) { + if (num_views == 0) { + return; + } + static_assert(alignof(D3D12_VERTEX_BUFFER_VIEW) <= alignof(uintmax_t)); + const size_t header_size = + ::rex::align(sizeof(D3DIASetVertexBuffersHeader), alignof(D3D12_VERTEX_BUFFER_VIEW)); + auto args = reinterpret_cast( + WriteCommand(Command::kD3DIASetVertexBuffers, + header_size + num_views * sizeof(D3D12_VERTEX_BUFFER_VIEW))); + args->start_slot = start_slot; + args->num_views = num_views; + std::memcpy(reinterpret_cast(args) + header_size, views, + sizeof(D3D12_VERTEX_BUFFER_VIEW) * num_views); + } + + void D3DOMSetBlendFactor(const FLOAT blend_factor[4]) { + auto args = + reinterpret_cast(WriteCommand(Command::kD3DOMSetBlendFactor, 4 * sizeof(FLOAT))); + args[0] = blend_factor[0]; + args[1] = blend_factor[1]; + args[2] = blend_factor[2]; + args[3] = blend_factor[3]; + } + + void D3DOMSetRenderTargets(UINT num_render_target_descriptors, + const D3D12_CPU_DESCRIPTOR_HANDLE* render_target_descriptors, + BOOL rts_single_handle_to_descriptor_range, + const D3D12_CPU_DESCRIPTOR_HANDLE* depth_stencil_descriptor) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kD3DOMSetRenderTargets, sizeof(D3DOMSetRenderTargetsArguments))); + num_render_target_descriptors = + std::min(num_render_target_descriptors, UINT(D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT)); + args.num_render_target_descriptors = num_render_target_descriptors; + args.rts_single_handle_to_descriptor_range = rts_single_handle_to_descriptor_range ? 1 : 0; + if (num_render_target_descriptors != 0) { + std::memcpy(args.render_target_descriptors, render_target_descriptors, + (rts_single_handle_to_descriptor_range ? 1 : num_render_target_descriptors) * + sizeof(D3D12_CPU_DESCRIPTOR_HANDLE)); + } + args.depth_stencil = (depth_stencil_descriptor != nullptr) ? 1 : 0; + if (depth_stencil_descriptor != nullptr) { + args.depth_stencil_descriptor.ptr = depth_stencil_descriptor->ptr; + } + } + + void D3DOMSetStencilRef(UINT stencil_ref) { + auto& arg = *reinterpret_cast(WriteCommand(Command::kD3DOMSetStencilRef, sizeof(UINT))); + arg = stencil_ref; + } + + void D3DResourceBarrier(UINT num_barriers, const D3D12_RESOURCE_BARRIER* barriers) { + if (num_barriers == 0) { + return; + } + static_assert(alignof(D3D12_RESOURCE_BARRIER) <= alignof(uintmax_t)); + const size_t header_size = ::rex::align(sizeof(UINT), alignof(D3D12_RESOURCE_BARRIER)); + uint8_t* args = reinterpret_cast(WriteCommand( + Command::kD3DResourceBarrier, header_size + num_barriers * sizeof(D3D12_RESOURCE_BARRIER))); + *reinterpret_cast(args) = num_barriers; + std::memcpy(args + header_size, barriers, num_barriers * sizeof(D3D12_RESOURCE_BARRIER)); + } + + void RSSetScissorRect(const D3D12_RECT& rect) { + auto& arg = *reinterpret_cast( + WriteCommand(Command::kRSSetScissorRect, sizeof(D3D12_RECT))); + arg = rect; + } + + void RSSetViewport(const D3D12_VIEWPORT& viewport) { + auto& arg = *reinterpret_cast( + WriteCommand(Command::kRSSetViewport, sizeof(D3D12_VIEWPORT))); + arg = viewport; + } + + void D3DSetComputeRoot32BitConstants(UINT root_parameter_index, UINT num_32bit_values_to_set, + const void* src_data, UINT dest_offset_in_32bit_values) { + if (num_32bit_values_to_set == 0) { + return; + } + auto args = reinterpret_cast(WriteCommand( + Command::kD3DSetComputeRoot32BitConstants, + sizeof(SetRoot32BitConstantsHeader) + num_32bit_values_to_set * sizeof(uint32_t))); + args->root_parameter_index = root_parameter_index; + args->num_32bit_values_to_set = num_32bit_values_to_set; + args->dest_offset_in_32bit_values = dest_offset_in_32bit_values; + std::memcpy(args + 1, src_data, num_32bit_values_to_set * sizeof(uint32_t)); + } + + void D3DSetGraphicsRoot32BitConstants(UINT root_parameter_index, UINT num_32bit_values_to_set, + const void* src_data, UINT dest_offset_in_32bit_values) { + if (num_32bit_values_to_set == 0) { + return; + } + auto args = reinterpret_cast(WriteCommand( + Command::kD3DSetGraphicsRoot32BitConstants, + sizeof(SetRoot32BitConstantsHeader) + num_32bit_values_to_set * sizeof(uint32_t))); + args->root_parameter_index = root_parameter_index; + args->num_32bit_values_to_set = num_32bit_values_to_set; + args->dest_offset_in_32bit_values = dest_offset_in_32bit_values; + std::memcpy(args + 1, src_data, num_32bit_values_to_set * sizeof(uint32_t)); + } + + void D3DSetComputeRootConstantBufferView(UINT root_parameter_index, + D3D12_GPU_VIRTUAL_ADDRESS buffer_location) { + auto& args = *reinterpret_cast(WriteCommand( + Command::kD3DSetComputeRootConstantBufferView, sizeof(SetRootConstantBufferViewArguments))); + args.root_parameter_index = root_parameter_index; + args.buffer_location = buffer_location; + } + + void D3DSetGraphicsRootConstantBufferView(UINT root_parameter_index, + D3D12_GPU_VIRTUAL_ADDRESS buffer_location) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kD3DSetGraphicsRootConstantBufferView, + sizeof(SetRootConstantBufferViewArguments))); + args.root_parameter_index = root_parameter_index; + args.buffer_location = buffer_location; + } + + void D3DSetComputeRootDescriptorTable(UINT root_parameter_index, + D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor) { + auto& args = *reinterpret_cast(WriteCommand( + Command::kD3DSetComputeRootDescriptorTable, sizeof(SetRootDescriptorTableArguments))); + args.root_parameter_index = root_parameter_index; + args.base_descriptor.ptr = base_descriptor.ptr; + } + + void D3DSetGraphicsRootDescriptorTable(UINT root_parameter_index, + D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor) { + auto& args = *reinterpret_cast(WriteCommand( + Command::kD3DSetGraphicsRootDescriptorTable, sizeof(SetRootDescriptorTableArguments))); + args.root_parameter_index = root_parameter_index; + args.base_descriptor.ptr = base_descriptor.ptr; + } + + void D3DSetComputeRootShaderResourceView(UINT root_parameter_index, + D3D12_GPU_VIRTUAL_ADDRESS buffer_location) { + auto& args = *reinterpret_cast(WriteCommand( + Command::kD3DSetComputeRootShaderResourceView, sizeof(SetRootConstantBufferViewArguments))); + args.root_parameter_index = root_parameter_index; + args.buffer_location = buffer_location; + } + + void D3DSetGraphicsRootShaderResourceView(UINT root_parameter_index, + D3D12_GPU_VIRTUAL_ADDRESS buffer_location) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kD3DSetGraphicsRootShaderResourceView, + sizeof(SetRootConstantBufferViewArguments))); + args.root_parameter_index = root_parameter_index; + args.buffer_location = buffer_location; + } + + void D3DSetComputeRootUnorderedAccessView(UINT root_parameter_index, + D3D12_GPU_VIRTUAL_ADDRESS buffer_location) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kD3DSetComputeRootUnorderedAccessView, + sizeof(SetRootConstantBufferViewArguments))); + args.root_parameter_index = root_parameter_index; + args.buffer_location = buffer_location; + } + + void D3DSetGraphicsRootUnorderedAccessView(UINT root_parameter_index, + D3D12_GPU_VIRTUAL_ADDRESS buffer_location) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kD3DSetGraphicsRootUnorderedAccessView, + sizeof(SetRootConstantBufferViewArguments))); + args.root_parameter_index = root_parameter_index; + args.buffer_location = buffer_location; + } + + void D3DSetComputeRootSignature(ID3D12RootSignature* root_signature) { + auto& arg = *reinterpret_cast( + WriteCommand(Command::kD3DSetComputeRootSignature, sizeof(ID3D12RootSignature*))); + arg = root_signature; + } + + void D3DSetGraphicsRootSignature(ID3D12RootSignature* root_signature) { + auto& arg = *reinterpret_cast( + WriteCommand(Command::kD3DSetGraphicsRootSignature, sizeof(ID3D12RootSignature*))); + arg = root_signature; + } + + void SetDescriptorHeaps(ID3D12DescriptorHeap* cbv_srv_uav_descriptor_heap, + ID3D12DescriptorHeap* sampler_descriptor_heap) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kSetDescriptorHeaps, sizeof(SetDescriptorHeapsArguments))); + args.cbv_srv_uav_descriptor_heap = cbv_srv_uav_descriptor_heap; + args.sampler_descriptor_heap = sampler_descriptor_heap; + } + + void D3DSetPipelineState(ID3D12PipelineState* pipeline_state) { + auto& arg = *reinterpret_cast( + WriteCommand(Command::kD3DSetPipelineState, sizeof(ID3D12PipelineState*))); + arg = pipeline_state; + } + + void SetPipelineStateHandle(void* pipeline_state_handle) { + auto& arg = + *reinterpret_cast(WriteCommand(Command::kSetPipelineStateHandle, sizeof(void*))); + arg = pipeline_state_handle; + } + + void D3DSetSamplePositions(UINT num_samples_per_pixel, UINT num_pixels, + const D3D12_SAMPLE_POSITION* sample_positions) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kD3DSetSamplePositions, sizeof(D3DSetSamplePositionsArguments))); + args.num_samples_per_pixel = num_samples_per_pixel; + args.num_pixels = num_pixels; + std::memcpy( + args.sample_positions, sample_positions, + std::min(num_samples_per_pixel * num_pixels, UINT(16)) * sizeof(D3D12_SAMPLE_POSITION)); + } + + void BeginDebugMarker(const char* label_name) { + size_t label_len = std::strlen(label_name); + uint8_t* args_ptr = reinterpret_cast( + WriteCommand(Command::kBeginDebugMarker, sizeof(DebugMarkerHeader) + label_len + 1)); + auto& args = *reinterpret_cast(args_ptr); + args.label_length = static_cast(label_len); + std::memcpy(args_ptr + sizeof(DebugMarkerHeader), label_name, label_len + 1); + } + + void EndDebugMarker() { WriteCommand(Command::kEndDebugMarker, 0); } + + void InsertDebugMarker(const char* label_name) { + size_t label_len = std::strlen(label_name); + uint8_t* args_ptr = reinterpret_cast( + WriteCommand(Command::kInsertDebugMarker, sizeof(DebugMarkerHeader) + label_len + 1)); + auto& args = *reinterpret_cast(args_ptr); + args.label_length = static_cast(label_len); + std::memcpy(args_ptr + sizeof(DebugMarkerHeader), label_name, label_len + 1); + } + + private: + enum class Command { + kD3DClearDepthStencilView, + kD3DClearRenderTargetView, + kD3DClearUnorderedAccessViewUint, + kD3DCopyBufferRegion, + kD3DCopyResource, + kCopyTexture, + kD3DCopyTextureRegion, + kD3DDispatch, + kD3DDrawIndexedInstanced, + kD3DDrawInstanced, + kD3DBeginQuery, + kD3DEndQuery, + kD3DResolveQueryData, + kD3DIASetIndexBuffer, + kD3DIASetPrimitiveTopology, + kD3DIASetVertexBuffers, + kD3DOMSetBlendFactor, + kD3DOMSetRenderTargets, + kD3DOMSetStencilRef, + kD3DResourceBarrier, + kRSSetScissorRect, + kRSSetViewport, + kD3DSetComputeRoot32BitConstants, + kD3DSetGraphicsRoot32BitConstants, + kD3DSetComputeRootConstantBufferView, + kD3DSetGraphicsRootConstantBufferView, + kD3DSetComputeRootDescriptorTable, + kD3DSetGraphicsRootDescriptorTable, + kD3DSetComputeRootShaderResourceView, + kD3DSetGraphicsRootShaderResourceView, + kD3DSetComputeRootSignature, + kD3DSetGraphicsRootSignature, + kD3DSetComputeRootUnorderedAccessView, + kD3DSetGraphicsRootUnorderedAccessView, + kSetDescriptorHeaps, + kD3DSetPipelineState, + kSetPipelineStateHandle, + kD3DSetSamplePositions, + kBeginDebugMarker, + kEndDebugMarker, + kInsertDebugMarker, + }; + + struct CommandHeader { + Command command; + uint32_t arguments_size_elements; + }; + static constexpr size_t kCommandHeaderSizeElements = + (sizeof(CommandHeader) + sizeof(uintmax_t) - 1) / sizeof(uintmax_t); + + struct ClearDepthStencilViewHeader { + D3D12_CPU_DESCRIPTOR_HANDLE depth_stencil_view; + D3D12_CLEAR_FLAGS clear_flags; + FLOAT depth; + UINT8 stencil; + UINT num_rects; + }; + + struct ClearRenderTargetViewHeader { + D3D12_CPU_DESCRIPTOR_HANDLE render_target_view; + FLOAT color_rgba[4]; + UINT num_rects; + }; + + struct ClearUnorderedAccessViewHeader { + D3D12_GPU_DESCRIPTOR_HANDLE view_gpu_handle_in_current_heap; + D3D12_CPU_DESCRIPTOR_HANDLE view_cpu_handle; + ID3D12Resource* resource; + union { + FLOAT values_float[4]; + UINT values_uint[4]; + }; + UINT num_rects; + }; + + struct D3DCopyBufferRegionArguments { + ID3D12Resource* dst_buffer; + UINT64 dst_offset; + ID3D12Resource* src_buffer; + UINT64 src_offset; + UINT64 num_bytes; + }; + + struct D3DCopyResourceArguments { + ID3D12Resource* dst_resource; + ID3D12Resource* src_resource; + }; + + struct CopyTextureArguments { + D3D12_TEXTURE_COPY_LOCATION dst; + D3D12_TEXTURE_COPY_LOCATION src; + }; + + struct D3DCopyTextureRegionArguments { + D3D12_TEXTURE_COPY_LOCATION dst; + UINT dst_x; + UINT dst_y; + UINT dst_z; + D3D12_TEXTURE_COPY_LOCATION src; + D3D12_BOX src_box; + bool has_src_box; + }; + + struct D3DDispatchArguments { + UINT thread_group_count_x; + UINT thread_group_count_y; + UINT thread_group_count_z; + }; + + struct D3DDrawIndexedInstancedArguments { + UINT index_count_per_instance; + UINT instance_count; + UINT start_index_location; + INT base_vertex_location; + UINT start_instance_location; + }; + + struct D3DDrawInstancedArguments { + UINT vertex_count_per_instance; + UINT instance_count; + UINT start_vertex_location; + UINT start_instance_location; + }; + + struct D3DQueryArguments { + ID3D12QueryHeap* query_heap; + D3D12_QUERY_TYPE type; + UINT index; + }; + + struct D3DResolveQueryDataArguments { + ID3D12QueryHeap* query_heap; + D3D12_QUERY_TYPE type; + UINT start_index; + UINT num_queries; + ID3D12Resource* destination_buffer; + UINT64 aligned_destination_buffer_offset; + }; + + struct D3DIASetVertexBuffersHeader { + UINT start_slot; + UINT num_views; + }; + + struct D3DOMSetRenderTargetsArguments { + uint8_t num_render_target_descriptors; + bool rts_single_handle_to_descriptor_range; + bool depth_stencil; + D3D12_CPU_DESCRIPTOR_HANDLE + render_target_descriptors[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT]; + D3D12_CPU_DESCRIPTOR_HANDLE depth_stencil_descriptor; + }; + + struct SetRoot32BitConstantsHeader { + UINT root_parameter_index; + UINT num_32bit_values_to_set; + UINT dest_offset_in_32bit_values; + }; + + struct SetRootConstantBufferViewArguments { + UINT root_parameter_index; + D3D12_GPU_VIRTUAL_ADDRESS buffer_location; + }; + + struct SetRootDescriptorTableArguments { + UINT root_parameter_index; + D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor; + }; + + struct SetDescriptorHeapsArguments { + ID3D12DescriptorHeap* cbv_srv_uav_descriptor_heap; + ID3D12DescriptorHeap* sampler_descriptor_heap; + }; + + struct D3DSetSamplePositionsArguments { + UINT num_samples_per_pixel; + UINT num_pixels; + D3D12_SAMPLE_POSITION sample_positions[16]; + }; + + struct DebugMarkerHeader { + uint32_t label_length; + // Followed by null-terminated label string. + }; + + void* WriteCommand(Command command, size_t arguments_size_bytes); + + const D3D12CommandProcessor& command_processor_; + + // uintmax_t to ensure uint64_t and pointer alignment of all structures. + std::vector command_stream_; +}; + +} // namespace rex::graphics::d3d12 diff --git a/include/rex/graphics/d3d12/graphics_system.h b/include/rex/graphics/d3d12/graphics_system.h new file mode 100644 index 0000000..3efe580 --- /dev/null +++ b/include/rex/graphics/d3d12/graphics_system.h @@ -0,0 +1,36 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include +#include +#include + +namespace rex::graphics::d3d12 { + +class D3D12GraphicsSystem : public GraphicsSystem { + public: + D3D12GraphicsSystem(); + ~D3D12GraphicsSystem() override; + + static bool IsAvailable(); + + std::string name() const override; + + protected: + void CreateProvider(bool with_presentation) override; + std::unique_ptr CreateCommandProcessor() override; +}; + +} // namespace rex::graphics::d3d12 diff --git a/include/rex/graphics/d3d12/pipeline_cache.h b/include/rex/graphics/d3d12/pipeline_cache.h new file mode 100644 index 0000000..7a9d6a2 --- /dev/null +++ b/include/rex/graphics/d3d12/pipeline_cache.h @@ -0,0 +1,424 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::graphics::d3d12 { + +class D3D12CommandProcessor; + +class PipelineCache { + public: + static constexpr size_t kLayoutUIDEmpty = 0; + + PipelineCache(D3D12CommandProcessor& command_processor, const RegisterFile& register_file, + const D3D12RenderTargetCache& render_target_cache, bool bindless_resources_used); + ~PipelineCache(); + + bool Initialize(); + void Shutdown(); + // No ClearCache because it's undesirable with the persistent shader storage + // (if the storage is reloaded, effectively nothing is cleared, while the call + // takes a long time, and if it's not, there will be heavy stuttering for the + // rest of the execution of the guest). + + void InitializeShaderStorage(const std::filesystem::path& cache_root, uint32_t title_id, + bool blocking); + void ShutdownShaderStorage(); + + void EndSubmission(); + bool IsCreatingPipelines(); + + D3D12Shader* LoadShader(xenos::ShaderType shader_type, const uint32_t* host_address, + uint32_t dword_count); + // Analyze shader microcode on the translator thread. + void AnalyzeShaderUcode(Shader& shader) { shader.AnalyzeUcode(ucode_disasm_buffer_); } + + // Retrieves the shader modification for the current state. The shader must + // have microcode analyzed. + DxbcShaderTranslator::Modification GetCurrentVertexShaderModification( + const Shader& shader, Shader::HostVertexShaderType host_vertex_shader_type, + uint32_t interpolator_mask) const; + DxbcShaderTranslator::Modification GetCurrentPixelShaderModification( + const Shader& shader, uint32_t interpolator_mask, uint32_t param_gen_pos, + reg::RB_DEPTHCONTROL normalized_depth_control) const; + + // If draw_util::IsRasterizationPotentiallyDone is false, the pixel shader + // MUST be made nullptr BEFORE calling this! + bool ConfigurePipeline(D3D12Shader::D3D12Translation* vertex_shader, + D3D12Shader::D3D12Translation* pixel_shader, + const PrimitiveProcessor::ProcessingResult& primitive_processing_result, + reg::RB_DEPTHCONTROL normalized_depth_control, + uint32_t normalized_color_mask, + uint32_t bound_depth_and_color_render_target_bits, + const uint32_t* bound_depth_and_color_render_targets_formats, + void** pipeline_handle_out, ID3D12RootSignature** root_signature_out); + + // Returns a pipeline with deferred creation by its handle. May return nullptr + // if failed to create the pipeline. + ID3D12PipelineState* GetD3D12PipelineByHandle(void* handle) const { + return reinterpret_cast(handle)->state.load(std::memory_order_acquire); + } + + private: + REXPACKEDSTRUCT(ShaderStoredHeader, { + uint64_t ucode_data_hash; + + uint32_t ucode_dword_count : 31; + xenos::ShaderType type : 1; + + static constexpr uint32_t kVersion = 0x20201219; + }); + + // Update PipelineDescription::kVersion if any of the Pipeline* enums are + // changed! + + enum class PipelineStripCutIndex : uint32_t { + kNone, + kFFFF, + kFFFFFFFF, + }; + + enum class PipelineTessellationMode : uint32_t { + kNone, + kDiscrete, + kContinuous, + kAdaptive, + }; + + enum class PipelinePatchType : uint32_t { + kNone, + kLine, + kTriangle, + kQuad, + }; + + enum class PipelinePrimitiveTopologyType : uint32_t { + kPoint, + kLine, + kTriangle, + }; + + enum class PipelineGeometryShader : uint32_t { + kNone, + kPointList, + kRectangleList, + kQuadList, + }; + + enum class PipelineCullMode : uint32_t { + kNone, + kFront, + kBack, + // Special case, handled via disabling the pixel shader and depth / stencil. + kDisableRasterization, + }; + + enum class PipelineBlendFactor : uint32_t { + kZero, + kOne, + kSrcColor, + kInvSrcColor, + kSrcAlpha, + kInvSrcAlpha, + kDestColor, + kInvDestColor, + kDestAlpha, + kInvDestAlpha, + kBlendFactor, + kInvBlendFactor, + kSrcAlphaSat, + }; + + // Update PipelineDescription::kVersion if anything is changed! + REXPACKEDSTRUCT(PipelineRenderTarget, { + uint32_t used : 1; // 1 + xenos::ColorRenderTargetFormat format : 4; // 5 + PipelineBlendFactor src_blend : 4; // 9 + PipelineBlendFactor dest_blend : 4; // 13 + xenos::BlendOp blend_op : 3; // 16 + PipelineBlendFactor src_blend_alpha : 4; // 20 + PipelineBlendFactor dest_blend_alpha : 4; // 24 + xenos::BlendOp blend_op_alpha : 3; // 27 + uint32_t write_mask : 4; // 31 + }); + + REXPACKEDSTRUCT(PipelineDescription, { + uint64_t vertex_shader_hash; + uint64_t vertex_shader_modification; + // 0 if drawing without a pixel shader. + uint64_t pixel_shader_hash; + uint64_t pixel_shader_modification; + + int32_t depth_bias; + float depth_bias_slope_scaled; + + PipelineStripCutIndex strip_cut_index : 2; // 2 + // PipelinePrimitiveTopologyType for a vertex shader. + // xenos::TessellationMode for a domain shader. + uint32_t primitive_topology_type_or_tessellation_mode : 2; // 4 + // Zero for non-kVertex host_vertex_shader_type. + PipelineGeometryShader geometry_shader : 2; // 6 + uint32_t fill_mode_wireframe : 1; // 7 + PipelineCullMode cull_mode : 2; // 9 + uint32_t front_counter_clockwise : 1; // 10 + uint32_t depth_clip : 1; // 11 + xenos::MsaaSamples host_msaa_samples : 2; // 13 + xenos::DepthRenderTargetFormat depth_format : 1; // 14 + xenos::CompareFunction depth_func : 3; // 17 + uint32_t depth_write : 1; // 18 + uint32_t stencil_enable : 1; // 19 + uint32_t stencil_read_mask : 8; // 27 + + uint32_t stencil_write_mask : 8; // 8 + xenos::StencilOp stencil_front_fail_op : 3; // 11 + xenos::StencilOp stencil_front_depth_fail_op : 3; // 14 + xenos::StencilOp stencil_front_pass_op : 3; // 17 + xenos::CompareFunction stencil_front_func : 3; // 20 + xenos::StencilOp stencil_back_fail_op : 3; // 23 + xenos::StencilOp stencil_back_depth_fail_op : 3; // 26 + xenos::StencilOp stencil_back_pass_op : 3; // 29 + xenos::CompareFunction stencil_back_func : 3; // 32 + + PipelineRenderTarget render_targets[xenos::kMaxColorRenderTargets]; + + static constexpr uint32_t kVersion = 0x20210425; + }); + + REXPACKEDSTRUCT(PipelineStoredDescription, { + uint64_t description_hash; + PipelineDescription description; + }); + + struct PipelineRuntimeDescription { + ID3D12RootSignature* root_signature; + D3D12Shader::D3D12Translation* vertex_shader; + D3D12Shader::D3D12Translation* pixel_shader; + const std::vector* geometry_shader; + PipelineDescription description; + }; + + struct Pipeline; + + union GeometryShaderKey { + uint32_t key; + struct { + PipelineGeometryShader type : 2; + uint32_t interpolator_count : 5; + uint32_t user_clip_plane_count : 3; + uint32_t user_clip_plane_cull : 1; + uint32_t has_vertex_kill_and : 1; + uint32_t has_point_size : 1; + uint32_t has_point_coordinates : 1; + // PA_CL_CLIP_CNTL::ps_ucp_mode for point primitives. + uint32_t point_ps_ucp_mode : 2; + }; + + GeometryShaderKey() : key(0) { static_assert_size(*this, sizeof(key)); } + + struct Hasher { + size_t operator()(const GeometryShaderKey& key) const { + return std::hash{}(key.key); + } + }; + bool operator==(const GeometryShaderKey& other_key) const { return key == other_key.key; } + bool operator!=(const GeometryShaderKey& other_key) const { return !(*this == other_key); } + }; + + D3D12Shader* LoadShader(xenos::ShaderType shader_type, const uint32_t* host_address, + uint32_t dword_count, uint64_t data_hash); + + // Can be called from multiple threads. + bool TranslateAnalyzedShader(DxbcShaderTranslator& translator, + D3D12Shader::D3D12Translation& translation, + IDxbcConverter* dxbc_converter = nullptr, + IDxcUtils* dxc_utils = nullptr, + IDxcCompiler* dxc_compiler = nullptr); + + // If draw_util::IsRasterizationPotentiallyDone is false, the pixel shader + // MUST be made nullptr BEFORE calling this! The shaders must be translated + // and valid unless for_placeholder is true. + bool GetCurrentStateDescription( + D3D12Shader::D3D12Translation* vertex_shader, D3D12Shader::D3D12Translation* pixel_shader, + const PrimitiveProcessor::ProcessingResult& primitive_processing_result, + reg::RB_DEPTHCONTROL normalized_depth_control, uint32_t normalized_color_mask, + uint32_t bound_depth_and_color_render_target_bits, + const uint32_t* bound_depth_and_color_render_target_formats, + PipelineRuntimeDescription& runtime_description_out, bool for_placeholder = false); + + static bool GetGeometryShaderKey(PipelineGeometryShader geometry_shader_type, + DxbcShaderTranslator::Modification vertex_shader_modification, + DxbcShaderTranslator::Modification pixel_shader_modification, + GeometryShaderKey& key_out); + static void CreateDxbcGeometryShader(GeometryShaderKey key, std::vector& shader_out); + const std::vector& GetGeometryShader(GeometryShaderKey key); + + ID3D12PipelineState* CreateD3D12Pipeline(const PipelineRuntimeDescription& runtime_description); + bool PrepareRuntimeDescriptionForQueuedCreation(Pipeline* pipeline, + PipelineRuntimeDescription& runtime_description); + + D3D12CommandProcessor& command_processor_; + const RegisterFile& register_file_; + const D3D12RenderTargetCache& render_target_cache_; + bool bindless_resources_used_; + + // Temporary storage for AnalyzeUcode calls on the processor thread. + string::StringBuffer ucode_disasm_buffer_; + // Reusable shader translator for the processor thread. + std::unique_ptr shader_translator_; + std::mutex translation_request_lock_; + + // Command processor thread DXIL conversion/disassembly interfaces, if DXIL + // disassembly is enabled. + IDxbcConverter* dxbc_converter_ = nullptr; + IDxcUtils* dxc_utils_ = nullptr; + IDxcCompiler* dxc_compiler_ = nullptr; + + // Ucode hash -> shader. + std::unordered_map> shaders_; + + struct LayoutUID { + size_t uid; + size_t vector_span_offset; + size_t vector_span_length; + }; + std::mutex layouts_mutex_; + // Texture binding layouts of different shaders, for obtaining layout UIDs. + std::vector texture_binding_layouts_; + // Map of texture binding layouts used by shaders, for obtaining UIDs. Keys + // are XXH3 hashes of layouts, values need manual collision resolution using + // layout_vector_offset:layout_length of texture_binding_layouts_. + std::unordered_multimap> + texture_binding_layout_map_; + // Bindless sampler indices of different shaders, for obtaining layout UIDs. + // For bindful, sampler count is used as the UID instead. + std::vector bindless_sampler_layouts_; + // Keys are XXH3 hashes of used bindless sampler indices. + std::unordered_multimap> + bindless_sampler_layout_map_; + + // Geometry shaders for Xenos primitive types not supported by Direct3D 12. + std::unordered_map, GeometryShaderKey::Hasher> + geometry_shaders_; + + // Empty depth-only pixel shader for writing to depth buffer via ROV when no + // Xenos pixel shader provided. + std::vector depth_only_pixel_shader_; + + struct Pipeline { + // nullptr if creation has failed. + std::atomic state{nullptr}; + std::atomic root_signature{nullptr}; + PipelineRuntimeDescription description; + D3D12Shader::D3D12Translation* pending_vertex_shader = nullptr; + D3D12Shader::D3D12Translation* pending_pixel_shader = nullptr; + uint8_t priority = 0; + }; + struct PipelineCreationPriorityComparator { + bool operator()(const Pipeline* a, const Pipeline* b) const { + uint8_t priority_a = a ? a->priority : 0; + uint8_t priority_b = b ? b->priority : 0; + return priority_a < priority_b; + } + }; + // All previously generated pipelines identified by hash and the description. + std::unordered_multimap> pipelines_; + + // Previously used pipeline. This matches our current state settings and + // allows us to quickly(ish) reuse the pipeline if no registers have been + // changed. + Pipeline* current_pipeline_ = nullptr; + + // Currently open shader storage path. + std::filesystem::path shader_storage_cache_root_; + uint32_t shader_storage_title_id_ = 0; + + // Shader storage output stream, for preload in the next emulator runs. + FILE* shader_storage_file_ = nullptr; + // For only writing shaders to the currently open storage once, incremented + // when switching the storage. + uint32_t shader_storage_index_ = 0; + bool shader_storage_file_flush_needed_ = false; + + // Pipeline storage output stream, for preload in the next emulator runs. + FILE* pipeline_storage_file_ = nullptr; + bool pipeline_storage_file_flush_needed_ = false; + + // Thread for asynchronous writing to the storage streams. + void StorageWriteThread(); + std::mutex storage_write_request_lock_; + std::condition_variable storage_write_request_cond_; + // Storage thread input is protected with storage_write_request_lock_, and the + // thread is notified about its change via storage_write_request_cond_. + std::deque storage_write_shader_queue_; + std::deque storage_write_pipeline_queue_; + bool storage_write_flush_shaders_ = false; + bool storage_write_flush_pipelines_ = false; + bool storage_write_thread_shutdown_ = false; + std::unique_ptr storage_write_thread_; + + // Pipeline creation threads. + void CreationThread(size_t thread_index); + void CreateQueuedPipelinesOnProcessorThread(); + std::mutex creation_request_lock_; + std::condition_variable creation_request_cond_; + // Protected with creation_request_lock_, notify_one creation_request_cond_ + // when set. + std::priority_queue, PipelineCreationPriorityComparator> + creation_queue_; + // Number of threads that are currently creating a pipeline - incremented when + // a pipeline is dequeued (the completion event can't be triggered before this + // is zero). Protected with creation_request_lock_. + size_t creation_threads_busy_ = 0; + // Manual-reset event set when the last queued pipeline is created and there + // are no more pipelines to create. This is triggered by the thread creating + // the last pipeline. + std::unique_ptr creation_completion_event_; + // Whether setting the event on completion is queued. Protected with + // creation_request_lock_, notify_one creation_request_cond_ when set. + bool creation_completion_set_event_ = false; + // Creation threads with this index or above need to be shut down as soon as + // possible. Protected with creation_request_lock_, notify_all + // creation_request_cond_ when set. + size_t creation_threads_shutdown_from_ = SIZE_MAX; + std::vector> creation_threads_; +}; + +} // namespace rex::graphics::d3d12 diff --git a/include/rex/graphics/d3d12/primitive_processor.h b/include/rex/graphics/d3d12/primitive_processor.h new file mode 100644 index 0000000..18249fb --- /dev/null +++ b/include/rex/graphics/d3d12/primitive_processor.h @@ -0,0 +1,81 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include + +#include +#include +#include +#include + +namespace rex::graphics::d3d12 { + +class D3D12CommandProcessor; + +class D3D12PrimitiveProcessor final : public PrimitiveProcessor { + public: + D3D12PrimitiveProcessor(const RegisterFile& register_file, memory::Memory& memory, + TraceWriter& trace_writer, SharedMemory& shared_memory, + D3D12CommandProcessor& command_processor) + : PrimitiveProcessor(register_file, memory, trace_writer, shared_memory), + command_processor_(command_processor) {} + ~D3D12PrimitiveProcessor(); + + bool Initialize(); + void Shutdown(bool from_destructor = false); + void ClearCache() { frame_index_buffer_pool_->ClearCache(); } + + void CompletedSubmissionUpdated(); + void BeginSubmission(); + void BeginFrame(); + void EndFrame(); + + D3D12_GPU_VIRTUAL_ADDRESS GetBuiltinIndexBufferGpuAddress(size_t handle) const { + assert_not_null(builtin_index_buffer_); + return D3D12_GPU_VIRTUAL_ADDRESS(builtin_index_buffer_gpu_address_ + + GetBuiltinIndexBufferOffsetBytes(handle)); + } + D3D12_GPU_VIRTUAL_ADDRESS GetConvertedIndexBufferGpuAddress(size_t handle) const { + return frame_index_buffers_[handle]; + } + + protected: + bool InitializeBuiltinIndexBuffer(size_t size_bytes, + std::function fill_callback) override; + + void* RequestHostConvertedIndexBufferForCurrentFrame(xenos::IndexFormat format, + uint32_t index_count, bool coalign_for_simd, + uint32_t coalignment_original_address, + size_t& backend_handle_out) override; + + private: + D3D12CommandProcessor& command_processor_; + + Microsoft::WRL::ComPtr builtin_index_buffer_; + D3D12_GPU_VIRTUAL_ADDRESS builtin_index_buffer_gpu_address_ = 0; + // Temporary buffer copied in the beginning of the first submission for + // uploading to builtin_index_buffer_, destroyed when the submission when it + // was uploaded is completed. + Microsoft::WRL::ComPtr builtin_index_buffer_upload_; + // UINT64_MAX means not uploaded yet and needs uploading in the first + // submission (if the upload buffer exists at all). + uint64_t builtin_index_buffer_upload_submission_ = UINT64_MAX; + + std::unique_ptr frame_index_buffer_pool_; + // Indexed by the backend handles. + std::deque frame_index_buffers_; +}; + +} // namespace rex::graphics::d3d12 diff --git a/include/rex/graphics/d3d12/render_target_cache.h b/include/rex/graphics/d3d12/render_target_cache.h new file mode 100644 index 0000000..b9d2688 --- /dev/null +++ b/include/rex/graphics/d3d12/render_target_cache.h @@ -0,0 +1,769 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +namespace rex::graphics::d3d12 { + +class D3D12CommandProcessor; + +class D3D12RenderTargetCache final : public RenderTargetCache { + public: + D3D12RenderTargetCache(const RegisterFile& register_file, const memory::Memory& memory, + TraceWriter& trace_writer, uint32_t draw_resolution_scale_x, + uint32_t draw_resolution_scale_y, D3D12CommandProcessor& command_processor, + bool bindless_resources_used) + : RenderTargetCache(register_file, memory, &trace_writer, draw_resolution_scale_x, + draw_resolution_scale_y), + command_processor_(command_processor), + trace_writer_(trace_writer), + bindless_resources_used_(bindless_resources_used) {} + ~D3D12RenderTargetCache() override; + + bool Initialize(); + void Shutdown(bool from_destructor = false); + + void CompletedSubmissionUpdated(); + void BeginSubmission(); + + Path GetPath() const override { return path_; } + + bool Update(bool is_rasterization_done, reg::RB_DEPTHCONTROL normalized_depth_control, + uint32_t normalized_color_mask, const Shader& vertex_shader) override; + + void InvalidateCommandListRenderTargets() { + are_current_command_list_render_targets_valid_ = false; + } + + bool msaa_2x_supported() const { return msaa_2x_supported_; } + + void WriteEdramRawSRVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle); + void WriteEdramRawUAVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle); + void WriteEdramUintPow2SRVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle, + uint32_t element_size_bytes_pow2); + void WriteEdramUintPow2UAVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle, + uint32_t element_size_bytes_pow2); + + // Performs the resolve to a shared memory area according to the current + // register values, and also clears the render targets if needed. Must be in a + // frame for calling. + bool Resolve(const memory::Memory& memory, D3D12SharedMemory& shared_memory, + D3D12TextureCache& texture_cache, uint32_t& written_address_out, + uint32_t& written_length_out); + + // Returns true if any downloads were submitted to the command processor. + bool InitializeTraceSubmitDownloads(); + void InitializeTraceCompleteDownloads(); + void RestoreEdramSnapshot(const void* snapshot); + + // For host render targets. + + bool gamma_render_target_as_unorm16() const { return gamma_render_target_as_unorm16_; } + + // Using R16G16[B16A16]_SNORM, which are -1...1, not the needed -32...32. + // Persistent data doesn't depend on this, so can be overriden by per-game + // configuration. + bool IsFixed16TruncatedToMinus1To1() const { + return GetPath() == Path::kHostRenderTargets && !REXCVAR_GET(snorm16_render_target_full_range); + } + + bool depth_float24_round() const { return depth_float24_round_; } + bool depth_float24_convert_in_pixel_shader() const { + return depth_float24_convert_in_pixel_shader_; + } + + DXGI_FORMAT GetColorResourceDXGIFormat(xenos::ColorRenderTargetFormat format) const; + DXGI_FORMAT GetColorDrawDXGIFormat(xenos::ColorRenderTargetFormat format) const; + DXGI_FORMAT GetColorOwnershipTransferDXGIFormat(xenos::ColorRenderTargetFormat format, + bool* is_integer_out = nullptr) const; + static DXGI_FORMAT GetDepthResourceDXGIFormat(xenos::DepthRenderTargetFormat format); + static DXGI_FORMAT GetDepthDSVDXGIFormat(xenos::DepthRenderTargetFormat format); + static DXGI_FORMAT GetDepthSRVDepthDXGIFormat(xenos::DepthRenderTargetFormat format); + static DXGI_FORMAT GetDepthSRVStencilDXGIFormat(xenos::DepthRenderTargetFormat format); + + protected: + uint32_t GetMaxRenderTargetWidth() const override { return D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; } + uint32_t GetMaxRenderTargetHeight() const override { + return D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; + } + + RenderTarget* CreateRenderTarget(RenderTargetKey key) override; + + bool IsHostDepthEncodingDifferent(xenos::DepthRenderTargetFormat format) const override; + + bool IsGammaFormatHostStorageSeparate() const override; + + void RequestPixelShaderInterlockBarrier() override; + + private: + enum class EdramBufferModificationStatus { + // The values are ordered by how strong the barrier conditions are. + // No uncommitted ROV/UAV writes. + kUnmodified, + // Need to commit before the next ROV usage with overlap. + kAsROV, + // Need to commit before any next ROV usage. + kAsUAV, + }; + void TransitionEdramBuffer(D3D12_RESOURCE_STATES new_state); + void MarkEdramBufferModified( + EdramBufferModificationStatus modification_status = EdramBufferModificationStatus::kAsUAV); + void CommitEdramBufferUAVWrites( + EdramBufferModificationStatus commit_status = EdramBufferModificationStatus::kAsROV); + + D3D12CommandProcessor& command_processor_; + TraceWriter& trace_writer_; + bool bindless_resources_used_; + + Path path_ = Path::kHostRenderTargets; + + // For host render targets, an EDRAM-sized scratch buffer for: + // - Guest render target data copied from host render targets during copying + // in resolves and in frame trace creation. + // - Host float32 depth in ownership transfers when the host depth texture and + // the destination are the same. + // For rasterizer-ordered view, the buffer containing the EDRAM data. + // (Note that if a hybrid RTV / DSV + ROV approach to color render targets is + // added, which is, however, unlikely as it would have very complicated + // interaction with depth / stencil testing, host depth will need to be + // copied to a different buffer - the same range may have ROV-owned color and + // host float32 depth at the same time). + ID3D12Resource* edram_buffer_ = nullptr; + D3D12_RESOURCE_STATES edram_buffer_state_; + EdramBufferModificationStatus edram_buffer_modification_status_ = + EdramBufferModificationStatus::kUnmodified; + + // Non-shader-visible descriptor heap containing pre-created SRV and UAV + // descriptors of the EDRAM buffer, for faster binding (by copying rather + // than creation). + enum class EdramBufferDescriptorIndex : uint32_t { + kRawSRV, + kR32UintSRV, + kR32G32UintSRV, + kR32G32B32A32UintSRV, + kRawUAV, + kR32UintUAV, + kR32G32UintUAV, + kR32G32B32A32UintUAV, + + kCount, + }; + ID3D12DescriptorHeap* edram_buffer_descriptor_heap_ = nullptr; + D3D12_CPU_DESCRIPTOR_HANDLE edram_buffer_descriptor_heap_start_; + + // Resolve copying root signature and pipelines. + // Parameter 0 - draw_util::ResolveCopyShaderConstants or its ::DestRelative. + // Parameter 1 - destination (shared memory or a part of it). + // Parameter 2 - source (EDRAM). + ID3D12RootSignature* resolve_copy_root_signature_ = nullptr; + struct ResolveCopyShaderCode { + const void* unscaled; + size_t unscaled_size; + const void* scaled; + size_t scaled_size; + }; + static const ResolveCopyShaderCode + kResolveCopyShaders[size_t(draw_util::ResolveCopyShaderIndex::kCount)]; + ID3D12PipelineState* resolve_copy_pipelines_[size_t(draw_util::ResolveCopyShaderIndex::kCount)] = + {}; + + // For traces. + ID3D12Resource* edram_snapshot_download_buffer_ = nullptr; + std::unique_ptr edram_snapshot_restore_pool_; + + // For host render targets. + + class D3D12RenderTarget final : public RenderTarget { + public: + // descriptor_load_separate is present when the DXGI formats are different + // for drawing and bit-exact loading (for NaN pattern preservation across + // EDRAM tile ownership transfers in floating-point formats, and to + // distinguish between two -1 representations in snorm formats). + D3D12RenderTarget(RenderTargetKey key, ID3D12Resource* resource, + ui::d3d12::D3D12CpuDescriptorPool::Descriptor&& descriptor_draw, + ui::d3d12::D3D12CpuDescriptorPool::Descriptor&& descriptor_load_separate, + ui::d3d12::D3D12CpuDescriptorPool::Descriptor&& descriptor_srv, + ui::d3d12::D3D12CpuDescriptorPool::Descriptor&& descriptor_srv_stencil, + D3D12_RESOURCE_STATES resource_state) + : RenderTarget(key), + resource_(resource), + descriptor_draw_(std::move(descriptor_draw)), + descriptor_load_separate_(std::move(descriptor_load_separate)), + descriptor_srv_(std::move(descriptor_srv)), + descriptor_srv_stencil_(std::move(descriptor_srv_stencil)), + resource_state_(resource_state) {} + + ID3D12Resource* resource() const { return resource_.Get(); } + const ui::d3d12::D3D12CpuDescriptorPool::Descriptor& descriptor_draw() const { + return descriptor_draw_; + } + const ui::d3d12::D3D12CpuDescriptorPool::Descriptor& descriptor_srv() const { + return descriptor_srv_; + } + const ui::d3d12::D3D12CpuDescriptorPool::Descriptor& descriptor_srv_stencil() const { + return descriptor_srv_stencil_; + } + const ui::d3d12::D3D12CpuDescriptorPool::Descriptor& descriptor_load_separate() const { + return descriptor_load_separate_; + } + + D3D12_RESOURCE_STATES SetResourceState(D3D12_RESOURCE_STATES new_state) { + D3D12_RESOURCE_STATES old_state = resource_state_; + resource_state_ = new_state; + return old_state; + } + + uint32_t temporary_srv_descriptor_index() const { return temporary_srv_descriptor_index_; } + void SetTemporarySRVDescriptorIndex(uint32_t index) { temporary_srv_descriptor_index_ = index; } + uint32_t temporary_srv_descriptor_index_stencil() const { + return temporary_srv_descriptor_index_stencil_; + } + void SetTemporarySRVDescriptorIndexStencil(uint32_t index) { + temporary_srv_descriptor_index_stencil_ = index; + } + uint32_t temporary_sort_index() const { return temporary_sort_index_; } + void SetTemporarySortIndex(uint32_t index) { temporary_sort_index_ = index; } + + private: + Microsoft::WRL::ComPtr resource_; + ui::d3d12::D3D12CpuDescriptorPool::Descriptor descriptor_draw_; + ui::d3d12::D3D12CpuDescriptorPool::Descriptor descriptor_load_separate_; + // Texture SRV non-shader-visible descriptors, to prepare shader-visible + // descriptors faster, by copying rather than by creating every time. + // TODO(Triang3l): With bindless resources, persistently store them in the + // heap. + ui::d3d12::D3D12CpuDescriptorPool::Descriptor descriptor_srv_; + ui::d3d12::D3D12CpuDescriptorPool::Descriptor descriptor_srv_stencil_; + D3D12_RESOURCE_STATES resource_state_; + // Temporary storage for indices in operations like transfers and dumps. + uint32_t temporary_srv_descriptor_index_ = UINT32_MAX; + uint32_t temporary_srv_descriptor_index_stencil_ = UINT32_MAX; + uint32_t temporary_sort_index_ = 0; + }; + + enum TransferCBVRegister : uint32_t { + kTransferCBVRegisterStencilMask, + kTransferCBVRegisterAddress, + kTransferCBVRegisterHostDepthAddress, + }; + enum TransferSRVRegister : uint32_t { + kTransferSRVRegisterColor, + kTransferSRVRegisterDepth, + kTransferSRVRegisterStencil, + kTransferSRVRegisterHostDepth, + kTransferSRVRegisterCount, + }; + enum TransferUsedRootParameter : uint32_t { + // Changed 8 times per transfer. + kTransferUsedRootParameterStencilMaskConstant, + kTransferUsedRootParameterColorSRV, + // Mutually exclusive with ColorSRV. + kTransferUsedRootParameterDepthSRV, + // Mutually exclusive with ColorSRV. + kTransferUsedRootParameterStencilSRV, + // May happen to be the same for different sources. + kTransferUsedRootParameterAddressConstant, + kTransferUsedRootParameterHostDepthSRV, + kTransferUsedRootParameterHostDepthAddressConstant, + kTransferUsedRootParameterCount, + + kTransferUsedRootParameterStencilMaskConstantBit = + uint32_t(1) << kTransferUsedRootParameterStencilMaskConstant, + kTransferUsedRootParameterColorSRVBit = uint32_t(1) << kTransferUsedRootParameterColorSRV, + kTransferUsedRootParameterDepthSRVBit = uint32_t(1) << kTransferUsedRootParameterDepthSRV, + kTransferUsedRootParameterStencilSRVBit = uint32_t(1) << kTransferUsedRootParameterStencilSRV, + kTransferUsedRootParameterAddressConstantBit = uint32_t(1) + << kTransferUsedRootParameterAddressConstant, + kTransferUsedRootParameterHostDepthSRVBit = uint32_t(1) + << kTransferUsedRootParameterHostDepthSRV, + kTransferUsedRootParameterHostDepthAddressConstantBit = + uint32_t(1) << kTransferUsedRootParameterHostDepthAddressConstant, + + kTransferUsedRootParametersDescriptorMask = + kTransferUsedRootParameterColorSRVBit | kTransferUsedRootParameterDepthSRVBit | + kTransferUsedRootParameterStencilSRVBit | kTransferUsedRootParameterHostDepthSRVBit, + }; + enum class TransferRootSignatureIndex { + kColor, + kDepth, + kDepthStencil, + kColorToStencilBit, + kStencilToStencilBit, + kColorAndHostDepth, + kDepthAndHostDepth, + kDepthStencilAndHostDepth, + kCount, + }; + static const uint32_t kTransferUsedRootParameters[size_t(TransferRootSignatureIndex::kCount)]; + enum class TransferMode : uint32_t { + // 1 SRV (color texture), source constant. + kColorToDepth, + // 1 SRV (color texture), source constant. + kColorToColor, + + // 1 or 2 SRVs (depth texture, stencil texture if SV_StencilRef is + // supported), source constant. + kDepthToDepth, + // 2 SRVs (depth texture, stencil texture), source constant. + kDepthToColor, + + // 1 SRV (color texture), mask constant (most frequently changed, 8 times + // per transfer), source constant. + kColorToStencilBit, + // 1 SRV (stencil texture), mask constant, source constant. + kDepthToStencilBit, + + // Two-source modes, using the host depth if it, when converted to the guest + // format, matches what's in the owner source (not modified, keep host + // precision), or the guest data otherwise (significantly modified, possibly + // cleared). Stencil for SV_StencilRef is always taken from the guest + // source. + + // 2 SRVs (color texture, host depth texture or buffer), source constant, + // host depth source constant. + kColorAndHostDepthToDepth, + // When using different source and destination depth formats. 2 or 3 SRVs + // (depth texture, stencil texture if SV_StencilRef is supported, host depth + // texture or buffer), source constant, host depth source constant. + kDepthAndHostDepthToDepth, + + kCount, + }; + enum class TransferOutput { + kColor, + kDepth, + // With this output, kTransferCBVRegisterStencilMask is used. + kStencilBit, + }; + struct TransferModeInfo { + TransferOutput output; + TransferRootSignatureIndex root_signature_no_stencil_ref; + TransferRootSignatureIndex root_signature_with_stencil_ref; + }; + static const TransferModeInfo kTransferModes[size_t(TransferMode::kCount)]; + + union TransferShaderKey { + uint32_t key; + struct { + xenos::MsaaSamples dest_msaa_samples : xenos::kMsaaSamplesBits; + uint32_t dest_resource_format : xenos::kRenderTargetFormatBits; + xenos::MsaaSamples source_msaa_samples : xenos::kMsaaSamplesBits; + // Always 1x when host_depth_source_is_copy is true not to create the same + // pipeline for different MSAA sample counts as it doesn't matter in this + // case. + xenos::MsaaSamples host_depth_source_msaa_samples : xenos::kMsaaSamplesBits; + uint32_t source_resource_format : xenos::kRenderTargetFormatBits; + // If host depth is also fetched, whether it's pre-copied to the EDRAM + // buffer (but since it's just a scratch buffer, with tiles laid out + // linearly with the same pitch as in the original render target; also no + // swapping of 40-sample columns as opposed to the host render target - + // this is done only for the color source). + uint32_t host_depth_source_is_copy : 1; + + // Last bits because this affects the root signature - after sorting, only + // change it as fewer times as possible. Depth buffers have an additional + // stencil SRV. + static_assert(size_t(TransferMode::kCount) <= (size_t(1) << 3)); + TransferMode mode : 3; + }; + + TransferShaderKey() : key(0) { static_assert_size(*this, sizeof(key)); } + + struct Hasher { + size_t operator()(const TransferShaderKey& key) const { + return std::hash{}(key.key); + } + }; + bool operator==(const TransferShaderKey& other_key) const { return key == other_key.key; } + bool operator!=(const TransferShaderKey& other_key) const { return !(*this == other_key); } + bool operator<(const TransferShaderKey& other_key) const { return key < other_key.key; } + }; + + union TransferAddressConstant { + uint32_t constant; + struct { + // All in tiles. + uint32_t dest_pitch : xenos::kEdramPitchTilesBits; + uint32_t source_pitch : xenos::kEdramPitchTilesBits; + // Destination base in tiles minus source base in tiles (not vice versa + // because this is a transform of the coordinate system, not addresses + // themselves). + // + 1 bit because this is a signed difference between two EDRAM bases. + // 0 for host_depth_source_is_copy (ignored in this case anyway as + // destination == source anyway). + int32_t source_to_dest : xenos::kEdramBaseTilesBits + 1; + }; + TransferAddressConstant() : constant(0) { static_assert_size(*this, sizeof(constant)); } + bool operator==(const TransferAddressConstant& other_constant) const { + return constant == other_constant.constant; + } + bool operator!=(const TransferAddressConstant& other_constant) const { + return !(*this == other_constant); + } + }; + + struct TransferInvocation { + Transfer transfer; + TransferShaderKey shader_key; + TransferInvocation(const Transfer& transfer, const TransferShaderKey& shader_key) + : transfer(transfer), shader_key(shader_key) {} + bool operator<(const TransferInvocation& other_invocation) const { + // TODO(Triang3l): See if it may be better to sort by the source in the + // first place, especially when reading the same data multiple times (like + // to write the stencil bits after depth) for better read locality. + // Sort by the shader key primarily to reduce pipeline state (context) + // switches. + if (shader_key != other_invocation.shader_key) { + return shader_key < other_invocation.shader_key; + } + // Host depth render targets are changed rarely if they exist, won't save + // many binding changes, ignore them for simplicity (their existence is + // caught by the shader key change). + assert_not_null(transfer.source); + assert_not_null(other_invocation.transfer.source); + uint32_t source_index = + static_cast(transfer.source)->temporary_sort_index(); + uint32_t other_source_index = + static_cast(other_invocation.transfer.source) + ->temporary_sort_index(); + if (source_index != other_source_index) { + return source_index < other_source_index; + } + return transfer.start_tiles < other_invocation.transfer.start_tiles; + } + bool CanBeMergedIntoOneDraw(const TransferInvocation& other_invocation) const { + return shader_key == other_invocation.shader_key && + transfer.AreSourcesSame(other_invocation.transfer); + } + }; + + enum { + kHostDepthStoreRootParameterConstants, + kHostDepthStoreRootParameterSource, + kHostDepthStoreRootParameterDest, + kHostDepthStoreRootParameterCount, + }; + + union DumpPipelineKey { + uint32_t key; + struct { + xenos::MsaaSamples msaa_samples : 2; + uint32_t resource_format : 4; + // Last bit because this affects the root signature - after sorting, only + // change it at most once. Depth buffers have an additional stencil SRV. + uint32_t is_depth : 1; + }; + + DumpPipelineKey() : key(0) { static_assert_size(*this, sizeof(key)); } + + struct Hasher { + size_t operator()(const DumpPipelineKey& key) const { return std::hash{}(key.key); } + }; + bool operator==(const DumpPipelineKey& other_key) const { return key == other_key.key; } + bool operator!=(const DumpPipelineKey& other_key) const { return !(*this == other_key); } + bool operator<(const DumpPipelineKey& other_key) const { return key < other_key.key; } + + xenos::ColorRenderTargetFormat GetColorFormat() const { + assert_false(is_depth); + return xenos::ColorRenderTargetFormat(resource_format); + } + xenos::DepthRenderTargetFormat GetDepthFormat() const { + assert_true(is_depth); + return xenos::DepthRenderTargetFormat(resource_format); + } + }; + + union DumpOffsets { + uint32_t offsets; + struct { + // May be beyond the EDRAM tile count in case of EDRAM addressing + // wrapping, thus + 1 bit. + uint32_t dispatch_first_tile : xenos::kEdramBaseTilesBits + 1; + uint32_t source_base_tiles : xenos::kEdramBaseTilesBits; + }; + DumpOffsets() : offsets(0) { static_assert_size(*this, sizeof(offsets)); } + bool operator==(const DumpOffsets& other_offsets) const { + return offsets == other_offsets.offsets; + } + bool operator!=(const DumpOffsets& other_offsets) const { return !(*this == other_offsets); } + }; + + union DumpPitches { + uint32_t pitches; + struct { + // Both in tiles. + uint32_t dest_pitch : xenos::kEdramPitchTilesBits; + uint32_t source_pitch : xenos::kEdramPitchTilesBits; + }; + DumpPitches() : pitches(0) { static_assert_size(*this, sizeof(pitches)); } + bool operator==(const DumpPitches& other_pitches) const { + return pitches == other_pitches.pitches; + } + bool operator!=(const DumpPitches& other_pitches) const { return !(*this == other_pitches); } + }; + + enum DumpCbuffer : uint32_t { + kDumpCbufferOffsets, + kDumpCbufferPitches, + kDumpCbufferCount, + }; + + enum DumpRootParameter : uint32_t { + // May be changed multiple times for the same source. + kDumpRootParameterOffsets, + // One resolve may need multiple sources. + kDumpRootParameterSource, + + // May be different for different sources. + kDumpRootParameterColorPitches = kDumpRootParameterSource + 1, + // Only changed between 32bpp and 64bpp. + kDumpRootParameterColorEdram, + + kDumpRootParameterColorCount, + + // Same change frequency than the source (though currently the command + // processor can't contiguously allocate multiple descriptors with bindless, + // when such functionality is added, switch to one root signature). + kDumpRootParameterDepthStencil = kDumpRootParameterSource + 1, + kDumpRootParameterDepthPitches, + kDumpRootParameterDepthEdram, + + kDumpRootParameterDepthCount, + }; + + struct DumpInvocation { + ResolveCopyDumpRectangle rectangle; + DumpPipelineKey pipeline_key; + DumpInvocation(const ResolveCopyDumpRectangle& rectangle, const DumpPipelineKey& pipeline_key) + : rectangle(rectangle), pipeline_key(pipeline_key) {} + bool operator<(const DumpInvocation& other_invocation) const { + // Sort by the pipeline key primarily to reduce pipeline state (context) + // switches. + if (pipeline_key != other_invocation.pipeline_key) { + return pipeline_key < other_invocation.pipeline_key; + } + assert_not_null(rectangle.render_target); + uint32_t render_target_index = + static_cast(rectangle.render_target)->temporary_sort_index(); + const ResolveCopyDumpRectangle& other_rectangle = other_invocation.rectangle; + uint32_t other_render_target_index = + static_cast(other_rectangle.render_target) + ->temporary_sort_index(); + if (render_target_index != other_render_target_index) { + return render_target_index < other_render_target_index; + } + if (rectangle.row_first != other_rectangle.row_first) { + return rectangle.row_first < other_rectangle.row_first; + } + return rectangle.row_first_start < other_rectangle.row_first_start; + } + }; + + struct DirectResolvePushConstants { + draw_util::ResolveCopyShaderConstants resolve; + uint32_t source_base_tiles; + uint32_t source_pitch_tiles; + uint32_t dispatch_first_tile; + }; + + struct DirectResolvePipelineKey { + DumpPipelineKey dump_pipeline_key; + draw_util::ResolveCopyShaderIndex copy_shader; + bool draw_resolution_scaled; + + uint64_t packed() const { + return uint64_t(dump_pipeline_key.key) | (uint64_t(size_t(copy_shader)) << 32) | + (uint64_t(draw_resolution_scaled ? 1 : 0) << 40); + } + struct Hasher { + size_t operator()(const DirectResolvePipelineKey& key) const { + return std::hash{}(key.packed()); + } + }; + bool operator==(const DirectResolvePipelineKey& other_key) const { + return packed() == other_key.packed(); + } + }; + + // Returns: + // - A pointer to 1 pipeline for writing color or depth (or stencil via + // SV_StencilRef). + // - A pointer to 8 pipelines for writing stencil by discarding samples + // depending on whether they have one bit set, from 1 << 0 to 1 << 7. + // - Null if failed to create. + ID3D12PipelineState* const* GetOrCreateTransferPipelines(TransferShaderKey key); + + static TransferMode GetTransferMode(bool dest_is_stencil_bit, bool dest_is_depth, + bool source_is_depth, bool source_has_host_depth) { + assert_true(dest_is_depth || (!dest_is_stencil_bit && !source_has_host_depth)); + if (dest_is_stencil_bit) { + return source_is_depth ? TransferMode::kDepthToStencilBit : TransferMode::kColorToStencilBit; + } + if (dest_is_depth) { + if (source_is_depth) { + return source_has_host_depth ? TransferMode::kDepthAndHostDepthToDepth + : TransferMode::kDepthToDepth; + } + return source_has_host_depth ? TransferMode::kColorAndHostDepthToDepth + : TransferMode::kColorToDepth; + } + return source_is_depth ? TransferMode::kDepthToColor : TransferMode::kColorToColor; + } + + // Do ownership transfers for render targets - each render target / vector may + // be null / empty in case there's nothing to do for them. + // resolve_clear_rectangle is expected to be provided by + // PrepareHostRenderTargetsResolveClear which should do all the needed size + // bound checks. + void PerformTransfersAndResolveClears( + uint32_t render_target_count, RenderTarget* const* render_targets, + const std::vector* render_target_transfers, + const uint64_t* render_target_resolve_clear_values = nullptr, + const Transfer::Rectangle* resolve_clear_rectangle = nullptr); + + // Accepts an array of (1 + xenos::kMaxColorRenderTargets) render targets, + // first depth, then color. + void SetCommandListRenderTargets(RenderTarget* const* depth_and_color_render_targets); + + ID3D12PipelineState* GetOrCreateDumpPipeline(DumpPipelineKey key); + ID3D12PipelineState* GetOrCreateDirectResolvePipeline(DirectResolvePipelineKey key); + bool TryResolveCopyDirectly(const draw_util::ResolveInfo& resolve_info, + draw_util::ResolveCopyShaderIndex copy_shader, + bool draw_resolution_scaled); + + // Writes contents of host render targets within rectangles from + // ResolveInfo::GetCopyEdramTileSpan to edram_buffer_. + bool DumpRenderTargets(uint32_t dump_base, uint32_t dump_row_length_used, uint32_t dump_rows, + uint32_t dump_pitch); + + bool use_stencil_reference_output_ = false; + + bool gamma_render_target_as_unorm16_ = false; + + bool depth_float24_round_ = false; + bool depth_float24_convert_in_pixel_shader_ = false; + + bool msaa_2x_supported_ = false; + + std::shared_ptr descriptor_pool_color_; + std::shared_ptr descriptor_pool_depth_; + std::shared_ptr descriptor_pool_srv_; + ui::d3d12::D3D12CpuDescriptorPool::Descriptor null_rtv_descriptor_ss_; + ui::d3d12::D3D12CpuDescriptorPool::Descriptor null_rtv_descriptor_ms_; + + // Possible tile ownership transfer paths: + // - To color: + // - From color: 1 SRV (color). + // - From depth: 2 SRVs (depth, stencil). + // - To depth / stencil (with SV_StencilRef): + // - From color: 1 SRV (color). + // - From depth: 2 SRVs (depth, stencil). + // - From color and float32 depth: 2 SRVs (color with stencil, depth). + // - Different depth buffer: depth SRV is a texture. + // - Same depth buffer: depth SRV is a buffer (pre-copied). + // - To depth (no SV_StencilRef): + // - From color: 1 SRV (color). + // - From depth: 1 SRV (depth). + // - From color and float32 depth: 2 SRVs (color, depth). + // - Different depth buffer: depth SRV is a texture. + // - Same depth buffer: depth SRV is a buffer (pre-copied). + // - To stencil (no SV_StencilRef): + // - From color: 1 SRV (color). + // - From depth: 1 SRV (stencil). + + const RenderTarget* const* + current_command_list_render_targets_[1 + xenos::kMaxColorRenderTargets]; + bool are_current_command_list_render_targets_valid_ = false; + + // Temporary storage for descriptors used in PerformTransfersAndResolveClears + // and DumpRenderTargets. + std::vector current_temporary_descriptors_cpu_; + std::vector current_temporary_descriptors_gpu_; + + ID3D12RootSignature* host_depth_store_root_signature_ = nullptr; + ID3D12PipelineState* host_depth_store_pipelines_[size_t(xenos::MsaaSamples::k4X) + 1] = {}; + + std::unique_ptr transfer_vertex_buffer_pool_; + + ID3D12RootSignature* transfer_root_signatures_[size_t(TransferRootSignatureIndex::kCount)] = {}; + std::unordered_map + transfer_pipelines_; + std::unordered_map, + TransferShaderKey::Hasher> + transfer_stencil_bit_pipelines_; + + // Temporary storage for PerformTransfersAndResolveClears. + std::vector current_transfer_invocations_; + + // Temporary storage for DumpRenderTargets. + std::vector dump_rectangles_; + std::vector dump_invocations_; + std::vector direct_resolve_dispatches_; + + ID3D12RootSignature* dump_root_signature_color_ = nullptr; + ID3D12RootSignature* dump_root_signature_depth_ = nullptr; + // Compute pipelines for copying host render target contents to the EDRAM + // buffer. May be null if failed to create. + std::unordered_map + dump_pipelines_; + ID3D12RootSignature* direct_resolve_root_signature_color_ = nullptr; + ID3D12RootSignature* direct_resolve_root_signature_depth_ = nullptr; + std::unordered_map + direct_resolve_pipelines_; + uint64_t direct_resolve_attempt_count_ = 0; + uint64_t direct_resolve_success_count_ = 0; + uint64_t direct_resolve_fallback_count_ = 0; + + // Parameter 0 - 2 root constants (red, green). + ID3D12RootSignature* uint32_rtv_clear_root_signature_ = nullptr; + // [32 or 32_32][MSAA samples]. + ID3D12PipelineState* uint32_rtv_clear_pipelines_[2][size_t(xenos::MsaaSamples::k4X) + 1] = {}; + + std::vector clear_transfers_[2]; + + // Temporary storage for DXBC building. + std::vector built_shader_; + + // For rasterizer-ordered view (pixel shader interlock). + + ID3D12RootSignature* resolve_rov_clear_root_signature_ = nullptr; + // Clearing 32bpp color or depth. + ID3D12PipelineState* resolve_rov_clear_32bpp_pipeline_ = nullptr; + // Clearing 64bpp color. + ID3D12PipelineState* resolve_rov_clear_64bpp_pipeline_ = nullptr; +}; + +} // namespace rex::graphics::d3d12 diff --git a/include/rex/graphics/d3d12/shader.h b/include/rex/graphics/d3d12/shader.h new file mode 100644 index 0000000..eb48eff --- /dev/null +++ b/include/rex/graphics/d3d12/shader.h @@ -0,0 +1,59 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include +#include + +namespace rex::graphics::d3d12 { + +class D3D12Shader : public DxbcShader { + public: + class D3D12Translation : public DxbcTranslation { + public: + D3D12Translation(D3D12Shader& shader, uint64_t modification) + : DxbcTranslation(shader, modification) {} + + void DisassembleDxbcAndDxil(const ui::d3d12::D3D12Provider& provider, bool disassemble_dxbc, + IDxbcConverter* dxbc_converter = nullptr, + IDxcUtils* dxc_utils = nullptr, + IDxcCompiler* dxc_compiler = nullptr); + }; + + D3D12Shader(xenos::ShaderType shader_type, uint64_t ucode_data_hash, const uint32_t* ucode_dwords, + size_t ucode_dword_count, std::endian ucode_source_endian = std::endian::big); + + // For owning subsystem like the pipeline cache, accessors for unique + // identifiers (used instead of hashes to make sure collisions can't happen) + // of binding layouts used by the shader, for invalidation if a shader with an + // incompatible layout was bound. + size_t GetTextureBindingLayoutUserUID() const { return texture_binding_layout_user_uid_; } + size_t GetSamplerBindingLayoutUserUID() const { return sampler_binding_layout_user_uid_; } + // Modifications of the same shader can be translated on different threads. + // The "set" function must only be called if "enter" returned true - these are + // set up only once. + bool EnterBindingLayoutUserUIDSetup() { return !binding_layout_user_uids_set_up_.test_and_set(); } + void SetTextureBindingLayoutUserUID(size_t uid) { texture_binding_layout_user_uid_ = uid; } + void SetSamplerBindingLayoutUserUID(size_t uid) { sampler_binding_layout_user_uid_ = uid; } + + protected: + Translation* CreateTranslationInstance(uint64_t modification) override; + + private: + std::atomic_flag binding_layout_user_uids_set_up_ = ATOMIC_FLAG_INIT; + size_t texture_binding_layout_user_uid_ = 0; + size_t sampler_binding_layout_user_uid_ = 0; +}; + +} // namespace rex::graphics::d3d12 diff --git a/include/rex/graphics/d3d12/shared_memory.h b/include/rex/graphics/d3d12/shared_memory.h new file mode 100644 index 0000000..40507d8 --- /dev/null +++ b/include/rex/graphics/d3d12/shared_memory.h @@ -0,0 +1,126 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace rex::graphics::d3d12 { + +class D3D12CommandProcessor; + +class D3D12SharedMemory : public SharedMemory { + public: + D3D12SharedMemory(D3D12CommandProcessor& command_processor, memory::Memory& memory, + TraceWriter& trace_writer); + ~D3D12SharedMemory() override; + + bool Initialize(); + void Shutdown(bool from_destructor = false); + void ClearCache() override; + + ID3D12Resource* GetBuffer() const { return buffer_; } + D3D12_GPU_VIRTUAL_ADDRESS GetGPUAddress() const { return buffer_gpu_address_; } + + void CompletedSubmissionUpdated(); + void BeginSubmission(); + + // RequestRange may transition the buffer to copy destination - call it before + // UseForReading or UseForWriting. + + // Makes the buffer usable for vertices, indices and texture untiling. + void UseForReading() { + // Vertex fetch is also allowed in pixel shaders. + CommitUAVWritesAndTransitionBuffer(D3D12_RESOURCE_STATE_INDEX_BUFFER | + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + } + // Makes the buffer usable for texture tiling after a resolve. + void UseForWriting() { + CommitUAVWritesAndTransitionBuffer(D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + } + // Makes the buffer usable as a source for copy commands. + void UseAsCopySource() { CommitUAVWritesAndTransitionBuffer(D3D12_RESOURCE_STATE_COPY_SOURCE); } + // Must be called when doing draws/dispatches modifying data within the shared + // memory buffer as a UAV, to make sure that when UseForWriting is called the + // next time, a UAV barrier will be done, and subsequent overlapping UAV + // writes and reads are ordered. + void MarkUAVWritesCommitNeeded() { + if (buffer_state_ == D3D12_RESOURCE_STATE_UNORDERED_ACCESS) { + buffer_uav_writes_commit_needed_ = true; + } + } + + void WriteRawSRVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle); + void WriteRawUAVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle); + // Due to the D3D12_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP limitation, the + // smallest supported formats are 32-bit. + void WriteUintPow2SRVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle, + uint32_t element_size_bytes_pow2); + void WriteUintPow2UAVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle, + uint32_t element_size_bytes_pow2); + + // Returns true if any downloads were submitted to the command processor. + bool InitializeTraceSubmitDownloads(); + void InitializeTraceCompleteDownloads(); + + protected: + bool AllocateSparseHostGpuMemoryRange(uint32_t offset_allocations, + uint32_t length_allocations) override; + + bool UploadRanges(const std::vector>& upload_page_ranges) override; + + private: + D3D12CommandProcessor& command_processor_; + TraceWriter& trace_writer_; + + // The 512 MB tiled buffer. + ID3D12Resource* buffer_ = nullptr; + D3D12_GPU_VIRTUAL_ADDRESS buffer_gpu_address_ = 0; + std::vector buffer_tiled_heaps_; + D3D12_RESOURCE_STATES buffer_state_ = D3D12_RESOURCE_STATE_COPY_DEST; + bool buffer_uav_writes_commit_needed_ = false; + void CommitUAVWritesAndTransitionBuffer(D3D12_RESOURCE_STATES new_state); + + // Non-shader-visible buffer descriptor heap for faster binding (via copying + // rather than creation). + enum class BufferDescriptorIndex : uint32_t { + kRawSRV, + kR32UintSRV, + kR32G32UintSRV, + kR32G32B32A32UintSRV, + kRawUAV, + kR32UintUAV, + kR32G32UintUAV, + kR32G32B32A32UintUAV, + + kCount, + }; + ID3D12DescriptorHeap* buffer_descriptor_heap_ = nullptr; + D3D12_CPU_DESCRIPTOR_HANDLE buffer_descriptor_heap_start_; + + std::unique_ptr upload_buffer_pool_; + + // Created temporarily, only for downloading. + ID3D12Resource* trace_download_buffer_ = nullptr; + void ResetTraceDownload(); +}; + +} // namespace rex::graphics::d3d12 diff --git a/include/rex/graphics/d3d12/texture_cache.h b/include/rex/graphics/d3d12/texture_cache.h new file mode 100644 index 0000000..4d845c7 --- /dev/null +++ b/include/rex/graphics/d3d12/texture_cache.h @@ -0,0 +1,544 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::graphics::d3d12 { + +class D3D12CommandProcessor; + +class D3D12TextureCache final : public TextureCache { + public: + // Keys that can be stored for checking validity whether descriptors for host + // shader bindings are up to date. + struct TextureSRVKey { + TextureKey key; + uint32_t host_swizzle; + uint8_t swizzled_signs; + }; + + // Sampler parameters that can be directly converted to a host sampler or used + // for binding checking validity whether samplers are up to date. + union SamplerParameters { + uint32_t value; + struct { + xenos::ClampMode clamp_x : 3; // 3 + xenos::ClampMode clamp_y : 3; // 6 + xenos::ClampMode clamp_z : 3; // 9 + xenos::BorderColor border_color : 2; // 11 + // For anisotropic, these are true. + uint32_t mag_linear : 1; // 12 + uint32_t min_linear : 1; // 13 + uint32_t mip_linear : 1; // 14 + xenos::AnisoFilter aniso_filter : 3; // 17 + uint32_t mip_min_level : 4; // 21 + uint32_t mip_base_map : 1; // 22 + // Maximum mip level is in the texture resource itself, but mip_base_map + // can be used to limit fetching to mip_min_level. + }; + + SamplerParameters() : value(0) { static_assert_size(*this, sizeof(value)); } + bool operator==(const SamplerParameters& parameters) const { return value == parameters.value; } + bool operator!=(const SamplerParameters& parameters) const { return value != parameters.value; } + }; + + static std::unique_ptr Create(const RegisterFile& register_file, + D3D12SharedMemory& shared_memory, + uint32_t draw_resolution_scale_x, + uint32_t draw_resolution_scale_y, + D3D12CommandProcessor& command_processor, + bool bindless_resources_used) { + std::unique_ptr texture_cache( + new D3D12TextureCache(register_file, shared_memory, draw_resolution_scale_x, + draw_resolution_scale_y, command_processor, bindless_resources_used)); + if (!texture_cache->Initialize()) { + return nullptr; + } + return std::move(texture_cache); + } + + ~D3D12TextureCache(); + + void ClearCache() override; + + void BeginSubmission(uint64_t new_submission_index) override; + void BeginFrame() override; + void EndFrame(); + + // Must be called within a submission - creates and untiles textures needed by + // shaders and puts them in the SRV state. This may bind compute pipelines + // (notifying the command processor about that), so this must be called before + // binding the actual drawing pipeline. + void RequestTextures(uint32_t used_texture_mask) override; + + // Returns whether texture SRV keys stored externally are still valid for the + // current bindings and host shader binding layout. Both keys and + // host_shader_bindings must have host_shader_binding_count elements + // (otherwise they are incompatible - like if this function returned false). + bool AreActiveTextureSRVKeysUpToDate(const TextureSRVKey* keys, + const D3D12Shader::TextureBinding* host_shader_bindings, + size_t host_shader_binding_count) const; + // Exports the current binding data to texture SRV keys so they can be stored + // for checking whether subsequent draw calls can keep using the same + // bindings. Write host_shader_binding_count keys. + void WriteActiveTextureSRVKeys(TextureSRVKey* keys, + const D3D12Shader::TextureBinding* host_shader_bindings, + size_t host_shader_binding_count) const; + void WriteActiveTextureBindfulSRV(const D3D12Shader::TextureBinding& host_shader_binding, + D3D12_CPU_DESCRIPTOR_HANDLE handle); + uint32_t GetActiveTextureBindlessSRVIndex(const D3D12Shader::TextureBinding& host_shader_binding); + + SamplerParameters GetSamplerParameters(const D3D12Shader::SamplerBinding& binding) const; + void WriteSampler(SamplerParameters parameters, D3D12_CPU_DESCRIPTOR_HANDLE handle) const; + + // Returns whether the actual scale is not smaller than the requested one. + static bool ClampDrawResolutionScaleToMaxSupported(uint32_t& scale_x, uint32_t& scale_y, + const ui::d3d12::D3D12Provider& provider); + // Ensures the tiles backing the range in the buffers are allocated. + bool EnsureScaledResolveMemoryCommitted(uint32_t start_unscaled, uint32_t length_unscaled, + uint32_t length_scaled_alignment_log2 = 0) override; + // Makes the specified range of up to 1-2 GB currently accessible on the GPU. + // One draw call can access only at most one range - the same memory is + // accessible through different buffers based on the range needed, so aliasing + // barriers are required. + bool MakeScaledResolveRangeCurrent(uint32_t start_unscaled, uint32_t length_unscaled, + uint32_t length_scaled_alignment_log2 = 0); + // These functions create a view of the range specified in the last successful + // MakeScaledResolveRangeCurrent call because that function must be called + // before this. + void CreateCurrentScaledResolveRangeUintPow2SRV(D3D12_CPU_DESCRIPTOR_HANDLE handle, + uint32_t element_size_bytes_pow2); + void CreateCurrentScaledResolveRangeUintPow2UAV(D3D12_CPU_DESCRIPTOR_HANDLE handle, + uint32_t element_size_bytes_pow2); + void TransitionCurrentScaledResolveRange(D3D12_RESOURCE_STATES new_state); + uint64_t GetCurrentScaledResolveRangeStartScaled() const { + return scaled_resolve_current_range_start_scaled_; + } + uint64_t GetCurrentScaledResolveRangeLengthScaled() const { + return scaled_resolve_current_range_length_scaled_; + } + ID3D12Resource* GetCurrentScaledResolveBufferResource() { + return GetCurrentScaledResolveBuffer().resource(); + } + size_t GetCurrentScaledResolveBufferIndexPublic() const { + return GetCurrentScaledResolveBufferIndex(); + } + void MarkCurrentScaledResolveRangeUAVWritesCommitNeeded() { + assert_true(IsDrawResolutionScaled()); + GetCurrentScaledResolveBuffer().SetUAVBarrierPending(); + } + + // Returns the ID3D12Resource of the front buffer texture (in + // NON_PIXEL_SHADER_RESOURCE state), or nullptr in case of failure, and writes + // the description of its SRV. May call LoadTextureData, so the same + // restrictions (such as about descriptor heap change possibility) apply. + ID3D12Resource* RequestSwapTexture(D3D12_SHADER_RESOURCE_VIEW_DESC& srv_desc_out, + xenos::TextureFormat& format_out, + uint32_t* width_unscaled_out = nullptr, + uint32_t* height_unscaled_out = nullptr); + + protected: + bool IsSignedVersionSeparateForFormat(TextureKey key) const override; + bool IsScaledResolveSupportedForFormat(TextureKey key) const override; + uint32_t GetHostFormatSwizzle(TextureKey key) const override; + + uint32_t GetMaxHostTextureWidthHeight(xenos::DataDimension dimension) const override; + uint32_t GetMaxHostTextureDepthOrArraySize(xenos::DataDimension dimension) const override; + + std::unique_ptr CreateTexture(TextureKey key) override; + + // This binds pipelines, allocates descriptors, and copies! + bool LoadTextureDataFromResidentMemoryImpl(Texture& texture, bool load_base, + bool load_mips) override; + + void UpdateTextureBindingsImpl(uint32_t fetch_constant_mask) override; + + private: + static constexpr uint32_t kLoadGuestXThreadsPerGroupLog2 = 2; + static constexpr uint32_t kLoadGuestYBlocksPerGroupLog2 = 5; + + struct HostFormat { + // Format info for the regular case. + // DXGI format (typeless when different signedness or number representation + // is used) for the texture resource. + DXGI_FORMAT dxgi_format_resource; + // DXGI format for unsigned normalized or unsigned/signed float SRV. + DXGI_FORMAT dxgi_format_unsigned; + // The regular load shader, used when special load shaders (like + // signed-specific or decompressing) aren't needed. + LoadShaderIndex load_shader; + // DXGI format for signed normalized or unsigned/signed float SRV. + DXGI_FORMAT dxgi_format_signed; + // If the signed version needs a different bit representation on the host, + // this is the load shader for the signed version. Otherwise the regular + // load_shader will be used for the signed version, and a single copy will + // be created if both unsigned and signed are used. + LoadShaderIndex load_shader_signed; + + // Do NOT add integer DXGI formats to this - they are not filterable, can + // only be read with Load, not Sample! If any game is seen using num_format + // 1 for fixed-point formats (for floating-point, it's normally set to 1 + // though), add a constant buffer containing multipliers for the + // textures and multiplication to the tfetch implementation. + + // Whether the DXGI format, if not uncompressing the texture, consists of + // blocks, thus copy regions must be aligned to block size (assuming it's + // the same as the guest block size). + bool is_block_compressed; + // Uncompression info for when the regular host format for this texture is + // block-compressed, but the size is not block-aligned, and thus such + // texture cannot be created in Direct3D on PC and needs decompression, + // however, such textures are common, for instance, in 4D5307E6. This only + // supports unsigned normalized formats - let's hope GPUSIGN_SIGNED was not + // used for DXN and DXT5A. + DXGI_FORMAT dxgi_format_uncompressed; + LoadShaderIndex load_shader_decompress; + + // Mapping of Xenos swizzle components to DXGI format components. + uint32_t swizzle; + }; + + class D3D12Texture final : public Texture { + public: + union SRVDescriptorKey { + uint32_t key; + struct { + uint32_t is_signed : 1; + uint32_t host_swizzle : 12; + uint32_t dimension : 2; + }; + + SRVDescriptorKey() : key(0) { static_assert_size(*this, sizeof(key)); } + + struct Hasher { + size_t operator()(const SRVDescriptorKey& key) const { + return std::hash{}(key.key); + } + }; + bool operator==(const SRVDescriptorKey& other_key) const { return key == other_key.key; } + bool operator!=(const SRVDescriptorKey& other_key) const { return !(*this == other_key); } + }; + + ID3D12Resource* GetOrCreate3DAs2DResource(D3D12_RESOURCE_STATES end_state); + + explicit D3D12Texture(D3D12TextureCache& texture_cache, const TextureKey& key, + ID3D12Resource* resource, D3D12_RESOURCE_STATES resource_state, + bool track_usage = true); + ~D3D12Texture(); + + ID3D12Resource* resource() const { return resource_.Get(); } + + D3D12_RESOURCE_STATES SetResourceState(D3D12_RESOURCE_STATES new_state) { + D3D12_RESOURCE_STATES old_state = resource_state_; + resource_state_ = new_state; + return old_state; + } + + uint32_t GetSRVDescriptorIndex(SRVDescriptorKey descriptor_key) const { + auto it = srv_descriptors_.find(descriptor_key); + return it != srv_descriptors_.cend() ? it->second : UINT32_MAX; + } + + void AddSRVDescriptorIndex(SRVDescriptorKey descriptor_key, uint32_t descriptor_index) { + srv_descriptors_.emplace(descriptor_key, descriptor_index); + } + + private: + Microsoft::WRL::ComPtr resource_; + D3D12_RESOURCE_STATES resource_state_; + std::unique_ptr texture_3d_as_2d_; + + // For bindful - indices in the non-shader-visible descriptor cache for + // copying to the shader-visible heap (much faster than recreating, which, + // according to profiling, was often a bottleneck in many games). + // For bindless - indices in the global shader-visible descriptor heap. + std::unordered_map srv_descriptors_; + }; + + static constexpr uint32_t kSRVDescriptorCachePageSize = 65536; + + struct SRVDescriptorCachePage { + public: + explicit SRVDescriptorCachePage(ID3D12DescriptorHeap* heap) + : heap_(heap), heap_start_(heap->GetCPUDescriptorHandleForHeapStart()) {} + SRVDescriptorCachePage(const SRVDescriptorCachePage& page) = delete; + SRVDescriptorCachePage& operator=(const SRVDescriptorCachePage& page) = delete; + SRVDescriptorCachePage(SRVDescriptorCachePage&& page) { + std::swap(heap_, page.heap_); + std::swap(heap_start_, page.heap_start_); + } + SRVDescriptorCachePage& operator=(SRVDescriptorCachePage&& page) { + std::swap(heap_, page.heap_); + std::swap(heap_start_, page.heap_start_); + return *this; + } + + ID3D12DescriptorHeap* heap() const { return heap_.Get(); } + D3D12_CPU_DESCRIPTOR_HANDLE heap_start() const { return heap_start_; } + + private: + Microsoft::WRL::ComPtr heap_; + D3D12_CPU_DESCRIPTOR_HANDLE heap_start_; + }; + + struct D3D12TextureBinding { + // Descriptor indices of texture and texture_signed of the respective + // TextureBinding returned from FindOrCreateTextureDescriptor. + uint32_t descriptor_index; + uint32_t descriptor_index_signed; + + D3D12TextureBinding() { Reset(); } + + void Reset() { + descriptor_index = UINT32_MAX; + descriptor_index_signed = UINT32_MAX; + } + }; + + class ScaledResolveVirtualBuffer { + public: + explicit ScaledResolveVirtualBuffer(ID3D12Resource* resource, + D3D12_RESOURCE_STATES resource_state) + : resource_(resource), resource_state_(resource_state) {} + ID3D12Resource* resource() const { return resource_.Get(); } + D3D12_RESOURCE_STATES SetResourceState(D3D12_RESOURCE_STATES new_state) { + D3D12_RESOURCE_STATES old_state = resource_state_; + if (old_state == D3D12_RESOURCE_STATE_UNORDERED_ACCESS) { + uav_barrier_pending_ = false; + } + resource_state_ = new_state; + return old_state; + } + // After writing through a UAV. + void SetUAVBarrierPending() { + if (resource_state_ == D3D12_RESOURCE_STATE_UNORDERED_ACCESS) { + uav_barrier_pending_ = true; + } + } + // After an aliasing barrier (which is even stronger than an UAV barrier). + void ClearUAVBarrierPending() { uav_barrier_pending_ = false; } + + private: + Microsoft::WRL::ComPtr resource_; + D3D12_RESOURCE_STATES resource_state_; + bool uav_barrier_pending_ = false; + }; + + explicit D3D12TextureCache(const RegisterFile& register_file, D3D12SharedMemory& shared_memory, + uint32_t draw_resolution_scale_x, uint32_t draw_resolution_scale_y, + D3D12CommandProcessor& command_processor, + bool bindless_resources_used); + + bool Initialize(); + + // Whether decompression is needed on the host (Direct3D only allows creation + // of block-compressed textures with 4x4-aligned dimensions on PC). + bool IsDecompressionNeeded(xenos::TextureFormat format, uint32_t width, uint32_t height) const; + DXGI_FORMAT GetDXGIResourceFormat(xenos::TextureFormat format, uint32_t width, + uint32_t height) const { + const HostFormat& host_format = host_formats_[uint32_t(format)]; + return IsDecompressionNeeded(format, width, height) ? host_format.dxgi_format_uncompressed + : host_format.dxgi_format_resource; + } + DXGI_FORMAT GetDXGIResourceFormat(TextureKey key) const { + return GetDXGIResourceFormat(key.format, key.GetWidth(), key.GetHeight()); + } + DXGI_FORMAT GetDXGIUnormFormat(xenos::TextureFormat format, uint32_t width, + uint32_t height) const { + const HostFormat& host_format = host_formats_[uint32_t(format)]; + return IsDecompressionNeeded(format, width, height) ? host_format.dxgi_format_uncompressed + : host_format.dxgi_format_unsigned; + } + DXGI_FORMAT GetDXGIUnormFormat(TextureKey key) const { + return GetDXGIUnormFormat(key.format, key.GetWidth(), key.GetHeight()); + } + + LoadShaderIndex GetLoadShaderIndex(TextureKey key) const; + + static constexpr bool AreDimensionsCompatible(xenos::FetchOpDimension binding_dimension, + xenos::DataDimension resource_dimension) { + switch (binding_dimension) { + case xenos::FetchOpDimension::k1D: + case xenos::FetchOpDimension::k2D: + return resource_dimension == xenos::DataDimension::k1D || + resource_dimension == xenos::DataDimension::k2DOrStacked || + resource_dimension == xenos::DataDimension::k3D; + case xenos::FetchOpDimension::k3DOrStacked: + return resource_dimension == xenos::DataDimension::k3D; + case xenos::FetchOpDimension::kCube: + return resource_dimension == xenos::DataDimension::kCube; + default: + return false; + } + } + + // Returns the index of an existing of a newly created non-shader-visible + // cached (for bindful) or a shader-visible global (for bindless) descriptor, + // or UINT32_MAX if failed to create. + uint32_t FindOrCreateTextureDescriptor(D3D12Texture& texture, xenos::DataDimension dimension, + bool is_signed, uint32_t host_swizzle); + void ReleaseTextureDescriptor(uint32_t descriptor_index); + D3D12_CPU_DESCRIPTOR_HANDLE GetTextureDescriptorCPUHandle(uint32_t descriptor_index) const; + + size_t GetScaledResolveBufferCount() const { + assert_true(IsDrawResolutionScaled()); + // Make sure any range up to 1 GB is accessible through 1 or 2 buffers. + // 2x2 scale buffers - just one 2 GB buffer for all 2 GB. + // 3x3 scale buffers - 4 buffers: + // +0.0 +0.5 +1.0 +1.5 +2.0 +2.5 +3.0 +3.5 +4.0 +4.5 + // |___________________|___________________| + // |___________________|______________| + // Buffer N has an offset of N * 1 GB in the scaled resolve address space. + // The logic is: + // - 2 GB can be accessed through a [0 GB ... 2 GB) buffer - only need one. + // - 2.1 GB needs [0 GB ... 2 GB) and [1 GB ... 2.1 GB) - two buffers. + // - 3 GB needs [0 GB ... 2 GB) and [1 GB ... 3 GB) - two buffers. + // - 3.1 GB needs [0 GB ... 2 GB), [1 GB ... 3 GB) and [2 GB ... 3.1 GB) - + // three buffers. + uint64_t address_space_size = uint64_t(SharedMemory::kBufferSize) * + (draw_resolution_scale_x() * draw_resolution_scale_y()); + return size_t((address_space_size - 1) >> 30); + } + // Returns indices of two scaled resolve virtual buffers that the location in + // memory may be accessible through. May be the same if it's a location near + // the beginning or the end of the address represented only by one buffer. + std::array GetPossibleScaledResolveBufferIndices(uint64_t address_scaled) const { + assert_true(IsDrawResolutionScaled()); + size_t address_gb = size_t(address_scaled >> 30); + size_t max_index = GetScaledResolveBufferCount() - 1; + // In different cases for 3x3: + // +0.0 +0.5 +1.0 +1.5 +2.0 +2.5 +3.0 +3.5 +4.0 +4.5 + // |12________2________|1_________2________| + // |1_________2________|1_________12__| + return std::array{std::min(address_gb, max_index), + std::min(std::max(address_gb, size_t(1)) - size_t(1), max_index)}; + } + // The index is also the gigabyte offset of the buffer from the start of the + // scaled physical memory address space. + size_t GetCurrentScaledResolveBufferIndex() const { + return scaled_resolve_1gb_buffer_indices_[scaled_resolve_current_range_start_scaled_ >> 30]; + } + ScaledResolveVirtualBuffer& GetCurrentScaledResolveBuffer() { + ScaledResolveVirtualBuffer* scaled_resolve_buffer = + scaled_resolve_2gb_buffers_[GetCurrentScaledResolveBufferIndex()].get(); + assert_not_null(scaled_resolve_buffer); + return *scaled_resolve_buffer; + } + + xenos::ClampMode NormalizeClampMode(xenos::ClampMode clamp_mode) const; + + static const HostFormat host_formats_[64]; + + D3D12CommandProcessor& command_processor_; + bool bindless_resources_used_; + + Microsoft::WRL::ComPtr load_root_signature_; + std::array, kLoadShaderCount> load_pipelines_; + // Load pipelines for resolution-scaled resolve targets. + std::array, kLoadShaderCount> load_pipelines_scaled_; + + std::vector srv_descriptor_cache_; + uint32_t srv_descriptor_cache_allocated_; + // Indices of cached descriptors used by deleted textures, for reuse. + std::vector srv_descriptor_cache_free_; + + enum class NullSRVDescriptorIndex { + k2DArray, + k3D, + kCube, + + kCount, + }; + // Contains null SRV descriptors of dimensions from NullSRVDescriptorIndex. + // For copying, not shader-visible. + Microsoft::WRL::ComPtr null_srv_descriptor_heap_; + D3D12_CPU_DESCRIPTOR_HANDLE null_srv_descriptor_heap_start_; + + std::array d3d12_texture_bindings_; + + // Unsupported texture formats used during this frame (for research and + // testing). + enum : uint8_t { + kUnsupportedResourceBit = 1, + kUnsupportedUnormBit = kUnsupportedResourceBit << 1, + kUnsupportedSnormBit = kUnsupportedUnormBit << 1, + }; + uint8_t unsupported_format_features_used_[64]; + + // The tiled buffer for resolved data with resolution scaling. + // Because on Direct3D 12 (at least on Windows 10 2004) typed SRV or UAV + // creation fails for offsets above 4 GB, a single tiled 4.5 GB buffer can't + // be used for 3x3 resolution scaling. + // Instead, "sliding window" buffers allowing to access a single range of up + // to 1 GB (or up to 2 GB, depending on the low bits) at any moment are used. + // Parts of 4.5 GB address space can be accessed through 2 GB buffers as: + // +0.0 +0.5 +1.0 +1.5 +2.0 +2.5 +3.0 +3.5 +4.0 +4.5 + // |___________________|___________________| or + // |___________________|______________| + // (2 GB is also the amount of scaled physical memory with 2x resolution + // scale, and older Intel GPUs, while support tiled resources, only support 31 + // virtual address bits per resource). + // Index is first gigabyte. Only including buffers containing over 1 GB + // (because otherwise the data will be fully contained in another). + // Size is calculated the same as in GetScaledResolveBufferCount. + std::array, + (uint64_t(SharedMemory::kBufferSize) * + (kMaxDrawResolutionScaleAlongAxis * kMaxDrawResolutionScaleAlongAxis) - + 1) / + (UINT32_C(1) << 30)> + scaled_resolve_2gb_buffers_; + // Not very big heaps (16 MB) because they are needed pretty sparsely. One + // 2x-scaled 1280x720x32bpp texture is slighly bigger than 14 MB. + static constexpr uint32_t kScaledResolveHeapSizeLog2 = 24; + static constexpr uint32_t kScaledResolveHeapSize = uint32_t(1) << kScaledResolveHeapSizeLog2; + static_assert((kScaledResolveHeapSize % D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES) == 0, + "Scaled resolve heap size must be a multiple of Direct3D tile size"); + static_assert(kScaledResolveHeapSizeLog2 <= SharedMemory::kBufferSizeLog2, + "Scaled resolve heaps are assumed to be wholly mappable irrespective of " + "resolution scale, never truncated, for example, if the scaled resolve " + "address space is 4.5 GB, but the heap size is 1 GB"); + static_assert(kScaledResolveHeapSizeLog2 <= 30, + "Scaled resolve heaps are assumed to only be wholly mappable to up to " + "two 2 GB buffers"); + // Resident portions of the tiled buffer. + std::vector> scaled_resolve_heaps_; + // Number of currently resident portions of the tiled buffer, for profiling. + uint32_t scaled_resolve_heap_count_ = 0; + // Current scaled resolve state. + // For aliasing barrier placement, last owning buffer index for each of 1 GB. + size_t scaled_resolve_1gb_buffer_indices_[(uint64_t(SharedMemory::kBufferSize) * + kMaxDrawResolutionScaleAlongAxis * + kMaxDrawResolutionScaleAlongAxis + + ((uint32_t(1) << 30) - 1)) >> + 30]; + // Range used in the last successful MakeScaledResolveRangeCurrent call. + uint64_t scaled_resolve_current_range_start_scaled_; + uint64_t scaled_resolve_current_range_length_scaled_; +}; + +} // namespace rex::graphics::d3d12 diff --git a/include/rex/graphics/flags.h b/include/rex/graphics/flags.h new file mode 100644 index 0000000..e0679b8 --- /dev/null +++ b/include/rex/graphics/flags.h @@ -0,0 +1,113 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +// GPU Core +REXCVAR_DECLARE(bool, vsync); +REXCVAR_DECLARE(bool, clear_memory_page_state); +REXCVAR_DECLARE(bool, half_pixel_offset); +REXCVAR_DECLARE(bool, async_shader_compilation); +REXCVAR_DECLARE(int32_t, video_mode_width); +REXCVAR_DECLARE(int32_t, video_mode_height); +REXCVAR_DECLARE(double, video_mode_refresh_rate); +REXCVAR_DECLARE(std::string, resolution); + +// GPU Resolution / Readback / Queries +REXCVAR_DECLARE(int32_t, resolution_scale); +REXCVAR_DECLARE(int32_t, draw_resolution_scale_x); +REXCVAR_DECLARE(int32_t, draw_resolution_scale_y); +REXCVAR_DECLARE(bool, resolve_resolution_scale_fill_half_pixel_offset); +REXCVAR_DECLARE(bool, draw_resolution_scaled_texture_offsets); +REXCVAR_DECLARE(std::string, readback_resolve); +REXCVAR_DECLARE(bool, readback_resolve_half_pixel_offset); +REXCVAR_DECLARE(bool, readback_memexport); +REXCVAR_DECLARE(bool, readback_memexport_fast); +REXCVAR_DECLARE(bool, occlusion_query_enable); +REXCVAR_DECLARE(int32_t, query_occlusion_fake_sample_count); + +// GPU Depth / Render Target Behavior +REXCVAR_DECLARE(bool, depth_float24_round); +REXCVAR_DECLARE(bool, depth_float24_convert_in_pixel_shader); +REXCVAR_DECLARE(bool, depth_transfer_not_equal_test); +REXCVAR_DECLARE(bool, native_stencil_value_output); +REXCVAR_DECLARE(bool, native_stencil_value_output_d3d12_intel); +REXCVAR_DECLARE(bool, gamma_render_target_as_unorm16); +REXCVAR_DECLARE(bool, native_2x_msaa); +REXCVAR_DECLARE(bool, snorm16_render_target_full_range); +REXCVAR_DECLARE(bool, mrt_edram_used_range_clamp_to_min); +REXCVAR_DECLARE(bool, direct_host_resolve); + +// GPU Textures +REXCVAR_DECLARE(bool, gpu_allow_invalid_fetch_constants); +REXCVAR_DECLARE(bool, gpu_3d_to_2d_texture); +REXCVAR_DECLARE(int32_t, anisotropic_override); +REXCVAR_DECLARE(int32_t, texture_cache_memory_limit_render_to_texture); +REXCVAR_DECLARE(int32_t, texture_cache_memory_limit_soft); +REXCVAR_DECLARE(int32_t, texture_cache_memory_limit_hard); +REXCVAR_DECLARE(int32_t, texture_cache_memory_limit_soft_lifetime); +REXCVAR_DECLARE(bool, non_seamless_cube_map); + +// GPU Primitive Processing +REXCVAR_DECLARE(bool, execute_unclipped_draw_vs_on_cpu); +REXCVAR_DECLARE(bool, execute_unclipped_draw_vs_on_cpu_for_psi_render_backend); +REXCVAR_DECLARE(bool, execute_unclipped_draw_vs_on_cpu_with_scissor); +REXCVAR_DECLARE(bool, force_convert_line_loops_to_strips); +REXCVAR_DECLARE(bool, force_convert_quad_lists_to_triangle_lists); +REXCVAR_DECLARE(bool, force_convert_triangle_fans_to_lists); +REXCVAR_DECLARE(int32_t, primitive_processor_cache_min_indices); + +// GPU Debug +REXCVAR_DECLARE(bool, gpu_debug_markers); +bool IsGpuDebugMarkersEnabled(); + +// GPU Alpha Test +REXCVAR_DECLARE(bool, use_fuzzy_alpha_epsilon); + +// GPU Shader Translation / Tracing +REXCVAR_DECLARE(std::string, dump_shaders); +REXCVAR_DECLARE(bool, dxbc_switch); +REXCVAR_DECLARE(bool, dxbc_source_map); +REXCVAR_DECLARE(std::string, trace_gpu_prefix); +REXCVAR_DECLARE(bool, trace_gpu_stream); +REXCVAR_DECLARE(std::string, swap_post_effect); + +// Vulkan +REXCVAR_DECLARE(bool, vulkan_sparse_shared_memory); +REXCVAR_DECLARE(bool, vulkan_submit_on_primary_buffer_end); +REXCVAR_DECLARE(bool, vulkan_dynamic_rendering); +REXCVAR_DECLARE(bool, vulkan_async_skip_incomplete_frames); +REXCVAR_DECLARE(int32_t, vulkan_pipeline_creation_threads); +REXCVAR_DECLARE(bool, vulkan_tessellation_wireframe); +REXCVAR_DECLARE(bool, vulkan_force_expand_point_sprites_in_vs); +REXCVAR_DECLARE(bool, vulkan_force_expand_rectangle_lists_in_vs); +REXCVAR_DECLARE(bool, vulkan_force_convert_quad_lists_to_triangle_lists); +REXCVAR_DECLARE(std::string, render_target_path_vulkan); +// Legacy backend compatibility aliases for shared readback controls. +REXCVAR_DECLARE(bool, vulkan_readback_resolve); +REXCVAR_DECLARE(bool, vulkan_readback_memexport); + +// D3D12 +REXCVAR_DECLARE(bool, d3d12_bindless); +REXCVAR_DECLARE(bool, d3d12_submit_on_primary_buffer_end); +REXCVAR_DECLARE(bool, d3d12_dxbc_disasm); +REXCVAR_DECLARE(bool, d3d12_dxbc_disasm_dxilconv); +REXCVAR_DECLARE(int32_t, d3d12_pipeline_creation_threads); +REXCVAR_DECLARE(bool, d3d12_tessellation_wireframe); +REXCVAR_DECLARE(bool, d3d12_tiled_shared_memory); +REXCVAR_DECLARE(std::string, render_target_path_d3d12); +// Legacy backend compatibility aliases for shared readback controls. +REXCVAR_DECLARE(bool, d3d12_readback_memexport); +REXCVAR_DECLARE(bool, d3d12_readback_resolve); + +#define XE_GPU_FINE_GRAINED_DRAW_SCOPES 1 diff --git a/include/rex/graphics/format/dxbc.h b/include/rex/graphics/format/dxbc.h new file mode 100644 index 0000000..a5eaa8f --- /dev/null +++ b/include/rex/graphics/format/dxbc.h @@ -0,0 +1,2403 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include + +namespace rex::graphics::dxbc { + +// Utilities for generating shader model 5_1 byte code (for Direct3D 12). +// +// This file contains only parts of DXBC used by Xenia currently or previously, +// not all of DXBC. If an operation, operand, blob or something else is needed +// for Xenia, but is not here, add it (after reproducing it with FXC to see what +// dependencies - such as STAT fields being modified - and encoding specifics it +// has). +// +// IMPORTANT CONTRIBUTION NOTES: +// +// While DXBC may look like a flexible and high-level representation with highly +// generalized building blocks, actually it has a lot of restrictions on operand +// usage! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!DO NOT ADD ANYTHING FXC THAT WOULD NOT PRODUCE!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// Before adding any sequence that you haven't seen in Xenia, try writing +// equivalent code in HLSL and running it through FXC, try with /Od, try with +// full optimization, but if you see that FXC follows a different pattern than +// what you are expecting, do what FXC does!!! +// Most important limitations: +// - Absolute, negate and saturate are only supported by instructions that +// explicitly support them. See MSDN pages of the specific instructions you +// want to use with modifiers: +// https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx9-graphics-reference-asm +// - Component selection in the general case (ALU instructions - things like +// resource access and flow control mostly explicitly need a specific +// component selection mode defined in the specification of the instruction): +// - 0-component - for operand types with no data (samplers, labels). +// - 1-component - for scalar destination operand types, and for scalar source +// operand types when the destination vector has 1 component masked +// (including scalar immediates). +// - Mask - for vector destination operand types. +// - Swizzle - for both vector and scalar (replicated in this case) source +// operand types, when the destination vector has 2 or more components +// masked. Immediates in this case have XYZW swizzle. +// - Select 1 - for vector source operand types, when the destination has 1 +// component masked or is of a scalar type. +// - Input operands (v#) can be used only as sources, output operands (o#) can +// be used only as destinations. +// - Indexable temporaries (x#) can only be used as a destination or a source +// operand (but not both at once) of a mov instruction - a load/store pattern +// here. Also, movs involving x# are counted as ArrayInstructions rather than +// MovInstructions in STAT. The other operand can be anything that most other +// instructions accept, but it still must be a mov with x# on one side. +// !NOTE!: The D3D11.3 Functional Specification on Microsoft's GitHub profile, +// as of March 27th, 2020, is NOT a reliable reference, even though it contains +// many DXBC details! There are multiple places where it clearly contradicts +// what FXC does, even when targeting old shader models like 4_0: +// - The limit of 1 immediate or constant buffer source operand per instruction +// is totally ignored by FXC - in simple tests, it can emit an instruction +// with two constant buffer sources, or one constant buffer source and one +// immediate, or a multiply-add with two immediate operands. +// - It says x# can be used wherever r# can be used - in synthetic tests, FXC +// always accesses x# in a load/store way via mov. +// - It says x# can be used for indexing, including nested indexing of x# (one +// level deep), however, FXC moves the inner index operand to r# first in this +// case. +// +// For bytecode structure, see d3d12TokenizedProgramFormat.hpp from the Windows +// Driver Kit, and DXILConv from DirectX Shader Compiler. +// +// Avoid using uninitialized register components - such as registers written to +// in "if" and not in "else", but then used outside unconditionally or with a +// different condition (or even with the same condition, but in a different "if" +// block). This will cause crashes on AMD drivers, and will also limit +// optimization possibilities as this may result in false dependencies. Always +// mov l(0, 0, 0, 0) to such components before potential branching - +// PushSystemTemp accepts a zero mask for this purpose. +// +// Clamping of non-negative values must be done first to the lower bound (using +// max), then to the upper bound (using min), to match the saturate modifier +// behavior, which results in 0 for NaN. +// +// Sources (apart from reverse engineering of compiled shaders): +// - Hash: +// - DXBCChecksum from GPUOpen-Archive/common-src-ShaderUtils +// - RDEF: +// - d3d12shader.h from the Windows SDK +// - D3D10ShaderObject.h from GPUOpen-Archive/common-src-ShaderUtils +// - ISGN, PCSG, OSGN: +// - d3d12shader.h from the Windows SDK +// - DxbcSignatures.h from DXILConv +// - SHEX: +// - d3d12TokenizedProgramFormat.hpp from the Windows Driver Kit +// - SFI0: +// - DXBCUtils.h from the D3D12 Translation Layer +// - STAT: +// - D3D10ShaderObject.h fromGPUOpen-Archive/common-src-ShaderUtils +// - d3dcompiler_parse_stat from Wine +// - d3d12shader.h from the Windows SDK +// Note that d3d12shader.h contains structures for use with Direct3D reflection +// interfaces, not the DXBC containers themselves. They may have fields removed, +// reordered or added. +// +// Pointers in RDEF and signatures are offsets from the start of the blob (not +// including the FourCC and the size), 0 pointer is considered null when +// applicable. +// +// Even if DXIL emission is added to Xenia, it's still desirable to keep the +// DXBC emitter as a usable option (unless supporting it becomes excessively +// burdensome) - apart from much worse readability of the resulting DXIL code, +// the UWP GPU driver on the Xbox One also doesn't support DXIL. + +constexpr uint8_t kAlignmentPadding = 0xAB; + +constexpr uint32_t MakeFourCC(uint32_t ch0, uint32_t ch1, uint32_t ch2, uint32_t ch3) { + return uint32_t(ch0) | (uint32_t(ch1) << 8) | (uint32_t(ch2) << 16) | (uint32_t(ch3) << 24); +} + +struct alignas(uint32_t) ContainerHeader { + static constexpr uint32_t kFourCC = MakeFourCC('D', 'X', 'B', 'C'); + static constexpr uint16_t kVersionMajor = 1; + static constexpr uint16_t kVersionMinor = 0; + uint32_t fourcc; + // Of the entire DXBC container including this header, with this set to 0 + // before hashing. Calculate using CalculateDXBCChecksum from + // GPUOpen-Archive/common-src-ShaderUtils. + uint32_t hash[4]; + uint16_t version_major; + uint16_t version_minor; + uint32_t size_bytes; + uint32_t blob_count; + void InitializeIdentification() { + fourcc = kFourCC; + version_major = kVersionMajor; + version_minor = kVersionMinor; + } + // Followed by uint32_t[blob_count] offsets from the start of the container in + // bytes to the start of each blob's header. +}; +static_assert_size(ContainerHeader, sizeof(uint32_t) * 8); + +struct alignas(uint32_t) BlobHeader { + enum class FourCC : uint32_t { + // In order of appearance in a container. + kResourceDefinition = MakeFourCC('R', 'D', 'E', 'F'), + kInputSignature = MakeFourCC('I', 'S', 'G', 'N'), + kInputSignature_11_1 = MakeFourCC('I', 'S', 'G', '1'), + kPatchConstantSignature = MakeFourCC('P', 'C', 'S', 'G'), + kOutputSignature = MakeFourCC('O', 'S', 'G', 'N'), + kOutputSignatureForGS = MakeFourCC('O', 'S', 'G', '5'), + kOutputSignature_11_1 = MakeFourCC('O', 'S', 'G', '1'), + kShaderEx = MakeFourCC('S', 'H', 'E', 'X'), + kShaderFeatureInfo = MakeFourCC('S', 'F', 'I', '0'), + kStatistics = MakeFourCC('S', 'T', 'A', 'T'), + }; + FourCC fourcc; + uint32_t size_bytes; +}; +static_assert_size(BlobHeader, sizeof(uint32_t) * 2); + +// Appends a string to a DWORD stream, returns the DWORD-aligned length. +inline uint32_t AppendAlignedString(std::vector& dest, const char* source) { + size_t size = std::strlen(source) + 1; + size_t size_aligned = rex::align(size, sizeof(uint32_t)); + size_t dest_position = dest.size(); + dest.resize(dest_position + size_aligned / sizeof(uint32_t)); + std::memcpy(&dest[dest_position], source, size); + // Don't leave uninitialized data, and make sure multiple uses of the + // assembler with the same input give the same DXBC for driver shader caching. + std::memset(reinterpret_cast(&dest[dest_position]) + size, dxbc::kAlignmentPadding, + size_aligned - size); + return uint32_t(size_aligned); +} + +// Returns the length of a string as if it was appended to a DWORD stream, in +// bytes. +inline uint32_t GetAlignedStringLength(const char* source) { + return uint32_t(rex::align(std::strlen(source) + 1, sizeof(uint32_t))); +} + +// D3DCOMPILE subset +enum CompileFlags : uint32_t { + // NoPreshader and PreferFlowControl are set by default for shader model 5_1. + kCompileFlagNoPreshader = 1 << 8, + kCompileFlagPreferFlowControl = 1 << 10, + kCompileFlagIeeeStrictness = 1 << 13, + kCompileFlagEnableUnboundedDescriptorTables = 1 << 20, + kCompileFlagAllResourcesBound = 1 << 21, +}; + +// D3D_SHADER_VARIABLE_CLASS +enum class RdefVariableClass : uint16_t { + kScalar, + kVector, + kMatrixRows, + kMatrixColumns, + kObject, + kStruct, + kInterfaceClass, + kInterfacePointer, +}; + +// D3D_SHADER_VARIABLE_TYPE subset +enum class RdefVariableType : uint16_t { + kInt = 2, + kFloat = 3, + kUInt = 19, +}; + +// D3D_SHADER_VARIABLE_FLAGS +enum RdefVariableFlags : uint32_t { + kRdefVariableFlagUserPacked = 1 << 0, + kRdefVariableFlagUsed = 1 << 1, + kRdefVariableFlagInterfacePointer = 1 << 2, + kRdefVariableFlagInterfaceParameter = 1 << 3, +}; + +// D3D_SHADER_CBUFFER_FLAGS +enum RdefCbufferFlags : uint32_t { + kRdefCbufferFlagUserPacked = 1 << 0, +}; + +// D3D_CBUFFER_TYPE +enum class RdefCbufferType : uint32_t { + kCbuffer, + kTbuffer, + kInterfacePointers, + kResourceBindInfo, +}; + +// D3D_SHADER_INPUT_TYPE +enum class RdefInputType : uint32_t { + kCbuffer, + kTbuffer, + kTexture, + kSampler, + kUAVRWTyped, + kStructured, + kUAVRWStructured, + kByteAddress, + kUAVRWByteAddress, + kUAVAppendStructured, + kUAVConsumeStructured, + kUAVRWStructuredWithCounter, +}; + +// D3D_RESOURCE_RETURN_TYPE / D3D10_SB_RESOURCE_RETURN_TYPE +enum class ResourceReturnType : uint32_t { + kVoid, + kUNorm, + kSNorm, + kSInt, + kUInt, + kFloat, + kMixed, + kDouble, + kContinued, +}; + +// D3D12_SRV_DIMENSION / D3D12_UAV_DIMENSION +enum class RdefDimension : uint32_t { + kUnknown = 0, + + kSRVBuffer = 1, + kSRVTexture1D, + kSRVTexture1DArray, + kSRVTexture2D, + kSRVTexture2DArray, + kSRVTexture2DMS, + kSRVTexture2DMSArray, + kSRVTexture3D, + kSRVTextureCube, + kSRVTextureCubeArray, + + kUAVBuffer = 1, + kUAVTexture1D, + kUAVTexture1DArray, + kUAVTexture2D, + kUAVTexture2DArray, + kUAVTexture3D, +}; + +// D3D_SHADER_INPUT_FLAGS +enum RdefInputFlags : uint32_t { + // For constant buffers, UserPacked is set if it was declared as `cbuffer` + // rather than `ConstantBuffer` (not dynamically indexable; though + // non-uniform dynamic indexing of constant buffers also didn't work on AMD + // drivers in 2018) - not to be confused with kRdefCbufferFlagUserPacked, + // which is set in a different case. + kRdefInputFlagUserPacked = 1 << 0, + kRdefInputFlagComparisonSampler = 1 << 1, + // Texture and typed buffer component count minus 1. + kRdefInputFlagsComponentsShift = 2, + kRdefInputFlags2Component = 1 << kRdefInputFlagsComponentsShift, + kRdefInputFlags3Component = 2 << kRdefInputFlagsComponentsShift, + kRdefInputFlags4Component = 3 << kRdefInputFlagsComponentsShift, + kRdefInputFlagUnused = 1 << 4, +}; + +enum class RdefShaderModel : uint32_t { + kPixelShader5_1 = 0xFFFF0501u, + kVertexShader5_1 = 0xFFFE0501u, + kGeometryShader5_1 = 0x47530501u, + kDomainShader5_1 = 0x44530501u, + kComputeShader5_1 = 0x43530501u, +}; + +// D3D12_SHADER_TYPE_DESC with some differences. +struct alignas(uint32_t) RdefType { + RdefVariableClass variable_class; + RdefVariableType variable_type; + // Matrix rows, 1 for other numeric, 0 if not applicable. + uint16_t row_count; + // Vector and matrix columns, 1 for other numerics, 0 if not applicable. + uint16_t column_count; + // 0 if not an array, except for structures which have 1. + uint16_t element_count; + // 0 if not a structure. + uint16_t member_count; + // Null if not a structure. + uint32_t members_ptr; + // Zero. + uint32_t unknown_0[4]; + // uint is called dword when it's scalar (but uint vectors are still uintN). + uint32_t name_ptr; +}; +static_assert_size(RdefType, sizeof(uint32_t) * 9); + +struct alignas(uint32_t) RdefStructureMember { + uint32_t name_ptr; + uint32_t type_ptr; + uint32_t offset_bytes; +}; +static_assert_size(RdefStructureMember, sizeof(uint32_t) * 3); + +// D3D12_SHADER_VARIABLE_DESC with some differences. +// Used for constants in constant buffers primarily. +struct alignas(uint32_t) RdefVariable { + uint32_t name_ptr; + uint32_t start_offset_bytes; + uint32_t size_bytes; + // RdefVariableFlags. + uint32_t flags; + uint32_t type_ptr; + uint32_t default_value_ptr; + // UINT32_MAX if no textures used. + uint32_t start_texture; + // Number of texture slots possibly used, 0 if no textures used. + uint32_t texture_size; + // UINT32_MAX if no textures used. + uint32_t start_sampler; + // Number of sampler slots possibly used, 0 if no textures used. + uint32_t sampler_size; +}; +static_assert_size(RdefVariable, sizeof(uint32_t) * 10); + +// Sorted by ID. +struct alignas(uint32_t) RdefCbuffer { + uint32_t name_ptr; + uint32_t variable_count; + uint32_t variables_ptr; + // 16-byte-aligned. + uint32_t size_vector_aligned_bytes; + RdefCbufferType type; + // RdefCbufferFlags. + uint32_t flags; +}; +static_assert_size(RdefCbuffer, sizeof(uint32_t) * 6); + +// D3D12_SHADER_INPUT_BIND_DESC with some differences. +// Placed in samplers, SRVs, UAVs, CBVs order, sorted by ID. +struct alignas(uint32_t) RdefInputBind { + uint32_t name_ptr; + RdefInputType type; + ResourceReturnType return_type; + RdefDimension dimension; + // 0 for multisampled textures (the sample count is specified in the SRV + // descriptor), constant buffers, ByteAddressBuffers and samplers. + // UINT32_MAX for single-sampled textures and typed buffers. + uint32_t sample_count; + uint32_t bind_point; + // 0 for unbounded. + uint32_t bind_count; + // RdefInputFlags. + uint32_t flags; + // Bind point space and ID added in shader model 5_1. + uint32_t bind_point_space; + uint32_t id; +}; +static_assert_size(RdefInputBind, sizeof(uint32_t) * 10); + +struct alignas(uint32_t) RdefHeader { + enum class FourCC : uint32_t { + // RD11 in Shader Model 5_0 shaders. + k5_0 = MakeFourCC('R', 'D', '1', '1'), + // RD11 with reversed nibbles in Shader Model 5_0 shaders. + k5_1 = 0x25441313u, + }; + uint32_t cbuffer_count; + uint32_t cbuffers_ptr; + uint32_t input_bind_count; + uint32_t input_binds_ptr; + RdefShaderModel shader_model; + // CompileFlags. + uint32_t compile_flags; + uint32_t generator_name_ptr; + FourCC fourcc; + uint32_t sizeof_header_bytes; + uint32_t sizeof_cbuffer_bytes; + uint32_t sizeof_input_bind_bytes; + uint32_t sizeof_variable_bytes; + uint32_t sizeof_type_bytes; + uint32_t sizeof_structure_member_bytes; + // Zero. + uint32_t unknown_0; + void InitializeSizes() { + sizeof_header_bytes = sizeof(*this); + sizeof_cbuffer_bytes = sizeof(RdefCbuffer); + sizeof_input_bind_bytes = sizeof(RdefInputBind); + sizeof_variable_bytes = sizeof(RdefVariable); + sizeof_type_bytes = sizeof(RdefType); + sizeof_structure_member_bytes = sizeof(RdefStructureMember); + } +}; +static_assert_size(RdefHeader, sizeof(uint32_t) * 15); + +// D3D_NAME subset +enum class Name : uint32_t { + kUndefined = 0, + kPosition = 1, + kClipDistance = 2, + kCullDistance = 3, + kVertexID = 6, + kIsFrontFace = 9, + kSampleIndex = 10, + kFinalQuadEdgeTessFactor = 11, + kFinalQuadInsideTessFactor = 12, + kFinalTriEdgeTessFactor = 13, + kFinalTriInsideTessFactor = 14, +}; + +// D3D_REGISTER_COMPONENT_TYPE +enum class SignatureRegisterComponentType : uint32_t { + kUnknown, + kUInt32, + kSInt32, + kFloat32, +}; + +// D3D_MIN_PRECISION +enum class MinPrecision : uint32_t { + kDefault, + kFloat16, + kFloat2_8, + kSInt16 = 4, + kUInt16, + kAny16 = 0xF0, + kAny10, +}; + +// D3D10_INTERNALSHADER_PARAMETER +struct alignas(uint32_t) SignatureParameter { + uint32_t semantic_name_ptr; + uint32_t semantic_index; + // kUndefined for pixel shader outputs - inferred from the component type and + // what is used in the shader. + Name system_value; + SignatureRegisterComponentType component_type; + // o#/v# when there's linkage, SV_Target index or UINT32_MAX in pixel shader + // output. + uint32_t register_index; + uint8_t mask; + union { + // For an output signature. + uint8_t never_writes_mask; + // For an input signature. + uint8_t always_reads_mask; + }; +}; +static_assert_size(SignatureParameter, sizeof(uint32_t) * 6); + +// D3D11_INTERNALSHADER_PARAMETER_FOR_GS +// Extends SignatureParameter, see it for more information. +struct alignas(uint32_t) SignatureParameterForGS { + // Stream index (parameters must appear in non-decreasing stream order). + uint32_t stream; + uint32_t semantic_name_ptr; + uint32_t semantic_index; + Name system_value; + SignatureRegisterComponentType component_type; + uint32_t register_index; + uint8_t mask; + union { + uint8_t never_writes_mask; + uint8_t always_reads_mask; + }; +}; +static_assert_size(SignatureParameterForGS, sizeof(uint32_t) * 7); + +// D3D11_INTERNALSHADER_PARAMETER_11_1 +// Extends SignatureParameterForGS, see it for more information. +struct alignas(uint32_t) SignatureParameter_11_1 { + uint32_t stream; + uint32_t semantic_name_ptr; + uint32_t semantic_index; + Name system_value; + SignatureRegisterComponentType component_type; + uint32_t register_index; + uint8_t mask; + union { + uint8_t never_writes_mask; + uint8_t always_reads_mask; + }; + MinPrecision min_precision; +}; +static_assert_size(SignatureParameter_11_1, sizeof(uint32_t) * 8); + +// D3D10_INTERNALSHADER_SIGNATURE +struct alignas(uint32_t) Signature { + uint32_t parameter_count; + // If the signature is empty, this still points after the header. + uint32_t parameter_info_ptr; +}; +static_assert_size(Signature, sizeof(uint32_t) * 2); + +// SHADER_FEATURE +// Low 32 bits. +enum ShaderFeature0 : uint32_t { + kShaderFeature0_Doubles = 1 << 0, + kShaderFeature0_ComputeShadersPlusRawAndStructuredBuffersViaShader_4_X = 1 << 1, + kShaderFeature0_UAVsAtEveryStage = 1 << 2, + kShaderFeature0_64UAVs = 1 << 3, + kShaderFeature0_MinimumPrecision = 1 << 4, + kShaderFeature0_11_1_DoubleExtensions = 1 << 5, + kShaderFeature0_11_1_ShaderExtensions = 1 << 6, + kShaderFeature0_Level9ComparisonFiltering = 1 << 7, + kShaderFeature0_TiledResources = 1 << 8, + kShaderFeature0_StencilRef = 1 << 9, + kShaderFeature0_InnerCoverage = 1 << 10, + kShaderFeature0_TypedUAVLoadAdditionalFormats = 1 << 11, + kShaderFeature0_ROVs = 1 << 12, + kShaderFeature0_ViewportAndRTArrayIndexFromAnyShaderFeedingRasterizer = 1 << 13, +}; + +struct alignas(uint32_t) ShaderFeatureInfo { + // UINT64 originally, but aligned to 4 rather than 8. + uint32_t feature_flags[2]; +}; +static_assert_size(ShaderFeatureInfo, sizeof(uint32_t) * 2); + +// D3D11_SB_TESSELLATOR_DOMAIN +enum class TessellatorDomain : uint32_t { + kUndefined, + kIsoline, + kTriangle, + kQuad, +}; + +// D3D10_SB_PRIMITIVE_TOPOLOGY +enum class PrimitiveTopology : uint32_t { + kUndefined = 0, + kPointList = 1, + kLineList = 2, + kLineStrip = 3, + kTriangleList = 4, + kTriangleStrip = 5, + kLineListWithAdjacency = 10, + kLineStripWithAdjacency = 11, + kTriangleListWithAdjacency = 12, + kTriangleStripWithAdjacency = 13, +}; + +// D3D10_SB_PRIMITIVE +enum class Primitive : uint32_t { + kUndefined = 0, + kPoint = 1, + kLine = 2, + kTriangle = 3, + kLineWithAdjacency = 6, + kTriangleWithAdjacency = 7, + k1ControlPointPatch = 8, + k2ControlPointPatch = 9, + k3ControlPointPatch = 10, + k4ControlPointPatch = 11, + k5ControlPointPatch = 12, + k6ControlPointPatch = 13, + k7ControlPointPatch = 14, + k8ControlPointPatch = 15, + k9ControlPointPatch = 16, + k10ControlPointPatch = 17, + k11ControlPointPatch = 18, + k12ControlPointPatch = 19, + k13ControlPointPatch = 20, + k14ControlPointPatch = 21, + k15ControlPointPatch = 22, + k16ControlPointPatch = 23, + k17ControlPointPatch = 24, + k18ControlPointPatch = 25, + k19ControlPointPatch = 26, + k20ControlPointPatch = 27, + k21ControlPointPatch = 28, + k22ControlPointPatch = 29, + k23ControlPointPatch = 30, + k24ControlPointPatch = 31, + k25ControlPointPatch = 32, + k26ControlPointPatch = 33, + k27ControlPointPatch = 34, + k28ControlPointPatch = 35, + k29ControlPointPatch = 36, + k30ControlPointPatch = 37, + k31ControlPointPatch = 38, + k32ControlPointPatch = 39, +}; + +// The STAT blob (based on Wine d3dcompiler_parse_stat). +struct alignas(uint32_t) Statistics { + // Not increased by declarations and labels. + uint32_t instruction_count; // +0 + uint32_t temp_register_count; // +4 + // Unknown in Wine. + uint32_t def_count; // +8 + // Only inputs and outputs, not CBVs, SRVs, UAVs and samplers. + uint32_t dcl_count; // +C + uint32_t float_instruction_count; // +10 + uint32_t int_instruction_count; // +14 + uint32_t uint_instruction_count; // +18 + // endif, ret. + uint32_t static_flow_control_count; // +1C + // if (but not else). + uint32_t dynamic_flow_control_count; // +20 + // Unknown in Wine. + uint32_t macro_instruction_count; // +24 + uint32_t temp_array_count; // +28 + uint32_t array_instruction_count; // +2C + uint32_t cut_instruction_count; // +30 + uint32_t emit_instruction_count; // +34 + uint32_t texture_normal_instructions; // +38 + uint32_t texture_load_instructions; // +3C + uint32_t texture_comp_instructions; // +40 + uint32_t texture_bias_instructions; // +44 + uint32_t texture_gradient_instructions; // +48 + // Not including indexable temp load/store. + uint32_t mov_instruction_count; // +4C + // Unknown in Wine. + uint32_t movc_instruction_count; // +50 + uint32_t conversion_instruction_count; // +54 + // Unknown in Wine. + uint32_t unknown_22; // +58 + Primitive input_primitive; // +5C + PrimitiveTopology gs_output_topology; // +60 + uint32_t gs_max_output_vertex_count; // +64 + uint32_t unknown_26; // +68 + // Unknown in Wine, but confirmed by testing. + uint32_t lod_instructions; // +6C + uint32_t unknown_28; // +70 + uint32_t unknown_29; // +74 + uint32_t c_control_points; // +78 + uint32_t hs_output_primitive; // +7C + uint32_t hs_partitioning; // +80 + TessellatorDomain tessellator_domain; // +84 + // Unknown in Wine. + uint32_t c_barrier_instructions; // +88 + // Unknown in Wine. + uint32_t c_interlocked_instructions; // +8C + // Unknown in Wine, but confirmed by testing. + uint32_t c_texture_store_instructions; // +90 +}; +static_assert_size(Statistics, sizeof(uint32_t) * 37); + +// A shader blob begins with a version token and the shader length in dwords +// (including the version token and the length token itself). + +// D3D10_SB_TOKENIZED_PROGRAM_TYPE +enum class ProgramType : uint32_t { + kPixelShader, + kVertexShader, + kGeometryShader, + kHullShader, + kDomainShader, + kComputeShader, +}; + +constexpr uint32_t VersionToken(ProgramType program_type, uint32_t major_version, + uint32_t minor_version) { + return (uint32_t(program_type) << 16) | (major_version << 4) | minor_version; +} + +// D3D10_SB_CUSTOMDATA_CLASS +enum class CustomDataClass : uint32_t { + kComment, + kDebugInfo, + kOpaque, + kDclImmediateConstantBuffer, + kShaderMessage, + kShaderClipPlaneConstantMappingsForDX9, +}; + +// D3D10_SB_OPERAND_TYPE subset +enum class OperandType : uint32_t { + kTemp = 0, + kInput = 1, + kOutput = 2, + // Only usable as destination or source (but not both) in mov (and it + // becomes an array instruction this way). + kIndexableTemp = 3, + kImmediate32 = 4, + kSampler = 6, + kResource = 7, + kConstantBuffer = 8, + kLabel = 10, + kInputPrimitiveID = 11, + kOutputDepth = 12, + kNull = 13, + kOutputCoverageMask = 15, + kStream = 16, + kInputControlPoint = 25, + kInputDomainPoint = 28, + kUnorderedAccessView = 30, + kInputThreadID = 32, + kInputThreadGroupID = 33, + kInputThreadIDInGroup = 34, + kInputCoverageMask = 35, + kOutputDepthLessEqual = 39, + kOutputStencilRef = 41, +}; + +// D3D10_SB_OPERAND_NUM_COMPONENTS +enum class OperandDimension : uint32_t { + kNoData, // D3D10_SB_OPERAND_0_COMPONENT + kScalar, // D3D10_SB_OPERAND_1_COMPONENT + kVector, // D3D10_SB_OPERAND_4_COMPONENT +}; + +constexpr OperandDimension GetOperandDimension(OperandType type, bool in_dcl = false) { + switch (type) { + case OperandType::kSampler: + return in_dcl ? OperandDimension::kVector : OperandDimension::kNoData; + case OperandType::kLabel: + case OperandType::kNull: + case OperandType::kStream: + return OperandDimension::kNoData; + case OperandType::kInputPrimitiveID: + case OperandType::kOutputDepth: + case OperandType::kOutputCoverageMask: + case OperandType::kOutputDepthLessEqual: + case OperandType::kOutputStencilRef: + return OperandDimension::kScalar; + case OperandType::kInputCoverageMask: + return in_dcl ? OperandDimension::kScalar : OperandDimension::kVector; + default: + return OperandDimension::kVector; + } +} + +// D3D10_SB_OPERAND_4_COMPONENT_SELECTION_MODE +enum class ComponentSelection { + kMask, + kSwizzle, + kSelect1, +}; + +struct Index { + // D3D10_SB_OPERAND_INDEX_REPRESENTATION + enum class Representation : uint32_t { + kImmediate32, + kImmediate64, + kRelative, + kImmediate32PlusRelative, + kImmediate64PlusRelative, + }; + + uint32_t index_; + // UINT32_MAX if absolute. Lower 2 bits are the component index, upper bits + // are the temp register index. Applicable to indexable temps, inputs, + // outputs except for pixel shaders, constant buffers and bindings. + uint32_t relative_to_temp_; + + // Implicit constructor. + Index(uint32_t index = 0) : index_(index), relative_to_temp_(UINT32_MAX) {} + Index(uint32_t temp, uint32_t temp_component, uint32_t offset = 0) + : index_(offset), relative_to_temp_((temp << 2) | temp_component) {} + + Representation GetRepresentation() const { + if (relative_to_temp_ != UINT32_MAX) { + return index_ != 0 ? Representation::kImmediate32PlusRelative : Representation::kRelative; + } + return Representation::kImmediate32; + } + uint32_t GetLength() const { return relative_to_temp_ != UINT32_MAX ? (index_ != 0 ? 3 : 2) : 1; } + void Write(std::vector& code) const { + if (relative_to_temp_ == UINT32_MAX || index_ != 0) { + code.push_back(index_); + } + if (relative_to_temp_ != UINT32_MAX) { + // Encode selecting one component from absolute-indexed r#. + code.push_back(uint32_t(OperandDimension::kVector) | + (uint32_t(ComponentSelection::kSelect1) << 2) | + ((relative_to_temp_ & 3) << 4) | (uint32_t(OperandType::kTemp) << 12) | + (1 << 20) | (uint32_t(Representation::kImmediate32) << 22)); + code.push_back(relative_to_temp_ >> 2); + } + } +}; + +struct OperandAddress { + OperandType type_; + uint32_t index_dimension_; + Index index_1d_, index_2d_, index_3d_; + + explicit OperandAddress(OperandType type) : type_(type), index_dimension_(0) {} + explicit OperandAddress(OperandType type, Index index_1d) + : type_(type), index_dimension_(1), index_1d_(index_1d) {} + explicit OperandAddress(OperandType type, Index index_1d, Index index_2d) + : type_(type), index_dimension_(2), index_1d_(index_1d), index_2d_(index_2d) {} + explicit OperandAddress(OperandType type, Index index_1d, Index index_2d, Index index_3d) + : type_(type), + index_dimension_(3), + index_1d_(index_1d), + index_2d_(index_2d), + index_3d_(index_3d) {} + + OperandDimension GetDimension(bool in_dcl = false) const { + return GetOperandDimension(type_, in_dcl); + } + uint32_t GetOperandTokenTypeAndIndex() const { + uint32_t operand_token = (uint32_t(type_) << 12) | (index_dimension_ << 20); + if (index_dimension_ > 0) { + operand_token |= uint32_t(index_1d_.GetRepresentation()) << 22; + if (index_dimension_ > 1) { + operand_token |= uint32_t(index_2d_.GetRepresentation()) << 25; + if (index_dimension_ > 2) { + operand_token |= uint32_t(index_3d_.GetRepresentation()) << 28; + } + } + } + return operand_token; + } + uint32_t GetLength() const { + uint32_t length = 0; + if (index_dimension_ > 0) { + length += index_1d_.GetLength(); + if (index_dimension_ > 1) { + length += index_2d_.GetLength(); + if (index_dimension_ > 2) { + length += index_3d_.GetLength(); + } + } + } + return length; + } + void Write(std::vector& code) const { + if (index_dimension_ > 0) { + index_1d_.Write(code); + if (index_dimension_ > 1) { + index_2d_.Write(code); + if (index_dimension_ > 2) { + index_3d_.Write(code); + } + } + } + } +}; + +// D3D10_SB_EXTENDED_OPERAND_TYPE +enum class ExtendedOperandType : uint32_t { + kEmpty, + kModifier, +}; + +// D3D10_SB_OPERAND_MODIFIER +enum class OperandModifier : uint32_t { + kNone, + kNegate, + kAbsolute, + kAbsoluteNegate, +}; + +struct Dest : OperandAddress { + // Ignored for 0-component and 1-component operand types. + // For 4-component operand types, if the write mask is 0, it's treated as + // 0-component. + uint32_t write_mask_; + + // Input destinations (v*) are for use only in declarations. Vector input + // declarations use read masks instead of swizzle (resource declarations still + // use swizzle when they're vector, however). + + explicit Dest(OperandType type, uint32_t write_mask) + : OperandAddress(type), write_mask_(write_mask) {} + explicit Dest(OperandType type, uint32_t write_mask, Index index_1d) + : OperandAddress(type, index_1d), write_mask_(write_mask) {} + explicit Dest(OperandType type, uint32_t write_mask, Index index_1d, Index index_2d) + : OperandAddress(type, index_1d, index_2d), write_mask_(write_mask) {} + explicit Dest(OperandType type, uint32_t write_mask, Index index_1d, Index index_2d, + Index index_3d) + : OperandAddress(type, index_1d, index_2d, index_3d), write_mask_(write_mask) {} + + static Dest R(uint32_t index, uint32_t write_mask = 0b1111) { + return Dest(OperandType::kTemp, write_mask, index); + } + static Dest V1D(uint32_t index, uint32_t read_mask = 0b1111) { + return Dest(OperandType::kInput, read_mask, index); + } + static Dest V2D(uint32_t index_1d, uint32_t index_2d, uint32_t read_mask = 0b1111) { + return Dest(OperandType::kInput, read_mask, index_1d, index_2d); + } + static Dest O(Index index, uint32_t write_mask = 0b1111) { + return Dest(OperandType::kOutput, write_mask, index); + } + static Dest X(uint32_t index_1d, Index index_2d, uint32_t write_mask = 0b1111) { + return Dest(OperandType::kIndexableTemp, write_mask, index_1d, index_2d); + } + static Dest VPrim() { return Dest(OperandType::kInputPrimitiveID, 0b0001); } + static Dest ODepth() { return Dest(OperandType::kOutputDepth, 0b0001); } + static Dest Null() { return Dest(OperandType::kNull, 0b0000); } + static Dest OMask() { return Dest(OperandType::kOutputCoverageMask, 0b0001); } + static Dest M(uint32_t index) { return Dest(OperandType::kStream, 0b0000, index); } + static Dest VICP(uint32_t control_point_count, uint32_t element, uint32_t read_mask = 0b1111) { + return Dest(OperandType::kInputControlPoint, read_mask, control_point_count, element); + } + static Dest VDomain(uint32_t read_mask) { + return Dest(OperandType::kInputDomainPoint, read_mask); + } + static Dest U(uint32_t index_1d, Index index_2d, uint32_t write_mask = 0b1111) { + return Dest(OperandType::kUnorderedAccessView, write_mask, index_1d, index_2d); + } + static Dest VThreadID(uint32_t read_mask) { return Dest(OperandType::kInputThreadID, read_mask); } + static Dest VThreadGroupID(uint32_t read_mask) { + return Dest(OperandType::kInputThreadGroupID, read_mask); + } + static Dest VThreadIDInGroup(uint32_t read_mask) { + return Dest(OperandType::kInputThreadIDInGroup, read_mask); + } + static Dest VCoverage() { return Dest(OperandType::kInputCoverageMask, 0b0001); } + static Dest ODepthLE() { return Dest(OperandType::kOutputDepthLessEqual, 0b0001); } + static Dest OStencilRef() { return Dest(OperandType::kOutputStencilRef, 0b0001); } + + uint32_t GetMask(bool in_dcl = false) const { + OperandDimension dimension = GetDimension(in_dcl); + switch (dimension) { + case OperandDimension::kNoData: + return 0b0000; + case OperandDimension::kScalar: + return 0b0001; + case OperandDimension::kVector: + return write_mask_; + default: + assert_unhandled_case(dimension); + return 0b0000; + } + } + [[nodiscard]] Dest Mask(uint32_t write_mask) const { + Dest new_dest(*this); + new_dest.write_mask_ = write_mask; + return new_dest; + } + [[nodiscard]] Dest MaskMasked(uint32_t write_mask) const { + Dest new_dest(*this); + new_dest.write_mask_ &= write_mask; + return new_dest; + } + static uint32_t GetMaskSingleComponent(uint32_t write_mask) { + uint32_t component; + if (rex::bit_scan_forward(write_mask, &component)) { + if ((write_mask >> component) == 1) { + return component; + } + } + return UINT32_MAX; + } + uint32_t GetMaskSingleComponent(bool in_dcl = false) const { + return GetMaskSingleComponent(GetMask(in_dcl)); + } + + uint32_t GetLength() const { return 1 + OperandAddress::GetLength(); } + void Write(std::vector& code, bool in_dcl = false) const { + uint32_t operand_token = GetOperandTokenTypeAndIndex(); + OperandDimension dimension = GetDimension(in_dcl); + if (dimension == OperandDimension::kVector) { + if (write_mask_) { + assert_true(write_mask_ <= 0b1111); + operand_token |= (uint32_t(ComponentSelection::kMask) << 2) | (write_mask_ << 4); + } else { + dimension = OperandDimension::kNoData; + } + } + operand_token |= uint32_t(dimension); + code.push_back(operand_token); + OperandAddress::Write(code); + } +}; + +struct Src : OperandAddress { + enum : uint32_t { + kXYZW = 0b11100100, + kXXXX = 0b00000000, + kYYYY = 0b01010101, + kZZZZ = 0b10101010, + kWWWW = 0b11111111, + }; + + // Ignored for 0-component and 1-component operand types. + uint32_t swizzle_; + bool absolute_ = false; + bool negate_ = false; + // Only valid for OperandType::kImmediate32. + uint32_t immediate_[4]; + + explicit Src(OperandType type, uint32_t swizzle) : OperandAddress(type), swizzle_(swizzle) {} + explicit Src(OperandType type, uint32_t swizzle, Index index_1d) + : OperandAddress(type, index_1d), swizzle_(swizzle) {} + explicit Src(OperandType type, uint32_t swizzle, Index index_1d, Index index_2d) + : OperandAddress(type, index_1d, index_2d), swizzle_(swizzle) {} + explicit Src(OperandType type, uint32_t swizzle, Index index_1d, Index index_2d, Index index_3d) + : OperandAddress(type, index_1d, index_2d, index_3d), swizzle_(swizzle) {} + + // For creating instances for use in declarations. + struct DclT {}; + static constexpr DclT Dcl = {}; + + static Src R(uint32_t index, uint32_t swizzle = kXYZW) { + return Src(OperandType::kTemp, swizzle, index); + } + static Src V1D(Index index, uint32_t swizzle = kXYZW) { + return Src(OperandType::kInput, swizzle, index); + } + static Src V2D(Index index_1d, Index index_2d, uint32_t swizzle = kXYZW) { + return Src(OperandType::kInput, swizzle, index_1d, index_2d); + } + static Src X(uint32_t index_1d, Index index_2d, uint32_t swizzle = kXYZW) { + return Src(OperandType::kIndexableTemp, swizzle, index_1d, index_2d); + } + static Src LU(uint32_t x, uint32_t y, uint32_t z, uint32_t w) { + Src src(OperandType::kImmediate32, kXYZW); + src.immediate_[0] = x; + src.immediate_[1] = y; + src.immediate_[2] = z; + src.immediate_[3] = w; + return src; + } + static Src LU(uint32_t x) { return LU(x, x, x, x); } + static Src LI(int32_t x, int32_t y, int32_t z, int32_t w) { + return LU(uint32_t(x), uint32_t(y), uint32_t(z), uint32_t(w)); + } + static Src LI(int32_t x) { return LI(x, x, x, x); } + static Src LF(float x, float y, float z, float w) { + return LU(rex::memory::Reinterpret(x), rex::memory::Reinterpret(y), + rex::memory::Reinterpret(z), rex::memory::Reinterpret(w)); + } + static Src LF(float x) { return LF(x, x, x, x); } + static Src LP(const uint32_t* xyzw) { return LU(xyzw[0], xyzw[1], xyzw[2], xyzw[3]); } + static Src LP(const int32_t* xyzw) { return LI(xyzw[0], xyzw[1], xyzw[2], xyzw[3]); } + static Src LP(const float* xyzw) { return LF(xyzw[0], xyzw[1], xyzw[2], xyzw[3]); } + static Src S(uint32_t index_1d, Index index_2d) { + return Src(OperandType::kSampler, kXXXX, index_1d, index_2d); + } + static Src S(DclT, uint32_t id, uint32_t lower_bound, uint32_t upper_bound) { + return Src(OperandType::kSampler, kXYZW, id, lower_bound, upper_bound); + } + static Src T(uint32_t index_1d, Index index_2d, uint32_t swizzle = kXYZW) { + return Src(OperandType::kResource, swizzle, index_1d, index_2d); + } + static Src T(DclT, uint32_t id, uint32_t lower_bound, uint32_t upper_bound) { + return Src(OperandType::kResource, kXYZW, id, lower_bound, upper_bound); + } + static Src CB(uint32_t id, Index index, Index location, uint32_t swizzle = kXYZW) { + return Src(OperandType::kConstantBuffer, swizzle, id, index, location); + } + static Src CB(DclT, uint32_t id, uint32_t lower_bound, uint32_t upper_bound) { + return Src(OperandType::kConstantBuffer, kXYZW, id, lower_bound, upper_bound); + } + static Src Label(uint32_t index) { return Src(OperandType::kLabel, kXXXX, index); } + static Src VPrim() { return Src(OperandType::kInputPrimitiveID, kXXXX); } + static Src VICP(Index control_point, Index element, uint32_t swizzle = kXYZW) { + return Src(OperandType::kInputControlPoint, swizzle, control_point, element); + } + static Src VDomain(uint32_t swizzle = kXYZW) { + return Src(OperandType::kInputDomainPoint, swizzle); + } + static Src U(uint32_t index_1d, Index index_2d, uint32_t swizzle = kXYZW) { + return Src(OperandType::kUnorderedAccessView, swizzle, index_1d, index_2d); + } + static Src U(DclT, uint32_t id, uint32_t lower_bound, uint32_t upper_bound) { + return Src(OperandType::kUnorderedAccessView, kXYZW, id, lower_bound, upper_bound); + } + static Src VThreadID(uint32_t swizzle = kXYZW) { + return Src(OperandType::kInputThreadID, swizzle); + } + static Src VThreadGroupID(uint32_t swizzle = kXYZW) { + return Src(OperandType::kInputThreadGroupID, swizzle); + } + static Src VThreadIDInGroup(uint32_t swizzle = kXYZW) { + return Src(OperandType::kInputThreadIDInGroup, swizzle); + } + static Src VCoverage() { return Src(OperandType::kInputCoverageMask, kXXXX); } + + [[nodiscard]] Src WithModifiers(bool absolute, bool negate) const { + Src new_src(*this); + new_src.absolute_ = absolute; + new_src.negate_ = negate; + return new_src; + } + [[nodiscard]] Src WithAbs(bool absolute) const { return WithModifiers(absolute, negate_); } + [[nodiscard]] Src WithNeg(bool negate) const { return WithModifiers(absolute_, negate); } + [[nodiscard]] Src Abs() const { return WithModifiers(true, false); } + [[nodiscard]] Src operator-() const { return WithModifiers(absolute_, !negate_); } + [[nodiscard]] Src Swizzle(uint32_t swizzle) const { + Src new_src(*this); + new_src.swizzle_ = swizzle; + return new_src; + } + [[nodiscard]] Src SwizzleSwizzled(uint32_t swizzle) const { + Src new_src(*this); + new_src.swizzle_ = 0; + for (uint32_t i = 0; i < 4; ++i) { + new_src.swizzle_ |= ((swizzle_ >> (((swizzle >> (i * 2)) & 3) * 2)) & 3) << (i * 2); + } + return new_src; + } + [[nodiscard]] Src Select(uint32_t component) const { + Src new_src(*this); + new_src.swizzle_ = component * 0b01010101; + return new_src; + } + [[nodiscard]] Src SelectFromSwizzled(uint32_t component) const { + Src new_src(*this); + new_src.swizzle_ = ((swizzle_ >> (component * 2)) & 3) * 0b01010101; + return new_src; + } + + uint32_t GetLength(uint32_t mask, bool force_vector = false) const { + bool is_vector = + force_vector || (mask != 0b0000 && Dest::GetMaskSingleComponent(mask) == UINT32_MAX); + if (type_ == OperandType::kImmediate32) { + return is_vector ? 5 : 2; + } + return ((absolute_ || negate_) ? 2 : 1) + OperandAddress::GetLength(); + } + static constexpr uint32_t GetModifiedImmediate(uint32_t value, bool is_integer, bool absolute, + bool negate) { + if (is_integer) { + if (absolute) { + value = uint32_t(std::abs(int32_t(value))); + } + if (negate) { + value = uint32_t(-int32_t(value)); + } + } else { + if (absolute) { + value &= uint32_t(INT32_MAX); + } + if (negate) { + value ^= uint32_t(INT32_MAX) + 1; + } + } + return value; + } + uint32_t GetModifiedImmediate(uint32_t swizzle_index, bool is_integer) const { + return GetModifiedImmediate(immediate_[(swizzle_ >> (swizzle_index * 2)) & 3], is_integer, + absolute_, negate_); + } + void Write(std::vector& code, bool is_integer, uint32_t mask, bool force_vector = false, + bool in_dcl = false) const { + uint32_t operand_token = GetOperandTokenTypeAndIndex(); + uint32_t mask_single_component = Dest::GetMaskSingleComponent(mask); + uint32_t select_component = mask_single_component != UINT32_MAX ? mask_single_component : 0; + bool is_vector = force_vector || (mask != 0b0000 && mask_single_component == UINT32_MAX); + if (type_ == OperandType::kImmediate32) { + if (is_vector) { + operand_token |= uint32_t(OperandDimension::kVector) | + (uint32_t(ComponentSelection::kSwizzle) << 2) | (Src::kXYZW << 4); + } else { + operand_token |= uint32_t(OperandDimension::kScalar); + } + code.push_back(operand_token); + if (is_vector) { + for (uint32_t i = 0; i < 4; ++i) { + code.push_back((mask & (1 << i)) ? GetModifiedImmediate(i, is_integer) : 0); + } + } else { + code.push_back(GetModifiedImmediate(select_component, is_integer)); + } + } else { + switch (GetDimension(in_dcl)) { + case OperandDimension::kScalar: + if (is_vector) { + operand_token |= uint32_t(OperandDimension::kVector) | + (uint32_t(ComponentSelection::kSwizzle) << 2) | (Src::kXXXX << 4); + } else { + operand_token |= uint32_t(OperandDimension::kScalar); + } + break; + case OperandDimension::kVector: + operand_token |= uint32_t(OperandDimension::kVector); + if (is_vector) { + operand_token |= uint32_t(ComponentSelection::kSwizzle) << 2; + // Clear swizzle of unused components to a used value to avoid + // referencing potentially uninitialized register components. + uint32_t used_component; + if (!rex::bit_scan_forward(mask, &used_component)) { + used_component = 0; + } + for (uint32_t i = 0; i < 4; ++i) { + uint32_t swizzle_index = (mask & (1 << i)) ? i : used_component; + operand_token |= (((swizzle_ >> (swizzle_index * 2)) & 3) << (4 + i * 2)); + } + } else { + operand_token |= (uint32_t(ComponentSelection::kSelect1) << 2) | + (((swizzle_ >> (select_component * 2)) & 3) << 4); + } + break; + default: + break; + } + OperandModifier modifier = OperandModifier::kNone; + if (absolute_ && negate_) { + modifier = OperandModifier::kAbsoluteNegate; + } else if (absolute_) { + modifier = OperandModifier::kAbsolute; + } else if (negate_) { + modifier = OperandModifier::kNegate; + } + if (modifier != OperandModifier::kNone) { + operand_token |= uint32_t(1) << 31; + } + code.push_back(operand_token); + if (modifier != OperandModifier::kNone) { + code.push_back(uint32_t(ExtendedOperandType::kModifier) | (uint32_t(modifier) << 6)); + } + OperandAddress::Write(code); + } + } +}; + +// D3D10_SB_GLOBAL_FLAGS_MASK +enum GlobalFlags : uint32_t { + // Permit the driver to reorder arithmetic operations for optimization. + kGlobalFlagRefactoringAllowed = 1 << 11, + kGlobalFlagEnableDoublePrecisionFloatOps = 1 << 12, + kGlobalFlagForceEarlyDepthStencil = 1 << 13, + // Enable RAW and structured buffers in non-CS 4.x shaders. Not needed on 5.x. + kGlobalFlagEnableRawAndStructuredBuffers = 1 << 14, + // Direct3D 11.1. + // Skip optimizations of shader IL when translating to native code. + kGlobalFlagSkipOptimization = 1 << 15, + kGlobalFlagEnableMinimumPrecision = 1 << 16, + // Enable 11.1 double-precision floating-point instruction extensions. Not + // needed on 5.1. + kGlobalFlagEnableDoubleExtensions = 1 << 17, + // Enable 11.1 non-double instruction extensions. Not needed on 5.1. + kGlobalFlagEnableShaderExtensions = 1 << 18, + // Direct3D 12. + kGlobalFlagAllResourcesBound = 1 << 19, +}; + +// D3D10_SB_SAMPLER_MODE +enum class SamplerMode : uint32_t { + kDefault, + kComparison, + kMono, +}; + +// D3D10_SB_CONSTANT_BUFFER_ACCESS_PATTERN +enum class ConstantBufferAccessPattern : uint32_t { + kImmediateIndexed, + kDynamicIndexed, +}; + +// D3D10_SB_INTERPOLATION_MODE +enum class InterpolationMode : uint32_t { + kUndefined, + kConstant, + kLinear, + kLinearCentroid, + kLinearNoPerspective, + kLinearNoPerspectiveCentroid, + kLinearSample, + kLinearNoPerspectiveSample, +}; + +// D3D10_SB_RESOURCE_DIMENSION +enum class ResourceDimension : uint32_t { + kUnknown, + kBuffer, + kTexture1D, + kTexture2D, + kTexture2DMS, + kTexture3D, + kTextureCube, + kTexture1DArray, + kTexture2DArray, + kTexture2DMSArray, + kTextureCubeArray, + kRawBuffer, + kStructuredBuffer, +}; + +// D3D11_SB_RESOURCE_FLAGS_MASK +enum UAVFlags : uint32_t { + kUAVFlagGloballyCoherentAccess = 1 << 16, + kUAVFlagRasterizerOrderedAccess = 1 << 17, + kUAVFlagHasOrderPreservingCounter = 1 << 23, +}; + +// D3D10_SB_OPCODE_TYPE subset +enum class Opcode : uint32_t { + kAdd = 0, + kAnd = 1, + kBreak = 2, + kCall = 4, + kCallC = 5, + kCase = 6, + kContinue = 7, + kDefault = 10, + kDiscard = 13, + kDiv = 14, + kDP2 = 15, + kDP3 = 16, + kDP4 = 17, + kElse = 18, + kEndIf = 21, + kEndLoop = 22, + kEndSwitch = 23, + kEq = 24, + kExp = 25, + kFrc = 26, + kFToI = 27, + kFToU = 28, + kGE = 29, + kIAdd = 30, + kIf = 31, + kIEq = 32, + kIGE = 33, + kILT = 34, + kIMAd = 35, + kIMax = 36, + kIMin = 37, + kIMul = 38, + kINE = 39, + kIShL = 41, + kIToF = 43, + kLabel = 44, + kLd = 45, + kLdMS = 46, + kLog = 47, + kLoop = 48, + kLT = 49, + kMAd = 50, + kMin = 51, + kMax = 52, + kCustomData = 53, + kMov = 54, + kMovC = 55, + kMul = 56, + kNE = 57, + kNot = 59, + kOr = 60, + kRet = 62, + kRetC = 63, + kRoundNE = 64, + kRoundNI = 65, + kRoundZ = 67, + kRSq = 68, + kSampleL = 72, + kSampleD = 73, + kSqRt = 75, + kSwitch = 76, + kSinCos = 77, + kUDiv = 78, + kULT = 79, + kUGE = 80, + kUMul = 81, + kUMAd = 82, + kUMax = 83, + kUMin = 84, + kUShR = 85, + kUToF = 86, + kXOr = 87, + kDclResource = 88, + kDclConstantBuffer = 89, + kDclSampler = 90, + kDclOutputTopology = 92, + kDclInputPrimitive = 93, + kDclMaxOutputVertexCount = 94, + kDclInput = 95, + kDclInputSGV = 96, + kDclInputSIV = 97, + kDclInputPS = 98, + kDclInputPSSGV = 99, + kDclInputPSSIV = 100, + kDclOutput = 101, + kDclOutputSIV = 103, + kDclTemps = 104, + kDclIndexableTemp = 105, + kDclGlobalFlags = 106, + kLOD = 108, + kEmitStream = 117, + kCutStream = 118, + kEmitThenCutStream = 119, + kDerivRTXCoarse = 122, + kDerivRTXFine = 123, + kDerivRTYCoarse = 124, + kDerivRTYFine = 125, + kRcp = 129, + kF32ToF16 = 130, + kF16ToF32 = 131, + kFirstBitHi = 135, + kFirstBitLo = 136, + kUBFE = 138, + kIBFE = 139, + kBFI = 140, + kBFRev = 141, + kDclStream = 143, + kDclInputControlPointCount = 147, + kDclTessDomain = 149, + kDclThreadGroup = 155, + kDclUnorderedAccessViewTyped = 156, + kDclUnorderedAccessViewRaw = 157, + kDclResourceRaw = 161, + kLdUAVTyped = 163, + kStoreUAVTyped = 164, + kLdRaw = 165, + kStoreRaw = 166, + kAtomicAnd = 169, + kAtomicOr = 170, + kEvalSampleIndex = 204, + kEvalCentroid = 205, +}; + +// D3D10_SB_EXTENDED_OPCODE_TYPE +enum class ExtendedOpcodeType : uint32_t { + kEmpty, + kSampleControls, + kResourceDim, + kResourceReturnType, +}; + +constexpr uint32_t OpcodeToken(Opcode opcode, uint32_t operands_length, bool saturate = false, + uint32_t extended_opcode_count = 0) { + return uint32_t(opcode) | (saturate ? (uint32_t(1) << 13) : 0) | + ((uint32_t(1) + extended_opcode_count + operands_length) << 24) | + (extended_opcode_count ? (uint32_t(1) << 31) : 0); +} + +constexpr uint32_t GetOpcodeTokenInstructionLength(uint32_t opcode_token) { + return (opcode_token >> 24) & ((UINT32_C(1) << 7) - 1); +} + +constexpr uint32_t SampleControlsExtendedOpcodeToken(int32_t aoffimmi_u, int32_t aoffimmi_v, + int32_t aoffimmi_w, bool extended = false) { + return uint32_t(ExtendedOpcodeType::kSampleControls) | + ((uint32_t(aoffimmi_u) & uint32_t(0b1111)) << 9) | + ((uint32_t(aoffimmi_v) & uint32_t(0b1111)) << 13) | + ((uint32_t(aoffimmi_w) & uint32_t(0b1111)) << 17) | (extended ? (uint32_t(1) << 31) : 0); +} + +constexpr uint32_t ResourceReturnTypeToken(ResourceReturnType x, ResourceReturnType y, + ResourceReturnType z, ResourceReturnType w) { + return uint32_t(x) | (uint32_t(y) << 4) | (uint32_t(z) << 8) | (uint32_t(w) << 12); +} + +// Even if a texture or a typed buffer has less than 4 components, it has the +// same return type specified for all 4 in its dcl instruction. +constexpr uint32_t ResourceReturnTypeX4Token(ResourceReturnType xyzw) { + return ResourceReturnTypeToken(xyzw, xyzw, xyzw, xyzw); +} + +// Assembler appending to the shader program code vector. +class Assembler { + public: + Assembler(std::vector& code, Statistics& stat) : code_(code), stat_(stat) {} + + void OpAdd(const Dest& dest, const Src& src0, const Src& src1, bool saturate = false) { + EmitAluOp(Opcode::kAdd, 0b00, dest, src0, src1, saturate); + ++stat_.float_instruction_count; + } + void OpAnd(const Dest& dest, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kAnd, 0b11, dest, src0, src1); + ++stat_.uint_instruction_count; + } + void OpBreak() { + code_.push_back(OpcodeToken(Opcode::kBreak, 0)); + ++stat_.instruction_count; + } + void OpCall(const Src& label) { + EmitFlowOp(Opcode::kCall, label); + ++stat_.static_flow_control_count; + } + void OpCallC(bool test, const Src& src, const Src& label) { + EmitFlowOp(Opcode::kCallC, src, label, test); + ++stat_.dynamic_flow_control_count; + } + void OpCase(const Src& src) { + EmitFlowOp(Opcode::kCase, src); + ++stat_.static_flow_control_count; + } + void OpContinue() { + code_.push_back(OpcodeToken(Opcode::kContinue, 0)); + ++stat_.instruction_count; + } + void OpDefault() { + code_.push_back(OpcodeToken(Opcode::kDefault, 0)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + } + void OpDiscard(bool test, const Src& src) { EmitFlowOp(Opcode::kDiscard, src, test); } + void OpDiv(const Dest& dest, const Src& src0, const Src& src1, bool saturate = false) { + EmitAluOp(Opcode::kDiv, 0b00, dest, src0, src1, saturate); + ++stat_.float_instruction_count; + } + void OpDP2(const Dest& dest, const Src& src0, const Src& src1, bool saturate = false) { + uint32_t operands_length = dest.GetLength() + src0.GetLength(0b0011) + src1.GetLength(0b0011); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(Opcode::kDP2, operands_length, saturate)); + dest.Write(code_); + src0.Write(code_, false, 0b0011); + src1.Write(code_, false, 0b0011); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + void OpDP3(const Dest& dest, const Src& src0, const Src& src1, bool saturate = false) { + uint32_t operands_length = dest.GetLength() + src0.GetLength(0b0111) + src1.GetLength(0b0111); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(Opcode::kDP3, operands_length, saturate)); + dest.Write(code_); + src0.Write(code_, false, 0b0111); + src1.Write(code_, false, 0b0111); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + void OpDP4(const Dest& dest, const Src& src0, const Src& src1, bool saturate = false) { + uint32_t operands_length = dest.GetLength() + src0.GetLength(0b1111) + src1.GetLength(0b1111); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(Opcode::kDP4, operands_length, saturate)); + dest.Write(code_); + src0.Write(code_, false, 0b1111); + src1.Write(code_, false, 0b1111); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + void OpElse() { + code_.push_back(OpcodeToken(Opcode::kElse, 0)); + ++stat_.instruction_count; + } + void OpEndIf() { + code_.push_back(OpcodeToken(Opcode::kEndIf, 0)); + ++stat_.instruction_count; + } + void OpEndLoop() { + code_.push_back(OpcodeToken(Opcode::kEndLoop, 0)); + ++stat_.instruction_count; + } + void OpEndSwitch() { + code_.push_back(OpcodeToken(Opcode::kEndSwitch, 0)); + ++stat_.instruction_count; + } + void OpEq(const Dest& dest, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kEq, 0b00, dest, src0, src1); + ++stat_.float_instruction_count; + } + void OpExp(const Dest& dest, const Src& src, bool saturate = false) { + EmitAluOp(Opcode::kExp, 0b0, dest, src, saturate); + ++stat_.float_instruction_count; + } + void OpFrc(const Dest& dest, const Src& src, bool saturate = false) { + EmitAluOp(Opcode::kFrc, 0b0, dest, src, saturate); + ++stat_.float_instruction_count; + } + void OpFToI(const Dest& dest, const Src& src) { + EmitAluOp(Opcode::kFToI, 0b0, dest, src); + ++stat_.conversion_instruction_count; + } + void OpFToU(const Dest& dest, const Src& src) { + EmitAluOp(Opcode::kFToU, 0b0, dest, src); + ++stat_.conversion_instruction_count; + } + void OpGE(const Dest& dest, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kGE, 0b00, dest, src0, src1); + ++stat_.float_instruction_count; + } + void OpIAdd(const Dest& dest, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kIAdd, 0b11, dest, src0, src1); + ++stat_.int_instruction_count; + } + void OpIf(bool test, const Src& src) { + EmitFlowOp(Opcode::kIf, src, test); + ++stat_.dynamic_flow_control_count; + } + void OpIEq(const Dest& dest, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kIEq, 0b11, dest, src0, src1); + ++stat_.int_instruction_count; + } + void OpIGE(const Dest& dest, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kIGE, 0b11, dest, src0, src1); + ++stat_.int_instruction_count; + } + void OpILT(const Dest& dest, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kILT, 0b11, dest, src0, src1); + ++stat_.int_instruction_count; + } + void OpIMAd(const Dest& dest, const Src& mul0, const Src& mul1, const Src& add) { + EmitAluOp(Opcode::kIMAd, 0b111, dest, mul0, mul1, add); + ++stat_.int_instruction_count; + } + void OpIMax(const Dest& dest, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kIMax, 0b11, dest, src0, src1); + ++stat_.int_instruction_count; + } + void OpIMin(const Dest& dest, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kIMin, 0b11, dest, src0, src1); + ++stat_.int_instruction_count; + } + void OpIMul(const Dest& dest_hi, const Dest& dest_lo, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kIMul, 0b11, dest_hi, dest_lo, src0, src1); + ++stat_.int_instruction_count; + } + void OpINE(const Dest& dest, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kINE, 0b11, dest, src0, src1); + ++stat_.int_instruction_count; + } + void OpIShL(const Dest& dest, const Src& value, const Src& shift) { + EmitAluOp(Opcode::kIShL, 0b11, dest, value, shift); + ++stat_.int_instruction_count; + } + void OpIToF(const Dest& dest, const Src& src) { + EmitAluOp(Opcode::kIToF, 0b1, dest, src); + ++stat_.conversion_instruction_count; + } + void OpLabel(const Src& label) { + // The label is source, not destination, for simplicity, to unify it will + // call/callc (in DXBC it's just a zero-component label operand). + uint32_t operands_length = label.GetLength(0b0000); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(Opcode::kLabel, operands_length)); + label.Write(code_, true, 0b0000); + // Doesn't count towards stat_.instruction_count. + } + void OpLd(const Dest& dest, const Src& address, uint32_t address_mask, const Src& resource, + int32_t aoffimmi_u = 0, int32_t aoffimmi_v = 0, int32_t aoffimmi_w = 0) { + uint32_t dest_write_mask = dest.GetMask(); + uint32_t sample_controls = 0; + if (aoffimmi_u || aoffimmi_v || aoffimmi_w) { + sample_controls = SampleControlsExtendedOpcodeToken(aoffimmi_u, aoffimmi_v, aoffimmi_w); + } + uint32_t operands_length = dest.GetLength() + address.GetLength(address_mask, true) + + resource.GetLength(dest_write_mask, true); + code_.reserve(code_.size() + 1 + (sample_controls ? 1 : 0) + operands_length); + code_.push_back(OpcodeToken(Opcode::kLd, operands_length, false, sample_controls ? 1 : 0)); + if (sample_controls) { + code_.push_back(sample_controls); + } + dest.Write(code_); + address.Write(code_, false, address_mask, true); + resource.Write(code_, false, dest_write_mask, true); + ++stat_.instruction_count; + ++stat_.texture_load_instructions; + } + void OpLdMS(const Dest& dest, const Src& address, uint32_t address_mask, const Src& resource, + const Src& sample_index, int32_t aoffimmi_u = 0, int32_t aoffimmi_v = 0) { + uint32_t dest_write_mask = dest.GetMask(); + uint32_t sample_controls = 0; + if (aoffimmi_u || aoffimmi_v) { + sample_controls = SampleControlsExtendedOpcodeToken(aoffimmi_u, aoffimmi_v, 0); + } + uint32_t operands_length = dest.GetLength() + address.GetLength(address_mask, true) + + resource.GetLength(dest_write_mask, true) + + sample_index.GetLength(0b0000); + code_.reserve(code_.size() + 1 + (sample_controls ? 1 : 0) + operands_length); + code_.push_back(OpcodeToken(Opcode::kLdMS, operands_length, false, sample_controls ? 1 : 0)); + if (sample_controls) { + code_.push_back(sample_controls); + } + dest.Write(code_); + address.Write(code_, false, address_mask, true); + resource.Write(code_, false, dest_write_mask, true); + sample_index.Write(code_, true, 0b0000); + ++stat_.instruction_count; + ++stat_.texture_load_instructions; + } + void OpLog(const Dest& dest, const Src& src, bool saturate = false) { + EmitAluOp(Opcode::kLog, 0b0, dest, src, saturate); + ++stat_.float_instruction_count; + } + void OpLoop() { + code_.push_back(OpcodeToken(Opcode::kLoop, 0)); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + } + void OpLT(const Dest& dest, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kLT, 0b00, dest, src0, src1); + ++stat_.float_instruction_count; + } + void OpMAd(const Dest& dest, const Src& mul0, const Src& mul1, const Src& add, + bool saturate = false) { + EmitAluOp(Opcode::kMAd, 0b000, dest, mul0, mul1, add, saturate); + ++stat_.float_instruction_count; + } + void OpMin(const Dest& dest, const Src& src0, const Src& src1, bool saturate = false) { + EmitAluOp(Opcode::kMin, 0b00, dest, src0, src1, saturate); + ++stat_.float_instruction_count; + } + void OpMax(const Dest& dest, const Src& src0, const Src& src1, bool saturate = false) { + EmitAluOp(Opcode::kMax, 0b00, dest, src0, src1, saturate); + ++stat_.float_instruction_count; + } + // Returns a pointer for writing the custom data to. + void* OpCustomData(CustomDataClass custom_data_class, uint32_t length_bytes) { + uint32_t length_bytes_aligned = rex::align(length_bytes, uint32_t(sizeof(uint32_t))); + uint32_t total_length_dwords = length_bytes_aligned / sizeof(uint32_t) + 2; + size_t offset_dwords = code_.size(); + code_.resize(offset_dwords + total_length_dwords); + uint32_t* data = code_.data() + offset_dwords; + // Different opcode encoding (no size). + *(data++) = uint32_t(Opcode::kCustomData) | (uint32_t(custom_data_class) << 11); + *(data++) = total_length_dwords; + // Don't leave uninitialized data, and make sure multiple uses of the + // assembler with the same input give the same DXBC for driver shader + // caching. + std::memset(reinterpret_cast(data) + length_bytes, dxbc::kAlignmentPadding, + length_bytes_aligned - length_bytes); + return data; + } + void OpMov(const Dest& dest, const Src& src, bool saturate = false) { + EmitAluOp(Opcode::kMov, 0b0, dest, src, saturate); + if (dest.type_ == OperandType::kIndexableTemp || src.type_ == OperandType::kIndexableTemp) { + ++stat_.array_instruction_count; + } else { + ++stat_.mov_instruction_count; + } + } + void OpMovC(const Dest& dest, const Src& test, const Src& src_nz, const Src& src_z, + bool saturate = false) { + EmitAluOp(Opcode::kMovC, 0b001, dest, test, src_nz, src_z, saturate); + ++stat_.movc_instruction_count; + } + void OpMul(const Dest& dest, const Src& src0, const Src& src1, bool saturate = false) { + EmitAluOp(Opcode::kMul, 0b00, dest, src0, src1, saturate); + ++stat_.float_instruction_count; + } + void OpNE(const Dest& dest, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kNE, 0b00, dest, src0, src1); + ++stat_.float_instruction_count; + } + void OpNot(const Dest& dest, const Src& src) { + EmitAluOp(Opcode::kNot, 0b1, dest, src); + ++stat_.uint_instruction_count; + } + void OpOr(const Dest& dest, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kOr, 0b11, dest, src0, src1); + ++stat_.uint_instruction_count; + } + void OpRet() { + code_.push_back(OpcodeToken(Opcode::kRet, 0)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + } + void OpRetC(bool test, const Src& src) { + EmitFlowOp(Opcode::kRetC, src, test); + ++stat_.dynamic_flow_control_count; + } + void OpRoundNE(const Dest& dest, const Src& src, bool saturate = false) { + EmitAluOp(Opcode::kRoundNE, 0b0, dest, src, saturate); + ++stat_.float_instruction_count; + } + void OpRoundNI(const Dest& dest, const Src& src, bool saturate = false) { + EmitAluOp(Opcode::kRoundNI, 0b0, dest, src, saturate); + ++stat_.float_instruction_count; + } + void OpRoundZ(const Dest& dest, const Src& src, bool saturate = false) { + EmitAluOp(Opcode::kRoundZ, 0b0, dest, src, saturate); + ++stat_.float_instruction_count; + } + void OpRSq(const Dest& dest, const Src& src, bool saturate = false) { + EmitAluOp(Opcode::kRSq, 0b0, dest, src, saturate); + ++stat_.float_instruction_count; + } + void OpSampleL(const Dest& dest, const Src& address, uint32_t address_components, + const Src& resource, const Src& sampler, const Src& lod, int32_t aoffimmi_u = 0, + int32_t aoffimmi_v = 0, int32_t aoffimmi_w = 0) { + uint32_t dest_write_mask = dest.GetMask(); + uint32_t sample_controls = 0; + if (aoffimmi_u || aoffimmi_v || aoffimmi_w) { + sample_controls = SampleControlsExtendedOpcodeToken(aoffimmi_u, aoffimmi_v, aoffimmi_w); + } + uint32_t address_mask = (1 << address_components) - 1; + uint32_t operands_length = dest.GetLength() + address.GetLength(address_mask) + + resource.GetLength(dest_write_mask, true) + + sampler.GetLength(0b0000) + lod.GetLength(0b0000); + code_.reserve(code_.size() + 1 + (sample_controls ? 1 : 0) + operands_length); + code_.push_back(OpcodeToken(Opcode::kSampleL, operands_length, false, sample_controls ? 1 : 0)); + if (sample_controls) { + code_.push_back(sample_controls); + } + dest.Write(code_); + address.Write(code_, false, address_mask); + resource.Write(code_, false, dest_write_mask, true); + sampler.Write(code_, false, 0b0000); + lod.Write(code_, false, 0b0000); + ++stat_.instruction_count; + ++stat_.texture_normal_instructions; + } + void OpSampleD(const Dest& dest, const Src& address, uint32_t address_components, + const Src& resource, const Src& sampler, const Src& x_derivatives, + const Src& y_derivatives, uint32_t derivatives_components, int32_t aoffimmi_u = 0, + int32_t aoffimmi_v = 0, int32_t aoffimmi_w = 0) { + // If the address is 1-component, the derivatives are 1-component, if the + // address is 4-component, the derivatives are 4-component. + assert_true(derivatives_components <= address_components); + uint32_t dest_write_mask = dest.GetMask(); + uint32_t sample_controls = 0; + if (aoffimmi_u || aoffimmi_v || aoffimmi_w) { + sample_controls = SampleControlsExtendedOpcodeToken(aoffimmi_u, aoffimmi_v, aoffimmi_w); + } + uint32_t address_mask = (1 << address_components) - 1; + uint32_t derivatives_mask = (1 << derivatives_components) - 1; + uint32_t operands_length = dest.GetLength() + address.GetLength(address_mask) + + resource.GetLength(dest_write_mask, true) + + sampler.GetLength(0b0000) + + x_derivatives.GetLength(derivatives_mask, address_components > 1) + + y_derivatives.GetLength(derivatives_mask, address_components > 1); + code_.reserve(code_.size() + 1 + (sample_controls ? 1 : 0) + operands_length); + code_.push_back(OpcodeToken(Opcode::kSampleD, operands_length, false, sample_controls ? 1 : 0)); + if (sample_controls) { + code_.push_back(sample_controls); + } + dest.Write(code_); + address.Write(code_, false, address_mask); + resource.Write(code_, false, dest_write_mask, true); + sampler.Write(code_, false, 0b0000); + x_derivatives.Write(code_, false, derivatives_mask, address_components > 1); + y_derivatives.Write(code_, false, derivatives_mask, address_components > 1); + ++stat_.instruction_count; + ++stat_.texture_gradient_instructions; + } + void OpSqRt(const Dest& dest, const Src& src, bool saturate = false) { + EmitAluOp(Opcode::kSqRt, 0b0, dest, src, saturate); + ++stat_.float_instruction_count; + } + void OpSwitch(const Src& src) { + EmitFlowOp(Opcode::kSwitch, src); + ++stat_.dynamic_flow_control_count; + } + void OpSinCos(const Dest& dest_sin, const Dest& dest_cos, const Src& src, bool saturate = false) { + EmitAluOp(Opcode::kSinCos, 0b0, dest_sin, dest_cos, src, saturate); + ++stat_.float_instruction_count; + } + void OpUDiv(const Dest& dest_quotient, const Dest& dest_remainder, const Src& src0, + const Src& src1) { + EmitAluOp(Opcode::kUDiv, 0b11, dest_quotient, dest_remainder, src0, src1); + ++stat_.uint_instruction_count; + } + void OpULT(const Dest& dest, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kULT, 0b11, dest, src0, src1); + ++stat_.uint_instruction_count; + } + void OpUGE(const Dest& dest, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kUGE, 0b11, dest, src0, src1); + ++stat_.uint_instruction_count; + } + void OpUMul(const Dest& dest_hi, const Dest& dest_lo, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kUMul, 0b11, dest_hi, dest_lo, src0, src1); + ++stat_.uint_instruction_count; + } + void OpUMAd(const Dest& dest, const Src& mul0, const Src& mul1, const Src& add) { + EmitAluOp(Opcode::kUMAd, 0b111, dest, mul0, mul1, add); + ++stat_.uint_instruction_count; + } + void OpUMax(const Dest& dest, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kUMax, 0b11, dest, src0, src1); + ++stat_.uint_instruction_count; + } + void OpUMin(const Dest& dest, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kUMin, 0b11, dest, src0, src1); + ++stat_.uint_instruction_count; + } + void OpUShR(const Dest& dest, const Src& value, const Src& shift) { + EmitAluOp(Opcode::kUShR, 0b11, dest, value, shift); + ++stat_.uint_instruction_count; + } + void OpUToF(const Dest& dest, const Src& src) { + EmitAluOp(Opcode::kUToF, 0b1, dest, src); + ++stat_.conversion_instruction_count; + } + void OpXOr(const Dest& dest, const Src& src0, const Src& src1) { + EmitAluOp(Opcode::kXOr, 0b11, dest, src0, src1); + ++stat_.uint_instruction_count; + } + void OpDclResource(ResourceDimension dimension, uint32_t return_type_token, const Src& operand, + uint32_t space = 0) { + uint32_t operands_length = operand.GetLength(0b1111, false); + code_.reserve(code_.size() + 3 + operands_length); + code_.push_back(OpcodeToken(Opcode::kDclResource, 2 + operands_length) | + (uint32_t(dimension) << 11)); + operand.Write(code_, false, 0b1111, false, true); + code_.push_back(return_type_token); + code_.push_back(space); + } + // The order of constant buffer declarations in a shader indicates their + // relative priority from highest to lowest (hint to driver). + void OpDclConstantBuffer( + const Src& operand, uint32_t size_vectors, + ConstantBufferAccessPattern access_pattern = ConstantBufferAccessPattern::kImmediateIndexed, + uint32_t space = 0) { + uint32_t operands_length = operand.GetLength(0b1111, false); + code_.reserve(code_.size() + 3 + operands_length); + code_.push_back(OpcodeToken(Opcode::kDclConstantBuffer, 2 + operands_length) | + (uint32_t(access_pattern) << 11)); + operand.Write(code_, false, 0b1111, false, true); + code_.push_back(size_vectors); + code_.push_back(space); + } + void OpDclSampler(const Src& operand, SamplerMode mode = SamplerMode::kDefault, + uint32_t space = 0) { + uint32_t operands_length = operand.GetLength(0b1111, false); + code_.reserve(code_.size() + 2 + operands_length); + code_.push_back(OpcodeToken(Opcode::kDclSampler, 1 + operands_length) | (uint32_t(mode) << 11)); + operand.Write(code_, false, 0b1111, false, true); + code_.push_back(space); + } + // In geometry shaders, only kPointList, kLineStrip and kTriangleStrip are + // allowed. + void OpDclOutputTopology(PrimitiveTopology output_topology) { + code_.push_back(OpcodeToken(Opcode::kDclOutputTopology, 0) | (uint32_t(output_topology) << 11)); + stat_.gs_output_topology = output_topology; + } + // In geometry shaders, only kPoint, kLine, kTriangle, kLineWithAdjacency and + // kTriangleWithAdjacency are allowed. + void OpDclInputPrimitive(Primitive input_primitive) { + code_.push_back(OpcodeToken(Opcode::kDclInputPrimitive, 0) | (uint32_t(input_primitive) << 11)); + stat_.input_primitive = input_primitive; + } + // Returns the index of the count written in the code_ vector. + size_t OpDclMaxOutputVertexCount(uint32_t count) { + code_.reserve(code_.size() + 2); + code_.push_back(OpcodeToken(Opcode::kDclMaxOutputVertexCount, 1)); + code_.push_back(count); + stat_.gs_max_output_vertex_count = count; + return code_.size() - 1; + } + void OpDclInput(const Dest& operand) { + uint32_t operands_length = operand.GetLength(); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(Opcode::kDclInput, operands_length)); + operand.Write(code_, true); + ++stat_.dcl_count; + } + void OpDclInputSGV(const Dest& operand, Name name) { + uint32_t operands_length = operand.GetLength(); + code_.reserve(code_.size() + 2 + operands_length); + code_.push_back(OpcodeToken(Opcode::kDclInputSGV, 1 + operands_length)); + operand.Write(code_, true); + code_.push_back(uint32_t(name)); + ++stat_.dcl_count; + } + void OpDclInputSIV(const Dest& operand, Name name) { + uint32_t operands_length = operand.GetLength(); + code_.reserve(code_.size() + 2 + operands_length); + code_.push_back(OpcodeToken(Opcode::kDclInputSIV, 1 + operands_length)); + operand.Write(code_, true); + code_.push_back(uint32_t(name)); + ++stat_.dcl_count; + } + void OpDclInputPS(InterpolationMode interpolation_mode, const Dest& operand) { + uint32_t operands_length = operand.GetLength(); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(Opcode::kDclInputPS, operands_length) | + (uint32_t(interpolation_mode) << 11)); + operand.Write(code_, true); + ++stat_.dcl_count; + } + void OpDclInputPSSGV(const Dest& operand, Name name) { + uint32_t operands_length = operand.GetLength(); + code_.reserve(code_.size() + 2 + operands_length); + // Constant interpolation mode is set in FXC output at least for + // SV_IsFrontFace, despite the comment in d3d12TokenizedProgramFormat.hpp + // saying bits 11:23 are ignored. + code_.push_back(OpcodeToken(Opcode::kDclInputPSSGV, 1 + operands_length) | + (uint32_t(InterpolationMode::kConstant) << 11)); + operand.Write(code_, true); + code_.push_back(uint32_t(name)); + ++stat_.dcl_count; + } + void OpDclInputPSSIV(InterpolationMode interpolation_mode, const Dest& operand, Name name) { + uint32_t operands_length = operand.GetLength(); + code_.reserve(code_.size() + 2 + operands_length); + code_.push_back(OpcodeToken(Opcode::kDclInputPSSIV, 1 + operands_length) | + (uint32_t(interpolation_mode) << 11)); + operand.Write(code_, true); + code_.push_back(uint32_t(name)); + ++stat_.dcl_count; + } + void OpDclOutput(const Dest& operand) { + uint32_t operands_length = operand.GetLength(); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(Opcode::kDclOutput, operands_length)); + operand.Write(code_, true); + ++stat_.dcl_count; + } + void OpDclOutputSIV(const Dest& operand, Name name) { + uint32_t operands_length = operand.GetLength(); + code_.reserve(code_.size() + 2 + operands_length); + code_.push_back(OpcodeToken(Opcode::kDclOutputSIV, 1 + operands_length)); + operand.Write(code_, true); + code_.push_back(uint32_t(name)); + ++stat_.dcl_count; + } + // Returns the index of the count written in the code_ vector. + size_t OpDclTemps(uint32_t count) { + code_.reserve(code_.size() + 2); + code_.push_back(OpcodeToken(Opcode::kDclTemps, 1)); + code_.push_back(count); + stat_.temp_register_count = count; + return code_.size() - 1; + } + void OpDclIndexableTemp(uint32_t index, uint32_t count, uint32_t component_count) { + code_.reserve(code_.size() + 4); + code_.push_back(OpcodeToken(Opcode::kDclIndexableTemp, 3)); + code_.push_back(index); + code_.push_back(count); + code_.push_back(component_count); + stat_.temp_array_count += count; + } + // flags are GlobalFlags. + void OpDclGlobalFlags(uint32_t flags) { + code_.push_back(OpcodeToken(Opcode::kDclGlobalFlags, 0) | flags); + } + void OpLOD(const Dest& dest, const Src& address, uint32_t address_components, const Src& resource, + const Src& sampler) { + uint32_t dest_write_mask = dest.GetMask(); + uint32_t address_mask = (1 << address_components) - 1; + uint32_t operands_length = dest.GetLength() + address.GetLength(address_mask) + + resource.GetLength(dest_write_mask) + sampler.GetLength(0b0000); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(Opcode::kLOD, operands_length)); + dest.Write(code_); + address.Write(code_, false, address_mask); + resource.Write(code_, false, dest_write_mask); + sampler.Write(code_, false, 0b0000); + ++stat_.instruction_count; + ++stat_.lod_instructions; + } + void OpEmitStream(const Dest& stream) { + uint32_t operands_length = stream.GetLength(); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(Opcode::kEmitStream, operands_length)); + stream.Write(code_); + ++stat_.instruction_count; + ++stat_.emit_instruction_count; + } + void OpCutStream(const Dest& stream) { + uint32_t operands_length = stream.GetLength(); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(Opcode::kCutStream, operands_length)); + stream.Write(code_); + ++stat_.instruction_count; + ++stat_.cut_instruction_count; + } + // Don't use emit_then_cut_stream - crashes AMD Software: Adrenalin Edition + // 23.3.2 shader compiler on RDNA 3 if used conditionally. + void OpEmitThenCutStream(const Dest& stream) { + uint32_t operands_length = stream.GetLength(); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(Opcode::kEmitThenCutStream, operands_length)); + stream.Write(code_); + ++stat_.instruction_count; + // TODO(Triang3l): Verify if the instruction counts should be incremented + // this way (haven't been able to obtain this from FXC because it generates + // separate emit_stream and cut_stream, at least for Shader Model 5.1). + ++stat_.emit_instruction_count; + ++stat_.cut_instruction_count; + } + void OpDerivRTXCoarse(const Dest& dest, const Src& src, bool saturate = false) { + EmitAluOp(Opcode::kDerivRTXCoarse, 0b0, dest, src, saturate); + ++stat_.float_instruction_count; + } + void OpDerivRTXFine(const Dest& dest, const Src& src, bool saturate = false) { + EmitAluOp(Opcode::kDerivRTXFine, 0b0, dest, src, saturate); + ++stat_.float_instruction_count; + } + void OpDerivRTYCoarse(const Dest& dest, const Src& src, bool saturate = false) { + EmitAluOp(Opcode::kDerivRTYCoarse, 0b0, dest, src, saturate); + ++stat_.float_instruction_count; + } + void OpDerivRTYFine(const Dest& dest, const Src& src, bool saturate = false) { + EmitAluOp(Opcode::kDerivRTYFine, 0b0, dest, src, saturate); + ++stat_.float_instruction_count; + } + void OpRcp(const Dest& dest, const Src& src, bool saturate = false) { + EmitAluOp(Opcode::kRcp, 0b0, dest, src, saturate); + ++stat_.float_instruction_count; + } + void OpF32ToF16(const Dest& dest, const Src& src) { + EmitAluOp(Opcode::kF32ToF16, 0b0, dest, src); + ++stat_.conversion_instruction_count; + } + void OpF16ToF32(const Dest& dest, const Src& src) { + EmitAluOp(Opcode::kF16ToF32, 0b1, dest, src); + ++stat_.conversion_instruction_count; + } + void OpFirstBitHi(const Dest& dest, const Src& src) { + EmitAluOp(Opcode::kFirstBitHi, 0b1, dest, src); + ++stat_.uint_instruction_count; + } + void OpFirstBitLo(const Dest& dest, const Src& src) { + EmitAluOp(Opcode::kFirstBitLo, 0b1, dest, src); + ++stat_.uint_instruction_count; + } + void OpUBFE(const Dest& dest, const Src& width, const Src& offset, const Src& src) { + EmitAluOp(Opcode::kUBFE, 0b111, dest, width, offset, src); + ++stat_.uint_instruction_count; + } + void OpIBFE(const Dest& dest, const Src& width, const Src& offset, const Src& src) { + EmitAluOp(Opcode::kIBFE, 0b111, dest, width, offset, src); + ++stat_.int_instruction_count; + } + void OpBFI(const Dest& dest, const Src& width, const Src& offset, const Src& from, + const Src& to) { + EmitAluOp(Opcode::kBFI, 0b1111, dest, width, offset, from, to); + ++stat_.uint_instruction_count; + } + void OpBFRev(const Dest& dest, const Src& src) { + EmitAluOp(Opcode::kBFRev, 0b1, dest, src); + ++stat_.uint_instruction_count; + } + void OpDclStream(const Dest& stream) { + uint32_t operands_length = stream.GetLength(); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(Opcode::kDclStream, operands_length)); + stream.Write(code_, true); + } + void OpDclInputControlPointCount(uint32_t count) { + code_.push_back(OpcodeToken(Opcode::kDclInputControlPointCount, 0) | (count << 11)); + stat_.c_control_points = count; + } + void OpDclTessDomain(TessellatorDomain domain) { + code_.push_back(OpcodeToken(Opcode::kDclTessDomain, 0) | (uint32_t(domain) << 11)); + stat_.tessellator_domain = domain; + } + void OpDclThreadGroup(uint32_t x, uint32_t y, uint32_t z) { + code_.reserve(code_.size() + 4); + code_.push_back(OpcodeToken(Opcode::kDclThreadGroup, 3)); + code_.push_back(x); + code_.push_back(y); + code_.push_back(z); + } + // Possible flags are kUAVFlagGloballyCoherentAccess and + // kUAVFlagRasterizerOrderedAccess. + void OpDclUnorderedAccessViewTyped(ResourceDimension dimension, uint32_t flags, + uint32_t return_type_token, const Src& operand, + uint32_t space = 0) { + uint32_t operands_length = operand.GetLength(0b1111, false); + code_.reserve(code_.size() + 3 + operands_length); + code_.push_back(OpcodeToken(Opcode::kDclUnorderedAccessViewTyped, 2 + operands_length) | + (uint32_t(dimension) << 11) | flags); + operand.Write(code_, false, 0b1111, false, true); + code_.push_back(return_type_token); + code_.push_back(space); + } + // Possible flags are kUAVFlagGloballyCoherentAccess and + // kUAVFlagRasterizerOrderedAccess. + void OpDclUnorderedAccessViewRaw(uint32_t flags, const Src& operand, uint32_t space = 0) { + uint32_t operands_length = operand.GetLength(0b1111, false); + code_.reserve(code_.size() + 2 + operands_length); + code_.push_back(OpcodeToken(Opcode::kDclUnorderedAccessViewRaw, 1 + operands_length) | flags); + operand.Write(code_, true, 0b1111, false, true); + code_.push_back(space); + } + void OpDclResourceRaw(const Src& operand, uint32_t space = 0) { + uint32_t operands_length = operand.GetLength(0b1111, false); + code_.reserve(code_.size() + 2 + operands_length); + code_.push_back(OpcodeToken(Opcode::kDclResourceRaw, 1 + operands_length)); + operand.Write(code_, true, 0b1111, false, true); + code_.push_back(space); + } + void OpLdUAVTyped(const Dest& dest, const Src& address, uint32_t address_components, + const Src& uav) { + uint32_t dest_write_mask = dest.GetMask(); + uint32_t address_mask = (1 << address_components) - 1; + uint32_t operands_length = dest.GetLength() + address.GetLength(address_mask, true) + + uav.GetLength(dest_write_mask, true); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(Opcode::kLdUAVTyped, operands_length)); + dest.Write(code_); + address.Write(code_, true, address_mask, true); + uav.Write(code_, false, dest_write_mask, true); + ++stat_.instruction_count; + ++stat_.texture_load_instructions; + } + void OpStoreUAVTyped(const Dest& dest, const Src& address, uint32_t address_components, + const Src& value) { + uint32_t dest_write_mask = dest.GetMask(); + // Typed UAV writes don't support write masking. + assert_true(dest_write_mask == 0b1111); + uint32_t address_mask = (1 << address_components) - 1; + uint32_t operands_length = + dest.GetLength() + address.GetLength(address_mask, true) + value.GetLength(dest_write_mask); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(Opcode::kStoreUAVTyped, operands_length)); + dest.Write(code_); + address.Write(code_, true, address_mask, true); + value.Write(code_, false, dest_write_mask); + ++stat_.instruction_count; + ++stat_.c_texture_store_instructions; + } + void OpLdRaw(const Dest& dest, const Src& byte_offset, const Src& src) { + // For Load, FXC emits code for writing to any component of the destination, + // with xxxx swizzle of the source SRV/UAV. + // For Load2/Load3/Load4, it's xy/xyz/xyzw write mask and xyxx/xyzx/xyzw + // swizzle. + uint32_t dest_write_mask = dest.GetMask(); + assert_true(dest_write_mask == 0b0001 || dest_write_mask == 0b0010 || + dest_write_mask == 0b0100 || dest_write_mask == 0b1000 || + dest_write_mask == 0b0011 || dest_write_mask == 0b0111 || + dest_write_mask == 0b1111); + uint32_t component_count = rex::bit_count(dest_write_mask); + assert_true((src.swizzle_ & ((1 << (component_count * 2)) - 1)) == + (Src::kXYZW & ((1 << (component_count * 2)) - 1))); + uint32_t src_mask = (1 << component_count) - 1; + uint32_t operands_length = + dest.GetLength() + byte_offset.GetLength(0b0000) + src.GetLength(src_mask, true); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(Opcode::kLdRaw, operands_length)); + dest.Write(code_); + byte_offset.Write(code_, true, 0b0000); + src.Write(code_, true, src_mask, true); + ++stat_.instruction_count; + ++stat_.texture_load_instructions; + } + void OpStoreRaw(const Dest& dest, const Src& byte_offset, const Src& value) { + uint32_t dest_write_mask = dest.GetMask(); + assert_true(dest_write_mask == 0b0001 || dest_write_mask == 0b0011 || + dest_write_mask == 0b0111 || dest_write_mask == 0b1111); + uint32_t operands_length = + dest.GetLength() + byte_offset.GetLength(0b0000) + value.GetLength(dest_write_mask); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(Opcode::kStoreRaw, operands_length)); + dest.Write(code_); + byte_offset.Write(code_, true, 0b0000); + value.Write(code_, true, dest_write_mask); + ++stat_.instruction_count; + ++stat_.c_texture_store_instructions; + } + void OpAtomicAnd(const Dest& dest, const Src& address, uint32_t address_components, + const Src& value) { + EmitAtomicOp(Opcode::kAtomicAnd, dest, address, address_components, value); + } + void OpAtomicOr(const Dest& dest, const Src& address, uint32_t address_components, + const Src& value) { + EmitAtomicOp(Opcode::kAtomicOr, dest, address, address_components, value); + } + void OpEvalSampleIndex(const Dest& dest, const Src& value, const Src& sample_index) { + uint32_t dest_write_mask = dest.GetMask(); + uint32_t operands_length = + dest.GetLength() + value.GetLength(dest_write_mask) + sample_index.GetLength(0b0000); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(Opcode::kEvalSampleIndex, operands_length)); + dest.Write(code_); + value.Write(code_, false, dest_write_mask); + sample_index.Write(code_, true, 0b0000); + ++stat_.instruction_count; + } + void OpEvalCentroid(const Dest& dest, const Src& value) { + uint32_t dest_write_mask = dest.GetMask(); + uint32_t operands_length = dest.GetLength() + value.GetLength(dest_write_mask); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(Opcode::kEvalCentroid, operands_length)); + dest.Write(code_); + value.Write(code_, false, dest_write_mask); + ++stat_.instruction_count; + } + + private: + void EmitAluOp(Opcode opcode, uint32_t src_are_integer, const Dest& dest, const Src& src, + bool saturate = false) { + uint32_t dest_write_mask = dest.GetMask(); + uint32_t operands_length = dest.GetLength() + src.GetLength(dest_write_mask); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(opcode, operands_length, saturate)); + dest.Write(code_); + src.Write(code_, (src_are_integer & 0b1) != 0, dest_write_mask); + ++stat_.instruction_count; + } + void EmitAluOp(Opcode opcode, uint32_t src_are_integer, const Dest& dest, const Src& src0, + const Src& src1, bool saturate = false) { + uint32_t dest_write_mask = dest.GetMask(); + uint32_t operands_length = + dest.GetLength() + src0.GetLength(dest_write_mask) + src1.GetLength(dest_write_mask); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(opcode, operands_length, saturate)); + dest.Write(code_); + src0.Write(code_, (src_are_integer & 0b1) != 0, dest_write_mask); + src1.Write(code_, (src_are_integer & 0b10) != 0, dest_write_mask); + ++stat_.instruction_count; + } + void EmitAluOp(Opcode opcode, uint32_t src_are_integer, const Dest& dest, const Src& src0, + const Src& src1, const Src& src2, bool saturate = false) { + uint32_t dest_write_mask = dest.GetMask(); + uint32_t operands_length = dest.GetLength() + src0.GetLength(dest_write_mask) + + src1.GetLength(dest_write_mask) + src2.GetLength(dest_write_mask); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(opcode, operands_length, saturate)); + dest.Write(code_); + src0.Write(code_, (src_are_integer & 0b1) != 0, dest_write_mask); + src1.Write(code_, (src_are_integer & 0b10) != 0, dest_write_mask); + src2.Write(code_, (src_are_integer & 0b100) != 0, dest_write_mask); + ++stat_.instruction_count; + } + void EmitAluOp(Opcode opcode, uint32_t src_are_integer, const Dest& dest, const Src& src0, + const Src& src1, const Src& src2, const Src& src3, bool saturate = false) { + uint32_t dest_write_mask = dest.GetMask(); + uint32_t operands_length = dest.GetLength() + src0.GetLength(dest_write_mask) + + src1.GetLength(dest_write_mask) + src2.GetLength(dest_write_mask) + + src3.GetLength(dest_write_mask); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(opcode, operands_length, saturate)); + dest.Write(code_); + src0.Write(code_, (src_are_integer & 0b1) != 0, dest_write_mask); + src1.Write(code_, (src_are_integer & 0b10) != 0, dest_write_mask); + src2.Write(code_, (src_are_integer & 0b100) != 0, dest_write_mask); + src3.Write(code_, (src_are_integer & 0b1000) != 0, dest_write_mask); + ++stat_.instruction_count; + } + void EmitAluOp(Opcode opcode, uint32_t src_are_integer, const Dest& dest0, const Dest& dest1, + const Src& src, bool saturate = false) { + uint32_t dest_write_mask = dest0.GetMask() | dest1.GetMask(); + uint32_t operands_length = + dest0.GetLength() + dest1.GetLength() + src.GetLength(dest_write_mask); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(opcode, operands_length, saturate)); + dest0.Write(code_); + dest1.Write(code_); + src.Write(code_, (src_are_integer & 0b1) != 0, dest_write_mask); + ++stat_.instruction_count; + } + void EmitAluOp(Opcode opcode, uint32_t src_are_integer, const Dest& dest0, const Dest& dest1, + const Src& src0, const Src& src1, bool saturate = false) { + uint32_t dest_write_mask = dest0.GetMask() | dest1.GetMask(); + uint32_t operands_length = dest0.GetLength() + dest1.GetLength() + + src0.GetLength(dest_write_mask) + src1.GetLength(dest_write_mask); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(opcode, operands_length, saturate)); + dest0.Write(code_); + dest1.Write(code_); + src0.Write(code_, (src_are_integer & 0b1) != 0, dest_write_mask); + src1.Write(code_, (src_are_integer & 0b10) != 0, dest_write_mask); + ++stat_.instruction_count; + } + void EmitFlowOp(Opcode opcode, const Src& src, bool test = false) { + uint32_t operands_length = src.GetLength(0b0000); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(opcode, operands_length) | (test ? (1 << 18) : 0)); + src.Write(code_, true, 0b0000); + ++stat_.instruction_count; + } + void EmitFlowOp(Opcode opcode, const Src& src0, const Src& src1, bool test = false) { + uint32_t operands_length = src0.GetLength(0b0000) + src1.GetLength(0b0000); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(opcode, operands_length) | (test ? (1 << 18) : 0)); + src0.Write(code_, true, 0b0000); + src1.Write(code_, true, 0b0000); + ++stat_.instruction_count; + } + void EmitAtomicOp(Opcode opcode, const Dest& dest, const Src& address, + uint32_t address_components, const Src& value) { + // Atomic operations require a 0-component memory destination. + assert_zero(dest.GetMask()); + uint32_t address_mask = (1 << address_components) - 1; + uint32_t operands_length = + dest.GetLength() + address.GetLength(address_mask) + value.GetLength(0b0001); + code_.reserve(code_.size() + 1 + operands_length); + code_.push_back(OpcodeToken(opcode, operands_length)); + dest.Write(code_); + address.Write(code_, true, address_mask); + value.Write(code_, true, 0b0001); + ++stat_.instruction_count; + ++stat_.c_interlocked_instructions; + } + + std::vector& code_; + Statistics& stat_; +}; + +} // namespace rex::graphics::dxbc diff --git a/include/rex/graphics/format/ucode.h b/include/rex/graphics/format/ucode.h new file mode 100644 index 0000000..6011d3c --- /dev/null +++ b/include/rex/graphics/format/ucode.h @@ -0,0 +1,2064 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include +#include +#include +#include + +// The XNA Game Studio 3.1 contains Graphics.ShaderCompiler.AssembleFromSource, +// which, for TargetPlatform.Xbox360, can validate and assemble Xbox 360 shader +// microcode from Xbox 360 and Direct3D 9 shader assembly, returning the binary, +// as well as validation warnings and errors and the disassembly via the warning +// output. It is the primary source of information about the binary encoding of +// the instructions, as well as valid usage of instruction parameters and +// sequences. +// https://www.microsoft.com/en-us/download/details.aspx?id=39 +// (XNAGS31_setup.exe) +// Xenia provides a tool, tools/shader-playground, that invokes the assembler, +// displays the binary and the disassembly from the official assembler, and also +// shows the disassembly generated by Xenia, and passes it back to the assembler +// to validate Xenia's microcode parsing and disassembly by checking if +// reassembling the disassembly results in the same binary. +// +// The behavior and the parameters of some of the instructions were previously +// documented on MSDN in the XNA Game Studio programming guide: +// http://web.archive.org/web/20081211005537/http://msdn.microsoft.com/en-us/library/bb313877.aspx +// +// A great amount of documentation, such as the R400 sequencer specification and +// the official emulator code, was made available during the LG Electronics, +// Inc. v. ATI Technologies ULC "Multi-thread Graphics Processing System" patent +// dispute IPR2015-00325, with the motion to seal having been denied due to "a +// strong public policy interest in making all information filed in an inter +// partes review publicly available". Most of the documents attached, however, +// cover early versions - the development process - of the R400 architecture, so +// there are some differences from the final Xenos GPU (DOT2ADDv is defined +// differently, for example, and MUL/ADD/SUB_CONST are missing). +// https://portal.unifiedpatents.com/ptab/case/IPR2015-00325 +// +// Also, the R600, while having a different 5-scalar, as opposed to vec4|scalar, +// parallelism model and instruction encodings and targeting Direct3D 10 rather +// that 9, inherits a lot of instructions and architectural concepts from the +// R400. +// https://www.x.org/docs/AMD/old/r600isa.pdf +// https://developer.amd.com/wordpress/media/2012/10/r600isa.pdf +// https://developer.amd.com/wordpress/media/2012/10/R600_Instruction_Set_Architecture.pdf + +// Parts of this code also come from the freedreno project: +// https://github.com/freedreno/freedreno/blob/master/includes/instr-a2xx.h +/* + * Copyright (c) 2012 Rob Clark + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +// Only 32-bit types (uint32_t, int32_t or enums with uint32_t / int32_t as the +// underlying type) are allowed in the bit fields here, as Visual C++ restarts +// packing when a field requires different alignment than the previous one. + +namespace rex::graphics::ucode { + +// Defines control flow opcodes used to schedule instructions. +enum class ControlFlowOpcode : uint32_t { + // No-op - used to fill space. + kNop = 0, + // Executes fetch or ALU instructions. + kExec = 1, + // Executes fetch or ALU instructions then ends execution. + kExecEnd = 2, + // Conditionally executes based on a bool const. + // PredicateClean = false. + kCondExec = 3, + // Conditionally executes based on a bool const then ends execution. + // PredicateClean = false. + // According to the IPR2015-00325 sequencer specification, execution ends only + // if the condition is actually met (unlike on the R600, where execution ends + // unconditionally if END_OF_PROGRAM is set in the control flow instruction). + // 4D5307ED has many shaders (used, in particular, in the Press Start screen + // background) with if / else in its tail done via cexece - cexece b130, then + // cexece !b130, and then an empty exece (if the condition was ignored, the + // second cexece would have never been reached). Also, the validator reports + // "Shader will try to execute instruction 3.0, but last possible instruction + // is 2.1" for a shader that contains just one cexece without an exece. + kCondExecEnd = 4, + // Conditionally executes based on the current predicate. + // Since 64 vertices or pixels are processed by each sequencer in the Xenos + // hardware, the actual condition is AND of the predicate values for all + // active (and not killed) invocations for (!p0) exec, and OR of them for + // (p0) exec - if any of the invocations passes the predicate check, all of + // them will enter the exec. This is according to the IPR2015-00325 sequencer + // specification. Because of this, the compiler makes the ALU and fetch + // instructions themselves inside a predicated exec predicated as well. The + // validator also reports mismatch between the control flow predication and + // ALU / fetch predication. + kCondExecPred = 5, + // Conditionally executes based on the current predicate then ends execution. + // According to the IPR2015-00325 sequencer specification, execution ends only + // if the condition is actually met for any of the invocations (unlike on the + // R600, where execution ends unconditionally if END_OF_PROGRAM is set in the + // control flow instruction). + kCondExecPredEnd = 6, + // Starts a loop that must be terminated with kLoopEnd, with depth of up to 4. + kLoopStart = 7, + // Continues or breaks out of a loop started with kLoopStart. According to the + // IPR2015-00325 sequencer specification, the incrementing of the loop + // iteration happens before the count and the predicated break checks. + kLoopEnd = 8, + // Conditionally calls a function, with depth of up to 4. + // A return address is pushed to the stack to be used by a kReturn. + kCondCall = 9, + // Returns from the current function as called by kCondCall. + // This is a no-op if not in a function. + kReturn = 10, + // Conditionally jumps to an arbitrary address based on a bool const. + kCondJmp = 11, + // Allocates output values. + kAlloc = 12, + // Conditionally executes based on a bool const. + // PredicateClean = true. + // This is cexec with a bool constant (kCondExec, can be verified by comparing + // the XNA disassembler output with cexec containing and not containing a setp + // instruction), not a kCondExecPred. kCondExec doesn't have a predicate clean + // field (the space is occupied by the bool constant index), while + // kCondExecPred itself does. This is unlike what the IPR2015-00325 sequencer + // specification says about the Conditional_Execute_Predicates_No_Stall + // instruction using this opcode (in the specification, this is described as + // behaving like kCondExecPred with PredicateClean = false, but the + // specification is likely highly outdated - it doesn't even have predicate + // clean fields in exec instructions overall). + kCondExecPredClean = 13, + // Conditionally executes based on a bool const then ends execution. + // PredicateClean = true. + kCondExecPredCleanEnd = 14, + // Hints that no more vertex fetches will be performed. + kMarkVsFetchDone = 15, +}; + +// Returns true if the given control flow opcode executes ALU or fetch +// instructions. +constexpr bool IsControlFlowOpcodeExec(ControlFlowOpcode opcode) { + return opcode == ControlFlowOpcode::kExec || opcode == ControlFlowOpcode::kExecEnd || + opcode == ControlFlowOpcode::kCondExec || opcode == ControlFlowOpcode::kCondExecEnd || + opcode == ControlFlowOpcode::kCondExecPred || + opcode == ControlFlowOpcode::kCondExecPredEnd || + opcode == ControlFlowOpcode::kCondExecPredClean || + opcode == ControlFlowOpcode::kCondExecPredCleanEnd; +} + +// Returns true if the given control flow opcode terminates the shader after +// executing. +constexpr bool DoesControlFlowOpcodeEndShader(ControlFlowOpcode opcode) { + return opcode == ControlFlowOpcode::kExecEnd || opcode == ControlFlowOpcode::kCondExecEnd || + opcode == ControlFlowOpcode::kCondExecPredEnd || + opcode == ControlFlowOpcode::kCondExecPredCleanEnd; +} + +// See the description of ControlFlowOpcode::kCondExecPredClean. +constexpr bool DoesControlFlowCondExecHaveCleanPredicate(ControlFlowOpcode opcode) { + return opcode == ControlFlowOpcode::kCondExecPredClean || + opcode == ControlFlowOpcode::kCondExecPredCleanEnd; +} + +// Determines whether addressing is based on a0 or aL. +enum class AddressingMode : uint32_t { + // Indexing into register sets is done based on aL. + // This allows forms like c[aL + 5]. + kRelative = 0, + // Indexing into register sets is done based on a0. + // This allows forms like c[a0 + 5]. + kAbsolute = 1, +}; + +// Defines the type of a ControlFlowOpcode::kAlloc instruction. +// The allocation is just a size reservation and there may be multiple in a +// shader. +enum class AllocType : uint32_t { + // ? + kNone = 0, + // Vertex shader exports a position. + kVsPosition = 1, + // Vertex shader exports interpolators. + kVsInterpolators = 2, + // Pixel shader exports colors. + kPsColors = 2, + // Memory export. + kMemory = 3, +}; + +// Instruction data for ControlFlowOpcode::kExec and kExecEnd. +struct ControlFlowExecInstruction { + ControlFlowOpcode opcode() const { return opcode_; } + AddressingMode addressing_mode() const { return address_mode_; } + // Address of the instructions to execute. + uint32_t address() const { return address_; } + // Number of instructions being executed. + uint32_t count() const { return count_; } + // Sequence bits, 2 per instruction. + // [0] - ALU (0) or fetch (1), [1] - serialize. + uint32_t sequence() const { return sequence_; } + bool is_predicate_clean() const { return is_predicate_clean_ == 1; } + // ? + bool is_yield() const { return is_yield_ == 1; } + + private: + // Word 0: (32 bits) + uint32_t address_ : 12; + uint32_t count_ : 3; + uint32_t is_yield_ : 1; + uint32_t sequence_ : 12; + [[maybe_unused]] uint32_t vc_hi_ : 4; // Vertex cache? + + // Word 1: (16 bits) + [[maybe_unused]] uint32_t vc_lo_ : 2; + uint32_t : 7; + // According to the description of Conditional_Execute_Predicates_No_Stall in + // the IPR2015-00325 sequencer specification, the sequencer's control flow + // logic will not wait for the predicate to be updated (apparently after this + // exec). The compiler specifies PredicateClean=false for the exec if the + // instructions inside it modify the predicate (but if the predicate set is + // only a refinement of the current predicate, like in case of a nested `if`, + // PredicateClean=true may still be set according to the IPR2015-00325 + // sequencer specification, because the optimization would still work). + uint32_t is_predicate_clean_ : 1; + uint32_t : 1; + AddressingMode address_mode_ : 1; + ControlFlowOpcode opcode_ : 4; +}; +static_assert_size(ControlFlowExecInstruction, sizeof(uint32_t) * 2); + +// Instruction data for ControlFlowOpcode::kCondExec, kCondExecEnd, +// kCondExecPredClean and kCondExecPredCleanEnd. +struct ControlFlowCondExecInstruction { + ControlFlowOpcode opcode() const { return opcode_; } + AddressingMode addressing_mode() const { return address_mode_; } + // Address of the instructions to execute. + uint32_t address() const { return address_; } + // Number of instructions being executed. + uint32_t count() const { return count_; } + // Sequence bits, 2 per instruction. + // [0] - ALU (0) or fetch (1), [1] - serialize. + uint32_t sequence() const { return sequence_; } + // Constant index used as the conditional. + uint32_t bool_address() const { return bool_address_; } + // Required condition value of the comparision (true or false). + bool condition() const { return condition_ == 1; } + // ? + bool is_yield() const { return is_yield_ == 1; } + + private: + // Word 0: (32 bits) + uint32_t address_ : 12; + uint32_t count_ : 3; + uint32_t is_yield_ : 1; + uint32_t sequence_ : 12; + [[maybe_unused]] uint32_t vc_hi_ : 4; // Vertex cache? + + // Word 1: (16 bits) + [[maybe_unused]] uint32_t vc_lo_ : 2; + uint32_t bool_address_ : 8; + uint32_t condition_ : 1; + AddressingMode address_mode_ : 1; + ControlFlowOpcode opcode_ : 4; +}; +static_assert_size(ControlFlowCondExecInstruction, sizeof(uint32_t) * 2); + +// Instruction data for ControlFlowOpcode::kCondExecPred and kCondExecPredEnd. +struct ControlFlowCondExecPredInstruction { + ControlFlowOpcode opcode() const { return opcode_; } + AddressingMode addressing_mode() const { return address_mode_; } + // Address of the instructions to execute. + uint32_t address() const { return address_; } + // Number of instructions being executed. + uint32_t count() const { return count_; } + // Sequence bits, 2 per instruction. + // [0] - ALU (0) or fetch (1), [1] - serialize. + uint32_t sequence() const { return sequence_; } + bool is_predicate_clean() const { return is_predicate_clean_ == 1; } + // Required condition value of the comparision (true or false). + bool condition() const { return condition_ == 1; } + // ? + bool is_yield() const { return is_yield_ == 1; } + + private: + // Word 0: (32 bits) + uint32_t address_ : 12; + uint32_t count_ : 3; + uint32_t is_yield_ : 1; + uint32_t sequence_ : 12; + [[maybe_unused]] uint32_t vc_hi_ : 4; // Vertex cache? + + // Word 1: (16 bits) + [[maybe_unused]] uint32_t vc_lo_ : 2; + uint32_t : 7; + uint32_t is_predicate_clean_ : 1; + uint32_t condition_ : 1; + AddressingMode address_mode_ : 1; + ControlFlowOpcode opcode_ : 4; +}; +static_assert_size(ControlFlowCondExecPredInstruction, sizeof(uint32_t) * 2); + +// Instruction data for ControlFlowOpcode::kLoopStart. +struct ControlFlowLoopStartInstruction { + ControlFlowOpcode opcode() const { return opcode_; } + AddressingMode addressing_mode() const { return address_mode_; } + // Target address to jump to when skipping the loop (normally points to the + // instruction right after the `endloop` instruction). + uint32_t address() const { return address_; } + // Whether to reuse the current aL instead of reset it to loop start. + bool is_repeat() const { return is_repeat_; } + // Integer constant register that holds the loop parameters + // (xenos::LoopConstant). + uint32_t loop_id() const { return loop_id_; } + + private: + // Word 0: (32 bits) + uint32_t address_ : 13; + uint32_t is_repeat_ : 1; + uint32_t : 2; + uint32_t loop_id_ : 5; + uint32_t : 11; + + // Word 1: (16 bits) + uint32_t : 11; + AddressingMode address_mode_ : 1; + ControlFlowOpcode opcode_ : 4; +}; +static_assert_size(ControlFlowLoopStartInstruction, sizeof(uint32_t) * 2); + +// Instruction data for ControlFlowOpcode::kLoopEnd. +struct ControlFlowLoopEndInstruction { + ControlFlowOpcode opcode() const { return opcode_; } + AddressingMode addressing_mode() const { return address_mode_; } + // Target address of the start of the loop body (normally points to the + // instruction right after the `loop` instruction). + uint32_t address() const { return address_; } + // Integer constant register that holds the loop parameters + // (xenos::LoopConstant). + uint32_t loop_id() const { return loop_id_; } + // Break from the loop if the predicate in all 64 invocations matches the + // expected value. + bool is_predicated_break() const { return is_predicated_break_; } + // Required condition value of the comparision (true or false). + bool condition() const { return condition_ == 1; } + + private: + // Word 0: (32 bits) + uint32_t address_ : 13; + uint32_t : 3; + uint32_t loop_id_ : 5; + uint32_t is_predicated_break_ : 1; + uint32_t : 10; + + // Word 1: (16 bits) + uint32_t : 10; + uint32_t condition_ : 1; + AddressingMode address_mode_ : 1; + ControlFlowOpcode opcode_ : 4; +}; +static_assert_size(ControlFlowLoopEndInstruction, sizeof(uint32_t) * 2); + +// Instruction data for ControlFlowOpcode::kCondCall. +struct ControlFlowCondCallInstruction { + ControlFlowOpcode opcode() const { return opcode_; } + AddressingMode addressing_mode() const { return address_mode_; } + // Target address. + uint32_t address() const { return address_; } + // Unconditional call - ignores condition/predication. + bool is_unconditional() const { return is_unconditional_; } + // Whether the call is predicated (or conditional). + bool is_predicated() const { return is_predicated_; } + // Constant index used as the conditional. + uint32_t bool_address() const { return bool_address_; } + // Required condition value of the comparision (true or false). + bool condition() const { return condition_ == 1; } + + private: + // Word 0: (32 bits) + uint32_t address_ : 13; + uint32_t is_unconditional_ : 1; + uint32_t is_predicated_ : 1; + uint32_t : 17; + + // Word 1: (16 bits) + uint32_t : 2; + uint32_t bool_address_ : 8; + uint32_t condition_ : 1; + AddressingMode address_mode_ : 1; + ControlFlowOpcode opcode_ : 4; +}; +static_assert_size(ControlFlowCondCallInstruction, sizeof(uint32_t) * 2); + +// Instruction data for ControlFlowOpcode::kReturn. +struct ControlFlowReturnInstruction { + ControlFlowOpcode opcode() const { return opcode_; } + AddressingMode addressing_mode() const { return address_mode_; } + + private: + // Word 0: (32 bits) + uint32_t : 32; + + // Word 1: (16 bits) + uint32_t : 11; + AddressingMode address_mode_ : 1; + ControlFlowOpcode opcode_ : 4; +}; +static_assert_size(ControlFlowReturnInstruction, sizeof(uint32_t) * 2); + +// Instruction data for ControlFlowOpcode::kCondJmp. +struct ControlFlowCondJmpInstruction { + ControlFlowOpcode opcode() const { return opcode_; } + AddressingMode addressing_mode() const { return address_mode_; } + // Target address. + uint32_t address() const { return address_; } + // Unconditional jump - ignores condition/predication. + bool is_unconditional() const { return is_unconditional_; } + // Whether the jump is predicated (or conditional). + bool is_predicated() const { return is_predicated_; } + // Constant index used as the conditional. + uint32_t bool_address() const { return bool_address_; } + // Required condition value of the comparision (true or false). + bool condition() const { return condition_ == 1; } + + private: + // Word 0: (32 bits) + uint32_t address_ : 13; + uint32_t is_unconditional_ : 1; + uint32_t is_predicated_ : 1; + uint32_t : 17; + + // Word 1: (16 bits) + uint32_t : 1; + [[maybe_unused]] uint32_t direction_ : 1; + uint32_t bool_address_ : 8; + uint32_t condition_ : 1; + AddressingMode address_mode_ : 1; + ControlFlowOpcode opcode_ : 4; +}; +static_assert_size(ControlFlowCondJmpInstruction, sizeof(uint32_t) * 2); + +// Instruction data for ControlFlowOpcode::kAlloc. +struct ControlFlowAllocInstruction { + ControlFlowOpcode opcode() const { return opcode_; } + // The total number of the given type allocated by this instruction. + uint32_t size() const { return size_; } + // Unconditional jump - ignores condition/predication. + AllocType alloc_type() const { return alloc_type_; } + + private: + // Word 0: (32 bits) + uint32_t size_ : 3; + uint32_t : 29; + + // Word 1: (16 bits) + uint32_t : 8; + uint32_t : 1; // is_unserialized_ + AllocType alloc_type_ : 2; + uint32_t : 1; + ControlFlowOpcode opcode_ : 4; +}; +static_assert_size(ControlFlowAllocInstruction, sizeof(uint32_t) * 2); + +union ControlFlowInstruction { + ControlFlowOpcode opcode() const { return opcode_value; } + + ControlFlowExecInstruction exec; // kExec* + ControlFlowCondExecInstruction cond_exec; // kCondExec* + ControlFlowCondExecPredInstruction cond_exec_pred; // kCondExecPred* + ControlFlowLoopStartInstruction loop_start; // kLoopStart + ControlFlowLoopEndInstruction loop_end; // kLoopEnd + ControlFlowCondCallInstruction cond_call; // kCondCall + ControlFlowReturnInstruction ret; // kReturn + ControlFlowCondJmpInstruction cond_jmp; // kCondJmp + ControlFlowAllocInstruction alloc; // kAlloc + + struct { + uint32_t dword_0; + uint32_t dword_1; + }; + struct { + uint32_t unused_0 : 32; + uint32_t unused_1 : 12; + ControlFlowOpcode opcode_value : 4; + }; +}; +static_assert_size(ControlFlowInstruction, sizeof(uint32_t) * 2); + +inline void UnpackControlFlowInstructions(const uint32_t* dwords, ControlFlowInstruction* out_ab) { + uint32_t dword_0 = dwords[0]; + uint32_t dword_1 = dwords[1]; + uint32_t dword_2 = dwords[2]; + out_ab[0].dword_0 = dword_0; + out_ab[0].dword_1 = dword_1 & 0xFFFF; + out_ab[1].dword_0 = (dword_1 >> 16) | (dword_2 << 16); + out_ab[1].dword_1 = dword_2 >> 16; +} + +enum class FetchOpcode : uint32_t { + kVertexFetch = 0, + + // http://web.archive.org/web/20090514012026/http://msdn.microsoft.com/en-us/library/bb313957.aspx + // + // Parameters: + // - UnnormalizedTextureCoords = false (default) / true. + // Only taken into account if AddressU (1D) / AddressU/V (2D) / AddressU/V/W + // (3D/cube) are all set to a non-wrapping mode. To access 1D textures that + // are wider than 8192 texels, unnormalized texture coordinates must be + // used. + // - MagFilter = point / linear / keep (default). + // - MinFilter = point / linear / keep (default). + // - MipFilter = point / linear / basemap (undocumented, but assembled) / keep + // (default). + // - VolMagFilter (3D only) - "filter used when the volume is magnified" + // ("volume" as opposed to "texture") - point / linear / keep (default). + // - VolMinFilter (3D only) - point / linear / keep (default). + // - AnisoFilter = disabled / max1to1 / max2to1 / max4to1 / max8to1 / + // max16to1 / keep (default). + // - UseComputedLOD = false / true (default). + // - UseRegisterLOD = false (default) / true. + // - LODBias = -4.0...3.9375, in 1/16 increments. the default is 0. + // - OffsetX - value added to the x-component of the texel address right + // before sampling = -8.0...7.5, in 1/2 increments, the default is 0. + // - OffsetY (2D, 3D and cube only) - similar to OffsetX. + // - OffsetZ (3D and cube only) - similar to OffsetX. + // - FetchValidOnly - performance booster, whether the data should be fetched + // only for pixels inside the current primitive in a 2x2 quad (must be set + // to false if the result itself is used to calculate gradients) = false / + // true (default). + // + // Coordinates: + // - 1D: U (normalized or unnormalized) + // - 2D: U, V (normalized or unnormalized) + // - 3D (used for both 3D and stacked 2D texture): U, V, W (normalized or + // unnormalized - same for both 3D W and stack layer; also VolMagFilter / + // VolMinFilter between stack layers is supported, used for color correction + // in 454107DC). + // - Cube: SC, TC (between 1 and 2 for normalized), face ID (0.0 to 5.0), the + // cube vector ALU instruction is used to calculate them. + // https://gpuopen.com/learn/fetching-from-cubes-and-octahedrons/ + // "The 1.5 constant is designed such that the output face coordinate (v4 and + // v5 in the above example) range is {1.0 <= x < 2.0} which has an advantage + // in bit encoding compared to {0.0 <= x < 1.0} in that the upper mantissa + // bits are constant throughout the entire output range." + // + // The total LOD for a sample is additive and is based on what is enabled. + // + // For cube maps, according to what texCUBEgrad compiles to in a modified + // HLSL shader of 455607D1 and to XNA assembler output for PC SM3 texldd, + // register gradients are in cube space (not in SC/TC space, unlike the + // coordinates themselves). This isn't true for the GCN, however. + // + // TODO(Triang3l): Find if gradients are unnormalized for cube maps if + // coordinates are unnormalized. Since texldd doesn't perform any + // transformation for gradients (unlike for the coordinates themselves), + // gradients are probably in cube space, which is -MA...MA, and LOD + // calculation involves gradients in this space, so probably gradients + // shouldn't be unnormalized. + // + // Adreno has only been supporting seamless cube map sampling since 3xx, so + // the Xenos likely doesn't support seamless sampling: + // https://developer.qualcomm.com/qfile/28557/80-nu141-1_b_adreno_opengl_es_developer_guide.pdf + // + // Offsets are likely applied at the LOD at which the texture is sampled (not + // sure if to the higher-quality or to both - though "right before sampling" + // probably means to both - in Direct3D 10, it's recommended to only use + // offsets at integer mip levels, otherwise "you may get results that do not + // translate well to hardware". + kTextureFetch = 1, + + // Gets the fraction of border color that would be blended into the texture + // data at the specified coordinates into the X component of the destination. + // http://web.archive.org/web/20090512001222/http://msdn.microsoft.com/en-us/library/bb313945.aspx + // + // According to MSDN, this may take all the parameters that tfetch takes. + kGetTextureBorderColorFrac = 16, + + // Gets the LOD for all of the pixels in the quad at the specified coordinates + // into the X component of the destination. + // http://web.archive.org/web/20090511233056/http://msdn.microsoft.com/en-us/library/bb313949.aspx + // + // According to MSDN, the only valid parameters for this are + // UnnormalizedTextureCoords, AnisoFilter, VolMagFilter and VolMinFilter. + // However, while XNA assembler rejects LODBias, it assembles UseComputedLOD / + // UseRegisterLOD / UseRegisterGradients for it. It's unlikely that it takes + // the LOD bias into account, because a getCompTexLOD + tfetch combination + // with biases in both would result in double biasing (though not sure whether + // grad_exp_adjust_h/v apply - in a getCompTexLOD + tfetch with + // UseComputedLOD=false pair, gradient exponent adjustment is more logical to + // be applied here). MipFilter also can't be overriden, the XNA assembler does + // not assemble this instruction at all with MipFilter, so it's possible that + // the mip filtering mode has no effect on the result (possibly should be + // treated as linear - so fractional biasing can be done before rounding). + // + // Valid only in pixel shaders. Since the documentation says "for all of the + // pixels in the quad" (with explicit gradients, this may diverge), and this + // instruction doesn't assemble at all in vertex shaders, even with + // UseRegisterGradients=true, it's possible that only implicit gradients may + // be used in this instruction. + // + // Used with AnisoFilter=max16to1 in one place in the Source Engine. + // + // Not sure if the LOD should be clamped - probably not, considering an + // out-of-range LOD passed from getCompTexLOD to setTexLOD may be biased back + // into the range later. + kGetTextureComputedLod = 17, + + // Source is 2-component. XZ = ddx(source.xy), YW = ddy(source.xy). + // TODO(Triang3l): Verify whether it's coarse or fine (on Adreno 200, for + // instance). This is using the texture unit, where the LOD is computed for + // the whole quad (according to the Direct3D 11.3 specification), so likely + // coarse; ddx / ddy from the Shader Model 4 era is also compiled by FXC to + // deriv_rtx/rty_coarse when targeting Shader Model 5, and on TeraScale, + // coarse / fine selection only appeared on Direct3D 11 GPUs. + kGetTextureGradients = 18, + + // Gets the weights used in a bilinear fetch. + // http://web.archive.org/web/20090511230938/http://msdn.microsoft.com/en-us/library/bb313953.aspx + // X - horizontal lerp factor. + // Y - vertical lerp factor. + // Z - depth lerp factor. + // W - mip lerp factor. + // + // According to MSDN, this may take all the parameters that tfetch takes. + // + // Takes filtering mode into account - in some games, used explicitly with + // MagFilter=linear, MinFilter=linear. Source Engine explicitly uses this with + // UseComputedLOD=false while only using XY of the result. Offsets and LOD + // biasing also apply. Likely the factors are at the higher-quality LOD of the + // pair used for filtering, though not checked. + // + // For cube maps, the factors are probably in SC/TC space (not sure what the + // depth lerp factor means in case of them), since apparently there's no + // seamless cube map sampling on the Xenos. + kGetTextureWeights = 19, + + // Source is 1-component. + kSetTextureLod = 24, + // Source is 3-component. + kSetTextureGradientsHorz = 25, + // Source is 3-component. + kSetTextureGradientsVert = 26, +}; + +enum class FetchDestinationSwizzle { + // The component indices are absolute (not relative to the component itself, + // unlike in ALU operation sources). + kX = 0, + kY = 1, + kZ = 2, + kW = 3, + k0 = 4, + k1 = 5, + // Keep the current value of the destination register (don't write). + kKeep = 7, +}; + +constexpr FetchDestinationSwizzle GetFetchDestinationComponentSwizzle(uint32_t swizzle, + uint32_t component) { + return FetchDestinationSwizzle((swizzle >> (3 * component)) & 0b111); +} + +struct alignas(uint32_t) VertexFetchInstruction { + FetchOpcode opcode() const { return data_.opcode_value; } + + // Whether the jump is predicated (or conditional). + bool is_predicated() const { return data_.is_predicated; } + // Required condition value of the comparision (true or false). + bool predicate_condition() const { return data_.pred_condition == 1; } + // Vertex fetch constant index [0-95]. + // Applicable only to vfetch_full (the address from vfetch_full is reused in + // vfetch_mini). + uint32_t fetch_constant_index() const { return data_.const_index * 3 + data_.const_index_sel; } + + uint32_t dest() const { return data_.dst_reg; } + uint32_t dest_swizzle() const { return data_.dst_swiz; } + bool is_dest_relative() const { return data_.dst_reg_am; } + // The source is applicable only to vfetch_full (the address from vfetch_full + // is reused in vfetch_mini). + uint32_t src() const { return data_.src_reg; } + uint32_t src_swizzle() const { return data_.src_swiz; } + bool is_src_relative() const { return data_.src_reg_am; } + + uint32_t prefetch_count() const { return data_.prefetch_count; } + bool is_mini_fetch() const { return data_.is_mini_fetch == 1; } + + xenos::VertexFormat data_format() const { return data_.format; } + // [-32, 31] + int exp_adjust() const { return data_.exp_adjust; } + bool is_signed() const { return data_.fomat_comp_all == 1; } + bool is_normalized() const { return data_.num_format_all == 0; } + xenos::SignedRepeatingFractionMode signed_rf_mode() const { return data_.signed_rf_mode_all; } + // If true, the floating-point index is rounded to the nearest integer (likely + // as floor(index + 0.5) because rounding to the nearest even makes no sense + // for addressing, both 1.5 and 2.5 would be 2). + // Otherwise, it's floored (rounded towards negative infinity). + // Applicable only to vfetch_full (the address from vfetch_full is reused in + // vfetch_mini). + // http://web.archive.org/web/20090914055358/http://msdn.microsoft.com/en-us/library/bb313960.aspx + bool is_index_rounded() const { return data_.is_index_rounded == 1; } + // Dword stride, [0, 255]. + // Applicable only to vfetch_full (the address from vfetch_full is reused in + // vfetch_mini). + uint32_t stride() const { return data_.stride; } + // Dword offset, [-4194304, 4194303]. + int32_t offset() const { return data_.offset; } + + private: + struct Data { + struct { + FetchOpcode opcode_value : 5; + uint32_t src_reg : 6; + uint32_t src_reg_am : 1; + uint32_t dst_reg : 6; + uint32_t dst_reg_am : 1; + uint32_t must_be_one : 1; + uint32_t const_index : 5; + uint32_t const_index_sel : 2; + // Prefetch count minus 1. + uint32_t prefetch_count : 3; + // Absolute, one component. + uint32_t src_swiz : 2; + }; + struct { + uint32_t dst_swiz : 12; + uint32_t fomat_comp_all : 1; + uint32_t num_format_all : 1; + xenos::SignedRepeatingFractionMode signed_rf_mode_all : 1; + uint32_t is_index_rounded : 1; + xenos::VertexFormat format : 6; + uint32_t reserved2 : 2; + int32_t exp_adjust : 6; + uint32_t is_mini_fetch : 1; + uint32_t is_predicated : 1; + }; + struct { + uint32_t stride : 8; + int32_t offset : 23; + uint32_t pred_condition : 1; + }; + }; + Data data_; +}; +static_assert_size(VertexFetchInstruction, sizeof(uint32_t) * 3); + +struct alignas(uint32_t) TextureFetchInstruction { + FetchOpcode opcode() const { return data_.opcode_value; } + + // Whether the jump is predicated (or conditional). + bool is_predicated() const { return data_.is_predicated; } + // Required condition value of the comparision (true or false). + bool predicate_condition() const { return data_.pred_condition == 1; } + // Texture fetch constant index [0-31]. + uint32_t fetch_constant_index() const { return data_.const_index; } + + uint32_t dest() const { return data_.dst_reg; } + uint32_t dest_swizzle() const { return data_.dst_swiz; } + bool is_dest_relative() const { return data_.dst_reg_am; } + uint32_t src() const { return data_.src_reg; } + uint32_t src_swizzle() const { return data_.src_swiz; } + bool is_src_relative() const { return data_.src_reg_am; } + + xenos::FetchOpDimension dimension() const { return data_.dimension; } + bool fetch_valid_only() const { return data_.fetch_valid_only == 1; } + bool unnormalized_coordinates() const { return data_.tx_coord_denorm == 1; } + bool has_mag_filter() const { return data_.mag_filter != xenos::TextureFilter::kUseFetchConst; } + xenos::TextureFilter mag_filter() const { return data_.mag_filter; } + bool has_min_filter() const { return data_.min_filter != xenos::TextureFilter::kUseFetchConst; } + xenos::TextureFilter min_filter() const { return data_.min_filter; } + bool has_mip_filter() const { return data_.mip_filter != xenos::TextureFilter::kUseFetchConst; } + xenos::TextureFilter mip_filter() const { return data_.mip_filter; } + bool has_aniso_filter() const { return data_.aniso_filter != xenos::AnisoFilter::kUseFetchConst; } + xenos::AnisoFilter aniso_filter() const { return data_.aniso_filter; } + bool has_vol_mag_filter() const { + return data_.vol_mag_filter != xenos::TextureFilter::kUseFetchConst; + } + xenos::TextureFilter vol_mag_filter() const { return data_.vol_mag_filter; } + bool has_vol_min_filter() const { + return data_.vol_min_filter != xenos::TextureFilter::kUseFetchConst; + } + xenos::TextureFilter vol_min_filter() const { return data_.vol_min_filter; } + bool use_computed_lod() const { return data_.use_comp_lod == 1; } + bool use_register_lod() const { return data_.use_reg_lod == 1; } + bool use_register_gradients() const { return data_.use_reg_gradients == 1; } + xenos::SampleLocation sample_location() const { return data_.sample_location; } + float lod_bias() const { + // http://web.archive.org/web/20090514012026/http://msdn.microsoft.com:80/en-us/library/bb313957.aspx + return data_.lod_bias * (1.0f / 16.0f); + } + float offset_x() const { return data_.offset_x * 0.5f; } + float offset_y() const { return data_.offset_y * 0.5f; } + float offset_z() const { return data_.offset_z * 0.5f; } + + private: + struct Data { + struct { + FetchOpcode opcode_value : 5; + uint32_t src_reg : 6; + uint32_t src_reg_am : 1; + uint32_t dst_reg : 6; + uint32_t dst_reg_am : 1; + uint32_t fetch_valid_only : 1; + uint32_t const_index : 5; + uint32_t tx_coord_denorm : 1; + // Absolute, three components. + uint32_t src_swiz : 6; + }; + struct { + uint32_t dst_swiz : 12; + xenos::TextureFilter mag_filter : 2; + xenos::TextureFilter min_filter : 2; + xenos::TextureFilter mip_filter : 2; + xenos::AnisoFilter aniso_filter : 3; + xenos::ArbitraryFilter arbitrary_filter : 3; + xenos::TextureFilter vol_mag_filter : 2; + xenos::TextureFilter vol_min_filter : 2; + uint32_t use_comp_lod : 1; + uint32_t use_reg_lod : 1; + uint32_t unk : 1; + uint32_t is_predicated : 1; + }; + struct { + uint32_t use_reg_gradients : 1; + xenos::SampleLocation sample_location : 1; + int32_t lod_bias : 7; + uint32_t unused : 5; + xenos::FetchOpDimension dimension : 2; + int32_t offset_x : 5; + int32_t offset_y : 5; + int32_t offset_z : 5; + uint32_t pred_condition : 1; + }; + }; + Data data_; +}; +static_assert_size(TextureFetchInstruction, sizeof(uint32_t) * 3); + +union alignas(uint32_t) FetchInstruction { + public: + FetchOpcode opcode() const { return data_.opcode_value; } + + // Whether the jump is predicated (or conditional). + bool is_predicated() const { return data_.is_predicated; } + // Required condition value of the comparision (true or false). + bool predicate_condition() const { return data_.pred_condition == 1; } + + uint32_t dest() const { return data_.dst_reg; } + uint32_t dest_swizzle() const { return data_.dst_swiz; } + bool is_dest_relative() const { return data_.dst_reg_am; } + uint32_t src() const { return data_.src_reg; } + bool is_src_relative() const { return data_.src_reg_am; } + + // For FetchOpcode::kVertexFetch. + const VertexFetchInstruction& vertex_fetch() const { return vertex_fetch_; } + // For operations other than FetchOpcode::kVertexFetch. + const TextureFetchInstruction& texture_fetch() const { return texture_fetch_; } + + private: + struct Data { + struct { + FetchOpcode opcode_value : 5; + uint32_t src_reg : 6; + uint32_t src_reg_am : 1; + uint32_t dst_reg : 6; + uint32_t dst_reg_am : 1; + // Specific to vertex or texture fetch. + uint32_t : 1; + // [0-31], points to one tf# or three vf# constants. + uint32_t const_index : 5; + // Specific to vertex or texture fetch. + uint32_t : 7; + }; + struct { + uint32_t dst_swiz : 12; + // Specific to vertex or texture fetch. + uint32_t : 19; + uint32_t is_predicated : 1; + }; + struct { + // Specific to vertex or texture fetch. + uint32_t : 31; + uint32_t pred_condition : 1; + }; + }; + Data data_; + VertexFetchInstruction vertex_fetch_; + TextureFetchInstruction texture_fetch_; +}; +static_assert_size(FetchInstruction, sizeof(uint32_t) * 3); + +// What follows is largely a mash up of the microcode assembly naming and the +// R600 docs that have a near 1:1 with the instructions available in the Xenos +// GPU, and Adreno 2xx instruction names found in Freedreno. Some of the +// behavior has been experimentally verified. Some has been guessed. Some +// instructions are implemented in the Exhibit 2092 - sq_alu of IPR2015-00325, +// however, the code provided there is early and incomplete. +// +// Conventions: +// - All temporary registers are vec4s. +// - Most scalar ALU operations work with one or two components of the source +// register or the float constant passed as the third operand of the whole +// co-issued ALU operation, denoted by `a` (the left-hand operand) and `b` +// (the right-hand operand). +// `a` is the [(3 + src3_swizzle[6:7]) & 3] component (W - alpha). +// `b` is the [(0 + src3_swizzle[0:1]) & 3] component (X - red). +// - mulsc, addsc, subsc scalar ALU operations accept two operands - a float +// constant with the `a` (W) swizzle (addressed by the third operand index and +// addressing mode) being the left-hand operand, and a temporary register with +// the `b` (X) swizzle with the index constructed from: +// - [0:0] = scalar_opcode[0:0] +// - [1:1] = src3_sel[0:0] +// - [2:5] = src3_swizzle[2:5] +// abs_constants and third source's negation are applied to both the constant +// and the temporary register. +// - Some scalar ALU instructions don't have operands. +// - Scalar ALU operations replicate the result into all masked components. +// - Overall, the WXYZ order is pretty commonly used in the Exhibit 2092 - +// sq_alu of IPR2015-00325, this is where the AB = WX order of scalar operands +// likely comes from. Vector predicate instructions also involve the W and X +// components, and in IPR2015-00325 sq_alu, individual components in the +// emulated vector instructions are handled in the WXYZ order. However, max4's +// "greater than the rest" check order is RGBA (XYZW) there. dp4, though, sums +// the products in WXYZ order in IPR2015-00325 sq_alu (but in XYZW order on +// MSDN). +// - ps is the previous result of a scalar ALU operation. It is not modified +// when the instruction that would write it fails its predication check. +// - Direct3D 9 rules (like in GCN v_*_legacy_f32 instructions) for +// multiplication (+-0 or denormal * anything = +0) wherever it's present +// (mul, mad, dp, etc.) and for NaN in min/max. It's very important to respect +// this rule for multiplication, as games often rely on it in vector +// normalization (rcp and mul), Infinity * 0 resulting in NaN breaks a lot of +// things in games - causes white screen in 4D5307E6, white specular on +// characters in 545407F2. The result is always positive zero in this case, no +// matter what the signs of the other operands are, according to R5xx +// Acceleration section 8.7.5 "Legacy multiply behavior" and testing on +// Adreno 200. This means that the following need to be taken into account +// (according to 8.7.2 "ALU Non-Transcendental Floating Point"): +// - +0 * -0 is -0 with IEEE conformance, however, with this legacy SM3 +// handling, it should result in +0. +// - +0 + -0 is +0, so multiply-add should not be replaced with conditional +// move of the third operand in case of zero multiplicands, because the term +// may be -0, while the result should be +0 in this case. +// http://developer.amd.com/wordpress/media/2013/10/R5xx_Acceleration_v1.5.pdf +// Multiply-add also appears to be not fused; the SM3 behavior instruction on +// GCN is called v_mad_legacy_f32, not v_fma_legacy_f32 (in 2012-2020, before +// RDNA 2, which removed v_mad_f32 as well) - shader translators should not +// use instructions that may be interpreted by the host GPU as fused +// multiply-add. + +// For analysis of shaders and skipping instructions that write nothing. +enum AluOpChangedState { + kAluOpChangedStateNone = 0, + kAluOpChangedStateAddressRegister = 1 << 0, + kAluOpChangedStatePredicate = 1 << 1, + kAluOpChangedStatePixelKill = 1 << 2, +}; + +enum class AluScalarOpcode : uint32_t { + // Floating-Point Add + // adds/ADDs dest, src0.ab + // dest.xyzw = src0.a + src0.b; + kAdds = 0, + + // Floating-Point Add (with Previous) + // adds_prev/ADD_PREVs dest, src0.a + // dest.xyzw = src0.a + ps; + kAddsPrev = 1, + + // Floating-Point Multiply + // muls/MULs dest, src0.ab + // dest.xyzw = src0.a * src0.b; + kMuls = 2, + + // Floating-Point Multiply (with Previous) + // muls_prev/MUL_PREVs dest, src0.a + // dest.xyzw = src0.a * ps; + kMulsPrev = 3, + + // Scalar Multiply Emulating LIT Operation + // muls_prev2/MUL_PREV2s dest, src0.ab + // dest.xyzw = + // ps == -FLT_MAX || !isfinite(ps) || !isfinite(src0.b) || src0.b <= 0 + // ? -FLT_MAX : src0.a * ps; + kMulsPrev2 = 4, + + // Floating-Point Maximum + // maxs/MAXs dest, src0.ab + // dest.xyzw = src0.a >= src0.b ? src0.a : src0.b; + kMaxs = 5, + + // Floating-Point Minimum + // mins/MINs dest, src0.ab + // dest.xyzw = src0.a < src0.b ? src0.a : src0.b; + kMins = 6, + + // Floating-Point Set If Equal + // seqs/SETEs dest, src0.a + // dest.xyzw = src0.a == 0.0 ? 1.0 : 0.0; + kSeqs = 7, + + // Floating-Point Set If Greater Than + // sgts/SETGTs dest, src0.a + // dest.xyzw = src0.a > 0.0 ? 1.0 : 0.0; + kSgts = 8, + + // Floating-Point Set If Greater Than Or Equal + // sges/SETGTEs dest, src0.a + // dest.xyzw = src0.a >= 0.0 ? 1.0 : 0.0; + kSges = 9, + + // Floating-Point Set If Not Equal + // snes/SETNEs dest, src0.a + // dest.xyzw = src0.a != 0.0 ? 1.0 : 0.0; + kSnes = 10, + + // Floating-Point Fractional + // frcs/FRACs dest, src0.a + // dest.xyzw = src0.a - floor(src0.a); + kFrcs = 11, + + // Floating-Point Truncate + // truncs/TRUNCs dest, src0.a + // dest.xyzw = src0.a >= 0 ? floor(src0.a) : -floor(-src0.a); + kTruncs = 12, + + // Floating-Point Floor + // floors/FLOORs dest, src0.a + // dest.xyzw = floor(src0.a); + kFloors = 13, + + // Scalar Base-2 Exponent, IEEE + // exp/EXP_IEEE dest, src0.a + // dest.xyzw = src0.a == 0.0 ? 1.0 : pow(2, src0.a); + kExp = 14, + + // Scalar Base-2 Log + // logc/LOG_CLAMP dest, src0.a + // float t = src0.a == 1.0 ? 0.0 : log(src0.a) / log(2.0); + // dest.xyzw = t == -INF ? -FLT_MAX : t; + kLogc = 15, + + // Scalar Base-2 IEEE Log + // log/LOG_IEEE dest, src0.a + // dest.xyzw = src0.a == 1.0 ? 0.0 : log(src0.a) / log(2.0); + kLog = 16, + + // Scalar Reciprocal, Clamp to Maximum + // rcpc/RECIP_CLAMP dest, src0.a + // float t = src0.a == 1.0 ? 1.0 : 1.0 / src0.a; + // if (t == -INF) t = -FLT_MAX; + // else if (t == INF) t = FLT_MAX; + // dest.xyzw = t; + kRcpc = 17, + + // Scalar Reciprocal, Clamp to Zero + // Mimicking the behavior of the fixed-function pipeline. + // rcpf/RECIP_FF dest, src0.a + // float t = src0.a == 1.0 ? 1.0 : 1.0 / src0.a; + // if (t == -INF) t = -0.0; + // else if (t == INF) t = 0.0; + // dest.xyzw = t; + kRcpf = 18, + + // Scalar Reciprocal, IEEE Approximation + // rcp/RECIP_IEEE dest, src0.a + // dest.xyzw = src0.a == 1.0 ? 1.0 : 1.0 / src0.a; + kRcp = 19, + + // Scalar Reciprocal Square Root, Clamp to Maximum + // rsqc/RECIPSQ_CLAMP dest, src0.a + // float t = src0.a == 1.0 ? 1.0 : 1.0 / sqrt(src0.a); + // if (t == -INF) t = -FLT_MAX; + // else if (t == INF) t = FLT_MAX; + // dest.xyzw = t; + kRsqc = 20, + + // Scalar Reciprocal Square Root, Clamp to Zero + // rsqf/RECIPSQ_FF dest, src0.a + // float t = src0.a == 1.0 ? 1.0 : 1.0 / sqrt(src0.a); + // if (t == -INF) t = -0.0; + // else if (t == INF) t = 0.0; + // dest.xyzw = t; + kRsqf = 21, + + // Scalar Reciprocal Square Root, IEEE Approximation + // rsq/RECIPSQ_IEEE dest, src0.a + // dest.xyzw = src0.a == 1.0 ? 1.0 : 1.0 / sqrt(src0.a); + kRsq = 22, + + // Floating-Point Maximum with Copy To Integer in AR + // maxas dest, src0.ab + // movas/MOVAs dest, src0.aa + // a0 = (int)clamp(floor(src0.a + 0.5), -256.0, 255.0); + // dest.xyzw = src0.a >= src0.b ? src0.a : src0.b; + kMaxAs = 23, + + // Floating-Point Maximum with Copy Truncated To Integer in AR + // maxasf dest, src0.ab + // movasf/MOVA_FLOORs dest, src0.aa + // a0 = (int)clamp(floor(src0.a), -256.0, 255.0); + // dest.xyzw = src0.a >= src0.b ? src0.a : src0.b; + kMaxAsf = 24, + + // Floating-Point Subtract + // subs/SUBs dest, src0.ab + // dest.xyzw = src0.a - src0.b; + kSubs = 25, + + // Floating-Point Subtract (with Previous) + // subs_prev/SUB_PREVs dest, src0.a + // dest.xyzw = src0.a - ps; + kSubsPrev = 26, + + // Floating-Point Predicate Set If Equal + // setp_eq/PRED_SETEs dest, src0.a + // if (src0.a == 0.0) { + // dest.xyzw = 0.0; + // p0 = 1; + // } else { + // dest.xyzw = 1.0; + // p0 = 0; + // } + kSetpEq = 27, + + // Floating-Point Predicate Set If Not Equal + // setp_ne/PRED_SETNEs dest, src0.a + // if (src0.a != 0.0) { + // dest.xyzw = 0.0; + // p0 = 1; + // } else { + // dest.xyzw = 1.0; + // p0 = 0; + // } + kSetpNe = 28, + + // Floating-Point Predicate Set If Greater Than + // setp_gt/PRED_SETGTs dest, src0.a + // if (src0.a > 0.0) { + // dest.xyzw = 0.0; + // p0 = 1; + // } else { + // dest.xyzw = 1.0; + // p0 = 0; + // } + kSetpGt = 29, + + // Floating-Point Predicate Set If Greater Than Or Equal + // setp_ge/PRED_SETGTEs dest, src0.a + // if (src0.a >= 0.0) { + // dest.xyzw = 0.0; + // p0 = 1; + // } else { + // dest.xyzw = 1.0; + // p0 = 0; + // } + kSetpGe = 30, + + // Predicate Counter Invert + // setp_inv/PRED_SET_INVs dest, src0.a + // if (src0.a == 1.0) { + // dest.xyzw = 0.0; + // p0 = 1; + // } else { + // if (src0.a == 0.0) { + // dest.xyzw = 1.0; + // } else { + // dest.xyzw = src0.a; + // } + // p0 = 0; + // } + kSetpInv = 31, + + // Predicate Counter Pop + // setp_pop/PRED_SET_POPs dest, src0.a + // if (src0.a - 1.0 <= 0.0) { + // dest.xyzw = 0.0; + // p0 = 1; + // } else { + // dest.xyzw = src0.a - 1.0; + // p0 = 0; + // } + kSetpPop = 32, + + // Predicate Counter Clear + // setp_clr/PRED_SET_CLRs dest + // dest.xyzw = FLT_MAX; + // p0 = 0; + kSetpClr = 33, + + // Predicate Counter Restore + // setp_rstr/PRED_SET_RESTOREs dest, src0.a + // if (src0.a == 0.0) { + // dest.xyzw = 0.0; + // p0 = 1; + // } else { + // dest.xyzw = src0.a; + // p0 = 0; + // } + kSetpRstr = 34, + + // Floating-Point Pixel Kill If Equal + // kills_eq/KILLEs dest, src0.a + // if (src0.a == 0.0) { + // dest.xyzw = 1.0; + // discard; + // } else { + // dest.xyzw = 0.0; + // } + kKillsEq = 35, + + // Floating-Point Pixel Kill If Greater Than + // kills_gt/KILLGTs dest, src0.a + // if (src0.a > 0.0) { + // dest.xyzw = 1.0; + // discard; + // } else { + // dest.xyzw = 0.0; + // } + kKillsGt = 36, + + // Floating-Point Pixel Kill If Greater Than Or Equal + // kills_ge/KILLGTEs dest, src0.a + // if (src0.a >= 0.0) { + // dest.xyzw = 1.0; + // discard; + // } else { + // dest.xyzw = 0.0; + // } + kKillsGe = 37, + + // Floating-Point Pixel Kill If Not Equal + // kills_ne/KILLNEs dest, src0.a + // if (src0.a != 0.0) { + // dest.xyzw = 1.0; + // discard; + // } else { + // dest.xyzw = 0.0; + // } + kKillsNe = 38, + + // Floating-Point Pixel Kill If One + // kills_one/KILLONEs dest, src0.a + // if (src0.a == 1.0) { + // dest.xyzw = 1.0; + // discard; + // } else { + // dest.xyzw = 0.0; + // } + kKillsOne = 39, + + // Scalar Square Root, IEEE Aproximation + // sqrt/SQRT_IEEE dest, src0.a + // dest.xyzw = sqrt(src0.a); + kSqrt = 40, + + // 0 and 1 are the same instruction - one bit of the register index is stored + // in the opcode field. + + // mulsc/MUL_CONST_0 dest, src0.a, src1.a + kMulsc0 = 42, + // mulsc/MUL_CONST_1 dest, src0.a, src1.a + kMulsc1 = 43, + // addsc/ADD_CONST_0 dest, src0.a, src1.a + kAddsc0 = 44, + // addsc/ADD_CONST_1 dest, src0.a, src1.a + kAddsc1 = 45, + // subsc/SUB_CONST_0 dest, src0.a, src1.a + kSubsc0 = 46, + // subsc/SUB_CONST_1 dest, src0.a, src1.a + kSubsc1 = 47, + + // Scalar Sin + // sin/SIN dest, src0.a + // dest.xyzw = sin(src0.a); + kSin = 48, + + // Scalar Cos + // cos/COS dest, src0.a + // dest.xyzw = cos(src0.a); + kCos = 49, + + // retain_prev/RETAIN_PREV dest + // dest.xyzw = ps; + kRetainPrev = 50, +}; + +struct AluScalarOpcodeInfo { + const char* name; + // 0 - no operands. + // 1 - one single-component (W) or two-component (WX) r# or c#. + // 2 - c#.w and r#.x. + uint32_t operand_count; + // If operand_count is 1, whether both W and X of the operand are used rather + // than only W. + bool single_operand_is_two_component; + // Note that all scalar instructions except for retain_prev modify the + // previous scalar register, so they must be executed even if they don't write + // any result and don't perform any other state changes. + AluOpChangedState changed_state; +}; + +// 6 scalar opcode bits - 64 entries. +extern const AluScalarOpcodeInfo kAluScalarOpcodeInfos[64]; + +inline const AluScalarOpcodeInfo& GetAluScalarOpcodeInfo(AluScalarOpcode opcode) { + assert_true(uint32_t(opcode) < rex::countof(kAluScalarOpcodeInfos)); + return kAluScalarOpcodeInfos[uint32_t(opcode)]; +} + +enum class AluVectorOpcode : uint32_t { + // Per-Component Floating-Point Add + // add/ADDv dest, src0, src1 + // dest.x = src0.x + src1.x; + // dest.y = src0.y + src1.y; + // dest.z = src0.z + src1.z; + // dest.w = src0.w + src1.w; + kAdd = 0, + + // Per-Component Floating-Point Multiply + // mul/MULv dest, src0, src1 + // dest.x = src0.x * src1.x; + // dest.y = src0.y * src1.y; + // dest.z = src0.z * src1.z; + // dest.w = src0.w * src1.w; + kMul = 1, + + // Per-Component Floating-Point Maximum + // max/MAXv dest, src0, src1 + // dest.x = src0.x >= src1.x ? src0.x : src1.x; + // dest.y = src0.x >= src1.y ? src0.y : src1.y; + // dest.z = src0.x >= src1.z ? src0.z : src1.z; + // dest.w = src0.x >= src1.w ? src0.w : src1.w; + kMax = 2, + + // Per-Component Floating-Point Minimum + // min/MINv dest, src0, src1 + // dest.x = src0.x < src1.x ? src0.x : src1.x; + // dest.y = src0.x < src1.y ? src0.y : src1.y; + // dest.z = src0.x < src1.z ? src0.z : src1.z; + // dest.w = src0.x < src1.w ? src0.w : src1.w; + kMin = 3, + + // Per-Component Floating-Point Set If Equal + // seq/SETEv dest, src0, src1 + // dest.x = src0.x == src1.x ? 1.0 : 0.0; + // dest.y = src0.y == src1.y ? 1.0 : 0.0; + // dest.z = src0.z == src1.z ? 1.0 : 0.0; + // dest.w = src0.w == src1.w ? 1.0 : 0.0; + kSeq = 4, + + // Per-Component Floating-Point Set If Greater Than + // sgt/SETGTv dest, src0, src1 + // dest.x = src0.x > src1.x ? 1.0 : 0.0; + // dest.y = src0.y > src1.y ? 1.0 : 0.0; + // dest.z = src0.z > src1.z ? 1.0 : 0.0; + // dest.w = src0.w > src1.w ? 1.0 : 0.0; + kSgt = 5, + + // Per-Component Floating-Point Set If Greater Than Or Equal + // sge/SETGTEv dest, src0, src1 + // dest.x = src0.x >= src1.x ? 1.0 : 0.0; + // dest.y = src0.y >= src1.y ? 1.0 : 0.0; + // dest.z = src0.z >= src1.z ? 1.0 : 0.0; + // dest.w = src0.w >= src1.w ? 1.0 : 0.0; + kSge = 6, + + // Per-Component Floating-Point Set If Not Equal + // sne/SETNEv dest, src0, src1 + // dest.x = src0.x != src1.x ? 1.0 : 0.0; + // dest.y = src0.y != src1.y ? 1.0 : 0.0; + // dest.z = src0.z != src1.z ? 1.0 : 0.0; + // dest.w = src0.w != src1.w ? 1.0 : 0.0; + kSne = 7, + + // Per-Component Floating-Point Fractional + // frc/FRACv dest, src0 + // dest.x = src0.x - floor(src0.x); + // dest.y = src0.y - floor(src0.y); + // dest.z = src0.z - floor(src0.z); + // dest.w = src0.w - floor(src0.w); + kFrc = 8, + + // Per-Component Floating-Point Truncate + // trunc/TRUNCv dest, src0 + // dest.x = src0.x >= 0 ? floor(src0.x) : -floor(-src0.x); + // dest.y = src0.y >= 0 ? floor(src0.y) : -floor(-src0.y); + // dest.z = src0.z >= 0 ? floor(src0.z) : -floor(-src0.z); + // dest.w = src0.w >= 0 ? floor(src0.w) : -floor(-src0.w); + kTrunc = 9, + + // Per-Component Floating-Point Floor + // floor/FLOORv dest, src0 + // dest.x = floor(src0.x); + // dest.y = floor(src0.y); + // dest.z = floor(src0.z); + // dest.w = floor(src0.w); + kFloor = 10, + + // Per-Component Floating-Point Multiply-Add + // mad/MULADDv dest, src0, src1, src2 + // dest.x = src0.x * src1.x + src2.x; + // dest.y = src0.y * src1.y + src2.y; + // dest.z = src0.z * src1.z + src2.z; + // dest.w = src0.w * src1.w + src2.w; + // According to SQ_ALU::multiply_add (used in the isHardwareAccurate case) + // from IPR2015-00325 sq_alu, this is FMA - rounding to single-precision only + // after the addition. + kMad = 11, + + // Per-Component Floating-Point Conditional Move If Equal + // cndeq/CNDEv dest, src0, src1, src2 + // dest.x = src0.x == 0.0 ? src1.x : src2.x; + // dest.y = src0.y == 0.0 ? src1.y : src2.y; + // dest.z = src0.z == 0.0 ? src1.z : src2.z; + // dest.w = src0.w == 0.0 ? src1.w : src2.w; + kCndEq = 12, + + // Per-Component Floating-Point Conditional Move If Greater Than Or Equal + // cndge/CNDGTEv dest, src0, src1, src2 + // dest.x = src0.x >= 0.0 ? src1.x : src2.x; + // dest.y = src0.y >= 0.0 ? src1.y : src2.y; + // dest.z = src0.z >= 0.0 ? src1.z : src2.z; + // dest.w = src0.w >= 0.0 ? src1.w : src2.w; + kCndGe = 13, + + // Per-Component Floating-Point Conditional Move If Greater Than + // cndgt/CNDGTv dest, src0, src1, src2 + // dest.x = src0.x > 0.0 ? src1.x : src2.x; + // dest.y = src0.y > 0.0 ? src1.y : src2.y; + // dest.z = src0.z > 0.0 ? src1.z : src2.z; + // dest.w = src0.w > 0.0 ? src1.w : src2.w; + kCndGt = 14, + + // Four-Element Dot Product + // dp4/DOT4v dest, src0, src1 + // dest.xyzw = src0.x * src1.x + src0.y * src1.y + src0.z * src1.z + + // src0.w * src1.w; + kDp4 = 15, + + // Three-Element Dot Product + // dp3/DOT3v dest, src0, src1 + // dest.xyzw = src0.x * src1.x + src0.y * src1.y + src0.z * src1.z; + kDp3 = 16, + + // Two-Element Dot Product and Add + // dp2add/DOT2ADDv dest, src0, src1, src2 + // dest.xyzw = src0.x * src1.x + src0.y * src1.y + src2.x; + // IPR2015-00325 sq_alu may be an outdated and unreliable reference (Sequencer + // Parts Development folder history lists a few changes regarding the swizzle + // in dot2add, sq_alu though implements the instruction as + // src0.x * src1.x + src0.z * src1.z + src2.y, but MSDN specifies the correct + // order as provided in the beginning of this comment, further proven by + // assembling PC shader assembly using XNA, with Shader Model 2 dp2add being + // translated directly into Xenos dp2add without additional swizzling). + // http://web.archive.org/web/20100705150552/http://msdn.microsoft.com/en-us/library/bb313922.aspx + kDp2Add = 17, + + // Cube Map + // cube/CUBEv dest, src0, src1 + // dest.x = T cube coordinate; + // dest.y = S cube coordinate; + // dest.z = 2.0 * major axis; + // dest.w = FaceID; + // https://developer.amd.com/wordpress/media/2012/12/AMD_Southern_Islands_Instruction_Set_Architecture.pdf + // if (abs(z) >= abs(x) && abs(z) >= abs(y)) { + // tc = -y; + // sc = z < 0.0 ? -x : x; + // ma = 2.0 * z; + // id = z < 0.0 ? 5.0 : 4.0; + // } else if (abs(y) >= abs(x)) { + // tc = y < 0.0 ? -z : z; + // sc = x; + // ma = 2.0 * y; + // id = y < 0.0 ? 3.0 : 2.0; + // } else { + // tc = -y; + // sc = x < 0.0 ? z : -z; + // ma = 2.0 * x; + // id = x < 0.0 ? 1.0 : 0.0; + // } + // Expects src0.zzxy and src1.yxzz swizzles. + // FaceID is D3DCUBEMAP_FACES: + // https://msdn.microsoft.com/en-us/library/windows/desktop/bb172528(v=vs.85).aspx + // Used like: + // cube r0, source.zzxy, source.yxz + // rcp r0.z, r0_abs.z + // mad r0.xy, r0, r0.zzzw, 1.5f + // tfetchCube r0, r0.yxw, tf0 + // http://web.archive.org/web/20100705154143/http://msdn.microsoft.com/en-us/library/bb313921.aspx + // On GCN, the sequence is the same, so GCN documentation can be used as a + // reference (tfetchCube doesn't accept the ST as if the texture was a 2D + // array in XY exactly, to get texture array ST, 1 must be subtracted from its + // XY inputs). + // https://gpuopen.com/learn/fetching-from-cubes-and-octahedrons/ + // "The 1.5 constant is designed such that the output face coordinate (v4 and + // v5 in the above example) range is {1.0 <= x < 2.0} which has an advantage + // in bit encoding compared to {0.0 <= x < 1.0} in that the upper mantissa + // bits are constant throughout the entire output range." + kCube = 18, + + // Four-Element Maximum + // max4/MAX4v dest, src0 + // According to IPR2015-00325 sq_alu: + // if (src0.x > src0.y && src0.x > src0.z && src0.x > src0.w) { + // dest.xyzw = src0.x; + // } else if (src0.y > src0.z && src0.y > src0.w) { + // dest.xyzw = src0.y; + // } else if (src0.z > src0.w) { + // dest.xyzw = src0.z; + // } else { + // dest.xyzw = src0.w; + // } + // However, the comparisons may be >= actually - the XNA documentation on + // MSDN, as well as R600 and GCN documentation, describe `max` as being + // implemented via >= rather than >. `max4` is documented vaguely, without the + // exact calculations for each component - MSDN describes it as max(xyzw), and + // in the R600 documentation it's max(wzyx). There's also a case more similar + // to `max4` where there also is a discrepancy between IPR2015-00325 sq_alu + // and the GCN documentation - `cube` has max3 in zyx priority order, and a >= + // comparison is used for this purpose on the GCN, but in IPR2015-00325 sq_alu + // it's implemented via >. It's possible that in an early version of the R400, + // the comparison was >, but was later changed to >=, but this is merely a + // guess. + kMax4 = 19, + + // Floating-Point Predicate Counter Increment If Equal + // setp_eq_push/PRED_SETE_PUSHv dest, src0, src1 + // if (src0.w == 0.0 && src1.w == 0.0) { + // p0 = 1; + // } else { + // p0 = 0; + // } + // if (src0.x == 0.0 && src1.x == 0.0) { + // dest.xyzw = 0.0; + // } else { + // dest.xyzw = src0.x + 1.0; + // } + kSetpEqPush = 20, + + // Floating-Point Predicate Counter Increment If Not Equal + // setp_ne_push/PRED_SETNE_PUSHv dest, src0, src1 + // if (src0.w == 0.0 && src1.w != 0.0) { + // p0 = 1; + // } else { + // p0 = 0; + // } + // if (src0.x == 0.0 && src1.x != 0.0) { + // dest.xyzw = 0.0; + // } else { + // dest.xyzw = src0.x + 1.0; + // } + kSetpNePush = 21, + + // Floating-Point Predicate Counter Increment If Greater Than + // setp_gt_push/PRED_SETGT_PUSHv dest, src0, src1 + // if (src0.w == 0.0 && src1.w > 0.0) { + // p0 = 1; + // } else { + // p0 = 0; + // } + // if (src0.x == 0.0 && src1.x > 0.0) { + // dest.xyzw = 0.0; + // } else { + // dest.xyzw = src0.x + 1.0; + // } + kSetpGtPush = 22, + + // Floating-Point Predicate Counter Increment If Greater Than Or Equal + // setp_ge_push/PRED_SETGTE_PUSHv dest, src0, src1 + // if (src0.w == 0.0 && src1.w >= 0.0) { + // p0 = 1; + // } else { + // p0 = 0; + // } + // if (src0.x == 0.0 && src1.x >= 0.0) { + // dest.xyzw = 0.0; + // } else { + // dest.xyzw = src0.x + 1.0; + // } + kSetpGePush = 23, + + // Floating-Point Pixel Kill If Equal + // kill_eq/KILLEv dest, src0, src1 + // if (src0.x == src1.x || + // src0.y == src1.y || + // src0.z == src1.z || + // src0.w == src1.w) { + // dest.xyzw = 1.0; + // discard; + // } else { + // dest.xyzw = 0.0; + // } + kKillEq = 24, + + // Floating-Point Pixel Kill If Greater Than + // kill_gt/KILLGTv dest, src0, src1 + // if (src0.x > src1.x || + // src0.y > src1.y || + // src0.z > src1.z || + // src0.w > src1.w) { + // dest.xyzw = 1.0; + // discard; + // } else { + // dest.xyzw = 0.0; + // } + kKillGt = 25, + + // Floating-Point Pixel Kill If Equal + // kill_ge/KILLGTEv dest, src0, src1 + // if (src0.x >= src1.x || + // src0.y >= src1.y || + // src0.z >= src1.z || + // src0.w >= src1.w) { + // dest.xyzw = 1.0; + // discard; + // } else { + // dest.xyzw = 0.0; + // } + kKillGe = 26, + + // Floating-Point Pixel Kill If Equal + // kill_ne/KILLNEv dest, src0, src1 + // if (src0.x != src1.x || + // src0.y != src1.y || + // src0.z != src1.z || + // src0.w != src1.w) { + // dest.xyzw = 1.0; + // discard; + // } else { + // dest.xyzw = 0.0; + // } + kKillNe = 27, + + // dst/DSTv dest, src0, src1 + // dest.x = 1.0; + // dest.y = src0.y * src1.y; + // dest.z = src0.z; + // dest.w = src1.w; + kDst = 28, + + // Per-Component Floating-Point Maximum with Copy To Integer in AR + // maxa dest, src0, src1 + // This is a combined max + mova/MOVAv. + // a0 = (int)clamp(floor(src0.w + 0.5), -256.0, 255.0); + // dest.x = src0.x >= src1.x ? src0.x : src1.x; + // dest.y = src0.x >= src1.y ? src0.y : src1.y; + // dest.z = src0.x >= src1.z ? src0.z : src1.z; + // dest.w = src0.x >= src1.w ? src0.w : src1.w; + // The MSDN documentation specifies clamp as: + // if (!(SQResultF >= -256.0)) { + // SQResultF = -256.0; + // } + // if (SQResultF > 255.0) { + // SQResultF = 255.0; + // } + // http://web.archive.org/web/20100705151335/http://msdn.microsoft.com:80/en-us/library/bb313931.aspx + // However, using NaN as an address would be unusual. + kMaxA = 29, +}; + +struct AluVectorOpcodeInfo { + const char* name; + uint32_t operand_components_used[3]; + AluOpChangedState changed_state; + + uint32_t GetOperandCount() const { + if (!operand_components_used[2]) { + if (!operand_components_used[1]) { + if (!operand_components_used[0]) { + return 0; + } + return 1; + } + return 2; + } + return 3; + } +}; + +// 5 vector opcode bits - 32 entries. +extern const AluVectorOpcodeInfo kAluVectorOpcodeInfos[32]; + +inline const AluVectorOpcodeInfo& GetAluVectorOpcodeInfo(AluVectorOpcode opcode) { + assert_true(uint32_t(opcode) < rex::countof(kAluVectorOpcodeInfos)); + return kAluVectorOpcodeInfos[uint32_t(opcode)]; +} + +// Whether each component of a source operand is needed for the instruction if +// executed with the specified write mask, and thus can't be thrown away or be +// undefined in translation. For per-component operations, for example, only the +// components specified in the write mask are needed, but there are instructions +// with special behavior for certain components. +inline uint32_t GetAluVectorOpNeededSourceComponents(AluVectorOpcode vector_opcode, + uint32_t src_index, + uint32_t used_result_components) { + assert_not_zero(src_index); + assert_zero(used_result_components & ~uint32_t(0b1111)); + uint32_t components = used_result_components; + switch (vector_opcode) { + case AluVectorOpcode::kDp4: + case AluVectorOpcode::kMax4: + components = used_result_components ? 0b1111 : 0; + break; + case AluVectorOpcode::kDp3: + components = used_result_components ? 0b0111 : 0; + break; + case AluVectorOpcode::kDp2Add: + components = used_result_components ? (src_index == 3 ? 0b0001 : 0b0011) : 0; + break; + case AluVectorOpcode::kCube: + components = used_result_components ? 0b1111 : 0; + break; + case AluVectorOpcode::kSetpEqPush: + case AluVectorOpcode::kSetpNePush: + case AluVectorOpcode::kSetpGtPush: + case AluVectorOpcode::kSetpGePush: + components = used_result_components ? 0b1001 : 0b1000; + break; + case AluVectorOpcode::kKillEq: + case AluVectorOpcode::kKillGt: + case AluVectorOpcode::kKillGe: + case AluVectorOpcode::kKillNe: + components = 0b1111; + break; + // kDst is per-component, but not all components are used. + // operand_components_used will filter out the unused ones. + case AluVectorOpcode::kMaxA: + if (src_index == 1) { + components |= 0b1000; + } + break; + default: + break; + } + return components & GetAluVectorOpcodeInfo(vector_opcode).operand_components_used[src_index - 1]; +} + +// eM# (kExportData) register count. +constexpr uint32_t kMaxMemExportElementCount = 5; + +enum class ExportRegister : uint32_t { + kVSInterpolator0 = 0, + kVSInterpolator1, + kVSInterpolator2, + kVSInterpolator3, + kVSInterpolator4, + kVSInterpolator5, + kVSInterpolator6, + kVSInterpolator7, + kVSInterpolator8, + kVSInterpolator9, + kVSInterpolator10, + kVSInterpolator11, + kVSInterpolator12, + kVSInterpolator13, + kVSInterpolator14, + kVSInterpolator15, + + kVSPosition = 62, + + // See R6xx/R7xx registers for details (USE_VTX_POINT_SIZE, USE_VTX_EDGE_FLAG, + // USE_VTX_KILL_FLAG). + // X - PSIZE (gl_PointSize). + // According to tests and GL_AMD_program_binary_Z400 disassembly on an + // Adreno 200 device: + // * This is the full width and height of the point sprite (not half - + // gl_PointSize goes directly to oPts.x). + // * Clamped to PA_SU_POINT_MINMAX as a signed integer in rasterization: + // * -NaN - min + // * -Infinity - min + // * -Normal - min + // * -0 (0x80000000 - the smallest signed integer) - min + // * +0 - min + // * +Infinity - max + // * +NaN - max + // Y - EDGEFLAG (glEdgeFlag) for PrimitiveType::kPolygon wireframe/point + // drawing. + // Z - KILLVERTEX flag (used in 4D5307ED for grass), set for killing + // primitives based on PA_CL_CLIP_CNTL::VTX_KILL_OR condition if bits 0:30 + // of this export value (the sign bit is ignored according to the + // IPR2015-00325 sequencer specification) are not zero. + kVSPointSizeEdgeFlagKillVertex = 63, + + kPSColor0 = 0, + kPSColor1, + kPSColor2, + kPSColor3, + + // In X. + kPSDepth = 61, + + // Memory export: index.?y?? * 0100 + xe_gpu_memexport_stream_t.xyzw. + kExportAddress = 32, + // Memory export: values for texels [index+0], [index+1], ..., [index+4]. + kExportData0 = 33, + kExportData1, + kExportData2, + kExportData3, + kExportData4, +}; + +struct alignas(uint32_t) AluInstruction { + // Raw accessors. + + // Whether data is being exported (or written to local registers). + bool is_export() const { return data_.export_data == 1; } + + // Whether the jump is predicated (or conditional). + bool is_predicated() const { return data_.is_predicated; } + // Required condition value of the comparision (true or false). + bool predicate_condition() const { return data_.pred_condition == 1; } + + bool abs_constants() const { return data_.abs_constants == 1; } + bool is_const_0_addressed() const { return data_.const_0_rel_abs == 1; } + bool is_const_1_addressed() const { return data_.const_1_rel_abs == 1; } + bool is_const_address_register_relative() const { + return data_.const_address_register_relative == 1; + } + + AluVectorOpcode vector_opcode() const { return data_.vector_opc; } + uint32_t vector_write_mask() const { return data_.vector_write_mask; } + uint32_t vector_dest() const { return data_.vector_dest; } + bool is_vector_dest_relative() const { return data_.vector_dest_rel == 1; } + bool vector_clamp() const { return data_.vector_clamp == 1; } + + AluScalarOpcode scalar_opcode() const { return data_.scalar_opc; } + uint32_t scalar_write_mask() const { return data_.scalar_write_mask; } + uint32_t scalar_dest() const { return data_.scalar_dest; } + bool is_scalar_dest_relative() const { return data_.scalar_dest_rel == 1; } + bool scalar_clamp() const { return data_.scalar_clamp == 1; } + + static constexpr uint32_t src_temp_reg(uint32_t src_reg) { return src_reg & 0x3F; } + static constexpr bool is_src_temp_relative(uint32_t src_reg) { return (src_reg & 0x40) != 0; } + static constexpr bool is_src_temp_value_absolute(uint32_t src_reg) { + return (src_reg & 0x80) != 0; + } + // Full register index for constants, packed structure for temporary + // registers (unpack using src_temp_reg, is_src_temp_relative, + // is_src_temp_value_absolute). + uint32_t src_reg(size_t i) const { + switch (i) { + case 1: + return data_.src1_reg; + case 2: + return data_.src2_reg; + case 3: + return data_.src3_reg; + default: + assert_unhandled_case(i); + return 0; + } + } + bool src_is_temp(size_t i) const { + switch (i) { + case 1: + return bool(data_.src1_sel); + case 2: + return bool(data_.src2_sel); + case 3: + return bool(data_.src3_sel); + default: + assert_unhandled_case(i); + return 0; + } + } + // Whether the specified operand is actually a constant is disregarded in this + // function so its scope is limited to just parsing the structure's layout - + // to decide whether to use relative addressing for the operand as a whole, + // check externally whether the operand is actually a constant first. + // + // For the constant operand in mulsc, addsc, subsc, this should be called for + // the operand index 3. Note that the XNA disassembler takes the addressing + // mode for the constant scalar operand unconditionally from const_1_rel_abs, + // and ignores the +aL for it unless the scalar operation is co-issued with a + // vector operation reading from a constant. However, the XNA assembler treats + // the constant scalar operand as a constant in the third operand, and places + // the addressing mode for it in const_0_rel_abs if no other constants are + // used in the whole ALU instruction. The validator also doesn't report + // anything if +aL is used when the constant scalar operand is the only + // constant in the instruction (and explicitly calls it the third constant in + // the error message in case both vector operands are constants, and different + // addressing modes are used for the second vector operand and the constant + // scalar operand). Passing the disassembly produced by XNA back to the + // assembler results in different microcode in this case. This indicates that + // most likely there's a bug in the XNA disassembler, and that the addressing + // mode for the constant scalar operand should actually be taken the same way + // as for the third vector operand - from const_0_rel_abs if there are no + // constant vector operands, or from const_1_rel_abs if there is at least one. + bool src_const_is_addressed(size_t i) const { + // "error X7100: When three constants are used in one instruction, the + // second and third constant must either both be non-relative, or both be + // relative." + // Whether to use const_0_rel_abs or const_1_rel_abs is essentially + // min(sum of whether the previous operands are constants, 1). + switch (i) { + case 1: + return bool(data_.const_0_rel_abs); + case 2: + return bool(src_is_temp(1) ? data_.const_0_rel_abs : data_.const_1_rel_abs); + case 3: + return bool((src_is_temp(1) && src_is_temp(2)) ? data_.const_0_rel_abs + : data_.const_1_rel_abs); + default: + assert_unhandled_case(i); + return false; + } + } + uint32_t src_swizzle(size_t i) const { + switch (i) { + case 1: + return data_.src1_swiz; + case 2: + return data_.src2_swiz; + case 3: + return data_.src3_swiz; + default: + assert_unhandled_case(i); + return 0; + } + } + bool src_negate(size_t i) const { + switch (i) { + case 1: + return data_.src1_reg_negate == 1; + case 2: + return data_.src2_reg_negate == 1; + case 3: + return data_.src3_reg_negate == 1; + default: + assert_unhandled_case(i); + return 0; + } + } + + uint32_t scalar_const_reg_op_src_temp_reg() const { + return (uint32_t(data_.scalar_opc) & 1) | (data_.src3_sel << 1) | (data_.src3_swiz & 0x3C); + } + + // Helpers. + + // Returns the absolute component index calculated from the relative swizzle + // in an ALU instruction. + static constexpr uint32_t GetSwizzledComponentIndex(uint32_t swizzle, uint32_t component_index) { + return ((swizzle >> (2 * component_index)) + component_index) & 3; + } + + // Note that even if the export component is unused (like W of the vertex + // shader misc register, YZW of pixel shader depth), it must still not be + // excluded - that may make disassembly not reassemblable if there are + // constant 0 writes in the export, like, oPts.x000 will be assembled, but + // oPts.x00_ will not, even though W has no effect on anything. + uint32_t GetVectorOpResultWriteMask() const { + uint32_t mask = vector_write_mask(); + if (is_export()) { + mask &= ~scalar_write_mask(); + } + return mask; + } + uint32_t GetScalarOpResultWriteMask() const { + uint32_t mask = scalar_write_mask(); + if (is_export()) { + mask &= ~vector_write_mask(); + } + return mask; + } + uint32_t GetConstant0WriteMask() const { + if (!is_export() || !is_scalar_dest_relative()) { + return 0b0000; + } + return 0b1111 & ~(vector_write_mask() | scalar_write_mask()); + } + uint32_t GetConstant1WriteMask() const { + if (!is_export()) { + return 0b0000; + } + return vector_write_mask() & scalar_write_mask(); + } + + private: + struct Data { + struct { + // If exporting, both vector and scalar operations use the vector + // destination (which can't be relative in this case). + // Not very important note: If both scalar and vector operations exporting + // something have empty write mask, the XNA assembler forces vector_dest + // to 0 (interpolator 0 or color 0) directly in the microcode. + uint32_t vector_dest : 6; + uint32_t vector_dest_rel : 1; + uint32_t abs_constants : 1; + uint32_t scalar_dest : 6; + uint32_t scalar_dest_rel : 1; + // Exports have different write masking (export is done to vector_dest by + // both the vector and the scalar operation, and exports can write + // constant 0 and 1). For each component: + // - vector_write_mask 0, scalar_write_mask 0: + // - scalar_dest_rel 0 - unchanged. + // - scalar_dest_rel 1 - constant 0 (all components must be written). + // - vector_write_mask 1, scalar_write_mask 0 - from vector operation. + // - vector_write_mask 0, scalar_write_mask 1 - from scalar operation. + // - vector_write_mask 1, scalar_write_mask 1 - constant 1. + uint32_t export_data : 1; + uint32_t vector_write_mask : 4; + uint32_t scalar_write_mask : 4; + uint32_t vector_clamp : 1; + uint32_t scalar_clamp : 1; + AluScalarOpcode scalar_opc : 6; + }; + struct { + // Swizzles are component-relative. + uint32_t src3_swiz : 8; + uint32_t src2_swiz : 8; + uint32_t src1_swiz : 8; + uint32_t src3_reg_negate : 1; + uint32_t src2_reg_negate : 1; + uint32_t src1_reg_negate : 1; + uint32_t pred_condition : 1; + uint32_t is_predicated : 1; + // Temporary registers can have only absolute and aL-relative indices, not + // a0-relative. + uint32_t const_address_register_relative : 1; + uint32_t const_1_rel_abs : 1; + uint32_t const_0_rel_abs : 1; + }; + struct { + uint32_t src3_reg : 8; + uint32_t src2_reg : 8; + uint32_t src1_reg : 8; + AluVectorOpcode vector_opc : 5; + uint32_t src3_sel : 1; + uint32_t src2_sel : 1; + uint32_t src1_sel : 1; + }; + }; + Data data_; +}; +static_assert_size(AluInstruction, sizeof(uint32_t) * 3); + +} // namespace rex::graphics::ucode diff --git a/include/rex/graphics/graphics_system.h b/include/rex/graphics/graphics_system.h new file mode 100644 index 0000000..8fe5ca1 --- /dev/null +++ b/include/rex/graphics/graphics_system.h @@ -0,0 +1,139 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include "rex/system/function_dispatcher.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +// Forward declarations +namespace rex { +class Memory; +namespace stream { +class ByteStream; +} // namespace stream +} // namespace rex + +namespace rex::ui { +class WindowedAppContext; +} // namespace rex::ui + +namespace rex::graphics { + +class CommandProcessor; + +class GraphicsSystem : public system::IGraphicsSystem { + public: + virtual ~GraphicsSystem(); + + virtual std::string name() const = 0; + + memory::Memory* memory() const { return memory_; } + runtime::FunctionDispatcher* function_dispatcher() const { return function_dispatcher_; } + system::KernelState* kernel_state() const { return kernel_state_; } + ::rex::ui::GraphicsProvider* provider() const { return provider_.get(); } + ::rex::ui::Presenter* presenter() const { return presenter_.get(); } + + X_STATUS SetupPresentation(::rex::ui::WindowedAppContext* app_context) override; + X_STATUS SetupGuestGpu(runtime::FunctionDispatcher* function_dispatcher, + system::KernelState* kernel_state) override; + bool has_presentation() const override { return presenter_ != nullptr; } + void Shutdown() override; + + // May be called from any thread any number of times, even during recovery + // from a device loss. + void OnHostGpuLossFromAnyThread(bool is_responsible); + + RegisterFile* register_file() { return ®ister_file_; } + CommandProcessor* command_processor() const { return command_processor_.get(); } + + virtual void InitializeRingBuffer(uint32_t ptr, uint32_t size_log2); + virtual void EnableReadPointerWriteBack(uint32_t ptr, uint32_t block_size_log2); + + virtual void SetInterruptCallback(uint32_t callback, uint32_t user_data); + void DispatchInterruptCallback(uint32_t source, uint32_t cpu); + + virtual void ClearCaches(); + virtual void InvalidateGpuMemory(); + + void InitializeShaderStorage(const std::filesystem::path& cache_root, uint32_t title_id, + bool blocking); + + void RequestFrameTrace(); + void BeginTracing(); + void EndTracing(); + + bool is_paused() const { return paused_; } + void Pause(); + void Resume(); + + bool Save(::rex::stream::ByteStream* stream); + bool Restore(::rex::stream::ByteStream* stream); + + protected: + GraphicsSystem(); + + // Backends build their provider here. Called lazily from either setup + // entry point; with_presentation is false only on headless guest-GPU paths. + virtual void CreateProvider(bool with_presentation) = 0; + + virtual std::unique_ptr CreateCommandProcessor() = 0; + + static uint32_t ReadRegisterThunk(void* ppc_context, GraphicsSystem* gs, uint32_t addr); + static void WriteRegisterThunk(void* ppc_context, GraphicsSystem* gs, uint32_t addr, + uint32_t value); + + uint32_t ReadRegister(uint32_t addr); + void WriteRegister(uint32_t addr, uint32_t value); + + void MarkVblank(); + + memory::Memory* memory_ = nullptr; + runtime::FunctionDispatcher* function_dispatcher_ = nullptr; + system::KernelState* kernel_state_ = nullptr; + ::rex::ui::WindowedAppContext* app_context_ = nullptr; + std::unique_ptr<::rex::ui::GraphicsProvider> provider_; + bool provider_supports_presentation_ = false; + + uint32_t interrupt_callback_ = 0; + uint32_t interrupt_callback_data_ = 0; + + std::atomic vsync_worker_running_; + system::object_ref vsync_worker_thread_; + + RegisterFile register_file_; + std::unique_ptr command_processor_; + + bool paused_ = false; + + private: + std::unique_ptr<::rex::ui::Presenter> presenter_; + + std::atomic_flag host_gpu_loss_reported_; +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/packet_disassembler.h b/include/rex/graphics/packet_disassembler.h new file mode 100644 index 0000000..1b1ba5f --- /dev/null +++ b/include/rex/graphics/packet_disassembler.h @@ -0,0 +1,95 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include + +namespace rex::graphics { + +enum class PacketCategory { + kGeneric, + kDraw, + kSwap, +}; + +struct PacketTypeInfo { + PacketCategory category; + const char* name; +}; + +struct PacketAction { + enum class Type { + kRegisterWrite, + kSetBinMask, + kSetBinSelect, + }; + Type type; + + union { + struct { + uint32_t index; + uint32_t value; + } register_write; + struct { + uint64_t value; + } set_bin_mask; + struct { + uint64_t value; + } set_bin_select; + }; + + static PacketAction RegisterWrite(uint32_t index, uint32_t value) { + PacketAction action; + action.type = Type::kRegisterWrite; + action.register_write.index = index; + action.register_write.value = value; + return action; + } + + static PacketAction SetBinMask(uint64_t value) { + PacketAction action; + action.type = Type::kSetBinMask; + action.set_bin_mask.value = value; + return action; + } + + static PacketAction SetBinSelect(uint64_t value) { + PacketAction action; + action.type = Type::kSetBinSelect; + action.set_bin_select.value = value; + return action; + } +}; + +struct PacketInfo { + const PacketTypeInfo* type_info; + bool predicated; + uint32_t count; + std::vector actions; +}; + +class PacketDisassembler { + public: + static PacketCategory GetPacketCategory(const uint8_t* base_ptr); + + static bool DisasmPacketType0(const uint8_t* base_ptr, uint32_t packet, PacketInfo* out_info); + static bool DisasmPacketType1(const uint8_t* base_ptr, uint32_t packet, PacketInfo* out_info); + static bool DisasmPacketType2(const uint8_t* base_ptr, uint32_t packet, PacketInfo* out_info); + static bool DisasmPacketType3(const uint8_t* base_ptr, uint32_t packet, PacketInfo* out_info); + static bool DisasmPacket(const uint8_t* base_ptr, PacketInfo* out_info); +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/pipeline/render_target/cache.h b/include/rex/graphics/pipeline/render_target/cache.h new file mode 100644 index 0000000..18e6b14 --- /dev/null +++ b/include/rex/graphics/pipeline/render_target/cache.h @@ -0,0 +1,700 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace rex::graphics { + +class RenderTargetCache { + public: + // High-level emulation logic implementation path. + enum class Path { + // Approximate method using conventional host render targets and copying + // ("transferring ownership" of tiles) between render targets to support + // aliasing. + // + // May be irreparably inaccurate, completely at the mercy of the host API's + // fixed-function output-merger, primarily because it has to perform + // blending - and when using a different pixel format, it will behave + // differently (the most important factor here is the range - it's clamped + // for normalized formats, but not for floating-point ones). + // + // On a Direct3D 11-level device, formats which can be mapped directly + // (disregarding things like blending internal precision details): + // - 8_8_8_8 + // - 2_10_10_10 + // - 32_FLOAT + // - 32_32_FLOAT + // - D24S8 + // Can be mapped directly, but require handling in shaders: + // - D24FS8 with truncated SV_DepthLessEqual output (or SV_Depth, which is + // suboptimal, as it prevents early depth / stencil from working). To + // support bit-exact reinterpretation to and from D24F for unmodified + // areas using pixel shader depth output without unrestricted depth range, + // 0...1 of the guest depth should be mapped to 0...0.5 on the host in the + // viewport and conversion. + // Can be mapped directly, but not supporting rare edge cases: + // - 16_16_FLOAT, k_16_16_16_16_FLOAT - the Xenos float16 doesn't have + // special values. + // Significant differences: + // - 8_8_8_8_GAMMA - the piecewise linear gamma curve is very different than + // sRGB, one possible path is conversion in shaders (resulting in + // incorrect blending, especially visible on decals in 4D5307E6), another + // is using sRGB render targets and either conversion on resolve or + // reading the resolved data as a true sRGB texture (incorrect when the + // game accesses the data directly, like 4541080F). + // - 2_10_10_10_FLOAT - ranges significantly different than in float16, much + // smaller RGB range, and alpha is fixed-point and has only 2 bits. + // - 16_16, 16_16_16_16 - has -32 to 32 range, not -1 to 1 - need either to + // truncate the range for blending to work correctly, or divide by 32 in + // shaders breaking multiplication in blending. + kHostRenderTargets, + + // Custom output-merger implementation, with full per-pixel and per-sample + // control, however, only available on hosts with raster-ordered writes from + // pixel shaders. + kPixelShaderInterlock, + }; + + // Pixel shader interlock implementation helpers. + + // Appended to the format in the format constant via bitwise OR. + enum : uint32_t { + kPSIColorFormatFlag_64bpp_Shift = xenos::kColorRenderTargetFormatBits, + // Requires clamping of blending sources and factors. + kPSIColorFormatFlag_FixedPointColor_Shift, + kPSIColorFormatFlag_FixedPointAlpha_Shift, + + kPSIColorFormatFlag_64bpp = uint32_t(1) << kPSIColorFormatFlag_64bpp_Shift, + kPSIColorFormatFlag_FixedPointColor = uint32_t(1) << kPSIColorFormatFlag_FixedPointColor_Shift, + kPSIColorFormatFlag_FixedPointAlpha = uint32_t(1) << kPSIColorFormatFlag_FixedPointAlpha_Shift, + }; + + static constexpr uint32_t AddPSIColorFormatFlags(xenos::ColorRenderTargetFormat format) { + uint32_t format_flags = uint32_t(format); + if (format == xenos::ColorRenderTargetFormat::k_16_16_16_16 || + format == xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT || + format == xenos::ColorRenderTargetFormat::k_32_32_FLOAT) { + format_flags |= kPSIColorFormatFlag_64bpp; + } + if (format == xenos::ColorRenderTargetFormat::k_8_8_8_8 || + format == xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA || + format == xenos::ColorRenderTargetFormat::k_2_10_10_10 || + format == xenos::ColorRenderTargetFormat::k_16_16 || + format == xenos::ColorRenderTargetFormat::k_16_16_16_16 || + format == xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10) { + format_flags |= kPSIColorFormatFlag_FixedPointColor | kPSIColorFormatFlag_FixedPointAlpha; + } else if (format == xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT || + format == xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16) { + format_flags |= kPSIColorFormatFlag_FixedPointAlpha; + } + return format_flags; + } + + static void GetPSIColorFormatInfo(xenos::ColorRenderTargetFormat format, uint32_t write_mask, + float& clamp_rgb_low, float& clamp_alpha_low, + float& clamp_rgb_high, float& clamp_alpha_high, + uint32_t& keep_mask_low, uint32_t& keep_mask_high); + + virtual ~RenderTargetCache(); + + virtual Path GetPath() const = 0; + + // Resolution scaling on the EDRAM side is performed by multiplying the EDRAM + // tile size by the resolution scale. + // Note: Only integer scaling factors are provided because fractional ones, + // even with 0.5 granularity, cause significant issues in addition to the ones + // already present with integer scaling. 1.5 (from 1280x720 to 1920x1080) may + // be useful, but it would cause pixel coverage issues with odd dimensions of + // screen-space geometry, most importantly 1x1 that is often the final step in + // reduction algorithms such as average luminance computation in HDR. A + // single-pixel quad, either 0...1 without half-pixel offset or 0.5...1.5 with + // it (covers only the first pixel according the top-left rule), with 1.5x + // resolution scaling, would become 0...1.5 (only the first pixel covered) or + // 0.75...2.25 (only the second). The workaround used in Xenia for 2x and 3x + // resolution scaling for filling the gap caused by the half-pixel offset + // becoming whole-pixel - stretching the second column / row of pixels into + // the first - will not work in this case, as for one-pixel primitives without + // half-pixel offset (covering only the first pixel, but not the second, with + // 1.5x), it will actually cause the pixel to be erased with 1.5x scaling. As + // within one pass there can be geometry both with and without the half-pixel + // offset (not only depending on PA_SU_VTX_CNTL::PIX_CENTER, but also with the + // half-pixel offset possibly reverted manually), the emulator can't decide + // whether the stretching workaround actually needs to be used. So, with 1.5x, + // depending on how the game draws its screen-space effects and on whether the + // workaround is used, in some cases, nothing will just be drawn to the first + // pixel, while in other cases, the effect will be drawn to it, but the + // stretching workaround will replace it with the undefined value in the + // second pixel. Also, with 1.5x, rounding of integer coordinates becomes + // complicated, also in part due to the half-pixel offset. Odd texture sizes + // would need to be rounded down, as according to the top-left rule, a 1.5x1.5 + // quad at the 0 or 0.75 origin (after the scaling) will cover only 1 pixel - + // so, if the resulting texture was 2x2 rather than 1x1, undefined pixels + // would participate in filtering. However, 1x1 scissor rounded to 1x1, with + // the half-pixel offset of vertices, would cause the entire 0.75...2.25 quad + // to be discarded. + uint32_t draw_resolution_scale_x() const { return draw_resolution_scale_x_; } + uint32_t draw_resolution_scale_y() const { return draw_resolution_scale_y_; } + bool IsDrawResolutionScaled() const { + return draw_resolution_scale_x() > 1 || draw_resolution_scale_y() > 1; + } + + // Virtual (both the common code and the implementation may do something + // here), don't call from destructors (does work not needed for shutdown + // also). + virtual void ClearCache(); + + virtual void BeginFrame(); + + virtual bool Update(bool is_rasterization_done, reg::RB_DEPTHCONTROL normalized_depth_control, + uint32_t normalized_color_mask, const Shader& vertex_shader); + + // Returns bits where 0 is whether a depth render target is currently bound on + // the host and 1... are whether the same applies to color render targets, and + // formats (resource formats, but if needed, with gamma taken into account) of + // each. + uint32_t GetLastUpdateBoundRenderTargets(uint32_t* depth_and_color_formats_out = nullptr) const; + + protected: + RenderTargetCache(const RegisterFile& register_file, const memory::Memory& memory, + TraceWriter* trace_writer, uint32_t draw_resolution_scale_x, + uint32_t draw_resolution_scale_y) + : register_file_(register_file), + draw_extent_estimator_(register_file, memory, trace_writer), + draw_resolution_scale_x_(draw_resolution_scale_x), + draw_resolution_scale_y_(draw_resolution_scale_y) { + assert_not_zero(draw_resolution_scale_x); + assert_not_zero(draw_resolution_scale_y); + } + + const RegisterFile& register_file() const { return register_file_; } + + virtual bool IsGammaFormatHostStorageSeparate() const = 0; + + // Call last in implementation-specific initialization (when things like path + // are initialized by the implementation). + void InitializeCommon(); + // May be called from the destructor, or from the implementation shutdown to + // destroy all render targets before destroying what they depend on in the + // implementation. + void DestroyAllRenderTargets(bool shutting_down); + // Call last in implementation-specific shutdown, also callable from the + // destructor. + void ShutdownCommon(); + + // For host render targets, implemented via transfer of ownership of EDRAM + // 80x16-sample tiles between host render targets. When a range is + // transferred, its data is copied, bit-exactly from the guest's perspective + // (when dangerous, such as because of non-propagated NaN, primarily in the + // float16 case, by drawing to an integer view of the render target texture), + // from the previous host render target to the new one, by drawing rectangles + // with a pixel shader converting the previous host render target to a guest + // bit pattern, reinterpreting it in the new format. If depth is emulated with + // float32, this may lead to loss of data - specifically for depth, both guest + // format ownership and float32 ownership are tracked, and to let color data + // overwrite depth data, loading during ownership transfer is done from + // intersections of the current guest ownership ranges and float32 ownership + // ranges. Ownership transfer happens when a render target is needed - based + // on the current viewport; or, if no viewport is available, ownership of the + // rest of the EDRAM is transferred. + + union RenderTargetKey { + uint32_t key; + struct { + uint32_t base_tiles : xenos::kEdramBaseTilesBits; // 11 + // At 4x MSAA (2 horizontal samples), max. align(8192 * 2, 80) / 80 = 205. + // For pitch at 64bpp, multiply by 2 (or use GetPitchTiles). + uint32_t pitch_tiles_at_32bpp : 8; // 19 + xenos::MsaaSamples msaa_samples : xenos::kMsaaSamplesBits; // 21 + uint32_t is_depth : 1; // 22 + // Ignoring the blending precision and sRGB. + uint32_t resource_format : xenos::kRenderTargetFormatBits; // 26 + }; + + RenderTargetKey() : key(0) { static_assert_size(*this, sizeof(key)); } + + struct Hasher { + size_t operator()(const RenderTargetKey& render_target_key) const { + return std::hash{}(render_target_key.key); + } + }; + bool operator==(const RenderTargetKey& other_key) const { return key == other_key.key; } + bool operator!=(const RenderTargetKey& other_key) const { return !(*this == other_key); } + + bool IsEmpty() const { + // Meaningless when pitch_tiles_at_32bpp == 0, but for comparison + // purposes, only treat everything being 0 as a special case. + return key == 0; + } + + xenos::ColorRenderTargetFormat GetColorFormat() const { + assert_false(is_depth); + return xenos::ColorRenderTargetFormat(resource_format); + } + xenos::DepthRenderTargetFormat GetDepthFormat() const { + assert_true(is_depth); + return xenos::DepthRenderTargetFormat(resource_format); + } + bool Is64bpp() const { + if (is_depth) { + return false; + } + return xenos::IsColorRenderTargetFormat64bpp(GetColorFormat()); + } + const char* GetFormatName() const { + return is_depth ? xenos::GetDepthRenderTargetFormatName(GetDepthFormat()) + : xenos::GetColorRenderTargetFormatName(GetColorFormat()); + } + + uint32_t GetPitchTiles() const { return pitch_tiles_at_32bpp << uint32_t(Is64bpp()); } + static constexpr uint32_t GetWidth(uint32_t pitch_tiles_at_32bpp, + xenos::MsaaSamples msaa_samples) { + return pitch_tiles_at_32bpp * + (xenos::kEdramTileWidthSamples >> uint32_t(msaa_samples >= xenos::MsaaSamples::k4X)); + } + uint32_t GetWidth() const { return GetWidth(pitch_tiles_at_32bpp, msaa_samples); } + + std::string GetDebugName() const { + return fmt::format("RT @ {}t, <{}t>, {}xMSAA, {}", base_tiles, GetPitchTiles(), + uint32_t(1) << uint32_t(msaa_samples), GetFormatName()); + } + }; + + class RenderTarget { + public: + virtual ~RenderTarget() = default; + // Exclusive ownership, plus no point in moving (only allocated via new). + RenderTarget(const RenderTarget& render_target) = delete; + RenderTarget& operator=(const RenderTarget& render_target) = delete; + RenderTarget(RenderTarget&& render_target) = delete; + RenderTarget& operator=(RenderTarget&& render_target) = delete; + RenderTargetKey key() const { return key_; } + + protected: + RenderTarget(RenderTargetKey key) : key_(key) {} + + private: + RenderTargetKey key_; + }; + + struct Transfer { + uint32_t start_tiles; + uint32_t end_tiles; + RenderTarget* source; + RenderTarget* host_depth_source; + Transfer(uint32_t start_tiles, uint32_t end_tiles, RenderTarget* source, + RenderTarget* host_depth_source) + : start_tiles(start_tiles), + end_tiles(end_tiles), + source(source), + host_depth_source(host_depth_source) { + assert_true(start_tiles < end_tiles); + } + struct Rectangle { + uint32_t x_pixels; + uint32_t y_pixels; + uint32_t width_pixels; + uint32_t height_pixels; + }; + static constexpr uint32_t kMaxRectanglesWithoutCutout = 3; + static constexpr uint32_t kMaxCutoutBorderRectangles = 4; + static constexpr uint32_t kMaxRectanglesWithCutout = + kMaxRectanglesWithoutCutout * kMaxCutoutBorderRectangles; + // Cutout can be specified for resolve clears - not to transfer areas that + // will be cleared to a single value anyway. + static uint32_t GetRangeRectangles(uint32_t start_tiles, uint32_t end_tiles, + uint32_t base_tiles, uint32_t pitch_tiles, + xenos::MsaaSamples msaa_samples, bool is_64bpp, + Rectangle* rectangles_out, + const Rectangle* cutout = nullptr); + uint32_t GetRectangles(uint32_t base_tiles, uint32_t pitch_tiles, + xenos::MsaaSamples msaa_samples, bool is_64bpp, + Rectangle* rectangles_out, const Rectangle* cutout = nullptr) const { + return GetRangeRectangles(start_tiles, end_tiles, base_tiles, pitch_tiles, msaa_samples, + is_64bpp, rectangles_out, cutout); + } + bool AreSourcesSame(const Transfer& other_transfer) const { + return source == other_transfer.source && + host_depth_source == other_transfer.host_depth_source; + } + + private: + static uint32_t AddRectangle(const Rectangle& rectangle, Rectangle* rectangles_out, + const Rectangle* cutout = nullptr); + }; + + union HostDepthStoreRectangleConstant { + uint32_t constant; + struct { + // - 1 because the maximum is 0x1FFF / 8, not 0x2000 / 8. + uint32_t x_pixels_div_8 : xenos::kResolveSizeBits - 1 - xenos::kResolveAlignmentPixelsLog2; + uint32_t y_pixels_div_8 : xenos::kResolveSizeBits - 1 - xenos::kResolveAlignmentPixelsLog2; + uint32_t width_pixels_div_8_minus_1 : xenos::kResolveSizeBits - 1 - + xenos::kResolveAlignmentPixelsLog2; + }; + HostDepthStoreRectangleConstant() : constant(0) { static_assert_size(*this, sizeof(constant)); } + }; + + union HostDepthStoreRenderTargetConstant { + uint32_t constant; + struct { + uint32_t pitch_tiles : xenos::kEdramPitchTilesBits; + uint32_t resolution_scale_x : 3; + uint32_t resolution_scale_y : 3; + // Whether 2x MSAA is supported natively rather than through 4x. + uint32_t msaa_2x_supported : 1; + }; + HostDepthStoreRenderTargetConstant() : constant(0) { + static_assert_size(*this, sizeof(constant)); + } + }; + + struct HostDepthStoreConstants { + HostDepthStoreRectangleConstant rectangle; + HostDepthStoreRenderTargetConstant render_target; + }; + + struct ResolveCopyDumpRectangle { + RenderTarget* render_target; + // If rows == 1: + // Row row_first span: + // [row_first_start, row_last_end) + // If rows > 1: + // Row row_first + row span: + // [row_first_start, row_length_used) + // Rows [row_first + 1, row_first + rows - 1) span: + // [row * pitch, row * pitch + row_length_used) + // Row row_first + rows - 1 span: + // [row * pitch, row * pitch + row_last_end) + uint32_t row_first; + uint32_t rows; + uint32_t row_first_start; + uint32_t row_last_end; + ResolveCopyDumpRectangle(RenderTarget* render_target, uint32_t row_first, uint32_t rows, + uint32_t row_first_start, uint32_t row_last_end) + : render_target(render_target), + row_first(row_first), + rows(rows), + row_first_start(row_first_start), + row_last_end(row_last_end) {} + struct Dispatch { + // Base plus offset may exceed the EDRAM tile count in case of EDRAM + // addressing wrapping. + uint32_t offset; + uint32_t width_tiles; + uint32_t height_tiles; + }; + static constexpr uint32_t kMaxDispatches = 3; + uint32_t GetDispatches(uint32_t pitch_tiles, uint32_t row_length_used, + Dispatch* dispatches_out) const { + if (!rows) { + return 0; + } + // If the first and / or the last rows have the same X spans as the middle + // part, merge them with it. + uint32_t dispatch_count = 0; + if (rows == 1 || row_first_start) { + Dispatch& dispatch_first = dispatches_out[dispatch_count++]; + dispatch_first.offset = row_first * pitch_tiles + row_first_start; + dispatch_first.width_tiles = (rows == 1 ? row_last_end : row_length_used) - row_first_start; + dispatch_first.height_tiles = 1; + if (rows == 1) { + return dispatch_count; + } + } + uint32_t mid_row_first = row_first + 1; + uint32_t mid_rows = rows - 2; + if (!row_first_start) { + --mid_row_first; + ++mid_rows; + } + if (row_last_end == row_length_used) { + ++mid_rows; + } + if (mid_rows) { + Dispatch& dispatch_mid = dispatches_out[dispatch_count++]; + dispatch_mid.offset = mid_row_first * pitch_tiles; + dispatch_mid.width_tiles = row_length_used; + dispatch_mid.height_tiles = mid_rows; + } + if (row_last_end != row_length_used) { + Dispatch& dispatch_last = dispatches_out[dispatch_count++]; + dispatch_last.offset = (row_first + rows - 1) * pitch_tiles; + dispatch_last.width_tiles = row_last_end; + dispatch_last.height_tiles = 1; + } + return dispatch_count; + } + }; + + // A flattened dispatch extracted from ResolveCopyDumpRectangle. + struct ResolveCopyDispatch { + uint32_t rectangle_index; + ResolveCopyDumpRectangle::Dispatch dispatch; + ResolveCopyDispatch(uint32_t rectangle_index, + const ResolveCopyDumpRectangle::Dispatch& dispatch) + : rectangle_index(rectangle_index), dispatch(dispatch) {} + }; + + virtual uint32_t GetMaxRenderTargetWidth() const = 0; + virtual uint32_t GetMaxRenderTargetHeight() const = 0; + + // Returns the height of a render target that's needed and can be created, + // taking guest and host limits into account. EDRAM base and 32bpp/64bpp are + // not taken into account, the same height is used for all render targets even + // if the implementation supports mixed-size render targets, so the + // implementation can freely disable individual render targets and let the + // other ones use the newly available space without restarting the whole + // render pass (on Vulkan, the actually used height is specified in + // VkFramebuffer). + uint32_t GetRenderTargetHeight(uint32_t pitch_tiles_at_32bpp, + xenos::MsaaSamples msaa_samples) const; + + virtual RenderTarget* CreateRenderTarget(RenderTargetKey key) = 0; + + // Whether depth buffer is encoded differently on the host, thus after + // aliasing naively, precision may be lost - host depth must only be + // overwritten if the new guest value is different than the current host depth + // when converted to the guest format (this catches the usual case of + // overwriting the depth buffer for clearing it mostly). 534507D6 intro + // cutscene, for example, has a good example of corruption that happens if + // this is not handled - the upper 1280x384 pixels are rendered in a very + // "striped" way if the depth precision is lost (if this is made always return + // false). + virtual bool IsHostDepthEncodingDifferent(xenos::DepthRenderTargetFormat format) const = 0; + + void ResetAccumulatedRenderTargets() { are_accumulated_render_targets_valid_ = false; } + RenderTarget* const* last_update_accumulated_render_targets() const { + assert_true(GetPath() == Path::kHostRenderTargets); + return last_update_accumulated_render_targets_; + } + const std::vector* last_update_transfers() const { + assert_true(GetPath() == Path::kHostRenderTargets); + return last_update_transfers_; + } + + HostDepthStoreRenderTargetConstant GetHostDepthStoreRenderTargetConstant( + uint32_t pitch_tiles, bool msaa_2x_supported) const { + HostDepthStoreRenderTargetConstant constant; + constant.pitch_tiles = pitch_tiles; + // 3 bits for each. + assert_true(draw_resolution_scale_x() <= 7); + assert_true(draw_resolution_scale_y() <= 7); + constant.resolution_scale_x = draw_resolution_scale_x(); + constant.resolution_scale_y = draw_resolution_scale_y(); + constant.msaa_2x_supported = uint32_t(msaa_2x_supported); + return constant; + } + void GetHostDepthStoreRectangleInfo(const Transfer::Rectangle& transfer_rectangle, + xenos::MsaaSamples msaa_samples, + HostDepthStoreRectangleConstant& rectangle_constant_out, + uint32_t& group_count_x_out, + uint32_t& group_count_y_out) const; + + // Returns mappings between ranges within the specified tile rectangle (not + // render target texture rectangle - textures may have any pitch they need) + // from ResolveInfo::GetCopyEdramTileSpan and render targets owning them to + // rectangles_out. + void GetResolveCopyRectanglesToDump(uint32_t base, uint32_t row_length, uint32_t rows, + uint32_t pitch, + std::vector& rectangles_out) const; + void GetResolveCopyDispatchesToDump(uint32_t base, uint32_t row_length, uint32_t rows, + uint32_t pitch, + std::vector& rectangles_out, + std::vector& dispatches_out) const; + + // Sets up the needed render targets and transfers to perform a clear in a + // resolve operation via a host render target clear. resolve_info is expected + // to be obtained via draw_util::GetResolveInfo. Returns whether any clears + // need to be done (false in both empty and error cases). + // TODO(Triang3l): Try to defer clears until the first draw in the next pass + // (if it uses one or both render targets being cleared) for tile-based GPUs. + bool PrepareHostRenderTargetsResolveClear(const draw_util::ResolveInfo& resolve_info, + Transfer::Rectangle& clear_rectangle_out, + RenderTarget*& depth_render_target_out, + std::vector& depth_transfers_out, + RenderTarget*& color_render_target_out, + std::vector& color_transfers_out); + + // For restoring EDRAM contents from frame traces, obtains or creates a render + // target at base 0 with of 1280 (only 1 sample and color because copying + // between MSAA render targets and buffers is not possible in Direct3D 12, and + // depth may require additional format conversions, not needed really) and + // transfers ownership of the entire EDRAM to that render target. If a + // full-EDRAM render target can't be created (for instance, due to size + // limitations on the host), nullptr is returned. + RenderTarget* PrepareFullEdram1280xRenderTargetForSnapshotRestoration( + xenos::ColorRenderTargetFormat color_format); + + // For pixel shader interlock. + + virtual void RequestPixelShaderInterlockBarrier() {} + + // To be called by the implementation when interlocked writes to all of the + // EDRAM memory are committed with a memory barrier. + void PixelShaderInterlockFullEdramBarrierPlaced(); + + private: + const RegisterFile& register_file_; + uint32_t draw_resolution_scale_x_; + uint32_t draw_resolution_scale_y_; + + DrawExtentEstimator draw_extent_estimator_; + + // For host render targets. + + struct OwnershipRange { + uint32_t end_tiles; + // Need to store keys, not pointers to render targets themselves, because + // ownership transfer is also what's used to determine when to place + // barriers with pixel shader interlock, and in this case there are no host + // render targets. + // Render target this range is last used by. + RenderTargetKey render_target; + // Last host-side depth render targets that used this range even if it has + // been used by a different render target since then, only used if the + // respective format has a different encoding on the host. They are tracked + // separately, overwritten if the host value converted to the guest format + // becomes out of sync with the guest value. Even if the host uses float32 + // to emulate both unorm24 and float24 (Vulkan on AMD), the unorm24 and + // float24 render targets are tracked separately from each other, so + // switching between unorm24 and float24 for the same depth data (clearing + // of most render targets is done through unorm24 without a viewport - very + // common) is not destructive as well (f32tof24(host_f32) == guest_f24 does + // not imply f32tou24(host_f32) == guest_u24, thus aliasing float24 with + // unorm24 through the same float32 buffer will drop the precision of the + // float32 value to that of an unorm24 with a totally wrong value). If the + // range hasn't been used yet (render_target.IsEmpty() == true), these are + // empty too. + RenderTargetKey host_depth_render_target_unorm24; + RenderTargetKey host_depth_render_target_float24; + OwnershipRange(uint32_t end_tiles, RenderTargetKey render_target, + RenderTargetKey host_depth_render_target_unorm24, + RenderTargetKey host_depth_render_target_float24) + : end_tiles(end_tiles), + render_target(render_target), + host_depth_render_target_unorm24(host_depth_render_target_unorm24), + host_depth_render_target_float24(host_depth_render_target_float24) {} + const RenderTargetKey& GetHostDepthRenderTarget( + xenos::DepthRenderTargetFormat resource_format) const { + assert_true(resource_format == xenos::DepthRenderTargetFormat::kD24S8 || + resource_format == xenos::DepthRenderTargetFormat::kD24FS8, + "Illegal resource format"); + return resource_format == xenos::DepthRenderTargetFormat::kD24S8 + ? host_depth_render_target_unorm24 + : host_depth_render_target_float24; + } + RenderTargetKey& GetHostDepthRenderTarget(xenos::DepthRenderTargetFormat resource_format) { + return const_cast( + const_cast(this)->GetHostDepthRenderTarget(resource_format)); + } + bool IsOwnedBy(RenderTargetKey key, bool host_depth_encoding_different) const { + if (render_target != key) { + // Last time used for something else. If it's a depth render target with + // different host depth encoding, might have been overwritten by color, + // or by a depth render target of a different format. + return false; + } + if (host_depth_encoding_different && !key.is_depth && + GetHostDepthRenderTarget(key.GetDepthFormat()) != key) { + // Depth encoding is the same, but different addressing is needed. + return false; + } + return true; + } + bool AreOwnersSame(const OwnershipRange& other_range) const { + return render_target == other_range.render_target && + host_depth_render_target_unorm24 == other_range.host_depth_render_target_unorm24 && + host_depth_render_target_float24 == other_range.host_depth_render_target_float24; + } + }; + + xenos::ColorRenderTargetFormat GetColorResourceFormat( + xenos::ColorRenderTargetFormat format) const { + if (format == xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA && + !IsGammaFormatHostStorageSeparate()) { + return xenos::ColorRenderTargetFormat::k_8_8_8_8; + } + return xenos::GetStorageColorFormat(format); + } + + RenderTarget* GetOrCreateRenderTarget(RenderTargetKey key); + + // Checks if changing ownership of the range to the specified render target + // would require transferring data - primarily for barrier placement on the + // pixel shader interlock path (where transfers do not involve copying, but + // barriers are still needed before accessing ranges written before the + // barrier and addressed by different target-independent rasterization pixel + // positions. + bool WouldOwnershipChangeRequireTransfers(RenderTargetKey dest, + uint32_t start_tiles_base_relative, + uint32_t length_tiles) const; + // Updates ownership_ranges_, adds the transfers needed for the ownership + // change to transfers_append_out if it's not null. + void ChangeOwnership(RenderTargetKey dest, uint32_t start_tiles_base_relative, + uint32_t length_tiles, std::vector* transfers_append_out, + const Transfer::Rectangle* resolve_clear_cutout = nullptr); + + // If failed to create, may contain nullptr to prevent attempting to create a + // render target twice. + std::unordered_map render_targets_; + + // Map of host render targets currently containing the most up-to-date version + // of the tile. Has no gaps, unused parts are represented by empty render + // target keys. + // TODO(Triang3l): Pool allocator (or a custom red-black tree with one even), + // since standard containers use dynamic allocation for elements, though + // changes to this throughout a frame are pretty rare. + std::map ownership_ranges_; + + // Render targets actually used by the draw call with the last successful + // update. 0 is depth, color starting from 1, nullptr if not bound. + // Only valid for non-pixel-shader-interlock paths. + RenderTarget* last_update_used_render_targets_[1 + xenos::kMaxColorRenderTargets]; + // Render targets used by the draw call with the last successful update or + // previous updates, unless a different or a totally new one was bound (or + // surface info was changed), to avoid unneeded render target switching (which + // is especially undesirable on tile-based GPUs) in the implementation if + // simply disabling depth / stencil test or color writes and then re-enabling + // (58410954 does this often with color). Must also be used to determine + // whether it's safe to enable depth / stencil or writing to a specific color + // render target in the pipeline for this draw call. + // Only valid for non-pixel-shader-interlock paths. + RenderTarget* last_update_accumulated_render_targets_[1 + xenos::kMaxColorRenderTargets]; + // If false, the next update must copy last_update_used_render_targets_ to + // last_update_accumulated_render_targets_ - it's not beneficial or even + // incorrect to keep the previously bound render targets. + bool are_accumulated_render_targets_valid_ = false; + // After an update (for simplicity, even an unsuccessful update invalidates + // this), contains needed ownership transfer sources for each of the current + // render targets. They are reordered so for one source, all transfers are + // consecutive in the array. + std::vector last_update_transfers_[1 + xenos::kMaxColorRenderTargets]; +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/pipeline/shader/dxbc.h b/include/rex/graphics/pipeline/shader/dxbc.h new file mode 100644 index 0000000..ed4452f --- /dev/null +++ b/include/rex/graphics/pipeline/shader/dxbc.h @@ -0,0 +1,82 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +#include +#include +#include + +namespace rex::graphics { + +class DxbcShader : public Shader { + public: + class DxbcTranslation : public Translation { + public: + DxbcTranslation(DxbcShader& shader, uint64_t modification) + : Translation(shader, modification) {} + }; + + DxbcShader(xenos::ShaderType shader_type, uint64_t ucode_data_hash, const uint32_t* ucode_dwords, + size_t ucode_dword_count, std::endian ucode_source_endian = std::endian::big); + + // Resource bindings are gathered after the successful translation of any + // modification for simplicity of translation (and they don't depend on + // modification bits). + + static constexpr uint32_t kMaxTextureBindingIndexBits = + DxbcShaderTranslator::kMaxTextureBindingIndexBits; + static constexpr uint32_t kMaxTextureBindings = DxbcShaderTranslator::kMaxTextureBindings; + struct TextureBinding { + uint32_t bindless_descriptor_index; + uint32_t fetch_constant; + // Stacked and 3D are separate TextureBindings, even for bindless for null + // descriptor handling simplicity. + xenos::FetchOpDimension dimension; + bool is_signed; + }; + // Safe to hash and compare with memcmp for layout hashing. + const std::vector& GetTextureBindingsAfterTranslation() const { + return texture_bindings_; + } + uint32_t GetUsedTextureMaskAfterTranslation() const { return used_texture_mask_; } + + static constexpr uint32_t kMaxSamplerBindingIndexBits = + DxbcShaderTranslator::kMaxSamplerBindingIndexBits; + static constexpr uint32_t kMaxSamplerBindings = DxbcShaderTranslator::kMaxSamplerBindings; + struct SamplerBinding { + uint32_t bindless_descriptor_index; + uint32_t fetch_constant; + xenos::TextureFilter mag_filter; + xenos::TextureFilter min_filter; + xenos::TextureFilter mip_filter; + xenos::AnisoFilter aniso_filter; + }; + const std::vector& GetSamplerBindingsAfterTranslation() const { + return sampler_bindings_; + } + + protected: + Translation* CreateTranslationInstance(uint64_t modification) override; + + private: + friend class DxbcShaderTranslator; + + std::atomic_flag bindings_setup_entered_ = ATOMIC_FLAG_INIT; + std::vector texture_bindings_; + std::vector sampler_bindings_; + uint32_t used_texture_mask_ = 0; +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/pipeline/shader/dxbc_translator.h b/include/rex/graphics/pipeline/shader/dxbc_translator.h new file mode 100644 index 0000000..3b0fd61 --- /dev/null +++ b/include/rex/graphics/pipeline/shader/dxbc_translator.h @@ -0,0 +1,1159 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace rex::graphics { + +// Generates shader model 5_1 byte code (for Direct3D 12). +// +// IMPORTANT CONTRIBUTION NOTES: +// +// While DXBC may look like a flexible and high-level representation with highly +// generalized building blocks, actually it has a lot of restrictions on operand +// usage! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!DO NOT ADD ANYTHING FXC THAT WOULD NOT PRODUCE!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// Before adding any sequence that you haven't seen in Xenia, try writing +// equivalent code in HLSL and running it through FXC, try with /Od, try with +// full optimization, but if you see that FXC follows a different pattern than +// what you are expecting, do what FXC does!!! +// SEE THE NOTES DXBC.H BEFORE WRITING ANYTHING RELATED TO DXBC! +class DxbcShaderTranslator : public ShaderTranslator { + public: + DxbcShaderTranslator(ui::GraphicsProvider::GpuVendorID vendor_id, bool bindless_resources_used, + bool edram_rov_used, bool gamma_render_target_as_unorm8 = false, + bool msaa_2x_supported = true, uint32_t draw_resolution_scale_x = 1, + uint32_t draw_resolution_scale_y = 1, bool force_emit_source_map = false); + ~DxbcShaderTranslator() override; + + // Stage linkage ordering and rules (must be respected not only within the + // DxbcShaderTranslator, but also by everything else between the VS and the + // PS, such as geometry shaders for primitive types, and built-in pixel + // shaders for processing the fragment depth when there's no guest pixel + // shader): + // + // Note that VS means the guest VS here - can be VS or DS on the host. RS + // means the fixed-function rasterizer. + // + // The beginning of the parameters must match between the output of the + // producing stage and the input of the consuming stage, while the tail can be + // stage-specific or cut off. + // + // - Interpolators (TEXCOORD) - VS > GS > RS > PS, used interpolators are all + // unconditionally referenced in all these stages. + // - Point coordinates (XESPRITETEXCOORD) - GS > RS > PS, must be present in + // none or in all, if drawing points, and PsParamGen is used. + // - Position (SV_Position) - VS > GS > RS > PS, used in PS if actually needed + // for something (PsParamGen, alpha to coverage when oC0 is written, depth + // conversion, ROV render backend), the presence in PS depends on the usage + // within the PS, not on linkage, therefore it's the last in PS so it can be + // dropped from PS without effect on linkage. + // - Clip distances (SV_ClipDistance) - VS > GS > RS. + // - Cull distances (SV_CullDistance) - VS > RS or VS > GS. + // - Vertex kill AND operator (SV_CullDistance) - VS > RS or VS > GS. + // - Point size (XEPSIZE) - VS > GS. + // + // Therefore, for the direct VS > PS path, the parameters may be the + // following: + // - Shared between VS and PS: + // - Interpolators (TEXCOORD). + // - Position (SV_Position). + // - VS output only: + // - Clip distances (SV_ClipDistance). + // - Cull distances (SV_CullDistance). + // - Vertex kill AND operator (SV_CullDistance). + // + // When a GS is also used, the path between the VS and the GS is: + // - Shared between VS and GS: + // - Interpolators (TEXCOORD). + // - Position (SV_Position). + // - Clip distances (SV_ClipDistance). + // - Cull distances (SV_CullDistance). + // - Vertex kill AND operator (SV_CullDistance). + // - Point size (XEPSIZE). + // + // Then, between GS and PS, it's: + // - Shared between GS and PS: + // - Interpolators (TEXCOORD). + // - Point coordinates (XESPRITETEXCOORD). + // - Position (SV_Position). + // - GS output only: + // - Clip distances (SV_ClipDistance). + + union Modification { + // If anything in this is structure is changed in a way not compatible with + // the previous layout, invalidate the pipeline storages by increasing this + // version number (0xYYYYMMDD)! + static constexpr uint32_t kVersion = 0x20260226; + + enum class DepthStencilMode : uint32_t { + kNoModifiers, + // [earlydepthstencil] - enable if alpha test and alpha to coverage are + // disabled; ignored if anything in the shader blocks early Z writing. + kEarlyHint, + // Converting the depth to the closest 32-bit float representable exactly + // as a 20e4 float, to support invariance in cases when the guest + // reuploads a previously resolved depth buffer to the EDRAM, rounding + // towards zero (which contradicts the rounding used by the Direct3D 9 + // reference rasterizer, but allows SV_DepthLessEqual to be used to allow + // slightly coarse early Z culling; also truncating regardless of whether + // the shader writes depth and thus always uses SV_Depth, for + // consistency). MSAA is limited - depth must be per-sample + // (SV_DepthLessEqual also explicitly requires sample or centroid position + // interpolation), thus the sampler has to run at sample frequency even if + // the device supports stencil loading and thus true non-ROV MSAA via + // SV_StencilRef. + // Fixed-function viewport depth bounds must be snapped to float24 for + // clamping purposes. + kFloat24Truncating, + // Similar to kFloat24Truncating, but rounding to the nearest even, + // however, always using SV_Depth rather than SV_DepthLessEqual because + // rounding up results in a bigger value. Same viewport usage rules apply. + kFloat24Rounding, + }; + + uint64_t value; + struct VertexShaderModification { + // uint32_t 0. + // Interpolators written by the vertex shader and needed by the pixel + // shader. + uint32_t interpolator_mask : xenos::kMaxInterpolators; + uint32_t user_clip_plane_count : 3; + uint32_t user_clip_plane_cull : 1; + // Whether vertex killing with the "and" operator is used, and one more + // SV_CullDistance needs to be written. + uint32_t vertex_kill_and : 1; + uint32_t output_point_size : 1; + // Dynamically indexable register count from SQ_PROGRAM_CNTL. + uint32_t dynamic_addressable_register_count : 8; + // PA_CL_CLIP_CNTL::ps_ucp_mode for point primitives. + uint32_t point_ps_ucp_mode : 2; + // uint32_t 1. + // Pipeline stage and input configuration. + Shader::HostVertexShaderType host_vertex_shader_type : Shader::kHostVertexShaderTypeBitCount; + } vertex; + struct PixelShaderModification { + // uint32_t 0. + // Interpolators written by the vertex shader and needed by the pixel + // shader. + uint32_t interpolator_mask : xenos::kMaxInterpolators; + uint32_t interpolators_centroid : xenos::kMaxInterpolators; + // uint32_t 1. + // Dynamically indexable register count from SQ_PROGRAM_CNTL. + uint32_t param_gen_enable : 1; + uint32_t param_gen_interpolator : 4; + // If param_gen_enable is set, this must be set for point primitives, and + // must not be set for other primitive types - enables the point sprite + // coordinates input, and also effects the flag bits in PsParamGen. + uint32_t param_gen_point : 1; + uint32_t dynamic_addressable_register_count : 8; + // Non-ROV - depth / stencil output mode. + DepthStencilMode depth_stencil_mode : 2; + } pixel; + + explicit Modification(uint64_t modification_value = 0) : value(modification_value) { + static_assert_size(*this, sizeof(value)); + } + + uint32_t GetVertexClipDistanceCount() const { + return vertex.user_clip_plane_cull ? 0 : vertex.user_clip_plane_count; + } + uint32_t GetVertexCullDistanceCount() const { + return (vertex.user_clip_plane_cull ? vertex.user_clip_plane_count : 0) + + vertex.vertex_kill_and; + } + }; + + // Constant buffer bindings in space 0. + enum class CbufferRegister { + kSystemConstants, + kFloatConstants, + kBoolLoopConstants, + kFetchConstants, + kDescriptorIndices, + }; + + // Some are referenced in xenos_draw.hlsli - check it too when updating! + enum : uint32_t { + kSysFlag_SharedMemoryIsUAV_Shift, + kSysFlag_XYDividedByW_Shift, + kSysFlag_ZDividedByW_Shift, + kSysFlag_WNotReciprocal_Shift, + kSysFlag_PrimitivePolygonal_Shift, + kSysFlag_PrimitiveLine_Shift, + kSysFlag_DepthFloat24_Shift, + kSysFlag_AlphaPassIfLess_Shift, + kSysFlag_AlphaPassIfEqual_Shift, + kSysFlag_AlphaPassIfGreater_Shift, + kSysFlag_ConvertColor0ToGamma_Shift, + kSysFlag_ConvertColor1ToGamma_Shift, + kSysFlag_ConvertColor2ToGamma_Shift, + kSysFlag_ConvertColor3ToGamma_Shift, + + kSysFlag_ROVDepthStencil_Shift, + kSysFlag_ROVDepthPassIfLess_Shift, + kSysFlag_ROVDepthPassIfEqual_Shift, + kSysFlag_ROVDepthPassIfGreater_Shift, + // 1 to write new depth to the depth buffer, 0 to keep the old one if the + // depth test passes. + kSysFlag_ROVDepthWrite_Shift, + kSysFlag_ROVStencilTest_Shift, + // If the depth / stencil test has failed, but resulted in a stencil value + // that is different than the one currently in the depth buffer, write it + // anyway and don't run the rest of the shader (to check if the sample may + // be discarded some way) - use when alpha test and alpha to coverage are + // disabled. Ignored by the shader if not applicable to it (like if it has + // kill instructions or writes the depth output). + // TODO(Triang3l): Investigate replacement with an alpha-to-mask flag, + // checking `(flags & (alpha test | alpha to mask)) == (always | disabled)`, + // taking into account the potential relation with occlusion queries (but + // should be safe at least temporarily). + kSysFlag_ROVDepthStencilEarlyWrite_Shift, + + kSysFlag_Count, + + kSysFlag_SharedMemoryIsUAV = 1u << kSysFlag_SharedMemoryIsUAV_Shift, + kSysFlag_XYDividedByW = 1u << kSysFlag_XYDividedByW_Shift, + kSysFlag_ZDividedByW = 1u << kSysFlag_ZDividedByW_Shift, + kSysFlag_WNotReciprocal = 1u << kSysFlag_WNotReciprocal_Shift, + kSysFlag_PrimitivePolygonal = 1u << kSysFlag_PrimitivePolygonal_Shift, + kSysFlag_PrimitiveLine = 1u << kSysFlag_PrimitiveLine_Shift, + kSysFlag_DepthFloat24 = 1u << kSysFlag_DepthFloat24_Shift, + kSysFlag_AlphaPassIfLess = 1u << kSysFlag_AlphaPassIfLess_Shift, + kSysFlag_AlphaPassIfEqual = 1u << kSysFlag_AlphaPassIfEqual_Shift, + kSysFlag_AlphaPassIfGreater = 1u << kSysFlag_AlphaPassIfGreater_Shift, + kSysFlag_ConvertColor0ToGamma = 1u << kSysFlag_ConvertColor0ToGamma_Shift, + kSysFlag_ConvertColor1ToGamma = 1u << kSysFlag_ConvertColor1ToGamma_Shift, + kSysFlag_ConvertColor2ToGamma = 1u << kSysFlag_ConvertColor2ToGamma_Shift, + kSysFlag_ConvertColor3ToGamma = 1u << kSysFlag_ConvertColor3ToGamma_Shift, + kSysFlag_ROVDepthStencil = 1u << kSysFlag_ROVDepthStencil_Shift, + kSysFlag_ROVDepthPassIfLess = 1u << kSysFlag_ROVDepthPassIfLess_Shift, + kSysFlag_ROVDepthPassIfEqual = 1u << kSysFlag_ROVDepthPassIfEqual_Shift, + kSysFlag_ROVDepthPassIfGreater = 1u << kSysFlag_ROVDepthPassIfGreater_Shift, + kSysFlag_ROVDepthWrite = 1u << kSysFlag_ROVDepthWrite_Shift, + kSysFlag_ROVStencilTest = 1u << kSysFlag_ROVStencilTest_Shift, + kSysFlag_ROVDepthStencilEarlyWrite = 1u << kSysFlag_ROVDepthStencilEarlyWrite_Shift, + }; + static_assert(kSysFlag_Count <= 32, "Too many flags in the system constants"); + + // IF SYSTEM CONSTANTS ARE CHANGED OR ADDED, THE FOLLOWING MUST BE UPDATED: + // - SystemConstants::Index enum. + // - system_constant_rdef_. + // - d3d12/shaders/xenos_draw.hlsli (for geometry shaders). + struct SystemConstants { + uint32_t flags; + union { + struct { + float tessellation_factor_range_min; + float tessellation_factor_range_max; + }; + float tessellation_factor_range[2]; + }; + uint32_t line_loop_closing_index; + + xenos::Endian vertex_index_endian; + uint32_t vertex_index_offset; + union { + struct { + uint32_t vertex_index_min; + uint32_t vertex_index_max; + }; + uint32_t vertex_index_min_max[2]; + }; + + float user_clip_planes[6][4]; + + float ndc_scale[3]; + float point_vertex_diameter_min; + + float ndc_offset[3]; + float point_vertex_diameter_max; + + float point_constant_diameter[2]; + // Diameter in guest screen coordinates > radius (0.5 * diameter) in the NDC + // for the host viewport. + float point_screen_diameter_to_ndc_radius[2]; + + // Each byte contains post-swizzle TextureSign values for each of the needed + // components of each of the 32 used texture fetch constants. + uint32_t texture_swizzled_signs[8]; + + // Whether each texture in fetch constants is resolution-scaled. + uint32_t textures_resolution_scaled; + // Log2 of X and Y sample size. Used for alpha to mask, and for MSAA with + // ROV, this is used for EDRAM address calculation. + uint32_t sample_count_log2[2]; + float alpha_test_reference; + + // If alpha to mask is disabled, the entire alpha_to_mask value must be 0. + // If alpha to mask is enabled, bits 0:7 are sample offsets, and bit 8 must + // be 1. + uint32_t alpha_to_mask; + uint32_t edram_32bpp_tile_pitch_dwords_scaled; + uint32_t edram_depth_base_dwords_scaled; + uint32_t padding_edram_depth_base_dwords_scaled; + + float color_exp_bias[4]; + + union { + struct { + float edram_poly_offset_front_scale; + float edram_poly_offset_front_offset; + }; + float edram_poly_offset_front[2]; + }; + union { + struct { + float edram_poly_offset_back_scale; + float edram_poly_offset_back_offset; + }; + float edram_poly_offset_back[2]; + }; + + // In stencil function/operations (they match the layout of the + // function/operations in RB_DEPTHCONTROL): + // 0:2 - comparison function (bit 0 - less, bit 1 - equal, bit 2 - greater). + // 3:5 - fail operation. + // 6:8 - pass operation. + // 9:11 - depth fail operation. + + union { + struct { + uint32_t edram_stencil_front_reference; + uint32_t edram_stencil_front_read_mask; + uint32_t edram_stencil_front_write_mask; + uint32_t edram_stencil_front_func_ops; + + uint32_t edram_stencil_back_reference; + uint32_t edram_stencil_back_read_mask; + uint32_t edram_stencil_back_write_mask; + uint32_t edram_stencil_back_func_ops; + }; + struct { + uint32_t edram_stencil_front[4]; + uint32_t edram_stencil_back[4]; + }; + uint32_t edram_stencil[2][4]; + }; + + uint32_t edram_rt_base_dwords_scaled[4]; + + // RT format combined with RenderTargetCache::kPSIColorFormatFlag values + // (pass via RenderTargetCache::AddPSIColorFormatFlags). + uint32_t edram_rt_format_flags[4]; + + // Format info - values to clamp the color to before blending or storing. + // Low color, low alpha, high color, high alpha. + float edram_rt_clamp[4][4]; + + // Format info - mask to apply to the old packed RT data, and to apply as + // inverted to the new packed data, before storing (more or less the inverse + // of the write mask packed like render target channels). This can be used + // to bypass unpacking if blending is not used. If 0 and not blending, + // reading the old data from the EDRAM buffer is not required. + uint32_t edram_rt_keep_mask[4][2]; + + // Render target blending options - RB_BLENDCONTROL, with only the relevant + // options (factors and operations - AND 0x1FFF1FFF). If 0x00010001 + // (1 * src + 0 * dst), blending is disabled for the render target. + uint32_t edram_rt_blend_factors_ops[4]; + + // The constant blend factor for the respective modes. + float edram_blend_constant[4]; + + private: + friend class DxbcShaderTranslator; + + enum class Index : uint32_t { + kFlags, + kTessellationFactorRange, + kLineLoopClosingIndex, + + kVertexIndexEndian, + kVertexIndexOffset, + kVertexIndexMinMax, + + kUserClipPlanes, + + kNDCScale, + kPointVertexDiameterMin, + + kNDCOffset, + kPointVertexDiameterMax, + + kPointConstantDiameter, + kPointScreenDiameterToNDCRadius, + + kTextureSwizzledSigns, + + kTexturesResolutionScaled, + kSampleCountLog2, + kAlphaTestReference, + + kAlphaToMask, + kEdram32bppTilePitchDwordsScaled, + kEdramDepthBaseDwordsScaled, + + kColorExpBias, + + kEdramPolyOffsetFront, + kEdramPolyOffsetBack, + + kEdramStencil, + + kEdramRTBaseDwordsScaled, + + kEdramRTFormatFlags, + + kEdramRTClamp, + + kEdramRTKeepMask, + + kEdramRTBlendFactorsOps, + + kEdramBlendConstant, + + kCount, + }; + static_assert(uint32_t(Index::kCount) <= 64, + "Too many system constants, can't use uint64_t for usage bits"); + }; + + // Shader resource view binding spaces. + enum class SRVSpace { + // SRVMainSpaceRegister t# layout. + kMain, + kBindlessTextures2DArray, + kBindlessTextures3D, + kBindlessTexturesCube, + }; + + // Shader resource view bindings in SRVSpace::kMain. + enum class SRVMainRegister { + kSharedMemory, + kBindfulTexturesStart, + }; + + // 192 textures at most because there are 32 fetch constants, and textures can + // be 2D array, 3D or cube, and also signed and unsigned. + static constexpr uint32_t kMaxTextureBindingIndexBits = 8; + static constexpr uint32_t kMaxTextureBindings = (1 << kMaxTextureBindingIndexBits) - 1; + struct TextureBinding { + uint32_t bindful_srv_index; + // Temporary for WriteResourceDefinition. + uint32_t bindful_srv_rdef_name_ptr; + uint32_t bindless_descriptor_index; + uint32_t fetch_constant; + // Stacked and 3D are separate TextureBindings, even for bindless for null + // descriptor handling simplicity. + xenos::FetchOpDimension dimension; + bool is_signed; + std::string bindful_name; + }; + + // Arbitrary limit - there can't be more than 2048 in a shader-visible + // descriptor heap, though some older hardware (tier 1 resource binding - + // Nvidia Fermi) doesn't support more than 16 samplers bound at once (we can't + // really do anything if a game uses more than 16), but just to have some + // limit so sampler count can easily be packed into 32-bit map keys (for + // instance, for root signatures). But shaders can specify overrides for + // filtering modes, and the number of possible combinations is huge - let's + // limit it to something sane. + static constexpr uint32_t kMaxSamplerBindingIndexBits = 7; + static constexpr uint32_t kMaxSamplerBindings = (1 << kMaxSamplerBindingIndexBits) - 1; + struct SamplerBinding { + uint32_t bindless_descriptor_index; + uint32_t fetch_constant; + xenos::TextureFilter mag_filter; + xenos::TextureFilter min_filter; + xenos::TextureFilter mip_filter; + xenos::AnisoFilter aniso_filter; + std::string bindful_name; + }; + + // Unordered access view bindings in space 0. + enum class UAVRegister { + kSharedMemory, + kEdram, + }; + + uint64_t GetDefaultVertexShaderModification( + uint32_t dynamic_addressable_register_count, + Shader::HostVertexShaderType host_vertex_shader_type = + Shader::HostVertexShaderType::kVertex) const override; + uint64_t GetDefaultPixelShaderModification( + uint32_t dynamic_addressable_register_count) const override; + + // Creates a special pixel shader without color outputs - this resets the + // state of the translator. + std::vector CreateDepthOnlyPixelShader(); + + // Common functions useful not only for the translator, but also for render + // target reinterpretation. + + // Converts the color value externally clamped to [0, 31.875] to 7e3 floating + // point, with zeros in bits 10:31, rounding to the nearest even. Source and + // destination may be the same, temporary must be different than both. + static void PreClampedFloat32To7e3(dxbc::Assembler& a, uint32_t f10_temp, + uint32_t f10_temp_component, uint32_t f32_temp, + uint32_t f32_temp_component, uint32_t temp_temp, + uint32_t temp_temp_component); + // Same as PreClampedFloat32To7e3, but clamps the input to [0, 31.875]. + static void UnclampedFloat32To7e3(dxbc::Assembler& a, uint32_t f10_temp, + uint32_t f10_temp_component, uint32_t f32_temp, + uint32_t f32_temp_component, uint32_t temp_temp, + uint32_t temp_temp_component); + // Converts the 7e3 number in bits [f10_shift, f10_shift + 10) to a 32-bit + // float. Two temporaries must be different, but one can be the same as the + // source. The destination may be anything writable. + static void Float7e3To32(dxbc::Assembler& a, const dxbc::Dest& f32, uint32_t f10_temp, + uint32_t f10_temp_component, uint32_t f10_shift, uint32_t temp1_temp, + uint32_t temp1_temp_component, uint32_t temp2_temp, + uint32_t temp2_temp_component); + // Converts the depth value externally clamped to the representable [0, 2) + // range to 20e4 floating point, with zeros in bits 24:31, rounding to the + // nearest even or towards zero. Source and destination may be the same, + // temporary must be different than both. If remap_from_0_to_0_5 is true, it's + // assumed that 0...1 is pre-remapped to 0...0.5 in the input. + static void PreClampedDepthTo20e4(dxbc::Assembler& a, uint32_t f24_temp, + uint32_t f24_temp_component, uint32_t f32_temp, + uint32_t f32_temp_component, uint32_t temp_temp, + uint32_t temp_temp_component, bool round_to_nearest_even, + bool remap_from_0_to_0_5); + // Converts the 20e4 number in bits [f24_shift, f24_shift + 10) to a 32-bit + // float. Two temporaries must be different, but one can be the same as the + // source. The destination may be anything writable. If remap_to_0_to_0_5 is + // true, 0...1 in float24 will be remaped to 0...0.5 in float32. + static void Depth20e4To32(dxbc::Assembler& a, const dxbc::Dest& f32, uint32_t f24_temp, + uint32_t f24_temp_component, uint32_t f24_shift, uint32_t temp1_temp, + uint32_t temp1_temp_component, uint32_t temp2_temp, + uint32_t temp2_temp_component, bool remap_to_0_to_0_5); + + // Converts one scalar from piecewise linear gamma to linear. The target may + // be the same as the source, the temporary variables must be different. If + // the source is not pre-saturated, saturation will be done internally. + static void PWLGammaToLinear(dxbc::Assembler& a, uint32_t target_temp, + uint32_t target_temp_component, uint32_t source_temp, + uint32_t source_temp_component, bool source_pre_saturated, + uint32_t temp1, uint32_t temp1_component, uint32_t temp2, + uint32_t temp2_component); + // Converts one scalar, which must be saturated before calling this function, + // from linear to piecewise linear gamma. The target may be the same as either + // the source or as temp_or_target, but not as both (and temp_or_target may + // not be the same as the source). temp_non_target must be different. + static void PreSaturatedLinearToPWLGamma(dxbc::Assembler& a, uint32_t target_temp, + uint32_t target_temp_component, uint32_t source_temp, + uint32_t source_temp_component, uint32_t temp_or_target, + uint32_t temp_or_target_component, + uint32_t temp_non_target, + uint32_t temp_non_target_component); + + protected: + void Reset() override; + + uint32_t GetModificationRegisterCount() const override; + + void StartTranslation() override; + std::vector CompleteTranslation() override; + void PostTranslation() override; + + void ProcessLabel(uint32_t cf_index) override; + + void ProcessExecInstructionBegin(const ParsedExecInstruction& instr) override; + void ProcessExecInstructionEnd(const ParsedExecInstruction& instr) override; + void ProcessLoopStartInstruction(const ParsedLoopStartInstruction& instr) override; + void ProcessLoopEndInstruction(const ParsedLoopEndInstruction& instr) override; + void ProcessJumpInstruction(const ParsedJumpInstruction& instr) override; + void ProcessAllocInstruction(const ParsedAllocInstruction& instr, uint8_t export_eM) override; + + void ProcessVertexFetchInstruction(const ParsedVertexFetchInstruction& instr) override; + void ProcessTextureFetchInstruction(const ParsedTextureFetchInstruction& instr) override; + void ProcessAluInstruction(const ParsedAluInstruction& instr, + uint8_t memexport_eM_potentially_written_before) override; + + private: + // IF ANY OF THESE ARE CHANGED, WriteInputSignature and WriteOutputSignature + // MUST BE UPDATED! + static constexpr uint32_t kInRegisterVSVertexIndex = 0; + static constexpr uint32_t kInRegisterDSControlPointIndex = 0; + + // GetSystemConstantSrc + MarkSystemConstantUsed is for special cases of + // building the source unconditionally - in general, LoadSystemConstant must + // be used instead. + void MarkSystemConstantUsed(SystemConstants::Index index) { + system_constants_used_ |= uint64_t(1) << uint32_t(index); + } + // Offset should be offsetof(SystemConstants, field). Swizzle values are + // relative to the first component in the vector according to offsetof - to + // request a scalar, use XXXX swizzle, and if it's at +4 in its 16-byte + // vector, it will be turned into YYYY, and so on. The swizzle may include + // out-of-bounds components of the vector for simplicity of use, assuming they + // will be dropped anyway later. + dxbc::Src GetSystemConstantSrc(size_t offset, uint32_t swizzle) const { + uint32_t first_component = uint32_t((offset >> 2) & 3); + return dxbc::Src::CB(cbuffer_index_system_constants_, + uint32_t(CbufferRegister::kSystemConstants), uint32_t(offset >> 4), + std::min((swizzle & 3) + first_component, uint32_t(3)) | + std::min(((swizzle >> 2) & 3) + first_component, uint32_t(3)) << 2 | + std::min(((swizzle >> 4) & 3) + first_component, uint32_t(3)) << 4 | + std::min(((swizzle >> 6) & 3) + first_component, uint32_t(3)) << 6); + } + dxbc::Src LoadSystemConstant(SystemConstants::Index index, size_t offset, uint32_t swizzle) { + MarkSystemConstantUsed(index); + return GetSystemConstantSrc(offset, swizzle); + } + dxbc::Src LoadFlagsSystemConstant() { + return LoadSystemConstant(SystemConstants::Index::kFlags, offsetof(SystemConstants, flags), + dxbc::Src::kXXXX); + } + + Modification GetDxbcShaderModification() const { + return Modification(current_translation().modification()); + } + + bool IsDxbcVertexShader() const { + return is_vertex_shader() && !Shader::IsHostVertexShaderTypeDomain( + GetDxbcShaderModification().vertex.host_vertex_shader_type); + } + bool IsDxbcDomainShader() const { + return is_vertex_shader() && Shader::IsHostVertexShaderTypeDomain( + GetDxbcShaderModification().vertex.host_vertex_shader_type); + } + + bool IsForceEarlyDepthStencilGlobalFlagEnabled() const { + return is_pixel_shader() && + GetDxbcShaderModification().pixel.depth_stencil_mode == + Modification::DepthStencilMode::kEarlyHint && + !edram_rov_used_ && current_shader().implicit_early_z_write_allowed(); + } + + uint32_t GetModificationInterpolatorMask() const { + Modification modification = GetDxbcShaderModification(); + return is_vertex_shader() ? modification.vertex.interpolator_mask + : modification.pixel.interpolator_mask; + } + + // Whether to use switch-case rather than if (pc >= label) for control flow. + bool UseSwitchForControlFlow() const; + + // Allocates new consecutive r# registers for internal use and returns the + // index of the first. + uint32_t PushSystemTemp(uint32_t zero_mask = 0, uint32_t count = 1); + // Frees the last allocated internal r# registers for later reuse. + void PopSystemTemp(uint32_t count = 1); + + // ExportToMemory modifies the values of eA/eM# for simplicity, call only + // before starting a new export or ending the invocation or making it + // inactive. + void ExportToMemory(uint8_t export_eM); + + bool IsSampleRate() const { + assert_true(is_pixel_shader()); + return DSV_IsWritingFloat24Depth() && !current_shader().writes_depth(); + } + bool IsDepthStencilSystemTempUsed() const { + // See system_temp_depth_stencil_ documentation for explanation of cases. + if (edram_rov_used_) { + // Needed for all cases (early, late, late with oDepth). + return true; + } + if (current_shader().writes_depth()) { + // With host render targets, the depth format may be float24, in this + // case, need to multiply it by 0.5 since 0...1 of the guest is stored as + // 0...0.5 on the host, and also to convert it. + // With ROV, need to store it to write later. + return true; + } + return false; + } + // Whether the current non-ROV pixel shader should convert the depth to 20e4. + bool DSV_IsWritingFloat24Depth() const { + if (edram_rov_used_) { + return false; + } + Modification::DepthStencilMode depth_stencil_mode = + GetDxbcShaderModification().pixel.depth_stencil_mode; + return depth_stencil_mode == Modification::DepthStencilMode::kFloat24Truncating || + depth_stencil_mode == Modification::DepthStencilMode::kFloat24Rounding; + } + // Whether it's possible and worth skipping running the translated shader for + // 2x2 quads. + bool ROV_IsDepthStencilEarly() const { + assert_true(edram_rov_used_); + return !is_depth_only_pixel_shader_ && !current_shader().writes_depth() && + !current_shader().memexport_eM_written(); + } + // Converts the pre-clamped depth value to 24-bit (storing the result in bits + // 0:23 and zeros in 24:31, not creating room for stencil - since this may be + // involved in comparisons) according to the format specified in the system + // constants. Source and destination may be the same, temporary must be + // different than both. + void ROV_DepthTo24Bit(uint32_t d24_temp, uint32_t d24_temp_component, uint32_t d32_temp, + uint32_t d32_temp_component, uint32_t temp_temp, + uint32_t temp_temp_component); + // Does all the related to depth / stencil, including or not including + // writing based on whether it's late, or on whether it's safe to do it early. + // Updates system_temp_rov_params_ result and coverage if allowed and safe, + // updates system_temp_depth_stencil_, and if early and the coverage is empty + // for all pixels in the 2x2 quad and safe to return early (stencil is + // unchanged or known that it's safe not to await kills/alphatest/AtoC), + // returns from the shader. + void ROV_DepthStencilTest(); + // Unpacks a 32bpp or a 64bpp color in packed_temp.packed_temp_components to + // color_temp, using 2 temporary VGPRs. + void ROV_UnpackColor(uint32_t rt_index, uint32_t packed_temp, uint32_t packed_temp_components, + uint32_t color_temp, uint32_t temp1, uint32_t temp1_component, + uint32_t temp2, uint32_t temp2_component); + // Packs a float32x4 color value to 32bpp or a 64bpp in color_temp to + // packed_temp.packed_temp_components, using 2 temporary VGPR. color_temp and + // packed_temp may be the same if packed_temp_components is 0. If the format + // is 32bpp, will still write the high part to break register dependency. + void ROV_PackPreClampedColor(uint32_t rt_index, uint32_t color_temp, uint32_t packed_temp, + uint32_t packed_temp_components, uint32_t temp1, + uint32_t temp1_component, uint32_t temp2, uint32_t temp2_component); + // Emits a sequence of `case` labels for color blend factors, generating the + // factor from src_temp.rgb and dst_temp.rgb to factor_temp.rgb. factor_temp + // can be the same as src_temp or dst_temp. + void ROV_HandleColorBlendFactorCases(uint32_t src_temp, uint32_t dst_temp, uint32_t factor_temp); + // Emits a sequence of `case` labels for alpha blend factors, generating the + // factor from src_temp.a and dst_temp.a to factor_temp.factor_component. + // factor_temp can be the same as src_temp or dst_temp. + void ROV_HandleAlphaBlendFactorCases(uint32_t src_temp, uint32_t dst_temp, uint32_t factor_temp, + uint32_t factor_component); + + // Writing the prologue. + // Applies the offset to vertex or tessellation patch indices in the source + // components, restricts them to the minimum and the maximum index values, and + // converts them to floating-point. The destination may be the same as the + // source. + void RemapAndConvertVertexIndices(uint32_t dest_temp, uint32_t dest_temp_components, + const dxbc::Src& src); + void StartVertexShader_LoadVertexIndex(); + void StartVertexOrDomainShader(); + void StartDomainShader(); + void StartPixelShader_LoadROVParameters(); + void StartPixelShader(); + + void CompleteVertexOrDomainShader(); + // For RTV, adds the sample to coverage_temp.coverage_temp_component if it + // passes alpha to mask (or, if initialize == true (for the first sample + // tested), overwrites the output to initialize it). + // For ROV, masks the sample away from coverage_temp.coverage_temp_component + // if it doesn't pass alpha to mask. + // threshold_offset and temp.temp_component can be the same if needed. + void CompletePixelShader_AlphaToMaskSample(bool initialize, uint32_t sample_index, + float threshold_base, dxbc::Src threshold_offset, + float threshold_offset_scale, uint32_t coverage_temp, + uint32_t coverage_temp_component, uint32_t temp, + uint32_t temp_component); + // Performs alpha to coverage if necessary, for RTV, writing to oMask, and for + // ROV, updating the low (coverage) bits of system_temp_rov_params_.x. Done + // manually even for RTV to maintain the guest dithering pattern and because + // alpha can be exponent-biased. + void CompletePixelShader_AlphaToMask(); + void CompletePixelShader_WriteToRTVs(); + void CompletePixelShader_DSV_DepthTo24Bit(); + void CompletePixelShader_WriteToROV(); + void CompletePixelShader(); + + void CompleteShaderCode(); + + // Writes the original instruction disassembly in the output DXBC if enabled, + // as shader messages, from instruction_disassembly_buffer_. + void EmitInstructionDisassembly(); + + // Converts a shader translator source operand to a DXBC emitter operand, or + // returns a zero literal operand if it's not going to be referenced. This may + // allocate a temporary register and emit instructions if the operand can't be + // used directly with most DXBC instructions (like, if it's an indexable GPR), + // in this case, temp_pushed_out will be set to true, and PopSystemTemp must + // be done when the operand is not needed anymore. + dxbc::Src LoadOperand(const InstructionOperand& operand, uint32_t needed_components, + bool& temp_pushed_out); + // Writes the specified source (src must be usable as a vector `mov` source, + // including to x#) to an instruction storage target. + // can_store_memexport_address is for safety, to allow only proper MADs with a + // stream constant to write to eA. + void StoreResult(const InstructionResult& result, const dxbc::Src& src, + bool can_store_memexport_address = false); + + // The nesting of `if` instructions is the following: + // - pc checks (labels). + // - exec predicate/bool constant check. + // - Instruction-level predicate checks. + // As an optimization, where possible, the DXBC translator tries to merge + // multiple execs into one, not creating endif/if doing nothing, if the + // execution condition is the same. This can't be done across labels + // (obviously) and in case `setp` is done in a predicated exec - in this case, + // the predicate value in the current exec may not match the predicate value + // in the next exec. + // Instruction-level predicate checks are also merged, and until a `setp` is + // done, if the instruction has the same predicate condition as the exec it is + // in, no instruction-level predicate `if` is created as well. One exception + // to the usual way of instruction-level predicate handling is made for + // instructions involving derivative computation, such as texture fetches with + // computed LOD. The part involving derivatives is executed disregarding the + // predication, but the result storing is predicated (this is handled in + // texture fetch instruction implementation): + // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx9-graphics-reference-asm-ps-registers-output-color + + // Updates the current flow control condition (to be called in the beginning + // of exec and in jumps), closing the previous conditionals if needed. + // However, if the condition is not different, the instruction-level predicate + // `if` also won't be closed - this must be checked separately if needed (for + // example, in jumps). Also emits the last disassembly written to + // instruction_disassembly_buffer_ after closing the previous conditional and + // before opening a new one. + void UpdateExecConditionalsAndEmitDisassembly(ParsedExecInstruction::Type type, + uint32_t bool_constant_index, bool condition); + // Closes `if`s opened by exec and instructions within them (but not by + // labels) and updates the state accordingly. + void CloseExecConditionals(); + // Opens or reopens the predicate check conditional for the instruction, and + // emits the last disassembly written to instruction_disassembly_buffer_ after + // closing the previous predicate conditional and before opening a new one. + // This should be called before processing a non-control-flow instruction. + void UpdateInstructionPredicationAndEmitDisassembly(bool predicated, bool condition); + // Closes the instruction-level predicate `if` if it's open, useful if a flow + // control instruction needs to do some code which needs to respect the exec's + // conditional, but can't itself be predicated. + void CloseInstructionPredication(); + void JumpToLabel(uint32_t address); + + uint32_t FindOrAddTextureBinding(uint32_t fetch_constant, xenos::FetchOpDimension dimension, + bool is_signed); + uint32_t FindOrAddSamplerBinding(uint32_t fetch_constant, xenos::TextureFilter mag_filter, + xenos::TextureFilter min_filter, xenos::TextureFilter mip_filter, + xenos::AnisoFilter aniso_filter); + // Returns the number of texture SRV and sampler offsets that need to be + // passed via a constant buffer to the shader. + uint32_t GetBindlessResourceCount() const { + return uint32_t(texture_bindings_.size() + sampler_bindings_.size()); + } + // Marks fetch constants as used by the DXBC shader and returns dxbc::Src + // for the words 01 (pair 0), 23 (pair 1) or 45 (pair 2) of the texture fetch + // constant. + dxbc::Src RequestTextureFetchConstantWordPair(uint32_t fetch_constant_index, + uint32_t pair_index) { + if (cbuffer_index_fetch_constants_ == kBindingIndexUnallocated) { + cbuffer_index_fetch_constants_ = cbuffer_count_++; + } + uint32_t total_pair_index = fetch_constant_index * 3 + pair_index; + return dxbc::Src::CB(cbuffer_index_fetch_constants_, uint32_t(CbufferRegister::kFetchConstants), + total_pair_index >> 1, (total_pair_index & 1) ? 0b10101110 : 0b00000100); + } + dxbc::Src RequestTextureFetchConstantWord(uint32_t fetch_constant_index, uint32_t word_index) { + return RequestTextureFetchConstantWordPair(fetch_constant_index, word_index >> 1) + .SelectFromSwizzled(word_index & 1); + } + + void KillPixel(bool condition, const dxbc::Src& condition_src, + uint8_t memexport_eM_potentially_written_before); + + void ProcessVectorAluOperation(const ParsedAluInstruction& instr, + uint8_t memexport_eM_potentially_written_before, + uint32_t& result_swizzle, bool& predicate_written); + void ProcessScalarAluOperation(const ParsedAluInstruction& instr, + uint8_t memexport_eM_potentially_written_before, + bool& predicate_written); + + void WriteResourceDefinition(); + void WriteInputSignature(); + void WritePatchConstantSignature(); + void WriteOutputSignature(); + void WriteShaderCode(); + + // Executable instructions - generated during translation. + std::vector shader_code_; + // Complete shader object, with all the needed blobs and dcl_ instructions - + // generated in the end of translation. + std::vector shader_object_; + + // Optional Direct3D features used by the shader. + dxbc::ShaderFeatureInfo shader_feature_info_; + // The statistics blob. + dxbc::Statistics statistics_; + + // Assembler for shader_code_ and statistics_ (must be placed after them for + // correct initialization order). + dxbc::Assembler a_; + // Assembler for shader_object_ and statistics_, for declarations before the + // shader code that depend on info gathered during translation (must be placed + // after them for correct initialization order). + dxbc::Assembler ao_; + + // Buffer for instruction disassembly comments. + string::StringBuffer instruction_disassembly_buffer_; + + // Whether to write comments with the original Xenos instructions to the + // output. + bool emit_source_map_; + + // Vendor ID of the GPU manufacturer, for toggling unsupported features. + ui::GraphicsProvider::GpuVendorID vendor_id_; + + // Whether textures and samplers should be bindless. + bool bindless_resources_used_; + + // Whether the output merger should be emulated in pixel shaders. + bool edram_rov_used_; + + // Whether with RTV-based output-merger, k_8_8_8_8_GAMMA render targets are + // stored as 8-bit with shader-side gamma conversion. + bool gamma_render_target_as_unorm8_; + + // Whether 2x MSAA is emulated using real 2x MSAA rather than two samples of + // 4x MSAA. + bool msaa_2x_supported_; + + // Guest pixel host width / height. + uint32_t draw_resolution_scale_x_; + uint32_t draw_resolution_scale_y_; + + // Is currently writing the empty depth-only pixel shader, for + // CompleteTranslation. + bool is_depth_only_pixel_shader_ = false; + + // Data types used in constants buffers. Listed in dependency order. + enum class ShaderRdefTypeIndex { + kFloat, + kFloat2, + kFloat3, + kFloat4, + kUint, + kUint2, + kUint4, + // Render target clamping ranges. + kFloat4Array4, + // User clip planes. + kFloat4Array6, + // Float constants - size written dynamically. + kFloat4ConstantArray, + // Bool constants, texture signedness, front/back stencil, render target + // keep masks. + kUint4Array2, + // Loop constants. + kUint4Array8, + // Fetch constants. + kUint4Array48, + // Descriptor indices - size written dynamically. + kUint4DescriptorIndexArray, + + kCount, + kUnknown = kCount + }; + + struct ShaderRdefType { + // Name ignored for arrays. + const char* name; + dxbc::RdefVariableClass variable_class; + dxbc::RdefVariableType variable_type; + uint16_t row_count; + uint16_t column_count; + uint16_t element_count; + ShaderRdefTypeIndex array_element_type; + }; + static const ShaderRdefType rdef_types_[size_t(ShaderRdefTypeIndex::kCount)]; + + static constexpr uint32_t kBindingIndexUnallocated = UINT32_MAX; + + // Number of constant buffer bindings used in this shader - also used for + // generation of indices of constant buffers that are optional. + uint32_t cbuffer_count_; + uint32_t cbuffer_index_system_constants_; + uint32_t cbuffer_index_float_constants_; + uint32_t cbuffer_index_bool_loop_constants_; + uint32_t cbuffer_index_fetch_constants_; + uint32_t cbuffer_index_descriptor_indices_; + + struct SystemConstantRdef { + const char* name; + ShaderRdefTypeIndex type; + uint32_t size; + uint32_t padding_after; + }; + static const SystemConstantRdef system_constant_rdef_[size_t(SystemConstants::Index::kCount)]; + // Mask of system constants (1 << SystemConstants::Index) used in the shader, + // so the remaining ones can be marked as unused in RDEF. + uint64_t system_constants_used_; + + uint32_t out_reg_vs_interpolators_; + uint32_t out_reg_vs_position_; + // Clip and cull distances must be tightly packed in Direct3D. + // Up to 6 SV_ClipDistances or SV_CullDistances depending on + // user_clip_plane_cull, then one SV_CullDistance if vertex_kill_and is used. + uint32_t out_reg_vs_clip_cull_distances_; + uint32_t out_reg_vs_point_size_; + uint32_t in_reg_ps_interpolators_; + uint32_t in_reg_ps_point_coordinates_; + uint32_t in_reg_ps_position_; + // nointerpolation inputs. SV_IsFrontFace (X) is for non-point PsParamGen, + // SV_SampleIndex (Y) is for memexport when sample-rate shading is otherwise + // needed anyway due to depth conversion. + uint32_t in_reg_ps_front_face_sample_index_; + + // Mask of domain location actually used in the domain shader. + uint32_t in_domain_location_used_; + // Whether kInRegisterDSControlPointIndex has been used in the shader. + bool in_control_point_index_used_; + // Mask of the pixel/sample position actually used in the pixel shader. + uint32_t in_position_used_; + // Whether the faceness has been used in the pixel shader. + bool in_front_face_used_; + + // Number of currently allocated Xenia internal r# registers. + uint32_t system_temp_count_current_; + // Total maximum number of temporary registers ever used during this + // translation (for the declaration). + uint32_t system_temp_count_max_; + + // Position in vertex shaders (because viewport and W transformations can be + // applied in the end of the shader). + uint32_t system_temp_position_; + // Special exports in vertex shaders. + uint32_t system_temp_point_size_edge_flag_kill_vertex_; + // ROV only - 4 persistent VGPRs when writing to color targets, 2 VGPRs when + // not: + // X - Bit masks: + // 0:3 - Per-sample coverage at the current stage of the shader's execution. + // Affected by things like SV_Coverage, early or late depth / stencil + // (always resets bits for failing, no matter if need to defer writing), + // alpha to coverage. + // 4:7 - Depth write deferred mask - when early depth / stencil resulted in a + // different value for the sample (like different stencil if the test + // failed), but can't write it before running the shader because it's + // not known if the sample will be discarded by the shader, alphatest or + // AtoC. + // Early depth / stencil rejection of the pixel is possible when both 0:3 and + // 4:7 are zero. + // 8:11 - Whether color buffers have been written to, if not written on the + // taken execution path, don't export according to Direct3D 9 register + // documentation (some games rely on this behavior). + // Y - Absolute resolution-scaled EDRAM offset for depth / stencil, in dwords, + // before and during depth testing. During color writing, when the depth / + // stencil address is not needed anymore, current color sample address. + // Z - Base-relative resolution-scaled EDRAM offset for 32bpp color data, in + // dwords. + // W - Base-relative resolution-scaled EDRAM offset for 64bpp color data, in + // dwords. + uint32_t system_temp_rov_params_; + // Different purposes: + // - When writing to oDepth: X also used to hold the depth written by the + // shader, which, for host render targets, if the depth buffer is float24, + // needs to be remapped from guest 0...1 to host 0...0.5 and, if needed, + // converted to float24 precision; and for ROV, needs to be written in the + // end of the shader. + // - When not writing to oDepth, but using ROV: + // - ROV_IsDepthStencilEarly: New per-sample depth / stencil values, + // generated during early depth / stencil test (actual writing checks + // the remaining coverage bits). + // - Not ROV_IsDepthStencilEarly: Z gradients in .xy taken in the beginning + // of the shader before any return statement is possibly reached. + uint32_t system_temp_depth_stencil_; + // Up to 4 color outputs in pixel shaders (needs to be readable, because of + // alpha test, alpha to coverage, exponent bias, gamma, and also for ROV + // writing). + uint32_t system_temps_color_[4]; + + // Memory export temporary registers are allocated if the shader writes any + // eM# (current_shader().memexport_eM_written() != 0). + // X - whether memexport is enabled for this invocation. + // Y - which eM# elements have been written so far by the invocation since the + // last memory write. + uint32_t system_temp_memexport_enabled_and_eM_written_; + // eA. + uint32_t system_temp_memexport_address_; + // eM#. + uint32_t system_temps_memexport_data_[ucode::kMaxMemExportElementCount]; + + // Vector ALU or fetch result / scratch (since Xenos write masks can contain + // swizzles). + uint32_t system_temp_result_; + // Temporary register ID for previous scalar result, program counter, + // predicate and absolute address register. + uint32_t system_temp_ps_pc_p0_a0_; + // Loop index stack - .x is the active loop, shifted right to .yzw on push. + uint32_t system_temp_aL_; + // Loop counter stack, .x is the active loop. Represents number of times + // remaining to loop. + uint32_t system_temp_loop_count_; + // Explicitly set texture gradients and LOD. + uint32_t system_temp_grad_h_lod_; + // .w stores `base + index * stride` in bytes from the last vfetch_full as it + // may be needed by vfetch_mini. + uint32_t system_temp_grad_v_vfetch_address_; + + // The bool constant number containing the condition for the currently + // processed exec (or the last - unless a label has reset this), or + // kCfExecBoolConstantNone if it's not checked. + uint32_t cf_exec_bool_constant_; + static constexpr uint32_t kCfExecBoolConstantNone = UINT32_MAX; + // The expected bool constant value in the current exec if + // cf_exec_bool_constant_ is not kCfExecBoolConstantNone. + bool cf_exec_bool_constant_condition_; + // Whether the currently processed exec is executed if a predicate is + // set/unset. + bool cf_exec_predicated_; + // The expected predicated condition if cf_exec_predicated_ is true. + bool cf_exec_predicate_condition_; + // Whether an `if` for instruction-level predicate check is currently open. + bool cf_instruction_predicate_if_open_; + // The expected predicate condition for the current or the last instruction if + // cf_exec_instruction_predicated_ is true. + bool cf_instruction_predicate_condition_; + // Whether there was a `setp` in the current exec before the current + // instruction, thus instruction-level predicate value can be different than + // the exec-level predicate value, and can't merge two execs with the same + // predicate condition anymore. + bool cf_exec_predicate_written_; + + // Number of SRV resources used in this shader - also used for generation of + // indices of SRV resources that are optional. + uint32_t srv_count_; + uint32_t srv_index_shared_memory_; + uint32_t srv_index_bindless_textures_2d_; + uint32_t srv_index_bindless_textures_3d_; + uint32_t srv_index_bindless_textures_cube_; + + // The first binding is at t[SRVMainRegister::kBindfulTexturesStart] of space + // SRVSpace::kMain. + std::vector texture_bindings_; + std::unordered_map texture_bindings_for_bindful_srv_indices_; + + // Number of UAV resources used in this shader - also used for generation of + // indices of UAV resources that are optional. + uint32_t uav_count_; + uint32_t uav_index_shared_memory_; + uint32_t uav_index_edram_; + + std::vector sampler_bindings_; +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/pipeline/shader/interpreter.h b/include/rex/graphics/pipeline/shader/interpreter.h new file mode 100644 index 0000000..9a90df2 --- /dev/null +++ b/include/rex/graphics/pipeline/shader/interpreter.h @@ -0,0 +1,140 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace rex::graphics { + +class ShaderInterpreter { + public: + ShaderInterpreter(const RegisterFile& register_file, const memory::Memory& memory) + : register_file_(register_file), memory_(memory) {} + + class ExportSink { + public: + virtual ~ExportSink() = default; + virtual void AllocExport(ucode::AllocType /*type*/, uint32_t /*size*/) {} + virtual void Export(ucode::ExportRegister /*export_register*/, const float* /*value*/, + uint32_t /*value_mask*/) {} + }; + + void SetTraceWriter(TraceWriter* new_trace_writer) { trace_writer_ = new_trace_writer; } + + ExportSink* GetExportSink() const { return export_sink_; } + void SetExportSink(ExportSink* new_export_sink) { export_sink_ = new_export_sink; } + + const float* temp_registers() const { return &temp_registers_[0][0]; } + float* temp_registers() { return &temp_registers_[0][0]; } + + static bool CanInterpretShader(const Shader& shader) { + assert_true(shader.is_ucode_analyzed()); + // Texture instructions are not very common in vertex shaders (and not used + // in Direct3D 9's internal rectangles such as clears) and are extremely + // complex, not implemented. + if (shader.uses_texture_fetch_instruction_results()) { + return false; + } + return true; + } + void SetShader(xenos::ShaderType shader_type, const uint32_t* ucode) { + shader_type_ = shader_type; + ucode_ = ucode; + } + void SetShader(const Shader& shader) { + assert_true(CanInterpretShader(shader)); + SetShader(shader.type(), shader.ucode_dwords()); + } + + void Execute(); + + private: + struct State { + ucode::VertexFetchInstruction vfetch_full_last; + uint32_t vfetch_address_dwords; + float previous_scalar; + uint32_t call_stack_depth; + uint32_t call_return_addresses[4]; + uint32_t loop_stack_depth; + xenos::LoopConstant loop_constants[4]; + uint32_t loop_iterators[4]; + int32_t address_register; + bool predicate; + + void Reset() { std::memset(this, 0, sizeof(*this)); } + + int32_t GetLoopAddress() const { + assert_true(loop_stack_depth && loop_stack_depth < 4); + if (!loop_stack_depth || loop_stack_depth >= 4) { + return 0; + } + xenos::LoopConstant loop_constant = loop_constants[loop_stack_depth]; + // Clamp to the real range specified in the IPR2015-00325 sequencer + // specification. + // https://portal.unifiedpatents.com/ptab/case/IPR2015-00325 + return std::min(INT32_C(256), + std::max(INT32_C(-256), int32_t(int32_t(loop_iterators[loop_stack_depth]) * + loop_constant.step + + loop_constant.start))); + } + }; + + static float FlushDenormal(float value) { + uint32_t bits = *reinterpret_cast(&value); + bits &= (bits & UINT32_C(0x7F800000)) ? ~UINT32_C(0) : (UINT32_C(1) << 31); + return *reinterpret_cast(&bits); + } + + uint32_t GetTempRegisterIndex(uint32_t address, bool is_relative) const { + return (int32_t(address) + (is_relative ? state_.GetLoopAddress() : 0)) & + ((UINT32_C(1) << xenos::kMaxShaderTempRegistersLog2) - 1); + } + const float* GetTempRegister(uint32_t address, bool is_relative) const { + return temp_registers_[GetTempRegisterIndex(address, is_relative)]; + } + float* GetTempRegister(uint32_t address, bool is_relative) { + return temp_registers_[GetTempRegisterIndex(address, is_relative)]; + } + const std::array GetFloatConstant(uint32_t address, bool is_relative, + bool relative_address_is_a0) const; + + void ExecuteAluInstruction(ucode::AluInstruction instr); + void StoreFetchResult(uint32_t dest, bool is_dest_relative, uint32_t swizzle, const float* value); + void ExecuteVertexFetchInstruction(ucode::VertexFetchInstruction instr); + + const RegisterFile& register_file_; + const memory::Memory& memory_; + + TraceWriter* trace_writer_ = nullptr; + + ExportSink* export_sink_ = nullptr; + + xenos::ShaderType shader_type_ = xenos::ShaderType::kVertex; + const uint32_t* ucode_ = nullptr; + + // For both inputs and locals. + float temp_registers_[xenos::kMaxShaderTempRegisters][4]; + + State state_; +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/pipeline/shader/shader.h b/include/rex/graphics/pipeline/shader/shader.h new file mode 100644 index 0000000..4cf3854 --- /dev/null +++ b/include/rex/graphics/pipeline/shader/shader.h @@ -0,0 +1,1054 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace rex::graphics { + +// The structures here are used for both translation and disassembly. +// +// Because disassembly uses them too, to make sure "assemble -> disassemble -> +// reassemble" round trip is always successful with the XNA assembler (as it is +// the accuracy benchmark for translation), only generalization - not +// optimization like nop skipping/replacement - must be done while converting +// microcode to these structures (in other words, parsed shader code should be +// enough to accurately reconstruct the microcode for any shader that could be +// written by a human in assembly). +// +// During the "parsed -> host" part of the translation, however, translators are +// free to make any optimizations (as long as they don't affect the result, of +// course) they find appropriate. + +enum class InstructionStorageTarget { + // Result is not stored. + kNone, + // Result is stored to a temporary register indexed by storage_index [0-63]. + kRegister, + // Result is stored into a vertex shader interpolator export [0-15]. + kInterpolator, + // Result is stored to the position export (gl_Position). + kPosition, + // Result is stored to the vertex shader misc export register, see + // ucode::ExportRegister::kVSPointSizeEdgeFlagKillVertex for description of + // components. + kPointSizeEdgeFlagKillVertex, + // Result is stored as memexport destination address + // (see xenos::xe_gpu_memexport_stream_t). + kExportAddress, + // Result is stored to memexport destination data. + kExportData, + // Result is stored to a color target export indexed by storage_index [0-3]. + kColor, + // X of the result is stored to the depth export (gl_FragDepth). + kDepth, +}; + +// Must be used only in translation to skip unused components, but not in +// disassembly (because oPts.x000 will be assembled, but oPts.x00_ has both +// skipped components and zeros, which cannot be encoded, and therefore it will +// not). +constexpr uint32_t GetInstructionStorageTargetUsedComponentCount(InstructionStorageTarget target) { + switch (target) { + case InstructionStorageTarget::kNone: + return 0; + case InstructionStorageTarget::kPointSizeEdgeFlagKillVertex: + return 3; + case InstructionStorageTarget::kDepth: + return 1; + default: + return 4; + } +} + +enum class InstructionStorageAddressingMode { + // The storage index is not dynamically addressed. + kAbsolute, + // The storage index is addressed by a0. + // Float constants only. + kAddressRegisterRelative, + // The storage index is addressed by aL. + // Float constants and temporary registers only. + kLoopRelative, +}; + +// Describes the source value of a particular component. +enum class SwizzleSource { + // Component receives the source X. + kX, + // Component receives the source Y. + kY, + // Component receives the source Z. + kZ, + // Component receives the source W. + kW, + // Component receives constant 0. + k0, + // Component receives constant 1. + k1, +}; + +constexpr SwizzleSource GetSwizzleFromComponentIndex(uint32_t i) { + return static_cast(i); +} +constexpr SwizzleSource GetSwizzledAluSourceComponent(uint32_t swizzle, uint32_t component_index) { + return GetSwizzleFromComponentIndex( + ucode::AluInstruction::GetSwizzledComponentIndex(swizzle, component_index)); +} +inline char GetCharForComponentIndex(uint32_t i) { + const static char kChars[] = {'x', 'y', 'z', 'w'}; + return kChars[i]; +} +inline char GetCharForSwizzle(SwizzleSource swizzle_source) { + const static char kChars[] = {'x', 'y', 'z', 'w', '0', '1'}; + return kChars[static_cast(swizzle_source)]; +} + +struct InstructionResult { + // Where the result is going. + InstructionStorageTarget storage_target = InstructionStorageTarget::kNone; + // Index into the storage_target, if it is indexed. + uint32_t storage_index = 0; + // How the storage index is dynamically addressed, if it is. + InstructionStorageAddressingMode storage_addressing_mode = + InstructionStorageAddressingMode::kAbsolute; + // True to clamp the result value to [0-1]. + bool is_clamped = false; + // Defines whether each output component is written, though this is from the + // original microcode, not taking into account whether such components + // actually exist in the target. + uint32_t original_write_mask = 0b0000; + // Defines the source for each output component xyzw. + SwizzleSource components[4] = {SwizzleSource::kX, SwizzleSource::kY, SwizzleSource::kZ, + SwizzleSource::kW}; + // Returns the write mask containing only components actually present in the + // target. + uint32_t GetUsedWriteMask() const { + uint32_t target_component_count = GetInstructionStorageTargetUsedComponentCount(storage_target); + return original_write_mask & ((1 << target_component_count) - 1); + } + // True if the components are in their 'standard' swizzle arrangement (xyzw). + bool IsStandardSwizzle() const { + return (GetUsedWriteMask() == 0b1111) && components[0] == SwizzleSource::kX && + components[1] == SwizzleSource::kY && components[2] == SwizzleSource::kZ && + components[3] == SwizzleSource::kW; + } + // Returns the components of the result, before swizzling, that won't be + // discarded or replaced with a constant. + uint32_t GetUsedResultComponents() const { + uint32_t used_write_mask = GetUsedWriteMask(); + uint32_t used_components = 0b0000; + for (uint32_t i = 0; i < 4; ++i) { + if ((used_write_mask & (1 << i)) && components[i] >= SwizzleSource::kX && + components[i] <= SwizzleSource::kW) { + used_components |= 1 << (uint32_t(components[i]) - uint32_t(SwizzleSource::kX)); + } + } + return used_components; + } + // Returns which components of the used write mask are constant, and what + // values they have. + uint32_t GetUsedConstantComponents(uint32_t& constant_values_out) const { + uint32_t constant_components = 0; + uint32_t constant_values = 0; + uint32_t used_write_mask = GetUsedWriteMask(); + for (uint32_t i = 0; i < 4; ++i) { + if (!(used_write_mask & (1 << i))) { + continue; + } + SwizzleSource component = components[i]; + if (component >= SwizzleSource::kX && component <= SwizzleSource::kW) { + continue; + } + constant_components |= 1 << i; + if (component == SwizzleSource::k1) { + constant_values |= 1 << i; + } + } + constant_values_out = constant_values; + return constant_components; + } +}; + +enum class InstructionStorageSource { + // Source is stored in a temporary register indexed by storage_index [0-63]. + kRegister, + // Source is stored in a float constant indexed by storage_index [0-255]. + kConstantFloat, + // Source is stored in a vertex fetch constant indexed by storage_index + // [0-95]. + kVertexFetchConstant, + // Source is stored in a texture fetch constant indexed by storage_index + // [0-31]. + kTextureFetchConstant, +}; + +struct InstructionOperand { + // Where the source comes from. + InstructionStorageSource storage_source = InstructionStorageSource::kRegister; + // Index into the storage_target, if it is indexed. + uint32_t storage_index = 0; + // How the storage index is dynamically addressed, if it is. + InstructionStorageAddressingMode storage_addressing_mode = + InstructionStorageAddressingMode::kAbsolute; + // True to negate the operand value. + bool is_negated = false; + // True to take the absolute value of the source (before any negation). + bool is_absolute_value = false; + // Number of components taken from the source operand. + uint32_t component_count = 4; + // Defines the source for each component xyzw (up to the given + // component_count). + SwizzleSource components[4] = {SwizzleSource::kX, SwizzleSource::kY, SwizzleSource::kZ, + SwizzleSource::kW}; + // Returns the swizzle source for the component, replicating the rightmost + // component if there are less than 4 components (similar to what the Xbox 360 + // shader compiler does as a general rule for unspecified components). + SwizzleSource GetComponent(uint32_t index) const { + return components[std::min(index, component_count - 1)]; + } + // True if the components are in their 'standard' swizzle arrangement (xyzw). + bool IsStandardSwizzle() const { + switch (component_count) { + case 4: + return components[0] == SwizzleSource::kX && components[1] == SwizzleSource::kY && + components[2] == SwizzleSource::kZ && components[3] == SwizzleSource::kW; + } + return false; + } + + // Returns which components of two operands will always be bitwise equal + // (disregarding component_count for simplicity of usage with GetComponent, + // treating the rightmost component as replicated). This, strictly with all + // conditions, must be used when emulating Shader Model 3 +-0 * x = +0 + // multiplication behavior with IEEE-compliant multiplication (because + // -0 * |-0|, or -0 * +0, is -0, while the result must be +0). + uint32_t GetIdenticalComponents(const InstructionOperand& other) const { + if (storage_source != other.storage_source || storage_index != other.storage_index || + storage_addressing_mode != other.storage_addressing_mode || + is_negated != other.is_negated || is_absolute_value != other.is_absolute_value) { + return 0; + } + uint32_t identical_components = 0; + for (uint32_t i = 0; i < 4; ++i) { + identical_components |= uint32_t(GetComponent(i) == other.GetComponent(i)) << i; + } + return identical_components; + } +}; + +struct ParsedExecInstruction { + // Index into the ucode dword source. + uint32_t dword_index = 0; + + // Opcode for the instruction. + ucode::ControlFlowOpcode opcode; + // Friendly name of the instruction. + const char* opcode_name = nullptr; + + // Instruction address where ALU/fetch instructions reside. + uint32_t instruction_address = 0; + // Number of instructions to execute. + uint32_t instruction_count = 0; + + enum class Type { + // Block is always executed. + kUnconditional, + // Execution is conditional on the value of the boolean constant. + kConditional, + // Execution is predicated. + kPredicated, + }; + // Condition required to execute the instructions. + Type type = Type::kUnconditional; + // Constant index used as the conditional if kConditional. + uint32_t bool_constant_index = 0; + // Required condition value of the comparision (true or false). + bool condition = false; + + // Whether this exec ends the shader. + bool is_end = false; + // Whether the hardware doesn't have to wait for the predicate to be updated + // after this exec. + bool is_predicate_clean = true; + // ? + bool is_yield = false; + + // Sequence bits, 2 per instruction, indicating whether ALU or fetch. + uint32_t sequence = 0; + + // Disassembles the instruction into ucode assembly text. + void Disassemble(string::StringBuffer* out) const; +}; + +struct ParsedLoopStartInstruction { + // Index into the ucode dword source. + uint32_t dword_index = 0; + + // Integer constant register that holds the loop parameters. + // 0:7 - uint8 loop count, 8:15 - uint8 start aL, 16:23 - int8 aL step. + uint32_t loop_constant_index = 0; + // Whether to reuse the current aL instead of reset it to loop start. + bool is_repeat = false; + + // Target address to jump to when skipping the loop. + uint32_t loop_skip_address = 0; + + // Disassembles the instruction into ucode assembly text. + void Disassemble(string::StringBuffer* out) const; +}; + +struct ParsedLoopEndInstruction { + // Index into the ucode dword source. + uint32_t dword_index = 0; + + // Break from the loop if the predicate matches the expected value. + bool is_predicated_break = false; + // Required condition value of the comparision (true or false). + bool predicate_condition = false; + + // Integer constant register that holds the loop parameters. + // 0:7 - uint8 loop count, 8:15 - uint8 start aL, 16:23 - int8 aL step. + uint32_t loop_constant_index = 0; + + // Target address of the start of the loop body. + uint32_t loop_body_address = 0; + + // Disassembles the instruction into ucode assembly text. + void Disassemble(string::StringBuffer* out) const; +}; + +struct ParsedCallInstruction { + // Index into the ucode dword source. + uint32_t dword_index = 0; + + // Target address. + uint32_t target_address = 0; + + enum class Type { + // Call is always made. + kUnconditional, + // Call is conditional on the value of the boolean constant. + kConditional, + // Call is predicated. + kPredicated, + }; + // Condition required to make the call. + Type type = Type::kUnconditional; + // Constant index used as the conditional if kConditional. + uint32_t bool_constant_index = 0; + // Required condition value of the comparision (true or false). + bool condition = false; + + // Disassembles the instruction into ucode assembly text. + void Disassemble(string::StringBuffer* out) const; +}; + +struct ParsedReturnInstruction { + // Index into the ucode dword source. + uint32_t dword_index = 0; + + // Disassembles the instruction into ucode assembly text. + void Disassemble(string::StringBuffer* out) const; +}; + +struct ParsedJumpInstruction { + // Index into the ucode dword source. + uint32_t dword_index = 0; + + // Target address. + uint32_t target_address = 0; + + enum class Type { + // Jump is always taken. + kUnconditional, + // Jump is conditional on the value of the boolean constant. + kConditional, + // Jump is predicated. + kPredicated, + }; + // Condition required to make the jump. + Type type = Type::kUnconditional; + // Constant index used as the conditional if kConditional. + uint32_t bool_constant_index = 0; + // Required condition value of the comparision (true or false). + bool condition = false; + + // Disassembles the instruction into ucode assembly text. + void Disassemble(string::StringBuffer* out) const; +}; + +struct ParsedAllocInstruction { + // Index into the ucode dword source. + uint32_t dword_index = 0; + + // The type of resource being allocated. + ucode::AllocType type = ucode::AllocType::kNone; + // Total count associated with the allocation. + int count = 0; + + // True if this allocation is in a vertex shader. + bool is_vertex_shader = false; + + // Disassembles the instruction into ucode assembly text. + void Disassemble(string::StringBuffer* out) const; +}; + +struct ParsedVertexFetchInstruction { + // Opcode for the instruction. + ucode::FetchOpcode opcode; + // Friendly name of the instruction. + const char* opcode_name = nullptr; + + // True if the fetch is reusing a previous full fetch. + // The previous fetch source and constant data will be populated. + bool is_mini_fetch = false; + + // True if the instruction is predicated on the specified + // predicate_condition. + bool is_predicated = false; + // Expected predication condition value if predicated. + bool predicate_condition = false; + + // Describes how the instruction result is stored. + // Note that if the result doesn't have any components to write the fetched + // value to, the address calculation in vfetch_full must still be performed + // because such a vfetch_full may be used to setup addressing for vfetch_mini + // (wires in the color pass of 5454082B do vfetch_full to r2.000_, and then a + // true vfetch_mini). + InstructionResult result; + + // Number of source operands. + size_t operand_count = 0; + // Describes each source operand. + // Note that for vfetch_mini, which inherits the operands from vfetch_full, + // the index operand register may been overwritten between the vfetch_full and + // the vfetch_mini (happens in 4D530910 for wheels), but that should have no + // effect on the index actually used for fetching. A copy of the index + // therefore must be stored by vfetch_full (the base address, stride and + // rounding may be pre-applied to it since they will be the same in the + // vfetch_full and all its vfetch_mini instructions). + InstructionOperand operands[2]; + + struct Attributes { + xenos::VertexFormat data_format = xenos::VertexFormat::kUndefined; + int32_t offset = 0; + uint32_t stride = 0; // In dwords. + int32_t exp_adjust = 0; + // Prefetch count minus 1. + uint32_t prefetch_count = 0; + xenos::SignedRepeatingFractionMode signed_rf_mode = + xenos::SignedRepeatingFractionMode::kZeroClampMinusOne; + bool is_index_rounded = false; + bool is_signed = false; + bool is_integer = false; + }; + // Attributes describing the fetch operation. + Attributes attributes; + + // Disassembles the instruction into ucode assembly text. + void Disassemble(string::StringBuffer* out) const; +}; + +struct ParsedTextureFetchInstruction { + // Opcode for the instruction. + ucode::FetchOpcode opcode; + // Friendly name of the instruction. + const char* opcode_name = nullptr; + // Texture dimension for opcodes that have multiple dimension forms. + xenos::FetchOpDimension dimension = xenos::FetchOpDimension::k1D; + + // True if the instruction is predicated on the specified + // predicate_condition. + bool is_predicated = false; + // Expected predication condition value if predicated. + bool predicate_condition = false; + + // True if the instruction has a result. + bool has_result() const { return result.storage_target != InstructionStorageTarget::kNone; } + // Describes how the instruction result is stored. + InstructionResult result; + + // Number of source operands. + size_t operand_count = 0; + // Describes each source operand. + InstructionOperand operands[2]; + + struct Attributes { + bool fetch_valid_only = true; + bool unnormalized_coordinates = false; + xenos::TextureFilter mag_filter = xenos::TextureFilter::kUseFetchConst; + xenos::TextureFilter min_filter = xenos::TextureFilter::kUseFetchConst; + xenos::TextureFilter mip_filter = xenos::TextureFilter::kUseFetchConst; + xenos::AnisoFilter aniso_filter = xenos::AnisoFilter::kUseFetchConst; + xenos::TextureFilter vol_mag_filter = xenos::TextureFilter::kUseFetchConst; + xenos::TextureFilter vol_min_filter = xenos::TextureFilter::kUseFetchConst; + bool use_computed_lod = true; + bool use_register_lod = false; + bool use_register_gradients = false; + float lod_bias = 0.0f; + float offset_x = 0.0f; + float offset_y = 0.0f; + float offset_z = 0.0f; + }; + // Attributes describing the fetch operation. + Attributes attributes; + + // Considering the operation, dimensions, filter overrides, and the result + // components, returns which components of the result will have a value that + // is not always zero. + uint32_t GetNonZeroResultComponents() const; + + // Disassembles the instruction into ucode assembly text. + void Disassemble(string::StringBuffer* out) const; +}; + +struct ParsedAluInstruction { + // Opcode for the vector part of the instruction. + ucode::AluVectorOpcode vector_opcode = ucode::AluVectorOpcode::kAdd; + // Opcode for the scalar part of the instruction. + ucode::AluScalarOpcode scalar_opcode = ucode::AluScalarOpcode::kAdds; + // Friendly name of the vector instruction. + const char* vector_opcode_name = nullptr; + // Friendly name of the scalar instruction. + const char* scalar_opcode_name = nullptr; + + // True if the instruction is predicated on the specified + // predicate_condition. + bool is_predicated = false; + // Expected predication condition value if predicated. + bool predicate_condition = false; + + // Describes how the vector operation result and, for exports, constant 0/1 + // are stored. For simplicity of translation and disassembly, treating + // constant 0/1 writes as a part of the vector operation - they need to be + // expressed somehow in the disassembly anyway with a properly disassembled + // instruction even if only constants are being exported. The XNA disassembler + // falls back to displaying the whole vector operation, even if only constant + // components are written, if the scalar operation is a nop or if the vector + // operation changes a0, p0 or kills pixels (but if the scalar operation isn't + // nop, it outputs the entire constant mask in the scalar operation + // destination). Normally the XNA disassembler outputs the constant mask in + // both vector and scalar operations, but that's not required by assembler, so + // it doesn't really matter whether it's specified in the vector operation, in + // the scalar operation, or in both. + InstructionResult vector_and_constant_result; + // Describes how the scalar operation result is stored. + InstructionResult scalar_result; + // Both operations must be executed before any result is stored if vector and + // scalar operations are paired. There are cases of vector result being used + // as scalar operand or vice versa (the ring on Avalanche in 4D5307E6, for + // example), in this case there must be no dependency between the two + // operations. + + // Number of source operands of the vector operation. + uint32_t vector_operand_count = 0; + // Describes each source operand of the vector operation. + InstructionOperand vector_operands[3]; + // Number of source operands of the scalar operation. + uint32_t scalar_operand_count = 0; + // Describes each source operand of the scalar operation. + InstructionOperand scalar_operands[2]; + + // Whether the vector part of the instruction is the same as if it was omitted + // in the assembly (if compiled or assembled with the Xbox 360 shader + // compiler), and thus reassembling the shader with this instruction omitted + // will result in the same microcode (since instructions with just an empty + // write mask may have different values in other fields). + // This is for disassembly! Translators should use the write masks and + // the changed state bits in the opcode info to skip operations, as this only + // covers one very specific nop format! + bool IsVectorOpDefaultNop() const; + // Whether the scalar part of the instruction is the same as if it was omitted + // in the assembly (if compiled or assembled with the Xbox 360 shader + // compiler), and thus reassembling the shader with this instruction omitted + // will result in the same microcode (since instructions with just an empty + // write mask may have different values in other fields). + bool IsScalarOpDefaultNop() const; + + // For translation (not disassembly) - whether this instruction has totally no + // effect. + bool IsNop() const; + + // If this is a "normal" eA write recognized by Xenia (MAD with a stream + // constant), returns the index of the stream float constant, otherwise + // returns UINT32_MAX. + uint32_t GetMemExportStreamConstant() const; + + // Disassembles the instruction into ucode assembly text. + void Disassemble(string::StringBuffer* out) const; +}; + +void ParseControlFlowExec(const ucode::ControlFlowExecInstruction& cf, uint32_t cf_index, + ParsedExecInstruction& instr); +void ParseControlFlowCondExec(const ucode::ControlFlowCondExecInstruction& cf, uint32_t cf_index, + ParsedExecInstruction& instr); +void ParseControlFlowCondExecPred(const ucode::ControlFlowCondExecPredInstruction& cf, + uint32_t cf_index, ParsedExecInstruction& instr); +void ParseControlFlowLoopStart(const ucode::ControlFlowLoopStartInstruction& cf, uint32_t cf_index, + ParsedLoopStartInstruction& instr); +void ParseControlFlowLoopEnd(const ucode::ControlFlowLoopEndInstruction& cf, uint32_t cf_index, + ParsedLoopEndInstruction& instr); +void ParseControlFlowCondCall(const ucode::ControlFlowCondCallInstruction& cf, uint32_t cf_index, + ParsedCallInstruction& instr); +void ParseControlFlowReturn(const ucode::ControlFlowReturnInstruction& cf, uint32_t cf_index, + ParsedReturnInstruction& instr); +void ParseControlFlowCondJmp(const ucode::ControlFlowCondJmpInstruction& cf, uint32_t cf_index, + ParsedJumpInstruction& instr); +void ParseControlFlowAlloc(const ucode::ControlFlowAllocInstruction& cf, uint32_t cf_index, + bool is_vertex_shader, ParsedAllocInstruction& instr); + +// Returns whether the fetch is a full one, and the next parsed mini vertex +// fetch should inherit most of its parameters. +bool ParseVertexFetchInstruction(const ucode::VertexFetchInstruction& op, + const ucode::VertexFetchInstruction& previous_full_op, + ParsedVertexFetchInstruction& instr); +void ParseTextureFetchInstruction(const ucode::TextureFetchInstruction& op, + ParsedTextureFetchInstruction& instr); +void ParseAluInstruction(const ucode::AluInstruction& op, xenos::ShaderType shader_type, + ParsedAluInstruction& instr); + +class Shader { + public: + // Type of the vertex shader on the host - shader interface depends on in, so + // it must be known at translation time. If values are changed, INVALIDATE + // SHADER STORAGES (increase their version constexpr) where those are stored! + // And check bit count where this is packed. This is : uint32_t for simplicity + // of packing in bit fields. + enum class HostVertexShaderType : uint32_t { + kVertex, + + kDomainStart, + kLineDomainCPIndexed = kDomainStart, + kLineDomainPatchIndexed, + kTriangleDomainCPIndexed, + kTriangleDomainPatchIndexed, + kQuadDomainCPIndexed, + kQuadDomainPatchIndexed, + kDomainEnd, + + // For implementation without unconditional support for memory writes from + // vertex shaders, vertex shader converted to a compute shader doing only + // memory export. + kMemExportCompute, + + // 4 host vertices for 1 guest vertex, for implementations without + // unconditional geometry shader support. + kPointListAsTriangleStrip, + // 3 guest vertices processed by the host shader invocation to choose the + // strip orientation, for implementations without unconditional geometry + // shader support. + kRectangleListAsTriangleStrip, + }; + // For packing HostVertexShaderType in bit fields. + static constexpr uint32_t kHostVertexShaderTypeBitCount = 4; + + static constexpr bool IsHostVertexShaderTypeDomain(HostVertexShaderType host_vertex_shader_type) { + return host_vertex_shader_type >= HostVertexShaderType::kDomainStart && + host_vertex_shader_type < HostVertexShaderType::kDomainEnd; + } + + struct Error { + bool is_fatal = false; + std::string message; + }; + + struct VertexBinding { + struct Attribute { + // Fetch instruction with all parameters. + ParsedVertexFetchInstruction fetch_instr; + }; + + // Index within the vertex binding listing. + int binding_index; + // Fetch constant index [0-95]. + uint32_t fetch_constant; + // Stride of the entire binding, in words. + uint32_t stride_words; + // Packed attributes within the binding buffer. + std::vector attributes; + }; + + struct TextureBinding { + // Index within the texture binding listing. + size_t binding_index; + // Fetch constant index [0-31]. + uint32_t fetch_constant; + // Fetch instruction with all parameters. + ParsedTextureFetchInstruction fetch_instr; + }; + + struct ConstantRegisterMap { + // Bitmap of all kConstantFloat registers read by the shader. + // Any shader can only read up to 256 of the 512, and the base is dependent + // on the shader type and SQ_VS/PS_CONST registers. Each bit corresponds to + // a storage index from the type base. + uint64_t float_bitmap[256 / 64]; + // Bitmap of all loop constants read by the shader. + // Each bit corresponds to a storage index [0-31]. + uint32_t loop_bitmap; + // Bitmap of all bool constants read by the shader. + // Each bit corresponds to a storage index [0-255]. + uint32_t bool_bitmap[256 / 32]; + // Bitmap of all vertex fetch constants read by the shader. + // Each bit corresponds to a storage index [0-95]. + uint32_t vertex_fetch_bitmap[96 / 32]; + + // Total number of kConstantFloat registers read by the shader. + uint32_t float_count; + + // Whether kConstantFloat registers are indexed dynamically - in this case, + // float_bitmap must be set to all 1, and tight packing must not be done. + bool float_dynamic_addressing; + + // Returns the index of the float4 constant as if all float4 constant + // registers actually referenced were tightly packed in a buffer, or + // UINT32_MAX if not found. + uint32_t GetPackedFloatConstantIndex(uint32_t float_constant) const { + if (float_constant >= 256) { + return UINT32_MAX; + } + if (float_dynamic_addressing) { + // Any can potentially be read - not packing. + return float_constant; + } + uint32_t block_index = float_constant / 64; + uint32_t bit_index = float_constant % 64; + if (!(float_bitmap[block_index] & (uint64_t(1) << bit_index))) { + return UINT32_MAX; + } + uint32_t offset = 0; + for (uint32_t i = 0; i < block_index; ++i) { + offset += rex::bit_count(float_bitmap[i]); + } + return offset + rex::bit_count(float_bitmap[block_index] & ((uint64_t(1) << bit_index) - 1)); + } + }; + + struct ControlFlowMemExportInfo { + // Which eM elements have potentially (regardless of conditionals, loop + // iteration counts, predication) been written earlier in the predecessor + // graph of the instruction since an `alloc export`. + uint8_t eM_potentially_written_before = 0; + // For exec sequences, which eM elements are potentially (regardless of + // predication) written by the instructions in the sequence. For other + // control flow instructions, it's 0. + uint8_t eM_potentially_written_by_exec = 0; + }; + + class Translation { + public: + virtual ~Translation() {} + + Shader& shader() const { return shader_; } + + // Translator-specific modification bits. + uint64_t modification() const { return modification_; } + + // True if the shader was translated and prepared without error. + bool is_valid() const { return is_valid_; } + + // True if the shader has already been translated. + bool is_translated() const { return is_translated_; } + + // Errors that occurred during translation. + const std::vector& errors() const { return errors_; } + + // Translated shader binary (or text). + const std::vector& translated_binary() const { return translated_binary_; } + + // Gets the translated shader binary as a string. + // This is only valid if it is actually text. + std::string GetTranslatedBinaryString() const; + + // Disassembly of the translated from the host graphics layer. + // May be empty if the host does not support disassembly. + const std::string& host_disassembly() const { return host_disassembly_; } + + // In case disassembly depends on the GPU backend, for setting it + // externally. + void set_host_disassembly(std::string disassembly) { + host_disassembly_ = std::move(disassembly); + } + + // For dumping after translation. Dumps the shader's translated code, and, + // if available, translated disassembly, to files in the given directory + // based on ucode hash. Returns {binary path, disassembly path if written}. + std::pair Dump( + const std::filesystem::path& base_path, const char* path_prefix) const; + + protected: + Translation(Shader& shader, uint64_t modification) + : shader_(shader), modification_(modification) {} + + // If there was some failure during preparation on the implementation side. + void MakeInvalid() { is_valid_ = false; } + + private: + friend class Shader; + friend class ShaderTranslator; + + Shader& shader_; + uint64_t modification_; + + bool is_valid_ = false; + bool is_translated_ = false; + std::vector errors_; + std::vector translated_binary_; + std::string host_disassembly_; + }; + + // ucode_source_endian specifies the endianness of the ucode_dwords argument - + // inside the Shader, the ucode will be stored with the native byte order. + Shader(xenos::ShaderType shader_type, uint64_t ucode_data_hash, const uint32_t* ucode_dwords, + size_t ucode_dword_count, std::endian ucode_source_endian = std::endian::big); + virtual ~Shader(); + + // Whether the shader is identified as a vertex or pixel shader. + xenos::ShaderType type() const { return shader_type_; } + + // Microcode dwords in host endianness. + const std::vector& ucode_data() const { return ucode_data_; } + uint64_t ucode_data_hash() const { return ucode_data_hash_; } + const uint32_t* ucode_dwords() const { return ucode_data_.data(); } + size_t ucode_dword_count() const { return ucode_data_.size(); } + + bool is_ucode_analyzed() const { return is_ucode_analyzed_; } + // ucode_disasm_buffer is temporary storage for disassembly (provided + // externally so it won't need to be reallocated for every shader). + void AnalyzeUcode(string::StringBuffer& ucode_disasm_buffer); + + // The following parameters, until the translation, are valid if ucode + // information has been gathered. + + // Microcode disassembly in D3D format. + const std::string& ucode_disassembly() const { return ucode_disassembly_; } + + // All vertex bindings used in the shader. + const std::vector& vertex_bindings() const { return vertex_bindings_; } + + // All texture bindings used in the shader. + const std::vector& texture_bindings() const { return texture_bindings_; } + + // Bitmaps of all constant registers accessed by the shader. + const ConstantRegisterMap& constant_register_map() const { return constant_register_map_; } + + // Information about memory export state at each control flow instruction. May + // be empty if there are no eM# writes. + const std::vector& cf_memexport_info() const { + return cf_memexport_info_; + } + + uint8_t memexport_eM_written() const { return memexport_eM_written_; } + uint8_t memexport_eM_potentially_written_before_end() const { + return memexport_eM_potentially_written_before_end_; + } + + // c# registers used as the addend in MAD operations to eA. + const std::set& memexport_stream_constants() const { + return memexport_stream_constants_; + } + + // Labels that jumps (explicit or from loops) can be done to. + const std::set& label_addresses() const { return label_addresses_; } + + // Exclusive upper bound of the indexes of paired control flow instructions + // (each corresponds to 3 dwords). + uint32_t cf_pair_index_bound() const { return cf_pair_index_bound_; } + + // Upper bound of temporary registers addressed statically by the shader - + // highest static register address + 1, or 0 if no registers referenced this + // way. SQ_PROGRAM_CNTL is not always reliable - some draws (like single point + // draws with oPos = 0001 that are done by Xbox 360's Direct3D 9 sometimes; + // can be reproduced by launching the intro mission in 4D5307E6 from the + // campaign lobby) that aren't supposed to cover any pixels use an invalid + // (zero) SQ_PROGRAM_CNTL, but with an outdated pixel shader loaded, in this + // case SQ_PROGRAM_CNTL may contain a number smaller than actually needed by + // the pixel shader - SQ_PROGRAM_CNTL should be used to go above this count if + // uses_register_dynamic_addressing is true. + uint32_t register_static_address_bound() const { return register_static_address_bound_; } + + // Whether the shader addresses temporary registers dynamically, thus + // SQ_PROGRAM_CNTL should determine the number of registers to use, not only + // register_static_address_bound. + bool uses_register_dynamic_addressing() const { return uses_register_dynamic_addressing_; } + + // For building shader modification bits (and also for normalization of them), + // returns the amount of temporary registers that need to be allocated + // explicitly - if not using register dynamic addressing, the shader + // translator will use register_static_address_bound directly. + uint32_t GetDynamicAddressableRegisterCount(uint32_t program_cntl_num_reg) const { + if (!uses_register_dynamic_addressing()) { + return 0; + } + return std::max(program_cntl_num_reg + uint32_t(1), register_static_address_bound()); + } + + // True if the current shader has any `kill` instructions. + bool kills_pixels() const { return kills_pixels_; } + + // True if the shader has any texture-related instructions (any fetch + // instructions other than vertex fetch) writing any non-constant components. + bool uses_texture_fetch_instruction_results() const { + return uses_texture_fetch_instruction_results_; + } + + // Whether each interpolator is written on any execution path. + uint32_t writes_interpolators() const { return writes_interpolators_; } + + // Whether the system vertex shader exports are written on any execution path. + uint32_t writes_point_size_edge_flag_kill_vertex() const { + return writes_point_size_edge_flag_kill_vertex_; + } + + // Returns the mask of the interpolators the pixel shader potentially requires + // from the vertex shader, and also the PsParamGen destination register, or + // UINT32_MAX if it's not needed. + uint32_t GetInterpolatorInputMask(reg::SQ_PROGRAM_CNTL sq_program_cntl, + reg::SQ_CONTEXT_MISC sq_context_misc, + uint32_t& param_gen_pos_out) const; + + // True if the shader overrides the pixel depth. + bool writes_depth() const { return writes_depth_; } + + // Whether the shader can have early depth and stencil writing enabled, unless + // alpha test or alpha to coverage is enabled. + bool implicit_early_z_write_allowed() const { + // TODO(Triang3l): Investigate what happens to memexport when the pixel + // fails the depth/stencil test, but in Direct3D 11 UAV writes disable early + // depth/stencil. + return !kills_pixels() && !writes_depth() && !memexport_eM_written(); + } + + // Whether each color render target is written to on any execution path. + uint32_t writes_color_targets() const { return writes_color_targets_; } + bool writes_color_target(uint32_t i) const { + return (writes_color_targets() & (uint32_t(1) << i)) != 0; + } + + // Host translations with the specified modification bits. Not thread-safe + // with respect to translation creation/destruction. + const std::unordered_map& translations() const { return translations_; } + Translation* GetTranslation(uint64_t modification) const { + auto it = translations_.find(modification); + if (it != translations_.cend()) { + return it->second; + } + return nullptr; + } + Translation* GetOrCreateTranslation(uint64_t modification, bool* is_new = nullptr); + // For shader storage loading, to remove a modification in case of translation + // failure. Not thread-safe. + void DestroyTranslation(uint64_t modification); + + // An externally managed identifier of the shader storage the microcode of the + // shader was last written to, or was loaded from, to only write the shader + // microcode to the storage once. UINT32_MAX by default. + uint32_t ucode_storage_index() const { return ucode_storage_index_; } + void set_ucode_storage_index(uint32_t storage_index) { ucode_storage_index_ = storage_index; } + + // Dumps the shader's microcode binary and, if analyzed, disassembly, to files + // in the given directory based on ucode hash. Returns the name of the written + // file. Can be called at any time, doesn't require the shader to be + // translated. Returns {binary path, disassembly path if written}. + std::pair DumpUcode( + const std::filesystem::path& base_path) const; + + protected: + friend class ShaderTranslator; + + virtual Translation* CreateTranslationInstance(uint64_t modification); + + xenos::ShaderType shader_type_; + std::vector ucode_data_; + uint64_t ucode_data_hash_; + + // Whether info needed before translating has been gathered already - may be + // needed to determine which modifications are actually needed and make sense + // (for instance, there may be draws not covering anything and not allocating + // any pixel shader registers in SQ_PROGRAM_CNTL, but still using the pixel + // shader from the previous draw - in this case, every shader that happens to + // be before such draw will need to be translated again with a different + // dynamically addressed register count, which may cause compilation of + // different random pipelines across many random frames, thus causing + // stuttering - normally host pipeline states are deterministically only + // compiled when a new material appears in the game, and having the order of + // draws also matter in such unpredictable way would break this rule; limit + // the effect to shaders with dynamic register addressing only, which are + // extremely rare; however care should be taken regarding depth format-related + // translation modifications in this case), also some info needed for drawing + // is collected during the ucode analysis. + bool is_ucode_analyzed_ = false; + + std::string ucode_disassembly_; + std::vector vertex_bindings_; + std::vector texture_bindings_; + ConstantRegisterMap constant_register_map_ = {}; + std::set label_addresses_; + uint32_t cf_pair_index_bound_ = 0; + uint32_t register_static_address_bound_ = 0; + uint32_t writes_interpolators_ = 0; + uint32_t writes_point_size_edge_flag_kill_vertex_ = 0; + uint32_t writes_color_targets_ = 0b0000; + bool uses_register_dynamic_addressing_ = false; + bool kills_pixels_ = false; + bool uses_texture_fetch_instruction_results_ = false; + bool writes_depth_ = false; + + // Memory export eM write info for each control flow instruction, if there are + // any eM writes in the shader. + std::vector cf_memexport_info_; + // Which memexport elements (eM#) are written for any memexport in the shader. + uint8_t memexport_eM_written_ = 0; + // ControlFlowMemExportInfo::eM_potentially_written_before equivalent for the + // end of the shader, for the last memory export (or exports if the end has + // multiple predecessor chains exporting to memory). + uint8_t memexport_eM_potentially_written_before_end_ = 0; + std::set memexport_stream_constants_; + + // Modification bits -> translation. + std::unordered_map translations_; + + uint32_t ucode_storage_index_ = UINT32_MAX; + + private: + void GatherExecInformation(const ParsedExecInstruction& instr, + ucode::VertexFetchInstruction& previous_vfetch_full, + uint32_t& unique_texture_bindings, + string::StringBuffer& ucode_disasm_buffer); + void GatherVertexFetchInformation(const ucode::VertexFetchInstruction& op, + ucode::VertexFetchInstruction& previous_vfetch_full, + string::StringBuffer& ucode_disasm_buffer); + void GatherTextureFetchInformation(const ucode::TextureFetchInstruction& op, + uint32_t& unique_texture_bindings, + string::StringBuffer& ucode_disasm_buffer); + void GatherAluInstructionInformation(const ucode::AluInstruction& op, uint32_t exec_cf_index, + string::StringBuffer& ucode_disasm_buffer); + void GatherOperandInformation(const InstructionOperand& operand); + void GatherFetchResultInformation(const InstructionResult& result); + void GatherAluResultInformation(const InstructionResult& result, uint32_t exec_cf_index); +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/pipeline/shader/spirv.h b/include/rex/graphics/pipeline/shader/spirv.h new file mode 100644 index 0000000..dd90ef7 --- /dev/null +++ b/include/rex/graphics/pipeline/shader/spirv.h @@ -0,0 +1,73 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include + +namespace rex::graphics { + +class SpirvShader : public Shader { + public: + class SpirvTranslation : public Translation { + public: + explicit SpirvTranslation(SpirvShader& shader, uint64_t modification) + : Translation(shader, modification) {} + }; + + explicit SpirvShader(xenos::ShaderType shader_type, uint64_t ucode_data_hash, + const uint32_t* ucode_dwords, size_t ucode_dword_count, + std::endian ucode_source_endian = std::endian::big); + + // Resource bindings are gathered after the successful translation of any + // modification for simplicity of translation (and they don't depend on + // modification bits). + + struct TextureBinding { + uint32_t fetch_constant : 5; + // Stacked and 3D are separate TextureBindings. + xenos::FetchOpDimension dimension : 2; + uint32_t is_signed : 1; + }; + // Safe to hash and compare with memcmp for layout hashing. + const std::vector& GetTextureBindingsAfterTranslation() const { + return texture_bindings_; + } + const uint32_t GetUsedTextureMaskAfterTranslation() const { return used_texture_mask_; } + + struct SamplerBinding { + uint32_t fetch_constant : 5; + xenos::TextureFilter mag_filter : 2; + xenos::TextureFilter min_filter : 2; + xenos::TextureFilter mip_filter : 2; + xenos::AnisoFilter aniso_filter : 3; + }; + const std::vector& GetSamplerBindingsAfterTranslation() const { + return sampler_bindings_; + } + + protected: + Translation* CreateTranslationInstance(uint64_t modification) override; + + private: + friend class SpirvShaderTranslator; + + std::atomic_flag bindings_setup_entered_ = ATOMIC_FLAG_INIT; + std::vector texture_bindings_; + std::vector sampler_bindings_; + uint32_t used_texture_mask_ = 0; +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/pipeline/shader/spirv_builder.h b/include/rex/graphics/pipeline/shader/spirv_builder.h new file mode 100644 index 0000000..dbd6b01 --- /dev/null +++ b/include/rex/graphics/pipeline/shader/spirv_builder.h @@ -0,0 +1,146 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2023 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include + +#include + +namespace rex::graphics { + +// SpvBuilder with extra helpers. + +class SpirvBuilder : public spv::Builder { + public: + SpirvBuilder(unsigned int spv_version, unsigned int user_number, spv::SpvBuildLogger* logger) + : spv::Builder(spv_version, user_number, logger) {} + + // Make public rather than protected. + using spv::Builder::createSelectionMerge; + + spv::Id createQuadOp(spv::Op op_code, spv::Id type_id, spv::Id operand1, spv::Id operand2, + spv::Id operand3, spv::Id operand4); + + spv::Id createNoContractionUnaryOp(spv::Op op_code, spv::Id type_id, spv::Id operand); + spv::Id createNoContractionBinOp(spv::Op op_code, spv::Id type_id, spv::Id operand1, + spv::Id operand2); + + spv::Id createUnaryBuiltinCall(spv::Id result_type, spv::Id builtins, int entry_point, + spv::Id operand); + spv::Id createBinBuiltinCall(spv::Id result_type, spv::Id builtins, int entry_point, + spv::Id operand1, spv::Id operand2); + spv::Id createTriBuiltinCall(spv::Id result_type, spv::Id builtins, int entry_point, + spv::Id operand1, spv::Id operand2, spv::Id operand3); + + // Helper to use for building nested control flow with if-then-else with + // additions over SpvBuilder::If. + class IfBuilder { + public: + IfBuilder(spv::Id condition, unsigned int control, SpirvBuilder& builder, + unsigned int thenWeight = 0, unsigned int elseWeight = 0); + + ~IfBuilder() { +#ifndef NDEBUG + assert_true(currentBranch == Branch::kMerge); +#endif + } + + void makeBeginElse(bool branchToMerge = true); + void makeEndIf(bool branchToMerge = true); + + // If there's no then/else block that branches to the merge block, the phi + // parent is the header block - this simplifies then-only usage. + spv::Id getThenPhiParent() const { return thenPhiParent; } + spv::Id getElsePhiParent() const { return elsePhiParent; } + + spv::Id createMergePhi(spv::Id then_variable, spv::Id else_variable) const; + + private: + enum class Branch { + kThen, + kElse, + kMerge, + }; + + IfBuilder(const IfBuilder& ifBuilder) = delete; + IfBuilder& operator=(const IfBuilder& ifBuilder) = delete; + + SpirvBuilder& builder; + spv::Id condition; + unsigned int control; + unsigned int thenWeight; + unsigned int elseWeight; + + spv::Function& function; + + spv::Block* headerBlock; + spv::Block* thenBlock; + spv::Block* elseBlock; + spv::Block* mergeBlock; + + spv::Id thenPhiParent; + spv::Id elsePhiParent; + +#ifndef NDEBUG + Branch currentBranch = Branch::kThen; +#endif + }; + + // Simpler and more flexible (such as multiple cases pointing to the same + // block) compared to makeSwitch. + class SwitchBuilder { + public: + SwitchBuilder(spv::Id selector, unsigned int selection_control, SpirvBuilder& builder); + ~SwitchBuilder() { assert_true(current_branch_ == Branch::kMerge); } + + void makeBeginDefault(); + void makeBeginCase(unsigned int literal); + void addCurrentCaseLiteral(unsigned int literal); + void makeEndSwitch(); + + // If there's no default block that branches to the merge block, the phi + // parent is the header block - this simplifies case-only usage. + spv::Id getDefaultPhiParent() const { return default_phi_parent_; } + + private: + enum class Branch { + kSelection, + kDefault, + kCase, + kMerge, + }; + + void endSegment(); + + SpirvBuilder& builder_; + spv::Id selector_; + unsigned int selection_control_; + + spv::Function& function_; + + spv::Block* header_block_; + spv::Block* merge_block_; + spv::Block* default_block_ = nullptr; + + std::vector> cases_; + + spv::Id default_phi_parent_; + + Branch current_branch_ = Branch::kSelection; + }; +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/pipeline/shader/spirv_translator.h b/include/rex/graphics/pipeline/shader/spirv_translator.h new file mode 100644 index 0000000..c51ea54 --- /dev/null +++ b/include/rex/graphics/pipeline/shader/spirv_translator.h @@ -0,0 +1,1075 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace rex::graphics { + +class SpirvShaderTranslator : public ShaderTranslator { + public: + union Modification { + // If anything in this is structure is changed in a way not compatible with + // the previous layout, invalidate the pipeline storages by increasing this + // version number (0xYYYYMMDD)! + // TODO(Triang3l): Change to 0xYYYYMMDD once it's out of the rapid + // prototyping stage (easier to do small granular updates with an + // incremental counter). + static constexpr uint32_t kVersion = 12; + + enum class DepthStencilMode : uint32_t { + kNoModifiers, + // Early fragment tests - enable if alpha test and alpha to coverage are + // disabled; ignored if anything in the shader blocks early Z writing. + kEarlyHint, + // Similar to DXBC float24 conversion modes, remapping the guest [0, 1] + // range to the host [0, 0.5] range. + kFloat24Truncating, + kFloat24Rounding, + }; + + struct { + // uint32_t 0. + // Interpolators written by the vertex shader and needed by the pixel + // shader. + uint32_t interpolator_mask : xenos::kMaxInterpolators; + // For HostVertexShaderType kPointListAsTriangleStrip, whether to output + // the point coordinates. + // For other HostVertexShaderTypes (though truly reachable only for + // kVertex), whether to output the point size. + uint32_t output_point_parameters : 1; + // Dynamically indexable register count from SQ_PROGRAM_CNTL. + uint32_t dynamic_addressable_register_count : 8; + uint32_t user_clip_plane_count : 3; + uint32_t user_clip_plane_cull : 1; + // Whether vertex killing with the "and" operator is used, and one more + // cull distance needs to be written. + uint32_t vertex_kill_and : 1; + // PA_CL_CLIP_CNTL::ps_ucp_mode for point primitives. + uint32_t point_ps_ucp_mode : 2; + // uint32_t 1. + // Pipeline stage and input configuration. + Shader::HostVertexShaderType host_vertex_shader_type : Shader::kHostVertexShaderTypeBitCount; + // For domain host vertex shader types only, xenos::TessellationMode. + uint32_t tessellation_mode : 2; + } vertex; + struct PixelShaderModification { + // uint32_t 0. + // Interpolators written by the vertex shader and needed by the pixel + // shader. + uint32_t interpolator_mask : xenos::kMaxInterpolators; + uint32_t interpolators_centroid : xenos::kMaxInterpolators; + // uint32_t 1. + // Dynamically indexable register count from SQ_PROGRAM_CNTL. + uint32_t dynamic_addressable_register_count : 8; + uint32_t param_gen_enable : 1; + uint32_t param_gen_interpolator : 4; + // If param_gen_enable is set, this must be set for point primitives, and + // must not be set for other primitive types - enables the point sprite + // coordinates input, and also effects the flag bits in PsParamGen. + uint32_t param_gen_point : 1; + // For host render targets - depth / stencil output mode. + DepthStencilMode depth_stencil_mode : 3; + } pixel; + uint64_t value = 0; + + explicit Modification(uint64_t modification_value = 0) : value(modification_value) { + static_assert_size(*this, sizeof(value)); + } + + uint32_t GetVertexClipDistanceCount() const { + return vertex.user_clip_plane_cull ? 0 : vertex.user_clip_plane_count; + } + uint32_t GetVertexCullDistanceCount() const { + return (vertex.user_clip_plane_cull ? vertex.user_clip_plane_count : 0) + + vertex.vertex_kill_and; + } + }; + + enum : uint32_t { + kSysFlag_VertexIndexLoad_Shift, + kSysFlag_ComputeOrPrimitiveVertexIndexLoad_Shift, + kSysFlag_ComputeOrPrimitiveVertexIndexLoad32Bit_Shift, + kSysFlag_ComputeOrPrimitiveVertexIndexReset_Shift, + // For memexport compute fallback only. + kSysFlag_ComputeMemExportPatchIndexFromInvocation_Shift, + // For memexport compute fallback only. + kSysFlag_ComputeMemExportPatchIndexInRegister1_Shift, + // For memexport compute fallback only. + kSysFlag_ComputeMemExportTriangleCPIndexed_Shift, + // For memexport compute fallback only. + kSysFlag_ComputeMemExportQuadCPIndexed_Shift, + kSysFlag_XYDividedByW_Shift, + kSysFlag_ZDividedByW_Shift, + kSysFlag_WNotReciprocal_Shift, + kSysFlag_PrimitivePolygonal_Shift, + kSysFlag_PrimitiveLine_Shift, + kSysFlag_MsaaSamples_Shift, + kSysFlag_DepthFloat24_Shift = kSysFlag_MsaaSamples_Shift + xenos::kMsaaSamplesBits, + kSysFlag_AlphaPassIfLess_Shift, + kSysFlag_AlphaPassIfEqual_Shift, + kSysFlag_AlphaPassIfGreater_Shift, + kSysFlag_ConvertColor0ToGamma_Shift, + kSysFlag_ConvertColor1ToGamma_Shift, + kSysFlag_ConvertColor2ToGamma_Shift, + kSysFlag_ConvertColor3ToGamma_Shift, + + kSysFlag_FSIDepthStencil_Shift, + kSysFlag_FSIDepthPassIfLess_Shift, + kSysFlag_FSIDepthPassIfEqual_Shift, + kSysFlag_FSIDepthPassIfGreater_Shift, + // 1 to write new depth to the depth buffer, 0 to keep the old one if the + // depth test passes. + kSysFlag_FSIDepthWrite_Shift, + kSysFlag_FSIStencilTest_Shift, + // If the depth / stencil test has failed, but resulted in a stencil value + // that is different than the one currently in the depth buffer, write it + // anyway and don't run the rest of the shader (to check if the sample may + // be discarded some way) - use when alpha test and alpha to coverage are + // disabled. Ignored by the shader if not applicable to it (like if it has + // kill instructions or writes the depth output). + // TODO(Triang3l): Investigate replacement with an alpha-to-mask flag, + // checking `(flags & (alpha test | alpha to mask)) == (always | disabled)`, + // taking into account the potential relation with occlusion queries (but + // should be safe at least temporarily). + kSysFlag_FSIDepthStencilEarlyWrite_Shift, + + kSysFlag_Count, + + // For HostVertexShaderType kVertex, if fullDrawIndexUint32 is not + // supported (ignored otherwise), whether to fetch the index manually + // (32-bit only - 16-bit indices are always fetched via the Vulkan index + // buffer). + kSysFlag_VertexIndexLoad = 1u << kSysFlag_VertexIndexLoad_Shift, + // For HostVertexShaderTypes kMemExportCompute, kPointListAsTriangleStrip, + // kRectangleListAsTriangleStrip, whether the vertex index needs to be + // loaded from the index buffer (rather than using autogenerated indices), + // and whether it's 32-bit. This is separate from kSysFlag_VertexIndexLoad + // because the same system constants may be used for the memexporting + // compute shader and the vertex shader for the same draw, but + // kSysFlag_VertexIndexLoad may be not needed. + kSysFlag_ComputeOrPrimitiveVertexIndexLoad = + 1u << kSysFlag_ComputeOrPrimitiveVertexIndexLoad_Shift, + kSysFlag_ComputeOrPrimitiveVertexIndexLoad32Bit = + 1u << kSysFlag_ComputeOrPrimitiveVertexIndexLoad32Bit_Shift, + kSysFlag_ComputeOrPrimitiveVertexIndexReset = + 1u << kSysFlag_ComputeOrPrimitiveVertexIndexReset_Shift, + kSysFlag_ComputeMemExportPatchIndexFromInvocation = + 1u << kSysFlag_ComputeMemExportPatchIndexFromInvocation_Shift, + kSysFlag_ComputeMemExportPatchIndexInRegister1 = + 1u << kSysFlag_ComputeMemExportPatchIndexInRegister1_Shift, + kSysFlag_ComputeMemExportTriangleCPIndexed = + 1u << kSysFlag_ComputeMemExportTriangleCPIndexed_Shift, + kSysFlag_ComputeMemExportQuadCPIndexed = 1u << kSysFlag_ComputeMemExportQuadCPIndexed_Shift, + kSysFlag_XYDividedByW = 1u << kSysFlag_XYDividedByW_Shift, + kSysFlag_ZDividedByW = 1u << kSysFlag_ZDividedByW_Shift, + kSysFlag_WNotReciprocal = 1u << kSysFlag_WNotReciprocal_Shift, + kSysFlag_PrimitivePolygonal = 1u << kSysFlag_PrimitivePolygonal_Shift, + kSysFlag_PrimitiveLine = 1u << kSysFlag_PrimitiveLine_Shift, + kSysFlag_DepthFloat24 = 1u << kSysFlag_DepthFloat24_Shift, + kSysFlag_AlphaPassIfLess = 1u << kSysFlag_AlphaPassIfLess_Shift, + kSysFlag_AlphaPassIfEqual = 1u << kSysFlag_AlphaPassIfEqual_Shift, + kSysFlag_AlphaPassIfGreater = 1u << kSysFlag_AlphaPassIfGreater_Shift, + kSysFlag_ConvertColor0ToGamma = 1u << kSysFlag_ConvertColor0ToGamma_Shift, + kSysFlag_ConvertColor1ToGamma = 1u << kSysFlag_ConvertColor1ToGamma_Shift, + kSysFlag_ConvertColor2ToGamma = 1u << kSysFlag_ConvertColor2ToGamma_Shift, + kSysFlag_ConvertColor3ToGamma = 1u << kSysFlag_ConvertColor3ToGamma_Shift, + kSysFlag_FSIDepthStencil = 1u << kSysFlag_FSIDepthStencil_Shift, + kSysFlag_FSIDepthPassIfLess = 1u << kSysFlag_FSIDepthPassIfLess_Shift, + kSysFlag_FSIDepthPassIfEqual = 1u << kSysFlag_FSIDepthPassIfEqual_Shift, + kSysFlag_FSIDepthPassIfGreater = 1u << kSysFlag_FSIDepthPassIfGreater_Shift, + kSysFlag_FSIDepthWrite = 1u << kSysFlag_FSIDepthWrite_Shift, + kSysFlag_FSIStencilTest = 1u << kSysFlag_FSIStencilTest_Shift, + kSysFlag_FSIDepthStencilEarlyWrite = 1u << kSysFlag_FSIDepthStencilEarlyWrite_Shift, + }; + static_assert(kSysFlag_Count <= 32, "Too many flags in the system constants"); + + // For Vulkan vertex memexport compute fallback dispatches. + static constexpr uint32_t kMemExportComputeDispatchX = 65535; + static constexpr uint32_t kMemExportComputeDispatchY = 65535; + + // IF SYSTEM CONSTANTS ARE CHANGED OR ADDED, THE FOLLOWING MUST BE UPDATED: + // - SystemConstantIndex enum. + // - Structure members in BeginTranslation. + // + // Using the std140 layout - vec2 must be aligned to 8 bytes, vec3 and vec4 to + // 16 bytes. + struct SystemConstants { + uint32_t flags; + uint32_t vertex_index_load_address; + xenos::Endian vertex_index_endian; + // For non-indexed line loop draws, host vertex index that should map to + // guest vertex 0. + uint32_t line_loop_closing_index; + int32_t vertex_base_index; + uint32_t vertex_index_reset; + // Number of guest vertices processed by the memexport compute dispatch. + uint32_t compute_memexport_vertex_count; + float user_clip_planes[6][4]; + + float ndc_scale[3]; + float point_vertex_diameter_min; + + float ndc_offset[3]; + float point_vertex_diameter_max; + + float point_constant_diameter[2]; + // Diameter in guest screen coordinates > radius (0.5 * diameter) in the NDC + // for the host viewport. + float point_screen_diameter_to_ndc_radius[2]; + // One bit per texture fetch constant indicating that it references a + // draw-resolution-scaled texture. + uint32_t textures_resolution_scaled; + + // Each byte contains post-swizzle TextureSign values for each of the needed + // components of each of the 32 used texture fetch constants. + uint32_t texture_swizzled_signs[8]; + + // If the imageViewFormatSwizzle portability subset is not supported, the + // component swizzle (taking both guest and host swizzles into account) to + // apply to the result directly in the shader code. In each uint32_t, + // swizzles for 2 texture fetch constants (in bits 0:11 and 12:23). + uint32_t texture_swizzles[16]; + + float alpha_test_reference; + // Bits 0:7 - alpha-to-coverage dither offsets from RB_COLORCONTROL bits + // 24:31, bit 8 - whether alpha-to-coverage is enabled. + uint32_t alpha_to_mask; + uint32_t edram_32bpp_tile_pitch_dwords_scaled; + uint32_t edram_depth_base_dwords_scaled; + + float color_exp_bias[4]; + + float edram_poly_offset_front_scale; + float edram_poly_offset_back_scale; + float edram_poly_offset_front_offset; + float edram_poly_offset_back_offset; + + union { + struct { + uint32_t edram_stencil_front_reference_masks; + uint32_t edram_stencil_front_func_ops; + + uint32_t edram_stencil_back_reference_masks; + uint32_t edram_stencil_back_func_ops; + }; + struct { + uint32_t edram_stencil_front[2]; + uint32_t edram_stencil_back[2]; + }; + }; + + uint32_t edram_rt_base_dwords_scaled[4]; + + // RT format combined with RenderTargetCache::kPSIColorFormatFlag values + // (pass via RenderTargetCache::AddPSIColorFormatFlags). + uint32_t edram_rt_format_flags[4]; + + // Render target blending options - RB_BLENDCONTROL, with only the relevant + // options (factors and operations - AND 0x1FFF1FFF). If 0x00010001 + // (1 * src + 0 * dst), blending is disabled for the render target. + uint32_t edram_rt_blend_factors_ops[4]; + + // Format info - mask to apply to the old packed RT data, and to apply as + // inverted to the new packed data, before storing (more or less the inverse + // of the write mask packed like render target channels). This can be used + // to bypass unpacking if blending is not used. If 0 and not blending, + // reading the old data from the EDRAM buffer is not required. + uint32_t edram_rt_keep_mask[4][2]; + + // Format info - values to clamp the color to before blending or storing. + // Low color, low alpha, high color, high alpha. + float edram_rt_clamp[4][4]; + + // The constant blend factor for the respective modes. + float edram_blend_constant[4]; + + // Tessellation helper shader constants. + uint32_t vertex_index_min; + uint32_t vertex_index_max; + float tessellation_factor_range_min; + float tessellation_factor_range_max; + }; + + enum ConstantBuffer : uint32_t { + kConstantBufferSystem, + kConstantBufferFloatVertex, + kConstantBufferFloatPixel, + kConstantBufferBoolLoop, + kConstantBufferFetch, + + kConstantBufferCount, + }; + + // The minimum limit for maxPerStageDescriptorStorageBuffers is 4, and for + // maxStorageBufferRange it's 128 MB. These are the values of those limits on + // Arm Mali as of November 2020. Xenia needs 512 MB shared memory to be bound, + // therefore SSBOs must only be used for shared memory - all other storage + // resources must be images or texel buffers. + enum DescriptorSet : uint32_t { + // According to the "Pipeline Layout Compatibility" section of the Vulkan + // specification: + // "Two pipeline layouts are defined to be "compatible for set N" if they + // were created with identically defined descriptor set layouts for sets + // zero through N, and if they were created with identical push constant + // ranges." + // "Place the least frequently changing descriptor sets near the start of + // the pipeline layout, and place the descriptor sets representing the most + // frequently changing resources near the end. When pipelines are switched, + // only the descriptor set bindings that have been invalidated will need to + // be updated and the remainder of the descriptor set bindings will remain + // in place." + // This is partially the reverse of the Direct3D 12's rule of placing the + // most frequently changed descriptor sets in the beginning. Here all + // descriptor sets with an immutable layout are placed first, in reverse + // frequency of changing, and sets that may be different for different + // pipeline states last. + + // Always the same descriptor set layouts for all pipeline layouts: + + // Never changed. + kDescriptorSetSharedMemoryAndEdram, + // Changed in case of changes in the data. + kDescriptorSetConstants, + + // Mutable part of the pipeline layout: + kDescriptorSetMutableLayoutsStart, + + // Rarely used at all, but may be changed at an unpredictable rate when + // vertex textures are used (for example, for bones of an object, which may + // consist of multiple draw commands with different materials). + kDescriptorSetTexturesVertex = kDescriptorSetMutableLayoutsStart, + // Per-material textures. + kDescriptorSetTexturesPixel, + + kDescriptorSetCount, + }; + static_assert(kDescriptorSetCount <= 4, + "The number of descriptor sets used by translated shaders must be within " + "the minimum Vulkan maxBoundDescriptorSets requirement of 4, which is " + "the limit on most GPUs used in Android devices - Arm Mali, Imagination " + "PowerVR, Qualcomm Adreno 6xx and older, as well as on old PC Nvidia " + "drivers"); + + // "Xenia Emulator Microcode Translator". + // https://github.com/KhronosGroup/SPIRV-Headers/blob/c43a43c7cc3af55910b9bec2a71e3e8a622443cf/include/spirv/spir-v.xml#L79 + static constexpr uint32_t kSpirvMagicToolId = 26; + + struct Features { + explicit Features(const ui::vulkan::VulkanDevice* vulkan_device); + explicit Features(bool all = false); + + unsigned int spirv_version; + + uint32_t max_storage_buffer_range; + + bool full_draw_index_uint32; + + bool vertex_pipeline_stores_and_atomics; + bool fragment_stores_and_atomics; + + bool clip_distance; + bool cull_distance; + + bool image_view_format_swizzle; + + bool signed_zero_inf_nan_preserve_float32; + bool denorm_flush_to_zero_float32; + bool rounding_mode_rte_float32; + + bool fragment_shader_sample_interlock; + + bool demote_to_helper_invocation; + bool sample_rate_shading; + }; + + SpirvShaderTranslator(const Features& features, bool native_2x_msaa_with_attachments, + bool native_2x_msaa_no_attachments, bool edram_fragment_shader_interlock, + uint32_t draw_resolution_scale_x = 1, uint32_t draw_resolution_scale_y = 1) + : features_(features), + native_2x_msaa_with_attachments_(native_2x_msaa_with_attachments), + native_2x_msaa_no_attachments_(native_2x_msaa_no_attachments), + edram_fragment_shader_interlock_(edram_fragment_shader_interlock), + draw_resolution_scale_x_(draw_resolution_scale_x ? draw_resolution_scale_x : 1), + draw_resolution_scale_y_(draw_resolution_scale_y ? draw_resolution_scale_y : 1) {} + + uint64_t GetDefaultVertexShaderModification( + uint32_t dynamic_addressable_register_count, + Shader::HostVertexShaderType host_vertex_shader_type = + Shader::HostVertexShaderType::kVertex) const override; + uint64_t GetDefaultPixelShaderModification( + uint32_t dynamic_addressable_register_count) const override; + + static constexpr uint32_t GetSharedMemoryStorageBufferCountLog2( + uint32_t max_storage_buffer_range) { + if (max_storage_buffer_range >= 512 * 1024 * 1024) { + return 0; + } + if (max_storage_buffer_range >= 256 * 1024 * 1024) { + return 1; + } + return 2; + } + uint32_t GetSharedMemoryStorageBufferCountLog2() const { + return GetSharedMemoryStorageBufferCountLog2(features_.max_storage_buffer_range); + } + + // Creates a special fragment shader without color outputs - this resets the + // state of the translator. + std::vector CreateDepthOnlyFragmentShader( + Modification::DepthStencilMode depth_stencil_mode = + Modification::DepthStencilMode::kNoModifiers); + + // Common functions useful not only for the translator, but also for EDRAM + // emulation via conventional render targets. + + // Converts the color value externally clamped to [0, 31.875] to 7e3 floating + // point, with zeros in bits 10:31, rounding to the nearest even. + static spv::Id PreClampedFloat32To7e3(SpirvBuilder& builder, spv::Id f32_scalar, + spv::Id ext_inst_glsl_std_450); + // Same as PreClampedFloat32To7e3, but clamps the input to [0, 31.875]. + static spv::Id UnclampedFloat32To7e3(SpirvBuilder& builder, spv::Id f32_scalar, + spv::Id ext_inst_glsl_std_450); + // Converts the 7e3 number in bits [f10_shift, f10_shift + 10) to a 32-bit + // float. + static spv::Id Float7e3To32(SpirvBuilder& builder, spv::Id f10_uint_scalar, uint32_t f10_shift, + bool result_as_uint, spv::Id ext_inst_glsl_std_450); + // Converts the depth value externally clamped to the representable [0, 2) + // range to 20e4 floating point, with zeros in bits 24:31, rounding to the + // nearest even or towards zero. If remap_from_0_to_0_5 is true, it's assumed + // that 0...1 is pre-remapped to 0...0.5 in the input. + static spv::Id PreClampedDepthTo20e4(SpirvBuilder& builder, spv::Id f32_scalar, + bool round_to_nearest_even, bool remap_from_0_to_0_5, + spv::Id ext_inst_glsl_std_450); + // Converts the 20e4 number in bits [f24_shift, f24_shift + 10) to a 32-bit + // float. + static spv::Id Depth20e4To32(SpirvBuilder& builder, spv::Id f24_uint_scalar, uint32_t f24_shift, + bool remap_to_0_to_0_5, bool result_as_uint, + spv::Id ext_inst_glsl_std_450); + + protected: + void Reset() override; + + uint32_t GetModificationRegisterCount() const override; + + void StartTranslation() override; + + std::vector CompleteTranslation() override; + + void PostTranslation() override; + + void ProcessLabel(uint32_t cf_index) override; + + void ProcessExecInstructionBegin(const ParsedExecInstruction& instr) override; + void ProcessExecInstructionEnd(const ParsedExecInstruction& instr) override; + void ProcessLoopStartInstruction(const ParsedLoopStartInstruction& instr) override; + void ProcessLoopEndInstruction(const ParsedLoopEndInstruction& instr) override; + void ProcessJumpInstruction(const ParsedJumpInstruction& instr) override; + void ProcessAllocInstruction(const ParsedAllocInstruction& instr, uint8_t export_eM) override; + + void ProcessVertexFetchInstruction(const ParsedVertexFetchInstruction& instr) override; + void ProcessTextureFetchInstruction(const ParsedTextureFetchInstruction& instr) override; + void ProcessAluInstruction(const ParsedAluInstruction& instr, + uint8_t memexport_eM_potentially_written_before) override; + + private: + struct TextureBinding { + uint32_t fetch_constant; + // Stacked and 3D are separate TextureBindings. + xenos::FetchOpDimension dimension; + bool is_signed; + + spv::Id variable; + }; + + struct SamplerBinding { + uint32_t fetch_constant; + xenos::TextureFilter mag_filter; + xenos::TextureFilter min_filter; + xenos::TextureFilter mip_filter; + xenos::AnisoFilter aniso_filter; + + spv::Id variable; + }; + + // Builder helpers. + spv::Id SpirvSmearScalarResultOrConstant(spv::Id scalar, spv::Id vector_type); + + Modification GetSpirvShaderModification() const { + return Modification(current_translation().modification()); + } + + bool IsSpirvVertexShader() const { + return is_vertex_shader() && !Shader::IsHostVertexShaderTypeDomain( + GetSpirvShaderModification().vertex.host_vertex_shader_type); + } + bool IsSpirvTessEvalShader() const { + return is_vertex_shader() && Shader::IsHostVertexShaderTypeDomain( + GetSpirvShaderModification().vertex.host_vertex_shader_type); + } + bool IsSpirvComputeShader() const { + return is_vertex_shader() && GetSpirvShaderModification().vertex.host_vertex_shader_type == + Shader::HostVertexShaderType::kMemExportCompute; + } + bool IsSpirvRectangleListVertexLoopEnabled() const { + return IsSpirvVertexShader() && GetSpirvShaderModification().vertex.host_vertex_shader_type == + Shader::HostVertexShaderType::kRectangleListAsTriangleStrip; + } + + bool IsExecutionModeEarlyFragmentTests() const { + return is_pixel_shader() && + GetSpirvShaderModification().pixel.depth_stencil_mode == + Modification::DepthStencilMode::kEarlyHint && + !edram_fragment_shader_interlock_ && current_shader().implicit_early_z_write_allowed(); + } + bool IsWritingFloat24Depth() const { + assert_true(is_pixel_shader()); + if (edram_fragment_shader_interlock_) { + return false; + } + Modification::DepthStencilMode depth_stencil_mode = + GetSpirvShaderModification().pixel.depth_stencil_mode; + return depth_stencil_mode == Modification::DepthStencilMode::kFloat24Truncating || + depth_stencil_mode == Modification::DepthStencilMode::kFloat24Rounding; + } + bool IsSampleRate() const { + assert_true(is_pixel_shader()); + return IsWritingFloat24Depth() && !current_shader().writes_depth(); + } + + uint32_t GetModificationInterpolatorMask() const { + Modification modification = GetSpirvShaderModification(); + return is_vertex_shader() ? modification.vertex.interpolator_mask + : modification.pixel.interpolator_mask; + } + + // Returns UINT32_MAX if PsParamGen doesn't need to be written. + uint32_t GetPsParamGenInterpolator() const; + + // Must be called before emitting any SPIR-V operations that must be in a + // block in translator callbacks to ensure that if the last instruction added + // was something like OpBranch - in this case, an unreachable block is + // created. + void EnsureBuildPointAvailable(); + + void StartVertexOrTessEvalShaderBeforeMain(); + void StartVertexOrTessEvalShaderInMain(); + void CompleteVertexOrTessEvalShaderInMain(); + + void StartFragmentShaderBeforeMain(); + void StartFragmentShaderInMain(); + void CompleteFragmentShaderInMain(); + + // Updates the current flow control condition (to be called in the beginning + // of exec and in jumps), closing the previous conditionals if needed. + // However, if the condition is not different, the instruction-level predicate + // conditional also won't be closed - this must be checked separately if + // needed (for example, in jumps). + void UpdateExecConditionals(ParsedExecInstruction::Type type, uint32_t bool_constant_index, + bool condition); + // Opens or reopens the predicate check conditional for the instruction. + // Should be called before processing a non-control-flow instruction. + void UpdateInstructionPredication(bool predicated, bool condition); + // Closes the instruction-level predicate conditional if it's open, useful if + // a control flow instruction needs to do some code which needs to respect the + // current exec conditional, but can't itself be predicated. + void CloseInstructionPredication(); + // Closes conditionals opened by exec and instructions within them (but not by + // labels) and updates the state accordingly. + void CloseExecConditionals(); + + spv::Id GetStorageAddressingIndex(InstructionStorageAddressingMode addressing_mode, + uint32_t storage_index, bool is_float_constant = false); + // Loads unswizzled operand without sign modifiers as float4. + spv::Id LoadOperandStorage(const InstructionOperand& operand); + spv::Id ApplyOperandModifiers(spv::Id operand_value, const InstructionOperand& original_operand, + bool invert_negate = false, bool force_absolute = false); + // Returns the requested components, with the operand's swizzle applied, in a + // condensed form, but without negation / absolute value modifiers. The + // storage is float4, no matter what the component count of original_operand + // is (the storage will be either r# or c#, but the instruction may be + // scalar). + spv::Id GetUnmodifiedOperandComponents(spv::Id operand_storage, + const InstructionOperand& original_operand, + uint32_t components); + spv::Id GetOperandComponents(spv::Id operand_storage, const InstructionOperand& original_operand, + uint32_t components, bool invert_negate = false, + bool force_absolute = false) { + return ApplyOperandModifiers( + GetUnmodifiedOperandComponents(operand_storage, original_operand, components), + original_operand, invert_negate, force_absolute); + } + // If components are identical, the same Id will be written to both outputs. + void GetOperandScalarXY(spv::Id operand_storage, const InstructionOperand& original_operand, + spv::Id& a_out, spv::Id& b_out, bool invert_negate = false, + bool force_absolute = false); + // Gets the absolute value of the loaded operand if it's not absolute already. + spv::Id GetAbsoluteOperand(spv::Id operand_storage, const InstructionOperand& original_operand); + // The type of the value must be a float vector consisting of + // rex::bit_count(result.GetUsedResultComponents()) elements, or (to replicate + // a scalar into all used components) float, or the value can be spv::NoResult + // if there's no result to store (like constants only). + // can_store_memexport_address is for safety, to allow only proper MADs with + // a stream constant to write to eA. + void StoreResult(const InstructionResult& result, spv::Id value, + bool can_store_memexport_address = false); + + // For Shader Model 3 multiplication (+-0 or denormal * anything = +0), + // replaces the value with +0 if the minimum of the two operands is 0. This + // must be called with absolute values of operands - use GetAbsoluteOperand! + spv::Id ZeroIfAnyOperandIsZero(spv::Id value, spv::Id operand_0_abs, spv::Id operand_1_abs); + // Conditionally discard the current fragment. Changes the build point. + void KillPixel(spv::Id condition, uint8_t memexport_eM_potentially_written_before); + // Return type is a rex::bit_count(result.GetUsedResultComponents())-component + // float vector or a single float, depending on whether it's a reduction + // instruction (check getTypeId of the result), or returns spv::NoResult if + // nothing to store. + spv::Id ProcessVectorAluOperation(const ParsedAluInstruction& instr, + uint8_t memexport_eM_potentially_written_before, + bool& predicate_written); + // Returns a float value to write to the previous scalar register and to the + // destination. If the return value is ps itself (in the retain_prev case), + // returns spv::NoResult (handled as a special case, so if it's retain_prev, + // but don't need to write to anywhere, no OpLoad(ps) will be done). + spv::Id ProcessScalarAluOperation(const ParsedAluInstruction& instr, + uint8_t memexport_eM_potentially_written_before, + bool& predicate_written); + + // Perform endian swap of a uint scalar or vector. + spv::Id EndianSwap32Uint(spv::Id value, spv::Id endian); + // Perform endian swap of a uint4 vector. + spv::Id EndianSwap128Uint4(spv::Id value, spv::Id endian); + + spv::Id LoadUint32FromSharedMemory(spv::Id address_dwords_int); + // If `replace_mask` is provided, the bits specified in the mask will be + // replaced with those from the value via OpAtomicAnd/Or. + // Bits of `value` not in `replace_mask` will be ignored. + void StoreUint32ToSharedMemory(spv::Id value, spv::Id address_dwords_int, + spv::Id replace_mask = spv::NoResult); + + bool IsMemoryExportSupported() const { + if (is_pixel_shader()) { + return features_.fragment_stores_and_atomics; + } + return features_.vertex_pipeline_stores_and_atomics || IsSpirvComputeShader(); + } + + bool IsMemoryExportUsed() const { + return current_shader().memexport_eM_written() && IsMemoryExportSupported(); + } + + void ExportToMemory(uint8_t export_eM); + + // The source may be a floating-point scalar or a vector. + spv::Id PWLGammaToLinear(spv::Id gamma, bool gamma_pre_saturated); + spv::Id LinearToPWLGamma(spv::Id linear, bool linear_pre_saturated); + + size_t FindOrAddTextureBinding(uint32_t fetch_constant, xenos::FetchOpDimension dimension, + bool is_signed); + size_t FindOrAddSamplerBinding(uint32_t fetch_constant, xenos::TextureFilter mag_filter, + xenos::TextureFilter min_filter, xenos::TextureFilter mip_filter, + xenos::AnisoFilter aniso_filter); + // `texture_parameters` need to be set up except for `sampler`, which will be + // set internally, optionally doing linear interpolation between the an + // existing value and the new one (the result location may be the same as for + // the first lerp endpoint, but not across signedness). + void SampleTexture(spv::Builder::TextureParameters& texture_parameters, + spv::ImageOperandsMask image_operands_mask, spv::Id image_unsigned, + spv::Id image_signed, spv::Id sampler, spv::Id is_any_unsigned, + spv::Id is_any_signed, spv::Id& result_unsigned_out, + spv::Id& result_signed_out, spv::Id lerp_factor = spv::NoResult, + spv::Id lerp_first_unsigned = spv::NoResult, + spv::Id lerp_first_signed = spv::NoResult); + // `texture_parameters` need to be set up except for `sampler`, which will be + // set internally. + spv::Id QueryTextureLod(spv::Builder::TextureParameters& texture_parameters, + spv::Id image_unsigned, spv::Id image_signed, spv::Id sampler, + spv::Id is_all_signed); + + spv::Id LoadMsaaSamplesFromFlags(); + // Whether it's possible and worth skipping running the translated shader for + // 2x2 quads. + bool FSI_IsDepthStencilEarly() const { + assert_true(edram_fragment_shader_interlock_); + return !is_depth_only_fragment_shader_ && !current_shader().writes_depth() && + !current_shader().memexport_eM_written(); + } + void FSI_LoadSampleMask(spv::Id msaa_samples); + void FSI_LoadEdramOffsets(spv::Id msaa_samples); + // The address must be a signed int. Whether the render target is 64bpp, if + // present at all, must be a bool (if it's NoResult, 32bpp will be assumed). + spv::Id FSI_AddSampleOffset(spv::Id sample_0_address, uint32_t sample_index, + spv::Id is_64bpp = spv::NoResult); + // Updates main_fsi_sample_mask_. Must be called outside non-uniform control + // flow because of taking derivatives of the fragment depth. + void FSI_DepthStencilTest(spv::Id msaa_samples, bool sample_mask_potentially_narrowed_previouly); + // Returns the first and the second 32 bits as two uints. + std::array FSI_ClampAndPackColor(spv::Id color_float4, spv::Id format_with_flags); + std::array FSI_UnpackColor(std::array color_packed, + spv::Id format_with_flags); + // The bounds must have the same number of components as the color or alpha. + spv::Id FSI_FlushNaNClampAndInBlending(spv::Id color_or_alpha, spv::Id is_fixed_point, + spv::Id min_value, spv::Id max_value); + spv::Id FSI_ApplyColorBlendFactor(spv::Id value, spv::Id is_fixed_point, spv::Id clamp_min_value, + spv::Id clamp_max_value, spv::Id factor, spv::Id source_color, + spv::Id source_alpha, spv::Id dest_color, spv::Id dest_alpha, + spv::Id constant_color, spv::Id constant_alpha); + spv::Id FSI_ApplyAlphaBlendFactor(spv::Id value, spv::Id is_fixed_point, spv::Id clamp_min_value, + spv::Id clamp_max_value, spv::Id factor, spv::Id source_alpha, + spv::Id dest_alpha, spv::Id constant_alpha); + // If source_color_clamped, dest_color, constant_color_clamped are + // spv::NoResult, will blend the alpha. Otherwise, will blend the color. + // The result will be unclamped (color packing is supposed to clamp it). + spv::Id FSI_BlendColorOrAlphaWithUnclampedResult( + spv::Id is_fixed_point, spv::Id clamp_min_value, spv::Id clamp_max_value, + spv::Id source_color_clamped, spv::Id source_alpha_clamped, spv::Id dest_color, + spv::Id dest_alpha, spv::Id constant_color_clamped, spv::Id constant_alpha_clamped, + spv::Id equation, spv::Id source_factor, spv::Id dest_factor); + + Features features_; + bool native_2x_msaa_with_attachments_; + bool native_2x_msaa_no_attachments_; + + // For safety with different drivers (even though fragment shader interlock in + // SPIR-V only has one control flow requirement - that both begin and end must + // be dynamically executed exactly once in this order), adhering to the more + // strict control flow limitations of OpenGL (GLSL) fragment shader interlock, + // that begin and end are called only on the outermost level of the control + // flow of the main function, and that there are no returns before either + // (there's a single return from the shader). + bool edram_fragment_shader_interlock_; + uint32_t draw_resolution_scale_x_; + uint32_t draw_resolution_scale_y_; + + // Is currently writing the empty depth-only pixel shader, such as for depth + // and stencil testing with fragment shader interlock. + bool is_depth_only_fragment_shader_ = false; + + std::unique_ptr builder_; + + std::vector id_vector_temp_; + // For helper functions like operand loading, so they don't conflict with + // id_vector_temp_ usage in bigger callbacks. + std::vector id_vector_temp_util_; + std::vector uint_vector_temp_; + std::vector uint_vector_temp_util_; + + spv::Id ext_inst_glsl_std_450_; + + spv::Id type_void_; + + union { + struct { + spv::Id type_bool_; + spv::Id type_bool2_; + spv::Id type_bool3_; + spv::Id type_bool4_; + }; + // Index = component count - 1. + spv::Id type_bool_vectors_[4]; + }; + union { + struct { + spv::Id type_int_; + spv::Id type_int2_; + spv::Id type_int3_; + spv::Id type_int4_; + }; + spv::Id type_int_vectors_[4]; + }; + union { + struct { + spv::Id type_uint_; + spv::Id type_uint2_; + spv::Id type_uint3_; + spv::Id type_uint4_; + }; + spv::Id type_uint_vectors_[4]; + }; + union { + struct { + spv::Id type_float_; + spv::Id type_float2_; + spv::Id type_float3_; + spv::Id type_float4_; + }; + spv::Id type_float_vectors_[4]; + }; + + spv::Id const_int_0_; + spv::Id const_int4_0_; + spv::Id const_uint_0_; + spv::Id const_uint4_0_; + union { + struct { + spv::Id const_float_0_; + spv::Id const_float2_0_; + spv::Id const_float3_0_; + spv::Id const_float4_0_; + }; + spv::Id const_float_vectors_0_[4]; + }; + union { + struct { + spv::Id const_float_1_; + spv::Id const_float2_1_; + spv::Id const_float3_1_; + spv::Id const_float4_1_; + }; + spv::Id const_float_vectors_1_[4]; + }; + // vec2(0.0, 1.0), to arbitrarily VectorShuffle non-constant and constant + // components. + spv::Id const_float2_0_1_; + + enum SystemConstantIndex : unsigned int { + kSystemConstantFlags, + kSystemConstantVertexIndexLoadAddress, + kSystemConstantVertexIndexEndian, + kSystemConstantLineLoopClosingIndex, + kSystemConstantVertexBaseIndex, + kSystemConstantVertexIndexReset, + kSystemConstantComputeMemExportVertexCount, + kSystemConstantUserClipPlanes, + kSystemConstantVertexIndexMin, + kSystemConstantVertexIndexMax, + kSystemConstantNdcScale, + kSystemConstantPointVertexDiameterMin, + kSystemConstantNdcOffset, + kSystemConstantPointVertexDiameterMax, + kSystemConstantPointConstantDiameter, + kSystemConstantPointScreenDiameterToNdcRadius, + kSystemConstantTexturesResolutionScaled, + kSystemConstantTextureSwizzledSigns, + kSystemConstantTextureSwizzles, + kSystemConstantAlphaTestReference, + kSystemConstantAlphaToMask, + kSystemConstantEdram32bppTilePitchDwordsScaled, + kSystemConstantEdramDepthBaseDwordsScaled, + kSystemConstantColorExpBias, + kSystemConstantEdramPolyOffsetFrontScale, + kSystemConstantEdramPolyOffsetBackScale, + kSystemConstantEdramPolyOffsetFrontOffset, + kSystemConstantEdramPolyOffsetBackOffset, + kSystemConstantEdramStencilFront, + kSystemConstantEdramStencilBack, + kSystemConstantEdramRTBaseDwordsScaled, + kSystemConstantEdramRTFormatFlags, + kSystemConstantEdramRTBlendFactorsOps, + // Accessed as float4[2], not float2[4], due to std140 array stride + // alignment. + kSystemConstantEdramRTKeepMask, + kSystemConstantEdramRTClamp, + kSystemConstantEdramBlendConstant, + }; + spv::Id uniform_system_constants_; + spv::Id uniform_float_constants_; + spv::Id uniform_bool_loop_constants_; + spv::Id uniform_fetch_constants_; + + spv::Id buffers_shared_memory_; + spv::Id buffer_edram_; + + // Not using combined images and samplers because + // maxPerStageDescriptorSamplers is often lower than + // maxPerStageDescriptorSampledImages, and for every fetch constant, there + // are, for regular fetches, two bindings (unsigned and signed). + std::vector texture_bindings_; + std::vector sampler_bindings_; + + // VS as VS only - int, or VS as compute (kMemExportCompute) only - uint3. + spv::Id input_vertex_index_; + // VS as TES only - int. + spv::Id input_primitive_id_; + // VS as TES only - float3. + spv::Id input_tess_coord_; + // VS as TES only - patch float4. + spv::Id input_patch_control_point_indices_; + // PS, only when needed - float2. + spv::Id input_point_coordinates_; + // PS, only when needed - float4. + spv::Id input_fragment_coordinates_; + // PS, only when needed - bool. + spv::Id input_front_facing_; + // PS, only when needed - int. + spv::Id input_sample_id_; + // PS, only when needed - int[1]. + spv::Id input_sample_mask_; + + // VS output or PS input, only the ones that are needed (spv::NoResult for the + // unneeded interpolators), indexed by the guest interpolator index - float4. + // The Qualcomm Adreno driver has strict requirements for stage linkage - as + // Xenia uses separate variables, not an array (so the interpolation + // qualifiers can be applied to each element separately), the interpolators + // must also be separate variables in the other stage, including the geometry + // shader (not just an array assuming that consecutive locations will be + // linked as consecutive array elements, on Qualcomm, they won't be linked at + // all). + std::array input_output_interpolators_; + + // VS, only for HostVertexShaderType::kPointListAsTriangleStrip when needed + // for the PS - float2. + spv::Id output_point_coordinates_; + // VS, only when needed - float. + spv::Id output_point_size_; + + enum OutputPerVertexMember : unsigned int { + kOutputPerVertexMemberPosition, + kOutputPerVertexMemberClipDistance, + kOutputPerVertexMemberCullDistance, + kOutputPerVertexMemberCountMax, + }; + uint32_t output_per_vertex_member_count_; + uint32_t output_per_vertex_member_clip_distance_; + uint32_t output_per_vertex_member_cull_distance_; + spv::Id type_output_per_vertex_; + spv::Id output_per_vertex_; + + // With fragment shader interlock, variables in the main function. + // Otherwise, framebuffer color attachment outputs. + std::array output_or_var_fragment_data_; + // For host render targets and only when needed - float. + spv::Id output_fragment_depth_; + // For host render targets and only when needed - int[1]. + spv::Id output_fragment_sample_mask_; + + std::vector main_interface_; + spv::Function* function_main_; + spv::Id main_system_constant_flags_; + // bool. + spv::Id var_main_predicate_; + // uint4. + spv::Id var_main_loop_count_; + // int4. + spv::Id var_main_loop_address_; + // int. + spv::Id var_main_address_register_; + // float. + spv::Id var_main_previous_scalar_; + // `base + index * stride` in dwords from the last vfetch_full as it may be + // needed by vfetch_mini - int. + spv::Id var_main_vfetch_address_; + // float. + spv::Id var_main_tfetch_lod_; + // float3. + spv::Id var_main_tfetch_gradients_h_; + spv::Id var_main_tfetch_gradients_v_; + // float4[register_count()]. + spv::Id var_main_registers_; + // Memory export variables are created only when needed. + // float4. + spv::Id var_main_memexport_address_; + // Each is float4. + spv::Id var_main_memexport_data_[ucode::kMaxMemExportElementCount]; + // Bit field of which eM# elements have been written so far by the invocation + // since the last memory write - uint. + spv::Id var_main_memexport_data_written_; + // If memory export is disabled in certain invocations or (if emulating some + // primitive types without a geometry shader) at specific guest vertex loop + // iterations because the translated shader is executed multiple times for the + // same guest vertex or pixel, this contains whether memory export is allowed + // in the current execution of the translated code. + // bool. + spv::Id main_memexport_allowed_; + // VS rectangle-list fallback only - uint. + spv::Id var_main_rectangle_guest_vertex_index_; + // VS rectangle-list fallback only - gl_PerVertex[3]. + spv::Id var_main_rectangle_per_vertex_; + // VS rectangle-list fallback only - float4[3] for each used interpolator. + std::array var_main_rectangle_interpolators_; + // VS only - float3 (special exports). + spv::Id var_main_point_size_edge_flag_kill_vertex_; + // PS, only when needed - bool. + spv::Id var_main_kill_pixel_; + // PS, with fragment shader interlock and depth export - float. + spv::Id var_main_fragment_depth_; + // PS, only when writing to color render targets with fragment shader + // interlock - uint. + // Whether color buffers have been written to, if not written on the taken + // execution path, don't export according to Direct3D 9 register documentation + // (some games rely on this behavior). + spv::Id var_main_fsi_color_written_; + // Loaded by FSI_LoadSampleMask. + // Can be modified on the outermost control flow level in the main function. + // 0:3 - Per-sample coverage at the current stage of the shader's execution. + // Affected by things like gl_SampleMaskIn, early or late depth / + // stencil (always resets bits for failing, no matter if need to defer + // writing), alpha to coverage. + // 4:7 - Depth write deferred mask - when early depth / stencil resulted in a + // different value for the sample (like different stencil if the test + // failed), but can't write it before running the shader because it's + // not known if the sample will be discarded by the shader, alphatest or + // AtoC. + // Early depth / stencil rejection of the pixel is possible when both 0:3 and + // 4:7 are zero. + spv::Id main_fsi_sample_mask_; + // Loaded by FSI_LoadEdramOffsets. + // Including the depth render target base. + spv::Id main_fsi_address_depth_; + // Not including the render target base. + spv::Id main_fsi_offset_32bpp_; + spv::Id main_fsi_offset_64bpp_; + // Loaded by FSI_DepthStencilTest for early depth / stencil, the depth / + // stencil values to write at the end of the shader if the specified in + // main_fsi_sample_mask_ and if the samples were not discarded later after the + // early test. + std::array main_fsi_late_write_depth_stencil_; + spv::Block* main_fsi_early_depth_stencil_execute_quad_merge_; + spv::Block* main_loop_header_; + spv::Block* main_loop_continue_; + // Convergence of loop body exits before per-iteration finalization in + // rectangle-list vertex fallback; otherwise also the loop merge. + spv::Block* main_loop_merge_; + // Actual loop merge for rectangle-list vertex fallback; otherwise the same as + // main_loop_merge_. + spv::Block* main_loop_exit_; + spv::Id main_loop_pc_next_; + spv::Block* main_switch_header_; + std::unique_ptr main_switch_op_; + spv::Block* main_switch_merge_; + std::vector main_switch_next_pc_phi_operands_; + + // If the exec bool constant / predicate conditional is open, block after it + // (not added to the function yet). + spv::Block* cf_exec_conditional_merge_; + // If the instruction-level predicate conditional is open, block after it (not + // added to the function yet). + spv::Block* cf_instruction_predicate_merge_; + // When cf_exec_conditional_merge_ is not null: + // If the current exec conditional is based on a bool constant: the number of + // the bool constant. + // If it's based on the predicate value: kCfExecBoolConstantPredicate. + uint32_t cf_exec_bool_constant_or_predicate_; + static constexpr uint32_t kCfExecBoolConstantPredicate = UINT32_MAX; + // When cf_exec_conditional_merge_ is not null, the expected bool constant or + // predicate value for the current exec conditional. + bool cf_exec_condition_; + // When cf_instruction_predicate_merge_ is not null, the expected predicate + // value for the current or the last instruction. + bool cf_instruction_predicate_condition_; + // Whether there was a `setp` in the current exec before the current + // instruction, thus instruction-level predicate value can be different than + // the exec-level predicate value, and can't merge two execs with the same + // predicate condition anymore. + bool cf_exec_predicate_written_; +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/pipeline/shader/translator.h b/include/rex/graphics/pipeline/shader/translator.h new file mode 100644 index 0000000..340ced5 --- /dev/null +++ b/include/rex/graphics/pipeline/shader/translator.h @@ -0,0 +1,154 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace rex::graphics { + +class ShaderTranslator { + public: + virtual ~ShaderTranslator(); + + virtual uint64_t GetDefaultVertexShaderModification( + uint32_t /*dynamic_addressable_register_count*/, + Shader::HostVertexShaderType /*host_vertex_shader_type*/ = + Shader::HostVertexShaderType::kVertex) const { + return 0; + } + virtual uint64_t GetDefaultPixelShaderModification( + uint32_t /*dynamic_addressable_register_count*/) const { + return 0; + } + + // AnalyzeUcode must be done on the shader before translating! + bool TranslateAnalyzedShader(Shader::Translation& translation); + + protected: + ShaderTranslator(); + + // Resets translator state before beginning translation. + virtual void Reset(); + + // Shader and modification currently being translated. + Shader::Translation& current_translation() const { return *translation_; } + Shader& current_shader() const { return current_translation().shader(); } + + // Register count from SQ_PROGRAM_CNTL, stored by the implementation in its + // modification bits. + virtual uint32_t GetModificationRegisterCount() const { return xenos::kMaxShaderTempRegisters; } + + // True if the current shader is a vertex shader. + bool is_vertex_shader() const { return current_shader().type() == xenos::ShaderType::kVertex; } + // True if the current shader is a pixel shader. + bool is_pixel_shader() const { return current_shader().type() == xenos::ShaderType::kPixel; } + + // Temporary register count, accessible via static and dynamic addressing. + uint32_t register_count() const { return register_count_; } + + // Emits a translation error that will be passed back in the result. + virtual void EmitTranslationError(const char* message, bool is_fatal = true); + + // Handles the start of translation. + // At this point the vertex and texture bindings have been gathered. + virtual void StartTranslation() {} + + // Handles the end of translation when all ucode has been processed. + // Returns the translated shader binary. + virtual std::vector CompleteTranslation() { return std::vector(); } + + // Handles post-translation tasks when the shader has been fully translated. + virtual void PostTranslation() {} + // Sets the host disassembly on a shader. + void set_host_disassembly(Shader::Translation& translation, std::string value) { + translation.host_disassembly_ = std::move(value); + } + + // Pre-process a control-flow instruction before anything else. + virtual void PreProcessControlFlowInstructions( + std::vector /*instrs*/) {} + + // Handles translation for control flow label addresses. + // This is triggered once for each label required (due to control flow + // operations) before any of the instructions within the target exec. + virtual void ProcessLabel(uint32_t /*cf_index*/) {} + + // Handles translation for control flow nop instructions. + virtual void ProcessControlFlowNopInstruction(uint32_t /*cf_index*/) {} + // Handles the start of a control flow instruction at the given address. + virtual void ProcessControlFlowInstructionBegin(uint32_t /*cf_index*/) {} + // Handles the end of a control flow instruction that began at the given + // address. + virtual void ProcessControlFlowInstructionEnd(uint32_t /*cf_index*/) {} + // Handles translation for control flow exec instructions prior to their + // contained ALU/fetch instructions. + virtual void ProcessExecInstructionBegin(const ParsedExecInstruction& /*instr*/) {} + // Handles translation for control flow exec instructions after their + // contained ALU/fetch instructions. + virtual void ProcessExecInstructionEnd(const ParsedExecInstruction& /*instr*/) {} + // Handles translation for loop start instructions. + virtual void ProcessLoopStartInstruction(const ParsedLoopStartInstruction& /*instr*/) {} + // Handles translation for loop end instructions. + virtual void ProcessLoopEndInstruction(const ParsedLoopEndInstruction& /*instr*/) {} + // Handles translation for function call instructions. + virtual void ProcessCallInstruction(const ParsedCallInstruction& /*instr*/) {} + // Handles translation for function return instructions. + virtual void ProcessReturnInstruction(const ParsedReturnInstruction& /*instr*/) {} + // Handles translation for jump instructions. + virtual void ProcessJumpInstruction(const ParsedJumpInstruction& /*instr*/) {} + // Handles translation for alloc instructions. Memory exports for eM# + // indicated by export_eM must be performed, regardless of the alloc type. + virtual void ProcessAllocInstruction(const ParsedAllocInstruction& /*instr*/, + uint8_t /*export_eM*/) {} + + // Handles translation for vertex fetch instructions. + virtual void ProcessVertexFetchInstruction(const ParsedVertexFetchInstruction& /*instr*/) {} + // Handles translation for texture fetch instructions. + virtual void ProcessTextureFetchInstruction(const ParsedTextureFetchInstruction& /*instr*/) {} + // Handles translation for ALU instructions. + // memexport_eM_potentially_written_before needs to be handled by `kill` + // instruction to make sure memory exports for the eM# writes earlier in + // previous execs and the current exec are done before the invocation becomes + // inactive. + virtual void ProcessAluInstruction(const ParsedAluInstruction& /*instr*/, + uint8_t /*memexport_eM_potentially_written_before*/) {} + + private: + void TranslateControlFlowInstruction(const ucode::ControlFlowInstruction& cf); + void TranslateExecInstructions(const ParsedExecInstruction& instr); + + // Current shader and modification being translated. + Shader::Translation* translation_ = nullptr; + + // Accumulated translation errors. + std::vector errors_; + + // Temporary register count, accessible via static and dynamic addressing. + uint32_t register_count_ = 0; + + // Current control flow dword index. + uint32_t cf_index_ = 0; + + // Kept for supporting vfetch_mini. + ucode::VertexFetchInstruction previous_vfetch_full_; +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/pipeline/texture/cache.h b/include/rex/graphics/pipeline/texture/cache.h new file mode 100644 index 0000000..d1580fc --- /dev/null +++ b/include/rex/graphics/pipeline/texture/cache.h @@ -0,0 +1,622 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace rex::graphics { + +// Manages host copies of guest textures, performing untiling, format and endian +// conversion of textures stored in the shared memory, and also handling +// invalidation. +// +// Mipmaps are treated the following way, according to the GPU hang message +// found in game executables explaining the valid usage of BaseAddress when +// streaming the largest LOD (it says games should not use 0 as the base address +// when the largest LOD isn't loaded, but rather, either allocate a valid +// address for it or make it the same as mip_address): +// - If the texture has a base address, but no mip address, it's not mipmapped - +// the host texture has only the largest level too. +// - If the texture has different non-zero base address and mip address, a host +// texture with mip_max_level+1 mipmaps is created - mip_min_level is ignored +// and treated purely as sampler state because there are tfetch instructions +// working directly with LOD values - including fetching with an explicit LOD. +// However, the max level is not ignored because any mip count can be +// specified when creating a texture, and another texture may be placed after +// the last one. +// - If the texture has a mip address, but the base address is 0 or the same as +// the mip address, a mipmapped texture is created, but min/max LOD is clamped +// to the lower bound of 1 - the game is expected to do that anyway until the +// largest LOD is loaded. +// TODO(Triang3l): Attach the largest LOD to existing textures with a valid +// mip_address but no base ever used yet (no base_address) to save memory +// because textures are streamed this way anyway. +class TextureCache { + public: + // Hard limit, originating from the half-pixel offset filling hack in the + // resolve shaders only filling up to 3 pixels, due to the bit counts used for + // passing the scale to shaders, and because the full 490 MB EDRAM buffer is + // within the minimum Direct3D 12 requirement of 128 * 2^20 texels in a single + // buffer binding (counted as R32 for a byte address buffer). + static constexpr uint32_t kMaxDrawResolutionScaleAlongAxis = 7; + + TextureCache(const TextureCache& texture_cache) = delete; + TextureCache& operator=(const TextureCache& texture_cache) = delete; + virtual ~TextureCache(); + + // Returns whether the actual scale is not smaller than the requested one. + static bool GetConfigDrawResolutionScale(uint32_t& x_out, uint32_t& y_out); + uint32_t draw_resolution_scale_x() const { return draw_resolution_scale_x_; } + uint32_t draw_resolution_scale_y() const { return draw_resolution_scale_y_; } + bool IsDrawResolutionScaled() const { + return draw_resolution_scale_x_ > 1 || draw_resolution_scale_y_ > 1; + } + + virtual void ClearCache(); + + virtual void CompletedSubmissionUpdated(uint64_t completed_submission_index); + virtual void BeginSubmission(uint64_t new_submission_index); + virtual void BeginFrame(); + + void MarkRangeAsResolved(uint32_t start_unscaled, uint32_t length_unscaled); + // Ensures the memory backing the range in the scaled resolve address space is + // allocated and returns whether it is. + virtual bool EnsureScaledResolveMemoryCommitted(uint32_t /*start_unscaled*/, + uint32_t /*length_unscaled*/, + uint32_t /*length_scaled_alignment_log2*/ = 0) { + return false; + } + + static uint32_t GuestToHostSwizzle(uint32_t guest_swizzle, uint32_t host_format_swizzle); + + void TextureFetchConstantWritten(uint32_t index) { TextureFetchConstantsWritten(index, index); } + void TextureFetchConstantsWritten(uint32_t first_index, uint32_t last_index) { + if (first_index > last_index) { + uint32_t swap_index = first_index; + first_index = last_index; + last_index = swap_index; + } + if (first_index > 31) { + return; + } + if (last_index > 31) { + last_index = 31; + } + uint32_t bit_count = last_index - first_index + 1; + uint32_t mask = bit_count == 32 ? UINT32_MAX : ((UINT32_C(1) << bit_count) - 1) << first_index; + texture_bindings_in_sync_ &= ~mask; + } + + virtual void RequestTextures(uint32_t used_texture_mask); + + // "ActiveTexture" means as of the latest RequestTextures call. + + uint32_t GetActiveTextureHostSwizzle(uint32_t fetch_constant_index) const { + const TextureBinding* binding = GetValidTextureBinding(fetch_constant_index); + return binding ? binding->host_swizzle : xenos::XE_GPU_TEXTURE_SWIZZLE_0000; + } + uint8_t GetActiveTextureSwizzledSigns(uint32_t fetch_constant_index) const { + const TextureBinding* binding = GetValidTextureBinding(fetch_constant_index); + return binding ? binding->swizzled_signs : kSwizzledSignsUnsigned; + } + bool IsActiveTextureResolutionScaled(uint32_t fetch_constant_index) const { + const TextureBinding* binding = GetValidTextureBinding(fetch_constant_index); + if (!binding) { + return false; + } + return (binding->texture && binding->texture->key().scaled_resolve) || + (binding->texture_signed && binding->texture_signed->key().scaled_resolve); + } + + protected: + struct TextureKey { + // Dimensions minus 1 are stored similarly to how they're stored in fetch + // constants so fewer bits can be used, while the maximum size (8192 for 2D) + // can still be encoded (a 8192x sky texture is used in 4D530910). + + // Physical 4 KB page with the base mip level, disregarding A/C/E address + // range prefix. + uint32_t base_page : 17; // 17 total + xenos::DataDimension dimension : 2; // 19 + uint32_t width_minus_1 : 13; // 32 + + uint32_t height_minus_1 : 13; // 45 + uint32_t tiled : 1; // 46 + uint32_t packed_mips : 1; // 47 + // Physical 4 KB page with mip 1 and smaller. + uint32_t mip_page : 17; // 64 + + // (Layers for stacked and 3D, 6 for cube, 1 for other dimensions) - 1. + uint32_t depth_or_array_size_minus_1 : 10; // 74 + uint32_t pitch : 9; // 83 + uint32_t mip_max_level : 4; // 87 + xenos::TextureFormat format : 6; // 93 + xenos::Endian endianness : 2; // 95 + // Whether this texture is signed and has a different host representation + // than an unsigned view of the same guest texture. + uint32_t signed_separate : 1; // 96 + + // Whether this texture is a resolution-scaled resolve target. + uint32_t scaled_resolve : 1; // 97 + // Least important in ==, so placed last. + uint32_t is_valid : 1; // 98 + + TextureKey() { MakeInvalid(); } + TextureKey(const TextureKey& key) { std::memcpy(this, &key, sizeof(*this)); } + TextureKey& operator=(const TextureKey& key) { + std::memcpy(this, &key, sizeof(*this)); + return *this; + } + void MakeInvalid() { + // Zero everything, including the padding, for a stable hash. + std::memset(this, 0, sizeof(*this)); + } + + using Hasher = rex::XXHasher; + bool operator==(const TextureKey& key) const { return !std::memcmp(this, &key, sizeof(*this)); } + bool operator!=(const TextureKey& key) const { return !(*this == key); } + + uint32_t GetWidth() const { return width_minus_1 + 1; } + uint32_t GetHeight() const { return height_minus_1 + 1; } + uint32_t GetDepthOrArraySize() const { return depth_or_array_size_minus_1 + 1; } + + texture_util::TextureGuestLayout GetGuestLayout() const { + return texture_util::GetGuestTextureLayout(dimension, pitch, GetWidth(), GetHeight(), + GetDepthOrArraySize(), tiled, format, packed_mips, + base_page != 0, mip_max_level); + } + + static const char* GetLogDimensionName(xenos::DataDimension dimension); + const char* GetLogDimensionName() const { return GetLogDimensionName(dimension); } + void LogAction(const char* action) const; + }; + + class Texture { + public: + Texture(const Texture& texture) = delete; + Texture& operator=(const Texture& texture) = delete; + virtual ~Texture(); + + TextureCache& texture_cache() const { return texture_cache_; } + + const TextureKey& key() const { return key_; } + + const texture_util::TextureGuestLayout& guest_layout() const { return guest_layout_; } + uint32_t GetGuestBaseSize() const { return guest_layout().base.level_data_extent_bytes; } + uint32_t GetGuestMipsSize() const { return guest_layout().mips_total_extent_bytes; } + + // For 3D-as-2D wrappers: the host texture is 2D, but guest memory tiling + // may still need to be interpreted as 3D. + bool force_load_3d_tiling() const { return force_load_3d_tiling_; } + void SetForceLoad3DTiling(bool force) { force_load_3d_tiling_ = force; } + + uint64_t GetHostMemoryUsage() const { return host_memory_usage_; } + + uint64_t last_usage_submission_index() const { return last_usage_submission_index_; } + uint64_t last_usage_time() const { return last_usage_time_; } + static constexpr uint32_t kOutdatedBitBase = UINT32_C(1) << 0; + static constexpr uint32_t kOutdatedBitMips = UINT32_C(1) << 1; + uint32_t outdated_mask() const { return outdated_mask_.load(std::memory_order_acquire); } + + bool base_outdated(const std::unique_lock& global_lock) const { + return base_outdated_; + } + bool mips_outdated(const std::unique_lock& global_lock) const { + return mips_outdated_; + } + void MakeUpToDateAndWatch(const std::unique_lock& global_lock); + + void WatchCallback(const std::unique_lock& global_lock, bool is_mip); + + // For LRU caching - updates the last usage frame and moves the texture to + // the end of the usage queue. Must be called any time the texture is + // referenced by any GPU work in the implementation to make sure it's not + // destroyed while still in use. + void MarkAsUsed(); + + void LogAction(const char* action) const; + + protected: + // If track_usage is false, the texture won't be added to the LRU list. + explicit Texture(TextureCache& texture_cache, const TextureKey& key, bool track_usage = true); + + void SetHostMemoryUsage(uint64_t new_host_memory_usage) { + texture_cache_.UpdateTexturesTotalHostMemoryUsage(new_host_memory_usage, host_memory_usage_); + host_memory_usage_ = new_host_memory_usage; + } + + private: + TextureCache& texture_cache_; + + TextureKey key_; + + texture_util::TextureGuestLayout guest_layout_; + + uint64_t host_memory_usage_ = 0; + + uint64_t last_usage_submission_index_; + uint64_t last_usage_time_; + Texture* used_previous_; + Texture* used_next_; + bool in_usage_list_; + bool force_load_3d_tiling_ = false; + + // These are to be accessed within the global critical region to synchronize + // with shared memory. + // Whether the recent base level data needs reloading from the memory. + bool base_outdated_ = false; + // Whether the recent mip data needs reloading from the memory. + bool mips_outdated_ = false; + std::atomic outdated_mask_{0}; + // Watch handles for the memory ranges. + SharedMemory::WatchHandle base_watch_handle_ = nullptr; + SharedMemory::WatchHandle mips_watch_handle_ = nullptr; + }; + + // Rules of data access in load shaders: + // - Source reading (from the shared memory or the scaled resolve buffer): + // - Guest data may be stored in a sparsely-allocated buffer, or, in + // Direct3D 12 terms, a tiled buffer. This means that some regions of the + // buffer may not be mapped. On tiled resources tier 1 hardware, accessing + // unmapped tiles results in undefined behavior, including a GPU page + // fault and device removal. So, shaders must not try to access + // potentially unmapped regions (that are outside the texture memory + // extents calculated on the CPU, taking into account that Xenia can't + // overestimate texture sizes freely since it must not try to upload + // unallocated pages on the CPU). + // - Buffer tiles have 64 KB size on Direct3D 12. Vulkan has its own + // alignment requirements for sparse binding. But overall, we're + // allocating pretty large regions. + // - Resolution scaling disabled: + // - Shared memory allocates regions of power of two sizes that map + // directly to the same portions of the 512 MB of the console's + // physical memory. So, a 64 KB-aligned host buffer region is also 64 + // KB-aligned in the guest address space. + // - Tiled textures: 32x32x4-block tiles are always resident each as a + // whole. If the width is bigger than the pitch, the overflowing 32x32x4 + // tiles are also loaded as entire tiles. We do not have separate + // shaders for 2D and 3D. So, for tiled textures, it's safe to consider + // that if any location within a 32x32-aligned portion is within the + // texture bounds, the entire 32x32 portion also can be read. + // - Linear textures: Pitch is aligned to 256 bytes. Row count, however, + // is not aligned to anything (unless the mip tail is being loaded). The + // overflowing last row in case `width > pitch`, however, is made + // resident up to the last texel in it. But row start alignment is 256, + // which is a power of two, and is smaller than the Direct3D 12 tile + // size of 64 KB. So, if any block within a 256-aligned region is within + // the texture bounds, without resolution scaling, reading from any + // location in that 256-aligned region is safe. + // - Since we use the same shaders for tiled and linear textures (as well + // as 1D textures), this means that without resolution scaling, it's + // safe to access a min(256 bytes, 32 blocks)-aligned portion along X, + // but only within the same row of blocks, with bounds checking only for + // such portion as a whole, but without additional bounds checking + // inside of it. + // - Therefore, it's recommended that shaders read power-of-two amounts of + // blocks (so there will naturally be some alignment to some power of + // two), and this way, each thread may read at most 16 16bpb blocks or + // at most 32 8bpb or smaller blocks with in a single `if (x < width)` + // for the whole aligned range of the same length. + // - Resolution scaling enabled: + // - For simplicity, unlike in the shared memory, buffer tile boundaries + // are not aligned to powers of 2 the same way as guest addresses are. + // While for 2x2 resolution scaling it still happens to be the case + // because `host scaling unit address = guest scaling unit address << 2` + // (similarly for 2x1 and 1x2), for 3x or x3, it's not - a 64 KB host + // tile would represent 7281.777 guest bytes with 3x3 (disregarding that + // sequences of texels that are adjacent in memory alongside the + // horizontal axis, not individual bytes, are scaled, but even in that + // case it's not scaling by 2^n still). + // - The above would affect the `width > pitch` case for linear textures, + // requiring overestimating the width in calculation of the range of the + // tiles to map, while not doing this overestimation on the guest memory + // extent calculation side (otherwise it may result in attempting to + // upload unallocated memory on the CPU). For example, let's take look + // at an extreme case of a 369x28 k_8 texture with a pitch of 256 bytes. + // The last row, in guest memory, would be loaded from the [7168, 7281) + // range, or, with 3x3 resolution scaling, from bytes [64512, 65529). + // However, if we try to unconditionally load 2 pixels, like the texture + // is 370x28, we will be accessing the bytes [64512, 65538). But bytes + // 65536 and 65537 will be in another 64 KB tile, which may be not + // mapped yet. However, none of this is an issue for one simple reason - + // resolving is only possible to tiled textures, so linear textures will + // never be resolution-scaled. + // - Tiled textures have potentially referenced guest 32x32-block tiles + // loaded in their entirety. So, just like for unscaled textures, if any + // block within a tile is available, the entire tile is as well. + // - Destination writing (to the linear buffer): + // - host_x_blocks_per_thread specifies how many pixels can be written + // without bounds checking within increments of that amount - the pitch of + // the destination buffer is manually overaligned if needed. + + // In textures, resolution scaling is done for 8-byte portions of memory for + // 8bpp textures, and for 16-byte portions for textures of higher bit depths + // (these are the sizes of regions where contiguous texels in memory are also + // contiguous in the texture along the horizontal axis, so 64-bit and 128-bit + // loads / stores, for 8bpp and 16bpp+ respectively, can be used for untiling + // regardless of the resolution scale). + + struct LoadConstants { + uint32_t is_tiled_3d_endian_scale; + // Base offset in bytes, resolution-scaled. + uint32_t guest_offset; + // For tiled textures - row pitch in blocks, aligned to 32, unscaled. + // For linear textures - row pitch in bytes. + uint32_t guest_pitch_aligned; + // For 3D textures only (ignored otherwise) - aligned to 32, unscaled. + uint32_t guest_z_stride_block_rows_aligned; + + // - std140 vector boundary - + + // If this is a packed mip tail, this is aligned to tile dimensions. + // Resolution-scaled. + uint32_t size_blocks[3]; + // Base offset in bytes. + uint32_t host_offset; + + // - std140 vector boundary - + + uint32_t host_pitch; + uint32_t height_texels; + }; + + static constexpr uint32_t kLoadGuestXThreadsPerGroupLog2 = 2; + static constexpr uint32_t kLoadGuestYBlocksPerGroupLog2 = 5; + + enum LoadShaderIndex { + kLoadShaderIndex8bpb, + kLoadShaderIndex16bpb, + kLoadShaderIndex32bpb, + kLoadShaderIndex64bpb, + kLoadShaderIndex128bpb, + kLoadShaderIndexR5G5B5A1ToB5G5R5A1, + kLoadShaderIndexR5G6B5ToB5G6R5, + kLoadShaderIndexR5G5B6ToB5G6R5WithRBGASwizzle, + kLoadShaderIndexRGBA4ToBGRA4, + kLoadShaderIndexRGBA4ToARGB4, + kLoadShaderIndexGBGR8ToGRGB8, + kLoadShaderIndexGBGR8ToRGB8, + kLoadShaderIndexBGRG8ToRGBG8, + kLoadShaderIndexBGRG8ToRGB8, + kLoadShaderIndexR10G11B11ToRGBA16, + kLoadShaderIndexR10G11B11ToRGBA16SNorm, + kLoadShaderIndexR11G11B10ToRGBA16, + kLoadShaderIndexR11G11B10ToRGBA16SNorm, + kLoadShaderIndexR16UNormToFloat, + kLoadShaderIndexR16SNormToFloat, + kLoadShaderIndexRG16UNormToFloat, + kLoadShaderIndexRG16SNormToFloat, + kLoadShaderIndexRGBA16UNormToFloat, + kLoadShaderIndexRGBA16SNormToFloat, + kLoadShaderIndexDXT1ToRGBA8, + kLoadShaderIndexDXT3ToRGBA8, + kLoadShaderIndexDXT5ToRGBA8, + kLoadShaderIndexDXNToRG8, + kLoadShaderIndexDXT3A, + kLoadShaderIndexDXT3AAs1111ToBGRA4, + kLoadShaderIndexDXT3AAs1111ToARGB4, + kLoadShaderIndexDXT5AToR8, + kLoadShaderIndexCTX1, + kLoadShaderIndexDepthUnorm, + kLoadShaderIndexDepthFloat, + + kLoadShaderCount, + kLoadShaderIndexUnknown = kLoadShaderCount, + }; + + struct LoadShaderInfo { + // Log2 of the sizes, in bytes, of the elements in the source (guest) and + // the destination (host) buffer bindings accessed by the copying shader, + // since the shader may copy multiple blocks per one invocation. + uint32_t source_bpe_log2; + uint32_t dest_bpe_log2; + // Number of bytes in a host resolution-scaled block (corresponding to a + // guest block if not decompressing, or a host texel if decompressing) + // written by the shader. + uint32_t bytes_per_host_block; + // Log2 of the number of guest resolution-scaled blocks along the X axis + // loaded by a single thread shader group. + uint32_t guest_x_blocks_per_thread_log2; + + uint32_t GetGuestXBlocksPerGroupLog2() const { + return kLoadGuestXThreadsPerGroupLog2 + guest_x_blocks_per_thread_log2; + } + }; + + static constexpr uint8_t kSwizzledSignsUnsigned = + uint8_t(xenos::TextureSign::kUnsigned) * uint8_t(0b01010101); + + struct TextureBinding { + TextureKey key; + // Destination swizzle merged with guest to host format swizzle. + uint32_t host_swizzle; + // Packed TextureSign values, 2 bit per each component, with guest-side + // destination swizzle from the fetch constant applied to them. + uint8_t swizzled_signs; + // Unsigned version of the texture (or signed if they have the same data). + Texture* texture; + // Signed version of the texture if the data in the signed version is + // different on the host. + Texture* texture_signed; + + TextureBinding() { Reset(); } + + void Reset() { + std::memset(this, 0, sizeof(*this)); + host_swizzle = xenos::XE_GPU_TEXTURE_SWIZZLE_0000; + swizzled_signs = kSwizzledSignsUnsigned; + } + }; + + explicit TextureCache(const RegisterFile& register_file, SharedMemory& shared_memory, + uint32_t draw_resolution_scale_x, uint32_t draw_resolution_scale_y); + + const RegisterFile& register_file() const { return register_file_; } + SharedMemory& shared_memory() const { return shared_memory_; } + + // May be called for purposes like clearing the cache, as well as in the + // destructor of the implementation if textures, for instance, have references + // to the implementation that are used in their destructor, and will become + // invalid if the implementation is destroyed before the texture. + void DestroyAllTextures(bool from_destructor = false); + + // Whether the signed version of the texture has a different representation on + // the host than its unsigned version (for example, if it's a fixed-point + // texture emulated with a larger host pixel format). + virtual bool IsSignedVersionSeparateForFormat(TextureKey /*key*/) const { return false; } + // Parameters like whether the texture is tiled and its dimensions are checked + // externally, the implementation should take only format-related parameters + // such as the format itself and the signedness into account. + virtual bool IsScaledResolveSupportedForFormat(TextureKey /*key*/) const { return false; } + // For formats with less than 4 components, implementations normally should + // replicate the last component into the non-existent ones, similar to what is + // done for unused components of operands in shaders by Microsoft's Xbox 360 + // shader compiler (.xxxx, .xyyy, .xyzz, .xyzw). + // For DXT3A and DXT5A, RRRR swizzle is specified in: + // http://fileadmin.cs.lth.se/cs/Personal/Michael_Doggett/talks/unc-xenos-doggett.pdf + // 4D5307E6 also expects replicated components in k_8 sprites. + // DXN is read as RG in 4D5307E6, but as RA in 415607E6. + // TODO(Triang3l): Find out the correct contents of unused texture components. + virtual uint32_t GetHostFormatSwizzle(TextureKey key) const = 0; + + virtual uint32_t GetMaxHostTextureWidthHeight(xenos::DataDimension dimension) const = 0; + virtual uint32_t GetMaxHostTextureDepthOrArraySize(xenos::DataDimension dimension) const = 0; + + // The texture must be created exactly with this key (if the implementation + // supports the texture with this key, otherwise, or in case of a runtime + // failure, it should return nullptr), modifying it is not allowed. + virtual std::unique_ptr CreateTexture(TextureKey key) = 0; + + // Returns nullptr not only if the key is not supported, but also if couldn't + // create the texture - if it's nullptr, occasionally a recreation attempt + // should be made. + Texture* FindOrCreateTexture(TextureKey key); + + static const LoadShaderInfo& GetLoadShaderInfo(LoadShaderIndex load_shader_index) { + assert_true(load_shader_index < kLoadShaderCount); + return load_shader_info_[load_shader_index]; + } + bool LoadTextureData(Texture& texture); + // Writes the texture data (for base, mips or both - but not neither) from the + // shared memory or the scaled resolve memory. The shared memory management is + // done outside this function, the implementation just needs to load the data + // into the texture object. + virtual bool LoadTextureDataFromResidentMemoryImpl(Texture& texture, bool load_base, + bool load_mips) = 0; + + // Converts a texture fetch constant to a texture key, normalizing and + // validating the values, or creating an invalid key, and also gets the + // post-guest-swizzle signedness. + static void BindingInfoFromFetchConstant(const xenos::xe_gpu_texture_fetch_t& fetch, + TextureKey& key_out, uint8_t* swizzled_signs_out); + + // Makes all texture bindings invalid. Also requesting textures after calling + // this will cause another attempt to create a texture or to untile it if + // there was an error. + void ResetTextureBindings(bool from_destructor = false); + + const TextureBinding* GetValidTextureBinding(uint32_t fetch_constant_index) const { + const TextureBinding& binding = texture_bindings_[fetch_constant_index]; + return binding.key.is_valid ? &binding : nullptr; + } + // Called when something in a texture binding is changed for the + // implementation to update the internal dependencies of the binding. + virtual void UpdateTextureBindingsImpl(uint32_t /*fetch_constant_mask*/) {} + + private: + struct PendingTextureLoad { + Texture* texture = nullptr; + bool load_base = false; + bool load_mips = false; + }; + struct PendingSharedMemoryRange { + uint32_t start = 0; + uint32_t length = 0; + }; + bool PrepareTextureLoad(Texture& texture, PendingTextureLoad& pending_load_out, + PendingSharedMemoryRange* pending_ranges_out, + size_t& pending_range_count_out); + bool CommitPreparedTextureLoad(const PendingTextureLoad& pending_load); + + void UpdateTexturesTotalHostMemoryUsage(uint64_t add, uint64_t subtract); + + // Shared memory callback for texture data invalidation. + static void WatchCallback(const std::unique_lock& global_lock, + void* context, void* data, uint64_t argument, bool invalidated_by_gpu); + + // Checks if there are any pages that contain scaled resolve data within the + // range. + bool IsRangeScaledResolved(uint32_t start_unscaled, uint32_t length_unscaled); + // Global shared memory invalidation callback for invalidating scaled resolved + // texture data. + static void ScaledResolveGlobalWatchCallbackThunk( + const std::unique_lock& global_lock, void* context, + uint32_t address_first, uint32_t address_last, bool invalidated_by_gpu); + void ScaledResolveGlobalWatchCallback(const std::unique_lock& global_lock, + uint32_t address_first, uint32_t address_last, + bool invalidated_by_gpu); + + const RegisterFile& register_file_; + SharedMemory& shared_memory_; + uint32_t draw_resolution_scale_x_; + uint32_t draw_resolution_scale_y_; + + static const LoadShaderInfo load_shader_info_[kLoadShaderCount]; + + rex::thread::global_critical_region global_critical_region_; + // Bit vector storing whether each 4 KB physical memory page contains scaled + // resolve data. uint32_t rather than uint64_t because parts of it can be sent + // to shaders. + std::unique_ptr scaled_resolve_pages_; + // Second level of the bit vector for faster rejection of non-scaled textures. + // >> 12 for 4 KB pages, >> 5 for uint32_t level 1 bits, >> 6 for uint64_t + // level 2 bits. + uint64_t scaled_resolve_pages_l2_[SharedMemory::kBufferSize >> (12 + 5 + 6)]; + + // Global watch for scaled resolve data invalidation. + SharedMemory::GlobalWatchHandle scaled_resolve_global_watch_handle_ = nullptr; + + uint64_t current_submission_index_ = 0; + uint64_t current_submission_time_ = 0; + + std::unordered_map, TextureKey::Hasher> textures_; + + uint64_t textures_total_host_memory_usage_ = 0; + + Texture* texture_used_first_ = nullptr; + Texture* texture_used_last_ = nullptr; + + // Whether a texture has become outdated (a memory watch has been triggered), + // so need to recheck if textures aren't outdated, disregarding whether fetch + // constants have been changed. + std::atomic texture_became_outdated_{false}; + + std::array texture_bindings_; + // Bit vector with bits reset on fetch constant writes to avoid parsing fetch + // constants again and again. + uint32_t texture_bindings_in_sync_ = 0; +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/pipeline/texture/conversion.h b/include/rex/graphics/pipeline/texture/conversion.h new file mode 100644 index 0000000..1dfcb42 --- /dev/null +++ b/include/rex/graphics/pipeline/texture/conversion.h @@ -0,0 +1,45 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include +#include + +namespace rex::graphics::texture_conversion { + +typedef std::function CopyBlockCallback; + +void CopySwapBlock(xenos::Endian endian, void* output, const void* input, size_t length); +void ConvertTexelCTX1ToR8G8(xenos::Endian endian, void* output, const void* input, size_t length); +void ConvertTexelDXT3AToDXT3(xenos::Endian endian, void* output, const void* input, size_t length); + +typedef std::function UntileCopyBlockCallback; + +typedef struct UntileInfo { + uint32_t offset_x; + uint32_t offset_y; + uint32_t width; + uint32_t height; + uint32_t input_pitch; + uint32_t output_pitch; + const FormatInfo* input_format_info; + const FormatInfo* output_format_info; + UntileCopyBlockCallback copy_callback; +} UntileInfo; + +void Untile(uint8_t* output_buffer, const uint8_t* input_buffer, const UntileInfo* untile_info); + +} // namespace rex::graphics::texture_conversion diff --git a/include/rex/graphics/pipeline/texture/info.h b/include/rex/graphics/pipeline/texture/info.h new file mode 100644 index 0000000..b7f66e2 --- /dev/null +++ b/include/rex/graphics/pipeline/texture/info.h @@ -0,0 +1,219 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +#include +#include + +namespace rex::graphics { + +inline xenos::TextureFormat GetBaseFormat(xenos::TextureFormat texture_format) { + // These formats are used for resampling textures / gamma control. + switch (texture_format) { + case xenos::TextureFormat::k_16_EXPAND: + return xenos::TextureFormat::k_16_FLOAT; + case xenos::TextureFormat::k_16_16_EXPAND: + return xenos::TextureFormat::k_16_16_FLOAT; + case xenos::TextureFormat::k_16_16_16_16_EXPAND: + return xenos::TextureFormat::k_16_16_16_16_FLOAT; + case xenos::TextureFormat::k_8_8_8_8_AS_16_16_16_16: + return xenos::TextureFormat::k_8_8_8_8; + case xenos::TextureFormat::k_DXT1_AS_16_16_16_16: + return xenos::TextureFormat::k_DXT1; + case xenos::TextureFormat::k_DXT2_3_AS_16_16_16_16: + return xenos::TextureFormat::k_DXT2_3; + case xenos::TextureFormat::k_DXT4_5_AS_16_16_16_16: + return xenos::TextureFormat::k_DXT4_5; + case xenos::TextureFormat::k_2_10_10_10_AS_16_16_16_16: + return xenos::TextureFormat::k_2_10_10_10; + case xenos::TextureFormat::k_10_11_11_AS_16_16_16_16: + return xenos::TextureFormat::k_10_11_11; + case xenos::TextureFormat::k_11_11_10_AS_16_16_16_16: + return xenos::TextureFormat::k_11_11_10; + case xenos::TextureFormat::k_8_8_8_8_GAMMA_EDRAM: + return xenos::TextureFormat::k_8_8_8_8; + default: + break; + } + + return texture_format; +} + +inline size_t GetTexelSize(xenos::TextureFormat format) { + switch (format) { + case xenos::TextureFormat::k_1_5_5_5: + return 2; + case xenos::TextureFormat::k_2_10_10_10: + return 4; + case xenos::TextureFormat::k_4_4_4_4: + return 2; + case xenos::TextureFormat::k_5_6_5: + return 2; + case xenos::TextureFormat::k_8: + return 1; + case xenos::TextureFormat::k_8_8: + return 2; + case xenos::TextureFormat::k_8_8_8_8: + return 4; + case xenos::TextureFormat::k_16: + return 4; + case xenos::TextureFormat::k_16_FLOAT: + return 4; + case xenos::TextureFormat::k_16_16: + return 4; + case xenos::TextureFormat::k_16_16_FLOAT: + return 4; + case xenos::TextureFormat::k_16_16_16_16: + return 8; + case xenos::TextureFormat::k_16_16_16_16_FLOAT: + return 8; + case xenos::TextureFormat::k_32_FLOAT: + return 4; + case xenos::TextureFormat::k_32_32_FLOAT: + return 8; + case xenos::TextureFormat::k_32_32_32_32_FLOAT: + return 16; + case xenos::TextureFormat::k_10_11_11: + case xenos::TextureFormat::k_11_11_10: + return 4; + default: + assert_unhandled_case(format); + return 0; + } +} + +inline xenos::TextureFormat ColorFormatToTextureFormat(xenos::ColorFormat color_format) { + return static_cast(color_format); +} + +inline xenos::TextureFormat DepthRenderTargetToTextureFormat( + xenos::DepthRenderTargetFormat depth_format) { + switch (depth_format) { + case xenos::DepthRenderTargetFormat::kD24S8: + return xenos::TextureFormat::k_24_8; + case xenos::DepthRenderTargetFormat::kD24FS8: + return xenos::TextureFormat::k_24_8_FLOAT; + default: + assert_unhandled_case(depth_format); + return xenos::TextureFormat(~0); + } +} + +enum class FormatType { + // Uncompressed, and is also a ColorFormat. + kResolvable, + // Uncompressed, but resolve or memory export cannot be done to the format. + kUncompressed, + kCompressed, +}; + +struct FormatInfo { + xenos::TextureFormat format; + const char* name; + FormatType type; + uint32_t block_width; + uint32_t block_height; + uint32_t bits_per_pixel; + + uint32_t bytes_per_block() const { return block_width * block_height * bits_per_pixel / 8; } + + static const FormatInfo* Get(uint32_t gpu_format); + + static const FormatInfo* Get(xenos::TextureFormat format) { + return Get(static_cast(format)); + } +}; + +struct TextureInfo; + +struct TextureExtent { + uint32_t pitch; // texel pitch + uint32_t height; // texel height + uint32_t block_width; // # of horizontal visible blocks + uint32_t block_height; // # of vertical visible blocks + uint32_t block_pitch_h; // # of horizontal pitch blocks + uint32_t block_pitch_v; // # of vertical pitch blocks + uint32_t depth; + + uint32_t all_blocks() const { return block_pitch_h * block_pitch_v * depth; } + uint32_t visible_blocks() const { return block_pitch_h * block_height * depth; } + + static TextureExtent Calculate(const FormatInfo* format_info, uint32_t pitch, uint32_t height, + uint32_t depth, bool is_tiled, bool is_guest); + static TextureExtent Calculate(const TextureInfo* texture_info, bool is_guest); +}; + +struct TextureMemoryInfo { + uint32_t base_address; + uint32_t base_size; + uint32_t mip_address; + uint32_t mip_size; +}; + +struct TextureInfo { + xenos::TextureFormat format; + xenos::Endian endianness; + + xenos::DataDimension dimension; + uint32_t width; // width in pixels + uint32_t height; // height in pixels + uint32_t depth; // depth in layers + uint32_t pitch; // pitch in blocks + uint32_t mip_min_level; + uint32_t mip_max_level; + bool is_stacked; + bool is_tiled; + bool has_packed_mips; + + TextureMemoryInfo memory; + TextureExtent extent; + + const FormatInfo* format_info() const { return FormatInfo::Get(static_cast(format)); } + + bool is_compressed() const { return format_info()->type == FormatType::kCompressed; } + + uint32_t mip_levels() const { return 1 + (mip_max_level - mip_min_level); } + + static bool Prepare(const xenos::xe_gpu_texture_fetch_t& fetch, TextureInfo* out_info); + + static bool PrepareResolve(uint32_t physical_address, xenos::TextureFormat texture_format, + xenos::Endian endian, uint32_t pitch, uint32_t width, uint32_t height, + uint32_t depth, TextureInfo* out_info); + + uint32_t GetMaxMipLevels() const; + + const TextureExtent GetMipExtent(uint32_t mip, bool is_guest) const; + + void GetMipSize(uint32_t mip, uint32_t* width, uint32_t* height) const; + + // Get the memory location of a mip. offset_x and offset_y are in blocks. + uint32_t GetMipLocation(uint32_t mip, uint32_t* offset_x, uint32_t* offset_y, + bool is_guest) const; + + static bool GetPackedTileOffset(uint32_t width, uint32_t height, const FormatInfo* format_info, + int packed_tile, uint32_t* offset_x, uint32_t* offset_y); + + bool GetPackedTileOffset(int packed_tile, uint32_t* offset_x, uint32_t* offset_y) const; + + uint64_t hash() const; + bool operator==(const TextureInfo& other) const { + return std::memcmp(this, &other, sizeof(TextureInfo)) == 0; + } + + private: + void SetupMemoryInfo(uint32_t base_address, uint32_t mip_address); +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/pipeline/texture/util.h b/include/rex/graphics/pipeline/texture/util.h new file mode 100644 index 0000000..2c9fad6 --- /dev/null +++ b/include/rex/graphics/pipeline/texture/util.h @@ -0,0 +1,332 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include + +namespace rex::graphics::texture_util { + +// This namespace replaces texture_extent and most of texture_info for +// simplicity. + +// Extracts the size from the fetch constant, and also cleans up addresses and +// mip range based on real presence of the base level and mips. Returns 6 faces +// for cube textures. +void GetSubresourcesFromFetchConstant(const xenos::xe_gpu_texture_fetch_t& fetch, + uint32_t* width_minus_1_out, uint32_t* height_minus_1_out, + uint32_t* depth_or_array_size_minus_1_out, + uint32_t* base_page_out, uint32_t* mip_page_out, + uint32_t* mip_min_level_out, uint32_t* mip_max_level_out); + +// Gets the number of the mipmap level where the packed mips are stored. +inline uint32_t GetPackedMipLevel(uint32_t width, uint32_t height) { + uint32_t log2_size = rex::log2_ceil(std::min(width, height)); + return log2_size > 4 ? log2_size - 4 : 0; +} + +// Gets the offset of the mipmap within the tail in blocks, or zeros (and +// returns false) if the mip level is not packed. Width, height and depth are in +// texels. For non-3D textures, set depth to 1. +// The offset is always within the dimensions of the image rounded to 32. +bool GetPackedMipOffset(uint32_t width, uint32_t height, uint32_t depth, + xenos::TextureFormat format, uint32_t mip, uint32_t& x_blocks, + uint32_t& y_blocks, uint32_t& z_blocks); + +// Both tiled and linear textures, as it appears from Direct3D 9 texture +// alignment disassembly (where the parameter indicating whether the texture is +// tiled only has effect on aligning the width to max(256 / block size, 32) +// rather than 32), are stored as tiles of 32x1x1 (for 1D), 32x32x1 (for 2D), or +// 32x32x4 (for 3D) texels (or compression blocks for compressed textures) for +// the purpose of calculation of the distance between subresources like array +// slices, and between depth slices (especially for linear textures). +// +// Textures have the base level (level 0) stored under their base_address, and +// mip levels (starting from 1) stored under their mip_address. There are +// differences in how texture data is stored under base_address and mip_address: +// - The base level uses the row pitch (specified in texels divided by 32 - thus +// implies 32-block alignment for both uncompressed and compressed textures) +// stored in the fetch constant, and height aligned to 32 blocks for Z slice +// and array layer stride calculation purposes. The pitch can be different +// from the actual width - an example is 584109FF, using 1408 pitch for a +// 1280x menu background). +// - The mip levels use `max(next_pow2(width or height in texels) >> level, 1)` +// aligned to 32 blocks for the same purpose, likely disregarding the pitch +// from the fetch constant. +// +// There is also mip tail packing if the fetch constant specifies that packed +// mips are enabled, for both tiled and linear textures (545407E0 uses linear +// DXT-compressed textures with packed mips very extensively for the game world +// materials). In this case, mips with width or height of 16 or smaller are +// stored not individually, but instead, in 32-texel (note: not 32-block - mip +// tail calculations are done with texel units; but 32-block padding can only be +// bigger than 32-texel padding for compressed textures) padding of the last +// level before the packed one. +// +// Note that the mip tail can be used both for the base level and mips (1...) if +// the entire texture has width or height of 16 or smaller. Therefore, both the +// base and the mips would be loaded from a mip tail that would be stored like +// the level 0 of the texture. But, in this case, under base_address and +// mip_address there are two separate mip tails, and the former likely uses the +// pitch from the fetch constant and no power of two size rounding, while for +// the latter the strides are likely calculated like for usual mips. The same +// applies to 17...32 texture sizes, though in this case the base is not packed +// tail, but the mips are still packed within an image that's stored like the +// level 0 of the texture. So, "storage level 0" is an ambiguous concept - host +// texture loading code should distinguish between "base level 0" and "mip tail +// for the mips 1... stored like level 0" and load the actual host level 0 from +// base_address, with all the base addressing properties, and host levels 1... +// from mip_address, with all the mips addressing properties. The base level +// being packed is evident from the function that tiles textures in game +// disassembly, which only checks the flag whether the data is packed passed to +// it, not the level, to see if it needs to calculate the offset in the mip +// tail, and the offset calculation function doesn't have level == 0 checks in +// it, only early-out if level < packed tail level (which can be 0). There are +// examples of textures with packed base, for example, in the intro level of +// 545407E0 (8x8 linear DXT1 - pairs of orange lights in the bottom of gambling +// machines). +// +// Linear texture rows are aligned to 256 bytes, for both the base and the mips +// (for the base, Direct3D 9 writes an already 256-byte-aligned pitch to the +// fetch constant). +// +// However, all the 32x32x4 padding, being just padding, is not necessarily +// being actually accessed, especially for linear textures. 4E4D083E has a +// 1280x720 k_8_8_8_8 linear texture, and allocates memory for exactly 1280x720, +// so aligning the height to 32 to 1280x736 results in access violations. So, +// while for stride calculations all the padding must be respected, for actual +// memory loads it's better to avoid trying to access it when possible: +// - If the pitch is bigger than the width, it's better to calculate the last +// row's length from the width rather than the pitch (this also possibly works +// in the other direction though - pitch < width is a weird situation, but +// probably legal, and may lead to reading data from beyond the calculated +// subresource stride). +// - For linear textures (like that 1280x720 example from 4E4D083E), it's easy +// to calculate the exact memory extent that may be accessed knowing the +// dimensions (unlike for tiled textures with complex addressing within +// 32x32x4-block tiles), so there's no need to align them to 32x32x4 for +// memory extent calculation. +// - For the linear packed mip tail, the extent can be calculated as max of +// (block offsets + block extents) of all levels stored in it. +// +// 1D textures are always linear and likely can't have packed mips (for `width > +// height` textures, mip offset calculation may result in packing along Y). +// +// Array slices are stored within levels (this is different than how Direct3D +// 10+ builds subresource indices, for instance). Each array slice or level is +// aligned to 4 KB (but this doesn't apply to 3D texture slices within one +// level). + +struct TextureGuestLayout { + struct Level { + // Distance between each row of blocks in bytes, including all the needed + // power of two (for mips) and 256-byte (for linear textures) alignment. + uint32_t row_pitch_bytes; + // Distance between Z slices in block rows, aligned to power of two for + // mips, and to tile height. + uint32_t z_slice_stride_block_rows; + // Distance between each array slice within the level in bytes, aligned to + // kTextureSubresourceAlignmentBytes. The distance to the next level is this + // multiplied by the array slice count. + uint32_t array_slice_stride_bytes; + + // The exclusive upper bound of blocks needed at this level (this level for + // non-packed levels, or all the packed levels for the packed mip tail). + uint32_t x_extent_blocks; + uint32_t y_extent_blocks; + uint32_t z_extent; + // Estimated amount of memory this level occupies. Not aligned to + // kTextureSubresourceAlignmentBytes. For tiled textures, this will be + // calculated for the extent rounded to 32x32x4 blocks (or 32x32x1 depending + // on the dimensionality), but for linear textures, as well as for mips of + // non-power-of-two tiled textures, this may be significantly (including + // less 4 KB pages) smaller than the aligned size (like for 4E4D083E where + // aligning the height of a 1280x720 linear texture results in access + // violations). For the linear mip tail, this includes all the mip levels + // stored in it. If the width is bigger than the pitch, this will also be + // taken into account for the last row so all memory actually used by the + // texture will be loaded, and may be bigger than the distance between array + // slices or levels. The purpose of this parameter is to make the memory + // amount that needs to be resident as close to the real amount as possible, + // to make sure all the needed data will be read, but also, if possible, + // unneeded memory pages won't be accessed (since that may trigger an access + // violation on the CPU). + uint32_t array_slice_data_extent_bytes; + // Including all array slices. + uint32_t level_data_extent_bytes; + }; + + Level base; + // If mip_max_level specified at calculation time is at least 1, the stored + // mips are min(1, packed_mip_level) through min(mip_max_level, + // packed_mip_level). + Level mips[xenos::kTextureMaxMips]; + uint32_t mip_offsets_bytes[xenos::kTextureMaxMips]; + uint32_t mips_total_extent_bytes; + uint32_t max_level; + // UINT32_MAX if there's no packed mip tail. + uint32_t packed_level; + uint32_t array_size; +}; + +TextureGuestLayout GetGuestTextureLayout(xenos::DataDimension dimension, + uint32_t base_pitch_texels_div_32, uint32_t width_texels, + uint32_t height_texels, uint32_t depth_or_array_size, + bool is_tiled, xenos::TextureFormat format, + bool has_packed_levels, bool has_base, uint32_t max_level); + +// Returns the total size of memory the texture uses starting from its base and +// mip addresses, in bytes (both are optional). +void GetTextureTotalSize(xenos::DataDimension dimension, uint32_t base_pitch_texels_div_32, + uint32_t width_texels, uint32_t height_texels, + uint32_t depth_or_array_size, bool is_tiled, xenos::TextureFormat format, + uint32_t mip_max_level, bool has_packed_mips, uint32_t* base_size_out, + uint32_t* mip_size_out); + +// Notes about tiled addresses: +// - The tiled address calculation functions work for both positive and negative +// offsets, so they can be used to go both from the origin of the texture to a +// region inside it and back (as long as the coordinates are a multiple of the +// period of the tiled address function in each direction - depends on whether +// the texture is 2D or 3D, and on the number of bytes per block). This is, in +// particular, used by Direct3D 9 inside resolving to allow resolving with an +// offset in the texture, so the rectangle coordinates are relative to both +// the render target and the region (with the appropriate alignment) in the +// texture at the same time. +// - 2D: +// - Origins of 32x32-block tiles grow monotonically as Y/32 (in blocks) +// increases, and in each tile row, as X/32 (in blocks) increases. +// - In each 32x32 tile, the block at (0, 0) within the tile has the address +// that matches the origin of the tile itself. This is not true for the +// block (31, 31), however - its address will be somewhere within the memory +// extent of the tile. +// - 1bpb: +// - The tiled address sequence repeats every 128 blocks along X or Y. +// - 32x32 tiles have their origins 0x200-bytes-aligned, and the addresses +// of the blocks within a 32x32 tile span 0xA00 bytes. +// - Note that 32x32x1bpb is 0x400 bytes, but addresses of blocks within a +// tile span the range of 0xA00 bytes - so 32x32 tiles are stored in +// memory ranges that may overlap (even across 128x128 - with the pitch of +// 192 blocks, the tile at (96, 32)...(127, 63) spans 0x2200...0x2BFF, +// while the tile at (128, 32)...(159, 63) spans 0x2400...0x2DFF. +// - All blocks within a 32x32 tile are located in the same 4KB-aligned +// region. +// - 2bpb: +// - The approach to storage is conceptually similar to that of 1bpb, with +// some quantitative differences. +// - The tiled address sequence repeats every 64 blocks along X or Y. +// - 32x32 tiles have their origins 0x400-bytes-aligned, and the addresses +// of the blocks within a 32x32 tile span 0xC00 bytes. +// - 4bpb and larger: +// - 32x32 tiles (which themselves are 4 KB or larger in this case) are +// stored simply in a tile-row-major way, separately from each other in +// memory, with independent addressing within each tile. +// - 3D: +// - Origins of 32x32x4-block tiles grow monotonically as Z/4 increases, and +// in each 4-slice portion, as Y/32 (in blocks) increases, and in each tile +// row, as X/32 (in blocks) increases. +// - Along Z, addressing repeats every 8 slices. Along Y, addressing repeats +// every 32 blocks regardless of the number of bytes per block. +// - 32-block-row x 4-slice portions are stored in disjoint 4KB-aligned ranges +// in memory (thus every 4 slices are also stored in disjoint ranges). +// - Addresses within a 32x32x4-block tile span widely throughout the X pitch, +// with a lot of overlap between 32x32x4 tiles with different X. +// - 1bpb: +// - The tiled address sequence repeats every 64 blocks along X. +// - Origins of 32x32x4-block tiles within 32-block-row x 4-slice portions: +// - X = 0, 64, 128...: (X / 64) * 0x1000 +// - X = 32, 96, 160...: (X / 64) * 0x1000 + 0x400 +// - Or: ((X >> 6) << 12) | (((X >> 5) & 1) << 10) +// - Span of the addresses within a 32x32x4-block tile: +// - Pitch = 32, 96, 160...: (Pitch / 64) * 0x1000 + 0x1000 +// - Pitch = 64, 128, 192...: (Pitch / 64) * 0x1000 + 0xC00 +// - Or: ((Pitch >> 6) << 12) + 0xC00 + (((Pitch >> 5) & 1) << 10) +// - Or: ((Pitch >> 6) << 12) + 0xC00 + ((Pitch & (1 << 5)) << (10 - 5)) +// - 2bpb and larger: +// - The tiled address sequence repeats every 32 blocks along X. +// - Origins of 32x32x4-block tiles within 32-block-row x 4-slice portions: +// (X / 32) * 0x1000 * (BPB / 2) +// - Span of the addresses within a 32x32x4-block tile: +// ((Pitch / 32) * 0x1000 + 0x1000) * (BPB / 2) +// - Addressing of blocks that are contiguous along X (for tiling/untiling of +// larger portions at once): +// - 1bpb - each 8 blocks are laid out sequentially, odd 8 blocks = +// even 8 blocks + 64 bytes (two R32G32_UINT tiled accesses for one +// R32G32B32A32_UINT linear access). +// - 2bpb, 4bpb, 8bpb, 16bpb - each 16 bytes contain blocks laid out +// sequentially (can tile/untile in R32G32B32A32_UINT portions). +// - 2bpb - odd 8 blocks = even 8 blocks + 64 bytes. +// - 4bpb - odd 4 blocks = even 4 blocks + 32 bytes. +// - 8bpb - odd 2 blocks = even 2 blocks + 32 bytes. +// - 16bpb - odd block = even block + 32 bytes. +// - Resolve granularity for both offset and size is 8x8 pixels - see +// xenos::kResolveAlignmentPixels. So, multiple pixels can still be loaded and +// stored when resolving, taking the contiguous storage patterns described +// above into account. + +// bytes_per_block_log2 is log2_floor according to how Direct3D 9 calculates it, +// but k_32_32_32 textures are never tiled anyway likely. + +int32_t GetTiledOffset2D(int32_t x, int32_t y, uint32_t pitch, uint32_t bytes_per_block_log2); +int32_t GetTiledOffset3D(int32_t x, int32_t y, int32_t z, uint32_t pitch, uint32_t height, + uint32_t bytes_per_block_log2); +// Because (0, 0, 0) within each 32x32x4-block tile is stored in memory first, +// and the tiled address grows monotonically with Z/4, then Y/32, then X/32 +// blocks. +inline uint32_t GetTiledAddressLowerBound2D(uint32_t left, uint32_t top, uint32_t pitch, + uint32_t bytes_per_block_log2) { + return uint32_t(GetTiledOffset2D(int32_t(left & ~(xenos::kTextureTileWidthHeight - 1)), + int32_t(top & ~(xenos::kTextureTileWidthHeight - 1)), pitch, + bytes_per_block_log2)); +} +inline uint32_t GetTiledAddressLowerBound3D(uint32_t left, uint32_t top, uint32_t front, + uint32_t pitch, uint32_t height, + uint32_t bytes_per_block_log2) { + return uint32_t(GetTiledOffset3D(int32_t(left & ~(xenos::kTextureTileWidthHeight - 1)), + int32_t(top & ~(xenos::kTextureTileWidthHeight - 1)), + int32_t(front & ~(xenos::kTextureTileDepth)), pitch, height, + bytes_per_block_log2)); +} +// Supporting the right > pitch and bottom > height (in tiles) cases also, for +// estimation how far addresses can actually go even potentially beyond the +// subresource stride. +uint32_t GetTiledAddressUpperBound2D(uint32_t right, uint32_t bottom, uint32_t pitch, + uint32_t bytes_per_block_log2); +uint32_t GetTiledAddressUpperBound3D(uint32_t right, uint32_t bottom, uint32_t back, uint32_t pitch, + uint32_t height, uint32_t bytes_per_block_log2); + +// Returns four packed TextureSign values swizzled according to the swizzle in +// the fetch constant, so the shader can apply TextureSigns after reading a +// pre-swizzled texture. 0/1 elements are considered unsigned (and not biased), +// however, if all non-constant components are signed, 0/1 are considered signed +// too (because in backends, unsigned and signed textures may use separate host +// textures with different formats, so just one is used for both signed and +// constant components). +uint8_t SwizzleSigns(const xenos::xe_gpu_texture_fetch_t& fetch); +constexpr bool IsAnySignNotSigned(uint8_t packed_signs) { + return packed_signs != uint32_t(xenos::TextureSign::kSigned) * 0b01010101; +} +constexpr bool IsAnySignSigned(uint8_t packed_signs) { + // Make signed 00 - check if all are 01, 10 or 11. + uint32_t xor_signed = packed_signs ^ (uint32_t(xenos::TextureSign::kSigned) * 0b01010101); + return ((xor_signed | (xor_signed >> 1)) & 0b01010101) != 0b01010101; +} + +// Returns normalized clamp modes specified in the fetch constant based on the +// texture data dimension in it. +void GetClampModesForDimension(const xenos::xe_gpu_texture_fetch_t& fetch, + xenos::ClampMode& clamp_x_out, xenos::ClampMode& clamp_y_out, + xenos::ClampMode& clamp_z_out); + +} // namespace rex::graphics::texture_util diff --git a/include/rex/graphics/pipeline_util.h b/include/rex/graphics/pipeline_util.h new file mode 100644 index 0000000..65a24ed --- /dev/null +++ b/include/rex/graphics/pipeline_util.h @@ -0,0 +1,44 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2026 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +namespace rex::graphics::pipeline_util { + +// Priority levels for async pipeline compilation. +// Higher values are compiled sooner. +constexpr uint8_t kPriorityLowest = 0; // Writes to unbound RTs only. +constexpr uint8_t kPriorityDepthOnly = 1; // Depth-only writes. +constexpr uint8_t kPriorityVisibleRT = 2; // Writes to a visible RT. +constexpr uint8_t kPriorityRT0 = 3; // Writes to RT0. + +// Converts normalized_color_mask to a 4-bit bitmask of bound RTs. +// normalized_color_mask contains 4 bits per RT (RGBA). +inline uint32_t GetBoundRTMaskFromNormalizedColorMask(uint32_t normalized_color_mask) { + return (((normalized_color_mask >> 0) & 0xF) ? 1 : 0) | + (((normalized_color_mask >> 4) & 0xF) ? 2 : 0) | + (((normalized_color_mask >> 8) & 0xF) ? 4 : 0) | + (((normalized_color_mask >> 12) & 0xF) ? 8 : 0); +} + +// Calculates async compilation priority from shader outputs. +inline uint8_t CalculatePipelinePriority(uint32_t bound_rts, uint32_t shader_writes_color_targets, + bool shader_writes_depth) { + uint32_t visible_writes = bound_rts & shader_writes_color_targets; + if (visible_writes) { + return (visible_writes & 1) ? kPriorityRT0 : kPriorityVisibleRT; + } + if (shader_writes_depth) { + return kPriorityDepthOnly; + } + return kPriorityLowest; +} + +} // namespace rex::graphics::pipeline_util diff --git a/include/rex/graphics/primitive_processor.h b/include/rex/graphics/primitive_processor.h new file mode 100644 index 0000000..eed9e1b --- /dev/null +++ b/include/rex/graphics/primitive_processor.h @@ -0,0 +1,836 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if REX_ARCH_AMD64 +// 128-bit SSSE3-level (SSE2+ for integer comparison, SSSE3 for pshufb) or AVX +// (256-bit AVX only got integer operations such as comparison in AVX2, which is +// above the minimum requirements of Xenia). +#include +#define XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE 16 +#elif REX_ARCH_ARM64 +#include +#define XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE 16 +#else +#define XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE 0 +#endif // XE_ARCH + +// The idea behind this config variable is to force both indirection without +// primitive reset and pre-masking / pre-swapping with primitive reset, +// therefore this is supposed to be checked only by the host if it supports +// indirection. It's pretty pointless to do only half of this on backends that +// support full 32-bit indices unconditionally. +REXCVAR_DECLARE(bool, ignore_32bit_vertex_index_support); + +namespace rex::graphics { + +// Normalizes primitive data in various ways for use with Direct3D 12 and Vulkan +// (down to its minimum requirements plus the portability subset). +// +// This solves various issues: +// - Triangle fans not supported on Direct3D 10+ and the Vulkan portability +// subset. +// - Converts to triangle lists, both with and without primitive reset. +// - Line loops are not supported on Direct3D 12 or Vulkan. +// - Converts to line strips. +// - Quads not reproducible with line lists with adjacency without geometry +// shaders (some Vulkan implementations), as well as being hard to debug in +// PIX due to "catastrophic failures". +// - Converts to triangle lists. +// - Vulkan requiring 0xFFFF primitive restart index for 16-bit indices and +// 0xFFFFFFFF for 32-bit (Direct3D 12 slightly relaxes this, allowing 0xFFFF +// for 32-bit also, but it's of no use to Xenia since guest indices are +// big-endian usually. Also, only 24 lower bits of the vertex index being used +// on the guest (tested on an Adreno 200 phone with drawing, though not with +// primitive restart as OpenGL ES 2.0 doesn't expose it), so the upper 8 bits +// likely shouldn't have effect on primitive restart (guest reset index +// 0xFFFFFF likely working for 0xFFFFFF, 0xFFFFFFFF, and 254 more indices), +// while Vulkan and Direct3D 12 require exactly 0xFFFFFFFF. +// - For 16-bit indices with guest reset index other than 0xFFFF (passing +// 0xFFFF directly to the host is fine because it's the same irrespective of +// endianness), there are two possible solutions: +// - If the index buffer otherwise doesn't contain 0xFFFF otherwise (since +// it's a valid vertex index in this case), replacing the primitive reset +// index with 0xFFFF in the 16-bit buffer. +// - If the index buffer contains any usage of 0xFFFF as a real vertex +// index, converting the index buffer to 32-bit, and replacing the +// primitive reset index with 0xFFFFFFFF. +// - For 32-bit indices, there are two paths: +// - If the guest reset index is 0xFFFFFF, and the index buffer actually +// uses only 0xFFFFFFFF for reset, using it without changes. +// - If the guest uses something other than 0xFFFFFFFF for primitive reset, +// replacing elements with (index & 0xFFFFFF) == reset_index with +// 0xFFFFFFFF. +// - Some Vulkan implementations only support 24-bit indices. The guests usually +// pass big-endian vertices, so we need all 32 bits (as the least significant +// bits will be in 24...31) to perform the byte swapping. For this reason, we +// load 32-bit indices indirectly, doing non-indexed draws and fetching the +// indices from the shared memory. This, however, is not compatible with +// primitive restart. +// - Pre-swapping, masking to 24 bits, and converting the reset index to +// 0xFFFFFFFF, resulting in an index buffer that can be used directly. + +class PrimitiveProcessor { + public: + enum ProcessedIndexBufferType { + // Auto-indexed on the host. + kNone, + // GPU DMA, from the shared memory. + // For 32-bit, indirection is needed if the host only supports 24-bit + // indices (even for non-endian-swapped, as the GPU should be ignoring the + // upper 8 bits completely, rather than exhibiting undefined behavior. + kGuestDMA, + // Converted and stored in the primitive converter for the current draw + // command. For 32-bit indices, if the host doesn't support all 32 bits, + // this kind of an index buffer will always be pre-masked and pre-swapped. + kHostConverted, + // Auto-indexed on the guest, but with an adapter index buffer on the host. + kHostBuiltinForAuto, + // Adapter index buffer on the host for indirect loading of indices via DMA + // (from the shared memory). + kHostBuiltinForDMA, + }; + + struct ProcessingResult { + xenos::PrimitiveType guest_primitive_type; + xenos::PrimitiveType host_primitive_type; + // Includes whether tessellation is enabled (not kVertex) and the type of + // tessellation. + Shader::HostVertexShaderType host_vertex_shader_type; + // Only used for non-kVertex host_vertex_shader_type. For kAdaptive, the + // index buffer is always from the guest and fully 32-bit, and contains the + // floating-point tessellation factors. + xenos::TessellationMode tessellation_mode; + // TODO(Triang3l): If important, split into the index count and the actual + // index buffer size, using zeros for out-of-bounds indices. + uint32_t guest_draw_vertex_count; + uint32_t host_draw_vertex_count; + uint32_t line_loop_closing_index; + ProcessedIndexBufferType index_buffer_type; + uint32_t guest_index_base; + xenos::IndexFormat host_index_format; + xenos::Endian host_shader_index_endian; + // The reset index, if enabled, is always 0xFFFF for host_index_format + // kInt16 and 0xFFFFFFFF for kInt32. Never enabled for "list" primitive + // types, thus safe for direct usage on Vulkan. + bool host_primitive_reset_enabled; + // Backend-specific handle for the index buffer valid for the current draw, + // only valid for index_buffer_type kHostConverted, kHostBuiltinForAuto and + // kHostBuiltinForDMA. + size_t host_index_buffer_handle; + bool IsTessellated() const { + return Shader::IsHostVertexShaderTypeDomain(host_vertex_shader_type); + } + }; + + virtual ~PrimitiveProcessor(); + + bool AreFull32BitVertexIndicesUsed() const { return full_32bit_vertex_indices_used_; } + bool IsConvertingTriangleFansToLists() const { return convert_triangle_fans_to_lists_; } + bool IsConvertingLineLoopsToStrips() const { return convert_line_loops_to_strips_; } + // Quad lists may be emulated as line lists with adjacency and a geometry + // shader, but geometry shaders must be supported for this. + bool IsConvertingQuadListsToTriangleLists() const { + return convert_quad_lists_to_triangle_lists_; + } + bool IsExpandingPointSpritesInVS() const { return expand_point_sprites_in_vs_; } + bool IsExpandingRectangleListsInVS() const { return expand_rectangle_lists_in_vs_; } + + // Submission must be open to call (may request the index buffer in the shared + // memory). + bool Process(ProcessingResult& result_out); + + // Invalidates the cache within the range. + std::pair MemoryInvalidationCallback(uint32_t physical_address_start, + uint32_t length, bool exact_range); + + protected: + // For host-side index buffer creation, the biggest possibly needed contiguous + // allocation, in indices. + // - No conversion: up to 0xFFFF vertices (as the vertex count in + // VGT_DRAW_INITIATOR is 16-bit). + // - Triangle fans to lists: since the 3rd vertex, every guest vertex creates + // a triangle, thus the maximum is 3 * (UINT16_MAX - 2), or 0x2FFF7. + // Primitive reset can only slow down the amplification - the 3 vertices + // after a reset add 1 host vertex each, not 3 each. + // - Line loops to strips: adding 1 vertex if there are at least 2 vertices in + // the original primitive, either replacing the primitive reset index with + // this new closing vertex, or in case of the final primitive, just adding a + // vertex - thus the absolute limit is UINT16_MAX + 1, or 0x10000. + // - Quad lists to triangle lists: vertices are processed in groups of 4, each + // group converted to 6 vertices, so the limit is 1.5 * 0xFFFC, or 0x17FFA. + // Thus, the maximum vertex count is defined by triangle fan to list + // conversion. + // Also include padding for co-alignment of the source and the destination for + // SIMD. + static constexpr uint32_t kMinRequiredConvertedIndexBufferSize = + sizeof(uint32_t) * (UINT16_MAX - 2) * 3 * +XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE; + + PrimitiveProcessor(const RegisterFile& register_file, memory::Memory& memory, + TraceWriter& trace_writer, SharedMemory& shared_memory) + : register_file_(register_file), + memory_(memory), + trace_writer_(trace_writer), + shared_memory_(shared_memory) {} + + // Call from the backend-specific initialization function. + // - full_32bit_vertex_indices_supported: + // - If the backend supports 32-bit indices unconditionally, and doesn't + // generate indirection logic in vertex shaders, pass hard-coded `true`. + // - Otherwise: + // - If the host doesn't support full 32-bit indices (but supports at + // least 24-bit indices), pass `false`. + // - If the host supports 32-bit indices, but the backend can handle both + // cases, pass `REXCVAR_GET(ignore_32bit_vertex_index_support)`, and + // afterwards, check `AreFull32BitVertexIndicesUsed()` externally to see + // if indirection may be needed. + // - When full 32-bit indices are not supported, the host must be using + // auto-indexed draws for 32-bit indices of ProcessedIndexBufferType + // kGuestDMA, while fetching the index data manually from the shared + // memory buffer and endian-swapping it. + // - Indirection, however, precludes primitive reset usage - so if + // primitive reset is needed, the primitive processor will pre-swap and + // pre-mask the index buffer so there are only host-endian 0x00###### or + // 0xFFFFFFFF values in it. In this case, a kHostConverted index buffer + // is returned from Process, and indirection is not needed (and + // impossible since the index buffer is not in the shared memory buffer + // anymore), though byte swap is still needed as 16-bit indices may also + // be kHostConverted, while they are completely unaffected by this. The + // same applies to primitive type conversion - if it happens for 32-bit + // guest indices, and kHostConverted is returned, they will be + // pre-swapped and pre-masked. + // - triangle_fans_supported, line_loops_supported, quad_lists_supported: + // - Pass true or false depending on whether the host actually supports + // those guest primitive types directly or through geometry shader + // emulation. Debug overriding will be resolved in the common code if + // needed. + // - point_sprites_supported_without_vs_expansion, + // rectangle_lists_supported_without_vs_expansion: + // - Pass true or false depending on whether the host actually supports + // those guest primitive types directly or through geometry shader + // emulation. Overrides do not apply to these as hosts are not required to + // support the fallback paths since they require different vertex shader + // structure (for the fallback HostVertexShaderTypes). + bool InitializeCommon(bool full_32bit_vertex_indices_supported, bool triangle_fans_supported, + bool line_loops_supported, bool quad_lists_supported, + bool point_sprites_supported_without_vs_expansion, + bool rectangle_lists_supported_without_vs_expansion); + // If any primitive type conversion is needed for auto-indexed draws, called + // from InitializeCommon (thus only once in the primitive processor's + // lifetime) to set up the backend's index buffer containing indices for + // primitive type remapping. The backend must allocate a 4-byte-aligned buffer + // with `size_bytes` and call fill_callback for its mapping if creation has + // been successful. + virtual bool InitializeBuiltinIndexBuffer(size_t size_bytes, + std::function fill_callback) = 0; + // Call last in implementation-specific shutdown, also callable from the + // destructor. + void ShutdownCommon(); + + // Call at boundaries of lifespans of converted data (between frames, + // preferably in the end of a frame so between the swap and the next draw, + // access violation handlers need to do less work). + void ClearPerFrameCache(); + + static constexpr size_t GetBuiltinIndexBufferOffsetBytes(size_t handle) { + // For simplicity, just using the handles as byte offsets. + return handle; + } + + // The destination allocation must have XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE + // excess bytes. + static ptrdiff_t GetSimdCoalignmentOffset(const void* host_index_ptr, uint32_t guest_index_base) { +#if XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE + // Always moving the host pointer only forward into the allocation padding + // space of XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE bytes. Without relying on + // two's complement wrapping overflow behavior, the logic would look like: + // uintptr_t host_subalignment = + // reinterpret_cast(host_index_ptr) & + // (XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE - 1); + // uint32_t guest_subalignment = guest_index_base & + // (XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE - 1); + // uintptr_t host_index_address_aligned = host_index_address; + // if (guest_subalignment >= host_subalignment) { + // return guest_subalignment - host_subalignment; + // } + // return XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE - + // (host_subalignment - guest_subalignment); + return ptrdiff_t((guest_index_base - reinterpret_cast(host_index_ptr)) & + (XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE - 1)); +#else + return 0; +#endif + } + + // Requests a buffer to write the new transformed indices to. The lifetime of + // the returned buffer must be that of the current frame. Returns the mapping + // of the buffer to write to, or nullptr in case of failure, in addition to, + // if successful, a handle that can be used by the backend's command processor + // to access the backend-specific data for binding the buffer. + virtual void* RequestHostConvertedIndexBufferForCurrentFrame( + xenos::IndexFormat format, uint32_t index_count, bool coalign_for_simd, + uint32_t coalignment_original_address, size_t& backend_handle_out) = 0; + + private: +#if XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE +#if REX_ARCH_AMD64 + // SSSE3 or AVX. + using SimdVectorU16 = __m128i; + using SimdVectorU32 = __m128i; + static SimdVectorU16 ReplicateU16(uint16_t value) { return _mm_set1_epi16(int16_t(value)); } + static SimdVectorU32 ReplicateU32(uint32_t value) { return _mm_set1_epi32(int32_t(value)); } + static SimdVectorU16 LoadAlignedVectorU16(const uint16_t* source) { + return _mm_load_si128(reinterpret_cast(source)); + } + static SimdVectorU32 LoadAlignedVectorU32(const uint32_t* source) { + return _mm_load_si128(reinterpret_cast(source)); + } + static void StoreUnalignedVectorU16(uint16_t* dest, SimdVectorU16 source) { + _mm_storeu_si128(reinterpret_cast<__m128i*>(dest), source); + } + static void StoreUnalignedVectorU32(uint32_t* dest, SimdVectorU32 source) { + _mm_storeu_si128(reinterpret_cast<__m128i*>(dest), source); + } +#elif REX_ARCH_ARM64 + // NEON. + using SimdVectorU16 = uint16x8_t; + using SimdVectorU32 = uint32x4_t; + static SimdVectorU16 ReplicateU16(uint16_t value) { return vdupq_n_u16(value); } + static SimdVectorU32 ReplicateU32(uint32_t value) { return vdupq_n_u32(value); } + static SimdVectorU16 LoadAlignedVectorU16(const uint16_t* source) { +#if REX_COMPILER_MSVC + return vld1q_u16_ex(source, sizeof(uint16x8_t) * CHAR_BIT); +#else + return vld1q_u16( + reinterpret_cast(__builtin_assume_aligned(source, sizeof(uint16x8_t)))); +#endif + } + static SimdVectorU32 LoadAlignedVectorU32(const uint32_t* source) { +#if REX_COMPILER_MSVC + return vld1q_u32_ex(source, sizeof(uint16x8_t) * CHAR_BIT); +#else + return vld1q_u32( + reinterpret_cast(__builtin_assume_aligned(source, sizeof(uint32x4_t)))); +#endif + } + static void StoreUnalignedVectorU16(uint16_t* dest, SimdVectorU16 source) { + vst1q_u16(dest, source); + } + static void StoreUnalignedVectorU32(uint32_t* dest, SimdVectorU32 source) { + vst1q_u32(dest, source); + } +#else +#error SIMD vector types and constant loads not specified. +#endif // XE_ARCH + static_assert(sizeof(SimdVectorU16) == XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE, + "XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE must reflect the vector size " + "actually used"); + static_assert(sizeof(SimdVectorU32) == XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE, + "XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE must reflect the vector size " + "actually used"); + static constexpr uint32_t kSimdVectorU16Elements = sizeof(SimdVectorU16) / sizeof(uint16_t); + static constexpr uint32_t kSimdVectorU32Elements = sizeof(SimdVectorU32) / sizeof(uint32_t); +#endif // XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE + + static bool IsResetUsed(const uint16_t* source, uint32_t count, + uint16_t reset_index_guest_endian); + static void Get16BitResetIndexUsage(const uint16_t* source, uint32_t count, + uint16_t reset_index_guest_endian, + bool& is_reset_index_used_out, + bool& is_ffff_used_as_vertex_index_out); + static bool IsResetUsed(const uint32_t* source, uint32_t count, uint32_t reset_index_guest_endian, + uint32_t low_bits_mask_guest_endian); + static void ReplaceResetIndex16To16(uint16_t* dest, const uint16_t* source, uint32_t count, + uint16_t reset_index_guest_endian); + // For use when the reset index is not 0xFFFF, and 0xFFFF is also used as a + // valid index - keeps 0xFFFF as a real index and replaces the reset index + // with 0xFFFFFFFF instead. + static void ReplaceResetIndex16To24(uint32_t* dest, const uint16_t* source, uint32_t count, + uint16_t reset_index_guest_endian); + // The reset index and the low 24 bits mask are taken explicitly because this + // function may be used two ways: + // - Passthrough - when the vertex shader swaps the indices (when 32-bit + // indices are supported on the host), in this case HostSwap is kNone, but + // the reset index and the guest low bits mask can be swapped according to + // the guest endian. + // - Swapping for the host - when only 24 bits of an index are supported on + // the host. In this case, masking and comparison are done before applying + // HostSwap, but according to HostSwap, if needed, the data is swapped from + // the PowerPC's big endianness to the host GPU little endianness that we + // assume, which matches the Xenos's little endianness. + template + static void ReplaceResetIndex32To24(uint32_t* dest, const uint32_t* source, uint32_t count, + uint32_t reset_index_guest_endian, + uint32_t low_bits_mask_guest_endian) { + // The Xbox 360's GPU only uses the low 24 bits of the index - masking. +#if XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE + while (count && + (reinterpret_cast(source) & (XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE - 1))) { + --count; + uint32_t index = *(source++) & low_bits_mask_guest_endian; + *(dest++) = index != reset_index_guest_endian ? xenos::GpuSwap(index, HostSwap) : UINT32_MAX; + } + if (count >= kSimdVectorU32Elements) { + SimdVectorU32 reset_index_guest_endian_simd = ReplicateU32(reset_index_guest_endian); + SimdVectorU32 low_bits_mask_guest_endian_simd = ReplicateU32(low_bits_mask_guest_endian); +#if REX_ARCH_AMD64 + __m128i host_swap_shuffle; + if constexpr (HostSwap != xenos::Endian::kNone) { + host_swap_shuffle = _mm_set_epi32(int32_t(xenos::GpuSwap(uint32_t(0x0F0E0D0C), HostSwap)), + int32_t(xenos::GpuSwap(uint32_t(0x0B0A0908), HostSwap)), + int32_t(xenos::GpuSwap(uint32_t(0x07060504), HostSwap)), + int32_t(xenos::GpuSwap(uint32_t(0x03020100), HostSwap))); + } +#endif // REX_ARCH_AMD64 + while (count >= kSimdVectorU32Elements) { + count -= kSimdVectorU32Elements; + // Comparison produces 0 or 0xFFFF on AVX and Neon - we need 0xFFFF as + // the result for the primitive reset indices, so the result is + // `index | (index == reset_index)`. + SimdVectorU32 source_simd = LoadAlignedVectorU32(source); + source += kSimdVectorU32Elements; + SimdVectorU32 result_simd; +#if REX_ARCH_AMD64 + source_simd = _mm_and_si128(source_simd, low_bits_mask_guest_endian_simd); + result_simd = + _mm_or_si128(source_simd, _mm_cmpeq_epi32(source_simd, reset_index_guest_endian_simd)); + if constexpr (HostSwap != xenos::Endian::kNone) { + result_simd = _mm_shuffle_epi8(result_simd, host_swap_shuffle); + } +#elif REX_ARCH_ARM64 + source_simd = vandq_u32(source_simd, low_bits_mask_guest_endian_simd); + result_simd = vorrq_u32(source_simd, vceqq_u32(source_simd, reset_index_guest_endian_simd)); + if constexpr (HostSwap == xenos::Endian::k8in16) { + result_simd = vreinterpretq_u32_u8(vrev16q_u8(vreinterpretq_u8_u32(result_simd))); + } else if constexpr (HostSwap == xenos::Endian::k8in32) { + result_simd = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(result_simd))); + } else if constexpr (HostSwap == xenos::Endian::k16in32) { + result_simd = vreinterpretq_u32_u16(vrev32q_u16(vreinterpretq_u16_u32(result_simd))); + } +#else +#error SIMD ReplaceResetIndex32To24 not implemented. +#endif // XE_ARCH + StoreUnalignedVectorU32(dest, result_simd); + dest += kSimdVectorU32Elements; + } + } +#endif // XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE + while (count--) { + uint32_t index = *(source++) & low_bits_mask_guest_endian; + *(dest++) = index != reset_index_guest_endian ? xenos::GpuSwap(index, HostSwap) : UINT32_MAX; + } + } + + // TODO(Triang3l): 16-bit > 32-bit primitive type conversion for Metal, where + // primitive reset is always enabled, if UINT16_MAX is used as a real vertex + // index. + + struct PassthroughIndexTransform { + uint16_t operator()(uint16_t index) const { return index; } + uint32_t operator()(uint32_t index) const { return index; } + }; + struct To24NonSwappingIndexTransform { + uint32_t operator()(uint32_t index) const { return index & xenos::kVertexIndexMask; } + }; + struct To24Swapping8In16IndexTransform { + uint32_t operator()(uint32_t index) const { + return xenos::GpuSwap(index, xenos::Endian::k8in16) & xenos::kVertexIndexMask; + } + }; + struct To24Swapping8In32IndexTransform { + uint32_t operator()(uint32_t index) const { + return xenos::GpuSwap(index, xenos::Endian::k8in32) & xenos::kVertexIndexMask; + } + }; + struct To24Swapping16In32IndexTransform { + uint32_t operator()(uint32_t index) const { + return xenos::GpuSwap(index, xenos::Endian::k16in32) & xenos::kVertexIndexMask; + } + }; + + static constexpr uint32_t GetTwoTriangleStripIndexCount(uint32_t strip_count) { + // 4 vertices per strip, and primitive restarts between strips. + return 4 * strip_count + (std::max(strip_count, UINT32_C(1)) - 1); + } + + // Triangle fan test cases: + // - 4D5307E6 - main menu - game logo, developer logo, backgrounds of the menu + // item list (the whole menu and individual items) - no index buffer. + // - 4E4D87E6 - terrain - with an index buffer and primitive reset (note that + // there, vfetch indices are computed in the vertex shader, involving + // floating-point reciprocal, so this case is very sensitive to rounding, + // and incorrect geometry may occur not because of vertex grouping issues, + // but also due to the behavior of the vertex shader). + // Triangle fans as triangle lists. + // Ordered as (v1, v2, v0), (v2, v3, v0) in Direct3D. + // https://docs.microsoft.com/en-us/windows/desktop/direct3d9/triangle-fans + static constexpr uint32_t GetTriangleFanListIndexCount(uint32_t fan_index_count) { + return fan_index_count > 2 ? (fan_index_count - 2) * 3 : 0; + } + template + static void TriangleFanToList(Index* dest, const Index* source, uint32_t source_index_count, + const IndexTransform& index_transform) { + if (source_index_count <= 2) { + // To match GetTriangleFanListIndexCount. + return; + } + Index index_first = index_transform(source[0]); + Index index_previous = index_transform(source[1]); + for (uint32_t i = 2; i < source_index_count; ++i) { + Index index_current = index_transform(source[i]); + *(dest++) = index_previous; + *(dest++) = index_current; + *(dest++) = index_first; + index_previous = index_current; + } + } + + static constexpr uint32_t GetLineLoopStripIndexCount(uint32_t loop_index_count) { + // Even if 2 vertices are supplied, two lines are still drawn between them. + // https://www.khronos.org/opengl/wiki/Primitive + // "You get n lines for n input vertices" + // "If the user only specifies 1 vertex, the drawing command is ignored" + return loop_index_count > 1 ? loop_index_count + 1 : 0; + } + template + static void LineLoopToStrip(Index* dest, const Index* source, uint32_t source_index_count, + const IndexTransform& index_transform) { + if (source_index_count <= 1) { + // To match GetLineLoopStripIndexCount. + return; + } + Index index_first = index_transform(source[0]); + dest[0] = index_first; + for (uint32_t i = 1; i < source_index_count; ++i) { + dest[i] = index_transform(source[i]); + } + dest[source_index_count] = index_first; + } + static void LineLoopToStrip(uint16_t* dest, const uint16_t* source, uint32_t source_index_count, + const PassthroughIndexTransform& index_transform); + static void LineLoopToStrip(uint32_t* dest, const uint32_t* source, uint32_t source_index_count, + const PassthroughIndexTransform& index_transform); + + // Quad list test cases: + // - 4D5307E6 - main menu - flying dust on the road - no index buffer. + static constexpr uint32_t GetQuadListTriangleListIndexCount(uint32_t quad_list_index_count) { + return (quad_list_index_count / 4) * 6; + } + template + static void QuadListToTriangleList(Index* dest, const Index* source, uint32_t source_index_count, + const IndexTransform& index_transform) { + uint32_t quad_count = source_index_count / 4; + for (uint32_t i = 0; i < quad_count; ++i) { + // TODO(Triang3l): Find the correct order. + // v0, v1, v2. + Index common_index_0 = index_transform(*(source++)); + *(dest++) = common_index_0; + *(dest++) = index_transform(*(source++)); + Index common_index_2 = index_transform(*(source++)); + *(dest++) = common_index_2; + // v0, v2, v3. + *(dest++) = common_index_0; + *(dest++) = common_index_2; + *(dest++) = index_transform(*(source++)); + } + } + + // Pre-gathering the ranges allows for usage of the same functions for + // conversion with and without reset. In addition, this increases safety in + // weird cases - there won't be mismatch between the pre-calculation of the + // post-conversion index count and the actual conversion if the game for some + // reason modifies the index buffer between the two and adds or removes reset + // indices in it. + struct SinglePrimitiveRange { + SinglePrimitiveRange(uint32_t guest_offset, uint32_t guest_index_count, + uint32_t host_index_count) + : guest_offset(guest_offset), + guest_index_count(guest_index_count), + host_index_count(host_index_count) {} + uint32_t guest_offset; + uint32_t guest_index_count; + uint32_t host_index_count; + }; + static uint32_t GetMultiPrimitiveHostIndexCountAndRanges( + std::function single_primitive_guest_to_host_count, + const uint16_t* source, uint32_t source_index_count, uint16_t reset_index_guest_endian, + std::deque& ranges_append_out); + static uint32_t GetMultiPrimitiveHostIndexCountAndRanges( + std::function single_primitive_guest_to_host_count, + const uint32_t* source, uint32_t source_index_count, uint32_t reset_index_guest_endian, + uint32_t low_bits_mask_guest_endian, std::deque& ranges_append_out); + + template + static void ConvertSinglePrimitiveRanges(Index* dest, const Index* source, + xenos::PrimitiveType source_primitive_type, + const IndexTransform& index_transform, + PrimitiveRangeIterator ranges_beginning, + PrimitiveRangeIterator ranges_end) { + Index* dest_write_ptr = dest; + switch (source_primitive_type) { + case xenos::PrimitiveType::kTriangleFan: + for (PrimitiveRangeIterator range_it = ranges_beginning; range_it != ranges_end; + ++range_it) { + TriangleFanToList(dest_write_ptr, source + range_it->guest_offset, + range_it->guest_index_count, index_transform); + dest_write_ptr += range_it->host_index_count; + } + break; + case xenos::PrimitiveType::kLineLoop: + for (PrimitiveRangeIterator range_it = ranges_beginning; range_it != ranges_end; + ++range_it) { + LineLoopToStrip(dest_write_ptr, source + range_it->guest_offset, + range_it->guest_index_count, index_transform); + dest_write_ptr += range_it->host_index_count; + } + break; + case xenos::PrimitiveType::kQuadList: + for (PrimitiveRangeIterator range_it = ranges_beginning; range_it != ranges_end; + ++range_it) { + QuadListToTriangleList(dest_write_ptr, source + range_it->guest_offset, + range_it->guest_index_count, index_transform); + dest_write_ptr += range_it->host_index_count; + } + break; + default: + assert_unhandled_case(source_primitive_type); + } + } + + const RegisterFile& register_file_; + memory::Memory& memory_; + TraceWriter& trace_writer_; + SharedMemory& shared_memory_; + + bool full_32bit_vertex_indices_used_ = false; + bool convert_triangle_fans_to_lists_ = false; + bool convert_line_loops_to_strips_ = false; + bool convert_quad_lists_to_triangle_lists_ = false; + bool expand_point_sprites_in_vs_ = false; + bool expand_rectangle_lists_in_vs_ = false; + + // Byte offsets used, for simplicity, directly as handles. + size_t builtin_ib_offset_two_triangle_strips_ = SIZE_MAX; + size_t builtin_ib_offset_triangle_fans_to_lists_ = SIZE_MAX; + size_t builtin_ib_offset_quad_lists_to_triangle_lists_ = SIZE_MAX; + + std::deque single_primitive_ranges_; + + // Caching for reuse of converted indices within a frame. + + // 256 KB as the largest possible guest index buffer - 0xFFFF 32-bit indices - + // is slightly smaller than 256 KB, thus cache entries need store links within + // at most 2 buckets. + static constexpr uint32_t kCacheBucketSizeBytesLog2 = 18; + static constexpr uint32_t kCacheBucketSizeBytes = uint32_t(1) << kCacheBucketSizeBytesLog2; + static constexpr uint32_t kCacheBucketCount = + rex::align(SharedMemory::kBufferSize, kCacheBucketSizeBytes) / kCacheBucketSizeBytes; + + union CacheKey { + uint64_t key; + struct { + uint32_t base; // 32 total + uint32_t count : 16; // 48 + xenos::IndexFormat format : 1; // 49 + xenos::Endian endian : 2; // 52 + uint32_t is_reset_enabled : 1; // 53 + // kNone if not changing the type (like only processing the reset index). + xenos::PrimitiveType conversion_guest_primitive_type : 6; // 59 + // If set, entry is for forced 32-bit guest DMA to host-endian 24-bit + // index conversion used by non-kVertex host vertex shader types on + // backends not supporting full 32-bit index fetch in this path. + uint32_t non_vertex_32bit_dma_to_24bit : 1; // 60 + }; + + CacheKey() : key(0) { static_assert_size(*this, sizeof(key)); } + CacheKey(uint32_t base, uint32_t count, xenos::IndexFormat format, xenos::Endian endian, + bool is_reset_enabled, + xenos::PrimitiveType conversion_guest_primitive_type = xenos::PrimitiveType::kNone, + bool non_vertex_32bit_dma_to_24bit = false) { + // Clear unused bits, then set each field explicitly, not via the + // initializer list (which causes `uint64_t key = 0;` to be ignored, and + // also can't contain initializers for aliasing union members). + key = 0; + this->base = base; + this->count = count; + this->format = format; + this->endian = endian; + this->is_reset_enabled = is_reset_enabled; + this->conversion_guest_primitive_type = conversion_guest_primitive_type; + this->non_vertex_32bit_dma_to_24bit = non_vertex_32bit_dma_to_24bit; + } + + struct Hasher { + size_t operator()(const CacheKey& key) const { return std::hash{}(key.key); } + }; + bool operator==(const CacheKey& other_key) const { return key == other_key.key; } + + uint32_t GetSizeBytes() const { + return count * (format == xenos::IndexFormat::kInt16 ? sizeof(uint16_t) : sizeof(uint32_t)); + } + }; + + // Subset of ConversionResult that can be reused for different primitive types + // if the same result is used irrespective of one (like when only processing + // the reset index). + struct CachedResult { + uint32_t host_draw_vertex_count; + ProcessedIndexBufferType index_buffer_type; + xenos::IndexFormat host_index_format; + xenos::Endian host_shader_index_endian; + bool host_primitive_reset_enabled; + size_t host_index_buffer_handle; + }; + + struct CacheEntry { + static_assert(UINT16_MAX * sizeof(uint32_t) <= (size_t(1) << kCacheBucketSizeBytesLog2), + "Assuming that primitive processor cache entries need to store to the " + "previous and to the next entries only within up to 2 buckets, so the " + "size of the cache buckets must be not smaller than the maximum guest " + "index buffer size"); + union { + size_t free_next; + size_t buckets_prev[2]; + }; + size_t buckets_next[2]; + CacheKey key; + CachedResult result; + static uint32_t GetBucketCount(CacheKey key) { + uint32_t count = ((key.base + (key.GetSizeBytes() - 1)) >> kCacheBucketSizeBytesLog2) - + (key.base >> kCacheBucketSizeBytesLog2) + 1; + assert_true(count <= 2, "Cache entries only store list links within two buckets"); + return count; + } + uint32_t GetBucketCount() const { return GetBucketCount(key); } + }; + + // A cache transaction performs a few operations in a RAII-like way (so + // processing may return an error for any reason, and won't have to clean up + // cache_currently_processing_base_ / size_bytes_ explicitly): + // - Transaction initialization: + // - Lookup of previously processed indices in the cache. + // - If not found, beginning to add a new entry that is going to be + // processed: + // - Marking the range as currently being processed, for slightly safer + // race condition handling if one happens - if invalidation happens + // during the transaction (but outside a global critical region lock, + // since processing may take a long time), the new cache entry won't be + // stored as it will already be invalid at the time of the completion of + // the transaction. + // - Enabling an access callback for the range. + // - Setting the new result after processing (if not found in the cache + // previously). + // - Transaction completion: + // - If the range wasn't invalidated during the transaction, storing the new + // entry in the cache. + // If an entry was found in the cache (GetFoundResult results non-null), it + // MUST be used instead of processing - this class doesn't provide the + // possibility replace existing entries. + class CacheTransaction final { + public: + CacheTransaction(PrimitiveProcessor& processor, CacheKey key); + const CachedResult* GetFoundResult() const { + return result_type_ == ResultType::kExisting ? &result_ : nullptr; + } + void SetNewResult(const CachedResult& new_result) { + // Replacement of an existing entry is not allowed. + assert_true(result_type_ != ResultType::kExisting); + result_ = new_result; + result_type_ = ResultType::kNewSet; + } + ~CacheTransaction(); + + private: + PrimitiveProcessor& processor_; + // If key_.count == 0, this transaction shouldn't do anything - for empty + // ranges it's pointless, and it's unsafe to get the end pointer without + // special logic, and count == 0 is also used as a special indicator for + // vertex count below the cache usage threshold. + CacheKey key_; + CachedResult result_; + enum class ResultType { + kNewUnset, + kNewSet, + kExisting, + }; + ResultType result_type_ = ResultType::kNewUnset; + }; + + std::deque cache_entry_pool_; + + void* memory_invalidation_callback_handle_ = nullptr; + + std::mutex cache_mutex_; + // Modified by both the processor and the invalidation callback. + std::unordered_map cache_map_; + // The conversion is performed while the lock is released since it may take a + // long time. + // If during the conversion the region currently being converted is + // invalidated, the current entry will not be added to the cache. + // Modified by the processor, read by the invalidation callback. + uint32_t cache_currently_processing_base_ = 0; + // 0 if not in a cache transaction that hasn't found an existing entry + // currently. + uint32_t cache_currently_processing_size_bytes_ = 0; + // Modified by both the processor and the invalidation callback. + size_t cache_bucket_free_first_entry_ = SIZE_MAX; + // Modified by both the processor and the invalidation callback. + uint64_t cache_buckets_non_empty_l1_[(kCacheBucketCount + 63) / 64] = {}; + // For even faster handling of memory invalidation - whether any bit is set in + // each cache_buckets_non_empty_l1_. + // Modified by both the processor and the invalidation callback. + uint64_t cache_buckets_non_empty_l2_[(kCacheBucketCount + (64 * 64 - 1)) / (64 * 64)] = {}; + // Must be called in a global critical region. + void UpdateCacheBucketsNonEmptyL2( + uint32_t bucket_index_div_64, + [[maybe_unused]] const std::lock_guard& cache_lock) { + uint64_t& cache_buckets_non_empty_l2_ref = + cache_buckets_non_empty_l2_[bucket_index_div_64 >> 6]; + uint64_t cache_buckets_non_empty_l2_bit = uint64_t(1) << (bucket_index_div_64 & 63); + if (cache_buckets_non_empty_l1_[bucket_index_div_64]) { + cache_buckets_non_empty_l2_ref |= cache_buckets_non_empty_l2_bit; + } else { + cache_buckets_non_empty_l2_ref &= ~cache_buckets_non_empty_l2_bit; + } + } + // cache_buckets_non_empty_l1_ (along with cache_buckets_non_empty_l2_, which + // must be kept in sync) used for indication whether each entry is non-empty, + // for faster clearing (there's no special index here for an empty entry). + // Huge, so it's the last in the class. + // Modified by both the processor and the invalidation callback. + size_t cache_bucket_first_entries_[kCacheBucketCount]; + static std::pair MemoryInvalidationCallbackThunk( + void* context_ptr, uint32_t physical_address_start, uint32_t length, bool exact_range); +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/register_file.h b/include/rex/graphics/register_file.h new file mode 100644 index 0000000..36e07dd --- /dev/null +++ b/include/rex/graphics/register_file.h @@ -0,0 +1,88 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include + +#include +#include +#include +#include + +namespace rex::graphics { + +struct RegisterInfo { + enum class Type { + kDword, + kFloat, + }; + Type type; + const char* name; +}; + +class RegisterFile { + public: + RegisterFile(); + + static const RegisterInfo* GetRegisterInfo(uint32_t index); + + static constexpr size_t kRegisterCount = 0x5003; + uint32_t values[kRegisterCount]; + + const uint32_t& operator[](uint32_t reg) const { return values[reg]; } + uint32_t& operator[](uint32_t reg) { return values[reg]; } + + template + T Get(uint32_t reg) const { + return rex::memory::Reinterpret(values[reg]); + } + template + T Get(Register reg) const { + return Get(static_cast(reg)); + } + template + T Get() const { + return Get(T::register_index); + } + + xenos::xe_gpu_vertex_fetch_t GetVertexFetch(uint32_t index) const { + assert_true(index < 96); + xenos::xe_gpu_vertex_fetch_t fetch; + std::memcpy( + &fetch, + &values[XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 + (sizeof(fetch) / sizeof(uint32_t)) * index], + sizeof(fetch)); + return fetch; + } + + xenos::xe_gpu_texture_fetch_t GetTextureFetch(uint32_t index) const { + assert_true(index < 32); + xenos::xe_gpu_texture_fetch_t fetch; + std::memcpy( + &fetch, + &values[XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 + (sizeof(fetch) / sizeof(uint32_t)) * index], + sizeof(fetch)); + return fetch; + } + + xenos::xe_gpu_memexport_stream_t GetMemExportStream(uint32_t float_constant_index) const { + assert_true(float_constant_index < 512); + xenos::xe_gpu_memexport_stream_t stream; + std::memcpy(&stream, &values[XE_GPU_REG_SHADER_CONSTANT_000_X + 4 * float_constant_index], + sizeof(stream)); + return stream; + } +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/register_table.inc b/include/rex/graphics/register_table.inc new file mode 100644 index 0000000..501147b --- /dev/null +++ b/include/rex/graphics/register_table.inc @@ -0,0 +1,3721 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +// This is a partial file designed to be included by other files when +// constructing various tables. + +// Most 3D registers are the same as in the Qualcomm Adreno 200 (AMD Z430, +// another R400 architecture family chip): +// https://github.com/UDOOboard/Kernel_Unico/blob/master/drivers/mxc/amd-gpu/include/reg/yamato/10/yamato_offset.h +// https://github.com/freedreno/amd-gpu/blob/master/include/reg/yamato/10/yamato_offset.h +// +// The addresses in this file are specified in dwords, similarly to how they are +// defined in yamato_offset.h. AMD, however, generally uses byte addresses in +// their documentation and open source drivers, so when looking up similar +// registers there, multiply by 4 and convert to hexadecimal. +// +// Display controller register addresses mostly match the M56 ones: +// https://www.x.org/docs/AMD/old/RRG-216M56-03oOEM.pdf +// +// 3D registers on the later chips such as the R600 are very different, but some +// of them are still partially or fully the same, and also share the address. +// However, on the R600, the 3D register space (at 0x8000 bytes, or 0x2000 +// dwords, on the Xenos) is split into config registers (at 0x8000 bytes) and +// context registers (at 0x28000 bytes), but the lower bits of the address may +// still be the same. + +//#define XE_GPU_REGISTER(index, type, name) + +XE_GPU_REGISTER(0x0048, kDword, BIF_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0049, kDword, BIF_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x004A, kDword, BIF_PERFCOUNTER0_LOW) + +XE_GPU_REGISTER(0x0080, kDword, SCLK_PWRMGT_CNTL1_REG) +XE_GPU_REGISTER(0x0081, kDword, SCLK_PWRMGT_CNTL2_REG) +XE_GPU_REGISTER(0x0082, kDword, SCLK_PWRMGT_CNTL3_REG) + +XE_GPU_REGISTER(0x01DD, kDword, SCRATCH_ADDR) +XE_GPU_REGISTER(0x01DC, kDword, SCRATCH_UMSK) + +XE_GPU_REGISTER(0x01E6, kDword, CP_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x01E7, kDword, CP_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x01E8, kDword, CP_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x01F5, kDword, CP_PERFMON_CNTL) + +XE_GPU_REGISTER(0x0395, kDword, RBBM_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0396, kDword, RBBM_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x0397, kDword, RBBM_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x0398, kDword, RBBM_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x0399, kDword, RBBM_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x039A, kDword, RBBM_PERFCOUNTER1_HI) + +XE_GPU_REGISTER(0x045E, kDword, CALLBACK_ACK) + +XE_GPU_REGISTER(0x0578, kDword, SCRATCH_REG0) // interrupt sync +XE_GPU_REGISTER(0x0579, kDword, SCRATCH_REG1) // present interval +XE_GPU_REGISTER(0x057A, kDword, SCRATCH_REG2) +XE_GPU_REGISTER(0x057B, kDword, SCRATCH_REG3) +XE_GPU_REGISTER(0x057C, kDword, CALLBACK_ADDRESS) +XE_GPU_REGISTER(0x057D, kDword, CALLBACK_CONTEXT) +XE_GPU_REGISTER(0x057E, kDword, SCRATCH_REG6) +XE_GPU_REGISTER(0x057F, kDword, SCRATCH_REG7) + +XE_GPU_REGISTER(0x05C8, kDword, WAIT_UNTIL) + +XE_GPU_REGISTER(0x0815, kDword, MC0_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0816, kDword, MC0_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x0817, kDword, MC0_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x0855, kDword, MC1_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0856, kDword, MC1_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x0857, kDword, MC1_PERFCOUNTER0_LOW) + +XE_GPU_REGISTER(0x0A02, kDword, UNKNOWN_0A02) +XE_GPU_REGISTER(0x0A03, kDword, UNKNOWN_0A03) +XE_GPU_REGISTER(0x0A04, kDword, UNKNOWN_0A04) +XE_GPU_REGISTER(0x0A05, kDword, UNKNOWN_0A05) + +XE_GPU_REGISTER(0x0A18, kDword, MH_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0A19, kDword, MH_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x0A1A, kDword, MH_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x0A1B, kDword, MH_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x0A1C, kDword, MH_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x0A1D, kDword, MH_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x0A1E, kDword, MH_PERFCOUNTER2_SELECT) +XE_GPU_REGISTER(0x0A1F, kDword, MH_PERFCOUNTER2_HI) +XE_GPU_REGISTER(0x0A20, kDword, MH_PERFCOUNTER2_LOW) + +XE_GPU_REGISTER(0x0A2F, kDword, COHER_SIZE_HOST) +XE_GPU_REGISTER(0x0A30, kDword, COHER_BASE_HOST) +XE_GPU_REGISTER(0x0A31, kDword, COHER_STATUS_HOST) + +// Status flags of viz queries, doesn't seem to be read back by d3d +// queries 0x00 to 0x1f (be), bit set when visible +XE_GPU_REGISTER(0x0C44, kDword, PA_SC_VIZ_QUERY_STATUS_0) +// queries 0x20 to 0x3f (be) +XE_GPU_REGISTER(0x0C45, kDword, PA_SC_VIZ_QUERY_STATUS_1) + +XE_GPU_REGISTER(0x0C48, kDword, VGT_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0C49, kDword, VGT_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x0C4A, kDword, VGT_PERFCOUNTER2_SELECT) +XE_GPU_REGISTER(0x0C4B, kDword, VGT_PERFCOUNTER3_SELECT) +XE_GPU_REGISTER(0x0C4C, kDword, VGT_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x0C4D, kDword, VGT_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x0C4E, kDword, VGT_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x0C4F, kDword, VGT_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x0C50, kDword, VGT_PERFCOUNTER2_LOW) +XE_GPU_REGISTER(0x0C51, kDword, VGT_PERFCOUNTER2_HI) +XE_GPU_REGISTER(0x0C52, kDword, VGT_PERFCOUNTER3_LOW) +XE_GPU_REGISTER(0x0C53, kDword, VGT_PERFCOUNTER3_HI) + +XE_GPU_REGISTER(0x0C85, kDword, PA_CL_ENHANCE) + +XE_GPU_REGISTER(0x0C88, kDword, PA_SU_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0C89, kDword, PA_SU_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x0C8A, kDword, PA_SU_PERFCOUNTER2_SELECT) +XE_GPU_REGISTER(0x0C8B, kDword, PA_SU_PERFCOUNTER3_SELECT) +XE_GPU_REGISTER(0x0C8C, kDword, PA_SU_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x0C8D, kDword, PA_SU_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x0C8E, kDword, PA_SU_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x0C8F, kDword, PA_SU_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x0C90, kDword, PA_SU_PERFCOUNTER2_LOW) +XE_GPU_REGISTER(0x0C91, kDword, PA_SU_PERFCOUNTER2_HI) +XE_GPU_REGISTER(0x0C92, kDword, PA_SU_PERFCOUNTER3_LOW) +XE_GPU_REGISTER(0x0C93, kDword, PA_SU_PERFCOUNTER3_HI) +XE_GPU_REGISTER(0x0C98, kDword, PA_SC_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0C99, kDword, PA_SC_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x0C9A, kDword, PA_SC_PERFCOUNTER2_SELECT) +XE_GPU_REGISTER(0x0C9B, kDword, PA_SC_PERFCOUNTER3_SELECT) +XE_GPU_REGISTER(0x0C9C, kDword, PA_SC_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x0C9D, kDword, PA_SC_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x0C9E, kDword, PA_SC_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x0C9F, kDword, PA_SC_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x0CA0, kDword, PA_SC_PERFCOUNTER2_LOW) +XE_GPU_REGISTER(0x0CA1, kDword, PA_SC_PERFCOUNTER2_HI) +XE_GPU_REGISTER(0x0CA2, kDword, PA_SC_PERFCOUNTER3_LOW) +XE_GPU_REGISTER(0x0CA3, kDword, PA_SC_PERFCOUNTER3_HI) + +XE_GPU_REGISTER(0x0D00, kDword, SQ_GPR_MANAGEMENT) +XE_GPU_REGISTER(0x0D01, kDword, SQ_FLOW_CONTROL) +XE_GPU_REGISTER(0x0D02, kDword, SQ_INST_STORE_MANAGMENT) + +XE_GPU_REGISTER(0x0D04, kDword, SQ_EO_RT) + +XE_GPU_REGISTER(0x0DC8, kDword, SQ_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0DC9, kDword, SQ_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x0DCA, kDword, SQ_PERFCOUNTER2_SELECT) +XE_GPU_REGISTER(0x0DCB, kDword, SQ_PERFCOUNTER3_SELECT) +XE_GPU_REGISTER(0x0DCC, kDword, SQ_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x0DCD, kDword, SQ_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x0DCE, kDword, SQ_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x0DCF, kDword, SQ_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x0DD0, kDword, SQ_PERFCOUNTER2_LOW) +XE_GPU_REGISTER(0x0DD1, kDword, SQ_PERFCOUNTER2_HI) +XE_GPU_REGISTER(0x0DD2, kDword, SQ_PERFCOUNTER3_LOW) +XE_GPU_REGISTER(0x0DD3, kDword, SQ_PERFCOUNTER3_HI) +XE_GPU_REGISTER(0x0DD4, kDword, SX_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0DD8, kDword, SX_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x0DD9, kDword, SX_PERFCOUNTER0_HI) + +// Set with WAIT_UNTIL = WAIT_3D_IDLECLEAN +XE_GPU_REGISTER(0x0E00, kDword, UNKNOWN_0E00) + +XE_GPU_REGISTER(0x0E05, kDword, TCR_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0E06, kDword, TCR_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x0E07, kDword, TCR_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x0E08, kDword, TCR_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x0E09, kDword, TCR_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x0E0A, kDword, TCR_PERFCOUNTER1_LOW) + +XE_GPU_REGISTER(0x0E1F, kDword, TP0_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0E20, kDword, TP0_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x0E21, kDword, TP0_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x0E22, kDword, TP0_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x0E23, kDword, TP0_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x0E24, kDword, TP0_PERFCOUNTER1_LOW) + +XE_GPU_REGISTER(0x0E28, kDword, TP1_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0E29, kDword, TP1_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x0E2A, kDword, TP1_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x0E2B, kDword, TP1_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x0E2C, kDword, TP1_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x0E2D, kDword, TP1_PERFCOUNTER1_LOW) + +XE_GPU_REGISTER(0x0E31, kDword, TP2_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0E32, kDword, TP2_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x0E33, kDword, TP2_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x0E34, kDword, TP2_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x0E35, kDword, TP2_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x0E36, kDword, TP2_PERFCOUNTER1_LOW) + +XE_GPU_REGISTER(0x0E3A, kDword, TP3_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0E3B, kDword, TP3_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x0E3C, kDword, TP3_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x0E3D, kDword, TP3_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x0E3E, kDword, TP3_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x0E3F, kDword, TP3_PERFCOUNTER1_LOW) + +// Set with WAIT_UNTIL = WAIT_3D_IDLECLEAN +XE_GPU_REGISTER(0x0E40, kDword, UNKNOWN_0E40) + +// Set during GPU initialization by D3D +XE_GPU_REGISTER(0x0E42, kDword, UNKNOWN_0E42) + +XE_GPU_REGISTER(0x0E48, kDword, VC_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0E49, kDword, VC_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x0E4A, kDword, VC_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x0E4B, kDword, VC_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x0E4C, kDword, VC_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x0E4D, kDword, VC_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x0E4E, kDword, VC_PERFCOUNTER2_SELECT) +XE_GPU_REGISTER(0x0E4F, kDword, VC_PERFCOUNTER2_HI) +XE_GPU_REGISTER(0x0E50, kDword, VC_PERFCOUNTER2_LOW) +XE_GPU_REGISTER(0x0E51, kDword, VC_PERFCOUNTER3_SELECT) +XE_GPU_REGISTER(0x0E52, kDword, VC_PERFCOUNTER3_HI) +XE_GPU_REGISTER(0x0E53, kDword, VC_PERFCOUNTER3_LOW) + +XE_GPU_REGISTER(0x0E54, kDword, TCM_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0E55, kDword, TCM_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x0E56, kDword, TCM_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x0E57, kDword, TCM_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x0E58, kDword, TCM_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x0E59, kDword, TCM_PERFCOUNTER1_LOW) + +XE_GPU_REGISTER(0x0E5A, kDword, TCF_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0E5B, kDword, TCF_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x0E5C, kDword, TCF_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x0E5D, kDword, TCF_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x0E5E, kDword, TCF_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x0E5F, kDword, TCF_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x0E60, kDword, TCF_PERFCOUNTER2_SELECT) +XE_GPU_REGISTER(0x0E61, kDword, TCF_PERFCOUNTER2_HI) +XE_GPU_REGISTER(0x0E62, kDword, TCF_PERFCOUNTER2_LOW) +XE_GPU_REGISTER(0x0E63, kDword, TCF_PERFCOUNTER3_SELECT) +XE_GPU_REGISTER(0x0E64, kDword, TCF_PERFCOUNTER3_HI) +XE_GPU_REGISTER(0x0E65, kDword, TCF_PERFCOUNTER3_LOW) +XE_GPU_REGISTER(0x0E66, kDword, TCF_PERFCOUNTER4_SELECT) +XE_GPU_REGISTER(0x0E67, kDword, TCF_PERFCOUNTER4_HI) +XE_GPU_REGISTER(0x0E68, kDword, TCF_PERFCOUNTER4_LOW) +XE_GPU_REGISTER(0x0E69, kDword, TCF_PERFCOUNTER5_SELECT) +XE_GPU_REGISTER(0x0E6A, kDword, TCF_PERFCOUNTER5_HI) +XE_GPU_REGISTER(0x0E6B, kDword, TCF_PERFCOUNTER5_LOW) +XE_GPU_REGISTER(0x0E6C, kDword, TCF_PERFCOUNTER6_SELECT) +XE_GPU_REGISTER(0x0E6D, kDword, TCF_PERFCOUNTER6_HI) +XE_GPU_REGISTER(0x0E6E, kDword, TCF_PERFCOUNTER6_LOW) +XE_GPU_REGISTER(0x0E6F, kDword, TCF_PERFCOUNTER7_SELECT) +XE_GPU_REGISTER(0x0E70, kDword, TCF_PERFCOUNTER7_HI) +XE_GPU_REGISTER(0x0E71, kDword, TCF_PERFCOUNTER7_LOW) +XE_GPU_REGISTER(0x0E72, kDword, TCF_PERFCOUNTER8_SELECT) +XE_GPU_REGISTER(0x0E73, kDword, TCF_PERFCOUNTER8_HI) +XE_GPU_REGISTER(0x0E74, kDword, TCF_PERFCOUNTER8_LOW) +XE_GPU_REGISTER(0x0E75, kDword, TCF_PERFCOUNTER9_SELECT) +XE_GPU_REGISTER(0x0E76, kDword, TCF_PERFCOUNTER9_HI) +XE_GPU_REGISTER(0x0E77, kDword, TCF_PERFCOUNTER9_LOW) +XE_GPU_REGISTER(0x0E78, kDword, TCF_PERFCOUNTER10_SELECT) +XE_GPU_REGISTER(0x0E79, kDword, TCF_PERFCOUNTER10_HI) +XE_GPU_REGISTER(0x0E7A, kDword, TCF_PERFCOUNTER10_LOW) +XE_GPU_REGISTER(0x0E7B, kDword, TCF_PERFCOUNTER11_SELECT) +XE_GPU_REGISTER(0x0E7C, kDword, TCF_PERFCOUNTER11_HI) +XE_GPU_REGISTER(0x0E7D, kDword, TCF_PERFCOUNTER11_LOW) + +XE_GPU_REGISTER(0x0F01, kDword, RB_BC_CONTROL) +XE_GPU_REGISTER(0x0F02, kDword, RB_EDRAM_INFO) + +XE_GPU_REGISTER(0x0F04, kDword, BC_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0F05, kDword, BC_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x0F06, kDword, BC_PERFCOUNTER2_SELECT) +XE_GPU_REGISTER(0x0F07, kDword, BC_PERFCOUNTER3_SELECT) +XE_GPU_REGISTER(0x0F08, kDword, BC_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x0F09, kDword, BC_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x0F0A, kDword, BC_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x0F0B, kDword, BC_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x0F0C, kDword, BC_PERFCOUNTER2_LOW) +XE_GPU_REGISTER(0x0F0D, kDword, BC_PERFCOUNTER2_HI) +XE_GPU_REGISTER(0x0F0E, kDword, BC_PERFCOUNTER3_LOW) +XE_GPU_REGISTER(0x0F0F, kDword, BC_PERFCOUNTER3_HI) + +XE_GPU_REGISTER(0x1004, kDword, HZ_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x1005, kDword, HZ_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x1006, kDword, HZ_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x1007, kDword, HZ_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x1008, kDword, HZ_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x1009, kDword, HZ_PERFCOUNTER1_LOW) + +// D1*, LUT, and AVIVO registers taken from libxenon and +// https://www.x.org/docs/AMD/old/RRG-216M56-03oOEM.pdf +XE_GPU_REGISTER(0x1838, kDword, D1MODE_MASTER_UPDATE_LOCK) + +XE_GPU_REGISTER(0x1841, kDword, D1GRPH_CONTROL) + +XE_GPU_REGISTER(0x1844, kDword, D1GRPH_PRIMARY_SURFACE_ADDRESS) + +XE_GPU_REGISTER(0x1852, kDword, D1GRPH_FLIP_CONTROL) + +// In 4B4F07FE, the 256-entry gamma ramp for the 8bpc framebuffer is set to +// different values in multiple places in the game. For VdGetCurrentDisplayGamma +// returning 1 (sRGB), it's set up in the beginning as: +// DC_LUTA_CONTROL = 0x00000000 (256-entry unsigned fixed-point) +// DC_LUT_RW_MODE = 0x00000000 +// DC_LUT_RW_INDEX = 0x00000000 +// DC_LUT_WRITE_EN_MASK = 0x00000007 +// DC_LUT_30_COLOR = 0x00000000 +// DC_LUT_RW_INDEX = 0x00000001 +// DC_LUT_30_COLOR = 0x04812048 +// DC_LUT_RW_INDEX = 0x00000002 +// DC_LUT_30_COLOR = 0x05916459 +// DC_LUT_RW_INDEX = 0x00000003 +// DC_LUT_30_COLOR = 0x06519465 +// ... +// DC_LUT_RW_INDEX = 0x000000FE +// DC_LUT_30_COLOR = 0x3FBFEFFB +// DC_LUT_RW_INDEX = 0x000000FF +// DC_LUT_30_COLOR = 0x3FFFFFFF +// DC_LUT_RW_INDEX = 0x00000100 +// +// One another possible setup in 4B4F07FE is: +// DC_LUTA_CONTROL = 0x00000000 (256-entry unsigned fixed-point) +// DC_LUT_RW_MODE = 0x00000000 +// DC_LUT_RW_INDEX = 0x00000000 +// DC_LUT_WRITE_EN_MASK = 0x00000007 +// DC_LUT_30_COLOR = 0x00000000 +// DC_LUT_RW_INDEX = 0x00000001 +// DC_LUT_30_COLOR = 0x01A0681A +// DC_LUT_RW_INDEX = 0x00000002 +// DC_LUT_30_COLOR = 0x02709C27 +// ... +// DC_LUT_RW_INDEX = 0x000000FE +// DC_LUT_30_COLOR = 0x3FBFEFFB +// DC_LUT_RW_INDEX = 0x000000FF +// DC_LUT_30_COLOR = 0x3FFFFFFF +// DC_LUT_RW_INDEX = 0x00000100 +// +// In 4D5307E6, the 128-entry PWL gamma ramp for the 10bpc framebuffer, for +// VdGetCurrentDisplayGamma returning 1 (sRGB), is set up right after launching +// the game as: +// DC_LUTA_CONTROL = 0x00000003 (8-increment unsigned fixed-point) +// DC_LUT_RW_MODE = 0x00000001 +// DC_LUT_RW_INDEX = 0x00000000 +// DC_LUT_WRITE_EN_MASK = 0x00000007 +// DC_LUT_PWL_DATA = 0x02000000 +// DC_LUT_PWL_DATA = 0x02000000 +// DC_LUT_PWL_DATA = 0x02000000 +// DC_LUT_RW_INDEX = 0x00000001 +// DC_LUT_PWL_DATA = 0x02000200 +// DC_LUT_PWL_DATA = 0x02000200 +// DC_LUT_PWL_DATA = 0x02000200 +// DC_LUT_RW_INDEX = 0x00000001 +// DC_LUT_PWL_DATA = 0x02000400 +// DC_LUT_PWL_DATA = 0x02000400 +// DC_LUT_PWL_DATA = 0x02000400 +// ... +// DC_LUT_RW_INDEX = 0x0000007D +// DC_LUT_PWL_DATA = 0x0200FBC0 +// DC_LUT_PWL_DATA = 0x0200FBC0 +// DC_LUT_PWL_DATA = 0x0200FBC0 +// DC_LUT_RW_INDEX = 0x0000007E +// DC_LUT_PWL_DATA = 0x0200FDC0 +// DC_LUT_PWL_DATA = 0x0200FDC0 +// DC_LUT_PWL_DATA = 0x0200FDC0 +// DC_LUT_RW_INDEX = 0x0000007F +// DC_LUT_PWL_DATA = 0x0000FFC0 +// DC_LUT_PWL_DATA = 0x0000FFC0 +// DC_LUT_PWL_DATA = 0x0000FFC0 +// DC_LUT_RW_INDEX = 0x00000080 +// +// Later in 4D5307E6, for the game itself (apparently for conversion of the bit +// representation of 7e3 floating-point data in the front buffer to 10-bit fixed +// point, as the game draws the final passes to a 7e3 framebuffer), with +// VdGetCurrentDisplayGamma returning 1 (sRGB) and the normal brightness in the +// game settings, it's: +// DC_LUTA_CONTROL = 0x00000003 (8-increment unsigned fixed-point) +// DC_LUT_RW_MODE = 0x00000001 +// DC_LUT_RW_INDEX = 0x00000000 +// DC_LUT_WRITE_EN_MASK = 0x00000007 +// DC_LUT_PWL_DATA = 0x05000000 +// DC_LUT_PWL_DATA = 0x05000000 +// DC_LUT_PWL_DATA = 0x05000000 +// DC_LUT_RW_INDEX = 0x00000001 +// DC_LUT_PWL_DATA = 0x02000500 +// DC_LUT_PWL_DATA = 0x02000500 +// DC_LUT_PWL_DATA = 0x02000500 +// DC_LUT_RW_INDEX = 0x00000001 +// DC_LUT_PWL_DATA = 0x01800740 +// DC_LUT_PWL_DATA = 0x01800740 +// DC_LUT_PWL_DATA = 0x01800740 +// ... +// DC_LUT_RW_INDEX = 0x0000007D +// DC_LUT_PWL_DATA = 0x0440F340 +// DC_LUT_PWL_DATA = 0x0440F340 +// DC_LUT_PWL_DATA = 0x0440F340 +// DC_LUT_RW_INDEX = 0x0000007E +// DC_LUT_PWL_DATA = 0x0400F780 +// DC_LUT_PWL_DATA = 0x0400F780 +// DC_LUT_PWL_DATA = 0x0400F780 +// DC_LUT_RW_INDEX = 0x0000007F +// DC_LUT_PWL_DATA = 0x0400FBC0 +// DC_LUT_PWL_DATA = 0x0400FBC0 +// DC_LUT_PWL_DATA = 0x0400FBC0 +// DC_LUT_RW_INDEX = 0x00000080 +// +// In 535107D4, the 256-entry gamma ramp for the 8bpc framebuffer is +// configurable from the game's settings menu for each channel independently. +// For VdGetCurrentDisplayGamma returning 1 (sRGB), when in the settings, the +// red gamma is at the maximum of 5.56, green is at 1.00, and blue is at the +// minimum of 0.17, the setup is done as: +// DC_LUT_RW_MODE = 0x00000000 +// DC_LUT_RW_INDEX = 0x00000000 +// DC_LUT_WRITE_EN_MASK = 0x00000007 +// DC_LUT_30_COLOR = 0x00000000 +// DC_LUT_RW_INDEX = 0x00000001 +// DC_LUT_30_COLOR = 0x17901000 +// DC_LUT_RW_INDEX = 0x00000002 +// DC_LUT_30_COLOR = 0x1AB02000 +// ... +// DC_LUT_RW_INDEX = 0x000000FE +// DC_LUT_30_COLOR = 0x3FEFE3D2 +// DC_LUT_RW_INDEX = 0x000000FF +// DC_LUT_30_COLOR = 0x3FFFF3E9 +// DC_LUT_RW_INDEX = 0x00000100 + +// Read / write mode in bit 0: 0 - 256-entry table, 1 - PWL. +// Default: 0x00000000. +XE_GPU_REGISTER(0x1921, kDword, DC_LUT_RW_MODE) +// Read / write index. No lower and upper halves on the Xenos apparently, for +// the 256-entry table, the bits 0:7 are the index directly (unlike on the M56, +// not split into the index in 1:7 and the lower or upper 10 bits selection in +// 0:0, instead, on the Xenos, the index in 0:7 is just increased +// monotonically). For some reason though Direct3D 9 writes an index that +// overflows by one (0x100 for the 256-entry table, 0x80 for the 128-entry PWL +// gamma ramp) after setting up all the values. However, the index is 8-bit, and +// for PWL, according to the M56 documentation, the bit 7 is not used. +// Default: 0x00000000. +XE_GPU_REGISTER(0x1922, kDword, DC_LUT_RW_INDEX) +// Sequential 10-bit R, G, B host read / write for the 256-entry table. After +// reset or writing DC_LUT_RW_INDEX, the first access is for the red component, +// the second is for green, the third is for blue, and after blue is accessed, +// the LUT index is increased by 1 (without having to explicitly change +// DC_LUT_RW_INDEX). Bits 0:5 are hardwired to zero. +// Default: 0x00000000. +XE_GPU_REGISTER(0x1923, kDword, DC_LUT_SEQ_COLOR) +// Read / write, 0:15 - base, 16:31 - delta. Bits 0:5 of both the base and the +// delta are hardwired to zero. The LUT index is increased by 1 when +// DC_LUT_PWL_DATA is accessed, though three DC_LUT_PWL_DATA writes are done for +// one entry (the order is likely R, G, B, similar to DC_LUT_SEQ_COLOR, but this +// hasn't been verified yet as no games using the PWL gamma ramp with separate +// settings for each channel have been found yet). +// Default: 0x00000000. +XE_GPU_REGISTER(0x1924, kDword, DC_LUT_PWL_DATA) +// Read / write, 0:9 - blue, 10:19 - green, 20:29 - red. The LUT index is +// increased by 1 when DC_LUT_30_COLOR is accessed. +// Default: 0x00000000. +XE_GPU_REGISTER(0x1925, kDword, DC_LUT_30_COLOR) + +// Only LUT pipe 1 on the Xenos apparently (Direct3D 9 sets DC_LUT_WRITE_EN_MASK +// to 0b111 before writing the gamma ramp), 3 bits set, rather than 6 on the +// M56. +// Bit 0 - blue write enable mask. +// Bit 1 - green write enable mask. +// Bit 2 - red write enable mask. +// Default: 0x00000007 (though 0x0000003F on the M56 where there are two pipes). +XE_GPU_REGISTER(0x1927, kDword, DC_LUT_WRITE_EN_MASK) + +// Single set of parameters for all channels apparently unlike on the M56 +// (4D5307E6 sets DC_LUTA_CONTROL to 0x00000003 for the data increment of 8 in +// the 128-entry PWL gamma ramp for a 10bpc framebuffer). Also set not only +// during setup, but also apparently during every swap by Direct3D 9, though not +// directly in all games (happens in 4B4F07FE and 4D5307E6 even without proper +// VdSwap emulation, but in 535107D4, with a fake VdSwap packet rather than the +// real ones, the register is not set at all, though the expected behavior is +// that of the value of 0x00000000). +// Default: 0x00000000. +XE_GPU_REGISTER(0x1930, kDword, DC_LUTA_CONTROL) + +XE_GPU_REGISTER(0x1961, kDword, AVIVO_D1MODE_VIEWPORT_SIZE) + +XE_GPU_REGISTER(0x1964, kDword, AVIVO_D1SCL_SCALER_ENABLE) + +XE_GPU_REGISTER(0x1973, kDword, AVIVO_D1SCL_UPDATE) + +XE_GPU_REGISTER(0x1E4E, kDword, XDVO_FORCE_OUTPUT_CNTL) + +XE_GPU_REGISTER(0x2000, kDword, RB_SURFACE_INFO) +XE_GPU_REGISTER(0x2001, kDword, RB_COLOR_INFO) +XE_GPU_REGISTER(0x2002, kDword, RB_DEPTH_INFO) +XE_GPU_REGISTER(0x2003, kDword, RB_COLOR1_INFO) +XE_GPU_REGISTER(0x2004, kDword, RB_COLOR2_INFO) +XE_GPU_REGISTER(0x2005, kDword, RB_COLOR3_INFO) +XE_GPU_REGISTER(0x2006, kDword, COHER_DEST_BASE_0) +XE_GPU_REGISTER(0x2007, kDword, COHER_DEST_BASE_1) +XE_GPU_REGISTER(0x2008, kDword, COHER_DEST_BASE_2) +XE_GPU_REGISTER(0x2009, kDword, COHER_DEST_BASE_3) +XE_GPU_REGISTER(0x200A, kDword, COHER_DEST_BASE_4) +XE_GPU_REGISTER(0x200B, kDword, COHER_DEST_BASE_5) +XE_GPU_REGISTER(0x200C, kDword, COHER_DEST_BASE_6) +XE_GPU_REGISTER(0x200D, kDword, COHER_DEST_BASE_7) +XE_GPU_REGISTER(0x200E, kDword, PA_SC_SCREEN_SCISSOR_TL) +XE_GPU_REGISTER(0x200F, kDword, PA_SC_SCREEN_SCISSOR_BR) + +XE_GPU_REGISTER(0x2080, kDword, PA_SC_WINDOW_OFFSET) +XE_GPU_REGISTER(0x2081, kDword, PA_SC_WINDOW_SCISSOR_TL) +XE_GPU_REGISTER(0x2082, kDword, PA_SC_WINDOW_SCISSOR_BR) + +XE_GPU_REGISTER(0x2100, kDword, VGT_MAX_VTX_INDX) +XE_GPU_REGISTER(0x2101, kDword, VGT_MIN_VTX_INDX) +XE_GPU_REGISTER(0x2102, kDword, VGT_INDX_OFFSET) +XE_GPU_REGISTER(0x2103, kDword, VGT_MULTI_PRIM_IB_RESET_INDX) +XE_GPU_REGISTER(0x2104, kDword, RB_COLOR_MASK) +XE_GPU_REGISTER(0x2105, kFloat, RB_BLEND_RED) +XE_GPU_REGISTER(0x2106, kFloat, RB_BLEND_GREEN) +XE_GPU_REGISTER(0x2107, kFloat, RB_BLEND_BLUE) +XE_GPU_REGISTER(0x2108, kFloat, RB_BLEND_ALPHA) +XE_GPU_REGISTER(0x2109, kFloat, RB_FOG_COLOR_RED) +XE_GPU_REGISTER(0x210A, kFloat, RB_FOG_COLOR_GREEN) +XE_GPU_REGISTER(0x210B, kFloat, RB_FOG_COLOR_BLUE) +XE_GPU_REGISTER(0x210C, kDword, RB_STENCILREFMASK_BF) +XE_GPU_REGISTER(0x210D, kDword, RB_STENCILREFMASK) +XE_GPU_REGISTER(0x210E, kFloat, RB_ALPHA_REF) +XE_GPU_REGISTER(0x210F, kFloat, PA_CL_VPORT_XSCALE) +XE_GPU_REGISTER(0x2110, kFloat, PA_CL_VPORT_XOFFSET) +XE_GPU_REGISTER(0x2111, kFloat, PA_CL_VPORT_YSCALE) +XE_GPU_REGISTER(0x2112, kFloat, PA_CL_VPORT_YOFFSET) +XE_GPU_REGISTER(0x2113, kFloat, PA_CL_VPORT_ZSCALE) +XE_GPU_REGISTER(0x2114, kFloat, PA_CL_VPORT_ZOFFSET) + +XE_GPU_REGISTER(0x2180, kDword, SQ_PROGRAM_CNTL) +XE_GPU_REGISTER(0x2181, kDword, SQ_CONTEXT_MISC) +XE_GPU_REGISTER(0x2182, kDword, SQ_INTERPOLATOR_CNTL) +XE_GPU_REGISTER(0x2183, kDword, SQ_WRAPPING_0) +XE_GPU_REGISTER(0x2184, kDword, SQ_WRAPPING_1) + +// These three registers are set by the command processor. +XE_GPU_REGISTER(0x21F9, kDword, VGT_EVENT_INITIATOR) +XE_GPU_REGISTER(0x21FA, kDword, VGT_DMA_BASE) +XE_GPU_REGISTER(0x21FB, kDword, VGT_DMA_SIZE) +XE_GPU_REGISTER(0x21FC, kDword, VGT_DRAW_INITIATOR) +XE_GPU_REGISTER(0x21FD, kDword, VGT_IMMED_DATA) + +XE_GPU_REGISTER(0x2200, kDword, RB_DEPTHCONTROL) +XE_GPU_REGISTER(0x2201, kDword, RB_BLENDCONTROL0) +XE_GPU_REGISTER(0x2202, kDword, RB_COLORCONTROL) +XE_GPU_REGISTER(0x2203, kDword, RB_HIZCONTROL) +XE_GPU_REGISTER(0x2204, kDword, PA_CL_CLIP_CNTL) +XE_GPU_REGISTER(0x2205, kDword, PA_SU_SC_MODE_CNTL) +XE_GPU_REGISTER(0x2206, kDword, PA_CL_VTE_CNTL) +XE_GPU_REGISTER(0x2207, kDword, VGT_CURRENT_BIN_ID_MIN) +XE_GPU_REGISTER(0x2208, kDword, RB_MODECONTROL) +XE_GPU_REGISTER(0x2209, kDword, RB_BLENDCONTROL1) +XE_GPU_REGISTER(0x220A, kDword, RB_BLENDCONTROL2) +XE_GPU_REGISTER(0x220B, kDword, RB_BLENDCONTROL3) + +XE_GPU_REGISTER(0x2280, kDword, PA_SU_POINT_SIZE) +XE_GPU_REGISTER(0x2281, kDword, PA_SU_POINT_MINMAX) +XE_GPU_REGISTER(0x2282, kDword, PA_SU_LINE_CNTL) +XE_GPU_REGISTER(0x2283, kDword, PA_SC_LINE_STIPPLE) +XE_GPU_REGISTER(0x2284, kDword, VGT_OUTPUT_PATH_CNTL) +XE_GPU_REGISTER(0x2285, kDword, VGT_HOS_CNTL) +XE_GPU_REGISTER(0x2286, kFloat, VGT_HOS_MAX_TESS_LEVEL) +XE_GPU_REGISTER(0x2287, kFloat, VGT_HOS_MIN_TESS_LEVEL) +XE_GPU_REGISTER(0x2288, kDword, VGT_HOS_REUSE_DEPTH) +XE_GPU_REGISTER(0x2289, kDword, VGT_GROUP_PRIM_TYPE) +XE_GPU_REGISTER(0x228A, kDword, VGT_GROUP_FIRST_DECR) +XE_GPU_REGISTER(0x228B, kDword, VGT_GROUP_DECR) +XE_GPU_REGISTER(0x228C, kDword, VGT_GROUP_VECT_0_CNTL) +XE_GPU_REGISTER(0x228D, kDword, VGT_GROUP_VECT_1_CNTL) +XE_GPU_REGISTER(0x228E, kDword, VGT_GROUP_VECT_0_FMT_CNTL) +XE_GPU_REGISTER(0x228F, kDword, VGT_GROUP_VECT_1_FMT_CNTL) +XE_GPU_REGISTER(0x2290, kDword, UNKNOWN_2290) +XE_GPU_REGISTER(0x2291, kDword, UNKNOWN_2291) +XE_GPU_REGISTER(0x2292, kDword, PA_SC_MPASS_PS_CNTL) +XE_GPU_REGISTER(0x2293, kDword, PA_SC_VIZ_QUERY) +XE_GPU_REGISTER(0x2294, kDword, VGT_ENHANCE) + +XE_GPU_REGISTER(0x2300, kDword, PA_SC_LINE_CNTL) +XE_GPU_REGISTER(0x2301, kDword, PA_SC_AA_CONFIG) +XE_GPU_REGISTER(0x2302, kDword, PA_SU_VTX_CNTL) +XE_GPU_REGISTER(0x2303, kFloat, PA_CL_GB_VERT_CLIP_ADJ) +XE_GPU_REGISTER(0x2304, kFloat, PA_CL_GB_VERT_DISC_ADJ) +XE_GPU_REGISTER(0x2305, kFloat, PA_CL_GB_HORZ_CLIP_ADJ) +XE_GPU_REGISTER(0x2306, kFloat, PA_CL_GB_HORZ_DISC_ADJ) +XE_GPU_REGISTER(0x2307, kDword, SQ_VS_CONST) +XE_GPU_REGISTER(0x2308, kDword, SQ_PS_CONST) +XE_GPU_REGISTER(0x2309, kDword, SQ_DEBUG_MISC_0) +XE_GPU_REGISTER(0x230A, kDword, SQ_DEBUG_MISC_1) +XE_GPU_REGISTER(0x230B, kDword, UNKNOWN_230B) +XE_GPU_REGISTER(0x230C, kDword, UNKNOWN_230C) +XE_GPU_REGISTER(0x230D, kDword, UNKNOWN_230D) +XE_GPU_REGISTER(0x230E, kDword, UNKNOWN_230E) +XE_GPU_REGISTER(0x230F, kDword, UNKNOWN_230F) +XE_GPU_REGISTER(0x2310, kDword, UNKNOWN_2310) +XE_GPU_REGISTER(0x2311, kDword, UNKNOWN_2311) +XE_GPU_REGISTER(0x2312, kDword, PA_SC_AA_MASK) +XE_GPU_REGISTER(0x2313, kDword, UNKNOWN_2313) +XE_GPU_REGISTER(0x2314, kDword, UNKNOWN_2314) +XE_GPU_REGISTER(0x2315, kDword, SQ_CF_PROGRAM_SIZE) +XE_GPU_REGISTER(0x2316, kDword, VGT_VERTEX_REUSE_BLOCK_CNTL) +XE_GPU_REGISTER(0x2317, kDword, VGT_OUT_DEALLOC_CNTL) +XE_GPU_REGISTER(0x2318, kDword, RB_COPY_CONTROL) +XE_GPU_REGISTER(0x2319, kDword, RB_COPY_DEST_BASE) +XE_GPU_REGISTER(0x231A, kDword, RB_COPY_DEST_PITCH) +XE_GPU_REGISTER(0x231B, kDword, RB_COPY_DEST_INFO) +XE_GPU_REGISTER(0x231C, kDword, RB_HIZ_CLEAR) +XE_GPU_REGISTER(0x231D, kDword, RB_DEPTH_CLEAR) +XE_GPU_REGISTER(0x231E, kDword, RB_COLOR_CLEAR) +XE_GPU_REGISTER(0x231F, kDword, RB_COLOR_CLEAR_LO) +XE_GPU_REGISTER(0x2320, kDword, RB_COPY_FUNC) +XE_GPU_REGISTER(0x2321, kDword, RB_COPY_REF) +XE_GPU_REGISTER(0x2322, kDword, RB_COPY_MASK) +XE_GPU_REGISTER(0x2323, kDword, RB_COPY_SURFACE_SLICE) +XE_GPU_REGISTER(0x2324, kDword, RB_SAMPLE_COUNT_CTL) +XE_GPU_REGISTER(0x2325, kDword, RB_SAMPLE_COUNT_ADDR) + +// Polygon offset scales and offsets are 32-bit floating-point. +// "slope computed in subpixels (1/12 or 1/16)" - R5xx Acceleration. +// But the correct scale for conversion of the slope scale (FRONT_BACK/SCALE) +// from subpixels to pixels is likely 1/16 according to: +// https://github.com/mesa3d/mesa/blob/54ad9b444c8e73da498211870e785239ad3ff1aa/src/gallium/drivers/radeonsi/si_state.c#L946 +XE_GPU_REGISTER(0x2380, kFloat, PA_SU_POLY_OFFSET_FRONT_SCALE) +XE_GPU_REGISTER(0x2381, kFloat, PA_SU_POLY_OFFSET_FRONT_OFFSET) +XE_GPU_REGISTER(0x2382, kFloat, PA_SU_POLY_OFFSET_BACK_SCALE) +XE_GPU_REGISTER(0x2383, kFloat, PA_SU_POLY_OFFSET_BACK_OFFSET) +XE_GPU_REGISTER(0x2384, kFloat, PA_CL_POINT_X_RAD) +XE_GPU_REGISTER(0x2385, kFloat, PA_CL_POINT_Y_RAD) +XE_GPU_REGISTER(0x2386, kFloat, PA_CL_POINT_SIZE) +XE_GPU_REGISTER(0x2387, kFloat, PA_CL_POINT_CULL_RAD) +XE_GPU_REGISTER(0x2388, kFloat, PA_CL_UCP_0_X) +XE_GPU_REGISTER(0x2389, kFloat, PA_CL_UCP_0_Y) +XE_GPU_REGISTER(0x238A, kFloat, PA_CL_UCP_0_Z) +XE_GPU_REGISTER(0x238B, kFloat, PA_CL_UCP_0_W) +XE_GPU_REGISTER(0x238C, kFloat, PA_CL_UCP_1_X) +XE_GPU_REGISTER(0x238D, kFloat, PA_CL_UCP_1_Y) +XE_GPU_REGISTER(0x238E, kFloat, PA_CL_UCP_1_Z) +XE_GPU_REGISTER(0x238F, kFloat, PA_CL_UCP_1_W) +XE_GPU_REGISTER(0x2390, kFloat, PA_CL_UCP_2_X) +XE_GPU_REGISTER(0x2391, kFloat, PA_CL_UCP_2_Y) +XE_GPU_REGISTER(0x2392, kFloat, PA_CL_UCP_2_Z) +XE_GPU_REGISTER(0x2393, kFloat, PA_CL_UCP_2_W) +XE_GPU_REGISTER(0x2394, kFloat, PA_CL_UCP_3_X) +XE_GPU_REGISTER(0x2395, kFloat, PA_CL_UCP_3_Y) +XE_GPU_REGISTER(0x2396, kFloat, PA_CL_UCP_3_Z) +XE_GPU_REGISTER(0x2397, kFloat, PA_CL_UCP_3_W) +XE_GPU_REGISTER(0x2398, kFloat, PA_CL_UCP_4_X) +XE_GPU_REGISTER(0x2399, kFloat, PA_CL_UCP_4_Y) +XE_GPU_REGISTER(0x239A, kFloat, PA_CL_UCP_4_Z) +XE_GPU_REGISTER(0x239B, kFloat, PA_CL_UCP_4_W) +XE_GPU_REGISTER(0x239C, kFloat, PA_CL_UCP_5_X) +XE_GPU_REGISTER(0x239D, kFloat, PA_CL_UCP_5_Y) +XE_GPU_REGISTER(0x239E, kFloat, PA_CL_UCP_5_Z) +XE_GPU_REGISTER(0x239F, kFloat, PA_CL_UCP_5_W) + +XE_GPU_REGISTER(0x4000, kFloat, SHADER_CONSTANT_000_X) +XE_GPU_REGISTER(0x4001, kFloat, SHADER_CONSTANT_000_Y) +XE_GPU_REGISTER(0x4002, kFloat, SHADER_CONSTANT_000_Z) +XE_GPU_REGISTER(0x4003, kFloat, SHADER_CONSTANT_000_W) +XE_GPU_REGISTER(0x4004, kFloat, SHADER_CONSTANT_001_X) +XE_GPU_REGISTER(0x4005, kFloat, SHADER_CONSTANT_001_Y) +XE_GPU_REGISTER(0x4006, kFloat, SHADER_CONSTANT_001_Z) +XE_GPU_REGISTER(0x4007, kFloat, SHADER_CONSTANT_001_W) +XE_GPU_REGISTER(0x4008, kFloat, SHADER_CONSTANT_002_X) +XE_GPU_REGISTER(0x4009, kFloat, SHADER_CONSTANT_002_Y) +XE_GPU_REGISTER(0x400A, kFloat, SHADER_CONSTANT_002_Z) +XE_GPU_REGISTER(0x400B, kFloat, SHADER_CONSTANT_002_W) +XE_GPU_REGISTER(0x400C, kFloat, SHADER_CONSTANT_003_X) +XE_GPU_REGISTER(0x400D, kFloat, SHADER_CONSTANT_003_Y) +XE_GPU_REGISTER(0x400E, kFloat, SHADER_CONSTANT_003_Z) +XE_GPU_REGISTER(0x400F, kFloat, SHADER_CONSTANT_003_W) +XE_GPU_REGISTER(0x4010, kFloat, SHADER_CONSTANT_004_X) +XE_GPU_REGISTER(0x4011, kFloat, SHADER_CONSTANT_004_Y) +XE_GPU_REGISTER(0x4012, kFloat, SHADER_CONSTANT_004_Z) +XE_GPU_REGISTER(0x4013, kFloat, SHADER_CONSTANT_004_W) +XE_GPU_REGISTER(0x4014, kFloat, SHADER_CONSTANT_005_X) +XE_GPU_REGISTER(0x4015, kFloat, SHADER_CONSTANT_005_Y) +XE_GPU_REGISTER(0x4016, kFloat, SHADER_CONSTANT_005_Z) +XE_GPU_REGISTER(0x4017, kFloat, SHADER_CONSTANT_005_W) +XE_GPU_REGISTER(0x4018, kFloat, SHADER_CONSTANT_006_X) +XE_GPU_REGISTER(0x4019, kFloat, SHADER_CONSTANT_006_Y) +XE_GPU_REGISTER(0x401A, kFloat, SHADER_CONSTANT_006_Z) +XE_GPU_REGISTER(0x401B, kFloat, SHADER_CONSTANT_006_W) +XE_GPU_REGISTER(0x401C, kFloat, SHADER_CONSTANT_007_X) +XE_GPU_REGISTER(0x401D, kFloat, SHADER_CONSTANT_007_Y) +XE_GPU_REGISTER(0x401E, kFloat, SHADER_CONSTANT_007_Z) +XE_GPU_REGISTER(0x401F, kFloat, SHADER_CONSTANT_007_W) +XE_GPU_REGISTER(0x4020, kFloat, SHADER_CONSTANT_008_X) +XE_GPU_REGISTER(0x4021, kFloat, SHADER_CONSTANT_008_Y) +XE_GPU_REGISTER(0x4022, kFloat, SHADER_CONSTANT_008_Z) +XE_GPU_REGISTER(0x4023, kFloat, SHADER_CONSTANT_008_W) +XE_GPU_REGISTER(0x4024, kFloat, SHADER_CONSTANT_009_X) +XE_GPU_REGISTER(0x4025, kFloat, SHADER_CONSTANT_009_Y) +XE_GPU_REGISTER(0x4026, kFloat, SHADER_CONSTANT_009_Z) +XE_GPU_REGISTER(0x4027, kFloat, SHADER_CONSTANT_009_W) +XE_GPU_REGISTER(0x4028, kFloat, SHADER_CONSTANT_010_X) +XE_GPU_REGISTER(0x4029, kFloat, SHADER_CONSTANT_010_Y) +XE_GPU_REGISTER(0x402A, kFloat, SHADER_CONSTANT_010_Z) +XE_GPU_REGISTER(0x402B, kFloat, SHADER_CONSTANT_010_W) +XE_GPU_REGISTER(0x402C, kFloat, SHADER_CONSTANT_011_X) +XE_GPU_REGISTER(0x402D, kFloat, SHADER_CONSTANT_011_Y) +XE_GPU_REGISTER(0x402E, kFloat, SHADER_CONSTANT_011_Z) +XE_GPU_REGISTER(0x402F, kFloat, SHADER_CONSTANT_011_W) +XE_GPU_REGISTER(0x4030, kFloat, SHADER_CONSTANT_012_X) +XE_GPU_REGISTER(0x4031, kFloat, SHADER_CONSTANT_012_Y) +XE_GPU_REGISTER(0x4032, kFloat, SHADER_CONSTANT_012_Z) +XE_GPU_REGISTER(0x4033, kFloat, SHADER_CONSTANT_012_W) +XE_GPU_REGISTER(0x4034, kFloat, SHADER_CONSTANT_013_X) +XE_GPU_REGISTER(0x4035, kFloat, SHADER_CONSTANT_013_Y) +XE_GPU_REGISTER(0x4036, kFloat, SHADER_CONSTANT_013_Z) +XE_GPU_REGISTER(0x4037, kFloat, SHADER_CONSTANT_013_W) +XE_GPU_REGISTER(0x4038, kFloat, SHADER_CONSTANT_014_X) +XE_GPU_REGISTER(0x4039, kFloat, SHADER_CONSTANT_014_Y) +XE_GPU_REGISTER(0x403A, kFloat, SHADER_CONSTANT_014_Z) +XE_GPU_REGISTER(0x403B, kFloat, SHADER_CONSTANT_014_W) +XE_GPU_REGISTER(0x403C, kFloat, SHADER_CONSTANT_015_X) +XE_GPU_REGISTER(0x403D, kFloat, SHADER_CONSTANT_015_Y) +XE_GPU_REGISTER(0x403E, kFloat, SHADER_CONSTANT_015_Z) +XE_GPU_REGISTER(0x403F, kFloat, SHADER_CONSTANT_015_W) +XE_GPU_REGISTER(0x4040, kFloat, SHADER_CONSTANT_016_X) +XE_GPU_REGISTER(0x4041, kFloat, SHADER_CONSTANT_016_Y) +XE_GPU_REGISTER(0x4042, kFloat, SHADER_CONSTANT_016_Z) +XE_GPU_REGISTER(0x4043, kFloat, SHADER_CONSTANT_016_W) +XE_GPU_REGISTER(0x4044, kFloat, SHADER_CONSTANT_017_X) +XE_GPU_REGISTER(0x4045, kFloat, SHADER_CONSTANT_017_Y) +XE_GPU_REGISTER(0x4046, kFloat, SHADER_CONSTANT_017_Z) +XE_GPU_REGISTER(0x4047, kFloat, SHADER_CONSTANT_017_W) +XE_GPU_REGISTER(0x4048, kFloat, SHADER_CONSTANT_018_X) +XE_GPU_REGISTER(0x4049, kFloat, SHADER_CONSTANT_018_Y) +XE_GPU_REGISTER(0x404A, kFloat, SHADER_CONSTANT_018_Z) +XE_GPU_REGISTER(0x404B, kFloat, SHADER_CONSTANT_018_W) +XE_GPU_REGISTER(0x404C, kFloat, SHADER_CONSTANT_019_X) +XE_GPU_REGISTER(0x404D, kFloat, SHADER_CONSTANT_019_Y) +XE_GPU_REGISTER(0x404E, kFloat, SHADER_CONSTANT_019_Z) +XE_GPU_REGISTER(0x404F, kFloat, SHADER_CONSTANT_019_W) +XE_GPU_REGISTER(0x4050, kFloat, SHADER_CONSTANT_020_X) +XE_GPU_REGISTER(0x4051, kFloat, SHADER_CONSTANT_020_Y) +XE_GPU_REGISTER(0x4052, kFloat, SHADER_CONSTANT_020_Z) +XE_GPU_REGISTER(0x4053, kFloat, SHADER_CONSTANT_020_W) +XE_GPU_REGISTER(0x4054, kFloat, SHADER_CONSTANT_021_X) +XE_GPU_REGISTER(0x4055, kFloat, SHADER_CONSTANT_021_Y) +XE_GPU_REGISTER(0x4056, kFloat, SHADER_CONSTANT_021_Z) +XE_GPU_REGISTER(0x4057, kFloat, SHADER_CONSTANT_021_W) +XE_GPU_REGISTER(0x4058, kFloat, SHADER_CONSTANT_022_X) +XE_GPU_REGISTER(0x4059, kFloat, SHADER_CONSTANT_022_Y) +XE_GPU_REGISTER(0x405A, kFloat, SHADER_CONSTANT_022_Z) +XE_GPU_REGISTER(0x405B, kFloat, SHADER_CONSTANT_022_W) +XE_GPU_REGISTER(0x405C, kFloat, SHADER_CONSTANT_023_X) +XE_GPU_REGISTER(0x405D, kFloat, SHADER_CONSTANT_023_Y) +XE_GPU_REGISTER(0x405E, kFloat, SHADER_CONSTANT_023_Z) +XE_GPU_REGISTER(0x405F, kFloat, SHADER_CONSTANT_023_W) +XE_GPU_REGISTER(0x4060, kFloat, SHADER_CONSTANT_024_X) +XE_GPU_REGISTER(0x4061, kFloat, SHADER_CONSTANT_024_Y) +XE_GPU_REGISTER(0x4062, kFloat, SHADER_CONSTANT_024_Z) +XE_GPU_REGISTER(0x4063, kFloat, SHADER_CONSTANT_024_W) +XE_GPU_REGISTER(0x4064, kFloat, SHADER_CONSTANT_025_X) +XE_GPU_REGISTER(0x4065, kFloat, SHADER_CONSTANT_025_Y) +XE_GPU_REGISTER(0x4066, kFloat, SHADER_CONSTANT_025_Z) +XE_GPU_REGISTER(0x4067, kFloat, SHADER_CONSTANT_025_W) +XE_GPU_REGISTER(0x4068, kFloat, SHADER_CONSTANT_026_X) +XE_GPU_REGISTER(0x4069, kFloat, SHADER_CONSTANT_026_Y) +XE_GPU_REGISTER(0x406A, kFloat, SHADER_CONSTANT_026_Z) +XE_GPU_REGISTER(0x406B, kFloat, SHADER_CONSTANT_026_W) +XE_GPU_REGISTER(0x406C, kFloat, SHADER_CONSTANT_027_X) +XE_GPU_REGISTER(0x406D, kFloat, SHADER_CONSTANT_027_Y) +XE_GPU_REGISTER(0x406E, kFloat, SHADER_CONSTANT_027_Z) +XE_GPU_REGISTER(0x406F, kFloat, SHADER_CONSTANT_027_W) +XE_GPU_REGISTER(0x4070, kFloat, SHADER_CONSTANT_028_X) +XE_GPU_REGISTER(0x4071, kFloat, SHADER_CONSTANT_028_Y) +XE_GPU_REGISTER(0x4072, kFloat, SHADER_CONSTANT_028_Z) +XE_GPU_REGISTER(0x4073, kFloat, SHADER_CONSTANT_028_W) +XE_GPU_REGISTER(0x4074, kFloat, SHADER_CONSTANT_029_X) +XE_GPU_REGISTER(0x4075, kFloat, SHADER_CONSTANT_029_Y) +XE_GPU_REGISTER(0x4076, kFloat, SHADER_CONSTANT_029_Z) +XE_GPU_REGISTER(0x4077, kFloat, SHADER_CONSTANT_029_W) +XE_GPU_REGISTER(0x4078, kFloat, SHADER_CONSTANT_030_X) +XE_GPU_REGISTER(0x4079, kFloat, SHADER_CONSTANT_030_Y) +XE_GPU_REGISTER(0x407A, kFloat, SHADER_CONSTANT_030_Z) +XE_GPU_REGISTER(0x407B, kFloat, SHADER_CONSTANT_030_W) +XE_GPU_REGISTER(0x407C, kFloat, SHADER_CONSTANT_031_X) +XE_GPU_REGISTER(0x407D, kFloat, SHADER_CONSTANT_031_Y) +XE_GPU_REGISTER(0x407E, kFloat, SHADER_CONSTANT_031_Z) +XE_GPU_REGISTER(0x407F, kFloat, SHADER_CONSTANT_031_W) +XE_GPU_REGISTER(0x4080, kFloat, SHADER_CONSTANT_032_X) +XE_GPU_REGISTER(0x4081, kFloat, SHADER_CONSTANT_032_Y) +XE_GPU_REGISTER(0x4082, kFloat, SHADER_CONSTANT_032_Z) +XE_GPU_REGISTER(0x4083, kFloat, SHADER_CONSTANT_032_W) +XE_GPU_REGISTER(0x4084, kFloat, SHADER_CONSTANT_033_X) +XE_GPU_REGISTER(0x4085, kFloat, SHADER_CONSTANT_033_Y) +XE_GPU_REGISTER(0x4086, kFloat, SHADER_CONSTANT_033_Z) +XE_GPU_REGISTER(0x4087, kFloat, SHADER_CONSTANT_033_W) +XE_GPU_REGISTER(0x4088, kFloat, SHADER_CONSTANT_034_X) +XE_GPU_REGISTER(0x4089, kFloat, SHADER_CONSTANT_034_Y) +XE_GPU_REGISTER(0x408A, kFloat, SHADER_CONSTANT_034_Z) +XE_GPU_REGISTER(0x408B, kFloat, SHADER_CONSTANT_034_W) +XE_GPU_REGISTER(0x408C, kFloat, SHADER_CONSTANT_035_X) +XE_GPU_REGISTER(0x408D, kFloat, SHADER_CONSTANT_035_Y) +XE_GPU_REGISTER(0x408E, kFloat, SHADER_CONSTANT_035_Z) +XE_GPU_REGISTER(0x408F, kFloat, SHADER_CONSTANT_035_W) +XE_GPU_REGISTER(0x4090, kFloat, SHADER_CONSTANT_036_X) +XE_GPU_REGISTER(0x4091, kFloat, SHADER_CONSTANT_036_Y) +XE_GPU_REGISTER(0x4092, kFloat, SHADER_CONSTANT_036_Z) +XE_GPU_REGISTER(0x4093, kFloat, SHADER_CONSTANT_036_W) +XE_GPU_REGISTER(0x4094, kFloat, SHADER_CONSTANT_037_X) +XE_GPU_REGISTER(0x4095, kFloat, SHADER_CONSTANT_037_Y) +XE_GPU_REGISTER(0x4096, kFloat, SHADER_CONSTANT_037_Z) +XE_GPU_REGISTER(0x4097, kFloat, SHADER_CONSTANT_037_W) +XE_GPU_REGISTER(0x4098, kFloat, SHADER_CONSTANT_038_X) +XE_GPU_REGISTER(0x4099, kFloat, SHADER_CONSTANT_038_Y) +XE_GPU_REGISTER(0x409A, kFloat, SHADER_CONSTANT_038_Z) +XE_GPU_REGISTER(0x409B, kFloat, SHADER_CONSTANT_038_W) +XE_GPU_REGISTER(0x409C, kFloat, SHADER_CONSTANT_039_X) +XE_GPU_REGISTER(0x409D, kFloat, SHADER_CONSTANT_039_Y) +XE_GPU_REGISTER(0x409E, kFloat, SHADER_CONSTANT_039_Z) +XE_GPU_REGISTER(0x409F, kFloat, SHADER_CONSTANT_039_W) +XE_GPU_REGISTER(0x40A0, kFloat, SHADER_CONSTANT_040_X) +XE_GPU_REGISTER(0x40A1, kFloat, SHADER_CONSTANT_040_Y) +XE_GPU_REGISTER(0x40A2, kFloat, SHADER_CONSTANT_040_Z) +XE_GPU_REGISTER(0x40A3, kFloat, SHADER_CONSTANT_040_W) +XE_GPU_REGISTER(0x40A4, kFloat, SHADER_CONSTANT_041_X) +XE_GPU_REGISTER(0x40A5, kFloat, SHADER_CONSTANT_041_Y) +XE_GPU_REGISTER(0x40A6, kFloat, SHADER_CONSTANT_041_Z) +XE_GPU_REGISTER(0x40A7, kFloat, SHADER_CONSTANT_041_W) +XE_GPU_REGISTER(0x40A8, kFloat, SHADER_CONSTANT_042_X) +XE_GPU_REGISTER(0x40A9, kFloat, SHADER_CONSTANT_042_Y) +XE_GPU_REGISTER(0x40AA, kFloat, SHADER_CONSTANT_042_Z) +XE_GPU_REGISTER(0x40AB, kFloat, SHADER_CONSTANT_042_W) +XE_GPU_REGISTER(0x40AC, kFloat, SHADER_CONSTANT_043_X) +XE_GPU_REGISTER(0x40AD, kFloat, SHADER_CONSTANT_043_Y) +XE_GPU_REGISTER(0x40AE, kFloat, SHADER_CONSTANT_043_Z) +XE_GPU_REGISTER(0x40AF, kFloat, SHADER_CONSTANT_043_W) +XE_GPU_REGISTER(0x40B0, kFloat, SHADER_CONSTANT_044_X) +XE_GPU_REGISTER(0x40B1, kFloat, SHADER_CONSTANT_044_Y) +XE_GPU_REGISTER(0x40B2, kFloat, SHADER_CONSTANT_044_Z) +XE_GPU_REGISTER(0x40B3, kFloat, SHADER_CONSTANT_044_W) +XE_GPU_REGISTER(0x40B4, kFloat, SHADER_CONSTANT_045_X) +XE_GPU_REGISTER(0x40B5, kFloat, SHADER_CONSTANT_045_Y) +XE_GPU_REGISTER(0x40B6, kFloat, SHADER_CONSTANT_045_Z) +XE_GPU_REGISTER(0x40B7, kFloat, SHADER_CONSTANT_045_W) +XE_GPU_REGISTER(0x40B8, kFloat, SHADER_CONSTANT_046_X) +XE_GPU_REGISTER(0x40B9, kFloat, SHADER_CONSTANT_046_Y) +XE_GPU_REGISTER(0x40BA, kFloat, SHADER_CONSTANT_046_Z) +XE_GPU_REGISTER(0x40BB, kFloat, SHADER_CONSTANT_046_W) +XE_GPU_REGISTER(0x40BC, kFloat, SHADER_CONSTANT_047_X) +XE_GPU_REGISTER(0x40BD, kFloat, SHADER_CONSTANT_047_Y) +XE_GPU_REGISTER(0x40BE, kFloat, SHADER_CONSTANT_047_Z) +XE_GPU_REGISTER(0x40BF, kFloat, SHADER_CONSTANT_047_W) +XE_GPU_REGISTER(0x40C0, kFloat, SHADER_CONSTANT_048_X) +XE_GPU_REGISTER(0x40C1, kFloat, SHADER_CONSTANT_048_Y) +XE_GPU_REGISTER(0x40C2, kFloat, SHADER_CONSTANT_048_Z) +XE_GPU_REGISTER(0x40C3, kFloat, SHADER_CONSTANT_048_W) +XE_GPU_REGISTER(0x40C4, kFloat, SHADER_CONSTANT_049_X) +XE_GPU_REGISTER(0x40C5, kFloat, SHADER_CONSTANT_049_Y) +XE_GPU_REGISTER(0x40C6, kFloat, SHADER_CONSTANT_049_Z) +XE_GPU_REGISTER(0x40C7, kFloat, SHADER_CONSTANT_049_W) +XE_GPU_REGISTER(0x40C8, kFloat, SHADER_CONSTANT_050_X) +XE_GPU_REGISTER(0x40C9, kFloat, SHADER_CONSTANT_050_Y) +XE_GPU_REGISTER(0x40CA, kFloat, SHADER_CONSTANT_050_Z) +XE_GPU_REGISTER(0x40CB, kFloat, SHADER_CONSTANT_050_W) +XE_GPU_REGISTER(0x40CC, kFloat, SHADER_CONSTANT_051_X) +XE_GPU_REGISTER(0x40CD, kFloat, SHADER_CONSTANT_051_Y) +XE_GPU_REGISTER(0x40CE, kFloat, SHADER_CONSTANT_051_Z) +XE_GPU_REGISTER(0x40CF, kFloat, SHADER_CONSTANT_051_W) +XE_GPU_REGISTER(0x40D0, kFloat, SHADER_CONSTANT_052_X) +XE_GPU_REGISTER(0x40D1, kFloat, SHADER_CONSTANT_052_Y) +XE_GPU_REGISTER(0x40D2, kFloat, SHADER_CONSTANT_052_Z) +XE_GPU_REGISTER(0x40D3, kFloat, SHADER_CONSTANT_052_W) +XE_GPU_REGISTER(0x40D4, kFloat, SHADER_CONSTANT_053_X) +XE_GPU_REGISTER(0x40D5, kFloat, SHADER_CONSTANT_053_Y) +XE_GPU_REGISTER(0x40D6, kFloat, SHADER_CONSTANT_053_Z) +XE_GPU_REGISTER(0x40D7, kFloat, SHADER_CONSTANT_053_W) +XE_GPU_REGISTER(0x40D8, kFloat, SHADER_CONSTANT_054_X) +XE_GPU_REGISTER(0x40D9, kFloat, SHADER_CONSTANT_054_Y) +XE_GPU_REGISTER(0x40DA, kFloat, SHADER_CONSTANT_054_Z) +XE_GPU_REGISTER(0x40DB, kFloat, SHADER_CONSTANT_054_W) +XE_GPU_REGISTER(0x40DC, kFloat, SHADER_CONSTANT_055_X) +XE_GPU_REGISTER(0x40DD, kFloat, SHADER_CONSTANT_055_Y) +XE_GPU_REGISTER(0x40DE, kFloat, SHADER_CONSTANT_055_Z) +XE_GPU_REGISTER(0x40DF, kFloat, SHADER_CONSTANT_055_W) +XE_GPU_REGISTER(0x40E0, kFloat, SHADER_CONSTANT_056_X) +XE_GPU_REGISTER(0x40E1, kFloat, SHADER_CONSTANT_056_Y) +XE_GPU_REGISTER(0x40E2, kFloat, SHADER_CONSTANT_056_Z) +XE_GPU_REGISTER(0x40E3, kFloat, SHADER_CONSTANT_056_W) +XE_GPU_REGISTER(0x40E4, kFloat, SHADER_CONSTANT_057_X) +XE_GPU_REGISTER(0x40E5, kFloat, SHADER_CONSTANT_057_Y) +XE_GPU_REGISTER(0x40E6, kFloat, SHADER_CONSTANT_057_Z) +XE_GPU_REGISTER(0x40E7, kFloat, SHADER_CONSTANT_057_W) +XE_GPU_REGISTER(0x40E8, kFloat, SHADER_CONSTANT_058_X) +XE_GPU_REGISTER(0x40E9, kFloat, SHADER_CONSTANT_058_Y) +XE_GPU_REGISTER(0x40EA, kFloat, SHADER_CONSTANT_058_Z) +XE_GPU_REGISTER(0x40EB, kFloat, SHADER_CONSTANT_058_W) +XE_GPU_REGISTER(0x40EC, kFloat, SHADER_CONSTANT_059_X) +XE_GPU_REGISTER(0x40ED, kFloat, SHADER_CONSTANT_059_Y) +XE_GPU_REGISTER(0x40EE, kFloat, SHADER_CONSTANT_059_Z) +XE_GPU_REGISTER(0x40EF, kFloat, SHADER_CONSTANT_059_W) +XE_GPU_REGISTER(0x40F0, kFloat, SHADER_CONSTANT_060_X) +XE_GPU_REGISTER(0x40F1, kFloat, SHADER_CONSTANT_060_Y) +XE_GPU_REGISTER(0x40F2, kFloat, SHADER_CONSTANT_060_Z) +XE_GPU_REGISTER(0x40F3, kFloat, SHADER_CONSTANT_060_W) +XE_GPU_REGISTER(0x40F4, kFloat, SHADER_CONSTANT_061_X) +XE_GPU_REGISTER(0x40F5, kFloat, SHADER_CONSTANT_061_Y) +XE_GPU_REGISTER(0x40F6, kFloat, SHADER_CONSTANT_061_Z) +XE_GPU_REGISTER(0x40F7, kFloat, SHADER_CONSTANT_061_W) +XE_GPU_REGISTER(0x40F8, kFloat, SHADER_CONSTANT_062_X) +XE_GPU_REGISTER(0x40F9, kFloat, SHADER_CONSTANT_062_Y) +XE_GPU_REGISTER(0x40FA, kFloat, SHADER_CONSTANT_062_Z) +XE_GPU_REGISTER(0x40FB, kFloat, SHADER_CONSTANT_062_W) +XE_GPU_REGISTER(0x40FC, kFloat, SHADER_CONSTANT_063_X) +XE_GPU_REGISTER(0x40FD, kFloat, SHADER_CONSTANT_063_Y) +XE_GPU_REGISTER(0x40FE, kFloat, SHADER_CONSTANT_063_Z) +XE_GPU_REGISTER(0x40FF, kFloat, SHADER_CONSTANT_063_W) +XE_GPU_REGISTER(0x4100, kFloat, SHADER_CONSTANT_064_X) +XE_GPU_REGISTER(0x4101, kFloat, SHADER_CONSTANT_064_Y) +XE_GPU_REGISTER(0x4102, kFloat, SHADER_CONSTANT_064_Z) +XE_GPU_REGISTER(0x4103, kFloat, SHADER_CONSTANT_064_W) +XE_GPU_REGISTER(0x4104, kFloat, SHADER_CONSTANT_065_X) +XE_GPU_REGISTER(0x4105, kFloat, SHADER_CONSTANT_065_Y) +XE_GPU_REGISTER(0x4106, kFloat, SHADER_CONSTANT_065_Z) +XE_GPU_REGISTER(0x4107, kFloat, SHADER_CONSTANT_065_W) +XE_GPU_REGISTER(0x4108, kFloat, SHADER_CONSTANT_066_X) +XE_GPU_REGISTER(0x4109, kFloat, SHADER_CONSTANT_066_Y) +XE_GPU_REGISTER(0x410A, kFloat, SHADER_CONSTANT_066_Z) +XE_GPU_REGISTER(0x410B, kFloat, SHADER_CONSTANT_066_W) +XE_GPU_REGISTER(0x410C, kFloat, SHADER_CONSTANT_067_X) +XE_GPU_REGISTER(0x410D, kFloat, SHADER_CONSTANT_067_Y) +XE_GPU_REGISTER(0x410E, kFloat, SHADER_CONSTANT_067_Z) +XE_GPU_REGISTER(0x410F, kFloat, SHADER_CONSTANT_067_W) +XE_GPU_REGISTER(0x4110, kFloat, SHADER_CONSTANT_068_X) +XE_GPU_REGISTER(0x4111, kFloat, SHADER_CONSTANT_068_Y) +XE_GPU_REGISTER(0x4112, kFloat, SHADER_CONSTANT_068_Z) +XE_GPU_REGISTER(0x4113, kFloat, SHADER_CONSTANT_068_W) +XE_GPU_REGISTER(0x4114, kFloat, SHADER_CONSTANT_069_X) +XE_GPU_REGISTER(0x4115, kFloat, SHADER_CONSTANT_069_Y) +XE_GPU_REGISTER(0x4116, kFloat, SHADER_CONSTANT_069_Z) +XE_GPU_REGISTER(0x4117, kFloat, SHADER_CONSTANT_069_W) +XE_GPU_REGISTER(0x4118, kFloat, SHADER_CONSTANT_070_X) +XE_GPU_REGISTER(0x4119, kFloat, SHADER_CONSTANT_070_Y) +XE_GPU_REGISTER(0x411A, kFloat, SHADER_CONSTANT_070_Z) +XE_GPU_REGISTER(0x411B, kFloat, SHADER_CONSTANT_070_W) +XE_GPU_REGISTER(0x411C, kFloat, SHADER_CONSTANT_071_X) +XE_GPU_REGISTER(0x411D, kFloat, SHADER_CONSTANT_071_Y) +XE_GPU_REGISTER(0x411E, kFloat, SHADER_CONSTANT_071_Z) +XE_GPU_REGISTER(0x411F, kFloat, SHADER_CONSTANT_071_W) +XE_GPU_REGISTER(0x4120, kFloat, SHADER_CONSTANT_072_X) +XE_GPU_REGISTER(0x4121, kFloat, SHADER_CONSTANT_072_Y) +XE_GPU_REGISTER(0x4122, kFloat, SHADER_CONSTANT_072_Z) +XE_GPU_REGISTER(0x4123, kFloat, SHADER_CONSTANT_072_W) +XE_GPU_REGISTER(0x4124, kFloat, SHADER_CONSTANT_073_X) +XE_GPU_REGISTER(0x4125, kFloat, SHADER_CONSTANT_073_Y) +XE_GPU_REGISTER(0x4126, kFloat, SHADER_CONSTANT_073_Z) +XE_GPU_REGISTER(0x4127, kFloat, SHADER_CONSTANT_073_W) +XE_GPU_REGISTER(0x4128, kFloat, SHADER_CONSTANT_074_X) +XE_GPU_REGISTER(0x4129, kFloat, SHADER_CONSTANT_074_Y) +XE_GPU_REGISTER(0x412A, kFloat, SHADER_CONSTANT_074_Z) +XE_GPU_REGISTER(0x412B, kFloat, SHADER_CONSTANT_074_W) +XE_GPU_REGISTER(0x412C, kFloat, SHADER_CONSTANT_075_X) +XE_GPU_REGISTER(0x412D, kFloat, SHADER_CONSTANT_075_Y) +XE_GPU_REGISTER(0x412E, kFloat, SHADER_CONSTANT_075_Z) +XE_GPU_REGISTER(0x412F, kFloat, SHADER_CONSTANT_075_W) +XE_GPU_REGISTER(0x4130, kFloat, SHADER_CONSTANT_076_X) +XE_GPU_REGISTER(0x4131, kFloat, SHADER_CONSTANT_076_Y) +XE_GPU_REGISTER(0x4132, kFloat, SHADER_CONSTANT_076_Z) +XE_GPU_REGISTER(0x4133, kFloat, SHADER_CONSTANT_076_W) +XE_GPU_REGISTER(0x4134, kFloat, SHADER_CONSTANT_077_X) +XE_GPU_REGISTER(0x4135, kFloat, SHADER_CONSTANT_077_Y) +XE_GPU_REGISTER(0x4136, kFloat, SHADER_CONSTANT_077_Z) +XE_GPU_REGISTER(0x4137, kFloat, SHADER_CONSTANT_077_W) +XE_GPU_REGISTER(0x4138, kFloat, SHADER_CONSTANT_078_X) +XE_GPU_REGISTER(0x4139, kFloat, SHADER_CONSTANT_078_Y) +XE_GPU_REGISTER(0x413A, kFloat, SHADER_CONSTANT_078_Z) +XE_GPU_REGISTER(0x413B, kFloat, SHADER_CONSTANT_078_W) +XE_GPU_REGISTER(0x413C, kFloat, SHADER_CONSTANT_079_X) +XE_GPU_REGISTER(0x413D, kFloat, SHADER_CONSTANT_079_Y) +XE_GPU_REGISTER(0x413E, kFloat, SHADER_CONSTANT_079_Z) +XE_GPU_REGISTER(0x413F, kFloat, SHADER_CONSTANT_079_W) +XE_GPU_REGISTER(0x4140, kFloat, SHADER_CONSTANT_080_X) +XE_GPU_REGISTER(0x4141, kFloat, SHADER_CONSTANT_080_Y) +XE_GPU_REGISTER(0x4142, kFloat, SHADER_CONSTANT_080_Z) +XE_GPU_REGISTER(0x4143, kFloat, SHADER_CONSTANT_080_W) +XE_GPU_REGISTER(0x4144, kFloat, SHADER_CONSTANT_081_X) +XE_GPU_REGISTER(0x4145, kFloat, SHADER_CONSTANT_081_Y) +XE_GPU_REGISTER(0x4146, kFloat, SHADER_CONSTANT_081_Z) +XE_GPU_REGISTER(0x4147, kFloat, SHADER_CONSTANT_081_W) +XE_GPU_REGISTER(0x4148, kFloat, SHADER_CONSTANT_082_X) +XE_GPU_REGISTER(0x4149, kFloat, SHADER_CONSTANT_082_Y) +XE_GPU_REGISTER(0x414A, kFloat, SHADER_CONSTANT_082_Z) +XE_GPU_REGISTER(0x414B, kFloat, SHADER_CONSTANT_082_W) +XE_GPU_REGISTER(0x414C, kFloat, SHADER_CONSTANT_083_X) +XE_GPU_REGISTER(0x414D, kFloat, SHADER_CONSTANT_083_Y) +XE_GPU_REGISTER(0x414E, kFloat, SHADER_CONSTANT_083_Z) +XE_GPU_REGISTER(0x414F, kFloat, SHADER_CONSTANT_083_W) +XE_GPU_REGISTER(0x4150, kFloat, SHADER_CONSTANT_084_X) +XE_GPU_REGISTER(0x4151, kFloat, SHADER_CONSTANT_084_Y) +XE_GPU_REGISTER(0x4152, kFloat, SHADER_CONSTANT_084_Z) +XE_GPU_REGISTER(0x4153, kFloat, SHADER_CONSTANT_084_W) +XE_GPU_REGISTER(0x4154, kFloat, SHADER_CONSTANT_085_X) +XE_GPU_REGISTER(0x4155, kFloat, SHADER_CONSTANT_085_Y) +XE_GPU_REGISTER(0x4156, kFloat, SHADER_CONSTANT_085_Z) +XE_GPU_REGISTER(0x4157, kFloat, SHADER_CONSTANT_085_W) +XE_GPU_REGISTER(0x4158, kFloat, SHADER_CONSTANT_086_X) +XE_GPU_REGISTER(0x4159, kFloat, SHADER_CONSTANT_086_Y) +XE_GPU_REGISTER(0x415A, kFloat, SHADER_CONSTANT_086_Z) +XE_GPU_REGISTER(0x415B, kFloat, SHADER_CONSTANT_086_W) +XE_GPU_REGISTER(0x415C, kFloat, SHADER_CONSTANT_087_X) +XE_GPU_REGISTER(0x415D, kFloat, SHADER_CONSTANT_087_Y) +XE_GPU_REGISTER(0x415E, kFloat, SHADER_CONSTANT_087_Z) +XE_GPU_REGISTER(0x415F, kFloat, SHADER_CONSTANT_087_W) +XE_GPU_REGISTER(0x4160, kFloat, SHADER_CONSTANT_088_X) +XE_GPU_REGISTER(0x4161, kFloat, SHADER_CONSTANT_088_Y) +XE_GPU_REGISTER(0x4162, kFloat, SHADER_CONSTANT_088_Z) +XE_GPU_REGISTER(0x4163, kFloat, SHADER_CONSTANT_088_W) +XE_GPU_REGISTER(0x4164, kFloat, SHADER_CONSTANT_089_X) +XE_GPU_REGISTER(0x4165, kFloat, SHADER_CONSTANT_089_Y) +XE_GPU_REGISTER(0x4166, kFloat, SHADER_CONSTANT_089_Z) +XE_GPU_REGISTER(0x4167, kFloat, SHADER_CONSTANT_089_W) +XE_GPU_REGISTER(0x4168, kFloat, SHADER_CONSTANT_090_X) +XE_GPU_REGISTER(0x4169, kFloat, SHADER_CONSTANT_090_Y) +XE_GPU_REGISTER(0x416A, kFloat, SHADER_CONSTANT_090_Z) +XE_GPU_REGISTER(0x416B, kFloat, SHADER_CONSTANT_090_W) +XE_GPU_REGISTER(0x416C, kFloat, SHADER_CONSTANT_091_X) +XE_GPU_REGISTER(0x416D, kFloat, SHADER_CONSTANT_091_Y) +XE_GPU_REGISTER(0x416E, kFloat, SHADER_CONSTANT_091_Z) +XE_GPU_REGISTER(0x416F, kFloat, SHADER_CONSTANT_091_W) +XE_GPU_REGISTER(0x4170, kFloat, SHADER_CONSTANT_092_X) +XE_GPU_REGISTER(0x4171, kFloat, SHADER_CONSTANT_092_Y) +XE_GPU_REGISTER(0x4172, kFloat, SHADER_CONSTANT_092_Z) +XE_GPU_REGISTER(0x4173, kFloat, SHADER_CONSTANT_092_W) +XE_GPU_REGISTER(0x4174, kFloat, SHADER_CONSTANT_093_X) +XE_GPU_REGISTER(0x4175, kFloat, SHADER_CONSTANT_093_Y) +XE_GPU_REGISTER(0x4176, kFloat, SHADER_CONSTANT_093_Z) +XE_GPU_REGISTER(0x4177, kFloat, SHADER_CONSTANT_093_W) +XE_GPU_REGISTER(0x4178, kFloat, SHADER_CONSTANT_094_X) +XE_GPU_REGISTER(0x4179, kFloat, SHADER_CONSTANT_094_Y) +XE_GPU_REGISTER(0x417A, kFloat, SHADER_CONSTANT_094_Z) +XE_GPU_REGISTER(0x417B, kFloat, SHADER_CONSTANT_094_W) +XE_GPU_REGISTER(0x417C, kFloat, SHADER_CONSTANT_095_X) +XE_GPU_REGISTER(0x417D, kFloat, SHADER_CONSTANT_095_Y) +XE_GPU_REGISTER(0x417E, kFloat, SHADER_CONSTANT_095_Z) +XE_GPU_REGISTER(0x417F, kFloat, SHADER_CONSTANT_095_W) +XE_GPU_REGISTER(0x4180, kFloat, SHADER_CONSTANT_096_X) +XE_GPU_REGISTER(0x4181, kFloat, SHADER_CONSTANT_096_Y) +XE_GPU_REGISTER(0x4182, kFloat, SHADER_CONSTANT_096_Z) +XE_GPU_REGISTER(0x4183, kFloat, SHADER_CONSTANT_096_W) +XE_GPU_REGISTER(0x4184, kFloat, SHADER_CONSTANT_097_X) +XE_GPU_REGISTER(0x4185, kFloat, SHADER_CONSTANT_097_Y) +XE_GPU_REGISTER(0x4186, kFloat, SHADER_CONSTANT_097_Z) +XE_GPU_REGISTER(0x4187, kFloat, SHADER_CONSTANT_097_W) +XE_GPU_REGISTER(0x4188, kFloat, SHADER_CONSTANT_098_X) +XE_GPU_REGISTER(0x4189, kFloat, SHADER_CONSTANT_098_Y) +XE_GPU_REGISTER(0x418A, kFloat, SHADER_CONSTANT_098_Z) +XE_GPU_REGISTER(0x418B, kFloat, SHADER_CONSTANT_098_W) +XE_GPU_REGISTER(0x418C, kFloat, SHADER_CONSTANT_099_X) +XE_GPU_REGISTER(0x418D, kFloat, SHADER_CONSTANT_099_Y) +XE_GPU_REGISTER(0x418E, kFloat, SHADER_CONSTANT_099_Z) +XE_GPU_REGISTER(0x418F, kFloat, SHADER_CONSTANT_099_W) +XE_GPU_REGISTER(0x4190, kFloat, SHADER_CONSTANT_100_X) +XE_GPU_REGISTER(0x4191, kFloat, SHADER_CONSTANT_100_Y) +XE_GPU_REGISTER(0x4192, kFloat, SHADER_CONSTANT_100_Z) +XE_GPU_REGISTER(0x4193, kFloat, SHADER_CONSTANT_100_W) +XE_GPU_REGISTER(0x4194, kFloat, SHADER_CONSTANT_101_X) +XE_GPU_REGISTER(0x4195, kFloat, SHADER_CONSTANT_101_Y) +XE_GPU_REGISTER(0x4196, kFloat, SHADER_CONSTANT_101_Z) +XE_GPU_REGISTER(0x4197, kFloat, SHADER_CONSTANT_101_W) +XE_GPU_REGISTER(0x4198, kFloat, SHADER_CONSTANT_102_X) +XE_GPU_REGISTER(0x4199, kFloat, SHADER_CONSTANT_102_Y) +XE_GPU_REGISTER(0x419A, kFloat, SHADER_CONSTANT_102_Z) +XE_GPU_REGISTER(0x419B, kFloat, SHADER_CONSTANT_102_W) +XE_GPU_REGISTER(0x419C, kFloat, SHADER_CONSTANT_103_X) +XE_GPU_REGISTER(0x419D, kFloat, SHADER_CONSTANT_103_Y) +XE_GPU_REGISTER(0x419E, kFloat, SHADER_CONSTANT_103_Z) +XE_GPU_REGISTER(0x419F, kFloat, SHADER_CONSTANT_103_W) +XE_GPU_REGISTER(0x41A0, kFloat, SHADER_CONSTANT_104_X) +XE_GPU_REGISTER(0x41A1, kFloat, SHADER_CONSTANT_104_Y) +XE_GPU_REGISTER(0x41A2, kFloat, SHADER_CONSTANT_104_Z) +XE_GPU_REGISTER(0x41A3, kFloat, SHADER_CONSTANT_104_W) +XE_GPU_REGISTER(0x41A4, kFloat, SHADER_CONSTANT_105_X) +XE_GPU_REGISTER(0x41A5, kFloat, SHADER_CONSTANT_105_Y) +XE_GPU_REGISTER(0x41A6, kFloat, SHADER_CONSTANT_105_Z) +XE_GPU_REGISTER(0x41A7, kFloat, SHADER_CONSTANT_105_W) +XE_GPU_REGISTER(0x41A8, kFloat, SHADER_CONSTANT_106_X) +XE_GPU_REGISTER(0x41A9, kFloat, SHADER_CONSTANT_106_Y) +XE_GPU_REGISTER(0x41AA, kFloat, SHADER_CONSTANT_106_Z) +XE_GPU_REGISTER(0x41AB, kFloat, SHADER_CONSTANT_106_W) +XE_GPU_REGISTER(0x41AC, kFloat, SHADER_CONSTANT_107_X) +XE_GPU_REGISTER(0x41AD, kFloat, SHADER_CONSTANT_107_Y) +XE_GPU_REGISTER(0x41AE, kFloat, SHADER_CONSTANT_107_Z) +XE_GPU_REGISTER(0x41AF, kFloat, SHADER_CONSTANT_107_W) +XE_GPU_REGISTER(0x41B0, kFloat, SHADER_CONSTANT_108_X) +XE_GPU_REGISTER(0x41B1, kFloat, SHADER_CONSTANT_108_Y) +XE_GPU_REGISTER(0x41B2, kFloat, SHADER_CONSTANT_108_Z) +XE_GPU_REGISTER(0x41B3, kFloat, SHADER_CONSTANT_108_W) +XE_GPU_REGISTER(0x41B4, kFloat, SHADER_CONSTANT_109_X) +XE_GPU_REGISTER(0x41B5, kFloat, SHADER_CONSTANT_109_Y) +XE_GPU_REGISTER(0x41B6, kFloat, SHADER_CONSTANT_109_Z) +XE_GPU_REGISTER(0x41B7, kFloat, SHADER_CONSTANT_109_W) +XE_GPU_REGISTER(0x41B8, kFloat, SHADER_CONSTANT_110_X) +XE_GPU_REGISTER(0x41B9, kFloat, SHADER_CONSTANT_110_Y) +XE_GPU_REGISTER(0x41BA, kFloat, SHADER_CONSTANT_110_Z) +XE_GPU_REGISTER(0x41BB, kFloat, SHADER_CONSTANT_110_W) +XE_GPU_REGISTER(0x41BC, kFloat, SHADER_CONSTANT_111_X) +XE_GPU_REGISTER(0x41BD, kFloat, SHADER_CONSTANT_111_Y) +XE_GPU_REGISTER(0x41BE, kFloat, SHADER_CONSTANT_111_Z) +XE_GPU_REGISTER(0x41BF, kFloat, SHADER_CONSTANT_111_W) +XE_GPU_REGISTER(0x41C0, kFloat, SHADER_CONSTANT_112_X) +XE_GPU_REGISTER(0x41C1, kFloat, SHADER_CONSTANT_112_Y) +XE_GPU_REGISTER(0x41C2, kFloat, SHADER_CONSTANT_112_Z) +XE_GPU_REGISTER(0x41C3, kFloat, SHADER_CONSTANT_112_W) +XE_GPU_REGISTER(0x41C4, kFloat, SHADER_CONSTANT_113_X) +XE_GPU_REGISTER(0x41C5, kFloat, SHADER_CONSTANT_113_Y) +XE_GPU_REGISTER(0x41C6, kFloat, SHADER_CONSTANT_113_Z) +XE_GPU_REGISTER(0x41C7, kFloat, SHADER_CONSTANT_113_W) +XE_GPU_REGISTER(0x41C8, kFloat, SHADER_CONSTANT_114_X) +XE_GPU_REGISTER(0x41C9, kFloat, SHADER_CONSTANT_114_Y) +XE_GPU_REGISTER(0x41CA, kFloat, SHADER_CONSTANT_114_Z) +XE_GPU_REGISTER(0x41CB, kFloat, SHADER_CONSTANT_114_W) +XE_GPU_REGISTER(0x41CC, kFloat, SHADER_CONSTANT_115_X) +XE_GPU_REGISTER(0x41CD, kFloat, SHADER_CONSTANT_115_Y) +XE_GPU_REGISTER(0x41CE, kFloat, SHADER_CONSTANT_115_Z) +XE_GPU_REGISTER(0x41CF, kFloat, SHADER_CONSTANT_115_W) +XE_GPU_REGISTER(0x41D0, kFloat, SHADER_CONSTANT_116_X) +XE_GPU_REGISTER(0x41D1, kFloat, SHADER_CONSTANT_116_Y) +XE_GPU_REGISTER(0x41D2, kFloat, SHADER_CONSTANT_116_Z) +XE_GPU_REGISTER(0x41D3, kFloat, SHADER_CONSTANT_116_W) +XE_GPU_REGISTER(0x41D4, kFloat, SHADER_CONSTANT_117_X) +XE_GPU_REGISTER(0x41D5, kFloat, SHADER_CONSTANT_117_Y) +XE_GPU_REGISTER(0x41D6, kFloat, SHADER_CONSTANT_117_Z) +XE_GPU_REGISTER(0x41D7, kFloat, SHADER_CONSTANT_117_W) +XE_GPU_REGISTER(0x41D8, kFloat, SHADER_CONSTANT_118_X) +XE_GPU_REGISTER(0x41D9, kFloat, SHADER_CONSTANT_118_Y) +XE_GPU_REGISTER(0x41DA, kFloat, SHADER_CONSTANT_118_Z) +XE_GPU_REGISTER(0x41DB, kFloat, SHADER_CONSTANT_118_W) +XE_GPU_REGISTER(0x41DC, kFloat, SHADER_CONSTANT_119_X) +XE_GPU_REGISTER(0x41DD, kFloat, SHADER_CONSTANT_119_Y) +XE_GPU_REGISTER(0x41DE, kFloat, SHADER_CONSTANT_119_Z) +XE_GPU_REGISTER(0x41DF, kFloat, SHADER_CONSTANT_119_W) +XE_GPU_REGISTER(0x41E0, kFloat, SHADER_CONSTANT_120_X) +XE_GPU_REGISTER(0x41E1, kFloat, SHADER_CONSTANT_120_Y) +XE_GPU_REGISTER(0x41E2, kFloat, SHADER_CONSTANT_120_Z) +XE_GPU_REGISTER(0x41E3, kFloat, SHADER_CONSTANT_120_W) +XE_GPU_REGISTER(0x41E4, kFloat, SHADER_CONSTANT_121_X) +XE_GPU_REGISTER(0x41E5, kFloat, SHADER_CONSTANT_121_Y) +XE_GPU_REGISTER(0x41E6, kFloat, SHADER_CONSTANT_121_Z) +XE_GPU_REGISTER(0x41E7, kFloat, SHADER_CONSTANT_121_W) +XE_GPU_REGISTER(0x41E8, kFloat, SHADER_CONSTANT_122_X) +XE_GPU_REGISTER(0x41E9, kFloat, SHADER_CONSTANT_122_Y) +XE_GPU_REGISTER(0x41EA, kFloat, SHADER_CONSTANT_122_Z) +XE_GPU_REGISTER(0x41EB, kFloat, SHADER_CONSTANT_122_W) +XE_GPU_REGISTER(0x41EC, kFloat, SHADER_CONSTANT_123_X) +XE_GPU_REGISTER(0x41ED, kFloat, SHADER_CONSTANT_123_Y) +XE_GPU_REGISTER(0x41EE, kFloat, SHADER_CONSTANT_123_Z) +XE_GPU_REGISTER(0x41EF, kFloat, SHADER_CONSTANT_123_W) +XE_GPU_REGISTER(0x41F0, kFloat, SHADER_CONSTANT_124_X) +XE_GPU_REGISTER(0x41F1, kFloat, SHADER_CONSTANT_124_Y) +XE_GPU_REGISTER(0x41F2, kFloat, SHADER_CONSTANT_124_Z) +XE_GPU_REGISTER(0x41F3, kFloat, SHADER_CONSTANT_124_W) +XE_GPU_REGISTER(0x41F4, kFloat, SHADER_CONSTANT_125_X) +XE_GPU_REGISTER(0x41F5, kFloat, SHADER_CONSTANT_125_Y) +XE_GPU_REGISTER(0x41F6, kFloat, SHADER_CONSTANT_125_Z) +XE_GPU_REGISTER(0x41F7, kFloat, SHADER_CONSTANT_125_W) +XE_GPU_REGISTER(0x41F8, kFloat, SHADER_CONSTANT_126_X) +XE_GPU_REGISTER(0x41F9, kFloat, SHADER_CONSTANT_126_Y) +XE_GPU_REGISTER(0x41FA, kFloat, SHADER_CONSTANT_126_Z) +XE_GPU_REGISTER(0x41FB, kFloat, SHADER_CONSTANT_126_W) +XE_GPU_REGISTER(0x41FC, kFloat, SHADER_CONSTANT_127_X) +XE_GPU_REGISTER(0x41FD, kFloat, SHADER_CONSTANT_127_Y) +XE_GPU_REGISTER(0x41FE, kFloat, SHADER_CONSTANT_127_Z) +XE_GPU_REGISTER(0x41FF, kFloat, SHADER_CONSTANT_127_W) +XE_GPU_REGISTER(0x4200, kFloat, SHADER_CONSTANT_128_X) +XE_GPU_REGISTER(0x4201, kFloat, SHADER_CONSTANT_128_Y) +XE_GPU_REGISTER(0x4202, kFloat, SHADER_CONSTANT_128_Z) +XE_GPU_REGISTER(0x4203, kFloat, SHADER_CONSTANT_128_W) +XE_GPU_REGISTER(0x4204, kFloat, SHADER_CONSTANT_129_X) +XE_GPU_REGISTER(0x4205, kFloat, SHADER_CONSTANT_129_Y) +XE_GPU_REGISTER(0x4206, kFloat, SHADER_CONSTANT_129_Z) +XE_GPU_REGISTER(0x4207, kFloat, SHADER_CONSTANT_129_W) +XE_GPU_REGISTER(0x4208, kFloat, SHADER_CONSTANT_130_X) +XE_GPU_REGISTER(0x4209, kFloat, SHADER_CONSTANT_130_Y) +XE_GPU_REGISTER(0x420A, kFloat, SHADER_CONSTANT_130_Z) +XE_GPU_REGISTER(0x420B, kFloat, SHADER_CONSTANT_130_W) +XE_GPU_REGISTER(0x420C, kFloat, SHADER_CONSTANT_131_X) +XE_GPU_REGISTER(0x420D, kFloat, SHADER_CONSTANT_131_Y) +XE_GPU_REGISTER(0x420E, kFloat, SHADER_CONSTANT_131_Z) +XE_GPU_REGISTER(0x420F, kFloat, SHADER_CONSTANT_131_W) +XE_GPU_REGISTER(0x4210, kFloat, SHADER_CONSTANT_132_X) +XE_GPU_REGISTER(0x4211, kFloat, SHADER_CONSTANT_132_Y) +XE_GPU_REGISTER(0x4212, kFloat, SHADER_CONSTANT_132_Z) +XE_GPU_REGISTER(0x4213, kFloat, SHADER_CONSTANT_132_W) +XE_GPU_REGISTER(0x4214, kFloat, SHADER_CONSTANT_133_X) +XE_GPU_REGISTER(0x4215, kFloat, SHADER_CONSTANT_133_Y) +XE_GPU_REGISTER(0x4216, kFloat, SHADER_CONSTANT_133_Z) +XE_GPU_REGISTER(0x4217, kFloat, SHADER_CONSTANT_133_W) +XE_GPU_REGISTER(0x4218, kFloat, SHADER_CONSTANT_134_X) +XE_GPU_REGISTER(0x4219, kFloat, SHADER_CONSTANT_134_Y) +XE_GPU_REGISTER(0x421A, kFloat, SHADER_CONSTANT_134_Z) +XE_GPU_REGISTER(0x421B, kFloat, SHADER_CONSTANT_134_W) +XE_GPU_REGISTER(0x421C, kFloat, SHADER_CONSTANT_135_X) +XE_GPU_REGISTER(0x421D, kFloat, SHADER_CONSTANT_135_Y) +XE_GPU_REGISTER(0x421E, kFloat, SHADER_CONSTANT_135_Z) +XE_GPU_REGISTER(0x421F, kFloat, SHADER_CONSTANT_135_W) +XE_GPU_REGISTER(0x4220, kFloat, SHADER_CONSTANT_136_X) +XE_GPU_REGISTER(0x4221, kFloat, SHADER_CONSTANT_136_Y) +XE_GPU_REGISTER(0x4222, kFloat, SHADER_CONSTANT_136_Z) +XE_GPU_REGISTER(0x4223, kFloat, SHADER_CONSTANT_136_W) +XE_GPU_REGISTER(0x4224, kFloat, SHADER_CONSTANT_137_X) +XE_GPU_REGISTER(0x4225, kFloat, SHADER_CONSTANT_137_Y) +XE_GPU_REGISTER(0x4226, kFloat, SHADER_CONSTANT_137_Z) +XE_GPU_REGISTER(0x4227, kFloat, SHADER_CONSTANT_137_W) +XE_GPU_REGISTER(0x4228, kFloat, SHADER_CONSTANT_138_X) +XE_GPU_REGISTER(0x4229, kFloat, SHADER_CONSTANT_138_Y) +XE_GPU_REGISTER(0x422A, kFloat, SHADER_CONSTANT_138_Z) +XE_GPU_REGISTER(0x422B, kFloat, SHADER_CONSTANT_138_W) +XE_GPU_REGISTER(0x422C, kFloat, SHADER_CONSTANT_139_X) +XE_GPU_REGISTER(0x422D, kFloat, SHADER_CONSTANT_139_Y) +XE_GPU_REGISTER(0x422E, kFloat, SHADER_CONSTANT_139_Z) +XE_GPU_REGISTER(0x422F, kFloat, SHADER_CONSTANT_139_W) +XE_GPU_REGISTER(0x4230, kFloat, SHADER_CONSTANT_140_X) +XE_GPU_REGISTER(0x4231, kFloat, SHADER_CONSTANT_140_Y) +XE_GPU_REGISTER(0x4232, kFloat, SHADER_CONSTANT_140_Z) +XE_GPU_REGISTER(0x4233, kFloat, SHADER_CONSTANT_140_W) +XE_GPU_REGISTER(0x4234, kFloat, SHADER_CONSTANT_141_X) +XE_GPU_REGISTER(0x4235, kFloat, SHADER_CONSTANT_141_Y) +XE_GPU_REGISTER(0x4236, kFloat, SHADER_CONSTANT_141_Z) +XE_GPU_REGISTER(0x4237, kFloat, SHADER_CONSTANT_141_W) +XE_GPU_REGISTER(0x4238, kFloat, SHADER_CONSTANT_142_X) +XE_GPU_REGISTER(0x4239, kFloat, SHADER_CONSTANT_142_Y) +XE_GPU_REGISTER(0x423A, kFloat, SHADER_CONSTANT_142_Z) +XE_GPU_REGISTER(0x423B, kFloat, SHADER_CONSTANT_142_W) +XE_GPU_REGISTER(0x423C, kFloat, SHADER_CONSTANT_143_X) +XE_GPU_REGISTER(0x423D, kFloat, SHADER_CONSTANT_143_Y) +XE_GPU_REGISTER(0x423E, kFloat, SHADER_CONSTANT_143_Z) +XE_GPU_REGISTER(0x423F, kFloat, SHADER_CONSTANT_143_W) +XE_GPU_REGISTER(0x4240, kFloat, SHADER_CONSTANT_144_X) +XE_GPU_REGISTER(0x4241, kFloat, SHADER_CONSTANT_144_Y) +XE_GPU_REGISTER(0x4242, kFloat, SHADER_CONSTANT_144_Z) +XE_GPU_REGISTER(0x4243, kFloat, SHADER_CONSTANT_144_W) +XE_GPU_REGISTER(0x4244, kFloat, SHADER_CONSTANT_145_X) +XE_GPU_REGISTER(0x4245, kFloat, SHADER_CONSTANT_145_Y) +XE_GPU_REGISTER(0x4246, kFloat, SHADER_CONSTANT_145_Z) +XE_GPU_REGISTER(0x4247, kFloat, SHADER_CONSTANT_145_W) +XE_GPU_REGISTER(0x4248, kFloat, SHADER_CONSTANT_146_X) +XE_GPU_REGISTER(0x4249, kFloat, SHADER_CONSTANT_146_Y) +XE_GPU_REGISTER(0x424A, kFloat, SHADER_CONSTANT_146_Z) +XE_GPU_REGISTER(0x424B, kFloat, SHADER_CONSTANT_146_W) +XE_GPU_REGISTER(0x424C, kFloat, SHADER_CONSTANT_147_X) +XE_GPU_REGISTER(0x424D, kFloat, SHADER_CONSTANT_147_Y) +XE_GPU_REGISTER(0x424E, kFloat, SHADER_CONSTANT_147_Z) +XE_GPU_REGISTER(0x424F, kFloat, SHADER_CONSTANT_147_W) +XE_GPU_REGISTER(0x4250, kFloat, SHADER_CONSTANT_148_X) +XE_GPU_REGISTER(0x4251, kFloat, SHADER_CONSTANT_148_Y) +XE_GPU_REGISTER(0x4252, kFloat, SHADER_CONSTANT_148_Z) +XE_GPU_REGISTER(0x4253, kFloat, SHADER_CONSTANT_148_W) +XE_GPU_REGISTER(0x4254, kFloat, SHADER_CONSTANT_149_X) +XE_GPU_REGISTER(0x4255, kFloat, SHADER_CONSTANT_149_Y) +XE_GPU_REGISTER(0x4256, kFloat, SHADER_CONSTANT_149_Z) +XE_GPU_REGISTER(0x4257, kFloat, SHADER_CONSTANT_149_W) +XE_GPU_REGISTER(0x4258, kFloat, SHADER_CONSTANT_150_X) +XE_GPU_REGISTER(0x4259, kFloat, SHADER_CONSTANT_150_Y) +XE_GPU_REGISTER(0x425A, kFloat, SHADER_CONSTANT_150_Z) +XE_GPU_REGISTER(0x425B, kFloat, SHADER_CONSTANT_150_W) +XE_GPU_REGISTER(0x425C, kFloat, SHADER_CONSTANT_151_X) +XE_GPU_REGISTER(0x425D, kFloat, SHADER_CONSTANT_151_Y) +XE_GPU_REGISTER(0x425E, kFloat, SHADER_CONSTANT_151_Z) +XE_GPU_REGISTER(0x425F, kFloat, SHADER_CONSTANT_151_W) +XE_GPU_REGISTER(0x4260, kFloat, SHADER_CONSTANT_152_X) +XE_GPU_REGISTER(0x4261, kFloat, SHADER_CONSTANT_152_Y) +XE_GPU_REGISTER(0x4262, kFloat, SHADER_CONSTANT_152_Z) +XE_GPU_REGISTER(0x4263, kFloat, SHADER_CONSTANT_152_W) +XE_GPU_REGISTER(0x4264, kFloat, SHADER_CONSTANT_153_X) +XE_GPU_REGISTER(0x4265, kFloat, SHADER_CONSTANT_153_Y) +XE_GPU_REGISTER(0x4266, kFloat, SHADER_CONSTANT_153_Z) +XE_GPU_REGISTER(0x4267, kFloat, SHADER_CONSTANT_153_W) +XE_GPU_REGISTER(0x4268, kFloat, SHADER_CONSTANT_154_X) +XE_GPU_REGISTER(0x4269, kFloat, SHADER_CONSTANT_154_Y) +XE_GPU_REGISTER(0x426A, kFloat, SHADER_CONSTANT_154_Z) +XE_GPU_REGISTER(0x426B, kFloat, SHADER_CONSTANT_154_W) +XE_GPU_REGISTER(0x426C, kFloat, SHADER_CONSTANT_155_X) +XE_GPU_REGISTER(0x426D, kFloat, SHADER_CONSTANT_155_Y) +XE_GPU_REGISTER(0x426E, kFloat, SHADER_CONSTANT_155_Z) +XE_GPU_REGISTER(0x426F, kFloat, SHADER_CONSTANT_155_W) +XE_GPU_REGISTER(0x4270, kFloat, SHADER_CONSTANT_156_X) +XE_GPU_REGISTER(0x4271, kFloat, SHADER_CONSTANT_156_Y) +XE_GPU_REGISTER(0x4272, kFloat, SHADER_CONSTANT_156_Z) +XE_GPU_REGISTER(0x4273, kFloat, SHADER_CONSTANT_156_W) +XE_GPU_REGISTER(0x4274, kFloat, SHADER_CONSTANT_157_X) +XE_GPU_REGISTER(0x4275, kFloat, SHADER_CONSTANT_157_Y) +XE_GPU_REGISTER(0x4276, kFloat, SHADER_CONSTANT_157_Z) +XE_GPU_REGISTER(0x4277, kFloat, SHADER_CONSTANT_157_W) +XE_GPU_REGISTER(0x4278, kFloat, SHADER_CONSTANT_158_X) +XE_GPU_REGISTER(0x4279, kFloat, SHADER_CONSTANT_158_Y) +XE_GPU_REGISTER(0x427A, kFloat, SHADER_CONSTANT_158_Z) +XE_GPU_REGISTER(0x427B, kFloat, SHADER_CONSTANT_158_W) +XE_GPU_REGISTER(0x427C, kFloat, SHADER_CONSTANT_159_X) +XE_GPU_REGISTER(0x427D, kFloat, SHADER_CONSTANT_159_Y) +XE_GPU_REGISTER(0x427E, kFloat, SHADER_CONSTANT_159_Z) +XE_GPU_REGISTER(0x427F, kFloat, SHADER_CONSTANT_159_W) +XE_GPU_REGISTER(0x4280, kFloat, SHADER_CONSTANT_160_X) +XE_GPU_REGISTER(0x4281, kFloat, SHADER_CONSTANT_160_Y) +XE_GPU_REGISTER(0x4282, kFloat, SHADER_CONSTANT_160_Z) +XE_GPU_REGISTER(0x4283, kFloat, SHADER_CONSTANT_160_W) +XE_GPU_REGISTER(0x4284, kFloat, SHADER_CONSTANT_161_X) +XE_GPU_REGISTER(0x4285, kFloat, SHADER_CONSTANT_161_Y) +XE_GPU_REGISTER(0x4286, kFloat, SHADER_CONSTANT_161_Z) +XE_GPU_REGISTER(0x4287, kFloat, SHADER_CONSTANT_161_W) +XE_GPU_REGISTER(0x4288, kFloat, SHADER_CONSTANT_162_X) +XE_GPU_REGISTER(0x4289, kFloat, SHADER_CONSTANT_162_Y) +XE_GPU_REGISTER(0x428A, kFloat, SHADER_CONSTANT_162_Z) +XE_GPU_REGISTER(0x428B, kFloat, SHADER_CONSTANT_162_W) +XE_GPU_REGISTER(0x428C, kFloat, SHADER_CONSTANT_163_X) +XE_GPU_REGISTER(0x428D, kFloat, SHADER_CONSTANT_163_Y) +XE_GPU_REGISTER(0x428E, kFloat, SHADER_CONSTANT_163_Z) +XE_GPU_REGISTER(0x428F, kFloat, SHADER_CONSTANT_163_W) +XE_GPU_REGISTER(0x4290, kFloat, SHADER_CONSTANT_164_X) +XE_GPU_REGISTER(0x4291, kFloat, SHADER_CONSTANT_164_Y) +XE_GPU_REGISTER(0x4292, kFloat, SHADER_CONSTANT_164_Z) +XE_GPU_REGISTER(0x4293, kFloat, SHADER_CONSTANT_164_W) +XE_GPU_REGISTER(0x4294, kFloat, SHADER_CONSTANT_165_X) +XE_GPU_REGISTER(0x4295, kFloat, SHADER_CONSTANT_165_Y) +XE_GPU_REGISTER(0x4296, kFloat, SHADER_CONSTANT_165_Z) +XE_GPU_REGISTER(0x4297, kFloat, SHADER_CONSTANT_165_W) +XE_GPU_REGISTER(0x4298, kFloat, SHADER_CONSTANT_166_X) +XE_GPU_REGISTER(0x4299, kFloat, SHADER_CONSTANT_166_Y) +XE_GPU_REGISTER(0x429A, kFloat, SHADER_CONSTANT_166_Z) +XE_GPU_REGISTER(0x429B, kFloat, SHADER_CONSTANT_166_W) +XE_GPU_REGISTER(0x429C, kFloat, SHADER_CONSTANT_167_X) +XE_GPU_REGISTER(0x429D, kFloat, SHADER_CONSTANT_167_Y) +XE_GPU_REGISTER(0x429E, kFloat, SHADER_CONSTANT_167_Z) +XE_GPU_REGISTER(0x429F, kFloat, SHADER_CONSTANT_167_W) +XE_GPU_REGISTER(0x42A0, kFloat, SHADER_CONSTANT_168_X) +XE_GPU_REGISTER(0x42A1, kFloat, SHADER_CONSTANT_168_Y) +XE_GPU_REGISTER(0x42A2, kFloat, SHADER_CONSTANT_168_Z) +XE_GPU_REGISTER(0x42A3, kFloat, SHADER_CONSTANT_168_W) +XE_GPU_REGISTER(0x42A4, kFloat, SHADER_CONSTANT_169_X) +XE_GPU_REGISTER(0x42A5, kFloat, SHADER_CONSTANT_169_Y) +XE_GPU_REGISTER(0x42A6, kFloat, SHADER_CONSTANT_169_Z) +XE_GPU_REGISTER(0x42A7, kFloat, SHADER_CONSTANT_169_W) +XE_GPU_REGISTER(0x42A8, kFloat, SHADER_CONSTANT_170_X) +XE_GPU_REGISTER(0x42A9, kFloat, SHADER_CONSTANT_170_Y) +XE_GPU_REGISTER(0x42AA, kFloat, SHADER_CONSTANT_170_Z) +XE_GPU_REGISTER(0x42AB, kFloat, SHADER_CONSTANT_170_W) +XE_GPU_REGISTER(0x42AC, kFloat, SHADER_CONSTANT_171_X) +XE_GPU_REGISTER(0x42AD, kFloat, SHADER_CONSTANT_171_Y) +XE_GPU_REGISTER(0x42AE, kFloat, SHADER_CONSTANT_171_Z) +XE_GPU_REGISTER(0x42AF, kFloat, SHADER_CONSTANT_171_W) +XE_GPU_REGISTER(0x42B0, kFloat, SHADER_CONSTANT_172_X) +XE_GPU_REGISTER(0x42B1, kFloat, SHADER_CONSTANT_172_Y) +XE_GPU_REGISTER(0x42B2, kFloat, SHADER_CONSTANT_172_Z) +XE_GPU_REGISTER(0x42B3, kFloat, SHADER_CONSTANT_172_W) +XE_GPU_REGISTER(0x42B4, kFloat, SHADER_CONSTANT_173_X) +XE_GPU_REGISTER(0x42B5, kFloat, SHADER_CONSTANT_173_Y) +XE_GPU_REGISTER(0x42B6, kFloat, SHADER_CONSTANT_173_Z) +XE_GPU_REGISTER(0x42B7, kFloat, SHADER_CONSTANT_173_W) +XE_GPU_REGISTER(0x42B8, kFloat, SHADER_CONSTANT_174_X) +XE_GPU_REGISTER(0x42B9, kFloat, SHADER_CONSTANT_174_Y) +XE_GPU_REGISTER(0x42BA, kFloat, SHADER_CONSTANT_174_Z) +XE_GPU_REGISTER(0x42BB, kFloat, SHADER_CONSTANT_174_W) +XE_GPU_REGISTER(0x42BC, kFloat, SHADER_CONSTANT_175_X) +XE_GPU_REGISTER(0x42BD, kFloat, SHADER_CONSTANT_175_Y) +XE_GPU_REGISTER(0x42BE, kFloat, SHADER_CONSTANT_175_Z) +XE_GPU_REGISTER(0x42BF, kFloat, SHADER_CONSTANT_175_W) +XE_GPU_REGISTER(0x42C0, kFloat, SHADER_CONSTANT_176_X) +XE_GPU_REGISTER(0x42C1, kFloat, SHADER_CONSTANT_176_Y) +XE_GPU_REGISTER(0x42C2, kFloat, SHADER_CONSTANT_176_Z) +XE_GPU_REGISTER(0x42C3, kFloat, SHADER_CONSTANT_176_W) +XE_GPU_REGISTER(0x42C4, kFloat, SHADER_CONSTANT_177_X) +XE_GPU_REGISTER(0x42C5, kFloat, SHADER_CONSTANT_177_Y) +XE_GPU_REGISTER(0x42C6, kFloat, SHADER_CONSTANT_177_Z) +XE_GPU_REGISTER(0x42C7, kFloat, SHADER_CONSTANT_177_W) +XE_GPU_REGISTER(0x42C8, kFloat, SHADER_CONSTANT_178_X) +XE_GPU_REGISTER(0x42C9, kFloat, SHADER_CONSTANT_178_Y) +XE_GPU_REGISTER(0x42CA, kFloat, SHADER_CONSTANT_178_Z) +XE_GPU_REGISTER(0x42CB, kFloat, SHADER_CONSTANT_178_W) +XE_GPU_REGISTER(0x42CC, kFloat, SHADER_CONSTANT_179_X) +XE_GPU_REGISTER(0x42CD, kFloat, SHADER_CONSTANT_179_Y) +XE_GPU_REGISTER(0x42CE, kFloat, SHADER_CONSTANT_179_Z) +XE_GPU_REGISTER(0x42CF, kFloat, SHADER_CONSTANT_179_W) +XE_GPU_REGISTER(0x42D0, kFloat, SHADER_CONSTANT_180_X) +XE_GPU_REGISTER(0x42D1, kFloat, SHADER_CONSTANT_180_Y) +XE_GPU_REGISTER(0x42D2, kFloat, SHADER_CONSTANT_180_Z) +XE_GPU_REGISTER(0x42D3, kFloat, SHADER_CONSTANT_180_W) +XE_GPU_REGISTER(0x42D4, kFloat, SHADER_CONSTANT_181_X) +XE_GPU_REGISTER(0x42D5, kFloat, SHADER_CONSTANT_181_Y) +XE_GPU_REGISTER(0x42D6, kFloat, SHADER_CONSTANT_181_Z) +XE_GPU_REGISTER(0x42D7, kFloat, SHADER_CONSTANT_181_W) +XE_GPU_REGISTER(0x42D8, kFloat, SHADER_CONSTANT_182_X) +XE_GPU_REGISTER(0x42D9, kFloat, SHADER_CONSTANT_182_Y) +XE_GPU_REGISTER(0x42DA, kFloat, SHADER_CONSTANT_182_Z) +XE_GPU_REGISTER(0x42DB, kFloat, SHADER_CONSTANT_182_W) +XE_GPU_REGISTER(0x42DC, kFloat, SHADER_CONSTANT_183_X) +XE_GPU_REGISTER(0x42DD, kFloat, SHADER_CONSTANT_183_Y) +XE_GPU_REGISTER(0x42DE, kFloat, SHADER_CONSTANT_183_Z) +XE_GPU_REGISTER(0x42DF, kFloat, SHADER_CONSTANT_183_W) +XE_GPU_REGISTER(0x42E0, kFloat, SHADER_CONSTANT_184_X) +XE_GPU_REGISTER(0x42E1, kFloat, SHADER_CONSTANT_184_Y) +XE_GPU_REGISTER(0x42E2, kFloat, SHADER_CONSTANT_184_Z) +XE_GPU_REGISTER(0x42E3, kFloat, SHADER_CONSTANT_184_W) +XE_GPU_REGISTER(0x42E4, kFloat, SHADER_CONSTANT_185_X) +XE_GPU_REGISTER(0x42E5, kFloat, SHADER_CONSTANT_185_Y) +XE_GPU_REGISTER(0x42E6, kFloat, SHADER_CONSTANT_185_Z) +XE_GPU_REGISTER(0x42E7, kFloat, SHADER_CONSTANT_185_W) +XE_GPU_REGISTER(0x42E8, kFloat, SHADER_CONSTANT_186_X) +XE_GPU_REGISTER(0x42E9, kFloat, SHADER_CONSTANT_186_Y) +XE_GPU_REGISTER(0x42EA, kFloat, SHADER_CONSTANT_186_Z) +XE_GPU_REGISTER(0x42EB, kFloat, SHADER_CONSTANT_186_W) +XE_GPU_REGISTER(0x42EC, kFloat, SHADER_CONSTANT_187_X) +XE_GPU_REGISTER(0x42ED, kFloat, SHADER_CONSTANT_187_Y) +XE_GPU_REGISTER(0x42EE, kFloat, SHADER_CONSTANT_187_Z) +XE_GPU_REGISTER(0x42EF, kFloat, SHADER_CONSTANT_187_W) +XE_GPU_REGISTER(0x42F0, kFloat, SHADER_CONSTANT_188_X) +XE_GPU_REGISTER(0x42F1, kFloat, SHADER_CONSTANT_188_Y) +XE_GPU_REGISTER(0x42F2, kFloat, SHADER_CONSTANT_188_Z) +XE_GPU_REGISTER(0x42F3, kFloat, SHADER_CONSTANT_188_W) +XE_GPU_REGISTER(0x42F4, kFloat, SHADER_CONSTANT_189_X) +XE_GPU_REGISTER(0x42F5, kFloat, SHADER_CONSTANT_189_Y) +XE_GPU_REGISTER(0x42F6, kFloat, SHADER_CONSTANT_189_Z) +XE_GPU_REGISTER(0x42F7, kFloat, SHADER_CONSTANT_189_W) +XE_GPU_REGISTER(0x42F8, kFloat, SHADER_CONSTANT_190_X) +XE_GPU_REGISTER(0x42F9, kFloat, SHADER_CONSTANT_190_Y) +XE_GPU_REGISTER(0x42FA, kFloat, SHADER_CONSTANT_190_Z) +XE_GPU_REGISTER(0x42FB, kFloat, SHADER_CONSTANT_190_W) +XE_GPU_REGISTER(0x42FC, kFloat, SHADER_CONSTANT_191_X) +XE_GPU_REGISTER(0x42FD, kFloat, SHADER_CONSTANT_191_Y) +XE_GPU_REGISTER(0x42FE, kFloat, SHADER_CONSTANT_191_Z) +XE_GPU_REGISTER(0x42FF, kFloat, SHADER_CONSTANT_191_W) +XE_GPU_REGISTER(0x4300, kFloat, SHADER_CONSTANT_192_X) +XE_GPU_REGISTER(0x4301, kFloat, SHADER_CONSTANT_192_Y) +XE_GPU_REGISTER(0x4302, kFloat, SHADER_CONSTANT_192_Z) +XE_GPU_REGISTER(0x4303, kFloat, SHADER_CONSTANT_192_W) +XE_GPU_REGISTER(0x4304, kFloat, SHADER_CONSTANT_193_X) +XE_GPU_REGISTER(0x4305, kFloat, SHADER_CONSTANT_193_Y) +XE_GPU_REGISTER(0x4306, kFloat, SHADER_CONSTANT_193_Z) +XE_GPU_REGISTER(0x4307, kFloat, SHADER_CONSTANT_193_W) +XE_GPU_REGISTER(0x4308, kFloat, SHADER_CONSTANT_194_X) +XE_GPU_REGISTER(0x4309, kFloat, SHADER_CONSTANT_194_Y) +XE_GPU_REGISTER(0x430A, kFloat, SHADER_CONSTANT_194_Z) +XE_GPU_REGISTER(0x430B, kFloat, SHADER_CONSTANT_194_W) +XE_GPU_REGISTER(0x430C, kFloat, SHADER_CONSTANT_195_X) +XE_GPU_REGISTER(0x430D, kFloat, SHADER_CONSTANT_195_Y) +XE_GPU_REGISTER(0x430E, kFloat, SHADER_CONSTANT_195_Z) +XE_GPU_REGISTER(0x430F, kFloat, SHADER_CONSTANT_195_W) +XE_GPU_REGISTER(0x4310, kFloat, SHADER_CONSTANT_196_X) +XE_GPU_REGISTER(0x4311, kFloat, SHADER_CONSTANT_196_Y) +XE_GPU_REGISTER(0x4312, kFloat, SHADER_CONSTANT_196_Z) +XE_GPU_REGISTER(0x4313, kFloat, SHADER_CONSTANT_196_W) +XE_GPU_REGISTER(0x4314, kFloat, SHADER_CONSTANT_197_X) +XE_GPU_REGISTER(0x4315, kFloat, SHADER_CONSTANT_197_Y) +XE_GPU_REGISTER(0x4316, kFloat, SHADER_CONSTANT_197_Z) +XE_GPU_REGISTER(0x4317, kFloat, SHADER_CONSTANT_197_W) +XE_GPU_REGISTER(0x4318, kFloat, SHADER_CONSTANT_198_X) +XE_GPU_REGISTER(0x4319, kFloat, SHADER_CONSTANT_198_Y) +XE_GPU_REGISTER(0x431A, kFloat, SHADER_CONSTANT_198_Z) +XE_GPU_REGISTER(0x431B, kFloat, SHADER_CONSTANT_198_W) +XE_GPU_REGISTER(0x431C, kFloat, SHADER_CONSTANT_199_X) +XE_GPU_REGISTER(0x431D, kFloat, SHADER_CONSTANT_199_Y) +XE_GPU_REGISTER(0x431E, kFloat, SHADER_CONSTANT_199_Z) +XE_GPU_REGISTER(0x431F, kFloat, SHADER_CONSTANT_199_W) +XE_GPU_REGISTER(0x4320, kFloat, SHADER_CONSTANT_200_X) +XE_GPU_REGISTER(0x4321, kFloat, SHADER_CONSTANT_200_Y) +XE_GPU_REGISTER(0x4322, kFloat, SHADER_CONSTANT_200_Z) +XE_GPU_REGISTER(0x4323, kFloat, SHADER_CONSTANT_200_W) +XE_GPU_REGISTER(0x4324, kFloat, SHADER_CONSTANT_201_X) +XE_GPU_REGISTER(0x4325, kFloat, SHADER_CONSTANT_201_Y) +XE_GPU_REGISTER(0x4326, kFloat, SHADER_CONSTANT_201_Z) +XE_GPU_REGISTER(0x4327, kFloat, SHADER_CONSTANT_201_W) +XE_GPU_REGISTER(0x4328, kFloat, SHADER_CONSTANT_202_X) +XE_GPU_REGISTER(0x4329, kFloat, SHADER_CONSTANT_202_Y) +XE_GPU_REGISTER(0x432A, kFloat, SHADER_CONSTANT_202_Z) +XE_GPU_REGISTER(0x432B, kFloat, SHADER_CONSTANT_202_W) +XE_GPU_REGISTER(0x432C, kFloat, SHADER_CONSTANT_203_X) +XE_GPU_REGISTER(0x432D, kFloat, SHADER_CONSTANT_203_Y) +XE_GPU_REGISTER(0x432E, kFloat, SHADER_CONSTANT_203_Z) +XE_GPU_REGISTER(0x432F, kFloat, SHADER_CONSTANT_203_W) +XE_GPU_REGISTER(0x4330, kFloat, SHADER_CONSTANT_204_X) +XE_GPU_REGISTER(0x4331, kFloat, SHADER_CONSTANT_204_Y) +XE_GPU_REGISTER(0x4332, kFloat, SHADER_CONSTANT_204_Z) +XE_GPU_REGISTER(0x4333, kFloat, SHADER_CONSTANT_204_W) +XE_GPU_REGISTER(0x4334, kFloat, SHADER_CONSTANT_205_X) +XE_GPU_REGISTER(0x4335, kFloat, SHADER_CONSTANT_205_Y) +XE_GPU_REGISTER(0x4336, kFloat, SHADER_CONSTANT_205_Z) +XE_GPU_REGISTER(0x4337, kFloat, SHADER_CONSTANT_205_W) +XE_GPU_REGISTER(0x4338, kFloat, SHADER_CONSTANT_206_X) +XE_GPU_REGISTER(0x4339, kFloat, SHADER_CONSTANT_206_Y) +XE_GPU_REGISTER(0x433A, kFloat, SHADER_CONSTANT_206_Z) +XE_GPU_REGISTER(0x433B, kFloat, SHADER_CONSTANT_206_W) +XE_GPU_REGISTER(0x433C, kFloat, SHADER_CONSTANT_207_X) +XE_GPU_REGISTER(0x433D, kFloat, SHADER_CONSTANT_207_Y) +XE_GPU_REGISTER(0x433E, kFloat, SHADER_CONSTANT_207_Z) +XE_GPU_REGISTER(0x433F, kFloat, SHADER_CONSTANT_207_W) +XE_GPU_REGISTER(0x4340, kFloat, SHADER_CONSTANT_208_X) +XE_GPU_REGISTER(0x4341, kFloat, SHADER_CONSTANT_208_Y) +XE_GPU_REGISTER(0x4342, kFloat, SHADER_CONSTANT_208_Z) +XE_GPU_REGISTER(0x4343, kFloat, SHADER_CONSTANT_208_W) +XE_GPU_REGISTER(0x4344, kFloat, SHADER_CONSTANT_209_X) +XE_GPU_REGISTER(0x4345, kFloat, SHADER_CONSTANT_209_Y) +XE_GPU_REGISTER(0x4346, kFloat, SHADER_CONSTANT_209_Z) +XE_GPU_REGISTER(0x4347, kFloat, SHADER_CONSTANT_209_W) +XE_GPU_REGISTER(0x4348, kFloat, SHADER_CONSTANT_210_X) +XE_GPU_REGISTER(0x4349, kFloat, SHADER_CONSTANT_210_Y) +XE_GPU_REGISTER(0x434A, kFloat, SHADER_CONSTANT_210_Z) +XE_GPU_REGISTER(0x434B, kFloat, SHADER_CONSTANT_210_W) +XE_GPU_REGISTER(0x434C, kFloat, SHADER_CONSTANT_211_X) +XE_GPU_REGISTER(0x434D, kFloat, SHADER_CONSTANT_211_Y) +XE_GPU_REGISTER(0x434E, kFloat, SHADER_CONSTANT_211_Z) +XE_GPU_REGISTER(0x434F, kFloat, SHADER_CONSTANT_211_W) +XE_GPU_REGISTER(0x4350, kFloat, SHADER_CONSTANT_212_X) +XE_GPU_REGISTER(0x4351, kFloat, SHADER_CONSTANT_212_Y) +XE_GPU_REGISTER(0x4352, kFloat, SHADER_CONSTANT_212_Z) +XE_GPU_REGISTER(0x4353, kFloat, SHADER_CONSTANT_212_W) +XE_GPU_REGISTER(0x4354, kFloat, SHADER_CONSTANT_213_X) +XE_GPU_REGISTER(0x4355, kFloat, SHADER_CONSTANT_213_Y) +XE_GPU_REGISTER(0x4356, kFloat, SHADER_CONSTANT_213_Z) +XE_GPU_REGISTER(0x4357, kFloat, SHADER_CONSTANT_213_W) +XE_GPU_REGISTER(0x4358, kFloat, SHADER_CONSTANT_214_X) +XE_GPU_REGISTER(0x4359, kFloat, SHADER_CONSTANT_214_Y) +XE_GPU_REGISTER(0x435A, kFloat, SHADER_CONSTANT_214_Z) +XE_GPU_REGISTER(0x435B, kFloat, SHADER_CONSTANT_214_W) +XE_GPU_REGISTER(0x435C, kFloat, SHADER_CONSTANT_215_X) +XE_GPU_REGISTER(0x435D, kFloat, SHADER_CONSTANT_215_Y) +XE_GPU_REGISTER(0x435E, kFloat, SHADER_CONSTANT_215_Z) +XE_GPU_REGISTER(0x435F, kFloat, SHADER_CONSTANT_215_W) +XE_GPU_REGISTER(0x4360, kFloat, SHADER_CONSTANT_216_X) +XE_GPU_REGISTER(0x4361, kFloat, SHADER_CONSTANT_216_Y) +XE_GPU_REGISTER(0x4362, kFloat, SHADER_CONSTANT_216_Z) +XE_GPU_REGISTER(0x4363, kFloat, SHADER_CONSTANT_216_W) +XE_GPU_REGISTER(0x4364, kFloat, SHADER_CONSTANT_217_X) +XE_GPU_REGISTER(0x4365, kFloat, SHADER_CONSTANT_217_Y) +XE_GPU_REGISTER(0x4366, kFloat, SHADER_CONSTANT_217_Z) +XE_GPU_REGISTER(0x4367, kFloat, SHADER_CONSTANT_217_W) +XE_GPU_REGISTER(0x4368, kFloat, SHADER_CONSTANT_218_X) +XE_GPU_REGISTER(0x4369, kFloat, SHADER_CONSTANT_218_Y) +XE_GPU_REGISTER(0x436A, kFloat, SHADER_CONSTANT_218_Z) +XE_GPU_REGISTER(0x436B, kFloat, SHADER_CONSTANT_218_W) +XE_GPU_REGISTER(0x436C, kFloat, SHADER_CONSTANT_219_X) +XE_GPU_REGISTER(0x436D, kFloat, SHADER_CONSTANT_219_Y) +XE_GPU_REGISTER(0x436E, kFloat, SHADER_CONSTANT_219_Z) +XE_GPU_REGISTER(0x436F, kFloat, SHADER_CONSTANT_219_W) +XE_GPU_REGISTER(0x4370, kFloat, SHADER_CONSTANT_220_X) +XE_GPU_REGISTER(0x4371, kFloat, SHADER_CONSTANT_220_Y) +XE_GPU_REGISTER(0x4372, kFloat, SHADER_CONSTANT_220_Z) +XE_GPU_REGISTER(0x4373, kFloat, SHADER_CONSTANT_220_W) +XE_GPU_REGISTER(0x4374, kFloat, SHADER_CONSTANT_221_X) +XE_GPU_REGISTER(0x4375, kFloat, SHADER_CONSTANT_221_Y) +XE_GPU_REGISTER(0x4376, kFloat, SHADER_CONSTANT_221_Z) +XE_GPU_REGISTER(0x4377, kFloat, SHADER_CONSTANT_221_W) +XE_GPU_REGISTER(0x4378, kFloat, SHADER_CONSTANT_222_X) +XE_GPU_REGISTER(0x4379, kFloat, SHADER_CONSTANT_222_Y) +XE_GPU_REGISTER(0x437A, kFloat, SHADER_CONSTANT_222_Z) +XE_GPU_REGISTER(0x437B, kFloat, SHADER_CONSTANT_222_W) +XE_GPU_REGISTER(0x437C, kFloat, SHADER_CONSTANT_223_X) +XE_GPU_REGISTER(0x437D, kFloat, SHADER_CONSTANT_223_Y) +XE_GPU_REGISTER(0x437E, kFloat, SHADER_CONSTANT_223_Z) +XE_GPU_REGISTER(0x437F, kFloat, SHADER_CONSTANT_223_W) +XE_GPU_REGISTER(0x4380, kFloat, SHADER_CONSTANT_224_X) +XE_GPU_REGISTER(0x4381, kFloat, SHADER_CONSTANT_224_Y) +XE_GPU_REGISTER(0x4382, kFloat, SHADER_CONSTANT_224_Z) +XE_GPU_REGISTER(0x4383, kFloat, SHADER_CONSTANT_224_W) +XE_GPU_REGISTER(0x4384, kFloat, SHADER_CONSTANT_225_X) +XE_GPU_REGISTER(0x4385, kFloat, SHADER_CONSTANT_225_Y) +XE_GPU_REGISTER(0x4386, kFloat, SHADER_CONSTANT_225_Z) +XE_GPU_REGISTER(0x4387, kFloat, SHADER_CONSTANT_225_W) +XE_GPU_REGISTER(0x4388, kFloat, SHADER_CONSTANT_226_X) +XE_GPU_REGISTER(0x4389, kFloat, SHADER_CONSTANT_226_Y) +XE_GPU_REGISTER(0x438A, kFloat, SHADER_CONSTANT_226_Z) +XE_GPU_REGISTER(0x438B, kFloat, SHADER_CONSTANT_226_W) +XE_GPU_REGISTER(0x438C, kFloat, SHADER_CONSTANT_227_X) +XE_GPU_REGISTER(0x438D, kFloat, SHADER_CONSTANT_227_Y) +XE_GPU_REGISTER(0x438E, kFloat, SHADER_CONSTANT_227_Z) +XE_GPU_REGISTER(0x438F, kFloat, SHADER_CONSTANT_227_W) +XE_GPU_REGISTER(0x4390, kFloat, SHADER_CONSTANT_228_X) +XE_GPU_REGISTER(0x4391, kFloat, SHADER_CONSTANT_228_Y) +XE_GPU_REGISTER(0x4392, kFloat, SHADER_CONSTANT_228_Z) +XE_GPU_REGISTER(0x4393, kFloat, SHADER_CONSTANT_228_W) +XE_GPU_REGISTER(0x4394, kFloat, SHADER_CONSTANT_229_X) +XE_GPU_REGISTER(0x4395, kFloat, SHADER_CONSTANT_229_Y) +XE_GPU_REGISTER(0x4396, kFloat, SHADER_CONSTANT_229_Z) +XE_GPU_REGISTER(0x4397, kFloat, SHADER_CONSTANT_229_W) +XE_GPU_REGISTER(0x4398, kFloat, SHADER_CONSTANT_230_X) +XE_GPU_REGISTER(0x4399, kFloat, SHADER_CONSTANT_230_Y) +XE_GPU_REGISTER(0x439A, kFloat, SHADER_CONSTANT_230_Z) +XE_GPU_REGISTER(0x439B, kFloat, SHADER_CONSTANT_230_W) +XE_GPU_REGISTER(0x439C, kFloat, SHADER_CONSTANT_231_X) +XE_GPU_REGISTER(0x439D, kFloat, SHADER_CONSTANT_231_Y) +XE_GPU_REGISTER(0x439E, kFloat, SHADER_CONSTANT_231_Z) +XE_GPU_REGISTER(0x439F, kFloat, SHADER_CONSTANT_231_W) +XE_GPU_REGISTER(0x43A0, kFloat, SHADER_CONSTANT_232_X) +XE_GPU_REGISTER(0x43A1, kFloat, SHADER_CONSTANT_232_Y) +XE_GPU_REGISTER(0x43A2, kFloat, SHADER_CONSTANT_232_Z) +XE_GPU_REGISTER(0x43A3, kFloat, SHADER_CONSTANT_232_W) +XE_GPU_REGISTER(0x43A4, kFloat, SHADER_CONSTANT_233_X) +XE_GPU_REGISTER(0x43A5, kFloat, SHADER_CONSTANT_233_Y) +XE_GPU_REGISTER(0x43A6, kFloat, SHADER_CONSTANT_233_Z) +XE_GPU_REGISTER(0x43A7, kFloat, SHADER_CONSTANT_233_W) +XE_GPU_REGISTER(0x43A8, kFloat, SHADER_CONSTANT_234_X) +XE_GPU_REGISTER(0x43A9, kFloat, SHADER_CONSTANT_234_Y) +XE_GPU_REGISTER(0x43AA, kFloat, SHADER_CONSTANT_234_Z) +XE_GPU_REGISTER(0x43AB, kFloat, SHADER_CONSTANT_234_W) +XE_GPU_REGISTER(0x43AC, kFloat, SHADER_CONSTANT_235_X) +XE_GPU_REGISTER(0x43AD, kFloat, SHADER_CONSTANT_235_Y) +XE_GPU_REGISTER(0x43AE, kFloat, SHADER_CONSTANT_235_Z) +XE_GPU_REGISTER(0x43AF, kFloat, SHADER_CONSTANT_235_W) +XE_GPU_REGISTER(0x43B0, kFloat, SHADER_CONSTANT_236_X) +XE_GPU_REGISTER(0x43B1, kFloat, SHADER_CONSTANT_236_Y) +XE_GPU_REGISTER(0x43B2, kFloat, SHADER_CONSTANT_236_Z) +XE_GPU_REGISTER(0x43B3, kFloat, SHADER_CONSTANT_236_W) +XE_GPU_REGISTER(0x43B4, kFloat, SHADER_CONSTANT_237_X) +XE_GPU_REGISTER(0x43B5, kFloat, SHADER_CONSTANT_237_Y) +XE_GPU_REGISTER(0x43B6, kFloat, SHADER_CONSTANT_237_Z) +XE_GPU_REGISTER(0x43B7, kFloat, SHADER_CONSTANT_237_W) +XE_GPU_REGISTER(0x43B8, kFloat, SHADER_CONSTANT_238_X) +XE_GPU_REGISTER(0x43B9, kFloat, SHADER_CONSTANT_238_Y) +XE_GPU_REGISTER(0x43BA, kFloat, SHADER_CONSTANT_238_Z) +XE_GPU_REGISTER(0x43BB, kFloat, SHADER_CONSTANT_238_W) +XE_GPU_REGISTER(0x43BC, kFloat, SHADER_CONSTANT_239_X) +XE_GPU_REGISTER(0x43BD, kFloat, SHADER_CONSTANT_239_Y) +XE_GPU_REGISTER(0x43BE, kFloat, SHADER_CONSTANT_239_Z) +XE_GPU_REGISTER(0x43BF, kFloat, SHADER_CONSTANT_239_W) +XE_GPU_REGISTER(0x43C0, kFloat, SHADER_CONSTANT_240_X) +XE_GPU_REGISTER(0x43C1, kFloat, SHADER_CONSTANT_240_Y) +XE_GPU_REGISTER(0x43C2, kFloat, SHADER_CONSTANT_240_Z) +XE_GPU_REGISTER(0x43C3, kFloat, SHADER_CONSTANT_240_W) +XE_GPU_REGISTER(0x43C4, kFloat, SHADER_CONSTANT_241_X) +XE_GPU_REGISTER(0x43C5, kFloat, SHADER_CONSTANT_241_Y) +XE_GPU_REGISTER(0x43C6, kFloat, SHADER_CONSTANT_241_Z) +XE_GPU_REGISTER(0x43C7, kFloat, SHADER_CONSTANT_241_W) +XE_GPU_REGISTER(0x43C8, kFloat, SHADER_CONSTANT_242_X) +XE_GPU_REGISTER(0x43C9, kFloat, SHADER_CONSTANT_242_Y) +XE_GPU_REGISTER(0x43CA, kFloat, SHADER_CONSTANT_242_Z) +XE_GPU_REGISTER(0x43CB, kFloat, SHADER_CONSTANT_242_W) +XE_GPU_REGISTER(0x43CC, kFloat, SHADER_CONSTANT_243_X) +XE_GPU_REGISTER(0x43CD, kFloat, SHADER_CONSTANT_243_Y) +XE_GPU_REGISTER(0x43CE, kFloat, SHADER_CONSTANT_243_Z) +XE_GPU_REGISTER(0x43CF, kFloat, SHADER_CONSTANT_243_W) +XE_GPU_REGISTER(0x43D0, kFloat, SHADER_CONSTANT_244_X) +XE_GPU_REGISTER(0x43D1, kFloat, SHADER_CONSTANT_244_Y) +XE_GPU_REGISTER(0x43D2, kFloat, SHADER_CONSTANT_244_Z) +XE_GPU_REGISTER(0x43D3, kFloat, SHADER_CONSTANT_244_W) +XE_GPU_REGISTER(0x43D4, kFloat, SHADER_CONSTANT_245_X) +XE_GPU_REGISTER(0x43D5, kFloat, SHADER_CONSTANT_245_Y) +XE_GPU_REGISTER(0x43D6, kFloat, SHADER_CONSTANT_245_Z) +XE_GPU_REGISTER(0x43D7, kFloat, SHADER_CONSTANT_245_W) +XE_GPU_REGISTER(0x43D8, kFloat, SHADER_CONSTANT_246_X) +XE_GPU_REGISTER(0x43D9, kFloat, SHADER_CONSTANT_246_Y) +XE_GPU_REGISTER(0x43DA, kFloat, SHADER_CONSTANT_246_Z) +XE_GPU_REGISTER(0x43DB, kFloat, SHADER_CONSTANT_246_W) +XE_GPU_REGISTER(0x43DC, kFloat, SHADER_CONSTANT_247_X) +XE_GPU_REGISTER(0x43DD, kFloat, SHADER_CONSTANT_247_Y) +XE_GPU_REGISTER(0x43DE, kFloat, SHADER_CONSTANT_247_Z) +XE_GPU_REGISTER(0x43DF, kFloat, SHADER_CONSTANT_247_W) +XE_GPU_REGISTER(0x43E0, kFloat, SHADER_CONSTANT_248_X) +XE_GPU_REGISTER(0x43E1, kFloat, SHADER_CONSTANT_248_Y) +XE_GPU_REGISTER(0x43E2, kFloat, SHADER_CONSTANT_248_Z) +XE_GPU_REGISTER(0x43E3, kFloat, SHADER_CONSTANT_248_W) +XE_GPU_REGISTER(0x43E4, kFloat, SHADER_CONSTANT_249_X) +XE_GPU_REGISTER(0x43E5, kFloat, SHADER_CONSTANT_249_Y) +XE_GPU_REGISTER(0x43E6, kFloat, SHADER_CONSTANT_249_Z) +XE_GPU_REGISTER(0x43E7, kFloat, SHADER_CONSTANT_249_W) +XE_GPU_REGISTER(0x43E8, kFloat, SHADER_CONSTANT_250_X) +XE_GPU_REGISTER(0x43E9, kFloat, SHADER_CONSTANT_250_Y) +XE_GPU_REGISTER(0x43EA, kFloat, SHADER_CONSTANT_250_Z) +XE_GPU_REGISTER(0x43EB, kFloat, SHADER_CONSTANT_250_W) +XE_GPU_REGISTER(0x43EC, kFloat, SHADER_CONSTANT_251_X) +XE_GPU_REGISTER(0x43ED, kFloat, SHADER_CONSTANT_251_Y) +XE_GPU_REGISTER(0x43EE, kFloat, SHADER_CONSTANT_251_Z) +XE_GPU_REGISTER(0x43EF, kFloat, SHADER_CONSTANT_251_W) +XE_GPU_REGISTER(0x43F0, kFloat, SHADER_CONSTANT_252_X) +XE_GPU_REGISTER(0x43F1, kFloat, SHADER_CONSTANT_252_Y) +XE_GPU_REGISTER(0x43F2, kFloat, SHADER_CONSTANT_252_Z) +XE_GPU_REGISTER(0x43F3, kFloat, SHADER_CONSTANT_252_W) +XE_GPU_REGISTER(0x43F4, kFloat, SHADER_CONSTANT_253_X) +XE_GPU_REGISTER(0x43F5, kFloat, SHADER_CONSTANT_253_Y) +XE_GPU_REGISTER(0x43F6, kFloat, SHADER_CONSTANT_253_Z) +XE_GPU_REGISTER(0x43F7, kFloat, SHADER_CONSTANT_253_W) +XE_GPU_REGISTER(0x43F8, kFloat, SHADER_CONSTANT_254_X) +XE_GPU_REGISTER(0x43F9, kFloat, SHADER_CONSTANT_254_Y) +XE_GPU_REGISTER(0x43FA, kFloat, SHADER_CONSTANT_254_Z) +XE_GPU_REGISTER(0x43FB, kFloat, SHADER_CONSTANT_254_W) +XE_GPU_REGISTER(0x43FC, kFloat, SHADER_CONSTANT_255_X) +XE_GPU_REGISTER(0x43FD, kFloat, SHADER_CONSTANT_255_Y) +XE_GPU_REGISTER(0x43FE, kFloat, SHADER_CONSTANT_255_Z) +XE_GPU_REGISTER(0x43FF, kFloat, SHADER_CONSTANT_255_W) +XE_GPU_REGISTER(0x4400, kFloat, SHADER_CONSTANT_256_X) +XE_GPU_REGISTER(0x4401, kFloat, SHADER_CONSTANT_256_Y) +XE_GPU_REGISTER(0x4402, kFloat, SHADER_CONSTANT_256_Z) +XE_GPU_REGISTER(0x4403, kFloat, SHADER_CONSTANT_256_W) +XE_GPU_REGISTER(0x4404, kFloat, SHADER_CONSTANT_257_X) +XE_GPU_REGISTER(0x4405, kFloat, SHADER_CONSTANT_257_Y) +XE_GPU_REGISTER(0x4406, kFloat, SHADER_CONSTANT_257_Z) +XE_GPU_REGISTER(0x4407, kFloat, SHADER_CONSTANT_257_W) +XE_GPU_REGISTER(0x4408, kFloat, SHADER_CONSTANT_258_X) +XE_GPU_REGISTER(0x4409, kFloat, SHADER_CONSTANT_258_Y) +XE_GPU_REGISTER(0x440A, kFloat, SHADER_CONSTANT_258_Z) +XE_GPU_REGISTER(0x440B, kFloat, SHADER_CONSTANT_258_W) +XE_GPU_REGISTER(0x440C, kFloat, SHADER_CONSTANT_259_X) +XE_GPU_REGISTER(0x440D, kFloat, SHADER_CONSTANT_259_Y) +XE_GPU_REGISTER(0x440E, kFloat, SHADER_CONSTANT_259_Z) +XE_GPU_REGISTER(0x440F, kFloat, SHADER_CONSTANT_259_W) +XE_GPU_REGISTER(0x4410, kFloat, SHADER_CONSTANT_260_X) +XE_GPU_REGISTER(0x4411, kFloat, SHADER_CONSTANT_260_Y) +XE_GPU_REGISTER(0x4412, kFloat, SHADER_CONSTANT_260_Z) +XE_GPU_REGISTER(0x4413, kFloat, SHADER_CONSTANT_260_W) +XE_GPU_REGISTER(0x4414, kFloat, SHADER_CONSTANT_261_X) +XE_GPU_REGISTER(0x4415, kFloat, SHADER_CONSTANT_261_Y) +XE_GPU_REGISTER(0x4416, kFloat, SHADER_CONSTANT_261_Z) +XE_GPU_REGISTER(0x4417, kFloat, SHADER_CONSTANT_261_W) +XE_GPU_REGISTER(0x4418, kFloat, SHADER_CONSTANT_262_X) +XE_GPU_REGISTER(0x4419, kFloat, SHADER_CONSTANT_262_Y) +XE_GPU_REGISTER(0x441A, kFloat, SHADER_CONSTANT_262_Z) +XE_GPU_REGISTER(0x441B, kFloat, SHADER_CONSTANT_262_W) +XE_GPU_REGISTER(0x441C, kFloat, SHADER_CONSTANT_263_X) +XE_GPU_REGISTER(0x441D, kFloat, SHADER_CONSTANT_263_Y) +XE_GPU_REGISTER(0x441E, kFloat, SHADER_CONSTANT_263_Z) +XE_GPU_REGISTER(0x441F, kFloat, SHADER_CONSTANT_263_W) +XE_GPU_REGISTER(0x4420, kFloat, SHADER_CONSTANT_264_X) +XE_GPU_REGISTER(0x4421, kFloat, SHADER_CONSTANT_264_Y) +XE_GPU_REGISTER(0x4422, kFloat, SHADER_CONSTANT_264_Z) +XE_GPU_REGISTER(0x4423, kFloat, SHADER_CONSTANT_264_W) +XE_GPU_REGISTER(0x4424, kFloat, SHADER_CONSTANT_265_X) +XE_GPU_REGISTER(0x4425, kFloat, SHADER_CONSTANT_265_Y) +XE_GPU_REGISTER(0x4426, kFloat, SHADER_CONSTANT_265_Z) +XE_GPU_REGISTER(0x4427, kFloat, SHADER_CONSTANT_265_W) +XE_GPU_REGISTER(0x4428, kFloat, SHADER_CONSTANT_266_X) +XE_GPU_REGISTER(0x4429, kFloat, SHADER_CONSTANT_266_Y) +XE_GPU_REGISTER(0x442A, kFloat, SHADER_CONSTANT_266_Z) +XE_GPU_REGISTER(0x442B, kFloat, SHADER_CONSTANT_266_W) +XE_GPU_REGISTER(0x442C, kFloat, SHADER_CONSTANT_267_X) +XE_GPU_REGISTER(0x442D, kFloat, SHADER_CONSTANT_267_Y) +XE_GPU_REGISTER(0x442E, kFloat, SHADER_CONSTANT_267_Z) +XE_GPU_REGISTER(0x442F, kFloat, SHADER_CONSTANT_267_W) +XE_GPU_REGISTER(0x4430, kFloat, SHADER_CONSTANT_268_X) +XE_GPU_REGISTER(0x4431, kFloat, SHADER_CONSTANT_268_Y) +XE_GPU_REGISTER(0x4432, kFloat, SHADER_CONSTANT_268_Z) +XE_GPU_REGISTER(0x4433, kFloat, SHADER_CONSTANT_268_W) +XE_GPU_REGISTER(0x4434, kFloat, SHADER_CONSTANT_269_X) +XE_GPU_REGISTER(0x4435, kFloat, SHADER_CONSTANT_269_Y) +XE_GPU_REGISTER(0x4436, kFloat, SHADER_CONSTANT_269_Z) +XE_GPU_REGISTER(0x4437, kFloat, SHADER_CONSTANT_269_W) +XE_GPU_REGISTER(0x4438, kFloat, SHADER_CONSTANT_270_X) +XE_GPU_REGISTER(0x4439, kFloat, SHADER_CONSTANT_270_Y) +XE_GPU_REGISTER(0x443A, kFloat, SHADER_CONSTANT_270_Z) +XE_GPU_REGISTER(0x443B, kFloat, SHADER_CONSTANT_270_W) +XE_GPU_REGISTER(0x443C, kFloat, SHADER_CONSTANT_271_X) +XE_GPU_REGISTER(0x443D, kFloat, SHADER_CONSTANT_271_Y) +XE_GPU_REGISTER(0x443E, kFloat, SHADER_CONSTANT_271_Z) +XE_GPU_REGISTER(0x443F, kFloat, SHADER_CONSTANT_271_W) +XE_GPU_REGISTER(0x4440, kFloat, SHADER_CONSTANT_272_X) +XE_GPU_REGISTER(0x4441, kFloat, SHADER_CONSTANT_272_Y) +XE_GPU_REGISTER(0x4442, kFloat, SHADER_CONSTANT_272_Z) +XE_GPU_REGISTER(0x4443, kFloat, SHADER_CONSTANT_272_W) +XE_GPU_REGISTER(0x4444, kFloat, SHADER_CONSTANT_273_X) +XE_GPU_REGISTER(0x4445, kFloat, SHADER_CONSTANT_273_Y) +XE_GPU_REGISTER(0x4446, kFloat, SHADER_CONSTANT_273_Z) +XE_GPU_REGISTER(0x4447, kFloat, SHADER_CONSTANT_273_W) +XE_GPU_REGISTER(0x4448, kFloat, SHADER_CONSTANT_274_X) +XE_GPU_REGISTER(0x4449, kFloat, SHADER_CONSTANT_274_Y) +XE_GPU_REGISTER(0x444A, kFloat, SHADER_CONSTANT_274_Z) +XE_GPU_REGISTER(0x444B, kFloat, SHADER_CONSTANT_274_W) +XE_GPU_REGISTER(0x444C, kFloat, SHADER_CONSTANT_275_X) +XE_GPU_REGISTER(0x444D, kFloat, SHADER_CONSTANT_275_Y) +XE_GPU_REGISTER(0x444E, kFloat, SHADER_CONSTANT_275_Z) +XE_GPU_REGISTER(0x444F, kFloat, SHADER_CONSTANT_275_W) +XE_GPU_REGISTER(0x4450, kFloat, SHADER_CONSTANT_276_X) +XE_GPU_REGISTER(0x4451, kFloat, SHADER_CONSTANT_276_Y) +XE_GPU_REGISTER(0x4452, kFloat, SHADER_CONSTANT_276_Z) +XE_GPU_REGISTER(0x4453, kFloat, SHADER_CONSTANT_276_W) +XE_GPU_REGISTER(0x4454, kFloat, SHADER_CONSTANT_277_X) +XE_GPU_REGISTER(0x4455, kFloat, SHADER_CONSTANT_277_Y) +XE_GPU_REGISTER(0x4456, kFloat, SHADER_CONSTANT_277_Z) +XE_GPU_REGISTER(0x4457, kFloat, SHADER_CONSTANT_277_W) +XE_GPU_REGISTER(0x4458, kFloat, SHADER_CONSTANT_278_X) +XE_GPU_REGISTER(0x4459, kFloat, SHADER_CONSTANT_278_Y) +XE_GPU_REGISTER(0x445A, kFloat, SHADER_CONSTANT_278_Z) +XE_GPU_REGISTER(0x445B, kFloat, SHADER_CONSTANT_278_W) +XE_GPU_REGISTER(0x445C, kFloat, SHADER_CONSTANT_279_X) +XE_GPU_REGISTER(0x445D, kFloat, SHADER_CONSTANT_279_Y) +XE_GPU_REGISTER(0x445E, kFloat, SHADER_CONSTANT_279_Z) +XE_GPU_REGISTER(0x445F, kFloat, SHADER_CONSTANT_279_W) +XE_GPU_REGISTER(0x4460, kFloat, SHADER_CONSTANT_280_X) +XE_GPU_REGISTER(0x4461, kFloat, SHADER_CONSTANT_280_Y) +XE_GPU_REGISTER(0x4462, kFloat, SHADER_CONSTANT_280_Z) +XE_GPU_REGISTER(0x4463, kFloat, SHADER_CONSTANT_280_W) +XE_GPU_REGISTER(0x4464, kFloat, SHADER_CONSTANT_281_X) +XE_GPU_REGISTER(0x4465, kFloat, SHADER_CONSTANT_281_Y) +XE_GPU_REGISTER(0x4466, kFloat, SHADER_CONSTANT_281_Z) +XE_GPU_REGISTER(0x4467, kFloat, SHADER_CONSTANT_281_W) +XE_GPU_REGISTER(0x4468, kFloat, SHADER_CONSTANT_282_X) +XE_GPU_REGISTER(0x4469, kFloat, SHADER_CONSTANT_282_Y) +XE_GPU_REGISTER(0x446A, kFloat, SHADER_CONSTANT_282_Z) +XE_GPU_REGISTER(0x446B, kFloat, SHADER_CONSTANT_282_W) +XE_GPU_REGISTER(0x446C, kFloat, SHADER_CONSTANT_283_X) +XE_GPU_REGISTER(0x446D, kFloat, SHADER_CONSTANT_283_Y) +XE_GPU_REGISTER(0x446E, kFloat, SHADER_CONSTANT_283_Z) +XE_GPU_REGISTER(0x446F, kFloat, SHADER_CONSTANT_283_W) +XE_GPU_REGISTER(0x4470, kFloat, SHADER_CONSTANT_284_X) +XE_GPU_REGISTER(0x4471, kFloat, SHADER_CONSTANT_284_Y) +XE_GPU_REGISTER(0x4472, kFloat, SHADER_CONSTANT_284_Z) +XE_GPU_REGISTER(0x4473, kFloat, SHADER_CONSTANT_284_W) +XE_GPU_REGISTER(0x4474, kFloat, SHADER_CONSTANT_285_X) +XE_GPU_REGISTER(0x4475, kFloat, SHADER_CONSTANT_285_Y) +XE_GPU_REGISTER(0x4476, kFloat, SHADER_CONSTANT_285_Z) +XE_GPU_REGISTER(0x4477, kFloat, SHADER_CONSTANT_285_W) +XE_GPU_REGISTER(0x4478, kFloat, SHADER_CONSTANT_286_X) +XE_GPU_REGISTER(0x4479, kFloat, SHADER_CONSTANT_286_Y) +XE_GPU_REGISTER(0x447A, kFloat, SHADER_CONSTANT_286_Z) +XE_GPU_REGISTER(0x447B, kFloat, SHADER_CONSTANT_286_W) +XE_GPU_REGISTER(0x447C, kFloat, SHADER_CONSTANT_287_X) +XE_GPU_REGISTER(0x447D, kFloat, SHADER_CONSTANT_287_Y) +XE_GPU_REGISTER(0x447E, kFloat, SHADER_CONSTANT_287_Z) +XE_GPU_REGISTER(0x447F, kFloat, SHADER_CONSTANT_287_W) +XE_GPU_REGISTER(0x4480, kFloat, SHADER_CONSTANT_288_X) +XE_GPU_REGISTER(0x4481, kFloat, SHADER_CONSTANT_288_Y) +XE_GPU_REGISTER(0x4482, kFloat, SHADER_CONSTANT_288_Z) +XE_GPU_REGISTER(0x4483, kFloat, SHADER_CONSTANT_288_W) +XE_GPU_REGISTER(0x4484, kFloat, SHADER_CONSTANT_289_X) +XE_GPU_REGISTER(0x4485, kFloat, SHADER_CONSTANT_289_Y) +XE_GPU_REGISTER(0x4486, kFloat, SHADER_CONSTANT_289_Z) +XE_GPU_REGISTER(0x4487, kFloat, SHADER_CONSTANT_289_W) +XE_GPU_REGISTER(0x4488, kFloat, SHADER_CONSTANT_290_X) +XE_GPU_REGISTER(0x4489, kFloat, SHADER_CONSTANT_290_Y) +XE_GPU_REGISTER(0x448A, kFloat, SHADER_CONSTANT_290_Z) +XE_GPU_REGISTER(0x448B, kFloat, SHADER_CONSTANT_290_W) +XE_GPU_REGISTER(0x448C, kFloat, SHADER_CONSTANT_291_X) +XE_GPU_REGISTER(0x448D, kFloat, SHADER_CONSTANT_291_Y) +XE_GPU_REGISTER(0x448E, kFloat, SHADER_CONSTANT_291_Z) +XE_GPU_REGISTER(0x448F, kFloat, SHADER_CONSTANT_291_W) +XE_GPU_REGISTER(0x4490, kFloat, SHADER_CONSTANT_292_X) +XE_GPU_REGISTER(0x4491, kFloat, SHADER_CONSTANT_292_Y) +XE_GPU_REGISTER(0x4492, kFloat, SHADER_CONSTANT_292_Z) +XE_GPU_REGISTER(0x4493, kFloat, SHADER_CONSTANT_292_W) +XE_GPU_REGISTER(0x4494, kFloat, SHADER_CONSTANT_293_X) +XE_GPU_REGISTER(0x4495, kFloat, SHADER_CONSTANT_293_Y) +XE_GPU_REGISTER(0x4496, kFloat, SHADER_CONSTANT_293_Z) +XE_GPU_REGISTER(0x4497, kFloat, SHADER_CONSTANT_293_W) +XE_GPU_REGISTER(0x4498, kFloat, SHADER_CONSTANT_294_X) +XE_GPU_REGISTER(0x4499, kFloat, SHADER_CONSTANT_294_Y) +XE_GPU_REGISTER(0x449A, kFloat, SHADER_CONSTANT_294_Z) +XE_GPU_REGISTER(0x449B, kFloat, SHADER_CONSTANT_294_W) +XE_GPU_REGISTER(0x449C, kFloat, SHADER_CONSTANT_295_X) +XE_GPU_REGISTER(0x449D, kFloat, SHADER_CONSTANT_295_Y) +XE_GPU_REGISTER(0x449E, kFloat, SHADER_CONSTANT_295_Z) +XE_GPU_REGISTER(0x449F, kFloat, SHADER_CONSTANT_295_W) +XE_GPU_REGISTER(0x44A0, kFloat, SHADER_CONSTANT_296_X) +XE_GPU_REGISTER(0x44A1, kFloat, SHADER_CONSTANT_296_Y) +XE_GPU_REGISTER(0x44A2, kFloat, SHADER_CONSTANT_296_Z) +XE_GPU_REGISTER(0x44A3, kFloat, SHADER_CONSTANT_296_W) +XE_GPU_REGISTER(0x44A4, kFloat, SHADER_CONSTANT_297_X) +XE_GPU_REGISTER(0x44A5, kFloat, SHADER_CONSTANT_297_Y) +XE_GPU_REGISTER(0x44A6, kFloat, SHADER_CONSTANT_297_Z) +XE_GPU_REGISTER(0x44A7, kFloat, SHADER_CONSTANT_297_W) +XE_GPU_REGISTER(0x44A8, kFloat, SHADER_CONSTANT_298_X) +XE_GPU_REGISTER(0x44A9, kFloat, SHADER_CONSTANT_298_Y) +XE_GPU_REGISTER(0x44AA, kFloat, SHADER_CONSTANT_298_Z) +XE_GPU_REGISTER(0x44AB, kFloat, SHADER_CONSTANT_298_W) +XE_GPU_REGISTER(0x44AC, kFloat, SHADER_CONSTANT_299_X) +XE_GPU_REGISTER(0x44AD, kFloat, SHADER_CONSTANT_299_Y) +XE_GPU_REGISTER(0x44AE, kFloat, SHADER_CONSTANT_299_Z) +XE_GPU_REGISTER(0x44AF, kFloat, SHADER_CONSTANT_299_W) +XE_GPU_REGISTER(0x44B0, kFloat, SHADER_CONSTANT_300_X) +XE_GPU_REGISTER(0x44B1, kFloat, SHADER_CONSTANT_300_Y) +XE_GPU_REGISTER(0x44B2, kFloat, SHADER_CONSTANT_300_Z) +XE_GPU_REGISTER(0x44B3, kFloat, SHADER_CONSTANT_300_W) +XE_GPU_REGISTER(0x44B4, kFloat, SHADER_CONSTANT_301_X) +XE_GPU_REGISTER(0x44B5, kFloat, SHADER_CONSTANT_301_Y) +XE_GPU_REGISTER(0x44B6, kFloat, SHADER_CONSTANT_301_Z) +XE_GPU_REGISTER(0x44B7, kFloat, SHADER_CONSTANT_301_W) +XE_GPU_REGISTER(0x44B8, kFloat, SHADER_CONSTANT_302_X) +XE_GPU_REGISTER(0x44B9, kFloat, SHADER_CONSTANT_302_Y) +XE_GPU_REGISTER(0x44BA, kFloat, SHADER_CONSTANT_302_Z) +XE_GPU_REGISTER(0x44BB, kFloat, SHADER_CONSTANT_302_W) +XE_GPU_REGISTER(0x44BC, kFloat, SHADER_CONSTANT_303_X) +XE_GPU_REGISTER(0x44BD, kFloat, SHADER_CONSTANT_303_Y) +XE_GPU_REGISTER(0x44BE, kFloat, SHADER_CONSTANT_303_Z) +XE_GPU_REGISTER(0x44BF, kFloat, SHADER_CONSTANT_303_W) +XE_GPU_REGISTER(0x44C0, kFloat, SHADER_CONSTANT_304_X) +XE_GPU_REGISTER(0x44C1, kFloat, SHADER_CONSTANT_304_Y) +XE_GPU_REGISTER(0x44C2, kFloat, SHADER_CONSTANT_304_Z) +XE_GPU_REGISTER(0x44C3, kFloat, SHADER_CONSTANT_304_W) +XE_GPU_REGISTER(0x44C4, kFloat, SHADER_CONSTANT_305_X) +XE_GPU_REGISTER(0x44C5, kFloat, SHADER_CONSTANT_305_Y) +XE_GPU_REGISTER(0x44C6, kFloat, SHADER_CONSTANT_305_Z) +XE_GPU_REGISTER(0x44C7, kFloat, SHADER_CONSTANT_305_W) +XE_GPU_REGISTER(0x44C8, kFloat, SHADER_CONSTANT_306_X) +XE_GPU_REGISTER(0x44C9, kFloat, SHADER_CONSTANT_306_Y) +XE_GPU_REGISTER(0x44CA, kFloat, SHADER_CONSTANT_306_Z) +XE_GPU_REGISTER(0x44CB, kFloat, SHADER_CONSTANT_306_W) +XE_GPU_REGISTER(0x44CC, kFloat, SHADER_CONSTANT_307_X) +XE_GPU_REGISTER(0x44CD, kFloat, SHADER_CONSTANT_307_Y) +XE_GPU_REGISTER(0x44CE, kFloat, SHADER_CONSTANT_307_Z) +XE_GPU_REGISTER(0x44CF, kFloat, SHADER_CONSTANT_307_W) +XE_GPU_REGISTER(0x44D0, kFloat, SHADER_CONSTANT_308_X) +XE_GPU_REGISTER(0x44D1, kFloat, SHADER_CONSTANT_308_Y) +XE_GPU_REGISTER(0x44D2, kFloat, SHADER_CONSTANT_308_Z) +XE_GPU_REGISTER(0x44D3, kFloat, SHADER_CONSTANT_308_W) +XE_GPU_REGISTER(0x44D4, kFloat, SHADER_CONSTANT_309_X) +XE_GPU_REGISTER(0x44D5, kFloat, SHADER_CONSTANT_309_Y) +XE_GPU_REGISTER(0x44D6, kFloat, SHADER_CONSTANT_309_Z) +XE_GPU_REGISTER(0x44D7, kFloat, SHADER_CONSTANT_309_W) +XE_GPU_REGISTER(0x44D8, kFloat, SHADER_CONSTANT_310_X) +XE_GPU_REGISTER(0x44D9, kFloat, SHADER_CONSTANT_310_Y) +XE_GPU_REGISTER(0x44DA, kFloat, SHADER_CONSTANT_310_Z) +XE_GPU_REGISTER(0x44DB, kFloat, SHADER_CONSTANT_310_W) +XE_GPU_REGISTER(0x44DC, kFloat, SHADER_CONSTANT_311_X) +XE_GPU_REGISTER(0x44DD, kFloat, SHADER_CONSTANT_311_Y) +XE_GPU_REGISTER(0x44DE, kFloat, SHADER_CONSTANT_311_Z) +XE_GPU_REGISTER(0x44DF, kFloat, SHADER_CONSTANT_311_W) +XE_GPU_REGISTER(0x44E0, kFloat, SHADER_CONSTANT_312_X) +XE_GPU_REGISTER(0x44E1, kFloat, SHADER_CONSTANT_312_Y) +XE_GPU_REGISTER(0x44E2, kFloat, SHADER_CONSTANT_312_Z) +XE_GPU_REGISTER(0x44E3, kFloat, SHADER_CONSTANT_312_W) +XE_GPU_REGISTER(0x44E4, kFloat, SHADER_CONSTANT_313_X) +XE_GPU_REGISTER(0x44E5, kFloat, SHADER_CONSTANT_313_Y) +XE_GPU_REGISTER(0x44E6, kFloat, SHADER_CONSTANT_313_Z) +XE_GPU_REGISTER(0x44E7, kFloat, SHADER_CONSTANT_313_W) +XE_GPU_REGISTER(0x44E8, kFloat, SHADER_CONSTANT_314_X) +XE_GPU_REGISTER(0x44E9, kFloat, SHADER_CONSTANT_314_Y) +XE_GPU_REGISTER(0x44EA, kFloat, SHADER_CONSTANT_314_Z) +XE_GPU_REGISTER(0x44EB, kFloat, SHADER_CONSTANT_314_W) +XE_GPU_REGISTER(0x44EC, kFloat, SHADER_CONSTANT_315_X) +XE_GPU_REGISTER(0x44ED, kFloat, SHADER_CONSTANT_315_Y) +XE_GPU_REGISTER(0x44EE, kFloat, SHADER_CONSTANT_315_Z) +XE_GPU_REGISTER(0x44EF, kFloat, SHADER_CONSTANT_315_W) +XE_GPU_REGISTER(0x44F0, kFloat, SHADER_CONSTANT_316_X) +XE_GPU_REGISTER(0x44F1, kFloat, SHADER_CONSTANT_316_Y) +XE_GPU_REGISTER(0x44F2, kFloat, SHADER_CONSTANT_316_Z) +XE_GPU_REGISTER(0x44F3, kFloat, SHADER_CONSTANT_316_W) +XE_GPU_REGISTER(0x44F4, kFloat, SHADER_CONSTANT_317_X) +XE_GPU_REGISTER(0x44F5, kFloat, SHADER_CONSTANT_317_Y) +XE_GPU_REGISTER(0x44F6, kFloat, SHADER_CONSTANT_317_Z) +XE_GPU_REGISTER(0x44F7, kFloat, SHADER_CONSTANT_317_W) +XE_GPU_REGISTER(0x44F8, kFloat, SHADER_CONSTANT_318_X) +XE_GPU_REGISTER(0x44F9, kFloat, SHADER_CONSTANT_318_Y) +XE_GPU_REGISTER(0x44FA, kFloat, SHADER_CONSTANT_318_Z) +XE_GPU_REGISTER(0x44FB, kFloat, SHADER_CONSTANT_318_W) +XE_GPU_REGISTER(0x44FC, kFloat, SHADER_CONSTANT_319_X) +XE_GPU_REGISTER(0x44FD, kFloat, SHADER_CONSTANT_319_Y) +XE_GPU_REGISTER(0x44FE, kFloat, SHADER_CONSTANT_319_Z) +XE_GPU_REGISTER(0x44FF, kFloat, SHADER_CONSTANT_319_W) +XE_GPU_REGISTER(0x4500, kFloat, SHADER_CONSTANT_320_X) +XE_GPU_REGISTER(0x4501, kFloat, SHADER_CONSTANT_320_Y) +XE_GPU_REGISTER(0x4502, kFloat, SHADER_CONSTANT_320_Z) +XE_GPU_REGISTER(0x4503, kFloat, SHADER_CONSTANT_320_W) +XE_GPU_REGISTER(0x4504, kFloat, SHADER_CONSTANT_321_X) +XE_GPU_REGISTER(0x4505, kFloat, SHADER_CONSTANT_321_Y) +XE_GPU_REGISTER(0x4506, kFloat, SHADER_CONSTANT_321_Z) +XE_GPU_REGISTER(0x4507, kFloat, SHADER_CONSTANT_321_W) +XE_GPU_REGISTER(0x4508, kFloat, SHADER_CONSTANT_322_X) +XE_GPU_REGISTER(0x4509, kFloat, SHADER_CONSTANT_322_Y) +XE_GPU_REGISTER(0x450A, kFloat, SHADER_CONSTANT_322_Z) +XE_GPU_REGISTER(0x450B, kFloat, SHADER_CONSTANT_322_W) +XE_GPU_REGISTER(0x450C, kFloat, SHADER_CONSTANT_323_X) +XE_GPU_REGISTER(0x450D, kFloat, SHADER_CONSTANT_323_Y) +XE_GPU_REGISTER(0x450E, kFloat, SHADER_CONSTANT_323_Z) +XE_GPU_REGISTER(0x450F, kFloat, SHADER_CONSTANT_323_W) +XE_GPU_REGISTER(0x4510, kFloat, SHADER_CONSTANT_324_X) +XE_GPU_REGISTER(0x4511, kFloat, SHADER_CONSTANT_324_Y) +XE_GPU_REGISTER(0x4512, kFloat, SHADER_CONSTANT_324_Z) +XE_GPU_REGISTER(0x4513, kFloat, SHADER_CONSTANT_324_W) +XE_GPU_REGISTER(0x4514, kFloat, SHADER_CONSTANT_325_X) +XE_GPU_REGISTER(0x4515, kFloat, SHADER_CONSTANT_325_Y) +XE_GPU_REGISTER(0x4516, kFloat, SHADER_CONSTANT_325_Z) +XE_GPU_REGISTER(0x4517, kFloat, SHADER_CONSTANT_325_W) +XE_GPU_REGISTER(0x4518, kFloat, SHADER_CONSTANT_326_X) +XE_GPU_REGISTER(0x4519, kFloat, SHADER_CONSTANT_326_Y) +XE_GPU_REGISTER(0x451A, kFloat, SHADER_CONSTANT_326_Z) +XE_GPU_REGISTER(0x451B, kFloat, SHADER_CONSTANT_326_W) +XE_GPU_REGISTER(0x451C, kFloat, SHADER_CONSTANT_327_X) +XE_GPU_REGISTER(0x451D, kFloat, SHADER_CONSTANT_327_Y) +XE_GPU_REGISTER(0x451E, kFloat, SHADER_CONSTANT_327_Z) +XE_GPU_REGISTER(0x451F, kFloat, SHADER_CONSTANT_327_W) +XE_GPU_REGISTER(0x4520, kFloat, SHADER_CONSTANT_328_X) +XE_GPU_REGISTER(0x4521, kFloat, SHADER_CONSTANT_328_Y) +XE_GPU_REGISTER(0x4522, kFloat, SHADER_CONSTANT_328_Z) +XE_GPU_REGISTER(0x4523, kFloat, SHADER_CONSTANT_328_W) +XE_GPU_REGISTER(0x4524, kFloat, SHADER_CONSTANT_329_X) +XE_GPU_REGISTER(0x4525, kFloat, SHADER_CONSTANT_329_Y) +XE_GPU_REGISTER(0x4526, kFloat, SHADER_CONSTANT_329_Z) +XE_GPU_REGISTER(0x4527, kFloat, SHADER_CONSTANT_329_W) +XE_GPU_REGISTER(0x4528, kFloat, SHADER_CONSTANT_330_X) +XE_GPU_REGISTER(0x4529, kFloat, SHADER_CONSTANT_330_Y) +XE_GPU_REGISTER(0x452A, kFloat, SHADER_CONSTANT_330_Z) +XE_GPU_REGISTER(0x452B, kFloat, SHADER_CONSTANT_330_W) +XE_GPU_REGISTER(0x452C, kFloat, SHADER_CONSTANT_331_X) +XE_GPU_REGISTER(0x452D, kFloat, SHADER_CONSTANT_331_Y) +XE_GPU_REGISTER(0x452E, kFloat, SHADER_CONSTANT_331_Z) +XE_GPU_REGISTER(0x452F, kFloat, SHADER_CONSTANT_331_W) +XE_GPU_REGISTER(0x4530, kFloat, SHADER_CONSTANT_332_X) +XE_GPU_REGISTER(0x4531, kFloat, SHADER_CONSTANT_332_Y) +XE_GPU_REGISTER(0x4532, kFloat, SHADER_CONSTANT_332_Z) +XE_GPU_REGISTER(0x4533, kFloat, SHADER_CONSTANT_332_W) +XE_GPU_REGISTER(0x4534, kFloat, SHADER_CONSTANT_333_X) +XE_GPU_REGISTER(0x4535, kFloat, SHADER_CONSTANT_333_Y) +XE_GPU_REGISTER(0x4536, kFloat, SHADER_CONSTANT_333_Z) +XE_GPU_REGISTER(0x4537, kFloat, SHADER_CONSTANT_333_W) +XE_GPU_REGISTER(0x4538, kFloat, SHADER_CONSTANT_334_X) +XE_GPU_REGISTER(0x4539, kFloat, SHADER_CONSTANT_334_Y) +XE_GPU_REGISTER(0x453A, kFloat, SHADER_CONSTANT_334_Z) +XE_GPU_REGISTER(0x453B, kFloat, SHADER_CONSTANT_334_W) +XE_GPU_REGISTER(0x453C, kFloat, SHADER_CONSTANT_335_X) +XE_GPU_REGISTER(0x453D, kFloat, SHADER_CONSTANT_335_Y) +XE_GPU_REGISTER(0x453E, kFloat, SHADER_CONSTANT_335_Z) +XE_GPU_REGISTER(0x453F, kFloat, SHADER_CONSTANT_335_W) +XE_GPU_REGISTER(0x4540, kFloat, SHADER_CONSTANT_336_X) +XE_GPU_REGISTER(0x4541, kFloat, SHADER_CONSTANT_336_Y) +XE_GPU_REGISTER(0x4542, kFloat, SHADER_CONSTANT_336_Z) +XE_GPU_REGISTER(0x4543, kFloat, SHADER_CONSTANT_336_W) +XE_GPU_REGISTER(0x4544, kFloat, SHADER_CONSTANT_337_X) +XE_GPU_REGISTER(0x4545, kFloat, SHADER_CONSTANT_337_Y) +XE_GPU_REGISTER(0x4546, kFloat, SHADER_CONSTANT_337_Z) +XE_GPU_REGISTER(0x4547, kFloat, SHADER_CONSTANT_337_W) +XE_GPU_REGISTER(0x4548, kFloat, SHADER_CONSTANT_338_X) +XE_GPU_REGISTER(0x4549, kFloat, SHADER_CONSTANT_338_Y) +XE_GPU_REGISTER(0x454A, kFloat, SHADER_CONSTANT_338_Z) +XE_GPU_REGISTER(0x454B, kFloat, SHADER_CONSTANT_338_W) +XE_GPU_REGISTER(0x454C, kFloat, SHADER_CONSTANT_339_X) +XE_GPU_REGISTER(0x454D, kFloat, SHADER_CONSTANT_339_Y) +XE_GPU_REGISTER(0x454E, kFloat, SHADER_CONSTANT_339_Z) +XE_GPU_REGISTER(0x454F, kFloat, SHADER_CONSTANT_339_W) +XE_GPU_REGISTER(0x4550, kFloat, SHADER_CONSTANT_340_X) +XE_GPU_REGISTER(0x4551, kFloat, SHADER_CONSTANT_340_Y) +XE_GPU_REGISTER(0x4552, kFloat, SHADER_CONSTANT_340_Z) +XE_GPU_REGISTER(0x4553, kFloat, SHADER_CONSTANT_340_W) +XE_GPU_REGISTER(0x4554, kFloat, SHADER_CONSTANT_341_X) +XE_GPU_REGISTER(0x4555, kFloat, SHADER_CONSTANT_341_Y) +XE_GPU_REGISTER(0x4556, kFloat, SHADER_CONSTANT_341_Z) +XE_GPU_REGISTER(0x4557, kFloat, SHADER_CONSTANT_341_W) +XE_GPU_REGISTER(0x4558, kFloat, SHADER_CONSTANT_342_X) +XE_GPU_REGISTER(0x4559, kFloat, SHADER_CONSTANT_342_Y) +XE_GPU_REGISTER(0x455A, kFloat, SHADER_CONSTANT_342_Z) +XE_GPU_REGISTER(0x455B, kFloat, SHADER_CONSTANT_342_W) +XE_GPU_REGISTER(0x455C, kFloat, SHADER_CONSTANT_343_X) +XE_GPU_REGISTER(0x455D, kFloat, SHADER_CONSTANT_343_Y) +XE_GPU_REGISTER(0x455E, kFloat, SHADER_CONSTANT_343_Z) +XE_GPU_REGISTER(0x455F, kFloat, SHADER_CONSTANT_343_W) +XE_GPU_REGISTER(0x4560, kFloat, SHADER_CONSTANT_344_X) +XE_GPU_REGISTER(0x4561, kFloat, SHADER_CONSTANT_344_Y) +XE_GPU_REGISTER(0x4562, kFloat, SHADER_CONSTANT_344_Z) +XE_GPU_REGISTER(0x4563, kFloat, SHADER_CONSTANT_344_W) +XE_GPU_REGISTER(0x4564, kFloat, SHADER_CONSTANT_345_X) +XE_GPU_REGISTER(0x4565, kFloat, SHADER_CONSTANT_345_Y) +XE_GPU_REGISTER(0x4566, kFloat, SHADER_CONSTANT_345_Z) +XE_GPU_REGISTER(0x4567, kFloat, SHADER_CONSTANT_345_W) +XE_GPU_REGISTER(0x4568, kFloat, SHADER_CONSTANT_346_X) +XE_GPU_REGISTER(0x4569, kFloat, SHADER_CONSTANT_346_Y) +XE_GPU_REGISTER(0x456A, kFloat, SHADER_CONSTANT_346_Z) +XE_GPU_REGISTER(0x456B, kFloat, SHADER_CONSTANT_346_W) +XE_GPU_REGISTER(0x456C, kFloat, SHADER_CONSTANT_347_X) +XE_GPU_REGISTER(0x456D, kFloat, SHADER_CONSTANT_347_Y) +XE_GPU_REGISTER(0x456E, kFloat, SHADER_CONSTANT_347_Z) +XE_GPU_REGISTER(0x456F, kFloat, SHADER_CONSTANT_347_W) +XE_GPU_REGISTER(0x4570, kFloat, SHADER_CONSTANT_348_X) +XE_GPU_REGISTER(0x4571, kFloat, SHADER_CONSTANT_348_Y) +XE_GPU_REGISTER(0x4572, kFloat, SHADER_CONSTANT_348_Z) +XE_GPU_REGISTER(0x4573, kFloat, SHADER_CONSTANT_348_W) +XE_GPU_REGISTER(0x4574, kFloat, SHADER_CONSTANT_349_X) +XE_GPU_REGISTER(0x4575, kFloat, SHADER_CONSTANT_349_Y) +XE_GPU_REGISTER(0x4576, kFloat, SHADER_CONSTANT_349_Z) +XE_GPU_REGISTER(0x4577, kFloat, SHADER_CONSTANT_349_W) +XE_GPU_REGISTER(0x4578, kFloat, SHADER_CONSTANT_350_X) +XE_GPU_REGISTER(0x4579, kFloat, SHADER_CONSTANT_350_Y) +XE_GPU_REGISTER(0x457A, kFloat, SHADER_CONSTANT_350_Z) +XE_GPU_REGISTER(0x457B, kFloat, SHADER_CONSTANT_350_W) +XE_GPU_REGISTER(0x457C, kFloat, SHADER_CONSTANT_351_X) +XE_GPU_REGISTER(0x457D, kFloat, SHADER_CONSTANT_351_Y) +XE_GPU_REGISTER(0x457E, kFloat, SHADER_CONSTANT_351_Z) +XE_GPU_REGISTER(0x457F, kFloat, SHADER_CONSTANT_351_W) +XE_GPU_REGISTER(0x4580, kFloat, SHADER_CONSTANT_352_X) +XE_GPU_REGISTER(0x4581, kFloat, SHADER_CONSTANT_352_Y) +XE_GPU_REGISTER(0x4582, kFloat, SHADER_CONSTANT_352_Z) +XE_GPU_REGISTER(0x4583, kFloat, SHADER_CONSTANT_352_W) +XE_GPU_REGISTER(0x4584, kFloat, SHADER_CONSTANT_353_X) +XE_GPU_REGISTER(0x4585, kFloat, SHADER_CONSTANT_353_Y) +XE_GPU_REGISTER(0x4586, kFloat, SHADER_CONSTANT_353_Z) +XE_GPU_REGISTER(0x4587, kFloat, SHADER_CONSTANT_353_W) +XE_GPU_REGISTER(0x4588, kFloat, SHADER_CONSTANT_354_X) +XE_GPU_REGISTER(0x4589, kFloat, SHADER_CONSTANT_354_Y) +XE_GPU_REGISTER(0x458A, kFloat, SHADER_CONSTANT_354_Z) +XE_GPU_REGISTER(0x458B, kFloat, SHADER_CONSTANT_354_W) +XE_GPU_REGISTER(0x458C, kFloat, SHADER_CONSTANT_355_X) +XE_GPU_REGISTER(0x458D, kFloat, SHADER_CONSTANT_355_Y) +XE_GPU_REGISTER(0x458E, kFloat, SHADER_CONSTANT_355_Z) +XE_GPU_REGISTER(0x458F, kFloat, SHADER_CONSTANT_355_W) +XE_GPU_REGISTER(0x4590, kFloat, SHADER_CONSTANT_356_X) +XE_GPU_REGISTER(0x4591, kFloat, SHADER_CONSTANT_356_Y) +XE_GPU_REGISTER(0x4592, kFloat, SHADER_CONSTANT_356_Z) +XE_GPU_REGISTER(0x4593, kFloat, SHADER_CONSTANT_356_W) +XE_GPU_REGISTER(0x4594, kFloat, SHADER_CONSTANT_357_X) +XE_GPU_REGISTER(0x4595, kFloat, SHADER_CONSTANT_357_Y) +XE_GPU_REGISTER(0x4596, kFloat, SHADER_CONSTANT_357_Z) +XE_GPU_REGISTER(0x4597, kFloat, SHADER_CONSTANT_357_W) +XE_GPU_REGISTER(0x4598, kFloat, SHADER_CONSTANT_358_X) +XE_GPU_REGISTER(0x4599, kFloat, SHADER_CONSTANT_358_Y) +XE_GPU_REGISTER(0x459A, kFloat, SHADER_CONSTANT_358_Z) +XE_GPU_REGISTER(0x459B, kFloat, SHADER_CONSTANT_358_W) +XE_GPU_REGISTER(0x459C, kFloat, SHADER_CONSTANT_359_X) +XE_GPU_REGISTER(0x459D, kFloat, SHADER_CONSTANT_359_Y) +XE_GPU_REGISTER(0x459E, kFloat, SHADER_CONSTANT_359_Z) +XE_GPU_REGISTER(0x459F, kFloat, SHADER_CONSTANT_359_W) +XE_GPU_REGISTER(0x45A0, kFloat, SHADER_CONSTANT_360_X) +XE_GPU_REGISTER(0x45A1, kFloat, SHADER_CONSTANT_360_Y) +XE_GPU_REGISTER(0x45A2, kFloat, SHADER_CONSTANT_360_Z) +XE_GPU_REGISTER(0x45A3, kFloat, SHADER_CONSTANT_360_W) +XE_GPU_REGISTER(0x45A4, kFloat, SHADER_CONSTANT_361_X) +XE_GPU_REGISTER(0x45A5, kFloat, SHADER_CONSTANT_361_Y) +XE_GPU_REGISTER(0x45A6, kFloat, SHADER_CONSTANT_361_Z) +XE_GPU_REGISTER(0x45A7, kFloat, SHADER_CONSTANT_361_W) +XE_GPU_REGISTER(0x45A8, kFloat, SHADER_CONSTANT_362_X) +XE_GPU_REGISTER(0x45A9, kFloat, SHADER_CONSTANT_362_Y) +XE_GPU_REGISTER(0x45AA, kFloat, SHADER_CONSTANT_362_Z) +XE_GPU_REGISTER(0x45AB, kFloat, SHADER_CONSTANT_362_W) +XE_GPU_REGISTER(0x45AC, kFloat, SHADER_CONSTANT_363_X) +XE_GPU_REGISTER(0x45AD, kFloat, SHADER_CONSTANT_363_Y) +XE_GPU_REGISTER(0x45AE, kFloat, SHADER_CONSTANT_363_Z) +XE_GPU_REGISTER(0x45AF, kFloat, SHADER_CONSTANT_363_W) +XE_GPU_REGISTER(0x45B0, kFloat, SHADER_CONSTANT_364_X) +XE_GPU_REGISTER(0x45B1, kFloat, SHADER_CONSTANT_364_Y) +XE_GPU_REGISTER(0x45B2, kFloat, SHADER_CONSTANT_364_Z) +XE_GPU_REGISTER(0x45B3, kFloat, SHADER_CONSTANT_364_W) +XE_GPU_REGISTER(0x45B4, kFloat, SHADER_CONSTANT_365_X) +XE_GPU_REGISTER(0x45B5, kFloat, SHADER_CONSTANT_365_Y) +XE_GPU_REGISTER(0x45B6, kFloat, SHADER_CONSTANT_365_Z) +XE_GPU_REGISTER(0x45B7, kFloat, SHADER_CONSTANT_365_W) +XE_GPU_REGISTER(0x45B8, kFloat, SHADER_CONSTANT_366_X) +XE_GPU_REGISTER(0x45B9, kFloat, SHADER_CONSTANT_366_Y) +XE_GPU_REGISTER(0x45BA, kFloat, SHADER_CONSTANT_366_Z) +XE_GPU_REGISTER(0x45BB, kFloat, SHADER_CONSTANT_366_W) +XE_GPU_REGISTER(0x45BC, kFloat, SHADER_CONSTANT_367_X) +XE_GPU_REGISTER(0x45BD, kFloat, SHADER_CONSTANT_367_Y) +XE_GPU_REGISTER(0x45BE, kFloat, SHADER_CONSTANT_367_Z) +XE_GPU_REGISTER(0x45BF, kFloat, SHADER_CONSTANT_367_W) +XE_GPU_REGISTER(0x45C0, kFloat, SHADER_CONSTANT_368_X) +XE_GPU_REGISTER(0x45C1, kFloat, SHADER_CONSTANT_368_Y) +XE_GPU_REGISTER(0x45C2, kFloat, SHADER_CONSTANT_368_Z) +XE_GPU_REGISTER(0x45C3, kFloat, SHADER_CONSTANT_368_W) +XE_GPU_REGISTER(0x45C4, kFloat, SHADER_CONSTANT_369_X) +XE_GPU_REGISTER(0x45C5, kFloat, SHADER_CONSTANT_369_Y) +XE_GPU_REGISTER(0x45C6, kFloat, SHADER_CONSTANT_369_Z) +XE_GPU_REGISTER(0x45C7, kFloat, SHADER_CONSTANT_369_W) +XE_GPU_REGISTER(0x45C8, kFloat, SHADER_CONSTANT_370_X) +XE_GPU_REGISTER(0x45C9, kFloat, SHADER_CONSTANT_370_Y) +XE_GPU_REGISTER(0x45CA, kFloat, SHADER_CONSTANT_370_Z) +XE_GPU_REGISTER(0x45CB, kFloat, SHADER_CONSTANT_370_W) +XE_GPU_REGISTER(0x45CC, kFloat, SHADER_CONSTANT_371_X) +XE_GPU_REGISTER(0x45CD, kFloat, SHADER_CONSTANT_371_Y) +XE_GPU_REGISTER(0x45CE, kFloat, SHADER_CONSTANT_371_Z) +XE_GPU_REGISTER(0x45CF, kFloat, SHADER_CONSTANT_371_W) +XE_GPU_REGISTER(0x45D0, kFloat, SHADER_CONSTANT_372_X) +XE_GPU_REGISTER(0x45D1, kFloat, SHADER_CONSTANT_372_Y) +XE_GPU_REGISTER(0x45D2, kFloat, SHADER_CONSTANT_372_Z) +XE_GPU_REGISTER(0x45D3, kFloat, SHADER_CONSTANT_372_W) +XE_GPU_REGISTER(0x45D4, kFloat, SHADER_CONSTANT_373_X) +XE_GPU_REGISTER(0x45D5, kFloat, SHADER_CONSTANT_373_Y) +XE_GPU_REGISTER(0x45D6, kFloat, SHADER_CONSTANT_373_Z) +XE_GPU_REGISTER(0x45D7, kFloat, SHADER_CONSTANT_373_W) +XE_GPU_REGISTER(0x45D8, kFloat, SHADER_CONSTANT_374_X) +XE_GPU_REGISTER(0x45D9, kFloat, SHADER_CONSTANT_374_Y) +XE_GPU_REGISTER(0x45DA, kFloat, SHADER_CONSTANT_374_Z) +XE_GPU_REGISTER(0x45DB, kFloat, SHADER_CONSTANT_374_W) +XE_GPU_REGISTER(0x45DC, kFloat, SHADER_CONSTANT_375_X) +XE_GPU_REGISTER(0x45DD, kFloat, SHADER_CONSTANT_375_Y) +XE_GPU_REGISTER(0x45DE, kFloat, SHADER_CONSTANT_375_Z) +XE_GPU_REGISTER(0x45DF, kFloat, SHADER_CONSTANT_375_W) +XE_GPU_REGISTER(0x45E0, kFloat, SHADER_CONSTANT_376_X) +XE_GPU_REGISTER(0x45E1, kFloat, SHADER_CONSTANT_376_Y) +XE_GPU_REGISTER(0x45E2, kFloat, SHADER_CONSTANT_376_Z) +XE_GPU_REGISTER(0x45E3, kFloat, SHADER_CONSTANT_376_W) +XE_GPU_REGISTER(0x45E4, kFloat, SHADER_CONSTANT_377_X) +XE_GPU_REGISTER(0x45E5, kFloat, SHADER_CONSTANT_377_Y) +XE_GPU_REGISTER(0x45E6, kFloat, SHADER_CONSTANT_377_Z) +XE_GPU_REGISTER(0x45E7, kFloat, SHADER_CONSTANT_377_W) +XE_GPU_REGISTER(0x45E8, kFloat, SHADER_CONSTANT_378_X) +XE_GPU_REGISTER(0x45E9, kFloat, SHADER_CONSTANT_378_Y) +XE_GPU_REGISTER(0x45EA, kFloat, SHADER_CONSTANT_378_Z) +XE_GPU_REGISTER(0x45EB, kFloat, SHADER_CONSTANT_378_W) +XE_GPU_REGISTER(0x45EC, kFloat, SHADER_CONSTANT_379_X) +XE_GPU_REGISTER(0x45ED, kFloat, SHADER_CONSTANT_379_Y) +XE_GPU_REGISTER(0x45EE, kFloat, SHADER_CONSTANT_379_Z) +XE_GPU_REGISTER(0x45EF, kFloat, SHADER_CONSTANT_379_W) +XE_GPU_REGISTER(0x45F0, kFloat, SHADER_CONSTANT_380_X) +XE_GPU_REGISTER(0x45F1, kFloat, SHADER_CONSTANT_380_Y) +XE_GPU_REGISTER(0x45F2, kFloat, SHADER_CONSTANT_380_Z) +XE_GPU_REGISTER(0x45F3, kFloat, SHADER_CONSTANT_380_W) +XE_GPU_REGISTER(0x45F4, kFloat, SHADER_CONSTANT_381_X) +XE_GPU_REGISTER(0x45F5, kFloat, SHADER_CONSTANT_381_Y) +XE_GPU_REGISTER(0x45F6, kFloat, SHADER_CONSTANT_381_Z) +XE_GPU_REGISTER(0x45F7, kFloat, SHADER_CONSTANT_381_W) +XE_GPU_REGISTER(0x45F8, kFloat, SHADER_CONSTANT_382_X) +XE_GPU_REGISTER(0x45F9, kFloat, SHADER_CONSTANT_382_Y) +XE_GPU_REGISTER(0x45FA, kFloat, SHADER_CONSTANT_382_Z) +XE_GPU_REGISTER(0x45FB, kFloat, SHADER_CONSTANT_382_W) +XE_GPU_REGISTER(0x45FC, kFloat, SHADER_CONSTANT_383_X) +XE_GPU_REGISTER(0x45FD, kFloat, SHADER_CONSTANT_383_Y) +XE_GPU_REGISTER(0x45FE, kFloat, SHADER_CONSTANT_383_Z) +XE_GPU_REGISTER(0x45FF, kFloat, SHADER_CONSTANT_383_W) +XE_GPU_REGISTER(0x4600, kFloat, SHADER_CONSTANT_384_X) +XE_GPU_REGISTER(0x4601, kFloat, SHADER_CONSTANT_384_Y) +XE_GPU_REGISTER(0x4602, kFloat, SHADER_CONSTANT_384_Z) +XE_GPU_REGISTER(0x4603, kFloat, SHADER_CONSTANT_384_W) +XE_GPU_REGISTER(0x4604, kFloat, SHADER_CONSTANT_385_X) +XE_GPU_REGISTER(0x4605, kFloat, SHADER_CONSTANT_385_Y) +XE_GPU_REGISTER(0x4606, kFloat, SHADER_CONSTANT_385_Z) +XE_GPU_REGISTER(0x4607, kFloat, SHADER_CONSTANT_385_W) +XE_GPU_REGISTER(0x4608, kFloat, SHADER_CONSTANT_386_X) +XE_GPU_REGISTER(0x4609, kFloat, SHADER_CONSTANT_386_Y) +XE_GPU_REGISTER(0x460A, kFloat, SHADER_CONSTANT_386_Z) +XE_GPU_REGISTER(0x460B, kFloat, SHADER_CONSTANT_386_W) +XE_GPU_REGISTER(0x460C, kFloat, SHADER_CONSTANT_387_X) +XE_GPU_REGISTER(0x460D, kFloat, SHADER_CONSTANT_387_Y) +XE_GPU_REGISTER(0x460E, kFloat, SHADER_CONSTANT_387_Z) +XE_GPU_REGISTER(0x460F, kFloat, SHADER_CONSTANT_387_W) +XE_GPU_REGISTER(0x4610, kFloat, SHADER_CONSTANT_388_X) +XE_GPU_REGISTER(0x4611, kFloat, SHADER_CONSTANT_388_Y) +XE_GPU_REGISTER(0x4612, kFloat, SHADER_CONSTANT_388_Z) +XE_GPU_REGISTER(0x4613, kFloat, SHADER_CONSTANT_388_W) +XE_GPU_REGISTER(0x4614, kFloat, SHADER_CONSTANT_389_X) +XE_GPU_REGISTER(0x4615, kFloat, SHADER_CONSTANT_389_Y) +XE_GPU_REGISTER(0x4616, kFloat, SHADER_CONSTANT_389_Z) +XE_GPU_REGISTER(0x4617, kFloat, SHADER_CONSTANT_389_W) +XE_GPU_REGISTER(0x4618, kFloat, SHADER_CONSTANT_390_X) +XE_GPU_REGISTER(0x4619, kFloat, SHADER_CONSTANT_390_Y) +XE_GPU_REGISTER(0x461A, kFloat, SHADER_CONSTANT_390_Z) +XE_GPU_REGISTER(0x461B, kFloat, SHADER_CONSTANT_390_W) +XE_GPU_REGISTER(0x461C, kFloat, SHADER_CONSTANT_391_X) +XE_GPU_REGISTER(0x461D, kFloat, SHADER_CONSTANT_391_Y) +XE_GPU_REGISTER(0x461E, kFloat, SHADER_CONSTANT_391_Z) +XE_GPU_REGISTER(0x461F, kFloat, SHADER_CONSTANT_391_W) +XE_GPU_REGISTER(0x4620, kFloat, SHADER_CONSTANT_392_X) +XE_GPU_REGISTER(0x4621, kFloat, SHADER_CONSTANT_392_Y) +XE_GPU_REGISTER(0x4622, kFloat, SHADER_CONSTANT_392_Z) +XE_GPU_REGISTER(0x4623, kFloat, SHADER_CONSTANT_392_W) +XE_GPU_REGISTER(0x4624, kFloat, SHADER_CONSTANT_393_X) +XE_GPU_REGISTER(0x4625, kFloat, SHADER_CONSTANT_393_Y) +XE_GPU_REGISTER(0x4626, kFloat, SHADER_CONSTANT_393_Z) +XE_GPU_REGISTER(0x4627, kFloat, SHADER_CONSTANT_393_W) +XE_GPU_REGISTER(0x4628, kFloat, SHADER_CONSTANT_394_X) +XE_GPU_REGISTER(0x4629, kFloat, SHADER_CONSTANT_394_Y) +XE_GPU_REGISTER(0x462A, kFloat, SHADER_CONSTANT_394_Z) +XE_GPU_REGISTER(0x462B, kFloat, SHADER_CONSTANT_394_W) +XE_GPU_REGISTER(0x462C, kFloat, SHADER_CONSTANT_395_X) +XE_GPU_REGISTER(0x462D, kFloat, SHADER_CONSTANT_395_Y) +XE_GPU_REGISTER(0x462E, kFloat, SHADER_CONSTANT_395_Z) +XE_GPU_REGISTER(0x462F, kFloat, SHADER_CONSTANT_395_W) +XE_GPU_REGISTER(0x4630, kFloat, SHADER_CONSTANT_396_X) +XE_GPU_REGISTER(0x4631, kFloat, SHADER_CONSTANT_396_Y) +XE_GPU_REGISTER(0x4632, kFloat, SHADER_CONSTANT_396_Z) +XE_GPU_REGISTER(0x4633, kFloat, SHADER_CONSTANT_396_W) +XE_GPU_REGISTER(0x4634, kFloat, SHADER_CONSTANT_397_X) +XE_GPU_REGISTER(0x4635, kFloat, SHADER_CONSTANT_397_Y) +XE_GPU_REGISTER(0x4636, kFloat, SHADER_CONSTANT_397_Z) +XE_GPU_REGISTER(0x4637, kFloat, SHADER_CONSTANT_397_W) +XE_GPU_REGISTER(0x4638, kFloat, SHADER_CONSTANT_398_X) +XE_GPU_REGISTER(0x4639, kFloat, SHADER_CONSTANT_398_Y) +XE_GPU_REGISTER(0x463A, kFloat, SHADER_CONSTANT_398_Z) +XE_GPU_REGISTER(0x463B, kFloat, SHADER_CONSTANT_398_W) +XE_GPU_REGISTER(0x463C, kFloat, SHADER_CONSTANT_399_X) +XE_GPU_REGISTER(0x463D, kFloat, SHADER_CONSTANT_399_Y) +XE_GPU_REGISTER(0x463E, kFloat, SHADER_CONSTANT_399_Z) +XE_GPU_REGISTER(0x463F, kFloat, SHADER_CONSTANT_399_W) +XE_GPU_REGISTER(0x4640, kFloat, SHADER_CONSTANT_400_X) +XE_GPU_REGISTER(0x4641, kFloat, SHADER_CONSTANT_400_Y) +XE_GPU_REGISTER(0x4642, kFloat, SHADER_CONSTANT_400_Z) +XE_GPU_REGISTER(0x4643, kFloat, SHADER_CONSTANT_400_W) +XE_GPU_REGISTER(0x4644, kFloat, SHADER_CONSTANT_401_X) +XE_GPU_REGISTER(0x4645, kFloat, SHADER_CONSTANT_401_Y) +XE_GPU_REGISTER(0x4646, kFloat, SHADER_CONSTANT_401_Z) +XE_GPU_REGISTER(0x4647, kFloat, SHADER_CONSTANT_401_W) +XE_GPU_REGISTER(0x4648, kFloat, SHADER_CONSTANT_402_X) +XE_GPU_REGISTER(0x4649, kFloat, SHADER_CONSTANT_402_Y) +XE_GPU_REGISTER(0x464A, kFloat, SHADER_CONSTANT_402_Z) +XE_GPU_REGISTER(0x464B, kFloat, SHADER_CONSTANT_402_W) +XE_GPU_REGISTER(0x464C, kFloat, SHADER_CONSTANT_403_X) +XE_GPU_REGISTER(0x464D, kFloat, SHADER_CONSTANT_403_Y) +XE_GPU_REGISTER(0x464E, kFloat, SHADER_CONSTANT_403_Z) +XE_GPU_REGISTER(0x464F, kFloat, SHADER_CONSTANT_403_W) +XE_GPU_REGISTER(0x4650, kFloat, SHADER_CONSTANT_404_X) +XE_GPU_REGISTER(0x4651, kFloat, SHADER_CONSTANT_404_Y) +XE_GPU_REGISTER(0x4652, kFloat, SHADER_CONSTANT_404_Z) +XE_GPU_REGISTER(0x4653, kFloat, SHADER_CONSTANT_404_W) +XE_GPU_REGISTER(0x4654, kFloat, SHADER_CONSTANT_405_X) +XE_GPU_REGISTER(0x4655, kFloat, SHADER_CONSTANT_405_Y) +XE_GPU_REGISTER(0x4656, kFloat, SHADER_CONSTANT_405_Z) +XE_GPU_REGISTER(0x4657, kFloat, SHADER_CONSTANT_405_W) +XE_GPU_REGISTER(0x4658, kFloat, SHADER_CONSTANT_406_X) +XE_GPU_REGISTER(0x4659, kFloat, SHADER_CONSTANT_406_Y) +XE_GPU_REGISTER(0x465A, kFloat, SHADER_CONSTANT_406_Z) +XE_GPU_REGISTER(0x465B, kFloat, SHADER_CONSTANT_406_W) +XE_GPU_REGISTER(0x465C, kFloat, SHADER_CONSTANT_407_X) +XE_GPU_REGISTER(0x465D, kFloat, SHADER_CONSTANT_407_Y) +XE_GPU_REGISTER(0x465E, kFloat, SHADER_CONSTANT_407_Z) +XE_GPU_REGISTER(0x465F, kFloat, SHADER_CONSTANT_407_W) +XE_GPU_REGISTER(0x4660, kFloat, SHADER_CONSTANT_408_X) +XE_GPU_REGISTER(0x4661, kFloat, SHADER_CONSTANT_408_Y) +XE_GPU_REGISTER(0x4662, kFloat, SHADER_CONSTANT_408_Z) +XE_GPU_REGISTER(0x4663, kFloat, SHADER_CONSTANT_408_W) +XE_GPU_REGISTER(0x4664, kFloat, SHADER_CONSTANT_409_X) +XE_GPU_REGISTER(0x4665, kFloat, SHADER_CONSTANT_409_Y) +XE_GPU_REGISTER(0x4666, kFloat, SHADER_CONSTANT_409_Z) +XE_GPU_REGISTER(0x4667, kFloat, SHADER_CONSTANT_409_W) +XE_GPU_REGISTER(0x4668, kFloat, SHADER_CONSTANT_410_X) +XE_GPU_REGISTER(0x4669, kFloat, SHADER_CONSTANT_410_Y) +XE_GPU_REGISTER(0x466A, kFloat, SHADER_CONSTANT_410_Z) +XE_GPU_REGISTER(0x466B, kFloat, SHADER_CONSTANT_410_W) +XE_GPU_REGISTER(0x466C, kFloat, SHADER_CONSTANT_411_X) +XE_GPU_REGISTER(0x466D, kFloat, SHADER_CONSTANT_411_Y) +XE_GPU_REGISTER(0x466E, kFloat, SHADER_CONSTANT_411_Z) +XE_GPU_REGISTER(0x466F, kFloat, SHADER_CONSTANT_411_W) +XE_GPU_REGISTER(0x4670, kFloat, SHADER_CONSTANT_412_X) +XE_GPU_REGISTER(0x4671, kFloat, SHADER_CONSTANT_412_Y) +XE_GPU_REGISTER(0x4672, kFloat, SHADER_CONSTANT_412_Z) +XE_GPU_REGISTER(0x4673, kFloat, SHADER_CONSTANT_412_W) +XE_GPU_REGISTER(0x4674, kFloat, SHADER_CONSTANT_413_X) +XE_GPU_REGISTER(0x4675, kFloat, SHADER_CONSTANT_413_Y) +XE_GPU_REGISTER(0x4676, kFloat, SHADER_CONSTANT_413_Z) +XE_GPU_REGISTER(0x4677, kFloat, SHADER_CONSTANT_413_W) +XE_GPU_REGISTER(0x4678, kFloat, SHADER_CONSTANT_414_X) +XE_GPU_REGISTER(0x4679, kFloat, SHADER_CONSTANT_414_Y) +XE_GPU_REGISTER(0x467A, kFloat, SHADER_CONSTANT_414_Z) +XE_GPU_REGISTER(0x467B, kFloat, SHADER_CONSTANT_414_W) +XE_GPU_REGISTER(0x467C, kFloat, SHADER_CONSTANT_415_X) +XE_GPU_REGISTER(0x467D, kFloat, SHADER_CONSTANT_415_Y) +XE_GPU_REGISTER(0x467E, kFloat, SHADER_CONSTANT_415_Z) +XE_GPU_REGISTER(0x467F, kFloat, SHADER_CONSTANT_415_W) +XE_GPU_REGISTER(0x4680, kFloat, SHADER_CONSTANT_416_X) +XE_GPU_REGISTER(0x4681, kFloat, SHADER_CONSTANT_416_Y) +XE_GPU_REGISTER(0x4682, kFloat, SHADER_CONSTANT_416_Z) +XE_GPU_REGISTER(0x4683, kFloat, SHADER_CONSTANT_416_W) +XE_GPU_REGISTER(0x4684, kFloat, SHADER_CONSTANT_417_X) +XE_GPU_REGISTER(0x4685, kFloat, SHADER_CONSTANT_417_Y) +XE_GPU_REGISTER(0x4686, kFloat, SHADER_CONSTANT_417_Z) +XE_GPU_REGISTER(0x4687, kFloat, SHADER_CONSTANT_417_W) +XE_GPU_REGISTER(0x4688, kFloat, SHADER_CONSTANT_418_X) +XE_GPU_REGISTER(0x4689, kFloat, SHADER_CONSTANT_418_Y) +XE_GPU_REGISTER(0x468A, kFloat, SHADER_CONSTANT_418_Z) +XE_GPU_REGISTER(0x468B, kFloat, SHADER_CONSTANT_418_W) +XE_GPU_REGISTER(0x468C, kFloat, SHADER_CONSTANT_419_X) +XE_GPU_REGISTER(0x468D, kFloat, SHADER_CONSTANT_419_Y) +XE_GPU_REGISTER(0x468E, kFloat, SHADER_CONSTANT_419_Z) +XE_GPU_REGISTER(0x468F, kFloat, SHADER_CONSTANT_419_W) +XE_GPU_REGISTER(0x4690, kFloat, SHADER_CONSTANT_420_X) +XE_GPU_REGISTER(0x4691, kFloat, SHADER_CONSTANT_420_Y) +XE_GPU_REGISTER(0x4692, kFloat, SHADER_CONSTANT_420_Z) +XE_GPU_REGISTER(0x4693, kFloat, SHADER_CONSTANT_420_W) +XE_GPU_REGISTER(0x4694, kFloat, SHADER_CONSTANT_421_X) +XE_GPU_REGISTER(0x4695, kFloat, SHADER_CONSTANT_421_Y) +XE_GPU_REGISTER(0x4696, kFloat, SHADER_CONSTANT_421_Z) +XE_GPU_REGISTER(0x4697, kFloat, SHADER_CONSTANT_421_W) +XE_GPU_REGISTER(0x4698, kFloat, SHADER_CONSTANT_422_X) +XE_GPU_REGISTER(0x4699, kFloat, SHADER_CONSTANT_422_Y) +XE_GPU_REGISTER(0x469A, kFloat, SHADER_CONSTANT_422_Z) +XE_GPU_REGISTER(0x469B, kFloat, SHADER_CONSTANT_422_W) +XE_GPU_REGISTER(0x469C, kFloat, SHADER_CONSTANT_423_X) +XE_GPU_REGISTER(0x469D, kFloat, SHADER_CONSTANT_423_Y) +XE_GPU_REGISTER(0x469E, kFloat, SHADER_CONSTANT_423_Z) +XE_GPU_REGISTER(0x469F, kFloat, SHADER_CONSTANT_423_W) +XE_GPU_REGISTER(0x46A0, kFloat, SHADER_CONSTANT_424_X) +XE_GPU_REGISTER(0x46A1, kFloat, SHADER_CONSTANT_424_Y) +XE_GPU_REGISTER(0x46A2, kFloat, SHADER_CONSTANT_424_Z) +XE_GPU_REGISTER(0x46A3, kFloat, SHADER_CONSTANT_424_W) +XE_GPU_REGISTER(0x46A4, kFloat, SHADER_CONSTANT_425_X) +XE_GPU_REGISTER(0x46A5, kFloat, SHADER_CONSTANT_425_Y) +XE_GPU_REGISTER(0x46A6, kFloat, SHADER_CONSTANT_425_Z) +XE_GPU_REGISTER(0x46A7, kFloat, SHADER_CONSTANT_425_W) +XE_GPU_REGISTER(0x46A8, kFloat, SHADER_CONSTANT_426_X) +XE_GPU_REGISTER(0x46A9, kFloat, SHADER_CONSTANT_426_Y) +XE_GPU_REGISTER(0x46AA, kFloat, SHADER_CONSTANT_426_Z) +XE_GPU_REGISTER(0x46AB, kFloat, SHADER_CONSTANT_426_W) +XE_GPU_REGISTER(0x46AC, kFloat, SHADER_CONSTANT_427_X) +XE_GPU_REGISTER(0x46AD, kFloat, SHADER_CONSTANT_427_Y) +XE_GPU_REGISTER(0x46AE, kFloat, SHADER_CONSTANT_427_Z) +XE_GPU_REGISTER(0x46AF, kFloat, SHADER_CONSTANT_427_W) +XE_GPU_REGISTER(0x46B0, kFloat, SHADER_CONSTANT_428_X) +XE_GPU_REGISTER(0x46B1, kFloat, SHADER_CONSTANT_428_Y) +XE_GPU_REGISTER(0x46B2, kFloat, SHADER_CONSTANT_428_Z) +XE_GPU_REGISTER(0x46B3, kFloat, SHADER_CONSTANT_428_W) +XE_GPU_REGISTER(0x46B4, kFloat, SHADER_CONSTANT_429_X) +XE_GPU_REGISTER(0x46B5, kFloat, SHADER_CONSTANT_429_Y) +XE_GPU_REGISTER(0x46B6, kFloat, SHADER_CONSTANT_429_Z) +XE_GPU_REGISTER(0x46B7, kFloat, SHADER_CONSTANT_429_W) +XE_GPU_REGISTER(0x46B8, kFloat, SHADER_CONSTANT_430_X) +XE_GPU_REGISTER(0x46B9, kFloat, SHADER_CONSTANT_430_Y) +XE_GPU_REGISTER(0x46BA, kFloat, SHADER_CONSTANT_430_Z) +XE_GPU_REGISTER(0x46BB, kFloat, SHADER_CONSTANT_430_W) +XE_GPU_REGISTER(0x46BC, kFloat, SHADER_CONSTANT_431_X) +XE_GPU_REGISTER(0x46BD, kFloat, SHADER_CONSTANT_431_Y) +XE_GPU_REGISTER(0x46BE, kFloat, SHADER_CONSTANT_431_Z) +XE_GPU_REGISTER(0x46BF, kFloat, SHADER_CONSTANT_431_W) +XE_GPU_REGISTER(0x46C0, kFloat, SHADER_CONSTANT_432_X) +XE_GPU_REGISTER(0x46C1, kFloat, SHADER_CONSTANT_432_Y) +XE_GPU_REGISTER(0x46C2, kFloat, SHADER_CONSTANT_432_Z) +XE_GPU_REGISTER(0x46C3, kFloat, SHADER_CONSTANT_432_W) +XE_GPU_REGISTER(0x46C4, kFloat, SHADER_CONSTANT_433_X) +XE_GPU_REGISTER(0x46C5, kFloat, SHADER_CONSTANT_433_Y) +XE_GPU_REGISTER(0x46C6, kFloat, SHADER_CONSTANT_433_Z) +XE_GPU_REGISTER(0x46C7, kFloat, SHADER_CONSTANT_433_W) +XE_GPU_REGISTER(0x46C8, kFloat, SHADER_CONSTANT_434_X) +XE_GPU_REGISTER(0x46C9, kFloat, SHADER_CONSTANT_434_Y) +XE_GPU_REGISTER(0x46CA, kFloat, SHADER_CONSTANT_434_Z) +XE_GPU_REGISTER(0x46CB, kFloat, SHADER_CONSTANT_434_W) +XE_GPU_REGISTER(0x46CC, kFloat, SHADER_CONSTANT_435_X) +XE_GPU_REGISTER(0x46CD, kFloat, SHADER_CONSTANT_435_Y) +XE_GPU_REGISTER(0x46CE, kFloat, SHADER_CONSTANT_435_Z) +XE_GPU_REGISTER(0x46CF, kFloat, SHADER_CONSTANT_435_W) +XE_GPU_REGISTER(0x46D0, kFloat, SHADER_CONSTANT_436_X) +XE_GPU_REGISTER(0x46D1, kFloat, SHADER_CONSTANT_436_Y) +XE_GPU_REGISTER(0x46D2, kFloat, SHADER_CONSTANT_436_Z) +XE_GPU_REGISTER(0x46D3, kFloat, SHADER_CONSTANT_436_W) +XE_GPU_REGISTER(0x46D4, kFloat, SHADER_CONSTANT_437_X) +XE_GPU_REGISTER(0x46D5, kFloat, SHADER_CONSTANT_437_Y) +XE_GPU_REGISTER(0x46D6, kFloat, SHADER_CONSTANT_437_Z) +XE_GPU_REGISTER(0x46D7, kFloat, SHADER_CONSTANT_437_W) +XE_GPU_REGISTER(0x46D8, kFloat, SHADER_CONSTANT_438_X) +XE_GPU_REGISTER(0x46D9, kFloat, SHADER_CONSTANT_438_Y) +XE_GPU_REGISTER(0x46DA, kFloat, SHADER_CONSTANT_438_Z) +XE_GPU_REGISTER(0x46DB, kFloat, SHADER_CONSTANT_438_W) +XE_GPU_REGISTER(0x46DC, kFloat, SHADER_CONSTANT_439_X) +XE_GPU_REGISTER(0x46DD, kFloat, SHADER_CONSTANT_439_Y) +XE_GPU_REGISTER(0x46DE, kFloat, SHADER_CONSTANT_439_Z) +XE_GPU_REGISTER(0x46DF, kFloat, SHADER_CONSTANT_439_W) +XE_GPU_REGISTER(0x46E0, kFloat, SHADER_CONSTANT_440_X) +XE_GPU_REGISTER(0x46E1, kFloat, SHADER_CONSTANT_440_Y) +XE_GPU_REGISTER(0x46E2, kFloat, SHADER_CONSTANT_440_Z) +XE_GPU_REGISTER(0x46E3, kFloat, SHADER_CONSTANT_440_W) +XE_GPU_REGISTER(0x46E4, kFloat, SHADER_CONSTANT_441_X) +XE_GPU_REGISTER(0x46E5, kFloat, SHADER_CONSTANT_441_Y) +XE_GPU_REGISTER(0x46E6, kFloat, SHADER_CONSTANT_441_Z) +XE_GPU_REGISTER(0x46E7, kFloat, SHADER_CONSTANT_441_W) +XE_GPU_REGISTER(0x46E8, kFloat, SHADER_CONSTANT_442_X) +XE_GPU_REGISTER(0x46E9, kFloat, SHADER_CONSTANT_442_Y) +XE_GPU_REGISTER(0x46EA, kFloat, SHADER_CONSTANT_442_Z) +XE_GPU_REGISTER(0x46EB, kFloat, SHADER_CONSTANT_442_W) +XE_GPU_REGISTER(0x46EC, kFloat, SHADER_CONSTANT_443_X) +XE_GPU_REGISTER(0x46ED, kFloat, SHADER_CONSTANT_443_Y) +XE_GPU_REGISTER(0x46EE, kFloat, SHADER_CONSTANT_443_Z) +XE_GPU_REGISTER(0x46EF, kFloat, SHADER_CONSTANT_443_W) +XE_GPU_REGISTER(0x46F0, kFloat, SHADER_CONSTANT_444_X) +XE_GPU_REGISTER(0x46F1, kFloat, SHADER_CONSTANT_444_Y) +XE_GPU_REGISTER(0x46F2, kFloat, SHADER_CONSTANT_444_Z) +XE_GPU_REGISTER(0x46F3, kFloat, SHADER_CONSTANT_444_W) +XE_GPU_REGISTER(0x46F4, kFloat, SHADER_CONSTANT_445_X) +XE_GPU_REGISTER(0x46F5, kFloat, SHADER_CONSTANT_445_Y) +XE_GPU_REGISTER(0x46F6, kFloat, SHADER_CONSTANT_445_Z) +XE_GPU_REGISTER(0x46F7, kFloat, SHADER_CONSTANT_445_W) +XE_GPU_REGISTER(0x46F8, kFloat, SHADER_CONSTANT_446_X) +XE_GPU_REGISTER(0x46F9, kFloat, SHADER_CONSTANT_446_Y) +XE_GPU_REGISTER(0x46FA, kFloat, SHADER_CONSTANT_446_Z) +XE_GPU_REGISTER(0x46FB, kFloat, SHADER_CONSTANT_446_W) +XE_GPU_REGISTER(0x46FC, kFloat, SHADER_CONSTANT_447_X) +XE_GPU_REGISTER(0x46FD, kFloat, SHADER_CONSTANT_447_Y) +XE_GPU_REGISTER(0x46FE, kFloat, SHADER_CONSTANT_447_Z) +XE_GPU_REGISTER(0x46FF, kFloat, SHADER_CONSTANT_447_W) +XE_GPU_REGISTER(0x4700, kFloat, SHADER_CONSTANT_448_X) +XE_GPU_REGISTER(0x4701, kFloat, SHADER_CONSTANT_448_Y) +XE_GPU_REGISTER(0x4702, kFloat, SHADER_CONSTANT_448_Z) +XE_GPU_REGISTER(0x4703, kFloat, SHADER_CONSTANT_448_W) +XE_GPU_REGISTER(0x4704, kFloat, SHADER_CONSTANT_449_X) +XE_GPU_REGISTER(0x4705, kFloat, SHADER_CONSTANT_449_Y) +XE_GPU_REGISTER(0x4706, kFloat, SHADER_CONSTANT_449_Z) +XE_GPU_REGISTER(0x4707, kFloat, SHADER_CONSTANT_449_W) +XE_GPU_REGISTER(0x4708, kFloat, SHADER_CONSTANT_450_X) +XE_GPU_REGISTER(0x4709, kFloat, SHADER_CONSTANT_450_Y) +XE_GPU_REGISTER(0x470A, kFloat, SHADER_CONSTANT_450_Z) +XE_GPU_REGISTER(0x470B, kFloat, SHADER_CONSTANT_450_W) +XE_GPU_REGISTER(0x470C, kFloat, SHADER_CONSTANT_451_X) +XE_GPU_REGISTER(0x470D, kFloat, SHADER_CONSTANT_451_Y) +XE_GPU_REGISTER(0x470E, kFloat, SHADER_CONSTANT_451_Z) +XE_GPU_REGISTER(0x470F, kFloat, SHADER_CONSTANT_451_W) +XE_GPU_REGISTER(0x4710, kFloat, SHADER_CONSTANT_452_X) +XE_GPU_REGISTER(0x4711, kFloat, SHADER_CONSTANT_452_Y) +XE_GPU_REGISTER(0x4712, kFloat, SHADER_CONSTANT_452_Z) +XE_GPU_REGISTER(0x4713, kFloat, SHADER_CONSTANT_452_W) +XE_GPU_REGISTER(0x4714, kFloat, SHADER_CONSTANT_453_X) +XE_GPU_REGISTER(0x4715, kFloat, SHADER_CONSTANT_453_Y) +XE_GPU_REGISTER(0x4716, kFloat, SHADER_CONSTANT_453_Z) +XE_GPU_REGISTER(0x4717, kFloat, SHADER_CONSTANT_453_W) +XE_GPU_REGISTER(0x4718, kFloat, SHADER_CONSTANT_454_X) +XE_GPU_REGISTER(0x4719, kFloat, SHADER_CONSTANT_454_Y) +XE_GPU_REGISTER(0x471A, kFloat, SHADER_CONSTANT_454_Z) +XE_GPU_REGISTER(0x471B, kFloat, SHADER_CONSTANT_454_W) +XE_GPU_REGISTER(0x471C, kFloat, SHADER_CONSTANT_455_X) +XE_GPU_REGISTER(0x471D, kFloat, SHADER_CONSTANT_455_Y) +XE_GPU_REGISTER(0x471E, kFloat, SHADER_CONSTANT_455_Z) +XE_GPU_REGISTER(0x471F, kFloat, SHADER_CONSTANT_455_W) +XE_GPU_REGISTER(0x4720, kFloat, SHADER_CONSTANT_456_X) +XE_GPU_REGISTER(0x4721, kFloat, SHADER_CONSTANT_456_Y) +XE_GPU_REGISTER(0x4722, kFloat, SHADER_CONSTANT_456_Z) +XE_GPU_REGISTER(0x4723, kFloat, SHADER_CONSTANT_456_W) +XE_GPU_REGISTER(0x4724, kFloat, SHADER_CONSTANT_457_X) +XE_GPU_REGISTER(0x4725, kFloat, SHADER_CONSTANT_457_Y) +XE_GPU_REGISTER(0x4726, kFloat, SHADER_CONSTANT_457_Z) +XE_GPU_REGISTER(0x4727, kFloat, SHADER_CONSTANT_457_W) +XE_GPU_REGISTER(0x4728, kFloat, SHADER_CONSTANT_458_X) +XE_GPU_REGISTER(0x4729, kFloat, SHADER_CONSTANT_458_Y) +XE_GPU_REGISTER(0x472A, kFloat, SHADER_CONSTANT_458_Z) +XE_GPU_REGISTER(0x472B, kFloat, SHADER_CONSTANT_458_W) +XE_GPU_REGISTER(0x472C, kFloat, SHADER_CONSTANT_459_X) +XE_GPU_REGISTER(0x472D, kFloat, SHADER_CONSTANT_459_Y) +XE_GPU_REGISTER(0x472E, kFloat, SHADER_CONSTANT_459_Z) +XE_GPU_REGISTER(0x472F, kFloat, SHADER_CONSTANT_459_W) +XE_GPU_REGISTER(0x4730, kFloat, SHADER_CONSTANT_460_X) +XE_GPU_REGISTER(0x4731, kFloat, SHADER_CONSTANT_460_Y) +XE_GPU_REGISTER(0x4732, kFloat, SHADER_CONSTANT_460_Z) +XE_GPU_REGISTER(0x4733, kFloat, SHADER_CONSTANT_460_W) +XE_GPU_REGISTER(0x4734, kFloat, SHADER_CONSTANT_461_X) +XE_GPU_REGISTER(0x4735, kFloat, SHADER_CONSTANT_461_Y) +XE_GPU_REGISTER(0x4736, kFloat, SHADER_CONSTANT_461_Z) +XE_GPU_REGISTER(0x4737, kFloat, SHADER_CONSTANT_461_W) +XE_GPU_REGISTER(0x4738, kFloat, SHADER_CONSTANT_462_X) +XE_GPU_REGISTER(0x4739, kFloat, SHADER_CONSTANT_462_Y) +XE_GPU_REGISTER(0x473A, kFloat, SHADER_CONSTANT_462_Z) +XE_GPU_REGISTER(0x473B, kFloat, SHADER_CONSTANT_462_W) +XE_GPU_REGISTER(0x473C, kFloat, SHADER_CONSTANT_463_X) +XE_GPU_REGISTER(0x473D, kFloat, SHADER_CONSTANT_463_Y) +XE_GPU_REGISTER(0x473E, kFloat, SHADER_CONSTANT_463_Z) +XE_GPU_REGISTER(0x473F, kFloat, SHADER_CONSTANT_463_W) +XE_GPU_REGISTER(0x4740, kFloat, SHADER_CONSTANT_464_X) +XE_GPU_REGISTER(0x4741, kFloat, SHADER_CONSTANT_464_Y) +XE_GPU_REGISTER(0x4742, kFloat, SHADER_CONSTANT_464_Z) +XE_GPU_REGISTER(0x4743, kFloat, SHADER_CONSTANT_464_W) +XE_GPU_REGISTER(0x4744, kFloat, SHADER_CONSTANT_465_X) +XE_GPU_REGISTER(0x4745, kFloat, SHADER_CONSTANT_465_Y) +XE_GPU_REGISTER(0x4746, kFloat, SHADER_CONSTANT_465_Z) +XE_GPU_REGISTER(0x4747, kFloat, SHADER_CONSTANT_465_W) +XE_GPU_REGISTER(0x4748, kFloat, SHADER_CONSTANT_466_X) +XE_GPU_REGISTER(0x4749, kFloat, SHADER_CONSTANT_466_Y) +XE_GPU_REGISTER(0x474A, kFloat, SHADER_CONSTANT_466_Z) +XE_GPU_REGISTER(0x474B, kFloat, SHADER_CONSTANT_466_W) +XE_GPU_REGISTER(0x474C, kFloat, SHADER_CONSTANT_467_X) +XE_GPU_REGISTER(0x474D, kFloat, SHADER_CONSTANT_467_Y) +XE_GPU_REGISTER(0x474E, kFloat, SHADER_CONSTANT_467_Z) +XE_GPU_REGISTER(0x474F, kFloat, SHADER_CONSTANT_467_W) +XE_GPU_REGISTER(0x4750, kFloat, SHADER_CONSTANT_468_X) +XE_GPU_REGISTER(0x4751, kFloat, SHADER_CONSTANT_468_Y) +XE_GPU_REGISTER(0x4752, kFloat, SHADER_CONSTANT_468_Z) +XE_GPU_REGISTER(0x4753, kFloat, SHADER_CONSTANT_468_W) +XE_GPU_REGISTER(0x4754, kFloat, SHADER_CONSTANT_469_X) +XE_GPU_REGISTER(0x4755, kFloat, SHADER_CONSTANT_469_Y) +XE_GPU_REGISTER(0x4756, kFloat, SHADER_CONSTANT_469_Z) +XE_GPU_REGISTER(0x4757, kFloat, SHADER_CONSTANT_469_W) +XE_GPU_REGISTER(0x4758, kFloat, SHADER_CONSTANT_470_X) +XE_GPU_REGISTER(0x4759, kFloat, SHADER_CONSTANT_470_Y) +XE_GPU_REGISTER(0x475A, kFloat, SHADER_CONSTANT_470_Z) +XE_GPU_REGISTER(0x475B, kFloat, SHADER_CONSTANT_470_W) +XE_GPU_REGISTER(0x475C, kFloat, SHADER_CONSTANT_471_X) +XE_GPU_REGISTER(0x475D, kFloat, SHADER_CONSTANT_471_Y) +XE_GPU_REGISTER(0x475E, kFloat, SHADER_CONSTANT_471_Z) +XE_GPU_REGISTER(0x475F, kFloat, SHADER_CONSTANT_471_W) +XE_GPU_REGISTER(0x4760, kFloat, SHADER_CONSTANT_472_X) +XE_GPU_REGISTER(0x4761, kFloat, SHADER_CONSTANT_472_Y) +XE_GPU_REGISTER(0x4762, kFloat, SHADER_CONSTANT_472_Z) +XE_GPU_REGISTER(0x4763, kFloat, SHADER_CONSTANT_472_W) +XE_GPU_REGISTER(0x4764, kFloat, SHADER_CONSTANT_473_X) +XE_GPU_REGISTER(0x4765, kFloat, SHADER_CONSTANT_473_Y) +XE_GPU_REGISTER(0x4766, kFloat, SHADER_CONSTANT_473_Z) +XE_GPU_REGISTER(0x4767, kFloat, SHADER_CONSTANT_473_W) +XE_GPU_REGISTER(0x4768, kFloat, SHADER_CONSTANT_474_X) +XE_GPU_REGISTER(0x4769, kFloat, SHADER_CONSTANT_474_Y) +XE_GPU_REGISTER(0x476A, kFloat, SHADER_CONSTANT_474_Z) +XE_GPU_REGISTER(0x476B, kFloat, SHADER_CONSTANT_474_W) +XE_GPU_REGISTER(0x476C, kFloat, SHADER_CONSTANT_475_X) +XE_GPU_REGISTER(0x476D, kFloat, SHADER_CONSTANT_475_Y) +XE_GPU_REGISTER(0x476E, kFloat, SHADER_CONSTANT_475_Z) +XE_GPU_REGISTER(0x476F, kFloat, SHADER_CONSTANT_475_W) +XE_GPU_REGISTER(0x4770, kFloat, SHADER_CONSTANT_476_X) +XE_GPU_REGISTER(0x4771, kFloat, SHADER_CONSTANT_476_Y) +XE_GPU_REGISTER(0x4772, kFloat, SHADER_CONSTANT_476_Z) +XE_GPU_REGISTER(0x4773, kFloat, SHADER_CONSTANT_476_W) +XE_GPU_REGISTER(0x4774, kFloat, SHADER_CONSTANT_477_X) +XE_GPU_REGISTER(0x4775, kFloat, SHADER_CONSTANT_477_Y) +XE_GPU_REGISTER(0x4776, kFloat, SHADER_CONSTANT_477_Z) +XE_GPU_REGISTER(0x4777, kFloat, SHADER_CONSTANT_477_W) +XE_GPU_REGISTER(0x4778, kFloat, SHADER_CONSTANT_478_X) +XE_GPU_REGISTER(0x4779, kFloat, SHADER_CONSTANT_478_Y) +XE_GPU_REGISTER(0x477A, kFloat, SHADER_CONSTANT_478_Z) +XE_GPU_REGISTER(0x477B, kFloat, SHADER_CONSTANT_478_W) +XE_GPU_REGISTER(0x477C, kFloat, SHADER_CONSTANT_479_X) +XE_GPU_REGISTER(0x477D, kFloat, SHADER_CONSTANT_479_Y) +XE_GPU_REGISTER(0x477E, kFloat, SHADER_CONSTANT_479_Z) +XE_GPU_REGISTER(0x477F, kFloat, SHADER_CONSTANT_479_W) +XE_GPU_REGISTER(0x4780, kFloat, SHADER_CONSTANT_480_X) +XE_GPU_REGISTER(0x4781, kFloat, SHADER_CONSTANT_480_Y) +XE_GPU_REGISTER(0x4782, kFloat, SHADER_CONSTANT_480_Z) +XE_GPU_REGISTER(0x4783, kFloat, SHADER_CONSTANT_480_W) +XE_GPU_REGISTER(0x4784, kFloat, SHADER_CONSTANT_481_X) +XE_GPU_REGISTER(0x4785, kFloat, SHADER_CONSTANT_481_Y) +XE_GPU_REGISTER(0x4786, kFloat, SHADER_CONSTANT_481_Z) +XE_GPU_REGISTER(0x4787, kFloat, SHADER_CONSTANT_481_W) +XE_GPU_REGISTER(0x4788, kFloat, SHADER_CONSTANT_482_X) +XE_GPU_REGISTER(0x4789, kFloat, SHADER_CONSTANT_482_Y) +XE_GPU_REGISTER(0x478A, kFloat, SHADER_CONSTANT_482_Z) +XE_GPU_REGISTER(0x478B, kFloat, SHADER_CONSTANT_482_W) +XE_GPU_REGISTER(0x478C, kFloat, SHADER_CONSTANT_483_X) +XE_GPU_REGISTER(0x478D, kFloat, SHADER_CONSTANT_483_Y) +XE_GPU_REGISTER(0x478E, kFloat, SHADER_CONSTANT_483_Z) +XE_GPU_REGISTER(0x478F, kFloat, SHADER_CONSTANT_483_W) +XE_GPU_REGISTER(0x4790, kFloat, SHADER_CONSTANT_484_X) +XE_GPU_REGISTER(0x4791, kFloat, SHADER_CONSTANT_484_Y) +XE_GPU_REGISTER(0x4792, kFloat, SHADER_CONSTANT_484_Z) +XE_GPU_REGISTER(0x4793, kFloat, SHADER_CONSTANT_484_W) +XE_GPU_REGISTER(0x4794, kFloat, SHADER_CONSTANT_485_X) +XE_GPU_REGISTER(0x4795, kFloat, SHADER_CONSTANT_485_Y) +XE_GPU_REGISTER(0x4796, kFloat, SHADER_CONSTANT_485_Z) +XE_GPU_REGISTER(0x4797, kFloat, SHADER_CONSTANT_485_W) +XE_GPU_REGISTER(0x4798, kFloat, SHADER_CONSTANT_486_X) +XE_GPU_REGISTER(0x4799, kFloat, SHADER_CONSTANT_486_Y) +XE_GPU_REGISTER(0x479A, kFloat, SHADER_CONSTANT_486_Z) +XE_GPU_REGISTER(0x479B, kFloat, SHADER_CONSTANT_486_W) +XE_GPU_REGISTER(0x479C, kFloat, SHADER_CONSTANT_487_X) +XE_GPU_REGISTER(0x479D, kFloat, SHADER_CONSTANT_487_Y) +XE_GPU_REGISTER(0x479E, kFloat, SHADER_CONSTANT_487_Z) +XE_GPU_REGISTER(0x479F, kFloat, SHADER_CONSTANT_487_W) +XE_GPU_REGISTER(0x47A0, kFloat, SHADER_CONSTANT_488_X) +XE_GPU_REGISTER(0x47A1, kFloat, SHADER_CONSTANT_488_Y) +XE_GPU_REGISTER(0x47A2, kFloat, SHADER_CONSTANT_488_Z) +XE_GPU_REGISTER(0x47A3, kFloat, SHADER_CONSTANT_488_W) +XE_GPU_REGISTER(0x47A4, kFloat, SHADER_CONSTANT_489_X) +XE_GPU_REGISTER(0x47A5, kFloat, SHADER_CONSTANT_489_Y) +XE_GPU_REGISTER(0x47A6, kFloat, SHADER_CONSTANT_489_Z) +XE_GPU_REGISTER(0x47A7, kFloat, SHADER_CONSTANT_489_W) +XE_GPU_REGISTER(0x47A8, kFloat, SHADER_CONSTANT_490_X) +XE_GPU_REGISTER(0x47A9, kFloat, SHADER_CONSTANT_490_Y) +XE_GPU_REGISTER(0x47AA, kFloat, SHADER_CONSTANT_490_Z) +XE_GPU_REGISTER(0x47AB, kFloat, SHADER_CONSTANT_490_W) +XE_GPU_REGISTER(0x47AC, kFloat, SHADER_CONSTANT_491_X) +XE_GPU_REGISTER(0x47AD, kFloat, SHADER_CONSTANT_491_Y) +XE_GPU_REGISTER(0x47AE, kFloat, SHADER_CONSTANT_491_Z) +XE_GPU_REGISTER(0x47AF, kFloat, SHADER_CONSTANT_491_W) +XE_GPU_REGISTER(0x47B0, kFloat, SHADER_CONSTANT_492_X) +XE_GPU_REGISTER(0x47B1, kFloat, SHADER_CONSTANT_492_Y) +XE_GPU_REGISTER(0x47B2, kFloat, SHADER_CONSTANT_492_Z) +XE_GPU_REGISTER(0x47B3, kFloat, SHADER_CONSTANT_492_W) +XE_GPU_REGISTER(0x47B4, kFloat, SHADER_CONSTANT_493_X) +XE_GPU_REGISTER(0x47B5, kFloat, SHADER_CONSTANT_493_Y) +XE_GPU_REGISTER(0x47B6, kFloat, SHADER_CONSTANT_493_Z) +XE_GPU_REGISTER(0x47B7, kFloat, SHADER_CONSTANT_493_W) +XE_GPU_REGISTER(0x47B8, kFloat, SHADER_CONSTANT_494_X) +XE_GPU_REGISTER(0x47B9, kFloat, SHADER_CONSTANT_494_Y) +XE_GPU_REGISTER(0x47BA, kFloat, SHADER_CONSTANT_494_Z) +XE_GPU_REGISTER(0x47BB, kFloat, SHADER_CONSTANT_494_W) +XE_GPU_REGISTER(0x47BC, kFloat, SHADER_CONSTANT_495_X) +XE_GPU_REGISTER(0x47BD, kFloat, SHADER_CONSTANT_495_Y) +XE_GPU_REGISTER(0x47BE, kFloat, SHADER_CONSTANT_495_Z) +XE_GPU_REGISTER(0x47BF, kFloat, SHADER_CONSTANT_495_W) +XE_GPU_REGISTER(0x47C0, kFloat, SHADER_CONSTANT_496_X) +XE_GPU_REGISTER(0x47C1, kFloat, SHADER_CONSTANT_496_Y) +XE_GPU_REGISTER(0x47C2, kFloat, SHADER_CONSTANT_496_Z) +XE_GPU_REGISTER(0x47C3, kFloat, SHADER_CONSTANT_496_W) +XE_GPU_REGISTER(0x47C4, kFloat, SHADER_CONSTANT_497_X) +XE_GPU_REGISTER(0x47C5, kFloat, SHADER_CONSTANT_497_Y) +XE_GPU_REGISTER(0x47C6, kFloat, SHADER_CONSTANT_497_Z) +XE_GPU_REGISTER(0x47C7, kFloat, SHADER_CONSTANT_497_W) +XE_GPU_REGISTER(0x47C8, kFloat, SHADER_CONSTANT_498_X) +XE_GPU_REGISTER(0x47C9, kFloat, SHADER_CONSTANT_498_Y) +XE_GPU_REGISTER(0x47CA, kFloat, SHADER_CONSTANT_498_Z) +XE_GPU_REGISTER(0x47CB, kFloat, SHADER_CONSTANT_498_W) +XE_GPU_REGISTER(0x47CC, kFloat, SHADER_CONSTANT_499_X) +XE_GPU_REGISTER(0x47CD, kFloat, SHADER_CONSTANT_499_Y) +XE_GPU_REGISTER(0x47CE, kFloat, SHADER_CONSTANT_499_Z) +XE_GPU_REGISTER(0x47CF, kFloat, SHADER_CONSTANT_499_W) +XE_GPU_REGISTER(0x47D0, kFloat, SHADER_CONSTANT_500_X) +XE_GPU_REGISTER(0x47D1, kFloat, SHADER_CONSTANT_500_Y) +XE_GPU_REGISTER(0x47D2, kFloat, SHADER_CONSTANT_500_Z) +XE_GPU_REGISTER(0x47D3, kFloat, SHADER_CONSTANT_500_W) +XE_GPU_REGISTER(0x47D4, kFloat, SHADER_CONSTANT_501_X) +XE_GPU_REGISTER(0x47D5, kFloat, SHADER_CONSTANT_501_Y) +XE_GPU_REGISTER(0x47D6, kFloat, SHADER_CONSTANT_501_Z) +XE_GPU_REGISTER(0x47D7, kFloat, SHADER_CONSTANT_501_W) +XE_GPU_REGISTER(0x47D8, kFloat, SHADER_CONSTANT_502_X) +XE_GPU_REGISTER(0x47D9, kFloat, SHADER_CONSTANT_502_Y) +XE_GPU_REGISTER(0x47DA, kFloat, SHADER_CONSTANT_502_Z) +XE_GPU_REGISTER(0x47DB, kFloat, SHADER_CONSTANT_502_W) +XE_GPU_REGISTER(0x47DC, kFloat, SHADER_CONSTANT_503_X) +XE_GPU_REGISTER(0x47DD, kFloat, SHADER_CONSTANT_503_Y) +XE_GPU_REGISTER(0x47DE, kFloat, SHADER_CONSTANT_503_Z) +XE_GPU_REGISTER(0x47DF, kFloat, SHADER_CONSTANT_503_W) +XE_GPU_REGISTER(0x47E0, kFloat, SHADER_CONSTANT_504_X) +XE_GPU_REGISTER(0x47E1, kFloat, SHADER_CONSTANT_504_Y) +XE_GPU_REGISTER(0x47E2, kFloat, SHADER_CONSTANT_504_Z) +XE_GPU_REGISTER(0x47E3, kFloat, SHADER_CONSTANT_504_W) +XE_GPU_REGISTER(0x47E4, kFloat, SHADER_CONSTANT_505_X) +XE_GPU_REGISTER(0x47E5, kFloat, SHADER_CONSTANT_505_Y) +XE_GPU_REGISTER(0x47E6, kFloat, SHADER_CONSTANT_505_Z) +XE_GPU_REGISTER(0x47E7, kFloat, SHADER_CONSTANT_505_W) +XE_GPU_REGISTER(0x47E8, kFloat, SHADER_CONSTANT_506_X) +XE_GPU_REGISTER(0x47E9, kFloat, SHADER_CONSTANT_506_Y) +XE_GPU_REGISTER(0x47EA, kFloat, SHADER_CONSTANT_506_Z) +XE_GPU_REGISTER(0x47EB, kFloat, SHADER_CONSTANT_506_W) +XE_GPU_REGISTER(0x47EC, kFloat, SHADER_CONSTANT_507_X) +XE_GPU_REGISTER(0x47ED, kFloat, SHADER_CONSTANT_507_Y) +XE_GPU_REGISTER(0x47EE, kFloat, SHADER_CONSTANT_507_Z) +XE_GPU_REGISTER(0x47EF, kFloat, SHADER_CONSTANT_507_W) +XE_GPU_REGISTER(0x47F0, kFloat, SHADER_CONSTANT_508_X) +XE_GPU_REGISTER(0x47F1, kFloat, SHADER_CONSTANT_508_Y) +XE_GPU_REGISTER(0x47F2, kFloat, SHADER_CONSTANT_508_Z) +XE_GPU_REGISTER(0x47F3, kFloat, SHADER_CONSTANT_508_W) +XE_GPU_REGISTER(0x47F4, kFloat, SHADER_CONSTANT_509_X) +XE_GPU_REGISTER(0x47F5, kFloat, SHADER_CONSTANT_509_Y) +XE_GPU_REGISTER(0x47F6, kFloat, SHADER_CONSTANT_509_Z) +XE_GPU_REGISTER(0x47F7, kFloat, SHADER_CONSTANT_509_W) +XE_GPU_REGISTER(0x47F8, kFloat, SHADER_CONSTANT_510_X) +XE_GPU_REGISTER(0x47F9, kFloat, SHADER_CONSTANT_510_Y) +XE_GPU_REGISTER(0x47FA, kFloat, SHADER_CONSTANT_510_Z) +XE_GPU_REGISTER(0x47FB, kFloat, SHADER_CONSTANT_510_W) +XE_GPU_REGISTER(0x47FC, kFloat, SHADER_CONSTANT_511_X) +XE_GPU_REGISTER(0x47FD, kFloat, SHADER_CONSTANT_511_Y) +XE_GPU_REGISTER(0x47FE, kFloat, SHADER_CONSTANT_511_Z) +XE_GPU_REGISTER(0x47FF, kFloat, SHADER_CONSTANT_511_W) + +XE_GPU_REGISTER(0x4800, kDword, SHADER_CONSTANT_FETCH_00_0) +XE_GPU_REGISTER(0x4801, kDword, SHADER_CONSTANT_FETCH_00_1) +XE_GPU_REGISTER(0x4802, kDword, SHADER_CONSTANT_FETCH_00_2) +XE_GPU_REGISTER(0x4803, kDword, SHADER_CONSTANT_FETCH_00_3) +XE_GPU_REGISTER(0x4804, kDword, SHADER_CONSTANT_FETCH_00_4) +XE_GPU_REGISTER(0x4805, kDword, SHADER_CONSTANT_FETCH_00_5) +XE_GPU_REGISTER(0x4806, kDword, SHADER_CONSTANT_FETCH_01_0) +XE_GPU_REGISTER(0x4807, kDword, SHADER_CONSTANT_FETCH_01_1) +XE_GPU_REGISTER(0x4808, kDword, SHADER_CONSTANT_FETCH_01_2) +XE_GPU_REGISTER(0x4809, kDword, SHADER_CONSTANT_FETCH_01_3) +XE_GPU_REGISTER(0x480A, kDword, SHADER_CONSTANT_FETCH_01_4) +XE_GPU_REGISTER(0x480B, kDword, SHADER_CONSTANT_FETCH_01_5) +XE_GPU_REGISTER(0x480C, kDword, SHADER_CONSTANT_FETCH_02_0) +XE_GPU_REGISTER(0x480D, kDword, SHADER_CONSTANT_FETCH_02_1) +XE_GPU_REGISTER(0x480E, kDword, SHADER_CONSTANT_FETCH_02_2) +XE_GPU_REGISTER(0x480F, kDword, SHADER_CONSTANT_FETCH_02_3) +XE_GPU_REGISTER(0x4810, kDword, SHADER_CONSTANT_FETCH_02_4) +XE_GPU_REGISTER(0x4811, kDword, SHADER_CONSTANT_FETCH_02_5) +XE_GPU_REGISTER(0x4812, kDword, SHADER_CONSTANT_FETCH_03_0) +XE_GPU_REGISTER(0x4813, kDword, SHADER_CONSTANT_FETCH_03_1) +XE_GPU_REGISTER(0x4814, kDword, SHADER_CONSTANT_FETCH_03_2) +XE_GPU_REGISTER(0x4815, kDword, SHADER_CONSTANT_FETCH_03_3) +XE_GPU_REGISTER(0x4816, kDword, SHADER_CONSTANT_FETCH_03_4) +XE_GPU_REGISTER(0x4817, kDword, SHADER_CONSTANT_FETCH_03_5) +XE_GPU_REGISTER(0x4818, kDword, SHADER_CONSTANT_FETCH_04_0) +XE_GPU_REGISTER(0x4819, kDword, SHADER_CONSTANT_FETCH_04_1) +XE_GPU_REGISTER(0x481A, kDword, SHADER_CONSTANT_FETCH_04_2) +XE_GPU_REGISTER(0x481B, kDword, SHADER_CONSTANT_FETCH_04_3) +XE_GPU_REGISTER(0x481C, kDword, SHADER_CONSTANT_FETCH_04_4) +XE_GPU_REGISTER(0x481D, kDword, SHADER_CONSTANT_FETCH_04_5) +XE_GPU_REGISTER(0x481E, kDword, SHADER_CONSTANT_FETCH_05_0) +XE_GPU_REGISTER(0x481F, kDword, SHADER_CONSTANT_FETCH_05_1) +XE_GPU_REGISTER(0x4820, kDword, SHADER_CONSTANT_FETCH_05_2) +XE_GPU_REGISTER(0x4821, kDword, SHADER_CONSTANT_FETCH_05_3) +XE_GPU_REGISTER(0x4822, kDword, SHADER_CONSTANT_FETCH_05_4) +XE_GPU_REGISTER(0x4823, kDword, SHADER_CONSTANT_FETCH_05_5) +XE_GPU_REGISTER(0x4824, kDword, SHADER_CONSTANT_FETCH_06_0) +XE_GPU_REGISTER(0x4825, kDword, SHADER_CONSTANT_FETCH_06_1) +XE_GPU_REGISTER(0x4826, kDword, SHADER_CONSTANT_FETCH_06_2) +XE_GPU_REGISTER(0x4827, kDword, SHADER_CONSTANT_FETCH_06_3) +XE_GPU_REGISTER(0x4828, kDword, SHADER_CONSTANT_FETCH_06_4) +XE_GPU_REGISTER(0x4829, kDword, SHADER_CONSTANT_FETCH_06_5) +XE_GPU_REGISTER(0x482A, kDword, SHADER_CONSTANT_FETCH_07_0) +XE_GPU_REGISTER(0x482B, kDword, SHADER_CONSTANT_FETCH_07_1) +XE_GPU_REGISTER(0x482C, kDword, SHADER_CONSTANT_FETCH_07_2) +XE_GPU_REGISTER(0x482D, kDword, SHADER_CONSTANT_FETCH_07_3) +XE_GPU_REGISTER(0x482E, kDword, SHADER_CONSTANT_FETCH_07_4) +XE_GPU_REGISTER(0x482F, kDword, SHADER_CONSTANT_FETCH_07_5) +XE_GPU_REGISTER(0x4830, kDword, SHADER_CONSTANT_FETCH_08_0) +XE_GPU_REGISTER(0x4831, kDword, SHADER_CONSTANT_FETCH_08_1) +XE_GPU_REGISTER(0x4832, kDword, SHADER_CONSTANT_FETCH_08_2) +XE_GPU_REGISTER(0x4833, kDword, SHADER_CONSTANT_FETCH_08_3) +XE_GPU_REGISTER(0x4834, kDword, SHADER_CONSTANT_FETCH_08_4) +XE_GPU_REGISTER(0x4835, kDword, SHADER_CONSTANT_FETCH_08_5) +XE_GPU_REGISTER(0x4836, kDword, SHADER_CONSTANT_FETCH_09_0) +XE_GPU_REGISTER(0x4837, kDword, SHADER_CONSTANT_FETCH_09_1) +XE_GPU_REGISTER(0x4838, kDword, SHADER_CONSTANT_FETCH_09_2) +XE_GPU_REGISTER(0x4839, kDword, SHADER_CONSTANT_FETCH_09_3) +XE_GPU_REGISTER(0x483A, kDword, SHADER_CONSTANT_FETCH_09_4) +XE_GPU_REGISTER(0x483B, kDword, SHADER_CONSTANT_FETCH_09_5) +XE_GPU_REGISTER(0x483C, kDword, SHADER_CONSTANT_FETCH_10_0) +XE_GPU_REGISTER(0x483D, kDword, SHADER_CONSTANT_FETCH_10_1) +XE_GPU_REGISTER(0x483E, kDword, SHADER_CONSTANT_FETCH_10_2) +XE_GPU_REGISTER(0x483F, kDword, SHADER_CONSTANT_FETCH_10_3) +XE_GPU_REGISTER(0x4840, kDword, SHADER_CONSTANT_FETCH_10_4) +XE_GPU_REGISTER(0x4841, kDword, SHADER_CONSTANT_FETCH_10_5) +XE_GPU_REGISTER(0x4842, kDword, SHADER_CONSTANT_FETCH_11_0) +XE_GPU_REGISTER(0x4843, kDword, SHADER_CONSTANT_FETCH_11_1) +XE_GPU_REGISTER(0x4844, kDword, SHADER_CONSTANT_FETCH_11_2) +XE_GPU_REGISTER(0x4845, kDword, SHADER_CONSTANT_FETCH_11_3) +XE_GPU_REGISTER(0x4846, kDword, SHADER_CONSTANT_FETCH_11_4) +XE_GPU_REGISTER(0x4847, kDword, SHADER_CONSTANT_FETCH_11_5) +XE_GPU_REGISTER(0x4848, kDword, SHADER_CONSTANT_FETCH_12_0) +XE_GPU_REGISTER(0x4849, kDword, SHADER_CONSTANT_FETCH_12_1) +XE_GPU_REGISTER(0x484A, kDword, SHADER_CONSTANT_FETCH_12_2) +XE_GPU_REGISTER(0x484B, kDword, SHADER_CONSTANT_FETCH_12_3) +XE_GPU_REGISTER(0x484C, kDword, SHADER_CONSTANT_FETCH_12_4) +XE_GPU_REGISTER(0x484D, kDword, SHADER_CONSTANT_FETCH_12_5) +XE_GPU_REGISTER(0x484E, kDword, SHADER_CONSTANT_FETCH_13_0) +XE_GPU_REGISTER(0x484F, kDword, SHADER_CONSTANT_FETCH_13_1) +XE_GPU_REGISTER(0x4850, kDword, SHADER_CONSTANT_FETCH_13_2) +XE_GPU_REGISTER(0x4851, kDword, SHADER_CONSTANT_FETCH_13_3) +XE_GPU_REGISTER(0x4852, kDword, SHADER_CONSTANT_FETCH_13_4) +XE_GPU_REGISTER(0x4853, kDword, SHADER_CONSTANT_FETCH_13_5) +XE_GPU_REGISTER(0x4854, kDword, SHADER_CONSTANT_FETCH_14_0) +XE_GPU_REGISTER(0x4855, kDword, SHADER_CONSTANT_FETCH_14_1) +XE_GPU_REGISTER(0x4856, kDword, SHADER_CONSTANT_FETCH_14_2) +XE_GPU_REGISTER(0x4857, kDword, SHADER_CONSTANT_FETCH_14_3) +XE_GPU_REGISTER(0x4858, kDword, SHADER_CONSTANT_FETCH_14_4) +XE_GPU_REGISTER(0x4859, kDword, SHADER_CONSTANT_FETCH_14_5) +XE_GPU_REGISTER(0x485A, kDword, SHADER_CONSTANT_FETCH_15_0) +XE_GPU_REGISTER(0x485B, kDword, SHADER_CONSTANT_FETCH_15_1) +XE_GPU_REGISTER(0x485C, kDword, SHADER_CONSTANT_FETCH_15_2) +XE_GPU_REGISTER(0x485D, kDword, SHADER_CONSTANT_FETCH_15_3) +XE_GPU_REGISTER(0x485E, kDword, SHADER_CONSTANT_FETCH_15_4) +XE_GPU_REGISTER(0x485F, kDword, SHADER_CONSTANT_FETCH_15_5) +XE_GPU_REGISTER(0x4860, kDword, SHADER_CONSTANT_FETCH_16_0) +XE_GPU_REGISTER(0x4861, kDword, SHADER_CONSTANT_FETCH_16_1) +XE_GPU_REGISTER(0x4862, kDword, SHADER_CONSTANT_FETCH_16_2) +XE_GPU_REGISTER(0x4863, kDword, SHADER_CONSTANT_FETCH_16_3) +XE_GPU_REGISTER(0x4864, kDword, SHADER_CONSTANT_FETCH_16_4) +XE_GPU_REGISTER(0x4865, kDword, SHADER_CONSTANT_FETCH_16_5) +XE_GPU_REGISTER(0x4866, kDword, SHADER_CONSTANT_FETCH_17_0) +XE_GPU_REGISTER(0x4867, kDword, SHADER_CONSTANT_FETCH_17_1) +XE_GPU_REGISTER(0x4868, kDword, SHADER_CONSTANT_FETCH_17_2) +XE_GPU_REGISTER(0x4869, kDword, SHADER_CONSTANT_FETCH_17_3) +XE_GPU_REGISTER(0x486A, kDword, SHADER_CONSTANT_FETCH_17_4) +XE_GPU_REGISTER(0x486B, kDword, SHADER_CONSTANT_FETCH_17_5) +XE_GPU_REGISTER(0x486C, kDword, SHADER_CONSTANT_FETCH_18_0) +XE_GPU_REGISTER(0x486D, kDword, SHADER_CONSTANT_FETCH_18_1) +XE_GPU_REGISTER(0x486E, kDword, SHADER_CONSTANT_FETCH_18_2) +XE_GPU_REGISTER(0x486F, kDword, SHADER_CONSTANT_FETCH_18_3) +XE_GPU_REGISTER(0x4870, kDword, SHADER_CONSTANT_FETCH_18_4) +XE_GPU_REGISTER(0x4871, kDword, SHADER_CONSTANT_FETCH_18_5) +XE_GPU_REGISTER(0x4872, kDword, SHADER_CONSTANT_FETCH_19_0) +XE_GPU_REGISTER(0x4873, kDword, SHADER_CONSTANT_FETCH_19_1) +XE_GPU_REGISTER(0x4874, kDword, SHADER_CONSTANT_FETCH_19_2) +XE_GPU_REGISTER(0x4875, kDword, SHADER_CONSTANT_FETCH_19_3) +XE_GPU_REGISTER(0x4876, kDword, SHADER_CONSTANT_FETCH_19_4) +XE_GPU_REGISTER(0x4877, kDword, SHADER_CONSTANT_FETCH_19_5) +XE_GPU_REGISTER(0x4878, kDword, SHADER_CONSTANT_FETCH_20_0) +XE_GPU_REGISTER(0x4879, kDword, SHADER_CONSTANT_FETCH_20_1) +XE_GPU_REGISTER(0x487A, kDword, SHADER_CONSTANT_FETCH_20_2) +XE_GPU_REGISTER(0x487B, kDword, SHADER_CONSTANT_FETCH_20_3) +XE_GPU_REGISTER(0x487C, kDword, SHADER_CONSTANT_FETCH_20_4) +XE_GPU_REGISTER(0x487D, kDword, SHADER_CONSTANT_FETCH_20_5) +XE_GPU_REGISTER(0x487E, kDword, SHADER_CONSTANT_FETCH_21_0) +XE_GPU_REGISTER(0x487F, kDword, SHADER_CONSTANT_FETCH_21_1) +XE_GPU_REGISTER(0x4880, kDword, SHADER_CONSTANT_FETCH_21_2) +XE_GPU_REGISTER(0x4881, kDword, SHADER_CONSTANT_FETCH_21_3) +XE_GPU_REGISTER(0x4882, kDword, SHADER_CONSTANT_FETCH_21_4) +XE_GPU_REGISTER(0x4883, kDword, SHADER_CONSTANT_FETCH_21_5) +XE_GPU_REGISTER(0x4884, kDword, SHADER_CONSTANT_FETCH_22_0) +XE_GPU_REGISTER(0x4885, kDword, SHADER_CONSTANT_FETCH_22_1) +XE_GPU_REGISTER(0x4886, kDword, SHADER_CONSTANT_FETCH_22_2) +XE_GPU_REGISTER(0x4887, kDword, SHADER_CONSTANT_FETCH_22_3) +XE_GPU_REGISTER(0x4888, kDword, SHADER_CONSTANT_FETCH_22_4) +XE_GPU_REGISTER(0x4889, kDword, SHADER_CONSTANT_FETCH_22_5) +XE_GPU_REGISTER(0x488A, kDword, SHADER_CONSTANT_FETCH_23_0) +XE_GPU_REGISTER(0x488B, kDword, SHADER_CONSTANT_FETCH_23_1) +XE_GPU_REGISTER(0x488C, kDword, SHADER_CONSTANT_FETCH_23_2) +XE_GPU_REGISTER(0x488D, kDword, SHADER_CONSTANT_FETCH_23_3) +XE_GPU_REGISTER(0x488E, kDword, SHADER_CONSTANT_FETCH_23_4) +XE_GPU_REGISTER(0x488F, kDword, SHADER_CONSTANT_FETCH_23_5) +XE_GPU_REGISTER(0x4890, kDword, SHADER_CONSTANT_FETCH_24_0) +XE_GPU_REGISTER(0x4891, kDword, SHADER_CONSTANT_FETCH_24_1) +XE_GPU_REGISTER(0x4892, kDword, SHADER_CONSTANT_FETCH_24_2) +XE_GPU_REGISTER(0x4893, kDword, SHADER_CONSTANT_FETCH_24_3) +XE_GPU_REGISTER(0x4894, kDword, SHADER_CONSTANT_FETCH_24_4) +XE_GPU_REGISTER(0x4895, kDword, SHADER_CONSTANT_FETCH_24_5) +XE_GPU_REGISTER(0x4896, kDword, SHADER_CONSTANT_FETCH_25_0) +XE_GPU_REGISTER(0x4897, kDword, SHADER_CONSTANT_FETCH_25_1) +XE_GPU_REGISTER(0x4898, kDword, SHADER_CONSTANT_FETCH_25_2) +XE_GPU_REGISTER(0x4899, kDword, SHADER_CONSTANT_FETCH_25_3) +XE_GPU_REGISTER(0x489A, kDword, SHADER_CONSTANT_FETCH_25_4) +XE_GPU_REGISTER(0x489B, kDword, SHADER_CONSTANT_FETCH_25_5) +XE_GPU_REGISTER(0x489C, kDword, SHADER_CONSTANT_FETCH_26_0) +XE_GPU_REGISTER(0x489D, kDword, SHADER_CONSTANT_FETCH_26_1) +XE_GPU_REGISTER(0x489E, kDword, SHADER_CONSTANT_FETCH_26_2) +XE_GPU_REGISTER(0x489F, kDword, SHADER_CONSTANT_FETCH_26_3) +XE_GPU_REGISTER(0x48A0, kDword, SHADER_CONSTANT_FETCH_26_4) +XE_GPU_REGISTER(0x48A1, kDword, SHADER_CONSTANT_FETCH_26_5) +XE_GPU_REGISTER(0x48A2, kDword, SHADER_CONSTANT_FETCH_27_0) +XE_GPU_REGISTER(0x48A3, kDword, SHADER_CONSTANT_FETCH_27_1) +XE_GPU_REGISTER(0x48A4, kDword, SHADER_CONSTANT_FETCH_27_2) +XE_GPU_REGISTER(0x48A5, kDword, SHADER_CONSTANT_FETCH_27_3) +XE_GPU_REGISTER(0x48A6, kDword, SHADER_CONSTANT_FETCH_27_4) +XE_GPU_REGISTER(0x48A7, kDword, SHADER_CONSTANT_FETCH_27_5) +XE_GPU_REGISTER(0x48A8, kDword, SHADER_CONSTANT_FETCH_28_0) +XE_GPU_REGISTER(0x48A9, kDword, SHADER_CONSTANT_FETCH_28_1) +XE_GPU_REGISTER(0x48AA, kDword, SHADER_CONSTANT_FETCH_28_2) +XE_GPU_REGISTER(0x48AB, kDword, SHADER_CONSTANT_FETCH_28_3) +XE_GPU_REGISTER(0x48AC, kDword, SHADER_CONSTANT_FETCH_28_4) +XE_GPU_REGISTER(0x48AD, kDword, SHADER_CONSTANT_FETCH_28_5) +XE_GPU_REGISTER(0x48AE, kDword, SHADER_CONSTANT_FETCH_29_0) +XE_GPU_REGISTER(0x48AF, kDword, SHADER_CONSTANT_FETCH_29_1) +XE_GPU_REGISTER(0x48B0, kDword, SHADER_CONSTANT_FETCH_29_2) +XE_GPU_REGISTER(0x48B1, kDword, SHADER_CONSTANT_FETCH_29_3) +XE_GPU_REGISTER(0x48B2, kDword, SHADER_CONSTANT_FETCH_29_4) +XE_GPU_REGISTER(0x48B3, kDword, SHADER_CONSTANT_FETCH_29_5) +XE_GPU_REGISTER(0x48B4, kDword, SHADER_CONSTANT_FETCH_30_0) +XE_GPU_REGISTER(0x48B5, kDword, SHADER_CONSTANT_FETCH_30_1) +XE_GPU_REGISTER(0x48B6, kDword, SHADER_CONSTANT_FETCH_30_2) +XE_GPU_REGISTER(0x48B7, kDword, SHADER_CONSTANT_FETCH_30_3) +XE_GPU_REGISTER(0x48B8, kDword, SHADER_CONSTANT_FETCH_30_4) +XE_GPU_REGISTER(0x48B9, kDword, SHADER_CONSTANT_FETCH_30_5) +XE_GPU_REGISTER(0x48BA, kDword, SHADER_CONSTANT_FETCH_31_0) +XE_GPU_REGISTER(0x48BB, kDword, SHADER_CONSTANT_FETCH_31_1) +XE_GPU_REGISTER(0x48BC, kDword, SHADER_CONSTANT_FETCH_31_2) +XE_GPU_REGISTER(0x48BD, kDword, SHADER_CONSTANT_FETCH_31_3) +XE_GPU_REGISTER(0x48BE, kDword, SHADER_CONSTANT_FETCH_31_4) +XE_GPU_REGISTER(0x48BF, kDword, SHADER_CONSTANT_FETCH_31_5) + +XE_GPU_REGISTER(0x4900, kDword, SHADER_CONSTANT_BOOL_000_031) +XE_GPU_REGISTER(0x4901, kDword, SHADER_CONSTANT_BOOL_032_063) +XE_GPU_REGISTER(0x4902, kDword, SHADER_CONSTANT_BOOL_064_095) +XE_GPU_REGISTER(0x4903, kDword, SHADER_CONSTANT_BOOL_096_127) +XE_GPU_REGISTER(0x4904, kDword, SHADER_CONSTANT_BOOL_128_159) +XE_GPU_REGISTER(0x4905, kDword, SHADER_CONSTANT_BOOL_160_191) +XE_GPU_REGISTER(0x4906, kDword, SHADER_CONSTANT_BOOL_192_223) +XE_GPU_REGISTER(0x4907, kDword, SHADER_CONSTANT_BOOL_224_255) + +XE_GPU_REGISTER(0x4908, kDword, SHADER_CONSTANT_LOOP_00) +XE_GPU_REGISTER(0x4909, kDword, SHADER_CONSTANT_LOOP_01) +XE_GPU_REGISTER(0x490A, kDword, SHADER_CONSTANT_LOOP_02) +XE_GPU_REGISTER(0x490B, kDword, SHADER_CONSTANT_LOOP_03) +XE_GPU_REGISTER(0x490C, kDword, SHADER_CONSTANT_LOOP_04) +XE_GPU_REGISTER(0x490D, kDword, SHADER_CONSTANT_LOOP_05) +XE_GPU_REGISTER(0x490E, kDword, SHADER_CONSTANT_LOOP_06) +XE_GPU_REGISTER(0x490F, kDword, SHADER_CONSTANT_LOOP_07) +XE_GPU_REGISTER(0x4910, kDword, SHADER_CONSTANT_LOOP_08) +XE_GPU_REGISTER(0x4911, kDword, SHADER_CONSTANT_LOOP_09) +XE_GPU_REGISTER(0x4912, kDword, SHADER_CONSTANT_LOOP_10) +XE_GPU_REGISTER(0x4913, kDword, SHADER_CONSTANT_LOOP_11) +XE_GPU_REGISTER(0x4914, kDword, SHADER_CONSTANT_LOOP_12) +XE_GPU_REGISTER(0x4915, kDword, SHADER_CONSTANT_LOOP_13) +XE_GPU_REGISTER(0x4916, kDword, SHADER_CONSTANT_LOOP_14) +XE_GPU_REGISTER(0x4917, kDword, SHADER_CONSTANT_LOOP_15) +XE_GPU_REGISTER(0x4918, kDword, SHADER_CONSTANT_LOOP_16) +XE_GPU_REGISTER(0x4919, kDword, SHADER_CONSTANT_LOOP_17) +XE_GPU_REGISTER(0x491A, kDword, SHADER_CONSTANT_LOOP_18) +XE_GPU_REGISTER(0x491B, kDword, SHADER_CONSTANT_LOOP_19) +XE_GPU_REGISTER(0x491C, kDword, SHADER_CONSTANT_LOOP_20) +XE_GPU_REGISTER(0x491D, kDword, SHADER_CONSTANT_LOOP_21) +XE_GPU_REGISTER(0x491E, kDword, SHADER_CONSTANT_LOOP_22) +XE_GPU_REGISTER(0x491F, kDword, SHADER_CONSTANT_LOOP_23) +XE_GPU_REGISTER(0x4920, kDword, SHADER_CONSTANT_LOOP_24) +XE_GPU_REGISTER(0x4921, kDword, SHADER_CONSTANT_LOOP_25) +XE_GPU_REGISTER(0x4922, kDword, SHADER_CONSTANT_LOOP_26) +XE_GPU_REGISTER(0x4923, kDword, SHADER_CONSTANT_LOOP_27) +XE_GPU_REGISTER(0x4924, kDword, SHADER_CONSTANT_LOOP_28) +XE_GPU_REGISTER(0x4925, kDword, SHADER_CONSTANT_LOOP_29) +XE_GPU_REGISTER(0x4926, kDword, SHADER_CONSTANT_LOOP_30) +XE_GPU_REGISTER(0x4927, kDword, SHADER_CONSTANT_LOOP_31) + +XE_GPU_REGISTER(0x5000, kDword, SHADER_CONSTANT_FLUSH_FETCH_0) +XE_GPU_REGISTER(0x5001, kDword, SHADER_CONSTANT_FLUSH_FETCH_1) +XE_GPU_REGISTER(0x5002, kDword, SHADER_CONSTANT_FLUSH_FETCH_2) + +// Ignored because I have no clue what these are. +// XE_GPU_REGISTER(0x8D00, kDword, UNKNOWN_8D00) +// XE_GPU_REGISTER(0x8D01, kDword, UNKNOWN_8D01) +// XE_GPU_REGISTER(0x8D02, kDword, UNKNOWN_8D02) +// XE_GPU_REGISTER(0x8D03, kDword, UNKNOWN_8D03) +// XE_GPU_REGISTER(0x8D04, kDword, UNKNOWN_8D04) +// XE_GPU_REGISTER(0x8D05, kDword, UNKNOWN_8D05) +// XE_GPU_REGISTER(0x8D06, kDword, UNKNOWN_8D06) +// XE_GPU_REGISTER(0x8D07, kDword, UNKNOWN_8D07) + +// Registers present in both Xenia Edge and Xenia Canary. +// Added to keep local register metadata aligned and reduce unknown-register warnings. +XE_GPU_REGISTER(0x0000, kDword, RBBM_RTL_RELEASE) +XE_GPU_REGISTER(0x0001, kDword, RBBM_PATCH_RELEASE) +XE_GPU_REGISTER(0x0002, kDword, RBBM_AUXILIARY_CONFIG) +XE_GPU_REGISTER(0x0004, kDword, BIOS_0_SCRATCH) +XE_GPU_REGISTER(0x0005, kDword, BIOS_1_SCRATCH) +XE_GPU_REGISTER(0x0006, kDword, BIOS_2_SCRATCH) +XE_GPU_REGISTER(0x0007, kDword, BIOS_3_SCRATCH) +XE_GPU_REGISTER(0x0008, kDword, BIOS_4_SCRATCH) +XE_GPU_REGISTER(0x0009, kDword, BIOS_5_SCRATCH) +XE_GPU_REGISTER(0x000A, kDword, BIOS_6_SCRATCH) +XE_GPU_REGISTER(0x000B, kDword, BIOS_7_SCRATCH) +XE_GPU_REGISTER(0x0038, kDword, CONFIG_CNTL) +XE_GPU_REGISTER(0x0039, kDword, CONFIG_XSTRAP) +XE_GPU_REGISTER(0x003A, kDword, CONFIG_XSTRAP2) +XE_GPU_REGISTER(0x003B, kDword, RBBM_CNTL) +XE_GPU_REGISTER(0x003C, kDword, RBBM_SOFT_RESET) +XE_GPU_REGISTER(0x003D, kDword, RBBM_SKEW_CNTL) +XE_GPU_REGISTER(0x0040, kDword, MH_MMU_CONFIG) +XE_GPU_REGISTER(0x0041, kDword, MH_MMU_VA_RANGE) +XE_GPU_REGISTER(0x0042, kDword, MH_MMU_PT_BASE) +XE_GPU_REGISTER(0x0043, kDword, MH_MMU_PAGE_FAULT) +XE_GPU_REGISTER(0x0044, kDword, MH_MMU_TRAN_ERROR) +XE_GPU_REGISTER(0x0045, kDword, MH_MMU_INVALIDATE) +XE_GPU_REGISTER(0x0046, kDword, MH_MMU_MPU_BASE) +XE_GPU_REGISTER(0x0047, kDword, MH_MMU_MPU_END) +XE_GPU_REGISTER(0x0064, kDword, ROM_PAR_DATA_REG) +XE_GPU_REGISTER(0x0065, kDword, ROM_BAD_PIPE_DISABLE_REGISTER) +XE_GPU_REGISTER(0x0066, kDword, ROM_PAR_ADDR_REG) +XE_GPU_REGISTER(0x0067, kDword, ROM_CLK_REG) +XE_GPU_REGISTER(0x0068, kDword, ROM_BAD_PIPE_FUSE_REG) +XE_GPU_REGISTER(0x0069, kDword, DBG_CNTL1_REG) +XE_GPU_REGISTER(0x006A, kDword, ROM_SIMD_PIPE_DISABLE_REGISTER) +XE_GPU_REGISTER(0x006B, kDword, DBG_READ_REG) +XE_GPU_REGISTER(0x006C, kDword, ROM_PADS_REG) +XE_GPU_REGISTER(0x006D, kDword, SOFT_STRAP_CNTL) +XE_GPU_REGISTER(0x006E, kDword, CONFIG_XSTRAP3) +XE_GPU_REGISTER(0x006F, kDword, EXTERN_TRIG_CNTL) +XE_GPU_REGISTER(0x0070, kDword, ROM_STATUS_REG) +XE_GPU_REGISTER(0x0071, kDword, ROM_PORT_REG) +XE_GPU_REGISTER(0x0083, kDword, FSB_STOP_CLK_REG) +XE_GPU_REGISTER(0x0084, kDword, SPLL_CNTL_REG) +XE_GPU_REGISTER(0x0085, kDword, CG_SCRATCH1) +XE_GPU_REGISTER(0x0086, kDword, RCLK_PWRMGT_CNTL_REG) +XE_GPU_REGISTER(0x0087, kDword, PSRO_REG) +XE_GPU_REGISTER(0x0091, kDword, RPLL_CNTL_REG) +XE_GPU_REGISTER(0x0092, kDword, FPLL_CNTL_REG) +XE_GPU_REGISTER(0x0093, kDword, CG_INT_MASK_REG) +XE_GPU_REGISTER(0x0094, kDword, CG_INT_STAT_REG) +XE_GPU_REGISTER(0x0095, kDword, CG_INT_ACK_REG) +XE_GPU_REGISTER(0x00A0, kDword, MCLK_CNTL1_REG) +XE_GPU_REGISTER(0x00A1, kDword, MPLL_CNTL_REG) +XE_GPU_REGISTER(0x00A2, kDword, YCLK_CNTL1_REG) +XE_GPU_REGISTER(0x00A3, kDword, MDLL_CNTL1_REG) +XE_GPU_REGISTER(0x00A6, kDword, MCLK_PWRMGT_CNTL_REG) +XE_GPU_REGISTER(0x00A7, kDword, MCLK_TEST_CNTL1_REG) +XE_GPU_REGISTER(0x00A8, kDword, CGM_MC0_IO_CNTL) +XE_GPU_REGISTER(0x00A9, kDword, CGM_DRAM_CNTL_REG) +XE_GPU_REGISTER(0x00AA, kDword, CGM_MC1_IO_CNTL) +XE_GPU_REGISTER(0x0128, kDword, PCLK_SOFT_RESET) +XE_GPU_REGISTER(0x0129, kDword, DCCG_SCLK_R_DISP_CNTL) +XE_GPU_REGISTER(0x012F, kDword, SCLK_G_SCL1_CNTL) +XE_GPU_REGISTER(0x0132, kDword, SCLK_SOFT_RESET) +XE_GPU_REGISTER(0x0133, kDword, DCCG_CLK_CNTL) +XE_GPU_REGISTER(0x0135, kDword, TEST_COUNT_CNTL) +XE_GPU_REGISTER(0x0136, kDword, DCCG_TEST_CLK_SEL) +XE_GPU_REGISTER(0x013C, kDword, DVOACLK_CNTL) +XE_GPU_REGISTER(0x0140, kDword, DCCG_ONE_SHOT_CLOCKING_CNTL) +XE_GPU_REGISTER(0x0141, kDword, DCCG_ONE_SHOT_STOP_CLOCKS_CNTL) +XE_GPU_REGISTER(0x0142, kDword, DCCG_ONE_SHOT_RUN_CLOCKS_CNTL) +XE_GPU_REGISTER(0x0143, kDword, DCCG_ONE_SHOT_RUN_CLOCKS_COUNT) +XE_GPU_REGISTER(0x0144, kDword, DCCG_DEBUG) +XE_GPU_REGISTER(0x015C, kDword, SCLK_G_DCP_CNTL) +XE_GPU_REGISTER(0x01C0, kDword, CP_RB_BASE) +XE_GPU_REGISTER(0x01C1, kDword, CP_RB_CNTL) +XE_GPU_REGISTER(0x01C3, kDword, CP_RB_RPTR_ADDR) +XE_GPU_REGISTER(0x01C4, kDword, CP_RB_RPTR) +XE_GPU_REGISTER(0x01C5, kDword, CP_RB_WPTR) +XE_GPU_REGISTER(0x01C6, kDword, CP_RB_WPTR_DELAY) +XE_GPU_REGISTER(0x01C7, kDword, CP_RB_RPTR_WR) +XE_GPU_REGISTER(0x01C8, kDword, CP_DMA_SRC_ADDR) +XE_GPU_REGISTER(0x01C9, kDword, CP_DMA_DST_ADDR) +XE_GPU_REGISTER(0x01CA, kDword, CP_DMA_COMMAND) +XE_GPU_REGISTER(0x01CC, kDword, CP_IB1_BASE) +XE_GPU_REGISTER(0x01CD, kDword, CP_IB1_BUFSZ) +XE_GPU_REGISTER(0x01CE, kDword, CP_IB2_BASE) +XE_GPU_REGISTER(0x01CF, kDword, CP_IB2_BUFSZ) +XE_GPU_REGISTER(0x01D0, kDword, CP_RT_BASE) +XE_GPU_REGISTER(0x01D1, kDword, CP_RT_BUFSZ) +XE_GPU_REGISTER(0x01D2, kDword, CP_RT_ST_BASE) +XE_GPU_REGISTER(0x01D3, kDword, CP_RT_ST_BUFSZ) +XE_GPU_REGISTER(0x01D5, kDword, CP_QUEUE_THRESHOLDS) +XE_GPU_REGISTER(0x01D6, kDword, CP_MEQ_THRESHOLDS) +XE_GPU_REGISTER(0x01D7, kDword, CP_CSQ_AVAIL) +XE_GPU_REGISTER(0x01D8, kDword, CP_STQ_AVAIL) +XE_GPU_REGISTER(0x01D9, kDword, CP_MEQ_AVAIL) +XE_GPU_REGISTER(0x01DA, kDword, CP_CMD_INDEX) +XE_GPU_REGISTER(0x01DB, kDword, CP_CMD_DATA) +XE_GPU_REGISTER(0x01DE, kDword, SCRATCH_CMP_HI) +XE_GPU_REGISTER(0x01DF, kDword, SCRATCH_CMP_LO) +XE_GPU_REGISTER(0x01E0, kDword, CP_DMA_TABLE_ADDR) +XE_GPU_REGISTER(0x01E1, kDword, CP_DMA_SRC_ADDR_STAT) +XE_GPU_REGISTER(0x01E2, kDword, CP_DMA_DST_ADDR_STAT) +XE_GPU_REGISTER(0x01E3, kDword, CP_DMA_COMMAND_STAT) +XE_GPU_REGISTER(0x01E4, kDword, CP_DMA_STAT) +XE_GPU_REGISTER(0x01E5, kDword, CP_DMA_ACT_DSCR_STAT) +XE_GPU_REGISTER(0x01E9, kDword, SCRATCH_CMP_CNTL) +XE_GPU_REGISTER(0x01EA, kDword, CP_ME_RDADDR) +XE_GPU_REGISTER(0x01EC, kDword, CP_STATE_DEBUG_INDEX) +XE_GPU_REGISTER(0x01ED, kDword, CP_STATE_DEBUG_DATA) +XE_GPU_REGISTER(0x01EE, kDword, CP_NV_FLAGS_0) +XE_GPU_REGISTER(0x01EF, kDword, CP_NV_FLAGS_1) +XE_GPU_REGISTER(0x01F0, kDword, CP_NV_FLAGS_2) +XE_GPU_REGISTER(0x01F1, kDword, CP_NV_FLAGS_3) +XE_GPU_REGISTER(0x01F2, kDword, CP_INT_CNTL) +XE_GPU_REGISTER(0x01F3, kDword, CP_INT_STATUS) +XE_GPU_REGISTER(0x01F4, kDword, CP_INT_ACK) +XE_GPU_REGISTER(0x01F6, kDword, CP_ME_CNTL) +XE_GPU_REGISTER(0x01F7, kDword, CP_ME_STATUS) +XE_GPU_REGISTER(0x01F8, kDword, CP_ME_RAM_WADDR) +XE_GPU_REGISTER(0x01F9, kDword, CP_ME_RAM_RADDR) +XE_GPU_REGISTER(0x01FA, kDword, CP_ME_RAM_DATA) +XE_GPU_REGISTER(0x01FB, kDword, CP_SNOOP_CNTL) +XE_GPU_REGISTER(0x01FC, kDword, CP_DEBUG) +XE_GPU_REGISTER(0x01FD, kDword, CP_CSQ_RB_STAT) +XE_GPU_REGISTER(0x01FE, kDword, CP_CSQ_IB1_STAT) +XE_GPU_REGISTER(0x01FF, kDword, CP_CSQ_IB2_STAT) +XE_GPU_REGISTER(0x0394, kDword, NQWAIT_UNTIL) +XE_GPU_REGISTER(0x039B, kDword, RBBM_DEBUG) +XE_GPU_REGISTER(0x039C, kDword, RBBM_STATUS2) +XE_GPU_REGISTER(0x039D, kDword, RBBM_CRC32) +XE_GPU_REGISTER(0x03A0, kDword, RBBM_DEBUG_OUT) +XE_GPU_REGISTER(0x03A1, kDword, RBBM_DEBUG_CNTL) +XE_GPU_REGISTER(0x03B2, kDword, RBBM_WAIT_IDLE_CLOCKS) +XE_GPU_REGISTER(0x03B3, kDword, RBBM_READ_ERROR) +XE_GPU_REGISTER(0x03B4, kDword, RBBM_INT_CNTL) +XE_GPU_REGISTER(0x03B5, kDword, RBBM_INT_STATUS) +XE_GPU_REGISTER(0x03B6, kDword, RBBM_INT_ACK) +XE_GPU_REGISTER(0x03B7, kDword, MASTER_INT_SIGNAL) +XE_GPU_REGISTER(0x03F9, kDword, RBBM_PERIPHID1) +XE_GPU_REGISTER(0x03FA, kDword, RBBM_PERIPHID2) +XE_GPU_REGISTER(0x0440, kDword, CP_NON_PREFETCH_CNTRS) +XE_GPU_REGISTER(0x0442, kDword, CP_STQ_RT_STAT) +XE_GPU_REGISTER(0x0443, kDword, CP_STQ_ST_STAT) +XE_GPU_REGISTER(0x0444, kDword, CP_STQ_RT_ST_STAT) +XE_GPU_REGISTER(0x0445, kDword, CP_RT_DMA_SRC_ADDR) +XE_GPU_REGISTER(0x0446, kDword, CP_RT_DMA_DST_ADDR) +XE_GPU_REGISTER(0x0447, kDword, CP_RT_DMA_COMMAND) +XE_GPU_REGISTER(0x0448, kDword, CP_RT_ME_RAM_WADDR) +XE_GPU_REGISTER(0x0449, kDword, CP_RT_ME_RAM_RADDR) +XE_GPU_REGISTER(0x044A, kDword, CP_RT_ME_RAM_DATA) +XE_GPU_REGISTER(0x044B, kDword, CP_PROG_COUNTER) +XE_GPU_REGISTER(0x044C, kDword, CP_RT_ME_RDADDR) +XE_GPU_REGISTER(0x044D, kDword, CP_ST_BASE) +XE_GPU_REGISTER(0x044E, kDword, CP_ST_BUFSZ) +XE_GPU_REGISTER(0x044F, kDword, CP_MEQ_STAT) +XE_GPU_REGISTER(0x0452, kDword, CP_MIU_TAG_STAT0) +XE_GPU_REGISTER(0x0453, kDword, CP_MIU_TAG_STAT1) +XE_GPU_REGISTER(0x0454, kDword, CP_BIN_MASK_LO) +XE_GPU_REGISTER(0x0455, kDword, CP_BIN_MASK_HI) +XE_GPU_REGISTER(0x0456, kDword, CP_BIN_SELECT_LO) +XE_GPU_REGISTER(0x0457, kDword, CP_BIN_SELECT_HI) +XE_GPU_REGISTER(0x0458, kDword, CP_RT_BIN_MASK_LO) +XE_GPU_REGISTER(0x0459, kDword, CP_RT_BIN_MASK_HI) +XE_GPU_REGISTER(0x045A, kDword, CP_RT_BIN_SELECT_LO) +XE_GPU_REGISTER(0x045B, kDword, CP_RT_BIN_SELECT_HI) +XE_GPU_REGISTER(0x045C, kDword, CP_CPU_INT_CNTL) +XE_GPU_REGISTER(0x045D, kDword, CP_CPU_INT_STATUS) +XE_GPU_REGISTER(0x045F, kDword, CP_PFP_UCODE_ADDR) +XE_GPU_REGISTER(0x0460, kDword, CP_PFP_UCODE_DATA) +XE_GPU_REGISTER(0x0461, kDword, CP_PFP_RT_UCODE_ADDR) +XE_GPU_REGISTER(0x0462, kDword, CP_PFP_RT_UCODE_DATA) +XE_GPU_REGISTER(0x047E, kDword, CP_RT_STAT) +XE_GPU_REGISTER(0x047F, kDword, CP_STAT) +XE_GPU_REGISTER(0x04C0, kDword, CP_RT0_COMMAND) +XE_GPU_REGISTER(0x04C1, kDword, CP_RT0_POLL_ADDRESS) +XE_GPU_REGISTER(0x04C2, kDword, CP_RT0_REFERENCE) +XE_GPU_REGISTER(0x04C3, kDword, CP_RT0_MASK) +XE_GPU_REGISTER(0x04C4, kDword, CP_RT0_BADR) +XE_GPU_REGISTER(0x04C5, kDword, CP_RT0_SIZE) +XE_GPU_REGISTER(0x04C6, kDword, CP_RT1_COMMAND) +XE_GPU_REGISTER(0x04C7, kDword, CP_RT1_POLL_ADDRESS) +XE_GPU_REGISTER(0x04C8, kDword, CP_RT1_REFERENCE) +XE_GPU_REGISTER(0x04C9, kDword, CP_RT1_MASK) +XE_GPU_REGISTER(0x04CA, kDword, CP_RT1_BADR) +XE_GPU_REGISTER(0x04CB, kDword, CP_RT1_SIZE) +XE_GPU_REGISTER(0x04CC, kDword, CP_RT2_COMMAND) +XE_GPU_REGISTER(0x04CD, kDword, CP_RT2_POLL_ADDRESS) +XE_GPU_REGISTER(0x04CE, kDword, CP_RT2_REFERENCE) +XE_GPU_REGISTER(0x04CF, kDword, CP_RT2_MASK) +XE_GPU_REGISTER(0x04D0, kDword, CP_RT2_BADR) +XE_GPU_REGISTER(0x04D1, kDword, CP_RT2_SIZE) +XE_GPU_REGISTER(0x04D2, kDword, CP_RT3_COMMAND) +XE_GPU_REGISTER(0x04D3, kDword, CP_RT3_POLL_ADDRESS) +XE_GPU_REGISTER(0x04D4, kDword, CP_RT3_REFERENCE) +XE_GPU_REGISTER(0x04D5, kDword, CP_RT3_MASK) +XE_GPU_REGISTER(0x04D6, kDword, CP_RT3_BADR) +XE_GPU_REGISTER(0x04D7, kDword, CP_RT3_SIZE) +XE_GPU_REGISTER(0x04D8, kDword, CP_RT4_COMMAND) +XE_GPU_REGISTER(0x04D9, kDword, CP_RT4_POLL_ADDRESS) +XE_GPU_REGISTER(0x04DA, kDword, CP_RT4_REFERENCE) +XE_GPU_REGISTER(0x04DB, kDword, CP_RT4_MASK) +XE_GPU_REGISTER(0x04DC, kDword, CP_RT4_BADR) +XE_GPU_REGISTER(0x04DD, kDword, CP_RT4_SIZE) +XE_GPU_REGISTER(0x04DE, kDword, CP_RT5_COMMAND) +XE_GPU_REGISTER(0x04DF, kDword, CP_RT5_POLL_ADDRESS) +XE_GPU_REGISTER(0x04E0, kDword, CP_RT5_REFERENCE) +XE_GPU_REGISTER(0x04E1, kDword, CP_RT5_MASK) +XE_GPU_REGISTER(0x04E2, kDword, CP_RT5_BADR) +XE_GPU_REGISTER(0x04E3, kDword, CP_RT5_SIZE) +XE_GPU_REGISTER(0x04E4, kDword, CP_RT6_COMMAND) +XE_GPU_REGISTER(0x04E5, kDword, CP_RT6_POLL_ADDRESS) +XE_GPU_REGISTER(0x04E6, kDword, CP_RT6_REFERENCE) +XE_GPU_REGISTER(0x04E7, kDword, CP_RT6_MASK) +XE_GPU_REGISTER(0x04E8, kDword, CP_RT6_BADR) +XE_GPU_REGISTER(0x04E9, kDword, CP_RT6_SIZE) +XE_GPU_REGISTER(0x04EA, kDword, CP_RT7_COMMAND) +XE_GPU_REGISTER(0x04EB, kDword, CP_RT7_POLL_ADDRESS) +XE_GPU_REGISTER(0x04EC, kDword, CP_RT7_REFERENCE) +XE_GPU_REGISTER(0x04ED, kDword, CP_RT7_MASK) +XE_GPU_REGISTER(0x04EE, kDword, CP_RT7_BADR) +XE_GPU_REGISTER(0x04EF, kDword, CP_RT7_SIZE) +XE_GPU_REGISTER(0x04F0, kDword, CP_RT8_COMMAND) +XE_GPU_REGISTER(0x04F1, kDword, CP_RT8_POLL_ADDRESS) +XE_GPU_REGISTER(0x04F2, kDword, CP_RT8_REFERENCE) +XE_GPU_REGISTER(0x04F3, kDword, CP_RT8_MASK) +XE_GPU_REGISTER(0x04F4, kDword, CP_RT8_BADR) +XE_GPU_REGISTER(0x04F5, kDword, CP_RT8_SIZE) +XE_GPU_REGISTER(0x04F6, kDword, CP_RT9_COMMAND) +XE_GPU_REGISTER(0x04F7, kDword, CP_RT9_POLL_ADDRESS) +XE_GPU_REGISTER(0x04F8, kDword, CP_RT9_REFERENCE) +XE_GPU_REGISTER(0x04F9, kDword, CP_RT9_MASK) +XE_GPU_REGISTER(0x04FA, kDword, CP_RT9_BADR) +XE_GPU_REGISTER(0x04FB, kDword, CP_RT9_SIZE) +XE_GPU_REGISTER(0x04FC, kDword, CP_RT10_COMMAND) +XE_GPU_REGISTER(0x04FD, kDword, CP_RT10_POLL_ADDRESS) +XE_GPU_REGISTER(0x04FE, kDword, CP_RT10_REFERENCE) +XE_GPU_REGISTER(0x04FF, kDword, CP_RT10_MASK) +XE_GPU_REGISTER(0x0500, kDword, CP_RT10_BADR) +XE_GPU_REGISTER(0x0501, kDword, CP_RT10_SIZE) +XE_GPU_REGISTER(0x0502, kDword, CP_RT11_COMMAND) +XE_GPU_REGISTER(0x0503, kDword, CP_RT11_POLL_ADDRESS) +XE_GPU_REGISTER(0x0504, kDword, CP_RT11_REFERENCE) +XE_GPU_REGISTER(0x0505, kDword, CP_RT11_MASK) +XE_GPU_REGISTER(0x0506, kDword, CP_RT11_BADR) +XE_GPU_REGISTER(0x0507, kDword, CP_RT11_SIZE) +XE_GPU_REGISTER(0x0508, kDword, CP_RT12_COMMAND) +XE_GPU_REGISTER(0x0509, kDword, CP_RT12_POLL_ADDRESS) +XE_GPU_REGISTER(0x050A, kDword, CP_RT12_REFERENCE) +XE_GPU_REGISTER(0x050B, kDword, CP_RT12_MASK) +XE_GPU_REGISTER(0x050C, kDword, CP_RT12_BADR) +XE_GPU_REGISTER(0x050D, kDword, CP_RT12_SIZE) +XE_GPU_REGISTER(0x050E, kDword, CP_RT13_COMMAND) +XE_GPU_REGISTER(0x050F, kDword, CP_RT13_POLL_ADDRESS) +XE_GPU_REGISTER(0x0510, kDword, CP_RT13_REFERENCE) +XE_GPU_REGISTER(0x0511, kDword, CP_RT13_MASK) +XE_GPU_REGISTER(0x0512, kDword, CP_RT13_BADR) +XE_GPU_REGISTER(0x0513, kDword, CP_RT13_SIZE) +XE_GPU_REGISTER(0x0514, kDword, CP_RT14_COMMAND) +XE_GPU_REGISTER(0x0515, kDword, CP_RT14_POLL_ADDRESS) +XE_GPU_REGISTER(0x0516, kDword, CP_RT14_REFERENCE) +XE_GPU_REGISTER(0x0517, kDword, CP_RT14_MASK) +XE_GPU_REGISTER(0x0518, kDword, CP_RT14_RADR) +XE_GPU_REGISTER(0x0519, kDword, CP_RT14_SIZE) +XE_GPU_REGISTER(0x051A, kDword, CP_RT15_COMMAND) +XE_GPU_REGISTER(0x051B, kDword, CP_RT15_POLL_ADDRESS) +XE_GPU_REGISTER(0x051C, kDword, CP_RT15_REFERENCE) +XE_GPU_REGISTER(0x051D, kDword, CP_RT15_MASK) +XE_GPU_REGISTER(0x051E, kDword, CP_RT15_BADR) +XE_GPU_REGISTER(0x051F, kDword, CP_RT15_SIZE) +XE_GPU_REGISTER(0x0520, kDword, CP_RT_POLL_INTERVAL) +XE_GPU_REGISTER(0x0521, kDword, CP_VIP_EOL_EOF_COUNTER) +XE_GPU_REGISTER(0x0522, kDword, CP_D1_EOL_SOF_COUNTER) +XE_GPU_REGISTER(0x0523, kDword, CP_D2_EOL_SOF_COUNTER) +XE_GPU_REGISTER(0x0580, kDword, BIOS_8_SCRATCH) +XE_GPU_REGISTER(0x0581, kDword, BIOS_9_SCRATCH) +XE_GPU_REGISTER(0x0582, kDword, BIOS_10_SCRATCH) +XE_GPU_REGISTER(0x0583, kDword, BIOS_11_SCRATCH) +XE_GPU_REGISTER(0x0584, kDword, BIOS_12_SCRATCH) +XE_GPU_REGISTER(0x0585, kDword, BIOS_13_SCRATCH) +XE_GPU_REGISTER(0x0586, kDword, BIOS_14_SCRATCH) +XE_GPU_REGISTER(0x0587, kDword, BIOS_15_SCRATCH) +XE_GPU_REGISTER(0x05C9, kDword, RBBM_ISYNC_CNTL) +XE_GPU_REGISTER(0x05F0, kDword, CP_IB2D_BASE) +XE_GPU_REGISTER(0x05F1, kDword, CP_IB2D_BUFSZ) +XE_GPU_REGISTER(0x05F2, kDword, CP_DEFAULT_PITCH_OFFSET) +XE_GPU_REGISTER(0x05F3, kDword, CP_DEFAULT2_PITCH_OFFSET) +XE_GPU_REGISTER(0x05F4, kDword, CP_DEFAULT_SC_BOTTOM_RIGHT) +XE_GPU_REGISTER(0x05F5, kDword, CP_DEFAULT2_SC_BOTTOM_RIGHT) +XE_GPU_REGISTER(0x05F6, kDword, CP_2D_BRUSH_BASE) +XE_GPU_REGISTER(0x05F7, kDword, CP_2D_PALETTE_BASE) +XE_GPU_REGISTER(0x05F8, kDword, CP_2D_IMMD_BASE) +XE_GPU_REGISTER(0x05F9, kDword, CP_2D_BOOLEANS) +XE_GPU_REGISTER(0x0600, kDword, CP_ME_VS_EVENT_SRC) +XE_GPU_REGISTER(0x0601, kDword, CP_ME_VS_EVENT_ADDR) +XE_GPU_REGISTER(0x0602, kDword, CP_ME_VS_EVENT_DATA) +XE_GPU_REGISTER(0x0603, kDword, CP_ME_VS_EVENT_ADDR_SWM) +XE_GPU_REGISTER(0x0604, kDword, CP_ME_VS_EVENT_DATA_SWM) +XE_GPU_REGISTER(0x0605, kDword, CP_ME_PS_EVENT_SRC) +XE_GPU_REGISTER(0x0606, kDword, CP_ME_PS_EVENT_ADDR) +XE_GPU_REGISTER(0x0607, kDword, CP_ME_PS_EVENT_DATA) +XE_GPU_REGISTER(0x0608, kDword, CP_ME_PS_EVENT_ADDR_SWM) +XE_GPU_REGISTER(0x0609, kDword, CP_ME_PS_EVENT_DATA_SWM) +XE_GPU_REGISTER(0x060A, kDword, CP_ME_CF_EVENT_SRC) +XE_GPU_REGISTER(0x060B, kDword, CP_ME_CF_EVENT_ADDR) +XE_GPU_REGISTER(0x060C, kDword, CP_ME_CF_EVENT_DATA) +XE_GPU_REGISTER(0x060D, kDword, CP_ME_NRT_ADDR) +XE_GPU_REGISTER(0x060E, kDword, CP_ME_NRT_DATA) +XE_GPU_REGISTER(0x060F, kDword, CP_ME_RT_ADDR) +XE_GPU_REGISTER(0x0610, kDword, CP_ME_RT_DATA) +XE_GPU_REGISTER(0x0611, kDword, CP_ME_SCREEN_EXT_RPT_ADDR) +XE_GPU_REGISTER(0x0612, kDword, CP_ME_VS_FETCH_DONE_SRC) +XE_GPU_REGISTER(0x0613, kDword, CP_ME_VS_FETCH_DONE_ADDR) +XE_GPU_REGISTER(0x0614, kDword, CP_ME_VS_FETCH_DONE_DATA) +XE_GPU_REGISTER(0x0800, kDword, MC0_CNTL) +XE_GPU_REGISTER(0x0801, kDword, MC0_DRAM_CONFIG) +XE_GPU_REGISTER(0x0802, kDword, MC0_BSB_SNOOPED_TIMER_CNTL) +XE_GPU_REGISTER(0x0803, kDword, MC0_TUNING_0) +XE_GPU_REGISTER(0x0804, kDword, MC0_TUNING_1) +XE_GPU_REGISTER(0x0805, kDword, MC0_RD_BUFFER_CNTL_0) +XE_GPU_REGISTER(0x0806, kDword, MC0_ARBITRATION_CNTL) +XE_GPU_REGISTER(0x0807, kDword, MC0_TIMING_CNTL_0) +XE_GPU_REGISTER(0x0808, kDword, MC0_TIMING_CNTL_1) +XE_GPU_REGISTER(0x0809, kDword, MC0_TIMING_CNTL_2) +XE_GPU_REGISTER(0x080A, kDword, MC0_PAD_CAL_CNTL) +XE_GPU_REGISTER(0x080B, kDword, MC0_DRAM_CMD) +XE_GPU_REGISTER(0x080C, kDword, MC0_DRAM_DATA) +XE_GPU_REGISTER(0x080D, kDword, MC0_POINTER) +XE_GPU_REGISTER(0x080E, kDword, MC0_RDBUF_DATA) +XE_GPU_REGISTER(0x080F, kDword, MC0_DRAM_DQ) +XE_GPU_REGISTER(0x0810, kDword, MC0_STATUS_0) +XE_GPU_REGISTER(0x0811, kDword, MC0_STATUS_1) +XE_GPU_REGISTER(0x0812, kDword, MC0_CRC_CNTL) +XE_GPU_REGISTER(0x0813, kDword, MC0_DEBUG) +XE_GPU_REGISTER(0x0814, kDword, MC0_CRC_READ) +XE_GPU_REGISTER(0x0818, kDword, MC0_PERFCOUNTER1_CNTL) +XE_GPU_REGISTER(0x0819, kDword, MC0_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x081A, kDword, MC0_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x081B, kDword, MC0_INTERRUPT_MASK) +XE_GPU_REGISTER(0x081C, kDword, MC0_INTERRUPT_STATUS) +XE_GPU_REGISTER(0x081D, kDword, MC0_INTERRUPT_ACK) +XE_GPU_REGISTER(0x081E, kDword, MC0_SECURE_MEMORY_APERTURE_LOG_MH) +XE_GPU_REGISTER(0x081F, kDword, MC0_SECURE_MEMORY_APERTURE_LOG_BIU) +XE_GPU_REGISTER(0x0820, kDword, MC0_WR_STR_DLL_0) +XE_GPU_REGISTER(0x0821, kDword, MC0_WR_STR_DLL_1) +XE_GPU_REGISTER(0x0822, kDword, MC0_DLL_MASTER_ADJ_0) +XE_GPU_REGISTER(0x0823, kDword, MC0_DLL_MASTER_ADJ_1) +XE_GPU_REGISTER(0x0824, kDword, MC0_TERM_CNTL) +XE_GPU_REGISTER(0x0825, kDword, MC0_WR_DATA_DLY_0) +XE_GPU_REGISTER(0x0826, kDword, MC0_WR_DATA_DLY_1) +XE_GPU_REGISTER(0x0827, kDword, MC0_RD_STR_DLY_0) +XE_GPU_REGISTER(0x0828, kDword, MC0_RD_STR_DLY_1) +XE_GPU_REGISTER(0x0829, kDword, MC0_WR_STR_DLY) +XE_GPU_REGISTER(0x082A, kDword, MC0_PAD_CAL_STATUS) +XE_GPU_REGISTER(0x082B, kDword, MC0_RD_STR_DLY_CNTL) +XE_GPU_REGISTER(0x0830, kDword, MC0_PAD_IF_CNTL) +XE_GPU_REGISTER(0x0831, kDword, MC0_PAD_IF_CNTL_2) +XE_GPU_REGISTER(0x0832, kDword, MC0_RD_BUFFER_CNTL_1) +XE_GPU_REGISTER(0x0840, kDword, MC1_CNTL) +XE_GPU_REGISTER(0x0841, kDword, MC1_DRAM_CONFIG) +XE_GPU_REGISTER(0x0842, kDword, MC1_BSB_SNOOPED_TIMER_CNTL) +XE_GPU_REGISTER(0x0843, kDword, MC1_TUNING_0) +XE_GPU_REGISTER(0x0844, kDword, MC1_TUNING_1) +XE_GPU_REGISTER(0x0845, kDword, MC1_RD_BUFFER_CNTL_0) +XE_GPU_REGISTER(0x0846, kDword, MC1_ARBITRATION_CNTL) +XE_GPU_REGISTER(0x0847, kDword, MC1_TIMING_CNTL_0) +XE_GPU_REGISTER(0x0848, kDword, MC1_TIMING_CNTL_1) +XE_GPU_REGISTER(0x0849, kDword, MC1_TIMING_CNTL_2) +XE_GPU_REGISTER(0x084A, kDword, MC1_PAD_CAL_CNTL) +XE_GPU_REGISTER(0x084B, kDword, MC1_DRAM_CMD) +XE_GPU_REGISTER(0x084C, kDword, MC1_DRAM_DATA) +XE_GPU_REGISTER(0x084D, kDword, MC1_POINTER) +XE_GPU_REGISTER(0x084E, kDword, MC1_RDBUF_DATA) +XE_GPU_REGISTER(0x084F, kDword, MC1_DRAM_DQ) +XE_GPU_REGISTER(0x0850, kDword, MC1_STATUS_0) +XE_GPU_REGISTER(0x0851, kDword, MC1_STATUS_1) +XE_GPU_REGISTER(0x0852, kDword, MC1_CRC_CNTL) +XE_GPU_REGISTER(0x0853, kDword, MC1_DEBUG) +XE_GPU_REGISTER(0x0854, kDword, MC1_CRC_READ) +XE_GPU_REGISTER(0x0858, kDword, MC1_PERFCOUNTER1_CNTL) +XE_GPU_REGISTER(0x0859, kDword, MC1_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x085A, kDword, MC1_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x085B, kDword, MC1_INTERRUPT_MASK) +XE_GPU_REGISTER(0x085C, kDword, MC1_INTERRUPT_STATUS) +XE_GPU_REGISTER(0x085D, kDword, MC1_INTERRUPT_ACK) +XE_GPU_REGISTER(0x085E, kDword, MC1_SECURE_MEMORY_APERTURE_LOG_MH) +XE_GPU_REGISTER(0x085F, kDword, MC1_SECURE_MEMORY_APERTURE_LOG_BIU) +XE_GPU_REGISTER(0x0860, kDword, MC1_WR_STR_DLL_0) +XE_GPU_REGISTER(0x0861, kDword, MC1_WR_STR_DLL_1) +XE_GPU_REGISTER(0x0862, kDword, MC1_DLL_MASTER_ADJ_0) +XE_GPU_REGISTER(0x0863, kDword, MC1_DLL_MASTER_ADJ_1) +XE_GPU_REGISTER(0x0864, kDword, MC1_TERM_CNTL) +XE_GPU_REGISTER(0x0865, kDword, MC1_WR_DATA_DLY_0) +XE_GPU_REGISTER(0x0866, kDword, MC1_WR_DATA_DLY_1) +XE_GPU_REGISTER(0x0867, kDword, MC1_RD_STR_DLY_0) +XE_GPU_REGISTER(0x0868, kDword, MC1_RD_STR_DLY_1) +XE_GPU_REGISTER(0x0869, kDword, MC1_WR_STR_DLY) +XE_GPU_REGISTER(0x086A, kDword, MC1_PAD_CAL_STATUS) +XE_GPU_REGISTER(0x086B, kDword, MC1_RD_STR_DLY_CNTL) +XE_GPU_REGISTER(0x0870, kDword, MC1_PAD_IF_CNTL) +XE_GPU_REGISTER(0x0871, kDword, MC1_PAD_IF_CNTL_2) +XE_GPU_REGISTER(0x0872, kDword, MC1_RD_BUFFER_CNTL_1) +XE_GPU_REGISTER(0x0A00, kDword, FB_START) +XE_GPU_REGISTER(0x0A01, kDword, FB_SIZE) +XE_GPU_REGISTER(0x0A06, kDword, MH_CNTL) +XE_GPU_REGISTER(0x0A07, kDword, MH_STATUS) +XE_GPU_REGISTER(0x0A08, kDword, MH_INT_MASK) +XE_GPU_REGISTER(0x0A09, kDword, MH_INT_STATUS) +XE_GPU_REGISTER(0x0A0A, kDword, MH_INT_CLEAR) +XE_GPU_REGISTER(0x0A0B, kDword, MH_INT_SIGNAL) +XE_GPU_REGISTER(0x0A0C, kDword, PGL_CTL0) +XE_GPU_REGISTER(0x0A0D, kDword, PGL_CTL1) +XE_GPU_REGISTER(0x0A10, kDword, DC_SURFACE_0_BASE) +XE_GPU_REGISTER(0x0A11, kDword, DC_SURFACE_0_EXTENT) +XE_GPU_REGISTER(0x0A12, kDword, DC_SURFACE_0_INFO) +XE_GPU_REGISTER(0x0A13, kDword, DC_SURFACE_2_BASE) +XE_GPU_REGISTER(0x0A14, kDword, DC_SURFACE_2_EXTENT) +XE_GPU_REGISTER(0x0A15, kDword, DC_SURFACE_2_INFO) +XE_GPU_REGISTER(0x0A21, kDword, DC_SURFACE_1_BASE) +XE_GPU_REGISTER(0x0A22, kDword, DC_SURFACE_1_EXTENT) +XE_GPU_REGISTER(0x0A23, kDword, DC_SURFACE_1_INFO) +XE_GPU_REGISTER(0x0A29, kDword, COHER_SIZE_PM4) +XE_GPU_REGISTER(0x0A2A, kDword, COHER_BASE_PM4) +XE_GPU_REGISTER(0x0A2B, kDword, COHER_STATUS_PM4) +XE_GPU_REGISTER(0x0A2C, kDword, COHER_SIZE_RT) +XE_GPU_REGISTER(0x0A2D, kDword, COHER_BASE_RT) +XE_GPU_REGISTER(0x0A2E, kDword, COHER_STATUS_RT) +XE_GPU_REGISTER(0x0A40, kDword, MH_ARBITER_CONFIG) +XE_GPU_REGISTER(0x0BFE, kDword, MH_DEBUG_INDEX) +XE_GPU_REGISTER(0x0BFF, kDword, MH_DEBUG_DATA) +XE_GPU_REGISTER(0x0C00, kDword, RTS_INITIATOR) +XE_GPU_REGISTER(0x0C01, kDword, RTS_BOUNDBOX_START) +XE_GPU_REGISTER(0x0C02, kDword, RTS_BOUNDBOX_END) +XE_GPU_REGISTER(0x0C03, kDword, RTS_BARYC_REF_VTX_X) +XE_GPU_REGISTER(0x0C04, kDword, RTS_BARYC_REF_VTX_Y) +XE_GPU_REGISTER(0x0C05, kDword, RTS_I_W_DX) +XE_GPU_REGISTER(0x0C06, kDword, RTS_J_W_DY) +XE_GPU_REGISTER(0x0C07, kDword, RTS_INV_W_REF) +XE_GPU_REGISTER(0x0C08, kDword, RTS_INV_W_DX) +XE_GPU_REGISTER(0x0C09, kDword, RTS_INV_W_DY) +XE_GPU_REGISTER(0x0C0A, kDword, RTS_I_W_REF) +XE_GPU_REGISTER(0x0C0B, kDword, RTS_I_W_DY) +XE_GPU_REGISTER(0x0C0C, kDword, RTS_J_W_REF) +XE_GPU_REGISTER(0x0C0D, kDword, RTS_J_W_DX) +XE_GPU_REGISTER(0x0C0E, kDword, RTS_Z_REF) +XE_GPU_REGISTER(0x0C0F, kDword, RTS_Z_DX_MSBS) +XE_GPU_REGISTER(0x0C10, kDword, RTS_Z_DY_MSBS) +XE_GPU_REGISTER(0x0C11, kDword, RTS_Z_DX_DY_LSBS) +XE_GPU_REGISTER(0x0C12, kDword, RTS_Z_MIN) +XE_GPU_REGISTER(0x0C13, kDword, RTS_Z_MAX) +XE_GPU_REGISTER(0x0C14, kDword, RTS_EDGE_0_DIST_LSBS) +XE_GPU_REGISTER(0x0C15, kDword, RTS_EDGE_1_DIST_LSBS) +XE_GPU_REGISTER(0x0C16, kDword, RTS_EDGE_2_DIST_LSBS) +XE_GPU_REGISTER(0x0C17, kDword, RTS_EDGE_DIST_MSBS) +XE_GPU_REGISTER(0x0C18, kDword, RTS_WD_EDGE_0_DIST_LSBS) +XE_GPU_REGISTER(0x0C19, kDword, RTS_WD_EDGE_1_DIST_LSBS) +XE_GPU_REGISTER(0x0C1A, kDword, RTS_WD_EDGE_2_DIST_LSBS) +XE_GPU_REGISTER(0x0C1B, kDword, RTS_WD_EDGE_DIST_MSBS) +XE_GPU_REGISTER(0x0C1C, kDword, RTS_EDGE_0_DX) +XE_GPU_REGISTER(0x0C1D, kDword, RTS_EDGE_0_DY) +XE_GPU_REGISTER(0x0C1E, kDword, RTS_EDGE_1_DX) +XE_GPU_REGISTER(0x0C1F, kDword, RTS_EDGE_1_DY) +XE_GPU_REGISTER(0x0C20, kDword, RTS_EDGE_2_DX) +XE_GPU_REGISTER(0x0C21, kDword, RTS_EDGE_2_DY) +XE_GPU_REGISTER(0x0C22, kDword, RTS_MISC) +XE_GPU_REGISTER(0x0C2C, kDword, VGT_VTX_VECT_EJECT_REG) +XE_GPU_REGISTER(0x0C2D, kDword, VGT_DMA_DATA_FIFO_DEPTH) +XE_GPU_REGISTER(0x0C2E, kDword, VGT_DMA_REQ_FIFO_DEPTH) +XE_GPU_REGISTER(0x0C2F, kDword, VGT_DRAW_INIT_FIFO_DEPTH) +XE_GPU_REGISTER(0x0C30, kDword, VGT_LAST_COPY_STATE) +XE_GPU_REGISTER(0x0C38, kDword, VGT_DEBUG_CNTL) +XE_GPU_REGISTER(0x0C39, kDword, VGT_DEBUG_DATA) +XE_GPU_REGISTER(0x0C3A, kDword, VGT_CRC_SQ_DATA) +XE_GPU_REGISTER(0x0C3B, kDword, VGT_CRC_SQ_CTRL) +XE_GPU_REGISTER(0x0C3C, kDword, VGT_CNTL_STATUS) +XE_GPU_REGISTER(0x0C40, kDword, PA_SC_LINE_STIPPLE_STATE) +XE_GPU_REGISTER(0x0C41, kDword, PA_SC_MULTI_CHIP_CNTL) +XE_GPU_REGISTER(0x0C80, kDword, PA_SU_DEBUG_CNTL) +XE_GPU_REGISTER(0x0C81, kDword, PA_SU_DEBUG_DATA) +XE_GPU_REGISTER(0x0C82, kDword, PA_SC_DEBUG_CNTL) +XE_GPU_REGISTER(0x0C83, kDword, PA_SC_DEBUG_DATA) +XE_GPU_REGISTER(0x0C84, kDword, PA_CL_CNTL_STATUS) +XE_GPU_REGISTER(0x0C86, kDword, PA_SU_FACE_DATA) +XE_GPU_REGISTER(0x0C94, kDword, PA_SU_CNTL_STATUS) +XE_GPU_REGISTER(0x0CA4, kDword, PA_SC_CNTL_STATUS) +XE_GPU_REGISTER(0x0CA5, kDword, PA_SC_ENHANCE) +XE_GPU_REGISTER(0x0CC0, kDword, PA_SC_FIFO_SIZE) +XE_GPU_REGISTER(0x0D03, kDword, SQ_RESOURCE_MANAGMENT) +XE_GPU_REGISTER(0x0D05, kDword, SQ_DEBUG_MISC) +XE_GPU_REGISTER(0x0D06, kDword, SQ_ACTIVITY_METER_CNTL) +XE_GPU_REGISTER(0x0D07, kDword, SQ_ACTIVITY_METER_STATUS) +XE_GPU_REGISTER(0x0D08, kDword, SQ_INPUT_ARB_PRIORITY) +XE_GPU_REGISTER(0x0D09, kDword, SQ_THREAD_ARB_PRIORITY) +XE_GPU_REGISTER(0x0D34, kDword, SQ_INT_CNTL) +XE_GPU_REGISTER(0x0D35, kDword, SQ_INT_STATUS) +XE_GPU_REGISTER(0x0D36, kDword, SQ_INT_ACK) +XE_GPU_REGISTER(0x0DAE, kDword, SQ_DEBUG_INPUT_FSM) +XE_GPU_REGISTER(0x0DAF, kDword, SQ_DEBUG_CONST_MGR_FSM) +XE_GPU_REGISTER(0x0DB0, kDword, SQ_DEBUG_TP_FSM) +XE_GPU_REGISTER(0x0DB1, kDword, SQ_DEBUG_FSM_ALU_0) +XE_GPU_REGISTER(0x0DB2, kDword, SQ_DEBUG_FSM_ALU_1) +XE_GPU_REGISTER(0x0DB3, kDword, SQ_DEBUG_EXP_ALLOC) +XE_GPU_REGISTER(0x0DB4, kDword, SQ_DEBUG_PTR_BUFF) +XE_GPU_REGISTER(0x0DB5, kDword, SQ_DEBUG_GPR_VTX) +XE_GPU_REGISTER(0x0DB6, kDword, SQ_DEBUG_GPR_PIX) +XE_GPU_REGISTER(0x0DB7, kDword, SQ_DEBUG_TB_STATUS_SEL) +XE_GPU_REGISTER(0x0DB8, kDword, SQ_DEBUG_VTX_TB_0) +XE_GPU_REGISTER(0x0DB9, kDword, SQ_DEBUG_VTX_TB_1) +XE_GPU_REGISTER(0x0DBA, kDword, SQ_DEBUG_VTX_TB_STATUS_REG) +XE_GPU_REGISTER(0x0DBB, kDword, SQ_DEBUG_VTX_TB_STATE_MEM) +XE_GPU_REGISTER(0x0DBC, kDword, SQ_DEBUG_PIX_TB_0) +XE_GPU_REGISTER(0x0DBD, kDword, SQ_DEBUG_PIX_TB_STATUS_REG_0) +XE_GPU_REGISTER(0x0DBE, kDword, SQ_DEBUG_PIX_TB_STATUS_REG_1) +XE_GPU_REGISTER(0x0DBF, kDword, SQ_DEBUG_PIX_TB_STATUS_REG_2) +XE_GPU_REGISTER(0x0DC0, kDword, SQ_DEBUG_PIX_TB_STATUS_REG_3) +XE_GPU_REGISTER(0x0DC1, kDword, SQ_DEBUG_PIX_TB_STATE_MEM) +XE_GPU_REGISTER(0x0DD5, kDword, SX_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x0DD6, kDword, SX_PERFCOUNTER2_SELECT) +XE_GPU_REGISTER(0x0DD7, kDword, SX_PERFCOUNTER3_SELECT) +XE_GPU_REGISTER(0x0DDA, kDword, SX_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x0DDB, kDword, SX_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x0DDC, kDword, SX_PERFCOUNTER2_LOW) +XE_GPU_REGISTER(0x0DDD, kDword, SX_PERFCOUNTER2_HI) +XE_GPU_REGISTER(0x0DDE, kDword, SX_PERFCOUNTER3_LOW) +XE_GPU_REGISTER(0x0DDF, kDword, SX_PERFCOUNTER3_HI) +XE_GPU_REGISTER(0x0E01, kDword, TP_DEBUG0) +XE_GPU_REGISTER(0x0E02, kDword, TCR_CHICKEN) +XE_GPU_REGISTER(0x0E03, kDword, TCF_CHICKEN) +XE_GPU_REGISTER(0x0E04, kDword, TCM_CHICKEN) +XE_GPU_REGISTER(0x0E17, kDword, TP_TC_CLKGATE_CNTL) +XE_GPU_REGISTER(0x0E18, kDword, TPC_CNTL_STATUS) +XE_GPU_REGISTER(0x0E19, kDword, TPC_DEBUG0) +XE_GPU_REGISTER(0x0E1A, kDword, TPC_DEBUG1) +XE_GPU_REGISTER(0x0E1B, kDword, TPC_CHICKEN) +XE_GPU_REGISTER(0x0E1C, kDword, TP0_CNTL_STATUS) +XE_GPU_REGISTER(0x0E1D, kDword, TP0_DEBUG) +XE_GPU_REGISTER(0x0E1E, kDword, TP0_CHICKEN) +XE_GPU_REGISTER(0x0E25, kDword, TP1_CNTL_STATUS) +XE_GPU_REGISTER(0x0E26, kDword, TP1_DEBUG) +XE_GPU_REGISTER(0x0E27, kDword, TP1_CHICKEN) +XE_GPU_REGISTER(0x0E2E, kDword, TP2_CNTL_STATUS) +XE_GPU_REGISTER(0x0E2F, kDword, TP2_DEBUG) +XE_GPU_REGISTER(0x0E30, kDword, TP2_CHICKEN) +XE_GPU_REGISTER(0x0E37, kDword, TP3_CNTL_STATUS) +XE_GPU_REGISTER(0x0E38, kDword, TP3_DEBUG) +XE_GPU_REGISTER(0x0E39, kDword, TP3_CHICKEN) +XE_GPU_REGISTER(0x0E41, kDword, VC_CNTL_STATUS) +XE_GPU_REGISTER(0x0E43, kDword, VC_DEBUG_CNTL) +XE_GPU_REGISTER(0x0E44, kDword, VC_DEBUG_DATA) +XE_GPU_REGISTER(0x0E45, kDword, VC_ENHANCE) +XE_GPU_REGISTER(0x0F10, kDword, RB_ZPASS_SAMPLES) +XE_GPU_REGISTER(0x0F11, kDword, RB_ZFAIL_SAMPLES) +XE_GPU_REGISTER(0x0F12, kDword, RB_SFAIL_SAMPLES) +XE_GPU_REGISTER(0x0F15, kDword, BC_DUMMY_CRAYRB_ENUMS) +XE_GPU_REGISTER(0x0F16, kDword, BC_DUMMY_CRAYRB_MOREENUMS) +XE_GPU_REGISTER(0x0F26, kDword, RB_DEBUG_CNTL) +XE_GPU_REGISTER(0x0F27, kDword, RB_DEBUG_DATA) +XE_GPU_REGISTER(0x0F28, kDword, RB_DEBUG_0) +XE_GPU_REGISTER(0x0F29, kDword, RB_DEBUG_1) +XE_GPU_REGISTER(0x0F2A, kDword, RB_DEBUG_2) +XE_GPU_REGISTER(0x0F2B, kDword, RB_FLAG_CONTROL) +XE_GPU_REGISTER(0x0F2C, kDword, RB_BC_SPARES) +XE_GPU_REGISTER(0x1800, kDword, D1CRTC_H_TOTAL) +XE_GPU_REGISTER(0x1801, kDword, D1CRTC_H_BLANK_START_END) +XE_GPU_REGISTER(0x1802, kDword, D1CRTC_H_SYNC_A) +XE_GPU_REGISTER(0x1803, kDword, D1CRTC_H_SYNC_A_CNTL) +XE_GPU_REGISTER(0x1804, kDword, D1CRTC_V_TOTAL) +XE_GPU_REGISTER(0x1805, kDword, D1CRTC_V_BLANK_START_END) +XE_GPU_REGISTER(0x1806, kDword, D1CRTC_V_SYNC_A) +XE_GPU_REGISTER(0x1807, kDword, D1CRTC_V_SYNC_A_CNTL) +XE_GPU_REGISTER(0x1808, kDword, D1CRTC_FORCE_COUNT_NOW_CNTL) +XE_GPU_REGISTER(0x1809, kDword, D1CRTC_PIXEL_DATA_READBACK) +XE_GPU_REGISTER(0x180A, kDword, D1CRTC_CONTROL) +XE_GPU_REGISTER(0x180B, kDword, D1CRTC_BLANK_CONTROL) +XE_GPU_REGISTER(0x180C, kDword, D1CRTC_INTERLACE_CONTROL) +XE_GPU_REGISTER(0x180D, kDword, D1CRTC_INTERLACE_STATUS) +XE_GPU_REGISTER(0x180E, kDword, D1CRTC_BLANK_DATA_COLOR) +XE_GPU_REGISTER(0x180F, kDword, D1CRTC_OVERSCAN_COLOR) +XE_GPU_REGISTER(0x1810, kDword, D1CRTC_BLACK_COLOR) +XE_GPU_REGISTER(0x1811, kDword, D1CRTC_OVERSCAN_TOP) +XE_GPU_REGISTER(0x1812, kDword, D1CRTC_OVERSCAN_BOTTOM) +XE_GPU_REGISTER(0x1813, kDword, D1CRTC_OVERSCAN_LEFT) +XE_GPU_REGISTER(0x1814, kDword, D1CRTC_OVERSCAN_RIGHT) +XE_GPU_REGISTER(0x1815, kDword, D1CRTC_STATUS) +XE_GPU_REGISTER(0x1816, kDword, D1CRTC_STATUS_POSITION) +XE_GPU_REGISTER(0x1817, kDword, D1CRTC_FRAME_COUNT_CONTROL) +XE_GPU_REGISTER(0x1818, kDword, D1CRTC_STATUS_FRAME_COUNT) +XE_GPU_REGISTER(0x1819, kDword, D1CRTC_STATUS_VF_COUNT) +XE_GPU_REGISTER(0x181A, kDword, D1CRTC_STATUS_HV_COUNT) +XE_GPU_REGISTER(0x181B, kDword, D1CRTC_FRAME_COUNT_START) +XE_GPU_REGISTER(0x181C, kDword, D1CRTC_COUNT_CONTROL) +XE_GPU_REGISTER(0x181D, kDword, D1CRTC_STEREO_STATUS) +XE_GPU_REGISTER(0x181E, kDword, D1CRTC_STEREO_CONTROL) +XE_GPU_REGISTER(0x181F, kDword, D1CRTC_FRAME_RESET_CONTRO) +XE_GPU_REGISTER(0x1839, kDword, D1MODE_MASTER_UPDATE_MODE) +XE_GPU_REGISTER(0x183A, kDword, D1CRTC_UPDATE_LOCK) +XE_GPU_REGISTER(0x183B, kDword, D1CRTC_DOUBLE_BUFFER_CONTROL) +XE_GPU_REGISTER(0x183C, kDword, CRTC_DEBUG) +XE_GPU_REGISTER(0x1840, kDword, D1GRPH_ENABLE) +XE_GPU_REGISTER(0x1842, kDword, D1GRPH_LUT_10BIT_BYPASS_CNTL) +XE_GPU_REGISTER(0x1843, kDword, D1GRPH_LUT_AFTER_CSC) +XE_GPU_REGISTER(0x1846, kDword, D1GRPH_SECONDARY_SURFACE_ADDRESS) +XE_GPU_REGISTER(0x1848, kDword, D1GRPH_PITCH) +XE_GPU_REGISTER(0x1849, kDword, D1GRPH_SURFACE_OFFSET_X) +XE_GPU_REGISTER(0x184A, kDword, D1GRPH_SURFACE_OFFSET_Y) +XE_GPU_REGISTER(0x184B, kDword, D1GRPH_X_START) +XE_GPU_REGISTER(0x184C, kDword, D1GRPH_Y_START) +XE_GPU_REGISTER(0x184D, kDword, D1GRPH_X_END) +XE_GPU_REGISTER(0x184E, kDword, D1GRPH_Y_END) +XE_GPU_REGISTER(0x184F, kDword, D1COLOR_SUBSAMPLE_CRCB_CNTL) +XE_GPU_REGISTER(0x1851, kDword, D1GRPH_UPDATE) +XE_GPU_REGISTER(0x1860, kDword, D1OVL_ENABLE) +XE_GPU_REGISTER(0x1861, kDword, D1OVL_CONTROL1) +XE_GPU_REGISTER(0x1864, kDword, D1OVL_SURFACE_ADDRESS) +XE_GPU_REGISTER(0x1866, kDword, D1OVL_PITCH) +XE_GPU_REGISTER(0x1867, kDword, D1OVL_SURFACE_OFFSET_X) +XE_GPU_REGISTER(0x1868, kDword, D1OVL_SURFACE_OFFSET_Y) +XE_GPU_REGISTER(0x1869, kDword, D1OVL_START) +XE_GPU_REGISTER(0x186A, kDword, D1OVL_END) +XE_GPU_REGISTER(0x186B, kDword, D1OVL_UPDATE) +XE_GPU_REGISTER(0x18C1, kDword, D1OVL_ALPHA_OUTSIDE_OVL_WINDOW) +XE_GPU_REGISTER(0x18C2, kDword, D1OVL_ALPHA_INSIDE_OVL_WINDOW) +XE_GPU_REGISTER(0x18C3, kDword, D1OVL_ALPHA_CONTROL) +XE_GPU_REGISTER(0x18E0, kDword, D1GRPH_COLOR_MATRIX_CNTL) +XE_GPU_REGISTER(0x18E1, kDword, D1GRPH_COLOR_MATRIX_COEF_1_1) +XE_GPU_REGISTER(0x18E2, kDword, D1GRPH_COLOR_MATRIX_COEF_1_2) +XE_GPU_REGISTER(0x18E3, kDword, D1GRPH_COLOR_MATRIX_COEF_1_3) +XE_GPU_REGISTER(0x18E4, kDword, D1GRPH_COLOR_MATRIX_COEF_1_4) +XE_GPU_REGISTER(0x18E5, kDword, D1GRPH_COLOR_MATRIX_COEF_2_1) +XE_GPU_REGISTER(0x18E6, kDword, D1GRPH_COLOR_MATRIX_COEF_2_2) +XE_GPU_REGISTER(0x18E7, kDword, D1GRPH_COLOR_MATRIX_COEF_2_3) +XE_GPU_REGISTER(0x18E8, kDword, D1GRPH_COLOR_MATRIX_COEF_2_4) +XE_GPU_REGISTER(0x18E9, kDword, D1GRPH_COLOR_MATRIX_COEF_3_1) +XE_GPU_REGISTER(0x18EA, kDword, D1GRPH_COLOR_MATRIX_COEF_3_2) +XE_GPU_REGISTER(0x18EB, kDword, D1GRPH_COLOR_MATRIX_COEF_3_3) +XE_GPU_REGISTER(0x18EC, kDword, D1GRPH_COLOR_MATRIX_COEF_3_4) +XE_GPU_REGISTER(0x1931, kDword, DC_LUTA_BLACK_OFFSET_BLUE) +XE_GPU_REGISTER(0x1932, kDword, DC_LUTA_BLACK_OFFSET_GREEN) +XE_GPU_REGISTER(0x1933, kDword, DC_LUTA_BLACK_OFFSET_RED) +XE_GPU_REGISTER(0x1934, kDword, DC_LUTA_WHITE_OFFSET_BLUE) +XE_GPU_REGISTER(0x1935, kDword, DC_LUTA_WHITE_OFFSET_GREEN) +XE_GPU_REGISTER(0x1936, kDword, DC_LUTA_WHITE_OFFSET_RED) +XE_GPU_REGISTER(0x1949, kDword, D1MODE_UNDERFLOW_STATUS) +XE_GPU_REGISTER(0x194A, kDword, D1MODE_DATA_FORMAT) +XE_GPU_REGISTER(0x194B, kDword, D1MODE_DESKTOP_HEIGHT) +XE_GPU_REGISTER(0x194C, kDword, D1MODE_V_COUNTER) +XE_GPU_REGISTER(0x194D, kDword, D1MODE_VBLANK_STATUS) +XE_GPU_REGISTER(0x194E, kDword, D1MODE_VLINE_START_END) +XE_GPU_REGISTER(0x194F, kDword, D1MODE_VLINE_STATUS) +XE_GPU_REGISTER(0x1950, kDword, D1MODE_INT_MASK) +XE_GPU_REGISTER(0x1951, kDword, D1MODE_VBLANK_VLINE_STATUS) +XE_GPU_REGISTER(0x1952, kDword, D1MODE_MAX_CHUNK_SIZE) +XE_GPU_REGISTER(0x1953, kDword, D1MODE_CHUNK_SIZE_DEBUG) +XE_GPU_REGISTER(0x1954, kDword, D1MODE_PRIORITY_A_CNT) +XE_GPU_REGISTER(0x1955, kDword, D1MODE_URGENCY_STAT) +XE_GPU_REGISTER(0x195E, kDword, D1SCL_COEF_RAM_SELECT) +XE_GPU_REGISTER(0x195F, kDword, D1SCL_COEF_RAM_TAP_DATA) +XE_GPU_REGISTER(0x1960, kDword, D1MODE_VIEWPORT_START) +XE_GPU_REGISTER(0x1965, kDword, D1SCL_TAP_CONTROL) +XE_GPU_REGISTER(0x1968, kDword, D1SCL_MANUAL_REPLICATE_CONTROL) +XE_GPU_REGISTER(0x196C, kDword, D1SCL_HORZ_FILTER_CONTROL) +XE_GPU_REGISTER(0x196D, kDword, D1SCL_HORZ_FILTER_SCALE_RATIO) +XE_GPU_REGISTER(0x196E, kDword, D1SCL_HORZ_FILTER_INIT_RGB_LUMA) +XE_GPU_REGISTER(0x196F, kDword, D1SCL_HORZ_FILTER_INIT_CHROMA) +XE_GPU_REGISTER(0x1970, kDword, D1SCL_VERT_FILTER_CONTROL) +XE_GPU_REGISTER(0x1971, kDword, D1SCL_VERT_FILTER_SCALE_RATIO) +XE_GPU_REGISTER(0x1972, kDword, D1SCL_VERT_FILTER_INIT) +XE_GPU_REGISTER(0x1974, kDword, D1SCL_UNDERFLOW_STATUS) +XE_GPU_REGISTER(0x1977, kDword, D1SCL_VERT_FILTER_INIT_BOT) +XE_GPU_REGISTER(0x1978, kDword, D1SCL_COEF_RAM_CONFLICT_STATUS) +XE_GPU_REGISTER(0x1979, kDword, D1SCL_ONE_SHOT_WATERMARK) +XE_GPU_REGISTER(0x197A, kDword, D1MODE_LB_PITCH_IN_WORDS) +XE_GPU_REGISTER(0x198C, kDword, DISP_RBBMIF_RDWR_TIMEOUT) +XE_GPU_REGISTER(0x19BA, kDword, D1SCL_CRC_ENABLE) +XE_GPU_REGISTER(0x19BC, kDword, D1SCL_CRC_SOURCE_SEL) +XE_GPU_REGISTER(0x19BD, kDword, D1SCL_CRC_MAS) +XE_GPU_REGISTER(0x19BE, kDword, D1SCL_CRC_CURRENT) +XE_GPU_REGISTER(0x19BF, kDword, D1SCL_CRC_LAST) +XE_GPU_REGISTER(0x1B20, kDword, DCP_CRC_CONTROL) +XE_GPU_REGISTER(0x1B21, kDword, DCP_CRC_MASK) +XE_GPU_REGISTER(0x1B22, kDword, DCP_CRC_P0_CURRENT) +XE_GPU_REGISTER(0x1B24, kDword, DCP_CRC_P0_LAST) +XE_GPU_REGISTER(0x1B25, kDword, DCP_DEBUG) +XE_GPU_REGISTER(0x1B2E, kDword, DMIF_STATUS) +XE_GPU_REGISTER(0x1B2F, kDword, DCP_LB_DATA_GAP_BETWEEN_CHUNK) +XE_GPU_REGISTER(0x1C46, kDword, DC_LB_MEM_SIZE) +XE_GPU_REGISTER(0x1E40, kDword, XDVO_ENABLE) +XE_GPU_REGISTER(0x1E43, kDword, XDVO_BIT_DEPTH_CONTROL) +XE_GPU_REGISTER(0x1E44, kDword, XDVO_CLOCK_INV) +XE_GPU_REGISTER(0x1E45, kDword, XDVO_CONTROL) +XE_GPU_REGISTER(0x1E46, kDword, XDVO_CRC_EN) +XE_GPU_REGISTER(0x1E47, kDword, XDVO_CRC_CNTL) +XE_GPU_REGISTER(0x1E48, kDword, XDVO_CRC_MASK_SIG_RGB) +XE_GPU_REGISTER(0x1E49, kDword, XDVO_CRC_MASK_SIG_CNTL) +XE_GPU_REGISTER(0x1E4A, kDword, XDVO_CRC_SIG_RGB) +XE_GPU_REGISTER(0x1E4B, kDword, XDVO_CRC_SIG_CNTL) +XE_GPU_REGISTER(0x1E4C, kDword, XDVO_STRENGTH_CONTROL) +XE_GPU_REGISTER(0x1E4D, kDword, XDVO_DATA_STRENGTH_CONTROL) +XE_GPU_REGISTER(0x1E4F, kDword, XDVO_FORCE_DATA) +XE_GPU_REGISTER(0x1E50, kDword, XDVO_2ND_CRC_EN) +XE_GPU_REGISTER(0x1E51, kDword, XDVO_2ND_CRC_CNTL) +XE_GPU_REGISTER(0x1E52, kDword, XDVO_2ND_CRC_MASK_SIG) +XE_GPU_REGISTER(0x1E53, kDword, XDVO_2ND_CRC_SIG) +XE_GPU_REGISTER(0x1E54, kDword, XDVO_REGISTER_INDEX) +XE_GPU_REGISTER(0x1E55, kDword, XDVO_REGISTER_DATA) +XE_GPU_REGISTER(0x1F98, kDword, DC_GPIO_XDVODATA_MASK) +XE_GPU_REGISTER(0x1F99, kDword, DC_GPIO_XDVODATA_A) +XE_GPU_REGISTER(0x1F9A, kDword, DC_GPIO_XDVODATA_EN) +XE_GPU_REGISTER(0x1F9B, kDword, DC_GPIO_XDVODATA_Y) +XE_GPU_REGISTER(0x1F9C, kDword, DC_HSYNC_DEBUG_TEST) +XE_GPU_REGISTER(0x1FB4, kDword, CAPTURE_START_STATUS) +XE_GPU_REGISTER(0x1FB7, kDword, DISP_INTERRUPT_STATUS) +XE_GPU_REGISTER(0x1FB8, kDword, DOUT_DEBUG) +XE_GPU_REGISTER(0x1FC0, kDword, DO_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x1FC1, kDword, DO_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x1FC2, kDword, DO_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x1FC3, kDword, DO_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x1FC4, kDword, DO_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x1FC5, kDword, DO_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x1FC8, kDword, DC_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x1FC9, kDword, DC_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x1FCA, kDword, DC_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x1FCB, kDword, DC_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x1FCC, kDword, DC_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x1FCD, kDword, DC_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x1FCE, kDword, DC_PERFMON_CNTL) +XE_GPU_REGISTER(0x1FD0, kDword, DC_DOUT_DEBUG_MUX_CNTL) +XE_GPU_REGISTER(0x1FE6, kDword, DC_TEST_DEBUG_BUS_CLK1_SEL) +XE_GPU_REGISTER(0x1FE7, kDword, DC_TEST_DEBUG_OUT_PIN_MASK) +XE_GPU_REGISTER(0x1FE8, kDword, DC_TEST_DEBUG_TRIGGER_CNTL) +XE_GPU_REGISTER(0x1FE9, kDword, DC_TEST_DEBUG_TRIGGER_STAT) +XE_GPU_REGISTER(0x1FEA, kDword, DC_TEST_DEBUG_EDGE_TRIGGER_MASK) +XE_GPU_REGISTER(0x1FEB, kDword, DC_TEST_DEBUG_EDGE_TRIGGER_PATTERN) +XE_GPU_REGISTER(0x1FEC, kDword, DC_TEST_DEBUG_DATA_TRIGGER_MASK) +XE_GPU_REGISTER(0x1FED, kDword, DC_TEST_DEBUG_DATA_TRIGGER_PATTERN) +XE_GPU_REGISTER(0x1FEE, kDword, DC_TEST_DEBUG_OUT_TEST_DATA) +XE_GPU_REGISTER(0x1FEF, kDword, DC_TEST_DEBUG_OUT_CNTL) +XE_GPU_REGISTER(0x1FF2, kDword, DO_TEST_DEBUG_BUS_CLK1_SEL) +XE_GPU_REGISTER(0x1FF3, kDword, DO_TEST_DEBUG_OUT_PIN_MASK) +XE_GPU_REGISTER(0x1FF4, kDword, DO_TEST_DEBUG_TRIGGER_CNTL) +XE_GPU_REGISTER(0x1FF5, kDword, DO_TEST_DEBUG_TRIGGER_STAT) +XE_GPU_REGISTER(0x1FF6, kDword, DO_TEST_DEBUG_EDGE_TRIGGER_MASK) +XE_GPU_REGISTER(0x1FF7, kDword, DO_TEST_DEBUG_EDGE_TRIGGER_PATTERN) +XE_GPU_REGISTER(0x1FF8, kDword, DO_TEST_DEBUG_DATA_TRIGGER_MASK) +XE_GPU_REGISTER(0x1FF9, kDword, DO_TEST_DEBUG_DATA_TRIGGER_PATTERN) +XE_GPU_REGISTER(0x1FFA, kDword, DO_TEST_DEBUG_OUT_TEST_DATA) +XE_GPU_REGISTER(0x1FFB, kDword, DO_TEST_DEBUG_OUT_CNTL) +XE_GPU_REGISTER(0x1FFC, kDword, DC_TEST_DEBUG_INDEX) +XE_GPU_REGISTER(0x1FFD, kDword, DC_TEST_DEBUG_DATA) +XE_GPU_REGISTER(0x1FFE, kDword, DO_TEST_DEBUG_INDEX) +XE_GPU_REGISTER(0x1FFF, kDword, DO_TEST_DEBUG_DATA) +XE_GPU_REGISTER(0x2083, kDword, PA_SC_CLIPRECT_RULE) +XE_GPU_REGISTER(0x2084, kDword, PA_SC_CLIPRECT_0_TL) +XE_GPU_REGISTER(0x2085, kDword, PA_SC_CLIPRECT_0_BR) +XE_GPU_REGISTER(0x2086, kDword, PA_SC_CLIPRECT_1_TL) +XE_GPU_REGISTER(0x2087, kDword, PA_SC_CLIPRECT_1_BR) +XE_GPU_REGISTER(0x2088, kDword, PA_SC_CLIPRECT_2_TL) +XE_GPU_REGISTER(0x2089, kDword, PA_SC_CLIPRECT_2_BR) +XE_GPU_REGISTER(0x208A, kDword, PA_SC_CLIPRECT_3_TL) +XE_GPU_REGISTER(0x208B, kDword, PA_SC_CLIPRECT_3_BR) +XE_GPU_REGISTER(0x21F4, kDword, GFX_COPY_STATE) +XE_GPU_REGISTER(0x21F5, kDword, SQ_CF_RD_BASE) +XE_GPU_REGISTER(0x21F6, kDword, SQ_PS_PROGRAM) +XE_GPU_REGISTER(0x21F7, kDword, SQ_VS_PROGRAM) +XE_GPU_REGISTER(0x2210, kDword, GRAS_CONTROL) +XE_GPU_REGISTER(0x2326, kFloat, RB_COLOR_DEST_MASK) +XE_GPU_REGISTER(0x2340, kFloat, GRAS_UCP0X) +XE_GPU_REGISTER(0x2357, kFloat, GRAS_UCP5W) +XE_GPU_REGISTER(0x2360, kFloat, GRAS_UCP_ENABLED) diff --git a/include/rex/graphics/registers.h b/include/rex/graphics/registers.h new file mode 100644 index 0000000..d80489e --- /dev/null +++ b/include/rex/graphics/registers.h @@ -0,0 +1,965 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +#include +#include + +// Most 3D registers are the same as in the Qualcomm Adreno 200 (AMD Z430, +// another R400 architecture family chip): +// +// https://github.com/UDOOboard/Kernel_Unico/blob/master/drivers/mxc/amd-gpu/include/reg/yamato/10/yamato_registers.h +// https://github.com/freedreno/amd-gpu/blob/master/include/reg/yamato/10/yamato_registers.h +// +// https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/freedreno/registers/adreno/a2xx.xml +// +// The Adreno 200, however, has various differences in its registers (primarily +// in the render backend, but not limited to that). Before adding the +// definitions from the Adreno 200, see the actual values of those registers set +// by games, and/or test them on the Xenos hardware. +// +// Other useful sources are the register references for later ATI/AMD 3D chips, +// most importantly the R600 - while it has a massive amount of differences, +// it's the closest relative of the R400 architecture that is available on the +// PC. Documentation for newer AMD GPUs, such as Evergreen, Northern Islands, +// and even GCN also can provide details in some cases. The earlier ATI's +// architecture, R3xx/R5xx, has very differently structured registers (although +// some are still very similar), but can provide some historical context. +// +// Display controller register addresses mostly match the M56 ones: +// https://www.x.org/docs/AMD/old/RRG-216M56-03oOEM.pdf + +// All unused bits are intentionally declared as named fields for stable +// comparisons when register values are constructed or modified by Xenia itself. + +// Only 32-bit types (uint32_t, int32_t, float or enums with uint32_t / int32_t +// as the underlying type) are allowed in the bit fields here, as Visual C++ +// restarts packing when a field requires different alignment than the previous +// one. + +namespace rex::graphics { + +enum Register { +#define XE_GPU_REGISTER(index, type, name) XE_GPU_REG_##name = index, +#include +#undef XE_GPU_REGISTER +}; + +namespace reg { + +/******************************************************************************* + ___ ___ _ _ _____ ___ ___ _ + / __/ _ \| \| |_ _| _ \/ _ \| | + | (_| (_) | .` | | | | / (_) | |__ + \___\___/|_|\_| |_| |_|_\\___/|____| + +*******************************************************************************/ + +union alignas(uint32_t) COHER_STATUS_HOST { + uint32_t value; + struct { + uint32_t matching_contexts : 8; // +0 + uint32_t rb_copy_dest_base_ena : 1; // +8 + uint32_t dest_base_0_ena : 1; // +9 + uint32_t dest_base_1_ena : 1; // +10 + uint32_t dest_base_2_ena : 1; // +11 + uint32_t dest_base_3_ena : 1; // +12 + uint32_t dest_base_4_ena : 1; // +13 + uint32_t dest_base_5_ena : 1; // +14 + uint32_t dest_base_6_ena : 1; // +15 + uint32_t dest_base_7_ena : 1; // +16 + uint32_t _pad_17 : 7; // +17 + uint32_t vc_action_ena : 1; // +24 + uint32_t tc_action_ena : 1; // +25 + uint32_t pglb_action_ena : 1; // +26 + uint32_t _pad_27 : 4; // +27 + uint32_t status : 1; // +31 + }; + static constexpr Register register_index = XE_GPU_REG_COHER_STATUS_HOST; +}; +static_assert_size(COHER_STATUS_HOST, sizeof(uint32_t)); + +union alignas(uint32_t) WAIT_UNTIL { + uint32_t value; + struct { + uint32_t _pad_0 : 1; // +0 + uint32_t wait_re_vsync : 1; // +1 + uint32_t wait_fe_vsync : 1; // +2 + uint32_t wait_vsync : 1; // +3 + uint32_t wait_dsply_id0 : 1; // +4 + uint32_t wait_dsply_id1 : 1; // +5 + uint32_t wait_dsply_id2 : 1; // +6 + uint32_t _pad_7 : 3; // +7 + uint32_t wait_cmdfifo : 1; // +10 + uint32_t _pad_11 : 3; // +11 + uint32_t wait_2d_idle : 1; // +14 + uint32_t wait_3d_idle : 1; // +15 + uint32_t wait_2d_idleclean : 1; // +16 + uint32_t wait_3d_idleclean : 1; // +17 + uint32_t _pad_18 : 2; // +18 + uint32_t cmdfifo_entries : 4; // +20 + uint32_t _pad_24 : 8; // +24 + }; + static constexpr Register register_index = XE_GPU_REG_WAIT_UNTIL; +}; +static_assert_size(WAIT_UNTIL, sizeof(uint32_t)); + +/******************************************************************************* + ___ ___ ___ _ _ ___ _ _ ___ ___ ___ + / __| __/ _ \| | | | __| \| |/ __| __| _ \ + \__ \ _| (_) | |_| | _|| .` | (__| _|| / + |___/___\__\_\\___/|___|_|\_|\___|___|_|_\ + +*******************************************************************************/ + +union alignas(uint32_t) SQ_PROGRAM_CNTL { + uint32_t value; + struct { + // GPR counts minus 1. + // Ignore the Freedreno a2xx.xml note about the bit 7 for zero registers, + // the fields are 6-bit, not 8-bit, in yamato_registers.h, and games never + // set the bits 7:6. + uint32_t vs_num_reg : 6; // +0, value minus 1 + uint32_t _pad_6 : 2; // +6 + uint32_t ps_num_reg : 6; // +8, value minus 1 + uint32_t _pad_14 : 2; // +14 + uint32_t vs_resource : 1; // +16 + uint32_t ps_resource : 1; // +17 + uint32_t param_gen : 1; // +18 + uint32_t gen_index_pix : 1; // +19 + // Interpolator output count minus 1. + uint32_t vs_export_count : 4; // +20, value minus 1 + xenos::VertexShaderExportMode vs_export_mode : 3; // +24 + uint32_t ps_export_mode : 4; // +27 + uint32_t gen_index_vtx : 1; // +31 + }; + static constexpr Register register_index = XE_GPU_REG_SQ_PROGRAM_CNTL; +}; +static_assert_size(SQ_PROGRAM_CNTL, sizeof(uint32_t)); + +union alignas(uint32_t) SQ_CONTEXT_MISC { + uint32_t value; + struct { + uint32_t inst_pred_optimize : 1; // +0 + uint32_t sc_output_screen_xy : 1; // +1 + xenos::SampleControl sc_sample_cntl : 2; // +2 + uint32_t _pad_4 : 4; // +4 + // Pixel shader interpolator (according to the XNA microcode validator - + // limited to the interpolator count, 16, not the total register count of + // 64) index to write pixel parameters to. + // See https://portal.unifiedpatents.com/ptab/case/IPR2015-00325 Exhibit + // 2039 R400 Sequencer Specification 2.11 (a significantly early version of + // the specification, however) section 19.2 "Sprites/ XY screen coordinates/ + // FB information" for additional details. + // * |XY| - position on screen (vPos - the XNA assembler translates ps_3_0 + // vPos directly to this, so at least in Direct3D 9 pixel center mode, + // this contains 0, 1, 2, not 0.5, 1.5, 2.5). flto also said in the + // Freedreno IRC that it's .0 even in OpenGL: + // https://dri.freedesktop.org/~cbrill/dri-log/?channel=freedreno&date=2020-04-19 + // According to the actual usage, in the final version of the hardware, + // the screen coordinates are passed to the shader directly as floats + // (contrary to what's written in the early 2.11 version of the sequencer + // specification from IPR2015-00325, where the coordinates are specified + // to be 2^23-biased, essentially packed as integers in the low mantissa + // bits of 2^23). + // * On Android, according to LG P705 - checked on the driver V@6.0 AU@ + // (CL@3050818) - GL_OES_get_program_binary disassembly, gl_FragCoord.xy + // is |r0.xy| * c221.xy + c222.zw. Though we haven't yet been able to + // dump the actual constant values by exploiting a huge uniform array, + // but flto says c222.zw contains tile offset plus 0.5. It also appears + // that the multiplication by c221.xy is done to flip the direction of + // the Y axis in gl_FragCoord (c221.y is probably -1). According to the + // tests performed with triangles and point sprites, the hardware uses + // the top-left rasterization rule just like Direct3D (tie-breaking + // sample coverage towards gl_FragCoord.-x+y, while Direct3D tie-breaks + // towards VPOS.-x-y), and the R400 / Z430 doesn't seem to have the + // equivalent of R5xx's SC_EDGERULE register for configuring this). + // Also, both OpenGL and apparently Direct3D 9 define the point sprite V + // coordinate to be 0 in the top, and 1 in the bottom (but OpenGL + // gl_FragCoord.y is towards the top, while Direct3D 9's VPOS.y is + // towards the bottom), gl_PointCoord.y is |PsParamGen.w| directly, and + // the R400 / Z430 doesn't appear to have an equivalent of R6xx's + // SPI_INTERP_CONTROL_0::PNT_SPRITE_TOP_1 for toggling the direction. + // So, it looks like the internal screen coordinates in the official + // OpenGL ES 2.0 driver are still top-to-bottom like in Direct3D, but + // gl_FragCoord.y is flipped in the shader code so it's bottom-to-top + // as OpenGL specifies. + // https://docs.microsoft.com/en-us/windows/win32/direct3d9/point-sprites + // * |ZW| - UV within a point sprite, [0, 1]. In OpenGL ES 2.0, this is + // interpreted directly as gl_PointCoord, with the directions matching the + // OpenGL ES 2.0 specification - 0 in the top (towards +gl_FragCoord.y in + // OpenGL ES bottom-to-top screen coordinates - but towards -PsParamGen.y + // likely, see the explanation of gl_FragCoord.xy above), 1 in the bottom + // (towards -gl_FragCoord.y, or +PsParamGen.y likely). The point sprite + // coordinates are exposed differently on the Xbox 360 and the PC + // Direct3D 9 - the Xbox 360 passes the whole PsParamGen register via the + // SPRITETEXCOORD input semantic directly (unlike on the PC, where point + // sprite coordinates are written to XY of TEXCOORD0), and shaders should + // take abs(SPRITETEXCOORD.zw) explicitly. + // https://shawnhargreaves.com/blog/point-sprites-on-xbox.html + // 4D5307F1 has snowflake point sprites with an asymmetric texture. + // * For non-point primitives, according to LG P705, this may be the IJ + // barycentric coordinates, however, it's not yet known how intentional, + // well-defined and reliable this behavior is, and whether any game uses + // it on purpose. Also, the mapping between the vertex indices and the + // order of these coordinates seems to vary possibly depending on the + // positions of the vertices relative to each other even when the + // winding order stays the same. It's also unknown what effect the + // provoking vertex convention has on the order. + // TODO(Triang3l): Research the order, as well as the sampling location, of + // PsParamGen.zw, the behavior (whether they're extrapolated) when the + // center of the pixel is not covered, on the real hardware. + // * Sign bit of X - is front face (according to the disassembly of vFace + // and gl_FrontFacing usage), non-negative for front face, negative for + // back face (used with `rcpc` in shaders to take signedness of 0 into + // account in `cndge`). + // * Sign bit of Y - is the primitive type a point (according to the + // IPR2015-00325 sequencer specification), negative for a point, + // non-negative for other primitive types. + // * Sign bit of Z - is the primitive type a line (according to the + // IPR2015-00325 sequencer specification), negative for a line, + // non-negative for other primitive types. + uint32_t param_gen_pos : 8; // +8 + uint32_t perfcounter_ref : 1; // +16 + uint32_t yield_optimize : 1; // +17 + uint32_t tx_cache_sel : 1; // +18 + uint32_t _pad_19 : 13; // +19 + }; + static constexpr Register register_index = XE_GPU_REG_SQ_CONTEXT_MISC; +}; +static_assert_size(SQ_CONTEXT_MISC, sizeof(uint32_t)); + +union alignas(uint32_t) SQ_INTERPOLATOR_CNTL { + uint32_t value; + struct { + uint32_t param_shade : 16; // +0 + // SampleLocation bits - 0 for centroid, 1 for center, if + // SQ_CONTEXT_MISC::sc_sample_cntl is kCentroidsAndCenters. + uint32_t sampling_pattern : 16; // +16 + }; + static constexpr Register register_index = XE_GPU_REG_SQ_INTERPOLATOR_CNTL; +}; +static_assert_size(SQ_INTERPOLATOR_CNTL, sizeof(uint32_t)); + +union alignas(uint32_t) SQ_VS_CONST { + uint32_t value; + struct { + uint32_t base : 9; // +0 + uint32_t _pad_9 : 3; // +9 + // Vec4 count minus one. + uint32_t size : 9; // +12, value minus 1 + uint32_t _pad_21 : 11; // +21 + }; + static constexpr Register register_index = XE_GPU_REG_SQ_VS_CONST; +}; +static_assert_size(SQ_VS_CONST, sizeof(uint32_t)); + +// Same as SQ_VS_CONST. +union alignas(uint32_t) SQ_PS_CONST { + uint32_t value; + struct { + uint32_t base : 9; // +0 + uint32_t _pad_9 : 3; // +9 + // Vec4 count minus one. + uint32_t size : 9; // +12, value minus 1 + uint32_t _pad_21 : 11; // +21 + }; + static constexpr Register register_index = XE_GPU_REG_SQ_PS_CONST; +}; +static_assert_size(SQ_PS_CONST, sizeof(uint32_t)); + +/******************************************************************************* + __ _____ ___ _____ _____ __ + \ \ / / __| _ \_ _| __\ \/ / + \ V /| _|| / | | | _| > < + \_/ |___|_|_\ |_| |___/_/\_\ + + ___ ___ ___ _ _ ___ ___ ___ _ _ _ ___ + / __| _ \/ _ \| | | | _ \ __| _ \ /_\ | \| | \ + | (_ | / (_) | |_| | _/ _|| / / _ \| .` | |) | + \___|_|_\\___/ \___/|_| |___|_|_\ /_/ \_\_|\_|___/ + + _____ ___ ___ ___ ___ _ _ _ _____ ___ ___ + |_ _| __/ __/ __| __| | | | /_\_ _/ _ \| _ \ + | | | _|\__ \__ \ _|| |__| |__ / _ \| || (_) | / + |_| |___|___/___/___|____|____/_/ \_\_| \___/|_|_\ + +*******************************************************************************/ + +union alignas(uint32_t) VGT_DMA_SIZE { + uint32_t value; + struct { + uint32_t num_words : 24; // +0 + uint32_t _pad_24 : 6; // +24 + xenos::Endian swap_mode : 2; // +30 + }; + static constexpr Register register_index = XE_GPU_REG_VGT_DMA_SIZE; +}; + +union alignas(uint32_t) VGT_DRAW_INITIATOR { + uint32_t value; + // Has differences from the Adreno 200. + struct { + xenos::PrimitiveType prim_type : 6; // +0 + xenos::SourceSelect source_select : 2; // +6 + // Adreno 200 replaced this with FACENESS_CULL_SELECT possibly due to the + // removal of tessellation, but on the Xenos this is MAJOR_MODE like on the + // R600, it's set to the explicit mode mainly for tessellated draws in games + // (because VGT_OUTPUT_PATH_CNTL where tessellation is enabled is ignored in + // the implicit major mode). + xenos::MajorMode major_mode : 2; // +8 + uint32_t _pad_10 : 1; // +10 + xenos::IndexFormat index_size : 1; // +11 + uint32_t not_eop : 1; // +12 + uint32_t _pad_13 : 3; // +13 + uint32_t num_indices : 16; // +16 + }; + static constexpr Register register_index = XE_GPU_REG_VGT_DRAW_INITIATOR; +}; +static_assert_size(VGT_DRAW_INITIATOR, sizeof(uint32_t)); + +// Unlike on R6xx (but closer to R5xx), and according to the Adreno 200 header, +// the registers related to the vertex index are 24-bit. Vertex indices are +// unsigned, and only the lower 24 bits of them are actually used by the GPU - +// this has been verified on an Adreno 200 phone (LG Optimus L7) on OpenGL ES +// using a GL_UNSIGNED_INT element array buffer with junk in the upper 8 bits +// that had no effect on drawing. + +// The order of operations is primitive reset index checking -> offsetting -> +// clamping. + +union alignas(uint32_t) VGT_MULTI_PRIM_IB_RESET_INDX { + uint32_t value; + struct { + // The upper 8 bits of the value from the index buffer are confirmed to be + // ignored. So, though this specifically is untested (because + // GL_PRIMITIVE_RESTART_FIXED_INDEX was added only in OpenGL ES 3.0, though + // it behaves conceptually close to our expectations anyway - uses the + // 0xFFFFFFFF restart index while GL_MAX_ELEMENT_INDEX may be 0xFFFFFF), + // the restart index check likely only involves the lower 24 bit of the + // vertex index - therefore, if reset_indx is 0xFFFFFF, likely 0xFFFFFF, + // 0x1FFFFFF, 0xFFFFFFFF all cause primitive reset. + uint32_t reset_indx : 24; // +0 + uint32_t _pad_24 : 8; // +24 + }; + static constexpr Register register_index = XE_GPU_REG_VGT_MULTI_PRIM_IB_RESET_INDX; +}; +static_assert_size(VGT_MULTI_PRIM_IB_RESET_INDX, sizeof(uint32_t)); + +union alignas(uint32_t) VGT_INDX_OFFSET { + uint32_t value; + struct { + // Unlike R5xx's VAP_INDEX_OFFSET, which is signed 25-bit, this is 24-bit - + // and signedness doesn't matter as index calculations are done in 24-bit + // integers, and ((0xFFFFFE + 3) & 0xFFFFFF) == 1 anyway, just like + // ((0xFFFFFFFE + 3) & 0xFFFFFF) == 1 if we treated it as signed by + // sign-extending on the host. Direct3D 9 just writes BaseVertexIndex as a + // signed int32 to the entire register, but the upper 8 bits are ignored + // anyway, and that has no effect on offsets that fit in 24 bits. + uint32_t indx_offset : 24; // +0 + uint32_t _pad_24 : 8; // +24 + }; + static constexpr Register register_index = XE_GPU_REG_VGT_INDX_OFFSET; +}; +static_assert_size(VGT_INDX_OFFSET, sizeof(uint32_t)); + +union alignas(uint32_t) VGT_MIN_VTX_INDX { + uint32_t value; + struct { + uint32_t min_indx : 24; // +0 + uint32_t _pad_24 : 8; // +24 + }; + static constexpr Register register_index = XE_GPU_REG_VGT_MIN_VTX_INDX; +}; +static_assert_size(VGT_MIN_VTX_INDX, sizeof(uint32_t)); + +union alignas(uint32_t) VGT_MAX_VTX_INDX { + uint32_t value; + struct { + // Usually 0xFFFF or 0xFFFFFF. + uint32_t max_indx : 24; // +0 + uint32_t _pad_24 : 8; // +24 + }; + static constexpr Register register_index = XE_GPU_REG_VGT_MAX_VTX_INDX; +}; +static_assert_size(VGT_MAX_VTX_INDX, sizeof(uint32_t)); + +union alignas(uint32_t) VGT_OUTPUT_PATH_CNTL { + uint32_t value; + struct { + xenos::VGTOutputPath path_select : 2; // +0 + uint32_t _pad_2 : 30; // +2 + }; + static constexpr Register register_index = XE_GPU_REG_VGT_OUTPUT_PATH_CNTL; +}; +static_assert_size(VGT_OUTPUT_PATH_CNTL, sizeof(uint32_t)); + +union alignas(uint32_t) VGT_HOS_CNTL { + uint32_t value; + struct { + xenos::TessellationMode tess_mode : 2; // +0 + uint32_t _pad_2 : 30; // +2 + }; + static constexpr Register register_index = XE_GPU_REG_VGT_HOS_CNTL; +}; +static_assert_size(VGT_HOS_CNTL, sizeof(uint32_t)); + +/******************************************************************************* + ___ ___ ___ __ __ ___ _____ _____ _____ + | _ \ _ \_ _| \/ |_ _|_ _|_ _\ \ / / __| + | _/ /| || |\/| || | | | | | \ V /| _| + |_| |_|_\___|_| |_|___| |_| |___| \_/ |___| + + _ ___ ___ ___ __ __ ___ _ ___ ___ + /_\ / __/ __| __| \/ | _ ) | | __| _ \ + / _ \\__ \__ \ _|| |\/| | _ \ |__| _|| / + /_/ \_\___/___/___|_| |_|___/____|___|_|_\ + +*******************************************************************************/ + +union alignas(uint32_t) PA_SU_POINT_MINMAX { + uint32_t value; + struct { + // For per-vertex size specification, radius (1/2 size), 12.4 fixed point. + uint32_t min_size : 16; // +0 + uint32_t max_size : 16; // +16 + }; + static constexpr Register register_index = XE_GPU_REG_PA_SU_POINT_MINMAX; +}; +static_assert_size(PA_SU_POINT_MINMAX, sizeof(uint32_t)); + +union alignas(uint32_t) PA_SU_POINT_SIZE { + uint32_t value; + struct { + // 1/2 width or height, 12.4 fixed point. + uint32_t height : 16; // +0 + uint32_t width : 16; // +16 + }; + static constexpr Register register_index = XE_GPU_REG_PA_SU_POINT_SIZE; +}; +static_assert_size(PA_SU_POINT_SIZE, sizeof(uint32_t)); + +// Setup Unit / Scanline Converter mode cntl +union alignas(uint32_t) PA_SU_SC_MODE_CNTL { + uint32_t value; + struct { + uint32_t cull_front : 1; // +0 + uint32_t cull_back : 1; // +1 + // 0 - front is CCW, 1 - front is CW. + uint32_t face : 1; // +2 + // 4541096E uses poly_mode 2 for triangles, which is "reserved" on R6xx and + // not defined on Adreno 2xx, but polymode_front/back_ptype are 0 (points) + // in this case in 4541096E, which should not be respected for non-kDualMode + // as the title wants to draw filled triangles. + xenos::PolygonModeEnable poly_mode : 2; // +3 + xenos::PolygonType polymode_front_ptype : 3; // +5 + xenos::PolygonType polymode_back_ptype : 3; // +8 + uint32_t poly_offset_front_enable : 1; // +11 + uint32_t poly_offset_back_enable : 1; // +12 + uint32_t poly_offset_para_enable : 1; // +13 + uint32_t _pad_14 : 1; // +14 + uint32_t msaa_enable : 1; // +15 + uint32_t vtx_window_offset_enable : 1; // +16 + // LINE_STIPPLE_ENABLE was added on Adreno. + uint32_t _pad_17 : 2; // +17 + uint32_t provoking_vtx_last : 1; // +19 + uint32_t persp_corr_dis : 1; // +20 + uint32_t multi_prim_ib_ena : 1; // +21 + uint32_t _pad_22 : 1; // +22 + uint32_t quad_order_enable : 1; // +23 + uint32_t sc_one_quad_per_clock : 1; // +24 + // WAIT_RB_IDLE_ALL_TRI and WAIT_RB_IDLE_FIRST_TRI_NEW_STATE were added on + // Adreno. + uint32_t _pad_25 : 7; // +25 + }; + static constexpr Register register_index = XE_GPU_REG_PA_SU_SC_MODE_CNTL; +}; +static_assert_size(PA_SU_SC_MODE_CNTL, sizeof(uint32_t)); + +// Setup Unit Vertex Control +union alignas(uint32_t) PA_SU_VTX_CNTL { + uint32_t value; + struct { + xenos::PixelCenter pix_center : 1; // +0 + xenos::VertexRounding round_mode : 2; // +1 + xenos::VertexQuantization quant_mode : 3; // +3 + uint32_t _pad_6 : 26; // +6 + }; + static constexpr Register register_index = XE_GPU_REG_PA_SU_VTX_CNTL; +}; +static_assert_size(PA_SU_VTX_CNTL, sizeof(uint32_t)); + +union alignas(uint32_t) PA_SC_MPASS_PS_CNTL { + uint32_t value; + struct { + uint32_t mpass_pix_vec_per_pass : 20; // +0 + uint32_t _pad_20 : 11; // +20 + uint32_t mpass_ps_ena : 1; // +31 + }; + static constexpr Register register_index = XE_GPU_REG_PA_SC_MPASS_PS_CNTL; +}; +static_assert_size(PA_SC_MPASS_PS_CNTL, sizeof(uint32_t)); + +// Scanline converter viz query, used by D3D for gpu side conditional rendering +union alignas(uint32_t) PA_SC_VIZ_QUERY { + uint32_t value; + struct { + // the visibility of draws should be evaluated + uint32_t viz_query_ena : 1; // +0 + uint32_t viz_query_id : 6; // +1 + // discard geometry after test (but use for testing) + uint32_t kill_pix_post_hi_z : 1; // +7 + // not used with d3d + uint32_t kill_pix_post_detail_mask : 1; // +8 + uint32_t _pad_9 : 23; // +9 + }; + static constexpr Register register_index = XE_GPU_REG_PA_SC_VIZ_QUERY; +}; +static_assert_size(PA_SC_VIZ_QUERY, sizeof(uint32_t)); + +// Clipper clip control +union alignas(uint32_t) PA_CL_CLIP_CNTL { + uint32_t value; + struct { + // Like on the Adreno 200, but with user clip planes from R3xx (used in + // 4D5307E6 for the hanging lamp on Last Resort). + uint32_t ucp_ena_0 : 1; // +0 + uint32_t ucp_ena_1 : 1; // +1 + uint32_t ucp_ena_2 : 1; // +2 + uint32_t ucp_ena_3 : 1; // +3 + uint32_t ucp_ena_4 : 1; // +4 + uint32_t ucp_ena_5 : 1; // +5 + uint32_t _pad_6 : 8; // +6 + uint32_t ps_ucp_mode : 2; // +14 + uint32_t clip_disable : 1; // +16 + uint32_t ucp_cull_only_ena : 1; // +17 + uint32_t boundary_edge_flag_ena : 1; // +18 + uint32_t dx_clip_space_def : 1; // +19 + uint32_t dis_clip_err_detect : 1; // +20 + uint32_t vtx_kill_or : 1; // +21 + uint32_t xy_nan_retain : 1; // +22 + uint32_t z_nan_retain : 1; // +23 + uint32_t w_nan_retain : 1; // +24 + uint32_t _pad_25 : 7; // +25 + }; + struct { + uint32_t ucp_ena : 6; + }; + static constexpr Register register_index = XE_GPU_REG_PA_CL_CLIP_CNTL; +}; +static_assert_size(PA_CL_CLIP_CNTL, sizeof(uint32_t)); + +// Viewport transform engine control +union alignas(uint32_t) PA_CL_VTE_CNTL { + uint32_t value; + struct { + uint32_t vport_x_scale_ena : 1; // +0 + uint32_t vport_x_offset_ena : 1; // +1 + uint32_t vport_y_scale_ena : 1; // +2 + uint32_t vport_y_offset_ena : 1; // +3 + uint32_t vport_z_scale_ena : 1; // +4 + uint32_t vport_z_offset_ena : 1; // +5 + uint32_t _pad_6 : 2; // +6 + uint32_t vtx_xy_fmt : 1; // +8 + uint32_t vtx_z_fmt : 1; // +9 + uint32_t vtx_w0_fmt : 1; // +10 + uint32_t perfcounter_ref : 1; // +11 + uint32_t _pad_12 : 20; // +12 + }; + static constexpr Register register_index = XE_GPU_REG_PA_CL_VTE_CNTL; +}; +static_assert_size(PA_CL_VTE_CNTL, sizeof(uint32_t)); + +union alignas(uint32_t) PA_SC_SCREEN_SCISSOR_TL { + uint32_t value; + struct { + int32_t tl_x : 15; // +0 + uint32_t _pad_15 : 1; // +15 + int32_t tl_y : 15; // +16 + uint32_t _pad_31 : 1; // +31 + }; + static constexpr Register register_index = XE_GPU_REG_PA_SC_SCREEN_SCISSOR_TL; +}; +static_assert_size(PA_SC_SCREEN_SCISSOR_TL, sizeof(uint32_t)); + +union alignas(uint32_t) PA_SC_SCREEN_SCISSOR_BR { + uint32_t value; + struct { + int32_t br_x : 15; // +0 + uint32_t _pad_15 : 1; // +15 + int32_t br_y : 15; // +16 + uint32_t _pad_31 : 1; // +31 + }; + static constexpr Register register_index = XE_GPU_REG_PA_SC_SCREEN_SCISSOR_BR; +}; +static_assert_size(PA_SC_SCREEN_SCISSOR_BR, sizeof(uint32_t)); + +union alignas(uint32_t) PA_SC_WINDOW_OFFSET { + uint32_t value; + struct { + int32_t window_x_offset : 15; // +0 + uint32_t _pad_15 : 1; // +15 + int32_t window_y_offset : 15; // +16 + uint32_t _pad_31 : 1; // +31 + }; + static constexpr Register register_index = XE_GPU_REG_PA_SC_WINDOW_OFFSET; +}; +static_assert_size(PA_SC_WINDOW_OFFSET, sizeof(uint32_t)); + +union alignas(uint32_t) PA_SC_WINDOW_SCISSOR_TL { + uint32_t value; + struct { + uint32_t tl_x : 14; // +0 + uint32_t _pad_14 : 2; // +14 + uint32_t tl_y : 14; // +16 + uint32_t _pad_30 : 1; // +30 + uint32_t window_offset_disable : 1; // +31 + }; + static constexpr Register register_index = XE_GPU_REG_PA_SC_WINDOW_SCISSOR_TL; +}; +static_assert_size(PA_SC_WINDOW_SCISSOR_TL, sizeof(uint32_t)); + +union alignas(uint32_t) PA_SC_WINDOW_SCISSOR_BR { + uint32_t value; + struct { + uint32_t br_x : 14; // +0 + uint32_t _pad_14 : 2; // +14 + uint32_t br_y : 14; // +16 + uint32_t _pad_30 : 2; // +30 + }; + static constexpr Register register_index = XE_GPU_REG_PA_SC_WINDOW_SCISSOR_BR; +}; +static_assert_size(PA_SC_WINDOW_SCISSOR_BR, sizeof(uint32_t)); + +/******************************************************************************* + ___ ___ _ _ ___ ___ ___ + | _ \ __| \| | \| __| _ \ + | / _|| .` | |) | _|| / + |_|_\___|_|\_|___/|___|_|_\ + + ___ _ ___ _ _____ _ _ ___ + | _ ) /_\ / __| |/ / __| \| | \ + | _ \/ _ \ (__| ' <| _|| .` | |) | + |___/_/ \_\___|_|\_\___|_|\_|___/ + +*******************************************************************************/ + +union alignas(uint32_t) RB_MODECONTROL { + uint32_t value; + struct { + xenos::EdramMode edram_mode : 3; // +0 + uint32_t _pad_3 : 29; // +3 + }; + static constexpr Register register_index = XE_GPU_REG_RB_MODECONTROL; +}; +static_assert_size(RB_MODECONTROL, sizeof(uint32_t)); + +union alignas(uint32_t) RB_SURFACE_INFO { + uint32_t value; + struct { + uint32_t surface_pitch : 14; // +0 in pixels. + uint32_t _pad_14 : 2; // +14 + xenos::MsaaSamples msaa_samples : 2; // +16 + uint32_t hiz_pitch : 14; // +18 + }; + static constexpr Register register_index = XE_GPU_REG_RB_SURFACE_INFO; +}; +static_assert_size(RB_SURFACE_INFO, sizeof(uint32_t)); + +union alignas(uint32_t) RB_COLORCONTROL { + uint32_t value; + struct { + xenos::CompareFunction alpha_func : 3; // +0 + uint32_t alpha_test_enable : 1; // +3 + uint32_t alpha_to_mask_enable : 1; // +4 + // Everything in between was added on Adreno. + uint32_t _pad_5 : 19; // +5 + // TODO(Triang3l): Redo these tests and possibly flip these vertically in + // the comment and in the actual implementation. It appears that + // gl_FragCoord.y is mirrored as opposed to the actual screen coordinates in + // the rasterizer (see the SQ_CONTEXT_MISC::param_gen_pos comment here). + // According to tests on an Adreno 200 device (LG Optimus L7), done by + // drawing 0.5x0.5 rectangles in different corners of four pixels in a quad + // to a multisampled GLSurfaceView, the coverage mask is the following for 4 + // samples: + // 0.25) [0.25, 0.5) [0.5, 0.75) [0.75, 1) [1 + // -- -- -- -- -- + // | | | | | #| |##| |##| + // | | |# | |# | |# | |##| + // -- -- -- -- -- + // (gl_FragCoord.y near 0 in the top, near 1 in the bottom here - D3D-like.) + // For 2 samples, the top sample (closer to gl_FragCoord.y 0) is covered + // when alpha is in [0.5, 1), the bottom sample is covered when the alpha is + // [1. With these thresholds, however, in 5454082B, almost all distant trees + // are transparent, this is asymmetric - fully transparent for a quarter of + // the range (or even half of the range for 2x and almost the entire range + // for 1x), but fully opaque only in one value. + // Though, 2, 2, 2, 2 offset values are commonly used for undithered alpha + // to coverage (in games such as 5454082B, and overall in AMD driver + // implementations) - it appears that 2, 2, 2, 2 offsets are supposed to + // make this symmetric. + // Both 5454082B and RADV (which used AMDVLK as a reference) use 3, 1, 0, 2 + // offsets for dithered alpha to mask. + // https://gitlab.freedesktop.org/nchery/mesa/commit/8a52e4cc4fad4f1c75acc0badd624778f9dfe202 + // It appears that the offsets lower the thresholds by (offset / 4 / + // sample count). That's consistent with both 2, 2, 2, 2 making the test + // symmetric and 0, 0, 0, 0 (forgetting to set the offset values) resulting + // in what the official Adreno 200 driver for Android (which is pretty buggy + // overall) produces. + // According to Evergreen register reference: + // - offset0 is for pixel (0, 0) in each quad. + // - offset1 is for pixel (0, 1) in each quad. + // - offset2 is for pixel (1, 0) in each quad. + // - offset3 is for pixel (1, 1) in each quad. + uint32_t alpha_to_mask_offset0 : 2; // +24 + uint32_t alpha_to_mask_offset1 : 2; // +26 + uint32_t alpha_to_mask_offset2 : 2; // +28 + uint32_t alpha_to_mask_offset3 : 2; // +30 + }; + static constexpr Register register_index = XE_GPU_REG_RB_COLORCONTROL; +}; +static_assert_size(RB_COLORCONTROL, sizeof(uint32_t)); + +union alignas(uint32_t) RB_COLOR_INFO { + uint32_t value; + struct { + // The original R400 structure has 12-bit color_base, however the Xenos has + // periodic 11-bit EDRAM tile addressing, so this field was split in Xenia + // for convenience and to avoid mistakes. + uint32_t color_base : 11; // +0 in tiles. + uint32_t color_base_bit_11 : 1; // +11 + uint32_t _pad_12 : 4; // +12 + xenos::ColorRenderTargetFormat color_format : 4; // +16 + int32_t color_exp_bias : 6; // +20 + uint32_t _pad_26 : 6; // +26 + }; + static constexpr Register register_index = XE_GPU_REG_RB_COLOR_INFO; + // RB_COLOR[1-3]_INFO also use this format. + static const Register rt_register_indices[4]; +}; +static_assert_size(RB_COLOR_INFO, sizeof(uint32_t)); + +union alignas(uint32_t) RB_COLOR_MASK { + uint32_t value; + struct { + uint32_t write_red0 : 1; // +0 + uint32_t write_green0 : 1; // +1 + uint32_t write_blue0 : 1; // +2 + uint32_t write_alpha0 : 1; // +3 + uint32_t write_red1 : 1; // +4 + uint32_t write_green1 : 1; // +5 + uint32_t write_blue1 : 1; // +6 + uint32_t write_alpha1 : 1; // +7 + uint32_t write_red2 : 1; // +8 + uint32_t write_green2 : 1; // +9 + uint32_t write_blue2 : 1; // +10 + uint32_t write_alpha2 : 1; // +11 + uint32_t write_red3 : 1; // +12 + uint32_t write_green3 : 1; // +13 + uint32_t write_blue3 : 1; // +14 + uint32_t write_alpha3 : 1; // +15 + uint32_t _pad_16 : 16; // +16 + }; + static constexpr Register register_index = XE_GPU_REG_RB_COLOR_MASK; +}; +static_assert_size(RB_COLOR_MASK, sizeof(uint32_t)); + +union alignas(uint32_t) RB_BLENDCONTROL { + uint32_t value; + struct { + xenos::BlendFactor color_srcblend : 5; // +0 + xenos::BlendOp color_comb_fcn : 3; // +5 + xenos::BlendFactor color_destblend : 5; // +8 + uint32_t _pad_13 : 3; // +13 + xenos::BlendFactor alpha_srcblend : 5; // +16 + xenos::BlendOp alpha_comb_fcn : 3; // +21 + xenos::BlendFactor alpha_destblend : 5; // +24 + // BLEND_FORCE_ENABLE and BLEND_FORCE were added on Adreno. + uint32_t _pad_29 : 3; // +29 + }; + // RB_BLENDCONTROL[0-3] use this format. + static constexpr Register register_index = XE_GPU_REG_RB_BLENDCONTROL0; + static const Register rt_register_indices[4]; +}; +static_assert_size(RB_BLENDCONTROL, sizeof(uint32_t)); + +union alignas(uint32_t) RB_DEPTHCONTROL { + uint32_t value; + struct { + uint32_t stencil_enable : 1; // +0 + uint32_t z_enable : 1; // +1 + uint32_t z_write_enable : 1; // +2 + // EARLY_Z_ENABLE was added on Adreno, never set by Xbox 360 games. + uint32_t _pad_3 : 1; // +3 + xenos::CompareFunction zfunc : 3; // +4 + uint32_t backface_enable : 1; // +7 + xenos::CompareFunction stencilfunc : 3; // +8 + xenos::StencilOp stencilfail : 3; // +11 + xenos::StencilOp stencilzpass : 3; // +14 + xenos::StencilOp stencilzfail : 3; // +17 + xenos::CompareFunction stencilfunc_bf : 3; // +20 + xenos::StencilOp stencilfail_bf : 3; // +23 + xenos::StencilOp stencilzpass_bf : 3; // +26 + xenos::StencilOp stencilzfail_bf : 3; // +29 + }; + static constexpr Register register_index = XE_GPU_REG_RB_DEPTHCONTROL; +}; +static_assert_size(RB_DEPTHCONTROL, sizeof(uint32_t)); + +union alignas(uint32_t) RB_STENCILREFMASK { + uint32_t value; + struct { + uint32_t stencilref : 8; // +0 + uint32_t stencilmask : 8; // +8 + uint32_t stencilwritemask : 8; // +16 + uint32_t _pad_24 : 8; // +24 + }; + static constexpr Register register_index = XE_GPU_REG_RB_STENCILREFMASK; + // RB_STENCILREFMASK_BF also uses this format. +}; +static_assert_size(RB_STENCILREFMASK, sizeof(uint32_t)); + +union alignas(uint32_t) RB_DEPTH_INFO { + uint32_t value; + struct { + // The original R400 structure has 12-bit depth_base, however the Xenos has + // periodic 11-bit EDRAM tile addressing, so this field was split in Xenia + // for convenience and to avoid mistakes. + uint32_t depth_base : 11; // +0 in tiles. + uint32_t depth_base_bit_11 : 1; // +11 + uint32_t _pad_12 : 4; // +12 + xenos::DepthRenderTargetFormat depth_format : 1; // +16 + uint32_t _pad_17 : 15; // +17 + }; + static constexpr Register register_index = XE_GPU_REG_RB_DEPTH_INFO; +}; +static_assert_size(RB_DEPTH_INFO, sizeof(uint32_t)); + +// Copy registers are very different than on Adreno. + +union alignas(uint32_t) RB_COPY_CONTROL { + uint32_t value; + struct { + uint32_t copy_src_select : 3; // +0 Depth is 4. + uint32_t _pad_3 : 1; // +3 + xenos::CopySampleSelect copy_sample_select : 3; // +4 + uint32_t _pad_7 : 1; // +7 + uint32_t color_clear_enable : 1; // +8 + uint32_t depth_clear_enable : 1; // +9 + uint32_t _pad_10 : 10; // +10 + xenos::CopyCommand copy_command : 2; // +20 + uint32_t _pad_22 : 10; // +22 + }; + static constexpr Register register_index = XE_GPU_REG_RB_COPY_CONTROL; +}; +static_assert_size(RB_COPY_CONTROL, sizeof(uint32_t)); + +union alignas(uint32_t) RB_COPY_DEST_INFO { + uint32_t value; + struct { + xenos::Endian128 copy_dest_endian : 3; // +0 + uint32_t copy_dest_array : 1; // +3 + uint32_t copy_dest_slice : 3; // +4 + xenos::ColorFormat copy_dest_format : 6; // +7 + xenos::SurfaceNumberFormat copy_dest_number : 3; // +13 + int32_t copy_dest_exp_bias : 6; // +16 + uint32_t _pad_22 : 2; // +22 + uint32_t copy_dest_swap : 1; // +24 + uint32_t _pad_25 : 7; // +25 + }; + static constexpr Register register_index = XE_GPU_REG_RB_COPY_DEST_INFO; +}; +static_assert_size(RB_COPY_DEST_INFO, sizeof(uint32_t)); + +union alignas(uint32_t) RB_COPY_DEST_PITCH { + uint32_t value; + struct { + uint32_t copy_dest_pitch : 14; // +0 + uint32_t _pad_14 : 2; // +14 + uint32_t copy_dest_height : 14; // +16 + uint32_t _pad_30 : 2; // +30 + }; + static constexpr Register register_index = XE_GPU_REG_RB_COPY_DEST_PITCH; +}; +static_assert_size(RB_COPY_DEST_PITCH, sizeof(uint32_t)); + +/******************************************************************************* + ___ ___ ___ ___ _ ___ __ + | \_ _/ __| _ \ | /_\ \ / / + | |) | |\__ \ _/ |__ / _ \ V / + |___/___|___/_| |____/_/ \_\_| + + ___ ___ _ _ _____ ___ ___ _ _ ___ ___ + / __/ _ \| \| |_ _| _ \/ _ \| | | | | __| _ \ + | (_| (_) | .` | | | | / (_) | |__| |__| _|| / + \___\___/|_|\_| |_| |_|_\\___/|____|____|___|_|_\ + +*******************************************************************************/ + +union alignas(uint32_t) DC_LUT_RW_INDEX { + uint32_t value; + struct { + // Unlike in the M56 documentation, for the 256-table entry, this is the + // absolute index, without the lower or upper 10 bits selection in the + // bit 0. For PWL, the bit 7 is ignored. + uint32_t rw_index : 8; // +0 + uint32_t _pad_8 : 24; // +8 + }; + static constexpr Register register_index = XE_GPU_REG_DC_LUT_RW_INDEX; +}; +static_assert_size(DC_LUT_RW_INDEX, sizeof(uint32_t)); + +union alignas(uint32_t) DC_LUT_SEQ_COLOR { + uint32_t value; + struct { + uint32_t seq_color : 16; // +0, bits 0:5 are hardwired to zero + uint32_t _pad_16 : 16; // +16 + }; + static constexpr Register register_index = XE_GPU_REG_DC_LUT_SEQ_COLOR; +}; +static_assert_size(DC_LUT_SEQ_COLOR, sizeof(uint32_t)); + +union alignas(uint32_t) DC_LUT_PWL_DATA { + uint32_t value; + struct { + // See the M56 DC_LUTA_CONTROL for information about the way these should be + // interpreted (`output = base + (multiplier * delta) / 2^increment`, where + // the increment is the value specified in DC_LUTA_CONTROL for the specific + // color channel, the base is 7 bits of the front buffer value above + // `increment` bits, the multiplier is the lower `increment` bits of it; the + // increment is nonzero, otherwise the 256-entry table should be used + // instead). + uint32_t base : 16; // +0, bits 0:5 are hardwired to zero + uint32_t delta : 16; // +16, bits 0:5 are hardwired to zero + }; + static constexpr Register register_index = XE_GPU_REG_DC_LUT_PWL_DATA; +}; +static_assert_size(DC_LUT_PWL_DATA, sizeof(uint32_t)); + +union alignas(uint32_t) DC_LUT_30_COLOR { + uint32_t value; + struct { + uint32_t color_10_blue : 10; // +0 + uint32_t color_10_green : 10; // +10 + uint32_t color_10_red : 10; // +20 + uint32_t _pad_30 : 2; // +30 + }; + static constexpr Register register_index = XE_GPU_REG_DC_LUT_30_COLOR; +}; +static_assert_size(DC_LUT_30_COLOR, sizeof(uint32_t)); + +} // namespace reg + +} // namespace rex::graphics diff --git a/include/rex/graphics/sampler_info.h b/include/rex/graphics/sampler_info.h new file mode 100644 index 0000000..193fd0f --- /dev/null +++ b/include/rex/graphics/sampler_info.h @@ -0,0 +1,45 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +namespace rex::graphics { + +struct SamplerInfo { + xenos::TextureFilter min_filter; + xenos::TextureFilter mag_filter; + xenos::TextureFilter mip_filter; + xenos::ClampMode clamp_u; + xenos::ClampMode clamp_v; + xenos::ClampMode clamp_w; + xenos::AnisoFilter aniso_filter; + xenos::BorderColor border_color; + float lod_bias; + uint32_t mip_min_level; + uint32_t mip_max_level; + + static bool Prepare(const xenos::xe_gpu_texture_fetch_t& fetch, + const ParsedTextureFetchInstruction& fetch_instr, SamplerInfo* out_info); + + uint64_t hash() const; + bool operator==(const SamplerInfo& other) const { + return min_filter == other.min_filter && mag_filter == other.mag_filter && + mip_filter == other.mip_filter && clamp_u == other.clamp_u && clamp_v == other.clamp_v && + clamp_w == other.clamp_w && aniso_filter == other.aniso_filter && + lod_bias == other.lod_bias && mip_min_level == other.mip_min_level && + mip_max_level == other.mip_max_level; + } +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/shared_memory.h b/include/rex/graphics/shared_memory.h new file mode 100644 index 0000000..b05df6a --- /dev/null +++ b/include/rex/graphics/shared_memory.h @@ -0,0 +1,266 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +#include +#include + +namespace rex::graphics { + +// Manages memory for unconverted textures, resolve targets, vertex and index +// buffers that can be accessed from shaders with Xenon physical addresses, with +// system page size granularity. +class SharedMemory { + public: + static constexpr uint32_t kBufferSizeLog2 = 29; + static constexpr uint32_t kBufferSize = 1 << kBufferSizeLog2; + + virtual ~SharedMemory(); + // Call in the implementation-specific ClearCache. + virtual void ClearCache(); + void SetSystemPageBlocksValidWithGpuDataWritten(); + void InvalidateAllPages(); + + typedef void (*GlobalWatchCallback)(const std::unique_lock& global_lock, + void* context, uint32_t address_first, uint32_t address_last, + bool invalidated_by_gpu); + typedef void* GlobalWatchHandle; + // Registers a callback invoked when something is invalidated in the GPU + // memory copy by the CPU or (if triggered explicitly - such as by a resolve) + // by the GPU. It will be fired for writes to pages previously requested, but + // may also be fired regardless of whether it was used by GPU emulation - for + // example, if the game changes protection level of a memory range containing + // the watched range. + // + // The callback is called within the global critical region. + GlobalWatchHandle RegisterGlobalWatch(GlobalWatchCallback callback, void* callback_context); + void UnregisterGlobalWatch(GlobalWatchHandle handle); + typedef void (*WatchCallback)(const std::unique_lock& global_lock, + void* context, void* data, uint64_t argument, + bool invalidated_by_gpu); + typedef void* WatchHandle; + // Registers a callback invoked when the specified memory range is invalidated + // in the GPU memory copy by the CPU or (if triggered explicitly - such as by + // a resolve) by the GPU. It will be fired for writes to pages previously + // requested, but may also be fired regardless of whether it was used by GPU + // emulation - for example, if the game changes protection level of a memory + // range containing the watched range. + // + // Generally the context is the subsystem pointer (for example, the texture + // cache), the data is the object (such as a texture), and the argument is + // additional subsystem/object-specific data (such as whether the range + // belongs to the base mip level or to the rest of the mips). + // + // Called with the global critical region locked. Do NOT watch or unwatch + // ranges from within it! The watch for the callback is cancelled after the + // callback - the handle becomes invalid. + WatchHandle WatchMemoryRange(uint32_t start, uint32_t length, WatchCallback callback, + void* callback_context, void* callback_data, + uint64_t callback_argument); + // Unregisters previously registered watched memory range. + void UnwatchMemoryRange(WatchHandle handle); + + // Checks if the range has been updated, uploads new data if needed and + // ensures the host GPU memory backing the range are resident. Returns true if + // the range has been fully updated and is usable. + bool RequestRanges(const std::pair* ranges, size_t count); + bool RequestRange(uint32_t start, uint32_t length); + + // Marks the range and, if not exact_range, potentially its surroundings + // (to up to the first GPU-written page, as an access violation exception + // count optimization) as modified by the CPU, also invalidating GPU-written + // pages directly in the range. + std::pair MemoryInvalidationCallback(uint32_t physical_address_start, + uint32_t length, bool exact_range); + + // Marks the range as containing GPU-generated data (such as resolves), + // triggering modification callbacks, making it valid (so pages are not + // copied from the main memory until they're modified by the CPU) and + // protecting it. Before writing anything from the GPU side, RequestRange must + // be called, to make sure, if the GPU writes don't overwrite *everything* in + // the pages they touch, the CPU data is properly loaded to the unmodified + // regions in those pages. + void RangeWrittenByGpu(uint32_t start, uint32_t length); + + protected: + SharedMemory(memory::Memory& memory); + // Call in implementation-specific initialization. + void InitializeCommon(); + void InitializeSparseHostGpuMemory(uint32_t granularity_log2); + // Call last in implementation-specific shutdown, also callable from the + // destructor. + void ShutdownCommon(); + + // Sparse allocations are 4 MB, so not too many of them are allocated, but + // also not to waste too much memory for padding (with 16 MB there's too + // much). + static constexpr uint32_t kHostGpuMemoryOptimalSparseAllocationLog2 = 22; + static_assert(kHostGpuMemoryOptimalSparseAllocationLog2 <= kBufferSizeLog2); + + memory::Memory& memory() const { return memory_; } + + uint32_t page_size_log2() const { return page_size_log2_; } + + uint32_t host_gpu_memory_sparse_granularity_log2() const { + return host_gpu_memory_sparse_granularity_log2_; + } + + // Allocations in the host buffer are aligned the same way as in the guest + // physical memory (for instance, if an allocation is 64 KB, it can represent + // 0-64 KB, 64-128 KB, 128-192 KB in the guest memory, and so on, but not + // something like 16-80 KB. This is assumed by the rules for texture data + // access in the texture cache. + virtual bool AllocateSparseHostGpuMemoryRange(uint32_t offset_allocations, + uint32_t length_allocations); + + // Mark the memory range as updated and protect it. + void MakeRangeValid(uint32_t start, uint32_t length, bool written_by_gpu); + + // Uploads a range of host pages - only called if host GPU sparse memory + // allocation succeeded if needed. While uploading, MakeRangeValid must be + // called for each successfully uploaded range as early as possible, before + // the memcpy, to make sure invalidation that happened during the CPU -> GPU + // memcpy isn't missed (upload_page_ranges is in pages because of this - + // MakeRangeValid has page granularity). upload_page_ranges are sorted in + // ascending address order, so front and back can be used to determine the + // overall bounds of pages to be uploaded. + virtual bool UploadRanges( + const std::vector>& upload_page_ranges) = 0; + + const std::vector>& trace_download_ranges() { + return trace_download_ranges_; + } + uint32_t trace_download_page_count() const { return trace_download_page_count_; } + // Fills trace_download_ranges() and trace_download_page_count() with + // GPU-written ranges that need to be downloaded, and also invalidates + // non-GPU-written ranges so only the needed data - not the all the collected + // data - will be written in the trace. trace_download_page_count() will be 0 + // if nothing to download. + void PrepareForTraceDownload(); + // Release memory used for trace download ranges, to be called after + // downloading or in cases when download is dropped. + void ReleaseTraceDownloadRanges(); + + private: + memory::Memory& memory_; + + // Log2 of invalidation granularity (the system page size, but the dependency + // on it is not hard - the access callback takes a range as an argument, and + // touched pages of the buffer of this size will be invalidated). + uint32_t page_size_log2_; + + bool EnsureHostGpuMemoryAllocated(uint32_t start, uint32_t length); + uint32_t host_gpu_memory_sparse_granularity_log2_ = UINT32_MAX; + std::vector host_gpu_memory_sparse_allocated_; + uint32_t host_gpu_memory_sparse_allocations_ = 0; + uint32_t host_gpu_memory_sparse_used_bytes_ = 0; + + void* memory_invalidation_callback_handle_ = nullptr; + void* memory_data_provider_handle_ = nullptr; + + // Ranges that need to be uploaded, generated by GetRangesToUpload (a + // persistently allocated vector). + std::vector> upload_ranges_; + + // GPU-written memory downloading for traces. . + std::vector> trace_download_ranges_; + uint32_t trace_download_page_count_ = 0; + + // Mutex between the guest memory subsystem and the command processor, to be + // locked when checking or updating validity of pages/ranges and when firing + // watches. + rex::thread::global_critical_region global_critical_region_; + + // *************************************************************************** + // Things below should be fully protected by global_critical_region. + // *************************************************************************** + + // Double-buffered valid-page flags for lockless checks in RequestRanges. + std::vector valid_buffer_a_; + std::vector valid_buffer_b_; + std::atomic active_valid_flags_{nullptr}; + std::atomic staging_valid_flags_{nullptr}; + // Subset of valid pages containing data written by the GPU. + std::vector system_page_flags_valid_and_gpu_written_; + // Dirty state tracking for frame-end page-state refresh. + std::atomic gpu_written_data_dirty_{false}; + std::atomic dirty_blocks_{0}; + uint32_t num_system_page_flags_ = 0; + + static std::pair MemoryInvalidationCallbackThunk( + void* context_ptr, uint32_t physical_address_start, uint32_t length, bool exact_range); + + struct GlobalWatch { + GlobalWatchCallback callback; + void* callback_context; + }; + std::vector global_watches_; + struct WatchNode; + // Watched range placed by other GPU subsystems. + struct WatchRange { + union { + struct { + WatchCallback callback; + void* callback_context; + void* callback_data; + uint64_t callback_argument; + WatchNode* node_first; + uint32_t page_first; + uint32_t page_last; + }; + WatchRange* next_free; + }; + }; + // Node for faster checking of watches when pages have been written to - all + // 512 MB are split into smaller equally sized buckets, and then ranges are + // linearly checked. + struct WatchNode { + union { + struct { + WatchRange* range; + // Link to another node of this watched range in the next bucket. + WatchNode* range_node_next; + // Links to nodes belonging to other watched ranges in the bucket. + WatchNode* bucket_node_previous; + WatchNode* bucket_node_next; + }; + WatchNode* next_free; + }; + }; + static constexpr uint32_t kWatchBucketSizeLog2 = 22; + static constexpr uint32_t kWatchBucketCount = 1 << (kBufferSizeLog2 - kWatchBucketSizeLog2); + WatchNode* watch_buckets_[kWatchBucketCount] = {}; + // Allocation from pools - taking new WatchRanges and WatchNodes from the free + // list, and if there are none, creating a pool if the current one is fully + // used, and linearly allocating from the current pool. + static constexpr uint32_t kWatchRangePoolSize = 8192; + static constexpr uint32_t kWatchNodePoolSize = 8192; + std::vector watch_range_pools_; + std::vector watch_node_pools_; + uint32_t watch_range_current_pool_allocated_ = 0; + uint32_t watch_node_current_pool_allocated_ = 0; + WatchRange* watch_range_first_free_ = nullptr; + WatchNode* watch_node_first_free_ = nullptr; + // Triggers the watches (global and per-range), removing triggered range + // watches. + void FireWatches(uint32_t page_first, uint32_t page_last, bool invalidated_by_gpu); + // Unlinks and frees the range and its nodes. Call this in the global critical + // region. + void UnlinkWatchRange(WatchRange* range); +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/trace_dump.h b/include/rex/graphics/trace_dump.h new file mode 100644 index 0000000..eb9c7e7 --- /dev/null +++ b/include/rex/graphics/trace_dump.h @@ -0,0 +1,54 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include +#include +#include + +namespace rex::graphics { + +struct SamplerInfo; +struct TextureInfo; + +class TraceDump { + public: + virtual ~TraceDump(); + + int Main(const std::vector& args); + + protected: + TraceDump(); + + virtual std::unique_ptr CreateGraphicsSystem() = 0; + + virtual void BeginHostCapture() = 0; + virtual void EndHostCapture() = 0; + + std::unique_ptr emulator_; + GraphicsSystem* graphics_system_ = nullptr; + std::unique_ptr player_; + + private: + bool Setup(); + bool Load(const std::filesystem::path& trace_file_path); + int Run(); + + std::filesystem::path trace_file_path_; + std::filesystem::path base_output_path_; +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/trace_player.h b/include/rex/graphics/trace_player.h new file mode 100644 index 0000000..7fe8c35 --- /dev/null +++ b/include/rex/graphics/trace_player.h @@ -0,0 +1,62 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include + +namespace rex::graphics { + +class GraphicsSystem; + +enum class TracePlaybackMode { + kUntilEnd, + kBreakOnSwap, +}; + +class TracePlayer : public TraceReader { + public: + TracePlayer(GraphicsSystem* graphics_system); + + GraphicsSystem* graphics_system() const { return graphics_system_; } + int current_frame_index() const { return current_frame_index_; } + int current_command_index() const { return current_command_index_; } + bool is_playing_trace() const { return playing_trace_; } + const Frame* current_frame() const; + + // Only valid if playing_trace is true. + // Scalar from 0-10000 + uint32_t playback_percent() const { return playback_percent_; } + + void SeekFrame(int target_frame); + void SeekCommand(int target_command); + + void WaitOnPlayback(); + + private: + void PlayTrace(const uint8_t* trace_data, size_t trace_size, TracePlaybackMode playback_mode, + bool clear_caches); + void PlayTraceOnThread(const uint8_t* trace_data, size_t trace_size, + TracePlaybackMode playback_mode, bool clear_caches); + + GraphicsSystem* graphics_system_; + int current_frame_index_; + int current_command_index_; + bool playing_trace_ = false; + std::atomic playback_percent_ = {0}; + std::unique_ptr playback_event_; +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/trace_protocol.h b/include/rex/graphics/trace_protocol.h new file mode 100644 index 0000000..c200d0c --- /dev/null +++ b/include/rex/graphics/trace_protocol.h @@ -0,0 +1,173 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +namespace rex::graphics { + +// Trace file extension. +static const char kTraceExtension[] = "xtr"; + +// Any byte changes to the files should bump this version. +// Only builds with matching versions will work. +// Other changes besides the file format may require bumps, such as +// anything that changes what is recorded into the files (new GPU +// command processor commands, etc). +constexpr uint32_t kTraceFormatVersion = 1; + +// Trace file header identifying information about the trace. +// This must be positioned at the start of the file and must only occur once. +struct TraceHeader { + // Must be the first 4 bytes of the file. + // Set to kTraceFormatVersion. + uint32_t version; + + // SHA1 of the commit used to record the trace. + char build_commit_sha[40]; + + // Title ID of game that was being recorded. + // May be 0 if not generated from a game or the ID could not be retrieved. + uint32_t title_id; +}; + +// Tags each command in the trace file stream as one of the *Command types. +// Each command has this value as its first dword. +enum class TraceCommandType : uint32_t { + kPrimaryBufferStart, + kPrimaryBufferEnd, + kIndirectBufferStart, + kIndirectBufferEnd, + kPacketStart, + kPacketEnd, + kMemoryRead, + kMemoryWrite, + kEdramSnapshot, + kEvent, + kRegisters, + kGammaRamp, +}; + +struct PrimaryBufferStartCommand { + TraceCommandType type; + uint32_t base_ptr; + uint32_t count; +}; + +struct PrimaryBufferEndCommand { + TraceCommandType type; +}; + +struct IndirectBufferStartCommand { + TraceCommandType type; + uint32_t base_ptr; + uint32_t count; +}; + +struct IndirectBufferEndCommand { + TraceCommandType type; +}; + +struct PacketStartCommand { + TraceCommandType type; + uint32_t base_ptr; + uint32_t count; +}; + +struct PacketEndCommand { + TraceCommandType type; +}; + +// The compression format used for memory read/write buffers. +// Note that not every memory read/write will have compressed data +// (as it's silly to compress 4 byte buffers). +enum class MemoryEncodingFormat { + // Data is in its raw form. encoded_length == decoded_length. + kNone, + // Data is compressed with third_party/snappy. + kSnappy, +}; + +// Represents the GPU reading or writing data from or to memory. +// Used for both TraceCommandType::kMemoryRead and kMemoryWrite. +struct MemoryCommand { + TraceCommandType type; + + // Base physical memory pointer this read starts at. + uint32_t base_ptr; + // Encoding format of the data in the trace file. + MemoryEncodingFormat encoding_format; + // Number of bytes the data occupies in the trace file in its encoded form. + uint32_t encoded_length; + // Number of bytes the data occupies in memory after decoding. + // Note that if no encoding is used this will equal encoded_length. + uint32_t decoded_length; +}; + +// Represents a full 10 MB snapshot of EDRAM contents, for trace initialization +// (since replaying the trace will reconstruct its state at any point later) as +// a sequence of tiles with row-major samples (2x multisampling as 1x2 samples, +// 4x as 2x2 samples). +struct EdramSnapshotCommand { + TraceCommandType type; + // Encoding format of the data in the trace file. + MemoryEncodingFormat encoding_format; + // Number of bytes the data occupies in the trace file in its encoded form. + uint32_t encoded_length; +}; + +// Represents a GPU event of EventCommand::Type. +struct EventCommand { + TraceCommandType type; + + // Identifies the event that occurred. + enum class Type { + kSwap, + }; + Type event_type; +}; + +// Represents a range of registers. +struct RegistersCommand { + TraceCommandType type; + + uint32_t first_register; + uint32_t register_count; + // Whether to set the registers via WriteRegister, which may have side + // effects, rather than by copying them directly to the register file. + bool execute_callbacks; + + // Encoding format of the values in the trace file. + MemoryEncodingFormat encoding_format; + // Number of bytes the values occupy in the trace file in their encoded form. + // If no encoding is used, this will be sizeof(uint32_t) * register_count. + uint32_t encoded_length; +}; + +// Represents a gamma ramp - encoded 256 DC_LUT_30_COLOR values and 128 +// interleaved RGB DC_LUT_PWL_DATA values. +// Assuming that all other gamma ramp state is saved as plain registers. +struct GammaRampCommand { + TraceCommandType type; + + // The component index (0 = red, 1 = green, 2 = blue) for the next + // DC_LUT_SEQ_COLOR or DC_LUT_PWL_DATA read or write. + uint8_t rw_component; + + // Encoding format of the ramps in the trace file. + MemoryEncodingFormat encoding_format; + // Number of bytes the ramps occupy in the trace file in their encoded form. + // If no encoding is used, this will be sizeof(uint32_t) * (256 + 3 * 128). + uint32_t encoded_length; +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/trace_reader.h b/include/rex/graphics/trace_reader.h new file mode 100644 index 0000000..1929316 --- /dev/null +++ b/include/rex/graphics/trace_reader.h @@ -0,0 +1,114 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include + +namespace rex::graphics { + +class TraceReader { + public: + struct CommandBuffer { + struct Command { + enum class Type { + kCommand, + kBuffer, + }; + + Command() {} + Command(Command&& other) { + type = other.type; + command_id = other.command_id; + command_subtree = std::move(other.command_subtree); + } + Command(CommandBuffer* buf) { + type = Type::kBuffer; + command_subtree = std::unique_ptr(buf); + } + Command(uint32_t id) { + type = Type::kCommand; + command_id = id; + } + ~Command() = default; + + Type type; + uint32_t command_id = -1; + std::unique_ptr command_subtree = nullptr; + }; + + CommandBuffer() {} + ~CommandBuffer() {} + + // Parent command buffer, if one exists. + CommandBuffer* parent = nullptr; + std::vector commands; + }; + + struct Frame { + struct Command { + enum class Type { + kDraw, + kSwap, + }; + const uint8_t* head_ptr; + const uint8_t* start_ptr; + const uint8_t* end_ptr; + Type type; + union { + struct { + // + } draw; + struct { + // + } swap; + }; + }; + + const uint8_t* start_ptr = nullptr; + const uint8_t* end_ptr = nullptr; + int command_count = 0; + + // Flat list of all commands in this frame. + std::vector commands; + + // Tree of all command buffers + std::unique_ptr command_tree; + }; + + TraceReader() = default; + virtual ~TraceReader() = default; + + const TraceHeader* header() const { return reinterpret_cast(trace_data_); } + + const Frame* frame(int n) const { return &frames_[n]; } + int frame_count() const { return int(frames_.size()); } + + bool Open(const std::string_view path); + + void Close(); + + protected: + void ParseTrace(); + bool DecompressMemory(MemoryEncodingFormat encoding_format, const void* src, size_t src_size, + void* dest, size_t dest_size); + + std::unique_ptr mmap_; + const uint8_t* trace_data_ = nullptr; + size_t trace_size_ = 0; + std::vector frames_; +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/trace_viewer.h b/include/rex/graphics/trace_viewer.h new file mode 100644 index 0000000..5528cef --- /dev/null +++ b/include/rex/graphics/trace_viewer.h @@ -0,0 +1,132 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::graphics { + +struct SamplerInfo; +struct TextureInfo; + +class TraceViewer : public rex::ui::WindowedApp { + public: + virtual ~TraceViewer(); + + bool OnInitialize() override; + + protected: + explicit TraceViewer(rex::ui::WindowedAppContext& app_context, const std::string_view name); + + virtual std::unique_ptr CreateGraphicsSystem() = 0; + GraphicsSystem* graphics_system() const { return graphics_system_; } + + void DrawMultilineString(const std::string_view str); + + virtual uintptr_t GetColorRenderTarget(uint32_t pitch, xenos::MsaaSamples samples, uint32_t base, + xenos::ColorRenderTargetFormat format) = 0; + virtual uintptr_t GetDepthRenderTarget(uint32_t pitch, xenos::MsaaSamples samples, uint32_t base, + xenos::DepthRenderTargetFormat format) = 0; + virtual uintptr_t GetTextureEntry(const TextureInfo& texture_info, + const SamplerInfo& sampler_info) = 0; + + virtual size_t QueryVSOutputSize() { return 0; } + virtual size_t QueryVSOutputElementSize() { return 0; } + virtual bool QueryVSOutput(void* buffer, size_t size) { return false; } + + virtual bool Setup(); + + private: + class TraceViewerWindowListener final : public rex::ui::WindowListener, + public rex::ui::WindowInputListener { + public: + explicit TraceViewerWindowListener(TraceViewer& trace_viewer) : trace_viewer_(trace_viewer) {} + + void OnClosing(rex::ui::UIEvent& e) override; + + void OnKeyDown(rex::ui::KeyEvent& e) override; + + private: + TraceViewer& trace_viewer_; + }; + + class TraceViewerDialog final : public ui::ImGuiDialog { + public: + explicit TraceViewerDialog(rex::ui::ImGuiDrawer* imgui_drawer, TraceViewer& trace_viewer) + : rex::ui::ImGuiDialog(imgui_drawer), trace_viewer_(trace_viewer) {} + + protected: + void OnDraw(ImGuiIO& io) override; + + private: + TraceViewer& trace_viewer_; + }; + + enum class ShaderDisplayType : int { + kUcode, + kTranslated, + kHostDisasm, + }; + + // Same as for Dear ImGui tooltips. Windows are translucent as the controls + // may take a pretty large fraction of the screen, especially on small + // screens, so the image from the guest can be seen through them. + static constexpr float kWindowBgAlpha = 0.6f; + + bool Load(const std::string_view trace_file_path); + + void DrawUI(); + void DrawControllerUI(); + void DrawPacketDisassemblerUI(); + int RecursiveDrawCommandBufferUI(const TraceReader::Frame* frame, + TraceReader::CommandBuffer* buffer); + void DrawCommandListUI(); + void DrawStateUI(); + + ShaderDisplayType DrawShaderTypeUI(); + void DrawShaderUI(Shader* shader, ShaderDisplayType display_type); + + void DrawBlendMode(uint32_t src_blend, uint32_t dest_blend, uint32_t blend_op); + + void DrawTextureInfo(const Shader::TextureBinding& texture_binding); + void DrawFailedTextureInfo(const Shader::TextureBinding& texture_binding, const char* message); + + void DrawVertexFetcher(Shader* shader, const Shader::VertexBinding& vertex_binding, + const xenos::xe_gpu_vertex_fetch_t& fetch); + + TraceViewerWindowListener window_listener_; + + std::unique_ptr window_; + + std::unique_ptr emulator_; + memory::Memory* memory_ = nullptr; + GraphicsSystem* graphics_system_ = nullptr; + std::unique_ptr player_; + + std::unique_ptr immediate_drawer_; + std::unique_ptr imgui_drawer_; + std::unique_ptr trace_viewer_dialog_; +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/trace_writer.h b/include/rex/graphics/trace_writer.h new file mode 100644 index 0000000..202c23f --- /dev/null +++ b/include/rex/graphics/trace_writer.h @@ -0,0 +1,65 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include + +namespace rex::graphics { + +class TraceWriter { + public: + explicit TraceWriter(uint8_t* membase); + ~TraceWriter(); + + bool is_open() const { return file_ != nullptr; } + + bool Open(const std::filesystem::path& path, uint32_t title_id); + void Flush(); + void Close(); + + void WritePrimaryBufferStart(uint32_t base_ptr, uint32_t count); + void WritePrimaryBufferEnd(); + void WriteIndirectBufferStart(uint32_t base_ptr, uint32_t count); + void WriteIndirectBufferEnd(); + void WritePacketStart(uint32_t base_ptr, uint32_t count); + void WritePacketEnd(); + void WriteMemoryRead(uint32_t base_ptr, size_t length, const void* host_ptr = nullptr); + void WriteMemoryReadCached(uint32_t base_ptr, size_t length); + void WriteMemoryReadCachedNop(uint32_t base_ptr, size_t length); + void WriteMemoryWrite(uint32_t base_ptr, size_t length, const void* host_ptr = nullptr); + void WriteEdramSnapshot(const void* snapshot); + void WriteEvent(EventCommand::Type event_type); + void WriteRegisters(uint32_t first_register, const uint32_t* register_values, + uint32_t register_count, bool execute_callbacks_on_play); + void WriteGammaRamp(const reg::DC_LUT_30_COLOR* gamma_ramp_256_entry_table, + const reg::DC_LUT_PWL_DATA* gamma_ramp_pwl_rgb, + uint32_t gamma_ramp_rw_component); + + private: + void WriteMemoryCommand(TraceCommandType type, uint32_t base_ptr, size_t length, + const void* host_ptr = nullptr); + + std::set cached_memory_reads_; + uint8_t* membase_; + FILE* file_ = nullptr; + + bool compress_output_ = true; + size_t compression_threshold_ = 1024; +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/util/draw.h b/include/rex/graphics/util/draw.h new file mode 100644 index 0000000..b6c914d --- /dev/null +++ b/include/rex/graphics/util/draw.h @@ -0,0 +1,590 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace rex::graphics::draw_util { + +constexpr bool IsPrimitiveLine(bool vgt_output_path_is_tessellation_enable, + xenos::PrimitiveType type) { + if (vgt_output_path_is_tessellation_enable && type == xenos::PrimitiveType::kLinePatch) { + // For patch primitive types, the major mode is always explicit, so just + // checking if VGT_OUTPUT_PATH_CNTL::path_select is kTessellationEnable is + // enough. + return true; + } + switch (type) { + case xenos::PrimitiveType::kLineList: + case xenos::PrimitiveType::kLineStrip: + case xenos::PrimitiveType::kLineLoop: + case xenos::PrimitiveType::k2DLineStrip: + return true; + default: + break; + } + return false; +} + +inline bool IsPrimitiveLine(const RegisterFile& regs) { + return IsPrimitiveLine(regs.Get().path_select == + xenos::VGTOutputPath::kTessellationEnable, + regs.Get().prim_type); +} + +// Polygonal primitive types (not including points and lines) are rasterized as +// triangles, have front and back faces, and also support face culling and fill +// modes (polymode_front_ptype, polymode_back_ptype). Other primitive types are +// always "front" (but don't support front face and back face culling, according +// to OpenGL and Vulkan specifications - even if glCullFace is +// GL_FRONT_AND_BACK, points and lines are still drawn), and may in some cases +// use the "para" registers instead of "front" or "back" (for "parallelogram" - +// like poly_offset_para_enable). +constexpr bool IsPrimitivePolygonal(bool vgt_output_path_is_tessellation_enable, + xenos::PrimitiveType type) { + if (vgt_output_path_is_tessellation_enable && + (type == xenos::PrimitiveType::kTrianglePatch || type == xenos::PrimitiveType::kQuadPatch)) { + // For patch primitive types, the major mode is always explicit, so just + // checking if VGT_OUTPUT_PATH_CNTL::path_select is kTessellationEnable is + // enough. + return true; + } + switch (type) { + case xenos::PrimitiveType::kTriangleList: + case xenos::PrimitiveType::kTriangleFan: + case xenos::PrimitiveType::kTriangleStrip: + case xenos::PrimitiveType::kTriangleWithWFlags: + case xenos::PrimitiveType::kQuadList: + case xenos::PrimitiveType::kQuadStrip: + case xenos::PrimitiveType::kPolygon: + return true; + default: + break; + } + // TODO(Triang3l): Investigate how kRectangleList should be treated - possibly + // actually drawn as two polygons on the console, however, the current + // geometry shader doesn't care about the winding order - allowing backface + // culling for rectangles currently breaks 4D53082D. + return false; +} + +inline bool IsPrimitivePolygonal(const RegisterFile& regs) { + return IsPrimitivePolygonal(regs.Get().path_select == + xenos::VGTOutputPath::kTessellationEnable, + regs.Get().prim_type); +} + +// Whether with the current state, any samples to rasterize (for any reason, not +// only to write something to a render target, but also to do sample counting or +// pixel shader memexport) can be generated. Finally dropping draw calls can +// only be done if the vertex shader doesn't memexport. Checks mostly special +// cases (for both the guest and usual host implementations), not everything +// like whether viewport / scissor are empty (until this truly matters in any +// game, of course). +bool IsRasterizationPotentiallyDone(const RegisterFile& regs, bool primitive_polygonal); + +// Direct3D 10.1+ standard sample positions, also used in Vulkan, for +// calculations related to host MSAA, in 1/16th of a pixel. +extern const int8_t kD3D10StandardSamplePositions2x[2][2]; +extern const int8_t kD3D10StandardSamplePositions4x[4][2]; + +reg::RB_DEPTHCONTROL GetNormalizedDepthControl(const RegisterFile& regs); + +// Direct3D 9 and Xenos constant polygon offset is an absolute floating-point +// value. +// It's possibly treated just as an absolute offset by the Xenos too - the +// PA_SU_POLY_OFFSET_DB_FMT_CNTL::POLY_OFFSET_DB_IS_FLOAT_FMT switch was added +// later in the R6xx, though this needs verification. +// 5454082B, for example, for float24, sets the bias to 0.000002 - or slightly +// above 2^-19. +// The total polygon offset formula specified by Direct3D 9 is: +// `offset = slope * slope factor + constant offset` +// +// Direct3D 10, Metal, OpenGL and Vulkan, however, take the constant polygon +// offset factor as a relative value, with the formula being: +// `offset = slope * slope factor + +// maximum resolvable difference * constant factor` +// where the maximum resolvable difference is: +// - For a fixed-point depth buffer, the minimum representable non-zero value in +// the depth buffer, that is 1 / (2^24 - 1) for unorm24 (on Vulkan though it's +// allowed to be up to 2 / 2^24 in this case). +// - For a floating-point depth buffer, it's: +// 2 ^ (exponent of the maximum Z in the primitive - the number of explicitly +// stored mantissa bits) +// (23 explicitly stored bits for float32 - and 20 explicitly stored bits for +// float24). +// +// While the polygon offset is a fixed-function feature in the pipeline, and the +// formula can't be toggled between absolute and relative, it's important that +// Xenia translates the guest absolute depth bias into the host relative depth +// bias in a way that the values that separate coplanar geometry on the guest +// qualitatively also still correctly separate them on the host. +// +// It also should be taken into account that on Xenia, float32 depth values may +// be snapped to float24 directly in the translated pixel shaders (to prevent +// data loss if after reuploading a depth buffer to the EDRAM there's no way to +// recover the full-precision value, that results in the inability to perform +// more rendering passes for the same geometry), and not only to the nearest +// value, but also just truncating them (so in case of data loss, the "greater +// or equal" depth test function still works). +// +// Because of this, the depth bias may be lost if Xenia translates it into a too +// small value, and the conversion of the depth is done in the pixel shader. +// Specifically, Xenia should not simply convert a value that separates coplanar +// primitives as float24 just into something that still separates them as +// float32. Essentially, if conversion to float24 is done in the pixel shader, +// Xenia should make sure the polygon offset on the host is calculated as if the +// host had float24 depth too, not float32. + +// Applies to both native host unorm24, and unorm24 emulated as host float32. +// For native unorm24, this is exactly the inverse of the minimum representable +// non-zero value. +// For unorm24 emulated as float32, the minimum representable non-zero value for +// a primitive in the [0.5, 1) range (the worst case that forward depth reaches +// very quickly, at nearly `2 * near clipping plane distance`) is 2 ^ (-1 - 23), +// or 2^-24, and this factor is almost 2^24. +constexpr float kD3D10PolygonOffsetFactorUnorm24 = float((UINT32_C(1) << 24) - 1); + +// For a host floating-point depth buffer, the integer value of the depth bias +// is roughly how many ULPs primitives should be separated by. +// +// Float24, however, has 3 mantissa bits fewer than float32 - so one float24 ULP +// corresponds to 8 float32 ULPs - which means each conceptual "layer" of the +// guest value should correspond to a polygon offset of 8. So, after the guest +// absolute value is converted to "layers", it should be multiplied by 8 before +// being used on the host with a float32 depth buffer. +// +// The scale for converting the guest absolute depth bias to the "layers" needs +// to be determined for the worst case - specifically, the [0.5, 1) range (1 is +// a single value, so there's no need to take it into consideration). In this +// range, Z values have the exponent of -1. Therefore, for float24, the absolute +// offset is obtained from the "layer index" in this range as (disregarding the +// slope term): +// offset = 2 ^ (-1 - 20) * constant factor +// Thus, to obtain the constant factor from the absolute offset in the range +// with the lowest absolute precision, the offset needs to be multiplied by +// 2^21. +// +// Finally, the 0...0.5 range may be used on the host to represent the 0...1 +// guest depth range to be able to copy all possible encodings, which are +// [0, 2), via a [0, 1] depth output variable, during EDRAM contents +// reinterpretation. This is done by scaling the viewport depth bounds by 0.5. +// However, there's no need to do anything to handle this scenario in the +// polygon offset - it's calculated after applying the viewport transformation, +// and the maximum Z value in the primitive will have an exponent lowered by 1, +// thus the result will also have an exponent lowered by 1 - exactly what's +// needed for remapping 0...1 to 0...0.5. +constexpr float kD3D10PolygonOffsetFactorFloat24 = float(UINT32_C(1) << (21 + 3)); + +inline int32_t GetD3D10IntegerPolygonOffset(xenos::DepthRenderTargetFormat depth_format, + float polygon_offset) { + bool is_float24 = depth_format == xenos::DepthRenderTargetFormat::kD24FS8; + // Using `ceil` because more offset is better, especially if flooring would + // result in 0 - conceptually, if the offset is used at all, primitives need + // to be separated in the depth buffer. + int32_t polygon_offset_int = int32_t(std::ceil( + std::abs(polygon_offset) * (is_float24 ? kD3D10PolygonOffsetFactorFloat24 * (1.0f / 8.0f) + : kD3D10PolygonOffsetFactorUnorm24))); + // For float24, the conversion may be done in the translated pixel shaders, + // including via truncation rather than rounding to the nearest. So, making + // the integer bias always in the increments of 2^3 (2 ^ the difference in the + // mantissa bit count between float32 and float24), and because of that, doing + // `ceil` before changing the units from float24 ULPs to float32 ULPs. + if (is_float24) { + polygon_offset_int <<= 3; + } + return polygon_offset < 0 ? -polygon_offset_int : polygon_offset_int; +} + +// For hosts not supporting separate front and back polygon offsets, returns the +// polygon offset for the face which likely needs the offset the most (and that +// will not be culled). The values returned will have the units of the original +// registers (the scale is for 1/16 subpixels, multiply by +// xenos::kPolygonOffsetScaleSubpixelUnit outside if the value for pixels is +// needed). +void GetPreferredFacePolygonOffset(const RegisterFile& regs, bool primitive_polygonal, + float& scale_out, float& offset_out); + +inline bool DoesCoverageDependOnAlpha(reg::RB_COLORCONTROL rb_colorcontrol) { + return (rb_colorcontrol.alpha_test_enable && + rb_colorcontrol.alpha_func != xenos::CompareFunction::kAlways) || + rb_colorcontrol.alpha_to_mask_enable; +} + +// Whether the pixel shader can be disabled on the host to speed up depth +// pre-passes and shadowmaps. The shader must have its ucode analyzed. If +// IsRasterizationPotentiallyDone, this shouldn't be called, and assumed false +// instead. Helps reject the pixel shader in some cases - memexport draws in +// 4D5307E6, and also most of some 1-point draws not covering anything done for +// some reason in different games with a leftover pixel shader from the previous +// draw, but with SQ_PROGRAM_CNTL destroyed, reducing the number of +// unpredictable unneeded translations of random shaders with different host +// modification bits, such as register count and depth format-related. +// include_memory_export may be set to false to evaluate whether the pixel +// shader has any side effects other than memexport. +bool IsPixelShaderNeededWithRasterization(const Shader& shader, const RegisterFile& regs, + bool include_memory_export = true); + +struct ViewportInfo { + // Offset from render target UV = 0 to +UV. + // For simplicity of cropping to the maximum size on the host; to match the + // Direct3D 12 clipping / scissoring behavior with a fractional viewport, to + // floor(TopLeftXY) ... floor(TopLeftXY + WidthHeight), on the real AMD, Intel + // and Nvidia hardware (not WARP); as well as to hide the differences between + // 0 and 8+ viewportSubPixelBits on Vulkan, and to prevent any numerical error + // in bound checking in host APIs, viewport bounds are returned as integers. + // Also they're returned as non-negative, also to make it easier to crop (so + // Vulkan maxViewportDimensions and viewportBoundsRange don't have to be + // handled separately - maxViewportDimensions is greater than or equal to the + // largest framebuffer image size, so it's safe, and viewportBoundsRange is + // always bigger than maxViewportDimensions. All fractional offsetting, + // including the half-pixel offset, and cropping are handled via ndc_scale and + // ndc_offset. + uint32_t xy_offset[2]; + // Extent can be zero for an empty viewport - host APIs not supporting empty + // viewports need to use an empty scissor rectangle. + uint32_t xy_extent[2]; + float z_min; + float z_max; + // The scale is applied before the offset (like using multiply-add). + float ndc_scale[3]; + float ndc_offset[3]; +}; +// Converts the guest viewport (or fakes one if drawing without a viewport) to +// a viewport, plus values to multiply-add the returned position by, usable on +// host graphics APIs such as Direct3D 11+ and Vulkan, also forcing it to the +// Direct3D clip space with 0...W Z rather than -W...W. +void GetHostViewportInfo(const RegisterFile& regs, uint32_t draw_resolution_scale_x, + uint32_t draw_resolution_scale_y, bool origin_bottom_left, uint32_t x_max, + uint32_t y_max, bool allow_reverse_z, + reg::RB_DEPTHCONTROL normalized_depth_control, bool convert_z_to_float24, + bool full_float24_in_0_to_1, bool pixel_shader_writes_depth, + ViewportInfo& viewport_info_out); + +struct Scissor { + // Offset from render target UV = 0 to +UV. + uint32_t offset[2]; + // Extent can be zero. + uint32_t extent[2]; +}; +void GetScissor(const RegisterFile& regs, Scissor& scissor_out, bool clamp_to_surface_pitch = true); + +// Returns the color component write mask for the draw command taking into +// account which color targets are written to by the pixel shader, as well as +// components that don't exist in the formats of the render targets (render +// targets with only non-existent components written are skipped, but +// non-existent components are forced to written if some existing components of +// the render target are actually used to make sure the host driver doesn't try +// to take a slow path involving reading and mixing if there are any disabled +// components even if they don't actually exist). +uint32_t GetNormalizedColorMask(const RegisterFile& regs, + uint32_t pixel_shader_writes_color_targets); + +// Never an identity conversion - can always write conditional move instructions +// to shaders that will be no-ops for conversion from guest to host samples. +// While we don't know the exact guest sample pattern, due to the way +// multisampled render targets are stored in the memory (like 1x2 single-sampled +// pixels with 2x MSAA, or like 2x2 single-sampled pixels with 4x), assuming +// that the sample 0 is the top sample, and the sample 1 is the bottom one. +inline uint32_t GetD3D10SampleIndexForGuest2xMSAA(uint32_t guest_sample_index, + bool native_2x_msaa_supported) { + assert(guest_sample_index <= 1); + if (native_2x_msaa_supported) { + // On Direct3D 10.1 with native 2x MSAA, the top-left sample is 1, and the + // bottom-right sample is 0. + return guest_sample_index ? 0 : 1; + } + // When native 2x MSAA is not supported, using the top-left (0) and the + // bottom-right (3) samples of the guaranteed 4x MSAA. + return guest_sample_index ? 3 : 0; +} + +struct MemExportRange { + uint32_t base_address_dwords; + uint32_t size_bytes; + + explicit MemExportRange(uint32_t base_address_dwords, uint32_t size_bytes) + : base_address_dwords(base_address_dwords), size_bytes(size_bytes) {} +}; + +// Gathers memory ranges involved in memexports in the shader with the float +// constants from the registers, adding them to ranges_out. +void AddMemExportRanges(const RegisterFile& regs, const Shader& shader, + std::vector& ranges_out); + +// To avoid passing values that the shader won't understand (even though +// Direct3D 9 shouldn't pass them anyway). +xenos::CopySampleSelect SanitizeCopySampleSelect(xenos::CopySampleSelect copy_sample_select, + xenos::MsaaSamples msaa_samples, bool is_depth); + +// Packed structures are small and can be passed to the shaders in root/push +// constants. + +union ResolveEdramInfo { + uint32_t packed; + struct { + // With 32bpp/64bpp taken into account. + uint32_t pitch_tiles : xenos::kEdramPitchTilesBits; + xenos::MsaaSamples msaa_samples : xenos::kMsaaSamplesBits; + uint32_t is_depth : 1; + // With offset to the region that edram_offset_x/y_div_8 are relative to. + uint32_t base_tiles : xenos::kEdramBaseTilesBits; + uint32_t format : xenos::kRenderTargetFormatBits; + uint32_t format_is_64bpp : 1; + // Whether to fill the half-pixel offset gap on the left and the top sides + // of the resolve region with the contents of the first surely covered + // column / row with resolution scaling. + uint32_t fill_half_pixel_offset : 1; + }; + ResolveEdramInfo() : packed(0) { static_assert_size(*this, sizeof(packed)); } +}; + +union ResolveCoordinateInfo { + uint32_t packed; + struct { + // In pixels relatively to the origin of the EDRAM base tile. + // 0...9 for 0...72. + uint32_t edram_offset_x_div_8 : 4; + // 0...1 for 0...8. + uint32_t edram_offset_y_div_8 : 1; + + // In pixels. + // May be zero if the original rectangle was somehow specified in a + // totally broken way - in this case, the resolve must be dropped. + uint32_t width_div_8 : xenos::kResolveSizeBits - xenos::kResolveAlignmentPixelsLog2; + + // 1 to 7. + uint32_t draw_resolution_scale_x : 3; + uint32_t draw_resolution_scale_y : 3; + }; + ResolveCoordinateInfo() : packed(0) { static_assert_size(*this, sizeof(packed)); } +}; + +// Returns tiles actually covered by a resolve area. Row length used is width of +// the area in tiles, but the pitch between rows is edram_info.pitch_tiles. +void GetResolveEdramTileSpan(ResolveEdramInfo edram_info, ResolveCoordinateInfo coordinate_info, + uint32_t height_div_8, uint32_t& base_out, + uint32_t& row_length_used_out, uint32_t& rows_out); + +union ResolveCopyDestCoordinateInfo { + uint32_t packed; + struct { + // 0...16384/32. + uint32_t pitch_aligned_div_32 : xenos::kTexture2DCubeMaxWidthHeightLog2 + 2 - + xenos::kTextureTileWidthHeightLog2; + uint32_t height_aligned_div_32 : xenos::kTexture2DCubeMaxWidthHeightLog2 + 2 - + xenos::kTextureTileWidthHeightLog2; + + // Up to the maximum period of the texture tiled address function (128x128 + // for 2D 1bpb). + uint32_t offset_x_div_8 : 7 - xenos::kResolveAlignmentPixelsLog2; + uint32_t offset_y_div_8 : 7 - xenos::kResolveAlignmentPixelsLog2; + + xenos::CopySampleSelect copy_sample_select : 3; + }; + ResolveCopyDestCoordinateInfo() : packed(0) { static_assert_size(*this, sizeof(packed)); } +}; + +// For backends with Shader Model 5-like compute, host shaders to use to perform +// copying in resolve operations. +enum class ResolveCopyShaderIndex { + kFast32bpp1x2xMSAA, + kFast32bpp4xMSAA, + kFast64bpp1x2xMSAA, + kFast64bpp4xMSAA, + + kFull8bpp, + kFull16bpp, + kFull32bpp, + kFull64bpp, + kFull128bpp, + + kCount, + kUnknown = kCount, +}; + +struct ResolveCopyShaderInfo { + // Debug name of the pipeline state object with this shader. + const char* debug_name; + // Whether the EDRAM source needs be bound as a raw buffer (ByteAddressBuffer + // in Direct3D) since it can load different numbers of 32-bit values at once + // on some hardware. If the host API doesn't support raw buffers, a typed + // buffer with source_bpe_log2-byte elements needs to be used instead. + bool source_is_raw; + // Log2 of bytes per element of the type of the EDRAM buffer bound to the + // shader (at least 2). + uint32_t source_bpe_log2; + // Log2 of bytes per element of the type of the destination buffer bound to + // the shader (at least 2 because of the 128 megatexel minimum requirement on + // Direct3D 10+ - D3D12_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP - that + // prevents binding the entire shared memory buffer with smaller element + // sizes). + uint32_t dest_bpe_log2; + // Log2 of number of pixels in a single thread group along X and Y. 64 threads + // per group preferred (GCN lane count). + uint32_t group_size_x_log2, group_size_y_log2; +}; + +extern const ResolveCopyShaderInfo resolve_copy_shader_info[size_t(ResolveCopyShaderIndex::kCount)]; + +struct ResolveCopyShaderConstants { + // When the destination base is not needed (not binding the entire shared + // memory buffer - with resoluion scaling, for instance), only the + // DestRelative part may be passed to the shader to use less constants. + struct DestRelative { + ResolveEdramInfo edram_info; + ResolveCoordinateInfo coordinate_info; + reg::RB_COPY_DEST_INFO dest_info; + ResolveCopyDestCoordinateInfo dest_coordinate_info; + }; + DestRelative dest_relative; + uint32_t dest_base; +}; + +struct ResolveClearShaderConstants { + // rt_specific is different for color and depth, the rest is the same and can + // be preserved in the root bindings when going from depth to color. + struct RenderTargetSpecific { + uint32_t clear_value[2]; + ResolveEdramInfo edram_info; + }; + RenderTargetSpecific rt_specific; + ResolveCoordinateInfo coordinate_info; +}; + +struct ResolveInfo { + reg::RB_COPY_CONTROL rb_copy_control; + + // depth_edram_info / depth_original_base and color_edram_info / + // color_original_base are set up if copying or clearing color and depth + // respectively, according to RB_COPY_CONTROL. + ResolveEdramInfo depth_edram_info; + ResolveEdramInfo color_edram_info; + // Original bases, without adjustment to a 160x32 region for packed offsets, + // for locating host render targets to perform clears if host render targets + // are used for EDRAM emulation - the same as the base that the render target + // will likely be used for drawing next, to prevent unneeded tile ownership + // transfers between clears and first usage if clearing a subregion. + uint32_t depth_original_base; + uint32_t color_original_base; + + ResolveCoordinateInfo coordinate_info; + // Like coordinate_info.width_div_8, but not needed for shaders. + // In pixels. + // May be zero if the original rectangle was somehow specified in a totally + // broken way - in this case, the resolve must be dropped. + uint32_t height_div_8; + + reg::RB_COPY_DEST_INFO copy_dest_info; + ResolveCopyDestCoordinateInfo copy_dest_coordinate_info; + + // The address of the texture or the location within the texture that + // copy_dest_coordinate_info.offset_x/y_div_8 - the origin of the copy + // destination - is relative to. + uint32_t copy_dest_base; + // Memory range that will potentially be modified by copying to the texture. + // copy_dest_extent_length may be zero if something is wrong with the + // destination, in this case, clearing may still be done, but copying must be + // dropped. + uint32_t copy_dest_extent_start; + uint32_t copy_dest_extent_length; + + // The clear shaders always write to a uint4 view of EDRAM. + uint32_t rb_depth_clear; + uint32_t rb_color_clear; + uint32_t rb_color_clear_lo; + + bool IsCopyingDepth() const { + return rb_copy_control.copy_src_select >= xenos::kMaxColorRenderTargets; + } + + // See GetResolveEdramTileSpan documentation for explanation. + void GetCopyEdramTileSpan(uint32_t& base_out, uint32_t& row_length_used_out, uint32_t& rows_out, + uint32_t& pitch_out) const { + ResolveEdramInfo edram_info = IsCopyingDepth() ? depth_edram_info : color_edram_info; + GetResolveEdramTileSpan(edram_info, coordinate_info, height_div_8, base_out, + row_length_used_out, rows_out); + pitch_out = edram_info.pitch_tiles; + } + + ResolveCopyShaderIndex GetCopyShader(uint32_t draw_resolution_scale_x, + uint32_t draw_resolution_scale_y, + ResolveCopyShaderConstants& constants_out, + uint32_t& group_count_x_out, + uint32_t& group_count_y_out) const; + + bool IsClearingDepth() const { return rb_copy_control.depth_clear_enable != 0; } + + bool IsClearingColor() const { + return !IsCopyingDepth() && rb_copy_control.color_clear_enable != 0; + } + + void GetDepthClearShaderConstants(ResolveClearShaderConstants& constants_out) const { + assert_true(IsClearingDepth()); + constants_out.rt_specific.clear_value[0] = rb_depth_clear; + constants_out.rt_specific.clear_value[1] = rb_depth_clear; + constants_out.rt_specific.edram_info = depth_edram_info; + constants_out.coordinate_info = coordinate_info; + } + + void GetColorClearShaderConstants(ResolveClearShaderConstants& constants_out) const { + assert_true(IsClearingColor()); + // Not doing -32...32 to -1...1 clamping here as a hack for k_16_16 and + // k_16_16_16_16 blending emulation when using host render targets as it + // would be inconsistent with the usual way of clearing with a depth quad. + // TODO(Triang3l): Check which 32-bit portion is in which register. + constants_out.rt_specific.clear_value[0] = rb_color_clear; + constants_out.rt_specific.clear_value[1] = rb_color_clear_lo; + constants_out.rt_specific.edram_info = color_edram_info; + constants_out.coordinate_info = coordinate_info; + } + + std::pair GetClearShaderGroupCount(uint32_t draw_resolution_scale_x, + uint32_t draw_resolution_scale_y) const { + // 8 guest MSAA samples per invocation. + uint32_t width_samples_div_8 = coordinate_info.width_div_8; + uint32_t height_samples_div_8 = height_div_8; + xenos::MsaaSamples samples = + IsCopyingDepth() ? depth_edram_info.msaa_samples : color_edram_info.msaa_samples; + if (samples >= xenos::MsaaSamples::k2X) { + height_samples_div_8 <<= 1; + if (samples >= xenos::MsaaSamples::k4X) { + width_samples_div_8 <<= 1; + } + } + width_samples_div_8 *= draw_resolution_scale_x; + height_samples_div_8 *= draw_resolution_scale_y; + return std::make_pair((width_samples_div_8 + uint32_t(7)) >> 3, height_samples_div_8); + } +}; + +// Returns false if there was an error obtaining the info making it totally +// invalid. fixed_rg[ba]16_truncated_to_minus_1_to_1 is false if 16_16[_16_16] +// color render target formats are properly emulated as -32...32, true if +// emulated as snorm, with range limited to -1...1, but with correct blending +// within that range. +bool GetResolveInfo(const RegisterFile& regs, const memory::Memory& memory, + TraceWriter& trace_writer, uint32_t draw_resolution_scale_x, + uint32_t draw_resolution_scale_y, bool fixed_rg16_truncated_to_minus_1_to_1, + bool fixed_rgba16_truncated_to_minus_1_to_1, ResolveInfo& info_out); + +} // namespace rex::graphics::draw_util diff --git a/include/rex/graphics/util/draw_extent_estimator.h b/include/rex/graphics/util/draw_extent_estimator.h new file mode 100644 index 0000000..d8ff8ec --- /dev/null +++ b/include/rex/graphics/util/draw_extent_estimator.h @@ -0,0 +1,71 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include +#include + +namespace rex::graphics { + +class DrawExtentEstimator { + public: + DrawExtentEstimator(const RegisterFile& register_file, const memory::Memory& memory, + TraceWriter* trace_writer) + : register_file_(register_file), + memory_(memory), + trace_writer_(trace_writer), + shader_interpreter_(register_file, memory) { + shader_interpreter_.SetTraceWriter(trace_writer); + } + + // The shader must have its ucode analyzed. + uint32_t EstimateVertexMaxY(const Shader& vertex_shader); + uint32_t EstimateMaxY(bool try_to_estimate_vertex_max_y, const Shader& vertex_shader); + + private: + class PositionYExportSink : public ShaderInterpreter::ExportSink { + public: + void Export(ucode::ExportRegister export_register, const float* value, + uint32_t value_mask) override; + + void Reset() { + position_y_.reset(); + position_w_.reset(); + point_size_.reset(); + vertex_kill_.reset(); + } + + const std::optional& position_y() const { return position_y_; } + const std::optional& position_w() const { return position_w_; } + const std::optional& point_size() const { return point_size_; } + const std::optional& vertex_kill() const { return vertex_kill_; } + + private: + std::optional position_y_; + std::optional position_w_; + std::optional point_size_; + std::optional vertex_kill_; + }; + + const RegisterFile& register_file_; + const memory::Memory& memory_; + TraceWriter* trace_writer_; + + ShaderInterpreter shader_interpreter_; +}; + +} // namespace rex::graphics diff --git a/include/rex/graphics/video_mode_util.h b/include/rex/graphics/video_mode_util.h new file mode 100644 index 0000000..004b8cf --- /dev/null +++ b/include/rex/graphics/video_mode_util.h @@ -0,0 +1,122 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2026 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include + +namespace rex::graphics::video_mode_util { + +inline bool TryParsePositiveInt32(std::string_view value, int32_t& value_out) { + if (value.empty()) { + return false; + } + + int32_t parsed_value = 0; + auto [parse_end, parse_error] = + std::from_chars(value.data(), value.data() + value.size(), parsed_value); + if (parse_error != std::errc() || parse_end != value.data() + value.size() || parsed_value <= 0) { + return false; + } + + value_out = parsed_value; + return true; +} + +inline bool TryParseResolutionPreset(std::string_view resolution_value, int32_t& width_out, + int32_t& height_out) { + std::string normalized; + normalized.reserve(resolution_value.size()); + for (char c : resolution_value) { + unsigned char c_unsigned = static_cast(c); + if (std::isspace(c_unsigned) || c == '_' || c == '-') { + continue; + } + normalized.push_back(char(std::tolower(c_unsigned))); + } + if (normalized.empty()) { + return false; + } + + size_t x_position = normalized.find('x'); + if (x_position != std::string::npos && x_position > 0 && x_position + 1 < normalized.size()) { + int32_t parsed_width = 0; + int32_t parsed_height = 0; + if (!TryParsePositiveInt32(std::string_view(normalized).substr(0, x_position), parsed_width) || + !TryParsePositiveInt32(std::string_view(normalized).substr(x_position + 1), + parsed_height)) { + return false; + } + width_out = parsed_width; + height_out = parsed_height; + return true; + } + + if (normalized == "480p") { + width_out = 640; + height_out = 480; + return true; + } + if (normalized == "540p") { + width_out = 960; + height_out = 540; + return true; + } + if (normalized == "720p") { + width_out = 1280; + height_out = 720; + return true; + } + if (normalized == "900p") { + width_out = 1600; + height_out = 900; + return true; + } + if (normalized == "1080p") { + width_out = 1920; + height_out = 1080; + return true; + } + if (normalized == "1440p") { + width_out = 2560; + height_out = 1440; + return true; + } + if (normalized == "1800p") { + width_out = 3200; + height_out = 1800; + return true; + } + if (normalized == "2160p" || normalized == "4k") { + width_out = 3840; + height_out = 2160; + return true; + } + return false; +} + +inline bool TryGetResolutionPresetFromCVar(int32_t& width_out, int32_t& height_out) { + if (!rex::cvar::HasNonDefaultValue("resolution")) { + return false; + } + const std::string& resolution_value = REXCVAR_GET(resolution); + if (resolution_value.empty()) { + return false; + } + return TryParseResolutionPreset(resolution_value, width_out, height_out); +} + +} // namespace rex::graphics::video_mode_util diff --git a/include/rex/graphics/vulkan/command_processor.h b/include/rex/graphics/vulkan/command_processor.h new file mode 100644 index 0000000..4b76791 --- /dev/null +++ b/include/rex/graphics/vulkan/command_processor.h @@ -0,0 +1,850 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::graphics::vulkan { + +class VulkanCommandProcessor : public CommandProcessor { + public: + // Single-descriptor layouts for use within a single frame. + enum class SingleTransientDescriptorLayout { + kStorageBufferCompute, + kStorageBufferPairCompute, + kCount, + }; + + class ScratchBufferAcquisition { + public: + explicit ScratchBufferAcquisition() = default; + explicit ScratchBufferAcquisition(VulkanCommandProcessor& command_processor, VkBuffer buffer, + VkPipelineStageFlags stage_mask, VkAccessFlags access_mask) + : command_processor_(&command_processor), + buffer_(buffer), + stage_mask_(stage_mask), + access_mask_(access_mask) {} + + ScratchBufferAcquisition(const ScratchBufferAcquisition& acquisition) = delete; + ScratchBufferAcquisition& operator=(const ScratchBufferAcquisition& acquisition) = delete; + + ScratchBufferAcquisition(ScratchBufferAcquisition&& acquisition) { + command_processor_ = acquisition.command_processor_; + buffer_ = acquisition.buffer_; + stage_mask_ = acquisition.stage_mask_; + access_mask_ = acquisition.access_mask_; + acquisition.command_processor_ = nullptr; + acquisition.buffer_ = VK_NULL_HANDLE; + acquisition.stage_mask_ = 0; + acquisition.access_mask_ = 0; + } + ScratchBufferAcquisition& operator=(ScratchBufferAcquisition&& acquisition) { + if (this == &acquisition) { + return *this; + } + command_processor_ = acquisition.command_processor_; + buffer_ = acquisition.buffer_; + stage_mask_ = acquisition.stage_mask_; + access_mask_ = acquisition.access_mask_; + acquisition.command_processor_ = nullptr; + acquisition.buffer_ = VK_NULL_HANDLE; + acquisition.stage_mask_ = 0; + acquisition.access_mask_ = 0; + return *this; + } + + ~ScratchBufferAcquisition() { + if (buffer_ != VK_NULL_HANDLE) { + assert_true(command_processor_->scratch_buffer_used_); + assert_true(command_processor_->scratch_buffer_ == buffer_); + command_processor_->scratch_buffer_last_stage_mask_ = stage_mask_; + command_processor_->scratch_buffer_last_access_mask_ = access_mask_; + command_processor_->scratch_buffer_last_usage_submission_ = + command_processor_->GetCurrentSubmission(); + command_processor_->scratch_buffer_used_ = false; + } + } + + // VK_NULL_HANDLE if failed to acquire or if moved. + VkBuffer buffer() const { return buffer_; } + + VkPipelineStageFlags GetStageMask() const { return stage_mask_; } + VkPipelineStageFlags SetStageMask(VkPipelineStageFlags new_stage_mask) { + VkPipelineStageFlags old_stage_mask = stage_mask_; + stage_mask_ = new_stage_mask; + return old_stage_mask; + } + VkAccessFlags GetAccessMask() const { return access_mask_; } + VkAccessFlags SetAccessMask(VkAccessFlags new_access_mask) { + VkAccessFlags old_access_mask = access_mask_; + access_mask_ = new_access_mask; + return old_access_mask; + } + + private: + VulkanCommandProcessor* command_processor_ = nullptr; + VkBuffer buffer_ = VK_NULL_HANDLE; + VkPipelineStageFlags stage_mask_ = 0; + VkAccessFlags access_mask_ = 0; + }; + + VulkanCommandProcessor(VulkanGraphicsSystem* graphics_system, system::KernelState* kernel_state); + ~VulkanCommandProcessor(); + + void ClearCaches() override; + void InvalidateGpuMemory() override; + void InitializeShaderStorage(const std::filesystem::path& cache_root, uint32_t title_id, + bool blocking) override; + + void TracePlaybackWroteMemory(uint32_t base_ptr, uint32_t length) override; + + void RestoreEdramSnapshot(const void* snapshot) override; + + ui::vulkan::VulkanDevice* GetVulkanDevice() const { + return static_cast(graphics_system_->provider()) + ->vulkan_device(); + } + + bool CompileGlslToSpirv(VkShaderStageFlagBits stage, std::string_view source, + std::vector& spirv_out, std::string& error_out) const; + + // Returns the deferred drawing command list for the currently open + // submission. + DeferredCommandBuffer& deferred_command_buffer() { + assert_true(submission_open_); + return deferred_command_buffer_; + } + + bool submission_open() const { return submission_open_; } + uint64_t GetCurrentSubmission() const { + return submission_completed_ + uint64_t(submissions_in_flight_fences_.size()) + 1; + } + uint64_t GetCompletedSubmission() const { return submission_completed_; } + + // Sparse binds are: + // - In a single submission, all submitted in one vkQueueBindSparse. + // - Sent to the queue without waiting for a semaphore. + // Thus, multiple sparse binds between the completed and the current + // submission, and within one submission, must not touch any overlapping + // memory regions. + void SparseBindBuffer(VkBuffer buffer, uint32_t bind_count, const VkSparseMemoryBind* binds, + VkPipelineStageFlags wait_stage_mask); + + uint64_t GetCurrentFrame() const { return frame_current_; } + uint64_t GetCompletedFrame() const { return frame_completed_; } + + // Submission must be open to insert barriers. If no pipeline stages access + // the resource in a synchronization scope, the stage masks should be 0 (top / + // bottom of pipe should be specified only if explicitly needed). Returning + // true if the barrier has actually been inserted and not dropped. + bool PushBufferMemoryBarrier(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size, + VkPipelineStageFlags src_stage_mask, + VkPipelineStageFlags dst_stage_mask, VkAccessFlags src_access_mask, + VkAccessFlags dst_access_mask, + uint32_t src_queue_family_index = VK_QUEUE_FAMILY_IGNORED, + uint32_t dst_queue_family_index = VK_QUEUE_FAMILY_IGNORED, + bool skip_if_equal = true); + bool PushImageMemoryBarrier(VkImage image, const VkImageSubresourceRange& subresource_range, + VkPipelineStageFlags src_stage_mask, + VkPipelineStageFlags dst_stage_mask, VkAccessFlags src_access_mask, + VkAccessFlags dst_access_mask, VkImageLayout old_layout, + VkImageLayout new_layout, + uint32_t src_queue_family_index = VK_QUEUE_FAMILY_IGNORED, + uint32_t dst_queue_family_index = VK_QUEUE_FAMILY_IGNORED, + bool skip_if_equal = true); + // Returns whether any barriers have been submitted - if true is returned, the + // render pass will also be closed. + bool SubmitBarriers(bool force_end_render_pass); + + // If not started yet, begins a render pass from the render target cache. + // Submission must be open. + void SubmitBarriersAndEnterRenderTargetCacheRenderPass( + VkRenderPass render_pass, const VulkanRenderTargetCache::Framebuffer* framebuffer); + // Overload for transfer operations with dynamic rendering. + void SubmitBarriersAndEnterRenderTargetCacheRenderPass( + VkRenderPass render_pass, const VulkanRenderTargetCache::Framebuffer* framebuffer, + VkImageView transfer_dest_view, bool transfer_dest_is_depth); + // Must be called before doing anything outside the render pass scope, + // including adding pipeline barriers that are not a part of the render pass + // scope. Submission must be open. + void EndRenderPass(); + + VkDescriptorSetLayout GetSingleTransientDescriptorLayout( + SingleTransientDescriptorLayout transient_descriptor_layout) const { + return descriptor_set_layouts_single_transient_[size_t(transient_descriptor_layout)]; + } + // A frame must be open. + VkDescriptorSet AllocateSingleTransientDescriptor( + SingleTransientDescriptorLayout transient_descriptor_layout); + + // The returned reference is valid until a cache clear. + VkDescriptorSetLayout GetTextureDescriptorSetLayout(bool is_vertex, size_t texture_count, + size_t sampler_count); + // The returned reference is valid until a cache clear. + const VulkanPipelineCache::PipelineLayoutProvider* GetPipelineLayout(size_t texture_count_pixel, + size_t sampler_count_pixel, + size_t texture_count_vertex, + size_t sampler_count_vertex); + + // Returns a single temporary GPU-side buffer within a submission for tasks + // like texture untiling and resolving. May push a buffer memory barrier into + // the initial usage. Submission must be open. + ScratchBufferAcquisition AcquireScratchGpuBuffer(VkDeviceSize size, + VkPipelineStageFlags initial_stage_mask, + VkAccessFlags initial_access_mask); + + // Binds a graphics pipeline for host-specific purposes, invalidating the + // affected state. keep_dynamic_* must be false (to invalidate the dynamic + // state after binding the pipeline with the same state being static, or if + // the caller changes the dynamic state bypassing the VulkanCommandProcessor) + // unless the caller has these state variables as dynamic and uses the + // tracking in VulkanCommandProcessor to modify them. + void BindExternalGraphicsPipeline(VkPipeline pipeline, bool keep_dynamic_depth_bias = false, + bool keep_dynamic_blend_constants = false, + bool keep_dynamic_stencil_mask_ref = false); + void BindExternalComputePipeline(VkPipeline pipeline); + void SetViewport(const VkViewport& viewport); + void SetScissor(const VkRect2D& scissor); + + // Returns the text to display in the GPU backend name in the window title. + std::string GetWindowTitleText() const; + + protected: + bool SetupContext() override; + void ShutdownContext() override; + + void WriteRegister(uint32_t index, uint32_t value) override; + void WriteRegistersFromMem(uint32_t start_index, uint32_t* base, uint32_t num_registers) override; + bool ExecutePacketType3_EVENT_WRITE_ZPD(memory::RingBuffer* reader, uint32_t packet, + uint32_t count) override; + + void OnGammaRamp256EntryTableValueWritten() override; + void OnGammaRampPWLValueWritten() override; + void OnPrimaryBufferEnd() override; + + void IssueSwap(uint32_t frontbuffer_ptr, uint32_t frontbuffer_width, + uint32_t frontbuffer_height) override; + + Shader* LoadShader(xenos::ShaderType shader_type, uint32_t guest_address, + const uint32_t* host_address, uint32_t dword_count) override; + + bool IssueDraw(xenos::PrimitiveType prim_type, uint32_t index_count, + IndexBufferInfo* index_buffer_info, bool major_mode_explicit) override; + bool IssueCopy() override; + + void InitializeTrace() override; + + private: + struct CommandBuffer { + VkCommandPool pool; + VkCommandBuffer buffer; + }; + + struct SparseBufferBind { + VkBuffer buffer; + size_t bind_offset; + uint32_t bind_count; + }; + + union TextureDescriptorSetLayoutKey { + uint32_t key; + struct { + // If texture and sampler counts are both 0, use + // descriptor_set_layout_empty_ instead as these are owning references. + uint32_t texture_count : 16; + uint32_t sampler_count : 15; + uint32_t is_vertex : 1; + }; + + TextureDescriptorSetLayoutKey() : key(0) { static_assert_size(*this, sizeof(key)); } + + struct Hasher { + size_t operator()(const TextureDescriptorSetLayoutKey& key) const { + return std::hash{}(key.key); + } + }; + bool operator==(const TextureDescriptorSetLayoutKey& other_key) const { + return key == other_key.key; + } + bool operator!=(const TextureDescriptorSetLayoutKey& other_key) const { + return !(*this == other_key); + } + }; + + union PipelineLayoutKey { + uint64_t key; + struct { + // Pixel textures in the low bits since those are varied much more + // commonly. + uint16_t texture_count_pixel; + uint16_t sampler_count_pixel; + uint16_t texture_count_vertex; + uint16_t sampler_count_vertex; + }; + + PipelineLayoutKey() : key(0) { static_assert_size(*this, sizeof(key)); } + + struct Hasher { + size_t operator()(const PipelineLayoutKey& key) const { + return std::hash{}(key.key); + } + }; + bool operator==(const PipelineLayoutKey& other_key) const { return key == other_key.key; } + bool operator!=(const PipelineLayoutKey& other_key) const { return !(*this == other_key); } + }; + + class PipelineLayout : public VulkanPipelineCache::PipelineLayoutProvider { + public: + explicit PipelineLayout(VkPipelineLayout pipeline_layout, + VkDescriptorSetLayout descriptor_set_layout_textures_vertex_ref, + VkDescriptorSetLayout descriptor_set_layout_textures_pixel_ref) + : pipeline_layout_(pipeline_layout), + descriptor_set_layout_textures_vertex_ref_(descriptor_set_layout_textures_vertex_ref), + descriptor_set_layout_textures_pixel_ref_(descriptor_set_layout_textures_pixel_ref) {} + VkPipelineLayout GetPipelineLayout() const override { return pipeline_layout_; } + VkDescriptorSetLayout descriptor_set_layout_textures_vertex_ref() const { + return descriptor_set_layout_textures_vertex_ref_; + } + VkDescriptorSetLayout descriptor_set_layout_textures_pixel_ref() const { + return descriptor_set_layout_textures_pixel_ref_; + } + + private: + VkPipelineLayout pipeline_layout_; + VkDescriptorSetLayout descriptor_set_layout_textures_vertex_ref_; + VkDescriptorSetLayout descriptor_set_layout_textures_pixel_ref_; + }; + + struct UsedSingleTransientDescriptor { + uint64_t frame; + SingleTransientDescriptorLayout layout; + VkDescriptorSet set; + }; + + struct UsedTextureTransientDescriptorSet { + uint64_t frame; + TextureDescriptorSetLayoutKey layout; + VkDescriptorSet set; + }; + + enum SwapApplyGammaDescriptorSet : uint32_t { + kSwapApplyGammaDescriptorSetRamp, + kSwapApplyGammaDescriptorSetSource, + + kSwapApplyGammaDescriptorSetCount, + }; + enum SwapApplyGammaComputeDescriptorSet : uint32_t { + kSwapApplyGammaComputeDescriptorSetRamp, + kSwapApplyGammaComputeDescriptorSetSource, + kSwapApplyGammaComputeDescriptorSetDestination, + + kSwapApplyGammaComputeDescriptorSetCount, + }; + struct SwapApplyGammaConstants { + uint32_t size[2]; + }; + enum SwapFxaaDescriptorSet : uint32_t { + kSwapFxaaDescriptorSetSource, + kSwapFxaaDescriptorSetDestination, + + kSwapFxaaDescriptorSetCount, + }; + struct SwapFxaaConstants { + uint32_t size[2]; + float size_inv[2]; + }; + + // Framebuffer for the current presenter's guest output image revision, and + // its usage tracking. + struct SwapFramebuffer { + VkFramebuffer framebuffer = VK_NULL_HANDLE; + uint64_t version = UINT64_MAX; + uint64_t last_submission = 0; + }; + + // BeginSubmission and EndSubmission may be called at any time. If there's an + // open non-frame submission, BeginSubmission(true) will promote it to a + // frame. EndSubmission(true) will close the frame no matter whether the + // submission has already been closed. + // Unlike on Direct3D 12, submission boundaries do not imply any memory + // barriers aside from an incoming host write (but not outgoing host read) + // dependency. + + // Rechecks submission number and reclaims per-submission resources. Pass 0 as + // the submission to await to simply check status, or pass + // GetCurrentSubmission() to wait for all queue operations to be completed. + void CheckSubmissionFenceAndDeviceLoss(uint64_t await_submission); + // If is_guest_command is true, a new full frame - with full cleanup of + // resources and, if needed, starting capturing - is opened if pending (as + // opposed to simply resuming after mid-frame synchronization). Returns + // whether a submission is open currently and the device is not lost. + bool BeginSubmission(bool is_guest_command); + // If is_swap is true, a full frame is closed - with, if needed, cache + // clearing and stopping capturing. Returns whether the submission was done + // successfully, if it has failed, leaves it open. + bool EndSubmission(bool is_swap); + bool AwaitAllQueueOperationsCompletion() { + CheckSubmissionFenceAndDeviceLoss(GetCurrentSubmission()); + return !submission_open_ && submissions_in_flight_fences_.empty(); + } + // Keep primary-buffer-end submit behavior aligned with D3D12: only submit + // when immediate submission is safe. + bool CanEndSubmissionImmediately() const; + + void ClearTransientDescriptorPools(); + bool IssueCopy_ReadbackResolvePath(); + bool IssueDraw_MemexportReadbackFullPath(uint32_t total_size); + bool IssueDraw_MemexportReadbackFastPath(uint32_t total_size); + + void SplitPendingBarrier(); + + void DestroyScratchBuffer(); + bool InitializeOcclusionQueryResources(); + void ShutdownOcclusionQueryResources(); + bool BeginGuestOcclusionQuery(uint32_t sample_count_address); + bool EndGuestOcclusionQuery(uint32_t sample_count_address); + bool AcquireOcclusionQueryIndex(uint32_t& host_index_out); + void DisableHostOcclusionQueries(); + uint64_t NormalizeOcclusionSamples(uint64_t samples) const; + void WriteGuestOcclusionResult(uint32_t sample_count_address, uint64_t samples); + void InvalidateAllVertexBufferResidency(); + void InvalidateVertexBufferResidency(uint32_t vfetch_index); + void InvalidateVertexBufferResidencyRange(uint32_t first_vfetch, uint32_t last_vfetch); + struct ReadbackBuffer { + VkBuffer buffers[2] = {VK_NULL_HANDLE, VK_NULL_HANDLE}; + VkDeviceMemory memories[2] = {VK_NULL_HANDLE, VK_NULL_HANDLE}; + void* mapped_data[2] = {nullptr, nullptr}; + uint32_t sizes[2] = {0, 0}; + uint64_t submission_written[2] = {0, 0}; + uint32_t written_size[2] = {0, 0}; + uint32_t current_index = 0; + uint64_t last_used_frame = 0; + }; + void EvictOldReadbackBuffers(std::unordered_map& buffer_map); + static constexpr uint32_t kReadbackBufferSizeIncrement = 16 * 1024 * 1024; + static constexpr size_t kMaxReadbackBuffers = 256; + static constexpr uint64_t kReadbackBufferEvictionAgeFrames = 60; + static inline uint32_t AlignReadbackBufferSize(uint32_t size) { + if (size < 1 * 1024 * 1024) { + return rex::align(size, 256u * 1024u); + } + if (size < 4 * 1024 * 1024) { + return rex::align(size, 1u * 1024u * 1024u); + } + return rex::align(size, kReadbackBufferSizeIncrement); + } + static inline uint64_t MakeReadbackResolveKey(uint32_t address, uint32_t length) { + return (uint64_t(address) << 32) | uint64_t(length); + } + static inline uint64_t MakeMemexportReadbackKey(uint32_t first_base_address_dwords, + uint32_t total_size) { + return (uint64_t(first_base_address_dwords) << 32) | uint64_t(total_size); + } + struct ResolveDownscaleConstants { + uint32_t scale_x; + uint32_t scale_y; + uint32_t pixel_size_log2; + uint32_t tile_count; + uint32_t source_offset_bytes; + uint32_t half_pixel_offset; + }; + bool EnsureSwapFxaaSourceImage(uint32_t width, uint32_t height); + void DestroySwapFxaaSourceImage(); + + void UpdateDynamicState(const draw_util::ViewportInfo& viewport_info, bool primitive_polygonal, + reg::RB_DEPTHCONTROL normalized_depth_control); + void UpdateSystemConstantValues( + bool primitive_polygonal, + const PrimitiveProcessor::ProcessingResult& primitive_processing_result, + bool shader_32bit_index_dma, uint32_t compute_memexport_vertex_count, + const draw_util::ViewportInfo& viewport_info, uint32_t used_texture_mask, + reg::RB_DEPTHCONTROL normalized_depth_control, uint32_t normalized_color_mask); + bool UpdateBindings(const VulkanShader* vertex_shader, const VulkanShader* pixel_shader); + // Allocates a descriptor set and fills one or two VkWriteDescriptorSet + // structure instances (for images and samplers). + // The descriptor set layout must be the one for the given is_vertex, + // texture_count, sampler_count (from GetTextureDescriptorSetLayout - may be + // already available at the moment of the call, no need to locate it again). + // Returns how many VkWriteDescriptorSet structure instances have been + // written, or 0 if there was a failure to allocate the descriptor set or no + // bindings were requested. + uint32_t WriteTransientTextureBindings(bool is_vertex, uint32_t texture_count, + uint32_t sampler_count, + VkDescriptorSetLayout descriptor_set_layout, + const VkDescriptorImageInfo* texture_image_info, + const VkDescriptorImageInfo* sampler_image_info, + VkWriteDescriptorSet* descriptor_set_writes_out); + + bool device_lost_ = false; + + bool cache_clear_requested_ = false; + + // Host shader types that guest shaders can be translated into - they can + // access the shared memory (via vertex fetch, memory export, or manual index + // buffer reading) and textures. + VkPipelineStageFlags guest_shader_pipeline_stages_ = 0; + VkShaderStageFlags guest_shader_vertex_stages_ = 0; + + std::vector fences_free_; + std::vector semaphores_free_; + + bool submission_open_ = false; + uint64_t submission_completed_ = 0; + // In case vkQueueSubmit fails after something like a successful + // vkQueueBindSparse, to wait correctly on the next attempt. + std::vector current_submission_wait_semaphores_; + std::vector current_submission_wait_stage_masks_; + std::vector submissions_in_flight_fences_; + std::deque> submissions_in_flight_semaphores_; + + static constexpr uint32_t kMaxFramesInFlight = 3; + bool frame_open_ = false; + // Tracks whether any draw in the current frame used an async placeholder + // graphics pipeline and may have produced incomplete output. + bool frame_used_async_placeholder_pipeline_ = false; + // Guest frame index, since some transient resources can be reused across + // submissions. Values updated in the beginning of a frame. + uint64_t frame_current_ = 1; + uint64_t frame_completed_ = 0; + // Submission indices of frames that have already been submitted. + uint64_t closed_frame_submissions_[kMaxFramesInFlight] = {}; + + // , sorted by the submission number. + std::deque> destroy_memory_; + std::deque> destroy_buffers_; + std::deque> destroy_image_views_; + std::deque> destroy_images_; + std::deque> destroy_framebuffers_; + + std::vector command_buffers_writable_; + std::deque> command_buffers_submitted_; + DeferredCommandBuffer deferred_command_buffer_; + + std::vector sparse_memory_binds_; + std::vector sparse_buffer_binds_; + // SparseBufferBind converted to VkSparseBufferMemoryBindInfo to this buffer + // on submission (because pBinds should point to a place in std::vector, but + // it may be reallocated). + std::vector sparse_buffer_bind_infos_temp_; + VkPipelineStageFlags sparse_bind_wait_stage_mask_ = 0; + + // Temporary storage with reusable memory for creating descriptor set layouts. + std::vector descriptor_set_layout_bindings_; + // Temporary storage with reusable memory for writing image and sampler + // descriptors. + std::vector descriptor_write_image_info_; + + std::unique_ptr uniform_buffer_pool_; + + // Descriptor set layouts used by different shaders. + VkDescriptorSetLayout descriptor_set_layout_empty_ = VK_NULL_HANDLE; + VkDescriptorSetLayout descriptor_set_layout_constants_ = VK_NULL_HANDLE; + std::array + descriptor_set_layouts_single_transient_{}; + VkDescriptorSetLayout descriptor_set_layout_shared_memory_and_edram_ = VK_NULL_HANDLE; + + // Descriptor set layouts are referenced by pipeline_layouts_. + std::unordered_map + descriptor_set_layouts_textures_; + // Pipeline layouts are referenced by VulkanPipelineCache. + std::unordered_map + pipeline_layouts_; + + // No specific reason for 32768, just the "too much" descriptor count from + // Direct3D 12 PIX warnings. + static constexpr uint32_t kLinkedTypeDescriptorPoolSetCount = 32768; + static const VkDescriptorPoolSize kDescriptorPoolSizeUniformBuffer; + static const VkDescriptorPoolSize kDescriptorPoolSizeStorageBuffer; + static const VkDescriptorPoolSize kDescriptorPoolSizeTextures[2]; + ui::vulkan::LinkedTypeDescriptorSetAllocator transient_descriptor_allocator_uniform_buffer_; + ui::vulkan::LinkedTypeDescriptorSetAllocator transient_descriptor_allocator_storage_buffer_; + std::deque single_transient_descriptors_used_; + std::array, size_t(SingleTransientDescriptorLayout::kCount)> + single_transient_descriptors_free_; + // . + std::deque> constants_transient_descriptors_used_; + std::vector constants_transient_descriptors_free_; + + ui::vulkan::LinkedTypeDescriptorSetAllocator transient_descriptor_allocator_textures_; + std::deque texture_transient_descriptor_sets_used_; + std::unordered_map, + TextureDescriptorSetLayoutKey::Hasher> + texture_transient_descriptor_sets_free_; + + std::unique_ptr shared_memory_; + + std::unique_ptr primitive_processor_; + + std::unique_ptr render_target_cache_; + + std::unique_ptr pipeline_cache_; + + std::unique_ptr texture_cache_; + + VkDescriptorPool shared_memory_and_edram_descriptor_pool_ = VK_NULL_HANDLE; + VkDescriptorSet shared_memory_and_edram_descriptor_set_; + + // Bytes 0x0...0x3FF - 256-entry gamma ramp table with B10G10R10X2 data (read + // as R10G10B10X2 with swizzle). + // Bytes 0x400...0x9FF - 128-entry PWL R16G16 gamma ramp (R - base, G - delta, + // low 6 bits of each are zero, 3 elements per entry). + // kMaxFramesInFlight pairs of gamma ramps if in host-visible memory and + // uploaded directly, one otherwise. + VkDeviceMemory gamma_ramp_buffer_memory_ = VK_NULL_HANDLE; + VkBuffer gamma_ramp_buffer_ = VK_NULL_HANDLE; + // kMaxFramesInFlight pairs, only when the gamma ramp buffer is not + // host-visible. + VkDeviceMemory gamma_ramp_upload_buffer_memory_ = VK_NULL_HANDLE; + VkBuffer gamma_ramp_upload_buffer_ = VK_NULL_HANDLE; + VkDeviceSize gamma_ramp_upload_memory_size_; + uint32_t gamma_ramp_upload_memory_type_; + // Mapping of either gamma_ramp_buffer_memory_ (if it's host-visible) or + // gamma_ramp_upload_buffer_memory_ (otherwise). + void* gamma_ramp_upload_mapping_; + std::array gamma_ramp_buffer_views_{}; + // UINT32_MAX if outdated. + uint32_t gamma_ramp_256_entry_table_current_frame_ = UINT32_MAX; + uint32_t gamma_ramp_pwl_current_frame_ = UINT32_MAX; + + VkDescriptorSetLayout swap_descriptor_set_layout_sampled_image_ = VK_NULL_HANDLE; + VkDescriptorSetLayout swap_descriptor_set_layout_combined_image_sampler_ = VK_NULL_HANDLE; + VkDescriptorSetLayout swap_descriptor_set_layout_storage_image_ = VK_NULL_HANDLE; + VkDescriptorSetLayout swap_descriptor_set_layout_uniform_texel_buffer_ = VK_NULL_HANDLE; + + // Descriptor pool for allocating descriptors needed for presentation, such as + // the destination images and the gamma ramps. + VkDescriptorPool swap_descriptor_pool_ = VK_NULL_HANDLE; + // Interleaved 256-entry table and PWL texel buffer descriptors. + // kMaxFramesInFlight pairs of gamma ramps if in host-visible memory and + // uploaded directly, one otherwise. + std::array swap_descriptors_gamma_ramp_; + // Sampled images. + std::array swap_descriptors_source_; + // Combined image sampler descriptors for FXAA. + std::array swap_descriptors_fxaa_source_; + // Storage image descriptors for the apply-gamma compute pass destination. + std::array swap_descriptors_destination_storage_; + // Separate storage image descriptors for the FXAA compute destination. + std::array swap_descriptors_fxaa_destination_storage_; + + VkSampler swap_sampler_linear_clamp_ = VK_NULL_HANDLE; + + VkPipelineLayout swap_apply_gamma_pipeline_layout_ = VK_NULL_HANDLE; + VkPipelineLayout swap_apply_gamma_compute_pipeline_layout_ = VK_NULL_HANDLE; + VkPipelineLayout swap_fxaa_pipeline_layout_ = VK_NULL_HANDLE; + // Has no dependencies on specific pipeline stages on both ends to simplify + // use in different scenarios with different pipelines - use explicit barriers + // for synchronization. + VkRenderPass swap_apply_gamma_render_pass_ = VK_NULL_HANDLE; + VkPipeline swap_apply_gamma_256_entry_table_pipeline_ = VK_NULL_HANDLE; + VkPipeline swap_apply_gamma_pwl_pipeline_ = VK_NULL_HANDLE; + VkPipeline swap_apply_gamma_256_entry_table_rb_swap_pipeline_ = VK_NULL_HANDLE; + VkPipeline swap_apply_gamma_pwl_rb_swap_pipeline_ = VK_NULL_HANDLE; + VkPipeline swap_apply_gamma_256_entry_table_fxaa_luma_pipeline_ = VK_NULL_HANDLE; + VkPipeline swap_apply_gamma_pwl_fxaa_luma_pipeline_ = VK_NULL_HANDLE; + VkPipeline swap_apply_gamma_compute_256_entry_table_pipeline_ = VK_NULL_HANDLE; + VkPipeline swap_apply_gamma_compute_pwl_pipeline_ = VK_NULL_HANDLE; + VkPipeline swap_apply_gamma_compute_256_entry_table_rb_swap_pipeline_ = VK_NULL_HANDLE; + VkPipeline swap_apply_gamma_compute_pwl_rb_swap_pipeline_ = VK_NULL_HANDLE; + VkPipeline swap_apply_gamma_compute_256_entry_table_fxaa_luma_pipeline_ = VK_NULL_HANDLE; + VkPipeline swap_apply_gamma_compute_pwl_fxaa_luma_pipeline_ = VK_NULL_HANDLE; + VkPipeline swap_apply_gamma_compute_256_entry_table_fxaa_luma_rb_swap_pipeline_ = VK_NULL_HANDLE; + VkPipeline swap_apply_gamma_compute_pwl_fxaa_luma_rb_swap_pipeline_ = VK_NULL_HANDLE; + VkPipeline swap_fxaa_pipeline_ = VK_NULL_HANDLE; + VkPipeline swap_fxaa_extreme_pipeline_ = VK_NULL_HANDLE; + VkPipelineLayout resolve_downscale_pipeline_layout_ = VK_NULL_HANDLE; + VkPipeline resolve_downscale_pipeline_ = VK_NULL_HANDLE; + VkBuffer resolve_downscale_buffer_ = VK_NULL_HANDLE; + VkDeviceMemory resolve_downscale_buffer_memory_ = VK_NULL_HANDLE; + uint32_t resolve_downscale_buffer_size_ = 0; + + VkImage swap_fxaa_source_image_ = VK_NULL_HANDLE; + VkDeviceMemory swap_fxaa_source_image_memory_ = VK_NULL_HANDLE; + VkImageView swap_fxaa_source_image_view_ = VK_NULL_HANDLE; + uint32_t swap_fxaa_source_image_width_ = 0; + uint32_t swap_fxaa_source_image_height_ = 0; + uint64_t swap_fxaa_source_image_submission_ = 0; + VkPipelineStageFlags swap_fxaa_source_stage_mask_ = 0; + VkAccessFlags swap_fxaa_source_access_mask_ = 0; + VkImageLayout swap_fxaa_source_layout_ = VK_IMAGE_LAYOUT_UNDEFINED; + + std::array + swap_framebuffers_; + + // Pending pipeline barriers. + std::vector pending_barriers_buffer_memory_barriers_; + std::vector pending_barriers_image_memory_barriers_; + struct PendingBarrier { + VkPipelineStageFlags src_stage_mask = 0; + VkPipelineStageFlags dst_stage_mask = 0; + size_t buffer_memory_barriers_offset = 0; + size_t image_memory_barriers_offset = 0; + }; + std::vector pending_barriers_; + PendingBarrier current_pending_barrier_; + + // GPU-local scratch buffer. + static constexpr VkDeviceSize kScratchBufferSizeIncrement = 16 * 1024 * 1024; + VkDeviceMemory scratch_buffer_memory_ = VK_NULL_HANDLE; + VkBuffer scratch_buffer_ = VK_NULL_HANDLE; + VkDeviceSize scratch_buffer_size_ = 0; + VkPipelineStageFlags scratch_buffer_last_stage_mask_ = 0; + VkAccessFlags scratch_buffer_last_access_mask_ = 0; + uint64_t scratch_buffer_last_usage_submission_ = 0; + bool scratch_buffer_used_ = false; + + static constexpr uint32_t kMaxOcclusionQueries = 8192; + VkQueryPool occlusion_query_pool_ = VK_NULL_HANDLE; + VkBuffer occlusion_query_readback_buffer_ = VK_NULL_HANDLE; + VkDeviceMemory occlusion_query_readback_memory_ = VK_NULL_HANDLE; + uint32_t occlusion_query_readback_memory_type_ = UINT32_MAX; + VkDeviceSize occlusion_query_readback_memory_size_ = 0; + uint8_t* occlusion_query_readback_mapping_ = nullptr; + uint32_t occlusion_query_cursor_ = 0; + bool occlusion_query_resources_available_ = false; + struct ActiveOcclusionQuery { + uint32_t sample_count_address = 0; + uint32_t host_index = UINT32_MAX; + bool valid = false; + } active_occlusion_query_; + struct VertexBufferState { + uint32_t address = UINT32_MAX; + uint32_t size = UINT32_MAX; + }; + std::array vertex_buffer_states_{}; + uint64_t vertex_buffers_in_sync_[2] = {}; + std::unordered_map readback_buffers_; + std::unordered_map memexport_readback_buffers_; + + // The current dynamic state of the graphics pipeline bind point. Note that + // binding any pipeline to the bind point with static state (even if it's + // unused, like depth bias being disabled, but the values themselves still not + // declared as dynamic in the pipeline) invalidates such dynamic state. + VkViewport dynamic_viewport_; + VkRect2D dynamic_scissor_; + // Dynamic fixed-function depth bias, blend constants, stencil state are + // applicable only to the render target implementations where they are + // actually involved. + float dynamic_depth_bias_constant_factor_; + float dynamic_depth_bias_slope_factor_; + float dynamic_blend_constants_[4]; + // The stencil values are pre-initialized (to D3D11_DEFAULT_STENCIL_*, and the + // initial values for front and back are the same for portability subset + // safety) because they're updated conditionally to avoid changing the back + // face values when stencil is disabled and the primitive type is changed + // between polygonal and non-polygonal. + uint32_t dynamic_stencil_compare_mask_front_ = UINT8_MAX; + uint32_t dynamic_stencil_compare_mask_back_ = UINT8_MAX; + uint32_t dynamic_stencil_write_mask_front_ = UINT8_MAX; + uint32_t dynamic_stencil_write_mask_back_ = UINT8_MAX; + uint32_t dynamic_stencil_reference_front_ = 0; + uint32_t dynamic_stencil_reference_back_ = 0; + bool dynamic_viewport_update_needed_; + bool dynamic_scissor_update_needed_; + bool dynamic_depth_bias_update_needed_; + bool dynamic_blend_constants_update_needed_; + bool dynamic_stencil_compare_mask_front_update_needed_; + bool dynamic_stencil_compare_mask_back_update_needed_; + bool dynamic_stencil_write_mask_front_update_needed_; + bool dynamic_stencil_write_mask_back_update_needed_; + bool dynamic_stencil_reference_front_update_needed_; + bool dynamic_stencil_reference_back_update_needed_; + + // Currently used samplers. + std::vector> current_samplers_vertex_; + std::vector> current_samplers_pixel_; + + // Cache render pass currently started in the command buffer with the + // framebuffer. For dynamic rendering, current_render_pass_ is VK_NULL_HANDLE + // but in_render_pass_ is true. + VkRenderPass current_render_pass_; + const VulkanRenderTargetCache::Framebuffer* current_framebuffer_; + bool in_render_pass_ = false; + + // Currently bound graphics pipeline, either from the pipeline cache (with + // potentially deferred creation - current_external_graphics_pipeline_ is + // VK_NULL_HANDLE in this case) or a non-Xenos one + // (current_guest_graphics_pipeline_ is VK_NULL_HANDLE in this case). + // TODO(Triang3l): Change to a deferred compilation handle. + VkPipeline current_guest_graphics_pipeline_; + VkPipeline current_external_graphics_pipeline_; + VkPipeline current_external_compute_pipeline_; + + // Pipeline layout of the current guest graphics pipeline. + const PipelineLayout* current_guest_graphics_pipeline_layout_; + VkDescriptorBufferInfo + current_constant_buffer_infos_[SpirvShaderTranslator::kConstantBufferCount]; + // Whether up-to-date data has been written to constant (uniform) buffers, and + // the buffer infos in current_constant_buffer_infos_ point to them. + uint32_t current_constant_buffers_up_to_date_; + VkDescriptorSet current_graphics_descriptor_sets_[SpirvShaderTranslator::kDescriptorSetCount]; + // Whether descriptor sets in current_graphics_descriptor_sets_ point to + // up-to-date data. + uint32_t current_graphics_descriptor_set_values_up_to_date_; + // Whether the descriptor sets currently bound to the command buffer - only + // low bits for the descriptor set layouts that remained the same are kept + // when changing the pipeline layout. May be out of sync with + // current_graphics_descriptor_set_values_up_to_date_, but should be ensured + // to be a subset of it at some point when it becomes important; bits for + // non-existent descriptor set layouts may also be set, but need to be ignored + // when they start to matter. + uint32_t current_graphics_descriptor_sets_bound_up_to_date_; + static_assert(SpirvShaderTranslator::kDescriptorSetCount <= + sizeof(current_graphics_descriptor_set_values_up_to_date_) * CHAR_BIT, + "Bit fields storing descriptor set validity must be large enough"); + static_assert(SpirvShaderTranslator::kDescriptorSetCount <= + sizeof(current_graphics_descriptor_sets_bound_up_to_date_) * CHAR_BIT, + "Bit fields storing descriptor set validity must be large enough"); + + // Float constant usage masks of the last draw call. + uint64_t current_float_constant_map_vertex_[4]; + uint64_t current_float_constant_map_pixel_[4]; + + // System shader constants. + SpirvShaderTranslator::SystemConstants system_constants_; + + // Temporary storage for memexport stream constants used in the draw. + std::vector memexport_ranges_; +}; + +} // namespace rex::graphics::vulkan diff --git a/include/rex/graphics/vulkan/deferred_command_buffer.h b/include/rex/graphics/vulkan/deferred_command_buffer.h new file mode 100644 index 0000000..9d2a848 --- /dev/null +++ b/include/rex/graphics/vulkan/deferred_command_buffer.h @@ -0,0 +1,588 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include +#include +#include + +namespace rex::graphics::vulkan { + +class VulkanCommandProcessor; + +class DeferredCommandBuffer { + public: + DeferredCommandBuffer(const VulkanCommandProcessor& command_processor, + size_t initial_size_bytes = 1024 * 1024); + + void Reset(); + void Execute(VkCommandBuffer command_buffer); + + // render_pass_begin->pNext of all barriers must be null. + void CmdVkBeginRenderPass(const VkRenderPassBeginInfo* render_pass_begin, + VkSubpassContents contents) { + assert_null(render_pass_begin->pNext); + size_t arguments_size = sizeof(ArgsVkBeginRenderPass); + uint32_t clear_value_count = render_pass_begin->clearValueCount; + size_t clear_values_offset = 0; + if (clear_value_count) { + arguments_size = rex::align(arguments_size, alignof(VkClearValue)); + clear_values_offset = arguments_size; + arguments_size += sizeof(VkClearValue) * clear_value_count; + } + uint8_t* args_ptr = + reinterpret_cast(WriteCommand(Command::kVkBeginRenderPass, arguments_size)); + auto& args = *reinterpret_cast(args_ptr); + args.render_pass = render_pass_begin->renderPass; + args.framebuffer = render_pass_begin->framebuffer; + args.render_area = render_pass_begin->renderArea; + args.clear_value_count = clear_value_count; + args.contents = contents; + if (clear_value_count) { + std::memcpy(args_ptr + clear_values_offset, render_pass_begin->pClearValues, + sizeof(VkClearValue) * clear_value_count); + } + } + + void CmdVkBindDescriptorSets(VkPipelineBindPoint pipeline_bind_point, VkPipelineLayout layout, + uint32_t first_set, uint32_t descriptor_set_count, + const VkDescriptorSet* descriptor_sets, + uint32_t dynamic_offset_count, const uint32_t* dynamic_offsets) { + size_t arguments_size = rex::align(sizeof(ArgsVkBindDescriptorSets), alignof(VkDescriptorSet)); + size_t descriptor_sets_offset = arguments_size; + arguments_size += sizeof(VkDescriptorSet) * descriptor_set_count; + size_t dynamic_offsets_offset = 0; + if (dynamic_offset_count) { + arguments_size = rex::align(arguments_size, alignof(uint32_t)); + dynamic_offsets_offset = arguments_size; + arguments_size += sizeof(uint32_t) * dynamic_offset_count; + } + uint8_t* args_ptr = + reinterpret_cast(WriteCommand(Command::kVkBindDescriptorSets, arguments_size)); + auto& args = *reinterpret_cast(args_ptr); + args.pipeline_bind_point = pipeline_bind_point; + args.layout = layout; + args.first_set = first_set; + args.descriptor_set_count = descriptor_set_count; + args.dynamic_offset_count = dynamic_offset_count; + std::memcpy(args_ptr + descriptor_sets_offset, descriptor_sets, + sizeof(VkDescriptorSet) * descriptor_set_count); + if (dynamic_offset_count) { + std::memcpy(args_ptr + dynamic_offsets_offset, dynamic_offsets, + sizeof(uint32_t) * dynamic_offset_count); + } + } + + void CmdVkBindIndexBuffer(VkBuffer buffer, VkDeviceSize offset, VkIndexType index_type) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kVkBindIndexBuffer, sizeof(ArgsVkBindIndexBuffer))); + args.buffer = buffer; + args.offset = offset; + args.index_type = index_type; + } + + void CmdVkBindPipeline(VkPipelineBindPoint pipeline_bind_point, VkPipeline pipeline) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kVkBindPipeline, sizeof(ArgsVkBindPipeline))); + args.pipeline_bind_point = pipeline_bind_point; + args.pipeline = pipeline; + } + + void CmdVkBindVertexBuffers(uint32_t first_binding, uint32_t binding_count, + const VkBuffer* buffers, const VkDeviceSize* offsets) { + size_t arguments_size = rex::align(sizeof(ArgsVkBindVertexBuffers), alignof(VkBuffer)); + size_t buffers_offset = arguments_size; + arguments_size = + rex::align(arguments_size + sizeof(VkBuffer) * binding_count, alignof(VkDeviceSize)); + size_t offsets_offset = arguments_size; + arguments_size += sizeof(VkDeviceSize) * binding_count; + uint8_t* args_ptr = + reinterpret_cast(WriteCommand(Command::kVkBindVertexBuffers, arguments_size)); + auto& args = *reinterpret_cast(args_ptr); + args.first_binding = first_binding; + args.binding_count = binding_count; + std::memcpy(args_ptr + buffers_offset, buffers, sizeof(VkBuffer) * binding_count); + std::memcpy(args_ptr + offsets_offset, offsets, sizeof(VkDeviceSize) * binding_count); + } + + void CmdClearAttachmentsEmplace(uint32_t attachment_count, VkClearAttachment*& attachments_out, + uint32_t rect_count, VkClearRect*& rects_out) { + size_t arguments_size = rex::align(sizeof(ArgsVkClearAttachments), alignof(VkClearAttachment)); + size_t attachments_offset = arguments_size; + arguments_size = rex::align(arguments_size + sizeof(VkClearAttachment) * attachment_count, + alignof(VkClearRect)); + size_t rects_offset = arguments_size; + arguments_size += sizeof(VkClearRect) * rect_count; + uint8_t* args_ptr = + reinterpret_cast(WriteCommand(Command::kVkClearAttachments, arguments_size)); + auto& args = *reinterpret_cast(args_ptr); + args.attachment_count = attachment_count; + args.rect_count = rect_count; + attachments_out = reinterpret_cast(args_ptr + attachments_offset); + rects_out = reinterpret_cast(args_ptr + rects_offset); + } + void CmdVkClearAttachments(uint32_t attachment_count, const VkClearAttachment* attachments, + uint32_t rect_count, const VkClearRect* rects) { + VkClearAttachment* attachments_arg; + VkClearRect* rects_arg; + CmdClearAttachmentsEmplace(attachment_count, attachments_arg, rect_count, rects_arg); + std::memcpy(attachments_arg, attachments, sizeof(VkClearAttachment) * attachment_count); + std::memcpy(rects_arg, rects, sizeof(VkClearRect) * rect_count); + } + + VkImageSubresourceRange* CmdClearColorImageEmplace(VkImage image, VkImageLayout image_layout, + const VkClearColorValue* color, + uint32_t range_count) { + const size_t header_size = + rex::align(sizeof(ArgsVkClearColorImage), alignof(VkImageSubresourceRange)); + uint8_t* args_ptr = reinterpret_cast(WriteCommand( + Command::kVkClearColorImage, header_size + sizeof(VkImageSubresourceRange) * range_count)); + auto& args = *reinterpret_cast(args_ptr); + args.image = image; + args.image_layout = image_layout; + args.color = *color; + args.range_count = range_count; + return reinterpret_cast(args_ptr + header_size); + } + void CmdVkClearColorImage(VkImage image, VkImageLayout image_layout, + const VkClearColorValue* color, uint32_t range_count, + const VkImageSubresourceRange* ranges) { + std::memcpy(CmdClearColorImageEmplace(image, image_layout, color, range_count), ranges, + sizeof(VkImageSubresourceRange) * range_count); + } + + VkBufferCopy* CmdCopyBufferEmplace(VkBuffer src_buffer, VkBuffer dst_buffer, + uint32_t region_count) { + const size_t header_size = rex::align(sizeof(ArgsVkCopyBuffer), alignof(VkBufferCopy)); + uint8_t* args_ptr = reinterpret_cast( + WriteCommand(Command::kVkCopyBuffer, header_size + sizeof(VkBufferCopy) * region_count)); + auto& args = *reinterpret_cast(args_ptr); + args.src_buffer = src_buffer; + args.dst_buffer = dst_buffer; + args.region_count = region_count; + return reinterpret_cast(args_ptr + header_size); + } + void CmdVkCopyBuffer(VkBuffer src_buffer, VkBuffer dst_buffer, uint32_t region_count, + const VkBufferCopy* regions) { + std::memcpy(CmdCopyBufferEmplace(src_buffer, dst_buffer, region_count), regions, + sizeof(VkBufferCopy) * region_count); + } + + void CmdVkBeginQuery(VkQueryPool query_pool, uint32_t query, VkQueryControlFlags flags) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kVkBeginQuery, sizeof(ArgsVkBeginQuery))); + args.query_pool = query_pool; + args.query = query; + args.flags = flags; + } + + VkBufferImageCopy* CmdCopyBufferToImageEmplace(VkBuffer src_buffer, VkImage dst_image, + VkImageLayout dst_image_layout, + uint32_t region_count) { + const size_t header_size = + rex::align(sizeof(ArgsVkCopyBufferToImage), alignof(VkBufferImageCopy)); + uint8_t* args_ptr = reinterpret_cast(WriteCommand( + Command::kVkCopyBufferToImage, header_size + sizeof(VkBufferImageCopy) * region_count)); + auto& args = *reinterpret_cast(args_ptr); + args.src_buffer = src_buffer; + args.dst_image = dst_image; + args.dst_image_layout = dst_image_layout; + args.region_count = region_count; + return reinterpret_cast(args_ptr + header_size); + } + void CmdVkCopyBufferToImage(VkBuffer src_buffer, VkImage dst_image, + VkImageLayout dst_image_layout, uint32_t region_count, + const VkBufferImageCopy* regions) { + std::memcpy(CmdCopyBufferToImageEmplace(src_buffer, dst_image, dst_image_layout, region_count), + regions, sizeof(VkBufferImageCopy) * region_count); + } + + void CmdVkCopyQueryPoolResults(VkQueryPool query_pool, uint32_t first_query, uint32_t query_count, + VkBuffer dst_buffer, VkDeviceSize dst_offset, VkDeviceSize stride, + VkQueryResultFlags flags) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kVkCopyQueryPoolResults, sizeof(ArgsVkCopyQueryPoolResults))); + args.query_pool = query_pool; + args.first_query = first_query; + args.query_count = query_count; + args.dst_buffer = dst_buffer; + args.dst_offset = dst_offset; + args.stride = stride; + args.flags = flags; + } + + void CmdVkDispatch(uint32_t group_count_x, uint32_t group_count_y, uint32_t group_count_z) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kVkDispatch, sizeof(ArgsVkDispatch))); + args.group_count_x = group_count_x; + args.group_count_y = group_count_y; + args.group_count_z = group_count_z; + } + + void CmdVkDraw(uint32_t vertex_count, uint32_t instance_count, uint32_t first_vertex, + uint32_t first_instance) { + auto& args = *reinterpret_cast(WriteCommand(Command::kVkDraw, sizeof(ArgsVkDraw))); + args.vertex_count = vertex_count; + args.instance_count = instance_count; + args.first_vertex = first_vertex; + args.first_instance = first_instance; + } + + void CmdVkDrawIndexed(uint32_t index_count, uint32_t instance_count, uint32_t first_index, + int32_t vertex_offset, uint32_t first_instance) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kVkDrawIndexed, sizeof(ArgsVkDrawIndexed))); + args.index_count = index_count; + args.instance_count = instance_count; + args.first_index = first_index; + args.vertex_offset = vertex_offset; + args.first_instance = first_instance; + } + + void CmdVkEndQuery(VkQueryPool query_pool, uint32_t query) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kVkEndQuery, sizeof(ArgsVkEndQuery))); + args.query_pool = query_pool; + args.query = query; + } + + void CmdVkEndRenderPass() { WriteCommand(Command::kVkEndRenderPass, 0); } + + // Dynamic rendering (VK_KHR_dynamic_rendering / Vulkan 1.3). + void CmdVkBeginRendering(const VkRenderingInfo* rendering_info); + void CmdVkEndRendering() { WriteCommand(Command::kVkEndRendering, 0); } + + void CmdVkResetQueryPool(VkQueryPool query_pool, uint32_t first_query, uint32_t query_count) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kVkResetQueryPool, sizeof(ArgsVkResetQueryPool))); + args.query_pool = query_pool; + args.first_query = first_query; + args.query_count = query_count; + } + + // pNext of all barriers must be null. + void CmdVkPipelineBarrier(VkPipelineStageFlags src_stage_mask, + VkPipelineStageFlags dst_stage_mask, VkDependencyFlags dependency_flags, + uint32_t memory_barrier_count, const VkMemoryBarrier* memory_barriers, + uint32_t buffer_memory_barrier_count, + const VkBufferMemoryBarrier* buffer_memory_barriers, + uint32_t image_memory_barrier_count, + const VkImageMemoryBarrier* image_memory_barriers); + + void CmdVkPushConstants(VkPipelineLayout layout, VkShaderStageFlags stage_flags, uint32_t offset, + uint32_t size, const void* values) { + uint8_t* args_ptr = reinterpret_cast( + WriteCommand(Command::kVkPushConstants, sizeof(ArgsVkPushConstants) + size)); + auto& args = *reinterpret_cast(args_ptr); + args.layout = layout; + args.stage_flags = stage_flags; + args.offset = offset; + args.size = size; + std::memcpy(args_ptr + sizeof(ArgsVkPushConstants), values, size); + } + + void CmdVkSetBlendConstants(const float* blend_constants) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kVkSetBlendConstants, sizeof(ArgsVkSetBlendConstants))); + std::memcpy(args.blend_constants, blend_constants, sizeof(float) * 4); + } + + void CmdVkSetDepthBias(float depth_bias_constant_factor, float depth_bias_clamp, + float depth_bias_slope_factor) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kVkSetDepthBias, sizeof(ArgsVkSetDepthBias))); + args.depth_bias_constant_factor = depth_bias_constant_factor; + args.depth_bias_clamp = depth_bias_clamp; + args.depth_bias_slope_factor = depth_bias_slope_factor; + } + + void CmdVkSetScissor(uint32_t first_scissor, uint32_t scissor_count, const VkRect2D* scissors) { + const size_t header_size = rex::align(sizeof(ArgsVkSetScissor), alignof(VkRect2D)); + uint8_t* args_ptr = reinterpret_cast( + WriteCommand(Command::kVkSetScissor, header_size + sizeof(VkRect2D) * scissor_count)); + auto& args = *reinterpret_cast(args_ptr); + args.first_scissor = first_scissor; + args.scissor_count = scissor_count; + std::memcpy(args_ptr + header_size, scissors, sizeof(VkRect2D) * scissor_count); + } + + void CmdVkSetStencilCompareMask(VkStencilFaceFlags face_mask, uint32_t compare_mask) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kVkSetStencilCompareMask, sizeof(ArgsSetStencilMaskReference))); + args.face_mask = face_mask; + args.mask_reference = compare_mask; + } + + void CmdVkSetStencilReference(VkStencilFaceFlags face_mask, uint32_t reference) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kVkSetStencilReference, sizeof(ArgsSetStencilMaskReference))); + args.face_mask = face_mask; + args.mask_reference = reference; + } + + void CmdVkSetStencilWriteMask(VkStencilFaceFlags face_mask, uint32_t write_mask) { + auto& args = *reinterpret_cast( + WriteCommand(Command::kVkSetStencilWriteMask, sizeof(ArgsSetStencilMaskReference))); + args.face_mask = face_mask; + args.mask_reference = write_mask; + } + + void CmdVkSetViewport(uint32_t first_viewport, uint32_t viewport_count, + const VkViewport* viewports) { + const size_t header_size = rex::align(sizeof(ArgsVkSetViewport), alignof(VkViewport)); + uint8_t* args_ptr = reinterpret_cast( + WriteCommand(Command::kVkSetViewport, header_size + sizeof(VkViewport) * viewport_count)); + auto& args = *reinterpret_cast(args_ptr); + args.first_viewport = first_viewport; + args.viewport_count = viewport_count; + std::memcpy(args_ptr + header_size, viewports, sizeof(VkViewport) * viewport_count); + } + + private: + enum class Command { + kVkBeginRenderPass, + kVkBeginQuery, + kVkBindDescriptorSets, + kVkBindIndexBuffer, + kVkBindPipeline, + kVkBindVertexBuffers, + kVkClearAttachments, + kVkClearColorImage, + kVkCopyBuffer, + kVkCopyBufferToImage, + kVkCopyQueryPoolResults, + kVkDispatch, + kVkDraw, + kVkDrawIndexed, + kVkEndQuery, + kVkEndRenderPass, + kVkBeginRendering, + kVkEndRendering, + kVkPipelineBarrier, + kVkPushConstants, + kVkResetQueryPool, + kVkSetBlendConstants, + kVkSetDepthBias, + kVkSetScissor, + kVkSetStencilCompareMask, + kVkSetStencilReference, + kVkSetStencilWriteMask, + kVkSetViewport, + }; + + struct CommandHeader { + Command command; + uint32_t arguments_size_elements; + }; + static constexpr size_t kCommandHeaderSizeElements = + (sizeof(CommandHeader) + sizeof(uintmax_t) - 1) / sizeof(uintmax_t); + + struct ArgsVkBeginRenderPass { + VkRenderPass render_pass; + VkFramebuffer framebuffer; + VkRect2D render_area; + uint32_t clear_value_count; + VkSubpassContents contents; + // Followed by aligned optional VkClearValue[]. + static_assert(alignof(VkClearValue) <= alignof(uintmax_t)); + }; + + struct ArgsVkBeginRendering { + VkRenderingFlags flags; + VkRect2D render_area; + uint32_t layer_count; + uint32_t view_mask; + uint32_t color_attachment_count; + bool has_depth_attachment; + bool has_stencil_attachment; + // Followed by: + // - VkRenderingAttachmentInfo[color_attachment_count] + // - VkRenderingAttachmentInfo depth (if has_depth_attachment) + // - VkRenderingAttachmentInfo stencil (if has_stencil_attachment) + static_assert(alignof(VkRenderingAttachmentInfo) <= alignof(uintmax_t)); + }; + + struct ArgsVkBeginQuery { + VkQueryPool query_pool; + uint32_t query; + VkQueryControlFlags flags; + }; + + struct ArgsVkBindDescriptorSets { + VkPipelineBindPoint pipeline_bind_point; + VkPipelineLayout layout; + uint32_t first_set; + uint32_t descriptor_set_count; + uint32_t dynamic_offset_count; + // Followed by aligned VkDescriptorSet[], optional uint32_t[]. + static_assert(alignof(VkDescriptorSet) <= alignof(uintmax_t)); + }; + + struct ArgsVkBindIndexBuffer { + VkBuffer buffer; + VkDeviceSize offset; + VkIndexType index_type; + }; + + struct ArgsVkBindPipeline { + VkPipelineBindPoint pipeline_bind_point; + VkPipeline pipeline; + }; + + struct ArgsVkBindVertexBuffers { + uint32_t first_binding; + uint32_t binding_count; + // Followed by aligned VkBuffer[], VkDeviceSize[]. + static_assert(alignof(VkBuffer) <= alignof(uintmax_t)); + static_assert(alignof(VkDeviceSize) <= alignof(uintmax_t)); + }; + + struct ArgsVkClearAttachments { + uint32_t attachment_count; + uint32_t rect_count; + // Followed by aligned VkClearAttachment[], VkClearRect[]. + static_assert(alignof(VkClearAttachment) <= alignof(uintmax_t)); + static_assert(alignof(VkClearRect) <= alignof(uintmax_t)); + }; + + struct ArgsVkClearColorImage { + VkImage image; + VkImageLayout image_layout; + VkClearColorValue color; + uint32_t range_count; + // Followed by aligned VkImageSubresourceRange[]. + static_assert(alignof(VkImageSubresourceRange) <= alignof(uintmax_t)); + }; + + struct ArgsVkCopyBuffer { + VkBuffer src_buffer; + VkBuffer dst_buffer; + uint32_t region_count; + // Followed by aligned VkBufferCopy[]. + static_assert(alignof(VkBufferCopy) <= alignof(uintmax_t)); + }; + + struct ArgsVkCopyBufferToImage { + VkBuffer src_buffer; + VkImage dst_image; + VkImageLayout dst_image_layout; + uint32_t region_count; + // Followed by aligned VkBufferImageCopy[]. + static_assert(alignof(VkBufferImageCopy) <= alignof(uintmax_t)); + }; + + struct ArgsVkCopyQueryPoolResults { + VkQueryPool query_pool; + uint32_t first_query; + uint32_t query_count; + VkBuffer dst_buffer; + VkDeviceSize dst_offset; + VkDeviceSize stride; + VkQueryResultFlags flags; + }; + + struct ArgsVkDispatch { + uint32_t group_count_x; + uint32_t group_count_y; + uint32_t group_count_z; + }; + + struct ArgsVkDraw { + uint32_t vertex_count; + uint32_t instance_count; + uint32_t first_vertex; + uint32_t first_instance; + }; + + struct ArgsVkDrawIndexed { + uint32_t index_count; + uint32_t instance_count; + uint32_t first_index; + int32_t vertex_offset; + uint32_t first_instance; + }; + + struct ArgsVkEndQuery { + VkQueryPool query_pool; + uint32_t query; + }; + + struct ArgsVkResetQueryPool { + VkQueryPool query_pool; + uint32_t first_query; + uint32_t query_count; + }; + + struct ArgsVkPipelineBarrier { + VkPipelineStageFlags src_stage_mask; + VkPipelineStageFlags dst_stage_mask; + VkDependencyFlags dependency_flags; + uint32_t memory_barrier_count; + uint32_t buffer_memory_barrier_count; + uint32_t image_memory_barrier_count; + // Followed by aligned optional VkMemoryBarrier[], + // optional VkBufferMemoryBarrier[], optional VkImageMemoryBarrier[]. + static_assert(alignof(VkMemoryBarrier) <= alignof(uintmax_t)); + static_assert(alignof(VkBufferMemoryBarrier) <= alignof(uintmax_t)); + static_assert(alignof(VkImageMemoryBarrier) <= alignof(uintmax_t)); + }; + + struct ArgsVkPushConstants { + VkPipelineLayout layout; + VkShaderStageFlags stage_flags; + uint32_t offset; + uint32_t size; + // Followed by `size` bytes of values. + }; + + struct ArgsVkSetBlendConstants { + float blend_constants[4]; + }; + + struct ArgsVkSetDepthBias { + float depth_bias_constant_factor; + float depth_bias_clamp; + float depth_bias_slope_factor; + }; + + struct ArgsVkSetScissor { + uint32_t first_scissor; + uint32_t scissor_count; + // Followed by aligned VkRect2D[]. + static_assert(alignof(VkRect2D) <= alignof(uintmax_t)); + }; + + struct ArgsSetStencilMaskReference { + VkStencilFaceFlags face_mask; + uint32_t mask_reference; + }; + + struct ArgsVkSetViewport { + uint32_t first_viewport; + uint32_t viewport_count; + // Followed by aligned VkViewport[]. + static_assert(alignof(VkViewport) <= alignof(uintmax_t)); + }; + + void* WriteCommand(Command command, size_t arguments_size_bytes); + + const VulkanCommandProcessor& command_processor_; + + // uintmax_t to ensure uint64_t and pointer alignment of all structures. + std::vector command_stream_; +}; + +} // namespace rex::graphics::vulkan diff --git a/include/rex/graphics/vulkan/graphics_system.h b/include/rex/graphics/vulkan/graphics_system.h new file mode 100644 index 0000000..ad5bc3e --- /dev/null +++ b/include/rex/graphics/vulkan/graphics_system.h @@ -0,0 +1,36 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include + +namespace rex::graphics::vulkan { + +class VulkanGraphicsSystem : public GraphicsSystem { + public: + VulkanGraphicsSystem(); + ~VulkanGraphicsSystem() override; + + static bool IsAvailable() { return true; } + + std::string name() const override; + + protected: + void CreateProvider(bool with_presentation) override; + + private: + std::unique_ptr CreateCommandProcessor() override; +}; + +} // namespace rex::graphics::vulkan diff --git a/include/rex/graphics/vulkan/pipeline_cache.h b/include/rex/graphics/vulkan/pipeline_cache.h new file mode 100644 index 0000000..7b938b9 --- /dev/null +++ b/include/rex/graphics/vulkan/pipeline_cache.h @@ -0,0 +1,473 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::graphics::vulkan { + +class VulkanCommandProcessor; + +// TODO(Triang3l): Create a common base for both the Vulkan and the Direct3D +// implementations. +class VulkanPipelineCache { + public: + static constexpr size_t kLayoutUIDEmpty = 0; + + class PipelineLayoutProvider { + public: + virtual ~PipelineLayoutProvider() {} + virtual VkPipelineLayout GetPipelineLayout() const = 0; + + protected: + PipelineLayoutProvider() = default; + }; + + VulkanPipelineCache(VulkanCommandProcessor& command_processor, const RegisterFile& register_file, + VulkanRenderTargetCache& render_target_cache, + VkShaderStageFlags guest_shader_vertex_stages); + ~VulkanPipelineCache(); + + bool Initialize(); + void Shutdown(); + void InitializeShaderStorage(const std::filesystem::path& cache_root, uint32_t title_id, + bool blocking); + void ShutdownShaderStorage(); + void EndSubmission(); + + VulkanShader* LoadShader(xenos::ShaderType shader_type, const uint32_t* host_address, + uint32_t dword_count); + // Analyze shader microcode on the translator thread. + void AnalyzeShaderUcode(Shader& shader) { shader.AnalyzeUcode(ucode_disasm_buffer_); } + + // Retrieves the shader modification for the current state. The shader must + // have microcode analyzed. + SpirvShaderTranslator::Modification GetCurrentVertexShaderModification( + const Shader& shader, Shader::HostVertexShaderType host_vertex_shader_type, + uint32_t interpolator_mask, bool ps_param_gen_used) const; + SpirvShaderTranslator::Modification GetCurrentPixelShaderModification( + const Shader& shader, uint32_t interpolator_mask, uint32_t param_gen_pos, + reg::RB_DEPTHCONTROL normalized_depth_control) const; + + bool EnsureShadersTranslated(VulkanShader::VulkanTranslation* vertex_shader, + VulkanShader::VulkanTranslation* pixel_shader); + // TODO(Triang3l): Return a deferred creation handle. + bool ConfigurePipeline( + VulkanShader::VulkanTranslation* vertex_shader, VulkanShader::VulkanTranslation* pixel_shader, + const PrimitiveProcessor::ProcessingResult& primitive_processing_result, + reg::RB_DEPTHCONTROL normalized_depth_control, uint32_t normalized_color_mask, + VulkanRenderTargetCache::RenderPassKey render_pass_key, VkPipeline& pipeline_out, + const PipelineLayoutProvider*& pipeline_layout_out, void** pipeline_handle_out = nullptr); + bool IsCreatingPipelines() const; + void GetPipelineAndLayoutByHandle(void* handle, VkPipeline& pipeline_out, + const PipelineLayoutProvider*& pipeline_layout_out, + bool* is_placeholder_out = nullptr) const; + + private: + REXPACKEDSTRUCT(ShaderStoredHeader, { + uint64_t ucode_data_hash; + + uint32_t ucode_dword_count : 31; + xenos::ShaderType type : 1; + + static constexpr uint32_t kVersion = 0x20201219; + }); + + enum class PipelineGeometryShader : uint32_t { + kNone, + kPointList, + kRectangleList, + kQuadList, + }; + + enum class PipelinePrimitiveTopology : uint32_t { + kPointList, + kLineList, + kLineStrip, + kTriangleList, + kTriangleStrip, + kTriangleFan, + kLineListWithAdjacency, + kPatchList, + }; + + enum class PipelinePolygonMode : uint32_t { + kFill, + kLine, + kPoint, + }; + + enum class PipelineBlendFactor : uint32_t { + kZero, + kOne, + kSrcColor, + kOneMinusSrcColor, + kDstColor, + kOneMinusDstColor, + kSrcAlpha, + kOneMinusSrcAlpha, + kDstAlpha, + kOneMinusDstAlpha, + kConstantColor, + kOneMinusConstantColor, + kConstantAlpha, + kOneMinusConstantAlpha, + kSrcAlphaSaturate, + }; + + // Update PipelineDescription::kVersion if anything is changed! + REXPACKEDSTRUCT(PipelineRenderTarget, { + PipelineBlendFactor src_color_blend_factor : 4; // 4 + PipelineBlendFactor dst_color_blend_factor : 4; // 8 + xenos::BlendOp color_blend_op : 3; // 11 + PipelineBlendFactor src_alpha_blend_factor : 4; // 15 + PipelineBlendFactor dst_alpha_blend_factor : 4; // 19 + xenos::BlendOp alpha_blend_op : 3; // 22 + uint32_t color_write_mask : 4; // 26 + }); + + REXPACKEDSTRUCT(PipelineDescription, { + uint64_t vertex_shader_hash; + uint64_t vertex_shader_modification; + // 0 if no pixel shader. + uint64_t pixel_shader_hash; + uint64_t pixel_shader_modification; + VulkanRenderTargetCache::RenderPassKey render_pass_key; + + // Shader stages. + PipelineGeometryShader geometry_shader : 2; // 2 + // Input assembly. + PipelinePrimitiveTopology primitive_topology : 3; // 5 + uint32_t primitive_restart : 1; // 6 + xenos::TessellationMode tessellation_mode : 2; // 8 + // Rasterization. + uint32_t depth_clamp_enable : 1; // 9 + PipelinePolygonMode polygon_mode : 2; // 11 + uint32_t cull_front : 1; // 12 + uint32_t cull_back : 1; // 13 + uint32_t front_face_clockwise : 1; // 14 + uint32_t rasterizer_discard : 1; // 15 + // Depth / stencil. + uint32_t depth_write_enable : 1; // 16 + xenos::CompareFunction depth_compare_op : 3; // 19 + uint32_t stencil_test_enable : 1; // 20 + xenos::StencilOp stencil_front_fail_op : 3; // 23 + xenos::StencilOp stencil_front_pass_op : 3; // 26 + xenos::StencilOp stencil_front_depth_fail_op : 3; // 29 + xenos::CompareFunction stencil_front_compare_op : 3; // 32 + xenos::StencilOp stencil_back_fail_op : 3; // 35 + + xenos::StencilOp stencil_back_pass_op : 3; // 3 + xenos::StencilOp stencil_back_depth_fail_op : 3; // 6 + xenos::CompareFunction stencil_back_compare_op : 3; // 9 + uint32_t sample_rate_shading : 1; // 10 + + // Filled only for the attachments present in the render pass object. + PipelineRenderTarget render_targets[xenos::kMaxColorRenderTargets]; + + // Including all the padding, for a stable hash. + static constexpr uint32_t kVersion = 0x20260228; + PipelineDescription() { + Reset(); + } + PipelineDescription(const PipelineDescription& description) { + std::memcpy(this, &description, sizeof(*this)); + } + PipelineDescription& operator=(const PipelineDescription& description) { + std::memcpy(this, &description, sizeof(*this)); + return *this; + } + bool operator==(const PipelineDescription& description) const { + return std::memcmp(this, &description, sizeof(*this)) == 0; + } + void Reset() { + std::memset(this, 0, sizeof(*this)); + } + uint64_t GetHash() const { + return XXH3_64bits(this, sizeof(*this)); + } + struct Hasher { + size_t operator()(const PipelineDescription& description) const { + return size_t(description.GetHash()); + } + }; + }); + REXPACKEDSTRUCT(PipelineStoredDescription, { + uint64_t description_hash; + PipelineDescription description; + }); + + struct Pipeline { + std::atomic pipeline{VK_NULL_HANDLE}; + // The layouts are owned by the VulkanCommandProcessor, and must not be + // destroyed by it while the pipeline cache is active. + std::atomic pipeline_layout{nullptr}; + std::atomic is_placeholder{false}; + Pipeline() = default; + Pipeline(const PipelineLayoutProvider* pipeline_layout_provider) + : pipeline_layout(pipeline_layout_provider) {} + Pipeline(const Pipeline& other) + : pipeline(other.pipeline.load(std::memory_order_acquire)), + pipeline_layout(other.pipeline_layout.load(std::memory_order_acquire)), + is_placeholder(other.is_placeholder.load(std::memory_order_acquire)) {} + Pipeline& operator=(const Pipeline& other) { + if (this == &other) { + return *this; + } + pipeline.store(other.pipeline.load(std::memory_order_acquire), std::memory_order_release); + pipeline_layout.store(other.pipeline_layout.load(std::memory_order_acquire), + std::memory_order_release); + is_placeholder.store(other.is_placeholder.load(std::memory_order_acquire), + std::memory_order_release); + return *this; + } + }; + + // Description that can be passed from the command processor thread to the + // creation threads, with everything needed from caches pre-looked-up. + struct PipelineCreationArguments { + uint8_t priority = 0; + std::pair* pipeline = nullptr; + const PipelineLayoutProvider* pipeline_layout = nullptr; + // Guest shader translation (VS or TES depending on host vertex type). + const VulkanShader::VulkanTranslation* vertex_shader = nullptr; + const VulkanShader::VulkanTranslation* pixel_shader = nullptr; + // Non-guest stages for tessellation. + VkShaderModule tessellation_vertex_shader = VK_NULL_HANDLE; + VkShaderModule tessellation_control_shader = VK_NULL_HANDLE; + uint32_t tessellation_patch_control_points = 0; + VkShaderModule geometry_shader = VK_NULL_HANDLE; + // VK_NULL_HANDLE when dynamic rendering is used. + VkRenderPass render_pass = VK_NULL_HANDLE; + }; + struct PipelineCreationArgumentsPriorityComparator { + bool operator()(const PipelineCreationArguments& a, const PipelineCreationArguments& b) const { + return a.priority < b.priority; + } + }; + + union TessellationControlShaderKey { + uint32_t key; + struct { + Shader::HostVertexShaderType host_vertex_shader_type : Shader::kHostVertexShaderTypeBitCount; + xenos::TessellationMode tessellation_mode : 2; + }; + + TessellationControlShaderKey() : key(0) { static_assert_size(*this, sizeof(key)); } + + struct Hasher { + size_t operator()(const TessellationControlShaderKey& key) const { + return std::hash{}(key.key); + } + }; + bool operator==(const TessellationControlShaderKey& other_key) const { + return key == other_key.key; + } + }; + + union GeometryShaderKey { + uint32_t key; + struct { + PipelineGeometryShader type : 2; + uint32_t interpolator_count : 5; + uint32_t user_clip_plane_count : 3; + uint32_t user_clip_plane_cull : 1; + uint32_t has_vertex_kill_and : 1; + uint32_t has_point_size : 1; + uint32_t has_point_coordinates : 1; + // PA_CL_CLIP_CNTL::ps_ucp_mode for point primitives. + uint32_t point_ps_ucp_mode : 2; + }; + + GeometryShaderKey() : key(0) { static_assert_size(*this, sizeof(key)); } + + struct Hasher { + size_t operator()(const GeometryShaderKey& key) const { + return std::hash{}(key.key); + } + }; + bool operator==(const GeometryShaderKey& other_key) const { return key == other_key.key; } + bool operator!=(const GeometryShaderKey& other_key) const { return !(*this == other_key); } + }; + + VulkanShader* LoadShader(xenos::ShaderType shader_type, const uint32_t* host_address, + uint32_t dword_count, uint64_t data_hash); + + // Can be called from multiple threads. + bool TranslateAnalyzedShader(SpirvShaderTranslator& translator, + VulkanShader::VulkanTranslation& translation); + + void WritePipelineRenderTargetDescription(reg::RB_BLENDCONTROL blend_control, uint32_t write_mask, + PipelineRenderTarget& render_target_out) const; + bool GetCurrentStateDescription( + const VulkanShader::VulkanTranslation* vertex_shader, + const VulkanShader::VulkanTranslation* pixel_shader, + const PrimitiveProcessor::ProcessingResult& primitive_processing_result, + reg::RB_DEPTHCONTROL normalized_depth_control, uint32_t normalized_color_mask, + VulkanRenderTargetCache::RenderPassKey render_pass_key, + PipelineDescription& description_out) const; + + // Whether the pipeline for the given description is supported by the device. + bool ArePipelineRequirementsMet(const PipelineDescription& description) const; + + static bool GetGeometryShaderKey(PipelineGeometryShader geometry_shader_type, + SpirvShaderTranslator::Modification vertex_shader_modification, + SpirvShaderTranslator::Modification pixel_shader_modification, + GeometryShaderKey& key_out); + static uint32_t GetTessellationPatchControlPointCount( + Shader::HostVertexShaderType host_vertex_shader_type, + xenos::TessellationMode tessellation_mode); + VkShaderModule GetTessellationVertexShader(bool adaptive); + VkShaderModule GetTessellationControlShader(Shader::HostVertexShaderType host_vertex_shader_type, + xenos::TessellationMode tessellation_mode); + VkShaderModule GetGeometryShader(GeometryShaderKey key); + bool TryGetPipelineCreationArgumentsForDescription( + const PipelineDescription& description, + std::pair* pipeline, + PipelineCreationArguments& creation_arguments, bool for_placeholder = false); + + // Can be called from creation threads - all needed data must be fully set up + // at the point of the call: shaders must be translated, and the pipeline + // layout and render pass object (unless dynamic rendering is used) must be + // available. + bool EnsurePipelineCreated(const PipelineCreationArguments& creation_arguments, + VkShaderModule fragment_shader_override = VK_NULL_HANDLE); + void CreationThread(size_t thread_index); + void CreateQueuedPipelinesOnProcessorThread(); + void ProcessDeferredPipelineDestructions(bool force_all); + + VulkanCommandProcessor& command_processor_; + const RegisterFile& register_file_; + VulkanRenderTargetCache& render_target_cache_; + VkShaderStageFlags guest_shader_vertex_stages_; + + // Temporary storage for AnalyzeUcode calls on the processor thread. + string::StringBuffer ucode_disasm_buffer_; + // Reusable shader translator on the command processor thread. + std::unique_ptr shader_translator_; + + struct LayoutUID { + size_t uid; + size_t vector_span_offset; + size_t vector_span_length; + }; + std::mutex layouts_mutex_; + // Texture binding layouts of different shaders, for obtaining layout UIDs. + std::vector texture_binding_layouts_; + // Map of texture binding layouts used by shaders, for obtaining UIDs. Keys + // are XXH3 hashes of layouts, values need manual collision resolution using + // layout_vector_offset:layout_length of texture_binding_layouts_. + std::unordered_multimap> + texture_binding_layout_map_; + + // Ucode hash -> shader. + std::unordered_map> shaders_; + + // Geometry shaders for Xenos primitive types not supported by Vulkan. + // Stores VK_NULL_HANDLE if failed to create. + std::unordered_map + geometry_shaders_; + + // Fixed-function emulation shaders for tessellation. + bool tessellation_indexed_vertex_shader_attempted_ = false; + VkShaderModule tessellation_indexed_vertex_shader_ = VK_NULL_HANDLE; + bool tessellation_adaptive_vertex_shader_attempted_ = false; + VkShaderModule tessellation_adaptive_vertex_shader_ = VK_NULL_HANDLE; + std::unordered_map + tessellation_control_shaders_; + + // Empty depth-only pixel shader for writing to depth buffer using fragment + // shader interlock when no Xenos pixel shader provided. + VkShaderModule depth_only_fragment_shader_ = VK_NULL_HANDLE; + VkShaderModule placeholder_pixel_shader_ = VK_NULL_HANDLE; + // Depth-only shaders for float24 emulation when no Xenos pixel shader is + // provided in host render target mode. + VkShaderModule depth_float24_truncate_fragment_shader_ = VK_NULL_HANDLE; + VkShaderModule depth_float24_round_fragment_shader_ = VK_NULL_HANDLE; + + std::unordered_map pipelines_; + + // Previously used pipeline, to avoid lookups if the state wasn't changed. + const std::pair* last_pipeline_ = nullptr; + // . + std::deque> deferred_destroy_pipelines_; + std::mutex deferred_destroy_lock_; + + // Currently open shader storage path. + std::filesystem::path shader_storage_cache_root_; + uint32_t shader_storage_title_id_ = 0; + + // Shader storage output stream, for preload in the next emulator runs. + FILE* shader_storage_file_ = nullptr; + // For only writing shaders to the currently open storage once, incremented + // when switching the storage. + uint32_t shader_storage_index_ = 0; + bool shader_storage_file_flush_needed_ = false; + + // Pipeline storage output stream, for preload in the next emulator runs. + FILE* pipeline_storage_file_ = nullptr; + bool pipeline_storage_file_flush_needed_ = false; + + // Thread for asynchronous writing to the storage streams. + void StorageWriteThread(); + std::mutex storage_write_request_lock_; + std::condition_variable storage_write_request_cond_; + // Storage thread input is protected with storage_write_request_lock_, and the + // thread is notified about its change via storage_write_request_cond_. + std::deque storage_write_shader_queue_; + std::deque storage_write_pipeline_queue_; + bool storage_write_flush_shaders_ = false; + bool storage_write_flush_pipelines_ = false; + bool storage_write_thread_shutdown_ = false; + std::unique_ptr storage_write_thread_; + + mutable std::mutex creation_request_lock_; + std::condition_variable creation_request_cond_; + std::priority_queue, + PipelineCreationArgumentsPriorityComparator> + creation_queue_; + size_t creation_threads_busy_ = 0; + bool startup_loading_ = false; + std::unique_ptr creation_completion_event_; + bool creation_completion_set_event_ = false; + size_t creation_threads_shutdown_from_ = SIZE_MAX; + std::vector> creation_threads_; +}; + +} // namespace rex::graphics::vulkan diff --git a/include/rex/graphics/vulkan/primitive_processor.h b/include/rex/graphics/vulkan/primitive_processor.h new file mode 100644 index 0000000..5e493e4 --- /dev/null +++ b/include/rex/graphics/vulkan/primitive_processor.h @@ -0,0 +1,81 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include + +namespace rex::graphics::vulkan { + +class VulkanCommandProcessor; + +class VulkanPrimitiveProcessor final : public PrimitiveProcessor { + public: + VulkanPrimitiveProcessor(const RegisterFile& register_file, memory::Memory& memory, + TraceWriter& trace_writer, SharedMemory& shared_memory, + VulkanCommandProcessor& command_processor) + : PrimitiveProcessor(register_file, memory, trace_writer, shared_memory), + command_processor_(command_processor) {} + ~VulkanPrimitiveProcessor(); + + bool Initialize(); + void Shutdown(bool from_destructor = false); + void ClearCache() { frame_index_buffer_pool_->ClearCache(); } + + void CompletedSubmissionUpdated(); + void BeginSubmission(); + void BeginFrame(); + void EndSubmission(); + void EndFrame(); + + std::pair GetBuiltinIndexBuffer(size_t handle) const { + assert_not_null(builtin_index_buffer_); + return std::make_pair(builtin_index_buffer_, + VkDeviceSize(GetBuiltinIndexBufferOffsetBytes(handle))); + } + std::pair GetConvertedIndexBuffer(size_t handle) const { + return frame_index_buffers_[handle]; + } + + protected: + bool InitializeBuiltinIndexBuffer(size_t size_bytes, + std::function fill_callback) override; + + void* RequestHostConvertedIndexBufferForCurrentFrame(xenos::IndexFormat format, + uint32_t index_count, bool coalign_for_simd, + uint32_t coalignment_original_address, + size_t& backend_handle_out) override; + + private: + VulkanCommandProcessor& command_processor_; + + VkDeviceSize builtin_index_buffer_size_ = 0; + VkBuffer builtin_index_buffer_ = VK_NULL_HANDLE; + VkDeviceMemory builtin_index_buffer_memory_ = VK_NULL_HANDLE; + // Temporary buffer copied in the beginning of the first submission for + // uploading to builtin_index_buffer_, destroyed when the submission when it + // was uploaded is completed. + VkBuffer builtin_index_buffer_upload_ = VK_NULL_HANDLE; + VkDeviceMemory builtin_index_buffer_upload_memory_ = VK_NULL_HANDLE; + // UINT64_MAX means not uploaded yet and needs uploading in the first + // submission (if the upload buffer exists at all). + uint64_t builtin_index_buffer_upload_submission_ = UINT64_MAX; + + std::unique_ptr frame_index_buffer_pool_; + // Indexed by the backend handles. + std::deque> frame_index_buffers_; +}; + +} // namespace rex::graphics::vulkan diff --git a/include/rex/graphics/vulkan/render_target_cache.h b/include/rex/graphics/vulkan/render_target_cache.h new file mode 100644 index 0000000..43ef7a2 --- /dev/null +++ b/include/rex/graphics/vulkan/render_target_cache.h @@ -0,0 +1,901 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::graphics::vulkan { + +class VulkanCommandProcessor; + +class VulkanRenderTargetCache final : public RenderTargetCache { + public: + union RenderPassKey { + struct { + // If emulating 2x as 4x, this is still 2x for simplicity of using this + // field to make guest-related decisions. Render pass objects are not very + // expensive, and their dependencies can't be shared between 2x-as-4x and + // true 4x MSAA passes (framebuffers because render target cache render + // targets are different for 2x and 4x guest MSAA, pipelines because the + // sample mask will have 2 samples excluded for 2x-as-4x). + // This has effect only on the attachments, but even in cases when there + // are no attachments, it can be used to pass the sample count between + // subsystems, for instance, to specify the desired number of samples to + // use when there are no attachments in pipelines. + // Also, without attachments, using separate render passes for different + // sample counts ensures that if the variableMultisampleRate feature is + // not supported, no draws with different rasterization sample counts end + // up in one render pass. + xenos::MsaaSamples msaa_samples : xenos::kMsaaSamplesBits; // 2 + // << 0 is depth, << 1...4 is color. + uint32_t depth_and_color_used : 1 + xenos::kMaxColorRenderTargets; // 7 + // 0 for unused attachments. + // If VK_FORMAT_D24_UNORM_S8_UINT is not supported, this must be kD24FS8 + // even for kD24S8. + xenos::DepthRenderTargetFormat depth_format : xenos::kDepthRenderTargetFormatBits; // 8 + // Linear or sRGB included if host sRGB is used. + xenos::ColorRenderTargetFormat color_0_view_format + : xenos::kColorRenderTargetFormatBits; // 12 + xenos::ColorRenderTargetFormat color_1_view_format + : xenos::kColorRenderTargetFormatBits; // 16 + xenos::ColorRenderTargetFormat color_2_view_format + : xenos::kColorRenderTargetFormatBits; // 20 + xenos::ColorRenderTargetFormat color_3_view_format + : xenos::kColorRenderTargetFormatBits; // 24 + uint32_t color_rts_use_transfer_formats : 1; // 25 + }; + uint32_t key = 0; + struct Hasher { + size_t operator()(const RenderPassKey& key) const { return std::hash{}(key.key); } + }; + bool operator==(const RenderPassKey& other_key) const { return key == other_key.key; } + bool operator!=(const RenderPassKey& other_key) const { return !(*this == other_key); } + bool operator<(const RenderPassKey& other_key) const { return key < other_key.key; } + }; + static_assert_size(RenderPassKey, sizeof(uint32_t)); + + struct Framebuffer { + VkFramebuffer framebuffer = VK_NULL_HANDLE; + VkExtent2D host_extent{}; + Framebuffer() = default; + Framebuffer(VkFramebuffer framebuffer, const VkExtent2D& host_extent) + : framebuffer(framebuffer), host_extent(host_extent) {} + }; + + VulkanRenderTargetCache(const RegisterFile& register_file, const memory::Memory& memory, + TraceWriter& trace_writer, uint32_t draw_resolution_scale_x, + uint32_t draw_resolution_scale_y, + VulkanCommandProcessor& command_processor); + ~VulkanRenderTargetCache(); + + // Transient descriptor set layouts must be initialized in the command + // processor. + bool Initialize(uint32_t shared_memory_binding_count); + void Shutdown(bool from_destructor = false); + void ClearCache() override; + + void CompletedSubmissionUpdated(); + void EndSubmission(); + + Path GetPath() const override { return path_; } + + VkBuffer edram_buffer() const { return edram_buffer_; } + + // Performs the resolve to a shared memory area according to the current + // register values, and also clears the render targets if needed. Must be in a + // frame for calling. + bool Resolve(const memory::Memory& memory, VulkanSharedMemory& shared_memory, + VulkanTextureCache& texture_cache, uint32_t& written_address_out, + uint32_t& written_length_out); + + // Returns true if any downloads were submitted to the command processor. + bool InitializeTraceSubmitDownloads(); + void InitializeTraceCompleteDownloads(); + void RestoreEdramSnapshot(const void* snapshot); + + bool Update(bool is_rasterization_done, reg::RB_DEPTHCONTROL normalized_depth_control, + uint32_t normalized_color_mask, const Shader& vertex_shader) override; + // Binding information for the last successful update. + RenderPassKey last_update_render_pass_key() const { return last_update_render_pass_key_; } + VkRenderPass last_update_render_pass() const { return last_update_render_pass_; } + const Framebuffer* last_update_framebuffer() const { return last_update_framebuffer_; } + void GetLastUpdateRenderingAttachments(VkRenderingAttachmentInfo* color_attachments, + uint32_t* color_attachment_count_out, + VkRenderingAttachmentInfo* depth_attachment, + VkRenderingAttachmentInfo* stencil_attachment) const; + + // Using R16G16[B16A16]_SNORM, which are -1...1, not the needed -32...32. + // Persistent data doesn't depend on this, so can be overriden by per-game + // configuration. + bool IsFixedRG16TruncatedToMinus1To1() const { + return GetPath() == Path::kHostRenderTargets && !color_rg16_draw_format_fallback_to_float_ && + !REXCVAR_GET(snorm16_render_target_full_range); + } + bool IsFixedRGBA16TruncatedToMinus1To1() const { + return GetPath() == Path::kHostRenderTargets && !color_rgba16_draw_format_fallback_to_float_ && + !REXCVAR_GET(snorm16_render_target_full_range); + } + bool gamma_render_target_as_unorm16() const { return gamma_render_target_as_unorm16_; } + + bool depth_unorm24_vulkan_format_supported() const { + return depth_unorm24_vulkan_format_supported_; + } + bool depth_float24_round() const { return depth_float24_round_; } + bool depth_float24_convert_in_pixel_shader() const { + return depth_float24_convert_in_pixel_shader_; + } + + bool msaa_2x_attachments_supported() const { return msaa_2x_attachments_supported_; } + bool msaa_2x_no_attachments_supported() const { return msaa_2x_no_attachments_supported_; } + bool IsMsaa2xSupported(bool subpass_has_attachments) const { + return subpass_has_attachments ? msaa_2x_attachments_supported_ + : msaa_2x_no_attachments_supported_; + } + + // Returns the render pass object, or VK_NULL_HANDLE if failed to create. + // A render pass managed by the render target cache may be ended and resumed + // at any time (to allow for things like copying and texture loading). + VkRenderPass GetHostRenderTargetsRenderPass(RenderPassKey key); + VkRenderPass GetFragmentShaderInterlockRenderPass() const { + assert_true(GetPath() == Path::kPixelShaderInterlock); + return fsi_render_pass_; + } + + VkFormat GetDepthVulkanFormat(xenos::DepthRenderTargetFormat format) const; + VkFormat GetColorVulkanFormat(xenos::ColorRenderTargetFormat format) const; + VkFormat GetColorOwnershipTransferVulkanFormat( + xenos::ColorRenderTargetFormat format, + xenos::MsaaSamples msaa_samples = xenos::MsaaSamples::k1X, + bool* is_integer_out = nullptr) const; + + protected: + uint32_t GetMaxRenderTargetWidth() const override; + uint32_t GetMaxRenderTargetHeight() const override; + + RenderTarget* CreateRenderTarget(RenderTargetKey key) override; + + bool IsHostDepthEncodingDifferent(xenos::DepthRenderTargetFormat format) const override; + + bool IsGammaFormatHostStorageSeparate() const override; + + void RequestPixelShaderInterlockBarrier() override; + + private: + enum class EdramBufferUsage { + // There's no need for combined fragment and compute usages. + // With host render targets, the usual usage sequence is as follows: + // - Optionally compute writes - host depth copy storing for EDRAM range + // ownership transfers. + // - Optionally fragment reads - host depth copy storing for EDRAM range + // ownership transfers. + // - Compute writes - copying from host render targets during resolving. + // - Compute reads - writing to the shared memory during resolving. + // With the render backend implementation based on fragment shader + // interlocks, it's: + // - Fragment reads and writes - depth / stencil and color operations. + // - Compute reads - writing to the shared memory during resolving. + // So, fragment reads and compute reads normally don't follow each other, + // and there's no need to amortize the cost of a read > read barrier in an + // exceptional situation by using a wider barrier in the normal scenario. + + // Host depth copy storing. + kFragmentRead, + // Fragment shader interlock depth / stencil and color operations. + kFragmentReadWrite, + // Resolve - copying to the shared memory. + kComputeRead, + // Resolve - copying from host render targets. + kComputeWrite, + // Trace recording. + kTransferRead, + // Trace playback. + kTransferWrite, + }; + + enum class EdramBufferModificationStatus { + // The values are ordered by how strong the barrier conditions are. + // No uncommitted shader writes. + kUnmodified, + // Need to commit before the next fragment shader interlock usage with + // overlap. + kViaFragmentShaderInterlock, + // Need to commit before any next fragment shader interlock usage. + kViaUnordered, + }; + + enum ResolveCopyDescriptorSet : uint32_t { + // Never changes. + kResolveCopyDescriptorSetEdram, + // Shared memory or a region in it. + kResolveCopyDescriptorSetDest, + + kResolveCopyDescriptorSetCount, + }; + + struct ResolveCopyShaderCode { + const uint32_t* unscaled; + size_t unscaled_size_bytes; + const uint32_t* scaled; + size_t scaled_size_bytes; + }; + + static void GetEdramBufferUsageMasks(EdramBufferUsage usage, VkPipelineStageFlags& stage_mask_out, + VkAccessFlags& access_mask_out); + bool IsColor16FormatFloatLike(xenos::ColorRenderTargetFormat format) const; + void UseEdramBuffer(EdramBufferUsage new_usage); + void MarkEdramBufferModified(EdramBufferModificationStatus modification_status = + EdramBufferModificationStatus::kViaUnordered); + void CommitEdramBufferShaderWrites( + EdramBufferModificationStatus commit_status = + EdramBufferModificationStatus::kViaFragmentShaderInterlock); + + VulkanCommandProcessor& command_processor_; + TraceWriter& trace_writer_; + + Path path_ = Path::kHostRenderTargets; + + // Accessible in fragment and compute shaders. + VkDescriptorSetLayout descriptor_set_layout_storage_buffer_ = VK_NULL_HANDLE; + VkDescriptorSetLayout descriptor_set_layout_sampled_image_ = VK_NULL_HANDLE; + VkDescriptorSetLayout descriptor_set_layout_sampled_image_x2_ = VK_NULL_HANDLE; + + std::unique_ptr descriptor_set_pool_sampled_image_; + std::unique_ptr descriptor_set_pool_sampled_image_x2_; + + VkDeviceMemory edram_buffer_memory_ = VK_NULL_HANDLE; + VkBuffer edram_buffer_ = VK_NULL_HANDLE; + EdramBufferUsage edram_buffer_usage_; + EdramBufferModificationStatus edram_buffer_modification_status_ = + EdramBufferModificationStatus::kUnmodified; + VkDescriptorPool edram_storage_buffer_descriptor_pool_ = VK_NULL_HANDLE; + VkDescriptorSet edram_storage_buffer_descriptor_set_; + + VkPipelineLayout resolve_copy_pipeline_layout_ = VK_NULL_HANDLE; + static const ResolveCopyShaderCode + kResolveCopyShaders[size_t(draw_util::ResolveCopyShaderIndex::kCount)]; + std::array + resolve_copy_pipelines_{}; + + // On the fragment shader interlock path, the render pass key is used purely + // for passing parameters to pipeline setup - there's always only one render + // pass. + RenderPassKey last_update_render_pass_key_; + VkRenderPass last_update_render_pass_ = VK_NULL_HANDLE; + // The pitch is not used on the fragment shader interlock path. + uint32_t last_update_framebuffer_pitch_tiles_at_32bpp_ = 0; + // The attachments are not used on the fragment shader interlock path. + const RenderTarget* const* + last_update_framebuffer_attachments_[1 + xenos::kMaxColorRenderTargets] = {}; + const Framebuffer* last_update_framebuffer_ = VK_NULL_HANDLE; + + // For host render targets. + + // Can only be destroyed when framebuffers referencing it are destroyed! + class VulkanRenderTarget final : public RenderTarget { + public: + static constexpr VkPipelineStageFlags kColorDrawStageMask = + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + static constexpr VkAccessFlags kColorDrawAccessMask = + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + static constexpr VkImageLayout kColorDrawLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + static constexpr VkPipelineStageFlags kDepthDrawStageMask = + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + static constexpr VkAccessFlags kDepthDrawAccessMask = + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + static constexpr VkImageLayout kDepthDrawLayout = + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + + // Takes ownership of the Vulkan objects passed to the constructor. + VulkanRenderTarget(RenderTargetKey key, VulkanRenderTargetCache& render_target_cache, + VkImage image, VkDeviceMemory memory, VkImageView view_depth_color, + VkImageView view_depth_stencil, VkImageView view_stencil, + VkImageView view_srgb, VkImageView view_color_transfer_separate, + size_t descriptor_set_index_transfer_source) + : RenderTarget(key), + render_target_cache_(render_target_cache), + image_(image), + memory_(memory), + view_depth_color_(view_depth_color), + view_depth_stencil_(view_depth_stencil), + view_stencil_(view_stencil), + view_srgb_(view_srgb), + view_color_transfer_separate_(view_color_transfer_separate), + descriptor_set_index_transfer_source_(descriptor_set_index_transfer_source) {} + ~VulkanRenderTarget(); + + VkImage image() const { return image_; } + + VkImageView view_depth_color() const { return view_depth_color_; } + VkImageView view_depth_stencil() const { return view_depth_stencil_; } + VkImageView view_color_transfer_separate() const { return view_color_transfer_separate_; } + VkImageView view_color_transfer() const { + return view_color_transfer_separate_ != VK_NULL_HANDLE ? view_color_transfer_separate_ + : view_depth_color_; + } + VkDescriptorSet GetDescriptorSetTransferSource() const { + ui::vulkan::SingleLayoutDescriptorSetPool& descriptor_set_pool = + key().is_depth ? *render_target_cache_.descriptor_set_pool_sampled_image_x2_ + : *render_target_cache_.descriptor_set_pool_sampled_image_; + return descriptor_set_pool.Get(descriptor_set_index_transfer_source_); + } + + static void GetDrawUsage(bool is_depth, VkPipelineStageFlags* stage_mask_out, + VkAccessFlags* access_mask_out, VkImageLayout* layout_out) { + if (stage_mask_out) { + *stage_mask_out = is_depth ? kDepthDrawStageMask : kColorDrawStageMask; + } + if (access_mask_out) { + *access_mask_out = is_depth ? kDepthDrawAccessMask : kColorDrawAccessMask; + } + if (layout_out) { + *layout_out = is_depth ? kDepthDrawLayout : kColorDrawLayout; + } + } + void GetDrawUsage(VkPipelineStageFlags* stage_mask_out, VkAccessFlags* access_mask_out, + VkImageLayout* layout_out) const { + GetDrawUsage(key().is_depth, stage_mask_out, access_mask_out, layout_out); + } + VkPipelineStageFlags current_stage_mask() const { return current_stage_mask_; } + VkAccessFlags current_access_mask() const { return current_access_mask_; } + VkImageLayout current_layout() const { return current_layout_; } + void SetUsage(VkPipelineStageFlags stage_mask, VkAccessFlags access_mask, + VkImageLayout layout) { + current_stage_mask_ = stage_mask; + current_access_mask_ = access_mask; + current_layout_ = layout; + } + + uint32_t temporary_sort_index() const { return temporary_sort_index_; } + void SetTemporarySortIndex(uint32_t index) { temporary_sort_index_ = index; } + + private: + VulkanRenderTargetCache& render_target_cache_; + + VkImage image_; + VkDeviceMemory memory_; + + // TODO(Triang3l): Per-format drawing views for mutable formats with EDRAM + // aliasing without transfers. + VkImageView view_depth_color_; + // Optional views. + VkImageView view_depth_stencil_; + VkImageView view_stencil_; + VkImageView view_srgb_; + VkImageView view_color_transfer_separate_; + + // 2 sampled images for depth / stencil, 1 sampled image for color. + size_t descriptor_set_index_transfer_source_; + + VkPipelineStageFlags current_stage_mask_ = 0; + VkAccessFlags current_access_mask_ = 0; + VkImageLayout current_layout_ = VK_IMAGE_LAYOUT_UNDEFINED; + + // Temporary storage for indices in operations like transfers and dumps. + uint32_t temporary_sort_index_ = 0; + }; + + struct FramebufferKey { + RenderPassKey render_pass_key; + + // Same as RenderTargetKey::pitch_tiles_at_32bpp. + uint32_t pitch_tiles_at_32bpp : 8; // 8 + // [0, 2047]. + uint32_t depth_base_tiles : xenos::kEdramBaseTilesBits; // 19 + uint32_t color_0_base_tiles : xenos::kEdramBaseTilesBits; // 30 + + uint32_t color_1_base_tiles : xenos::kEdramBaseTilesBits; // 43 + uint32_t color_2_base_tiles : xenos::kEdramBaseTilesBits; // 54 + + uint32_t color_3_base_tiles : xenos::kEdramBaseTilesBits; // 75 + + // Including all the padding, for a stable hash. + FramebufferKey() { Reset(); } + FramebufferKey(const FramebufferKey& key) { std::memcpy(this, &key, sizeof(*this)); } + FramebufferKey& operator=(const FramebufferKey& key) { + std::memcpy(this, &key, sizeof(*this)); + return *this; + } + bool operator==(const FramebufferKey& key) const { + return std::memcmp(this, &key, sizeof(*this)) == 0; + } + using Hasher = rex::XXHasher; + void Reset() { std::memset(this, 0, sizeof(*this)); } + }; + + enum TransferUsedDescriptorSet : uint32_t { + // Ordered from the least to the most frequently changed. + kTransferUsedDescriptorSetHostDepthBuffer, + kTransferUsedDescriptorSetHostDepthStencilTextures, + kTransferUsedDescriptorSetDepthStencilTextures, + // Mutually exclusive with kTransferUsedDescriptorSetDepthStencilTextures. + kTransferUsedDescriptorSetColorTexture, + + kTransferUsedDescriptorSetCount, + + kTransferUsedDescriptorSetHostDepthBufferBit = uint32_t(1) + << kTransferUsedDescriptorSetHostDepthBuffer, + kTransferUsedDescriptorSetHostDepthStencilTexturesBit = + uint32_t(1) << kTransferUsedDescriptorSetHostDepthStencilTextures, + kTransferUsedDescriptorSetDepthStencilTexturesBit = + uint32_t(1) << kTransferUsedDescriptorSetDepthStencilTextures, + kTransferUsedDescriptorSetColorTextureBit = uint32_t(1) + << kTransferUsedDescriptorSetColorTexture, + }; + + // 32-bit push constants (for simplicity of size calculation and to avoid + // std140 packing issues). + enum TransferUsedPushConstantDword : uint32_t { + kTransferUsedPushConstantDwordHostDepthAddress, + kTransferUsedPushConstantDwordAddress, + // Changed 8 times per transfer. + kTransferUsedPushConstantDwordStencilMask, + + kTransferUsedPushConstantDwordCount, + + kTransferUsedPushConstantDwordHostDepthAddressBit = + uint32_t(1) << kTransferUsedPushConstantDwordHostDepthAddress, + kTransferUsedPushConstantDwordAddressBit = uint32_t(1) << kTransferUsedPushConstantDwordAddress, + kTransferUsedPushConstantDwordStencilMaskBit = uint32_t(1) + << kTransferUsedPushConstantDwordStencilMask, + }; + + enum class TransferPipelineLayoutIndex { + kColor, + kDepth, + kColorToStencilBit, + kDepthToStencilBit, + kColorAndHostDepthTexture, + kColorAndHostDepthBuffer, + kDepthAndHostDepthTexture, + kDepthAndHostDepthBuffer, + + kCount, + }; + + struct TransferPipelineLayoutInfo { + uint32_t used_descriptor_sets; + uint32_t used_push_constant_dwords; + }; + + static const TransferPipelineLayoutInfo + kTransferPipelineLayoutInfos[size_t(TransferPipelineLayoutIndex::kCount)]; + + enum class TransferMode : uint32_t { + kColorToDepth, + kColorToColor, + + kDepthToDepth, + kDepthToColor, + + kColorToStencilBit, + kDepthToStencilBit, + + // Two-source modes, using the host depth if it, when converted to the guest + // format, matches what's in the owner source (not modified, keep host + // precision), or the guest data otherwise (significantly modified, possibly + // cleared). Stencil for FragStencilRef is always taken from the guest + // source. + + kColorAndHostDepthToDepth, + // When using different source and destination depth formats. + kDepthAndHostDepthToDepth, + + // If host depth is fetched, but it's the same image as the destination, + // it's copied to the EDRAM buffer (but since it's just a scratch buffer, + // with tiles laid out linearly with the same pitch as in the original + // render target; also no swapping of 40-sample columns as opposed to the + // host render target - this is done only for the color source) and fetched + // from there instead of the host depth texture. + kColorAndHostDepthCopyToDepth, + kDepthAndHostDepthCopyToDepth, + + kCount, + }; + + enum class TransferOutput { + kColor, + kDepth, + kStencilBit, + }; + + struct TransferModeInfo { + TransferOutput output; + TransferPipelineLayoutIndex pipeline_layout; + }; + + static const TransferModeInfo kTransferModes[size_t(TransferMode::kCount)]; + + union TransferShaderKey { + uint32_t key; + struct { + xenos::MsaaSamples dest_msaa_samples : xenos::kMsaaSamplesBits; + uint32_t dest_color_rt_index : xenos::kColorRenderTargetIndexBits; + uint32_t dest_resource_format : xenos::kRenderTargetFormatBits; + xenos::MsaaSamples source_msaa_samples : xenos::kMsaaSamplesBits; + // Always 1x when the host depth is a copy from a buffer rather than an + // image, not to create the same pipeline for different MSAA sample counts + // as it doesn't matter in this case. + xenos::MsaaSamples host_depth_source_msaa_samples : xenos::kMsaaSamplesBits; + uint32_t source_resource_format : xenos::kRenderTargetFormatBits; + + // Last bits because this affects the pipeline layout - after sorting, + // only change it as fewer times as possible. Depth buffers have an + // additional stencil texture. + static_assert(size_t(TransferMode::kCount) <= (size_t(1) << 4)); + TransferMode mode : 4; + }; + + TransferShaderKey() : key(0) { static_assert_size(*this, sizeof(key)); } + + struct Hasher { + size_t operator()(const TransferShaderKey& key) const { + return std::hash{}(key.key); + } + }; + bool operator==(const TransferShaderKey& other_key) const { return key == other_key.key; } + bool operator!=(const TransferShaderKey& other_key) const { return !(*this == other_key); } + bool operator<(const TransferShaderKey& other_key) const { return key < other_key.key; } + }; + + struct TransferPipelineKey { + RenderPassKey render_pass_key; + TransferShaderKey shader_key; + + TransferPipelineKey(RenderPassKey render_pass_key, TransferShaderKey shader_key) + : render_pass_key(render_pass_key), shader_key(shader_key) {} + + struct Hasher { + size_t operator()(const TransferPipelineKey& key) const { + XXH3_state_t hash_state; + XXH3_64bits_reset(&hash_state); + XXH3_64bits_update(&hash_state, &key.render_pass_key, sizeof(key.render_pass_key)); + XXH3_64bits_update(&hash_state, &key.shader_key, sizeof(key.shader_key)); + return static_cast(XXH3_64bits_digest(&hash_state)); + } + }; + bool operator==(const TransferPipelineKey& other_key) const { + return render_pass_key == other_key.render_pass_key && shader_key == other_key.shader_key; + } + bool operator!=(const TransferPipelineKey& other_key) const { return !(*this == other_key); } + bool operator<(const TransferPipelineKey& other_key) const { + if (render_pass_key != other_key.render_pass_key) { + return render_pass_key < other_key.render_pass_key; + } + return shader_key < other_key.shader_key; + } + }; + + union TransferAddressConstant { + uint32_t constant; + struct { + // All in tiles. + uint32_t dest_pitch : xenos::kEdramPitchTilesBits; + uint32_t source_pitch : xenos::kEdramPitchTilesBits; + // Destination base in tiles minus source base in tiles (not vice versa + // because this is a transform of the coordinate system, not addresses + // themselves). + // + 1 bit because this is a signed difference between two EDRAM bases. + // 0 for host_depth_source_is_copy (ignored in this case anyway as + // destination == source anyway). + int32_t source_to_dest : xenos::kEdramBaseTilesBits + 1; + }; + TransferAddressConstant() : constant(0) { static_assert_size(*this, sizeof(constant)); } + bool operator==(const TransferAddressConstant& other_constant) const { + return constant == other_constant.constant; + } + bool operator!=(const TransferAddressConstant& other_constant) const { + return !(*this == other_constant); + } + }; + + struct TransferInvocation { + Transfer transfer; + TransferShaderKey shader_key; + TransferInvocation(const Transfer& transfer, const TransferShaderKey& shader_key) + : transfer(transfer), shader_key(shader_key) {} + bool operator<(const TransferInvocation& other_invocation) const { + // TODO(Triang3l): See if it may be better to sort by the source in the + // first place, especially when reading the same data multiple times (like + // to write the stencil bits after depth) for better read locality. + // Sort by the shader key primarily to reduce pipeline state (context) + // switches. + if (shader_key != other_invocation.shader_key) { + return shader_key < other_invocation.shader_key; + } + // Host depth render targets are changed rarely if they exist, won't save + // many binding changes, ignore them for simplicity (their existence is + // caught by the shader key change). + assert_not_null(transfer.source); + assert_not_null(other_invocation.transfer.source); + uint32_t source_index = + static_cast(transfer.source)->temporary_sort_index(); + uint32_t other_source_index = + static_cast(other_invocation.transfer.source) + ->temporary_sort_index(); + if (source_index != other_source_index) { + return source_index < other_source_index; + } + return transfer.start_tiles < other_invocation.transfer.start_tiles; + } + bool CanBeMergedIntoOneDraw(const TransferInvocation& other_invocation) const { + return shader_key == other_invocation.shader_key && + transfer.AreSourcesSame(other_invocation.transfer); + } + }; + + union DumpPipelineKey { + uint32_t key; + struct { + xenos::MsaaSamples msaa_samples : 2; + uint32_t resource_format : 4; + // Last bit because this affects the pipeline - after sorting, only change + // it at most once. Depth buffers have an additional stencil SRV. + uint32_t is_depth : 1; + }; + + DumpPipelineKey() : key(0) { static_assert_size(*this, sizeof(key)); } + + struct Hasher { + size_t operator()(const DumpPipelineKey& key) const { return std::hash{}(key.key); } + }; + bool operator==(const DumpPipelineKey& other_key) const { return key == other_key.key; } + bool operator!=(const DumpPipelineKey& other_key) const { return !(*this == other_key); } + bool operator<(const DumpPipelineKey& other_key) const { return key < other_key.key; } + + xenos::ColorRenderTargetFormat GetColorFormat() const { + assert_false(is_depth); + return xenos::ColorRenderTargetFormat(resource_format); + } + xenos::DepthRenderTargetFormat GetDepthFormat() const { + assert_true(is_depth); + return xenos::DepthRenderTargetFormat(resource_format); + } + }; + + // There's no strict dependency on the group size in dumping, for simplicity + // calculations especially with resolution scaling, dividing manually (as the + // group size is not unlimited). The only restriction is that an integer + // multiple of it must be 80x16 samples (and no larger than that) for 32bpp, + // or 40x16 samples for 64bpp (because only a half of the pair of tiles may + // need to be dumped). Using 8x16 since that's 128 - the minimum required + // group size on Vulkan, and the maximum number of lanes in a subgroup on + // Vulkan. + static constexpr uint32_t kDumpSamplesPerGroupX = 8; + static constexpr uint32_t kDumpSamplesPerGroupY = 16; + + union DumpPitches { + uint32_t pitches; + struct { + // Both in tiles. + uint32_t dest_pitch : xenos::kEdramPitchTilesBits; + uint32_t source_pitch : xenos::kEdramPitchTilesBits; + }; + DumpPitches() : pitches(0) { static_assert_size(*this, sizeof(pitches)); } + bool operator==(const DumpPitches& other_pitches) const { + return pitches == other_pitches.pitches; + } + bool operator!=(const DumpPitches& other_pitches) const { return !(*this == other_pitches); } + }; + + union DumpOffsets { + uint32_t offsets; + struct { + // May be beyond the EDRAM tile count in case of EDRAM addressing + // wrapping, thus + 1 bit. + uint32_t dispatch_first_tile : xenos::kEdramBaseTilesBits + 1; + uint32_t source_base_tiles : xenos::kEdramBaseTilesBits; + }; + DumpOffsets() : offsets(0) { static_assert_size(*this, sizeof(offsets)); } + bool operator==(const DumpOffsets& other_offsets) const { + return offsets == other_offsets.offsets; + } + bool operator!=(const DumpOffsets& other_offsets) const { return !(*this == other_offsets); } + }; + + enum DumpDescriptorSet : uint32_t { + // Never changes. Same in both color and depth pipeline layouts, keep the + // first for pipeline layout compatibility, to only have to set it once. + kDumpDescriptorSetEdram, + // One resolve may need multiple sources. Different descriptor set layouts + // for color and depth. + kDumpDescriptorSetSource, + + kDumpDescriptorSetCount, + }; + + enum DumpPushConstant : uint32_t { + // May be different for different sources. + kDumpPushConstantPitches, + // May be changed multiple times for the same source. + kDumpPushConstantOffsets, + + kDumpPushConstantCount, + }; + + struct DumpInvocation { + ResolveCopyDumpRectangle rectangle; + DumpPipelineKey pipeline_key; + DumpInvocation(const ResolveCopyDumpRectangle& rectangle, const DumpPipelineKey& pipeline_key) + : rectangle(rectangle), pipeline_key(pipeline_key) {} + bool operator<(const DumpInvocation& other_invocation) const { + // Sort by the pipeline key primarily to reduce pipeline state (context) + // switches. + if (pipeline_key != other_invocation.pipeline_key) { + return pipeline_key < other_invocation.pipeline_key; + } + assert_not_null(rectangle.render_target); + uint32_t render_target_index = + static_cast(rectangle.render_target)->temporary_sort_index(); + const ResolveCopyDumpRectangle& other_rectangle = other_invocation.rectangle; + uint32_t other_render_target_index = + static_cast(other_rectangle.render_target) + ->temporary_sort_index(); + if (render_target_index != other_render_target_index) { + return render_target_index < other_render_target_index; + } + if (rectangle.row_first != other_rectangle.row_first) { + return rectangle.row_first < other_rectangle.row_first; + } + return rectangle.row_first_start < other_rectangle.row_first_start; + } + }; + + struct DirectResolvePushConstants { + draw_util::ResolveCopyShaderConstants resolve; + uint32_t source_base_tiles; + uint32_t source_pitch_tiles; + uint32_t dispatch_first_tile; + }; + + struct DirectResolvePipelineKey { + DumpPipelineKey dump_pipeline_key; + draw_util::ResolveCopyShaderIndex copy_shader; + bool draw_resolution_scaled; + uint64_t packed() const { + return uint64_t(dump_pipeline_key.key) | (uint64_t(size_t(copy_shader)) << 32) | + (uint64_t(draw_resolution_scaled ? 1 : 0) << 40); + } + struct Hasher { + size_t operator()(const DirectResolvePipelineKey& key) const { + return std::hash{}(key.packed()); + } + }; + bool operator==(const DirectResolvePipelineKey& other_key) const { + return packed() == other_key.packed(); + } + }; + + // Returns the framebuffer object, or VK_NULL_HANDLE if failed to create. + const Framebuffer* GetHostRenderTargetsFramebuffer( + RenderPassKey render_pass_key, uint32_t pitch_tiles_at_32bpp, + const RenderTarget* const* depth_and_color_render_targets); + + VkShaderModule GetTransferShader(TransferShaderKey key); + // With sample-rate shading, returns a pointer to one pipeline. Without + // sample-rate shading, returns a pointer to as many pipelines as there are + // samples. If there was a failure to create a pipeline, returns nullptr. + VkPipeline const* GetTransferPipelines(TransferPipelineKey key); + + // Do ownership transfers for render targets - each render target / vector may + // be null / empty in case there's nothing to do for them. + // resolve_clear_rectangle is expected to be provided by + // PrepareHostRenderTargetsResolveClear which should do all the needed size + // bound checks. + void PerformTransfersAndResolveClears( + uint32_t render_target_count, RenderTarget* const* render_targets, + const std::vector* render_target_transfers, + const uint64_t* render_target_resolve_clear_values = nullptr, + const Transfer::Rectangle* resolve_clear_rectangle = nullptr); + + VkPipeline GetDumpPipeline(DumpPipelineKey key); + VkPipeline GetDirectResolvePipeline(DirectResolvePipelineKey key); + bool TryResolveCopyDirectly(const draw_util::ResolveInfo& resolve_info, + draw_util::ResolveCopyShaderIndex copy_shader, + bool draw_resolution_scaled); + + // Writes contents of host render targets within rectangles from + // ResolveInfo::GetCopyEdramTileSpan to edram_buffer_. + bool DumpRenderTargets(uint32_t dump_base, uint32_t dump_row_length_used, uint32_t dump_rows, + uint32_t dump_pitch); + + bool gamma_render_target_as_unorm16_ = false; + + bool depth_unorm24_vulkan_format_supported_ = false; + bool depth_float24_round_ = false; + bool depth_float24_convert_in_pixel_shader_ = false; + + bool msaa_2x_attachments_supported_ = false; + bool msaa_2x_no_attachments_supported_ = false; + bool color_16bit_transfer_uint_formats_supported_ = true; + bool color_32bit_transfer_uint_formats_supported_ = true; + bool color_rg16_draw_format_fallback_to_float_ = false; + bool color_rgba16_draw_format_fallback_to_float_ = false; + + // VK_NULL_HANDLE if failed to create. + std::unordered_map render_passes_; + + std::unordered_map framebuffers_; + + // Set 0 - EDRAM storage buffer, set 1 - source depth sampled image (and + // unused stencil from the transfer descriptor set), HostDepthStoreConstants + // passed via push constants. + VkPipelineLayout host_depth_store_pipeline_layout_ = VK_NULL_HANDLE; + VkPipeline host_depth_store_pipelines_[size_t(xenos::MsaaSamples::k4X) + 1] = {}; + + std::unique_ptr transfer_vertex_buffer_pool_; + VkShaderModule transfer_passthrough_vertex_shader_ = VK_NULL_HANDLE; + VkPipelineLayout transfer_pipeline_layouts_[size_t(TransferPipelineLayoutIndex::kCount)] = {}; + // VK_NULL_HANDLE if failed to create. + std::unordered_map + transfer_shaders_; + // With sample-rate shading, one pipeline per entry. Without sample-rate + // shading, one pipeline per sample per entry. VK_NULL_HANDLE if failed to + // create. + std::unordered_map, TransferPipelineKey::Hasher> + transfer_pipelines_; + + VkPipelineLayout dump_pipeline_layout_color_ = VK_NULL_HANDLE; + VkPipelineLayout dump_pipeline_layout_depth_ = VK_NULL_HANDLE; + // Compute pipelines for copying host render target contents to the EDRAM + // buffer. VK_NULL_HANDLE if failed to create. + std::unordered_map dump_pipelines_; + VkPipelineLayout direct_resolve_pipeline_layout_color_ = VK_NULL_HANDLE; + VkPipelineLayout direct_resolve_pipeline_layout_depth_ = VK_NULL_HANDLE; + std::unordered_map + direct_resolve_pipelines_; + + // Temporary storage for Resolve. + std::vector clear_transfers_[2]; + + // Temporary storage for PerformTransfersAndResolveClears. + std::vector current_transfer_invocations_; + + // Temporary storage for DumpRenderTargets. + std::vector dump_rectangles_; + std::vector dump_invocations_; + std::vector direct_resolve_dispatches_; + uint64_t direct_resolve_attempt_count_ = 0; + uint64_t direct_resolve_success_count_ = 0; + uint64_t direct_resolve_fallback_count_ = 0; + + // For traces. + VkBuffer edram_snapshot_download_buffer_ = VK_NULL_HANDLE; + VkDeviceMemory edram_snapshot_download_buffer_memory_ = VK_NULL_HANDLE; + uint32_t edram_snapshot_download_buffer_memory_type_ = UINT32_MAX; + VkDeviceSize edram_snapshot_download_buffer_memory_size_ = 0; + std::unique_ptr edram_snapshot_restore_pool_; + void ResetTraceDownload(); + + // For pixel (fragment) shader interlock. + + VkRenderPass fsi_render_pass_ = VK_NULL_HANDLE; + Framebuffer fsi_framebuffer_; + + VkPipelineLayout resolve_fsi_clear_pipeline_layout_ = VK_NULL_HANDLE; + VkPipeline resolve_fsi_clear_32bpp_pipeline_ = VK_NULL_HANDLE; + VkPipeline resolve_fsi_clear_64bpp_pipeline_ = VK_NULL_HANDLE; +}; + +} // namespace rex::graphics::vulkan diff --git a/include/rex/graphics/vulkan/shader.h b/include/rex/graphics/vulkan/shader.h new file mode 100644 index 0000000..28e87e3 --- /dev/null +++ b/include/rex/graphics/vulkan/shader.h @@ -0,0 +1,65 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include + +namespace rex::graphics::vulkan { + +class VulkanShader : public SpirvShader { + public: + class VulkanTranslation : public SpirvTranslation { + public: + explicit VulkanTranslation(VulkanShader& shader, uint64_t modification) + : SpirvTranslation(shader, modification) {} + ~VulkanTranslation() override; + + VkShaderModule GetOrCreateShaderModule(); + VkShaderModule shader_module() const { return shader_module_; } + + private: + VkShaderModule shader_module_ = VK_NULL_HANDLE; + }; + + explicit VulkanShader(const ui::vulkan::VulkanDevice* vulkan_device, + xenos::ShaderType shader_type, uint64_t ucode_data_hash, + const uint32_t* ucode_dwords, size_t ucode_dword_count, + std::endian ucode_source_endian = std::endian::big); + + // For owning subsystem like the pipeline cache, accessors for unique + // identifiers (used instead of hashes to make sure collisions can't happen) + // of binding layouts used by the shader, for invalidation if a shader with an + // incompatible layout has been bound. + size_t GetTextureBindingLayoutUserUID() const { return texture_binding_layout_user_uid_; } + size_t GetSamplerBindingLayoutUserUID() const { return sampler_binding_layout_user_uid_; } + // Modifications of the same shader can be translated on different threads. + // The "set" function must only be called if "enter" returned true - these are + // set up only once. + bool EnterBindingLayoutUserUIDSetup() { return !binding_layout_user_uids_set_up_.test_and_set(); } + void SetTextureBindingLayoutUserUID(size_t uid) { texture_binding_layout_user_uid_ = uid; } + void SetSamplerBindingLayoutUserUID(size_t uid) { sampler_binding_layout_user_uid_ = uid; } + + protected: + Translation* CreateTranslationInstance(uint64_t modification) override; + + private: + const ui::vulkan::VulkanDevice* vulkan_device_; + + std::atomic_flag binding_layout_user_uids_set_up_ = ATOMIC_FLAG_INIT; + size_t texture_binding_layout_user_uid_ = 0; + size_t sampler_binding_layout_user_uid_ = 0; +}; + +} // namespace rex::graphics::vulkan diff --git a/include/rex/graphics/vulkan/shared_memory.h b/include/rex/graphics/vulkan/shared_memory.h new file mode 100644 index 0000000..8c3f93f --- /dev/null +++ b/include/rex/graphics/vulkan/shared_memory.h @@ -0,0 +1,88 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace rex::graphics::vulkan { + +class VulkanCommandProcessor; + +class VulkanSharedMemory : public SharedMemory { + public: + VulkanSharedMemory(VulkanCommandProcessor& command_processor, memory::Memory& memory, + TraceWriter& trace_writer, VkPipelineStageFlags guest_shader_pipeline_stages); + ~VulkanSharedMemory() override; + + bool Initialize(); + void Shutdown(bool from_destructor = false); + + void CompletedSubmissionUpdated(); + void EndSubmission(); + + enum class Usage { + // Index buffer, vfetch, compute read, transfer source. + kRead, + // Index buffer, vfetch, memexport. + kGuestDrawReadWrite, + kComputeWrite, + kTransferDestination, + }; + // Inserts a pipeline barrier for the target usage, also ensuring consecutive + // read-write accesses are ordered with each other. + void Use(Usage usage, std::pair written_range = {}); + + VkBuffer buffer() const { return buffer_; } + + // Returns true if any downloads were submitted to the command processor. + bool InitializeTraceSubmitDownloads(); + void InitializeTraceCompleteDownloads(); + + protected: + bool AllocateSparseHostGpuMemoryRange(uint32_t offset_allocations, + uint32_t length_allocations) override; + + bool UploadRanges(const std::vector>& upload_page_ranges) override; + + private: + void GetUsageMasks(Usage usage, VkPipelineStageFlags& stage_mask, + VkAccessFlags& access_mask) const; + + VulkanCommandProcessor& command_processor_; + TraceWriter& trace_writer_; + VkPipelineStageFlags guest_shader_pipeline_stages_; + + VkBuffer buffer_ = VK_NULL_HANDLE; + uint32_t buffer_memory_type_; + // Single for non-sparse, every allocation so far for sparse. + std::vector buffer_memory_; + + Usage last_usage_; + std::pair last_written_range_; + + std::unique_ptr upload_buffer_pool_; + std::vector upload_regions_; + + // Created temporarily, only for downloading. + VkBuffer trace_download_buffer_ = VK_NULL_HANDLE; + VkDeviceMemory trace_download_buffer_memory_ = VK_NULL_HANDLE; + void ResetTraceDownload(); +}; + +} // namespace rex::graphics::vulkan diff --git a/include/rex/graphics/vulkan/texture_cache.h b/include/rex/graphics/vulkan/texture_cache.h new file mode 100644 index 0000000..04856ee --- /dev/null +++ b/include/rex/graphics/vulkan/texture_cache.h @@ -0,0 +1,394 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace rex::graphics::vulkan { + +class VulkanCommandProcessor; + +class VulkanTextureCache final : public TextureCache { + public: + // Sampler parameters that can be directly converted to a host sampler or used + // for checking whether samplers bindings are up to date. + union SamplerParameters { + uint32_t value; + struct { + xenos::ClampMode clamp_x : 3; // 3 + xenos::ClampMode clamp_y : 3; // 6 + xenos::ClampMode clamp_z : 3; // 9 + xenos::BorderColor border_color : 2; // 11 + uint32_t mag_linear : 1; // 12 + uint32_t min_linear : 1; // 13 + uint32_t mip_linear : 1; // 14 + xenos::AnisoFilter aniso_filter : 3; // 17 + uint32_t mip_min_level : 4; // 21 + uint32_t mip_base_map : 1; // 22 + // Maximum mip level is in the texture resource itself, but mip_base_map + // can be used to limit fetching to mip_min_level. + }; + + SamplerParameters() : value(0) { static_assert_size(*this, sizeof(value)); } + struct Hasher { + size_t operator()(const SamplerParameters& parameters) const { + return std::hash{}(parameters.value); + } + }; + bool operator==(const SamplerParameters& parameters) const { return value == parameters.value; } + bool operator!=(const SamplerParameters& parameters) const { return value != parameters.value; } + }; + + // Transient descriptor set layouts must be initialized in the command + // processor. + static std::unique_ptr Create( + const RegisterFile& register_file, VulkanSharedMemory& shared_memory, + uint32_t draw_resolution_scale_x, uint32_t draw_resolution_scale_y, + VulkanCommandProcessor& command_processor, + VkPipelineStageFlags guest_shader_pipeline_stages) { + std::unique_ptr texture_cache(new VulkanTextureCache( + register_file, shared_memory, draw_resolution_scale_x, draw_resolution_scale_y, + command_processor, guest_shader_pipeline_stages)); + if (!texture_cache->Initialize()) { + return nullptr; + } + return std::move(texture_cache); + } + + ~VulkanTextureCache(); + + void BeginSubmission(uint64_t new_submission_index) override; + void BeginFrame() override; + void EndFrame(); + + // Must be called within a frame - creates and untiles textures needed by + // shaders, and enqueues transitioning them into the sampled usage. This may + // bind compute pipelines (notifying the command processor about that), and + // also since it may insert deferred barriers, before flushing the barriers + // preceding host GPU work. + void RequestTextures(uint32_t used_texture_mask) override; + + VkImageView GetActiveBindingOrNullImageView(uint32_t fetch_constant_index, + xenos::FetchOpDimension dimension, bool is_signed); + + SamplerParameters GetSamplerParameters(const VulkanShader::SamplerBinding& binding) const; + + // Must be called for every used sampler at least once in a single submission, + // and a submission must be open for this to be callable. + // Returns: + // - The sampler, if obtained successfully - and increases its last usage + // submission index - and has_overflown_out = false. + // - VK_NULL_HANDLE and has_overflown_out = true if there's a total sampler + // count overflow in a submission that potentially hasn't completed yet. + // - VK_NULL_HANDLE and has_overflown_out = false in case of a general failure + // to create a sampler. + VkSampler UseSampler(SamplerParameters parameters, bool& has_overflown_out); + // Returns the submission index to await (may be the current submission in + // case of an overflow within a single submission - in this case, it must be + // ended, and a new one must be started) in case of sampler count overflow, so + // samplers may be freed, and UseSamplers may take their slots. + uint64_t GetSubmissionToAwaitOnSamplerOverflow(uint32_t overflowed_sampler_count) const; + + // Returns the 2D view of the front buffer texture (for fragment shader + // reading - the barrier will be pushed in the command processor if needed), + // or VK_NULL_HANDLE in case of failure. May call LoadTextureData. + // If swap_source_needs_rb_swap_out is not nullptr, writes whether the final + // guest-to-host swizzle requires swapping red and blue (R <- B, B <- R) with + // green preserved, which is needed by the presentation fallback path on + // devices without imageViewFormatSwizzle. + VkImageView RequestSwapTexture(uint32_t& width_scaled_out, uint32_t& height_scaled_out, + xenos::TextureFormat& format_out, + uint32_t* width_unscaled_out = nullptr, + uint32_t* height_unscaled_out = nullptr, + bool* swap_source_needs_rb_swap_out = nullptr); + + bool GetScaledResolveRange(uint32_t start_unscaled, uint32_t length_unscaled, + uint32_t length_scaled_alignment_log2, uint64_t& start_scaled_out, + uint64_t& length_scaled_out) const; + bool CommitScaledResolveRange(uint32_t start_unscaled, uint32_t length_unscaled, + uint32_t length_scaled_alignment_log2 = 0) { + return EnsureScaledResolveMemoryCommitted(start_unscaled, length_unscaled, + length_scaled_alignment_log2); + } + VkBuffer scaled_resolve_buffer() const { return scaled_resolve_buffer_; } + void UseScaledResolveBufferForRead(); + void UseScaledResolveBufferForWrite(uint64_t written_start_scaled, + uint64_t written_length_scaled); + + protected: + bool IsSignedVersionSeparateForFormat(TextureKey key) const override; + bool IsScaledResolveSupportedForFormat(TextureKey key) const override; + uint32_t GetHostFormatSwizzle(TextureKey key) const override; + + uint32_t GetMaxHostTextureWidthHeight(xenos::DataDimension dimension) const override; + uint32_t GetMaxHostTextureDepthOrArraySize(xenos::DataDimension dimension) const override; + + std::unique_ptr CreateTexture(TextureKey key) override; + + bool EnsureScaledResolveMemoryCommitted(uint32_t start_unscaled, uint32_t length_unscaled, + uint32_t length_scaled_alignment_log2 = 0) override; + + bool LoadTextureDataFromResidentMemoryImpl(Texture& texture, bool load_base, + bool load_mips) override; + + void UpdateTextureBindingsImpl(uint32_t fetch_constant_mask) override; + + private: + enum LoadDescriptorSetIndex { + kLoadDescriptorSetIndexDestination, + kLoadDescriptorSetIndexSource, + kLoadDescriptorSetCount, + }; + + struct HostFormat { + LoadShaderIndex load_shader; + // Do NOT add integer formats to this - they are not filterable, can only be + // read with ImageFetch, not ImageSample! If any game is seen using + // num_format 1 for fixed-point formats (for floating-point, it's normally + // set to 1 though), add a constant buffer containing multipliers for the + // textures and multiplication to the tfetch implementation. + VkFormat format; + // Whether the format is block-compressed on the host (the host block size + // matches the guest format block size in this case), and isn't decompressed + // on load. + bool block_compressed; + + // Set up dynamically based on what's supported by the device. + bool linear_filterable; + }; + + struct HostFormatPair { + HostFormat format_unsigned; + HostFormat format_signed; + // Mapping of Xenos swizzle components to Vulkan format components. + uint32_t swizzle; + // Whether the unsigned and the signed formats are compatible for one image + // and the same image data (on a portability subset device, this should also + // take imageViewFormatReinterpretation into account). + bool unsigned_signed_compatible; + }; + + class VulkanTexture final : public Texture { + public: + enum class Usage { + kUndefined, + kTransferDestination, + kGuestShaderSampled, + kSwapSampled, + }; + + // Takes ownership of the image and its memory. + explicit VulkanTexture(VulkanTextureCache& texture_cache, const TextureKey& key, VkImage image, + VmaAllocation allocation, bool track_usage = true); + ~VulkanTexture(); + + VkImage image() const { return image_; } + + // Doesn't transition (the caller must insert the barrier). + Usage SetUsage(Usage new_usage) { + Usage old_usage = usage_; + usage_ = new_usage; + return old_usage; + } + + VkImageView GetView(bool is_signed, uint32_t host_swizzle, bool is_array = true); + VkImageView GetOrCreate3DAs2DImageView(bool is_signed, uint32_t host_swizzle); + + private: + union ViewKey { + uint32_t key; + struct { + uint32_t is_signed_separate_view : 1; + uint32_t host_swizzle : 12; + uint32_t is_array : 1; + }; + + ViewKey() : key(0) { static_assert_size(*this, sizeof(key)); } + + struct Hasher { + size_t operator()(const ViewKey& key) const { + return std::hash{}(key.key); + } + }; + bool operator==(const ViewKey& other_key) const { return key == other_key.key; } + bool operator!=(const ViewKey& other_key) const { return !(*this == other_key); } + }; + + static constexpr VkComponentSwizzle GetComponentSwizzle(uint32_t texture_swizzle, + uint32_t component_index) { + xenos::XE_GPU_TEXTURE_SWIZZLE texture_component_swizzle = + xenos::XE_GPU_TEXTURE_SWIZZLE((texture_swizzle >> (3 * component_index)) & 0b111); + if (texture_component_swizzle == xenos::XE_GPU_TEXTURE_SWIZZLE(component_index)) { + // The portability subset requires all swizzles to be IDENTITY, return + // IDENTITY specifically, not R, G, B, A. + return VK_COMPONENT_SWIZZLE_IDENTITY; + } + switch (texture_component_swizzle) { + case xenos::XE_GPU_TEXTURE_SWIZZLE_R: + return VK_COMPONENT_SWIZZLE_R; + case xenos::XE_GPU_TEXTURE_SWIZZLE_G: + return VK_COMPONENT_SWIZZLE_G; + case xenos::XE_GPU_TEXTURE_SWIZZLE_B: + return VK_COMPONENT_SWIZZLE_B; + case xenos::XE_GPU_TEXTURE_SWIZZLE_A: + return VK_COMPONENT_SWIZZLE_A; + case xenos::XE_GPU_TEXTURE_SWIZZLE_0: + return VK_COMPONENT_SWIZZLE_ZERO; + case xenos::XE_GPU_TEXTURE_SWIZZLE_1: + return VK_COMPONENT_SWIZZLE_ONE; + default: + // An invalid value. + return VK_COMPONENT_SWIZZLE_IDENTITY; + } + } + + VkImage image_; + VmaAllocation allocation_; + + Usage usage_ = Usage::kUndefined; + + std::unordered_map views_; + std::unique_ptr texture_3d_as_2d_; + VkImageView image_view_3d_as_2d_unsigned_ = VK_NULL_HANDLE; + VkImageView image_view_3d_as_2d_signed_ = VK_NULL_HANDLE; + }; + + struct VulkanTextureBinding { + VkImageView image_view_unsigned; + VkImageView image_view_signed; + + VulkanTextureBinding() { Reset(); } + + void Reset() { + image_view_unsigned = VK_NULL_HANDLE; + image_view_signed = VK_NULL_HANDLE; + } + }; + + struct Sampler { + VkSampler sampler; + bool uses_custom_border_color; + uint64_t last_usage_submission; + std::pair* used_previous; + std::pair* used_next; + }; + + static constexpr bool AreDimensionsCompatible(xenos::FetchOpDimension binding_dimension, + xenos::DataDimension resource_dimension) { + switch (binding_dimension) { + case xenos::FetchOpDimension::k1D: + case xenos::FetchOpDimension::k2D: + return resource_dimension == xenos::DataDimension::k1D || + resource_dimension == xenos::DataDimension::k2DOrStacked || + resource_dimension == xenos::DataDimension::k3D; + case xenos::FetchOpDimension::k3DOrStacked: + return resource_dimension == xenos::DataDimension::k3D; + case xenos::FetchOpDimension::kCube: + return resource_dimension == xenos::DataDimension::kCube; + default: + return false; + } + } + + explicit VulkanTextureCache(const RegisterFile& register_file, VulkanSharedMemory& shared_memory, + uint32_t draw_resolution_scale_x, uint32_t draw_resolution_scale_y, + VulkanCommandProcessor& command_processor, + VkPipelineStageFlags guest_shader_pipeline_stages); + + bool Initialize(); + bool InitializeScaledResolveBuffer(); + void ShutdownScaledResolveBuffer(); + + const HostFormatPair& GetHostFormatPair(TextureKey key) const; + + void GetTextureUsageMasks(VulkanTexture::Usage usage, VkPipelineStageFlags& stage_mask, + VkAccessFlags& access_mask, VkImageLayout& layout); + bool EnsureScaledResolveBufferAllocated(uint64_t start_scaled, uint64_t length_scaled); + void GetScaledResolveUsageMasks(VkPipelineStageFlags& stage_mask_out, + VkAccessFlags& access_mask_out, bool write) const; + + xenos::ClampMode NormalizeClampMode(xenos::ClampMode clamp_mode) const; + + VulkanCommandProcessor& command_processor_; + VkPipelineStageFlags guest_shader_pipeline_stages_; + + // Using the Vulkan Memory Allocator because texture count in games is + // naturally pretty much unbounded, while Vulkan implementations, especially + // on Windows versions before 10, may have an allocation count limit as low as + // 4096. + VmaAllocator vma_allocator_ = VK_NULL_HANDLE; + + static const HostFormatPair kBestHostFormats[64]; + static const HostFormatPair kHostFormatGBGRUnaligned; + static const HostFormatPair kHostFormatBGRGUnaligned; + static const HostFormatPair kHostFormatDXT1Unaligned; + static const HostFormatPair kHostFormatDXT2_3Unaligned; + static const HostFormatPair kHostFormatDXT4_5Unaligned; + static const HostFormatPair kHostFormatDXNUnaligned; + static const HostFormatPair kHostFormatDXT5AUnaligned; + HostFormatPair host_formats_[64]; + + VkPipelineLayout load_pipeline_layout_ = VK_NULL_HANDLE; + std::array load_pipelines_{}; + std::array load_pipelines_scaled_{}; + + // If both images can be placed in the same allocation, it's one allocation, + // otherwise it's two separate. + std::array null_images_memory_{}; + VkImage null_image_2d_array_cube_ = VK_NULL_HANDLE; + VkImage null_image_3d_ = VK_NULL_HANDLE; + VkImageView null_image_view_2d_array_ = VK_NULL_HANDLE; + VkImageView null_image_view_cube_ = VK_NULL_HANDLE; + VkImageView null_image_view_3d_ = VK_NULL_HANDLE; + bool null_images_cleared_ = false; + + std::array vulkan_texture_bindings_; + + // Unsupported texture formats used during this frame (for research and + // testing). + enum : uint8_t { + kUnsupportedResourceBit = 1, + kUnsupportedUnormBit = kUnsupportedResourceBit << 1, + kUnsupportedSnormBit = kUnsupportedUnormBit << 1, + }; + uint8_t unsupported_format_features_used_[64] = {}; + + uint32_t sampler_max_count_; + + xenos::AnisoFilter max_anisotropy_; + + std::unordered_map samplers_; + std::pair* sampler_used_first_ = nullptr; + std::pair* sampler_used_last_ = nullptr; + uint32_t custom_border_color_sampler_count_ = 0; + + VkBuffer scaled_resolve_buffer_ = VK_NULL_HANDLE; + uint64_t scaled_resolve_buffer_size_ = 0; + bool scaled_resolve_buffer_sparse_ = false; + uint32_t scaled_resolve_buffer_memory_type_ = UINT32_MAX; + std::vector scaled_resolve_buffer_memory_; + uint32_t scaled_resolve_sparse_granularity_log2_ = UINT32_MAX; + std::vector scaled_resolve_sparse_allocated_; + bool scaled_resolve_last_usage_write_ = false; + std::pair scaled_resolve_last_written_range_{0, 0}; +}; + +} // namespace rex::graphics::vulkan diff --git a/include/rex/graphics/xenos.h b/include/rex/graphics/xenos.h new file mode 100644 index 0000000..f7fd14e --- /dev/null +++ b/include/rex/graphics/xenos.h @@ -0,0 +1,1648 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include +#include +#include +#include +#include + +namespace rex::graphics { +namespace xenos { + +// enum types used in the GPU registers or the microcode must be : uint32_t or +// : int32_t, as Visual C++ restarts bit field packing when a field requires +// different alignment than the previous one, so only 32-bit types must be used +// in bit fields (registers are 32-bit, and the microcode consists of triples of +// 32-bit words). + +constexpr memory::fourcc_t kSwapSignature = memory::make_fourcc("SWAP"); + +enum class ShaderType : uint32_t { + kVertex = 0, + kPixel = 1, +}; + +// Only the lower 24 bits of the vertex index are used (tested on an Adreno 200 +// phone using a GL_UNSIGNED_INT element array buffer with junk in the upper 8 +// bits that had no effect on drawing). +constexpr uint32_t kVertexIndexBits = 24; +constexpr uint32_t kVertexIndexMask = (uint32_t(1) << kVertexIndexBits) - 1; + +enum class PrimitiveType : uint32_t { + kNone = 0x00, + kPointList = 0x01, + kLineList = 0x02, + kLineStrip = 0x03, + kTriangleList = 0x04, + kTriangleFan = 0x05, + kTriangleStrip = 0x06, + kTriangleWithWFlags = 0x07, + kRectangleList = 0x08, + kLineLoop = 0x0C, + kQuadList = 0x0D, + kQuadStrip = 0x0E, + kPolygon = 0x0F, + + // Starting with this primitive type, explicit major mode is assumed (in the + // R6xx/R7xx registers, k2DCopyRectListV0 is 22, and implicit major mode is + // only used for primitive types 0 through 21) - and tessellation patches use + // the range that starts from k2DCopyRectListV0. + // TODO(Triang3l): Verify if this is also true for the Xenos. + kExplicitMajorModeForceStart = 0x10, + + k2DCopyRectListV0 = 0x10, + k2DCopyRectListV1 = 0x11, + k2DCopyRectListV2 = 0x12, + k2DCopyRectListV3 = 0x13, + k2DFillRectList = 0x14, + k2DLineStrip = 0x15, + k2DTriStrip = 0x16, + + // Tessellation patches when VGT_OUTPUT_PATH_CNTL::path_select is + // VGTOutputPath::kTessellationEnable. The vertex shader receives the patch + // index rather than control point indices. + // With non-adaptive tessellation, VGT_DRAW_INITIATOR::num_indices is the + // patch count (4D5307F1 draws single ground patches by passing 1 as the index + // count). VGT_INDX_OFFSET is also applied to the patch index - 4D5307F1 uses + // auto-indexed patches with a nonzero VGT_INDX_OFFSET, which contains the + // base patch index there. + // With adaptive tessellation, however, num_indices is the number of + // tessellation factors in the "index buffer" reused for tessellation factors, + // which is the patch count multiplied by the edge count (if num_indices is + // multiplied further by 4 for quad patches for the ground in 4D5307F2, for + // example, some incorrect patches are drawn, so Xenia shouldn't do that; also + // 4D5307E6 draws water triangle patches with the number of indices that is 3 + // times the invocation count of the memexporting shader that calculates the + // tessellation factors for a single patch for each "point"). + kLinePatch = 0x10, + kTrianglePatch = 0x11, + kQuadPatch = 0x12, +}; + +// For the texture fetch constant (not the tfetch instruction), stacked stored +// as 2D. +enum class DataDimension : uint32_t { + k1D = 0, + k2DOrStacked = 1, + k3D = 2, + kCube = 3, +}; + +enum class ClampMode : uint32_t { + kRepeat = 0, + kMirroredRepeat = 1, + kClampToEdge = 2, + kMirrorClampToEdge = 3, + kClampToHalfway = 4, + kMirrorClampToHalfway = 5, + kClampToBorder = 6, + kMirrorClampToBorder = 7, +}; + +constexpr bool ClampModeUsesBorder(ClampMode clamp_mode) { + return clamp_mode == ClampMode::kClampToBorder || clamp_mode == ClampMode::kMirrorClampToBorder; +} + +// TEX_FORMAT_COMP, known as GPUSIGN on the Xbox 360. +enum class TextureSign : uint32_t { + kUnsigned = 0, + // Two's complement texture data. + kSigned = 1, + // 2*color-1 - https://xboxforums.create.msdn.com/forums/t/107374.aspx + kUnsignedBiased = 2, + // Linearized when sampled. + kGamma = 3, +}; + +enum class TextureFilter : uint32_t { + kPoint = 0, + kLinear = 1, + // Only applicable to the mip filter - like OpenGL minification filters + // GL_NEAREST / GL_LINEAR without MIPMAP_NEAREST / MIPMAP_LINEAR. + kBaseMap = 2, + kUseFetchConst = 3, +}; + +enum class AnisoFilter : uint32_t { + kDisabled = 0, + kMax_1_1 = 1, + kMax_2_1 = 2, + kMax_4_1 = 3, + kMax_8_1 = 4, + kMax_16_1 = 5, + kUseFetchConst = 7, +}; + +enum class BorderColor : uint32_t { + // (0.0, 0.0, 0.0) + // TODO(Triang3l): Is the alpha 0 or 1? + k_ABGR_Black = 0, + // (1.0, 1.0, 1.0, 1.0) + k_ABGR_White = 1, + // Unknown precisely, but likely (0.5, 0.0, 0.5) for unsigned (Cr, Y, Cb) + // TODO(Triang3l): Real hardware border color, and is the alpha 0 or 1? + k_ACBYCR_Black = 2, + // Unknown precisely, but likely (0.0, 0.5, 0.5) for unsigned (Y, Cr, Cb) + // TODO(Triang3l): Real hardware border color, and is the alpha 0 or 1? + k_ACBCRY_Black = 3, +}; + +// For the tfetch instruction (not the fetch constant) and related instructions, +// stacked accessed using tfetch3D. +enum class FetchOpDimension : uint32_t { + k1D = 0, + k2D = 1, + k3DOrStacked = 2, + kCube = 3, +}; + +inline int GetFetchOpDimensionComponentCount(FetchOpDimension dimension) { + switch (dimension) { + case FetchOpDimension::k1D: + return 1; + case FetchOpDimension::k2D: + return 2; + case FetchOpDimension::k3DOrStacked: + case FetchOpDimension::kCube: + return 3; + default: + assert_unhandled_case(dimension); + return 1; + } +} + +enum class SampleLocation : uint32_t { + kCentroid = 0, + kCenter = 1, +}; + +enum class Endian : uint32_t { + kNone = 0, + k8in16 = 1, + k8in32 = 2, + k16in32 = 3, +}; + +enum class Endian128 : uint32_t { + kNone = 0, + k8in16 = 1, + k8in32 = 2, + k16in32 = 3, + k8in64 = 4, + k8in128 = 5, +}; + +enum class IndexFormat : uint32_t { + kInt16, + // Not very common, but used for some world draws in 545407E0. + kInt32, +}; + +// SurfaceNumberX from yamato_enum.h. +enum class SurfaceNumberFormat : uint32_t { + kUnsignedRepeatingFraction = 0, + // Microsoft-style, scale factor (2^(n-1))-1. + kSignedRepeatingFraction = 1, + kUnsignedInteger = 2, + kSignedInteger = 3, + kFloat = 7, +}; + +// The EDRAM is an opaque block of memory accessible by the RB (render backend) +// pipeline stage of the GPU, which performs output-merger functionality (color +// render target writing and blending, depth and stencil testing) and resolve +// (copy) operations. +// +// Data in the 10 MiB of EDRAM is laid out as 2048 tiles on 80x16 32bpp MSAA +// samples. With 2x MSAA, one pixel consists of 1x2 samples, and with 4x, it +// consists of 2x2 samples. Thus, for a 32bpp render target, one tile contains +// 80x16 pixels without MSAA, samples of 80x8 pixels with 2x MSAA, or samples of +// 40x8 pixels with 4x MSAA. The base is specified in tiles, the pitch is also +// treated as tiles (so a 256x single-sampled surface will be stored in the +// EDRAM as 320x). +// +// XGSurfaceSize code in game executables calculates the size in tiles in the +// following order: +// 1) If MSAA is >=2x, multiply the height by 2. +// 2) If MSAA is 4x, multiply the width by 2. +// 3) 80x16-align width and height in samples. +// 4) Multiply width*height in samples by 4 or 8 depending on the pixel format. +// 5) Divide the byte size by 5120. +// This means that when working with layout of surfaces in the EDRAM, it should +// be assumed that a multisampled surface is the same as a single-sampled +// surface with 2x height and (with 4x MSAA) width - however, format size +// doesn't effect the dimensions, 64bpp surfaces take twice as many tiles as +// 32bpp surfaces. +// +// From this, it follows that the tile row pitch in tiles can be multiplied by +// 64bpp too. In the formula for calculating the tile count: +// (height rounded up to 16) * (width rounded up to 80) * (4 or 8) / 5120 +// the fraction can be reduced because the numerator is always divisible by +// 5120 - it changes in 80 * 16 * 4 = 5120 increments - in tile increments - +// resulting in: +// (height in tiles) * (width in tiles) * (1 or 2) +// Here we get only multiplication, which (disregarding the variable size) is +// associative for integers, so: +// ((height in tiles) * (width in tiles)) * (1 or 2) +// is identical to: +// (height in tiles) * ((width in tiles) * (1 or 2)) +// +// Depth surfaces are also stored as 32bpp tiles, however, as opposed to color +// surfaces, 40x16-sample halves of each tile are swapped - game shaders (for +// example, in 4D5307E6 main menu, 545407F2) perform this swapping when writing +// specific depth/stencil values by drawing to a depth buffer's memory through a +// color render target (to reupload a depth/stencil surface previously evicted +// from the EDRAM to the main memory, for instance). +// +// EDRAM addressing is circular - a render target may be backed by a EDRAM range +// that extends beyond 2048 tiles, in which case, what would go to the tile 2048 +// will actually be in tile 0, tile 2049 will go to tile 1, and so on. 4D5307F1 +// heavily relies on this behavior for its depth buffer. Specifically, it's used +// the following way: +// - First, a depth-only 1120x720 2xMSAA pass is performed with the depth buffer +// in tiles [1008, 2268), or [1008, 2048) and [0, 220). +// - Then, the depth buffer in [1008, 2268) is resolved into a texture, later +// used in screen-space effects. +// - The upper 1120x576 bin is drawn into the color buffer in [0, 1008), using +// the [1008, 2016) portion of the previously populated depth buffer for early +// depth testing (there seems to be no true early Z on the Xenos, only early +// hi-Z, but still it possibly needs to be in sync with the per-sample depth +// buffer), and overwriting the tail of the previously filled depth buffer in +// [0, 220). +// - The lower 1120x144 bin is drawn without the pregenerated depth buffer data. + +enum class MsaaSamples : uint32_t { + k1X = 0, + k2X = 1, + k4X = 2, +}; + +constexpr uint32_t kMsaaSamplesBits = 2; + +constexpr uint32_t kColorRenderTargetIndexBits = 2; +constexpr uint32_t kMaxColorRenderTargets = 4; + +enum class ColorRenderTargetFormat : uint32_t { + k_8_8_8_8 = 0, + k_8_8_8_8_GAMMA = 1, + k_2_10_10_10 = 2, + // 7e3 [0, 32) RGB, unorm alpha. + // http://fileadmin.cs.lth.se/cs/Personal/Michael_Doggett/talks/eg05-xenos-doggett.pdf + k_2_10_10_10_FLOAT = 3, + // Fixed point -32...32. + // http://www.students.science.uu.nl/~3220516/advancedgraphics/papers/inferred_lighting.pdf + k_16_16 = 4, + // Fixed point -32...32. + k_16_16_16_16 = 5, + k_16_16_FLOAT = 6, + k_16_16_16_16_FLOAT = 7, + k_2_10_10_10_AS_10_10_10_10 = 10, + // 16-bit fixed point at half speed, with full blending. + // http://fileadmin.cs.lth.se/cs/Personal/Michael_Doggett/talks/unc-xenos-doggett.pdf + k_2_10_10_10_FLOAT_AS_16_16_16_16 = 12, + k_32_FLOAT = 14, + k_32_32_FLOAT = 15, +}; + +const char* GetColorRenderTargetFormatName(ColorRenderTargetFormat format); + +constexpr bool IsColorRenderTargetFormat64bpp(ColorRenderTargetFormat format) { + return format == ColorRenderTargetFormat::k_16_16_16_16 || + format == ColorRenderTargetFormat::k_16_16_16_16_FLOAT || + format == ColorRenderTargetFormat::k_32_32_FLOAT; +} + +inline uint32_t GetColorRenderTargetFormatComponentCount(ColorRenderTargetFormat format) { + switch (format) { + case ColorRenderTargetFormat::k_8_8_8_8: + case ColorRenderTargetFormat::k_8_8_8_8_GAMMA: + case ColorRenderTargetFormat::k_2_10_10_10: + case ColorRenderTargetFormat::k_2_10_10_10_FLOAT: + case ColorRenderTargetFormat::k_16_16_16_16: + case ColorRenderTargetFormat::k_16_16_16_16_FLOAT: + case ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: + case ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16: + return 4; + case ColorRenderTargetFormat::k_16_16: + case ColorRenderTargetFormat::k_16_16_FLOAT: + case ColorRenderTargetFormat::k_32_32_FLOAT: + return 2; + case ColorRenderTargetFormat::k_32_FLOAT: + return 1; + default: + assert_unhandled_case(format); + return 0; + } +} + +// Returns the version of the format with the same packing and meaning of values +// stored in it, but without blending precision modifiers. +constexpr ColorRenderTargetFormat GetStorageColorFormat(ColorRenderTargetFormat format) { + switch (format) { + case ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: + return ColorRenderTargetFormat::k_2_10_10_10; + case ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16: + return ColorRenderTargetFormat::k_2_10_10_10_FLOAT; + default: + return format; + } +} + +enum class DepthRenderTargetFormat : uint32_t { + kD24S8 = 0, + // 20e4 [0, 2). + kD24FS8 = 1, +}; + +const char* GetDepthRenderTargetFormatName(DepthRenderTargetFormat format); + +float PWLGammaToLinear(float gamma); +float LinearToPWLGamma(float linear); + +// Converts Xenos floating-point 7e3 color value in bits 0:9 (not clamping) to +// an IEEE-754 32-bit floating-point number. +float Float7e3To32(uint32_t f10); +// Converts 24-bit unorm depth in the value (not clamping) to an IEEE-754 32-bit +// floating-point number. +// Converts an IEEE-754 32-bit floating-point number to Xenos floating-point +// depth, rounding to the nearest even or towards zero. +uint32_t Float32To20e4(float f32, bool round_to_nearest_even); +// Converts Xenos floating-point depth in bits 0:23 (not clamping) to an +// IEEE-754 32-bit floating-point number. +float Float20e4To32(uint32_t f24); +// Converts 24-bit unorm depth in the value (not clamping) to an IEEE-754 32-bit +// floating-point number. +constexpr float UNorm24To32(uint32_t n24) { + // Not 1.0f / 16777215.0f as that gives an incorrect result (like for a very + // common 0xC00000 which clears 2_10_10_10 to 0001). Division by 2^24 is just + // an exponent shift though, thus exact. + // Division by 16777215.0f behaves this way. + return float(n24 + (n24 >> 23)) * (1.0f / float(1 << 24)); +} + +// Scale for conversion of slope scales from PA_SU_POLY_OFFSET_FRONT/BACK_SCALE +// units to those used when the slope is computed from the difference between +// adjacent pixels, for conversion from the guest to common host APIs or to +// calculation using max(|ddx(z)|, |ddy(z)|). +// "slope computed in subpixels (1/12 or 1/16)" - R5xx Acceleration. +// But the correct scale for conversion of the slope scale from subpixels to +// pixels is likely 1/16 according to: +// https://github.com/mesa3d/mesa/blob/54ad9b444c8e73da498211870e785239ad3ff1aa/src/gallium/drivers/radeonsi/si_state.c#L946 +constexpr float kPolygonOffsetScaleSubpixelUnit = 1.0f / 16.0f; + +constexpr uint32_t kColorRenderTargetFormatBits = 4; +constexpr uint32_t kDepthRenderTargetFormatBits = 1; +constexpr uint32_t kRenderTargetFormatBits = + std::max(kColorRenderTargetFormatBits, kDepthRenderTargetFormatBits); + +constexpr uint32_t kEdramTileWidthSamples = 80; +constexpr uint32_t kEdramTileHeightSamples = 16; +constexpr uint32_t kEdramTileCount = 2048; +constexpr uint32_t kEdramSizeBytes = + kEdramTileCount * kEdramTileHeightSamples * kEdramTileWidthSamples * sizeof(uint32_t); + +// RB_SURFACE_INFO::surface_pitch width. +constexpr uint32_t kEdramPitchPixelsBits = 14; +// The part of RB_COLOR_INFO::color_base and RB_DEPTH_INFO::depth_base width +// usable on the Xenos, which has periodic 11-bit EDRAM tile addressing. +constexpr uint32_t kEdramBaseTilesBits = 11; + +constexpr uint32_t GetSurfacePitchTiles(uint32_t pitch_pixels, MsaaSamples msaa_samples, + bool is_64bpp) { + uint32_t pitch_samples = pitch_pixels << uint32_t(msaa_samples >= MsaaSamples::k4X); + uint32_t pitch_tiles = (pitch_samples + (kEdramTileWidthSamples - 1)) / kEdramTileWidthSamples; + if (is_64bpp) { + pitch_tiles <<= 1; + } + return pitch_tiles; +} + +// log2_ceil of the maximum value of GetSurfacePitchTiles, assuming 16383 being +// the maximum pitch in pixels (not sure about the validity of values above +// 8192, but to avoid bounds checking). +// log2_ceil of 16383, multiplied by 2 for 4x MSAA, rounded to 80 samples, +// multiplied by 2 for 64bpp. +constexpr uint32_t kEdramPitchTilesBits = 10; + +constexpr uint32_t kFormatBits = 6; + +// a2xx_sq_surfaceformat + +// https://github.com/indirivacua/RAGE-Console-Texture-Editor/blob/master/Console.Xbox360.Graphics.pas +enum class TextureFormat : uint32_t { + k_1_REVERSE = 0, + k_1 = 1, + k_8 = 2, + k_1_5_5_5 = 3, + k_5_6_5 = 4, + k_6_5_5 = 5, + k_8_8_8_8 = 6, + k_2_10_10_10 = 7, + // Possibly similar to k_8, but may be storing alpha instead of red when + // resolving/memexporting, though not exactly known. From the point of view of + // sampling, it should be treated the same as k_8 (given that textures have + // the last - and single-component textures have the only - component + // replicated into all the remaining ones before the swizzle). + // Used as: + // - Texture in 4B4E083C - text, starting from the "Loading..." and the "This + // game saves data automatically" messages. The swizzle in the fetch + // constant is 111W (suggesting that internally the only component may be + // the alpha one, not red). + // TODO(Triang3l): Investigate how k_8_A and k_8_B work in resolves and + // memexports, whether they store alpha/blue of the input or red. + k_8_A = 8, + k_8_B = 9, + k_8_8 = 10, + // Though it's unknown what exactly REP means, likely it's "repeating + // fraction" (the term used for normalized fixed-point formats, UNORM in + // particular for unsigned signedness - 0.0 to 1.0 range, like in + // Direct3D 10+, unlike the 0.0 to 255.0 range for D3DFMT_R8G8_B8G8 and + // D3DFMT_G8R8_G8B8 in Direct3D 9). 54540829 uses k_Y1_Cr_Y0_Cb_REP directly + // as UNORM. + k_Cr_Y1_Cb_Y0_REP = 11, + // Used for videos in 54540829. + k_Y1_Cr_Y0_Cb_REP = 12, + k_16_16_EDRAM = 13, + // Likely same as k_8_8_8_8. + // Used as: + // - Memexport destination in 4D5308BC - multiple small draws when looking + // back at the door behind the player in the first room of gameplay. + // - Memexport destination in 4D53085B and 4D530919 - in 4D53085B, in a frame + // between the intro video and the main menu, in a 8192-point draw. + k_8_8_8_8_A = 14, + k_4_4_4_4 = 15, + k_10_11_11 = 16, + k_11_11_10 = 17, + k_DXT1 = 18, + k_DXT2_3 = 19, + k_DXT4_5 = 20, + k_16_16_16_16_EDRAM = 21, + k_24_8 = 22, + k_24_8_FLOAT = 23, + k_16 = 24, + k_16_16 = 25, + k_16_16_16_16 = 26, + k_16_EXPAND = 27, + k_16_16_EXPAND = 28, + k_16_16_16_16_EXPAND = 29, + k_16_FLOAT = 30, + k_16_16_FLOAT = 31, + k_16_16_16_16_FLOAT = 32, + k_32 = 33, + k_32_32 = 34, + k_32_32_32_32 = 35, + k_32_FLOAT = 36, + k_32_32_FLOAT = 37, + k_32_32_32_32_FLOAT = 38, + k_32_AS_8 = 39, + k_32_AS_8_8 = 40, + k_16_MPEG = 41, + k_16_16_MPEG = 42, + k_8_INTERLACED = 43, + k_32_AS_8_INTERLACED = 44, + k_32_AS_8_8_INTERLACED = 45, + k_16_INTERLACED = 46, + k_16_MPEG_INTERLACED = 47, + k_16_16_MPEG_INTERLACED = 48, + k_DXN = 49, + k_8_8_8_8_AS_16_16_16_16 = 50, + k_DXT1_AS_16_16_16_16 = 51, + k_DXT2_3_AS_16_16_16_16 = 52, + k_DXT4_5_AS_16_16_16_16 = 53, + k_2_10_10_10_AS_16_16_16_16 = 54, + k_10_11_11_AS_16_16_16_16 = 55, + k_11_11_10_AS_16_16_16_16 = 56, + k_32_32_32_FLOAT = 57, + k_DXT3A = 58, + k_DXT5A = 59, + k_CTX1 = 60, + k_DXT3A_AS_1_1_1_1 = 61, + k_8_8_8_8_GAMMA_EDRAM = 62, + k_2_10_10_10_FLOAT_EDRAM = 63, +}; + +// Subset of a2xx_sq_surfaceformat - formats that RTs can be resolved to. +enum class ColorFormat : uint32_t { + k_8 = 2, + k_1_5_5_5 = 3, + k_5_6_5 = 4, + k_6_5_5 = 5, + k_8_8_8_8 = 6, + k_2_10_10_10 = 7, + k_8_A = 8, + k_8_B = 9, + k_8_8 = 10, + k_8_8_8_8_A = 14, + k_4_4_4_4 = 15, + k_10_11_11 = 16, + k_11_11_10 = 17, + k_16 = 24, + k_16_16 = 25, + k_16_16_16_16 = 26, + k_16_FLOAT = 30, + k_16_16_FLOAT = 31, + k_16_16_16_16_FLOAT = 32, + k_32_FLOAT = 36, + k_32_32_FLOAT = 37, + k_32_32_32_32_FLOAT = 38, + k_8_8_8_8_AS_16_16_16_16 = 50, + k_2_10_10_10_AS_16_16_16_16 = 54, + k_10_11_11_AS_16_16_16_16 = 55, + k_11_11_10_AS_16_16_16_16 = 56, +}; + +// Resolve writes unsigned data for fixed-point formats (so k_16_16 and +// k_16_16_16_16 render target formats, which are signed and also have a +// different range, are not equivalent to the respective texture formats). +constexpr bool IsColorResolveFormatBitwiseEquivalent(ColorRenderTargetFormat render_target_format, + ColorFormat color_format) { + switch (render_target_format) { + case ColorRenderTargetFormat::k_8_8_8_8: + // Shaders fetch data copied from k_8_8_8_8_GAMMA with TextureSign::kGamma. + case ColorRenderTargetFormat::k_8_8_8_8_GAMMA: + // TODO(Triang3l): Investigate k_8_8_8_8_A. + return color_format == ColorFormat::k_8_8_8_8 || color_format == ColorFormat::k_8_8_8_8_A || + color_format == ColorFormat::k_8_8_8_8_AS_16_16_16_16; + case ColorRenderTargetFormat::k_2_10_10_10: + case ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: + return color_format == ColorFormat::k_2_10_10_10 || + color_format == ColorFormat::k_2_10_10_10_AS_16_16_16_16; + case ColorRenderTargetFormat::k_16_16_FLOAT: + return color_format == ColorFormat::k_16_16_FLOAT; + case ColorRenderTargetFormat::k_16_16_16_16_FLOAT: + return color_format == ColorFormat::k_16_16_16_16_FLOAT; + case ColorRenderTargetFormat::k_32_FLOAT: + return color_format == ColorFormat::k_32_FLOAT; + case ColorRenderTargetFormat::k_32_32_FLOAT: + return color_format == ColorFormat::k_32_32_FLOAT; + default: + return false; + } +} + +enum class VertexFormat : uint32_t { + kUndefined = 0, + k_8_8_8_8 = 6, + k_2_10_10_10 = 7, + k_10_11_11 = 16, + k_11_11_10 = 17, + k_16_16 = 25, + k_16_16_16_16 = 26, + k_16_16_FLOAT = 31, + k_16_16_16_16_FLOAT = 32, + k_32 = 33, + k_32_32 = 34, + k_32_32_32_32 = 35, + k_32_FLOAT = 36, + k_32_32_FLOAT = 37, + k_32_32_32_32_FLOAT = 38, + k_32_32_32_FLOAT = 57, +}; + +inline int GetVertexFormatComponentCount(VertexFormat format) { + switch (format) { + case VertexFormat::k_32: + case VertexFormat::k_32_FLOAT: + return 1; + case VertexFormat::k_16_16: + case VertexFormat::k_16_16_FLOAT: + case VertexFormat::k_32_32: + case VertexFormat::k_32_32_FLOAT: + return 2; + case VertexFormat::k_10_11_11: + case VertexFormat::k_11_11_10: + case VertexFormat::k_32_32_32_FLOAT: + return 3; + case VertexFormat::k_8_8_8_8: + case VertexFormat::k_2_10_10_10: + case VertexFormat::k_16_16_16_16: + case VertexFormat::k_16_16_16_16_FLOAT: + case VertexFormat::k_32_32_32_32: + case VertexFormat::k_32_32_32_32_FLOAT: + return 4; + default: + assert_unhandled_case(format); + return 0; + } +} + +inline uint32_t GetVertexFormatNeededWords(VertexFormat format, uint32_t used_components) { + assert_zero(used_components & ~uint32_t(0b1111)); + if (!used_components) { + return 0; + } + switch (format) { + case VertexFormat::k_8_8_8_8: + case VertexFormat::k_2_10_10_10: + return 0b0001; + case VertexFormat::k_10_11_11: + case VertexFormat::k_11_11_10: + return (used_components & 0b0111) ? 0b0001 : 0b0000; + case VertexFormat::k_16_16: + case VertexFormat::k_16_16_FLOAT: + return (used_components & 0b0011) ? 0b0001 : 0b0000; + case VertexFormat::k_16_16_16_16: + case VertexFormat::k_16_16_16_16_FLOAT: + return ((used_components & 0b0011) ? 0b0001 : 0b0000) | + ((used_components & 0b1100) ? 0b0010 : 0b0000); + case VertexFormat::k_32: + case VertexFormat::k_32_FLOAT: + return used_components & 0b0001; + case VertexFormat::k_32_32: + case VertexFormat::k_32_32_FLOAT: + return used_components & 0b0011; + case VertexFormat::k_32_32_32_32: + case VertexFormat::k_32_32_32_32_FLOAT: + return used_components; + case VertexFormat::k_32_32_32_FLOAT: + return used_components & 0b0111; + default: + assert_unhandled_case(format); + return 0b0000; + } +} + +enum class CompareFunction : uint32_t { + kNever = 0b000, + kLess = 0b001, + kEqual = 0b010, + kLessEqual = 0b011, + kGreater = 0b100, + kNotEqual = 0b101, + kGreaterEqual = 0b110, + kAlways = 0b111, +}; + +enum class StencilOp : uint32_t { + kKeep = 0, + kZero = 1, + kReplace = 2, + kIncrementClamp = 3, + kDecrementClamp = 4, + kInvert = 5, + kIncrementWrap = 6, + kDecrementWrap = 7, +}; + +// adreno_rb_blend_factor +enum class BlendFactor : uint32_t { + kZero = 0, + kOne = 1, + kSrcColor = 4, + kOneMinusSrcColor = 5, + kSrcAlpha = 6, + kOneMinusSrcAlpha = 7, + kDstColor = 8, + kOneMinusDstColor = 9, + kDstAlpha = 10, + kOneMinusDstAlpha = 11, + kConstantColor = 12, + kOneMinusConstantColor = 13, + kConstantAlpha = 14, + kOneMinusConstantAlpha = 15, + kSrcAlphaSaturate = 16, + // SRC1 added on Adreno. +}; + +enum class BlendOp : uint32_t { + kAdd = 0, + kSubtract = 1, + kMin = 2, + kMax = 3, + kRevSubtract = 4, +}; + +typedef enum { + XE_GPU_INVALIDATE_MASK_VERTEX_SHADER = 1 << 8, + XE_GPU_INVALIDATE_MASK_PIXEL_SHADER = 1 << 9, + + XE_GPU_INVALIDATE_MASK_ALL = 0x7FFF, +} XE_GPU_INVALIDATE_MASK; + +// VGT_DRAW_INITIATOR::DI_SRC_SEL_* +enum class SourceSelect : uint32_t { + kDMA, + kImmediate, + kAutoIndex, +}; + +// VGT_DRAW_INITIATOR::DI_MAJOR_MODE_* +enum class MajorMode : uint32_t { + kImplicit, + kExplicit, +}; + +inline bool IsMajorModeExplicit(MajorMode major_mode, PrimitiveType primitive_type) { + return major_mode != MajorMode::kImplicit || + primitive_type >= PrimitiveType::kExplicitMajorModeForceStart; +} + +enum class SignedRepeatingFractionMode : uint32_t { + // Microsoft-style representation with two -1 representations (one is slightly + // past -1 but clamped). + kZeroClampMinusOne, + // OpenGL "alternate mapping" format lacking representation for zero. + kNoZero, +}; + +// Arbitrary filter is still present in the Code Aurora Forum release of the +// Adreno 200 programming interface, but is deprecated according to the +// IPR2015-00325 R400 Document Library Folder History: +// "Change 124923 on 2003/10/03 by jhoule@jhoule_doc_lt +// [...] +// Deprecated the ARBITRARY_FILTER fields from TFetch instr+const." +enum class ArbitraryFilter : uint32_t { + k2x4Sym = 0, + k2x4Asym = 1, + k4x2Sym = 2, + k4x2Asym = 3, + k4x4Sym = 4, + k4x4Asym = 5, + kUseFetchConst = 7, +}; + +constexpr uint32_t kMaxShaderTempRegistersLog2 = 6; +constexpr uint32_t kMaxShaderTempRegisters = UINT32_C(1) << kMaxShaderTempRegistersLog2; + +// a2xx_sq_ps_vtx_mode +enum class VertexShaderExportMode : uint32_t { + kPosition1Vector = 0, + kPosition2VectorsSprite = 2, + kPosition2VectorsEdge = 3, + kPosition2VectorsKill = 4, + kPosition2VectorsSpriteKill = 5, + kPosition2VectorsEdgeKill = 6, + // Vertex shader outputs are ignored (kill all primitives) - see + // SX_MISC::MULTIPASS on R6xx/R7xx. + kMultipass = 7, +}; + +constexpr uint32_t kMaxInterpolators = 16; + +enum class SampleControl : uint32_t { + kCentroidsOnly = 0, + kCentersOnly = 1, + kCentroidsAndCenters = 2, +}; + +// - msaa_samples is RB_SURFACE_INFO::msaa_samples. +// - sample_control is SQ_CONTEXT_MISC::sc_sample_cntl. +// - interpolator_control_sampling_pattern is +// SQ_INTERPOLATOR_CNTL::sampling_pattern. +// Centroid interpolation can be tested in 5454082B. If the GPU host backend +// implements guest MSAA properly, using host MSAA, with everything interpolated +// at centers, the Monument Valley start screen background may have a few +// distinctly bright pixels on the mesas/buttes, where extrapolation happens. +// Interpolating certain values (ones that aren't used for gradient calculation, +// not texture coordinates) at centroids fixes this issue. +inline uint32_t GetInterpolatorSamplingPattern(MsaaSamples msaa_samples, + SampleControl sample_control, + uint32_t interpolator_control_sampling_pattern) { + if (msaa_samples == MsaaSamples::k1X || sample_control == SampleControl::kCentersOnly) { + return ((1 << kMaxInterpolators) - 1) * uint32_t(SampleLocation::kCenter); + } + if (sample_control == SampleControl::kCentroidsOnly) { + return ((1 << kMaxInterpolators) - 1) * uint32_t(SampleLocation::kCentroid); + } + assert_true(sample_control == SampleControl::kCentroidsAndCenters); + return interpolator_control_sampling_pattern; +} + +enum class VGTOutputPath : uint32_t { + kVertexReuse = 0, + kTessellationEnable = 1, + kPassthru = 2, +}; + +enum class TessellationMode : uint32_t { + kDiscrete = 0, + kContinuous = 1, + kAdaptive = 2, +}; + +enum class PolygonModeEnable : uint32_t { + kDisabled = 0, // Render triangles. + kDualMode = 1, // Send 2 sets of 3 polygons with the specified polygon type. + // 4541096E uses 2 for triangles, which is "reserved" on R6xx and not defined + // on Adreno 2xx, but polymode_front/back_ptype are 0 (points) in this case in + // 4541096E, which should not be respected for non-kDualMode as the title + // wants to draw filled triangles. +}; + +enum class PolygonType : uint32_t { + kPoints = 0, + kLines = 1, + kTriangles = 2, +}; + +enum class PixelCenter : uint32_t { + // Pixel center at vertex positions .0, like in Direct3D 9. + // Commonly used in Xbox 360 games. + kD3DZero = 0, + // Pixel center at vertex positions .5, like in OpenGL. + // Used in 415607E6. + kOGLHalf = 1, +}; + +enum class VertexRounding : uint32_t { + kTruncate = 0, // OpenGL. + kRound = 1, + kRoundToEven = 2, // Direct3D. Common in Xbox 360 games. + kRoundToOdd = 3, +}; + +enum class VertexQuantization : uint32_t { + k_1_16th = 0, + k_1_8th = 1, + k_1_4th = 2, + k_1_2 = 3, + k_1 = 4, + // 1/256th was added in R600. On the Xbox 360, games normally use 1/16th. +}; + +enum class EdramMode : uint32_t { + kNoOperation = 0, + kColorDepth = 4, + // TODO(Triang3l): Verify whether kDepthOnly means the pixel shader is ignored + // completely even if it writes depth, exports to memory or kills pixels. + // Hints suggesting that it should be completely ignored (which is desirable + // on real hardware to avoid scheduling the pixel shader at all and waiting + // for it especially since the Xbox 360 doesn't have early per-sample depth / + // stencil, only early hi-Z / hi-stencil, and other registers possibly + // toggling pixel shader execution are yet to be found): + // - Most of depth pre-pass draws in 415607E6 use the kDepthOnly more with a + // `oC0 = tfetch2D(tf0, r0.xy) * r1` shader, some use `oC0 = r0` though. + // However, when alphatested surfaces are drawn, kColorDepth is explicitly + // used with the same shader performing the texture fetch. + // - 5454082B has some kDepthOnly draws with alphatest enabled, but the shader + // is `oC0 = r0`, which makes no sense (alphatest based on an interpolant + // from the vertex shader) as no texture alpha cutout is involved. + // - 5454082B also has kDepthOnly draws with pretty complex shaders clearly + // for use only in the color pass - even fetching and filtering a shadowmap. + // For now, based on these, let's assume the pixel shader is never used with + // kDepthOnly. + kDepthOnly = 5, + kCopy = 6, +}; + +// Xenos copies EDRAM contents to a tiled 2D or 3D texture (resolves - from +// "MSAA resolve", but this name is also used for single-sampled copying) by +// drawing primitives with the EDRAM mode EdramMode::kCopy. Pixels covered by +// the drawn geometry are copied. It's likely that only rectangular regions can +// be resolved. +// +// Resolve operation can write color data in ColorFormat formats, with or +// without MSAA color sample averaging, endian swap, red/blue swap, and exponent +// bias. Depth resolving likely has a lot more restrictions, considering sample +// averaging, red/blue swap and exponent bias would be pretty meaningless for it +// (also, Direct3D 9 specifies k_8_8_8_8 as RB_COPY_DEST_INFO::copy_dest_format +// for depth, which is clearly not true - the right format would be k_24_8 or +// k_24_8_FLOAT, so depth resolving likely doesn't support format conversion), +// though endian swap is supported. +// +// In addition, a resolve draw may clear the region it copies (this feature is +// commonly used when going to the next tile with predicated tiling). While one +// resolve draw call may copy just one color or depth buffer, it may clear both +// color and depth at once (or just color or depth, or nothing) if copying a +// color buffer (the color render target cleared is the same as the one copied - +// however, depth resolves have RB_COPY_CONTROL::copy_src_select 4, so they +// can't clear color). +// +// Direct3D 9 does resolving by drawing kRectangleList with 3 vertices with a +// vertex shader that accepts k_32_32_FLOAT vertices with k8in32 endianness in +// SHADER_CONSTANT_FETCH_00_0, with the half-pixel offset, according to the +// PA_SU_VTX_CNTL::pix_center setting, pre-applied to the vertices (for Direct3D +// 9 pixel centers, 0.5 must be added to the vertex positions to get the +// coordinates of the corners). +// +// The rectangle is used for both the source render target and the destination +// texture, according to how it's used in 4E4D07E9. +// +// Direct3D 9 gives the rectangle in source render target coordinates (for +// example, in 4D5307E6, the sniper rifle scope has a (128,64)->(448,256) +// rectangle). It doesn't adjust the EDRAM base pointer, otherwise (taking into +// account that 4x MSAA is used for the scope) it would have been +// (8,0)->(328,192), but it's not. However, it adjusts the destination texture +// address so (0,0) relative to the destination address is (0,0) relative to +// the render target (if resolving a part of a render target to the top-left +// corner of a texture, Direct3D 9 actually moves the destination pointer before +// the start of the texture, with tiled offset internally calculated for a +// negative offset). When copying, the pointer needs to be adjusted to the first +// 32x32 tile that will actually be modified, by adding the value of +// XGAddress2D/3DTiledOffset called for left/top & ~31. +// +// RB_COPY_DEST_PITCH's purpose appears to be not clamping or something like +// that, but just specifying pitch for going between rows, and height for going +// between 3D texture slices. copy_dest_pitch is rounded to 32 by Direct3D 9, +// copy_dest_height is not. In the 4D5307E6 sniper rifle scope example, +// copy_dest_pitch is 320, and copy_dest_height is 192 - the same as the resolve +// rectangle size (resolving from a 320x192 portion of the surface at 128,64 to +// the whole texture, at 0,0). Relative to RB_COPY_DEST_BASE, the height should +// have been 256, but it's not. Adreno doesn't have copy_dest_height at all (as +// well as RB_COPY_DEST_INFO::copy_dest_slice), suggesting (alongside the name +// of the register) that it exists purely to be able to go between 3D texture +// slices. +// +// Window scissor must also be applied - in the jigsaw puzzle in 58410955, there +// are 1280x720 resolve rectangles, but only the scissored 1280x256 needs to be +// copied, otherwise it overflows even beyond the EDRAM, and the depth buffer is +// visible on the screen. It also ensures the coordinates are not negative (in +// 565507D9, for example, the right tile is resolved with vertices +// (-640,0)->(640,720), however, the destination texture pointer is adjusted +// properly to the right half of the texture, and the source render target has a +// pitch of 800). + +// Granularity of offset and size in resolve operations is 8x8 pixels +// (GPU_RESOLVE_ALIGNMENT - for example, 4D5307E6 resolves a 24x16 region for a +// 18x10 texture, 8x8 region for a 1x1 texture). +// https://github.com/jmfauvel/CSGO-SDK/blob/master/game/client/view.cpp#L944 +// https://github.com/stanriders/hl2-asw-port/blob/master/src/game/client/vgui_int.cpp#L901 +constexpr uint32_t kResolveAlignmentPixelsLog2 = 3; +constexpr uint32_t kResolveAlignmentPixels = 1 << kResolveAlignmentPixelsLog2; + +// Same as RB_SURFACE_INFO::surface_pitch, RB_COPY_DEST_PITCH::copy_dest_pitch +// and RB_COPY_DEST_PITCH::copy_dest_height. +constexpr uint32_t kResolveSizeBits = 14; +constexpr uint32_t kMaxResolveSize = (1 << kResolveSizeBits) - kResolveAlignmentPixels; + +enum class CopyCommand : uint32_t { + kRaw = 0, + kConvert = 1, + kConstantOne = 2, + kNull = 3, // ? +}; + +// a2xx_rb_copy_sample_select +enum class CopySampleSelect : uint32_t { + k0, + k1, + k2, + k3, + k01, + k23, + k0123, +}; + +constexpr bool IsSingleCopySampleSelected(CopySampleSelect copy_sample_select) { + return copy_sample_select >= CopySampleSelect::k0 && copy_sample_select <= CopySampleSelect::k3; +} + +#define XE_GPU_MAKE_TEXTURE_SWIZZLE(x, y, z, w) \ + (((rex::graphics::xenos::XE_GPU_TEXTURE_SWIZZLE_##x) << 0) | \ + ((rex::graphics::xenos::XE_GPU_TEXTURE_SWIZZLE_##y) << 3) | \ + ((rex::graphics::xenos::XE_GPU_TEXTURE_SWIZZLE_##z) << 6) | \ + ((rex::graphics::xenos::XE_GPU_TEXTURE_SWIZZLE_##w) << 9)) +typedef enum { + XE_GPU_TEXTURE_SWIZZLE_X = 0, + XE_GPU_TEXTURE_SWIZZLE_R = 0, + XE_GPU_TEXTURE_SWIZZLE_Y = 1, + XE_GPU_TEXTURE_SWIZZLE_G = 1, + XE_GPU_TEXTURE_SWIZZLE_Z = 2, + XE_GPU_TEXTURE_SWIZZLE_B = 2, + XE_GPU_TEXTURE_SWIZZLE_W = 3, + XE_GPU_TEXTURE_SWIZZLE_A = 3, + XE_GPU_TEXTURE_SWIZZLE_0 = 4, + XE_GPU_TEXTURE_SWIZZLE_1 = 5, + XE_GPU_TEXTURE_SWIZZLE_RRRR = XE_GPU_MAKE_TEXTURE_SWIZZLE(R, R, R, R), + XE_GPU_TEXTURE_SWIZZLE_RGGG = XE_GPU_MAKE_TEXTURE_SWIZZLE(R, G, G, G), + XE_GPU_TEXTURE_SWIZZLE_RGBB = XE_GPU_MAKE_TEXTURE_SWIZZLE(R, G, B, B), + XE_GPU_TEXTURE_SWIZZLE_RGBA = XE_GPU_MAKE_TEXTURE_SWIZZLE(R, G, B, A), + XE_GPU_TEXTURE_SWIZZLE_0000 = XE_GPU_MAKE_TEXTURE_SWIZZLE(0, 0, 0, 0), +} XE_GPU_TEXTURE_SWIZZLE; + +inline uint16_t GpuSwap(uint16_t value, Endian endianness) { + switch (endianness) { + case Endian::kNone: + // No swap. + return value; + case Endian::k8in16: + // Swap bytes in half words. + return ((value << 8) & 0xFF00FF00) | ((value >> 8) & 0x00FF00FF); + default: + assert_unhandled_case(endianness); + return value; + } +} + +inline uint32_t GpuSwap(uint32_t value, Endian endianness) { + switch (endianness) { + default: + case Endian::kNone: + // No swap. + return value; + case Endian::k8in16: + // Swap bytes in half words. + return ((value << 8) & 0xFF00FF00) | ((value >> 8) & 0x00FF00FF); + case Endian::k8in32: + // Swap bytes. + // NOTE: we are likely doing two swaps here. Wasteful. Oh well. + return rex::byte_swap(value); + case Endian::k16in32: + // Swap half words. + return ((value >> 16) & 0xFFFF) | (value << 16); + } +} + +inline float GpuSwap(float value, Endian endianness) { + union { + uint32_t i; + float f; + } v; + v.f = value; + v.i = GpuSwap(v.i, endianness); + return v.f; +} + +inline uint32_t GpuToCpu(uint32_t p) { + return p; +} + +inline uint32_t CpuToGpu(uint32_t p) { + return p & 0x1FFFFFFF; +} + +// XE_GPU_REG_SHADER_CONSTANT_LOOP_* +union alignas(uint32_t) LoopConstant { + uint32_t value; + struct { + uint32_t count : 8; // +0 + // Address (aL) start and step. + // The resulting aL is `iterator * step + start`, 10-bit, and has the real + // range of [-256, 256], according to the IPR2015-00325 sequencer + // specification. + uint32_t start : 8; // +8 + int32_t step : 8; // +16 + uint32_t _pad_24 : 8; // +24 + }; +}; +static_assert_size(LoopConstant, sizeof(uint32_t)); + +// SQ_TEX_VTX_INVALID/VALID_TEXTURE/BUFFER +enum class FetchConstantType : uint32_t { + kInvalidTexture, + kInvalidVertex, + kTexture, + kVertex, +}; + +constexpr uint32_t kTextureFetchConstantCount = 32; +constexpr uint32_t kVertexFetchConstantCount = 3 * kTextureFetchConstantCount; + +// XE_GPU_REG_SHADER_CONSTANT_FETCH_* +union alignas(uint32_t) xe_gpu_vertex_fetch_t { + struct { + uint32_t dword_0; + uint32_t dword_1; + }; + struct { + FetchConstantType type : 2; // +0 + uint32_t address : 30; // +2 address in dwords + + Endian endian : 2; // +0 + uint32_t size : 24; // +2 size in words + uint32_t _pad_1_26 : 6; // +26 + }; +}; +static_assert_size(xe_gpu_vertex_fetch_t, sizeof(uint32_t) * 2); + +// Byte alignment of texture subresources in memory - of each mip and stack +// slice / cube face (and of textures themselves), this number of bits is also +// omitted from base_address and mip_address. +constexpr uint32_t kTextureSubresourceAlignmentBytesLog2 = 12; +constexpr uint32_t kTextureSubresourceAlignmentBytes = 1 << kTextureSubresourceAlignmentBytesLog2; + +// Texture fetch constant size field widths. +constexpr uint32_t kTexture1DMaxWidthLog2 = 24; +constexpr uint32_t kTexture1DMaxWidth = 1 << kTexture1DMaxWidthLog2; +constexpr uint32_t kTexture2DCubeMaxWidthHeightLog2 = 13; +constexpr uint32_t kTexture2DCubeMaxWidthHeight = 1 << kTexture2DCubeMaxWidthHeightLog2; +constexpr uint32_t kTexture2DMaxStackDepthLog2 = 6; +constexpr uint32_t kTexture2DMaxStackDepth = 1 << kTexture2DMaxStackDepthLog2; +constexpr uint32_t kTexture3DMaxWidthHeightLog2 = 11; +constexpr uint32_t kTexture3DMaxWidthHeight = 1 << kTexture3DMaxWidthHeightLog2; +constexpr uint32_t kTexture3DMaxDepthLog2 = 10; +constexpr uint32_t kTexture3DMaxDepth = 1 << kTexture3DMaxDepthLog2; + +constexpr uint32_t kTextureMaxMips = + std::max(kTexture2DCubeMaxWidthHeightLog2, kTexture3DMaxWidthHeightLog2) + 1; + +constexpr uint32_t kTextureTileWidthHeightLog2 = 5; +constexpr uint32_t kTextureTileWidthHeight = 1 << kTextureTileWidthHeightLog2; +// 3D tiled texture slices 0:3 and 4:7 are stored separately in memory, in +// non-overlapping ranges, but addressing in 4:7 is different than in 0:3. +constexpr uint32_t kTextureTileDepthLog2 = 2; +constexpr uint32_t kTextureTileDepth = 1 << kTextureTileDepthLog2; + +// Texture tile address function periods: +// - 2D 1bpb: 128x128 +// - 2D 2bpb: 64x64 +// - 2D 4bpb+: 32x32 +// - 3D 1bpb: 64x32x8 +// - 3D 2bpb+: 32x32x8 +constexpr uint32_t GetTextureTiledXBaseGranularityLog2(bool is_3d, uint32_t bytes_per_block_log2) { + return 7 - std::min(UINT32_C(2), bytes_per_block_log2 + uint32_t(is_3d)); +} +constexpr uint32_t GetTextureTiledYBaseGranularityLog2(bool is_3d, uint32_t bytes_per_block_log2) { + return is_3d ? 5 : (7 - std::min(UINT32_C(2), bytes_per_block_log2)); +} +constexpr uint32_t kTextureTiledZBaseGranularityLog2 = 3; +constexpr uint32_t kTextureTiledZBaseGranularity = 1 << kTextureTiledZBaseGranularityLog2; + +// Row pitch alignment of non-tiled textures. +constexpr uint32_t kTextureLinearRowAlignmentBytesLog2 = 8; +constexpr uint32_t kTextureLinearRowAlignmentBytes = 1 << kTextureLinearRowAlignmentBytesLog2; + +// XE_GPU_REG_SHADER_CONSTANT_FETCH_* +union alignas(uint32_t) xe_gpu_texture_fetch_t { + struct { + uint32_t dword_0; + uint32_t dword_1; + uint32_t dword_2; + uint32_t dword_3; + uint32_t dword_4; + uint32_t dword_5; + }; + struct { + FetchConstantType type : 2; // +0 dword_0 + // The signedness applies to the data components (before the swizzle, which + // is the destination selection). + // Signed repeating fraction formats always use the kZeroClampMinusOne mode, + // according to the IPR2015-00325 R400 Document Library Folder History: + // "Change 133990 on 2003/11/25 by jhoule@jhoule_doc_lt + // v1.80 - Indicated that NO_ZERO srf mode is unsupported for Xenos (will + // currently only work in the VC path)" + TextureSign sign_x : 2; // +2 + TextureSign sign_y : 2; // +4 + TextureSign sign_z : 2; // +6 + TextureSign sign_w : 2; // +8 + ClampMode clamp_x : 3; // +10 + ClampMode clamp_y : 3; // +13 + ClampMode clamp_z : 3; // +16 + uint32_t _pad_0_19 : 3; // +19 + // Base row pitch in pixels (not blocks) >> 5. For linear textures, this is + // provided by Direct3D 9 in a way that every row of blocks ends up aligned + // to kTextureLinearRowAlignmentBytes (the GPU requires 256-byte alignment + // of linear texture block rows for all textures). + // Mips are always stored with padding to the `max(next_pow2(base width or + // height) >> level, 1)` or a 32x32x4 tile (whichever is larger), so this + // pitch is irrelevant to them (but the 256-byte alignment requirement still + // applies to linear textures). + // Examples of pitch > aligned width: + // - 584109FF (loading screen and menu backgrounds, 1408 for a 1280x linear + // k_DXT4_5 texture, which corresponds to 22 * 256 bytes rather than + // 20 * 256 for just 1280x). + uint32_t pitch : 9; // +22 + uint32_t tiled : 1; // +31 + + TextureFormat format : 6; // +0 dword_1 + Endian endianness : 2; // +6 + uint32_t request_size : 2; // +8 + uint32_t stacked : 1; // +10 + uint32_t nearest_clamp_policy : 1; // +11 d3d/opengl + uint32_t base_address : 20; // +12 base address >> 12 + + // Size is stored with 1 subtracted from each component. + union { // dword_2 + struct { + uint32_t width : 24; + uint32_t _pad_size_1d : 8; + } size_1d; + struct { + uint32_t width : 13; + uint32_t height : 13; + // Should be 0 for k2D and 5 for kCube if not stacked, but not very + // meaningful in this case, likely should be ignored for non-stacked. + uint32_t stack_depth : 6; + } size_2d; + struct { + uint32_t width : 11; + uint32_t height : 11; + uint32_t depth : 10; + } size_3d; + }; + + uint32_t num_format : 1; // +0 dword_3 frac/int + // xyzw, 3b each (XE_GPU_TEXTURE_SWIZZLE) + uint32_t swizzle : 12; // +1 + int32_t exp_adjust : 6; // +13 + TextureFilter mag_filter : 2; // +19 + TextureFilter min_filter : 2; // +21 + TextureFilter mip_filter : 2; // +23 + AnisoFilter aniso_filter : 3; // +25 + ArbitraryFilter arbitrary_filter : 3; // +28 + uint32_t border_size : 1; // +31 + + uint32_t vol_mag_filter : 1; // +0 dword_4 + uint32_t vol_min_filter : 1; // +1 + uint32_t mip_min_level : 4; // +2 + uint32_t mip_max_level : 4; // +6 + uint32_t mag_aniso_walk : 1; // +10 + uint32_t min_aniso_walk : 1; // +11 + // 5 fractional bits (A2XX_SQ_TEX_4_LOD_BIAS). + int32_t lod_bias : 10; // +12 + // Also known as LodBiasH/V in sys2gmem. + int32_t grad_exp_adjust_h : 5; // +22 + int32_t grad_exp_adjust_v : 5; // +27 + + BorderColor border_color : 2; // +0 dword_5 + uint32_t force_bc_w_to_max : 1; // +2 + // Also known as TriJuice. + uint32_t tri_clamp : 2; // +3 + int32_t aniso_bias : 4; // +5 + DataDimension dimension : 2; // +9 + uint32_t packed_mips : 1; // +11 + uint32_t mip_address : 20; // +12 mip address >> 12 + }; +}; +static_assert_size(xe_gpu_texture_fetch_t, sizeof(uint32_t) * 6); + +// XE_GPU_REG_SHADER_CONSTANT_FETCH_* +union alignas(uint32_t) xe_gpu_fetch_group_t { + struct { + uint32_t dword_0; + uint32_t dword_1; + uint32_t dword_2; + uint32_t dword_3; + uint32_t dword_4; + uint32_t dword_5; + }; + xe_gpu_texture_fetch_t texture_fetch; + struct { + xe_gpu_vertex_fetch_t vertex_fetch_0; + xe_gpu_vertex_fetch_t vertex_fetch_1; + xe_gpu_vertex_fetch_t vertex_fetch_2; + }; + struct { + uint32_t type_0 : 2; + uint32_t data_0_a : 30; + uint32_t data_0_b : 32; + uint32_t type_1 : 2; + uint32_t data_1_a : 30; + uint32_t data_1_b : 32; + uint32_t type_2 : 2; + uint32_t data_2_a : 30; + uint32_t data_2_b : 32; + }; +}; +static_assert_size(xe_gpu_fetch_group_t, sizeof(uint32_t) * 6); + +// Shader memory export (memexport) allows for writing of arbitrary formatted +// data with random access / scatter capabilities. It provides functionality +// largely similar to resolving - format packing, supporting arbitrary color +// formats, from sub-dword ones such as k_8 in 58410B86, to 128-bit ones, with +// endian swap similar to how it's performed in resolves (up to 128-bit); +// specifying the number format, swapping red and blue channels - though with no +// exponent biasing. Unlike resolving, however, instead of writing to tiled +// textures, it exports the data to up to 5 elements (the eM# shader registers, +// each corresponding to `base address + element size * (offset + 0...4)`) in a +// stream defined by a stream constant and an offset in elements written to eA - +// a shader, however, can write to multiple streams with different or the same +// stream constants, by performing `alloc export` multiple times. It's used +// mostly in vertex shaders (most commonly in improvised "compute shaders" done +// by executing a vertex shader for a number of point-type primitives covering +// nothing), though usage in pixel shaders is also possible - an example is +// provided in the "Advanced Screenspace Antialiasing" presentation by Arne +// Schober. +// https://ubm-twvideo01.s3.amazonaws.com/o1/vault/gdceurope2010/slides/A_Schober_Advanced_Screenspace_Antialiasing.pdf +// +// Unlike fetch constants, which are passed via special registers, a memory +// export stream is configured by writing the stream constant and the offset to +// a shader export register (eA) allocated by the shader - similar to more +// conventional exports like oPos, o#, oC#. Therefore, in general, it's not +// possible to know what its value will be without running the shader. For +// emulation, this means that the memory range referenced by an export - that +// needs to be validated - requires running the shader on the CPU in general. +// Thankfully, however, the usual way of setting up eA is by executing: +// `mad eA, r#, const0100, c#` +// where c# is the stream float4 constant from the float constant registers, and +// const0100 is a literal (0.0f, 1.0f, 0.0f, 0.0f) constant, also from the float +// constant registers, used for placing the element index (r#) in the correct +// component of eA. This allows for easy gathering of memexport stream +// constants, which contain both the base address and the size of the +// destination buffer for bounds checking, from the shader code and the float +// constant registers, as long as the guest uses this instruction pattern to +// write to eA. +// +// The Xenos doesn't have an integer ALU, and denormals are treated as zero and +// are flushed. However, eA contains integers and bit fields. A stream constant +// is thus structured in a way that allows for packing integers in normalized +// floating-point numbers. +// +// X contains the base address of the stream in dwords as integer bits in the +// lower 30 bits, and bits 0b01 in the top. The 0b01 bits make the exponent +// nonzero, so the number is considered normalized, and therefore isn't flushed +// to zero. With only 512 MB of the physical memory on the Xbox 360, the +// exponent can't become 0b11111111, so X also won't be NaN for any valid Xbox +// 360 physical address (though in general the GPU supports 32-bit addresses, +// but this is originally an Xbox 360-specific feature, that was later, however, +// likely reused for GL_QCOM_writeonly_rendering). +// +// TODO(Triang3l): Verify whether GL_QCOM_writeonly_rendering is actually +// memexport on the Adreno 2xx using GL_OES_get_program_binary - it's also +// interesting to see how alphatest interacts with it, whether it's still true +// fixed-function alphatest, as it's claimed to be supported as usual by the +// extension specification. +// +// Y of eA contains the offset in elements - this is what shaders are supposed +// to calculate from something like the vertex index. Again, it's specified as +// an integer in the low bits, not as a truly floating-point number. For this +// purpose, stream constants contain the value 2^23 - when a whole +// floating-point number smaller than 2^23 is added as floating-point to 2^23, +// its integer representation becomes the mantissa bits of a number with an +// exponent of 23. Via multiply-add, `offset * 1.0f + exp2f(23)` is written here +// by the shader, allowing for element offsets of up to 2^23 - 1. +// +// Z is a bit field with the information about the formatting of the data. It's +// also packed as a normalized floating-point number, but in a cleaner way than +// X because not as many bits are required - just like Y, it has an exponent of +// 23 (possibly to let shaders build these values manually using floating-point +// multiply-add like integer shift-or, and finally to add 2^23, though that's +// not a case easy to handle in emulation, unlike prebuilt stream constants). +// +// W contains the number of elements in the stream. It's also packed with the +// full 23 exponent just like Y and Z, there's no way to index more than 2^23 +// elements using packing via addition to 2^23, so this field also doesn't need +// more bits than that. +// +// According to the sequencer specification from IPR2015-00325 (where memexport +// is called "pass thru export"): +// - Pass thru exports can occur anywhere in the shader program. +// - There can be any number of pass thru exports. +// - The address register is not kept across clause boundaries, so it must be +// refreshed after any Serialize (or yield), allocate instruction or resource +// change. +// - The write to eM# may be predicated if the export is not needed. +// - Exports are dropped if: +// - The index is above the maximum. +// - The index sign bit is 1. +// - The exponent of the index is not 23. +// The requirement that eM4 must be written if any eM# other than eM0 is also +// written doesn't apply to the final Xenos, it's likely an outdated note in the +// specification considering that it's very preliminary. +// +// According to Microsoft's shader validator: +// - eA can be written only by `mad`. +// - A single eM# can be written by any number of instruction, including with +// write masking. +// - eA must be written before eM#. +// - Any alloc instruction or a `serialize` terminates the current memory +// export. This doesn't apply to `exec Yield=true`, however, and it's not +// clear if that's an oversight or if that's not considered a yield that +// terminates the export. +// +// From the emulation perspective, this means that: +// - Alloc instructions (`alloc export` mandatorily, other allocs optionally), +// and optionally `serialize` instructions within `exec`, should be treated as +// the locations where the currently open export should be flushed to the +// memory. It should be taken into account that an export may be in looping +// control flow, and in this case it must be performed at every iteration. +// - Whether each eM# was written to must be tracked at shader execution time, +// as predication can disable the export of an element. +// +// TODO(Triang3l): Investigate how memory export interacts with pixel killing. +// Given that eM# writes disabled by predication don't cause an export, it's +// possible that killed invocations are treated as inactive (invalid in Xenos +// terms) overall, and thus new memory exports from them shouldn't be done, but +// that's not verified. However, given that on Direct3D 11+, OpenGL and Vulkan +// hosts, discarding disables subsequent storage resource writes, on the host, +// it would be natural to perform all outstanding memory exports before +// discarding if the kill condition passes. +// +// Memory exports can be performed to any ColorFormat, including 8bpp and 16bpp +// ones. Hosts, however, may have the memory bound as a 32bpp buffer (for +// instance, due to the minimum resource view size limitation on Direct3D 11). +// In this case, bytes and shorts aren't addressable directly. However, taking +// into account that memory accesses are coherent within one shader invocation +// on Direct3D 11+, OpenGL and Vulkan and thus are done in order relatively to +// each other, it should be possible to implement them by clearing the bits via +// an atomic AND, and writing the new value using an atomic OR. This will, of +// course, make the entire write operation non-atomic, and in case of a race +// between writes to the same location, the final result may not even be just a +// value from one of the invocations, but rather, it can be OR of the values +// from any invocations involved. However, on the Xenos, there doesn't seem to +// be any possibility of meaningfully accessing the same location from multiple +// invocations if any of them is writing, memory exports are out-of-order, so +// such an implementation shouldn't be causing issues in reality. Atomic +// compare-exchange, however, should not be used for this purpose, as it may +// result in an infinite loop if different invocations want to write different +// values to the same memory location. +// +// Examples of setup in titles (Z from MSB to LSB): +// +// 4D5307E6 particles (different VS invocation counts, like 1, 2, 4): +// There is a passthrough shader - useful for verification as it simply writes +// directly what it reads via vfetch of various formats. Another shader (with +// different c# numbers, but same formats) does complicated math to process the +// particles. +// c152: Z = 010010110000|0|111|00|100110|00000|010, count = 35840 +// 8in32, 32_32_32_32_FLOAT, float, RGBA - from 32_32_32_32_FLOAT vfetch +// c154, 162: Z = 010010110000|0|111|00|100000|00000|001, count = 71680 +// 8in16, 16_16_16_16_FLOAT, float, RGBA - from 16_16_16_16_FLOAT vfetch +// c156, 158, 160: Z = 010010110000|0|000|00|011010|00000|001, count = 71680 +// 8in16, 16_16_16_16, unorm, RGBA - from 16_16_16_16 unorm vfetch +// c164: Z = 010010110000|0|111|00|011111|00000|001, count = 143360 +// 8in16, 16_16_FLOAT, float, RGBA - from 16_16_FLOAT vfetch +// c166: Z = 010010110000|0|000|00|011001|00000|001, count = 143360 +// 8in16, 16_16, unorm, RGBA - from 16_16 unorm vfetch +// c168: Z = 010010110000|0|001|00|000111|00000|010, count = 143360 +// 8in32, 2_10_10_10, snorm, RGBA - from 2_10_10_10 snorm vfetch +// c170, c172: Z = 010010110000|1|000|00|000110|00000|010, count = 143360 +// 8in32, 8_8_8_8, unorm, BGRA - from 8_8_8_8 unorm vfetch with .zyxw swizzle +// +// 4D5307E6 water simulation (2048 VS invocations): +// c130: Z = 010010110000|0|111|00|100110|00000|010, count = 16384 +// 8in32, 32_32_32_32_FLOAT, float, RGBA +// The shader has 5 memexports of this kind and 6 32_32_32_32_FLOAT vfetches. +// +// 4D5307E6 water tessellation factors (1 VS invocation per triangle patch): +// c130: Z = 010010110000|0|111|11|100100|11111|010, count = patch count * 3 +// 8in32, 32_FLOAT, float, RGBA +// +// 41560817 texture memory copying (64 bytes per invocation, two eA, eight eM#): +// c0: Z = 010010110000|0|010|11|011010|00011|001 +// 8in16, 16_16_16_16, uint, RGBA - from 16_16_16_16 uint vfetch +// (16_16_16_16 is the largest color format without special values) +// +// 58410B86 hierarchical depth buffer occlusion culling with the result read on +// the CPU (15000 VS invocations in the main menu): +// c8: Z = 010010110000|0|010|00|000010|00000|000, count = invocation count +// No endian swap, 8, uint, RGBA +union alignas(uint32_t) xe_gpu_memexport_stream_t { + struct { + uint32_t dword_0; + uint32_t dword_1; + uint32_t dword_2; + uint32_t dword_3; + }; + struct { + uint32_t base_address : 30; // +0 dword_0 physical address >> 2 + uint32_t const_0x1 : 2; // +30 + + uint32_t const_0x4b000000; // +0 dword_1 + + Endian128 endianness : 3; // +0 dword_2 + uint32_t unused_0 : 5; // +3 + ColorFormat format : 6; // +8 + uint32_t unused_1 : 2; // +14 + SurfaceNumberFormat num_format : 3; // +16 + uint32_t red_blue_swap : 1; // +19 + uint32_t const_0x4b0 : 12; // +20 + + uint32_t index_count : 23; // +0 dword_3 + uint32_t const_0x96 : 9; // +23 + }; +}; +static_assert_size(xe_gpu_memexport_stream_t, sizeof(uint32_t) * 4); + +struct alignas(uint32_t) xe_gpu_depth_sample_counts { + // This is little endian as it is swapped in D3D code. + // Corresponding A and B values are summed up by D3D. + // Occlusion there is calculated by substracting begin from end struct. + le Total_A; + le Total_B; + le ZFail_A; + le ZFail_B; + le ZPass_A; + le ZPass_B; + le StencilFail_A; + le StencilFail_B; +}; +static_assert_size(xe_gpu_depth_sample_counts, sizeof(uint32_t) * 8); + +// Enum of event values used for VGT_EVENT_INITIATOR +enum Event { + VS_DEALLOC = 0, + PS_DEALLOC = 1, + VS_DONE_TS = 2, + PS_DONE_TS = 3, + CACHE_FLUSH_TS = 4, + CONTEXT_DONE = 5, + CACHE_FLUSH = 6, + VIZQUERY_START = 7, + VIZQUERY_END = 8, + SC_WAIT_WC = 9, + MPASS_PS_CP_REFETCH = 10, + MPASS_PS_RST_START = 11, + MPASS_PS_INCR_START = 12, + RST_PIX_CNT = 13, + RST_VTX_CNT = 14, + TILE_FLUSH = 15, + CACHE_FLUSH_AND_INV_TS_EVENT = 20, + ZPASS_DONE = 21, + CACHE_FLUSH_AND_INV_EVENT = 22, + PERFCOUNTER_START = 23, + PERFCOUNTER_STOP = 24, + SCREEN_EXT_INIT = 25, + SCREEN_EXT_RPT = 26, + VS_FETCH_DONE_TS = 27, +}; + +// Opcodes (IT_OPCODE) for Type-3 commands in the ringbuffer. +// https://github.com/freedreno/amd-gpu/blob/master/include/api/gsl_pm4types.h +// Not sure if all of these are used. +// clang-format off +enum Type3Opcode { + PM4_ME_INIT = 0x48, // initialize CP's micro-engine + + PM4_NOP = 0x10, // skip N 32-bit words to get to the next packet + + PM4_INDIRECT_BUFFER = 0x3f, // indirect buffer dispatch. prefetch parser uses this packet type to determine whether to pre-fetch the IB + PM4_INDIRECT_BUFFER_PFD = 0x37, // indirect buffer dispatch. same as IB, but init is pipelined + + PM4_WAIT_FOR_IDLE = 0x26, // wait for the IDLE state of the engine + PM4_WAIT_REG_MEM = 0x3c, // wait until a register or memory location is a specific value + PM4_WAIT_REG_EQ = 0x52, // wait until a register location is equal to a specific value + PM4_WAIT_REG_GTE = 0x53, // wait until a register location is >= a specific value + PM4_WAIT_UNTIL_READ = 0x5c, // wait until a read completes + PM4_WAIT_IB_PFD_COMPLETE = 0x5d, // wait until all base/size writes from an IB_PFD packet have completed + + PM4_REG_RMW = 0x21, // register read/modify/write + PM4_REG_TO_MEM = 0x3e, // reads register in chip and writes to memory + PM4_MEM_WRITE = 0x3d, // write N 32-bit words to memory + PM4_MEM_WRITE_CNTR = 0x4f, // write CP_PROG_COUNTER value to memory + PM4_COND_EXEC = 0x44, // conditional execution of a sequence of packets + PM4_COND_WRITE = 0x45, // conditional write to memory or register + + PM4_EVENT_WRITE = 0x46, // generate an event that creates a write to memory when completed + PM4_EVENT_WRITE_SHD = 0x58, // generate a VS|PS_done event + PM4_EVENT_WRITE_CFL = 0x59, // generate a cache flush done event + PM4_EVENT_WRITE_EXT = 0x5a, // generate a screen extent event + PM4_EVENT_WRITE_ZPD = 0x5b, // generate a z_pass done event + + PM4_DRAW_INDX = 0x22, // initiate fetch of index buffer and draw + PM4_DRAW_INDX_2 = 0x36, // draw using supplied indices in packet + PM4_DRAW_INDX_BIN = 0x34, // initiate fetch of index buffer and binIDs and draw + PM4_DRAW_INDX_2_BIN = 0x35, // initiate fetch of bin IDs and draw using supplied indices + + PM4_VIZ_QUERY = 0x23, // begin/end initiator for viz query extent processing + PM4_SET_STATE = 0x25, // fetch state sub-blocks and initiate shader code DMAs + PM4_SET_CONSTANT = 0x2d, // load constant into chip and to memory + PM4_SET_CONSTANT2 = 0x55, // INCR_UPDATE_STATE + PM4_SET_SHADER_CONSTANTS = 0x56, // INCR_UPDT_CONST + PM4_LOAD_ALU_CONSTANT = 0x2f, // load constants from memory + PM4_IM_LOAD = 0x27, // load sequencer instruction memory (pointer-based) + PM4_IM_LOAD_IMMEDIATE = 0x2b, // load sequencer instruction memory (code embedded in packet) + PM4_LOAD_CONSTANT_CONTEXT = 0x2e, // load constants from a location in memory + PM4_INVALIDATE_STATE = 0x3b, // selective invalidation of state pointers + + PM4_SET_SHADER_BASES = 0x4A, // dynamically changes shader instruction memory partition + PM4_SET_BIN_BASE_OFFSET = 0x4B, // program an offset that will added to the BIN_BASE value of the 3D_DRAW_INDX_BIN packet + PM4_SET_BIN_MASK = 0x50, // sets the 64-bit BIN_MASK register in the PFP + PM4_SET_BIN_SELECT = 0x51, // sets the 64-bit BIN_SELECT register in the PFP + + PM4_CONTEXT_UPDATE = 0x5e, // updates the current context, if needed + PM4_INTERRUPT = 0x54, // generate interrupt from the command stream + + PM4_XE_SWAP = 0x64, // Xenia only: VdSwap uses this to trigger a swap. + + PM4_IM_STORE = 0x2c, // copy sequencer instruction memory to system memory + + // Tiled rendering: + // https://www.google.com/patents/US20060055701 + PM4_SET_BIN_MASK_LO = 0x60, + PM4_SET_BIN_MASK_HI = 0x61, + PM4_SET_BIN_SELECT_LO = 0x62, + PM4_SET_BIN_SELECT_HI = 0x63, +}; +// clang-format on + +inline uint32_t MakePacketType0(uint16_t index, uint16_t count, bool one_reg = false) { + // ttcccccc cccccccc oiiiiiii iiiiiiii + assert(index <= 0x7FFF); + assert(count >= 1 && count <= 0x4000); + return (0u << 30) | (((count - 1) & 0x3FFF) << 16) | (index & 0x7FFF); +} + +inline uint32_t MakePacketType1(uint16_t index_1, uint16_t index_2) { + // tt?????? ??222222 22222111 11111111 + assert(index_1 <= 0x7FF); + assert(index_2 <= 0x7FF); + return (1u << 30) | ((index_2 & 0x7FF) << 11) | (index_1 & 0x7FF); +} + +constexpr inline uint32_t MakePacketType2() { + // tt?????? ???????? ???????? ???????? + return (2u << 30); +} + +inline uint32_t MakePacketType3(Type3Opcode opcode, uint16_t count, bool predicate = false) { + // ttcccccc cccccccc ?ooooooo ???????p + assert(opcode <= 0x7F); + assert(count >= 1 && count <= 0x4000); + return (3u << 30) | (((count - 1) & 0x3FFF) << 16) | ((opcode & 0x7F) << 8) | (predicate ? 1 : 0); +} + +} // namespace xenos +} // namespace rex::graphics diff --git a/include/rex/hash.h b/include/rex/hash.h new file mode 100644 index 0000000..e3a5373 --- /dev/null +++ b/include/rex/hash.h @@ -0,0 +1,45 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +// Enable inline implementations and advanced API (XXH3) +#ifndef XXH_INLINE_ALL +#define XXH_INLINE_ALL +#endif + +// Can't use XXH_X86DISPATCH because XXH is calculated on multiple threads, +// while the dispatch writes the result (multiple pointers without any +// synchronization) to XXH_g_dispatch at the first call. + +#include + +namespace rex { + +// For use in unordered_sets and unordered_maps (primarily multisets and +// multimaps, with manual collision resolution), where the hash is calculated +// externally (for instance, as XXH3), possibly requiring context data rather +// than a pure function to calculate the hash +template +struct IdentityHasher { + size_t operator()(const Key& key) const { return static_cast(key); } +}; + +template +struct XXHasher { + size_t operator()(const Key& key) const { + return static_cast(XXH3_64bits(&key, sizeof(key))); + } +}; + +} // namespace rex diff --git a/include/rex/hook.h b/include/rex/hook.h new file mode 100644 index 0000000..c8d98b9 --- /dev/null +++ b/include/rex/hook.h @@ -0,0 +1,239 @@ +/** + * @file hook.h + * @brief Hook authoring API: macros, typed imports, RAII helpers + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +//============================================================================= +// Hook Macros +//============================================================================= + +// Hook a recompiled function with an auto-marshaled native C++ function. +// The native function uses plain types (u32, mapped_u32, etc.) and +// HostToGuestFunction handles register translation automatically. +#ifdef REXGLUE_ENABLE_PROFILING +#include +#define REX_HOOK(subroutine, function) \ + extern "C" REX_FUNC(subroutine) { \ + ZoneNamedN(___tracy_hook_zone, #subroutine, true); \ + rex::ppc::HostToGuestFunction(ctx, base); \ + } +#else +#define REX_HOOK(subroutine, function) \ + extern "C" REX_FUNC(subroutine) { \ + rex::ppc::HostToGuestFunction(ctx, base); \ + } +#endif + +// Define a raw hook with direct ctx/base access. +#define REX_HOOK_RAW(name) extern "C" REX_FUNC(name) + +// Stub: logs a warning when called. +#define REX_STUB(subroutine) \ + extern "C" REX_FUNC(subroutine) { \ + (void)base; \ + REXKRNL_WARN("{} STUB", #subroutine); \ + } + +#define REX_STUB_LOG(subroutine, msg) \ + extern "C" REX_FUNC(subroutine) { \ + (void)base; \ + REXKRNL_WARN("{} STUB - {}", #subroutine, msg); \ + } + +#define REX_STUB_RETURN(subroutine, value) \ + extern "C" REX_FUNC(subroutine) { \ + (void)base; \ + REXKRNL_WARN("{} STUB - returning {:#x}", #subroutine, static_cast(value)); \ + ctx.r3.u64 = (value); \ + } + +// Export: hook + register in global registry for kernel ordinal lookup. +#define REX_EXPORT(name, function) \ + REX_HOOK(name, function) \ + static rex::ppc::detail::PPCFuncRegistrar _ppc_reg_##name(#name, &name); + +#define REX_EXPORT_STUB(name) \ + REX_STUB(name) \ + static rex::ppc::detail::PPCFuncRegistrar _ppc_reg_##name(#name, &name); + +#define REX_EXPORT_STUB_RETURN(name, retval) \ + REX_STUB_RETURN(name, retval) \ + static rex::ppc::detail::PPCFuncRegistrar _ppc_reg_##name(#name, &name); + +namespace rex { + +//============================================================================= +// CallFrame - Lightweight isolated calling context +//============================================================================= +// For side calls that must not disturb the outer hook's register state. +// Stack-allocated, NOT zero-initialized. Only copies the registers a callee +// actually needs from the parent context. + +struct CallFrame { + PPCContext ctx; + PPCContext& parent_; + + explicit CallFrame(PPCContext& parent) : parent_(parent) { + ctx.r1 = parent.r1; + ctx.r13 = parent.r13; + ctx.fpscr = parent.fpscr; + } + + ~CallFrame() { parent_.fpscr = ctx.fpscr; } + + operator PPCContext&() { return ctx; } + + CallFrame(const CallFrame&) = delete; + CallFrame& operator=(const CallFrame&) = delete; +}; + +} // namespace rex + +namespace rex::ppc { + +//============================================================================= +// ImportFunction - Zero-overhead typed callable for recompiled functions +//============================================================================= + +template +struct ImportFunction; + +template +struct ImportFunction { + PPCFunc& fn; + + R operator()(PPCContext& ctx, uint8_t* base, Args... args) const { + auto tpl = std::make_tuple(args...); + _translate_args_to_guest(ctx, base, tpl); + fn(ctx, base); + if constexpr (std::is_void_v) { + return; + } else if constexpr (is_precise_v) { + return static_cast(ctx.f1.f64); + } else { + return static_cast(ctx.r3.u64); + } + } + + R operator()(rex::CallFrame& frame, uint8_t* base, Args... args) const { + return (*this)(frame.ctx, base, args...); + } + + /// Auto-isolating call: retrieves ctx/base internally, creates isolated + /// context with 0x70 frame, calls function, returns result. + R operator()(Args... args) const { + auto* ts = rex::runtime::ThreadState::Get(); + PPCContext* parentCtx = ts->context(); + + auto* ks = rex::system::kernel_state(); + uint8_t* base = ks->memory()->virtual_membase(); + + PPCContext ctx{}; + ctx.r1 = parentCtx->r1; + ctx.r1.u32 -= 0x70; + ctx.r13 = parentCtx->r13; + ctx.fpscr = parentCtx->fpscr; + + auto tpl = std::make_tuple(args...); + _translate_args_to_guest(ctx, base, tpl); + fn(ctx, base); + + parentCtx->fpscr = ctx.fpscr; + + if constexpr (std::is_void_v) { + return; + } else if constexpr (is_precise_v) { + return static_cast(ctx.f1.f64); + } else { + return static_cast(ctx.r3.u64); + } + } +}; + +} // namespace rex::ppc + +namespace rex { + +//============================================================================= +// StackFrame - RAII guest stack allocation +//============================================================================= + +class [[deprecated("Use rex::ppc::stack_push / stack_guard instead")]] StackFrame { + PPCContext& ctx_; + u32 size_; + + public: + explicit StackFrame(PPCContext& ctx, u32 size) : ctx_(ctx), size_(size) { ctx_.r1.u32 -= size; } + + ~StackFrame() { ctx_.r1.u32 += size_; } + + u32 addr() const { return ctx_.r1.u32; } + u32 addr(u32 offset) const { return ctx_.r1.u32 + offset; } + + void write_string(u32 offset, const char* str, u8* base) const { + std::memcpy(rex::memory::GuestPtr(base, addr(offset)), str, std::strlen(str) + 1); + } + + void write(u32 offset, const void* data, size_t len, u8* base) const { + std::memcpy(rex::memory::GuestPtr(base, addr(offset)), data, len); + } + + template + size_t write_fmt(u32 offset, u8* base, fmt::format_string fmtstr, A&&... args) const { + char* dst = rex::memory::GuestPtr(base, addr(offset)); + auto result = fmt::format_to_n(dst, size_ - offset - 1, fmtstr, std::forward(args)...); + *result.out = '\0'; + return result.size; + } + + StackFrame(const StackFrame&) = delete; + StackFrame& operator=(const StackFrame&) = delete; +}; + +} // namespace rex + +//============================================================================= +// REX_IMPORT - Typed callable import of a recompiled function +//============================================================================= +// Three explicit arguments, no hidden prefix transformations: +// symbol: the exact linker symbol to reference +// callable: the name of the typed callable variable +// sig: the function signature (e.g. u32(u32, u32)) + +#define REX_IMPORT(symbol, callable, sig) \ + REX_EXTERN(symbol); \ + inline rex::ppc::ImportFunction callable { \ + symbol \ + } + +//============================================================================= +// Legacy Compat Aliases +//============================================================================= + +#define XBOXKRNL_EXPORT(n, f) REX_EXPORT(n, f) +#define XBOXKRNL_EXPORT_STUB(n) REX_EXPORT_STUB(n) +#define XAM_EXPORT(n, f) REX_EXPORT(n, f) +#define XAM_EXPORT_STUB(n) REX_EXPORT_STUB(n) +#define REXCRT_EXPORT(n, f) REX_HOOK(n, f) +#define REXCRT_EXPORT_STUB(n) REX_STUB(n) diff --git a/include/rex/image_info.h b/include/rex/image_info.h new file mode 100644 index 0000000..80b7672 --- /dev/null +++ b/include/rex/image_info.h @@ -0,0 +1,40 @@ +/** + * @file image_info.h + * @brief Image layout descriptor for recompiled binaries + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include + +struct PPCFuncMapping; + +namespace rex::system { +class KernelState; +} + +namespace rex { + +/** + * Callback for registering recompiled modules with KernelState (multi-binary projects). + */ +using RegisterModulesFunc = void (*)(system::KernelState*); + +/// PPC image layout passed from the generated config header into ReXApp. +struct PPCImageInfo { + u32 code_base; + u32 code_size; + u32 image_base; + u32 image_size; + const PPCFuncMapping* func_mappings; + bool rexcrt_heap = false; ///< Set by codegen when [rexcrt] has heap functions + RegisterModulesFunc register_modules = nullptr; ///< Set by codegen for multi-binary projects +}; + +} // namespace rex diff --git a/include/rex/input/flags.h b/include/rex/input/flags.h new file mode 100644 index 0000000..f29d8ac --- /dev/null +++ b/include/rex/input/flags.h @@ -0,0 +1,18 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +// Input/HID configuration flags +REXCVAR_DECLARE(bool, guide_button); +REXCVAR_DECLARE(std::string, hid_mappings_file); +REXCVAR_DECLARE(std::string, input_backend); diff --git a/include/rex/input/input.h b/include/rex/input/input.h new file mode 100644 index 0000000..450eb34 --- /dev/null +++ b/include/rex/input/input.h @@ -0,0 +1,103 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +namespace rex::input { + +enum X_INPUT_CAPS { + X_INPUT_CAPS_FFB_SUPPORTED = 0x0001, + X_INPUT_CAPS_WIRELESS = 0x0002, + X_INPUT_CAPS_VOICE_SUPPORTED = 0x0004, + X_INPUT_CAPS_PMD_SUPPORTED = 0x0008, + X_INPUT_CAPS_NO_NAVIGATION = 0x0010, +}; + +enum X_INPUT_DEVTYPE { + XINPUT_DEVTYPE_GAMEPAD = 0x00000001, + XINPUT_DEVTYPE_KEYBOARD = 0x00000002, +}; + +enum X_INPUT_FLAG { + X_INPUT_FLAG_GAMEPAD = 0x00000001, +}; + +enum X_INPUT_GAMEPAD_BUTTON { + X_INPUT_GAMEPAD_DPAD_UP = 0x0001, + X_INPUT_GAMEPAD_DPAD_DOWN = 0x0002, + X_INPUT_GAMEPAD_DPAD_LEFT = 0x0004, + X_INPUT_GAMEPAD_DPAD_RIGHT = 0x0008, + X_INPUT_GAMEPAD_START = 0x0010, + X_INPUT_GAMEPAD_BACK = 0x0020, + X_INPUT_GAMEPAD_LEFT_THUMB = 0x0040, + X_INPUT_GAMEPAD_RIGHT_THUMB = 0x0080, + X_INPUT_GAMEPAD_LEFT_SHOULDER = 0x0100, + X_INPUT_GAMEPAD_RIGHT_SHOULDER = 0x0200, + X_INPUT_GAMEPAD_GUIDE = 0x0400, + X_INPUT_GAMEPAD_A = 0x1000, + X_INPUT_GAMEPAD_B = 0x2000, + X_INPUT_GAMEPAD_X = 0x4000, + X_INPUT_GAMEPAD_Y = 0x8000, +}; + +// For VK_PAD, use ui::VirtualKey. + +enum X_INPUT_KEYSTROKE_FLAGS { + X_INPUT_KEYSTROKE_KEYDOWN = 0x0001, + X_INPUT_KEYSTROKE_KEYUP = 0x0002, + X_INPUT_KEYSTROKE_REPEAT = 0x0004, +}; + +struct X_INPUT_GAMEPAD { + be buttons; + uint8_t left_trigger; + uint8_t right_trigger; + be thumb_lx; + be thumb_ly; + be thumb_rx; + be thumb_ry; +}; +static_assert_size(X_INPUT_GAMEPAD, 12); + +struct X_INPUT_STATE { + be packet_number; + X_INPUT_GAMEPAD gamepad; +}; +static_assert_size(X_INPUT_STATE, sizeof(X_INPUT_GAMEPAD) + 4); + +struct X_INPUT_VIBRATION { + be left_motor_speed; + be right_motor_speed; +}; +static_assert_size(X_INPUT_VIBRATION, 4); + +struct X_INPUT_CAPABILITIES { + uint8_t type; + uint8_t sub_type; + be flags; + X_INPUT_GAMEPAD gamepad; + X_INPUT_VIBRATION vibration; +}; +static_assert_size(X_INPUT_CAPABILITIES, sizeof(X_INPUT_GAMEPAD) + sizeof(X_INPUT_VIBRATION) + 4); + +// https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinput_keystroke(v=vs.85).aspx +struct X_INPUT_KEYSTROKE { + be virtual_key; + be unicode; + be flags; + uint8_t user_index; + uint8_t hid_code; +}; +static_assert_size(X_INPUT_KEYSTROKE, 8); + +} // namespace rex::input diff --git a/include/rex/input/input_driver.h b/include/rex/input/input_driver.h new file mode 100644 index 0000000..b579ef4 --- /dev/null +++ b/include/rex/input/input_driver.h @@ -0,0 +1,62 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include + +namespace rex::ui { +class Window; +} + +namespace rex::input { + +class InputSystem; + +class InputDriver { + public: + virtual ~InputDriver() = default; + + virtual X_STATUS Setup() = 0; + + virtual X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags, + X_INPUT_CAPABILITIES* out_caps) = 0; + virtual X_RESULT GetState(uint32_t user_index, X_INPUT_STATE* out_state) = 0; + virtual X_RESULT SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration) = 0; + virtual X_RESULT GetKeystroke(uint32_t user_index, uint32_t flags, + X_INPUT_KEYSTROKE* out_keystroke) = 0; + + virtual void OnWindowAvailable(rex::ui::Window* /*window*/) {} + + void set_is_active_callback(std::function is_active_callback) { + is_active_callback_ = is_active_callback; + } + + protected: + explicit InputDriver(rex::ui::Window* window, size_t window_z_order) + : window_(window), window_z_order_(window_z_order) {} + + rex::ui::Window* window() const { return window_; } + size_t window_z_order() const { return window_z_order_; } + + bool is_active() const { return !is_active_callback_ || is_active_callback_(); } + + private: + rex::ui::Window* window_; + size_t window_z_order_; + std::function is_active_callback_ = nullptr; +}; + +} // namespace rex::input diff --git a/include/rex/input/input_system.h b/include/rex/input/input_system.h new file mode 100644 index 0000000..8f34d97 --- /dev/null +++ b/include/rex/input/input_system.h @@ -0,0 +1,55 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include + +namespace rex::ui { +class Window; +} + +namespace rex::input { + +class InputSystem : public system::IInputSystem { + public: + explicit InputSystem(rex::ui::Window* window); + ~InputSystem() override; + + rex::ui::Window* window() const { return window_; } + + X_STATUS Setup() override; + void Shutdown() override; + + void AddDriver(std::unique_ptr driver); + void AttachWindow(rex::ui::Window* window); + void SetActiveCallback(std::function callback); + + X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES* out_caps); + X_RESULT GetState(uint32_t user_index, X_INPUT_STATE* out_state); + X_RESULT SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration); + X_RESULT GetKeystroke(uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE* out_keystroke); + + private: + rex::ui::Window* window_ = nullptr; + + std::vector> drivers_; +}; + +/// Create a default InputSystem with SDL + NOP drivers. +/// In tool mode, only the NOP driver is added. +std::unique_ptr CreateDefaultInputSystem(bool tool_mode); + +} // namespace rex::input diff --git a/include/rex/input/mnk/mnk_input_driver.h b/include/rex/input/mnk/mnk_input_driver.h new file mode 100644 index 0000000..2483b99 --- /dev/null +++ b/include/rex/input/mnk/mnk_input_driver.h @@ -0,0 +1,81 @@ +/** + * @file rex/input/mnk/mnk_input_driver.h + * @brief Keyboard/mouse input driver - maps MnK to Xbox 360 controller. + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ +#pragma once + +#include +#include + +#include +#include +#include +#include + +namespace rex::input::mnk { + +class MnkInputDriver final : public InputDriver, + public rex::ui::WindowInputListener, + public rex::ui::WindowListener { + public: + explicit MnkInputDriver(rex::ui::Window* window, size_t window_z_order); + ~MnkInputDriver() override; + + X_STATUS Setup() override; + + X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags, + X_INPUT_CAPABILITIES* out_caps) override; + X_RESULT GetState(uint32_t user_index, X_INPUT_STATE* out_state) override; + X_RESULT SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration) override; + X_RESULT GetKeystroke(uint32_t user_index, uint32_t flags, + X_INPUT_KEYSTROKE* out_keystroke) override; + + void OnWindowAvailable(rex::ui::Window* window) override; + + // WindowInputListener + void OnKeyDown(rex::ui::KeyEvent& e) override; + void OnKeyUp(rex::ui::KeyEvent& e) override; + void OnMouseDown(rex::ui::MouseEvent& e) override; + void OnMouseUp(rex::ui::MouseEvent& e) override; + void OnMouseMove(rex::ui::MouseEvent& e) override; + + // WindowListener + void OnClosing(rex::ui::UIEvent& e) override; + void OnLostFocus(rex::ui::UISetupEvent& e) override; + void OnGotFocus(rex::ui::UISetupEvent& e) override; + + private: + uint32_t UserIndex() const; + bool IsEnabled() const; + void CenterCursor(); + void UpdateMouseCapture(); + void SetKeyState(uint16_t vk, bool down); + void EnqueueKeystroke(uint16_t vk_pad, bool down); + + rex::ui::Window* attached_window_ = nullptr; + + std::mutex state_mutex_; + bool key_down_[256] = {}; + + // Mouse delta tracking + int32_t mouse_dx_ = 0; + int32_t mouse_dy_ = 0; + int32_t prev_mouse_x_ = 0; + int32_t prev_mouse_y_ = 0; + bool mouse_captured_ = false; + bool has_focus_ = true; + + // Keystroke queue + std::queue keystroke_queue_; + + // Packet number incremented on state change + uint32_t packet_number_ = 0; +}; + +} // namespace rex::input::mnk diff --git a/include/rex/input/nop/nop_input_driver.h b/include/rex/input/nop/nop_input_driver.h new file mode 100644 index 0000000..c3e46cf --- /dev/null +++ b/include/rex/input/nop/nop_input_driver.h @@ -0,0 +1,32 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +namespace rex::input::nop { + +class NopInputDriver final : public InputDriver { + public: + explicit NopInputDriver(rex::ui::Window* window, size_t window_z_order); + ~NopInputDriver() override; + + X_STATUS Setup() override; + + X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags, + X_INPUT_CAPABILITIES* out_caps) override; + X_RESULT GetState(uint32_t user_index, X_INPUT_STATE* out_state) override; + X_RESULT SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration) override; + X_RESULT GetKeystroke(uint32_t user_index, uint32_t flags, + X_INPUT_KEYSTROKE* out_keystroke) override; +}; + +} // namespace rex::input::nop diff --git a/include/rex/input/sdl/sdl_input_driver.h b/include/rex/input/sdl/sdl_input_driver.h new file mode 100644 index 0000000..92bec81 --- /dev/null +++ b/include/rex/input/sdl/sdl_input_driver.h @@ -0,0 +1,102 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include + +#include + +#define HID_SDL_USER_COUNT 4 +#define HID_SDL_THUMB_THRES 0x4E00 +#define HID_SDL_TRIGG_THRES 0x1F +#define HID_SDL_REPEAT_DELAY 400 +#define HID_SDL_REPEAT_RATE 100 + +namespace rex::input::sdl { + +class SDLInputDriver final : public InputDriver, public rex::ui::WindowListener { + public: + explicit SDLInputDriver(rex::ui::Window* window, size_t window_z_order); + ~SDLInputDriver() override; + + X_STATUS Setup() override; + + X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags, + X_INPUT_CAPABILITIES* out_caps) override; + X_RESULT GetState(uint32_t user_index, X_INPUT_STATE* out_state) override; + X_RESULT SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration) override; + X_RESULT GetKeystroke(uint32_t user_index, uint32_t flags, + X_INPUT_KEYSTROKE* out_keystroke) override; + void OnWindowAvailable(rex::ui::Window* window) override; + + private: + struct ControllerState { + SDL_Gamepad* sdl; + X_INPUT_CAPABILITIES caps; + X_INPUT_STATE state; + bool state_changed; + bool is_active; + }; + + enum class RepeatState { + Idle, // no buttons pressed or repeating has ended + Waiting, // a button is held and the delay is awaited + Repeating, // actively repeating at a rate + }; + struct KeystrokeState { + uint64_t buttons; + RepeatState repeat_state; + // the button number that was pressed last: + uint8_t repeat_butt_idx; + // the last time (ms) a down (and/or repeat) event for that button was send: + uint32_t repeat_time; + }; + + // WindowListener + void OnClosing(rex::ui::UIEvent& e) override; + void OnLostFocus(rex::ui::UISetupEvent& e) override; + void OnGotFocus(rex::ui::UISetupEvent& e) override; + + void HandleEvent(const SDL_Event& event); + std::unique_lock DrainAndLock(); + void ProcessEventLocked(const SDL_Event& event); + void OnControllerDeviceAddedLocked(const SDL_Event& event); + void OnControllerDeviceRemovedLocked(const SDL_Event& event); + void OnControllerDeviceAxisMotionLocked(const SDL_Event& event); + void OnControllerDeviceButtonChangedLocked(const SDL_Event& event); + + inline uint64_t AnalogToKeyfield(const X_INPUT_GAMEPAD& gamepad) const; + std::optional GetControllerIndexFromInstanceID(SDL_JoystickID instance_id); + ControllerState* GetControllerState(uint32_t user_index); + bool TestSDLVersion() const; + void UpdateXCapabilities(ControllerState& state); + void QueueControllerUpdate(); + + rex::ui::Window* attached_window_ = nullptr; + bool sdl_events_initialized_; + bool SDL_Gamepad_initialized_; + std::atomic sdl_events_unflushed_; + std::atomic sdl_pumpevents_queued_; + std::array controllers_; + std::mutex controllers_mutex_; + std::mutex event_queue_mutex_; + std::vector pending_events_; + std::array keystroke_states_; +}; + +} // namespace rex::input::sdl diff --git a/include/rex/input/xinput/xinput_input_driver.h b/include/rex/input/xinput/xinput_input_driver.h new file mode 100644 index 0000000..053b5f6 --- /dev/null +++ b/include/rex/input/xinput/xinput_input_driver.h @@ -0,0 +1,47 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Sanjay Govind, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include + +#include + +namespace rex::input::xinput { + +class XinputInputDriver final : public InputDriver { + public: + explicit XinputInputDriver(rex::ui::Window* window, size_t window_z_order); + ~XinputInputDriver() override; + + X_STATUS Setup() override; + + X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags, + X_INPUT_CAPABILITIES* out_caps) override; + X_RESULT GetState(uint32_t user_index, X_INPUT_STATE* out_state) override; + X_RESULT SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration) override; + X_RESULT GetKeystroke(uint32_t user_index, uint32_t flags, + X_INPUT_KEYSTROKE* out_keystroke) override; + + private: + void* module_; + void* XInputGetCapabilities_; + void* XInputGetState_; + void* XInputGetStateEx_; + void* XInputGetKeystroke_; + void* XInputSetState_; + void* XInputEnable_; +}; + +} // namespace rex::input::xinput diff --git a/include/rex/kernel.h b/include/rex/kernel.h new file mode 100644 index 0000000..4c252e3 --- /dev/null +++ b/include/rex/kernel.h @@ -0,0 +1,33 @@ +/** + * @file kernel.h + * @brief Umbrella header for Xbox kernel types and objects + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +// Core system types (X_STATUS, X_RESULT, X_HRESULT, X_HANDLE) +#include + +// I/O types (file attributes, overlapped) +#include + +// Kernel objects +#include +#include +#include +#include +#include +#include +#include + +// Memory (Xbox API wrappers - core Memory class is in rex/memory.h) +#include + +// System state +#include diff --git a/include/rex/kernel/crt/heap.h b/include/rex/kernel/crt/heap.h new file mode 100644 index 0000000..70b49b0 --- /dev/null +++ b/include/rex/kernel/crt/heap.h @@ -0,0 +1,77 @@ +/** + * @file kernel/crt/heap.h + * @brief ReXHeap -- O(1) native heap for guest memory using o1heap. + * Provides rexcrt hooks for RtlAllocateHeap, RtlFreeHeap, etc. + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ +#pragma once + +#include +#include +#include + +#include + +REXCVAR_DECLARE(bool, rexcrt_heap_enable); +REXCVAR_DECLARE(uint32_t, rexcrt_heap_size_mb); + +struct O1HeapInstance; + +namespace rex::memory { +class Memory; +} + +namespace rex::kernel::crt { + +/// Mirrors O1HeapDiagnostics without requiring o1heap.h in consumer headers. +struct HeapDiagnostics { + uint64_t capacity; + uint64_t allocated; + uint64_t peak_allocated; + uint64_t peak_request_size; + uint64_t oom_count; +}; + +class ReXHeap { + public: + bool Init(uint32_t heap_size_bytes, rex::memory::Memory* memory); + + uint32_t Alloc(uint32_t size, bool zero = false); + void Free(uint32_t guest_addr); + uint32_t Size(uint32_t guest_addr); + uint32_t Realloc(uint32_t guest_addr, uint32_t new_size, bool zero_new = false); + + bool InHeap(uint32_t guest_addr) const; + HeapDiagnostics GetDiagnostics() const; + + private: + struct HeapSegment { + O1HeapInstance* heap = nullptr; + uint32_t guest_base = 0; + uint32_t guest_end = 0; + }; + + mutable std::mutex mutex_; + std::vector segments_; + uint8_t* membase_ = nullptr; + uint32_t initial_segment_size_ = 0; + rex::memory::Memory* memory_ = nullptr; + + void* GuestToHost(uint32_t guest_addr) const; + uint32_t HostToGuest(void* host_ptr) const; + bool AllocateSegmentLocked(uint32_t segment_size_bytes); + uint32_t AllocLocked(uint32_t size, bool zero = false); + HeapSegment* FindSegmentByGuestLocked(uint32_t guest_addr); + const HeapSegment* FindSegmentByGuestLocked(uint32_t guest_addr) const; + HeapDiagnostics GetDiagnosticsLocked() const; +}; + +/// Initialize the global rexcrt heap. Called by Runtime::Setup() when enabled. +bool InitHeap(uint32_t heap_size_mb, rex::memory::Memory* memory); + +/// Access the global heap instance (valid after InitHeap). +ReXHeap& GetHeap(); + +} // namespace rex::kernel::crt diff --git a/include/rex/kernel/init.h b/include/rex/kernel/init.h new file mode 100644 index 0000000..005f916 --- /dev/null +++ b/include/rex/kernel/init.h @@ -0,0 +1,23 @@ +/** + * @file kernel/init.h + * @brief Kernel initialization entry point + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +namespace rex { +class Runtime; +namespace system { +class KernelState; +} +} // namespace rex + +namespace rex::kernel { +void InitializeKernel(Runtime* runtime, system::KernelState* kernel_state); +} diff --git a/include/rex/kernel/xam/apps/app.h b/include/rex/kernel/xam/apps/app.h new file mode 100644 index 0000000..f401213 --- /dev/null +++ b/include/rex/kernel/xam/apps/app.h @@ -0,0 +1,32 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +namespace rex { +namespace kernel { +namespace xam { +namespace apps { + +class XamApp : public system::xam::App { + public: + explicit XamApp(system::KernelState* kernel_state); + + X_HRESULT DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, + uint32_t buffer_length) override; +}; + +} // namespace apps +} // namespace xam +} // namespace kernel +} // namespace rex diff --git a/include/rex/kernel/xam/apps/xgi_app.h b/include/rex/kernel/xam/apps/xgi_app.h new file mode 100644 index 0000000..3a5ff93 --- /dev/null +++ b/include/rex/kernel/xam/apps/xgi_app.h @@ -0,0 +1,32 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +namespace rex { +namespace kernel { +namespace xam { +namespace apps { + +class XgiApp : public system::xam::App { + public: + explicit XgiApp(system::KernelState* kernel_state); + + X_HRESULT DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, + uint32_t buffer_length) override; +}; + +} // namespace apps +} // namespace xam +} // namespace kernel +} // namespace rex diff --git a/include/rex/kernel/xam/apps/xlivebase_app.h b/include/rex/kernel/xam/apps/xlivebase_app.h new file mode 100644 index 0000000..4cd55a8 --- /dev/null +++ b/include/rex/kernel/xam/apps/xlivebase_app.h @@ -0,0 +1,32 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +namespace rex { +namespace kernel { +namespace xam { +namespace apps { + +class XLiveBaseApp : public system::xam::App { + public: + explicit XLiveBaseApp(system::KernelState* kernel_state); + + X_HRESULT DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, + uint32_t buffer_length) override; +}; + +} // namespace apps +} // namespace xam +} // namespace kernel +} // namespace rex diff --git a/include/rex/kernel/xam/apps/xmp_app.h b/include/rex/kernel/xam/apps/xmp_app.h new file mode 100644 index 0000000..d939d62 --- /dev/null +++ b/include/rex/kernel/xam/apps/xmp_app.h @@ -0,0 +1,117 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include +#include +#include + +namespace rex { +namespace kernel { +namespace xam { +namespace apps { + +// Only source of docs for a lot of these functions: +// https://github.com/oukiar/freestyledash/blob/master/Freestyle/Scenes/Media/Music/ScnMusic.cpp + +class XmpApp : public system::xam::App { + public: + enum class State : uint32_t { + kIdle = 0, + kPlaying = 1, + kPaused = 2, + }; + enum class PlaybackClient : uint32_t { + kSystem = 0, + kTitle = 1, + }; + enum class PlaybackMode : uint32_t { + // kInOrder = ?, + kUnknown = 0, + }; + enum class RepeatMode : uint32_t { + // kNoRepeat = ?, + kUnknown = 0, + }; + struct Song { + enum class Format : uint32_t { + kWma = 0, + kMp3 = 1, + }; + + uint32_t handle; + std::u16string file_path; + std::u16string name; + std::u16string artist; + std::u16string album; + std::u16string album_artist; + std::u16string genre; + uint32_t track_number; + uint32_t duration_ms; + Format format; + }; + struct Playlist { + uint32_t handle; + std::u16string name; + uint32_t flags; + std::vector> songs; + }; + + explicit XmpApp(system::KernelState* kernel_state); + + X_HRESULT XMPGetStatus(uint32_t status_ptr); + + X_HRESULT XMPCreateTitlePlaylist(uint32_t songs_ptr, uint32_t song_count, + uint32_t playlist_name_ptr, const std::u16string& playlist_name, + uint32_t flags, uint32_t out_song_handles, + uint32_t out_playlist_handle); + X_HRESULT XMPDeleteTitlePlaylist(uint32_t playlist_handle); + X_HRESULT XMPPlayTitlePlaylist(uint32_t playlist_handle, uint32_t song_handle); + X_HRESULT XMPContinue(); + X_HRESULT XMPStop(uint32_t unk); + X_HRESULT XMPPause(); + X_HRESULT XMPNext(); + X_HRESULT XMPPrevious(); + + X_HRESULT DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, + uint32_t buffer_length) override; + + private: + static const uint32_t kMsgStateChanged = 0x0A000001; + static const uint32_t kMsgPlaybackBehaviorChanged = 0x0A000002; + static const uint32_t kMsgPlaybackControllerChanged = 0x0A000003; + + void OnStateChanged(); + + State state_; + PlaybackClient playback_client_; + PlaybackMode playback_mode_; + RepeatMode repeat_mode_; + uint32_t unknown_flags_; + float volume_; + Playlist* active_playlist_; + int active_song_index_; + + rex::thread::global_critical_region global_critical_region_; + std::unordered_map playlists_; + uint32_t next_playlist_handle_; + uint32_t next_song_handle_; +}; + +} // namespace apps +} // namespace xam +} // namespace kernel +} // namespace rex diff --git a/include/rex/kernel/xam/module.h b/include/rex/kernel/xam/module.h new file mode 100644 index 0000000..b2818f2 --- /dev/null +++ b/include/rex/kernel/xam/module.h @@ -0,0 +1,49 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include + +namespace rex { +namespace kernel { +namespace xam { + +bool xeXamIsUIActive(); + +class XamModule : public system::KernelModule { + public: + XamModule(Runtime* emulator, system::KernelState* kernel_state); + virtual ~XamModule(); + + static void RegisterExportTable(rex::runtime::ExportResolver* export_resolver); + + struct LoaderData { + bool launch_data_present = false; + std::vector launch_data; + uint32_t launch_flags = 0; + std::string launch_path; // Full path to next xex + }; + + const LoaderData& loader_data() const { return loader_data_; } + LoaderData& loader_data() { return loader_data_; } + + private: + LoaderData loader_data_; +}; + +} // namespace xam +} // namespace kernel +} // namespace rex diff --git a/include/rex/kernel/xam/module_export_groups.inc b/include/rex/kernel/xam/module_export_groups.inc new file mode 100644 index 0000000..563b789 --- /dev/null +++ b/include/rex/kernel/xam/module_export_groups.inc @@ -0,0 +1,30 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +// This is a partial file designed to be included by other files when +// constructing various tables. + +XE_MODULE_EXPORT_GROUP(xam, Avatar) +XE_MODULE_EXPORT_GROUP(xam, Content) +XE_MODULE_EXPORT_GROUP(xam, ContentAggregate) +XE_MODULE_EXPORT_GROUP(xam, ContentDevice) +XE_MODULE_EXPORT_GROUP(xam, Enum) +XE_MODULE_EXPORT_GROUP(xam, Info) +XE_MODULE_EXPORT_GROUP(xam, Input) +XE_MODULE_EXPORT_GROUP(xam, Locale) +XE_MODULE_EXPORT_GROUP(xam, Msg) +XE_MODULE_EXPORT_GROUP(xam, Net) +XE_MODULE_EXPORT_GROUP(xam, Notify) +XE_MODULE_EXPORT_GROUP(xam, NUI) +XE_MODULE_EXPORT_GROUP(xam, Party) +XE_MODULE_EXPORT_GROUP(xam, Task) +XE_MODULE_EXPORT_GROUP(xam, UI) +XE_MODULE_EXPORT_GROUP(xam, User) +XE_MODULE_EXPORT_GROUP(xam, Video) +XE_MODULE_EXPORT_GROUP(xam, Voice) diff --git a/include/rex/kernel/xam/private.h b/include/rex/kernel/xam/private.h new file mode 100644 index 0000000..3df4776 --- /dev/null +++ b/include/rex/kernel/xam/private.h @@ -0,0 +1,33 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2019 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +namespace rex { +namespace kernel { +namespace xam { + +bool xeXamIsUIActive(); + +rex::runtime::Export* RegisterExport_xam(rex::runtime::Export* export_entry); + +// Registration functions, one per file. +#define XE_MODULE_EXPORT_GROUP(m, n) \ + void Register##n##Exports(rex::runtime::ExportResolver* export_resolver, \ + system::KernelState* kernel_state); +#include "module_export_groups.inc" +#undef XE_MODULE_EXPORT_GROUP + +} // namespace xam +} // namespace kernel +} // namespace rex diff --git a/include/rex/kernel/xbdm/module.h b/include/rex/kernel/xbdm/module.h new file mode 100644 index 0000000..1353d9b --- /dev/null +++ b/include/rex/kernel/xbdm/module.h @@ -0,0 +1,34 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Joseph Lee, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include + +namespace rex { +namespace kernel { +namespace xbdm { + +class XbdmModule : public system::KernelModule { + public: + XbdmModule(Runtime* emulator, system::KernelState* kernel_state); + virtual ~XbdmModule(); + + static void RegisterExportTable(rex::runtime::ExportResolver* export_resolver); +}; + +} // namespace xbdm +} // namespace kernel +} // namespace rex diff --git a/include/rex/kernel/xbdm/module_export_groups.inc b/include/rex/kernel/xbdm/module_export_groups.inc new file mode 100644 index 0000000..f47842d --- /dev/null +++ b/include/rex/kernel/xbdm/module_export_groups.inc @@ -0,0 +1,13 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +// This is a partial file designed to be included by other files when +// constructing various tables. + +XE_MODULE_EXPORT_GROUP(xbdm, Misc) diff --git a/include/rex/kernel/xbdm/private.h b/include/rex/kernel/xbdm/private.h new file mode 100644 index 0000000..133e1b5 --- /dev/null +++ b/include/rex/kernel/xbdm/private.h @@ -0,0 +1,31 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2019 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Joseph Lee, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +namespace rex { +namespace kernel { +namespace xbdm { + +rex::runtime::Export* RegisterExport_xbdm(rex::runtime::Export* export_entry); + +// Registration functions, one per file. +#define XE_MODULE_EXPORT_GROUP(m, n) \ + void Register##n##Exports(rex::runtime::ExportResolver* export_resolver, \ + system::KernelState* kernel_state); +#include "module_export_groups.inc" +#undef XE_MODULE_EXPORT_GROUP + +} // namespace xbdm +} // namespace kernel +} // namespace rex diff --git a/include/rex/kernel/xboxkrnl/cert_monitor.h b/include/rex/kernel/xboxkrnl/cert_monitor.h new file mode 100644 index 0000000..c489e6c --- /dev/null +++ b/include/rex/kernel/xboxkrnl/cert_monitor.h @@ -0,0 +1,29 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { + +struct X_KECERTMONITORDATA { + rex::be callback_fn; +}; + +void KeCertMonitorCallback(::PPCContext* ppc_context, rex::system::KernelState* kernel_state); + +} // namespace rex::kernel::xboxkrnl diff --git a/include/rex/kernel/xboxkrnl/debug_monitor.h b/include/rex/kernel/xboxkrnl/debug_monitor.h new file mode 100644 index 0000000..10df4aa --- /dev/null +++ b/include/rex/kernel/xboxkrnl/debug_monitor.h @@ -0,0 +1,37 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { + +struct X_KEDEBUGMONITORDATA { + rex::be unk_00; // 0x00 + rex::be unk_04; // 0x04 + rex::be unk_08; // 0x08 + rex::be unk_0C; // 0x0C + rex::be unk_10; // 0x10 + rex::be unk_14; // 0x14 + rex::be callback_fn; // 0x18 function + rex::be unk_1C; // 0x1C + rex::be unk_20; // 0x20 Vd graphics data? +}; + +void KeDebugMonitorCallback(::PPCContext* ppc_context, rex::system::KernelState* kernel_state); + +} // namespace rex::kernel::xboxkrnl diff --git a/include/rex/kernel/xboxkrnl/error.h b/include/rex/kernel/xboxkrnl/error.h new file mode 100644 index 0000000..5aafce0 --- /dev/null +++ b/include/rex/kernel/xboxkrnl/error.h @@ -0,0 +1,20 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +namespace rex::kernel::xboxkrnl { + +uint32_t xeRtlNtStatusToDosError(uint32_t source_status); + +} // namespace rex::kernel::xboxkrnl diff --git a/include/rex/kernel/xboxkrnl/module.h b/include/rex/kernel/xboxkrnl/module.h new file mode 100644 index 0000000..e4cbbbc --- /dev/null +++ b/include/rex/kernel/xboxkrnl/module.h @@ -0,0 +1,45 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include +#include +#include +#include +#include + +// All of the exported functions: +#include + +namespace rex::kernel::xboxkrnl { + +class XboxkrnlModule : public system::KernelModule { + public: + XboxkrnlModule(Runtime* emulator, system::KernelState* kernel_state); + virtual ~XboxkrnlModule(); + + static void RegisterExportTable(rex::runtime::ExportResolver* export_resolver); + + bool SendPIXCommand(const char* cmd); + + void set_pix_function(uint32_t addr) { pix_function_ = addr; } + + protected: + uint32_t pix_function_ = 0; + + private: + std::unique_ptr timestamp_timer_; +}; + +} // namespace rex::kernel::xboxkrnl diff --git a/include/rex/kernel/xboxkrnl/module_export_groups.inc b/include/rex/kernel/xboxkrnl/module_export_groups.inc new file mode 100644 index 0000000..2506c90 --- /dev/null +++ b/include/rex/kernel/xboxkrnl/module_export_groups.inc @@ -0,0 +1,31 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +// This is a partial file designed to be included by other files when +// constructing various tables. + +XE_MODULE_EXPORT_GROUP(xboxkrnl, Audio) +XE_MODULE_EXPORT_GROUP(xboxkrnl, AudioXma) +XE_MODULE_EXPORT_GROUP(xboxkrnl, Crypt) +XE_MODULE_EXPORT_GROUP(xboxkrnl, Debug) +XE_MODULE_EXPORT_GROUP(xboxkrnl, Error) +XE_MODULE_EXPORT_GROUP(xboxkrnl, Hal) +XE_MODULE_EXPORT_GROUP(xboxkrnl, Hid) +XE_MODULE_EXPORT_GROUP(xboxkrnl, Io) +XE_MODULE_EXPORT_GROUP(xboxkrnl, IoInfo) +XE_MODULE_EXPORT_GROUP(xboxkrnl, Memory) +XE_MODULE_EXPORT_GROUP(xboxkrnl, Misc) +XE_MODULE_EXPORT_GROUP(xboxkrnl, Module) +XE_MODULE_EXPORT_GROUP(xboxkrnl, Ob) +XE_MODULE_EXPORT_GROUP(xboxkrnl, Rtl) +XE_MODULE_EXPORT_GROUP(xboxkrnl, String) +XE_MODULE_EXPORT_GROUP(xboxkrnl, Threading) +XE_MODULE_EXPORT_GROUP(xboxkrnl, Usbcam) +XE_MODULE_EXPORT_GROUP(xboxkrnl, Video) +XE_MODULE_EXPORT_GROUP(xboxkrnl, XConfig) diff --git a/include/rex/kernel/xboxkrnl/private.h b/include/rex/kernel/xboxkrnl/private.h new file mode 100644 index 0000000..df540e0 --- /dev/null +++ b/include/rex/kernel/xboxkrnl/private.h @@ -0,0 +1,14 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +namespace rex::kernel::xboxkrnl {} // namespace rex::kernel::xboxkrnl diff --git a/include/rex/kernel/xboxkrnl/rtl.h b/include/rex/kernel/xboxkrnl/rtl.h new file mode 100644 index 0000000..540f698 --- /dev/null +++ b/include/rex/kernel/xboxkrnl/rtl.h @@ -0,0 +1,24 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +namespace rex::kernel::xboxkrnl { + +struct X_RTL_CRITICAL_SECTION; + +void xeRtlInitializeCriticalSection(X_RTL_CRITICAL_SECTION* cs, uint32_t cs_ptr); +X_STATUS xeRtlInitializeCriticalSectionAndSpinCount(X_RTL_CRITICAL_SECTION* cs, uint32_t cs_ptr, + uint32_t spin_count); + +} // namespace rex::kernel::xboxkrnl diff --git a/include/rex/kernel/xboxkrnl/threading.h b/include/rex/kernel/xboxkrnl/threading.h new file mode 100644 index 0000000..204c446 --- /dev/null +++ b/include/rex/kernel/xboxkrnl/threading.h @@ -0,0 +1,45 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { + +uint32_t xeNtSetEvent(uint32_t handle, rex::be* previous_state_ptr); +uint32_t xeNtClearEvent(uint32_t handle); + +uint32_t xeNtWaitForMultipleObjectsEx(uint32_t count, rex::be* handles, + uint32_t wait_type, uint32_t wait_mode, uint32_t alertable, + uint64_t* timeout_ptr); + +uint32_t xeKeWaitForSingleObject(void* object_ptr, uint32_t wait_reason, uint32_t processor_mode, + uint32_t alertable, uint64_t* timeout_ptr); +uint32_t xeKeSetEvent(rex::system::X_KEVENT* event_ptr, uint32_t increment, uint32_t wait); + +// Guest-memory spinlock helpers (PPCContext* for r13/PCR access) +uint32_t xeKeKfAcquireSpinLock(PPCContext* ctx, rex::X_KSPINLOCK* lock, bool change_irql = true); +void xeKeKfReleaseSpinLock(PPCContext* ctx, rex::X_KSPINLOCK* lock, uint32_t old_irql, + bool change_irql = true); + +// Guest-memory APC helpers +void xeKeInitializeApc(rex::system::XAPC* apc, uint32_t thread_ptr, uint32_t kernel_routine, + uint32_t rundown_routine, uint32_t normal_routine, uint32_t apc_mode, + uint32_t normal_context); +uint32_t xeKeInsertQueueApc(rex::system::XAPC* apc, uint32_t arg1, uint32_t arg2, + uint32_t priority_increment, PPCContext* ctx); + +} // namespace rex::kernel::xboxkrnl diff --git a/include/rex/kernel/xboxkrnl/video.h b/include/rex/kernel/xboxkrnl/video.h new file mode 100644 index 0000000..0b9bd41 --- /dev/null +++ b/include/rex/kernel/xboxkrnl/video.h @@ -0,0 +1,34 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +namespace rex::runtime { +class ExportResolver; +} + +namespace rex::system { +class KernelState; +} + +namespace rex::kernel::xboxkrnl { + +void VdQueryVideoMode(system::X_VIDEO_MODE* video_mode); + +// Register video variable exports (VdGlobalDevice, VdHSIOCalibrationLock, etc.) +// Must be called during kernel initialization before XEX modules are loaded. +void RegisterVideoExports(rex::runtime::ExportResolver* export_resolver, + system::KernelState* kernel_state); + +} // namespace rex::kernel::xboxkrnl diff --git a/include/rex/literals.h b/include/rex/literals.h new file mode 100644 index 0000000..264a35b --- /dev/null +++ b/include/rex/literals.h @@ -0,0 +1,38 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +namespace rex::literals { + +constexpr size_t operator""_KiB(unsigned long long int x) { + return 1024ULL * x; +} + +constexpr size_t operator""_MiB(unsigned long long int x) { + return 1024_KiB * x; +} + +constexpr size_t operator""_GiB(unsigned long long int x) { + return 1024_MiB * x; +} + +constexpr size_t operator""_TiB(unsigned long long int x) { + return 1024_GiB * x; +} + +constexpr size_t operator""_PiB(unsigned long long int x) { + return 1024_TiB * x; +} + +} // namespace rex::literals diff --git a/include/rex/logging.h b/include/rex/logging.h new file mode 100644 index 0000000..d1b9835 --- /dev/null +++ b/include/rex/logging.h @@ -0,0 +1,27 @@ +/** + * @file logging.h + * @brief Logging subsystem umbrella header + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +// Category types, constants, configuration, deprecated enum compat +#include + +// Function declarations, CVAR declarations +#include + +// Logging macros (parameterized, per-subsystem aliases, category definition) +#include + +// Fatal error and assertion macros +#include + +// Formatting helpers (ptr, hex, boolean) +#include diff --git a/include/rex/logging/api.h b/include/rex/logging/api.h new file mode 100644 index 0000000..5f84121 --- /dev/null +++ b/include/rex/logging/api.h @@ -0,0 +1,246 @@ +/** + * @file rex/logging/api.h + * @brief Logging system function declarations and CVAR declarations + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include + +#include +#include + +#include + +// Logging CVAR declarations (defined in logging.cpp) +REXCVAR_DECLARE(std::string, log_level); +REXCVAR_DECLARE(std::string, log_file); +REXCVAR_DECLARE(bool, log_verbose); +REXCVAR_DECLARE(bool, log_noisy); +REXCVAR_DECLARE(int32_t, log_flush_interval); +REXCVAR_DECLARE(int32_t, log_max_file_size_mb); +REXCVAR_DECLARE(int32_t, log_max_files); + +namespace rex { + +/* ========================================================================= + Log Level Guidelines + ========================================================================= + TRACE - Per-instruction, per-iteration detail (massive output) + DEBUG - Development info, function entry/exit, intermediate state + INFO - Normal operational events, progress updates + WARN - Recoverable issues, fallback behaviors, unsupported features + ERROR - Serious problems affecting functionality + CRITICAL - Fatal errors, memory corruption, unrecoverable state + ========================================================================= */ + +/** + * Initialize the logging system with full configuration. + * + * Creates shared sinks and loggers for all built-in categories. + * Safe to call multiple times; subsequent calls update levels only. + * + * @param config Logging configuration. + */ +void InitLogging(const LogConfig& config); + +/** + * Initialize logging with simple parameters (convenience overload). + * + * @param log_file Path to log file, or nullptr for no file logging. + * @param level Default log level for all categories. + */ +void InitLogging(const char* log_file = nullptr, + spdlog::level::level_enum level = spdlog::level::info); + +/** + * Early-phase logging initialization (before config is loaded). + * Creates a platform debug sink (OutputDebugString on Windows, stdout elsewhere) + * so log lines emitted before InitLogging() is called are captured. + */ +void InitLoggingEarly(); + +/** + * Flush all loggers and shut down the logging system. + */ +void ShutdownLogging(); + +/** + * Register a new log category at runtime. + * + * The returned handle can be used with REXLOG_CAT_* macros and all + * category-accepting API functions. The category's logger is created + * with the current default sinks and any matching entries from the + * stored LogConfig::category_levels and LogConfig::category_sinks. + * + * Thread-safe but intended to be called during startup. + * + * @param name Human-readable category name (e.g. "app.network"). + * @return Handle for the new category. + */ +LogCategoryId RegisterLogCategory(const char* name); + +LogCategoryId RegisterLogSubcategory(const char* name, LogCategoryId parent); +void SetRootLevel(LogCategoryId root, spdlog::level::level_enum level); + +/** + * Look up a category by name. + * + * @param name Category name to search for (case-sensitive). + * @return Category handle, or std::nullopt if not found. + */ +std::optional FindCategory(const std::string& name); + +/** + * Get a read-only view of all registered categories. + * + * @return Span over the registry entries in registration order. + */ +std::span GetAllCategories(); + +/** + * Get the raw logger pointer for a category (zero overhead). + * + * This is the fast path used by logging macros. Returns nullptr if + * the category is not yet initialized. + * + * @param category Category handle. + * @return Raw pointer to the spdlog logger (not owning). + */ +spdlog::logger* GetLoggerRaw(LogCategoryId category); + +/** + * Get the shared logger pointer for a category. + * + * Prefer GetLoggerRaw() in hot paths. This overload is useful when + * you need to hold the logger or manipulate its sinks. + * + * @param category Category handle. + * @return Shared pointer to the spdlog logger. + */ +std::shared_ptr GetLogger(LogCategoryId category); + +/** + * Get the default (Core) logger. + * + * @return Shared pointer to the Core category logger. + */ +std::shared_ptr GetLogger(); + +/** + * Set the log level for a specific category at runtime. + * + * @param category Category handle. + * @param level New log level. + */ +void SetCategoryLevel(LogCategoryId category, spdlog::level::level_enum level); + +/** + * Set the log level for all registered categories. + * + * @param level New log level. + */ +void SetAllLevels(spdlog::level::level_enum level); + +/** + * Register a CVAR change callback for the "log_level" CVAR. + * Call this after InitLogging() to enable runtime level changes. + */ +void RegisterLogLevelCallback(); + +/** + * Add a sink to all current and future loggers. + * + * @param sink Shared pointer to the spdlog sink. + */ +void AddSink(spdlog::sink_ptr sink); + +/** + * Add a sink to a specific category's logger only. + * + * @param category Category handle. + * @param sink Shared pointer to the spdlog sink. + */ +void AddSink(LogCategoryId category, spdlog::sink_ptr sink); + +/** + * Remove a sink from all loggers. + * + * @param sink The sink to remove (matched by pointer identity). + */ +void RemoveSink(spdlog::sink_ptr sink); + +/** + * Remove a sink from a specific category's logger. + * + * @param category Category handle. + * @param sink The sink to remove (matched by pointer identity). + */ +void RemoveSink(LogCategoryId category, spdlog::sink_ptr sink); + +/** + * Replace the global console sink on every registered logger with `sink`. + * Pass nullptr to remove the console sink without replacement. + * + * @param sink New console sink, or nullptr to remove. + */ +void ReplaceConsoleSink(spdlog::sink_ptr sink); + +/** + * Update the format pattern on the stdout console sink. + * + * @param pattern spdlog pattern string. + */ +void SetConsolePattern(const std::string& pattern); + +/** + * Update the format pattern on the file sink. + * + * @param pattern spdlog pattern string. + */ +void SetFilePattern(const std::string& pattern); + +/** + * Parse a log level string to spdlog level enum. + * + * Accepts: "trace", "debug", "info", "warn"/"warning", "error"/"err", + * "critical", "off". Case-insensitive. + * + * @param level_str Level name string. + * @return Parsed level, or std::nullopt if invalid. + */ +std::optional ParseLogLevel(const std::string& level_str); + +/** + * Parse log level from string, returning a default on failure. + * + * @param level_str Level name string. + * @param default_level Fallback level if parsing fails. + * @return Parsed level or default_level. + */ +spdlog::level::level_enum ParseLogLevelOr(const std::string& level_str, + spdlog::level::level_enum default_level); + +/** + * Build a LogConfig from CLI arguments and environment variables. + * + * Precedence: CLI args > environment (REX_LOG_LEVEL) > build-type default. + * + * @param log_file Path to log file, or nullptr. + * @param cli_level Global level from CLI (empty string = not set). + * @param category_levels Per-category level overrides from CLI. + * @return Populated LogConfig. + */ +LogConfig BuildLogConfig(const char* log_file, const std::string& cli_level, + const std::map& category_levels); + +std::map ParseCategoryLevelsFromConfig( + const std::filesystem::path& config_path); + +} // namespace rex diff --git a/include/rex/logging/assert.h b/include/rex/logging/assert.h new file mode 100644 index 0000000..8035960 --- /dev/null +++ b/include/rex/logging/assert.h @@ -0,0 +1,91 @@ +/** + * @file rex/logging/assert.h + * @brief Fatal error and assertion macros + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include + +#include +#include + +/* ========================================================================= + Fatal Error Macros + ========================================================================= */ + +/** Log a critical error to Core and abort. */ +#define REX_FATAL(fmt, ...) \ + do { \ + REXLOG_CRITICAL("[FATAL] " fmt __VA_OPT__(, ) __VA_ARGS__); \ + if (auto _l = ::rex::GetLogger()) \ + _l->flush(); \ + std::abort(); \ + } while (0) + +/** Log a critical error to a specific category and abort. */ +#define REX_FATAL_CAT(cat, fmt, ...) \ + do { \ + REXLOG_CAT_CRITICAL(cat, "[FATAL] " fmt __VA_OPT__(, ) __VA_ARGS__); \ + if (auto* _l = ::rex::GetLoggerRaw(cat)) \ + _l->flush(); \ + std::abort(); \ + } while (0) + +/** Log a critical error with function name and abort. */ +#define REX_FATAL_FN(fmt, ...) \ + do { \ + REXLOG_CRITICAL("[FATAL] {}: " fmt, __FUNCTION__ __VA_OPT__(, ) __VA_ARGS__); \ + if (auto _l = ::rex::GetLogger()) \ + _l->flush(); \ + std::abort(); \ + } while (0) + +/** Check condition and abort with fatal error if false. */ +#define REX_FATAL_IF(cond, fmt, ...) \ + do { \ + if (!(cond)) { \ + REXLOG_CRITICAL("[FATAL] {}: check failed: " #cond " - " fmt, \ + __FUNCTION__ __VA_OPT__(, ) __VA_ARGS__); \ + if (auto _l = ::rex::GetLogger()) \ + _l->flush(); \ + std::abort(); \ + } \ + } while (0) + +/* ========================================================================= + Assertion Macros + ========================================================================= */ + +/** Log error and assert (debug-only crash). */ +#define REX_ASSERT(cond, msg) \ + do { \ + if (!(cond)) { \ + REXLOG_ERROR("Assertion failed: {} - {}", #cond, msg); \ + assert(cond); \ + } \ + } while (0) + +/** Log error and return a value if condition fails. */ +#define REX_ASSERT_RET(cond, msg, retval) \ + do { \ + if (!(cond)) { \ + REXLOG_ERROR("Assertion failed: {} - {}", #cond, msg); \ + return retval; \ + } \ + } while (0) + +/** Log error and return void if condition fails. */ +#define REX_ASSERT_RET_VOID(cond, msg) \ + do { \ + if (!(cond)) { \ + REXLOG_ERROR("Assertion failed: {} - {}", #cond, msg); \ + return; \ + } \ + } while (0) diff --git a/include/rex/logging/format.h b/include/rex/logging/format.h new file mode 100644 index 0000000..e9ba047 --- /dev/null +++ b/include/rex/logging/format.h @@ -0,0 +1,60 @@ +/** + * @file rex/logging/format.h + * @brief Formatting helpers for log messages - ptr(), hex(), boolean() + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include + +#include + +namespace rex::log { + +/** Format a 32-bit address as hex (e.g. "0x0040F000"). */ +inline std::string ptr(uint32_t addr) { + return fmt::format("0x{:08X}", addr); +} + +/** Format a 64-bit address as hex, auto-selecting width. */ +inline std::string ptr(uint64_t addr) { + if (addr > 0xFFFFFFFFULL) { + return fmt::format("0x{:016X}", addr); + } + return fmt::format("0x{:08X}", static_cast(addr)); +} + +/** Format a void pointer. */ +inline std::string ptr(const void* p) { + return fmt::format("{}", p); +} + +/** Format a typed pointer. */ +template +inline std::string ptr(T* p) { + return fmt::format("{}", static_cast(p)); +} + +/** Format a 32-bit value as hex (e.g. "0x1A"). */ +inline std::string hex(uint32_t val) { + return fmt::format("0x{:X}", val); +} + +/** Format a 64-bit value as hex. */ +inline std::string hex(uint64_t val) { + return fmt::format("0x{:X}", val); +} + +/** Format a boolean as "true" or "false". */ +inline const char* boolean(bool b) { + return b ? "true" : "false"; +} + +} // namespace rex::log diff --git a/include/rex/logging/macros.h b/include/rex/logging/macros.h new file mode 100644 index 0000000..504fdcb --- /dev/null +++ b/include/rex/logging/macros.h @@ -0,0 +1,171 @@ +/** + * @file rex/logging/macros.h + * @brief Logging macros - parameterized, per-subsystem aliases, category definition + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include + +/* Implementation macro - do not call directly. Uses raw pointer for zero + ref-count overhead and gates on should_log() to skip format evaluation. */ +#define REX_LOG_IMPL(cat, lvl, ...) \ + do { \ + auto* rex_log_ptr_ = ::rex::GetLoggerRaw(cat); \ + if (rex_log_ptr_ && rex_log_ptr_->should_log(lvl)) \ + rex_log_ptr_->log(spdlog::source_loc{__FILE__, __LINE__, __FUNCTION__}, lvl, __VA_ARGS__); \ + } while (0) + +#define REX_LOG_NOISY_IMPL(cat, lvl, ...) \ + do { \ + if (!REXCVAR_GET(log_noisy)) \ + break; \ + REX_LOG_IMPL(cat, lvl, __VA_ARGS__); \ + } while (0) + +/* --- Parameterized Macros (Primary API) --------------------------------- */ + +/** @{ */ +#define REXLOG_CAT_TRACE(cat, ...) REX_LOG_IMPL(cat, spdlog::level::trace, __VA_ARGS__) +#define REXLOG_CAT_DEBUG(cat, ...) REX_LOG_IMPL(cat, spdlog::level::debug, __VA_ARGS__) +#define REXLOG_CAT_INFO(cat, ...) REX_LOG_IMPL(cat, spdlog::level::info, __VA_ARGS__) +#define REXLOG_CAT_WARN(cat, ...) REX_LOG_IMPL(cat, spdlog::level::warn, __VA_ARGS__) +#define REXLOG_CAT_ERROR(cat, ...) REX_LOG_IMPL(cat, spdlog::level::err, __VA_ARGS__) +#define REXLOG_CAT_CRITICAL(cat, ...) REX_LOG_IMPL(cat, spdlog::level::critical, __VA_ARGS__) +/** @} */ + +/* --- Noisy Parameterized Macros (cvar-gated) ------------------------------ */ + +#define REXLOG_CAT_NOISY_TRACE(cat, ...) REX_LOG_NOISY_IMPL(cat, spdlog::level::trace, __VA_ARGS__) +#define REXLOG_CAT_NOISY_DEBUG(cat, ...) REX_LOG_NOISY_IMPL(cat, spdlog::level::debug, __VA_ARGS__) + +/* --- Per-Subsystem Alias Macros - Core Category -------------------------- */ + +/** @{ */ +#define REXLOG_TRACE(...) REXLOG_CAT_TRACE(::rex::log::core(), __VA_ARGS__) +#define REXLOG_DEBUG(...) REXLOG_CAT_DEBUG(::rex::log::core(), __VA_ARGS__) +#define REXLOG_INFO(...) REXLOG_CAT_INFO(::rex::log::core(), __VA_ARGS__) +#define REXLOG_WARN(...) REXLOG_CAT_WARN(::rex::log::core(), __VA_ARGS__) +#define REXLOG_ERROR(...) REXLOG_CAT_ERROR(::rex::log::core(), __VA_ARGS__) +#define REXLOG_CRITICAL(...) REXLOG_CAT_CRITICAL(::rex::log::core(), __VA_ARGS__) +/** @} */ + +/* --- Per-Subsystem Alias Macros ------------------------------------------ */ + +/** @{ CPU */ +#define REXCPU_TRACE(...) REXLOG_CAT_TRACE(::rex::log::cpu(), __VA_ARGS__) +#define REXCPU_DEBUG(...) REXLOG_CAT_DEBUG(::rex::log::cpu(), __VA_ARGS__) +#define REXCPU_INFO(...) REXLOG_CAT_INFO(::rex::log::cpu(), __VA_ARGS__) +#define REXCPU_WARN(...) REXLOG_CAT_WARN(::rex::log::cpu(), __VA_ARGS__) +#define REXCPU_ERROR(...) REXLOG_CAT_ERROR(::rex::log::cpu(), __VA_ARGS__) +#define REXCPU_CRITICAL(...) REXLOG_CAT_CRITICAL(::rex::log::cpu(), __VA_ARGS__) +/** @} */ + +/** @{ APU */ +#define REXAPU_TRACE(...) REXLOG_CAT_TRACE(::rex::log::apu(), __VA_ARGS__) +#define REXAPU_DEBUG(...) REXLOG_CAT_DEBUG(::rex::log::apu(), __VA_ARGS__) +#define REXAPU_INFO(...) REXLOG_CAT_INFO(::rex::log::apu(), __VA_ARGS__) +#define REXAPU_WARN(...) REXLOG_CAT_WARN(::rex::log::apu(), __VA_ARGS__) +#define REXAPU_ERROR(...) REXLOG_CAT_ERROR(::rex::log::apu(), __VA_ARGS__) +#define REXAPU_CRITICAL(...) REXLOG_CAT_CRITICAL(::rex::log::apu(), __VA_ARGS__) +/** @} */ + +/** @{ GPU */ +#define REXGPU_TRACE(...) REXLOG_CAT_TRACE(::rex::log::gpu(), __VA_ARGS__) +#define REXGPU_DEBUG(...) REXLOG_CAT_DEBUG(::rex::log::gpu(), __VA_ARGS__) +#define REXGPU_INFO(...) REXLOG_CAT_INFO(::rex::log::gpu(), __VA_ARGS__) +#define REXGPU_WARN(...) REXLOG_CAT_WARN(::rex::log::gpu(), __VA_ARGS__) +#define REXGPU_ERROR(...) REXLOG_CAT_ERROR(::rex::log::gpu(), __VA_ARGS__) +#define REXGPU_CRITICAL(...) REXLOG_CAT_CRITICAL(::rex::log::gpu(), __VA_ARGS__) +/** @} */ + +/** @{ Kernel */ +#define REXKRNL_TRACE(...) REXLOG_CAT_TRACE(::rex::log::krnl(), __VA_ARGS__) +#define REXKRNL_DEBUG(...) REXLOG_CAT_DEBUG(::rex::log::krnl(), __VA_ARGS__) +#define REXKRNL_INFO(...) REXLOG_CAT_INFO(::rex::log::krnl(), __VA_ARGS__) +#define REXKRNL_WARN(...) REXLOG_CAT_WARN(::rex::log::krnl(), __VA_ARGS__) +#define REXKRNL_ERROR(...) REXLOG_CAT_ERROR(::rex::log::krnl(), __VA_ARGS__) +#define REXKRNL_CRITICAL(...) REXLOG_CAT_CRITICAL(::rex::log::krnl(), __VA_ARGS__) +/** @} */ + +/** @{ System */ +#define REXSYS_TRACE(...) REXLOG_CAT_TRACE(::rex::log::sys(), __VA_ARGS__) +#define REXSYS_DEBUG(...) REXLOG_CAT_DEBUG(::rex::log::sys(), __VA_ARGS__) +#define REXSYS_INFO(...) REXLOG_CAT_INFO(::rex::log::sys(), __VA_ARGS__) +#define REXSYS_WARN(...) REXLOG_CAT_WARN(::rex::log::sys(), __VA_ARGS__) +#define REXSYS_ERROR(...) REXLOG_CAT_ERROR(::rex::log::sys(), __VA_ARGS__) +#define REXSYS_CRITICAL(...) REXLOG_CAT_CRITICAL(::rex::log::sys(), __VA_ARGS__) +/** @} */ + +/** @{ Filesystem */ +#define REXFS_TRACE(...) REXLOG_CAT_TRACE(::rex::log::fs(), __VA_ARGS__) +#define REXFS_DEBUG(...) REXLOG_CAT_DEBUG(::rex::log::fs(), __VA_ARGS__) +#define REXFS_INFO(...) REXLOG_CAT_INFO(::rex::log::fs(), __VA_ARGS__) +#define REXFS_WARN(...) REXLOG_CAT_WARN(::rex::log::fs(), __VA_ARGS__) +#define REXFS_ERROR(...) REXLOG_CAT_ERROR(::rex::log::fs(), __VA_ARGS__) +#define REXFS_CRITICAL(...) REXLOG_CAT_CRITICAL(::rex::log::fs(), __VA_ARGS__) +/** @} */ + +/* --- Noisy Aliases - Per-Subsystem ---------------------------------------- */ + +#define REXLOG_NOISY_TRACE(...) REXLOG_CAT_NOISY_TRACE(::rex::log::core(), __VA_ARGS__) +#define REXLOG_NOISY_DEBUG(...) REXLOG_CAT_NOISY_DEBUG(::rex::log::core(), __VA_ARGS__) +#define REXCPU_NOISY_TRACE(...) REXLOG_CAT_NOISY_TRACE(::rex::log::cpu(), __VA_ARGS__) +#define REXCPU_NOISY_DEBUG(...) REXLOG_CAT_NOISY_DEBUG(::rex::log::cpu(), __VA_ARGS__) +#define REXAPU_NOISY_TRACE(...) REXLOG_CAT_NOISY_TRACE(::rex::log::apu(), __VA_ARGS__) +#define REXAPU_NOISY_DEBUG(...) REXLOG_CAT_NOISY_DEBUG(::rex::log::apu(), __VA_ARGS__) +#define REXGPU_NOISY_TRACE(...) REXLOG_CAT_NOISY_TRACE(::rex::log::gpu(), __VA_ARGS__) +#define REXGPU_NOISY_DEBUG(...) REXLOG_CAT_NOISY_DEBUG(::rex::log::gpu(), __VA_ARGS__) +#define REXKRNL_NOISY_TRACE(...) REXLOG_CAT_NOISY_TRACE(::rex::log::krnl(), __VA_ARGS__) +#define REXKRNL_NOISY_DEBUG(...) REXLOG_CAT_NOISY_DEBUG(::rex::log::krnl(), __VA_ARGS__) +#define REXSYS_NOISY_TRACE(...) REXLOG_CAT_NOISY_TRACE(::rex::log::sys(), __VA_ARGS__) +#define REXSYS_NOISY_DEBUG(...) REXLOG_CAT_NOISY_DEBUG(::rex::log::sys(), __VA_ARGS__) +#define REXFS_NOISY_TRACE(...) REXLOG_CAT_NOISY_TRACE(::rex::log::fs(), __VA_ARGS__) +#define REXFS_NOISY_DEBUG(...) REXLOG_CAT_NOISY_DEBUG(::rex::log::fs(), __VA_ARGS__) + +/* --- Custom Category Definition ----------------------------------------- */ + +/** + * Define a custom log category with Meyers singleton, guaranteed to + * initialize on first use regardless of static init order. + * + * Usage (in a header): + * REXLOG_DEFINE_CATEGORY(codegen) + * #define REXCODEGEN_TRACE(...) REXLOG_CAT_TRACE(::rex::log::codegen(), __VA_ARGS__) + * // ... etc for DEBUG, INFO, WARN, ERROR, CRITICAL + * + * Expands to an inline function rex::log::codegen() returning LogCategoryId. + */ +#define REXLOG_DEFINE_CATEGORY(name) \ + namespace rex::log { \ + inline ::rex::LogCategoryId name() { \ + static const ::rex::LogCategoryId id = ::rex::RegisterLogCategory(#name); \ + return id; \ + } \ + } + +// For dynamic parents (defined via REXLOG_DEFINE_CATEGORY) +#define REXLOG_DEFINE_SUBCATEGORY(child, parent) \ + namespace rex::log { \ + inline ::rex::LogCategoryId parent##_##child() { \ + static const ::rex::LogCategoryId id = \ + ::rex::RegisterLogSubcategory(#child, ::rex::log::parent()); \ + return id; \ + } \ + } + +/* --- Built-in SDK Categories ---------------------------------------------- */ + +REXLOG_DEFINE_CATEGORY(core) +REXLOG_DEFINE_CATEGORY(cpu) +REXLOG_DEFINE_CATEGORY(apu) +REXLOG_DEFINE_CATEGORY(gpu) +REXLOG_DEFINE_CATEGORY(krnl) +REXLOG_DEFINE_CATEGORY(sys) +REXLOG_DEFINE_CATEGORY(fs) diff --git a/include/rex/logging/sink.h b/include/rex/logging/sink.h new file mode 100644 index 0000000..44edb40 --- /dev/null +++ b/include/rex/logging/sink.h @@ -0,0 +1,97 @@ +/** + * @file rex/logging/sink.h + * @brief Thread-safe ring-buffer spdlog sink for in-memory log capture + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ +#pragma once + +#include + +#include + +#include +#include +#include +#include +#include + +namespace rex { + +struct LogEntry { + spdlog::level::level_enum level = spdlog::level::info; + std::string category; // e.g. "core", "gpu" + std::string text; // formatted message only (no timestamp/level prefix) +}; + +// Thread-safe ring-buffer spdlog sink. +// Capacity is fixed at 2048 entries; oldest entries are overwritten. +class LogCaptureSink : public spdlog::sinks::base_sink { + public: + static constexpr size_t kCapacity = 2048; + + // Copy all current entries in chronological order into `out`. + // Safe to call from any thread (e.g. the UI/render thread). + void CopyEntries(std::vector& out) const { + std::lock_guard lock(mutable_mutex_); + out.clear(); + out.reserve(count_); + if (count_ < kCapacity) { + // Buffer not yet full - entries start at index 0. + for (size_t i = 0; i < count_; ++i) { + out.push_back(buf_[i]); + } + } else { + // Full - oldest entry is at write_pos_ (wraps around). + for (size_t i = 0; i < kCapacity; ++i) { + out.push_back(buf_[(write_pos_ + i) % kCapacity]); + } + } + } + + // Returns true if new entries have been added since the last call + // to CopyEntries (checked by comparing generation counter). + uint64_t generation() const { + std::lock_guard lock(mutable_mutex_); + return generation_; + } + + protected: + void sink_it_(const spdlog::details::log_msg& msg) override { + std::string cat(msg.logger_name.begin(), msg.logger_name.end()); + + // Format just the payload (no timestamp, level, or logger name). + spdlog::memory_buf_t formatted; + formatter_->format(msg, formatted); + // Strip trailing newline spdlog adds. + std::string text(formatted.begin(), formatted.end()); + while (!text.empty() && (text.back() == '\n' || text.back() == '\r')) { + text.pop_back(); + } + + // Lock mutable_mutex_ so writes to buf_ are synchronized with + // CopyEntries() and generation() which also lock this mutex. + // (base_sink::mutex_ alone is insufficient -- CopyEntries doesn't hold it.) + std::lock_guard lock(mutable_mutex_); + buf_[write_pos_] = LogEntry{msg.level, std::move(cat), std::move(text)}; + write_pos_ = (write_pos_ + 1) % kCapacity; + if (count_ < kCapacity) + ++count_; + ++generation_; + } + + void flush_() override {} + + private: + std::array buf_{}; + size_t write_pos_ = 0; + size_t count_ = 0; + uint64_t generation_ = 0; + mutable std::mutex mutable_mutex_; +}; + +} // namespace rex diff --git a/include/rex/logging/types.h b/include/rex/logging/types.h new file mode 100644 index 0000000..984e28a --- /dev/null +++ b/include/rex/logging/types.h @@ -0,0 +1,115 @@ +/** + * @file rex/logging/types.h + * @brief Log category types, constants, and configuration + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include + +namespace rex { + +/** + * Lightweight handle identifying a log category. + * + * Internally a uint16_t index into the global category registry. + * SDK built-in categories are registered via REXLOG_DEFINE_CATEGORY; + * consumer categories are obtained at runtime via RegisterLogCategory(). + */ +struct LogCategoryId { + uint16_t id; + constexpr explicit LogCategoryId(uint16_t id) : id(id) {} + constexpr bool operator==(const LogCategoryId&) const = default; +}; + +/** + * Entry in the global category registry. + * Each registered category has a human-readable name and its own spdlog logger. + */ +struct LogCategoryEntry { + std::string name; /**< Category name (e.g. "core", "app.network") */ + std::shared_ptr logger; /**< Per-category spdlog logger instance */ + std::optional parent; + bool has_explicit_level = false; +}; + +#if defined(NDEBUG) +inline constexpr auto kDefaultLogLevel = spdlog::level::info; +inline constexpr auto kVerboseLogLevel = spdlog::level::trace; +#else +inline constexpr auto kDefaultLogLevel = spdlog::level::debug; +inline constexpr auto kVerboseLogLevel = spdlog::level::trace; +#endif + +/** + * Configuration for the logging system. + * + * Fill out and pass to InitLogging(). All fields have sensible defaults. + * String-keyed maps (category_levels, category_sinks) resolve by name so + * they work for categories that haven't been registered yet. + */ +struct LogConfig { + /** Global default log level applied to all categories unless overridden. */ + spdlog::level::level_enum default_level = spdlog::level::info; + + /** Whether to create a colored stdout sink. Intended for console-subsystem + * processes (CLI tools). Windowed apps should leave this false and rely on + * the platform debug sink created by InitLoggingEarly(). */ + bool log_to_console = false; + + /** Path to a log file, or nullptr for no file logging. */ + const char* log_file = nullptr; + + /** spdlog pattern string for the stdout console sink. */ + std::string console_pattern = "[%^%l%$] [%n] [t%t] %v"; + + /** spdlog pattern string for the file sink. */ + std::string file_pattern = "[%Y-%m-%d %H:%M:%S.%e] [%l] [%n] [t%t] %v"; + + /** Messages at or above this level trigger an immediate flush. */ + spdlog::level::level_enum flush_level = spdlog::level::info; + + /** + * Per-category log level overrides. + * Key is the category name (e.g. "core", "gpu", "app.network"). + * Categories not listed here use default_level. + */ + std::map category_levels; + + /** + * Extra sinks added to ALL loggers alongside the default console/file sinks. + * Useful for ring-buffer capture sinks, network sinks, etc. + */ + std::vector extra_sinks; + + /** + * Per-category extra sinks. Key is category name. + * Each vector of sinks is added ONLY to the specified category's logger. + */ + std::map> category_sinks; + + /** + * If true, per-category sinks in category_sinks REPLACE the default sinks + * for that category rather than being added alongside them. + * Default is false (additive). + */ + bool category_sinks_exclusive = false; + + std::string app_name; + std::string log_dir; +}; + +} // namespace rex diff --git a/include/rex/math.h b/include/rex/math.h new file mode 100644 index 0000000..ab7960f --- /dev/null +++ b/include/rex/math.h @@ -0,0 +1,317 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2019 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#if REX_ARCH_AMD64 +#include +#endif + +namespace rex { + +template +constexpr size_t countof(T (&)[N]) { + return std::extent::value; +} + +template +constexpr bool is_pow2(T value) { + return (value & (value - 1)) == 0; +} + +// Rounds up the given value to the given alignment. +template +constexpr T align(T value, T alignment) { + return (value + alignment - 1) & ~(alignment - 1); +} + +// Rounds the given number up to the next highest multiple. +template +constexpr T round_up(T value, V multiple, bool force_non_zero = true) { + if (force_non_zero && !value) { + return multiple; + } + return (value + multiple - 1) / multiple * multiple; +} + +// For NaN, returns min_value (or, if it's NaN too, max_value). +// If either of the boundaries is zero, and if the value is at that boundary or +// exceeds it, the result will have the sign of that boundary. If both +// boundaries are zero, which sign is selected among the argument signs is not +// explicitly defined. +template +T clamp_float(T value, T min_value, T max_value) { + float clamped_to_min = std::isgreater(value, min_value) ? value : min_value; + return std::isless(clamped_to_min, max_value) ? clamped_to_min : max_value; +} + +// Using the same conventions as in shading languages, returning 0 for NaN. +// 0 is always returned as positive. +template +T saturate(T value) { + return clamp_float(value, static_cast(0.0f), static_cast(1.0f)); +} + +// Gets the next power of two value that is greater than or equal to the given +// value. +template +T next_pow2(T value) { + value--; + value |= value >> 1; + value |= value >> 2; + value |= value >> 4; + value |= value >> 8; + value |= value >> 16; + value++; + return value; +} + +#if __cpp_lib_gcd_lcm +template +constexpr T greatest_common_divisor(T a, T b) { + return std::gcd(a, b); +} +#else +template +constexpr T greatest_common_divisor(T a, T b) { + // Use the Euclid algorithm to calculate the greatest common divisor + while (b) { + a = std::exchange(b, a % b); + } + return a; +} +#endif + +template +constexpr void reduce_fraction(T& numerator, T& denominator) { + auto gcd = greatest_common_divisor(numerator, denominator); + numerator /= gcd; + denominator /= gcd; +} + +template +constexpr void reduce_fraction(std::pair& fraction) { + reduce_fraction(fraction.first, fraction.second); +} + +constexpr uint32_t make_bitmask(uint32_t a, uint32_t b) { + return (static_cast(-1) >> (31 - b)) & ~((1u << a) - 1); +} + +constexpr uint32_t select_bits(uint32_t value, uint32_t a, uint32_t b) { + return (value & make_bitmask(a, b)) >> a; +} + +template +constexpr uint32_t bit_count(T v) { + return static_cast(std::popcount(v)); +} + +// lzcnt - count leading zeros. +// Returns the size of the input operand if value is zero. +uint8_t lzcnt(uint8_t v); +uint8_t lzcnt(uint16_t v); +uint8_t lzcnt(uint32_t v); +uint8_t lzcnt(uint64_t v); + +// tzcnt - count trailing zeros. +uint8_t tzcnt(uint8_t v); +uint8_t tzcnt(uint16_t v); +uint8_t tzcnt(uint32_t v); +uint8_t tzcnt(uint64_t v); +inline uint8_t lzcnt(int8_t v) { + return lzcnt(static_cast(v)); +} +inline uint8_t lzcnt(int16_t v) { + return lzcnt(static_cast(v)); +} +inline uint8_t lzcnt(int32_t v) { + return lzcnt(static_cast(v)); +} +inline uint8_t lzcnt(int64_t v) { + return lzcnt(static_cast(v)); +} +inline uint8_t tzcnt(int8_t v) { + return tzcnt(static_cast(v)); +} +inline uint8_t tzcnt(int16_t v) { + return tzcnt(static_cast(v)); +} +inline uint8_t tzcnt(int32_t v) { + return tzcnt(static_cast(v)); +} +inline uint8_t tzcnt(int64_t v) { + return tzcnt(static_cast(v)); +} + +// BitScanForward (bsf). +// Search the value from least significant bit (LSB) to the most significant bit +// (MSB) for a set bit (1). +// Returns false if no bits are set and the output index is invalid. +bool bit_scan_forward(uint32_t v, uint32_t* out_first_set_index); +bool bit_scan_forward(uint64_t v, uint32_t* out_first_set_index); +inline bool bit_scan_forward(int32_t v, uint32_t* out_first_set_index) { + return bit_scan_forward(static_cast(v), out_first_set_index); +} +inline bool bit_scan_forward(int64_t v, uint32_t* out_first_set_index) { + return bit_scan_forward(static_cast(v), out_first_set_index); +} + +template +inline T log2_floor(T v) { + return sizeof(T) * 8 - 1 - lzcnt(v); +} +template +inline T log2_ceil(T v) { + return sizeof(T) * 8 - lzcnt(v - 1); +} + +template +inline T rotate_left(T v, uint8_t sh) { + return (T(v) << sh) | (T(v) >> ((sizeof(T) * 8) - sh)); +} + +#if REX_ARCH_AMD64 +// Utilities for SSE values. +template +float m128_f32(const __m128& v) { + float ret; + _mm_store_ss(&ret, _mm_shuffle_ps(v, v, _MM_SHUFFLE(N, N, N, N))); + return ret; +} +template +int32_t m128_i32(const __m128& v) { + float f; + _mm_store_ss(&f, _mm_shuffle_ps(v, v, _MM_SHUFFLE(N, N, N, N))); + return std::bit_cast(f); +} +template +double m128_f64(const __m128d& v) { + double ret; + _mm_store_sd(&ret, _mm_shuffle_pd(v, v, _MM_SHUFFLE2(N, N))); + return ret; +} +template +double m128_f64(const __m128& v) { + return m128_f64(_mm_castps_pd(v)); +} +template +int64_t m128_i64(const __m128d& v) { + double f; + _mm_store_sd(&f, _mm_shuffle_pd(v, v, _MM_SHUFFLE2(N, N))); + return std::bit_cast(f); +} +template +int64_t m128_i64(const __m128& v) { + return m128_i64(_mm_castps_pd(v)); +} +#endif + +// Similar to the C++ implementation of XMConvertFloatToHalf and +// XMConvertHalfToFloat from DirectXMath 3.00 (pre-3.04, which switched from the +// Xenos encoding to IEEE 754), with the extended range instead of infinity and +// NaN, and optionally with denormalized numbers - as used in vpkd3d128 (no +// denormals, rounding towards zero) and on the Xenos (GL_OES_texture_float +// alternative encoding). + +inline uint16_t float_to_xenos_half(float value, bool preserve_denormal = false, + bool round_to_nearest_even = false) { + uint32_t integer_value = std::bit_cast(value); + uint32_t abs_value = integer_value & 0x7FFFFFFFu; + uint32_t result; + if (abs_value >= 0x47FFE000u) { + // Saturate. + result = 0x7FFFu; + } else { + if (abs_value < 0x38800000u) { + // The number is too small to be represented as a normalized half. + if (preserve_denormal) { + uint32_t shift = std::min(uint32_t(113u - (abs_value >> 23u)), uint32_t(24u)); + result = (0x800000u | (abs_value & 0x7FFFFFu)) >> shift; + } else { + result = 0u; + } + } else { + // Rebias the exponent to represent the value as a normalized half. + result = abs_value + 0xC8000000u; + } + if (round_to_nearest_even) { + result += 0xFFFu + ((result >> 13u) & 1u); + } + result = (result >> 13u) & 0x7FFFu; + } + return uint16_t(result | ((integer_value & 0x80000000u) >> 16u)); +} + +inline float xenos_half_to_float(uint16_t value, bool preserve_denormal = false) { + uint32_t mantissa = value & 0x3FFu; + uint32_t exponent = (value >> 10u) & 0x1Fu; + if (!exponent) { + if (!preserve_denormal) { + mantissa = 0; + } else if (mantissa) { + // Normalize the value in the resulting float. + // do { Exponent--; Mantissa <<= 1; } while ((Mantissa & 0x0400) == 0) + uint32_t mantissa_lzcnt = rex::lzcnt(mantissa) - (32u - 11u); + exponent = uint32_t(1 - int32_t(mantissa_lzcnt)); + mantissa = (mantissa << mantissa_lzcnt) & 0x3FFu; + } + if (!mantissa) { + exponent = uint32_t(-112); + } + } + uint32_t result = + (uint32_t(value & 0x8000u) << 16u) | ((exponent + 112u) << 23u) | (mantissa << 13u); + return std::bit_cast(result); +} + +// https://locklessinc.com/articles/sat_arithmetic/ +template +inline T sat_add(T a, T b) { + using TU = typename std::make_unsigned::type; + TU result = TU(a) + TU(b); + if (std::is_unsigned::value) { + result |= TU(-static_cast::type>(result < TU(a))); + } else { + TU overflowed = (TU(a) >> (sizeof(T) * 8 - 1)) + std::numeric_limits::max(); + if (T((overflowed ^ TU(b)) | ~(TU(b) ^ result)) >= 0) { + result = overflowed; + } + } + return T(result); +} +template +inline T sat_sub(T a, T b) { + using TU = typename std::make_unsigned::type; + TU result = TU(a) - TU(b); + if (std::is_unsigned::value) { + result &= TU(-static_cast::type>(result <= TU(a))); + } else { + TU overflowed = (TU(a) >> (sizeof(T) * 8 - 1)) + std::numeric_limits::max(); + if (T((overflowed ^ TU(b)) & (overflowed ^ result)) < 0) { + result = overflowed; + } + } + return T(result); +} + +} // namespace rex diff --git a/include/rex/memory.h b/include/rex/memory.h new file mode 100644 index 0000000..6df60dc --- /dev/null +++ b/include/rex/memory.h @@ -0,0 +1,27 @@ +/** + * @file memory.h + * @brief Memory subsystem umbrella header + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +// Memory utilities (page allocation, protection, load/store helpers) +#include + +// Arena allocator +#include + +// Memory-mapped files +#include + +// Ring buffer +#include + +// Memory class (Xbox 360 guest memory system with heaps) +#include diff --git a/include/rex/memory/arena.h b/include/rex/memory/arena.h new file mode 100644 index 0000000..5755122 --- /dev/null +++ b/include/rex/memory/arena.h @@ -0,0 +1,69 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include + +#include + +namespace rex::memory { + +using namespace rex::literals; + +class Arena { + public: + explicit Arena(size_t chunk_size = 4_MiB); + ~Arena(); + + void Reset(); + void DebugFill(); + + void* Alloc(size_t size, size_t align); + template + T* Alloc() { + return reinterpret_cast(Alloc(sizeof(T), alignof(T))); + } + // When rewinding aligned allocations, any padding that was applied during + // allocation will be leaked + void Rewind(size_t size); + + void* CloneContents(); + template + void CloneContents(std::vector* buffer) { + buffer->resize(CalculateSize() / sizeof(T)); + CloneContents(buffer->data(), buffer->size() * sizeof(T)); + } + + private: + class Chunk { + public: + explicit Chunk(size_t chunk_size); + ~Chunk(); + + Chunk* next; + + size_t capacity; + uint8_t* buffer; + size_t offset; + }; + + size_t CalculateSize(); + void CloneContents(void* buffer, size_t buffer_length); + + size_t chunk_size_; + Chunk* head_chunk_; + Chunk* active_chunk_; +}; + +} // namespace rex::memory diff --git a/include/rex/memory/mapped_memory.h b/include/rex/memory/mapped_memory.h new file mode 100644 index 0000000..6a73d9a --- /dev/null +++ b/include/rex/memory/mapped_memory.h @@ -0,0 +1,92 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include + +#include + +namespace rex::memory { + +class MappedMemory { + public: + enum class Mode { + kRead, + kReadWrite, + }; + + static std::unique_ptr Open(const std::filesystem::path& path, Mode mode, + size_t offset = 0, size_t length = 0); +#if REX_PLATFORM_ANDROID + static std::unique_ptr OpenForAndroidContentUri(const std::string_view uri, + Mode mode, size_t offset = 0, + size_t length = 0); +#endif // REX_PLATFORM_ANDROID + + MappedMemory() : data_(nullptr), size_(0) {} + MappedMemory(void* data, size_t size) : data_(data), size_(size) {} + MappedMemory(const MappedMemory& mapped_memory) = delete; + MappedMemory& operator=(const MappedMemory& mapped_memory) = delete; + MappedMemory(MappedMemory&& mapped_memory) = delete; + MappedMemory& operator=(MappedMemory&& mapped_memory) = delete; + virtual ~MappedMemory() = default; + + // The mapping is still backed by the object the slice was created from, a + // slice is not owning. + std::unique_ptr Slice(size_t offset, size_t length) { + return std::unique_ptr(new MappedMemory(data() + offset, length)); + } + + uint8_t* data() const { return reinterpret_cast(data_); } + size_t size() const { return size_; } + + // Close, and optionally truncate file to size + virtual void Close(uint64_t truncate_size = 0) { (void)truncate_size; } + virtual void Flush() {} + + // Changes the offset inside the file. This will update data() and size()! + virtual bool Remap(size_t offset, size_t length) { + (void)offset; + (void)length; + return false; + } + + protected: + void* data_; + size_t size_; +}; + +class ChunkedMappedMemoryWriter { + public: + virtual ~ChunkedMappedMemoryWriter() = default; + + static std::unique_ptr Open(const std::filesystem::path& path, + size_t chunk_size, + bool low_address_space = false); + + virtual uint8_t* Allocate(size_t length) = 0; + virtual void Flush() = 0; + virtual void FlushNew() = 0; + + protected: + ChunkedMappedMemoryWriter(const std::filesystem::path& path, size_t chunk_size, + bool low_address_space) + : path_(path), chunk_size_(chunk_size), low_address_space_(low_address_space) {} + + std::filesystem::path path_; + size_t chunk_size_; + bool low_address_space_; +}; + +} // namespace rex::memory diff --git a/include/rex/memory/ring_buffer.h b/include/rex/memory/ring_buffer.h new file mode 100644 index 0000000..0a5b96e --- /dev/null +++ b/include/rex/memory/ring_buffer.h @@ -0,0 +1,144 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include + +namespace rex::memory { + +// Use uint32_t instead of size_t to eliminate REX prefix on x86-64 +// instructions in this hot class. +using ring_size_t = uint32_t; + +class RingBuffer { + public: + RingBuffer(uint8_t* buffer, size_t capacity); + + uint8_t* buffer() const { return buffer_; } + ring_size_t capacity() const { return capacity_; } + bool empty() const { return read_offset_ == write_offset_; } + + ring_size_t read_offset() const { return read_offset_; } + uintptr_t read_ptr() const { return uintptr_t(buffer_) + static_cast(read_offset_); } + void set_read_offset(size_t offset) { + read_offset_ = static_cast(offset) % capacity_; + } + ring_size_t read_count() const { + ring_size_t read_offs = read_offset_; + ring_size_t write_offs = write_offset_; + ring_size_t cap = capacity_; + if (read_offs <= write_offs) { + return write_offs - read_offs; + } else { + return (cap - read_offs) + write_offs; + } + } + + ring_size_t write_offset() const { return write_offset_; } + uintptr_t write_ptr() const { return uintptr_t(buffer_) + static_cast(write_offset_); } + void set_write_offset(size_t offset) { + write_offset_ = static_cast(offset) % capacity_; + } + ring_size_t write_count() const { + ring_size_t read_offs = read_offset_; + ring_size_t write_offs = write_offset_; + ring_size_t cap = capacity_; + if (read_offs == write_offs) { + return cap; + } else if (write_offs < read_offs) { + return read_offs - write_offs; + } else { + return (cap - write_offs) + read_offs; + } + } + + void AdvanceRead(size_t count); + void AdvanceWrite(size_t count); + + struct ReadRange { + const uint8_t* __restrict first; + const uint8_t* __restrict second; + ring_size_t first_length; + ring_size_t second_length; + }; + ReadRange BeginRead(size_t count); + void EndRead(ReadRange read_range); + + size_t Read(uint8_t* buffer, size_t count); + template + size_t Read(T* buffer, size_t count) { + return Read(reinterpret_cast(buffer), count); + } + + template + T Read() { + static_assert(std::is_fundamental::value, "Immediate read only supports basic types!"); + + T imm; + size_t read = Read(reinterpret_cast(&imm), sizeof(T)); + assert_true(read == sizeof(T)); + return imm; + } + + template + T ReadAndSwap() { + static_assert(std::is_fundamental::value, "Immediate read only supports basic types!"); + + T imm; + size_t read = Read(reinterpret_cast(&imm), sizeof(T)); + assert_true(read == sizeof(T)); + imm = rex::byte_swap(imm); + return imm; + } + + size_t Write(const uint8_t* buffer, size_t count); + template + size_t Write(const T* buffer, size_t count) { + return Write(reinterpret_cast(buffer), count); + } + + template + size_t Write(T& data) { + return Write(reinterpret_cast(&data), sizeof(T)); + } + + private: + uint8_t* __restrict buffer_ = nullptr; + ring_size_t capacity_ = 0; + ring_size_t read_offset_ = 0; + ring_size_t write_offset_ = 0; +}; + +// Fast path for GPU command processor - the hottest path. +// Direct load bypasses generic Read() + memcpy. +// Uses == (not >=) for wrap check: capacity must be a multiple of 4, +// so next_read_offset can only land exactly at capacity, never past it. +template <> +inline uint32_t RingBuffer::ReadAndSwap() { + assert_true(capacity_ >= 4); + ring_size_t read_offs = read_offset_; + ring_size_t next_read_offs = read_offs + 4; + if (next_read_offs == capacity_) [[unlikely]] { + next_read_offs = 0; + } + read_offset_ = next_read_offs; + uint32_t ring_value = *(uint32_t*)(buffer_ + read_offs); + return rex::byte_swap(ring_value); +} + +} // namespace rex::memory diff --git a/include/rex/memory/utils.h b/include/rex/memory/utils.h new file mode 100644 index 0000000..8ccb52c --- /dev/null +++ b/include/rex/memory/utils.h @@ -0,0 +1,312 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace rex { +namespace memory { + +// For variable declarations (not return values or `this` pointer). +// Not propagated. +#define REX_RESTRICT_VAR __restrict + +// Aliasing-safe bit reinterpretation. +// For more complex cases such as non-trivially-copyable types, write copying +// code respecting the requirements for them externally instead of using these +// functions. + +template +void Reinterpret(Dst& REX_RESTRICT_VAR dst, const Src& REX_RESTRICT_VAR src) { + static_assert(sizeof(Dst) == sizeof(Src)); + static_assert(std::is_trivially_copyable_v); + static_assert(std::is_trivially_copyable_v); + std::memcpy(&dst, &src, sizeof(Dst)); +} + +template +Dst Reinterpret(const Src& REX_RESTRICT_VAR src) { + Dst dst; + Reinterpret(dst, src); + return dst; +} + +#if REX_PLATFORM_ANDROID +void AndroidInitialize(); +void AndroidShutdown(); +#endif + +// Returns the native page size of the system, in bytes. +// This should be ~4KiB. +size_t page_size(); + +// Returns the allocation granularity of the system, in bytes. +// This is likely 64KiB. +size_t allocation_granularity(); + +enum class PageAccess { + kNoAccess = 0, + kReadOnly = 1 << 0, + kReadWrite = kReadOnly | 1 << 1, + kExecuteReadOnly = kReadOnly | 1 << 2, + kExecuteReadWrite = kReadWrite | 1 << 2, +}; + +enum class AllocationType { + kReserve = 1 << 0, + kCommit = 1 << 1, + kReserveCommit = kReserve | kCommit, +}; + +enum class DeallocationType { + kRelease = 1 << 0, + kDecommit = 1 << 1, +}; + +// Whether the host allows the pages to be allocated or mapped with +// PageAccess::kExecuteReadWrite - if not, separate mappings backed by the same +// memory-mapped file must be used to write to executable pages. +bool IsWritableExecutableMemorySupported(); + +// Whether PageAccess::kExecuteReadWrite is a supported and preferred way of +// writing executable memory, useful for simulating how Xenia would work without +// writable executable memory on a system with it. +bool IsWritableExecutableMemoryPreferred(); + +// Allocates a block of memory at the given page-aligned base address. +// Fails if the memory is not available. +// Specify nullptr for base_address to leave it up to the system. +void* AllocFixed(void* base_address, size_t length, AllocationType allocation_type, + PageAccess access); + +// Deallocates and/or releases the given block of memory. +// When releasing memory length must be zero, as all pages in the region are +// released. +bool DeallocFixed(void* base_address, size_t length, DeallocationType deallocation_type); + +// Sets the access rights for the given block of memory and returns the previous +// access rights. Both base_address and length will be adjusted to page_size(). +bool Protect(void* base_address, size_t length, PageAccess access, + PageAccess* out_old_access = nullptr); + +// Queries a region of pages to get the access rights. This will modify the +// length parameter to the length of pages with the same consecutive access +// rights. The length will start from the first byte of the first page of +// the region. +bool QueryProtect(void* base_address, size_t& length, PageAccess& access_out); + +// Allocates a block of memory for a type with the given alignment. +// The memory must be freed with AlignedFree. +template +inline T* AlignedAlloc(size_t alignment) { +#if REX_PLATFORM_WIN32 + return reinterpret_cast(_aligned_malloc(sizeof(T), alignment)); +#else + void* ptr = nullptr; + if (posix_memalign(&ptr, alignment, sizeof(T))) { + return nullptr; + } + return reinterpret_cast(ptr); +#endif +} + +// Frees memory previously allocated with AlignedAlloc. +template +void AlignedFree(T* ptr) { +#if REX_PLATFORM_WIN32 + _aligned_free(ptr); +#else + free(ptr); +#endif +} + +// Opaque file mapping handle. +// On Windows this holds a HANDLE (void*), on POSIX a file descriptor (int). +// We use intptr_t to hold either without platform guards. +using FileMappingHandle = intptr_t; +constexpr FileMappingHandle kFileMappingHandleInvalid = -1; + +FileMappingHandle CreateFileMappingHandle(const std::filesystem::path& path, size_t length, + PageAccess access, bool commit); +void CloseFileMappingHandle(FileMappingHandle handle, const std::filesystem::path& path); +void* MapFileView(FileMappingHandle handle, void* base_address, size_t length, PageAccess access, + size_t file_offset); +bool UnmapFileView(FileMappingHandle handle, void* base_address, size_t length); + +inline size_t hash_combine(size_t seed) { + return seed; +} + +template +size_t hash_combine(size_t seed, const T& v, const Ts&... vs) { + std::hash hasher; + seed ^= hasher(v) + 0x9E3779B9 + (seed << 6) + (seed >> 2); + return hash_combine(seed, vs...); +} + +inline void* low_address(void* address) { + return reinterpret_cast(uint64_t(address) & 0xFFFFFFFF); +} + +void copy_128_aligned(void* dest, const void* src, size_t count); + +void copy_and_swap_16_aligned(void* dest, const void* src, size_t count); +void copy_and_swap_16_unaligned(void* dest, const void* src, size_t count); +void copy_and_swap_32_aligned(void* dest, const void* src, size_t count); +void copy_and_swap_32_unaligned(void* dest, const void* src, size_t count); +void copy_and_swap_64_aligned(void* dest, const void* src, size_t count); +void copy_and_swap_64_unaligned(void* dest, const void* src, size_t count); +void copy_and_swap_16_in_32_aligned(void* dest, const void* src, size_t count); +void copy_and_swap_16_in_32_unaligned(void* dest, const void* src, size_t count); + +template +void copy_and_swap(T* dest, const T* src, size_t count) { + bool is_aligned = + reinterpret_cast(dest) % 32 == 0 && reinterpret_cast(src) % 32 == 0; + if (sizeof(T) == 1) { + std::memcpy(dest, src, count); + } else if (sizeof(T) == 2) { + auto ps = reinterpret_cast(src); + auto pd = reinterpret_cast(dest); + if (is_aligned) { + copy_and_swap_16_aligned(pd, ps, count); + } else { + copy_and_swap_16_unaligned(pd, ps, count); + } + } else if (sizeof(T) == 4) { + auto ps = reinterpret_cast(src); + auto pd = reinterpret_cast(dest); + if (is_aligned) { + copy_and_swap_32_aligned(pd, ps, count); + } else { + copy_and_swap_32_unaligned(pd, ps, count); + } + } else if (sizeof(T) == 8) { + auto ps = reinterpret_cast(src); + auto pd = reinterpret_cast(dest); + if (is_aligned) { + copy_and_swap_64_aligned(pd, ps, count); + } else { + copy_and_swap_64_unaligned(pd, ps, count); + } + } else { + assert_always("Invalid memory::copy_and_swap size"); + } +} + +/// Load a value of type T from arbitrary memory (handles unaligned access). +template +inline T load(const void* mem) { + static_assert(std::is_trivially_copyable_v, "T must be trivially copyable"); + T result; + std::memcpy(&result, mem, sizeof(T)); + return result; +} + +/// Load a value of type T from memory and byte-swap it. +template +inline T load_and_swap(const void* mem) { + return byte_swap(load(mem)); +} + +// String specializations need custom logic +template <> +inline std::string load_and_swap(const void* mem) { + std::string value; + for (int i = 0;; ++i) { + auto c = load_and_swap(reinterpret_cast(mem) + i); + if (!c) { + break; + } + value.push_back(static_cast(c)); + } + return value; +} +template <> +inline std::u16string load_and_swap(const void* mem) { + std::u16string value; + for (int i = 0;; ++i) { + auto c = load_and_swap(reinterpret_cast(mem) + i); + if (!c) { + break; + } + value.push_back(static_cast(c)); + } + return value; +} + +/// Store a value of type T to arbitrary memory (handles unaligned access). +template +inline void store(void* mem, const T& value) { + static_assert(std::is_trivially_copyable_v, "T must be trivially copyable"); + std::memcpy(mem, &value, sizeof(T)); +} + +/// Store a byte-swapped value of type T to memory. +template +inline void store_and_swap(void* mem, const T& value) { + store(mem, byte_swap(value)); +} + +// String specializations need custom logic +template <> +inline void store_and_swap(void* mem, const std::string_view& value) { + for (size_t i = 0; i < value.size(); ++i) { + store_and_swap(reinterpret_cast(mem) + i, value[i]); + } +} +template <> +inline void store_and_swap(void* mem, const std::string& value) { + return store_and_swap(mem, value); +} +template <> +inline void store_and_swap(void* mem, const std::u16string_view& value) { + for (size_t i = 0; i < value.size(); ++i) { + store_and_swap(reinterpret_cast(mem) + i, value[i]); + } +} +template <> +inline void store_and_swap(void* mem, const std::u16string& value) { + return store_and_swap(mem, value); +} + +using fourcc_t = uint32_t; + +// Get FourCC in host byte order +// make_fourcc('a', 'b', 'c', 'd') == 0x61626364 +constexpr inline fourcc_t make_fourcc(char a, char b, char c, char d) { + return fourcc_t((static_cast(a) << 24) | (static_cast(b) << 16) | + (static_cast(c) << 8) | static_cast(d)); +} + +// Get FourCC in host byte order +// This overload requires fourcc.length() == 4 +// make_fourcc("abcd") == 'abcd' == 0x61626364 for most compilers +constexpr inline fourcc_t make_fourcc(const std::string_view fourcc) { + if (fourcc.length() != 4) { + throw std::runtime_error("Invalid fourcc length"); + } + return make_fourcc(fourcc[0], fourcc[1], fourcc[2], fourcc[3]); +} + +} // namespace memory +} // namespace rex diff --git a/include/rex/net/socket.h b/include/rex/net/socket.h new file mode 100644 index 0000000..f107c8a --- /dev/null +++ b/include/rex/net/socket.h @@ -0,0 +1,17 @@ +/** + * @file net/socket.h + * @brief Platform-agnostic socket operations + */ +#pragma once + +#include + +namespace rex::net { + +using SocketHandle = int64_t; +constexpr SocketHandle kInvalidSocket = -1; + +int socket_close(SocketHandle handle); +int socket_ioctl(SocketHandle handle, uint32_t cmd, uint8_t* arg); + +} // namespace rex::net diff --git a/include/rex/o1heap_config.h b/include/rex/o1heap_config.h new file mode 100644 index 0000000..31ba131 --- /dev/null +++ b/include/rex/o1heap_config.h @@ -0,0 +1,26 @@ +/** + * @file o1heap_config.h + * @brief o1heap build configuration -- provides correct 64-bit CLZ. + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +// On Windows, unsigned long is 32 bits even on x64. o1heap.c auto-selects +// __builtin_clzl under clang-cl (because __clang__ is defined), but that +// gives a 32-bit CLZ while o1heap needs 64-bit (size_t-width). This causes +// roundUpToPowerOf2() to produce astronomically large values, corrupting the +// heap bin structure on first allocation. +#pragma once + +#if defined(__clang__) || defined(__GNUC__) +#define O1HEAP_CLZ(x) ((uint8_t)__builtin_clzll((unsigned long long)(x))) +#elif defined(_MSC_VER) +#include +static __inline uint8_t o1heap_clz_(size_t x) { + unsigned long index; + _BitScanReverse64(&index, (unsigned __int64)x); + return (uint8_t)(63U - index); +} +#define O1HEAP_CLZ(x) o1heap_clz_(x) +#endif diff --git a/include/rex/perf/counter.h b/include/rex/perf/counter.h new file mode 100644 index 0000000..167b645 --- /dev/null +++ b/include/rex/perf/counter.h @@ -0,0 +1,186 @@ +/** + * @file perf/counter.h + * @brief Performance counter registry and profiler + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ +#pragma once + +#include +#include + +#ifdef REXGLUE_ENABLE_PROFILING +#include +#endif + +namespace rex::perf { + +enum class CounterId : uint16_t { + // Frame + kFrameTimeUs, + kFps, + + // GPU + kDrawCalls, + kCommandBufferStalls, + kVerticesProcessed, + + // Audio + kXmaFramesDecoded, + kAudioFrameLatencyUs, + kBufferQueueDepth, + + // Dispatch + kFunctionsDispatched, + kInterruptDispatches, + + // Threading + kActiveThreads, + kApcQueueDepth, + kCriticalRegionContentions, + + // Caches + kTextureCacheHits, + kTextureCacheMisses, + kPipelineCacheHits, + kPipelineCacheMisses, + + kCount // sentinel -- must be last +}; + +// Returns human-readable name for a counter (e.g. "frame_time_us") +const char* CounterName(CounterId id); + +// Set a counter to an absolute value +void SetCounter(CounterId id, int64_t value); + +// Atomically add to a counter +void IncrementCounter(CounterId id, int64_t delta = 1); + +// Read a counter's current live value +int64_t GetCounter(CounterId id); + +// Snapshot current values into the read buffer and zero the live counters. +// Called once per frame by Profiler::Flip(). +void ResetFrameCounters(); + +// Read a counter from the last-frame snapshot (stable between frames). +int64_t GetSnapshotCounter(CounterId id); + +// Initialize the counter system (zeroes everything). Safe to call multiple times. +void Init(); + +// CSV logging +void SetCsvLogPath(const std::string& path); +void WriteCsvFrame(); +void FlushCsv(); + +// Profiler -- coordinates Tracy frame marks and counter snapshots. +// Moved here from rex::debug to consolidate all perf code under rex::perf. +class Profiler { + public: + // Call once at runtime startup to enable Tracy's network threads. + // CLI tools should skip this to avoid socket listeners entirely. + static void Startup() { +#ifdef REXGLUE_ENABLE_PROFILING + tracy::StartupProfiler(); +#endif + } + static void OnThreadEnter(const char* name = nullptr) { +#ifdef REXGLUE_ENABLE_PROFILING + if (name) + tracy::SetThreadName(name); +#else + (void)name; +#endif + } + static void OnThreadExit() {} + static void ThreadEnter(const char* name = nullptr) { OnThreadEnter(name); } + static void ThreadExit() {} + static void Flip() { +#ifdef REXGLUE_ENABLE_PROFILING + FrameMark; +#endif +#ifdef REXGLUE_ENABLE_PERF_COUNTERS + ResetFrameCounters(); + WriteCsvFrame(); +#endif + } + static void Flush() {} + static void Shutdown() { +#ifdef REXGLUE_ENABLE_PROFILING + tracy::ShutdownProfiler(); +#endif +#ifdef REXGLUE_ENABLE_PERF_COUNTERS + FlushCsv(); +#endif + } + static bool is_enabled() { +#ifdef REXGLUE_ENABLE_PROFILING + return tracy::IsProfilerStarted(); +#else + return false; +#endif + } +}; + +} // namespace rex::perf + +// Perf counter macros -- compile to no-ops when counters are disabled. +#ifdef REXGLUE_ENABLE_PERF_COUNTERS + +// Generic helpers for easily adding new counters +#define PERF_counter_set(id, value) rex::perf::SetCounter(rex::perf::CounterId::id, value) +#define PERF_counter_inc(id) rex::perf::IncrementCounter(rex::perf::CounterId::id) +#define PERF_counter_add(id, delta) rex::perf::IncrementCounter(rex::perf::CounterId::id, delta) + +// Purpose-specific macros so callsites stay clean +#define PROFILE_FRAME_TIME_US(value) PERF_counter_set(kFrameTimeUs, value) +#define PROFILE_FPS(value) PERF_counter_set(kFps, value) +#define PROFILE_FUNCTION_DISPATCHED() PERF_counter_inc(kFunctionsDispatched) +#define PROFILE_INTERRUPT_DISPATCHED() PERF_counter_inc(kInterruptDispatches) +#define PROFILE_XMA_FRAME_DECODED() PERF_counter_inc(kXmaFramesDecoded) +#define PROFILE_DRAW_CALL() PERF_counter_inc(kDrawCalls) +#define PROFILE_VERTICES(n) PERF_counter_add(kVerticesProcessed, n) +#define PROFILE_CMD_BUFFER_STALL() PERF_counter_inc(kCommandBufferStalls) +#define PROFILE_AUDIO_LATENCY_US(value) PERF_counter_set(kAudioFrameLatencyUs, value) +#define PROFILE_BUFFER_QUEUE_DEPTH(value) PERF_counter_set(kBufferQueueDepth, value) +#define PROFILE_THREAD_CREATED() PERF_counter_inc(kActiveThreads) +#define PROFILE_THREAD_EXITED() PERF_counter_add(kActiveThreads, -1) +#define PROFILE_APC_QUEUE_DEPTH(value) PERF_counter_set(kApcQueueDepth, value) +#define PROFILE_CRITICAL_REGION_CONTENTION() PERF_counter_inc(kCriticalRegionContentions) +#define PROFILE_TEXTURE_CACHE_HIT() PERF_counter_inc(kTextureCacheHits) +#define PROFILE_TEXTURE_CACHE_MISS() PERF_counter_inc(kTextureCacheMisses) +#define PROFILE_PIPELINE_CACHE_HIT() PERF_counter_inc(kPipelineCacheHits) +#define PROFILE_PIPELINE_CACHE_MISS() PERF_counter_inc(kPipelineCacheMisses) + +#else + +#define PERF_counter_set(id, value) +#define PERF_counter_inc(id) +#define PERF_counter_add(id, delta) + +#define PROFILE_FRAME_TIME_US(value) +#define PROFILE_FPS(value) +#define PROFILE_FUNCTION_DISPATCHED() +#define PROFILE_INTERRUPT_DISPATCHED() +#define PROFILE_XMA_FRAME_DECODED() +#define PROFILE_DRAW_CALL() +#define PROFILE_VERTICES(n) +#define PROFILE_CMD_BUFFER_STALL() +#define PROFILE_AUDIO_LATENCY_US(value) +#define PROFILE_BUFFER_QUEUE_DEPTH(value) +#define PROFILE_THREAD_CREATED() +#define PROFILE_THREAD_EXITED() +#define PROFILE_APC_QUEUE_DEPTH(value) +#define PROFILE_CRITICAL_REGION_CONTENTION() +#define PROFILE_TEXTURE_CACHE_HIT() +#define PROFILE_TEXTURE_CACHE_MISS() +#define PROFILE_PIPELINE_CACHE_HIT() +#define PROFILE_PIPELINE_CACHE_MISS() + +#endif diff --git a/include/rex/platform.h b/include/rex/platform.h new file mode 100644 index 0000000..57d8cf6 --- /dev/null +++ b/include/rex/platform.h @@ -0,0 +1,158 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +// This file contains the main platform switches used by rex as well as any +// fixups required to normalize the environment. Everything in here should be +// largely portable. +// Platform-specific headers, like platform_win.h, are used to house any +// super platform-specific stuff that implies code is not platform-agnostic. +// +// NOTE: ordering matters here as sometimes multiple flags are defined on +// certain platforms. +// +// Great resource on predefined macros: +// https://sourceforge.net/p/predef/wiki/OperatingSystems/ +// Original link: https://predef.sourceforge.net/preos.html + +#if defined(__APPLE__) +#include +#endif + +#if defined(TARGET_OS_MAC) && TARGET_OS_MAC +#define REX_PLATFORM_MAC 1 +#elif defined(WIN32) || defined(_WIN32) +#define REX_PLATFORM_WIN32 1 +#elif defined(__ANDROID__) +#define REX_PLATFORM_ANDROID 1 +#define REX_PLATFORM_LINUX 1 +#elif defined(__gnu_linux__) +#define REX_PLATFORM_GNU_LINUX 1 +#define REX_PLATFORM_LINUX 1 +#else +#error Unsupported target OS. +#endif + +// Ensure all platform macros are always defined (0 when inactive) +// so they can be used in static_assert and regular expressions. +#ifndef REX_PLATFORM_MAC +#define REX_PLATFORM_MAC 0 +#endif +#ifndef REX_PLATFORM_WIN32 +#define REX_PLATFORM_WIN32 0 +#endif +#ifndef REX_PLATFORM_ANDROID +#define REX_PLATFORM_ANDROID 0 +#endif +#ifndef REX_PLATFORM_GNU_LINUX +#define REX_PLATFORM_GNU_LINUX 0 +#endif +#ifndef REX_PLATFORM_LINUX +#define REX_PLATFORM_LINUX 0 +#endif + +#if defined(__clang__) +#define REX_COMPILER_CLANG 1 +#elif defined(__GNUC__) +#define REX_COMPILER_GNUC 1 +#elif defined(_MSC_VER) +#define REX_COMPILER_MSVC 1 +#elif defined(__MINGW32) +#define REX_COMPILER_MINGW32 1 +#elif defined(__INTEL_COMPILER) +#define REX_COMPILER_INTEL 1 +#else +#define REX_COMPILER_UNKNOWN 1 +#endif + +#if defined(_M_AMD64) || defined(__amd64__) +#define REX_ARCH_AMD64 1 +#elif defined(_M_ARM64) || defined(__aarch64__) +#define REX_ARCH_ARM64 1 +#elif defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__) +#error Rex is not supported on 32-bit platforms. +#elif defined(_M_PPC) || defined(__powerpc__) +#define REX_ARCH_PPC 1 +#endif + +#if REX_PLATFORM_WIN32 +#define WIN32_LEAN_AND_MEAN +#define NOMINMAX // Don't want windows.h including min/max macros. +#endif // REX_PLATFORM_WIN32 + +#if REX_PLATFORM_WIN32 +#include +#elif REX_ARCH_AMD64 +#include +#endif // REX_PLATFORM_WIN32 + +#if REX_PLATFORM_MAC +#include +#endif // REX_PLATFORM_MAC + +#include +#include + +//============================================================================= +// Compiler Polyfills +//============================================================================= + +#if defined(__clang__) +// Clang has builtin rotate functions and debugtrap +#elif defined(__GNUC__) +#ifndef __builtin_rotateleft32 +#define __builtin_rotateleft32(x, n) std::rotl(static_cast(x), static_cast(n)) +#endif +#ifndef __builtin_rotateleft64 +#define __builtin_rotateleft64(x, n) std::rotl(static_cast(x), static_cast(n)) +#endif +#ifndef __builtin_debugtrap +#if defined(__x86_64__) || defined(__i386__) +#define __builtin_debugtrap() __asm__ __volatile__("int3") +#else +#define __builtin_debugtrap() __builtin_trap() +#endif +#endif +#endif + +#if REX_COMPILER_MSVC +#define _REXPACKEDSCOPE(body) __pragma(pack(push, 1)) body __pragma(pack(pop)); +#else +#define _REXPACKEDSCOPE(body) \ + _Pragma("pack(push, 1)") body; \ + _Pragma("pack(pop)"); +#endif // REX_COMPILER_MSVC + +#define REXPACKEDSTRUCT(name, value) _REXPACKEDSCOPE(struct name value) +#define REXPACKEDSTRUCTANONYMOUS(value) _REXPACKEDSCOPE(struct value) +#define REXPACKEDUNION(name, value) _REXPACKEDSCOPE(union name value) + +// Compiler capability macros +#if REX_COMPILER_CLANG || REX_COMPILER_GNUC +#define REX_HAS_BUILTIN_STRLEN 1 +#define REX_LACKS_FLOAT_FROM_CHARS 1 +#else +#define REX_HAS_BUILTIN_STRLEN 0 +#define REX_LACKS_FLOAT_FROM_CHARS 0 +#endif + +namespace rex { + +#if REX_PLATFORM_WIN32 +const char kPathSeparator = '\\'; +#else +const char kPathSeparator = '/'; +#endif // REX_PLATFORM_WIN32 + +const char kGuestPathSeparator = '\\'; + +} // namespace rex diff --git a/include/rex/platform/dynlib.h b/include/rex/platform/dynlib.h new file mode 100644 index 0000000..c30ae1c --- /dev/null +++ b/include/rex/platform/dynlib.h @@ -0,0 +1,65 @@ +/** + * @file platform/dynlib.h + * @brief Platform-agnostic dynamic library loading + */ +#pragma once + +#include +#include + +#include + +namespace rex::platform { + +class DynamicLibrary { + public: + DynamicLibrary() = default; + ~DynamicLibrary(); + + DynamicLibrary(const DynamicLibrary&) = delete; + DynamicLibrary& operator=(const DynamicLibrary&) = delete; + DynamicLibrary(DynamicLibrary&& other) noexcept; + DynamicLibrary& operator=(DynamicLibrary&& other) noexcept; + + bool Load(const std::filesystem::path& path); + void Close(); + explicit operator bool() const { return handle_ != nullptr; } + + void* GetRawSymbol(const char* name) const; + + template + T GetSymbol(const char* name) const { + return reinterpret_cast(GetRawSymbol(name)); + } + + private: + void* handle_ = nullptr; +}; + +namespace lib_names { + +#if REX_PLATFORM_WIN32 + +inline constexpr const char* kVulkanLoader = "vulkan-1.dll"; +inline constexpr const char* kRenderDoc = "renderdoc.dll"; +inline constexpr const char* kSpirvToolsSdkPath = "Bin/SPIRV-Tools-shared.dll"; + +#elif REX_PLATFORM_ANDROID + +inline constexpr const char* kVulkanLoader = "libvulkan.so"; +inline constexpr const char* kRenderDoc = "libVkLayer_GLES_RenderDoc.so"; +inline constexpr const char* kSpirvToolsSdkPath = "bin/libSPIRV-Tools-shared.so"; + +#elif REX_PLATFORM_LINUX + +inline constexpr const char* kVulkanLoader = "libvulkan.so.1"; +inline constexpr const char* kRenderDoc = "librenderdoc.so"; +inline constexpr const char* kSpirvToolsSdkPath = "bin/libSPIRV-Tools-shared.so"; + +#else +#error No library names provided for the target platform. +#endif + +} // namespace lib_names + +} // namespace rex::platform diff --git a/include/rex/platform/exceptions.h b/include/rex/platform/exceptions.h new file mode 100644 index 0000000..1614b4d --- /dev/null +++ b/include/rex/platform/exceptions.h @@ -0,0 +1,151 @@ +/** + * @file platform/exceptions.h + * @brief Structured Exception Handling (SEH) support for recompiled code + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + * + * @remarks Provides cross-platform SEH support for recompiled PPC code. + * On Windows, uses native __try/__except (works with MSVC and Clang-cl). + * On Linux, uses signal handlers for SIGSEGV/SIGBUS. + * + * @usage 1. Call rex::initialize_seh() at startup + * 2. Generated code wraps SEH scopes with try/catch blocks + * 3. Hardware exceptions (null deref, access violation) throw SehException + * 4. Catch blocks call finally handlers and rethrow + */ + +#pragma once + +#include +#include + +#include +#include +#include + +namespace rex { + +//============================================================================= +// SEH Exception Type +//============================================================================= + +/** + * @brief Exception thrown when hardware exception occurs in SEH-protected code + */ +class SehException : public std::exception { + public: + /// Exception codes matching Windows EXCEPTION_* values + enum Code : u32 { + ACCESS_VIOLATION = 0xC0000005, + IN_PAGE_ERROR = 0xC0000006, + ILLEGAL_INSTRUCTION = 0xC000001D, + STACK_OVERFLOW = 0xC00000FD, + FLOAT_DIVIDE_BY_ZERO = 0xC000008E, + INTEGER_DIVIDE_BY_ZERO = 0xC0000094, + UNKNOWN = 0xFFFFFFFF + }; + + explicit SehException(Code code, uintptr_t address = 0) : code_(code), address_(address) {} + + const char* what() const noexcept override { + switch (code_) { + case ACCESS_VIOLATION: + return "SEH: Access Violation"; + case IN_PAGE_ERROR: + return "SEH: In-Page Error"; + case ILLEGAL_INSTRUCTION: + return "SEH: Illegal Instruction"; + case STACK_OVERFLOW: + return "SEH: Stack Overflow"; + case FLOAT_DIVIDE_BY_ZERO: + return "SEH: Float Divide by Zero"; + case INTEGER_DIVIDE_BY_ZERO: + return "SEH: Integer Divide by Zero"; + default: + return "SEH: Unknown Exception"; + } + } + + Code code() const noexcept { return code_; } + uintptr_t address() const noexcept { return address_; } + + private: + Code code_; + uintptr_t address_; +}; + +//============================================================================= +// Initialization +//============================================================================= + +inline void initialize_seh_thread() { + platform::seh_active() = false; +} + +inline void initialize_seh() { + platform::seh_initialize(); +} + +//============================================================================= +// SEH Guard Scope and Macros +//============================================================================= + +#if REX_PLATFORM_WIN32 + +class SehGuard { + public: + SehGuard() = default; + ~SehGuard() = default; + SehGuard(const SehGuard&) = delete; + SehGuard& operator=(const SehGuard&) = delete; +}; + +#define SEH_TRY __try { +#define SEH_CATCH \ + } \ + __except (::rex::platform::seh_filter(GetExceptionCode(), GetExceptionInformation())) { +#define SEH_CATCH_ALL \ + } \ + __except (::rex::platform::seh_filter(GetExceptionCode(), GetExceptionInformation())) { +#define SEH_RETHROW ::rex::platform::seh_rethrow() + +#define SEH_END } + +#else // !REX_PLATFORM_WIN32 + +class SehGuard { + public: + SehGuard() { + was_active_ = platform::seh_active(); + platform::seh_active() = true; + } + + ~SehGuard() { platform::seh_active() = was_active_; } + + SehGuard(const SehGuard&) = delete; + SehGuard& operator=(const SehGuard&) = delete; + + private: + bool was_active_ = false; +}; + +#define SEH_TRY \ + { \ + ::rex::SehGuard __seh_guard; \ + try + +#define SEH_CATCH catch (const ::rex::SehException&) + +#define SEH_CATCH_ALL catch (...) + +#define SEH_RETHROW throw + +#define SEH_END } + +#endif // REX_PLATFORM_WIN32 + +} // namespace rex diff --git a/include/rex/platform/fpscr.h b/include/rex/platform/fpscr.h new file mode 100644 index 0000000..c2c4fd4 --- /dev/null +++ b/include/rex/platform/fpscr.h @@ -0,0 +1,89 @@ +/** + * @file platform/fpscr.h + * @brief Platform-specific FPSCR constants and intrinsics + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include + +#include + +#include + +// SSE3 constants are missing from simde +#ifndef _MM_DENORMALS_ZERO_MASK +#define _MM_DENORMALS_ZERO_MASK 0x0040 +#endif + +namespace rex::platform { + +// simde does not handle denormal flags, so we need to implement per-arch. +#if defined(__x86_64__) || defined(_M_X64) + +struct FPSCRPlatform { + static constexpr size_t RoundShift = 13; + static constexpr size_t RoundMaskVal = SIMDE_MM_ROUND_MASK; + static constexpr size_t FlushMask = SIMDE_MM_FLUSH_ZERO_MASK | _MM_DENORMALS_ZERO_MASK; + // Exception mask bits (1 = exception masked/disabled) + static constexpr u32 ExceptionMask = (1 << 7) | // IM - Invalid operation + (1 << 8) | // DM - Denormal operand + (1 << 9) | // ZM - Zero divide + (1 << 10) | // OM - Overflow + (1 << 11) | // UM - Underflow + (1 << 12); // PM - Precision (Inexact) + static constexpr size_t GuestToHost[] = {SIMDE_MM_ROUND_NEAREST, SIMDE_MM_ROUND_TOWARD_ZERO, + SIMDE_MM_ROUND_UP, SIMDE_MM_ROUND_DOWN}; + + static inline u32 getcsr() noexcept { return simde_mm_getcsr(); } + + static inline void setcsr(u32 csr) noexcept { simde_mm_setcsr(csr); } + + static inline void InitHostExceptions(u32& csr) noexcept { + csr |= ExceptionMask; // Set mask bits to disable exceptions + } +}; + +#elif defined(__aarch64__) || defined(_M_ARM64) + +struct FPSCRPlatform { + // RMode + static constexpr size_t RoundShift = 22; + static constexpr size_t RoundMaskVal = 3 << RoundShift; + // FZ and FZ16 + static constexpr size_t FlushMask = (1 << 19) | (1 << 24); + // Nearest, Zero, -Infinity, -Infinity + static constexpr size_t GuestToHost[] = {0 << RoundShift, 3 << RoundShift, 1 << RoundShift, + 2 << RoundShift}; + // Exception enable bits (0 = exception disabled, ARM defaults to 0) + static constexpr u32 ExceptionMask = (1 << 8) | // IOE - Invalid Operation + (1 << 9) | // DZE - Division by Zero + (1 << 10) | // OFE - Overflow + (1 << 11) | // UFE - Underflow + (1 << 12) | // IXE - Inexact + (1 << 15); // IDE - Input Denormal + + static inline u32 getcsr() noexcept { + u64 csr; + __asm__ __volatile__("mrs %0, fpcr" : "=r"(csr)); + return csr; + } + + static inline void setcsr(u32 csr) noexcept { __asm__ __volatile__("msr fpcr, %0" : : "r"(csr)); } + + static inline void InitHostExceptions(u32& csr) noexcept { + csr &= ~ExceptionMask; // Clear enable bits to disable exceptions + } +}; + +#else +#error "Missing implementation for FPSCR." +#endif + +} // namespace rex::platform diff --git a/include/rex/platform/seh.h b/include/rex/platform/seh.h new file mode 100644 index 0000000..3b8f739 --- /dev/null +++ b/include/rex/platform/seh.h @@ -0,0 +1,46 @@ +/** + * @file platform/seh.h + * @brief Platform-specific SEH implementation details + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#pragma once + +#include +#include + +#include + +namespace rex { +class SehException; +} + +namespace rex::platform { + +inline std::atomic g_seh_initialized{false}; + +/// Thread-local SEH state for capturing exception info. +struct SehThreadState { + u32 code = 0; + uintptr_t info[2] = {0, 0}; +}; + +/// Get the thread-local SEH state. +SehThreadState& seh_thread_state(); + +/// SEH filter function - captures exception info and determines whether to handle. +/// Returns non-zero if the exception should be handled. +int seh_filter(u32 code, void* exception_pointers); + +/// Re-raise the captured exception. +[[noreturn]] void seh_rethrow(); + +/// Initialize SEH signal handlers (POSIX only, no-op on Windows). +void seh_initialize(); + +/// Thread-local flag for POSIX: true when in SEH-protected code. +bool& seh_active(); + +} // namespace rex::platform diff --git a/include/rex/ppc.h b/include/rex/ppc.h new file mode 100644 index 0000000..63c5ab5 --- /dev/null +++ b/include/rex/ppc.h @@ -0,0 +1,27 @@ +/** + * @file ppc.h + * @brief PPC recompilation support -- umbrella header + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include + +#include +#include +#include +#include + +// Consumer-facing using declarations +using rex::ppc::FindPPCFuncByName; +using rex::ppc::GetPPCFuncRegistry; +using rex::ppc::GuestToHostFunction; +using rex::ppc::HostToGuestFunction; +using rex::ppc::ImportFunction; diff --git a/include/rex/ppc/context.h b/include/rex/ppc/context.h new file mode 100644 index 0000000..321fab3 --- /dev/null +++ b/include/rex/ppc/context.h @@ -0,0 +1,533 @@ +/** + * @file ppc/context.h + * @brief PPC thread context, guest function macros, and interrupt handling + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + * + * @remarks Based on XenonRecomp/UnleashedRecomp PPCContext infrastructure + */ + +#pragma once + +#include +#include +#include + +#include +#include + +#include +#include +#include + +//============================================================================= +// PPCFunc Type Definition +//============================================================================= +// Function signature for recompiled PPC functions. +// All recompiled functions take a context reference and memory base pointer. + +// Forward declaration of the PPC execution context +struct PPCContext; + +// Function signature for recompiled PPC functions +using PPCFunc = void(PPCContext& ctx, uint8_t* base); + +namespace rex::runtime { +PPCFunc* ResolveIndirectFunction(uint32_t guest_address); +} // namespace rex::runtime + +//============================================================================= +// PPC Function Macros +//============================================================================= + +#define REX_JOIN(x, y) x##y +#define REX_XSTRINGIFY(x) #x +#define REX_STRINGIFY(x) REX_XSTRINGIFY(x) +#define REX_FUNC(x) void x([[maybe_unused]] PPCContext& __restrict ctx, uint8_t* base) +#define REX_EXTERN(x) extern "C" REX_FUNC(x) +#define REX_WEAK_FUNC(x) __attribute__((weak, noinline)) REX_FUNC(x) + +//============================================================================= +// Function Mapping +//============================================================================= + +struct PPCFuncMapping { + size_t guest; + PPCFunc* host; +}; + +extern PPCFuncMapping PPCFuncMappings[]; + +//============================================================================= +// Pack/Unpack Constants (NORMPACKED32 - 2:10:10:10 format) +//============================================================================= + +constexpr float kPack2101010_Min10 = std::bit_cast(0x403FFE01u); +constexpr float kPack2101010_Max10 = std::bit_cast(0x404001FFu); +constexpr float kPack2101010_Min2 = std::bit_cast(0x40400000u); +constexpr float kPack2101010_Max2 = std::bit_cast(0x40400003u); + +namespace rex::ppc { + +//============================================================================= +// General Purpose Register +//============================================================================= + +union Register { + int8_t s8; + uint8_t u8; + int16_t s16; + uint16_t u16; + int32_t s32; + uint32_t u32; + int64_t s64; + uint64_t u64; + float f32; + double f64; +}; + +//============================================================================= +// Fixed-Point Exception Register (XER) +//============================================================================= + +struct XERRegister { + uint8_t so; + uint8_t ov; + uint8_t ca; +}; + +//============================================================================= +// Condition Register (CR) Field +//============================================================================= + +struct CRRegister { + uint8_t lt; + uint8_t gt; + uint8_t eq; + union { + uint8_t so; + uint8_t un; + }; + + inline uint32_t raw() const noexcept { return (lt << 3) | (gt << 2) | (eq << 1) | so; } + + inline void set_raw(uint32_t value) noexcept { + lt = (value >> 3) & 1; + gt = (value >> 2) & 1; + eq = (value >> 1) & 1; + so = value & 1; + } + + template + inline void compare(T left, T right, const XERRegister& xer) noexcept { + lt = left < right; + gt = left > right; + eq = left == right; + so = xer.so; + } + + inline void compare(double left, double right) noexcept { + un = __builtin_isnan(left) || __builtin_isnan(right); + lt = !un && (left < right); + gt = !un && (left > right); + eq = !un && (left == right); + } + + inline void setFromMask(simde__m128 mask, int imm) noexcept { + int m = simde_mm_movemask_ps(mask); + lt = m == imm; + gt = 0; + eq = m == 0; + so = 0; + } + + inline void setFromMask(simde__m128i mask, int imm) noexcept { + int m = simde_mm_movemask_epi8(mask); + lt = m == imm; + gt = 0; + eq = m == 0; + so = 0; + } +}; + +//============================================================================= +// Vector Register (128-bit) +//============================================================================= + +union alignas(0x10) VRegister { + int8_t s8[16]; + uint8_t u8[16]; + int16_t s16[8]; + uint16_t u16[8]; + int32_t s32[4]; + uint32_t u32[4]; + int64_t s64[2]; + uint64_t u64[2]; + float f32[4]; + double f64[2]; +}; + +//============================================================================= +// Floating-Point Status and Control Register (FPSCR) +//============================================================================= + +constexpr uint32_t kRoundNearest = 0x00; +constexpr uint32_t kRoundTowardZero = 0x01; +constexpr uint32_t kRoundUp = 0x02; +constexpr uint32_t kRoundDown = 0x03; +constexpr uint32_t kRoundMask = 0x03; + +struct FPSCRRegister { + uint32_t csr; + + static constexpr size_t HostToGuest[] = {kRoundNearest, kRoundDown, kRoundUp, kRoundTowardZero}; + + using Platform = platform::FPSCRPlatform; + static constexpr size_t RoundShift = Platform::RoundShift; + static constexpr size_t RoundMaskVal = Platform::RoundMaskVal; + static constexpr size_t FlushMask = Platform::FlushMask; + + inline uint32_t getcsr() noexcept { return Platform::getcsr(); } + inline void setcsr(uint32_t csr) noexcept { Platform::setcsr(csr); } + + inline uint32_t loadFromHost() noexcept { + csr = getcsr(); + return HostToGuest[(csr & RoundMaskVal) >> RoundShift]; + } + + inline void storeFromGuest(uint32_t value) noexcept { + csr &= ~RoundMaskVal; + csr |= Platform::GuestToHost[value & kRoundMask]; + setcsr(csr); + } + + inline void enableFlushModeUnconditional() noexcept { + csr |= FlushMask; + setcsr(csr); + } + + inline void disableFlushModeUnconditional() noexcept { + csr &= ~FlushMask; + setcsr(csr); + } + + inline void enableFlushMode() noexcept { + if ((csr & FlushMask) != FlushMask) [[unlikely]] { + csr |= FlushMask; + setcsr(csr); + } + } + + inline void disableFlushMode() noexcept { + if ((csr & FlushMask) != 0) [[unlikely]] { + csr &= ~FlushMask; + setcsr(csr); + } + } + + inline void InitHost() noexcept { + csr = getcsr(); + Platform::InitHostExceptions(csr); + setcsr(csr); + } +}; + +} // namespace rex::ppc + +using PPCRegister = rex::ppc::Register; +using PPCXERRegister = rex::ppc::XERRegister; +using PPCCRRegister = rex::ppc::CRRegister; +using PPCVRegister = rex::ppc::VRegister; +using PPCFPSCRRegister = rex::ppc::FPSCRRegister; + +//============================================================================= +// PPCContext Structure +//============================================================================= + +struct alignas(0x40) PPCContext { + PPCRegister r3; +#if !defined(REX_CONFIG_NON_ARGUMENT_AS_LOCAL) + PPCRegister r0; +#endif + PPCRegister r1; +#if !defined(REX_CONFIG_NON_ARGUMENT_AS_LOCAL) + PPCRegister r2; +#endif + PPCRegister r4; + PPCRegister r5; + PPCRegister r6; + PPCRegister r7; + PPCRegister r8; + PPCRegister r9; + PPCRegister r10; +#if !defined(REX_CONFIG_NON_ARGUMENT_AS_LOCAL) + PPCRegister r11; + PPCRegister r12; +#endif + PPCRegister r13; +#if !defined(REX_CONFIG_NON_VOLATILE_AS_LOCAL) + PPCRegister r14; + PPCRegister r15; + PPCRegister r16; + PPCRegister r17; + PPCRegister r18; + PPCRegister r19; + PPCRegister r20; + PPCRegister r21; + PPCRegister r22; + PPCRegister r23; + PPCRegister r24; + PPCRegister r25; + PPCRegister r26; + PPCRegister r27; + PPCRegister r28; + PPCRegister r29; + PPCRegister r30; + PPCRegister r31; +#endif + +#if !defined(REX_CONFIG_SKIP_LR) + uint64_t lr; +#endif +#if !defined(REX_CONFIG_CTR_AS_LOCAL) + PPCRegister ctr; +#endif +#if !defined(REX_CONFIG_XER_AS_LOCAL) + PPCXERRegister xer; +#endif +#if !defined(REX_CONFIG_RESERVED_AS_LOCAL) + PPCRegister reserved; +#endif +#if !defined(REX_CONFIG_SKIP_MSR) + uint32_t msr = 0x200A000; +#endif +#if !defined(REX_CONFIG_CR_AS_LOCAL) + PPCCRRegister cr0; + PPCCRRegister cr1; + PPCCRRegister cr2; + PPCCRRegister cr3; + PPCCRRegister cr4; + PPCCRRegister cr5; + PPCCRRegister cr6; + PPCCRRegister cr7; +#endif + PPCFPSCRRegister fpscr; + uint8_t vscr_sat = 0; // VSCR saturation flag (for vector ops) + + /** + * Last indirect call target address. Set by REX_CALL_INDIRECT_FUNC before + * dispatch. Used by the invalid-function trap to report the faulting address. + * Unconditional (not guarded by config flags) because ctr may be optimized + * to a local variable via REX_CONFIG_CTR_AS_LOCAL. + */ + uint32_t last_indirect_target = 0; + +#if !defined(REX_CONFIG_NON_ARGUMENT_AS_LOCAL) + PPCRegister f0; +#endif + PPCRegister f1; + PPCRegister f2; + PPCRegister f3; + PPCRegister f4; + PPCRegister f5; + PPCRegister f6; + PPCRegister f7; + PPCRegister f8; + PPCRegister f9; + PPCRegister f10; + PPCRegister f11; + PPCRegister f12; + PPCRegister f13; +#if !defined(REX_CONFIG_NON_VOLATILE_AS_LOCAL) + PPCRegister f14; + PPCRegister f15; + PPCRegister f16; + PPCRegister f17; + PPCRegister f18; + PPCRegister f19; + PPCRegister f20; + PPCRegister f21; + PPCRegister f22; + PPCRegister f23; + PPCRegister f24; + PPCRegister f25; + PPCRegister f26; + PPCRegister f27; + PPCRegister f28; + PPCRegister f29; + PPCRegister f30; + PPCRegister f31; +#endif + + PPCVRegister v0; + PPCVRegister v1; + PPCVRegister v2; + PPCVRegister v3; + PPCVRegister v4; + PPCVRegister v5; + PPCVRegister v6; + PPCVRegister v7; + PPCVRegister v8; + PPCVRegister v9; + PPCVRegister v10; + PPCVRegister v11; + PPCVRegister v12; + PPCVRegister v13; +#if !defined(REX_CONFIG_NON_VOLATILE_AS_LOCAL) + PPCVRegister v14; + PPCVRegister v15; + PPCVRegister v16; + PPCVRegister v17; + PPCVRegister v18; + PPCVRegister v19; + PPCVRegister v20; + PPCVRegister v21; + PPCVRegister v22; + PPCVRegister v23; + PPCVRegister v24; + PPCVRegister v25; + PPCVRegister v26; + PPCVRegister v27; + PPCVRegister v28; + PPCVRegister v29; + PPCVRegister v30; + PPCVRegister v31; +#endif +#if !defined(REX_CONFIG_NON_ARGUMENT_AS_LOCAL) + PPCVRegister v32; + PPCVRegister v33; + PPCVRegister v34; + PPCVRegister v35; + PPCVRegister v36; + PPCVRegister v37; + PPCVRegister v38; + PPCVRegister v39; + PPCVRegister v40; + PPCVRegister v41; + PPCVRegister v42; + PPCVRegister v43; + PPCVRegister v44; + PPCVRegister v45; + PPCVRegister v46; + PPCVRegister v47; + PPCVRegister v48; + PPCVRegister v49; + PPCVRegister v50; + PPCVRegister v51; + PPCVRegister v52; + PPCVRegister v53; + PPCVRegister v54; + PPCVRegister v55; + PPCVRegister v56; + PPCVRegister v57; + PPCVRegister v58; + PPCVRegister v59; + PPCVRegister v60; + PPCVRegister v61; + PPCVRegister v62; + PPCVRegister v63; +#endif +#if !defined(REX_CONFIG_NON_VOLATILE_AS_LOCAL) + PPCVRegister v64; + PPCVRegister v65; + PPCVRegister v66; + PPCVRegister v67; + PPCVRegister v68; + PPCVRegister v69; + PPCVRegister v70; + PPCVRegister v71; + PPCVRegister v72; + PPCVRegister v73; + PPCVRegister v74; + PPCVRegister v75; + PPCVRegister v76; + PPCVRegister v77; + PPCVRegister v78; + PPCVRegister v79; + PPCVRegister v80; + PPCVRegister v81; + PPCVRegister v82; + PPCVRegister v83; + PPCVRegister v84; + PPCVRegister v85; + PPCVRegister v86; + PPCVRegister v87; + PPCVRegister v88; + PPCVRegister v89; + PPCVRegister v90; + PPCVRegister v91; + PPCVRegister v92; + PPCVRegister v93; + PPCVRegister v94; + PPCVRegister v95; + PPCVRegister v96; + PPCVRegister v97; + PPCVRegister v98; + PPCVRegister v99; + PPCVRegister v100; + PPCVRegister v101; + PPCVRegister v102; + PPCVRegister v103; + PPCVRegister v104; + PPCVRegister v105; + PPCVRegister v106; + PPCVRegister v107; + PPCVRegister v108; + PPCVRegister v109; + PPCVRegister v110; + PPCVRegister v111; + PPCVRegister v112; + PPCVRegister v113; + PPCVRegister v114; + PPCVRegister v115; + PPCVRegister v116; + PPCVRegister v117; + PPCVRegister v118; + PPCVRegister v119; + PPCVRegister v120; + PPCVRegister v121; + PPCVRegister v122; + PPCVRegister v123; + PPCVRegister v124; + PPCVRegister v125; + PPCVRegister v126; + PPCVRegister v127; +#endif + +#if !defined(REX_CONFIG_NON_VOLATILE_AS_LOCAL) + //--- Non-volatile register save/restore -------- + // Layout: r14-r31 (144) | f14-f31 (144) | v14-v31 (288) | v64-v127 (1024) + // Total: 1600 bytes. Buffer must be at least this large. + static constexpr size_t kNonVolatileSaveSize = + 18 * sizeof(PPCRegister) + 18 * sizeof(PPCRegister) + 18 * sizeof(PPCVRegister) + + 64 * sizeof(PPCVRegister); + + inline void SaveNonVolatiles(uint8_t* dst) const { + std::memcpy(dst, &r14, 18 * sizeof(PPCRegister)); + dst += 18 * sizeof(PPCRegister); + std::memcpy(dst, &f14, 18 * sizeof(PPCRegister)); + dst += 18 * sizeof(PPCRegister); + std::memcpy(dst, &v14, 18 * sizeof(PPCVRegister)); + dst += 18 * sizeof(PPCVRegister); + std::memcpy(dst, &v64, 64 * sizeof(PPCVRegister)); + } + + inline void RestoreNonVolatiles(const uint8_t* src) { + std::memcpy(&r14, src, 18 * sizeof(PPCRegister)); + src += 18 * sizeof(PPCRegister); + std::memcpy(&f14, src, 18 * sizeof(PPCRegister)); + src += 18 * sizeof(PPCRegister); + std::memcpy(&v14, src, 18 * sizeof(PPCVRegister)); + src += 18 * sizeof(PPCVRegister); + std::memcpy(&v64, src, 64 * sizeof(PPCVRegister)); + } +#else + static constexpr size_t kNonVolatileSaveSize = 0; + inline void SaveNonVolatiles(uint8_t*) const {} + inline void RestoreNonVolatiles(const uint8_t*) {} +#endif +}; diff --git a/include/rex/ppc/function.h b/include/rex/ppc/function.h new file mode 100644 index 0000000..611a52f --- /dev/null +++ b/include/rex/ppc/function.h @@ -0,0 +1,497 @@ +/** + * @file ppc/function.h + * @brief PPC calling convention translation, host/PPC wrappers, and hooks + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + * + * @remarks Based on XenonRecomp/UnleashedRecomp translation wrappers + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace rex::ppc { + +//============================================================================= +// Global PPC Function Registry (for runtime ordinal lookup) +//============================================================================= +// Populated by static constructors from XAM_EXPORT / XBOXKRNL_EXPORT macros. + +inline std::vector>& GetPPCFuncRegistry() { + static std::vector> registry; + return registry; +} + +inline PPCFunc* FindPPCFuncByName(const char* name) { + for (auto& [n, f] : GetPPCFuncRegistry()) { + if (std::strcmp(n, name) == 0) + return f; + } + return nullptr; +} + +namespace detail { +struct PPCFuncRegistrar { + PPCFuncRegistrar(const char* name, PPCFunc* func) { + GetPPCFuncRegistry().emplace_back(name, func); + } +}; +} // namespace detail + +//============================================================================= +// Type Traits (additional, types.h has is_be_type) +//============================================================================= + +// Function argument helpers +template +constexpr std::tuple function_args(R (*)(T...)) noexcept { + return std::tuple(); +} + +template +static constexpr decltype(V) constant_v = V; + +template +static constexpr bool is_precise_v = std::is_same_v || std::is_same_v; + +//============================================================================= +// Concepts for Type Constraints +//============================================================================= + +template +concept BigEndianType = is_be_type_v; + +template +concept MappedPtrType = is_mapped_ptr_v; + +template +concept PreciseType = is_precise_v; + +// A "plain" type: not a pointer, not be, not MappedPtr +template +concept PlainType = !std::is_pointer_v && !BigEndianType && !MappedPtrType; + +template +struct arg_count_t { + static constexpr size_t value = std::tuple_size_v; +}; + +//============================================================================= +// Argument Translator +//============================================================================= + +struct ArgTranslator { + // Get integer argument value from register or stack + static constexpr uint64_t GetIntegerArgumentValue(const PPCContext& ctx, uint8_t* base, + size_t arg) noexcept { + if (arg <= 7) { + switch (arg) { + case 0: + return ctx.r3.u32; + case 1: + return ctx.r4.u32; + case 2: + return ctx.r5.u32; + case 3: + return ctx.r6.u32; + case 4: + return ctx.r7.u32; + case 5: + return ctx.r8.u32; + case 6: + return ctx.r9.u32; + case 7: + return ctx.r10.u32; + default: + break; + } + } + // Stack arguments at r1 + 0x54 + ((arg - 8) * 8) + return __builtin_bswap32( + *rex::memory::GuestPtr(base, ctx.r1.u32 + 0x54 + ((arg - 8) * 8))); + } + + // Get float/double argument value from FPR + static double GetPrecisionArgumentValue(const PPCContext& ctx, [[maybe_unused]] uint8_t* base, + size_t arg) noexcept { + switch (arg) { + case 0: + return ctx.f1.f64; + case 1: + return ctx.f2.f64; + case 2: + return ctx.f3.f64; + case 3: + return ctx.f4.f64; + case 4: + return ctx.f5.f64; + case 5: + return ctx.f6.f64; + case 6: + return ctx.f7.f64; + case 7: + return ctx.f8.f64; + case 8: + return ctx.f9.f64; + case 9: + return ctx.f10.f64; + case 10: + return ctx.f11.f64; + case 11: + return ctx.f12.f64; + case 12: + return ctx.f13.f64; + [[unlikely]] default: + break; + } + return 0; + } + + // Set integer argument value + static constexpr void SetIntegerArgumentValue(PPCContext& ctx, uint8_t* base, size_t arg, + uint64_t value) noexcept { + if (arg <= 7) { + switch (arg) { + case 0: + ctx.r3.u64 = value; + return; + case 1: + ctx.r4.u64 = value; + return; + case 2: + ctx.r5.u64 = value; + return; + case 3: + ctx.r6.u64 = value; + return; + case 4: + ctx.r7.u64 = value; + return; + case 5: + ctx.r8.u64 = value; + return; + case 6: + ctx.r9.u64 = value; + return; + case 7: + ctx.r10.u64 = value; + return; + [[unlikely]] default: + break; + } + } + // Stack-passed arguments (mirrors GetIntegerArgumentValue layout) + *rex::memory::GuestPtr(base, ctx.r1.u32 + 0x54 + ((arg - 8) * 8)) = + __builtin_bswap32(static_cast(value)); + } + + // Set float/double argument value + static void SetPrecisionArgumentValue(PPCContext& ctx, [[maybe_unused]] uint8_t* base, size_t arg, + double value) noexcept { + switch (arg) { + case 0: + ctx.f1.f64 = value; + return; + case 1: + ctx.f2.f64 = value; + return; + case 2: + ctx.f3.f64 = value; + return; + case 3: + ctx.f4.f64 = value; + return; + case 4: + ctx.f5.f64 = value; + return; + case 5: + ctx.f6.f64 = value; + return; + case 6: + ctx.f7.f64 = value; + return; + case 7: + ctx.f8.f64 = value; + return; + case 8: + ctx.f9.f64 = value; + return; + case 9: + ctx.f10.f64 = value; + return; + case 10: + ctx.f11.f64 = value; + return; + case 11: + ctx.f12.f64 = value; + return; + case 12: + ctx.f13.f64 = value; + return; + [[unlikely]] default: + break; + } + } + + // Get typed value (be types) + template + static constexpr T GetValue(PPCContext& ctx, uint8_t* base, size_t idx) noexcept { + T result; + result.value = static_cast(GetIntegerArgumentValue(ctx, base, idx)); + return result; + } + + // Get typed value (MappedPtr) + template + static T GetValue(PPCContext& ctx, uint8_t* base, size_t idx) noexcept { + using inner_t = typename mapped_ptr_inner_type::type; + const auto v = GetIntegerArgumentValue(ctx, base, idx); + if (!v) { + return T(nullptr); + } + uint32_t guest_addr = static_cast(v); + inner_t* host_ptr = rex::memory::GuestPtr(base, guest_addr); + return T(host_ptr, guest_addr); + } + + // Get typed value (non-pointer, non-be, non-MappedPtr) + template + static constexpr T GetValue(PPCContext& ctx, uint8_t* base, size_t idx) noexcept { + if constexpr (is_precise_v) { + return static_cast(GetPrecisionArgumentValue(ctx, base, idx)); + } else { + return static_cast(GetIntegerArgumentValue(ctx, base, idx)); + } + } + + // Get typed value (pointer - translates guest address to host pointer) + template + requires std::is_pointer_v + static constexpr T GetValue(PPCContext& ctx, uint8_t* base, size_t idx) noexcept { + const auto v = GetIntegerArgumentValue(ctx, base, idx); + if (!v) { + return nullptr; + } + uint32_t guest_addr = static_cast(v); + return rex::memory::GuestPtr(base, guest_addr); + } + + // Set typed value + template + static constexpr void SetValue(PPCContext& ctx, uint8_t* base, size_t idx, T value) noexcept { + if constexpr (is_precise_v) { + SetPrecisionArgumentValue(ctx, base, idx, value); + } else if constexpr (std::is_null_pointer_v) { + SetIntegerArgumentValue(ctx, base, idx, 0); + } else if constexpr (std::is_pointer_v) { + SetIntegerArgumentValue(ctx, base, idx, + static_cast(reinterpret_cast(value) - + reinterpret_cast(base))); + } else { + SetIntegerArgumentValue(ctx, base, idx, value); + } + } +}; + +//============================================================================= +// Argument Gathering +//============================================================================= + +struct Argument { + int type{}; // 0 = integer, 1 = float + int ordinal{}; // Position in integer or float argument list +}; + +// Helper to detect precise types +template +constexpr bool is_precise_type() { + return is_precise_v; +} + +// Type-only gather helper - doesn't require constexpr-constructible types +template +constexpr std::array GatherFunctionArgumentsFromTypes() { + std::array args{}; + if constexpr (sizeof...(Args) > 0) { + int floatOrdinal{}; + int intOrdinal{}; + size_t i{}; + ( + [&]() { + if constexpr (is_precise_type()) { + args[i] = {1, floatOrdinal++}; + } else { + args[i] = {0, intOrdinal++}; + } + i++; + }.template operator()(), + ...); + } + return args; +} + +// Helper to extract args tuple types and call GatherFunctionArgumentsFromTypes +template +constexpr auto GatherFromSignature(R (*)(Args...)) { + return GatherFunctionArgumentsFromTypes(); +} + +template +constexpr auto GatherFunctionArguments() { + return GatherFromSignature(Func); +} + +template +struct arg_ordinal_t { + static constexpr size_t value = GatherFunctionArguments()[I].ordinal; +}; + +//============================================================================= +// Argument Translation +//============================================================================= + +template + requires(I >= sizeof...(TArgs)) +void _translate_args_to_host([[maybe_unused]] PPCContext& ctx, [[maybe_unused]] uint8_t* base, + [[maybe_unused]] std::tuple&) noexcept {} + +template + requires(I < sizeof...(TArgs)) +void _translate_args_to_host(PPCContext& ctx, uint8_t* base, std::tuple& tpl) noexcept { + using T = std::tuple_element_t>; + std::get(tpl) = ArgTranslator::GetValue(ctx, base, arg_ordinal_t::value); + _translate_args_to_host(ctx, base, tpl); +} + +template + requires(I >= sizeof...(TArgs)) +void _translate_args_to_guest([[maybe_unused]] PPCContext& ctx, [[maybe_unused]] uint8_t* base, + [[maybe_unused]] std::tuple&) noexcept {} + +template + requires(I < sizeof...(TArgs)) +void _translate_args_to_guest(PPCContext& ctx, uint8_t* base, std::tuple& tpl) noexcept { + using T = std::tuple_element_t>; + ArgTranslator::SetValue(ctx, base, GatherFunctionArgumentsFromTypes()[I].ordinal, + std::get(tpl)); + _translate_args_to_guest(ctx, base, tpl); +} + +//============================================================================= +// Host To PPC Function Wrapper +//============================================================================= +// Calls a native C++ function with arguments extracted from PPC context + +template +__attribute__((noinline)) void HostToGuestFunction(PPCContext& ctx, uint8_t* base) { + using ret_t = decltype(std::apply(Func, function_args(Func))); + + auto args = function_args(Func); + _translate_args_to_host(ctx, base, args); + + if constexpr (std::is_same_v) { + std::apply(Func, args); + } else { + auto v = std::apply(Func, args); + + // Memory barrier to ensure compiler doesn't reorder + asm volatile("" ::: "memory"); + + if constexpr (std::is_pointer()) { + if (v != nullptr) { + ctx.r3.u64 = + static_cast(reinterpret_cast(v) - reinterpret_cast(base)); + } else { + ctx.r3.u64 = 0; + } + } else if constexpr (is_precise_v) { + ctx.f1.f64 = v; + } else { + ctx.r3.u64 = static_cast(v); + } + } +} + +//============================================================================= +// PPC To Host Function Wrapper +//============================================================================= +// Calls a PPC function from host code with proper context setup + +template +T GuestToHostFunction(const TFunction& func, TArgs&&... argv) { + auto args = std::make_tuple(std::forward(argv)...); + + auto* ts = rex::runtime::ThreadState::Get(); + if (!ts) { + if constexpr (std::is_void_v) { + return; + } else { + return T{}; + } + } + PPCContext* currentCtx = ts->context(); + + auto* ks = rex::system::kernel_state(); + if (!ks || !ks->memory()) { + if constexpr (std::is_void_v) { + return; + } else { + return T{}; + } + } + uint8_t* base = ks->memory()->virtual_membase(); + + PPCContext newCtx{}; + newCtx.r1 = currentCtx->r1; + newCtx.r1.u32 -= 0x70; // PPC64 minimum frame: linkage + param save + newCtx.r13 = currentCtx->r13; + newCtx.fpscr = currentCtx->fpscr; + + _translate_args_to_guest(newCtx, base, args); + + if constexpr (std::is_function_v) { + func(newCtx, base); + } else if constexpr (std::is_integral_v) { + (void)func; + } else { + func(newCtx, base); + } + + currentCtx->fpscr = newCtx.fpscr; + + if constexpr (std::is_void_v) { + return; + } else if constexpr (std::is_pointer_v) { + uint32_t guest_addr = newCtx.r3.u32; + return guest_addr ? rex::memory::GuestPtr(base, guest_addr) : nullptr; + } else if constexpr (is_precise_v) { + return static_cast(newCtx.f1.f64); + } else { + return static_cast(newCtx.r3.u64); + } +} + +} // namespace rex::ppc + +/// Maximum size of the loaded image name buffer (255 chars + NUL). +constexpr size_t kExLoadedImageNameSize = 255 + 1; diff --git a/include/rex/ppc/intrinsics.h b/include/rex/ppc/intrinsics.h new file mode 100644 index 0000000..93d87b9 --- /dev/null +++ b/include/rex/ppc/intrinsics.h @@ -0,0 +1,405 @@ +/** + * @file ppc/intrinsics.h + * @brief SIMD intrinsic helpers and vector lookup tables for PPC AltiVec emulation + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + * + * @remarks Based on XenonRecomp/UnleashedRecomp SIMD patterns and simde + */ + +#pragma once + +#include +#include +#include + +#include +#include +#include +#include + +#if defined(__aarch64__) || defined(_M_ARM64) +#include +#endif + +#include + +namespace rex::ppc { + +//============================================================================= +// Vector Load/Store Mask Tables +//============================================================================= +// These tables are used for lvlx/lvrx (load vector left/right) and +// stvlx/stvrx (store vector left/right) instructions. + +inline uint8_t VectorMaskL[] = { + 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, + 0xFF, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, + 0xFF, 0xFF, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, + 0xFF, 0xFF, 0xFF, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0E, 0x0D, 0x0C, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0E, 0x0D, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0E, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, +}; + +inline uint8_t VectorMaskR[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x02, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x03, 0x02, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x04, 0x03, 0x02, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0xFF, 0xFF, 0xFF, + 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0xFF, 0xFF, + 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0xFF, +}; + +inline uint8_t VectorShiftTableL[] = { + 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, + 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, + 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, + 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, + 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, + 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, + 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, + 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, + 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, + 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, + 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, + 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, + 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, + 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, + 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, + 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, +}; + +inline uint8_t VectorShiftTableR[] = { + 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, + 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, + 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, + 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, + 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, + 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, + 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, + 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, + 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, + 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, + 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, + 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, + 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, + 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, + 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, + 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, +}; + +//============================================================================= +// SIMD Helper Functions +//============================================================================= + +// Unsigned 32-bit saturating add +inline simde__m128i simde_mm_adds_epu32(simde__m128i a, simde__m128i b) { + return simde_mm_add_epi32( + a, simde_mm_min_epu32(simde_mm_xor_si128(a, simde_mm_cmpeq_epi32(a, a)), b)); +} + +// Signed 8-bit average (rounds towards zero) +inline simde__m128i simde_mm_avg_epi8(simde__m128i a, simde__m128i b) { + simde__m128i c = simde_mm_set1_epi8(char(128)); + return simde_mm_xor_si128(c, + simde_mm_avg_epu8(simde_mm_xor_si128(c, a), simde_mm_xor_si128(c, b))); +} + +// Signed 16-bit average +inline simde__m128i simde_mm_avg_epi16(simde__m128i a, simde__m128i b) { + simde__m128i c = simde_mm_set1_epi16(short(32768)); + return simde_mm_xor_si128(c, + simde_mm_avg_epu16(simde_mm_xor_si128(c, a), simde_mm_xor_si128(c, b))); +} + +// Signed 32-bit average +inline simde__m128i simde_mm_avg_epi32(simde__m128i a, simde__m128i b) { + simde__m128i sum = simde_mm_add_epi32(simde_mm_srai_epi32(a, 1), simde_mm_srai_epi32(b, 1)); + return simde_mm_add_epi32(sum, + simde_mm_and_si128(simde_mm_or_si128(a, b), simde_mm_set1_epi32(1))); +} + +// Convert unsigned 32-bit integers to floats +inline simde__m128 simde_mm_cvtepu32_ps_(simde__m128i src1) { + simde__m128i xmm1 = simde_mm_add_epi32(src1, simde_mm_set1_epi32(127)); + simde__m128i xmm0 = simde_mm_slli_epi32(src1, 31 - 8); + xmm0 = simde_mm_srli_epi32(xmm0, 31); + xmm0 = simde_mm_add_epi32(xmm0, xmm1); + xmm0 = simde_mm_srai_epi32(xmm0, 8); + xmm0 = simde_mm_add_epi32(xmm0, simde_mm_set1_epi32(0x4F800000)); + simde__m128 xmm2 = simde_mm_cvtepi32_ps(src1); + return simde_mm_blendv_ps(xmm2, simde_mm_castsi128_ps(xmm0), simde_mm_castsi128_ps(src1)); +} + +// Permute bytes from two vectors based on control vector +inline simde__m128i simde_mm_perm_epi8_(simde__m128i a, simde__m128i b, simde__m128i c) { + simde__m128i d = simde_mm_set1_epi8(0xF); + simde__m128i e = simde_mm_sub_epi8(d, simde_mm_and_si128(c, d)); + return simde_mm_blendv_epi8(simde_mm_shuffle_epi8(a, e), simde_mm_shuffle_epi8(b, e), + simde_mm_slli_epi32(c, 3)); +} + +// Unsigned 8-bit compare greater than +inline simde__m128i simde_mm_cmpgt_epu8(simde__m128i a, simde__m128i b) { + simde__m128i c = simde_mm_set1_epi8(char(128)); + return simde_mm_cmpgt_epi8(simde_mm_xor_si128(a, c), simde_mm_xor_si128(b, c)); +} + +// Unsigned 16-bit compare greater than +inline simde__m128i simde_mm_cmpgt_epu16(simde__m128i a, simde__m128i b) { + simde__m128i c = simde_mm_set1_epi16(short(32768)); + return simde_mm_cmpgt_epi16(simde_mm_xor_si128(a, c), simde_mm_xor_si128(b, c)); +} + +// Vector Convert To Signed Fixed-Point Word Saturate +inline simde__m128i simde_mm_vctsxs(simde__m128 src1) { + simde__m128 xmm2 = simde_mm_cmpunord_ps(src1, src1); + simde__m128i xmm0 = simde_mm_cvttps_epi32(src1); + simde__m128i xmm1 = simde_mm_cmpeq_epi32(xmm0, simde_mm_set1_epi32(INT_MIN)); + xmm1 = simde_mm_andnot_si128(simde_mm_castps_si128(src1), xmm1); + simde__m128 dest = simde_mm_blendv_ps(simde_mm_castsi128_ps(xmm0), + simde_mm_castsi128_ps(simde_mm_set1_epi32(INT_MAX)), + simde_mm_castsi128_ps(xmm1)); + return simde_mm_andnot_si128(simde_mm_castps_si128(xmm2), simde_mm_castps_si128(dest)); +} + +// Vector Convert To Unsigned Fixed-Point Word Saturate +// Convert float to unsigned int with saturation to [0, UINT_MAX] +// NaN -> 0, negative -> 0, > UINT_MAX -> UINT_MAX +inline simde__m128i simde_mm_vctuxs(simde__m128 src1) { + simde__m128 nan_mask = simde_mm_cmpunord_ps(src1, src1); + simde__m128 neg_mask = simde_mm_cmplt_ps(src1, simde_mm_setzero_ps()); + simde__m128 max_val = simde_mm_set1_ps(4294967295.0f); // UINT_MAX as float + simde__m128 overflow_mask = simde_mm_cmpge_ps(src1, max_val); + + // Clamp to [0, UINT_MAX] + simde__m128 clamped = simde_mm_max_ps(src1, simde_mm_setzero_ps()); + clamped = simde_mm_min_ps(clamped, max_val); + + // Convert to signed int first (will handle values up to INT_MAX correctly) + // For values > INT_MAX, we need special handling + simde__m128 half_range = simde_mm_set1_ps(2147483648.0f); // 2^31 + simde__m128 high_bit_mask = simde_mm_cmpge_ps(clamped, half_range); + + // For values >= 2^31, subtract 2^31 before conversion and add it back after + simde__m128 adjusted = simde_mm_sub_ps(clamped, simde_mm_and_ps(high_bit_mask, half_range)); + simde__m128i low_bits = simde_mm_cvttps_epi32(adjusted); + simde__m128i high_bit = simde_mm_and_si128(simde_mm_castps_si128(high_bit_mask), + simde_mm_set1_epi32(int(0x80000000u))); + simde__m128i result = simde_mm_or_si128(low_bits, high_bit); + + // Apply saturation: NaN -> 0, overflow -> UINT_MAX + result = simde_mm_andnot_si128(simde_mm_castps_si128(nan_mask), result); + result = simde_mm_andnot_si128(simde_mm_castps_si128(neg_mask), result); + result = simde_mm_or_si128( + simde_mm_andnot_si128(simde_mm_castps_si128(overflow_mask), result), + simde_mm_and_si128(simde_mm_castps_si128(overflow_mask), simde_mm_set1_epi32(-1))); + + return result; +} + +// Vector Shift Right +inline simde__m128i simde_mm_vsr(simde__m128i a, simde__m128i b) { + b = simde_mm_srli_epi64(simde_mm_slli_epi64(b, 61), 61); + return simde_mm_castps_si128(simde_mm_insert_ps( + simde_mm_castsi128_ps(simde_mm_srl_epi64(a, b)), + simde_mm_castsi128_ps(simde_mm_srl_epi64(simde_mm_srli_si128(a, 4), b)), 0x10)); +} + +// Vector Shift Left - shift entire 128-bit vector left by bits in low 3 bits of b +inline simde__m128i simde_mm_vsl(simde__m128i a, simde__m128i b) { + int shift = simde_mm_extract_epi8(b, 15) & 0x7; // Get low 3 bits from byte 15 (BE: byte 0) + if (shift == 0) + return a; + +#if defined(__x86_64__) || defined(_M_X64) + // Split into high and low 64-bit parts + simde__m128i low_shifted = simde_mm_slli_epi64(a, shift); + simde__m128i high_carry = simde_mm_srli_epi64(a, 64 - shift); + // Shift the carry from low qword to high qword position + high_carry = simde_mm_slli_si128(high_carry, 8); + return simde_mm_or_si128(low_shifted, high_carry); +#elif defined(__aarch64__) || defined(_M_ARM64) + // ARM64 NEON implementation using vld1/vst1 for conversion + uint64_t vals[2]; + uint64_t res[2] = {0, 0}; + + // Store simde__m128i to memory + simde_mm_store_si128((simde__m128i*)vals, a); + + // Load as NEON vector + uint64x2_t va = vld1q_u64(vals); + + // vshlq_u64 accepts variable shift per lane + int64x2_t shift_vector = vdupq_n_s64(shift); + uint64x2_t low_shifted = vshlq_u64(va, shift_vector); + + // For the carry, we need right shift + int64x2_t rshift_vector = vdupq_n_s64(64 - shift); + uint64x2_t high_carry = vshlq_u64(va, rshift_vector); + + // Combine results + uint64x2_t result_vec = vdupq_n_u64(0); + result_vec = vsetq_lane_u64(vgetq_lane_u64(low_shifted, 0), result_vec, 0); + result_vec = + vsetq_lane_u64(vgetq_lane_u64(low_shifted, 1) | vgetq_lane_u64(high_carry, 0), result_vec, 1); + + // Store back to memory and reload as simde__m128i + vst1q_u64(res, result_vec); + return simde_mm_load_si128((simde__m128i*)res); +#else +#error "Unsupported architecture for simde_mm_vsl (only x86_64 and ARM64 supported)" +#endif +} + +// Vector Shift Left by Octet - shift entire vector left by bytes in bits [121:124] of vB +// In PPC big-endian byte 15 is at LSB position, which in x86 LE is at index 0 +// Bits 121:124 within the byte are extracted as (byte >> 3) & 0xF +// PPC left shift = shift towards MSB (lower PPC addresses) = shift towards higher x86 addresses +inline simde__m128i simde_mm_vslo(simde__m128i a, simde__m128i b) { + int shift_bytes = (simde_mm_extract_epi8(b, 0) >> 3) & 0xF; + if (shift_bytes == 0) + return a; + if (shift_bytes >= 16) + return simde_mm_setzero_si128(); + +#if defined(__x86_64__) || defined(_M_X64) + alignas(16) uint8_t src[16], dst[16]; + simde_mm_store_si128((simde__m128i*)src, a); + memset(dst, 0, sizeof(dst)); + memcpy(dst + shift_bytes, src, 16 - shift_bytes); + return simde_mm_load_si128((simde__m128i*)dst); +#elif defined(__aarch64__) || defined(_M_ARM64) + // ARM64 NEON implementation using memory for conversion + uint8_t src[16]; + uint8_t dst[16] = {0}; + + simde_mm_store_si128((simde__m128i*)src, a); + memcpy(dst + shift_bytes, src, 16 - shift_bytes); + + return simde_mm_load_si128((simde__m128i*)dst); +#else +#error "Unsupported architecture for simde_mm_vslo (only x86_64 and ARM64 supported)" +#endif +} + +// Vector Shift Right by Octet - shift entire vector right by bytes in bits [121:124] of vB +// In PPC big-endian byte 15 is at LSB position, which in x86 LE is at index 0 +// Bits 121:124 within the byte are extracted as (byte >> 3) & 0xF +// PPC right shift = shift towards LSB (higher PPC addresses) = shift towards lower x86 addresses +inline simde__m128i simde_mm_vsro(simde__m128i a, simde__m128i b) { + int shift_bytes = (simde_mm_extract_epi8(b, 0) >> 3) & 0xF; + if (shift_bytes == 0) + return a; + if (shift_bytes >= 16) + return simde_mm_setzero_si128(); + +#if defined(__x86_64__) || defined(_M_X64) + alignas(16) uint8_t src[16], dst[16]; + simde_mm_store_si128((simde__m128i*)src, a); + memset(dst, 0, sizeof(dst)); + memcpy(dst, src + shift_bytes, 16 - shift_bytes); + return simde_mm_load_si128((simde__m128i*)dst); +#elif defined(__aarch64__) || defined(_M_ARM64) + // ARM64 NEON implementation using memory for conversion + uint8_t src[16]; + uint8_t dst[16] = {0}; + + simde_mm_store_si128((simde__m128i*)src, a); + memcpy(dst, src + shift_bytes, 16 - shift_bytes); + + return simde_mm_load_si128((simde__m128i*)dst); +#else +#error "Unsupported architecture for simde_mm_vsro (only x86_64 and ARM64 supported)" +#endif +} + +// Variable 16-bit shift left: widen to 32-bit, shift, narrow back +inline simde__m128i simde_mm_sllv_epi16(simde__m128i a, simde__m128i count) { + simde__m128i zero = simde_mm_setzero_si128(); + simde__m128i a_lo = simde_mm_unpacklo_epi16(a, zero); + simde__m128i a_hi = simde_mm_unpackhi_epi16(a, zero); + simde__m128i s_lo = simde_mm_unpacklo_epi16(count, zero); + simde__m128i s_hi = simde_mm_unpackhi_epi16(count, zero); + simde__m128i r_lo = simde_mm_sllv_epi32(a_lo, s_lo); + simde__m128i r_hi = simde_mm_sllv_epi32(a_hi, s_hi); + simde__m128i mask16 = simde_mm_set1_epi32(0xFFFF); + r_lo = simde_mm_and_si128(r_lo, mask16); + r_hi = simde_mm_and_si128(r_hi, mask16); + return simde_mm_packus_epi32(r_lo, r_hi); +} + +// Variable 16-bit logical right shift: widen to 32-bit, shift, narrow back +inline simde__m128i simde_mm_srlv_epi16(simde__m128i a, simde__m128i count) { + simde__m128i zero = simde_mm_setzero_si128(); + simde__m128i a_lo = simde_mm_unpacklo_epi16(a, zero); + simde__m128i a_hi = simde_mm_unpackhi_epi16(a, zero); + simde__m128i s_lo = simde_mm_unpacklo_epi16(count, zero); + simde__m128i s_hi = simde_mm_unpackhi_epi16(count, zero); + simde__m128i r_lo = simde_mm_srlv_epi32(a_lo, s_lo); + simde__m128i r_hi = simde_mm_srlv_epi32(a_hi, s_hi); + return simde_mm_packus_epi32(r_lo, r_hi); +} + +// Variable 16-bit arithmetic right shift: sign-extend to 32-bit, shift, narrow back +inline simde__m128i simde_mm_srav_epi16(simde__m128i a, simde__m128i count) { + simde__m128i zero = simde_mm_setzero_si128(); + // Sign-extend a: duplicate each 16-bit lane, then arithmetic shift right by 16 + simde__m128i a_lo = simde_mm_srai_epi32(simde_mm_unpacklo_epi16(a, a), 16); + simde__m128i a_hi = simde_mm_srai_epi32(simde_mm_unpackhi_epi16(a, a), 16); + simde__m128i s_lo = simde_mm_unpacklo_epi16(count, zero); + simde__m128i s_hi = simde_mm_unpackhi_epi16(count, zero); + simde__m128i r_lo = simde_mm_srav_epi32(a_lo, s_lo); + simde__m128i r_hi = simde_mm_srav_epi32(a_hi, s_hi); + return simde_mm_packs_epi32(r_lo, r_hi); +} + +// Variable 8-bit shift left: widen to 16-bit, shift, narrow back +inline simde__m128i simde_mm_sllv_epi8(simde__m128i a, simde__m128i count) { + simde__m128i zero = simde_mm_setzero_si128(); + simde__m128i a_lo = simde_mm_unpacklo_epi8(a, zero); + simde__m128i a_hi = simde_mm_unpackhi_epi8(a, zero); + simde__m128i s_lo = simde_mm_unpacklo_epi8(count, zero); + simde__m128i s_hi = simde_mm_unpackhi_epi8(count, zero); + simde__m128i r_lo = simde_mm_sllv_epi16(a_lo, s_lo); + simde__m128i r_hi = simde_mm_sllv_epi16(a_hi, s_hi); + simde__m128i mask8 = simde_mm_set1_epi16(0xFF); + r_lo = simde_mm_and_si128(r_lo, mask8); + r_hi = simde_mm_and_si128(r_hi, mask8); + return simde_mm_packus_epi16(r_lo, r_hi); +} + +} // namespace rex::ppc + +//============================================================================= +// Global Aliases for Generated Code +//============================================================================= +// Vector mask tables accessible from global scope for generated code +using rex::ppc::VectorMaskL; +using rex::ppc::VectorMaskR; +using rex::ppc::VectorShiftTableL; +using rex::ppc::VectorShiftTableR; diff --git a/include/rex/ppc/stack.h b/include/rex/ppc/stack.h new file mode 100644 index 0000000..cc92f76 --- /dev/null +++ b/include/rex/ppc/stack.h @@ -0,0 +1,166 @@ +/** + * @file ppc/stack.h + * @brief Guest PPC stack push/pop operations and scope guard. + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace rex::ppc { + +//============================================================================= +// Stack bounds helper +//============================================================================= + +/// Read stack_end_ptr from KPCR at r13 + 0x74. +/// Returns 0 if r13 is not set (e.g. in unit tests without a live thread). +inline uint32_t stack_limit_from_pcr(PPCContext& ctx, uint8_t* base) { + if (ctx.r13.u32 == 0) + return 0; + uint32_t raw; + std::memcpy(&raw, base + ctx.r13.u32 + 0x74, sizeof(raw)); + return __builtin_bswap32(raw); +} + +inline void stack_bounds_check(PPCContext& ctx, uint8_t* base, uint32_t new_r1) { + uint32_t limit = stack_limit_from_pcr(ctx, base); + if (limit != 0) { + REX_FATAL_IF(new_r1 > limit, "PPC stack overflow: r1 ({:#x}) below stack_end_ptr ({:#x})", + new_r1, limit); + } +} + +// note(tomc): PPC64 ABI requires 16-byte frame alignment, but r1 is already frame-aligned +// on entry; individual pushes round to 8 bytes to maintain doubleword alignment. +inline constexpr uint32_t stack_align(uint32_t size) { + return (size + 7u) & ~7u; +} + +//============================================================================= +// Core push/pop (explicit ctx/base) +//============================================================================= + +/// Push a byte-swapped scalar onto the guest stack. +template + requires std::is_arithmetic_v +inline uint32_t stack_push(PPCContext& ctx, uint8_t* base, T value) { + uint32_t alloc = stack_align(sizeof(T)); + uint32_t new_r1 = ctx.r1.u32 - alloc; + stack_bounds_check(ctx, base, new_r1); + ctx.r1.u32 = new_r1; + + // Byte-swap and write + T swapped; + if constexpr (sizeof(T) == 1) { + swapped = value; + } else if constexpr (sizeof(T) == 2) { + uint16_t bits; + std::memcpy(&bits, &value, 2); + bits = __builtin_bswap16(bits); + std::memcpy(&swapped, &bits, 2); + } else if constexpr (sizeof(T) == 4) { + uint32_t bits; + std::memcpy(&bits, &value, 4); + bits = __builtin_bswap32(bits); + std::memcpy(&swapped, &bits, 4); + } else if constexpr (sizeof(T) == 8) { + uint64_t bits; + std::memcpy(&bits, &value, 8); + bits = __builtin_bswap64(bits); + std::memcpy(&swapped, &bits, 8); + } + std::memcpy(base + new_r1, &swapped, sizeof(T)); + return new_r1; +} + +/// Push a NUL-terminated string onto the guest stack (no byte-swap, raw bytes). +inline uint32_t stack_push_string(PPCContext& ctx, uint8_t* base, const char* str) { + uint32_t len = static_cast(std::strlen(str)) + 1; + uint32_t alloc = stack_align(len); + uint32_t new_r1 = ctx.r1.u32 - alloc; + stack_bounds_check(ctx, base, new_r1); + ctx.r1.u32 = new_r1; + std::memcpy(base + new_r1, str, len); + return new_r1; +} + +/// Push raw bytes onto the guest stack (no byte-swap). +inline uint32_t stack_push(PPCContext& ctx, uint8_t* base, const void* data, uint32_t len) { + uint32_t alloc = stack_align(len); + uint32_t new_r1 = ctx.r1.u32 - alloc; + stack_bounds_check(ctx, base, new_r1); + ctx.r1.u32 = new_r1; + std::memcpy(base + new_r1, data, len); + return new_r1; +} + +/// Pop bytes from the guest stack. +inline void stack_pop(PPCContext& ctx, uint32_t size) { + ctx.r1.u32 += stack_align(size); +} + +//============================================================================= +// Scope guard +//============================================================================= + +/// RAII guard that saves r1 on construction and restores on destruction. +class stack_guard { + PPCContext& ctx_; + uint32_t saved_r1_; + + public: + explicit stack_guard(PPCContext& ctx) : ctx_(ctx), saved_r1_(ctx.r1.u32) {} + stack_guard() : stack_guard(*rex::runtime::ThreadState::Get()->context()) {} + ~stack_guard() { ctx_.r1.u32 = saved_r1_; } + + stack_guard(const stack_guard&) = delete; + stack_guard& operator=(const stack_guard&) = delete; +}; + +//============================================================================= +// Implicit ctx/base overloads (use current thread context) +//============================================================================= + +namespace detail { +inline PPCContext& current_ctx() { + return *rex::runtime::ThreadState::Get()->context(); +} +inline uint8_t* current_base() { + return rex::system::kernel_state()->memory()->virtual_membase(); +} +} // namespace detail + +template + requires std::is_arithmetic_v +inline uint32_t stack_push(T value) { + return stack_push(detail::current_ctx(), detail::current_base(), value); +} + +inline uint32_t stack_push_string(const char* str) { + return stack_push_string(detail::current_ctx(), detail::current_base(), str); +} + +inline uint32_t stack_push(const void* data, uint32_t len) { + return stack_push(detail::current_ctx(), detail::current_base(), data, len); +} + +inline void stack_pop(uint32_t size) { + stack_pop(detail::current_ctx(), size); +} + +} // namespace rex::ppc diff --git a/include/rex/result.h b/include/rex/result.h new file mode 100644 index 0000000..8e9f2ed --- /dev/null +++ b/include/rex/result.h @@ -0,0 +1,170 @@ +/** + * @file result.h + * @brief Error handling using std::expected + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include + +namespace rex { + +//============================================================================= +// Error Categories +//============================================================================= + +enum class ErrorCategory { + NoError, // No error (success) + IO, // File I/O errors + Memory, // Memory allocation/mapping errors + Format, // File format parsing errors (XEX, PE, ELF) + Crypto, // Cryptography errors (decryption, signature) + Compression, // Decompression errors + Runtime, // Runtime execution errors + Platform, // Platform-specific errors + Config, // Configuration errors + Validation, // Validation errors (e.g., unresolved functions) + NotFound, // Resource not found + NotImplemented, // Feature not implemented + UserAbort, // User declined an interactive prompt +}; + +//============================================================================= +// Error Structure +//============================================================================= + +struct Error { + ErrorCategory category = ErrorCategory::NoError; + std::string message; + int code = 0; // Platform or library-specific error code + + Error() = default; + + Error(ErrorCategory cat, std::string msg, int err_code = 0) + : category(cat), message(std::move(msg)), code(err_code) {} + + // Create from system error code + static Error from_errno(ErrorCategory cat, std::string msg, int errno_value) { + return Error(cat, std::move(msg), errno_value); + } + + // Check if error represents success + [[nodiscard]] bool is_success() const noexcept { return category == ErrorCategory::NoError; } + + // Get full error description + [[nodiscard]] std::string what() const { + if (is_success()) { + return "Success"; + } + std::string result = message; + if (code != 0) { + result += " (code: " + std::to_string(code) + ")"; + } + return result; + } +}; + +//============================================================================= +// Result Type Aliases +//============================================================================= + +/** + * Result type for operations that can fail + * Usage: + * Result result = some_operation(); + * if (result) { + * int value = *result; // Success + * } else { + * Error err = result.error(); // Failure + * } + */ +template +using Result = std::expected; + +/** + * Result type for operations that return nothing on success + */ +using VoidResult = std::expected; + +//============================================================================= +// Helper Functions +//============================================================================= + +/** + * Create a success result + */ +template +inline Result Ok(T&& value) { + return Result(std::forward(value)); +} + +/** + * Create a success result for void operations + */ +inline VoidResult Ok() { + return VoidResult(); +} + +/** + * Create an error result + */ +template +inline auto Err(Error error) { + if constexpr (std::is_void_v) { + return VoidResult(std::unexpected(std::move(error))); + } else { + return Result(std::unexpected(std::move(error))); + } +} + +/** + * Create an error result (convenience overload) + */ +template +inline auto Err(ErrorCategory category, std::string message, int code = 0) { + return Err(Error(category, std::move(message), code)); +} + +} // namespace rex + +//============================================================================= +// TRY Macro - Early return on error +//============================================================================= +// Evaluates the expression and returns early if it contains an error. +// The value is extracted and assigned if successful. +// +// Usage: +// Result get_value(); +// VoidResult do_something() { +// int value = TRY(get_value()); +// // ... use value ... +// return rex::Ok(); +// } +// +// For void results: +// VoidResult validate(); +// VoidResult process() { +// TRY(validate()); // Returns on error, continues on success +// return rex::Ok(); +// } +//============================================================================= + +#define REX_TRY_CONCAT_IMPL(x, y) x##y +#define REX_TRY_CONCAT(x, y) REX_TRY_CONCAT_IMPL(x, y) + +#define TRY(expr) \ + ({ \ + auto REX_TRY_CONCAT(_rex_try_result_, __LINE__) = (expr); \ + if (!REX_TRY_CONCAT(_rex_try_result_, __LINE__)) { \ + return std::unexpected(REX_TRY_CONCAT(_rex_try_result_, __LINE__).error()); \ + } \ + std::move(REX_TRY_CONCAT(_rex_try_result_, __LINE__)).value(); \ + }) diff --git a/include/rex/rex_app.h b/include/rex/rex_app.h new file mode 100644 index 0000000..56b378d --- /dev/null +++ b/include/rex/rex_app.h @@ -0,0 +1,228 @@ +/** + * @file rex/rex_app.h + * @brief ReXApp - base class for recompiled windowed applications + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct ImFontAtlas; + +namespace rex { + +class LogCaptureSink; + +/// Content path configuration, passed to OnConfigurePaths(). +/// All paths start with sensible defaults derived from CLI args and cvars. +/// Subclasses may override any field before Runtime is constructed. +struct PathConfig { + std::filesystem::path game_data_root; + std::filesystem::path user_data_root; + std::filesystem::path update_data_root; + std::filesystem::path cache_root; + std::filesystem::path config_path; +}; + +namespace ui { +class ConsoleDialog; +class SettingsDialog; +} // namespace ui + +/// Base class for recompiled Xbox 360 applications. +/// +/// OnInitialize is a thin coordinator that runs four phases in order: +/// +/// SetupEnvironment -> paths, config, logging +/// SetupPresentation -> window, graphics presentation, ImGui drawer +/// OnFinalizePaths -> hook for wizard-driven path resolution (sync or async) +/// ConstructRuntime -> Runtime, guest GPU init, XEX load, rexcrt heap +/// LaunchModule -> shader cache, PrepareModuleLaunch, background wait +/// +/// Each phase is a protected virtual; consumers override selectively without +/// re-implementing the whole flow. +/// +/// Subclass skeleton: +/// @code +/// // src/my_app_app.h (yours to customize) +/// class MyApp : public rex::ReXApp { +/// public: +/// using rex::ReXApp::ReXApp; +/// static std::unique_ptr Create( +/// rex::ui::WindowedAppContext& ctx) { +/// return std::unique_ptr(new MyApp(ctx, "my_app", +/// PPCImageConfig)); +/// } +/// // Override hooks: OnPreSetup, OnPostSetup, OnCreateDialogs, +/// // OnConfigureFonts, OnFinalizePaths, etc. +/// }; +/// +/// // src/main.cpp +/// #include "generated/my_app_init.h" +/// #include "my_app_app.h" +/// REX_DEFINE_APP(my_app, MyApp::Create) +/// @endcode +class ReXApp : public ui::WindowedApp, public ui::WindowListener, public ui::WindowInputListener { + public: + ~ReXApp() override; + + protected: + ReXApp(ui::WindowedAppContext& ctx, std::string_view name, PPCImageInfo ppc_info, + std::string_view usage = ""); + + // --- Virtual hooks for customization --- + + /// Called before Runtime::Setup(). Override to modify backend config. + virtual void OnPreSetup(RuntimeConfig& config) {} + + /// Called before Runtime::LoadXexImage(). Override to modify xex image. + virtual void OnLoadXexImage(std::string& xex_image) {} + + /// Called after runtime is fully initialized, before window creation. + virtual void OnPostSetup() {} + + /// Called after ImGui drawer is created. Add custom dialogs here. + virtual void OnCreateDialogs(ui::ImGuiDrawer* drawer) { (void)drawer; } + + /// Called before cleanup begins. Release custom resources here. + virtual void OnShutdown() {} + + /// Called after path defaults are computed, before Runtime is constructed. + /// Override to adjust game/user/update data paths programmatically. + virtual void OnConfigurePaths(PathConfig& paths) { (void)paths; } + + /// Called after SetupPresentation returns (window and ImGui drawer are live) + /// and before Runtime construction. Override to resolve paths from user + /// input shown through an ImGui dialog. + /// + /// Return a PathConfig to continue initialization synchronously. Return + /// std::nullopt and invoke `resume(path_config)` later (e.g. from a wizard + /// completion handler) to continue asynchronously. `resume` must be called + /// on the UI thread. Calling `resume` after the app has begun shutdown is + /// a no-op. + /// + /// Default implementation returns `defaults` unchanged. + virtual std::optional OnFinalizePaths(const PathConfig& defaults, + std::function resume) { + (void)resume; + return defaults; + } + + /// Called from the ImGui drawer's Initialize() after the default font is + /// registered and before the atlas is built. Override to add additional + /// fonts via AddFontFromMemoryTTF() or similar. + virtual void OnConfigureFonts(ImFontAtlas* atlas) { (void)atlas; } + + /// Called after logging is initialized. Add log sinks here. + virtual void OnPostInitLogging() {} + + /// Called after Runtime::LoadXexImage() succeeds. The XEX is loaded and + /// mapped into guest memory but the module has not launched. + /// Use this for data patches on the loaded image. + virtual void OnPostLoadXexImage() {} + + /// Called immediately before the main guest thread is created. + /// Everything is set up -- last chance to patch guest memory/code. + virtual void OnPreLaunchModule() {} + + /// Called after the main guest thread is created but before it starts + /// executing. The thread is suspended -- attach debuggers/monitors here. + virtual void OnPostLaunchModule(system::XThread* thread) { (void)thread; } + + /// Called when the main guest thread exits. The runtime is still alive. + /// Use for cleanup that depends on runtime resources. + virtual void OnGuestThreadExit(system::XThread* thread) { (void)thread; } + + // --- Init phase methods (called in order from OnInitialize) --- + + /// Resolve path defaults, load config TOML, initialize logging. + /// Populates `resolved_defaults_` with the PathConfig produced by + /// OnConfigurePaths. + virtual bool SetupEnvironment(); + + /// Construct Runtime with the given paths, call runtime_->Setup, load the + /// XEX image, initialize the rexcrt heap. Runs OnPostSetup at the end. + virtual bool ConstructRuntime(const PathConfig& paths); + + /// Create the window, stand up graphics presentation, create the ImGui + /// drawer, register overlay keybinds, run OnCreateDialogs. + virtual bool SetupPresentation(); + + /// Kick off the deferred module launch: shader storage init, + /// PrepareModuleLaunch, main thread resume, background wait. + virtual void LaunchModule(); + + // --- Accessors for subclass use --- + Runtime* runtime() const { return runtime_.get(); } + ui::Window* window() const { return window_.get(); } + ui::ImGuiDrawer* imgui_drawer() const { return imgui_drawer_.get(); } + ui::ImmediateDrawer* immediate_drawer() const { return immediate_drawer_.get(); } + + const std::filesystem::path& game_data_root() const { return game_data_root_; } + const std::filesystem::path& user_data_root() const { return user_data_root_; } + const std::filesystem::path& update_data_root() const { return update_data_root_; } + const std::filesystem::path& cache_root() const { return cache_root_; } + + /// Set a callback that provides guest frame stats to the debug overlay. + void SetGuestFrameStats(ui::DebugOverlayDialog::FrameStatsProvider provider); + + private: + std::function MakeResumeCallback(); + + // WindowedApp overrides + bool OnInitialize() override; + void OnDestroy() override; + + // WindowListener overrides + void OnClosing(ui::UIEvent& e) override; + + // WindowInputListener overrides + void OnKeyDown(ui::KeyEvent& e) override; + + PPCImageInfo ppc_info_; + PathConfig resolved_defaults_; + RuntimeConfig config_; + std::filesystem::path game_data_root_; + std::filesystem::path user_data_root_; + std::filesystem::path update_data_root_; + std::filesystem::path cache_root_; + std::unique_ptr runtime_; + std::unique_ptr window_; + std::thread module_thread_; + std::atomic shutting_down_{false}; + std::unique_ptr immediate_drawer_; + std::unique_ptr imgui_drawer_; + + // Built-in overlays + std::shared_ptr log_sink_; + std::unique_ptr debug_overlay_; + std::unique_ptr console_overlay_; + std::unique_ptr settings_overlay_; + ui::DebugOverlayDialog::FrameStatsProvider frame_stats_provider_; + std::filesystem::path config_path_; +}; + +} // namespace rex diff --git a/include/rex/runtime.h b/include/rex/runtime.h new file mode 100644 index 0000000..1f316d2 --- /dev/null +++ b/include/rex/runtime.h @@ -0,0 +1,189 @@ +/** + * @file runtime.h + * @brief Runtime subsystem entry point + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + * @remarks Based on Xenia emulator.h/cc + */ + +#pragma once + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include // object_ref + +// Forward declaration for function mapping (defined in rex/ppc/context.h) +struct PPCFuncMapping; + +#include + +REXCVAR_DECLARE(std::string, game_data_root); +REXCVAR_DECLARE(std::string, user_data_root); +REXCVAR_DECLARE(std::string, update_data_root); +REXCVAR_DECLARE(std::string, cache_path); + +namespace rex { + +// Forward declarations +namespace runtime { +class FunctionDispatcher; +class ExportResolver; +} // namespace runtime +namespace system { +class KernelState; +class XThread; +} // namespace system +namespace ui { +class WindowedAppContext; +class Window; +class ImGuiDrawer; +} // namespace ui + +/// Configuration for Runtime subsystem injection. +/// Graphics and audio backends are provided by the caller, keeping the runtime +/// library decoupled from concrete backend implementations. +/// Audio uses a factory because AudioSystem requires a FunctionDispatcher* at +/// construction time, which is only available during Setup(). +struct RuntimeConfig { + std::unique_ptr graphics; + std::function(runtime::FunctionDispatcher*)> audio_factory; + std::function(bool tool_mode)> input_factory; + std::function kernel_init; + bool tool_mode = false; +}; + +/// Helper macros for populating RuntimeConfig with concrete backends. +/// Usage: +/// rex::RuntimeConfig config; +/// config.graphics = REX_GRAPHICS_BACKEND(rex::graphics::vulkan::VulkanGraphicsSystem); +/// config.audio_factory = REX_AUDIO_BACKEND(rex::audio::sdl::SDLAudioSystem); +#define REX_GRAPHICS_BACKEND(Type) std::make_unique() +#define REX_AUDIO_BACKEND(Type) \ + [](::rex::runtime::FunctionDispatcher* _fd) -> std::unique_ptr<::rex::system::IAudioSystem> { \ + return Type::Create(_fd); \ + } +#define REX_INPUT_BACKEND(SetupFunc) \ + [](bool _tool_mode) -> std::unique_ptr<::rex::system::IInputSystem> { \ + return SetupFunc(_tool_mode); \ + } + +/** + * Runtime class - the main entry point for recompiled applications. + * + * Owns all subsystems: + * - Memory: Virtual address space for guest code + * - VFS: Virtual file system + * - KernelState: Kernel objects, threading, etc. + */ +class Runtime { + public: + explicit Runtime(const std::filesystem::path& game_data_root, + const std::filesystem::path& user_data_root = {}, + const std::filesystem::path& update_data_root = {}, + const std::filesystem::path& cache_root = {}); + ~Runtime(); + + // Non-copyable + Runtime(const Runtime&) = delete; + Runtime& operator=(const Runtime&) = delete; + + // Global instance accessor - set after Setup() is called + static Runtime* instance(); + + // Subsystem accessors + memory::Memory* memory() const { return memory_.get(); } + rex::filesystem::VirtualFileSystem* file_system() const { return file_system_.get(); } + system::KernelState* kernel_state() const { return kernel_state_.get(); } + system::IGraphicsSystem* graphics_system() const { return graphics_system_.get(); } + system::IAudioSystem* audio_system() const { return audio_system_.get(); } + system::IInputSystem* input_system() const { return input_system_.get(); } + + // FunctionDispatcher for guest function dispatch and interrupt execution + runtime::FunctionDispatcher* function_dispatcher() const { return function_dispatcher_.get(); } + // Export resolver - used for variable import resolution in guest memory + runtime::ExportResolver* export_resolver() const { return export_resolver_.get(); } + + // Path accessors + const std::filesystem::path& game_data_root() const { return game_data_root_; } + const std::filesystem::path& user_data_root() const { return user_data_root_; } + const std::filesystem::path& update_data_root() const { return update_data_root_; } + const std::filesystem::path& cache_root() const { return cache_root_; } + + // Set the app context for presentation (call before Setup) + void set_app_context(ui::WindowedAppContext* context) { app_context_ = context; } + ui::WindowedAppContext* app_context() const { return app_context_; } + + // UI accessors for dialog system + void set_display_window(ui::Window* window) { display_window_ = window; } + ui::Window* display_window() const { return display_window_; } + void set_imgui_drawer(ui::ImGuiDrawer* drawer) { imgui_drawer_ = drawer; } + ui::ImGuiDrawer* imgui_drawer() const { return imgui_drawer_; } + + // Setup the runtime environment + // config.tool_mode: If true, skips GPU initialization (for analysis tools) + X_STATUS Setup(RuntimeConfig config = {}); + + // rexglue - initializes per-module function dispatch table + X_STATUS Setup(const PPCImageInfo& image_info, RuntimeConfig config = {}); + + // Check if running in tool mode (no GPU) + bool is_tool_mode() const { return tool_mode_; } + + void Shutdown(); + + // Load XEX image into guest memory + X_STATUS LoadXexImage(const std::string_view module_path); + + // Launch XEX module and return main thread + // Call after LoadXexImage to start execution + system::object_ref LaunchModule(); + + // Prepare module launch: creates suspended main thread without resuming. + // Call thread->Resume() after any pre-launch hooks. + system::object_ref PrepareModuleLaunch(); + + // Access the memory base pointer for recompiled code + uint8_t* virtual_membase() const; + + private: + // Set up VFS: mounts game_data_root as game:/d:, update_data_root as update: + bool SetupVfs(); + + std::filesystem::path game_data_root_; + std::filesystem::path user_data_root_; + std::filesystem::path update_data_root_; + std::filesystem::path cache_root_; + + ui::WindowedAppContext* app_context_ = nullptr; + ui::Window* display_window_ = nullptr; + ui::ImGuiDrawer* imgui_drawer_ = nullptr; + bool tool_mode_ = false; + bool setup_complete_ = false; + + std::unique_ptr memory_; + std::unique_ptr function_dispatcher_; + std::unique_ptr file_system_; + std::unique_ptr kernel_state_; + std::unique_ptr graphics_system_; + std::unique_ptr audio_system_; + std::unique_ptr input_system_; + std::unique_ptr export_resolver_; + + static Runtime* instance_; +}; + +} // namespace rex diff --git a/include/rex/stream.h b/include/rex/stream.h new file mode 100644 index 0000000..07eb5ea --- /dev/null +++ b/include/rex/stream.h @@ -0,0 +1,117 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015-2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified 2026 Tom Clay + * Modified for rexglue - Xbox 360 recompilation framework + * + * @changes - Consolidated bit.h and byte.h into single header + */ + +#pragma once + +#include +#include +#include +#include + +namespace rex::stream { + +//============================================================================= +// BitStream - Bit-level stream operations +//============================================================================= + +class BitStream { + public: + BitStream(uint8_t* buffer, size_t size_in_bits); + ~BitStream(); + + const uint8_t* buffer() const { return buffer_; } + uint8_t* buffer() { return buffer_; } + size_t offset_bits() const { return offset_bits_; } + size_t size_bits() const { return size_bits_; } + + void Advance(size_t num_bits); + void SetOffset(size_t offset_bits); + size_t BitsRemaining(); + + // Note: num_bits MUST be in the range 0-57 (inclusive) + uint64_t Peek(size_t num_bits); + uint64_t Read(size_t num_bits); + bool Write(uint64_t val, size_t num_bits); // TODO(DrChat): Not tested! + + size_t Copy(uint8_t* dest_buffer, size_t num_bits); + + private: + uint8_t* buffer_ = nullptr; + size_t offset_bits_ = 0; + size_t size_bits_ = 0; +}; + +//============================================================================= +// ByteStream - Byte-level stream operations +//============================================================================= + +class ByteStream { + public: + ByteStream(uint8_t* data, size_t data_length, size_t offset = 0); + ~ByteStream(); + + void Advance(size_t num_bytes); + void Read(std::span buf); + void Write(std::span buf); + + // Convenience overloads for void* (legacy compatibility) + void Read(void* buf, size_t len) { + return Read(std::span(reinterpret_cast(buf), len)); + } + void Write(const void* buf, size_t len) { + return Write(std::span(reinterpret_cast(buf), len)); + } + + const uint8_t* data() const { return data_; } + uint8_t* data() { return data_; } + size_t data_length() const { return data_length_; } + + size_t offset() const { return offset_; } + void set_offset(size_t offset) { offset_ = offset; } + + template + T Read() { + T data; + Read(std::span(reinterpret_cast(&data), sizeof(T))); + return data; + } + + template + void Write(T data) { + Write(std::span(reinterpret_cast(&data), sizeof(T))); + } + + void Write(const std::string_view str) { + Write(uint32_t(str.length())); + Write(str.data(), str.length() * sizeof(char)); + } + + void Write(const std::u16string_view str) { + Write(uint32_t(str.length())); + Write(str.data(), str.length() * sizeof(char16_t)); + } + + private: + uint8_t* data_ = nullptr; + size_t data_length_ = 0; + size_t offset_ = 0; +}; + +template <> +std::string ByteStream::Read(); + +template <> +std::u16string ByteStream::Read(); + +} // namespace rex::stream diff --git a/include/rex/string.h b/include/rex/string.h new file mode 100644 index 0000000..8ed18b2 --- /dev/null +++ b/include/rex/string.h @@ -0,0 +1,55 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified 2026 Tom Clay + * Modified for rexglue - Xbox 360 recompilation framework + * + * @changes - Moved functions from rex:: to rex::string:: namespace + * - Renamed xe_* functions to cleaner names + */ + +#pragma once + +#include +#include +#include + +#include + +namespace rex::string { + +// Basic string comparison (case-insensitive) +int compare_case(const char* string1, const char* string2); +int compare_case_n(const char* string1, const char* string2, size_t count); + +// Whitespace trimming +inline constexpr std::string_view kWhitespace = " \t\r\n"; + +/// Trim whitespace from the left of a string_view +std::string_view trim_left(std::string_view sv, std::string_view chars = kWhitespace); + +/// Trim whitespace from the right of a string_view +std::string_view trim_right(std::string_view sv, std::string_view chars = kWhitespace); + +/// Trim whitespace from both ends of a string_view +std::string_view trim(std::string_view sv, std::string_view chars = kWhitespace); + +/// Trim and convert to string +std::string trim_string(std::string_view sv, std::string_view chars = kWhitespace); + +// String duplication +char* duplicate(const char* source); + +// Encoding conversion +std::string to_utf8(const std::u16string_view source); +std::u16string to_utf16(const std::string_view source); + +// Safe string copy - copies up to max_count chars and null-terminates +void rex_strcpy(char* dest, size_t dest_size, const char* src, size_t max_count = 0); + +} // namespace rex::string diff --git a/include/rex/string/buffer.h b/include/rex/string/buffer.h new file mode 100644 index 0000000..5988259 --- /dev/null +++ b/include/rex/string/buffer.h @@ -0,0 +1,61 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified 2026 Tom Clay + * Modified for rexglue - Xbox 360 recompilation framework + * + * @changes - Moved StringBuffer from rex:: to rex::string:: namespace + */ + +#pragma once + +#include +#include +#include + +#include + +namespace rex::string { + +class StringBuffer { + public: + explicit StringBuffer(size_t initial_capacity = 0); + ~StringBuffer(); + + char* buffer() const { return buffer_; } + size_t length() const { return buffer_offset_; } + + void Reset(); + + void Append(char c); + void Append(char c, size_t count); + void Append(const char* value); + void Append(const std::string_view value); + + template + void AppendFormat(const char* format, const Args&... args) { + auto s = fmt::format(fmt::runtime(format), args...); + Append(s.c_str()); + } + + void AppendVarargs(const char* format, va_list args); + void AppendBytes(const uint8_t* buffer, size_t length); + + std::string to_string(); + std::string_view to_string_view() const; + std::vector to_bytes() const; + + private: + void Grow(size_t additional_length); + + char* buffer_ = nullptr; + size_t buffer_offset_ = 0; + size_t buffer_capacity_ = 0; +}; + +} // namespace rex::string diff --git a/include/rex/string/key.h b/include/rex/string/key.h new file mode 100644 index 0000000..d8a80a4 --- /dev/null +++ b/include/rex/string/key.h @@ -0,0 +1,94 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified 2026 Tom Clay + * Modified for rexglue - Xbox 360 recompilation framework + * + * @changes - Moved string_key and string_key_case from rex:: to rex::string:: + */ + +#pragma once + +#include +#include + +#include + +namespace rex::string { + +namespace detail { + +struct string_key_base { + private: + std::variant value_; + + public: + explicit string_key_base(const std::string_view value) : value_(value) {} + explicit string_key_base(std::string value) : value_(std::move(value)) {} + + std::string_view view() const { + return std::holds_alternative(value_) ? std::get(value_) + : std::get(value_); + } +}; + +} // namespace detail + +struct string_key : detail::string_key_base { + public: + explicit string_key(const std::string_view value) : string_key_base(value) {} + explicit string_key(std::string value) : string_key_base(value) {} + + static string_key create(const std::string_view value) { return string_key(std::string(value)); } + + static string_key create(std::string value) { return string_key(value); } + + bool operator==(const string_key& other) const { return other.view() == view(); } + + size_t hash() const { return rex::string::utf8_hash_fnv1a(view()); } + + struct Hash { + size_t operator()(const string_key& t) const { return t.hash(); } + }; +}; + +struct string_key_case : detail::string_key_base { + public: + explicit string_key_case(const std::string_view value) : string_key_base(value) {} + explicit string_key_case(std::string value) : string_key_base(value) {} + + static string_key_case create(const std::string_view value) { + return string_key_case(std::string(value)); + } + + static string_key_case create(std::string value) { return string_key_case(value); } + + bool operator==(const string_key_case& other) const { + return rex::string::utf8_equal_case(other.view(), view()); + } + + size_t hash() const { return rex::string::utf8_hash_fnv1a_case(view()); } + + struct Hash { + size_t operator()(const string_key_case& t) const { return t.hash(); } + }; +}; + +} // namespace rex::string + +namespace std { +template <> +struct hash { + std::size_t operator()(const rex::string::string_key& t) const { return t.hash(); } +}; + +template <> +struct hash { + std::size_t operator()(const rex::string::string_key_case& t) const { return t.hash(); } +}; +} // namespace std diff --git a/include/rex/string/utf8.h b/include/rex/string/utf8.h new file mode 100644 index 0000000..d419be1 --- /dev/null +++ b/include/rex/string/utf8.h @@ -0,0 +1,147 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified 2026 Tom Clay + * Modified for rexglue - Xbox 360 recompilation framework + * + * @changes - Flattened rex::string::utf8_ namespace to rex::string:: + * - Added utf8_ prefix to all functions + */ + +#pragma once + +#include +#include + +#include + +namespace rex::string { + +// UTF-8 path separator constants +constexpr char32_t kUtf8PathSeparator = static_cast(rex::kPathSeparator); +constexpr char32_t kUtf8GuestPathSeparator = U'\\'; + +size_t utf8_count(const std::string_view view); + +std::string utf8_lower_ascii(const std::string_view view); +std::string utf8_upper_ascii(const std::string_view view); + +size_t utf8_hash_fnv1a(const std::string_view view); +size_t utf8_hash_fnv1a_case(const std::string_view view); + +// Splits the given haystack on any delimiters (needles) and returns all parts. +std::vector utf8_split(const std::string_view haystack, + const std::string_view needles, bool remove_empty = false); + +bool utf8_equal_z(const std::string_view left, const std::string_view right); + +bool utf8_equal_case(const std::string_view left, const std::string_view right); + +bool utf8_equal_case_z(const std::string_view left, const std::string_view right); + +std::string_view::size_type utf8_find_any_of(const std::string_view haystack, + const std::string_view needles); + +std::string_view::size_type utf8_find_any_of_case(const std::string_view haystack, + const std::string_view needles); + +std::string_view::size_type utf8_find_first_of(const std::string_view haystack, + const std::string_view needle); + +// find_first_of string, case insensitive. +std::string_view::size_type utf8_find_first_of_case(const std::string_view haystack, + const std::string_view needle); + +bool utf8_starts_with(const std::string_view haystack, const std::string_view needle); + +bool utf8_starts_with_case(const std::string_view haystack, const std::string_view needle); + +bool utf8_ends_with(const std::string_view haystack, const std::string_view needle); + +bool utf8_ends_with_case(const std::string_view haystack, const std::string_view needle); + +// Splits the given path on any valid path separator and returns all parts. +std::vector utf8_split_path(const std::string_view path); + +// Joins two path segments with the given separator. +std::string utf8_join_paths(const std::string_view left_path, const std::string_view right_path, + char32_t separator = kUtf8PathSeparator); + +std::string utf8_join_paths(const std::vector& paths, + char32_t separator = kUtf8PathSeparator); + +std::string utf8_join_paths(const std::vector& paths, + char32_t separator = kUtf8PathSeparator); + +inline std::string utf8_join_paths(std::initializer_list paths, + char32_t separator = kUtf8PathSeparator) { + std::string result; + for (auto path : paths) { + result = utf8_join_paths(result, path, separator); + } + return result; +} + +inline std::string utf8_join_guest_paths(const std::string_view left_path, + const std::string_view right_path) { + return utf8_join_paths(left_path, right_path, kUtf8GuestPathSeparator); +} + +inline std::string utf8_join_guest_paths(const std::vector& paths) { + return utf8_join_paths(paths, kUtf8GuestPathSeparator); +} + +inline std::string utf8_join_guest_paths(const std::vector& paths) { + return utf8_join_paths(paths, kUtf8GuestPathSeparator); +} + +inline std::string utf8_join_guest_paths(std::initializer_list paths) { + return utf8_join_paths(paths, kUtf8GuestPathSeparator); +} + +// Replaces all path separators with the given value and removes redundant +// separators. +std::string utf8_fix_path_separators(const std::string_view path, + char32_t new_separator = kUtf8PathSeparator); + +inline std::string utf8_fix_guest_path_separators(const std::string_view path) { + return utf8_fix_path_separators(path, kUtf8GuestPathSeparator); +} + +// Find the top directory name or filename from a path. +std::string utf8_find_name_from_path(const std::string_view path, + char32_t separator = kUtf8PathSeparator); + +inline std::string utf8_find_name_from_guest_path(const std::string_view path) { + return utf8_find_name_from_path(path, kUtf8GuestPathSeparator); +} + +std::string utf8_find_base_name_from_path(const std::string_view path, + char32_t separator = kUtf8PathSeparator); + +inline std::string utf8_find_base_name_from_guest_path(const std::string_view path) { + return utf8_find_base_name_from_path(path, kUtf8GuestPathSeparator); +} + +// Get parent path of the given directory or filename. +std::string utf8_find_base_path(const std::string_view path, + char32_t separator = kUtf8PathSeparator); + +inline std::string utf8_find_base_guest_path(const std::string_view path) { + return utf8_find_base_path(path, kUtf8GuestPathSeparator); +} + +// Canonicalizes a path, removing ..'s. +std::string utf8_canonicalize_path(const std::string_view path, + char32_t separator = kUtf8PathSeparator); + +inline std::string utf8_canonicalize_guest_path(const std::string_view path) { + return utf8_canonicalize_path(path, kUtf8GuestPathSeparator); +} + +} // namespace rex::string diff --git a/include/rex/string/util.h b/include/rex/string/util.h new file mode 100644 index 0000000..ac6f9e1 --- /dev/null +++ b/include/rex/string/util.h @@ -0,0 +1,374 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified 2026 Tom Clay + * Modified for rexglue - Xbox 360 recompilation framework + * + * @changes - Flattened rex::string::util:: namespace to rex::string:: + * - Renamed Safety enum to CopySafety + * - Added util_ prefix to copy functions + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +// TODO(gibbed): Clang and GCC don't have std::from_chars for floating point(!) +// despite it being part of the C++17 standard. Check this in the future to see +// if it's been resolved. + +#if REX_LACKS_FLOAT_FROM_CHARS +#include +#endif + +namespace rex::string { + +enum class CopySafety { + IDontKnowWhatIAmDoing, + IKnowWhatIAmDoing, +}; + +inline size_t util_copy_truncating(char* dest, const std::string_view source, + size_t dest_buffer_count) { + if (!dest_buffer_count) { + return 0; + } + size_t chars_copied = std::min(source.size(), dest_buffer_count - size_t(1)); + std::memcpy(dest, source.data(), chars_copied); + dest[chars_copied] = '\0'; + return chars_copied; +} + +inline size_t util_copy_truncating(char16_t* dest, const std::u16string_view source, + size_t dest_buffer_count) { + if (!dest_buffer_count) { + return 0; + } + size_t chars_copied = std::min(source.size(), dest_buffer_count - size_t(1)); + std::memcpy(dest, source.data(), chars_copied * sizeof(char16_t)); + dest[chars_copied] = u'\0'; + return chars_copied; +} + +inline size_t util_copy_and_swap_truncating(char16_t* dest, const std::u16string_view source, + size_t dest_buffer_count) { + if (!dest_buffer_count) { + return 0; + } + size_t chars_copied = std::min(source.size(), dest_buffer_count - size_t(1)); + memory::copy_and_swap(dest, source.data(), chars_copied); + dest[chars_copied] = u'\0'; + return chars_copied; +} + +template +inline size_t util_copy_maybe_truncating(char* dest, const std::string_view source, + size_t dest_buffer_count) { + static_assert(safety == CopySafety::IKnowWhatIAmDoing); + if (!dest_buffer_count) { + return 0; + } + size_t chars_copied = std::min(source.size(), dest_buffer_count); + std::memcpy(dest, source.data(), chars_copied); + return chars_copied; +} + +template +inline size_t util_copy_maybe_truncating(char16_t* dest, const std::u16string_view source, + size_t dest_buffer_count) { + static_assert(safety == CopySafety::IKnowWhatIAmDoing); + if (!dest_buffer_count) { + return 0; + } + size_t chars_copied = std::min(source.size(), dest_buffer_count); + std::memcpy(dest, source.data(), chars_copied * sizeof(char16_t)); + return chars_copied; +} + +template +inline size_t util_copy_and_swap_maybe_truncating(char16_t* dest, const std::u16string_view source, + size_t dest_buffer_count) { + static_assert(safety == CopySafety::IKnowWhatIAmDoing); + if (!dest_buffer_count) { + return 0; + } + size_t chars_copied = std::min(source.size(), dest_buffer_count); + memory::copy_and_swap(dest, source.data(), chars_copied); + return chars_copied; +} + +inline std::string to_hex_string(uint32_t value) { + return fmt::format("{:08X}", value); +} + +inline std::string to_hex_string(uint64_t value) { + return fmt::format("{:016X}", value); +} + +inline std::string to_hex_string(float value) { + static_assert(sizeof(uint32_t) == sizeof(value)); + uint32_t pun; + std::memcpy(&pun, &value, sizeof(value)); + return to_hex_string(pun); +} + +inline std::string to_hex_string(double value) { + static_assert(sizeof(uint64_t) == sizeof(value)); + uint64_t pun; + std::memcpy(&pun, &value, sizeof(value)); + return to_hex_string(pun); +} + +inline std::string to_hex_string(const vec128_t& value) { + return fmt::format("[{:08X} {:08X} {:08X} {:08X}]", value.u32[0], value.u32[1], value.u32[2], + value.u32[3]); +} + +template +inline T from_string(const std::string_view value, bool force_hex = false) { + (void)value; + (void)force_hex; + // Missing implementation for converting type T from string + throw; +} + +namespace detail { + +template > +inline T make_negative(T value) { + if constexpr (std::is_unsigned_v) { + value = static_cast(-static_cast(value)); + } else { + value = -value; + } + return value; +} + +// integral_from_string +template +inline T ifs(const std::string_view value, bool force_hex) { + int base = 10; + std::string_view range = value; + bool is_hex = force_hex; + bool is_negative = false; + if (rex::string::utf8_starts_with(range, "-")) { + is_negative = true; + range = range.substr(1); + } + if (rex::string::utf8_starts_with(range, "0x")) { + is_hex = true; + range = range.substr(2); + } + if (rex::string::utf8_ends_with(range, "h")) { + is_hex = true; + range = range.substr(0, range.length() - 1); + } + T result; + if (is_hex) { + base = 16; + } + // TODO(gibbed): do something more with errors? + auto [p, error] = std::from_chars(range.data(), range.data() + range.size(), result, base); + if (error != std::errc()) { + assert_always(); + return T(); + } + if (is_negative) { + result = make_negative(result); + } + return result; +} + +// floating_point_from_string +template +inline T fpfs(const std::string_view value, bool force_hex) { + static_assert(sizeof(T) == sizeof(PUN)); + std::string_view range = value; + bool is_hex = force_hex; + bool is_negative = false; + if (rex::string::utf8_starts_with(range, "-")) { + is_negative = true; + range = range.substr(1); + } + if (rex::string::utf8_starts_with(range, "0x")) { + is_hex = true; + range = range.substr(2); + } + if (rex::string::utf8_ends_with(range, "h")) { + is_hex = true; + range = range.substr(0, range.length() - 1); + } + T result; + if (is_hex) { + PUN pun = from_string(range, true); + if (is_negative) { + pun = make_negative(pun); + } + std::memcpy(&result, &pun, sizeof(PUN)); + } else { +#if REX_LACKS_FLOAT_FROM_CHARS + auto temp = std::string(range); + result = std::strtod(temp.c_str(), nullptr); +#else + auto [p, error] = std::from_chars(range.data(), range.data() + range.size(), result, + std::chars_format::general); + // TODO(gibbed): do something more with errors? + if (error != std::errc()) { + assert_always(); + return T(); + } +#endif + if (is_negative) { + result = -result; + } + } + return result; +} + +} // namespace detail + +template <> +inline bool from_string(const std::string_view value, bool force_hex) { + (void)force_hex; + return value == "true" || value == "1"; +} + +template <> +inline int8_t from_string(const std::string_view value, bool force_hex) { + return detail::ifs(value, force_hex); +} + +template <> +inline uint8_t from_string(const std::string_view value, bool force_hex) { + return detail::ifs(value, force_hex); +} + +template <> +inline int16_t from_string(const std::string_view value, bool force_hex) { + return detail::ifs(value, force_hex); +} + +template <> +inline uint16_t from_string(const std::string_view value, bool force_hex) { + return detail::ifs(value, force_hex); +} + +template <> +inline int32_t from_string(const std::string_view value, bool force_hex) { + return detail::ifs(value, force_hex); +} + +template <> +inline uint32_t from_string(const std::string_view value, bool force_hex) { + return detail::ifs(value, force_hex); +} + +template <> +inline int64_t from_string(const std::string_view value, bool force_hex) { + return detail::ifs(value, force_hex); +} + +template <> +inline uint64_t from_string(const std::string_view value, bool force_hex) { + return detail::ifs(value, force_hex); +} + +template <> +inline float from_string(const std::string_view value, bool force_hex) { + return detail::fpfs(value, force_hex); +} + +template <> +inline double from_string(const std::string_view value, bool force_hex) { + return detail::fpfs(value, force_hex); +} + +template <> +inline vec128_t from_string(const std::string_view value, bool force_hex) { + if (!value.size()) { + return vec128_t(); + } + vec128_t v; +#if REX_LACKS_FLOAT_FROM_CHARS + auto temp = std::string(value); + auto p = temp.c_str(); + auto end = temp.c_str() + temp.size(); +#else + auto p = value.data(); + auto end = value.data() + value.size(); +#endif + bool is_hex = force_hex; + if (p != end && *p == '[') { + is_hex = true; + ++p; + } else if (p != end && *p == '(') { + is_hex = false; + ++p; + } else { + // Assume hex? + is_hex = true; + } + if (p == end) { + assert_always(); + return vec128_t(); + } + if (is_hex) { + for (size_t i = 0; i < 4; i++) { + while (p != end && (*p == ' ' || *p == ',')) { + ++p; + } + if (p == end) { + assert_always(); + return vec128_t(); + } + auto result = std::from_chars(p, end, v.u32[i], 16); + if (result.ec != std::errc()) { + assert_always(); + return vec128_t(); + } + p = result.ptr; + } + } else { + for (size_t i = 0; i < 4; i++) { + while (p != end && (*p == ' ' || *p == ',')) { + ++p; + } + if (p == end) { + assert_always(); + return vec128_t(); + } +#if REX_LACKS_FLOAT_FROM_CHARS + char* next_p; + v.f32[i] = std::strtof(p, &next_p); + p = next_p; +#else + auto result = std::from_chars(p, end, v.f32[i], std::chars_format::general); + if (result.ec != std::errc()) { + assert_always(); + return vec128_t(); + } + p = result.ptr; +#endif + } + } + return v; +} + +} // namespace rex::string diff --git a/include/rex/system.h b/include/rex/system.h new file mode 100644 index 0000000..337bd8b --- /dev/null +++ b/include/rex/system.h @@ -0,0 +1,40 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +#include +#include + +namespace rex { + +#if REX_PLATFORM_ANDROID +bool InitializeAndroidSystemForApplicationContext(); +void ShutdownAndroidSystem(); +#endif + +// The URL must include the protocol. +void LaunchWebBrowser(const std::string_view url); +void LaunchFileExplorer(const std::filesystem::path& path); + +enum class SimpleMessageBoxType { + Help, + Warning, + Error, +}; + +// This is expected to block the caller until the message box is closed. +void ShowSimpleMessageBox(SimpleMessageBoxType type, std::string_view message); + +} // namespace rex diff --git a/include/rex/system/binary_types.h b/include/rex/system/binary_types.h new file mode 100644 index 0000000..63a4b7b --- /dev/null +++ b/include/rex/system/binary_types.h @@ -0,0 +1,38 @@ +/** + * @file runtime/binary_types.h + * @brief Types for binary introspection (symbols, sections) + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include + +namespace rex::runtime { + +enum class BinarySymbolType { Function, Data, Import, Unknown }; + +struct BinarySymbol { + std::string name; + uint32_t address = 0; + uint32_t size = 0; + BinarySymbolType type = BinarySymbolType::Unknown; +}; + +struct BinarySection { + std::string name; + uint32_t virtual_address = 0; + uint32_t virtual_size = 0; + const uint8_t* host_data = nullptr; // Pointer to data in host memory + bool executable = false; + bool writable = false; +}; + +} // namespace rex::runtime diff --git a/include/rex/system/elf_module.h b/include/rex/system/elf_module.h new file mode 100644 index 0000000..ab8dd2d --- /dev/null +++ b/include/rex/system/elf_module.h @@ -0,0 +1,55 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include + +namespace rex::system { +class KernelState; +} // namespace rex::system + +namespace rex::runtime { + +// ELF module: Used to load libxenon executables. +class ElfModule : public Module { + public: + ElfModule(FunctionDispatcher* function_dispatcher, rex::system::KernelState* kernel_state); + virtual ~ElfModule(); + + bool loaded() const { return loaded_; } + const std::string& name() const override { return name_; } + bool is_executable() const override; + const std::string& path() const { return path_; } + + // Binary introspection overrides + uint32_t base_address() const override { return base_address_; } + uint32_t image_size() const override { return image_size_; } + uint32_t entry_point() const override { return entry_point_; } + + bool Load(const std::string_view name, const std::string_view path, const void* elf_addr, + size_t elf_length); + bool Unload(); + + private: + std::string name_; + std::string path_; + + bool loaded_ = false; + std::vector elf_header_mem_; // Holds the ELF header + uint32_t entry_point_ = 0; + uint32_t base_address_ = 0; + uint32_t image_size_ = 0; +}; + +} // namespace rex::runtime diff --git a/include/rex/system/entry_table.h b/include/rex/system/entry_table.h new file mode 100644 index 0000000..88d3c5f --- /dev/null +++ b/include/rex/system/entry_table.h @@ -0,0 +1,52 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include + +namespace rex::runtime { + +class Function; + +typedef struct Entry_t { + typedef enum { + STATUS_NEW = 0, + STATUS_COMPILING, + STATUS_READY, + STATUS_FAILED, + } Status; + + uint32_t address; + uint32_t end_address; + Status status; + Function* function; +} Entry; + +class EntryTable { + public: + EntryTable(); + ~EntryTable(); + + Entry* Get(uint32_t address); + Entry::Status GetOrCreate(uint32_t address, Entry** out_entry); + + std::vector FindWithAddress(uint32_t address); + + private: + rex::thread::global_critical_region global_critical_region_; + // TODO(benvanik): replace with a better data structure. + std::unordered_map map_; +}; + +} // namespace rex::runtime diff --git a/include/rex/system/export_resolver.h b/include/rex/system/export_resolver.h new file mode 100644 index 0000000..82646be --- /dev/null +++ b/include/rex/system/export_resolver.h @@ -0,0 +1,133 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include + +namespace rex::runtime { + +enum class ExportCategory : uint8_t { + kNone = 0, + kAudio, + kAvatars, + kContent, + kDebug, + kFileSystem, + kInput, + kLocale, + kMemory, + kMisc, + kModules, + kNetworking, + kThreading, + kUI, + kUserProfiles, + kVideo, +}; + +struct ExportTag { + using type = uint32_t; + + // packed like so: + // ll...... cccccccc ........ ..bihssi + + static const int CategoryShift = 16; + + // Export is implemented in some form and can be used. + static const type kImplemented = 1u << 0; + // Export is a stub and is probably bad. + static const type kStub = 1u << 1; + // Export is known to cause problems, or may not be complete. + static const type kSketchy = 1u << 2; + // Export is called *a lot*. + static const type kHighFrequency = 1u << 3; + // Export is important and should always be logged. + static const type kImportant = 1u << 4; + // Export blocks the calling thread + static const type kBlocking = 1u << 5; + + // Export will be logged on each call. + static const type kLog = 1u << 30; + // Export's result will be logged on each call. + static const type kLogResult = 1u << 31; +}; + +class Export { + public: + enum class Type { + kFunction = 0, + kVariable = 1, + }; + + Export(uint16_t ordinal, Type type, const char* name, ExportTag::type tags = 0) + : ordinal(ordinal), type(type), tags(tags), function_data({0}) { + rex::string::rex_strcpy(this->name, rex::countof(this->name), name); + } + + uint16_t ordinal; + Type type; + char name[96]; + ExportTag::type tags; + + bool is_implemented() const { + return (tags & ExportTag::kImplemented) == ExportTag::kImplemented; + } + + union { + // Variable data. Only valid when type == kVariable. + // This is an address in the guest memory space where the variable can + // be found at. + uint32_t variable_ptr; + + struct { + // Function data (not used in recompiled builds, but kept for structure) + uint64_t call_count; + } function_data; + }; +}; +class ExportResolver { + public: + class Table { + public: + Table(const std::string_view module_name, const std::vector* exports); + + const std::string& module_name() const { return module_name_; } + const std::vector& exports_by_ordinal() const { return *exports_by_ordinal_; } + const std::vector& exports_by_name() const { return exports_by_name_; } + + private: + std::string module_name_; + const std::vector* exports_by_ordinal_ = nullptr; + std::vector exports_by_name_; + }; + + ExportResolver(); + ~ExportResolver(); + + void RegisterTable(const std::string_view module_name, const std::vector* exports); + const std::vector& tables() const { return tables_; } + const std::vector& all_exports_by_name() const { return all_exports_by_name_; } + + Export* GetExportByOrdinal(const std::string_view module_name, uint16_t ordinal); + + void SetVariableMapping(const std::string_view module_name, uint16_t ordinal, uint32_t value); + + private: + std::vector
tables_; + std::vector all_exports_by_name_; +}; + +} // namespace rex::runtime diff --git a/include/rex/system/flags.h b/include/rex/system/flags.h new file mode 100644 index 0000000..b9e2f58 --- /dev/null +++ b/include/rex/system/flags.h @@ -0,0 +1,31 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +REXCVAR_DECLARE(bool, headless); +REXCVAR_DECLARE(bool, log_high_frequency_kernel_calls); +REXCVAR_DECLARE(bool, xex_apply_patches); +REXCVAR_DECLARE(uint32_t, license_mask); +REXCVAR_DECLARE(uint32_t, user_country); +REXCVAR_DECLARE(uint32_t, user_language); +REXCVAR_DECLARE(bool, kernel_pix); +REXCVAR_DECLARE(std::string, cl); +REXCVAR_DECLARE(bool, kernel_debug_monitor); +REXCVAR_DECLARE(bool, kernel_cert_monitor); +REXCVAR_DECLARE(bool, ignore_thread_priorities); +REXCVAR_DECLARE(bool, ignore_thread_affinities); +REXCVAR_DECLARE(bool, writable_executable_memory); +REXCVAR_DECLARE(bool, protect_zero); +REXCVAR_DECLARE(bool, protect_on_release); +REXCVAR_DECLARE(bool, scribble_heap); diff --git a/include/rex/system/format.h b/include/rex/system/format.h new file mode 100644 index 0000000..bb0d9ac --- /dev/null +++ b/include/rex/system/format.h @@ -0,0 +1,841 @@ +/** + * @file kernel/format.h + * @brief PPC printf format engine for kernel string exports + * + * @copyright Copyright (c) 2026 Tom Clay + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + * + * @remarks Based on Xenia's format_core + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace rex::system::format { + +enum FormatState { + FS_Invalid = 0, + FS_Unknown, + FS_Start, + FS_Flags, + FS_Width, + FS_PrecisionStart, + FS_Precision, + FS_Size, + FS_Type, + FS_End, +}; + +enum FormatFlags { + FF_LeftJustify = 1 << 0, + FF_AddLeadingZeros = 1 << 1, + FF_AddPositive = 1 << 2, + FF_AddPositiveAsSpace = 1 << 3, + FF_AddNegative = 1 << 4, + FF_AddPrefix = 1 << 5, + FF_IsShort = 1 << 6, + FF_IsLong = 1 << 7, + FF_IsLongLong = 1 << 8, + FF_IsWide = 1 << 9, + FF_IsSigned = 1 << 10, + FF_ForceLeadingZero = 1 << 11, + FF_InvertWide = 1 << 12, +}; + +enum ArgumentSize { + AS_Default = 0, + AS_Short, + AS_Long, + AS_LongLong, +}; + +//============================================================================= +// Concepts +//============================================================================= +template +concept FormatDataSource = requires(T& t, int32_t n, uint16_t c) { + { t.get() } -> std::same_as; + { t.peek(n) } -> std::same_as; + { t.skip(n) } -> std::same_as; + { t.put(c) } -> std::same_as; +}; + +template +concept ArgListSource = requires(T& t) { + { t.get32() } -> std::same_as; + { t.get64() } -> std::same_as; +}; + +//============================================================================= +// format_double helper +//============================================================================= +inline std::string format_double(double value, int32_t precision, uint16_t c, uint32_t flags) { + if (precision < 0) { + precision = 6; + } else if (precision == 0 && c == 'g') { + precision = 1; + } + + std::ostringstream temp; + temp << std::setprecision(precision); + + if (c == 'f') { + temp << std::fixed; + } else if (c == 'e' || c == 'E') { + temp << std::scientific; + } else if (c == 'a' || c == 'A') { + temp << std::hexfloat; + } else if (c == 'g' || c == 'G') { + temp << std::defaultfloat; + } + + if (c == 'E' || c == 'G' || c == 'A') { + temp << std::uppercase; + } + + if (flags & FF_AddPrefix) { + temp << std::showpoint; + } + + temp << value; + return temp.str(); +} + +//============================================================================= +// StackArgList — reads variadic args from PPC registers/stack +//============================================================================= +// For sprintf, _snprintf, DbgPrint, etc. where varargs follow fixed params. +// Xbox 360 PPC has 64-bit GPRs. Variadic args in r3-r10, then stack at +// r1+0x54 in 8-byte slots. +class StackArgList { + public: + StackArgList(PPCContext& ctx, uint8_t* base, int32_t start_index) + : ctx_(ctx), base_(base), index_(start_index) {} + + uint32_t get32() { return static_cast(get64()); } + + uint64_t get64() { + uint64_t value; + if (index_ <= 7) { + switch (index_) { + case 0: + value = ctx_.r3.u64; + break; + case 1: + value = ctx_.r4.u64; + break; + case 2: + value = ctx_.r5.u64; + break; + case 3: + value = ctx_.r6.u64; + break; + case 4: + value = ctx_.r7.u64; + break; + case 5: + value = ctx_.r8.u64; + break; + case 6: + value = ctx_.r9.u64; + break; + case 7: + value = ctx_.r10.u64; + break; + default: + value = 0; + break; + } + } else { + // Stack arguments: 8-byte big-endian values at r1 + 0x54 + ((index - 8) * 8) + uint32_t stack_addr = ctx_.r1.u32 + 0x54 + ((index_ - 8) * 8); + value = static_cast(*rex::memory::GuestPtr*>(base_, stack_addr)); + } + ++index_; + return value; + } + + private: + PPCContext& ctx_; + uint8_t* base_; + int32_t index_; +}; + +//============================================================================= +// ArrayArgList — reads from guest va_list (8-byte-aligned array in memory) +//============================================================================= +// For vsprintf, _vsnprintf, etc. where a va_list pointer is passed. +// On Xbox 360, va_list is a pointer to an array of 8-byte-aligned values. +class ArrayArgList { + public: + ArrayArgList(uint8_t* base, uint32_t arg_ptr) : base_(base), arg_ptr_(arg_ptr), index_(0) {} + + uint32_t get32() { return static_cast(get64()); } + + uint64_t get64() { + uint32_t addr = arg_ptr_ + (8 * index_); + uint64_t value = static_cast(*rex::memory::GuestPtr*>(base_, addr)); + ++index_; + return value; + } + + private: + uint8_t* base_; + uint32_t arg_ptr_; + int32_t index_; +}; + +//============================================================================= +// StringFormatData — narrow char format string I/O +//============================================================================= +class StringFormatData { + public: + explicit StringFormatData(const uint8_t* input) : input_(input) {} + + uint16_t get() { + uint16_t result = *input_; + if (result) { + input_++; + } + return result; + } + + uint16_t peek(int32_t offset) { return input_[offset]; } + + void skip(int32_t count) { + while (count-- > 0) { + if (!get()) { + break; + } + } + } + + bool put(uint16_t c) { + if (c >= 0x100) { + return false; + } + output_.push_back(char(c)); + return true; + } + + const std::string& str() const { return output_; } + + private: + const uint8_t* input_; + std::string output_; +}; + +//============================================================================= +// WideStringFormatData — wide (char16_t) format string I/O +//============================================================================= +class WideStringFormatData { + public: + explicit WideStringFormatData(const uint16_t* input) : input_(input) {} + + uint16_t get() { + uint16_t result = *input_; + if (result) { + input_++; + } + return rex::byte_swap(result); + } + + uint16_t peek(int32_t offset) { return rex::byte_swap(input_[offset]); } + + void skip(int32_t count) { + while (count-- > 0) { + if (!get()) { + break; + } + } + } + + bool put(uint16_t c) { + output_.push_back(char16_t(c)); + return true; + } + + const std::u16string& wstr() const { return output_; } + + private: + const uint16_t* input_; + std::u16string output_; +}; + +//============================================================================= +// WideCountFormatData — counts wide output without storing +//============================================================================= +class WideCountFormatData { + public: + explicit WideCountFormatData(const uint16_t* input) : input_(input), count_(0) {} + + uint16_t get() { + uint16_t result = *input_; + if (result) { + input_++; + } + return rex::byte_swap(result); + } + + uint16_t peek(int32_t offset) { return rex::byte_swap(input_[offset]); } + + void skip(int32_t count) { + while (count-- > 0) { + if (!get()) { + break; + } + } + } + + bool put(uint16_t c) { + ++count_; + return true; + } + + int32_t count() const { return count_; } + + private: + const uint16_t* input_; + int32_t count_; +}; + +//============================================================================= +// format_core — printf format string state machine +//============================================================================= +// Reference: https://msdn.microsoft.com/en-us/library/56e442dc.aspx +template +int32_t format_core(uint8_t* base, Data& data, Args& args, const bool wide) { + int32_t count = 0; + + char work8[512]; + char16_t work16[4]; + + struct { + const void* buffer; + int32_t length; + bool is_wide; + bool swap_wide; + } text; + + struct { + char buffer[2]; + int32_t length; + } prefix; + + auto state = FS_Unknown; + uint32_t flags = 0; + int32_t width = 0; + int32_t precision = -1; + [[maybe_unused]] ArgumentSize size = AS_Default; + int32_t radix = 0; + const char* digits = nullptr; + + text.buffer = nullptr; + text.is_wide = false; + text.swap_wide = true; + text.length = 0; + prefix.buffer[0] = '\0'; + prefix.length = 0; + + for (uint16_t c = data.get();; c = data.get()) { + if (state == FS_Unknown) { + if (!c) { // the end + return count; + } else if (c != '%') { + output: + if (!data.put(c)) { + return -1; + } + ++count; + continue; + } + + state = FS_Start; + c = data.get(); + // fall through + } + + // in any state, if c is \0, it's bad + if (!c) { + return -1; + } + + restart: + switch (state) { + case FS_Invalid: + case FS_Unknown: + case FS_End: + default: { + assert_always(); + } + + case FS_Start: { + if (c == '%') { + state = FS_Unknown; + goto output; + } + + state = FS_Flags; + + // reset to defaults + flags = 0; + width = 0; + precision = -1; + size = AS_Default; + radix = 0; + digits = nullptr; + + text.buffer = nullptr; + text.is_wide = false; + text.swap_wide = true; + text.length = 0; + prefix.buffer[0] = '\0'; + prefix.length = 0; + + // fall through, don't need to goto restart + } + + case FS_Flags: { + if (c == '-') { + flags |= FF_LeftJustify; + continue; + } else if (c == '+') { + flags |= FF_AddPositive; + continue; + } else if (c == '0') { + flags |= FF_AddLeadingZeros; + continue; + } else if (c == ' ') { + flags |= FF_AddPositiveAsSpace; + continue; + } else if (c == '#') { + flags |= FF_AddPrefix; + continue; + } + state = FS_Width; + // fall through + } + + case FS_Width: { + if (c == '*') { + width = (int32_t)args.get32(); + if (width < 0) { + flags |= FF_LeftJustify; + width = -width; + } + state = FS_PrecisionStart; + continue; + } else if (c >= '0' && c <= '9') { + width *= 10; + width += c - '0'; + continue; + } + state = FS_PrecisionStart; + // fall through + } + + case FS_PrecisionStart: { + if (c == '.') { + state = FS_Precision; + precision = 0; + continue; + } + state = FS_Size; + goto restart; + } + + case FS_Precision: { + if (c == '*') { + precision = (int32_t)args.get32(); + if (precision < 0) { + precision = -1; + } + state = FS_Size; + continue; + } else if (c >= '0' && c <= '9') { + precision *= 10; + precision += c - '0'; + continue; + } + state = FS_Size; + // fall through + } + + case FS_Size: { + if (c == 'l') { + if (data.peek(0) == 'l') { + data.skip(1); + flags |= FF_IsLongLong; + } else { + flags |= FF_IsLong; + } + state = FS_Type; + continue; + } else if (c == 'L') { + state = FS_Type; + continue; + } else if (c == 'h') { + flags |= FF_IsShort; + state = FS_Type; + continue; + } else if (c == 'w') { + flags |= FF_IsWide; + state = FS_Type; + continue; + } else if (c == 'I') { + if (data.peek(0) == '6' && data.peek(1) == '4') { + data.skip(2); + flags |= FF_IsLongLong; + state = FS_Type; + continue; + } else if (data.peek(0) == '3' && data.peek(1) == '2') { + data.skip(2); + state = FS_Type; + continue; + } else { + state = FS_Type; + continue; + } + } + // fall through + } + + case FS_Type: { + switch (c) { + case 'C': { + flags |= FF_InvertWide; + [[fallthrough]]; + } + + case 'c': { + bool is_wide; + if (flags & (FF_IsLong | FF_IsWide)) { + is_wide = true; + } else if (flags & FF_IsShort) { + is_wide = false; + } else { + is_wide = ((flags & FF_InvertWide) != 0) ^ wide; + } + + auto value = args.get32(); + + if (!is_wide) { + work8[0] = (uint8_t)value; + text.buffer = &work8[0]; + text.length = 1; + text.is_wide = false; + } else { + work16[0] = (uint16_t)value; + text.buffer = &work16[0]; + text.length = 1; + text.is_wide = true; + text.swap_wide = false; + } + + break; + } + + case 'd': + case 'i': { + flags |= FF_IsSigned; + digits = "0123456789"; + radix = 10; + + integer: + assert_not_null(digits); + assert_not_zero(radix); + + int64_t value; + + if (flags & FF_IsLongLong) { + value = (int64_t)args.get64(); + } else if (flags & FF_IsLong) { + value = (int32_t)args.get32(); + } else if (flags & FF_IsShort) { + value = (int16_t)args.get32(); + } else { + value = (int32_t)args.get32(); + } + + if (precision >= 0) { + precision = std::min(precision, (int32_t)std::size(work8)); + } else { + precision = 1; + } + + if ((flags & FF_IsSigned) && value < 0) { + value = -value; + flags |= FF_AddNegative; + } + + if (!(flags & FF_IsLongLong)) { + value &= UINT32_MAX; + } + + if (value == 0) { + prefix.length = 0; + } + + char* end = &work8[std::size(work8) - 1]; + char* start = end; + start[0] = '\0'; + + while (precision-- > 0 || value != 0) { + auto digit = (int32_t)(value % radix); + value /= radix; + assert_true(digit < (int32_t)strlen(digits)); + *--start = digits[digit]; + } + + if ((flags & FF_ForceLeadingZero) && (start == end || *start != '0')) { + *--start = '0'; + } + + text.buffer = start; + text.length = (int32_t)(end - start); + text.is_wide = false; + break; + } + + case 'o': { + digits = "01234567"; + radix = 8; + if (flags & FF_AddPrefix) { + flags |= FF_ForceLeadingZero; + } + goto integer; + } + + case 'u': { + digits = "0123456789"; + radix = 10; + goto integer; + } + + case 'x': + case 'X': { + digits = c == 'x' ? "0123456789abcdef" : "0123456789ABCDEF"; + radix = 16; + + if (flags & FF_AddPrefix) { + prefix.buffer[0] = '0'; + prefix.buffer[1] = c == 'x' ? 'x' : 'X'; + prefix.length = 2; + } + + goto integer; + } + + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + case 'a': + case 'A': { + flags |= FF_IsSigned; + + int64_t dummy = args.get64(); + double value; + std::memcpy(&value, &dummy, sizeof(double)); + + if (value < 0) { + value = -value; + flags |= FF_AddNegative; + } + + auto s = format_double(value, precision, c, flags); + auto length = (int32_t)s.size(); + assert_true(length < (int32_t)std::size(work8)); + + auto fstart = &work8[0]; + auto fend = &fstart[length]; + + std::memcpy(fstart, s.c_str(), length); + fend[0] = '\0'; + + text.buffer = fstart; + text.length = (int32_t)(fend - fstart); + text.is_wide = false; + break; + } + + // %n: write character count to guest memory + case 'n': { + auto pointer = (uint32_t)args.get32(); + if (flags & FF_IsShort) { + *rex::memory::GuestPtr*>(base, pointer) = (u16)count; + } else { + *rex::memory::GuestPtr*>(base, pointer) = (u32)count; + } + continue; + } + + case 'p': { + digits = "0123456789ABCDEF"; + radix = 16; + precision = 8; + flags &= ~(FF_IsLongLong | FF_IsShort); + flags |= FF_IsLong; + goto integer; + } + + case 'S': { + flags |= FF_InvertWide; + [[fallthrough]]; + } + + case 's': { + uint32_t pointer = args.get32(); + int32_t cap = precision < 0 ? INT32_MAX : precision; + + if (pointer == 0) { + auto nullstr = "(null)"; + text.buffer = nullstr; + text.length = std::min((int32_t)strlen(nullstr), cap); + text.is_wide = false; + } else { + void* str = rex::memory::GuestPtr(base, pointer); + bool is_wide; + if (flags & (FF_IsLong | FF_IsWide)) { + is_wide = true; + } else if (flags & FF_IsShort) { + is_wide = false; + } else { + is_wide = ((flags & FF_InvertWide) != 0) ^ wide; + } + int32_t length; + + if (!is_wide) { + length = 0; + for (auto s = (const uint8_t*)str; cap > 0 && *s; ++s, cap--) { + length++; + } + } else { + length = 0; + for (auto s = (const uint16_t*)str; cap > 0 && *s; ++s, cap--) { + length++; + } + } + + text.buffer = str; + text.length = length; + text.is_wide = is_wide; + } + break; + } + + // ANSI_STRING / UNICODE_STRING (not implemented) + case 'Z': { + assert_always(); + break; + } + + default: { + assert_always(); + } + } + } + } + + if (flags & FF_IsSigned) { + if (flags & FF_AddNegative) { + prefix.buffer[0] = '-'; + prefix.length = 1; + } else if (flags & FF_AddPositive) { + prefix.buffer[0] = '+'; + prefix.length = 1; + } else if (flags & FF_AddPositiveAsSpace) { + prefix.buffer[0] = ' '; + prefix.length = 1; + } + } + + int32_t padding = width - text.length - prefix.length; + + if (!(flags & (FF_LeftJustify | FF_AddLeadingZeros)) && padding > 0) { + count += padding; + while (padding-- > 0) { + if (!data.put(' ')) { + return -1; + } + } + } + + if (prefix.length > 0) { + int32_t remaining = prefix.length; + count += prefix.length; + auto b = &prefix.buffer[0]; + while (remaining-- > 0) { + if (!data.put(*b++)) { + return -1; + } + } + } + + if ((flags & FF_AddLeadingZeros) && !(flags & (FF_LeftJustify)) && padding > 0) { + count += padding; + while (padding-- > 0) { + if (!data.put('0')) { + return -1; + } + } + } + + int32_t remaining = text.length; + if (!text.is_wide) { + auto b = (const uint8_t*)text.buffer; + while (remaining-- > 0) { + if (!data.put(*b++)) { + return -1; + } + } + } else { + auto b = (const uint16_t*)text.buffer; + if (text.swap_wide) { + while (remaining-- > 0) { + if (!data.put(rex::byte_swap(*b++))) { + return -1; + } + } + } else { + while (remaining-- > 0) { + if (!data.put(*b++)) { + return -1; + } + } + } + } + count += text.length; + + // right padding + if ((flags & FF_LeftJustify) && padding > 0) { + count += padding; + while (padding-- > 0) { + if (!data.put(' ')) { + return -1; + } + } + } + + state = FS_Unknown; + } + + return count; +} + +} // namespace rex::system::format diff --git a/include/rex/system/function.h b/include/rex/system/function.h new file mode 100644 index 0000000..da0ca1d --- /dev/null +++ b/include/rex/system/function.h @@ -0,0 +1,58 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include + +namespace rex::runtime { + +class Module; +class ThreadState; + +class Function : public Symbol { + public: + enum class Behavior { + kDefault = 0, + kProlog, + kEpilog, + kEpilogReturn, + kBuiltin, + kExtern, + }; + + virtual ~Function() = default; + + uint32_t address() const { return address_; } + bool has_end_address() const { return end_address_ > 0; } + uint32_t end_address() const { return end_address_; } + void set_end_address(uint32_t value) { end_address_ = value; } + Behavior behavior() const { return behavior_; } + void set_behavior(Behavior value) { behavior_ = value; } + bool is_guest() const { return behavior_ != Behavior::kBuiltin; } + + bool ContainsAddress(uint32_t addr) const { + if (!address_ || !end_address_) { + return false; + } + return addr >= address_ && addr < end_address_; + } + + protected: + Function(Module* module, uint32_t address) : Symbol(Symbol::Type::kFunction, module, address) {} + + uint32_t end_address_ = 0; + Behavior behavior_ = Behavior::kDefault; +}; + +} // namespace rex::runtime diff --git a/include/rex/system/function_dispatcher.h b/include/rex/system/function_dispatcher.h new file mode 100644 index 0000000..f5d5637 --- /dev/null +++ b/include/rex/system/function_dispatcher.h @@ -0,0 +1,151 @@ +/** + * @file system/function_dispatcher.h + * @brief Guest function dispatch coordinator for recompiled code + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + * + * @remarks Derived from Xenia's runtime::Processor (Ben Vanik, 2020). + * Stripped of emulation-era dead code and renamed to reflect its + * role as a function dispatch table rather than a CPU emulator. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace rex::runtime { + +// Forward declarations +class ExportResolver; +class ThreadState; + +/** + * Narrow registration interface used by generated DLLs. + */ +class IModuleRegistrar { + public: + /** + * Returns false (and logs) if guest_address is outside every module range. + */ + virtual bool SetFunction(uint32_t guest_address, ::PPCFunc* func) = 0; + + protected: + ~IModuleRegistrar() = default; +}; + +class FunctionDispatcher : public IModuleRegistrar { + public: + /** + * Callback type for module registration functions. + */ + using RegisterFn = void (*)(IModuleRegistrar*); + + FunctionDispatcher(memory::Memory* memory, ExportResolver* export_resolver); + ~FunctionDispatcher(); + + memory::Memory* memory() const { return memory_; } + ExportResolver* export_resolver() const { return export_resolver_; } + + uint64_t Execute(ThreadState* thread_state, uint32_t address, uint64_t args[], size_t arg_count); + uint64_t ExecuteInterrupt(ThreadState* thread_state, uint32_t address, uint64_t args[], + size_t arg_count); + + // Shared thunk region size per module. + static constexpr uint32_t kThunkReserveSize = 0x10000; // 64KB + + // rexglue function table management (per-module table at IMAGE_BASE + IMAGE_SIZE) + // Set is_entrypoint=true exactly once for the host-loaded entrypoint so + // AllocateThunk(caller_address=0) can route to its pool. + bool InitializeFunctionTable(uint32_t code_base, uint32_t code_size, uint32_t image_base, + uint32_t image_size, bool is_entrypoint = false); + bool SetFunction(uint32_t guest_address, ::PPCFunc* func) override; + ::PPCFunc* GetFunction(uint32_t guest_address); + bool HasAnyFunctionTable() const { return !module_tables_.empty(); } + /** + * caller_address must be inside a registered module, or 0 to mean "host- + * initiated, route to the entrypoint pool". + */ + uint32_t AllocateThunk(::PPCFunc* func, uint32_t caller_address); + + /** + * Returns the `code_base` of the module containing `guest_address`, + * or 0 if no module covers that address. + */ + uint32_t FindCallerModuleBase(uint32_t guest_address); + + /** + * Register a module while recording guest addresses written via SetFunction. + * `code_base` must equal the value previously passed to InitializeFunctionTable + * for the same module. + */ + void RegisterModule(const std::string& module_id, uint32_t code_base, RegisterFn register_func); + + /** + * Unregister `module_id`: clears its function-table entries, releases its + * thunk pool, and removes its per-module function table. Returns the + * cleared thunk-pool range `[lo, hi)` for external cache invalidation, or + * nullopt if the module was not registered. + */ + std::optional> UnregisterModule(const std::string& module_id); + + private: + bool Execute(ThreadState* thread_state, uint32_t address); + + struct ModuleTableInfo { + uint32_t code_base; + uint32_t code_size; + uint32_t image_base; + uint32_t image_size; + uint32_t next_thunk_address; + uint32_t thunk_limit; + }; + + ModuleTableInfo* FindModuleByAddress(uint32_t guest_address); + + memory::Memory* memory_ = nullptr; + ExportResolver* export_resolver_ = nullptr; + + rex::thread::global_critical_region global_critical_region_; + + // Host-side function lookup. + std::unordered_map function_table_; + + // Per-module function table metadata. + std::vector module_tables_; + + // code_base of the entrypoint module, or 0 if not yet registered. + uint32_t entrypoint_code_base_ = 0; + + // Module recording for RegisterModule/UnregisterModule. + bool recording_ = false; + std::vector recording_addresses_; + + struct ModuleRegistration { + uint32_t code_base; + std::vector addresses; + }; + + // Recorded state per module, keyed by module_id. + std::unordered_map module_addresses_; + + // Protects dispatcher metadata during module registration and callback dispatch. + mutable std::recursive_mutex dispatch_mutex_; +}; + +} // namespace rex::runtime diff --git a/include/rex/system/guest_path.h b/include/rex/system/guest_path.h new file mode 100644 index 0000000..0bd80d9 --- /dev/null +++ b/include/rex/system/guest_path.h @@ -0,0 +1,30 @@ +/** + * @file rex/system/guest_path.h + * @brief Guest path normalization for Xbox 360 VFS paths + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include + +namespace rex::system { + +/** + * Normalize a guest path to the canonical form used as a key for runtime + * lookups: device prefix stripped, separators canonicalized to forward + * slashes, redundant `..` segments resolved, leading slashes removed, + * and ASCII lowercased. Codegen-side canonicalization + * (rex::codegen::CanonicalizeModuleGuestPath) layers a project-scoped prefix + * strip on top of this; both must agree on this base form for runtime + * lookups to find the registered module. + */ +std::string NormalizeGuestPath(std::string_view path); + +} // namespace rex::system diff --git a/include/rex/system/info/file.h b/include/rex/system/info/file.h new file mode 100644 index 0000000..ef0a9ad --- /dev/null +++ b/include/rex/system/info/file.h @@ -0,0 +1,138 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +namespace rex { +namespace system { + +// https://github.com/oukiar/vdash/blob/master/vdash/include/kernel.h +enum X_FILE_INFORMATION_CLASS { + XFileDirectoryInformation = 1, + XFileFullDirectoryInformation, + XFileBothDirectoryInformation, + XFileBasicInformation, + XFileStandardInformation, + XFileInternalInformation, + XFileEaInformation, + XFileAccessInformation, + XFileNameInformation, + XFileRenameInformation, + XFileLinkInformation, + XFileNamesInformation, + XFileDispositionInformation, + XFilePositionInformation, + XFileFullEaInformation, + XFileModeInformation, + XFileAlignmentInformation, + XFileAllInformation, + XFileAllocationInformation, + XFileEndOfFileInformation, + XFileAlternateNameInformation, + XFileStreamInformation, + XFileMountPartitionInformation, + XFileMountPartitionsInformation, + XFilePipeRemoteInformation, + XFileSectorInformation, + XFileXctdCompressionInformation, + XFileCompressionInformation, + XFileObjectIdInformation, + XFileCompletionInformation, + XFileMoveClusterInformation, + XFileIoPriorityInformation, + XFileReparsePointInformation, + XFileNetworkOpenInformation, + XFileAttributeTagInformation, + XFileTrackingInformation, + XFileMaximumInformation +}; + +#pragma pack(push, 1) + +// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_file_basic_information +struct X_FILE_BASIC_INFORMATION { + be creation_time; + be last_access_time; + be last_write_time; + be change_time; + be attributes; +}; +static_assert_size(X_FILE_BASIC_INFORMATION, 0x28); + +// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_file_internal_information +struct X_FILE_INTERNAL_INFORMATION { + be index_number; +}; +static_assert_size(X_FILE_INTERNAL_INFORMATION, 8); + +// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_file_rename_information +struct X_FILE_RENAME_INFORMATION { + be replace_existing; + be root_dir_handle; + X_ANSI_STRING ansi_string; +}; +static_assert_size(X_FILE_RENAME_INFORMATION, 16); + +// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/ns-ntddk-_file_disposition_information +struct X_FILE_DISPOSITION_INFORMATION { + uint8_t delete_file; +}; +static_assert_size(X_FILE_DISPOSITION_INFORMATION, 1); + +// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_file_position_information +struct X_FILE_POSITION_INFORMATION { + be current_byte_offset; +}; +static_assert_size(X_FILE_POSITION_INFORMATION, 8); + +// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/ns-ntddk-_file_end_of_file_information +struct X_FILE_END_OF_FILE_INFORMATION { + be end_of_file; +}; +static_assert_size(X_FILE_END_OF_FILE_INFORMATION, 8); + +// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_file_allocation_information +struct X_FILE_ALLOCATION_INFORMATION { + be allocation_size; +}; +static_assert_size(X_FILE_ALLOCATION_INFORMATION, 8); + +struct X_FILE_XCTD_COMPRESSION_INFORMATION { + be unknown; +}; +static_assert_size(X_FILE_XCTD_COMPRESSION_INFORMATION, 4); + +// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_file_completion_information +struct X_FILE_COMPLETION_INFORMATION { + be handle; + be key; +}; +static_assert_size(X_FILE_COMPLETION_INFORMATION, 8); + +// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_file_network_open_information +struct X_FILE_NETWORK_OPEN_INFORMATION { + be creation_time; + be last_access_time; + be last_write_time; + be change_time; + be allocation_size; + be end_of_file; // size in bytes + be attributes; + be pad; +}; +static_assert_size(X_FILE_NETWORK_OPEN_INFORMATION, 56); + +#pragma pack(pop) + +} // namespace system +} // namespace rex diff --git a/include/rex/system/info/volume.h b/include/rex/system/info/volume.h new file mode 100644 index 0000000..e7e66e1 --- /dev/null +++ b/include/rex/system/info/volume.h @@ -0,0 +1,71 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +namespace rex { +namespace system { + +enum X_FILE_FS_INFORMATION_CLASS { + XFileFsVolumeInformation = 1, + XFileFsSizeInformation = 3, + XFileFsDeviceInformation, + XFileFsAttributeInformation = 5, +}; + +enum X_FILE_DEVICE_TYPE : uint32_t { + FILE_DEVICE_UNKNOWN = 0x00000022, + FILE_DEVICE_EHSTOR = 0x00000046, +}; + +#pragma pack(push, 1) + +// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/ns-ntddk-_file_fs_volume_information +struct X_FILE_FS_VOLUME_INFORMATION { + be creation_time; + be serial_number; + be label_length; + uint8_t supports_objects; + char label[1]; + uint8_t pad[6]; +}; +static_assert_size(X_FILE_FS_VOLUME_INFORMATION, 24); + +// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/ns-ntddk-_file_fs_size_information +struct X_FILE_FS_SIZE_INFORMATION { + be total_allocation_units; + be available_allocation_units; + be sectors_per_allocation_unit; + be bytes_per_sector; +}; +static_assert_size(X_FILE_FS_SIZE_INFORMATION, 24); + +// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_file_fs_attribute_information +struct X_FILE_FS_ATTRIBUTE_INFORMATION { + be attributes; + be component_name_max_length; + be name_length; + char name[1]; + uint8_t pad[3]; +}; +static_assert_size(X_FILE_FS_ATTRIBUTE_INFORMATION, 16); + +struct X_FILE_FS_DEVICE_INFORMATION { + be device_type; + be characteristics; +}; +static_assert_size(X_FILE_FS_DEVICE_INFORMATION, 8); + +#pragma pack(pop) + +} // namespace system +} // namespace rex diff --git a/include/rex/system/interfaces/audio.h b/include/rex/system/interfaces/audio.h new file mode 100644 index 0000000..a934066 --- /dev/null +++ b/include/rex/system/interfaces/audio.h @@ -0,0 +1,29 @@ +/** + * @file system/interfaces/audio.h + * @brief Abstract audio system interface for dependency injection + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include + +namespace rex::system { +class KernelState; +} + +namespace rex::system { + +class IAudioSystem { + public: + virtual ~IAudioSystem() = default; + virtual X_STATUS Setup(KernelState* kernel_state) = 0; + virtual void Shutdown() = 0; +}; + +} // namespace rex::system diff --git a/include/rex/system/interfaces/graphics.h b/include/rex/system/interfaces/graphics.h new file mode 100644 index 0000000..a0ed931 --- /dev/null +++ b/include/rex/system/interfaces/graphics.h @@ -0,0 +1,63 @@ +/** + * @file system/interfaces/graphics.h + * @brief Abstract graphics system interface for dependency injection + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include + +// Forward declarations +namespace rex::runtime { +class FunctionDispatcher; +} +namespace rex::ui { +class WindowedAppContext; +} +namespace rex::system { +class KernelState; +} + +namespace rex::system { + +class IGraphicsSystem { + public: + virtual ~IGraphicsSystem() = default; + + // Build the provider + presenter. Safe to call standalone (without a + // Runtime) to stand up a window + ImGui for an installer. Idempotent. + // Must be called before SetupGuestGpu if presentation is desired: some + // backends (e.g. Vulkan) bake swapchain support into the provider, and + // a headless provider from SetupGuestGpu cannot be upgraded in place. + virtual X_STATUS SetupPresentation(ui::WindowedAppContext* app_context) = 0; + + // Wire the GPU into the guest address space: MMIO, command processor, + // vsync worker. Needs the Runtime's dispatcher + kernel state. If + // SetupPresentation has not been called, a headless provider is built. + virtual X_STATUS SetupGuestGpu(runtime::FunctionDispatcher* function_dispatcher, + KernelState* kernel_state) = 0; + + virtual bool has_presentation() const = 0; + + // One-shot convenience for callers that don't care about the split. + X_STATUS Setup(runtime::FunctionDispatcher* function_dispatcher, KernelState* kernel_state, + ui::WindowedAppContext* app_context, bool with_presentation) { + if (with_presentation && !has_presentation()) { + X_STATUS status = SetupPresentation(app_context); + if (XFAILED(status)) { + return status; + } + } + return SetupGuestGpu(function_dispatcher, kernel_state); + } + + virtual void Shutdown() = 0; +}; + +} // namespace rex::system diff --git a/include/rex/system/interfaces/input.h b/include/rex/system/interfaces/input.h new file mode 100644 index 0000000..6a61743 --- /dev/null +++ b/include/rex/system/interfaces/input.h @@ -0,0 +1,25 @@ +/** + * @file system/interfaces/input.h + * @brief Abstract input system interface for dependency injection + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include + +namespace rex::system { + +class IInputSystem { + public: + virtual ~IInputSystem() = default; + virtual X_STATUS Setup() = 0; + virtual void Shutdown() = 0; +}; + +} // namespace rex::system diff --git a/include/rex/system/kernel_module.h b/include/rex/system/kernel_module.h new file mode 100644 index 0000000..eeffdc1 --- /dev/null +++ b/include/rex/system/kernel_module.h @@ -0,0 +1,68 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include + +namespace rex { +class Runtime; + +namespace system { + +class KernelState; + +class KernelModule : public XModule { + public: + KernelModule(KernelState* kernel_state, const std::string_view path); + ~KernelModule() override; + + const std::string& path() const override { return path_; } + const std::string& name() const override { return name_; } + + uint32_t GetProcAddressByOrdinal(uint16_t ordinal, uint32_t caller_address = 0) override; + uint32_t GetProcAddressByName(const std::string_view name) override; + + /** + * Erase any cached thunks whose guest address falls in [lo, hi). + */ + void InvalidateThunkCacheInRange(uint32_t lo, uint32_t hi); + + protected: + Runtime* emulator_; + memory::Memory* memory_; + rex::runtime::ExportResolver* export_resolver_; + + std::string name_; + std::string path_; + + rex::thread::global_critical_region global_critical_region_; + + // Cache of (caller_module_base, ordinal) -> thunk guest address. + struct ThunkKey { + uint32_t caller_module_base; + uint16_t ordinal; + bool operator==(const ThunkKey& other) const { + return caller_module_base == other.caller_module_base && ordinal == other.ordinal; + } + }; + struct ThunkKeyHash { + std::size_t operator()(const ThunkKey& k) const noexcept { + return std::hash{}((uint64_t(k.caller_module_base) << 16) | k.ordinal); + } + }; + std::unordered_map thunk_cache_; +}; + +} // namespace system +} // namespace rex diff --git a/include/rex/system/kernel_state.h b/include/rex/system/kernel_state.h new file mode 100644 index 0000000..92e7f2f --- /dev/null +++ b/include/rex/system/kernel_state.h @@ -0,0 +1,389 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//============================================================================= +// Kernel Import Trace Helpers +//============================================================================= +// Use these macros for consistent logging of kernel import function calls. +// Example usage: +// REXKRNL_IMPORT_TRACE("NtCreateFile", "path={} options={:#x}", path, opts); +// REXKRNL_IMPORT_RESULT("NtCreateFile", "{:#x}", result); +// REXKRNL_IMPORT_FAIL("NtCreateFile", "path='{}' -> {:#x}", path, result); + +#define REXKRNL_IMPORT_TRACE(name, fmt, ...) REXKRNL_NOISY_TRACE("[" name "] " fmt, ##__VA_ARGS__) + +#define REXKRNL_IMPORT_RESULT(name, fmt, ...) \ + REXKRNL_NOISY_TRACE("[" name "] -> " fmt, ##__VA_ARGS__) + +#define REXKRNL_IMPORT_FAIL(name, fmt, ...) REXKRNL_WARN("[" name "] FAILED: " fmt, ##__VA_ARGS__) + +#define REXKRNL_IMPORT_WARN(name, fmt, ...) REXKRNL_NOISY_DEBUG("[" name "] " fmt, ##__VA_ARGS__) + +//============================================================================= +// Kernel State Access Macros +//============================================================================= +// Convenience macros for accessing the current thread's kernel state and +// subsystems from kernel export (_entry) functions. These use the ThreadState +// bound to the current thread via ThreadState::Bind(). + +#define REX_KERNEL_STATE() (::rex::runtime::current_kernel_state()) +#define REX_KERNEL_MEMORY() (REX_KERNEL_STATE()->memory()) +#define REX_KERNEL_OBJECTS() (REX_KERNEL_STATE()->object_table()) +#define REX_KERNEL_FS() (REX_KERNEL_STATE()->file_system()) + +namespace rex { +class Runtime; +namespace stream { +class ByteStream; +} // namespace stream +namespace runtime { +class FunctionDispatcher; +} // namespace runtime +} // namespace rex + +struct PPCContext; + +namespace rex::system { + +constexpr memory::fourcc_t kKernelSaveSignature = memory::make_fourcc("KRNL"); + +class Dispatcher; +class XHostThread; +class KernelModule; +class XModule; +class XNotifyListener; +class XThread; +class UserModule; + +// (?), used by KeGetCurrentProcessType +constexpr uint32_t X_PROCTYPE_IDLE = 0; +constexpr uint32_t X_PROCTYPE_USER = 1; +constexpr uint32_t X_PROCTYPE_SYSTEM = 2; + +struct X_KPROCESS { + X_KSPINLOCK thread_list_spinlock; // 0x00 + X_LIST_ENTRY thread_list; // 0x04 + rex::be quantum; // 0x0C + rex::be clrdataa_masked_ptr; // 0x10 + rex::be thread_count; // 0x14 + uint8_t unk_18; // 0x18 + uint8_t unk_19; // 0x19 + uint8_t unk_1A; // 0x1A + uint8_t unk_1B; // 0x1B + rex::be kernel_stack_size; // 0x1C + rex::be tls_static_data_address; // 0x20 + rex::be tls_data_size; // 0x24 + rex::be tls_raw_data_size; // 0x28 + rex::be tls_slot_size; // 0x2C + uint8_t is_terminating; // 0x2E + uint8_t process_type; // 0x2F + rex::be tls_slot_bitmap[8]; // 0x30 + rex::be unk_50; // 0x50 + X_LIST_ENTRY unk_54; // 0x54 + rex::be unk_5C; // 0x5C +}; +static_assert_size(X_KPROCESS, 0x60); + +// Keep old name as alias for code that still references it +using ProcessInfoBlock = X_KPROCESS; + +struct X_UNKNOWN_TYPE_REFED { + rex::be field0; + rex::be field4; + rex::be points_to_self; + rex::be points_to_prior; +}; +static_assert_size(X_UNKNOWN_TYPE_REFED, 16); + +struct X_KEVENT; // forward decl, defined in xevent.h + +struct KernelGuestGlobals { + X_OBJECT_TYPE ExThreadObjectType; + X_OBJECT_TYPE ExEventObjectType; + X_OBJECT_TYPE ExMutantObjectType; + X_OBJECT_TYPE ExSemaphoreObjectType; + X_OBJECT_TYPE ExTimerObjectType; + X_OBJECT_TYPE IoCompletionObjectType; + X_OBJECT_TYPE IoDeviceObjectType; + X_OBJECT_TYPE IoFileObjectType; + X_OBJECT_TYPE ObDirectoryObjectType; + X_OBJECT_TYPE ObSymbolicLinkObjectType; + X_UNKNOWN_TYPE_REFED OddObj; + X_KPROCESS idle_process; + X_KPROCESS title_process; + X_KPROCESS system_process; + X_KSPINLOCK dispatcher_lock; + X_KSPINLOCK ob_lock; + X_KSPINLOCK tls_lock; // protects per-process TLS slot allocation bitmap + // UsbdBootEnumerationDoneEvent uses X_DISPATCH_HEADER layout (0x10 bytes) + uint8_t UsbdBootEnumerationDoneEvent[0x10]; +}; + +struct DPCImpersonationScope { + uint8_t previous_irql_; +}; + +struct TerminateNotification { + uint32_t guest_routine; + uint32_t priority; +}; + +/// Host-side metadata for a fiber managed by rexcrt hooks. +struct FiberInfo { + rex::thread::Fiber* host_fiber; ///< Host OS fiber handle + uint32_t uid; ///< Unique identifier + uint32_t guest_context_addr; ///< Guest fiber context buffer address + uint32_t guest_stack_base; ///< Top of guest kernel stack (0 for thread fibers) + uint32_t guest_stack_bottom; ///< Bottom of guest kernel stack (0 for thread fibers) + bool is_thread_fiber; ///< true = ConvertThreadToFiber (don't free guest stack) +}; + +class KernelState { + public: + explicit KernelState(Runtime* emulator); + ~KernelState(); + + static KernelState* shared(); + + Runtime* emulator() const { return emulator_; } + memory::Memory* memory() const { return memory_; } + runtime::FunctionDispatcher* function_dispatcher() const { return function_dispatcher_; } + rex::filesystem::VirtualFileSystem* file_system() const { return file_system_; } + + uint32_t title_id() const; + util::XdbfGameData title_xdbf() const; + util::XdbfGameData module_xdbf(object_ref exec_module) const; + + xam::AppManager* app_manager() const { return app_manager_.get(); } + xam::ContentManager* content_manager() const { return content_manager_.get(); } + xam::UserProfile* user_profile() const { return user_profile_.get(); } + + // Access must be guarded by the global critical region. + util::ObjectTable* object_table() { return &object_table_; } + + uint32_t process_type() const; + void set_process_type(uint32_t value); + uint32_t process_info_block_address() const { + return kernel_guest_globals_ + ? kernel_guest_globals_ + offsetof(KernelGuestGlobals, title_process) + : 0; + } + + uint32_t GetKernelGuestGlobals() const { return kernel_guest_globals_; } + + uint32_t GetTitleProcess() const { + return kernel_guest_globals_ + offsetof(KernelGuestGlobals, title_process); + } + uint32_t GetSystemProcess() const { + return kernel_guest_globals_ + offsetof(KernelGuestGlobals, system_process); + } + uint32_t GetIdleProcess() const { + return kernel_guest_globals_ + offsetof(KernelGuestGlobals, idle_process); + } + + DPCImpersonationScope BeginDPCImpersonation(); + void EndDPCImpersonation(const DPCImpersonationScope& scope); + + uint32_t AllocateTLS(PPCContext* context); + void FreeTLS(PPCContext* context, uint32_t slot); + + void RegisterTitleTerminateNotification(uint32_t routine, uint32_t priority); + void RemoveTitleTerminateNotification(uint32_t routine); + + void RegisterModule(XModule* module); + void UnregisterModule(XModule* module); + bool RegisterUserModule(object_ref module); + void UnregisterUserModule(UserModule* module); + bool IsKernelModule(const std::string_view name); + object_ref GetModule(const std::string_view name, bool user_only = false); + + object_ref LaunchModule(object_ref module); + object_ref PrepareModuleLaunch(object_ref module); + object_ref GetExecutableModule(); + void SetExecutableModule(object_ref module); + object_ref LoadUserModule(const std::string_view name, bool call_entry = true); + void UnloadUserModule(const object_ref& module, bool call_entry = true); + + // Recompiled module registry (populated by generated RegisterRecompiledModules) + struct RecompiledModuleInfo { + std::string pe_name; + std::string guest_path; + std::string shared_lib_name; + }; + + void RegisterRecompiledModule(const char* pe_name, const char* guest_path, + const char* shared_lib_name); + std::optional FindRecompiledModule(std::string_view guest_path); + + object_ref GetKernelModule(const std::string_view name); + template + object_ref LoadKernelModule() { + auto kernel_module = object_ref(new T(emulator_, this)); + LoadKernelModule(kernel_module); + return kernel_module; + } + template + object_ref GetKernelModule(const std::string_view name) { + auto module = GetKernelModule(name); + return object_ref(reinterpret_cast(module.release())); + } + + // Terminates a title: Unloads all modules, and kills all guest threads. + // This DOES NOT RETURN if called from a guest thread! + void TerminateTitle(); + + void RegisterThread(XThread* thread); + void UnregisterThread(XThread* thread); + void OnThreadExecute(XThread* thread); + void OnThreadExit(XThread* thread); + object_ref GetThreadByID(uint32_t thread_id); + + FiberInfo* LookupFiber(uint32_t guest_addr); + void RegisterFiber(uint32_t guest_addr, const FiberInfo& info); + void UnregisterFiber(uint32_t guest_addr); + + /// Returns a fiber name for profiling + const char* GetOrCreateFiberName(uint32_t guest_addr, const char* thread_name); + + void RegisterNotifyListener(XNotifyListener* listener); + void UnregisterNotifyListener(XNotifyListener* listener); + void BroadcastNotification(XNotificationID id, uint32_t data); + + util::NativeList* dpc_list() { return &dpc_list_; } + + void CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result); + void CompleteOverlappedEx(uint32_t overlapped_ptr, X_RESULT result, uint32_t extended_error, + uint32_t length); + + void CompleteOverlappedImmediate(uint32_t overlapped_ptr, X_RESULT result); + void CompleteOverlappedImmediateEx(uint32_t overlapped_ptr, X_RESULT result, + uint32_t extended_error, uint32_t length); + + void CompleteOverlappedDeferred(std::function completion_callback, + uint32_t overlapped_ptr, X_RESULT result, + std::function pre_callback = nullptr, + std::function post_callback = nullptr); + void CompleteOverlappedDeferredEx(std::function completion_callback, + uint32_t overlapped_ptr, X_RESULT result, + uint32_t extended_error, uint32_t length, + std::function pre_callback = nullptr, + std::function post_callback = nullptr); + + void CompleteOverlappedDeferred(std::function completion_callback, + uint32_t overlapped_ptr, + std::function pre_callback = nullptr, + std::function post_callback = nullptr); + void CompleteOverlappedDeferredEx( + std::function completion_callback, uint32_t overlapped_ptr, + std::function pre_callback = nullptr, std::function post_callback = nullptr); + + bool Save(stream::ByteStream* stream); + bool Restore(stream::ByteStream* stream); + + private: + void LoadKernelModule(object_ref kernel_module); + void InitializeProcess(X_KPROCESS* process, uint32_t process_type, uint8_t unk_18, uint8_t unk_19, + uint8_t unk_1A); + void SetProcessTLSVars(X_KPROCESS* process, uint32_t num_slots, uint32_t tls_data_size, + uint32_t tls_raw_data_address); + + Runtime* emulator_; + memory::Memory* memory_; + runtime::FunctionDispatcher* function_dispatcher_; + rex::filesystem::VirtualFileSystem* file_system_; + + std::unique_ptr app_manager_; + std::unique_ptr content_manager_; + std::unique_ptr user_profile_; + + rex::thread::global_critical_region global_critical_region_; + + // Must be guarded by the global critical region. + util::ObjectTable object_table_; + std::unordered_map threads_by_id_; + std::vector> notify_listeners_; + bool has_notified_startup_ = false; + + // Protected by global_critical_region_. + std::unordered_map fiber_map_; + + // Fiber name pool for profiling. + // Never erased, Tracy references pointers async. + std::mutex fiber_name_pool_mutex_; + std::unordered_map> fiber_name_pool_; + + uint32_t process_type_ = X_PROCTYPE_USER; + object_ref executable_module_; + std::vector> kernel_modules_; + std::vector> user_modules_; + // Paths in-flight in LoadUserModule. Guarded by the global critical region. + std::unordered_set loading_paths_; + std::vector terminate_notifications_; + std::vector recompiled_modules_; + std::unordered_map module_libraries_; + // FreeLibrary deferred to teardown so guest threads still in unloaded code + // don't return into freed pages. Drained at the end of ~KernelState. + std::vector deferred_unload_libraries_; + + uint32_t kernel_guest_globals_ = 0; + + std::atomic dispatch_thread_running_; + object_ref dispatch_thread_; + // Must be guarded by the global critical region. + util::NativeList dpc_list_; + std::condition_variable_any dispatch_cond_; + std::list> dispatch_queue_; + + friend class XObject; +}; + +// Global kernel state accessor (defined in kernel_state.cpp) +KernelState* kernel_state(); + +// Convenience accessor for kernel memory +inline memory::Memory* kernel_memory() { + return kernel_state()->memory(); +} + +} // namespace rex::system diff --git a/include/rex/system/lzx.h b/include/rex/system/lzx.h new file mode 100644 index 0000000..a310bad --- /dev/null +++ b/include/rex/system/lzx.h @@ -0,0 +1,26 @@ +/** + * @file runtime/lzx.h + * @brief LZX decompression interface for XEX loading + * + * @copyright Copyright 2022 Ben Vanik. All rights reserved. (Xenia Project) + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +namespace rex { +struct xex2_delta_patch; +} // namespace rex + +int lzx_decompress(const void* lzx_data, size_t lzx_len, void* dest, size_t dest_len, + uint32_t window_size, void* window_data, size_t window_data_len); + +int lzxdelta_apply_patch(rex::xex2_delta_patch* patch, size_t patch_len, uint32_t window_size, + void* dest); diff --git a/include/rex/system/map_parser.h b/include/rex/system/map_parser.h new file mode 100644 index 0000000..732b2f1 --- /dev/null +++ b/include/rex/system/map_parser.h @@ -0,0 +1,91 @@ +/** + * @file runtime/map_parser.h + * @brief Utilities for parsing symbol map files + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include + +namespace rex::runtime { + +/** + * Options for parsing map files. + */ +struct MapParseOptions { + /// Base address to add to all symbol addresses (for relative maps) + uint32_t base_address = 0; + + /// If true, only parse symbols that look like functions + bool functions_only = false; + + /// If non-empty, only include symbols whose names start with this prefix + std::string_view prefix_filter; +}; + +/** + * Error types for map parsing operations. + */ +enum class MapParseError { FileNotFound, FileReadError, InvalidFormat, Empty }; + +/** + * Get a human-readable string for a MapParseError. + */ +constexpr std::string_view to_string(MapParseError error) { + switch (error) { + case MapParseError::FileNotFound: + return "File not found"; + case MapParseError::FileReadError: + return "Failed to read file"; + case MapParseError::InvalidFormat: + return "Invalid map format"; + case MapParseError::Empty: + return "No symbols found"; + } + return "Unknown error"; +} + +/** + * Parse an nm-style map file (format: "address type name"). + * + * This is the format produced by `nm` on Unix systems: + * 00000000 t test_add1 + * 00000010 T test_sub1 + * + * Symbol types: + * T/t = text (code) + * D/d = data + * B/b = bss + * U = undefined + * + * @param map_path Path to the .map file + * @param options Parsing options (base address, filters) + * @return Vector of parsed symbols or error + */ +std::expected, MapParseError> ParseNmMap( + const std::filesystem::path& map_path, const MapParseOptions& options = {}); + +/** + * Parse nm-style map data from a string. + * + * @param map_data Map file contents as a string + * @param options Parsing options + * @return Vector of parsed symbols or error + */ +std::expected, MapParseError> ParseNmMapString( + std::string_view map_data, const MapParseOptions& options = {}); + +} // namespace rex::runtime diff --git a/include/rex/system/mmio_handler.h b/include/rex/system/mmio_handler.h new file mode 100644 index 0000000..7ae42a8 --- /dev/null +++ b/include/rex/system/mmio_handler.h @@ -0,0 +1,148 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include + +#include +#include + +namespace rex::arch { +class Exception; +class HostThreadContext; +} // namespace rex::arch + +namespace rex::runtime { + +typedef uint32_t (*MMIOReadCallback)(void* ppc_context, void* callback_context, uint32_t addr); +typedef void (*MMIOWriteCallback)(void* ppc_context, void* callback_context, uint32_t addr, + uint32_t value); + +struct MMIORange { + uint32_t address; + uint32_t mask; + uint32_t size; + void* callback_context; + MMIOReadCallback read; + MMIOWriteCallback write; +}; + +// NOTE: only one can exist at a time! +class MMIOHandler { + public: + virtual ~MMIOHandler(); + + typedef uint32_t (*HostToGuestVirtual)(const void* context, const void* host_address); + typedef bool (*AccessViolationCallback)( + std::unique_lock global_lock_locked_once, void* context, + void* host_address, bool is_write); + + // access_violation_callback is called with global_critical_region locked once + // on the thread, so if multiple threads trigger an access violation in the + // same page, the callback will be called only once. + static std::unique_ptr Install(uint8_t* virtual_membase, uint8_t* physical_membase, + uint8_t* membase_end, + HostToGuestVirtual host_to_guest_virtual, + const void* host_to_guest_virtual_context, + AccessViolationCallback access_violation_callback, + void* access_violation_callback_context); + static MMIOHandler* global_handler(); + + bool RegisterRange(uint32_t virtual_address, uint32_t mask, uint32_t size, void* context, + MMIOReadCallback read_callback, MMIOWriteCallback write_callback); + MMIORange* LookupRange(uint32_t virtual_address); + + bool CheckLoad(uint32_t virtual_address, uint32_t* out_value); + bool CheckStore(uint32_t virtual_address, uint32_t value); + + protected: + MMIOHandler(uint8_t* virtual_membase, uint8_t* physical_membase, uint8_t* membase_end, + HostToGuestVirtual host_to_guest_virtual, const void* host_to_guest_virtual_context, + AccessViolationCallback access_violation_callback, + void* access_violation_callback_context); + + static bool ExceptionCallbackThunk(arch::Exception* ex, void* data); + bool ExceptionCallback(arch::Exception* ex); + + uint8_t* virtual_membase_; + uint8_t* physical_membase_; + uint8_t* memory_end_; + + std::vector mapped_ranges_; + + HostToGuestVirtual host_to_guest_virtual_; + const void* host_to_guest_virtual_context_; + + AccessViolationCallback access_violation_callback_; + void* access_violation_callback_context_; + + static MMIOHandler* global_handler_; + + rex::thread::global_critical_region global_critical_region_; + + private: + struct DecodedLoadStore { + // Matches the Xn/Wn register number for 0 reads and ignored writes in many + // usage cases. + static constexpr uint8_t kArm64RegZero = 31; + + // Matches the actual register number encoding for an SP base in AArch64 + // load and store instructions. + static constexpr uint8_t kArm64MemBaseRegSp = kArm64RegZero; + + static constexpr uint8_t kArm64ValueRegX0 = 0; + static constexpr uint8_t kArm64ValueRegZero = kArm64ValueRegX0 + kArm64RegZero; + static constexpr uint8_t kArm64ValueRegV0 = 32; + + size_t length; + // Inidicates this is a load (or conversely a store). + bool is_load; + // Indicates the memory must be swapped. + bool byte_swap; + // Source (for store) or target (for load) register. + // For x86-64: + // AX CX DX BX SP BP SI DI // REX.R=0 + // R8 R9 R10 R11 R12 R13 R14 R15 // REX.R=1 + // For AArch64: + // - kArm64ValueRegX0 + [0...30]: Xn (Wn for 32 bits - upper 32 bits of Xn + // are zeroed on Wn write). + // - kArm64ValueRegZero: Zero constant for register read, ignored register + // write (though memory must still be accessed - a MMIO load may have side + // effects even if the result is discarded). + // - kArm64ValueRegV0 + [0...31]: Vn (Sn for 32 bits). + uint8_t value_reg; + // [base + (index * scale) + displacement] + bool mem_has_base; + // On AArch64, if mem_base_reg is kArm64MemBaseRegSp, the base register is + // SP, not Xn. + uint8_t mem_base_reg; + // For AArch64 pre- and post-indexing. In case of a load, the base register + // is written back after the loaded data is written to the register, + // overwriting the value register if it's the same. + bool mem_base_writeback; + int32_t mem_base_writeback_offset; + bool mem_has_index; + uint8_t mem_index_reg; + uint8_t mem_index_size; + bool mem_index_sign_extend; + uint8_t mem_scale; + ptrdiff_t mem_displacement; + bool is_constant; + int32_t constant; + }; + + static bool TryDecodeLoadStore(const uint8_t* p, DecodedLoadStore& decoded_out); +}; + +} // namespace rex::runtime diff --git a/include/rex/system/module.h b/include/rex/system/module.h new file mode 100644 index 0000000..9f9457c --- /dev/null +++ b/include/rex/system/module.h @@ -0,0 +1,78 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include + +namespace rex::runtime { + +class FunctionDispatcher; + +class Module { + public: + explicit Module(FunctionDispatcher* function_dispatcher); + virtual ~Module(); + + memory::Memory* memory() const { return memory_; } + FunctionDispatcher* function_dispatcher() const { return function_dispatcher_; } + + virtual const std::string& name() const = 0; + virtual bool is_executable() const = 0; + + virtual bool ContainsAddress(uint32_t address); + + // Binary introspection interface (virtual with defaults for backwards compat) + virtual uint32_t base_address() const { return 0; } + virtual uint32_t image_size() const { return 0; } + virtual uint32_t entry_point() const { return 0; } + virtual uint32_t export_table_address() const { return 0; } + + // Exception DataDirectory accessors (for PDATA table) + // These return the correct PDATA location from the PE Optional Header. + virtual uint32_t exception_directory_rva() const { return 0; } + virtual uint32_t exception_directory_size() const { return 0; } + virtual uint32_t exception_directory_address() const { return 0; } + + // Check if address is in an executable section + bool isExecutableSection(uint32_t address) const; + + // Section access - default implementations return empty + virtual std::span binary_sections() const; + virtual const BinarySection* FindSectionByName(std::string_view name) const; + virtual const BinarySection* FindSectionByAddress(uint32_t address) const; + + // Symbol access - default implementations return empty + virtual std::span binary_symbols() const; + virtual const BinarySymbol* FindSymbolByName(std::string_view name) const; + virtual const BinarySymbol* FindSymbolByAddress(uint32_t address) const; + virtual const BinarySymbol* FindSymbolContainingAddress(uint32_t address) const; + + // Symbol manipulation helpers (for external symbol loading, e.g., from map files) + void AddBinarySymbol(BinarySymbol symbol); + void ClearBinarySymbols(); + + protected: + FunctionDispatcher* function_dispatcher_ = nullptr; + memory::Memory* memory_ = nullptr; + + // Storage for binary introspection (populated by derived classes) + std::vector binary_sections_; + std::vector binary_symbols_; +}; + +} // namespace rex::runtime diff --git a/include/rex/system/shared_library.h b/include/rex/system/shared_library.h new file mode 100644 index 0000000..eda3234 --- /dev/null +++ b/include/rex/system/shared_library.h @@ -0,0 +1,37 @@ +/** + * @file rex/system/shared_library.h + * @brief Platform-agnostic shared library loader + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include + +namespace rex::system { + +class SharedLibrary { + public: + SharedLibrary() = default; + ~SharedLibrary(); + + SharedLibrary(const SharedLibrary&) = delete; + SharedLibrary& operator=(const SharedLibrary&) = delete; + SharedLibrary(SharedLibrary&& other) noexcept; + SharedLibrary& operator=(SharedLibrary&& other) noexcept; + + bool Load(const std::string& name); + void* GetSymbol(const char* name); + void Close(); + bool is_loaded() const { return handle_ != nullptr; } + + private: + void* handle_ = nullptr; +}; + +} // namespace rex::system diff --git a/include/rex/system/symbol.h b/include/rex/system/symbol.h new file mode 100644 index 0000000..5b7d09d --- /dev/null +++ b/include/rex/system/symbol.h @@ -0,0 +1,47 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +namespace rex::runtime { + +class Module; + +class Symbol { + public: + enum class Type { + kFunction, + kVariable, + }; + + Symbol(Type type, Module* module, uint32_t address) + : type_(type), module_(module), address_(address) {} + virtual ~Symbol() = default; + + Type type() const { return type_; } + Module* module() const { return module_; } + uint32_t address() const { return address_; } + + const std::string& name() const { return name_; } + void set_name(const std::string_view value) { name_ = value; } + + protected: + Type type_ = Type::kVariable; + Module* module_ = nullptr; + uint32_t address_ = 0; + + std::string name_; +}; + +} // namespace rex::runtime diff --git a/include/rex/system/thread.h b/include/rex/system/thread.h new file mode 100644 index 0000000..721276d --- /dev/null +++ b/include/rex/system/thread.h @@ -0,0 +1,51 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2017 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include + +namespace rex::runtime { + +class ThreadState; + +// Represents a thread that runs guest code. +class Thread { + public: + Thread(); + ~Thread(); + + static bool IsInThread(); + static Thread* GetCurrentThread(); + static uint32_t GetCurrentThreadId(); + ThreadState* thread_state() const { return thread_state_; } + + // True if the thread should be paused by the debugger. + // All threads that can run guest code must be stopped for the debugger to + // work properly. + bool can_debugger_suspend() const { return can_debugger_suspend_; } + void set_can_debugger_suspend(bool value) { can_debugger_suspend_ = value; } + + rex::thread::Thread* thread() { return thread_.get(); } + const std::string& thread_name() const { return thread_name_; } + + protected: + thread_local static Thread* current_thread_; + + ThreadState* thread_state_ = nullptr; + std::unique_ptr thread_ = nullptr; + + bool can_debugger_suspend_ = true; + std::string thread_name_; +}; + +} // namespace rex::runtime diff --git a/include/rex/system/thread_state.h b/include/rex/system/thread_state.h new file mode 100644 index 0000000..ee074b2 --- /dev/null +++ b/include/rex/system/thread_state.h @@ -0,0 +1,69 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include + +namespace rex::runtime { + +class ThreadState { + public: + // rexglue constructor - takes Memory directly, no Processor needed (maybe add later) + ThreadState(uint32_t thread_id, uint32_t stack_base, uint32_t pcr_address, + memory::Memory* memory); + ~ThreadState(); + + memory::Memory* memory() const { return memory_; } + ::PPCContext* context() const { return context_; } + uint32_t thread_id() const { return thread_id_; } + + static void Bind(ThreadState* thread_state); + static ThreadState* Get(); + static uint32_t GetThreadID(); + + private: + memory::Memory* memory_; + + uint32_t pcr_address_ = 0; + uint32_t thread_id_ = 0; + + // NOTE: must be 64b aligned for SSE ops. + alignas(64)::PPCContext context_storage_; + ::PPCContext* context_ = &context_storage_; +}; + +// Thread-safe accessors for current thread's PPC context and kernel state. +// Require ThreadState::Bind() to have been called on the current thread. +inline PPCContext* current_ppc_context() { + auto* ts = ThreadState::Get(); + assert(ts && "current_ppc_context() called without bound ThreadState"); + return ts->context(); +} + +} // namespace rex::runtime + +// Forward declaration in correct namespace +namespace rex::system { +class KernelState; +KernelState* kernel_state(); +} // namespace rex::system + +namespace rex::runtime { + +inline rex::system::KernelState* current_kernel_state() { + return rex::system::kernel_state(); +} + +} // namespace rex::runtime diff --git a/include/rex/system/user_module.h b/include/rex/system/user_module.h new file mode 100644 index 0000000..49c7696 --- /dev/null +++ b/include/rex/system/user_module.h @@ -0,0 +1,108 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include + +namespace rex { +namespace runtime { +class XexModule; +class ElfModule; +} // namespace runtime +namespace system { +class XThread; +} // namespace system +} // namespace rex + +namespace rex::system { + +class UserModule : public XModule { + public: + UserModule(KernelState* kernel_state); + ~UserModule() override; + + const std::string& path() const override { return path_; } + const std::string& name() const override { return name_; } + + enum ModuleFormat { + kModuleFormatUndefined = 0, + kModuleFormatXex, + kModuleFormatElf, + }; + + const rex::runtime::XexModule* xex_module() const { + assert_true(module_format_ == kModuleFormatXex); + return reinterpret_cast(processor_module_); + } + rex::runtime::XexModule* xex_module() { + assert_true(module_format_ == kModuleFormatXex); + return reinterpret_cast(processor_module_); + } + + const xex2_header* xex_header() const { return xex_module()->xex_header(); } + uint32_t guest_xex_header() const { return guest_xex_header_; } + // The title ID in the xex header or 0 if this is not a xex. + uint32_t title_id() const; + bool is_executable() const { return processor_module_->is_executable(); } + bool is_dll_module() const { return is_dll_module_; } + + uint32_t entry_point() const { return entry_point_; } + uint32_t stack_size() const { return stack_size_; } + + X_STATUS LoadFromFile(const std::string_view path); + X_STATUS LoadFromMemory(const void* addr, const size_t length); + X_STATUS Unload(); + + uint32_t GetProcAddressByOrdinal(uint16_t ordinal, uint32_t caller_address = 0) override; + uint32_t GetProcAddressByName(const std::string_view name) override; + X_STATUS GetSection(const std::string_view name, uint32_t* out_section_data, + uint32_t* out_section_size) override; + + // Get optional header - FOR HOST USE ONLY! + X_STATUS GetOptHeader(xex2_header_keys key, void** out_ptr); + + // Get optional header - FOR HOST USE ONLY! + template + X_STATUS GetOptHeader(xex2_header_keys key, T* out_ptr) { + return GetOptHeader(key, reinterpret_cast(out_ptr)); + } + + // Get optional header that can safely be returned to guest code. + X_STATUS GetOptHeader(xex2_header_keys key, uint32_t* out_header_guest_ptr); + static X_STATUS GetOptHeader(const memory::Memory* memory, const xex2_header* header, + xex2_header_keys key, uint32_t* out_header_guest_ptr); + + void Dump(); + + bool Save(stream::ByteStream* stream) override; + static object_ref Restore(KernelState* kernel_state, stream::ByteStream* stream, + const std::string_view path); + + private: + X_STATUS LoadXexContinue(); + + std::string name_; + std::string path_; + + uint32_t guest_xex_header_ = 0; + ModuleFormat module_format_ = kModuleFormatUndefined; + + bool is_dll_module_ = false; + uint32_t entry_point_ = 0; + uint32_t stack_size_ = 0; +}; + +} // namespace rex::system diff --git a/include/rex/system/util/gameinfo_utils.h b/include/rex/system/util/gameinfo_utils.h new file mode 100644 index 0000000..550ede3 --- /dev/null +++ b/include/rex/system/util/gameinfo_utils.h @@ -0,0 +1,78 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include + +namespace rex { +namespace system { +namespace util { + +class GameInfoWrapper { + public: + GameInfoWrapper(const uint8_t* data, size_t data_size); + + bool is_valid() const { return data_ != nullptr; } + + protected: + struct GameInfoBlockHeader { + rex::be magic; + rex::be block_size; + }; + static_assert_size(GameInfoBlockHeader, 8); + + struct GameInfoBlockExec { + const char* virtual_titleid; + const char* module_name; + const char* build_description; + + const uint32_t VirtualTitleIdLength = 32; + const uint32_t ModuleNameLength = 42; + const uint32_t BuildDescriptionLength = 64; + }; + + struct GameInfoBlockComm { + rex::be title_id; + }; + static_assert_size(GameInfoBlockComm, 4); + + struct GameInfoBlockTitl { + rex::be title[128]; + rex::be description[256]; + rex::be publisher[256]; // assumed field name from wxPirs + }; + + private: + const uint8_t* data_ = nullptr; + size_t data_size_ = 0; + + protected: + GameInfoBlockExec exec_; + const GameInfoBlockComm* comm_ = nullptr; + const GameInfoBlockTitl* titl_ = nullptr; +}; + +class GameInfo : public GameInfoWrapper { + public: + GameInfo(const std::vector& data) + : GameInfoWrapper(reinterpret_cast(data.data()), data.size()) {} + + uint32_t title_id() const; + std::string virtual_title_id() const; + std::string module_name() const; +}; + +} // namespace util +} // namespace system +} // namespace rex diff --git a/include/rex/system/util/native_list.h b/include/rex/system/util/native_list.h new file mode 100644 index 0000000..01c496a --- /dev/null +++ b/include/rex/system/util/native_list.h @@ -0,0 +1,258 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include + +namespace rex::system::util { + +// List is designed for storing pointers to objects in the guest heap. +// All values in the list should be assumed to be in big endian. + +// Pass LIST_ENTRY pointers. +// struct MYOBJ { +// uint32_t stuff; +// LIST_ENTRY list_entry; <-- pass this +// ... +// } + +class NativeList { + public: + NativeList(); + explicit NativeList(memory::Memory* memory); + + void Insert(uint32_t list_entry_ptr); + bool IsQueued(uint32_t list_entry_ptr); + void Remove(uint32_t list_entry_ptr); + uint32_t Shift(); + bool HasPending(); + + uint32_t head() const { return head_; } + void set_head(uint32_t head) { head_ = head; } + + void set_memory(memory::Memory* mem) { memory_ = mem; } + + private: + const uint32_t kInvalidPointer = 0xE0FE0FFF; + + private: + memory::Memory* memory_ = nullptr; + uint32_t head_; +}; + +// Guest-memory linked list utilities. +// VirtualTranslator is any type with TranslateVirtual(uint32_t) +// and HostToGuestVirtual(void*) methods (e.g. memory::Memory*). +// Overloads also accept a raw uint32_t guest pointer in place of the +// translator when the caller already has the guest address. + +template +X_LIST_ENTRY* XeHostList(uint32_t ptr, VirtualTranslator context) { + return context->template TranslateVirtual(ptr); +} + +template +uint32_t XeGuestList(X_LIST_ENTRY* ptr, VirtualTranslator context) { + return context->HostToGuestVirtual(ptr); +} + +template +void XeInitializeListHead(X_LIST_ENTRY* entry, VirtualTranslator context) { + if constexpr (std::is_unsigned_v) { + entry->blink_ptr = context; + entry->flink_ptr = context; + } else { + uint32_t orig_ptr = XeGuestList(entry, context); + entry->blink_ptr = orig_ptr; + entry->flink_ptr = orig_ptr; + } +} + +template +bool XeIsListEmpty(X_LIST_ENTRY* entry, VirtualTranslator context) { + return XeHostList(entry->flink_ptr, context) == entry; +} + +template +void XeRemoveEntryList(X_LIST_ENTRY* entry, VirtualTranslator context) { + uint32_t front = entry->flink_ptr; + uint32_t back = entry->blink_ptr; + XeHostList(back, context)->flink_ptr = front; + XeHostList(front, context)->blink_ptr = back; +} + +template +void XeRemoveEntryList(uint32_t entry, VirtualTranslator context) { + XeRemoveEntryList(XeHostList(entry, context), context); +} + +template +uint32_t XeRemoveHeadList(X_LIST_ENTRY* entry, VirtualTranslator context) { + uint32_t result = entry->flink_ptr; + XeRemoveEntryList(result, context); + return result; +} + +template +uint32_t XeRemoveTailList(X_LIST_ENTRY* entry, VirtualTranslator context) { + uint32_t result = entry->blink_ptr; + XeRemoveEntryList(result, context); + return result; +} + +template +void XeInsertTailList(X_LIST_ENTRY* list_head, uint32_t list_head_guest, X_LIST_ENTRY* host_entry, + uint32_t entry, VirtualTranslator context) { + uint32_t old_tail = list_head->blink_ptr; + host_entry->flink_ptr = list_head_guest; + host_entry->blink_ptr = old_tail; + XeHostList(old_tail, context)->flink_ptr = entry; + list_head->blink_ptr = entry; +} + +template +void XeInsertTailList(uint32_t list_head, uint32_t entry, VirtualTranslator context) { + XeInsertTailList(XeHostList(list_head, context), list_head, XeHostList(entry, context), entry, + context); +} + +template +void XeInsertTailList(X_LIST_ENTRY* list_head, uint32_t entry, VirtualTranslator context) { + XeInsertTailList(list_head, XeGuestList(list_head, context), XeHostList(entry, context), entry, + context); +} + +template +void XeInsertTailList(X_LIST_ENTRY* list_head, X_LIST_ENTRY* entry, VirtualTranslator context) { + XeInsertTailList(list_head, XeGuestList(list_head, context), entry, XeGuestList(entry, context), + context); +} + +template +void XeInsertHeadList(X_LIST_ENTRY* list_head, uint32_t list_head_guest, X_LIST_ENTRY* host_entry, + uint32_t entry, VirtualTranslator context) { + uint32_t old_list_head_flink = list_head->flink_ptr; + host_entry->flink_ptr = old_list_head_flink; + host_entry->blink_ptr = list_head_guest; + XeHostList(old_list_head_flink, context)->blink_ptr = entry; + list_head->flink_ptr = entry; +} + +template +void XeInsertHeadList(uint32_t list_head, uint32_t entry, VirtualTranslator context) { + XeInsertHeadList(XeHostList(list_head, context), list_head, XeHostList(entry, context), entry, + context); +} + +template +void XeInsertHeadList(X_LIST_ENTRY* list_head, uint32_t entry, VirtualTranslator context) { + XeInsertHeadList(list_head, XeGuestList(list_head, context), XeHostList(entry, context), entry, + context); +} + +template +void XeInsertHeadList(uint32_t list_head, X_LIST_ENTRY* entry, VirtualTranslator context) { + XeInsertHeadList(XeHostList(list_head, context), list_head, entry, XeGuestList(entry, context), + context); +} + +template +void XeInsertHeadList(X_LIST_ENTRY* list_head, X_LIST_ENTRY* entry, VirtualTranslator context) { + XeInsertHeadList(list_head, XeGuestList(list_head, context), entry, XeGuestList(entry, context), + context); +} + +// Typed intrusive list built on X_LIST_ENTRY. +// TObject is the containing struct, EntryListOffset is offsetof the +// X_LIST_ENTRY member within TObject. +template +struct X_TYPED_LIST : public X_LIST_ENTRY { + using this_type = X_TYPED_LIST; + + static X_LIST_ENTRY* ObjectListEntry(TObject* obj) { + return reinterpret_cast( + &reinterpret_cast(obj)[static_cast(EntryListOffset)]); + } + + static TObject* ListEntryObject(X_LIST_ENTRY* entry) { + return reinterpret_cast( + &reinterpret_cast(entry)[-static_cast(EntryListOffset)]); + } + + template + struct ForwardIterator { + VirtualTranslator vt; + uint32_t current_entry; + + ForwardIterator& operator++() { + current_entry = vt->template TranslateVirtual(current_entry)->flink_ptr; + return *this; + } + + bool operator!=(uint32_t other_ptr) const { return current_entry != other_ptr; } + + TObject& operator*() { + return *ListEntryObject(vt->template TranslateVirtual(current_entry)); + } + }; + + template + struct ForwardIteratorBegin { + VirtualTranslator vt; + this_type* const thiz; + + ForwardIterator begin() { + return ForwardIterator{vt, thiz->flink_ptr}; + } + + uint32_t end() { return vt->HostToGuestVirtual(thiz); } + }; + + template + ForwardIteratorBegin IterateForward(VirtualTranslator vt) { + return ForwardIteratorBegin{vt, this}; + } + + template + void Initialize(VirtualTranslator translator) { + XeInitializeListHead(this, translator); + } + + template + void InsertHead(TObject* entry, VirtualTranslator translator) { + XeInsertHeadList(static_cast(this), ObjectListEntry(entry), translator); + } + + template + void InsertTail(TObject* entry, VirtualTranslator translator) { + XeInsertTailList(this, ObjectListEntry(entry), translator); + } + + template + bool empty(VirtualTranslator vt) const { + return vt->template TranslateVirtual(flink_ptr) == this; + } + + template + TObject* HeadObject(VirtualTranslator vt) { + return ListEntryObject(vt->template TranslateVirtual(flink_ptr)); + } + + template + TObject* TailObject(VirtualTranslator vt) { + return ListEntryObject(vt->template TranslateVirtual(blink_ptr)); + } +}; + +} // namespace rex::system::util diff --git a/include/rex/system/util/object_table.h b/include/rex/system/util/object_table.h new file mode 100644 index 0000000..df9bad4 --- /dev/null +++ b/include/rex/system/util/object_table.h @@ -0,0 +1,110 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include +#include +#include + +namespace rex::stream { +class ByteStream; +} // namespace rex::stream + +namespace rex::system::util { + +class ObjectTable { + public: + ObjectTable(); + ~ObjectTable(); + + void Reset(); + + X_STATUS AddHandle(XObject* object, X_HANDLE* out_handle); + X_STATUS DuplicateHandle(X_HANDLE orig, X_HANDLE* out_handle); + X_STATUS RetainHandle(X_HANDLE handle); + X_STATUS ReleaseHandle(X_HANDLE handle); + X_STATUS RemoveHandle(X_HANDLE handle); + + bool Save(stream::ByteStream* stream); + bool Restore(stream::ByteStream* stream); + + // Restores a XObject reference with a handle. Mainly for internal use - do + // not use. + X_STATUS RestoreHandle(X_HANDLE handle, XObject* object); + + template + object_ref LookupObject(X_HANDLE handle) { + auto object = LookupObject(handle, false); + if (object) { + if (object->type() != T::kObjectType) { + object->Release(); + return object_ref(); + } + } + auto result = object_ref(reinterpret_cast(object)); + return result; + } + + X_STATUS AddNameMapping(const std::string_view name, X_HANDLE handle); + void RemoveNameMapping(const std::string_view name); + X_STATUS GetObjectByName(const std::string_view name, X_HANDLE* out_handle); + template + std::vector> GetObjectsByType(XObject::Type type) { + std::vector> results; + GetObjectsByType(type, reinterpret_cast>*>(&results)); + return results; + } + + template + std::vector> GetObjectsByType() { + std::vector> results; + GetObjectsByType(T::kObjectType, reinterpret_cast>*>(&results)); + return results; + } + + std::vector> GetAllObjects(); + void PurgeAllObjects(); // Purges the object table of all guest objects + + private: + struct ObjectTableEntry { + int handle_ref_count = 0; + XObject* object = nullptr; + }; + + ObjectTableEntry* LookupTable(X_HANDLE handle); + XObject* LookupObject(X_HANDLE handle, bool already_locked); + void GetObjectsByType(XObject::Type type, std::vector>* results); + + X_HANDLE TranslateHandle(X_HANDLE handle); + static constexpr uint32_t GetHandleSlot(X_HANDLE handle) { + return (handle - XObject::kHandleBase) >> 2; + } + X_STATUS FindFreeSlot(uint32_t* out_slot); + bool Resize(uint32_t new_capacity); + + rex::thread::global_critical_region global_critical_region_; + std::mutex name_mutex_; + uint32_t table_capacity_ = 0; + ObjectTableEntry* table_ = nullptr; + uint32_t last_free_entry_ = 0; + std::unordered_map name_table_; +}; + +// Generic lookup +template <> +object_ref ObjectTable::LookupObject(X_HANDLE handle); + +} // namespace rex::system::util diff --git a/include/rex/system/util/ordinal_table_post.inc b/include/rex/system/util/ordinal_table_post.inc new file mode 100644 index 0000000..62c8819 --- /dev/null +++ b/include/rex/system/util/ordinal_table_post.inc @@ -0,0 +1,12 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +// Post-include file for an ordinal table. + +#undef XE_EXPORT diff --git a/include/rex/system/util/ordinal_table_pre.inc b/include/rex/system/util/ordinal_table_pre.inc new file mode 100644 index 0000000..4380634 --- /dev/null +++ b/include/rex/system/util/ordinal_table_pre.inc @@ -0,0 +1,24 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +/** + * Pre-include file for an ordinal table. + * Use this to build tables of constants describing the ordinals: + * + * // Build an ordinal enum to make it easy to lookup ordinals. + * #include "rex/kernel/util/ordinal_table_pre.inc" + * namespace ordinals { + * enum { + * #include "xenia/kernel/my_module/my_module_table.inc" + * }; + * } // namespace ordinals + * #include "rex/kernel/util/ordinal_table_post.inc" + */ + +#define XE_EXPORT(module, ordinal, name, type) name = ordinal diff --git a/include/rex/system/util/string_utils.h b/include/rex/system/util/string_utils.h new file mode 100644 index 0000000..e2b0470 --- /dev/null +++ b/include/rex/system/util/string_utils.h @@ -0,0 +1,70 @@ +/** + * @file kernel/util/string_utils.h + * @brief String utility functions for kernel operations + * + * @copyright Copyright 2022 Ben Vanik. All rights reserved. (Xenia Project) + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +#include +#include +#include // X_ANSI_STRING, X_UNICODE_STRING +#include + +namespace rex { +namespace system { +namespace util { + +inline std::string_view TranslateAnsiString(const memory::Memory* memory, + const X_ANSI_STRING* ansi_string) { + if (!ansi_string || !ansi_string->length) { + return ""; + } + return std::string_view(memory->TranslateVirtual(ansi_string->pointer), + ansi_string->length); +} + +inline std::string TranslateAnsiPath(const memory::Memory* memory, + const X_ANSI_STRING* ansi_string) { + return rex::string::trim_string(std::string(TranslateAnsiString(memory, ansi_string))); +} + +inline std::string_view TranslateAnsiStringAddress(const memory::Memory* memory, + uint32_t guest_address) { + if (!guest_address) { + return ""; + } + return TranslateAnsiString(memory, memory->TranslateVirtual(guest_address)); +} + +inline std::u16string TranslateUnicodeString(const memory::Memory* memory, + const X_UNICODE_STRING* unicode_string) { + if (!unicode_string) { + return u""; + } + uint16_t length = unicode_string->length; + if (!length) { + return u""; + } + auto src = memory->TranslateVirtual(unicode_string->pointer); + std::u16string result; + result.reserve(length); + for (uint16_t i = 0; i < length / 2; ++i) { + uint16_t c = rex::byte_swap(src[i]); + result.push_back(c); + } + return result; +} + +} // namespace util +} // namespace system +} // namespace rex diff --git a/include/rex/system/util/xdbf_utils.h b/include/rex/system/util/xdbf_utils.h new file mode 100644 index 0000000..96e6a21 --- /dev/null +++ b/include/rex/system/util/xdbf_utils.h @@ -0,0 +1,154 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2016 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +#include +#include +#include + +namespace rex { +namespace system { +namespace util { + +// https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/XEX/SPA.h +// https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/XEX/SPA.cpp + +enum class XdbfSection : uint16_t { + kMetadata = 0x0001, + kImage = 0x0002, + kStringTable = 0x0003, +}; + +#pragma pack(push, 1) +struct XbdfHeader { + rex::be magic; + rex::be version; + rex::be entry_count; + rex::be entry_used; + rex::be free_count; + rex::be free_used; +}; +static_assert_size(XbdfHeader, 24); + +struct XbdfEntry { + rex::be section; + rex::be id; + rex::be offset; + rex::be size; +}; +static_assert_size(XbdfEntry, 18); + +struct XbdfFileLoc { + rex::be offset; + rex::be size; +}; +static_assert_size(XbdfFileLoc, 8); + +struct XdbfXstc { + rex::be magic; + rex::be version; + rex::be size; + rex::be default_language; +}; +static_assert_size(XdbfXstc, 16); + +struct XdbfSectionHeader { + rex::be magic; + rex::be version; + rex::be size; + rex::be count; +}; +static_assert_size(XdbfSectionHeader, 14); + +struct XdbfStringTableEntry { + rex::be id; + rex::be string_length; +}; +static_assert_size(XdbfStringTableEntry, 4); + +struct XdbfAchievementTableEntry { + rex::be id; + rex::be label_id; + rex::be description_id; + rex::be unachieved_id; + rex::be image_id; + rex::be gamerscore; + rex::be unkE; + rex::be flags; + rex::be unk14; + rex::be unk18; + rex::be unk1C; + rex::be unk20; +}; +static_assert_size(XdbfAchievementTableEntry, 0x24); +#pragma pack(pop) + +struct XdbfBlock { + const uint8_t* buffer; + size_t size; + + operator bool() const { return buffer != nullptr; } +}; + +// Wraps an XBDF (XboxDataBaseFormat) in-memory database. +// https://free60project.github.io/wiki/XDBF.html +class XdbfWrapper { + public: + XdbfWrapper(const uint8_t* data, size_t data_size); + + // True if the target memory contains a valid XDBF instance. + bool is_valid() const { return data_ != nullptr; } + + // Gets an entry in the given section. + // If the entry is not found the returned block will be nullptr. + XdbfBlock GetEntry(XdbfSection section, uint64_t id) const; + + // Gets a string from the string table in the given language. + // Returns the empty string if the entry is not found. + std::string GetStringTableEntry(XLanguage language, uint16_t string_id) const; + std::vector GetAchievements() const; + + private: + const uint8_t* data_ = nullptr; + size_t data_size_ = 0; + const uint8_t* content_offset_ = nullptr; + + const XbdfHeader* header_ = nullptr; + const XbdfEntry* entries_ = nullptr; + const XbdfFileLoc* files_ = nullptr; +}; + +class XdbfGameData : public XdbfWrapper { + public: + XdbfGameData(const uint8_t* data, size_t data_size) : XdbfWrapper(data, data_size) {} + + // Checks if provided language exist, if not returns default title language. + XLanguage GetExistingLanguage(XLanguage language_to_check) const; + + // The game icon image, if found. + XdbfBlock icon() const; + + // The game's default language. + XLanguage default_language() const; + + // The game's title in its default language. + std::string title() const; + + std::string title(XLanguage language) const; +}; + +} // namespace util +} // namespace system +} // namespace rex diff --git a/include/rex/system/util/xex2_info.h b/include/rex/system/util/xex2_info.h new file mode 100644 index 0000000..c813989 --- /dev/null +++ b/include/rex/system/util/xex2_info.h @@ -0,0 +1,621 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include + +union xe_xex2_version_t { + uint32_t value; + struct { + uint32_t major : 4; + uint32_t minor : 4; + uint32_t build : 16; + uint32_t qfe : 8; + }; +}; + +enum xe_pe_section_flags_e : uint32_t { + kXEPESectionContainsCode = 0x00000020, + kXEPESectionContainsDataInit = 0x00000040, + kXEPESectionContainsDataUninit = 0x00000080, + kXEPESectionMemoryExecute = 0x20000000, + kXEPESectionMemoryRead = 0x40000000, + kXEPESectionMemoryWrite = 0x80000000, +}; + +class PESection { + public: + char name[9]; // 8 + 1 for \0 + uint32_t raw_address; + uint32_t raw_size; + uint32_t address; + uint32_t size; + uint32_t flags; // kXEPESection* +}; + +struct PEExport { + const char* name; + uint32_t ordinal; + + uint64_t addr; // Function address +}; + +namespace rex { + +enum xex2_section_type { + XEX_SECTION_CODE = 1, + XEX_SECTION_DATA = 2, + XEX_SECTION_READONLY_DATA = 3, +}; + +enum xex2_image_flags : uint32_t { + XEX_IMAGE_MANUFACTURING_UTILITY = 0x00000002, + XEX_IMAGE_MANUFACTURING_SUPPORT_TOOLS = 0x00000004, + XEX_IMAGE_XGD2_MEDIA_ONLY = 0x00000008, + XEX_IMAGE_CARDEA_KEY = 0x00000100, + XEX_IMAGE_XEIKA_KEY = 0x00000200, + XEX_IMAGE_USERMODE_TITLE = 0x00000400, + XEX_IMAGE_USERMODE_SYSTEM = 0x00000800, + XEX_IMAGE_ORANGE0 = 0x00001000, + XEX_IMAGE_ORANGE1 = 0x00002000, + XEX_IMAGE_ORANGE2 = 0x00004000, + XEX_IMAGE_IPTV_SIGNUP_APPLICATION = 0x00010000, + XEX_IMAGE_IPTV_TITLE_APPLICATION = 0x00020000, + XEX_IMAGE_KEYVAULT_PRIVILEGES_REQUIRED = 0x04000000, + XEX_IMAGE_ONLINE_ACTIVATION_REQUIRED = 0x08000000, + XEX_IMAGE_PAGE_SIZE_4KB = 0x10000000, // else 64KB + XEX_IMAGE_REGION_FREE = 0x20000000, + XEX_IMAGE_REVOCATION_CHECK_OPTIONAL = 0x40000000, + XEX_IMAGE_REVOCATION_CHECK_REQUIRED = 0x80000000, +}; + +enum xex2_media_flags : uint32_t { + XEX_MEDIA_HARDDISK = 0x00000001, + XEX_MEDIA_DVD_X2 = 0x00000002, + XEX_MEDIA_DVD_CD = 0x00000004, + XEX_MEDIA_DVD_5 = 0x00000008, + XEX_MEDIA_DVD_9 = 0x00000010, + XEX_MEDIA_SYSTEM_FLASH = 0x00000020, + XEX_MEDIA_MEMORY_UNIT = 0x00000080, + XEX_MEDIA_USB_MASS_STORAGE_DEVICE = 0x00000100, + XEX_MEDIA_NETWORK = 0x00000200, + XEX_MEDIA_DIRECT_FROM_MEMORY = 0x00000400, + XEX_MEDIA_RAM_DRIVE = 0x00000800, + XEX_MEDIA_SVOD = 0x00001000, + XEX_MEDIA_INSECURE_PACKAGE = 0x01000000, + XEX_MEDIA_SAVEGAME_PACKAGE = 0x02000000, + XEX_MEDIA_LOCALLY_SIGNED_PACKAGE = 0x04000000, + XEX_MEDIA_LIVE_SIGNED_PACKAGE = 0x08000000, + XEX_MEDIA_XBOX_PACKAGE = 0x10000000, +}; + +enum xex2_region_flags : uint32_t { + XEX_REGION_NTSCU = 0x000000FF, + XEX_REGION_NTSCJ = 0x0000FF00, + XEX_REGION_NTSCJ_JAPAN = 0x00000100, + XEX_REGION_NTSCJ_CHINA = 0x00000200, + XEX_REGION_PAL = 0x00FF0000, + XEX_REGION_PAL_AU_NZ = 0x00010000, + XEX_REGION_OTHER = 0xFF000000, + XEX_REGION_ALL = 0xFFFFFFFF, +}; + +enum xex2_module_flags : uint32_t { + XEX_MODULE_TITLE = 0x00000001, + XEX_MODULE_EXPORTS_TO_TITLE = 0x00000002, + XEX_MODULE_SYSTEM_DEBUGGER = 0x00000004, + XEX_MODULE_DLL_MODULE = 0x00000008, + XEX_MODULE_MODULE_PATCH = 0x00000010, + XEX_MODULE_PATCH_FULL = 0x00000020, + XEX_MODULE_PATCH_DELTA = 0x00000040, + XEX_MODULE_USER_MODE = 0x00000080, +}; + +enum xex2_system_flags : uint32_t { + XEX_SYSTEM_NO_FORCED_REBOOT = 0x00000001, + XEX_SYSTEM_FOREGROUND_TASKS = 0x00000002, + XEX_SYSTEM_NO_ODD_MAPPING = 0x00000004, + XEX_SYSTEM_HANDLE_MCE_INPUT = 0x00000008, + XEX_SYSTEM_RESTRICTED_HUD_FEATURES = 0x00000010, + XEX_SYSTEM_HANDLE_GAMEPAD_DISCONNECT = 0x00000020, + XEX_SYSTEM_INSECURE_SOCKETS = 0x00000040, + XEX_SYSTEM_XBOX1_INTEROPERABILITY = 0x00000080, + XEX_SYSTEM_DASH_CONTEXT = 0x00000100, + XEX_SYSTEM_USES_GAME_VOICE_CHANNEL = 0x00000200, + XEX_SYSTEM_PAL50_INCOMPATIBLE = 0x00000400, + XEX_SYSTEM_INSECURE_UTILITY_DRIVE = 0x00000800, + XEX_SYSTEM_XAM_HOOKS = 0x00001000, + XEX_SYSTEM_ACCESS_PII = 0x00002000, + XEX_SYSTEM_CROSS_PLATFORM_SYSTEM_LINK = 0x00004000, + XEX_SYSTEM_MULTIDISC_SWAP = 0x00008000, + XEX_SYSTEM_MULTIDISC_INSECURE_MEDIA = 0x00010000, + XEX_SYSTEM_AP25_MEDIA = 0x00020000, + XEX_SYSTEM_NO_CONFIRM_EXIT = 0x00040000, + XEX_SYSTEM_ALLOW_BACKGROUND_DOWNLOAD = 0x00080000, + XEX_SYSTEM_CREATE_PERSISTABLE_RAMDRIVE = 0x00100000, + XEX_SYSTEM_INHERIT_PERSISTENT_RAMDRIVE = 0x00200000, + XEX_SYSTEM_ALLOW_HUD_VIBRATION = 0x00400000, + XEX_SYSTEM_ACCESS_UTILITY_PARTITIONS = 0x00800000, + XEX_SYSTEM_IPTV_INPUT_SUPPORTED = 0x01000000, + XEX_SYSTEM_PREFER_BIG_BUTTON_INPUT = 0x02000000, + XEX_SYSTEM_ALLOW_EXTENDED_SYSTEM_RESERVATION = 0x04000000, + XEX_SYSTEM_MULTIDISC_CROSS_TITLE = 0x08000000, + XEX_SYSTEM_INSTALL_INCOMPATIBLE = 0x10000000, + XEX_SYSTEM_ALLOW_AVATAR_GET_METADATA_BY_XUID = 0x20000000, + XEX_SYSTEM_ALLOW_CONTROLLER_SWAPPING = 0x40000000, + XEX_SYSTEM_DASH_EXTENSIBILITY_MODULE = 0x80000000, + // TODO(benvanik): figure out how stored. + /*XEX_SYSTEM_ALLOW_NETWORK_READ_CANCEL = 0x0, + XEX_SYSTEM_UNINTERRUPTABLE_READS = 0x0, + XEX_SYSTEM_REQUIRE_FULL_EXPERIENCE = 0x0, + XEX_SYSTEM_GAME_VOICE_REQUIRED_UI = 0x0, + XEX_SYSTEM_CAMERA_ANGLE = 0x0, + XEX_SYSTEM_SKELETAL_TRACKING_REQUIRED = 0x0, + XEX_SYSTEM_SKELETAL_TRACKING_SUPPORTED = 0x0,*/ +}; + +// ESRB (Entertainment Software Rating Board) +enum xex2_rating_esrb_value : uint32_t { + XEX_RATING_ESRB_eC = 0x00, + XEX_RATING_ESRB_E = 0x02, + XEX_RATING_ESRB_E10 = 0x04, + XEX_RATING_ESRB_T = 0x06, + XEX_RATING_ESRB_M = 0x08, + XEX_RATING_ESRB_AO = 0x0E, + XEX_RATING_ESRB_UNRATED = 0xFF, +}; +// PEGI (Pan European Game Information) +enum xex2_rating_pegi_value : uint32_t { + XEX_RATING_PEGI_3_PLUS = 0, + XEX_RATING_PEGI_7_PLUS = 4, + XEX_RATING_PEGI_12_PLUS = 9, + XEX_RATING_PEGI_16_PLUS = 13, + XEX_RATING_PEGI_18_PLUS = 14, + XEX_RATING_PEGI_UNRATED = 0xFF, +}; +// PEGI (Pan European Game Information) - Finland +enum xex2_rating_pegi_fi_value : uint32_t { + XEX_RATING_PEGI_FI_3_PLUS = 0, + XEX_RATING_PEGI_FI_7_PLUS = 4, + XEX_RATING_PEGI_FI_11_PLUS = 8, + XEX_RATING_PEGI_FI_15_PLUS = 12, + XEX_RATING_PEGI_FI_18_PLUS = 14, + XEX_RATING_PEGI_FI_UNRATED = 0xFF, +}; +// PEGI (Pan European Game Information) - Portugal +enum xex2_rating_pegi_pt_value : uint32_t { + XEX_RATING_PEGI_PT_4_PLUS = 1, + XEX_RATING_PEGI_PT_6_PLUS = 3, + XEX_RATING_PEGI_PT_12_PLUS = 9, + XEX_RATING_PEGI_PT_16_PLUS = 13, + XEX_RATING_PEGI_PT_18_PLUS = 14, + XEX_RATING_PEGI_PT_UNRATED = 0xFF, +}; +// BBFC (British Board of Film Classification) - UK/Ireland +enum xex2_rating_bbfc_value : uint32_t { + XEX_RATING_BBFC_UNIVERSAL = 1, + XEX_RATING_BBFC_PG = 5, + XEX_RATING_BBFC_3_PLUS = 0, + XEX_RATING_BBFC_7_PLUS = 4, + XEX_RATING_BBFC_12_PLUS = 9, + XEX_RATING_BBFC_15_PLUS = 12, + XEX_RATING_BBFC_16_PLUS = 13, + XEX_RATING_BBFC_18_PLUS = 14, + XEX_RATING_BBFC_UNRATED = 0xFF, +}; +// CERO (Computer Entertainment Rating Organization) +enum xex2_rating_cero_value : uint32_t { + XEX_RATING_CERO_A = 0, + XEX_RATING_CERO_B = 2, + XEX_RATING_CERO_C = 4, + XEX_RATING_CERO_D = 6, + XEX_RATING_CERO_Z = 8, + XEX_RATING_CERO_UNRATED = 0xFF, +}; +// USK (Unterhaltungssoftware SelbstKontrolle) +enum xex2_rating_usk_value : uint32_t { + XEX_RATING_USK_ALL = 0, + XEX_RATING_USK_6_PLUS = 2, + XEX_RATING_USK_12_PLUS = 4, + XEX_RATING_USK_16_PLUS = 6, + XEX_RATING_USK_18_PLUS = 8, + XEX_RATING_USK_UNRATED = 0xFF, +}; +// OFLC (Office of Film and Literature Classification) - Australia +enum xex2_rating_oflc_au_value : uint32_t { + XEX_RATING_OFLC_AU_G = 0, + XEX_RATING_OFLC_AU_PG = 2, + XEX_RATING_OFLC_AU_M = 4, + XEX_RATING_OFLC_AU_MA15_PLUS = 6, + XEX_RATING_OFLC_AU_UNRATED = 0xFF, +}; +// OFLC (Office of Film and Literature Classification) - New Zealand +enum xex2_rating_oflc_nz_value : uint32_t { + XEX_RATING_OFLC_NZ_G = 0, + XEX_RATING_OFLC_NZ_PG = 2, + XEX_RATING_OFLC_NZ_M = 4, + XEX_RATING_OFLC_NZ_MA15_PLUS = 6, + XEX_RATING_OFLC_NZ_UNRATED = 0xFF, +}; +// KMRB (Korea Media Rating Board) +enum xex2_rating_kmrb_value : uint32_t { + XEX_RATING_KMRB_ALL = 0, + XEX_RATING_KMRB_12_PLUS = 2, + XEX_RATING_KMRB_15_PLUS = 4, + XEX_RATING_KMRB_18_PLUS = 6, + XEX_RATING_KMRB_UNRATED = 0xFF, +}; +// Brazil +enum xex2_rating_brazil_value : uint32_t { + XEX_RATING_BRAZIL_ALL = 0, + XEX_RATING_BRAZIL_12_PLUS = 2, + XEX_RATING_BRAZIL_14_PLUS = 4, + XEX_RATING_BRAZIL_16_PLUS = 5, + XEX_RATING_BRAZIL_18_PLUS = 8, + XEX_RATING_BRAZIL_UNRATED = 0xFF, +}; +// FPB (Film and Publication Board) +enum xex2_rating_fpb_value : uint32_t { + XEX_RATING_FPB_ALL = 0, + XEX_RATING_FPB_PG = 6, + XEX_RATING_FPB_10_PLUS = 7, + XEX_RATING_FPB_13_PLUS = 10, + XEX_RATING_FPB_16_PLUS = 13, + XEX_RATING_FPB_18_PLUS = 14, + XEX_RATING_FPB_UNRATED = 0xFF, +}; + +enum xex2_header_keys : uint32_t { + XEX_HEADER_RESOURCE_INFO = 0x000002FF, + XEX_HEADER_FILE_FORMAT_INFO = 0x000003FF, + XEX_HEADER_DELTA_PATCH_DESCRIPTOR = 0x000005FF, + XEX_HEADER_BASE_REFERENCE = 0x00000405, + XEX_HEADER_BOUNDING_PATH = 0x000080FF, + XEX_HEADER_DEVICE_ID = 0x00008105, + XEX_HEADER_ORIGINAL_BASE_ADDRESS = 0x00010001, + XEX_HEADER_ENTRY_POINT = 0x00010100, + XEX_HEADER_IMAGE_BASE_ADDRESS = 0x00010201, + XEX_HEADER_IMPORT_LIBRARIES = 0x000103FF, + XEX_HEADER_CHECKSUM_TIMESTAMP = 0x00018002, + XEX_HEADER_ENABLED_FOR_CALLCAP = 0x00018102, + XEX_HEADER_ENABLED_FOR_FASTCAP = 0x00018200, + XEX_HEADER_ORIGINAL_PE_NAME = 0x000183FF, + XEX_HEADER_STATIC_LIBRARIES = 0x000200FF, + XEX_HEADER_TLS_INFO = 0x00020104, + XEX_HEADER_DEFAULT_STACK_SIZE = 0x00020200, + XEX_HEADER_DEFAULT_FILESYSTEM_CACHE_SIZE = 0x00020301, + XEX_HEADER_DEFAULT_HEAP_SIZE = 0x00020401, + XEX_HEADER_PAGE_HEAP_SIZE_AND_FLAGS = 0x00028002, + XEX_HEADER_SYSTEM_FLAGS = 0x00030000, + XEX_HEADER_EXECUTION_INFO = 0x00040006, + XEX_HEADER_TITLE_WORKSPACE_SIZE = 0x00040201, + XEX_HEADER_GAME_RATINGS = 0x00040310, + XEX_HEADER_LAN_KEY = 0x00040404, + XEX_HEADER_XBOX360_LOGO = 0x000405FF, + XEX_HEADER_MULTIDISC_MEDIA_IDS = 0x000406FF, + XEX_HEADER_ALTERNATE_TITLE_IDS = 0x000407FF, + XEX_HEADER_ADDITIONAL_TITLE_MEMORY = 0x00040801, + XEX_HEADER_EXPORTS_BY_NAME = 0x00E10402, +}; + +enum xex2_encryption_type : uint16_t { + XEX_ENCRYPTION_NONE = 0, + XEX_ENCRYPTION_NORMAL = 1, +}; + +enum xex2_compression_type : uint16_t { + XEX_COMPRESSION_NONE = 0, + XEX_COMPRESSION_BASIC = 1, + XEX_COMPRESSION_NORMAL = 2, + XEX_COMPRESSION_DELTA = 3, +}; + +enum xex2_approval_type : uint32_t { + XEX_APPROVAL_UNAPPROVED = 0, + XEX_APPROVAL_POSSIBLE = 1, + XEX_APPROVAL_APPROVED = 2, + XEX_APPROVAL_EXPIRED = 3, +}; + +struct xex2_game_ratings_t { + be esrb; + be pegi; + be pegifi; + be pegipt; + be bbfc; + be cero; + be usk; + be oflcau; + be oflcnz; + be kmrb; + be brazil; + be fpb; +}; + +struct xex2_file_basic_compression_block { + be data_size; + be zero_size; +}; + +struct xex2_file_basic_compression_info { + xex2_file_basic_compression_block blocks[1]; +}; + +struct xex2_compressed_block_info { + be block_size; + uint8_t block_hash[20]; +}; + +struct xex2_file_normal_compression_info { + be window_size; + xex2_compressed_block_info first_block; +}; + +struct xex2_opt_file_format_info { + be info_size; + be encryption_type; + be compression_type; + union { + xex2_file_basic_compression_info basic; + xex2_file_normal_compression_info normal; + } compression_info; +}; + +union xex2_version { + uint32_t value; + struct { + uint32_t major : 4; + uint32_t minor : 4; + uint32_t build : 16; + uint32_t qfe : 8; + }; +}; + +struct xex2_opt_lan_key { + uint8_t key[0x10]; +}; + +struct xex2_opt_bound_path { + be size; + char path[1]; +}; + +struct xex2_opt_static_library { + char name[8]; // 0x0 + be version_major; // 0x8 + be version_minor; // 0xA + be version_build; // 0xC + uint8_t approval_type; // 0xE + uint8_t version_qfe; // 0xF +}; +static_assert_size(xex2_opt_static_library, 0x10); + +struct xex2_opt_static_libraries { + be size; // 0x0 + xex2_opt_static_library libraries[1]; // 0x4 +}; + +struct xex2_opt_original_pe_name { + be size; + char name[1]; +}; + +struct xex2_opt_data_directory { + be offset; // 0x0 + be size; // 0x4 +}; +static_assert_size(xex2_opt_data_directory, 0x8); + +struct xex2_opt_tls_info { + be slot_count; // 0x0 + be raw_data_address; // 0x4 + be data_size; // 0x8 + be raw_data_size; // 0xC +}; +static_assert_size(xex2_opt_tls_info, 0x10); + +struct xex2_resource { + char name[8]; // 0x0 + be address; // 0x8 + be size; // 0xC +}; +static_assert_size(xex2_resource, 0x10); + +struct xex2_opt_resource_info { + be size; // 0x0 Resource count is (size - 4) / 16 + xex2_resource resources[1]; // 0x4 +}; + +struct xex2_delta_patch { + be old_addr; + be new_addr; + be uncompressed_len; + be compressed_len; + char patch_data[1]; +}; + +struct xex2_opt_delta_patch_descriptor { + be size; // 0x0 + be target_version_value; // 0x4 + be source_version_value; // 0x8 + uint8_t digest_source[0x14]; // 0xC + uint8_t image_key_source[0x10]; // 0x20 + be size_of_target_headers; // 0x30 + be delta_headers_source_offset; // 0x34 + be delta_headers_source_size; // 0x38 + be delta_headers_target_offset; // 0x3C + be delta_image_source_offset; // 0x40 + be delta_image_source_size; // 0x44 + be delta_image_target_offset; // 0x48 + xex2_delta_patch info; // 0x4C + + xex2_version target_version() const { return xex2_version{target_version_value}; } + + void set_target_version(xex2_version version) { target_version_value = version.value; } + + xex2_version source_version() const { return xex2_version{source_version_value}; } + + void set_source_version(xex2_version version) { source_version_value = version.value; } +}; + +struct xex2_opt_execution_info { + be media_id; // 0x0 + be version_value; // 0x4 + be base_version_value; // 0x8 + be title_id; // 0xC + uint8_t platform; // 0x10 + uint8_t executable_table; // 0x11 + uint8_t disc_number; // 0x12 + uint8_t disc_count; // 0x13 + be savegame_id; // 0x14 + + xex2_version version() const { return xex2_version{version_value}; } + + void set_version(xex2_version version) { version_value = version.value; } + + xex2_version base_version() const { return xex2_version{base_version_value}; } + + void set_base_version(xex2_version version) { base_version_value = version.value; } +}; +static_assert_size(xex2_opt_execution_info, 0x18); + +struct xex2_opt_import_libraries { + be size; // 0x0 + struct { + be size; // 0x4 + be count; // 0x8 + char data[1]; // 0xC string_table_size bytes + } string_table; +}; + +struct xex2_import_library { + be size; // 0x0 + char next_import_digest[0x14]; // 0x4 + be id; // 0x18 + be version_value; // 0x1C + be version_min_value; // 0x20 + be name_index; // 0x24 + be count; // 0x26 + be import_table[1]; // 0x28 + + xex2_version version() const { return xex2_version{version_value}; } + + void set_version(xex2_version version) { version_value = version.value; } + + xex2_version version_min() const { return xex2_version{version_min_value}; } + + void set_version_min(xex2_version version) { version_min_value = version.value; } +}; + +struct xex2_opt_generic_u32 { + be size; + be values[1]; + + uint32_t count() const { return (size - 4) / 4; } +}; + +struct xex2_opt_header { + be key; // 0x0 + + union { + be value; // 0x4 + be offset; // 0x4 + }; +}; + +struct xex2_header { + be magic; // 0x0 'XEX2' + be module_flags; // 0x4 + be header_size; // 0x8 + be reserved; // 0xC + be security_offset; // 0x10 + be header_count; // 0x14 + + xex2_opt_header headers[1]; // 0x18 +}; + +struct xex2_page_descriptor { + union { + be value; // 0x0 + struct { + xex2_section_type info : 4; + uint32_t page_count : 28; + }; + }; + char data_digest[0x14]; // 0x4 +}; + +struct xex2_security_info { + be header_size; // 0x0 + be image_size; // 0x4 + char rsa_signature[0x100]; // 0x8 + be unk_108; // 0x108 unk length + be image_flags; // 0x10C + be load_address; // 0x110 + char section_digest[0x14]; // 0x114 + be import_table_count; // 0x128 + char import_table_digest[0x14]; // 0x12C + char xgd2_media_id[0x10]; // 0x140 + char aes_key[0x10]; // 0x150 + be export_table; // 0x160 + char header_digest[0x14]; // 0x164 + be region; // 0x178 + be allowed_media_types; // 0x17C + be page_descriptor_count; // 0x180 + xex2_page_descriptor page_descriptors[1]; // 0x184 +}; + +struct xex1_security_info { + be header_size; + be image_size; + char rsa_signature[0x100]; + char image_digest[0x14]; + char import_table_digest[0x14]; + be load_address; + char aes_key[0x10]; + char xgd2_media_id[0x10]; + be region; + be image_flags; + be export_table; + be allowed_media_types; + be page_descriptor_count; + xex2_page_descriptor page_descriptors[1]; +}; + +struct xex2_export_table { + be magic[3]; // 0x0 + be modulenumber[2]; // 0xC + be version[3]; // 0x14 + be imagebaseaddr; // 0x20 must be <<16 to be accurate + be count; // 0x24 + be base; // 0x28 + be ordOffset[1]; // 0x2C ordOffset[0] + (imagebaseaddr << 16) = function +}; + +// Little endian PE export directory (from winnt.h) +struct X_IMAGE_EXPORT_DIRECTORY { + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t Name; + uint32_t Base; + uint32_t NumberOfFunctions; + uint32_t NumberOfNames; + uint32_t AddressOfFunctions; // RVA from base of image + uint32_t AddressOfNames; // RVA from base of image + uint32_t AddressOfNameOrdinals; // RVA from base of image +}; + +} // namespace rex diff --git a/include/rex/system/xam/app_manager.h b/include/rex/system/xam/app_manager.h new file mode 100644 index 0000000..84be3e4 --- /dev/null +++ b/include/rex/system/xam/app_manager.h @@ -0,0 +1,66 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include + +namespace rex { +class Memory; +namespace system { +class KernelState; +} // namespace system +} // namespace rex + +namespace rex { +namespace system { +namespace xam { + +class App { + public: + uint32_t app_id() const { return app_id_; } + + virtual X_HRESULT DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, + uint32_t buffer_length) = 0; + + virtual ~App() = default; + + protected: + App(KernelState* kernel_state, uint32_t app_id); + + KernelState* kernel_state_; + memory::Memory* memory_; + uint32_t app_id_; +}; + +class AppManager { + public: + void RegisterApp(std::unique_ptr app); + + X_HRESULT DispatchMessageSync(uint32_t app_id, uint32_t message, uint32_t buffer_ptr, + uint32_t buffer_length); + X_HRESULT DispatchMessageAsync(uint32_t app_id, uint32_t message, uint32_t buffer_ptr, + uint32_t buffer_length); + + private: + std::vector> apps_; + std::unordered_map app_lookup_; +}; + +} // namespace xam +} // namespace system +} // namespace rex diff --git a/include/rex/system/xam/content_device.h b/include/rex/system/xam/content_device.h new file mode 100644 index 0000000..c7118cb --- /dev/null +++ b/include/rex/system/xam/content_device.h @@ -0,0 +1,41 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +namespace rex { +namespace system { +namespace xam { + +enum class DeviceType : uint32_t { + HDD = 1, + ODD = 4, +}; + +enum class DummyDeviceId : uint32_t { + HDD = 1, + ODD = 2, +}; + +struct DummyDeviceInfo { + DummyDeviceId device_id; + DeviceType device_type; + uint64_t total_bytes; + uint64_t free_bytes; + const std::u16string_view name; +}; + +const DummyDeviceInfo* GetDummyDeviceInfo(uint32_t device_id); + +} // namespace xam +} // namespace system +} // namespace rex diff --git a/include/rex/system/xam/content_manager.h b/include/rex/system/xam/content_manager.h new file mode 100644 index 0000000..0890be5 --- /dev/null +++ b/include/rex/system/xam/content_manager.h @@ -0,0 +1,211 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace rex { +namespace system { +class KernelState; +} // namespace system +} // namespace rex + +namespace rex { +namespace system { +namespace xam { + +// If set in XCONTENT_AGGREGATE_DATA, will be substituted with the running +// titles ID +// TODO: check if actual x360 kernel/xam has a value similar to this +constexpr uint32_t kCurrentlyRunningTitleId = 0xFFFFFFFF; + +struct XCONTENT_DATA { + be device_id; + be content_type; + union { + // this should be be, but that stops copy constructor being + // generated... + uint16_t uint[128]; + char16_t chars[128]; + } display_name_raw; + + char file_name_raw[42]; + + // Some games use this padding field as a null-terminator, as eg. + // DLC packages usually fill the entire file_name_raw array + // Not every game sets it to 0 though, so make sure any file_name_raw reads + // only go up to 42 chars! + uint8_t padding[2]; + + bool operator==(const XCONTENT_DATA& other) const { + // Package is located via device_id/content_type/file_name, so only need to + // compare those + return device_id == other.device_id && content_type == other.content_type && + file_name() == other.file_name(); + } + + std::u16string display_name() const { + return memory::load_and_swap(display_name_raw.uint); + } + + std::string file_name() const { + std::string value; + value.assign(file_name_raw, std::min(strlen(file_name_raw), countof(file_name_raw))); + return value; + } + + void set_display_name(const std::u16string_view value) { + // Some games (e.g. 584108A9) require multiple null-terminators for it to + // read the string properly, blanking the array should take care of that + + std::fill_n(display_name_raw.chars, countof(display_name_raw.chars), 0); + rex::string::util_copy_and_swap_truncating(display_name_raw.chars, value, + countof(display_name_raw.chars)); + } + + void set_file_name(const std::string_view value) { + std::fill_n(file_name_raw, countof(file_name_raw), 0); + rex::string::util_copy_maybe_truncating( + file_name_raw, value, rex::countof(file_name_raw)); + + // Some games rely on padding field acting as a null-terminator... + padding[0] = padding[1] = 0; + } +}; +static_assert_size(XCONTENT_DATA, 0x134); + +struct XCONTENT_AGGREGATE_DATA : XCONTENT_DATA { + be xuid; // some titles store XUID here? + be title_id; + + XCONTENT_AGGREGATE_DATA() = default; + XCONTENT_AGGREGATE_DATA(const XCONTENT_DATA& other) { + device_id = other.device_id; + content_type = other.content_type; + set_display_name(other.display_name()); + set_file_name(other.file_name()); + padding[0] = padding[1] = 0; + xuid = 0; + title_id = kCurrentlyRunningTitleId; + } + + bool operator==(const XCONTENT_AGGREGATE_DATA& other) const { + // Package is located via device_id/title_id/content_type/file_name, so only + // need to compare those + return device_id == other.device_id && title_id == other.title_id && + content_type == other.content_type && file_name() == other.file_name(); + } +}; +static_assert_size(XCONTENT_AGGREGATE_DATA, 0x148); + +class ContentPackage { + public: + ContentPackage(KernelState* kernel_state, const std::string_view root_name, + const XCONTENT_AGGREGATE_DATA& data, const std::filesystem::path& package_path); + ~ContentPackage(); + + void LoadPackageLicenseMask(const std::filesystem::path header_path); + + const XCONTENT_AGGREGATE_DATA& GetPackageContentData() const { return content_data_; } + + const std::filesystem::path& package_path() const { return package_path_; } + + uint32_t GetPackageLicense() const { return license_; } + + private: + KernelState* kernel_state_; + std::string root_name_; + std::string device_path_; + std::filesystem::path package_path_; + XCONTENT_AGGREGATE_DATA content_data_; + uint32_t license_ = 0; +}; + +class ContentManager { + public: + ContentManager(KernelState* kernel_state, const std::filesystem::path& root_path); + ~ContentManager(); + + std::vector ListContent(uint32_t device_id, uint64_t xuid, + XContentType content_type, + uint32_t title_id = -1); + + std::unique_ptr ResolvePackage(const std::string_view root_name, uint64_t xuid, + const XCONTENT_AGGREGATE_DATA& data); + + bool ContentExists(uint64_t xuid, const XCONTENT_AGGREGATE_DATA& data); + X_RESULT CreateContent(const std::string_view root_name, uint64_t xuid, + const XCONTENT_AGGREGATE_DATA& data); + X_RESULT OpenContent(const std::string_view root_name, uint64_t xuid, + const XCONTENT_AGGREGATE_DATA& data, uint32_t& content_license); + X_RESULT CloseContent(const std::string_view root_name); + X_RESULT GetContentThumbnail(uint64_t xuid, const XCONTENT_AGGREGATE_DATA& data, + std::vector* buffer); + X_RESULT SetContentThumbnail(uint64_t xuid, const XCONTENT_AGGREGATE_DATA& data, + std::vector buffer); + X_RESULT DeleteContent(uint64_t xuid, const XCONTENT_AGGREGATE_DATA& data); + X_RESULT UnmountContent(uint64_t xuid, const XCONTENT_AGGREGATE_DATA& data); + X_RESULT UnmountAndDeleteContent(uint64_t xuid, const XCONTENT_AGGREGATE_DATA& data); + + X_RESULT WriteContentHeaderFile(uint64_t xuid, XCONTENT_AGGREGATE_DATA data, + uint32_t license_mask = 0); + X_RESULT ReadContentHeaderFile(const std::string_view file_name, uint64_t xuid, uint32_t title_id, + XContentType content_type, XCONTENT_AGGREGATE_DATA& data) const; + + std::filesystem::path ResolveGameUserContentPath(); + bool IsContentOpen(const XCONTENT_AGGREGATE_DATA& data) const; + void CloseOpenedFilesFromContent(const std::string_view root_name); + + // Returns the host filesystem path for an open content package, or empty. + std::filesystem::path GetOpenPackagePath(const std::string_view root_name) const; + + // Installs an STFS content package from an arbitrary host path. + // Extracts the package into root_path_/0000000000000000/{title_id}/00000002/{filename}/ + // and writes a .header file for XAM enumeration. + X_RESULT InstallContent(const std::filesystem::path& package_path); + + private: + std::filesystem::path ResolvePackageRoot(uint64_t xuid, XContentType content_type, + uint32_t title_id = -1); + std::filesystem::path ResolvePackagePath(uint64_t xuid, const XCONTENT_AGGREGATE_DATA& data); + std::filesystem::path ResolvePackageHeaderPath(const std::string_view file_name, uint64_t xuid, + uint32_t title_id, + XContentType content_type) const; + + std::unordered_map::iterator + FindOpenPackageByData(const XCONTENT_AGGREGATE_DATA& data); + ContentPackage* DetachPackage(std::unordered_map::iterator it); + + KernelState* kernel_state_; + std::filesystem::path root_path_; + + // TODO(benvanik): remove use of global lock, it's bad here! + rex::thread::global_critical_region global_critical_region_; + std::unordered_map + open_packages_; +}; + +} // namespace xam +} // namespace system +} // namespace rex diff --git a/include/rex/system/xam/user_profile.h b/include/rex/system/xam/user_profile.h new file mode 100644 index 0000000..ec37017 --- /dev/null +++ b/include/rex/system/xam/user_profile.h @@ -0,0 +1,251 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include + +#include + +#include +#include +#include + +namespace rex::system { +class KernelState; +} + +namespace rex { +namespace system { +namespace xam { + +struct X_USER_PROFILE_SETTING_DATA { + // UserProfile::Setting::Type. Appears to be 8-in-32 field, and the upper 24 + // are not always zeroed by the game. + uint8_t type; + uint8_t unk_1[3]; + rex::be unk_4; + // TODO(sabretooth): not sure if this is a union, but it seems likely. + // Haven't run into cases other than "binary data" yet. + union { + rex::be s32; + rex::be s64; + rex::be u32; + rex::be f64; + struct { + rex::be size; + rex::be ptr; + } unicode; + rex::be f32; + struct { + rex::be size; + rex::be ptr; + } binary; + rex::be filetime; + }; +}; +static_assert_size(X_USER_PROFILE_SETTING_DATA, 16); + +struct X_USER_PROFILE_SETTING { + rex::be from; + rex::be unk04; + union { + rex::be user_index; + rex::be xuid; + }; + rex::be setting_id; + rex::be unk14; + union { + uint8_t data_bytes[sizeof(X_USER_PROFILE_SETTING_DATA)]; + X_USER_PROFILE_SETTING_DATA data; + }; +}; +static_assert_size(X_USER_PROFILE_SETTING, 40); + +class UserProfile { + public: + class SettingByteStream : public stream::ByteStream { + public: + SettingByteStream(uint32_t ptr, uint8_t* data, size_t data_length, size_t offset = 0) + : stream::ByteStream(data, data_length, offset), ptr_(ptr) {} + + uint32_t ptr() const { return static_cast(ptr_ + offset()); } + + private: + uint32_t ptr_; + }; + struct Setting { + enum class Type { + CONTENT = 0, + INT32 = 1, + INT64 = 2, + DOUBLE = 3, + WSTRING = 4, + FLOAT = 5, + BINARY = 6, + DATETIME = 7, + UNSET = 0xFF, + }; + union Key { + uint32_t value; + struct { + uint32_t id : 14; + uint32_t unk : 2; + uint32_t size : 12; + uint32_t type : 4; + }; + }; + uint32_t setting_id; + Type type; + size_t size; + bool is_set; + uint32_t loaded_title_id; + Setting(uint32_t setting_id, Type type, size_t size, bool is_set) + : setting_id(setting_id), type(type), size(size), is_set(is_set), loaded_title_id(0) {} + virtual void Append(X_USER_PROFILE_SETTING_DATA* data, SettingByteStream* stream) { + (void)stream; + data->type = static_cast(type); + } + virtual std::vector Serialize() const { return std::vector(); } + virtual void Deserialize(std::vector) {} + bool is_title_specific() const { return (setting_id & 0x3F00) == 0x3F00; } + }; + struct Int32Setting : public Setting { + Int32Setting(uint32_t setting_id, int32_t value) + : Setting(setting_id, Type::INT32, 4, true), value(value) {} + int32_t value; + void Append(X_USER_PROFILE_SETTING_DATA* data, SettingByteStream* stream) override { + Setting::Append(data, stream); + data->s32 = value; + } + }; + struct Int64Setting : public Setting { + Int64Setting(uint32_t setting_id, int64_t value) + : Setting(setting_id, Type::INT64, 8, true), value(value) {} + int64_t value; + void Append(X_USER_PROFILE_SETTING_DATA* data, SettingByteStream* stream) override { + Setting::Append(data, stream); + data->s64 = value; + } + }; + struct DoubleSetting : public Setting { + DoubleSetting(uint32_t setting_id, double value) + : Setting(setting_id, Type::DOUBLE, 8, true), value(value) {} + double value; + void Append(X_USER_PROFILE_SETTING_DATA* data, SettingByteStream* stream) override { + Setting::Append(data, stream); + data->f64 = value; + } + }; + struct UnicodeSetting : public Setting { + UnicodeSetting(uint32_t setting_id, const std::u16string& value) + : Setting(setting_id, Type::WSTRING, 8, true), value(value) {} + std::u16string value; + void Append(X_USER_PROFILE_SETTING_DATA* data, SettingByteStream* stream) override { + Setting::Append(data, stream); + if (value.empty()) { + data->unicode.size = 0; + data->unicode.ptr = 0; + } else { + size_t count = value.size() + 1; + size_t size = 2 * count; + assert_true(size <= std::numeric_limits::max()); + data->unicode.size = static_cast(size); + data->unicode.ptr = stream->ptr(); + auto buffer = reinterpret_cast(&stream->data()[stream->offset()]); + stream->Advance(size); + memory::copy_and_swap(buffer, (uint16_t*)value.data(), count); + } + } + }; + struct FloatSetting : public Setting { + FloatSetting(uint32_t setting_id, float value) + : Setting(setting_id, Type::FLOAT, 4, true), value(value) {} + float value; + void Append(X_USER_PROFILE_SETTING_DATA* data, SettingByteStream* stream) override { + Setting::Append(data, stream); + data->f32 = value; + } + }; + struct BinarySetting : public Setting { + BinarySetting(uint32_t setting_id) : Setting(setting_id, Type::BINARY, 8, false), value() {} + BinarySetting(uint32_t setting_id, const std::vector& value) + : Setting(setting_id, Type::BINARY, 8, true), value(value) {} + std::vector value; + void Append(X_USER_PROFILE_SETTING_DATA* data, SettingByteStream* stream) override { + Setting::Append(data, stream); + if (value.empty()) { + data->binary.size = 0; + data->binary.ptr = 0; + } else { + size_t size = value.size(); + assert_true(size <= std::numeric_limits::max()); + data->binary.size = static_cast(size); + data->binary.ptr = stream->ptr(); + stream->Write(value.data(), size); + } + } + std::vector Serialize() const override { + return std::vector(value.data(), value.data() + value.size()); + } + void Deserialize(std::vector data) override { + value = data; + is_set = true; + } + }; + struct DateTimeSetting : public Setting { + DateTimeSetting(uint32_t setting_id, int64_t value) + : Setting(setting_id, Type::DATETIME, 8, true), value(value) {} + int64_t value; + void Append(X_USER_PROFILE_SETTING_DATA* data, SettingByteStream* stream) override { + Setting::Append(data, stream); + data->filetime = value; + } + }; + + UserProfile(); + + uint64_t xuid() const { return xuid_; } + std::string name() const { return name_; } + uint32_t signin_state() const { return 1; } + uint32_t type() const { return 1 | 2; /* local | online profile? */ } + + void set_kernel_state(KernelState* ks) { kernel_state_ = ks; } + + void AddSetting(std::unique_ptr setting); + Setting* GetSetting(uint32_t setting_id); + + private: + uint64_t xuid_; + std::string name_; + std::vector> setting_list_; + std::unordered_map settings_; + KernelState* kernel_state_ = nullptr; + + void LoadSetting(UserProfile::Setting*); + void SaveSetting(UserProfile::Setting*); +}; + +} // namespace xam +} // namespace system +} // namespace rex + +// fmt formatter for UserProfile::Setting::Type +template <> +struct fmt::formatter : fmt::formatter { + template + auto format(rex::system::xam::UserProfile::Setting::Type t, FormatContext& ctx) const { + return fmt::formatter::format(static_cast(t), ctx); + } +}; diff --git a/include/rex/system/xcontent.h b/include/rex/system/xcontent.h new file mode 100644 index 0000000..bd404d1 --- /dev/null +++ b/include/rex/system/xcontent.h @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified 2026 Tom Clay + * Modified for rexglue - Xbox 360 recompilation framework + * + * @changes - Extracted content types from xbox.h + */ + +#pragma once + +#include + +namespace rex::system { + +typedef uint32_t XNotificationID; + +enum class XLanguage : uint32_t { + kInvalid = 0, + kEnglish = 1, + kJapanese = 2, + kGerman = 3, + kFrench = 4, + kSpanish = 5, + kItalian = 6, + kKorean = 7, + kTChinese = 8, + kPortuguese = 9, + kSChinese = 10, + kPolish = 11, + kRussian = 12, + kMaxLanguages = 13 +}; + +enum class XContentType : uint32_t { + kSavedGame = 0x00000001, + kMarketplaceContent = 0x00000002, + kPublisher = 0x00000003, + kXbox360Title = 0x00001000, + kIptvPauseBuffer = 0x00002000, + kXNACommunity = 0x00003000, + kInstalledGame = 0x00004000, + kXboxTitle = 0x00005000, + kSocialTitle = 0x00006000, + kGamesOnDemand = 0x00007000, + kSUStoragePack = 0x00008000, + kAvatarItem = 0x00009000, + kProfile = 0x00010000, + kGamerPicture = 0x00020000, + kTheme = 0x00030000, + kCacheFile = 0x00040000, + kStorageDownload = 0x00050000, + kXboxSavedGame = 0x00060000, + kXboxDownload = 0x00070000, + kGameDemo = 0x00080000, + kVideo = 0x00090000, + kGameTitle = 0x000A0000, + kInstaller = 0x000B0000, + kGameTrailer = 0x000C0000, + kArcadeTitle = 0x000D0000, + kXNA = 0x000E0000, + kLicenseStore = 0x000F0000, + kMovie = 0x00100000, + kTV = 0x00200000, + kMusicVideo = 0x00300000, + kGameVideo = 0x00400000, + kPodcastVideo = 0x00500000, + kViralVideo = 0x00600000, + kCommunityGame = 0x02000000, +}; + +} // namespace rex::system diff --git a/include/rex/system/xenumerator.h b/include/rex/system/xenumerator.h new file mode 100644 index 0000000..866943b --- /dev/null +++ b/include/rex/system/xenumerator.h @@ -0,0 +1,107 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include + +namespace rex::system { + +struct X_KENUMERATOR { + be app_id; + be open_message; + be close_message; + be user_index; + be items_per_enumerate; + be flags; +}; +static_assert_size(X_KENUMERATOR, 0x18); + +struct X_KENUMERATOR_CONTENT_AGGREGATE { + be magic; + be handle; +}; + +class XEnumerator : public XObject { + public: + static const XObject::Type kObjectType = XObject::Type::Enumerator; + + XEnumerator(KernelState* kernel_state, size_t items_per_enumerate, size_t item_size); + virtual ~XEnumerator(); + + X_STATUS Initialize(uint32_t user_index, uint32_t app_id, uint32_t open_message, + uint32_t close_message, uint32_t flags, uint32_t extra_size, + void** extra_buffer); + + X_STATUS Initialize(uint32_t user_index, uint32_t app_id, uint32_t open_message, + uint32_t close_message, uint32_t flags); + + template + X_STATUS Initialize(uint32_t user_index, uint32_t app_id, uint32_t open_message, + uint32_t close_message, uint32_t flags, T** extra) { + void* dummy; + auto result = Initialize(user_index, app_id, open_message, close_message, flags, + static_cast(sizeof(T)), &dummy); + if (extra) { + *extra = XFAILED(result) ? nullptr : static_cast(dummy); + } + return result; + } + + virtual uint32_t WriteItems(uint32_t buffer_ptr, uint8_t* buffer_data, + uint32_t* written_count) = 0; + + size_t item_size() const { return item_size_; } + size_t items_per_enumerate() const { return items_per_enumerate_; } + + private: + size_t items_per_enumerate_; + size_t item_size_; +}; + +class XStaticUntypedEnumerator : public XEnumerator { + public: + XStaticUntypedEnumerator(KernelState* kernel_state, size_t items_per_enumerate, size_t item_size) + : XEnumerator(kernel_state, items_per_enumerate, item_size), + item_count_(0), + current_item_(0) {} + + size_t item_count() const { return item_count_; } + + uint8_t* AppendItem(); + + uint32_t WriteItems(uint32_t buffer_ptr, uint8_t* buffer_data, uint32_t* written_count) override; + + private: + size_t item_count_; + size_t current_item_; + std::vector buffer_; +}; + +template +class XStaticEnumerator : public XStaticUntypedEnumerator { + public: + XStaticEnumerator(KernelState* kernel_state, size_t items_per_enumerate) + : XStaticUntypedEnumerator(kernel_state, items_per_enumerate, sizeof(T)) {} + + T* AppendItem() { return reinterpret_cast(XStaticUntypedEnumerator::AppendItem()); } + + void AppendItem(const T& item) { + auto ptr = AppendItem(); + item.Write(ptr); + } +}; + +} // namespace rex::system diff --git a/include/rex/system/xevent.h b/include/rex/system/xevent.h new file mode 100644 index 0000000..e81df52 --- /dev/null +++ b/include/rex/system/xevent.h @@ -0,0 +1,53 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +namespace rex::system { + +// https://www.nirsoft.net/kernel_struct/vista/KEVENT.html +struct X_KEVENT { + X_DISPATCH_HEADER header; +}; +static_assert_size(X_KEVENT, 0x10); + +class XEvent : public XObject { + public: + static const XObject::Type kObjectType = XObject::Type::Event; + + explicit XEvent(KernelState* kernel_state); + ~XEvent() override; + + void Initialize(bool manual_reset, bool initial_state); + void InitializeNative(void* native_ptr, X_DISPATCH_HEADER* header); + + void Query(uint32_t* out_type, uint32_t* out_state); + + int32_t Set(uint32_t priority_increment, bool wait); + int32_t Pulse(uint32_t priority_increment, bool wait); + int32_t Reset(); + void Clear(); + + bool Save(stream::ByteStream* stream) override; + static object_ref Restore(KernelState* kernel_state, stream::ByteStream* stream); + + protected: + rex::thread::WaitHandle* GetWaitHandle() override { return event_.get(); } + + private: + bool manual_reset_ = false; + std::unique_ptr event_; +}; + +} // namespace rex::system diff --git a/include/rex/system/xex_module.h b/include/rex/system/xex_module.h new file mode 100644 index 0000000..69e22f5 --- /dev/null +++ b/include/rex/system/xex_module.h @@ -0,0 +1,233 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include + +namespace rex::system { +class KernelState; +} // namespace rex::system + +namespace rex::runtime { + +constexpr memory::fourcc_t kXEX1Signature = memory::make_fourcc("XEX1"); +constexpr memory::fourcc_t kXEX2Signature = memory::make_fourcc("XEX2"); +constexpr memory::fourcc_t kElfSignature = memory::make_fourcc(0x7F, 'E', 'L', 'F'); + +class Runtime; + +class XexModule : public Module { + public: + struct ImportLibraryFn { + public: + uint32_t ordinal = 0; + uint32_t value_address = 0; + uint32_t thunk_address = 0; + }; + struct ImportLibrary { + public: + std::string name; + uint32_t id; + xe_xex2_version_t version; + xe_xex2_version_t min_version; + std::vector imports; + }; + struct SecurityInfoContext { + const char* rsa_signature; + const char* aes_key; + uint32_t image_size; + uint32_t image_flags; + uint32_t export_table; + uint32_t load_address; + uint32_t page_descriptor_count; + const xex2_page_descriptor* page_descriptors; + }; + enum XexFormat { + kFormatUnknown, + kFormatXex1, + kFormatXex2, + }; + + XexModule(FunctionDispatcher* function_dispatcher, system::KernelState* kernel_state); + virtual ~XexModule(); + + bool loaded() const { return loaded_; } + const xex2_header* xex_header() const { + return reinterpret_cast(xex_header_mem_.data()); + } + const SecurityInfoContext* xex_security_info() const { return &security_info_; } + + uint32_t image_size() const override { + assert_not_zero(base_address_); + + // Calculate the new total size of the XEX image from its headers. + auto heap = memory()->LookupHeap(base_address_); + uint32_t total_size = 0; + for (uint32_t i = 0; i < xex_security_info()->page_descriptor_count; i++) { + // Byteswap the bitfield manually. + xex2_page_descriptor desc; + desc.value = rex::byte_swap(xex_security_info()->page_descriptors[i].value); + + total_size += desc.page_count * heap->page_size(); + } + return total_size; + } + + const std::vector* import_libraries() const { return &import_libs_; } + + const xex2_opt_execution_info* opt_execution_info() const { + xex2_opt_execution_info* retval = nullptr; + GetOptHeader(XEX_HEADER_EXECUTION_INFO, &retval); + return retval; + } + + const xex2_opt_file_format_info* opt_file_format_info() const { + xex2_opt_file_format_info* retval = nullptr; + GetOptHeader(XEX_HEADER_FILE_FORMAT_INFO, &retval); + return retval; + } + + std::vector opt_alternate_title_ids() const { return opt_alternate_title_ids_; } + + uint32_t base_address() const override { return base_address_; } + bool is_dev_kit() const { return is_dev_kit_; } + + // Gets an optional header. Returns NULL if not found. + // Special case: if key & 0xFF == 0x00, this function will return the value, + // not a pointer! This assumes out_ptr points to uint32_t. + static bool GetOptHeader(const xex2_header* header, xex2_header_keys key, void** out_ptr); + bool GetOptHeader(xex2_header_keys key, void** out_ptr) const; + + // Ultra-cool templated version + // Special case: if key & 0xFF == 0x00, this function will return the value, + // not a pointer! This assumes out_ptr points to uint32_t. + template + static bool GetOptHeader(const xex2_header* header, xex2_header_keys key, T* out_ptr) { + return GetOptHeader(header, key, reinterpret_cast(out_ptr)); + } + + template + bool GetOptHeader(xex2_header_keys key, T* out_ptr) const { + return GetOptHeader(key, reinterpret_cast(out_ptr)); + } + + static const void* GetSecurityInfo(const xex2_header* header); + + const PESection* GetPESection(const char* name); + + const std::vector& pe_sections() const { return pe_sections_; } + + uint32_t entry_point() const override { + uint32_t ep = 0; + GetOptHeader(XEX_HEADER_ENTRY_POINT, &ep); + return ep; + } + + uint32_t export_table_address() const override { return xex_security_info()->export_table; } + + // Exception DataDirectory accessors (for PDATA table) + // These return the correct PDATA location from the PE Optional Header, + // which may differ from the .pdata section's VirtualAddress. + uint32_t exception_directory_rva() const override { return exception_dir_rva_; } + uint32_t exception_directory_size() const override { return exception_dir_size_; } + uint32_t exception_directory_address() const override { + return base_address_ + exception_dir_rva_; + } + + // Binary introspection overrides + std::span binary_sections() const override; + const BinarySection* FindSectionByName(std::string_view name) const override; + std::span binary_symbols() const override; + + uint32_t GetProcAddress(uint16_t ordinal) const; + uint32_t GetProcAddress(const std::string_view name) const; + + int ApplyPatch(XexModule* module); + bool Load(const std::string_view name, const std::string_view path, const void* xex_addr, + size_t xex_length); + bool LoadContinue(); + bool Unload(); + + bool ContainsAddress(uint32_t address) override; + + const std::string& name() const override { return name_; } + bool is_executable() const override { + return (xex_header()->module_flags & XEX_MODULE_TITLE) != 0; + } + + bool is_valid_executable() const { + assert_not_zero(base_address_); + if (!base_address_) { + return false; + } + uint8_t* buffer = memory()->TranslateVirtual(base_address_); + return *(uint32_t*)buffer == 0x905A4D; + } + + bool is_patch() const { + assert_not_null(xex_header()); + if (!xex_header()) { + return false; + } + return (xex_header()->module_flags & + (XEX_MODULE_MODULE_PATCH | XEX_MODULE_PATCH_DELTA | XEX_MODULE_PATCH_FULL)); + } + + private: + void ReadSecurityInfo(); + + int ReadImage(const void* xex_addr, size_t xex_length, bool use_dev_key); + int ReadImageUncompressed(const void* xex_addr, size_t xex_length); + int ReadImageBasicCompressed(const void* xex_addr, size_t xex_length); + int ReadImageCompressed(const void* xex_addr, size_t xex_length); + + int ReadPEHeaders(); + + bool SetupLibraryImports(const std::string_view name, const xex2_import_library* library); + + void PopulateBinaryData(); + + system::KernelState* kernel_state_ = nullptr; + std::string name_; + std::string path_; + std::vector xex_header_mem_; // Holds the xex header + std::vector xexp_data_mem_; // Holds XEXP patch data + + std::vector import_libs_; // pre-loaded import libraries for ease of use + std::vector pe_sections_; + + // XEX_HEADER_ALTERNATE_TITLE_IDS loaded into a safe std::vector + std::vector opt_alternate_title_ids_; + + uint8_t session_key_[0x10]; + bool is_dev_kit_ = false; + + bool loaded_ = false; // Loaded into memory? + bool finished_load_ = false; // PE/imports/symbols/etc all loaded? + + uint32_t base_address_ = 0; + uint32_t low_address_ = 0; + uint32_t high_address_ = 0; + + // Exception DataDirectory from PE Optional Header + uint32_t exception_dir_rva_ = 0; + uint32_t exception_dir_size_ = 0; + + XexFormat xex_format_ = kFormatUnknown; + SecurityInfoContext security_info_ = {}; +}; + +} // namespace rex::runtime +// (removed orphan xe namespace) diff --git a/include/rex/system/xexception.h b/include/rex/system/xexception.h new file mode 100644 index 0000000..70483a4 --- /dev/null +++ b/include/rex/system/xexception.h @@ -0,0 +1,44 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified 2026 Tom Clay + * Modified for rexglue - Xbox 360 recompilation framework + * + * @changes - Extracted exception types from xbox.h + */ + +#pragma once + +#include +#include + +namespace rex::system { + +#pragma pack(push, 4) + +struct X_EX_TITLE_TERMINATE_REGISTRATION { + be notification_routine; // 0x0 + be priority; // 0x4 + X_LIST_ENTRY list_entry; // 0x8 +}; +static_assert_size(X_EX_TITLE_TERMINATE_REGISTRATION, 16); + +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363082.aspx +struct X_EXCEPTION_RECORD { + be code; + be exception_flags; + be exception_record; + be exception_address; + be number_parameters; + be exception_information[15]; +}; +static_assert_size(X_EXCEPTION_RECORD, 0x50); + +#pragma pack(pop) + +} // namespace rex::system diff --git a/include/rex/system/xfile.h b/include/rex/system/xfile.h new file mode 100644 index 0000000..6063f3c --- /dev/null +++ b/include/rex/system/xfile.h @@ -0,0 +1,150 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::system { + +// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_file_directory_information +class X_FILE_DIRECTORY_INFORMATION { + public: + // FILE_DIRECTORY_INFORMATION + be next_entry_offset; // 0x0 + be file_index; // 0x4 + be creation_time; // 0x8 + be last_access_time; // 0x10 + be last_write_time; // 0x18 + be change_time; // 0x20 + be end_of_file; // 0x28 size in bytes + be allocation_size; // 0x30 + be attributes; // 0x38 X_FILE_ATTRIBUTES + be file_name_length; // 0x3C + char file_name[1]; // 0x40 + + void Write(uint8_t* base, uint32_t p) { + uint8_t* dst = base + p; + uint8_t* src = reinterpret_cast(this); + X_FILE_DIRECTORY_INFORMATION* right; + do { + auto left = reinterpret_cast(dst); + right = reinterpret_cast(src); + left->next_entry_offset = right->next_entry_offset; + left->file_index = right->file_index; + left->creation_time = right->creation_time; + left->last_access_time = right->last_access_time; + left->last_write_time = right->last_write_time; + left->change_time = right->change_time; + left->end_of_file = right->end_of_file; + left->allocation_size = right->allocation_size; + left->attributes = right->attributes; + left->file_name_length = right->file_name_length; + std::memcpy(left->file_name, right->file_name, right->file_name_length); + + dst += right->next_entry_offset; + src += right->next_entry_offset; + } while (right->next_entry_offset != 0); + } +}; + +class XFile : public XObject { + public: + static const XObject::Type kObjectType = XObject::Type::File; + + XFile(KernelState* kernel_state, rex::filesystem::File* file, bool synchronous); + ~XFile() override; + + rex::filesystem::Device* device() const { return file_->entry()->device(); } + rex::filesystem::Entry* entry() const { return file_->entry(); } + rex::filesystem::File* file() const { return file_; } + uint32_t file_access() const { return file_->file_access(); } + + const std::string& path() const { return file_->entry()->path(); } + const std::string& name() const { return file_->entry()->name(); } + + uint64_t position() const; + void set_position(uint64_t value); + + X_STATUS QueryDirectory(X_FILE_DIRECTORY_INFORMATION* out_info, size_t length, + const std::string_view file_name, bool restart); + + // Don't do within the global critical region because invalidation callbacks + // may be triggered (as per the usual rule of not doing I/O within the global + // critical region). + X_STATUS Read(uint32_t buffer_guess_address, uint32_t buffer_length, uint64_t byte_offset, + uint32_t* out_bytes_read, uint32_t apc_context, bool notify_completion = true); + + X_STATUS ReadScatter(uint32_t segments_guest_address, uint32_t length, uint64_t byte_offset, + uint32_t* out_bytes_read, uint32_t apc_context); + + X_STATUS Write(uint32_t buffer_guess_address, uint32_t buffer_length, uint64_t byte_offset, + uint32_t* out_bytes_written, uint32_t apc_context); + + X_STATUS SetLength(size_t length); + X_STATUS Rename(const std::filesystem::path& file_path); + + void RegisterIOCompletionPort(uint32_t key, object_ref port); + void RemoveIOCompletionPort(uint32_t key); + + bool Save(stream::ByteStream* stream) override; + static object_ref Restore(KernelState* kernel_state, stream::ByteStream* stream); + + bool is_synchronous() const { return is_synchronous_; } + + void SetFindPattern(const std::string_view pattern) { + find_engine_.SetRule(pattern); + find_index_ = 0; + } + + rex::filesystem::Entry* FindNext() { + return file_->entry()->IterateChildren(find_engine_, &find_index_); + } + + protected: + void NotifyIOCompletionPorts(XIOCompletion::IONotification& notification); + + rex::thread::WaitHandle* GetWaitHandle() override { return async_event_.get(); } + + private: + XFile(); + + X_STATUS ReadInternal(uint32_t buffer_guest_address, uint32_t buffer_length, uint64_t byte_offset, + uint32_t* out_bytes_read, uint32_t apc_context, bool notify_completion); + + rex::filesystem::File* file_ = nullptr; + std::unique_ptr async_event_ = nullptr; + + mutable std::mutex file_lock_; + std::mutex completion_port_lock_; + std::vector>> completion_ports_; + + // TODO(benvanik): create flags, open state, etc. + + uint64_t position_ = 0; + + rex::filesystem::WildcardEngine find_engine_; + size_t find_index_ = 0; + + bool is_synchronous_ = false; +}; + +} // namespace rex::system diff --git a/include/rex/system/xio.h b/include/rex/system/xio.h new file mode 100644 index 0000000..a74ef41 --- /dev/null +++ b/include/rex/system/xio.h @@ -0,0 +1,131 @@ +/** + * @file kernel/xio.h + * @brief Xbox 360 I/O structures (overlapped, strings, file attributes) + * + * @copyright Copyright 2020 Ben Vanik. All rights reserved. (Xenia Project) + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +namespace rex::system { + +#pragma pack(push, 4) + +enum X_FILE_ATTRIBUTES : uint32_t { + X_FILE_ATTRIBUTE_NONE = 0x0000, + X_FILE_ATTRIBUTE_READONLY = 0x0001, + X_FILE_ATTRIBUTE_HIDDEN = 0x0002, + X_FILE_ATTRIBUTE_SYSTEM = 0x0004, + X_FILE_ATTRIBUTE_DIRECTORY = 0x0010, + X_FILE_ATTRIBUTE_ARCHIVE = 0x0020, + X_FILE_ATTRIBUTE_DEVICE = 0x0040, + X_FILE_ATTRIBUTE_NORMAL = 0x0080, + X_FILE_ATTRIBUTE_TEMPORARY = 0x0100, + X_FILE_ATTRIBUTE_COMPRESSED = 0x0800, + X_FILE_ATTRIBUTE_ENCRYPTED = 0x4000, +}; + +// Known as XOVERLAPPED to 360 code. +struct XAM_OVERLAPPED { + be result; // 0x0 + be length; // 0x4 + be context; // 0x8 + be event; // 0xC + be completion_routine; // 0x10 + be completion_context; // 0x14 + be extended_error; // 0x18 +}; + +inline uint32_t XOverlappedGetResult(void* ptr) { + auto p = reinterpret_cast(ptr); + return memory::load_and_swap(&p[0]); +} +inline void XOverlappedSetResult(void* ptr, uint32_t value) { + auto p = reinterpret_cast(ptr); + memory::store_and_swap(&p[0], value); +} +inline uint32_t XOverlappedGetLength(void* ptr) { + auto p = reinterpret_cast(ptr); + return memory::load_and_swap(&p[1]); +} +inline void XOverlappedSetLength(void* ptr, uint32_t value) { + auto p = reinterpret_cast(ptr); + memory::store_and_swap(&p[1], value); +} +inline uint32_t XOverlappedGetContext(void* ptr) { + auto p = reinterpret_cast(ptr); + return memory::load_and_swap(&p[2]); +} +inline void XOverlappedSetContext(void* ptr, uint32_t value) { + auto p = reinterpret_cast(ptr); + memory::store_and_swap(&p[2], value); +} +inline X_HANDLE XOverlappedGetEvent(void* ptr) { + auto p = reinterpret_cast(ptr); + return memory::load_and_swap(&p[3]); +} +inline uint32_t XOverlappedGetCompletionRoutine(void* ptr) { + auto p = reinterpret_cast(ptr); + return memory::load_and_swap(&p[4]); +} +inline uint32_t XOverlappedGetCompletionContext(void* ptr) { + auto p = reinterpret_cast(ptr); + return memory::load_and_swap(&p[5]); +} +inline void XOverlappedSetExtendedError(void* ptr, uint32_t value) { + auto p = reinterpret_cast(ptr); + memory::store_and_swap(&p[6], value); +} + +struct X_ANSI_STRING { + be length; + be maximum_length; + be pointer; + + void reset() { + length = 0; + maximum_length = 0; + pointer = 0; + } +}; +static_assert_size(X_ANSI_STRING, 8); + +struct X_UNICODE_STRING { + be length; // 0x0 + be maximum_length; // 0x2 + be pointer; // 0x4 + + void reset() { + length = 0; + maximum_length = 0; + pointer = 0; + } +}; +static_assert_size(X_UNICODE_STRING, 8); + +// https://msdn.microsoft.com/en-us/library/windows/hardware/ff550671(v=vs.85).aspx +struct X_IO_STATUS_BLOCK { + union { + be status; + be pointer; + }; + be information; +}; + +struct X_OBJECT_ATTRIBUTES { + be root_directory; // 0x0 + be name_ptr; // 0x4 PANSI_STRING + be attributes; // 0xC +}; + +#pragma pack(pop) + +} // namespace rex::system diff --git a/include/rex/system/xiocompletion.h b/include/rex/system/xiocompletion.h new file mode 100644 index 0000000..7d75118 --- /dev/null +++ b/include/rex/system/xiocompletion.h @@ -0,0 +1,48 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include + +namespace rex::system { + +class XIOCompletion : public XObject { + public: + static const XObject::Type kObjectType = XObject::Type::IOCompletion; + + explicit XIOCompletion(KernelState* kernel_state); + ~XIOCompletion() override; + + struct IONotification { + uint32_t key_context; + uint32_t apc_context; + uint32_t status; + uint32_t num_bytes; + }; + + void QueueNotification(IONotification& notification); + + // Returns true if the wait ended because a notification was received. + bool WaitForNotification(uint64_t wait_ticks, IONotification* notify); + + private: + static const uint32_t kMaxNotifications = 1024; + + std::mutex notification_lock_; + std::queue notifications_; + std::unique_ptr notification_semaphore_ = nullptr; +}; + +} // namespace rex::system diff --git a/include/rex/system/xmemory.h b/include/rex/system/xmemory.h new file mode 100644 index 0000000..3c3969a --- /dev/null +++ b/include/rex/system/xmemory.h @@ -0,0 +1,586 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include + +#include +#include // PPCFunc type (minimal header) +#include +#include + +namespace rex::stream { +class ByteStream; +} // namespace rex::stream + +namespace rex::memory::detail { + +/// Compensates for Windows 64KB allocation granularity on the 0xE0 physical heap. +/// The backing file maps the 0xE0 heap at a 0x1000-byte offset, but MapViewOfFileEx +/// rounds down to 64KB boundaries. Linux mmap handles 4KB offsets natively. +constexpr u32 PhysicalHostOffset([[maybe_unused]] u32 guest_addr) noexcept { +#if REX_PLATFORM_WIN32 + return (guest_addr >= 0xE0000000u) ? 0x1000u : 0u; +#else + return 0u; +#endif +} + +} // namespace rex::memory::detail + +namespace rex::memory { + +/// Lightweight guest-to-host pointer translation using the memory base. +/// For hooks and kernel code operating with the base pointer directly. +/// Same raw arithmetic as recompiled code; no Memory* or heap lookup needed. +template +inline T GuestPtr(u8* base, u32 guest_address) noexcept { + return reinterpret_cast(base + guest_address + detail::PhysicalHostOffset(guest_address)); +} + +class Memory; + +enum SystemHeapFlag : uint32_t { + kSystemHeapVirtual = 1 << 0, + kSystemHeapPhysical = 1 << 1, + + kSystemHeapDefault = kSystemHeapVirtual, +}; + +enum class HeapType : uint8_t { + kGuestVirtual, + kGuestXex, + kGuestPhysical, + kHostPhysical, +}; + +enum MemoryAllocationFlag : uint32_t { + kMemoryAllocationReserve = 1 << 0, + kMemoryAllocationCommit = 1 << 1, +}; + +enum MemoryProtectFlag : uint32_t { + kMemoryProtectRead = 1 << 0, + kMemoryProtectWrite = 1 << 1, + kMemoryProtectNoCache = 1 << 2, + kMemoryProtectWriteCombine = 1 << 3, + + kMemoryProtectNoAccess = 0, +}; + +// Equivalent to the Win32 MEMORY_BASIC_INFORMATION struct. +struct HeapAllocationInfo { + // A pointer to the base address of the region of pages. + uint32_t base_address; + // A pointer to the base address of a range of pages allocated by the + // VirtualAlloc function. The page pointed to by the BaseAddress member is + // contained within this allocation range. + uint32_t allocation_base; + // The memory protection option when the region was initially allocated. + uint32_t allocation_protect; + // The size specified when the region was initially allocated, in bytes. + uint32_t allocation_size; + // The size of the region beginning at the base address in which all pages + // have identical attributes, in bytes. + uint32_t region_size; + // The state of the pages in the region (commit/free/reserve). + uint32_t state; + // The access protection of the pages in the region. + uint32_t protect; +}; + +// Describes a single page in the page table. +union PageEntry { + uint64_t qword; + struct { + // Base address of the allocated region in 4k pages. + uint32_t base_address : 20; + // Total number of pages in the allocated region in 4k pages. + uint32_t region_page_count : 20; + // Protection bits specified during region allocation. + // Composed of bits from MemoryProtectFlag. + uint32_t allocation_protect : 4; + // Current protection bits as of the last Protect. + // Composed of bits from MemoryProtectFlag. + uint32_t current_protect : 4; + // Allocation state of the page as a MemoryAllocationFlag bit mask. + uint32_t state : 2; + uint32_t reserved : 14; + }; +}; + +// Heap abstraction for page-based allocation. +class BaseHeap { + public: + virtual ~BaseHeap(); + + // Offset of the heap in relative to membase, without host_address_offset + // adjustment. + uint32_t heap_base() const { return heap_base_; } + + // Length of the heap range. + uint32_t heap_size() const { return heap_size_; } + + // Size of each page within the heap range in bytes. + uint32_t page_size() const { return page_size_; } + + // Type of specified heap + HeapType heap_type() const { return heap_type_; } + + // Offset added to the virtual addresses to convert them to host addresses + // (not including membase). + uint32_t host_address_offset() const { return host_address_offset_; } + + template + inline T TranslateRelative(size_t relative_address) const { + return reinterpret_cast(membase_ + heap_base_ + host_address_offset_ + relative_address); + } + + // Disposes and decommits all memory and clears the page table. + virtual void Dispose(); + + // Dumps information about all allocations within the heap to the log. + void DumpMap(); + + uint32_t GetTotalPageCount(); + uint32_t GetUnreservedPageCount(); + + uint32_t total_page_count() const { return uint32_t(page_table_.size()); } + uint32_t unreserved_page_count() const { return unreserved_page_count_; } + uint32_t reserved_page_count() const { return total_page_count() - unreserved_page_count(); } + + // Allocates pages with the given properties and allocation strategy. + // This can reserve and commit the pages as well as set protection modes. + // This will fail if not enough contiguous pages can be found. + virtual bool Alloc(uint32_t size, uint32_t alignment, uint32_t allocation_type, uint32_t protect, + bool top_down, uint32_t* out_address); + + // Allocates pages at the given address. + // This can reserve and commit the pages as well as set protection modes. + // This will fail if the pages are already allocated. + virtual bool AllocFixed(uint32_t base_address, uint32_t size, uint32_t alignment, + uint32_t allocation_type, uint32_t protect); + + // Allocates pages at an address within the given address range. + // This can reserve and commit the pages as well as set protection modes. + // This will fail if not enough contiguous pages can be found. + virtual bool AllocRange(uint32_t low_address, uint32_t high_address, uint32_t size, + uint32_t alignment, uint32_t allocation_type, uint32_t protect, + bool top_down, uint32_t* out_address); + + // Allocates from the system portion of the heap (top of virtual heaps). + // Physical heaps delegate to regular Alloc since there is no split. + virtual bool AllocSystemHeap(uint32_t size, uint32_t alignment, uint32_t allocation_type, + uint32_t protect, bool top_down, uint32_t* out_address); + + // Decommits pages in the given range. + // Partial overlapping pages will also be decommitted. + virtual bool Decommit(uint32_t address, uint32_t size); + + // Decommits and releases pages in the given range. + // Partial overlapping pages will also be released. + virtual bool Release(uint32_t address, uint32_t* out_region_size = nullptr); + + // Modifies the protection mode of pages within the given range. + virtual bool Protect(uint32_t address, uint32_t size, uint32_t protect, + uint32_t* old_protect = nullptr); + + // Queries information about the given region of pages. + bool QueryRegionInfo(uint32_t base_address, HeapAllocationInfo* out_info); + + // Queries the size of the region containing the given address. + bool QuerySize(uint32_t address, uint32_t* out_size); + + // Queries the base and size of a region containing the given address. + bool QueryBaseAndSize(uint32_t* in_out_address, uint32_t* out_size); + + // Queries the current protection mode of the region containing the given + // address. + bool QueryProtect(uint32_t address, uint32_t* out_protect); + + // Queries the currently strictest readability and writability for the entire + // range. + rex::memory::PageAccess QueryRangeAccess(uint32_t low_address, uint32_t high_address); + + bool Save(stream::ByteStream* stream); + bool Restore(stream::ByteStream* stream); + + void Reset(); + + protected: + BaseHeap(); + + void Initialize(memory::Memory* memory, uint8_t* membase, HeapType heap_type, uint32_t heap_base, + uint32_t heap_size, uint32_t page_size, uint32_t host_address_offset = 0); + + memory::Memory* memory_; + uint8_t* membase_; + HeapType heap_type_; + uint32_t heap_base_; + uint32_t heap_size_; + uint32_t page_size_; + uint32_t page_size_shift_ = 0; + uint32_t host_address_offset_; + uint32_t unreserved_page_count_ = 0; + rex::thread::global_critical_region global_critical_region_; + std::recursive_mutex heap_mutex_; + std::vector page_table_; +}; + +// Normal heap allowing allocations from guest virtual address ranges. +class VirtualHeap : public BaseHeap { + public: + VirtualHeap(); + ~VirtualHeap() override; + + // Initializes the heap properties and allocates the page table. + void Initialize(memory::Memory* memory, uint8_t* membase, HeapType heap_type, uint32_t heap_base, + uint32_t heap_size, uint32_t page_size); +}; + +// A heap for ranges of memory that are mapped to physical ranges. +// Physical ranges are used by the audio and graphics subsystems representing +// hardware wired directly to memory in the console. +// +// The physical heap and the behavior of sharing pages with virtual pages is +// implemented by having a 'parent' heap that is used to perform allocation in +// the guest virtual address space 1:1 with the physical address space. +class PhysicalHeap : public BaseHeap { + public: + PhysicalHeap(); + ~PhysicalHeap() override; + + // Initializes the heap properties and allocates the page table. + void Initialize(memory::Memory* memory, uint8_t* membase, HeapType heap_type, uint32_t heap_base, + uint32_t heap_size, uint32_t page_size, VirtualHeap* parent_heap); + + bool Alloc(uint32_t size, uint32_t alignment, uint32_t allocation_type, uint32_t protect, + bool top_down, uint32_t* out_address) override; + bool AllocFixed(uint32_t base_address, uint32_t size, uint32_t alignment, + uint32_t allocation_type, uint32_t protect) override; + bool AllocRange(uint32_t low_address, uint32_t high_address, uint32_t size, uint32_t alignment, + uint32_t allocation_type, uint32_t protect, bool top_down, + uint32_t* out_address) override; + bool AllocSystemHeap(uint32_t size, uint32_t alignment, uint32_t allocation_type, + uint32_t protect, bool top_down, uint32_t* out_address) override; + bool Decommit(uint32_t address, uint32_t size) override; + bool Release(uint32_t base_address, uint32_t* out_region_size = nullptr) override; + bool Protect(uint32_t address, uint32_t size, uint32_t protect, + uint32_t* old_protect = nullptr) override; + + void EnableAccessCallbacks(uint32_t physical_address, uint32_t length, + bool enable_invalidation_notifications, bool enable_data_providers); + // Returns true if any page in the range was watched. + bool TriggerCallbacks(std::unique_lock global_lock_locked_once, + uint32_t virtual_address, uint32_t length, bool is_write, + bool unwatch_exact_range, bool unprotect = true); + + uint32_t GetPhysicalAddress(uint32_t address) const; + + protected: + VirtualHeap* parent_heap_; + + uint32_t system_page_size_; + uint32_t system_page_count_; + + struct SystemPageFlagsBlock { + // Whether writing to each page should result trigger invalidation + // callbacks. + uint64_t notify_on_invalidation; + }; + // Protected by global_critical_region. Flags for each 64 system pages, + // interleaved as blocks, so bit scan can be used to quickly extract ranges. + std::vector system_page_flags_; +}; + +// Models the entire guest memory system on the console. +// This exposes interfaces to both virtual and physical memory and a TLB and +// page table for allocation, mapping, and protection. +// +// The memory is backed by a memory mapped file and is placed at a stable +// fixed address in the host address space (like 0x100000000). This allows +// efficient guest<->host address translations as well as easy sharing of the +// memory across various subsystems. +// +// The guest memory address space is split into several ranges that have varying +// properties such as page sizes, caching strategies, protections, and +// overlap with other ranges. Each range is represented by a BaseHeap of either +// VirtualHeap or PhysicalHeap depending on type. Heaps model the page tables +// and can handle reservation and committing of requested pages. +class Memory { + public: + Memory(); + ~Memory(); + + // Initializes the memory system. + // This may fail if the host address space could not be reserved or the + // mapping to the file system fails. + bool Initialize(); + + // Resets all memory to zero and resets all allocations. + void Reset(); + + // Full file name and path of the memory-mapped file backing all memory. + const std::filesystem::path& file_name() const { return file_name_; } + + // Base address of virtual memory in the host address space. + // This is often something like 0x100000000. + inline uint8_t* virtual_membase() const { return virtual_membase_; } + + // Translates a guest virtual address to a host address that can be accessed + // as a normal pointer. + // Note that the contents at the specified host address are big-endian. + template + inline T TranslateVirtual(uint32_t guest_address) const { + uint8_t* host_address = virtual_membase_ + guest_address; + const auto heap = LookupHeap(guest_address); + if (heap) { + host_address += heap->host_address_offset(); + } + return reinterpret_cast(host_address); + } + + // Base address of physical memory in the host address space. + // This is often something like 0x200000000. + inline uint8_t* physical_membase() const { return physical_membase_; } + + // Translates a guest physical address to a host address that can be accessed + // as a normal pointer. + // Note that the contents at the specified host address are big-endian. + template + inline T TranslatePhysical(uint32_t guest_address) const { + return reinterpret_cast(physical_membase_ + (guest_address & 0x1FFFFFFF)); + } + + // Translates a host address to a guest virtual address. + // Note that the contents at the returned host address are big-endian. + uint32_t HostToGuestVirtual(const void* host_address) const; + + // Returns the guest physical address for the guest virtual address, or + // UINT32_MAX if it can't be obtained. + uint32_t GetPhysicalAddress(uint32_t address) const; + + // Zeros out a range of memory at the given guest address. + void Zero(uint32_t address, uint32_t size); + + // Fills a range of guest memory with the given byte value. + void Fill(uint32_t address, uint32_t size, uint8_t value); + + // Copies a non-overlapping range of guest memory (like a memcpy). + void Copy(uint32_t dest, uint32_t src, uint32_t size); + + // Searches the given range of guest memory for a run of dword values in + // big-endian order. + uint32_t SearchAligned(uint32_t start, uint32_t end, const uint32_t* values, size_t value_count); + + // Defines a memory-mapped IO (MMIO) virtual address range that when accessed + // will trigger the specified read and write callbacks for dword read/writes. + bool AddVirtualMappedRange(uint32_t virtual_address, uint32_t mask, uint32_t size, void* context, + runtime::MMIOReadCallback read_callback, + runtime::MMIOWriteCallback write_callback); + + // Gets the defined MMIO range for the given virtual address, if any. + runtime::MMIORange* LookupVirtualMappedRange(uint32_t virtual_address); + + // Physical memory access callbacks, two types of them. + // + // This is simple per-system-page protection without reference counting or + // stored ranges. Whenever a watched page is accessed, all callbacks for it + // are triggered. Also the only way to remove callbacks is to trigger them + // somehow. Since there are no references from pages to individual callbacks, + // there's no way to disable only a specific callback for a page. Also + // callbacks may be triggered spuriously, and handlers should properly ignore + // pages they don't care about. + // + // Once callbacks are triggered for a page, the page is not watched anymore + // until requested again later. It is, however, unwatched only in one guest + // view of physical memory (because different views may have different + // protection for the same memory) - but it's rare when the same memory is + // used with different guest page sizes, and it's okay to fire a callback more + // than once. + // + // Only accessing the guest virtual memory views of physical memory triggers + // callbacks - data providers, for instance, must write to the host physical + // heap directly, otherwise their threads may infinitely await themselves. + // + // - Invalidation notifications: + // + // Protecting from writing. One-shot callbacks for invalidation of various + // kinds of physical memory caches (such as the GPU copy of the memory). + // + // May be triggered for a single page (in case of a write access violation or + // when need to synchronize data given by data providers) or for multiple + // pages (like when memory is released, or explicitly to trigger callbacks + // when host-side code can't rely on regular access violations, like when + // accessing a file). + // + // Since granularity of callbacks is one single page, an invalidation + // notification handler must invalidate the all the data stored in the touched + // pages. + // + // Because large ranges (like whole framebuffers) may be written to and + // exceptions are expensive, it's better to unprotect multiple pages as a + // result of a write access violation, so the shortest common range returned + // by all the invalidation callbacks (clamped to a sane range and also not to + // touch pages with provider callbacks) is unprotected. + // + // - Data providers: + // + // TODO(Triang3l): Implement data providers - more complicated because they + // will need to be able to release the global lock. + + // Returns start and length of the smallest physical memory region surrounding + // the watched region that can be safely unwatched, if it doesn't matter, + // return (0, UINT32_MAX). + typedef std::pair (*PhysicalMemoryInvalidationCallback)( + void* context_ptr, uint32_t physical_address_start, uint32_t length, bool exact_range); + // Returns a handle for unregistering or for skipping one notification handler + // while triggering data providers. + void* RegisterPhysicalMemoryInvalidationCallback(PhysicalMemoryInvalidationCallback callback, + void* callback_context); + // Unregisters a physical memory invalidation callback previously added with + // RegisterPhysicalMemoryInvalidationCallback. + void UnregisterPhysicalMemoryInvalidationCallback(void* callback_handle); + + // Enables physical memory access callbacks for the specified memory range, + // snapped to system page boundaries. + void EnablePhysicalMemoryAccessCallbacks(uint32_t physical_address, uint32_t length, + bool enable_invalidation_notifications, + bool enable_data_providers); + + // Forces triggering of watch callbacks for a virtual address range if pages + // are watched there and unwatching them. Returns whether any page was + // watched. Must be called with global critical region locking depth of 1. + // TODO(Triang3l): Implement data providers - this is why locking depth of 1 + // will be required in the future. + bool TriggerPhysicalMemoryCallbacks( + std::unique_lock global_lock_locked_once, uint32_t virtual_address, + uint32_t length, bool is_write, bool unwatch_exact_range, bool unprotect = true); + + // Allocates virtual memory from the 'system' heap. + // System memory is kept separate from game memory but is still accessible + // using normal guest virtual addresses. Kernel structures and other internal + // 'system' allocations should come from this heap when possible. + uint32_t SystemHeapAlloc(uint32_t size, uint32_t alignment = 0x20, + uint32_t system_heap_flags = kSystemHeapDefault); + + // Frees memory allocated with SystemHeapAlloc. + void SystemHeapFree(uint32_t address, uint32_t* out_region_size = nullptr); + + // Gets the heap for the address space containing the given address. + const BaseHeap* LookupHeap(uint32_t address) const; + + inline BaseHeap* LookupHeap(uint32_t address) { + return const_cast(const_cast(this)->LookupHeap(address)); + } + + // Gets the heap with the given properties. + BaseHeap* LookupHeapByType(bool physical, uint32_t page_size); + + // Aggregates page statistics across the given heaps. + void GetHeapsPageStatsSummary(const BaseHeap* const* provided_heaps, size_t heaps_count, + uint32_t& unreserved_pages, uint32_t& reserved_pages, + uint32_t& used_pages, uint32_t& reserved_bytes); + + // Gets the physical base heap. + VirtualHeap* GetPhysicalHeap(); + + // Dumps a map of all allocated memory to the log. + void DumpMap(); + + bool Save(stream::ByteStream* stream); + bool Restore(stream::ByteStream* stream); + + //========================================================================== + // Recompiled Code Function Table API + //========================================================================== + // Per-module function dispatch table at IMAGE_BASE + IMAGE_SIZE, indexed by + // (guest_addr - code_base) * 2. Internally locked: callers may invoke from + // any thread. + bool InitializeFunctionTable(uint32_t code_base, uint32_t code_size, uint32_t image_base, + uint32_t image_size); + bool DestroyFunctionTable(uint32_t code_base); + // Returns false if guest_address is outside every registered module range. + bool SetFunction(uint32_t guest_address, PPCFunc* host_function); + bool HasAnyFunctionTable() const; + + private: + int MapViews(uint8_t* mapping_base); + void UnmapViews(); + + static uint32_t HostToGuestVirtualThunk(const void* context, const void* host_address); + + bool AccessViolationCallback(std::unique_lock global_lock_locked_once, + void* host_address, bool is_write); + static bool AccessViolationCallbackThunk( + std::unique_lock global_lock_locked_once, void* context, + void* host_address, bool is_write); + + std::filesystem::path file_name_; + uint32_t system_page_size_ = 0; + uint32_t system_allocation_granularity_ = 0; + uint8_t* virtual_membase_ = nullptr; + uint8_t* physical_membase_ = nullptr; + + struct FunctionTableEntry { + uint32_t table_base; + uint32_t code_base; + uint32_t code_size; + uint32_t thunk_reserve; + }; + std::vector function_tables_; + mutable std::mutex function_tables_mutex_; + + rex::memory::FileMappingHandle mapping_ = rex::memory::kFileMappingHandleInvalid; + uint8_t* mapping_base_ = nullptr; + union { + struct { + uint8_t* v00000000; + uint8_t* v40000000; + uint8_t* v7F000000; + uint8_t* v80000000; + uint8_t* v90000000; + uint8_t* vA0000000; + uint8_t* vC0000000; + uint8_t* vE0000000; + uint8_t* physical; + }; + uint8_t* all_views[9]; + } views_ = {{0, 0, 0, 0, 0, 0, 0, 0, 0}}; + + std::unique_ptr mmio_handler_; + + struct { + VirtualHeap v00000000; + VirtualHeap v40000000; + VirtualHeap v80000000; + VirtualHeap v90000000; + + VirtualHeap physical; + PhysicalHeap vA0000000; + PhysicalHeap vC0000000; + PhysicalHeap vE0000000; + } heaps_; + + friend class BaseHeap; + + friend class PhysicalHeap; + rex::thread::global_critical_region global_critical_region_; + std::vector*> + physical_memory_invalidation_callbacks_; +}; + +} // namespace rex::memory diff --git a/include/rex/system/xmodule.h b/include/rex/system/xmodule.h new file mode 100644 index 0000000..f6f6a47 --- /dev/null +++ b/include/rex/system/xmodule.h @@ -0,0 +1,97 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include + +namespace rex::system { + +constexpr memory::fourcc_t kModuleSaveSignature = memory::make_fourcc("XMOD"); + +// https://www.nirsoft.net/kernel_struct/vista/LDR_DATA_TABLE_ENTRY.html +// HMODULE points to this struct! +struct X_LDR_DATA_TABLE_ENTRY { + X_LIST_ENTRY in_load_order_links; // 0x0 + X_LIST_ENTRY in_memory_order_links; // 0x8 + X_LIST_ENTRY in_initialization_order_links; // 0x10 + + rex::be dll_base; // 0x18 + rex::be image_base; // 0x1C + rex::be image_size; // 0x20 + + X_UNICODE_STRING full_dll_name; // 0x24 + X_UNICODE_STRING base_dll_name; // 0x2C + + rex::be flags; // 0x34 + rex::be full_image_size; // 0x38 + rex::be entry_point; // 0x3C + rex::be load_count; // 0x40 + rex::be module_index; // 0x42 + rex::be dll_base_original; // 0x44 + rex::be checksum; // 0x48 hijacked to hold kernel handle + rex::be load_flags; // 0x4C + rex::be time_date_stamp; // 0x50 + rex::be loaded_imports; // 0x54 + rex::be xex_header_base; // 0x58 + // X_ANSI_STRING load_file_name; // 0x5C + rex::be closure_root; // 0x5C + rex::be traversal_parent; // 0x60 +}; + +class XModule : public XObject { + public: + enum class ModuleType { + // Matches debugger Module type. + kKernelModule = 0, + kUserModule = 1, + }; + + static const XObject::Type kObjectType = XObject::Type::Module; + + XModule(KernelState* kernel_state, ModuleType module_type); + virtual ~XModule(); + + ModuleType module_type() const { return module_type_; } + virtual const std::string& path() const = 0; + virtual const std::string& name() const = 0; + bool Matches(const std::string_view name) const; + + rex::runtime::Module* processor_module() const { return processor_module_; } + uint32_t hmodule_ptr() const { return hmodule_ptr_; } + + virtual uint32_t GetProcAddressByOrdinal(uint16_t ordinal, uint32_t caller_address = 0) = 0; + virtual uint32_t GetProcAddressByName(const std::string_view name) = 0; + virtual X_STATUS GetSection(const std::string_view name, uint32_t* out_section_data, + uint32_t* out_section_size); + + static object_ref GetFromHModule(KernelState* kernel_state, void* hmodule); + static uint32_t GetHandleFromHModule(void* hmodule); + + virtual bool Save(stream::ByteStream* stream) override; + static object_ref Restore(KernelState* kernel_state, stream::ByteStream* stream); + + protected: + void OnLoad(); + void OnUnload(); + + ModuleType module_type_; + + rex::runtime::Module* processor_module_; + + uint32_t hmodule_ptr_; // This points to LDR_DATA_TABLE_ENTRY. +}; + +} // namespace rex::system diff --git a/include/rex/system/xmutant.h b/include/rex/system/xmutant.h new file mode 100644 index 0000000..6498d15 --- /dev/null +++ b/include/rex/system/xmutant.h @@ -0,0 +1,47 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +namespace rex::system { + +class XThread; + +class XMutant : public XObject { + public: + static const XObject::Type kObjectType = XObject::Type::Mutant; + + explicit XMutant(KernelState* kernel_state); + ~XMutant() override; + + void Initialize(bool initial_owner); + void InitializeNative(void* native_ptr, X_DISPATCH_HEADER* header); + + X_STATUS ReleaseMutant(uint32_t priority_increment, bool abandon, bool wait); + + bool Save(stream::ByteStream* stream) override; + static object_ref Restore(KernelState* kernel_state, stream::ByteStream* stream); + + protected: + rex::thread::WaitHandle* GetWaitHandle() override { return mutant_.get(); } + void WaitCallback() override; + + private: + XMutant(); + + std::unique_ptr mutant_; + XThread* owning_thread_ = nullptr; +}; + +} // namespace rex::system diff --git a/include/rex/system/xnotifylistener.h b/include/rex/system/xnotifylistener.h new file mode 100644 index 0000000..39a2a7b --- /dev/null +++ b/include/rex/system/xnotifylistener.h @@ -0,0 +1,72 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace rex::system { + +union XNotificationKey { + XNotificationID id; + struct { + uint32_t local_id : 16; + uint32_t version : 9; + uint32_t mask_index : 6; + uint32_t : 1; + }; + + constexpr XNotificationKey(XNotificationID notification_id = XNotificationID(0)) + : id(notification_id) { + static_assert_size(*this, sizeof(id)); + } + + constexpr operator XNotificationID() { return id; } +}; + +class XNotifyListener : public XObject { + public: + static const XObject::Type kObjectType = XObject::Type::NotifyListener; + + explicit XNotifyListener(KernelState* kernel_state); + ~XNotifyListener() override; + + uint64_t mask() const { return mask_; } + uint32_t max_version() const { return max_version_; } + + void Initialize(uint64_t mask, uint32_t max_version); + + void EnqueueNotification(XNotificationID id, uint32_t data); + bool DequeueNotification(XNotificationID* out_id, uint32_t* out_data); + bool DequeueNotification(XNotificationID id, uint32_t* out_data); + + bool Save(stream::ByteStream* stream) override; + static object_ref Restore(KernelState* kernel_state, stream::ByteStream* stream); + + protected: + rex::thread::WaitHandle* GetWaitHandle() override { return wait_handle_.get(); } + + private: + std::unique_ptr wait_handle_; + rex::thread::global_critical_region global_critical_region_; + std::vector> notifications_; + uint64_t mask_ = 0; + uint32_t max_version_ = 0; +}; + +} // namespace rex::system diff --git a/include/rex/system/xobject.h b/include/rex/system/xobject.h new file mode 100644 index 0000000..0a43f07 --- /dev/null +++ b/include/rex/system/xobject.h @@ -0,0 +1,389 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +namespace rex { +class Runtime; +namespace stream { +class ByteStream; +} // namespace stream +} // namespace rex + +namespace rex::system { + +constexpr memory::fourcc_t kXObjSignature = memory::make_fourcc('R', 'E', 'X', '\0'); + +class KernelState; + +template +class object_ref; + +// https://www.nirsoft.net/kernel_struct/vista/DISPATCHER_HEADER.html +typedef struct { + struct { + uint8_t type; + + union { + uint8_t abandoned; + uint8_t absolute; + uint8_t npx_irql; + uint8_t signalling; + }; + union { + uint8_t size; + uint8_t hand; + uint8_t process_type; + }; + union { + uint8_t inserted; + uint8_t debug_active; + uint8_t dpc_active; + }; + }; + + rex::be signal_state; + rex::be wait_list_flink; + rex::be wait_list_blink; +} X_DISPATCH_HEADER; +static_assert_size(X_DISPATCH_HEADER, 0x10); + +// https://www.nirsoft.net/kernel_struct/vista/OBJECT_HEADER.html +struct X_OBJECT_HEADER { + rex::be pointer_count; + union { + rex::be handle_count; + rex::be next_to_free; + }; + uint8_t name_info_offset; + uint8_t handle_info_offset; + uint8_t quota_info_offset; + uint8_t flags; + union { + rex::be object_create_info; // X_OBJECT_CREATE_INFORMATION + rex::be quota_block_charged; + }; + rex::be object_type_ptr; // -0x8 POBJECT_TYPE + rex::be unk_04; // -0x4 + + // Object lives after this header. + // (There's actually a body field here which is the object itself) +}; + +// https://www.nirsoft.net/kernel_struct/vista/OBJECT_CREATE_INFORMATION.html +struct X_OBJECT_CREATE_INFORMATION { + rex::be attributes; // 0x0 + rex::be root_directory_ptr; // 0x4 + rex::be parse_context_ptr; // 0x8 + rex::be probe_mode; // 0xC + rex::be paged_pool_charge; // 0x10 + rex::be non_paged_pool_charge; // 0x14 + rex::be security_descriptor_charge; // 0x18 + rex::be security_descriptor; // 0x1C + rex::be security_qos_ptr; // 0x20 + + // Security QoS here (SECURITY_QUALITY_OF_SERVICE) too! +}; + +struct X_OBJECT_TYPE { + rex::be constructor; // 0x0 + rex::be destructor; // 0x4 + rex::be unk_08; // 0x8 + rex::be unk_0C; // 0xC + rex::be unk_10; // 0x10 + rex::be unk_14; // 0x14 probably offset from ntobject to keobject + rex::be pool_tag; // 0x18 +}; + +class XObject { + public: + // 45410806 needs proper handle value for certain calculations + // It gets handle value from TLS (without base handle value is 0x88) + // and substract 0xF8000088. Without base we're receiving wrong address + // Instead of receiving address that starts with 0x82... we're receiving + // one with 0x8A... which causes crash + static constexpr uint32_t kHandleBase = 0xF8000000; + + enum class Type : uint32_t { + Undefined, + Enumerator, + Event, + File, + IOCompletion, + Module, + Mutant, + NotifyListener, + Semaphore, + Session, + Socket, + SymbolicLink, + Thread, + Timer, + }; + + XObject(Type type); + XObject(KernelState* kernel_state, Type type); + virtual ~XObject(); + + rex::Runtime* emulator() const; + KernelState* kernel_state() const; + rex::memory::Memory* memory() const; + + Type type() const; + + // Returns the primary handle of this object. + X_HANDLE handle() const { return handles_[0]; } + + // Returns all associated handles with this object. + std::vector handles() const { return handles_; } + std::vector& handles() { return handles_; } + + const std::string& name() const { return name_; } + uint32_t guest_object() const { return guest_object_ptr_; } + + // Has this object been created for use by the host? + // Host objects are persisted through reloads/etc. + bool is_host_object() const { return host_object_; } + void set_host_object(bool host_object) { host_object_ = host_object; } + + template + T* guest_object() { + return memory()->TranslateVirtual(guest_object_ptr_); + } + + void RetainHandle(); + bool ReleaseHandle(); + void Retain(); + void Release(); + X_STATUS Delete(); + + virtual bool Save(stream::ByteStream* stream) { + (void)stream; + return false; + } + static object_ref Restore(KernelState* kernel_state, Type type, + stream::ByteStream* stream); + + // Reference() + // Dereference() + + void SetAttributes(uint32_t obj_attributes_ptr); + + X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable, + uint64_t* opt_timeout); + static X_STATUS SignalAndWait(XObject* signal_object, XObject* wait_object, uint32_t wait_reason, + uint32_t processor_mode, uint32_t alertable, uint64_t* opt_timeout); + static X_STATUS WaitMultiple(uint32_t count, XObject** objects, uint32_t wait_type, + uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable, + uint64_t* opt_timeout); + + static object_ref GetNativeObject(KernelState* kernel_state, void* native_ptr, + int32_t as_type = -1); + template + static object_ref GetNativeObject(KernelState* kernel_state, void* native_ptr, + int32_t as_type = -1); + + protected: + bool SaveObject(stream::ByteStream* stream); + bool RestoreObject(stream::ByteStream* stream); + + // Called on successful wait. + virtual void WaitCallback() {} + virtual rex::thread::WaitHandle* GetWaitHandle() { return nullptr; } + + // Creates the kernel object for guest code to use. Typically not needed. + uint8_t* CreateNative(uint32_t size); + void SetNativePointer(uint32_t native_ptr, bool uninitialized = false); + + template + T* CreateNative() { + return reinterpret_cast(CreateNative(sizeof(T))); + } + + // Stash native pointer into X_DISPATCH_HEADER + static void StashHandle(X_DISPATCH_HEADER* header, uint32_t handle) { + header->wait_list_flink = kXObjSignature; + header->wait_list_blink = handle; + } + + static uint32_t TimeoutTicksToMs(int64_t timeout_ticks); + + KernelState* kernel_state_; + + // Host objects are persisted through resets/etc. + bool host_object_ = false; + + private: + std::atomic pointer_ref_count_; + + Type type_; + std::vector handles_; + std::string name_; // May be zero length. + + // Guest pointer for kernel object. Remember: X_OBJECT_HEADER precedes this + // if we allocated it! + uint32_t guest_object_ptr_ = 0; + bool allocated_guest_object_ = false; +}; + +template +class object_ref { + public: + object_ref() noexcept : value_(nullptr) {} + object_ref(std::nullptr_t) noexcept // NOLINT(runtime/explicit) + : value_(nullptr) {} + object_ref& operator=(std::nullptr_t) noexcept { + reset(); + return (*this); + } + + explicit object_ref(T* value) noexcept : value_(value) { + // Assumes retained on call. + } + explicit object_ref(const object_ref& right) noexcept { + reset(right.get()); + if (value_) + value_->Retain(); + } + template + requires std::convertible_to + object_ref(const object_ref& right) noexcept { + reset(right.get()); + if (value_) + value_->Retain(); + } + + object_ref(object_ref&& right) noexcept : value_(right.release()) {} + object_ref& operator=(object_ref&& right) noexcept { + object_ref(std::move(right)).swap(*this); + return (*this); + } + template + object_ref& operator=(object_ref&& right) noexcept { + object_ref(std::move(right)).swap(*this); + return (*this); + } + + object_ref& operator=(const object_ref& right) noexcept { + object_ref(right).swap(*this); // NOLINT(runtime/explicit): misrecognized? + return (*this); + } + template + object_ref& operator=(const object_ref& right) noexcept { + object_ref(right).swap(*this); // NOLINT(runtime/explicit): misrecognized? + return (*this); + } + + void swap(object_ref& right) noexcept { std::swap(value_, right.value_); } + + ~object_ref() noexcept { + if (value_) { + value_->Release(); + value_ = nullptr; + } + } + + typename std::add_lvalue_reference::type operator*() const { return (*get()); } + + T* operator->() const noexcept { return std::pointer_traits::pointer_to(**this); } + + T* get() const noexcept { return value_; } + + template + V* get() const noexcept { + return reinterpret_cast(value_); + } + + explicit operator bool() const noexcept { return value_ != nullptr; } + + T* release() noexcept { + T* value = value_; + value_ = nullptr; + return value; + } + + void reset() noexcept { object_ref().swap(*this); } + + void reset(T* value) noexcept { object_ref(value).swap(*this); } + + inline bool operator==(const T* right) const noexcept { return value_ == right; } + inline bool operator!=(const T* right) const noexcept { return value_ != right; } + + // Explicit nullptr comparison to avoid C++20 synthesized operator ambiguity + inline bool operator==(std::nullptr_t) const noexcept { return value_ == nullptr; } + inline bool operator!=(std::nullptr_t) const noexcept { return value_ != nullptr; } + + private: + T* value_ = nullptr; +}; + +template +bool operator==(const object_ref<_Ty>& _Left, std::nullptr_t) noexcept { + return (_Left.get() == reinterpret_cast<_Ty*>(0)); +} + +template +bool operator==(std::nullptr_t, const object_ref<_Ty>& _Right) noexcept { + return (reinterpret_cast<_Ty*>(0) == _Right.get()); +} + +template +bool operator!=(const object_ref<_Ty>& _Left, std::nullptr_t _Right) noexcept { + return (!(_Left == _Right)); +} + +template +bool operator!=(std::nullptr_t _Left, const object_ref<_Ty>& _Right) noexcept { + return (!(_Left == _Right)); +} + +template + requires(!std::is_array_v) +object_ref make_object(Args&&... args) { + return object_ref(new T(std::forward(args)...)); +} + +template +object_ref retain_object(T* ptr) { + if (ptr) + ptr->Retain(); + return object_ref(ptr); +} + +template +object_ref XObject::GetNativeObject(KernelState* kernel_state, void* native_ptr, + int32_t as_type) { + return object_ref( + reinterpret_cast(GetNativeObject(kernel_state, native_ptr, as_type).release())); +} + +} // namespace rex::system + +// fmt formatter for XObject::Type - format as underlying uint32_t +template <> +struct fmt::formatter : fmt::formatter { + template + auto format(rex::system::XObject::Type t, FormatContext& ctx) const { + return fmt::formatter::format(static_cast(t), ctx); + } +}; diff --git a/include/rex/system/xsemaphore.h b/include/rex/system/xsemaphore.h new file mode 100644 index 0000000..89cbbfe --- /dev/null +++ b/include/rex/system/xsemaphore.h @@ -0,0 +1,48 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +namespace rex::system { + +struct X_KSEMAPHORE { + X_DISPATCH_HEADER header; + rex::be limit; +}; +static_assert_size(X_KSEMAPHORE, 0x14); + +class XSemaphore : public XObject { + public: + static const XObject::Type kObjectType = XObject::Type::Semaphore; + + explicit XSemaphore(KernelState* kernel_state); + ~XSemaphore() override; + + [[nodiscard]] bool Initialize(int32_t initial_count, int32_t maximum_count); + [[nodiscard]] bool InitializeNative(void* native_ptr, X_DISPATCH_HEADER* header); + + [[nodiscard]] bool ReleaseSemaphore(int32_t release_count, int32_t* out_previous_count); + + bool Save(stream::ByteStream* stream) override; + static object_ref Restore(KernelState* kernel_state, stream::ByteStream* stream); + + protected: + rex::thread::WaitHandle* GetWaitHandle() override { return semaphore_.get(); } + + private: + std::unique_ptr semaphore_; + uint32_t maximum_count_ = 0; +}; + +} // namespace rex::system diff --git a/include/rex/system/xsocket.h b/include/rex/system/xsocket.h new file mode 100644 index 0000000..d5493a7 --- /dev/null +++ b/include/rex/system/xsocket.h @@ -0,0 +1,149 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include + +namespace rex::system { + +struct XSOCKADDR { + rex::be address_family; + char sa_data[14]; +}; + +struct N_XSOCKADDR { + N_XSOCKADDR() {} + N_XSOCKADDR(const XSOCKADDR* other) { *this = *other; } + N_XSOCKADDR& operator=(const XSOCKADDR& other) { + address_family = other.address_family; + std::memcpy(sa_data, other.sa_data, rex::countof(sa_data)); + return *this; + } + + uint16_t address_family; + char sa_data[14]; +}; + +struct XSOCKADDR_IN { + rex::be sin_family; + + // Always big-endian! + rex::be sin_port; + rex::be sin_addr; + // sin_zero is defined as __pad on Android, so prefixed here. + char x_sin_zero[8]; +}; + +// Xenia native sockaddr_in +struct N_XSOCKADDR_IN { + N_XSOCKADDR_IN() {} + N_XSOCKADDR_IN(const XSOCKADDR_IN* other) { *this = *other; } + N_XSOCKADDR_IN& operator=(const XSOCKADDR_IN& other) { + sin_family = other.sin_family; + sin_port = other.sin_port; + sin_addr = other.sin_addr; + std::memset(x_sin_zero, 0, sizeof(x_sin_zero)); + + return *this; + } + + uint16_t sin_family; + rex::be sin_port; + rex::be sin_addr; + // sin_zero is defined as __pad on Android, so prefixed here. + char x_sin_zero[8]; +}; + +class XSocket : public XObject { + public: + static const XObject::Type kObjectType = XObject::Type::Socket; + + enum AddressFamily { + AF_INET = 2, + }; + + enum Type { + SOCK_STREAM = 1, + SOCK_DGRAM = 2, + }; + + enum Protocol { + IPPROTO_TCP = 6, + IPPROTO_UDP = 17, + + // LIVE Voice and Data Protocol + // https://blog.csdn.net/baozi3026/article/details/4277227 + // Format: [cbGameData][GameData(encrypted)][VoiceData(unencrypted)] + IPPROTO_VDP = 254, + }; + + XSocket(KernelState* kernel_state); + ~XSocket(); + + uint64_t native_handle() const { return native_handle_; } + uint16_t bound_port() const { return bound_port_; } + + X_STATUS Initialize(AddressFamily af, Type type, Protocol proto); + X_STATUS Close(); + + X_STATUS SetOption(uint32_t level, uint32_t optname, void* optval_ptr, uint32_t optlen); + X_STATUS IOControl(uint32_t cmd, uint8_t* arg_ptr); + + X_STATUS Connect(N_XSOCKADDR* name, int name_len); + X_STATUS Bind(N_XSOCKADDR_IN* name, int name_len); + X_STATUS Listen(int backlog); + object_ref Accept(N_XSOCKADDR* name, int* name_len); + int Shutdown(int how); + + int Recv(uint8_t* buf, uint32_t buf_len, uint32_t flags); + int Send(const uint8_t* buf, uint32_t buf_len, uint32_t flags); + + int RecvFrom(uint8_t* buf, uint32_t buf_len, uint32_t flags, N_XSOCKADDR_IN* from, + uint32_t* from_len); + int SendTo(uint8_t* buf, uint32_t buf_len, uint32_t flags, N_XSOCKADDR_IN* to, uint32_t to_len); + + struct packet { + // These values are in network byte order. + rex::be src_port; + rex::be src_ip; + + uint16_t data_len; + uint8_t data[1]; + }; + + // Queue a packet into our internal buffer. + bool QueuePacket(uint32_t src_ip, uint16_t src_port, const uint8_t* buf, size_t len); + + private: + XSocket(KernelState* kernel_state, uint64_t native_handle); + uint64_t native_handle_ = -1; + + AddressFamily af_; // Address family + Type type_; // Type (DGRAM/Stream/etc) + Protocol proto_; // Protocol (TCP/UDP/etc) + bool secure_ = true; // Secure socket (encryption enabled) + + bool bound_ = false; // Explicitly bound to an IP address? + uint16_t bound_port_ = 0; + + bool broadcast_socket_ = false; + + std::unique_ptr event_; + std::mutex incoming_packet_mutex_; + std::queue incoming_packets_; +}; + +} // namespace rex::system \ No newline at end of file diff --git a/include/rex/system/xsymboliclink.h b/include/rex/system/xsymboliclink.h new file mode 100644 index 0000000..a354ffb --- /dev/null +++ b/include/rex/system/xsymboliclink.h @@ -0,0 +1,45 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include + +namespace rex::system { + +class XSymbolicLink : public XObject { + public: + static const XObject::Type kObjectType = XObject::Type::SymbolicLink; + + explicit XSymbolicLink(KernelState* kernel_state); + ~XSymbolicLink() override; + + void Initialize(const std::string_view path, const std::string_view target); + + bool Save(stream::ByteStream* stream) override; + static object_ref Restore(KernelState* kernel_state, stream::ByteStream* stream); + + const std::string& path() const { return path_; } + const std::string& target() const { return target_; } + + private: + XSymbolicLink(); + + std::string path_; + std::string target_; +}; + +} // namespace rex::system diff --git a/include/rex/system/xthread.h b/include/rex/system/xthread.h new file mode 100644 index 0000000..1b2e0c1 --- /dev/null +++ b/include/rex/system/xthread.h @@ -0,0 +1,446 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::system { + +constexpr memory::fourcc_t kThreadSaveSignature = memory::make_fourcc("THRD"); + +class XEvent; + +enum IRQL_FLAGS : uint8_t { + IRQL_PASSIVE = 0, + IRQL_APC = 1, + IRQL_DISPATCH = 2, + IRQL_DPC = 3, + IRQL_AUDIO = 68, + IRQL_CLOCK = 116, + IRQL_HIGHEST = 124 +}; + +enum X_DISPATCHER_FLAGS { + DISPATCHER_MANUAL_RESET_EVENT = 0, + DISPATCHER_AUTO_RESET_EVENT = 1, + DISPATCHER_MUTANT = 2, + DISPATCHER_QUEUE = 4, + DISPATCHER_SEMAPHORE = 5, + DISPATCHER_THREAD = 6, + DISPATCHER_MANUAL_RESET_TIMER = 8, + DISPATCHER_AUTO_RESET_TIMER = 9, +}; + +// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/ntos/ke/kthread_state.htm +enum X_KTHREAD_STATE_FLAGS : uint8_t { + KTHREAD_STATE_INITIALIZED = 0, + KTHREAD_STATE_READY = 1, + KTHREAD_STATE_RUNNING = 2, + KTHREAD_STATE_STANDBY = 3, + KTHREAD_STATE_TERMINATED = 4, + KTHREAD_STATE_WAITING = 5, + KTHREAD_STATE_UNKNOWN = 6, +}; + +constexpr uint32_t X_CREATE_SUSPENDED = 0x00000001; + +constexpr uint32_t X_TLS_OUT_OF_INDEXES = UINT32_MAX; + +struct XDPC { + rex::be type; + uint8_t selected_cpu_number; + uint8_t desired_cpu_number; + X_LIST_ENTRY list_entry; + rex::be routine; + rex::be context; + rex::be arg1; + rex::be arg2; + + void Initialize(uint32_t guest_func, uint32_t guest_context) { + type = 19; + selected_cpu_number = 0; + desired_cpu_number = 0; + routine = guest_func; + context = guest_context; + } +}; + +struct XAPC { + static constexpr uint32_t kSize = 40; + static constexpr uint32_t kDummyKernelRoutine = 0xF00DFF00; + static constexpr uint32_t kDummyRundownRoutine = 0xF00DFF01; + + // KAPC is 0x28(40) bytes? (what's passed to ExAllocatePoolWithTag) + // This is 4b shorter than NT - looks like the reserved dword at +4 is gone. + // NOTE: stored in guest memory. + uint16_t type; // +0 + uint8_t apc_mode; // +2 + uint8_t enqueued; // +3 + rex::be thread_ptr; // +4 + X_LIST_ENTRY list_entry; // +8 + rex::be kernel_routine; // +16 + rex::be rundown_routine; // +20 + rex::be normal_routine; // +24 + rex::be normal_context; // +28 + rex::be arg1; // +32 + rex::be arg2; // +36 +}; +static_assert_size(XAPC, 40); + +/// Guest fiber context buffer layout. +struct X_FIBER_CONTEXT { + rex::be fiber_data; // 0x00 lpParameter + rex::be stack_alloc_base; // 0x04 KTHREAD.stack_alloc_base (0xD0) + rex::be stack_base; // 0x08 KTHREAD.stack_base (0x5C), PCR.stack_base_ptr + rex::be stack_limit; // 0x0C KTHREAD.stack_limit (0x60), PCR.stack_end_ptr + uint8_t reserved_10[0x0C]; // 0x10 padding + rex::be lr_save; // 0x1C saved LR (zeroed, unused by host) + uint8_t reserved_20[0x10]; // 0x20 padding + rex::be sp_save; // 0x30 saved r1 + uint8_t register_save_area[0xA50 - 0x38]; // non-volatile PPCContext register save area +}; +static_assert_size(X_FIBER_CONTEXT, 0xA50); + +struct X_KTHREAD; +struct X_KPROCESS; + +struct X_KWAIT_BLOCK { + X_LIST_ENTRY wait_list_entry; // 0x0 + TypedGuestPointer thread; // 0x8 + TypedGuestPointer object; // 0xC + TypedGuestPointer next_wait_block; // 0x10 + rex::be wait_result_xstatus; // 0x14 + rex::be wait_type; // 0x16 +}; +static_assert_size(X_KWAIT_BLOCK, 0x18); + +struct X_KPRCB { + TypedGuestPointer current_thread; // 0x0 + TypedGuestPointer next_thread; // 0x4 + TypedGuestPointer idle_thread; // 0x8 + uint8_t current_cpu; // 0xC + uint8_t unk_D[3]; // 0xD + rex::be processor_mask; // 0x10 + rex::be dpc_clock; // 0x14 + rex::be interrupt_clock; // 0x18 + rex::be unk_1C; // 0x1C + rex::be unk_20; // 0x20 + rex::be ipi_args[3]; // 0x24 + rex::be targeted_ipi_cpus_mask; // 0x30 + rex::be ipi_function; // 0x34 + TypedGuestPointer ipi_initiator_prcb; // 0x38 + rex::be unk_3C; // 0x3C + rex::be dpc_related_40; // 0x40 + rex::be dpc_lock; // 0x44 + X_LIST_ENTRY queued_dpcs_list_head; // 0x48 + rex::be dpc_active; // 0x50 + X_KSPINLOCK spin_lock; // 0x54 + TypedGuestPointer running_idle_thread; // 0x58 + X_SINGLE_LIST_ENTRY enqueued_threads_list; // 0x5C + rex::be has_ready_thread_by_priority; // 0x60 + rex::be unk_mask_64; // 0x64 + X_LIST_ENTRY unk_68[32]; // 0x68 + XDPC thread_exit_dpc; // 0x168 + X_LIST_ENTRY terminating_threads_list; // 0x184 + XDPC switch_thread_processor_dpc; // 0x18C +}; + +// Processor Control Region +struct X_KPCR { + rex::be tls_ptr; // 0x0 + rex::be msr_mask; // 0x4 + union { + rex::be software_interrupt_state; // 0x8 + struct { + uint8_t generic_software_interrupt; // 0x8 + uint8_t apc_software_interrupt_state; // 0x9 + }; + }; + rex::be unk_0A; // 0xA + uint8_t processtype_value_in_dpc; // 0xC + uint8_t timeslice_ended; // 0xD + uint8_t timer_pending; // 0xE + uint8_t unk_0F; // 0xF + rex::be thread_fpu_related; // 0x10 + rex::be thread_vmx_related; // 0x14 + uint8_t current_irql; // 0x18 + uint8_t background_scheduling_active; // 0x19 + uint8_t background_scheduling_1A; // 0x1A + uint8_t background_scheduling_1B; // 0x1B + rex::be timer_related; // 0x1C + uint8_t unk_20[0x10]; // 0x20 + rex::be pcr_ptr; // 0x30 + union { + uint8_t unk_38[8]; // 0x38 + uint64_t host_stash; // 0x38 + }; + uint8_t unk_40[28]; // 0x40 + rex::be unk_stack_5c; // 0x5C + uint8_t unk_60[12]; // 0x60 + rex::be use_alternative_stack; // 0x6C + rex::be stack_base_ptr; // 0x70 Stack base address (high addr) + rex::be stack_end_ptr; // 0x74 Stack end (low addr) + rex::be alt_stack_base_ptr; // 0x78 + rex::be alt_stack_end_ptr; // 0x7C + rex::be interrupt_handlers[32]; // 0x80 + X_KPRCB prcb_data; // 0x100 + TypedGuestPointer prcb; // 0x2A8 + uint8_t unk_2AC[0x2C]; // 0x2AC +}; + +struct X_KTHREAD { + X_DISPATCH_HEADER header; // 0x0 + rex::be unk_10; // 0x10 + rex::be unk_14; // 0x14 + X_KTIMER wait_timeout_timer; // 0x18 + X_KWAIT_BLOCK wait_timeout_block; // 0x40 + uint8_t unk_58[0x4]; // 0x58 + rex::be stack_base; // 0x5C + rex::be stack_limit; // 0x60 + rex::be stack_kernel; // 0x64 + rex::be tls_address; // 0x68 + uint8_t thread_state; // 0x6C + uint8_t alerted[2]; // 0x6D + uint8_t alertable; // 0x6F + uint8_t priority; // 0x70 + uint8_t fpu_exceptions_on; // 0x71 + uint8_t process_type_dup; // 0x72 (same as process_type below) + uint8_t process_type; // 0x73 (referenced most frequently) + // apc_mode determines which list an apc goes into + util::X_TYPED_LIST apc_lists[2]; // 0x74 + TypedGuestPointer process; // 0x84 + uint8_t executing_kernel_apc; // 0x88 + uint8_t deferred_apc_software_interrupt_state; // 0x89 + uint8_t user_apc_pending; // 0x8A + uint8_t may_queue_apcs; // 0x8B + X_KSPINLOCK apc_lock; // 0x8C + rex::be num_context_switches_to; // 0x90 + X_LIST_ENTRY ready_prcb_entry; // 0x94 + rex::be msr_mask; // 0x9C + rex::be wait_result; // 0xA0 + uint8_t wait_irql; // 0xA4 + uint8_t unk_A5[0xB]; // 0xA5 + int32_t apc_disable_count; // 0xB0 + rex::be quantum; // 0xB4 + uint8_t unk_B8; // 0xB8 + uint8_t unk_B9; // 0xB9 + uint8_t unk_BA; // 0xBA + uint8_t boost_disabled; // 0xBB + uint8_t suspend_count; // 0xBC + uint8_t was_preempted; // 0xBD + uint8_t terminated; // 0xBE + uint8_t current_cpu; // 0xBF + TypedGuestPointer a_prcb_ptr; // 0xC0 + TypedGuestPointer another_prcb_ptr; // 0xC4 + uint8_t unk_C8; // 0xC8 + uint8_t unk_C9; // 0xC9 + uint8_t unk_CA; // 0xCA + uint8_t unk_CB; // 0xCB + X_KSPINLOCK timer_list_lock; // 0xCC + rex::be stack_alloc_base; // 0xD0 + XAPC on_suspend; // 0xD4 + X_KSEMAPHORE suspend_sema; // 0xFC + X_LIST_ENTRY process_threads; // 0x110 + rex::be unk_118; // 0x118 + X_LIST_ENTRY queue_related; // 0x11C + rex::be unk_124; // 0x124 + rex::be unk_128; // 0x128 + rex::be unk_12C; // 0x12C + rex::be create_time; // 0x130 + rex::be exit_time; // 0x138 + rex::be exit_status; // 0x140 + X_LIST_ENTRY timer_list; // 0x144 + rex::be thread_id; // 0x14C + rex::be start_address; // 0x150 + X_LIST_ENTRY unk_154; // 0x154 + uint8_t unk_15C[0x4]; // 0x15C + rex::be last_error; // 0x160 + rex::be fiber_ptr; // 0x164 + uint8_t unk_168[0x4]; // 0x168 + rex::be creation_flags; // 0x16C + uint8_t unk_170[0xC]; // 0x170 + rex::be unk_17C; // 0x17C + uint8_t unk_180[0x930]; // 0x180 +}; +static_assert_size(X_KTHREAD, 0xAB0); + +class XThread : public XObject { + public: + static const XObject::Type kObjectType = XObject::Type::Thread; + + static constexpr uint32_t kStackAddressRangeBegin = 0x70000000; + static constexpr uint32_t kStackAddressRangeEnd = 0x7F000000; + + struct CreationParams { + uint32_t stack_size; + uint32_t xapi_thread_startup; + uint32_t start_address; + uint32_t start_context; + uint32_t creation_flags; + uint32_t guest_process; + }; + + XThread(KernelState* kernel_state); + XThread(KernelState* kernel_state, uint32_t stack_size, uint32_t xapi_thread_startup, + uint32_t start_address, uint32_t start_context, uint32_t creation_flags, + bool guest_thread, bool main_thread = false, uint32_t guest_process = 0); + ~XThread() override; + + static bool IsInThread(XThread* other); + static bool IsInThread(); + static XThread* GetCurrentThread(); + static uint32_t GetCurrentThreadHandle(); + static uint32_t GetCurrentThreadId(); + + static uint32_t GetLastError(); + static void SetLastError(uint32_t error_code); + + const CreationParams* creation_params() const { return &creation_params_; } + uint32_t tls_ptr() const { return tls_static_address_; } + uint32_t pcr_ptr() const { return pcr_address_; } + // True if the thread is created by the guest app. + bool is_guest_thread() const { return guest_thread_; } + bool main_thread() const { return main_thread_; } + bool is_running() const { return running_; } + + uint32_t thread_id() const { return thread_id_; } + uint32_t last_error(); + void set_last_error(uint32_t error_code); + void set_name(const std::string_view name); + + X_STATUS Create(); + X_STATUS Exit(int exit_code); + X_STATUS Terminate(int exit_code); + + virtual void Execute(); + + rex::thread::Fiber* main_fiber() const { return main_fiber_; } + void set_main_fiber(rex::thread::Fiber* fiber) { main_fiber_ = fiber; } + + void EnterCriticalRegion(); + void LeaveCriticalRegion(); + + void DeliverAPCs(); + void LockApc(); + void UnlockApc(bool queue_delivery); + void EnqueueApc(uint32_t normal_routine, uint32_t normal_context, uint32_t arg1, uint32_t arg2); + + int32_t priority() const { return priority_; } + int32_t QueryPriority(); + void SetPriority(int32_t increment); + + // Xbox thread IDs: + // 0 - core 0, thread 0 - user + // 1 - core 0, thread 1 - user + // 2 - core 1, thread 0 - sometimes xcontent + // 3 - core 1, thread 1 - user + // 4 - core 2, thread 0 - xaudio + // 5 - core 2, thread 1 - user + void SetAffinity(uint32_t affinity); + uint8_t active_cpu() const; + void SetActiveCpu(uint8_t cpu_index); + + bool GetTLSValue(uint32_t slot, uint32_t* value_out); + bool SetTLSValue(uint32_t slot, uint32_t value); + + uint32_t suspend_count(); + X_STATUS Resume(uint32_t* out_suspend_count = nullptr); + X_STATUS Suspend(uint32_t* out_suspend_count = nullptr); +#if REX_PLATFORM_LINUX + // Increment suspend count and block until another thread resumes us. + uint32_t SelfSuspend(); +#endif + X_STATUS Delay(uint32_t processor_mode, uint32_t alertable, uint64_t interval); + + rex::thread::Thread* thread() { return thread_.get(); } + runtime::ThreadState* thread_state() { return thread_state_.get(); } + + virtual bool Save(stream::ByteStream* stream) override; + static object_ref Restore(KernelState* kernel_state, stream::ByteStream* stream); + + // Internal - do not use. + void AcquireMutantOnStartup(object_ref mutant) { + pending_mutant_acquires_.push_back(mutant); + } + + protected: + bool AllocateStack(uint32_t size); + void FreeStack(); + void InitializeGuestObject(); + + void RundownAPCs(); + + rex::thread::WaitHandle* GetWaitHandle() override { return thread_.get(); } + + CreationParams creation_params_ = {0, 0, 0, 0, 0, 0}; + + std::vector> pending_mutant_acquires_; + + uint32_t thread_id_ = 0; + uint32_t scratch_address_ = 0; + uint32_t scratch_size_ = 0; + uint32_t tls_static_address_ = 0; + uint32_t tls_dynamic_address_ = 0; + uint32_t tls_total_size_ = 0; + uint32_t pcr_address_ = 0; + uint32_t stack_alloc_base_ = 0; // Stack alloc base + uint32_t stack_alloc_size_ = 0; // Stack alloc size + uint32_t stack_base_ = 0; // High address + uint32_t stack_limit_ = 0; // Low address + bool guest_thread_ = false; + bool main_thread_ = false; // Entry-point thread + bool running_ = false; + + std::string thread_name_; + std::unique_ptr thread_state_; + + int32_t priority_ = 0; + +#if REX_PLATFORM_LINUX + std::mutex suspend_mutex_; + std::condition_variable suspend_cv_; +#endif + + std::mutex thread_lock_; + + rex::thread::global_critical_region global_critical_region_; + uint32_t apc_lock_old_irql_ = 0; + + std::unique_ptr thread_ = nullptr; + rex::thread::Fiber* main_fiber_ = nullptr; +}; + +class XHostThread : public XThread { + public: + XHostThread(KernelState* kernel_state, uint32_t stack_size, uint32_t creation_flags, + std::function host_fn); + + virtual void Execute(); + + private: + std::function host_fn_; +}; + +} // namespace rex::system diff --git a/include/rex/system/xtimer.h b/include/rex/system/xtimer.h new file mode 100644 index 0000000..c7ce93f --- /dev/null +++ b/include/rex/system/xtimer.h @@ -0,0 +1,56 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +namespace rex::system { + +struct XDPC; + +struct X_KTIMER { + X_DISPATCH_HEADER header; // 0x0 + rex::be due_time; // 0x10 + X_LIST_ENTRY table_bucket_entry; // 0x18 + TypedGuestPointer dpc; // 0x20 + rex::be period; // 0x24 +}; +static_assert_size(X_KTIMER, 0x28); + +class XThread; + +class XTimer : public XObject { + public: + static const XObject::Type kObjectType = XObject::Type::Timer; + + explicit XTimer(KernelState* kernel_state); + ~XTimer() override; + + void Initialize(uint32_t timer_type); + + X_STATUS SetTimer(int64_t due_time, uint32_t period_ms, uint32_t routine, uint32_t routine_arg, + bool resume); + X_STATUS Cancel(); + + protected: + rex::thread::WaitHandle* GetWaitHandle() override { return timer_.get(); } + + private: + std::unique_ptr timer_; + + XThread* callback_thread_ = nullptr; + uint32_t callback_routine_ = 0; + uint32_t callback_routine_arg_ = 0; +}; + +} // namespace rex::system diff --git a/include/rex/system/xtypes.h b/include/rex/system/xtypes.h new file mode 100644 index 0000000..d0e8f67 --- /dev/null +++ b/include/rex/system/xtypes.h @@ -0,0 +1,193 @@ +/** + * @file kernel/xtypes.h + * @brief Core Xbox 360 type definitions (X_STATUS, X_RESULT, X_HRESULT) + * + * @copyright Copyright 2020 Ben Vanik. All rights reserved. (Xenia Project) + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include // static_assert_size +#include // be + +namespace rex { + +typedef uint32_t X_HANDLE; +#define X_INVALID_HANDLE_VALUE ((X_HANDLE) - 1) + +// NT_STATUS (STATUS_*) +// https://msdn.microsoft.com/en-us/library/cc704588.aspx +typedef uint32_t X_STATUS; +#define XSUCCEEDED(s) ((s & 0xC0000000) == 0) +#define XFAILED(s) (!XSUCCEEDED(s)) +#define X_STATUS_SUCCESS ((X_STATUS)0x00000000L) +#define X_STATUS_ABANDONED_WAIT_0 ((X_STATUS)0x00000080L) +#define X_STATUS_USER_APC ((X_STATUS)0x000000C0L) +#define X_STATUS_ALERTED ((X_STATUS)0x00000101L) +#define X_STATUS_TIMEOUT ((X_STATUS)0x00000102L) +#define X_STATUS_PENDING ((X_STATUS)0x00000103L) +#define X_STATUS_OBJECT_NAME_EXISTS ((X_STATUS)0x40000000L) +#define X_STATUS_TIMER_RESUME_IGNORED ((X_STATUS)0x40000025L) +#define X_STATUS_BUFFER_OVERFLOW ((X_STATUS)0x80000005L) +#define X_STATUS_NO_MORE_FILES ((X_STATUS)0x80000006L) +#define X_STATUS_UNSUCCESSFUL ((X_STATUS)0xC0000001L) +#define X_STATUS_NOT_IMPLEMENTED ((X_STATUS)0xC0000002L) +#define X_STATUS_INVALID_INFO_CLASS ((X_STATUS)0xC0000003L) +#define X_STATUS_INFO_LENGTH_MISMATCH ((X_STATUS)0xC0000004L) +#define X_STATUS_ACCESS_VIOLATION ((X_STATUS)0xC0000005L) +#define X_STATUS_INVALID_HANDLE ((X_STATUS)0xC0000008L) +#define X_STATUS_INVALID_PARAMETER ((X_STATUS)0xC000000DL) +#define X_STATUS_NO_SUCH_FILE ((X_STATUS)0xC000000FL) +#define X_STATUS_END_OF_FILE ((X_STATUS)0xC0000011L) +#define X_STATUS_NO_MEMORY ((X_STATUS)0xC0000017L) +#define X_STATUS_ALREADY_COMMITTED ((X_STATUS)0xC0000021L) +#define X_STATUS_ACCESS_DENIED ((X_STATUS)0xC0000022L) +#define X_STATUS_BUFFER_TOO_SMALL ((X_STATUS)0xC0000023L) +#define X_STATUS_OBJECT_TYPE_MISMATCH ((X_STATUS)0xC0000024L) +#define X_STATUS_OBJECT_NAME_INVALID ((X_STATUS)0xC0000033L) +#define X_STATUS_OBJECT_NAME_NOT_FOUND ((X_STATUS)0xC0000034L) +#define X_STATUS_OBJECT_NAME_COLLISION ((X_STATUS)0xC0000035L) +#define X_STATUS_INVALID_PAGE_PROTECTION ((X_STATUS)0xC0000045L) +#define X_STATUS_MUTANT_NOT_OWNED ((X_STATUS)0xC0000046L) +#define X_STATUS_THREAD_IS_TERMINATING ((X_STATUS)0xC000004BL) +#define X_STATUS_PROCEDURE_NOT_FOUND ((X_STATUS)0xC000007AL) +#define X_STATUS_INSUFFICIENT_RESOURCES ((X_STATUS)0xC000009AL) +#define X_STATUS_MEMORY_NOT_ALLOCATED ((X_STATUS)0xC00000A0L) +#define X_STATUS_FILE_IS_A_DIRECTORY ((X_STATUS)0xC00000BAL) +#define X_STATUS_NOT_SUPPORTED ((X_STATUS)0xC00000BBL) +#define X_STATUS_INVALID_PARAMETER_1 ((X_STATUS)0xC00000EFL) +#define X_STATUS_INVALID_PARAMETER_2 ((X_STATUS)0xC00000F0L) +#define X_STATUS_INVALID_PARAMETER_3 ((X_STATUS)0xC00000F1L) +#define X_STATUS_DLL_NOT_FOUND ((X_STATUS)0xC0000135L) +#define X_STATUS_ENTRYPOINT_NOT_FOUND ((X_STATUS)0xC0000139L) +#define X_STATUS_SEMAPHORE_LIMIT_EXCEEDED ((X_STATUS)0xC000012BL) +#define X_STATUS_MAPPED_ALIGNMENT ((X_STATUS)0xC0000220L) +#define X_STATUS_NOT_FOUND ((X_STATUS)0xC0000225L) +#define X_STATUS_DRIVER_ORDINAL_NOT_FOUND ((X_STATUS)0xC0000262L) +#define X_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND ((X_STATUS)0xC0000263L) + +// Win32 error codes (ERROR_*) +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx +typedef uint32_t X_RESULT; +#define X_FACILITY_WIN32 0x0007 +#define X_RESULT_FROM_WIN32(x) ((X_RESULT)(x)) + +#define X_ERROR_SUCCESS X_RESULT_FROM_WIN32(0x00000000L) +#define X_ERROR_FILE_NOT_FOUND X_RESULT_FROM_WIN32(0x00000002L) +#define X_ERROR_PATH_NOT_FOUND X_RESULT_FROM_WIN32(0x00000003L) +#define X_ERROR_ACCESS_DENIED X_RESULT_FROM_WIN32(0x00000005L) +#define X_ERROR_INVALID_HANDLE X_RESULT_FROM_WIN32(0x00000006L) +#define X_ERROR_NO_MORE_FILES X_RESULT_FROM_WIN32(0x00000012L) +#define X_ERROR_INVALID_PARAMETER X_RESULT_FROM_WIN32(0x00000057L) +#define X_ERROR_INSUFFICIENT_BUFFER X_RESULT_FROM_WIN32(0x0000007AL) +#define X_ERROR_INVALID_NAME X_RESULT_FROM_WIN32(0x0000007BL) +#define X_ERROR_BAD_ARGUMENTS X_RESULT_FROM_WIN32(0x000000A0L) +#define X_ERROR_BUSY X_RESULT_FROM_WIN32(0x000000AAL) +#define X_ERROR_ALREADY_EXISTS X_RESULT_FROM_WIN32(0x000000B7L) +#define X_ERROR_IO_INCOMPLETE X_RESULT_FROM_WIN32(0x000003E4L) +#define X_ERROR_IO_PENDING X_RESULT_FROM_WIN32(0x000003E5L) +#define X_ERROR_DEVICE_NOT_CONNECTED X_RESULT_FROM_WIN32(0x0000048FL) +#define X_ERROR_NOT_FOUND X_RESULT_FROM_WIN32(0x00000490L) +#define X_ERROR_CANCELLED X_RESULT_FROM_WIN32(0x000004C7L) +#define X_ERROR_NOT_LOGGED_ON X_RESULT_FROM_WIN32(0x000004DDL) +#define X_ERROR_NO_SUCH_USER X_RESULT_FROM_WIN32(0x00000525L) +#define X_ERROR_FUNCTION_FAILED X_RESULT_FROM_WIN32(0x0000065BL) +#define X_ERROR_EMPTY X_RESULT_FROM_WIN32(0x000010D2L) + +// HRESULT codes +typedef uint32_t X_HRESULT; +#define X_HRESULT_FROM_WIN32(x) \ + ((int32_t)(x) <= 0 \ + ? (static_cast(x)) \ + : (static_cast(((x) & 0xFFFF) | (X_FACILITY_WIN32 << 16) | 0x80000000L))) + +#define X_E_FALSE static_cast(0x80000000L) +#define X_E_SUCCESS X_HRESULT_FROM_WIN32(X_ERROR_SUCCESS) +#define X_E_FAIL static_cast(0x80004005L) +#define X_E_NO_MORE_FILES X_HRESULT_FROM_WIN32(X_ERROR_NO_MORE_FILES) +#define X_E_INVALIDARG X_HRESULT_FROM_WIN32(X_ERROR_INVALID_PARAMETER) +#define X_E_DEVICE_NOT_CONNECTED X_HRESULT_FROM_WIN32(X_ERROR_DEVICE_NOT_CONNECTED) +#define X_E_NOTFOUND X_HRESULT_FROM_WIN32(X_ERROR_NOT_FOUND) +#define X_E_NO_SUCH_USER X_HRESULT_FROM_WIN32(X_ERROR_NO_SUCH_USER) + +// MEM_*, used by NtAllocateVirtualMemory +enum X_MEM : uint32_t { + X_MEM_COMMIT = 0x00001000, + X_MEM_RESERVE = 0x00002000, + X_MEM_DECOMMIT = 0x00004000, + X_MEM_RELEASE = 0x00008000, + X_MEM_FREE = 0x00010000, + X_MEM_PRIVATE = 0x00020000, + X_MEM_RESET = 0x00080000, + X_MEM_TOP_DOWN = 0x00100000, + X_MEM_NOZERO = 0x00800000, + X_MEM_LARGE_PAGES = 0x20000000, + X_MEM_HEAP = 0x40000000, + X_MEM_16MB_PAGES = 0x80000000 // from Valve SDK +}; + +// PAGE_*, used by NtAllocateVirtualMemory +enum X_PAGE : uint32_t { + X_PAGE_NOACCESS = 0x00000001, + X_PAGE_READONLY = 0x00000002, + X_PAGE_READWRITE = 0x00000004, + X_PAGE_WRITECOPY = 0x00000008, + X_PAGE_EXECUTE = 0x00000010, + X_PAGE_EXECUTE_READ = 0x00000020, + X_PAGE_EXECUTE_READWRITE = 0x00000040, + X_PAGE_EXECUTE_WRITECOPY = 0x00000080, + X_PAGE_GUARD = 0x00000100, + X_PAGE_NOCACHE = 0x00000200, + X_PAGE_WRITECOMBINE = 0x00000400 +}; + +// Sockets/networking +#define X_INVALID_SOCKET (uint32_t)(~0) +#define X_SOCKET_ERROR (uint32_t)(-1) + +// https://docs.microsoft.com/en-us/windows/win32/api/ntdef/ns-ntdef-list_entry +struct X_LIST_ENTRY { + be flink_ptr; // next entry / head + be blink_ptr; // previous entry / head +}; +static_assert_size(X_LIST_ENTRY, 8); + +struct X_SINGLE_LIST_ENTRY { + be next; // 0x0 pointer to next entry +}; +static_assert_size(X_SINGLE_LIST_ENTRY, 4); + +// https://www.nirsoft.net/kernel_struct/vista/SLIST_HEADER.html +struct X_SLIST_HEADER { + X_SINGLE_LIST_ENTRY next; // 0x0 + be depth; // 0x4 + be sequence; // 0x6 +}; +static_assert_size(X_SLIST_HEADER, 8); + +struct X_KSPINLOCK { + be prcb_of_owner; +}; +static_assert_size(X_KSPINLOCK, 4); + +// Typed guest pointer - holds a guest address but provides type documentation. +// Implicitly converts to/from uint32_t via the be member. +template +struct TypedGuestPointer { + be value; + + operator uint32_t() const { return value; } + TypedGuestPointer& operator=(uint32_t v) { + value = v; + return *this; + } +}; + +} // namespace rex diff --git a/include/rex/system/xvideo.h b/include/rex/system/xvideo.h new file mode 100644 index 0000000..72382a0 --- /dev/null +++ b/include/rex/system/xvideo.h @@ -0,0 +1,40 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified 2026 Tom Clay + * Modified for rexglue - Xbox 360 recompilation framework + * + * @changes - Extracted X_VIDEO_MODE from xbox.h + */ + +#pragma once + +#include // for be + +namespace rex::system { + +#pragma pack(push, 4) + +// https://github.com/CodeAsm/ffplay360/blob/master/Common/XTLOnPC.h +struct X_VIDEO_MODE { + be display_width; + be display_height; + be is_interlaced; + be is_widescreen; + be is_hi_def; + be refresh_rate; + be video_standard; + be unknown_0x8a; + be unknown_0x01; + be reserved[3]; +}; +static_assert_size(X_VIDEO_MODE, 48); + +#pragma pack(pop) + +} // namespace rex::system diff --git a/include/rex/thread.h b/include/rex/thread.h new file mode 100644 index 0000000..30b207d --- /dev/null +++ b/include/rex/thread.h @@ -0,0 +1,465 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace rex::thread { + +using namespace rex::literals; + +#if REX_PLATFORM_ANDROID +void AndroidInitialize(); +void AndroidShutdown(); +#endif + +// This is more like an Event with self-reset when returning from Wait() +class Fence { + public: + Fence() : signal_state_(0) {} + + void Signal() { + std::unique_lock lock(mutex_); + signal_state_.store(signal_state_.load() | SIGMASK_, std::memory_order_release); + cond_.notify_all(); + } + + // Wait for the Fence to be signaled. Clears the signal on return. + void Wait() { + std::unique_lock lock(mutex_); + assert_true((signal_state_.load() & ~SIGMASK_) < (SIGMASK_ - 1) && "Too many threads?"); + + // keep local copy to minimize loads + auto signal_state = signal_state_.fetch_add(1) + 1; + for (; !(signal_state & SIGMASK_); signal_state = signal_state_.load()) { + cond_.wait(lock); + } + + // We can't just clear the signal as other threads may not have read it yet + assert_true((signal_state & ~SIGMASK_) > 0); // wait_count > 0 + if (signal_state == (1 | SIGMASK_)) { // wait_count == 1 + // Last one out turn off the lights + signal_state_.store(0, std::memory_order_release); + } else { + // Oops, another thread is still waiting, set the new count and keep the + // signal. + signal_state_.store(--signal_state, std::memory_order_release); + } + } + + private: + using state_t_ = uint_fast32_t; + static constexpr state_t_ SIGMASK_ = state_t_(1) << (sizeof(state_t_) * 8 - 1); + + std::mutex mutex_; + std::condition_variable cond_; + // Use the highest bit (sign bit) as the signal flag and the rest to count + // waiting threads. + std::atomic signal_state_; +}; + +// Returns the total number of logical processors in the host system. +uint32_t logical_processor_count(); + +// Enables the current process to set thread affinity. +// Must be called at startup before attempting to set thread affinity. +void EnableAffinityConfiguration(); + +// Gets a stable thread-specific ID, but may not be. Use for informative +// purposes only. +uint32_t current_thread_system_id(); + +// Gets a stable thread-specific ID that defaults to the same value as +// current_thread_system_id but may be overridden. +// Guest threads often change this to the guest thread handle. +uint32_t current_thread_id(); +void set_current_thread_id(uint32_t id); + +// Sets the current thread name. +void set_current_thread_name(const std::string_view name); + +// Yields the current thread to the scheduler. Maybe. +void MaybeYield(); + +// Memory barrier (request - may be ignored). +void SyncMemory(); + +// Sleeps the current thread for at least as long as the given duration. +void Sleep(std::chrono::microseconds duration); +template +void Sleep(std::chrono::duration duration) { + Sleep(std::chrono::duration_cast(duration)); +} + +enum class SleepResult { + kSuccess, + kAlerted, +}; +// Sleeps the current thread for at least as long as the given duration. +// The thread is put in an alertable state and may wake to dispatch user +// callbacks. If this happens the sleep returns early with +// SleepResult::kAlerted. +SleepResult AlertableSleep(std::chrono::microseconds duration); +template +SleepResult AlertableSleep(std::chrono::duration duration) { + return AlertableSleep(std::chrono::duration_cast(duration)); +} + +typedef uint32_t TlsHandle; +constexpr TlsHandle kInvalidTlsHandle = UINT_MAX; + +TlsHandle AllocateTlsHandle(); +bool FreeTlsHandle(TlsHandle handle); +uintptr_t GetTlsValue(TlsHandle handle); +bool SetTlsValue(TlsHandle handle, uintptr_t value); + +// A high-resolution timer capable of firing at millisecond-precision. All +// timers created in this way are executed in the same thread so callbacks must +// be kept short or else all timers will be impacted. This is a simplified +// wrapper around QueueTimerRecurring which automatically cancels the timer on +// destruction. +class HighResolutionTimer { + HighResolutionTimer(std::chrono::milliseconds interval, std::function callback) { + assert_not_null(callback); + wait_item_ = QueueTimerRecurring([callback = std::move(callback)](void*) { callback(); }, + nullptr, TimerQueueWaitItem::clock::now(), interval); + } + + public: + ~HighResolutionTimer() { + if (auto wait_item = wait_item_.lock()) { + wait_item->Disarm(); + } + } + + // Creates a new repeating timer with the given period. + // The given function will be called back as close to the given period as + // possible. + static std::unique_ptr CreateRepeating(std::chrono::milliseconds period, + std::function callback) { + return std::unique_ptr( + new HighResolutionTimer(period, std::move(callback))); + } + + private: + std::weak_ptr wait_item_; +}; + +// Results for a WaitHandle operation. +enum class WaitResult { + // The state of the specified object is signaled. + // In a WaitAny the tuple will contain the index of the wait handle that + // caused the wait to be satisfied. + kSuccess, + // The wait was ended by one or more user-mode callbacks queued to the thread. + // This will occur when is_alertable is set true. + kUserCallback, + // The time-out interval elapsed, and the object's state is nonsignaled. + kTimeout, + // The specified object is a mutex object that was not released by the thread + // that owned the mutex object before the owning thread terminated. Ownership + // of the mutex object is granted to the calling thread and the mutex is set + // to nonsignaled. + // In a WaitAny the tuple will contain the index of the wait handle that + // caused the wait to be abandoned. + kAbandoned, + // The function has failed. + kFailed, +}; + +class WaitHandle { + public: + virtual ~WaitHandle() = default; + + // Returns the native handle of the object on the host system. + // This value is platform specific. + virtual void* native_handle() const = 0; + + protected: + WaitHandle() = default; +}; + +// Waits until the wait handle is in the signaled state, an alert triggers and +// a user callback is queued to the thread, or the timeout interval elapses. +// If timeout is zero the call will return immediately instead of waiting and +// if the timeout is max() the wait will not time out. +WaitResult Wait(WaitHandle* wait_handle, bool is_alertable, + std::chrono::milliseconds timeout = std::chrono::milliseconds::max()); + +// Signals one object and waits on another object as a single operation. +// Waits until the wait handle is in the signaled state, an alert triggers and +// a user callback is queued to the thread, or the timeout interval elapses. +// If timeout is zero the call will return immediately instead of waiting and +// if the timeout is max() the wait will not time out. +WaitResult SignalAndWait(WaitHandle* wait_handle_to_signal, WaitHandle* wait_handle_to_wait_on, + bool is_alertable, + std::chrono::milliseconds timeout = std::chrono::milliseconds::max()); + +std::pair WaitMultiple( + WaitHandle* wait_handles[], size_t wait_handle_count, bool wait_all, bool is_alertable, + std::chrono::milliseconds timeout = std::chrono::milliseconds::max()); + +// Waits until all of the specified objects are in the signaled state, a +// user callback is queued to the thread, or the time-out interval elapses. +// If timeout is zero the call will return immediately instead of waiting and +// if the timeout is max() the wait will not time out. +inline WaitResult WaitAll(WaitHandle* wait_handles[], size_t wait_handle_count, bool is_alertable, + std::chrono::milliseconds timeout = std::chrono::milliseconds::max()) { + return WaitMultiple(wait_handles, wait_handle_count, true, is_alertable, timeout).first; +} +inline WaitResult WaitAll(std::vector wait_handles, bool is_alertable, + std::chrono::milliseconds timeout = std::chrono::milliseconds::max()) { + return WaitAll(wait_handles.data(), wait_handles.size(), is_alertable, timeout); +} + +// Waits until any of the specified objects are in the signaled state, a +// user callback is queued to the thread, or the time-out interval elapses. +// If timeout is zero the call will return immediately instead of waiting and +// if the timeout is max() the wait will not time out. +// The second argument of the return tuple indicates which wait handle caused +// the wait to be satisfied or abandoned. +inline std::pair WaitAny( + WaitHandle* wait_handles[], size_t wait_handle_count, bool is_alertable, + std::chrono::milliseconds timeout = std::chrono::milliseconds::max()) { + return WaitMultiple(wait_handles, wait_handle_count, false, is_alertable, timeout); +} +inline std::pair WaitAny( + std::vector wait_handles, bool is_alertable, + std::chrono::milliseconds timeout = std::chrono::milliseconds::max()) { + return WaitAny(wait_handles.data(), wait_handles.size(), is_alertable, timeout); +} + +// Models a Win32-like event object. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682396(v=vs.85).aspx +class Event : public WaitHandle { + public: + // Creates a manual-reset event object, which requires the use of the + // Reset() function to set the event state to nonsignaled. + // If initial_state is true the event will start in the signaled state. + static std::unique_ptr CreateManualResetEvent(bool initial_state); + + // Creates an auto-reset event object, and system automatically resets the + // event state to nonsignaled after a single waiting thread has been released. + // If initial_state is true the event will start in the signaled state. + static std::unique_ptr CreateAutoResetEvent(bool initial_state); + + // Sets the specified event object to the signaled state. + // If this is a manual reset event the event stays signaled until Reset() is + // called. If this is an auto reset event until exactly one wait is satisfied. + virtual void Set() = 0; + + // Sets the specified event object to the nonsignaled state. + // Resetting an event that is already reset has no effect. + virtual void Reset() = 0; + + // Sets the specified event object to the signaled state and then resets it to + // the nonsignaled state after releasing the appropriate number of waiting + // threads. + virtual void Pulse() = 0; +}; + +// Models a Win32-like semaphore object. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682438(v=vs.85).aspx +class Semaphore : public WaitHandle { + public: + // Creates a new semaphore object. + // The initial_count must be greater than or equal to zero and less than or + // equal to maximum_count. The state of a semaphore is signaled when its count + // is greater than zero and nonsignaled when it is zero. The count is + // decreased by one whenever a wait function releases a thread that was + // waiting for the semaphore. The count is increased by a specified amount by + // calling the Release() function. + static std::unique_ptr Create(int initial_count, int maximum_count); + + // Increases the count of the specified semaphore object by a specified + // amount. + // release_count must be greater than zero. + // Returns false if adding release_count would set the semaphore over the + // initially specified maximum_count. + virtual bool Release(int release_count, int* out_previous_count) = 0; +}; + +// Models a Win32-like mutant (mutex) object. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682411(v=vs.85).aspx +class Mutant : public WaitHandle { + public: + // Creates a new mutant object, initially owned by the calling thread if + // specified. + static std::unique_ptr Create(bool initial_owner); + + // Releases ownership of the specified mutex object. + // Returns false if the calling thread does not own the mutant object. + virtual bool Release() = 0; +}; + +// Models a Win32-like timer object. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms687012(v=vs.85).aspx +class Timer : public WaitHandle { + public: + // Make vtable entries for both so we can defer conversions and only do them + // if really necessary (let the calling code what clock it prefers). Windows + // kernel sync primitives will work with WinSystemClock while our own + // implementation works with steady_clock. + using WClock_ = rex::chrono::WinSystemClock; + using GClock_ = std::chrono::steady_clock; // generic + + // Creates a timer whose state remains signaled until SetOnce() or + // SetRepeating() is called to establish a new due time. + static std::unique_ptr CreateManualResetTimer(); + + // Creates a timer whose state remains signaled until a thread completes a + // wait operation on the timer object. + static std::unique_ptr CreateSynchronizationTimer(); + + // Activates the specified waitable timer. When the due time arrives, the + // timer is signaled and the thread that set the timer calls the optional + // completion routine. + // Returns true on success. + virtual bool SetOnceAfter(rex::chrono::hundrednanoseconds rel_time, + std::function opt_callback = nullptr) = 0; + virtual bool SetOnceAt(WClock_::time_point due_time, + std::function opt_callback = nullptr) = 0; + virtual bool SetOnceAt(GClock_::time_point due_time, + std::function opt_callback = nullptr) = 0; + + // Activates the specified waitable timer. When the due time arrives, the + // timer is signaled and the thread that set the timer calls the optional + // completion routine. A periodic timer automatically reactivates each time + // the period elapses, until the timer is canceled or reset. + // Returns true on success. + virtual bool SetRepeatingAfter(rex::chrono::hundrednanoseconds rel_time, + std::chrono::milliseconds period, + std::function opt_callback = nullptr) = 0; + virtual bool SetRepeatingAt(WClock_::time_point due_time, std::chrono::milliseconds period, + std::function opt_callback = nullptr) = 0; + virtual bool SetRepeatingAt(GClock_::time_point due_time, std::chrono::milliseconds period, + std::function opt_callback = nullptr) = 0; + + // Stops the timer before it can be set to the signaled state and cancels + // outstanding callbacks. Threads performing a wait operation on the timer + // remain waiting until they time out or the timer is reactivated and its + // state is set to signaled. If the timer is already in the signaled state, it + // remains in that state. + // Returns true on success. + virtual bool Cancel() = 0; +}; + +#if REX_PLATFORM_WIN32 +struct ThreadPriority { + static const int32_t kLowest = -2; + static const int32_t kBelowNormal = -1; + static const int32_t kNormal = 0; + static const int32_t kAboveNormal = 1; + static const int32_t kHighest = 2; +}; +#else +struct ThreadPriority { + static const int32_t kLowest = 1; + static const int32_t kBelowNormal = 8; + static const int32_t kNormal = 16; + static const int32_t kAboveNormal = 24; + static const int32_t kHighest = 32; +}; +#endif + +// Models a Win32-like thread object. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682453(v=vs.85).aspx +class Thread : public WaitHandle { + public: + struct CreationParameters { + size_t stack_size = 4_MiB; + bool create_suspended = false; + int32_t initial_priority = 0; + }; + + // Creates a thread with the given parameters and calls the start routine from + // within that thread. + static std::unique_ptr Create(CreationParameters params, + std::function start_routine); + static Thread* GetCurrentThread(); + + // Ends the calling thread. + // No destructors are called, and this function does not return. + // The state of the thread object becomes signaled, releasing any other + // threads that had been waiting for the thread to terminate. + static void Exit(int exit_code); + + // Returns the ID of the thread. + virtual uint32_t system_id() const = 0; + + // Returns the current name of the thread, if previously specified. + const std::string& name() const { return name_; } + + // Sets the name of the thread, used in debugging and logging. + virtual void set_name(std::string name) { name_ = std::move(name); } + + // Returns the current priority value for the thread. + virtual int32_t priority() = 0; + + // Sets the priority value for the thread. This value, together with the + // priority class of the thread's process, determines the thread's base + // priority level. ThreadPriority contains useful constants. + virtual void set_priority(int32_t new_priority) = 0; + + // Returns the current processor affinity mask for the thread. + virtual uint64_t affinity_mask() = 0; + + // Sets a processor affinity mask for the thread. + // A thread affinity mask is a bit vector in which each bit represents a + // logical processor that a thread is allowed to run on. A thread affinity + // mask must be a subset of the process affinity mask for the containing + // process of a thread. + virtual void set_affinity_mask(uint64_t new_affinity_mask) = 0; + + // Adds a user-mode asynchronous procedure call request to the thread queue. + // When a user-mode APC is queued, the thread is not directed to call the APC + // function unless it is in an alertable state. After the thread is in an + // alertable state, the thread handles all pending APCs in first in, first out + // (FIFO) order, and the wait operation returns WaitResult::kUserCallback. + virtual void QueueUserCallback(std::function callback) = 0; + + // Decrements a thread's suspend count. When the suspend count is decremented + // to zero, the execution of the thread is resumed. + virtual bool Resume(uint32_t* out_previous_suspend_count = nullptr) = 0; + + // Suspends the specified thread. + virtual bool Suspend(uint32_t* out_previous_suspend_count = nullptr) = 0; + + // Terminates the thread. + // No destructors are called, and this function does not return. + // The state of the thread object becomes signaled, releasing any other + // threads that had been waiting for the thread to terminate. + virtual void Terminate(int exit_code) = 0; + + protected: + std::string name_; +}; + +} // namespace rex::thread diff --git a/include/rex/thread/atomic.h b/include/rex/thread/atomic.h new file mode 100644 index 0000000..f7eecf9 --- /dev/null +++ b/include/rex/thread/atomic.h @@ -0,0 +1,69 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +namespace rex::thread { + +int32_t atomic_inc(volatile int32_t* value); +int32_t atomic_dec(volatile int32_t* value); + +int32_t atomic_exchange(int32_t new_value, volatile int32_t* value); +int64_t atomic_exchange(int64_t new_value, volatile int64_t* value); + +int32_t atomic_exchange_add(int32_t amount, volatile int32_t* value); +int64_t atomic_exchange_add(int64_t amount, volatile int64_t* value); + +bool atomic_cas(int32_t old_value, int32_t new_value, volatile int32_t* value); +bool atomic_cas(int64_t old_value, int64_t new_value, volatile int64_t* value); +void atomic_store_release(int32_t new_value, volatile int32_t* value); + +inline uint32_t atomic_inc(volatile uint32_t* value) { + return static_cast(atomic_inc(reinterpret_cast(value))); +} +inline uint32_t atomic_dec(volatile uint32_t* value) { + return static_cast(atomic_dec(reinterpret_cast(value))); +} + +inline uint32_t atomic_exchange(uint32_t new_value, volatile uint32_t* value) { + return static_cast( + atomic_exchange(static_cast(new_value), reinterpret_cast(value))); +} +inline uint64_t atomic_exchange(uint64_t new_value, volatile uint64_t* value) { + return static_cast( + atomic_exchange(static_cast(new_value), reinterpret_cast(value))); +} + +inline uint32_t atomic_exchange_add(uint32_t amount, volatile uint32_t* value) { + return static_cast(atomic_exchange_add(static_cast(amount), + reinterpret_cast(value))); +} +inline uint64_t atomic_exchange_add(uint64_t amount, volatile uint64_t* value) { + return static_cast(atomic_exchange_add(static_cast(amount), + reinterpret_cast(value))); +} + +inline bool atomic_cas(uint32_t old_value, uint32_t new_value, volatile uint32_t* value) { + return atomic_cas(static_cast(old_value), static_cast(new_value), + reinterpret_cast(value)); +} +inline bool atomic_cas(uint64_t old_value, uint64_t new_value, volatile uint64_t* value) { + return atomic_cas(static_cast(old_value), static_cast(new_value), + reinterpret_cast(value)); +} + +inline void atomic_store_release(uint32_t new_value, volatile uint32_t* value) { + atomic_store_release(static_cast(new_value), reinterpret_cast(value)); +} + +} // namespace rex::thread diff --git a/include/rex/thread/fiber.h b/include/rex/thread/fiber.h new file mode 100644 index 0000000..64e70a7 --- /dev/null +++ b/include/rex/thread/fiber.h @@ -0,0 +1,65 @@ +/** + * @file rex/thread/fiber.h + * @brief Host OS fiber primitive for cooperative context switching + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include + +#if REX_PLATFORM_LINUX || REX_PLATFORM_MAC +#include +#include +#include +#endif + +namespace rex::thread { + +/// Host OS fiber primitive. +/// Each guest fiber gets one Fiber. Switching preserves the entire C++ call +/// stack, so mid-function resume works without any LR lookup. +struct Fiber { + /// Convert the calling thread into a fiber. + /// Must be called once on a thread before any SwitchTo. + /// Returns a handle for the thread's current execution context. + static Fiber* ConvertCurrentThread(); + + /// Create a new fiber with its own host stack. + /// entry(arg) is called when the fiber is first switched to. + static Fiber* Create(size_t stack_size, void (*entry)(void*), void* arg); + + /// Suspend the current fiber and resume target. + /// Returns when another fiber calls SwitchTo back to this one. + static void SwitchTo(Fiber* target); + + /// Destroy this fiber. Must not be called while it is executing. + void Destroy(); + + /// Returns the fiber currently executing on this thread, or nullptr. + static Fiber* Current() { return tls_current_; } + + private: + static thread_local Fiber* tls_current_; + +#if REX_PLATFORM_WIN32 + void* handle_ = nullptr; + bool is_thread_fiber_ = false; +#elif REX_PLATFORM_LINUX + ucontext_t context_{}; + std::vector stack_; + void (*entry_)(void*) = nullptr; + void* arg_ = nullptr; + bool is_thread_fiber_ = false; + + static void Trampoline(); +#endif +}; + +} // namespace rex::thread diff --git a/include/rex/thread/mutex.h b/include/rex/thread/mutex.h new file mode 100644 index 0000000..6e5755a --- /dev/null +++ b/include/rex/thread/mutex.h @@ -0,0 +1,85 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +namespace rex::thread { + +// The global critical region mutex singleton. +// This must guard any operation that may suspend threads or be sensitive to +// being suspended such as global table locks and such. +// To prevent deadlocks this should be the first lock acquired and be held +// for the entire duration of the critical region (longer than any other lock). +// +// As a general rule if some code can only be accessed from the guest you can +// guard it with only the global critical region and be assured nothing else +// will touch it. If it will be accessed from non-guest threads you may need +// some additional protection. +// +// You can think of this as disabling interrupts in the guest. The thread in the +// global critical region has exclusive access to the entire system and cannot +// be preempted. This also means that all activity done while in the critical +// region must be extremely fast (no IO!), as it has the chance to block any +// other thread until its done. +// +// For example, in the following situation thread 1 will not be able to suspend +// thread 0 until it has exited its critical region, preventing it from being +// suspended while holding the table lock: +// [thread 0]: +// DoKernelStuff(): +// auto global_lock = global_critical_region_.Acquire(); +// std::lock_guard table_lock(table_mutex_); +// table_->InsertStuff(); +// [thread 1]: +// MySuspendThread(): +// auto global_lock = global_critical_region_.Acquire(); +// ::SuspendThread(thread0); +// +// To use the region it's strongly recommended that you keep an instance near +// the data requiring it. This makes it clear to those reading that the data +// is protected by the global critical region. For example: +// class MyType { +// // Implies my_list_ is protected: +// xe::global_critical_region global_critical_region_; +// std::list<...> my_list_; +// }; +class global_critical_region { + public: + static std::recursive_mutex& mutex(); + + // Acquires a lock on the global critical section. + // Use this when keeping an instance is not possible. Otherwise, prefer + // to keep an instance of global_critical_region near the members requiring + // it to keep things readable. + static std::unique_lock AcquireDirect() { + return std::unique_lock(mutex()); + } + + // Acquires a lock on the global critical section. + inline std::unique_lock Acquire() { + return std::unique_lock(mutex()); + } + + // Acquires a deferred lock on the global critical section. + inline std::unique_lock AcquireDeferred() { + return std::unique_lock(mutex(), std::defer_lock); + } + + // Tries to acquire a lock on the glboal critical section. + // Check owns_lock() to see if the lock was successfully acquired. + inline std::unique_lock TryAcquire() { + return std::unique_lock(mutex(), std::try_to_lock); + } +}; + +} // namespace rex::thread diff --git a/include/rex/thread/timer_queue.h b/include/rex/thread/timer_queue.h new file mode 100644 index 0000000..b1f9ab7 --- /dev/null +++ b/include/rex/thread/timer_queue.h @@ -0,0 +1,78 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include + +// This is a platform independent implementation of a timer queue similar to +// Windows CreateTimerQueueTimer with WT_EXECUTEINTIMERTHREAD. + +namespace rex::thread { + +class TimerQueue; + +struct TimerQueueWaitItem { + using clock = std::chrono::steady_clock; + + TimerQueueWaitItem(std::function callback, void* userdata, TimerQueue* parent_queue, + clock::time_point due, clock::duration interval) + : callback_(std::move(callback)), + userdata_(userdata), + parent_queue_(parent_queue), + due_(due), + interval_(interval), + state_(State::kIdle) {} + + // Cancel the pending wait item. No callbacks will be running after this call. + // The function blocks if a callback is running and returns only after the + // callback has finished (except when called from the corresponding callback + // itself, where it will mark the wait item for disarmament and return + // immediately). Deadlocks are possible when a lock is held during disamament + // and the corresponding callback is running concurrently, trying to acquire + // said lock. + void Disarm(); + + friend TimerQueue; + + private: + enum class State : uint_least8_t { + kIdle = 0, // Waiting for the due time + kInCallback, // Callback is being executed + kInCallbackSelfDisarmed, // Callback is being executed and disarmed itself + kDisarmed // Disarmed, waiting for destruction + }; + static_assert(std::atomic::is_always_lock_free); + + std::function callback_; + void* userdata_; + TimerQueue* parent_queue_; + clock::time_point due_; + clock::duration interval_; // zero if not recurring + std::atomic state_; +}; + +std::weak_ptr QueueTimerOnce(std::function callback, + void* userdata, + TimerQueueWaitItem::clock::time_point due); + +// Callback is first executed at due, then again repeatedly after interval +// passes (unless interval == 0). The first callback will be scheduled at +// `max(now() - interval, due)` to mitigate callback flooding. +std::weak_ptr QueueTimerRecurring(std::function callback, + void* userdata, + TimerQueueWaitItem::clock::time_point due, + TimerQueueWaitItem::clock::duration interval); + +} // namespace rex::thread diff --git a/include/rex/types.h b/include/rex/types.h new file mode 100644 index 0000000..5581440 --- /dev/null +++ b/include/rex/types.h @@ -0,0 +1,420 @@ +/** + * @file types.h + * @brief Core type definitions and aliases + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +// Check for mixed endian +static_assert((std::endian::native == std::endian::big) || + (std::endian::native == std::endian::little)); + +namespace rex { + +/// Byte-swap a value of any trivially copyable type (1, 2, 4, or 8 bytes). +/// Uses std::bit_cast for safe type punning and std::byteswap for the swap. +template +constexpr T byte_swap(T value) noexcept { + static_assert(sizeof(T) == 8 || sizeof(T) == 4 || sizeof(T) == 2 || sizeof(T) == 1, + "byte_swap(T value): Type T has illegal size"); + if constexpr (sizeof(T) == 1) { + return value; + } else { + // Convert to unsigned integer of same size, byteswap, convert back + using uint_t = std::conditional_t>; + return std::bit_cast(std::byteswap(std::bit_cast(value))); + } +} + +template +struct endian_store { + using value_type = T; // Type alias for value() in MappedPtr + + endian_store() = default; + endian_store(const T& src) { set(src); } + endian_store(const endian_store&) = default; + endian_store& operator=(const endian_store&) = default; + operator T() const { return get(); } + + void set(const T& src) { + if constexpr (std::endian::native == E) { + value = src; + } else { + value = rex::byte_swap(src); + } + } + T get() const { + if constexpr (std::endian::native == E) { + return value; + } + return rex::byte_swap(value); + } + + endian_store& operator+=(int a) { + *this = *this + a; + return *this; + } + endian_store& operator-=(int a) { + *this = *this - a; + return *this; + } + endian_store& operator++() { + *this += 1; + return *this; + } // ++a + endian_store operator++(int) { + *this += 1; + return (*this - 1); + } // a++ + endian_store& operator--() { + *this -= 1; + return *this; + } // --a + endian_store operator--(int) { + *this -= 1; + return (*this + 1); + } // a-- + + T value; +}; + +template +using be = endian_store; +template +using le = endian_store; + +//============================================================================= +// Big-Endian Type Detection +//============================================================================= + +template +struct is_be_type : std::false_type {}; + +template +struct is_be_type> : std::true_type {}; + +template +inline constexpr bool is_be_type_v = is_be_type::value; + +//============================================================================= +// Basic Integer Types +//============================================================================= + +using u8 = uint8_t; +using u16 = uint16_t; +using u32 = uint32_t; +using u64 = uint64_t; + +using i8 = int8_t; +using i16 = int16_t; +using i32 = int32_t; +using i64 = int64_t; + +using f32 = float; +using f64 = double; + +static_assert(sizeof(f32) == 4, "float must be 4 bytes"); +static_assert(sizeof(f64) == 8, "double must be 8 bytes"); + +//============================================================================= +// Memory Address Types +//============================================================================= + +using guest_addr_t = u32; // Xbox 360 guest address (32-bit) +using host_addr_t = uintptr_t; // Host native address (64-bit on x64) + +//============================================================================= +// Big-Endian Type Aliases (using rex::be) +//============================================================================= + +using be_u8 = u8; // No byte-swapping needed for single bytes +using be_u16 = be; +using be_u32 = be; +using be_u64 = be; + +using be_i8 = i8; +using be_i16 = be; +using be_i32 = be; +using be_i64 = be; + +using be_f32 = be; +using be_f64 = be; + +//============================================================================= +// MappedPtr - Wraps host pointer with guest address tracking +//============================================================================= + +template +class MappedPtr { + T* host_ptr_; + u32 guest_addr_; + + public: + MappedPtr() : host_ptr_(nullptr), guest_addr_(0) {} + MappedPtr(T* host_ptr, u32 guest_addr) : host_ptr_(host_ptr), guest_addr_(guest_addr) {} + MappedPtr(std::nullptr_t) : host_ptr_(nullptr), guest_addr_(0) {} + + static MappedPtr from_host(T* host_ptr) { return MappedPtr(host_ptr, 0); } + + u32 guest_address() const { return guest_addr_; } + T* host_address() const { return host_ptr_; } + + operator T*() const { return host_ptr_; } + + T* operator->() const { return host_ptr_; } + T& operator*() const { return *host_ptr_; } + + auto value() const { + if constexpr (is_be_type_v) { + return static_cast(*host_ptr_); + } else { + return *host_ptr_; + } + } + + explicit operator bool() const { return host_ptr_ != nullptr; } + explicit operator u32() const { return guest_address(); } + + MappedPtr operator+(std::ptrdiff_t offset) const { + return MappedPtr(host_ptr_ + offset, guest_addr_ + static_cast(offset * sizeof(T))); + } + MappedPtr operator-(std::ptrdiff_t offset) const { + return MappedPtr(host_ptr_ - offset, guest_addr_ - static_cast(offset * sizeof(T))); + } + + template + U as() const { + return reinterpret_cast(host_ptr_); + } + + template + rex::be* as_array() const { + return reinterpret_cast*>(host_ptr_); + } + + void Zero() const { + if (host_ptr_) { + std::memset(host_ptr_, 0, sizeof(T)); + } + } + + void Zero(size_t size) const { + if (host_ptr_) { + std::memset(host_ptr_, 0, size); + } + } +}; + +//============================================================================= +// MappedPtr Specialization +//============================================================================= + +template <> +class MappedPtr { + void* host_ptr_; + u32 guest_addr_; + + public: + MappedPtr() : host_ptr_(nullptr), guest_addr_(0) {} + MappedPtr(void* host_ptr, u32 guest_addr) : host_ptr_(host_ptr), guest_addr_(guest_addr) {} + MappedPtr(std::nullptr_t) : host_ptr_(nullptr), guest_addr_(0) {} + + static MappedPtr from_host(void* host_ptr) { return MappedPtr(host_ptr, 0); } + + u32 guest_address() const { return guest_addr_; } + u32 value() const { return guest_addr_; } + void* host_address() const { return host_ptr_; } + + operator void*() const { return host_ptr_; } + operator uint8_t*() const { return static_cast(host_ptr_); } + explicit operator bool() const { return host_ptr_ != nullptr; } + explicit operator u32() const { return guest_addr_; } + + template + MappedPtr operator+(IntType offset) const { + return MappedPtr(static_cast(host_ptr_) + static_cast(offset), + guest_addr_ + static_cast(offset)); + } + template + MappedPtr operator-(IntType offset) const { + return MappedPtr(static_cast(host_ptr_) - static_cast(offset), + guest_addr_ - static_cast(offset)); + } + + template + U as() const { + return reinterpret_cast(host_ptr_); + } + + template + rex::be* as_array() const { + return reinterpret_cast*>(host_ptr_); + } + + void Zero(size_t size) const { + if (host_ptr_) { + std::memset(host_ptr_, 0, size); + } + } +}; + +//============================================================================= +// MappedPtr Specialization (strings) +//============================================================================= + +template <> +class MappedPtr { + char* host_ptr_; + u32 guest_addr_; + + public: + MappedPtr() : host_ptr_(nullptr), guest_addr_(0) {} + MappedPtr(char* host_ptr, u32 guest_addr) : host_ptr_(host_ptr), guest_addr_(guest_addr) {} + MappedPtr(std::nullptr_t) : host_ptr_(nullptr), guest_addr_(0) {} + + u32 guest_address() const { return guest_addr_; } + char* host_address() const { return host_ptr_; } + + operator char*() const { return host_ptr_; } + explicit operator bool() const { return host_ptr_ != nullptr; } + + std::string_view value() const { + return host_ptr_ ? std::string_view(host_ptr_) : std::string_view(); + } + + char* operator->() const { return host_ptr_; } + char& operator*() const { return *host_ptr_; } + + MappedPtr operator+(std::ptrdiff_t offset) const { + return MappedPtr(host_ptr_ + offset, guest_addr_ + static_cast(offset)); + } + MappedPtr operator-(std::ptrdiff_t offset) const { + return MappedPtr(host_ptr_ - offset, guest_addr_ - static_cast(offset)); + } + + char& operator[](size_t idx) const { return host_ptr_[idx]; } + + template + U as() const { + return reinterpret_cast(host_ptr_); + } +}; + +//============================================================================= +// MappedPtr Specialization (wide strings) +//============================================================================= + +template <> +class MappedPtr { + char16_t* host_ptr_; + u32 guest_addr_; + + public: + MappedPtr() : host_ptr_(nullptr), guest_addr_(0) {} + MappedPtr(char16_t* host_ptr, u32 guest_addr) : host_ptr_(host_ptr), guest_addr_(guest_addr) {} + MappedPtr(std::nullptr_t) : host_ptr_(nullptr), guest_addr_(0) {} + + u32 guest_address() const { return guest_addr_; } + char16_t* host_address() const { return host_ptr_; } + + operator char16_t*() const { return host_ptr_; } + explicit operator bool() const { return host_ptr_ != nullptr; } + + std::u16string_view value() const { + return host_ptr_ ? std::u16string_view(host_ptr_) : std::u16string_view(); + } + + char16_t* operator->() const { return host_ptr_; } + char16_t& operator*() const { return *host_ptr_; } + + MappedPtr operator+(std::ptrdiff_t offset) const { + return MappedPtr(host_ptr_ + offset, guest_addr_ + static_cast(offset * sizeof(char16_t))); + } + MappedPtr operator-(std::ptrdiff_t offset) const { + return MappedPtr(host_ptr_ - offset, guest_addr_ - static_cast(offset * sizeof(char16_t))); + } + + char16_t& operator[](size_t idx) const { return host_ptr_[idx]; } + + template + U as() const { + return reinterpret_cast(host_ptr_); + } +}; + +//============================================================================= +// MappedPtr Type Traits +//============================================================================= + +template +struct is_mapped_ptr : std::false_type {}; +template +struct is_mapped_ptr> : std::true_type {}; +template +inline constexpr bool is_mapped_ptr_v = is_mapped_ptr::value; + +template +struct mapped_ptr_inner_type; +template +struct mapped_ptr_inner_type> { + using type = T; +}; + +} // namespace rex + +//============================================================================= +// Global Namespace Exports +//============================================================================= + +using u8 = rex::u8; +using i8 = rex::i8; +using u16 = rex::u16; +using i16 = rex::i16; +using u32 = rex::u32; +using i32 = rex::i32; +using u64 = rex::u64; +using i64 = rex::i64; +using f32 = rex::f32; +using f64 = rex::f64; + +using be_u16 = rex::be_u16; +using be_u32 = rex::be_u32; +using be_u64 = rex::be_u64; +using be_i16 = rex::be_i16; +using be_i32 = rex::be_i32; +using be_i64 = rex::be_i64; +using be_f32 = rex::be_f32; +using be_f64 = rex::be_f64; + +using mapped_void = rex::MappedPtr; +using mapped_u8 = rex::MappedPtr; +using mapped_u16 = rex::MappedPtr; +using mapped_u32 = rex::MappedPtr; +using mapped_u64 = rex::MappedPtr; +using mapped_f32 = rex::MappedPtr; +using mapped_f64 = rex::MappedPtr; +using mapped_string = rex::MappedPtr; +using mapped_wstring = rex::MappedPtr; + +// Legacy compat alias for ppc_ptr_t +template +using ppc_ptr_t = rex::MappedPtr; diff --git a/include/rex/ui/d3d12/d3d12_api.h b/include/rex/ui/d3d12/d3d12_api.h new file mode 100644 index 0000000..d0e7252 --- /dev/null +++ b/include/rex/ui/d3d12/d3d12_api.h @@ -0,0 +1,35 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2018 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +// clang - format off +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#include + +#include +#include +#include +#include +#include +#include +// For Microsoft::WRL::ComPtr. +#include +#include +#include "DxbcConverter.h" + +// clang-format on diff --git a/include/rex/ui/d3d12/d3d12_cpu_descriptor_pool.h b/include/rex/ui/d3d12/d3d12_cpu_descriptor_pool.h new file mode 100644 index 0000000..c1cd1cc --- /dev/null +++ b/include/rex/ui/d3d12/d3d12_cpu_descriptor_pool.h @@ -0,0 +1,109 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include + +namespace rex::ui::d3d12 { + +// Single-descriptor pool with reference counting and unique ownership of +// allocations, safe to use in environments where the order of releasing of the +// descriptor heap and of allocated descriptors is undefined. +class D3D12CpuDescriptorPool : public std::enable_shared_from_this { + public: + class Descriptor { + public: + Descriptor() = default; + // shared_ptr to ensure correct release order with between render targets + // and descriptor pools. + Descriptor(std::shared_ptr pool, size_t index) + : pool_(pool), index_(index) {} + // Owns a descriptor in the pool exclusively. + Descriptor(const Descriptor& descriptor) = delete; + Descriptor& operator=(const Descriptor& descriptor) = delete; + Descriptor(Descriptor&& descriptor) { + pool_ = std::move(descriptor.pool_); + index_ = descriptor.index_; + } + Descriptor& operator=(Descriptor&& descriptor) { + if (IsValid() && pool_ == descriptor.pool_ && index_ == descriptor.index_) { + // If moving to self, don't free. + return *this; + } + Free(); + pool_ = std::move(descriptor.pool_); + index_ = descriptor.index_; + return *this; + } + ~Descriptor() { Free(); } + void Free() { + if (!pool_) { + return; + } + pool_->FreeDescriptor(index_); + pool_.reset(); + } + bool IsValid() const { return pool_.get() != nullptr; } + operator bool() const { return IsValid(); } + D3D12_CPU_DESCRIPTOR_HANDLE GetHandle() const { + assert_true(IsValid()); + return pool_->GetHandle(index_); + } + + private: + std::shared_ptr pool_; + size_t index_ = 0; + }; + + D3D12CpuDescriptorPool(const ui::d3d12::D3D12Provider& provider, D3D12_DESCRIPTOR_HEAP_TYPE type, + uint32_t heap_size_log2) + : provider_(provider), type_(type), heap_size_log2_(heap_size_log2) { + assert_true(heap_size_log2 <= 31); + } + D3D12CpuDescriptorPool(const D3D12CpuDescriptorPool& pool) = delete; + D3D12CpuDescriptorPool& operator=(const D3D12CpuDescriptorPool& pool) = delete; + // No point in moving, created only via make_shared. + D3D12CpuDescriptorPool(D3D12CpuDescriptorPool&& pool) = delete; + D3D12CpuDescriptorPool& operator=(D3D12CpuDescriptorPool&& pool) = delete; + ~D3D12CpuDescriptorPool() { + for (ID3D12DescriptorHeap* heap : heaps_) { + heap->Release(); + } + } + + Descriptor AllocateDescriptor(); + + private: + void FreeDescriptor(size_t index) { freed_indices_.push_back(index); } + + D3D12_CPU_DESCRIPTOR_HANDLE GetHandle(size_t index) const { + D3D12_CPU_DESCRIPTOR_HANDLE heap_start = + heaps_[index >> heap_size_log2_]->GetCPUDescriptorHandleForHeapStart(); + uint32_t heap_local_index = uint32_t(index & ((uint32_t(1) << heap_size_log2_) - 1)); + return provider_.OffsetDescriptor(type_, heap_start, heap_local_index); + } + + const ui::d3d12::D3D12Provider& provider_; + D3D12_DESCRIPTOR_HEAP_TYPE type_; + uint32_t heap_size_log2_; + std::vector heaps_; + std::vector freed_indices_; + uint32_t last_heap_allocated_ = 0; +}; + +} // namespace rex::ui::d3d12 diff --git a/include/rex/ui/d3d12/d3d12_descriptor_heap_pool.h b/include/rex/ui/d3d12/d3d12_descriptor_heap_pool.h new file mode 100644 index 0000000..68a54af --- /dev/null +++ b/include/rex/ui/d3d12/d3d12_descriptor_heap_pool.h @@ -0,0 +1,103 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include + +namespace rex::ui::d3d12 { + +// Submission index is the fence value or a value derived from it (if reclaiming +// less often than once per fence value, for instance). + +class D3D12DescriptorHeapPool { + public: + static constexpr uint64_t kHeapIndexInvalid = UINT64_MAX; + + D3D12DescriptorHeapPool(ID3D12Device* device, D3D12_DESCRIPTOR_HEAP_TYPE type, + uint32_t page_size); + ~D3D12DescriptorHeapPool(); + + void Reclaim(uint64_t completed_submission_index); + void ChangeSubmissionTimeline(); + void ClearCache(); + + // Because all descriptors for a single draw call must be in the same heap, + // sometimes all descriptors, rather than only the modified portion of it, + // needs to be written. + // + // This may happen if there's not enough free space even for a partial update + // in the current heap, or if the heap which contains the unchanged part of + // the descriptors is outdated. + // + // If something uses this pool to do partial updates, it must let this + // function determine whether a partial update is possible. For this purpose, + // this function returns the heap reset index - and it must be called with its + // previous return value for the set of descriptors it's updating. + // + // If this function returns a value that is the same as previous_heap_index, a + // partial update needs to be done - and space for count_for_partial_update is + // allocated. + // + // If it's different, all descriptors must be written again - and space for + // count_for_full_update is allocated. + // + // If kHeapIndexInvalid is returned, there was an error. + // + // This MUST be called even if there's nothing to write in a partial update + // (with count_for_partial_update being 0), because a full update may still be + // required. + uint64_t Request(uint64_t submission_index, uint64_t previous_heap_index, + uint32_t count_for_partial_update, uint32_t count_for_full_update, + uint32_t& index_out); + + // The current heap, for binding and actually writing - may be called only + // after a successful request because before a request, the heap may not exist + // yet. + ID3D12DescriptorHeap* GetLastRequestHeap() const { return writable_first_->heap.Get(); } + D3D12_CPU_DESCRIPTOR_HANDLE GetLastRequestHeapCPUStart() const { + return writable_first_->cpu_start; + } + D3D12_GPU_DESCRIPTOR_HANDLE GetLastRequestHeapGPUStart() const { + return writable_first_->gpu_start; + } + + private: + ID3D12Device* device_; + D3D12_DESCRIPTOR_HEAP_TYPE type_; + uint32_t page_size_; + + struct Page { + Microsoft::WRL::ComPtr heap; + D3D12_CPU_DESCRIPTOR_HANDLE cpu_start; + D3D12_GPU_DESCRIPTOR_HANDLE gpu_start; + uint64_t last_submission_index; + Page* next; + }; + + // A list of heap with free space, with the first buffer being the one + // currently being filled. + Page* writable_first_ = nullptr; + Page* writable_last_ = nullptr; + // A list of full heaps that can be reclaimed when the GPU doesn't use them + // anymore. + Page* submitted_first_ = nullptr; + Page* submitted_last_ = nullptr; + // Monotonically increased when a new request is going to a different + // ID3D12DescriptorHeap than the one that may be bound currently. See Request + // for more information. + uint64_t current_heap_index_ = 0; + uint32_t current_page_used_ = 0; +}; + +} // namespace rex::ui::d3d12 diff --git a/include/rex/ui/d3d12/d3d12_immediate_drawer.h b/include/rex/ui/d3d12/d3d12_immediate_drawer.h new file mode 100644 index 0000000..ef511e0 --- /dev/null +++ b/include/rex/ui/d3d12/d3d12_immediate_drawer.h @@ -0,0 +1,161 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace rex::ui::d3d12 { + +class D3D12ImmediateDrawer final : public ImmediateDrawer { + public: + static std::unique_ptr Create(const D3D12Provider& provider) { + auto immediate_drawer = + std::unique_ptr(new D3D12ImmediateDrawer(provider)); + if (!immediate_drawer->Initialize()) { + return nullptr; + } + return std::move(immediate_drawer); + } + + ~D3D12ImmediateDrawer(); + + std::unique_ptr CreateTexture(uint32_t width, uint32_t height, + ImmediateTextureFilter filter, bool is_repeated, + const uint8_t* data) override; + + void Begin(UIDrawContext& ui_draw_context, float coordinate_space_width, + float coordinate_space_height) override; + void BeginDrawBatch(const ImmediateDrawBatch& batch) override; + void Draw(const ImmediateDraw& draw) override; + void EndDrawBatch() override; + void End() override; + + protected: + void OnLeavePresenter() override; + + private: + enum class SamplerIndex { + kNearestClamp, + kLinearClamp, + kNearestRepeat, + kLinearRepeat, + + kCount, + kInvalid = kCount + }; + + class D3D12ImmediateTexture final : public ImmediateTexture { + public: + static constexpr DXGI_FORMAT kFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + D3D12ImmediateTexture(uint32_t width, uint32_t height, ID3D12Resource* resource, + SamplerIndex sampler_index, D3D12ImmediateDrawer* immediate_drawer, + size_t immediate_drawer_index); + ~D3D12ImmediateTexture() override; + + ID3D12Resource* resource() const { return resource_.Get(); } + SamplerIndex sampler_index() const { return sampler_index_; } + + size_t immediate_drawer_index() const { return immediate_drawer_index_; } + void SetImmediateDrawerIndex(size_t index) { immediate_drawer_index_ = index; } + void OnImmediateDrawerDestroyed(); + + UINT64 last_usage_submission_index() const { return last_usage_submission_index_; } + void SetLastUsageSubmissionIndex(UINT64 submission_index) { + last_usage_submission_index_ = submission_index; + } + + private: + Microsoft::WRL::ComPtr resource_; + SamplerIndex sampler_index_; + + D3D12ImmediateDrawer* immediate_drawer_; + size_t immediate_drawer_index_; + + UINT64 last_usage_submission_index_ = 0; + }; + + D3D12ImmediateDrawer(const D3D12Provider& provider) : provider_(provider) {} + bool Initialize(); + + void OnImmediateTextureDestroyed(D3D12ImmediateTexture& texture); + + void UploadTextures(); + + const D3D12Provider& provider_; + + Microsoft::WRL::ComPtr root_signature_; + enum class RootParameter { + kTexture, + kSampler, + kCoordinateSpaceSizeInv, + + kCount + }; + + Microsoft::WRL::ComPtr pipeline_triangle_; + Microsoft::WRL::ComPtr pipeline_line_; + + Microsoft::WRL::ComPtr sampler_heap_; + D3D12_CPU_DESCRIPTOR_HANDLE sampler_heap_cpu_start_; + D3D12_GPU_DESCRIPTOR_HANDLE sampler_heap_gpu_start_; + + // Only with non-null resources. + std::vector textures_; + + struct PendingTextureUpload { + PendingTextureUpload(ID3D12Resource* texture, ID3D12Resource* buffer) + : texture(texture), buffer(buffer) {} + Microsoft::WRL::ComPtr texture; + Microsoft::WRL::ComPtr buffer; + }; + std::vector texture_uploads_pending_; + + struct SubmittedTextureUpload { + SubmittedTextureUpload(ID3D12Resource* texture, ID3D12Resource* buffer, UINT64 submission_index) + : texture(texture), buffer(buffer), submission_index(submission_index) {} + Microsoft::WRL::ComPtr texture; + Microsoft::WRL::ComPtr buffer; + UINT64 submission_index; + }; + std::deque texture_uploads_submitted_; + + std::deque, UINT64>> textures_deleted_; + + std::unique_ptr vertex_buffer_pool_; + std::unique_ptr texture_descriptor_pool_; + + // The submission index within the current Begin (or the last, if outside + // one). + UINT64 last_paint_submission_index_ = 0; + // Completed submission index as of the latest Begin, to coarsely skip delayed + // texture deletion. + UINT64 last_completed_submission_index_ = 0; + + bool batch_open_ = false; + bool batch_has_index_buffer_; + D3D12_RECT current_scissor_; + D3D_PRIMITIVE_TOPOLOGY current_primitive_topology_; + ID3D12Resource* current_texture_; + uint64_t current_texture_descriptor_heap_index_; + SamplerIndex current_sampler_index_; +}; + +} // namespace rex::ui::d3d12 diff --git a/include/rex/ui/d3d12/d3d12_presenter.h b/include/rex/ui/d3d12/d3d12_presenter.h new file mode 100644 index 0000000..83d09f7 --- /dev/null +++ b/include/rex/ui/d3d12/d3d12_presenter.h @@ -0,0 +1,325 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace rex::ui::d3d12 { + +class D3D12UIDrawContext final : public UIDrawContext { + public: + D3D12UIDrawContext(Presenter& presenter, uint32_t render_target_width, + uint32_t render_target_height, ID3D12GraphicsCommandList* command_list, + UINT64 submission_index_current, UINT64 submission_index_completed) + : UIDrawContext(presenter, render_target_width, render_target_height), + command_list_(command_list), + submission_index_current_(submission_index_current), + submission_index_completed_(submission_index_completed) {} + + ID3D12GraphicsCommandList* command_list() const { return command_list_.Get(); } + UINT64 submission_index_current() const { return submission_index_current_; } + UINT64 submission_index_completed() const { return submission_index_completed_; } + + private: + Microsoft::WRL::ComPtr command_list_; + UINT64 submission_index_current_; + UINT64 submission_index_completed_; +}; + +class D3D12Presenter final : public Presenter { + public: + static constexpr DXGI_FORMAT kGuestOutputFormat = DXGI_FORMAT_R10G10B10A2_UNORM; + static constexpr D3D12_RESOURCE_STATES kGuestOutputInternalState = + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + + static constexpr DXGI_FORMAT kGuestOutputIntermediateFormat = DXGI_FORMAT_R10G10B10A2_UNORM; + + // The format used internally by Windows composition. + static constexpr DXGI_FORMAT kSwapChainFormat = DXGI_FORMAT_B8G8R8A8_UNORM; + + // The callback must use the main direct queue of the provider. + class D3D12GuestOutputRefreshContext final : public GuestOutputRefreshContext { + public: + D3D12GuestOutputRefreshContext(bool& is_8bpc_out_ref, ID3D12Resource* resource) + : GuestOutputRefreshContext(is_8bpc_out_ref), resource_(resource) {} + + // kGuestOutputFormat, supports UAV. The initial state in the callback is + // kGuestOutputInternalState, and the callback must also transition it back + // to kGuestOutputInternalState before finishing. + ID3D12Resource* resource_uav_capable() const { return resource_.Get(); } + + private: + Microsoft::WRL::ComPtr resource_; + }; + + static std::unique_ptr Create(HostGpuLossCallback host_gpu_loss_callback, + const D3D12Provider& provider) { + auto presenter = + std::unique_ptr(new D3D12Presenter(host_gpu_loss_callback, provider)); + if (!presenter->InitializeSurfaceIndependent()) { + return nullptr; + } + return presenter; + } + + ~D3D12Presenter(); + + const D3D12Provider& provider() const { return provider_; } + + Surface::TypeFlags GetSupportedSurfaceTypes() const override; + + bool CaptureGuestOutput(RawImage& image_out) override; + + void AwaitUISubmissionCompletionFromUIThread(UINT64 submission_index) { + ui_submission_tracker_.AwaitSubmissionCompletion(submission_index); + } + + protected: + SurfacePaintConnectResult ConnectOrReconnectPaintingToSurfaceFromUIThread( + Surface& new_surface, uint32_t new_surface_width, uint32_t new_surface_height, + bool was_paintable, bool& is_vsync_implicit_out) override; + void DisconnectPaintingFromSurfaceFromUIThreadImpl() override; + + bool RefreshGuestOutputImpl(uint32_t mailbox_index, uint32_t frontbuffer_width, + uint32_t frontbuffer_height, + std::function refresher, + bool& is_8bpc_out) override; + + PaintResult PaintAndPresentImpl(bool execute_ui_drawers) override; + + private: + struct GuestOutputPaintRectangleConstants { + union { + struct { + float x; + float y; + }; + float offset[2]; + }; + union { + struct { + float width; + float height; + }; + float size[2]; + }; + }; + + enum class GuestOutputPaintRootParameter : UINT { + kSource, + kRectangle, + kEffectConstants, + + kCount, + }; + + enum GuestOutputPaintRootSignatureIndex : size_t { + kGuestOutputPaintRootSignatureIndexBilinear, +#if defined(REX_HAS_FIDELITYFX_SDK) + kGuestOutputPaintRootSignatureIndexCasSharpen, + kGuestOutputPaintRootSignatureIndexCasResample, + kGuestOutputPaintRootSignatureIndexFsrEasu, + kGuestOutputPaintRootSignatureIndexFsrRcas, +#endif + + kGuestOutputPaintRootSignatureCount, + }; + + static constexpr GuestOutputPaintRootSignatureIndex GetGuestOutputPaintRootSignatureIndex( + GuestOutputPaintEffect effect) { + switch (effect) { + case GuestOutputPaintEffect::kBilinear: + case GuestOutputPaintEffect::kBilinearDither: + return kGuestOutputPaintRootSignatureIndexBilinear; +#if defined(REX_HAS_FIDELITYFX_SDK) + case GuestOutputPaintEffect::kCasSharpen: + case GuestOutputPaintEffect::kCasSharpenDither: + return kGuestOutputPaintRootSignatureIndexCasSharpen; + case GuestOutputPaintEffect::kCasResample: + case GuestOutputPaintEffect::kCasResampleDither: + return kGuestOutputPaintRootSignatureIndexCasResample; + case GuestOutputPaintEffect::kFsrEasu: + return kGuestOutputPaintRootSignatureIndexFsrEasu; + case GuestOutputPaintEffect::kFsrRcas: + case GuestOutputPaintEffect::kFsrRcasDither: + return kGuestOutputPaintRootSignatureIndexFsrRcas; +#endif + default: + assert_unhandled_case(effect); + return kGuestOutputPaintRootSignatureCount; + } + } + + struct PaintContext { + explicit PaintContext() = default; + PaintContext(const PaintContext& paint_context) = delete; + PaintContext& operator=(const PaintContext& paint_context) = delete; + + static constexpr uint32_t kSwapChainBufferCount = 3; + + enum RTVIndex : UINT { + // Swap chain buffers - updated when creating the swap chain + // (connection-specific). + kRTVIndexSwapChainBuffer0, + + // Intermediate textures - the last usage is + // guest_output_intermediate_texture_paint_last_usage_. + kRTVIndexGuestOutputIntermediate0 = kRTVIndexSwapChainBuffer0 + kSwapChainBufferCount, + + kRTVCount = kRTVIndexGuestOutputIntermediate0 + kGuestOutputMailboxSize - 1, + }; + + enum ViewIndex : UINT { + // Guest output textures - indices are the same as in + // guest_output_resource_paint_refs, and the last usage is tied to them. + kViewIndexGuestOutput0Srv, + + // Intermediate textures - the last usage is + // guest_output_intermediate_texture_paint_last_usage_. + kViewIndexGuestOutputIntermediate0Srv = kViewIndexGuestOutput0Srv + kGuestOutputMailboxSize, + + kViewCount = kViewIndexGuestOutputIntermediate0Srv + kMaxGuestOutputPaintEffects - 1, + }; + + void AwaitSwapChainUsageCompletion() { + // Presentation engine usage. + present_submission_tracker.AwaitAllSubmissionsCompletion(); + // Paint (render target) usage. While the presentation fence is signaled + // on the same queue, and presentation happens after painting, awaiting + // anyway for safety just to make less assumptions in the architecture. + paint_submission_tracker.AwaitAllSubmissionsCompletion(); + } + + void DestroySwapChain(); + + // Connection-independent. + + // Signaled before presenting. + D3D12SubmissionTracker paint_submission_tracker; + // Signaled after presenting. + D3D12SubmissionTracker present_submission_tracker; + + std::array, kSwapChainBufferCount> + command_allocators; + Microsoft::WRL::ComPtr command_list; + + // Descriptor heaps for views of the current resources related to the guest + // output and to painting, updated either during painting or during + // connection lifetime management if outdated after awaiting usage + // completion. + // RTV heap. + Microsoft::WRL::ComPtr rtv_heap; + // Shader-visible CBV/SRV/UAV heap. + Microsoft::WRL::ComPtr view_heap; + + // Refreshed and cleaned up during guest output painting. The first is the + // paint submission index in which the guest output texture (and its + // descriptors) was last used, the second is the reference to the texture, + // which may be null. The indices are not mailbox indices here, rather, if + // the reference is not in this array yet, the most outdated reference, if + // needed, is replaced with the new one, awaiting the completion of the last + // paint usage. + std::array>, kGuestOutputMailboxSize> + guest_output_resource_paint_refs; + + // Current intermediate textures for guest output painting, refreshed when + // painting guest output. While not in use, they are in + // D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE. + std::array, kMaxGuestOutputPaintEffects - 1> + guest_output_intermediate_textures; + UINT64 guest_output_intermediate_texture_last_usage = 0; + + // Connection-specific. + + uint32_t swap_chain_width = 0; + uint32_t swap_chain_height = 0; + bool swap_chain_allows_tearing = false; + Microsoft::WRL::ComPtr swap_chain; + std::array, kSwapChainBufferCount> swap_chain_buffers; + }; + + explicit D3D12Presenter(HostGpuLossCallback host_gpu_loss_callback, const D3D12Provider& provider) + : Presenter(host_gpu_loss_callback), provider_(provider) {} + + bool dxgi_supports_tearing() const { return dxgi_supports_tearing_; } + + bool InitializeSurfaceIndependent(); + +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME + bool EnsureTemporalUpscalerContext(uint32_t render_width, uint32_t render_height, + uint32_t output_width, uint32_t output_height); + bool DispatchTemporalUpscaler(ID3D12GraphicsCommandList* command_list, + ID3D12Resource* input_resource, uint32_t input_width, + uint32_t input_height, ID3D12Resource* output_resource, + uint32_t output_width, uint32_t output_height, + const GuestOutputPaintConfig& config); + void DestroyTemporalUpscalerContext(); +#endif + + const D3D12Provider& provider_; + + // Whether DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING is supported by DXGI (depends in + // particular on the Windows 10 version and hardware support), primarily for + // variable refresh rate support. + bool dxgi_supports_tearing_ = false; + + // Static objects for guest output presentation, used only when painting the + // main target (can be destroyed only after awaiting main target usage + // completion). + std::array, kGuestOutputPaintRootSignatureCount> + guest_output_paint_root_signatures_; + std::array, size_t(GuestOutputPaintEffect::kCount)> + guest_output_paint_intermediate_pipelines_; + std::array, size_t(GuestOutputPaintEffect::kCount)> + guest_output_paint_final_pipelines_; + + // The first is the refresher submission tracker fence value at which the + // guest output texture was last refreshed, the second is the reference to the + // texture, which may be null. The indices are the mailbox indices. + std::array>, kGuestOutputMailboxSize> + guest_output_resources_; + // The guest output resources are protected by two submission trackers - the + // refresher ones (for writing to them via the guest_output_resources_ + // references) and the paint one (for presenting it via the + // paint_context_.guest_output_resource_paint_refs references taken from + // guest_output_resources_). + D3D12SubmissionTracker guest_output_resource_refresher_submission_tracker_; + + // UI submission tracker with the submission index that can be given to UI + // drawers (accessible from the UI thread only, at any time). + D3D12SubmissionTracker ui_submission_tracker_; + + // Accessible only by painting and by surface connection lifetime management + // (ConnectOrReconnectPaintingToSurfaceFromUIThread, + // DisconnectPaintingFromSurfaceFromUIThreadImpl) by the thread doing it, as + // well as by presenter initialization and shutdown. + PaintContext paint_context_; + +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME + void* temporal_upscaler_context_ = nullptr; + uint32_t temporal_upscaler_max_render_width_ = 0; + uint32_t temporal_upscaler_max_render_height_ = 0; + uint32_t temporal_upscaler_max_output_width_ = 0; + uint32_t temporal_upscaler_max_output_height_ = 0; + bool temporal_upscaler_provider_logged_ = false; +#endif +}; + +} // namespace rex::ui::d3d12 diff --git a/include/rex/ui/d3d12/d3d12_provider.h b/include/rex/ui/d3d12/d3d12_provider.h new file mode 100644 index 0000000..35035a4 --- /dev/null +++ b/include/rex/ui/d3d12/d3d12_provider.h @@ -0,0 +1,172 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include +#include + +namespace rex::ui::d3d12 { + +class D3D12Provider : public GraphicsProvider { + public: + ~D3D12Provider(); + + static bool IsD3D12APIAvailable(); + + static std::unique_ptr Create(); + + std::unique_ptr CreatePresenter(Presenter::HostGpuLossCallback host_gpu_loss_callback = + Presenter::FatalErrorHostGpuLossCallback) override; + + std::unique_ptr CreateImmediateDrawer() override; + + IDXGIFactory2* GetDXGIFactory() const { return dxgi_factory_; } + // nullptr if PIX not attached. + IDXGraphicsAnalysis* GetGraphicsAnalysis() const { return graphics_analysis_; } + ID3D12Device* GetDevice() const { return device_; } + ID3D12CommandQueue* GetDirectQueue() const { return direct_queue_; } + + uint32_t GetDescriptorSize(D3D12_DESCRIPTOR_HEAP_TYPE type) const { + return descriptor_sizes_[type]; + } + uint32_t GetViewDescriptorSize() const { + return GetDescriptorSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + } + uint32_t GetSamplerDescriptorSize() const { + return GetDescriptorSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + } + uint32_t GetRTVDescriptorSize() const { + return GetDescriptorSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + } + uint32_t GetDSVDescriptorSize() const { + return GetDescriptorSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); + } + template + T OffsetDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE type, T start, uint32_t index) const { + start.ptr += index * GetDescriptorSize(type); + return start; + } + template + T OffsetViewDescriptor(T start, uint32_t index) const { + start.ptr += index * GetViewDescriptorSize(); + return start; + } + template + T OffsetSamplerDescriptor(T start, uint32_t index) const { + start.ptr += index * GetSamplerDescriptorSize(); + return start; + } + template + T OffsetRTVDescriptor(T start, uint32_t index) const { + start.ptr += index * GetRTVDescriptorSize(); + return start; + } + template + T OffsetDSVDescriptor(T start, uint32_t index) const { + start.ptr += index * GetDSVDescriptorSize(); + return start; + } + + // Adapter info. + GpuVendorID GetAdapterVendorID() const { return adapter_vendor_id_; } + + // Device features. + D3D12_HEAP_FLAGS GetHeapFlagCreateNotZeroed() const { return heap_flag_create_not_zeroed_; } + D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER + GetProgrammableSamplePositionsTier() const { return programmable_sample_positions_tier_; } + bool IsPSSpecifiedStencilReferenceSupported() const { + return ps_specified_stencil_reference_supported_; + } + bool AreRasterizerOrderedViewsSupported() const { return rasterizer_ordered_views_supported_; } + D3D12_RESOURCE_BINDING_TIER GetResourceBindingTier() const { return resource_binding_tier_; } + D3D12_TILED_RESOURCES_TIER GetTiledResourcesTier() const { return tiled_resources_tier_; } + bool AreUnalignedBlockTexturesSupported() const { return unaligned_block_textures_supported_; } + uint32_t GetVirtualAddressBitsPerResource() const { return virtual_address_bits_per_resource_; } + + // Proxies for DirectX functions since they are loaded dynamically. + HRESULT SerializeRootSignature(const D3D12_ROOT_SIGNATURE_DESC* desc, + D3D_ROOT_SIGNATURE_VERSION version, ID3DBlob** blob_out, + ID3DBlob** error_blob_out) const { + return pfn_d3d12_serialize_root_signature_(desc, version, blob_out, error_blob_out); + } + HRESULT Disassemble(const void* src_data, size_t src_data_size, UINT flags, const char* comments, + ID3DBlob** disassembly_out) const { + if (!pfn_d3d_disassemble_) { + return E_NOINTERFACE; + } + return pfn_d3d_disassemble_(src_data, src_data_size, flags, comments, disassembly_out); + } + HRESULT DxbcConverterCreateInstance(const CLSID& rclsid, const IID& riid, void** ppv) const { + if (!pfn_dxilconv_dxc_create_instance_) { + return E_NOINTERFACE; + } + return pfn_dxilconv_dxc_create_instance_(rclsid, riid, ppv); + } + HRESULT DxcCreateInstance(const CLSID& rclsid, const IID& riid, void** ppv) const { + if (!pfn_dxcompiler_dxc_create_instance_) { + return E_NOINTERFACE; + } + return pfn_dxcompiler_dxc_create_instance_(rclsid, riid, ppv); + } + + private: + D3D12Provider() = default; + + static bool EnableIncreaseBasePriorityPrivilege(); + bool Initialize(); + + typedef HRESULT(WINAPI* PFNCreateDXGIFactory2)(UINT Flags, REFIID riid, + _COM_Outptr_ void** ppFactory); + typedef HRESULT(WINAPI* PFNDXGIGetDebugInterface1)(UINT Flags, REFIID riid, + _COM_Outptr_ void** pDebug); + + HMODULE library_dxgi_ = nullptr; + PFNCreateDXGIFactory2 pfn_create_dxgi_factory2_; + // Needed during shutdown as well to report live objects, so may be nullptr. + PFNDXGIGetDebugInterface1 pfn_dxgi_get_debug_interface1_ = nullptr; + + HMODULE library_d3d12_ = nullptr; + PFN_D3D12_GET_DEBUG_INTERFACE pfn_d3d12_get_debug_interface_; + PFN_D3D12_CREATE_DEVICE pfn_d3d12_create_device_; + PFN_D3D12_SERIALIZE_ROOT_SIGNATURE pfn_d3d12_serialize_root_signature_; + + HMODULE library_d3dcompiler_ = nullptr; + pD3DDisassemble pfn_d3d_disassemble_ = nullptr; + + HMODULE library_dxilconv_ = nullptr; + DxcCreateInstanceProc pfn_dxilconv_dxc_create_instance_ = nullptr; + + HMODULE library_dxcompiler_ = nullptr; + DxcCreateInstanceProc pfn_dxcompiler_dxc_create_instance_ = nullptr; + + IDXGIFactory2* dxgi_factory_ = nullptr; + ID3D12Device* device_ = nullptr; + ID3D12CommandQueue* direct_queue_ = nullptr; + IDXGraphicsAnalysis* graphics_analysis_ = nullptr; + + uint32_t descriptor_sizes_[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES]; + + GpuVendorID adapter_vendor_id_; + + D3D12_HEAP_FLAGS heap_flag_create_not_zeroed_; + D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER programmable_sample_positions_tier_; + D3D12_RESOURCE_BINDING_TIER resource_binding_tier_; + D3D12_TILED_RESOURCES_TIER tiled_resources_tier_; + uint32_t virtual_address_bits_per_resource_; + bool ps_specified_stencil_reference_supported_; + bool rasterizer_ordered_views_supported_; + bool unaligned_block_textures_supported_; +}; + +} // namespace rex::ui::d3d12 diff --git a/include/rex/ui/d3d12/d3d12_submission_tracker.h b/include/rex/ui/d3d12/d3d12_submission_tracker.h new file mode 100644 index 0000000..2ca1704 --- /dev/null +++ b/include/rex/ui/d3d12/d3d12_submission_tracker.h @@ -0,0 +1,86 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +namespace rex::ui::d3d12 { + +// GPU > CPU fence wrapper, safely handling cases when the fence has not been +// initialized yet or has already been shut down, dropped submissions, and also +// transfers between queues so signals stay ordered. +// +// The current submission index can be associated with the usage of objects to +// release them when the GPU isn't potentially referencing them anymore, and +// should be incremented only +// +// 0 can be used as a "never referenced" submission index. +// +// The submission index timeline survives Shutdown / Initialize, so submission +// indices can be given to clients that are not aware of the lifetime of the +// tracker. +class D3D12SubmissionTracker { + public: + D3D12SubmissionTracker() = default; + D3D12SubmissionTracker(const D3D12SubmissionTracker& submission_tracker) = delete; + D3D12SubmissionTracker& operator=(const D3D12SubmissionTracker& submission_tracker) = delete; + ~D3D12SubmissionTracker() { Shutdown(); } + + // The queue may be null if it's going to be set dynamically. Will also take a + // reference to the queue. + bool Initialize(ID3D12Device* device, ID3D12CommandQueue* queue); + void Shutdown(); + + // Will perform an ownership transfer if the queue is different than the + // current one, and take a reference to the queue. + void SetQueue(ID3D12CommandQueue* new_queue); + + UINT64 GetCurrentSubmission() const { return submission_current_; } + // May be lower than a value awaited by AwaitSubmissionCompletion if it + // returned false. + UINT64 GetCompletedSubmission() const { + // If shut down already or haven't fully initialized yet, don't care, for + // simplicity of external code, as any downloads are unlikely in this case, + // but destruction can be simplified. + return fence_ ? fence_->GetCompletedValue() : (GetCurrentSubmission() - 1); + } + + // Returns whether the expected GPU signal has actually been reached (rather + // than some fallback condition) for cases when stronger completeness + // guarantees as needed (when downloading, as opposed to just destroying). + // If false is returned, it's also not guaranteed that GetCompletedSubmission + // will return a value >= submission_index. + bool AwaitSubmissionCompletion(UINT64 submission_index); + bool AwaitAllSubmissionsCompletion() { + return AwaitSubmissionCompletion(GetCurrentSubmission() - 1); + } + + // Call after a successful ExecuteCommandList. Unconditionally increments the + // current submission index, and tries to enqueue the fence signal. Returns + // true if enqueued successfully, but even if not, waiting for submissions + // without a successfully enqueued signal is handled in the tracker in a way + // that it won't be infinite, so there's no need for clients to revert updates + // to submission indices associated with GPU usage of objects. + bool NextSubmission(); + // If NextSubmission has failed, but it's important that the signal is + // enqueued, can be used to retry enqueueing the signal. + bool TrySignalEnqueueing(); + + private: + UINT64 submission_current_ = 1; + UINT64 submission_signal_queued_ = 0; + HANDLE fence_completion_event_ = nullptr; + Microsoft::WRL::ComPtr fence_; + Microsoft::WRL::ComPtr queue_; +}; + +} // namespace rex::ui::d3d12 diff --git a/include/rex/ui/d3d12/d3d12_upload_buffer_pool.h b/include/rex/ui/d3d12/d3d12_upload_buffer_pool.h new file mode 100644 index 0000000..0e33a65 --- /dev/null +++ b/include/rex/ui/d3d12/d3d12_upload_buffer_pool.h @@ -0,0 +1,46 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +namespace rex::ui::d3d12 { + +class D3D12UploadBufferPool : public GraphicsUploadBufferPool { + public: + D3D12UploadBufferPool(const D3D12Provider& provider, size_t page_size = kDefaultPageSize); + + uint8_t* Request(uint64_t submission_index, size_t size, size_t alignment, + ID3D12Resource** buffer_out, size_t* offset_out, + D3D12_GPU_VIRTUAL_ADDRESS* gpu_address_out); + uint8_t* RequestPartial(uint64_t submission_index, size_t size, size_t alignment, + ID3D12Resource** buffer_out, size_t* offset_out, size_t* size_out, + D3D12_GPU_VIRTUAL_ADDRESS* gpu_address_out); + + protected: + Page* CreatePageImplementation() override; + + private: + struct D3D12Page : public Page { + // Creates a reference to the buffer. It must not be unmapped until this + // D3D12Page is deleted. + D3D12Page(ID3D12Resource* buffer, void* mapping); + Microsoft::WRL::ComPtr buffer_; + void* mapping_; + D3D12_GPU_VIRTUAL_ADDRESS gpu_address_; + }; + + const D3D12Provider& provider_; +}; + +} // namespace rex::ui::d3d12 diff --git a/include/rex/ui/d3d12/d3d12_util.h b/include/rex/ui/d3d12/d3d12_util.h new file mode 100644 index 0000000..364690d --- /dev/null +++ b/include/rex/ui/d3d12/d3d12_util.h @@ -0,0 +1,88 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2018 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include + +namespace rex::ui::d3d12 { +namespace util { + +using DescriptorCpuGpuHandlePair = + std::pair; + +inline constexpr D3D12_HEAP_PROPERTIES kHeapPropertiesDefault = {D3D12_HEAP_TYPE_DEFAULT}; +inline constexpr D3D12_HEAP_PROPERTIES kHeapPropertiesUpload = {D3D12_HEAP_TYPE_UPLOAD}; +inline constexpr D3D12_HEAP_PROPERTIES kHeapPropertiesReadback = {D3D12_HEAP_TYPE_READBACK}; + +template +bool ReleaseAndNull(T& object) { + if (object != nullptr) { + object->Release(); + object = nullptr; + return true; + } + return false; +}; + +ID3D12RootSignature* CreateRootSignature(const D3D12Provider& provider, + const D3D12_ROOT_SIGNATURE_DESC& desc); + +ID3D12PipelineState* CreateComputePipeline(ID3D12Device* device, const void* shader, + size_t shader_size, ID3D12RootSignature* root_signature); + +constexpr DXGI_FORMAT GetUintPow2DXGIFormat(uint32_t element_size_bytes_log2) { + switch (element_size_bytes_log2) { + case 0: + return DXGI_FORMAT_R8_UINT; + case 1: + return DXGI_FORMAT_R16_UINT; + case 2: + return DXGI_FORMAT_R32_UINT; + case 3: + return DXGI_FORMAT_R32G32_UINT; + case 4: + return DXGI_FORMAT_R32G32B32A32_UINT; + default: + return DXGI_FORMAT_UNKNOWN; + } +} + +inline void FillBufferResourceDesc(D3D12_RESOURCE_DESC& desc, UINT64 size, + D3D12_RESOURCE_FLAGS flags) { + desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + desc.Alignment = 0; + desc.Width = size; + desc.Height = 1; + desc.DepthOrArraySize = 1; + desc.MipLevels = 1; + desc.Format = DXGI_FORMAT_UNKNOWN; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + desc.Flags = flags; +} + +void CreateBufferRawSRV(ID3D12Device* device, D3D12_CPU_DESCRIPTOR_HANDLE handle, + ID3D12Resource* buffer, uint32_t size, uint64_t offset = 0); +void CreateBufferRawUAV(ID3D12Device* device, D3D12_CPU_DESCRIPTOR_HANDLE handle, + ID3D12Resource* buffer, uint32_t size, uint64_t offset = 0); +void CreateBufferTypedSRV(ID3D12Device* device, D3D12_CPU_DESCRIPTOR_HANDLE handle, + ID3D12Resource* buffer, DXGI_FORMAT format, uint32_t num_elements, + uint64_t first_element = 0); +void CreateBufferTypedUAV(ID3D12Device* device, D3D12_CPU_DESCRIPTOR_HANDLE handle, + ID3D12Resource* buffer, DXGI_FORMAT format, uint32_t num_elements, + uint64_t first_element = 0); + +} // namespace util +} // namespace rex::ui::d3d12 diff --git a/include/rex/ui/flags.h b/include/rex/ui/flags.h new file mode 100644 index 0000000..ad6065d --- /dev/null +++ b/include/rex/ui/flags.h @@ -0,0 +1,56 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +// Presenter +REXCVAR_DECLARE(bool, present_render_pass_clear); +REXCVAR_DECLARE(bool, present_letterbox); +REXCVAR_DECLARE(int32_t, present_safe_area_x); +REXCVAR_DECLARE(int32_t, present_safe_area_y); +REXCVAR_DECLARE(std::string, present_effect); +REXCVAR_DECLARE(double, present_cas_additional_sharpness); +REXCVAR_DECLARE(int32_t, present_fsr_max_upsampling_passes); +REXCVAR_DECLARE(double, present_fsr_sharpness_reduction); +REXCVAR_DECLARE(std::string, present_fsr_quality_mode); +REXCVAR_DECLARE(bool, present_dither); +REXCVAR_DECLARE(bool, present_allow_overscan_cutoff); +REXCVAR_DECLARE(bool, host_present_from_non_ui_thread); +REXCVAR_DECLARE(int32_t, window_width); +REXCVAR_DECLARE(int32_t, window_height); +REXCVAR_DECLARE(bool, fullscreen); +REXCVAR_DECLARE(int32_t, monitor); + +// D3D12 +REXCVAR_DECLARE(bool, d3d12_debug); +REXCVAR_DECLARE(bool, d3d12_break_on_error); +REXCVAR_DECLARE(bool, d3d12_break_on_warning); +REXCVAR_DECLARE(int32_t, d3d12_adapter); +REXCVAR_DECLARE(int32_t, d3d12_queue_priority); +REXCVAR_DECLARE(bool, d3d12_allow_variable_refresh_rate_and_tearing); + +// Vulkan +REXCVAR_DECLARE(bool, vulkan_log_debug_messages); +REXCVAR_DECLARE(bool, vulkan_allow_present_mode_immediate); +REXCVAR_DECLARE(bool, vulkan_allow_present_mode_mailbox); +REXCVAR_DECLARE(bool, vulkan_allow_present_mode_fifo_relaxed); +REXCVAR_DECLARE(bool, vulkan_validation_enabled); +REXCVAR_DECLARE(int32_t, vulkan_device); +REXCVAR_DECLARE(bool, vulkan_prefer_geometry_shader); +REXCVAR_DECLARE(bool, vulkan_prefer_fragment_stores_and_atomics); +REXCVAR_DECLARE(bool, vulkan_prefer_vertex_pipeline_stores_and_atomics); +REXCVAR_DECLARE(bool, vulkan_prefer_fill_mode_non_solid); +REXCVAR_DECLARE(bool, vulkan_require_geometry_shader); +REXCVAR_DECLARE(bool, vulkan_require_fragment_stores_and_atomics); +REXCVAR_DECLARE(bool, vulkan_require_vertex_pipeline_stores_and_atomics); +REXCVAR_DECLARE(bool, vulkan_require_fill_mode_non_solid); diff --git a/include/rex/ui/graphics_provider.h b/include/rex/ui/graphics_provider.h new file mode 100644 index 0000000..dea7f16 --- /dev/null +++ b/include/rex/ui/graphics_provider.h @@ -0,0 +1,59 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include + +namespace rex { +namespace ui { + +class Window; + +// Factory for graphics contexts. +// All contexts created by the same provider will be able to share resources +// according to the rules of the backing graphics API. +class GraphicsProvider { + public: + enum class GpuVendorID { + kAMD = 0x1002, + kApple = 0x106B, + kArm = 0x13B5, + kImagination = 0x1010, + kIntel = 0x8086, + kMicrosoft = 0x1414, + kNvidia = 0x10DE, + kQualcomm = 0x5143, + }; + + GraphicsProvider(const GraphicsProvider&) = delete; + GraphicsProvider& operator=(const GraphicsProvider&) = delete; + GraphicsProvider(GraphicsProvider&&) = delete; + GraphicsProvider& operator=(GraphicsProvider&&) = delete; + + virtual ~GraphicsProvider() = default; + + // It's safe to reinitialize the presenter in the host GPU loss callback if it + // was called from the UI thread as specified in the arguments. + virtual std::unique_ptr CreatePresenter( + Presenter::HostGpuLossCallback host_gpu_loss_callback = + Presenter::FatalErrorHostGpuLossCallback) = 0; + + virtual std::unique_ptr CreateImmediateDrawer() = 0; + + protected: + GraphicsProvider() = default; +}; + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/graphics_upload_buffer_pool.h b/include/rex/ui/graphics_upload_buffer_pool.h new file mode 100644 index 0000000..517513c --- /dev/null +++ b/include/rex/ui/graphics_upload_buffer_pool.h @@ -0,0 +1,82 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include + +namespace rex { +namespace ui { + +using namespace rex::literals; + +// Submission index is the fence value or a value derived from it (if reclaiming +// less often than once per fence value, for instance). + +class GraphicsUploadBufferPool { + public: + // Taken from the Direct3D 12 MiniEngine sample (LinearAllocator + // kCpuAllocatorPageSize). Large enough for most cases. + static constexpr size_t kDefaultPageSize = 2_MiB; + + virtual ~GraphicsUploadBufferPool(); + + void Reclaim(uint64_t completed_submission_index); + void ChangeSubmissionTimeline(); + void ClearCache(); + + // Should be called before submitting anything using this pool, unless the + // implementation doesn't require explicit flushing. + void FlushWrites(); + + protected: + // Extended by the implementation. + struct Page { + virtual ~Page(); + uint64_t last_submission_index_; + Page* next_; + }; + + GraphicsUploadBufferPool(size_t page_size) : page_size_(page_size) {} + + // Request to write data in a single piece, creating a new page if the current + // one doesn't have enough free space. + Page* Request(uint64_t submission_index, size_t size, size_t alignment, size_t& offset_out); + // Request to write data in multiple parts, filling the buffer entirely. + Page* RequestPartial(uint64_t submission_index, size_t size, size_t alignment, size_t& offset_out, + size_t& size_out); + + virtual Page* CreatePageImplementation() = 0; + + virtual void FlushPageWrites(Page* page, size_t offset, size_t size); + + // May be increased by the implementation on creation or on first allocation + // to avoid wasting space if the real allocation turns out to be bigger than + // the specified page size. + size_t page_size_; + + // A list of buffers with free space, with the first buffer being the one + // currently being filled. + Page* writable_first_ = nullptr; + Page* writable_last_ = nullptr; + // A list of full buffers that can be reclaimed when the GPU doesn't use them + // anymore. + Page* submitted_first_ = nullptr; + Page* submitted_last_ = nullptr; + + size_t current_page_used_ = 0; + size_t current_page_flushed_ = 0; +}; + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/graphics_util.h b/include/rex/ui/graphics_util.h new file mode 100644 index 0000000..97198ea --- /dev/null +++ b/include/rex/ui/graphics_util.h @@ -0,0 +1,28 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +namespace rex { +namespace ui { + +// For estimating coverage extents from vertices. This may give results that are +// different than what the GPU will actually draw (this is the reference +// conversion with 1/2 ULP accuracy, but Direct3D 11 permits 0.6 ULP tolerance +// in floating point to fixed point conversion), but is enough to tie-break +// vertices at pixel centers (due to the half-pixel offset applied to integer +// coordinates incorrectly, for instance) with some error tolerance near 0.5, +// for use with the top-left rasterization rule later. +int32_t FloatToD3D11Fixed16p8(float f32); + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/imgui_dialog.h b/include/rex/ui/imgui_dialog.h new file mode 100644 index 0000000..1018d5e --- /dev/null +++ b/include/rex/ui/imgui_dialog.h @@ -0,0 +1,64 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#ifndef REX_UI_IMGUI_DIALOG_H_ +#define REX_UI_IMGUI_DIALOG_H_ + +#include +#include + +#include +#include +#include + +struct ImGuiIO; + +namespace rex { +namespace ui { + +class ImGuiDialog { + public: + ~ImGuiDialog(); + + // Shows a simple message box containing a text message. + // Callers can want for the dialog to close with Wait(). + // Dialogs retain themselves and will delete themselves when closed. + static ImGuiDialog* ShowMessageBox(ImGuiDrawer* imgui_drawer, std::string title, + std::string body); + + // A fence to signal when the dialog is closed. + void Then(rex::thread::Fence* fence); + + void Draw(); + + protected: + ImGuiDialog(ImGuiDrawer* imgui_drawer); + + ImGuiDrawer* imgui_drawer() const { return imgui_drawer_; } + ImGuiIO& GetIO(); + + // Closes the dialog and returns to any waiters. + void Close(); + + virtual void OnShow() {} + virtual void OnClose() {} + virtual void OnDraw(ImGuiIO& io) { (void)io; } + + private: + ImGuiDrawer* imgui_drawer_ = nullptr; + bool has_close_pending_ = false; + std::vector waiting_fences_; +}; + +} // namespace ui +} // namespace rex + +#endif // REX_UI_IMGUI_DIALOG_H_ diff --git a/include/rex/ui/imgui_drawer.h b/include/rex/ui/imgui_drawer.h new file mode 100644 index 0000000..c72b628 --- /dev/null +++ b/include/rex/ui/imgui_drawer.h @@ -0,0 +1,127 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#ifndef REX_UI_IMGUI_DRAWER_H_ +#define REX_UI_IMGUI_DRAWER_H_ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +struct ImDrawData; +struct ImFontAtlas; +struct ImGuiContext; +struct ImGuiIO; +enum ImGuiKey : int; + +namespace rex { +namespace ui { + +class ImGuiDialog; +class Window; + +class ImGuiDrawer : public WindowInputListener, public UIDrawer { + public: + using FontSetupCallback = std::function; + ImGuiDrawer(Window* window, size_t z_order, FontSetupCallback font_setup = nullptr); + ~ImGuiDrawer(); + + ImGuiIO& GetIO(); + + void AddDialog(ImGuiDialog* dialog); + void RemoveDialog(ImGuiDialog* dialog); + + // SetPresenter may be called from the destructor. + void SetPresenter(Presenter* new_presenter); + void SetImmediateDrawer(ImmediateDrawer* new_immediate_drawer); + void SetPresenterAndImmediateDrawer(Presenter* new_presenter, + ImmediateDrawer* new_immediate_drawer) { + SetPresenter(new_presenter); + SetImmediateDrawer(new_immediate_drawer); + } + + void Draw(UIDrawContext& ui_draw_context) override; + + protected: + void OnKeyDown(KeyEvent& e) override; + void OnKeyUp(KeyEvent& e) override; + void OnKeyChar(KeyEvent& e) override; + void OnMouseDown(MouseEvent& e) override; + void OnMouseMove(MouseEvent& e) override; + void OnMouseUp(MouseEvent& e) override; + void OnMouseWheel(MouseEvent& e) override; + void OnTouchEvent(TouchEvent& e) override; + // For now, no need for OnDpiChanged because redrawing is done continuously. + + private: + void Initialize(); + + void SetupFontTexture(); + + void RenderDrawLists(ImDrawData* data, UIDrawContext& ui_draw_context); + + void ClearInput(); + void OnKey(KeyEvent& e, bool is_down); + void UpdateMousePosition(float x, float y); + void SwitchToPhysicalMouseAndUpdateMousePosition(const MouseEvent& e); + + bool IsDrawingDialogs() const { return dialog_loop_next_index_ != SIZE_MAX; } + void DetachIfLastDialogRemoved(); + + std::optional VirtualKeyToImGuiKey(VirtualKey vkey); + + Window* window_; + size_t z_order_; + FontSetupCallback font_setup_; + + ImGuiContext* internal_state_ = nullptr; + + // All currently-attached dialogs that get drawn. + std::vector dialogs_; + // Using an index, not an iterator, because after the erasure, the adjustment + // must be done for the vector element indices that would be in the iterator + // range that would be invalidated. + // SIZE_MAX if not currently in the dialog loop. + size_t dialog_loop_next_index_ = SIZE_MAX; + + Presenter* presenter_ = nullptr; + + ImmediateDrawer* immediate_drawer_ = nullptr; + // Resources specific to an immediate drawer - must be destroyed before + // detaching the presenter. + std::unique_ptr font_texture_; + + // If there's an active pointer, the ImGui mouse is controlled by this touch. + // If it's TouchEvent::kPointerIDNone, the ImGui mouse is controlled by the + // mouse. + uint32_t touch_pointer_id_ = TouchEvent::kPointerIDNone; + // Whether after the next frame (since the mouse up event needs to be handled + // with the correct mouse position still), the ImGui mouse position should be + // reset (for instance, after releasing a touch), so it's not hovering over + // anything. + bool reset_mouse_position_after_next_frame_ = false; + + double frame_time_tick_frequency_; + uint64_t last_frame_time_ticks_; +}; + +} // namespace ui +} // namespace rex + +#endif // REX_UI_IMGUI_DRAWER_H_ diff --git a/include/rex/ui/immediate_drawer.h b/include/rex/ui/immediate_drawer.h new file mode 100644 index 0000000..500b9a4 --- /dev/null +++ b/include/rex/ui/immediate_drawer.h @@ -0,0 +1,150 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include + +namespace rex { +namespace ui { + +// Describes the filter applied when sampling textures. +enum class ImmediateTextureFilter { + kNearest, + kLinear, +}; + +// Simple texture compatible with the immediate renderer. +class ImmediateTexture { + public: + virtual ~ImmediateTexture() = default; + + // Texture width, in pixels. + uint32_t width; + // Texture height, in pixels. + uint32_t height; + + protected: + ImmediateTexture(uint32_t width, uint32_t height) : width(width), height(height) {} +}; + +// Describes the primitive type used by a draw call. +enum class ImmediatePrimitiveType { + kLines, + kTriangles, +}; + +// Simple vertex used by the immediate mode drawer. +// To avoid translations, this matches both imgui and elemental-forms vertices: +// ImDrawVert +// el::graphics::Renderer::Vertex +struct ImmediateVertex { + float x, y; + float u, v; + uint32_t color; +}; + +// All parameters required to draw an immediate-mode batch of vertices. +struct ImmediateDrawBatch { + // Vertices to draw. + const ImmediateVertex* vertices = nullptr; + int vertex_count = 0; + + // Optional index buffer indices. + const uint16_t* indices = nullptr; + int index_count = 0; +}; + +struct ImmediateDraw { + // Primitive type the vertices/indices represent. + ImmediatePrimitiveType primitive_type = ImmediatePrimitiveType::kTriangles; + // Total number of elements to draw. + int count = 0; + // Starting offset in the index buffer. + int index_offset = 0; + // Base vertex of elements, if using an index buffer. + int base_vertex = 0; + + // Texture used when drawing, or nullptr if color only. + ImmediateTexture* texture = nullptr; + + // True to enable scissoring using the region defined by scissor_rect. + bool scissor = false; + // Scissoring region in the coordinate space (if right < left or bottom < top, + // not drawing). + float scissor_left = 0.0f; + float scissor_top = 0.0f; + float scissor_right = 0.0f; + float scissor_bottom = 0.0f; +}; + +class ImmediateDrawer { + public: + ImmediateDrawer(const ImmediateDrawer& immediate_drawer) = delete; + ImmediateDrawer& operator=(const ImmediateDrawer& immediate_drawer) = delete; + + virtual ~ImmediateDrawer() = default; + + void SetPresenter(Presenter* new_presenter); + + // Creates a new texture with the given attributes and R8G8B8A8 data. + virtual std::unique_ptr CreateTexture(uint32_t width, uint32_t height, + ImmediateTextureFilter filter, + bool is_repeated, + const uint8_t* data) = 0; + + // Begins drawing in immediate mode using the given projection matrix. The + // presenter that is currently attached to the immediate drawer, as the + // implementation may hold presenter-specific information such as UI + // submission indices. Pass 0 or a negative value as the coordinate space + // width or height to use raw render target pixel coordinates (or this will + // just be used as a safe fallback when with a non-zero-sized surface the + // coordinate space size becomes zero somehow). + virtual void Begin(UIDrawContext& ui_draw_context, float coordinate_space_width, + float coordinate_space_height); + // Starts a draw batch. + virtual void BeginDrawBatch(const ImmediateDrawBatch& batch) = 0; + // Draws one set of a batch. + virtual void Draw(const ImmediateDraw& draw) = 0; + // Ends a draw batch. + virtual void EndDrawBatch() = 0; + // Ends drawing in immediate mode and flushes contents. + virtual void End(); + + protected: + ImmediateDrawer() = default; + + Presenter* presenter() const { return presenter_; } + virtual void OnLeavePresenter() {} + virtual void OnEnterPresenter() {} + + // Available between Begin and End. + UIDrawContext* ui_draw_context() const { return ui_draw_context_; } + float coordinate_space_width() const { return coordinate_space_width_; } + float coordinate_space_height() const { return coordinate_space_height_; } + + // Converts and clamps the scissor in the immediate draw to render target + // coordinates. Returns whether the scissor contains any render target pixels + // (but a valid scissor is written even if false is returned). + bool ScissorToRenderTarget(const ImmediateDraw& immediate_draw, uint32_t& out_left, + uint32_t& out_top, uint32_t& out_width, uint32_t& out_height); + + private: + Presenter* presenter_ = nullptr; + + UIDrawContext* ui_draw_context_ = nullptr; + float coordinate_space_width_; + float coordinate_space_height_; +}; + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/keybinds.h b/include/rex/ui/keybinds.h new file mode 100644 index 0000000..3120f16 --- /dev/null +++ b/include/rex/ui/keybinds.h @@ -0,0 +1,85 @@ +/** + * @file rex/ui/keybinds.h + * @brief Key binding registry with cvar-backed rebindable keys. + * + * Provides a global bind registry where components (like overlay dialogs) + * can register named keybinds with default keys and callbacks. Binds are + * backed by string CVARs in the "Keybinds" category, so they appear in + * the settings overlay and can be saved to config files. + * + * @section keybinds_usage Usage + * + * @code + * // Register a bind (typically in a constructor): + * rex::ui::RegisterBind("bind_console", "Backtick", + * "Toggle console overlay", [this]{ ToggleVisible(); }); + * + * // Dispatch key events (typically in OnKeyDown): + * rex::ui::ProcessKeyEvent(e); + * + * // Unregister (typically in a destructor): + * rex::ui::UnregisterBind("bind_console"); + * @endcode + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ +#pragma once +#include +#include +#include +#include +#include + +namespace rex::ui { + +/** + * Parse a human-readable key name to a VirtualKey enum value. + * @param name Key name string (e.g. "F3", "Backtick", "A", "Escape"). + * @return Matching VirtualKey, or VirtualKey::kNone if unrecognized. + */ +VirtualKey ParseVirtualKey(std::string_view name); + +/** + * Convert a VirtualKey to its human-readable string name. + * @param vk VirtualKey to convert. + * @return Key name string (e.g. "F3", "LMB"), or empty if unrecognized. + */ +std::string VirtualKeyToString(VirtualKey vk); + +/** + * Register a named keybind with a default key and callback. + * + * Creates a string CVAR named @p name in the "Keybinds" category so the + * binding is visible in the settings overlay and persisted to config. + * + * @param name CVAR name for this bind (e.g. "bind_console"). + * @param default_key Default key name (e.g. "Backtick", "F3"). + * @param description Human-readable description for the settings UI. + * @param callback Function to invoke when the bound key is pressed. + */ +void RegisterBind(std::string_view name, std::string_view default_key, std::string_view description, + std::function callback); + +/** + * Remove a previously registered keybind. + * @param name The CVAR name used when registering the bind. + */ +void UnregisterBind(std::string_view name); + +/** + * Process a key-down event against all registered binds. + * + * Looks up each bind's current key from its CVAR, parses it, and compares + * against the event's virtual key. If a match is found, the bind's callback + * is invoked and the event is marked as handled. + * + * @param e The key event to process. + * @return True if a bind matched and the event was consumed. + */ +bool ProcessKeyEvent(KeyEvent& e); + +} // namespace rex::ui diff --git a/include/rex/ui/menu_item.h b/include/rex/ui/menu_item.h new file mode 100644 index 0000000..97f2214 --- /dev/null +++ b/include/rex/ui/menu_item.h @@ -0,0 +1,86 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include + +namespace rex { +namespace ui { + +class Window; + +class MenuItem { + public: + typedef std::unique_ptr MenuItemPtr; + + enum class Type { + kPopup, // Popup menu (submenu) + kSeparator, + kNormal, // Root menu + kString, // Menu is just a string + }; + + static std::unique_ptr Create(Type type); + static std::unique_ptr Create(Type type, const std::string& text); + static std::unique_ptr Create(Type type, const std::string& text, + std::function callback); + static std::unique_ptr Create(Type type, const std::string& text, + const std::string& hotkey, + std::function callback); + + virtual ~MenuItem(); + + MenuItem* parent_item() const { return parent_item_; } + Type type() { return type_; } + const std::string& text() { return text_; } + const std::string& hotkey() { return hotkey_; } + + // If the menu is currently attached to a Window, changes to it (such as the + // elements and the enabled / disabled state) may be not reflected + // immediately - call Window::CompleteMainMenuItemsUpdate when the + // modifications are done. + + void AddChild(MenuItem* child_item); + void AddChild(std::unique_ptr child_item); + void AddChild(MenuItemPtr child_item); + void RemoveChild(MenuItem* child_item); + MenuItem* child(size_t index); + + virtual void SetEnabled(bool enabled) { (void)enabled; } + + protected: + MenuItem(Type type, const std::string& text, const std::string& hotkey, + std::function callback); + + virtual void OnChildAdded(MenuItem* child_item) { (void)child_item; } + virtual void OnChildRemoved(MenuItem* child_item) { (void)child_item; } + + // This MenuItem may be destroyed as a result of the callback, don't do + // anything with it after the call. + void OnSelected(); + + Type type_; + MenuItem* parent_item_; + std::vector children_; + std::string text_; + std::string hotkey_; + + private: + std::function callback_; +}; + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/overlay/console_overlay.h b/include/rex/ui/overlay/console_overlay.h new file mode 100644 index 0000000..2cfa4c6 --- /dev/null +++ b/include/rex/ui/overlay/console_overlay.h @@ -0,0 +1,58 @@ +/** + * @file rex/ui/overlay/console_overlay.h + * + * @brief ImGui console overlay dialog for viewing captured log output. + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::ui { + +class ConsoleDialog : public ImGuiDialog { + public: + ConsoleDialog(ImGuiDrawer* imgui_drawer, std::shared_ptr sink); + ~ConsoleDialog(); + + protected: + void OnDraw(ImGuiIO& io) override; + + private: + void ExecuteCommand(std::string_view cmd); + void RefreshCategories(); + static int InputTextCallback(ImGuiInputTextCallbackData* data); + + bool focus_input_next_frame_ = true; + bool scroll_to_bottom_ = true; + uint64_t last_generation_ = 0; + + std::shared_ptr sink_; + std::vector entries_; // refreshed each frame when generation changes + std::vector local_entries_; // console-only output (command feedback) + + // Filters + int min_level_ = 0; // index into spdlog level enum; 0 = trace + std::set known_categories_; + std::map category_filter_; // category -> enabled + + // Command input + char input_buf_[512] = {}; + std::deque history_; + int history_pos_ = -1; + static constexpr size_t kMaxHistory = 32; +}; + +} // namespace rex::ui diff --git a/include/rex/ui/overlay/debug_overlay.h b/include/rex/ui/overlay/debug_overlay.h new file mode 100644 index 0000000..e15e410 --- /dev/null +++ b/include/rex/ui/overlay/debug_overlay.h @@ -0,0 +1,47 @@ +/** + * @file rex/ui/overlay/debug_overlay.h + * + * @brief ImGui debug overlay dialog for frame timing display. + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ +#pragma once +#include +#include +#include +#include + +namespace rex::ui { + +struct FrameStats { + double frame_time_ms = 0; + double fps = 0; + uint64_t frame_count = 0; +}; + +class DebugOverlayDialog : public ImGuiDialog { + public: + using FrameStatsProvider = std::function; + + explicit DebugOverlayDialog(ImGuiDrawer* imgui_drawer, FrameStatsProvider stats_provider = {}); + ~DebugOverlayDialog(); + + void SetStatsProvider(FrameStatsProvider provider) { stats_provider_ = std::move(provider); } + + protected: + void OnDraw(ImGuiIO& io) override; + + private: + FrameStatsProvider stats_provider_; +#ifdef REXGLUE_ENABLE_PERF_COUNTERS + static constexpr size_t kFrameHistorySize = 120; + std::array frame_time_history_{}; + size_t frame_history_idx_ = 0; +#endif +}; + +} // namespace rex::ui diff --git a/include/rex/ui/overlay/settings_overlay.h b/include/rex/ui/overlay/settings_overlay.h new file mode 100644 index 0000000..5b80eac --- /dev/null +++ b/include/rex/ui/overlay/settings_overlay.h @@ -0,0 +1,35 @@ +/** + * @file rex/ui/overlay/settings_overlay.h + * + * @brief ImGui settings overlay dialog for cvar editing with save-to-config. + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ +#pragma once +#include +#include +#include + +namespace rex::ui { + +class SettingsDialog : public ImGuiDialog { + public: + // config_path: where "Save to config" writes (e.g. exe_dir / "app.toml") + SettingsDialog(ImGuiDrawer* imgui_drawer, std::filesystem::path config_path); + ~SettingsDialog(); + + protected: + void OnDraw(ImGuiIO& io) override; + + private: + std::filesystem::path config_path_; + char search_buf_[128] = {}; + std::string selected_category_; + std::string capturing_bind_name_; +}; + +} // namespace rex::ui diff --git a/include/rex/ui/presenter.h b/include/rex/ui/presenter.h new file mode 100644 index 0000000..8358f29 --- /dev/null +++ b/include/rex/ui/presenter.h @@ -0,0 +1,1038 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#if REX_PLATFORM_WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#include + +#include +#endif // XE_PLATFORM + +namespace rex { +namespace ui { + +class Presenter; +class Window; +class Win32Window; + +class UIDrawContext { + public: + UIDrawContext(const UIDrawContext& context) = delete; + UIDrawContext& operator=(const UIDrawContext& context) = delete; + virtual ~UIDrawContext() = default; + + Presenter& presenter() const { return presenter_; } + + // It's assumed that the render target size will be either equal to the size + // of the surface, or the render target will be stretched to cover the entire + // surface (not in the corner of the surface). + uint32_t render_target_width() const { return render_target_width_; } + uint32_t render_target_height() const { return render_target_height_; } + + protected: + explicit UIDrawContext(Presenter& presenter, uint32_t render_target_width, + uint32_t render_target_height) + : presenter_(presenter), + render_target_width_(render_target_width), + render_target_height_(render_target_height) {} + + private: + Presenter& presenter_; + uint32_t render_target_width_; + uint32_t render_target_height_; +}; + +struct RawImage { + uint32_t width = 0; + uint32_t height = 0; + size_t stride = 0; + // R8 G8 B8 X8. The last row is not required to be padded to the stride. + std::vector data; +}; + +// The presenter displays up to two layers of content on a host surface: +// - Guest output image, focusing on lowering latency and maintaining stable +// frame pacing, with various scaling and sharpening methods and letterboxing; +// - Xenia's internal UI (such as the profiler and Dear ImGui). +// +// The guest output image may be refreshed from any thread generating it +// (usually the GPU emulation thread), as long as there are no multiple threads +// doing that simultaneously (since that would functionally be a race condition +// even if refreshing is performed in a critical section). +// +// The UI overlays are managed entirely by the UI thread. +// +// Painting on the host surface may occur in two places: +// - If there are no UI overlays, painting of the guest output may be performed +// immediately from the thread refreshing it, to bypass the OS scheduling and +// event handling. This is especially important on platforms where the native +// surface paint event has a frame rate limit (such as the display refresh +// rate), and the limit may differ greatly from the guest frame rate (such as +// presenting a 30 or 60 FPS guest to a 144 Hz host surface). +// - If the UI overlays (owned by the UI thread) are present, painting of both +// the guest output (is available) and the UI is done exclusively from the +// platform paint event handler. The guest output without UI overlays may also +// be painted from the platform paint callback in certain cases, such as when +// an additional paint beyond the guest's frame rate may be needed (like when +// resizing the window), or when painting from the thread refreshing the guest +// output is undesirable (for instance, if it will result in waiting for host +// vertical sync in that thread too early if host vertical sync can't be +// disabled on the platform, blocking the next frame of GPU emulation). +// +// The composition of the guest and the UI is done by Xenia manually, as opposed +// to using platform functionality such as DirectComposition, in order to have +// more predictability of GPU queue scheduling, but primarily to be able to take +// advantage of independent host presentation where it's available, so variable +// refresh rate may be used where possible, and latency may be significantly +// reduced. Also, at least on some configurations (checked on Windows 11 21H2 on +// Nvidia GeForce GTX 1070 with driver version 472.12), when in borderless +// fullscreen, any composition causes the DXGI Present to wait for vertical sync +// on the GPU even if the sync interval 0 is specified. +// +// An intermediate image with the size requested by the guest is used for guest +// output in all cases. Even though it adds some GPU overhead, especially in the +// 1:1 size case, using it solves multiple issues: +// - Presentation may be done more often than by the guest. +// - There is clear separation between pre-scaling and mid- / post-scaling +// operations. The gamma ramp, for instance, may be applied before scaling, +// with one lookup per pixel rather than four with fetch4. +// - A simpler compute shader may be used instead of setting up the whole +// graphics pipeline for copying in the GPU command processor in all cases, +// while Direct3D 12 does not allow UAVs for swap chain buffers. +// +// The presenter limits the frame rate of the UI overlay (when possible) to a +// value that's ideally the refresh rate of the monitor containing the window if +// the platform's paint event doesn't have an internal limiter. However, where +// possible, the arrival of a new guest output image will interrupt the UI tick +// wait. +// +// Because the UI overlays preclude the possibility of presenting directly from +// the thread refreshing the guest output, and on some platforms, result in the +// frame rate limiting of paint events manifesting itself, there must be no +// persistent UI overlays that haven't been explicitly requested by the user. +// However, for temporary (primarily non-modal) UI elements such as various +// timed notifications, using the Presenter should be preferred to implementing +// them via overlaying native windows on top of the presentation surface on +// platforms where the concept of independent presentation exists, as multiple +// windows will result in native composition disabling it. +// +// The painting connection between the Presenter and the Surface can be managed +// only by the UI thread. However, the thread refreshing the guest output may +// still mark the current connection as outdated and ask the UI thread (by +// requesting painting) to try to recover - but the guest output refresh thread +// must not try to reconnect by itself, as methods of the Surface are available +// only to the UI thread. +class Presenter { + public: + // May be actually called on the UI thread even if statically_from_ui_thread + // is false, such as when the guest output is refreshed by the UI thread. + using HostGpuLossCallback = + std::function; + static void FatalErrorHostGpuLossCallback(bool is_responsible, bool statically_from_ui_thread); + + class GuestOutputRefreshContext { + public: + GuestOutputRefreshContext(const GuestOutputRefreshContext& context) = delete; + GuestOutputRefreshContext& operator=(const GuestOutputRefreshContext& context) = delete; + virtual ~GuestOutputRefreshContext() = default; + + // Sets whether the source actually has no more than 8 bits of precision + // (though the image provided by the refresher may still have a higher + // storage precision). If never called, assuming it's false. + void SetIs8bpc(bool is_8bpc) { is_8bpc_out_ref_ = is_8bpc; } + + protected: + GuestOutputRefreshContext(bool& is_8bpc_out_ref) : is_8bpc_out_ref_(is_8bpc_out_ref) { + is_8bpc_out_ref = false; + } + + private: + bool& is_8bpc_out_ref_; + }; + + class GuestOutputPaintConfig { + public: + enum class Effect { + kBilinear, +#if defined(REX_HAS_FIDELITYFX_SDK) + kCas, + // AMD FidelityFX Super Resolution upsampling, Contrast Adaptive + // Sharpening otherwise. + kFsr, + // FidelityFX FSR2 selection. Uses the runtime temporal upscaler path + // where available; currently still experimental due to limited temporal + // inputs in the presenter path. + kFsr2, + // FidelityFX FSR3 selection. Uses the runtime temporal upscaler path + // where available; currently still experimental due to limited temporal + // inputs in the presenter path. + kFsr3, +#endif + }; + +#if defined(REX_HAS_FIDELITYFX_SDK) + enum class FsrQualityMode { + // Keep current behavior and use the guest output size as-is. + kAuto, + kNativeAa, + kQuality, + kBalanced, + kPerformance, + kUltraPerformance, + }; + + // This value is used as a lerp factor. + static constexpr float kCasAdditionalSharpnessMin = 0.0f; + static constexpr float kCasAdditionalSharpnessMax = 1.0f; + static constexpr float kCasAdditionalSharpnessDefault = 0.0f; + static_assert(kCasAdditionalSharpnessDefault >= kCasAdditionalSharpnessMin && + kCasAdditionalSharpnessDefault <= kCasAdditionalSharpnessMax); + + // EASU (as well as CAS) is designed for scaling by factors of up to 2x2. + // Some sensible limit for unusual cases, when the game for some reason + // presents a very small back buffer. + // This is enough for 480p > 960p > 1920p > 3840p > 7680p (bigger than 8K, + // or 4320p). + static constexpr uint32_t kFsrMaxUpscalingPassesMax = 4; + + static constexpr float kFsrSharpnessReductionMin = 0.0f; + // "Values above 2.0 won't make a visible difference." + // https://raw.githubusercontent.com/GPUOpen-Effects/FidelityFX-FSR/master/docs/FidelityFX-FSR-Overview-Integration.pdf + static constexpr float kFsrSharpnessReductionMax = 2.0f; + static constexpr float kFsrSharpnessReductionDefault = 0.2f; + static_assert(kFsrSharpnessReductionDefault >= kFsrSharpnessReductionMin && + kFsrSharpnessReductionDefault <= kFsrSharpnessReductionMax); +#endif // defined(REX_HAS_FIDELITYFX_SDK) + + // In the sharpness setters, min / max with a constant as the first argument + // also drops NaNs. + + bool GetAllowOverscanCutoff() const { return allow_overscan_cutoff_; } + void SetAllowOverscanCutoff(bool new_allow_overscan_cutoff) { + allow_overscan_cutoff_ = new_allow_overscan_cutoff; + } + + Effect GetEffect() const { return effect_; } + void SetEffect(Effect new_effect) { effect_ = new_effect; } + +#if defined(REX_HAS_FIDELITYFX_SDK) + float GetCasAdditionalSharpness() const { return cas_additional_sharpness_; } + void SetCasAdditionalSharpness(float new_cas_additional_sharpness) { + cas_additional_sharpness_ = + std::min(kCasAdditionalSharpnessMax, + std::max(kCasAdditionalSharpnessMin, new_cas_additional_sharpness)); + } + + uint32_t GetFsrMaxUpsamplingPasses() const { return fsr_max_upsampling_passes_; } + void SetFsrMaxUpsamplingPasses(uint32_t new_fsr_max_upsampling_passes) { + fsr_max_upsampling_passes_ = + std::min(kFsrMaxUpscalingPassesMax, std::max(uint32_t(1), new_fsr_max_upsampling_passes)); + } + + // In stops. + float GetFsrSharpnessReduction() const { return fsr_sharpness_reduction_; } + void SetFsrSharpnessReduction(float new_fsr_sharpness_reduction) { + fsr_sharpness_reduction_ = + std::min(kFsrSharpnessReductionMax, + std::max(kFsrSharpnessReductionMin, new_fsr_sharpness_reduction)); + } + + FsrQualityMode GetFsrQualityMode() const { return fsr_quality_mode_; } + void SetFsrQualityMode(FsrQualityMode new_fsr_quality_mode) { + fsr_quality_mode_ = new_fsr_quality_mode; + } +#endif // defined(REX_HAS_FIDELITYFX_SDK) + + // Very tiny effect, but highly noticeable, for instance, on the sky in the + // 4D5307E6 main menu (prominently in Custom Games, especially with FSR - + // banding around the clouds can be clearly seen without dithering with 8bpc + // final host output). + bool GetDither() const { return dither_; } + void SetDither(bool new_dither) { dither_ = new_dither; } + + private: + // Tools, rather than the emulator itself, must not allow overscan cutoff + // and must use the kBilinear effect as the image must be as close to the + // original front buffer as possible. + bool allow_overscan_cutoff_ = false; + Effect effect_ = Effect::kBilinear; +#if defined(REX_HAS_FIDELITYFX_SDK) + float cas_additional_sharpness_ = kCasAdditionalSharpnessDefault; + uint32_t fsr_max_upsampling_passes_ = kFsrMaxUpscalingPassesMax; + float fsr_sharpness_reduction_ = kFsrSharpnessReductionDefault; + FsrQualityMode fsr_quality_mode_ = FsrQualityMode::kAuto; +#endif + bool dither_ = false; + }; + + Presenter(const Presenter& presenter) = delete; + Presenter& operator=(const Presenter& presenter) = delete; + virtual ~Presenter(); + + virtual Surface::TypeFlags GetSupportedSurfaceTypes() const = 0; + + // For calling from the Window for the Presenter attached to it. + // May be called from the destructor of the presenter through the window. + void SetWindowSurfaceFromUIThread(Window* new_window, Surface* new_surface); + void OnSurfaceMonitorUpdateFromUIThread(bool old_monitor_potentially_disconnected); + void OnSurfaceResizeFromUIThread(); + + // For calling from the platform paint event handler. Refreshes the surface + // connection if needed, and also paints if possible and if needed (if there + // are no UI overlays, and the guest output is presented directly from the + // thread refreshing it, the paint may be skipped unless there has been an + // explicit request previously or force_paint is true). If painting happens, + // both the guest output and the UI overlays (if any are active) are drawn. + // The background / letterbox of the painted context will be black - windows + // should preferably have a black background before a Presenter is attached to + // them too. + void PaintFromUIThread(bool force_paint = false); + + // Pass 0 as width or height to disable guest output until the next refresh + // with an actual size. The display aspect ratio may be specified like 16:9 or + // like 1280:720, both are accepted, for simplicity, the guest display size + // may just be passed. The callback will receive a backend-specific context, + // and will not be called in case of an error such as the wrong size, or if + // guest output is disabled. Returns whether the callback was called and it + // returned true. The callback must submit all updating work to the host GPU + // before successfully returning, and also signal all the GPU synchronization + // primitives required by the GuestOutputRefreshContext implementation. + bool RefreshGuestOutput(uint32_t frontbuffer_width, uint32_t frontbuffer_height, + uint32_t display_aspect_ratio_x, uint32_t display_aspect_ratio_y, + std::function refresher); + // The implementation must be callable from any thread, including from + // multiple at the same time, and it should acquire the latest guest output + // image via ConsumeGuestOutput. + virtual bool CaptureGuestOutput(RawImage& image_out) = 0; + const GuestOutputPaintConfig& GetGuestOutputPaintConfigFromUIThread() const { + return guest_output_paint_config_; + } + // For simplicity, may be called repeatedly even if no changes have been made. + void SetGuestOutputPaintConfigFromUIThread(const GuestOutputPaintConfig& new_config); + + void AddUIDrawerFromUIThread(UIDrawer* drawer, size_t z_order); + void RemoveUIDrawerFromUIThread(UIDrawer* drawer); + + // Requests (re)painting with the UI if there's UI to draw. + void RequestUIPaintFromUIThread(); + + protected: + enum class PaintResult { + kPresented, + kPresentedSuboptimal, + // Refused for internal reasons or a host API side failure, but still may + // try to present without resetting the graphics provider in the future. + kNotPresented, + kNotPresentedConnectionOutdated, + kGpuLostExternally, + kGpuLostResponsible, + }; + + enum class SurfacePaintConnectResult { + // Redrawing not necessary, nothing changed. Must not be returned for a new + // connection (when was previously disconnected from the surface). + kSuccessUnchanged, + kSuccess, + kFailure, + kFailureSurfaceUnusable, + }; + + static constexpr uint32_t kGuestOutputMailboxSize = 3; + + struct GuestOutputProperties { + // At least any value being 0 here means the guest output is disabled for + // this frame. + uint32_t frontbuffer_width; + uint32_t frontbuffer_height; + // Guest display aspect ratio numerator and denominator (both 16:9 and + // 1280:720 kinds of values are accepted). + uint32_t display_aspect_ratio_x; + uint32_t display_aspect_ratio_y; + bool is_8bpc; + + GuestOutputProperties() { SetToInactive(); } + + bool IsActive() const { + return frontbuffer_width && frontbuffer_height && display_aspect_ratio_x && + display_aspect_ratio_y; + } + + void SetToInactive() { + frontbuffer_width = 0; + frontbuffer_height = 0; + display_aspect_ratio_x = 0; + display_aspect_ratio_y = 0; + is_8bpc = false; + } + }; + + enum class GuestOutputPaintEffect { + kBilinear, + kBilinearDither, +#if defined(REX_HAS_FIDELITYFX_SDK) + kCasSharpen, + kCasSharpenDither, + kCasResample, + kCasResampleDither, + kFsrEasu, + kFsrRcas, + kFsrRcasDither, +#endif + + kCount, + }; + + static constexpr bool CanGuestOutputPaintEffectBeIntermediate(GuestOutputPaintEffect effect) { + switch (effect) { + case GuestOutputPaintEffect::kBilinear: + // Dithering is never performed in intermediate passes because it may be + // interpreted as features by the subsequent passes. + case GuestOutputPaintEffect::kBilinearDither: +#if defined(REX_HAS_FIDELITYFX_SDK) + case GuestOutputPaintEffect::kCasSharpenDither: + case GuestOutputPaintEffect::kCasResampleDither: + case GuestOutputPaintEffect::kFsrRcasDither: +#endif + return false; + default: + // The result of any other effect can be stretched with bilinear + // filtering to the final resolution. + return true; + }; + } + + static constexpr bool CanGuestOutputPaintEffectBeFinal(GuestOutputPaintEffect effect) { + switch (effect) { +#if defined(REX_HAS_FIDELITYFX_SDK) + case GuestOutputPaintEffect::kFsrEasu: + return false; +#endif + default: + return true; + }; + } + +#if defined(REX_HAS_FIDELITYFX_SDK) + // The longest path is kFsrMaxUpscalingPassesMax + optionally RCAS + + // optionally bilinear, when upscaling by more than + // 2^kFsrMaxUpscalingPassesMax along any direction. + // Non-FSR paths are either only bilinear, only CAS, or (when upscaling by + // more than 2 along any direction) CAS followed by bilinear. + static constexpr size_t kMaxGuestOutputPaintEffects = + GuestOutputPaintConfig::kFsrMaxUpscalingPassesMax + 2; +#else + // Bilinear-only path: at most 1 effect. + static constexpr size_t kMaxGuestOutputPaintEffects = 1; +#endif + + struct GuestOutputPaintFlow { + // Letterbox on up to 4 sides. + static constexpr size_t kMaxClearRectangles = 4; + + struct ClearRectangle { + uint32_t x; + uint32_t y; + uint32_t width; + uint32_t height; + }; + + GuestOutputProperties properties; + + // If 0, don't display the guest output. + size_t effect_count; + std::array effects; + std::array, kMaxGuestOutputPaintEffects> effect_output_sizes; + + // Offset of the rectangle for final drawing to the host window with + // letterboxing. + int32_t output_x; + int32_t output_y; + + // If there is guest output (effect_count is not 0), contains the letterbox + // rectangles around the guest output. + size_t letterbox_clear_rectangle_count; + std::array letterbox_clear_rectangles; + + void GetEffectInputSize(size_t effect_index, uint32_t& width_out, uint32_t& height_out) const { + assert_true(effect_index < effect_count); + if (!effect_index) { + width_out = properties.frontbuffer_width; + height_out = properties.frontbuffer_height; + return; + } + const std::pair& intermediate_size = + effect_output_sizes[effect_index - 1]; + width_out = intermediate_size.first; + height_out = intermediate_size.second; + } + + void GetEffectOutputOffset(size_t effect_index, int32_t& x_out, int32_t& y_out) const { + assert_true(effect_index < effect_count); + if (effect_index + 1 < effect_count) { + x_out = 0; + y_out = 0; + return; + } + x_out = output_x; + y_out = output_y; + } + }; + + struct BilinearConstants { + int32_t output_offset[2]; + float output_size_inv[2]; + + void Initialize(const GuestOutputPaintFlow& flow, size_t effect_index) { + flow.GetEffectOutputOffset(effect_index, output_offset[0], output_offset[1]); + const std::pair& output_size = flow.effect_output_sizes[effect_index]; + output_size_inv[0] = 1.0f / float(output_size.first); + output_size_inv[1] = 1.0f / float(output_size.second); + } + }; + +#if defined(REX_HAS_FIDELITYFX_SDK) + static constexpr float CalculateCasPostSetupSharpness(float sharpness) { + // CasSetup const1.x. + return -1.0f / (8.0f - 3.0f * sharpness); + } + + struct CasSharpenConstants { + int32_t output_offset[2]; + float sharpness_post_setup; + + void Initialize(const GuestOutputPaintFlow& flow, size_t effect_index, + const GuestOutputPaintConfig& config) { + flow.GetEffectOutputOffset(effect_index, output_offset[0], output_offset[1]); + sharpness_post_setup = CalculateCasPostSetupSharpness(config.GetCasAdditionalSharpness()); + } + }; + + struct CasResampleConstants { + int32_t output_offset[2]; + // Input size / output size. + float input_output_size_ratio[2]; + float sharpness_post_setup; + + void Initialize(const GuestOutputPaintFlow& flow, size_t effect_index, + const GuestOutputPaintConfig& config) { + flow.GetEffectOutputOffset(effect_index, output_offset[0], output_offset[1]); + uint32_t input_width, input_height; + flow.GetEffectInputSize(effect_index, input_width, input_height); + const std::pair& output_size = flow.effect_output_sizes[effect_index]; + input_output_size_ratio[0] = float(input_width) / float(output_size.first); + input_output_size_ratio[1] = float(input_height) / float(output_size.second); + sharpness_post_setup = CalculateCasPostSetupSharpness(config.GetCasAdditionalSharpness()); + } + }; + + struct FsrEasuConstants { + // No output offset because the EASU pass is always done to an intermediate + // framebuffer. + float input_output_size_ratio[2]; + float input_size_inv[2]; + + void Initialize(const GuestOutputPaintFlow& flow, size_t effect_index) { + uint32_t input_width, input_height; + flow.GetEffectInputSize(effect_index, input_width, input_height); + const std::pair& output_size = flow.effect_output_sizes[effect_index]; + input_output_size_ratio[0] = float(input_width) / float(output_size.first); + input_output_size_ratio[1] = float(input_height) / float(output_size.second); + input_size_inv[0] = 1.0f / float(input_width); + input_size_inv[1] = 1.0f / float(input_height); + } + }; + + struct FsrRcasConstants { + int32_t output_offset[2]; + float sharpness_post_setup; + + static float CalculatePostSetupSharpness(float sharpness_reduction_stops) { + // FsrRcasCon const0.x. + return std::exp2f(-sharpness_reduction_stops); + } + + void Initialize(const GuestOutputPaintFlow& flow, size_t effect_index, + const GuestOutputPaintConfig& config) { + flow.GetEffectOutputOffset(effect_index, output_offset[0], output_offset[1]); + sharpness_post_setup = CalculatePostSetupSharpness(config.GetFsrSharpnessReduction()); + } + }; +#endif // defined(REX_HAS_FIDELITYFX_SDK) + + explicit Presenter(HostGpuLossCallback host_gpu_loss_callback) + : host_gpu_loss_callback_(host_gpu_loss_callback) {} + + // Must be called by the implementation's initialization, before the presenter + // is used for anything. + bool InitializeCommonSurfaceIndependent(); + + // ConnectOrReconnect and Disconnect are callable only by the UI thread and + // only when it has access to painting (PaintMode is not + // kGuestOutputThreadImmediately). + // Called only for a non-zero-area surface potentially supporting painting via + // the presenter. In case of a failure, internally no resources referencing + // the surface must be held by the implementation anymore - the implementation + // must be left in the same state as after + // DisconnectPaintingFromSurfaceFromUIThreadImpl. If the call is successful, + // the implementation must write to is_vsync_implicit_out whether the + // connection will now have vertical sync forced by the host window system, + // which may cause undesirable waits on the CPU when beginning or ending + // frames. + virtual SurfacePaintConnectResult ConnectOrReconnectPaintingToSurfaceFromUIThread( + Surface& new_surface, uint32_t new_surface_width, uint32_t new_surface_height, + bool was_paintable, bool& is_vsync_implicit_out) = 0; + // Releases resources referencing the surface in the implementation if they + // are held by it. Call through DisconnectPaintingFromSurfaceFromUIThread to + // ensure the implementation is only called while the connection is active. + virtual void DisconnectPaintingFromSurfaceFromUIThreadImpl() = 0; + + // The returned lock interlocks multiple consumers (but not the producer and + // the consumer) and must be held while accessing implementation-specific + // objects that depend on the image or its index in the mailbox (unless there + // are other locking mechanisms involved for the resources, such as reference + // counting for the guest output images, which doesn't have to be atomic + // though for the reason described later in this paragraph, or assumptions + // like of main target painting being possible only in at most one thread at + // once). While this lock is held, the currently acquired image index can't be + // changed (by other consumers advancing the acquired image index to the new + // ready image index), so the image with the index given by this function + // can't be released and be made writable or given to a different consumer + // (thus it's owned exclusively by the consumer who has called this function). + // The properties are returned by copy rather than returning a pointer to them + // or asking the consumer to pull them for the current mailbox index, so there + // are less things to take into consideration while leaving the guest output + // consumer critical section earlier (as if a pointer was returned, the data + // behind it could be overwritten at any time after leaving the consumer + // critical section) if the implementation has its own synchronization + // mechanisms that allow for doing so as described earlier. Returns UINT32_MAX + // as the mailbox index if the image is inactive (if it's active, it has + // proper properties though). + [[nodiscard]] std::unique_lock ConsumeGuestOutput( + uint32_t& mailbox_index_or_max_if_inactive_out, GuestOutputProperties* properties_out, + GuestOutputPaintConfig* paint_config_out); + // The properties are passed explicitly, not taken from the current acquired + // image, so it can be called for a copy of the acquired image's properties + // outside the consumer lock if the implementation has its own synchronization + // (like reference counting for the guest output images) that makes it + // possible to leave the consumer critical section earlier. Also, the guest + // output paint configuration is passed explicitly too so calling this + // function multiple times is safer. + GuestOutputPaintFlow GetGuestOutputPaintFlow(const GuestOutputProperties& properties, + uint32_t host_rt_width, uint32_t host_rt_height, + uint32_t max_rt_width, uint32_t max_rt_height, + const GuestOutputPaintConfig& config) const; + // is_8bpc_out_ref is where to write whether the source actually has no more + // than 8 bits of precision per channel (though the image provided by the + // refresher may still have a higher storage precision) - if not written, it + // will be assumed to be false. + virtual bool RefreshGuestOutputImpl( + uint32_t mailbox_index, uint32_t frontbuffer_width, uint32_t frontbuffer_height, + std::function refresher, bool& is_8bpc_out_ref) = 0; + + // For guest output capturing (for debugging use thus - shouldn't be adding + // any noise like dithering that's not present in the original image), + // converting a 10bpc RGB pixel to 8bpc that can be stored in common image + // formats. + static uint32_t Packed10bpcRGBTo8bpcBytes(uint32_t rgb10) { + // Conversion almost according to the Direct3D 10+ rules (unorm > float > + // unorm), but with one multiplication rather than separate division and + // multiplication - the results are the same for unorm10 to unorm8. + if constexpr (std::endian::native == std::endian::big) { + return (uint32_t(float(rgb10 & 0x3FF) * (255.0f / 1023.0f) + 0.5f) << 24) | + (uint32_t(float((rgb10 >> 10) & 0x3FF) * (255.0f / 1023.0f) + 0.5f) << 16) | + (uint32_t(float((rgb10 >> 20) & 0x3FF) * (255.0f / 1023.0f) + 0.5f) << 8) | + uint32_t(0xFF); + } + return uint32_t(float(rgb10 & 0x3FF) * (255.0f / 1023.0f) + 0.5f) | + (uint32_t(float((rgb10 >> 10) & 0x3FF) * (255.0f / 1023.0f) + 0.5f) << 8) | + (uint32_t(float((rgb10 >> 20) & 0x3FF) * (255.0f / 1023.0f) + 0.5f) << 16) | + (uint32_t(0xFF) << 24); + } + + // Paints and presents the guest output if available (or just solid black + // color), and if requested, the UI on top of it. + // + // May be called from the non-UI thread, but only to paint the guest output + // (no UI drawing, with execute_ui_drawers disabled). + // + // Call via PaintAndPresent. + virtual PaintResult PaintAndPresentImpl(bool execute_ui_drawers) = 0; + + // For calling from the painting implementations if requested. + void ExecuteUIDrawersFromUIThread(UIDrawContext& ui_draw_context); + + private: + enum class PaintMode { + // Don't paint at all. + // Painting lifecycle is accessible only by the UI thread. + // window_->RequestPaint() must not be called in this mode at all regardless + // of whether the Window object exists because the Window object in this + // case may correspond to a window without a paintable Surface (in a closed + // state, or in the middle of a surface change), and non-UI threads (such as + // the guest output thread) may result in a race condition internally inside + // Window::RequestPaint during the access to the Window's state, such as the + // availability of the Surface that can handle the paint (therefore, if + // there's no Surface, this is the only valid mode). + kNone, + // Guest output refreshing notifies the `window_`, which must be valid and + // safe to call RequestPaint for, that painting should be done in the UI + // thread (including the UI if needed). Painting is possible, and painting + // lifecycle is accessible, only by the UI thread. + kUIThreadOnRequest, + // Paint immediately in the guest output thread for lower latency. The + // `window_`, however, may be notified that the surface painting connection + // has become outdated (via RequestPaint, as in this case the UI thread will + // need to repaint as sooner as possible after reconnecting anyway), and + // change the surface connection state accordingly (only to + // kConnectedOutdated). + // Painting is possible only by the guest output thread, lifecycle + // management cannot be done from the UI thread until it takes over. + kGuestOutputThreadImmediately, + }; + + enum class SurfacePaintConnectionState { + // No surface at all, or couldn't connect with the current state of the + // surface (such as because the surface was zero-sized because the window + // was minimized, for example). Or, the connection has become outdated, and + // the attempt to reconnect at kRetryConnectingSoon has failed. Try to + // reconnect if anything changes in the state of the surface, such as its + // size. + kUnconnectedRetryAtStateChange, + // Can't connect to the current existing surface (the surface has been lost + // or it's completely incompatible). No point in retrying connecting until + // the surface is replaced. + kUnconnectedSurfaceReportedUnusable, + // Everything is fine, can paint. The connection might have become + // suboptimal though, and haven't tried refreshing yet, but still usable for + // painting nonetheless. + kConnectedPaintable, + // The implementation still holds resources associated with the connection, + // but presentation has reported that it has become outdated, try + // reconnecting as soon as possible (at the next paint attempt, requesting + // it if needed). This is the only state that the guest output thread may + // transition the connection to (from kConnectedPaintable only) if it has + // access to painting (the paint mode is kGuestOutputThreadImmediately). + kConnectedOutdated, + }; + + static constexpr bool IsConnectedSurfacePaintConnectionState( + SurfacePaintConnectionState connection_state) { + return connection_state == SurfacePaintConnectionState::kConnectedPaintable || + connection_state == SurfacePaintConnectionState::kConnectedOutdated; + } + + struct UIDrawerReference { + UIDrawer* drawer; + uint64_t last_draw; + + explicit UIDrawerReference(UIDrawer* drawer, uint64_t last_draw = UINT64_MAX) + : drawer(drawer), last_draw(last_draw) {} + }; + + void SetPaintModeFromUIThread(PaintMode new_mode); + // Based on conditions like whether UI needs to be drawn and whether vertical + // sync is implicit - see the implementation for the requirements. + // is_paintable is an explicit parameter because this function may be called + // in two scenarios: + // - After connection updates - painting connection is owned by the UI thread, + // so the actual state can be obtained and passed here so kNone can be + // returned. + // - When merely toggling something local to the UI thread - only to toggle + // between the two threads, but not to switch from or to kNone (make sure + // it's not kNone before calling), pass `true` in this case. + PaintMode GetDesiredPaintModeFromUIThread(bool is_paintable) const; + + // Callable only by the UI thread and only when it has access to painting + // (PaintMode is not kGuestOutputThreadImmediately). + // This can be called to a surface after having not been connected to any (in + // this case, surface_paint_connection_state_ must be + // kUnconnectedRetryAtStateChange, not kUnconnectedNoUsableSurface, otherwise + // the call will be dropped), or to handle surface state changes such as + // resizing. However, this must not be called to change directly from one + // surface to another - need to disconnect prior to that, because the + // implementation may assume that the surface is still the same, and may try + // to, for instance, resize the buffers for the existing surface. + void UpdateSurfacePaintConnectionFromUIThread(bool* repaint_needed_out, + bool update_paint_mode_to_desired); + // Callable only by the UI thread and only when it has access to painting + // (PaintMode is not kGuestOutputThreadImmediately). + // See DisconnectPaintingFromSurfaceFromUIThreadImpl for more information. + void DisconnectPaintingFromSurfaceFromUIThread(SurfacePaintConnectionState new_state); + + // Can be called from any thread if an existing window_ safe to RequestPaint + // (not closed) is available in it, so doesn't check the surface painting + // connection state. Returns whether the window_->RequestPaint() call has been + // made. + bool RequestPaintOrConnectionRecoveryViaWindow(bool force_ui_thread_paint_tick); + + // Platform-specific function refreshing the monitor the current window + // surface is on, through the Surface or its Window. A reference to the + // monitor is held only when a Surface is available, so it's automatically + // dropped when the Window loses its Surface when it's being closed (but the + // Window object keeps being attached to the Presenter), for instance. + void UpdateSurfaceMonitorFromUIThread(bool old_monitor_potentially_disconnected); + // Platform-specific function returning whether the surface the presenter is + // currently attached it is actually visible on any monitor. UI thread + // painting may be dropped if this returns false - need to request painting if + // the surface appears on a monitor again. May be using the state cached at + // window / surface state changes, not the actual state from the platform. + bool InSurfaceOnMonitorFromUIThread() const; + + // Calls PaintAndPresentImpl and does post-paint checks that are safe to do on + // both the UI thread and the guest output thread. See the information about + // PaintAndPresentImpl for details. + // A kPresentedSuboptimal result is returned as is, but the connection may or + // may not be made outdated if that happens - though if it's + // kPresentedSuboptimal rather than kNotPresentedConnectionOutdated, the image + // has been successfully sent to the OS presentation at least. + PaintResult PaintAndPresent(bool execute_ui_drawers); + + void HandleUIDrawersChangeFromUIThread(bool drawers_were_empty); + + bool AreUITicksNeededFromUIThread() const { + // UI drawing should be done, and painting needs to be possible (coarsely + // checking because the actual connection state, including outdated, may be + // currently unavailable from the UI thread). + // There's no need to limit the frame rate manually if there is vertical + // sync in the presentation already as that might result in inconsistent + // frame pacing and potentially skipped vertical sync intervals. + return !ui_drawers_.empty() && paint_mode_ != PaintMode::kNone && + !surface_paint_connection_has_implicit_vsync_; + } + void UpdateUITicksNeededFromUIThread(); + void WaitForUITickFromUIThread(); + // May be called from any thread. + void ForceUIThreadPaintTick(); + + // Must be called only in the end of entry points - reinitialization of the + // presenter may be done by the handler if it was called from the UI thread + // (even if the UI thread argument is false - such as when the guest output is + // refreshed on the UI thread). + HostGpuLossCallback host_gpu_loss_callback_; + + // May be accessed by the guest output thread if the paint mode is not kNone, + // to request painting (for kUIThreadOnRequest) or reconnection (for + // kGuestOutputThreadImmediately) in the UI thread. Set the paint mode to + // kNone before modifying (that naturally has to be done anyway by + // disconnecting painting). + Window* window_ = nullptr; + + // The surface of the `window_` the presenter is currently attached to. + Surface* surface_ = nullptr; + + // Mutex protecting paint_mode_ (and, in the guest output thread, objects + // related to painting themselves). + // + // The UI thread (as the mode is modifiable only by it) can use it as + // "barriers", like: + // 1) If needed, lock and disable guest output thread access to painting. + // 2) Interact with the painting connection. + // 3) If needed, lock and re-enable guest output thread access to the + // painting. + // + // On the other hand, the guest output thread _must_ hold it all the time it's + // painting, to ensure the mode stays the same while it's painting. + std::mutex paint_mode_mutex_; + // UI thread: writable, guest output thread: read-only. + PaintMode paint_mode_ = PaintMode::kNone; + + // These fields can be accessed _exclusively_ by either the UI thread or the + // guest output thread, depending on paint_mode_. + // If it's kGuestOutputThreadImmediately, they can be accessed _only_ by the + // guest output thread (though the UI thread can still read, but not modify, + // fields that are writable by the UI thread and readadable by both). + // Otherwise, they can be accessed _only_ by the UI thread. + // The connection state may be changed from the guest output thread, but only + // from kConnectedPaintable to kConnectedOutdated. + SurfacePaintConnectionState surface_paint_connection_state_ = + SurfacePaintConnectionState::kUnconnectedRetryAtStateChange; + // If the surface connection was optimal at the last paint attempt, but now + // has become suboptimal, need to try to reconnect. But only in this case - if + // the connection has been suboptimal from the very beginning don't try to + // reconnect every frame. + bool surface_paint_connection_was_optimal_at_successful_paint_ = false; + + // Modifiable only by the UI thread (therefore can be accessed by the UI + // thread regardless of the paint mode) while (re)connecting painting to the + // surface. + bool surface_paint_connection_has_implicit_vsync_ = false; + // Modifiable only by the UI thread, can be read by the thread that's + // painting. + uint32_t surface_width_in_paint_connection_ = 0; + uint32_t surface_height_in_paint_connection_ = 0; + + // Can be set by both the UI thread and the guest output thread before doing + // window_->RequestPaint() - whether an extra painting (preceded by + // reconnection if needed, and painting) was requested, primarily after some + // state change that may effect the surface painting connection, resulting in + // the need to refresh it as soon as possible. + // + // Relaxed memory order is enough, everything that may influence painting is + // either local to the UI thread or protected with barriers elsewhere. + // + // There's no need to bother about resetting this variable when losing + // connection as the next successful reconnection should be followed by a + // repaint request anyway. + std::atomic ui_thread_paint_requested_{false}; + + std::mutex guest_output_paint_config_mutex_; + // UI thread: writable, guest output thread: read-only. + GuestOutputPaintConfig guest_output_paint_config_; + + // Single-producer-multiple-consumers (lock-free SPSC + consumer lock) mailbox + // for presenting of the most up-to-date guest output image without long + // interlocking between guest output refreshing and painting. + static_assert(kGuestOutputMailboxSize == 3); + // The "acquired" image (in bits 0:1) is the one that is currently being read, + // or was last read, by a consumer of the guest output. The index of it can be + // modified only by the consumer and stays the same while it's processing the + // image. + // The "ready" image (in bits 2:3) is the most up-to-date image that the + // refresher has completely written, and a consumer may acquire it. It may be + // == acquired if there has been no refresh since the last acquisition. + // These two images can be accessed by painting in parallel, in an unordered + // way, with guest output refreshing. + std::atomic guest_output_mailbox_acquired_and_ready_{0}; + // The "writable" image is different than both "acquired" and "ready" and is + // accessible only by the guest output refreshing - it's the image that the + // refresher may write to. + uint32_t guest_output_mailbox_writable_ = 1; + // The guest output images may be consumed by two operations - painting, and + // capturing to a CPU-side buffer. These two usually never happen in parallel + // in reality though, as they're usually not even needed both at once in the + // same app within Xenia, so there's no need to create any + // complex lock-free synchronization between the two, but still, the situation + // when multiple consumers want the guest output image at the same is + // perfectly valid (unlike for producers, because even with a producer lock + // that would still be a race condition since the two refreshes themselves + // will be done in an undefined order) - so, a sufficient synchronization + // mechanism is used to make sure multiple consumers can acquire images + // without interfering with each other. + // While this is held, paint_mode_mutex_ must not be locked (the lock order is + // the reverse when painting in the guest output thread - painting is done + // with paint_mode_mutex_ held in this case, and guest output consumption + // happens as part of painting. + std::mutex guest_output_mailbox_consumer_mutex_; + + std::array guest_output_properties_; + // Accessible only by refreshing, whether the last refresh contained an image + // rather than being blank. + bool guest_output_active_last_refresh_ = false; + + // Ordered by the Z order, and then by the time of addition. + // Note: All the iteration logic involving this Z ordering must be the same as + // in input handling (in the input listeners in the Window), but in reverse. + std::multimap ui_drawers_; + + size_t ui_draw_current_ = 0; + size_t ui_draw_current_z_order_; + std::multimap::iterator ui_draw_next_iterator_; + bool is_executing_ui_drawers_ = false; + + // Whether currently running the logic of PaintFromUIThread, so certain + // actions (such as changing the paint mode, requesting a redraw) must be + // deferred and be handled by the tail of PaintFromUIThread for consistency + // with what PaintFromUIThread does internally. + bool is_in_ui_thread_paint_ = false; + bool request_guest_output_paint_after_current_ui_thread_paint_; + bool request_ui_paint_after_current_ui_thread_paint_; + + // Platform-specific, but implementation-agnostic parts, primarily for + // limiting of the frame rate of the UI to avoid drawing the UI at extreme + // frame rates wasting the CPU and the GPU resources and starving everything + // else. The waits performed here must be interruptible by guest output + // presentation requests to prevent adding arbitrary amounts of latency to it. + // On Android and GTK, this is not needed, the frame rate of draw events is + // limited to the display refresh rate internally. +#if REX_PLATFORM_WIN32 + static Microsoft::WRL::ComPtr GetDXGIOutputForMonitor(IDXGIFactory1* factory, + HMONITOR monitor); + bool AreDXGIUITicksWaitable( + [[maybe_unused]] const std::unique_lock& dxgi_ui_tick_lock) { + return dxgi_ui_ticks_needed_ && !dxgi_ui_tick_thread_shutdown_ && dxgi_ui_tick_output_; + } + void DXGIUITickThread(); + + // Accessible only from the UI thread, to avoid updating monitor-dependent + // information such as the DXGI output if the monitor hasn't actually been + // changed in the current state change (such as window positioning changes). + HMONITOR surface_win32_monitor_ = nullptr; + + // Requiring the lowest version of DXGI for IDXGIOutput::WaitForVBlank, which + // is available even on Windows Vista, but for IDXGIFactory1::IsCurrent, + // DXGI 1.1 is needed (available starting from Windows 7; also mixing DXGI 1.0 + // and 1.1+ in the Direct3D 12 code is not supported, see CreateDXGIFactory on + // MSDN). The factory is created when it's needed, and may be released and + // recreated when it's not current anymore and that becomes relevant. + Microsoft::WRL::ComPtr dxgi_ui_tick_factory_; + + // Accessible only from the UI thread, though the value is taken from the + // tick-mutex-protected variable. + uint64_t dxgi_ui_tick_last_draw_ = 0; + + std::mutex dxgi_ui_tick_mutex_; + uint64_t dxgi_ui_tick_last_vblank_ = 1; + // If output is null or shutdown is true, the signal may not be sent, either + // don't limit the frame rate in this case (an exceptional situation, such as + // a failure to find the output in DXGI), or don't draw at all if the window + // was removed from a connected monitor. + Microsoft::WRL::ComPtr dxgi_ui_tick_output_; + // To avoid allocating processing resources to the thread when nothing needs + // the ticks (not drawing the UI), the thread waits for vertical blanking + // intervals only when the UI drawing ticks are needed, and sleeping waiting + // for the control condition variable signals otherwise. Modifiable only from + // the UI thread, so readable by it without locking the mutex. + bool dxgi_ui_ticks_needed_ = false; + // The shutdown flag is modifiable only from the UI thread. + bool dxgi_ui_tick_thread_shutdown_ = false; + bool dxgi_ui_tick_force_requested_ = false; + + std::condition_variable dxgi_ui_tick_control_condition_; + // May be signaled by guest output refreshing. + std::condition_variable dxgi_ui_tick_signal_condition_; + + std::thread dxgi_ui_tick_thread_; +#endif // XE_PLATFORM +}; + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/renderdoc_api.h b/include/rex/ui/renderdoc_api.h new file mode 100644 index 0000000..04262f2 --- /dev/null +++ b/include/rex/ui/renderdoc_api.h @@ -0,0 +1,43 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include + +#include + +namespace rex { +namespace ui { + +class RenderDocAPI { + public: + static std::unique_ptr CreateIfConnected(); + + RenderDocAPI(const RenderDocAPI&) = delete; + RenderDocAPI& operator=(const RenderDocAPI&) = delete; + + ~RenderDocAPI(); + + // Always present if this object exists. + const RENDERDOC_API_1_0_0* api_1_0_0() const { return api_1_0_0_; } + + private: + explicit RenderDocAPI() = default; + + rex::platform::DynamicLibrary library_; + + const RENDERDOC_API_1_0_0* api_1_0_0_ = nullptr; +}; + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/surface.h b/include/rex/ui/surface.h new file mode 100644 index 0000000..34e1d65 --- /dev/null +++ b/include/rex/ui/surface.h @@ -0,0 +1,80 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include + +namespace rex { +namespace ui { + +// Represents a surface that presenting can be performed to. +// Surface methods can be called only from the UI thread. + +class Surface { + public: + enum TypeIndex { + // Within one platform, the more preferable surface types are earlier in + // this enumeration, so rex::bit_scan_forward can be used to try creating + // surfaces of all types supported by both the graphics provider and the + // window. + // Android. + kTypeIndex_AndroidNativeWindow, + // GNU/Linux. + kTypeIndex_XcbWindow, + // Windows. + kTypeIndex_Win32Hwnd, + }; + using TypeFlags = uint32_t; + enum : TypeFlags { + kTypeFlag_AndroidNativeWindow = TypeFlags(1) << kTypeIndex_AndroidNativeWindow, + kTypeFlag_XcbWindow = TypeFlags(1) << kTypeIndex_XcbWindow, + kTypeFlag_Win32Hwnd = TypeFlags(1) << kTypeIndex_Win32Hwnd, + }; + + Surface(const Surface& surface) = delete; + Surface& operator=(const Surface& surface) = delete; + virtual ~Surface() = default; + + virtual TypeIndex GetType() const = 0; + + // Returns the up-to-date size (and true), or zeros (and false) if not ready + // to open a presentation connection yet. The size preferably should be + // exactly the dimensions of the surface in physical pixels of the display + // (without stretching performed by the platform's composition), but even if + // stretching happens, it is required that surface pixels have 1:1 aspect + // ratio relatively to the physical display. + bool GetSize(uint32_t& width_out, uint32_t& height_out) { + // If any dimension is 0 (like, resized completely to zero in one direction, + // but not in another), the surface is zero-area - don't try to present to + // it. + uint32_t width, height; + if (!GetSizeImpl(width, height) || !width || !height) { + width_out = 0; + height_out = 0; + return false; + } + width_out = width; + height_out = height; + return true; + } + + protected: + Surface() = default; + + // Returns the up-to-date size in physical pixels (and true), or zeros (and + // optionally false) if not ready to open a presentation connection yet. + virtual bool GetSizeImpl(uint32_t& width_out, uint32_t& height_out) const = 0; +}; + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/surface_gnulinux.h b/include/rex/ui/surface_gnulinux.h new file mode 100644 index 0000000..668993c --- /dev/null +++ b/include/rex/ui/surface_gnulinux.h @@ -0,0 +1,37 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include + +namespace rex { +namespace ui { + +class XcbWindowSurface final : public Surface { + public: + explicit XcbWindowSurface(xcb_connection_t* connection, xcb_window_t window) + : connection_(connection), window_(window) {} + TypeIndex GetType() const override { return kTypeIndex_XcbWindow; } + xcb_connection_t* connection() const { return connection_; } + xcb_window_t window() const { return window_; } + + protected: + bool GetSizeImpl(uint32_t& width_out, uint32_t& height_out) const override; + + private: + xcb_connection_t* connection_; + xcb_window_t window_; +}; + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/surface_win.h b/include/rex/ui/surface_win.h new file mode 100644 index 0000000..51bb534 --- /dev/null +++ b/include/rex/ui/surface_win.h @@ -0,0 +1,47 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include + +namespace rex { +namespace ui { + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_GAMES) +class Win32HwndSurface final : public Surface { + public: + explicit Win32HwndSurface(HINSTANCE hinstance, HWND hwnd) : hinstance_(hinstance), hwnd_(hwnd) {} + TypeIndex GetType() const override { return kTypeIndex_Win32Hwnd; } + HINSTANCE hinstance() const { return hinstance_; } + HWND hwnd() const { return hwnd_; } + + protected: + bool GetSizeImpl(uint32_t& width_out, uint32_t& height_out) const override; + + private: + HINSTANCE hinstance_; + HWND hwnd_; +}; +#endif + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/ui_drawer.h b/include/rex/ui/ui_drawer.h new file mode 100644 index 0000000..4006af6 --- /dev/null +++ b/include/rex/ui/ui_drawer.h @@ -0,0 +1,36 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +namespace rex { +namespace ui { + +class UIDrawContext; + +class UIDrawer { + public: + // No preparation or finishing callbacks because drawers may register or + // unregister each other, so between the loops the list may be different. + + // The draw function may register or unregister drawers (and depending on the + // Z order the changes may or may not effect immediately). However, they must + // not perform any lifetime management of the presenter and of its connection + // to the surface. Ideally drawing should not be changing any state at all, + // however, in Dear ImGui, input is handled directly during drawing - any + // quitting or resizing, if done in the UI, must be deferred via something + // like WindowedAppContext::CallInUIThreadDeferred. + virtual void Draw(UIDrawContext& context) = 0; +}; + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/ui_event.h b/include/rex/ui/ui_event.h new file mode 100644 index 0000000..99dea21 --- /dev/null +++ b/include/rex/ui/ui_event.h @@ -0,0 +1,188 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include + +namespace rex { +namespace ui { + +class Window; + +class UIEvent { + public: + explicit UIEvent(Window* target = nullptr) : target_(target) {} + virtual ~UIEvent() = default; + + Window* target() const { return target_; } + + private: + Window* target_; +}; + +class UISetupEvent : public UIEvent { + public: + explicit UISetupEvent(Window* target = nullptr, bool is_initial_setup = false) + : UIEvent(target), is_initial_setup_(is_initial_setup) {} + + bool is_initial_setup() const { return is_initial_setup_; } + + private: + bool is_initial_setup_; +}; + +class MonitorUpdateEvent : public UISetupEvent { + public: + explicit MonitorUpdateEvent(Window* target, bool old_monitor_potentially_disconnected, + bool is_initial_setup = false) + : UISetupEvent(target, is_initial_setup), + old_monitor_potentially_disconnected_(old_monitor_potentially_disconnected) {} + + bool old_monitor_potentially_disconnected() const { + return old_monitor_potentially_disconnected_; + } + + private: + bool old_monitor_potentially_disconnected_; +}; + +class FileDropEvent : public UIEvent { + public: + explicit FileDropEvent(Window* target, std::filesystem::path filename) + : UIEvent(target), filename_(std::move(filename)) {} + ~FileDropEvent() override = default; + + const std::filesystem::path& filename() const { return filename_; } + + private: + const std::filesystem::path filename_; +}; + +class KeyEvent : public UIEvent { + public: + explicit KeyEvent(Window* target, VirtualKey virtual_key, int repeat_count, bool prev_state, + bool modifier_shift_pressed, bool modifier_ctrl_pressed, + bool modifier_alt_pressed, bool modifier_super_pressed) + : UIEvent(target), + virtual_key_(virtual_key), + repeat_count_(repeat_count), + prev_state_(prev_state), + modifier_shift_pressed_(modifier_shift_pressed), + modifier_ctrl_pressed_(modifier_ctrl_pressed), + modifier_alt_pressed_(modifier_alt_pressed), + modifier_super_pressed_(modifier_super_pressed) {} + ~KeyEvent() override = default; + + bool is_handled() const { return handled_; } + void set_handled(bool value) { handled_ = value; } + + VirtualKey virtual_key() const { return virtual_key_; } + + int repeat_count() const { return repeat_count_; } + bool prev_state() const { return prev_state_; } + + bool is_shift_pressed() const { return modifier_shift_pressed_; } + bool is_ctrl_pressed() const { return modifier_ctrl_pressed_; } + bool is_alt_pressed() const { return modifier_alt_pressed_; } + bool is_super_pressed() const { return modifier_super_pressed_; } + + private: + bool handled_ = false; + VirtualKey virtual_key_ = VirtualKey::kNone; + + int repeat_count_ = 0; + bool prev_state_ = false; // Key previously down(true) or up(false) + + bool modifier_shift_pressed_ = false; + bool modifier_ctrl_pressed_ = false; + bool modifier_alt_pressed_ = false; + bool modifier_super_pressed_ = false; +}; + +class MouseEvent : public UIEvent { + public: + enum class Button { + kNone = 0, + kLeft, + kRight, + kMiddle, + kX1, + kX2, + }; + + public: + // Matching Windows WHEEL_DELTA. + static constexpr uint32_t kScrollPerDetent = 120; + + explicit MouseEvent(Window* target, Button button, int32_t x, int32_t y, int32_t scroll_x = 0, + int32_t scroll_y = 0) + : UIEvent(target), button_(button), x_(x), y_(y), scroll_x_(scroll_x), scroll_y_(scroll_y) {} + ~MouseEvent() override = default; + + bool is_handled() const { return handled_; } + void set_handled(bool value) { handled_ = value; } + + Button button() const { return button_; } + int32_t x() const { return x_; } + int32_t y() const { return y_; } + int32_t scroll_x() const { return scroll_x_; } + int32_t scroll_y() const { return scroll_y_; } + + private: + bool handled_ = false; + Button button_; + int32_t x_ = 0; + int32_t y_ = 0; + int32_t scroll_x_ = 0; + // Positive is up (away from the user), negative is down (towards the user). + int32_t scroll_y_ = 0; +}; + +class TouchEvent : public UIEvent { + public: + enum class Action { + kDown, + kUp, + // Should be treated as an up event, but without performing the usual action + // for releasing. + kCancel, + kMove, + }; + + // Can be used by event listeners as the value for when there's no current + // pointer, for example. + static constexpr uint32_t kPointerIDNone = UINT32_MAX; + + explicit TouchEvent(Window* target, uint32_t pointer_id, Action action, float x, float y) + : UIEvent(target), pointer_id_(pointer_id), action_(action), x_(x), y_(y) {} + + bool is_handled() const { return handled_; } + void set_handled(bool value) { handled_ = value; } + + uint32_t pointer_id() { return pointer_id_; } + Action action() const { return action_; } + // Can be outside the boundaries of the surface. + float x() const { return x_; } + float y() const { return y_; } + + private: + bool handled_ = false; + uint32_t pointer_id_; + Action action_; + float x_; + float y_; +}; + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/virtual_key.h b/include/rex/ui/virtual_key.h new file mode 100644 index 0000000..3e1b948 --- /dev/null +++ b/include/rex/ui/virtual_key.h @@ -0,0 +1,360 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +namespace rex { +namespace ui { + +// Windows and Xbox 360 / XInput virtual key enumeration. +// This is what platform-specific keys should be translated to, for both HID +// keystroke emulation and Xenia-internal UI events. On Windows, the translation +// is a simple cast. +// This is uint16_t as it's WPARAM (which was 16-bit back in Win16 days, where +// virtual key codes were added), and XINPUT_KEYSTROKE stores the virtual key as +// a WORD. In some cases (see kPacket), bits above 16 may be used as well, but +// VK_ on Windows are defined up to 0xFF (0xFE not counting the reserved 0xFF) +// as of Windows SDK 10.0.19041.0, and XInput virtual key codes are 16-bit. +// Base virtual key codes as of _WIN32_WINNT 0x0500 (Windows 2000, which the +// Xbox 360's kernel is based on), virtual key codes added later are marked +// explicitly as such. +enum class VirtualKey : uint16_t { + // Not a valid key - MapVirtualKey returns zero when there is no translation. + kNone, + + kLButton = 0x01, + kRButton = 0x02, + kCancel = 0x03, // Control-break. + kMButton = 0x04, // Not contiguous with kLButton and kRButton. + + kXButton1 = 0x05, // Not contiguous with kLButton and kRButton. + kXButton2 = 0x06, // Not contiguous with kLButton and kRButton. + + kBack = 0x08, // Backspace. + kTab = 0x09, + + kClear = 0x0C, + kReturn = 0x0D, // Enter. + + kShift = 0x10, + kControl = 0x11, // Ctrl. + kMenu = 0x12, // Alt. + kPause = 0x13, + kCapital = 0x14, // Caps Lock. + + kKana = 0x15, + kHangeul = 0x15, // Old name. + kHangul = 0x15, + kImeOn = 0x16, + kJunja = 0x17, + kFinal = 0x18, + kHanja = 0x19, + kKanji = 0x19, + kImeOff = 0x1A, + + kEscape = 0x1B, + + kConvert = 0x1C, + kNonConvert = 0x1D, + kAccept = 0x1E, + kModeChange = 0x1F, + + kSpace = 0x20, + kPrior = 0x21, // Page Up. + kNext = 0x22, // Page Down. + kEnd = 0x23, + kHome = 0x24, + kLeft = 0x25, + kUp = 0x26, + kRight = 0x27, + kDown = 0x28, + kSelect = 0x29, + kPrint = 0x2A, + kExecute = 0x2B, + kSnapshot = 0x2C, + kInsert = 0x2D, + kDelete = 0x2E, + kHelp = 0x2F, + + // Same as ASCII '0' - '9'. + k0 = 0x30, + k1 = 0x31, + k2 = 0x32, + k3 = 0x33, + k4 = 0x34, + k5 = 0x35, + k6 = 0x36, + k7 = 0x37, + k8 = 0x38, + k9 = 0x39, + + // Same as ASCII 'A' - 'Z'. + kA = 0x41, + kB = 0x42, + kC = 0x43, + kD = 0x44, + kE = 0x45, + kF = 0x46, + kG = 0x47, + kH = 0x48, + kI = 0x49, + kJ = 0x4A, + kK = 0x4B, + kL = 0x4C, + kM = 0x4D, + kN = 0x4E, + kO = 0x4F, + kP = 0x50, + kQ = 0x51, + kR = 0x52, + kS = 0x53, + kT = 0x54, + kU = 0x55, + kV = 0x56, + kW = 0x57, + kX = 0x58, + kY = 0x59, + kZ = 0x5A, + + kLWin = 0x5B, + kRWin = 0x5C, + kApps = 0x5D, + + kSleep = 0x5F, + + kNumpad0 = 0x60, + kNumpad1 = 0x61, + kNumpad2 = 0x62, + kNumpad3 = 0x63, + kNumpad4 = 0x64, + kNumpad5 = 0x65, + kNumpad6 = 0x66, + kNumpad7 = 0x67, + kNumpad8 = 0x68, + kNumpad9 = 0x69, + kMultiply = 0x6A, + kAdd = 0x6B, + kSeparator = 0x6C, + kSubtract = 0x6D, + kDecimal = 0x6E, + kDivide = 0x6F, + kF1 = 0x70, + kF2 = 0x71, + kF3 = 0x72, + kF4 = 0x73, + kF5 = 0x74, + kF6 = 0x75, + kF7 = 0x76, + kF8 = 0x77, + kF9 = 0x78, + kF10 = 0x79, + kF11 = 0x7A, + kF12 = 0x7B, + kF13 = 0x7C, + kF14 = 0x7D, + kF15 = 0x7E, + kF16 = 0x7F, + kF17 = 0x80, + kF18 = 0x81, + kF19 = 0x82, + kF20 = 0x83, + kF21 = 0x84, + kF22 = 0x85, + kF23 = 0x86, + kF24 = 0x87, + + // VK_NAVIGATION_* added in _WIN32_WINNT 0x0604, but marked as reserved in + // WinUser.h and not documented on MSDN. + kNavigationView = 0x88, + kNavigationMenu = 0x89, + kNavigationUp = 0x8A, + kNavigationDown = 0x8B, + kNavigationLeft = 0x8C, + kNavigationRight = 0x8D, + kNavigationAccept = 0x8E, + kNavigationCancel = 0x8F, + + kNumLock = 0x90, + kScroll = 0x91, + + // NEC PC-9800 keyboard. + kOemNecEqual = 0x92, // '=' key on the numpad. + + // Fujitsu/OASYS keyboard. + kOemFjJisho = 0x92, // 'Dictionary' key. + kOemFjMasshou = 0x93, // 'Unregister word' key. + kOemFjTouroku = 0x94, // 'Register word' key. + kOemFjLOya = 0x95, // 'Left OYAYUBI' key. + kOemFjROya = 0x96, // 'Right OYAYUBI' key. + + // Left and right Alt, Ctrl and Shift virtual keys. + // On Windows (from WinUser.h): + // "Used only as parameters to GetAsyncKeyState() and GetKeyState(). + // No other API or message will distinguish left and right keys in this way." + kLShift = 0xA0, + kRShift = 0xA1, + kLControl = 0xA2, + kRControl = 0xA3, + kLMenu = 0xA4, + kRMenu = 0xA5, + + kBrowserBack = 0xA6, + kBrowserForward = 0xA7, + kBrowserRefresh = 0xA8, + kBrowserStop = 0xA9, + kBrowserSearch = 0xAA, + kBrowserFavorites = 0xAB, + kBrowserHome = 0xAC, + + kVolumeMute = 0xAD, + kVolumeDown = 0xAE, + kVolumeUp = 0xAF, + kMediaNextTrack = 0xB0, + kMediaPrevTrack = 0xB1, + kMediaStop = 0xB2, + kMediaPlayPause = 0xB3, + kLaunchMail = 0xB4, + kLaunchMediaSelect = 0xB5, + kLaunchApp1 = 0xB6, + kLaunchApp2 = 0xB7, + + kOem1 = 0xBA, // ';:' for the US. + kOemPlus = 0xBB, // '+' for any country. + kOemComma = 0xBC, // ',' for any country. + kOemMinus = 0xBD, // '-' for any country. + kOemPeriod = 0xBE, // '.' for any country. + kOem2 = 0xBF, // '/?' for the US. + kOem3 = 0xC0, // '`~' for the US. + + // VK_GAMEPAD_* (since _WIN32_WINNT 0x0604) virtual key codes are marked as + // reserved in WinUser.h and are mostly not documented on MSDN (with the + // exception of the Xbox Device Portal Remote Input REST API in the "UWP on + // Xbox One" section). + // Xenia uses VK_PAD_* (kXInputPad*) for HID emulation internally instead + // because XInput is the API used for the Xbox 360 controller. + // To avoid confusion between VK_GAMEPAD_* and VK_PAD_*, here they are + // prefixed with kXboxOne and kXInput respectively. + kXboxOneGamepadA = 0xC3, + kXboxOneGamepadB = 0xC4, + kXboxOneGamepadX = 0xC5, + kXboxOneGamepadY = 0xC6, + kXboxOneGamepadRightShoulder = 0xC7, + kXboxOneGamepadLeftShoulder = 0xC8, + kXboxOneGamepadLeftTrigger = 0xC9, + kXboxOneGamepadRightTrigger = 0xCA, + kXboxOneGamepadDpadUp = 0xCB, + kXboxOneGamepadDpadDown = 0xCC, + kXboxOneGamepadDpadLeft = 0xCD, + kXboxOneGamepadDpadRight = 0xCE, + kXboxOneGamepadMenu = 0xCF, + kXboxOneGamepadView = 0xD0, + kXboxOneGamepadLeftThumbstickButton = 0xD1, + kXboxOneGamepadRightThumbstickButton = 0xD2, + kXboxOneGamepadLeftThumbstickUp = 0xD3, + kXboxOneGamepadLeftThumbstickDown = 0xD4, + kXboxOneGamepadLeftThumbstickRight = 0xD5, + kXboxOneGamepadLeftThumbstickLeft = 0xD6, + kXboxOneGamepadRightThumbstickUp = 0xD7, + kXboxOneGamepadRightThumbstickDown = 0xD8, + kXboxOneGamepadRightThumbstickRight = 0xD9, + kXboxOneGamepadRightThumbstickLeft = 0xDA, + + kOem4 = 0xDB, // '[{' for the US. + kOem5 = 0xDC, // '\|' for the US. + kOem6 = 0xDD, // ']}' for the US. + kOem7 = 0xDE, // ''"' for the US. + kOem8 = 0xDF, + + kOemAx = 0xE1, // 'AX' key on the Japanese AX keyboard. + kOem102 = 0xE2, // "<>" or "\|" on the RT 102-key keyboard. + kIcoHelp = 0xE3, // Help key on the Olivetti keyboard (ICO). + kIco00 = 0xE4, // 00 key on the ICO. + + kProcessKey = 0xE5, + + kIcoClear = 0xE6, + + // From MSDN: + // "Used to pass Unicode characters as if they were keystrokes. The VK_PACKET + // key is the low word of a 32-bit Virtual Key value used for non-keyboard + // input methods." + kPacket = 0xE7, + + // Nokia/Ericsson. + kOemReset = 0xE9, + kOemJump = 0xEA, + kOemPa1 = 0xEB, + kOemPa2 = 0xEC, + kOemPa3 = 0xED, + kOemWsCtrl = 0xEE, + kOemCuSel = 0xEF, + kOemAttn = 0xF0, + kOemFinish = 0xF1, + kOemCopy = 0xF2, + kOemAuto = 0xF3, + kOemEnlW = 0xF4, + kOemBackTab = 0xF5, + + kAttn = 0xF6, + kCrSel = 0xF7, + kExSel = 0xF8, + kErEof = 0xF9, + kPlay = 0xFA, + kZoom = 0xFB, + kNoName = 0xFC, + kPa1 = 0xFD, + kOemClear = 0xFE, + + // VK_PAD_* from XInput.h for XInputGetKeystroke. kXInput prefix added to + // distinguish from VK_GAMEPAD_*, added much later for the Xbox One + // controller. + + kXInputPadA = 0x5800, + kXInputPadB = 0x5801, + kXInputPadX = 0x5802, + kXInputPadY = 0x5803, + // RShoulder before LShoulder, not a typo. + kXInputPadRShoulder = 0x5804, + kXInputPadLShoulder = 0x5805, + kXInputPadLTrigger = 0x5806, + kXInputPadRTrigger = 0x5807, + + kXInputPadDpadUp = 0x5810, + kXInputPadDpadDown = 0x5811, + kXInputPadDpadLeft = 0x5812, + kXInputPadDpadRight = 0x5813, + kXInputPadStart = 0x5814, + kXInputPadBack = 0x5815, + kXInputPadLThumbPress = 0x5816, + kXInputPadRThumbPress = 0x5817, + + kXInputPadLThumbUp = 0x5820, + kXInputPadLThumbDown = 0x5821, + kXInputPadLThumbRight = 0x5822, + kXInputPadLThumbLeft = 0x5823, + kXInputPadLThumbUpLeft = 0x5824, + kXInputPadLThumbUpRight = 0x5825, + kXInputPadLThumbDownRight = 0x5826, + kXInputPadLThumbDownLeft = 0x5827, + + kXInputPadRThumbUp = 0x5830, + kXInputPadRThumbDown = 0x5831, + kXInputPadRThumbRight = 0x5832, + kXInputPadRThumbLeft = 0x5833, + kXInputPadRThumbUpLeft = 0x5834, + kXInputPadRThumbUpRight = 0x5835, + kXInputPadRThumbDownRight = 0x5836, + kXInputPadRThumbDownLeft = 0x5837, +}; + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/vulkan/api.h b/include/rex/ui/vulkan/api.h new file mode 100644 index 0000000..278e955 --- /dev/null +++ b/include/rex/ui/vulkan/api.h @@ -0,0 +1,56 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include // For Vulkan-Hpp. +#include + +#ifndef VK_NO_PROTOTYPES +#define VK_NO_PROTOTYPES +#endif + +#ifndef VK_ENABLE_BETA_EXTENSIONS +#define VK_ENABLE_BETA_EXTENSIONS +#endif + +// Disable to_string in vulkan.hpp to avoid circular dependency with vulkan_to_string.hpp +#ifndef VULKAN_HPP_NO_TO_STRING +#define VULKAN_HPP_NO_TO_STRING +#endif + +#if REX_PLATFORM_ANDROID +#ifndef VK_USE_PLATFORM_ANDROID_KHR +#define VK_USE_PLATFORM_ANDROID_KHR +#endif +#endif + +#if REX_PLATFORM_GNU_LINUX +#ifndef VK_USE_PLATFORM_XCB_KHR +#define VK_USE_PLATFORM_XCB_KHR +#endif +#endif + +#if REX_PLATFORM_WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#ifndef VK_USE_PLATFORM_WIN32_KHR +#define VK_USE_PLATFORM_WIN32_KHR +#endif +#endif + +#include +#include +#include diff --git a/include/rex/ui/vulkan/device.h b/include/rex/ui/vulkan/device.h new file mode 100644 index 0000000..947817f --- /dev/null +++ b/include/rex/ui/vulkan/device.h @@ -0,0 +1,313 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include + +namespace rex { +namespace ui { +namespace vulkan { + +class VulkanDevice { + public: + static std::unique_ptr CreateIfSupported(const VulkanInstance* vulkan_instance, + VkPhysicalDevice physical_device, + bool with_gpu_emulation, + bool with_swapchain); + + VulkanDevice(const VulkanDevice&) = delete; + VulkanDevice& operator=(const VulkanDevice&) = delete; + VulkanDevice(VulkanDevice&&) = delete; + VulkanDevice& operator=(VulkanDevice&&) = delete; + + ~VulkanDevice(); + + const VulkanInstance* vulkan_instance() const { return vulkan_instance_; } + + VkPhysicalDevice physical_device() const { return physical_device_; } + + // If functionality from higher API versions is used, increase this. + // This is for VkApplicationInfo. + // "apiVersion must be the highest version of Vulkan that the application is + // designed to use" + // "The patch version number specified in apiVersion is ignored when creating + // an instance object" + static constexpr uint32_t kHighestUsedApiMinorVersion = VK_MAKE_API_VERSION(0, 1, 3, 0); + + struct Properties { + // Vulkan 1.0 + uint32_t apiVersion = VK_MAKE_API_VERSION(0, 1, 0, 0); + uint32_t driverVersion = 0; + uint32_t vendorID = 0; + uint32_t deviceID = 0; + char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE] = {}; + + uint32_t maxImageDimension2D = 4096; + uint32_t maxImageDimension3D = 256; + uint32_t maxImageDimensionCube = 4096; + uint32_t maxImageArrayLayers = 256; + uint32_t maxStorageBufferRange = uint32_t(1) << 27; + uint32_t maxSamplerAllocationCount = 4000; + uint32_t maxPerStageDescriptorSamplers = 16; + uint32_t maxPerStageDescriptorStorageBuffers = 4; + uint32_t maxPerStageDescriptorSampledImages = 16; + uint32_t maxPerStageResources = 128; + uint32_t maxVertexOutputComponents = 64; + uint32_t maxTessellationEvaluationOutputComponents = 64; + uint32_t maxGeometryInputComponents = 64; + uint32_t maxGeometryOutputComponents = 64; + uint32_t maxFragmentInputComponents = 64; + uint32_t maxFragmentCombinedOutputResources = 4; + float maxSamplerAnisotropy = 1.0f; + uint32_t maxViewportDimensions[2] = {4096, 4096}; + VkDeviceSize minUniformBufferOffsetAlignment = 256; + VkDeviceSize minStorageBufferOffsetAlignment = 256; + uint32_t maxFramebufferWidth = 4096; + uint32_t maxFramebufferHeight = 4096; + VkSampleCountFlags framebufferColorSampleCounts = VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT; + VkSampleCountFlags framebufferDepthSampleCounts = VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT; + VkSampleCountFlags framebufferStencilSampleCounts = + VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT; + VkSampleCountFlags framebufferNoAttachmentsSampleCounts = + VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT; + VkSampleCountFlags sampledImageColorSampleCounts = + VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT; + VkSampleCountFlags sampledImageIntegerSampleCounts = VK_SAMPLE_COUNT_1_BIT; + VkSampleCountFlags sampledImageDepthSampleCounts = + VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT; + VkSampleCountFlags sampledImageStencilSampleCounts = + VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT; + bool standardSampleLocations = false; + VkDeviceSize optimalBufferCopyOffsetAlignment = 1; + VkDeviceSize optimalBufferCopyRowPitchAlignment = 1; + VkDeviceSize nonCoherentAtomSize = 256; + + bool robustBufferAccess = false; + bool fullDrawIndexUint32 = false; + bool independentBlend = false; + bool geometryShader = false; + bool tessellationShader = false; + bool sampleRateShading = false; + bool depthClamp = false; + bool fillModeNonSolid = false; + bool samplerAnisotropy = false; + bool occlusionQueryPrecise = false; + bool vertexPipelineStoresAndAtomics = false; + bool fragmentStoresAndAtomics = false; + bool shaderClipDistance = false; + bool shaderCullDistance = false; + bool sparseBinding = false; + bool sparseResidencyBuffer = false; + + // VK_KHR_sampler_mirror_clamp_to_edge (#15, promoted to 1.2) + + bool samplerMirrorClampToEdge = false; + + // VK_KHR_uniform_buffer_standard_layout (#253, promoted to 1.2) + + bool uniformBufferStandardLayout = false; + + // VK_EXT_scalar_block_layout (#222, promoted to 1.2) + + bool scalarBlockLayout = false; + + // VK_KHR_portability_subset (#164) + + bool constantAlphaColorBlendFactors = false; + bool imageViewFormatReinterpretation = false; + bool imageViewFormatSwizzle = false; + bool pointPolygons = false; + bool separateStencilMaskRef = false; + bool shaderSampleRateInterpolationFunctions = false; + + // VK_KHR_driver_properties (#197, promoted to 1.2) + + VkDriverId driverID = VkDriverId(0); + + // VK_KHR_shader_float_controls (#198, promoted to 1.2) + + bool shaderSignedZeroInfNanPreserveFloat32 = false; + bool shaderDenormFlushToZeroFloat32 = false; + bool shaderRoundingModeRTEFloat32 = false; + + // VK_EXT_fragment_shader_interlock (#252) + + bool fragmentShaderSampleInterlock = false; + bool fragmentShaderPixelInterlock = false; + + // VK_EXT_shader_demote_to_helper_invocation (#277, promoted to 1.3) + + bool shaderDemoteToHelperInvocation = false; + + // VK_KHR_dynamic_rendering (#55, promoted to 1.3) + + bool dynamicRendering = false; + + // VK_EXT_non_seamless_cube_map (#423) + + bool nonSeamlessCubeMap = false; + + // VK_EXT_custom_border_color + + bool customBorderColors = false; + bool customBorderColorWithoutFormat = false; + uint32_t maxCustomBorderColorSamplers = 0; + + // VK_EXT_robustness2 + + bool nullDescriptor = false; + }; + + // Properties of the core API and enabled extensions, and enabled features. + // Some supported functionality is enabled conditionally based on the + // `with_swapchain` and `with_gpu_emulation` options. + const Properties& properties() const { return properties_; } + + // Enabled extensions not fully covered by the device properties and optional + // feature flags in the `Properties` structure (primarily those adding API + // functionality rather than GPU features). Also set to true if the version of + // the Vulkan API they were promoted to it supported (with the + // `ext_major_minor_` prefix rather than `ext_`). + struct Extensions { + bool ext_KHR_swapchain = false; // #2 + bool ext_1_1_KHR_dedicated_allocation = false; // #128 + bool ext_EXT_shader_stencil_export = false; // #141 + bool ext_1_1_KHR_get_memory_requirements2 = false; // #147 + bool ext_1_2_KHR_image_format_list = false; // #148 + // Has optional features not implied by this being true. + bool ext_1_1_KHR_sampler_ycbcr_conversion = false; // #157 + bool ext_1_1_KHR_bind_memory2 = false; // #158 + bool ext_1_2_KHR_spirv_1_4 = false; // #237 + bool ext_EXT_memory_budget = false; // #238 + // Has optional features not implied by this being true. + bool ext_EXT_custom_border_color = false; + // Has optional features not implied by this being true. + bool ext_EXT_robustness2 = false; + // Has optional features not implied by this being true. + bool ext_1_3_KHR_maintenance4 = false; // #414 + // Has optional features not implied by this being true. + bool ext_1_3_KHR_dynamic_rendering = false; // #55 + }; + + const Extensions& extensions() const { return extensions_; } + + VkDevice device() const { return device_; } + + struct Functions { +#define XE_UI_VULKAN_FUNCTION(name) PFN_##name name = nullptr; +#define XE_UI_VULKAN_FUNCTION_PROMOTED(extension_name, core_name) \ + PFN_##core_name core_name = nullptr; +#include + // VK_KHR_swapchain (#2) +#include + // VK_KHR_get_memory_requirements2 (#147, promoted to 1.1) +#include + // VK_KHR_bind_memory2 (#158, promoted to 1.1) +#include + // VK_KHR_maintenance4 (#414, promoted to 1.3) +#include + // VK_KHR_dynamic_rendering (#55, promoted to 1.3) +#include +#undef XE_UI_VULKAN_FUNCTION_PROMOTED +#undef XE_UI_VULKAN_FUNCTION + }; + + const Functions& functions() const { return functions_; } + + template + void SetObjectName(const VkObjectType object_type, const Object object_handle, + const char* const object_name) const { + if (!vulkan_instance()->extensions().ext_EXT_debug_utils) { + return; + } + VkDebugUtilsObjectNameInfoEXT object_name_info; + object_name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + object_name_info.pNext = nullptr; + object_name_info.objectType = object_type; + object_name_info.objectHandle = (uint64_t)object_handle; + object_name_info.pObjectName = object_name; + vulkan_instance()->functions().vkSetDebugUtilsObjectNameEXT(device(), &object_name_info); + } + + struct Queue { + // Host access to queues must be externally synchronized in Vulkan. + std::recursive_mutex mutex; + VkQueue queue = nullptr; + + explicit Queue(const VkQueue queue) : queue(queue) {} + + class Acquisition { + public: + explicit Acquisition(Queue& queue) : lock_(queue.mutex), queue_(queue.queue) {} + + VkQueue queue() const { return queue_; } + + private: + std::unique_lock lock_; + VkQueue queue_; + }; + + Acquisition Acquire() { return Acquisition(*this); } + }; + + struct QueueFamily { + VkQueueFlags queue_flags = 0; + bool may_support_presentation = false; + std::vector> queues; + }; + + const std::vector& queue_families() const { return queue_families_; } + uint32_t queue_family_graphics_compute() const { return queue_family_graphics_compute_; } + // UINT32_MAX if not supported or not enabled. + // May be the same as queue_family_graphics_compute(). + uint32_t queue_family_sparse_binding() const { return queue_family_sparse_binding_; } + + Queue::Acquisition AcquireQueue(const uint32_t queue_family_index, + const uint32_t queue_index) const { + return queue_families()[queue_family_index].queues[queue_index]->Acquire(); + } + + struct MemoryTypes { + uint32_t device_local = 0b0; + uint32_t host_visible = 0b0; + uint32_t host_coherent = 0b0; + uint32_t host_cached = 0b0; + }; + + const MemoryTypes& memory_types() const { return memory_types_; } + + private: + explicit VulkanDevice(const VulkanInstance* vulkan_instance, VkPhysicalDevice physical_device); + + const VulkanInstance* vulkan_instance_ = nullptr; + VkPhysicalDevice physical_device_ = nullptr; + + Properties properties_; + Extensions extensions_; + + VkDevice device_ = nullptr; + + Functions functions_; + + std::vector queue_families_; + uint32_t queue_family_graphics_compute_ = UINT32_MAX; + uint32_t queue_family_sparse_binding_ = UINT32_MAX; + + MemoryTypes memory_types_; +}; + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/vulkan/functions/device_1_0.inc b/include/rex/ui/vulkan/functions/device_1_0.inc new file mode 100644 index 0000000..aa55a4a --- /dev/null +++ b/include/rex/ui/vulkan/functions/device_1_0.inc @@ -0,0 +1,84 @@ +// Vulkan 1.0 core device functions used in Xenia. +XE_UI_VULKAN_FUNCTION(vkAllocateCommandBuffers) +XE_UI_VULKAN_FUNCTION(vkAllocateDescriptorSets) +XE_UI_VULKAN_FUNCTION(vkAllocateMemory) +XE_UI_VULKAN_FUNCTION(vkBeginCommandBuffer) +XE_UI_VULKAN_FUNCTION(vkBindBufferMemory) +XE_UI_VULKAN_FUNCTION(vkBindImageMemory) +XE_UI_VULKAN_FUNCTION(vkCmdBeginRenderPass) +XE_UI_VULKAN_FUNCTION(vkCmdBindDescriptorSets) +XE_UI_VULKAN_FUNCTION(vkCmdBindIndexBuffer) +XE_UI_VULKAN_FUNCTION(vkCmdBindPipeline) +XE_UI_VULKAN_FUNCTION(vkCmdBindVertexBuffers) +XE_UI_VULKAN_FUNCTION(vkCmdClearAttachments) +XE_UI_VULKAN_FUNCTION(vkCmdClearColorImage) +XE_UI_VULKAN_FUNCTION(vkCmdCopyBuffer) +XE_UI_VULKAN_FUNCTION(vkCmdCopyBufferToImage) +XE_UI_VULKAN_FUNCTION(vkCmdCopyImageToBuffer) +XE_UI_VULKAN_FUNCTION(vkCmdCopyQueryPoolResults) +XE_UI_VULKAN_FUNCTION(vkCmdDispatch) +XE_UI_VULKAN_FUNCTION(vkCmdDraw) +XE_UI_VULKAN_FUNCTION(vkCmdDrawIndexed) +XE_UI_VULKAN_FUNCTION(vkCmdEndRenderPass) +XE_UI_VULKAN_FUNCTION(vkCmdBeginQuery) +XE_UI_VULKAN_FUNCTION(vkCmdEndQuery) +XE_UI_VULKAN_FUNCTION(vkCmdPipelineBarrier) +XE_UI_VULKAN_FUNCTION(vkCmdPushConstants) +XE_UI_VULKAN_FUNCTION(vkCmdResetQueryPool) +XE_UI_VULKAN_FUNCTION(vkCmdSetBlendConstants) +XE_UI_VULKAN_FUNCTION(vkCmdSetDepthBias) +XE_UI_VULKAN_FUNCTION(vkCmdSetScissor) +XE_UI_VULKAN_FUNCTION(vkCmdSetStencilCompareMask) +XE_UI_VULKAN_FUNCTION(vkCmdSetStencilReference) +XE_UI_VULKAN_FUNCTION(vkCmdSetStencilWriteMask) +XE_UI_VULKAN_FUNCTION(vkCmdSetViewport) +XE_UI_VULKAN_FUNCTION(vkCreateBuffer) +XE_UI_VULKAN_FUNCTION(vkCreateBufferView) +XE_UI_VULKAN_FUNCTION(vkCreateCommandPool) +XE_UI_VULKAN_FUNCTION(vkCreateComputePipelines) +XE_UI_VULKAN_FUNCTION(vkCreateDescriptorPool) +XE_UI_VULKAN_FUNCTION(vkCreateDescriptorSetLayout) +XE_UI_VULKAN_FUNCTION(vkCreateFence) +XE_UI_VULKAN_FUNCTION(vkCreateFramebuffer) +XE_UI_VULKAN_FUNCTION(vkCreateGraphicsPipelines) +XE_UI_VULKAN_FUNCTION(vkCreateImage) +XE_UI_VULKAN_FUNCTION(vkCreateImageView) +XE_UI_VULKAN_FUNCTION(vkCreatePipelineLayout) +XE_UI_VULKAN_FUNCTION(vkCreateQueryPool) +XE_UI_VULKAN_FUNCTION(vkCreateRenderPass) +XE_UI_VULKAN_FUNCTION(vkCreateSampler) +XE_UI_VULKAN_FUNCTION(vkCreateSemaphore) +XE_UI_VULKAN_FUNCTION(vkCreateShaderModule) +XE_UI_VULKAN_FUNCTION(vkDestroyBuffer) +XE_UI_VULKAN_FUNCTION(vkDestroyBufferView) +XE_UI_VULKAN_FUNCTION(vkDestroyCommandPool) +XE_UI_VULKAN_FUNCTION(vkDestroyDescriptorPool) +XE_UI_VULKAN_FUNCTION(vkDestroyDescriptorSetLayout) +XE_UI_VULKAN_FUNCTION(vkDestroyFence) +XE_UI_VULKAN_FUNCTION(vkDestroyFramebuffer) +XE_UI_VULKAN_FUNCTION(vkDestroyImage) +XE_UI_VULKAN_FUNCTION(vkDestroyImageView) +XE_UI_VULKAN_FUNCTION(vkDestroyPipeline) +XE_UI_VULKAN_FUNCTION(vkDestroyPipelineLayout) +XE_UI_VULKAN_FUNCTION(vkDestroyQueryPool) +XE_UI_VULKAN_FUNCTION(vkDestroyRenderPass) +XE_UI_VULKAN_FUNCTION(vkDestroySampler) +XE_UI_VULKAN_FUNCTION(vkDestroySemaphore) +XE_UI_VULKAN_FUNCTION(vkDestroyShaderModule) +XE_UI_VULKAN_FUNCTION(vkEndCommandBuffer) +XE_UI_VULKAN_FUNCTION(vkFlushMappedMemoryRanges) +XE_UI_VULKAN_FUNCTION(vkFreeMemory) +XE_UI_VULKAN_FUNCTION(vkGetBufferMemoryRequirements) +XE_UI_VULKAN_FUNCTION(vkGetDeviceQueue) +XE_UI_VULKAN_FUNCTION(vkGetFenceStatus) +XE_UI_VULKAN_FUNCTION(vkGetImageMemoryRequirements) +XE_UI_VULKAN_FUNCTION(vkInvalidateMappedMemoryRanges) +XE_UI_VULKAN_FUNCTION(vkMapMemory) +XE_UI_VULKAN_FUNCTION(vkResetCommandPool) +XE_UI_VULKAN_FUNCTION(vkResetDescriptorPool) +XE_UI_VULKAN_FUNCTION(vkResetFences) +XE_UI_VULKAN_FUNCTION(vkQueueBindSparse) +XE_UI_VULKAN_FUNCTION(vkQueueSubmit) +XE_UI_VULKAN_FUNCTION(vkUnmapMemory) +XE_UI_VULKAN_FUNCTION(vkUpdateDescriptorSets) +XE_UI_VULKAN_FUNCTION(vkWaitForFences) diff --git a/include/rex/ui/vulkan/functions/device_1_1_khr_bind_memory2.inc b/include/rex/ui/vulkan/functions/device_1_1_khr_bind_memory2.inc new file mode 100644 index 0000000..ebefbc5 --- /dev/null +++ b/include/rex/ui/vulkan/functions/device_1_1_khr_bind_memory2.inc @@ -0,0 +1,4 @@ +// VK_KHR_bind_memory2 functions used in Xenia. +// Promoted to Vulkan 1.1 core. +XE_UI_VULKAN_FUNCTION_PROMOTED(vkBindBufferMemory2KHR, vkBindBufferMemory2) +XE_UI_VULKAN_FUNCTION_PROMOTED(vkBindImageMemory2KHR, vkBindImageMemory2) diff --git a/include/rex/ui/vulkan/functions/device_1_1_khr_get_memory_requirements2.inc b/include/rex/ui/vulkan/functions/device_1_1_khr_get_memory_requirements2.inc new file mode 100644 index 0000000..11068c4 --- /dev/null +++ b/include/rex/ui/vulkan/functions/device_1_1_khr_get_memory_requirements2.inc @@ -0,0 +1,6 @@ +// VK_KHR_get_memory_requirements2 functions used in Xenia. +// Promoted to Vulkan 1.1 core. +XE_UI_VULKAN_FUNCTION_PROMOTED(vkGetBufferMemoryRequirements2KHR, + vkGetBufferMemoryRequirements2) +XE_UI_VULKAN_FUNCTION_PROMOTED(vkGetImageMemoryRequirements2KHR, + vkGetImageMemoryRequirements2) diff --git a/include/rex/ui/vulkan/functions/device_1_3_khr_dynamic_rendering.inc b/include/rex/ui/vulkan/functions/device_1_3_khr_dynamic_rendering.inc new file mode 100644 index 0000000..b168ee6 --- /dev/null +++ b/include/rex/ui/vulkan/functions/device_1_3_khr_dynamic_rendering.inc @@ -0,0 +1,4 @@ +// VK_KHR_dynamic_rendering functions used in ReXGlue. +// Promoted to Vulkan 1.3 core. +XE_UI_VULKAN_FUNCTION_PROMOTED(vkCmdBeginRenderingKHR, vkCmdBeginRendering) +XE_UI_VULKAN_FUNCTION_PROMOTED(vkCmdEndRenderingKHR, vkCmdEndRendering) diff --git a/include/rex/ui/vulkan/functions/device_1_3_khr_maintenance4.inc b/include/rex/ui/vulkan/functions/device_1_3_khr_maintenance4.inc new file mode 100644 index 0000000..11c0787 --- /dev/null +++ b/include/rex/ui/vulkan/functions/device_1_3_khr_maintenance4.inc @@ -0,0 +1,6 @@ +// VK_KHR_maintenance4 functions used in Xenia. +// Promoted to Vulkan 1.3 core. +XE_UI_VULKAN_FUNCTION_PROMOTED(vkGetDeviceBufferMemoryRequirementsKHR, + vkGetDeviceBufferMemoryRequirements) +XE_UI_VULKAN_FUNCTION_PROMOTED(vkGetDeviceImageMemoryRequirementsKHR, + vkGetDeviceImageMemoryRequirements) diff --git a/include/rex/ui/vulkan/functions/device_khr_swapchain.inc b/include/rex/ui/vulkan/functions/device_khr_swapchain.inc new file mode 100644 index 0000000..435d88a --- /dev/null +++ b/include/rex/ui/vulkan/functions/device_khr_swapchain.inc @@ -0,0 +1,6 @@ +// VK_KHR_swapchain functions used in Xenia. +XE_UI_VULKAN_FUNCTION(vkAcquireNextImageKHR) +XE_UI_VULKAN_FUNCTION(vkCreateSwapchainKHR) +XE_UI_VULKAN_FUNCTION(vkDestroySwapchainKHR) +XE_UI_VULKAN_FUNCTION(vkGetSwapchainImagesKHR) +XE_UI_VULKAN_FUNCTION(vkQueuePresentKHR) diff --git a/include/rex/ui/vulkan/functions/instance_1_0.inc b/include/rex/ui/vulkan/functions/instance_1_0.inc new file mode 100644 index 0000000..b4ad934 --- /dev/null +++ b/include/rex/ui/vulkan/functions/instance_1_0.inc @@ -0,0 +1,11 @@ +// Vulkan 1.0 core instance functions used in Xenia. +XE_UI_VULKAN_FUNCTION(vkCreateDevice) +XE_UI_VULKAN_FUNCTION(vkDestroyDevice) +XE_UI_VULKAN_FUNCTION(vkEnumerateDeviceExtensionProperties) +XE_UI_VULKAN_FUNCTION(vkEnumeratePhysicalDevices) +XE_UI_VULKAN_FUNCTION(vkGetDeviceProcAddr) +XE_UI_VULKAN_FUNCTION(vkGetPhysicalDeviceFeatures) +XE_UI_VULKAN_FUNCTION(vkGetPhysicalDeviceFormatProperties) +XE_UI_VULKAN_FUNCTION(vkGetPhysicalDeviceMemoryProperties) +XE_UI_VULKAN_FUNCTION(vkGetPhysicalDeviceProperties) +XE_UI_VULKAN_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties) diff --git a/include/rex/ui/vulkan/functions/instance_1_1_khr_get_physical_device_properties2.inc b/include/rex/ui/vulkan/functions/instance_1_1_khr_get_physical_device_properties2.inc new file mode 100644 index 0000000..bdc483c --- /dev/null +++ b/include/rex/ui/vulkan/functions/instance_1_1_khr_get_physical_device_properties2.inc @@ -0,0 +1,8 @@ +// VK_KHR_get_physical_device_properties2 functions used in Xenia. +// Promoted to Vulkan 1.1 core. +XE_UI_VULKAN_FUNCTION_PROMOTED(vkGetPhysicalDeviceFeatures2KHR, + vkGetPhysicalDeviceFeatures2) +XE_UI_VULKAN_FUNCTION_PROMOTED(vkGetPhysicalDeviceMemoryProperties2KHR, + vkGetPhysicalDeviceMemoryProperties2) +XE_UI_VULKAN_FUNCTION_PROMOTED(vkGetPhysicalDeviceProperties2KHR, + vkGetPhysicalDeviceProperties2) diff --git a/include/rex/ui/vulkan/functions/instance_ext_debug_utils.inc b/include/rex/ui/vulkan/functions/instance_ext_debug_utils.inc new file mode 100644 index 0000000..c0c9df2 --- /dev/null +++ b/include/rex/ui/vulkan/functions/instance_ext_debug_utils.inc @@ -0,0 +1,4 @@ +// VK_EXT_debug_utils functions used in Xenia. +XE_UI_VULKAN_FUNCTION(vkCreateDebugUtilsMessengerEXT) +XE_UI_VULKAN_FUNCTION(vkDestroyDebugUtilsMessengerEXT) +XE_UI_VULKAN_FUNCTION(vkSetDebugUtilsObjectNameEXT) diff --git a/include/rex/ui/vulkan/functions/instance_khr_android_surface.inc b/include/rex/ui/vulkan/functions/instance_khr_android_surface.inc new file mode 100644 index 0000000..7449ac2 --- /dev/null +++ b/include/rex/ui/vulkan/functions/instance_khr_android_surface.inc @@ -0,0 +1,2 @@ +// VK_KHR_android_surface functions used in Xenia. +XE_UI_VULKAN_FUNCTION(vkCreateAndroidSurfaceKHR) diff --git a/include/rex/ui/vulkan/functions/instance_khr_surface.inc b/include/rex/ui/vulkan/functions/instance_khr_surface.inc new file mode 100644 index 0000000..ca3efde --- /dev/null +++ b/include/rex/ui/vulkan/functions/instance_khr_surface.inc @@ -0,0 +1,6 @@ +// VK_KHR_surface functions used in Xenia. +XE_UI_VULKAN_FUNCTION(vkDestroySurfaceKHR) +XE_UI_VULKAN_FUNCTION(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) +XE_UI_VULKAN_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR) +XE_UI_VULKAN_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR) +XE_UI_VULKAN_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR) diff --git a/include/rex/ui/vulkan/functions/instance_khr_win32_surface.inc b/include/rex/ui/vulkan/functions/instance_khr_win32_surface.inc new file mode 100644 index 0000000..9b6d673 --- /dev/null +++ b/include/rex/ui/vulkan/functions/instance_khr_win32_surface.inc @@ -0,0 +1,3 @@ +// VK_KHR_win32_surface functions used in Xenia. +XE_UI_VULKAN_FUNCTION(vkCreateWin32SurfaceKHR) +XE_UI_VULKAN_FUNCTION(vkGetPhysicalDeviceWin32PresentationSupportKHR) diff --git a/include/rex/ui/vulkan/functions/instance_khr_xcb_surface.inc b/include/rex/ui/vulkan/functions/instance_khr_xcb_surface.inc new file mode 100644 index 0000000..4faa37b --- /dev/null +++ b/include/rex/ui/vulkan/functions/instance_khr_xcb_surface.inc @@ -0,0 +1,2 @@ +// VK_KHR_xcb_surface functions used in Xenia. +XE_UI_VULKAN_FUNCTION(vkCreateXcbSurfaceKHR) diff --git a/include/rex/ui/vulkan/immediate_drawer.h b/include/rex/ui/vulkan/immediate_drawer.h new file mode 100644 index 0000000..2c2c63c --- /dev/null +++ b/include/rex/ui/vulkan/immediate_drawer.h @@ -0,0 +1,168 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace rex { +namespace ui { +namespace vulkan { + +class VulkanImmediateDrawer : public ImmediateDrawer { + public: + static std::unique_ptr Create(const VulkanDevice* vulkan_device, + const UISamplers* ui_samplers); + + ~VulkanImmediateDrawer(); + + std::unique_ptr CreateTexture(uint32_t width, uint32_t height, + ImmediateTextureFilter filter, bool is_repeated, + const uint8_t* data) override; + + void Begin(UIDrawContext& ui_draw_context, float coordinate_space_width, + float coordinate_space_height) override; + void BeginDrawBatch(const ImmediateDrawBatch& batch) override; + void Draw(const ImmediateDraw& draw) override; + void EndDrawBatch() override; + void End() override; + + protected: + void OnLeavePresenter() override; + + private: + struct PushConstants { + struct Vertex { + float coordinate_space_size_inv[2]; + } vertex; + }; + + class VulkanImmediateTexture : public ImmediateTexture { + public: + struct Resource { + VkImage image; + VkDeviceMemory memory; + VkImageView image_view; + uint32_t descriptor_index; + }; + + VulkanImmediateTexture(uint32_t width, uint32_t height) + : ImmediateTexture(width, height), immediate_drawer_(nullptr) {} + ~VulkanImmediateTexture() override; + + // If null, this is either a blank texture, or the immediate drawer has been + // destroyed. + VulkanImmediateDrawer* immediate_drawer_; + size_t immediate_drawer_index_; + // Invalid if immediate_drawer_ is null, since it's managed by the immediate + // drawer. + Resource resource_; + size_t pending_upload_index_; + uint64_t last_usage_submission_ = 0; + }; + + struct TextureDescriptorPool { + // Using uint64_t for recycled bits. + static constexpr uint32_t kDescriptorCount = 64; + VkDescriptorPool pool; + VkDescriptorSet sets[kDescriptorCount]; + uint32_t index; + uint32_t unallocated_count; + uint64_t recycled_bits; + TextureDescriptorPool* unallocated_next; + TextureDescriptorPool* recycled_next; + }; + + explicit VulkanImmediateDrawer(const VulkanDevice* vulkan_device, const UISamplers* ui_samplers); + bool Initialize(); + + bool EnsurePipelinesCreatedForCurrentRenderPass(); + + // Allocates a combined image sampler in a pool and returns its index, or + // UINT32_MAX in case of failure. + uint32_t AllocateTextureDescriptor(); + VkDescriptorSet GetTextureDescriptor(uint32_t descriptor_index) const; + void FreeTextureDescriptor(uint32_t descriptor_index); + + // If data is null, a (1, 1, 1, 1) image will be created, which can be used as + // a replacement when drawing without a real texture. + bool CreateTextureResource(uint32_t width, uint32_t height, ImmediateTextureFilter filter, + bool is_repeated, const uint8_t* data, + VulkanImmediateTexture::Resource& resource_out, + size_t& pending_upload_index_out); + void DestroyTextureResource(VulkanImmediateTexture::Resource& resource); + void OnImmediateTextureDestroyed(VulkanImmediateTexture& texture); + + const VulkanDevice* vulkan_device_; + const UISamplers* ui_samplers_; + + // Combined image sampler pools for textures. + VkDescriptorSetLayout texture_descriptor_set_layout_; + std::vector texture_descriptor_pools_; + TextureDescriptorPool* texture_descriptor_pool_unallocated_first_ = nullptr; + TextureDescriptorPool* texture_descriptor_pool_recycled_first_ = nullptr; + + VulkanImmediateTexture::Resource white_texture_ = {}; + std::vector textures_; + struct PendingTextureUpload { + // Null for internal resources such as the white texture. + VulkanImmediateTexture* texture; + // VK_NULL_HANDLE if need to clear rather than to copy. + VkBuffer buffer; + VkDeviceMemory buffer_memory; + VkImage image; + uint32_t width; + uint32_t height; + }; + std::vector texture_uploads_pending_; + struct SubmittedTextureUploadBuffer { + VkBuffer buffer; + VkDeviceMemory buffer_memory; + uint64_t submission_index; + }; + std::deque texture_upload_buffers_submitted_; + // Resource and last usage submission pairs. + std::vector> textures_deleted_; + + std::unique_ptr vertex_buffer_pool_; + + VkPipelineLayout pipeline_layout_ = VK_NULL_HANDLE; + + VkFormat pipeline_framebuffer_format_ = VK_FORMAT_UNDEFINED; + VkPipeline pipeline_triangle_ = VK_NULL_HANDLE; + VkPipeline pipeline_line_ = VK_NULL_HANDLE; + + // The submission index within the current Begin (or the last, if outside + // one). + uint64_t last_paint_submission_index_ = 0; + // Completed submission index as of the latest Begin, to coarsely skip delayed + // texture deletion. + uint64_t last_completed_submission_index_ = 0; + + VkCommandBuffer current_command_buffer_ = VK_NULL_HANDLE; + VkExtent2D current_render_target_extent_; + VkRect2D current_scissor_; + VkPipeline current_pipeline_; + uint32_t current_texture_descriptor_index_; + bool batch_open_ = false; + bool batch_has_index_buffer_; +}; + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/vulkan/instance.h b/include/rex/ui/vulkan/instance.h new file mode 100644 index 0000000..e672629 --- /dev/null +++ b/include/rex/ui/vulkan/instance.h @@ -0,0 +1,131 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include + +namespace rex { +namespace ui { +namespace vulkan { + +class VulkanInstance { + public: + static std::unique_ptr Create(bool with_surface, bool try_enable_validation); + + VulkanInstance(const VulkanInstance&) = delete; + VulkanInstance& operator=(const VulkanInstance&) = delete; + VulkanInstance(VulkanInstance&&) = delete; + VulkanInstance& operator=(VulkanInstance&&) = delete; + + ~VulkanInstance(); + + // nullptr if RenderDoc is not connected. + RenderDocAPI* renderdoc_api() const { return renderdoc_api_.get(); } + + struct Functions { + // From the loader module. + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = nullptr; + PFN_vkDestroyInstance vkDestroyInstance = nullptr; + + // From vkGetInstanceProcAddr for nullptr. + PFN_vkCreateInstance vkCreateInstance = nullptr; + PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties = nullptr; + PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties = nullptr; + // Vulkan 1.1. + PFN_vkEnumerateInstanceVersion vkEnumerateInstanceVersion = nullptr; + + // From vkGetInstanceProcAddr for the instance. +#define XE_UI_VULKAN_FUNCTION(name) PFN_##name name = nullptr; +#define XE_UI_VULKAN_FUNCTION_PROMOTED(extension_name, core_name) \ + PFN_##core_name core_name = nullptr; +#include + // VK_KHR_surface (#1) +#include + // VK_KHR_xcb_surface (#6) +#ifdef VK_USE_PLATFORM_XCB_KHR +#include +#endif + // VK_KHR_android_surface (#9) +#ifdef VK_USE_PLATFORM_ANDROID_KHR +#include +#endif + // VK_KHR_win32_surface (#10) +#ifdef VK_USE_PLATFORM_WIN32_KHR +#include +#endif + // VK_KHR_get_physical_device_properties2 (#60, promoted to 1.1) +#include + // VK_EXT_debug_utils (#129) +#include +#undef XE_UI_VULKAN_FUNCTION_PROMOTED +#undef XE_UI_VULKAN_FUNCTION + }; + + const Functions& functions() const { return functions_; } + + uint32_t api_version() const { return api_version_; } + + // Also set to true if the version of the Vulkan API they were promoted to it + // supported (with the `ext_major_minor_` prefix rather than `ext_`). + struct Extensions { + bool ext_KHR_surface = false; // #1 +#ifdef VK_USE_PLATFORM_XCB_KHR + bool ext_KHR_xcb_surface = false; // #6 +#endif +#ifdef VK_USE_PLATFORM_ANDROID_KHR + bool ext_KHR_android_surface = false; // #9 +#endif +#ifdef VK_USE_PLATFORM_WIN32_KHR + bool ext_KHR_win32_surface = false; // #10 +#endif + bool ext_1_1_KHR_get_physical_device_properties2 = false; // #60 + bool ext_EXT_debug_utils = false; // #129 + bool ext_KHR_portability_enumeration = false; // #395 + }; + + const Extensions& extensions() const { return extensions_; } + + VkInstance instance() const { return instance_; } + + void EnumeratePhysicalDevices(std::vector& physical_devices_out) const; + + private: + explicit VulkanInstance() = default; + + std::unique_ptr renderdoc_api_; + + rex::platform::DynamicLibrary loader_; + + Functions functions_; + + uint32_t api_version_ = VK_MAKE_API_VERSION(0, 1, 0, 0); + + Extensions extensions_; + + VkInstance instance_ = nullptr; + + static VkBool32 DebugUtilsMessengerCallback( + VkDebugUtilsMessageSeverityFlagBitsEXT message_severity, + VkDebugUtilsMessageTypeFlagsEXT message_types, + const VkDebugUtilsMessengerCallbackDataEXT* callback_data, void* user_data); + + VkDebugUtilsMessengerEXT debug_utils_messenger_ = VK_NULL_HANDLE; +}; + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/vulkan/linked_type_descriptor_set_allocator.h b/include/rex/ui/vulkan/linked_type_descriptor_set_allocator.h new file mode 100644 index 0000000..ce8aa72 --- /dev/null +++ b/include/rex/ui/vulkan/linked_type_descriptor_set_allocator.h @@ -0,0 +1,123 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace rex { +namespace ui { +namespace vulkan { + +// Allocates multiple descriptors of in descriptor set layouts consisting of +// descriptors of types specified during initialization. +// +// "LinkedType" means that the allocator is designed for allocating descriptor +// sets containing descriptors of multiple types together - for instance, it +// will mark the entire page as full even if no space is left in it for just one +// of the descriptor types (not all at once). +// +// The primary usage scenario for this kind of an allocator is allocating image +// and sampler descriptors in a single descriptor set if they both are actually +// used in one. It is expected that the ratio of the numbers of descriptors per +// type specified during the initialization will roughly correspond to the ratio +// of the numbers of descriptors that will actually be allocated. For instance, +// if there are approximately 2 images for each 1 sampler, it's recommended to +// make the image count per page twice the sampler count per page. +// +// If some allocations use just one type, and some use just another, completely +// independently, it's preferable to use separate allocators rather than a +// single one. +// +// This allocator is also suitable for allocating variable-length descriptor +// sets containing descriptors of just a single type. +// +// There's no way to free these descriptors within the allocator object itself, +// per-layout free lists should be used externally. +class LinkedTypeDescriptorSetAllocator { + public: + // Multiple descriptor sizes for the same descriptor type, and zero sizes, are + // not allowed. + explicit LinkedTypeDescriptorSetAllocator(const VulkanDevice* const vulkan_device, + const VkDescriptorPoolSize* const descriptor_sizes, + const uint32_t descriptor_size_count, + const uint32_t descriptor_sets_per_page) + : vulkan_device_(vulkan_device), + descriptor_pool_sizes_(new VkDescriptorPoolSize[descriptor_size_count]), + descriptor_pool_size_count_(descriptor_size_count), + descriptor_sets_per_page_(descriptor_sets_per_page) { + assert_not_null(vulkan_device); + assert_not_zero(descriptor_size_count); + assert_not_zero(descriptor_sets_per_page_); +#ifndef NDEBUG + for (uint32_t i = 0; i < descriptor_size_count; ++i) { + const VkDescriptorPoolSize& descriptor_size = descriptor_sizes[i]; + assert_not_zero(descriptor_size.descriptorCount); + for (uint32_t j = 0; j < i; ++j) { + assert_true(descriptor_sizes[j].type != descriptor_size.type); + } + } +#endif + std::memcpy(descriptor_pool_sizes_.get(), descriptor_sizes, + sizeof(VkDescriptorPoolSize) * descriptor_size_count); + } + LinkedTypeDescriptorSetAllocator(const LinkedTypeDescriptorSetAllocator& allocator) = delete; + LinkedTypeDescriptorSetAllocator& operator=(const LinkedTypeDescriptorSetAllocator& allocator) = + delete; + ~LinkedTypeDescriptorSetAllocator() { Reset(); } + + void Reset(); + + VkDescriptorSet Allocate(VkDescriptorSetLayout descriptor_set_layout, + const VkDescriptorPoolSize* descriptor_counts, + uint32_t descriptor_type_count); + + private: + struct Page { + VkDescriptorPool pool; + std::unique_ptr descriptors_remaining; + uint32_t descriptor_sets_remaining; + }; + + const VulkanDevice* vulkan_device_; + + std::unique_ptr descriptor_pool_sizes_; + uint32_t descriptor_pool_size_count_; + uint32_t descriptor_sets_per_page_; + + std::vector pages_full_; + // Because allocations must be contiguous, overflow may happen even if a page + // still has free descriptors, so multiple pages may have free space. + // To avoid removing and re-adding the page to the map that keeps them sorted + // (the key is the maximum number of free descriptors remaining across all + // types - and lookups need to be made with the maximum of the requested + // number of descriptors across all types since it's pointless to check the + // pages that can't even potentially fit the largest amount of descriptors of + // a requested type, and unlike using the minimum as the key, this doesn't + // degenerate if, for example, 0 descriptors are requested for some type - and + // it changes at every allocation from a page), instead of always looking for + // a free space in the map, maintaining one page outside the map, and + // allocation attempts will be made from that page first. + std::multimap pages_usable_; + // Doesn't exist if page_usable_latest_.pool == VK_NULL_HANDLE. + Page page_usable_latest_ = {}; +}; + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/vulkan/mem_alloc.h b/include/rex/ui/vulkan/mem_alloc.h new file mode 100644 index 0000000..4cd18b7 --- /dev/null +++ b/include/rex/ui/vulkan/mem_alloc.h @@ -0,0 +1,36 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Make sure vulkan.h is included from third_party (rather than from the system +// include directory) before vk_mem_alloc.h. + +#include + +#define VMA_STATIC_VULKAN_FUNCTIONS 0 +// Work around the pointer nullability completeness warnings on Clang. +#ifndef VMA_NULLABLE +#define VMA_NULLABLE +#endif +#ifndef VMA_NOT_NULL +#define VMA_NOT_NULL +#endif +#include + +namespace rex { +namespace ui { +namespace vulkan { + +VmaAllocator CreateVmaAllocator(const VulkanDevice* vulkan_device, bool externally_synchronized); + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/vulkan/presenter.h b/include/rex/ui/vulkan/presenter.h new file mode 100644 index 0000000..56ee43b --- /dev/null +++ b/include/rex/ui/vulkan/presenter.h @@ -0,0 +1,496 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace rex { +namespace ui { +namespace vulkan { + +class VulkanUIDrawContext final : public UIDrawContext { + public: + VulkanUIDrawContext(Presenter& presenter, uint32_t render_target_width, + uint32_t render_target_height, VkCommandBuffer draw_command_buffer, + uint64_t submission_index_current, uint64_t submission_index_completed, + VkRenderPass render_pass, VkFormat render_pass_format) + : UIDrawContext(presenter, render_target_width, render_target_height), + draw_command_buffer_(draw_command_buffer), + submission_index_current_(submission_index_current), + submission_index_completed_(submission_index_completed), + render_pass_(render_pass), + render_pass_format_(render_pass_format) {} + + VkCommandBuffer draw_command_buffer() const { return draw_command_buffer_; } + uint64_t submission_index_current() const { return submission_index_current_; } + uint64_t submission_index_completed() const { return submission_index_completed_; } + VkRenderPass render_pass() const { return render_pass_; } + VkFormat render_pass_format() const { return render_pass_format_; } + + private: + VkCommandBuffer draw_command_buffer_; + uint64_t submission_index_current_; + uint64_t submission_index_completed_; + // Has 1 subpass with a single render_pass_format_ attachment. + VkRenderPass render_pass_; + VkFormat render_pass_format_; +}; + +class VulkanPresenter final : public Presenter { + public: + // Maximum number of different guest output image versions still potentially + // considered alive that may be given to the refresher - this many instances + // of dependent objects (such as framebuffers) may need to be kept by the + // refresher across invocations (due to multiple-buffering of guest output + // images inside the presenter, different versions may be given even every + // invocation), to avoid recreation of dependent objects every frame. + static constexpr size_t kMaxActiveGuestOutputImageVersions = kGuestOutputMailboxSize; + + static constexpr VkFormat kGuestOutputFormat = VK_FORMAT_A2B10G10R10_UNORM_PACK32; + // The guest output is expected to be acquired and released in this state by + // the refresher. The exception is the first write to the current guest output + // image - in this case, a barrier is only needed from + // VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT without access. Also if the image is + // being refreshed for the first time, it's in VK_IMAGE_LAYOUT_UNDEFINED (but + // it's safe, and preferred, to transition it from VK_IMAGE_LAYOUT_UNDEFINED + // when writing to it in general). + static constexpr VkPipelineStageFlagBits kGuestOutputInternalStageMask = + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + static constexpr VkAccessFlags kGuestOutputInternalAccessMask = VK_ACCESS_SHADER_READ_BIT; + static constexpr VkImageLayout kGuestOutputInternalLayout = + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + // The callback must use the graphics and compute queue 0 of the device. + class VulkanGuestOutputRefreshContext final : public GuestOutputRefreshContext { + public: + VulkanGuestOutputRefreshContext(bool& is_8bpc_out_ref, VkImage image, VkImageView image_view, + uint64_t image_version, bool image_ever_written_previously) + : GuestOutputRefreshContext(is_8bpc_out_ref), + image_(image), + image_view_(image_view), + image_version_(image_version), + image_ever_written_previously_(image_ever_written_previously) {} + + // The format is kGuestOutputFormat. + // Supports usage as a color attachment and as a sampled image, as well as + // transfer source (but the reason of that is guest output capturing). + VkImage image() const { return image_; } + VkImageView image_view() const { return image_view_; } + uint64_t image_version() const { return image_version_; } + // Whether a proper barrier must be done to acquire the image. + bool image_ever_written_previously() const { return image_ever_written_previously_; } + + private: + VkImage image_; + VkImageView image_view_; + uint64_t image_version_; + bool image_ever_written_previously_; + }; + + static std::unique_ptr Create(HostGpuLossCallback host_gpu_loss_callback, + const VulkanDevice* vulkan_device, + const UISamplers* ui_samplers) { + auto presenter = std::unique_ptr( + new VulkanPresenter(host_gpu_loss_callback, vulkan_device, ui_samplers)); + if (!presenter->InitializeSurfaceIndependent()) { + return nullptr; + } + return presenter; + } + + ~VulkanPresenter(); + + const VulkanDevice* vulkan_device() const { return vulkan_device_; } + + static Surface::TypeFlags GetSurfaceTypesSupportedByInstance( + const VulkanInstance::Extensions& instance_extensions); + Surface::TypeFlags GetSupportedSurfaceTypes() const override; + + bool CaptureGuestOutput(RawImage& image_out) override; + + void AwaitUISubmissionCompletionFromUIThread(uint64_t submission_index) { + ui_submission_tracker_.AwaitSubmissionCompletion(submission_index); + } + VkCommandBuffer AcquireUISetupCommandBufferFromUIThread(); + + protected: + SurfacePaintConnectResult ConnectOrReconnectPaintingToSurfaceFromUIThread( + Surface& new_surface, uint32_t new_surface_width, uint32_t new_surface_height, + bool was_paintable, bool& is_vsync_implicit_out) override; + void DisconnectPaintingFromSurfaceFromUIThreadImpl() override; + + bool RefreshGuestOutputImpl(uint32_t mailbox_index, uint32_t frontbuffer_width, + uint32_t frontbuffer_height, + std::function refresher, + bool& is_8bpc_out_ref) override; + + PaintResult PaintAndPresentImpl(bool execute_ui_drawers) override; + + private: + // Usable for both the guest output image itself and for intermediate images. + class GuestOutputImage { + public: + static std::unique_ptr Create(const VulkanDevice* const vulkan_device, + const uint32_t width, const uint32_t height) { + assert_not_zero(width); + assert_not_zero(height); + auto image = + std::unique_ptr(new GuestOutputImage(vulkan_device, width, height)); + if (!image->Initialize()) { + return nullptr; + } + return std::move(image); + } + + GuestOutputImage(const GuestOutputImage& image) = delete; + GuestOutputImage& operator=(const GuestOutputImage& image) = delete; + ~GuestOutputImage(); + + const VkExtent2D& extent() const { return extent_; } + + VkImage image() const { return image_; } + VkDeviceMemory memory() const { return memory_; } + VkImageView view() const { return view_; } + + private: + GuestOutputImage(const VulkanDevice* const vulkan_device, const uint32_t width, + const uint32_t height) + : vulkan_device_(vulkan_device) { + extent_.width = width; + extent_.height = height; + } + + bool Initialize(); + + const VulkanDevice* vulkan_device_; + + VkExtent2D extent_; + VkImage image_ = VK_NULL_HANDLE; + VkDeviceMemory memory_ = VK_NULL_HANDLE; + VkImageView view_ = VK_NULL_HANDLE; + }; + + struct GuestOutputImageInstance { + // Refresher-side reference (painting has its own references for the purpose + // of destruction only after painting is done on the GPU). + std::shared_ptr image; + uint64_t version = UINT64_MAX; + uint64_t last_refresher_submission = 0; + // For choosing the barrier stage and access mask and layout depending on + // whether the image has previously been written. If an image is active + // after a refresh, it can be assumed that this is true. + bool ever_successfully_refreshed = false; + + void SetToNewImage(const std::shared_ptr& new_image, uint64_t new_version) { + image = new_image; + version = new_version; + last_refresher_submission = 0; + ever_successfully_refreshed = false; + } + }; + + struct GuestOutputPaintRectangleConstants { + union { + struct { + float x; + float y; + }; + float offset[2]; + }; + union { + struct { + float width; + float height; + }; + float size[2]; + }; + }; + + enum GuestOutputPaintPipelineLayoutIndex : size_t { + kGuestOutputPaintPipelineLayoutIndexBilinear, +#if defined(REX_HAS_FIDELITYFX_SDK) + kGuestOutputPaintPipelineLayoutIndexCasSharpen, + kGuestOutputPaintPipelineLayoutIndexCasResample, + kGuestOutputPaintPipelineLayoutIndexFsrEasu, + kGuestOutputPaintPipelineLayoutIndexFsrRcas, +#endif + + kGuestOutputPaintPipelineLayoutCount, + }; + + static constexpr GuestOutputPaintPipelineLayoutIndex GetGuestOutputPaintPipelineLayoutIndex( + GuestOutputPaintEffect effect) { + switch (effect) { + case GuestOutputPaintEffect::kBilinear: + case GuestOutputPaintEffect::kBilinearDither: + return kGuestOutputPaintPipelineLayoutIndexBilinear; +#if defined(REX_HAS_FIDELITYFX_SDK) + case GuestOutputPaintEffect::kCasSharpen: + case GuestOutputPaintEffect::kCasSharpenDither: + return kGuestOutputPaintPipelineLayoutIndexCasSharpen; + case GuestOutputPaintEffect::kCasResample: + case GuestOutputPaintEffect::kCasResampleDither: + return kGuestOutputPaintPipelineLayoutIndexCasResample; + case GuestOutputPaintEffect::kFsrEasu: + return kGuestOutputPaintPipelineLayoutIndexFsrEasu; + case GuestOutputPaintEffect::kFsrRcas: + case GuestOutputPaintEffect::kFsrRcasDither: + return kGuestOutputPaintPipelineLayoutIndexFsrRcas; +#endif + default: + assert_unhandled_case(effect); + return kGuestOutputPaintPipelineLayoutCount; + } + } + + struct PaintContext { + class Submission { + public: + static std::unique_ptr Create(const VulkanDevice* const vulkan_device) { + auto submission = std::unique_ptr(new Submission(vulkan_device)); + if (!submission->Initialize()) { + return nullptr; + } + return submission; + } + + Submission(const Submission& submission) = delete; + Submission& operator=(const Submission& submission) = delete; + ~Submission(); + + VkSemaphore acquire_semaphore() const { return acquire_semaphore_; } + VkSemaphore present_semaphore() const { return present_semaphore_; } + VkCommandPool draw_command_pool() const { return draw_command_pool_; } + VkCommandBuffer draw_command_buffer() const { return draw_command_buffer_; } + + private: + explicit Submission(const VulkanDevice* const vulkan_device) + : vulkan_device_(vulkan_device) {} + bool Initialize(); + + const VulkanDevice* vulkan_device_; + VkSemaphore acquire_semaphore_ = VK_NULL_HANDLE; + VkSemaphore present_semaphore_ = VK_NULL_HANDLE; + VkCommandPool draw_command_pool_ = VK_NULL_HANDLE; + VkCommandBuffer draw_command_buffer_ = VK_NULL_HANDLE; + }; + + static constexpr uint32_t kSubmissionCount = 3; + + struct GuestOutputPaintPipeline { + // Created on initialization. + VkPipeline intermediate_pipeline = VK_NULL_HANDLE; + // Created during guest output painting (after awaiting the last guest + // output paint if outdated and needs to be recreated), when needed, for + // the up-to-date render pass that draws to the swapchain with the actual + // image format. + VkPipeline swapchain_pipeline = VK_NULL_HANDLE; + VkFormat swapchain_format = VK_FORMAT_UNDEFINED; + }; + + enum GuestOutputDescriptorSet : uint32_t { + kGuestOutputDescriptorSetGuestOutput0Sampled, + + kGuestOutputDescriptorSetIntermediate0Sampled = + kGuestOutputDescriptorSetGuestOutput0Sampled + kGuestOutputMailboxSize, + + kGuestOutputDescriptorSetCount = + kGuestOutputDescriptorSetIntermediate0Sampled + kMaxGuestOutputPaintEffects - 1, + }; + + struct UISetupCommandBuffer { + UISetupCommandBuffer(VkCommandPool command_pool, VkCommandBuffer command_buffer, + uint64_t last_usage_submission_index = 0) + : command_pool(command_pool), + command_buffer(command_buffer), + last_usage_submission_index(last_usage_submission_index) {} + + VkCommandPool command_pool; + VkCommandBuffer command_buffer; + uint64_t last_usage_submission_index; + }; + + struct SwapchainFramebuffer { + SwapchainFramebuffer(VkImageView image_view, VkFramebuffer framebuffer) + : image_view(image_view), framebuffer(framebuffer) {} + + VkImageView image_view; + VkFramebuffer framebuffer; + }; + + explicit PaintContext(const VulkanDevice* const vulkan_device) + : vulkan_device(vulkan_device), submission_tracker(vulkan_device) {} + PaintContext(const PaintContext& paint_context) = delete; + PaintContext& operator=(const PaintContext& paint_context) = delete; + + // The old swapchain, if passed, should be assumed to be retired after this + // call (though it may fail before the vkCreateSwapchainKHR that will + // technically retire it, so it will be in an undefined state), and needs to + // be destroyed externally no matter what the result is. + static VkSwapchainKHR CreateSwapchainForVulkanSurface( + const VulkanDevice* vulkan_device, VkSurfaceKHR surface, uint32_t width, uint32_t height, + VkSwapchainKHR old_swapchain, uint32_t& present_queue_family_out, + VkFormat& image_format_out, VkExtent2D& image_extent_out, bool& is_fifo_out, + bool& ui_surface_unusable_out); + + // Destroys the swapchain and its derivatives, nulls `swapchain` and returns + // the original swapchain object, if it existed, for use as oldSwapchain if + // needed and for destruction. + VkSwapchainKHR PrepareForSwapchainRetirement(); + // May be called from the destructor of the presenter. + void DestroySwapchainAndVulkanSurface(); + + // Connection-indepedent. + + const VulkanDevice* vulkan_device; + + std::array, kSubmissionCount> submissions; + VulkanSubmissionTracker submission_tracker; + + std::array + guest_output_paint_pipelines; + + VkDescriptorPool guest_output_descriptor_pool = VK_NULL_HANDLE; + // Descriptors are updated while painting if they're out of date. + VkDescriptorSet guest_output_descriptor_sets[kGuestOutputDescriptorSetCount]; + + // Refreshed and cleaned up during guest output painting. The first is the + // paint submission index in which the guest output image (and its + // descriptors) was last used, the second is the reference to the image, + // which may be null. The indices are not mailbox indices here, rather, if + // the reference is not in this array yet, the most outdated reference, if + // needed, is replaced with the new one, awaiting the usage completion of + // the last paint usage. + std::array>, kGuestOutputMailboxSize> + guest_output_image_paint_refs; + // The latest submission index at which any guest output image was drawn. + uint64_t guest_output_image_paint_last_submission = 0; + + // Current intermediate images for guest output painting, refreshed when + // painting guest output. + std::array, kMaxGuestOutputPaintEffects - 1> + guest_output_intermediate_images; + // Created and destroyed alongside the images. UNORM only. + std::array + guest_output_intermediate_framebuffers = {}; + uint64_t guest_output_intermediate_image_last_submission = 0; + + // Command buffers optionally executed before the draw command buffer, + // outside the painting render pass. + std::vector ui_setup_command_buffers; + size_t ui_setup_command_buffer_current_index = SIZE_MAX; + + // Connection-specific. + + // May be reused between connections if the format stays the same. + VkRenderPass swapchain_render_pass = VK_NULL_HANDLE; + VkFormat swapchain_render_pass_format = VK_FORMAT_UNDEFINED; + bool swapchain_render_pass_clear_load_op = false; + + VkSurfaceKHR vulkan_surface = VK_NULL_HANDLE; + uint32_t present_queue_family = UINT32_MAX; + VkSwapchainKHR swapchain = VK_NULL_HANDLE; + VkExtent2D swapchain_extent = {}; + bool swapchain_is_fifo = false; + std::vector swapchain_images; + std::vector swapchain_framebuffers; + }; + + explicit VulkanPresenter(HostGpuLossCallback host_gpu_loss_callback, + const VulkanDevice* vulkan_device, const UISamplers* ui_samplers) + : Presenter(host_gpu_loss_callback), + vulkan_device_(vulkan_device), + ui_samplers_(ui_samplers), + guest_output_image_refresher_submission_tracker_(vulkan_device), + ui_submission_tracker_(vulkan_device), + paint_context_(vulkan_device) { + assert_not_null(vulkan_device); + assert_not_null(ui_samplers); + } + + bool InitializeSurfaceIndependent(); + + [[nodiscard]] VkPipeline CreateGuestOutputPaintPipeline(GuestOutputPaintEffect effect, + VkRenderPass render_pass); + +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME + bool EnsureTemporalUpscalerContext(uint32_t render_width, uint32_t render_height, + uint32_t output_width, uint32_t output_height); + bool DispatchTemporalUpscaler(VkCommandBuffer command_buffer, VkImage input_image, + uint32_t input_width, uint32_t input_height, VkImage output_image, + uint32_t output_width, uint32_t output_height, + const GuestOutputPaintConfig& config); + void DestroyTemporalUpscalerContext(); +#endif + + const VulkanDevice* vulkan_device_; + const UISamplers* ui_samplers_; + + // Static objects for guest output presentation, used only when painting the + // main target (can be destroyed only after awaiting main target usage + // completion). + VkDescriptorSetLayout guest_output_paint_image_descriptor_set_layout_ = VK_NULL_HANDLE; + std::array + guest_output_paint_pipeline_layouts_ = {}; + VkShaderModule guest_output_paint_vs_ = VK_NULL_HANDLE; + std::array guest_output_paint_fs_ = {}; + // Not compatible with the swapchain render pass even if the format is the + // same due to different dependencies (this is shader read > color + // attachment > shader read). + VkRenderPass guest_output_intermediate_render_pass_ = VK_NULL_HANDLE; + + // Value monotonically increased every time a new guest output image is + // initialized, for recreation of dependent objects such as framebuffers in + // the refreshers - saving and comparing the handle in the refresher is not + // enough as Create > Destroy > Create may result in the same handle for + // actually different objects without the refresher being aware of the + // destruction. + uint64_t guest_output_image_next_version_ = 0; + std::array guest_output_images_; + VulkanSubmissionTracker guest_output_image_refresher_submission_tracker_; + + // UI submission tracker with the submission index that can be given to UI + // drawers (accessible from the UI thread only, at any time). + VulkanSubmissionTracker ui_submission_tracker_; + + // Accessible only by painting and by surface connection lifetime management + // (ConnectOrReconnectPaintingToSurfaceFromUIThread, + // DisconnectPaintingFromSurfaceFromUIThreadImpl) by the thread doing it, as + // well as by presenter initialization and shutdown. + PaintContext paint_context_; + +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME + void* temporal_upscaler_context_ = nullptr; + uint32_t temporal_upscaler_max_render_width_ = 0; + uint32_t temporal_upscaler_max_render_height_ = 0; + uint32_t temporal_upscaler_max_output_width_ = 0; + uint32_t temporal_upscaler_max_output_height_ = 0; + bool temporal_upscaler_provider_logged_ = false; +#endif +}; + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/vulkan/provider.h b/include/rex/ui/vulkan/provider.h new file mode 100644 index 0000000..3d603f5 --- /dev/null +++ b/include/rex/ui/vulkan/provider.h @@ -0,0 +1,54 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include + +namespace rex { +namespace ui { +namespace vulkan { + +class VulkanProvider : public GraphicsProvider { + public: + static std::unique_ptr Create(bool with_gpu_emulation, bool with_presentation); + + VulkanInstance* vulkan_instance() const { return vulkan_instance_.get(); } + + VulkanDevice* vulkan_device() const { return vulkan_device_.get(); } + + // nullptr if created without presentation support. + const UISamplers* ui_samplers() const { return ui_samplers_.get(); } + + std::unique_ptr CreatePresenter(Presenter::HostGpuLossCallback host_gpu_loss_callback = + Presenter::FatalErrorHostGpuLossCallback) override; + + std::unique_ptr CreateImmediateDrawer() override; + + private: + explicit VulkanProvider() = default; + + std::unique_ptr vulkan_instance_; + + // Depends on the instance. + std::unique_ptr vulkan_device_; + + // Depends on the device. + std::unique_ptr ui_samplers_; +}; + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/vulkan/single_layout_descriptor_set_pool.h b/include/rex/ui/vulkan/single_layout_descriptor_set_pool.h new file mode 100644 index 0000000..3bc4785 --- /dev/null +++ b/include/rex/ui/vulkan/single_layout_descriptor_set_pool.h @@ -0,0 +1,60 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include + +namespace rex { +namespace ui { +namespace vulkan { + +class SingleLayoutDescriptorSetPool { + public: + // set_layout_descriptor_counts must contain the numbers of descriptors of + // each type in a single set with the layout (the multiplication by the pool + // set count will be done internally). The descriptor set layout must not be + // destroyed until this object is also destroyed. + SingleLayoutDescriptorSetPool(const VulkanDevice* vulkan_device, uint32_t pool_set_count, + uint32_t set_layout_descriptor_counts_count, + const VkDescriptorPoolSize* set_layout_descriptor_counts, + VkDescriptorSetLayout set_layout); + ~SingleLayoutDescriptorSetPool(); + + // Returns SIZE_MAX in case of a failure. + size_t Allocate(); + void Free(size_t index) { + assert_true(index < descriptor_sets_.size()); + descriptor_sets_free_.push_back(index); + } + VkDescriptorSet Get(size_t index) const { return descriptor_sets_[index]; } + + private: + const VulkanDevice* vulkan_device_; + uint32_t pool_set_count_; + std::vector pool_descriptor_counts_; + VkDescriptorSetLayout set_layout_; + + std::vector full_pools_; + VkDescriptorPool current_pool_ = VK_NULL_HANDLE; + uint32_t current_pool_sets_remaining_ = 0; + + std::vector descriptor_sets_; + std::vector descriptor_sets_free_; +}; + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/vulkan/spirv_tools_context.h b/include/rex/ui/vulkan/spirv_tools_context.h new file mode 100644 index 0000000..e572b90 --- /dev/null +++ b/include/rex/ui/vulkan/spirv_tools_context.h @@ -0,0 +1,53 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include + +#include + +namespace rex { +namespace ui { +namespace vulkan { + +class SpirvToolsContext { + public: + SpirvToolsContext() {} + SpirvToolsContext(const SpirvToolsContext& context) = delete; + SpirvToolsContext& operator=(const SpirvToolsContext& context) = delete; + ~SpirvToolsContext() { Shutdown(); } + bool Initialize(unsigned int spirv_version); + void Shutdown(); + + spv_result_t Validate(const uint32_t* words, size_t num_words, std::string* error) const; + + private: + rex::platform::DynamicLibrary library_; + + template + bool LoadLibraryFunction(FunctionPointer& function, const char* name) { + function = library_.GetSymbol(name); + return function != nullptr; + } + decltype(&spvContextCreate) fn_spvContextCreate_ = nullptr; + decltype(&spvContextDestroy) fn_spvContextDestroy_ = nullptr; + decltype(&spvValidateBinary) fn_spvValidateBinary_ = nullptr; + decltype(&spvDiagnosticDestroy) fn_spvDiagnosticDestroy_ = nullptr; + + spv_context context_ = nullptr; +}; + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/vulkan/submission_tracker.h b/include/rex/ui/vulkan/submission_tracker.h new file mode 100644 index 0000000..505b599 --- /dev/null +++ b/include/rex/ui/vulkan/submission_tracker.h @@ -0,0 +1,133 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include +#include + +namespace rex { +namespace ui { +namespace vulkan { + +// Fence wrapper, safely handling cases when the fence has not been initialized +// yet or has already been shut down, and failed or dropped submissions. +// +// The current submission index can be associated with the usage of objects to +// release them when the GPU isn't potentially referencing them anymore, and +// should be incremented only +// +// 0 can be used as a "never referenced" submission index. +// +// The submission index timeline survives Shutdown, so submission indices can be +// given to clients that are not aware of the lifetime of the tracker. +// +// To transfer the tracker to another queue (to make sure the first signal on +// the new queue does not happen before the last signal on the old one), call +// AwaitAllSubmissionsCompletion before doing the first submission on the new +// one. +class VulkanSubmissionTracker { + public: + class FenceAcquisition { + public: + FenceAcquisition() : submission_tracker_(nullptr), fence_(VK_NULL_HANDLE) {} + FenceAcquisition(VulkanSubmissionTracker& submission_tracker, VkFence fence) + : submission_tracker_(&submission_tracker), fence_(fence) {} + FenceAcquisition(const FenceAcquisition& fence_acquisition) = delete; + FenceAcquisition& operator=(const FenceAcquisition& fence_acquisition) = delete; + FenceAcquisition(FenceAcquisition&& fence_acquisition) { *this = std::move(fence_acquisition); } + FenceAcquisition& operator=(FenceAcquisition&& fence_acquisition) { + if (this == &fence_acquisition) { + return *this; + } + submission_tracker_ = fence_acquisition.submission_tracker_; + fence_acquisition.submission_tracker_ = nullptr; + fence_ = fence_acquisition.fence_; + fence_acquisition.fence_ = VK_NULL_HANDLE; + return *this; + } + ~FenceAcquisition(); + + // In unsignaled state. May be null if failed to create or to reset a fence. + VkFence fence() { return fence_; } + + // Call if vkQueueSubmit has failed (or it was decided not to commit the + // submission), and the submission index shouldn't be incremented by + // releasing this submission (for instance, to retry commands with long-term + // effects like copying or image layout changes later if in the attempt the + // submission index stays the same). + void SubmissionFailedOrDropped(); + // Call if for some reason (like signaling multiple fences) the fence + // signaling was done in a separate submission than the command buffer, and + // the command buffer vkQueueSubmit succeeded (so commands with long-term + // effects will be executed), but the fence-only vkQueueSubmit has failed, + // thus the tracker shouldn't attempt to wait for that fence (it will be in + // the unsignaled state). + void SubmissionSucceededSignalFailed() { signal_failed_ = true; } + + private: + // If nullptr, has been moved to another FenceAcquisition - not holding a + // fence from now on. + VulkanSubmissionTracker* submission_tracker_; + VkFence fence_; + bool signal_failed_ = false; + }; + + VulkanSubmissionTracker(const VulkanDevice* vulkan_device) : vulkan_device_(vulkan_device) { + assert_not_null(vulkan_device); + } + + VulkanSubmissionTracker(const VulkanSubmissionTracker& submission_tracker) = delete; + VulkanSubmissionTracker& operator=(const VulkanSubmissionTracker& submission_tracker) = delete; + + ~VulkanSubmissionTracker() { Shutdown(); } + + void Shutdown(); + + uint64_t GetCurrentSubmission() const { return submission_current_; } + uint64_t UpdateAndGetCompletedSubmission(); + + // Returns whether the expected GPU signal has actually been reached (rather + // than some fallback condition) for cases when stronger completeness + // guarantees as needed (when downloading, as opposed to just destroying). + // If false is returned, it's also not guaranteed that GetCompletedSubmission + // will return a value >= submission_index. + bool AwaitSubmissionCompletion(uint64_t submission_index); + bool AwaitAllSubmissionsCompletion() { + return AwaitSubmissionCompletion(submission_current_ - 1); + } + + [[nodiscard]] FenceAcquisition AcquireFenceToAdvanceSubmission(); + + private: + const VulkanDevice* vulkan_device_; + uint64_t submission_current_ = 1; + // Last submission with a successful fence signal as well as a successful + // fence wait / query. + uint64_t submission_completed_on_gpu_ = 0; + // The flow is: + // Reclaimed (or create if empty) > acquired > pending > reclaimed. + // Or, if dropped the submission while acquired: + // Reclaimed (or create if empty) > acquired > reclaimed. + VkFence fence_acquired_ = VK_NULL_HANDLE; + // Ordered by the submission index (the first pair member). + std::deque> fences_pending_; + // Fences are reclaimed when awaiting or when refreshing the completed value. + std::vector fences_reclaimed_; +}; + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/vulkan/ui_samplers.h b/include/rex/ui/vulkan/ui_samplers.h new file mode 100644 index 0000000..f6fa365 --- /dev/null +++ b/include/rex/ui/vulkan/ui_samplers.h @@ -0,0 +1,59 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include + +namespace rex { +namespace ui { +namespace vulkan { + +/// Samplers that can be used for presentation and UI drawing. +/// Because maxSamplerAllocationCount can be as low as 4000 (on Nvidia and Intel +/// GPUs primarily), no other samplers must be created for UI purposes. +/// The rest of the sampler allocation space on the device must be available to +/// GPU emulation. +class UISamplers { + public: + static std::unique_ptr Create(const VulkanDevice* vulkan_device); + + UISamplers(const UISamplers&) = delete; + UISamplers& operator=(const UISamplers&) = delete; + UISamplers(UISamplers&&) = delete; + UISamplers& operator=(UISamplers&&) = delete; + + ~UISamplers(); + + enum SamplerIndex { + kSamplerIndexNearestRepeat, + kSamplerIndexNearestClampToEdge, + kSamplerIndexLinearRepeat, + kSamplerIndexLinearClampToEdge, + + kSamplerCount, + }; + + const std::array& samplers() const { return samplers_; } + + private: + explicit UISamplers(const VulkanDevice* vulkan_device); + + const VulkanDevice* vulkan_device_; + + std::array samplers_; +}; + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/vulkan/upload_buffer_pool.h b/include/rex/ui/vulkan/upload_buffer_pool.h new file mode 100644 index 0000000..4b9fb3d --- /dev/null +++ b/include/rex/ui/vulkan/upload_buffer_pool.h @@ -0,0 +1,60 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +namespace rex { +namespace ui { +namespace vulkan { + +class VulkanUploadBufferPool : public GraphicsUploadBufferPool { + public: + VulkanUploadBufferPool(const VulkanDevice* vulkan_device, VkBufferUsageFlags usage, + size_t page_size = kDefaultPageSize); + + uint8_t* Request(uint64_t submission_index, size_t size, size_t alignment, VkBuffer& buffer_out, + VkDeviceSize& offset_out); + uint8_t* RequestPartial(uint64_t submission_index, size_t size, size_t alignment, + VkBuffer& buffer_out, VkDeviceSize& offset_out, VkDeviceSize& size_out); + + protected: + Page* CreatePageImplementation() override; + + void FlushPageWrites(Page* page, size_t offset, size_t size) override; + + private: + struct VulkanPage : public Page { + // Takes ownership of the buffer and its memory and mapping. + VulkanPage(const VulkanDevice* vulkan_device, VkBuffer buffer, VkDeviceMemory memory, + void* mapping) + : vulkan_device_(vulkan_device), buffer_(buffer), memory_(memory), mapping_(mapping) {} + ~VulkanPage() override; + const VulkanDevice* vulkan_device_; + VkBuffer buffer_; + VkDeviceMemory memory_; + void* mapping_; + }; + + const VulkanDevice* vulkan_device_; + + VkDeviceSize allocation_size_; + static constexpr uint32_t kMemoryTypeUnknown = UINT32_MAX; + static constexpr uint32_t kMemoryTypeUnavailable = kMemoryTypeUnknown - 1; + uint32_t memory_type_ = UINT32_MAX; + + VkBufferUsageFlags usage_; +}; + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/vulkan/util.h b/include/rex/ui/vulkan/util.h new file mode 100644 index 0000000..27a5136 --- /dev/null +++ b/include/rex/ui/vulkan/util.h @@ -0,0 +1,167 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include + +namespace rex { +namespace ui { +namespace vulkan { +namespace util { + +template +inline bool DestroyAndNullHandle(DestroyFunction* const destroy_function, Object& handle) { + if (handle != VK_NULL_HANDLE) { + destroy_function(handle, nullptr); + handle = VK_NULL_HANDLE; + return true; + } + return false; +} + +template +inline bool DestroyAndNullHandle(DestroyFunction* const destroy_function, const Parent parent, + Object& handle) { + if (handle != VK_NULL_HANDLE) { + destroy_function(parent, handle, nullptr); + handle = VK_NULL_HANDLE; + return true; + } + return false; +} + +enum class MemoryPurpose { + kDeviceLocal, + kUpload, + kReadback, +}; + +inline uint32_t ChooseHostMemoryType(const VulkanDevice::MemoryTypes& memory_types, + uint32_t supported_types, const bool is_readback) { + supported_types &= memory_types.host_visible; + uint32_t memory_type; + // For upload, uncached is preferred so writes do not pollute the CPU cache. + // For readback, cached is preferred so multiple CPU reads are fast. + // If the preferred caching behavior is not available, pick any host-visible. + if (rex::bit_scan_forward( + supported_types & (is_readback ? memory_types.host_cached : ~memory_types.host_cached), + &memory_type) || + rex::bit_scan_forward(supported_types, &memory_type)) { + return memory_type; + } + return UINT32_MAX; +} + +inline uint32_t ChooseMemoryType(const VulkanDevice::MemoryTypes& memory_types, + const uint32_t supported_types, const MemoryPurpose purpose) { + switch (purpose) { + case MemoryPurpose::kDeviceLocal: { + uint32_t memory_type; + if (rex::bit_scan_forward(supported_types & memory_types.device_local, &memory_type)) { + return memory_type; + } + if (rex::bit_scan_forward(supported_types, &memory_type)) { + return memory_type; + } + return UINT32_MAX; + } break; + case MemoryPurpose::kUpload: + case MemoryPurpose::kReadback: + return ChooseHostMemoryType(memory_types, supported_types, + purpose == MemoryPurpose::kReadback); + default: + assert_unhandled_case(purpose); + return UINT32_MAX; + } +} + +// Actual memory size is required if explicit size is specified for clamping to +// the actual memory allocation size while rounding to the non-coherent atom +// size (offset + size passed to vkFlushMappedMemoryRanges inside this function +// must be either a multiple of nonCoherentAtomSize (but not exceeding the +// memory size) or equal to the memory size). +void FlushMappedMemoryRange(const VulkanDevice* vulkan_device, VkDeviceMemory memory, + uint32_t memory_type, VkDeviceSize offset = 0, + VkDeviceSize memory_size = VK_WHOLE_SIZE, + VkDeviceSize size = VK_WHOLE_SIZE); + +inline VkExtent2D GetMax2DFramebufferExtent(const VulkanDevice::Properties& device_properties) { + VkExtent2D max_extent; + max_extent.width = + std::min(device_properties.maxFramebufferWidth, device_properties.maxImageDimension2D); + max_extent.height = + std::min(device_properties.maxFramebufferHeight, device_properties.maxImageDimension2D); + return max_extent; +} + +inline VkImageSubresourceRange InitializeSubresourceRange( + const VkImageAspectFlags aspect_mask = VK_IMAGE_ASPECT_COLOR_BIT, + const uint32_t base_mip_level = 0, const uint32_t level_count = VK_REMAINING_MIP_LEVELS, + const uint32_t base_array_layer = 0, const uint32_t layer_count = VK_REMAINING_ARRAY_LAYERS) { + VkImageSubresourceRange range; + range.aspectMask = aspect_mask; + range.baseMipLevel = base_mip_level; + range.levelCount = level_count; + range.baseArrayLayer = base_array_layer; + range.layerCount = layer_count; + return range; +} + +// Creates a buffer backed by a dedicated allocation. The allocation size will +// NOT be aligned to nonCoherentAtomSize - if mapping or flushing not the whole +// size, memory_size_out must be used for clamping the range. +bool CreateDedicatedAllocationBuffer(const VulkanDevice* vulkan_device, VkDeviceSize size, + VkBufferUsageFlags usage, MemoryPurpose memory_purpose, + VkBuffer& buffer_out, VkDeviceMemory& memory_out, + uint32_t* memory_type_out = nullptr, + VkDeviceSize* memory_size_out = nullptr); + +bool CreateDedicatedAllocationImage(const VulkanDevice* vulkan_device, + const VkImageCreateInfo& create_info, + MemoryPurpose memory_purpose, VkImage& image_out, + VkDeviceMemory& memory_out, uint32_t* memory_type_out = nullptr, + VkDeviceSize* memory_size_out = nullptr); + +// Explicitly accepting const uint32_t* to make sure attention is paid to the +// alignment where this is called for safety on different host architectures. +inline VkShaderModule CreateShaderModule(const VulkanDevice* const vulkan_device, + const uint32_t* const code, const size_t code_size_bytes) { + VkShaderModuleCreateInfo shader_module_create_info; + shader_module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + shader_module_create_info.pNext = nullptr; + shader_module_create_info.flags = 0; + shader_module_create_info.codeSize = code_size_bytes; + shader_module_create_info.pCode = code; + VkShaderModule shader_module; + return vulkan_device->functions().vkCreateShaderModule(vulkan_device->device(), + &shader_module_create_info, nullptr, + &shader_module) == VK_SUCCESS + ? shader_module + : VK_NULL_HANDLE; +} + +VkPipeline CreateComputePipeline(const VulkanDevice* vulkan_device, VkPipelineLayout layout, + VkShaderModule shader, + const VkSpecializationInfo* specialization_info = nullptr, + const char* entry_point = "main"); +VkPipeline CreateComputePipeline(const VulkanDevice* vulkan_device, VkPipelineLayout layout, + const uint32_t* shader_code, size_t shader_code_size_bytes, + const VkSpecializationInfo* specialization_info = nullptr, + const char* entry_point = "main"); + +} // namespace util +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/window.h b/include/rex/ui/window.h new file mode 100644 index 0000000..4bf2d7c --- /dev/null +++ b/include/rex/ui/window.h @@ -0,0 +1,702 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex { +namespace ui { + +class Window { + public: + // Transitions between these phases is sequential and looped (and >= and <= + // can be used for openness checks, for closedness checks ! of >= and <= is + // needed due to looping), with the exception of kDeleting that may be entered + // from any other state (with an assertion for that not being done during + // kOpening though as that's extremely dangerous and would require a lot of + // handling in OpenImpl on all platforms) as the Window object may be deleted + // externally at any moment, and the Window will have no control anymore when + // that happens. Another exception is that the window may be closed in the + // platform during kOpening - in this case, it will skip kOpenBeforeClosing + // and go directly to kClosing and beyond. + enum class Phase { + // The window hasn't been opened yet, or has been fully closed and can be + // reopened. + // No native window - external state updates change only the desired state, + // don't go to the implementation immediately. + // No actual state. + // Listeners are not called. + kClosedOpenable, + // OpenImpl is being invoked, the implementation is performing initial + // setup. + // External state changes are functionally near-impossible as OpenImpl + // mostly isn't able to communicate with external Xenia code that may have + // any effect on the Window, to avoid interference during the native window + // setup which may be pretty complex - and also, this is the phase in which + // the native window is being created, so there's no guarantee that the + // native window exists throughout this phase. + // However, it's still not strictly enforceable that OpenImpl will not cause + // any interaction with the Window - it may happen, for instance, if + // OpenImpl causes the OS to execute the pending functions in the + // WindowedAppContext that might have been, for example, left over from when + // the window was still open last time. Therefore, for the reason of state + // consistency within OpenImpl, all external state changes are simply + // dropped in this phase. + // However, the desired state may be updated by the implementation during + // OpenImpl still, but via the Update functions (if the implementation or + // the OS, for instance, clamps the size of the window during creation, or + // refuses to enter fullscreen). + // Actual state is first populated during this phase, and it's readable + // (with its level of completeness at the specific point in time) for the + // internal purposes of the implementation. + // Listeners are not called so the implementation can perform all the setup + // without outer interference (the common code calls some to let the + // listeners be aware of the initial state when the window enters kOpen + // anyway). + // Note: Closing may occur in the platform during kOpening - skip + // kOpenBeforeClosing in this case while closing. + kOpening, + // Fully interactive. + // The native window exists, external state changes are applied immediately + // (or at least immediately requested to be applied shortly after, but the + // implementation must make sure that, for instance, if SetFullscreen is + // successfully called, but the window will actually enter fullscreen only + // at the next platform event loop tick, IsFullscreen will start returning + // true immediately). + // The desired state can be updated as feedback from the implementation. + // Actual state can be retrieved. + // Listeners are called. + // The only state in which a non-null Surface can be created (it's destroyed + // after entering kClosing). + kOpen, + // OnBeforeClose is being invoked. + // The native window still exists, this is mostly like kOpen, but with no + // way of creating a Surface (it's becoming destroyed in this state so the + // native window can be destroyed safely in the next phase) or recursively + // requesting closing - for consistency during closing within the platform, + // state changes also behave like in kOpen. + // Listeners are still called as normal, primarily because this is where the + // OnClosing listener function is invoked, but reopening the window from a + // listener is not possible for state consistency during closing. + kOpenBeforeClosing, + // OnBeforeClose has completed, but OnAfterClose hasn't been called yet for + // the implementation to confirm that it has finished destroying the native + // window being closed. This state exists to prevent the situation in which + // the Window is somehow reopened in the middle of the implementation's + // internal work in closing. + // The implementation must detach from the native window and destroy it in + // this phase. + // The native window is being destroyed - external state updates change only + // the desired state, don't go to the implementation immediately. + // Actual state is still queryable for internal purposes of the + // implementation. + // Listeners are not called. + kClosing, + // OnBeforeClose has completed, but the close has occurred from a listener, + // and the call stack of listeners still hasn't been exited. + // This state exists to prevent the situation in which the Window is being + // closed and then reopened in the middle of the implementation's internal + // work in event handlers. For example, let's assume putting a window (HWND) + // in the fullscreen state requires removing window decorations + // (SetWindowLong) and resizing the window (SetWindowPos), both being able + // to invoke the resize handler (WM_SIZE) and thus the resize listener. In + // this case, consider the following situation: + // - SetWindowLong called for HWND. + // - WM_SIZE arrives. + // - Listener's OnResize called. + // - Listener's OnResize does RequestClose, destroying the current HWND. + // - Listener's OnResize does Open, creating a new HWND. + // - SetWindowPos called for HWND, which is different now. + // Here, SetWindowLong will be called for one native window, but then it + // will be replaced, and SetWindowPos will be called for a different one. + // No native window - external state updates change only the desired state, + // don't go to the implementation immediately. + // No actual state. + // Listeners are not called. + kClosedLeavingListeners, + // The destructor has been called - should transition into this before doing + // anything not only in the common, but in the implementation's destructor + // as well. The transition must be done regardless of the previous phase as + // there's no way the Window can stop its destruction from now on. This is + // mostly similar to kClosedLeavingListeners, except there's no way to leave + // this phase. + kDeleting, + }; + + enum class CursorVisibility { + kVisible, + // Temporarily revealed, hidden if not interacting with the mouse. + kAutoHidden, + kHidden, + }; + + static std::unique_ptr Create(WindowedAppContext& app_context, + const std::string_view title, + uint32_t desired_logical_width, + uint32_t desired_logical_height); + + virtual ~Window(); + + WindowedAppContext& app_context() const { return app_context_; } + + Phase phase() const { return phase_; } + bool HasActualState() const { + // kOpening - for internal use by the implementation. + // kOpen, kOpenBeforeClosing - for both external and internal use. + // kClosing - for internal use by the implementation. + return phase_ >= Phase::kOpening && phase_ <= Phase::kClosing; + } + + void AddListener(WindowListener* listener); + void RemoveListener(WindowListener* listener); + void AddInputListener(WindowInputListener* listener, size_t z_order); + void RemoveInputListener(WindowInputListener* listener); + + // `false` is returned only in case of an error while trying to perform the + // platform window opening. If the window is already open, or just can't be + // reopened in the current phase (as in this case it's assumed that the outer + // will handle this situation properly and won't, for instance, leave a + // process without windows - it will quit the application in OnBeforeClose of + // the window closing of which was initiated before or even during opening, + // for instance), `true` is returned. The functions of WindowListeners will be + // called only for a newly opened platform window - and the listeners may + // close or even destroy the window, in which case this function will still + // return `true` to differentiate from an actual error - if it's really + // necessary that the platform window is open after the call, check phase() + // after calling. + bool Open(); + // The call may or may not close the window immediately, depending on the + // platform (phase() may still return an open phase, and events may still be + // sent after the call). Use phase() to check if closing has actually + // happened immediately. + void RequestClose() { + // Don't allow external close requests during opening for state consistency + // inside OpenImpl (if an internal close happens during OpenImpl, the + // implementation will be aware of that at least), and don't allow closing + // twice. + if (phase_ != Phase::kOpen) { + return; + } + RequestCloseImpl(); + // Must not doing anything else with *this as callbacks might have been + // triggered during closing (if it has actually even happened), and the + // Window might have been deleted. + } + + // The `public` state setters are for calling from outside. + // The implementation must use the public getters to obtain the desired state + // while applying, but for updating the actual state, or for overriding the + // desired state, the `protected` On*Update functions must be used (overall + // the On* functions are for the implementation's feedback). + + virtual uint32_t GetMediumDpi() const { return 96; } + uint32_t GetDpi() const { + uint32_t dpi = GetLatestDpiImpl(); + return dpi ? dpi : GetMediumDpi(); + } + + // Round trips are not guaranteed to return the same results. + static constexpr uint32_t ConvertSizeDpi(uint32_t size, uint32_t new_dpi, uint32_t old_dpi) { + // Always rounding up to prevent zero sizes (unless the input is zero) as + // well as gaps at the edge. + return uint32_t((uint64_t(size) * new_dpi + (old_dpi - 1)) / old_dpi); + } + uint32_t SizeToLogical(uint32_t size) const { + return ConvertSizeDpi(size, GetMediumDpi(), GetDpi()); + } + uint32_t SizeToPhysical(uint32_t size) const { + return ConvertSizeDpi(size, GetDpi(), GetMediumDpi()); + } + static constexpr int32_t ConvertPositionDpi(int32_t position, uint32_t new_dpi, + uint32_t old_dpi) { + // Rounding to the nearest mostly similar to Windows MulDiv. + // Plus old_dpi / 2 for positive values, minus old_dpi / 2 for negative + // values for consistent rounding for both positive and negative values (as + // the `/` operator rounds towards zero). + // Example: + // (-3 - 1) / 3 == -1 + // (-2 - 1) / 3 == -1 + // (-1 - 1) / 3 == 0 + // --- + // (0 + 1) / 3 == 0 + // (1 + 1) / 3 == 0 + // (2 + 1) / 3 == 1 + return int32_t((int64_t(position) * new_dpi + int32_t(old_dpi >> 1) * (position < 0 ? -1 : 1)) / + old_dpi); + } + int32_t PositionToLogical(int32_t position) const { + return ConvertPositionDpi(position, GetMediumDpi(), GetDpi()); + } + int32_t PositionToPhysical(int32_t position) const { + return ConvertPositionDpi(position, GetDpi(), GetMediumDpi()); + } + + // The desired logical size of the window when it's not maximized, regardless + // of the current state of the window (maximized, fullscreen, etc.) + // The implementation may update it, for instance, to clamp it, or when the + // user resizes a non-maximized window. + uint32_t GetDesiredLogicalWidth() const { return desired_logical_width_; } + uint32_t GetDesiredLogicalHeight() const { return desired_logical_height_; } + + // 0 width or height may be returned even in case of an open window with a + // valid non-zero-area surface depending on the platform. + uint32_t GetActualPhysicalWidth() const { return HasActualState() ? actual_physical_width_ : 0; } + uint32_t GetActualPhysicalHeight() const { + return HasActualState() ? actual_physical_height_ : 0; + } + uint32_t GetActualLogicalWidth() const { return SizeToLogical(GetActualPhysicalWidth()); } + uint32_t GetActualLogicalHeight() const { return SizeToLogical(GetActualPhysicalHeight()); } + + // Desired state stored by the common Window, modifiable both externally and + // by the implementation (including from SetFullscreen itself). + bool IsFullscreen() const { return fullscreen_; } + void SetFullscreen(bool new_fullscreen); + + // Desired state stored by the common Window, externally modifiable, read-only + // in the implementation. + const std::string& GetTitle() const { return title_; } + void SetTitle(const std::string_view new_title); + + // Desired state stored in a platform-dependent way in the implementation, + // externally modifiable, read-only by the implementation unless from the + // LoadAndApplyIcon implementation. The icon is in Windows .ico format. + // Provide null buffer and / or zero size to reset the icon. + void SetIcon(const void* buffer, size_t size); + void ResetIcon() { SetIcon(nullptr, 0); } + + /// Returns the platform-native window handle (HWND on Windows), or nullptr. + /// Valid after Open() returns successfully. + virtual void* GetNativeWindowHandle() const { return nullptr; } + + // Desired state stored by the common Window, externally modifiable, read-only + // in the implementation. + void SetMainMenu(std::unique_ptr new_main_menu); + void CompleteMainMenuItemsUpdate(); + void SetMainMenuEnabled(bool enabled); + + // Desired state stored by the common Window, externally modifiable, read-only + // in the implementation. + bool IsMouseCaptureRequested() const { return mouse_capture_request_count_ != 0; } + void CaptureMouse(); + void ReleaseMouse(); + + // Desired state stored by the common Window, externally modifiable, read-only + // in the implementation. + CursorVisibility GetCursorVisibility() const { return cursor_visibility_; } + // Setting this to kAutoHidden from any _other_ visibility should hide the + // cursor immediately - for instance, if the external code wants to auto-hide + // the cursor in fullscreen, to allow going into the fullscreen mode to hide + // the cursor instantly. + void SetCursorVisibility(CursorVisibility new_cursor_visibility); + + bool HasFocus() const { return HasActualState() ? has_focus_ : false; } + // May be applied in a delayed way or dropped at all, HasFocus will not + // necessarily be true immediately. + void Focus(); + + // TODO(Triang3l): A resize function, primarily for snapping externally to + // 1280x720, 1920x1080, and other 1:1 resolutions. It will need to resize the + // window (to a desired logical size - the actual physical size is entirely + // the feedback of the implementation) in the normal state, and possibly also + // un-maximize (and possibly un-fullscreen) it (but this choice will possibly + // need to be exposed to the caller). Because it's currently not needed, it's + // not implemented to avoid platform-specific complexities regarding + // maximization, DPI, etc. + + void SetPresenter(Presenter* presenter); + + // Request repainting of the surface. Can be called from non-UI threads as + // long as they know the Surface exists and isn't in the middle of being + // changed to another (the synchronization of this fact between the UI thread + // and the caller thread must be done externally through OnSurfaceChanged). + void RequestPaint() { + if (presenter_surface_) { + RequestPaintImpl(); + } + } + void RequestPresenterUIPaintFromUIThread() { + if (presenter_) { + presenter_->RequestUIPaintFromUIThread(); + } + } + + protected: + // The receiver, which must never be instantiated in the Window object itself + // (rather, usually it should be created as a local variable, because only + // LIFO-ordered creation and deletion of these is supported), that allows + // deletion of the Window from within an event handler (which may invoke a + // WindowListener, and window listeners are allowed to destroy windows; also + // they may execute, for instance, the functions requested to be executed in + // the UI thread in the WindowedAppContext, which are also allowed to destroy + // windows - because if the former wasn't allowed, the latter would be + // required to destroy windows as a result of UI interaction) to be caught by + // functions inside the Window in order to stop interacting with `*this` and + // returning after this happens. + // Note that the receivers are signaled in the *end* of the destruction of the + // common Window, when truly nothing can be done with it anymore, so it's safe + // to assume that right after the creation of the WindowDestructionReceiver, + // it will still be in an unsignaled state even if it's used somewhere in the + // destructor. The reason is that the users of the WindowDestructionReceiver + // are expected to stop accessing the Window *immediately* once + // IsWindowDestroyed becomes `true`, and to leave it in a potentially + // indeterminate state - but the code executed subsequently in the destructor + // may still use that state meaningfully. + class WindowDestructionReceiver { + public: + explicit WindowDestructionReceiver(Window* window) : window_(window) { + if (window_) { + outer_receiver_ = window_->innermost_destruction_receiver_; + window_->innermost_destruction_receiver_ = this; + } + } + + ~WindowDestructionReceiver() { + // If the window is not null, removal from the stack must happen + // regardless of `phase_ == Phase::kDeleting`, because the window + // destructor iterates the receivers after EnterDestructor(), and if the + // receiver is not removed in this case, the destructor will do + // use-after-free. + if (window_) { + // Only LIFO order is supported (normally through RAII). + assert_true(window_->innermost_destruction_receiver_ == this); + window_->innermost_destruction_receiver_ = outer_receiver_; + } + } + + bool IsWindowDestroyed() const { return window_ == nullptr; } + + // Helper functions for common usages of the receiver. Unlike + // IsWindowDestroyed, these, however, may return false immediately on + // creation. + // Primarily for the implementation (most importantly its native event + // handler), to stop interacting with the native window given that it was + // possible before the function call it's guarded with. + bool IsWindowDestroyedOrClosed() const { return IsWindowDestroyed() || window_->IsClosed(); } + // For guarding Apply* calls if one state setter needs to make multiple of + // them (or just detecting if it's okay to call Apply*). + bool IsWindowDestroyedOrStateInapplicable() const { + return IsWindowDestroyed() || !window_->CanApplyState(); + } + bool IsWindowDestroyedOrListenersUncallable() const { + return IsWindowDestroyed() || !window_->CanSendEventsToListeners(); + } + + private: + // The Window must set window_ to nullptr in its destructor. + friend Window; + Window* window_; + WindowDestructionReceiver* outer_receiver_ = nullptr; + }; + + // Like in the Windows Media Player. + // A more modern Windows example, Movies & TV in Windows 11 21H2, has 5000, + // but it's too long especially for highly dynamic games. + // Implementations may use different values according to the platform's UX + // conventions. + static constexpr uint32_t kDefaultCursorAutoHideMilliseconds = 3333; + + Window(WindowedAppContext& app_context, const std::string_view title, + uint32_t desired_logical_width, uint32_t desired_logical_height); + + // If implementation-specific destruction happens, should be called in the + // beginning of the implementation's destructor so the implementation can + // destroy the platform window without doing something unsafe in destruction. + void EnterDestructor() { + phase_ = Phase::kDeleting; + // Disconnect from the surface before destroying the window behind it. + OnSurfaceChanged(false); + } + + // For an open window, the implementation should return the current DPI for + // the window. For a non-open one, it should be the closest approximation, + // such as the last DPI from an existing window, the system DPI, or just the + // medium DPI (0 returned from it will also be treated as medium DPI). + virtual uint32_t GetLatestDpiImpl() const { return GetMediumDpi(); } + + // Deletion of the window may (and must) not happen in OpenImpl, the listeners + // are deferred, so there's no need to use WindowDestructionReceiver in it. + // In case of failure, the implementation must not leave itself in an + // indeterminate state, so another attempt to open the window can be made. + // The implementation must apply the following desired state if it needs it, + // directly (not via Set* methods as they will be dropped during OpenImpl + // since the window is not fully open yet): + // - Title (GetTitle()). + // - Icon (from the last LoadAndApplyIcon call). + // - Main menu (GetMainMenu()) and its enablement. + // - Desired logical size (GetDesiredLogicalWidth() / Height(), taking into + // account that the main menu, during the initial opening, should not be + // included in this size - it specifies the client area that painting will + // be done to), within the capabilities of the platform (may be clamped by + // the OS, for instance - in this case, OnDesiredLogicalSizeUpdate may be + // called from within OpenImpl to store the clamped size for later). + // - Fullscreen (GetFullscreen()) - however, if possible, the calculations + // that would normally be done for a non-fullscreen window in OpenImpl + // should also be done if entering fullscreen, including the menu-related + // ones - first, the usual windowed geometry calculations should be done, + // and then fullscreen should be entered; but preferably still entering + // fullscreen before actually showing a visible window to the user for a + // seamless transition. + // - Mouse capture (IsMouseCaptureRequested()). + // - Cursor visibility (GetCursorVisibility()). + // Also, as a result of the OpenImpl call, these function should be called + // (immediately from within OpenImpl directly or indirectly through the native + // event handling, or shortly after during the UI main loop) to provide the + // initial actual state to the common Window code so it returns the correct + // values: + // - OnActualSizeUpdate, at least if the window isn't opened as not yet + // visible on screen (otherwise the size will be assumed to be 0x0 until the + // next size update caused by something likely requiring user interaction). + // - OnFocusUpdate, at least if the focus has been obtained (otherwise the + // window will be assumed to be not in focus until it goes into the focus + // again). + // Also, if some of the desired state that may be updated by the + // implementation could not be applied (such as the fullscreen mode), and + // certain values of the implementation state are either normally + // differentiated within the implementation or are just meaningful considering + // the platform's defaults (for instance, the platform inherently supports + // only fullscreen, possibly doesn't have a concept of windows at all), it's + // recommended to call the appropriate On*Update functions to update the + // desired state to the actual one. + virtual bool OpenImpl() = 0; + virtual void RequestCloseImpl() = 0; + + // Apply* are called only if CanApplyState() is true (unless the function + // should do more than just applying, such as also updating the desired state + // in a platform-dependent way - see each individual function). + // ApplyNew* means that the value has actually been changed to something + // different than it was previously. + virtual void ApplyNewFullscreen() {} + virtual void ApplyNewTitle() {} + // can_apply_state_in_current_phase whether the window is in a life cycle + // phase that would normally accept Apply calls (the native window surely + // exists), since this function may be called in closed states too to update + // the desired icon (since it's stored in the implementation) - the + // implementation may, however, ignore it and use a more granular check of the + // existence of the native window and the safety of updating the icon for + // better internal state consistency. The icon is in Windows .ico format. If + // the buffer is null or the size is 0, the icon should be reset to the + // default one. Returns whether the icon has been updated successfully. + virtual void LoadAndApplyIcon(const void* buffer, size_t size, + bool can_apply_state_in_current_phase) { + (void)buffer; + (void)size; + (void)can_apply_state_in_current_phase; + } + MenuItem* GetMainMenu() const { return main_menu_.get(); } + // May be called to add, replace or remove the main menu. + virtual void ApplyNewMainMenu(MenuItem* old_main_menu) { (void)old_main_menu; } + // If there's main menu, and state can be applied, will be called to make the + // implementation's state consistent with the new state of the MenuItems of + // the main menu after changes have been made to them. + virtual void CompleteMainMenuItemsUpdateImpl() {} + // Will be called even if capturing while the mouse is already assumed to be + // captured, in case something has released it in the OS. + virtual void ApplyNewMouseCapture() {} + virtual void ApplyNewMouseRelease() {} + virtual void ApplyNewCursorVisibility(CursorVisibility old_cursor_visibility) { + (void)old_cursor_visibility; + } + // If state can be applied, this is called to request bringing the window into + // focus (and once that's done by the OS, update the actual focus state). Does + // nothing otherwise (focus can't be requested before the window is open, a + // closed window is always assumed to be not in focus). + virtual void FocusImpl() {} + + Presenter* presenter() const { return presenter_; } + bool HasSurface() const { return presenter_surface_ != nullptr; } + // If new_surface_potentially_exists is false, creation of the new surface for + // the window won't be updated, and it may be called from the destructor (via + // EnterDestructor to destroy the surface before destroying what it depends + // on) as no virtual functions (including CreateSurface) will be called. + // This function is nonvirtual itself for this reason as well. + void OnSurfaceChanged(bool new_surface_potentially_exists); + // Called only for an open window. + virtual std::unique_ptr CreateSurfaceImpl(Surface::TypeFlags allowed_types) = 0; + // Called only if the Surface exists. + virtual void RequestPaintImpl() = 0; + + // Will also disconnect the surface if needed. + void OnBeforeClose(WindowDestructionReceiver& destruction_receiver); + void OnAfterClose(); + + // These functions may usually also be called as part of the opening process + // from within OpenImpl (directly or through the platform event handler + // invoked during it) to actualize the state for the newly createad window, + // especially if it's different than the desired one. + void OnDpiChanged(UISetupEvent& e, WindowDestructionReceiver& destruction_receiver); + void OnMonitorUpdate(MonitorUpdateEvent& e); + // For calling when the platform changes something in the non-maximized, + // non-fullscreen size of the window. + void OnDesiredLogicalSizeUpdate(uint32_t new_desired_logical_width, + uint32_t new_desired_logical_height) { + desired_logical_width_ = new_desired_logical_width; + desired_logical_height_ = new_desired_logical_height; + } + // If the size of the client area is the same as the currently assumed one + // (the desired / last size for a newly opened / reopened window, the last + // actual size for an already open window), does nothing and returns false. + // Otherwise, updates the size, notifies what depends on the size about the + // change, and returns true. Not storing the new size in the UISetupEvent + // because a resize listener may request another resize, in which case it will + // be outdated - listeners must query the new physical size from the window + // explicitly. + bool OnActualSizeUpdate(uint32_t new_physical_width, uint32_t new_physical_height, + WindowDestructionReceiver& destruction_receiver); + void OnDesiredFullscreenUpdate(bool new_fullscreen) { fullscreen_ = new_fullscreen; } + void OnFocusUpdate(bool new_has_focus, WindowDestructionReceiver& destruction_receiver); + + // Pass true as force_paint in case the platform can't retain the image from + // the previous paint so it won't be skipped if there are no content updates. + void OnPaint(bool force_paint = false); + + void OnFileDrop(FileDropEvent& e, WindowDestructionReceiver& destruction_receiver); + + void OnKeyDown(KeyEvent& e, WindowDestructionReceiver& destruction_receiver); + void OnKeyUp(KeyEvent& e, WindowDestructionReceiver& destruction_receiver); + void OnKeyChar(KeyEvent& e, WindowDestructionReceiver& destruction_receiver); + + void OnMouseDown(MouseEvent& e, WindowDestructionReceiver& destruction_receiver); + void OnMouseMove(MouseEvent& e, WindowDestructionReceiver& destruction_receiver); + void OnMouseUp(MouseEvent& e, WindowDestructionReceiver& destruction_receiver); + void OnMouseWheel(MouseEvent& e, WindowDestructionReceiver& destruction_receiver); + + void OnTouchEvent(TouchEvent& e, WindowDestructionReceiver& destruction_receiver); + + private: + struct ListenerIterationContext { + explicit ListenerIterationContext(ListenerIterationContext* outer_context, + size_t first_index = 0) + : outer_context(outer_context), next_index(first_index) {} + // To support nested listener calls, in case a listener does some + // interaction with the window that results in more events being triggered + // (such as calling Windows API functions that return a result from a + // message handled by a window, rather that simply enqueueing the message). + ListenerIterationContext* outer_context; + // Using indices, not iterators, because after the erasure, the adjustment + // must be done for the vector element indices that would be in the iterator + // range that would be invalidated. + size_t next_index; + }; + + struct InputListenerIterationContext { + explicit InputListenerIterationContext( + InputListenerIterationContext* outer_context, + std::multimap::const_reverse_iterator first_iterator, + size_t first_z_order = SIZE_MAX) + : outer_context(outer_context), + next_iterator(first_iterator), + current_z_order(first_z_order) {} + // To support nested listener calls. + InputListenerIterationContext* outer_context; + // Reverse iterator because input handlers with a higher Z order index may + // correspond to what's displayed on top of what has a lower Z order index, + // so what's higher may consum the event. + std::multimap::const_reverse_iterator next_iterator; + size_t current_z_order; + }; + + // If the window is closed, the platform native window is either being + // destroyed, or doesn't exist anymore, and thus it's in a non-interactive + // state. + bool IsClosed() const { return phase_ < Phase::kOpening || phase_ > Phase::kOpenBeforeClosing; } + + bool CanApplyState() const { + // In kOpening, OpenImpl itself pulls the desired state itself and applies + // it, the Apply* functions can't be called and are unsafe to call because + // the implementation is an incomplete state, with the platform window + // potentially not existing. In kOpenBeforeClosing, as the native window + // still hasn't been destroyed and it can receive new state, still allowing + // applying new state for more consistency between the desired and the + // actual state during the final listener invocation. + return phase_ >= Phase::kOpen && phase_ <= Phase::kOpenBeforeClosing; + } + + bool CanSendEventsToListeners() const { + return phase_ >= Phase::kOpen && phase_ <= Phase::kOpenBeforeClosing; + } + // The listeners may delete the Window - check the destruction receiver after + // calling and stop doing anything accessing *this if that happens. + void SendEventToListeners(std::function fn, + WindowDestructionReceiver& destruction_receiver); + void PropagateEventThroughInputListeners(std::function fn, + WindowDestructionReceiver& destruction_receiver); + + std::unique_ptr CreateSurface(Surface::TypeFlags allowed_types) { + // If opening, surface creation is deferred until all the initial setup has + // completed. Destruction of the surface is also a part of the closing + // process in OnBeforeClose. + if (phase_ != Phase::kOpen) { + return nullptr; + } + return CreateSurfaceImpl(allowed_types); + } + + WindowedAppContext& app_context_; + + Phase phase_ = Phase::kClosedOpenable; + WindowDestructionReceiver* innermost_destruction_receiver_ = nullptr; + + // All currently-attached listeners that get event notifications. + std::vector listeners_; + // Ordered by the Z order, and then by the time of addition (but executed in + // reverse order). + // Note: All the iteration logic involving this Z ordering must be the same as + // in drawing (in the UI drawers in the Presenter), but in reverse. + std::multimap input_listeners_; + // Linked list-based stacks of the contexts of the listener iterations + // currently being done, usually allocated on the stack. + ListenerIterationContext* innermost_listener_iteration_context_ = nullptr; + InputListenerIterationContext* innermost_input_listener_iteration_context_ = nullptr; + + uint32_t desired_logical_width_ = 0; + uint32_t desired_logical_height_ = 0; + // Set by the implementation via OnActualSizeUpdate (from OpenImpl or from the + // platform resize handler). + uint32_t actual_physical_width_ = 0; + uint32_t actual_physical_height_ = 0; + + bool fullscreen_ = false; + + std::string title_; + + std::unique_ptr main_menu_; + + uint32_t mouse_capture_request_count_ = 0; + + CursorVisibility cursor_visibility_ = CursorVisibility::kVisible; + + bool has_focus_ = false; + + Presenter* presenter_ = nullptr; + std::unique_ptr presenter_surface_; + // Whether currently in InPaint to prevent recursive painting in case it's + // triggered somehow from within painting again, because painting is much more + // complex than just a small state update, and recursive painting is + // completely unsupported by the Presenter. + bool is_painting_ = false; +}; + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/window_gtk.h b/include/rex/ui/window_gtk.h new file mode 100644 index 0000000..433fda3 --- /dev/null +++ b/include/rex/ui/window_gtk.h @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +#include +#include +#include + +#include +#include +#include + +namespace rex { +namespace ui { + +class GTKWindow : public Window { + using super = Window; + + public: + GTKWindow(WindowedAppContext& app_context, const std::string_view title, + uint32_t desired_logical_width, uint32_t desired_logical_height); + ~GTKWindow() override; + + // Will be null if the window hasn't been successfully opened yet, or has been + // closed. + GtkWidget* window() const { return window_; } + + protected: + bool OpenImpl() override; + void RequestCloseImpl() override; + + void ApplyNewFullscreen() override; + void ApplyNewTitle() override; + void ApplyNewMainMenu(MenuItem* old_main_menu) override; + // Mouse capture seems to happen implicitly compared to Windows. + void FocusImpl() override; + + std::unique_ptr CreateSurfaceImpl(Surface::TypeFlags allowed_types) override; + void RequestPaintImpl() override; + + private: + void HandleSizeUpdate(WindowDestructionReceiver& destruction_receiver); + // For updating multiple factors that may influence the window size at once, + // without handling the configure event multiple times (that may not only + // result in wasted handling, but also in the state potentially changed to an + // inconsistent one in the middle of a size update by the listeners). + void BeginBatchedSizeUpdate(); + void EndBatchedSizeUpdate(WindowDestructionReceiver& destruction_receiver); + + // Handling events related to the whole window. + bool HandleMouse(GdkEvent* event, WindowDestructionReceiver& destruction_receiver); + bool HandleKeyboard(GdkEventKey* event, WindowDestructionReceiver& destruction_receiver); + gboolean WindowEventHandler(GdkEvent* event); + static gboolean WindowEventHandlerThunk(GtkWidget* widget, GdkEvent* event, gpointer user_data); + + // Handling events related specifically to the drawing (client) area. + gboolean DrawingAreaEventHandler(GdkEvent* event); + static gboolean DrawingAreaEventHandlerThunk(GtkWidget* widget, GdkEvent* event, + gpointer user_data); + static gboolean DrawHandler(GtkWidget* widget, cairo_t* cr, gpointer data); + + // Non-owning (initially floating) references to the widgets. + GtkWidget* window_ = nullptr; + GtkWidget* box_ = nullptr; + GtkWidget* drawing_area_ = nullptr; + + uint32_t batched_size_update_depth_ = 0; + bool batched_size_update_contained_configure_ = false; + bool batched_size_update_contained_draw_ = false; +}; + +class GTKMenuItem : public MenuItem { + public: + GTKMenuItem(Type type, const std::string& text, const std::string& hotkey, + std::function callback); + ~GTKMenuItem() override; + + GtkWidget* handle() const { return menu_; } + + protected: + void OnChildAdded(MenuItem* child_item) override; + void OnChildRemoved(MenuItem* child_item) override; + + private: + static void ActivateHandler(GtkWidget* menu_item, gpointer user_data); + + // An owning reference because a menu may be transferred between windows. + GtkWidget* menu_ = nullptr; +}; + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/window_listener.h b/include/rex/ui/window_listener.h new file mode 100644 index 0000000..36aed2f --- /dev/null +++ b/include/rex/ui/window_listener.h @@ -0,0 +1,56 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +namespace rex { +namespace ui { + +// Virtual interfaces for types that want to listen for Window events. +// Use Window::Add[Input]Listener and Window::Remove[Input]Listener to manage +// active listeners. + +class WindowListener { + public: + virtual ~WindowListener() = default; + + // OnOpened will be followed by various initial setup listeners. + virtual void OnOpened(UISetupEvent&) {} + virtual void OnClosing(UIEvent&) {} + + virtual void OnDpiChanged(UISetupEvent&) {} + virtual void OnResize(UISetupEvent&) {} + + virtual void OnGotFocus(UISetupEvent&) {} + virtual void OnLostFocus(UISetupEvent&) {} + + virtual void OnFileDrop(FileDropEvent&) {} +}; + +class WindowInputListener { + public: + virtual ~WindowInputListener() = default; + + virtual void OnKeyDown(KeyEvent&) {} + virtual void OnKeyUp(KeyEvent&) {} + virtual void OnKeyChar(KeyEvent&) {} + + virtual void OnMouseDown(MouseEvent&) {} + virtual void OnMouseMove(MouseEvent&) {} + virtual void OnMouseUp(MouseEvent&) {} + virtual void OnMouseWheel(MouseEvent&) {} + + virtual void OnTouchEvent(TouchEvent&) {} +}; + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/window_win.h b/include/rex/ui/window_win.h new file mode 100644 index 0000000..0b0bb85 --- /dev/null +++ b/include/rex/ui/window_win.h @@ -0,0 +1,177 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#include + +#include + +namespace rex { +namespace ui { + +class Win32Window : public Window { + using super = Window; + + public: + Win32Window(WindowedAppContext& app_context, const std::string_view title, + uint32_t desired_logical_width, uint32_t desired_logical_height); + ~Win32Window() override; + + // Will be null if the window hasn't been successfully opened yet, or has been + // closed. + HWND hwnd() const { return hwnd_; } + + void* GetNativeWindowHandle() const override { return reinterpret_cast(hwnd_); } + + uint32_t GetMediumDpi() const override; + + protected: + bool OpenImpl() override; + void RequestCloseImpl() override; + + uint32_t GetLatestDpiImpl() const override; + + void ApplyNewFullscreen() override; + void ApplyNewTitle() override; + void LoadAndApplyIcon(const void* buffer, size_t size, + bool can_apply_state_in_current_phase) override; + void ApplyNewMainMenu(MenuItem* old_main_menu) override; + void CompleteMainMenuItemsUpdateImpl() override; + void ApplyNewMouseCapture() override; + void ApplyNewMouseRelease() override; + void ApplyNewCursorVisibility(CursorVisibility old_cursor_visibility) override; + void FocusImpl() override; + + std::unique_ptr CreateSurfaceImpl(Surface::TypeFlags allowed_types) override; + void RequestPaintImpl() override; + + private: + enum : UINT { + kUserMessageAutoHideCursor = WM_USER, + }; + + BOOL AdjustWindowRectangle(RECT& rect, DWORD style, BOOL menu, DWORD ex_style, UINT dpi) const; + BOOL AdjustWindowRectangle(RECT& rect) const; + + uint32_t GetCurrentSystemDpi() const; + uint32_t GetCurrentDpi() const; + + void ApplyFullscreenEntry(WindowDestructionReceiver& destruction_receiver); + + void HandleSizeUpdate(WindowDestructionReceiver& destruction_receiver); + // For updating multiple factors that may influence the window size at once, + // without handling WM_SIZE multiple times (that may not only result in wasted + // handling, but also in the state potentially changed to an inconsistent one + // in the middle of a size update by the listeners). + void BeginBatchedSizeUpdate(); + void EndBatchedSizeUpdate(WindowDestructionReceiver& destruction_receiver); + + bool HandleMouse(UINT message, WPARAM wParam, LPARAM lParam, + WindowDestructionReceiver& destruction_receiver); + bool HandleKeyboard(UINT message, WPARAM wParam, LPARAM lParam, + WindowDestructionReceiver& destruction_receiver); + + void SetCursorIfFocusedOnClientArea(HCURSOR cursor) const; + void SetCursorAutoHideTimer(); + static void NTAPI AutoHideCursorTimerCallback(void* parameter, BOOLEAN timer_or_wait_fired); + + static LRESULT CALLBACK WndProcThunk(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + // This can't handle messages sent during CreateWindow (hwnd_ still not + // assigned to) or after nulling hwnd_ in closing / deleting. + virtual LRESULT WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + + HCURSOR arrow_cursor_ = nullptr; + + HICON icon_ = nullptr; + + uint32_t dpi_ = USER_DEFAULT_SCREEN_DPI; + + // hwnd_ may be accessed by the cursor hiding timer callback from a separate + // thread, but the timer can be active only with a valid window anyway. + HWND hwnd_ = nullptr; + + uint32_t batched_size_update_depth_ = 0; + bool batched_size_update_contained_wm_size_ = false; + bool batched_size_update_contained_wm_paint_ = false; + + uint32_t pre_fullscreen_dpi_; + WINDOWPLACEMENT pre_fullscreen_placement_; + // The client area part of pre_fullscreen_placement_.rcNormalPosition, saved + // in case something effecting the behavior of AdjustWindowRectEx for the + // non-fullscreen state is changed mid-fullscreen (for instance, the menu is + // toggled), so a new AdjustWindowRectExForDpi call for the old DPI, but with + // the other state different than the old one, while exiting fullscreen, won't + // cause anomalies like negative size. + uint32_t pre_fullscreen_normal_client_width_; + uint32_t pre_fullscreen_normal_client_height_; + + // Must be the screen position, not the client position, so it's possible to + // immediately hide the cursor, for instance, when switching to fullscreen + // (and thus changing the client area top-left corner, resulting in + // WM_MOUSEMOVE being sent, which would instantly reveal the cursor because of + // that relative position change). + POINT cursor_auto_hide_last_screen_pos_ = {LONG_MAX, LONG_MAX}; + // Using a timer queue timer for hiding the cursor rather than WM_TIMER + // because the latter is a very low-priority message which is never received + // if WM_PAINT messages are sent continuously (invalidating the window right + // after painting). + HANDLE cursor_auto_hide_timer_ = nullptr; + // Last hiding case numbers for skipping of obsolete cursor hiding messages + // (both WM_MOUSEMOVE and the hiding message have been sent, for instance, and + // WM_MOUSEMOVE hasn't been handled yet, or the cursor visibility state has + // been changed). The queued index is read, and the signaled index is written, + // by the timer callback, which is executed outside the message thread, so + // before modifying the queued number, or reading the signaled number, in the + // message thread, delete the timer (deleting the timer awaits cancels the + // callback if it hasn't been invoked yet, or awaits it if it has). Use + // equality comparison for safe rollover handling. + WPARAM last_cursor_auto_hide_queued = 0; + WPARAM last_cursor_auto_hide_signaled = 0; + // Whether the cursor has been hidden after the expiration of the timer, and + // hasn't been revealed yet. + bool cursor_currently_auto_hidden_ = false; +}; + +class Win32MenuItem : public MenuItem { + public: + Win32MenuItem(Type type, const std::string& text, const std::string& hotkey, + std::function callback); + ~Win32MenuItem() override; + + HMENU handle() const { return handle_; } + + void SetEnabled(bool enabled) override; + + using MenuItem::OnSelected; + + protected: + void OnChildAdded(MenuItem* child_item) override; + void OnChildRemoved(MenuItem* child_item) override; + + private: + HMENU handle_ = nullptr; +}; + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/windowed_app.h b/include/rex/ui/windowed_app.h new file mode 100644 index 0000000..50638d6 --- /dev/null +++ b/include/rex/ui/windowed_app.h @@ -0,0 +1,189 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if REX_PLATFORM_ANDROID +// Multiple apps in a single library instead of separate executables. +#define XE_UI_WINDOWED_APPS_IN_LIBRARY 1 +#endif + +namespace rex { +namespace ui { + +// Interface between the platform's entry points (in the main, UI, thread that +// also runs the message loop) and the app that implements it. +class WindowedApp { + public: + // WindowedApps are expected to provide a static creation function, for + // creating an instance of the class (which may be called before + // initialization of platform-specific parts, should preferably be as simple + // as possible). + + using Creator = + std::unique_ptr (*)(rex::ui::WindowedAppContext& app_context); + + WindowedApp(const WindowedApp& app) = delete; + WindowedApp& operator=(const WindowedApp& app) = delete; + virtual ~WindowedApp() = default; + + WindowedAppContext& app_context() const { return app_context_; } + + // Same as the executable (project), xenia-library-app. + const std::string& GetName() const { return name_; } + const std::string& GetPositionalOptionsUsage() const { return positional_options_usage_; } + const std::vector& GetPositionalOptions() const { return positional_options_; } + + // TEMP: Replace with CVAR system + // Called by entry point after construction, before OnInitialize() + void SetParsedArguments(std::map args) { + parsed_args_ = std::move(args); + } + + // TEMP: Replace with CVAR system + // Retrieve a parsed argument by name + std::optional GetArgument(const std::string& name) const { + auto it = parsed_args_.find(name); + if (it != parsed_args_.end()) { + return it->second; + } + return std::nullopt; + } + + // Called once before receiving other lifecycle callback invocations. Cvars + // will be initialized with the launch arguments. Returns whether the app has + // been initialized successfully (otherwise platform-specific code must call + // OnDestroy and refuse to continue running the app). + virtual bool OnInitialize() = 0; + // See OnDestroy for more info. + void InvokeOnDestroy() { + // For safety and convenience of referencing objects owned by the app in + // pending functions queued in or after OnInitialize, make sure they are + // executed before telling the app that destruction needs to happen. + app_context().ExecutePendingFunctionsFromUIThread(); + OnDestroy(); + } + + protected: + // Positional options should be initialized in the constructor if needed. + // Cvars will not have been initialized with the arguments at the moment of + // construction (as the result depends on construction). + explicit WindowedApp(WindowedAppContext& app_context, const std::string_view name, + const std::string_view positional_options_usage = std::string_view()) + : app_context_(app_context), + name_(name), + positional_options_usage_(positional_options_usage) {} + + // For calling from the constructor. + void AddPositionalOption(const std::string_view option) { + positional_options_.emplace_back(option); + } + + // OnDestroy entry point may be called (through InvokeOnDestroy) by the + // platform-specific lifecycle interface at request of either the app itself + // or the OS - thus should be possible for the lifecycle interface to call at + // any moment (not from inside other lifecycle callbacks though). The app will + // also be destroyed when that happens, so the destructor will also be called + // (but this is more safe with respect to exceptions). This is only guaranteed + // to be called if OnInitialize has already happened (successfully or not) - + // in case of an error before initialization, the destructor may be called + // alone as well. Context's pending functions will be executed before the + // call, so it's safe to destroy dependencies of them here (though it may + // still be possible to add more pending functions here depending on whether + // the context was explicitly shut down before this is invoked). + virtual void OnDestroy() {} + + private: + WindowedAppContext& app_context_; + + std::string name_; + std::string positional_options_usage_; + std::vector positional_options_; + // TEMP: Replace with CVAR system + std::map parsed_args_; + +#if XE_UI_WINDOWED_APPS_IN_LIBRARY + public: + class CreatorRegistration { + public: + CreatorRegistration(const std::string_view identifier, Creator creator) { + if (!creators_) { + // Will be deleted by the last creator registration's destructor, no + // need for a library destructor. + creators_ = new std::unordered_map; + } + iterator_inserted_ = creators_->emplace(identifier, creator); + assert_true(iterator_inserted_.second); + } + + ~CreatorRegistration() { + if (iterator_inserted_.second) { + creators_->erase(iterator_inserted_.first); + if (creators_->empty()) { + delete creators_; + } + } + } + + private: + std::pair::iterator, bool> iterator_inserted_; + }; + + static Creator GetCreator(const std::string& identifier) { + if (!creators_) { + return nullptr; + } + auto it = creators_->find(identifier); + return it != creators_->end() ? it->second : nullptr; + } + + private: + static std::unordered_map* creators_; +#endif // XE_UI_WINDOWED_APPS_IN_LIBRARY +}; + +#if XE_UI_WINDOWED_APPS_IN_LIBRARY +// Multiple apps in a single library. +#define REX_DEFINE_APP(identifier, creator) \ + namespace rex { \ + namespace ui { \ + namespace windowed_app_creator_registrations { \ + rex::ui::WindowedApp::CreatorRegistration identifier(#identifier, creator); \ + } \ + } \ + } +#else +// Separate executables for each app. +std::unique_ptr (*GetWindowedAppCreator())(WindowedAppContext& app_context); +#define REX_DEFINE_APP(identifier, creator) \ + rex::ui::WindowedApp::Creator rex::ui::GetWindowedAppCreator() { \ + return creator; \ + } +#endif // XE_UI_WINDOWED_APPS_IN_LIBRARY + +// Deprecated: use REX_DEFINE_APP +#define XE_DEFINE_WINDOWED_APP(identifier, creator) REX_DEFINE_APP(identifier, creator) + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/windowed_app_context.h b/include/rex/ui/windowed_app_context.h new file mode 100644 index 0000000..02d3bca --- /dev/null +++ b/include/rex/ui/windowed_app_context.h @@ -0,0 +1,178 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +#include + +namespace rex { +namespace ui { + +// Context for inputs provided by the entry point and interacting with the +// platform's UI loop, to be implemented by platforms. +class WindowedAppContext { + public: + WindowedAppContext(const WindowedAppContext& context) = delete; + WindowedAppContext& operator=(const WindowedAppContext& context) = delete; + virtual ~WindowedAppContext(); + + // The thread where the object is created will be assumed to be the UI thread, + // for the purpose of being able to perform CallInUIThreadSynchronous before + // running the loop. + bool IsInUIThread() const { return std::this_thread::get_id() == ui_thread_id_; } + + // CallInUIThreadDeferred and CallInUIThread are fire and forget - will be + // executed at some point the future when the UI thread is running the loop + // and is not busy doing other things. + // Therefore, references to objects in the function may outlive the owners of + // those objects, so use-after-free is very easy to create if not being + // careful enough. + // There are two solutions to this issue: + // - Signaling a fence in the function, awaiting it before destroying objects + // referenced by the function (works for shutdown from non-UI threads, or + // for CallInUIThread, but not CallInUIThreadDeferred, in the UI thread). + // - Calling ExecutePendingFunctionsFromUIThread in the UI thread before + // destroying objects referenced by the function (works for shutdown from + // the UI thread, though CallInUIThreadSynchronous doing + // ExecutePendingFunctionsFromUIThread is also an option for shutdown from + // any thread). + // (These are not required if all the called function is doing is triggering a + // quit with the context pointer captured by value, as the only object + // involved will be the context itself, with a pointer that is valid until + // it's destroyed - the most late location of the pending function execution + // possible.) + // Returning true if the function has been enqueued (it will be called at some + // point, at worst, before exiting the loop) or called immediately, false if + // it was dropped (if calling after exiting the loop). + // It's okay to enqueue functions from queued functions already being + // executed. As execution may be happening during the destruction of the + // context as well, in this case, CallInUIThreadDeferred must make sure it + // doesn't call anything virtual in the destructor. + + // Enqueues the function regardless of the current thread. Won't necessarily + // be executed directly from the platform main loop as + // ExecutePendingFunctionsFromUIThread may be called anywhere (for instance, + // to await pending functions before destroying what they are referencing). + bool CallInUIThreadDeferred(std::function function); + // Executes the function immediately if already in the UI thread, enqueues it + // otherwise. + bool CallInUIThread(std::function function); + bool CallInUIThreadSynchronous(std::function function); + // It's okay to call this function from the queued functions themselves (such + // as in the case of waiting for a pending async CallInUIThreadDeferred + // described above - the wait may be done inside a CallInUIThreadSynchronous + // function safely). + void ExecutePendingFunctionsFromUIThread() { ExecutePendingFunctionsFromUIThread(false); } + + // If on the target platform, the program itself is supposed to run the UI + // loop, this may be checked before doing blocking message waits as an + // additional safety measure beyond what PlatformQuitFromUIThread guarantees, + // and if true, the loop should be terminated (pending function will already + // have been executed). This doesn't imply that pending functions have been + // executed in all contexts, however - they can be executing from quitting + // itself (in the worst case, in the destructor where virtual methods can't be + // called), and in this case, this will be returning true. + bool HasQuitFromUIThread() const { + assert_true(IsInUIThread()); + return has_quit_; + } + + // Immediately disallows adding new pending UI functions, executes the already + // queued ones, and makes sure that the UI loop is aware that it was asked to + // stop running. This must not destroy the context or the app directly - the + // actual app shutdown will be initiated at some point outside the scope of + // app's callbacks. May call virtual functions - invoke + // ExecutePendingFunctionsFromUIThread(true) in the destructor instead, and + // use the platform-specific destructor to invoke the needed + // PlatformQuitFromUIThread logic (it should be safe, in case of destruction, + // to perform platform-specific quit request logic before the common part - + // NotifyUILoopOfPendingFunctions won't be called after the platform-specific + // quit request logic in this case anyway as destruction expects that there + // are no references to the object in other threads). Safe to call from within + // pending functions - requesting quit from non-UI threads is possible via + // methods like CallInUIThreadSynchronous. For deferred, rather than + // immediate, quitting from the UI thread, CallInUIThreadDeferred may be used + // (but the context pointer should be captured by value not to require + // explicit completion forcing in case the storage of the pointer is lost + // before the function is called). + void QuitFromUIThread(); + // Callable from any thread. This is a special case where a completely + // fire-and-forget CallInUIThreadDeferred is safe, as the function only + // references nonvirtual functions of the context itself, and will be called + // at most from the destructor. No need to return the result - it doesn't + // matter if has quit already or not, as that's the intention anyway. + void RequestDeferredQuit() { + CallInUIThreadDeferred([this] { QuitFromUIThread(); }); + } + + protected: + WindowedAppContext() : ui_thread_id_(std::this_thread::get_id()) {} + + // Can be called from any thread (including the UI thread) to ask the OS to + // run an iteration of the UI loop (with or without processing internal UI + // messages, this is platform-dependent) so pending functions will be executed + // at some point. pending_functions_mutex_ will not be locked when this is + // called (to make sure that, for example, the caller, waiting for space in + // the OS's message queue, such as in case of a Linux pipe, won't be blocking + // the UI thread that has started executing pending messages while pumping + // that pipe, resulting in a deadlock) - implementations don't directly see + // anything protected by it anyway, and a spurious notification shouldn't be + // causing any damage, this is similar to how condition variables can be + // signaled outside the critical section (signaling inside the critical + // section may also cause contention if the thread waiting is woken up quickly + // enough). This, however, means that NotifyUILoopOfPendingFunctions may be + // called in a non-UI thread after the final pending message processing + // followed by PlatformQuitFromUIThread in the UI thread - so it can still be + // called after a quit. + virtual void NotifyUILoopOfPendingFunctions() = 0; + + // Called when requesting a quit in the UI thread to tell the platform that + // the UI loop needs to be terminated. The pending function queue is assumed + // to be empty before this is called, and no new pending functions can be + // added (but NotifyUILoopOfPendingFunctions may still be called as it's not + // mutually exclusive with PlatformQuitFromUIThread - if this matters, the + // platform implementation itself should be resolving this case). + virtual void PlatformQuitFromUIThread() = 0; + + std::thread::id ui_thread_id_; + + private: + // May be called with is_final == true from the destructor - must not call + // anything virtual in this case. + void ExecutePendingFunctionsFromUIThread(bool is_final); + + // Accessible by the UI thread. + bool has_quit_ = false; + bool is_in_destructor_ = false; + + // Synchronizes producers with each other and with the consumer, as well as + // all of them with the pending_functions_accepted_ variable which indicates + // whether shutdown has not been performed yet, as after the shutdown, no new + // functions will be executed anymore, therefore no new function should be + // queued, as it will never be called (thus CallInUIThreadSynchronous for it + // will never return, for instance). + std::mutex pending_functions_mutex_; + std::deque> pending_functions_; + // Protected by pending_functions_mutex_, writable by the UI thread, readable + // by any thread. Must be set to false before exiting the main platform loop, + // but before that, all pending functions must be executed no matter what, as + // they may need to signal fences currently being awaited (like the + // CallInUIThreadSynchronous fence). + bool pending_functions_accepted_ = true; +}; + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/windowed_app_context_gtk.h b/include/rex/ui/windowed_app_context_gtk.h new file mode 100644 index 0000000..644b21c --- /dev/null +++ b/include/rex/ui/windowed_app_context_gtk.h @@ -0,0 +1,46 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include + +#include + +namespace rex { +namespace ui { + +class GTKWindowedAppContext final : public WindowedAppContext { + public: + GTKWindowedAppContext() = default; + ~GTKWindowedAppContext(); + + void NotifyUILoopOfPendingFunctions() override; + + void PlatformQuitFromUIThread() override; + + void RunMainGTKLoop(); + + private: + static gboolean PendingFunctionsSourceFunc(gpointer data); + + static gboolean QuitSourceFunc(gpointer data); + + std::mutex pending_functions_idle_pending_mutex_; + guint pending_functions_idle_pending_ = 0; + + guint quit_idle_pending_ = 0; +}; + +} // namespace ui +} // namespace rex diff --git a/include/rex/ui/windowed_app_context_win.h b/include/rex/ui/windowed_app_context_win.h new file mode 100644 index 0000000..09b20f7 --- /dev/null +++ b/include/rex/ui/windowed_app_context_win.h @@ -0,0 +1,117 @@ +#pragma once +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#include + +#include + +// For per-monitor DPI awareness v1. +#include + +namespace rex { +namespace ui { + +class Win32WindowedAppContext final : public WindowedAppContext { + public: + // clang-format off + struct PerMonitorDpiV1Api { + HRESULT (STDAPICALLTYPE* get_dpi_for_monitor)( + HMONITOR hmonitor, MONITOR_DPI_TYPE dpi_type, UINT* dpi_x, UINT* dpi_y); + }; + struct PerMonitorDpiV2Api { + // Important note: Even though per-monitor DPI awareness version 2 + // inherently has automatic non-client area DPI scaling, PMv2 was added in + // Windows 10 1703. However, these functions were added earlier, in 1607. + // While we haven't tested the actual behavior on 1607 and this is just a + // guess, still, before using AdjustWindowRectExForDpi for the window DPI, + // make sure that EnableNonClientDpiScaling is called for the window in its + // WM_NCCREATE handler to enable automatic non-client DPI scaling on PMv1 on + // 1607, so AdjustWindowRectExForDpi (which doesn't have a window argument + // so it can't know whether automatic scaling is enabled for it) will likely + // return values that reflect the actual size of the non-client area of the + // window (otherwise, for instance, "un-adjusting" the actual window + // rectangle using AdjustWindowRectExForDpi may result in a negative client + // area size if the DPI passed to it is larger than the DPI actually used + // for the non-client area). + BOOL (WINAPI* adjust_window_rect_ex_for_dpi)( + LPRECT rect, DWORD style, BOOL menu, DWORD ex_style, UINT dpi); + BOOL (WINAPI* enable_non_client_dpi_scaling)(HWND hwnd); + UINT (WINAPI* get_dpi_for_system)(); + UINT (WINAPI* get_dpi_for_window)(HWND hwnd); + }; + // clang-format on + + // Must call Initialize and check its result after creating to be able to + // perform pending function calls. + explicit Win32WindowedAppContext(HINSTANCE hinstance, int show_cmd) + : hinstance_(hinstance), show_cmd_(show_cmd) {} + ~Win32WindowedAppContext(); + + bool Initialize(); + + HINSTANCE hinstance() const { return hinstance_; } + int show_cmd() const { return show_cmd_; } + + void NotifyUILoopOfPendingFunctions() override; + + void PlatformQuitFromUIThread() override; + + int RunMainMessageLoop(); + + // Per-monitor DPI awareness version 2 is expected to be enabled via the + // manifest, as that's the recommended way, which also doesn't require calling + // SetProcessDpiAwareness before doing anything that may depend on DPI + // awareness (so it's safe to use any Windows APIs before what would be + // supposed to initialize it). + // Windows 8.1 per-monitor DPI awareness version 1. + const PerMonitorDpiV1Api* per_monitor_dpi_v1_api() const { + return per_monitor_dpi_v1_api_available_ ? &per_monitor_dpi_v1_api_ : nullptr; + } + // Windows 10 1607 per-monitor DPI awareness API, also heavily used for + // per-monitor DPI awareness version 2 functionality added in Windows 10 1703. + const PerMonitorDpiV2Api* per_monitor_dpi_v2_api() const { + return per_monitor_dpi_v2_api_available_ ? &per_monitor_dpi_v2_api_ : nullptr; + } + + private: + enum : UINT { + kPendingFunctionsWindowClassMessageExecute = WM_USER, + }; + + static LRESULT CALLBACK PendingFunctionsWndProc(HWND hwnd, UINT message, WPARAM wparam, + LPARAM lparam); + + HINSTANCE hinstance_; + int show_cmd_; + + HMODULE shcore_module_ = nullptr; + HMODULE user32_module_ = nullptr; + PerMonitorDpiV1Api per_monitor_dpi_v1_api_ = {}; + PerMonitorDpiV2Api per_monitor_dpi_v2_api_ = {}; + bool per_monitor_dpi_v1_api_available_ = false; + bool per_monitor_dpi_v2_api_available_ = false; + + static bool pending_functions_window_class_registered_; + HWND pending_functions_hwnd_ = nullptr; +}; + +} // namespace ui +} // namespace rex diff --git a/include/rex/vec128.h b/include/rex/vec128.h new file mode 100644 index 0000000..d7ff6b5 --- /dev/null +++ b/include/rex/vec128.h @@ -0,0 +1,258 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include +#include + +#include +#include + +namespace rex { + +// The first rule of vector programming is to only rely on exact positions +// when absolutely required - prefer dumb loops to exact offsets. +// Vectors in memory are laid out as in AVX registers on little endian +// machines. Note that little endian is dumb, so the byte at index 0 in +// the vector is is really byte 15 (or the high byte of short 7 or int 3). +// Because of this, all byte access should be via the accessors instead of +// the direct array. + +// Altivec big endian layout: AVX little endian layout: +// +---------+---------+---------+ +---------+---------+---------+ +// | int32 0 | int16 0 | int8 0 | | int32 3 | int16 7 | int8 15 | +// | | +---------+ | | +---------+ +// | | | int8 1 | | | | int8 14 | +// | +---------+---------+ | +---------+---------+ +// | | int16 1 | int8 2 | | | int16 6 | int8 13 | +// | | +---------+ | | +---------+ +// | | | int8 3 | | | | int8 12 | +// +---------+---------+---------+ +---------+---------+---------+ +// | int32 1 | int16 2 | int8 4 | | int32 2 | int16 5 | int8 11 | +// | | +---------+ | | +---------+ +// | | | int8 5 | | | | int8 10 | +// | +---------+---------+ | +---------+---------+ +// | | int16 3 | int8 6 | | | int16 4 | int8 9 | +// | | +---------+ | | +---------+ +// | | | int8 7 | | | | int8 8 | +// +---------+---------+---------+ +---------+---------+---------+ +// | int32 2 | int16 4 | int8 8 | | int32 1 | int16 3 | int8 7 | +// | | +---------+ | | +---------+ +// | | | int8 9 | | | | int8 6 | +// | +---------+---------+ | +---------+---------+ +// | | int16 5 | int8 10 | | | int16 2 | int8 5 | +// | | +---------+ | | +---------+ +// | | | int8 11 | | | | int8 4 | +// +---------+---------+---------+ +---------+---------+---------+ +// | int32 3 | int16 6 | int8 12 | | int32 0 | int16 1 | int8 3 | +// | | +---------+ | | +---------+ +// | | | int8 13 | | | | int8 2 | +// | +---------+---------+ | +---------+---------+ +// | | int16 7 | int8 14 | | | int16 0 | int8 1 | +// | | +---------+ | | +---------+ +// | | | int8 15 | | | | int8 0 | +// +---------+---------+---------+ +---------+---------+---------+ +// +// Logical order: +// +-----+-----+-----+-----+ +-----+-----+-----+-----+ +// | X | Y | Z | W | | W | Z | Y | X | +// +-----+-----+-----+-----+ +-----+-----+-----+-----+ +// +// Mapping indices is easy: +// int32[i ^ 0x3] +// int16[i ^ 0x7] +// int8[i ^ 0xF] +typedef struct alignas(16) vec128_s { + union { + struct { + float x; + float y; + float z; + float w; + }; + struct { + int32_t ix; + int32_t iy; + int32_t iz; + int32_t iw; + }; + struct { + uint32_t ux; + uint32_t uy; + uint32_t uz; + uint32_t uw; + }; + float f32[4]; + double f64[2]; + int8_t i8[16]; + uint8_t u8[16]; + int16_t i16[8]; + uint16_t u16[8]; + int32_t i32[4]; + uint32_t u32[4]; + int64_t i64[2]; + uint64_t u64[2]; + struct { + uint64_t low; + uint64_t high; + }; + }; + + bool operator==(const vec128_s& b) const { return low == b.low && high == b.high; } + bool operator!=(const vec128_s& b) const { return low != b.low || high != b.high; } + vec128_s operator^(const vec128_s& b) const { + vec128_s a = *this; + a.high ^= b.high; + a.low ^= b.low; + return a; + }; + vec128_s& operator^=(const vec128_s& b) { + *this = *this ^ b; + return *this; + }; + vec128_s operator&(const vec128_s& b) const { + vec128_s a = *this; + a.high &= b.high; + a.low &= b.low; + return a; + }; + vec128_s& operator&=(const vec128_s& b) { + *this = *this & b; + return *this; + }; + vec128_s operator|(const vec128_s& b) const { + vec128_s a = *this; + a.high |= b.high; + a.low |= b.low; + return a; + }; + vec128_s& operator|=(const vec128_s& b) { + *this = *this | b; + return *this; + }; +} vec128_t; + +static inline vec128_t vec128i(uint32_t src) { + vec128_t v; + for (auto i = 0; i < 4; ++i) { + v.u32[i] = src; + } + return v; +} +static inline vec128_t vec128i(uint32_t x, uint32_t y, uint32_t z, uint32_t w) { + vec128_t v; + v.u32[0] = x; + v.u32[1] = y; + v.u32[2] = z; + v.u32[3] = w; + return v; +} +static inline vec128_t vec128q(uint64_t src) { + vec128_t v; + for (auto i = 0; i < 2; ++i) { + v.i64[i] = src; + } + return v; +} +static inline vec128_t vec128q(uint64_t x, uint64_t y) { + vec128_t v; + v.i64[0] = x; + v.i64[1] = y; + return v; +} +static inline vec128_t vec128d(double src) { + vec128_t v; + for (auto i = 0; i < 2; ++i) { + v.f64[i] = src; + } + return v; +} +static inline vec128_t vec128d(double x, double y) { + vec128_t v; + v.f64[0] = x; + v.f64[1] = y; + return v; +} +static inline vec128_t vec128f(float src) { + vec128_t v; + for (auto i = 0; i < 4; ++i) { + v.f32[i] = src; + } + return v; +} +static inline vec128_t vec128f(float x, float y, float z, float w) { + vec128_t v; + v.f32[0] = x; + v.f32[1] = y; + v.f32[2] = z; + v.f32[3] = w; + return v; +} +static inline vec128_t vec128s(uint16_t src) { + vec128_t v; + for (auto i = 0; i < 8; ++i) { + v.u16[i] = src; + } + return v; +} +static inline vec128_t vec128s(uint16_t x0, uint16_t x1, uint16_t y0, uint16_t y1, uint16_t z0, + uint16_t z1, uint16_t w0, uint16_t w1) { + vec128_t v; + v.u16[0] = x1; + v.u16[1] = x0; + v.u16[2] = y1; + v.u16[3] = y0; + v.u16[4] = z1; + v.u16[5] = z0; + v.u16[6] = w1; + v.u16[7] = w0; + return v; +} +static inline vec128_t vec128b(uint8_t src) { + vec128_t v; + for (auto i = 0; i < 16; ++i) { + v.u8[i] = src; + } + return v; +} +static inline vec128_t vec128b(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t y0, + uint8_t y1, uint8_t y2, uint8_t y3, uint8_t z0, uint8_t z1, + uint8_t z2, uint8_t z3, uint8_t w0, uint8_t w1, uint8_t w2, + uint8_t w3) { + vec128_t v; + v.u8[0] = x3; + v.u8[1] = x2; + v.u8[2] = x1; + v.u8[3] = x0; + v.u8[4] = y3; + v.u8[5] = y2; + v.u8[6] = y1; + v.u8[7] = y0; + v.u8[8] = z3; + v.u8[9] = z2; + v.u8[10] = z1; + v.u8[11] = z0; + v.u8[12] = w3; + v.u8[13] = w2; + v.u8[14] = w1; + v.u8[15] = w0; + return v; +} + +// TODO(gibbed): Figure out why clang doesn't line forward declarations of +// inline functions. + +std::string to_string(const vec128_t& value); + +std::ostream& operator<<(std::ostream& os, const vec128_t& value); + +} // namespace rex diff --git a/include/rex/version.h.in b/include/rex/version.h.in new file mode 100644 index 0000000..818367b --- /dev/null +++ b/include/rex/version.h.in @@ -0,0 +1,22 @@ +#pragma once + +// Auto-generated by CMake -- do not edit +#define REXGLUE_VERSION_MAJOR @REXGLUE_DERIVED_MAJOR@ +#define REXGLUE_VERSION_MINOR @REXGLUE_DERIVED_MINOR@ +#define REXGLUE_VERSION_PATCH @REXGLUE_DERIVED_PATCH@ +#define REXGLUE_VERSION_TWEAK @REXGLUE_DERIVED_TWEAK@ +#define REXGLUE_VERSION_STRING "@REXGLUE_FULL_VERSION@" +#define REXGLUE_VERSION_NUMERIC "@REXGLUE_NUMERIC_VERSION@" + +#define REXGLUE_BUILD_PLATFORM "@REX_PLATFORM@" +#define REXGLUE_BUILD_TIMESTAMP "@REXGLUE_BUILD_TIMESTAMP@" + +// Requires REXGLUE_BUILD_CONFIG compile definition +// Title: "[rexglue-v0.7.5.38-dev.gb27f3f74-Release]" +#define REXGLUE_BUILD_TITLE \ + "[rexglue-v" REXGLUE_VERSION_STRING "-" REXGLUE_BUILD_CONFIG "]" + +// Overlay: "build: rexglue-v0.7.5.38-dev.gb27f3f74-win-amd64-Release@20260420_1430" +#define REXGLUE_BUILD_STAMP \ + "build: rexglue-v" REXGLUE_VERSION_STRING "-" REXGLUE_BUILD_PLATFORM \ + "-" REXGLUE_BUILD_CONFIG "@" REXGLUE_BUILD_TIMESTAMP diff --git a/resources/templates/codegen/_indirect_call.inja b/resources/templates/codegen/_indirect_call.inja new file mode 100644 index 0000000..d4b1830 --- /dev/null +++ b/resources/templates/codegen/_indirect_call.inja @@ -0,0 +1,38 @@ +//============================================================================= +// Indirect Call Dispatch +// +// REX_LOOKUP_FUNC indexes into the per-module dispatch table at +// IMAGE_BASE + IMAGE_SIZE. REX_CALL_INDIRECT_FUNC bounds-checks the target +// against the caller's [REX_CODE_BASE, REX_CODE_BASE + REX_CODE_SIZE + +// REX_THUNK_RESERVE_SIZE) range; out-of-bounds targets and in-bounds +// unregistered slots fall back to rex::runtime::ResolveIndirectFunction, +// which queries the global FunctionDispatcher across every loaded module. +//============================================================================= + +#ifdef REXGLUE_ENABLE_PROFILING +#include +#define REX_PROFILE_INDIRECT_DISPATCH() PROFILE_FUNCTION_DISPATCHED() +#else +#define REX_PROFILE_INDIRECT_DISPATCH() +#endif + +#define REX_LOOKUP_FUNC(x, y) \ + (*(PPCFunc**)(x + REX_IMAGE_BASE + REX_IMAGE_SIZE + (u64(u32(y) - REX_CODE_BASE) * 2))) + +#define REX_CALL_INDIRECT_FUNC(x) \ + do { \ + REX_PROFILE_INDIRECT_DISPATCH(); \ + uint32_t rex_indirect_target_ = (uint32_t)(x); \ + PPCFunc* rex_indirect_func_; \ + if ((uint32_t)(rex_indirect_target_ - REX_CODE_BASE) < \ + REX_CODE_SIZE + REX_THUNK_RESERVE_SIZE) [[likely]] { \ + rex_indirect_func_ = REX_LOOKUP_FUNC(base, rex_indirect_target_); \ + } else { \ + rex_indirect_func_ = nullptr; \ + } \ + if (!rex_indirect_func_) [[unlikely]] { \ + ctx.last_indirect_target = rex_indirect_target_; \ + rex_indirect_func_ = rex::runtime::ResolveIndirectFunction(rex_indirect_target_); \ + } \ + rex_indirect_func_(ctx, base); \ + } while (0) diff --git a/resources/templates/codegen/dll_targets_cmake.inja b/resources/templates/codegen/dll_targets_cmake.inja new file mode 100644 index 0000000..0486594 --- /dev/null +++ b/resources/templates/codegen/dll_targets_cmake.inja @@ -0,0 +1,32 @@ +# Auto-generated by rexglue codegen - DO NOT EDIT +# DLL module shared library targets + +{% for mod in dll_modules %} +# DLL module: {{ mod.target_name }} +if(EXISTS "{{ cmake_var("CMAKE_CURRENT_SOURCE_DIR") }}/{{ mod.output_dir }}/sources.cmake") + set(_REXGLUE_RESTORE_GENERATED_SOURCES FALSE) + if(DEFINED GENERATED_SOURCES) + set(_REXGLUE_PREVIOUS_GENERATED_SOURCES {{ cmake_var("GENERATED_SOURCES") }}) + set(_REXGLUE_RESTORE_GENERATED_SOURCES TRUE) + endif() + include({{ mod.output_dir }}/sources.cmake) + set(DLL_SOURCES_{{ mod.target_name }} {{ cmake_var("GENERATED_SOURCES") }}) + if(_REXGLUE_RESTORE_GENERATED_SOURCES) + set(GENERATED_SOURCES {{ cmake_var("_REXGLUE_PREVIOUS_GENERATED_SOURCES") }}) + else() + unset(GENERATED_SOURCES) + endif() + unset(_REXGLUE_PREVIOUS_GENERATED_SOURCES) + unset(_REXGLUE_RESTORE_GENERATED_SOURCES) + add_library({{ mod.lib_name }} SHARED {{ cmake_var("DLL_SOURCES_" + mod.target_name) }}) + target_include_directories({{ mod.lib_name }} PRIVATE + {{ cmake_var("CMAKE_CURRENT_SOURCE_DIR") }} + {{ cmake_var("CMAKE_CURRENT_SOURCE_DIR") }}/{{ mod.output_dir }} + ) + target_link_libraries({{ mod.lib_name }} PRIVATE rex::runtime) + set_target_properties({{ mod.lib_name }} PROPERTIES + CXX_VISIBILITY_PRESET hidden + ) + rexglue_configure_module_target({{ mod.lib_name }} HOST {{ cmake_var("REXGLUE_HOST_TARGET") }}) +endif() +{% endfor %} diff --git a/resources/templates/codegen/init_cpp.inja b/resources/templates/codegen/init_cpp.inja new file mode 100644 index 0000000..c379117 --- /dev/null +++ b/resources/templates/codegen/init_cpp.inja @@ -0,0 +1,25 @@ +// Generated by rexglue +// DO NOT EDIT - this file is auto-generated + +#include "{{ project }}_init.h" + +{% if has_dll_modules and not is_dll %} +void RegisterRecompiledModules(rex::system::KernelState*); +{% endif %} + +const rex::PPCImageInfo PPCImageConfig = { + .code_base = REX_CODE_BASE, + .code_size = REX_CODE_SIZE, + .image_base = REX_IMAGE_BASE, + .image_size = REX_IMAGE_SIZE, + .func_mappings = PPCFuncMappings, + .rexcrt_heap = REXCRT_HEAP, +{% if has_dll_modules and not is_dll %} + .register_modules = RegisterRecompiledModules, +{% endif %} +}; + +PPCFuncMapping PPCFuncMappings[] = { +{% for fn in functions %}{% if not fn.below_code_base or fn.is_import %} { {{ fn.address }}, {{ fn.name }} }, +{% endif %}{% endfor %} { 0, nullptr } +}; diff --git a/resources/templates/codegen/init_h.inja b/resources/templates/codegen/init_h.inja new file mode 100644 index 0000000..8449a0b --- /dev/null +++ b/resources/templates/codegen/init_h.inja @@ -0,0 +1,320 @@ +// Generated by rexglue +// DO NOT EDIT - this file is auto-generated +#pragma once + +//============================================================================= +// Project Configuration +//============================================================================= + +#define REX_CONFIG_H_INCLUDED + +{% if config_flags.skip_lr %}#define REX_CONFIG_SKIP_LR +{% endif %}{% if config_flags.ctr_as_local %}#define REX_CONFIG_CTR_AS_LOCAL +{% endif %}{% if config_flags.xer_as_local %}#define REX_CONFIG_XER_AS_LOCAL +{% endif %}{% if config_flags.reserved_as_local %}#define REX_CONFIG_RESERVED_AS_LOCAL +{% endif %}{% if config_flags.skip_msr %}#define REX_CONFIG_SKIP_MSR +{% endif %}{% if config_flags.cr_as_local %}#define REX_CONFIG_CR_AS_LOCAL +{% endif %}{% if config_flags.non_argument_as_local %}#define REX_CONFIG_NON_ARGUMENT_AS_LOCAL +{% endif %}{% if config_flags.non_volatile_as_local %}#define REX_CONFIG_NON_VOLATILE_AS_LOCAL +{% endif %} +#define REX_IMAGE_BASE {{ image_base }}ull +#define REX_IMAGE_SIZE {{ image_size }}ull +#define REX_CODE_BASE {{ code_base }}ull +#define REX_CODE_SIZE {{ code_size }}ull +#define REX_THUNK_RESERVE_SIZE {{ thunk_reserve_size }}ull + +#define REXCRT_HEAP {% if rexcrt_heap %}1{% else %}0{% endif %} + +//============================================================================= +// SDK Headers +//============================================================================= + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +//============================================================================= +// Image Info +//============================================================================= + +extern const rex::PPCImageInfo PPCImageConfig; +extern PPCFuncMapping PPCFuncMappings[]; + +//============================================================================= +// Function Definition Macros +//============================================================================= + +#define DECLARE_REX_FUNC(name) \ + REX_EXTERN(name); \ + REX_EXTERN(__imp__##name) + +#define DEFINE_REX_FUNC(name) \ + __attribute__((alias("__imp__" #name))) REX_WEAK_FUNC(name); \ + REX_EXTERN(__imp__##name) + +//============================================================================= +// Function Prologue +//============================================================================= + +#if defined(REXGLUE_PROFILE_GUEST_FUNCTIONS) && defined(REXGLUE_ENABLE_PROFILING) +#include +#if defined(__clang__) +#define REX_FUNC_PROLOGUE() \ + __builtin_assume(((size_t)base & 0x1F) == 0); \ + ZoneNamedN(___tracy_guest_zone, __func__, true) +#elif defined(__GNUC__) +#define REX_FUNC_PROLOGUE() \ + do { \ + if (((size_t)base & 0x1F) != 0) \ + __builtin_unreachable(); \ + } while (0); \ + ZoneNamedN(___tracy_guest_zone, __func__, true) +#else +#define REX_FUNC_PROLOGUE() ZoneNamedN(___tracy_guest_zone, __func__, true) +#endif +#else +#if defined(__clang__) +#define REX_FUNC_PROLOGUE() __builtin_assume(((size_t)base & 0x1F) == 0) +#elif defined(__GNUC__) +#define REX_FUNC_PROLOGUE() \ + do { \ + if (((size_t)base & 0x1F) != 0) \ + __builtin_unreachable(); \ + } while (0) +#else +#define REX_FUNC_PROLOGUE() ((void)0) +#endif +#endif + +//============================================================================= +// Memory Access +//============================================================================= + +#if REX_PLATFORM_WIN32 +#define REX_PHYS_HOST_OFFSET(addr) (((u32)(addr) >= 0xE0000000u) ? 0x1000u : 0u) +#else +#define REX_PHYS_HOST_OFFSET(addr) 0u +#endif + +#define REX_RAW_ADDR(x) (base + (u32)(x) + REX_PHYS_HOST_OFFSET(x)) + +#define REX_LOAD_U8(x) (*(volatile u8*)(base + (u32)(x) + REX_PHYS_HOST_OFFSET(x))) +#define REX_LOAD_U16(x) __builtin_bswap16(*(volatile u16*)(base + (u32)(x) + REX_PHYS_HOST_OFFSET(x))) +#define REX_LOAD_U32(x) __builtin_bswap32(*(volatile u32*)(base + (u32)(x) + REX_PHYS_HOST_OFFSET(x))) +#define REX_LOAD_U64(x) __builtin_bswap64(*(volatile u64*)(base + (u32)(x) + REX_PHYS_HOST_OFFSET(x))) +#define REX_LOAD_STRING(x, len) \ + std::string_view(reinterpret_cast(base + (u32)(x) + REX_PHYS_HOST_OFFSET(x)), (len)) + +#define REX_STORE_U8(x, y) (*(volatile u8*)(base + (u32)(x) + REX_PHYS_HOST_OFFSET(x)) = (y)) +#define REX_STORE_U16(x, y) (*(volatile u16*)(base + (u32)(x) + REX_PHYS_HOST_OFFSET(x)) = __builtin_bswap16(y)) +#define REX_STORE_U32(x, y) (*(volatile u32*)(base + (u32)(x) + REX_PHYS_HOST_OFFSET(x)) = __builtin_bswap32(y)) +#define REX_STORE_U64(x, y) (*(volatile u64*)(base + (u32)(x) + REX_PHYS_HOST_OFFSET(x)) = __builtin_bswap64(y)) + +#define REX_MEMORY_SIZE 0x100000000ull + +//============================================================================= +// MMIO +//============================================================================= + +#define REX_IS_MMIO_ADDR(addr) ((addr) >= 0x7F000000u && (addr) < 0x80000000u) + +#define REX_MM_STORE_U8(addr, val) \ + do { \ + u32 _mmio_addr = (addr); \ + if (REX_IS_MMIO_ADDR(_mmio_addr)) { \ + rex::runtime::MMIOHandler::global_handler()->CheckStore(_mmio_addr, \ + static_cast(val)); \ + } else { \ + *(volatile u8*)(base + _mmio_addr + REX_PHYS_HOST_OFFSET(_mmio_addr)) = (val); \ + } \ + } while (0) + +#define REX_MM_STORE_U16(addr, val) \ + do { \ + u32 _mmio_addr = (addr); \ + if (REX_IS_MMIO_ADDR(_mmio_addr)) { \ + rex::runtime::MMIOHandler::global_handler()->CheckStore(_mmio_addr, \ + static_cast(val)); \ + } else { \ + *(volatile u16*)(base + _mmio_addr + REX_PHYS_HOST_OFFSET(_mmio_addr)) = \ + __builtin_bswap16(val); \ + } \ + } while (0) + +#define REX_MM_STORE_U32(addr, val) \ + do { \ + u32 _mmio_addr = (addr); \ + if (REX_IS_MMIO_ADDR(_mmio_addr)) { \ + rex::runtime::MMIOHandler::global_handler()->CheckStore(_mmio_addr, \ + static_cast(val)); \ + } else { \ + *(volatile u32*)(base + _mmio_addr + REX_PHYS_HOST_OFFSET(_mmio_addr)) = \ + __builtin_bswap32(val); \ + } \ + } while (0) + +#define REX_MM_STORE_U64(addr, val) \ + do { \ + u32 _mmio_addr = (addr); \ + if (REX_IS_MMIO_ADDR(_mmio_addr)) { \ + u64 _v64 = static_cast(val); \ + rex::runtime::MMIOHandler::global_handler()->CheckStore(_mmio_addr, \ + static_cast(_v64 >> 32)); \ + rex::runtime::MMIOHandler::global_handler()->CheckStore(_mmio_addr + 4, \ + static_cast(_v64)); \ + } else { \ + *(volatile u64*)(base + _mmio_addr + REX_PHYS_HOST_OFFSET(_mmio_addr)) = \ + __builtin_bswap64(val); \ + } \ + } while (0) + +#define REX_MM_LOAD_U8(addr) \ + (REX_IS_MMIO_ADDR(addr) ? ({ \ + u32 _v; \ + rex::runtime::MMIOHandler::global_handler()->CheckLoad(addr, &_v); \ + static_cast(_v); \ + }) \ + : *(volatile u8*)(base + (addr) + REX_PHYS_HOST_OFFSET(addr))) + +#define REX_MM_LOAD_U16(addr) \ + (REX_IS_MMIO_ADDR(addr) \ + ? ({ \ + u32 _v; \ + rex::runtime::MMIOHandler::global_handler()->CheckLoad(addr, &_v); \ + static_cast(_v); \ + }) \ + : __builtin_bswap16(*(volatile u16*)(base + (addr) + REX_PHYS_HOST_OFFSET(addr)))) + +#define REX_MM_LOAD_U32(addr) \ + (REX_IS_MMIO_ADDR(addr) \ + ? ({ \ + u32 _v; \ + rex::runtime::MMIOHandler::global_handler()->CheckLoad(addr, &_v); \ + _v; \ + }) \ + : __builtin_bswap32(*(volatile u32*)(base + (addr) + REX_PHYS_HOST_OFFSET(addr)))) + +#define REX_MM_LOAD_U64(addr) \ + (REX_IS_MMIO_ADDR(addr) \ + ? ({ \ + u32 _hi, _lo; \ + rex::runtime::MMIOHandler::global_handler()->CheckLoad(addr, &_hi); \ + rex::runtime::MMIOHandler::global_handler()->CheckLoad((addr) + 4, &_lo); \ + (static_cast(_hi) << 32) | _lo; \ + }) \ + : __builtin_bswap64(*(volatile u64*)(base + (addr) + REX_PHYS_HOST_OFFSET(addr)))) + +//============================================================================= +// Function Dispatch +//============================================================================= + +#define REX_CALL_FUNC(x) x(ctx, base) + +{% include "codegen/_indirect_call.inja" %} + +//============================================================================= +// Flush Mode +//============================================================================= + +#define REX_SET_FLUSH_MODE(enable) \ + do { if (enable) ctx.fpscr.enableFlushMode(); else ctx.fpscr.disableFlushMode(); } while (0) + +//============================================================================= +// Misc +//============================================================================= + +#define REX_UNIMPLEMENTED(addr, opcode) \ + throw std::runtime_error("Unimplemented PPC instruction: " opcode) + +#define REX_QUERY_TIMEBASE() rex::chrono::Clock::QueryGuestTickCount() + +//============================================================================= +// Setjmp/Longjmp +//============================================================================= + +inline std::unordered_map& get_jmp_buf_map() { + static thread_local std::unordered_map map; + return map; +} + +#define ppc_setjmp(guest_buf_addr) (setjmp(::get_jmp_buf_map()[(guest_buf_addr)])) + +[[noreturn]] inline void ppc_longjmp(u32 guest_buf_addr, int val) { + auto& map = get_jmp_buf_map(); + auto it = map.find(guest_buf_addr); + if (it != map.end()) { + longjmp(it->second, val); + } + std::abort(); +} + +//============================================================================= +// Trap Handling +//============================================================================= + +inline void ppc_trap(PPCContext& ctx, u8* base, u16 trap_type) { + switch (trap_type) { + case 20: + case 26: { + auto str = REX_LOAD_STRING(ctx.r3.u32, ctx.r4.u16); + REXCPU_DEBUG("(service trap) {}", str); + break; + } + case 0: + case 22: + REXCPU_WARN("tw/td trap hit (type {})", trap_type); + break; + case 25: + break; + default: + REXCPU_WARN("Unknown trap type {}", trap_type); + break; + } +} + +//============================================================================= +// Interrupt Locks +//============================================================================= + +inline std::atomic& ppc_global_lock_count_() { + static std::atomic count{0}; + return count; +} + +#define REX_CHECK_GLOBAL_LOCK() \ + ([&]() -> u64 { \ + auto lock_ = rex::thread::global_critical_region::AcquireDirect(); \ + return ppc_global_lock_count_().load() ? 0 : 0x8000; \ + }()) + +#define REX_ENTER_GLOBAL_LOCK() \ + do { \ + rex::thread::global_critical_region::mutex().lock(); \ + ppc_global_lock_count_().fetch_add(1); \ + } while (0) + +#define REX_LEAVE_GLOBAL_LOCK() \ + do { \ + auto old_count_ = ppc_global_lock_count_().fetch_sub(1); \ + assert(old_count_ >= 1 && "LeaveGlobalLock called without matching EnterGlobalLock"); \ + rex::thread::global_critical_region::mutex().unlock(); \ + } while (0) + +//============================================================================= +// Function Declarations +//============================================================================= + +{% for fn in functions %}DECLARE_REX_FUNC({{ fn.name }}); +{% endfor %} diff --git a/resources/templates/codegen/module_registry_cpp.inja b/resources/templates/codegen/module_registry_cpp.inja new file mode 100644 index 0000000..e52471a --- /dev/null +++ b/resources/templates/codegen/module_registry_cpp.inja @@ -0,0 +1,14 @@ +//============================================================================= +// ReXGlue Generated - {{ project }} Module Registry +//============================================================================= + +#include + +void RegisterRecompiledModules(rex::system::KernelState* kernel_state) { +{% for mod in dll_modules %} + kernel_state->RegisterRecompiledModule( + "{{ mod.pe_name }}", + "{{ mod.guest_path }}", + "{{ mod.shared_lib_name }}"); +{% endfor %} +} diff --git a/resources/templates/codegen/register_cpp.inja b/resources/templates/codegen/register_cpp.inja new file mode 100644 index 0000000..a864dc1 --- /dev/null +++ b/resources/templates/codegen/register_cpp.inja @@ -0,0 +1,21 @@ +//============================================================================= +// ReXGlue Generated - {{ project }} Function Registration +//============================================================================= + +#include "{{ project }}_init.h" +#include + +{% if is_dll %} +#ifdef _WIN32 +#define REX_MODULE_EXPORT __declspec(dllexport) +#else +#define REX_MODULE_EXPORT __attribute__((visibility("default"))) +#endif + +extern "C" REX_MODULE_EXPORT +void ReXModule_Register(rex::runtime::IModuleRegistrar* registrar) { +{% else %} +void {{ project }}_RegisterFunctions(rex::runtime::IModuleRegistrar* registrar) { +{% endif %} +{% for fn in functions %}{% if not fn.below_code_base or fn.is_import %} registrar->SetFunction({{ fn.address }}, {{ fn.name }}); +{% endif %}{% endfor %}} diff --git a/resources/templates/codegen/sources_cmake.inja b/resources/templates/codegen/sources_cmake.inja new file mode 100644 index 0000000..cfadd56 --- /dev/null +++ b/resources/templates/codegen/sources_cmake.inja @@ -0,0 +1,12 @@ +# Auto-generated by rexglue codegen - DO NOT EDIT +# +# IMPORTANT: For SEH (Structured Exception Handling) support on Windows, +# add /EHa to your compile options: +# target_compile_options(your_target PRIVATE $<$:/EHa>) +# +set(GENERATED_SOURCES + {{ cmake_var("CMAKE_CURRENT_LIST_DIR") }}/{{ project }}_init.cpp + {{ cmake_var("CMAKE_CURRENT_LIST_DIR") }}/{{ project }}_register.cpp +{% if has_dll_modules and not is_dll %} {{ cmake_var("CMAKE_CURRENT_LIST_DIR") }}/module_registry.cpp +{% endif %}{% for file in recomp_files %} {{ cmake_var("CMAKE_CURRENT_LIST_DIR") }}/{{ file }} +{% endfor %}) diff --git a/resources/templates/init/app_header.inja b/resources/templates/init/app_header.inja new file mode 100644 index 0000000..c6bd00c --- /dev/null +++ b/resources/templates/init/app_header.inja @@ -0,0 +1,27 @@ +// {{ names.snake_case }} - ReXGlue Recompiled Project +// +// Customize your app by overriding virtual hooks from rex::ReXApp. + +#pragma once + +#include + +class {{ names.pascal_case }}App : public rex::ReXApp { + public: + using rex::ReXApp::ReXApp; + + static std::unique_ptr Create( + rex::ui::WindowedAppContext& ctx) { + return std::unique_ptr<{{ names.pascal_case }}App>(new {{ names.pascal_case }}App(ctx, "{{ names.snake_case }}", + PPCImageConfig)); + } + + // Override virtual hooks for customization: + // void OnPostInitLogging() override {} + // void OnPreSetup(rex::RuntimeConfig& config) override {} + // void OnLoadXexImage(std::string& xex_image) override {} + // void OnPostSetup() override {} + // void OnCreateDialogs(rex::ui::ImGuiDrawer* drawer) override {} + // void OnShutdown() override {} + // void OnConfigurePaths(rex::PathConfig& paths) override {} +}; diff --git a/resources/templates/init/cmake_presets.inja b/resources/templates/init/cmake_presets.inja new file mode 100644 index 0000000..9b69ed9 --- /dev/null +++ b/resources/templates/init/cmake_presets.inja @@ -0,0 +1,140 @@ +{ + "version": 6, + "cmakeMinimumRequired": { "major": 3, "minor": 25, "patch": 0 }, + "configurePresets": [ + { + "name": "windows-base", + "hidden": true, + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "cacheVariables": { + "CMAKE_C_COMPILER": "clang", + "CMAKE_CXX_COMPILER": "clang++" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + } + }, + { + "name": "linux-base", + "hidden": true, + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "cacheVariables": { + "CMAKE_C_COMPILER": "clang-20", + "CMAKE_CXX_COMPILER": "clang++-20" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Linux" + } + }, + { + "name": "windows-arm64-base", + "hidden": true, + "inherits": "windows-base", + "cacheVariables": { + "CMAKE_C_FLAGS": "-march=armv8-a", + "CMAKE_CXX_FLAGS": "-march=armv8-a" + } + }, + { + "name": "linux-arm64-base", + "hidden": true, + "inherits": "linux-base", + "cacheVariables": { + "CMAKE_C_FLAGS": "-march=armv8-a", + "CMAKE_CXX_FLAGS": "-march=armv8-a" + } + }, + { + "name": "win-amd64-debug", + "displayName": "Windows AMD64 Debug", + "inherits": "windows-base", + "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" } + }, + { + "name": "win-amd64-release", + "displayName": "Windows AMD64 Release", + "inherits": "windows-base", + "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" } + }, + { + "name": "linux-amd64-debug", + "displayName": "Linux AMD64 Debug", + "inherits": "linux-base", + "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" } + }, + { + "name": "linux-amd64-release", + "displayName": "Linux AMD64 Release", + "inherits": "linux-base", + "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" } + }, + { + "name": "win-amd64-relwithdebinfo", + "displayName": "Windows AMD64 RelWithDebInfo", + "inherits": "windows-base", + "cacheVariables": { "CMAKE_BUILD_TYPE": "RelWithDebInfo" } + }, + { + "name": "linux-amd64-relwithdebinfo", + "displayName": "Linux AMD64 RelWithDebInfo", + "inherits": "linux-base", + "cacheVariables": { "CMAKE_BUILD_TYPE": "RelWithDebInfo" } + }, + { + "name": "win-arm64-debug", + "displayName": "Windows ARM64 Debug", + "inherits": "windows-arm64-base", + "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" } + }, + { + "name": "win-arm64-release", + "displayName": "Windows ARM64 Release", + "inherits": "windows-arm64-base", + "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" } + }, + { + "name": "win-arm64-relwithdebinfo", + "displayName": "Windows ARM64 RelWithDebInfo", + "inherits": "windows-arm64-base", + "cacheVariables": { "CMAKE_BUILD_TYPE": "RelWithDebInfo" } + }, + { + "name": "linux-arm64-debug", + "displayName": "Linux ARM64 Debug", + "inherits": "linux-arm64-base", + "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" } + }, + { + "name": "linux-arm64-release", + "displayName": "Linux ARM64 Release", + "inherits": "linux-arm64-base", + "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" } + }, + { + "name": "linux-arm64-relwithdebinfo", + "displayName": "Linux ARM64 RelWithDebInfo", + "inherits": "linux-arm64-base", + "cacheVariables": { "CMAKE_BUILD_TYPE": "RelWithDebInfo" } + } + ], + "buildPresets": [ + { "name": "win-amd64-debug", "configurePreset": "win-amd64-debug" }, + { "name": "win-amd64-release", "configurePreset": "win-amd64-release" }, + { "name": "win-amd64-relwithdebinfo", "configurePreset": "win-amd64-relwithdebinfo" }, + { "name": "linux-amd64-debug", "configurePreset": "linux-amd64-debug" }, + { "name": "linux-amd64-release", "configurePreset": "linux-amd64-release" }, + { "name": "linux-amd64-relwithdebinfo", "configurePreset": "linux-amd64-relwithdebinfo" }, + { "name": "win-arm64-debug", "configurePreset": "win-arm64-debug" }, + { "name": "win-arm64-release", "configurePreset": "win-arm64-release" }, + { "name": "win-arm64-relwithdebinfo", "configurePreset": "win-arm64-relwithdebinfo" }, + { "name": "linux-arm64-debug", "configurePreset": "linux-arm64-debug" }, + { "name": "linux-arm64-release", "configurePreset": "linux-arm64-release" }, + { "name": "linux-arm64-relwithdebinfo", "configurePreset": "linux-arm64-relwithdebinfo" } + ] +} diff --git a/resources/templates/init/cmakelists.inja b/resources/templates/init/cmakelists.inja new file mode 100644 index 0000000..859e6e6 --- /dev/null +++ b/resources/templates/init/cmakelists.inja @@ -0,0 +1,24 @@ +# {{ names.snake_case }} - ReXGlue Recompiled Project +# +# SDK boilerplate lives in generated/rexglue.cmake. + +cmake_minimum_required(VERSION 3.25) +project({{ names.snake_case }} LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +include(generated/rexglue.cmake) + +# Sources +set({{ names.upper_case }}_SOURCES + src/main.cpp +) + +if(WIN32) + add_executable({{ names.snake_case }} WIN32 {{ cmake_var(names.upper_case + "_SOURCES") }}) +else() + add_executable({{ names.snake_case }} {{ cmake_var(names.upper_case + "_SOURCES") }}) +endif() + +rexglue_setup_target({{ names.snake_case }}) diff --git a/resources/templates/init/main_cpp.inja b/resources/templates/init/main_cpp.inja new file mode 100644 index 0000000..cb6ffd9 --- /dev/null +++ b/resources/templates/init/main_cpp.inja @@ -0,0 +1,7 @@ +// {{ names.snake_case }} - ReXGlue Recompiled Project + +#include "{{ entrypoint_out_dir }}/{{ names.snake_case }}_init.h" + +#include "{{ names.snake_case }}_app.h" + +REX_DEFINE_APP({{ names.snake_case }}, {{ names.pascal_case }}App::Create) diff --git a/resources/templates/init/manifest_toml.inja b/resources/templates/init/manifest_toml.inja new file mode 100644 index 0000000..d09a0f6 --- /dev/null +++ b/resources/templates/init/manifest_toml.inja @@ -0,0 +1,21 @@ +# Generated by ReXGlue v{{ sdk_version_full }} on {{ generated_on }}. + +[project] +name = "{{ names.snake_case }}" +{% if include_stamp -%} +sdk_version = "{{ sdk_version }}" +{% endif -%} +{% if game_root -%} +game_root = "{{ game_root }}" +{% endif %} +[entrypoint] +file_path = "{{ xex_path }}" +out_directory_path = "{{ out_directory_path }}" +includes = [] +{% for m in modules %} +[[modules]] +guest_path = "{{ m.guest_path }}" +file_path = "{{ m.file_path }}" +out_directory_path = "{{ m.out_directory_path }}" +includes = [] +{% endfor -%} diff --git a/resources/templates/init/rexglue_cmake.inja b/resources/templates/init/rexglue_cmake.inja new file mode 100644 index 0000000..2137491 --- /dev/null +++ b/resources/templates/init/rexglue_cmake.inja @@ -0,0 +1,68 @@ +# Auto-generated by rexglue - DO NOT EDIT + +# SDK version +# Set REXSDK_VERSION to pin a specific SDK version. +# Otherwise, the version of the SDK that generated this file is used. +set(REXSDK_VERSION "" CACHE STRING "Override SDK version (leave empty for default)") + +# Find SDK +set(REXSDK_DIR "" CACHE PATH "Path to rexglue-sdk source tree") +if(REXSDK_DIR) + add_subdirectory("{{ cmake_var("REXSDK_DIR") }}" rexglue-sdk) + message(STATUS "Using ReXGlue SDK from source tree: {{ cmake_var("REXSDK_DIR") }}") +else() + if(REXSDK_VERSION) + find_package(rexglue {{ cmake_var("REXSDK_VERSION") }} EXACT QUIET CONFIG) + else() + find_package(rexglue {{ sdk_version }} QUIET CONFIG) + endif() + if(NOT rexglue_FOUND) + message(FATAL_ERROR + "ReXGlue SDK not found. Either:\n" + " - Set REXSDK_DIR to the rexglue-sdk source tree (e.g. thirdparty/rexglue-sdk)\n" + " - Install the SDK package and ensure it is on CMAKE_PREFIX_PATH") + endif() + message(STATUS "Found ReXGlue SDK ${REXGLUE_VERSION_STRING} at ${rexglue_DIR}") +endif() + +# Host target name used by the codegen-emitted dll_targets.cmake to colocate +# guest DLLs with the host EXE. Defaults to PROJECT_NAME (which the +# manifest-first init flow sets equal to the host target name). +if(NOT DEFINED REXGLUE_HOST_TARGET) + set(REXGLUE_HOST_TARGET {{ cmake_var("PROJECT_NAME") }}) +endif() + +# Include entrypoint generated code if codegen has been run. +if(EXISTS "{{ cmake_var("CMAKE_CURRENT_SOURCE_DIR") }}/{{ entrypoint_out_dir }}/sources.cmake") + include({{ entrypoint_out_dir }}/sources.cmake) + set(REXGLUE_ENTRYPOINT_GENERATED_SOURCES {{ cmake_var("GENERATED_SOURCES") }}) + set(REXGLUE_ENTRYPOINT_INCLUDE_DIR "{{ cmake_var("CMAKE_CURRENT_SOURCE_DIR") }}/{{ entrypoint_out_dir }}") +endif() + +# Configure a rexglue target with SDK libraries and platform settings. +# Call after add_executable() in your CMakeLists.txt. +# Usage: rexglue_setup_target() +macro(rexglue_setup_target target_name) + target_sources({{ cmake_var("target_name") }} PRIVATE {{ cmake_var("REXGLUE_ENTRYPOINT_GENERATED_SOURCES") }}) + target_include_directories({{ cmake_var("target_name") }} PRIVATE + {{ cmake_var("CMAKE_CURRENT_SOURCE_DIR") }} + {{ cmake_var("CMAKE_CURRENT_SOURCE_DIR") }}/src + {{ cmake_var("REXGLUE_ENTRYPOINT_INCLUDE_DIR") }} + ) + target_link_libraries({{ cmake_var("target_name") }} PRIVATE rex::runtime) + rexglue_configure_target({{ cmake_var("target_name") }}) +endmacro() + +# Include DLL module shared library targets if codegen has generated them +if(EXISTS "{{ cmake_var("CMAKE_CURRENT_SOURCE_DIR") }}/{{ entrypoint_out_dir }}/dll_targets.cmake") + include({{ entrypoint_out_dir }}/dll_targets.cmake) +endif() + +# Codegen target - run 'cmake --build . --target {{ names.snake_case }}_codegen' +# Uses the manifest to drive codegen for all modules (entrypoint + DLLs). +add_custom_target({{ names.snake_case }}_codegen + COMMAND $ codegen {{ cmake_var("CMAKE_CURRENT_SOURCE_DIR") }}/{{ names.snake_case }}_manifest.toml + WORKING_DIRECTORY {{ cmake_var("CMAKE_CURRENT_SOURCE_DIR") }} + COMMENT "Generating recompiled code for {{ names.snake_case }}" + VERBATIM +) diff --git a/resources/templates/test/ppc_config_h.inja b/resources/templates/test/ppc_config_h.inja new file mode 100644 index 0000000..f2c2d62 --- /dev/null +++ b/resources/templates/test/ppc_config_h.inja @@ -0,0 +1,180 @@ +// Generated by rexglue recompile-tests + +#pragma once + +#ifndef REX_CONFIG_H_INCLUDED +#define REX_CONFIG_H_INCLUDED + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +// Test code base address (matches -Ttext=0x82010000 linker option) +#define REX_IMAGE_BASE 0x{{ image_base }}ull +#define REX_IMAGE_SIZE 0x{{ image_size }}ull +#define REX_CODE_BASE 0x{{ code_base }}ull +#define REX_CODE_SIZE 0x{{ code_size }}ull +#define REX_THUNK_RESERVE_SIZE 0x10000ull + +#endif // REX_CONFIG_H_INCLUDED + +// Prologue macro (codegen init header defines this with Tracy/alignment hints; +// tests just need a no-op) +#ifndef REX_FUNC_PROLOGUE +#if defined(__clang__) +#define REX_FUNC_PROLOGUE() __builtin_assume(((size_t)base & 0x1F) == 0) +#elif defined(__GNUC__) +#define REX_FUNC_PROLOGUE() \ + do { \ + if (((size_t)base & 0x1F) != 0) \ + __builtin_unreachable(); \ + } while (0) +#else +#define REX_FUNC_PROLOGUE() ((void)0) +#endif +#endif + +// Function definition macros (same as codegen init header) +#ifndef DECLARE_REX_FUNC +#define DECLARE_REX_FUNC(name) \ + REX_EXTERN(name); \ + REX_EXTERN(__imp__##name) +#endif + +#ifndef DEFINE_REX_FUNC +#define DEFINE_REX_FUNC(name) \ + __attribute__((alias("__imp__" #name))) REX_WEAK_FUNC(name); \ + REX_EXTERN(__imp__##name) +#endif + +#if REX_PLATFORM_WIN32 +#define REX_PHYS_HOST_OFFSET(addr) (((u32)(addr) >= 0xE0000000u) ? 0x1000u : 0u) +#else +#define REX_PHYS_HOST_OFFSET(addr) 0u +#endif + +#define REX_RAW_ADDR(x) (base + (u32)(x) + REX_PHYS_HOST_OFFSET(x)) + +#define REX_LOAD_U8(x) (*(volatile u8*)(base + (u32)(x) + REX_PHYS_HOST_OFFSET(x))) +#define REX_LOAD_U16(x) __builtin_bswap16(*(volatile u16*)(base + (u32)(x) + REX_PHYS_HOST_OFFSET(x))) +#define REX_LOAD_U32(x) __builtin_bswap32(*(volatile u32*)(base + (u32)(x) + REX_PHYS_HOST_OFFSET(x))) +#define REX_LOAD_U64(x) __builtin_bswap64(*(volatile u64*)(base + (u32)(x) + REX_PHYS_HOST_OFFSET(x))) +#define REX_LOAD_STRING(x, len) \ + std::string_view(reinterpret_cast(base + (u32)(x) + REX_PHYS_HOST_OFFSET(x)), (len)) + +#define REX_STORE_U8(x, y) (*(volatile u8*)(base + (u32)(x) + REX_PHYS_HOST_OFFSET(x)) = (y)) +#define REX_STORE_U16(x, y) (*(volatile u16*)(base + (u32)(x) + REX_PHYS_HOST_OFFSET(x)) = __builtin_bswap16(y)) +#define REX_STORE_U32(x, y) (*(volatile u32*)(base + (u32)(x) + REX_PHYS_HOST_OFFSET(x)) = __builtin_bswap32(y)) +#define REX_STORE_U64(x, y) (*(volatile u64*)(base + (u32)(x) + REX_PHYS_HOST_OFFSET(x)) = __builtin_bswap64(y)) + +#define REX_MEMORY_SIZE 0x100000000ull + +//============================================================================= +// Function Dispatch +//============================================================================= + +#define REX_CALL_FUNC(x) x(ctx, base) + +{% include "codegen/_indirect_call.inja" %} + +//============================================================================= +// Flush Mode +//============================================================================= + +#define REX_SET_FLUSH_MODE(enable) \ + do { if (enable) ctx.fpscr.enableFlushMode(); else ctx.fpscr.disableFlushMode(); } while (0) + +//============================================================================= +// Misc +//============================================================================= + +#define REX_UNIMPLEMENTED(addr, opcode) \ + throw std::runtime_error("Unimplemented PPC instruction: " opcode) + +#define REX_QUERY_TIMEBASE() rex::chrono::Clock::QueryGuestTickCount() + +//============================================================================= +// Setjmp/Longjmp +//============================================================================= + +inline std::unordered_map& get_jmp_buf_map() { + static thread_local std::unordered_map map; + return map; +} + +#define ppc_setjmp(guest_buf_addr) (setjmp(::get_jmp_buf_map()[(guest_buf_addr)])) + +[[noreturn]] inline void ppc_longjmp(u32 guest_buf_addr, int val) { + auto& map = get_jmp_buf_map(); + auto it = map.find(guest_buf_addr); + if (it != map.end()) { + longjmp(it->second, val); + } + std::abort(); +} + +//============================================================================= +// Trap Handling +//============================================================================= + +inline void ppc_trap(PPCContext& ctx, u8* base, u16 trap_type) { + switch (trap_type) { + case 20: + case 26: { + auto str = REX_LOAD_STRING(ctx.r3.u32, ctx.r4.u16); + REXCPU_DEBUG("(service trap) {}", str); + break; + } + case 0: + case 22: + REXCPU_WARN("tw/td trap hit (type {})", trap_type); + break; + case 25: + break; + default: + REXCPU_WARN("Unknown trap type {}", trap_type); + break; + } +} + +//============================================================================= +// Interrupt Locks +//============================================================================= + +inline std::atomic& ppc_global_lock_count_() { + static std::atomic count{0}; + return count; +} + +#define REX_CHECK_GLOBAL_LOCK() \ + ([&]() -> u64 { \ + auto lock_ = rex::thread::global_critical_region::AcquireDirect(); \ + return ppc_global_lock_count_().load() ? 0 : 0x8000; \ + }()) + +#define REX_ENTER_GLOBAL_LOCK() \ + do { \ + rex::thread::global_critical_region::mutex().lock(); \ + ppc_global_lock_count_().fetch_add(1); \ + } while (0) + +#define REX_LEAVE_GLOBAL_LOCK() \ + do { \ + auto old_count_ = ppc_global_lock_count_().fetch_sub(1); \ + assert(old_count_ >= 1 && "LeaveGlobalLock called without matching EnterGlobalLock"); \ + rex::thread::global_critical_region::mutex().unlock(); \ + } while (0) + diff --git a/resources/templates/test/ppc_test_cases_cpp.inja b/resources/templates/test/ppc_test_cases_cpp.inja new file mode 100644 index 0000000..ebc731b --- /dev/null +++ b/resources/templates/test/ppc_test_cases_cpp.inja @@ -0,0 +1,94 @@ +// Generated by rexglue recompile-tests +// DO NOT EDIT - this file is auto-generated + +#include +#include +#include +#include +#include "ppc_config.h" +#include +#include +#include "ppc_test_decls.h" + +// Global memory instance - same class used by real runtime +static rex::memory::Memory& get_memory() { + static rex::memory::Memory memory; + static bool initialized = false; + if (!initialized) { + if (!memory.Initialize()) { + throw std::runtime_error("Failed to initialize memory"); + } + // Allocate test memory region starting after null guard page (0x10000) + auto* heap = memory.LookupHeap(0x10000); + if (heap) { + // Allocate from end of guard page (0x10000) up to cover test addresses + heap->AllocFixed(0x10000, 0x10000000, 0x1000, + rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite); + } + initialized = true; + } + return memory; +} + +## for test in tests +TEST_CASE("{{ test.name }}", "[ppc][{{ test.category }}][{{ test.stem }}]") { + auto& mem = get_memory(); + uint8_t* memory = mem.virtual_membase(); + PPCContext ctx{}; + ctx.fpscr.loadFromHost(); + +## for reg in test.inputs.registers +## if reg.type == "cr" + ctx.cr0.set_raw(({{ reg.value }} >> 28) & 0xF); + ctx.cr1.set_raw(({{ reg.value }} >> 24) & 0xF); + ctx.cr2.set_raw(({{ reg.value }} >> 20) & 0xF); + ctx.cr3.set_raw(({{ reg.value }} >> 16) & 0xF); + ctx.cr4.set_raw(({{ reg.value }} >> 12) & 0xF); + ctx.cr5.set_raw(({{ reg.value }} >> 8) & 0xF); + ctx.cr6.set_raw(({{ reg.value }} >> 4) & 0xF); + ctx.cr7.set_raw({{ reg.value }} & 0xF); +## else if reg.type == "vector" + ctx.{{ reg.reg }}.u32[3] = 0x{{ reg.values.0 }}; + ctx.{{ reg.reg }}.u32[2] = 0x{{ reg.values.1 }}; + ctx.{{ reg.reg }}.u32[1] = 0x{{ reg.values.2 }}; + ctx.{{ reg.reg }}.u32[0] = 0x{{ reg.values.3 }}; +## else if reg.type == "float" + ctx.{{ reg.reg }}.f64 = {{ reg.value }}; +## else + ctx.{{ reg.reg }}.u64 = {{ reg.value }}; +## endif +## endfor +## for mem_in in test.inputs.memory +## for entry in mem_in.bytes + memory[0x{{ mem_in.address }} + 0x{{ entry.offset }}] = 0x{{ entry.value }}; +## endfor +## endfor + + {{ test.symbol }}(ctx, memory); + +## for reg in test.outputs.registers +## if reg.type == "cr" + { + uint32_t cr_actual = (ctx.cr0.raw() << 28) | (ctx.cr1.raw() << 24) | (ctx.cr2.raw() << 20) | (ctx.cr3.raw() << 16) | (ctx.cr4.raw() << 12) | (ctx.cr5.raw() << 8) | (ctx.cr6.raw() << 4) | ctx.cr7.raw(); + REQUIRE(cr_actual == {{ reg.value }}); + } +## else if reg.type == "vector" + REQUIRE(ctx.{{ reg.reg }}.u32[3] == 0x{{ reg.values.0 }}); + REQUIRE(ctx.{{ reg.reg }}.u32[2] == 0x{{ reg.values.1 }}); + REQUIRE(ctx.{{ reg.reg }}.u32[1] == 0x{{ reg.values.2 }}); + REQUIRE(ctx.{{ reg.reg }}.u32[0] == 0x{{ reg.values.3 }}); +## else if reg.type == "float" + REQUIRE(ctx.{{ reg.reg }}.f64 == {{ reg.value }}); +## else + REQUIRE(ctx.{{ reg.reg }}.u64 == {{ reg.value }}); +## endif +## endfor +## for mem_out in test.outputs.memory +## for entry in mem_out.bytes + REQUIRE(memory[0x{{ mem_out.address }} + 0x{{ entry.offset }}] == 0x{{ entry.value }}); +## endfor +## endfor +} + +## endfor diff --git a/resources/templates/test/ppc_test_decls_h.inja b/resources/templates/test/ppc_test_decls_h.inja new file mode 100644 index 0000000..d7d5ded --- /dev/null +++ b/resources/templates/test/ppc_test_decls_h.inja @@ -0,0 +1,9 @@ +// Generated by rexglue recompile-tests +#pragma once + +#include "ppc_config.h" +#include + +## for func in functions +DECLARE_REX_FUNC({{ func.name }}); +## endfor diff --git a/resources/templates/test/ppc_test_functions_cpp.inja b/resources/templates/test/ppc_test_functions_cpp.inja new file mode 100644 index 0000000..6001ef1 --- /dev/null +++ b/resources/templates/test/ppc_test_functions_cpp.inja @@ -0,0 +1,14 @@ +// Generated by rexglue recompile-tests +// DO NOT EDIT - this file is auto-generated + +#include "ppc_config.h" +#include +#include // For REX_FATAL on unresolved calls + +// Forward declarations +## for func in functions +DECLARE_REX_FUNC({{ func.name }}); +## endfor + +// Function implementations +{{ functions_code }} diff --git a/scripts/PSReX/PSReX.psd1 b/scripts/PSReX/PSReX.psd1 new file mode 100644 index 0000000..4c732a0 --- /dev/null +++ b/scripts/PSReX/PSReX.psd1 @@ -0,0 +1,28 @@ +@{ + RootModule = 'PSReX.psm1' + ModuleVersion = '0.1.0' + GUID = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890' + Author = 'Tom Clay' + Description = 'ReXGlue SDK dev tooling' + PowerShellVersion = '7.0' + FunctionsToExport = @( + 'Invoke-ReXConfigure' + 'Invoke-ReXBuild' + 'Invoke-ReXTest' + 'Invoke-ReXInstall' + 'Invoke-ReXFormat' + 'Invoke-ReXLint' + 'Invoke-ReXSetup' + ) + AliasesToExport = @( + 'rex-configure' + 'rex-build' + 'rex-test' + 'rex-install' + 'rex-format' + 'rex-lint' + 'rex-setup' + ) + CmdletsToExport = @() + VariablesToExport = @() +} diff --git a/scripts/PSReX/PSReX.psm1 b/scripts/PSReX/PSReX.psm1 new file mode 100644 index 0000000..0e39151 --- /dev/null +++ b/scripts/PSReX/PSReX.psm1 @@ -0,0 +1,33 @@ +<# +.SYNOPSIS + PSReX module root - dot-sources helpers and public functions, registers aliases. +.NOTES + Copyright (c) 2026 Tom Clay + All rights reserved. + Licensed under the BSD 3-Clause License. + See LICENSE file in the project root for full license text. +#> +#Requires -Version 7.0 + +$Private = @(Get-ChildItem -Path "$PSScriptRoot/Private/*.ps1" -ErrorAction SilentlyContinue) +foreach ($file in $Private) { . $file.FullName } + +$Public = @(Get-ChildItem -Path "$PSScriptRoot/Public/*.ps1" -ErrorAction SilentlyContinue) +foreach ($file in $Public) { . $file.FullName } + +# Ensure VS developer tools are on PATH (no-op if already active or not on Windows) +Initialize-VsEnvironment + +# Convenience aliases +New-Alias -Name 'rex-configure' -Value 'Invoke-ReXConfigure' +New-Alias -Name 'rex-build' -Value 'Invoke-ReXBuild' +New-Alias -Name 'rex-test' -Value 'Invoke-ReXTest' +New-Alias -Name 'rex-install' -Value 'Invoke-ReXInstall' +New-Alias -Name 'rex-format' -Value 'Invoke-ReXFormat' +New-Alias -Name 'rex-lint' -Value 'Invoke-ReXLint' +New-Alias -Name 'rex-setup' -Value 'Invoke-ReXSetup' + +Export-ModuleMember -Function $Public.BaseName -Alias @( + 'rex-configure', 'rex-build', 'rex-test', 'rex-install', + 'rex-format', 'rex-lint', 'rex-setup' +) diff --git a/scripts/PSReX/Private/Get-ReXPreset.ps1 b/scripts/PSReX/Private/Get-ReXPreset.ps1 new file mode 100644 index 0000000..0c21fee --- /dev/null +++ b/scripts/PSReX/Private/Get-ReXPreset.ps1 @@ -0,0 +1,15 @@ +<# +.SYNOPSIS + Auto-detect the platform CMake preset. +.NOTES + Copyright (c) 2026 Tom Clay + All rights reserved. + Licensed under the BSD 3-Clause License. + See LICENSE file in the project root for full license text. +#> +function Get-ReXPreset { + if ($env:REXGLUE_PRESET) { return $env:REXGLUE_PRESET } + $platform = if ($IsWindows) { "win" } else { "linux" } + $arch = if ($IsWindows -and $env:PROCESSOR_ARCHITECTURE -eq "ARM64") { "arm64" } else { "amd64" } + return "$platform-$arch" +} diff --git a/scripts/PSReX/Private/Get-ReXRoot.ps1 b/scripts/PSReX/Private/Get-ReXRoot.ps1 new file mode 100644 index 0000000..58b27fd --- /dev/null +++ b/scripts/PSReX/Private/Get-ReXRoot.ps1 @@ -0,0 +1,16 @@ +<# +.SYNOPSIS + Auto-detect the rexglue-sdk repository root. +.NOTES + Copyright (c) 2026 Tom Clay + All rights reserved. + Licensed under the BSD 3-Clause License. + See LICENSE file in the project root for full license text. +#> +function Get-ReXRoot { + if ($env:REXGLUE_ROOT) { return $env:REXGLUE_ROOT } + $root = git rev-parse --show-toplevel 2>$null + if ($root) { return [System.IO.Path]::GetFullPath($root) } + # Fallback: module is at /scripts/PSReX/ + return (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) +} diff --git a/scripts/PSReX/Private/Initialize-VsEnvironment.ps1 b/scripts/PSReX/Private/Initialize-VsEnvironment.ps1 new file mode 100644 index 0000000..3327eff --- /dev/null +++ b/scripts/PSReX/Private/Initialize-VsEnvironment.ps1 @@ -0,0 +1,25 @@ +<# +.SYNOPSIS + Initialize Visual Studio Developer Shell environment. +.NOTES + Copyright (c) 2026 Tom Clay + All rights reserved. + Licensed under the BSD 3-Clause License. + See LICENSE file in the project root for full license text. +#> +function Initialize-VsEnvironment { + if (-not $IsWindows) { return } + if ($env:VSCMD_VER) { return } + + $vsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" + if (-not (Test-Path $vsWhere)) { return } + + $vsInstall = & $vsWhere -latest -property installationPath + if (-not $vsInstall) { return } + + $launchScript = Join-Path $vsInstall "Common7\Tools\Launch-VsDevShell.ps1" + if (-not (Test-Path $launchScript)) { return } + + $arch = if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { "arm64" } else { "amd64" } + & $launchScript -Arch $arch -HostArch amd64 -SkipAutomaticLocation +} diff --git a/scripts/PSReX/Public/Invoke-ReXBuild.ps1 b/scripts/PSReX/Public/Invoke-ReXBuild.ps1 new file mode 100644 index 0000000..366e5a5 --- /dev/null +++ b/scripts/PSReX/Public/Invoke-ReXBuild.ps1 @@ -0,0 +1,25 @@ +<# +.SYNOPSIS + Build the rexglue-sdk project for a given configuration. +.NOTES + Copyright (c) 2026 Tom Clay + All rights reserved. + Licensed under the BSD 3-Clause License. + See LICENSE file in the project root for full license text. +#> +function Invoke-ReXBuild { + [CmdletBinding()] + param( + [Parameter(Mandatory)] + [ValidateSet("Debug", "Release", "RelWithDebInfo")] + [string]$Config + ) + + $root = Get-ReXRoot + $preset = Get-ReXPreset + $buildDir = Join-Path $root "out/build/$preset" + + Write-Host "=== Building $Config ===" + cmake --build $buildDir --config $Config + if ($LASTEXITCODE -ne 0) { throw "cmake build failed (exit $LASTEXITCODE)" } +} diff --git a/scripts/PSReX/Public/Invoke-ReXConfigure.ps1 b/scripts/PSReX/Public/Invoke-ReXConfigure.ps1 new file mode 100644 index 0000000..3670e13 --- /dev/null +++ b/scripts/PSReX/Public/Invoke-ReXConfigure.ps1 @@ -0,0 +1,18 @@ +<# +.SYNOPSIS + Configure the rexglue-sdk CMake project. +.NOTES + Copyright (c) 2026 Tom Clay + All rights reserved. + Licensed under the BSD 3-Clause License. + See LICENSE file in the project root for full license text. +#> +function Invoke-ReXConfigure { + [CmdletBinding()] + param() + + $preset = Get-ReXPreset + Write-Host "=== Configuring with preset: $preset ===" + cmake --preset $preset + if ($LASTEXITCODE -ne 0) { throw "cmake configure failed (exit $LASTEXITCODE)" } +} diff --git a/scripts/PSReX/Public/Invoke-ReXFormat.ps1 b/scripts/PSReX/Public/Invoke-ReXFormat.ps1 new file mode 100644 index 0000000..0a16224 --- /dev/null +++ b/scripts/PSReX/Public/Invoke-ReXFormat.ps1 @@ -0,0 +1,55 @@ +<# +.SYNOPSIS + Format C/C++ source files with clang-format. +.NOTES + Copyright (c) 2026 Tom Clay + All rights reserved. + Licensed under the BSD 3-Clause License. + See LICENSE file in the project root for full license text. +#> +function Invoke-ReXFormat { + [CmdletBinding(DefaultParameterSetName = 'Modified')] + param( + [Parameter(ParameterSetName = 'Files', Position = 0, ValueFromRemainingArguments)] + [string[]]$Path, + + [Parameter(ParameterSetName = 'Modified')] + [switch]$Modified, + + [Parameter(ParameterSetName = 'All')] + [switch]$All + ) + + $root = Get-ReXRoot + $extensions = @("*.cpp", "*.h", "*.hpp", "*.c") + + if ($Path) { + # Explicit files provided + $files = @($Path | ForEach-Object { Resolve-Path $_ -ErrorAction Stop }) + Write-Host "=== Formatting $($files.Count) specified file(s) ===" + } elseif ($All) { + # All source files + $searchDirs = @("include", "src", "tests") | ForEach-Object { Join-Path $root $_ } | Where-Object { Test-Path $_ } + $files = @(Get-ChildItem -Path $searchDirs -Recurse -Include $extensions | Select-Object -ExpandProperty FullName) + Write-Host "=== Formatting all C/C++ files ===" + } else { + # Default: modified files (staged + unstaged changes) + $diff = git -C $root diff --name-only HEAD 2>$null + $untracked = git -C $root ls-files --others --exclude-standard 2>$null + $candidates = @($diff) + @($untracked) | Where-Object { $_ } + $files = @($candidates | Where-Object { + $ext = [System.IO.Path]::GetExtension($_) + $ext -in @('.cpp', '.h', '.hpp', '.c') + } | ForEach-Object { Join-Path $root $_ } | Where-Object { Test-Path $_ }) + Write-Host "=== Formatting modified C/C++ files ===" + } + + if ($files.Count -gt 0) { + $files | ForEach-Object { clang-format -i $_ } + Write-Host " Formatted $($files.Count) files" + } else { + Write-Host " No files found" + } + + Write-Host "Done." +} diff --git a/scripts/PSReX/Public/Invoke-ReXInstall.ps1 b/scripts/PSReX/Public/Invoke-ReXInstall.ps1 new file mode 100644 index 0000000..48f7381 --- /dev/null +++ b/scripts/PSReX/Public/Invoke-ReXInstall.ps1 @@ -0,0 +1,23 @@ +<# +.SYNOPSIS + Install all rexglue-sdk build configurations. +.NOTES + Copyright (c) 2026 Tom Clay + All rights reserved. + Licensed under the BSD 3-Clause License. + See LICENSE file in the project root for full license text. +#> +function Invoke-ReXInstall { + [CmdletBinding()] + param() + + $root = Get-ReXRoot + $preset = Get-ReXPreset + $buildDir = Join-Path $root "out/build/$preset" + + foreach ($config in @("Debug", "Release", "RelWithDebInfo")) { + Write-Host "=== Installing $config ===" + cmake --install $buildDir --config $config + if ($LASTEXITCODE -ne 0) { throw "cmake install ($config) failed (exit $LASTEXITCODE)" } + } +} diff --git a/scripts/PSReX/Public/Invoke-ReXLint.ps1 b/scripts/PSReX/Public/Invoke-ReXLint.ps1 new file mode 100644 index 0000000..9911823 --- /dev/null +++ b/scripts/PSReX/Public/Invoke-ReXLint.ps1 @@ -0,0 +1,37 @@ +<# +.SYNOPSIS + Run clang-tidy on rexglue-sdk source files. +.NOTES + Copyright (c) 2026 Tom Clay + All rights reserved. + Licensed under the BSD 3-Clause License. + See LICENSE file in the project root for full license text. +#> +function Invoke-ReXLint { + [CmdletBinding()] + param( + [string]$BuildDir + ) + + $root = Get-ReXRoot + if (-not $BuildDir) { + $preset = Get-ReXPreset + $BuildDir = Join-Path $root "out/build/$preset" + } + + $compileDb = Join-Path $BuildDir "compile_commands.json" + if (-not (Test-Path $compileDb)) { + Write-Error "compile_commands.json not found at $BuildDir`nGenerate it first: rex-configure (or cmake --preset )" + return + } + + Write-Host "=== Running clang-tidy ===" + $files = Get-ChildItem -Path (Join-Path $root "include"), (Join-Path $root "src") ` + -Recurse -Include *.cpp, *.h + + $files | ForEach-Object { + clang-tidy --config-file="$root/.clang-tidy" -p $BuildDir $_.FullName + } + + Write-Host "Done." +} diff --git a/scripts/PSReX/Public/Invoke-ReXSetup.ps1 b/scripts/PSReX/Public/Invoke-ReXSetup.ps1 new file mode 100644 index 0000000..061b019 --- /dev/null +++ b/scripts/PSReX/Public/Invoke-ReXSetup.ps1 @@ -0,0 +1,118 @@ +<# +.SYNOPSIS + Set up the rexglue-sdk developer environment. +.NOTES + Copyright (c) 2026 Tom Clay + All rights reserved. + Licensed under the BSD 3-Clause License. + See LICENSE file in the project root for full license text. +#> +function Invoke-ReXSetup { + [CmdletBinding()] + param( + [string]$RepoRoot + ) + + $ErrorActionPreference = "Stop" + + if (-not $RepoRoot) { $RepoRoot = Get-ReXRoot } + $RepoRoot = [System.IO.Path]::GetFullPath($RepoRoot) + + Write-Host "=== ReXGlue Developer Environment Setup ===" + Write-Host "Repo root: $RepoRoot" + Write-Host "" + + # -- Install pre-commit hook ----------------------------------------------- + $hookDst = Join-Path $RepoRoot ".git/hooks/pre-commit" + $hooksDir = Split-Path $hookDst + if (-not (Test-Path $hooksDir)) { + New-Item -ItemType Directory -Path $hooksDir -Force | Out-Null + } + + # Resolve pwsh path and bake it into the hook so MSYS2 bash can find it. + $pwshCmd = Get-Command pwsh -ErrorAction SilentlyContinue + if (-not $pwshCmd) { + Write-Host "[WARN] pwsh not found — cannot install pre-commit hook" + } else { + $pwshPath = $pwshCmd.Source + # On Windows, express pwsh path using $PROGRAMFILES so Git Bash + # can resolve it without MSYS2 path-escaping issues. + if ($IsWindows) { + $pfPrefix = $env:ProgramFiles + if ($pwshPath.StartsWith($pfPrefix, [System.StringComparison]::OrdinalIgnoreCase)) { + $remainder = ($pwshPath.Substring($pfPrefix.Length)) -replace '\\', '/' + $pwshExpr = "`"`$PROGRAMFILES$remainder`"" + } else { + $p = $pwshPath -replace '\\', '/' + $drive = $p[0].ToString().ToLower() + $pwshExpr = '"/' + $drive + $p.Substring(2) + '"' + } + } else { + $pwshExpr = $pwshPath + } + + $hookLines = @( + '#!/bin/sh' + '# Auto-generated by Invoke-ReXSetup. Do not edit.' + 'REPO_ROOT="$(git rev-parse --show-toplevel)"' + "exec $pwshExpr -NoProfile -NonInteractive -File ""`$REPO_ROOT/scripts/git/hook-pre-commit.ps1""" + ) + $hookLines -join "`n" | Set-Content -Path $hookDst -NoNewline + Write-Host "[OK] Pre-commit hook installed (pwsh: $pwshExpr)" + } + + # -- Install VS Developer PowerShell profile (Windows only) ---------------- + if ($IsWindows) { + $profileSrc = Join-Path $RepoRoot "scripts/vs/rexglue-devprompt.ps1" + $profileDst = Join-Path $RepoRoot ".vs/rexglue-devprompt.ps1" + + if (Test-Path $profileSrc) { + $vsDir = Split-Path $profileDst + if (-not (Test-Path $vsDir)) { + New-Item -ItemType Directory -Path $vsDir -Force | Out-Null + } + Copy-Item -Path $profileSrc -Destination $profileDst -Force + Write-Host "[OK] VS Developer PowerShell profile installed to .vs/" + } else { + Write-Host "[WARN] Profile source not found: $profileSrc" + } + } + + # -- Verify toolchain ------------------------------------------------------ + Write-Host "" + Write-Host "Toolchain:" + + $required = @("pwsh", "clang++", "clang-format", "cmake", "ninja") + $optional = @("clang-tidy", "cmake-format") + + foreach ($tool in $required) { + $cmd = Get-Command $tool -ErrorAction SilentlyContinue + if ($cmd) { + $ver = & $tool --version 2>&1 | Select-Object -First 1 + Write-Host " [OK] ${tool}: $ver" + } else { + Write-Host " [MISS] $tool (required)" + } + } + + foreach ($tool in $optional) { + $cmd = Get-Command $tool -ErrorAction SilentlyContinue + if ($cmd) { + $ver = & $tool --version 2>&1 | Select-Object -First 1 + Write-Host " [OK] ${tool}: $ver" + } else { + Write-Host " [SKIP] $tool (optional, not found)" + } + } + + # -- Summary --------------------------------------------------------------- + Write-Host "" + Write-Host "Setup complete." + Write-Host " Configure: rex-configure (or cmake --preset )" + Write-Host " Build: rex-build -Config Debug" + Write-Host " Test: rex-test" + Write-Host " Format: rex-format" + Write-Host " Lint: rex-lint" + Write-Host "" + +} diff --git a/scripts/PSReX/Public/Invoke-ReXTest.ps1 b/scripts/PSReX/Public/Invoke-ReXTest.ps1 new file mode 100644 index 0000000..689fb37 --- /dev/null +++ b/scripts/PSReX/Public/Invoke-ReXTest.ps1 @@ -0,0 +1,23 @@ +<# +.SYNOPSIS + Run rexglue-sdk tests via ctest. +.NOTES + Copyright (c) 2026 Tom Clay + All rights reserved. + Licensed under the BSD 3-Clause License. + See LICENSE file in the project root for full license text. +#> +function Invoke-ReXTest { + [CmdletBinding()] + param( + [ValidateSet("Debug", "Release", "RelWithDebInfo")] + [string]$Config = "Debug" + ) + + $preset = Get-ReXPreset + $testPreset = "$preset-$($Config.ToLower())" + + Write-Host "=== Running tests: $testPreset ===" + ctest --preset $testPreset + if ($LASTEXITCODE -ne 0) { throw "ctest failed (exit $LASTEXITCODE)" } +} diff --git a/scripts/git/hook-pre-commit.ps1 b/scripts/git/hook-pre-commit.ps1 new file mode 100644 index 0000000..d19a782 --- /dev/null +++ b/scripts/git/hook-pre-commit.ps1 @@ -0,0 +1,102 @@ +<# +.SYNOPSIS + Pre-commit hook - check formatting on staged files. +.NOTES + Copyright (c) 2026 Tom Clay + All rights reserved. + Licensed under the BSD 3-Clause License. + See LICENSE file in the project root for full license text. +#> +#Requires -Version 7.0 + +$ErrorActionPreference = "Stop" + +$RepoRoot = git rev-parse --show-toplevel +if (-not $RepoRoot) { exit 1 } +$RepoRoot = [System.IO.Path]::GetFullPath($RepoRoot) + +# Import PSReX module (initializes VS environment if needed) +Import-Module "$RepoRoot/scripts/PSReX" -Force -WarningAction SilentlyContinue + +# -- Collect staged files ------------------------------------------------------ +$staged = git diff --cached --name-only --diff-filter=ACM +if (-not $staged) { exit 0 } + +$cppFiles = @() +$cmakeFiles = @() +foreach ($file in $staged) { + switch -Wildcard ($file) { + "*.cpp" { $cppFiles += $file } + "*.hpp" { $cppFiles += $file } + "*.c" { $cppFiles += $file } + "*.h" { $cppFiles += $file } + "*.cc" { $cppFiles += $file } + "*.hh" { $cppFiles += $file } + "*.cxx" { $cppFiles += $file } + "*.hxx" { $cppFiles += $file } + "CMakeLists.txt" { $cmakeFiles += $file } + "*.cmake" { $cmakeFiles += $file } + } +} + +if ($cppFiles.Count -eq 0 -and $cmakeFiles.Count -eq 0) { exit 0 } + +# -- Temp directory for staged content ----------------------------------------- +$tmpDir = Join-Path ([System.IO.Path]::GetTempPath()) "rexglue-precommit-$PID" +New-Item -ItemType Directory -Path $tmpDir -Force | Out-Null + +$failedFiles = @() + +function Extract-Staged { + param([string]$File) + $dest = Join-Path $tmpDir $File + $destDir = Split-Path $dest + if (-not (Test-Path $destDir)) { + New-Item -ItemType Directory -Path $destDir -Force | Out-Null + } + # Rejoin with LF to avoid PowerShell pipeline stripping newlines + $lines = @(& git show ":$File") + ($lines -join "`n") + "`n" | Set-Content -Path $dest -NoNewline -Encoding utf8NoBOM + return $dest +} + +try { + # -- clang-format (C/C++) -------------------------------------------------- + if ($cppFiles.Count -gt 0 -and (Get-Command clang-format -ErrorAction SilentlyContinue)) { + foreach ($file in $cppFiles) { + $tmpFile = Extract-Staged $file + & clang-format --dry-run --Werror ` + --style="file:$RepoRoot/.clang-format" ` + $tmpFile *> $null + if ($LASTEXITCODE -ne 0) { + Write-Host "[$file] failed clang-format" + $failedFiles += $file + } + } + } + + # -- cmake-format (CMake files) -------------------------------------------- + if ($cmakeFiles.Count -gt 0 -and (Get-Command cmake-format -ErrorAction SilentlyContinue)) { + foreach ($file in $cmakeFiles) { + $tmpFile = Extract-Staged $file + & cmake-format --check ` + -c "$RepoRoot/.cmake-format.yaml" ` + $tmpFile *> $null + if ($LASTEXITCODE -ne 0) { + Write-Host "[$file] failed cmake-format" + $failedFiles += $file + } + } + } + + # -- Summary --------------------------------------------------------------- + if ($failedFiles.Count -gt 0) { + Write-Host "" + Write-Host "Pre-commit check FAILED ($($failedFiles.Count) file(s))." + exit 1 + } + + exit 0 +} finally { + Remove-Item -Recurse -Force $tmpDir -ErrorAction SilentlyContinue +} diff --git a/scripts/ida/export_named_funcs.py b/scripts/ida/export_named_funcs.py new file mode 100644 index 0000000..5fd7e84 --- /dev/null +++ b/scripts/ida/export_named_funcs.py @@ -0,0 +1,613 @@ +""" +Export functions from IDA into an existing ReXGlue TOML config. + +Reads the existing TOML file, updates entries that already exist, +and appends new entries for functions not yet in the config. Preserves all +existing entry metadata (parent, size, etc.). + +@file export_named_funcs.py + +@copyright Copyright (c) 2026 Tom Clay + All rights reserved. + +@license BSD 3-Clause License + See LICENSE file in the project root for full license text. +""" + +import fnmatch +import json +import os +import re + +import idaapi +import ida_funcs +import ida_kernwin +import ida_nalt +import idautils +import idc + + +# ── Config persistence ────────────────────────────────────────────────────── + +def _config_path(): + """Return path to the JSON config sidecar next to the current IDB.""" + return os.path.splitext(idc.get_idb_path())[0] + ".export_config.json" + + +def load_config(): + """Load saved export config from the IDB sidecar, or return defaults.""" + defaults = { + "toml_path": "", + "prefix": "rex_", + "name_filter": "", + "name_exclude": "", + "export_group": 0x3, + "sync_group": 0xF, + "skip_group": 0x7, + } + path = _config_path() + if not os.path.isfile(path): + return defaults + try: + with open(path, "r", encoding="utf-8") as f: + saved = json.load(f) + # Merge with defaults so new keys are always present + for k, v in defaults.items(): + saved.setdefault(k, v) + return saved + except (json.JSONDecodeError, OSError): + return defaults + + +def save_config(cfg): + """Persist export config to the IDB sidecar.""" + try: + with open(_config_path(), "w", encoding="utf-8") as f: + json.dump(cfg, f, indent=2) + except OSError: + pass # non-fatal + + +# ── Helpers ───────────────────────────────────────────────────────────────── + +def collect_import_eas(): + """Build a set of all imported function addresses for lookup.""" + imports = set() + for i in range(ida_nalt.get_import_module_qty()): + def callback(ea, name, ordinal): + if ea != idaapi.BADADDR: + imports.add(ea) + return True + ida_nalt.enum_import_names(i, callback) + return imports + + +def sanitize_name(name): + """Convert a mangled IDA name into a valid C/C++ identifier.""" + # Replace any non-alphanumeric/underscore character with _ + name = re.sub(r'[^a-zA-Z0-9_]', '_', name) + # Collapse consecutive underscores + name = re.sub(r'_+', '_', name) + # Strip leading/trailing underscores + name = name.strip('_') + # If starts with a digit, prepend _ + if name and name[0].isdigit(): + name = '_' + name + return name + + +# ── TOML parsing / writing ────────────────────────────────────────────────── + +# Regex to match a [functions] entry line like: +# 0x82C061F0 = { parent = 0x82C03A58, size = 8 } +# 0x82452ec0 = {} +# 0x82170000 = { name = "rex_RtlOutputDebugString", size = 0xC } +_ENTRY_RE = re.compile( + r'^(0[xX][0-9a-fA-F]+)\s*=\s*\{(.*)\}\s*$' +) + +# Matches a key = value pair inside the braces (handles quoted strings) +_KV_RE = re.compile( + r'(\w+)\s*=\s*("(?:[^"\\]|\\.)*"|0[xX][0-9a-fA-F]+|\d+)' +) + + +def parse_entry(line): + """Parse a [functions] entry line. Returns (addr_int, addr_str, dict) or None.""" + m = _ENTRY_RE.match(line.strip()) + if not m: + return None + addr_str = m.group(1) + body = m.group(2).strip() + addr_int = int(addr_str, 16) + + props = {} + for kv in _KV_RE.finditer(body): + key = kv.group(1) + val = kv.group(2) + props[key] = val + + return addr_int, addr_str, props + + +def format_entry(addr_str, props): + """Format a single entry line from address string and properties dict.""" + if not props: + return f"{addr_str} = {{}}" + parts = [] + # Maintain a consistent key order: name, parent, size, then rest + key_order = ["name", "parent", "size"] + for k in key_order: + if k in props: + parts.append(f"{k} = {props[k]}") + for k, v in props.items(): + if k not in key_order: + parts.append(f"{k} = {v}") + return f"{addr_str} = {{ {', '.join(parts)} }}" + + +def load_toml_functions(toml_path): + """Read TOML, find [functions] section, return parsed state. + + Returns (lines, section_start, section_end, existing_addrs, func_lines) + or None if the section is missing. + """ + with open(toml_path, "r", encoding="utf-8") as f: + lines = f.readlines() + + func_section_start = None + func_section_end = None + for i, line in enumerate(lines): + stripped = line.strip() + if stripped == "[functions]": + func_section_start = i + elif (func_section_start is not None + and stripped.startswith("[") and stripped.endswith("]")): + func_section_end = i + break + + if func_section_start is None: + ida_kernwin.info("No [functions] section found in the TOML file.") + return None + + if func_section_end is None: + func_section_end = len(lines) + + existing_addrs = {} # addr_int -> index in func_lines + func_lines = [] # list of (is_entry, content) + + for i in range(func_section_start + 1, func_section_end): + line = lines[i] + parsed = parse_entry(line) + if parsed: + addr_int, addr_str, props = parsed + idx = len(func_lines) + func_lines.append((True, (addr_int, addr_str, props))) + existing_addrs[addr_int] = idx + else: + func_lines.append((False, line)) + + return lines, func_section_start, func_section_end, existing_addrs, func_lines + + +def write_toml(out_path, lines, func_section_start, func_section_end, + func_lines): + """Rebuild and write the TOML file with function entries sorted by address.""" + out_lines = [] + + # Everything before [functions] section (including the header) + for i in range(func_section_start + 1): + out_lines.append(lines[i]) + + # Separate entries from non-entry header lines + all_entries = [] + non_entry_header = [] + + for is_entry, content in func_lines: + if is_entry: + all_entries.append(content) + elif not all_entries: + non_entry_header.append(content) + + all_entries.sort(key=lambda e: e[0]) # sort by addr_int + + for line in non_entry_header: + out_lines.append(line) + for addr_int, addr_str, props in all_entries: + out_lines.append(format_entry(addr_str, props) + "\n") + + # Everything after [functions] section + for i in range(func_section_end, len(lines)): + out_lines.append(lines[i]) + + with open(out_path, "w", encoding="utf-8") as f: + f.writelines(out_lines) + + +# ── UI ────────────────────────────────────────────────────────────────────── + +class ExportOptionsForm(ida_kernwin.Form): + """Options dialog for export_named_funcs script.""" + + def __init__(self): + super().__init__( + r"""STARTITEM 0 +Export Functions to ReXGlue TOML + + + + + +Export Options + +{cExportGroup}> + +TOML Sync Options + + + +{cSyncGroup}> + +Output + + +{cSkipGroup}> +""", + { + "cExportGroup": ida_kernwin.Form.ChkGroupControl(( + "cNamed", + "cFuncPtrs", + )), + "cSyncGroup": ida_kernwin.Form.ChkGroupControl(( + "cRemoveStale", + "cUpdateSizes", + "cUpdateNames", + "cOverwrite", + )), + "cSkipGroup": ida_kernwin.Form.ChkGroupControl(( + "cIgnoreRestSave", + "cIgnoreNullsub", + "cIgnoreThunks", + )), + "iPrefix": ida_kernwin.Form.StringInput(value="rex_"), + "iNameFilter": ida_kernwin.Form.StringInput(value=""), + "iNameExclude": ida_kernwin.Form.StringInput(value=""), + }, + ) + + +def show_options(): + """Prompt for TOML file, then show the options dialog. + + Returns a settings dict or None if cancelled. + """ + cfg = load_config() + + # Prompt for input TOML file first (before showing options UI) + default_toml = cfg["toml_path"] + if not default_toml: + default_toml = os.path.join( + os.path.dirname(idc.get_idb_path()), "refii_config.toml" + ) + toml_path = ida_kernwin.ask_file( + False, default_toml, "Select existing TOML config to update" + ) + if not toml_path: + return None + + # Show options dialog with last-used settings + form = ExportOptionsForm() + form.Compile() + form.cExportGroup.value = cfg["export_group"] + form.cSyncGroup.value = cfg["sync_group"] + form.cSkipGroup.value = cfg["skip_group"] + form.iPrefix.value = cfg["prefix"] + form.iNameFilter.value = cfg["name_filter"] + form.iNameExclude.value = cfg["name_exclude"] + ok = form.Execute() + if not ok: + form.Free() + return None + + export_val = form.cExportGroup.value + sync_val = form.cSyncGroup.value + skip_val = form.cSkipGroup.value + name_prefix = form.iPrefix.value + name_filter = form.iNameFilter.value + name_exclude = form.iNameExclude.value + form.Free() + + do_named = bool(export_val & (1 << 0)) + do_func_ptrs = bool(export_val & (1 << 1)) + + remove_stale = bool(sync_val & (1 << 0)) + update_sizes = bool(sync_val & (1 << 1)) + update_names = bool(sync_val & (1 << 2)) + overwrite = bool(sync_val & (1 << 3)) + + ignore_rest_save = bool(skip_val & (1 << 0)) + ignore_nullsub = bool(skip_val & (1 << 1)) + ignore_thunks = bool(skip_val & (1 << 2)) + + if not do_named and not do_func_ptrs: + ida_kernwin.info("Nothing selected to export.") + return None + + # Persist config for next run + save_config({ + "toml_path": toml_path, + "prefix": name_prefix, + "export_group": export_val, + "sync_group": sync_val, + "skip_group": skip_val, + "name_filter": name_filter, + "name_exclude": name_exclude, + }) + + # Build ignore prefixes from checkbox state + ignore_prefixes = ["sub_", "start"] # always skip IDA defaults + if ignore_rest_save: + ignore_prefixes.extend(["__rest", "__save", "__"]) + if ignore_nullsub: + ignore_prefixes.append("nullsub_") + if ignore_thunks: + ignore_prefixes.append("j_") + + # Resolve output path: overwrite reuses input, otherwise prompt save-as + if overwrite: + out_path = toml_path + else: + out_path = ida_kernwin.ask_file( + True, toml_path, "Save updated TOML config as" + ) + if not out_path: + return None + + return { + "toml_path": toml_path, + "out_path": out_path, + "do_named": do_named, + "do_func_ptrs": do_func_ptrs, + "ignore_prefixes": tuple(ignore_prefixes), + "name_prefix": name_prefix, + "remove_stale": remove_stale, + "update_sizes": update_sizes, + "update_names": update_names, + "name_filter": name_filter, + "name_exclude": name_exclude, + } + + +# ── IDA data collection ──────────────────────────────────────────────────── + +def collect_func_ptr_args(): + """Find functions whose addresses are only loaded in code as values + (lis/addi pattern) and never called directly. These are function + pointers passed as arguments that rexglue codegen misses.""" + import_eas = collect_import_eas() + func_ptrs = {} # addr -> size or None + + for func_ea in idautils.Functions(): + if func_ea in import_eas: + continue + + has_direct_call = False + has_code_data_xref = False + + for xref in idautils.XrefsTo(func_ea): + if xref.type in (idaapi.fl_CF, idaapi.fl_CN, + idaapi.fl_JF, idaapi.fl_JN): + has_direct_call = True + break + elif xref.type in (idaapi.dr_O, idaapi.dr_W, + idaapi.dr_R, idaapi.dr_I): + if idaapi.get_func(xref.frm): + has_code_data_xref = True + + if has_direct_call or not has_code_data_xref: + continue + + func = ida_funcs.get_func(func_ea) + size = (func.end_ea - func.start_ea) if func else None + func_ptrs[func_ea] = size + + return func_ptrs + + +# ── Main export workflow ──────────────────────────────────────────────────── + +def run_export(settings): + """Unified export workflow: collect IDA data, sync with TOML, write output.""" + toml_path = settings["toml_path"] + out_path = settings["out_path"] + ignore_prefixes = settings["ignore_prefixes"] + name_prefix = settings["name_prefix"] + do_named = settings["do_named"] + do_func_ptrs = settings["do_func_ptrs"] + remove_stale = settings["remove_stale"] + update_sizes = settings["update_sizes"] + update_names = settings["update_names"] + name_filter = settings["name_filter"] + name_exclude = settings["name_exclude"] + + # Step 1 — Load & parse TOML + result = load_toml_functions(toml_path) + if result is None: + return + lines, section_start, section_end, existing_addrs, func_lines = result + + # Step 2 — Collect IDA data into a unified map: addr -> (name|None, size|None) + import_eas = collect_import_eas() + ida_funcs_map = {} + + if do_named: + for ea in idautils.Functions(): + name = idc.get_func_name(ea) + if not name: + continue + if name.startswith(ignore_prefixes): + continue + if ea in import_eas: + continue + if name_filter and not fnmatch.fnmatchcase(name, name_filter): + continue + if name_exclude and fnmatch.fnmatchcase(name, name_exclude): + continue + func = ida_funcs.get_func(ea) + if not func: + continue + size = func.end_ea - func.start_ea + ida_funcs_map[ea] = (name, size) + + if do_func_ptrs and not name_filter: + func_ptrs = collect_func_ptr_args() + for ea, size in func_ptrs.items(): + if ea not in ida_funcs_map: + ida_funcs_map[ea] = (None, size) + + # Build a map of names already claimed by existing TOML entries + # so we can detect duplicates from IDA exports + used_names = {} # name_str -> addr_int (first addr that claimed it) + for idx, (is_entry, content) in enumerate(func_lines): + if not is_entry: + continue + addr_int, addr_str, props = content + if "name" in props: + n = props["name"].strip('"') + if n not in used_names: + used_names[n] = addr_int + + duplicate_names = [] # list of (name, new_addr, existing_addr) for reporting + + # Strip pre-existing duplicate names from the TOML + for idx, (is_entry, content) in enumerate(func_lines): + if not is_entry: + continue + addr_int, addr_str, props = content + if "name" in props: + n = props["name"].strip('"') + if n in used_names and used_names[n] != addr_int: + duplicate_names.append((n, addr_int, used_names[n])) + print(f"[export] PRE-EXISTING DUPLICATE: '{n}' at 0x{addr_int:08X} " + f"conflicts with 0x{used_names[n]:08X} -- removing name") + del props["name"] + func_lines[idx] = (True, (addr_int, addr_str, props)) + + # Step 3 -- Iterate existing TOML entries against IDA data + updated_count = 0 + removed_count = 0 + stale_indices = set() + + for idx, (is_entry, content) in enumerate(func_lines): + if not is_entry: + continue + addr_int, addr_str, props = content + + if addr_int in ida_funcs_map: + ida_name, ida_size = ida_funcs_map[addr_int] + changed = False + + if update_names and ida_name is not None: + sanitized = sanitize_name(ida_name) + full_name = f"{name_prefix}{sanitized}" + rex_name = f'"{full_name}"' + if "name" not in props or props["name"] != rex_name: + # Check for name collision with another address + if full_name in used_names and used_names[full_name] != addr_int: + duplicate_names.append((full_name, addr_int, used_names[full_name])) + print(f"[export] DUPLICATE: '{full_name}' at 0x{addr_int:08X} " + f"conflicts with 0x{used_names[full_name]:08X} -- skipping name update") + else: + # Remove old name from tracking if it had one + if "name" in props: + old_name = props["name"].strip('"') + if old_name in used_names and used_names[old_name] == addr_int: + del used_names[old_name] + props["name"] = rex_name + used_names[full_name] = addr_int + changed = True + + if update_sizes and ida_size is not None: + size_str = f"0x{ida_size:X}" + if "size" not in props or props["size"] != size_str: + props["size"] = size_str + changed = True + + if changed: + func_lines[idx] = (True, (addr_int, addr_str, props)) + updated_count += 1 + + # Remove from map so it's not re-added as new + del ida_funcs_map[addr_int] + + elif remove_stale: + # Never remove chunks (entries with parent) — they're manual config + if "parent" in props: + continue + # Check if this address is a valid function or chunk start in IDA + # (covers entries skipped by name filters like sub_, nullsub_, etc.) + func = ida_funcs.get_func(addr_int) + chunk = ida_funcs.get_fchunk(addr_int) + is_func_start = func is not None and func.start_ea == addr_int + is_chunk_start = chunk is not None and chunk.start_ea == addr_int + if not is_func_start and not is_chunk_start: + stale_indices.add(idx) + removed_count += 1 + + # Remove stale entries + if stale_indices: + func_lines = [ + item for idx, item in enumerate(func_lines) + if idx not in stale_indices + ] + + # Step 4 -- Insert new entries from remaining ida_funcs_map items + added_count = 0 + for ea, (name, size) in sorted(ida_funcs_map.items()): + addr_str = f"0x{ea:08X}" + props = {} + if name is not None: + sanitized = sanitize_name(name) + full_name = f"{name_prefix}{sanitized}" + # Check for name collision before inserting + if full_name in used_names: + duplicate_names.append((full_name, ea, used_names[full_name])) + print(f"[export] DUPLICATE: '{full_name}' at 0x{ea:08X} " + f"conflicts with 0x{used_names[full_name]:08X} -- inserting without name") + else: + props["name"] = f'"{full_name}"' + used_names[full_name] = ea + if size is not None: + props["size"] = f"0x{size:X}" + func_lines.append((True, (ea, addr_str, props))) + added_count += 1 + + # Step 5 & 6 -- Sort and write (out_path resolved in show_options) + write_toml(out_path, lines, section_start, section_end, func_lines) + + # Step 7 -- Report duplicates in detail to console + if duplicate_names: + print(f"\n[export] WARNING: {len(duplicate_names)} duplicate function name(s) detected:") + for dup_name, new_addr, existing_addr in duplicate_names: + print(f" '{dup_name}': 0x{new_addr:08X} conflicts with 0x{existing_addr:08X}") + print("") + + # Step 8 -- Show single stats dialog + dup_msg = "" + if duplicate_names: + dup_msg = (f"\n WARNING: {len(duplicate_names)} duplicate name(s) skipped " + f"(see console for details)\n") + ida_kernwin.info( + f"Export complete.\n" + f" {updated_count} existing functions updated (name and/or size)\n" + f" {removed_count} stale functions removed (invalid entry point)\n" + f" {added_count} new functions added\n" + f"{dup_msg}" + f"Saved to: {out_path}" + ) + + +if __name__ == "__main__": + opts = show_options() + if opts: + run_export(opts) diff --git a/scripts/vs/rexglue-devprompt.bat b/scripts/vs/rexglue-devprompt.bat new file mode 100644 index 0000000..cd2e2d3 --- /dev/null +++ b/scripts/vs/rexglue-devprompt.bat @@ -0,0 +1 @@ +@pwsh -NoExit -ExecutionPolicy Bypass -File "%~dpn0.ps1" %* diff --git a/scripts/vs/rexglue-devprompt.ps1 b/scripts/vs/rexglue-devprompt.ps1 new file mode 100644 index 0000000..35d6615 --- /dev/null +++ b/scripts/vs/rexglue-devprompt.ps1 @@ -0,0 +1,78 @@ +<# +.SYNOPSIS + Visual Studio Developer PowerShell profile for rexglue-sdk. +.NOTES + Copyright (c) 2026 Tom Clay + All rights reserved. + Licensed under the BSD 3-Clause License. + See LICENSE file in the project root for full license text. +#> +param( + [ValidateSet("amd64", "arm64")] + [string]$Arch = $(if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { "arm64" } else { "amd64" }) +) + +$ErrorActionPreference = "Stop" + +# -- Locate repo root ---------------------------------------------------------- +$RepoRoot = (git rev-parse --show-toplevel 2>$null) +if (-not $RepoRoot) { + $RepoRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) +} +$RepoRoot = [System.IO.Path]::GetFullPath($RepoRoot) + +# -- Initialize VS Developer Shell -------------------------------------------- +if (-not $env:VSCMD_VER) { + $vsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" + if (-not (Test-Path $vsWhere)) { + Write-Error "vswhere.exe not found. Is Visual Studio installed?" + return + } + + $vsInstall = & $vsWhere -latest -property installationPath + if (-not $vsInstall) { + Write-Error "No Visual Studio installation found via vswhere." + return + } + + $launchScript = Join-Path $vsInstall "Common7\Tools\Launch-VsDevShell.ps1" + if (-not (Test-Path $launchScript)) { + Write-Error "Launch-VsDevShell.ps1 not found at: $launchScript" + return + } + + & $launchScript -Arch $Arch -HostArch amd64 -SkipAutomaticLocation +} + +# -- ReXGlue environment ------------------------------------------------------ +$Preset = "win-$Arch" + +$env:REXGLUE_ROOT = $RepoRoot +$env:REXGLUE_PRESET = $Preset + +# Add install bin directory to PATH +$InstallBin = Join-Path $RepoRoot "out\install\$Preset\bin" +if ($env:PATH -notlike "*$InstallBin*") { + $env:PATH = "$InstallBin;$env:PATH" +} + +# -- Import ReXGlue module ---------------------------------------------------- +Import-Module "$PSScriptRoot/../PSReX" -Force -Global + +# -- Banner -------------------------------------------------------------------- +Write-Host "" +Write-Host " ReXGlue SDK Developer Shell" -ForegroundColor Cyan +Write-Host " Arch: $Arch" -ForegroundColor Gray +Write-Host " Preset: $Preset" -ForegroundColor Gray +Write-Host " Root: $RepoRoot" -ForegroundColor Gray +Write-Host "" +Write-Host " Commands:" -ForegroundColor Yellow +Write-Host " rex-configure cmake --preset $Preset" +Write-Host " rex-build -Config Debug Build Debug" +Write-Host " rex-build -Config Release Build Release" +Write-Host " rex-test Run tests (Debug)" +Write-Host " rex-install cmake --install (all configs)" +Write-Host " rex-format Format all C/C++ sources" +Write-Host " rex-lint Run clang-tidy" +Write-Host " rex-setup Run developer environment setup" +Write-Host "" diff --git a/src/audio/CMakeLists.txt b/src/audio/CMakeLists.txt new file mode 100644 index 0000000..6300cf2 --- /dev/null +++ b/src/audio/CMakeLists.txt @@ -0,0 +1,27 @@ +# rexaudio - Audio subsystem library +# Audio processing and XMA decoding for Xbox 360 emulation + +add_library(rexaudio OBJECT + + audio_driver.cpp + audio_system.cpp + xma_context.cpp + xma_decoder.cpp + xma_register_file.cpp + # NOP backend (always available) + nop/nop_audio_system.cpp + # SDL backend + sdl/sdl_audio_system.cpp + sdl/sdl_audio_driver.cpp +) +add_library(rex::audio ALIAS rexaudio) + +target_include_directories(rexaudio PUBLIC + $ + $ +) + +target_link_libraries(rexaudio + PUBLIC rexcore SDL3::SDL3 + PRIVATE libavcodec libavutil +) diff --git a/src/audio/audio_driver.cpp b/src/audio/audio_driver.cpp new file mode 100644 index 0000000..f01eb6a --- /dev/null +++ b/src/audio/audio_driver.cpp @@ -0,0 +1,20 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +namespace rex::audio { + +AudioDriver::AudioDriver(memory::Memory* memory) : memory_(memory) {} + +AudioDriver::~AudioDriver() = default; + +} // namespace rex::audio diff --git a/src/audio/audio_system.cpp b/src/audio/audio_system.cpp new file mode 100644 index 0000000..fe62017 --- /dev/null +++ b/src/audio/audio_system.cpp @@ -0,0 +1,382 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_INT32( + audio_maxqframes, 8, "Audio", + "Max buffered audio frames (range 4-64). Lower reduces latency but may cause stuttering."); + +// As with normal Microsoft, there are like twelve different ways to access +// the audio APIs. Early games use XMA*() methods almost exclusively to touch +// decoders. Later games use XAudio*() and direct memory writes to the XMA +// structures (as opposed to the XMA* calls), meaning that we have to support +// both. +// +// For ease of implementation, most audio related processing is handled in +// AudioSystem, and the functions here call off to it. +// The XMA*() functions just manipulate the audio system in the guest context +// and let the normal AudioSystem handling take it, to prevent duplicate +// implementations. They can be found in xboxkrnl_audio_xma.cc + +namespace rex::audio { + +AudioSystem::AudioSystem(runtime::FunctionDispatcher* function_dispatcher) + : memory_(function_dispatcher->memory()), + function_dispatcher_(function_dispatcher), + worker_running_(false) { + std::memset(clients_, 0, sizeof(clients_)); + + queued_frames_ = std::min( + static_cast(kMaximumQueuedFrames), + std::max(static_cast(REXCVAR_GET(audio_maxqframes)), static_cast(4))); + + for (size_t i = 0; i < kMaximumClientCount; ++i) { + client_semaphores_[i] = rex::thread::Semaphore::Create(0, queued_frames_); + assert_not_null(client_semaphores_[i]); + wait_handles_[i] = client_semaphores_[i].get(); + } + shutdown_event_ = rex::thread::Event::CreateAutoResetEvent(false); + assert_not_null(shutdown_event_); + wait_handles_[kMaximumClientCount] = shutdown_event_.get(); + + xma_decoder_ = std::make_unique(function_dispatcher_); + + resume_event_ = rex::thread::Event::CreateAutoResetEvent(false); + assert_not_null(resume_event_); +} + +AudioSystem::~AudioSystem() { + if (xma_decoder_) { + xma_decoder_->Shutdown(); + } +} + +X_STATUS AudioSystem::Setup(system::KernelState* kernel_state) { + X_STATUS result = xma_decoder_->Setup(kernel_state); + if (result) { + return result; + } + + worker_running_ = true; + worker_thread_ = system::object_ref( + new system::XHostThread(kernel_state, 128 * 1024, 0, [this]() { + WorkerThreadMain(); + return 0; + })); + + worker_thread_->set_name("Audio Worker"); + worker_thread_->Create(); + + return X_STATUS_SUCCESS; +} + +void AudioSystem::WorkerThreadMain() { + // Initialize driver and ringbuffer. + Initialize(); + + // Main run loop. + uint32_t diag_pump_count = 0; + while (worker_running_) { + // These handles signify the number of submitted samples. Once we reach + // 64 samples, we wait until our audio backend releases a semaphore + // (signaling a sample has finished playing) + auto result = rex::thread::WaitAny(wait_handles_, rex::countof(wait_handles_), true, + std::chrono::milliseconds(500)); + if (result.first == rex::thread::WaitResult::kFailed) { + REXAPU_WARN("AudioWorker: WaitAny failed"); + continue; + } + + if (result.first == rex::thread::WaitResult::kTimeout) { + if (diag_pump_count < 5) { + REXAPU_NOISY_DEBUG("AudioWorker: WaitAny timed out (no semaphore signals)"); + } + } + + if (result.first == thread::WaitResult::kSuccess && result.second == kMaximumClientCount) { + // Shutdown event signaled. + if (paused_) { + pause_fence_.Signal(); + thread::Wait(resume_event_.get(), false); + } + + continue; + } + + // Number of clients pumped + bool pumped = false; + if (result.first == rex::thread::WaitResult::kSuccess) { + auto index = result.second; + + auto global_lock = global_critical_region_.Acquire(); + uint32_t client_callback = clients_[index].callback; + uint32_t client_callback_arg = clients_[index].wrapped_callback_arg; + global_lock.unlock(); + + if (client_callback) { + if (diag_pump_count < 10) { + REXAPU_DEBUG("AudioWorker: dispatching callback {:08X} with arg {:08X} for client {}", + client_callback, client_callback_arg, index); + } + SCOPE_profile_cpu_i("apu", "rex::audio::AudioSystem->client_callback"); + uint64_t args[] = {client_callback_arg}; + function_dispatcher_->Execute(worker_thread_->thread_state(), client_callback, args, + rex::countof(args)); + if (diag_pump_count < 10) { + REXAPU_DEBUG("AudioWorker: callback returned for client {}", index); + } + diag_pump_count++; + } else { + REXAPU_DEBUG("AudioWorker: semaphore signaled for client {} but callback is 0", index); + } + + pumped = true; + } + + if (!worker_running_) { + break; + } + + if (!pumped) { + SCOPE_profile_cpu_i("apu", "Sleep"); + rex::thread::Sleep(std::chrono::milliseconds(500)); + } + } + worker_running_ = false; + + // TODO(benvanik): call module API to kill? +} + +int AudioSystem::FindFreeClient() { + for (size_t i = 0; i < kMaximumClientCount; i++) { + auto& client = clients_[i]; + if (!client.in_use) { + return i; + } + } + + return -1; +} + +void AudioSystem::Initialize() {} + +void AudioSystem::Shutdown() { + if (!worker_running_) { + return; + } + + // Shut down XMA decoder first - its worker can stall in FFmpeg + if (xma_decoder_) { + xma_decoder_->Shutdown(); + } + + worker_running_ = false; + shutdown_event_->Set(); + if (worker_thread_) { + // The worker may be stuck inside a guest callback that is itself blocked + // on guest objects (e.g. KeWaitForMultipleObjects). + // Terminate the thread to break the deadlock. + worker_thread_->Terminate(0); + worker_thread_.reset(); + } + + // Destroy all active client drivers (closes SDL audio devices, stopping + // callback threads) before the semaphores they reference are destroyed. + for (size_t i = 0; i < kMaximumClientCount; i++) { + if (clients_[i].in_use) { + DestroyDriver(clients_[i].driver); + if (clients_[i].wrapped_callback_arg) { + memory()->SystemHeapFree(clients_[i].wrapped_callback_arg); + } + clients_[i] = {nullptr, 0, 0, 0, false}; + } + } +} + +X_STATUS AudioSystem::RegisterClient(uint32_t callback, uint32_t callback_arg, size_t* out_index) { + REXAPU_DEBUG("AudioSystem::RegisterClient: callback={:08X} callback_arg={:08X}", callback, + callback_arg); + auto global_lock = global_critical_region_.Acquire(); + + auto index = FindFreeClient(); + assert_true(index >= 0); + REXAPU_DEBUG("AudioSystem::RegisterClient: using client index={} queued_frames={}", index, + queued_frames_); + + auto client_semaphore = client_semaphores_[index].get(); + auto ret = client_semaphore->Release(queued_frames_, nullptr); + assert_true(ret); + + AudioDriver* driver; + auto result = CreateDriver(index, client_semaphore, &driver); + if (XFAILED(result)) { + return result; + } + assert_not_null(driver); + + uint32_t ptr = memory()->SystemHeapAlloc(0x4); + memory::store_and_swap(memory()->TranslateVirtual(ptr), callback_arg); + + clients_[index] = {driver, callback, callback_arg, ptr, true}; + + if (out_index) { + *out_index = index; + } + + return X_STATUS_SUCCESS; +} + +void AudioSystem::SubmitFrame(size_t index, uint32_t samples_ptr) { + SCOPE_profile_cpu_f("apu"); + + static uint32_t submit_count = 0; + if (submit_count < 10) { + REXAPU_DEBUG("AudioSystem::SubmitFrame called: index={} samples_ptr={:08X}", index, + samples_ptr); + submit_count++; + } + + auto global_lock = global_critical_region_.Acquire(); + assert_true(index < kMaximumClientCount); + assert_true(clients_[index].driver != NULL); + (clients_[index].driver)->SubmitFrame(samples_ptr); +} + +void AudioSystem::UnregisterClient(size_t index) { + SCOPE_profile_cpu_f("apu"); + + auto global_lock = global_critical_region_.Acquire(); + assert_true(index < kMaximumClientCount); + DestroyDriver(clients_[index].driver); + memory()->SystemHeapFree(clients_[index].wrapped_callback_arg); + clients_[index] = {nullptr, 0, 0, 0, false}; + + // Drain the semaphore of its count. + auto client_semaphore = client_semaphores_[index].get(); + rex::thread::WaitResult wait_result; + do { + wait_result = rex::thread::Wait(client_semaphore, false, std::chrono::milliseconds(0)); + } while (wait_result == rex::thread::WaitResult::kSuccess); + assert_true(wait_result == rex::thread::WaitResult::kTimeout); +} + +bool AudioSystem::Save(stream::ByteStream* stream) { + stream->Write(kAudioSaveSignature); + + // Count the number of used clients first. + // Any gaps should be handled gracefully. + uint32_t used_clients = 0; + for (size_t i = 0; i < kMaximumClientCount; i++) { + if (clients_[i].in_use) { + used_clients++; + } + } + + stream->Write(used_clients); + for (uint32_t i = 0; i < kMaximumClientCount; i++) { + auto& client = clients_[i]; + if (!client.in_use) { + continue; + } + + stream->Write(i); + stream->Write(client.callback); + stream->Write(client.callback_arg); + stream->Write(client.wrapped_callback_arg); + } + + return true; +} + +bool AudioSystem::Restore(stream::ByteStream* stream) { + if (stream->Read() != kAudioSaveSignature) { + REXAPU_ERROR("AudioSystem::Restore - Invalid magic value!"); + return false; + } + + uint32_t num_clients = stream->Read(); + for (uint32_t i = 0; i < num_clients; i++) { + auto id = stream->Read(); + assert_true(id < kMaximumClientCount); + + auto& client = clients_[id]; + + // Reset the semaphore and recreate the driver ourselves. + if (client.driver) { + UnregisterClient(id); + } + + client.callback = stream->Read(); + client.callback_arg = stream->Read(); + client.wrapped_callback_arg = stream->Read(); + + client.in_use = true; + + auto client_semaphore = client_semaphores_[id].get(); + auto ret = client_semaphore->Release(queued_frames_, nullptr); + assert_true(ret); + + AudioDriver* driver = nullptr; + auto status = CreateDriver(id, client_semaphore, &driver); + if (XFAILED(status)) { + REXAPU_ERROR( + "AudioSystem::Restore - Call to CreateDriver failed with status " + "{:08X}", + status); + return false; + } + + assert_not_null(driver); + client.driver = driver; + } + + return true; +} + +void AudioSystem::Pause() { + if (paused_) { + return; + } + paused_ = true; + + // Kind of a hack, but it works. + shutdown_event_->Set(); + pause_fence_.Wait(); + + xma_decoder_->Pause(); +} + +void AudioSystem::Resume() { + if (!paused_) { + return; + } + paused_ = false; + + resume_event_->Set(); + + xma_decoder_->Resume(); +} + +} // namespace rex::audio diff --git a/src/audio/nop/nop_audio_system.cpp b/src/audio/nop/nop_audio_system.cpp new file mode 100644 index 0000000..e479311 --- /dev/null +++ b/src/audio/nop/nop_audio_system.cpp @@ -0,0 +1,37 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +namespace rex::audio::nop { + +std::unique_ptr NopAudioSystem::Create( + runtime::FunctionDispatcher* function_dispatcher) { + return std::make_unique(function_dispatcher); +} + +NopAudioSystem::NopAudioSystem(runtime::FunctionDispatcher* function_dispatcher) + : AudioSystem(function_dispatcher) {} + +NopAudioSystem::~NopAudioSystem() = default; + +X_STATUS NopAudioSystem::CreateDriver(size_t /*index*/, rex::thread::Semaphore* /*semaphore*/, + AudioDriver** /*out_driver*/) { + return X_STATUS_NOT_IMPLEMENTED; +} + +void NopAudioSystem::DestroyDriver(AudioDriver* driver) { + (void)driver; + assert_always(); +} + +} // namespace rex::audio::nop diff --git a/src/audio/sdl/sdl_audio_driver.cpp b/src/audio/sdl/sdl_audio_driver.cpp new file mode 100644 index 0000000..46719f3 --- /dev/null +++ b/src/audio/sdl/sdl_audio_driver.cpp @@ -0,0 +1,216 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(audio_mute, false, "Audio", "Mute audio output"); + +namespace rex::audio::sdl { + +SDLAudioDriver::SDLAudioDriver(memory::Memory* memory, rex::thread::Semaphore* semaphore) + : AudioDriver(memory), semaphore_(semaphore) {} + +SDLAudioDriver::~SDLAudioDriver() { + assert_true(frames_queued_.empty()); + assert_true(frames_unused_.empty()); +} + +bool SDLAudioDriver::Initialize() { + // Prevent SDL from interfering with timer resolution (causes FPS drops) + SDL_SetHintWithPriority(SDL_HINT_TIMER_RESOLUTION, "0", SDL_HINT_OVERRIDE); + + // Set audio category for proper OS audio handling + SDL_SetHint(SDL_HINT_AUDIO_CATEGORY, "playback"); + + // Set app name for audio device identification + SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_NAME_STRING, "rexglue"); + + if (!SDL_InitSubSystem(SDL_INIT_AUDIO)) { + REXAPU_ERROR("SDL_InitSubSystem(SDL_INIT_AUDIO) failed: {}", SDL_GetError()); + return false; + } + sdl_initialized_ = true; + + SDL_AudioSpec desired_spec = {}; + SDL_AudioSpec obtained_spec = {}; + desired_spec.freq = frame_frequency_; + desired_spec.format = SDL_AUDIO_F32LE; + desired_spec.channels = frame_channels_; + sdl_device_channels_ = frame_channels_; + sdl_stream_ = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &desired_spec, + SDLCallback, this); + if (!sdl_stream_) { + REXAPU_ERROR("SDL_OpenAudioDeviceStream() failed: {}", SDL_GetError()); + return false; + } + + SDL_AudioDeviceID sdl_device = SDL_GetAudioStreamDevice(sdl_stream_); + if (!sdl_device) { + REXAPU_ERROR("SDL_GetAudioStreamDevice() failed: {}", SDL_GetError()); + return false; + } + + if (!SDL_GetAudioDeviceFormat(sdl_device, &obtained_spec, NULL)) { + REXAPU_WARN("SDL_GetAudioDeviceFormat() failed: {}", SDL_GetError()); + obtained_spec = desired_spec; + } + + if (obtained_spec.channels == 2) { + SDL_DestroyAudioStream(sdl_stream_); + sdl_stream_ = nullptr; + desired_spec.channels = 2; + sdl_device_channels_ = 2; + sdl_stream_ = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &desired_spec, + SDLCallback, this); + if (!sdl_stream_) { + REXAPU_ERROR("SDL_OpenAudioDeviceStream() stereo fallback failed: {}", SDL_GetError()); + return false; + } + sdl_device = SDL_GetAudioStreamDevice(sdl_stream_); + if (!sdl_device) { + REXAPU_ERROR("SDL_GetAudioStreamDevice() failed after stereo fallback: {}", SDL_GetError()); + return false; + } + } + + if (!SDL_ResumeAudioDevice(sdl_device)) { + REXAPU_ERROR("SDL_ResumeAudioDevice() failed: {}", SDL_GetError()); + return false; + } + + return true; +} + +void SDLAudioDriver::SubmitFrame(uint32_t frame_ptr) { + const auto input_frame = memory_->TranslateVirtual(frame_ptr); + float* output_frame; + { + std::unique_lock guard(frames_mutex_); + if (frames_unused_.empty()) { + output_frame = new float[frame_samples_]; + } else { + output_frame = frames_unused_.top(); + frames_unused_.pop(); + } + } + + std::memcpy(output_frame, input_frame, frame_samples_ * sizeof(float)); + + static uint32_t sdl_submit_count = 0; + if (sdl_submit_count < 10) { + REXAPU_DEBUG("SDLAudioDriver::SubmitFrame: frame_ptr={:08X} queued_count={}", frame_ptr, + frames_queued_.size() + 1); + sdl_submit_count++; + } + + { + std::unique_lock guard(frames_mutex_); + frames_queued_.push(output_frame); + PROFILE_BUFFER_QUEUE_DEPTH(static_cast(frames_queued_.size())); + } +} + +void SDLAudioDriver::Shutdown() { + if (sdl_stream_) { + SDL_DestroyAudioStream(sdl_stream_); + sdl_stream_ = nullptr; + } + if (sdl_initialized_) { + SDL_QuitSubSystem(SDL_INIT_AUDIO); + sdl_initialized_ = false; + } + std::unique_lock guard(frames_mutex_); + while (!frames_unused_.empty()) { + delete[] frames_unused_.top(); + frames_unused_.pop(); + } + while (!frames_queued_.empty()) { + delete[] frames_queued_.front(); + frames_queued_.pop(); + } +} + +void SDLAudioDriver::SDLCallback(void* userdata, SDL_AudioStream* stream, int additional_amount, + [[maybe_unused]] int total_amount) { + SCOPE_profile_cpu_f("apu"); + if (!userdata || !stream) { + REXAPU_ERROR("SDLAudioDriver::SDLCallback called with nullptr."); + return; + } + const auto driver = static_cast(userdata); + const int sample_count = + static_cast(channel_samples_ * std::max(driver->sdl_device_channels_, 1)); + const int len = static_cast(sizeof(float) * sample_count); + float* data = SDL_stack_alloc(float, sample_count); + if (!data) { + REXAPU_ERROR("SDLAudioDriver::SDLCallback failed to allocate {} samples", sample_count); + return; + } + while (additional_amount > 0) { + static uint32_t sdl_callback_count = 0; + std::unique_lock guard(driver->frames_mutex_); + if (driver->frames_queued_.empty()) { + if (sdl_callback_count < 10) { + REXAPU_DEBUG("SDLCallback: no frames queued (silence)"); + sdl_callback_count++; + } + std::memset(data, 0, len); + if (!SDL_PutAudioStreamData(stream, data, len)) { + REXAPU_ERROR("SDL_PutAudioStreamData() failed while filling silence: {}", SDL_GetError()); + break; + } + additional_amount -= len; + } else { + auto buffer = driver->frames_queued_.front(); + driver->frames_queued_.pop(); + if (REXCVAR_GET(audio_mute)) { + std::memset(data, 0, len); + } else { + switch (driver->sdl_device_channels_) { + case 2: + conversion::sequential_6_BE_to_interleaved_2_LE(data, buffer, channel_samples_); + break; + case 6: + conversion::sequential_6_BE_to_interleaved_6_LE(data, buffer, channel_samples_); + break; + default: + assert_unhandled_case(driver->sdl_device_channels_); + break; + } + } + if (!SDL_PutAudioStreamData(stream, data, len)) { + REXAPU_ERROR("SDL_PutAudioStreamData() failed: {}", SDL_GetError()); + driver->frames_unused_.push(buffer); + break; + } + driver->frames_unused_.push(buffer); + + auto ret = driver->semaphore_->Release(1, nullptr); + assert_true(ret); + additional_amount -= len; + } + } + SDL_stack_free(data); +} + +} // namespace rex::audio::sdl diff --git a/src/audio/sdl/sdl_audio_system.cpp b/src/audio/sdl/sdl_audio_system.cpp new file mode 100644 index 0000000..68da0cf --- /dev/null +++ b/src/audio/sdl/sdl_audio_system.cpp @@ -0,0 +1,54 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +namespace rex::audio::sdl { + +std::unique_ptr SDLAudioSystem::Create( + runtime::FunctionDispatcher* function_dispatcher) { + return std::make_unique(function_dispatcher); +} + +SDLAudioSystem::SDLAudioSystem(runtime::FunctionDispatcher* function_dispatcher) + : AudioSystem(function_dispatcher) {} + +SDLAudioSystem::~SDLAudioSystem() {} + +void SDLAudioSystem::Initialize() { + AudioSystem::Initialize(); +} + +X_STATUS SDLAudioSystem::CreateDriver([[maybe_unused]] size_t index, + rex::thread::Semaphore* semaphore, AudioDriver** out_driver) { + assert_not_null(out_driver); + auto driver = new SDLAudioDriver(memory_, semaphore); + if (!driver->Initialize()) { + driver->Shutdown(); + delete driver; + return X_STATUS_UNSUCCESSFUL; + } + + *out_driver = driver; + return X_STATUS_SUCCESS; +} + +void SDLAudioSystem::DestroyDriver(AudioDriver* driver) { + assert_not_null(driver); + auto sdldriver = dynamic_cast(driver); + assert_not_null(sdldriver); + sdldriver->Shutdown(); + delete sdldriver; +} + +} // namespace rex::audio::sdl diff --git a/src/audio/xma_context.cpp b/src/audio/xma_context.cpp new file mode 100644 index 0000000..451eb47 --- /dev/null +++ b/src/audio/xma_context.cpp @@ -0,0 +1,768 @@ +/** +****************************************************************************** +* Xenia : Xbox 360 Emulator Research Project * +****************************************************************************** +* Copyright 2021 Ben Vanik. All rights reserved. * +* Released under the BSD license - see LICENSE in the root for more details. * +****************************************************************************** +* +* @modified Tom Clay, 2026 - Adapted for ReXGlue runtime +*/ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#if REX_COMPILER_MSVC +#pragma warning(push) +#pragma warning(disable : 4101 4244 5033) +#endif +#include "libavcodec/avcodec.h" +#include "libavutil/error.h" +#if REX_COMPILER_MSVC +#pragma warning(pop) +#endif +} // extern "C" + +// Credits for most of this code goes to: +// https://github.com/koolkdev/libertyv/blob/master/libav_wrapper/xma2dec.c + +namespace rex::audio { + +using stream::BitStream; + +const uint32_t XmaContext::kBitsPerPacketHeader; +const uint32_t XmaContext::kOutputMaxSizeBytes; + +XmaContext::XmaContext() + : work_completion_event_(rex::thread::Event::CreateAutoResetEvent(false)) {} + +XmaContext::~XmaContext() { + if (av_context_) { + avcodec_free_context(&av_context_); + } + if (av_frame_) { + av_frame_free(&av_frame_); + } +} + +int XmaContext::Setup(uint32_t id, memory::Memory* memory, uint32_t guest_ptr) { + id_ = id; + memory_ = memory; + guest_ptr_ = guest_ptr; + + // Allocate ffmpeg stuff: + av_packet_ = av_packet_alloc(); + assert_not_null(av_packet_); + av_packet_->buf = av_buffer_alloc(128 * 1024); + + // find the XMA2 audio decoder + av_codec_ = avcodec_find_decoder(AV_CODEC_ID_XMAFRAMES); + if (!av_codec_) { + REXAPU_ERROR("XmaContext {}: Codec not found", id); + return 1; + } + + av_context_ = avcodec_alloc_context3(av_codec_); + if (!av_context_) { + REXAPU_ERROR("XmaContext {}: Couldn't allocate context", id); + return 1; + } + + // Initialize these to 0. They'll actually be set later. + av_context_->channels = 0; + av_context_->sample_rate = 0; + + av_frame_ = av_frame_alloc(); + if (!av_frame_) { + REXAPU_ERROR("XmaContext {}: Couldn't allocate frame", id); + return 1; + } + + // FYI: We're purposely not opening the codec here. That is done later. + return 0; +} + +bool XmaContext::Work() { + if (!is_allocated() || !is_enabled()) { + return false; + } + + std::lock_guard lock(lock_); + set_is_enabled(false); + + auto context_ptr = memory()->TranslateVirtual(guest_ptr()); + XMA_CONTEXT_DATA data(context_ptr); + const XMA_CONTEXT_DATA initial_data = data; + + if (!data.output_buffer_valid) { + return true; + } + + memory::RingBuffer output_rb = PrepareOutputRingBuffer(&data); + + // Consume-only context: no input, just drain remaining subframes. + if (data.IsConsumeOnlyContext()) { + if (current_frame_remaining_subframes_ == 0) { + return true; + } + Consume(&output_rb, &data); + data.output_buffer_write_offset = output_rb.write_offset() / kOutputBytesPerBlock; + StoreContextMerged(data, initial_data, context_ptr); + return true; + } + + // Minimum free blocks needed before attempting a decode. + // Use subframe_decode_count (clamped to 1) instead of full frame size. + const uint32_t effective_sdc = std::max(static_cast(1), data.subframe_decode_count); + const int32_t minimum_subframe_decode_count = + static_cast(effective_sdc) + data.output_buffer_padding; + + if (minimum_subframe_decode_count > remaining_subframe_blocks_in_output_buffer_) { + StoreContextMerged(data, initial_data, context_ptr); + return true; + } + + while (remaining_subframe_blocks_in_output_buffer_ >= minimum_subframe_decode_count) { + Decode(&data); + Consume(&output_rb, &data); + + if (!data.IsAnyInputBufferValid() || data.error_status == 4) { + break; + } + } + + data.output_buffer_write_offset = output_rb.write_offset() / kOutputBytesPerBlock; + + if (output_rb.empty()) { + data.output_buffer_valid = 0; + } + + StoreContextMerged(data, initial_data, context_ptr); + return true; +} + +void XmaContext::Enable() { + std::lock_guard lock(lock_); + set_is_enabled(true); +} + +bool XmaContext::Block(bool poll) { + if (!lock_.try_lock()) { + if (poll) { + return false; + } + lock_.lock(); + } + lock_.unlock(); + return true; +} + +void XmaContext::Clear() { + std::lock_guard lock(lock_); + REXAPU_NOISY_DEBUG("XmaContext: reset context {}", id()); + + auto context_ptr = memory()->TranslateVirtual(guest_ptr()); + XMA_CONTEXT_DATA data(context_ptr); + ClearLocked(&data); + data.Store(context_ptr); +} + +void XmaContext::ClearLocked(XMA_CONTEXT_DATA* data) { + data->input_buffer_0_valid = 0; + data->input_buffer_1_valid = 0; + data->output_buffer_valid = 0; + + data->input_buffer_read_offset = kBitsPerPacketHeader; + data->output_buffer_read_offset = 0; + data->output_buffer_write_offset = 0; + + current_frame_remaining_subframes_ = 0; + loop_frame_output_limit_ = 0; + loop_start_skip_pending_ = false; +} + +void XmaContext::Disable() { + std::lock_guard lock(lock_); + set_is_enabled(false); +} + +void XmaContext::Release() { + std::lock_guard lock(lock_); + assert_true(is_allocated()); + + set_is_allocated(false); + auto context_ptr = memory()->TranslateVirtual(guest_ptr()); + std::memset(context_ptr, 0, sizeof(XMA_CONTEXT_DATA)); +} + +void XmaContext::SwapInputBuffer(XMA_CONTEXT_DATA* data) { + if (data->current_buffer == 0) { + data->input_buffer_0_valid = 0; + } else { + data->input_buffer_1_valid = 0; + } + data->current_buffer ^= 1; + data->input_buffer_read_offset = kBitsPerPacketHeader; +} + +void XmaContext::UpdateLoopStatus(XMA_CONTEXT_DATA* data) { + if (data->loop_count == 0) { + return; + } + + const uint32_t loop_start = std::max(kBitsPerPacketHeader, data->loop_start); + const uint32_t loop_end = std::max(kBitsPerPacketHeader, data->loop_end); + + if (data->input_buffer_read_offset != loop_end) { + return; + } + + data->input_buffer_read_offset = loop_start; + loop_start_skip_pending_ = true; + + if (data->loop_count < 255) { + data->loop_count--; + } +} + +int XmaContext::GetSampleRate(int id) { + return kIdToSampleRate[std::min(id, 3)]; +} + +int16_t XmaContext::GetPacketNumber(size_t size, size_t bit_offset) { + if (bit_offset < kBitsPerPacketHeader) { + assert_always(); + return -1; + } + if (bit_offset >= (size << 3)) { + assert_always(); + return -1; + } + size_t byte_offset = bit_offset >> 3; + size_t packet_number = byte_offset / kBytesPerPacket; + return static_cast(packet_number); +} + +uint32_t XmaContext::GetCurrentInputBufferSize(XMA_CONTEXT_DATA* data) { + return data->GetCurrentInputBufferPacketCount() * kBytesPerPacket; +} + +uint8_t* XmaContext::GetCurrentInputBuffer(XMA_CONTEXT_DATA* data) { + return memory()->TranslatePhysical(data->GetCurrentInputBufferAddress()); +} + +uint32_t XmaContext::GetAmountOfBitsToRead(uint32_t remaining_stream_bits, uint32_t frame_size) { + return std::min(remaining_stream_bits, frame_size); +} + +const uint8_t* XmaContext::GetNextPacket(XMA_CONTEXT_DATA* data, uint32_t next_packet_index, + uint32_t current_input_packet_count) { + if (next_packet_index < current_input_packet_count) { + return memory()->TranslatePhysical(data->GetCurrentInputBufferAddress()) + + next_packet_index * kBytesPerPacket; + } + + const uint8_t next_buffer_index = data->current_buffer ^ 1; + if (!data->IsInputBufferValid(next_buffer_index)) { + return nullptr; + } + + const uint32_t next_buffer_address = data->GetInputBufferAddress(next_buffer_index); + if (!next_buffer_address) { + REXAPU_ERROR("XmaContext {}: Buffer marked valid but has null pointer!", id()); + return nullptr; + } + + return memory()->TranslatePhysical(next_buffer_address); +} + +uint32_t XmaContext::GetNextPacketReadOffset(uint8_t* buffer, uint32_t next_packet_index, + uint32_t current_input_packet_count) { + while (next_packet_index < current_input_packet_count) { + uint8_t* next_packet = buffer + (next_packet_index * kBytesPerPacket); + const uint32_t packet_frame_offset = xma::GetPacketFrameOffset(next_packet); + + if (packet_frame_offset <= kMaxFrameSizeinBits) { + return (next_packet_index * kBitsPerPacket) + packet_frame_offset; + } + next_packet_index++; + } + + return kBitsPerPacketHeader; +} + +memory::RingBuffer XmaContext::PrepareOutputRingBuffer(XMA_CONTEXT_DATA* data) { + const uint32_t output_capacity = data->output_buffer_block_count * kOutputBytesPerBlock; + const uint32_t output_read_offset = data->output_buffer_read_offset * kOutputBytesPerBlock; + const uint32_t output_write_offset = data->output_buffer_write_offset * kOutputBytesPerBlock; + + if (output_capacity > kOutputMaxSizeBytes) { + REXAPU_WARN( + "XmaContext {}: Output buffer exceeds expected size! " + "(Actual: {} Max: {})", + id(), output_capacity, kOutputMaxSizeBytes); + } + + uint8_t* output_buffer = memory()->TranslatePhysical(data->output_buffer_ptr); + + memory::RingBuffer output_rb(output_buffer, output_capacity); + output_rb.set_read_offset(output_read_offset); + output_rb.set_write_offset(output_write_offset); + remaining_subframe_blocks_in_output_buffer_ = + static_cast(output_rb.write_count()) / kOutputBytesPerBlock; + + return output_rb; +} + +kPacketInfo XmaContext::GetPacketInfo(uint8_t* packet, uint32_t frame_offset) { + kPacketInfo packet_info = {}; + + const uint32_t first_frame_offset = xma::GetPacketFrameOffset(packet); + BitStream stream(packet, kBitsPerPacket); + stream.SetOffset(first_frame_offset); + + if (frame_offset < first_frame_offset) { + packet_info.current_frame_ = 0; + packet_info.current_frame_size_ = first_frame_offset - frame_offset; + } + + while (true) { + if (stream.BitsRemaining() < kBitsPerFrameHeader) { + break; + } + + const uint64_t frame_size = stream.Peek(kBitsPerFrameHeader); + if (frame_size == 0 || frame_size == xma::kMaxFrameLength) { + break; + } + + if (stream.offset_bits() == frame_offset) { + packet_info.current_frame_ = packet_info.frame_count_; + packet_info.current_frame_size_ = static_cast(frame_size); + } + + packet_info.frame_count_++; + + if (frame_size > stream.BitsRemaining()) { + break; + } + + stream.Advance(frame_size - 1); + + if (stream.Read(1) == 0) { + break; + } + } + + if (xma::IsPacketXma2Type(packet)) { + const uint8_t xma2_frame_count = xma::GetPacketFrameCount(packet); + if (xma2_frame_count > packet_info.frame_count_) { + if (packet_info.current_frame_size_ == 0) { + packet_info.current_frame_ = packet_info.frame_count_; + } + packet_info.frame_count_ = xma2_frame_count; + } + } + return packet_info; +} + +void XmaContext::StoreContextMerged(const XMA_CONTEXT_DATA& data, + const XMA_CONTEXT_DATA& initial_data, uint8_t* context_ptr) { + XMA_CONTEXT_DATA fresh(context_ptr); + + fresh.loop_count = data.loop_count; + fresh.output_buffer_write_offset = data.output_buffer_write_offset; + if (initial_data.input_buffer_0_valid && !data.input_buffer_0_valid) { + fresh.input_buffer_0_valid = 0; + } + if (initial_data.input_buffer_1_valid && !data.input_buffer_1_valid) { + fresh.input_buffer_1_valid = 0; + } + + if (initial_data.output_buffer_valid && !data.output_buffer_valid) { + fresh.output_buffer_valid = 0; + } + + fresh.input_buffer_read_offset = data.input_buffer_read_offset; + fresh.error_status = data.error_status; + fresh.current_buffer = data.current_buffer; + fresh.output_buffer_read_offset = data.output_buffer_read_offset; + + fresh.Store(context_ptr); +} + +void XmaContext::Consume(memory::RingBuffer* output_rb, const XMA_CONTEXT_DATA* data) { + if (!current_frame_remaining_subframes_) { + return; + } + + if (loop_frame_output_limit_ > 0) { + const uint8_t total_subframes = (kBytesPerFrameChannel / kOutputBytesPerBlock) + << data->is_stereo; + const uint8_t consumed = total_subframes - current_frame_remaining_subframes_; + if (consumed >= loop_frame_output_limit_) { + remaining_subframe_blocks_in_output_buffer_ -= data->output_buffer_padding; + current_frame_remaining_subframes_ = 0; + loop_frame_output_limit_ = 0; + return; + } + } + + const uint8_t effective_sdc = std::max(static_cast(1), data->subframe_decode_count); + int8_t subframes_to_write = std::min(static_cast(current_frame_remaining_subframes_), + static_cast(effective_sdc)); + + if (loop_frame_output_limit_ > 0) { + const uint8_t total_subframes = (kBytesPerFrameChannel / kOutputBytesPerBlock) + << data->is_stereo; + const uint8_t consumed = total_subframes - current_frame_remaining_subframes_; + const int8_t remaining_until_limit = static_cast(loop_frame_output_limit_ - consumed); + if (subframes_to_write > remaining_until_limit) { + subframes_to_write = remaining_until_limit; + } + } + + const int8_t raw_frame_read_offset = + ((kBytesPerFrameChannel / kOutputBytesPerBlock) << data->is_stereo) - + current_frame_remaining_subframes_; + + output_rb->Write(raw_frame_.data() + (kOutputBytesPerBlock * raw_frame_read_offset), + subframes_to_write * kOutputBytesPerBlock); + + const int8_t headroom = (current_frame_remaining_subframes_ - subframes_to_write == 0) + ? data->output_buffer_padding + : 0; + + remaining_subframe_blocks_in_output_buffer_ -= subframes_to_write + headroom; + current_frame_remaining_subframes_ -= subframes_to_write; +} + +int XmaContext::PrepareDecoder(int sample_rate, bool is_two_channel) { + sample_rate = GetSampleRate(sample_rate); + + uint32_t channels = is_two_channel ? 2 : 1; + if (av_context_->sample_rate != sample_rate || + av_context_->channels != static_cast(channels)) { + REXAPU_NOISY_DEBUG("XmaContext {}: Codec reinit: rate {} -> {}, channels {} -> {}", id(), + av_context_->sample_rate, sample_rate, av_context_->channels, channels); + avcodec_free_context(&av_context_); + av_context_ = avcodec_alloc_context3(av_codec_); + + av_context_->sample_rate = sample_rate; + av_context_->channels = channels; + av_context_->flags2 |= AV_CODEC_FLAG2_SKIP_MANUAL; + + if (avcodec_open2(av_context_, av_codec_, NULL) < 0) { + REXAPU_ERROR("XmaContext: Failed to reopen FFmpeg context"); + return -1; + } + return 1; + } + return 0; +} + +void XmaContext::PreparePacket(uint32_t frame_size, uint32_t frame_padding) { + av_packet_->data = xma_frame_.data(); + av_packet_->size = static_cast(1 + ((frame_padding + frame_size) / 8) + + (((frame_padding + frame_size) % 8) ? 1 : 0)); + + auto padding_end = av_packet_->size * 8 - (8 + frame_padding + frame_size); + assert_true(padding_end < 8); + xma_frame_[0] = ((frame_padding & 7) << 5) | ((padding_end & 7) << 2); +} + +bool XmaContext::DecodePacket(AVCodecContext* av_context, const AVPacket* av_packet, + AVFrame* av_frame) { + auto ret = avcodec_send_packet(av_context, av_packet); + if (ret < 0) { + char errbuf[AV_ERROR_MAX_STRING_SIZE]; + av_strerror(ret, errbuf, sizeof(errbuf)); + REXAPU_ERROR("XmaContext {}: Error sending packet for decoding: {} ({})", id(), errbuf, ret); + return false; + } + ret = avcodec_receive_frame(av_context, av_frame); + + if (ret == AVERROR(EAGAIN)) { + return false; + } + if (ret < 0) { + char errbuf[AV_ERROR_MAX_STRING_SIZE]; + av_strerror(ret, errbuf, sizeof(errbuf)); + REXAPU_ERROR("XmaContext {}: Error during decoding: {} ({})", id(), errbuf, ret); + return false; + } + return true; +} + +void XmaContext::Decode(XMA_CONTEXT_DATA* data) { + SCOPE_profile_cpu_f("apu"); + + if (!data->IsAnyInputBufferValid()) { + return; + } + + if (current_frame_remaining_subframes_ > 0) { + return; + } + + if (!data->IsCurrentInputBufferValid()) { + SwapInputBuffer(data); + if (!data->IsCurrentInputBufferValid()) { + return; + } + } + + uint8_t* current_input_buffer = GetCurrentInputBuffer(data); + + input_buffer_.fill(0); + + // Detect loop end frame before UpdateLoopStatus resets the offset. + bool is_loop_end_frame = false; + if (data->loop_count > 0) { + const uint32_t loop_end = std::max(kBitsPerPacketHeader, data->loop_end); + is_loop_end_frame = (data->input_buffer_read_offset == loop_end); + } + + UpdateLoopStatus(data); + + if (!data->output_buffer_block_count) { + REXAPU_ERROR("XmaContext {}: Error - Received 0 for output_buffer_block_count!", id()); + return; + } + + if (data->input_buffer_read_offset < kBitsPerPacketHeader) { + data->input_buffer_read_offset = kBitsPerPacketHeader; + } + + const uint32_t current_input_size = GetCurrentInputBufferSize(data); + const uint32_t current_input_packet_count = current_input_size / kBytesPerPacket; + + const int16_t packet_index = GetPacketNumber(current_input_size, data->input_buffer_read_offset); + + if (packet_index == -1) { + REXAPU_ERROR("XmaContext {}: Invalid packet index. Input read offset: {}", id(), + static_cast(data->input_buffer_read_offset)); + return; + } + + uint8_t* packet = current_input_buffer + (packet_index * kBytesPerPacket); + const uint32_t packet_first_frame_offset = xma::GetPacketFrameOffset(packet); + uint32_t relative_offset = data->input_buffer_read_offset % kBitsPerPacket; + + if (relative_offset < packet_first_frame_offset) { + data->input_buffer_read_offset = (packet_index * kBitsPerPacket) + packet_first_frame_offset; + relative_offset = packet_first_frame_offset; + } + + const uint8_t skip_count = xma::GetPacketSkipCount(packet); + + // Full packet skip (0xFF) -- no new frames begin in this packet. + if (skip_count == 0xFF) { + uint32_t next_input_offset = + GetNextPacketReadOffset(current_input_buffer, packet_index + 1, current_input_packet_count); + if (next_input_offset == kBitsPerPacketHeader) { + SwapInputBuffer(data); + } + data->input_buffer_read_offset = next_input_offset; + return; + } + + kPacketInfo packet_info = GetPacketInfo(packet, relative_offset); + const uint32_t packet_to_skip = skip_count + 1; + const uint32_t next_packet_index = packet_index + packet_to_skip; + + // Frame header split across packet boundary. + if (packet_info.current_frame_size_ == 0) { + const uint8_t* next_packet = GetNextPacket(data, next_packet_index, current_input_packet_count); + if (!next_packet) { + SwapInputBuffer(data); + return; + } + std::memcpy(input_buffer_.data(), packet + kBytesPerPacketHeader, kBytesPerPacketData); + std::memcpy(input_buffer_.data() + kBytesPerPacketData, next_packet + kBytesPerPacketHeader, + kBytesPerPacketData); + + BitStream combined(input_buffer_.data(), (kBitsPerPacket - kBitsPerPacketHeader) * 2); + combined.SetOffset(relative_offset - kBitsPerPacketHeader); + + uint64_t frame_size = combined.Peek(kBitsPerFrameHeader); + if (frame_size == xma::kMaxFrameLength) { + data->error_status = 4; + return; + } + packet_info.current_frame_size_ = static_cast(frame_size); + } + + BitStream stream(current_input_buffer, (packet_index + 1) * kBitsPerPacket); + stream.SetOffset(data->input_buffer_read_offset); + + const uint64_t bits_to_copy = GetAmountOfBitsToRead(static_cast(stream.BitsRemaining()), + packet_info.current_frame_size_); + + if (bits_to_copy == 0) { + REXAPU_ERROR("XmaContext {}: There are no bits to copy!", id()); + SwapInputBuffer(data); + return; + } + + if (packet_info.isLastFrameInPacket()) { + if (stream.BitsRemaining() < packet_info.current_frame_size_) { + const uint8_t* next_packet = + GetNextPacket(data, next_packet_index, current_input_packet_count); + if (!next_packet) { + data->error_status = 4; + return; + } + std::memcpy(input_buffer_.data() + kBytesPerPacketData, next_packet + kBytesPerPacketHeader, + kBytesPerPacketData); + } + } + + std::memcpy(input_buffer_.data(), packet + kBytesPerPacketHeader, kBytesPerPacketData); + + stream = BitStream(input_buffer_.data(), (kBitsPerPacket - kBitsPerPacketHeader) * 2); + stream.SetOffset(relative_offset - kBitsPerPacketHeader); + + xma_frame_.fill(0); + + const uint32_t padding_start = + static_cast(stream.Copy(xma_frame_.data() + 1, packet_info.current_frame_size_)); + + raw_frame_.fill(0); + + PrepareDecoder(data->sample_rate, bool(data->is_stereo)); + PreparePacket(packet_info.current_frame_size_, padding_start); + if (DecodePacket(av_context_, av_packet_, av_frame_)) { + ConvertFrame(reinterpret_cast(&av_frame_->data), bool(data->is_stereo), + raw_frame_.data()); + current_frame_remaining_subframes_ = 4 << data->is_stereo; + + // Loop end: limit output to subframes 0..loop_subframe_end. + if (is_loop_end_frame) { + loop_frame_output_limit_ = (data->loop_subframe_end + 1) << data->is_stereo; + } else { + loop_frame_output_limit_ = 0; + } + + // Loop start: skip leading subframes per loop_subframe_skip. + if (loop_start_skip_pending_) { + const uint8_t skip = data->loop_subframe_skip << data->is_stereo; + if (skip < current_frame_remaining_subframes_) { + current_frame_remaining_subframes_ -= skip; + } + loop_start_skip_pending_ = false; + } + } + + // Compute where to go next. + if (!packet_info.isLastFrameInPacket()) { + const uint32_t next_frame_offset = + (data->input_buffer_read_offset + bits_to_copy) % kBitsPerPacket; + data->input_buffer_read_offset = (packet_index * kBitsPerPacket) + next_frame_offset; + return; + } + + uint32_t next_input_offset = + GetNextPacketReadOffset(current_input_buffer, next_packet_index, current_input_packet_count); + + if (next_input_offset == kBitsPerPacketHeader) { + SwapInputBuffer(data); + if (data->IsAnyInputBufferValid()) { + next_input_offset = xma::GetPacketFrameOffset( + memory()->TranslatePhysical(data->GetCurrentInputBufferAddress())); + + if (next_input_offset > kMaxFrameSizeinBits) { + SwapInputBuffer(data); + return; + } + } + } + data->input_buffer_read_offset = next_input_offset; +} + +void XmaContext::ConvertFrame(const uint8_t** samples, bool is_two_channel, + uint8_t* output_buffer) { + // Loop through every sample, convert and drop it into the output array. + // If more than one channel, we need to interleave the samples from each + // channel next to each other. Always saturate because FFmpeg output is + // not limited to [-1, 1] (for example 1.095 as seen in 5454082B). + constexpr float scale = (1 << 15) - 1; + auto out = reinterpret_cast(output_buffer); + + // For testing of vectorized versions, stereo audio is common in 4D5307E6, + // since the first menu frame; the intro cutscene also has more than 2 + // channels. +#if REX_ARCH_AMD64 + static_assert(kSamplesPerFrame % 8 == 0); + const auto in_channel_0 = reinterpret_cast(samples[0]); + const __m128 scale_mm = _mm_set1_ps(scale); + if (is_two_channel) { + const auto in_channel_1 = reinterpret_cast(samples[1]); + const __m128i shufmask = _mm_set_epi8(14, 15, 6, 7, 12, 13, 4, 5, 10, 11, 2, 3, 8, 9, 0, 1); + for (uint32_t i = 0; i < kSamplesPerFrame; i += 4) { + // Load 8 samples, 4 for each channel. + __m128 in_mm0 = _mm_loadu_ps(&in_channel_0[i]); + __m128 in_mm1 = _mm_loadu_ps(&in_channel_1[i]); + // Rescale. + in_mm0 = _mm_mul_ps(in_mm0, scale_mm); + in_mm1 = _mm_mul_ps(in_mm1, scale_mm); + // Cast to int32. + __m128i out_mm0 = _mm_cvtps_epi32(in_mm0); + __m128i out_mm1 = _mm_cvtps_epi32(in_mm1); + // Saturated cast and pack to int16. + __m128i out_mm = _mm_packs_epi32(out_mm0, out_mm1); + // Interleave channels and byte swap. + out_mm = _mm_shuffle_epi8(out_mm, shufmask); + // Store, as [out + i * 4] movdqu. + _mm_storeu_si128(reinterpret_cast<__m128i*>(&out[i * 2]), out_mm); + } + } else { + const __m128i shufmask = _mm_set_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1); + for (uint32_t i = 0; i < kSamplesPerFrame; i += 8) { + // Load 8 samples, as [in_channel_0 + i * 4] and + // [in_channel_0 + i * 4 + 16] movups. + __m128 in_mm0 = _mm_loadu_ps(&in_channel_0[i]); + __m128 in_mm1 = _mm_loadu_ps(&in_channel_0[i + 4]); + // Rescale. + in_mm0 = _mm_mul_ps(in_mm0, scale_mm); + in_mm1 = _mm_mul_ps(in_mm1, scale_mm); + // Cast to int32. + __m128i out_mm0 = _mm_cvtps_epi32(in_mm0); + __m128i out_mm1 = _mm_cvtps_epi32(in_mm1); + // Saturated cast and pack to int16. + __m128i out_mm = _mm_packs_epi32(out_mm0, out_mm1); + // Byte swap. + out_mm = _mm_shuffle_epi8(out_mm, shufmask); + // Store, as [out + i * 2] movdqu. + _mm_storeu_si128(reinterpret_cast<__m128i*>(&out[i]), out_mm); + } + } +#else + uint32_t o = 0; + for (uint32_t i = 0; i < kSamplesPerFrame; i++) { + for (uint32_t j = 0; j <= uint32_t(is_two_channel); j++) { + // Select the appropriate array based on the current channel. + auto in = reinterpret_cast(samples[j]); + + // Raw samples sometimes aren't within [-1, 1] + float scaled_sample = rex::clamp_float(in[i], -1.0f, 1.0f) * scale; + + // Convert the sample and output it in big endian. + auto sample = static_cast(scaled_sample); + out[o++] = rex::byte_swap(sample); + } + } +#endif +} + +} // namespace rex::audio diff --git a/src/audio/xma_decoder.cpp b/src/audio/xma_decoder.cpp new file mode 100644 index 0000000..cbcdece --- /dev/null +++ b/src/audio/xma_decoder.cpp @@ -0,0 +1,375 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include "libavutil/log.h" +} // extern "C" + +REXCVAR_DEFINE_BOOL(ffmpeg_verbose, false, "Audio", "Verbose FFmpeg output (debug and above)"); + +// As with normal Microsoft, there are like twelve different ways to access +// the audio APIs. Early games use XMA*() methods almost exclusively to touch +// decoders. Later games use XAudio*() and direct memory writes to the XMA +// structures (as opposed to the XMA* calls), meaning that we have to support +// both. +// +// The XMA*() functions just manipulate the audio system in the guest context +// and let the normal XmaDecoder handling take it, to prevent duplicate +// implementations. They can be found in xboxkrnl_audio_xma.cc +// +// XMA details: +// https://devel.nuclex.org/external/svn/directx/trunk/include/xma2defs.h +// https://github.com/gdawg/fsbext/blob/master/src/xma_header.h +// +// XAudio2 uses XMA under the covers, and seems to map with the same +// restrictions of frame/subframe/etc: +// https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.xaudio2.xaudio2_buffer(v=vs.85).aspx +// +// XMA contexts are 64b in size and tight bitfields. They are in physical +// memory not usually available to games. Games will use MmMapIoSpace to get +// the 64b pointer in user memory so they can party on it. If the game doesn't +// do this, it's likely they are either passing the context to XAudio or +// using the XMA* functions. + +namespace rex::audio { + +XmaDecoder::XmaDecoder(runtime::FunctionDispatcher* function_dispatcher) + : memory_(function_dispatcher->memory()), function_dispatcher_(function_dispatcher) {} + +XmaDecoder::~XmaDecoder() = default; + +void av_log_callback(void* avcl, int level, const char* fmt, va_list va) { + if (!REXCVAR_GET(ffmpeg_verbose) && level > AV_LOG_WARNING) { + return; + } + + string::StringBuffer buff; + buff.AppendVarargs(fmt, va); + auto msg = buff.to_string_view(); + + switch (level) { + case AV_LOG_ERROR: + REXAPU_ERROR("ffmpeg: {}", msg); + break; + case AV_LOG_WARNING: + REXAPU_WARN("ffmpeg: {}", msg); + break; + case AV_LOG_INFO: + REXAPU_INFO("ffmpeg: {}", msg); + break; + case AV_LOG_VERBOSE: + case AV_LOG_DEBUG: + default: + REXAPU_DEBUG("ffmpeg: {}", msg); + break; + } +} + +X_STATUS XmaDecoder::Setup(system::KernelState* kernel_state) { + // Setup ffmpeg logging callback + av_log_set_callback(av_log_callback); + + // Register APU/XMA MMIO handlers + // XMA registers are at 0x7FEA0000-0x7FEAFFFF + memory()->AddVirtualMappedRange( + 0x7FEA0000, // base address + 0xFFFF0000, // mask + 0x0000FFFF, // size (64KB) + this, // context (XmaDecoder*) + reinterpret_cast(MMIOReadRegisterThunk), + reinterpret_cast(MMIOWriteRegisterThunk)); + REXAPU_DEBUG("XMA: Registered MMIO handlers at 0x7FEA0000-0x7FEAFFFF"); + + // Setup XMA context data. + // The Xbox 360 kernel allocates the contexts with X_PAGE_NOCACHE | + // X_PAGE_READWRITE and writes MmGetPhysicalAddress for the address to the + // register. + context_data_first_ptr_ = memory()->SystemHeapAlloc(sizeof(XMA_CONTEXT_DATA) * kContextCount, 256, + memory::kSystemHeapPhysical); + context_data_last_ptr_ = context_data_first_ptr_ + (sizeof(XMA_CONTEXT_DATA) * kContextCount - 1); + register_file_[XmaRegister::ContextArrayAddress] = + memory()->GetPhysicalAddress(context_data_first_ptr_); + + // Setup XMA contexts. + for (size_t i = 0; i < kContextCount; ++i) { + uint32_t guest_ptr = context_data_first_ptr_ + i * sizeof(XMA_CONTEXT_DATA); + XmaContext& context = contexts_[i]; + if (context.Setup(i, memory(), guest_ptr)) { + assert_always(); + } + } + register_file_[XmaRegister::NextContextIndex] = 1; + context_bitmap_.Resize(kContextCount); + + worker_running_ = true; + work_event_ = rex::thread::Event::CreateAutoResetEvent(false); + assert_not_null(work_event_); + worker_thread_ = system::object_ref( + new system::XHostThread(kernel_state, 128 * 1024, 0, [this]() { + WorkerThreadMain(); + return 0; + })); + worker_thread_->set_name("XMA Decoder"); + + worker_thread_->Create(); + + return X_STATUS_SUCCESS; +} + +void XmaDecoder::WorkerThreadMain() { + while (worker_running_) { + // Okay, let's loop through XMA contexts to find ones we need to decode! + bool did_work = false; + for (uint32_t n = 0; n < kContextCount && worker_running_; n++) { + XmaContext& context = contexts_[n]; + bool worked = context.Work(); + if (worked) { + context.SignalWorkDone(); + PROFILE_XMA_FRAME_DECODED(); + } + did_work = did_work || worked; + } + + if (paused_) { + pause_fence_.Signal(); + resume_fence_.Wait(); + } + + if (did_work) { + continue; + } + // No work done this iteration, block until signaled. + rex::thread::Wait(work_event_.get(), false); + } +} + +void XmaDecoder::Shutdown() { + if (!worker_thread_) { + return; + } + + worker_running_ = false; + + if (work_event_) { + work_event_->Set(); + } + + if (paused_) { + Resume(); + } + + // Wait up to 2 seconds for worker thread to exit gracefully. + auto result = rex::thread::Wait(worker_thread_->thread(), false, std::chrono::milliseconds(2000)); + if (result == rex::thread::WaitResult::kTimeout) { + REXAPU_WARN("XMA: Worker thread did not exit within 2s, abandoning"); + } + worker_thread_.reset(); + + if (context_data_first_ptr_) { + memory()->SystemHeapFree(context_data_first_ptr_); + } + + context_data_first_ptr_ = 0; + context_data_last_ptr_ = 0; +} + +int XmaDecoder::GetContextId(uint32_t guest_ptr) { + static_assert_size(XMA_CONTEXT_DATA, 64); + if (guest_ptr < context_data_first_ptr_ || guest_ptr > context_data_last_ptr_) { + return -1; + } + assert_zero(guest_ptr & 0x3F); + return (guest_ptr - context_data_first_ptr_) >> 6; +} + +uint32_t XmaDecoder::AllocateContext() { + size_t index = context_bitmap_.Acquire(); + if (index == -1) { + // Out of contexts. + return 0; + } + + XmaContext& context = contexts_[index]; + assert_false(context.is_allocated()); + context.set_is_allocated(true); + return context.guest_ptr(); +} + +void XmaDecoder::ReleaseContext(uint32_t guest_ptr) { + auto context_id = GetContextId(guest_ptr); + assert_true(context_id >= 0); + + XmaContext& context = contexts_[context_id]; + assert_true(context.is_allocated()); + context.Release(); + context_bitmap_.Release(context_id); +} + +bool XmaDecoder::BlockOnContext(uint32_t guest_ptr, bool poll) { + auto context_id = GetContextId(guest_ptr); + assert_true(context_id >= 0); + + XmaContext& context = contexts_[context_id]; + return context.Block(poll); +} + +uint32_t XmaDecoder::ReadRegister(uint32_t addr) { + auto r = (addr & 0xFFFF) / 4; + + assert_true(r < XmaRegisterFile::kRegisterCount); + + switch (r) { + case XmaRegister::ContextArrayAddress: + break; + case XmaRegister::CurrentContextIndex: { + // 0606h (1818h) is rotating context processing # set to hardware ID of + // context being processed. + // If bit 200h is set, the locking code will possibly collide on hardware + // IDs and error out, so we should never set it (I think?). + uint32_t& current_context_index = register_file_[XmaRegister::CurrentContextIndex]; + uint32_t& next_context_index = register_file_[XmaRegister::NextContextIndex]; + // To prevent games from seeing a stuck XMA context, return a rotating + // number. + current_context_index = next_context_index; + next_context_index = (next_context_index + 1) % kContextCount; + break; + } + default: + const auto register_info = register_file_.GetRegisterInfo(r); + if (register_info) { + REXAPU_DEBUG("XMA: Read from unhandled register ({:04X}, {})", r, register_info->name); + } else { + REXAPU_DEBUG("XMA: Read from unknown register ({:04X})", r); + } + break; + } + + return rex::byte_swap(register_file_[r]); +} + +void XmaDecoder::WriteRegister(uint32_t addr, uint32_t value) { + SCOPE_profile_cpu_f("apu"); + + uint32_t r = (addr & 0xFFFF) / 4; + value = rex::byte_swap(value); + + assert_true(r < XmaRegisterFile::kRegisterCount); + register_file_[r] = value; + + if (r >= XmaRegister::Context0Kick && r <= XmaRegister::Context9Kick) { + // Context kick command. + // This will kick off the given hardware contexts. + // Basically, this kicks the SPU and says "hey, decode that audio!" + // XMAEnableContext + + // The context ID is a bit in the range of the entire context array. + uint32_t base_context_id = (r - XmaRegister::Context0Kick) * 32; + uint32_t kicked_value = value; + for (int i = 0; value && i < 32; ++i, value >>= 1) { + if (value & 1) { + uint32_t context_id = base_context_id + i; + auto& context = contexts_[context_id]; + context.Enable(); + } + } + // Signal the decoder thread to start processing. + work_event_->Set(); + // Block until the worker finishes, so the game sees updated context data. + for (int i = 0; kicked_value && i < 32; ++i, kicked_value >>= 1) { + if (kicked_value & 1) { + uint32_t context_id = base_context_id + i; + contexts_[context_id].WaitForWorkDone(); + } + } + } else if (r >= XmaRegister::Context0Lock && r <= XmaRegister::Context9Lock) { + // Context lock command. + // This requests a lock by flagging the context. + // XMADisableContext + uint32_t base_context_id = (r - XmaRegister::Context0Lock) * 32; + for (int i = 0; value && i < 32; ++i, value >>= 1) { + if (value & 1) { + uint32_t context_id = base_context_id + i; + auto& context = contexts_[context_id]; + context.Disable(); + // [XMA fix] Added Block(false) after Disable(). Without this, the game + // could call XMADisableContext and start modifying the context struct + // while a decode was still in progress on the worker thread. Block() + // waits for the context mutex to be free (poll=false means wait, not spin). + context.Block(false); + } + } + // Signal the decoder thread to start processing. + // work_event_->Set(); + } else if (r >= XmaRegister::Context0Clear && r <= XmaRegister::Context9Clear) { + // Context clear command. + // This will reset the given hardware contexts. + uint32_t base_context_id = (r - XmaRegister::Context0Clear) * 32; + for (int i = 0; value && i < 32; ++i, value >>= 1) { + if (value & 1) { + uint32_t context_id = base_context_id + i; + XmaContext& context = contexts_[context_id]; + context.Clear(); + } + } + } else { + // 0601h (1804h) is written to with 0x02000000 and 0x03000000 around a lock + // operation + switch (r) { + default: { + const auto register_info = register_file_.GetRegisterInfo(r); + if (register_info) { + REXAPU_DEBUG("XMA: Write to unhandled register ({:04X}, {}): {:08X}", r, + register_info->name, value); + } else { + REXAPU_DEBUG("XMA: Write to unknown register ({:04X}): {:08X}", r, value); + } + break; + } +#pragma warning(suppress : 4065) + } + } +} + +void XmaDecoder::Pause() { + if (paused_) { + return; + } + paused_ = true; + + if (work_event_) { + work_event_->Set(); + } + pause_fence_.Wait(); +} + +void XmaDecoder::Resume() { + if (!paused_) { + return; + } + paused_ = false; + + resume_fence_.Signal(); +} + +} // namespace rex::audio diff --git a/src/audio/xma_register_file.cpp b/src/audio/xma_register_file.cpp new file mode 100644 index 0000000..d4b31db --- /dev/null +++ b/src/audio/xma_register_file.cpp @@ -0,0 +1,39 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include + +namespace rex::audio { + +XmaRegisterFile::XmaRegisterFile() { + std::memset(values, 0, sizeof(values)); +} + +const XmaRegisterInfo* XmaRegisterFile::GetRegisterInfo(uint32_t index) { + switch (index) { +#define XE_XMA_REGISTER(index, name) \ + case index: { \ + static const XmaRegisterInfo reg_info = { \ + #name, \ + }; \ + return ®_info; \ + } +#include +#undef XE_XMA_REGISTER + default: + return nullptr; + } +} + +} // namespace rex::audio diff --git a/src/codegen/CMakeLists.txt b/src/codegen/CMakeLists.txt new file mode 100644 index 0000000..0e67405 --- /dev/null +++ b/src/codegen/CMakeLists.txt @@ -0,0 +1,130 @@ +# Codegen library - PPC to C++ recompiler + +# Core recompiler sources +set(CODEGEN_CORE_SOURCES + codegen.cpp + codegen_flags.cpp + analyze.cpp + code_emitter.cpp + decoded_binary.cpp + codegen_writer.cpp + config.cpp + function_graph.cpp + function_scanner.cpp + sig_scanner.cpp + vtable_scanner.cpp + binary_view.cpp + instruction_dispatch.cpp + test_support.cpp + codegen_context.cpp + phase_register.cpp + phase_scan.cpp + phase_discover.cpp + phase_gapfill.cpp + phase_merge.cpp + phase_validate.cpp + template_registry.cpp + manifest.cpp + project_recompiler.cpp +) + +# PPC architecture sources (merged from rexarch) +set(CODEGEN_PPC_SOURCES + ppc/opcode.cpp + ppc/instruction.cpp + ppc/disasm.cpp +) + +# Instruction builder sources +set(CODEGEN_BUILDER_SOURCES + builders/context.cpp + builders/comparison.cpp + builders/arithmetic.cpp + builders/logical.cpp + builders/control_flow.cpp + builders/floating_point.cpp + builders/memory.cpp + builders/system.cpp + builders/vector.cpp +) + +# Inja templates +set(TEMPLATE_SOURCE_DIR "${REXGLUE_ROOT}/resources/templates") +set(TEMPLATE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated/templates") + +set(INJA_TEMPLATE_FILES + ${TEMPLATE_SOURCE_DIR}/init/app_header.inja + ${TEMPLATE_SOURCE_DIR}/init/main_cpp.inja + ${TEMPLATE_SOURCE_DIR}/init/cmakelists.inja + ${TEMPLATE_SOURCE_DIR}/init/cmake_presets.inja + ${TEMPLATE_SOURCE_DIR}/init/rexglue_cmake.inja + ${TEMPLATE_SOURCE_DIR}/init/manifest_toml.inja + ${TEMPLATE_SOURCE_DIR}/codegen/_indirect_call.inja + ${TEMPLATE_SOURCE_DIR}/codegen/init_cpp.inja + ${TEMPLATE_SOURCE_DIR}/codegen/init_h.inja + ${TEMPLATE_SOURCE_DIR}/codegen/sources_cmake.inja + ${TEMPLATE_SOURCE_DIR}/test/ppc_test_cases_cpp.inja + ${TEMPLATE_SOURCE_DIR}/test/ppc_test_decls_h.inja + ${TEMPLATE_SOURCE_DIR}/test/ppc_test_functions_cpp.inja + ${TEMPLATE_SOURCE_DIR}/test/ppc_config_h.inja +) + +# Build output header paths +set(EMBEDDED_HEADERS "") +foreach(TEMPLATE_FILE ${INJA_TEMPLATE_FILES}) + file(RELATIVE_PATH REL_PATH "${TEMPLATE_SOURCE_DIR}" "${TEMPLATE_FILE}") + string(REGEX REPLACE "\\.inja$" "" CANONICAL_ID "${REL_PATH}") + string(REPLACE "/" "_" VAR_NAME "${CANONICAL_ID}") + string(REPLACE "-" "_" VAR_NAME "${VAR_NAME}") + list(APPEND EMBEDDED_HEADERS "${TEMPLATE_OUTPUT_DIR}/${VAR_NAME}.inja.h") +endforeach() +list(APPEND EMBEDDED_HEADERS "${TEMPLATE_OUTPUT_DIR}/embedded_templates.h") + +add_custom_command( + OUTPUT ${EMBEDDED_HEADERS} + COMMAND ${CMAKE_COMMAND} + -DTEMPLATE_SOURCE_DIR=${TEMPLATE_SOURCE_DIR} + -DTEMPLATE_OUTPUT_DIR=${TEMPLATE_OUTPUT_DIR} + -P ${REXGLUE_ROOT}/cmake/embed_templates.cmake + DEPENDS ${INJA_TEMPLATE_FILES} ${REXGLUE_ROOT}/cmake/embed_templates.cmake + COMMENT "Embedding inja templates" + VERBATIM +) + +add_custom_target(embed_templates DEPENDS ${EMBEDDED_HEADERS}) + +add_library(rexcodegen STATIC + ${CODEGEN_CORE_SOURCES} + ${CODEGEN_PPC_SOURCES} + ${CODEGEN_BUILDER_SOURCES} +) +add_library(rex::codegen ALIAS rexcodegen) +add_dependencies(rexcodegen embed_templates) + + +target_include_directories(rexcodegen + PUBLIC + $ + $ + $ + $ + PRIVATE + ${REXGLUE_ROOT}/thirdparty/disasm + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/builders + ${CMAKE_CURRENT_BINARY_DIR}/generated/templates +) + +target_link_libraries(rexcodegen + PUBLIC + rexcore + rexruntime + fmt::fmt + spdlog::spdlog + PRIVATE + tomlplusplus + disasm + xxHash::xxhash + simde +) + diff --git a/src/codegen/analyze.cpp b/src/codegen/analyze.cpp new file mode 100644 index 0000000..c5f3d14 --- /dev/null +++ b/src/codegen/analyze.cpp @@ -0,0 +1,154 @@ +/** + * @file codegen/analyze.cpp + * @brief Analysis pipeline orchestrator + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "decoded_binary.h" + +#include +#include + +#include +#include +#include +#include + +#include "codegen_logging.h" + +namespace rex::codegen { + +Result Analyze(CodegenContext& ctx, ProgressReporter* reporter) { + REXCODEGEN_TRACE("Analyze: starting analysis..."); + + ctx.initDecoded(); + REXCODEGEN_TRACE("Analyze: decoded {} instructions across {} code regions", + ctx.decoded().instructionCount(), ctx.decoded().codeRegions().size()); + + // 1. Register entry points (imports, helpers, config, pdata) + if (reporter) + reporter->phaseChanged("Register"); + auto regResult = phases::Register(ctx, reporter); + if (!regResult) { + return regResult; + } + + // 2. Scan binary into code/data regions + if (reporter) + reporter->phaseChanged("Scan"); + auto scanResult = phases::Scan(ctx, reporter); + if (!scanResult) { + return scanResult; + } + + // 3. Discover function blocks iteratively (includes vtable scan) + if (reporter) + reporter->phaseChanged("Discover"); + auto discoverResult = phases::Discover(ctx, reporter); + if (!discoverResult) { + return discoverResult; + } + + // 3.5. Function pointer scan: find lis/addi pairs loading code addresses + // TODO(tomc): disabled for now, causes too many false positives + // functionPointerScan(ctx); + + // 4. Gap fill uncovered regions + discover blocks for gap-filled functions + cleanup + if (reporter) + reporter->phaseChanged("GapFill"); + auto gapFillResult = phases::GapFill(ctx, reporter); + if (!gapFillResult) { + return gapFillResult; + } + + // 5. Merge: resolve jumps and seal functions + if (reporter) + reporter->phaseChanged("Merge"); + auto mergeResult = phases::Merge(ctx, reporter); + if (!mergeResult) { + return mergeResult; + } + + // 6. Validate + if (reporter) + reporter->phaseChanged("Validate"); + auto validateResult = phases::Validate(ctx, reporter); + if (!validateResult) { + return validateResult; + } + + REXCODEGEN_TRACE("Analyze: complete - {} functions ready for code generation", + ctx.graph.functionCount()); + + return Ok(); +} + +//============================================================================= +// AnalysisErrors implementation +//============================================================================= + +const char* AnalysisErrors::CategoryName(Category cat) { + switch (cat) { + case Category::UnresolvedCall: + return "UnresolvedCall"; + case Category::MissingJumpTable: + return "MissingJumpTable"; + case Category::JumpTargetOutOfBounds: + return "JumpTargetOutOfBounds"; + case Category::DiscontinuousFunction: + return "DiscontinuousFunction"; + case Category::UnimplementedInsn: + return "UnimplementedInsn"; + default: + return "Unknown"; + } +} + +void AnalysisErrors::Add(Category cat, uint32_t addr, const std::string& msg) { + Add(cat, addr, 0, msg); +} + +void AnalysisErrors::Add(Category cat, uint32_t addr, uint32_t secondary, const std::string& msg) { + entries_.push_back({cat, addr, secondary, msg}); +} + +size_t AnalysisErrors::Count(Category cat) const { + return std::count_if(entries_.begin(), entries_.end(), + [cat](const Entry& e) { return e.category == cat; }); +} + +void AnalysisErrors::PrintReport() const { + if (entries_.empty()) { + return; + } + + REXCODEGEN_ERROR("=== ANALYSIS ERRORS ==="); + + // Group by category + std::map> byCategory; + for (const auto& entry : entries_) { + byCategory[entry.category].push_back(&entry); + } + + for (const auto& [cat, entries] : byCategory) { + REXCODEGEN_ERROR("{} ({}):", CategoryName(cat), entries.size()); + + for (const auto* entry : entries) { + if (entry->secondaryAddress != 0) { + REXCODEGEN_ERROR(" 0x{:08X} from 0x{:08X}: {}", entry->address, entry->secondaryAddress, + entry->message); + } else { + REXCODEGEN_ERROR(" 0x{:08X}: {}", entry->address, entry->message); + } + } + } + + REXCODEGEN_ERROR("Total: {} errors", entries_.size()); +} + +} // namespace rex::codegen diff --git a/src/codegen/binary_view.cpp b/src/codegen/binary_view.cpp new file mode 100644 index 0000000..30694bc --- /dev/null +++ b/src/codegen/binary_view.cpp @@ -0,0 +1,141 @@ +/** + * @file codegen/binary_view.cpp + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include + +#include +#include + +#include "codegen_logging.h" +#include +#include + +namespace rex::codegen { + +BinaryView BinaryView::fromModule(const runtime::Module& module) { + BinaryView view; + + // Copy metadata + view.baseAddress_ = module.base_address(); + view.imageSize_ = module.image_size(); + view.entryPoint_ = module.entry_point(); + view.exceptionDirectoryAddr_ = module.exception_directory_address(); + view.exceptionDirectorySize_ = module.exception_directory_size(); + view.exportTableAddr_ = module.export_table_address(); + + // Copy import symbols and calculate import thunk table start + // The import thunk table (and export table after it) extends to end of .text + uint32_t minImportAddr = std::numeric_limits::max(); + for (const auto& sym : module.binary_symbols()) { + if (sym.type == runtime::BinarySymbolType::Import) { + // Copy symbol for Register phase to use + view.importSymbols_.push_back(ImportSymbol{.address = sym.address, .name = sym.name}); + + // Track minimum address for thunk table range + if (sym.address != 0 && sym.address < minImportAddr) { + minImportAddr = sym.address; + } + } + } + if (minImportAddr != std::numeric_limits::max()) { + view.importThunkTableStart_ = minImportAddr; + REXCODEGEN_DEBUG("BinaryView: import thunk table starts at 0x{:08X}", minImportAddr); + + // Find section containing the import thunk table to determine end of import/export range + for (const auto& section : module.binary_sections()) { + uint32_t sectionEnd = section.virtual_address + section.virtual_size; + if (minImportAddr >= section.virtual_address && minImportAddr < sectionEnd) { + view.importExportRangeEnd_ = sectionEnd; + REXCODEGEN_DEBUG("BinaryView: import/export range ends at 0x{:08X} (end of {} section)", + view.importExportRangeEnd_, section.name); + break; + } + } + } + REXCODEGEN_DEBUG("BinaryView: copied {} import symbols", view.importSymbols_.size()); + + // Copy section data + const auto& binarySections = module.binary_sections(); + view.sectionNames_.reserve(binarySections.size()); + view.sectionData_.reserve(binarySections.size()); + view.sections_.reserve(binarySections.size()); + + uint32_t imageEnd = view.baseAddress_ + view.imageSize_; + for (const auto& section : binarySections) { + // Skip sections not mapped into memory + if (!section.host_data || section.virtual_size == 0) { + REXCODEGEN_DEBUG("BinaryView: skipping unmapped section '{}'", section.name); + continue; + } + // Skip sections that extend beyond the loaded image + if (section.virtual_address + section.virtual_size > imageEnd) { + REXCODEGEN_DEBUG("BinaryView: skipping section '{}' (extends past image end 0x{:08X})", + section.name, imageEnd); + continue; + } + + // Copy name + view.sectionNames_.push_back(std::string(section.name)); + + // Copy bytes + view.sectionData_.emplace_back(section.host_data, section.host_data + section.virtual_size); + + // Create view pointing into our owned data + view.sections_.push_back(SectionView{.name = view.sectionNames_.back(), + .baseAddress = section.virtual_address, + .size = section.virtual_size, + .data = view.sectionData_.back().data(), + .executable = section.executable}); + + REXCODEGEN_DEBUG("BinaryView: section '{}' at 0x{:08X} size 0x{:X} exec={}", section.name, + section.virtual_address, section.virtual_size, section.executable); + } + + REXCODEGEN_DEBUG("BinaryView: loaded {} sections, base=0x{:08X}, size=0x{:X}", + view.sections_.size(), view.baseAddress_, view.imageSize_); + + return view; +} + +const uint8_t* BinaryView::translate(uint32_t addr) const { + for (const auto& section : sections_) { + if (auto* ptr = section.translate(addr)) { + return ptr; + } + } + return nullptr; +} + +bool BinaryView::isExecutable(uint32_t addr) const { + if (auto* section = findSection(addr)) { + return section->executable; + } + return false; +} + +const SectionView* BinaryView::findSection(uint32_t addr) const { + for (const auto& section : sections_) { + if (section.contains(addr)) { + return §ion; + } + } + return nullptr; +} + +const SectionView* BinaryView::findSectionByName(std::string_view name) const { + for (const auto& section : sections_) { + if (section.name == name) { + return §ion; + } + } + return nullptr; +} + +} // namespace rex::codegen diff --git a/src/codegen/builders.h b/src/codegen/builders.h new file mode 100644 index 0000000..24894f2 --- /dev/null +++ b/src/codegen/builders.h @@ -0,0 +1,586 @@ +/** + * @file rexcodegen/internal/builders.h + * @brief Code builder interface definitions + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +namespace rex::codegen { + +struct BuilderContext; + +/** + * Build C++ code for a PPC instruction using the dispatch table. + * + * @param id The PPC instruction ID (PPC_INST_*) + * @param ctx The builder context + * @return true if instruction was handled, false if unknown + */ +bool DispatchInstruction(int id, BuilderContext& ctx); + +//============================================================================= +// Comparison Builders (CMP*, CMPL*) +//============================================================================= + +bool build_cmpd(BuilderContext& ctx); +bool build_cmpdi(BuilderContext& ctx); +bool build_cmpld(BuilderContext& ctx); +bool build_cmpldi(BuilderContext& ctx); +bool build_cmplw(BuilderContext& ctx); +bool build_cmplwi(BuilderContext& ctx); +bool build_cmpw(BuilderContext& ctx); +bool build_cmpwi(BuilderContext& ctx); + +//============================================================================= +// Arithmetic Builders (ADD, SUB, MUL, DIV, NEG) +//============================================================================= + +// Addition +bool build_add(BuilderContext& ctx); +bool build_addc(BuilderContext& ctx); +bool build_adde(BuilderContext& ctx); +bool build_addi(BuilderContext& ctx); +bool build_addic(BuilderContext& ctx); +bool build_addis(BuilderContext& ctx); +bool build_addme(BuilderContext& ctx); +bool build_addze(BuilderContext& ctx); + +// Division +bool build_divd(BuilderContext& ctx); +bool build_divdu(BuilderContext& ctx); +bool build_divw(BuilderContext& ctx); +bool build_divwu(BuilderContext& ctx); + +// Multiplication +bool build_mulhd(BuilderContext& ctx); +bool build_mulhdu(BuilderContext& ctx); +bool build_mulhw(BuilderContext& ctx); +bool build_mulhwu(BuilderContext& ctx); +bool build_mulld(BuilderContext& ctx); +bool build_mulli(BuilderContext& ctx); +bool build_mullw(BuilderContext& ctx); + +// Negation +bool build_neg(BuilderContext& ctx); + +// Subtraction +bool build_subf(BuilderContext& ctx); +bool build_subfc(BuilderContext& ctx); +bool build_subfe(BuilderContext& ctx); +bool build_subfic(BuilderContext& ctx); +bool build_subfme(BuilderContext& ctx); +bool build_subfze(BuilderContext& ctx); + +//============================================================================= +// Logical Builders (AND, OR, XOR, shifts, rotates, bit manipulation) +//============================================================================= + +// AND operations +bool build_and(BuilderContext& ctx); +bool build_andc(BuilderContext& ctx); +bool build_andi(BuilderContext& ctx); +bool build_andis(BuilderContext& ctx); + +// OR operations +bool build_nand(BuilderContext& ctx); +bool build_nor(BuilderContext& ctx); +bool build_not(BuilderContext& ctx); +bool build_or(BuilderContext& ctx); +bool build_orc(BuilderContext& ctx); +bool build_ori(BuilderContext& ctx); +bool build_oris(BuilderContext& ctx); + +// XOR operations +bool build_xor(BuilderContext& ctx); +bool build_xori(BuilderContext& ctx); +bool build_xoris(BuilderContext& ctx); + +// Conditional Register operations +bool build_crand(BuilderContext& ctx); +bool build_crandc(BuilderContext& ctx); +bool build_creqv(BuilderContext& ctx); +bool build_crnand(BuilderContext& ctx); +bool build_crnor(BuilderContext& ctx); +bool build_cror(BuilderContext& ctx); +bool build_crorc(BuilderContext& ctx); +bool build_crxor(BuilderContext& ctx); + +// Equivalence (XNOR) +bool build_eqv(BuilderContext& ctx); + +// Count leading zeros +bool build_cntlzd(BuilderContext& ctx); +bool build_cntlzw(BuilderContext& ctx); + +// Sign extension +bool build_extsb(BuilderContext& ctx); +bool build_extsh(BuilderContext& ctx); +bool build_extsw(BuilderContext& ctx); + +// Clear operations +bool build_clrlwi(BuilderContext& ctx); + +// Rotate left double word +bool build_rldcl(BuilderContext& ctx); +bool build_rldcr(BuilderContext& ctx); +bool build_rldic(BuilderContext& ctx); +bool build_rldicl(BuilderContext& ctx); +bool build_rldicr(BuilderContext& ctx); +bool build_rldimi(BuilderContext& ctx); +bool build_rotldi(BuilderContext& ctx); + +// Rotate left word +bool build_rlwimi(BuilderContext& ctx); +bool build_rlwinm(BuilderContext& ctx); +bool build_rlwnm(BuilderContext& ctx); +bool build_rotlw(BuilderContext& ctx); +bool build_rotlwi(BuilderContext& ctx); + +// Shift left +bool build_sld(BuilderContext& ctx); +bool build_slw(BuilderContext& ctx); + +// Shift right algebraic +bool build_srad(BuilderContext& ctx); +bool build_sradi(BuilderContext& ctx); +bool build_sraw(BuilderContext& ctx); +bool build_srawi(BuilderContext& ctx); + +// Shift right logical +bool build_srd(BuilderContext& ctx); +bool build_srw(BuilderContext& ctx); + +//============================================================================= +// Control Flow Builders (branches, calls, returns) +//============================================================================= + +// Unconditional branch +bool build_b(BuilderContext& ctx); +bool build_bl(BuilderContext& ctx); +bool build_blr(BuilderContext& ctx); +bool build_blrl(BuilderContext& ctx); + +// Count register branch +bool build_bctr(BuilderContext& ctx); +bool build_bctrl(BuilderContext& ctx); +bool build_bnectr(BuilderContext& ctx); + +// Decrement counter and branch +bool build_bdz(BuilderContext& ctx); +bool build_bdzf(BuilderContext& ctx); +bool build_bdzlr(BuilderContext& ctx); +bool build_bdnz(BuilderContext& ctx); +bool build_bdnzf(BuilderContext& ctx); +bool build_bdnzlr(BuilderContext& ctx); +bool build_bdnzt(BuilderContext& ctx); + +// Conditional branch (eq) +bool build_beq(BuilderContext& ctx); +bool build_beqlr(BuilderContext& ctx); +bool build_bne(BuilderContext& ctx); +bool build_bnelr(BuilderContext& ctx); + +// Conditional branch (lt) +bool build_blt(BuilderContext& ctx); +bool build_bltlr(BuilderContext& ctx); +bool build_bge(BuilderContext& ctx); +bool build_bgelr(BuilderContext& ctx); + +// Conditional branch (gt) +bool build_bgt(BuilderContext& ctx); +bool build_bgtlr(BuilderContext& ctx); +bool build_ble(BuilderContext& ctx); +bool build_blelr(BuilderContext& ctx); + +// Conditional branch (so - summary overflow / unordered) +bool build_bso(BuilderContext& ctx); +bool build_bsolr(BuilderContext& ctx); +bool build_bns(BuilderContext& ctx); +bool build_bnslr(BuilderContext& ctx); + +//============================================================================= +// Floating Point Builders +//============================================================================= + +// Sign manipulation +bool build_fabs(BuilderContext& ctx); +bool build_fnabs(BuilderContext& ctx); +bool build_fneg(BuilderContext& ctx); + +// Move and conversion +bool build_fmr(BuilderContext& ctx); +bool build_fcfid(BuilderContext& ctx); +bool build_fctid(BuilderContext& ctx); +bool build_fctidz(BuilderContext& ctx); +bool build_fctiw(BuilderContext& ctx); +bool build_fctiwz(BuilderContext& ctx); +bool build_frsp(BuilderContext& ctx); + +// Comparison +bool build_fcmpu(BuilderContext& ctx); +bool build_fcmpo(BuilderContext& ctx); + +// Addition +bool build_fadd(BuilderContext& ctx); +bool build_fadds(BuilderContext& ctx); + +// Subtraction +bool build_fsub(BuilderContext& ctx); +bool build_fsubs(BuilderContext& ctx); + +// Multiplication +bool build_fmul(BuilderContext& ctx); +bool build_fmuls(BuilderContext& ctx); + +// Division +bool build_fdiv(BuilderContext& ctx); +bool build_fdivs(BuilderContext& ctx); + +// Fused multiply-add +bool build_fmadd(BuilderContext& ctx); +bool build_fmadds(BuilderContext& ctx); +bool build_fmsub(BuilderContext& ctx); +bool build_fmsubs(BuilderContext& ctx); +bool build_fnmadd(BuilderContext& ctx); +bool build_fnmadds(BuilderContext& ctx); +bool build_fnmsub(BuilderContext& ctx); +bool build_fnmsubs(BuilderContext& ctx); + +// Reciprocal and square root +bool build_fres(BuilderContext& ctx); +bool build_frsqrte(BuilderContext& ctx); +bool build_fsqrt(BuilderContext& ctx); +bool build_fsqrts(BuilderContext& ctx); + +// Selection +bool build_fsel(BuilderContext& ctx); + +//============================================================================= +// Memory Builders (loads and stores) +//============================================================================= + +// Load immediate +bool build_li(BuilderContext& ctx); +bool build_lis(BuilderContext& ctx); + +// Byte loads +bool build_lbz(BuilderContext& ctx); +bool build_lbzu(BuilderContext& ctx); +bool build_lbzx(BuilderContext& ctx); +bool build_lbzux(BuilderContext& ctx); + +// Halfword loads +bool build_lha(BuilderContext& ctx); +bool build_lhau(BuilderContext& ctx); +bool build_lhaux(BuilderContext& ctx); +bool build_lhax(BuilderContext& ctx); +bool build_lhbrx(BuilderContext& ctx); +bool build_lhz(BuilderContext& ctx); +bool build_lhzu(BuilderContext& ctx); +bool build_lhzux(BuilderContext& ctx); +bool build_lhzx(BuilderContext& ctx); + +// Word loads +bool build_lwa(BuilderContext& ctx); +bool build_lwaux(BuilderContext& ctx); +bool build_lwax(BuilderContext& ctx); +bool build_lwbrx(BuilderContext& ctx); +bool build_lwz(BuilderContext& ctx); +bool build_lwzu(BuilderContext& ctx); +bool build_lwzux(BuilderContext& ctx); +bool build_lwzx(BuilderContext& ctx); + +// Doubleword loads +bool build_ld(BuilderContext& ctx); +bool build_ldu(BuilderContext& ctx); +bool build_ldx(BuilderContext& ctx); +bool build_ldux(BuilderContext& ctx); + +// Atomic load and reserve +bool build_lwarx(BuilderContext& ctx); +bool build_ldarx(BuilderContext& ctx); + +// Floating point loads +bool build_lfd(BuilderContext& ctx); +bool build_lfdu(BuilderContext& ctx); +bool build_lfdux(BuilderContext& ctx); +bool build_lfdx(BuilderContext& ctx); +bool build_lfs(BuilderContext& ctx); +bool build_lfsu(BuilderContext& ctx); +bool build_lfsux(BuilderContext& ctx); +bool build_lfsx(BuilderContext& ctx); + +// Byte stores +bool build_stb(BuilderContext& ctx); +bool build_stbu(BuilderContext& ctx); +bool build_stbx(BuilderContext& ctx); +bool build_stbux(BuilderContext& ctx); + +// Halfword stores +bool build_sth(BuilderContext& ctx); +bool build_sthbrx(BuilderContext& ctx); +bool build_sthu(BuilderContext& ctx); +bool build_sthux(BuilderContext& ctx); +bool build_sthx(BuilderContext& ctx); + +// Word stores +bool build_stw(BuilderContext& ctx); +bool build_stwu(BuilderContext& ctx); +bool build_stwux(BuilderContext& ctx); +bool build_stwx(BuilderContext& ctx); +bool build_stwbrx(BuilderContext& ctx); +bool build_stmw(BuilderContext& ctx); + +// Atomic store conditional +bool build_stwcx(BuilderContext& ctx); +bool build_stdcx(BuilderContext& ctx); + +// Doubleword stores +bool build_std(BuilderContext& ctx); +bool build_stdu(BuilderContext& ctx); +bool build_stdx(BuilderContext& ctx); +bool build_stdux(BuilderContext& ctx); + +// Floating point stores +bool build_stfd(BuilderContext& ctx); +bool build_stfdu(BuilderContext& ctx); +bool build_stfdux(BuilderContext& ctx); +bool build_stfdx(BuilderContext& ctx); +bool build_stfiwx(BuilderContext& ctx); +bool build_stfs(BuilderContext& ctx); +bool build_stfsu(BuilderContext& ctx); +bool build_stfsux(BuilderContext& ctx); +bool build_stfsx(BuilderContext& ctx); + +// Vector loads +bool build_lvx(BuilderContext& ctx); +bool build_lvlx(BuilderContext& ctx); +bool build_lvrx(BuilderContext& ctx); +bool build_lvsl(BuilderContext& ctx); +bool build_lvsr(BuilderContext& ctx); + +// Vector stores +bool build_stvebx(BuilderContext& ctx); +bool build_stvehx(BuilderContext& ctx); +bool build_stvewx(BuilderContext& ctx); +bool build_stvlx(BuilderContext& ctx); +bool build_stvrx(BuilderContext& ctx); +bool build_stvx(BuilderContext& ctx); + +//============================================================================= +// System Builders (NOP, SYNC, MF*, MT*, DC*, trap) +//============================================================================= + +// No-ops and sync +bool build_nop(BuilderContext& ctx); +bool build_attn(BuilderContext& ctx); +bool build_sync(BuilderContext& ctx); +bool build_lwsync(BuilderContext& ctx); +bool build_eieio(BuilderContext& ctx); +bool build_db16cyc(BuilderContext& ctx); +bool build_cctpl(BuilderContext& ctx); +bool build_cctpm(BuilderContext& ctx); +bool build_cctph(BuilderContext& ctx); + +// Trap instructions (generic builders - all specific variants map to these) +bool build_twi(BuilderContext& ctx); // Trap word immediate +bool build_tdi(BuilderContext& ctx); // Trap doubleword immediate +bool build_tw(BuilderContext& ctx); // Trap word register +bool build_td(BuilderContext& ctx); // Trap doubleword register + +// Cache operations +bool build_dcbf(BuilderContext& ctx); +bool build_dcbt(BuilderContext& ctx); +bool build_dcbtst(BuilderContext& ctx); +bool build_dcbz(BuilderContext& ctx); +bool build_dcbzl(BuilderContext& ctx); +bool build_dcbst(BuilderContext& ctx); + +// Move register +bool build_mr(BuilderContext& ctx); + +// Move register field +bool build_mcrf(BuilderContext& ctx); + +// Move from special registers +bool build_mfctr(BuilderContext& ctx); +bool build_mfcr(BuilderContext& ctx); +bool build_mfxer(BuilderContext& ctx); +bool build_mfocrf(BuilderContext& ctx); +bool build_mflr(BuilderContext& ctx); +bool build_mfmsr(BuilderContext& ctx); +bool build_mffs(BuilderContext& ctx); +bool build_mftb(BuilderContext& ctx); +bool build_mftbu(BuilderContext& ctx); + +// Move to special registers +bool build_mtcr(BuilderContext& ctx); +bool build_mtcrf(BuilderContext& ctx); +bool build_mtctr(BuilderContext& ctx); +bool build_mtlr(BuilderContext& ctx); +bool build_mtmsrd(BuilderContext& ctx); +bool build_mtfsf(BuilderContext& ctx); +bool build_mtxer(BuilderContext& ctx); + +// Clear left double word immediate +bool build_clrldi(BuilderContext& ctx); + +//============================================================================= +// Vector Builders (AltiVec/VMX instructions) +//============================================================================= + +// Vector floating point arithmetic +bool build_vaddfp(BuilderContext& ctx); +bool build_vsubfp(BuilderContext& ctx); +bool build_vmulfp128(BuilderContext& ctx); +bool build_vmaddfp(BuilderContext& ctx); +bool build_vnmsubfp(BuilderContext& ctx); +bool build_vmaxfp(BuilderContext& ctx); +bool build_vminfp(BuilderContext& ctx); +bool build_vrefp(BuilderContext& ctx); +bool build_vrsqrtefp(BuilderContext& ctx); +bool build_vexptefp(BuilderContext& ctx); +bool build_vlogefp(BuilderContext& ctx); + +// Vector dot products +bool build_vmsum3fp128(BuilderContext& ctx); +bool build_vmsum4fp128(BuilderContext& ctx); + +// Vector rounding +bool build_vrfim(BuilderContext& ctx); +bool build_vrfin(BuilderContext& ctx); +bool build_vrfip(BuilderContext& ctx); +bool build_vrfiz(BuilderContext& ctx); + +// Vector integer arithmetic +bool build_vaddsbs(BuilderContext& ctx); +bool build_vaddshs(BuilderContext& ctx); +bool build_vaddsws(BuilderContext& ctx); +bool build_vaddubm(BuilderContext& ctx); +bool build_vaddubs(BuilderContext& ctx); +bool build_vadduhm(BuilderContext& ctx); +bool build_vadduwm(BuilderContext& ctx); +bool build_vadduws(BuilderContext& ctx); +bool build_vadduhs(BuilderContext& ctx); +bool build_vsubsbs(BuilderContext& ctx); +bool build_vsubshs(BuilderContext& ctx); +bool build_vsubsws(BuilderContext& ctx); +bool build_vsububm(BuilderContext& ctx); +bool build_vsububs(BuilderContext& ctx); +bool build_vsubuws(BuilderContext& ctx); +bool build_vsubuhs(BuilderContext& ctx); +bool build_vsubuhm(BuilderContext& ctx); +bool build_vsubuwm(BuilderContext& ctx); +bool build_vmaxsh(BuilderContext& ctx); +bool build_vmaxsb(BuilderContext& ctx); +bool build_vmaxsw(BuilderContext& ctx); +bool build_vmaxuh(BuilderContext& ctx); +bool build_vminsh(BuilderContext& ctx); +bool build_vminsb(BuilderContext& ctx); +bool build_vminsw(BuilderContext& ctx); +bool build_vminuh(BuilderContext& ctx); +bool build_vminuw(BuilderContext& ctx); +bool build_vmaxub(BuilderContext& ctx); +bool build_vminub(BuilderContext& ctx); + +// Vector average +bool build_vavgsb(BuilderContext& ctx); +bool build_vavgsh(BuilderContext& ctx); +bool build_vavgsw(BuilderContext& ctx); +bool build_vavgub(BuilderContext& ctx); +bool build_vavguh(BuilderContext& ctx); + +// Vector logical +bool build_vand(BuilderContext& ctx); +bool build_vandc(BuilderContext& ctx); +bool build_vandc128(BuilderContext& ctx); +bool build_vor(BuilderContext& ctx); +bool build_vxor(BuilderContext& ctx); +bool build_vnor(BuilderContext& ctx); +bool build_vsel(BuilderContext& ctx); + +// Vector compare +bool build_vcmpbfp(BuilderContext& ctx); +bool build_vcmpeqfp(BuilderContext& ctx); +bool build_vcmpequb(BuilderContext& ctx); +bool build_vcmpequh(BuilderContext& ctx); +bool build_vcmpequw(BuilderContext& ctx); +bool build_vcmpgefp(BuilderContext& ctx); +bool build_vcmpgtfp(BuilderContext& ctx); +bool build_vcmpgtub(BuilderContext& ctx); +bool build_vcmpgtuh(BuilderContext& ctx); +bool build_vcmpgtuw(BuilderContext& ctx); +bool build_vcmpgtsb(BuilderContext& ctx); +bool build_vcmpgtsh(BuilderContext& ctx); +bool build_vcmpgtsw(BuilderContext& ctx); + +// Vector conversion +bool build_vctsxs(BuilderContext& ctx); +bool build_vctuxs(BuilderContext& ctx); +bool build_vcfsx(BuilderContext& ctx); +bool build_vcfux(BuilderContext& ctx); + +// Vector merge +bool build_vmrghb(BuilderContext& ctx); +bool build_vmrghh(BuilderContext& ctx); +bool build_vmrghw(BuilderContext& ctx); +bool build_vmrglb(BuilderContext& ctx); +bool build_vmrglh(BuilderContext& ctx); +bool build_vmrglw(BuilderContext& ctx); + +// Vector permute +bool build_vperm(BuilderContext& ctx); +bool build_vpermwi128(BuilderContext& ctx); +bool build_vrlimi128(BuilderContext& ctx); + +// Vector shift +bool build_vsl(BuilderContext& ctx); +bool build_vslb(BuilderContext& ctx); +bool build_vslh(BuilderContext& ctx); +bool build_vsldoi(BuilderContext& ctx); +bool build_vslw(BuilderContext& ctx); +bool build_vslo(BuilderContext& ctx); +bool build_vsr(BuilderContext& ctx); +bool build_vsrh(BuilderContext& ctx); +bool build_vsrb(BuilderContext& ctx); +bool build_vsrab(BuilderContext& ctx); +bool build_vsrah(BuilderContext& ctx); +bool build_vsraw(BuilderContext& ctx); +bool build_vsrw(BuilderContext& ctx); +bool build_vsro(BuilderContext& ctx); +bool build_vrlh(BuilderContext& ctx); +bool build_vrlw(BuilderContext& ctx); + +// Vector splat +bool build_vspltb(BuilderContext& ctx); +bool build_vsplth(BuilderContext& ctx); +bool build_vspltisb(BuilderContext& ctx); +bool build_vspltish(BuilderContext& ctx); +bool build_vspltisw(BuilderContext& ctx); +bool build_vspltw(BuilderContext& ctx); + +// Vector pack +bool build_vpkuhum(BuilderContext& ctx); +bool build_vpkuhus(BuilderContext& ctx); +bool build_vpkuwum(BuilderContext& ctx); +bool build_vpkuwus(BuilderContext& ctx); +bool build_vpkshss(BuilderContext& ctx); +bool build_vpkshus(BuilderContext& ctx); +bool build_vpkswss(BuilderContext& ctx); +bool build_vpkswus(BuilderContext& ctx); +bool build_vpkd3d128(BuilderContext& ctx); + +// Vector unpack +bool build_vupkd3d128(BuilderContext& ctx); +bool build_vupkhsb(BuilderContext& ctx); +bool build_vupkhsh(BuilderContext& ctx); +bool build_vupklsb(BuilderContext& ctx); +bool build_vupklsh(BuilderContext& ctx); + +} // namespace rex::codegen diff --git a/src/codegen/builders/arithmetic.cpp b/src/codegen/builders/arithmetic.cpp new file mode 100644 index 0000000..3908bdf --- /dev/null +++ b/src/codegen/builders/arithmetic.cpp @@ -0,0 +1,287 @@ +/** + * @file rexcodegen/builders/arithmetic.cpp + * @brief PPC arithmetic instruction code generation + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "builder_context.h" +#include "helpers.h" +namespace rex::codegen { + +//============================================================================= +// Addition +//============================================================================= + +bool build_add(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u64 + {}.u64;", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_adde(BuilderContext& ctx) { + ctx.println("\t{}.u8 = ({}.u32 + {}.u32 < {}.u32) | ({}.u32 + {}.u32 + {}.ca < {}.ca);", + ctx.temp(), ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2]), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2]), + ctx.xer(), ctx.xer()); + ctx.println("\t{}.u64 = {}.u64 + {}.u64 + {}.ca;", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2]), ctx.xer()); + ctx.println("\t{}.ca = {}.u8;", ctx.xer(), ctx.temp()); + emitRecordFormCompare(ctx); + return true; +} + +bool build_addi(BuilderContext& ctx) { + ctx.print("\t{}.s64 = ", ctx.r(ctx.insn.operands[0])); + if (ctx.insn.operands[1] != 0) + ctx.print("{}.s64 + ", ctx.r(ctx.insn.operands[1])); + ctx.println("{};", static_cast(ctx.insn.operands[2])); + return true; +} + +bool build_addic(BuilderContext& ctx) { + ctx.println("\t{}.ca = {}.u32 > {};", ctx.xer(), ctx.r(ctx.insn.operands[1]), + ~ctx.insn.operands[2]); + ctx.println("\t{}.s64 = {}.s64 + {};", ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), + static_cast(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_addis(BuilderContext& ctx) { + ctx.print("\t{}.s64 = ", ctx.r(ctx.insn.operands[0])); + if (ctx.insn.operands[1] != 0) + ctx.print("{}.s64 + ", ctx.r(ctx.insn.operands[1])); + ctx.println("{};", static_cast(ctx.insn.operands[2] << 16)); + return true; +} + +bool build_addze(BuilderContext& ctx) { + ctx.println("\t{}.s64 = {}.s64 + {}.ca;", ctx.temp(), ctx.r(ctx.insn.operands[1]), ctx.xer()); + ctx.println("\t{}.ca = {}.u32 < {}.u32;", ctx.xer(), ctx.temp(), ctx.r(ctx.insn.operands[1])); + ctx.println("\t{}.s64 = {}.s64;", ctx.r(ctx.insn.operands[0]), ctx.temp()); + emitRecordFormCompare(ctx); + return true; +} + +bool build_addme(BuilderContext& ctx) { + // addme: rD = rA + CA - 1 (which is rA + CA + 0xFFFFFFFFFFFFFFFF) + ctx.println("\t{}.u8 = ({}.u32 + 0xFFFFFFFFu < {}.u32) | ({}.u32 + 0xFFFFFFFFu + {}.ca < {}.ca);", + ctx.temp(), ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[1]), ctx.xer(), ctx.xer()); + ctx.println("\t{}.u64 = {}.u64 + {}.ca + 0xFFFFFFFFFFFFFFFFull;", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.xer()); + ctx.println("\t{}.ca = {}.u8;", ctx.xer(), ctx.temp()); + emitRecordFormCompare(ctx); + return true; +} + +bool build_addc(BuilderContext& ctx) { + // addc: rD = rA + rB, CA = carry out + ctx.println("\t{}.ca = {}.u32 + {}.u32 < {}.u32;", ctx.xer(), ctx.r(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2]), ctx.r(ctx.insn.operands[1])); + ctx.println("\t{}.u64 = {}.u64 + {}.u64;", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +//============================================================================= +// Division +//============================================================================= +// PPC division instructions do NOT trap on divide-by-zero - they produce undefined results. +// We generate safe division that returns 0 when the divisor is zero. + +bool build_divd(BuilderContext& ctx) { + // divd rD,rA,rB: rD = rA / rB (64-bit signed) + // Safe division: return 0 if divisor is zero or INT64_MIN / -1 (UB in C) + auto rD = ctx.r(ctx.insn.operands[0]); + auto rA = ctx.r(ctx.insn.operands[1]); + auto rB = ctx.r(ctx.insn.operands[2]); + ctx.println( + "\t{}.s64 = ({}.s64 && !({}.s64 == INT64_MIN && {}.s64 == -1)) ? {}.s64 / {}.s64 : 0;", rD, + rB, rA, rB, rA, rB); + emitRecordFormCompare(ctx); + return true; +} + +bool build_divdu(BuilderContext& ctx) { + // divdu rD,rA,rB: rD = rA / rB (64-bit unsigned) + // Safe division: return 0 if divisor is zero + auto rD = ctx.r(ctx.insn.operands[0]); + auto rA = ctx.r(ctx.insn.operands[1]); + auto rB = ctx.r(ctx.insn.operands[2]); + ctx.println("\t{}.u64 = {}.u64 ? {}.u64 / {}.u64 : 0;", rD, rB, rA, rB); + emitRecordFormCompare(ctx); + return true; +} + +bool build_divw(BuilderContext& ctx) { + // divw rD,rA,rB: rD = rA / rB (32-bit signed) + // Safe division: return 0 if divisor is zero or INT32_MIN / -1 (UB in C) + auto rD = ctx.r(ctx.insn.operands[0]); + auto rA = ctx.r(ctx.insn.operands[1]); + auto rB = ctx.r(ctx.insn.operands[2]); + ctx.println( + "\t{}.u64 = uint32_t(({}.s32 && !({}.s32 == INT32_MIN && {}.s32 == -1)) ? {}.s32 / {}.s32 : " + "0);", + rD, rB, rA, rB, rA, rB); + emitRecordFormCompare(ctx); + return true; +} + +bool build_divwu(BuilderContext& ctx) { + // divwu rD,rA,rB: rD = rA / rB (32-bit unsigned) + // Safe division: return 0 if divisor is zero + auto rD = ctx.r(ctx.insn.operands[0]); + auto rA = ctx.r(ctx.insn.operands[1]); + auto rB = ctx.r(ctx.insn.operands[2]); + ctx.println("\t{}.u64 = uint32_t({}.u32 ? {}.u32 / {}.u32 : 0);", rD, rB, rA, rB); + emitRecordFormCompare(ctx); + return true; +} + +//============================================================================= +// Multiplication +//============================================================================= + +bool build_mulhw(BuilderContext& ctx) { + ctx.println("\t{}.s64 = (int64_t({}.s32) * int64_t({}.s32)) >> 32;", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_mulhwu(BuilderContext& ctx) { + ctx.println("\t{}.u64 = (uint64_t({}.u32) * uint64_t({}.u32)) >> 32;", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_mulld(BuilderContext& ctx) { + // Use unsigned multiplication to avoid signed overflow UB (PPC wraps on overflow) + ctx.println("\t{}.s64 = static_cast({}.u64 * {}.u64);", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_mulli(BuilderContext& ctx) { + // Use unsigned multiplication to avoid signed overflow UB (PPC wraps on overflow) + ctx.println("\t{}.s64 = static_cast({}.u64 * static_cast({}));", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), + static_cast(ctx.insn.operands[2])); + return true; +} + +bool build_mullw(BuilderContext& ctx) { + ctx.println("\t{}.s64 = int64_t({}.s32) * int64_t({}.s32);", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_mulhd(BuilderContext& ctx) { + // mulhd: rD = high 64 bits of (rA * rB) (signed) + ctx.println( + "\t{}.s64 = static_cast((static_cast<__int128>(static_cast({}.s64)) * " + "static_cast<__int128>(static_cast({}.s64))) >> 64);", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_mulhdu(BuilderContext& ctx) { + // mulhdu: rD = high 64 bits of (rA * rB) (unsigned) + ctx.println( + "\t{}.u64 = static_cast((static_cast<__uint128_t>({}.u64) * " + "static_cast<__uint128_t>({}.u64)) >> 64);", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +//============================================================================= +// Negation +//============================================================================= + +bool build_neg(BuilderContext& ctx) { + // Use unsigned negation to avoid signed overflow UB when negating INT64_MIN + ctx.println("\t{}.s64 = static_cast(-{}.u64);", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1])); + emitRecordFormCompare(ctx); + return true; +} + +//============================================================================= +// Subtraction +//============================================================================= + +bool build_subf(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u64 - {}.u64;", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[2]), ctx.r(ctx.insn.operands[1])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_subfc(BuilderContext& ctx) { + ctx.println("\t{}.ca = {}.u32 >= {}.u32;", ctx.xer(), ctx.r(ctx.insn.operands[2]), + ctx.r(ctx.insn.operands[1])); + ctx.println("\t{}.u64 = {}.u64 - {}.u64;", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[2]), ctx.r(ctx.insn.operands[1])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_subfe(BuilderContext& ctx) { + ctx.println("\t{}.u8 = (~{}.u32 + {}.u32 < ~{}.u32) | (~{}.u32 + {}.u32 + {}.ca < {}.ca);", + ctx.temp(), ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2]), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2]), + ctx.xer(), ctx.xer()); + ctx.println("\t{}.u64 = ~{}.u64 + {}.u64 + {}.ca;", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2]), ctx.xer()); + ctx.println("\t{}.ca = {}.u8;", ctx.xer(), ctx.temp()); + emitRecordFormCompare(ctx); + return true; +} + +bool build_subfic(BuilderContext& ctx) { + ctx.println("\t{}.ca = {}.u32 <= {};", ctx.xer(), ctx.r(ctx.insn.operands[1]), + ctx.insn.operands[2]); + ctx.println("\t{}.u64 = static_cast({}) - {}.u64;", ctx.r(ctx.insn.operands[0]), + static_cast(ctx.insn.operands[2]), ctx.r(ctx.insn.operands[1])); + return true; +} + +bool build_subfze(BuilderContext& ctx) { + // subfze: rD = ~rA + CA (subtract from zero extended) + ctx.println("\t{}.u8 = ~{}.u32 + {}.ca < ~{}.u32;", ctx.temp(), ctx.r(ctx.insn.operands[1]), + ctx.xer(), ctx.r(ctx.insn.operands[1])); + ctx.println("\t{}.u64 = ~{}.u64 + {}.ca;", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.xer()); + ctx.println("\t{}.ca = {}.u8;", ctx.xer(), ctx.temp()); + emitRecordFormCompare(ctx); + return true; +} + +bool build_subfme(BuilderContext& ctx) { + // subfme: rD = ~rA + CA - 1 (subtract from minus one extended) + ctx.println( + "\t{}.u8 = (~{}.u32 + 0xFFFFFFFFu < ~{}.u32) | (~{}.u32 + 0xFFFFFFFFu + {}.ca < {}.ca);", + ctx.temp(), ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[1]), ctx.xer(), ctx.xer()); + ctx.println("\t{}.u64 = ~{}.u64 + {}.ca + 0xFFFFFFFFFFFFFFFFull;", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.xer()); + ctx.println("\t{}.ca = {}.u8;", ctx.xer(), ctx.temp()); + emitRecordFormCompare(ctx); + return true; +} + +} // namespace rex::codegen diff --git a/src/codegen/builders/builder_context.h b/src/codegen/builders/builder_context.h new file mode 100644 index 0000000..c9ac44e --- /dev/null +++ b/src/codegen/builders/builder_context.h @@ -0,0 +1,353 @@ +/** + * @file rex/codegen/builder_context.h + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include + +#include + +#include +#include + +struct ppc_insn; + +namespace rex::codegen { + +class FunctionNode; + +struct RecompilerLocalVariables { + bool ctr{}; + bool xer{}; + bool reserved{}; + bool cr[8]{}; + bool r[32]{}; + bool f[32]{}; + bool v[128]{}; + bool env{}; + bool temp{}; + bool v_temp{}; + bool ea{}; + + /// Tracks which GPRs contain MMIO base addresses (bit N = rN is MMIO base) + /// Set when lis loads a value with upper 16 bits >= 0x7F00 (address >= 0x7F000000) + /// or when oris sets upper bits >= 0xC800 (address >= 0xC8000000) + uint32_t mmio_base_regs{0}; + + void set_mmio_base(size_t reg) { + if (reg < 32) + mmio_base_regs |= (1u << reg); + } + void clear_mmio_base(size_t reg) { + if (reg < 32) + mmio_base_regs &= ~(1u << reg); + } + bool is_mmio_base(size_t reg) const { return reg < 32 && (mmio_base_regs & (1u << reg)); } +}; + +/** + * @brief CSR (Control/Status Register) flush mode state. + * + * Tracks the current MXCSR configuration for floating-point operations: + * - **Unknown**: Initial state or after function call. Next FP/VMX instruction + * will emit a conditional mode check. + * - **FPU**: Denormals preserved (flush-to-zero disabled). Used by scalar + * floating-point instructions (fadd, fmul, etc.) + * - **VMX**: Denormals flushed to zero. Used by vector floating-point + * instructions (vaddfp, vmaddfp, etc.) + */ +enum class CSRState { Unknown, FPU, VMX }; + +/** + * @brief Context passed to instruction builders during code generation. + */ +struct BuilderContext { + /// Raw output buffer for code generation + std::string& out; + + /// Emission context (binary, config, graph, resolver) + const EmitContext& emitCtx; + + /// The function currently being recompiled (FunctionNode from graph) + const FunctionNode& fn; + + /// The decoded instruction being processed (opcode, operands, disassembly) + const ppc_insn& insn; + + /// Address of the current instruction in guest memory + uint32_t base; + + /// Pointer to raw instruction data in the image + const uint32_t* data; + + /// Tracks which registers need local variable declarations + RecompilerLocalVariables& locals; + + /// Current CSR state for flush mode (FPU vs VMX) + CSRState& csrState; + + /// Pointer to active jump table for bctr dispatch, or nullptr + const JumpTable* activeJumpTable = nullptr; + + /// Get the recompiler configuration + const RecompilerConfig& config() const; + + /// Get the function graph (single source of truth for function info) + const FunctionGraph& graph() const; + + //========================================================================= + // Register Accessors + //========================================================================= + + /** + * @brief Get expression for general-purpose register access. + * @param index Register index (0-31) + * @return "rN" for local variables, "ctx.rN" for context access + */ + std::string r(size_t index); + + /** + * @brief Get expression for floating-point register access. + * @param index Register index (0-31) + * @return "fN" for local variables, "ctx.fN" for context access + */ + std::string f(size_t index); + + /** + * @brief Get expression for vector register access. + * @param index Register index (0-127, Xbox 360 extended VMX128) + * @return "vN" for local variables, "ctx.vN" for context access + */ + std::string v(size_t index); + + /** + * @brief Get expression for condition register field access. + * @param index CR field index (0-7) + * @return "crN" for local variables, "ctx.crN" for context access + */ + std::string cr(size_t index); + + /// Get expression for count register ("ctr" or "ctx.ctr") + const char* ctr(); + + /// Get expression for XER register ("xer" or "ctx.xer") + const char* xer(); + + /// Get expression for reservation register (used by lwarx/stwcx) + const char* reserved(); + + /// Get expression for scalar temporary variable (always "temp") + const char* temp(); + + /// Get expression for vector temporary variable (always "vTemp") + const char* v_temp(); + + /// Get expression for setjmp environment storage (always "env") + const char* env(); + + /// Get expression for effective address temporary (always "ea") + const char* ea(); + + //========================================================================= + // Output Helpers + //========================================================================= + + /** + * @brief Print formatted text to the output buffer (no newline). + * @tparam Args Format argument types (deduced) + * @param fmt Format string with {} placeholders + * @param args Values to substitute into placeholders + */ + template + void print(fmt::format_string fmt, Args&&... args) { + fmt::vformat_to(std::back_inserter(out), fmt.get(), fmt::make_format_args(args...)); + } + + /** + * @brief Print formatted text to output buffer with newline. + * @tparam Args Format argument types (deduced) + * @param fmt Format string with {} placeholders + * @param args Values to substitute into placeholders + */ + template + void println(fmt::format_string fmt, Args&&... args) { + fmt::vformat_to(std::back_inserter(out), fmt.get(), fmt::make_format_args(args...)); + out += '\n'; + } + + //========================================================================= + // Code Generation Helpers + //========================================================================= + + /** + * @brief Check if current D-form load/store targets MMIO address. + * + * Checks: next instruction is eieio, or operands[2] (base register) is MMIO base. + * + * @return true if this is an MMIO access + */ + bool mmio_check_d_form(); + + /** + * @brief Check if current X-form load/store targets MMIO address. + * + * Checks: next instruction is eieio, or operands[1]/operands[2] is MMIO base. + * + * @return true if this is an MMIO access + */ + bool mmio_check_x_form(); + + /** + * @brief Find pre-resolved call target for an instruction site. + * @param site Address of the call/branch instruction + * @return Pointer to CallTarget if found, nullptr otherwise + * + * Searches the FunctionNode's calls and tailCalls for a matching site. + */ + const CallTarget* findCallTarget(uint32_t site) const; + + /** + * @brief Emit C++ code for a function call. + * @param address Target function address + * + * Uses pre-resolved CallTarget from FunctionNode when available. + * Falls back to symbol lookup for backward compatibility. + * Handles special cases like setjmp/longjmp and __restgprlr_N functions. + */ + void emit_function_call(uint32_t address); + + /** + * @brief Emit C++ code for a conditional branch. + * @param not_ If true, invert the condition + * @param cond Condition field name ("eq", "lt", "gt") + * + * Emits either `goto loc_X` for intra-function branches or a function + * call for inter-function branches. + */ + void emit_conditional_branch(bool not_, std::string_view cond); + + /** + * @brief Emit CSR flush mode change if needed. + * @param enable true for VMX mode (flush-to-zero), false for FPU mode + */ + void emit_set_flush_mode(bool enable); + + /// Emit mid-asm hook if configured for current address + void emit_mid_asm_hook(); + + /// Check if mid-asm hook exists for current address + bool has_mid_asm_hook() const; + + /// Clear active jump table pointer (used after processing a switch) + void reset_switch_table() { activeJumpTable = nullptr; } + + //========================================================================= + // Vector (SIMD) Code Generation Helpers + //========================================================================= + + /** + * @brief Emit binary float vector operation: vD = op(vA, vB) + * @param simd_op The SIMDE function name (e.g., "add_ps", "sub_ps", "mul_ps") + * + * Emits: simde_mm_store_ps(vD.f32, simde_mm_OP(load(vA.f32), load(vB.f32))); + * Uses operands[0]=vD, operands[1]=vA, operands[2]=vB from current instruction. + */ + void emit_vec_fp_binary(const char* simd_op); + + /** + * @brief Emit unary float vector operation: vD = op(vA) + * @param simd_expr SIMDE expression for the operation (will be wrapped in store) + * + * Use when the operation is more complex than a single function call. + * Emits: simde_mm_store_ps(vD.f32, EXPR); + * Uses operands[0]=vD, operands[1]=vA from current instruction. + * Example: emit_vec_fp_unary_expr("simde_mm_sqrt_ps(simde_mm_load_ps({vA}.f32))") + */ + void emit_vec_fp_unary_expr(std::string_view simd_expr); + + /** + * @brief Emit binary integer vector operation: vD = op(vA, vB) + * @param simd_op The SIMDE function name (e.g., "add_epi16", "and_si128") + * @param element_type The vector element type suffix (e.g., "u8", "s16", "u32") + * + * Emits: simde_mm_store_si128((simde__m128i*)vD.TYPE, simde_mm_OP(load(vA), load(vB))); + * Uses operands[0]=vD, operands[1]=vA, operands[2]=vB from current instruction. + */ + void emit_vec_int_binary(const char* simd_op, const char* element_type); + + /** + * @brief Emit binary integer vector operation with swapped operands: vD = op(vB, vA) + * @param simd_op The SIMDE function name + * @param element_type The vector element type suffix + * + * Same as emit_vec_int_binary but swaps vA and vB order (useful for andnot, etc.) + */ + void emit_vec_int_binary_swapped(const char* simd_op, const char* element_type); + + /** + * @brief Emit variable shift: vD = rex::ppc::simde_mm_{shift_dir}_{element_type}(vA, vB & mask) + * @param shift_dir The shift direction ("sllv", "srlv", or "srav") + * @param element_type The SIMDE element type suffix ("epi16") + * @param mask_value Shift amount mask (e.g., 0xF for 16-bit) + * + * Uses the custom rex:: variable shift helpers (simde_mm_{sllv,srlv,srav}_epi16). + * Uses operands[0]=vD, operands[1]=vA, operands[2]=vB from current instruction. + */ + void emit_vec_var_shift(const char* shift_dir, const char* element_type, uint32_t mask_value); + + //========================================================================= + // Memory (Load/Store) Code Generation Helpers + //========================================================================= + + /** + * @brief Emit load with D-form addressing: rD = LOAD(rA + offset) + * @param load_macro The load macro name (e.g., "REX_LOAD_U8", "REX_LOAD_U32") + * @param dest_type The destination type suffix (e.g., "u64", "s64") + * @param check_mmio If true, uses mmio_load() to detect memory-mapped I/O + * + * Uses operands[0]=rD, operands[1]=offset (D), operands[2]=rA from current instruction. + * If rA (operands[2]) is 0, omits the base register addition. + */ + void emit_load_d_form(const char* load_macro, const char* dest_type, bool check_mmio = true); + + /** + * @brief Emit load with X-form addressing: rD = LOAD(rA + rB) + * @param load_macro The load macro name + * @param dest_type The destination type suffix + * @param check_mmio If true, uses mmio_load_x_form() to detect memory-mapped I/O + * + * Uses operands[0]=rD, operands[1]=rA, operands[2]=rB from current instruction. + * If rA (operands[1]) is 0, omits the first register addition. + */ + void emit_load_x_form(const char* load_macro, const char* dest_type, bool check_mmio = true); + + /** + * @brief Emit store with D-form addressing: STORE(rA + offset, rS) + * @param store_macro The store macro name (e.g., "REX_STORE_U8") + * @param src_type The source type suffix (e.g., "u8", "u32") + * @param check_mmio If true, uses mmio_store() to detect memory-mapped I/O + * + * Uses operands[0]=rS, operands[1]=offset (D), operands[2]=rA from current instruction. + */ + void emit_store_d_form(const char* store_macro, const char* src_type, bool check_mmio = true); + + /** + * @brief Emit store with X-form addressing: STORE(rA + rB, rS) + * @param store_macro The store macro name + * @param src_type The source type suffix + * @param check_mmio If true, uses mmio_store() to detect memory-mapped I/O + * + * Uses operands[0]=rS, operands[1]=rA, operands[2]=rB from current instruction. + */ + void emit_store_x_form(const char* store_macro, const char* src_type, bool check_mmio = true); +}; +} // namespace rex::codegen \ No newline at end of file diff --git a/src/codegen/builders/comparison.cpp b/src/codegen/builders/comparison.cpp new file mode 100644 index 0000000..0c3fd33 --- /dev/null +++ b/src/codegen/builders/comparison.cpp @@ -0,0 +1,73 @@ +/** + * @file rexcodegen/builders/comparison.cpp + * @brief PPC comparison instruction code generation + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "builder_context.h" +#include "helpers.h" + +namespace rex::codegen { + +//============================================================================= +// Signed 64-bit Comparisons +//============================================================================= + +bool build_cmpd(BuilderContext& ctx) { + emitCompareRegister(ctx, "int64_t", "s64"); + return true; +} + +bool build_cmpdi(BuilderContext& ctx) { + emitCompareImmediate(ctx, "int64_t", "s64", true); + return true; +} + +//============================================================================= +// Unsigned 64-bit Comparisons +//============================================================================= + +bool build_cmpld(BuilderContext& ctx) { + emitCompareRegister(ctx, "uint64_t", "u64"); + return true; +} + +bool build_cmpldi(BuilderContext& ctx) { + emitCompareImmediate(ctx, "uint64_t", "u64", false); + return true; +} + +//============================================================================= +// Unsigned 32-bit Comparisons +//============================================================================= + +bool build_cmplw(BuilderContext& ctx) { + emitCompareRegister(ctx, "uint32_t", "u32"); + return true; +} + +bool build_cmplwi(BuilderContext& ctx) { + emitCompareImmediate(ctx, "uint32_t", "u32", false); + return true; +} + +//============================================================================= +// Signed 32-bit Comparisons +//============================================================================= + +bool build_cmpw(BuilderContext& ctx) { + emitCompareRegister(ctx, "int32_t", "s32"); + return true; +} + +bool build_cmpwi(BuilderContext& ctx) { + emitCompareImmediate(ctx, "int32_t", "s32", true); + return true; +} + +} // namespace rex::codegen diff --git a/src/codegen/builders/context.cpp b/src/codegen/builders/context.cpp new file mode 100644 index 0000000..6eae29d --- /dev/null +++ b/src/codegen/builders/context.cpp @@ -0,0 +1,540 @@ +/** + * @file rexcodegen/builders/context.cpp + * @brief PPC context instruction code generation + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "builder_context.h" +#include "helpers.h" + +#include + +#include +#include + +#include "../codegen_logging.h" +#include + +namespace rex::codegen { + +/// eieio instruction encoding (big-endian). Used for MMIO detection: +/// if the next instruction after a load/store is eieio, the access is MMIO. +static constexpr uint32_t kEieioEncoding = 0xAC06007C; + +//============================================================================= +// Convenience Accessors +//============================================================================= + +const RecompilerConfig& BuilderContext::config() const { + return emitCtx.config; +} + +const FunctionGraph& BuilderContext::graph() const { + return emitCtx.graph; +} + +//============================================================================= +// Register Accessors +//============================================================================= + +std::string BuilderContext::r(size_t index) { + const auto& cfg = config(); + if ((cfg.nonArgumentRegistersAsLocalVariables && + (index == 0 || index == 2 || index == 11 || index == 12)) || + (cfg.nonVolatileRegistersAsLocalVariables && index >= 14)) { + locals.r[index] = true; + return fmt::format("r{}", index); + } + return fmt::format("ctx.r{}", index); +} + +std::string BuilderContext::f(size_t index) { + const auto& cfg = config(); + if ((cfg.nonArgumentRegistersAsLocalVariables && index == 0) || + (cfg.nonVolatileRegistersAsLocalVariables && index >= 14)) { + locals.f[index] = true; + return fmt::format("f{}", index); + } + return fmt::format("ctx.f{}", index); +} + +std::string BuilderContext::v(size_t index) { + const auto& cfg = config(); + if ((cfg.nonArgumentRegistersAsLocalVariables && (index >= 32 && index <= 63)) || + (cfg.nonVolatileRegistersAsLocalVariables && + ((index >= 14 && index <= 31) || (index >= 64 && index <= 127)))) { + locals.v[index] = true; + return fmt::format("v{}", index); + } + return fmt::format("ctx.v{}", index); +} + +std::string BuilderContext::cr(size_t index) { + if (config().crRegistersAsLocalVariables) { + locals.cr[index] = true; + return fmt::format("cr{}", index); + } + return fmt::format("ctx.cr{}", index); +} + +const char* BuilderContext::ctr() { + if (config().ctrAsLocalVariable) { + locals.ctr = true; + return "ctr"; + } + return "ctx.ctr"; +} + +const char* BuilderContext::xer() { + if (config().xerAsLocalVariable) { + locals.xer = true; + return "xer"; + } + return "ctx.xer"; +} + +const char* BuilderContext::reserved() { + if (config().reservedRegisterAsLocalVariable) { + locals.reserved = true; + return "reserved"; + } + return "ctx.reserved"; +} + +const char* BuilderContext::temp() { + locals.temp = true; + return "temp"; +} + +const char* BuilderContext::v_temp() { + locals.v_temp = true; + return "vTemp"; +} + +const char* BuilderContext::env() { + locals.env = true; + return "env"; +} + +const char* BuilderContext::ea() { + locals.ea = true; + return "ea"; +} + +//============================================================================= +// Output Helpers +//============================================================================= + +// Template implementations in header, but we need explicit instantiations +// for common format strings to avoid link errors in some cases + +//============================================================================= +// Code Generation Helpers +//============================================================================= + +bool BuilderContext::mmio_check_d_form() { + if (base + 4 < fn.end() && *(data + 1) == kEieioEncoding) + return true; + return locals.is_mmio_base(insn.operands[2]); +} + +bool BuilderContext::mmio_check_x_form() { + if (base + 4 < fn.end() && *(data + 1) == kEieioEncoding) + return true; + return locals.is_mmio_base(insn.operands[1]) || locals.is_mmio_base(insn.operands[2]); +} + +const CallTarget* BuilderContext::findCallTarget(uint32_t site) const { + // Search in calls (bl instructions) + for (const auto& edge : fn.calls()) { + if (edge.site == site) { + return &edge.target; + } + } + + // Search in tail calls (b instructions to other functions) + for (const auto& edge : fn.tailCalls()) { + if (edge.site == site) { + return &edge.target; + } + } + + return nullptr; +} + +void BuilderContext::emit_function_call(uint32_t address) { + const auto& cfg = config(); + + if (address == cfg.longJmpAddress) { + // Use custom ppc_longjmp that uses guest address as key (not for storage) + println("\tppc_longjmp({}.u32, {}.s32);", r(3), r(4)); + return; + } + + if (address == cfg.setJmpAddress) { + // Save PPCContext for restoration after longjmp + println("\t{} = ctx;", env()); + // Use custom ppc_setjmp that uses guest address as key + println("\t{}.s64 = ppc_setjmp({}.u32);", temp(), r(3)); + // Restore PPCContext if returning from longjmp + println("\tif ({}.s64 != 0) ctx = {};", temp(), env()); + println("\t{} = {};", r(3), temp()); + return; + } + + // Try to use pre-resolved call target from FunctionGraph + if (const auto* target = findCallTarget(base)) { + if (target->isFunction()) { + auto* targetFn = target->asFunction(); + const auto& name = targetFn->name(); + + // Handle save/restore helpers + if (cfg.nonVolatileRegistersAsLocalVariables && + (name.find("__rest") == 0 || name.find("__save") == 0)) { + // print nothing - these are handled by local variable tracking + return; + } + + println("\t{}(ctx, base);", name); + return; + } + + if (target->isImport()) { + const auto& importTarget = std::get(target->value); + std::string func_name; + + // Try to resolve ordinal to actual function name + auto at_pos = importTarget.name.find('@'); + if (at_pos != std::string::npos && emitCtx.resolver) { + auto lib_name = importTarget.name.substr(0, at_pos); + auto ordinal_str = importTarget.name.substr(at_pos + 1); + uint16_t ordinal = static_cast(std::stoul(ordinal_str)); + + auto* exp = emitCtx.resolver->GetExportByOrdinal(lib_name + ".xex", ordinal); + if (!exp) + exp = emitCtx.resolver->GetExportByOrdinal(lib_name, ordinal); + + if (exp) { + func_name = "__imp__" + std::string(exp->name); + } + } + + if (func_name.empty()) { + func_name = "__imp__" + importTarget.name; + std::replace(func_name.begin(), func_name.end(), '@', '_'); + std::replace(func_name.begin(), func_name.end(), '.', '_'); + } + + println("\t{}(ctx, base);", func_name); + return; + } + + // Unresolved target from graph + REXCODEGEN_ERROR("Unresolved function 0x{:08X} from 0x{:08X}", address, base); + println("\t// FATAL: unresolved function 0x{:08X}", address); + println("\tREX_FATAL(\"Unresolved call from 0x{:08X} to 0x{:08X}\");", base, address); + return; + } + + // No pre-resolved target found - this is an error + REXCODEGEN_ERROR("Unresolved function 0x{:08X} from 0x{:08X} (no CallTarget in FunctionNode)", + address, base); + println("\t// FATAL: unresolved function 0x{:08X} (no CallTarget in FunctionNode)", address); + println("\tREX_FATAL(\"Unresolved call from 0x{:08X} to 0x{:08X}\");", base, address); +} + +void BuilderContext::emit_conditional_branch(bool not_, std::string_view cond) { + uint32_t target = insn.operands[1]; + + // Use classifyTarget for consistent branch classification + // false = branch instruction (not a call), so own-base means loop back + auto kind = graph().classifyTarget(target, base, false); + + switch (kind) { + case TargetKind::InternalLabel: + // Target is within this function - local goto + println("\tif ({}{}.{}) goto loc_{:08X};", not_ ? "!" : "", cr(insn.operands[0]), cond, + target); + break; + + case TargetKind::Function: + case TargetKind::Import: + // Conditional tail call to another function - check pre-resolved call target + if (const auto* callTarget = findCallTarget(base)) { + if (callTarget->isFunction()) { + auto* targetFn = callTarget->asFunction(); + println("\tif ({}{}.{}) {{", not_ ? "!" : "", cr(insn.operands[0]), cond); + println("\t\t{}(ctx, base);", targetFn->name()); + println("\t\treturn;"); + println("\t}}"); + } else if (callTarget->isImport()) { + const auto& importTarget = std::get(callTarget->value); + std::string func_name = "__imp__" + importTarget.name; + std::replace(func_name.begin(), func_name.end(), '@', '_'); + std::replace(func_name.begin(), func_name.end(), '.', '_'); + println("\tif ({}{}.{}) {{", not_ ? "!" : "", cr(insn.operands[0]), cond); + println("\t\t{}(ctx, base);", func_name); + println("\t\treturn;"); + println("\t}}"); + } + } else { + REXCODEGEN_ERROR("Unresolved conditional branch to 0x{:08X} from 0x{:08X} (no CallTarget)", + target, base); + println("\tif ({}{}.{}) REX_FATAL(\"Unresolved branch from 0x{:08X} to 0x{:08X}\");", + not_ ? "!" : "", cr(insn.operands[0]), cond, base, target); + } + break; + + case TargetKind::Unknown: + REXCODEGEN_ERROR("Unresolved conditional branch to 0x{:08X} from 0x{:08X}", target, base); + println("\t// ERROR: conditional branch to unknown address 0x{:08X}", target); + println("\tif ({}{}.{}) REX_FATAL(\"Unresolved branch from 0x{:08X} to 0x{:08X}\");", + not_ ? "!" : "", cr(insn.operands[0]), cond, base, target); + break; + } +} + +void BuilderContext::emit_set_flush_mode(bool enable) { + auto newState = enable ? CSRState::VMX : CSRState::FPU; + if (csrState != newState) { + auto prefix = enable ? "enable" : "disable"; + auto suffix = csrState != CSRState::Unknown ? "Unconditional" : ""; + println("\tctx.fpscr.{}FlushMode{}();", prefix, suffix); + + csrState = newState; + } +} + +bool BuilderContext::has_mid_asm_hook() const { + return config().midAsmHooks.find(base) != config().midAsmHooks.end(); +} + +void BuilderContext::emit_mid_asm_hook() { + auto midAsmHook = config().midAsmHooks.find(base); + if (midAsmHook == config().midAsmHooks.end()) { + return; + } + + bool returnsBool = midAsmHook->second.returnOnFalse || midAsmHook->second.returnOnTrue || + midAsmHook->second.jumpAddressOnFalse != 0 || + midAsmHook->second.jumpAddressOnTrue != 0; + + print("\t"); + if (returnsBool) + print("if ("); + + // Build call -- no ctx/base prefix, just register arguments resolved through accessors + print("{}(", midAsmHook->second.name); + for (auto& reg : midAsmHook->second.registers) { + if (out.back() != '(') + out += ", "; + + switch (reg[0]) { + case 'c': + if (reg == "ctr") + out += ctr(); + else + out += cr(std::atoi(reg.c_str() + 2)); + break; + case 'x': + out += xer(); + break; + case 'r': + if (reg == "reserved") + out += reserved(); + else + out += r(std::atoi(reg.c_str() + 1)); + break; + case 'f': + if (reg == "fpscr") + out += "ctx.fpscr"; + else + out += f(std::atoi(reg.c_str() + 1)); + break; + case 'v': + out += v(std::atoi(reg.c_str() + 1)); + break; + } + } + + if (returnsBool) { + println(")) {{"); + + if (midAsmHook->second.returnOnTrue) + println("\t\treturn;"); + else if (midAsmHook->second.jumpAddressOnTrue != 0) + println("\t\tgoto loc_{:X};", midAsmHook->second.jumpAddressOnTrue); + + println("\t}}"); + + println("\telse {{"); + + if (midAsmHook->second.returnOnFalse) + println("\t\treturn;"); + else if (midAsmHook->second.jumpAddressOnFalse != 0) + println("\t\tgoto loc_{:X};", midAsmHook->second.jumpAddressOnFalse); + + println("\t}}"); + } else { + println(");"); + + if (midAsmHook->second.ret) + println("\treturn;"); + else if (midAsmHook->second.jumpAddress != 0) + println("\tgoto loc_{:X};", midAsmHook->second.jumpAddress); + } +} + +//============================================================================= +// Vector (SIMD) Code Generation Helpers +//============================================================================= + +void BuilderContext::emit_vec_fp_binary(const char* simd_op) { + println( + "\tsimde_mm_store_ps({}.f32, simde_mm_{}_ps(simde_mm_load_ps({}.f32), " + "simde_mm_load_ps({}.f32)));", + v(insn.operands[0]), simd_op, v(insn.operands[1]), v(insn.operands[2])); +} + +void BuilderContext::emit_vec_fp_unary_expr(std::string_view simd_expr) { + auto vD = v(insn.operands[0]); + auto vA = v(insn.operands[1]); + + // Replace {vA} placeholder in expression with actual register + std::string expr(simd_expr); + size_t pos; + while ((pos = expr.find("{vA}")) != std::string::npos) { + expr.replace(pos, 4, vA); + } + + println("\tsimde_mm_store_ps({}.f32, {});", vD, expr); +} + +void BuilderContext::emit_vec_int_binary(const char* simd_op, const char* element_type) { + println( + "\tsimde_mm_store_si128((simde__m128i*){}.{}, " + "simde_mm_{}(simde_mm_load_si128((simde__m128i*){}.{}), " + "simde_mm_load_si128((simde__m128i*){}.{})));", + v(insn.operands[0]), element_type, simd_op, v(insn.operands[1]), element_type, + v(insn.operands[2]), element_type); +} + +void BuilderContext::emit_vec_int_binary_swapped(const char* simd_op, const char* element_type) { + // Swapped: op(vB, vA) instead of op(vA, vB) - useful for andnot which has reversed operand + // semantics + println( + "\tsimde_mm_store_si128((simde__m128i*){}.{}, " + "simde_mm_{}(simde_mm_load_si128((simde__m128i*){}.{}), " + "simde_mm_load_si128((simde__m128i*){}.{})));", + v(insn.operands[0]), element_type, simd_op, v(insn.operands[2]), element_type, + v(insn.operands[1]), element_type); +} + +void BuilderContext::emit_vec_var_shift(const char* shift_dir, const char* element_type, + uint32_t mask_value) { + auto vD = v(insn.operands[0]); + auto vA = v(insn.operands[1]); + auto vB = v(insn.operands[2]); + println("\t{{"); + println("\t\tsimde__m128i a = simde_mm_load_si128((simde__m128i*){}.u8);", vA); + println("\t\tsimde__m128i b = simde_mm_load_si128((simde__m128i*){}.u8);", vB); + println("\t\tsimde__m128i shift = simde_mm_and_si128(b, simde_mm_set1_{}(0x{:X}));", element_type, + mask_value); + println( + "\t\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "rex::ppc::simde_mm_{}_{}" + "(a, shift));", + vD, shift_dir, element_type); + println("\t}}"); +} + +//============================================================================= +// Memory (Load/Store) Code Generation Helpers +//============================================================================= + +void BuilderContext::emit_load_d_form(const char* load_macro, const char* dest_type, + bool check_mmio) { + // D-form: rD = LOAD(rA + D) where operands[0]=rD, operands[1]=D, operands[2]=rA + // load_macro should be like "REX_LOAD_U8" - we replace REX_LOAD with REX_MM_LOAD for MMIO + const char* macro = load_macro; + static char mm_macro[64]; + if (check_mmio && mmio_check_d_form()) { + // Replace "REX_LOAD_" with "REX_MM_LOAD_" + if (strncmp(load_macro, "REX_LOAD_", 9) == 0) { + snprintf(mm_macro, sizeof(mm_macro), "REX_MM_LOAD_%s", load_macro + 9); + macro = mm_macro; + } + } + + print("\t{}.{} = {}(", r(insn.operands[0]), dest_type, macro); + if (insn.operands[2] != 0) + print("{}.u32 + ", r(insn.operands[2])); + println("{});", static_cast(insn.operands[1])); +} + +void BuilderContext::emit_load_x_form(const char* load_macro, const char* dest_type, + bool check_mmio) { + // X-form: rD = LOAD(rA + rB) where operands[0]=rD, operands[1]=rA, operands[2]=rB + // load_macro should be like "REX_LOAD_U8" - we replace REX_LOAD with REX_MM_LOAD for MMIO + const char* macro = load_macro; + static char mm_macro[64]; + if (check_mmio && mmio_check_x_form()) { + // Replace "REX_LOAD_" with "REX_MM_LOAD_" + if (strncmp(load_macro, "REX_LOAD_", 9) == 0) { + snprintf(mm_macro, sizeof(mm_macro), "REX_MM_LOAD_%s", load_macro + 9); + macro = mm_macro; + } + } + + print("\t{}.{} = {}(", r(insn.operands[0]), dest_type, macro); + if (insn.operands[1] != 0) + print("{}.u32 + ", r(insn.operands[1])); + println("{}.u32);", r(insn.operands[2])); +} + +void BuilderContext::emit_store_d_form(const char* store_macro, const char* src_type, + bool check_mmio) { + // D-form: STORE(rA + D, rS) where operands[0]=rS, operands[1]=D, operands[2]=rA + // store_macro should be like "REX_STORE_U8" - we replace REX_STORE with REX_MM_STORE for MMIO + const char* macro = store_macro; + static char mm_macro[64]; + if (check_mmio && mmio_check_d_form()) { + // Replace "REX_STORE_" with "REX_MM_STORE_" + if (strncmp(store_macro, "REX_STORE_", 10) == 0) { + snprintf(mm_macro, sizeof(mm_macro), "REX_MM_STORE_%s", store_macro + 10); + macro = mm_macro; + } + } + + print("\t{}(", macro); + if (insn.operands[2] != 0) + print("{}.u32 + ", r(insn.operands[2])); + println("{}, {}.{});", static_cast(insn.operands[1]), r(insn.operands[0]), src_type); +} + +void BuilderContext::emit_store_x_form(const char* store_macro, const char* src_type, + bool check_mmio) { + // X-form: STORE(rA + rB, rS) where operands[0]=rS, operands[1]=rA, operands[2]=rB + // store_macro should be like "REX_STORE_U8" - we replace REX_STORE with REX_MM_STORE for MMIO + const char* macro = store_macro; + static char mm_macro[64]; + if (check_mmio && mmio_check_x_form()) { // Use X-form specific check (operands[1] is base) + // Replace "REX_STORE_" with "REX_MM_STORE_" + if (strncmp(store_macro, "REX_STORE_", 10) == 0) { + snprintf(mm_macro, sizeof(mm_macro), "REX_MM_STORE_%s", store_macro + 10); + macro = mm_macro; + } + } + + print("\t{}(", macro); + if (insn.operands[1] != 0) + print("{}.u32 + ", r(insn.operands[1])); + println("{}.u32, {}.{});", r(insn.operands[2]), r(insn.operands[0]), src_type); +} + +} // namespace rex::codegen diff --git a/src/codegen/builders/control_flow.cpp b/src/codegen/builders/control_flow.cpp new file mode 100644 index 0000000..102a538 --- /dev/null +++ b/src/codegen/builders/control_flow.cpp @@ -0,0 +1,357 @@ +/** + * @file rexcodegen/builders/control_flow.cpp + * @brief PPC control flow instruction code generation + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "builder_context.h" +#include "helpers.h" + +#include + +#include + +#include "../codegen_logging.h" + +namespace rex::codegen { + +//============================================================================= +// Unconditional Branch +//============================================================================= + +bool build_b(BuilderContext& ctx) { + uint32_t target = ctx.insn.operands[0]; + + // Use graph to classify the target - handles thunks that branch to nearby functions + // false = branch instruction (not a call), so own-base means loop back + auto kind = ctx.graph().classifyTarget(target, ctx.base, false); + + switch (kind) { + case TargetKind::InternalLabel: + // Target is within this function and not another function's entry point + ctx.println("\tgoto loc_{:X};", target); + break; + + case TargetKind::Function: + case TargetKind::Import: + // Tail call to another function or import + ctx.emit_function_call(target); + ctx.println("\treturn;"); + break; + + case TargetKind::Unknown: + // Unknown target - fall back to range check + if (target >= ctx.fn.base() && target < ctx.fn.end()) { + ctx.println("\tgoto loc_{:X};", target); + } else { + REXCODEGEN_WARN("Unresolved b target 0x{:08X} from 0x{:08X}", target, ctx.base); + ctx.emit_function_call(target); + ctx.println("\treturn;"); + } + break; + } + return true; +} + +bool build_bl(BuilderContext& ctx) { + uint32_t target = ctx.insn.operands[0]; + + // Always set LR (unless skipLr) + if (!ctx.config().skipLr) + ctx.println("\tctx.lr = 0x{:X};", ctx.base + 4); + + // Use graph to classify the target + // true = call instruction, so own-base means recursive call (not loop back) + auto kind = ctx.graph().classifyTarget(target, ctx.base, true); + + switch (kind) { + case TargetKind::InternalLabel: + // PIC code pattern - bl to get PC into LR, treat as local jump + // LR is already set above, now jump to the target + ctx.println("\tgoto loc_{:X};", target); + break; + + case TargetKind::Function: + case TargetKind::Import: + ctx.emit_function_call(target); + ctx.csrState = CSRState::Unknown; // Call could change CSR state + break; + + case TargetKind::Unknown: + REXCODEGEN_ERROR("Unresolved bl target 0x{:08X} from 0x{:08X}", target, ctx.base); + ctx.println("\t// ERROR: unresolved bl target 0x{:08X}", target); + ctx.println("\tREX_FATAL(\"Unresolved call from 0x{:08X} to 0x{:08X}\");", ctx.base, target); + break; + } + return true; +} + +bool build_blr(BuilderContext& ctx) { + ctx.println("\treturn;"); + return true; +} + +bool build_blrl(BuilderContext& ctx) { + // BLRL: save return address, then branch-and-link to current LR + ctx.println("\t{{ auto old_lr = ctx.lr;"); + if (!ctx.config().skipLr) + ctx.println("\tctx.lr = 0x{:X};", ctx.base + 4); + ctx.println("\tREX_CALL_INDIRECT_FUNC(uint32_t(old_lr)); }}"); + ctx.csrState = CSRState::Unknown; + return true; +} + +//============================================================================= +// Count Register Branch +//============================================================================= + +bool build_bctr(BuilderContext& ctx) { + // Check active jump table (set by emitCpp before dispatch), then auto-detected + const JumpTable* jt = ctx.activeJumpTable; + + if (!jt) { + // Check auto-detected jump tables from function analysis + for (const auto& autoJt : ctx.fn.jumpTables()) { + if (autoJt.bctrAddress == ctx.base) { + jt = &autoJt; + break; + } + } + } + + if (jt) { + ctx.println("\tswitch ({}.u32) {{", ctx.r(jt->indexRegister)); + + for (size_t i = 0; i < jt->targets.size(); i++) { + ctx.println("\tcase {}:", i); + auto label = jt->targets[i]; + + // TODO(tomc): Figure out if this actually is triggered on real hardware and what would + // happen? + if (label == 0) { + ctx.println("\t\t__builtin_trap(); // ERROR - detected jump to null value"); + continue; + } + + auto kind = ctx.graph().classifyTarget(label, ctx.base, false); + switch (kind) { + case TargetKind::InternalLabel: + ctx.println("\t\tgoto loc_{:X};", label); + break; + case TargetKind::Function: + case TargetKind::Import: + if (auto* targetFn = ctx.graph().getFunction(label)) { + ctx.println("\t\t{}(ctx, base);", targetFn->name()); + } else { + REXCODEGEN_ERROR( + "Jump target 0x{:08X} classified as function but not in graph at bctr 0x{:08X}", + label, ctx.base); + ctx.println( + "\t\tREX_FATAL(\"Jump target 0x{:08X} classified as function but not " + "in graph at bctr 0x{:08X}\");", + label, ctx.base); + } + ctx.println("\t\treturn;"); + break; + default: + REXCODEGEN_ERROR("Jump target 0x{:08X} unresolved at bctr 0x{:08X}", label, ctx.base); + ctx.println("\t\tREX_FATAL(\"Jump target 0x{:08X} unresolved at bctr 0x{:08X}\");", label, + ctx.base); + break; + } + } + + ctx.println("\tdefault:"); + ctx.println("\t\t__builtin_trap(); // Switch case out of range"); + ctx.println("\t}}"); + + ctx.reset_switch_table(); + } else { + // No switch table - assume tail call via CTR + // NOTE(tomc): If this is actually an unresolved switch table, the code after + // will be unreachable. This is caught during analysis by discover_blocks. + // The validation phase will report missing switch tables. + ctx.println("\tREX_CALL_INDIRECT_FUNC({}.u32);", ctx.ctr()); + ctx.println("\treturn;"); + } + return true; +} + +bool build_bctrl(BuilderContext& ctx) { + if (!ctx.config().skipLr) + ctx.println("\tctx.lr = 0x{:X};", ctx.base + 4); + ctx.println("\tREX_CALL_INDIRECT_FUNC({}.u32);", ctx.ctr()); + ctx.csrState = CSRState::Unknown; // the call could change it + return true; +} + +bool build_bnectr(BuilderContext& ctx) { + ctx.println("\tif (!{}.eq) {{", ctx.cr(ctx.insn.operands[0])); + ctx.println("\t\tREX_CALL_INDIRECT_FUNC({}.u32);", ctx.ctr()); + ctx.println("\t\treturn;"); + ctx.println("\t}}"); + return true; +} + +//============================================================================= +// Decrement Counter and Branch +//============================================================================= + +bool build_bdz(BuilderContext& ctx) { + ctx.println("\t--{}.u64;", ctx.ctr()); + emitBranchWithBoundsCheck(ctx, ctx.insn.operands[0], fmt::format("{}.u32 == 0", ctx.ctr()), + "bdz"); + return true; +} + +bool build_bdzlr(BuilderContext& ctx) { + ctx.println("\t--{}.u64;", ctx.ctr()); + ctx.println("\tif ({}.u32 == 0) return;", ctx.ctr()); + return true; +} + +bool build_bdnzlr(BuilderContext& ctx) { + ctx.println("\t--{}.u64;", ctx.ctr()); + ctx.println("\tif ({}.u32 != 0) return;", ctx.ctr()); + return true; +} + +bool build_bdnz(BuilderContext& ctx) { + ctx.println("\t--{}.u64;", ctx.ctr()); + emitBranchWithBoundsCheck(ctx, ctx.insn.operands[0], fmt::format("{}.u32 != 0", ctx.ctr()), + "bdnz"); + return true; +} + +bool build_bdnzf(BuilderContext& ctx) { + auto bit = crBitName(ctx.insn.operands[0]); + ctx.println("\t--{}.u64;", ctx.ctr()); + emitBranchWithBoundsCheck( + ctx, ctx.insn.operands[1], + fmt::format("{}.u32 != 0 && !{}.{}", ctx.ctr(), ctx.cr(ctx.insn.operands[0] / 4), bit), + "bdnzf"); + return true; +} + +bool build_bdnzt(BuilderContext& ctx) { + auto bit = crBitName(ctx.insn.operands[0]); + ctx.println("\t--{}.u64;", ctx.ctr()); + emitBranchWithBoundsCheck( + ctx, ctx.insn.operands[1], + fmt::format("{}.u32 != 0 && {}.{}", ctx.ctr(), ctx.cr(ctx.insn.operands[0] / 4), bit), + "bdnzt"); + return true; +} + +bool build_bdzf(BuilderContext& ctx) { + auto bit = crBitName(ctx.insn.operands[0]); + ctx.println("\t--{}.u64;", ctx.ctr()); + emitBranchWithBoundsCheck( + ctx, ctx.insn.operands[1], + fmt::format("{}.u32 == 0 && !{}.{}", ctx.ctr(), ctx.cr(ctx.insn.operands[0] / 4), bit), + "bdzf"); + return true; +} + +//============================================================================= +// Conditional Branch (eq) +//============================================================================= + +bool build_beq(BuilderContext& ctx) { + ctx.emit_conditional_branch(false, "eq"); + return true; +} + +bool build_beqlr(BuilderContext& ctx) { + ctx.println("\tif ({}.eq) return;", ctx.cr(ctx.insn.operands[0])); + return true; +} + +bool build_bne(BuilderContext& ctx) { + ctx.emit_conditional_branch(true, "eq"); + return true; +} + +bool build_bnelr(BuilderContext& ctx) { + ctx.println("\tif (!{}.eq) return;", ctx.cr(ctx.insn.operands[0])); + return true; +} + +//============================================================================= +// Conditional Branch (lt) +//============================================================================= + +bool build_blt(BuilderContext& ctx) { + ctx.emit_conditional_branch(false, "lt"); + return true; +} + +bool build_bltlr(BuilderContext& ctx) { + ctx.println("\tif ({}.lt) return;", ctx.cr(ctx.insn.operands[0])); + return true; +} + +bool build_bge(BuilderContext& ctx) { + ctx.emit_conditional_branch(true, "lt"); + return true; +} + +bool build_bgelr(BuilderContext& ctx) { + ctx.println("\tif (!{}.lt) return;", ctx.cr(ctx.insn.operands[0])); + return true; +} + +//============================================================================= +// Conditional Branch (gt) +//============================================================================= + +bool build_bgt(BuilderContext& ctx) { + ctx.emit_conditional_branch(false, "gt"); + return true; +} + +bool build_bgtlr(BuilderContext& ctx) { + ctx.println("\tif ({}.gt) return;", ctx.cr(ctx.insn.operands[0])); + return true; +} + +bool build_ble(BuilderContext& ctx) { + ctx.emit_conditional_branch(true, "gt"); + return true; +} + +bool build_blelr(BuilderContext& ctx) { + ctx.println("\tif (!{}.gt) return;", ctx.cr(ctx.insn.operands[0])); + return true; +} + +//============================================================================= +// Conditional Branch (so - summary overflow / unordered) +//============================================================================= + +bool build_bso(BuilderContext& ctx) { + ctx.emit_conditional_branch(false, "so"); + return true; +} + +bool build_bsolr(BuilderContext& ctx) { + ctx.println("\tif ({}.so) return;", ctx.cr(ctx.insn.operands[0])); + return true; +} + +bool build_bns(BuilderContext& ctx) { + ctx.emit_conditional_branch(true, "so"); + return true; +} + +bool build_bnslr(BuilderContext& ctx) { + ctx.println("\tif (!{}.so) return;", ctx.cr(ctx.insn.operands[0])); + return true; +} + +} // namespace rex::codegen diff --git a/src/codegen/builders/floating_point.cpp b/src/codegen/builders/floating_point.cpp new file mode 100644 index 0000000..8f446d2 --- /dev/null +++ b/src/codegen/builders/floating_point.cpp @@ -0,0 +1,307 @@ +/** + * @file rexcodegen/builders/floating_point.cpp + * @brief PPC floating point instruction code generation + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "builder_context.h" +#include "helpers.h" + +namespace rex::codegen { + +//============================================================================= +// Sign Manipulation +//============================================================================= + +bool build_fabs(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.u64 = {}.u64 & ~0x8000000000000000;", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1])); + return true; +} + +bool build_fnabs(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.u64 = {}.u64 | 0x8000000000000000;", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1])); + return true; +} + +bool build_fneg(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.u64 = {}.u64 ^ 0x8000000000000000;", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1])); + return true; +} + +//============================================================================= +// Move and Conversion +//============================================================================= + +bool build_fmr(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = {}.f64;", ctx.f(ctx.insn.operands[0]), ctx.f(ctx.insn.operands[1])); + return true; +} + +bool build_fcfid(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = double({}.s64);", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1])); + return true; +} + +bool build_fctid(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println( + "\t{0}.s64 = std::isnan({1}.f64) ? int64_t(0x8000000000000000ULL) : " + "({1}.f64 > double(LLONG_MAX)) ? LLONG_MAX : " + "simde_mm_cvtsd_si64(simde_mm_load_sd(&{1}.f64));", + ctx.f(ctx.insn.operands[0]), ctx.f(ctx.insn.operands[1])); + return true; +} + +bool build_fctidz(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println( + "\t{0}.s64 = std::isnan({1}.f64) ? int64_t(0x8000000000000000ULL) : " + "({1}.f64 > double(LLONG_MAX)) ? LLONG_MAX : " + "simde_mm_cvttsd_si64(simde_mm_load_sd(&{1}.f64));", + ctx.f(ctx.insn.operands[0]), ctx.f(ctx.insn.operands[1])); + return true; +} + +bool build_fctiw(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println( + "\t{0}.s64 = std::isnan({1}.f64) ? int64_t(0x80000000U) : " + "({1}.f64 > double(INT_MAX)) ? INT_MAX : " + "simde_mm_cvtsd_si32(simde_mm_load_sd(&{1}.f64));", + ctx.f(ctx.insn.operands[0]), ctx.f(ctx.insn.operands[1])); + return true; +} + +bool build_fctiwz(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println( + "\t{0}.s64 = std::isnan({1}.f64) ? int64_t(0x80000000U) : " + "({1}.f64 > double(INT_MAX)) ? INT_MAX : " + "simde_mm_cvttsd_si32(simde_mm_load_sd(&{1}.f64));", + ctx.f(ctx.insn.operands[0]), ctx.f(ctx.insn.operands[1])); + return true; +} + +bool build_frsp(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = double(float({}.f64));", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1])); + return true; +} + +//============================================================================= +// Comparison +//============================================================================= + +bool build_fcmpu(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.compare({}.f64, {}.f64);", ctx.cr(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1]), ctx.f(ctx.insn.operands[2])); + return true; +} + +bool build_fcmpo(BuilderContext& ctx) { + // fcmpo is identical to fcmpu for recompilation purposes. + // The difference is that fcmpo sets FPSCR exception flags for SNaN operands, + // which we don't need to emulate. + return build_fcmpu(ctx); +} + +//============================================================================= +// Addition +//============================================================================= + +bool build_fadd(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = {}.f64 + {}.f64;", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1]), ctx.f(ctx.insn.operands[2])); + return true; +} + +bool build_fadds(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = double(float({}.f64 + {}.f64));", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1]), ctx.f(ctx.insn.operands[2])); + return true; +} + +//============================================================================= +// Subtraction +//============================================================================= + +bool build_fsub(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = {}.f64 - {}.f64;", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1]), ctx.f(ctx.insn.operands[2])); + return true; +} + +bool build_fsubs(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = double(float({}.f64 - {}.f64));", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1]), ctx.f(ctx.insn.operands[2])); + return true; +} + +//============================================================================= +// Multiplication +//============================================================================= + +bool build_fmul(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = {}.f64 * {}.f64;", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1]), ctx.f(ctx.insn.operands[2])); + return true; +} + +bool build_fmuls(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = double(float({}.f64 * {}.f64));", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1]), ctx.f(ctx.insn.operands[2])); + return true; +} + +//============================================================================= +// Division +//============================================================================= + +bool build_fdiv(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = {}.f64 / {}.f64;", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1]), ctx.f(ctx.insn.operands[2])); + return true; +} + +bool build_fdivs(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = double(float({}.f64 / {}.f64));", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1]), ctx.f(ctx.insn.operands[2])); + return true; +} + +//============================================================================= +// Fused Multiply-Add +//============================================================================= + +bool build_fmadd(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = std::fma({}.f64, {}.f64, {}.f64);", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1]), ctx.f(ctx.insn.operands[2]), + ctx.f(ctx.insn.operands[3])); + return true; +} + +bool build_fmadds(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = double(float(std::fma({}.f64, {}.f64, {}.f64)));", + ctx.f(ctx.insn.operands[0]), ctx.f(ctx.insn.operands[1]), ctx.f(ctx.insn.operands[2]), + ctx.f(ctx.insn.operands[3])); + return true; +} + +bool build_fmsub(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = std::fma({}.f64, {}.f64, -{}.f64);", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1]), ctx.f(ctx.insn.operands[2]), + ctx.f(ctx.insn.operands[3])); + return true; +} + +bool build_fmsubs(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = double(float(std::fma({}.f64, {}.f64, -{}.f64)));", + ctx.f(ctx.insn.operands[0]), ctx.f(ctx.insn.operands[1]), ctx.f(ctx.insn.operands[2]), + ctx.f(ctx.insn.operands[3])); + return true; +} + +bool build_fnmadd(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = -std::fma({}.f64, {}.f64, {}.f64);", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1]), ctx.f(ctx.insn.operands[2]), + ctx.f(ctx.insn.operands[3])); + return true; +} + +bool build_fnmadds(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = double(float(-std::fma({}.f64, {}.f64, {}.f64)));", + ctx.f(ctx.insn.operands[0]), ctx.f(ctx.insn.operands[1]), ctx.f(ctx.insn.operands[2]), + ctx.f(ctx.insn.operands[3])); + return true; +} + +bool build_fnmsub(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = -std::fma({}.f64, {}.f64, -{}.f64);", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1]), ctx.f(ctx.insn.operands[2]), + ctx.f(ctx.insn.operands[3])); + return true; +} + +bool build_fnmsubs(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = double(float(-std::fma({}.f64, {}.f64, -{}.f64)));", + ctx.f(ctx.insn.operands[0]), ctx.f(ctx.insn.operands[1]), ctx.f(ctx.insn.operands[2]), + ctx.f(ctx.insn.operands[3])); + return true; +} + +//============================================================================= +// Reciprocal and Square Root +//============================================================================= + +bool build_fres(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = double(float(1.0 / {}.f64));", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1])); + return true; +} + +bool build_frsqrte(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = double(float(1.0 / sqrt({}.f64)));", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1])); + return true; +} + +bool build_fsqrt(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = sqrt({}.f64);", ctx.f(ctx.insn.operands[0]), ctx.f(ctx.insn.operands[1])); + return true; +} + +bool build_fsqrts(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = double(float(sqrt({}.f64)));", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1])); + return true; +} + +//============================================================================= +// Selection +//============================================================================= + +bool build_fsel(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f64 = {}.f64 >= 0.0 ? {}.f64 : {}.f64;", ctx.f(ctx.insn.operands[0]), + ctx.f(ctx.insn.operands[1]), ctx.f(ctx.insn.operands[2]), + ctx.f(ctx.insn.operands[3])); + return true; +} + +} // namespace rex::codegen diff --git a/src/codegen/builders/helpers.h b/src/codegen/builders/helpers.h new file mode 100644 index 0000000..dbc8d51 --- /dev/null +++ b/src/codegen/builders/helpers.h @@ -0,0 +1,483 @@ +/** + * @file rexcodegen/internal/helpers.h + * @brief Recompiler helper utilities + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include "builder_context.h" + +#include + +#include +#include + +#include "../codegen_logging.h" + +#include +#include + +namespace rex::codegen { + +/** + * Compute a 64-bit mask for PPC rotate/mask instructions. + * @param mstart Starting bit position (0-63) + * @param mstop Ending bit position (0-63) + * @return 64-bit mask with bits set between mstart and mstop + */ +inline uint64_t compute_mask(uint32_t mstart, uint32_t mstop) { + mstart &= 0x3F; + mstop &= 0x3F; + uint64_t value = (UINT64_MAX >> mstart) ^ ((mstop >= 63) ? 0 : UINT64_MAX >> (mstop + 1)); + return mstart <= mstop ? value : ~value; +} + +//============================================================================= +// CR Bit Helpers +//============================================================================= + +/// Map PPC BI field bit index (0-3) to CRRegister member name. +inline const char* crBitName(uint32_t bi) { + static constexpr const char* names[] = {"lt", "gt", "eq", "so"}; + return names[bi & 3]; +} + +//============================================================================= +// Record-Form Helpers +//============================================================================= + +/** + * Check if the current instruction is a record form (has '.' suffix). + * + * Record-form instructions update CR0 based on the result. + * + * @param insn The ppc_insn being processed + * @return true if the instruction name contains '.' (record form) + */ +inline bool isRecordForm(const ppc_insn& insn) { + return std::strchr(insn.opcode->name, '.') != nullptr; +} + +/** + * Emit CR0 comparison for record-form instructions. + * + * Record-form instructions (those with '.' suffix like add., and., etc.) + * update CR0 based on the result compared to zero: + * CR0[LT] = result < 0 + * CR0[GT] = result > 0 + * CR0[EQ] = result == 0 + * CR0[SO] = XER[SO] + * + * @param ctx The builder context containing the instruction being processed + */ +inline void emitRecordFormCompare(BuilderContext& ctx) { + if (isRecordForm(ctx.insn)) { + ctx.println("\t{}.compare({}.s32, 0, {});", ctx.cr(0), ctx.r(ctx.insn.operands[0]), + ctx.xer()); + } +} + +/** + * Emit a CR bit operation: crD = crA crB + * + * CR bit operations work on individual CR bits (0-31). This helper: + * - Maps bit indices to CR field (0-7) and field bit (0-3) + * - Emits code to access CR fields by bit name + * + * @param ctx The builder context + * @param op The operation symbol as a string (e.g., "|", "&", "^") + * @param invertA If true, invert the value of crA before the operation + * @param invertB If true, invert the value of crB before the operation + * @param invertResult If true, invert the final result before storing in crD + */ +inline void emitCRBitOperation(BuilderContext& ctx, std::string_view op, bool invertA = false, + bool invertB = false, bool invertResult = false) { + uint32_t crD = ctx.insn.operands[0]; + uint32_t crA = ctx.insn.operands[1]; + uint32_t crB = ctx.insn.operands[2]; + + uint32_t crField_D = crD / 4; + uint32_t crBit_D = crD % 4; + uint32_t crField_A = crA / 4; + uint32_t crBit_A = crA % 4; + uint32_t crField_B = crB / 4; + uint32_t crBit_B = crB % 4; + + std::string aExpr = fmt::format("{}.{}", ctx.cr(crField_A), crBitName(crBit_A)); + + std::string bExpr = fmt::format("{}.{}", ctx.cr(crField_B), crBitName(crBit_B)); + + if (invertA) + aExpr = "!(" + aExpr + ")"; + if (invertB) + bExpr = "!(" + bExpr + ")"; + + std::string expr = fmt::format("{} {} {}", aExpr, op, bExpr); + + if (invertResult) + expr = "!(" + expr + ")"; + + ctx.println("\t{}.{} = {};", ctx.cr(crField_D), crBitName(crBit_D), expr); +} + +//============================================================================= +// Comparison Instruction Helpers +//============================================================================= + +/** + * Emit register-to-register comparison. + * + * Pattern: crD.compare(rA.field, rB.field, XER) + * Used by: cmpd, cmpld, cmplw, cmpw + * + * @param ctx The builder context + * @param type_name The comparison type (e.g., "int64_t", "uint32_t") + * @param field The register field accessor (e.g., "s64", "u32") + */ +inline void emitCompareRegister(BuilderContext& ctx, const char* type_name, const char* field) { + ctx.println("\t{}.compare<{}>({}.{}, {}.{}, {});", ctx.cr(ctx.insn.operands[0]), type_name, + ctx.r(ctx.insn.operands[1]), field, ctx.r(ctx.insn.operands[2]), field, ctx.xer()); +} + +/** + * Emit register-to-immediate comparison. + * + * Pattern: crD.compare(rA.field, imm, XER) + * Used by: cmpdi, cmpldi, cmplwi, cmpwi + * + * @param ctx The builder context + * @param type_name The comparison type (e.g., "int64_t", "uint32_t") + * @param field The register field accessor (e.g., "s64", "u32") + * @param sign_extend If true, sign-extend the immediate via static_cast + */ +inline void emitCompareImmediate(BuilderContext& ctx, const char* type_name, const char* field, + bool sign_extend) { + if (sign_extend) { + ctx.println("\t{}.compare<{}>({}.{}, {}, {});", ctx.cr(ctx.insn.operands[0]), type_name, + ctx.r(ctx.insn.operands[1]), field, static_cast(ctx.insn.operands[2]), + ctx.xer()); + } else { + ctx.println("\t{}.compare<{}>({}.{}, {}, {});", ctx.cr(ctx.insn.operands[0]), type_name, + ctx.r(ctx.insn.operands[1]), field, ctx.insn.operands[2], ctx.xer()); + } +} + +//============================================================================= +// Memory Operation Helpers +//============================================================================= + +/** + * Emit D-form load with update instruction. + * + * Pattern: EA = (rA) + d; rD = MEM[EA]; rA = EA + * Used by: lbzu, lwzu, ldu, etc. + * + * @param ctx The builder context + * @param load_macro The REX_LOAD_* macro to use (e.g., "REX_LOAD_U8") + */ +inline void emitLoadWithUpdate(BuilderContext& ctx, const char* load_macro) { + // EA = displacement + rA + ctx.println("\t{} = {} + {}.u32;", ctx.ea(), static_cast(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + // rD = MEM[EA] + ctx.println("\t{}.u64 = {}({});", ctx.r(ctx.insn.operands[0]), load_macro, ctx.ea()); + // rA = EA (update) + ctx.println("\t{}.u32 = {};", ctx.r(ctx.insn.operands[2]), ctx.ea()); +} + +/** + * Emit X-form load with update instruction. + * + * Pattern: EA = rA + rB; rD = MEM[EA]; rA = EA + * Used by: lbzux, lhzux, lwzux, ldux + * + * @param ctx The builder context + * @param load_macro The REX_LOAD_* macro to use (e.g., "REX_LOAD_U8") + */ +inline void emitLoadXFormWithUpdate(BuilderContext& ctx, const char* load_macro) { + ctx.println("\t{} = {}.u32 + {}.u32;", ctx.ea(), ctx.r(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + ctx.println("\t{}.u64 = {}({});", ctx.r(ctx.insn.operands[0]), load_macro, ctx.ea()); + ctx.println("\t{}.u32 = {};", ctx.r(ctx.insn.operands[1]), ctx.ea()); +} + +/** + * Emit D-form store with update instruction. + * + * Pattern: EA = (rA) + d; MEM[EA] = rS; rA = EA + * Used by: stbu, stwu, stdu, etc. + * + * @param ctx The builder context + * @param store_macro The REX_STORE_* macro to use (e.g., "REX_STORE_U8") + * @param field The register field to store (e.g., "u8", "u32", "u64") + */ +inline void emitStoreWithUpdate(BuilderContext& ctx, const char* store_macro, const char* field) { + // EA = displacement + rA + ctx.println("\t{} = {} + {}.u32;", ctx.ea(), static_cast(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + // MEM[EA] = rS + ctx.println("\t{}({}, {}.{});", store_macro, ctx.ea(), ctx.r(ctx.insn.operands[0]), field); + // rA = EA (update) + ctx.println("\t{}.u32 = {};", ctx.r(ctx.insn.operands[2]), ctx.ea()); +} + +/** + * Emit X-form store with update instruction. + * + * Pattern: EA = rA + rB; MEM[EA] = rS; rA = EA + * Used by: stbux, sthux, stwux, stdux + * + * @param ctx The builder context + * @param store_macro The REX_STORE_* normal macro (e.g., "REX_STORE_U8") + * @param mmio_macro The REX_MM_STORE_* MMIO macro (e.g., "REX_MM_STORE_U8") + * @param field The register field to store (e.g., "u8", "u32", "u64") + */ +inline void emitStoreXFormWithUpdate(BuilderContext& ctx, const char* store_macro, + const char* mmio_macro, const char* field) { + ctx.println("\t{} = {}.u32 + {}.u32;", ctx.ea(), ctx.r(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + ctx.println("\t{}({}, {}.{});", ctx.mmio_check_x_form() ? mmio_macro : store_macro, ctx.ea(), + ctx.r(ctx.insn.operands[0]), field); + ctx.println("\t{}.u32 = {};", ctx.r(ctx.insn.operands[1]), ctx.ea()); +} + +/** + * Get the appropriate store macro based on MMIO context. + * + * @param ctx The builder context + * @param normal_macro Normal store macro (e.g., "REX_STORE_U32") + * @param mmio_macro MMIO store macro (e.g., "REX_MM_STORE_U32") + * @return The appropriate macro string + */ +inline const char* getStoreMacro(BuilderContext& ctx, const char* normal_macro, + const char* mmio_macro) { + return ctx.mmio_check_d_form() ? mmio_macro : normal_macro; +} + +//============================================================================= +// Atomic Operation Helpers +//============================================================================= + +/** + * Emit atomic load-and-reserve instruction (lwarx/ldarx pattern). + * + * Pattern: EA = rA + rB; reserved = *(T*)REX_RAW_ADDR(EA); rD = bswap(reserved) + * + * @param ctx The builder context + * @param ptr_type The pointer type (e.g., "uint32_t", "uint64_t") + * @param bswap_func The byte-swap builtin (e.g., "__builtin_bswap32") + * @param reserved_field The reserved register field (e.g., "u32", "u64") + */ +inline void emitAtomicLoadReserve(BuilderContext& ctx, const char* ptr_type, const char* bswap_func, + const char* reserved_field) { + ctx.print("\t{} = ", ctx.ea()); + if (ctx.insn.operands[1] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[1])); + ctx.println("{}.u32;", ctx.r(ctx.insn.operands[2])); + ctx.println("\t{}.{} = *({}*)REX_RAW_ADDR({});", ctx.reserved(), reserved_field, ptr_type, + ctx.ea()); + ctx.println("\t{}.u64 = {}({}.{});", ctx.r(ctx.insn.operands[0]), bswap_func, ctx.reserved(), + reserved_field); +} + +/** + * Emit atomic store-conditional instruction (stwcx./stdcx. pattern). + * + * Pattern: EA = rA + rB; cr0 = CAS(EA, reserved, bswap(rS)) + * + * @param ctx The builder context + * @param ptr_type The pointer type (e.g., "uint32_t", "uint64_t") + * @param bswap_func The byte-swap builtin (e.g., "__builtin_bswap32") + * @param field The register field (e.g., "s32", "s64") + */ +inline void emitAtomicStoreConditional(BuilderContext& ctx, const char* ptr_type, + const char* bswap_func, const char* field) { + ctx.print("\t{} = ", ctx.ea()); + if (ctx.insn.operands[1] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[1])); + ctx.println("{}.u32;", ctx.r(ctx.insn.operands[2])); + ctx.println("\t{}.lt = 0;", ctx.cr(0)); + ctx.println("\t{}.gt = 0;", ctx.cr(0)); + ctx.println( + "\t{}.eq = __sync_bool_compare_and_swap(reinterpret_cast<{}*>(REX_RAW_ADDR({})), " + "{}.{}, {}({}.{}));", + ctx.cr(0), ptr_type, ctx.ea(), ctx.reserved(), field, bswap_func, ctx.r(ctx.insn.operands[0]), + field); + ctx.println("\t{}.so = {}.so;", ctx.cr(0), ctx.xer()); +} + +//============================================================================= +// Sign-Extending Load Helpers +//============================================================================= + +/** + * Emit D-form sign-extending load instruction. + * + * Pattern: rD = sign_extend(LOAD(rA + d)) + * Used by: lha, lwa (halfword/word algebraic loads) + * + * @param ctx The builder context + * @param cast_type The cast for sign extension (e.g., "int16_t", "int32_t") + * @param load_macro The REX_LOAD_* macro to use + */ +inline void emitSignExtendLoadDForm(BuilderContext& ctx, const char* cast_type, + const char* load_macro) { + ctx.print("\t{}.s64 = {}({}(", ctx.r(ctx.insn.operands[0]), cast_type, load_macro); + if (ctx.insn.operands[2] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[2])); + ctx.println("{}));", static_cast(ctx.insn.operands[1])); +} + +/** + * Emit X-form sign-extending load instruction. + * + * Pattern: rD = sign_extend(LOAD(rA + rB)) + * Used by: lhax, lwax (halfword/word algebraic indexed loads) + * + * @param ctx The builder context + * @param cast_type The cast for sign extension (e.g., "int16_t", "int32_t") + * @param load_macro The REX_LOAD_* macro to use + */ +inline void emitSignExtendLoadXForm(BuilderContext& ctx, const char* cast_type, + const char* load_macro) { + ctx.print("\t{}.s64 = {}({}(", ctx.r(ctx.insn.operands[0]), cast_type, load_macro); + if (ctx.insn.operands[1] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[1])); + ctx.println("{}.u32));", ctx.r(ctx.insn.operands[2])); +} + +//============================================================================= +// MMIO Detection Helpers +//============================================================================= + +/** + * Check if an upper-16-bit immediate value corresponds to a known MMIO range. + * + * Xbox 360 hardware register ranges: + * - GPU MMIO: 0x7FC80000-0x7FCFFFFF (upper bits: 0x7FC8-0x7FCF) + * - XMA/APU MMIO: 0x7FEA0000-0x7FEAFFFF (upper bits: 0x7FEA) + * + * @param imm The upper 16 bits loaded by lis/oris + * @return true if the value matches a known MMIO base address range + */ +inline bool isMMIOUpperBits(uint32_t imm) { + return (imm >= 0x7FC8 && imm <= 0x7FCF) || imm == 0x7FEA; +} + +//============================================================================= +// Branch Bounds-Checking Helper +//============================================================================= + +/** + * Emit a conditional branch with bounds checking. + * + * If the target is within the current function, emits a goto. + * If outside, emits a warning and a return statement. + * + * @param ctx The builder context + * @param target Target address of the branch + * @param condition Pre-formatted condition expression (e.g., "ctr.u32 != 0") + * @param instr_name Instruction mnemonic for the warning message + */ +inline void emitBranchWithBoundsCheck(BuilderContext& ctx, uint32_t target, + std::string_view condition, std::string_view instr_name) { + if (target < ctx.fn.base() || target >= ctx.fn.end()) { + REXCODEGEN_WARN("{} at {:X} branches outside function to {:X}", instr_name, ctx.base, target); + ctx.println("\tif ({}) {{ /* branch to 0x{:X} outside function */ return; }}", condition, + target); + } else { + ctx.println("\tif ({}) goto loc_{:X};", condition, target); + } +} + +//============================================================================= +// Vector EA Calculation Helpers +//============================================================================= + +/** + * Emit aligned or unaligned vector effective address calculation to ea. + * + * Pattern: ea = (opt_rA + rB) [& ~align_mask] + * Uses operands[1] as optional base register and operands[2] as index register. + * + * @param ctx The builder context + * @param align_mask Alignment mask string (e.g., "0xF"), or nullptr for no alignment + */ +inline void emitVectorEA(BuilderContext& ctx, const char* align_mask = nullptr) { + if (align_mask) + ctx.print("\t{} = (", ctx.ea()); + else + ctx.print("\t{} = ", ctx.ea()); + if (ctx.insn.operands[1] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[1])); + if (align_mask) + ctx.println("{}.u32) & ~{};", ctx.r(ctx.insn.operands[2]), align_mask); + else + ctx.println("{}.u32;", ctx.r(ctx.insn.operands[2])); +} + +/** + * Emit unaligned vector effective address calculation to temp. + * + * Pattern: temp.u32 = opt_rA + rB + * Uses operands[1] as optional base register and operands[2] as index register. + * + * @param ctx The builder context + */ +inline void emitVectorTempEA(BuilderContext& ctx) { + ctx.print("\t{}.u32 = ", ctx.temp()); + if (ctx.insn.operands[1] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[1])); + ctx.println("{}.u32;", ctx.r(ctx.insn.operands[2])); +} + +//============================================================================= +// Trap Instruction Helper +//============================================================================= + +/** + * Emit a PPC trap instruction: if () ppc_trap(ctx, base, 0); + * + * @param to 5-bit TO field + * @param aSigned First operand, signed (e.g., "ctx.r3.s32") + * @param aUnsigned First operand, unsigned (e.g., "ctx.r3.u32") + * @param bSigned Second operand, signed (e.g., "ctx.r4.s32" or "-1") + * @param bUnsigned Second operand, unsigned (e.g., "ctx.r4.u32" or "4294967295u") + */ +inline void emitTrap(BuilderContext& ctx, uint32_t to, const std::string& aSigned, + const std::string& aUnsigned, const std::string& bSigned, + const std::string& bUnsigned) { + if (to == 0) + return; + if (to == 0x1F) { + ctx.println("\tppc_trap(ctx, base, 0);"); + return; + } + + std::string cond; + auto add = [&](std::string_view c) { + if (!cond.empty()) + cond += " || "; + cond += c; + }; + if (to & 0x10) + add(fmt::format("{} < {}", aSigned, bSigned)); + if (to & 0x08) + add(fmt::format("{} > {}", aSigned, bSigned)); + if (to & 0x04) + add(fmt::format("{} == {}", aSigned, bSigned)); + if (to & 0x02) + add(fmt::format("{} < {}", aUnsigned, bUnsigned)); + if (to & 0x01) + add(fmt::format("{} > {}", aUnsigned, bUnsigned)); + + ctx.println("\tif ({}) ppc_trap(ctx, base, 0);", cond); +} + +} // namespace rex::codegen diff --git a/src/codegen/builders/logical.cpp b/src/codegen/builders/logical.cpp new file mode 100644 index 0000000..a58f51d --- /dev/null +++ b/src/codegen/builders/logical.cpp @@ -0,0 +1,470 @@ +/** + * @file rexcodegen/builders/logical.cpp + * @brief PPC logical instruction code generation + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "helpers.h" + +namespace rex::codegen { + +//============================================================================= +// AND Operations +//============================================================================= + +bool build_and(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u64 & {}.u64;", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_andc(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u64 & ~{}.u64;", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_andi(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u64 & {};", ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), + ctx.insn.operands[2]); + // ANDI. always sets CR0 + ctx.println("\t{}.compare({}.s32, 0, {});", ctx.cr(0), ctx.r(ctx.insn.operands[0]), + ctx.xer()); + return true; +} + +bool build_andis(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u64 & {};", ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), + ctx.insn.operands[2] << 16); + // ANDIS. always sets CR0 + ctx.println("\t{}.compare({}.s32, 0, {});", ctx.cr(0), ctx.r(ctx.insn.operands[0]), + ctx.xer()); + return true; +} + +//============================================================================= +// OR Operations +//============================================================================= + +bool build_nand(BuilderContext& ctx) { + ctx.println("\t{}.u64 = ~({}.u64 & {}.u64);", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_nor(BuilderContext& ctx) { + ctx.println("\t{}.u64 = ~({}.u64 | {}.u64);", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_not(BuilderContext& ctx) { + ctx.println("\t{}.u64 = ~{}.u64;", ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_or(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u64 | {}.u64;", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + + // Propagates MMIO base flag if either source register is marked MMIO + // covers mr rD,rS which assembles as or rD,rS,rS + if (ctx.locals.is_mmio_base(ctx.insn.operands[1]) || + ctx.locals.is_mmio_base(ctx.insn.operands[2])) + ctx.locals.set_mmio_base(ctx.insn.operands[0]); + else + ctx.locals.clear_mmio_base(ctx.insn.operands[0]); + + return true; +} + +bool build_orc(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u64 | ~{}.u64;", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_ori(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u64 | {};", ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), + ctx.insn.operands[2]); + + // ori only sets low bits - propagate MMIO base from source + if (ctx.locals.is_mmio_base(ctx.insn.operands[1])) + ctx.locals.set_mmio_base(ctx.insn.operands[0]); + else + ctx.locals.clear_mmio_base(ctx.insn.operands[0]); + + return true; +} + +bool build_oris(BuilderContext& ctx) { + uint32_t imm = static_cast(ctx.insn.operands[2]); + size_t dest_reg = ctx.insn.operands[0]; + + ctx.println("\t{}.u64 = {}.u64 | {};", ctx.r(dest_reg), ctx.r(ctx.insn.operands[1]), imm << 16); + + if (isMMIOUpperBits(imm)) { + ctx.locals.set_mmio_base(dest_reg); + } + // NOTE(tomc): don't clear flag here - oris may preserve MMIO base from source + + return true; +} + +//============================================================================= +// XOR Operations +//============================================================================= + +bool build_xor(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u64 ^ {}.u64;", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_xori(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u64 ^ {};", ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), + ctx.insn.operands[2]); + return true; +} + +bool build_xoris(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u64 ^ {};", ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), + ctx.insn.operands[2] << 16); + return true; +} + +bool build_eqv(BuilderContext& ctx) { + // eqv: rA = ~(rS ^ rB) (XNOR - equivalent) + ctx.println("\t{}.u64 = ~({}.u64 ^ {}.u64);", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +//============================================================================= +// Count Leading Zeros +//============================================================================= + +bool build_cntlzd(BuilderContext& ctx) { + ctx.println("\t{0}.u64 = {1}.u64 == 0 ? 64 : __builtin_clzll({1}.u64);", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_cntlzw(BuilderContext& ctx) { + ctx.println("\t{0}.u64 = {1}.u32 == 0 ? 32 : __builtin_clz({1}.u32);", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1])); + emitRecordFormCompare(ctx); + return true; +} + +//============================================================================= +// Sign Extension +//============================================================================= + +bool build_extsb(BuilderContext& ctx) { + ctx.println("\t{}.s64 = {}.s8;", ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_extsh(BuilderContext& ctx) { + ctx.println("\t{}.s64 = {}.s16;", ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_extsw(BuilderContext& ctx) { + ctx.println("\t{}.s64 = {}.s32;", ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1])); + emitRecordFormCompare(ctx); + return true; +} + +//============================================================================= +// Clear Left Word Immediate +//============================================================================= + +bool build_clrlwi(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u32 & 0x{:X};", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), (1ull << (32 - ctx.insn.operands[2])) - 1); + emitRecordFormCompare(ctx); + return true; +} + +//============================================================================= +// Rotate Left Double Word +//============================================================================= + +bool build_rldicl(BuilderContext& ctx) { + ctx.println("\t{}.u64 = __builtin_rotateleft64({}.u64, {}) & 0x{:X};", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), ctx.insn.operands[2], + compute_mask(ctx.insn.operands[3], 63)); + emitRecordFormCompare(ctx); + return true; +} + +bool build_rldicr(BuilderContext& ctx) { + ctx.println("\t{}.u64 = __builtin_rotateleft64({}.u64, {}) & 0x{:X};", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), ctx.insn.operands[2], + compute_mask(0, ctx.insn.operands[3])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_rldic(BuilderContext& ctx) { + uint32_t sh = ctx.insn.operands[2]; + uint64_t mask = compute_mask(ctx.insn.operands[3], 63 - sh); + if (sh) + ctx.println("\t{}.u64 = __builtin_rotateleft64({}.u64, {}) & 0x{:X};", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), sh, mask); + else + ctx.println("\t{}.u64 = {}.u64 & 0x{:X};", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), mask); + emitRecordFormCompare(ctx); + return true; +} + +bool build_rldcl(BuilderContext& ctx) { + uint64_t mask = compute_mask(ctx.insn.operands[3], 63); + ctx.println("\t{}.u64 = __builtin_rotateleft64({}.u64, {}.u8 & 0x3F) & 0x{:X};", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2]), + mask); + emitRecordFormCompare(ctx); + return true; +} + +bool build_rldcr(BuilderContext& ctx) { + uint64_t mask = compute_mask(0, ctx.insn.operands[3]); + ctx.println("\t{}.u64 = __builtin_rotateleft64({}.u64, {}.u8 & 0x3F) & 0x{:X};", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[2]), + mask); + emitRecordFormCompare(ctx); + return true; +} + +bool build_rldimi(BuilderContext& ctx) { + const uint64_t mask = compute_mask(ctx.insn.operands[3], ~ctx.insn.operands[2]); + ctx.println("\t{}.u64 = (__builtin_rotateleft64({}.u64, {}) & 0x{:X}) | ({}.u64 & 0x{:X});", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), ctx.insn.operands[2], mask, + ctx.r(ctx.insn.operands[0]), ~mask); + emitRecordFormCompare(ctx); + return true; +} + +bool build_rotldi(BuilderContext& ctx) { + ctx.println("\t{}.u64 = __builtin_rotateleft64({}.u64, {});", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.insn.operands[2]); + emitRecordFormCompare(ctx); + return true; +} + +//============================================================================= +// Rotate Left Word +//============================================================================= + +bool build_rlwimi(BuilderContext& ctx) { + const uint64_t mask = compute_mask(ctx.insn.operands[3] + 32, ctx.insn.operands[4] + 32); + ctx.println( + "\t{}.u64 = (__builtin_rotateleft64({}.u32 | ({}.u64 << 32), {}) & 0x{:X}) | ({}.u64 & " + "0x{:X});", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[1]), + ctx.insn.operands[2], mask, ctx.r(ctx.insn.operands[0]), ~mask); + emitRecordFormCompare(ctx); + return true; +} + +bool build_rlwinm(BuilderContext& ctx) { + ctx.println("\t{}.u64 = __builtin_rotateleft64({}.u32 | ({}.u64 << 32), {}) & 0x{:X};", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[1]), + ctx.insn.operands[2], + compute_mask(ctx.insn.operands[3] + 32, ctx.insn.operands[4] + 32)); + emitRecordFormCompare(ctx); + return true; +} + +bool build_rlwnm(BuilderContext& ctx) { + // Like rlwinm but shift amount comes from register, not immediate + ctx.println("\t{}.u64 = __builtin_rotateleft64({}.u32 | ({}.u64 << 32), {}.u8 & 0x1F) & 0x{:X};", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2]), // Register, not immediate + compute_mask(ctx.insn.operands[3] + 32, ctx.insn.operands[4] + 32)); + emitRecordFormCompare(ctx); + return true; +} + +bool build_rotlw(BuilderContext& ctx) { + ctx.println("\t{}.u64 = __builtin_rotateleft32({}.u32, {}.u8 & 0x1F);", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_rotlwi(BuilderContext& ctx) { + ctx.println("\t{}.u64 = __builtin_rotateleft32({}.u32, {});", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.insn.operands[2]); + emitRecordFormCompare(ctx); + return true; +} + +//============================================================================= +// Shift Left +//============================================================================= + +bool build_sld(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u8 & 0x40 ? 0 : ({}.u64 << ({}.u8 & 0x7F));", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[2]), ctx.r(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_slw(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u8 & 0x20 ? 0 : ({}.u32 << ({}.u8 & 0x3F));", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[2]), ctx.r(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +//============================================================================= +// Shift Right Algebraic (signed) +//============================================================================= + +bool build_srad(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u64 & 0x7F;", ctx.temp(), ctx.r(ctx.insn.operands[2])); + ctx.println("\tif ({}.u64 > 0x3F) {}.u64 = 0x3F;", ctx.temp(), ctx.temp()); + ctx.println("\t{}.ca = ({}.s64 < 0) & ((({}.s64 >> {}.u64) << {}.u64) != {}.s64);", ctx.xer(), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[1]), ctx.temp(), ctx.temp(), + ctx.r(ctx.insn.operands[1])); + ctx.println("\t{}.s64 = {}.s64 >> {}.u64;", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.temp()); + emitRecordFormCompare(ctx); + return true; +} + +bool build_sradi(BuilderContext& ctx) { + if (ctx.insn.operands[2] != 0) { + ctx.println("\t{}.ca = ({}.s64 < 0) & (({}.u64 & 0x{:X}) != 0);", ctx.xer(), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[1]), + compute_mask(64 - ctx.insn.operands[2], 63)); + ctx.println("\t{}.s64 = {}.s64 >> {};", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.insn.operands[2]); + } else { + ctx.println("\t{}.ca = 0;", ctx.xer()); + ctx.println("\t{}.s64 = {}.s64;", ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1])); + } + emitRecordFormCompare(ctx); + return true; +} + +bool build_sraw(BuilderContext& ctx) { + ctx.println("\t{}.u32 = {}.u32 & 0x3F;", ctx.temp(), ctx.r(ctx.insn.operands[2])); + ctx.println("\tif ({}.u32 > 0x1F) {}.u32 = 0x1F;", ctx.temp(), ctx.temp()); + ctx.println("\t{}.ca = ({}.s32 < 0) & ((({}.s32 >> {}.u32) << {}.u32) != {}.s32);", ctx.xer(), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[1]), ctx.temp(), ctx.temp(), + ctx.r(ctx.insn.operands[1])); + ctx.println("\t{}.s64 = {}.s32 >> {}.u32;", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.temp()); + emitRecordFormCompare(ctx); + return true; +} + +bool build_srawi(BuilderContext& ctx) { + if (ctx.insn.operands[2] != 0) { + ctx.println("\t{}.ca = ({}.s32 < 0) & (({}.u32 & 0x{:X}) != 0);", ctx.xer(), + ctx.r(ctx.insn.operands[1]), ctx.r(ctx.insn.operands[1]), + compute_mask(64 - ctx.insn.operands[2], 63)); + ctx.println("\t{}.s64 = {}.s32 >> {};", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), ctx.insn.operands[2]); + } else { + ctx.println("\t{}.ca = 0;", ctx.xer()); + ctx.println("\t{}.s64 = {}.s32;", ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1])); + } + emitRecordFormCompare(ctx); + return true; +} + +//============================================================================= +// Shift Right (unsigned) +//============================================================================= + +bool build_srd(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u8 & 0x40 ? 0 : ({}.u64 >> ({}.u8 & 0x7F));", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[2]), ctx.r(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_srw(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u8 & 0x20 ? 0 : ({}.u32 >> ({}.u8 & 0x3F));", + ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[2]), ctx.r(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + emitRecordFormCompare(ctx); + return true; +} + +bool build_crand(BuilderContext& ctx) { + // crand: CR[crD] = CR[crA] & CR[crB] + emitCRBitOperation(ctx, "&"); + return true; +} + +bool build_crandc(BuilderContext& ctx) { + // crandc: CR[crD] = CR[crA] & ~CR[crB] + emitCRBitOperation(ctx, "&", false, true, false); + return true; +} + +bool build_creqv(BuilderContext& ctx) { + // creqv: CR[crD] = ~(CR[crA] ^ CR[crB]) (XNOR) + emitCRBitOperation(ctx, "^", false, false, true); + return true; +} + +bool build_crnand(BuilderContext& ctx) { + // crnand: CR[crD] = ~(CR[crA] & CR[crB]) + emitCRBitOperation(ctx, "&", false, false, true); + return true; +} + +bool build_crnor(BuilderContext& ctx) { + // crnor: CR[crD] = ~(CR[crA] | CR[crB]) + emitCRBitOperation(ctx, "|", false, false, true); + return true; +} + +bool build_cror(BuilderContext& ctx) { + // cror: CR[crD] = CR[crA] | CR[crB] + emitCRBitOperation(ctx, "|"); + return true; +} + +bool build_crorc(BuilderContext& ctx) { + // crorc: CR[crD] = CR[crA] | ~CR[crB] + emitCRBitOperation(ctx, "|", false, true, false); + return true; +} + +bool build_crxor(BuilderContext& ctx) { + // crxor: CR[crD] = CR[crA] ^ CR[crB] + emitCRBitOperation(ctx, "^"); + return true; +} + +} // namespace rex::codegen diff --git a/src/codegen/builders/memory.cpp b/src/codegen/builders/memory.cpp new file mode 100644 index 0000000..3dd7fa5 --- /dev/null +++ b/src/codegen/builders/memory.cpp @@ -0,0 +1,656 @@ +/** + * @file rexcodegen/builders/memory.cpp + * @brief PPC memory instruction code generation + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "builder_context.h" +#include "helpers.h" + +namespace rex::codegen { + +//============================================================================= +// Load Immediate (not really memory operations, but L* category) +//============================================================================= + +bool build_li(BuilderContext& ctx) { + ctx.println("\t{}.s64 = {};", ctx.r(ctx.insn.operands[0]), + static_cast(ctx.insn.operands[1])); + return true; +} + +bool build_lis(BuilderContext& ctx) { + uint32_t imm = static_cast(ctx.insn.operands[1]); + size_t dest_reg = ctx.insn.operands[0]; + + ctx.println("\t{}.s64 = {};", ctx.r(dest_reg), static_cast(imm << 16)); + + if (isMMIOUpperBits(imm)) { + ctx.locals.set_mmio_base(dest_reg); + } else { + ctx.locals.clear_mmio_base(dest_reg); + } + + return true; +} + +//============================================================================= +// Byte Loads +//============================================================================= + +bool build_lbz(BuilderContext& ctx) { + ctx.emit_load_d_form("REX_LOAD_U8", "u64"); + return true; +} + +bool build_lbzu(BuilderContext& ctx) { + emitLoadWithUpdate(ctx, "REX_LOAD_U8"); + return true; +} + +bool build_lbzx(BuilderContext& ctx) { + ctx.emit_load_x_form("REX_LOAD_U8", "u64"); + return true; +} + +bool build_lbzux(BuilderContext& ctx) { + emitLoadXFormWithUpdate(ctx, "REX_LOAD_U8"); + return true; +} + +//============================================================================= +// Halfword Loads +//============================================================================= + +bool build_lha(BuilderContext& ctx) { + emitSignExtendLoadDForm(ctx, "int16_t", "REX_LOAD_U16"); + return true; +} + +bool build_lhax(BuilderContext& ctx) { + emitSignExtendLoadXForm(ctx, "int16_t", "REX_LOAD_U16"); + return true; +} + +bool build_lhz(BuilderContext& ctx) { + ctx.emit_load_d_form("REX_LOAD_U16", "u64"); + return true; +} + +bool build_lhzx(BuilderContext& ctx) { + ctx.emit_load_x_form("REX_LOAD_U16", "u64"); + return true; +} + +bool build_lhzu(BuilderContext& ctx) { + emitLoadWithUpdate(ctx, "REX_LOAD_U16"); + return true; +} + +bool build_lhzux(BuilderContext& ctx) { + emitLoadXFormWithUpdate(ctx, "REX_LOAD_U16"); + return true; +} + +bool build_lhau(BuilderContext& ctx) { + // Load Halfword Algebraic with Update: sign-extend then update rA + ctx.println("\t{} = {} + {}.u32;", ctx.ea(), static_cast(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + ctx.println("\t{}.s64 = int16_t(REX_LOAD_U16({}));", ctx.r(ctx.insn.operands[0]), ctx.ea()); + ctx.println("\t{}.u32 = {};", ctx.r(ctx.insn.operands[2]), ctx.ea()); + return true; +} + +bool build_lhaux(BuilderContext& ctx) { + // Load Halfword Algebraic with Update Indexed: EA = rA + rB; rD = EXTS(MEM16(EA)); rA = EA + ctx.println("\t{} = {}.u32 + {}.u32;", ctx.ea(), ctx.r(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + ctx.println("\t{}.s64 = int16_t(REX_LOAD_U16({}));", ctx.r(ctx.insn.operands[0]), ctx.ea()); + ctx.println("\t{}.u32 = {};", ctx.r(ctx.insn.operands[1]), ctx.ea()); + return true; +} + +bool build_lhbrx(BuilderContext& ctx) { + // Load Halfword Byte-Reverse Indexed + ctx.print("\t{}.u64 = __builtin_bswap16({}(", ctx.r(ctx.insn.operands[0]), + ctx.mmio_check_x_form() ? "REX_MM_LOAD_U16" : "REX_LOAD_U16"); + if (ctx.insn.operands[1] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[1])); + ctx.println("{}.u32));", ctx.r(ctx.insn.operands[2])); + return true; +} + +//============================================================================= +// Word Loads +//============================================================================= + +bool build_lwa(BuilderContext& ctx) { + emitSignExtendLoadDForm(ctx, "int32_t", "REX_LOAD_U32"); + return true; +} + +bool build_lwaux(BuilderContext& ctx) { + // Load Word Algebraic with Update Indexed: EA = rA + rB; rD = EXTS(MEM32(EA)); rA = EA + ctx.println("\t{} = {}.u32 + {}.u32;", ctx.ea(), ctx.r(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + ctx.println("\t{}.s64 = int32_t(REX_LOAD_U32({}));", ctx.r(ctx.insn.operands[0]), ctx.ea()); + ctx.println("\t{}.u32 = {};", ctx.r(ctx.insn.operands[1]), ctx.ea()); + return true; +} + +bool build_lwax(BuilderContext& ctx) { + emitSignExtendLoadXForm(ctx, "int32_t", "REX_LOAD_U32"); + return true; +} + +bool build_lwz(BuilderContext& ctx) { + ctx.emit_load_d_form("REX_LOAD_U32", "u64"); + return true; +} + +bool build_lwzu(BuilderContext& ctx) { + emitLoadWithUpdate(ctx, "REX_LOAD_U32"); + return true; +} + +bool build_lwzx(BuilderContext& ctx) { + ctx.emit_load_x_form("REX_LOAD_U32", "u64"); + return true; +} + +bool build_lwzux(BuilderContext& ctx) { + emitLoadXFormWithUpdate(ctx, "REX_LOAD_U32"); + return true; +} + +bool build_lwbrx(BuilderContext& ctx) { + ctx.print("\t{}.u64 = __builtin_bswap32({}(", ctx.r(ctx.insn.operands[0]), + ctx.mmio_check_x_form() ? "REX_MM_LOAD_U32" : "REX_LOAD_U32"); + if (ctx.insn.operands[1] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[1])); + ctx.println("{}.u32));", ctx.r(ctx.insn.operands[2])); + return true; +} + +//============================================================================= +// Doubleword Loads +//============================================================================= + +bool build_ld(BuilderContext& ctx) { + ctx.emit_load_d_form("REX_LOAD_U64", "u64"); + return true; +} + +bool build_ldu(BuilderContext& ctx) { + emitLoadWithUpdate(ctx, "REX_LOAD_U64"); + return true; +} + +bool build_ldx(BuilderContext& ctx) { + ctx.emit_load_x_form("REX_LOAD_U64", "u64"); + return true; +} + +bool build_ldux(BuilderContext& ctx) { + emitLoadXFormWithUpdate(ctx, "REX_LOAD_U64"); + return true; +} + +//============================================================================= +// Atomic Load and Reserve +//============================================================================= + +bool build_lwarx(BuilderContext& ctx) { + emitAtomicLoadReserve(ctx, "uint32_t", "__builtin_bswap32", "u32"); + return true; +} + +bool build_ldarx(BuilderContext& ctx) { + emitAtomicLoadReserve(ctx, "uint64_t", "__builtin_bswap64", "u64"); + return true; +} + +//============================================================================= +// Floating Point Loads +//============================================================================= + +bool build_lfd(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.print("\t{}.u64 = REX_LOAD_U64(", ctx.f(ctx.insn.operands[0])); + if (ctx.insn.operands[2] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[2])); + ctx.println("{});", static_cast(ctx.insn.operands[1])); + return true; +} + +bool build_lfdx(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.print("\t{}.u64 = REX_LOAD_U64(", ctx.f(ctx.insn.operands[0])); + if (ctx.insn.operands[1] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[1])); + ctx.println("{}.u32);", ctx.r(ctx.insn.operands[2])); + return true; +} + +bool build_lfs(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.print("\t{}.u32 = REX_LOAD_U32(", ctx.temp()); + if (ctx.insn.operands[2] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[2])); + ctx.println("{});", static_cast(ctx.insn.operands[1])); + ctx.println("\t{}.f64 = double({}.f32);", ctx.f(ctx.insn.operands[0]), ctx.temp()); + return true; +} + +bool build_lfsx(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.print("\t{}.u32 = REX_LOAD_U32(", ctx.temp()); + if (ctx.insn.operands[1] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[1])); + ctx.println("{}.u32);", ctx.r(ctx.insn.operands[2])); + ctx.println("\t{}.f64 = double({}.f32);", ctx.f(ctx.insn.operands[0]), ctx.temp()); + return true; +} + +bool build_lfdu(BuilderContext& ctx) { + // Load Floating-point Double with Update + ctx.emit_set_flush_mode(false); + ctx.println("\t{} = {} + {}.u32;", ctx.ea(), static_cast(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + ctx.println("\t{}.u64 = REX_LOAD_U64({});", ctx.f(ctx.insn.operands[0]), ctx.ea()); + ctx.println("\t{}.u32 = {};", ctx.r(ctx.insn.operands[2]), ctx.ea()); + return true; +} + +bool build_lfdux(BuilderContext& ctx) { + // Load Floating-point Double with Update Indexed + ctx.emit_set_flush_mode(false); + ctx.println("\t{} = {}.u32 + {}.u32;", ctx.ea(), ctx.r(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + ctx.println("\t{}.u64 = REX_LOAD_U64({});", ctx.f(ctx.insn.operands[0]), ctx.ea()); + ctx.println("\t{}.u32 = {};", ctx.r(ctx.insn.operands[1]), ctx.ea()); + return true; +} + +bool build_lfsu(BuilderContext& ctx) { + // Load Floating-point Single with Update (convert to double) + ctx.emit_set_flush_mode(false); + ctx.println("\t{} = {} + {}.u32;", ctx.ea(), static_cast(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + ctx.println("\t{}.u32 = REX_LOAD_U32({});", ctx.temp(), ctx.ea()); + ctx.println("\t{}.f64 = double({}.f32);", ctx.f(ctx.insn.operands[0]), ctx.temp()); + ctx.println("\t{}.u32 = {};", ctx.r(ctx.insn.operands[2]), ctx.ea()); + return true; +} + +bool build_lfsux(BuilderContext& ctx) { + // Load Floating-point Single with Update Indexed (convert to double) + ctx.emit_set_flush_mode(false); + ctx.println("\t{} = {}.u32 + {}.u32;", ctx.ea(), ctx.r(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + ctx.println("\t{}.u32 = REX_LOAD_U32({});", ctx.temp(), ctx.ea()); + ctx.println("\t{}.f64 = double({}.f32);", ctx.f(ctx.insn.operands[0]), ctx.temp()); + ctx.println("\t{}.u32 = {};", ctx.r(ctx.insn.operands[1]), ctx.ea()); + return true; +} + +//============================================================================= +// Byte Stores +//============================================================================= + +bool build_stb(BuilderContext& ctx) { + ctx.emit_store_d_form("REX_STORE_U8", "u8", true); + return true; +} + +bool build_stbu(BuilderContext& ctx) { + emitStoreWithUpdate(ctx, "REX_STORE_U8", "u8"); + return true; +} + +bool build_stbx(BuilderContext& ctx) { + ctx.emit_store_x_form("REX_STORE_U8", "u8", true); + return true; +} + +bool build_stbux(BuilderContext& ctx) { + emitStoreXFormWithUpdate(ctx, "REX_STORE_U8", "REX_MM_STORE_U8", "u8"); + return true; +} + +//============================================================================= +// Halfword Stores +//============================================================================= + +bool build_sth(BuilderContext& ctx) { + ctx.emit_store_d_form("REX_STORE_U16", "u16", true); + return true; +} + +bool build_sthbrx(BuilderContext& ctx) { + ctx.print("{}", ctx.mmio_check_x_form() ? "\tREX_MM_STORE_U16(" : "\tREX_STORE_U16("); + if (ctx.insn.operands[1] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[1])); + ctx.println("{}.u32, __builtin_bswap16({}.u16));", ctx.r(ctx.insn.operands[2]), + ctx.r(ctx.insn.operands[0])); + return true; +} + +bool build_sthx(BuilderContext& ctx) { + ctx.emit_store_x_form("REX_STORE_U16", "u16", true); + return true; +} + +bool build_sthu(BuilderContext& ctx) { + emitStoreWithUpdate(ctx, "REX_STORE_U16", "u16"); + return true; +} + +bool build_sthux(BuilderContext& ctx) { + emitStoreXFormWithUpdate(ctx, "REX_STORE_U16", "REX_MM_STORE_U16", "u16"); + return true; +} + +//============================================================================= +// Word Stores +//============================================================================= + +bool build_stw(BuilderContext& ctx) { + ctx.emit_store_d_form("REX_STORE_U32", "u32", true); + return true; +} + +bool build_stwu(BuilderContext& ctx) { + emitStoreWithUpdate(ctx, "REX_STORE_U32", "u32"); + return true; +} + +bool build_stwux(BuilderContext& ctx) { + emitStoreXFormWithUpdate(ctx, "REX_STORE_U32", "REX_MM_STORE_U32", "u32"); + return true; +} + +bool build_stwx(BuilderContext& ctx) { + ctx.emit_store_x_form("REX_STORE_U32", "u32", true); + return true; +} + +bool build_stmw(BuilderContext& ctx) { + // EA = (rA == 0 ? 0 : r[rA]) + EXTS(d); store r[rS]..r[31] at EA, EA+4, ... + uint32_t rS = ctx.insn.operands[0]; + int32_t offset = static_cast(ctx.insn.operands[1]); + uint32_t rA = ctx.insn.operands[2]; + if (rA != 0) + ctx.println("\t{} = {}.u32 + {};", ctx.ea(), ctx.r(rA), offset); + else + ctx.println("\t{} = {};", ctx.ea(), offset); + for (uint32_t i = rS; i <= 31; ++i) { + ctx.println("\tREX_STORE_U32({} + {}, {}.u32);", ctx.ea(), (i - rS) * 4, ctx.r(i)); + } + return true; +} + +bool build_stwbrx(BuilderContext& ctx) { + ctx.print("{}", ctx.mmio_check_x_form() ? "\tREX_MM_STORE_U32(" : "\tREX_STORE_U32("); + if (ctx.insn.operands[1] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[1])); + ctx.println("{}.u32, __builtin_bswap32({}.u32));", ctx.r(ctx.insn.operands[2]), + ctx.r(ctx.insn.operands[0])); + return true; +} + +//============================================================================= +// Atomic Store Conditional +//============================================================================= + +bool build_stwcx(BuilderContext& ctx) { + emitAtomicStoreConditional(ctx, "uint32_t", "__builtin_bswap32", "s32"); + return true; +} + +bool build_stdcx(BuilderContext& ctx) { + emitAtomicStoreConditional(ctx, "uint64_t", "__builtin_bswap64", "s64"); + return true; +} + +//============================================================================= +// Doubleword Stores +//============================================================================= + +bool build_std(BuilderContext& ctx) { + ctx.emit_store_d_form("REX_STORE_U64", "u64", true); + return true; +} + +bool build_stdu(BuilderContext& ctx) { + emitStoreWithUpdate(ctx, "REX_STORE_U64", "u64"); + return true; +} + +bool build_stdx(BuilderContext& ctx) { + ctx.emit_store_x_form("REX_STORE_U64", "u64", true); + return true; +} + +bool build_stdux(BuilderContext& ctx) { + emitStoreXFormWithUpdate(ctx, "REX_STORE_U64", "REX_MM_STORE_U64", "u64"); + return true; +} + +//============================================================================= +// Floating Point Stores +//============================================================================= + +bool build_stfd(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.print("{}", ctx.mmio_check_d_form() ? "\tREX_MM_STORE_U64(" : "\tREX_STORE_U64("); + if (ctx.insn.operands[2] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[2])); + ctx.println("{}, {}.u64);", static_cast(ctx.insn.operands[1]), + ctx.f(ctx.insn.operands[0])); + return true; +} + +bool build_stfdx(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.print("{}", ctx.mmio_check_x_form() ? "\tREX_MM_STORE_U64(" : "\tREX_STORE_U64("); + if (ctx.insn.operands[1] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[1])); + ctx.println("{}.u32, {}.u64);", ctx.r(ctx.insn.operands[2]), ctx.f(ctx.insn.operands[0])); + return true; +} + +bool build_stfdux(BuilderContext& ctx) { + // Store Floating-point Double with Update Indexed: EA = rA + rB; MEM(EA) = FRS; rA = EA + ctx.emit_set_flush_mode(false); + ctx.println("\t{} = {}.u32 + {}.u32;", ctx.ea(), ctx.r(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + ctx.println("\tREX_STORE_U64({}, {}.u64);", ctx.ea(), ctx.f(ctx.insn.operands[0])); + ctx.println("\t{}.u32 = {};", ctx.r(ctx.insn.operands[1]), ctx.ea()); + return true; +} + +bool build_stfiwx(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.print("{}", ctx.mmio_check_x_form() ? "\tREX_MM_STORE_U32(" : "\tREX_STORE_U32("); + if (ctx.insn.operands[1] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[1])); + ctx.println("{}.u32, {}.u32);", ctx.r(ctx.insn.operands[2]), ctx.f(ctx.insn.operands[0])); + return true; +} + +bool build_stfs(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f32 = float({}.f64);", ctx.temp(), ctx.f(ctx.insn.operands[0])); + ctx.print("{}", ctx.mmio_check_d_form() ? "\tREX_MM_STORE_U32(" : "\tREX_STORE_U32("); + if (ctx.insn.operands[2] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[2])); + ctx.println("{}, {}.u32);", static_cast(ctx.insn.operands[1]), ctx.temp()); + return true; +} + +bool build_stfsx(BuilderContext& ctx) { + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f32 = float({}.f64);", ctx.temp(), ctx.f(ctx.insn.operands[0])); + ctx.print("{}", ctx.mmio_check_x_form() ? "\tREX_MM_STORE_U32(" : "\tREX_STORE_U32("); + if (ctx.insn.operands[1] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[1])); + ctx.println("{}.u32, {}.u32);", ctx.r(ctx.insn.operands[2]), ctx.temp()); + return true; +} + +bool build_stfdu(BuilderContext& ctx) { + // Store Floating-point Double with Update + ctx.emit_set_flush_mode(false); + ctx.println("\t{} = {} + {}.u32;", ctx.ea(), static_cast(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + ctx.println("\tREX_STORE_U64({}, {}.u64);", ctx.ea(), ctx.f(ctx.insn.operands[0])); + ctx.println("\t{}.u32 = {};", ctx.r(ctx.insn.operands[2]), ctx.ea()); + return true; +} + +bool build_stfsu(BuilderContext& ctx) { + // Store Floating-point Single with Update (convert double to float first) + ctx.emit_set_flush_mode(false); + ctx.println("\t{} = {} + {}.u32;", ctx.ea(), static_cast(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + ctx.println("\t{}.f32 = float({}.f64);", ctx.temp(), ctx.f(ctx.insn.operands[0])); + ctx.println("\tREX_STORE_U32({}, {}.u32);", ctx.ea(), ctx.temp()); + ctx.println("\t{}.u32 = {};", ctx.r(ctx.insn.operands[2]), ctx.ea()); + return true; +} + +bool build_stfsux(BuilderContext& ctx) { + // Store Floating-point Single with Update Indexed + ctx.emit_set_flush_mode(false); + ctx.println("\t{}.f32 = float({}.f64);", ctx.temp(), ctx.f(ctx.insn.operands[0])); + ctx.println("\t{} = {}.u32 + {}.u32;", ctx.ea(), ctx.r(ctx.insn.operands[1]), + ctx.r(ctx.insn.operands[2])); + ctx.println("\t{}({}, {}.u32);", ctx.mmio_check_x_form() ? "REX_MM_STORE_U32" : "REX_STORE_U32", + ctx.ea(), ctx.temp()); + ctx.println("\t{}.u32 = {};", ctx.r(ctx.insn.operands[1]), ctx.ea()); + return true; +} + +//============================================================================= +// Vector Loads (will be more comprehensive in vector.cpp) +//============================================================================= + +bool build_lvx(BuilderContext& ctx) { + // NOTE(tomc): for endian swapping, we reverse the whole vector instead of individual elements. + // this is accounted for in every instruction (eg. dp3 sums yzw instead of xyz) + emitVectorEA(ctx, "0xF"); + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "simde_mm_shuffle_epi8(simde_mm_load_si128((simde__m128i*)REX_RAW_ADDR({})), " + "simde_mm_load_si128((simde__m128i*)VectorMaskL)));", + ctx.v(ctx.insn.operands[0]), ctx.ea()); + return true; +} + +bool build_lvlx(BuilderContext& ctx) { + emitVectorTempEA(ctx); + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "simde_mm_shuffle_epi8(simde_mm_load_si128((simde__m128i*)REX_RAW_ADDR({}.u32 & ~0xF)), " + "simde_mm_load_si128((simde__m128i*)&VectorMaskL[({}.u32 & 0xF) * 16])));", + ctx.v(ctx.insn.operands[0]), ctx.temp(), ctx.temp()); + return true; +} + +bool build_lvrx(BuilderContext& ctx) { + emitVectorTempEA(ctx); + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, {}.u32 & 0xF ? " + "simde_mm_shuffle_epi8(simde_mm_load_si128((simde__m128i*)REX_RAW_ADDR({}.u32 & ~0xF)), " + "simde_mm_load_si128((simde__m128i*)&VectorMaskR[({}.u32 & 0xF) * 16])) : " + "simde_mm_setzero_si128());", + ctx.v(ctx.insn.operands[0]), ctx.temp(), ctx.temp(), ctx.temp()); + return true; +} + +bool build_lvsl(BuilderContext& ctx) { + emitVectorTempEA(ctx); + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "simde_mm_load_si128((simde__m128i*)&VectorShiftTableL[({}.u32 & 0xF) * 16]));", + ctx.v(ctx.insn.operands[0]), ctx.temp()); + return true; +} + +bool build_lvsr(BuilderContext& ctx) { + emitVectorTempEA(ctx); + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "simde_mm_load_si128((simde__m128i*)&VectorShiftTableR[({}.u32 & 0xF) * 16]));", + ctx.v(ctx.insn.operands[0]), ctx.temp()); + return true; +} + +//============================================================================= +// Vector Stores +//============================================================================= + +bool build_stvebx(BuilderContext& ctx) { + // TODO(tomc): vectorize + // NOTE: accounting for the full vector reversal here + emitVectorEA(ctx); + ctx.println("\tREX_STORE_U8({}, {}.u8[15 - ({} & 0xF)]);", ctx.ea(), ctx.v(ctx.insn.operands[0]), + ctx.ea()); + return true; +} + +bool build_stvehx(BuilderContext& ctx) { + // TODO(tomc): vectorize + // NOTE: accounting for the full vector reversal here + emitVectorEA(ctx, "0x1"); + ctx.println("\tREX_STORE_U16(ea, {}.u16[7 - (({} & 0xF) >> 1)]);", ctx.v(ctx.insn.operands[0]), + ctx.ea()); + return true; +} + +bool build_stvewx(BuilderContext& ctx) { + // TODO(tomc): vectorize + // NOTE: accounting for the full vector reversal here + emitVectorEA(ctx, "0x3"); + ctx.println("\tREX_STORE_U32(ea, {}.u32[3 - (({} & 0xF) >> 2)]);", ctx.v(ctx.insn.operands[0]), + ctx.ea()); + return true; +} + +bool build_stvlx(BuilderContext& ctx) { + // TODO(tomc): vectorize + // NOTE: accounting for the full vector reversal here + emitVectorEA(ctx); + + ctx.println("\tfor (size_t i = 0; i < (16 - ({} & 0xF)); i++)", ctx.ea()); + ctx.println("\t\tREX_STORE_U8({} + i, {}.u8[15 - i]);", ctx.ea(), ctx.v(ctx.insn.operands[0])); + return true; +} + +bool build_stvrx(BuilderContext& ctx) { + // TODO(tomc): vectorize + // NOTE: accounting for the full vector reversal here + emitVectorEA(ctx); + + ctx.println("\tfor (size_t i = 0; i < ({} & 0xF); i++)", ctx.ea()); + ctx.println("\t\tREX_STORE_U8({} - i - 1, {}.u8[i]);", ctx.ea(), ctx.v(ctx.insn.operands[0])); + return true; +} + +bool build_stvx(BuilderContext& ctx) { + emitVectorEA(ctx, "0xF"); + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*)REX_RAW_ADDR({}), " + "simde_mm_shuffle_epi8(simde_mm_load_si128((simde__m128i*){}.u8), " + "simde_mm_load_si128((simde__m128i*)VectorMaskL)));", + ctx.ea(), ctx.v(ctx.insn.operands[0])); + return true; +} + +} // namespace rex::codegen diff --git a/src/codegen/builders/system.cpp b/src/codegen/builders/system.cpp new file mode 100644 index 0000000..b2d70f5 --- /dev/null +++ b/src/codegen/builders/system.cpp @@ -0,0 +1,373 @@ +/** + * @file rexcodegen/builders/system.cpp + * @brief PPC system instruction code generation + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "builder_context.h" +#include "helpers.h" + +namespace rex::codegen { + +//============================================================================= +// No-ops and Sync Operations +//============================================================================= + +bool build_nop(BuilderContext& ctx) { + // Canonical PPC no-op (ori 0,0,0) + (void)ctx; + return true; +} + +bool build_attn(BuilderContext& ctx) { + // Xenon-specific debug breakpoint, no effect in recompiled code + (void)ctx; + return true; +} + +bool build_sync(BuilderContext& ctx) { + // Memory barrier, x86 has strong ordering so this is a no-op + (void)ctx; + return true; +} + +bool build_lwsync(BuilderContext& ctx) { + // Lightweight memory barrier, x86 has strong ordering so this is a no-op + (void)ctx; + return true; +} + +bool build_eieio(BuilderContext& ctx) { + // Enforce in-order execution of I/O, x86 has strong ordering so this is a no-op + (void)ctx; + return true; +} + +bool build_db16cyc(BuilderContext& ctx) { + // Xenon-specific 16-cycle delay hint, no effect in recompiled code + (void)ctx; + return true; +} + +bool build_cctpl(BuilderContext& ctx) { + // Xenon-specific cache control thread priority low, no effect in recompiled code + (void)ctx; + return true; +} + +bool build_cctpm(BuilderContext& ctx) { + // Xenon-specific cache control thread priority medium, no effect in recompiled code + (void)ctx; + return true; +} + +bool build_cctph(BuilderContext& ctx) { + // Xenon-specific cache control thread priority high, no effect in recompiled code + (void)ctx; + return true; +} + +//============================================================================= +// Trap Instructions +// PPC trap instructions are assertion/debug checks. The TO field (bits 21-25) +// is a 5-bit mask specifying which conditions trigger: signed lt/gt, eq, +// unsigned lt/gt. We extract TO directly from the instruction word so that +// both generic (tw TO,rA,rB) and simplified (tweq rA,rB) forms work with +// the same builder. +//============================================================================= + +bool build_tdi(BuilderContext& ctx) { + uint32_t to = (ctx.insn.instruction >> 21) & 0x1F; + uint32_t ra = (ctx.insn.instruction >> 16) & 0x1F; + int64_t simm = static_cast(ctx.insn.instruction & 0xFFFF); + emitTrap(ctx, to, fmt::format("{}.s64", ctx.r(ra)), fmt::format("{}.u64", ctx.r(ra)), + fmt::format("{}ll", simm), fmt::format("{}ull", static_cast(simm))); + return true; +} + +bool build_twi(BuilderContext& ctx) { + uint32_t to = (ctx.insn.instruction >> 21) & 0x1F; + uint32_t ra = (ctx.insn.instruction >> 16) & 0x1F; + int32_t simm = static_cast(ctx.insn.instruction & 0xFFFF); + + // twi 31, r0, is an unconditional trap with service code in the immediate + if (to == 0x1F && ra == 0) { + uint16_t trap_type = static_cast(simm); + ctx.println("\tppc_trap(ctx, base, {});", trap_type); + return true; + } + + emitTrap(ctx, to, fmt::format("{}.s32", ctx.r(ra)), fmt::format("{}.u32", ctx.r(ra)), + fmt::format("{}", simm), fmt::format("{}u", static_cast(simm))); + return true; +} + +bool build_td(BuilderContext& ctx) { + uint32_t to = (ctx.insn.instruction >> 21) & 0x1F; + uint32_t ra = (ctx.insn.instruction >> 16) & 0x1F; + uint32_t rb = (ctx.insn.instruction >> 11) & 0x1F; + emitTrap(ctx, to, fmt::format("{}.s64", ctx.r(ra)), fmt::format("{}.u64", ctx.r(ra)), + fmt::format("{}.s64", ctx.r(rb)), fmt::format("{}.u64", ctx.r(rb))); + return true; +} + +bool build_tw(BuilderContext& ctx) { + uint32_t to = (ctx.insn.instruction >> 21) & 0x1F; + uint32_t ra = (ctx.insn.instruction >> 16) & 0x1F; + uint32_t rb = (ctx.insn.instruction >> 11) & 0x1F; + emitTrap(ctx, to, fmt::format("{}.s32", ctx.r(ra)), fmt::format("{}.u32", ctx.r(ra)), + fmt::format("{}.s32", ctx.r(rb)), fmt::format("{}.u32", ctx.r(rb))); + return true; +} + +//============================================================================= +// Cache Operations +//============================================================================= + +bool build_dcbf(BuilderContext& ctx) { + // Hint instruction, access violation callback handlers take care of this on write + (void)ctx; + return true; +} + +bool build_dcbt(BuilderContext& ctx) { + // Hint instruction, prefetch has no semantic effect + (void)ctx; + return true; +} + +bool build_dcbtst(BuilderContext& ctx) { + // Hint instruction, prefetch-for-store has no semantic effect + (void)ctx; + return true; +} + +bool build_dcbz(BuilderContext& ctx) { + // Compute EA, align to 32-byte cache line, apply physical offset + ctx.print("\t{} = (", ctx.ea()); + if (ctx.insn.operands[0] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[0])); + ctx.println("{}.u32) & ~31;", ctx.r(ctx.insn.operands[1])); + ctx.println("\tmemset((void*)REX_RAW_ADDR({}), 0, 32);", ctx.ea()); + return true; +} + +bool build_dcbzl(BuilderContext& ctx) { + // Compute EA, align to 128-byte cache line, apply physical offset + ctx.print("\t{} = (", ctx.ea()); + if (ctx.insn.operands[0] != 0) + ctx.print("{}.u32 + ", ctx.r(ctx.insn.operands[0])); + ctx.println("{}.u32) & ~127;", ctx.r(ctx.insn.operands[1])); + ctx.println("\tmemset((void*)REX_RAW_ADDR({}), 0, 128);", ctx.ea()); + return true; +} + +bool build_dcbst(BuilderContext& ctx) { + // Hint instruction, access violation callback handlers take care of this on write + (void)ctx; + return true; +} + +//============================================================================= +// Move Register +//============================================================================= + +bool build_mr(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u64;", ctx.r(ctx.insn.operands[0]), ctx.r(ctx.insn.operands[1])); + emitRecordFormCompare(ctx); + + // Propagates MMIO base flag from source to destination register + if (ctx.locals.is_mmio_base(ctx.insn.operands[1])) + ctx.locals.set_mmio_base(ctx.insn.operands[0]); + else + ctx.locals.clear_mmio_base(ctx.insn.operands[0]); + + return true; +} + +//============================================================================= +// Move Register Field +//============================================================================= + +bool build_mcrf(BuilderContext& ctx) { + // Trivally copy one Control Register Field to another: + ctx.println("\t{0} = {1};", ctx.cr(ctx.insn.operands[0]), ctx.cr(ctx.insn.operands[1])); + return true; +} + +//============================================================================= +// Move From Special Registers +//============================================================================= + +bool build_mfxer(BuilderContext& ctx) { + ctx.println("\t{}.u64 = ({}.so << 31) | ({}.ov << 30) | ({}.ca << 29);", + ctx.r(ctx.insn.operands[0]), ctx.xer(), ctx.xer(), ctx.xer()); + return true; +} + +bool build_mfctr(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u64;", ctx.r(ctx.insn.operands[0]), ctx.ctr()); + return true; +} + +bool build_mfcr(BuilderContext& ctx) { + for (size_t i = 0; i < 32; i++) { + constexpr std::string_view fields[] = {"lt", "gt", "eq", "so"}; + ctx.println("\t{}.u64 {}= {}.{} ? 0x{:X} : 0;", ctx.r(ctx.insn.operands[0]), i == 0 ? "" : "|", + ctx.cr(i / 4), fields[i % 4], 1u << (31 - i)); + } + return true; +} + +bool build_mfocrf(BuilderContext& ctx) { + // FXM is a one-hot mask: bit 7 = CR0, bit 6 = CR1, ..., bit 0 = CR7 + uint32_t fxm = ctx.insn.operands[1]; + uint32_t crField = 0; + for (uint32_t i = 0; i < 8; i++) { + if (fxm & (0x80u >> i)) { + crField = i; + break; + } + } + uint32_t baseShift = 28 - 4 * crField; + ctx.println("\t{}.u64 = ({}.lt << {}) | ({}.gt << {}) | ({}.eq << {}) | ({}.so << {});", + ctx.r(ctx.insn.operands[0]), ctx.cr(crField), baseShift + 3, ctx.cr(crField), + baseShift + 2, ctx.cr(crField), baseShift + 1, ctx.cr(crField), baseShift); + return true; +} + +bool build_mflr(BuilderContext& ctx) { + if (!ctx.config().skipLr) + ctx.println("\t{}.u64 = ctx.lr;", ctx.r(ctx.insn.operands[0])); + return true; +} + +bool build_mfmsr(BuilderContext& ctx) { + if (!ctx.config().skipMsr) { + // Memory barrier for MSR read + ctx.println("\tstd::atomic_thread_fence(std::memory_order_seq_cst);"); + // Check global lock and return appropriate value + // Returns 0x8000 if unlocked (interrupts enabled), 0 if locked + ctx.println("\t{}.u64 = REX_CHECK_GLOBAL_LOCK();", ctx.r(ctx.insn.operands[0])); + } + return true; +} + +bool build_mffs(BuilderContext& ctx) { + ctx.println("\t{}.u64 = ctx.fpscr.loadFromHost();", ctx.f(ctx.insn.operands[0])); + return true; +} + +bool build_mftb(BuilderContext& ctx) { + // Xbox 360 timebase runs at 50 MHz (guest tick frequency) + // Using REX_QUERY_TIMEBASE() macro provides properly scaled timing from the runtime + ctx.println("\t{}.u64 = REX_QUERY_TIMEBASE();", ctx.r(ctx.insn.operands[0])); + return true; +} + +bool build_mftbu(BuilderContext& ctx) { + // Upper 32 bits of timebase + ctx.println("\t{}.u64 = REX_QUERY_TIMEBASE() >> 32;", ctx.r(ctx.insn.operands[0])); + return true; +} + +//============================================================================= +// Move To Special Registers +//============================================================================= + +bool build_mtcr(BuilderContext& ctx) { + for (size_t i = 0; i < 32; i++) { + constexpr std::string_view fields[] = {"lt", "gt", "eq", "so"}; + ctx.println("\t{}.{} = ({}.u32 & 0x{:X}) != 0;", ctx.cr(i / 4), fields[i % 4], + ctx.r(ctx.insn.operands[0]), 1u << (31 - i)); + } + return true; +} + +bool build_mtcrf(BuilderContext& ctx) { + uint32_t fxm = ctx.insn.operands[0]; + constexpr std::string_view names[] = {"lt", "gt", "eq", "so"}; + for (uint32_t field = 0; field < 8; field++) { + if (fxm & (0x80u >> field)) { + uint32_t base_bit = 28 - 4 * field; + for (int b = 0; b < 4; b++) { + ctx.println("\t{}.{} = ({}.u32 & 0x{:X}) != 0;", ctx.cr(field), names[b], + ctx.r(ctx.insn.operands[1]), 1u << (base_bit + 3 - b)); + } + } + } + return true; +} + +bool build_mtctr(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u64;", ctx.ctr(), ctx.r(ctx.insn.operands[0])); + return true; +} + +bool build_mtlr(BuilderContext& ctx) { + if (!ctx.config().skipLr) + ctx.println("\tctx.lr = {}.u64;", ctx.r(ctx.insn.operands[0])); + return true; +} + +bool build_mtmsrd(BuilderContext& ctx) { + if (!ctx.config().skipMsr) { + // Memory barrier for MSR write + ctx.println("\tstd::atomic_thread_fence(std::memory_order_seq_cst);"); + // Update MSR bits + ctx.println("\tctx.msr = ({}.u32 & 0x8020) | (ctx.msr & ~0x8020);", + ctx.r(ctx.insn.operands[0])); + // Global lock mechanism: + // R13 = enter lock (disable interrupts) + // Other = leave lock (enable interrupts) + uint32_t src_reg = ctx.insn.operands[0]; + if (src_reg == 13) { + ctx.println("\tREX_ENTER_GLOBAL_LOCK();"); + } else { + ctx.println("\tREX_LEAVE_GLOBAL_LOCK();"); + } + } + return true; +} + +bool build_mtfsf(BuilderContext& ctx) { + uint32_t fm = ctx.insn.operands[0]; + uint32_t mask = 0; + for (int j = 0; j < 8; j++) { + if (fm & (1 << (7 - j))) + mask |= 0xF << (4 * j); + } + if (mask == 0xFFFFFFFF) { + ctx.println("\tctx.fpscr.storeFromGuest({}.u32);", ctx.f(ctx.insn.operands[1])); + } else { + ctx.println( + "\tctx.fpscr.storeFromGuest((ctx.fpscr.loadFromHost() & 0x{:08X}) | ({}.u32 & 0x{:08X}));", + ~mask, ctx.f(ctx.insn.operands[1]), mask); + } + return true; +} + +bool build_mtxer(BuilderContext& ctx) { + ctx.println("\t{}.so = ({}.u64 & 0x80000000) != 0;", ctx.xer(), ctx.r(ctx.insn.operands[0])); + ctx.println("\t{}.ov = ({}.u64 & 0x40000000) != 0;", ctx.xer(), ctx.r(ctx.insn.operands[0])); + ctx.println("\t{}.ca = ({}.u64 & 0x20000000) != 0;", ctx.xer(), ctx.r(ctx.insn.operands[0])); + return true; +} + +//============================================================================= +// Clear Left Double Word Immediate +//============================================================================= + +bool build_clrldi(BuilderContext& ctx) { + ctx.println("\t{}.u64 = {}.u64 & 0x{:X};", ctx.r(ctx.insn.operands[0]), + ctx.r(ctx.insn.operands[1]), (1ull << (64 - ctx.insn.operands[2])) - 1); + emitRecordFormCompare(ctx); + return true; +} + +} // namespace rex::codegen diff --git a/src/codegen/builders/vector.cpp b/src/codegen/builders/vector.cpp new file mode 100644 index 0000000..d74e053 --- /dev/null +++ b/src/codegen/builders/vector.cpp @@ -0,0 +1,1590 @@ +/** + * @file rexcodegen/builders/vector.cpp + * @brief PPC vector instruction code generation + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "builder_context.h" +#include "helpers.h" + +#include + +#include + +#include + +#include "../codegen_logging.h" + +#include + +namespace rex::codegen { + +//============================================================================= +// SIMD Constants Documentation +//============================================================================= +// This file uses several magic constants from Intel SSE/SSE4 intrinsics. +// Here are the key constants and their meanings: +// +// === Dot Product Masks (simde_mm_dp_ps) === +// The mask byte controls which elements participate in the dot product and +// where the result is broadcast. Format: 0bAAAABBBB +// High nibble (AAAA): Which source elements to multiply (bit 7=x, 6=y, 5=z, 4=w) +// Low nibble (BBBB): Which destination elements receive the result +// +// 0xEF = 0b11101111: Dot product of elements y,z,w (bits 765 set), result to all (bits 3210 set) +// This computes dot(yzw) due to guest->host vector element reversal. +// 0xFF = 0b11111111: Full 4-element dot product, result broadcast to all elements +// +// === Floating-Point Sign Bit === +// 0x80000000: IEEE 754 sign bit mask for 32-bit float +// Used for negation via XOR and sign extraction +// +// === IEEE 754 Single Precision Exponent === +// 0x7f800000: Exponent field mask (bits 23-30) for float +// 0x7FFFFFFF: Magnitude mask (clears sign bit) +// 0x3F800000: IEEE 754 representation of 1.0f (used for OR-ing in exponent) +// 0x40400000: IEEE 754 representation of 3.0f (D3D NORMSHORT encoding bias) +// +// === Half-Float (FP16) Conversion === +// 0x7C00: FP16 exponent mask +// 0x1C000: Exponent bias adjustment for FP16->FP32 conversion +// 0x8000: FP16 sign bit +// 0x03FF: FP16 mantissa mask +// 0x7FFF: FP16 positive infinity/max value +// +// === Packed Integer Masks === +// 0x3FF: 10-bit mask for NORMPACKED32 format (10 bits per component) +// 0xFFFFF: 20-bit mask for NORMPACKED64 format +// 0x1F: 5-bit mask for shift amounts (shifts are mod 32) +// 0xFF: 8-bit mask for byte values +// 0xFFFF: 16-bit mask for halfword values +// +// === D3D Color Format === +// 0x404000FF: D3D color packing constant (ARGB8888) +//============================================================================= + +//============================================================================= +// Vector Floating Point Arithmetic +//============================================================================= + +bool build_vaddfp(BuilderContext& ctx) { + ctx.emit_set_flush_mode(true); + ctx.emit_vec_fp_binary("add"); + return true; +} + +bool build_vsubfp(BuilderContext& ctx) { + ctx.emit_set_flush_mode(true); + ctx.emit_vec_fp_binary("sub"); + return true; +} + +bool build_vmulfp128(BuilderContext& ctx) { + ctx.emit_set_flush_mode(true); + ctx.emit_vec_fp_binary("mul"); + return true; +} + +bool build_vmaddfp(BuilderContext& ctx) { + ctx.emit_set_flush_mode(true); + ctx.println( + "\tsimde_mm_store_ps({}.f32, simde_mm_add_ps(simde_mm_mul_ps(simde_mm_load_ps({}.f32), " + "simde_mm_load_ps({}.f32)), simde_mm_load_ps({}.f32)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2]), + ctx.v(ctx.insn.operands[3])); + return true; +} + +bool build_vnmsubfp(BuilderContext& ctx) { + // vnmsubfp: vD = -(vA * vB - vC) - negation done by XOR with sign bit (0x80000000) + ctx.emit_set_flush_mode(true); + ctx.println( + "\tsimde_mm_store_ps({}.f32, " + "simde_mm_xor_ps(simde_mm_sub_ps(simde_mm_mul_ps(simde_mm_load_ps({}.f32), " + "simde_mm_load_ps({}.f32)), simde_mm_load_ps({}.f32)), " + "simde_mm_castsi128_ps(simde_mm_set1_epi32(int(0x80000000)))));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2]), + ctx.v(ctx.insn.operands[3])); + return true; +} + +bool build_vmaxfp(BuilderContext& ctx) { + ctx.emit_set_flush_mode(true); + ctx.emit_vec_fp_binary("max"); + return true; +} + +bool build_vminfp(BuilderContext& ctx) { + ctx.emit_set_flush_mode(true); + ctx.emit_vec_fp_binary("min"); + return true; +} + +bool build_vrefp(BuilderContext& ctx) { + // TODO: see if we can use rcp safely + ctx.emit_set_flush_mode(true); + ctx.emit_vec_fp_unary_expr("simde_mm_div_ps(simde_mm_set1_ps(1), simde_mm_load_ps({vA}.f32))"); + return true; +} + +bool build_vrsqrtefp(BuilderContext& ctx) { + // TODO: see if we can use rsqrt safely + ctx.emit_set_flush_mode(true); + ctx.emit_vec_fp_unary_expr( + "simde_mm_div_ps(simde_mm_set1_ps(1), simde_mm_sqrt_ps(simde_mm_load_ps({vA}.f32)))"); + return true; +} + +bool build_vexptefp(BuilderContext& ctx) { + // SIMD exp2 estimate (~12-bit precision, matching PPC vexptefp spec) + // Algorithm: exp2(x) = 2^n * poly(f), where n = floor(x), f = x - n + auto vD = ctx.v(ctx.insn.operands[0]); + auto vA = ctx.v(ctx.insn.operands[1]); + ctx.emit_set_flush_mode(true); + ctx.println("\t{{"); + ctx.println("\t\tsimde__m128 x = simde_mm_load_ps({}.f32);", vA); + ctx.println( + "\t\tsimde__m128 n = simde_mm_round_ps(x, " + "SIMDE_MM_FROUND_TO_NEG_INF | SIMDE_MM_FROUND_NO_EXC);"); + ctx.println("\t\tsimde__m128 f = simde_mm_sub_ps(x, n);"); + // 4th-order minimax polynomial for 2^f, f in [0,1), ~12-bit accuracy + ctx.println("\t\tsimde__m128 p = simde_mm_set1_ps(1.8775767e-3f);"); + ctx.println("\t\tp = simde_mm_add_ps(simde_mm_mul_ps(p, f), simde_mm_set1_ps(8.9893397e-3f));"); + ctx.println("\t\tp = simde_mm_add_ps(simde_mm_mul_ps(p, f), simde_mm_set1_ps(5.5826318e-2f));"); + ctx.println("\t\tp = simde_mm_add_ps(simde_mm_mul_ps(p, f), simde_mm_set1_ps(2.4015361e-1f));"); + ctx.println("\t\tp = simde_mm_add_ps(simde_mm_mul_ps(p, f), simde_mm_set1_ps(6.9315308e-1f));"); + ctx.println("\t\tp = simde_mm_add_ps(simde_mm_mul_ps(p, f), simde_mm_set1_ps(1.0f));"); + // Construct 2^n by adding n to the IEEE 754 exponent bias and shifting into place + ctx.println("\t\tsimde__m128i exp_bits = simde_mm_slli_epi32("); + ctx.println("\t\t\tsimde_mm_add_epi32(simde_mm_cvttps_epi32(n), simde_mm_set1_epi32(127)), 23);"); + ctx.println( + "\t\tsimde_mm_store_ps({}.f32, " + "simde_mm_mul_ps(p, simde_mm_castsi128_ps(exp_bits)));", + vD); + ctx.println("\t}}"); + return true; +} + +bool build_vlogefp(BuilderContext& ctx) { + // TODO: vectorize + ctx.emit_set_flush_mode(true); + for (size_t i = 0; i < 4; i++) + ctx.println("\t{}.f32[{}] = log2f({}.f32[{}]);", ctx.v(ctx.insn.operands[0]), i, + ctx.v(ctx.insn.operands[1]), i); + return true; +} + +//============================================================================= +// Vector Dot Products +//============================================================================= + +bool build_vmsum3fp128(BuilderContext& ctx) { + // 3-element dot product accounting for guest->host vector element reversal + // 0xEF = dot(yzw) with result broadcast to all elements (see constants doc) + ctx.emit_set_flush_mode(true); + ctx.println( + "\tsimde_mm_store_ps({}.f32, simde_mm_dp_ps(simde_mm_load_ps({}.f32), " + "simde_mm_load_ps({}.f32), 0xEF));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2])); + return true; +} + +bool build_vmsum4fp128(BuilderContext& ctx) { + // 4-element dot product: 0xFF = all 4 elements, result to all (see constants doc) + ctx.emit_set_flush_mode(true); + ctx.println( + "\tsimde_mm_store_ps({}.f32, simde_mm_dp_ps(simde_mm_load_ps({}.f32), " + "simde_mm_load_ps({}.f32), 0xFF));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2])); + return true; +} + +//============================================================================= +// Vector Rounding +//============================================================================= + +bool build_vrfim(BuilderContext& ctx) { + ctx.emit_set_flush_mode(true); + ctx.emit_vec_fp_unary_expr( + "simde_mm_round_ps(simde_mm_load_ps({vA}.f32), " + "SIMDE_MM_FROUND_TO_NEG_INF | SIMDE_MM_FROUND_NO_EXC)"); + return true; +} + +bool build_vrfin(BuilderContext& ctx) { + ctx.emit_set_flush_mode(true); + ctx.emit_vec_fp_unary_expr( + "simde_mm_round_ps(simde_mm_load_ps({vA}.f32), " + "SIMDE_MM_FROUND_TO_NEAREST_INT | SIMDE_MM_FROUND_NO_EXC)"); + return true; +} + +bool build_vrfip(BuilderContext& ctx) { + ctx.emit_set_flush_mode(true); + ctx.emit_vec_fp_unary_expr( + "simde_mm_round_ps(simde_mm_load_ps({vA}.f32), " + "SIMDE_MM_FROUND_TO_POS_INF | SIMDE_MM_FROUND_NO_EXC)"); + return true; +} + +bool build_vrfiz(BuilderContext& ctx) { + ctx.emit_set_flush_mode(true); + ctx.emit_vec_fp_unary_expr( + "simde_mm_round_ps(simde_mm_load_ps({vA}.f32), " + "SIMDE_MM_FROUND_TO_ZERO | SIMDE_MM_FROUND_NO_EXC)"); + return true; +} + +//============================================================================= +// Vector Integer Arithmetic +//============================================================================= + +bool build_vaddsbs(BuilderContext& ctx) { + ctx.emit_vec_int_binary("adds_epi8", "s8"); + return true; +} + +bool build_vaddshs(BuilderContext& ctx) { + ctx.emit_vec_int_binary("adds_epi16", "s16"); + return true; +} + +bool build_vaddsws(BuilderContext& ctx) { + // vaddsws: Vector Add Signed Word Saturate + auto vD = ctx.v(ctx.insn.operands[0]); + auto vA = ctx.v(ctx.insn.operands[1]); + auto vB = ctx.v(ctx.insn.operands[2]); + + ctx.println("\t{{"); + // No direct SSE intrinsic, so use overflow detection and blend + ctx.println("\t\tsimde__m128i a = simde_mm_load_si128((simde__m128i*){}.u8);", vA); + ctx.println("\t\tsimde__m128i b = simde_mm_load_si128((simde__m128i*){}.u8);", vB); + ctx.println("\t\tsimde__m128i sum = simde_mm_add_epi32(a, b);"); + // Overflow if: (a ^ sum) & (b ^ sum) has MSB set (signs of a,b match but sum differs) + ctx.println( + "\t\tsimde__m128i overflow = simde_mm_and_si128(simde_mm_xor_si128(a, sum), " + "simde_mm_xor_si128(b, sum));"); + // Saturation value: if a positive (MSB=0), use INT32_MAX; + // if negative, use INT32_MIN (a >> 31) gives all 1s if negative, all 0s + // if positive XOR with 0x7FFFFFFF: negative -> 0x80000000, positive -> 0x7FFFFFFF + ctx.println( + "\t\tsimde__m128i sat_val = simde_mm_xor_si128(simde_mm_srai_epi32(a, 31), " + "simde_mm_set1_epi32(0x7FFFFFFF));"); + // Blend: select sat_val where overflow MSB is set, else sum + ctx.println( + "\t\tsimde_mm_store_si128((simde__m128i*){}.u8, simde_mm_blendv_epi8(sum, sat_val, " + "overflow));", + vD); + ctx.println("\t}}"); + return true; +} + +bool build_vaddubm(BuilderContext& ctx) { + ctx.emit_vec_int_binary("add_epi8", "u8"); + return true; +} + +bool build_vaddubs(BuilderContext& ctx) { + ctx.emit_vec_int_binary("adds_epu8", "u8"); + return true; +} + +bool build_vadduhm(BuilderContext& ctx) { + ctx.emit_vec_int_binary("add_epi16", "u16"); + return true; +} + +bool build_vadduwm(BuilderContext& ctx) { + ctx.emit_vec_int_binary("add_epi32", "u32"); + return true; +} + +bool build_vadduws(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u32, " + "rex::ppc::simde_mm_adds_epu32(simde_mm_load_si128((simde__m128i*){}.u32), " + "simde_mm_load_si128((simde__m128i*){}.u32)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2])); + return true; +} + +bool build_vadduhs(BuilderContext& ctx) { + ctx.emit_vec_int_binary("adds_epu16", "u16"); + return true; +} + +bool build_vsubsws(BuilderContext& ctx) { + // TODO: vectorize + for (size_t i = 0; i < 4; i++) { + ctx.println("\t{}.s64 = int64_t({}.s32[{}]) - int64_t({}.s32[{}]);", ctx.temp(), + ctx.v(ctx.insn.operands[1]), i, ctx.v(ctx.insn.operands[2]), i); + ctx.println("\t{}.s32[{}] = {}.s64 > INT_MAX ? INT_MAX : {}.s64 < INT_MIN ? INT_MIN : {}.s64;", + ctx.v(ctx.insn.operands[0]), i, ctx.temp(), ctx.temp(), ctx.temp()); + } + return true; +} + +bool build_vsububm(BuilderContext& ctx) { + ctx.emit_vec_int_binary("sub_epi8", "u8"); + return true; +} + +bool build_vsububs(BuilderContext& ctx) { + ctx.emit_vec_int_binary("subs_epu8", "u8"); + return true; +} + +bool build_vsubuws(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u32, " + "simde_mm_sub_epi32(simde_mm_load_si128((simde__m128i*) {}.u32), " + "simde_mm_min_epu32(simde_mm_load_si128((simde__m128i*){}.u32), " + "simde_mm_load_si128((simde__m128i*){}.u32))));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[1]), + ctx.v(ctx.insn.operands[2])); + return true; +} + +bool build_vsubuhs(BuilderContext& ctx) { + ctx.emit_vec_int_binary("subs_epu16", "u16"); + return true; +} + +bool build_vsubuhm(BuilderContext& ctx) { + ctx.emit_vec_int_binary("sub_epi16", "u16"); + return true; +} + +bool build_vsubuwm(BuilderContext& ctx) { + ctx.emit_vec_int_binary("sub_epi32", "u32"); + return true; +} + +bool build_vmaxsw(BuilderContext& ctx) { + ctx.emit_vec_int_binary("max_epi32", "s32"); + return true; +} + +bool build_vmaxsh(BuilderContext& ctx) { + ctx.emit_vec_int_binary("max_epi16", "s16"); + return true; +} + +bool build_vmaxsb(BuilderContext& ctx) { + ctx.emit_vec_int_binary("max_epi8", "s8"); + return true; +} + +bool build_vminsh(BuilderContext& ctx) { + ctx.emit_vec_int_binary("min_epi16", "s16"); + return true; +} + +bool build_vminsb(BuilderContext& ctx) { + ctx.emit_vec_int_binary("min_epi8", "s8"); + return true; +} + +bool build_vminsw(BuilderContext& ctx) { + ctx.emit_vec_int_binary("min_epi32", "s32"); + return true; +} + +bool build_vmaxuh(BuilderContext& ctx) { + ctx.emit_vec_int_binary("max_epu16", "u16"); + return true; +} + +bool build_vminuh(BuilderContext& ctx) { + ctx.emit_vec_int_binary("min_epu16", "u16"); + return true; +} + +bool build_vminuw(BuilderContext& ctx) { + ctx.emit_vec_int_binary("min_epu32", "u32"); + return true; +} + +bool build_vsubsbs(BuilderContext& ctx) { + ctx.emit_vec_int_binary("subs_epi8", "s8"); + return true; +} + +bool build_vmaxub(BuilderContext& ctx) { + ctx.emit_vec_int_binary("max_epu8", "u8"); + return true; +} + +bool build_vminub(BuilderContext& ctx) { + ctx.emit_vec_int_binary("min_epu8", "u8"); + return true; +} + +bool build_vsubshs(BuilderContext& ctx) { + ctx.emit_vec_int_binary("subs_epi16", "s16"); + return true; +} + +//============================================================================= +// Vector Average +//============================================================================= + +bool build_vavgsb(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "rex::ppc::simde_mm_avg_epi8(simde_mm_load_si128((simde__m128i*){}.u8), " + "simde_mm_load_si128((simde__m128i*){}.u8)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2])); + return true; +} + +bool build_vavgsh(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u16, " + "rex::ppc::simde_mm_avg_epi16(simde_mm_load_si128((simde__m128i*){}.u16), " + "simde_mm_load_si128((simde__m128i*){}.u16)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2])); + return true; +} + +bool build_vavgsw(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.s32, " + "rex::ppc::simde_mm_avg_epi32(" + "simde_mm_load_si128((simde__m128i*){}.s32), " + "simde_mm_load_si128((simde__m128i*){}.s32)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2])); + return true; +} + +bool build_vavgub(BuilderContext& ctx) { + ctx.emit_vec_int_binary("avg_epu8", "u8"); + return true; +} + +bool build_vavguh(BuilderContext& ctx) { + ctx.emit_vec_int_binary("avg_epu16", "u16"); + return true; +} + +//============================================================================= +// Vector Logical +//============================================================================= + +bool build_vand(BuilderContext& ctx) { + ctx.emit_vec_int_binary("and_si128", "u8"); + return true; +} + +bool build_vandc128(BuilderContext& ctx) { + // vandc128: vD = vA & ~vB (simde_mm_andnot_si128 has reversed operand semantics) + ctx.emit_vec_int_binary_swapped("andnot_si128", "u8"); + return true; +} + +bool build_vandc(BuilderContext& ctx) { + // vandc: vD = vA & ~vB (simde_mm_andnot_si128 has reversed operand semantics) + ctx.emit_vec_int_binary_swapped("andnot_si128", "u8"); + return true; +} + +bool build_vor(BuilderContext& ctx) { + ctx.print("\tsimde_mm_store_si128((simde__m128i*){}.u8, ", ctx.v(ctx.insn.operands[0])); + + if (ctx.insn.operands[1] != ctx.insn.operands[2]) + ctx.println( + "simde_mm_or_si128(simde_mm_load_si128((simde__m128i*){}.u8), " + "simde_mm_load_si128((simde__m128i*){}.u8)));", + ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2])); + else + ctx.println("simde_mm_load_si128((simde__m128i*){}.u8));", ctx.v(ctx.insn.operands[1])); + + return true; +} + +bool build_vxor(BuilderContext& ctx) { + ctx.print("\tsimde_mm_store_si128((simde__m128i*){}.u8, ", ctx.v(ctx.insn.operands[0])); + + if (ctx.insn.operands[1] != ctx.insn.operands[2]) + ctx.println( + "simde_mm_xor_si128(simde_mm_load_si128((simde__m128i*){}.u8), " + "simde_mm_load_si128((simde__m128i*){}.u8)));", + ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2])); + else + ctx.println("simde_mm_setzero_si128());"); + + return true; +} + +bool build_vnor(BuilderContext& ctx) { + // vnor: vD = ~(vA | vB) + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "simde_mm_xor_si128(" + "simde_mm_or_si128(" + "simde_mm_load_si128((simde__m128i*){}.u8), " + "simde_mm_load_si128((simde__m128i*){}.u8)), " + "simde_mm_set1_epi32(-1)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2])); + return true; +} + +bool build_vsel(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "simde_mm_or_si128(simde_mm_andnot_si128(simde_mm_load_si128((simde__m128i*){}.u8), " + "simde_mm_load_si128((simde__m128i*){}.u8)), " + "simde_mm_and_si128(simde_mm_load_si128((simde__m128i*){}.u8), " + "simde_mm_load_si128((simde__m128i*){}.u8))));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[3]), ctx.v(ctx.insn.operands[1]), + ctx.v(ctx.insn.operands[3]), ctx.v(ctx.insn.operands[2])); + return true; +} + +//============================================================================= +// Vector Compare +//============================================================================= + +bool build_vcmpbfp(BuilderContext& ctx) { + ctx.emit_set_flush_mode(true); + // vcmpbfp: Vector Compare Bounds Floating Point + // For each element i: + // bit 0 (0x80000000) = 1 if vSrcA[i] > vSrcB[i] + // bit 1 (0x40000000) = 1 if vSrcA[i] < -vSrcB[i] + auto vA = ctx.v(ctx.insn.operands[1]); + auto vB = ctx.v(ctx.insn.operands[2]); + auto vD = ctx.v(ctx.insn.operands[0]); + + // Use v_temp as intermediate storage + // gt_mask = (vA > vB) & 0x80000000 + ctx.println( + "\tsimde_mm_store_ps({}.f32, simde_mm_and_ps(simde_mm_cmpgt_ps(simde_mm_load_ps({}.f32), " + "simde_mm_load_ps({}.f32)), simde_mm_castsi128_ps(simde_mm_set1_epi32(int(0x80000000)))));", + ctx.v_temp(), vA, vB); + // lt_neg_mask = (vA < -vB) & 0x40000000 + ctx.println( + "\tsimde_mm_store_ps({}.f32, simde_mm_and_ps(simde_mm_cmplt_ps(simde_mm_load_ps({}.f32), " + "simde_mm_xor_ps(simde_mm_load_ps({}.f32), " + "simde_mm_castsi128_ps(simde_mm_set1_epi32(int(0x80000000))))), " + "simde_mm_castsi128_ps(simde_mm_set1_epi32(int(0x40000000)))));", + vD, vA, vB); + // result = gt_mask | lt_neg_mask + ctx.println( + "\tsimde_mm_store_ps({}.f32, simde_mm_or_ps(simde_mm_load_ps({}.f32), " + "simde_mm_load_ps({}.f32)));", + vD, ctx.v_temp(), vD); + + // CR6 from vD: movemask_ps only checks bit 31, but lower-bound violations only + // set bit 30. Shift left by 1 to move bit 30 into bit 31, then OR with original + // so movemask detects both upper and lower bound violations. + if (isRecordForm(ctx.insn)) + ctx.println( + "\t{}.setFromMask(simde_mm_castsi128_ps(simde_mm_or_si128(" + "simde_mm_load_si128((simde__m128i*){}.f32), " + "simde_mm_slli_epi32(simde_mm_load_si128((simde__m128i*){}.f32), 1))), 0xF);", + ctx.cr(6), vD, vD); + return true; +} + +bool build_vcmpeqfp(BuilderContext& ctx) { + ctx.emit_set_flush_mode(true); + ctx.emit_vec_fp_binary("cmpeq"); + if (isRecordForm(ctx.insn)) + ctx.println("\t{}.setFromMask(simde_mm_load_ps({}.f32), 0xF);", ctx.cr(6), + ctx.v(ctx.insn.operands[0])); + return true; +} + +bool build_vcmpequb(BuilderContext& ctx) { + ctx.emit_vec_int_binary("cmpeq_epi8", "u8"); + if (isRecordForm(ctx.insn)) + ctx.println("\t{}.setFromMask(simde_mm_load_si128((simde__m128i*){}.u8), 0xFFFF);", ctx.cr(6), + ctx.v(ctx.insn.operands[0])); + return true; +} + +bool build_vcmpequh(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "simde_mm_cmpeq_epi16(simde_mm_load_si128((simde__m128i*){}.u16), " + "simde_mm_load_si128((simde__m128i*){}.u16)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2])); + if (isRecordForm(ctx.insn)) + ctx.println("\t{}.setFromMask(simde_mm_load_si128((simde__m128i*){}.u16), 0xFFFF);", ctx.cr(6), + ctx.v(ctx.insn.operands[0])); + return true; +} + +bool build_vcmpequw(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "simde_mm_cmpeq_epi32(simde_mm_load_si128((simde__m128i*){}.u32), " + "simde_mm_load_si128((simde__m128i*){}.u32)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2])); + if (isRecordForm(ctx.insn)) + ctx.println("\t{}.setFromMask(simde_mm_load_ps({}.f32), 0xF);", ctx.cr(6), + ctx.v(ctx.insn.operands[0])); + return true; +} + +bool build_vcmpgefp(BuilderContext& ctx) { + ctx.emit_set_flush_mode(true); + ctx.emit_vec_fp_binary("cmpge"); + if (isRecordForm(ctx.insn)) + ctx.println("\t{}.setFromMask(simde_mm_load_ps({}.f32), 0xF);", ctx.cr(6), + ctx.v(ctx.insn.operands[0])); + return true; +} + +bool build_vcmpgtfp(BuilderContext& ctx) { + ctx.emit_set_flush_mode(true); + ctx.emit_vec_fp_binary("cmpgt"); + if (isRecordForm(ctx.insn)) + ctx.println("\t{}.setFromMask(simde_mm_load_ps({}.f32), 0xF);", ctx.cr(6), + ctx.v(ctx.insn.operands[0])); + return true; +} + +bool build_vcmpgtub(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "rex::ppc::simde_mm_cmpgt_epu8(simde_mm_load_si128((simde__m128i*){}.u8), " + "simde_mm_load_si128((simde__m128i*){}.u8)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2])); + if (isRecordForm(ctx.insn)) + ctx.println("\t{}.setFromMask(simde_mm_load_si128((simde__m128i*){}.u8), 0xFFFF);", ctx.cr(6), + ctx.v(ctx.insn.operands[0])); + return true; +} + +bool build_vcmpgtuh(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "rex::ppc::simde_mm_cmpgt_epu16(simde_mm_load_si128((simde__m128i*){}.u16), " + "simde_mm_load_si128((simde__m128i*){}.u16)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2])); + if (isRecordForm(ctx.insn)) + ctx.println("\t{}.setFromMask(simde_mm_load_si128((simde__m128i*){}.u16), 0xFFFF);", ctx.cr(6), + ctx.v(ctx.insn.operands[0])); + return true; +} + +bool build_vcmpgtuw(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u32, " + "simde_mm_cmpgt_epi32(simde_mm_xor_si128(simde_mm_load_si128((simde__m128i*){}.u32), " + "simde_mm_set1_epi32((int32_t)0x80000000)), " + "simde_mm_xor_si128(simde_mm_load_si128((simde__m128i*){}.u32), " + "simde_mm_set1_epi32((int32_t)0x80000000))));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2])); + + if (isRecordForm(ctx.insn)) + ctx.println( + "\t{}.setFromMask(simde_mm_castsi128_ps(simde_mm_load_si128((simde__m128i*){}.u32)), 0xF);", + ctx.cr(6), ctx.v(ctx.insn.operands[0])); + return true; +} + +bool build_vcmpgtsb(BuilderContext& ctx) { + ctx.emit_vec_int_binary("cmpgt_epi8", "u8"); + if (isRecordForm(ctx.insn)) + ctx.println("\t{}.setFromMask(simde_mm_load_si128((simde__m128i*){}.u8), 0xFFFF);", ctx.cr(6), + ctx.v(ctx.insn.operands[0])); + return true; +} + +bool build_vcmpgtsh(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "simde_mm_cmpgt_epi16(simde_mm_load_si128((simde__m128i*){}.u16), " + "simde_mm_load_si128((simde__m128i*){}.u16)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2])); + if (isRecordForm(ctx.insn)) + ctx.println("\t{}.setFromMask(simde_mm_load_si128((simde__m128i*){}.u16), 0xFFFF);", ctx.cr(6), + ctx.v(ctx.insn.operands[0])); + return true; +} + +bool build_vcmpgtsw(BuilderContext& ctx) { + ctx.emit_vec_int_binary("cmpgt_epi32", "u32"); + if (isRecordForm(ctx.insn)) + ctx.println( + "\t{}.setFromMask(simde_mm_castsi128_ps(simde_mm_load_si128((simde__m128i*){}.u32)), 0xF);", + ctx.cr(6), ctx.v(ctx.insn.operands[0])); + return true; +} + +//============================================================================= +// Vector Conversion +//============================================================================= + +bool build_vctsxs(BuilderContext& ctx) { + ctx.emit_set_flush_mode(true); + ctx.print("\tsimde_mm_store_si128((simde__m128i*){}.s32, rex::ppc::simde_mm_vctsxs(", + ctx.v(ctx.insn.operands[0])); + if (ctx.insn.operands[2] != 0) + ctx.println("simde_mm_mul_ps(simde_mm_load_ps({}.f32), simde_mm_set1_ps({}))));", + ctx.v(ctx.insn.operands[1]), 1u << ctx.insn.operands[2]); + else + ctx.println("simde_mm_load_ps({}.f32)));", ctx.v(ctx.insn.operands[1])); + return true; +} + +bool build_vcfsx(BuilderContext& ctx) { + ctx.emit_set_flush_mode(true); + ctx.print("\tsimde_mm_store_ps({}.f32, ", ctx.v(ctx.insn.operands[0])); + if (ctx.insn.operands[2] != 0) { + const float value = std::ldexp(1.0f, -static_cast(ctx.insn.operands[2])); + ctx.println( + "simde_mm_mul_ps(simde_mm_cvtepi32_ps(simde_mm_load_si128((simde__m128i*){}.u32)), " + "simde_mm_castsi128_ps(simde_mm_set1_epi32(int(0x{:X})))));", + ctx.v(ctx.insn.operands[1]), *reinterpret_cast(&value)); + } else { + ctx.println("simde_mm_cvtepi32_ps(simde_mm_load_si128((simde__m128i*){}.u32)));", + ctx.v(ctx.insn.operands[1])); + } + return true; +} + +bool build_vcfux(BuilderContext& ctx) { + ctx.emit_set_flush_mode(true); + ctx.print("\tsimde_mm_store_ps({}.f32, ", ctx.v(ctx.insn.operands[0])); + if (ctx.insn.operands[2] != 0) { + const float value = std::ldexp(1.0f, -static_cast(ctx.insn.operands[2])); + ctx.println( + "simde_mm_mul_ps(rex::ppc::simde_mm_cvtepu32_ps_(simde_mm_load_si128((simde__m128i*){}.u32)" + "), " + "simde_mm_castsi128_ps(simde_mm_set1_epi32(int(0x{:X})))));", + ctx.v(ctx.insn.operands[1]), *reinterpret_cast(&value)); + } else { + ctx.println("rex::ppc::simde_mm_cvtepu32_ps_(simde_mm_load_si128((simde__m128i*){}.u32)));", + ctx.v(ctx.insn.operands[1])); + } + return true; +} + +bool build_vctuxs(BuilderContext& ctx) { + // Vector Convert To Unsigned Fixed-Point Word Saturate + ctx.emit_set_flush_mode(true); + ctx.print("\tsimde_mm_store_si128((simde__m128i*){}.u32, rex::ppc::simde_mm_vctuxs(", + ctx.v(ctx.insn.operands[0])); + if (ctx.insn.operands[2] != 0) + ctx.println("simde_mm_mul_ps(simde_mm_load_ps({}.f32), simde_mm_set1_ps({}))));", + ctx.v(ctx.insn.operands[1]), 1u << ctx.insn.operands[2]); + else + ctx.println("simde_mm_load_ps({}.f32)));", ctx.v(ctx.insn.operands[1])); + return true; +} + +//============================================================================= +// Vector Merge +//============================================================================= + +bool build_vmrghb(BuilderContext& ctx) { + ctx.emit_vec_int_binary_swapped("unpackhi_epi8", "u8"); + return true; +} + +bool build_vmrghh(BuilderContext& ctx) { + ctx.emit_vec_int_binary_swapped("unpackhi_epi16", "u16"); + return true; +} + +bool build_vmrghw(BuilderContext& ctx) { + ctx.emit_vec_int_binary_swapped("unpackhi_epi32", "u32"); + return true; +} + +bool build_vmrglb(BuilderContext& ctx) { + ctx.emit_vec_int_binary_swapped("unpacklo_epi8", "u8"); + return true; +} + +bool build_vmrglh(BuilderContext& ctx) { + ctx.emit_vec_int_binary_swapped("unpacklo_epi16", "u16"); + return true; +} + +bool build_vmrglw(BuilderContext& ctx) { + ctx.emit_vec_int_binary_swapped("unpacklo_epi32", "u32"); + return true; +} + +//============================================================================= +// Vector Permute +//============================================================================= + +bool build_vperm(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "rex::ppc::simde_mm_perm_epi8_(simde_mm_load_si128((simde__m128i*){}.u8), " + "simde_mm_load_si128((simde__m128i*){}.u8), simde_mm_load_si128((simde__m128i*){}.u8)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2]), + ctx.v(ctx.insn.operands[3])); + return true; +} + +bool build_vpermwi128(BuilderContext& ctx) { + // NOTE: accounting for full vector reversal here + uint32_t x = 3 - (ctx.insn.operands[2] & 0x3); + uint32_t y = 3 - ((ctx.insn.operands[2] >> 2) & 0x3); + uint32_t z = 3 - ((ctx.insn.operands[2] >> 4) & 0x3); + uint32_t w = 3 - ((ctx.insn.operands[2] >> 6) & 0x3); + uint32_t perm = x | (y << 2) | (z << 4) | (w << 6); + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u32, " + "simde_mm_shuffle_epi32(simde_mm_load_si128((simde__m128i*){}.u32), 0x{:X}));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), perm); + return true; +} + +bool build_vrlimi128(BuilderContext& ctx) { + constexpr size_t shuffles[] = {SIMDE_MM_SHUFFLE(3, 2, 1, 0), SIMDE_MM_SHUFFLE(2, 1, 0, 3), + SIMDE_MM_SHUFFLE(1, 0, 3, 2), SIMDE_MM_SHUFFLE(0, 3, 2, 1)}; + ctx.println( + "\tsimde_mm_store_ps({}.f32, simde_mm_blend_ps(simde_mm_load_ps({}.f32), " + "simde_mm_permute_ps(simde_mm_load_ps({}.f32), {}), {}));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), + shuffles[ctx.insn.operands[3]], ctx.insn.operands[2]); + return true; +} + +//============================================================================= +// Vector Shift +//============================================================================= + +bool build_vslb(BuilderContext& ctx) { + ctx.emit_vec_var_shift("sllv", "epi8", 0x7); + return true; +} + +bool build_vsldoi(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "simde_mm_alignr_epi8(simde_mm_load_si128((simde__m128i*){}.u8), " + "simde_mm_load_si128((simde__m128i*){}.u8), {}));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2]), + 16 - ctx.insn.operands[3]); + return true; +} + +bool build_vslh(BuilderContext& ctx) { + ctx.emit_vec_var_shift("sllv", "epi16", 0xF); + return true; +} + +bool build_vsrh(BuilderContext& ctx) { + ctx.emit_vec_var_shift("srlv", "epi16", 0xF); + return true; +} + +bool build_vsrb(BuilderContext& ctx) { + // TODO(tomc): vectorize + for (size_t i = 0; i < 16; i++) + ctx.println("\t{}.u8[{}] = {}.u8[{}] >> ({}.u8[{}] & 0x7);", ctx.v(ctx.insn.operands[0]), i, + ctx.v(ctx.insn.operands[1]), i, ctx.v(ctx.insn.operands[2]), i); + return true; +} + +bool build_vsrab(BuilderContext& ctx) { + // TODO(tomc): vectorize + for (size_t i = 0; i < 16; i++) + ctx.println("\t{}.s8[{}] = {}.s8[{}] >> ({}.u8[{}] & 0x7);", ctx.v(ctx.insn.operands[0]), i, + ctx.v(ctx.insn.operands[1]), i, ctx.v(ctx.insn.operands[2]), i); + return true; +} + +bool build_vsrah(BuilderContext& ctx) { + ctx.emit_vec_var_shift("srav", "epi16", 0xF); + return true; +} + +bool build_vrlh(BuilderContext& ctx) { + auto vD = ctx.v(ctx.insn.operands[0]); + auto vA = ctx.v(ctx.insn.operands[1]); + auto vB = ctx.v(ctx.insn.operands[2]); + ctx.println("\t{{"); + ctx.println("\t\tsimde__m128i a = simde_mm_load_si128((simde__m128i*){}.u8);", vA); + ctx.println("\t\tsimde__m128i sh = simde_mm_and_si128("); + ctx.println("\t\t\tsimde_mm_load_si128((simde__m128i*){}.u8), simde_mm_set1_epi16(0xF));", vB); + ctx.println("\t\tsimde__m128i rsh = simde_mm_sub_epi16(simde_mm_set1_epi16(16), sh);"); + ctx.println("\t\tsimde__m128i result = simde_mm_or_si128("); + ctx.println("\t\t\trex::ppc::simde_mm_sllv_epi16(a, sh),"); + ctx.println("\t\t\trex::ppc::simde_mm_srlv_epi16(a, rsh));"); + ctx.println("\t\tsimde_mm_store_si128((simde__m128i*){}.u8, result);", vD); + ctx.println("\t}}"); + return true; +} + +bool build_vrlw(BuilderContext& ctx) { + // TODO(tomc): vectorize + for (size_t i = 0; i < 4; i++) { + ctx.println("\t{{ uint32_t sh = {}.u32[{}] & 0x1F;", ctx.v(ctx.insn.operands[2]), i); + ctx.println("\t{}.u32[{}] = ({}.u32[{}] << sh) | (sh ? ({}.u32[{}] >> (32 - sh)) : 0); }}", + ctx.v(ctx.insn.operands[0]), i, ctx.v(ctx.insn.operands[1]), i, + ctx.v(ctx.insn.operands[1]), i); + } + return true; +} + +bool build_vsl(BuilderContext& ctx) { + // Vector Shift Left (128-bit) - shift entire vector left by bits specified in low 3 bits of vB + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "rex::ppc::simde_mm_vsl(simde_mm_load_si128((simde__m128i*){}.u8), " + "simde_mm_load_si128((simde__m128i*){}.u8)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2])); + return true; +} + +bool build_vslo(BuilderContext& ctx) { + // Vector Shift Left by Octet - shift entire vector left by bytes specified in bits 121:124 of vB + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "rex::ppc::simde_mm_vslo(simde_mm_load_si128((simde__m128i*){}.u8), " + "simde_mm_load_si128((simde__m128i*){}.u8)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2])); + return true; +} + +bool build_vsro(BuilderContext& ctx) { + // Vector Shift Right by Octet - shift entire vector right by bytes specified in bits 121:124 of + // vB + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "rex::ppc::simde_mm_vsro(simde_mm_load_si128((simde__m128i*){}.u8), " + "simde_mm_load_si128((simde__m128i*){}.u8)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2])); + return true; +} + +bool build_vslw(BuilderContext& ctx) { + auto vD = ctx.v(ctx.insn.operands[0]); + auto vA = ctx.v(ctx.insn.operands[1]); + auto vB = ctx.v(ctx.insn.operands[2]); + ctx.println("\t{{"); + ctx.println("\t\tsimde__m128i a = simde_mm_load_si128((simde__m128i*){}.u8);", vA); + ctx.println("\t\tsimde__m128i b = simde_mm_load_si128((simde__m128i*){}.u8);", vB); + ctx.println("\t\tsimde__m128i shift = simde_mm_and_si128(b, simde_mm_set1_epi32(0x1F));"); + ctx.println( + "\t\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "simde_mm_sllv_epi32(a, shift));", + vD); + ctx.println("\t}}"); + return true; +} + +bool build_vsr(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "rex::ppc::simde_mm_vsr(simde_mm_load_si128((simde__m128i*){}.u8), " + "simde_mm_load_si128((simde__m128i*){}.u8)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[2])); + return true; +} + +bool build_vsraw(BuilderContext& ctx) { + // TODO(tomc): vectorize + for (size_t i = 0; i < 4; i++) + ctx.println("\t{}.s32[{}] = {}.s32[{}] >> ({}.u8[{}] & 0x1F);", ctx.v(ctx.insn.operands[0]), i, + ctx.v(ctx.insn.operands[1]), i, ctx.v(ctx.insn.operands[2]), i * 4); + return true; +} + +bool build_vsrw(BuilderContext& ctx) { + // TODO(tomc): vectorize + for (size_t i = 0; i < 4; i++) + ctx.println("\t{}.u32[{}] = {}.u32[{}] >> ({}.u8[{}] & 0x1F);", ctx.v(ctx.insn.operands[0]), i, + ctx.v(ctx.insn.operands[1]), i, ctx.v(ctx.insn.operands[2]), i * 4); + return true; +} + +//============================================================================= +// Vector Splat +//============================================================================= + +bool build_vspltb(BuilderContext& ctx) { + // NOTE: accounting for full vector reversal here + uint32_t perm = 15 - ctx.insn.operands[2]; + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "simde_mm_shuffle_epi8(simde_mm_load_si128((simde__m128i*){}.u8), " + "simde_mm_set1_epi8(char(0x{:X}))));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), perm); + return true; +} + +bool build_vsplth(BuilderContext& ctx) { + // NOTE: accounting for full vector reversal here + uint32_t perm = 7 - ctx.insn.operands[2]; + perm = (perm * 2) | ((perm * 2 + 1) << 8); + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u16, " + "simde_mm_shuffle_epi8(simde_mm_load_si128((simde__m128i*){}.u16), " + "simde_mm_set1_epi16(short(0x{:X}))));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), perm); + return true; +} + +bool build_vspltisb(BuilderContext& ctx) { + // Sign-extend 5-bit immediate to 8-bit + int8_t imm5 = static_cast(ctx.insn.operands[1] << 3) >> 3; + ctx.println("\tsimde_mm_store_si128((simde__m128i*){}.u8, simde_mm_set1_epi8(char(0x{:X})));", + ctx.v(ctx.insn.operands[0]), static_cast(imm5)); + return true; +} + +bool build_vspltisw(BuilderContext& ctx) { + // Sign-extend 5-bit immediate to 32-bit + int8_t imm5 = static_cast(ctx.insn.operands[1] << 3) >> 3; + ctx.println("\tsimde_mm_store_si128((simde__m128i*){}.u32, simde_mm_set1_epi32(int(0x{:X})));", + ctx.v(ctx.insn.operands[0]), static_cast(static_cast(imm5))); + return true; +} + +bool build_vspltish(BuilderContext& ctx) { + // Sign-extend 5-bit immediate to 16-bit + int8_t imm5 = static_cast(ctx.insn.operands[1] << 3) >> 3; + ctx.println("\tsimde_mm_store_si128((simde__m128i*){}.s16, simde_mm_set1_epi16(short(0x{:X})));", + ctx.v(ctx.insn.operands[0]), static_cast(static_cast(imm5))); + return true; +} + +bool build_vspltw(BuilderContext& ctx) { + // NOTE: accounting for full vector reversal here + uint32_t perm = 3 - ctx.insn.operands[2]; + perm |= (perm << 2) | (perm << 4) | (perm << 6); + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u32, " + "simde_mm_shuffle_epi32(simde_mm_load_si128((simde__m128i*){}.u32), 0x{:X}));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), perm); + return true; +} + +//============================================================================= +// Vector Pack +//============================================================================= + +bool build_vpkshus(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "simde_mm_packus_epi16(simde_mm_load_si128((simde__m128i*){}.s16), " + "simde_mm_load_si128((simde__m128i*){}.s16)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[2]), ctx.v(ctx.insn.operands[1])); + return true; +} + +bool build_vpkuhum(BuilderContext& ctx) { + // Vector Pack Unsigned Halfword Unsigned Modulo - pack low 8 bits from each halfword + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u8, " + "simde_mm_packus_epi16(simde_mm_and_si128(simde_mm_load_si128((simde__m128i*){}.u16), " + "simde_mm_set1_epi16(0xFF)), simde_mm_and_si128(simde_mm_load_si128((simde__m128i*){}.u16), " + "simde_mm_set1_epi16(0xFF))));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[2]), ctx.v(ctx.insn.operands[1])); + return true; +} + +bool build_vpkuhus(BuilderContext& ctx) { + // Vector Pack Unsigned Halfword Unsigned Saturate + // NOTE(tomc): _mm_packus_epi16 treats inputs as signed, so we need custom saturation for + // unsigned. Unsigned halfwords >= 0x8000 would be interpreted as negative and clamped to 0 + // instead of 0xFF. + for (size_t i = 0; i < 8; i++) { + ctx.println("\t{}.u8[{}] = {}.u16[{}] > 0xFF ? 0xFF : (uint8_t){}.u16[{}];", + ctx.v(ctx.insn.operands[0]), 15 - i, ctx.v(ctx.insn.operands[1]), 7 - i, + ctx.v(ctx.insn.operands[1]), 7 - i); + ctx.println("\t{}.u8[{}] = {}.u16[{}] > 0xFF ? 0xFF : (uint8_t){}.u16[{}];", + ctx.v(ctx.insn.operands[0]), 7 - i, ctx.v(ctx.insn.operands[2]), 7 - i, + ctx.v(ctx.insn.operands[2]), 7 - i); + } + return true; +} + +bool build_vpkuwum(BuilderContext& ctx) { + // Vector Pack Unsigned Word Unsigned Modulo - pack low 16 bits from each word + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u16, " + "simde_mm_packus_epi32(simde_mm_and_si128(simde_mm_load_si128((simde__m128i*){}.u32), " + "simde_mm_set1_epi32(0xFFFF)), " + "simde_mm_and_si128(simde_mm_load_si128((simde__m128i*){}.u32), " + "simde_mm_set1_epi32(0xFFFF))));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[2]), ctx.v(ctx.insn.operands[1])); + return true; +} + +bool build_vpkuwus(BuilderContext& ctx) { + // Vector Pack Unsigned Word Unsigned Saturate + + // NOTE(tomc): _mm_packus_epi32 treats inputs as signed, so we need custom saturation for unsigned + // Saturate each u32 to [0, 0xFFFF], then pack to u16 + for (size_t i = 0; i < 4; i++) { + ctx.println("\t{}.u16[{}] = {}.u32[{}] > 0xFFFF ? 0xFFFF : (uint16_t){}.u32[{}];", + ctx.v(ctx.insn.operands[0]), 7 - i, ctx.v(ctx.insn.operands[1]), 3 - i, + ctx.v(ctx.insn.operands[1]), 3 - i); + ctx.println("\t{}.u16[{}] = {}.u32[{}] > 0xFFFF ? 0xFFFF : (uint16_t){}.u32[{}];", + ctx.v(ctx.insn.operands[0]), 3 - i, ctx.v(ctx.insn.operands[2]), 3 - i, + ctx.v(ctx.insn.operands[2]), 3 - i); + } + return true; +} + +bool build_vpkshss(BuilderContext& ctx) { + // Vector Pack Signed Halfword Signed Saturate + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.s8, " + "simde_mm_packs_epi16(simde_mm_load_si128((simde__m128i*){}.s16), " + "simde_mm_load_si128((simde__m128i*){}.s16)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[2]), ctx.v(ctx.insn.operands[1])); + return true; +} + +bool build_vpkswss(BuilderContext& ctx) { + // Vector Pack Signed Word Signed Saturate + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.s16, " + "simde_mm_packs_epi32(simde_mm_load_si128((simde__m128i*){}.s32), " + "simde_mm_load_si128((simde__m128i*){}.s32)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[2]), ctx.v(ctx.insn.operands[1])); + return true; +} + +bool build_vpkswus(BuilderContext& ctx) { + // Vector Pack Signed Word Unsigned Saturate + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.u16, " + "simde_mm_packus_epi32(simde_mm_load_si128((simde__m128i*){}.s32), " + "simde_mm_load_si128((simde__m128i*){}.s32)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[2]), ctx.v(ctx.insn.operands[1])); + return true; +} + +bool build_vpkd3d128(BuilderContext& ctx) { + // TODO(tomc): vectorize + // NOTE: handling vector reversal here too + ctx.emit_set_flush_mode(true); + switch (ctx.insn.operands[2]) { + case 0: // D3D color + { + uint32_t mask = ctx.insn.operands[3]; + uint32_t shift = ctx.insn.operands[4]; + + // Pack the 4 floats to D3DCOLOR + for (size_t i = 0; i < 4; i++) { + constexpr size_t indices[] = {3, 0, 1, 2}; + ctx.println("\t{}.u32[{}] = 0x404000FF;", ctx.v_temp(), i); + // Use !(x >= 3.0f) instead of (x < 3.0f) to properly clamp NaN to minimum + ctx.println( + "\t{}.f32[{}] = !({}.f32[{}] >= 3.0f) ? 3.0f : ({}.f32[{}] > {}.f32[{}] ? {}.f32[{}] : " + "{}.f32[{}]);", + ctx.v_temp(), i, ctx.v(ctx.insn.operands[1]), i, ctx.v(ctx.insn.operands[1]), i, + ctx.v_temp(), i, ctx.v_temp(), i, ctx.v(ctx.insn.operands[1]), i); + ctx.println("\t{}.u32 {}= uint32_t({}.u8[{}]) << {};", ctx.temp(), i == 0 ? "" : "|", + ctx.v_temp(), i * 4, indices[i] * 8); + } + + // Handle mask operand: + // mask=1: Write result to word[shift] + // mask=2: Write result to word[shift], clear word[shift+1] to 0 + // mask=3: Same as mask=2, but for shift=3 only clear word[0] (don't write result) + if (mask == 3 && shift == 3) { + // Special case: mask=3, shift=3 - only clear word 0 + ctx.println("\t{}.u32[0] = 0;", ctx.v(ctx.insn.operands[0])); + } else { + // Write result to word[shift] + ctx.println("\t{}.u32[{}] = {}.u32;", ctx.v(ctx.insn.operands[0]), shift, ctx.temp()); + // For mask=2 or mask=3, also clear the adjacent word + if (mask >= 2 && shift < 3) { + ctx.println("\t{}.u32[{}] = 0;", ctx.v(ctx.insn.operands[0]), shift + 1); + } + } + break; + } + + case 1: // NORMSHORT2 - pack 2 floats (in 3.0+X form) to 2 signed shorts + { + // Extract signed 16-bit values from floats and pack into one 32-bit word + // floats are in form: 3.0f + X (stored as integer add to 3.0f representation 0x40400000) + // We need to saturate to signed 16-bit range [-32767, 32767] (NOT -32768, based on tests) + // NOTE: Guest element 0 is at array index 3, element 1 is at index 2 (reversed for host) + // Element 0 (index 3) goes to HIGH word, element 1 (index 2) goes to LOW word + ctx.println("\t{}.s32 = {}.s32[3] - 0x40400000;", ctx.temp(), ctx.v(ctx.insn.operands[1])); + ctx.println("\t{}.s32 = {}.s32 > 32767 ? 32767 : ({}.s32 < -32767 ? -32767 : {}.s32);", + ctx.temp(), ctx.temp(), ctx.temp(), ctx.temp()); + ctx.println("\t{}.u32[0] = uint32_t(uint16_t({}.s32)) << 16;", ctx.v_temp(), + ctx.temp()); // element 0 to high word + ctx.println("\t{}.s32 = {}.s32[2] - 0x40400000;", ctx.temp(), ctx.v(ctx.insn.operands[1])); + ctx.println("\t{}.s32 = {}.s32 > 32767 ? 32767 : ({}.s32 < -32767 ? -32767 : {}.s32);", + ctx.temp(), ctx.temp(), ctx.temp(), ctx.temp()); + ctx.println("\t{}.u32[0] |= uint16_t({}.s32);", ctx.v_temp(), + ctx.temp()); // element 1 to low word + ctx.println("\t{}.u32[{}] = {}.u32[0];", ctx.v(ctx.insn.operands[0]), ctx.insn.operands[4], + ctx.v_temp()); + break; + } + + case 2: // NORMPACKED32 - pack 4 floats (in 3.0+X form) to 2:10:10:10 format (w:x:y:z) + { + // Format: 2 bits for w (element 3), 10 bits each for x, y, z (elements 0, 1, 2) + // Input floats are in 3.0+X form where X is the integer to pack + // Algorithm: saturate float to range, then mask low bits to extract X + // Constants kPack2101010_* are defined in ppc/context.h + ctx.println("\t{}.u32[0] = 0;", ctx.v_temp()); + + // Pack x (10 bits, position 0-9) - Guest element 0 is at index 3 + ctx.println( + "\t{}.f32 = {}.f32[3] < kPack2101010_Min10 ? kPack2101010_Min10 : ({}.f32[3] > " + "kPack2101010_Max10 ? kPack2101010_Max10 : {}.f32[3]);", + ctx.temp(), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[1]), + ctx.v(ctx.insn.operands[1])); + ctx.println("\t{}.u32[0] = {}.u32 & 0x3FF;", ctx.v_temp(), ctx.temp()); + + // Pack y (10 bits, position 10-19) - Guest element 1 is at index 2 + ctx.println( + "\t{}.f32 = {}.f32[2] < kPack2101010_Min10 ? kPack2101010_Min10 : ({}.f32[2] > " + "kPack2101010_Max10 ? kPack2101010_Max10 : {}.f32[2]);", + ctx.temp(), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[1]), + ctx.v(ctx.insn.operands[1])); + ctx.println("\t{}.u32[0] |= ({}.u32 & 0x3FF) << 10;", ctx.v_temp(), ctx.temp()); + + // Pack z (10 bits, position 20-29) - Guest element 2 is at index 1 + ctx.println( + "\t{}.f32 = {}.f32[1] < kPack2101010_Min10 ? kPack2101010_Min10 : ({}.f32[1] > " + "kPack2101010_Max10 ? kPack2101010_Max10 : {}.f32[1]);", + ctx.temp(), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[1]), + ctx.v(ctx.insn.operands[1])); + ctx.println("\t{}.u32[0] |= ({}.u32 & 0x3FF) << 20;", ctx.v_temp(), ctx.temp()); + + // Pack w (2 bits, position 30-31) - Guest element 3 is at index 0 + ctx.println( + "\t{}.f32 = {}.f32[0] < kPack2101010_Min2 ? kPack2101010_Min2 : ({}.f32[0] > " + "kPack2101010_Max2 ? kPack2101010_Max2 : {}.f32[0]);", + ctx.temp(), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[1]), + ctx.v(ctx.insn.operands[1])); + ctx.println("\t{}.u32[0] |= ({}.u32 & 0x3) << 30;", ctx.v_temp(), ctx.temp()); + + ctx.println("\t{}.u32[{}] = {}.u32[0];", ctx.v(ctx.insn.operands[0]), ctx.insn.operands[4], + ctx.v_temp()); + break; + } + + case 3: // FLOAT16_2 - pack 2 floats to 2 float16s + { + // Pack 2 elements into 32 bits (1 word) + // Guest element 0 goes to high 16 bits, element 1 to low 16 bits + // Output u16 index = (1-i) + 2*shift for element i + for (size_t i = 0; i < 2; i++) { + size_t srcIdx = 3 - i; // Guest element i is at host array index 3-i + size_t dstIdx = + (1 - i) + (2 * ctx.insn.operands[4]); // Output reversed: elem 0 to high, elem 1 to low + ctx.println("\t{}.u32 = ({}.u32[{}]&0x7FFFFFFF);", ctx.temp(), ctx.v(ctx.insn.operands[1]), + srcIdx); + ctx.println( + "\t{0}.u8[0] = ({1}.f32 != {1}.f32) || ({1}.f32 > 65504.0f) ? 0xFF : " + "(({2}.u32[{3}]&0x7f800000)>>23);", + ctx.v_temp(), ctx.temp(), ctx.v(ctx.insn.operands[1]), srcIdx); + ctx.println("\t{}.u16 = {}.u8[0] != 0xFF ? (({}.u32[{}]&0x7FE000)>>13) : 0x0;", ctx.temp(), + ctx.v_temp(), ctx.v(ctx.insn.operands[1]), srcIdx); + ctx.println( + "\t{0}.u16[{1}] = {2}.u8[0] != 0xFF ? ({2}.u8[0] > 0x70 ? " + "((({2}.u8[0]-0x70)<<10)+{3}.u16) : (0x71-{2}.u8[0] > 31 ? 0x0 : " + "((0x400+{3}.u16)>>(0x71-{2}.u8[0])))) : 0x7FFF;", + ctx.v(ctx.insn.operands[0]), dstIdx, ctx.v_temp(), ctx.temp()); + ctx.println("\t{}.u16[{}] |= (({}.u32[{}]&0x80000000)>>16);", ctx.v(ctx.insn.operands[0]), + dstIdx, ctx.v(ctx.insn.operands[1]), srcIdx); + } + break; + } + + case 4: // NORMSHORT4 - pack 4 floats (in 3.0+X form) to 4 signed shorts + { + // Pack 4 elements into 64 bits (2 words) + // Guest element 0 goes to highest 16-bit position, element 3 to lowest + // Output u16 index = (3-i) + 2*shift for element i + for (size_t i = 0; i < 4; i++) { + size_t srcIdx = 3 - i; // Guest element i is at host array index 3-i + size_t dstIdx = (3 - i) + (2 * ctx.insn.operands[4]); // Output also reversed + ctx.println("\t{}.s32 = {}.s32[{}] - 0x40400000;", ctx.temp(), ctx.v(ctx.insn.operands[1]), + srcIdx); + ctx.println("\t{}.s32 = {}.s32 > 32767 ? 32767 : ({}.s32 < -32767 ? -32767 : {}.s32);", + ctx.temp(), ctx.temp(), ctx.temp(), ctx.temp()); + ctx.println("\t{}.u16[{}] = uint16_t({}.s32);", ctx.v(ctx.insn.operands[0]), dstIdx, + ctx.temp()); + } + break; + } + + case 5: // float16_4 + { + // NOTE: These combinations come from game traces (heuristic handling), not the official spec. + // The spec only defines the encoding, not the exact semantics of y (mask) and z (shift) here. + // Anyone reading this later should know it may need extending if new combos turn up in other + // games. Combinations observed so far: mask=2, shift=0 → write u16[3..0], zero u16[4..7] + // mask=2, shift=2 → write u16[7..4], zero u16[3..0] (first pass) + // mask=3, shift=0 → write u16[3..0] without zeroing (second pass, preserves the upper half) + + uint32_t mask = ctx.insn.operands[3]; + uint32_t shift = ctx.insn.operands[4]; + + // Guard fix: The shift bound was too loose (shift=3 would cause dstIdx to reach 9, an OOB + // store). We also explicitly reject shift == 1 since the clear block below only handles 0 + // and 2. Furthermore, we explicitly warn on unexpected mask values (e.g., 0, 1) to avoid + // silent fallthroughs and silently generating miscompiled code. + if ((shift != 0 && shift != 2) || (mask != 2 && mask != 3)) { + REXCODEGEN_WARN("Unexpected float16_4 pack instruction at {:X} (mask={}, shift={})", + ctx.base, mask, shift); + // Emits a debug trap in the generated code to catch this at runtime. + ctx.println("\t__builtin_debugtrap();"); + return true; + } + + // mask=2: before writing, clear the half that will NOT be written. + // Shift is guaranteed to be 0 or 2 at this point due to the guard above. + if (mask == 2) { + // Optimization: Emit a single u64 write instead of two u32 writes. + // shift=0 → clears upper half u64[1] + // shift=2 → clears lower half u64[0] + size_t clearU64Start = (shift == 0) ? 1 : 0; + ctx.println("\t{}.u64[{}] = 0;", ctx.v(ctx.insn.operands[0]), clearU64Start); + } + + // Invariant: dstIdx must stay under 8 (valid u16 lanes are 0..7). + // Capping the shift to 0 or 2 in the guard check above ensures this is safe: + // it restricts the max dstIdx to (3 - 0) + (2 * 2) = 7. + // Do not widen the shift bounds without adjusting this logic. + for (size_t i = 0; i < 4; i++) { + size_t srcIdx = 3 - i; + size_t dstIdx = (3 - i) + (2 * shift); + + ctx.println("\t{}.u32 = ({}.u32[{}]&0x7FFFFFFF);", ctx.temp(), ctx.v(ctx.insn.operands[1]), + srcIdx); + ctx.println( + "\t{0}.u8[0] = ({1}.f32 != {1}.f32) || ({1}.f32 > 65504.0f) ? 0xFF : " + "(({2}.u32[{3}]&0x7f800000)>>23);", + ctx.v_temp(), ctx.temp(), ctx.v(ctx.insn.operands[1]), srcIdx); + ctx.println("\t{}.u16 = {}.u8[0] != 0xFF ? (({}.u32[{}]&0x7FE000)>>13) : 0x0;", ctx.temp(), + ctx.v_temp(), ctx.v(ctx.insn.operands[1]), srcIdx); + ctx.println( + "\t{0}.u16[{1}] = {2}.u8[0] != 0xFF ? ({2}.u8[0] > 0x70 ? " + "((({2}.u8[0]-0x70)<<10)+{3}.u16) : (0x71-{2}.u8[0] > 31 ? 0x0 : " + "((0x400+{3}.u16)>>(0x71-{2}.u8[0])))) : 0x7FFF;", + ctx.v(ctx.insn.operands[0]), dstIdx, ctx.v_temp(), ctx.temp()); + ctx.println("\t{}.u16[{}] |= (({}.u32[{}]&0x80000000)>>16);", ctx.v(ctx.insn.operands[0]), + dstIdx, ctx.v(ctx.insn.operands[1]), srcIdx); + } + break; + } + + case 6: // NORMPACKED64 - pack 4 floats to 4:20:20:20 format + { + // Format: 4 bits for w, 20 bits each for x, y, z (packed into 64 bits) + ctx.println("\t{}.u64[0] = 0;", ctx.v_temp()); + // Pack x (20 bits, position 0-19) + ctx.println("\t{}.s32 = int32_t({}.f32[0]);", ctx.temp(), ctx.v(ctx.insn.operands[1])); + ctx.println("\t{}.u64[0] = uint64_t({}.s32 & 0xFFFFF);", ctx.v_temp(), ctx.temp()); + // Pack y (20 bits, position 20-39) + ctx.println("\t{}.s32 = int32_t({}.f32[1]);", ctx.temp(), ctx.v(ctx.insn.operands[1])); + ctx.println("\t{}.u64[0] |= uint64_t({}.s32 & 0xFFFFF) << 20;", ctx.v_temp(), ctx.temp()); + // Pack z (20 bits, position 40-59) + ctx.println("\t{}.s32 = int32_t({}.f32[2]);", ctx.temp(), ctx.v(ctx.insn.operands[1])); + ctx.println("\t{}.u64[0] |= uint64_t({}.s32 & 0xFFFFF) << 40;", ctx.v_temp(), ctx.temp()); + // Pack w (4 bits, position 60-63) + ctx.println("\t{}.s32 = int32_t({}.f32[3]);", ctx.temp(), ctx.v(ctx.insn.operands[1])); + ctx.println("\t{}.u64[0] |= uint64_t({}.s32 & 0xF) << 60;", ctx.v_temp(), ctx.temp()); + ctx.println("\t{}.u64[{}] = {}.u64[0];", ctx.v(ctx.insn.operands[0]), + ctx.insn.operands[4] >> 1, ctx.v_temp()); + break; + } + + default: + ctx.println("\t__builtin_debugtrap();"); + break; + } + return true; +} + +//============================================================================= +// Vector Unpack +//============================================================================= + +bool build_vupkd3d128(BuilderContext& ctx) { + // TODO(tomc): Vectorize + // NOTE: handling vector reversal here too + switch (ctx.insn.operands[2] >> 2) { + case 0: // D3D color + for (size_t i = 0; i < 4; i++) { + constexpr size_t indices[] = {3, 0, 1, 2}; + ctx.println("\t{}.u32[{}] = {}.u8[{}] | 0x3F800000;", ctx.v_temp(), i, + ctx.v(ctx.insn.operands[1]), indices[i]); + } + ctx.println("\t{} = {};", ctx.v(ctx.insn.operands[0]), ctx.v_temp()); + break; + + case 1: // NORMSHORT2 - unpack 2 shorts to floats (3.0+X form) + for (size_t i = 0; i < 2; i++) { + ctx.println("\t{}.f32 = 3.0f;", ctx.temp()); + ctx.println("\t{}.s32 += {}.s16[{}];", ctx.temp(), ctx.v(ctx.insn.operands[1]), 1 - i); + ctx.println("\t{}.f32[{}] = {}.f32;", ctx.v_temp(), 3 - i, ctx.temp()); + } + ctx.println("\t{}.f32[1] = 0.0f;", ctx.v_temp()); + ctx.println("\t{}.f32[0] = 1.0f;", ctx.v_temp()); + ctx.println("\t{} = {};", ctx.v(ctx.insn.operands[0]), ctx.v_temp()); + break; + + case 2: // NORMPACKED32 - unpack 2:10:10:10 to floats + { + // Format: w(2 bits):z(10 bits):y(10 bits):x(10 bits) in Guest element 3 (host s32[0]) + // x, y, z --> 3.0+X form (signed 10-bit), w --> 1.0+w form + // Output: x --> Guest element 0 (host u32[3]), y --> Guest element 1 (host u32[2]), + // z --> Guest element 2 (host u32[1]), w --> Guest element 3 (host u32[0]) + auto vSrc = ctx.v(ctx.insn.operands[1]); + auto vDst = ctx.v(ctx.insn.operands[0]); + // x (bits 0-9) - sign extend from 10 bits --> Guest element 0 (host u32[3]) + ctx.println("\t{}.s32 = ({}.s32[0] << 22) >> 22;", ctx.temp(), vSrc); + ctx.println("\t{}.s32[0] = {}.s32 == -512 ? 0x7FC00000 : ({}.s32 + 0x40400000);", + ctx.v_temp(), ctx.temp(), ctx.temp()); + ctx.println("\t{}.u32[3] = {}.u32[0];", vDst, ctx.v_temp()); + // y (bits 10-19) - sign extend from 10 bits --> Guest element 1 (host u32[2]) + ctx.println("\t{}.s32 = ({}.s32[0] << 12) >> 22;", ctx.temp(), vSrc); + ctx.println("\t{}.s32[0] = {}.s32 + 0x40400000;", ctx.v_temp(), ctx.temp()); + ctx.println("\t{}.u32[2] = {}.u32[0];", vDst, ctx.v_temp()); + // z (bits 20-29) - sign extend from 10 bits --> Guest element 2 (host u32[1]) + ctx.println("\t{}.s32 = ({}.s32[0] << 2) >> 22;", ctx.temp(), vSrc); + ctx.println("\t{}.s32[0] = {}.s32 + 0x40400000;", ctx.v_temp(), ctx.temp()); + ctx.println("\t{}.u32[1] = {}.u32[0];", vDst, ctx.v_temp()); + // w (bits 30-31) - 2 bits, convert to 1.0+w form --> Guest element 3 (host u32[0]) + ctx.println("\t{}.u32[0] = ({}.u32[0] >> 30) | 0x3F800000;", ctx.v_temp(), vSrc); + ctx.println("\t{}.u32[0] = {}.u32[0];", vDst, ctx.v_temp()); + break; + } + + case 3: // FLOAT16_2 - unpack 2 float16 to floats + { + auto vSrc = ctx.v(ctx.insn.operands[1]); + auto vDst = ctx.v(ctx.insn.operands[0]); + // Unpack 2 float16s from u16[0,1] to elements 0,1 (stored at u32[3,2]) + // Element 0 (at u32[3]) from u16[1] (high), element 1 (at u32[2]) from u16[0] (low) + for (size_t i = 0; i < 2; i++) { + size_t srcIdx = 1 - i; // Read from u16[1], u16[0] + size_t dstIdx = 3 - i; // Write to u32[3], u32[2] + ctx.println("\t{}.u32 = {}.u16[{}];", ctx.temp(), vSrc, srcIdx); + // Extract sign, exponent, mantissa + ctx.println( + "\t{}.u32[0] = (({}.u32 & 0x8000) << 16) | ((({}.u32 & 0x7C00) + 0x1C000) << 13) | " + "(({}.u32 & 0x03FF) << 13);", + ctx.v_temp(), ctx.temp(), ctx.temp(), ctx.temp()); + // Handle zero/denorm case + ctx.println("\tif (({}.u32 & 0x7C00) == 0) {}.u32[0] = ({}.u32 & 0x8000) << 16;", + ctx.temp(), ctx.v_temp(), ctx.temp()); + ctx.println("\t{}.u32[{}] = {}.u32[0];", vDst, dstIdx, ctx.v_temp()); + } + ctx.println("\t{}.f32[1] = 0.0f;", vDst); + ctx.println("\t{}.f32[0] = 1.0f;", vDst); + break; + } + + case 4: // NORMSHORT4 - unpack 4 shorts to floats (3.0+X form) + { + // Unpack 4 shorts from Guest elements 2-3 (host u16[0-3]) to 4 floats + // Guest element order is reversed in host arrays + for (size_t i = 0; i < 4; i++) { + size_t srcIdx = 3 - i; // Read from u16 indices 3, 2, 1, 0 (guest shorts 0, 1, 2, 3) + size_t dstIdx = 3 - i; // Write to f32 indices 3, 2, 1, 0 (Guest elements 0, 1, 2, 3) + ctx.println("\t{}.f32 = 3.0f;", ctx.temp()); + ctx.println("\t{}.s32 += {}.s16[{}];", ctx.temp(), ctx.v(ctx.insn.operands[1]), srcIdx); + ctx.println("\t{}.f32[{}] = {}.f32;", ctx.v(ctx.insn.operands[0]), dstIdx, ctx.temp()); + } + break; + } + + case 5: // FLOAT16_4 - unpack 4 float16 to floats + { + auto vSrc = ctx.v(ctx.insn.operands[1]); + auto vDst = ctx.v(ctx.insn.operands[0]); + // Unpack 4 float16s from Guest elements 2-3 (host u16[0-3]) to elements 0-3 + // Guest element order is reversed in host arrays + for (size_t i = 0; i < 4; i++) { + size_t srcIdx = 3 - i; // Read from u16 indices 3, 2, 1, 0 (guest shorts 0, 1, 2, 3) + size_t dstIdx = 3 - i; // Write to u32 indices 3, 2, 1, 0 (Guest elements 0, 1, 2, 3) + ctx.println("\t{}.u32 = {}.u16[{}];", ctx.temp(), vSrc, srcIdx); + // Extract sign, exponent, mantissa and convert to float32 + ctx.println( + "\t{}.u32[0] = (({}.u32 & 0x8000) << 16) | ((({}.u32 & 0x7C00) + 0x1C000) << 13) | " + "(({}.u32 & 0x03FF) << 13);", + ctx.v_temp(), ctx.temp(), ctx.temp(), ctx.temp()); + // Handle zero/denorm case + ctx.println("\tif (({}.u32 & 0x7C00) == 0) {}.u32[0] = ({}.u32 & 0x8000) << 16;", + ctx.temp(), ctx.v_temp(), ctx.temp()); + ctx.println("\t{}.u32[{}] = {}.u32[0];", vDst, dstIdx, ctx.v_temp()); + } + break; + } + + case 6: // NORMPACKED64 - unpack 4:20:20:20 to floats + { + auto vSrc = ctx.v(ctx.insn.operands[1]); + auto vDst = ctx.v(ctx.insn.operands[0]); + // Format: w(4 bits):z(20 bits):y(20 bits):x(20 bits) in 64 bits + // x, y, z --> floats, w --> float + ctx.println("\t{}.u64[0] = {}.u64[1];", ctx.v_temp(), vSrc); + // x (bits 0-19) - sign extend from 20 bits + ctx.println("\t{}.s32 = (int32_t({}.u64[0] << 44) >> 44);", ctx.temp(), ctx.v_temp()); + ctx.println("\t{}.f32[0] = float({}.s32);", vDst, ctx.temp()); + // y (bits 20-39) - sign extend from 20 bits + ctx.println("\t{}.s32 = (int32_t({}.u64[0] << 24) >> 44);", ctx.temp(), ctx.v_temp()); + ctx.println("\t{}.f32[1] = float({}.s32);", vDst, ctx.temp()); + // z (bits 40-59) - sign extend from 20 bits + ctx.println("\t{}.s32 = (int32_t({}.u64[0] << 4) >> 44);", ctx.temp(), ctx.v_temp()); + ctx.println("\t{}.f32[2] = float({}.s32);", vDst, ctx.temp()); + // w (bits 60-63) - 4 bits + ctx.println("\t{}.f32[3] = float({}.u64[0] >> 60);", vDst, ctx.v_temp()); + break; + } + + default: + ctx.println("\t__builtin_debugtrap();"); + break; + } + return true; +} + +bool build_vupkhsb(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.s16, " + "simde_mm_cvtepi8_epi16(simde_mm_unpackhi_epi64(simde_mm_load_si128((simde__m128i*){}.s8), " + "simde_mm_load_si128((simde__m128i*){}.s8))));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[1])); + return true; +} + +bool build_vupkhsh(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.s32, " + "simde_mm_cvtepi16_epi32(simde_mm_unpackhi_epi64(simde_mm_load_si128((simde__m128i*){}.s16), " + "simde_mm_load_si128((simde__m128i*){}.s16))));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1]), ctx.v(ctx.insn.operands[1])); + return true; +} + +bool build_vupklsb(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.s32, " + "simde_mm_cvtepi8_epi16(simde_mm_load_si128((simde__m128i*){}.s16)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1])); + return true; +} + +bool build_vupklsh(BuilderContext& ctx) { + ctx.println( + "\tsimde_mm_store_si128((simde__m128i*){}.s32, " + "simde_mm_cvtepi16_epi32(simde_mm_load_si128((simde__m128i*){}.s16)));", + ctx.v(ctx.insn.operands[0]), ctx.v(ctx.insn.operands[1])); + return true; +} + +} // namespace rex::codegen diff --git a/src/codegen/code_emitter.cpp b/src/codegen/code_emitter.cpp new file mode 100644 index 0000000..34ba50d --- /dev/null +++ b/src/codegen/code_emitter.cpp @@ -0,0 +1,29 @@ +/** + * @file code_emitter.cpp + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include + +namespace rex::codegen { + +void CodeEmitter::ensureCsrState(CsrState required) { + if (csrState_ == required) + return; + + // Emit CSR mode change if needed + if (required == CsrState::Vmx) { + line("REX_SET_FLUSH_MODE(true);"); + } else if (required == CsrState::Fpu) { + line("REX_SET_FLUSH_MODE(false);"); + } + + csrState_ = required; +} + +} // namespace rex::codegen diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp new file mode 100644 index 0000000..0fcf635 --- /dev/null +++ b/src/codegen/codegen.cpp @@ -0,0 +1,102 @@ +/** + * @file codegen/codegen.cpp + * @brief Codegen pipeline implementation + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include + +#include +#include +#include +#include +#include +#include + +namespace rex::codegen { + +CodegenPipeline::~CodegenPipeline() = default; +CodegenPipeline::CodegenPipeline(CodegenPipeline&&) noexcept = default; +CodegenPipeline& CodegenPipeline::operator=(CodegenPipeline&&) noexcept = default; + +Result CodegenPipeline::Create(const std::filesystem::path& configPath) { + CodegenPipeline pipeline; + + // Load config to get XEX path + RecompilerConfig tempConfig; + if (!tempConfig.Load(configPath.string())) { + return Err(ErrorCategory::Config, + fmt::format("Failed to load config: {}", configPath.string())); + } + + auto configDir = configPath.parent_path(); + + // Determine XEX path + std::filesystem::path xexPath; + if (!tempConfig.patchedFilePath.empty()) { + xexPath = configDir / tempConfig.patchedFilePath; + if (!std::filesystem::exists(xexPath)) { + xexPath.clear(); + } + } + if (xexPath.empty()) { + xexPath = configDir / tempConfig.filePath; + } + + if (!std::filesystem::exists(xexPath)) { + return Err(ErrorCategory::IO, + fmt::format("XEX file not found: {}", xexPath.string())); + } + xexPath = std::filesystem::canonical(xexPath); + + // Create Runtime + auto xexDir = xexPath.parent_path(); + pipeline.runtime_ = std::make_unique(xexDir.string()); + auto status = pipeline.runtime_->Setup(rex::RuntimeConfig{ + .kernel_init = rex::kernel::InitializeKernel, + .tool_mode = true, + }); + if (status != X_STATUS_SUCCESS) { + return Err(ErrorCategory::IO, + fmt::format("Failed to initialize Runtime: {:#x}", status)); + } + + // Create CodegenContext (AnalysisState is populated from binary there) + auto ctxResult = CodegenContext::Create(configPath, *pipeline.runtime_); + if (!ctxResult) { + return Err(ctxResult.error()); + } + pipeline.ctx_ = std::make_unique(std::move(*ctxResult)); + + return Ok(std::move(pipeline)); +} + +Result CodegenPipeline::Run(bool force) { + auto result = RunAnalyze(); + if (!result) + return result; + return RunWrite(force); +} + +Result CodegenPipeline::RunAnalyze() { + auto analyzeResult = Analyze(*ctx_); + if (!analyzeResult) { + REXLOG_ERROR("Analysis failed: {}", analyzeResult.error().message); + return analyzeResult; + } + return Ok(); +} + +Result CodegenPipeline::RunWrite(bool force) { + CodegenWriter writer(*ctx_, runtime_.get()); + if (!writer.write(force)) + return Err(ErrorCategory::Validation, "Code generation failed."); + return Ok(); +} + +} // namespace rex::codegen diff --git a/src/codegen/codegen_context.cpp b/src/codegen/codegen_context.cpp new file mode 100644 index 0000000..6a3d3ab --- /dev/null +++ b/src/codegen/codegen_context.cpp @@ -0,0 +1,128 @@ +/** + * @file rexcodegen/codegen_context.cpp + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "decoded_binary.h" + +#include + +#include +#include + +#include "codegen_logging.h" +#include +#include +#include +#include + +namespace rex::codegen { + +Result CodegenContext::Create(const std::filesystem::path& configPath, + Runtime& runtime) { + CodegenContext ctx; + + // Load configuration + if (!ctx.config_.Load(configPath.string())) { + return Err(ErrorCategory::Config, + fmt::format("Failed to load config: {}", configPath.string())); + } + ctx.configDir_ = configPath.parent_path(); + + // Determine XEX path + std::filesystem::path xexPath; + if (!ctx.config_.patchedFilePath.empty()) { + xexPath = ctx.configDir_ / ctx.config_.patchedFilePath; + if (!std::filesystem::exists(xexPath)) { + REXCODEGEN_ERROR("Patched file not found: {}", xexPath.string()); + xexPath.clear(); + } + } + + if (xexPath.empty()) { + xexPath = ctx.configDir_ / ctx.config_.filePath; + + if (!ctx.config_.patchFilePath.empty()) { + REXCODEGEN_WARN( + "Patch file specified but XexPatcher not available. Use a pre-patched XEX file instead."); + REXCODEGEN_WARN("Ignoring patch file: {}", ctx.config_.patchFilePath); + } + } + + // Resolve path + if (std::filesystem::exists(xexPath)) { + xexPath = std::filesystem::canonical(xexPath); + } else { + return Err(ErrorCategory::NotFound, + fmt::format("XEX file not found: {}", xexPath.string())); + } + + // Load XEX via Runtime + auto xexFilename = xexPath.filename(); + auto vfsPath = "game:\\" + xexFilename.string(); + auto status = runtime.LoadXexImage(vfsPath); + if (status != X_STATUS_SUCCESS) { + return Err( + ErrorCategory::Format, + fmt::format("Failed to load XEX: {} (status {:#x})", xexPath.string(), status)); + } + + // Get module and create BinaryView + auto user_module = runtime.kernel_state()->GetExecutableModule(); + if (!user_module) { + return Err(ErrorCategory::Format, + "Failed to get executable module after loading"); + } + + auto* module = user_module->xex_module(); + if (!module) { + return Err(ErrorCategory::Format, "Failed to get XexModule from UserModule"); + } + + ctx.binary_ = BinaryView::fromModule(*module); + ctx.resolver_ = runtime.export_resolver(); + + REXCODEGEN_TRACE("Loaded XEX: base=0x{:08X}, size=0x{:X}, entry=0x{:08X}", + ctx.binary_.baseAddress(), ctx.binary_.imageSize(), ctx.binary_.entryPoint()); + + // Initialize AnalysisState from binary + ctx.analysisState_.format = "xex"; + ctx.analysisState_.loadAddress = ctx.binary_.baseAddress(); + ctx.analysisState_.entryPoint = ctx.binary_.entryPoint(); + ctx.analysisState_.imageSize = ctx.binary_.imageSize(); + + return ctx; +} + +CodegenContext CodegenContext::Create(BinaryView binary, RecompilerConfig config) { + CodegenContext ctx; + ctx.binary_ = std::move(binary); + ctx.config_ = std::move(config); + return ctx; +} + +CodegenContext::~CodegenContext() = default; +CodegenContext::CodegenContext(CodegenContext&&) = default; +CodegenContext& CodegenContext::operator=(CodegenContext&&) = default; + +DecodedBinary& CodegenContext::decoded() { + assert(decoded_ && "Call initDecoded() before accessing decoded()"); + return *decoded_; +} + +const DecodedBinary& CodegenContext::decoded() const { + assert(decoded_ && "Call initDecoded() before accessing decoded()"); + return *decoded_; +} + +void CodegenContext::initDecoded() { + decoded_ = std::make_unique(binary_); + decoded_->decode(); +} + +} // namespace rex::codegen diff --git a/src/codegen/codegen_flags.cpp b/src/codegen/codegen_flags.cpp new file mode 100644 index 0000000..a8cb5e3 --- /dev/null +++ b/src/codegen/codegen_flags.cpp @@ -0,0 +1,88 @@ +/** + * @file codegen/codegen_flags.cpp + * @brief CVar definitions for the codegen pipeline + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include + +// clang-format off + +//============================================================================= +// Codegen/Output +//============================================================================= + +REXCVAR_DEFINE_UINT32(max_file_size_bytes, 2097152, "Codegen", + "Target maximum source file size in bytes") + .lifecycle(rex::cvar::Lifecycle::kInitOnly) + .range(65536, 67108864); + +REXCVAR_DEFINE_UINT32(progress_log_frequency, 100, "Codegen", + "Log progress every N functions") + .lifecycle(rex::cvar::Lifecycle::kInitOnly) + .range(1, 100000); + +//============================================================================= +// Codegen/Analysis +//============================================================================= + +REXCVAR_DEFINE_UINT32(max_discovery_iterations, 1000, "Codegen", + "Max iterations for function discovery convergence") + .lifecycle(rex::cvar::Lifecycle::kInitOnly) + .range(1, 100000); + +REXCVAR_DEFINE_UINT32(max_vtable_iterations, 100, "Codegen", + "Max iterations for vtable discovery") + .lifecycle(rex::cvar::Lifecycle::kInitOnly) + .range(1, 100000); + +REXCVAR_DEFINE_UINT32(max_resolve_iterations, 100, "Codegen", + "Max iterations for call target resolution") + .lifecycle(rex::cvar::Lifecycle::kInitOnly) + .range(1, 100000); + +REXCVAR_DEFINE_UINT32(max_eh_states, 100, "Codegen", + "Max C++ EH states before rejecting handler") + .lifecycle(rex::cvar::Lifecycle::kInitOnly) + .range(1, 100000); + +REXCVAR_DEFINE_UINT32(max_eh_try_blocks, 50, "Codegen", + "Max try blocks before rejecting handler") + .lifecycle(rex::cvar::Lifecycle::kInitOnly) + .range(1, 100000); + +REXCVAR_DEFINE_UINT32(max_eh_ip_map_entries, 200, "Codegen", + "Max IP-to-state map entries") + .lifecycle(rex::cvar::Lifecycle::kInitOnly) + .range(1, 100000); + +REXCVAR_DEFINE_UINT32(max_seh_scope_entries, 100, "Codegen", + "Max SEH scope table entries") + .lifecycle(rex::cvar::Lifecycle::kInitOnly) + .range(1, 100000); + +//============================================================================= +// Codegen/Discovery +//============================================================================= + +REXCVAR_DEFINE_UINT32(backward_scan_limit, 64, "Codegen", + "Max instructions to scan backward for jump table patterns") + .lifecycle(rex::cvar::Lifecycle::kInitOnly) + .range(1, 10000); + +REXCVAR_DEFINE_UINT32(max_jump_table_entries, 512, "Codegen", + "Max entries per detected jump table") + .lifecycle(rex::cvar::Lifecycle::kInitOnly) + .range(1, 100000); + +REXCVAR_DEFINE_UINT32(max_blocks_per_function, 10000, "Codegen", + "Safety limit on blocks per function") + .lifecycle(rex::cvar::Lifecycle::kInitOnly) + .range(1, 1000000); + +// clang-format on diff --git a/src/codegen/codegen_flags.h b/src/codegen/codegen_flags.h new file mode 100644 index 0000000..27b80db --- /dev/null +++ b/src/codegen/codegen_flags.h @@ -0,0 +1,35 @@ +/** + * @file codegen/codegen_flags.h + * @brief CVar declarations for the codegen pipeline + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include + +#include + +// Codegen/Output +REXCVAR_DECLARE(uint32_t, max_file_size_bytes); +REXCVAR_DECLARE(uint32_t, progress_log_frequency); + +// Codegen/Analysis +REXCVAR_DECLARE(uint32_t, max_discovery_iterations); +REXCVAR_DECLARE(uint32_t, max_vtable_iterations); +REXCVAR_DECLARE(uint32_t, max_resolve_iterations); +REXCVAR_DECLARE(uint32_t, max_eh_states); +REXCVAR_DECLARE(uint32_t, max_eh_try_blocks); +REXCVAR_DECLARE(uint32_t, max_eh_ip_map_entries); +REXCVAR_DECLARE(uint32_t, max_seh_scope_entries); + +// Codegen/Discovery +REXCVAR_DECLARE(uint32_t, backward_scan_limit); +REXCVAR_DECLARE(uint32_t, max_jump_table_entries); +REXCVAR_DECLARE(uint32_t, max_blocks_per_function); diff --git a/src/codegen/codegen_logging.h b/src/codegen/codegen_logging.h new file mode 100644 index 0000000..88a1c61 --- /dev/null +++ b/src/codegen/codegen_logging.h @@ -0,0 +1,30 @@ +/** + * @file codegen/codegen_logging.h + * @brief Codegen subsystem logging category registration + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include + +REXLOG_DEFINE_CATEGORY(codegen) + +/** @{ Codegen subsystem logging macros */ +#define REXCODEGEN_TRACE(...) REXLOG_CAT_TRACE(::rex::log::codegen(), __VA_ARGS__) +#define REXCODEGEN_DEBUG(...) REXLOG_CAT_DEBUG(::rex::log::codegen(), __VA_ARGS__) +#define REXCODEGEN_INFO(...) REXLOG_CAT_INFO(::rex::log::codegen(), __VA_ARGS__) +#define REXCODEGEN_WARN(...) REXLOG_CAT_WARN(::rex::log::codegen(), __VA_ARGS__) +#define REXCODEGEN_ERROR(...) REXLOG_CAT_ERROR(::rex::log::codegen(), __VA_ARGS__) +#define REXCODEGEN_CRITICAL(...) REXLOG_CAT_CRITICAL(::rex::log::codegen(), __VA_ARGS__) +/** @} */ + +/** @{ Codegen subsystem noisy logging macros */ +#define REXCODEGEN_NOISY_TRACE(...) REXLOG_CAT_NOISY_TRACE(::rex::log::codegen(), __VA_ARGS__) +#define REXCODEGEN_NOISY_DEBUG(...) REXLOG_CAT_NOISY_DEBUG(::rex::log::codegen(), __VA_ARGS__) +/** @} */ diff --git a/src/codegen/codegen_writer.cpp b/src/codegen/codegen_writer.cpp new file mode 100644 index 0000000..69e4793 --- /dev/null +++ b/src/codegen/codegen_writer.cpp @@ -0,0 +1,331 @@ +/** + * @file codegen/codegen_writer.cpp + * @brief Consolidated codegen output writer + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include +#include "codegen_flags.h" + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "codegen_logging.h" +#include "template_registry_internal.h" + +#include + +namespace { + +nlohmann::json buildTemplateData(const rex::codegen::CodegenContext& ctx, + const std::vector& functions, + const std::unordered_map& rexcrtByAddr) { + const auto& cfg = ctx.Config(); + + // Compute code_base and code_size from binary sections + size_t codeMin = ~size_t(0); + size_t codeMax = 0; + for (const auto& section : ctx.binary().sections()) { + if (section.executable) { + if (section.baseAddress < codeMin) + codeMin = section.baseAddress; + if ((section.baseAddress + section.size) > codeMax) + codeMax = section.baseAddress + section.size; + } + } + + // Build functions JSON array + nlohmann::json functionsJson = nlohmann::json::array(); + for (const auto* fn : functions) { + std::string funcName; + bool isRexcrt = false; + + auto crtIt = rexcrtByAddr.find(static_cast(fn->base())); + if (crtIt != rexcrtByAddr.end()) { + funcName = crtIt->second; + isRexcrt = true; + } else if (fn->base() == ctx.analysisState().entryPoint) { + funcName = "xstart"; + } else if (!fn->name().empty()) { + funcName = fn->name(); + } else { + funcName = fmt::format("sub_{:08X}", fn->base()); + } + + functionsJson.push_back({ + {"address", fmt::format("0x{:X}", fn->base())}, + {"name", funcName}, + {"is_rexcrt", isRexcrt}, + {"below_code_base", (fn->base() < codeMin)}, + {"is_import", fn->authority() == rex::codegen::FunctionAuthority::IMPORT}, + }); + } + + // Build config flags + nlohmann::json configFlags = { + {"skip_lr", cfg.skipLr}, + {"ctr_as_local", cfg.ctrAsLocalVariable}, + {"xer_as_local", cfg.xerAsLocalVariable}, + {"reserved_as_local", cfg.reservedRegisterAsLocalVariable}, + {"skip_msr", cfg.skipMsr}, + {"cr_as_local", cfg.crRegistersAsLocalVariables}, + {"non_argument_as_local", cfg.nonArgumentRegistersAsLocalVariables}, + {"non_volatile_as_local", cfg.nonVolatileRegistersAsLocalVariables}, + }; + + return { + {"project", cfg.projectName}, + {"image_base", fmt::format("0x{:X}", ctx.binary().baseAddress())}, + {"image_size", fmt::format("0x{:X}", ctx.binary().imageSize())}, + {"code_base", fmt::format("0x{:X}", codeMin)}, + {"code_size", fmt::format("0x{:X}", codeMax - codeMin)}, + {"rexcrt_heap", cfg.rexcrtFunctions.contains("RtlAllocateHeap") ? 1 : 0}, + {"thunk_reserve_size", fmt::format("0x{:X}", 0x10000u)}, + {"has_dll_modules", ctx.hasDllModules()}, + {"is_dll", ctx.isDllModule()}, + {"config_flags", configFlags}, + {"functions", functionsJson}, + {"recomp_files", nlohmann::json::array()}, + }; +} + +} // namespace + +namespace rex::codegen { + +constexpr size_t kOutputBufferReserveSize = 32 * 1024 * 1024; // 32 MB + +CodegenWriter::CodegenWriter(CodegenContext& ctx, Runtime* runtime) + : ctx_(ctx), runtime_(runtime) {} + +// Convenience accessors +FunctionGraph& CodegenWriter::graph() { + return ctx_.graph; +} +const FunctionGraph& CodegenWriter::graph() const { + return ctx_.graph; +} +const BinaryView& CodegenWriter::binary() const { + return ctx_.binary(); +} +RecompilerConfig& CodegenWriter::config() { + return ctx_.Config(); +} +const RecompilerConfig& CodegenWriter::config() const { + return ctx_.Config(); +} +AnalysisState& CodegenWriter::analysisState() { + return ctx_.analysisState(); +} +const AnalysisState& CodegenWriter::analysisState() const { + return ctx_.analysisState(); +} + +bool CodegenWriter::write(bool force) { + // --- Validation gate (from recompile.cpp) --- + if (ctx_.errors.HasErrors() && !force) { + REXCODEGEN_ERROR("Code generation blocked: {} validation errors. Use --force to override.", + ctx_.errors.Count()); + return false; + } + + // --- Output directory setup (from recompile.cpp) --- + std::filesystem::path outputPath = ctx_.configDir() / config().outDirectoryPath; + REXCODEGEN_TRACE("Output path: {}", outputPath.string()); + std::filesystem::create_directories(outputPath); + + // --- Clean old generated files (from recompile.cpp) --- + std::string prefix = config().projectName + "_"; + for (const auto& entry : std::filesystem::directory_iterator(outputPath)) { + auto ext = entry.path().extension(); + if (ext == ".cpp" || ext == ".h" || ext == ".cmake") { + std::string filename = entry.path().filename().string(); + if (filename == "sources.cmake" || filename.starts_with(prefix) || + filename.starts_with("ppc_recomp") || filename.starts_with("ppc_func_mapping") || + filename.starts_with("function_table_init") || filename.starts_with("ppc_config")) { + deletedFiles_.push_back(filename); + std::filesystem::remove(entry.path()); + } + } + } + + // --- Everything below from recompiler.cpp recompile() --- + REXCODEGEN_TRACE("Recompile: starting"); + out.reserve(kOutputBufferReserveSize); + + // Build sorted function list from graph + std::vector functions; + functions.reserve(graph().functionCount()); + for (const auto& [addr, node] : graph().functions()) { + functions.push_back(node.get()); + } + std::sort(functions.begin(), functions.end(), + [](const auto* a, const auto* b) { return a->base() < b->base(); }); + + // Build rexcrt reverse map and rename graph nodes + std::unordered_map rexcrtByAddr; + for (const auto& [name, addr] : config().rexcrtFunctions) { + auto crtName = fmt::format("rexcrt_{}", name); + rexcrtByAddr[addr] = crtName; + if (auto* node = graph().getFunction(addr)) { + node->setName(std::move(crtName)); + } + } + + const std::string& projectName = config().projectName; + + TemplateRegistry registry; + if (!config().templateDir.empty()) + registry.loadOverrides(config().templateDir); + + auto tmplData = buildTemplateData(ctx_, functions, rexcrtByAddr); + + // Generate {project}_init.h (self-contained: config + declarations + macros) + REXCODEGEN_TRACE("Recompile: generating {}_init.h", projectName); + out = renderWithJson(registry, "codegen/init_h", tmplData); + SaveCurrentOutData(fmt::format("{}_init.h", projectName)); + + // Generate {project}_init.cpp (PPCImageConfig + PPCFuncMappings) + REXCODEGEN_TRACE("Recompile: generating {}_init.cpp", projectName); + out = renderWithJson(registry, "codegen/init_cpp", tmplData); + SaveCurrentOutData(fmt::format("{}_init.cpp", projectName)); + + // Generate {project}_register.cpp (registration function for hash-based dispatch) + REXCODEGEN_TRACE("Recompile: generating {}_register.cpp", projectName); + tmplData["is_dll"] = ctx_.isDllModule(); + out = renderWithJson(registry, "codegen/register_cpp", tmplData); + SaveCurrentOutData(fmt::format("{}_register.cpp", projectName)); + + // Filter out imports and rexcrt functions before recompilation + std::erase_if(functions, [](const FunctionNode* fn) { + return fn->authority() == FunctionAuthority::IMPORT; + }); + std::erase_if(functions, [&rexcrtByAddr](const FunctionNode* fn) { + return rexcrtByAddr.contains(static_cast(fn->base())); + }); + + // Build EmitContext -- resolver is now properly connected + EmitContext emitCtx{binary(), config(), graph(), + static_cast(analysisState().entryPoint), nullptr}; + if (runtime_) + emitCtx.resolver = runtime_->export_resolver(); + + // Generate recomp files with size-based splitting + REXCODEGEN_TRACE("Recompiling {} functions...", functions.size()); + size_t currentFileBytes = 0; + println("#include \"{}_init.h\"\n", projectName); + + for (size_t i = 0; i < functions.size(); i++) { + std::string code = functions[i]->emitCpp(emitCtx); + + if (currentFileBytes > 0 && currentFileBytes + code.size() > REXCVAR_GET(max_file_size_bytes)) { + SaveCurrentOutData(); + println("#include \"{}_init.h\"\n", projectName); + currentFileBytes = 0; + } + + if (code.size() > REXCVAR_GET(max_file_size_bytes)) { + REXCODEGEN_WARN("Function 0x{:08X} is {} bytes, exceeds max_file_size_bytes ({})", + functions[i]->base(), code.size(), REXCVAR_GET(max_file_size_bytes)); + } + + out += code; + currentFileBytes += code.size(); + } + + SaveCurrentOutData(); + REXCODEGEN_TRACE("Recompilation complete."); + + // Generate sources.cmake + REXCODEGEN_TRACE("Recompile: generating sources.cmake"); + { + auto& recompFiles = tmplData["recomp_files"]; + recompFiles = nlohmann::json::array(); + for (size_t i = 0; i < cppFileIndex; ++i) { + recompFiles.push_back(fmt::format("{}_recomp.{}.cpp", projectName, i)); + } + out = renderWithJson(registry, "codegen/sources_cmake", tmplData); + SaveCurrentOutData("sources.cmake"); + } + + // Write all buffered files to disk + FlushPendingWrites(); + return true; +} + +void CodegenWriter::SaveCurrentOutData(const std::string_view name) { + if (!out.empty()) { + std::string filename; + + if (name.empty()) { + filename = fmt::format("{}_recomp.{}.cpp", config().projectName, cppFileIndex); + ++cppFileIndex; + } else { + filename = std::string(name); + } + + pendingWrites.emplace_back(std::move(filename), std::move(out)); + out.clear(); + } +} + +void CodegenWriter::FlushPendingWrites() { + std::filesystem::path outputPath = ctx_.configDir() / config().outDirectoryPath; + + for (const auto& [filename, content] : pendingWrites) { + std::string filePath = (outputPath / filename).string(); + REXCODEGEN_TRACE("flush_pending_writes: filePath={}", filePath); + + bool shouldWrite = true; + + FILE* f = fopen(filePath.c_str(), "rb"); + if (f) { + std::vector temp; + + fseek(f, 0, SEEK_END); + long fileSize = ftell(f); + if (fileSize == static_cast(content.size())) { + fseek(f, 0, SEEK_SET); + temp.resize(fileSize); + fread(temp.data(), 1, fileSize, f); + + shouldWrite = !XXH128_isEqual(XXH3_128bits(temp.data(), temp.size()), + XXH3_128bits(content.data(), content.size())); + } + fclose(f); + } + + if (shouldWrite) { + f = fopen(filePath.c_str(), "wb"); + if (!f) { + REXCODEGEN_ERROR("Failed to open file for writing: {}", filePath); + continue; + } + fwrite(content.data(), 1, content.size(), f); + fclose(f); + REXCODEGEN_TRACE("Wrote {} bytes to {}", content.size(), filePath); + } + + writtenFiles_.push_back(filename); + } + + pendingWrites.clear(); +} + +} // namespace rex::codegen diff --git a/src/codegen/config.cpp b/src/codegen/config.cpp new file mode 100644 index 0000000..47ccd26 --- /dev/null +++ b/src/codegen/config.cpp @@ -0,0 +1,625 @@ +/** + * @file rexcodegen/config.cpp + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + * + * @remarks Based on XenonRecomp/UnleashedRecomp toml config + */ + +// TOML config file loading + +#include +#include +#include + +#include + +#include +#include + +#include "codegen_logging.h" + +#include + +namespace rex::codegen { + +namespace { + +/// Maximum nesting depth for include chains. +constexpr uint32_t kMaxIncludeDepth = 32; + +/// Parse a hex address string (with or without "0x"/"0X" prefix). +std::optional ParseHexAddress(const std::string& keyStr) { + try { + if (keyStr.starts_with("0x") || keyStr.starts_with("0X")) { + return static_cast(std::stoul(keyStr.substr(2), nullptr, 16)); + } else { + return static_cast(std::stoul(keyStr, nullptr, 16)); + } + } catch (...) { + return std::nullopt; + } +} + +// --------------------------------------------------------------------------- +// Scalar merge helpers -- log overrides at debug level +// --------------------------------------------------------------------------- + +template +void MergeScalar(T& dst, const T& src, const char* name) { + if (src != T{} && src != dst) { + if (dst != T{}) { + if constexpr (std::is_same_v) { + REXCODEGEN_DEBUG("[config] {}: {} -> {} (overridden)", name, dst, src); + } else if constexpr (std::is_same_v) { + REXCODEGEN_DEBUG("[config] {}: \"{}\" -> \"{}\" (overridden)", name, dst, src); + } else { + REXCODEGEN_DEBUG("[config] {}: {} -> {} (overridden)", name, dst, src); + } + } + dst = src; + } +} + +/// Overload for booleans where the "zero" state (false) is meaningful. +/// Only skip the merge when the overlay explicitly did not set the key. +void MergeBool(bool& dst, bool src, bool present, const char* name) { + if (!present) + return; + if (src != dst) { + REXCODEGEN_DEBUG("[config] {}: {} -> {} (overridden)", name, dst ? "true" : "false", + src ? "true" : "false"); + } + dst = src; +} + +// --------------------------------------------------------------------------- +// Apply a single parsed TOML table onto the config (merge semantics) +// --------------------------------------------------------------------------- + +void ApplyToml(const toml::table& toml, RecompilerConfig& cfg, const std::string& filePath) { + // --- Scalars: last wins --- + + // String scalars (only override if present in this file) + if (auto v = toml["project_name"].value()) { + MergeScalar(cfg.projectName, *v, "project_name"); + } + if (auto v = toml["file_path"].value()) { + MergeScalar(cfg.filePath, *v, "file_path"); + } + if (auto v = toml["out_directory_path"].value()) { + MergeScalar(cfg.outDirectoryPath, *v, "out_directory_path"); + } + if (auto v = toml["template_dir"].value()) { + MergeScalar(cfg.templateDir, *v, "template_dir"); + } + if (auto v = toml["patch_file_path"].value()) { + MergeScalar(cfg.patchFilePath, *v, "patch_file_path"); + } + if (auto v = toml["patched_file_path"].value()) { + MergeScalar(cfg.patchedFilePath, *v, "patched_file_path"); + } + + // Bool scalars + auto hasBool = [&](const char* key) -> bool { return toml[key].is_boolean(); }; + MergeBool(cfg.skipLr, toml["skip_lr"].value_or(false), hasBool("skip_lr"), "skip_lr"); + MergeBool(cfg.skipMsr, toml["skip_msr"].value_or(false), hasBool("skip_msr"), "skip_msr"); + MergeBool(cfg.ctrAsLocalVariable, toml["ctr_as_local"].value_or(false), hasBool("ctr_as_local"), + "ctr_as_local"); + MergeBool(cfg.xerAsLocalVariable, toml["xer_as_local"].value_or(false), hasBool("xer_as_local"), + "xer_as_local"); + MergeBool(cfg.reservedRegisterAsLocalVariable, toml["reserved_as_local"].value_or(false), + hasBool("reserved_as_local"), "reserved_as_local"); + MergeBool(cfg.crRegistersAsLocalVariables, toml["cr_as_local"].value_or(false), + hasBool("cr_as_local"), "cr_as_local"); + MergeBool(cfg.nonArgumentRegistersAsLocalVariables, toml["non_argument_as_local"].value_or(false), + hasBool("non_argument_as_local"), "non_argument_as_local"); + MergeBool(cfg.nonVolatileRegistersAsLocalVariables, toml["non_volatile_as_local"].value_or(false), + hasBool("non_volatile_as_local"), "non_volatile_as_local"); + MergeBool(cfg.generateExceptionHandlers, toml["generate_exception_handlers"].value_or(false), + hasBool("generate_exception_handlers"), "generate_exception_handlers"); + if (hasBool("is_dll")) { + cfg.isDll = toml["is_dll"].value_or(false); + } + + // Integer scalars (only override if present) + if (auto v = toml["longjmp_address"].value()) { + uint32_t addr = static_cast(*v); + MergeScalar(cfg.longJmpAddress, addr, "longjmp_address"); + } + if (auto v = toml["setjmp_address"].value()) { + uint32_t addr = static_cast(*v); + MergeScalar(cfg.setJmpAddress, addr, "setjmp_address"); + } + + // --- [analysis] section scalars --- + if (auto* analysisTable = toml["analysis"].as_table()) { + if (auto v = (*analysisTable)["max_jump_extension"].value()) { + MergeScalar(cfg.maxJumpExtension, *v, "analysis.max_jump_extension"); + } + if (auto v = (*analysisTable)["data_region_threshold"].value()) { + MergeScalar(cfg.dataRegionThreshold, *v, "analysis.data_region_threshold"); + } + if (auto v = (*analysisTable)["large_function_threshold"].value()) { + MergeScalar(cfg.largeFunctionThreshold, *v, "analysis.large_function_threshold"); + } + + // exceptionHandlerFuncHints -- push_back then deduplicate at end + if (auto handlers = (*analysisTable)["exception_handler_funcs"].as_array()) { + for (const auto& elem : *handlers) { + if (auto val = elem.value()) { + cfg.exceptionHandlerFuncHints.push_back(static_cast(*val)); + } + } + } + } + + // --- Keyed tables: additive, same key = last wins --- + + // [rexcrt] + if (auto* rexcrt = toml["rexcrt"].as_table()) { + size_t added = 0; + for (const auto& [name, val] : *rexcrt) { + if (auto addr = val.value()) { + auto key = std::string(name); + auto it = cfg.rexcrtFunctions.find(key); + if (it != cfg.rexcrtFunctions.end()) { + REXCODEGEN_DEBUG("[config] [rexcrt] {} overridden: 0x{:08X} -> 0x{:08X}", key, + it->second, static_cast(*addr)); + } + cfg.rexcrtFunctions[key] = static_cast(*addr); + ++added; + } + } + if (added > 0) { + REXCODEGEN_DEBUG("[config] [rexcrt] added/updated {} entries from {}", added, filePath); + } + } + + // [functions] + if (auto functionsTable = toml["functions"].as_table()) { + size_t added = 0; + for (auto& [key, value] : *functionsTable) { + std::string keyStr(key.str()); + auto addrOpt = ParseHexAddress(keyStr); + if (!addrOpt) { + REXCODEGEN_ERROR("Invalid function address key: {}", keyStr); + continue; + } + uint32_t address = *addrOpt; + + auto* table = value.as_table(); + if (!table) { + REXCODEGEN_ERROR("Invalid [functions] entry at 0x{:08X}: expected table", address); + continue; + } + + FunctionConfig fcfg; + fcfg.size = (*table)["size"].value_or(0u); + fcfg.end = (*table)["end"].value_or(0u); + fcfg.name = (*table)["name"].value_or(std::string{}); + fcfg.parent = (*table)["parent"].value_or(0u); + + if (fcfg.size && fcfg.end) { + REXCODEGEN_ERROR("Function 0x{:08X}: cannot specify both 'size' and 'end'", address); + continue; + } + if (fcfg.end && fcfg.end <= address) { + REXCODEGEN_ERROR("Function 0x{:08X}: 'end' (0x{:08X}) must be greater than address", + address, fcfg.end); + continue; + } + + auto it = cfg.functions.find(address); + if (it != cfg.functions.end()) { + REXCODEGEN_DEBUG("[config] [functions] 0x{:08X} overridden from {}", address, filePath); + } + cfg.functions.insert_or_assign(address, std::move(fcfg)); + ++added; + } + if (added > 0) { + REXCODEGEN_DEBUG("[config] [functions] added/updated {} entries from {}", added, filePath); + } + } + + // --- Arrays of tables: deduplicated by primary key (address), last wins --- + + // [[invalid_instructions]] -- keyed by "data" address + if (auto invalidArray = toml["invalid_instructions"].as_array()) { + for (auto& entry : *invalidArray) { + auto* table = entry.as_table(); + if (!table) { + REXCODEGEN_ERROR("Invalid [[invalid_instructions]] entry: expected table"); + continue; + } + + auto data_opt = (*table)["data"].value(); + auto size_opt = (*table)["size"].value(); + + if (!data_opt) { + REXCODEGEN_ERROR("Missing 'data' in [[invalid_instructions]] entry"); + continue; + } + if (!size_opt) { + REXCODEGEN_ERROR("Missing 'size' in [[invalid_instructions]] entry"); + continue; + } + + auto it = cfg.invalidInstructionHints.find(*data_opt); + if (it != cfg.invalidInstructionHints.end()) { + REXCODEGEN_DEBUG("[config] [[invalid_instructions]] 0x{:08X} overridden from {}", + *data_opt, filePath); + } + cfg.invalidInstructionHints.insert_or_assign(*data_opt, *size_opt); + } + } + + // [[switch_tables]] -- keyed by "address" + if (auto switchTableArray = toml["switch_tables"].as_array()) { + for (auto& entry : *switchTableArray) { + auto* table = entry.as_table(); + if (!table) { + REXCODEGEN_ERROR("Invalid [[switch_tables]] entry: expected table"); + continue; + } + + auto address_opt = (*table)["address"].value(); + auto register_opt = (*table)["register"].value(); + auto labels_array = (*table)["labels"].as_array(); + + if (!address_opt) { + REXCODEGEN_ERROR("Missing 'address' in [[switch_tables]] entry"); + continue; + } + if (!register_opt) { + REXCODEGEN_ERROR("Missing 'register' in [[switch_tables]] entry"); + continue; + } + if (!labels_array) { + REXCODEGEN_ERROR("Missing 'labels' in [[switch_tables]] entry"); + continue; + } + + JumpTable jt; + jt.bctrAddress = *address_opt; + jt.tableAddress = 0; + jt.indexRegister = static_cast(*register_opt); + + for (auto& label : *labels_array) { + if (auto label_val = label.value()) { + jt.targets.push_back(static_cast(*label_val)); + } + } + + if (jt.targets.empty()) { + REXCODEGEN_ERROR("Empty 'labels' array in [[switch_tables]] at 0x{:08X}", *address_opt); + continue; + } + + auto it = cfg.switchTables.find(*address_opt); + if (it != cfg.switchTables.end()) { + REXCODEGEN_DEBUG("[config] [[switch_tables]] 0x{:08X} overridden from {}", *address_opt, + filePath); + } + size_t label_count = jt.targets.size(); + cfg.switchTables.insert_or_assign(*address_opt, std::move(jt)); + REXCODEGEN_DEBUG("Loaded manual switch table at 0x{:08X} with {} labels", *address_opt, + label_count); + } + } + + // [[midasm_hook]] -- keyed by "address" + if (auto midAsmHookArray = toml["midasm_hook"].as_array()) { + for (auto& entry : *midAsmHookArray) { + auto* table = entry.as_table(); + if (!table) { + REXCODEGEN_ERROR("Invalid [[midasm_hook]] entry: expected table"); + continue; + } + + auto address_opt = (*table)["address"].value(); + auto name_opt = (*table)["name"].value(); + + if (!address_opt) { + REXCODEGEN_ERROR("Missing 'address' in [[midasm_hook]] entry"); + continue; + } + if (!name_opt) { + REXCODEGEN_ERROR("Missing 'name' in [[midasm_hook]] entry"); + continue; + } + + MidAsmHook midAsmHook; + midAsmHook.name = *name_opt; + + if (auto registerArray = (*table)["registers"].as_array()) { + for (auto& reg : *registerArray) { + if (auto reg_str = reg.value()) { + midAsmHook.registers.push_back(*reg_str); + } + } + } + + midAsmHook.ret = (*table)["return"].value_or(false); + midAsmHook.returnOnTrue = (*table)["return_on_true"].value_or(false); + midAsmHook.returnOnFalse = (*table)["return_on_false"].value_or(false); + + midAsmHook.jumpAddress = (*table)["jump_address"].value_or(0u); + midAsmHook.jumpAddressOnTrue = (*table)["jump_address_on_true"].value_or(0u); + midAsmHook.jumpAddressOnFalse = (*table)["jump_address_on_false"].value_or(0u); + + if ((midAsmHook.ret && midAsmHook.jumpAddress != 0) || + (midAsmHook.returnOnTrue && midAsmHook.jumpAddressOnTrue != 0) || + (midAsmHook.returnOnFalse && midAsmHook.jumpAddressOnFalse != 0)) { + REXCODEGEN_ERROR("{}: can't return and jump at the same time", midAsmHook.name); + } + + if ((midAsmHook.ret || midAsmHook.jumpAddress != 0) && + (midAsmHook.returnOnFalse || midAsmHook.returnOnTrue || + midAsmHook.jumpAddressOnFalse != 0 || midAsmHook.jumpAddressOnTrue != 0)) { + REXCODEGEN_ERROR("{}: can't mix direct and conditional return/jump", midAsmHook.name); + } + + midAsmHook.afterInstruction = (*table)["after_instruction"].value_or(false); + + auto it = cfg.midAsmHooks.find(*address_opt); + if (it != cfg.midAsmHooks.end()) { + REXCODEGEN_DEBUG("[config] [[midasm_hook]] 0x{:08X} overridden from {}", *address_opt, + filePath); + } + cfg.midAsmHooks.insert_or_assign(*address_opt, std::move(midAsmHook)); + } + } + + // --- Sets: additive --- + + // indirect_calls -> knownIndirectCallHints (set) + if (auto indirectCallArray = toml["indirect_calls"].as_array()) { + for (auto& entry : *indirectCallArray) { + if (auto addr = entry.value()) { + cfg.knownIndirectCallHints.insert(static_cast(*addr)); + REXCODEGEN_DEBUG("Loaded known indirect call hint at 0x{:08X}", *addr); + } + } + } +} + +bool ApplyTableWithIncludes(const toml::table& tbl, const std::filesystem::path& base_dir, + RecompilerConfig& cfg, std::set& visited, uint32_t depth, + const std::string& description); + +bool LoadRecursive(const std::filesystem::path& filePath, RecompilerConfig& cfg, + std::set& visited, uint32_t depth) { + if (depth > kMaxIncludeDepth) { + REXCODEGEN_ERROR("[config] include depth exceeds maximum ({}) at: {}", kMaxIncludeDepth, + filePath.string()); + return false; + } + + std::error_code ec; + auto canonical = std::filesystem::canonical(filePath, ec); + if (ec) { + REXCODEGEN_ERROR("[config] cannot resolve path '{}': {}", filePath.string(), ec.message()); + return false; + } + std::string canonicalStr = canonical.string(); + if (visited.contains(canonicalStr)) { + REXCODEGEN_ERROR("[config] circular include detected: {}", canonicalStr); + return false; + } + visited.insert(canonicalStr); + + toml::table toml; + try { + toml = toml::parse_file(canonicalStr); + } catch (const toml::parse_error& e) { + REXCODEGEN_ERROR("Failed to parse config file '{}': {}", canonicalStr, e.what()); + return false; + } + REXCODEGEN_DEBUG("[config] loaded: {}", filePath.filename().string()); + return ApplyTableWithIncludes(toml, canonical.parent_path(), cfg, visited, depth, + filePath.filename().string()); +} + +bool ApplyTableWithIncludes(const toml::table& tbl, const std::filesystem::path& base_dir, + RecompilerConfig& cfg, std::set& visited, uint32_t depth, + const std::string& description) { + // Process includes first (depth-first), so this table's own values win. + if (auto* includesArray = tbl["includes"].as_array()) { + for (const auto& elem : *includesArray) { + if (auto includePath = elem.value()) { + auto resolved = base_dir / *includePath; + if (!std::filesystem::exists(resolved)) { + REXCODEGEN_ERROR("[config] included file not found: {} (resolved from {})", *includePath, + description); + return false; + } + if (!LoadRecursive(resolved, cfg, visited, depth + 1)) { + return false; + } + } + } + } + ApplyToml(tbl, cfg, description); + return true; +} + +} // namespace + +// --------------------------------------------------------------------------- +// Public API +// --------------------------------------------------------------------------- + +namespace { + +bool FinalizeConfig(RecompilerConfig& cfg) { + if (!cfg.functions.empty()) { + size_t chunks_count = 0; + for (const auto& [addr, fc] : cfg.functions) { + if (fc.isChunk()) + chunks_count++; + } + REXCODEGEN_TRACE("Loaded {} function configs ({} standalone, {} chunks)", cfg.functions.size(), + cfg.functions.size() - chunks_count, chunks_count); + } + if (!cfg.exceptionHandlerFuncHints.empty()) { + std::sort(cfg.exceptionHandlerFuncHints.begin(), cfg.exceptionHandlerFuncHints.end()); + cfg.exceptionHandlerFuncHints.erase( + std::unique(cfg.exceptionHandlerFuncHints.begin(), cfg.exceptionHandlerFuncHints.end()), + cfg.exceptionHandlerFuncHints.end()); + } + + bool ok = true; + if (cfg.filePath.empty()) { + REXCODEGEN_ERROR("Missing required field: file_path"); + ok = false; + } + + auto result = cfg.Validate(); + for (const auto& warning : result.warnings) { + REXCODEGEN_WARN("[config] {}", warning); + } + for (const auto& error : result.errors) { + REXCODEGEN_ERROR("[config] {}", error); + } + if (!result.valid) { + ok = false; + } + return ok; +} + +} // namespace + +bool RecompilerConfig::Load(const std::string_view& configFilePath) { + std::set visited; + std::filesystem::path path(configFilePath); + if (!LoadRecursive(path, *this, visited, 0)) { + return false; + } + return FinalizeConfig(*this); +} + +bool RecompilerConfig::LoadFromTable(const toml::table& tbl, + const std::filesystem::path& base_dir) { + std::set visited; + if (!ApplyTableWithIncludes(tbl, base_dir, *this, visited, 0, "")) { + return false; + } + return FinalizeConfig(*this); +} + +RecompilerConfig::ValidationResult RecompilerConfig::Validate() const { + ValidationResult result; + + // Helper to check 4-byte alignment (PPC instructions are 4-byte aligned) + auto checkAlignment = [&](uint32_t addr, const char* name) { + if (addr != 0 && (addr & 0x3) != 0) { + result.errors.push_back(fmt::format("{} address 0x{:08X} is not 4-byte aligned", name, addr)); + result.valid = false; + } + }; + + // Check special address alignment + checkAlignment(longJmpAddress, "longjmp"); + checkAlignment(setJmpAddress, "setjmp"); + + for (const auto& [name, addr] : rexcrtFunctions) { + if (addr & 0x3) { + result.errors.push_back( + fmt::format("rexcrt function '{}' address 0x{:08X} is not 4-byte aligned", name, addr)); + result.valid = false; + } + } + + // Check function address alignment + for (const auto& [addr, size] : functions) { + if (addr & 0x3) { + result.errors.push_back(fmt::format("Function address 0x{:08X} is not 4-byte aligned", addr)); + result.valid = false; + } + } + + // Check for duplicate function boundaries + { + std::map seen; + for (const auto& [addr, cfg] : functions) { + uint32_t funcSize = cfg.getSize(addr); + auto it = seen.find(addr); + if (it != seen.end()) { + if (it->second == funcSize) { + result.errors.push_back( + fmt::format("Duplicate function boundary: 0x{:08X} size 0x{:X}", addr, funcSize)); + } else { + result.errors.push_back(fmt::format("Conflicting sizes at 0x{:08X}: 0x{:X} vs 0x{:X}", + addr, it->second, funcSize)); + } + result.valid = false; + } + seen[addr] = funcSize; + } + } + + // Check for overlapping function boundaries (standalone functions only) + { + std::vector> sorted; + for (const auto& [addr, cfg] : functions) { + if (!cfg.isChunk()) { + sorted.emplace_back(addr, cfg.getSize(addr)); + } + } + std::sort(sorted.begin(), sorted.end()); + for (size_t i = 1; i < sorted.size(); ++i) { + uint32_t prev_end = sorted[i - 1].first + sorted[i - 1].second; + if (sorted[i].first < prev_end) { + result.errors.push_back(fmt::format( + "Overlapping boundaries: 0x{:08X}+0x{:X} overlaps 0x{:08X}+0x{:X}", sorted[i - 1].first, + sorted[i - 1].second, sorted[i].first, sorted[i].second)); + result.valid = false; + } + } + } + + // Validate rexcrt all-or-nothing groups -- originals are stripped so partial + // sets would leave the game with missing CRT functions at runtime. + if (!rexcrtFunctions.empty()) { + auto checkGroup = [&](const char* groupName, std::initializer_list required) { + size_t found = 0; + for (const char* name : required) { + if (rexcrtFunctions.contains(name)) + ++found; + } + if (found > 0 && found < required.size()) { + std::string missing; + for (const char* name : required) { + if (!rexcrtFunctions.contains(name)) { + if (!missing.empty()) + missing += ", "; + missing += name; + } + } + result.errors.push_back( + fmt::format("[rexcrt] {} group is incomplete ({}/{} specified), missing: {}", groupName, + found, required.size(), missing)); + result.valid = false; + } + }; + + checkGroup("heap", {"RtlAllocateHeap", "RtlFreeHeap", "RtlSizeHeap", "RtlReAllocateHeap"}); + } + + // Check required fields + if (filePath.empty()) { + result.warnings.push_back("file_path is empty"); + } + if (outDirectoryPath.empty()) { + result.warnings.push_back("out_directory_path is empty"); + } + + return result; +} + +} // namespace rex::codegen diff --git a/src/codegen/decoded_binary.cpp b/src/codegen/decoded_binary.cpp new file mode 100644 index 0000000..f148099 --- /dev/null +++ b/src/codegen/decoded_binary.cpp @@ -0,0 +1,201 @@ +/** + * @file decoded_binary.cpp + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "decoded_binary.h" + +#include + +#include +#include + +using rex::memory::load_and_swap; + +namespace rex::codegen { + +//============================================================================= +// DecodedBinary Implementation +//============================================================================= + +DecodedBinary::DecodedBinary(const BinaryView& binary) : binary_(binary) {} + +void DecodedBinary::decode() { + sections_.clear(); + codeRegions_.clear(); + + for (const auto& section : binary_.sections()) { + Section sec; + sec.base = section.baseAddress; + sec.size = section.size; + + // Copy raw section data (needed for reading jump tables and other data) + sec.data.assign(section.data, section.data + section.size); + + // Only decode instructions for executable sections + if (section.executable) { + // Reserve space for instructions + size_t insnCount = section.size / 4; + sec.instructions.reserve(insnCount); + + for (uint32_t offset = 0; offset < section.size; offset += 4) { + uint32_t addr = section.baseAddress + offset; + uint32_t raw = load_and_swap(section.data + offset); + + auto insn = rex::codegen::ppc::decode_instruction(addr, raw); + sec.instructions.push_back(insn); + } + } + + sections_.push_back(std::move(sec)); + } + + // Sort sections by base address for binary search + std::sort(sections_.begin(), sections_.end(), + [](const Section& a, const Section& b) { return a.base < b.base; }); + + // Compute code regions + computeCodeRegions(); +} + +DecodedInsn* DecodedBinary::get(uint32_t addr) { + Section* sec = findSection(addr); + return sec ? sec->get(addr) : nullptr; +} + +const DecodedInsn* DecodedBinary::get(uint32_t addr) const { + const Section* sec = findSection(addr); + return sec ? sec->get(addr) : nullptr; +} + +InsnRange DecodedBinary::range(uint32_t start, uint32_t end) { + Section* sec = findSection(start); + if (!sec || !sec->contains(end - 4)) { + return InsnRange(nullptr, nullptr); + } + + uint32_t startIdx = (start - sec->base) / 4; + uint32_t endIdx = (end - sec->base) / 4; + + // Clamp to section bounds + endIdx = std::min(endIdx, static_cast(sec->instructions.size())); + + return InsnRange(&sec->instructions[startIdx], &sec->instructions[endIdx]); +} + +const uint8_t* DecodedBinary::rawData(uint32_t addr, size_t len) const { + const Section* sec = findSection(addr); + if (!sec) + return nullptr; + + uint32_t offset = addr - sec->base; + if (offset + len > sec->data.size()) + return nullptr; + + return sec->data.data() + offset; +} + +const CodeRegion* DecodedBinary::regionContaining(uint32_t addr) const { + for (const auto& region : codeRegions_) { + if (region.contains(addr)) + return ®ion; + } + return nullptr; +} + +bool DecodedBinary::crossesNullBoundary(uint32_t from, uint32_t to) const { + const CodeRegion* fromRegion = regionContaining(from); + const CodeRegion* toRegion = regionContaining(to); + + // If either is not in a code region, or they're in different regions + return !fromRegion || !toRegion || fromRegion != toRegion; +} + +bool DecodedBinary::isInCodeRegion(uint32_t addr) const { + return regionContaining(addr) != nullptr; +} + +bool DecodedBinary::isNullPadding(uint32_t addr) const { + const DecodedInsn* insn = get(addr); + return insn && isInvalid(*insn); +} + +size_t DecodedBinary::instructionCount() const { + size_t count = 0; + for (const auto& sec : sections_) { + count += sec.instructions.size(); + } + return count; +} + +DecodedBinary::Section* DecodedBinary::findSection(uint32_t addr) { + for (auto& sec : sections_) { + if (sec.contains(addr)) + return &sec; + } + return nullptr; +} + +const DecodedBinary::Section* DecodedBinary::findSection(uint32_t addr) const { + for (const auto& sec : sections_) { + if (sec.contains(addr)) + return &sec; + } + return nullptr; +} + +void DecodedBinary::computeCodeRegions() { + codeRegions_.clear(); + + // Minimum consecutive nulls to consider as a boundary + constexpr size_t kMinNullRun = 2; + + for (const auto& sec : sections_) { + if (sec.instructions.empty()) + continue; + + CodeRegion current; + current.start = sec.base; + size_t nullRun = 0; + bool inCode = false; + + for (size_t i = 0; i < sec.instructions.size(); i++) { + const auto& insn = sec.instructions[i]; + bool isNull = isInvalid(insn); + + if (isNull) { + nullRun++; + if (inCode && nullRun >= kMinNullRun) { + // End of code region (at start of null run) + current.end = sec.base + static_cast((i - nullRun + 1) * 4); + if (current.end > current.start) { + codeRegions_.push_back(current); + } + inCode = false; + } + } else { + if (!inCode) { + // Start of new code region + current.start = sec.base + static_cast(i * 4); + inCode = true; + } + nullRun = 0; + } + } + + // Close final region if still in code + if (inCode) { + current.end = sec.base + sec.size; + if (current.end > current.start) { + codeRegions_.push_back(current); + } + } + } +} + +} // namespace rex::codegen diff --git a/src/codegen/decoded_binary.h b/src/codegen/decoded_binary.h new file mode 100644 index 0000000..75a4afb --- /dev/null +++ b/src/codegen/decoded_binary.h @@ -0,0 +1,247 @@ +/** + * @file rex/codegen/decoded_binary.h + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include "ppc/instruction.h" + +#include +#include +#include +#include + +#include +#include + +namespace rex::codegen { + +using DecodedInsn = rex::codegen::ppc::Instruction; + +//============================================================================= +// Instruction Range Iterator +//============================================================================= + +class InsnRange { + public: + class Iterator { + public: + using iterator_category = std::forward_iterator_tag; + using value_type = DecodedInsn*; + using difference_type = std::ptrdiff_t; + using pointer = DecodedInsn**; + using reference = DecodedInsn*&; + + explicit Iterator(DecodedInsn* ptr) : ptr_(ptr) {} + + DecodedInsn* operator*() const { return ptr_; } + Iterator& operator++() { + ++ptr_; + return *this; + } + Iterator operator++(int) { + Iterator tmp = *this; + ++ptr_; + return tmp; + } + bool operator==(const Iterator& other) const { return ptr_ == other.ptr_; } + bool operator!=(const Iterator& other) const { return ptr_ != other.ptr_; } + + private: + DecodedInsn* ptr_; + }; + + InsnRange(DecodedInsn* begin, DecodedInsn* end) : begin_(begin), end_(end) {} + + Iterator begin() const { return Iterator(begin_); } + Iterator end() const { return Iterator(end_); } + size_t size() const { return end_ - begin_; } + bool empty() const { return begin_ == end_; } + + DecodedInsn* data() const { return begin_; } + + private: + DecodedInsn* begin_; + DecodedInsn* end_; +}; + +//============================================================================= +// Decoded Binary - Single-pass instruction decoder +//============================================================================= + +class DecodedBinary { + public: + explicit DecodedBinary(const BinaryView& binary); + + // Non-copyable, non-movable (holds reference to binary) + DecodedBinary(DecodedBinary&&) = delete; + DecodedBinary& operator=(DecodedBinary&&) = delete; + DecodedBinary(const DecodedBinary&) = delete; + DecodedBinary& operator=(const DecodedBinary&) = delete; + + /// Decode all executable sections (call once after construction) + void decode(); + + /// Get instruction at address (O(1) lookup) + /// Returns nullptr if address not in any executable section + DecodedInsn* get(uint32_t addr); + const DecodedInsn* get(uint32_t addr) const; + + /// Get range of instructions [start, end) + /// Returns empty range if addresses not in same section + InsnRange range(uint32_t start, uint32_t end); + + /// Get raw data at address (for reading non-instruction data like jump tables) + const uint8_t* rawData(uint32_t addr, size_t len) const; + + /// Read a value at address (with byte-swap for big-endian) + template + std::optional read(uint32_t addr) const; + + /// Get all code regions (separated by null padding) + const std::vector& codeRegions() const { return codeRegions_; } + + /// Find code region containing address + const CodeRegion* regionContaining(uint32_t addr) const; + + /// Check if branch from->to crosses a null boundary + bool crossesNullBoundary(uint32_t from, uint32_t to) const; + + /// Check if address is in any code region + bool isInCodeRegion(uint32_t addr) const; + + /// Check if instruction at address is null/invalid + bool isNullPadding(uint32_t addr) const; + + /// Statistics + size_t instructionCount() const; + size_t sectionCount() const { return sections_.size(); } + + private: + struct Section { + uint32_t base; + uint32_t size; + std::vector instructions; + std::vector data; // Copy of raw section data + + bool contains(uint32_t addr) const { return addr >= base && addr < base + size; } + + DecodedInsn* get(uint32_t addr) { + if (!contains(addr)) + return nullptr; + uint32_t idx = (addr - base) / 4; + if (idx >= instructions.size()) + return nullptr; + return &instructions[idx]; + } + + const DecodedInsn* get(uint32_t addr) const { + if (!contains(addr)) + return nullptr; + uint32_t idx = (addr - base) / 4; + if (idx >= instructions.size()) + return nullptr; + return &instructions[idx]; + } + }; + + const BinaryView& binary_; + std::vector
sections_; + std::vector codeRegions_; + + /// Compute code regions by finding null padding boundaries + void computeCodeRegions(); + + /// Find section containing address + Section* findSection(uint32_t addr); + const Section* findSection(uint32_t addr) const; +}; + +//============================================================================= +// Template Implementation +//============================================================================= + +template +std::optional DecodedBinary::read(uint32_t addr) const { + const uint8_t* data = rawData(addr, sizeof(T)); + if (!data) + return std::nullopt; + + T value; + std::memcpy(&value, data, sizeof(T)); + + // Byte-swap for big-endian PPC + if constexpr (sizeof(T) == 2) { + value = static_cast((value >> 8) | (value << 8)); + } else if constexpr (sizeof(T) == 4) { + value = static_cast(((value >> 24) & 0xFF) | ((value >> 8) & 0xFF00) | + ((value << 8) & 0xFF0000) | ((value << 24) & 0xFF000000)); + } else if constexpr (sizeof(T) == 8) { + value = static_cast(((value >> 56) & 0xFF) | ((value >> 40) & 0xFF00) | + ((value >> 24) & 0xFF0000) | ((value >> 8) & 0xFF000000) | + ((value << 8) & 0xFF00000000ULL) | ((value << 24) & 0xFF0000000000ULL) | + ((value << 40) & 0xFF000000000000ULL) | + ((value << 56) & 0xFF00000000000000ULL)); + } + + return value; +} + +//============================================================================= +// Helper functions for branch analysis (using existing arch::ppc) +//============================================================================= + +/// Check if instruction is a branch +inline bool isBranch(const DecodedInsn& insn) { + return insn.is_branch(); +} + +/// Check if instruction is a call (branch with link) +inline bool isCall(const DecodedInsn& insn) { + return insn.is_call(); +} + +/// Check if instruction is a return (blr) +inline bool isReturn(const DecodedInsn& insn) { + return insn.is_return(); +} + +/// Check if instruction is indirect branch (bcctr/bclr) +inline bool isIndirect(const DecodedInsn& insn) { + return insn.is_indirect_branch(); +} + +/// Check if instruction is a terminator (unconditional branch, return, bctr) +inline bool isTerminator(const DecodedInsn& insn) { + return rex::codegen::ppc::is_terminator_instruction(insn.opcode); +} + +/// Check if instruction is conditional branch +inline bool isConditional(const DecodedInsn& insn) { + return insn.is_conditional(); +} + +/// Check if instruction is lis (addis rD, 0, imm) +inline bool isLis(const DecodedInsn& insn) { + return insn.opcode == rex::codegen::ppc::Opcode::lis; +} + +/// Get branch target address (for direct branches) +inline std::optional getBranchTarget(const DecodedInsn& insn) { + return insn.branch_target; +} + +/// Check if instruction is null/invalid (null padding) +inline bool isInvalid(const DecodedInsn& insn) { + uint32_t raw = static_cast(insn.code); + return raw == 0x00000000 || raw == 0xFFFFFFFF || + insn.opcode == rex::codegen::ppc::Opcode::kUnknown; +} + +} // namespace rex::codegen diff --git a/src/codegen/function_graph.cpp b/src/codegen/function_graph.cpp new file mode 100644 index 0000000..0c0d1be --- /dev/null +++ b/src/codegen/function_graph.cpp @@ -0,0 +1,1216 @@ +/** + * @file rexcodegen/function_graph.cpp + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "ppc/instruction.h" +#include "ppc/disasm.h" +#include "builders/builder_context.h" +#include "builders.h" + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "codegen_logging.h" + +#include +#include + +using rex::codegen::ppc::Disassemble; +using rex::memory::load_and_swap; + +namespace rex::codegen { + +//============================================================================= +// Utility +//============================================================================= + +const char* AuthorityName(FunctionAuthority auth) { + switch (auth) { + case FunctionAuthority::GAP_FILL: + return "gap_fill"; + case FunctionAuthority::DISCOVERED: + return "discovered"; + case FunctionAuthority::VTABLE: + return "vtable"; + case FunctionAuthority::HELPER: + return "helper"; + case FunctionAuthority::PDATA: + return "pdata"; + case FunctionAuthority::CONFIG: + return "config"; + case FunctionAuthority::IMPORT: + return "import"; + default: + return "unknown"; + } +} + +//============================================================================= +// FunctionNode +//============================================================================= + +FunctionNode::FunctionNode(uint32_t base, uint32_t size, FunctionAuthority authority) + : base_(base), size_(size), authority_(authority), state_(FunctionState::kRegistered) { + // Generate default name + char buf[32]; + snprintf(buf, sizeof(buf), "sub_%08X", base); + name_ = buf; + + // All functions start kRegistered - waiting for discover() to assign blocks. + // Authority prevents merging via vacancy checks, not via initial state. +} + +//============================================================================= +// State Machine Methods +//============================================================================= + +void FunctionNode::discover(std::vector blocks, + std::vector instructions, + std::set labels) { + assert(canDiscover() && "Invalid state transition: must be kRegistered"); + + // Non-imports must have blocks + if (!isImport()) { + assert(!blocks.empty() && "Non-import function must have blocks"); + } + + blocks_ = std::move(blocks); + instructions_ = std::move(instructions); + labels_ = std::move(labels); + + // Update size based on blocks + for (const auto& block : blocks_) { + uint32_t blockEnd = block.base + block.size; + if (blockEnd > base_ + size_) { + size_ = blockEnd - base_; + } + } + + state_ = FunctionState::kDiscovered; + REXCODEGEN_DEBUG( + "FunctionNode 0x{:08X} ({}): DISCOVERED with {} blocks, {} instructions, {} labels", base_, + name_, blocks_.size(), instructions_.size(), labels_.size()); +} + +void FunctionNode::discoverAsImport() { + assert(canDiscover() && "Invalid state transition: must be kRegistered"); + assert(isImport() && "Only imports can use discoverAsImport()"); + + // blocks_ and instructions_ remain empty for imports + state_ = FunctionState::kDiscovered; + REXCODEGEN_DEBUG("FunctionNode 0x{:08X} ({}): DISCOVERED as import", base_, name_); +} + +bool FunctionNode::canSeal() const { + if (state_ != FunctionState::kDiscovered) + return false; + if (isImport()) + return true; // Imports can seal without blocks + if (blocks_.empty()) + return false; // Non-imports must have blocks + if (!unresolvedJumps_.empty()) + return false; // All branches must be resolved + return true; +} + +const FunctionAnalysis& FunctionNode::analysis() const { + assert(state_ == FunctionState::kSealed && "Analysis only valid after seal"); + assert(analysis_.has_value() && "Analysis not computed"); + return *analysis_; +} + +void FunctionNode::addBlock(Block block) { + blocks_.push_back(block); + + // Extend size if block extends past current end + uint32_t blockEnd = block.base + block.size; + if (blockEnd > base_ + size_) { + size_ = blockEnd - base_; + } +} + +bool FunctionNode::containsAddress(uint32_t addr) const { + // First check overall bounds + if (addr < base_ || addr >= base_ + size_) { + return false; + } + + // If no blocks defined, use linear range + if (blocks_.empty()) { + return true; + } + + // Check individual blocks + for (const auto& block : blocks_) { + if (block.contains(addr)) { + return true; + } + } + + // For CONFIG and PDATA functions, trust the declared size even if blocks don't cover it + // This handles out-of-line switch cases where compiler places code after epilogue + if (authority_ == FunctionAuthority::CONFIG || authority_ == FunctionAuthority::PDATA) { + return true; // Already passed bounds check above + } + + return false; +} + +void FunctionNode::addLabel(uint32_t addr) { + labels_.insert(addr); +} + +void FunctionNode::addCall(uint32_t site, CallTarget target) { + calls_.push_back({site, std::move(target)}); +} + +void FunctionNode::addTailCall(uint32_t site, CallTarget target) { + tailCalls_.push_back({site, std::move(target)}); +} + +void FunctionNode::addJumpTable(JumpTable jt) { + // All jump table targets become labels + for (uint32_t target : jt.targets) { + labels_.insert(target); + } + jumpTables_.push_back(std::move(jt)); +} + +void FunctionNode::addUnresolvedJump(uint32_t site, uint32_t target, bool isCall, + bool conditional) { + unresolvedJumps_.push_back({site, target, isCall, conditional}); +} + +void FunctionNode::removeUnresolvedJump(uint32_t site) { + auto it = std::remove_if(unresolvedJumps_.begin(), unresolvedJumps_.end(), + [site](const UnresolvedJump& j) { return j.site == site; }); + unresolvedJumps_.erase(it, unresolvedJumps_.end()); +} + +bool FunctionNode::tryResolveAgainst(FunctionNode* newFunction) { + if (isSealed()) + return false; + if (!newFunction) + return false; + + bool anyResolved = false; + + // Check each unresolved jump + for (auto it = unresolvedJumps_.begin(); it != unresolvedJumps_.end();) { + if (it->target == newFunction->base()) { + // Target matches new function's entry point -> external call/tail call + REXCODEGEN_TRACE( + "FunctionNode 0x{:08X}: resolved jump 0x{:08X} -> 0x{:08X} as external to {}", base_, + it->site, it->target, newFunction->name()); + + // Add as tail call (unconditional branch to another function) + addTailCall(it->site, CallTarget::function(newFunction)); + + it = unresolvedJumps_.erase(it); + anyResolved = true; + } else { + ++it; + } + } + + return anyResolved; +} + +bool FunctionNode::tryResolveAgainstImport(uint32_t importAddr, const std::string& importName) { + if (isSealed()) + return false; + + bool anyResolved = false; + + for (auto it = unresolvedJumps_.begin(); it != unresolvedJumps_.end();) { + if (it->target == importAddr) { + REXCODEGEN_TRACE("FunctionNode 0x{:08X}: resolved jump 0x{:08X} -> 0x{:08X} as import {}", + base_, it->site, it->target, importName); + + // Add as tail call to import + addTailCall(it->site, CallTarget::import(importAddr, importName)); + + it = unresolvedJumps_.erase(it); + anyResolved = true; + } else { + ++it; + } + } + + return anyResolved; +} + +bool FunctionNode::tryResolveAsInternalLabel(uint32_t target) { + // Check if target is within our blocks + if (!containsAddress(target)) { + return false; + } + + // It's internal - add as label + addLabel(target); + return true; +} + +void FunctionNode::absorbRegion(uint32_t regionBase, uint32_t regionSize) { + assert(state_ != FunctionState::kSealed && "Cannot absorb into SEALED function"); + + // Add as a new block + addBlock({regionBase, regionSize}); + + REXCODEGEN_DEBUG("FunctionNode 0x{:08X}: absorbed region 0x{:08X}-0x{:08X}, new size=0x{:X}", + base_, regionBase, regionBase + regionSize, size_); +} + +void FunctionNode::seal() { + assert(canSeal() && "Cannot seal: invariants not met"); + + // Sort blocks by address for correct emission order + std::sort(blocks_.begin(), blocks_.end(), + [](const Block& a, const Block& b) { return a.base < b.base; }); + + // Merge overlapping blocks - can happen when multiple paths reach the same code + // (e.g., jump table targets and unconditional branches both targeting an epilogue) + if (blocks_.size() > 1) { + std::vector merged; + merged.reserve(blocks_.size()); + merged.push_back(blocks_[0]); + + for (size_t i = 1; i < blocks_.size(); i++) { + Block& last = merged.back(); + const Block& curr = blocks_[i]; + + // Check for overlap or adjacency + if (curr.base <= last.end()) { + // Extend last block to cover both + uint32_t newEnd = std::max(last.end(), curr.end()); + last.size = newEnd - last.base; + REXCODEGEN_TRACE( + "FunctionNode 0x{:08X}: merged overlapping blocks 0x{:08X}-0x{:08X} and " + "0x{:08X}-0x{:08X}", + base_, last.base, last.base + last.size - (newEnd - last.end()), curr.base, curr.end()); + } else { + merged.push_back(curr); + } + } + + if (merged.size() < blocks_.size()) { + REXCODEGEN_DEBUG("FunctionNode 0x{:08X}: reduced {} blocks to {} after merging", base_, + blocks_.size(), merged.size()); + blocks_ = std::move(merged); + } + } + + // Compute function analysis + FunctionAnalysis analysis; + analysis_ = std::move(analysis); + state_ = FunctionState::kSealed; + + REXCODEGEN_TRACE( + "FunctionNode 0x{:08X} ({}): SEALED with {} blocks, {} labels, {} calls, {} tail calls", + base_, name_, blocks_.size(), labels_.size(), calls_.size(), tailCalls_.size()); +} + +//============================================================================= +// FunctionNode - C++ Code Emission +//============================================================================= + +namespace { + +// Helper: append formatted text to a raw string (matches Recompiler::println pattern) +template +void emit_println(std::string& out, fmt::format_string fmt, Args&&... args) { + fmt::vformat_to(std::back_inserter(out), fmt.get(), fmt::make_format_args(args...)); + out += '\n'; +} + +template +void emit_print(std::string& out, fmt::format_string fmt, Args&&... args) { + fmt::vformat_to(std::back_inserter(out), fmt.get(), fmt::make_format_args(args...)); +} + +} // namespace + +std::string FunctionNode::emitCpp(const EmitContext& ctx) const { + if (authority() == FunctionAuthority::IMPORT) { + return ""; + } + + std::string out; + + // --- Empty stub for functions with no blocks --- + if (blocks().empty()) { + REXCODEGEN_WARN("Function 0x{:08X} has no blocks - generating stub", base()); + + std::string name; + if (base() == ctx.entryPoint) { + name = "xstart"; + } else if (!name_.empty()) { + name = name_; + } else { + name = fmt::format("sub_{:08X}", base()); + } + + emit_println(out, "// STUB: Function at 0x{:08X} has no discovered code blocks", base()); + emit_println(out, "DEFINE_REX_FUNC({}) {{", name); + emit_println(out, "\tREX_FUNC_PROLOGUE();"); + emit_println(out, "}}\n"); + return out; + } + + // --- Check for SEH exception info --- + const SehExceptionInfo* sehInfo = nullptr; + if (hasExceptionInfo()) { + sehInfo = exceptionInfo()->asSeh(); + if (sehInfo && !sehInfo->scopes.empty()) { + REXCODEGEN_TRACE("Function 0x{:08X} has {} SEH scopes", base(), sehInfo->scopes.size()); + } + } + + // --- First pass: collect labels from all blocks --- + std::unordered_set labels; + labels.reserve(64); + + for (const auto& block : blocks()) { + auto* blockData = reinterpret_cast(ctx.binary.translate(block.base)); + if (!blockData) + continue; + + for (size_t addr = block.base; addr < block.end(); addr += 4) { + const uint32_t instruction = + load_and_swap((const uint8_t*)blockData + addr - block.base); + if (!PPC_BL(instruction)) { + const size_t op = PPC_OP(instruction); + if (op == PPC_OP_B) + labels.emplace(addr + PPC_BI(instruction)); + else if (op == PPC_OP_BC) + labels.emplace(addr + PPC_BD(instruction)); + } + + // Labels from config switch tables + auto stIt = ctx.config.switchTables.find(static_cast(addr)); + if (stIt != ctx.config.switchTables.end()) { + for (auto label : stIt->second.targets) + labels.emplace(label); + } + + // Labels and extern declarations from mid-asm hooks + auto hookIt = ctx.config.midAsmHooks.find(static_cast(addr)); + if (hookIt != ctx.config.midAsmHooks.end()) { + if (hookIt->second.returnOnFalse || hookIt->second.returnOnTrue || + hookIt->second.jumpAddressOnFalse != 0 || hookIt->second.jumpAddressOnTrue != 0) { + emit_print(out, "extern bool "); + } else { + emit_print(out, "extern void "); + } + + emit_print(out, "{}(", hookIt->second.name); + for (auto& reg : hookIt->second.registers) { + if (out.back() != '(') + out += ", "; + + switch (reg[0]) { + case 'c': + if (reg == "ctr") + emit_print(out, "PPCRegister& ctr"); + else + emit_print(out, "PPCCRRegister& {}", reg); + break; + case 'x': + emit_print(out, "PPCXERRegister& xer"); + break; + case 'r': + emit_print(out, "PPCRegister& {}", reg); + break; + case 'f': + if (reg == "fpscr") + emit_print(out, "PPCFPSCRRegister& fpscr"); + else + emit_print(out, "PPCRegister& {}", reg); + break; + case 'v': + emit_print(out, "PPCVRegister& {}", reg); + break; + } + } + + emit_println(out, ");\n"); + + if (hookIt->second.jumpAddress != 0) + labels.emplace(hookIt->second.jumpAddress); + if (hookIt->second.jumpAddressOnTrue != 0) + labels.emplace(hookIt->second.jumpAddressOnTrue); + if (hookIt->second.jumpAddressOnFalse != 0) + labels.emplace(hookIt->second.jumpAddressOnFalse); + } + } + } + + // Collect labels from auto-detected jump tables + for (const auto& jt : jumpTables()) { + for (auto label : jt.targets) { + labels.emplace(label); + } + } + + // --- Function name --- + std::string name; + if (base() == ctx.entryPoint) { + name = "xstart"; + } else if (!name_.empty()) { + name = name_; + } else { + name = fmt::format("sub_{:08X}", base()); + } + + // Function signature with weak/alias pattern + emit_println(out, "DEFINE_REX_FUNC({}) {{", name); + emit_println(out, "\tREX_FUNC_PROLOGUE();"); + + // --- Second pass: emit instruction code --- + const JumpTable* activeJt = nullptr; + bool allRecompiled = true; + CSRState csrState = CSRState::Unknown; + RecompilerLocalVariables localVariables; + + // Local map for late-detected jump tables (can't mutate const config) + std::unordered_map lateJumpTables; + + std::string body; + body.reserve(4096); + + ppc_insn insn; + std::unordered_set emittedLabels; + + for (const auto& block : blocks()) { + auto blockBase = block.base; + auto blockEnd = block.end(); + auto* data = reinterpret_cast(ctx.binary.translate(block.base)); + if (!data) { + REXCODEGEN_WARN("Block 0x{:08X} in function 0x{:08X} has no mapped data - skipping", + block.base, base()); + continue; + } + + while (blockBase < blockEnd) { + // Only emit each label once + if (labels.find(blockBase) != labels.end() && emittedLabels.insert(blockBase).second) { + emit_println(body, "loc_{:X}:", blockBase); + csrState = CSRState::Unknown; + } + + // Look up switch table for this address + activeJt = nullptr; + auto stIt = ctx.config.switchTables.find(blockBase); + if (stIt != ctx.config.switchTables.end()) { + activeJt = &stIt->second; + } else { + auto lateIt = lateJumpTables.find(blockBase); + if (lateIt != lateJumpTables.end()) { + activeJt = &lateIt->second; + } + } + + Disassemble(data, 4, blockBase, insn); + + if (insn.opcode == nullptr) { + emit_println(body, "\t// {}", insn.op_str); + if (*data != 0) + REXCODEGEN_WARN("Unable to decode instruction {:X} at {:X}", *data, blockBase); + } else { + // Late jump table detection for bctr + if (insn.opcode->id == PPC_INST_BCTR && !activeJt) { + bool is_switch_pattern = false; + constexpr uint32_t MTCTR_MASK = 0xFC1FFFFF; + constexpr uint32_t MTCTR_OPCODE = 0x7C0003A6; + constexpr uint32_t NOP = 0x60000000; + + for (int i = 1; i <= 3 && !is_switch_pattern; i++) { + uint32_t prev_insn = load_and_swap(data - i); + if ((prev_insn & MTCTR_MASK) == MTCTR_OPCODE) { + is_switch_pattern = true; + for (int j = 1; j < i; j++) { + if (load_and_swap(data - j) != NOP) { + is_switch_pattern = false; + break; + } + } + } else if (prev_insn != NOP) { + break; + } + } + + if (is_switch_pattern) { + FunctionScanner scanner(ctx.binary); + auto jt_opt = scanner.detect_jump_table(blockBase); + if (jt_opt.has_value()) { + lateJumpTables.emplace(blockBase, std::move(*jt_opt)); + activeJt = &lateJumpTables.at(blockBase); + for (auto label : activeJt->targets) { + labels.emplace(label); + } + REXCODEGEN_TRACE("Late-detected jump table at 0x{:08X} with {} entries", blockBase, + activeJt->targets.size()); + } + } + } + + // Emit comment with instruction disassembly + emit_println(body, "\t// {} {}", insn.opcode->name, insn.op_str); + + // Check for mid-asm hook BEFORE instruction + auto hookIt = ctx.config.midAsmHooks.find(blockBase); + bool hasHookBefore = + (hookIt != ctx.config.midAsmHooks.end() && !hookIt->second.afterInstruction); + + // Dispatch instruction to builder + int id = insn.opcode->id; + BuilderContext builderCtx{body, ctx, *this, insn, blockBase, data, + localVariables, csrState, activeJt}; + + if (hasHookBefore) { + builderCtx.emit_mid_asm_hook(); + } + + if (!DispatchInstruction(id, builderCtx)) { + REXCODEGEN_WARN("Unrecognized instruction at 0x{:X}: {}", blockBase, insn.opcode->name); + allRecompiled = false; + } + + // Check for mid-asm hook AFTER instruction + if (hookIt != ctx.config.midAsmHooks.end() && hookIt->second.afterInstruction) { + builderCtx.emit_mid_asm_hook(); + } + } + + blockBase += 4; + ++data; + } + } + + // --- Close function body (or SEH try block) --- + bool generateSeh = sehInfo && !sehInfo->scopes.empty() && ctx.config.generateExceptionHandlers; + if (generateSeh) { + emit_println(body, "\t\t}} SEH_CATCH_ALL {{"); + emit_println(body, "\t\t\tREXLOG_WARN(\"SEH exception caught in sub_{:08X}\");", base()); + + if (sehInfo->frameSize > 0) { + emit_println(body, "\t\t\tctx.r12.s64 = ctx.r31.s64 + {}; // Establisher frame pointer", + sehInfo->frameSize); + } + + for (auto it = sehInfo->scopes.rbegin(); it != sehInfo->scopes.rend(); ++it) { + const auto& scope = *it; + if (scope.filter == 0 && scope.handler != 0) { + emit_println(body, "\t\t\tsub_{:08X}(ctx, base); // __finally handler", scope.handler); + } + } + + if (sehInfo->restoreHelper != 0) { + auto* restoreFn = ctx.graph.getFunction(sehInfo->restoreHelper); + if (restoreFn && !restoreFn->name().empty()) { + emit_println(body, "\t\t\t{}(ctx, base); // Restore caller registers", restoreFn->name()); + } + } + + emit_println(body, "\t\t\tSEH_RETHROW;"); + emit_println(body, "\t\t}} SEH_END"); + emit_println(body, "\t}}\n"); + } else { + emit_println(body, "}}\n"); + } + + // --- Emit local variable declarations, then body --- + if (localVariables.ctr) + emit_println(out, "\tPPCRegister ctr{{}};"); + if (localVariables.xer) + emit_println(out, "\tPPCXERRegister xer{{}};"); + if (localVariables.reserved) + emit_println(out, "\tPPCRegister reserved{{}};"); + + for (size_t i = 0; i < 8; i++) { + if (localVariables.cr[i]) + emit_println(out, "\tPPCCRRegister cr{}{{}};", i); + } + + for (size_t i = 0; i < 32; i++) { + if (localVariables.r[i]) + emit_println(out, "\tPPCRegister r{}{{}};", i); + } + + for (size_t i = 0; i < 32; i++) { + if (localVariables.f[i]) + emit_println(out, "\tPPCRegister f{}{{}};", i); + } + + for (size_t i = 0; i < 128; i++) { + if (localVariables.v[i]) + emit_println(out, "\tPPCVRegister v{}{{}};", i); + } + + if (localVariables.env) + emit_println(out, "\tPPCContext env{{}};"); + if (localVariables.temp) + emit_println(out, "\tPPCRegister temp{{}};"); + if (localVariables.v_temp) + emit_println(out, "\tPPCVRegister vTemp{{}};"); + if (localVariables.ea) + emit_println(out, "\tuint32_t ea{{}};"); + + // If SEH, emit SEH_TRY and indent body + if (generateSeh) { + emit_println(out, "\tSEH_TRY {{"); + std::string indentedBody; + indentedBody.reserve(body.size() + body.size() / 20); + for (size_t i = 0; i < body.size(); ++i) { + indentedBody += body[i]; + if (body[i] == '\n' && i + 1 < body.size() && body[i + 1] == '\t') { + indentedBody += '\t'; + } + } + out += indentedBody; + } else { + out += body; + } + + return out; +} + +void FunctionGraph::addCodeBuffer(uint32_t baseAddress, const uint8_t* data, size_t size) { + assert_always("FunctionGraph::addCodeBuffer not implemented. Use Recompiler with builders"); + return; + // CodeBuffer buffer; + // buffer.baseAddress = baseAddress; + // buffer.data.assign(data, data + size); + // codeBuffers_.push_back(std::move(buffer)); + // REXCODEGEN_DEBUG("FunctionGraph: added code buffer 0x{:08X}-0x{:08X} ({} bytes)", + // baseAddress, baseAddress + static_cast(size), size); +} + +const uint8_t* FunctionGraph::translateCode(uint32_t addr) const { + assert_always("FunctionGraph::translateCode not implemented. Use Recompiler with builders"); + return nullptr; + // for (const auto& buffer : codeBuffers_) { + // if (buffer.contains(addr)) { + // return buffer.translate(addr); + // } + // } + // return nullptr; +} + +void FunctionGraph::updateFunctionCodePointers() { + // size_t updated = 0; + // for (auto& [base, node] : functions_) { + // const uint8_t* code = translateCode(base); + // if (code) { + // node->setCode(code); + // updated++; + // } else { + // REXCODEGEN_WARN("FunctionGraph: no code buffer for function 0x{:08X}", base); + // } + // } + // REXCODEGEN_DEBUG("FunctionGraph: updated code pointers for {} functions", updated); +} + +//============================================================================= +// FunctionGraph - Function Management +//============================================================================= + +FunctionNode* FunctionGraph::addFunction(uint32_t base, uint32_t size, FunctionAuthority authority, + bool hasXrefs) { + // Check for existing function at this address + auto it = functions_.find(base); + if (it != functions_.end()) { + FunctionNode* existing = it->second.get(); + + // Higher authority wins + if (existing->authority() >= authority) { + REXCODEGEN_TRACE( + "FunctionGraph: ignoring add of 0x{:08X} ({}) - existing has higher authority ({})", base, + AuthorityName(authority), AuthorityName(existing->authority())); + return existing; + } + + // Replace with higher authority + REXCODEGEN_DEBUG("FunctionGraph: replacing 0x{:08X} ({}) with ({})", base, + AuthorityName(existing->authority()), AuthorityName(authority)); + } + + // Create new node + auto node = std::make_unique(base, size, authority); + FunctionNode* nodePtr = node.get(); + functions_[base] = std::move(node); + functionsByBase_[base] = nodePtr; + + // Track xrefs for merge eligibility + functionHasXrefs_[base] = hasXrefs; + + // Notify all PENDING functions + notifyFunctionAdded(nodePtr); + + return nodePtr; +} + +FunctionNode* FunctionGraph::addFunction(uint32_t base, uint32_t size, FunctionAuthority authority, + std::string_view name, bool hasXrefs) { + auto* node = addFunction(base, size, authority, hasXrefs); + if (node && !name.empty()) { + node->setName(std::string(name)); + } + return node; +} + +FunctionNode* FunctionGraph::addImportFunction(uint32_t address, std::string_view resolvedName) { + // Add as function with IMPORT authority + auto* node = addFunction(address, 4, FunctionAuthority::IMPORT, resolvedName, true); + REXCODEGEN_TRACE("FunctionGraph: added import function 0x{:08X} -> {}", address, resolvedName); + return node; +} + +FunctionNode* FunctionGraph::getFunction(uint32_t entryPoint) { + auto it = functions_.find(entryPoint); + return it != functions_.end() ? it->second.get() : nullptr; +} + +const FunctionNode* FunctionGraph::getFunction(uint32_t entryPoint) const { + auto it = functions_.find(entryPoint); + return it != functions_.end() ? it->second.get() : nullptr; +} + +bool FunctionGraph::removeFunction(uint32_t entryPoint) { + auto it = functions_.find(entryPoint); + if (it == functions_.end()) { + return false; + } + REXCODEGEN_TRACE("FunctionGraph: removing absorbed function 0x{:08X}", entryPoint); + functionsByBase_.erase(entryPoint); + functions_.erase(it); + functionHasXrefs_.erase(entryPoint); // Clean up xref tracking + return true; +} + +FunctionNode* FunctionGraph::getFunctionContaining(uint32_t addr) { + // O(log f) lookup via sorted base index: find last function with base <= addr + auto it = functionsByBase_.upper_bound(addr); + if (it != functionsByBase_.begin()) { + --it; + if (it->second->containsAddress(addr)) { + return it->second; + } + } + return nullptr; +} + +const FunctionNode* FunctionGraph::getFunctionContaining(uint32_t addr) const { + auto it = functionsByBase_.upper_bound(addr); + if (it != functionsByBase_.begin()) { + --it; + if (it->second->containsAddress(addr)) { + return it->second; + } + } + return nullptr; +} + +bool FunctionGraph::isEntryPoint(uint32_t addr) const { + return functions_.contains(addr); +} + +bool FunctionGraph::isImport(uint32_t addr) const { + auto it = functions_.find(addr); + return it != functions_.end() && it->second->authority() == FunctionAuthority::IMPORT; +} + +std::vector FunctionGraph::getPendingFunctions() { + std::vector result; + for (auto& [base, node] : functions_) { + if (node->isPending()) { + result.push_back(node.get()); + } + } + return result; +} + +std::vector FunctionGraph::getSealedFunctions() { + std::vector result; + for (auto& [base, node] : functions_) { + if (node->isSealed()) { + result.push_back(node.get()); + } + } + return result; +} + +size_t FunctionGraph::pendingCount() const { + size_t count = 0; + for (const auto& [base, node] : functions_) { + if (node->isPending()) + ++count; + } + return count; +} + +size_t FunctionGraph::sealedCount() const { + size_t count = 0; + for (const auto& [base, node] : functions_) { + if (node->isSealed()) + ++count; + } + return count; +} + +//============================================================================= +// Function Setup (called during Discover phase) +//============================================================================= + +void FunctionGraph::setFunctionName(uint32_t entry, std::string name) { + if (auto* node = getFunction(entry)) { + node->setName(std::move(name)); + } +} + +void FunctionGraph::setFunctionHasExceptionHandler(uint32_t entry, bool val) { + if (auto* node = getFunction(entry)) { + node->setHasExceptionHandler(val); + } +} + +void FunctionGraph::setFunctionExceptionInfo(uint32_t entry, ExceptionInfo info) { + if (auto* node = getFunction(entry)) { + node->setExceptionInfo(std::move(info)); + } +} + +void FunctionGraph::addBlockToFunction(uint32_t entry, Block block) { + if (auto* node = getFunction(entry)) { + node->addBlock(block); + } +} + +void FunctionGraph::addLabelToFunction(uint32_t entry, uint32_t label) { + if (auto* node = getFunction(entry)) { + node->addLabel(label); + } +} + +void FunctionGraph::addCallToFunction(uint32_t entry, uint32_t site, CallTarget target) { + if (auto* node = getFunction(entry)) { + node->addCall(site, std::move(target)); + } +} + +void FunctionGraph::addTailCallToFunction(uint32_t entry, uint32_t site, CallTarget target) { + if (auto* node = getFunction(entry)) { + node->addTailCall(site, std::move(target)); + } +} + +void FunctionGraph::addJumpTableToFunction(uint32_t entry, JumpTable jt) { + if (auto* node = getFunction(entry)) { + node->addJumpTable(std::move(jt)); + } +} + +void FunctionGraph::addUnresolvedJumpToFunction(uint32_t entry, uint32_t site, uint32_t target, + bool isCall, bool conditional) { + auto* node = getFunction(entry); + if (!node) + return; + + // Try immediate resolution against existing functions/imports + if (auto* targetFn = getFunction(target)) { + // Target is a known function - resolve as call or tail call + if (isCall) { + node->addCall(site, CallTarget::function(targetFn)); + } else { + node->addTailCall(site, CallTarget::function(targetFn)); + } + REXCODEGEN_TRACE("FunctionGraph: immediately resolved 0x{:08X}->0x{:08X} as {} to {}", site, + target, isCall ? "call" : "tail call", targetFn->name()); + return; + } + + if (isImport(target)) { + // Target is an import - resolve as call or tail call to import + auto* importNode = getFunction(target); + const std::string& importName = importNode->name(); + if (isCall) { + node->addCall(site, CallTarget::import(target, importName)); + } else { + node->addTailCall(site, CallTarget::import(target, importName)); + } + REXCODEGEN_TRACE("FunctionGraph: immediately resolved 0x{:08X}->0x{:08X} as {} to import {}", + site, target, isCall ? "call" : "tail call", importName); + return; + } + + // Not resolvable yet - add as unresolved + node->addUnresolvedJump(site, target, isCall, conditional); + REXCODEGEN_TRACE("FunctionGraph: added unresolved {} 0x{:08X}->0x{:08X} to function 0x{:08X}", + isCall ? "call" : "jump", site, target, entry); +} + +//============================================================================= +// Resolution and Expansion (called during Merge phase) +//============================================================================= + +size_t FunctionGraph::tryResolveFunction(uint32_t entry) { + auto* node = getFunction(entry); + if (!node || node->isSealed()) + return 0; + + size_t resolved = 0; + + // Get copy of unresolved jumps (list will be modified) + auto jumps = node->unresolvedJumps(); + + REXCODEGEN_TRACE("FunctionGraph::tryResolveFunction 0x{:08X}: {} unresolved jumps", entry, + jumps.size()); + + for (const auto& jump : jumps) { + // Try internal label first + if (node->tryResolveAsInternalLabel(jump.target)) { + REXCODEGEN_TRACE(" 0x{:08X}->0x{:08X}: resolved as internal label", jump.site, jump.target); + node->removeUnresolvedJump(jump.site); + resolved++; + continue; + } + + // Try function entry + if (auto* targetFn = getFunction(jump.target)) { + REXCODEGEN_TRACE(" 0x{:08X}->0x{:08X}: resolved as {} to function {}", jump.site, + jump.target, jump.isCall ? "call" : "tail call", targetFn->name()); + if (jump.isCall) { + node->addCall(jump.site, CallTarget::function(targetFn)); + } else { + node->addTailCall(jump.site, CallTarget::function(targetFn)); + } + node->removeUnresolvedJump(jump.site); + resolved++; + continue; + } + + // Try import + if (isImport(jump.target)) { + auto* importNode = getFunction(jump.target); + const std::string& importName = importNode->name(); + REXCODEGEN_TRACE(" 0x{:08X}->0x{:08X}: resolved as {} to import {}", jump.site, jump.target, + jump.isCall ? "call" : "tail call", importName); + if (jump.isCall) { + node->addCall(jump.site, CallTarget::import(jump.target, importName)); + } else { + node->addTailCall(jump.site, CallTarget::import(jump.target, importName)); + } + node->removeUnresolvedJump(jump.site); + resolved++; + continue; + } + + REXCODEGEN_TRACE(" 0x{:08X}->0x{:08X}: still unresolved", jump.site, jump.target); + } + + return resolved; +} + +void FunctionGraph::absorbRegionIntoFunction(uint32_t entry, uint32_t regionBase, + uint32_t regionSize) { + if (auto* node = getFunction(entry)) { + node->absorbRegion(regionBase, regionSize); + } +} + +bool FunctionGraph::trySealFunction(uint32_t entry) { + auto* node = getFunction(entry); + if (!node || node->isSealed()) + return false; + + if (node->canSeal()) { + node->seal(); + return true; + } + return false; +} + +size_t FunctionGraph::sealAllReady() { + size_t sealed = 0; + size_t couldNotSeal = 0; + for (auto& [base, node] : functions_) { + if (node->isPending()) { + if (node->canSeal()) { + node->seal(); + sealed++; + } else { + couldNotSeal++; + REXCODEGEN_DEBUG("FunctionGraph::sealAllReady: 0x{:08X} ({}) cannot seal ({} unresolved)", + base, node->name(), node->unresolvedJumps().size()); + for (const auto& jump : node->unresolvedJumps()) { + REXCODEGEN_DEBUG(" 0x{:08X} -> 0x{:08X}", jump.site, jump.target); + } + } + } + } + REXCODEGEN_DEBUG("FunctionGraph::sealAllReady: sealed {} functions, {} could not seal", sealed, + couldNotSeal); + return sealed; +} + +void FunctionGraph::sealAll() { + std::vector> errors; + + for (auto& [base, node] : functions_) { + if (node->isSealed()) + continue; + + if (!node->canSeal()) { + std::string reason; + if (node->isRegistered()) { + reason = "still in kRegistered state (blocks not discovered)"; + } else if (node->blocks().empty() && !node->isImport()) { + reason = "has 0 blocks (non-import)"; + } else if (!node->unresolvedJumps().empty()) { + reason = fmt::format("{} unresolved jumps", node->unresolvedJumps().size()); + } else { + reason = "unknown reason"; + } + errors.emplace_back(base, fmt::format("{} (0x{:08X}): {}", node->name(), base, reason)); + continue; + } + + node->seal(); + } + + if (!errors.empty()) { + std::string msg = fmt::format("sealAll: {} functions cannot be sealed:\n", errors.size()); + for (const auto& [addr, err] : errors) { + msg += fmt::format(" - {}\n", err); + } + throw std::runtime_error(msg); + } + + REXCODEGEN_TRACE("FunctionGraph::sealAll: all {} functions sealed", functions_.size()); +} + +//============================================================================= +// Vacancy Checking +//============================================================================= + +void FunctionGraph::registerChunk(uint32_t base, uint32_t size) { + chunks_.emplace_back(base, size); + REXCODEGEN_TRACE("FunctionGraph: registered chunk 0x{:08X}-0x{:08X}", base, base + size); +} + +bool FunctionGraph::isVacant(uint32_t fromAddr, uint32_t targetAddr) const { + // Rule 1: Check for null dword at boundary + if (memoryReader_) { + if (targetAddr > fromAddr) { + // Check for null at target (typical inter-function padding) + auto val = memoryReader_(targetAddr); + if (val && *val == 0x00000000) { + REXCODEGEN_TRACE("FunctionGraph::isVacant: null dword at 0x{:08X} blocks vacancy", + targetAddr); + return false; + } + } + } + + // Rule 2: Check if any chunk claims the target region + for (const auto& [chunkBase, chunkSize] : chunks_) { + if (targetAddr >= chunkBase && targetAddr < chunkBase + chunkSize) { + REXCODEGEN_TRACE("FunctionGraph::isVacant: chunk 0x{:08X}-0x{:08X} claims 0x{:08X}", + chunkBase, chunkBase + chunkSize, targetAddr); + return false; + } + } + + // Rule 3: Check if target falls within any function's range + for (const auto& [base, node] : functions_) { + if (node->containsAddress(targetAddr)) { + // Target is within a function - check if it's mergeable + if (isMergeableEntryPoint(targetAddr)) { + // GAP_FILL can be absorbed + REXCODEGEN_TRACE("FunctionGraph::isVacant: 0x{:08X} is mergeable (GAP_FILL)", targetAddr); + continue; // Don't block, it's mergeable + } + // Protected function - blocks vacancy + REXCODEGEN_TRACE("FunctionGraph::isVacant: 0x{:08X} is within protected function 0x{:08X}", + targetAddr, base); + return false; + } + } + + // green light for vacancy + return true; +} + +bool FunctionGraph::isMergeableEntryPoint(uint32_t addr) const { + // Only entry points can be mergeable + auto it = functions_.find(addr); + if (it == functions_.end()) { + return false; // Not an entry point + } + + const FunctionNode* node = it->second.get(); + + // Only GAP_FILL authority can be absorbed + // All other authorities represent immutable entry points + return node->authority() == FunctionAuthority::GAP_FILL; +} + +TargetKind FunctionGraph::classifyTarget(uint32_t target, uint32_t callerAddr, + bool isCallInstruction) const { + // Find the caller's function + const FunctionNode* callerFn = getFunctionContaining(callerAddr); + + // Case 1: Target is an import - always a call/tail-call + if (isImport(target)) { + return TargetKind::Import; + } + + // Case 2: Target is the caller's own entry point + if (callerFn && target == callerFn->base()) { + // bl to own base = recursive call (Function) + // b to own base = loop back to start (InternalLabel) + return isCallInstruction ? TargetKind::Function : TargetKind::InternalLabel; + } + + // Case 3: Target is a DIFFERENT function's entry point - this is a call/tail-call + // This handles cases where a small thunk function branches to another function + // whose entry point happens to fall within the thunk's address range + if (isEntryPoint(target)) { + return TargetKind::Function; + } + + // Case 4: Target is inside caller's function -> InternalLabel + // For bl, this would be a rare PIC code pattern + if (callerFn && callerFn->containsAddress(target)) { + return TargetKind::InternalLabel; + } + + // Case 5: Unknown target + return TargetKind::Unknown; +} + +void FunctionGraph::notifyFunctionAdded(FunctionNode* newFunction) { + for (auto& [base, node] : functions_) { + if (node.get() != newFunction && node->isPending()) { + node->tryResolveAgainst(newFunction); + } + } +} + +} // namespace rex::codegen diff --git a/src/codegen/function_scanner.cpp b/src/codegen/function_scanner.cpp new file mode 100644 index 0000000..05fb6bf --- /dev/null +++ b/src/codegen/function_scanner.cpp @@ -0,0 +1,2012 @@ +/** + * @file codegen/function_scanner.cpp + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "codegen_flags.h" +#include "decoded_binary.h" +#include "ppc/instruction.h" +#include "ppc/opcode.h" + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "codegen_logging.h" +#include +#include + +namespace rex::codegen { + +// Import PPC types +using rex::codegen::ppc::decode_instruction; +using rex::codegen::ppc::Instruction; +using rex::codegen::ppc::Opcode; +using rex::memory::load_and_swap; + +//============================================================================= +// Constructors +//============================================================================= + +FunctionScanner::FunctionScanner(const BinaryView& binary) : binary_(&binary) {} + +//============================================================================= +// Address Translation +//============================================================================= + +template +const T* FunctionScanner::translate_address(rex::guest_addr_t guest_addr) const { + return reinterpret_cast(binary_->translate(static_cast(guest_addr))); +} + +bool FunctionScanner::isExecutableSection(rex::guest_addr_t address) const { + return binary_->isExecutable(static_cast(address)); +} + +//============================================================================= +// Helper: Detect function prologue pattern +//============================================================================= + +bool FunctionScanner::is_prologue_pattern(guest_addr_t address) { + auto host_ptr = translate_address(address); + if (!host_ptr) + return false; + + u32 code = load_and_swap(host_ptr); + Instruction instr = decode_instruction(address, code); + + // Check for mflr + if (instr.opcode == Opcode::mflr) { + return true; + } + + // Check for mfspr lr (SPR 8) + if (instr.opcode == Opcode::mfspr && instr.XFX.spr_num() == 8) { + return true; + } + + // Check for stack frame allocation: stwu r1, -X(r1) + if (instr.opcode == Opcode::stwu && instr.D.RS() == 1 && instr.D.RA == 1 && instr.D.SIMM() < 0) { + return true; + } + + return false; +} + +//============================================================================= +// Helper: Detect function epilogue pattern +//============================================================================= + +bool FunctionScanner::is_epilogue_pattern(guest_addr_t address) { + auto host_ptr = translate_address(address); + if (!host_ptr) + return false; + + u32 code = load_and_swap(host_ptr); + + Instruction instr = decode_instruction(address, code); + + // Check for blr + if (instr.is_return()) { + return true; + } + + // Check for mtlr + if (instr.opcode == Opcode::mtlr) { + return true; + } + + // Check for stack restore: lwz r1, 0(r1) + if (instr.opcode == Opcode::lwz && instr.D.RT == 1 && instr.D.RA == 1 && instr.D.SIMM() == 0) { + return true; + } + + return false; +} + +//============================================================================= +// Helper: Detect save/restore helper functions via byte pattern matching +//============================================================================= +bool FunctionScanner::is_restgprlr_function(guest_addr_t address) { + auto host_ptr = translate_address(address); + if (!host_ptr) + return false; + + u32 first = load_and_swap(host_ptr); + + // Check single-instruction patterns (4 bytes each) + constexpr u32 RESTGPRLR_14 = 0xe9c1ff68; // ld r14, -0x98(r1) + constexpr u32 SAVEGPRLR_14 = 0xf9c1ff68; // std r14, -0x98(r1) + constexpr u32 RESTFPR_14 = 0xc9ccff70; // lfd f14, -0x90(r12) + constexpr u32 SAVEFPR_14 = 0xd9ccff70; // stfd f14, -0x90(r12) + + if (first == RESTGPRLR_14 || first == SAVEGPRLR_14 || first == RESTFPR_14 || + first == SAVEFPR_14) { + return true; + } + + // Check two-instruction patterns (8 bytes each) + // Pattern: li r11, -0x120 (0x3960fee0) + lvx/stvx + if (first == 0x3960fee0) { // li r11, -0x120 + auto second_ptr = translate_address(address + 4); + if (second_ptr) { + u32 second = load_and_swap(second_ptr); + constexpr u32 RESTVMX_14 = 0x7dcb60ce; // lvx v14, r11, r12 + constexpr u32 SAVEVMX_14 = 0x7dcb61ce; // stvx v14, r11, r12 + if (second == RESTVMX_14 || second == SAVEVMX_14) { + return true; + } + } + } + + // Pattern: li r11, -0x400 (0x3960fc00) + lvx128/stvx128 + if (first == 0x3960fc00) { // li r11, -0x400 + auto second_ptr = translate_address(address + 4); + if (second_ptr) { + u32 second = load_and_swap(second_ptr); + constexpr u32 RESTVMX_64 = 0x100b60cb; // lvx128 v64, r11, r12 + constexpr u32 SAVEVMX_64 = 0x100b61cb; // stvx128 v64, r11, r12 + if (second == RESTVMX_64 || second == SAVEVMX_64) { + return true; + } + } + } + + return false; +} + +//============================================================================= +// Jump Table Pattern Detection +//============================================================================= +// Xbox 360 compilers emit 4 distinct jump table patterns (maybe more?): +// +// 1. ABSOLUTE: lwzx loads full 32-bit target addresses +// lis rT, table@ha; addi rT, rT, table@l; rlwinm rI, rIdx, 2; lwzx rT, rI, rT; mtctr; bctr +// +// 2. COMPUTED: lbzx loads byte offset, shifted and added to base +// lis rT, table@ha; addi rT, rT, table@l; lbzx rO, rIdx, rT; rlwinm rO, rO, shift; +// lis rB, base@ha; addi rB, rB, base@l; add rT, rB, rO; mtctr; bctr +// +// 3. BYTEOFFSET: lbzx loads byte offset, added directly to base +// lis rT, table@ha; addi rT, rT, table@l; lbzx rO, rIdx, rT; +// lis rB, base@ha; addi rB, rB, base@l; add rT, rB, rO; mtctr; bctr +// +// 4. SHORTOFFSET: lhzx loads 16-bit offset, added to base +// lis rT, table@ha; addi rT, rT, table@l; rlwinm rI, rIdx, 1; lhzx rO, rI, rT; +// lis rB, base@ha; addi rB, rB, base@l; add rT, rB, rO; mtctr; bctr +//============================================================================= + +namespace { + +// Jump table type - internal use only during detection +// Determines how target addresses are stored/computed in the binary +enum class JumpTableType : u8 { + kAbsolute, // lwzx - table contains full 32-bit target addresses + kComputed, // lbzx + rlwinm + add - byte offset shifted and added to base + kByteOffset, // lbzx + add - byte offset added directly to base + kShortOffset, // lhzx + add - 16-bit offset added to base +}; + +// Helper struct for tracking pattern match state +struct JumpTableMatch { + JumpTableType type = JumpTableType::kAbsolute; + u8 ctr_source_reg = 0; // Register moved to CTR + u8 table_reg = 0; // Register holding table address + u8 base_reg = 0; // Register holding base address (offset types) + u8 index_reg = 0; // Register holding original switch index + u8 offset_reg = 0; // Register holding loaded offset + u8 shift_amount = 0; // Shift amount for COMPUTED type + guest_addr_t table_high = 0; + guest_addr_t table_low = 0; + guest_addr_t base_high = 0; + guest_addr_t base_low = 0; + + // Pattern matching state + bool found_mtctr = false; + bool found_add = false; // For offset-based types + bool found_load = false; // lwzx/lbzx/lhzx + bool found_shift = false; // rlwinm for shift + bool found_table_lis = false; + bool found_table_addi = false; + bool found_base_lis = false; + bool found_base_addi = false; + + // For @ha/@l pairs, addi uses signed immediate, so we need addition with sign extension + guest_addr_t table_address() const { return table_high + static_cast(table_low); } + guest_addr_t base_address() const { return base_high + static_cast(base_low); } +}; + +// Scan backward for CMPLWI bounds check and conditional branch +struct BoundsInfo { + uint32_t maxEntries = 0; + uint8_t indexReg = 0; + uint32_t defaultTarget = 0; + bool found = false; +}; + +//============================================================================= +// Helper: Scan for bounds check (CMPLWI + BGT/BLE) +//============================================================================= + +BoundsInfo scanForBounds(const FunctionScanner& scanner, guest_addr_t bctr_address, + u8 expected_index_reg) { + BoundsInfo bounds; + constexpr int MAX_SCAN = 64; + + u8 cr_field = 0xFF; // CR field from conditional branch + + for (int i = 1; i <= MAX_SCAN; ++i) { + guest_addr_t addr = bctr_address - (i * 4); + if (addr < 4) + break; + + auto host_ptr = scanner.translate_address(addr); + if (!host_ptr) + break; + + u32 code = load_and_swap(host_ptr); + if (code == 0) + break; + + Instruction instr = decode_instruction(addr, code); + + // Look for conditional branch (bc, bca, bcl, bcla, bclr, bclrl) + // bgt/ble/bgtlr/blelr are simplified mnemonics for bc with specific BO/BI + if (cr_field == 0xFF) { + bool is_cond_branch = (instr.opcode == Opcode::bc || instr.opcode == Opcode::bca || + instr.opcode == Opcode::bcl || instr.opcode == Opcode::bcla || + instr.opcode == Opcode::bclr || instr.opcode == Opcode::bclrl); + + if (is_cond_branch) { + // Check if this could be a bounds check branch (bgt or ble pattern) + // BO[4] (bit 0) = 0 means test CR bit + // BI[0:1] = condition bit within CR field (GT=1, LT=0, EQ=2, SO=3) + u8 bi = instr.B.BI; + + // Check for branches that test the GT bit (BI mod 4 == 1) + // bgt: BO=12 (01100), tests CR[GT]=true + // ble: BO=4 (00100), tests CR[GT]=false (i.e., not greater = less or equal) + if ((bi & 0x3) == 1) { // Tests GT bit + // Extract CR field (bits 2-4 of BI) + cr_field = (bi >> 2) & 0x7; + + // Extract default target if branch has target + if (instr.branch_target.has_value()) { + bounds.defaultTarget = instr.branch_target.value(); + } + } + } + } + + // Look for rlwinm that sets the index register with a mask + // clrlwi rD, rS, n = rlwinm rD, rS, 0, n, 31 + // This bounds the value to 2^(32-n) - 1 entries + if (instr.opcode == Opcode::rlwinm && instr.M.RA == expected_index_reg) { + u8 sh = instr.M.SH; + u8 mb = instr.M.MB; + u8 me = instr.M.ME; + + // clrlwi pattern: SH=0, ME=31, MB > 0 + // The mask clears leftmost MB bits, so max value = 2^(32-MB) - 1 + // Entry count = max value + 1 = 2^(32-MB) + if (sh == 0 && me == 31 && mb > 0 && mb < 32) { + u32 implicit_count = 1u << (32 - mb); + REXCODEGEN_TRACE( + " [0x{:08X}] Found clrlwi/rlwinm r{}, ..., {} -> {} entries (implicit mask)", addr, + static_cast(expected_index_reg), mb, implicit_count); + + // Only accept if count is reasonable (2-256 entries) + if (implicit_count >= 2 && implicit_count <= 256) { + bounds.maxEntries = implicit_count; + bounds.indexReg = expected_index_reg; + bounds.found = true; + break; // Implicit bounds are definitive + } + } + } + + // Look for cmpli or cmpi (cmplwi/cmpwi - unsigned/signed bounds check) + if (instr.opcode == Opcode::cmpli || instr.opcode == Opcode::cmpi) { + // cmpli format: cmpli BF, L, RA, UIMM + // BF (bits 23-25): CR field + // L (bit 21): 0=32-bit, 1=64-bit + // RA (bits 16-20): Register to compare + // UIMM (bits 0-15): Immediate value + + // BF is top 3 bits of RT field for compare instructions + u8 cmp_cr = instr.D.RT >> 2; + u8 cmp_ra = instr.D.RA; // Register being compared + u16 cmp_imm = instr.D.UIMM(); // Immediate value (max index) + + // Prefer register match, accept CR-only match as fallback + bool cr_matches = (cr_field != 0xFF && cmp_cr == cr_field); + bool reg_matches = (cmp_ra == expected_index_reg); + + // CRITICAL: Reject very small immediates (0 or 1) even if register matches + // These are likely unrelated comparisons (checking for zero/null, boolean tests) + // A real switch table bounds check would have immediate >= 2 (at least 3 cases) + if (cmp_imm <= 1) { + REXCODEGEN_TRACE( + " [0x{:08X}] Skipping cmpli r{}, {} (immediate too small for switch bounds)", addr, + static_cast(cmp_ra), cmp_imm); + continue; + } + + // Only accept if register matches, or if CR matches AND immediate is reasonable + if (reg_matches || (cr_matches && cmp_imm > 1)) { + bounds.maxEntries = cmp_imm + 1; // cmpli compares against max, so count = max + 1 + bounds.indexReg = cmp_ra; + bounds.found = true; + + // If register matches, we found the best match - done + if (reg_matches) + break; + // If only CR matches, continue scanning for a better (register) match + } + } + } + + return bounds; +} + +//============================================================================= +// Helper: Read table entries based on type +//============================================================================= +std::vector read_table_entries(const FunctionScanner& scanner, + const JumpTableMatch& match, u32 entry_count) { + std::vector targets; + guest_addr_t table_addr = match.table_address(); + + // entry_count comes from bounds check analysis - use it exactly if available + // If no bounds check was found (entry_count == 0), read until we hit invalid entries + // Loop terminates via goto done when invalid memory is hit + for (u32 i = 0; entry_count == 0 || i < entry_count; ++i) { + guest_addr_t target = 0; + + switch (match.type) { + case JumpTableType::kAbsolute: { + // Read 32-bit address directly (big-endian) + auto entry_ptr = scanner.translate_address(table_addr + (i * 4)); + if (!entry_ptr) + goto done; + target = load_and_swap(entry_ptr); + break; + } + + case JumpTableType::kComputed: { + // Read byte, shift, add to base + auto entry_ptr = scanner.translate_address(table_addr + i); + if (!entry_ptr) + goto done; + u8 offset = *entry_ptr; + target = match.base_address() + (static_cast(offset) << match.shift_amount); + break; + } + + case JumpTableType::kByteOffset: { + // Read byte, add directly to base + auto entry_ptr = scanner.translate_address(table_addr + i); + if (!entry_ptr) + goto done; + u8 offset = *entry_ptr; + target = match.base_address() + offset; + break; + } + + case JumpTableType::kShortOffset: { + // Read 16-bit value (big-endian), add to base + auto entry_ptr = scanner.translate_address(table_addr + (i * 2)); + if (!entry_ptr) + goto done; + u16 offset = load_and_swap(entry_ptr); + target = match.base_address() + offset; + break; + } + } + + // PPC instructions must be 4-byte aligned + if (target & 3) + goto done; + + // Validate target (stop on null or invalid for absolute type) + if (target == 0 && match.type == JumpTableType::kAbsolute) + goto done; + + // Validate target is in EXECUTABLE section (not just mapped memory) + // This prevents false positives from data tables containing addresses + if (!scanner.isExecutableSection(target)) { + // For absolute tables, non-executable target means wrong table address + if (match.type == JumpTableType::kAbsolute) + goto done; + continue; // Skip non-executable entries in offset tables (might be default/error cases) + } + + targets.push_back(target); + } + +done: + return targets; +} + +} // anonymous namespace + +//============================================================================= +// Helper: Check if instruction indicates a function boundary +//============================================================================= +// Returns true if the instruction at 'code' indicates we've crossed into +// a different function (either previous function's terminator or current +// function's prologue). +static bool is_function_boundary(u32 code, const Instruction& instr, guest_addr_t addr) { + // Zero padding between functions + if (code == 0x00000000) { + REXCODEGEN_TRACE(" [0x{:08X}] Hit zero padding - function boundary", addr); + return true; + } + + // blr - previous function's return + if (instr.is_return()) { + REXCODEGEN_TRACE(" [0x{:08X}] Hit blr - function boundary", addr); + return true; + } + + // bctr/bctrl - indirect branch/call via CTR + if (instr.opcode == Opcode::bcctr || instr.opcode == Opcode::bcctrl) { + REXCODEGEN_TRACE(" [0x{:08X}] Hit bctr/bctrl - function boundary", addr); + return true; + } + + // Unconditional branch 'b' (tail call to named function) + if (instr.opcode == Opcode::b || instr.opcode == Opcode::ba) { + REXCODEGEN_TRACE(" [0x{:08X}] Hit unconditional branch (b) - function boundary", addr); + return true; + } + + // mflr - function prologue (saving link register) + if (instr.opcode == Opcode::mflr) { + REXCODEGEN_TRACE(" [0x{:08X}] Hit mflr - function prologue", addr); + return true; + } + + // stw rX, offset(r1) where offset is negative - stack frame setup + // This catches "stwu r1, -N(r1)" which is a common prologue + if (instr.opcode == Opcode::stwu && instr.D.RA == 1 && instr.D.RT == 1) { + // stwu r1, -N(r1) is stack frame allocation + REXCODEGEN_TRACE(" [0x{:08X}] Hit stwu r1 (stack frame) - function prologue", addr); + return true; + } + + // nop (ori r0,r0,0 = 0x60000000) - often used as padding + // But nops can appear mid-function too, so only treat consecutive nops as boundary + // For now, don't treat single nop as boundary + + return false; +} + +//============================================================================= +// Helper: Detect jump table pattern at bctr instruction +//============================================================================= +std::optional FunctionScanner::detect_jump_table(guest_addr_t bctr_address) { + // Skip detection if this address has a manually-specified switch table + if (known_switch_tables_.count(static_cast(bctr_address))) { + REXCODEGEN_TRACE("detect_jump_table: skipping 0x{:08X} (manual table exists)", bctr_address); + return std::nullopt; // Will be handled by the pre-loaded config + } + + const int MAX_SCAN_BACK = static_cast(REXCVAR_GET(backward_scan_limit)); + + JumpTableMatch match; + + REXCODEGEN_TRACE("detect_jump_table: scanning backward from bctr at 0x{:08X}", bctr_address); + + // Backward scan to match pattern + for (int i = 1; i <= MAX_SCAN_BACK; ++i) { + guest_addr_t addr = bctr_address - (i * 4); + if (addr < 4) + break; + + auto host_ptr = translate_address(addr); + if (!host_ptr) + break; + + // Read as big-endian (PPC is big-endian) + u32 code = load_and_swap(host_ptr); + + Instruction instr = decode_instruction(addr, code); + + // Stop at function boundaries - but allow continuing past bctr if we're still + // looking for lis (handles adjacent switch tables sharing setup code) + if (is_function_boundary(code, instr, addr)) { + // If we found load but not lis, and this is bctr, continue scanning + // (adjacent switch tables may share the same lis setup) + if (instr.opcode == Opcode::bcctr && match.found_load && !match.found_table_lis) { + REXCODEGEN_TRACE(" [0x{:08X}] Continuing past bctr to find shared lis", addr); + continue; + } + break; + } + + // Step 1: Find mtctr rX + if (!match.found_mtctr && instr.opcode == Opcode::mtctr) { + match.ctr_source_reg = instr.XFX.RS(); + match.found_mtctr = true; + REXCODEGEN_TRACE(" [0x{:08X}] Found mtctr r{}", addr, + static_cast(match.ctr_source_reg)); + continue; + } + + if (!match.found_mtctr) + continue; + + // Step 2a: Find add rT, rBase, rOffset (for offset-based types) + if (!match.found_add && !match.found_load && instr.opcode == Opcode::add) { + if (instr.XO.RT == match.ctr_source_reg) { + // Store both RA and RB - we'll determine which is base/offset later + match.base_reg = instr.XO.RA; + match.offset_reg = instr.XO.RB; + match.found_add = true; + REXCODEGEN_TRACE(" [0x{:08X}] Found add r{}, r{}, r{}", addr, + static_cast(instr.XO.RT), static_cast(match.base_reg), + static_cast(match.offset_reg)); + continue; + } + } + + // Step 2b: Find lwzx (ABSOLUTE type) - only if no add found + // lwzx RT, RA, RB: RT = mem[RA + RB] + // Note: RA and RB can be in either order (table/index or index/table) + if (!match.found_add && !match.found_load && instr.opcode == Opcode::lwzx) { + if (instr.X.RT == match.ctr_source_reg) { + match.type = JumpTableType::kAbsolute; + // Initially assume RA=table, RB=index (will verify/swap later) + match.table_reg = instr.X.RA; + match.index_reg = instr.X.RB; + match.found_load = true; + REXCODEGEN_TRACE(" [0x{:08X}] Found lwzx r{}, r{}, r{} (tentative table=r{}, index=r{})", + addr, static_cast(instr.X.RT), static_cast(instr.X.RA), + static_cast(instr.X.RB), static_cast(match.table_reg), + static_cast(match.index_reg)); + continue; + } + } + + // For offset-based types: find the load instruction + if (match.found_add && !match.found_load) { + // lbzx for COMPUTED or BYTEOFFSET + // lbzx RT, RA, RB: RT = *(RA + RB) + if (instr.opcode == Opcode::lbzx && instr.X.RT == match.offset_reg) { + // Initially assume RA=table, RB=index + match.table_reg = instr.X.RA; + match.index_reg = instr.X.RB; + match.found_load = true; + // Only set type if we haven't already found a shift (which means kComputed) + if (!match.found_shift) { + match.type = JumpTableType::kByteOffset; // Default when no shift + } + REXCODEGEN_TRACE(" [0x{:08X}] Found lbzx r{}, r{}, r{}", addr, + static_cast(instr.X.RT), static_cast(instr.X.RA), + static_cast(instr.X.RB)); + continue; + } + + // lhzx for SHORTOFFSET + if (instr.opcode == Opcode::lhzx && instr.X.RT == match.offset_reg) { + match.type = JumpTableType::kShortOffset; + match.table_reg = instr.X.RA; + match.index_reg = instr.X.RB; + match.found_load = true; + REXCODEGEN_TRACE(" [0x{:08X}] Found lhzx r{}, r{}, r{}", addr, + static_cast(instr.X.RT), static_cast(instr.X.RA), + static_cast(instr.X.RB)); + continue; + } + } + + // Step 3: Find rlwinm for shift (COMPUTED type or index scaling) + if (!match.found_shift && instr.opcode == Opcode::rlwinm) { + // Check if this is scaling the index (for ABSOLUTE, SHORT, or offset-based types) + // Must check BEFORE offset shift to handle SHORTOFFSET with scaled index + if (match.found_load && instr.M.RA == match.index_reg) { + match.index_reg = instr.M.RS; + match.found_shift = true; + REXCODEGEN_TRACE(" [0x{:08X}] Found rlwinm (index scale) r{}, r{}, {}", addr, + static_cast(instr.M.RA), static_cast(instr.M.RS), + static_cast(instr.M.SH)); + continue; + } + // Check if this is shifting the offset (COMPUTED type) + // Only set COMPUTED type if we haven't already identified as SHORTOFFSET + // (SHORTOFFSET uses rlwinm for index scaling, not offset shifting) + if (match.found_add && instr.M.RA == match.offset_reg && + match.type != JumpTableType::kShortOffset) { + match.shift_amount = instr.M.SH; + match.type = JumpTableType::kComputed; + match.found_shift = true; + match.offset_reg = instr.M.RS; + REXCODEGEN_TRACE(" [0x{:08X}] Found rlwinm (shift) r{}, r{}, {} -> COMPUTED type", addr, + static_cast(instr.M.RA), static_cast(instr.M.RS), + static_cast(instr.M.SH)); + continue; + } + } + + // Step 4: Find lis/addi pairs for table address (and base for register reuse case) + // Also check if we need to swap table_reg/index_reg (RA/RB ambiguity) + if (match.found_load) { + // Check for register reuse: same register used for both table and base (offset-based types) + // In this case, backward scan finds BASE first (closer to bctr), then TABLE + bool register_reuse = match.found_add && (match.table_reg == match.base_reg); + + // Check for lis matching table_reg + if (instr.opcode == Opcode::lis && instr.D.RT == match.table_reg) { + if (register_reuse) { + // Register reuse: first lis = BASE, second lis = TABLE + if (!match.found_base_lis) { + match.base_high = static_cast(instr.D.UIMM()) << 16; + match.found_base_lis = true; + REXCODEGEN_TRACE(" [0x{:08X}] Found base lis r{}, 0x{:04X} (register reuse)", addr, + static_cast(instr.D.RT), instr.D.UIMM()); + continue; + } else if (!match.found_table_lis) { + match.table_high = static_cast(instr.D.UIMM()) << 16; + match.found_table_lis = true; + REXCODEGEN_TRACE(" [0x{:08X}] Found table lis r{}, 0x{:04X} (register reuse)", addr, + static_cast(instr.D.RT), instr.D.UIMM()); + continue; + } + } else if (!match.found_table_lis) { + match.table_high = static_cast(instr.D.UIMM()) << 16; + match.found_table_lis = true; + REXCODEGEN_TRACE(" [0x{:08X}] Found lis r{}, 0x{:04X}", addr, + static_cast(instr.D.RT), instr.D.UIMM()); + continue; + } + } + // Check if lis matches index_reg - means we guessed wrong, need to swap + else if (!match.found_table_lis && instr.opcode == Opcode::lis && + instr.D.RT == match.index_reg) { + REXCODEGEN_TRACE(" [0x{:08X}] Found lis for index_reg r{}, swapping table/index", addr, + static_cast(instr.D.RT)); + std::swap(match.table_reg, match.index_reg); + match.table_high = static_cast(instr.D.UIMM()) << 16; + match.found_table_lis = true; + continue; + } + + // Check for addi/ori matching table_reg + if ((instr.opcode == Opcode::addi || instr.opcode == Opcode::ori) && + instr.D.RT == match.table_reg) { + if (register_reuse) { + // Register reuse: first addi = BASE, second addi = TABLE + if (!match.found_base_addi) { + match.base_low = instr.D.UIMM(); + match.found_base_addi = true; + REXCODEGEN_TRACE(" [0x{:08X}] Found base addi r{}, 0x{:04X} (register reuse)", addr, + static_cast(instr.D.RT), instr.D.UIMM()); + continue; + } else if (!match.found_table_addi) { + match.table_low = instr.D.UIMM(); + match.found_table_addi = true; + REXCODEGEN_TRACE(" [0x{:08X}] Found table addi r{}, 0x{:04X} (register reuse)", addr, + static_cast(instr.D.RT), instr.D.UIMM()); + continue; + } + } else if (!match.found_table_addi) { + match.table_low = instr.D.UIMM(); + match.found_table_addi = true; + REXCODEGEN_TRACE(" [0x{:08X}] Found addi r{}, r{}, 0x{:04X}", addr, + static_cast(instr.D.RT), static_cast(instr.D.RA), + instr.D.UIMM()); + continue; + } + } + // Check if addi matches index_reg - means we guessed wrong, need to swap + else if (!match.found_table_addi && + (instr.opcode == Opcode::addi || instr.opcode == Opcode::ori) && + instr.D.RT == match.index_reg) { + REXCODEGEN_TRACE(" [0x{:08X}] Found addi for index_reg r{}, swapping table/index", addr, + static_cast(instr.D.RT)); + std::swap(match.table_reg, match.index_reg); + match.table_low = instr.D.UIMM(); + match.found_table_addi = true; + continue; + } + } + + // Step 5: Find lis/addi pairs for base address (offset-based types) + // Also handle RA/RB ambiguity for add instruction + if (match.found_add) { + if (!match.found_base_lis && instr.opcode == Opcode::lis) { + if (instr.D.RT == match.base_reg) { + match.base_high = static_cast(instr.D.UIMM()) << 16; + match.found_base_lis = true; + REXCODEGEN_TRACE(" [0x{:08X}] Found base lis r{}, 0x{:04X}", addr, + static_cast(instr.D.RT), instr.D.UIMM()); + continue; + } + // Check if lis matches offset_reg - means we guessed wrong + else if (instr.D.RT == match.offset_reg && !match.found_base_lis) { + REXCODEGEN_TRACE(" [0x{:08X}] Found lis for offset_reg r{}, swapping base/offset", addr, + static_cast(instr.D.RT)); + std::swap(match.base_reg, match.offset_reg); + match.base_high = static_cast(instr.D.UIMM()) << 16; + match.found_base_lis = true; + continue; + } + } + if (!match.found_base_addi && (instr.opcode == Opcode::addi || instr.opcode == Opcode::ori)) { + if (instr.D.RT == match.base_reg) { + match.base_low = instr.D.UIMM(); + match.found_base_addi = true; + REXCODEGEN_TRACE(" [0x{:08X}] Found base addi r{}, 0x{:04X}", addr, + static_cast(instr.D.RT), instr.D.UIMM()); + continue; + } + // Check if addi matches offset_reg - means we guessed wrong + else if (instr.D.RT == match.offset_reg && !match.found_base_addi) { + REXCODEGEN_TRACE(" [0x{:08X}] Found addi for offset_reg r{}, swapping base/offset", addr, + static_cast(instr.D.RT)); + std::swap(match.base_reg, match.offset_reg); + match.base_low = instr.D.UIMM(); + match.found_base_addi = true; + continue; + } + } + } + + // Check if we have a complete pattern + bool table_complete = match.found_table_lis && match.found_table_addi; + bool base_complete = !match.found_add || (match.found_base_lis && match.found_base_addi); + + if (match.found_mtctr && match.found_load && table_complete && base_complete) { + REXCODEGEN_TRACE(" Pattern complete at 0x{:08X}", addr); + break; // Pattern complete + } + } + + // Verify minimum required pattern elements + if (!match.found_mtctr || !match.found_load || !match.found_table_lis || + !match.found_table_addi) { + REXCODEGEN_TRACE(" Pattern incomplete: mtctr={}, load={}, table_lis={}, table_addi={}", + match.found_mtctr, match.found_load, match.found_table_lis, + match.found_table_addi); + // Only report error if we found indexed load AND lis/addi for the table address. + // If we found load but NO lis, it's a vtable/indirect call (runtime pointer), not a switch + // table. + if (match.found_load && (match.found_table_lis || match.found_base_lis)) { + REXCODEGEN_ERROR( + "Jump table detection failed at bctr 0x{:08X}: mtctr={}, load={}, table_lis={}, " + "table_addi={}, table_reg=r{}, base_lis={}, base_addi={}", + bctr_address, match.found_mtctr, match.found_load, match.found_table_lis, + match.found_table_addi, match.table_reg, match.found_base_lis, match.found_base_addi); + } else if (match.found_load) { + // Load but no lis = vtable/indirect call with runtime pointer, not a switch table + REXCODEGEN_TRACE("bctr 0x{:08X}: indexed load without lis - treating as vtable/indirect call", + bctr_address); + } + return std::nullopt; + } + + // For offset-based types, require base address + if (match.found_add && (!match.found_base_lis || !match.found_base_addi)) { + REXCODEGEN_TRACE(" Offset-based pattern incomplete: base_lis={}, base_addi={}", + match.found_base_lis, match.found_base_addi); + return std::nullopt; + } + + // Validate table address + guest_addr_t table_address = match.table_address(); + REXCODEGEN_TRACE(" Table address: 0x{:08X} (high=0x{:08X}, low=0x{:04X})", table_address, + match.table_high, match.table_low); + + auto table_ptr = translate_address(table_address); + if (!table_ptr) { + REXCODEGEN_TRACE(" Invalid table address 0x{:08X} - not in mapped memory", table_address); + return std::nullopt; + } + + // Scan for bounds check (CMPLWI) + BoundsInfo bounds = scanForBounds(*this, bctr_address, match.index_reg); + REXCODEGEN_TRACE(" Bounds check: found={}, count={}, default=0x{:08X}, index_reg=r{}", + bounds.found, bounds.maxEntries, bounds.defaultTarget, bounds.indexReg); + + // Read table entries + std::vector targets = read_table_entries(*this, match, bounds.maxEntries); + + // Require at least 2 entries + if (targets.size() < 2) { + REXCODEGEN_TRACE(" Insufficient entries: {} (need at least 2)", targets.size()); + return std::nullopt; + } + + // Build result + JumpTable jt; + jt.bctrAddress = static_cast(bctr_address); + jt.tableAddress = static_cast(table_address); + jt.indexRegister = match.index_reg; + jt.targets = std::move(targets); + + return jt; +} + +//============================================================================= +// Block-Based Discovery +//============================================================================= +FunctionBlocks FunctionScanner::discover_blocks(rex::guest_addr_t entry_point, + rex::u32 pdata_size) { + FunctionBlocks result; + result.entry = entry_point; + result.pdata_size = pdata_size; + + // Track all instruction addresses scanned (prevents overlap between blocks) + std::unordered_set scannedAddrs; + + // DFS block stack - tracks blocks being processed + // this allows projection carry-forward on continuous blocks + std::vector block_stack; + + // Start with entry block + DiscoveredBlock entry_block; + entry_block.base = entry_point; + entry_block.end = entry_point; + entry_block.projectedSize = -1; // No limit + block_stack.push_back(entry_block); + + const size_t MAX_BLOCKS = REXCVAR_GET(max_blocks_per_function); // Safety limit + + while (!block_stack.empty() && result.blocks.size() < MAX_BLOCKS) { + // Get current block from stack (by reference for in-place modification) + DiscoveredBlock& block = block_stack.back(); + + // Only check for duplicates if this is a FRESH block (not partially scanned) + // When block.end > block.base, we're continuing to process an existing block + if (block.end == block.base) { + // Fresh block - check if already scanned by another block + if (scannedAddrs.count(block.base)) { + block_stack.pop_back(); + continue; + } + } + + // Validate alignment + if ((block.base & 0x3) != 0) { + REXCODEGEN_WARN("discover_blocks: misaligned block start 0x{:08X}", block.base); + block_stack.pop_back(); + continue; + } + + // Calculate current position in block + guest_addr_t addr = block.end; // end tracks where we are (exclusive becomes next addr) + if (addr == block.base) { + // Fresh block - start scanning from base + } + + // Check projection limit BEFORE processing instruction + // if block.size >= projectedSize, block is done + guest_addr_t block_size = addr - block.base; + if (block.projectedSize != -1 && block_size >= static_cast(block.projectedSize)) { + REXCODEGEN_TRACE("Block 0x{:08X} hit projection limit at size 0x{:X}", block.base, + block_size); + // Block done - save and pop + result.blocks.push_back(block); + block_stack.pop_back(); + continue; + } + + // Check if this address was already scanned by another block (overlap prevention) + // This catches cases where a fall-through block tries to scan into territory + // already covered by another block (e.g., shared epilogue code) + if (scannedAddrs.count(addr)) { + // Block ends here - don't include the already-scanned instruction + if (addr > block.base) { + // Record the overlap address as a successor so codegen emits a goto + block.successors.push_back(addr); + block.has_terminator = true; + result.blocks.push_back(block); + } + block_stack.pop_back(); + continue; + } + + // CRITICAL: Check if we've hit another function's entry point + // This enforces the authority system - PDATA/config entries cannot be consumed + if (addr != entry_point && known_callables_.contains(static_cast(addr))) { + REXCODEGEN_TRACE("discover_blocks: hit entry point 0x{:08X} - stopping block", addr); + if (addr > block.base) { + // Block has content - save it + block.end = addr; // Don't include this instruction + block.has_terminator = true; + result.blocks.push_back(block); + } + // Either way, pop this block - we can't continue into another function + block_stack.pop_back(); + continue; + } + + // Fetch instruction + auto host_ptr = translate_address(addr); + if (!host_ptr) { + REXCODEGEN_DEBUG("discover_blocks: invalid address 0x{:08X}", addr); + block.has_terminator = true; + result.blocks.push_back(block); + block_stack.pop_back(); + continue; + } + + u32 code = load_and_swap(host_ptr); + + // Null instruction ends block + if (code == 0x00000000) { + block.end = addr; // Don't include the null + block.has_terminator = true; + result.blocks.push_back(block); + block_stack.pop_back(); + continue; + } + + // Include this instruction in block + block.end = addr + 4; + scannedAddrs.insert(addr); // Mark this address as scanned + + Instruction instr = decode_instruction(addr, code); + + // Check for blr (return) + if (instr.is_return()) { + block.has_terminator = true; + result.blocks.push_back(block); + block_stack.pop_back(); + continue; + } + + // Check for bctr (indirect branch) + if (instr.opcode == Opcode::bcctr) { + auto jt_info = detect_jump_table(addr); + if (jt_info.has_value()) { + result.jump_tables.push_back(jt_info.value()); + // Add all jump table targets as successors + for (guest_addr_t target : jt_info->targets) { + block.successors.push_back(target); + } + } + block.has_terminator = true; + result.blocks.push_back(block); + block_stack.pop_back(); + + // Push jump table targets onto stack (if any) + if (jt_info.has_value()) { + for (guest_addr_t target : jt_info->targets) { + if (!scannedAddrs.count(target)) { + DiscoveredBlock jt_block; + jt_block.base = target; + jt_block.end = target; + jt_block.projectedSize = -1; + block_stack.push_back(jt_block); + } + } + } + continue; + } + + // Check for unconditional branch (b/ba) + if (instr.opcode == Opcode::b || instr.opcode == Opcode::ba) { + if (instr.branch_target.has_value()) { + guest_addr_t target = instr.branch_target.value(); + block.successors.push_back(target); + + // Check known_callables_ FIRST (gathered before discovery) + bool is_tail_call = known_callables_.contains(static_cast(target)); + + // Backward branch to unknown = probably tail call + if (!is_tail_call && target < entry_point) { + is_tail_call = true; + } + + // Large forward branch (>1MB) = probably tail call to shared code + // No legitimate internal branch spans more than 1MB + if (!is_tail_call && target > addr && (target - addr) > 0x100000) { + is_tail_call = true; + } + + // Check if target is a known callable (function or import) + if (!is_tail_call && isKnownCallable(static_cast(target))) { + is_tail_call = true; + } + + // CRITICAL: Check code region boundary + // If target is in a different region (and not a configured chunk), + // it MUST be a tail call - prevents mega-merges across null boundaries + if (!is_tail_call && + !isInternalBranch(static_cast(addr), static_cast(target), + static_cast(entry_point))) { + is_tail_call = true; + } + + // CRITICAL: Check if target looks like a function entry (has prologue) + // If branching to a prologue, it's definitely a tail call to another function + if (!is_tail_call && is_prologue_pattern(target)) { + REXCODEGEN_TRACE("discover_blocks: target 0x{:08X} has prologue pattern (TAIL CALL)", + target); + is_tail_call = true; + } + + if (is_tail_call) { + REXCODEGEN_TRACE("discover_blocks: b 0x{:08X} -> 0x{:08X} is TAIL CALL", addr, target); + result.tail_calls.push_back(target); + } else if (!scannedAddrs.count(target)) { + REXCODEGEN_TRACE( + "discover_blocks: b 0x{:08X} -> 0x{:08X} treated as INTERNAL (entry=0x{:08X})", addr, + target, entry_point); + // Carry projection forward if branch is continuous + bool is_continuous = (target == block.end); + int64_t carry_projection = -1; + if (is_continuous && block.projectedSize != -1) { + carry_projection = block.projectedSize - static_cast(block.end - block.base); + if (carry_projection <= 0) + carry_projection = -1; + } + + // IMPORTANT: Save and pop current block FIRST, before push_back + // push_back can reallocate the vector, invalidating 'block' reference + block.has_terminator = true; + result.blocks.push_back(block); + block_stack.pop_back(); + + // Now safe to push new block + DiscoveredBlock target_block; + target_block.base = target; + target_block.end = target; + target_block.projectedSize = carry_projection; + block_stack.push_back(target_block); + continue; + } + } + block.has_terminator = true; + result.blocks.push_back(block); + block_stack.pop_back(); + continue; + } + + // Check for function call (bl) - doesn't end block + if (instr.is_call() && instr.branch_target.has_value()) { + result.external_calls.push_back(instr.branch_target.value()); + // Continue to next instruction (block.end already updated) + continue; + } + + // Check for conditional return (bclr/bclrl with conditional BO) + // These return to LR if condition is met, otherwise fall through + // Examples: blelr, bgtlr, bnelr, beqlr, etc. + if ((instr.opcode == Opcode::bclr || instr.opcode == Opcode::bclrl) && + !instr.is_return()) { // is_return() only matches unconditional blr + guest_addr_t fall_through = addr + 4; + block.successors.push_back(fall_through); + block.has_terminator = true; + result.blocks.push_back(block); + block_stack.pop_back(); // Pop current block BEFORE pushing fall-through + + // Push fall-through block onto stack + if (!scannedAddrs.count(fall_through)) { + DiscoveredBlock ft_block; + ft_block.base = fall_through; + ft_block.end = fall_through; + ft_block.projectedSize = -1; + block_stack.push_back(ft_block); + } + continue; + } + + // Check for conditional branch (bc, bca, etc.) + if (instr.is_branch() && instr.branch_target.has_value()) { + guest_addr_t target = instr.branch_target.value(); + guest_addr_t fall_through = addr + 4; + + // Block ends at conditional branch + block.successors.push_back(fall_through); + block.successors.push_back(target); + result.blocks.push_back(block); + block_stack.pop_back(); + + // Push true-case first, then false-case + // False-case (fall-through) gets projectedSize = distance to true-case + // This prevents fall-through from growing past the branch target + + // Check if target is internal to function (at or after entry point) + bool target_is_internal = (target >= entry_point); + + // Push true-case block (branch target) - no projection + if (target_is_internal && !scannedAddrs.count(target)) { + DiscoveredBlock true_block; + true_block.base = target; + true_block.end = target; + true_block.projectedSize = -1; // No limit on true-case + block_stack.push_back(true_block); + } + + // Push false-case block (fall-through) WITH projection + if (!scannedAddrs.count(fall_through)) { + DiscoveredBlock false_block; + false_block.base = fall_through; + false_block.end = fall_through; + + // Project size: distance from fall-through to branch target + // This prevents fall-through from consuming code past the branch target + if (target_is_internal && target > fall_through) { + false_block.projectedSize = static_cast(target - fall_through); + REXCODEGEN_TRACE( + "Conditional branch at 0x{:08X}: fall-through 0x{:08X} projected to 0x{:X} bytes", + addr, fall_through, false_block.projectedSize); + } else { + false_block.projectedSize = -1; + } + block_stack.push_back(false_block); + } + continue; + } + + // Regular instruction - continue to next (block.end already updated) + } + + if (result.blocks.empty()) { + REXCODEGEN_WARN("discover_blocks: no blocks found for entry 0x{:08X}", entry_point); + } + + // Sort blocks by address for deterministic output and easier diffing + std::sort(result.blocks.begin(), result.blocks.end(), + [](const DiscoveredBlock& a, const DiscoveredBlock& b) { return a.base < b.base; }); + + return result; +} + +//============================================================================= +// Code Region Boundary Checking +//============================================================================= + +const CodeRegion* FunctionScanner::findRegionContaining(uint32_t address) const { + if (!code_regions_) + return nullptr; + + for (const auto& region : *code_regions_) { + if (region.contains(address)) { + return ®ion; + } + } + return nullptr; +} + +bool FunctionScanner::isInternalBranch(uint32_t currentAddr, uint32_t targetAddr, + uint32_t functionEntry) const { + // Check if target is a configured chunk of the current function + // Chunks can cross region boundaries by design + if (isWithinChunk(targetAddr, functionEntry)) { + return true; + } + + // Find regions for both addresses + const auto* currentRegion = findRegionContaining(currentAddr); + const auto* targetRegion = findRegionContaining(targetAddr); + + // If target is in a different region (or no region), it's a tail call + if (currentRegion != targetRegion) { + REXCODEGEN_TRACE("isInternalBranch: 0x{:08X} -> 0x{:08X} crosses region boundary (TAIL CALL)", + currentAddr, targetAddr); + return false; + } + + return true; +} + +//============================================================================= +// Block Discovery +//============================================================================= + +namespace { + +//============================================================================= +// Helper: Check if instruction is prologue pattern +//============================================================================= + +[[maybe_unused]] +bool isProloguePattern(const DecodedInsn& insn) { + using namespace rex::codegen::ppc; + switch (insn.opcode) { + case Opcode::mflr: + case Opcode::mfspr: // mflr is really mfspr with SPR=8 + return true; + case Opcode::stwu: + // stwu r1, -X(r1) - stack frame setup + return insn.D.RA == 1 && insn.D.RT == 1 && static_cast(insn.D.d) < 0; + default: + return false; + } +} + +//============================================================================= +// Helper: Check if block should stop at this instruction +//============================================================================= + +bool isBlockTerminator(const DecodedInsn& insn, uint32_t addr, const CodeRegion& region, + const std::unordered_set& knownFunctions) { + using namespace rex::codegen::ppc; + + // NULL padding ends block (but NOT unknown instructions - those get emitted as comments) + uint32_t raw = static_cast(insn.code); + if (raw == 0x00000000 || raw == 0xFFFFFFFF) { + return true; + } + // Note: kUnknown opcodes (like 64-bit rotate instructions) are NOT terminators. + // They should be included in the block and emitted as comments during codegen. + + // Check for terminators + if (isReturn(insn)) + return true; + + // bcctr (indirect branch via CTR) + if (insn.opcode == Opcode::bcctr || insn.opcode == Opcode::bcctrl) { + // bcctrl is call, bcctr is terminator + return insn.opcode == Opcode::bcctr; + } + + // Unconditional branch + if (isBranch(insn) && !isConditional(insn) && !isCall(insn)) { + auto target = getBranchTarget(insn); + if (target) { + // Branch outside region is terminator + if (!region.contains(*target)) + return true; + // Branch to known function is tail call (terminator) + if (knownFunctions.contains(*target)) + return true; + } + return true; // Unconditional branch always terminates block + } + + return false; +} + +//============================================================================= +// Helper: Detect bounds check for jump table +//============================================================================= + +BoundsInfo scanForBounds(DecodedBinary& decoded, uint32_t bctrAddr, const CodeRegion& region, + uint8_t expectedReg, uint32_t funcStart) { + BoundsInfo result; + const int backwardScanLimit = static_cast(REXCVAR_GET(backward_scan_limit)); + + // Use funcStart as lower bound to avoid scanning into other functions + uint32_t scanLowerBound = std::max(region.start, funcStart); + + REXCODEGEN_TRACE( + "scanForBounds: bctr=0x{:08X} region=[0x{:08X}-0x{:08X}] funcStart=0x{:08X} expectedReg=r{}", + bctrAddr, region.start, region.end, funcStart, expectedReg); + + uint32_t scanAddr = bctrAddr; + for (int i = 0; i < backwardScanLimit && scanAddr >= scanLowerBound + 4; i++) { + scanAddr -= 4; + auto* insn = decoded.get(scanAddr); + if (!insn) + break; + + // Stop at unconditional terminators - scanning past basic block boundaries + // risks finding unrelated comparisons on the index register + if (isTerminator(*insn) && !isConditional(*insn)) + break; + + using namespace rex::codegen::ppc; + + // Look for cmpli/cmpi followed by conditional branch + if (insn->opcode == Opcode::cmpli) { + // cmpli crX, L, rA, UIMM + REXCODEGEN_TRACE("scanForBounds: found cmpli at 0x{:08X} RA=r{} UIMM={} (expecting r{})", + scanAddr, static_cast(insn->D.RA), static_cast(insn->D.d), + expectedReg); + if (insn->D.RA == expectedReg) { + result.maxEntries = static_cast(insn->D.d) + 1; + result.indexReg = expectedReg; + result.found = true; + REXCODEGEN_TRACE("scanForBounds: MATCHED! maxEntries={}", result.maxEntries); + return result; + } + } + + if (insn->opcode == Opcode::cmpi) { + // cmpi crX, L, rA, SIMM + REXCODEGEN_TRACE("scanForBounds: found cmpi at 0x{:08X} RA=r{} SIMM={} (expecting r{})", + scanAddr, static_cast(insn->D.RA), static_cast(insn->D.d), + expectedReg); + if (insn->D.RA == expectedReg) { + result.maxEntries = static_cast(insn->D.d) + 1; + result.indexReg = expectedReg; + result.found = true; + REXCODEGEN_TRACE("scanForBounds: MATCHED! maxEntries={}", result.maxEntries); + return result; + } + } + + // Look for clrlwi (rlwinm rA, rS, 0, MB, 31) which masks bits + // MB must be > 0 to actually mask something; MB=0 is a no-op + if (insn->opcode == Opcode::rlwinm) { + if (insn->M.RA == expectedReg && insn->M.SH == 0 && insn->M.ME == 31 && insn->M.MB > 0) { + // Masked to (32 - MB) bits, max value is 2^(32-MB) - 1 + uint32_t bits = 32 - insn->M.MB; + result.maxEntries = 1u << bits; + result.indexReg = expectedReg; + result.found = true; + REXCODEGEN_TRACE("scanForBounds: found clrlwi at 0x{:08X} MB={} maxEntries={}", scanAddr, + static_cast(insn->M.MB), result.maxEntries); + return result; + } + } + } + + REXCODEGEN_TRACE("scanForBounds: no bounds found for bctr=0x{:08X}", bctrAddr); + return result; +} + +} // anonymous namespace + +//============================================================================= +// Jump Table Detection +//============================================================================= +std::optional detectJumpTable(DecodedBinary& decoded, uint32_t bctrAddr, + const CodeRegion& containingRegion, uint32_t funcStart, + uint32_t funcEnd) { + using namespace rex::codegen::ppc; + + const int kMaxBackwardScan = static_cast(REXCVAR_GET(backward_scan_limit)); + const uint32_t kMaxTableEntries = REXCVAR_GET(max_jump_table_entries); + + // State for backward scan + uint8_t ctrSourceReg = 0xFF; + uint32_t tableAddr = 0; + uint32_t baseAddr = 0; + // Pending address parts (order of lis/addi varies in backward scan) + // Note: addi uses sign-extended addition, ori uses OR + uint32_t pendingTableLo = 0, pendingTableHi = 0; + uint32_t pendingBaseLo = 0, pendingBaseHi = 0; + bool hasPendingTableLo = false, hasPendingTableHi = false; + bool hasPendingBaseLo = false, hasPendingBaseHi = false; + bool pendingTableLoIsAddi = false, pendingBaseLoIsAddi = false; + + // Helper to combine lis high bits with addi/ori low bits + auto combineHiLo = [](uint32_t hi, uint32_t lo, bool isAddi) -> uint32_t { + if (isAddi) { + // addi: sign-extend lo and add + return hi + static_cast(static_cast(static_cast(lo))); + } else { + // ori: zero-extend and OR + return hi | lo; + } + }; + JumpTableType tableType = JumpTableType::kAbsolute; + uint8_t indexReg = 0xFF; // Current reg being traced (0xFF = stop tracing) + uint8_t finalIndexReg = 0xFF; // Last valid indexReg for scanForBounds/output + int shiftAmount = 0; + + // Backward scan from bctr + uint32_t scanAddr = bctrAddr; + bool foundMtctr = false; + bool foundLoad = false; + + for (int i = 0; i < kMaxBackwardScan && scanAddr >= containingRegion.start + 4; i++) { + scanAddr -= 4; + auto* insn = decoded.get(scanAddr); + if (!insn) + break; + + // Stop at unconditional terminators (but NOT conditional branches - they're often bounds + // checks) + if (isTerminator(*insn) && !isConditional(*insn)) + break; + + // Find mtctr rX + if (!foundMtctr) { + if (insn->opcode == Opcode::mtctr || insn->opcode == Opcode::mtspr) { + // mtctr is mtspr 9, rS + ctrSourceReg = insn->XFX.RT; + foundMtctr = true; + continue; + } + } + + // After mtctr, look for load into ctrSourceReg + if (foundMtctr && !foundLoad) { + // lwzx rD, rA, rB - indexed word load (ABSOLUTE table) + if (insn->opcode == Opcode::lwzx && insn->X.RT == ctrSourceReg) { + // Table address is in rA, index scaled in rB + tableType = JumpTableType::kAbsolute; + indexReg = insn->X.RB; + finalIndexReg = indexReg; + foundLoad = true; + REXCODEGEN_TRACE("detectJumpTable: bctr=0x{:08X} found lwzx at 0x{:08X}", bctrAddr, + scanAddr); + continue; + } + + // lbzx rD, rA, rB - indexed byte load (BYTE/COMPUTED table) + if (insn->opcode == Opcode::lbzx && insn->X.RT == ctrSourceReg) { + // Don't overwrite kComputed (set by rlwinm for shifted byte tables) + if (tableType != JumpTableType::kComputed) { + tableType = JumpTableType::kByteOffset; + } + indexReg = insn->X.RB; + finalIndexReg = indexReg; + foundLoad = true; + REXCODEGEN_TRACE("detectJumpTable: bctr=0x{:08X} found lbzx at 0x{:08X}", bctrAddr, + scanAddr); + continue; + } + + // lhzx rD, rA, rB - indexed halfword load (SHORTOFFSET table) + if (insn->opcode == Opcode::lhzx && insn->X.RT == ctrSourceReg) { + // Don't overwrite kComputed + if (tableType != JumpTableType::kComputed) { + tableType = JumpTableType::kShortOffset; + } + indexReg = insn->X.RB; + finalIndexReg = indexReg; + foundLoad = true; + REXCODEGEN_TRACE("detectJumpTable: bctr=0x{:08X} found lhzx at 0x{:08X}", bctrAddr, + scanAddr); + continue; + } + + // add rD, rA, rB - combining base with offset + // Pattern: rD = base + offset, where one operand is base, other is from table + if (insn->opcode == Opcode::add && insn->XO.RT == ctrSourceReg) { + // If RA == rD (e.g., r12 = r12 + r0), then RB has the table offset + // If RA != rD (e.g., r12 = r11 + r0), follow RA for the chain + if (insn->XO.RA == ctrSourceReg) { + // Pattern: r12 = r12 + r0 --> r0 came from table load + ctrSourceReg = insn->XO.RB; + } else { + // Follow RA + ctrSourceReg = insn->XO.RA; + } + REXCODEGEN_TRACE("detectJumpTable: bctr=0x{:08X} found add at 0x{:08X}, now tracking r{}", + bctrAddr, scanAddr, ctrSourceReg); + continue; + } + + // rlwinm - shift for computed offset (slwi is rlwinm simplified) + if (insn->opcode == Opcode::rlwinm && insn->M.RA == ctrSourceReg) { + shiftAmount = insn->M.SH; + if (shiftAmount > 0) { + tableType = JumpTableType::kComputed; + } + ctrSourceReg = insn->M.RS; + REXCODEGEN_TRACE("detectJumpTable: bctr=0x{:08X} found rlwinm at 0x{:08X}", bctrAddr, + scanAddr); + continue; + } + + // Log unhandled instructions in the chain (potential issue) + REXCODEGEN_TRACE( + "detectJumpTable: bctr=0x{:08X} unhandled insn at 0x{:08X} opcode={} while looking for " + "load into r{}", + bctrAddr, scanAddr, static_cast(insn->opcode), ctrSourceReg); + } + + // After load: trace back indexReg through LEFT SHIFT (slwi) instructions only + // slwi rA, rS, n is rlwinm rA, rS, n, 0, 31-n (MB=0, ME=31-SH) + // This scales the index for table lookup (e.g., slwi r0, r31, 1 for halfword table) + // DON'T trace back through extrwi/other rlwinm variants - those transform the value + // NOTE: SH must be > 0 for a real shift; SH=0 is just a move/no-op (clrlwi r,r,0) + // IMPORTANT: Stop tracing if another instruction writes to indexReg (breaks the chain) + if (foundLoad && indexReg != 0xFF) { + // Check if this instruction writes to indexReg + bool writesToIndexReg = false; + uint8_t destReg = 0xFF; + + // Check common instruction forms that write to a register + if (insn->opcode == Opcode::rlwinm) { + destReg = insn->M.RA; + } else if (insn->opcode == Opcode::srawi || insn->opcode == Opcode::sraw || + insn->opcode == Opcode::srw || insn->opcode == Opcode::slw) { + // X-form shift instructions: destination is RA (bits 11-15) + destReg = insn->X.RA; + } else if (insn->opcode == Opcode::lbz || insn->opcode == Opcode::lhz || + insn->opcode == Opcode::lwz || insn->opcode == Opcode::li || + insn->opcode == Opcode::lis || insn->opcode == Opcode::addi) { + destReg = insn->D.RT; + } else if (insn->opcode == Opcode::lbzx || insn->opcode == Opcode::lhzx || + insn->opcode == Opcode::lwzx) { + // X-form load instructions: destination is RT (bits 6-10) + destReg = insn->X.RT; + } else if (insn->opcode == Opcode::or_ || insn->opcode == Opcode::and_ || + insn->opcode == Opcode::xor_ || insn->opcode == Opcode::mr) { + // X-form logical instructions: destination is RA (bits 11-15), NOT RT + // (RT is RS/source for these instructions) + destReg = insn->X.RA; + } else if (insn->opcode == Opcode::add || insn->opcode == Opcode::subf) { + // XO-form instructions (add, subf) + destReg = insn->XO.RT; + } + + if (destReg == indexReg) { + writesToIndexReg = true; + + // Check for slwi pattern: if it matches, trace back; otherwise stop tracing + if (insn->opcode == Opcode::rlwinm) { + uint8_t sh = insn->M.SH; + uint8_t mb = insn->M.MB; + uint8_t me = insn->M.ME; + // Check for slwi pattern: SH>0, MB=0, ME=31-SH + if (sh > 0 && mb == 0 && me == (31 - sh)) { + indexReg = insn->M.RS; + finalIndexReg = indexReg; + REXCODEGEN_TRACE( + "detectJumpTable: bctr=0x{:08X} found slwi at 0x{:08X} indexReg now r{}", bctrAddr, + scanAddr, indexReg); + } else { + // Non-slwi rlwinm writes to indexReg, stop tracing + REXCODEGEN_TRACE( + "detectJumpTable: bctr=0x{:08X} indexReg r{} overwritten by non-slwi rlwinm at " + "0x{:08X}, stop tracing", + bctrAddr, indexReg, scanAddr); + indexReg = 0xFF; // Mark as invalid to stop further tracing + } + } else { + // Another instruction writes to indexReg, stop tracing + REXCODEGEN_TRACE( + "detectJumpTable: bctr=0x{:08X} indexReg r{} overwritten at 0x{:08X}, stop tracing", + bctrAddr, indexReg, scanAddr); + indexReg = 0xFF; // Mark as invalid to stop further tracing + } + } + } + + // Find lis/addi pairs for table and base addresses + // When scanning backward for byte offset tables: + // - BEFORE foundLoad (between mtctr and lbzx): baseAddr + // - AFTER foundLoad (before lbzx in forward order): tableAddr + // For absolute tables (lwzx), there's only tableAddr (after foundLoad) + if (foundMtctr) { + // lis rD, HI + if (insn->opcode == Opcode::lis) { + uint32_t hi = static_cast(static_cast(insn->D.d)) << 16; + REXCODEGEN_TRACE( + "detectJumpTable: bctr=0x{:08X} found lis at 0x{:08X} hi=0x{:08X} foundLoad={}", + bctrAddr, scanAddr, hi, foundLoad); + if (foundLoad) { + // After load: this is tableAddr (only capture first complete address) + if (tableAddr == 0) { + tableAddr = + hasPendingTableLo ? combineHiLo(hi, pendingTableLo, pendingTableLoIsAddi) : hi; + hasPendingTableLo = false; + REXCODEGEN_TRACE("detectJumpTable: bctr=0x{:08X} set tableAddr=0x{:08X}", bctrAddr, + tableAddr); + } + // Once tableAddr is set, ignore further lis instructions + } else { + // Before load (between mtctr and load): this is baseAddr + if (baseAddr == 0) { + baseAddr = hasPendingBaseLo ? combineHiLo(hi, pendingBaseLo, pendingBaseLoIsAddi) : hi; + hasPendingBaseLo = false; + REXCODEGEN_TRACE("detectJumpTable: bctr=0x{:08X} set baseAddr=0x{:08X}", bctrAddr, + baseAddr); + } + // Once baseAddr is set, ignore further lis instructions + } + } + + // addi rD, rA, LO (ori also possible) + if (insn->opcode == Opcode::addi || insn->opcode == Opcode::ori) { + uint32_t lo = static_cast(insn->D.d); + bool isAddi = (insn->opcode == Opcode::addi); + REXCODEGEN_TRACE( + "detectJumpTable: bctr=0x{:08X} found {} at 0x{:08X} lo=0x{:04X} foundLoad={}", + bctrAddr, isAddi ? "addi" : "ori", scanAddr, lo, foundLoad); + if (foundLoad) { + // After load: this is tableAddr (only capture first complete address) + if (tableAddr == 0) { + if (hasPendingTableHi) { + tableAddr = combineHiLo(pendingTableHi, lo, isAddi); + hasPendingTableHi = false; + REXCODEGEN_TRACE("detectJumpTable: bctr=0x{:08X} set tableAddr=0x{:08X} from pending", + bctrAddr, tableAddr); + } else if (!hasPendingTableLo) { + pendingTableLo = lo; + pendingTableLoIsAddi = isAddi; + hasPendingTableLo = true; + REXCODEGEN_TRACE("detectJumpTable: bctr=0x{:08X} pending tableLo=0x{:04X}", bctrAddr, + lo); + } + } else if ((tableAddr & 0xFFFF) == 0) { + // tableAddr has only high bits, add low bits + tableAddr = combineHiLo(tableAddr, lo, isAddi); + REXCODEGEN_TRACE("detectJumpTable: bctr=0x{:08X} combined tableAddr=0x{:08X}", bctrAddr, + tableAddr); + } + // Once tableAddr is fully set, ignore further addi instructions + } else { + // Before load: this is baseAddr + if (baseAddr == 0) { + if (hasPendingBaseHi) { + baseAddr = combineHiLo(pendingBaseHi, lo, isAddi); + hasPendingBaseHi = false; + REXCODEGEN_TRACE("detectJumpTable: bctr=0x{:08X} set baseAddr=0x{:08X} from pending", + bctrAddr, baseAddr); + } else if (!hasPendingBaseLo) { + pendingBaseLo = lo; + pendingBaseLoIsAddi = isAddi; + hasPendingBaseLo = true; + REXCODEGEN_TRACE("detectJumpTable: bctr=0x{:08X} pending baseLo=0x{:04X}", bctrAddr, + lo); + } + } else if ((baseAddr & 0xFFFF) == 0) { + baseAddr = combineHiLo(baseAddr, lo, isAddi); + REXCODEGEN_TRACE("detectJumpTable: bctr=0x{:08X} combined baseAddr=0x{:08X}", bctrAddr, + baseAddr); + } + // Once baseAddr is fully set, ignore further addi instructions + } + } + } + } + + REXCODEGEN_TRACE( + "detectJumpTable: bctr=0x{:08X} scan complete: foundMtctr={} foundLoad={} tableAddr=0x{:08X} " + "baseAddr=0x{:08X}", + bctrAddr, foundMtctr, foundLoad, tableAddr, baseAddr); + + if (!foundMtctr || !foundLoad || tableAddr == 0) { + REXCODEGEN_TRACE( + "detectJumpTable: bctr=0x{:08X} FAILED foundMtctr={} foundLoad={} tableAddr=0x{:08X}", + bctrAddr, foundMtctr, foundLoad, tableAddr); + return std::nullopt; + } + + // For offset-based tables, we need a base address + if (tableType != JumpTableType::kAbsolute && baseAddr == 0) { + baseAddr = containingRegion.start; // Fallback to region start + } + + // Find bounds + auto bounds = scanForBounds(decoded, bctrAddr, containingRegion, finalIndexReg, funcStart); + // If bounds not found (e.g., state machine pattern with forward bounds check), + // use max entries and let the validation loop determine actual table size + uint32_t entryCount = bounds.found ? bounds.maxEntries : kMaxTableEntries; + + // Read table entries + JumpTable jt; + jt.bctrAddress = bctrAddr; + jt.tableAddress = tableAddr; + jt.indexRegister = finalIndexReg; + + REXCODEGEN_TRACE( + "detectJumpTable: bctr=0x{:08X} reading {} entries from table=0x{:08X} base=0x{:08X} type={}", + bctrAddr, entryCount, tableAddr, baseAddr, static_cast(tableType)); + + for (uint32_t i = 0; i < entryCount; i++) { + uint32_t target = 0; + + switch (tableType) { + case JumpTableType::kAbsolute: { + auto val = decoded.read(tableAddr + i * 4); + if (!val) { + REXCODEGEN_TRACE("detectJumpTable: bctr=0x{:08X} entry[{}] read failed at 0x{:08X}", + bctrAddr, i, tableAddr + i * 4); + break; + } + target = *val; + break; + } + case JumpTableType::kByteOffset: { + auto val = decoded.read(tableAddr + i); + if (!val) { + REXCODEGEN_TRACE("detectJumpTable: bctr=0x{:08X} entry[{}] read failed at 0x{:08X}", + bctrAddr, i, tableAddr + i); + break; + } + target = baseAddr + *val; + REXCODEGEN_TRACE("detectJumpTable: bctr=0x{:08X} entry[{}] offset=0x{:02X} target=0x{:08X}", + bctrAddr, i, *val, target); + break; + } + case JumpTableType::kComputed: { + auto val = decoded.read(tableAddr + i); + if (!val) + break; + target = baseAddr + (static_cast(*val) << shiftAmount); + break; + } + case JumpTableType::kShortOffset: { + auto val = decoded.read(tableAddr + i * 2); + if (!val) + break; + target = baseAddr + *val; + break; + } + } + + // PPC instructions must be 4-byte aligned + if (target & 3) { + REXCODEGEN_TRACE( + "detectJumpTable: bctr=0x{:08X} entry[{}] target=0x{:08X} not 4-byte aligned", bctrAddr, + i, target); + if (jt.targets.empty()) + return std::nullopt; + break; + } + + // Validate target is within code region - jump table targets help DEFINE function extent + // Don't constrain by funcEnd since that's just PDATA which may not include out-of-line code + if (target == 0 || !containingRegion.contains(target)) { + // TODO(tomc): Figure out what this voodoo does on real hardware. Its a jump target that + // points to a null value..? + if (target != 0) { + auto outsideInsn = decoded.read(target); + if (outsideInsn && (*outsideInsn == 0x00000000 || *outsideInsn == 0xFFFFFFFF)) { + REXCODEGEN_TRACE( + "detectJumpTable: bctr=0x{:08X} entry[{}] target=0x{:08X} null jump sentinel", + bctrAddr, i, target); + jt.targets.push_back(0); // sentinel + continue; + } + } + // End of valid entries + REXCODEGEN_TRACE( + "detectJumpTable: bctr=0x{:08X} entry[{}] target=0x{:08X} invalid (region " + "0x{:08X}-0x{:08X})", + bctrAddr, i, target, containingRegion.start, containingRegion.end); + if (jt.targets.empty()) + return std::nullopt; + break; + } + + // Target must be >= function start (can't jump backward past entry point) + if (target < funcStart) { + REXCODEGEN_TRACE( + "detectJumpTable: bctr=0x{:08X} entry[{}] target=0x{:08X} < funcStart=0x{:08X}", bctrAddr, + i, target, funcStart); + if (jt.targets.empty()) + return std::nullopt; + break; + } + + // Validate target points to valid code, not null padding + // TODO(tomc): look into this more. what is the expected behavior when the processor executes + // a null instruction. + auto targetInsn = decoded.read(target); + if (targetInsn && (*targetInsn == 0x00000000 || *targetInsn == 0xFFFFFFFF)) { + REXCODEGEN_TRACE( + "detectJumpTable: bctr=0x{:08X} entry[{}] target=0x{:08X} points to null/padding " + "(0x{:08X})", + bctrAddr, i, target, *targetInsn); + jt.targets.push_back(0); // sentinel, handled in codegen as __builtin_trap() + continue; + } + + jt.targets.push_back(target); + } + + if (jt.targets.empty()) { + REXCODEGEN_TRACE( + "detectJumpTable: bctr=0x{:08X} table=0x{:08X} NO VALID TARGETS (funcStart=0x{:08X} " + "funcEnd=0x{:08X})", + bctrAddr, tableAddr, funcStart, funcEnd); + return std::nullopt; + } + + REXCODEGEN_TRACE("detectJumpTable: bctr=0x{:08X} table=0x{:08X} entries={} funcEnd=0x{:08X}", + bctrAddr, tableAddr, jt.targets.size(), funcEnd); + return jt; +} + +//============================================================================= +// Block Discovery +//============================================================================= + +BlockDiscoveryResult discoverBlocks(DecodedBinary& decoded, uint32_t entryPoint, + const CodeRegion& containingRegion, + const std::unordered_set& knownFunctions, + uint32_t pdataSize) { + BlockDiscoveryResult result; + std::unordered_set visited; + std::unordered_set blockStarts; + std::queue worklist; + + // Function extent - use pdataSize when available + uint32_t funcEnd = (pdataSize > 0) ? (entryPoint + pdataSize) : containingRegion.end; + + REXCODEGEN_TRACE( + "discoverBlocks: entry=0x{:08X} pdataSize={} funcEnd=0x{:08X} region=[0x{:08X}-0x{:08X}]", + entryPoint, pdataSize, funcEnd, containingRegion.start, containingRegion.end); + + // Helper to check if address is within function bounds + auto isWithinFunction = [&](uint32_t addr) -> bool { + return addr >= entryPoint && addr < funcEnd; + }; + + // Start with entry point + worklist.push(entryPoint); + blockStarts.insert(entryPoint); + + while (!worklist.empty()) { + uint32_t blockStart = worklist.front(); + worklist.pop(); + + if (visited.contains(blockStart)) + continue; + if (!isWithinFunction(blockStart)) + continue; + + // Linear scan until terminator + uint32_t addr = blockStart; + Block block; + block.base = blockStart; + block.size = 0; + + while (isWithinFunction(addr)) { + auto* insn = decoded.get(addr); + if (!insn) { + REXCODEGEN_TRACE("discoverBlocks: 0x{:08X} no instruction at addr, breaking", entryPoint); + break; + } + + // Mark as visited + visited.insert(addr); + + // Collect instruction pointer + result.instructions.push_back(insn); + + // Handle branches + if (isBranch(*insn)) { + auto target = getBranchTarget(*insn); + + // Helper: check if target is internal to this function + // Uses funcEnd (from pdataSize or region) defined at top of function + auto isInternalTarget = [&](uint32_t t) -> bool { + // Must be within function bounds + if (t < entryPoint || t >= funcEnd) { + return false; + } + // Must not be a known function entry (except our own entry point) + if (t != entryPoint && knownFunctions.contains(t)) { + return false; + } + return true; + }; + + if (isCall(*insn)) { + // bl - function call + if (target) { + // All bl instructions need to be recorded as unresolved branches + // so they can be resolved to CallEdges during merge phase + result.unresolvedBranches.push_back({addr, *target, true, false}); + + // Track as external call for function discovery + if (!isInternalTarget(*target)) { + result.externalCalls.push_back(*target); + } + } + // Calls don't terminate block, fall through + } else if (isReturn(*insn)) { + // blr - end of function path + block.size = addr - blockStart + 4; + break; + } else if (insn->opcode == rex::codegen::ppc::Opcode::bcctr) { + // bctr - try to detect jump table + REXCODEGEN_TRACE("discoverBlocks: bctr at 0x{:08X} in func 0x{:08X}, funcEnd=0x{:08X}", + addr, entryPoint, funcEnd); + auto jt = detectJumpTable(decoded, addr, containingRegion, entryPoint, funcEnd); + if (jt) { + REXCODEGEN_TRACE("discoverBlocks: detected jump table at bctr 0x{:08X} with {} targets", + addr, jt->targets.size()); + result.jumpTables.push_back(*jt); + // Jump table targets are definitionally part of this function + // Extend funcEnd if any target exceeds it (within region bounds) + // This handles out-of-line switch case code + for (uint32_t t : jt->targets) { + if (t == 0) + continue; // sentinel from null-padding detection + if (t >= funcEnd && t < containingRegion.end) { + funcEnd = t + 4; // Extend to include this target + } + result.labels.insert(t); + if (!visited.contains(t) && !blockStarts.contains(t)) { + blockStarts.insert(t); + worklist.push(t); + } + } + } + block.size = addr - blockStart + 4; + break; + } else if (isConditional(*insn)) { + // Conditional branch - follow both paths + if (target && isInternalTarget(*target)) { + result.labels.insert(*target); + if (!visited.contains(*target) && !blockStarts.contains(*target)) { + blockStarts.insert(*target); + worklist.push(*target); + } + } else if (target) { + // External conditional branch (or conditional tail call to known function) + result.unresolvedBranches.push_back({addr, *target, false, true}); + } + // CRITICAL: Fall-through also needs a label + uint32_t fallthrough = addr + 4; + if (isInternalTarget(fallthrough)) { + result.labels.insert(fallthrough); + if (!visited.contains(fallthrough) && !blockStarts.contains(fallthrough)) { + blockStarts.insert(fallthrough); + worklist.push(fallthrough); + } + } + } else { + // Unconditional branch + if (target) { + if (isInternalTarget(*target)) { + // Internal unconditional branch (includes backward branches) + result.labels.insert(*target); + if (!visited.contains(*target) && !blockStarts.contains(*target)) { + blockStarts.insert(*target); + worklist.push(*target); + } + } else { + // Tail call to external + result.tailCalls.push_back(*target); + result.unresolvedBranches.push_back({addr, *target, false, false}); + } + } + block.size = addr - blockStart + 4; + break; + } + } + + // Check for block terminator (null, prologue of next function, etc.) + if (isBlockTerminator(*insn, addr, containingRegion, knownFunctions)) { + REXCODEGEN_TRACE("discoverBlocks: 0x{:08X} block terminator at 0x{:08X}", entryPoint, addr); + block.size = addr - blockStart + 4; + break; + } + + addr += 4; + } + + // Log why loop exited if not due to terminator + if (block.size == 0 && !isWithinFunction(addr)) { + REXCODEGEN_TRACE("discoverBlocks: 0x{:08X} addr 0x{:08X} outside function (funcEnd=0x{:08X})", + entryPoint, addr, funcEnd); + } + + // Finalize block size if not set + if (block.size == 0) { + block.size = addr - blockStart; + } + + if (block.size > 0) { + result.blocks.push_back(block); + } + } + + // Sort blocks by address + std::sort(result.blocks.begin(), result.blocks.end(), + [](const Block& a, const Block& b) { return a.base < b.base; }); + + // Remove duplicate instructions (in case of overlapping scans) + std::sort(result.instructions.begin(), result.instructions.end(), + [](auto* a, auto* b) { return a->address < b->address; }); + result.instructions.erase(std::unique(result.instructions.begin(), result.instructions.end()), + result.instructions.end()); + + REXCODEGEN_TRACE("discoverBlocks: entry=0x{:08X} blocks={} instructions={} labels={}", entryPoint, + result.blocks.size(), result.instructions.size(), result.labels.size()); + + return result; +} + +} // namespace rex::codegen diff --git a/src/codegen/instruction_dispatch.cpp b/src/codegen/instruction_dispatch.cpp new file mode 100644 index 0000000..40ae269 --- /dev/null +++ b/src/codegen/instruction_dispatch.cpp @@ -0,0 +1,665 @@ +/** + * @file rexcodegen/instruction_dispatch.cpp + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "builders/builder_context.h" +#include "builders.h" + +#include + +#include + +#include "codegen_logging.h" + +#include +#include +#include + +namespace rex::codegen { + +using Builder = bool (*)(BuilderContext&); + +// Static dispatch table +static const std::unordered_map& GetDispatchTable() { + static const std::unordered_map table = { + //===================================================================== + // Arithmetic + //===================================================================== + {PPC_INST_ADD, build_add}, + {PPC_INST_ADDE, build_adde}, + {PPC_INST_ADDI, build_addi}, + {PPC_INST_ADDIC, build_addic}, + {PPC_INST_ADDIS, build_addis}, + {PPC_INST_ADDZE, build_addze}, + {PPC_INST_ADDME, build_addme}, + {PPC_INST_ADDC, build_addc}, + {PPC_INST_DIVD, build_divd}, + {PPC_INST_DIVDU, build_divdu}, + {PPC_INST_DIVW, build_divw}, + {PPC_INST_DIVWU, build_divwu}, + {PPC_INST_MULHW, build_mulhw}, + {PPC_INST_MULHWU, build_mulhwu}, + {PPC_INST_MULLD, build_mulld}, + {PPC_INST_MULLI, build_mulli}, + {PPC_INST_MULLW, build_mullw}, + {PPC_INST_NEG, build_neg}, + {PPC_INST_SUBF, build_subf}, + {PPC_INST_SUBFC, build_subfc}, + {PPC_INST_SUBFE, build_subfe}, + {PPC_INST_SUBFIC, build_subfic}, + {PPC_INST_SUBFZE, build_subfze}, + {PPC_INST_SUBFME, build_subfme}, + {PPC_INST_MULHD, build_mulhd}, + {PPC_INST_MULHDU, build_mulhdu}, + + //===================================================================== + // Logical + //===================================================================== + {PPC_INST_AND, build_and}, + {PPC_INST_ANDC, build_andc}, + {PPC_INST_ANDI, build_andi}, + {PPC_INST_ANDIS, build_andis}, + {PPC_INST_NAND, build_nand}, + {PPC_INST_NOR, build_nor}, + {PPC_INST_NOT, build_not}, + {PPC_INST_OR, build_or}, + {PPC_INST_ORC, build_orc}, + {PPC_INST_ORI, build_ori}, + {PPC_INST_ORIS, build_oris}, + {PPC_INST_XOR, build_xor}, + {PPC_INST_XORI, build_xori}, + {PPC_INST_XORIS, build_xoris}, + {PPC_INST_EQV, build_eqv}, + {PPC_INST_CNTLZD, build_cntlzd}, + {PPC_INST_CNTLZW, build_cntlzw}, + {PPC_INST_EXTSB, build_extsb}, + {PPC_INST_EXTSH, build_extsh}, + {PPC_INST_EXTSW, build_extsw}, + {PPC_INST_CLRLWI, build_clrlwi}, + {PPC_INST_RLDCL, build_rldcl}, + {PPC_INST_RLDCR, build_rldcr}, + {PPC_INST_RLDIC, build_rldic}, + {PPC_INST_RLDICL, build_rldicl}, + {PPC_INST_RLDICR, build_rldicr}, + {PPC_INST_RLDIMI, build_rldimi}, + {PPC_INST_ROTLDI, build_rotldi}, + {PPC_INST_RLWIMI, build_rlwimi}, + {PPC_INST_RLWINM, build_rlwinm}, + {PPC_INST_RLWNM, build_rlwnm}, + {PPC_INST_ROTLW, build_rotlw}, + {PPC_INST_ROTLWI, build_rotlwi}, + {PPC_INST_SLD, build_sld}, + {PPC_INST_SLW, build_slw}, + {PPC_INST_SRAD, build_srad}, + {PPC_INST_SRADI, build_sradi}, + {PPC_INST_SRAW, build_sraw}, + {PPC_INST_SRAWI, build_srawi}, + {PPC_INST_SRD, build_srd}, + {PPC_INST_SRW, build_srw}, + + //===================================================================== + // Conditional Register + //===================================================================== + {PPC_INST_CRAND, build_crand}, + {PPC_INST_CRANDC, build_crandc}, + {PPC_INST_CREQV, build_creqv}, + {PPC_INST_CRNAND, build_crnand}, + {PPC_INST_CRNOR, build_crnor}, + {PPC_INST_CROR, build_cror}, + {PPC_INST_CRORC, build_crorc}, + {PPC_INST_CRXOR, build_crxor}, + + //===================================================================== + // Comparison + //===================================================================== + {PPC_INST_CMPD, build_cmpd}, + {PPC_INST_CMPDI, build_cmpdi}, + {PPC_INST_CMPLD, build_cmpld}, + {PPC_INST_CMPLDI, build_cmpldi}, + {PPC_INST_CMPLW, build_cmplw}, + {PPC_INST_CMPLWI, build_cmplwi}, + {PPC_INST_CMPW, build_cmpw}, + {PPC_INST_CMPWI, build_cmpwi}, + + //===================================================================== + // Control Flow + //===================================================================== + {PPC_INST_B, build_b}, + {PPC_INST_BL, build_bl}, + {PPC_INST_BLR, build_blr}, + {PPC_INST_BLRL, build_blrl}, + {PPC_INST_BCTR, build_bctr}, + {PPC_INST_BCTRL, build_bctrl}, + {PPC_INST_BNECTR, build_bnectr}, + {PPC_INST_BDZ, build_bdz}, + {PPC_INST_BDZF, build_bdzf}, + {PPC_INST_BDZLR, build_bdzlr}, + {PPC_INST_BDNZ, build_bdnz}, + {PPC_INST_BDNZF, build_bdnzf}, + {PPC_INST_BDNZLR, build_bdnzlr}, + {PPC_INST_BDNZT, build_bdnzt}, + {PPC_INST_BEQ, build_beq}, + {PPC_INST_BEQLR, build_beqlr}, + {PPC_INST_BNE, build_bne}, + {PPC_INST_BNELR, build_bnelr}, + {PPC_INST_BLT, build_blt}, + {PPC_INST_BLTLR, build_bltlr}, + {PPC_INST_BGE, build_bge}, + {PPC_INST_BGELR, build_bgelr}, + {PPC_INST_BGT, build_bgt}, + {PPC_INST_BGTLR, build_bgtlr}, + {PPC_INST_BLE, build_ble}, + {PPC_INST_BLELR, build_blelr}, + {PPC_INST_BSO, build_bso}, + {PPC_INST_BSOLR, build_bsolr}, + {PPC_INST_BNS, build_bns}, + {PPC_INST_BNSLR, build_bnslr}, + + //===================================================================== + // Floating Point + //===================================================================== + {PPC_INST_FABS, build_fabs}, + {PPC_INST_FNABS, build_fnabs}, + {PPC_INST_FNEG, build_fneg}, + {PPC_INST_FMR, build_fmr}, + {PPC_INST_FCFID, build_fcfid}, + {PPC_INST_FCTID, build_fctid}, + {PPC_INST_FCTIDZ, build_fctidz}, + {PPC_INST_FCTIW, build_fctiw}, + {PPC_INST_FCTIWZ, build_fctiwz}, + {PPC_INST_FRSP, build_frsp}, + {PPC_INST_FCMPU, build_fcmpu}, + {PPC_INST_FCMPO, build_fcmpo}, + {PPC_INST_FADD, build_fadd}, + {PPC_INST_FADDS, build_fadds}, + {PPC_INST_FSUB, build_fsub}, + {PPC_INST_FSUBS, build_fsubs}, + {PPC_INST_FMUL, build_fmul}, + {PPC_INST_FMULS, build_fmuls}, + {PPC_INST_FDIV, build_fdiv}, + {PPC_INST_FDIVS, build_fdivs}, + {PPC_INST_FMADD, build_fmadd}, + {PPC_INST_FMADDS, build_fmadds}, + {PPC_INST_FMSUB, build_fmsub}, + {PPC_INST_FMSUBS, build_fmsubs}, + {PPC_INST_FNMADD, build_fnmadd}, + {PPC_INST_FNMADDS, build_fnmadds}, + {PPC_INST_FNMSUB, build_fnmsub}, + {PPC_INST_FNMSUBS, build_fnmsubs}, + {PPC_INST_FRES, build_fres}, + {PPC_INST_FRSQRTE, build_frsqrte}, + {PPC_INST_FSQRT, build_fsqrt}, + {PPC_INST_FSQRTS, build_fsqrts}, + {PPC_INST_FSEL, build_fsel}, + + //===================================================================== + // Memory - Load Immediate + //===================================================================== + {PPC_INST_LI, build_li}, + {PPC_INST_LIS, build_lis}, + + //===================================================================== + // Memory - Loads + //===================================================================== + {PPC_INST_LBZ, build_lbz}, + {PPC_INST_LBZU, build_lbzu}, + {PPC_INST_LBZX, build_lbzx}, + {PPC_INST_LBZUX, build_lbzux}, + {PPC_INST_LHA, build_lha}, + {PPC_INST_LHAU, build_lhau}, + {PPC_INST_LHAUX, build_lhaux}, + {PPC_INST_LHAX, build_lhax}, + {PPC_INST_LHBRX, build_lhbrx}, + {PPC_INST_LHZ, build_lhz}, + {PPC_INST_LHZU, build_lhzu}, + {PPC_INST_LHZUX, build_lhzux}, + {PPC_INST_LHZX, build_lhzx}, + {PPC_INST_LWA, build_lwa}, + {PPC_INST_LWAUX, build_lwaux}, + {PPC_INST_LWAX, build_lwax}, + {PPC_INST_LWZ, build_lwz}, + {PPC_INST_LWZU, build_lwzu}, + {PPC_INST_LWZUX, build_lwzux}, + {PPC_INST_LWZX, build_lwzx}, + {PPC_INST_LWBRX, build_lwbrx}, + {PPC_INST_LD, build_ld}, + {PPC_INST_LDU, build_ldu}, + {PPC_INST_LDX, build_ldx}, + {PPC_INST_LDUX, build_ldux}, + {PPC_INST_LWARX, build_lwarx}, + {PPC_INST_LDARX, build_ldarx}, + {PPC_INST_LFD, build_lfd}, + {PPC_INST_LFDU, build_lfdu}, + {PPC_INST_LFDUX, build_lfdux}, + {PPC_INST_LFDX, build_lfdx}, + {PPC_INST_LFS, build_lfs}, + {PPC_INST_LFSU, build_lfsu}, + {PPC_INST_LFSUX, build_lfsux}, + {PPC_INST_LFSX, build_lfsx}, + + //===================================================================== + // Memory - Stores + //===================================================================== + {PPC_INST_STB, build_stb}, + {PPC_INST_STBU, build_stbu}, + {PPC_INST_STBX, build_stbx}, + {PPC_INST_STBUX, build_stbux}, + {PPC_INST_STH, build_sth}, + {PPC_INST_STHBRX, build_sthbrx}, + {PPC_INST_STHU, build_sthu}, + {PPC_INST_STHUX, build_sthux}, + {PPC_INST_STHX, build_sthx}, + {PPC_INST_STW, build_stw}, + {PPC_INST_STWU, build_stwu}, + {PPC_INST_STWUX, build_stwux}, + {PPC_INST_STWX, build_stwx}, + {PPC_INST_STWBRX, build_stwbrx}, + {PPC_INST_STMW, build_stmw}, + {PPC_INST_STWCX, build_stwcx}, + {PPC_INST_STDCX, build_stdcx}, + {PPC_INST_STD, build_std}, + {PPC_INST_STDU, build_stdu}, + {PPC_INST_STDX, build_stdx}, + {PPC_INST_STDUX, build_stdux}, + {PPC_INST_STFD, build_stfd}, + {PPC_INST_STFDU, build_stfdu}, + {PPC_INST_STFDUX, build_stfdux}, + {PPC_INST_STFDX, build_stfdx}, + {PPC_INST_STFIWX, build_stfiwx}, + {PPC_INST_STFS, build_stfs}, + {PPC_INST_STFSU, build_stfsu}, + {PPC_INST_STFSUX, build_stfsux}, + {PPC_INST_STFSX, build_stfsx}, + + //===================================================================== + // Memory - Vector Loads + //===================================================================== + {PPC_INST_LVX, build_lvx}, + {PPC_INST_LVX128, build_lvx}, + {PPC_INST_LVXL, build_lvx}, + {PPC_INST_LVXL128, build_lvx}, + {PPC_INST_LVLX, build_lvlx}, + {PPC_INST_LVLX128, build_lvlx}, + {PPC_INST_LVRX, build_lvrx}, + {PPC_INST_LVRX128, build_lvrx}, + {PPC_INST_LVSL, build_lvsl}, + {PPC_INST_LVSR, build_lvsr}, + {PPC_INST_LVEBX, build_lvx}, + {PPC_INST_LVEHX, build_lvx}, + {PPC_INST_LVEWX, build_lvx}, + {PPC_INST_LVEWX128, build_lvx}, + + //===================================================================== + // Memory - Vector Stores + //===================================================================== + {PPC_INST_STVEBX, build_stvebx}, + {PPC_INST_STVEHX, build_stvehx}, + {PPC_INST_STVEWX, build_stvewx}, + {PPC_INST_STVEWX128, build_stvewx}, + {PPC_INST_STVLX, build_stvlx}, + {PPC_INST_STVLX128, build_stvlx}, + {PPC_INST_STVLXL128, build_stvlx}, + {PPC_INST_STVRX, build_stvrx}, + {PPC_INST_STVRX128, build_stvrx}, + {PPC_INST_STVX, build_stvx}, + {PPC_INST_STVX128, build_stvx}, + {PPC_INST_STVXL, build_stvx}, + + //===================================================================== + // System + //===================================================================== + {PPC_INST_NOP, build_nop}, + {PPC_INST_ATTN, build_attn}, + {PPC_INST_SYNC, build_sync}, + {PPC_INST_LWSYNC, build_lwsync}, + {PPC_INST_EIEIO, build_eieio}, + {PPC_INST_DB16CYC, build_db16cyc}, + {PPC_INST_CCTPL, build_cctpl}, + {PPC_INST_CCTPM, build_cctpm}, + {PPC_INST_CCTPH, build_cctph}, + // Trap word immediate (all variants map to generic TWI) + {PPC_INST_TWI, build_twi}, + {PPC_INST_TWLGTI, build_twi}, + {PPC_INST_TWLLTI, build_twi}, + {PPC_INST_TWEQI, build_twi}, + {PPC_INST_TWLGEI, build_twi}, + {PPC_INST_TWLNLI, build_twi}, + {PPC_INST_TWLLEI, build_twi}, + {PPC_INST_TWLNGI, build_twi}, + {PPC_INST_TWGTI, build_twi}, + {PPC_INST_TWGEI, build_twi}, + {PPC_INST_TWNLI, build_twi}, + {PPC_INST_TWLTI, build_twi}, + {PPC_INST_TWLEI, build_twi}, + {PPC_INST_TWNGI, build_twi}, + {PPC_INST_TWNEI, build_twi}, + // Trap doubleword immediate (all variants map to generic TDI) + {PPC_INST_TDI, build_tdi}, + {PPC_INST_TDLGTI, build_tdi}, + {PPC_INST_TDLLTI, build_tdi}, + {PPC_INST_TDEQI, build_tdi}, + {PPC_INST_TDLGEI, build_tdi}, + {PPC_INST_TDLNLI, build_tdi}, + {PPC_INST_TDLLEI, build_tdi}, + {PPC_INST_TDLNGI, build_tdi}, + {PPC_INST_TDGTI, build_tdi}, + {PPC_INST_TDGEI, build_tdi}, + {PPC_INST_TDNLI, build_tdi}, + {PPC_INST_TDLTI, build_tdi}, + {PPC_INST_TDLEI, build_tdi}, + {PPC_INST_TDNGI, build_tdi}, + {PPC_INST_TDNEI, build_tdi}, + // Trap word register (all variants map to generic TW) + {PPC_INST_TW, build_tw}, + {PPC_INST_TWGE, build_tw}, + {PPC_INST_TWGT, build_tw}, + {PPC_INST_TWLE, build_tw}, + {PPC_INST_TWLT, build_tw}, + {PPC_INST_TWEQ, build_tw}, + {PPC_INST_TWNE, build_tw}, + {PPC_INST_TWLGE, build_tw}, + {PPC_INST_TWLGT, build_tw}, + {PPC_INST_TWLLE, build_tw}, + {PPC_INST_TWLLT, build_tw}, + // Trap doubleword register (all variants map to generic TD) + {PPC_INST_TD, build_td}, + {PPC_INST_TDGE, build_td}, + {PPC_INST_TDGT, build_td}, + {PPC_INST_TDLE, build_td}, + {PPC_INST_TDLT, build_td}, + {PPC_INST_TDEQ, build_td}, + {PPC_INST_TDNE, build_td}, + {PPC_INST_TDLGE, build_td}, + {PPC_INST_TDLGT, build_td}, + {PPC_INST_TDLLE, build_td}, + {PPC_INST_TDLLT, build_td}, + {PPC_INST_DCBF, build_dcbf}, + {PPC_INST_DCBT, build_dcbt}, + {PPC_INST_DCBTST, build_dcbtst}, + {PPC_INST_DCBZ, build_dcbz}, + {PPC_INST_DCBZL, build_dcbzl}, + {PPC_INST_DCBST, build_dcbst}, + {PPC_INST_MR, build_mr}, + {PPC_INST_MCRF, build_mcrf}, + {PPC_INST_MFXER, build_mfxer}, + {PPC_INST_MFCTR, build_mfctr}, + {PPC_INST_MFCR, build_mfcr}, + {PPC_INST_MFOCRF, build_mfocrf}, + {PPC_INST_MFLR, build_mflr}, + {PPC_INST_MFMSR, build_mfmsr}, + {PPC_INST_MFFS, build_mffs}, + {PPC_INST_MFTB, build_mftb}, + {PPC_INST_MFTBU, build_mftbu}, + {PPC_INST_MTCR, build_mtcr}, + {PPC_INST_MTCRF, build_mtcrf}, + {PPC_INST_MTOCRF, build_mtcrf}, + {PPC_INST_MTCTR, build_mtctr}, + {PPC_INST_MTLR, build_mtlr}, + {PPC_INST_MTMSRD, build_mtmsrd}, + {PPC_INST_MTFSF, build_mtfsf}, + {PPC_INST_MTXER, build_mtxer}, + {PPC_INST_CLRLDI, build_clrldi}, + + //===================================================================== + // Vector - Floating Point Arithmetic + //===================================================================== + {PPC_INST_VADDFP, build_vaddfp}, + {PPC_INST_VADDFP128, build_vaddfp}, + {PPC_INST_VSUBFP, build_vsubfp}, + {PPC_INST_VSUBFP128, build_vsubfp}, + {PPC_INST_VMULFP128, build_vmulfp128}, + {PPC_INST_VMADDFP, build_vmaddfp}, + {PPC_INST_VMADDFP128, build_vmaddfp}, + {PPC_INST_VMADDCFP128, build_vmaddfp}, // Same as VMADDFP + {PPC_INST_VNMSUBFP, build_vnmsubfp}, + {PPC_INST_VNMSUBFP128, build_vnmsubfp}, + {PPC_INST_VMAXFP, build_vmaxfp}, + {PPC_INST_VMAXFP128, build_vmaxfp}, + {PPC_INST_VMINFP, build_vminfp}, + {PPC_INST_VMINFP128, build_vminfp}, + {PPC_INST_VREFP, build_vrefp}, + {PPC_INST_VREFP128, build_vrefp}, + {PPC_INST_VRSQRTEFP, build_vrsqrtefp}, + {PPC_INST_VRSQRTEFP128, build_vrsqrtefp}, + {PPC_INST_VEXPTEFP, build_vexptefp}, + {PPC_INST_VEXPTEFP128, build_vexptefp}, + {PPC_INST_VLOGEFP, build_vlogefp}, + {PPC_INST_VLOGEFP128, build_vlogefp}, + + //===================================================================== + // Vector - Dot Products + //===================================================================== + {PPC_INST_VMSUM3FP128, build_vmsum3fp128}, + {PPC_INST_VMSUM4FP128, build_vmsum4fp128}, + + //===================================================================== + // Vector - Rounding + //===================================================================== + {PPC_INST_VRFIM, build_vrfim}, + {PPC_INST_VRFIM128, build_vrfim}, + {PPC_INST_VRFIN, build_vrfin}, + {PPC_INST_VRFIN128, build_vrfin}, + {PPC_INST_VRFIP, build_vrfip}, + {PPC_INST_VRFIP128, build_vrfip}, + {PPC_INST_VRFIZ, build_vrfiz}, + {PPC_INST_VRFIZ128, build_vrfiz}, + + //===================================================================== + // Vector - Integer Arithmetic + //===================================================================== + {PPC_INST_VADDSBS, build_vaddsbs}, + {PPC_INST_VADDSHS, build_vaddshs}, + {PPC_INST_VADDSWS, build_vaddsws}, + {PPC_INST_VADDUBM, build_vaddubm}, + {PPC_INST_VADDUBS, build_vaddubs}, + {PPC_INST_VADDUHM, build_vadduhm}, + {PPC_INST_VADDUWM, build_vadduwm}, + {PPC_INST_VADDUWS, build_vadduws}, + {PPC_INST_VADDUHS, build_vadduhs}, + {PPC_INST_VSUBSBS, build_vsubsbs}, + {PPC_INST_VSUBSWS, build_vsubsws}, + {PPC_INST_VSUBUBM, build_vsububm}, + {PPC_INST_VSUBUBS, build_vsububs}, + {PPC_INST_VSUBUHS, build_vsubuhs}, + {PPC_INST_VSUBUWS, build_vsubuws}, + {PPC_INST_VSUBUHM, build_vsubuhm}, + {PPC_INST_VSUBUWM, build_vsubuwm}, + {PPC_INST_VSUBSHS, build_vsubshs}, + {PPC_INST_VMAXSW, build_vmaxsw}, + {PPC_INST_VMAXSH, build_vmaxsh}, + {PPC_INST_VMAXSB, build_vmaxsb}, + {PPC_INST_VMINSH, build_vminsh}, + {PPC_INST_VMINSB, build_vminsb}, + {PPC_INST_VMINSW, build_vminsw}, + {PPC_INST_VMAXUH, build_vmaxuh}, + {PPC_INST_VMINUH, build_vminuh}, + {PPC_INST_VMAXUB, build_vmaxub}, + {PPC_INST_VMINUB, build_vminub}, + {PPC_INST_VMINUW, build_vminuw}, + + //===================================================================== + // Vector - Average + //===================================================================== + {PPC_INST_VAVGSB, build_vavgsb}, + {PPC_INST_VAVGSH, build_vavgsh}, + {PPC_INST_VAVGSW, build_vavgsw}, + {PPC_INST_VAVGUB, build_vavgub}, + {PPC_INST_VAVGUH, build_vavguh}, + + //===================================================================== + // Vector - Logical + //===================================================================== + {PPC_INST_VAND, build_vand}, + {PPC_INST_VAND128, build_vand}, + {PPC_INST_VANDC, build_vandc}, + {PPC_INST_VANDC128, build_vandc128}, + {PPC_INST_VOR, build_vor}, + {PPC_INST_VOR128, build_vor}, + {PPC_INST_VXOR, build_vxor}, + {PPC_INST_VXOR128, build_vxor}, + {PPC_INST_VNOR, build_vnor}, + {PPC_INST_VNOR128, build_vnor}, + {PPC_INST_VSEL, build_vsel}, + {PPC_INST_VSEL128, build_vsel}, + + //===================================================================== + // Vector - Compare + //===================================================================== + {PPC_INST_VCMPBFP, build_vcmpbfp}, + {PPC_INST_VCMPBFP128, build_vcmpbfp}, + {PPC_INST_VCMPEQFP, build_vcmpeqfp}, + {PPC_INST_VCMPEQFP128, build_vcmpeqfp}, + {PPC_INST_VCMPEQUB, build_vcmpequb}, + {PPC_INST_VCMPEQUH, build_vcmpequh}, + {PPC_INST_VCMPEQUW, build_vcmpequw}, + {PPC_INST_VCMPEQUW128, build_vcmpequw}, + {PPC_INST_VCMPGEFP, build_vcmpgefp}, + {PPC_INST_VCMPGEFP128, build_vcmpgefp}, + {PPC_INST_VCMPGTFP, build_vcmpgtfp}, + {PPC_INST_VCMPGTFP128, build_vcmpgtfp}, + {PPC_INST_VCMPGTUB, build_vcmpgtub}, + {PPC_INST_VCMPGTUH, build_vcmpgtuh}, + {PPC_INST_VCMPGTUW, build_vcmpgtuw}, + {PPC_INST_VCMPGTSB, build_vcmpgtsb}, + {PPC_INST_VCMPGTSH, build_vcmpgtsh}, + {PPC_INST_VCMPGTSW, build_vcmpgtsw}, + + //===================================================================== + // Vector - Conversion + //===================================================================== + {PPC_INST_VCTSXS, build_vctsxs}, + {PPC_INST_VCFPSXWS128, build_vctsxs}, // Alias + {PPC_INST_VCTUXS, build_vctuxs}, + {PPC_INST_VCFPUXWS128, build_vctuxs}, // Alias + {PPC_INST_VCFSX, build_vcfsx}, + {PPC_INST_VCSXWFP128, build_vcfsx}, // Alias + {PPC_INST_VCFUX, build_vcfux}, + {PPC_INST_VCUXWFP128, build_vcfux}, // Alias + + //===================================================================== + // Vector - Merge + //===================================================================== + {PPC_INST_VMRGHB, build_vmrghb}, + {PPC_INST_VMRGHH, build_vmrghh}, + {PPC_INST_VMRGHW, build_vmrghw}, + {PPC_INST_VMRGHW128, build_vmrghw}, + {PPC_INST_VMRGLB, build_vmrglb}, + {PPC_INST_VMRGLH, build_vmrglh}, + {PPC_INST_VMRGLW, build_vmrglw}, + {PPC_INST_VMRGLW128, build_vmrglw}, + + //===================================================================== + // Vector - Permute + //===================================================================== + {PPC_INST_VPERM, build_vperm}, + {PPC_INST_VPERM128, build_vperm}, + {PPC_INST_VPERMWI128, build_vpermwi128}, + {PPC_INST_VRLIMI128, build_vrlimi128}, + + //===================================================================== + // Vector - Shift + //===================================================================== + {PPC_INST_VSL, build_vsl}, + {PPC_INST_VSLB, build_vslb}, + {PPC_INST_VSLH, build_vslh}, + {PPC_INST_VSLDOI, build_vsldoi}, + {PPC_INST_VSLDOI128, build_vsldoi}, + {PPC_INST_VSLW, build_vslw}, + {PPC_INST_VSLW128, build_vslw}, + {PPC_INST_VSLO, build_vslo}, + {PPC_INST_VSLO128, build_vslo}, + {PPC_INST_VSR, build_vsr}, + {PPC_INST_VSRH, build_vsrh}, + {PPC_INST_VSRB, build_vsrb}, + {PPC_INST_VSRAB, build_vsrab}, + {PPC_INST_VSRAH, build_vsrah}, + {PPC_INST_VSRAW, build_vsraw}, + {PPC_INST_VSRAW128, build_vsraw}, + {PPC_INST_VSRW, build_vsrw}, + {PPC_INST_VSRW128, build_vsrw}, + {PPC_INST_VSRO, build_vsro}, + {PPC_INST_VSRO128, build_vsro}, + {PPC_INST_VRLH, build_vrlh}, + {PPC_INST_VRLW, build_vrlw}, + {PPC_INST_VRLW128, build_vrlw}, + + //===================================================================== + // Vector - Splat + //===================================================================== + {PPC_INST_VSPLTB, build_vspltb}, + {PPC_INST_VSPLTH, build_vsplth}, + {PPC_INST_VSPLTISB, build_vspltisb}, + {PPC_INST_VSPLTISH, build_vspltish}, + {PPC_INST_VSPLTISW, build_vspltisw}, + {PPC_INST_VSPLTISW128, build_vspltisw}, + {PPC_INST_VSPLTW, build_vspltw}, + {PPC_INST_VSPLTW128, build_vspltw}, + + //===================================================================== + // Vector - Pack + //===================================================================== + {PPC_INST_VPKUHUM, build_vpkuhum}, + {PPC_INST_VPKUHUM128, build_vpkuhum}, + {PPC_INST_VPKUHUS, build_vpkuhus}, + {PPC_INST_VPKUHUS128, build_vpkuhus}, + {PPC_INST_VPKUWUM, build_vpkuwum}, + {PPC_INST_VPKUWUM128, build_vpkuwum}, + {PPC_INST_VPKUWUS, build_vpkuwus}, + {PPC_INST_VPKUWUS128, build_vpkuwus}, + {PPC_INST_VPKSHSS, build_vpkshss}, + {PPC_INST_VPKSHSS128, build_vpkshss}, + {PPC_INST_VPKSHUS, build_vpkshus}, + {PPC_INST_VPKSHUS128, build_vpkshus}, + {PPC_INST_VPKSWSS, build_vpkswss}, + {PPC_INST_VPKSWSS128, build_vpkswss}, + {PPC_INST_VPKSWUS, build_vpkswus}, + {PPC_INST_VPKSWUS128, build_vpkswus}, + {PPC_INST_VPKD3D128, build_vpkd3d128}, + + //===================================================================== + // Vector - Unpack + //===================================================================== + {PPC_INST_VUPKD3D128, build_vupkd3d128}, + {PPC_INST_VUPKHSB, build_vupkhsb}, + {PPC_INST_VUPKHSB128, build_vupkhsb}, + {PPC_INST_VUPKHSH, build_vupkhsh}, + {PPC_INST_VUPKHSH128, build_vupkhsh}, + {PPC_INST_VUPKLSB, build_vupklsb}, + {PPC_INST_VUPKLSB128, build_vupklsb}, + {PPC_INST_VUPKLSH, build_vupklsh}, + {PPC_INST_VUPKLSH128, build_vupklsh}, + }; + return table; +} + +bool DispatchInstruction(int id, BuilderContext& ctx) { + // VUPKHSB128/VUPKLSB128 misidentification fixup (moved from recompiler.cpp). + // Only fires when operands[2]==0x60; table entries for *128 variants + // still serve the non-0x60 case. + if (id == PPC_INST_VUPKHSB128 && ctx.insn.operands[2] == 0x60) { + id = PPC_INST_VUPKHSH128; + } else if (id == PPC_INST_VUPKLSB128 && ctx.insn.operands[2] == 0x60) { + id = PPC_INST_VUPKLSH128; + } + + const auto& table = GetDispatchTable(); + auto it = table.find(id); + if (it != table.end()) { + return it->second(ctx); + } + + // Emit trap code for unimplemented instruction - allows tests to be generated + // and fail at runtime rather than skipping the entire function + REXCODEGEN_WARN("Unimplemented: {} at 0x{:08X}", ctx.insn.opcode->name, ctx.base); + ctx.println("\t// UNIMPLEMENTED: {}", ctx.insn.opcode->name); + ctx.println("\tREX_UNIMPLEMENTED(0x{:X}, \"{}\");", ctx.base, ctx.insn.opcode->name); + return true; +} + +} // namespace rex::codegen diff --git a/src/codegen/manifest.cpp b/src/codegen/manifest.cpp new file mode 100644 index 0000000..8aca4d6 --- /dev/null +++ b/src/codegen/manifest.cpp @@ -0,0 +1,268 @@ +/** + * @file codegen/manifest.cpp + * @brief Manifest TOML parser for multi-binary projects + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +namespace rex::codegen { + +std::string CanonicalizeModuleGuestPath(std::string_view path, std::string_view project_name) { + std::string guest_path = rex::system::NormalizeGuestPath(path); + + if (!project_name.empty()) { + std::string lower_project(project_name); + std::transform(lower_project.begin(), lower_project.end(), lower_project.begin(), + [](unsigned char c) { return static_cast(std::tolower(c)); }); + const std::string project_assets_prefix = lower_project + "/assets/"; + if (guest_path.rfind(project_assets_prefix, 0) == 0) { + guest_path.erase(0, project_assets_prefix.size()); + } + } + + return guest_path; +} + +namespace { + +bool IsValidProjectName(std::string_view name) { + if (name.empty()) + return false; + if (!(std::isalpha(static_cast(name[0])) || name[0] == '_')) { + return false; + } + return std::all_of(name.begin(), name.end(), + [](unsigned char c) { return std::isalnum(c) || c == '_'; }); +} + +/** + * Pull file_path / out_directory_path / project_name onto the recompiler + * config so downstream consumers can rely on them. Other fields (codegen + * flags, sub-tables, includes) come from RecompilerConfig::LoadFromTable. + */ +bool LoadBinaryConfig(const toml::table& tbl, const std::filesystem::path& base_dir, + std::string_view project_name, BinaryConfig& out) { + out.recompiler = RecompilerConfig{}; + out.recompiler.projectName = std::string(project_name); + if (!out.recompiler.LoadFromTable(tbl, base_dir)) { + return false; + } + return true; +} + +} // namespace + +std::optional ManifestConfig::Load(const std::filesystem::path& path) { + toml::table tbl; + try { + tbl = toml::parse_file(path.string()); + } catch (const toml::parse_error& err) { + REXLOG_ERROR("Failed to parse manifest {}: {}", path.string(), err.what()); + return std::nullopt; + } + + ManifestConfig manifest; + manifest.manifestDir = path.parent_path(); + + auto* project = tbl["project"].as_table(); + if (!project) { + REXLOG_ERROR("Manifest missing [project] section: {}", path.string()); + return std::nullopt; + } + manifest.projectName = (*project)["name"].value_or(""); + if (manifest.projectName.empty()) { + REXLOG_ERROR("Manifest missing [project].name: {}", path.string()); + return std::nullopt; + } + if (!IsValidProjectName(manifest.projectName)) { + REXLOG_ERROR( + "Manifest [project].name '{}' is not a valid identifier " + "(letters, digits, underscore; must not start with a digit): {}", + manifest.projectName, path.string()); + return std::nullopt; + } + if (auto stamp = (*project)["sdk_version"].value(); stamp && !stamp->empty()) { + manifest.sdkVersion = *stamp; + } + if (auto root = (*project)["game_root"].value(); root && !root->empty()) { + manifest.gameRoot = *root; + } + + auto* entrypoint = tbl["entrypoint"].as_table(); + if (!entrypoint) { + REXLOG_ERROR("Manifest missing [entrypoint] section: {}", path.string()); + return std::nullopt; + } + if (!LoadBinaryConfig(*entrypoint, manifest.manifestDir, manifest.projectName, + manifest.entrypoint)) { + return std::nullopt; + } + + if (auto modules = tbl["modules"].as_array()) { + size_t index = 0; + for (const auto& mod : *modules) { + auto* modTbl = mod.as_table(); + if (!modTbl) { + REXLOG_ERROR("Manifest [[modules]] entry #{} is not a table", index); + return std::nullopt; + } + BinaryConfig binary; + if (!LoadBinaryConfig(*modTbl, manifest.manifestDir, manifest.projectName, binary)) { + return std::nullopt; + } + auto guest_path = (*modTbl)["guest_path"].value_or(""); + if (guest_path.empty()) { + REXLOG_ERROR("Manifest [[modules]] entry #{} missing guest_path", index); + return std::nullopt; + } + binary.guestPath = CanonicalizeModuleGuestPath(guest_path, manifest.projectName); + for (const auto& existing : manifest.modules) { + if (existing.guestPath == binary.guestPath) { + REXLOG_ERROR("Manifest [[modules]] duplicate guest_path '{}' (entry #{})", + binary.guestPath, index); + return std::nullopt; + } + } + manifest.modules.push_back(std::move(binary)); + ++index; + } + } + + return manifest; +} + +bool ManifestConfig::IsManifest(const std::filesystem::path& path) { + try { + auto tbl = toml::parse_file(path.string()); + return tbl.contains("project"); + } catch (const toml::parse_error&) { + return false; + } +} + +namespace { + +std::optional ParseSectionHeader(std::string_view line) { + auto first = line.find_first_not_of(" \t"); + if (first == std::string_view::npos) + return std::nullopt; + if (line[first] != '[' || (first + 1 < line.size() && line[first + 1] == '[')) + return std::nullopt; + auto end = line.find(']', first + 1); + if (end == std::string_view::npos) + return std::nullopt; + return std::string(line.substr(first + 1, end - first - 1)); +} + +bool LineSetsKey(std::string_view line, std::string_view key) { + auto first = line.find_first_not_of(" \t"); + if (first == std::string_view::npos) + return false; + if (line.compare(first, key.size(), key) != 0) + return false; + auto after = first + key.size(); + while (after < line.size() && (line[after] == ' ' || line[after] == '\t')) + ++after; + return after < line.size() && line[after] == '='; +} + +} // namespace + +bool ManifestConfig::WriteSdkVersionStamp(const std::filesystem::path& path, + std::string_view version) { + std::ifstream in(path); + if (!in) { + REXLOG_ERROR("Failed to open manifest for stamping: {}", path.string()); + return false; + } + std::vector lines; + std::string buf; + while (std::getline(in, buf)) { + lines.push_back(std::move(buf)); + buf.clear(); + } + in.close(); + + const std::string stamp_line = "sdk_version = \"" + std::string(version) + "\""; + + std::optional project_header_idx; + std::optional stamp_idx; + bool in_project = false; + for (size_t i = 0; i < lines.size(); ++i) { + auto sec = ParseSectionHeader(lines[i]); + if (sec) { + in_project = (*sec == "project"); + if (in_project) { + project_header_idx = i; + stamp_idx.reset(); + } + continue; + } + if (in_project && !stamp_idx && LineSetsKey(lines[i], "sdk_version")) { + stamp_idx = i; + } + } + + if (stamp_idx) { + lines[*stamp_idx] = stamp_line; + } else if (project_header_idx) { + lines.insert(lines.begin() + *project_header_idx + 1, stamp_line); + } else { + if (!lines.empty() && !lines.back().empty()) + lines.emplace_back(); + lines.emplace_back("[project]"); + lines.push_back(stamp_line); + } + + auto tmp_path = path; + tmp_path += ".tmp"; + { + std::ofstream out(tmp_path, std::ios::binary); + if (!out) { + REXLOG_ERROR("Failed to open manifest tmp for writing: {}", tmp_path.string()); + return false; + } + for (size_t i = 0; i < lines.size(); ++i) { + out << lines[i]; + if (i + 1 < lines.size()) + out << '\n'; + } + out << '\n'; + if (!out.good()) { + REXLOG_ERROR("Failed while writing manifest tmp: {}", tmp_path.string()); + std::error_code ignore; + std::filesystem::remove(tmp_path, ignore); + return false; + } + } + + std::error_code ec; + std::filesystem::rename(tmp_path, path, ec); + if (ec) { + REXLOG_ERROR("Failed to rename manifest tmp into place: {}", ec.message()); + std::error_code ignore; + std::filesystem::remove(tmp_path, ignore); + return false; + } + return true; +} + +} // namespace rex::codegen diff --git a/src/codegen/phase_discover.cpp b/src/codegen/phase_discover.cpp new file mode 100644 index 0000000..cfae8b8 --- /dev/null +++ b/src/codegen/phase_discover.cpp @@ -0,0 +1,431 @@ +/** + * @file codegen/phase_discover.cpp + * @brief Discover phase: iterative function block discovery + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "codegen_flags.h" +#include "decoded_binary.h" +#include + +#include +#include +#include + +#include +#include "phase_helpers.h" + +#include +#include + +#include "codegen_logging.h" +#include + +#include + +using rex::codegen::ppc::Opcode; +using rex::memory::load_and_swap; + +namespace rex::codegen { + +namespace { + +//============================================================================= +// Discover Phase: iterative function block discovery +//============================================================================= + +void discoverFunction(CodegenContext& ctx, uint32_t funcAddr, + const std::unordered_set& knownFunctions) { + auto& graph = ctx.graph; + auto& binary = ctx.binary(); + auto& decoded = ctx.decoded(); + + auto* node = graph.getFunction(funcAddr); + if (!node) + return; + + // Skip if already discovered + if (!node->canDiscover()) { + REXCODEGEN_TRACE("Analyze: function 0x{:08X} already discovered, skipping", funcAddr); + return; + } + + // Imports don't need block discovery + if (node->isImport()) { + node->discoverAsImport(); + return; + } + + REXCODEGEN_TRACE("Analyze: discovering function 0x{:08X} ({})", funcAddr, node->name()); + + // Lookup pdataSize for exception handler boundary + uint32_t pdataSize = 0; + + // For CONFIG functions: use only the explicitly declared size (if any) + // If no size specified (size=0), let discovery find natural boundaries via region + // Don't inherit PDATA sizes for CONFIG functions - they're user hints for entry points + if (node->authority() == FunctionAuthority::CONFIG) { + pdataSize = node->size(); // 0 if not specified, which is correct + REXCODEGEN_TRACE("Analyze: 0x{:08X} is CONFIG, using declared size={}", funcAddr, pdataSize); + } else { + // For non-CONFIG functions, use PDATA size if available + auto pdataIt = ctx.scan.pdataSizes.find(funcAddr); + if (pdataIt != ctx.scan.pdataSizes.end()) { + pdataSize = pdataIt->second; + REXCODEGEN_TRACE("Analyze: 0x{:08X} using PDATA size={}", funcAddr, pdataSize); + } + } + + // Find the code region containing this function + const CodeRegion* region = nullptr; + for (const auto& r : ctx.scan.codeRegions) { + if (r.contains(funcAddr)) { + region = &r; + break; + } + } + if (!region) { + REXCODEGEN_WARN("Analyze: function 0x{:08X} not in any code region", funcAddr); + return; + } + + // Pass pdataSize so forward branches within function extent are correctly identified + auto result = discoverBlocks(decoded, funcAddr, *region, knownFunctions, pdataSize); + + if (result.blocks.empty()) { + REXCODEGEN_WARN("Analyze: no blocks found for function 0x{:08X}", funcAddr); + return; + } + + // snooper the function with the discovered blocks and instructions + node->discover(std::move(result.blocks), std::move(result.instructions), + std::move(result.labels)); + + // Add jump tables (targets become labels in the function) + for (const auto& jt : result.jumpTables) { + graph.addJumpTableToFunction(funcAddr, jt); + } + + // Register external call targets as new functions (bl only, not b) + for (uint32_t target : result.externalCalls) { + if (!graph.isEntryPoint(target) && !graph.isImport(target)) { + if (binary.isInImportExportRange(target)) { + continue; + } + graph.addFunction(target, 4, FunctionAuthority::DISCOVERED, true); + } + } + + // Add unresolved branches for later resolution + for (const auto& branch : result.unresolvedBranches) { + graph.addUnresolvedJumpToFunction(funcAddr, branch.site, branch.target, branch.isCall, + branch.isConditional); + } + + // Scan exception handler regions for branches not in discovered blocks + if (pdataSize > 0) { + std::unordered_set discoveredAddrs; + for (const auto& block : result.blocks) { + for (uint32_t addr = block.base; addr < block.base + block.size; addr += 4) { + discoveredAddrs.insert(addr); + } + } + + uint32_t pdataEnd = funcAddr + pdataSize; + const uint8_t* funcData = binary.translate(funcAddr); + if (funcData) { + for (uint32_t offset = 0; offset < pdataSize; offset += 4) { + uint32_t site = funcAddr + offset; + + // Skip if already discovered by normal control flow + if (discoveredAddrs.count(site)) + continue; + + // Skip if marked invalid + auto invalidIt = ctx.analysisState().invalidInstructions.find(site); + if (invalidIt != ctx.analysisState().invalidInstructions.end()) { + continue; + } + + uint32_t insn = load_and_swap(funcData + offset); + uint32_t opcode = PPC_OP(insn); + + if (opcode != PPC_OP_B && opcode != PPC_OP_BC) + continue; + + uint32_t target = 0; + bool isCall = PPC_BL(insn); + bool isAbsolute = PPC_BA(insn); + + if (opcode == PPC_OP_B) { + int32_t branchOffset = PPC_BI(insn); + target = isAbsolute ? static_cast(branchOffset) : site + branchOffset; + } else { + int32_t branchOffset = PPC_BD(insn); + target = isAbsolute ? static_cast(branchOffset) : site + branchOffset; + } + + // Skip internal jumps within pdata region + if (!isCall && target >= funcAddr && target < pdataEnd) { + continue; + } + + graph.addUnresolvedJumpToFunction(funcAddr, site, target, isCall, false); + + // Register call targets as new functions + if (isCall && !graph.isEntryPoint(target) && !graph.isImport(target)) { + if (binary.isInImportExportRange(target)) { + continue; + } + graph.addFunction(target, 4, FunctionAuthority::DISCOVERED, true); + } + } + } + } +} + +void discoverAllFunctions(CodegenContext& ctx) { + REXCODEGEN_TRACE("Analyze: starting iterative discovery..."); + + auto& graph = ctx.graph; + auto& binary = ctx.binary(); + + // Iterative discovery + size_t iteration = 0; + size_t lastFunctionCount = 0; + const size_t maxIterations = REXCVAR_GET(max_discovery_iterations); + + while (iteration < maxIterations) { + iteration++; + + size_t currentFunctionCount = graph.functionCount(); + if (currentFunctionCount == lastFunctionCount && iteration > 1) { + REXCODEGEN_DEBUG("Analyze: fixed point at iteration {} ({} functions)", iteration, + currentFunctionCount); + break; + } + + lastFunctionCount = currentFunctionCount; + + auto knownFunctions = buildKnownFunctions(graph); + if (discoverPendingFunctions(ctx, knownFunctions) == 0) { + break; + } + } + + REXCODEGEN_TRACE("Analyze: {} functions after call graph expansion", graph.functionCount()); + + // VTable scanning + { + VTableScanner vtScanner(binary); + auto vtables = vtScanner.scan(); + + size_t newFunctions = 0; + + for (const auto& vt : vtables) { + for (size_t i = 0; i < vt.slots.size(); i++) { + uint32_t funcAddr = vt.slots[i]; + + if (graph.isEntryPoint(funcAddr)) + continue; + if (binary.isInImportExportRange(funcAddr)) + continue; + + graph.addFunction(funcAddr, 4, FunctionAuthority::VTABLE, true); + newFunctions++; + } + } + + REXCODEGEN_TRACE("Analyze: VTable scan found {} vtables, {} new functions", vtables.size(), + newFunctions); + + // Continue discovery for vtable functions + if (newFunctions > 0) { + size_t vtableIteration = 0; + const size_t maxVtableIterations = REXCVAR_GET(max_vtable_iterations); + + while (vtableIteration < maxVtableIterations) { + vtableIteration++; + + auto knownFunctions = buildKnownFunctions(graph); + if (discoverPendingFunctions(ctx, knownFunctions) == 0) + break; + + if (graph.functionCount() == lastFunctionCount) + break; + lastFunctionCount = graph.functionCount(); + } + } + } + + REXCODEGEN_TRACE("Analyze: {} total functions after vtable scan", graph.functionCount()); +} + +//============================================================================= +// Function Pointer Scan: find lis/addi pairs loading code addresses +// TODO(tomc): THIS IS WIP AND PROB A BAD IDEA LOL LETS SEE +//============================================================================= +void functionPointerScan(CodegenContext& ctx) { + if (!ctx.hasDecoded()) { + REXCODEGEN_WARN("functionPointerScan: DecodedBinary not initialized, skipping"); + return; + } + + auto& graph = ctx.graph; + auto& decoded = ctx.decoded(); + const auto& codeRegions = decoded.codeRegions(); + + if (codeRegions.empty()) { + REXCODEGEN_WARN("functionPointerScan: no code regions, skipping"); + return; + } + + // Build set of existing functions to avoid duplicates + std::unordered_set existingFunctions; + for (const auto& [addr, node] : graph.functions()) { + existingFunctions.insert(addr); + } + + // Track lis values: register -> (high_value, lis_address) + // We scan linearly and track the most recent lis for each register + // PPC has exactly 32 GPRs, so a fixed-size array is more efficient than a map + std::array, 32> lisValues{}; + std::bitset<32> lisValid; + + size_t foundCount = 0; + + for (const auto& region : codeRegions) { + lisValid.reset(); // Reset tracking at region boundaries + + for (uint32_t addr = region.start; addr < region.end; addr += 4) { + auto* insn = decoded.get(addr); + if (!insn) + continue; + + // Track lis rD, IMM + if (isLis(*insn)) { + uint8_t rd = static_cast(insn->D.RT); + uint32_t hi = static_cast(static_cast(insn->D.d)) << 16; + lisValues[rd] = {hi, addr}; + lisValid.set(rd); + continue; + } + + // Check for addi rD, rA, IMM where rA was set by lis + if (insn->opcode == rex::codegen::ppc::Opcode::addi) { + uint8_t ra = static_cast(insn->D.RA); + if (ra == 0) + continue; // li pseudo-op, not addi + + if (!lisValid.test(ra)) + continue; + + uint32_t hi = lisValues[ra].first; + int16_t lo = static_cast(insn->D.d); + uint32_t fullAddr = hi + lo; // Sign-extended add + + // PPC instructions are 4-byte aligned + if (fullAddr & 0x3) + continue; + + // Check if this address is in a code region + const CodeRegion* targetRegion = decoded.regionContaining(fullAddr); + if (!targetRegion) + continue; + + // Skip if already a known function + if (existingFunctions.contains(fullAddr)) + continue; + + // Skip if it's an internal address (within same function's likely range) + // Heuristic: if target is very close to current address, probably internal label + int32_t distance = static_cast(fullAddr) - static_cast(addr); + if (distance > -0x1000 && distance < 0x1000) { + // Could be local label, skip for now + continue; + } + + // Register as function with DISCOVERED authority and hasXrefs=true + graph.addFunction(fullAddr, 4, FunctionAuthority::DISCOVERED, true); + existingFunctions.insert(fullAddr); + foundCount++; + + REXCODEGEN_TRACE("functionPointerScan: found 0x{:08X} via lis/addi at 0x{:08X}", fullAddr, + addr); + } + + // Also check ori rD, rA, IMM (alternative to addi for unsigned) + if (insn->opcode == rex::codegen::ppc::Opcode::ori) { + uint8_t ra = static_cast(insn->D.RA); + if (!lisValid.test(ra)) + continue; + + uint32_t hi = lisValues[ra].first; + uint16_t lo = static_cast(insn->D.d); + uint32_t fullAddr = hi | lo; // Unsigned OR + + // PPC instructions are 4-byte aligned + if (fullAddr & 0x3) + continue; + + const CodeRegion* targetRegion = decoded.regionContaining(fullAddr); + if (!targetRegion) + continue; + + if (existingFunctions.contains(fullAddr)) + continue; + + int32_t distance = static_cast(fullAddr) - static_cast(addr); + if (distance > -0x1000 && distance < 0x1000) + continue; + + graph.addFunction(fullAddr, 4, FunctionAuthority::DISCOVERED, true); + existingFunctions.insert(fullAddr); + foundCount++; + + REXCODEGEN_TRACE("functionPointerScan: found 0x{:08X} via lis/ori at 0x{:08X}", fullAddr, + addr); + } + + // Clear lis tracking if register is overwritten by other instruction + // (Simplified: we clear on any write to the register) + // This is conservative - could miss some patterns but avoids false positives + } + } + + REXCODEGEN_TRACE("functionPointerScan: found {} new function pointer targets", foundCount); +} + +} // anonymous namespace + +/// Discover blocks for all pending functions (shared helper, declared in phase_helpers.h). +size_t discoverPendingFunctions(CodegenContext& ctx, + const std::unordered_set& knownFunctions) { + std::vector pending; + for (const auto& [addr, node] : ctx.graph.functions()) { + if (node->canDiscover()) { + pending.push_back(addr); + } + } + for (uint32_t funcAddr : pending) { + discoverFunction(ctx, funcAddr, knownFunctions); + } + return pending.size(); +} + +namespace phases { + +VoidResult Discover(CodegenContext& ctx, ProgressReporter* reporter) { + (void)reporter; + discoverAllFunctions(ctx); + return Ok(); +} + +} // namespace phases + +} // namespace rex::codegen diff --git a/src/codegen/phase_gapfill.cpp b/src/codegen/phase_gapfill.cpp new file mode 100644 index 0000000..f3da777 --- /dev/null +++ b/src/codegen/phase_gapfill.cpp @@ -0,0 +1,235 @@ +/** + * @file codegen/phase_gapfill.cpp + * @brief GapFill phase: find uncovered code regions and register them as functions + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "ppc/instruction.h" + +#include + +#include +#include "phase_helpers.h" + +#include + +#include "codegen_logging.h" +#include + +#include + +using rex::codegen::ppc::decode_instruction; +using rex::codegen::ppc::Opcode; +using rex::memory::load_and_swap; + +namespace rex::codegen { + +namespace { + +//============================================================================= +// GapFill to register uncovered code regions +//============================================================================= + +// Split a code region into function segments based on terminators (blr, tail calls). +std::vector splitRegionOnTerminators( + const CodeRegion& region, const BinaryView& binary, + const std::unordered_set& knownCallables) { + std::vector segments; + uint32_t segmentStart = region.start; + + for (uint32_t addr = region.start; addr < region.end; addr += 4) { + const uint8_t* data = binary.translate(addr); + if (!data) + break; + + uint32_t raw = load_and_swap(data); + auto decoded = decode_instruction(addr, raw); + bool shouldSplit = false; + const char* reason = nullptr; + + // Check for terminators + if (decoded.is_return()) { + shouldSplit = true; + reason = "blr"; + } else if (decoded.opcode == Opcode::b && decoded.branch_target.has_value()) { + uint32_t target = decoded.branch_target.value(); + // Don't split on tail recursion (branch to own segment start) + if (target != segmentStart && knownCallables.contains(target)) { + shouldSplit = true; + reason = "tail call"; + } + } + + if (shouldSplit) { + uint32_t segmentEnd = addr + 4; + if (segmentEnd > segmentStart) { + segments.push_back({segmentStart, segmentEnd}); + REXCODEGEN_TRACE("GapFill: split segment 0x{:08X}-0x{:08X} ({} at 0x{:08X})", segmentStart, + segmentEnd, reason, addr); + } + segmentStart = segmentEnd; + } + } + + // Handle remaining code after last terminator + if (segmentStart < region.end) { + segments.push_back({segmentStart, region.end}); + } + + return segments; +} + +// Check if address looks like exception handler data (handler ptr + rdata ptr) +bool looksLikeExceptionData(const BinaryView& binary, const FunctionGraph& graph, uint32_t addr) { + const uint8_t* data = binary.translate(addr); + if (!data) + return false; + + // Exception handler data pattern: + // [addr+0]: pointer to __C_specific_handler (entry point) + // [addr+4]: pointer to scope table in .rdata + uint32_t firstDword = load_and_swap(data); + uint32_t secondDword = load_and_swap(data + 4); + + // Check if first dword is a known entry point (like __C_specific_handler) + if (!graph.isEntryPoint(firstDword)) { + return false; + } + + // Check if second dword points to .rdata section + auto* rdataSection = binary.findSectionByName(".rdata"); + if (!rdataSection) + return false; + + uint32_t rdataStart = rdataSection->baseAddress; + uint32_t rdataEnd = rdataStart + rdataSection->size; + + if (secondDword >= rdataStart && secondDword < rdataEnd) { + REXCODEGEN_TRACE( + "GapFill: 0x{:08X} looks like exception data (handler=0x{:08X}, scope=0x{:08X}), skipping", + addr, firstDword, secondDword); + return true; + } + + return false; +} + +void gapFillCodeRegions(CodegenContext& ctx) { + REXCODEGEN_TRACE("Analyze: checking for uncovered code regions..."); + + auto& graph = ctx.graph; + auto& binary = ctx.binary(); + auto& scan = ctx.scan; + + // Build set of known callables for tail call detection + std::unordered_set knownCallables; + for (const auto& [addr, node] : graph.functions()) { + knownCallables.insert(addr); + } + + size_t gapsFound = 0; + size_t segmentsCreated = 0; + + for (const auto& region : scan.codeRegions) { + // Split region on terminators (blr, tail calls), then check each segment + auto segments = splitRegionOnTerminators(region, binary, knownCallables); + + for (const auto& segment : segments) { + // Skip if this segment's start is already a registered function entry + if (graph.isEntryPoint(segment.start)) + continue; + + // Skip if this segment's start is inside another function + if (auto* containingFunc = graph.getFunctionContaining(segment.start)) { + continue; + } + + // Skip if this looks like exception handler data (handler ptr + rdata ptr) + if (looksLikeExceptionData(binary, graph, segment.start)) + continue; + + uint32_t segmentSize = segment.size(); + graph.addFunction(segment.start, segmentSize, FunctionAuthority::GAP_FILL, false); + + REXCODEGEN_TRACE("GapFill: registered sub_{:08X} (0x{:08X}-0x{:08X}, {} bytes)", + segment.start, segment.start, segment.end, segmentSize); + segmentsCreated++; + } + + gapsFound++; + } + + if (segmentsCreated > 0) { + REXCODEGEN_TRACE("Analyze: registered {} gap functions from {} regions", segmentsCreated, + gapsFound); + } else { + REXCODEGEN_TRACE("Analyze: no uncovered regions found"); + } +} + +//============================================================================= +// Cleanup absorbed GAP_FILL functions +//============================================================================= + +void cleanupAbsorbedGapFills(CodegenContext& ctx) { + auto& graph = ctx.graph; + std::vector toRemove; + + for (const auto& [addr, node] : graph.functions()) { + if (node->authority() != FunctionAuthority::GAP_FILL) + continue; + + for (const auto& [otherAddr, otherNode] : graph.functions()) { + if (otherAddr == addr) + continue; + if (!otherNode->containsAddress(addr)) + continue; + + // This GAP_FILL is inside another function's blocks + if (otherNode->authority() != FunctionAuthority::GAP_FILL) { + // Absorbed by higher authority - remove + toRemove.push_back(addr); + break; + } else if (otherAddr < addr) { + // Both GAP_FILL, other has lower address - it survives + toRemove.push_back(addr); + break; + } + } + } + + for (uint32_t addr : toRemove) { + graph.removeFunction(addr); + } + + if (!toRemove.empty()) { + REXCODEGEN_TRACE("Analyze: removed {} absorbed GAP_FILL functions", toRemove.size()); + } +} + +} // anonymous namespace + +namespace phases { + +VoidResult GapFill(CodegenContext& ctx, ProgressReporter* reporter) { + (void)reporter; + gapFillCodeRegions(ctx); + + // Discover blocks for gap-filled functions + auto known = buildKnownFunctions(ctx.graph, /*excludeGapFill=*/true); + size_t discovered = discoverPendingFunctions(ctx, known); + REXCODEGEN_TRACE("Analyze: discovered blocks for {} gap-filled functions", discovered); + + cleanupAbsorbedGapFills(ctx); + + return Ok(); +} + +} // namespace phases + +} // namespace rex::codegen diff --git a/src/codegen/phase_helpers.h b/src/codegen/phase_helpers.h new file mode 100644 index 0000000..fdecb6f --- /dev/null +++ b/src/codegen/phase_helpers.h @@ -0,0 +1,41 @@ +/** + * @file codegen/phase_helpers.h + * @brief Shared helpers for analysis phase files + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include + +#include + +namespace rex::codegen { + +/// Build set of non-helper function entry points for boundary detection. +/// @param graph The function graph to scan +/// @param excludeGapFill If true, also exclude GAP_FILL authority functions +inline std::unordered_set buildKnownFunctions(const FunctionGraph& graph, + bool excludeGapFill = false) { + std::unordered_set result; + for (const auto& [addr, node] : graph.functions()) { + auto auth = node->authority(); + if (auth == FunctionAuthority::HELPER) + continue; + if (excludeGapFill && auth == FunctionAuthority::GAP_FILL) + continue; + result.insert(addr); + } + return result; +} + +/// Discover blocks for all pending functions. +size_t discoverPendingFunctions(CodegenContext& ctx, + const std::unordered_set& knownFunctions); + +} // namespace rex::codegen diff --git a/src/codegen/phase_merge.cpp b/src/codegen/phase_merge.cpp new file mode 100644 index 0000000..16071c2 --- /dev/null +++ b/src/codegen/phase_merge.cpp @@ -0,0 +1,94 @@ +/** + * @file codegen/phase_merge.cpp + * @brief Merge phase: resolve jumps and seal functions + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "codegen_flags.h" + +#include + +#include + +#include "codegen_logging.h" +#include + +using rex::memory::load_and_swap; + +namespace rex::codegen { + +namespace { + +//============================================================================= +// Merge to resolve jumps then seal functions +//============================================================================= +void mergeAndSeal(CodegenContext& ctx) { + REXCODEGEN_TRACE("Analyze: resolving jumps and sealing functions..."); + + auto& graph = ctx.graph; + auto& binary = ctx.binary(); + + graph.setMemoryReader([&binary](uint32_t addr) -> std::optional { + auto* section = binary.findSection(addr); + if (!section || !section->data) { + return std::nullopt; + } + uint32_t offset = addr - section->baseAddress; + if (offset + 4 > section->size) { + return std::nullopt; + } + return load_and_swap(section->data + offset); + }); + + size_t iteration = 0; + size_t totalResolved = 0; + const size_t maxResolveIterations = REXCVAR_GET(max_resolve_iterations); + + while (iteration < maxResolveIterations) { + iteration++; + size_t changesThisIteration = 0; + + std::vector pendingAddrs; + for (const auto* node : graph.getPendingFunctions()) { + pendingAddrs.push_back(node->base()); + } + + for (uint32_t funcAddr : pendingAddrs) { + size_t resolved = graph.tryResolveFunction(funcAddr); + changesThisIteration += resolved; + totalResolved += resolved; + } + + if (changesThisIteration == 0) + break; + } + + size_t totalSealed = graph.sealAllReady(); + size_t stillPending = graph.pendingCount(); + + REXCODEGEN_TRACE("Analyze: {} iterations, resolved={}, sealed={}/{}", iteration, totalResolved, + totalSealed, graph.functionCount()); + + if (stillPending > 0) { + REXCODEGEN_DEBUG("Analyze: {} functions still PENDING with unresolved jumps", stillPending); + } +} + +} // anonymous namespace + +namespace phases { + +VoidResult Merge(CodegenContext& ctx, ProgressReporter* reporter) { + (void)reporter; + mergeAndSeal(ctx); + return Ok(); +} + +} // namespace phases + +} // namespace rex::codegen diff --git a/src/codegen/phase_register.cpp b/src/codegen/phase_register.cpp new file mode 100644 index 0000000..6487853 --- /dev/null +++ b/src/codegen/phase_register.cpp @@ -0,0 +1,705 @@ +/** + * @file codegen/phase_register.cpp + * @brief Register phase: imports, helpers, PDATA, config functions + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "codegen_flags.h" +#include "ppc/instruction.h" + +#include +#include "phase_helpers.h" + +#include + +#include +#include + +#include "codegen_logging.h" +#include +#include +#include + +#include + +using rex::codegen::ppc::decode_instruction; +using rex::codegen::ppc::Opcode; +using rex::memory::load_and_swap; + +namespace rex::codegen { + +namespace { + +//============================================================================= +// PE Structures +//============================================================================= + +#pragma pack(push, 1) +struct IMAGE_CE_RUNTIME_FUNCTION { + uint32_t BeginAddress; + union { + uint32_t Data; + struct { + uint32_t PrologLength : 8; + uint32_t FunctionLength : 22; + uint32_t ThirtyTwoBit : 1; + uint32_t ExceptionFlag : 1; + }; + }; +}; +#pragma pack(pop) + +//============================================================================= +// Exception Info Parsing +//============================================================================= + +struct ParsedExceptionInfo { + ExceptionInfo info; + uint32_t maxAddress; + std::vector discoveredFuncs; +}; + +// Prolog info extracted from function prologue for SEH unwinding +struct PrologInfo { + uint32_t frameSize = 0; // From addi r31, r1, -N + uint32_t saveHelper = 0; // From bl __savegprlr_N + bool valid = false; // True if frame size was successfully detected +}; + +// Scan function prolog to extract frame size and save helper +// Only called for functions with ExceptionFlag set +PrologInfo scanProlog(const BinaryView& binary, uint32_t funcAddr, uint32_t prologLength) { + PrologInfo info; + + auto* section = binary.findSection(funcAddr); + if (!section || !section->data) { + return info; + } + + uint32_t offset = funcAddr - section->baseAddress; + if (offset + prologLength * 4 > section->size) { + return info; + } + + const uint8_t* code = section->data + offset; + + // Use pdata prolog length - if 0, we can't safely scan + if (prologLength == 0) { + REXCODEGEN_WARN("SEH function 0x{:08X}: PrologLength=0, cannot determine frame size", funcAddr); + return info; + } + + for (uint32_t i = 0; i < prologLength; i++) { + uint32_t raw = load_and_swap(code + i * 4); + uint32_t addr = funcAddr + i * 4; + auto decoded = decode_instruction(addr, raw); + + // Check for addi r31, r1, -N (frame pointer setup) + if (decoded.opcode == Opcode::addi && decoded.D.RT == 31 && decoded.D.RA == 1) { + int16_t simm = decoded.D.SIMM(); + if (simm < 0) { + info.frameSize = static_cast(-simm); + info.valid = true; + } + } + + // Check for bl - save helper call + if (decoded.is_call() && decoded.branch_target.has_value()) { + info.saveHelper = decoded.branch_target.value(); + } + } + + // NOTE(tomc): info.valid may be false for handler functions that receive frame in r12 + // The caller should warn only if frameSize is actually needed (i.e., function has SEH scopes) + return info; +} + +std::optional parseSehScopeTable(uint32_t handlerThunk, + uint32_t scopeTableAddr, uint32_t count, + const uint8_t* rdataBase, uint32_t rdataStart, + uint32_t rdataSize, + uint32_t functionBeginAddr, + std::vector& discoveredFuncs) { + uint32_t tableOffset = scopeTableAddr - rdataStart; + if (tableOffset + 4 + count * 16 > rdataSize) { + return std::nullopt; + } + + SehExceptionInfo sehInfo; + sehInfo.handlerThunk = handlerThunk; + sehInfo.scopeTableAddr = scopeTableAddr; + + uint32_t maxAddr = functionBeginAddr; + + const uint32_t* entriesData = reinterpret_cast(rdataBase + tableOffset + 4); + for (uint32_t i = 0; i < count; i++) { + SehScope scope; + scope.tryStart = byte_swap(entriesData[i * 4 + 0]); + scope.tryEnd = byte_swap(entriesData[i * 4 + 1]); + scope.filter = byte_swap(entriesData[i * 4 + 2]); + scope.handler = byte_swap(entriesData[i * 4 + 3]); + + // __finally has layout [2]=handler, [3]=0; __except has [2]=filter, [3]=handler + if (scope.handler == 0 && scope.filter != 0) { + scope.handler = scope.filter; + scope.filter = 0; + } + + sehInfo.scopes.push_back(scope); + + if (scope.tryStart != 0 && scope.tryStart > maxAddr) + maxAddr = scope.tryStart; + if (scope.tryEnd != 0 && scope.tryEnd > maxAddr) + maxAddr = scope.tryEnd; + if (scope.filter != 0 && scope.filter > maxAddr) + maxAddr = scope.filter; + if (scope.handler != 0 && scope.handler > maxAddr) + maxAddr = scope.handler; + + // For __finally (filter=0), handler is a separate function + // For __except (filter!=0), only filter is a separate function (handler is inline) + if (scope.filter == 0 && scope.handler != 0) { + discoveredFuncs.push_back(scope.handler); // __finally handler + } + if (scope.filter != 0) { + discoveredFuncs.push_back(scope.filter); // __except filter + } + } + + discoveredFuncs.push_back(handlerThunk); + + ParsedExceptionInfo result; + result.info.data = std::move(sehInfo); + result.maxAddress = maxAddr; + result.discoveredFuncs = std::move(discoveredFuncs); + return result; +} + +std::optional parseCxxFuncInfo(uint32_t handlerThunk, uint32_t funcInfoAddr, + const uint8_t* rdataBase, uint32_t rdataStart, + uint32_t rdataSize, uint32_t functionBeginAddr, + std::vector& discoveredFuncs) { + uint32_t tableOffset = funcInfoAddr - rdataStart; + if (tableOffset + 28 > rdataSize) { + return std::nullopt; + } + + auto readU32 = [&](uint32_t addr) { + return load_and_swap(rdataBase + (addr - rdataStart)); + }; + auto readI32 = [&](uint32_t addr) { + return static_cast(load_and_swap(rdataBase + (addr - rdataStart))); + }; + + CxxExceptionInfo cxxInfo; + cxxInfo.handlerThunk = handlerThunk; + cxxInfo.funcInfoAddr = funcInfoAddr; + + uint32_t magic = readU32(funcInfoAddr + 0); + cxxInfo.maxState = readU32(funcInfoAddr + 4); + uint32_t pUnwindMap = readU32(funcInfoAddr + 8); + uint32_t nTryBlocks = readU32(funcInfoAddr + 12); + uint32_t pTryBlockMap = readU32(funcInfoAddr + 16); + uint32_t nIPMapEntries = readU32(funcInfoAddr + 20); + uint32_t pIPtoStateMap = readU32(funcInfoAddr + 24); + + if (magic != CXX_EH_MAGIC) { + return std::nullopt; + } + + if (cxxInfo.maxState > REXCVAR_GET(max_eh_states) || + nTryBlocks > REXCVAR_GET(max_eh_try_blocks) || + nIPMapEntries > REXCVAR_GET(max_eh_ip_map_entries)) { + return std::nullopt; + } + + uint32_t maxAddr = functionBeginAddr; + discoveredFuncs.push_back(handlerThunk); + + // Parse UnwindMap + if (pUnwindMap != 0 && cxxInfo.maxState > 0) { + if (pUnwindMap >= rdataStart && pUnwindMap + cxxInfo.maxState * 8 <= rdataStart + rdataSize) { + for (uint32_t i = 0; i < cxxInfo.maxState; i++) { + CxxUnwindEntry entry; + entry.toState = readI32(pUnwindMap + i * 8); + entry.action = readU32(pUnwindMap + i * 8 + 4); + cxxInfo.unwindMap.push_back(entry); + + if (entry.action != 0) { + discoveredFuncs.push_back(entry.action); + } + } + } + } + + // Parse TryBlockMap + if (pTryBlockMap != 0 && nTryBlocks > 0) { + if (pTryBlockMap >= rdataStart && pTryBlockMap + nTryBlocks * 20 <= rdataStart + rdataSize) { + for (uint32_t i = 0; i < nTryBlocks; i++) { + uint32_t entryAddr = pTryBlockMap + i * 20; + CxxTryBlock tryBlock; + tryBlock.tryLow = readI32(entryAddr + 0); + tryBlock.tryHigh = readI32(entryAddr + 4); + tryBlock.catchHigh = readI32(entryAddr + 8); + uint32_t nCatches = readU32(entryAddr + 12); + uint32_t pHandlers = readU32(entryAddr + 16); + + if (pHandlers != 0 && nCatches > 0 && nCatches <= 20) { + if (pHandlers >= rdataStart && pHandlers + nCatches * 16 <= rdataStart + rdataSize) { + for (uint32_t j = 0; j < nCatches; j++) { + uint32_t hAddr = pHandlers + j * 16; + CxxCatchHandler handler; + handler.adjectives = readU32(hAddr + 0); + handler.typeDescriptor = readU32(hAddr + 4); + handler.catchObjDisplacement = readI32(hAddr + 8); + handler.handlerAddress = readU32(hAddr + 12); + tryBlock.handlers.push_back(handler); + + if (handler.handlerAddress != 0) { + discoveredFuncs.push_back(handler.handlerAddress); + } + } + } + } + + cxxInfo.tryBlocks.push_back(std::move(tryBlock)); + } + } + } + + // Parse IPtoStateMap + if (pIPtoStateMap != 0 && nIPMapEntries > 0) { + if (pIPtoStateMap >= rdataStart && + pIPtoStateMap + nIPMapEntries * 8 <= rdataStart + rdataSize) { + for (uint32_t i = 0; i < nIPMapEntries; i++) { + CxxIPStateEntry entry; + entry.ip = readU32(pIPtoStateMap + i * 8); + entry.state = readI32(pIPtoStateMap + i * 8 + 4); + cxxInfo.ipToStateMap.push_back(entry); + + if (entry.ip != 0 && entry.ip > maxAddr) { + maxAddr = entry.ip; + } + } + } + } + + ParsedExceptionInfo result; + result.info.data = std::move(cxxInfo); + result.maxAddress = maxAddr; + result.discoveredFuncs = std::move(discoveredFuncs); + return result; +} + +std::optional parseExceptionInfo(const BinaryView& binary, + uint32_t functionBeginAddr) { + uint32_t headerAddr = functionBeginAddr - 8; + + auto* textSection = binary.findSection(headerAddr); + if (!textSection || !textSection->data) { + return std::nullopt; + } + + uint32_t headerOffset = headerAddr - textSection->baseAddress; + if (headerOffset + 8 > textSection->size) { + return std::nullopt; + } + + const uint8_t* headerData = textSection->data + headerOffset; + uint32_t handlerThunk = load_and_swap(headerData); + uint32_t tableAddr = load_and_swap(headerData + 4); + + auto* rdataSection = binary.findSectionByName(".rdata"); + if (!rdataSection || !rdataSection->data) { + return std::nullopt; + } + + uint32_t rdataStart = rdataSection->baseAddress; + uint32_t rdataSize = rdataSection->size; + uint32_t rdataEnd = rdataStart + rdataSize; + const uint8_t* rdataBase = rdataSection->data; + + if (tableAddr < rdataStart || tableAddr >= rdataEnd) { + return std::nullopt; + } + + uint32_t tableOffset = tableAddr - rdataStart; + if (tableOffset + 4 > rdataSize) { + return std::nullopt; + } + + uint32_t firstWord = load_and_swap(rdataBase + tableOffset); + std::vector discoveredFuncs; + + if (firstWord == CXX_EH_MAGIC) { + return parseCxxFuncInfo(handlerThunk, tableAddr, rdataBase, rdataStart, rdataSize, + functionBeginAddr, discoveredFuncs); + } else { + uint32_t count = firstWord; + if (count == 0 || count > REXCVAR_GET(max_seh_scope_entries)) { + return std::nullopt; + } + return parseSehScopeTable(handlerThunk, tableAddr, count, rdataBase, rdataStart, rdataSize, + functionBeginAddr, discoveredFuncs); + } +} + +//============================================================================= +// Helper Detection +//============================================================================= + +void detectSaveRestoreHelpers(const BinaryView& binary, AnalysisState& state) { + struct HelperPattern { + uint32_t pattern; + uint32_t* state_addr; + const char* name; + }; + + HelperPattern patterns[] = { + {0xe9c1ff68, &state.restGpr14Address, "__restgprlr_14"}, + {0xf9c1ff68, &state.saveGpr14Address, "__savegprlr_14"}, + {0xc9ccff70, &state.restFpr14Address, "__restfpr_14"}, + {0xd9ccff70, &state.saveFpr14Address, "__savefpr_14"}, + }; + + for (const auto& section : binary.sections()) { + if (!section.executable) + continue; + + const uint8_t* data = section.data; + const size_t size = section.size; + const size_t base = section.baseAddress; + + for (size_t offset = 0; offset + 4 <= size; offset += 4) { + uint32_t instr = load_and_swap(data + offset); + uint32_t addr = static_cast(base + offset); + + for (auto& p : patterns) { + if (instr == p.pattern && *p.state_addr == 0) { + *p.state_addr = addr; + REXCODEGEN_DEBUG("Found {} at 0x{:08X}", p.name, addr); + } + } + + if (offset + 8 <= size) { + uint32_t next = load_and_swap(data + offset + 4); + + if (instr == 0x3960fee0) { + if (next == 0x7dcb60ce && state.restVmx14Address == 0) { + state.restVmx14Address = addr; + REXCODEGEN_DEBUG("Found __restvmx_14 at 0x{:08X}", addr); + } else if (next == 0x7dcb61ce && state.saveVmx14Address == 0) { + state.saveVmx14Address = addr; + REXCODEGEN_DEBUG("Found __savevmx_14 at 0x{:08X}", addr); + } + } + + if (instr == 0x3960fc00) { + if (next == 0x100b60cb && state.restVmx64Address == 0) { + state.restVmx64Address = addr; + REXCODEGEN_DEBUG("Found __restvmx_64 at 0x{:08X}", addr); + } else if (next == 0x100b61cb && state.saveVmx64Address == 0) { + state.saveVmx64Address = addr; + REXCODEGEN_DEBUG("Found __savevmx_64 at 0x{:08X}", addr); + } + } + } + } + } +} + +//============================================================================= +// Register Phase: imports, helpers, PDATA, config functions +//============================================================================= + +VoidResult registerEntryPoints(CodegenContext& ctx) { + REXCODEGEN_TRACE("Analyze: registering entry points..."); + + auto& graph = ctx.graph; + auto& config = ctx.Config(); + auto& state = ctx.analysisState(); + auto& binary = ctx.binary(); + auto& ehDiscoveredFuncs = state.ehDiscoveredFuncs; + + // Merge user hints into analysis state + for (const auto& [addr, size] : config.invalidInstructionHints) { + state.invalidInstructions[addr] = size; + } + for (uint32_t addr : config.knownIndirectCallHints) { + state.knownIndirectCalls.insert(addr); + } + for (uint32_t addr : config.exceptionHandlerFuncHints) { + state.exceptionHandlerFuncs.push_back(addr); + } + + // Build chunksByParent from config.functions + for (const auto& [addr, cfg] : config.functions) { + if (cfg.isChunk()) { + state.chunksByParent[cfg.parent].push_back(addr); + } + } + + detectSaveRestoreHelpers(binary, state); + + // Register imports + { + auto* resolver = ctx.resolver(); + if (!resolver) { + REXCODEGEN_WARN("No export resolver available - imports won't be resolved"); + } + + size_t importCount = 0; + size_t resolvedCount = 0; + size_t variableCount = 0; + size_t unresolvedCount = 0; + + for (const auto& sym : binary.importSymbols()) { + auto at_pos = sym.name.find('@'); + if (at_pos == std::string::npos) { + REXCODEGEN_ERROR("Invalid import format (missing @): {}", sym.name); + continue; + } + + auto lib_name = sym.name.substr(0, at_pos); + auto ordinal_str = sym.name.substr(at_pos + 1); + uint16_t ordinal = static_cast(std::stoul(ordinal_str)); + + std::string resolvedName; + if (resolver) { + auto* exp = resolver->GetExportByOrdinal(lib_name + ".xex", ordinal); + if (!exp) + exp = resolver->GetExportByOrdinal(lib_name, ordinal); + + if (exp) { + if (exp->type == runtime::Export::Type::kFunction) { + resolvedName = "__imp__" + std::string(exp->name); + resolvedCount++; + } else { + variableCount++; + continue; + } + } + } + + if (resolvedName.empty()) { + REXCODEGEN_ERROR("Cannot resolve ordinal {} from {}", ordinal, lib_name); + resolvedName = fmt::format("sub_{:X}", sym.address); + unresolvedCount++; + } + + auto* node = graph.addImportFunction(sym.address, resolvedName); + if (node && node->canDiscover()) { + node->discoverAsImport(); + if (node->canSeal()) { + node->seal(); + } + } + importCount++; + } + + REXCODEGEN_TRACE( + "Analyze: loaded {} imports ({} resolved, {} unresolved, {} variables skipped)", + importCount, resolvedCount, unresolvedCount, variableCount); + } + + // Register save/restore helpers + auto registerHelpers = [&](uint32_t base14, const char* prefix, size_t stride, size_t endReg, + size_t extraSize) { + if (base14 == 0) + return; + for (size_t i = 14; i <= endReg; i++) { + uint32_t addr = base14 + static_cast((i - 14) * stride); + uint32_t size = static_cast((endReg + 1 - i) * stride + extraSize); + graph.addFunction(addr, size, FunctionAuthority::HELPER, true); + graph.setFunctionName(addr, fmt::format("{}{}", prefix, i)); + } + }; + + registerHelpers(state.restGpr14Address, "__restgprlr_", 4, 31, 12); + registerHelpers(state.saveGpr14Address, "__savegprlr_", 4, 31, 8); + registerHelpers(state.restFpr14Address, "__restfpr_", 4, 31, 4); + registerHelpers(state.saveFpr14Address, "__savefpr_", 4, 31, 4); + registerHelpers(state.restVmx14Address, "__restvmx_", 8, 31, 4); + registerHelpers(state.saveVmx14Address, "__savevmx_", 8, 31, 4); + + // VMX 64-127 + if (state.restVmx64Address != 0) { + for (size_t i = 64; i < 128; i++) { + uint32_t addr = state.restVmx64Address + static_cast((i - 64) * 8); + uint32_t size = static_cast((128 - i) * 8 + 4); + graph.addFunction(addr, size, FunctionAuthority::HELPER, true); + graph.setFunctionName(addr, fmt::format("__restvmx_{}", i)); + } + } + if (state.saveVmx64Address != 0) { + for (size_t i = 64; i < 128; i++) { + uint32_t addr = state.saveVmx64Address + static_cast((i - 64) * 8); + uint32_t size = static_cast((128 - i) * 8 + 4); + graph.addFunction(addr, size, FunctionAuthority::HELPER, true); + graph.setFunctionName(addr, fmt::format("__savevmx_{}", i)); + } + } + + // Register CONFIG functions + size_t configFuncs = 0, configChunks = 0; + for (const auto& [address, cfg] : config.functions) { + uint32_t size = cfg.getSize(address); + std::string name = cfg.name.empty() ? fmt::format("sub_{:08X}", address) : cfg.name; + graph.addFunction(address, size, FunctionAuthority::CONFIG, true); + graph.setFunctionName(address, name); + configFuncs++; + + if (cfg.isChunk()) { + graph.registerChunk(address, size); + configChunks++; + } + } + if (configFuncs > 0) { + REXCODEGEN_DEBUG("Analyze: {} CONFIG functions, {} chunks", configFuncs, configChunks); + } + + // Register PDATA functions + uint32_t pdataAddr = binary.exceptionDirectoryAddr(); + uint32_t pdataSize = binary.exceptionDirectorySize(); + + if (pdataSize == 0) { + return Err(ErrorCategory::Format, "Exception DataDirectory not found (size=0)"); + } + + auto* pdataSection = binary.findSection(pdataAddr); + if (!pdataSection) { + return Err(ErrorCategory::Format, + fmt::format("Cannot find section containing PDATA at 0x{:08X}", pdataAddr)); + } + + uint32_t offsetInSection = pdataAddr - pdataSection->baseAddress; + const uint8_t* pdataData = pdataSection->data + offsetInSection; + + REXCODEGEN_TRACE("Analyze: PDATA base=0x{:08X}, size={}", pdataAddr, pdataSize); + + size_t count = pdataSize / sizeof(IMAGE_CE_RUNTIME_FUNCTION); + auto* entries = reinterpret_cast(pdataData); + + size_t pdataAdded = 0; + for (size_t i = 0; i < count; i++) { + uint32_t beginAddr = byte_swap(entries[i].BeginAddress); + uint32_t data = byte_swap(entries[i].Data); + + IMAGE_CE_RUNTIME_FUNCTION fn; + fn.BeginAddress = beginAddr; + fn.Data = data; + + uint32_t size = fn.FunctionLength * 4; + if (size == 0) + size = 4; + + if (graph.getFunction(beginAddr) != nullptr) { + continue; + } + + std::optional exInfo; + PrologInfo prologInfo; + if (fn.ExceptionFlag) { + // Scan prolog to get frame size for SEH unwinding + prologInfo = scanProlog(binary, beginAddr, fn.PrologLength); + + exInfo = parseExceptionInfo(binary, beginAddr); + if (exInfo) { + if (exInfo->maxAddress > beginAddr + size) { + size = exInfo->maxAddress - beginAddr + 4; + } + state.invalidInstructions[beginAddr - 8] = 8; + + for (uint32_t addr : exInfo->discoveredFuncs) { + ehDiscoveredFuncs.push_back(addr); + } + + // Populate SEH frame info for unwinding + if (exInfo->info.isSeh()) { + // Need non-const access to set frame info + auto& sehInfo = std::get(exInfo->info.data); + sehInfo.frameSize = prologInfo.frameSize; + + // Warn if we have SEH scopes but couldn't determine frame size + if (!prologInfo.valid && !sehInfo.scopes.empty()) { + REXCODEGEN_WARN("SEH function 0x{:08X}: could not determine frame size from prolog", + beginAddr); + } + + // Compute restore helper from save helper + // Save helpers and restore helpers are at matching offsets from their base addresses + if (prologInfo.saveHelper != 0 && state.restGpr14Address != 0 && + state.saveGpr14Address != 0) { + sehInfo.restoreHelper = + prologInfo.saveHelper + (state.restGpr14Address - state.saveGpr14Address); + } + } + } + } + + graph.addFunction(beginAddr, size, FunctionAuthority::PDATA, true); + graph.setFunctionHasExceptionHandler(beginAddr, fn.ExceptionFlag); + + if (exInfo && exInfo->info.hasInfo()) { + if (auto* seh = exInfo->info.asSeh()) { + for (const auto& scope : seh->scopes) { + if (scope.tryStart != 0) + graph.addLabelToFunction(beginAddr, scope.tryStart); + if (scope.tryEnd != 0) + graph.addLabelToFunction(beginAddr, scope.tryEnd); + // For __except (filter!=0), handler is inline code - add as label + if (scope.filter != 0 && scope.handler != 0) { + graph.addLabelToFunction(beginAddr, scope.handler); + } + } + } else if (auto* cxx = exInfo->info.asCxx()) { + for (const auto& entry : cxx->ipToStateMap) { + if (entry.ip != 0) + graph.addLabelToFunction(beginAddr, entry.ip); + } + } + graph.setFunctionExceptionInfo(beginAddr, std::move(exInfo->info)); + } + + ctx.scan.pdataSizes[beginAddr] = size; + pdataAdded++; + } + + REXCODEGEN_TRACE("Analyze: added {} functions from PDATA", pdataAdded); + + // Queue EH-discovered functions + size_t ehFuncsQueued = 0; + for (uint32_t addr : ehDiscoveredFuncs) { + if (graph.getFunction(addr) != nullptr) + continue; + if (graph.isImport(addr)) + continue; + + graph.addFunction(addr, 0, FunctionAuthority::DISCOVERED, true); + ehFuncsQueued++; + } + + if (ehFuncsQueued > 0) { + REXCODEGEN_TRACE("Analyze: queued {} functions from exception handling", ehFuncsQueued); + } + + return Ok(); +} + +} // anonymous namespace + +namespace phases { + +VoidResult Register(CodegenContext& ctx, ProgressReporter* reporter) { + (void)reporter; + return registerEntryPoints(ctx); +} + +} // namespace phases + +} // namespace rex::codegen diff --git a/src/codegen/phase_scan.cpp b/src/codegen/phase_scan.cpp new file mode 100644 index 0000000..ebfa4bd --- /dev/null +++ b/src/codegen/phase_scan.cpp @@ -0,0 +1,178 @@ +/** + * @file codegen/phase_scan.cpp + * @brief Scan phase: segment binary into code/data regions + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include + +#include + +#include +#include + +#include "codegen_logging.h" +#include + +using rex::memory::load_and_swap; + +namespace rex::codegen { + +namespace { + +//============================================================================= +// Scan Phase: segment binary into code/data regions +//============================================================================= + +std::vector segmentSection(const SectionView& section, + const std::unordered_set& exceptionHandlerFuncs, + uint32_t exportTable) { + std::vector regions; + + const uint8_t* data = section.data; + const uint8_t* dataEnd = section.data + section.size; + + if (exportTable && exportTable >= section.baseAddress && + exportTable < section.baseAddress + section.size) { + dataEnd = section.data + (exportTable - section.baseAddress); + } + + uint32_t regionStart = 0; + bool inCode = false; + + while (data < dataEnd) { + uint32_t addr = section.baseAddress + static_cast(data - section.data); + uint32_t word = load_and_swap(data); + + if (word == 0x00000000) { + if (inCode) { + regions.push_back({regionStart, addr}); + inCode = false; + } + + if (data + 12 <= dataEnd) { + uint32_t nextWord = load_and_swap(data + 4); + if (exceptionHandlerFuncs.contains(nextWord)) { + data += 12; + continue; + } + } + data += 4; + continue; + } + + if (!inCode) { + regionStart = addr; + inCode = true; + } + data += 4; + } + + if (inCode) { + uint32_t endAddr = section.baseAddress + static_cast(dataEnd - section.data); + regions.push_back({regionStart, endAddr}); + } + + return regions; +} + +void scanBinary(CodegenContext& ctx) { + REXCODEGEN_TRACE("Analyze: scanning binary..."); + + auto& binary = ctx.binary(); + auto& config = ctx.Config(); + auto& state = ctx.analysisState(); + auto& scan = ctx.scan; + auto& graph = ctx.graph; + + uint32_t exportTable = binary.exportTableAddr(); + + // Build exception handler function set + std::unordered_set exceptionHandlerFuncs; + for (uint32_t addr : state.exceptionHandlerFuncs) { + exceptionHandlerFuncs.insert(addr); + } + + for (const auto& [addr, node] : graph.functions()) { + if (node->authority() != FunctionAuthority::IMPORT) + continue; + if (node->name() == "__imp____C_specific_handler") { + exceptionHandlerFuncs.insert(addr); + break; + } + } + + // Segment executable sections + for (const auto& section : binary.sections()) { + if (!section.executable) + continue; + + auto regions = segmentSection(section, exceptionHandlerFuncs, exportTable); + scan.codeRegions.insert(scan.codeRegions.end(), regions.begin(), regions.end()); + } + + REXCODEGEN_TRACE("Analyze: segmented into {} code regions", scan.codeRegions.size()); + + // Detect data regions + for (const auto& section : binary.sections()) { + if (!section.executable) + continue; + + const uint8_t* data = section.data; + const uint8_t* dataEnd = section.data + section.size; + + if (exportTable && exportTable >= section.baseAddress && + exportTable < section.baseAddress + section.size) { + dataEnd = section.data + (exportTable - section.baseAddress); + } + + uint32_t consecutiveInvalid = 0; + uint32_t dataRegionStart = 0; + + while (data < dataEnd) { + uint32_t addr = section.baseAddress + static_cast(data - section.data); + uint32_t insn = load_and_swap(data); + + bool isInvalid = (insn == 0x00000000 || insn == 0xFFFFFFFF); + if (isInvalid) { + if (consecutiveInvalid == 0) + dataRegionStart = addr; + consecutiveInvalid++; + } else { + if (consecutiveInvalid >= config.dataRegionThreshold) { + scan.dataRegions.emplace_back(dataRegionStart, addr); + } + consecutiveInvalid = 0; + } + + data += 4; + } + + if (consecutiveInvalid >= config.dataRegionThreshold) { + uint32_t endAddr = section.baseAddress + static_cast(dataEnd - section.data); + scan.dataRegions.emplace_back(dataRegionStart, endAddr); + } + } + + REXCODEGEN_TRACE("Analyze: {} code regions, {} data regions", scan.codeRegions.size(), + scan.dataRegions.size()); +} + +} // anonymous namespace + +namespace phases { + +VoidResult Scan(CodegenContext& ctx, ProgressReporter* reporter) { + (void)reporter; + scanBinary(ctx); + return Ok(); +} + +} // namespace phases + +} // namespace rex::codegen diff --git a/src/codegen/phase_validate.cpp b/src/codegen/phase_validate.cpp new file mode 100644 index 0000000..f6691c0 --- /dev/null +++ b/src/codegen/phase_validate.cpp @@ -0,0 +1,169 @@ +/** + * @file codegen/phase_validate.cpp + * @brief Validate phase: verify all call targets resolve + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include + +#include + +#include +#include + +#include "codegen_logging.h" +#include + +#include + +using rex::memory::load_and_swap; + +namespace rex::codegen { + +namespace { + +//============================================================================= +// Validate all calls resolve +//============================================================================= +const CallEdge* findCallEdgeAt(const FunctionNode* node, uint32_t site) { + for (const auto& edge : node->calls()) { + if (edge.site == site) + return &edge; + } + for (const auto& edge : node->tailCalls()) { + if (edge.site == site) + return &edge; + } + return nullptr; +} + +VoidResult validateGraph(CodegenContext& ctx) { + REXCODEGEN_TRACE("Analyze: validating call graph..."); + + auto& graph = ctx.graph; + auto& binary = ctx.binary(); + auto& errors = ctx.errors; + + size_t functionsChecked = 0; + size_t callsChecked = 0; + size_t edgesVerified = 0; + + for (const auto& [addr, node] : graph.functions()) { + functionsChecked++; + + for (const auto& block : node->blocks()) { + const uint8_t* data = binary.translate(block.base); + if (!data) + continue; + + for (size_t offset = 0; offset < block.size; offset += 4) { + uint32_t insn = load_and_swap(data + offset); + + if (PPC_OP(insn) == PPC_OP_B && !PPC_BA(insn)) { + uint32_t site = block.base + static_cast(offset); + int32_t branchOffset = PPC_BI(insn); + uint32_t target = site + branchOffset; + bool isCall = PPC_BL(insn); + + callsChecked++; + + bool targetExists = false; + bool isInternalJump = false; + + // Check if target is within this function's blocks + if (node->containsAddress(target)) { + isInternalJump = true; + targetExists = true; + } + + // Check if target is within this function's overall bounds + // (handles cases where blocks don't cover all owned addresses) + if (!targetExists && node->isWithinBounds(target)) { + isInternalJump = true; + targetExists = true; + } + + // Check if target is another function's entry point + if (!targetExists && graph.isEntryPoint(target)) { + targetExists = true; + } + + // Check if target is an import + if (!targetExists && graph.isImport(target)) { + targetExists = true; + } + + // Check if target is inside any other function's blocks + // (handles cross-function internal branches due to gap-fill merging) + if (!targetExists) { + const FunctionNode* containingFunc = graph.getFunctionContaining(target); + if (containingFunc) { + // Target is inside another function - treat as internal to that function + // This can happen when gap-fill created overlapping regions + targetExists = true; + } + } + + if (!targetExists) { + // Target is not in any function - this is an error that must stop the build + errors.Add(AnalysisErrors::Category::UnresolvedCall, target, site, + fmt::format("{} 0x{:08X} from 0x{:08X} - target not in any function", + isCall ? "bl" : "b", target, site)); + continue; + } + + if (!isInternalJump) { + const CallEdge* edge = findCallEdgeAt(node.get(), site); + if (!edge) { + // Check if target is inside another function - this is a special case + // where code branches to another function's internal address + const FunctionNode* containingFunc = graph.getFunctionContaining(target); + if (!containingFunc) { + // Target is not in any function - this is an error (call the cops) + errors.Add(AnalysisErrors::Category::UnresolvedCall, target, site, + fmt::format("{} 0x{:08X} from 0x{:08X} in {} - no CallEdge recorded", + isCall ? "bl" : "b", target, site, node->name())); + } + // If target is inside another function, it will be handled as a tail call + // to that function's internal label during code generation + } else { + edgesVerified++; + } + } + } + } + } + } + + REXCODEGEN_TRACE("Analyze: checked {} branches in {} functions, verified {} edges", callsChecked, + functionsChecked, edgesVerified); + + if (errors.HasErrors()) { + REXCODEGEN_ERROR("Analyze: found {} errors", errors.Count()); + errors.PrintReport(); + return Err(ErrorCategory::Validation, + fmt::format("Validation failed: {} unresolved calls", + errors.Count(AnalysisErrors::Category::UnresolvedCall))); + } + + REXCODEGEN_TRACE("Analyze: all calls resolve"); + return Ok(); +} + +} // anonymous namespace + +namespace phases { + +VoidResult Validate(CodegenContext& ctx, ProgressReporter* reporter) { + (void)reporter; + return validateGraph(ctx); +} + +} // namespace phases + +} // namespace rex::codegen diff --git a/src/codegen/ppc/disasm.cpp b/src/codegen/ppc/disasm.cpp new file mode 100644 index 0000000..c7fe10b --- /dev/null +++ b/src/codegen/ppc/disasm.cpp @@ -0,0 +1,53 @@ +/** + * @file rexcodegen/disasm.cpp + * @brief PPC disassembly implementation + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "disasm.h" + +namespace rex::codegen::ppc { + +// Binutils PPC_OPCODE_* dialect bits (see thirdparty/disasm/ppc-dis.c) +constexpr uintptr_t kXenonDialect = 0x1 // PPC + | 0x4 // 64 + | 0x4000 // POWER4 + | 0x8000000 // CELL + | 0x200 // ALTIVEC + | 0x1000000 // VMX_128 + | 0x10000; // CLASSIC + +thread_local DisassemblerEngine gBigEndianDisassembler{BFD_ENDIAN_BIG, nullptr}; + +DisassemblerEngine::DisassemblerEngine(bfd_endian endian, const char* options) { + INIT_DISASSEMBLE_INFO(info, stdout, fprintf); + info.arch = bfd_arch_powerpc; + info.endian = endian; + info.disassembler_options = options; + info.private_data = reinterpret_cast(kXenonDialect); +} + +int DisassemblerEngine::Disassemble(const void* code, size_t size, uint64_t base, ppc_insn& out) { + if (size < 4) { + return 0; + } + + info.buffer = (bfd_byte*)code; + info.buffer_vma = base; + info.buffer_length = size; + return decode_insn_ppc(base, &info, &out); +} + +int Disassemble(const void* code, uint64_t base, ppc_insn* out, size_t nOut) { + for (size_t i = 0; i < nOut; i++) { + Disassemble(static_cast(code) + i, base, out[i]); + } + return static_cast(nOut) * 4; +} + +} // namespace rex::codegen::ppc diff --git a/src/codegen/ppc/disasm.h b/src/codegen/ppc/disasm.h new file mode 100644 index 0000000..b1823e7 --- /dev/null +++ b/src/codegen/ppc/disasm.h @@ -0,0 +1,51 @@ +/** + * @file rexcodegen/internal/ppc/disasm.h + * @brief PPC disassembler interface + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include + +namespace rex::codegen::ppc { + +//============================================================================= +// Low-level Disassembler Engine (binutils wrapper) +//============================================================================= +// Decodes raw bytes into ppc_insn struct using GNU binutils + +struct DisassemblerEngine { + disassemble_info info{}; + DisassemblerEngine(const DisassemblerEngine&) = default; + DisassemblerEngine& operator=(const DisassemblerEngine&) = delete; + + DisassemblerEngine(bfd_endian endian, const char* options); + ~DisassemblerEngine() = default; + + /** + * Disassemble a single instruction + * @return Number of bytes decoded + */ + int Disassemble(const void* code, size_t size, uint64_t base, ppc_insn& out); +}; + +thread_local extern DisassemblerEngine gBigEndianDisassembler; + +inline int Disassemble(const void* code, size_t size, uint64_t base, ppc_insn& out) { + return gBigEndianDisassembler.Disassemble(code, size, base, out); +} + +inline int Disassemble(const void* code, uint64_t base, ppc_insn& out) { + return Disassemble(code, 4, base, out); +} + +int Disassemble(const void* code, uint64_t base, ppc_insn* out, size_t nOut); + +} // namespace rex::codegen::ppc diff --git a/src/codegen/ppc/instruction.cpp b/src/codegen/ppc/instruction.cpp new file mode 100644 index 0000000..dee4d1d --- /dev/null +++ b/src/codegen/ppc/instruction.cpp @@ -0,0 +1,355 @@ +/** + * @file arch/ppc/instruction.cpp + * @brief PowerPC instruction implementation + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "instruction.h" +#include "opcode.h" + +#include + +namespace rex::codegen::ppc { + +//============================================================================= +// Helper functions +//============================================================================= + +// Special SPR numbers +constexpr u32 SPR_LR = 8; // Link Register +constexpr u32 SPR_CTR = 9; // Count Register + +//============================================================================= +// Instruction helper methods implementation +//============================================================================= + +bool Instruction::is_branch() const { + const auto& info = get_opcode_info(opcode); + return info.group == OpcodeGroup::kBranch; +} + +bool Instruction::is_call() const { + switch (opcode) { + case Opcode::bl: + case Opcode::bla: + return true; + case Opcode::bcl: + case Opcode::bcla: + case Opcode::bclrl: + case Opcode::bcctrl: + return true; + default: + return false; + } +} + +bool Instruction::is_return() const { + // blr is bclr with BO=20 (unconditional) + if (opcode == Opcode::bclr) { + return (raw == 0x4E800020); // Specific encoding for blr + } + return false; +} + +bool Instruction::is_indirect_branch() const { + return opcode == Opcode::bclr || opcode == Opcode::bcctr; +} + +bool Instruction::is_record_form() const { + switch (format) { + case InstrFormat::kX: + return X.Rc != 0; + case InstrFormat::kXO: + return XO.Rc != 0; + case InstrFormat::kM: + return M.Rc != 0; + case InstrFormat::kMD: + return MD.Rc != 0; + case InstrFormat::kA: + return A.Rc != 0; + case InstrFormat::kVXR: + return VXR.Rc != 0; + default: + return false; + } +} + +bool Instruction::is_conditional() const { + switch (opcode) { + case Opcode::bc: + case Opcode::bca: + case Opcode::bcl: + case Opcode::bcla: + return true; + case Opcode::bclr: + case Opcode::bclrl: + case Opcode::bcctr: + case Opcode::bcctrl: + // Check BO field - unconditional if BO=20 + return XL.BO != 20; + default: + return false; + } +} + +std::vector Instruction::get_register_reads() const { + std::vector regs; + + switch (format) { + case InstrFormat::kD: + if (D.RA != 0) + regs.push_back((u8)D.RA); + break; + case InstrFormat::kX: + if (X.RA != 0) + regs.push_back((u8)X.RA); + if (X.RB != 0) + regs.push_back((u8)X.RB); + break; + case InstrFormat::kXO: + if (XO.RA != 0) + regs.push_back((u8)XO.RA); + if (XO.RB != 0) + regs.push_back((u8)XO.RB); + break; + case InstrFormat::kM: + regs.push_back((u8)M.RS); + break; + default: + break; + } + + return regs; +} + +std::vector Instruction::get_register_writes() const { + std::vector regs; + + switch (format) { + case InstrFormat::kD: + regs.push_back((u8)D.RT); + break; + case InstrFormat::kX: + regs.push_back((u8)X.RT); + break; + case InstrFormat::kXO: + regs.push_back((u8)XO.RT); + break; + case InstrFormat::kM: + regs.push_back((u8)M.RA); + break; + default: + break; + } + + return regs; +} + +Instruction::Semantics Instruction::get_semantics() const { + Semantics sem; + + sem.reads_gpr = get_register_reads(); + sem.writes_gpr = get_register_writes(); + sem.is_branch = is_branch(); + sem.is_call = is_call(); + sem.is_return = is_return(); + + // Memory access + const auto& info = get_opcode_info(opcode); + if (info.group == OpcodeGroup::kMemory) { + switch (opcode) { + case Opcode::lbz: + case Opcode::lbzu: + case Opcode::lhz: + case Opcode::lhzu: + case Opcode::lwz: + case Opcode::lwzu: + case Opcode::ld: + case Opcode::ldu: + sem.reads_memory = true; + break; + case Opcode::stb: + case Opcode::stbu: + case Opcode::sth: + case Opcode::sthu: + case Opcode::stw: + case Opcode::stwu: + case Opcode::std: + case Opcode::stdu: + sem.writes_memory = true; + break; + default: + break; + } + } + + // Special register access + if (opcode == Opcode::mfspr) { + u32 spr = XFX.spr_num(); + if (spr == SPR_LR) + sem.reads_lr = true; + else if (spr == SPR_CTR) + sem.reads_ctr = true; + } else if (opcode == Opcode::mtspr) { + u32 spr = XFX.spr_num(); + if (spr == SPR_LR) + sem.writes_lr = true; + else if (spr == SPR_CTR) + sem.writes_ctr = true; + } + + // Simplified mnemonics + if (opcode == Opcode::mflr) + sem.reads_lr = true; + if (opcode == Opcode::mtlr) + sem.writes_lr = true; + if (opcode == Opcode::mfctr) + sem.reads_ctr = true; + if (opcode == Opcode::mtctr) + sem.writes_ctr = true; + + // Branch instructions + if (opcode == Opcode::bclr || opcode == Opcode::bclrl) { + sem.reads_lr = true; + } + if (opcode == Opcode::bcctr || opcode == Opcode::bcctrl) { + sem.reads_ctr = true; + } + + // Condition register + if (opcode == Opcode::cmp || opcode == Opcode::cmpi || opcode == Opcode::cmpl || + opcode == Opcode::cmpli) { + sem.writes_cr = true; + } + + return sem; +} + +//============================================================================= +// Instruction decoding +//============================================================================= + +Instruction decode_instruction(guest_addr_t address, u32 code) { + Instruction instr; + instr.address = address; + instr.code = code; + instr.raw = code; // Store in union + + // Lookup opcode + instr.opcode = lookup_opcode(code); + + // Get opcode info + const auto& info = get_opcode_info(instr.opcode); + instr.format = info.format; + + // Compute branch target if applicable + if (instr.is_branch()) { + switch (instr.format) { + case InstrFormat::kI: { + // Unconditional branch (b, ba, bl, bla) + // Use reliable XOR-subtract sign extension + i32 offset = Instruction::get_i_offset(code); + bool aa = (code >> 1) & 1; // AA bit (absolute address) + if (aa) { + // Absolute address + instr.branch_target = static_cast(offset & 0xFFFFFFFF); + } else { + // Relative address + instr.branch_target = address + offset; + } + break; + } + + case InstrFormat::kB: { + // Conditional branch (bc, bca, bcl, bcla) + // Use reliable XOR-subtract sign extension + i32 offset = Instruction::get_b_offset(code); + bool aa = (code >> 1) & 1; // AA bit (absolute address) + if (aa) { + // Absolute address + instr.branch_target = static_cast(offset & 0xFFFF); + } else { + // Relative address + instr.branch_target = address + offset; + } + break; + } + + case InstrFormat::kXL: { + // Indirect branch (bclr, bcctr) + // Target is runtime-dependent (in LR or CTR) + instr.branch_target = std::nullopt; + break; + } + + default: + instr.branch_target = std::nullopt; + break; + } + } + + // Handle simplified mnemonics + // blr = bclr with BO=20 + if (code == 0x4E800020) { + instr.opcode = Opcode::bclr; // Already set, but ensure + } + + // bctr = bcctr with BO=20 + if (code == 0x4E800420) { + instr.opcode = Opcode::bcctr; + } + + // nop = ori 0,0,0 + if (code == 0x60000000) { + instr.opcode = Opcode::nop; + } + + // li rD, value = addi rD, 0, value + if (instr.opcode == Opcode::addi && instr.D.RA == 0) { + instr.opcode = Opcode::li; + } + + // lis rD, value = addis rD, 0, value + if (instr.opcode == Opcode::addis && instr.D.RA == 0) { + instr.opcode = Opcode::lis; + } + + // mr rA, rS = or rA, rS, rS (both source operands are the same register) + if (instr.opcode == Opcode::or_ && instr.X.RT == instr.X.RB) { + instr.opcode = Opcode::mr; + } + + // mflr rD = mfspr rD, LR (SPR 8) + if (instr.opcode == Opcode::mfspr && instr.XFX.spr_num() == SPR_LR) { + instr.opcode = Opcode::mflr; + } + + // mtlr rS = mtspr LR, rS (SPR 8) + if (instr.opcode == Opcode::mtspr && instr.XFX.spr_num() == SPR_LR) { + instr.opcode = Opcode::mtlr; + } + + // mfctr rD = mfspr rD, CTR (SPR 9) + if (instr.opcode == Opcode::mfspr && instr.XFX.spr_num() == SPR_CTR) { + instr.opcode = Opcode::mfctr; + } + + // mtctr rS = mtspr CTR, rS (SPR 9) + if (instr.opcode == Opcode::mtspr && instr.XFX.spr_num() == SPR_CTR) { + instr.opcode = Opcode::mtctr; + } + + return instr; +} + +std::string Instruction::to_string() const { + // Placeholder - will be implemented in ppc_disasm.cpp + const auto& info = get_opcode_info(opcode); + return std::string(info.name); +} +} // namespace rex::codegen::ppc diff --git a/src/codegen/ppc/instruction.h b/src/codegen/ppc/instruction.h new file mode 100644 index 0000000..cb46f84 --- /dev/null +++ b/src/codegen/ppc/instruction.h @@ -0,0 +1,464 @@ +/** + * @file arch/ppc/instruction.h + * @brief PowerPC instruction representation and decoding + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include "opcode.h" + +#include +#include +#include +#include + +#include + +namespace rex::codegen::ppc { + +/** + * PowerPC instruction with decoded fields + * + * Uses union-based decoding for efficient field access. + * Includes semantic information for future recompilation support. + */ +struct Instruction { + uint32_t address = 0; // Guest address of instruction + rex::be code{0}; // Raw instruction encoding (big-endian) + Opcode opcode = Opcode::kUnknown; + InstrFormat format = InstrFormat::kUnknown; + + //========================================================================= + // Format-specific field unions + //========================================================================= + + /** + * Format I - Unconditional Branch (b, ba, bl, bla) + * Fields: LI (24-bit), AA (1-bit), LK (1-bit) + */ + struct FormatI { + uint32_t LI : 24; // Branch offset (bits 6-29) + uint32_t AA : 1; // Absolute address flag (bit 30) + uint32_t LK : 1; // Link flag (bit 31) + uint32_t _pad : 6; // Primary opcode (bits 0-5) + + // Get sign-extended branch target offset + int32_t offset() const { + // Sign-extend 24-bit to 32-bit, then multiply by 4 + int32_t val = (int32_t)(LI << 8) >> 6; // Sign extend and * 4 + return val; + } + }; + + /** + * Format B - Conditional Branch (bc, bca, bcl, bcla) + * Fields: BO (5-bit), BI (5-bit), BD (14-bit), AA (1-bit), LK (1-bit) + */ + struct FormatB { + uint32_t BD : 14; // Branch displacement (bits 16-29) + uint32_t AA : 1; // Absolute address flag (bit 30) + uint32_t LK : 1; // Link flag (bit 31) + uint32_t BI : 5; // Condition register bit (bits 11-15) + uint32_t BO : 5; // Branch options (bits 6-10) + uint32_t _pad : 6; // Primary opcode (bits 0-5) + + // Get sign-extended branch target offset + int32_t offset() const { + // Sign-extend 14-bit to 32-bit, then multiply by 4 + int32_t val = (int32_t)(BD << 18) >> 16; // Sign extend and * 4 + return val; + } + }; + + /** + * Format D - Immediate operations (load, store, addi, etc.) + * Fields: RT/RS (5-bit), RA (5-bit), d/SIMM/UIMM (16-bit) + */ + struct FormatD { + uint32_t d : 16; // Immediate value (bits 16-31) + uint32_t RA : 5; // Register A (bits 11-15) + uint32_t RT : 5; // Register T/S (bits 6-10) + uint32_t _pad : 6; // Primary opcode (bits 0-5) + + // Signed immediate + int32_t SIMM() const { + return (int32_t)((int16_t)d); // Sign-extend 16-bit + } + + // Unsigned immediate + uint32_t UIMM() const { return (uint32_t)d; } + + // Register S (store instructions use this field) + uint32_t RS() const { return RT; } + }; + + /** + * Format DS - Double-word operations (ld, std) + * Fields: RT/RS (5-bit), RA (5-bit), DS (14-bit), XO (2-bit) + */ + struct FormatDS { + uint32_t XO : 2; // Extended opcode (bits 30-31) + uint32_t DS : 14; // Displacement (bits 16-29, multiple of 4) + uint32_t RA : 5; // Register A (bits 11-15) + uint32_t RT : 5; // Register T/S (bits 6-10) + uint32_t _pad : 6; // Primary opcode (bits 0-5) + + // Get sign-extended displacement (multiple of 4) + int32_t displacement() const { + return (int32_t)((int16_t)(DS << 2)); // Sign-extend and * 4 + } + + uint32_t RS() const { return RT; } + }; + + /** + * Format X - General register operations (logical, shifts, loads/stores) + * Fields: RT/RS (5-bit), RA (5-bit), RB (5-bit), XO (10-bit), Rc (1-bit) + */ + struct FormatX { + uint32_t Rc : 1; // Record bit (bit 31) + uint32_t XO : 10; // Extended opcode (bits 21-30) + uint32_t RB : 5; // Register B (bits 16-20) + uint32_t RA : 5; // Register A (bits 11-15) + uint32_t RT : 5; // Register T/S (bits 6-10) + uint32_t _pad : 6; // Primary opcode (bits 0-5) + + uint32_t RS() const { return RT; } + }; + + /** + * Format XL - Branch to LR/CTR (bclr, bcctr) + * Fields: BO (5-bit), BI (5-bit), XO (10-bit), LK (1-bit) + */ + struct FormatXL { + uint32_t LK : 1; // Link bit (bit 31) + uint32_t XO : 10; // Extended opcode (bits 21-30) + uint32_t _unused : 5; // Unused (bits 16-20) + uint32_t BI : 5; // Condition register bit (bits 11-15) + uint32_t BO : 5; // Branch options (bits 6-10) + uint32_t _pad : 6; // Primary opcode (bits 0-5) + }; + + /** + * Format XFX - SPR access (mfspr, mtspr) + * Fields: RT/RS (5-bit), SPR (10-bit), XO (10-bit) + */ + struct FormatXFX { + uint32_t _unused : 1; // Unused (bit 31) + uint32_t XO : 10; // Extended opcode (bits 21-30) + uint32_t SPR : 10; // SPR number (bits 11-20, encoded split) + uint32_t RT : 5; // Register T/S (bits 6-10) + uint32_t _pad : 6; // Primary opcode (bits 0-5) + + // Get actual SPR number (bits are swapped in encoding) + uint32_t spr_num() const { + uint32_t lower = (SPR >> 5) & 0x1F; + uint32_t upper = SPR & 0x1F; + return (upper << 5) | lower; + } + + uint32_t RS() const { return RT; } + }; + + /** + * Format XO - Arithmetic with overflow (add, sub, mul, div) + * Fields: RT (5-bit), RA (5-bit), RB (5-bit), OE (1-bit), XO (9-bit), Rc (1-bit) + */ + struct FormatXO { + uint32_t Rc : 1; // Record bit (bit 31) + uint32_t XO : 9; // Extended opcode (bits 22-30) + uint32_t OE : 1; // Overflow enable (bit 21) + uint32_t RB : 5; // Register B (bits 16-20) + uint32_t RA : 5; // Register A (bits 11-15) + uint32_t RT : 5; // Register T (bits 6-10) + uint32_t _pad : 6; // Primary opcode (bits 0-5) + }; + + /** + * Format M - Rotate and mask (rlwinm, rlwnm) + * Fields: RS (5-bit), RA (5-bit), SH/RB (5-bit), MB (5-bit), ME (5-bit), Rc (1-bit) + */ + struct FormatM { + uint32_t Rc : 1; // Record bit (bit 31) + uint32_t ME : 5; // Mask end (bits 26-30) + uint32_t MB : 5; // Mask begin (bits 21-25) + uint32_t SH : 5; // Shift amount (bits 16-20) + uint32_t RA : 5; // Register A (bits 11-15) + uint32_t RS : 5; // Register S (bits 6-10) + uint32_t _pad : 6; // Primary opcode (bits 0-5) + + uint32_t RB() const { return SH; } // For rlwnm + }; + + /** + * Format MD - Rotate double-word (64-bit) + * Fields: RS (5-bit), RA (5-bit), sh (6-bit), mb (6-bit), XO (3-bit), Rc (1-bit) + */ + struct FormatMD { + uint32_t Rc : 1; // Record bit (bit 31) + uint32_t XO : 3; // Extended opcode (bits 27-30, includes sh bit 5) + uint32_t mb : 6; // Mask begin (bits 21-26, includes bit 5) + uint32_t sh : 6; // Shift amount (bits 16-20, includes bit 30) + uint32_t RA : 5; // Register A (bits 11-15) + uint32_t RS : 5; // Register S (bits 6-10) + uint32_t _pad : 6; // Primary opcode (bits 0-5) + }; + + /** + * Format A - Floating-point arithmetic (fmadd, fmul, etc.) + * Fields: FRT (5-bit), FRA (5-bit), FRB (5-bit), FRC (5-bit), XO (5-bit), Rc (1-bit) + */ + struct FormatA { + uint32_t Rc : 1; // Record bit (bit 31) + uint32_t XO : 5; // Extended opcode (bits 26-30) + uint32_t FRC : 5; // FPR C (bits 21-25) + uint32_t FRB : 5; // FPR B (bits 16-20) + uint32_t FRA : 5; // FPR A (bits 11-15) + uint32_t FRT : 5; // FPR T (target, bits 6-10) + uint32_t _pad : 6; // Primary opcode (bits 0-5) + }; + + /** + * Format VA - Vector 4-operand (vperm, vmaddfp, etc.) + * Fields: VRT (5-bit), VRA (5-bit), VRB (5-bit), VRC (5-bit), XO (6-bit) + */ + struct FormatVA { + uint32_t XO : 6; // Extended opcode (bits 26-31) + uint32_t VRC : 5; // Vector register C (bits 21-25) + uint32_t VRB : 5; // Vector register B (bits 16-20) + uint32_t VRA : 5; // Vector register A (bits 11-15) + uint32_t VRT : 5; // Vector register T (bits 6-10) + uint32_t _pad : 6; // Primary opcode (bits 0-5) + + // Alias for VD (destination) + uint32_t VD() const { return VRT; } + }; + + /** + * Format VX - Vector 3-operand/2-operand (vaddfp, vand, etc.) + * Fields: VRT (5-bit), VRA (5-bit), VRB (5-bit), XO (11-bit) + */ + struct FormatVX { + uint32_t XO : 11; // Extended opcode (bits 21-31) + uint32_t VRB : 5; // Vector register B (bits 16-20) + uint32_t VRA : 5; // Vector register A (bits 11-15) + uint32_t VRT : 5; // Vector register T (bits 6-10) + uint32_t _pad : 6; // Primary opcode (bits 0-5) + + // Alias for immediate in some instructions (UIMM in VRA field) + uint32_t UIMM() const { return VRA; } + int32_t SIMM() const { return (int32_t)((int8_t)(VRA << 3) >> 3); } // Sign extend 5-bit + uint32_t VD() const { return VRT; } + }; + + /** + * Format VXR - Vector with record bit (vcmp instructions) + * Fields: VRT (5-bit), VRA (5-bit), VRB (5-bit), Rc (1-bit), XO (10-bit) + */ + struct FormatVXR { + uint32_t XO : 10; // Extended opcode (bits 21-30) + uint32_t Rc : 1; // Record bit (bit 31, sets CR6) + uint32_t VRB : 5; // Vector register B (bits 16-20) + uint32_t VRA : 5; // Vector register A (bits 11-15) + uint32_t VRT : 5; // Vector register T (bits 6-10) + uint32_t _pad : 6; // Primary opcode (bits 0-5) + + uint32_t VD() const { return VRT; } + }; + + /** + * Format VMX128 - Xbox 360 extended vector format + * Uses different register encoding for 128 vector registers + */ + struct FormatVMX128 { + uint32_t XO : 6; // Extended opcode (variable position) + uint32_t VRC : 5; // Vector register C (bits 21-25), extended + uint32_t VRB : 5; // Vector register B (bits 16-20), extended + uint32_t VRA : 5; // Vector register A (bits 11-15), extended + uint32_t VRT : 5; // Vector register T (bits 6-10), extended + uint32_t _pad : 6; // Primary opcode (bits 0-5) + + // Get full 7-bit register numbers (0-127) + uint32_t VD() const { return VRT; } + }; + + // Union to access different formats + union { + FormatI I; + FormatB B; + FormatD D; + FormatDS DS; + FormatX X; + FormatXL XL; + FormatXFX XFX; + FormatXO XO; + FormatM M; + FormatMD MD; + FormatA A; // Floating-point A-form + FormatVA VA; // Vector A-form (4 operands) + FormatVX VX; // Vector X-form (3 operands) + FormatVXR VXR; // Vector X-form with record bit + FormatVMX128 VMX128; // Xbox 360 VMX128 extended + uint32_t raw; // Raw 32-bit value for direct access + }; + + //========================================================================= + // Branch offset extraction using XOR-subtract sign extension + //========================================================================= + + /** + * Get I-form branch offset (26-bit LI field, sign-extended, * 4) + * For b, ba, bl, bla instructions + * Uses XOR-subtract technique for reliable sign extension + */ + static int32_t get_i_offset(uint32_t instr) { + // LI is bits 6-29 (24 bits), but stored with implicit 00 suffix + // Mask 0x3FFFFFC extracts bits 2-25 (which is LI * 4) + // XOR-subtract with sign bit 0x2000000 for 26-bit sign extension + return static_cast(((instr & 0x3FFFFFC) ^ 0x2000000) - 0x2000000); + } + + /** + * Get B-form branch offset (14-bit BD field, sign-extended, * 4) + * For bc, bca, bcl, bcla instructions + * Uses XOR-subtract technique for reliable sign extension + */ + static int32_t get_b_offset(uint32_t instr) { + // BD is bits 16-29 (14 bits), but stored with implicit 00 suffix + // Mask 0xFFFC extracts bits 2-15 (which is BD * 4) + // XOR-subtract with sign bit 0x8000 for 16-bit sign extension + return static_cast(((instr & 0xFFFC) ^ 0x8000) - 0x8000); + } + + // Pre-computed branch target (if applicable) + std::optional branch_target; + + //========================================================================= + // Helper methods + //========================================================================= + + /** + * Check if this is a branch instruction + */ + bool is_branch() const; + + /** + * Check if this is a function call (branch with link) + */ + bool is_call() const; + + /** + * Check if this is a return instruction (blr) + */ + bool is_return() const; + + /** + * Check if this is an indirect branch (bcctr, bclr) + */ + bool is_indirect_branch() const; + + /** + * Check if this is a record-form instruction (sets CR0). + * Checks the Rc bit based on the instruction format. + */ + bool is_record_form() const; + + /** + * Check if this is a conditional branch + * Returns false for unconditional branches (BO=20) + */ + bool is_conditional() const; + + /** + * Get register numbers that this instruction reads from + */ + std::vector get_register_reads() const; + + /** + * Get register numbers that this instruction writes to + */ + std::vector get_register_writes() const; + + /** + * Disassemble instruction to string + */ + std::string to_string() const; + + //========================================================================= + // Semantic information (for future HIR translation) + //========================================================================= + + struct Semantics { + std::vector reads_gpr; // GPR registers read + std::vector writes_gpr; // GPR registers written + bool reads_memory = false; + bool writes_memory = false; + bool reads_lr = false; + bool writes_lr = false; + bool reads_ctr = false; + bool writes_ctr = false; + bool reads_cr = false; // Condition register + bool writes_cr = false; + bool is_branch = false; + bool is_call = false; + bool is_return = false; + }; + + /** + * Get semantic information (computed on demand) + */ + Semantics get_semantics() const; +}; + +/** + * Decode instruction from raw code + * @param address Guest address of instruction + * @param code Raw 32-bit instruction code (host byte order) + * @return Decoded instruction structure + */ +Instruction decode_instruction(uint32_t address, uint32_t code); + +/** + * PowerPC disassembler to string converter + * + * Converts instructions to GNU objdump-style assembly text. + * Examples: + * bl 0x82001234 + * addi r3, r1, 100 + * stw r4, 0x20(r1) + */ +class InstructionString { + public: + /** + * Disassemble a single instruction + * @param instr Decoded instruction + * @return Assembly text string + */ + static std::string disassemble(const Instruction& instr); + + private: + // Format helpers + static std::string format_register(u8 reg); + static std::string format_immediate(i32 imm); + static std::string format_address(guest_addr_t addr); + static std::string format_offset(i32 offset, u8 base_reg); + + // Instruction-specific formatters + static std::string format_branch(const Instruction& instr); + static std::string format_load_store(const Instruction& instr); + static std::string format_immediate_alu(const Instruction& instr); + static std::string format_register_alu(const Instruction& instr); + static std::string format_compare(const Instruction& instr); + static std::string format_spr(const Instruction& instr); + static std::string format_rotate(const Instruction& instr); + static std::string format_float(const Instruction& instr); + static std::string format_vector(const Instruction& instr); +}; + +} // namespace rex::codegen::ppc diff --git a/src/codegen/ppc/opcode.cpp b/src/codegen/ppc/opcode.cpp new file mode 100644 index 0000000..c079469 --- /dev/null +++ b/src/codegen/ppc/opcode.cpp @@ -0,0 +1,1279 @@ +/** + * @file rexcodegen/internal/ppc/opcodes.cpp + * @brief PPC opcode table implementation + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "opcode.h" + +#include +#include +#include + +#include + +using namespace rex; + +namespace rex::codegen::ppc { + +// Helper to extract bit fields from instruction +constexpr u32 extract_bits(u32 value, u32 start, u32 count) { + return (value >> (32 - start - count)) & ((1u << count) - 1); +} + +//============================================================================= +// Opcode information table +//============================================================================= + +static const std::array g_opcode_table = {{ + // Primary opcode 16: bcx (conditional branch) - all variants + {Opcode::bc, InstrFormat::kB, OpcodeGroup::kBranch, "bc", 16, 0, false}, + {Opcode::bca, InstrFormat::kB, OpcodeGroup::kBranch, "bca", 16, 0, false}, + {Opcode::bcl, InstrFormat::kB, OpcodeGroup::kBranch, "bcl", 16, 0, false}, + {Opcode::bcla, InstrFormat::kB, OpcodeGroup::kBranch, "bcla", 16, 0, false}, + + // Primary opcode 18: bx (unconditional branch) - all variants + {Opcode::b, InstrFormat::kI, OpcodeGroup::kBranch, "b", 18, 0, false}, + {Opcode::ba, InstrFormat::kI, OpcodeGroup::kBranch, "ba", 18, 0, false}, + {Opcode::bl, InstrFormat::kI, OpcodeGroup::kBranch, "bl", 18, 0, false}, + {Opcode::bla, InstrFormat::kI, OpcodeGroup::kBranch, "bla", 18, 0, false}, + + // Primary opcode 19: Extended branch instructions - all variants + {Opcode::bclr, InstrFormat::kXL, OpcodeGroup::kBranch, "bclr", 19, 16, true}, + {Opcode::bclrl, InstrFormat::kXL, OpcodeGroup::kBranch, "bclrl", 19, 16, true}, + {Opcode::bcctr, InstrFormat::kXL, OpcodeGroup::kBranch, "bcctr", 19, 528, true}, + {Opcode::bcctrl, InstrFormat::kXL, OpcodeGroup::kBranch, "bcctrl", 19, 528, true}, + + // Primary opcode 14: addi + {Opcode::addi, InstrFormat::kD, OpcodeGroup::kGeneral, "addi", 14, 0, false}, + + // Primary opcode 15: addis + {Opcode::addis, InstrFormat::kD, OpcodeGroup::kGeneral, "addis", 15, 0, false}, + + // Primary opcode 24: ori + {Opcode::ori, InstrFormat::kD, OpcodeGroup::kGeneral, "ori", 24, 0, false}, + + // Primary opcode 25: oris + {Opcode::oris, InstrFormat::kD, OpcodeGroup::kGeneral, "oris", 25, 0, false}, + + // Primary opcode 26: xori + {Opcode::xori, InstrFormat::kD, OpcodeGroup::kGeneral, "xori", 26, 0, false}, + + // Primary opcode 27: xoris + {Opcode::xoris, InstrFormat::kD, OpcodeGroup::kGeneral, "xoris", 27, 0, false}, + + // Primary opcode 28: andi. + {Opcode::andi_, InstrFormat::kD, OpcodeGroup::kGeneral, "andi.", 28, 0, false}, + + // Primary opcode 29: andis. + {Opcode::andis_, InstrFormat::kD, OpcodeGroup::kGeneral, "andis.", 29, 0, false}, + + // Primary opcode 32: lwz + {Opcode::lwz, InstrFormat::kD, OpcodeGroup::kMemory, "lwz", 32, 0, false}, + + // Primary opcode 33: lwzu + {Opcode::lwzu, InstrFormat::kD, OpcodeGroup::kMemory, "lwzu", 33, 0, false}, + + // Primary opcode 34: lbz + {Opcode::lbz, InstrFormat::kD, OpcodeGroup::kMemory, "lbz", 34, 0, false}, + + // Primary opcode 35: lbzu + {Opcode::lbzu, InstrFormat::kD, OpcodeGroup::kMemory, "lbzu", 35, 0, false}, + + // Primary opcode 36: stw + {Opcode::stw, InstrFormat::kD, OpcodeGroup::kMemory, "stw", 36, 0, false}, + + // Primary opcode 37: stwu + {Opcode::stwu, InstrFormat::kD, OpcodeGroup::kMemory, "stwu", 37, 0, false}, + + // Primary opcode 38: stb + {Opcode::stb, InstrFormat::kD, OpcodeGroup::kMemory, "stb", 38, 0, false}, + + // Primary opcode 39: stbu + {Opcode::stbu, InstrFormat::kD, OpcodeGroup::kMemory, "stbu", 39, 0, false}, + + // Primary opcode 40: lhz + {Opcode::lhz, InstrFormat::kD, OpcodeGroup::kMemory, "lhz", 40, 0, false}, + + // Primary opcode 41: lhzu + {Opcode::lhzu, InstrFormat::kD, OpcodeGroup::kMemory, "lhzu", 41, 0, false}, + + // Primary opcode 44: sth + {Opcode::sth, InstrFormat::kD, OpcodeGroup::kMemory, "sth", 44, 0, false}, + + // Primary opcode 45: sthu + {Opcode::sthu, InstrFormat::kD, OpcodeGroup::kMemory, "sthu", 45, 0, false}, + + // Primary opcode 58: ld, ldu (DS format with XO) + {Opcode::ld, InstrFormat::kDS, OpcodeGroup::kMemory, "ld", 58, 0, true}, + {Opcode::ldu, InstrFormat::kDS, OpcodeGroup::kMemory, "ldu", 58, 1, true}, + + // Primary opcode 62: std, stdu (DS format with XO) + {Opcode::std, InstrFormat::kDS, OpcodeGroup::kMemory, "std", 62, 0, true}, + {Opcode::stdu, InstrFormat::kDS, OpcodeGroup::kMemory, "stdu", 62, 1, true}, + + // Primary opcode 31: Extended instructions (many ALU/logical operations) + {Opcode::cmp, InstrFormat::kX, OpcodeGroup::kGeneral, "cmp", 31, 0, true}, + {Opcode::cmpl, InstrFormat::kX, OpcodeGroup::kGeneral, "cmpl", 31, 32, true}, + {Opcode::tw, InstrFormat::kX, OpcodeGroup::kSystem, "tw", 31, 4, true}, + {Opcode::subf, InstrFormat::kXO, OpcodeGroup::kGeneral, "subf", 31, 40, true}, + {Opcode::neg, InstrFormat::kXO, OpcodeGroup::kGeneral, "neg", 31, 104, true}, + {Opcode::and_, InstrFormat::kX, OpcodeGroup::kGeneral, "and", 31, 28, true}, + {Opcode::or_, InstrFormat::kX, OpcodeGroup::kGeneral, "or", 31, 444, true}, + {Opcode::xor_, InstrFormat::kX, OpcodeGroup::kGeneral, "xor", 31, 316, true}, + {Opcode::nand, InstrFormat::kX, OpcodeGroup::kGeneral, "nand", 31, 476, true}, + {Opcode::nor, InstrFormat::kX, OpcodeGroup::kGeneral, "nor", 31, 124, true}, + {Opcode::add, InstrFormat::kXO, OpcodeGroup::kGeneral, "add", 31, 266, true}, + {Opcode::slw, InstrFormat::kX, OpcodeGroup::kGeneral, "slw", 31, 24, true}, + {Opcode::srw, InstrFormat::kX, OpcodeGroup::kGeneral, "srw", 31, 536, true}, + {Opcode::sraw, InstrFormat::kX, OpcodeGroup::kGeneral, "sraw", 31, 792, true}, + {Opcode::mfspr, InstrFormat::kXFX, OpcodeGroup::kSpecial, "mfspr", 31, 339, true}, + {Opcode::mtspr, InstrFormat::kXFX, OpcodeGroup::kSpecial, "mtspr", 31, 467, true}, + // Simplified mnemonics for SPR access (synthetic opcodes from post-decode) + {Opcode::mflr, InstrFormat::kXFX, OpcodeGroup::kSpecial, "mflr", 0, 0, false}, + {Opcode::mtlr, InstrFormat::kXFX, OpcodeGroup::kSpecial, "mtlr", 0, 0, false}, + {Opcode::mfctr, InstrFormat::kXFX, OpcodeGroup::kSpecial, "mfctr", 0, 0, false}, + {Opcode::mtctr, InstrFormat::kXFX, OpcodeGroup::kSpecial, "mtctr", 0, 0, false}, + {Opcode::mfcr, InstrFormat::kX, OpcodeGroup::kSpecial, "mfcr", 31, 19, true}, + {Opcode::mtcr, InstrFormat::kXFX, OpcodeGroup::kSpecial, "mtcrf", 31, 144, true}, + {Opcode::sync, InstrFormat::kX, OpcodeGroup::kSync, "sync", 31, 598, true}, + {Opcode::isync, InstrFormat::kXL, OpcodeGroup::kSync, "isync", 19, 150, true}, + + // Primary opcode 11: cmpi + {Opcode::cmpi, InstrFormat::kD, OpcodeGroup::kGeneral, "cmpi", 11, 0, false}, + + // Primary opcode 10: cmpli + {Opcode::cmpli, InstrFormat::kD, OpcodeGroup::kGeneral, "cmpli", 10, 0, false}, + + // Primary opcode 21: rlwinm + {Opcode::rlwinm, InstrFormat::kM, OpcodeGroup::kGeneral, "rlwinm", 21, 0, false}, + + // Primary opcode 23: rlwnm + {Opcode::rlwnm, InstrFormat::kM, OpcodeGroup::kGeneral, "rlwnm", 23, 0, false}, + + // Primary opcode 17: sc + {Opcode::sc, InstrFormat::kX, OpcodeGroup::kSystem, "sc", 17, 0, false}, + + // Primary opcode 3: twi + {Opcode::twi, InstrFormat::kD, OpcodeGroup::kSystem, "twi", 3, 0, false}, + + //========================================================================= + // Floating-Point Load/Store + //========================================================================= + {Opcode::lfs, InstrFormat::kD, OpcodeGroup::kFloat, "lfs", 48, 0, false}, + {Opcode::lfsu, InstrFormat::kD, OpcodeGroup::kFloat, "lfsu", 49, 0, false}, + {Opcode::lfd, InstrFormat::kD, OpcodeGroup::kFloat, "lfd", 50, 0, false}, + {Opcode::lfdu, InstrFormat::kD, OpcodeGroup::kFloat, "lfdu", 51, 0, false}, + {Opcode::stfs, InstrFormat::kD, OpcodeGroup::kFloat, "stfs", 52, 0, false}, + {Opcode::stfsu, InstrFormat::kD, OpcodeGroup::kFloat, "stfsu", 53, 0, false}, + {Opcode::stfd, InstrFormat::kD, OpcodeGroup::kFloat, "stfd", 54, 0, false}, + {Opcode::stfdu, InstrFormat::kD, OpcodeGroup::kFloat, "stfdu", 55, 0, false}, + {Opcode::lfsx, InstrFormat::kX, OpcodeGroup::kFloat, "lfsx", 31, 535, true}, + {Opcode::lfdx, InstrFormat::kX, OpcodeGroup::kFloat, "lfdx", 31, 599, true}, + {Opcode::stfsx, InstrFormat::kX, OpcodeGroup::kFloat, "stfsx", 31, 663, true}, + {Opcode::stfdx, InstrFormat::kX, OpcodeGroup::kFloat, "stfdx", 31, 727, true}, + + //========================================================================= + // Floating-Point Arithmetic (Primary 59 - Single Precision) + //========================================================================= + {Opcode::fadds, InstrFormat::kX, OpcodeGroup::kFloat, "fadds", 59, 21, true}, + {Opcode::fsubs, InstrFormat::kX, OpcodeGroup::kFloat, "fsubs", 59, 20, true}, + {Opcode::fmuls, InstrFormat::kX, OpcodeGroup::kFloat, "fmuls", 59, 25, true}, + {Opcode::fdivs, InstrFormat::kX, OpcodeGroup::kFloat, "fdivs", 59, 18, true}, + {Opcode::fsqrts, InstrFormat::kX, OpcodeGroup::kFloat, "fsqrts", 59, 22, true}, + {Opcode::fres, InstrFormat::kX, OpcodeGroup::kFloat, "fres", 59, 24, true}, + {Opcode::frsqrtes, InstrFormat::kX, OpcodeGroup::kFloat, "frsqrtes", 59, 26, true}, + {Opcode::fmadds, InstrFormat::kX, OpcodeGroup::kFloat, "fmadds", 59, 29, true}, + {Opcode::fmsubs, InstrFormat::kX, OpcodeGroup::kFloat, "fmsubs", 59, 28, true}, + {Opcode::fnmadds, InstrFormat::kX, OpcodeGroup::kFloat, "fnmadds", 59, 31, true}, + {Opcode::fnmsubs, InstrFormat::kX, OpcodeGroup::kFloat, "fnmsubs", 59, 30, true}, + + //========================================================================= + // Floating-Point Arithmetic (Primary 63 - Double Precision) + //========================================================================= + {Opcode::fadd, InstrFormat::kX, OpcodeGroup::kFloat, "fadd", 63, 21, true}, + {Opcode::fsub, InstrFormat::kX, OpcodeGroup::kFloat, "fsub", 63, 20, true}, + {Opcode::fmul, InstrFormat::kX, OpcodeGroup::kFloat, "fmul", 63, 25, true}, + {Opcode::fdiv, InstrFormat::kX, OpcodeGroup::kFloat, "fdiv", 63, 18, true}, + {Opcode::fsqrt, InstrFormat::kX, OpcodeGroup::kFloat, "fsqrt", 63, 22, true}, + {Opcode::fre, InstrFormat::kX, OpcodeGroup::kFloat, "fre", 63, 24, true}, + {Opcode::frsqrte, InstrFormat::kX, OpcodeGroup::kFloat, "frsqrte", 63, 26, true}, + {Opcode::fmadd, InstrFormat::kX, OpcodeGroup::kFloat, "fmadd", 63, 29, true}, + {Opcode::fmsub, InstrFormat::kX, OpcodeGroup::kFloat, "fmsub", 63, 28, true}, + {Opcode::fnmadd, InstrFormat::kX, OpcodeGroup::kFloat, "fnmadd", 63, 31, true}, + {Opcode::fnmsub, InstrFormat::kX, OpcodeGroup::kFloat, "fnmsub", 63, 30, true}, + {Opcode::fsel, InstrFormat::kX, OpcodeGroup::kFloat, "fsel", 63, 23, true}, + + //========================================================================= + // Floating-Point Move/Misc + //========================================================================= + {Opcode::fmr, InstrFormat::kX, OpcodeGroup::kFloat, "fmr", 63, 72, true}, + {Opcode::fneg, InstrFormat::kX, OpcodeGroup::kFloat, "fneg", 63, 40, true}, + {Opcode::fabs, InstrFormat::kX, OpcodeGroup::kFloat, "fabs", 63, 264, true}, + {Opcode::fnabs, InstrFormat::kX, OpcodeGroup::kFloat, "fnabs", 63, 136, true}, + + //========================================================================= + // Floating-Point Conversion + //========================================================================= + {Opcode::frsp, InstrFormat::kX, OpcodeGroup::kFloat, "frsp", 63, 12, true}, + {Opcode::fctiw, InstrFormat::kX, OpcodeGroup::kFloat, "fctiw", 63, 14, true}, + {Opcode::fctiwz, InstrFormat::kX, OpcodeGroup::kFloat, "fctiwz", 63, 15, true}, + {Opcode::fctid, InstrFormat::kX, OpcodeGroup::kFloat, "fctid", 63, 814, true}, + {Opcode::fctidz, InstrFormat::kX, OpcodeGroup::kFloat, "fctidz", 63, 815, true}, + {Opcode::fcfid, InstrFormat::kX, OpcodeGroup::kFloat, "fcfid", 63, 846, true}, + + //========================================================================= + // Floating-Point Compare + //========================================================================= + {Opcode::fcmpu, InstrFormat::kX, OpcodeGroup::kFloat, "fcmpu", 63, 0, true}, + {Opcode::fcmpo, InstrFormat::kX, OpcodeGroup::kFloat, "fcmpo", 63, 32, true}, + + //========================================================================= + // Floating-Point Status/Control + //========================================================================= + {Opcode::mffs, InstrFormat::kX, OpcodeGroup::kFloat, "mffs", 63, 583, true}, + {Opcode::mtfsf, InstrFormat::kX, OpcodeGroup::kFloat, "mtfsf", 63, 711, true}, + {Opcode::mtfsfi, InstrFormat::kX, OpcodeGroup::kFloat, "mtfsfi", 63, 134, true}, + {Opcode::mtfsb0, InstrFormat::kX, OpcodeGroup::kFloat, "mtfsb0", 63, 70, true}, + {Opcode::mtfsb1, InstrFormat::kX, OpcodeGroup::kFloat, "mtfsb1", 63, 38, true}, + + //========================================================================= + // VMX Load/Store + //========================================================================= + {Opcode::lvx, InstrFormat::kX, OpcodeGroup::kVector, "lvx", 4, 103, true}, + {Opcode::lvxl, InstrFormat::kX, OpcodeGroup::kVector, "lvxl", 4, 359, true}, + {Opcode::stvx, InstrFormat::kX, OpcodeGroup::kVector, "stvx", 4, 231, true}, + {Opcode::stvxl, InstrFormat::kX, OpcodeGroup::kVector, "stvxl", 4, 487, true}, + {Opcode::lvlx, InstrFormat::kX, OpcodeGroup::kVector, "lvlx", 4, 39, true}, + {Opcode::lvrx, InstrFormat::kX, OpcodeGroup::kVector, "lvrx", 4, 71, true}, + {Opcode::stvlx, InstrFormat::kX, OpcodeGroup::kVector, "stvlx", 4, 167, true}, + {Opcode::stvrx, InstrFormat::kX, OpcodeGroup::kVector, "stvrx", 4, 199, true}, + {Opcode::lvsl, InstrFormat::kX, OpcodeGroup::kVector, "lvsl", 4, 6, true}, + {Opcode::lvsr, InstrFormat::kX, OpcodeGroup::kVector, "lvsr", 4, 38, true}, + + //========================================================================= + // VMX Floating-Point Arithmetic + //========================================================================= + {Opcode::vaddfp, InstrFormat::kX, OpcodeGroup::kVector, "vaddfp", 4, 10, true}, + {Opcode::vsubfp, InstrFormat::kX, OpcodeGroup::kVector, "vsubfp", 4, 74, true}, + {Opcode::vmaddfp, InstrFormat::kX, OpcodeGroup::kVector, "vmaddfp", 4, 32, true}, + {Opcode::vnmsubfp, InstrFormat::kX, OpcodeGroup::kVector, "vnmsubfp", 4, 33, true}, + {Opcode::vmaxfp, InstrFormat::kX, OpcodeGroup::kVector, "vmaxfp", 4, 1034, true}, + {Opcode::vminfp, InstrFormat::kX, OpcodeGroup::kVector, "vminfp", 4, 1098, true}, + {Opcode::vrsqrtefp, InstrFormat::kX, OpcodeGroup::kVector, "vrsqrtefp", 4, 330, true}, + {Opcode::vrefp, InstrFormat::kX, OpcodeGroup::kVector, "vrefp", 4, 266, true}, + {Opcode::vlogfp, InstrFormat::kX, OpcodeGroup::kVector, "vlogfp", 4, 458, true}, + {Opcode::vexptefp, InstrFormat::kX, OpcodeGroup::kVector, "vexptefp", 4, 394, true}, + + //========================================================================= + // VMX Integer Arithmetic + //========================================================================= + {Opcode::vaddubm, InstrFormat::kX, OpcodeGroup::kVector, "vaddubm", 4, 0, true}, + {Opcode::vadduhm, InstrFormat::kX, OpcodeGroup::kVector, "vadduhm", 4, 64, true}, + {Opcode::vadduwm, InstrFormat::kX, OpcodeGroup::kVector, "vadduwm", 4, 128, true}, + {Opcode::vsububm, InstrFormat::kX, OpcodeGroup::kVector, "vsububm", 4, 1024, true}, + {Opcode::vsubuhm, InstrFormat::kX, OpcodeGroup::kVector, "vsubuhm", 4, 1088, true}, + {Opcode::vsubuwm, InstrFormat::kX, OpcodeGroup::kVector, "vsubuwm", 4, 1152, true}, + {Opcode::vmuloub, InstrFormat::kX, OpcodeGroup::kVector, "vmuloub", 4, 8, true}, + {Opcode::vmulouh, InstrFormat::kX, OpcodeGroup::kVector, "vmulouh", 4, 72, true}, + {Opcode::vmuleub, InstrFormat::kX, OpcodeGroup::kVector, "vmuleub", 4, 264, true}, + {Opcode::vmuleuh, InstrFormat::kX, OpcodeGroup::kVector, "vmuleuh", 4, 328, true}, + {Opcode::vavgub, InstrFormat::kX, OpcodeGroup::kVector, "vavgub", 4, 1026, true}, + {Opcode::vavguh, InstrFormat::kX, OpcodeGroup::kVector, "vavguh", 4, 1090, true}, + {Opcode::vavguw, InstrFormat::kX, OpcodeGroup::kVector, "vavguw", 4, 1154, true}, + + //========================================================================= + // VMX Logical + //========================================================================= + {Opcode::vand, InstrFormat::kX, OpcodeGroup::kVector, "vand", 4, 1028, true}, + {Opcode::vandc, InstrFormat::kX, OpcodeGroup::kVector, "vandc", 4, 1092, true}, + {Opcode::vor, InstrFormat::kX, OpcodeGroup::kVector, "vor", 4, 1156, true}, + {Opcode::vxor, InstrFormat::kX, OpcodeGroup::kVector, "vxor", 4, 1220, true}, + {Opcode::vnor, InstrFormat::kX, OpcodeGroup::kVector, "vnor", 4, 1284, true}, + {Opcode::vsel, InstrFormat::kX, OpcodeGroup::kVector, "vsel", 4, 42, true}, + + //========================================================================= + // VMX Compare (Floating-Point) + //========================================================================= + {Opcode::vcmpeqfp, InstrFormat::kX, OpcodeGroup::kVector, "vcmpeqfp", 4, 198, true}, + {Opcode::vcmpgefp, InstrFormat::kX, OpcodeGroup::kVector, "vcmpgefp", 4, 454, true}, + {Opcode::vcmpgtfp, InstrFormat::kX, OpcodeGroup::kVector, "vcmpgtfp", 4, 710, true}, + {Opcode::vcmpbfp, InstrFormat::kX, OpcodeGroup::kVector, "vcmpbfp", 4, 966, true}, + {Opcode::vcmpeqfp_, InstrFormat::kX, OpcodeGroup::kVector, "vcmpeqfp.", 4, 198, true}, + {Opcode::vcmpgefp_, InstrFormat::kX, OpcodeGroup::kVector, "vcmpgefp.", 4, 454, true}, + {Opcode::vcmpgtfp_, InstrFormat::kX, OpcodeGroup::kVector, "vcmpgtfp.", 4, 710, true}, + + //========================================================================= + // VMX Compare (Integer) + //========================================================================= + {Opcode::vcmpequb, InstrFormat::kX, OpcodeGroup::kVector, "vcmpequb", 4, 6, true}, + {Opcode::vcmpequh, InstrFormat::kX, OpcodeGroup::kVector, "vcmpequh", 4, 70, true}, + {Opcode::vcmpequw, InstrFormat::kX, OpcodeGroup::kVector, "vcmpequw", 4, 134, true}, + {Opcode::vcmpgtub, InstrFormat::kX, OpcodeGroup::kVector, "vcmpgtub", 4, 518, true}, + {Opcode::vcmpgtuh, InstrFormat::kX, OpcodeGroup::kVector, "vcmpgtuh", 4, 582, true}, + {Opcode::vcmpgtuw, InstrFormat::kX, OpcodeGroup::kVector, "vcmpgtuw", 4, 646, true}, + {Opcode::vcmpgtsb, InstrFormat::kX, OpcodeGroup::kVector, "vcmpgtsb", 4, 774, true}, + {Opcode::vcmpgtsh, InstrFormat::kX, OpcodeGroup::kVector, "vcmpgtsh", 4, 838, true}, + {Opcode::vcmpgtsw, InstrFormat::kX, OpcodeGroup::kVector, "vcmpgtsw", 4, 902, true}, + + //========================================================================= + // VMX Permute/Merge + //========================================================================= + {Opcode::vperm, InstrFormat::kX, OpcodeGroup::kVector, "vperm", 4, 43, true}, + {Opcode::vmrghb, InstrFormat::kX, OpcodeGroup::kVector, "vmrghb", 4, 12, true}, + {Opcode::vmrghh, InstrFormat::kX, OpcodeGroup::kVector, "vmrghh", 4, 76, true}, + {Opcode::vmrghw, InstrFormat::kX, OpcodeGroup::kVector, "vmrghw", 4, 140, true}, + {Opcode::vmrglb, InstrFormat::kX, OpcodeGroup::kVector, "vmrglb", 4, 268, true}, + {Opcode::vmrglh, InstrFormat::kX, OpcodeGroup::kVector, "vmrglh", 4, 332, true}, + {Opcode::vmrglw, InstrFormat::kX, OpcodeGroup::kVector, "vmrglw", 4, 396, true}, + + //========================================================================= + // VMX Pack/Unpack + //========================================================================= + {Opcode::vpkuhum, InstrFormat::kX, OpcodeGroup::kVector, "vpkuhum", 4, 14, true}, + {Opcode::vpkuwum, InstrFormat::kX, OpcodeGroup::kVector, "vpkuwum", 4, 78, true}, + {Opcode::vpkuhus, InstrFormat::kX, OpcodeGroup::kVector, "vpkuhus", 4, 142, true}, + {Opcode::vpkuwus, InstrFormat::kX, OpcodeGroup::kVector, "vpkuwus", 4, 206, true}, + {Opcode::vpkshus, InstrFormat::kX, OpcodeGroup::kVector, "vpkshus", 4, 270, true}, + {Opcode::vpkswus, InstrFormat::kX, OpcodeGroup::kVector, "vpkswus", 4, 334, true}, + {Opcode::vpkshss, InstrFormat::kX, OpcodeGroup::kVector, "vpkshss", 4, 398, true}, + {Opcode::vpkswss, InstrFormat::kX, OpcodeGroup::kVector, "vpkswss", 4, 462, true}, + {Opcode::vupkhsb, InstrFormat::kX, OpcodeGroup::kVector, "vupkhsb", 4, 526, true}, + {Opcode::vupkhsh, InstrFormat::kX, OpcodeGroup::kVector, "vupkhsh", 4, 590, true}, + {Opcode::vupklsb, InstrFormat::kX, OpcodeGroup::kVector, "vupklsb", 4, 654, true}, + {Opcode::vupklsh, InstrFormat::kX, OpcodeGroup::kVector, "vupklsh", 4, 718, true}, + + //========================================================================= + // VMX Splat + //========================================================================= + {Opcode::vspltb, InstrFormat::kX, OpcodeGroup::kVector, "vspltb", 4, 524, true}, + {Opcode::vsplth, InstrFormat::kX, OpcodeGroup::kVector, "vsplth", 4, 588, true}, + {Opcode::vspltw, InstrFormat::kX, OpcodeGroup::kVector, "vspltw", 4, 652, true}, + {Opcode::vspltisb, InstrFormat::kX, OpcodeGroup::kVector, "vspltisb", 4, 780, true}, + {Opcode::vspltish, InstrFormat::kX, OpcodeGroup::kVector, "vspltish", 4, 844, true}, + {Opcode::vspltisw, InstrFormat::kX, OpcodeGroup::kVector, "vspltisw", 4, 908, true}, + + //========================================================================= + // VMX Shift/Rotate + //========================================================================= + {Opcode::vslb, InstrFormat::kX, OpcodeGroup::kVector, "vslb", 4, 260, true}, + {Opcode::vslh, InstrFormat::kX, OpcodeGroup::kVector, "vslh", 4, 324, true}, + {Opcode::vslw, InstrFormat::kX, OpcodeGroup::kVector, "vslw", 4, 388, true}, + {Opcode::vsrb, InstrFormat::kX, OpcodeGroup::kVector, "vsrb", 4, 516, true}, + {Opcode::vsrh, InstrFormat::kX, OpcodeGroup::kVector, "vsrh", 4, 580, true}, + {Opcode::vsrw, InstrFormat::kX, OpcodeGroup::kVector, "vsrw", 4, 644, true}, + {Opcode::vsrab, InstrFormat::kX, OpcodeGroup::kVector, "vsrab", 4, 772, true}, + {Opcode::vsrah, InstrFormat::kX, OpcodeGroup::kVector, "vsrah", 4, 836, true}, + {Opcode::vsraw, InstrFormat::kX, OpcodeGroup::kVector, "vsraw", 4, 900, true}, + {Opcode::vrlb, InstrFormat::kX, OpcodeGroup::kVector, "vrlb", 4, 4, true}, + {Opcode::vrlh, InstrFormat::kX, OpcodeGroup::kVector, "vrlh", 4, 68, true}, + {Opcode::vrlw, InstrFormat::kX, OpcodeGroup::kVector, "vrlw", 4, 132, true}, + {Opcode::vsl, InstrFormat::kX, OpcodeGroup::kVector, "vsl", 4, 452, true}, + {Opcode::vsr, InstrFormat::kX, OpcodeGroup::kVector, "vsr", 4, 708, true}, + {Opcode::vslo, InstrFormat::kX, OpcodeGroup::kVector, "vslo", 4, 1036, true}, + {Opcode::vsro, InstrFormat::kX, OpcodeGroup::kVector, "vsro", 4, 1100, true}, + + //========================================================================= + // VMX Conversion + //========================================================================= + {Opcode::vcfux, InstrFormat::kX, OpcodeGroup::kVector, "vcfux", 4, 778, true}, + {Opcode::vcfsx, InstrFormat::kX, OpcodeGroup::kVector, "vcfsx", 4, 842, true}, + {Opcode::vctuxs, InstrFormat::kX, OpcodeGroup::kVector, "vctuxs", 4, 906, true}, + {Opcode::vctsxs, InstrFormat::kX, OpcodeGroup::kVector, "vctsxs", 4, 970, true}, + {Opcode::vrfin, InstrFormat::kX, OpcodeGroup::kVector, "vrfin", 4, 522, true}, + {Opcode::vrfiz, InstrFormat::kX, OpcodeGroup::kVector, "vrfiz", 4, 586, true}, + {Opcode::vrfip, InstrFormat::kX, OpcodeGroup::kVector, "vrfip", 4, 650, true}, + {Opcode::vrfim, InstrFormat::kX, OpcodeGroup::kVector, "vrfim", 4, 714, true}, + + //========================================================================= + // VMX Status/Control + //========================================================================= + {Opcode::mfvscr, InstrFormat::kX, OpcodeGroup::kVector, "mfvscr", 4, 1540, true}, + {Opcode::mtvscr, InstrFormat::kX, OpcodeGroup::kVector, "mtvscr", 4, 1604, true}, + + //========================================================================= + // VMX128 (Xbox 360 Extensions) + //========================================================================= + {Opcode::lvx128, InstrFormat::kX, OpcodeGroup::kVector, "lvx128", 4, 0, true}, + {Opcode::stvx128, InstrFormat::kX, OpcodeGroup::kVector, "stvx128", 4, 0, true}, + {Opcode::lvlx128, InstrFormat::kX, OpcodeGroup::kVector, "lvlx128", 4, 0, true}, + {Opcode::lvrx128, InstrFormat::kX, OpcodeGroup::kVector, "lvrx128", 4, 0, true}, + {Opcode::stvlx128, InstrFormat::kX, OpcodeGroup::kVector, "stvlx128", 4, 0, true}, + {Opcode::stvrx128, InstrFormat::kX, OpcodeGroup::kVector, "stvrx128", 4, 0, true}, + {Opcode::lvlxl128, InstrFormat::kX, OpcodeGroup::kVector, "lvlxl128", 4, 0, true}, + {Opcode::lvrxl128, InstrFormat::kX, OpcodeGroup::kVector, "lvrxl128", 4, 0, true}, + {Opcode::stvlxl128, InstrFormat::kX, OpcodeGroup::kVector, "stvlxl128", 4, 0, true}, + {Opcode::stvrxl128, InstrFormat::kX, OpcodeGroup::kVector, "stvrxl128", 4, 0, true}, + {Opcode::vmulfp128, InstrFormat::kX, OpcodeGroup::kVector, "vmulfp128", 4, 0, true}, + {Opcode::vdot3fp128, InstrFormat::kX, OpcodeGroup::kVector, "vdot3fp128", 4, 0, true}, + {Opcode::vdot4fp128, InstrFormat::kX, OpcodeGroup::kVector, "vdot4fp128", 4, 0, true}, + {Opcode::vmsum3fp128, InstrFormat::kX, OpcodeGroup::kVector, "vmsum3fp128", 4, 0, true}, + {Opcode::vmsum4fp128, InstrFormat::kX, OpcodeGroup::kVector, "vmsum4fp128", 4, 0, true}, + {Opcode::vperm128, InstrFormat::kX, OpcodeGroup::kVector, "vperm128", 4, 0, true}, + {Opcode::vmrgow128, InstrFormat::kX, OpcodeGroup::kVector, "vmrgow128", 4, 0, true}, + {Opcode::vmrgew128, InstrFormat::kX, OpcodeGroup::kVector, "vmrgew128", 4, 0, true}, + {Opcode::vrlw128, InstrFormat::kX, OpcodeGroup::kVector, "vrlw128", 4, 0, true}, + {Opcode::vslw128, InstrFormat::kX, OpcodeGroup::kVector, "vslw128", 4, 0, true}, + {Opcode::vsrw128, InstrFormat::kX, OpcodeGroup::kVector, "vsrw128", 4, 0, true}, + {Opcode::vsraw128, InstrFormat::kX, OpcodeGroup::kVector, "vsraw128", 4, 0, true}, + {Opcode::vupkd3d128, InstrFormat::kX, OpcodeGroup::kVector, "vupkd3d128", 4, 0, true}, + {Opcode::vpkd3d128, InstrFormat::kX, OpcodeGroup::kVector, "vpkd3d128", 4, 0, true}, + {Opcode::vorc, InstrFormat::kX, OpcodeGroup::kVector, "vorc", 4, 0, true}, + + //========================================================================= + // Additional Integer Operations + //========================================================================= + {Opcode::mulli, InstrFormat::kD, OpcodeGroup::kGeneral, "mulli", 7, 0, false}, + {Opcode::subfic, InstrFormat::kD, OpcodeGroup::kGeneral, "subfic", 8, 0, false}, + {Opcode::addic, InstrFormat::kD, OpcodeGroup::kGeneral, "addic", 12, 0, false}, + {Opcode::addic_, InstrFormat::kD, OpcodeGroup::kGeneral, "addic.", 13, 0, false}, + {Opcode::lha, InstrFormat::kD, OpcodeGroup::kMemory, "lha", 42, 0, false}, + {Opcode::mullw, InstrFormat::kXO, OpcodeGroup::kGeneral, "mullw", 31, 235, true}, + {Opcode::mulhw, InstrFormat::kXO, OpcodeGroup::kGeneral, "mulhw", 31, 75, true}, + {Opcode::mulhwu, InstrFormat::kXO, OpcodeGroup::kGeneral, "mulhwu", 31, 11, true}, + {Opcode::divw, InstrFormat::kXO, OpcodeGroup::kGeneral, "divw", 31, 491, true}, + {Opcode::divwu, InstrFormat::kXO, OpcodeGroup::kGeneral, "divwu", 31, 459, true}, + {Opcode::cntlzw, InstrFormat::kX, OpcodeGroup::kGeneral, "cntlzw", 31, 26, true}, + {Opcode::srawi, InstrFormat::kX, OpcodeGroup::kGeneral, "srawi", 31, 824, true}, + {Opcode::extsb, InstrFormat::kX, OpcodeGroup::kGeneral, "extsb", 31, 954, true}, + {Opcode::extsh, InstrFormat::kX, OpcodeGroup::kGeneral, "extsh", 31, 922, true}, + + //========================================================================= + // Indexed Memory Operations + //========================================================================= + {Opcode::lbzx, InstrFormat::kX, OpcodeGroup::kMemory, "lbzx", 31, 87, true}, + {Opcode::lhzx, InstrFormat::kX, OpcodeGroup::kMemory, "lhzx", 31, 279, true}, + {Opcode::lhax, InstrFormat::kX, OpcodeGroup::kMemory, "lhax", 31, 311, true}, + {Opcode::lwzx, InstrFormat::kX, OpcodeGroup::kMemory, "lwzx", 31, 23, true}, + {Opcode::ldx, InstrFormat::kX, OpcodeGroup::kMemory, "ldx", 31, 21, true}, + {Opcode::stbx, InstrFormat::kX, OpcodeGroup::kMemory, "stbx", 31, 215, true}, + {Opcode::sthx, InstrFormat::kX, OpcodeGroup::kMemory, "sthx", 31, 407, true}, + {Opcode::stwx, InstrFormat::kX, OpcodeGroup::kMemory, "stwx", 31, 151, true}, + {Opcode::stdx, InstrFormat::kX, OpcodeGroup::kMemory, "stdx", 31, 149, true}, +}}; + +// Map for fast lookup: (primary_opcode, extended_opcode) -> index +static std::unordered_map g_opcode_lookup_map; +static std::once_flag g_opcode_init_flag; + +// Initialize lookup map implementation +static void init_opcode_lookup_map_impl() { + g_opcode_lookup_map.reserve(g_opcode_table.size()); + for (size_t i = 0; i < g_opcode_table.size(); ++i) { + const auto& info = g_opcode_table[i]; + if (info.opcode == Opcode::kUnknown) + continue; + + u64 key = ((u64)info.primary_opcode << 32) | info.extended_opcode; + g_opcode_lookup_map[key] = i; + } +} + +// Thread-safe initialization (called once) +static void init_opcode_lookup_map() { + std::call_once(g_opcode_init_flag, init_opcode_lookup_map_impl); +} + +//============================================================================= +// Public API +//============================================================================= + +Opcode lookup_opcode(u32 code) { + init_opcode_lookup_map(); + + // Extract primary opcode (bits 0-5) + u32 primary = extract_bits(code, 0, 6); + + // Handle instructions with no extended opcode + switch (primary) { + case 3: + return Opcode::twi; + case 7: + return Opcode::mulli; + case 8: + return Opcode::subfic; + case 10: + return Opcode::cmpli; + case 11: + return Opcode::cmpi; + case 12: + return Opcode::addic; + case 13: + return Opcode::addic_; + case 14: + return Opcode::addi; + case 15: + return Opcode::addis; + case 16: { + // Conditional branch - check AA (bit 30) and LK (bit 31) + // Note: PPC bit numbering is MSB=0, so bit 30 is position 1, bit 31 is position 0 + bool aa = (code >> 1) & 1; // Absolute address + bool lk = code & 1; // Link + if (lk && aa) + return Opcode::bcla; + if (lk) + return Opcode::bcl; + if (aa) + return Opcode::bca; + return Opcode::bc; + } + case 17: + return Opcode::sc; + case 18: { + // Unconditional branch - check AA (bit 30) and LK (bit 31) + bool aa = (code >> 1) & 1; // Absolute address + bool lk = code & 1; // Link + if (lk && aa) + return Opcode::bla; + if (lk) + return Opcode::bl; + if (aa) + return Opcode::ba; + return Opcode::b; + } + case 21: + return Opcode::rlwinm; + case 23: + return Opcode::rlwnm; + case 24: + return Opcode::ori; + case 25: + return Opcode::oris; + case 26: + return Opcode::xori; + case 27: + return Opcode::xoris; + case 28: + return Opcode::andi_; + case 29: + return Opcode::andis_; + case 32: + return Opcode::lwz; + case 33: + return Opcode::lwzu; + case 34: + return Opcode::lbz; + case 35: + return Opcode::lbzu; + case 36: + return Opcode::stw; + case 37: + return Opcode::stwu; + case 38: + return Opcode::stb; + case 39: + return Opcode::stbu; + case 40: + return Opcode::lhz; + case 41: + return Opcode::lhzu; + case 42: + return Opcode::lha; + case 44: + return Opcode::sth; + case 45: + return Opcode::sthu; + + // Floating-point load/store + case 48: + return Opcode::lfs; + case 49: + return Opcode::lfsu; + case 50: + return Opcode::lfd; + case 51: + return Opcode::lfdu; + case 52: + return Opcode::stfs; + case 53: + return Opcode::stfsu; + case 54: + return Opcode::stfd; + case 55: + return Opcode::stfdu; + } + + // Handle instructions with extended opcodes + u32 extended = 0; + if (primary == 19) { + // XL format: extended opcode in bits 21-30 + extended = extract_bits(code, 21, 10); + bool lk = code & 1; // LK bit is bit 31 (position 0) + if (extended == 16) + return lk ? Opcode::bclrl : Opcode::bclr; + if (extended == 528) + return lk ? Opcode::bcctrl : Opcode::bcctr; + if (extended == 150) + return Opcode::isync; + } else if (primary == 31) { + // X/XO/XFX format: extended opcode in bits 21-30 + extended = extract_bits(code, 21, 10); + + // Map extended opcodes for primary 31 + switch (extended) { + case 0: + return Opcode::cmp; + case 4: + return Opcode::tw; + case 11: + return Opcode::mulhwu; + case 19: + return Opcode::mfcr; + case 23: + return Opcode::lwzx; + case 24: + return Opcode::slw; + case 26: + return Opcode::cntlzw; + case 28: + return Opcode::and_; + case 32: + return Opcode::cmpl; + case 40: + return Opcode::subf; + case 60: + return Opcode::andc; + case 75: + return Opcode::mulhw; + case 87: + return Opcode::lbzx; + case 104: + return Opcode::neg; + case 124: + return Opcode::nor; + case 144: + return Opcode::mtcr; + case 151: + return Opcode::stwx; + case 215: + return Opcode::stbx; + case 235: + return Opcode::mullw; + case 266: + return Opcode::add; + case 279: + return Opcode::lhzx; + case 284: + return Opcode::eqv; + case 311: + return Opcode::lhax; + case 316: + return Opcode::xor_; + case 339: + return Opcode::mfspr; + case 407: + return Opcode::sthx; + case 412: + return Opcode::orc; + case 444: + return Opcode::or_; + case 459: + return Opcode::divwu; + case 467: + return Opcode::mtspr; + case 476: + return Opcode::nand; + case 491: + return Opcode::divw; + case 536: + return Opcode::srw; + case 598: + return Opcode::sync; + case 792: + return Opcode::sraw; + case 824: + return Opcode::srawi; + case 922: + return Opcode::extsh; + case 954: + return Opcode::extsb; + } + } else if (primary == 58) { + // DS format: XO in bits 30-31 + extended = extract_bits(code, 30, 2); + if (extended == 0) + return Opcode::ld; + if (extended == 1) + return Opcode::ldu; + } else if (primary == 62) { + // DS format: XO in bits 30-31 + extended = extract_bits(code, 30, 2); + if (extended == 0) + return Opcode::std; + if (extended == 1) + return Opcode::stdu; + } else if (primary == 59) { + // Single-precision floating-point (A-form): extended in bits 26-30 + extended = extract_bits(code, 26, 5); + switch (extended) { + case 18: + return Opcode::fdivs; + case 20: + return Opcode::fsubs; + case 21: + return Opcode::fadds; + case 22: + return Opcode::fsqrts; + case 24: + return Opcode::fres; + case 25: + return Opcode::fmuls; + case 26: + return Opcode::frsqrtes; + case 28: + return Opcode::fmsubs; + case 29: + return Opcode::fmadds; + case 30: + return Opcode::fnmsubs; + case 31: + return Opcode::fnmadds; + } + } else if (primary == 63) { + // Double-precision floating-point: check both X-form and A-form + // First try X-form extended opcode (bits 21-30) + extended = extract_bits(code, 21, 10); + switch (extended) { + case 0: + return Opcode::fcmpu; + case 12: + return Opcode::frsp; + case 14: + return Opcode::fctiw; + case 15: + return Opcode::fctiwz; + case 32: + return Opcode::fcmpo; + case 40: + return Opcode::fneg; + case 72: + return Opcode::fmr; + case 136: + return Opcode::fnabs; + case 264: + return Opcode::fabs; + case 583: + return Opcode::mffs; + case 711: + return Opcode::mtfsf; + case 814: + return Opcode::fctid; + case 815: + return Opcode::fctidz; + case 846: + return Opcode::fcfid; + } + // Try A-form extended opcode (bits 26-30) + extended = extract_bits(code, 26, 5); + switch (extended) { + case 18: + return Opcode::fdiv; + case 20: + return Opcode::fsub; + case 21: + return Opcode::fadd; + case 22: + return Opcode::fsqrt; + case 23: + return Opcode::fsel; + case 24: + return Opcode::fre; + case 25: + return Opcode::fmul; + case 26: + return Opcode::frsqrte; + case 28: + return Opcode::fmsub; + case 29: + return Opcode::fmadd; + case 30: + return Opcode::fnmsub; + case 31: + return Opcode::fnmadd; + } + } else if (primary == 4) { + // VMX/AltiVec instructions (primary opcode 4) + // Try VA-form first (bits 26-31, 6-bit XO) + extended = extract_bits(code, 26, 6); + switch (extended) { + case 32: + return Opcode::vmaddfp; // vmaddfp vD, vA, vC, vB + case 33: + return Opcode::vnmsubfp; // vnmsubfp vD, vA, vC, vB + case 43: + return Opcode::vperm; // vperm vD, vA, vB, vC + case 44: + return Opcode::vsel; // vsel vD, vA, vB, vC + } + + // Try VX-form (bits 21-31, 11-bit XO) + extended = extract_bits(code, 21, 11); + switch (extended) { + // Vector load/store + case 7: + return Opcode::lvx; // lvx vD, rA, rB (XO=7 is lvebx, lvx is 103) + case 39: + return Opcode::lvlx; // lvlx vD, rA, rB + case 71: + return Opcode::lvrx; // lvrx vD, rA, rB + case 103: + return Opcode::lvx; // lvx vD, rA, rB + case 135: + return Opcode::stvx; // stvx vS, rA, rB + case 167: + return Opcode::stvlx; // stvlx vS, rA, rB + case 199: + return Opcode::stvrx; // stvrx vS, rA, rB + case 231: + return Opcode::stvx; // stvx vS, rA, rB + case 359: + return Opcode::lvxl; // lvxl vD, rA, rB + case 487: + return Opcode::stvxl; // stvxl vS, rA, rB + case 6: + return Opcode::lvsl; // lvsl vD, rA, rB + case 38: + return Opcode::lvsr; // lvsr vD, rA, rB + + // Vector floating-point arithmetic + case 10: + return Opcode::vaddfp; // vaddfp vD, vA, vB + case 74: + return Opcode::vsubfp; // vsubfp vD, vA, vB + case 1034: + return Opcode::vmaxfp; // vmaxfp vD, vA, vB + case 1098: + return Opcode::vminfp; // vminfp vD, vA, vB + case 266: + return Opcode::vrsqrtefp; // vrsqrtefp vD, vB + case 330: + return Opcode::vrefp; // vrefp vD, vB + case 394: + return Opcode::vlogfp; // vlogfp vD, vB + case 458: + return Opcode::vexptefp; // vexptefp vD, vB + + // Vector integer arithmetic + case 0: + return Opcode::vaddubm; // vaddubm vD, vA, vB + case 64: + return Opcode::vadduhm; // vadduhm vD, vA, vB + case 128: + return Opcode::vadduwm; // vadduwm vD, vA, vB + case 1024: + return Opcode::vsububm; // vsububm vD, vA, vB + case 1088: + return Opcode::vsubuhm; // vsubuhm vD, vA, vB + case 1152: + return Opcode::vsubuwm; // vsubuwm vD, vA, vB + case 8: + return Opcode::vmuloub; // vmuloub vD, vA, vB + case 72: + return Opcode::vmulouh; // vmulouh vD, vA, vB + case 264: + return Opcode::vmuleub; // vmuleub vD, vA, vB + case 328: + return Opcode::vmuleuh; // vmuleuh vD, vA, vB + case 1026: + return Opcode::vavgub; // vavgub vD, vA, vB + case 1090: + return Opcode::vavguh; // vavguh vD, vA, vB + case 1154: + return Opcode::vavguw; // vavguw vD, vA, vB + + // Vector logical + case 1028: + return Opcode::vand; // vand vD, vA, vB + case 1092: + return Opcode::vandc; // vandc vD, vA, vB + case 1156: + return Opcode::vor; // vor vD, vA, vB + case 1220: + return Opcode::vxor; // vxor vD, vA, vB + case 1284: + return Opcode::vnor; // vnor vD, vA, vB + + // Vector merge + case 12: + return Opcode::vmrghb; // vmrghb vD, vA, vB + case 76: + return Opcode::vmrghh; // vmrghh vD, vA, vB + case 140: + return Opcode::vmrghw; // vmrghw vD, vA, vB + case 268: + return Opcode::vmrglb; // vmrglb vD, vA, vB + case 332: + return Opcode::vmrglh; // vmrglh vD, vA, vB + case 396: + return Opcode::vmrglw; // vmrglw vD, vA, vB + + // Vector pack/unpack + case 14: + return Opcode::vpkuhum; // vpkuhum vD, vA, vB + case 78: + return Opcode::vpkuwum; // vpkuwum vD, vA, vB + case 142: + return Opcode::vpkuhus; // vpkuhus vD, vA, vB + case 206: + return Opcode::vpkuwus; // vpkuwus vD, vA, vB + case 270: + return Opcode::vpkshus; // vpkshus vD, vA, vB + case 334: + return Opcode::vpkswus; // vpkswus vD, vA, vB + case 398: + return Opcode::vpkshss; // vpkshss vD, vA, vB + case 462: + return Opcode::vpkswss; // vpkswss vD, vA, vB + case 526: + return Opcode::vupkhsb; // vupkhsb vD, vB + case 590: + return Opcode::vupkhsh; // vupkhsh vD, vB + case 654: + return Opcode::vupklsb; // vupklsb vD, vB + case 718: + return Opcode::vupklsh; // vupklsh vD, vB + + // Vector splat + case 524: + return Opcode::vspltb; // vspltb vD, vB, UIMM + case 588: + return Opcode::vsplth; // vsplth vD, vB, UIMM + case 652: + return Opcode::vspltw; // vspltw vD, vB, UIMM + case 780: + return Opcode::vspltisb; // vspltisb vD, SIMM + case 844: + return Opcode::vspltish; // vspltish vD, SIMM + case 908: + return Opcode::vspltisw; // vspltisw vD, SIMM + + // Vector shift/rotate + case 260: + return Opcode::vslb; // vslb vD, vA, vB + case 324: + return Opcode::vslh; // vslh vD, vA, vB + case 388: + return Opcode::vslw; // vslw vD, vA, vB + case 516: + return Opcode::vsrb; // vsrb vD, vA, vB + case 580: + return Opcode::vsrh; // vsrh vD, vA, vB + case 644: + return Opcode::vsrw; // vsrw vD, vA, vB + case 772: + return Opcode::vsrab; // vsrab vD, vA, vB + case 836: + return Opcode::vsrah; // vsrah vD, vA, vB + case 900: + return Opcode::vsraw; // vsraw vD, vA, vB + case 4: + return Opcode::vrlb; // vrlb vD, vA, vB + case 68: + return Opcode::vrlh; // vrlh vD, vA, vB + case 132: + return Opcode::vrlw; // vrlw vD, vA, vB + case 452: + return Opcode::vsl; // vsl vD, vA, vB + case 708: + return Opcode::vsr; // vsr vD, vA, vB + case 1036: + return Opcode::vslo; // vslo vD, vA, vB + case 1100: + return Opcode::vsro; // vsro vD, vA, vB + + // Vector conversion + case 778: + return Opcode::vcfux; // vcfux vD, vB, UIMM + case 842: + return Opcode::vcfsx; // vcfsx vD, vB, UIMM + case 906: + return Opcode::vctuxs; // vctuxs vD, vB, UIMM + case 970: + return Opcode::vctsxs; // vctsxs vD, vB, UIMM + case 522: + return Opcode::vrfin; // vrfin vD, vB + case 586: + return Opcode::vrfiz; // vrfiz vD, vB + case 650: + return Opcode::vrfip; // vrfip vD, vB + case 714: + return Opcode::vrfim; // vrfim vD, vB + + // Vector status/control + case 1540: + return Opcode::mfvscr; // mfvscr vD + case 1604: + return Opcode::mtvscr; // mtvscr vB + } + + // Try VXR-form for compare instructions (bits 21-30, 10-bit XO with Rc at 31) + extended = extract_bits(code, 21, 10); + u32 rc = extract_bits(code, 31, 1); + switch (extended) { + case 198: + return rc ? Opcode::vcmpeqfp_ : Opcode::vcmpeqfp; + case 454: + return rc ? Opcode::vcmpgefp_ : Opcode::vcmpgefp; + case 710: + return rc ? Opcode::vcmpgtfp_ : Opcode::vcmpgtfp; + case 966: + return Opcode::vcmpbfp; + case 6: + return Opcode::vcmpequb; + case 70: + return Opcode::vcmpequh; + case 134: + return Opcode::vcmpequw; + case 518: + return Opcode::vcmpgtub; + case 582: + return Opcode::vcmpgtuh; + case 646: + return Opcode::vcmpgtuw; + case 774: + return Opcode::vcmpgtsb; + case 838: + return Opcode::vcmpgtsh; + case 902: + return Opcode::vcmpgtsw; + } + + // VMX128 Load/Store instructions (Xbox 360 extension) + // These use primary opcode 4 with bits 30-31 = 11 (value 3) + u32 bits_30_31 = code & 0x3; // Extract bits 30-31 + if (bits_30_31 == 3) { + // VMX128 load/store format: bits 21-27 contain extended opcode + u32 vmx128_xo = extract_bits(code, 21, 7); + switch (vmx128_xo) { + case 0: + return Opcode::lvsl128; // 0000000 + case 4: + return Opcode::lvsr128; // 0000100 + case 8: + return Opcode::lvewx128; // 0001000 + case 12: + return Opcode::lvx128; // 0001100 + case 28: + return Opcode::stvx128; // 0011100 + case 44: + return Opcode::lvxl128; // 0101100 + case 48: + return Opcode::stvewx128; // 0110000 + case 60: + return Opcode::stvxl128; // 0111100 + case 64: + return Opcode::lvlx128; // 1000000 + case 68: + return Opcode::lvrx128; // 1000100 + case 80: + return Opcode::stvlx128; // 1010000 + case 84: + return Opcode::stvrx128; // 1010100 + case 96: + return Opcode::lvlxl128; // 1100000 + case 100: + return Opcode::lvrxl128; // 1100100 + case 112: + return Opcode::stvlxl128; // 1110000 + case 116: + return Opcode::stvrxl128; // 1110100 + } + // vsldoi128 has a different pattern: bit 27=1, bits 22-26 encode SHB + // |0 0 0 1 0 0|VD128|VA128|VB128|A|SHB|a|1|VDh|VBh| + if ((code & 0x10) == 0x10) { // bit 27 == 1 + return Opcode::vsldoi128; + } + } + } + + // VMX128 arithmetic/logical instructions (primary opcode 5) + // Format: |0 0 0 1 0 1|VD128|VA128|VB128|A|xxxx|a|y|VDh|VBh| + else if (primary == 5) { + // Extract operation bits 22-25 (4 bits) and bit 27 + u32 op4 = extract_bits(code, 22, 4); + u32 bit27 = extract_bits(code, 27, 1); + u32 bit26 = extract_bits(code, 26, 1); + + if (bit27 == 1) { + // Most VMX128 arithmetic instructions + switch (op4) { + case 0: + return Opcode::vaddfp128; // 0000 + case 1: + return bit26 ? Opcode::vsubfp128 : Opcode::vrlw128; // 0001 + case 2: + return Opcode::vmulfp128; // 0010 + case 3: + return Opcode::vmaddfp128; // 0011 + case 4: + return Opcode::vmaddcfp128; // 0100 + case 5: + return Opcode::vnmsubfp128; // 0101 + case 6: + return Opcode::vmsum3fp128; // 0110 + case 7: + return Opcode::vmsum4fp128; // 0111 + case 8: + return Opcode::vand128; // 1000 + case 9: + return Opcode::vpkshss128; // 1001 (bit27=0) or other + case 10: + return bit26 ? Opcode::vnor128 : Opcode::vandc128; // 1010 + case 11: + return bit26 ? Opcode::vor128 : Opcode::vpkswss128; // 1011 + case 12: + return Opcode::vxor128; // 1100 + case 13: + return Opcode::vsel128; // 1101 + case 14: + return Opcode::vslo128; // 1110 + case 15: + return Opcode::vsro128; // 1111 (only in primary 6?) + } + } else { + // VMX128 instructions with bit27=0 + switch (op4) { + case 0: + return Opcode::vperm128; // vperm has different encoding + case 8: + return Opcode::vpkshss128; + case 9: + return Opcode::vpkshus128; + case 10: + return Opcode::vpkswss128; + case 11: + return Opcode::vpkswus128; + case 12: + return Opcode::vpkuhum128; + case 13: + return Opcode::vpkuhus128; + case 14: + return Opcode::vpkuwum128; + case 15: + return Opcode::vpkuwus128; + } + } + } + + // VMX128 compare/convert/unary instructions (primary opcode 6) + // Format varies by instruction + else if (primary == 6) { + u32 op4 = extract_bits(code, 22, 4); + u32 bit27 = extract_bits(code, 27, 1); + [[maybe_unused]] u32 bit26 = extract_bits(code, 26, 1); + u32 bits_21_27 = extract_bits(code, 21, 7); + + // Check for specific extended opcodes + if (bit27 == 0) { + // Compare and some other instructions + switch (op4) { + case 0: + return Opcode::vcmpeqfp128; // 0000 + case 1: + return Opcode::vcmpgefp128; // 0001 + case 2: + return Opcode::vcmpgtfp128; // 0010 + case 3: + return Opcode::vcmpbfp128; // 0011 + case 8: + return Opcode::vcmpequw128; // 1000 + case 10: + return Opcode::vmaxfp128; // 1010 + case 11: + return Opcode::vminfp128; // 1011 + case 12: + return Opcode::vmrghw128; // 1100 + case 13: + return Opcode::vmrglw128; // 1101 + } + } else { + // bit27 == 1: conversion, rounding, splat, shift instructions + switch (bits_21_27) { + case 0x23: + return Opcode::vcfpsxws128; // 0100011 + case 0x27: + return Opcode::vcfpuxws128; // 0100111 + case 0x2B: + return Opcode::vcsxwfp128; // 0101011 + case 0x2F: + return Opcode::vcuxwfp128; // 0101111 + case 0x33: + return Opcode::vrfim128; // 0110011 + case 0x37: + return Opcode::vrfin128; // 0110111 + case 0x3B: + return Opcode::vrfip128; // 0111011 + case 0x3F: + return Opcode::vrfiz128; // 0111111 + case 0x63: + return Opcode::vrefp128; // 1100011 + case 0x67: + return Opcode::vrsqrtefp128; // 1100111 + case 0x6B: + return Opcode::vexptefp128; // 1101011 + case 0x6F: + return Opcode::vlogefp128; // 1101111 + case 0x73: + return Opcode::vspltw128; // 1110011 + case 0x77: + return Opcode::vspltisw128; // 1110111 + case 0x7F: + return Opcode::vupkd3d128; // 1111111 + } + // vpermwi128, vpkd3d128, vrlimi128 have special encodings + u32 bits_25_27 = extract_bits(code, 25, 3); + if (bits_25_27 == 1) { // 001 + return Opcode::vpermwi128; + } + if (bits_25_27 == 5) { // 101 + return Opcode::vrlimi128; + } + u32 bits_23_25 = extract_bits(code, 23, 3); + if (extract_bits(code, 21, 2) == 3 && (bits_23_25 >= 4)) { + return Opcode::vpkd3d128; + } + // vslw128, vsrw128, vsraw128, vsro128 + if (op4 == 3) + return Opcode::vslw128; + if (op4 == 5) + return Opcode::vsraw128; + if (op4 == 7) + return Opcode::vsrw128; + if (op4 == 15) + return Opcode::vsro128; + } + } + + return Opcode::kUnknown; +} + +const OpcodeInfo& get_opcode_info(Opcode opcode) { + init_opcode_lookup_map(); + + // Static unknown entry for fallback + static const OpcodeInfo unknown = { + Opcode::kUnknown, InstrFormat::kUnknown, OpcodeGroup::kGeneral, "unknown", 0, 0, false}; + + // bail early if we already know its unknown. + if (opcode == Opcode::kUnknown) { + return unknown; + } + + // Linear search through table (small table, acceptable) + for (const auto& info : g_opcode_table) { + // Skip uninitialized entries (name will be null) + if (info.name == nullptr) + continue; + if (info.opcode == opcode) { + return info; + } + } + return unknown; +} + +} // namespace rex::codegen::ppc diff --git a/src/codegen/ppc/opcode.h b/src/codegen/ppc/opcode.h new file mode 100644 index 0000000..3bdba66 --- /dev/null +++ b/src/codegen/ppc/opcode.h @@ -0,0 +1,589 @@ +/** + * @file arch/ppc/opcode.h + * @brief PowerPC opcode definitions for Xbox 360 + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include + +namespace rex::codegen::ppc { + +/** + * PowerPC instruction formats + */ +enum class InstrFormat : uint8_t { + kUnknown = 0, + kI, // Branch (LI, AA, LK) + kB, // Conditional branch (BO, BI, BD, AA, LK) + kD, // Immediate (RT, RA, d/SIMM/UIMM) + kDS, // Double-word store (RT, RA, DS, XO) + kX, // General purpose (RT, RA, RB, XO, Rc) + kXL, // Branch to LR/CTR (BO, BI, XO, LK) + kXFX, // Move to/from SPR (RT, SPR, XO) + kXO, // Arithmetic with OE (RT, RA, RB, OE, XO, Rc) + kM, // Rotate/mask (RS, RA, RB, MB, ME, Rc) + kMD, // Rotate double-word (RS, RA, sh, mb, XO, Rc) + kA, // Floating-point arithmetic (FRT, FRA, FRB, FRC, XO, Rc) + kVXR, // Vector with record bit (VRT, VRA, VRB, Rc, XO) +}; + +/** + * PowerPC opcodes + * Covers essential control flow, ALU, memory, and special register operations + */ +enum class Opcode : uint16_t { + kUnknown = 0, + + // Branch instructions (essential for control flow) + b, // Branch + ba, // Branch absolute + bl, // Branch and link + bla, // Branch and link absolute + bc, // Branch conditional + bca, // Branch conditional absolute + bcl, // Branch conditional and link + bcla, // Branch conditional and link absolute + bclr, // Branch conditional to link register + bclrl, // Branch conditional to link register and link + bcctr, // Branch conditional to count register + bcctrl, // Branch conditional to count register and link + + // Load instructions (byte, half-word, word, double-word) + lbz, // Load byte and zero + lbzu, // Load byte and zero with update + lbzx, // Load byte and zero indexed + lhz, // Load half-word and zero + lhzu, // Load half-word and zero with update + lhzx, // Load half-word and zero indexed + lha, // Load half-word algebraic + lhax, // Load half-word algebraic indexed + lwz, // Load word and zero + lwzu, // Load word and zero with update + lwzx, // Load word and zero indexed + ld, // Load double-word + ldu, // Load double-word with update + ldx, // Load double-word indexed + + // Store instructions + stb, // Store byte + stbu, // Store byte with update + stbx, // Store byte indexed + sth, // Store half-word + sthu, // Store half-word with update + sthx, // Store half-word indexed + stw, // Store word + stwu, // Store word with update + stwx, // Store word indexed + std, // Store double-word + stdu, // Store double-word with update + stdx, // Store double-word indexed + + // Integer arithmetic/logical + add, // Add + addi, // Add immediate + addis, // Add immediate shifted + addic, // Add immediate carrying + addic_, // Add immediate carrying and record + subf, // Subtract from + subfic, // Subtract from immediate carrying + neg, // Negate + ori, // OR immediate + oris, // OR immediate shifted + xori, // XOR immediate + xoris, // XOR immediate shifted + andi_, // AND immediate (note: andi. in assembly) + andis_, // AND immediate shifted + mulli, // Multiply low immediate + + // Multiply/divide + mullw, // Multiply low word + mulhw, // Multiply high word (signed) + mulhwu, // Multiply high word (unsigned) + divw, // Divide word (signed) + divwu, // Divide word (unsigned) + + // Logical operations + and_, // AND (note: and in assembly) + or_, // OR + xor_, // XOR + nand, // NAND + nor, // NOR + andc, // AND with complement + orc, // OR with complement + eqv, // Equivalent (XNOR) + + // Shifts and rotates + slw, // Shift left word + srw, // Shift right word + sraw, // Shift right algebraic word + srawi, // Shift right algebraic word immediate + rlwinm, // Rotate left word immediate then AND with mask + rlwnm, // Rotate left word then AND with mask + cntlzw, // Count leading zeros word + + // Sign/zero extension + extsb, // Extend sign byte + extsh, // Extend sign halfword + + // Comparison + cmp, // Compare + cmpi, // Compare immediate + cmpl, // Compare logical + cmpli, // Compare logical immediate + + // Special purpose register access + mfspr, // Move from special purpose register + mtspr, // Move to special purpose register + mfcr, // Move from condition register + mtcr, // Move to condition register + + // Move to/from count/link registers (simplified mnemonics) + mflr, // Move from link register (mfspr simplified) + mtlr, // Move to link register (mtspr simplified) + mfctr, // Move from count register (mfspr simplified) + mtctr, // Move to count register (mtspr simplified) + + // Synchronization + sync, // Synchronize + isync, // Instruction synchronize + + // System call + sc, // System call + + // Trap + tw, // Trap word + twi, // Trap word immediate + + // Move register (simplified) + mr, // Move register (or rA, rS, rS) + + // No-op + nop, // No operation (ori 0, 0, 0) + + // Load immediate (simplified) + li, // Load immediate (addi rD, 0, value) + lis, // Load immediate shifted (addis rD, 0, value) + + //========================================================================= + // Floating-Point Instructions + //========================================================================= + + // Floating-point load/store + lfs, // Load floating-point single + lfsu, // Load floating-point single with update + lfsx, // Load floating-point single indexed + lfd, // Load floating-point double + lfdu, // Load floating-point double with update + lfdx, // Load floating-point double indexed + stfs, // Store floating-point single + stfsu, // Store floating-point single with update + stfsx, // Store floating-point single indexed + stfd, // Store floating-point double + stfdu, // Store floating-point double with update + stfdx, // Store floating-point double indexed + + // Floating-point arithmetic + fadd, // Floating add (double) + fadds, // Floating add single + fsub, // Floating subtract (double) + fsubs, // Floating subtract single + fmul, // Floating multiply (double) + fmuls, // Floating multiply single + fdiv, // Floating divide (double) + fdivs, // Floating divide single + fsqrt, // Floating square root (double) + fsqrts, // Floating square root single + fre, // Floating reciprocal estimate + fres, // Floating reciprocal estimate single + frsqrte, // Floating reciprocal square root estimate + frsqrtes, // Floating reciprocal square root estimate single + + // Floating-point multiply-add + fmadd, // Floating multiply-add (double) + fmadds, // Floating multiply-add single + fmsub, // Floating multiply-subtract (double) + fmsubs, // Floating multiply-subtract single + fnmadd, // Floating negative multiply-add (double) + fnmadds, // Floating negative multiply-add single + fnmsub, // Floating negative multiply-subtract (double) + fnmsubs, // Floating negative multiply-subtract single + + // Floating-point rounding/conversion + frsp, // Floating round to single precision + fctiw, // Floating convert to integer word + fctiwz, // Floating convert to integer word with round toward zero + fcfid, // Floating convert from integer doubleword + fctid, // Floating convert to integer doubleword + fctidz, // Floating convert to integer doubleword with round toward zero + + // Floating-point move/misc + fmr, // Floating move register + fabs, // Floating absolute value + fnabs, // Floating negative absolute value + fneg, // Floating negate + fsel, // Floating select + + // Floating-point compare + fcmpu, // Floating compare unordered + fcmpo, // Floating compare ordered + + // Floating-point status/control + mffs, // Move from FPSCR + mtfsf, // Move to FPSCR fields + mtfsfi, // Move to FPSCR field immediate + mtfsb0, // Move to FPSCR bit 0 + mtfsb1, // Move to FPSCR bit 1 + + //========================================================================= + // VMX/VMX128 Vector Instructions (Xbox 360) + //========================================================================= + + // Vector load/store (standard VMX) + lvx, // Load vector indexed + lvxl, // Load vector indexed LRU + stvx, // Store vector indexed + stvxl, // Store vector indexed LRU + lvlx, // Load vector left indexed + lvrx, // Load vector right indexed + stvlx, // Store vector left indexed + stvrx, // Store vector right indexed + lvsl, // Load vector for shift left + lvsr, // Load vector for shift right + + // Vector load/store (VMX128 extended - 128 registers) + lvx128, // Load vector indexed (128-reg) + stvx128, // Store vector indexed (128-reg) + lvlx128, // Load vector left indexed (128-reg) + lvrx128, // Load vector right indexed (128-reg) + stvlx128, // Store vector left indexed (128-reg) + stvrx128, // Store vector right indexed (128-reg) + lvlxl128, // Load vector left indexed LRU (128-reg) + lvrxl128, // Load vector right indexed LRU (128-reg) + stvlxl128, // Store vector left indexed LRU (128-reg) + stvrxl128, // Store vector right indexed LRU (128-reg) + lvsl128, // Load vector for shift left (128-reg) + lvsr128, // Load vector for shift right (128-reg) + lvewx128, // Load vector element word indexed (128-reg) + lvxl128, // Load vector indexed LRU (128-reg) + stvewx128, // Store vector element word indexed (128-reg) + stvxl128, // Store vector indexed LRU (128-reg) + vsldoi128, // Vector shift left double by octet immediate (128-reg) + + // Vector floating-point arithmetic + vaddfp, // Vector add floating-point + vsubfp, // Vector subtract floating-point + vmaddfp, // Vector multiply-add floating-point + vnmsubfp, // Vector negative multiply-subtract floating-point + vmulfp128, // Vector multiply floating-point (128-reg) + vrsqrtefp, // Vector reciprocal square root estimate floating-point + vrefp, // Vector reciprocal estimate floating-point + vlogfp, // Vector log2 estimate floating-point + vexptefp, // Vector 2^x estimate floating-point + vmaxfp, // Vector maximum floating-point + vminfp, // Vector minimum floating-point + + // VMX128 floating-point arithmetic (Xbox 360 specific) + vaddfp128, // Vector add floating-point (128-reg) + vsubfp128, // Vector subtract floating-point (128-reg) + vmaddfp128, // Vector multiply-add floating-point (128-reg) + vmaddcfp128, // Vector multiply-add floating-point (C variant, 128-reg) + vnmsubfp128, // Vector negative multiply-subtract floating-point (128-reg) + vmaxfp128, // Vector maximum floating-point (128-reg) + vminfp128, // Vector minimum floating-point (128-reg) + vrefp128, // Vector reciprocal estimate floating-point (128-reg) + vrsqrtefp128, // Vector reciprocal square root estimate floating-point (128-reg) + vexptefp128, // Vector 2^x estimate floating-point (128-reg) + vlogefp128, // Vector log2 estimate floating-point (128-reg) + + // VMX128 dot product instructions (Xbox 360 specific) + vdot3fp128, // Vector 3-element dot product (128-reg) + vdot4fp128, // Vector 4-element dot product (128-reg) + vmsum3fp128, // Vector multiply-sum 3-element (128-reg) + vmsum4fp128, // Vector multiply-sum 4-element (128-reg) + + // Vector integer arithmetic + vaddubm, // Vector add unsigned byte modulo + vadduhm, // Vector add unsigned halfword modulo + vadduwm, // Vector add unsigned word modulo + vsububm, // Vector subtract unsigned byte modulo + vsubuhm, // Vector subtract unsigned halfword modulo + vsubuwm, // Vector subtract unsigned word modulo + vmuloub, // Vector multiply odd unsigned byte + vmulouh, // Vector multiply odd unsigned halfword + vmulouw, // Vector multiply odd unsigned word + vmuleub, // Vector multiply even unsigned byte + vmuleuh, // Vector multiply even unsigned halfword + vmuleuw, // Vector multiply even unsigned word + vavgub, // Vector average unsigned byte + vavguh, // Vector average unsigned halfword + vavguw, // Vector average unsigned word + + // Vector logical + vand, // Vector AND + vandc, // Vector AND with complement + vor, // Vector OR + vorc, // Vector OR with complement (VMX128) + vxor, // Vector XOR + vnor, // Vector NOR + vsel, // Vector select + + // VMX128 logical (Xbox 360 specific) + vand128, // Vector AND (128-reg) + vandc128, // Vector AND with complement (128-reg) + vor128, // Vector OR (128-reg) + vxor128, // Vector XOR (128-reg) + vnor128, // Vector NOR (128-reg) + vsel128, // Vector select (128-reg) + vslo128, // Vector shift left by octet (128-reg) + vsro128, // Vector shift right by octet (128-reg) + + // Vector compare floating-point + vcmpeqfp, // Vector compare equal-to floating-point + vcmpgefp, // Vector compare greater-than-or-equal floating-point + vcmpgtfp, // Vector compare greater-than floating-point + vcmpbfp, // Vector compare bounds floating-point + vcmpeqfp_, // Vector compare equal-to floating-point (Rc=1) + vcmpgefp_, // Vector compare greater-than-or-equal floating-point (Rc=1) + vcmpgtfp_, // Vector compare greater-than floating-point (Rc=1) + + // Vector compare integer + vcmpequb, // Vector compare equal unsigned byte + vcmpequh, // Vector compare equal unsigned halfword + vcmpequw, // Vector compare equal unsigned word + vcmpgtub, // Vector compare greater-than unsigned byte + vcmpgtuh, // Vector compare greater-than unsigned halfword + vcmpgtuw, // Vector compare greater-than unsigned word + vcmpgtsb, // Vector compare greater-than signed byte + vcmpgtsh, // Vector compare greater-than signed halfword + vcmpgtsw, // Vector compare greater-than signed word + + // VMX128 compare (Xbox 360 specific) + vcmpeqfp128, // Vector compare equal-to floating-point (128-reg) + vcmpgefp128, // Vector compare greater-than-or-equal floating-point (128-reg) + vcmpgtfp128, // Vector compare greater-than floating-point (128-reg) + vcmpbfp128, // Vector compare bounds floating-point (128-reg) + vcmpequw128, // Vector compare equal unsigned word (128-reg) + + // Vector permute/merge + vperm, // Vector permute + vperm128, // Vector permute (128-reg) + vmrghb, // Vector merge high byte + vmrghh, // Vector merge high halfword + vmrghw, // Vector merge high word + vmrglb, // Vector merge low byte + vmrglh, // Vector merge low halfword + vmrglw, // Vector merge low word + + // VMX128 merge (Xbox 360 specific) + vmrghw128, // Vector merge high word (128-reg) + vmrglw128, // Vector merge low word (128-reg) + vpermwi128, // Vector permute word immediate (128-reg) + + // Vector pack/unpack + vpkuhum, // Vector pack unsigned halfword unsigned modulo + vpkuwum, // Vector pack unsigned word unsigned modulo + vpkuhus, // Vector pack unsigned halfword unsigned saturate + vpkuwus, // Vector pack unsigned word unsigned saturate + vpkshus, // Vector pack signed halfword unsigned saturate + vpkswus, // Vector pack signed word unsigned saturate + vpkshss, // Vector pack signed halfword signed saturate + vpkswss, // Vector pack signed word signed saturate + vupkhsb, // Vector unpack high signed byte + vupkhsh, // Vector unpack high signed halfword + vupklsb, // Vector unpack low signed byte + vupklsh, // Vector unpack low signed halfword + + // VMX128 pack (Xbox 360 specific) + vpkshss128, // Vector pack signed halfword signed saturate (128-reg) + vpkshus128, // Vector pack signed halfword unsigned saturate (128-reg) + vpkswss128, // Vector pack signed word signed saturate (128-reg) + vpkswus128, // Vector pack signed word unsigned saturate (128-reg) + vpkuhum128, // Vector pack unsigned halfword unsigned modulo (128-reg) + vpkuhus128, // Vector pack unsigned halfword unsigned saturate (128-reg) + vpkuwum128, // Vector pack unsigned word unsigned modulo (128-reg) + vpkuwus128, // Vector pack unsigned word unsigned saturate (128-reg) + vupkhsb128, // Vector unpack high signed byte (128-reg) + vupklsb128, // Vector unpack low signed byte (128-reg) + + // Vector splat + vspltb, // Vector splat byte + vsplth, // Vector splat halfword + vspltw, // Vector splat word + vspltisb, // Vector splat immediate signed byte + vspltish, // Vector splat immediate signed halfword + vspltisw, // Vector splat immediate signed word + + // VMX128 splat (Xbox 360 specific) + vspltw128, // Vector splat word (128-reg) + vspltisw128, // Vector splat immediate signed word (128-reg) + + // Vector shift/rotate + vslb, // Vector shift left byte + vslh, // Vector shift left halfword + vslw, // Vector shift left word + vsrb, // Vector shift right byte + vsrh, // Vector shift right halfword + vsrw, // Vector shift right word + vsrab, // Vector shift right algebraic byte + vsrah, // Vector shift right algebraic halfword + vsraw, // Vector shift right algebraic word + vrlb, // Vector rotate left byte + vrlh, // Vector rotate left halfword + vrlw, // Vector rotate left word + vsl, // Vector shift left (128-bit) + vsr, // Vector shift right (128-bit) + vslo, // Vector shift left by octet + vsro, // Vector shift right by octet + + // Vector conversion + vcfux, // Vector convert from unsigned fixed-point word + vcfsx, // Vector convert from signed fixed-point word + vctuxs, // Vector convert to unsigned fixed-point word saturate + vctsxs, // Vector convert to signed fixed-point word saturate + vrfin, // Vector round to floating-point integer nearest + vrfiz, // Vector round to floating-point integer toward zero + vrfip, // Vector round to floating-point integer toward +infinity + vrfim, // Vector round to floating-point integer toward -infinity + + // VMX128 conversion (Xbox 360 specific) + vcfpsxws128, // Vector convert from FP to signed fixed-point word saturate (128-reg) + vcfpuxws128, // Vector convert from FP to unsigned fixed-point word saturate (128-reg) + vcsxwfp128, // Vector convert from signed fixed-point word to FP (128-reg) + vcuxwfp128, // Vector convert from unsigned fixed-point word to FP (128-reg) + vrfim128, // Vector round to FP integer toward -infinity (128-reg) + vrfin128, // Vector round to FP integer nearest (128-reg) + vrfip128, // Vector round to FP integer toward +infinity (128-reg) + vrfiz128, // Vector round to FP integer toward zero (128-reg) + + // VMX128 move/misc + vmrgow128, // Vector merge odd word (128-reg) + vmrgew128, // Vector merge even word (128-reg) + vrlw128, // Vector rotate left word (128-reg) + vslw128, // Vector shift left word (128-reg) + vsrw128, // Vector shift right word (128-reg) + vsraw128, // Vector shift right algebraic word (128-reg) + vupkd3d128, // Vector unpack D3D format (128-reg) + vpkd3d128, // Vector pack D3D format (128-reg) + vrlimi128, // Vector rotate left immediate and mask insert (128-reg) + + // Vector status/control + mfvscr, // Move from vector status and control register + mtvscr, // Move to vector status and control register +}; + +/** + * Opcode groups for classification + */ +enum class OpcodeGroup : uint8_t { + kGeneral, // General ALU/logical + kBranch, // Branch/control flow + kMemory, // Load/store + kSpecial, // SPR access + kSync, // Synchronization + kSystem, // System call/trap + kFloat, // Floating-point + kVector, // VMX/VMX128 vector +}; + +/** + * Check if opcode is a branch instruction + * Used for basic block boundary detection + */ +inline bool is_branch_instruction(Opcode op) { + switch (op) { + case Opcode::b: + case Opcode::ba: + case Opcode::bl: + case Opcode::bla: + case Opcode::bc: + case Opcode::bca: + case Opcode::bcl: + case Opcode::bcla: + case Opcode::bclr: + case Opcode::bclrl: + case Opcode::bcctr: + case Opcode::bcctrl: + return true; + default: + return false; + } +} + +/** + * Check if opcode is an unconditional branch (always taken) + * Used for control flow analysis + */ +inline bool is_unconditional_branch(Opcode op) { + switch (op) { + case Opcode::b: + case Opcode::ba: + case Opcode::bl: + case Opcode::bla: + return true; + default: + return false; + } +} + +/** + * Check if opcode terminates a basic block (branch or return) + * Used for control flow analysis + */ +inline bool is_terminator_instruction(Opcode op) { + switch (op) { + case Opcode::b: + case Opcode::ba: + case Opcode::bl: + case Opcode::bla: + case Opcode::bc: + case Opcode::bca: + case Opcode::bcl: + case Opcode::bcla: + case Opcode::bclr: + case Opcode::bclrl: + case Opcode::bcctr: + case Opcode::bcctrl: + case Opcode::sc: // System call + case Opcode::tw: // Trap word + case Opcode::twi: // Trap word immediate + return true; + default: + return false; + } +} + +/** + * Opcode information structure + */ +struct OpcodeInfo { + Opcode opcode; + InstrFormat format; + OpcodeGroup group; + const char* name; + uint32_t primary_opcode; // Bits 0-5 + uint32_t extended_opcode; // Bits 21-30 (or other extended field) + bool has_extended; // True if uses extended opcode +}; + +/** + * Lookup opcode from instruction code + * @param code Raw 32-bit instruction (big-endian) + * @return Opcode enum value + */ +Opcode lookup_opcode(uint32_t code); + +/** + * Get opcode information + * @param opcode Opcode enum value + * @return Opcode information structure + */ +const OpcodeInfo& get_opcode_info(Opcode opcode); + +} // namespace rex::codegen::ppc diff --git a/src/codegen/project_recompiler.cpp b/src/codegen/project_recompiler.cpp new file mode 100644 index 0000000..e6c410a --- /dev/null +++ b/src/codegen/project_recompiler.cpp @@ -0,0 +1,435 @@ +/** + * @file codegen/project_recompiler.cpp + * @brief Project-level recompiler driving manifest-based multi-binary codegen + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "codegen_logging.h" +#include "template_registry_internal.h" + +namespace rex::codegen { + +namespace { + +std::string DeriveTargetNameFromFilePath(const std::string& file_path) { + std::filesystem::path p(file_path); + std::string name = p.stem().string(); + std::replace(name.begin(), name.end(), '.', '_'); + std::replace(name.begin(), name.end(), ' ', '_'); + return name; +} + +} // namespace + +ProjectRecompiler::ProjectRecompiler(ManifestConfig manifest) : manifest_(std::move(manifest)) {} + +Result ProjectRecompiler::Run(const ProjectRecompilerOptions& opts) { + namespace fs = std::filesystem; + + deletedFiles_.clear(); + writtenFiles_.clear(); + + if (manifest_.modules.empty()) { + REXCODEGEN_TRACE("Recompiling '{}' (entrypoint)", manifest_.projectName); + } else { + REXCODEGEN_TRACE("Recompiling '{}' (entrypoint + {} DLL{})", manifest_.projectName, + manifest_.modules.size(), manifest_.modules.size() == 1 ? "" : "s"); + } + + struct ModuleEntry { + std::string targetName; + std::string guestPath; + bool isDll; + RecompilerConfig config; + }; + + std::vector allModules; + allModules.push_back({DeriveTargetNameFromFilePath(manifest_.entrypoint.recompiler.filePath), "", + false, std::move(manifest_.entrypoint.recompiler)}); + for (auto& mod : manifest_.modules) { + allModules.push_back({DeriveTargetNameFromFilePath(mod.recompiler.filePath), mod.guestPath, + true, std::move(mod.recompiler)}); + } + + if (!opts.targets.empty()) { + std::vector unknown; + for (const auto& t : opts.targets) { + bool match = std::any_of(allModules.begin() + 1, allModules.end(), + [&t](const ModuleEntry& m) { return m.targetName == t; }); + if (!match) { + unknown.push_back(t); + } + } + if (!unknown.empty()) { + std::string known; + for (size_t i = 1; i < allModules.size(); ++i) { + if (i > 1) + known += ", "; + known += allModules[i].targetName; + } + std::string list; + for (size_t i = 0; i < unknown.size(); ++i) { + if (i > 0) + list += ", "; + list += unknown[i]; + } + return Err(ErrorCategory::Config, + fmt::format("Unknown --target value(s): {}. Known DLL targets: {}", list, + known.empty() ? "(none)" : known)); + } + } + + std::vector targeted; + targeted.push_back(std::move(allModules[0])); + for (size_t i = 1; i < allModules.size(); ++i) { + if (opts.targets.empty() || std::find(opts.targets.begin(), opts.targets.end(), + allModules[i].targetName) != opts.targets.end()) { + targeted.push_back(std::move(allModules[i])); + } + } + + // Two binaries sharing an out_directory_path would clobber each other's + // sources.cmake on emit (the writer's cleanup sweep is unprefixed for + // that file). + std::unordered_map outDirOwner; + for (const auto& m : targeted) { + const auto& outDir = m.config.outDirectoryPath; + if (outDir.empty()) + continue; + auto [it, inserted] = outDirOwner.emplace(outDir, m.targetName); + if (!inserted) { + return Err( + ErrorCategory::Validation, + fmt::format("out_directory_path '{}' is shared by '{}' and '{}'; each binary " + "needs its own output directory", + outDir, it->second, m.targetName)); + } + } + + const auto& entryConfig = targeted[0].config; + auto configDir = manifest_.manifestDir; + fs::path entryXexPath = configDir / entryConfig.filePath; + if (!entryConfig.patchedFilePath.empty()) { + auto patched = configDir / entryConfig.patchedFilePath; + if (fs::exists(patched)) + entryXexPath = patched; + } + if (!fs::exists(entryXexPath)) { + return Err(ErrorCategory::IO, + fmt::format("Entrypoint XEX not found: {}", entryXexPath.string())); + } + entryXexPath = fs::canonical(entryXexPath); + + // gameRoot anchors VFS root and DLL guest_path derivation. Honor the + // manifest override if set; otherwise default to the entrypoint's parent. + fs::path gameRoot; + if (manifest_.gameRoot && !manifest_.gameRoot->empty()) { + fs::path resolved = configDir / *manifest_.gameRoot; + if (!fs::exists(resolved) || !fs::is_directory(resolved)) { + return Err(ErrorCategory::Validation, + fmt::format("[project].game_root '{}' does not resolve to a directory", + resolved.string())); + } + gameRoot = fs::canonical(resolved); + } else { + gameRoot = fs::canonical(entryXexPath.parent_path()); + } + + fs::path entryRel = fs::relative(entryXexPath, gameRoot); + if (entryRel.empty() || *entryRel.begin() == "..") { + return Err(ErrorCategory::Validation, + fmt::format("Entrypoint XEX '{}' resolves outside game root '{}'", + entryXexPath.string(), gameRoot.string())); + } + + auto runtime = std::make_unique(gameRoot.string()); + auto rtStatus = runtime->Setup(rex::RuntimeConfig{ + .kernel_init = rex::kernel::InitializeKernel, + .tool_mode = true, + }); + if (rtStatus != X_STATUS_SUCCESS) { + return Err(ErrorCategory::IO, + fmt::format("Failed to initialize Runtime: {:#x}", rtStatus)); + } + + std::string entryRelStr = entryRel.string(); + std::replace(entryRelStr.begin(), entryRelStr.end(), '/', '\\'); + auto entryVfsPath = "game:\\" + entryRelStr; + rtStatus = runtime->LoadXexImage(entryVfsPath); + if (rtStatus != X_STATUS_SUCCESS) { + return Err(ErrorCategory::IO, + fmt::format("Failed to load entrypoint XEX: {:#x}", rtStatus)); + } + + std::vector> dllModules; + for (size_t i = 1; i < targeted.size(); ++i) { + const auto& dllConfig = targeted[i].config; + fs::path dllXexPath = configDir / dllConfig.filePath; + if (!dllConfig.patchedFilePath.empty()) { + auto patched = configDir / dllConfig.patchedFilePath; + if (fs::exists(patched)) + dllXexPath = patched; + } + if (!fs::exists(dllXexPath)) { + return Err(ErrorCategory::IO, + fmt::format("DLL XEX not found: {}", dllXexPath.string())); + } + dllXexPath = fs::canonical(dllXexPath); + + auto relPath = fs::relative(dllXexPath, gameRoot); + if (relPath.empty() || *relPath.begin() == "..") { + return Err(ErrorCategory::Validation, + fmt::format("DLL '{}' resolves outside game root '{}': {}", + targeted[i].targetName, gameRoot.string(), dllXexPath.string())); + } + std::string relStr = relPath.string(); + std::replace(relStr.begin(), relStr.end(), '/', '\\'); + auto dllVfsPath = "game:\\" + relStr; + auto userMod = runtime->kernel_state()->LoadUserModule(dllVfsPath, false); + if (!userMod) { + return Err(ErrorCategory::IO, + fmt::format("Failed to load DLL module: {}", targeted[i].targetName)); + } + REXCODEGEN_TRACE("Loaded DLL module '{}' at base 0x{:08X}", targeted[i].targetName, + userMod->xex_module()->base_address()); + dllModules.push_back(std::move(userMod)); + } + + struct ContextEntry { + CodegenContext ctx; + const ModuleEntry* module; + std::string display_name; + }; + std::vector contexts; + + auto make_display_name = [](const std::string& filePath) { + return std::filesystem::path(filePath).filename().string(); + }; + + auto* resolver = runtime->export_resolver(); + + { + auto execMod = runtime->kernel_state()->GetExecutableModule(); + auto bv = BinaryView::fromModule(*execMod->xex_module()); + + auto entry_display = make_display_name(targeted[0].config.filePath); + RecompilerConfig cfg = std::move(targeted[0].config); + if (opts.enableExceptionHandlers) + cfg.generateExceptionHandlers = true; + + auto ctx = CodegenContext::Create(std::move(bv), std::move(cfg)); + ctx.setResolver(resolver); + ctx.setConfigDir(configDir); + ctx.analysisState().format = "xex"; + ctx.analysisState().loadAddress = ctx.binary().baseAddress(); + ctx.analysisState().entryPoint = ctx.binary().entryPoint(); + ctx.analysisState().imageSize = ctx.binary().imageSize(); + ctx.setHasDllModules(!manifest_.modules.empty()); + if (ctx.Config().isDll.has_value()) + ctx.setDllModule(*ctx.Config().isDll); + + contexts.push_back({std::move(ctx), &targeted[0], std::move(entry_display)}); + } + + for (size_t i = 0; i < dllModules.size(); ++i) { + auto& userMod = dllModules[i]; + auto bv = BinaryView::fromModule(*userMod->xex_module()); + + auto dll_display = make_display_name(targeted[i + 1].config.filePath); + RecompilerConfig cfg = std::move(targeted[i + 1].config); + if (opts.enableExceptionHandlers) + cfg.generateExceptionHandlers = true; + + auto ctx = CodegenContext::Create(std::move(bv), std::move(cfg)); + ctx.setResolver(resolver); + ctx.setConfigDir(configDir); + ctx.analysisState().format = "xex"; + ctx.analysisState().loadAddress = ctx.binary().baseAddress(); + ctx.analysisState().entryPoint = ctx.binary().entryPoint(); + ctx.analysisState().imageSize = ctx.binary().imageSize(); + ctx.setDllModule(ctx.Config().isDll.value_or(true)); + ctx.setHasDllModules(true); + + contexts.push_back({std::move(ctx), &targeted[i + 1], std::move(dll_display)}); + } + + std::vector module_started_at(contexts.size()); + for (size_t i = 0; i < contexts.size(); ++i) { + auto& entry = contexts[i]; + if (opts.reporter) { + opts.reporter->moduleStarted(entry.display_name, i, contexts.size()); + } + module_started_at[i] = std::chrono::steady_clock::now(); + REXCODEGEN_TRACE("Analyzing '{}'...", entry.module->targetName); + auto result = Analyze(entry.ctx, opts.reporter); + if (!result) { + if (opts.force && result.error().category == ErrorCategory::Validation) { + REXLOG_WARN("Analysis errors for '{}' (continuing due to --force): {}", + entry.module->targetName, result.error().message); + } else { + REXLOG_ERROR("Analysis failed for '{}'", entry.module->targetName); + return result; + } + } + } + + for (size_t i = 0; i < contexts.size(); ++i) { + uint32_t a_base = contexts[i].ctx.binary().baseAddress(); + uint32_t a_end = a_base + contexts[i].ctx.binary().imageSize(); + for (size_t j = i + 1; j < contexts.size(); ++j) { + uint32_t b_base = contexts[j].ctx.binary().baseAddress(); + uint32_t b_end = b_base + contexts[j].ctx.binary().imageSize(); + if (a_base < b_end && b_base < a_end) { + return Err(ErrorCategory::Validation, + fmt::format("Module '{}' [{:08X}, {:08X}) overlaps '{}' [{:08X}, {:08X})", + contexts[i].module->targetName, a_base, a_end, + contexts[j].module->targetName, b_base, b_end)); + } + } + } + + deletedFiles_.clear(); + writtenFiles_.clear(); + for (size_t i = 0; i < contexts.size(); ++i) { + auto& entry = contexts[i]; + if (opts.reporter) { + opts.reporter->moduleStarted(entry.display_name, i, contexts.size()); + opts.reporter->phaseChanged("Write"); + } + REXCODEGEN_TRACE("Writing output for '{}'...", entry.module->targetName); + CodegenWriter writer(entry.ctx, runtime.get()); + if (!writer.write(opts.force)) { + return Err(ErrorCategory::Validation, + fmt::format("Write failed for '{}'", entry.module->targetName)); + } + deletedFiles_.insert(deletedFiles_.end(), writer.deletedFiles().begin(), + writer.deletedFiles().end()); + writtenFiles_.insert(writtenFiles_.end(), writer.writtenFiles().begin(), + writer.writtenFiles().end()); + if (opts.reporter) { + auto elapsed = std::chrono::duration_cast( + std::chrono::steady_clock::now() - module_started_at[i]); + opts.reporter->moduleFinished(elapsed); + } + } + + if (manifest_.modules.empty()) { + REXCODEGEN_TRACE("Project recompiler complete"); + return Ok(); + } + + auto outputPath = contexts[0].ctx.configDir() / contexts[0].ctx.Config().outDirectoryPath; + std::error_code mk_ec; + fs::create_directories(outputPath, mk_ec); + if (mk_ec) { + return Err(ErrorCategory::IO, fmt::format("Failed to create output dir {}: {}", + outputPath.string(), mk_ec.message())); + } + + if (opts.reporter) + opts.reporter->projectPhaseStarted("module_registry"); + { + nlohmann::json registryData; + registryData["project"] = manifest_.projectName; + + auto& dllArray = registryData["dll_modules"]; + dllArray = nlohmann::json::array(); + for (size_t i = 1; i < targeted.size(); ++i) { + auto& mod = targeted[i]; + auto guestPath = mod.guestPath; + std::replace(guestPath.begin(), guestPath.end(), '\\', '/'); + nlohmann::json dllEntry; + dllEntry["pe_name"] = fs::path(mod.guestPath).filename().string(); + dllEntry["guest_path"] = guestPath; + dllEntry["shared_lib_name"] = manifest_.projectName + "_" + mod.targetName; + dllArray.push_back(dllEntry); + } + + TemplateRegistry registry; + auto registryContent = renderWithJson(registry, "codegen/module_registry_cpp", registryData); + + auto registryPath = outputPath / "module_registry.cpp"; + std::ofstream f(registryPath); + if (!f) { + return Err(ErrorCategory::IO, fmt::format("Failed to open {}", registryPath.string())); + } + f << registryContent; + if (!f.good()) { + return Err(ErrorCategory::IO, + fmt::format("Failed while writing {}", registryPath.string())); + } + writtenFiles_.push_back(registryPath.filename().string()); + REXCODEGEN_TRACE("Wrote {}", registryPath.string()); + } + if (opts.reporter) + opts.reporter->projectPhaseFinished(); + + if (opts.reporter) + opts.reporter->projectPhaseStarted("dll_targets.cmake"); + { + nlohmann::json dllTargetsData; + auto& dllTargetsArray = dllTargetsData["dll_modules"]; + dllTargetsArray = nlohmann::json::array(); + for (size_t i = 0; i < dllModules.size(); ++i) { + auto& mod = targeted[i + 1]; + auto& dllCtx = contexts[i + 1].ctx; + nlohmann::json entry; + entry["target_name"] = mod.targetName; + entry["lib_name"] = manifest_.projectName + "_" + mod.targetName; + entry["output_dir"] = dllCtx.Config().outDirectoryPath; + dllTargetsArray.push_back(entry); + } + + TemplateRegistry registry; + auto dllCmakeContent = renderWithJson(registry, "codegen/dll_targets_cmake", dllTargetsData); + + auto dllCmakePath = outputPath / "dll_targets.cmake"; + std::ofstream cf(dllCmakePath); + if (!cf) { + return Err(ErrorCategory::IO, fmt::format("Failed to open {}", dllCmakePath.string())); + } + cf << dllCmakeContent; + if (!cf.good()) { + return Err(ErrorCategory::IO, + fmt::format("Failed while writing {}", dllCmakePath.string())); + } + writtenFiles_.push_back(dllCmakePath.filename().string()); + REXCODEGEN_TRACE("Wrote {}", dllCmakePath.string()); + } + if (opts.reporter) + opts.reporter->projectPhaseFinished(); + + REXCODEGEN_TRACE("Project recompiler complete"); + return Ok(); +} + +} // namespace rex::codegen diff --git a/src/codegen/sig_scanner.cpp b/src/codegen/sig_scanner.cpp new file mode 100644 index 0000000..2fdda5d --- /dev/null +++ b/src/codegen/sig_scanner.cpp @@ -0,0 +1,167 @@ +/** + * @file rexcodegen/sig_scanner.cpp + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include +#include + +#include "codegen_logging.h" +#include +#include + +using rex::memory::load_and_swap; + +namespace rex::codegen { + +SigScanner::SigScanner(const runtime::Module& module) : module_(module) {} + +std::vector SigScanner::scan(const Signature& sig) { + std::vector matches; + + // Scan all executable sections + // TODO(tomc): maybe i wanna scan other sections... + for (const auto& section : module_.binary_sections()) { + if (!section.host_data) + continue; + + if (!section.executable) + continue; + + auto rangeMatches = + scanRange(section.virtual_address, section.virtual_address + section.virtual_size, + sig.pattern, sig.mask, sig.entryOffset); + + matches.insert(matches.end(), rangeMatches.begin(), rangeMatches.end()); + } + + return matches; +} + +std::unordered_map> SigScanner::scanAll( + const std::vector& sigs) { + std::unordered_map> results; + + for (const auto& sig : sigs) { + results[sig.name] = scan(sig); + } + + return results; +} + +std::vector SigScanner::scanRange(uint32_t start, uint32_t end, + const std::vector& pattern, + const std::vector& mask, size_t entryOffset) { + std::vector matches; + + if (pattern.empty() || pattern.size() != mask.size()) { + return matches; + } + + // Find section containing this range + const auto* section = module_.FindSectionByAddress(start); + if (!section || !section->host_data) { + return matches; + } + + size_t patternBytes = pattern.size() * 4; + uint32_t sectionEnd = section->virtual_address + section->virtual_size; + uint32_t scanEnd = std::min(end, sectionEnd); + + if (start + patternBytes > scanEnd) { + return matches; + } + + const uint8_t* data = section->host_data; + uint32_t sectionBase = section->virtual_address; + + // Scan through the range (4-byte aligned for PPC) + for (uint32_t addr = start; addr + patternBytes <= scanEnd; addr += 4) { + bool matched = true; + uint32_t offset = addr - sectionBase; + + for (size_t i = 0; i < pattern.size() && matched; i++) { + uint32_t dword = load_and_swap(data + offset + i * 4); + uint32_t masked = dword & mask[i]; + uint32_t expected = pattern[i] & mask[i]; + + if (masked != expected) { + matched = false; + } + } + + if (matched) { + uint32_t entryPoint = addr + static_cast(entryOffset * 4); + matches.push_back(entryPoint); + REXCODEGEN_TRACE("SigScanner: pattern match at 0x{:08X}, entry=0x{:08X}", addr, entryPoint); + } + } + + return matches; +} + +std::vector SigScanner::helperSignatures() { + std::vector sigs; + + // __savegprlr_14 pattern: + // The save helpers are a sequence of stw rN, offset(r12) instructions + // followed by stw r0, 8(r12) and blr + // + // stw rN, offset(r12) = 0x9180XXXX where XX encodes the offset + // For r14: stw r14, -0x48(r12) = 0x91CBFFB8 + // + // We look for the first instruction of the sequence. + // stw r14, -0x48(r12) = 0x91CBFFB8 + + sigs.push_back({ + "__savegprlr_14", + {0x91CBFFB8}, // stw r14, -0x48(r12) + {0xFFFFFFFF}, // Exact match + 0, // Entry at pattern start + std::nullopt // Size computed from stride + }); + + // __restgprlr_14 pattern: + // lwz rN, offset(r12) followed by eventually mtlr r0 and blr + // lwz r14, -0x48(r12) = 0x81CBFFB8 + + sigs.push_back({"__restgprlr_14", + {0x81CBFFB8}, // lwz r14, -0x48(r12) + {0xFFFFFFFF}, // Exact match + 0, + std::nullopt}); + + // __savefpr_14 pattern: + // stfd frN, offset(r12) + // stfd fr14, -0x98(r12) = 0xD9CCFF68 + + sigs.push_back({"__savefpr_14", + {0xD9CCFF68}, // stfd fr14, -0x98(r12) + {0xFFFFFFFF}, + 0, + std::nullopt}); + + // __restfpr_14 pattern: + // lfd frN, offset(r12) + // lfd fr14, -0x98(r12) = 0xC9CCFF68 + + sigs.push_back({"__restfpr_14", + {0xC9CCFF68}, // lfd fr14, -0x98(r12) + {0xFFFFFFFF}, + 0, + std::nullopt}); + + return sigs; +} + +std::vector SigScanner::hleSignatures() { + // TODO(tomc): mayhaps have signatures memset, memmove, memcpy, strcmp patterns + return {}; +} + +} // namespace rex::codegen diff --git a/src/codegen/template_registry.cpp b/src/codegen/template_registry.cpp new file mode 100644 index 0000000..d8c20c2 --- /dev/null +++ b/src/codegen/template_registry.cpp @@ -0,0 +1,205 @@ +/** + * @file codegen/template_registry.cpp + * @brief Template registry implementation + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include +#include "template_registry_internal.h" + +#include +#include + +#include "codegen_logging.h" + +// Generated at build time by cmake/embed_templates.cmake +#include "embedded_templates.h" + +#include +#include + +namespace rex::codegen { + +// --------------------------------------------------------------------------- +// TemplateError +// --------------------------------------------------------------------------- + +TemplateError::TemplateError(const std::string& templateId, const std::string& message, + const std::string& source) + : std::runtime_error("[" + source + "] template '" + templateId + "': " + message), + templateId_(templateId), + source_(source) {} + +// --------------------------------------------------------------------------- +// TemplateRegistry::Impl +// --------------------------------------------------------------------------- + +struct TemplateRegistry::Impl { + inja::Environment env_; + std::unordered_map embedded_; + std::unordered_map overrides_; + std::unordered_map parsedCache_; + + Impl() { + embedded_ = embeddedTemplates(); + + // cmake_var callback: wraps a variable name in ${ } + env_.add_callback("cmake_var", 1, [](inja::Arguments& args) { + return "${" + args.at(0)->get() + "}"; + }); + + // hex callback: format an integer as 0x-prefixed hex + env_.add_callback("hex", 1, [](inja::Arguments& args) { + auto val = args.at(0)->get(); + std::ostringstream oss; + oss << "0x" << std::hex << std::uppercase << val; + return oss.str(); + }); + + // Resolve {% include "" %} against the embedded registry. Templates + // are embedded under canonical IDs without the .inja extension; accept + // either form so include directives can use either. + env_.set_search_included_templates_in_files(false); + env_.set_include_callback( + [this](const std::filesystem::path&, const std::string& name) -> inja::Template { + std::string id = name; + if (id.size() > 5 && id.compare(id.size() - 5, 5, ".inja") == 0) { + id.erase(id.size() - 5); + } + auto it = embedded_.find(id); + if (it == embedded_.end()) { + throw TemplateError(name, "include not found in embedded registry"); + } + return env_.parse(std::string(it->second)); + }); + } + + std::string renderImpl(const std::string& id, const nlohmann::json& data) { + // Check overrides first + auto ovIt = overrides_.find(id); + if (ovIt != overrides_.end()) { + return env_.render(ovIt->second, data); + } + + // Check parsed cache + auto cacheIt = parsedCache_.find(id); + if (cacheIt != parsedCache_.end()) { + return env_.render(cacheIt->second, data); + } + + // Look up in embedded templates + auto embIt = embedded_.find(id); + if (embIt == embedded_.end()) { + throw TemplateError(id, "no template registered with this ID"); + } + + // Parse, cache, and render + auto tmpl = env_.parse(std::string(embIt->second)); + auto [it, _] = parsedCache_.emplace(id, std::move(tmpl)); + return env_.render(it->second, data); + } +}; + +// --------------------------------------------------------------------------- +// TemplateRegistry special members +// --------------------------------------------------------------------------- + +TemplateRegistry::TemplateRegistry() : impl_(std::make_unique()) {} +TemplateRegistry::~TemplateRegistry() = default; +TemplateRegistry::TemplateRegistry(TemplateRegistry&&) noexcept = default; +TemplateRegistry& TemplateRegistry::operator=(TemplateRegistry&&) noexcept = default; + +// --------------------------------------------------------------------------- +// TemplateRegistry public methods +// --------------------------------------------------------------------------- + +void TemplateRegistry::loadOverrides(const std::filesystem::path& dir) { + if (!std::filesystem::exists(dir)) { + REXCODEGEN_WARN("Override directory does not exist: {}", dir.string()); + return; + } + + for (auto const& entry : std::filesystem::recursive_directory_iterator(dir)) { + if (!entry.is_regular_file()) + continue; + if (entry.path().extension() != ".inja") + continue; + + // Compute canonical ID from relative path, stripping .inja extension + auto relPath = std::filesystem::relative(entry.path(), dir).string(); + // Normalize path separators to forward slash + std::replace(relPath.begin(), relPath.end(), '\\', '/'); + // Strip .inja extension + auto id = relPath.substr(0, relPath.size() - 5); // strlen(".inja") == 5 + + if (impl_->embedded_.find(id) == impl_->embedded_.end()) { + REXCODEGEN_WARN("Override file does not match a known template ID: {} (from {})", id, + entry.path().string()); + continue; + } + + try { + auto content = [&]() { + std::ifstream ifs(entry.path()); + return std::string(std::istreambuf_iterator(ifs), std::istreambuf_iterator()); + }(); + auto tmpl = impl_->env_.parse(content); + impl_->overrides_[id] = std::move(tmpl); + REXCODEGEN_TRACE("Loaded template override: {} -> {}", id, entry.path().string()); + } catch (const std::exception& e) { + throw TemplateError(id, e.what(), entry.path().string()); + } + } +} + +std::string TemplateRegistry::render(const std::string& id, const std::string& jsonData) { + try { + auto data = nlohmann::json::parse(jsonData); + return impl_->renderImpl(id, data); + } catch (const TemplateError&) { + throw; // Already wrapped + } catch (const nlohmann::json::exception& e) { + throw TemplateError(id, std::string("JSON parse error: ") + e.what()); + } catch (const inja::InjaError& e) { + throw TemplateError(id, e.what()); + } catch (const std::exception& e) { + throw TemplateError(id, e.what()); + } +} + +std::string TemplateRegistry::renderString(const std::string& templateContent, + const std::string& jsonData) { + try { + auto data = nlohmann::json::parse(jsonData); + auto tmpl = impl_->env_.parse(templateContent); + return impl_->env_.render(tmpl, data); + } catch (const nlohmann::json::exception& e) { + throw TemplateError("", std::string("JSON parse error: ") + e.what(), "string"); + } catch (const inja::InjaError& e) { + throw TemplateError("", e.what(), "string"); + } catch (const std::exception& e) { + throw TemplateError("", e.what(), "string"); + } +} + +std::vector TemplateRegistry::registeredIds() const { + std::vector ids; + ids.reserve(impl_->embedded_.size()); + for (const auto& [id, _] : impl_->embedded_) { + ids.push_back(id); + } + return ids; +} + +// --------------------------------------------------------------------------- +// Free function: renderWithJson (internal API) +// --------------------------------------------------------------------------- + +std::string renderWithJson(TemplateRegistry& registry, const std::string& id, + const nlohmann::json& data) { + return registry.render(id, data.dump()); +} + +} // namespace rex::codegen diff --git a/src/codegen/template_registry_internal.h b/src/codegen/template_registry_internal.h new file mode 100644 index 0000000..cb85a77 --- /dev/null +++ b/src/codegen/template_registry_internal.h @@ -0,0 +1,21 @@ +/** + * @file codegen/template_registry_internal.h + * @brief Internal json-native render for TemplateRegistry + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#pragma once + +#include +#include + +namespace rex::codegen { + +/// Render with pre-parsed json. Avoids double-serialization for internal callers. +/// Implementation lives in template_registry.cpp. +std::string renderWithJson(TemplateRegistry& registry, const std::string& id, + const nlohmann::json& data); + +} // namespace rex::codegen diff --git a/src/codegen/test_support.cpp b/src/codegen/test_support.cpp new file mode 100644 index 0000000..06147ed --- /dev/null +++ b/src/codegen/test_support.cpp @@ -0,0 +1,117 @@ +/** + * @file codegen/test_support.cpp + * @brief Test support utilities + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include + +#include +#include + +#include + +#include "ppc/instruction.h" + +#include +#include +#include +#include +#include + +using rex::codegen::ppc::decode_instruction; +using rex::memory::load_and_swap; + +namespace rex::codegen { + +// --- TestModule --- + +TestModule::TestModule() : Module(nullptr) {} + +void TestModule::Load(uint32_t base_address, const uint8_t* data, size_t size) { + base_address_ = base_address; + size_ = static_cast(size); + + // Populate binary section for FunctionScanner to read instructions + binary_sections_.clear(); + binary_sections_.push_back(runtime::BinarySection{ + ".text", base_address, static_cast(size), data, + true, // executable + false // writable + }); +} + +bool TestModule::ContainsAddress(uint32_t address) { + return address >= base_address_ && address < base_address_ + size_; +} + +// --- AnalyzeTestBinary --- + +void AnalyzeTestBinary(CodegenContext& ctx, std::string_view testName, + const std::map& symbols, uint32_t baseAddress, + const uint8_t* data, size_t dataSize) { + // Extract only test_ prefixed symbols as function entry points + std::vector> testFunctions; + for (const auto& [addr, name] : symbols) { + if (name.starts_with("test_")) { + testFunctions.push_back({addr, name}); + } + } + + // Sort by address + std::sort(testFunctions.begin(), testFunctions.end()); + + // First pass: add all functions and transition through state machine + for (size_t i = 0; i < testFunctions.size(); i++) { + uint32_t fnAddr = static_cast(testFunctions[i].first); + + // Size extends to next test_ function or end of binary + uint32_t nextAddr = static_cast(baseAddress + dataSize); + if (i + 1 < testFunctions.size()) { + nextAddr = static_cast(testFunctions[i + 1].first); + } + uint32_t fnSize = nextAddr - fnAddr; + + auto* node = ctx.graph.addFunction(fnAddr, fnSize, FunctionAuthority::DISCOVERED, true); + + if (node) { + // kRegistered -> kDiscovered -> kSealed + node->discover({{fnAddr, fnSize}}, {}, {}); + ctx.graph.setFunctionName(fnAddr, fmt::format("{}_{:X}", testName, fnAddr)); + node->seal(); + } + } + + // Second pass: scan for bl instructions and register resolved call edges + for (size_t i = 0; i < testFunctions.size(); i++) { + uint32_t fnAddr = static_cast(testFunctions[i].first); + uint32_t nextAddr = static_cast(baseAddress + dataSize); + if (i + 1 < testFunctions.size()) { + nextAddr = static_cast(testFunctions[i + 1].first); + } + uint32_t fnSize = nextAddr - fnAddr; + + // Scan each instruction in this function + for (uint32_t offset = 0; offset < fnSize; offset += 4) { + uint32_t pc = fnAddr + offset; + uint32_t raw = load_and_swap(data + (fnAddr - baseAddress) + offset); + auto decoded = decode_instruction(pc, raw); + + // Check for bl (branch with link = function call) + if (decoded.is_call() && decoded.branch_target.has_value()) { + uint32_t target = decoded.branch_target.value(); + auto* targetNode = ctx.graph.getFunction(target); + if (targetNode) { + ctx.graph.addCallToFunction(fnAddr, pc, CallTarget::function(targetNode)); + } + } + } + } +} + +} // namespace rex::codegen diff --git a/src/codegen/vtable_scanner.cpp b/src/codegen/vtable_scanner.cpp new file mode 100644 index 0000000..25a3de4 --- /dev/null +++ b/src/codegen/vtable_scanner.cpp @@ -0,0 +1,227 @@ +/** + * @file rexcodegen/vtable_scanner.cpp + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include +#include + +#include "codegen_logging.h" +#include +#include + +using rex::memory::load_and_swap; + +namespace rex::codegen { + +VTableScanner::VTableScanner(const BinaryView& binary) : binary_(binary) {} + +std::vector VTableScanner::scan() { + std::vector vtables; + + // Step 1: Find all Complete Object Locators + auto cols = findCompleteObjectLocators(); + REXCODEGEN_DEBUG("VTableScanner: found {} Complete Object Locators", cols.size()); + + // Step 2: For each COL, find its vtable and read slots + for (uint32_t colAddr : cols) { + auto vtableAddr = findVTableForCOL(colAddr); + if (!vtableAddr) { + REXCODEGEN_TRACE("VTableScanner: COL at 0x{:08X} has no referencing vtable", colAddr); + continue; + } + + VTableInfo info; + info.vtableAddress = *vtableAddr; + info.colAddress = colAddr; + info.className = extractClassName(colAddr); + info.slots = readVTableSlots(*vtableAddr); + + if (info.slots.empty()) { + REXCODEGEN_TRACE("VTableScanner: vtable at 0x{:08X} has no valid slots", *vtableAddr); + continue; + } + + REXCODEGEN_DEBUG("VTableScanner: vtable at 0x{:08X} ({}) has {} slots", info.vtableAddress, + info.className, info.slots.size()); + + vtables.push_back(std::move(info)); + } + + return vtables; +} + +std::vector VTableScanner::findCompleteObjectLocators() { + std::vector cols; + + // Scan .rdata section for COL patterns + const auto* rdata = binary_.findSectionByName(".rdata"); + if (!rdata || !rdata->data) { + REXCODEGEN_WARN("VTableScanner: .rdata section not found"); + return cols; + } + + const uint8_t* data = rdata->data; + uint32_t base = rdata->baseAddress; + size_t size = rdata->size; + + // COL is 20 bytes, need room for it + if (size < sizeof(RTTICompleteObjectLocator)) { + return cols; + } + + // Scan for COL pattern: signature=0, valid type descriptor pointer + for (size_t offset = 0; offset + sizeof(RTTICompleteObjectLocator) <= size; offset += 4) { + auto* col = reinterpret_cast(data + offset); + + uint32_t signature = load_and_swap(&col->signature); + uint32_t typeDescPtr = load_and_swap(&col->pTypeDescriptor); + + // COL signature must be 0 for 32-bit MSVC RTTI + if (signature != 0) { + continue; + } + + // Type descriptor must point to valid memory + const auto* typeDescSection = binary_.findSection(typeDescPtr); + if (!typeDescSection || !typeDescSection->data) { + continue; + } + + // Check if type descriptor has ".?AV" mangling prefix + std::string typeName = readString(typeDescPtr + 8, 64); + if (typeName.find(".?AV") != 0 && typeName.find(".?AU") != 0) { + continue; + } + + uint32_t colAddr = base + static_cast(offset); + cols.push_back(colAddr); + + REXCODEGEN_TRACE("VTableScanner: found COL at 0x{:08X} -> {}", colAddr, typeName); + } + + return cols; +} + +std::optional VTableScanner::findVTableForCOL(uint32_t colAddr) { + // The vtable pointer to COL is stored at vtable[-1] + // So we need to find a dword in .rdata that contains colAddr, + // and the vtable starts at that address + 4 + + const auto* rdata = binary_.findSectionByName(".rdata"); + if (!rdata || !rdata->data) { + return std::nullopt; + } + + const uint8_t* data = rdata->data; + uint32_t base = rdata->baseAddress; + size_t size = rdata->size; + + for (size_t offset = 0; offset + 4 <= size; offset += 4) { + uint32_t value = load_and_swap(data + offset); + + if (value == colAddr) { + // Found reference to COL - vtable starts at next dword + uint32_t vtableAddr = base + static_cast(offset) + 4; + return vtableAddr; + } + } + + return std::nullopt; +} + +std::vector VTableScanner::readVTableSlots(uint32_t vtableStart) { + std::vector slots; + + uint32_t slotAddr = vtableStart; + + while (true) { + auto funcAddr = readDword(slotAddr); + if (!funcAddr) { + break; // Can't read memory + } + + uint32_t addr = *funcAddr; + + // Termination: null pointer + if (addr == 0) { + break; + } + + // Termination: not executable address + if (!isExecutableAddress(addr)) { + break; + } + + // Termination: not 4-byte aligned (PPC requirement) + if (addr & 0x3) { + break; + } + + slots.push_back(addr); + slotAddr += 4; + } + + return slots; +} + +std::string VTableScanner::extractClassName(uint32_t colAddr) { + auto typeDescPtr = readDword(colAddr + 12); // pTypeDescriptor offset + if (!typeDescPtr) { + return ""; + } + + // Class name is at typeDescriptor + 8 + std::string mangled = readString(*typeDescPtr + 8, 256); + + // Simple demangling: ".?AVClassName@@" -> "ClassName" + if (mangled.size() > 4 && (mangled.substr(0, 4) == ".?AV" || mangled.substr(0, 4) == ".?AU")) { + size_t end = mangled.find("@@"); + if (end != std::string::npos) { + return mangled.substr(4, end - 4); + } + } + + return mangled; +} + +bool VTableScanner::isExecutableAddress(uint32_t addr) const { + return binary_.isExecutable(addr); +} + +std::optional VTableScanner::readDword(uint32_t addr) const { + const auto* section = binary_.findSection(addr); + if (!section || !section->data) { + return std::nullopt; + } + + uint32_t offset = addr - section->baseAddress; + if (offset + 4 > section->size) { + return std::nullopt; + } + + return load_and_swap(section->data + offset); +} + +std::string VTableScanner::readString(uint32_t addr, size_t maxLen) const { + const auto* section = binary_.findSection(addr); + if (!section || !section->data) { + return ""; + } + + uint32_t offset = addr - section->baseAddress; + size_t available = section->size - offset; + size_t len = std::min(maxLen, available); + + const char* str = reinterpret_cast(section->data + offset); + size_t actualLen = strnlen(str, len); + + return std::string(str, actualLen); +} + +} // namespace rex::codegen diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt new file mode 100644 index 0000000..44e1005 --- /dev/null +++ b/src/core/CMakeLists.txt @@ -0,0 +1,105 @@ +# rexcore - Core utilities library +# Foundation types, data structures, and threading primitives + +add_library(rexcore OBJECT + arena.cpp + bit_map.cpp + bit_stream.cpp + byte_stream.cpp + clock.cpp + cvar.cpp + exception_handler.cpp + filesystem.cpp + filesystem_wildcard.cpp + logging.cpp + memory.cpp + mutex.cpp + ring_buffer.cpp + sha256.cpp + string.cpp + string_buffer.cpp + threading.cpp + timer_queue.cpp + utf8.cpp + vec128.cpp +) +add_library(rex::core ALIAS rexcore) + +# Platform-specific sources +if(WIN32) + target_sources(rexcore PRIVATE + atomic_win.cpp + clock_win.cpp + dbg_win.cpp + dynlib_win.cpp + exception_handler_win.cpp + filesystem_win.cpp + fiber_win32.cpp + mapped_memory_win.cpp + math_msvc.cpp + memory_win.cpp + seh_win.cpp + socket_win.cpp + string_win.cpp + system_win.cpp + threading_win.cpp + ) +elseif(UNIX) + target_sources(rexcore PRIVATE + atomic_posix.cpp + clock_posix.cpp + dbg_posix.cpp + dynlib_posix.cpp + exception_handler_posix.cpp + filesystem_posix.cpp + fiber_posix.cpp + mapped_memory_posix.cpp + math_gcc.cpp + memory_posix.cpp + seh_posix.cpp + socket_posix.cpp + string_posix.cpp + system_posix.cpp + threading_posix.cpp + ) +endif() + +target_include_directories(rexcore PUBLIC + $ + $ + $ +) + +target_include_directories(rexcore PRIVATE + ${PROJECT_SOURCE_DIR} + ${PROJECT_SOURCE_DIR}/thirdparty/cli11/include +) + +if(UNIX) + target_link_libraries(rexcore PRIVATE pthread rt dl) +elseif(WIN32) + target_link_libraries(rexcore PUBLIC ws2_32) +endif() + +target_link_libraries(rexcore + PUBLIC + fmt::fmt + simde + tomlplusplus + spdlog::spdlog + PRIVATE + disruptorplus + utf8cpp +) + +if(REXGLUE_ENABLE_TRACY) + target_link_libraries(rexcore PUBLIC TracyClient) + target_compile_definitions(rexcore PUBLIC + $<$>:REXGLUE_ENABLE_PROFILING>) +endif() + +if(REXGLUE_ENABLE_PERF_COUNTERS) + target_sources(rexcore PRIVATE perf/counter.cpp) + target_compile_definitions(rexcore PUBLIC + $<$>:REXGLUE_ENABLE_PERF_COUNTERS>) +endif() diff --git a/src/core/arena.cpp b/src/core/arena.cpp new file mode 100644 index 0000000..71e926a --- /dev/null +++ b/src/core/arena.cpp @@ -0,0 +1,141 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include + +namespace rex::memory { + +Arena::Arena(size_t chunk_size) + : chunk_size_(chunk_size), head_chunk_(nullptr), active_chunk_(nullptr) {} + +Arena::~Arena() { + Reset(); + Chunk* chunk = head_chunk_; + while (chunk) { + Chunk* next = chunk->next; + delete chunk; + chunk = next; + } + head_chunk_ = nullptr; +} + +void Arena::Reset() { + active_chunk_ = head_chunk_; + if (active_chunk_) { + active_chunk_->offset = 0; + } +} + +void Arena::DebugFill() { + auto chunk = head_chunk_; + while (chunk) { + std::memset(chunk->buffer, 0xCD, chunk->capacity); + chunk = chunk->next; + } +} + +void* Arena::Alloc(size_t size, size_t align) { + assert_true(align > 0 && rex::is_pow2(align) && align <= 16, + "align needs to be a power of 2 and not greater than Chunk alignment"); + + // for alignment + const auto get_padding = [this, align]() -> size_t { + const size_t mask = align - 1; + size_t deviation = active_chunk_->offset & mask; + return (align - deviation) & mask; + }; + + if (active_chunk_) { + if (active_chunk_->capacity - active_chunk_->offset < size + get_padding() + 4_KiB) { + Chunk* next = active_chunk_->next; + if (!next) { + assert_true(size + get_padding() < chunk_size_, "need to support larger chunks"); + next = new Chunk(chunk_size_); + active_chunk_->next = next; + } + next->offset = 0; + active_chunk_ = next; + } + } else { + head_chunk_ = active_chunk_ = new Chunk(chunk_size_); + } + + active_chunk_->offset += get_padding(); + uint8_t* p = active_chunk_->buffer + active_chunk_->offset; + active_chunk_->offset += size; + assert_true((reinterpret_cast(p) & (align - 1)) == 0, "alignment failed"); + return p; +} + +void Arena::Rewind(size_t size) { + active_chunk_->offset -= size; +} + +size_t Arena::CalculateSize() { + size_t total_length = 0; + Chunk* chunk = head_chunk_; + while (chunk) { + total_length += chunk->offset; + if (chunk == active_chunk_) { + break; + } + chunk = chunk->next; + } + return total_length; +} + +void* Arena::CloneContents() { + size_t total_length = CalculateSize(); + auto result = reinterpret_cast(malloc(total_length)); + auto p = result; + Chunk* chunk = head_chunk_; + while (chunk) { + std::memcpy(p, chunk->buffer, chunk->offset); + p += chunk->offset; + if (chunk == active_chunk_) { + break; + } + chunk = chunk->next; + } + return result; +} + +void Arena::CloneContents(void* buffer, size_t buffer_length) { + assert_true(buffer_length >= CalculateSize(), "destination buffer is too small"); + uint8_t* p = reinterpret_cast(buffer); + Chunk* chunk = head_chunk_; + while (chunk) { + std::memcpy(p, chunk->buffer, chunk->offset); + p += chunk->offset; + if (chunk == active_chunk_) { + break; + } + chunk = chunk->next; + } +} + +Arena::Chunk::Chunk(size_t chunk_size) : next(nullptr), capacity(chunk_size), buffer(0), offset(0) { + buffer = reinterpret_cast(malloc(capacity)); + assert_true((reinterpret_cast(buffer) & size_t(15)) == 0, "16 byte alignment required"); +} + +Arena::Chunk::~Chunk() { + if (buffer) { + free(buffer); + } +} + +} // namespace rex::memory diff --git a/src/core/atomic_posix.cpp b/src/core/atomic_posix.cpp new file mode 100644 index 0000000..378aa4b --- /dev/null +++ b/src/core/atomic_posix.cpp @@ -0,0 +1,42 @@ +#include +#include + +static_assert(REX_PLATFORM_LINUX || REX_PLATFORM_MAC, "This file is POSIX-only"); + +namespace rex::thread { + +int32_t atomic_inc(volatile int32_t* value) { + return __sync_add_and_fetch(value, 1); +} +int32_t atomic_dec(volatile int32_t* value) { + return __sync_sub_and_fetch(value, 1); +} + +int32_t atomic_exchange(int32_t new_value, volatile int32_t* value) { + return __atomic_exchange_n(value, new_value, __ATOMIC_SEQ_CST); +} +int64_t atomic_exchange(int64_t new_value, volatile int64_t* value) { + return __atomic_exchange_n(value, new_value, __ATOMIC_SEQ_CST); +} + +int32_t atomic_exchange_add(int32_t amount, volatile int32_t* value) { + return __sync_fetch_and_add(value, amount); +} +int64_t atomic_exchange_add(int64_t amount, volatile int64_t* value) { + return __sync_fetch_and_add(value, amount); +} + +bool atomic_cas(int32_t old_value, int32_t new_value, volatile int32_t* value) { + return __sync_bool_compare_and_swap(reinterpret_cast(value), old_value, + new_value); +} +bool atomic_cas(int64_t old_value, int64_t new_value, volatile int64_t* value) { + return __sync_bool_compare_and_swap(reinterpret_cast(value), old_value, + new_value); +} + +void atomic_store_release(int32_t new_value, volatile int32_t* value) { + __atomic_store_n(value, new_value, __ATOMIC_RELEASE); +} + +} // namespace rex::thread diff --git a/src/core/atomic_win.cpp b/src/core/atomic_win.cpp new file mode 100644 index 0000000..11bce24 --- /dev/null +++ b/src/core/atomic_win.cpp @@ -0,0 +1,44 @@ +#include +#include + +static_assert(REX_PLATFORM_WIN32, "This file is Windows-only"); + +#include + +namespace rex::thread { + +int32_t atomic_inc(volatile int32_t* value) { + return _InterlockedIncrement(reinterpret_cast(value)); +} +int32_t atomic_dec(volatile int32_t* value) { + return _InterlockedDecrement(reinterpret_cast(value)); +} + +int32_t atomic_exchange(int32_t new_value, volatile int32_t* value) { + return _InterlockedExchange(reinterpret_cast(value), new_value); +} +int64_t atomic_exchange(int64_t new_value, volatile int64_t* value) { + return _InterlockedExchange64(reinterpret_cast(value), new_value); +} + +int32_t atomic_exchange_add(int32_t amount, volatile int32_t* value) { + return _InterlockedExchangeAdd(reinterpret_cast(value), amount); +} +int64_t atomic_exchange_add(int64_t amount, volatile int64_t* value) { + return _InterlockedExchangeAdd64(reinterpret_cast(value), amount); +} + +bool atomic_cas(int32_t old_value, int32_t new_value, volatile int32_t* value) { + return _InterlockedCompareExchange(reinterpret_cast(value), new_value, + old_value) == old_value; +} +bool atomic_cas(int64_t old_value, int64_t new_value, volatile int64_t* value) { + return _InterlockedCompareExchange64(reinterpret_cast(value), new_value, + old_value) == old_value; +} + +void atomic_store_release(int32_t new_value, volatile int32_t* value) { + _InterlockedExchange(reinterpret_cast(value), new_value); +} + +} // namespace rex::thread diff --git a/src/core/bit_map.cpp b/src/core/bit_map.cpp new file mode 100644 index 0000000..effc247 --- /dev/null +++ b/src/core/bit_map.cpp @@ -0,0 +1,99 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +namespace rex::bit { + +BitMap::BitMap() = default; + +BitMap::BitMap(size_t size_bits) { + Resize(size_bits); +} + +BitMap::BitMap(uint64_t* data, size_t size_bits) { + assert_true(size_bits % kDataSizeBits == 0); + + data_.resize(size_bits / kDataSizeBits); + std::memcpy(data_.data(), data, size_bits / kDataSizeBits); +} + +size_t BitMap::Acquire() { + for (size_t i = 0; i < data_.size(); i++) { + uint64_t entry = 0; + uint64_t new_entry = 0; + int64_t acquired_idx = -1; + + do { + entry = data_[i]; + uint8_t index = lzcnt(entry); + if (index == kDataSizeBits) { + // None free. + acquired_idx = -1; + break; + } + + // Entry has a free bit. Acquire it. + uint64_t bit = 1ull << (kDataSizeBits - index - 1); + new_entry = entry & ~bit; + assert_not_zero(entry & bit); + + acquired_idx = index; + } while (!thread::atomic_cas(entry, new_entry, &data_[i])); + + if (acquired_idx != -1) { + // Acquired. + return (i * kDataSizeBits) + acquired_idx; + } + } + + return -1; +} + +void BitMap::Release(size_t index) { + auto slot = index / kDataSizeBits; + index -= slot * kDataSizeBits; + + uint64_t bit = 1ull << (kDataSizeBits - index - 1); + + uint64_t entry = 0; + uint64_t new_entry = 0; + do { + entry = data_[slot]; + assert_zero(entry & bit); + + new_entry = entry | bit; + } while (!thread::atomic_cas(entry, new_entry, &data_[slot])); +} + +void BitMap::Resize(size_t new_size_bits) { + auto old_size = data_.size(); + assert_true(new_size_bits % kDataSizeBits == 0); + data_.resize(new_size_bits / kDataSizeBits); + + // Initialize new entries. + if (data_.size() > old_size) { + for (size_t i = old_size; i < data_.size(); i++) { + data_[i] = -1; + } + } +} + +void BitMap::Reset() { + for (size_t i = 0; i < data_.size(); i++) { + data_[i] = -1; + } +} + +} // namespace rex::bit \ No newline at end of file diff --git a/src/core/bit_stream.cpp b/src/core/bit_stream.cpp new file mode 100644 index 0000000..9329c6d --- /dev/null +++ b/src/core/bit_stream.cpp @@ -0,0 +1,154 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include + +namespace rex::stream { + +BitStream::BitStream(uint8_t* buffer, size_t size_in_bits) + : buffer_(buffer), size_bits_(size_in_bits) {} + +BitStream::~BitStream() = default; + +void BitStream::SetOffset(size_t offset_bits) { + assert_false(offset_bits > size_bits_); + offset_bits_ = std::min(offset_bits, size_bits_); +} + +size_t BitStream::BitsRemaining() { + return size_bits_ - offset_bits_; +} + +uint64_t BitStream::Peek(size_t num_bits) { + // FYI: The reason we can't copy more than 57 bits is: + // 57 = 7 * 8 + 1 - that can only span a maximum of 8 bytes. + // We can't read in 9 bytes (easily), so we limit it. + assert_false(num_bits > 57); + assert_false(offset_bits_ + num_bits > size_bits_); + + size_t offset_bytes = offset_bits_ >> 3; + size_t rel_offset_bits = offset_bits_ - (offset_bytes << 3); + + // offset --> + // ..[junk]..| target bits |....[junk]............. + uint64_t bits = *(uint64_t*)(buffer_ + offset_bytes); + + // We need the data in little endian. + // TODO: Have a flag specifying endianness of data? + bits = rex::byte_swap(bits); + + // Shift right + // .....[junk]........| target bits | + bits >>= 64 - (rel_offset_bits + num_bits); + + // AND with mask + // ...................| target bits | + bits &= (1ULL << num_bits) - 1; + + return bits; +} + +uint64_t BitStream::Read(size_t num_bits) { + uint64_t val = Peek(num_bits); + Advance(num_bits); + + return val; +} + +// TODO: This is totally not tested! +bool BitStream::Write(uint64_t val, size_t num_bits) { + assert_false(num_bits > 57); + assert_false(offset_bits_ + num_bits >= size_bits_); + + size_t offset_bytes = offset_bits_ >> 3; + size_t rel_offset_bits = offset_bits_ - (offset_bytes << 3); + + // Construct a mask + uint64_t mask = (1ULL << num_bits) - 1; + mask <<= 64 - (rel_offset_bits + num_bits); + mask = ~mask; + + // Shift the value left into position. + val <<= 64 - (rel_offset_bits + num_bits); + + // offset -----> + // ....[junk]...| target bits w/ junk |....[junk]...... + uint64_t bits = *(uint64_t*)(buffer_ + offset_bytes); + + // AND with mask + // ....[junk]...| target bits (0) |........[junk]...... + bits &= mask; + + // OR with val + // ....[junk]...| target bits (val) |......[junk]...... + bits |= val; + + // Store into the bitstream. + *(uint64_t*)(buffer_ + offset_bytes) = bits; + + // Advance the bitstream forward. + Advance(num_bits); + + return true; +} + +size_t BitStream::Copy(uint8_t* dest_buffer, size_t num_bits) { + size_t offset_bytes = offset_bits_ >> 3; + size_t rel_offset_bits = offset_bits_ - (offset_bytes << 3); + size_t bits_left = num_bits; + size_t out_offset_bytes = 0; + + // First: Copy the first few bits up to a byte boundary. + if (rel_offset_bits) { + uint64_t bits = Peek(8 - rel_offset_bits); + uint8_t clear_mask = ~((uint8_t(1) << rel_offset_bits) - 1); + dest_buffer[out_offset_bytes] &= clear_mask; + dest_buffer[out_offset_bytes] |= (uint8_t)bits; + + bits_left -= 8 - rel_offset_bits; + Advance(8 - rel_offset_bits); + out_offset_bytes++; + } + + // Second: Use memcpy for the bytes left. + if (bits_left >= 8) { + std::memcpy(dest_buffer + out_offset_bytes, buffer_ + offset_bytes + out_offset_bytes, + bits_left / 8); + out_offset_bytes += (bits_left / 8); + Advance((bits_left / 8) * 8); + bits_left -= (bits_left / 8) * 8; + } + + // Third: Copy the last few bits. + if (bits_left) { + uint64_t bits = Peek(bits_left); + bits <<= 8 - bits_left; + + uint8_t clear_mask = ((uint8_t(1) << bits_left) - 1); + dest_buffer[out_offset_bytes] &= clear_mask; + dest_buffer[out_offset_bytes] |= (uint8_t)bits; + Advance(bits_left); + } + + // Return the bit offset to the copied bits. + return rel_offset_bits; +} + +void BitStream::Advance(size_t num_bits) { + SetOffset(offset_bits_ + num_bits); +} + +} // namespace rex::stream diff --git a/src/core/byte_stream.cpp b/src/core/byte_stream.cpp new file mode 100644 index 0000000..3dd190e --- /dev/null +++ b/src/core/byte_stream.cpp @@ -0,0 +1,60 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include + +namespace rex::stream { + +ByteStream::ByteStream(uint8_t* data, size_t data_length, size_t offset) + : data_(data), data_length_(data_length), offset_(offset) {} + +ByteStream::~ByteStream() = default; + +void ByteStream::Advance(size_t num_bytes) { + assert_true(offset_ + num_bytes <= data_length_); + offset_ += num_bytes; +} + +void ByteStream::Read(std::span buf) { + assert_true(offset_ + buf.size() <= data_length_); + std::memcpy(buf.data(), data_ + offset_, buf.size()); + Advance(buf.size()); +} + +void ByteStream::Write(std::span buf) { + assert_true(offset_ + buf.size() <= data_length_); + std::memcpy(data_ + offset_, buf.data(), buf.size()); + Advance(buf.size()); +} + +template <> +std::string ByteStream::Read() { + std::string str; + uint32_t len = Read(); + str.resize(len); + Read(std::span(reinterpret_cast(str.data()), len)); + return str; +} + +template <> +std::u16string ByteStream::Read() { + std::u16string str; + size_t len = Read(); + str.resize(len); + Read(std::span(reinterpret_cast(str.data()), len * sizeof(char16_t))); + return str; +} + +} // namespace rex::stream diff --git a/src/core/clock.cpp b/src/core/clock.cpp new file mode 100644 index 0000000..ae72b7a --- /dev/null +++ b/src/core/clock.cpp @@ -0,0 +1,244 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2019 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include +#include + +REXCVAR_DEFINE_BOOL(clock_no_scaling, false, "Clock", + "Disable clock scaling (inverted: false = scaling enabled)"); + +REXCVAR_DEFINE_BOOL(clock_source_raw, false, "Clock", "Use raw clock source without scaling"); + +namespace rex::chrono { + +// Time scalar applied to all time operations. +double guest_time_scalar_ = 1.0; +// Tick frequency of guest. +uint64_t guest_tick_frequency_ = Clock::host_tick_frequency_platform(); +// Base FILETIME of the guest system from app start. +uint64_t guest_system_time_base_ = Clock::QueryHostSystemTime(); +// Combined time and frequency ratio between host and guest. +// Split in numerator (first) and denominator (second). +// Computed by RecomputeGuestTickScalar. +std::pair guest_tick_ratio_ = std::make_pair(1, 1); + +// Native guest ticks. +uint64_t last_guest_tick_count_ = 0; +// Last sampled host tick count. +uint64_t last_host_tick_count_ = Clock::QueryHostTickCount(); +// Mutex to ensure last_host_tick_count_ and last_guest_tick_count_ are in sync +std::mutex tick_mutex_; + +void RecomputeGuestTickScalar() { + // Create a rational number with numerator (first) and denominator (second) + auto frac = std::make_pair(guest_tick_frequency_, Clock::QueryHostTickFrequency()); + // Doing it this way ensures we don't mess up our frequency scaling and + // precisely controls the precision the guest_time_scalar_ can have. + if (guest_time_scalar_ > 1.0) { + frac.first *= static_cast(guest_time_scalar_ * 10.0); + frac.second *= 10; + } else { + frac.first *= 10; + frac.second *= static_cast(10.0 / guest_time_scalar_); + } + // Keep this a rational calculation and reduce the fraction + reduce_fraction(frac); + + std::lock_guard lock(tick_mutex_); + guest_tick_ratio_ = frac; +} + +// Update the guest timer for all threads. +// Return a copy of the value so locking is reduced. +uint64_t UpdateGuestClock() { + uint64_t host_tick_count = Clock::QueryHostTickCount(); + + if (REXCVAR_GET(clock_no_scaling)) { + // Nothing to update, calculate on the fly + return host_tick_count * guest_tick_ratio_.first / guest_tick_ratio_.second; + } + + std::unique_lock lock(tick_mutex_, std::defer_lock); + if (lock.try_lock()) { + // Translate host tick count to guest tick count. + uint64_t host_tick_delta = + host_tick_count > last_host_tick_count_ ? host_tick_count - last_host_tick_count_ : 0; + last_host_tick_count_ = host_tick_count; + uint64_t guest_tick_delta = + host_tick_delta * guest_tick_ratio_.first / guest_tick_ratio_.second; + last_guest_tick_count_ += guest_tick_delta; + return last_guest_tick_count_; + } else { + // Wait until another thread has finished updating the clock. + lock.lock(); + return last_guest_tick_count_; + } +} + +// Offset of the current guest system file time relative to the guest base time. +inline uint64_t QueryGuestSystemTimeOffset() { + if (REXCVAR_GET(clock_no_scaling)) { + return Clock::QueryHostSystemTime() - guest_system_time_base_; + } + + auto guest_tick_count = UpdateGuestClock(); + + uint64_t numerator = 10000000; // 100ns/10MHz resolution + uint64_t denominator = guest_tick_frequency_; + reduce_fraction(numerator, denominator); + + return guest_tick_count * numerator / denominator; +} + +uint64_t Clock::QueryHostTickFrequency() { +#if REX_CLOCK_RAW_AVAILABLE + if (REXCVAR_GET(clock_source_raw)) { + return host_tick_frequency_raw(); + } +#endif + return host_tick_frequency_platform(); +} +uint64_t Clock::QueryHostTickCount() { +#if REX_CLOCK_RAW_AVAILABLE + if (REXCVAR_GET(clock_source_raw)) { + return host_tick_count_raw(); + } +#endif + return host_tick_count_platform(); +} + +double Clock::guest_time_scalar() { + return guest_time_scalar_; +} + +void Clock::set_guest_time_scalar(double scalar) { + if (REXCVAR_GET(clock_no_scaling)) { + return; + } + + guest_time_scalar_ = scalar; + RecomputeGuestTickScalar(); +} + +std::pair Clock::guest_tick_ratio() { + std::lock_guard lock(tick_mutex_); + return guest_tick_ratio_; +} + +uint64_t Clock::guest_tick_frequency() { + return guest_tick_frequency_; +} + +void Clock::set_guest_tick_frequency(uint64_t frequency) { + guest_tick_frequency_ = frequency; + RecomputeGuestTickScalar(); +} + +uint64_t Clock::guest_system_time_base() { + return guest_system_time_base_; +} + +void Clock::set_guest_system_time_base(uint64_t time_base) { + guest_system_time_base_ = time_base; +} + +uint64_t Clock::QueryGuestTickCount() { + auto guest_tick_count = UpdateGuestClock(); + return guest_tick_count; +} + +uint64_t Clock::QueryGuestSystemTime() { + if (REXCVAR_GET(clock_no_scaling)) { + return Clock::QueryHostSystemTime(); + } + + auto guest_system_time_offset = QueryGuestSystemTimeOffset(); + return guest_system_time_base_ + guest_system_time_offset; +} + +uint32_t Clock::QueryGuestUptimeMillis() { + return static_cast(std::min(QueryGuestSystemTimeOffset() / 10000, + std::numeric_limits::max())); +} + +void Clock::SetGuestSystemTime(uint64_t system_time) { + if (REXCVAR_GET(clock_no_scaling)) { + // Time is fixed to host time. + return; + } + + // Query the filetime offset to calculate a new base time. + auto guest_system_time_offset = QueryGuestSystemTimeOffset(); + guest_system_time_base_ = system_time - guest_system_time_offset; +} + +uint32_t Clock::ScaleGuestDurationMillis(uint32_t guest_ms) { + if (REXCVAR_GET(clock_no_scaling)) { + return guest_ms; + } + + constexpr uint64_t max = std::numeric_limits::max(); + + if (guest_ms >= max) { + return max; + } else if (!guest_ms) { + return 0; + } + uint64_t scaled_ms = + static_cast((static_cast(guest_ms) * guest_time_scalar_)); + return static_cast(std::min(scaled_ms, max)); +} + +int64_t Clock::ScaleGuestDurationFileTime(int64_t guest_file_time) { + if (REXCVAR_GET(clock_no_scaling)) { + return static_cast(guest_file_time); + } + + if (!guest_file_time) { + return 0; + } else if (guest_file_time > 0) { + // Absolute time. + uint64_t guest_time = Clock::QueryGuestSystemTime(); + int64_t relative_time = guest_file_time - static_cast(guest_time); + int64_t scaled_time = static_cast(relative_time * guest_time_scalar_); + return static_cast(guest_time) + scaled_time; + } else { + // Relative time. + uint64_t scaled_file_time = + static_cast((static_cast(guest_file_time) * guest_time_scalar_)); + // TODO(benvanik): check for overflow? + return scaled_file_time; + } +} + +void Clock::ScaleGuestDurationTimeval(int32_t* tv_sec, int32_t* tv_usec) { + if (REXCVAR_GET(clock_no_scaling)) { + return; + } + + uint64_t scaled_sec = static_cast(static_cast(*tv_sec) * guest_time_scalar_); + uint64_t scaled_usec = + static_cast(static_cast(*tv_usec) * guest_time_scalar_); + if (scaled_usec > std::numeric_limits::max()) { + uint64_t overflow_sec = scaled_usec / 1000000; + scaled_usec -= overflow_sec * 1000000; + scaled_sec += overflow_sec; + } + *tv_sec = int32_t(scaled_sec); + *tv_usec = int32_t(scaled_usec); +} + +} // namespace rex::chrono diff --git a/src/core/clock_posix.cpp b/src/core/clock_posix.cpp new file mode 100644 index 0000000..53b4462 --- /dev/null +++ b/src/core/clock_posix.cpp @@ -0,0 +1,56 @@ +/** + * @file core/clock_posix.cpp + * @brief POSIX platform clock implementations + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include +#include +#include + +static_assert(REX_PLATFORM_LINUX || REX_PLATFORM_MAC, "This file is POSIX-only"); + +#include + +namespace rex::chrono { + +uint64_t Clock::host_tick_frequency_platform() { + timespec res; + int error = clock_getres(CLOCK_MONOTONIC_RAW, &res); + assert_zero(error); + assert_zero(res.tv_sec); // Sub second resolution is required. + + // Convert nano seconds to hertz. Resolution is 1ns on most systems. + return 1000000000ull / res.tv_nsec; +} + +uint64_t Clock::host_tick_count_platform() { + timespec tp; + int error = clock_gettime(CLOCK_MONOTONIC_RAW, &tp); + assert_zero(error); + + return tp.tv_nsec + tp.tv_sec * 1000000000ull; +} + +uint64_t Clock::QueryHostSystemTime() { + // https://docs.microsoft.com/en-us/windows/win32/sysinfo/converting-a-time-t-value-to-a-file-time + constexpr uint64_t seconds_per_day = 3600 * 24; + // Don't forget the 89 leap days. + constexpr uint64_t seconds_1601_to_1970 = ((369 * 365 + 89) * seconds_per_day); + + timeval now; + int error = gettimeofday(&now, nullptr); + assert_zero(error); + + // NT systems use 100ns intervals. + return static_cast( + (static_cast(now.tv_sec) + seconds_1601_to_1970) * 10000000ull + now.tv_usec * 10); +} + +uint64_t Clock::QueryHostUptimeMillis() { + return host_tick_count_platform() * 1000 / host_tick_frequency_platform(); +} + +} // namespace rex::chrono diff --git a/src/core/clock_win.cpp b/src/core/clock_win.cpp new file mode 100644 index 0000000..440f155 --- /dev/null +++ b/src/core/clock_win.cpp @@ -0,0 +1,43 @@ +/** + * @file core/clock_win.cpp + * @brief Windows platform clock implementations + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include +#include + +static_assert(REX_PLATFORM_WIN32, "This file is Windows-only"); + +#include "platform_win.h" + +namespace rex::chrono { + +uint64_t Clock::host_tick_frequency_platform() { + LARGE_INTEGER frequency; + QueryPerformanceFrequency(&frequency); + return frequency.QuadPart; +} + +uint64_t Clock::host_tick_count_platform() { + LARGE_INTEGER counter; + uint64_t time = 0; + if (QueryPerformanceCounter(&counter)) { + time = counter.QuadPart; + } + return time; +} + +uint64_t Clock::QueryHostSystemTime() { + FILETIME t; + GetSystemTimeAsFileTime(&t); + return (uint64_t(t.dwHighDateTime) << 32) | t.dwLowDateTime; +} + +uint64_t Clock::QueryHostUptimeMillis() { + return host_tick_count_platform() * 1000 / host_tick_frequency_platform(); +} + +} // namespace rex::chrono diff --git a/src/core/cvar.cpp b/src/core/cvar.cpp new file mode 100644 index 0000000..fa69487 --- /dev/null +++ b/src/core/cvar.cpp @@ -0,0 +1,578 @@ +/** + * @file cvar.cpp + * @brief Configuration variable system implementation + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +namespace rex::cvar { + +namespace { + +bool g_finalized = false; +bool g_lifecycle_override = false; +std::mutex g_mutex; + +// Recursive: FlagRegistrar chain methods re-enter; change callbacks invoked +// from SetFlagByName must not mutate the registry. +std::recursive_mutex& GetRegistryMutex() { + static std::recursive_mutex m; + return m; +} + +// Flag registry - use functions to avoid static init order issues +std::vector& GetRegistryStorage() { + static std::vector registry; + return registry; +} + +std::unordered_map& GetRegistryIndex() { + static std::unordered_map index; + return index; +} + +// Convert flag name to environment variable: gpu_vsync -> REX_GPU_VSYNC +std::string FlagNameToEnvVar(std::string_view name) { + std::string result = "REX_"; + for (char c : name) { + result += static_cast(std::toupper(static_cast(c))); + } + return result; +} + +// Recursively apply TOML values +void ApplyTomlTable(const toml::table& table, const std::string& prefix) { + for (const auto& [key, value] : table) { + std::string full_key = prefix.empty() ? std::string(key) : prefix + "_" + std::string(key); + + if (value.is_table()) { + ApplyTomlTable(*value.as_table(), full_key); + } else { + std::string value_str; + if (value.is_boolean()) { + value_str = value.as_boolean()->get() ? "true" : "false"; + } else if (value.is_integer()) { + value_str = std::to_string(value.as_integer()->get()); + } else if (value.is_floating_point()) { + value_str = std::to_string(value.as_floating_point()->get()); + } else if (value.is_string()) { + value_str = value.as_string()->get(); + } else { + REXLOG_WARN("Config: unsupported type for key '{}'", full_key); + continue; + } + + if (SetFlagByName(full_key, value_str)) { + REXLOG_DEBUG("Config: {} = {}", full_key, value_str); + } else { + REXLOG_WARN("Config: unknown cvar '{}'", full_key); + } + } + } +} + +// todo(tomc): move restart manager to Runtime +std::vector& GetPendingRestartStorage() { + static std::vector pending; + return pending; +} + +// Callback storage for change notifications +std::unordered_map>& GetCallbackStorage() { + static std::unordered_map> callbacks; + return callbacks; +} + +void MarkPendingRestart(std::string_view name) { + auto& pending = GetPendingRestartStorage(); + std::string name_str(name); + if (std::find(pending.begin(), pending.end(), name_str) == pending.end()) { + pending.push_back(name_str); + } +} + +bool ValidateConstraints(const FlagEntry& entry, std::string_view value) { + const auto& c = entry.constraints; + + // Range validation for numeric types + if (c.HasRangeConstraint()) { + double numeric_val = 0; + if (entry.type == FlagType::String || entry.type == FlagType::Boolean) { + // These types don't have numeric range constraints + } else if (entry.type == FlagType::Double) { + if (!ParseDouble(value, numeric_val)) + return false; + } else { + // Integer types + int64_t int_val = 0; + auto [ptr, ec] = std::from_chars(value.data(), value.data() + value.size(), int_val); + if (ec != std::errc()) + return false; + numeric_val = static_cast(int_val); + } + + if (c.min.has_value() && numeric_val < *c.min) { + REXLOG_WARN("Flag '{}': value {} below min ({})", entry.name, value, *c.min); + return false; + } + if (c.max.has_value() && numeric_val > *c.max) { + REXLOG_WARN("Flag '{}': value {} exceeds max ({})", entry.name, value, *c.max); + return false; + } + } + + // Allowed values validation + if (c.HasAllowedValues()) { + bool found = false; + for (const auto& allowed : c.allowed_values) { + if (allowed == value) { + found = true; + break; + } + } + if (!found) { + REXLOG_WARN("Flag '{}': '{}' not in allowed values", entry.name, value); + return false; + } + } + + // Custom validator + if (c.custom_validator && !c.custom_validator(value)) { + REXLOG_WARN("Flag '{}': custom validation failed for '{}'", entry.name, value); + return false; + } + + return true; +} + +} // namespace + +//============================================================================= +// Registry +//============================================================================= + +std::vector& GetRegistry() { + return GetRegistryStorage(); +} + +std::optional RegisterFlag(FlagEntry entry) { + std::lock_guard lock(GetRegistryMutex()); + (void)GetCallbackStorage(); + (void)GetPendingRestartStorage(); + auto& index = GetRegistryIndex(); + auto& storage = GetRegistryStorage(); + auto it = index.find(entry.name); + if (it != index.end()) { + REXLOG_ERROR("cvar: duplicate registration of '{}'; second registration ignored", entry.name); + return std::nullopt; + } + size_t pos = storage.size(); + index[entry.name] = pos; + storage.push_back(std::move(entry)); + return pos; +} + +void UnregisterFlag(std::string_view name) { + std::lock_guard lock(GetRegistryMutex()); + auto& index = GetRegistryIndex(); + auto& storage = GetRegistryStorage(); + std::string key(name); + auto idx_it = index.find(key); + if (idx_it == index.end()) { + return; + } + size_t pos = idx_it->second; + index.erase(idx_it); + storage.erase(storage.begin() + pos); + for (auto& [n, i] : index) { + if (i > pos) { + --i; + } + } + GetCallbackStorage().erase(key); + auto& pending = GetPendingRestartStorage(); + pending.erase(std::remove(pending.begin(), pending.end(), key), pending.end()); +} + +void FlagRegistrar::apply_(std::function fn) { + if (owned_name_.empty()) { + return; + } + std::lock_guard lock(GetRegistryMutex()); + auto& index = GetRegistryIndex(); + auto it = index.find(owned_name_); + if (it == index.end()) { + return; + } + fn(GetRegistryStorage()[it->second]); +} + +bool SetFlagByName(std::string_view name, std::string_view value) { + std::lock_guard lock(GetRegistryMutex()); + auto it = GetRegistryIndex().find(std::string(name)); + if (it == GetRegistryIndex().end()) { + return false; + } + + const auto& entry = GetRegistryStorage()[it->second]; + + // Check lifecycle + if (!g_lifecycle_override && entry.lifecycle == Lifecycle::kInitOnly && IsFinalized()) { + REXLOG_WARN("Cannot modify init-only flag '{}' after initialization", name); + return false; + } + + // Validate constraints + if (!ValidateConstraints(entry, value)) { + return false; + } + + bool success = entry.setter(value); + + // Track pending restart flags + if (success && entry.lifecycle == Lifecycle::kRequiresRestart) { + MarkPendingRestart(name); + } + + // Invoke registered callbacks + if (success) { + auto& callbacks = GetCallbackStorage(); + auto it = callbacks.find(std::string(name)); + if (it != callbacks.end()) { + for (const auto& callback : it->second) { + callback(name, value); + } + } + } + + return success; +} + +std::string GetFlagByName(std::string_view name) { + std::lock_guard lock(GetRegistryMutex()); + auto it = GetRegistryIndex().find(std::string(name)); + if (it == GetRegistryIndex().end()) { + return ""; + } + + return GetRegistryStorage()[it->second].getter(); +} + +std::vector ListFlags() { + std::lock_guard lock(GetRegistryMutex()); + std::vector result; + result.reserve(GetRegistryStorage().size()); + for (const auto& entry : GetRegistryStorage()) { + result.push_back(entry.name); + } + std::sort(result.begin(), result.end()); + return result; +} + +std::vector ListFlagsByCategory(std::string_view category) { + std::lock_guard lock(GetRegistryMutex()); + std::vector result; + for (const auto& entry : GetRegistryStorage()) { + if (entry.category == category) { + result.push_back(entry.name); + } + } + std::sort(result.begin(), result.end()); + return result; +} + +std::vector ListFlagsByLifecycle(Lifecycle lc) { + std::lock_guard lock(GetRegistryMutex()); + std::vector result; + for (const auto& entry : GetRegistryStorage()) { + if (entry.lifecycle == lc) { + result.push_back(entry.name); + } + } + std::sort(result.begin(), result.end()); + return result; +} + +const FlagEntry* GetFlagInfo(std::string_view name) { + // Pointer is invalidated by any subsequent registry call. + std::lock_guard lock(GetRegistryMutex()); + auto it = GetRegistryIndex().find(std::string(name)); + if (it == GetRegistryIndex().end()) { + return nullptr; + } + return &GetRegistryStorage()[it->second]; +} + +template <> +bool Query(std::string_view name) { + std::string v = GetFlagByName(name); + return v == "true" || v == "1" || v == "yes"; +} + +template <> +int32_t Query(std::string_view name) { + std::string v = GetFlagByName(name); + int32_t out = 0; + std::from_chars(v.data(), v.data() + v.size(), out); + return out; +} + +template <> +int64_t Query(std::string_view name) { + std::string v = GetFlagByName(name); + int64_t out = 0; + std::from_chars(v.data(), v.data() + v.size(), out); + return out; +} + +template <> +uint32_t Query(std::string_view name) { + std::string v = GetFlagByName(name); + uint32_t out = 0; + std::from_chars(v.data(), v.data() + v.size(), out); + return out; +} + +template <> +uint64_t Query(std::string_view name) { + std::string v = GetFlagByName(name); + uint64_t out = 0; + std::from_chars(v.data(), v.data() + v.size(), out); + return out; +} + +template <> +double Query(std::string_view name) { + std::string v = GetFlagByName(name); + double out = 0.0; + ParseDouble(v, out); + return out; +} + +template <> +std::string Query(std::string_view name) { + return GetFlagByName(name); +} + +std::vector GetPendingRestartFlags() { + std::lock_guard lock(GetRegistryMutex()); + return GetPendingRestartStorage(); +} + +void ClearPendingRestartFlags() { + std::lock_guard lock(GetRegistryMutex()); + GetPendingRestartStorage().clear(); +} + +void ResetToDefault(std::string_view name) { + std::lock_guard lock(GetRegistryMutex()); + auto it = GetRegistryIndex().find(std::string(name)); + if (it == GetRegistryIndex().end()) { + return; + } + const auto& entry = GetRegistryStorage()[it->second]; + entry.setter(entry.default_value); +} + +void ResetAllToDefaults() { + std::lock_guard lock(GetRegistryMutex()); + for (const auto& entry : GetRegistryStorage()) { + entry.setter(entry.default_value); + } +} + +bool HasNonDefaultValue(std::string_view name) { + std::lock_guard lock(GetRegistryMutex()); + auto it = GetRegistryIndex().find(std::string(name)); + if (it == GetRegistryIndex().end()) { + return false; + } + const auto& entry = GetRegistryStorage()[it->second]; + return entry.getter() != entry.default_value; +} + +std::vector ListModifiedFlags() { + std::lock_guard lock(GetRegistryMutex()); + std::vector result; + for (const auto& entry : GetRegistryStorage()) { + if (entry.getter() != entry.default_value) { + result.push_back(entry.name); + } + } + return result; +} + +std::string SerializeToTOML() { + std::lock_guard lock(GetRegistryMutex()); + std::string result; + for (const auto& entry : GetRegistryStorage()) { + if (entry.getter() != entry.default_value) { + if (entry.type == FlagType::String) { + result += entry.name + " = \"" + entry.getter() + "\"\n"; + } else { + result += entry.name + " = " + entry.getter() + "\n"; + } + } + } + return result; +} + +std::string SerializeToTOML(std::string_view category) { + std::lock_guard lock(GetRegistryMutex()); + std::string result; + for (const auto& entry : GetRegistryStorage()) { + if (entry.category == category && entry.getter() != entry.default_value) { + if (entry.type == FlagType::String) { + result += entry.name + " = \"" + entry.getter() + "\"\n"; + } else { + result += entry.name + " = " + entry.getter() + "\n"; + } + } + } + return result; +} + +void RegisterChangeCallback(std::string_view name, ChangeCallback callback) { + std::lock_guard lock(GetRegistryMutex()); + GetCallbackStorage()[std::string(name)].push_back(std::move(callback)); +} + +void UnregisterChangeCallbacks(std::string_view name) { + std::lock_guard lock(GetRegistryMutex()); + GetCallbackStorage().erase(std::string(name)); +} + +//============================================================================= +// Initialization +//============================================================================= + +std::vector Init(int argc, char** argv) { + CLI::App app{"", ""}; + app.allow_extras(); + + for (auto& entry : GetRegistryStorage()) { + if (entry.type == FlagType::Boolean) { + app.add_flag_function( + "--" + entry.name + ",!--no-" + entry.name, + [&entry](int64_t count) { entry.setter(count > 0 ? "true" : "false"); }, + entry.description); + } else { + app.add_option_function( + "--" + entry.name, [&entry](const std::string& val) { entry.setter(val); }, + entry.description); + } + } + + try { + app.parse(argc, argv); + } catch (const CLI::ParseError& e) { + // TODO(tomc): dumb workaround for the stupid chicken and its egg. + // dont call rex logging funcs here for now. + fprintf(stderr, "cvar: CLI11 parse error: %s\n", e.what()); + } + + return app.remaining(); +} + +void LoadConfig(const std::filesystem::path& config_path) { + if (!std::filesystem::exists(config_path)) { + REXLOG_DEBUG("Config file not found: {}", config_path.string()); + return; + } + + try { + auto config = toml::parse_file(config_path.string()); + ApplyTomlTable(config, ""); + REXLOG_INFO("Loaded config from {}", config_path.string()); + } catch (const toml::parse_error& err) { + REXLOG_ERROR("Failed to parse config {}: {}", config_path.string(), err.what()); + } +} + +void ApplyEnvironment() { + int count = 0; + for (const auto& entry : GetRegistryStorage()) { + std::string env_name = FlagNameToEnvVar(entry.name); + const char* env_value = std::getenv(env_name.c_str()); + if (env_value != nullptr) { + if (entry.setter(env_value)) { + REXLOG_DEBUG("Env: {} = {} (from {})", entry.name, env_value, env_name); + ++count; + } else { + REXLOG_WARN("Env: failed to parse {} = {}", env_name, env_value); + } + } + } + + if (count > 0) { + REXLOG_INFO("Applied {} environment variable override(s)", count); + } +} + +void FinalizeInit() { + std::lock_guard lock(g_mutex); + g_finalized = true; + REXLOG_DEBUG("cvar: initialization finalized"); +} + +bool IsFinalized() { + return g_finalized; +} + +void SaveConfig(const std::filesystem::path& config_path) { + std::string content = SerializeToTOML(); + if (content.empty()) { + REXLOG_DEBUG("SaveConfig: no modified flags to save"); + return; + } + + try { + std::ofstream file(config_path); + if (!file) { + REXLOG_ERROR("SaveConfig: failed to open {}", config_path.string()); + return; + } + file << "# Auto-generated cvar configuration\n"; + file << content; + REXLOG_INFO("Saved config to {}", config_path.string()); + } catch (const std::exception& e) { + REXLOG_ERROR("SaveConfig: {}", e.what()); + } +} + +namespace testing { + +ScopedLifecycleOverride::ScopedLifecycleOverride() { + g_lifecycle_override = true; +} + +ScopedLifecycleOverride::~ScopedLifecycleOverride() { + g_lifecycle_override = false; +} + +void ResetAllForTesting() { + ResetAllToDefaults(); + ClearPendingRestartFlags(); + g_finalized = false; +} + +} // namespace testing + +} // namespace rex::cvar diff --git a/src/core/dbg_posix.cpp b/src/core/dbg_posix.cpp new file mode 100644 index 0000000..a8dcba2 --- /dev/null +++ b/src/core/dbg_posix.cpp @@ -0,0 +1,61 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2017 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace rex::debug { + +bool IsDebuggerAttached() { + std::ifstream proc_status_stream("/proc/self/status"); + if (!proc_status_stream.is_open()) { + return false; + } + std::string line; + while (std::getline(proc_status_stream, line)) { + std::istringstream line_stream(line); + std::string key; + line_stream >> key; + if (key == "TracerPid:") { + uint32_t tracer_pid; + line_stream >> tracer_pid; + return tracer_pid != 0; + } + } + return false; +} + +void Break() { + static std::once_flag flag; + std::call_once(flag, []() { + // Install handler for sigtrap only once + std::signal(SIGTRAP, [](int) { + // Forward signal to default handler after being caught + std::signal(SIGTRAP, SIG_DFL); + }); + }); + std::raise(SIGTRAP); +} + +namespace detail { +void DebugPrint(const char* s) { + std::clog << s << std::endl; +} +} // namespace detail + +} // namespace rex::debug diff --git a/src/core/dbg_win.cpp b/src/core/dbg_win.cpp new file mode 100644 index 0000000..225c7d9 --- /dev/null +++ b/src/core/dbg_win.cpp @@ -0,0 +1,33 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include "platform_win.h" + +#include +#include + +namespace rex::debug { + +bool IsDebuggerAttached() { + return IsDebuggerPresent() ? true : false; +} + +void Break() { + __debugbreak(); +} + +namespace detail { +void DebugPrint(const char* s) { + OutputDebugStringA(s); +} +} // namespace detail + +} // namespace rex::debug diff --git a/src/core/dynlib_posix.cpp b/src/core/dynlib_posix.cpp new file mode 100644 index 0000000..ca1994c --- /dev/null +++ b/src/core/dynlib_posix.cpp @@ -0,0 +1,46 @@ +#include +#include + +static_assert(REX_PLATFORM_LINUX || REX_PLATFORM_MAC, "This file is POSIX-only"); + +#include + +namespace rex::platform { + +DynamicLibrary::~DynamicLibrary() { + Close(); +} + +DynamicLibrary::DynamicLibrary(DynamicLibrary&& other) noexcept : handle_(other.handle_) { + other.handle_ = nullptr; +} + +DynamicLibrary& DynamicLibrary::operator=(DynamicLibrary&& other) noexcept { + if (this != &other) { + Close(); + handle_ = other.handle_; + other.handle_ = nullptr; + } + return *this; +} + +bool DynamicLibrary::Load(const std::filesystem::path& path) { + Close(); + handle_ = dlopen(path.c_str(), RTLD_LAZY); + return handle_ != nullptr; +} + +void DynamicLibrary::Close() { + if (handle_) { + dlclose(handle_); + handle_ = nullptr; + } +} + +void* DynamicLibrary::GetRawSymbol(const char* name) const { + if (!handle_) + return nullptr; + return dlsym(handle_, name); +} + +} // namespace rex::platform diff --git a/src/core/dynlib_win.cpp b/src/core/dynlib_win.cpp new file mode 100644 index 0000000..73a48d5 --- /dev/null +++ b/src/core/dynlib_win.cpp @@ -0,0 +1,46 @@ +#include +#include + +static_assert(REX_PLATFORM_WIN32, "This file is Windows-only"); + +#include "platform_win.h" + +namespace rex::platform { + +DynamicLibrary::~DynamicLibrary() { + Close(); +} + +DynamicLibrary::DynamicLibrary(DynamicLibrary&& other) noexcept : handle_(other.handle_) { + other.handle_ = nullptr; +} + +DynamicLibrary& DynamicLibrary::operator=(DynamicLibrary&& other) noexcept { + if (this != &other) { + Close(); + handle_ = other.handle_; + other.handle_ = nullptr; + } + return *this; +} + +bool DynamicLibrary::Load(const std::filesystem::path& path) { + Close(); + handle_ = static_cast(LoadLibraryW(path.c_str())); + return handle_ != nullptr; +} + +void DynamicLibrary::Close() { + if (handle_) { + FreeLibrary(static_cast(handle_)); + handle_ = nullptr; + } +} + +void* DynamicLibrary::GetRawSymbol(const char* name) const { + if (!handle_) + return nullptr; + return reinterpret_cast(GetProcAddress(static_cast(handle_), name)); +} + +} // namespace rex::platform diff --git a/src/core/exception_handler.cpp b/src/core/exception_handler.cpp new file mode 100644 index 0000000..368daa9 --- /dev/null +++ b/src/core/exception_handler.cpp @@ -0,0 +1,89 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +namespace rex::arch { + +// Based on VIXL Instruction::IsLoad and IsStore. +// https://github.com/Linaro/vixl/blob/d48909dd0ac62197edb75d26ed50927e4384a199/src/aarch64/instructions-aarch64.cc#L484 +// +// Copyright 2015, VIXL authors +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of ARM Limited nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +bool IsArm64LoadPrefetchStore(uint32_t instruction, bool& is_store_out) { + if ((instruction & kArm64LoadLiteralFMask) == kArm64LoadLiteralFixed) { + return true; + } + if ((instruction & kArm64LoadStoreAnyFMask) != kArm64LoadStoreAnyFixed) { + return false; + } + if ((instruction & kArm64LoadStorePairAnyFMask) == kArm64LoadStorePairAnyFixed) { + is_store_out = !(instruction & kArm64LoadStorePairLoadBit); + return true; + } + switch (Arm64LoadStoreOp(instruction & kArm64LoadStoreMask)) { + case Arm64LoadStoreOp::kLDRB_w: + case Arm64LoadStoreOp::kLDRH_w: + case Arm64LoadStoreOp::kLDR_w: + case Arm64LoadStoreOp::kLDR_x: + case Arm64LoadStoreOp::kLDRSB_x: + case Arm64LoadStoreOp::kLDRSH_x: + case Arm64LoadStoreOp::kLDRSW_x: + case Arm64LoadStoreOp::kLDRSB_w: + case Arm64LoadStoreOp::kLDRSH_w: + case Arm64LoadStoreOp::kLDR_b: + case Arm64LoadStoreOp::kLDR_h: + case Arm64LoadStoreOp::kLDR_s: + case Arm64LoadStoreOp::kLDR_d: + case Arm64LoadStoreOp::kLDR_q: + case Arm64LoadStoreOp::kPRFM: + is_store_out = false; + return true; + case Arm64LoadStoreOp::kSTRB_w: + case Arm64LoadStoreOp::kSTRH_w: + case Arm64LoadStoreOp::kSTR_w: + case Arm64LoadStoreOp::kSTR_x: + case Arm64LoadStoreOp::kSTR_b: + case Arm64LoadStoreOp::kSTR_h: + case Arm64LoadStoreOp::kSTR_s: + case Arm64LoadStoreOp::kSTR_d: + case Arm64LoadStoreOp::kSTR_q: + is_store_out = true; + return true; + default: + return false; + } +} + +} // namespace rex::arch diff --git a/src/core/exception_handler_posix.cpp b/src/core/exception_handler_posix.cpp new file mode 100644 index 0000000..8aced51 --- /dev/null +++ b/src/core/exception_handler_posix.cpp @@ -0,0 +1,271 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#if REX_PLATFORM_LINUX || REX_PLATFORM_MAC + +#include + +#include +#include + +#include +#include +#include +#include + +#include + +namespace rex::arch { + +bool signal_handlers_installed_ = false; +struct sigaction original_sigill_handler_; +struct sigaction original_sigsegv_handler_; + +// This can be as large as needed, but isn't often needed. +// As we will be sometimes firing many exceptions we want to avoid having to +// scan the table too much or invoke many custom handlers. +constexpr size_t kMaxHandlerCount = 8; + +// All custom handlers, left-aligned and null terminated. +// Executed in order. +std::pair handlers_[kMaxHandlerCount]; + +static void ExceptionHandlerCallback(int signal_number, siginfo_t* signal_info, + void* signal_context) { + mcontext_t& mcontext = reinterpret_cast(signal_context)->uc_mcontext; + + HostThreadContext thread_context; + +#if REX_ARCH_AMD64 + thread_context.rip = uint64_t(mcontext.gregs[REG_RIP]); + thread_context.eflags = uint32_t(mcontext.gregs[REG_EFL]); + // The REG_ order may be different than the register indices in the + // instruction encoding. + thread_context.rax = uint64_t(mcontext.gregs[REG_RAX]); + thread_context.rcx = uint64_t(mcontext.gregs[REG_RCX]); + thread_context.rdx = uint64_t(mcontext.gregs[REG_RDX]); + thread_context.rbx = uint64_t(mcontext.gregs[REG_RBX]); + thread_context.rsp = uint64_t(mcontext.gregs[REG_RSP]); + thread_context.rbp = uint64_t(mcontext.gregs[REG_RBP]); + thread_context.rsi = uint64_t(mcontext.gregs[REG_RSI]); + thread_context.rdi = uint64_t(mcontext.gregs[REG_RDI]); + thread_context.r8 = uint64_t(mcontext.gregs[REG_R8]); + thread_context.r9 = uint64_t(mcontext.gregs[REG_R9]); + thread_context.r10 = uint64_t(mcontext.gregs[REG_R10]); + thread_context.r11 = uint64_t(mcontext.gregs[REG_R11]); + thread_context.r12 = uint64_t(mcontext.gregs[REG_R12]); + thread_context.r13 = uint64_t(mcontext.gregs[REG_R13]); + thread_context.r14 = uint64_t(mcontext.gregs[REG_R14]); + thread_context.r15 = uint64_t(mcontext.gregs[REG_R15]); + std::memcpy(thread_context.xmm_registers, mcontext.fpregs->_xmm, + sizeof(thread_context.xmm_registers)); +#elif REX_ARCH_ARM64 + std::memcpy(thread_context.x, mcontext.regs, sizeof(thread_context.x)); + thread_context.sp = mcontext.sp; + thread_context.pc = mcontext.pc; + thread_context.pstate = mcontext.pstate; + struct fpsimd_context* mcontext_fpsimd = nullptr; + struct esr_context* mcontext_esr = nullptr; + for (struct _aarch64_ctx* mcontext_extension = + reinterpret_cast(mcontext.__reserved); + mcontext_extension->magic; + mcontext_extension = reinterpret_cast( + reinterpret_cast(mcontext_extension) + mcontext_extension->size)) { + switch (mcontext_extension->magic) { + case FPSIMD_MAGIC: + mcontext_fpsimd = reinterpret_cast(mcontext_extension); + break; + case ESR_MAGIC: + mcontext_esr = reinterpret_cast(mcontext_extension); + break; + default: + break; + } + } + assert_not_null(mcontext_fpsimd); + if (mcontext_fpsimd) { + thread_context.fpsr = mcontext_fpsimd->fpsr; + thread_context.fpcr = mcontext_fpsimd->fpcr; + std::memcpy(thread_context.v, mcontext_fpsimd->vregs, sizeof(thread_context.v)); + } +#endif // REX_ARCH + + Exception ex; + switch (signal_number) { + case SIGILL: + ex.InitializeIllegalInstruction(&thread_context); + break; + case SIGSEGV: { + Exception::AccessViolationOperation access_violation_operation; +#if REX_ARCH_AMD64 + // x86_pf_error_code::X86_PF_WRITE + constexpr uint64_t kX86PageFaultErrorCodeWrite = UINT64_C(1) << 1; + access_violation_operation = (uint64_t(mcontext.gregs[REG_ERR]) & kX86PageFaultErrorCodeWrite) + ? Exception::AccessViolationOperation::kWrite + : Exception::AccessViolationOperation::kRead; +#elif REX_ARCH_ARM64 + // For a Data Abort (EC - ESR_EL1 bits 31:26 - 0b100100 from a lower + // Exception Level, 0b100101 without a change in the Exception Level), + // bit 6 is 0 for reading from a memory location, 1 for writing to a + // memory location. + if (mcontext_esr && ((mcontext_esr->esr >> 26) & 0b111110) == 0b100100) { + access_violation_operation = (mcontext_esr->esr & (UINT64_C(1) << 6)) + ? Exception::AccessViolationOperation::kWrite + : Exception::AccessViolationOperation::kRead; + } else { + // Determine the memory access direction based on which instruction has + // requested it. + // esr_context may be unavailable on certain hosts (for instance, on + // Android, it was added only in NDK r16 - which is the first NDK + // version to support the Android API level 27, while NDK r15 doesn't + // have esr_context in its API 26 sigcontext.h). + // On AArch64 (unlike on AArch32), the program counter is the address of + // the currently executing instruction. + bool instruction_is_store; + if (IsArm64LoadPrefetchStore(*reinterpret_cast(mcontext.pc), + instruction_is_store)) { + access_violation_operation = instruction_is_store + ? Exception::AccessViolationOperation::kWrite + : Exception::AccessViolationOperation::kRead; + } else { + assert_always( + "No ESR in the exception thread context, or it's not a Data " + "Abort, and the faulting instruction is not a known load, " + "prefetch or store instruction"); + access_violation_operation = Exception::AccessViolationOperation::kUnknown; + } + } +#else + access_violation_operation = Exception::AccessViolationOperation::kUnknown; +#endif // REX_ARCH + ex.InitializeAccessViolation(&thread_context, + reinterpret_cast(signal_info->si_addr), + access_violation_operation); + } break; + default: + assert_unhandled_case(signal_number); + } + + for (size_t i = 0; i < rex::countof(handlers_) && handlers_[i].first; ++i) { + if (handlers_[i].first(&ex, handlers_[i].second)) { + // Exception handled. +#if REX_ARCH_AMD64 + mcontext.gregs[REG_RIP] = greg_t(thread_context.rip); + mcontext.gregs[REG_EFL] = greg_t(thread_context.eflags); + uint32_t modified_register_index; + // The order must match the order in X64Register. + static const size_t kIntRegisterMap[] = { + REG_RAX, REG_RCX, REG_RDX, REG_RBX, REG_RSP, REG_RBP, REG_RSI, REG_RDI, + REG_R8, REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15, + }; + uint16_t modified_int_registers_remaining = ex.modified_int_registers(); + while (rex::bit_scan_forward(modified_int_registers_remaining, &modified_register_index)) { + modified_int_registers_remaining &= ~(UINT16_C(1) << modified_register_index); + mcontext.gregs[kIntRegisterMap[modified_register_index]] = + thread_context.int_registers[modified_register_index]; + } + uint16_t modified_xmm_registers_remaining = ex.modified_xmm_registers(); + while (rex::bit_scan_forward(modified_xmm_registers_remaining, &modified_register_index)) { + modified_xmm_registers_remaining &= ~(UINT16_C(1) << modified_register_index); + std::memcpy(&mcontext.fpregs->_xmm[modified_register_index], + &thread_context.xmm_registers[modified_register_index], sizeof(vec128_t)); + } +#elif REX_ARCH_ARM64 + uint32_t modified_register_index; + uint32_t modified_x_registers_remaining = ex.modified_x_registers(); + while (rex::bit_scan_forward(modified_x_registers_remaining, &modified_register_index)) { + modified_x_registers_remaining &= ~(UINT32_C(1) << modified_register_index); + mcontext.regs[modified_register_index] = thread_context.x[modified_register_index]; + } + mcontext.sp = thread_context.sp; + mcontext.pc = thread_context.pc; + mcontext.pstate = thread_context.pstate; + if (mcontext_fpsimd) { + mcontext_fpsimd->fpsr = thread_context.fpsr; + mcontext_fpsimd->fpcr = thread_context.fpcr; + uint32_t modified_v_registers_remaining = ex.modified_v_registers(); + while (rex::bit_scan_forward(modified_v_registers_remaining, &modified_register_index)) { + modified_v_registers_remaining &= ~(UINT32_C(1) << modified_register_index); + std::memcpy(&mcontext_fpsimd->vregs[modified_register_index], + &thread_context.v[modified_register_index], sizeof(vec128_t)); + mcontext.regs[modified_register_index] = thread_context.x[modified_register_index]; + } + } +#endif // REX_ARCH + return; + } + } +} + +void ExceptionHandler::Install(Handler fn, void* data) { + if (!signal_handlers_installed_) { + struct sigaction signal_handler; + + std::memset(&signal_handler, 0, sizeof(signal_handler)); + signal_handler.sa_sigaction = ExceptionHandlerCallback; + signal_handler.sa_flags = SA_SIGINFO; + + if (sigaction(SIGILL, &signal_handler, &original_sigill_handler_) != 0) { + assert_always("Failed to install new SIGILL handler"); + } + if (sigaction(SIGSEGV, &signal_handler, &original_sigsegv_handler_) != 0) { + assert_always("Failed to install new SIGSEGV handler"); + } + signal_handlers_installed_ = true; + } + + for (size_t i = 0; i < rex::countof(handlers_); ++i) { + if (!handlers_[i].first) { + handlers_[i].first = fn; + handlers_[i].second = data; + return; + } + } + assert_always("Too many exception handlers installed"); +} + +void ExceptionHandler::Uninstall(Handler fn, void* data) { + for (size_t i = 0; i < rex::countof(handlers_); ++i) { + if (handlers_[i].first == fn && handlers_[i].second == data) { + for (; i < rex::countof(handlers_) - 1; ++i) { + handlers_[i] = handlers_[i + 1]; + } + handlers_[i].first = nullptr; + handlers_[i].second = nullptr; + break; + } + } + + bool has_any = false; + for (size_t i = 0; i < rex::countof(handlers_); ++i) { + if (handlers_[i].first) { + has_any = true; + break; + } + } + if (!has_any) { + if (signal_handlers_installed_) { + if (sigaction(SIGILL, &original_sigill_handler_, NULL) != 0) { + assert_always("Failed to restore original SIGILL handler"); + } + if (sigaction(SIGSEGV, &original_sigsegv_handler_, NULL) != 0) { + assert_always("Failed to restore original SIGSEGV handler"); + } + signal_handlers_installed_ = false; + } + } +} + +} // namespace rex::arch + +#endif // REX_PLATFORM_LINUX || REX_PLATFORM_MAC diff --git a/src/core/exception_handler_win.cpp b/src/core/exception_handler_win.cpp new file mode 100644 index 0000000..4a9b1ee --- /dev/null +++ b/src/core/exception_handler_win.cpp @@ -0,0 +1,158 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#if REX_PLATFORM_WIN32 + +#include "platform_win.h" + +#include +#include + +namespace rex::arch { + +// Handle of the added VectoredExceptionHandler. +void* veh_handle_ = nullptr; +// Handle of the added VectoredContinueHandler. +void* vch_handle_ = nullptr; + +// This can be as large as needed, but isn't often needed. +// As we will be sometimes firing many exceptions we want to avoid having to +// scan the table too much or invoke many custom handlers. +constexpr size_t kMaxHandlerCount = 8; + +// All custom handlers, left-aligned and null terminated. +// Executed in order. +std::pair handlers_[kMaxHandlerCount]; + +LONG CALLBACK ExceptionHandlerCallback(PEXCEPTION_POINTERS ex_info) { + // Visual Studio SetThreadName. + if (ex_info->ExceptionRecord->ExceptionCode == 0x406D1388) { + return EXCEPTION_CONTINUE_SEARCH; + } + + HostThreadContext thread_context; + thread_context.rip = ex_info->ContextRecord->Rip; + thread_context.eflags = ex_info->ContextRecord->EFlags; + std::memcpy(thread_context.int_registers, &ex_info->ContextRecord->Rax, + sizeof(thread_context.int_registers)); + std::memcpy(thread_context.xmm_registers, &ex_info->ContextRecord->Xmm0, + sizeof(thread_context.xmm_registers)); + + // https://msdn.microsoft.com/en-us/library/ms679331(v=vs.85).aspx + // https://msdn.microsoft.com/en-us/library/aa363082(v=vs.85).aspx + Exception ex; + switch (ex_info->ExceptionRecord->ExceptionCode) { + case STATUS_ILLEGAL_INSTRUCTION: + ex.InitializeIllegalInstruction(&thread_context); + break; + case STATUS_ACCESS_VIOLATION: { + Exception::AccessViolationOperation access_violation_operation; + switch (ex_info->ExceptionRecord->ExceptionInformation[0]) { + case 0: + access_violation_operation = Exception::AccessViolationOperation::kRead; + break; + case 1: + access_violation_operation = Exception::AccessViolationOperation::kWrite; + break; + default: + access_violation_operation = Exception::AccessViolationOperation::kUnknown; + break; + } + ex.InitializeAccessViolation(&thread_context, + ex_info->ExceptionRecord->ExceptionInformation[1], + access_violation_operation); + } break; + default: + // Unknown/unhandled type. + return EXCEPTION_CONTINUE_SEARCH; + } + + for (size_t i = 0; i < rex::countof(handlers_) && handlers_[i].first; ++i) { + if (handlers_[i].first(&ex, handlers_[i].second)) { + // Exception handled. + ex_info->ContextRecord->Rip = thread_context.rip; + ex_info->ContextRecord->EFlags = thread_context.eflags; + uint32_t modified_register_index; + uint16_t modified_int_registers_remaining = ex.modified_int_registers(); + while (rex::bit_scan_forward(modified_int_registers_remaining, &modified_register_index)) { + modified_int_registers_remaining &= ~(UINT16_C(1) << modified_register_index); + (&ex_info->ContextRecord->Rax)[modified_register_index] = + thread_context.int_registers[modified_register_index]; + } + uint16_t modified_xmm_registers_remaining = ex.modified_xmm_registers(); + while (rex::bit_scan_forward(modified_xmm_registers_remaining, &modified_register_index)) { + modified_xmm_registers_remaining &= ~(UINT16_C(1) << modified_register_index); + std::memcpy(&ex_info->ContextRecord->Xmm0 + modified_register_index, + &thread_context.xmm_registers[modified_register_index], sizeof(vec128_t)); + } + return EXCEPTION_CONTINUE_EXECUTION; + } + } + return EXCEPTION_CONTINUE_SEARCH; +} + +void ExceptionHandler::Install(Handler fn, void* data) { + if (!veh_handle_) { + veh_handle_ = AddVectoredExceptionHandler(1, ExceptionHandlerCallback); + + if (IsDebuggerPresent()) { + // TODO(benvanik): do we need a continue handler if a debugger is + // attached? + // vch_handle_ = AddVectoredContinueHandler(1, ExceptionHandlerCallback); + } + } + + for (size_t i = 0; i < rex::countof(handlers_); ++i) { + if (!handlers_[i].first) { + handlers_[i].first = fn; + handlers_[i].second = data; + return; + } + } + assert_always("Too many exception handlers installed"); +} + +void ExceptionHandler::Uninstall(Handler fn, void* data) { + for (size_t i = 0; i < rex::countof(handlers_); ++i) { + if (handlers_[i].first == fn && handlers_[i].second == data) { + for (; i < rex::countof(handlers_) - 1; ++i) { + handlers_[i] = handlers_[i + 1]; + } + handlers_[i].first = nullptr; + handlers_[i].second = nullptr; + break; + } + } + + bool has_any = false; + for (size_t i = 0; i < rex::countof(handlers_); ++i) { + if (handlers_[i].first) { + has_any = true; + break; + } + } + if (!has_any) { + if (veh_handle_) { + RemoveVectoredExceptionHandler(veh_handle_); + veh_handle_ = nullptr; + } + if (vch_handle_) { + RemoveVectoredContinueHandler(vch_handle_); + vch_handle_ = nullptr; + } + } +} + +} // namespace rex::arch + +#endif // REX_PLATFORM_WIN32 diff --git a/src/core/fiber_posix.cpp b/src/core/fiber_posix.cpp new file mode 100644 index 0000000..e7c53fd --- /dev/null +++ b/src/core/fiber_posix.cpp @@ -0,0 +1,78 @@ +/** + * @file rex/core/fiber_posix.cpp + * @brief POSIX backend for rex::thread::Fiber (makecontext/swapcontext) + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include +#if REX_PLATFORM_LINUX || REX_PLATFORM_MAC + +#include + +#include +#include + +namespace rex::thread { + +thread_local Fiber* Fiber::tls_current_ = nullptr; + +Fiber* Fiber::ConvertCurrentThread() { + auto* f = new Fiber(); + if (getcontext(&f->context_) == -1) { + delete f; + return nullptr; + } + f->is_thread_fiber_ = true; + tls_current_ = f; + return f; +} + +Fiber* Fiber::Create(size_t stack_size, void (*entry)(void*), void* arg) { + auto* f = new Fiber(); + f->entry_ = entry; + f->arg_ = arg; + f->stack_.resize(stack_size); + + if (getcontext(&f->context_) == -1) { + delete f; + return nullptr; + } + f->context_.uc_stack.ss_sp = f->stack_.data(); + f->context_.uc_stack.ss_size = f->stack_.size(); + f->context_.uc_link = nullptr; + // Trampoline reads entry_/arg_ from tls_current_ — no pointer splitting needed. + makecontext(&f->context_, &Fiber::Trampoline, 0); + return f; +} + +/*static*/ void Fiber::Trampoline() { + // tls_current_ was updated by SwitchTo before swapcontext returned here. + Fiber* f = tls_current_; + f->entry_(f->arg_); +} + +void Fiber::SwitchTo(Fiber* target) { + Fiber* from = tls_current_; + tls_current_ = target; + swapcontext(&from->context_, &target->context_); +} + +void Fiber::Destroy() { + // Thread fibers are destroyed from the owning thread itself. + if (is_thread_fiber_) { + tls_current_ = nullptr; + } else { + assert(this != tls_current_ && "Destroy called on the currently running fiber"); + } + // No POSIX equivalent of ConvertFiberToThread; stack_ is freed by the vector destructor. + delete this; +} + +} // namespace rex::thread + +#endif // REX_PLATFORM_LINUX || REX_PLATFORM_MAC diff --git a/src/core/fiber_win32.cpp b/src/core/fiber_win32.cpp new file mode 100644 index 0000000..5744a90 --- /dev/null +++ b/src/core/fiber_win32.cpp @@ -0,0 +1,64 @@ +/** + * @file rex/core/fiber_win32.cpp + * @brief Win32 backend for rex::thread::Fiber + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include +#if REX_PLATFORM_WIN32 +#include +#include + +#include + +namespace rex::thread { + +thread_local Fiber* Fiber::tls_current_ = nullptr; + +Fiber* Fiber::ConvertCurrentThread() { + auto* f = new Fiber(); + f->handle_ = ::ConvertThreadToFiber(nullptr); + if (!f->handle_) { + delete f; + return nullptr; + } + f->is_thread_fiber_ = true; + tls_current_ = f; + return f; +} + +Fiber* Fiber::Create(size_t stack_size, void (*entry)(void*), void* arg) { + auto* f = new Fiber(); + f->handle_ = ::CreateFiber(stack_size, reinterpret_cast(entry), arg); + if (!f->handle_) { + delete f; + return nullptr; + } + return f; +} + +void Fiber::SwitchTo(Fiber* target) { + tls_current_ = target; + ::SwitchToFiber(target->handle_); +} + +void Fiber::Destroy() { + // Thread fibers are destroyed from the owning thread itself. + if (is_thread_fiber_) { + ::ConvertFiberToThread(); + tls_current_ = nullptr; + } else { + assert(this != tls_current_ && "Destroy called on the currently running fiber"); + ::DeleteFiber(handle_); + } + delete this; +} + +} // namespace rex::thread + +#endif // REX_PLATFORM_WIN32 diff --git a/src/core/filesystem.cpp b/src/core/filesystem.cpp new file mode 100644 index 0000000..42b0468 --- /dev/null +++ b/src/core/filesystem.cpp @@ -0,0 +1,30 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include + +namespace rex { +namespace filesystem { + +bool CreateParentFolder(const std::filesystem::path& path) { + if (path.has_parent_path()) { + auto parent_path = path.parent_path(); + if (!std::filesystem::exists(parent_path)) { + return std::filesystem::create_directories(parent_path); + } + } + return true; +} + +} // namespace filesystem +} // namespace rex diff --git a/src/core/filesystem_posix.cpp b/src/core/filesystem_posix.cpp new file mode 100644 index 0000000..00648e4 --- /dev/null +++ b/src/core/filesystem_posix.cpp @@ -0,0 +1,258 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace rex { + +std::string path_to_utf8(const std::filesystem::path& path) { + return path.string(); +} + +std::u16string path_to_utf16(const std::filesystem::path& path) { + return rex::string::to_utf16(path.string()); +} + +std::filesystem::path to_path(const std::string_view source) { + return source; +} + +std::filesystem::path to_path(const std::u16string_view source) { + return rex::string::to_utf8(source); +} + +namespace filesystem { + +std::filesystem::path GetExecutablePath() { + char buff[FILENAME_MAX] = ""; + readlink("/proc/self/exe", buff, FILENAME_MAX); + std::string s(buff); + return s; +} + +std::filesystem::path GetExecutableFolder() { + return GetExecutablePath().parent_path(); +} + +std::filesystem::path GetUserFolder() { + // get preferred data home + char* home = std::getenv("XDG_DATA_HOME"); + if (home) { + return std::string(home); + } + + // if XDG_DATA_HOME not set, fallback to HOME directory + home = std::getenv("HOME"); + + // if HOME not set, fall back to this + if (home == NULL) { + struct passwd pw1; + struct passwd* pw; + char buf[4096]; // could potentionally lower this + getpwuid_r(getuid(), &pw1, buf, sizeof(buf), &pw); + assert(&pw1 == pw); // sanity check + home = pw->pw_dir; + } + + return std::filesystem::path(home) / ".local" / "share"; +} + +FILE* OpenFile(const std::filesystem::path& path, const std::string_view mode) { + return fopen(path.c_str(), std::string(mode).c_str()); +} + +bool Seek(FILE* file, int64_t offset, int origin) { + return fseeko64(file, off64_t(offset), origin) == 0; +} + +int64_t Tell(FILE* file) { + return int64_t(ftello64(file)); +} + +bool TruncateStdioFile(FILE* file, uint64_t length) { + if (fflush(file)) { + return false; + } + int64_t position = Tell(file); + if (position < 0) { + return false; + } + if (ftruncate64(fileno(file), off64_t(length))) { + return false; + } + if (uint64_t(position) > length) { + if (!Seek(file, 0, SEEK_END)) { + return false; + } + } + return true; +} + +static int removeCallback(const char* fpath, const struct stat* sb, int typeflag, + struct FTW* ftwbuf) { + int rv = remove(fpath); + return rv; +} + +static uint64_t convertUnixtimeToWinFiletime(time_t unixtime) { + // Linux uses number of seconds since 1/1/1970, and Windows uses + // number of nanoseconds since 1/1/1601 + // so we convert linux time to nanoseconds and then add the number of + // nanoseconds from 1601 to 1970 + // see https://msdn.microsoft.com/en-us/library/ms724228 + uint64_t filetime = filetime = (unixtime * 10000000) + 116444736000000000; + return filetime; +} + +bool CreateEmptyFile(const std::filesystem::path& path) { + int file = creat(path.c_str(), 0774); + if (file >= 0) { + close(file); + return true; + } + return false; +} + +class PosixFileHandle : public FileHandle { + public: + PosixFileHandle(std::filesystem::path path, int handle) + : FileHandle(std::move(path)), handle_(handle) {} + ~PosixFileHandle() override { + close(handle_); + handle_ = -1; + } + bool Read(size_t file_offset, void* buffer, size_t buffer_length, + size_t* out_bytes_read) override { + ssize_t out = pread(handle_, buffer, buffer_length, file_offset); + *out_bytes_read = out; + return out >= 0 ? true : false; + } + bool Write(size_t file_offset, const void* buffer, size_t buffer_length, + size_t* out_bytes_written) override { + ssize_t out = pwrite(handle_, buffer, buffer_length, file_offset); + *out_bytes_written = out; + return out >= 0 ? true : false; + } + bool SetLength(size_t length) override { return ftruncate(handle_, length) >= 0 ? true : false; } + void Flush() override { fsync(handle_); } + + private: + int handle_ = -1; +}; + +std::unique_ptr FileHandle::OpenExisting(const std::filesystem::path& path, + uint32_t desired_access) { + int open_access = 0; + if (desired_access & FileAccess::kGenericRead) { + open_access |= O_RDONLY; + } + if (desired_access & FileAccess::kGenericWrite) { + open_access |= O_WRONLY; + } + if (desired_access & FileAccess::kGenericExecute) { + open_access |= O_RDONLY; + } + if (desired_access & FileAccess::kGenericAll) { + open_access |= O_RDWR; + } + if (desired_access & FileAccess::kFileReadData) { + open_access |= O_RDONLY; + } + if (desired_access & FileAccess::kFileWriteData) { + open_access |= O_WRONLY; + } + if (desired_access & FileAccess::kFileAppendData) { + open_access |= O_APPEND; + } + int handle = open(path.c_str(), open_access); + if (handle == -1) { + // TODO(benvanik): pick correct response. + return nullptr; + } + return std::make_unique(path, handle); +} + +bool GetInfo(const std::filesystem::path& path, FileInfo* out_info) { + struct stat st; + if (stat(path.c_str(), &st) == 0) { + if (S_ISDIR(st.st_mode)) { + out_info->type = FileInfo::Type::kDirectory; + out_info->total_size = 0; + } else { + out_info->type = FileInfo::Type::kFile; + out_info->total_size = st.st_size; + } + out_info->path = path.parent_path(); + out_info->name = path.filename(); + out_info->create_timestamp = convertUnixtimeToWinFiletime(st.st_ctime); + out_info->access_timestamp = convertUnixtimeToWinFiletime(st.st_atime); + out_info->write_timestamp = convertUnixtimeToWinFiletime(st.st_mtime); + return true; + } + return false; +} + +std::vector ListFiles(const std::filesystem::path& path) { + std::vector result; + + DIR* dir = opendir(path.c_str()); + if (!dir) { + return result; + } + + while (auto ent = readdir(dir)) { + if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) { + continue; + } + + FileInfo info; + + info.name = ent->d_name; + struct stat st; + stat((path / info.name).c_str(), &st); + info.create_timestamp = convertUnixtimeToWinFiletime(st.st_ctime); + info.access_timestamp = convertUnixtimeToWinFiletime(st.st_atime); + info.write_timestamp = convertUnixtimeToWinFiletime(st.st_mtime); + info.path = path; + if (ent->d_type == DT_DIR) { + info.type = FileInfo::Type::kDirectory; + info.total_size = 0; + } else { + info.type = FileInfo::Type::kFile; + info.total_size = st.st_size; + } + result.push_back(info); + } + closedir(dir); + return result; +} + +} // namespace filesystem +} // namespace rex diff --git a/src/core/filesystem_wildcard.cpp b/src/core/filesystem_wildcard.cpp new file mode 100644 index 0000000..7f70b23 --- /dev/null +++ b/src/core/filesystem_wildcard.cpp @@ -0,0 +1,111 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include + +namespace rex::filesystem { + +WildcardFlags WildcardFlags::FIRST(true, false, false); +WildcardFlags WildcardFlags::LAST(false, true, false); +WildcardFlags WildcardFlags::ANY(false, false, true); +WildcardFlags WildcardFlags::FIRST_AND_LAST(true, true, false); + +WildcardFlags::WildcardFlags() : FromStart(false), ToEnd(false), ExactLength(false) {} + +WildcardFlags::WildcardFlags(bool start, bool end, bool exact_length) + : FromStart(start), ToEnd(end), ExactLength(exact_length) {} + +WildcardRule::WildcardRule(const std::string_view match, const WildcardFlags& flags) + : match_(rex::string::utf8_lower_ascii(match)), rules_(flags) {} + +bool WildcardRule::Check(const std::string_view lower, std::string::size_type* offset) const { + if (match_.empty()) { + return true; + } + + if ((lower.size() - *offset) < match_.size()) { + return false; + } + + if (rules_.ExactLength) { + *offset += match_.size(); + return true; + } + + std::string_view::size_type result(lower.find(match_, *offset)); + + if (result != std::string_view::npos) { + if (rules_.FromStart && result != *offset) { + return false; + } + + if (rules_.ToEnd && result != (lower.size() - match_.size())) { + return false; + } + + *offset = (result + match_.size()); + return true; + } + + return false; +} + +void WildcardEngine::PreparePattern(const std::string_view pattern) { + rules_.clear(); + + WildcardFlags flags(WildcardFlags::FIRST); + size_t n = 0; + size_t last = 0; + while ((n = pattern.find_first_of("*?", last)) != pattern.npos) { + if (last != n) { + std::string str_str(pattern.substr(last, n - last)); + rules_.push_back(WildcardRule(str_str, flags)); + } + if (pattern[n] == '?') { + auto end = pattern.find_first_not_of('?', n + 1); + auto count = end == pattern.npos ? (pattern.size() - n) : (end - n); + rules_.push_back(WildcardRule(pattern.substr(n, count), WildcardFlags::ANY)); + last = n + count; + } else if (pattern[n] == '*') { + last = n + 1; + } else { + assert_always(); + } + flags = WildcardFlags(); + } + if (last != pattern.size()) { + std::string str_str(pattern.substr(last)); + rules_.push_back( + WildcardRule(str_str, last ? WildcardFlags::LAST : WildcardFlags::FIRST_AND_LAST)); + } +} + +void WildcardEngine::SetRule(const std::string_view pattern) { + PreparePattern(pattern); +} + +bool WildcardEngine::Match(const std::string_view str) const { + std::string str_lc = rex::string::utf8_lower_ascii(str); + std::string::size_type offset(0); + for (const auto& rule : rules_) { + if (!(rule.Check(str_lc, &offset))) { + return false; + } + } + + return true; +} + +} // namespace rex::filesystem diff --git a/src/core/filesystem_win.cpp b/src/core/filesystem_win.cpp new file mode 100644 index 0000000..8cc3036 --- /dev/null +++ b/src/core/filesystem_win.cpp @@ -0,0 +1,263 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include + +#undef CreateFile + +#include "platform_win.h" + +#include +#include +#include + +namespace rex { + +std::string path_to_utf8(const std::filesystem::path& path) { + return rex::string::to_utf8(path.u16string()); +} + +std::u16string path_to_utf16(const std::filesystem::path& path) { + return path.u16string(); +} + +std::filesystem::path to_path(const std::string_view source) { + return rex::string::to_utf16(source); +} + +std::filesystem::path to_path(const std::u16string_view source) { + return source; +} + +namespace filesystem { + +std::filesystem::path GetExecutablePath() { + wchar_t* path; + auto error = _get_wpgmptr(&path); + return !error ? std::filesystem::path(path) : std::filesystem::path(); +} + +std::filesystem::path GetExecutableFolder() { + return GetExecutablePath().parent_path(); +} + +std::filesystem::path GetUserFolder() { + std::filesystem::path result; + PWSTR path; + if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Documents, KF_FLAG_DEFAULT, nullptr, &path))) { + result.assign(path); + CoTaskMemFree(path); + } + return result; +} + +bool CreateEmptyFile(const std::filesystem::path& path) { + auto handle = + CreateFileW(path.c_str(), 0, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + if (handle == INVALID_HANDLE_VALUE) { + return false; + } + + CloseHandle(handle); + return true; +} + +FILE* OpenFile(const std::filesystem::path& path, const std::string_view mode) { + // Dumb, but OK. + const auto wmode = rex::string::to_utf16(mode); + return _wfopen(path.c_str(), reinterpret_cast(wmode.c_str())); +} + +bool Seek(FILE* file, int64_t offset, int origin) { + return _fseeki64(file, offset, origin) == 0; +} + +int64_t Tell(FILE* file) { + return _ftelli64(file); +} + +bool TruncateStdioFile(FILE* file, uint64_t length) { + // Flush is necessary - if not flushing, stream position may be out of sync. + if (fflush(file)) { + return false; + } + int64_t position = Tell(file); + if (position < 0) { + return false; + } + if (_chsize_s(_fileno(file), int64_t(length))) { + return false; + } + if (uint64_t(position) > length) { + if (!Seek(file, 0, SEEK_END)) { + return false; + } + } + return true; +} + +class Win32FileHandle : public FileHandle { + public: + Win32FileHandle(const std::filesystem::path& path, HANDLE handle) + : FileHandle(path), handle_(handle) {} + ~Win32FileHandle() override { + CloseHandle(handle_); + handle_ = nullptr; + } + bool Read(size_t file_offset, void* buffer, size_t buffer_length, + size_t* out_bytes_read) override { + *out_bytes_read = 0; + OVERLAPPED overlapped; + overlapped.Pointer = (PVOID)file_offset; + overlapped.hEvent = NULL; + DWORD bytes_read = 0; + BOOL read = ReadFile(handle_, buffer, (DWORD)buffer_length, &bytes_read, &overlapped); + if (read) { + *out_bytes_read = bytes_read; + return true; + } else { + if (GetLastError() == ERROR_NOACCESS) { + REXLOG_WARN( + "Win32FileHandle::Read(..., {}, 0x{:X}, ...) returned " + "ERROR_NOACCESS. Read-only memory?", + buffer, buffer_length); + } + return false; + } + } + bool Write(size_t file_offset, const void* buffer, size_t buffer_length, + size_t* out_bytes_written) override { + *out_bytes_written = 0; + OVERLAPPED overlapped; + overlapped.Pointer = (PVOID)file_offset; + overlapped.hEvent = NULL; + DWORD bytes_written = 0; + BOOL wrote = WriteFile(handle_, buffer, (DWORD)buffer_length, &bytes_written, &overlapped); + if (wrote) { + *out_bytes_written = bytes_written; + return true; + } else { + return false; + } + } + bool SetLength(size_t length) override { + LARGE_INTEGER position; + position.QuadPart = length; + if (!SetFilePointerEx(handle_, position, nullptr, SEEK_SET)) { + return false; + } + if (!SetEndOfFile(handle_)) { + return false; + } + return true; + } + void Flush() override { FlushFileBuffers(handle_); } + + private: + HANDLE handle_ = nullptr; +}; + +std::unique_ptr FileHandle::OpenExisting(const std::filesystem::path& path, + uint32_t desired_access) { + DWORD open_access = 0; + if (desired_access & FileAccess::kGenericRead) { + open_access |= GENERIC_READ; + } + if (desired_access & FileAccess::kGenericWrite) { + open_access |= GENERIC_WRITE; + } + if (desired_access & FileAccess::kGenericExecute) { + open_access |= GENERIC_EXECUTE; + } + if (desired_access & FileAccess::kGenericAll) { + open_access |= GENERIC_READ | GENERIC_WRITE; + } + if (desired_access & FileAccess::kFileReadData) { + open_access |= FILE_READ_DATA; + } + if (desired_access & FileAccess::kFileWriteData) { + open_access |= FILE_WRITE_DATA; + } + if (desired_access & FileAccess::kFileAppendData) { + open_access |= FILE_APPEND_DATA; + } + DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE; + // We assume we've already created the file in the caller. + DWORD creation_disposition = OPEN_EXISTING; + HANDLE handle = CreateFileW(path.c_str(), open_access, share_mode, nullptr, creation_disposition, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, nullptr); + if (handle == INVALID_HANDLE_VALUE) { + // TODO(benvanik): pick correct response. + return nullptr; + } + return std::make_unique(path, handle); +} + +#define COMBINE_TIME(t) (((uint64_t)t.dwHighDateTime << 32) | t.dwLowDateTime) + +bool GetInfo(const std::filesystem::path& path, FileInfo* out_info) { + *out_info = FileInfo{}; + WIN32_FILE_ATTRIBUTE_DATA data = {}; + if (!GetFileAttributesExW(path.c_str(), GetFileExInfoStandard, &data)) { + return false; + } + if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + out_info->type = FileInfo::Type::kDirectory; + out_info->total_size = 0; + } else { + out_info->type = FileInfo::Type::kFile; + out_info->total_size = (data.nFileSizeHigh * (size_t(MAXDWORD) + 1)) + data.nFileSizeLow; + } + out_info->path = path.parent_path(); + out_info->name = path.filename(); + out_info->create_timestamp = COMBINE_TIME(data.ftCreationTime); + out_info->access_timestamp = COMBINE_TIME(data.ftLastAccessTime); + out_info->write_timestamp = COMBINE_TIME(data.ftLastWriteTime); + return true; +} + +std::vector ListFiles(const std::filesystem::path& path) { + std::vector result; + + WIN32_FIND_DATAW ffd; + HANDLE handle = FindFirstFileW((path / "*").c_str(), &ffd); + if (handle == INVALID_HANDLE_VALUE) { + return result; + } + do { + if (std::wcscmp(ffd.cFileName, L".") == 0 || std::wcscmp(ffd.cFileName, L"..") == 0) { + continue; + } + FileInfo info; + if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + info.type = FileInfo::Type::kDirectory; + info.total_size = 0; + } else { + info.type = FileInfo::Type::kFile; + info.total_size = (ffd.nFileSizeHigh * (size_t(MAXDWORD) + 1)) + ffd.nFileSizeLow; + } + info.path = path; + info.name = ffd.cFileName; + info.create_timestamp = COMBINE_TIME(ffd.ftCreationTime); + info.access_timestamp = COMBINE_TIME(ffd.ftLastAccessTime); + info.write_timestamp = COMBINE_TIME(ffd.ftLastWriteTime); + result.push_back(info); + } while (FindNextFileW(handle, &ffd) != 0); + FindClose(handle); + + return result; +} + +} // namespace filesystem +} // namespace rex diff --git a/src/core/logging.cpp b/src/core/logging.cpp new file mode 100644 index 0000000..a91a38c --- /dev/null +++ b/src/core/logging.cpp @@ -0,0 +1,556 @@ +/** + * @file core/logging.cpp + * @brief Logging infrastructure implementation + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#if REX_PLATFORM_WIN32 +#include +#else +#include +#endif + +REXCVAR_DEFINE_STRING(log_level, "info", "Log", + "Global log level: trace, debug, info, warn, error, critical, off") + .allowed({"trace", "debug", "info", "warn", "error", "critical", "off"}); + +REXCVAR_DEFINE_STRING(log_file, "", "Log", "Log file path (empty = auto sequential naming)"); + +REXCVAR_DEFINE_BOOL(log_verbose, false, "Log", "Enable verbose logging (sets level to trace)") + .debug_only(); + +REXCVAR_DEFINE_BOOL(log_noisy, false, "Log", "Enable noisy/high-frequency log macros"); + +REXCVAR_DEFINE_INT32(log_flush_interval, 0, "Log", "Periodic flush interval in seconds (0 = off)") + .range(0, 60) + .lifecycle(rex::cvar::Lifecycle::kInitOnly); + +REXCVAR_DEFINE_INT32(log_max_file_size_mb, 5, "Log", "Max log file size in MB before rotation") + .range(1, 100) + .lifecycle(rex::cvar::Lifecycle::kInitOnly); + +REXCVAR_DEFINE_INT32(log_max_files, 20, "Log", "Max number of rotated log files to keep") + .range(1, 100) + .lifecycle(rex::cvar::Lifecycle::kInitOnly); + +namespace rex { + +namespace { + +std::vector g_registry; +spdlog::sink_ptr g_console_sink; +spdlog::sink_ptr g_file_sink; +spdlog::sink_ptr g_early_sink; +std::vector g_extra_sinks; +bool g_early_initialized = false; +bool g_initialized = false; +std::mutex g_mutex; +LogConfig g_config; + +std::filesystem::path NextSequentialLogPath(const std::filesystem::path& logs_dir, + std::string_view app_name) { + std::filesystem::create_directories(logs_dir); + + int max_seq = 0; + std::string prefix = std::string(app_name) + "_"; + std::error_code ec; + for (const auto& entry : std::filesystem::directory_iterator(logs_dir, ec)) { + if (!entry.is_regular_file()) + continue; + auto stem = entry.path().stem().string(); + if (stem.starts_with(prefix)) { + auto num_str = stem.substr(prefix.size()); + int num = 0; + auto [ptr, parse_ec] = std::from_chars(num_str.data(), num_str.data() + num_str.size(), num); + if (parse_ec == std::errc() && ptr == num_str.data() + num_str.size()) + max_seq = std::max(max_seq, num); + } + } + + return logs_dir / fmt::format("{}_{:03d}.log", app_name, max_seq + 1); +} + +std::vector BuildDefaultSinks() { + std::vector sinks; + if (g_early_sink) + sinks.push_back(g_early_sink); + if (g_console_sink) + sinks.push_back(g_console_sink); + if (g_file_sink) + sinks.push_back(g_file_sink); + for (auto& s : g_extra_sinks) + sinks.push_back(s); + return sinks; +} + +// Build sinks for a specific category (handles per-category sinks from config) +std::vector BuildCategorySinks(const std::string& name) { + auto it = g_config.category_sinks.find(name); + if (it != g_config.category_sinks.end()) { + if (g_config.category_sinks_exclusive) { + // Replace default sinks entirely + return it->second; + } + // Additive: default sinks + category-specific sinks + auto sinks = BuildDefaultSinks(); + for (auto& s : it->second) + sinks.push_back(s); + return sinks; + } + return BuildDefaultSinks(); +} + +// Resolve per-category level from config, or return default +spdlog::level::level_enum ResolveCategoryLevel(const std::string& name) { + auto it = g_config.category_levels.find(name); + if (it != g_config.category_levels.end()) + return it->second; + return g_config.default_level; +} + +// Create a logger and register it +std::shared_ptr CreateCategoryLogger(const std::string& name) { + auto sinks = BuildCategorySinks(name); + auto logger = std::make_shared(name, sinks.begin(), sinks.end()); + logger->set_level(ResolveCategoryLevel(name)); + logger->flush_on(g_config.flush_level); + spdlog::register_logger(logger); + return logger; +} + +} // namespace + +void InitLoggingEarly() { + std::lock_guard lock(g_mutex); + if (g_early_initialized || g_initialized) + return; + +#if REX_PLATFORM_WIN32 + auto sink = std::make_shared(); +#else + auto sink = std::make_shared(); +#endif + sink->set_level(spdlog::level::trace); + sink->set_pattern("[%l] [%n] %v"); + g_early_sink = sink; + + g_config.default_level = kDefaultLogLevel; + + // Create loggers for any categories already registered during static init + for (auto& entry : g_registry) { + if (!entry.name.empty() && !entry.logger) + entry.logger = CreateCategoryLogger(entry.name); + } + + // Set default logger to "core" if registered + for (auto& entry : g_registry) { + if (entry.name == "core") { + spdlog::set_default_logger(entry.logger); + break; + } + } + g_early_initialized = true; +} + +void InitLogging(const LogConfig& config) { + std::lock_guard lock(g_mutex); + + if (g_initialized) { + g_config = config; + for (auto& entry : g_registry) { + if (!entry.logger) + continue; + entry.logger->set_level(ResolveCategoryLevel(entry.name)); + entry.logger->flush_on(config.flush_level); + if (g_config.category_levels.count(entry.name)) + entry.has_explicit_level = true; + } + return; + } + + g_config = config; + + // Early sink handling: + // Windows: the early msvc_sink is the persistent debug channel for GUI + // apps and does not conflict with the stdout console sink, so keep it. + // Non-Windows: drop the early stdout sink unconditionally so file-only + // configs don't leak to stdout and console configs don't duplicate. +#if !REX_PLATFORM_WIN32 + if (g_early_sink) { + for (auto& entry : g_registry) { + if (entry.logger) + std::erase(entry.logger->sinks(), g_early_sink); + } + g_early_sink.reset(); + } +#endif + + // Console sink (stdout, colored). Intended for console-subsystem processes. + if (config.log_to_console) { + auto sink = std::make_shared(); + sink->set_level(spdlog::level::trace); + sink->set_pattern(config.console_pattern); + g_console_sink = sink; + } + + // File sink (rotating) with sequential naming fallback + std::string resolved_path; + if (config.log_file) { + resolved_path = config.log_file; + } else if (!config.app_name.empty()) { + auto log_dir = config.log_dir.empty() ? std::filesystem::current_path() / "logs" + : std::filesystem::path(config.log_dir); + resolved_path = NextSequentialLogPath(log_dir, config.app_name).string(); + } + if (!resolved_path.empty()) { + auto sink = std::make_shared( + resolved_path, static_cast(REXCVAR_GET(log_max_file_size_mb)) * 1024 * 1024, + static_cast(REXCVAR_GET(log_max_files)), false); + sink->set_level(spdlog::level::trace); + sink->set_pattern(config.file_pattern); + g_file_sink = sink; + } + + g_extra_sinks = config.extra_sinks; + + // Rebuild all loggers with new sinks + for (auto& entry : g_registry) { + if (entry.name.empty()) + continue; + if (entry.logger) + spdlog::drop(entry.name); + entry.logger = CreateCategoryLogger(entry.name); + if (g_config.category_levels.count(entry.name)) + entry.has_explicit_level = true; + } + + // Set default logger to "core" + for (auto& entry : g_registry) { + if (entry.name == "core") { + spdlog::set_default_logger(entry.logger); + break; + } + } + g_initialized = true; + + // Periodic flush + int flush_interval = REXCVAR_GET(log_flush_interval); + if (flush_interval > 0) + spdlog::flush_every(std::chrono::seconds(flush_interval)); +} + +void InitLogging(const char* log_file, spdlog::level::level_enum level) { + LogConfig config; + config.log_file = log_file; + config.default_level = level; + InitLogging(config); +} + +void ShutdownLogging() { + std::lock_guard lock(g_mutex); + if (!g_initialized && !g_early_initialized) + return; + + for (auto& entry : g_registry) + if (entry.logger) + entry.logger->flush(); + + spdlog::shutdown(); + g_registry.clear(); + g_console_sink.reset(); + g_file_sink.reset(); + g_early_sink.reset(); + g_extra_sinks.clear(); + g_initialized = false; + g_early_initialized = false; +} + +LogCategoryId RegisterLogCategory(const char* name) { + std::lock_guard lock(g_mutex); + + // Check for duplicates + for (size_t i = 0; i < g_registry.size(); ++i) { + if (g_registry[i].name == name) { + return LogCategoryId{static_cast(i)}; + } + } + + uint16_t id = static_cast(g_registry.size()); + LogCategoryEntry entry; + entry.name = name; + if (g_initialized || g_early_initialized) { + entry.logger = CreateCategoryLogger(name); + } + g_registry.push_back(std::move(entry)); + return LogCategoryId{id}; +} + +LogCategoryId RegisterLogSubcategory(const char* name, LogCategoryId parent) { + std::lock_guard lock(g_mutex); + + std::string parent_name; + if (parent.id < g_registry.size()) + parent_name = g_registry[parent.id].name; + std::string full_name = parent_name + "." + name; + + for (size_t i = 0; i < g_registry.size(); ++i) { + if (g_registry[i].name == full_name) + return LogCategoryId{static_cast(i)}; + } + + uint16_t id = static_cast(g_registry.size()); + LogCategoryEntry entry; + entry.name = full_name; + entry.parent = parent; + if (g_initialized || g_early_initialized) { + entry.logger = CreateCategoryLogger(full_name); + if (g_config.category_levels.count(full_name)) + entry.has_explicit_level = true; + } + g_registry.push_back(std::move(entry)); + return LogCategoryId{id}; +} + +std::optional FindCategory(const std::string& name) { + std::lock_guard lock(g_mutex); + for (size_t i = 0; i < g_registry.size(); ++i) { + if (g_registry[i].name == name) { + return LogCategoryId{static_cast(i)}; + } + } + return std::nullopt; +} + +std::span GetAllCategories() { + // No lock: only safe to call from main thread or after init. + return {g_registry.data(), g_registry.size()}; +} + +spdlog::logger* GetLoggerRaw(LogCategoryId category) { + if (!g_initialized && !g_early_initialized) + InitLoggingEarly(); + if (category.id < g_registry.size()) { + return g_registry[category.id].logger.get(); + } + return nullptr; +} + +std::shared_ptr GetLogger(LogCategoryId category) { + if (!g_initialized && !g_early_initialized) + InitLoggingEarly(); + if (category.id < g_registry.size()) { + return g_registry[category.id].logger; + } + return nullptr; +} + +std::shared_ptr GetLogger() { + return GetLogger(rex::log::core()); +} + +void SetCategoryLevel(LogCategoryId category, spdlog::level::level_enum level) { + if (category.id < g_registry.size()) { + if (auto& logger = g_registry[category.id].logger) { + logger->set_level(level); + } + } +} + +void SetAllLevels(spdlog::level::level_enum level) { + for (auto& entry : g_registry) { + if (entry.logger) + entry.logger->set_level(level); + } +} + +void SetRootLevel(LogCategoryId root, spdlog::level::level_enum level) { + SetCategoryLevel(root, level); + for (auto& entry : g_registry) { + if (entry.parent.has_value() && entry.parent->id == root.id && !entry.has_explicit_level && + entry.logger) + entry.logger->set_level(level); + } +} + +void RegisterLogLevelCallback() { + rex::cvar::RegisterChangeCallback("log_level", [](std::string_view, std::string_view value) { + if (auto level = ParseLogLevel(std::string(value))) { + for (size_t i = 0; i < g_registry.size(); ++i) { + auto& entry = g_registry[i]; + if (!entry.parent.has_value() && entry.logger && !entry.has_explicit_level) + SetRootLevel(LogCategoryId{static_cast(i)}, *level); + } + } + }); +} + +void AddSink(spdlog::sink_ptr sink) { + std::lock_guard lock(g_mutex); + g_extra_sinks.push_back(sink); + for (auto& entry : g_registry) { + if (entry.logger) + entry.logger->sinks().push_back(sink); + } +} + +void AddSink(LogCategoryId category, spdlog::sink_ptr sink) { + std::lock_guard lock(g_mutex); + if (category.id < g_registry.size()) { + if (auto& logger = g_registry[category.id].logger) { + logger->sinks().push_back(sink); + } + } +} + +void RemoveSink(spdlog::sink_ptr sink) { + std::lock_guard lock(g_mutex); + std::erase(g_extra_sinks, sink); + for (auto& entry : g_registry) { + if (entry.logger) + std::erase(entry.logger->sinks(), sink); + } +} + +void RemoveSink(LogCategoryId category, spdlog::sink_ptr sink) { + std::lock_guard lock(g_mutex); + if (category.id < g_registry.size()) { + if (auto& logger = g_registry[category.id].logger) { + std::erase(logger->sinks(), sink); + } + } +} + +void ReplaceConsoleSink(spdlog::sink_ptr sink) { + std::lock_guard lock(g_mutex); + for (auto& entry : g_registry) { + if (!entry.logger) + continue; + auto& sinks = entry.logger->sinks(); + if (g_console_sink) + std::erase(sinks, g_console_sink); + if (sink) + sinks.push_back(sink); + } + g_console_sink = sink; +} + +void SetConsolePattern(const std::string& pattern) { + if (g_console_sink) + g_console_sink->set_pattern(pattern); +} + +void SetFilePattern(const std::string& pattern) { + if (g_file_sink) + g_file_sink->set_pattern(pattern); +} + +// ========================================================================== +// CLI Helpers +// ========================================================================== + +std::optional ParseLogLevel(const std::string& level_str) { + static const std::unordered_map level_map = { + {"trace", spdlog::level::trace}, {"debug", spdlog::level::debug}, + {"info", spdlog::level::info}, {"warn", spdlog::level::warn}, + {"warning", spdlog::level::warn}, {"error", spdlog::level::err}, + {"err", spdlog::level::err}, {"critical", spdlog::level::critical}, + {"off", spdlog::level::off}, + }; + + std::string lower = level_str; + std::transform(lower.begin(), lower.end(), lower.begin(), + [](unsigned char c) { return std::tolower(c); }); + + auto it = level_map.find(lower); + if (it != level_map.end()) + return it->second; + return std::nullopt; +} + +spdlog::level::level_enum ParseLogLevelOr(const std::string& level_str, + spdlog::level::level_enum default_level) { + return ParseLogLevel(level_str).value_or(default_level); +} + +LogConfig BuildLogConfig(const char* log_file, const std::string& cli_level, + const std::map& category_levels) { + LogConfig config; + config.log_file = log_file; + + // Build-type default + config.default_level = kDefaultLogLevel; + + // Environment variable + if (const char* env_level = std::getenv("REX_LOG_LEVEL")) { + if (auto level = ParseLogLevel(env_level)) + config.default_level = *level; + } else if (const char* env_level2 = std::getenv("SPDLOG_LEVEL")) { + if (auto level = ParseLogLevel(env_level2)) + config.default_level = *level; + } + + // CLI global level overrides environment + if (!cli_level.empty()) { + if (auto level = ParseLogLevel(cli_level)) + config.default_level = *level; + } + + // Per-category CLI levels (string-keyed) + for (const auto& [cat_name, level_str] : category_levels) { + if (level_str.empty()) + continue; + if (auto level = ParseLogLevel(level_str)) { + config.category_levels[cat_name] = *level; + } + } + + return config; +} + +std::map ParseCategoryLevelsFromConfig( + const std::filesystem::path& config_path) { + std::map result; + if (!std::filesystem::exists(config_path)) + return result; + + try { + auto config = toml::parse_file(config_path.string()); + auto* log_table = config["log"].as_table(); + if (!log_table) + return result; + auto* levels_table = (*log_table)["levels"].as_table(); + if (!levels_table) + return result; + + for (const auto& [key, value] : *levels_table) { + if (value.is_string()) + result[std::string(key)] = value.as_string()->get(); + } + } catch (const toml::parse_error&) {} + + return result; +} + +} // namespace rex diff --git a/src/core/mapped_memory_posix.cpp b/src/core/mapped_memory_posix.cpp new file mode 100644 index 0000000..92c06c8 --- /dev/null +++ b/src/core/mapped_memory_posix.cpp @@ -0,0 +1,136 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +namespace rex::memory { + +class PosixMappedMemory : public MappedMemory { + public: + PosixMappedMemory(void* data, size_t size, int file_descriptor) + : MappedMemory(data, size), file_descriptor_(file_descriptor) {} + + ~PosixMappedMemory() override { + if (data_) { + munmap(data_, size()); + } + if (file_descriptor_ >= 0) { + close(file_descriptor_); + } + } + + static std::unique_ptr WrapFileDescriptor(int file_descriptor, Mode mode, + size_t offset = 0, + size_t length = 0) { + int protection = 0; + switch (mode) { + case Mode::kRead: + protection |= PROT_READ; + break; + case Mode::kReadWrite: + protection |= PROT_READ | PROT_WRITE; + break; + } + + size_t map_length = length; + if (!length) { + struct stat64 file_stat; + if (fstat64(file_descriptor, &file_stat)) { + close(file_descriptor); + return nullptr; + } + map_length = size_t(file_stat.st_size); + } + + void* data = mmap(0, map_length, protection, MAP_SHARED, file_descriptor, offset); + if (!data || data == MAP_FAILED) { + close(file_descriptor); + return nullptr; + } + + return std::make_unique(data, map_length, file_descriptor); + } + + void Close(uint64_t truncate_size) override { + if (data_) { + munmap(data_, size()); + data_ = nullptr; + } + if (file_descriptor_ >= 0) { + if (truncate_size) { + ftruncate64(file_descriptor_, off64_t(truncate_size)); + } + close(file_descriptor_); + file_descriptor_ = -1; + } + } + + void Flush() override { msync(data(), size(), MS_ASYNC); } + + private: + int file_descriptor_; +}; + +std::unique_ptr MappedMemory::Open(const std::filesystem::path& path, Mode mode, + size_t offset, size_t length) { + int open_flags = 0; + switch (mode) { + case Mode::kRead: + open_flags |= O_RDONLY; + break; + case Mode::kReadWrite: + open_flags |= O_RDWR; + break; + } + int file_descriptor = open(path.c_str(), open_flags); + if (file_descriptor < 0) { + return nullptr; + } + return PosixMappedMemory::WrapFileDescriptor(file_descriptor, mode, offset, length); +} + +#if REX_PLATFORM_ANDROID +std::unique_ptr MappedMemory::OpenForAndroidContentUri(const std::string_view uri, + Mode mode, size_t offset, + size_t length) { + const char* open_mode = nullptr; + switch (mode) { + case Mode::kRead: + open_mode = "r"; + break; + case Mode::kReadWrite: + open_mode = "rw"; + break; + } + int file_descriptor = rex::filesystem::OpenAndroidContentFileDescriptor(uri, open_mode); + if (file_descriptor < 0) { + return nullptr; + } + return PosixMappedMemory::WrapFileDescriptor(file_descriptor, mode, offset, length); +} +#endif // REX_PLATFORM_ANDROID + +std::unique_ptr ChunkedMappedMemoryWriter::Open( + const std::filesystem::path& path, size_t chunk_size, bool low_address_space) { + // TODO: Implement if needed + return nullptr; +} + +} // namespace rex::memory diff --git a/src/core/mapped_memory_win.cpp b/src/core/mapped_memory_win.cpp new file mode 100644 index 0000000..6085abc --- /dev/null +++ b/src/core/mapped_memory_win.cpp @@ -0,0 +1,365 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include "platform_win.h" + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | \ + WINAPI_PARTITION_GAMES) +#define REX_BASE_MAPPED_MEMORY_WIN_USE_DESKTOP_FUNCTIONS +#endif + +namespace rex::memory { + +class Win32MappedMemory : public MappedMemory { + public: + // CreateFile returns INVALID_HANDLE_VALUE in case of failure. + static inline const HANDLE kFileHandleInvalid = INVALID_HANDLE_VALUE; + // CreateFileMapping returns nullptr in case of failure. + static constexpr HANDLE kMappingHandleInvalid = nullptr; + + ~Win32MappedMemory() override { + if (data_) { + UnmapViewOfFile(data_); + } + if (mapping_handle != kMappingHandleInvalid) { + CloseHandle(mapping_handle); + } + if (file_handle != kFileHandleInvalid) { + CloseHandle(file_handle); + } + } + + void Close(uint64_t truncate_size) override { + if (data_) { + UnmapViewOfFile(data_); + data_ = nullptr; + } + if (mapping_handle != kMappingHandleInvalid) { + CloseHandle(mapping_handle); + mapping_handle = kMappingHandleInvalid; + } + if (file_handle != kFileHandleInvalid) { + if (truncate_size) { + LONG distance_high = truncate_size >> 32; + SetFilePointer(file_handle, truncate_size & 0xFFFFFFFF, &distance_high, FILE_BEGIN); + SetEndOfFile(file_handle); + } + + CloseHandle(file_handle); + file_handle = kFileHandleInvalid; + } + } + + void Flush() override { FlushViewOfFile(data(), size()); } + bool Remap(size_t offset, size_t length) override { + size_t aligned_offset = offset & ~(memory::allocation_granularity() - 1); + size_t aligned_length = length + (offset - aligned_offset); + + UnmapViewOfFile(data_); +#ifdef REX_BASE_MAPPED_MEMORY_WIN_USE_DESKTOP_FUNCTIONS + data_ = MapViewOfFile(mapping_handle, view_access_, aligned_offset >> 32, + aligned_offset & 0xFFFFFFFF, aligned_length); +#else + data_ = MapViewOfFileFromApp(mapping_handle, ULONG(view_access_), ULONG64(aligned_offset), + aligned_length); +#endif + if (!data_) { + return false; + } + + if (length) { + size_ = aligned_length; + } else { + DWORD length_high; + size_t map_length = GetFileSize(file_handle, &length_high); + map_length |= static_cast(length_high) << 32; + size_ = map_length - aligned_offset; + } + + return true; + } + + HANDLE file_handle = kFileHandleInvalid; + HANDLE mapping_handle = kMappingHandleInvalid; + DWORD view_access_ = 0; +}; + +std::unique_ptr MappedMemory::Open(const std::filesystem::path& path, Mode mode, + size_t offset, size_t length) { + DWORD file_access = 0; + DWORD file_share = 0; + DWORD create_mode = 0; + DWORD mapping_protect = 0; + DWORD view_access = 0; + switch (mode) { + case Mode::kRead: + file_access |= GENERIC_READ; + file_share |= FILE_SHARE_READ; + create_mode |= OPEN_EXISTING; + mapping_protect |= PAGE_READONLY; + view_access |= FILE_MAP_READ; + break; + case Mode::kReadWrite: + file_access |= GENERIC_READ | GENERIC_WRITE; + file_share |= 0; + create_mode |= OPEN_EXISTING; + mapping_protect |= PAGE_READWRITE; + view_access |= FILE_MAP_READ | FILE_MAP_WRITE; + break; + } + + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + + const size_t aligned_offset = + offset & ~static_cast(system_info.dwAllocationGranularity - 1); + const size_t aligned_length = length + (offset - aligned_offset); + + auto mm = std::make_unique(); + mm->view_access_ = view_access; + + mm->file_handle = CreateFileW(path.c_str(), file_access, file_share, nullptr, create_mode, + FILE_ATTRIBUTE_NORMAL, nullptr); + if (mm->file_handle == Win32MappedMemory::kFileHandleInvalid) { + return nullptr; + } + +#ifdef REX_BASE_MAPPED_MEMORY_WIN_USE_DESKTOP_FUNCTIONS + mm->mapping_handle = + CreateFileMapping(mm->file_handle, nullptr, mapping_protect, DWORD(aligned_length >> 32), + DWORD(aligned_length), nullptr); +#else + mm->mapping_handle = CreateFileMappingFromApp(mm->file_handle, nullptr, ULONG(mapping_protect), + ULONG64(aligned_length), nullptr); +#endif + if (mm->mapping_handle == Win32MappedMemory::kMappingHandleInvalid) { + return nullptr; + } + +#ifdef REX_BASE_MAPPED_MEMORY_WIN_USE_DESKTOP_FUNCTIONS + mm->data_ = reinterpret_cast(MapViewOfFile(mm->mapping_handle, view_access, + DWORD(aligned_offset >> 32), + DWORD(aligned_offset), aligned_length)); +#else + mm->data_ = reinterpret_cast(MapViewOfFileFromApp( + mm->mapping_handle, ULONG(view_access), ULONG64(aligned_offset), aligned_length)); +#endif + if (!mm->data_) { + return nullptr; + } + + if (length) { + mm->size_ = aligned_length; + } else { + DWORD length_high; + size_t map_length = GetFileSize(mm->file_handle, &length_high); + map_length |= static_cast(length_high) << 32; + mm->size_ = map_length - aligned_offset; + } + + return std::move(mm); +} + +class Win32ChunkedMappedMemoryWriter : public ChunkedMappedMemoryWriter { + public: + Win32ChunkedMappedMemoryWriter(const std::filesystem::path& path, size_t chunk_size, + bool low_address_space) + : ChunkedMappedMemoryWriter(path, chunk_size, low_address_space) {} + + ~Win32ChunkedMappedMemoryWriter() override { + std::lock_guard lock(mutex_); + chunks_.clear(); + } + + uint8_t* Allocate(size_t length) override { + std::lock_guard lock(mutex_); + if (!chunks_.empty()) { + uint8_t* result = chunks_.back()->Allocate(length); + if (result != nullptr) { + return result; + } + } + auto chunk = std::make_unique(chunk_size_); + auto chunk_path = path_.replace_extension(fmt::format(".{}", chunks_.size())); + if (!chunk->Open(chunk_path, low_address_space_)) { + return nullptr; + } + uint8_t* result = chunk->Allocate(length); + chunks_.push_back(std::move(chunk)); + return result; + } + + void Flush() override { + std::lock_guard lock(mutex_); + for (auto& chunk : chunks_) { + chunk->Flush(); + } + } + + void FlushNew() override { + std::lock_guard lock(mutex_); + for (auto& chunk : chunks_) { + chunk->FlushNew(); + } + } + + private: + class Chunk { + public: + explicit Chunk(size_t capacity) + : file_handle_(Win32MappedMemory::kFileHandleInvalid), + mapping_handle_(Win32MappedMemory::kMappingHandleInvalid), + data_(nullptr), + offset_(0), + capacity_(capacity), + last_flush_offset_(0) {} + + ~Chunk() { + if (data_) { + UnmapViewOfFile(data_); + } + if (mapping_handle_ != Win32MappedMemory::kMappingHandleInvalid) { + CloseHandle(mapping_handle_); + } + if (file_handle_ != Win32MappedMemory::kFileHandleInvalid) { + CloseHandle(file_handle_); + } + } + + bool Open(const std::filesystem::path& path, bool low_address_space) { + DWORD file_access = GENERIC_READ | GENERIC_WRITE; + DWORD file_share = FILE_SHARE_READ; + DWORD create_mode = CREATE_ALWAYS; + DWORD mapping_protect = PAGE_READWRITE; + DWORD view_access = FILE_MAP_READ | FILE_MAP_WRITE; + + file_handle_ = CreateFileW(path.c_str(), file_access, file_share, nullptr, create_mode, + FILE_ATTRIBUTE_NORMAL, nullptr); + if (file_handle_ == Win32MappedMemory::kFileHandleInvalid) { + return false; + } + +#ifdef REX_BASE_MAPPED_MEMORY_WIN_USE_DESKTOP_FUNCTIONS + mapping_handle_ = CreateFileMapping(file_handle_, nullptr, mapping_protect, + DWORD(capacity_ >> 32), DWORD(capacity_), nullptr); +#else + mapping_handle_ = CreateFileMappingFromApp(file_handle_, nullptr, ULONG(mapping_protect), + ULONG64(capacity_), nullptr); +#endif + if (mapping_handle_ == Win32MappedMemory::kMappingHandleInvalid) { + return false; + } + + // If specified, ensure the allocation occurs in the lower 32-bit address + // space. + if (low_address_space) { + bool successful = false; + data_ = reinterpret_cast(0x10000000); +#ifndef REX_BASE_MAPPED_MEMORY_WIN_USE_DESKTOP_FUNCTIONS + HANDLE process = GetCurrentProcess(); +#endif + for (int i = 0; i < 1000; ++i) { +#ifdef REX_BASE_MAPPED_MEMORY_WIN_USE_DESKTOP_FUNCTIONS + if (MapViewOfFileEx(mapping_handle_, view_access, 0, 0, capacity_, data_)) { + successful = true; + } +#else + // VirtualAlloc2FromApp and MapViewOfFile3FromApp were added in + // 10.0.17134.0. + // https://docs.microsoft.com/en-us/uwp/win32-and-com/win32-apis + if (VirtualAlloc2FromApp(process, data_, capacity_, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, + PAGE_NOACCESS, nullptr, 0)) { + if (MapViewOfFile3FromApp(mapping_handle_, process, data_, 0, capacity_, + MEM_REPLACE_PLACEHOLDER, ULONG(mapping_protect), nullptr, + 0)) { + successful = true; + } else { + VirtualFree(data_, capacity_, MEM_RELEASE); + } + } +#endif + if (successful) { + break; + } + data_ += capacity_; + if (!successful) { + REXLOG_ERROR("Unable to find space for mapping"); + data_ = nullptr; + return false; + } + } + } else { +#ifdef REX_BASE_MAPPED_MEMORY_WIN_USE_DESKTOP_FUNCTIONS + data_ = reinterpret_cast( + MapViewOfFile(mapping_handle_, view_access, 0, 0, capacity_)); +#else + data_ = reinterpret_cast( + MapViewOfFileFromApp(mapping_handle_, ULONG(view_access), 0, capacity_)); +#endif + } + if (!data_) { + return false; + } + + return true; + } + + uint8_t* Allocate(size_t length) { + if (capacity_ - offset_ < length) { + return nullptr; + } + uint8_t* result = data_ + offset_; + offset_ += length; + return result; + } + + void Flush() { FlushViewOfFile(data_, offset_); } + + void FlushNew() { + FlushViewOfFile(data_ + last_flush_offset_, offset_ - last_flush_offset_); + last_flush_offset_ = offset_; + } + + private: + HANDLE file_handle_; + HANDLE mapping_handle_; + uint8_t* data_; + size_t offset_; + size_t capacity_; + size_t last_flush_offset_; + }; + + std::mutex mutex_; + std::vector> chunks_; +}; + +std::unique_ptr ChunkedMappedMemoryWriter::Open( + const std::filesystem::path& path, size_t chunk_size, bool low_address_space) { + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + size_t aligned_chunk_size = + rex::round_up(chunk_size, size_t(system_info.dwAllocationGranularity)); + return std::make_unique(path, aligned_chunk_size, + low_address_space); +} + +} // namespace rex::memory diff --git a/src/core/math_gcc.cpp b/src/core/math_gcc.cpp new file mode 100644 index 0000000..1ec7192 --- /dev/null +++ b/src/core/math_gcc.cpp @@ -0,0 +1,47 @@ +#include +#include + +#if REX_PLATFORM_WIN32 +static_assert(false, "This file is non-MSVC only"); +#endif + +namespace rex { + +uint8_t lzcnt(uint8_t v) { + return v == 0 ? 8 : static_cast(__builtin_clz(v) - 24); +} +uint8_t lzcnt(uint16_t v) { + return v == 0 ? 16 : static_cast(__builtin_clz(v) - 16); +} +uint8_t lzcnt(uint32_t v) { + return v == 0 ? 32 : static_cast(__builtin_clz(v)); +} +uint8_t lzcnt(uint64_t v) { + return v == 0 ? 64 : static_cast(__builtin_clzll(v)); +} + +uint8_t tzcnt(uint8_t v) { + return v == 0 ? 8 : static_cast(__builtin_ctz(v)); +} +uint8_t tzcnt(uint16_t v) { + return v == 0 ? 16 : static_cast(__builtin_ctz(v)); +} +uint8_t tzcnt(uint32_t v) { + return v == 0 ? 32 : static_cast(__builtin_ctz(v)); +} +uint8_t tzcnt(uint64_t v) { + return v == 0 ? 64 : static_cast(__builtin_ctzll(v)); +} + +bool bit_scan_forward(uint32_t v, uint32_t* out_first_set_index) { + int i = ffs(v); + *out_first_set_index = i - 1; + return i != 0; +} +bool bit_scan_forward(uint64_t v, uint32_t* out_first_set_index) { + int i = __builtin_ffsll(v); + *out_first_set_index = i - 1; + return i != 0; +} + +} // namespace rex diff --git a/src/core/math_msvc.cpp b/src/core/math_msvc.cpp new file mode 100644 index 0000000..d9afc56 --- /dev/null +++ b/src/core/math_msvc.cpp @@ -0,0 +1,67 @@ +#include +#include + +static_assert(REX_PLATFORM_WIN32, "This file is Windows-only"); + +#include + +namespace rex { + +uint8_t lzcnt(uint8_t v) { + unsigned long index; + unsigned long mask = v; + unsigned char is_nonzero = _BitScanReverse(&index, mask); + return static_cast(is_nonzero ? int8_t(index) ^ 0x7 : 8); +} +uint8_t lzcnt(uint16_t v) { + unsigned long index; + unsigned long mask = v; + unsigned char is_nonzero = _BitScanReverse(&index, mask); + return static_cast(is_nonzero ? int8_t(index) ^ 0xF : 16); +} +uint8_t lzcnt(uint32_t v) { + unsigned long index; + unsigned long mask = v; + unsigned char is_nonzero = _BitScanReverse(&index, mask); + return static_cast(is_nonzero ? int8_t(index) ^ 0x1F : 32); +} +uint8_t lzcnt(uint64_t v) { + unsigned long index; + unsigned long long mask = v; + unsigned char is_nonzero = _BitScanReverse64(&index, mask); + return static_cast(is_nonzero ? int8_t(index) ^ 0x3F : 64); +} + +uint8_t tzcnt(uint8_t v) { + unsigned long index; + unsigned long mask = v; + unsigned char is_nonzero = _BitScanForward(&index, mask); + return static_cast(is_nonzero ? int8_t(index) : 8); +} +uint8_t tzcnt(uint16_t v) { + unsigned long index; + unsigned long mask = v; + unsigned char is_nonzero = _BitScanForward(&index, mask); + return static_cast(is_nonzero ? int8_t(index) : 16); +} +uint8_t tzcnt(uint32_t v) { + unsigned long index; + unsigned long mask = v; + unsigned char is_nonzero = _BitScanForward(&index, mask); + return static_cast(is_nonzero ? int8_t(index) : 32); +} +uint8_t tzcnt(uint64_t v) { + unsigned long index; + unsigned long long mask = v; + unsigned char is_nonzero = _BitScanForward64(&index, mask); + return static_cast(is_nonzero ? int8_t(index) : 64); +} + +bool bit_scan_forward(uint32_t v, uint32_t* out_first_set_index) { + return _BitScanForward(reinterpret_cast(out_first_set_index), v) != 0; +} +bool bit_scan_forward(uint64_t v, uint32_t* out_first_set_index) { + return _BitScanForward64(reinterpret_cast(out_first_set_index), v) != 0; +} + +} // namespace rex diff --git a/src/core/memory.cpp b/src/core/memory.cpp new file mode 100644 index 0000000..316eb00 --- /dev/null +++ b/src/core/memory.cpp @@ -0,0 +1,380 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +REXCVAR_DEFINE_BOOL(writable_executable_memory, true, "Memory", + "Allow executable memory to be writable") + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +#if REX_ARCH_ARM64 +#include +#endif + +#include + +namespace rex { +namespace memory { + +bool IsWritableExecutableMemoryPreferred() { + return REXCVAR_GET(writable_executable_memory); +} + +// TODO(benvanik): fancy AVX versions. +// https://github.com/gnuradio/volk/blob/master/kernels/volk/volk_16u_byteswap.h +// https://github.com/gnuradio/volk/blob/master/kernels/volk/volk_32u_byteswap.h +// https://github.com/gnuradio/volk/blob/master/kernels/volk/volk_64u_byteswap.h +// Original links: +// https://gnuradio.org/redmine/projects/gnuradio/repository/revisions/cb32b70b79f430456208a2cd521d028e0ece5d5b/entry/volk/kernels/volk/volk_16u_byteswap.h +// https://gnuradio.org/redmine/projects/gnuradio/repository/revisions/f2bc76cc65ffba51a141950f98e75364e49df874/entry/volk/kernels/volk/volk_32u_byteswap.h +// https://gnuradio.org/redmine/projects/gnuradio/repository/revisions/2c4c371885c31222362f70a1cd714415d1398021/entry/volk/kernels/volk/volk_64u_byteswap.h + +void copy_128_aligned(void* dest, const void* src, size_t count) { + std::memcpy(dest, src, count * 16); +} + +#if REX_ARCH_AMD64 + +// This works around a GCC bug +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100801 +// TODO(Joel Linn): Remove this when fixed GCC versions are common place. +#if REX_COMPILER_GNUC +#define REX_WORKAROUND_CONSTANT_RETURN_IF(x) \ + if (__builtin_constant_p(x) && (x)) \ + return; +#else +#define REX_WORKAROUND_CONSTANT_RETURN_IF(x) +#endif +void copy_and_swap_16_aligned(void* dest_ptr, const void* src_ptr, size_t count) { + assert_zero(reinterpret_cast(dest_ptr) & 0xF); + assert_zero(reinterpret_cast(src_ptr) & 0xF); + + auto dest = reinterpret_cast(dest_ptr); + auto src = reinterpret_cast(src_ptr); + __m128i shufmask = _mm_set_epi8(0x0E, 0x0F, 0x0C, 0x0D, 0x0A, 0x0B, 0x08, 0x09, 0x06, 0x07, 0x04, + 0x05, 0x02, 0x03, 0x00, 0x01); + + size_t i = 0; + for (i = 0; i + 8 <= count; i += 8) { + __m128i input = _mm_load_si128(reinterpret_cast(&src[i])); + __m128i output = _mm_shuffle_epi8(input, shufmask); + _mm_store_si128(reinterpret_cast<__m128i*>(&dest[i]), output); + } + REX_WORKAROUND_CONSTANT_RETURN_IF(count % 8 == 0); + for (; i < count; ++i) { // handle residual elements + dest[i] = byte_swap(src[i]); + } +} + +void copy_and_swap_16_unaligned(void* dest_ptr, const void* src_ptr, size_t count) { + auto dest = reinterpret_cast(dest_ptr); + auto src = reinterpret_cast(src_ptr); + __m128i shufmask = _mm_set_epi8(0x0E, 0x0F, 0x0C, 0x0D, 0x0A, 0x0B, 0x08, 0x09, 0x06, 0x07, 0x04, + 0x05, 0x02, 0x03, 0x00, 0x01); + + size_t i; + for (i = 0; i + 8 <= count; i += 8) { + __m128i input = _mm_loadu_si128(reinterpret_cast(&src[i])); + __m128i output = _mm_shuffle_epi8(input, shufmask); + _mm_storeu_si128(reinterpret_cast<__m128i*>(&dest[i]), output); + } + REX_WORKAROUND_CONSTANT_RETURN_IF(count % 8 == 0); + for (; i < count; ++i) { // handle residual elements + dest[i] = byte_swap(src[i]); + } +} + +void copy_and_swap_32_aligned(void* dest_ptr, const void* src_ptr, size_t count) { + assert_zero(reinterpret_cast(dest_ptr) & 0xF); + assert_zero(reinterpret_cast(src_ptr) & 0xF); + + auto dest = reinterpret_cast(dest_ptr); + auto src = reinterpret_cast(src_ptr); + __m128i shufmask = _mm_set_epi8(0x0C, 0x0D, 0x0E, 0x0F, 0x08, 0x09, 0x0A, 0x0B, 0x04, 0x05, 0x06, + 0x07, 0x00, 0x01, 0x02, 0x03); + + size_t i; + for (i = 0; i + 4 <= count; i += 4) { + __m128i input = _mm_load_si128(reinterpret_cast(&src[i])); + __m128i output = _mm_shuffle_epi8(input, shufmask); + _mm_store_si128(reinterpret_cast<__m128i*>(&dest[i]), output); + } + REX_WORKAROUND_CONSTANT_RETURN_IF(count % 4 == 0); + for (; i < count; ++i) { // handle residual elements + dest[i] = byte_swap(src[i]); + } +} + +void copy_and_swap_32_unaligned(void* dest_ptr, const void* src_ptr, size_t count) { + auto dest = reinterpret_cast(dest_ptr); + auto src = reinterpret_cast(src_ptr); + __m128i shufmask = _mm_set_epi8(0x0C, 0x0D, 0x0E, 0x0F, 0x08, 0x09, 0x0A, 0x0B, 0x04, 0x05, 0x06, + 0x07, 0x00, 0x01, 0x02, 0x03); + + size_t i; + for (i = 0; i + 4 <= count; i += 4) { + __m128i input = _mm_loadu_si128(reinterpret_cast(&src[i])); + __m128i output = _mm_shuffle_epi8(input, shufmask); + _mm_storeu_si128(reinterpret_cast<__m128i*>(&dest[i]), output); + } + REX_WORKAROUND_CONSTANT_RETURN_IF(count % 4 == 0); + for (; i < count; ++i) { // handle residual elements + dest[i] = byte_swap(src[i]); + } +} + +void copy_and_swap_64_aligned(void* dest_ptr, const void* src_ptr, size_t count) { + assert_zero(reinterpret_cast(dest_ptr) & 0xF); + assert_zero(reinterpret_cast(src_ptr) & 0xF); + + auto dest = reinterpret_cast(dest_ptr); + auto src = reinterpret_cast(src_ptr); + __m128i shufmask = _mm_set_epi8(0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, + 0x03, 0x04, 0x05, 0x06, 0x07); + + size_t i; + for (i = 0; i + 2 <= count; i += 2) { + __m128i input = _mm_load_si128(reinterpret_cast(&src[i])); + __m128i output = _mm_shuffle_epi8(input, shufmask); + _mm_store_si128(reinterpret_cast<__m128i*>(&dest[i]), output); + } + REX_WORKAROUND_CONSTANT_RETURN_IF(count % 2 == 0); + for (; i < count; ++i) { // handle residual elements + dest[i] = byte_swap(src[i]); + } +} + +void copy_and_swap_64_unaligned(void* dest_ptr, const void* src_ptr, size_t count) { + auto dest = reinterpret_cast(dest_ptr); + auto src = reinterpret_cast(src_ptr); + __m128i shufmask = _mm_set_epi8(0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, + 0x03, 0x04, 0x05, 0x06, 0x07); + + size_t i; + for (i = 0; i + 2 <= count; i += 2) { + __m128i input = _mm_loadu_si128(reinterpret_cast(&src[i])); + __m128i output = _mm_shuffle_epi8(input, shufmask); + _mm_storeu_si128(reinterpret_cast<__m128i*>(&dest[i]), output); + } + REX_WORKAROUND_CONSTANT_RETURN_IF(count % 2 == 0); + for (; i < count; ++i) { // handle residual elements + dest[i] = byte_swap(src[i]); + } +} + +void copy_and_swap_16_in_32_aligned(void* dest_ptr, const void* src_ptr, size_t count) { + auto dest = reinterpret_cast(dest_ptr); + auto src = reinterpret_cast(src_ptr); + size_t i; + for (i = 0; i + 4 <= count; i += 4) { + __m128i input = _mm_load_si128(reinterpret_cast(&src[i])); + __m128i output = _mm_or_si128(_mm_slli_epi32(input, 16), _mm_srli_epi32(input, 16)); + _mm_store_si128(reinterpret_cast<__m128i*>(&dest[i]), output); + } + REX_WORKAROUND_CONSTANT_RETURN_IF(count % 4 == 0); + for (; i < count; ++i) { // handle residual elements + dest[i] = (src[i] >> 16) | (src[i] << 16); + } +} + +void copy_and_swap_16_in_32_unaligned(void* dest_ptr, const void* src_ptr, size_t count) { + auto dest = reinterpret_cast(dest_ptr); + auto src = reinterpret_cast(src_ptr); + size_t i; + for (i = 0; i + 4 <= count; i += 4) { + __m128i input = _mm_loadu_si128(reinterpret_cast(&src[i])); + __m128i output = _mm_or_si128(_mm_slli_epi32(input, 16), _mm_srli_epi32(input, 16)); + _mm_storeu_si128(reinterpret_cast<__m128i*>(&dest[i]), output); + } + REX_WORKAROUND_CONSTANT_RETURN_IF(count % 4 == 0); + for (; i < count; ++i) { // handle residual elements + dest[i] = (src[i] >> 16) | (src[i] << 16); + } +} + +#elif REX_ARCH_ARM64 + +// Although NEON offers vector rev instructions (like vrev32q_u8), they are +// slower in benchmarks. Also, using uint8x16xN_t wasn't any faster in the +// benchmarks, hence we use just use one SIMD register to minimize residual +// processing. + +void copy_and_swap_16_aligned(void* dst_ptr, const void* src_ptr, size_t count) { + copy_and_swap_16_unaligned(dst_ptr, src_ptr, count); +} + +void copy_and_swap_16_unaligned(void* dst_ptr, const void* src_ptr, size_t count) { + auto dst = reinterpret_cast(dst_ptr); + auto src = reinterpret_cast(src_ptr); + + const uint8x16_t tbl_idx = vcombine_u8(vcreate_u8(UINT64_C(0x0607040502030001)), + vcreate_u8(UINT64_C(0x0E0F0C0D0A0B0809))); + + while (count >= 8) { + uint8x16_t data = vld1q_u8(src); + data = vqtbl1q_u8(data, tbl_idx); + vst1q_u8(dst, data); + + count -= 8; + // These pointer increments will be combined with the load/stores (ldr/str) + // into single instructions (at least by clang) + dst += 16; + src += 16; + } + + while (count > 0) { + store_and_swap(dst, load(src)); + + count--; + dst += 2; + src += 2; + } +} + +void copy_and_swap_32_aligned(void* dst, const void* src, size_t count) { + copy_and_swap_32_unaligned(dst, src, count); +} + +void copy_and_swap_32_unaligned(void* dst_ptr, const void* src_ptr, size_t count) { + auto dst = reinterpret_cast(dst_ptr); + auto src = reinterpret_cast(src_ptr); + + const uint8x16_t tbl_idx = vcombine_u8(vcreate_u8(UINT64_C(0x405060700010203)), + vcreate_u8(UINT64_C(0x0C0D0E0F08090A0B))); + + while (count >= 4) { + uint8x16_t data = vld1q_u8(src); + data = vqtbl1q_u8(data, tbl_idx); + vst1q_u8(dst, data); + + count -= 4; + dst += 16; + src += 16; + } + + while (count > 0) { + store_and_swap(dst, load(src)); + + count--; + dst += 4; + src += 4; + } +} + +void copy_and_swap_64_aligned(void* dst, const void* src, size_t count) { + copy_and_swap_64_unaligned(dst, src, count); +} + +void copy_and_swap_64_unaligned(void* dst_ptr, const void* src_ptr, size_t count) { + auto dst = reinterpret_cast(dst_ptr); + auto src = reinterpret_cast(src_ptr); + + const uint8x16_t tbl_idx = vcombine_u8(vcreate_u8(UINT64_C(0x0001020304050607)), + vcreate_u8(UINT64_C(0x08090A0B0C0D0E0F))); + + while (count >= 2) { + uint8x16_t data = vld1q_u8(src); + data = vqtbl1q_u8(data, tbl_idx); + vst1q_u8(dst, data); + + count -= 2; + dst += 16; + src += 16; + } + + while (count > 0) { + store_and_swap(dst, load(src)); + + count--; + dst += 8; + src += 8; + } +} + +void copy_and_swap_16_in_32_aligned(void* dst, const void* src, size_t count) { + return copy_and_swap_16_in_32_unaligned(dst, src, count); +} + +void copy_and_swap_16_in_32_unaligned(void* dst_ptr, const void* src_ptr, size_t count) { + auto dst = reinterpret_cast(dst_ptr); + auto src = reinterpret_cast(src_ptr); + while (count > 0) { + uint16_t word0 = *src++; + uint16_t word1 = *src++; + *dst++ = word1; + *dst++ = word0; + + count--; + } +} + +#else + +// Generic routines. +void copy_and_swap_16_aligned(void* dest, const void* src, size_t count) { + return copy_and_swap_16_unaligned(dest, src, count); +} + +void copy_and_swap_16_unaligned(void* dest_ptr, const void* src_ptr, size_t count) { + auto dest = reinterpret_cast(dest_ptr); + auto src = reinterpret_cast(src_ptr); + for (size_t i = 0; i < count; ++i) { + dest[i] = byte_swap(src[i]); + } +} + +void copy_and_swap_32_aligned(void* dest, const void* src, size_t count) { + return copy_and_swap_32_unaligned(dest, src, count); +} + +void copy_and_swap_32_unaligned(void* dest_ptr, const void* src_ptr, size_t count) { + auto dest = reinterpret_cast(dest_ptr); + auto src = reinterpret_cast(src_ptr); + for (size_t i = 0; i < count; ++i) { + dest[i] = byte_swap(src[i]); + } +} + +void copy_and_swap_64_aligned(void* dest, const void* src, size_t count) { + return copy_and_swap_64_unaligned(dest, src, count); +} + +void copy_and_swap_64_unaligned(void* dest_ptr, const void* src_ptr, size_t count) { + auto dest = reinterpret_cast(dest_ptr); + auto src = reinterpret_cast(src_ptr); + for (size_t i = 0; i < count; ++i) { + dest[i] = byte_swap(src[i]); + } +} + +void copy_and_swap_16_in_32_aligned(void* dest, const void* src, size_t count) { + return copy_and_swap_16_in_32_unaligned(dest, src, count); +} + +void copy_and_swap_16_in_32_unaligned(void* dst_ptr, const void* src_ptr, size_t count) { + auto dst = reinterpret_cast(dst_ptr); + auto src = reinterpret_cast(src_ptr); + while (count > 0) { + uint16_t word0 = *src++; + uint16_t word1 = *src++; + *dst++ = word1; + *dst++ = word0; + + count--; + } +} + +#endif + +} // namespace memory +} // namespace rex diff --git a/src/core/memory_posix.cpp b/src/core/memory_posix.cpp new file mode 100644 index 0000000..fce701e --- /dev/null +++ b/src/core/memory_posix.cpp @@ -0,0 +1,430 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#if REX_PLATFORM_ANDROID +#include + +#include +#include + +#include + +// TODO(tomc): Android or maybe na. idk +// #include "xenia/base/main_android.h" +#endif + +namespace rex { +namespace memory { + +// Convert filesystem path to valid shm_open name (must start with /, no other slashes) +static std::string MakeShmName(const std::filesystem::path& path) { + std::string name = path.string(); + for (char& c : name) { + if (c == '/') + c = '_'; + } + if (name.empty() || name[0] != '/') { + name.insert(name.begin(), '/'); + } + return name; +} + +#if REX_PLATFORM_ANDROID +// May be null if no dynamically loaded functions are required. +static void* libandroid_; +// API 26+. +static int (*android_ASharedMemory_create_)(const char* name, size_t size); + +void AndroidInitialize() { + if (rex::GetAndroidApiLevel() >= 26) { + libandroid_ = dlopen("libandroid.so", RTLD_NOW); + assert_not_null(libandroid_); + if (libandroid_) { + android_ASharedMemory_create_ = reinterpret_cast( + dlsym(libandroid_, "ASharedMemory_create")); + assert_not_null(android_ASharedMemory_create_); + } + } +} + +void AndroidShutdown() { + android_ASharedMemory_create_ = nullptr; + if (libandroid_) { + dlclose(libandroid_); + libandroid_ = nullptr; + } +} +#endif + +size_t page_size() { + return getpagesize(); +} +size_t allocation_granularity() { + return page_size(); +} + +uint32_t ToPosixProtectFlags(PageAccess access) { + switch (access) { + case PageAccess::kNoAccess: + return PROT_NONE; + case PageAccess::kReadOnly: + return PROT_READ; + case PageAccess::kReadWrite: + return PROT_READ | PROT_WRITE; + case PageAccess::kExecuteReadOnly: + return PROT_READ | PROT_EXEC; + case PageAccess::kExecuteReadWrite: + return PROT_READ | PROT_WRITE | PROT_EXEC; + default: + assert_unhandled_case(access); + return PROT_NONE; + } +} + +bool IsWritableExecutableMemorySupported() { + return true; +} + +// TODO(tomc): this needs to go somewhere else. we should utilize the platform namespace more. +#if REX_PLATFORM_LINUX +namespace { + +struct LinuxMapEntry { + uintptr_t start = 0; + uintptr_t end = 0; + char perms[5] = {}; +}; + +// Parse a line from /proc/self/maps into a LinuxMapEntry +static bool ParseProcMapsLine(const std::string& line, LinuxMapEntry& out) { + out = LinuxMapEntry{}; + unsigned long long start = 0, end = 0; + char perms[5] = {}; + const int matched = std::sscanf(line.c_str(), "%llx-%llx %4s", &start, &end, perms); + if (matched < 3) + return false; + out.start = static_cast(start); + out.end = static_cast(end); + std::memcpy(out.perms, perms, sizeof(out.perms)); + return out.start < out.end; +} + +// Find the mapping entry in /proc/self/maps that contains the given address +static bool FindEntryForAddress(void* address, LinuxMapEntry& out_entry) { + const uintptr_t addr = reinterpret_cast(address); + std::ifstream maps("/proc/self/maps"); + if (!maps.is_open()) + return false; + std::string line; + while (std::getline(maps, line)) { + LinuxMapEntry e; + if (!ParseProcMapsLine(line, e)) + continue; + if (addr >= e.start && addr < e.end) { + out_entry = e; + return true; + } + } + return false; +} + +// Check if [base, base+length) is fully covered by existing mappings (no gaps) +static bool IsRangeFullyMapped(void* base_address, size_t length) { + if (!base_address || length == 0) + return false; + + const uintptr_t begin = reinterpret_cast(base_address); + const uintptr_t end = begin + length; + if (end < begin) { // overflow check + return false; + } + + std::ifstream maps("/proc/self/maps"); + if (!maps.is_open()) + return false; + + uintptr_t cursor = begin; + std::string line; + while (std::getline(maps, line)) { + LinuxMapEntry e; + if (!ParseProcMapsLine(line, e)) + continue; + if (e.end <= cursor) + continue; + if (e.start > cursor) + return false; // gap found + cursor = e.end; + if (cursor >= end) + return true; + } + return cursor >= end; +} + +// Convert /proc/self/maps permission chars to PageAccess +static PageAccess PermsToPageAccess(const char perms[5]) { + const bool r = perms[0] == 'r'; + const bool w = perms[1] == 'w'; + const bool x = perms[2] == 'x'; + + if (!r && !w && !x) + return PageAccess::kNoAccess; + if (x) + return w ? PageAccess::kExecuteReadWrite : PageAccess::kExecuteReadOnly; + return w ? PageAccess::kReadWrite : PageAccess::kReadOnly; +} + +} // namespace +#endif // REX_PLATFORM_LINUX + +void* AllocFixed(void* base_address, size_t length, AllocationType allocation_type, + PageAccess access) { + // Emulates Windows VirtualAlloc behavior: + // - Reserve: create PROT_NONE mapping to hold address space + // - Commit on existing reservation: mprotect to enable access (EEXIST path) + // - New allocation: mmap with MAP_FIXED_NOREPLACE (never silently replace) + const uint32_t prot_requested = ToPosixProtectFlags(access); + + // Determine initial protection based on allocation type + int prot_initial = 0; + switch (allocation_type) { + case AllocationType::kReserve: + prot_initial = PROT_NONE; + break; + case AllocationType::kCommit: + case AllocationType::kReserveCommit: + default: + prot_initial = static_cast(prot_requested); + break; + } + + // Build flags - always use MAP_FIXED_NOREPLACE for fixed addresses + int flags = MAP_PRIVATE | MAP_ANONYMOUS; +#if defined(MAP_FIXED_NOREPLACE) + if (base_address) { + flags |= MAP_FIXED_NOREPLACE; + } +#else + if (base_address) { + flags |= MAP_FIXED; + } +#endif + + void* result = mmap(base_address, length, prot_initial, flags, -1, 0); + if (result != MAP_FAILED) { + return result; + } +#if defined(MAP_FIXED_NOREPLACE) && REX_PLATFORM_LINUX + // Handle EEXIST: address already has a mapping (e.g., from prior Reserve) + // This is the "commit on existing reservation" path + if (errno == EEXIST && base_address && + (allocation_type == AllocationType::kCommit || + allocation_type == AllocationType::kReserveCommit)) { + // Verify the entire range is mapped before using mprotect + if (IsRangeFullyMapped(base_address, length)) { + if (mprotect(base_address, length, static_cast(prot_requested)) == 0) { + return base_address; + } + } + } +#endif + + return nullptr; +} + +bool DeallocFixed(void* base_address, size_t length, DeallocationType deallocation_type) { + switch (deallocation_type) { + case DeallocationType::kDecommit: { + // Decommit: remove access first, then release physical pages + if (mprotect(base_address, length, PROT_NONE) != 0) { + return false; + } +#if defined(MADV_DONTNEED) + (void)madvise(base_address, length, MADV_DONTNEED); +#endif + return true; + } + case DeallocationType::kRelease: { + return munmap(base_address, length) == 0; + } + default: + // how we get here? :( + assert_always(); + return false; + } +} + +bool Protect(void* base_address, size_t length, PageAccess access, PageAccess* out_old_access) { + if (out_old_access) { + *out_old_access = PageAccess::kNoAccess; + } + +#if REX_PLATFORM_LINUX + // NOTE(tomc): we may want to look at doing this differently. it should work for now + // but there is a TOCTOU window between reading and changing. + // This really shouldn't be an issue since VirtualProtect on Windows isn't truly + // atomic in a mutli-threaded process either, but it's something to be aware of. + // Query old access before changing, if the caller needs it + if (out_old_access) { + LinuxMapEntry e; + if (FindEntryForAddress(base_address, e)) { + *out_old_access = PermsToPageAccess(e.perms); + } + } +#endif + + uint32_t prot = ToPosixProtectFlags(access); + return mprotect(base_address, length, prot) == 0; +} + +bool QueryProtect(void* base_address, size_t& length, PageAccess& access_out) { +#if !REX_PLATFORM_LINUX + access_out = PageAccess::kNoAccess; + length = 0; + return false; +#else + access_out = PageAccess::kNoAccess; + length = 0; + + LinuxMapEntry e; + if (!FindEntryForAddress(base_address, e)) { + return false; + } + + const uintptr_t addr = reinterpret_cast(base_address); + length = static_cast(e.end - addr); + access_out = PermsToPageAccess(e.perms); + + return true; +#endif +} + +FileMappingHandle CreateFileMappingHandle(const std::filesystem::path& path, size_t length, + PageAccess access, bool commit) { +#if REX_PLATFORM_ANDROID + // TODO(Triang3l): Check if memfd can be used instead on API 30+. + if (android_ASharedMemory_create_) { + int sharedmem_fd = android_ASharedMemory_create_(path.c_str(), length); + return sharedmem_fd >= 0 ? static_cast(sharedmem_fd) + : kFileMappingHandleInvalid; + } + + // Use /dev/ashmem on API versions below 26, which added ASharedMemory. + // /dev/ashmem was disabled on API 29 for apps targeting it. + // https://chromium.googlesource.com/chromium/src/+/master/third_party/ashmem/ashmem-dev.c + int ashmem_fd = open("/" ASHMEM_NAME_DEF, O_RDWR); + if (ashmem_fd < 0) { + return kFileMappingHandleInvalid; + } + char ashmem_name[ASHMEM_NAME_LEN]; + strlcpy(ashmem_name, path.c_str(), rex::countof(ashmem_name)); + if (ioctl(ashmem_fd, ASHMEM_SET_NAME, ashmem_name) < 0 || + ioctl(ashmem_fd, ASHMEM_SET_SIZE, length) < 0) { + close(ashmem_fd); + return kFileMappingHandleInvalid; + } + return static_cast(ashmem_fd); +#else + int oflag; + switch (access) { + case PageAccess::kNoAccess: + oflag = 0; + break; + case PageAccess::kReadOnly: + case PageAccess::kExecuteReadOnly: + oflag = O_RDONLY; + break; + case PageAccess::kReadWrite: + case PageAccess::kExecuteReadWrite: + oflag = O_RDWR; + break; + default: + assert_always(); + return kFileMappingHandleInvalid; + } + oflag |= O_CREAT; + auto full_path = MakeShmName(path); + int ret = shm_open(full_path.c_str(), oflag, 0777); + if (ret < 0) { + return kFileMappingHandleInvalid; + } + if (ftruncate64(ret, static_cast(length)) != 0) { + close(ret); + shm_unlink(full_path.c_str()); + return kFileMappingHandleInvalid; + } + return static_cast(ret); +#endif +} + +void CloseFileMappingHandle(FileMappingHandle handle, const std::filesystem::path& path) { + close(static_cast(handle)); +#if !REX_PLATFORM_ANDROID + auto full_path = MakeShmName(path); + shm_unlink(full_path.c_str()); +#endif +} + +void* MapFileView(FileMappingHandle handle, void* base_address, size_t length, PageAccess access, + size_t file_offset) { + // file_offset must be page-aligned + const size_t page = page_size(); + if (file_offset % page != 0) { + return nullptr; + } + + int flags = MAP_SHARED; + + // For file views, we need MAP_FIXED to replace existing reservations. + // The emulator reserves address space first, then maps file views into it. + // MAP_FIXED_NOREPLACE would fail with EEXIST in this case. + if (base_address) { + flags |= MAP_FIXED; + } + + uint32_t prot = ToPosixProtectFlags(access); + void* result = mmap64(base_address, length, prot, flags, static_cast(handle), + static_cast(file_offset)); + if (result == MAP_FAILED) { + return nullptr; + } + + // Verify we got the address we asked for + if (base_address && result != base_address) { + munmap(result, length); + return nullptr; + } + + return result; +} + +bool UnmapFileView(FileMappingHandle handle, void* base_address, size_t length) { + return munmap(base_address, length) == 0; +} + +} // namespace memory +} // namespace rex diff --git a/src/core/memory_win.cpp b/src/core/memory_win.cpp new file mode 100644 index 0000000..9a668e9 --- /dev/null +++ b/src/core/memory_win.cpp @@ -0,0 +1,247 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include "platform_win.h" + +#include + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | \ + WINAPI_PARTITION_GAMES) +#define REX_BASE_MEMORY_WIN_USE_DESKTOP_FUNCTIONS +#endif + +namespace rex { +namespace memory { + +size_t page_size() { + static size_t value = 0; + if (!value) { + SYSTEM_INFO si; + GetSystemInfo(&si); + value = si.dwPageSize; + } + return value; +} + +size_t allocation_granularity() { + static size_t value = 0; + if (!value) { + SYSTEM_INFO si; + GetSystemInfo(&si); + value = si.dwAllocationGranularity; + } + return value; +} + +DWORD ToWin32ProtectFlags(PageAccess access) { + switch (access) { + case PageAccess::kNoAccess: + return PAGE_NOACCESS; + case PageAccess::kReadOnly: + return PAGE_READONLY; + case PageAccess::kReadWrite: + return PAGE_READWRITE; + case PageAccess::kExecuteReadOnly: + return PAGE_EXECUTE_READ; + case PageAccess::kExecuteReadWrite: + return PAGE_EXECUTE_READWRITE; + default: + assert_unhandled_case(access); + return PAGE_NOACCESS; + } +} + +PageAccess ToXeniaProtectFlags(DWORD access) { + if (access & PAGE_GUARD) { + // Strip the page guard flag for now... + access &= ~PAGE_GUARD; + } + + switch (access) { + case PAGE_NOACCESS: + return PageAccess::kNoAccess; + case PAGE_READONLY: + return PageAccess::kReadOnly; + case PAGE_READWRITE: + return PageAccess::kReadWrite; + case PAGE_EXECUTE_READ: + return PageAccess::kExecuteReadOnly; + case PAGE_EXECUTE_READWRITE: + return PageAccess::kExecuteReadWrite; + default: + return PageAccess::kNoAccess; + } +} + +bool IsWritableExecutableMemorySupported() { +#ifdef REX_BASE_MEMORY_WIN_USE_DESKTOP_FUNCTIONS + return true; +#else + // To test FromApp functions on desktop, undefine + // REX_BASE_MEMORY_WIN_USE_DESKTOP_FUNCTIONS and link to WindowsApp.lib. + return false; +#endif +} + +void* AllocFixed(void* base_address, size_t length, AllocationType allocation_type, + PageAccess access) { + DWORD alloc_type = 0; + switch (allocation_type) { + case AllocationType::kReserve: + alloc_type = MEM_RESERVE; + break; + case AllocationType::kCommit: + alloc_type = MEM_COMMIT; + break; + case AllocationType::kReserveCommit: + alloc_type = MEM_RESERVE | MEM_COMMIT; + break; + default: + assert_unhandled_case(allocation_type); + break; + } + DWORD protect = ToWin32ProtectFlags(access); +#ifdef REX_BASE_MEMORY_WIN_USE_DESKTOP_FUNCTIONS + return VirtualAlloc(base_address, length, alloc_type, protect); +#else + return VirtualAllocFromApp(base_address, length, ULONG(alloc_type), ULONG(protect)); +#endif +} + +bool DeallocFixed(void* base_address, size_t length, DeallocationType deallocation_type) { + DWORD free_type = 0; + switch (deallocation_type) { + case DeallocationType::kRelease: + free_type = MEM_RELEASE; + length = 0; + break; + case DeallocationType::kDecommit: + free_type = MEM_DECOMMIT; + break; + default: + assert_unhandled_case(deallocation_type); + break; + } + return VirtualFree(base_address, length, free_type) ? true : false; +} + +bool Protect(void* base_address, size_t length, PageAccess access, PageAccess* out_old_access) { + if (out_old_access) { + *out_old_access = PageAccess::kNoAccess; + } + DWORD new_protect = ToWin32ProtectFlags(access); +#ifdef REX_BASE_MEMORY_WIN_USE_DESKTOP_FUNCTIONS + DWORD old_protect = 0; + BOOL result = VirtualProtect(base_address, length, new_protect, &old_protect); +#else + ULONG old_protect = 0; + BOOL result = VirtualProtectFromApp(base_address, length, ULONG(new_protect), &old_protect); +#endif + if (!result) { + return false; + } + if (out_old_access) { + *out_old_access = ToXeniaProtectFlags(DWORD(old_protect)); + } + return true; +} + +bool QueryProtect(void* base_address, size_t& length, PageAccess& access_out) { + access_out = PageAccess::kNoAccess; + + MEMORY_BASIC_INFORMATION info; + ZeroMemory(&info, sizeof(info)); + + SIZE_T result = VirtualQuery(base_address, &info, sizeof(info)); + if (!result) { + return false; + } + + length = info.RegionSize; + access_out = ToXeniaProtectFlags(info.Protect); + return true; +} + +FileMappingHandle CreateFileMappingHandle(const std::filesystem::path& path, size_t length, + PageAccess access, bool commit) { + DWORD protect = ToWin32ProtectFlags(access) | (commit ? SEC_COMMIT : SEC_RESERVE); + auto full_path = "Local" / path; +#ifdef REX_BASE_MEMORY_WIN_USE_DESKTOP_FUNCTIONS + HANDLE h = + CreateFileMappingW(INVALID_HANDLE_VALUE, nullptr, protect, static_cast(length >> 32), + static_cast(length), full_path.c_str()); +#else + HANDLE h = CreateFileMappingFromApp(INVALID_HANDLE_VALUE, nullptr, ULONG(protect), + ULONG64(length), full_path.c_str()); +#endif + if (!h) { + return kFileMappingHandleInvalid; + } + return reinterpret_cast(h); +} + +void CloseFileMappingHandle(FileMappingHandle handle, const std::filesystem::path& path) { + CloseHandle(reinterpret_cast(handle)); +} + +void* MapFileView(FileMappingHandle handle, void* base_address, size_t length, PageAccess access, + size_t file_offset) { +#ifdef REX_BASE_MEMORY_WIN_USE_DESKTOP_FUNCTIONS + DWORD target_address_low = static_cast(file_offset); + DWORD target_address_high = static_cast(file_offset >> 32); + DWORD file_access = 0; + switch (access) { + case PageAccess::kReadOnly: + file_access = FILE_MAP_READ; + break; + case PageAccess::kReadWrite: + file_access = FILE_MAP_ALL_ACCESS; + break; + case PageAccess::kExecuteReadOnly: + file_access = FILE_MAP_READ | FILE_MAP_EXECUTE; + break; + case PageAccess::kExecuteReadWrite: + file_access = FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE; + break; + case PageAccess::kNoAccess: + default: + assert_unhandled_case(access); + return nullptr; + } + return MapViewOfFileEx(reinterpret_cast(handle), file_access, target_address_high, + target_address_low, length, base_address); +#else + // VirtualAlloc2FromApp and MapViewOfFile3FromApp were added in 10.0.17134.0. + // https://docs.microsoft.com/en-us/uwp/win32-and-com/win32-apis + HANDLE process = GetCurrentProcess(); + void* placeholder = + VirtualAlloc2FromApp(process, base_address, length, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, + PAGE_NOACCESS, nullptr, 0); + if (!placeholder) { + return nullptr; + } + void* mapping = MapViewOfFile3FromApp(reinterpret_cast(handle), process, placeholder, + ULONG64(file_offset), length, MEM_REPLACE_PLACEHOLDER, + ULONG(ToWin32ProtectFlags(access)), nullptr, 0); + if (!mapping) { + VirtualFree(placeholder, length, MEM_RELEASE); + return nullptr; + } + return mapping; +#endif +} + +bool UnmapFileView(FileMappingHandle handle, void* base_address, size_t length) { + return UnmapViewOfFile(base_address) ? true : false; +} + +} // namespace memory +} // namespace rex diff --git a/src/core/mutex.cpp b/src/core/mutex.cpp new file mode 100644 index 0000000..d639924 --- /dev/null +++ b/src/core/mutex.cpp @@ -0,0 +1,21 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +namespace rex::thread { + +std::recursive_mutex& global_critical_region::mutex() { + static std::recursive_mutex global_mutex; + return global_mutex; +} + +} // namespace rex::thread diff --git a/src/core/perf/counter.cpp b/src/core/perf/counter.cpp new file mode 100644 index 0000000..2ec4363 --- /dev/null +++ b/src/core/perf/counter.cpp @@ -0,0 +1,181 @@ +/** + * @file core/perf/counter.cpp + * @brief Performance counter registry implementation + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ +#include + +#include +#include + +#include +#include +#include +#include + +REXCVAR_DEFINE_STRING(perf_log_csv, "", "Perf", + "Path to write per-frame CSV log (empty = disabled)"); + +namespace rex::perf { + +namespace { + +constexpr size_t kNumCounters = static_cast(CounterId::kCount); + +std::array, kNumCounters> g_counters{}; +std::array, kNumCounters> g_snapshot{}; + +constexpr const char* kCounterNames[] = { + "frame_time_us", + "fps", + "draw_calls", + "command_buffer_stalls", + "vertices_processed", + "xma_frames_decoded", + "audio_frame_latency_us", + "buffer_queue_depth", + "functions_dispatched", + "interrupt_dispatches", + "active_threads", + "apc_queue_depth", + "critical_region_contentions", + "texture_cache_hits", + "texture_cache_misses", + "pipeline_cache_hits", + "pipeline_cache_misses", +}; +static_assert(std::size(kCounterNames) == kNumCounters, "kCounterNames must match CounterId enum"); + +// Gauge counters are snapshotted but NOT zeroed each frame. +// Accumulators (everything else) are zeroed after snapshot. +constexpr bool kIsGauge[] = { + false, // kFrameTimeUs (set each frame) + false, // kFps (set each frame) + false, // kDrawCalls + false, // kCommandBufferStalls + false, // kVerticesProcessed + false, // kXmaFramesDecoded + false, // kAudioFrameLatencyUs + false, // kBufferQueueDepth (set each frame) + false, // kFunctionsDispatched + false, // kInterruptDispatches + true, // kActiveThreads (inc/dec over lifetime) + false, // kApcQueueDepth + true, // kCriticalRegionContentions (running total) + false, // kTextureCacheHits + false, // kTextureCacheMisses + false, // kPipelineCacheHits + false, // kPipelineCacheMisses +}; +static_assert(std::size(kIsGauge) == kNumCounters, "kIsGauge must match CounterId enum"); + +// CSV state +std::FILE* g_csv_file = nullptr; +std::string g_csv_path; +int g_csv_frame_count = 0; + +} // anonymous namespace + +const char* CounterName(CounterId id) { + auto idx = static_cast(id); + if (idx < kNumCounters) + return kCounterNames[idx]; + return "unknown"; +} + +void SetCounter(CounterId id, int64_t value) { + g_counters[static_cast(id)].store(value, std::memory_order_relaxed); +} + +void IncrementCounter(CounterId id, int64_t delta) { + g_counters[static_cast(id)].fetch_add(delta, std::memory_order_relaxed); +} + +int64_t GetCounter(CounterId id) { + return g_counters[static_cast(id)].load(std::memory_order_relaxed); +} + +void ResetFrameCounters() { + for (size_t i = 0; i < kNumCounters; ++i) { + if (kIsGauge[i]) { + // Gauges: snapshot the current value, don't zero + g_snapshot[i].store(g_counters[i].load(std::memory_order_relaxed), std::memory_order_relaxed); + } else { + // Accumulators: snapshot and zero for next frame + g_snapshot[i].store(g_counters[i].exchange(0, std::memory_order_relaxed), + std::memory_order_relaxed); + } + } +} + +int64_t GetSnapshotCounter(CounterId id) { + return g_snapshot[static_cast(id)].load(std::memory_order_relaxed); +} + +void Init() { + for (auto& c : g_counters) + c.store(0, std::memory_order_relaxed); + for (auto& s : g_snapshot) + s.store(0, std::memory_order_relaxed); +} + +void SetCsvLogPath(const std::string& path) { + if (g_csv_file) { + std::fflush(g_csv_file); + std::fclose(g_csv_file); + g_csv_file = nullptr; + } + g_csv_path = path; + g_csv_frame_count = 0; + + if (path.empty()) + return; + + g_csv_file = std::fopen(path.c_str(), "w"); + if (!g_csv_file) { + REXLOG_WARN("perf: failed to open CSV log: {}", path); + g_csv_path.clear(); + return; + } + + // Write header + for (size_t i = 0; i < kNumCounters; ++i) { + if (i > 0) + std::fputc(',', g_csv_file); + std::fputs(kCounterNames[i], g_csv_file); + } + std::fputc('\n', g_csv_file); +} + +void WriteCsvFrame() { + if (!g_csv_file) + return; + + for (size_t i = 0; i < kNumCounters; ++i) { + if (i > 0) + std::fputc(',', g_csv_file); + std::fprintf(g_csv_file, "%lld", + static_cast(g_snapshot[i].load(std::memory_order_relaxed))); + } + std::fputc('\n', g_csv_file); + + if (++g_csv_frame_count % 60 == 0) { + std::fflush(g_csv_file); + } +} + +void FlushCsv() { + if (g_csv_file) { + std::fflush(g_csv_file); + std::fclose(g_csv_file); + g_csv_file = nullptr; + } + g_csv_path.clear(); +} + +} // namespace rex::perf diff --git a/src/core/platform_posix.h b/src/core/platform_posix.h new file mode 100644 index 0000000..14207a5 --- /dev/null +++ b/src/core/platform_posix.h @@ -0,0 +1,17 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +// NOTE: This file is auto-included by platform.h on Linux. +// It contains Linux-specific headers and definitions. + +#include diff --git a/src/core/platform_win.h b/src/core/platform_win.h new file mode 100644 index 0000000..44be14e --- /dev/null +++ b/src/core/platform_win.h @@ -0,0 +1,34 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +// NOTE: This file is auto-included by platform.h on Windows. +// It contains Windows-specific headers and definitions. + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#define NOMINMAX +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#undef DeleteBitmap +#undef DeleteFile +#undef GetFirstChild diff --git a/src/core/ring_buffer.cpp b/src/core/ring_buffer.cpp new file mode 100644 index 0000000..51340f5 --- /dev/null +++ b/src/core/ring_buffer.cpp @@ -0,0 +1,126 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include + +namespace rex::memory { + +RingBuffer::RingBuffer(uint8_t* buffer, size_t capacity) + : buffer_(buffer), capacity_(static_cast(capacity)) {} + +void RingBuffer::AdvanceRead(size_t count) { + ring_size_t cnt = static_cast(count); + if (read_offset_ + cnt < capacity_) { + read_offset_ += cnt; + } else { + ring_size_t left_half = capacity_ - read_offset_; + ring_size_t right_half = cnt - left_half; + read_offset_ = right_half; + } +} + +void RingBuffer::AdvanceWrite(size_t count) { + ring_size_t cnt = static_cast(count); + if (write_offset_ + cnt < capacity_) { + write_offset_ += cnt; + } else { + ring_size_t left_half = capacity_ - write_offset_; + ring_size_t right_half = cnt - left_half; + write_offset_ = right_half; + } +} + +RingBuffer::ReadRange RingBuffer::BeginRead(size_t count) { + ring_size_t cnt = static_cast(std::min(count, static_cast(capacity_))); + if (!cnt) { + return {nullptr, nullptr, 0, 0}; + } + if (read_offset_ + cnt < capacity_) { + return {buffer_ + read_offset_, nullptr, cnt, 0}; + } else { + ring_size_t left_half = capacity_ - read_offset_; + ring_size_t right_half = cnt - left_half; + return {buffer_ + read_offset_, buffer_, left_half, right_half}; + } +} + +void RingBuffer::EndRead(ReadRange read_range) { + if (read_range.second) { + read_offset_ = read_range.second_length; + } else { + read_offset_ += read_range.first_length; + } +} + +size_t RingBuffer::Read(uint8_t* buffer, size_t count) { + count = std::min(count, static_cast(capacity_)); + if (!count) { + return 0; + } + + ring_size_t cnt = static_cast(count); + + // Sanity check: Make sure we don't read over the write offset. + if (read_offset_ < write_offset_) { + assert_true(read_offset_ + cnt <= write_offset_); + } else if (read_offset_ + cnt >= capacity_) { + ring_size_t left_half = capacity_ - read_offset_; + assert_true(cnt - left_half <= write_offset_); + } + + if (read_offset_ + cnt < capacity_) { + std::memcpy(buffer, buffer_ + read_offset_, cnt); + read_offset_ += cnt; + } else { + ring_size_t left_half = capacity_ - read_offset_; + ring_size_t right_half = cnt - left_half; + std::memcpy(buffer, buffer_ + read_offset_, left_half); + std::memcpy(buffer + left_half, buffer_, right_half); + read_offset_ = right_half; + } + + return count; +} + +size_t RingBuffer::Write(const uint8_t* buffer, size_t count) { + count = std::min(count, static_cast(capacity_)); + if (!count) { + return 0; + } + + ring_size_t cnt = static_cast(count); + + // Sanity check: Make sure we don't write over the read offset. + if (write_offset_ < read_offset_) { + assert_true(write_offset_ + cnt <= read_offset_); + } else if (write_offset_ + cnt >= capacity_) { + ring_size_t left_half = capacity_ - write_offset_; + assert_true(cnt - left_half <= read_offset_); + } + + if (write_offset_ + cnt < capacity_) { + std::memcpy(buffer_ + write_offset_, buffer, cnt); + write_offset_ += cnt; + } else { + ring_size_t left_half = capacity_ - write_offset_; + ring_size_t right_half = cnt - left_half; + std::memcpy(buffer_ + write_offset_, buffer, left_half); + std::memcpy(buffer_, buffer + left_half, right_half); + write_offset_ = right_half; + } + + return count; +} + +} // namespace rex::memory diff --git a/src/core/seh_posix.cpp b/src/core/seh_posix.cpp new file mode 100644 index 0000000..5e0a932 --- /dev/null +++ b/src/core/seh_posix.cpp @@ -0,0 +1,123 @@ +/** + * @file core/seh_posix.cpp + * @brief POSIX platform SEH implementations + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include +#include + +static_assert(REX_PLATFORM_LINUX || REX_PLATFORM_MAC, "This file is POSIX-only"); + +#include +#include // std::abort() + +#include + +namespace rex::platform { + +static thread_local SehThreadState tls_seh_state; +static thread_local bool tls_seh_active = false; + +SehThreadState& seh_thread_state() { + return tls_seh_state; +} + +int seh_filter(uint32_t /*code*/, void* /*ep*/) { + // Not used on POSIX - signal handlers throw directly + return 0; +} + +/// Signal handler for SIGSEGV/SIGBUS/SIGFPE/SIGILL +static void signal_handler(int sig, siginfo_t* info, void* /*ucontext*/) { + // Only handle if we're in SEH-protected code + if (!tls_seh_active) { + // Not in SEH region - restore default handler and re-raise + signal(sig, SIG_DFL); + raise(sig); + return; + } + + // Determine exception code based on signal + SehException::Code code; + switch (sig) { + case SIGSEGV: + code = SehException::ACCESS_VIOLATION; + break; + case SIGBUS: + code = SehException::IN_PAGE_ERROR; + break; + case SIGFPE: + code = SehException::FLOAT_DIVIDE_BY_ZERO; + break; + case SIGILL: + code = SehException::ILLEGAL_INSTRUCTION; + break; + default: + code = SehException::UNKNOWN; + break; + } + + // Get fault address + uintptr_t address = info ? reinterpret_cast(info->si_addr) : 0; + + // Store in thread state for potential rethrow + tls_seh_state.code = static_cast(code); + tls_seh_state.info[0] = 0; + tls_seh_state.info[1] = address; + + // Use libunwind to throw from signal context + // This works because libunwind can unwind through signal frames + throw SehException(code, address); +} + +[[noreturn]] void seh_rethrow() { + // Map stored code back to signal and re-raise + uint32_t code = tls_seh_state.code; + int sig; + switch (code) { + case SehException::ACCESS_VIOLATION: + sig = SIGSEGV; + break; + case SehException::IN_PAGE_ERROR: + sig = SIGBUS; + break; + case SehException::FLOAT_DIVIDE_BY_ZERO: + case SehException::INTEGER_DIVIDE_BY_ZERO: + sig = SIGFPE; + break; + case SehException::ILLEGAL_INSTRUCTION: + sig = SIGILL; + break; + default: + abort(); + } + // Restore default handler and re-raise + signal(sig, SIG_DFL); + raise(sig); + abort(); // Should not reach here +} + +void seh_initialize() { + if (g_seh_initialized.exchange(true)) { + return; // Already initialized + } + + struct sigaction sa; + sa.sa_sigaction = signal_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO | SA_NODEFER; // SA_NODEFER allows re-entry for nested exceptions + + sigaction(SIGSEGV, &sa, nullptr); + sigaction(SIGBUS, &sa, nullptr); + sigaction(SIGFPE, &sa, nullptr); + sigaction(SIGILL, &sa, nullptr); +} + +bool& seh_active() { + return tls_seh_active; +} + +} // namespace rex::platform diff --git a/src/core/seh_win.cpp b/src/core/seh_win.cpp new file mode 100644 index 0000000..9fc4763 --- /dev/null +++ b/src/core/seh_win.cpp @@ -0,0 +1,72 @@ +/** + * @file core/seh_win.cpp + * @brief Windows platform SEH implementations + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include +#include + +static_assert(REX_PLATFORM_WIN32, "This file is Windows-only"); + +#include "platform_win.h" + +namespace rex::platform { + +static thread_local SehThreadState tls_seh_state; +static thread_local bool tls_seh_active = false; + +SehThreadState& seh_thread_state() { + return tls_seh_state; +} + +int seh_filter(uint32_t code, void* ep) { + auto* pointers = static_cast(ep); + switch (code) { + case EXCEPTION_ACCESS_VIOLATION: + case EXCEPTION_IN_PAGE_ERROR: + case EXCEPTION_INT_DIVIDE_BY_ZERO: + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + case EXCEPTION_ILLEGAL_INSTRUCTION: + case EXCEPTION_STACK_OVERFLOW: + tls_seh_state.code = code; + if (pointers && pointers->ExceptionRecord) { + tls_seh_state.info[0] = pointers->ExceptionRecord->ExceptionInformation[0]; + tls_seh_state.info[1] = pointers->ExceptionRecord->ExceptionInformation[1]; + } + return EXCEPTION_EXECUTE_HANDLER; + default: + return EXCEPTION_CONTINUE_SEARCH; + } +} + +[[noreturn]] void seh_rethrow() { + uint32_t code = tls_seh_state.code; + ULONG_PTR info[2] = {tls_seh_state.info[0], tls_seh_state.info[1]}; + + // For access violations, include the extra info (read/write flag and address) + if (code == EXCEPTION_ACCESS_VIOLATION || code == EXCEPTION_IN_PAGE_ERROR) { + RaiseException(code, EXCEPTION_NONCONTINUABLE, 2, info); + } else { + RaiseException(code, EXCEPTION_NONCONTINUABLE, 0, nullptr); + } + // RaiseException doesn't return, but compiler may not know that +#ifdef __clang__ + __builtin_unreachable(); +#else + __assume(false); +#endif +} + +void seh_initialize() { + // Native SEH needs no signal handler setup, but mark as initialized + g_seh_initialized.store(true, std::memory_order_relaxed); +} + +bool& seh_active() { + return tls_seh_active; +} + +} // namespace rex::platform diff --git a/src/core/sha256.cpp b/src/core/sha256.cpp new file mode 100644 index 0000000..f7eeb95 --- /dev/null +++ b/src/core/sha256.cpp @@ -0,0 +1,32 @@ +/** + * SHA256 hashing utilities implementation + * + * Uses picosha2 header-only library for SHA256 computation. + */ + +#include "thirdparty/picosha2/picosha2.h" + +#include +#include + +#include + +namespace rex::crypto { + +std::string sha256(std::string_view data) { + std::string hash_hex; + picosha2::hash256_hex_string(data.begin(), data.end(), hash_hex); + return hash_hex; +} + +std::string sha256_file(const std::filesystem::path& path) { + std::ifstream file(path, std::ios::binary); + if (!file) { + return ""; + } + std::ostringstream ss; + ss << file.rdbuf(); + return sha256(ss.str()); +} + +} // namespace rex::crypto diff --git a/src/core/socket_posix.cpp b/src/core/socket_posix.cpp new file mode 100644 index 0000000..b4b885a --- /dev/null +++ b/src/core/socket_posix.cpp @@ -0,0 +1,19 @@ +#include +#include + +static_assert(REX_PLATFORM_LINUX || REX_PLATFORM_MAC, "This file is POSIX-only"); + +#include +#include + +namespace rex::net { + +int socket_close(SocketHandle handle) { + return close(static_cast(handle)); +} + +int socket_ioctl(SocketHandle handle, uint32_t cmd, uint8_t* arg) { + return ioctl(static_cast(handle), cmd, arg); +} + +} // namespace rex::net diff --git a/src/core/socket_win.cpp b/src/core/socket_win.cpp new file mode 100644 index 0000000..87f1960 --- /dev/null +++ b/src/core/socket_win.cpp @@ -0,0 +1,20 @@ +#include +#include + +static_assert(REX_PLATFORM_WIN32, "This file is Windows-only"); + +#include "platform_win.h" + +#include + +namespace rex::net { + +int socket_close(SocketHandle handle) { + return closesocket(static_cast(handle)); +} + +int socket_ioctl(SocketHandle handle, uint32_t cmd, uint8_t* arg) { + return ioctlsocket(static_cast(handle), cmd, reinterpret_cast(arg)); +} + +} // namespace rex::net diff --git a/src/core/string.cpp b/src/core/string.cpp new file mode 100644 index 0000000..2d72504 --- /dev/null +++ b/src/core/string.cpp @@ -0,0 +1,56 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified 2026 Tom Clay + * Modified for rexglue - Xbox 360 recompilation framework + * + * @changes - Moved functions from rex:: to rex::string:: namespace + * - Renamed xe_* functions to cleaner names + */ + +#include + +#include +#include + +#include + +#define UTF_CPP_CPLUSPLUS 201703L +#include + +namespace utfcpp = utf8; + +namespace rex::string { + +std::string to_utf8(const std::u16string_view source) { + return utfcpp::utf16to8(source); +} + +std::u16string to_utf16(const std::string_view source) { + return utfcpp::utf8to16(source); +} + +std::string_view trim_left(std::string_view sv, std::string_view chars) { + auto start = sv.find_first_not_of(chars); + return start == std::string_view::npos ? std::string_view{} : sv.substr(start); +} + +std::string_view trim_right(std::string_view sv, std::string_view chars) { + auto end = sv.find_last_not_of(chars); + return end == std::string_view::npos ? std::string_view{} : sv.substr(0, end + 1); +} + +std::string_view trim(std::string_view sv, std::string_view chars) { + return trim_right(trim_left(sv, chars), chars); +} + +std::string trim_string(std::string_view sv, std::string_view chars) { + return std::string(trim(sv, chars)); +} + +} // namespace rex::string diff --git a/src/core/string_buffer.cpp b/src/core/string_buffer.cpp new file mode 100644 index 0000000..8f8fd63 --- /dev/null +++ b/src/core/string_buffer.cpp @@ -0,0 +1,106 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include + +namespace rex::string { + +using namespace rex::literals; + +StringBuffer::StringBuffer(size_t initial_capacity) { + buffer_capacity_ = std::max(initial_capacity, static_cast(16_KiB)); + buffer_ = reinterpret_cast(std::malloc(buffer_capacity_)); + assert_not_null(buffer_); + buffer_[0] = 0; +} + +StringBuffer::~StringBuffer() { + free(buffer_); + buffer_ = nullptr; +} + +void StringBuffer::Reset() { + buffer_offset_ = 0; + buffer_[0] = 0; +} + +void StringBuffer::Grow(size_t additional_length) { + if (buffer_offset_ + additional_length <= buffer_capacity_) { + return; + } + size_t old_capacity = buffer_capacity_; + size_t new_capacity = + std::max(rex::round_up(buffer_offset_ + additional_length, 16_KiB), old_capacity * 2); + auto new_buffer = std::realloc(buffer_, new_capacity); + assert_not_null(new_buffer); + buffer_ = reinterpret_cast(new_buffer); + buffer_capacity_ = new_capacity; +} + +void StringBuffer::Append(char c) { + AppendBytes(reinterpret_cast(&c), 1); +} + +void StringBuffer::Append(char c, size_t count) { + Grow(count + 1); + std::memset(buffer_ + buffer_offset_, c, count); + buffer_offset_ += count; + buffer_[buffer_offset_] = 0; +} + +void StringBuffer::Append(const char* value) { + AppendBytes(reinterpret_cast(value), std::strlen(value)); +} + +void StringBuffer::Append(const std::string_view value) { + AppendBytes(reinterpret_cast(value.data()), value.size()); +} + +void StringBuffer::AppendVarargs(const char* format, va_list args) { + int result = vsnprintf(nullptr, 0, format, args); + if (result <= 0) { + return; + } + auto length = static_cast(result); + Grow(length + 1); + vsnprintf(buffer_ + buffer_offset_, buffer_capacity_, format, args); + buffer_offset_ += length; + buffer_[buffer_offset_] = 0; +} + +void StringBuffer::AppendBytes(const uint8_t* buffer, size_t length) { + Grow(length + 1); + memcpy(buffer_ + buffer_offset_, buffer, length); + buffer_offset_ += length; + buffer_[buffer_offset_] = 0; +} + +std::string StringBuffer::to_string() { + return std::string(buffer_, buffer_offset_); +} + +std::string_view StringBuffer::to_string_view() const { + return std::string_view(buffer_, buffer_offset_); +} + +std::vector StringBuffer::to_bytes() const { + std::vector bytes(buffer_offset_); + std::memcpy(bytes.data(), buffer_, buffer_offset_); + return bytes; +} + +} // namespace rex::string diff --git a/src/core/string_posix.cpp b/src/core/string_posix.cpp new file mode 100644 index 0000000..5e59c28 --- /dev/null +++ b/src/core/string_posix.cpp @@ -0,0 +1,42 @@ +/** + * @file core/string_posix.cpp + * @brief POSIX platform string function implementations + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include +#include + +static_assert(REX_PLATFORM_LINUX || REX_PLATFORM_MAC, "This file is POSIX-only"); + +#include + +#include + +#include + +namespace rex::string { + +int compare_case(const char* string1, const char* string2) { + return strcasecmp(string1, string2); +} + +int compare_case_n(const char* string1, const char* string2, size_t count) { + return strncasecmp(string1, string2, count); +} + +char* duplicate(const char* source) { + return strdup(source); +} + +void rex_strcpy(char* dest, size_t dest_size, const char* src, size_t max_count) { + if (dest_size == 0) + return; + size_t copy_size = (max_count == 0) ? dest_size - 1 : std::min(max_count, dest_size - 1); + strncpy(dest, src, copy_size); + dest[copy_size] = '\0'; +} + +} // namespace rex::string diff --git a/src/core/string_win.cpp b/src/core/string_win.cpp new file mode 100644 index 0000000..2ec4cd3 --- /dev/null +++ b/src/core/string_win.cpp @@ -0,0 +1,37 @@ +/** + * @file core/string_win.cpp + * @brief Windows platform string function implementations + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include +#include + +static_assert(REX_PLATFORM_WIN32, "This file is Windows-only"); + +#include + +namespace rex::string { + +int compare_case(const char* string1, const char* string2) { + return _stricmp(string1, string2); +} + +int compare_case_n(const char* string1, const char* string2, size_t count) { + return _strnicmp(string1, string2, count); +} + +char* duplicate(const char* source) { + return _strdup(source); +} + +void rex_strcpy(char* dest, size_t dest_size, const char* src, size_t max_count) { + if (dest_size == 0) + return; + size_t count = (max_count == 0) ? _TRUNCATE : max_count; + strncpy_s(dest, dest_size, src, count); +} + +} // namespace rex::string diff --git a/src/core/system_posix.cpp b/src/core/system_posix.cpp new file mode 100644 index 0000000..1655695 --- /dev/null +++ b/src/core/system_posix.cpp @@ -0,0 +1,33 @@ +/** + * @file core/system_posix.cpp + * @brief POSIX implementations of rex/system.h platform helpers. + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include + +#include + +namespace rex { + +// TODO(tomc): add linux support for showing a native message box +void ShowSimpleMessageBox(SimpleMessageBoxType type, std::string_view message) { + const char* level = "INFO"; + switch (type) { + case SimpleMessageBoxType::Help: + level = "INFO"; + break; + case SimpleMessageBoxType::Warning: + level = "WARNING"; + break; + case SimpleMessageBoxType::Error: + level = "ERROR"; + break; + } + std::fprintf(stderr, "[%s] %.*s\n", level, static_cast(message.size()), message.data()); + std::fflush(stderr); +} + +} // namespace rex diff --git a/src/core/system_win.cpp b/src/core/system_win.cpp new file mode 100644 index 0000000..bb9e1cb --- /dev/null +++ b/src/core/system_win.cpp @@ -0,0 +1,37 @@ +/** + * @file core/system_win.cpp + * @brief Windows implementations of rex/system.h platform helpers. + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include + +#include +#include + +namespace rex { + +void ShowSimpleMessageBox(SimpleMessageBoxType type, std::string_view message) { + UINT flags = MB_OK | MB_TOPMOST | MB_SETFOREGROUND; + const wchar_t* title = L"ReXGlue"; + switch (type) { + case SimpleMessageBoxType::Help: + flags |= MB_ICONINFORMATION; + break; + case SimpleMessageBoxType::Warning: + flags |= MB_ICONWARNING; + break; + case SimpleMessageBoxType::Error: + flags |= MB_ICONERROR; + break; + } + auto wide = rex::string::to_utf16(message); + ::MessageBoxW(nullptr, reinterpret_cast(wide.c_str()), title, flags); +} + +} // namespace rex diff --git a/src/core/threading.cpp b/src/core/threading.cpp new file mode 100644 index 0000000..fd06c66 --- /dev/null +++ b/src/core/threading.cpp @@ -0,0 +1,40 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include + +namespace rex::thread { + +// ============================================================================= +// Common code +// ============================================================================= + +uint32_t logical_processor_count() { + static uint32_t value = 0; + if (!value) { + value = std::thread::hardware_concurrency(); + } + return value; +} + +thread_local uint32_t current_thread_id_ = UINT_MAX; + +uint32_t current_thread_id() { + return current_thread_id_ == UINT_MAX ? current_thread_system_id() : current_thread_id_; +} + +void set_current_thread_id(uint32_t id) { + current_thread_id_ = id; +} + +} // namespace rex::thread diff --git a/src/core/threading_posix.cpp b/src/core/threading_posix.cpp new file mode 100644 index 0000000..e10e30b --- /dev/null +++ b/src/core/threading_posix.cpp @@ -0,0 +1,1427 @@ +/** + * @file core/threading_posix.cpp + * @brief POSIX platform threading implementations + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include +#include + +static_assert(REX_PLATFORM_LINUX || REX_PLATFORM_MAC, "This file is POSIX-only"); + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#if REX_PLATFORM_ANDROID +#include + +#include +#include +#endif + +#if REX_PLATFORM_LINUX +// SIGEV_THREAD_ID in timer_create(...) is a Linux extension +#define REX_HAS_SIGEV_THREAD_ID 1 +#ifdef __GLIBC__ +#define sigev_notify_thread_id _sigev_un._tid +#endif +#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 30 +#define gettid() syscall(SYS_gettid) +#endif +#else +#define REX_HAS_SIGEV_THREAD_ID 0 +#endif + +namespace rex::thread { + +#if REX_PLATFORM_ANDROID +// May be null if no dynamically loaded functions are required. +static void* android_libc_; +// API 26+. +static int (*android_pthread_getname_np_)(pthread_t pthread, char* buf, size_t n); + +void AndroidInitialize() { + if (rex::GetAndroidApiLevel() >= 26) { + android_libc_ = dlopen("libc.so", RTLD_NOW); + assert_not_null(android_libc_); + if (android_libc_) { + android_pthread_getname_np_ = reinterpret_cast( + dlsym(android_libc_, "pthread_getname_np")); + assert_not_null(android_pthread_getname_np_); + } + } +} + +void AndroidShutdown() { + android_pthread_getname_np_ = nullptr; + if (android_libc_) { + dlclose(android_libc_); + android_libc_ = nullptr; + } +} +#endif + +template +inline timespec DurationToTimeSpec(std::chrono::duration<_Rep, _Period> duration) { + auto nanoseconds = std::chrono::duration_cast(duration); + auto div = ldiv(nanoseconds.count(), 1000000000L); + return timespec{div.quot, div.rem}; +} + +// Thread interruption is done using user-defined signals +// This implementation uses the SIGRTMAX - SIGRTMIN to signal to a thread +// gdb tip, for SIG = SIGRTMIN + SignalType : handle SIG nostop +// lldb tip, for SIG = SIGRTMIN + SignalType : process handle SIG -s false +enum class SignalType { + kThreadSuspend, + kThreadUserCallback, +#if REX_PLATFORM_ANDROID + // pthread_cancel is not available on Android, using a signal handler for + // simplified PTHREAD_CANCEL_ASYNCHRONOUS-like behavior - not disabling + // cancellation currently, so should be enough. + kThreadTerminate, +#endif + k_Count +}; + +int GetSystemSignal(SignalType num) { + auto result = SIGRTMIN + static_cast(num); + assert_true(result < SIGRTMAX); + return result; +} + +SignalType GetSystemSignalType(int num) { + return static_cast(num - SIGRTMIN); +} + +std::array, static_cast(SignalType::k_Count)> signal_handler_installed = + {}; + +static void signal_handler(int signal, siginfo_t* info, void* context); + +void install_signal_handler(SignalType type) { + bool expected = false; + if (!signal_handler_installed[static_cast(type)].compare_exchange_strong(expected, + true)) { + return; + } + struct sigaction action{}; + action.sa_flags = SA_SIGINFO | SA_RESTART; + action.sa_sigaction = signal_handler; + sigemptyset(&action.sa_mask); + if (sigaction(GetSystemSignal(type), &action, nullptr) != 0) { + signal_handler_installed[static_cast(type)] = false; + } +} + +// TODO(dougvj) +void EnableAffinityConfiguration() {} + +// uint64_t ticks() { return mach_absolute_time(); } + +uint32_t current_thread_system_id() { + return static_cast(syscall(SYS_gettid)); +} + +void MaybeYield() { + sched_yield(); + __sync_synchronize(); +} + +void SyncMemory() { + __sync_synchronize(); +} + +void Sleep(std::chrono::microseconds duration) { + timespec rqtp = DurationToTimeSpec(duration); + timespec rmtp = {}; + auto p_rqtp = &rqtp; + auto p_rmtp = &rmtp; + int ret = 0; + do { + ret = nanosleep(p_rqtp, p_rmtp); + // Swap requested for remaining in case of signal interruption + // in which case, we start sleeping again for the remainder + std::swap(p_rqtp, p_rmtp); + } while (ret == -1 && errno == EINTR); +} + +// TODO(bwrsandman) Implement by allowing alert interrupts from IO operations +thread_local bool alertable_state_ = false; +bool DispatchCurrentThreadUserCallback(); +SleepResult AlertableSleep(std::chrono::microseconds duration) { + alertable_state_ = true; + auto deadline = std::chrono::steady_clock::now() + duration; + while (true) { + if (DispatchCurrentThreadUserCallback()) { + alertable_state_ = false; + return SleepResult::kAlerted; + } + auto now = std::chrono::steady_clock::now(); + if (now >= deadline) { + alertable_state_ = false; + return SleepResult::kSuccess; + } + auto remaining = std::chrono::duration_cast(deadline - now); + Sleep(std::min(remaining, std::chrono::microseconds(1000))); + } +} + +TlsHandle AllocateTlsHandle() { + auto key = static_cast(-1); + auto res = pthread_key_create(&key, nullptr); + assert_zero(res); + assert_true(key != static_cast(-1)); + return static_cast(key); +} + +bool FreeTlsHandle(TlsHandle handle) { + return pthread_key_delete(static_cast(handle)) == 0; +} + +uintptr_t GetTlsValue(TlsHandle handle) { + return reinterpret_cast(pthread_getspecific(static_cast(handle))); +} + +bool SetTlsValue(TlsHandle handle, uintptr_t value) { + return pthread_setspecific(static_cast(handle), reinterpret_cast(value)) == + 0; +} + +class PosixConditionBase { + public: + PosixConditionBase() { +#if REX_PLATFORM_LINUX + // Use robust mutexes so waits can recover if owner thread terminates. + pthread_mutexattr_t attr; + if (pthread_mutexattr_init(&attr) == 0) { + if (pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST) == 0) { + auto native_mutex = static_cast(mutex_.native_handle()); + pthread_mutex_destroy(native_mutex); + pthread_mutex_init(native_mutex, &attr); + } + pthread_mutexattr_destroy(&attr); + } +#endif + } + + virtual ~PosixConditionBase() = default; + virtual bool Signal() = 0; + + WaitResult Wait(std::chrono::milliseconds timeout) { + bool executed; + auto predicate = [this] { return this->signaled(); }; +#if REX_PLATFORM_LINUX + auto native_mutex = static_cast(mutex_.native_handle()); + int lock_result = pthread_mutex_lock(native_mutex); + if (lock_result == EOWNERDEAD) { + pthread_mutex_consistent(native_mutex); + } else if (lock_result != 0) { + return WaitResult::kFailed; + } + std::unique_lock lock(mutex_, std::adopt_lock); +#else + std::unique_lock lock(mutex_); +#endif + if (predicate()) { + executed = true; + } else { + if (timeout == std::chrono::milliseconds::max()) { + cond_.wait(lock, predicate); + executed = true; // Did not time out; + } else { + executed = cond_.wait_for(lock, timeout, predicate); + } + } + if (executed) { + post_execution(); + return WaitResult::kSuccess; + } else { + return WaitResult::kTimeout; + } + } + + static std::pair WaitMultiple(std::vector&& handles, + bool wait_all, + std::chrono::milliseconds timeout) { + assert_true(!handles.empty()); + + if (handles.size() == 1) { + auto result = handles[0]->Wait(timeout); + return std::make_pair(result, 0); + } + + auto start_time = std::chrono::steady_clock::now(); + auto end_time = (timeout == std::chrono::milliseconds::max()) + ? std::chrono::steady_clock::time_point::max() + : start_time + timeout; + + while (true) { + size_t first_signaled = std::numeric_limits::max(); + bool condition_met = false; + bool all_locked = true; + + std::vector> locks; + locks.reserve(handles.size()); + + for (size_t i = 0; i < handles.size(); ++i) { +#if REX_PLATFORM_LINUX + auto native_mutex = static_cast(handles[i]->mutex_.native_handle()); + int result = pthread_mutex_trylock(native_mutex); + if (result == 0 || result == EOWNERDEAD) { + if (result == EOWNERDEAD) { + pthread_mutex_consistent(native_mutex); + } + locks.emplace_back(handles[i]->mutex_, std::adopt_lock); + } else { + all_locked = false; + break; + } +#else + locks.emplace_back(handles[i]->mutex_, std::try_to_lock); + if (!locks.back().owns_lock()) { + all_locked = false; + break; + } +#endif + } + + if (!all_locked) { + locks.clear(); + std::this_thread::yield(); + continue; + } + + if (wait_all) { + bool all_signaled = true; + for (size_t i = 0; i < handles.size(); ++i) { + if (!handles[i]->signaled()) { + all_signaled = false; + break; + } + if (first_signaled == std::numeric_limits::max()) { + first_signaled = i; + } + } + condition_met = all_signaled; + } else { + for (size_t i = 0; i < handles.size(); ++i) { + if (handles[i]->signaled()) { + first_signaled = i; + condition_met = true; + break; + } + } + } + + if (condition_met) { + if (wait_all) { + for (size_t i = 0; i < handles.size(); ++i) { + handles[i]->post_execution(); + } + } else { + handles[first_signaled]->post_execution(); + } + return std::make_pair(WaitResult::kSuccess, first_signaled); + } + + locks.clear(); + + auto now = std::chrono::steady_clock::now(); + if (now >= end_time) { + return std::make_pair(WaitResult::kTimeout, 0); + } + + if (timeout == std::chrono::milliseconds::max()) { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } else { + auto remaining = std::chrono::duration_cast(end_time - now); + auto sleep_time = std::min(remaining, std::chrono::milliseconds(1)); + std::this_thread::sleep_for(sleep_time); + } + } + } + + virtual void* native_handle() const { + return const_cast(cond_).native_handle(); + } + + protected: + inline virtual bool signaled() const = 0; + inline virtual void post_execution() = 0; + std::condition_variable cond_; + std::mutex mutex_; +}; + +// There really is no native POSIX handle for a single wait/signal construct +// pthreads is at a lower level with more handles for such a mechanism. +// This simple wrapper class functions as our handle and uses conditional +// variables for waits and signals. +template +class PosixCondition {}; + +template <> +class PosixCondition : public PosixConditionBase { + public: + PosixCondition(bool manual_reset, bool initial_state) + : signal_(initial_state), manual_reset_(manual_reset) {} + virtual ~PosixCondition() = default; + + bool Signal() override { + auto lock = std::unique_lock(mutex_); + signal_ = true; + cond_.notify_all(); + return true; + } + + void Reset() { + auto lock = std::unique_lock(mutex_); + signal_ = false; + } + + private: + inline bool signaled() const override { return signal_; } + inline void post_execution() override { + if (!manual_reset_) { + signal_ = false; + } + } + bool signal_; + const bool manual_reset_; +}; + +template <> +class PosixCondition : public PosixConditionBase { + public: + PosixCondition(uint32_t initial_count, uint32_t maximum_count) + : count_(initial_count), maximum_count_(maximum_count) {} + + bool Signal() override { return Release(1, nullptr); } + + bool Release(uint32_t release_count, int* out_previous_count) { + auto lock = std::unique_lock(mutex_); + if (release_count > maximum_count_ - count_) { + return false; + } + if (out_previous_count) { + *out_previous_count = count_; + } + count_ += release_count; + cond_.notify_all(); + return true; + } + + private: + inline bool signaled() const override { return count_ > 0; } + inline void post_execution() override { + count_--; + cond_.notify_all(); + } + uint32_t count_; + const uint32_t maximum_count_; +}; + +template <> +class PosixCondition : public PosixConditionBase { + public: + explicit PosixCondition(bool initial_owner) : count_(0) { + if (initial_owner) { + count_ = 1; + owner_ = std::this_thread::get_id(); + } + } + + bool Signal() override { return Release(); } + + bool Release() { + if (owner_ == std::this_thread::get_id() && count_ > 0) { + auto lock = std::unique_lock(mutex_); + --count_; + // Free to be acquired by another thread + if (count_ == 0) { + cond_.notify_all(); + } + return true; + } + return false; + } + + void* native_handle() const override { return const_cast(mutex_).native_handle(); } + + private: + inline bool signaled() const override { + return count_ == 0 || owner_ == std::this_thread::get_id(); + } + inline void post_execution() override { + count_++; + owner_ = std::this_thread::get_id(); + } + uint32_t count_; + std::thread::id owner_; +}; + +template <> +class PosixCondition : public PosixConditionBase { + public: + explicit PosixCondition(bool manual_reset) + : callback_(nullptr), signal_(false), manual_reset_(manual_reset) {} + + virtual ~PosixCondition() { Cancel(); } + + bool Signal() override { + std::lock_guard lock(mutex_); + signal_ = true; + cond_.notify_all(); + return true; + } + + void SetOnce(std::chrono::steady_clock::time_point due_time, std::function opt_callback) { + Cancel(); + + std::lock_guard lock(mutex_); + + callback_ = std::move(opt_callback); + signal_ = false; + wait_item_ = QueueTimerOnce(&CompletionRoutine, this, due_time); + } + + void SetRepeating(std::chrono::steady_clock::time_point due_time, + std::chrono::milliseconds period, std::function opt_callback) { + Cancel(); + + std::lock_guard lock(mutex_); + + callback_ = std::move(opt_callback); + signal_ = false; + wait_item_ = QueueTimerRecurring(&CompletionRoutine, this, due_time, period); + } + + void Cancel() { + if (auto wait_item = wait_item_.lock()) { + wait_item->Disarm(); + } + } + + void* native_handle() const override { + assert_always(); + return nullptr; + } + + private: + static void CompletionRoutine(void* userdata) { + assert_not_null(userdata); + auto timer = reinterpret_cast*>(userdata); + timer->Signal(); + // As the callback may reset the timer, store local. + std::function callback; + { + std::lock_guard lock(timer->mutex_); + callback = timer->callback_; + } + if (callback) { + callback(); + } + } + + private: + inline bool signaled() const override { return signal_; } + inline void post_execution() override { + if (!manual_reset_) { + signal_ = false; + } + } + std::weak_ptr wait_item_; + std::function callback_; + bool signal_; // Protected by mutex_ + const bool manual_reset_; +}; + +struct ThreadStartData { + std::function start_routine; + bool create_suspended; + Thread* thread_obj; +}; + +template <> +class PosixCondition : public PosixConditionBase { + enum class State { + kUninitialized, + kRunning, + kSuspended, + kFinished, + }; + + public: + PosixCondition() + : thread_(0), + signaled_(false), + exit_code_(0), + state_(State::kUninitialized), + suspend_count_(0) { + sem_init(&suspend_sem_, 0, 0); +#if REX_PLATFORM_ANDROID + android_pre_api_26_name_[0] = '\0'; +#endif + } + bool Initialize(Thread::CreationParameters params, ThreadStartData* start_data) { + start_data->create_suspended = params.create_suspended; + pthread_attr_t attr; + if (pthread_attr_init(&attr) != 0) + return false; + if (pthread_attr_setstacksize(&attr, params.stack_size) != 0) { + pthread_attr_destroy(&attr); + return false; + } + if (params.initial_priority != 0) { + sched_param sched{}; + sched.sched_priority = params.initial_priority + 1; + if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO) != 0) { + pthread_attr_destroy(&attr); + return false; + } + if (pthread_attr_setschedparam(&attr, &sched) != 0) { + pthread_attr_destroy(&attr); + return false; + } + } + if (pthread_create(&thread_, &attr, ThreadStartRoutine, start_data) != 0) { + pthread_attr_destroy(&attr); + return false; + } + pthread_attr_destroy(&attr); + return true; + } + + /// Constructor for existing thread. This should only happen once called by + /// Thread::GetCurrentThread() on the main thread + explicit PosixCondition(pthread_t thread) + : thread_(thread), + signaled_(false), + exit_code_(0), + state_(State::kRunning), + suspend_count_(0) { + sem_init(&suspend_sem_, 0, 0); +#if REX_PLATFORM_ANDROID + android_pre_api_26_name_[0] = '\0'; +#endif + } + + virtual ~PosixCondition() { + // Match Canary/Edge behavior. + // Force-cancel/join from the condition destructor can self-join/crash + // depending on shutdown ordering, so threads must be stopped explicitly. + } + + bool Signal() override { return true; } + + std::string name() const { + WaitStarted(); + auto result = std::array{'\0'}; + std::unique_lock lock(state_mutex_); + if (state_ != State::kUninitialized && state_ != State::kFinished) { +#if REX_PLATFORM_ANDROID + // pthread_getname_np was added in API 26 - below that, store the name in + // this object, which may be only modified through Xenia threading, but + // should be enough in most cases. + if (android_pthread_getname_np_) { + if (android_pthread_getname_np_(thread_, result.data(), result.size() - 1) != 0) { + assert_always(); + } + } else { + std::lock_guard lock(android_pre_api_26_name_mutex_); + std::strcpy(result.data(), android_pre_api_26_name_); + } +#else + if (pthread_getname_np(thread_, result.data(), result.size() - 1) != 0) { + assert_always(); + } +#endif + } + return std::string(result.data()); + } + + void set_name(const std::string& name) { + WaitStarted(); + std::unique_lock lock(state_mutex_); + if (state_ != State::kUninitialized && state_ != State::kFinished) { + pthread_setname_np(thread_, std::string(name).c_str()); +#if REX_PLATFORM_ANDROID + SetAndroidPreApi26Name(name); +#endif + } + } + +#if REX_PLATFORM_ANDROID + void SetAndroidPreApi26Name(const std::string_view name) { + if (android_pthread_getname_np_) { + return; + } + std::lock_guard lock(android_pre_api_26_name_mutex_); + rex::string::util_copy_truncating(android_pre_api_26_name_, name, + rex::countof(android_pre_api_26_name_)); + } +#endif + + uint32_t system_id() const { return static_cast(thread_); } + + uint64_t affinity_mask() { + WaitStarted(); + cpu_set_t cpu_set; +#if REX_PLATFORM_ANDROID + if (sched_getaffinity(pthread_gettid_np(thread_), sizeof(cpu_set_t), &cpu_set) != 0) { + assert_always(); + } +#else + if (pthread_getaffinity_np(thread_, sizeof(cpu_set_t), &cpu_set) != 0) { + assert_always(); + } +#endif + uint64_t result = 0; + auto cpu_count = std::min(CPU_SETSIZE, 64); + for (auto i = 0u; i < cpu_count; i++) { + auto set = CPU_ISSET(i, &cpu_set); + result |= set << i; + } + return result; + } + + void set_affinity_mask(uint64_t mask) { + WaitStarted(); + cpu_set_t cpu_set; + CPU_ZERO(&cpu_set); + for (auto i = 0u; i < 64; i++) { + if (mask & (1ULL << i)) { + CPU_SET(i, &cpu_set); + } + } +#if REX_PLATFORM_ANDROID + if (sched_setaffinity(pthread_gettid_np(thread_), sizeof(cpu_set_t), &cpu_set) != 0) { + assert_always(); + } +#else + if (pthread_setaffinity_np(thread_, sizeof(cpu_set_t), &cpu_set) != 0) { + assert_always(); + } +#endif + } + + int priority() { + WaitStarted(); + int policy; + sched_param param{}; + int ret = pthread_getschedparam(thread_, &policy, ¶m); + if (ret != 0) { + return -1; + } + + return param.sched_priority; + } + + void set_priority(int new_priority) { + WaitStarted(); + sched_param param{}; + param.sched_priority = new_priority; + int result = pthread_setschedparam(thread_, SCHED_FIFO, ¶m); + if (result != 0) { + switch (result) { + case EPERM: + REXSYS_WARN("set_priority: permission denied"); + break; + case EINVAL: + assert_always(); + break; + default: + REXSYS_WARN("set_priority: pthread_setschedparam failed ({})", result); + break; + } + } + } + + void QueueUserCallback(std::function callback) { + WaitStarted(); + { + std::unique_lock lock(callback_mutex_); + user_callbacks_.push_back(std::move(callback)); + has_pending_user_callbacks_.store(true, std::memory_order_release); + } + + // If the callback is queued on the current thread, don't self-signal. + // Alertable waits drain this queue in normal thread context. + if (pthread_equal(thread_, pthread_self())) { + if (alertable_state_) { + DispatchQueuedUserCallbacks(); + } + return; + } + + sigval value{}; + value.sival_ptr = this; +#if REX_PLATFORM_ANDROID + int result = sigqueue(pthread_gettid_np(thread_), + GetSystemSignal(SignalType::kThreadUserCallback), value); +#else + int result = pthread_sigqueue(thread_, GetSystemSignal(SignalType::kThreadUserCallback), value); +#endif + if (result != 0) { + REXSYS_WARN("QueueUserCallback: signal delivery failed ({})", result); + } + } + + bool DispatchQueuedUserCallbacks() { + if (!has_pending_user_callbacks_.load(std::memory_order_acquire)) { + return false; + } + + std::function callback; + { + std::unique_lock lock(callback_mutex_); + if (user_callbacks_.empty()) { + has_pending_user_callbacks_.store(false, std::memory_order_release); + return false; + } + callback = std::move(user_callbacks_.front()); + user_callbacks_.pop_front(); + has_pending_user_callbacks_.store(!user_callbacks_.empty(), std::memory_order_release); + } + if (callback) { + callback(); + } + return true; + } + + bool Resume(uint32_t* out_previous_suspend_count = nullptr) { + if (out_previous_suspend_count) { + *out_previous_suspend_count = 0; + } + WaitStarted(); + std::unique_lock lock(state_mutex_); + if (suspend_count_ == 0) { + return false; + } + if (out_previous_suspend_count) { + *out_previous_suspend_count = suspend_count_; + } + --suspend_count_; + if (suspend_count_ == 0 && state_ == State::kSuspended) { + state_ = State::kRunning; + // Async-signal-safe wakeup for WaitSuspended() from signal handler path. + sem_post(&suspend_sem_); + } + state_signal_.notify_all(); + return true; + } + + bool Suspend(uint32_t* out_previous_suspend_count = nullptr) { + if (out_previous_suspend_count) { + *out_previous_suspend_count = 0; + } + WaitStarted(); + bool is_current_thread = pthread_self() == thread_; + { + std::unique_lock lock(state_mutex_); + if (out_previous_suspend_count) { + *out_previous_suspend_count = suspend_count_; + } + state_ = State::kSuspended; + ++suspend_count_; + } + + if (is_current_thread) { + WaitSuspended(); + return true; + } + + int result = pthread_kill(thread_, GetSystemSignal(SignalType::kThreadSuspend)); + return result == 0; + } + + void Terminate(int exit_code) { + bool is_current_thread = pthread_self() == thread_; + { + std::unique_lock lock(state_mutex_); + if (state_ == State::kFinished) { + if (is_current_thread) { + // This is really bad. Some thread must have called Terminate() on us + // just before we decided to terminate ourselves + assert_always(); + for (;;) { + // Wait for pthread_cancel() to actually happen. + } + } + return; + } + state_ = State::kFinished; + } + + { + std::lock_guard lock(mutex_); + + exit_code_ = exit_code; + signaled_ = true; + cond_.notify_all(); + } + if (is_current_thread) { + pthread_exit(reinterpret_cast(exit_code)); + } else { +#if REX_PLATFORM_ANDROID + if (pthread_kill(thread_, GetSystemSignal(SignalType::kThreadTerminate)) != 0) { + assert_always(); + } +#else + if (pthread_cancel(thread_) != 0) { + assert_always(); + } +#endif + } + } + + void WaitStarted() const { + std::unique_lock lock(state_mutex_); + state_signal_.wait(lock, [this] { return state_ != State::kUninitialized; }); + } + + /// Uses sem_wait because it may be called from signal handler context. + void WaitSuspended() { + int ret; + do { + ret = sem_wait(&suspend_sem_); + } while (ret == -1 && errno == EINTR); + } + + void* native_handle() const override { return reinterpret_cast(thread_); } + + private: + static void* ThreadStartRoutine(void* parameter); + inline bool signaled() const override { return signaled_; } + inline void post_execution() override { + if (thread_) { + pthread_join(thread_, nullptr); + } + sem_destroy(&suspend_sem_); + } + pthread_t thread_; + bool signaled_; + int exit_code_; + State state_; // Protected by state_mutex_ + uint32_t suspend_count_; // Protected by state_mutex_ + sem_t suspend_sem_; + mutable std::mutex state_mutex_; + mutable std::mutex callback_mutex_; + mutable std::condition_variable state_signal_; + std::deque> user_callbacks_; + std::atomic has_pending_user_callbacks_{false}; +#if REX_PLATFORM_ANDROID + // Name accessible via name() on Android before API 26 which added + // pthread_getname_np. + mutable std::mutex android_pre_api_26_name_mutex_; + char android_pre_api_26_name_[16]; +#endif +}; + +class PosixWaitHandle { + public: + virtual ~PosixWaitHandle(); + virtual PosixConditionBase& condition() = 0; +}; + +PosixWaitHandle::~PosixWaitHandle() = default; + +thread_local PosixCondition* current_thread_condition_ = nullptr; + +bool DispatchCurrentThreadUserCallback() { + if (!current_thread_condition_) { + Thread::GetCurrentThread(); + } + return current_thread_condition_ && current_thread_condition_->DispatchQueuedUserCallbacks(); +} + +namespace { + +constexpr auto kAlertablePollSlice = std::chrono::milliseconds(1); + +class ScopedAlertableState { + public: + explicit ScopedAlertableState(bool alertable) : alertable_(alertable) { + if (alertable_) { + alertable_state_ = true; + } + } + ~ScopedAlertableState() { + if (alertable_) { + alertable_state_ = false; + } + } + + private: + bool alertable_; +}; + +std::chrono::steady_clock::time_point ComputeAlertableDeadline(std::chrono::milliseconds timeout) { + if (timeout == std::chrono::milliseconds::max()) { + return std::chrono::steady_clock::time_point::max(); + } + return std::chrono::steady_clock::now() + timeout; +} + +bool HasAlertableTimeoutElapsed(std::chrono::steady_clock::time_point deadline) { + return deadline != std::chrono::steady_clock::time_point::max() && + std::chrono::steady_clock::now() >= deadline; +} + +std::chrono::milliseconds ComputeAlertableWaitTimeout( + std::chrono::steady_clock::time_point deadline) { + if (deadline == std::chrono::steady_clock::time_point::max()) { + return kAlertablePollSlice; + } + auto remaining = std::chrono::duration_cast( + deadline - std::chrono::steady_clock::now()); + if (remaining <= std::chrono::milliseconds::zero()) { + return std::chrono::milliseconds::zero(); + } + return std::min(remaining, kAlertablePollSlice); +} + +} // namespace + +// This wraps a condition object as our handle because posix has no single +// native handle for higher level concurrency constructs such as semaphores +template +class PosixConditionHandle : public T, public PosixWaitHandle { + public: + PosixConditionHandle() = default; + explicit PosixConditionHandle(bool); + explicit PosixConditionHandle(pthread_t thread); + PosixConditionHandle(bool manual_reset, bool initial_state); + PosixConditionHandle(uint32_t initial_count, uint32_t maximum_count); + ~PosixConditionHandle() override = default; + + PosixCondition& condition() override { return handle_; } + void* native_handle() const override { return handle_.native_handle(); } + + protected: + PosixCondition handle_; + friend PosixCondition; +}; + +template <> +PosixConditionHandle::PosixConditionHandle(uint32_t initial_count, + uint32_t maximum_count) + : handle_(initial_count, maximum_count) {} + +template <> +PosixConditionHandle::PosixConditionHandle(bool initial_owner) : handle_(initial_owner) {} + +template <> +PosixConditionHandle::PosixConditionHandle(bool manual_reset) : handle_(manual_reset) {} + +template <> +PosixConditionHandle::PosixConditionHandle(bool manual_reset, bool initial_state) + : handle_(manual_reset, initial_state) {} + +template <> +PosixConditionHandle::PosixConditionHandle(pthread_t thread) : handle_(thread) {} + +WaitResult Wait(WaitHandle* wait_handle, bool is_alertable, std::chrono::milliseconds timeout) { + auto posix_wait_handle = dynamic_cast(wait_handle); + if (posix_wait_handle == nullptr) { + return WaitResult::kFailed; + } + if (!is_alertable) { + return posix_wait_handle->condition().Wait(timeout); + } + + ScopedAlertableState alertable_state_guard(true); + auto deadline = ComputeAlertableDeadline(timeout); + + while (true) { + if (DispatchCurrentThreadUserCallback()) { + return WaitResult::kUserCallback; + } + if (HasAlertableTimeoutElapsed(deadline)) { + return WaitResult::kTimeout; + } + auto result = posix_wait_handle->condition().Wait(ComputeAlertableWaitTimeout(deadline)); + if (result != WaitResult::kTimeout) { + return result; + } + } +} + +WaitResult SignalAndWait(WaitHandle* wait_handle_to_signal, WaitHandle* wait_handle_to_wait_on, + bool is_alertable, std::chrono::milliseconds timeout) { + auto result = WaitResult::kFailed; + auto posix_wait_handle_to_signal = dynamic_cast(wait_handle_to_signal); + auto posix_wait_handle_to_wait_on = dynamic_cast(wait_handle_to_wait_on); + if (posix_wait_handle_to_signal == nullptr || posix_wait_handle_to_wait_on == nullptr) { + return WaitResult::kFailed; + } + if (!posix_wait_handle_to_signal->condition().Signal()) { + return WaitResult::kFailed; + } + + if (!is_alertable) { + return posix_wait_handle_to_wait_on->condition().Wait(timeout); + } + + ScopedAlertableState alertable_state_guard(true); + auto deadline = ComputeAlertableDeadline(timeout); + while (true) { + if (DispatchCurrentThreadUserCallback()) { + return WaitResult::kUserCallback; + } + if (HasAlertableTimeoutElapsed(deadline)) { + return WaitResult::kTimeout; + } + result = posix_wait_handle_to_wait_on->condition().Wait(ComputeAlertableWaitTimeout(deadline)); + if (result != WaitResult::kTimeout) { + return result; + } + } +} + +std::pair WaitMultiple(WaitHandle* wait_handles[], size_t wait_handle_count, + bool wait_all, bool is_alertable, + std::chrono::milliseconds timeout) { + std::vector conditions; + conditions.reserve(wait_handle_count); + for (size_t i = 0u; i < wait_handle_count; ++i) { + auto handle = dynamic_cast(wait_handles[i]); + if (handle == nullptr) { + return std::make_pair(WaitResult::kFailed, 0); + } + conditions.push_back(&handle->condition()); + } + if (!is_alertable) { + return PosixConditionBase::WaitMultiple(std::move(conditions), wait_all, timeout); + } + + ScopedAlertableState alertable_state_guard(true); + auto deadline = ComputeAlertableDeadline(timeout); + while (true) { + if (DispatchCurrentThreadUserCallback()) { + return std::make_pair(WaitResult::kUserCallback, 0); + } + if (HasAlertableTimeoutElapsed(deadline)) { + return std::make_pair(WaitResult::kTimeout, 0); + } + auto result = PosixConditionBase::WaitMultiple(std::vector(conditions), + wait_all, ComputeAlertableWaitTimeout(deadline)); + if (result.first != WaitResult::kTimeout) { + return result; + } + } +} + +class PosixEvent : public PosixConditionHandle { + public: + PosixEvent(bool manual_reset, bool initial_state) + : PosixConditionHandle(manual_reset, initial_state) {} + ~PosixEvent() override = default; + void Set() override { handle_.Signal(); } + void Reset() override { handle_.Reset(); } + void Pulse() override { + using namespace std::chrono_literals; + handle_.Signal(); + MaybeYield(); + Sleep(10us); + handle_.Reset(); + } +}; + +std::unique_ptr Event::CreateManualResetEvent(bool initial_state) { + return std::make_unique(true, initial_state); +} + +std::unique_ptr Event::CreateAutoResetEvent(bool initial_state) { + return std::make_unique(false, initial_state); +} + +class PosixSemaphore : public PosixConditionHandle { + public: + PosixSemaphore(int initial_count, int maximum_count) + : PosixConditionHandle(static_cast(initial_count), + static_cast(maximum_count)) {} + ~PosixSemaphore() override = default; + bool Release(int release_count, int* out_previous_count) override { + if (release_count < 1) { + return false; + } + return handle_.Release(static_cast(release_count), out_previous_count); + } +}; + +std::unique_ptr Semaphore::Create(int initial_count, int maximum_count) { + if (initial_count < 0 || initial_count > maximum_count || maximum_count <= 0) { + return nullptr; + } + return std::make_unique(initial_count, maximum_count); +} + +class PosixMutant : public PosixConditionHandle { + public: + explicit PosixMutant(bool initial_owner) : PosixConditionHandle(initial_owner) {} + ~PosixMutant() override = default; + bool Release() override { return handle_.Release(); } +}; + +std::unique_ptr Mutant::Create(bool initial_owner) { + return std::make_unique(initial_owner); +} + +class PosixTimer : public PosixConditionHandle { + using WClock_ = Timer::WClock_; + using GClock_ = Timer::GClock_; + + public: + explicit PosixTimer(bool manual_reset) : PosixConditionHandle(manual_reset) {} + ~PosixTimer() override = default; + + bool SetOnceAfter(rex::chrono::hundrednanoseconds rel_time, + std::function opt_callback = nullptr) override { + return SetOnceAt(GClock_::now() + rel_time, std::move(opt_callback)); + } + bool SetOnceAt(WClock_::time_point due_time, + std::function opt_callback = nullptr) override { + return SetOnceAt(std::chrono::clock_cast(due_time), std::move(opt_callback)); + }; + bool SetOnceAt(GClock_::time_point due_time, + std::function opt_callback = nullptr) override { + handle_.SetOnce(due_time, std::move(opt_callback)); + return true; + } + + bool SetRepeatingAfter(rex::chrono::hundrednanoseconds rel_time, std::chrono::milliseconds period, + std::function opt_callback = nullptr) override { + return SetRepeatingAt(GClock_::now() + rel_time, period, std::move(opt_callback)); + } + bool SetRepeatingAt(WClock_::time_point due_time, std::chrono::milliseconds period, + std::function opt_callback = nullptr) override { + return SetRepeatingAt(std::chrono::clock_cast(due_time), period, + std::move(opt_callback)); + } + bool SetRepeatingAt(GClock_::time_point due_time, std::chrono::milliseconds period, + std::function opt_callback = nullptr) override { + handle_.SetRepeating(due_time, period, std::move(opt_callback)); + return true; + } + bool Cancel() override { + handle_.Cancel(); + return true; + } +}; + +std::unique_ptr Timer::CreateManualResetTimer() { + return std::make_unique(true); +} + +std::unique_ptr Timer::CreateSynchronizationTimer() { + return std::make_unique(false); +} + +class PosixThread : public PosixConditionHandle { + public: + PosixThread() = default; + explicit PosixThread(pthread_t thread) : PosixConditionHandle(thread) {} + ~PosixThread() override = default; + + bool Initialize(CreationParameters params, std::function start_routine) { + auto start_data = new ThreadStartData({std::move(start_routine), false, this}); + return handle_.Initialize(params, start_data); + } + + void set_name(std::string name) override { + handle_.WaitStarted(); + Thread::set_name(name); + if (name.length() > 15) { + name = name.substr(0, 15); + } + handle_.set_name(name); + } + + uint32_t system_id() const override { return handle_.system_id(); } + + uint64_t affinity_mask() override { return handle_.affinity_mask(); } + void set_affinity_mask(uint64_t mask) override { handle_.set_affinity_mask(mask); } + + int priority() override { return handle_.priority(); } + void set_priority(int new_priority) override { handle_.set_priority(new_priority); } + + void QueueUserCallback(std::function callback) override { + handle_.QueueUserCallback(std::move(callback)); + } + + bool Resume(uint32_t* out_previous_suspend_count) override { + return handle_.Resume(out_previous_suspend_count); + } + + bool Suspend(uint32_t* out_previous_suspend_count) override { + return handle_.Suspend(out_previous_suspend_count); + } + + void Terminate(int exit_code) override { handle_.Terminate(exit_code); } + + void WaitSuspended() { handle_.WaitSuspended(); } +}; + +thread_local PosixThread* current_thread_ = nullptr; + +void* PosixCondition::ThreadStartRoutine(void* parameter) { +#if !REX_PLATFORM_ANDROID + if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, nullptr) != 0) { + assert_always(); + } +#endif + set_current_thread_name(""); + + auto start_data = static_cast(parameter); + assert_not_null(start_data); + assert_not_null(start_data->thread_obj); + + auto thread = dynamic_cast(start_data->thread_obj); + auto start_routine = std::move(start_data->start_routine); + auto create_suspended = start_data->create_suspended; + delete start_data; + + current_thread_ = thread; + current_thread_condition_ = &thread->handle_; + { + std::unique_lock lock(thread->handle_.state_mutex_); + thread->handle_.state_ = create_suspended ? State::kSuspended : State::kRunning; + thread->handle_.state_signal_.notify_all(); + } + + if (create_suspended) { + std::unique_lock lock(thread->handle_.state_mutex_); + thread->handle_.suspend_count_ = 1; + thread->handle_.state_signal_.wait(lock, + [thread] { return thread->handle_.suspend_count_ == 0; }); + } + + start_routine(); + + { + std::unique_lock lock(thread->handle_.state_mutex_); + thread->handle_.state_ = State::kFinished; + } + + { + std::unique_lock lock(thread->handle_.mutex_); + thread->handle_.exit_code_ = 0; + thread->handle_.signaled_ = true; + thread->handle_.cond_.notify_all(); + } + + current_thread_ = nullptr; + current_thread_condition_ = nullptr; + return nullptr; +} + +std::unique_ptr Thread::Create(CreationParameters params, + std::function start_routine) { + install_signal_handler(SignalType::kThreadSuspend); + install_signal_handler(SignalType::kThreadUserCallback); +#if REX_PLATFORM_ANDROID + install_signal_handler(SignalType::kThreadTerminate); +#endif + auto thread = std::make_unique(); + if (!thread->Initialize(params, std::move(start_routine))) + return nullptr; + assert_not_null(thread); + return thread; +} + +Thread* Thread::GetCurrentThread() { + if (current_thread_) { + return current_thread_; + } + + // Threads not created by Thread::Create (typically main thread) still need + // process-wide signal handlers used by suspend/APC machinery. + install_signal_handler(SignalType::kThreadSuspend); + install_signal_handler(SignalType::kThreadUserCallback); +#if REX_PLATFORM_ANDROID + install_signal_handler(SignalType::kThreadTerminate); +#endif + + // Should take this route only for threads not created by Thread::Create. + // The only thread not created by Thread::Create should be the main thread. + pthread_t handle = pthread_self(); + + current_thread_ = new PosixThread(handle); + current_thread_condition_ = ¤t_thread_->condition(); + // TODO(bwrsandman): Disabling deleting thread_local current thread to prevent + // assert in destructor. Since this is thread local, the + // "memory leaking" is controlled. + // atexit([] { delete current_thread_; }); + + return current_thread_; +} + +void Thread::Exit(int exit_code) { + if (current_thread_) { + current_thread_->Terminate(exit_code); + } else { + // Should only happen with the main thread + pthread_exit(reinterpret_cast(exit_code)); + } + // Function must not return + assert_always(); +} + +void set_current_thread_name(const std::string_view name) { + pthread_setname_np(pthread_self(), std::string(name).c_str()); +#if REX_PLATFORM_ANDROID + if (!android_pthread_getname_np_ && current_thread_) { + current_thread_->condition().SetAndroidPreApi26Name(name); + } +#endif +} + +static void signal_handler(int signal, siginfo_t* /*info*/, void* /*context*/) { + switch (GetSystemSignalType(signal)) { + case SignalType::kThreadSuspend: { + if (!current_thread_) { + return; + } + current_thread_->WaitSuspended(); + } break; + case SignalType::kThreadUserCallback: { + // Callbacks are drained from alertable waits in normal thread context. + // This signal is only used as a wakeup hint. + } break; +#if REX_PLATFORM_ANDROID + case SignalType::kThreadTerminate: { + pthread_exit(reinterpret_cast(-1)); + } break; +#endif + default: + assert_always(); + } +} + +} // namespace rex::thread diff --git a/src/core/threading_win.cpp b/src/core/threading_win.cpp new file mode 100644 index 0000000..896dfec --- /dev/null +++ b/src/core/threading_win.cpp @@ -0,0 +1,486 @@ +/** + * @file core/threading_win.cpp + * @brief Windows platform threading implementations + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include +#include + +static_assert(REX_PLATFORM_WIN32, "This file is Windows-only"); + +#include "platform_win.h" + +#include + +#include +#include + +#define LOG_LASTERROR() \ + { spdlog::error("Win32 Error 0x{:08X} in {}(...)", GetLastError(), __FUNCTION__); } + +typedef HANDLE (*SetThreadDescriptionFn)(HANDLE hThread, PCWSTR lpThreadDescription); + +namespace rex::thread { + +void EnableAffinityConfiguration() { + HANDLE process_handle = GetCurrentProcess(); + DWORD_PTR process_affinity_mask; + DWORD_PTR system_affinity_mask; + GetProcessAffinityMask(process_handle, &process_affinity_mask, &system_affinity_mask); + SetProcessAffinityMask(process_handle, system_affinity_mask); +} + +uint32_t current_thread_system_id() { + return static_cast(GetCurrentThreadId()); +} + +// https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx +#pragma pack(push, 8) +struct THREADNAME_INFO { + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. +}; +#pragma pack(pop) + +void raise_thread_name_exception(HANDLE thread, const std::string& name) { + if (!IsDebuggerPresent()) { + return; + } + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = name.c_str(); + info.dwThreadID = ::GetThreadId(thread); + info.dwFlags = 0; + __try { + RaiseException(0x406D1388, 0, sizeof(info) / sizeof(ULONG_PTR), + reinterpret_cast(&info)); + } __except (EXCEPTION_EXECUTE_HANDLER) { // NOLINT + } +} + +static void set_thread_name_impl(HANDLE thread, const std::string_view name) { + auto kernel = GetModuleHandleW(L"kernel32.dll"); + if (kernel) { + auto func = (SetThreadDescriptionFn)GetProcAddress(kernel, "SetThreadDescription"); + if (func) { + // Convert UTF-8 name to UTF-16 using Windows API + int size_needed = + MultiByteToWideChar(CP_UTF8, 0, name.data(), static_cast(name.size()), nullptr, 0); + std::wstring u16name(size_needed, 0); + MultiByteToWideChar(CP_UTF8, 0, name.data(), static_cast(name.size()), u16name.data(), + size_needed); + func(thread, u16name.c_str()); + } + } + raise_thread_name_exception(thread, std::string(name)); +} + +void set_current_thread_name(const std::string_view name) { + set_thread_name_impl(GetCurrentThread(), name); +} + +void MaybeYield() { + SwitchToThread(); + MemoryBarrier(); +} + +void SyncMemory() { + MemoryBarrier(); +} + +void Sleep(std::chrono::microseconds duration) { + if (duration.count() < 100) { + MaybeYield(); + } else { + ::Sleep(static_cast(duration.count() / 1000)); + } +} + +SleepResult AlertableSleep(std::chrono::microseconds duration) { + if (SleepEx(static_cast(duration.count() / 1000), TRUE) == WAIT_IO_COMPLETION) { + return SleepResult::kAlerted; + } + return SleepResult::kSuccess; +} + +TlsHandle AllocateTlsHandle() { + return TlsAlloc(); +} + +bool FreeTlsHandle(TlsHandle handle) { + return TlsFree(handle) ? true : false; +} + +uintptr_t GetTlsValue(TlsHandle handle) { + return reinterpret_cast(TlsGetValue(handle)); +} + +bool SetTlsValue(TlsHandle handle, uintptr_t value) { + return TlsSetValue(handle, reinterpret_cast(value)) ? true : false; +} + +template +class Win32Handle : public T { + public: + explicit Win32Handle(HANDLE handle) : handle_(handle) { assert_not_null(handle); } + ~Win32Handle() override { + CloseHandle(handle_); + handle_ = nullptr; + } + + protected: + void* native_handle() const override { return handle_; } + + HANDLE handle_ = nullptr; +}; + +WaitResult Wait(WaitHandle* wait_handle, bool is_alertable, std::chrono::milliseconds timeout) { + HANDLE handle = wait_handle->native_handle(); + DWORD result = WaitForSingleObjectEx(handle, DWORD(timeout.count()), is_alertable ? TRUE : FALSE); + switch (result) { + case WAIT_OBJECT_0: + return WaitResult::kSuccess; + case WAIT_ABANDONED: + return WaitResult::kAbandoned; + case WAIT_IO_COMPLETION: + return WaitResult::kUserCallback; + case WAIT_TIMEOUT: + return WaitResult::kTimeout; + default: + case WAIT_FAILED: + return WaitResult::kFailed; + } +} + +WaitResult SignalAndWait(WaitHandle* wait_handle_to_signal, WaitHandle* wait_handle_to_wait_on, + bool is_alertable, std::chrono::milliseconds timeout) { + HANDLE handle_to_signal = wait_handle_to_signal->native_handle(); + HANDLE handle_to_wait_on = wait_handle_to_wait_on->native_handle(); + DWORD result = SignalObjectAndWait(handle_to_signal, handle_to_wait_on, DWORD(timeout.count()), + is_alertable ? TRUE : FALSE); + switch (result) { + case WAIT_OBJECT_0: + return WaitResult::kSuccess; + case WAIT_ABANDONED: + return WaitResult::kAbandoned; + case WAIT_IO_COMPLETION: + return WaitResult::kUserCallback; + case WAIT_TIMEOUT: + return WaitResult::kTimeout; + default: + case WAIT_FAILED: + return WaitResult::kFailed; + } +} + +std::pair WaitMultiple(WaitHandle* wait_handles[], size_t wait_handle_count, + bool wait_all, bool is_alertable, + std::chrono::milliseconds timeout) { + std::vector handles(wait_handle_count); + for (size_t i = 0; i < wait_handle_count; ++i) { + handles[i] = wait_handles[i]->native_handle(); + } + DWORD result = + WaitForMultipleObjectsEx(DWORD(handles.size()), handles.data(), wait_all ? TRUE : FALSE, + DWORD(timeout.count()), is_alertable ? TRUE : FALSE); + if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + handles.size()) { + return std::pair(WaitResult::kSuccess, result - WAIT_OBJECT_0); + } else if (result >= WAIT_ABANDONED_0 && result < WAIT_ABANDONED_0 + handles.size()) { + return std::pair(WaitResult::kAbandoned, result - WAIT_ABANDONED_0); + } + switch (result) { + case WAIT_IO_COMPLETION: + return std::pair(WaitResult::kUserCallback, 0); + case WAIT_TIMEOUT: + return std::pair(WaitResult::kTimeout, 0); + default: + case WAIT_FAILED: + return std::pair(WaitResult::kFailed, 0); + } +} + +class Win32Event : public Win32Handle { + public: + explicit Win32Event(HANDLE handle) : Win32Handle(handle) {} + ~Win32Event() override = default; + void Set() override { SetEvent(handle_); } + void Reset() override { ResetEvent(handle_); } + void Pulse() override { PulseEvent(handle_); } +}; + +std::unique_ptr Event::CreateManualResetEvent(bool initial_state) { + HANDLE handle = CreateEvent(nullptr, TRUE, initial_state ? TRUE : FALSE, nullptr); + if (handle) { + return std::make_unique(handle); + } else { + LOG_LASTERROR(); + return nullptr; + } +} + +std::unique_ptr Event::CreateAutoResetEvent(bool initial_state) { + HANDLE handle = CreateEvent(nullptr, FALSE, initial_state ? TRUE : FALSE, nullptr); + if (handle) { + return std::make_unique(handle); + } else { + LOG_LASTERROR(); + return nullptr; + } +} + +class Win32Semaphore : public Win32Handle { + public: + explicit Win32Semaphore(HANDLE handle) : Win32Handle(handle) {} + ~Win32Semaphore() override = default; + bool Release(int release_count, int* out_previous_count) override { + return ReleaseSemaphore(handle_, release_count, reinterpret_cast(out_previous_count)) + ? true + : false; + } +}; + +std::unique_ptr Semaphore::Create(int initial_count, int maximum_count) { + HANDLE handle = CreateSemaphore(nullptr, initial_count, maximum_count, nullptr); + if (handle) { + return std::make_unique(handle); + } else { + LOG_LASTERROR(); + return nullptr; + } +} + +class Win32Mutant : public Win32Handle { + public: + explicit Win32Mutant(HANDLE handle) : Win32Handle(handle) {} + ~Win32Mutant() = default; + bool Release() override { return ReleaseMutex(handle_) ? true : false; } +}; + +std::unique_ptr Mutant::Create(bool initial_owner) { + HANDLE handle = CreateMutex(nullptr, initial_owner ? TRUE : FALSE, nullptr); + if (handle) { + return std::make_unique(handle); + } else { + LOG_LASTERROR(); + return nullptr; + } +} + +class Win32Timer : public Win32Handle { + using WClock_ = Timer::WClock_; + using GClock_ = Timer::GClock_; + + public: + explicit Win32Timer(HANDLE handle) : Win32Handle(handle) {} + ~Win32Timer() = default; + + bool SetOnceAfter(rex::chrono::hundrednanoseconds rel_time, + std::function opt_callback) override { + return SetOnceAt(WClock_::now() + rel_time, std::move(opt_callback)); + } + bool SetOnceAt(GClock_::time_point due_time, std::function opt_callback) override { + return SetOnceAt(std::chrono::clock_cast(due_time), std::move(opt_callback)); + } + bool SetOnceAt(WClock_::time_point due_time, std::function opt_callback) override { + std::lock_guard lock(mutex_); + callback_ = std::move(opt_callback); + LARGE_INTEGER due_time_li; + due_time_li.QuadPart = WClock_::to_file_time(due_time); + auto completion_routine = + callback_ ? reinterpret_cast(CompletionRoutine) : NULL; + return SetWaitableTimer(handle_, &due_time_li, 0, completion_routine, this, FALSE) ? true + : false; + } + + bool SetRepeatingAfter(rex::chrono::hundrednanoseconds rel_time, std::chrono::milliseconds period, + std::function opt_callback = nullptr) override { + return SetRepeatingAt(WClock_::now() + rel_time, period, std::move(opt_callback)); + } + bool SetRepeatingAt(GClock_::time_point due_time, std::chrono::milliseconds period, + std::function opt_callback = nullptr) { + return SetRepeatingAt(std::chrono::clock_cast(due_time), period, + std::move(opt_callback)); + } + bool SetRepeatingAt(WClock_::time_point due_time, std::chrono::milliseconds period, + std::function opt_callback) override { + std::lock_guard lock(mutex_); + callback_ = std::move(opt_callback); + LARGE_INTEGER due_time_li; + due_time_li.QuadPart = WClock_::to_file_time(due_time); + auto completion_routine = + callback_ ? reinterpret_cast(CompletionRoutine) : NULL; + return SetWaitableTimer(handle_, &due_time_li, int32_t(period.count()), completion_routine, + this, FALSE) + ? true + : false; + } + + bool Cancel() override { + // Reset the callback immediately so that any completions don't call it. + std::lock_guard lock(mutex_); + callback_ = nullptr; + return CancelWaitableTimer(handle_) ? true : false; + } + + private: + static void CompletionRoutine(Win32Timer* timer, DWORD timer_low, DWORD timer_high) { + // As the callback may reset the timer, store local. + std::function callback; + { + std::lock_guard lock(timer->mutex_); + callback = timer->callback_; + } + callback(); + } + + std::mutex mutex_; + std::function callback_; +}; + +std::unique_ptr Timer::CreateManualResetTimer() { + HANDLE handle = CreateWaitableTimer(NULL, TRUE, NULL); + if (handle) { + return std::make_unique(handle); + } else { + LOG_LASTERROR(); + return nullptr; + } +} + +std::unique_ptr Timer::CreateSynchronizationTimer() { + HANDLE handle = CreateWaitableTimer(NULL, FALSE, NULL); + if (handle) { + return std::make_unique(handle); + } else { + LOG_LASTERROR(); + return nullptr; + } +} + +class Win32Thread : public Win32Handle { + public: + explicit Win32Thread(HANDLE handle) : Win32Handle(handle) {} + ~Win32Thread() = default; + + void set_name(std::string name) override { + set_thread_name_impl(handle_, name); + Thread::set_name(name); + } + + int32_t priority() override { return GetThreadPriority(handle_); } + uint32_t system_id() const override { return GetThreadId(handle_); } + + void set_priority(int32_t new_priority) override { SetThreadPriority(handle_, new_priority); } + + uint64_t affinity_mask() override { + DWORD_PTR prev = SetThreadAffinityMask(handle_, 1); + if (prev) { + SetThreadAffinityMask(handle_, prev); + } + return static_cast(prev); + } + + void set_affinity_mask(uint64_t new_affinity_mask) override { + SetThreadAffinityMask(handle_, new_affinity_mask); + } + + struct ApcData { + std::function callback; + }; + static void NTAPI DispatchApc(ULONG_PTR parameter) { + auto apc_data = reinterpret_cast(parameter); + apc_data->callback(); + delete apc_data; + } + + void QueueUserCallback(std::function callback) override { + auto apc_data = new ApcData({std::move(callback)}); + QueueUserAPC(DispatchApc, handle_, reinterpret_cast(apc_data)); + } + + bool Resume(uint32_t* out_previous_suspend_count = nullptr) override { + if (out_previous_suspend_count) { + *out_previous_suspend_count = 0; + } + DWORD result = ResumeThread(handle_); + if (result == UINT_MAX) { + return false; + } + if (out_previous_suspend_count) { + *out_previous_suspend_count = result; + } + return true; + } + + bool Suspend(uint32_t* out_previous_suspend_count = nullptr) override { + if (out_previous_suspend_count) { + *out_previous_suspend_count = 0; + } + DWORD result = SuspendThread(handle_); + if (result == UINT_MAX) { + return false; + } + if (out_previous_suspend_count) { + *out_previous_suspend_count = result; + } + return true; + } + + void Terminate(int exit_code) override { TerminateThread(handle_, exit_code); } + + private: + void AssertCallingThread() { assert_true(GetCurrentThreadId() == GetThreadId(handle_)); } +}; + +thread_local std::unique_ptr current_thread_ = nullptr; + +struct ThreadStartData { + std::function start_routine; +}; +DWORD WINAPI ThreadStartRoutine(LPVOID parameter) { + current_thread_ = std::make_unique(::GetCurrentThread()); + + auto start_data = reinterpret_cast(parameter); + start_data->start_routine(); + delete start_data; + return 0; +} + +std::unique_ptr Thread::Create(CreationParameters params, + std::function start_routine) { + auto start_data = new ThreadStartData({std::move(start_routine)}); + HANDLE handle = CreateThread(NULL, params.stack_size, ThreadStartRoutine, start_data, + params.create_suspended ? CREATE_SUSPENDED : 0, NULL); + if (handle) { + return std::make_unique(handle); + } else { + LOG_LASTERROR(); + delete start_data; + return nullptr; + } +} + +Thread* Thread::GetCurrentThread() { + if (current_thread_) { + return current_thread_.get(); + } + + HANDLE handle = ::GetCurrentThread(); + if (handle == INVALID_HANDLE_VALUE) { + return nullptr; + } + + current_thread_ = std::make_unique(handle); + return current_thread_.get(); +} + +void Thread::Exit(int exit_code) { + ExitThread(exit_code); +} + +} // namespace rex::thread diff --git a/src/core/timer_queue.cpp b/src/core/timer_queue.cpp new file mode 100644 index 0000000..5cfea05 --- /dev/null +++ b/src/core/timer_queue.cpp @@ -0,0 +1,203 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +namespace dp = disruptorplus; + +namespace rex::thread { + +using WaitItem = TimerQueueWaitItem; + +class TimerQueue { + public: + using clock = WaitItem::clock; + static_assert(clock::is_steady); + + public: + TimerQueue() + : buffer_(kWaitCount), + wait_strategy_(), + claim_strategy_(kWaitCount, wait_strategy_), + consumed_(wait_strategy_) { + claim_strategy_.add_claim_barrier(consumed_); + dispatch_thread_ = + std::jthread([this](std::stop_token stop_token) { TimerThreadMain(stop_token); }); + } + + ~TimerQueue() { + dispatch_thread_.request_stop(); + + // Kick dispatch thread to check stop token + auto wait_item = std::make_shared(nullptr, nullptr, this, clock::time_point::min(), + clock::duration::zero()); + wait_item->Disarm(); + QueueTimer(std::move(wait_item)); + + // std::jthread auto-joins on destruction + } + + void TimerThreadMain(std::stop_token stop_token) { + dp::sequence_t next_sequence = 0; + const auto comp = [](const std::shared_ptr& left, + const std::shared_ptr& right) { + return left->due_ < right->due_; + }; + + set_current_thread_name("rex::thread::TimerQueue"); + + while (!stop_token.stop_requested()) { + { + // Consume new wait items and add them to sorted wait queue + dp::sequence_t available = claim_strategy_.wait_until_published( + next_sequence, next_sequence - 1, + wait_queue_.empty() ? clock::time_point::max() : wait_queue_.front()->due_); + + // Check for timeout + if (available != next_sequence - 1) { + std::forward_list> wait_items; + do { + wait_items.push_front(std::move(buffer_[next_sequence])); + } while (next_sequence++ != available); + + consumed_.publish(available); + + wait_items.sort(comp); + wait_queue_.merge(wait_items, comp); + } + } + + { + // Check wait queue, invoke callbacks and reschedule + std::forward_list> wait_items; + while (!wait_queue_.empty() && wait_queue_.front()->due_ <= clock::now()) { + auto wait_item = std::move(wait_queue_.front()); + wait_queue_.pop_front(); + + // Ensure that it isn't disarmed + auto state = WaitItem::State::kIdle; + if (wait_item->state_.compare_exchange_strong(state, WaitItem::State::kInCallback, + std::memory_order_acq_rel)) { + // Possibility to dispatch to a thread pool here + assert_not_null(wait_item->callback_); + wait_item->callback_(wait_item->userdata_); + + if (wait_item->interval_ != clock::duration::zero() && + wait_item->state_.load(std::memory_order_acquire) != + WaitItem::State::kInCallbackSelfDisarmed) { + // Item is recurring and didn't self-disarm during callback: + wait_item->due_ += wait_item->interval_; + wait_item->state_.store(WaitItem::State::kIdle, std::memory_order_release); + wait_item->state_.notify_all(); + wait_items.push_front(std::move(wait_item)); + } else { + wait_item->state_.store(WaitItem::State::kDisarmed, std::memory_order_release); + wait_item->state_.notify_all(); + } + } else { + // Specifically, kInCallback is illegal here + assert_true(WaitItem::State::kDisarmed == state); + } + } + wait_items.sort(comp); + wait_queue_.merge(wait_items, comp); + } + } + } + + std::weak_ptr QueueTimer(std::shared_ptr wait_item) { + auto wait_item_weak = std::weak_ptr(wait_item); + + // Mitigate callback flooding + wait_item->due_ = std::max(clock::now() - wait_item->interval_, wait_item->due_); + + auto sequence = claim_strategy_.claim_one(); + buffer_[sequence] = std::move(wait_item); + claim_strategy_.publish(sequence); + + return wait_item_weak; + } + + std::jthread::id dispatch_thread_id() const { return dispatch_thread_.get_id(); } + + private: + // This ring buffer will be used to introduce timers queued by the public API + static constexpr size_t kWaitCount = 512; + dp::ring_buffer> buffer_; + dp::spin_wait_strategy wait_strategy_; + dp::multi_threaded_claim_strategy claim_strategy_; + dp::sequence_barrier consumed_; + + // This is a _sorted_ (ascending due_) list of active timers managed by a + // dedicated thread + std::forward_list> wait_queue_; + std::jthread dispatch_thread_; +}; + +rex::thread::TimerQueue timer_queue_; + +void TimerQueueWaitItem::Disarm() { + State state; + + // Special case for calling from a callback itself + if (std::this_thread::get_id() == parent_queue_->dispatch_thread_id()) { + state = State::kInCallback; + if (state_.compare_exchange_strong(state, State::kInCallbackSelfDisarmed, + std::memory_order_acq_rel)) { + // If we are self disarming from the callback set this special state and + // exit + return; + } + // Normal case can handle the rest + } + + state = State::kIdle; + // Classes which hold WaitItems will often call Disarm() to cancel them during + // destruction. This may lead to race conditions when the dispatch thread + // executes a callback which accesses memory that is freed simultaneously due + // to this. Therefore, we need to guarantee that no callbacks will be running + // once Disarm() has returned. + while (!state_.compare_exchange_weak(state, State::kDisarmed, std::memory_order_acq_rel)) { + if (state == State::kDisarmed) { + break; + } + if (state == State::kInCallback || state == State::kInCallbackSelfDisarmed) { + // Wait for callback to complete - dispatch thread will notify + state_.wait(state, std::memory_order_acquire); + } + state = State::kIdle; + } +} + +std::weak_ptr QueueTimerOnce(std::function callback, void* userdata, + WaitItem::clock::time_point due) { + return timer_queue_.QueueTimer(std::make_shared( + std::move(callback), userdata, &timer_queue_, due, WaitItem::clock::duration::zero())); +} + +std::weak_ptr QueueTimerRecurring(std::function callback, void* userdata, + WaitItem::clock::time_point due, + WaitItem::clock::duration interval) { + return timer_queue_.QueueTimer( + std::make_shared(std::move(callback), userdata, &timer_queue_, due, interval)); +} + +} // namespace rex::thread diff --git a/src/core/utf8.cpp b/src/core/utf8.cpp new file mode 100644 index 0000000..a97702e --- /dev/null +++ b/src/core/utf8.cpp @@ -0,0 +1,704 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +#include + +#define UTF_CPP_CPLUSPLUS 201703L +#include + +namespace utfcpp = utf8; + +using citer = std::string_view::const_iterator; +using utf8_citer = utfcpp::iterator; + +namespace rex::string { + +std::string to_string(char32_t c) { + std::string result; + utfcpp::append(c, result); + return result; +} + +uint32_t lower_ascii(const uint32_t c) { + return c >= 'A' && c <= 'Z' ? c + 32 : c; +} + +uint32_t upper_ascii(const uint32_t c) { + return c >= 'A' && c <= 'Z' ? c + 32 : c; +} + +bool equal_ascii_case(const uint32_t l, const uint32_t r) { + return l == r || lower_ascii(l) == lower_ascii(r); +} + +std::pair make_citer(const std::string_view view) { + return {utf8_citer(view.cbegin(), view.cbegin(), view.cend()), + utf8_citer(view.cend(), view.cbegin(), view.cend())}; +} + +std::pair make_citer(const utf8_citer begin, const utf8_citer end) { + return {utf8_citer(begin.base(), begin.base(), end.base()), + utf8_citer(end.base(), begin.base(), end.base())}; +} + +size_t byte_length(utf8_citer begin, utf8_citer end) { + return size_t(std::distance(begin.base(), end.base())); +} + +size_t utf8_count(const std::string_view view) { + return size_t(utfcpp::distance(view.cbegin(), view.cend())); +} + +std::string utf8_lower_ascii(const std::string_view view) { + auto [begin, end] = make_citer(view); + std::string result; + for (auto it = begin; it != end; ++it) { + utfcpp::append(char32_t(lower_ascii(*it)), result); + } + return result; +} + +std::string utf8_upper_ascii(const std::string_view view) { + auto [begin, end] = make_citer(view); + std::string result; + for (auto it = begin; it != end; ++it) { + utfcpp::append(char32_t(upper_ascii(*it)), result); + } + return result; +} + +template +inline size_t hash_fnv1a(const std::string_view view) { + const size_t offset_basis = 0xCBF29CE484222325ull; + const size_t prime = 0x00000100000001B3ull; + auto work = [&prime](size_t hash, uint8_t byte_of_data) { + hash ^= byte_of_data; + hash *= prime; + return hash; + }; + auto hash = offset_basis; + auto [begin, end] = make_citer(view); + for (auto it = begin; it != end; ++it) { + uint32_t c; + if constexpr (LOWER) { + c = lower_ascii(*it); + } else { + c = *it; + } + hash = work(hash, uint8_t((c >> 0) & 0xFF)); + hash = work(hash, uint8_t((c >> 8) & 0xFF)); + hash = work(hash, uint8_t((c >> 16) & 0xFF)); + hash = work(hash, uint8_t((c >> 24) & 0xFF)); + } + return hash; +} + +size_t utf8_hash_fnv1a(const std::string_view view) { + return hash_fnv1a(view); +} + +size_t utf8_hash_fnv1a_case(const std::string_view view) { + return hash_fnv1a(view); +} + +// TODO(gibbed): this is a separate inline function instead of inline within +// split due to a Clang bug: reference to local binding 'needle_begin' declared +// in enclosing function 'split'. +inline utf8_citer find_needle(utf8_citer haystack_it, utf8_citer haystack_end, + utf8_citer needle_begin, utf8_citer needle_end) { + return std::find_if(haystack_it, haystack_end, [&](const auto& c) { + for (auto needle = needle_begin; needle != needle_end; ++needle) { + if (c == *needle) { + return true; + } + } + return false; + }); +} + +inline utf8_citer find_needle_case(utf8_citer haystack_it, utf8_citer haystack_end, + utf8_citer needle_begin, utf8_citer needle_end) { + return std::find_if(haystack_it, haystack_end, [&](const auto& c) { + for (auto needle = needle_begin; needle != needle_end; ++needle) { + if (equal_ascii_case(c, *needle)) { + return true; + } + } + return false; + }); +} + +std::vector utf8_split(const std::string_view haystack, + const std::string_view needles, bool remove_empty) { + std::vector result; + + auto [haystack_begin, haystack_end] = make_citer(haystack); + auto [needle_begin, needle_end] = make_citer(needles); + + auto it = haystack_begin; + auto last = it; + for (;;) { + it = find_needle(it, haystack_end, needle_begin, needle_end); + if (it == haystack_end) { + break; + } + + if (it != last) { + auto offset = byte_length(haystack_begin, last); + auto length = byte_length(haystack_begin, it) - offset; + result.push_back(haystack.substr(offset, length)); + } else if (!remove_empty) { + result.push_back(""); + } + + ++it; + last = it; + } + + if (last != haystack_end) { + auto offset = byte_length(haystack_begin, last); + result.push_back(haystack.substr(offset)); + } + + return result; +} + +bool utf8_equal_z(const std::string_view left, const std::string_view right) { + if (!left.size()) { + return !right.size(); + } else if (!right.size()) { + return false; + } + auto [left_begin, left_end] = make_citer(left); + auto [right_begin, right_end] = make_citer(right); + auto left_it = left_begin; + auto right_it = right_begin; + for (; left_it != left_end && *left_it != 0 && right_it != right_end && *right_it != 0; + ++left_it, ++right_it) { + if (*left_it != *right_it) { + return false; + } + } + return (left_it == left_end || *left_it == 0) && (right_it == right_end || *right_it == 0); +} + +bool utf8_equal_case(const std::string_view left, const std::string_view right) { + if (!left.size()) { + return !right.size(); + } else if (!right.size()) { + return false; + } + auto [left_begin, left_end] = make_citer(left); + auto [right_begin, right_end] = make_citer(right); + return std::equal(left_begin, left_end, right_begin, right_end, equal_ascii_case); +} + +bool utf8_equal_case_z(const std::string_view left, const std::string_view right) { + if (!left.size()) { + return !right.size(); + } else if (!right.size()) { + return false; + } + auto [left_begin, left_end] = make_citer(left); + auto [right_begin, right_end] = make_citer(right); + auto left_it = left_begin; + auto right_it = right_begin; + for (; left_it != left_end && *left_it != 0 && right_it != right_end && *right_it != 0; + ++left_it, ++right_it) { + if (!equal_ascii_case(*left_it, *right_it)) { + return false; + } + } + return (left_it == left_end || *left_it == 0) && (right_it == right_end || *right_it == 0); +} + +std::string_view::size_type utf8_find_any_of(const std::string_view haystack, + const std::string_view needles) { + if (needles.empty()) { + return std::string_view::size_type(0); + } else if (haystack.empty()) { + return std::string_view::npos; + } + + auto [haystack_begin, haystack_end] = make_citer(haystack); + auto [needle_begin, needle_end] = make_citer(needles); + + auto it = find_needle(haystack_begin, haystack_end, needle_begin, needle_end); + if (it == haystack_end) { + return std::string_view::npos; + } + + return std::string_view::size_type(byte_length(haystack_begin, it)); +} + +std::string_view::size_type utf8_find_any_of_case(const std::string_view haystack, + const std::string_view needles) { + if (needles.empty()) { + return std::string_view::size_type(0); + } else if (haystack.empty()) { + return std::string_view::npos; + } + + auto [haystack_begin, haystack_end] = make_citer(haystack); + auto [needle_begin, needle_end] = make_citer(needles); + + auto it = find_needle_case(haystack_begin, haystack_end, needle_begin, needle_end); + if (it == haystack_end) { + return std::string_view::npos; + } + + return std::string_view::size_type(byte_length(haystack_begin, it)); +} + +std::string_view::size_type utf8_find_first_of(const std::string_view haystack, + const std::string_view needle) { + if (needle.empty()) { + return std::string_view::size_type(0); + } else if (haystack.empty()) { + return std::string_view::npos; + } + + auto [haystack_begin, haystack_end] = make_citer(haystack); + auto [needle_begin, needle_end] = make_citer(needle); + auto needle_count = utf8_count(needle); + + auto it = haystack_begin; + for (; it != haystack_end; ++it) { + it = std::find(it, haystack_end, *needle_begin); + if (it == haystack_end) { + return std::string_view::npos; + } + + auto end = it; + for (size_t i = 0; i < needle_count; ++i) { + if (end == haystack_end) { + // not enough room in target for search + return std::string_view::npos; + } + ++end; + } + + auto [sub_start, sub_end] = make_citer(it, end); + if (std::equal(needle_begin, needle_end, sub_start, sub_end)) { + return std::string_view::size_type(byte_length(haystack_begin, it)); + } + } + + return std::string_view::npos; +} + +std::string_view::size_type utf8_find_first_of_case(const std::string_view haystack, + const std::string_view needle) { + if (needle.empty()) { + return std::string_view::size_type(0); + } else if (haystack.empty()) { + return std::string_view::npos; + } + + auto [haystack_begin, haystack_end] = make_citer(haystack); + auto [needle_begin, needle_end] = make_citer(needle); + auto needle_count = utf8_count(needle); + auto nc = *needle_begin; + + auto it = haystack_begin; + for (; it != haystack_end; ++it) { + it = std::find_if(it, haystack_end, + [&nc](const uint32_t& c) { return equal_ascii_case(nc, c); }); + if (it == haystack_end) { + return std::string_view::npos; + } + + auto end = it; + for (size_t i = 0; i < needle_count; ++i) { + if (end == haystack_end) { + // not enough room in target for search + return std::string_view::npos; + } + ++end; + } + + auto [sub_start, sub_end] = make_citer(it, end); + if (std::equal(needle_begin, needle_end, sub_start, sub_end, equal_ascii_case)) { + return std::string_view::size_type(byte_length(haystack_begin, it)); + } + } + + return std::string_view::npos; +} + +bool utf8_starts_with(const std::string_view haystack, char32_t needle) { + if (haystack.empty()) { + return false; + } + auto [it, end] = make_citer(haystack); + return *it == uint32_t(needle); +} + +bool utf8_starts_with(const std::string_view haystack, const std::string_view needle) { + if (needle.empty()) { + return true; + } else if (haystack.empty()) { + return false; + } + + auto [haystack_begin, haystack_end] = make_citer(haystack); + auto [needle_begin, needle_end] = make_citer(needle); + auto needle_count = utf8_count(needle); + + auto it = haystack_begin; + auto end = it; + for (size_t i = 0; i < needle_count; ++i) { + if (end == haystack_end) { + // not enough room in target for search + return false; + } + ++end; + } + + auto [sub_start, sub_end] = make_citer(it, end); + return std::equal(needle_begin, needle_end, sub_start, sub_end); +} + +bool utf8_starts_with_case(const std::string_view haystack, const std::string_view needle) { + if (needle.empty()) { + return true; + } else if (haystack.empty()) { + return false; + } + + auto [haystack_begin, haystack_end] = make_citer(haystack); + auto [needle_begin, needle_end] = make_citer(needle); + auto needle_count = utf8_count(needle); + + auto it = haystack_begin; + auto end = it; + for (size_t i = 0; i < needle_count; ++i) { + if (end == haystack_end) { + // not enough room in target for search + return false; + } + ++end; + } + + auto [sub_start, sub_end] = make_citer(it, end); + return std::equal(needle_begin, needle_end, sub_start, sub_end, equal_ascii_case); +} + +bool utf8_ends_with(const std::string_view haystack, const std::string_view needle) { + if (needle.empty()) { + return true; + } else if (haystack.empty()) { + return false; + } + + auto [haystack_begin, haystack_end] = make_citer(haystack); + auto [needle_begin, needle_end] = make_citer(needle); + auto needle_count = utf8_count(needle); + + auto it = haystack_end; + auto end = it; + --it; + + for (size_t i = 1; i < needle_count; ++i) { + if (it == haystack_begin) { + // not enough room in target for search + return false; + } + --it; + } + + auto [sub_start, sub_end] = make_citer(it, end); + return std::equal(needle_begin, needle_end, sub_start, sub_end); +} + +bool utf8_ends_with_case(const std::string_view haystack, const std::string_view needle) { + if (needle.empty()) { + return true; + } else if (haystack.empty()) { + return false; + } + + auto [haystack_begin, haystack_end] = make_citer(haystack); + auto [needle_begin, needle_end] = make_citer(needle); + auto needle_count = utf8_count(needle); + + auto it = haystack_end; + auto end = it; + --it; + + for (size_t i = 0; i < needle_count; ++i) { + if (it == haystack_begin) { + // not enough room in target for search + return false; + } + --it; + } + + auto [sub_start, sub_end] = make_citer(it, end); + return std::equal(needle_begin, needle_end, sub_start, sub_end, equal_ascii_case); +} + +std::vector utf8_split_path(const std::string_view path) { + return utf8_split(path, "\\/", true); +} + +std::string utf8_join_paths(const std::string_view left_path, const std::string_view right_path, + char32_t separator) { + if (!left_path.length()) { + return std::string(right_path); + } else if (!right_path.length()) { + return std::string(left_path); + } + + utf8_citer it; + std::tie(std::ignore, it) = make_citer(left_path); + --it; + + std::string result = std::string(left_path); + if (*it != static_cast(separator)) { + utfcpp::append(separator, result); + } + return result + std::string(right_path); +} + +std::string utf8_join_paths(const std::vector& paths, char32_t separator) { + std::string result; + auto it = paths.cbegin(); + if (it != paths.cend()) { + result = *it++; + for (; it != paths.cend(); ++it) { + result = utf8_join_paths(result, *it, separator); + } + } + return result; +} + +std::string utf8_join_paths(const std::vector& paths, char32_t separator) { + std::string result; + auto it = paths.cbegin(); + if (it != paths.cend()) { + result = *it++; + for (; it != paths.cend(); ++it) { + result = utf8_join_paths(result, *it, separator); + } + } + return result; +} + +std::string utf8_fix_path_separators(const std::string_view path, char32_t new_separator) { + if (path.empty()) { + return std::string(); + } + + // Swap all separators to new_sep. + const char32_t old_separator = new_separator == U'\\' ? U'/' : U'\\'; + + auto [path_begin, path_end] = make_citer(path); + + std::string result; + auto it = path_begin; + auto last = it; + + auto is_separator = [old_separator, new_separator](char32_t c) { + return c == uint32_t(old_separator) || c == uint32_t(new_separator); + }; + + // Begins with a separator + if (is_separator(*it)) { + utfcpp::append(new_separator, result); + ++it; + last = it; + } + + for (;;) { + it = std::find_if(it, path_end, is_separator); + if (it == path_end) { + break; + } + + if (it != last) { + auto offset = byte_length(path_begin, last); + auto length = byte_length(path_begin, it) - offset; + result += path.substr(offset, length); + utfcpp::append(new_separator, result); + } + + ++it; + last = it; + } + + if (last == path_begin) { + return std::string(path); + } + + if (last != path_end) { + auto offset = byte_length(path_begin, last); + result += path.substr(offset); + } + + return result; +} + +std::string utf8_find_name_from_path(const std::string_view path, char32_t separator) { + if (path.empty()) { + return std::string(); + } + + auto [begin, end] = make_citer(path); + + auto it = end; + --it; + + // skip trailing separators at the end of the path + while (*it == uint32_t(separator)) { + if (it == begin) { + // path is all separators, name is empty + return std::string(); + } + --it; + } + + // update end so it is before any trailing separators + end = std::next(it); + + // skip non-separators + while (*it != uint32_t(separator)) { + if (it == begin) { + break; + } + --it; + } + + // if the iterator is on a separator, advance + if (*it == uint32_t(separator)) { + ++it; + } + + auto offset = byte_length(begin, it); + auto length = byte_length(it, end); + return std::string(path.substr(offset, length)); +} + +std::string utf8_find_base_name_from_path(const std::string_view path, char32_t separator) { + auto name = utf8_find_name_from_path(path, separator); + if (!name.length()) { + return std::string(); + } + + auto [begin, end] = make_citer(name); + + auto it = end; + --it; + + while (it != begin) { + if (*it == uint32_t('.')) { + break; + } + --it; + } + + if (it == begin) { + return name; + } + + auto length = byte_length(it, end); + auto offset = name.length() - length; + return std::string(name.substr(0, offset)); +} + +std::string utf8_find_base_path(const std::string_view path, char32_t separator) { + if (path.empty()) { + return std::string(); + } + + auto [begin, end] = make_citer(path); + + auto it = end; + --it; + + // skip trailing separators at the end of the path + while (*it == uint32_t(separator)) { + if (it == begin) { + return std::string(); + } + --it; + } + + // skip non-separators + while (*it != uint32_t(separator)) { + if (it == begin) { + // there are no separators, base path is empty + return std::string(); + } + --it; + } + + // Save position of the separator we just found + auto sep_pos = it; + + // skip trailing separators at the end of the base path + while (*it == uint32_t(separator)) { + if (it == begin) { + // base path is all separators, base path is empty + return std::string(); + } + --it; + } + + // If we stopped at a colon (drive letter like "D:"), include the root separator + // This ensures "D:\file.txt" returns "D:\" not "D:" + if (*it == uint32_t(':')) { + auto length = byte_length(begin, std::next(sep_pos)); + return std::string(path.substr(0, length)); + } + + auto length = byte_length(begin, std::next(it)); + return std::string(path.substr(0, length)); +} + +std::string utf8_canonicalize_path(const std::string_view path, char32_t separator) { + if (path.empty()) { + return std::string(); + } + + auto is_rooted = utf8_starts_with(path, separator); + + auto parts = utf8_split_path(path); + for (auto it = parts.begin(); it != parts.end();) { + const auto& part = *it; + if (part == ".") { + // Potential marker for current directory. + it = parts.erase(it); + } else if (part == "..") { + // Ensure we don't override the device name. + if (it != parts.begin()) { + auto prev = std::prev(it); + if (!utf8_ends_with(*prev, ":")) { + it = parts.erase(prev); + } + } + it = parts.erase(it); + } else { + ++it; + } + } + + return !is_rooted ? utf8_join_paths(parts, separator) + : to_string(separator) + utf8_join_paths(parts, separator); +} + +} // namespace rex::string diff --git a/src/core/vec128.cpp b/src/core/vec128.cpp new file mode 100644 index 0000000..ac3b955 --- /dev/null +++ b/src/core/vec128.cpp @@ -0,0 +1,33 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include + +#include + +namespace rex { + +std::string to_string(const vec128_t& value) { + return fmt::format("({}, {}, {}, {})", value.x, value.y, value.z, value.w); +} + +std::ostream& operator<<(std::ostream& os, const vec128_t& value) { + // Inline hex format to avoid string_util dependency + os << fmt::format("[{:08X} {:08X} {:08X} {:08X}]", value.u32[0], value.u32[1], value.u32[2], + value.u32[3]); + return os; +} + +} // namespace rex diff --git a/src/filesystem/CMakeLists.txt b/src/filesystem/CMakeLists.txt new file mode 100644 index 0000000..11dd251 --- /dev/null +++ b/src/filesystem/CMakeLists.txt @@ -0,0 +1,25 @@ +add_library(rexfilesystem OBJECT + device.cpp + entry.cpp + virtual_file_system.cpp + devices/disc_image_device.cpp + devices/disc_image_entry.cpp + devices/disc_image_file.cpp + devices/host_path_device.cpp + devices/host_path_entry.cpp + devices/host_path_file.cpp + devices/null_device.cpp + devices/null_entry.cpp + devices/null_file.cpp + devices/stfs_container_device.cpp + devices/stfs_container_entry.cpp + devices/stfs_container_file.cpp +) +add_library(rex::filesystem ALIAS rexfilesystem) + +target_link_libraries(rexfilesystem PUBLIC rexcore) +target_include_directories(rexfilesystem PUBLIC + $ + $ +) +target_include_directories(rexfilesystem PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/devices) diff --git a/src/filesystem/device.cpp b/src/filesystem/device.cpp new file mode 100644 index 0000000..98ed5eb --- /dev/null +++ b/src/filesystem/device.cpp @@ -0,0 +1,20 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +namespace rex::filesystem { + +Device::Device(const std::string_view mount_path) : mount_path_(mount_path) {} +Device::~Device() = default; + +} // namespace rex::filesystem diff --git a/src/filesystem/devices/disc_image_device.cpp b/src/filesystem/devices/disc_image_device.cpp new file mode 100644 index 0000000..225f0ac --- /dev/null +++ b/src/filesystem/devices/disc_image_device.cpp @@ -0,0 +1,193 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include + +namespace rex::filesystem { + +using namespace rex::literals; + +const size_t kXESectorSize = 2_KiB; + +DiscImageDevice::DiscImageDevice(const std::string_view mount_path, + const std::filesystem::path& host_path) + : Device(mount_path), name_("GDFX"), host_path_(host_path) {} + +DiscImageDevice::~DiscImageDevice() = default; + +bool DiscImageDevice::Initialize() { + mmap_ = memory::MappedMemory::Open(host_path_, memory::MappedMemory::Mode::kRead); + if (!mmap_) { + REXFS_ERROR("Disc image could not be mapped"); + return false; + } + + ParseState state = {}; + state.ptr = mmap_->data(); + state.size = mmap_->size(); + auto result = Verify(&state); + if (result != Error::kSuccess) { + REXFS_ERROR("Failed to verify disc image header: {}", static_cast(result)); + return false; + } + + result = ReadAllEntries(&state, state.ptr + state.root_offset); + if (result != Error::kSuccess) { + REXFS_ERROR("Failed to read all GDFX entries: {}", static_cast(result)); + return false; + } + + return true; +} + +void DiscImageDevice::Dump(string::StringBuffer* string_buffer) { + auto global_lock = global_critical_region_.Acquire(); + root_entry_->Dump(string_buffer, 0); +} + +Entry* DiscImageDevice::ResolvePath(const std::string_view path) { + // The filesystem will have stripped our prefix off already, so the path will + // be in the form: + // some\PATH.foo + REXFS_DEBUG("DiscImageDevice::ResolvePath({})", path); + return root_entry_->ResolvePath(path); +} + +DiscImageDevice::Error DiscImageDevice::Verify(ParseState* state) { + // Find sector 32 of the game partition - try at a few points. + static const size_t likely_offsets[] = { + 0x00000000, 0x0000FB20, 0x00020600, 0x02080000, 0x0FD90000, + }; + bool magic_found = false; + for (size_t n = 0; n < rex::countof(likely_offsets); n++) { + state->game_offset = likely_offsets[n]; + if (VerifyMagic(state, state->game_offset + (32 * kXESectorSize))) { + magic_found = true; + break; + } + } + if (!magic_found) { + // File doesn't have the magic values - likely not a real GDFX source. + return Error::kErrorFileMismatch; + } + + // Read sector 32 to get FS state. + if (state->size < state->game_offset + (32 * kXESectorSize)) { + return Error::kErrorReadError; + } + uint8_t* fs_ptr = state->ptr + state->game_offset + (32 * kXESectorSize); + state->root_sector = memory::load(fs_ptr + 20); + state->root_size = memory::load(fs_ptr + 24); + state->root_offset = state->game_offset + (state->root_sector * kXESectorSize); + if (state->root_size < 13 || state->root_size > 32_MiB) { + return Error::kErrorDamagedFile; + } + + disc_info_.game_offset = state->game_offset; + disc_info_.root_sector = state->root_sector; + disc_info_.root_size = state->root_size; + disc_info_.host_size = state->size; + + return Error::kSuccess; +} + +bool DiscImageDevice::VerifyMagic(ParseState* state, size_t offset) { + if (offset >= state->size) { + return false; + } + + // Simple check to see if the given offset contains the magic value. + return std::memcmp(state->ptr + offset, "MICROSOFT*XBOX*MEDIA", 20) == 0; +} + +DiscImageDevice::Error DiscImageDevice::ReadAllEntries(ParseState* state, + const uint8_t* root_buffer) { + auto root_entry = new DiscImageEntry(this, nullptr, "", mmap_.get()); + root_entry->attributes_ = kFileAttributeDirectory; + root_entry_ = std::unique_ptr(root_entry); + + if (!ReadEntry(state, root_buffer, 0, root_entry)) { + return Error::kErrorOutOfMemory; + } + + return Error::kSuccess; +} + +bool DiscImageDevice::ReadEntry(ParseState* state, const uint8_t* buffer, uint16_t entry_ordinal, + DiscImageEntry* parent) { + const uint8_t* p = buffer + (entry_ordinal * 4); + + uint16_t node_l = memory::load(p + 0); + uint16_t node_r = memory::load(p + 2); + size_t sector = memory::load(p + 4); + size_t length = memory::load(p + 8); + uint8_t attributes = memory::load(p + 12); + uint8_t name_length = memory::load(p + 13); + auto name_buffer = reinterpret_cast(p + 14); + + if (node_l && !ReadEntry(state, buffer, node_l, parent)) { + return false; + } + + auto name = std::string(name_buffer, name_length); + + auto entry = DiscImageEntry::Create(this, parent, name, mmap_.get()); + entry->attributes_ = attributes | kFileAttributeReadOnly; + entry->size_ = length; + entry->allocation_size_ = rex::round_up(length, bytes_per_sector()); + + // Set to January 1, 1970 (UTC) in 100-nanosecond intervals + entry->create_timestamp_ = 10000 * 11644473600000LL; + entry->access_timestamp_ = 10000 * 11644473600000LL; + entry->write_timestamp_ = 10000 * 11644473600000LL; + + if (attributes & kFileAttributeDirectory) { + // Folder. + entry->data_offset_ = 0; + entry->data_size_ = 0; + if (length) { + // Not a leaf - read in children. + if (state->size < state->game_offset + (sector * kXESectorSize)) { + // Out of bounds read. + return false; + } + // Read child list. + uint8_t* folder_ptr = state->ptr + state->game_offset + (sector * kXESectorSize); + if (!ReadEntry(state, folder_ptr, 0, entry.get())) { + return false; + } + } + } else { + // File. + entry->data_offset_ = state->game_offset + (sector * kXESectorSize); + entry->data_size_ = length; + ++file_count_; + total_file_size_ += length; + } + + // Add to parent. + parent->children_.emplace_back(std::move(entry)); + + // Read next file in the list. + if (node_r && !ReadEntry(state, buffer, node_r, parent)) { + return false; + } + + return true; +} + +} // namespace rex::filesystem diff --git a/src/filesystem/devices/disc_image_entry.cpp b/src/filesystem/devices/disc_image_entry.cpp new file mode 100644 index 0000000..1986c71 --- /dev/null +++ b/src/filesystem/devices/disc_image_entry.cpp @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include + +#include + +namespace rex::filesystem { + +DiscImageEntry::DiscImageEntry(Device* device, Entry* parent, const std::string_view path, + memory::MappedMemory* mmap) + : Entry(device, parent, path), mmap_(mmap), data_offset_(0), data_size_(0) {} + +DiscImageEntry::~DiscImageEntry() = default; + +std::unique_ptr DiscImageEntry::Create(Device* device, Entry* parent, + const std::string_view name, + memory::MappedMemory* mmap) { + auto path = rex::string::utf8_join_guest_paths(parent->path(), name); + auto entry = std::make_unique(device, parent, path, mmap); + return std::move(entry); +} + +X_STATUS DiscImageEntry::Open(uint32_t desired_access, File** out_file) { + *out_file = new DiscImageFile(desired_access, this); + return X_STATUS_SUCCESS; +} + +std::unique_ptr DiscImageEntry::OpenMapped(memory::MappedMemory::Mode mode, + size_t offset, size_t length) { + if (mode != memory::MappedMemory::Mode::kRead) { + // Only allow reads. + return nullptr; + } + + size_t real_offset = data_offset_ + offset; + size_t real_length = length ? std::min(length, data_size_) : data_size_; + return mmap_->Slice(real_offset, real_length); +} + +} // namespace rex::filesystem diff --git a/src/filesystem/devices/disc_image_file.cpp b/src/filesystem/devices/disc_image_file.cpp new file mode 100644 index 0000000..313c9af --- /dev/null +++ b/src/filesystem/devices/disc_image_file.cpp @@ -0,0 +1,40 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include + +namespace rex::filesystem { + +DiscImageFile::DiscImageFile(uint32_t file_access, DiscImageEntry* entry) + : File(file_access, entry), entry_(entry) {} + +DiscImageFile::~DiscImageFile() = default; + +void DiscImageFile::Destroy() { + delete this; +} + +X_STATUS DiscImageFile::ReadSync(std::span buffer, size_t byte_offset, + size_t* out_bytes_read) { + if (byte_offset >= entry_->size()) { + return X_STATUS_END_OF_FILE; + } + size_t real_offset = entry_->data_offset() + byte_offset; + size_t real_length = std::min(buffer.size(), entry_->data_size() - byte_offset); + std::memcpy(buffer.data(), entry_->mmap()->data() + real_offset, real_length); + *out_bytes_read = real_length; + return X_STATUS_SUCCESS; +} + +} // namespace rex::filesystem diff --git a/src/filesystem/devices/host_path_device.cpp b/src/filesystem/devices/host_path_device.cpp new file mode 100644 index 0000000..99397d5 --- /dev/null +++ b/src/filesystem/devices/host_path_device.cpp @@ -0,0 +1,109 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include + +#include +#include +#include +#include +#include + +namespace rex::filesystem { + +HostPathDevice::HostPathDevice(const std::string_view mount_path, + const std::filesystem::path& host_path, bool read_only) + : Device(mount_path), name_("STFS"), host_path_(host_path), read_only_(read_only) {} + +HostPathDevice::~HostPathDevice() = default; + +bool HostPathDevice::Initialize() { + if (!std::filesystem::exists(host_path_)) { + if (!read_only_) { + // Create the path. + std::filesystem::create_directories(host_path_); + } else { + REXFS_ERROR("Host path does not exist"); + return false; + } + } + + auto root_entry = new HostPathEntry(this, nullptr, "", host_path_); + root_entry->attributes_ = kFileAttributeDirectory; + root_entry_ = std::unique_ptr(root_entry); + PopulateEntry(root_entry); + + return true; +} + +void HostPathDevice::Dump(string::StringBuffer* string_buffer) { + auto global_lock = global_critical_region_.Acquire(); + root_entry_->Dump(string_buffer, 0); +} + +Entry* HostPathDevice::ResolvePath(const std::string_view path) { + // The filesystem will have stripped our prefix off already, so the path will + // be in the form: + // some\PATH.foo + auto* resolved = root_entry_->ResolvePath(path); + if (resolved) { + return resolved; + } + + // Fallback to a lazy case-insensitive host lookup when an entry is missing + // from the in-memory tree (for example because casing differs on Linux). + auto* current_entry = static_cast(root_entry_.get()); + for (const auto& part : rex::string::utf8_split_path(path)) { + if (part.empty()) { + continue; + } + + auto* child = current_entry->GetChild(part); + if (!child) { + auto child_infos = rex::filesystem::ListFiles(current_entry->host_path()); + auto match = std::find_if(child_infos.begin(), child_infos.end(), [&](const auto& info) { + return rex::string::utf8_equal_case(rex::path_to_utf8(info.name), part); + }); + if (match == child_infos.end()) { + return nullptr; + } + + auto new_child = HostPathEntry::Create(this, current_entry, + current_entry->host_path() / match->name, *match); + if (!new_child) { + return nullptr; + } + child = new_child; + current_entry->children_.push_back(std::unique_ptr(new_child)); + } + + current_entry = static_cast(child); + } + + return current_entry; +} + +void HostPathDevice::PopulateEntry(HostPathEntry* parent_entry) { + auto child_infos = rex::filesystem::ListFiles(parent_entry->host_path()); + for (auto& child_info : child_infos) { + auto child = HostPathEntry::Create(this, parent_entry, + parent_entry->host_path() / child_info.name, child_info); + parent_entry->children_.push_back(std::unique_ptr(child)); + + if (child_info.type == rex::filesystem::FileInfo::Type::kDirectory) { + PopulateEntry(child); + } + } +} + +} // namespace rex::filesystem diff --git a/src/filesystem/devices/host_path_entry.cpp b/src/filesystem/devices/host_path_entry.cpp new file mode 100644 index 0000000..56f5a97 --- /dev/null +++ b/src/filesystem/devices/host_path_entry.cpp @@ -0,0 +1,181 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace rex::filesystem { + +HostPathEntry::HostPathEntry(Device* device, Entry* parent, const std::string_view path, + const std::filesystem::path& host_path) + : Entry(device, parent, path), host_path_(host_path) {} + +HostPathEntry::~HostPathEntry() = default; + +HostPathEntry* HostPathEntry::Create(Device* device, Entry* parent, + const std::filesystem::path& full_path, + rex::filesystem::FileInfo file_info) { + auto path = rex::string::utf8_join_guest_paths(parent->path(), rex::path_to_utf8(file_info.name)); + auto entry = new HostPathEntry(device, parent, path, full_path); + + entry->create_timestamp_ = file_info.create_timestamp; + entry->access_timestamp_ = file_info.access_timestamp; + entry->write_timestamp_ = file_info.write_timestamp; + if (file_info.type == rex::filesystem::FileInfo::Type::kDirectory) { + entry->attributes_ = kFileAttributeDirectory; + } else { + entry->attributes_ = kFileAttributeNormal; + if (device->is_read_only()) { + entry->attributes_ |= kFileAttributeReadOnly; + } + entry->size_ = file_info.total_size; + entry->allocation_size_ = rex::round_up(file_info.total_size, device->bytes_per_sector()); + } + return entry; +} + +X_STATUS HostPathEntry::Open(uint32_t desired_access, File** out_file) { + if (is_read_only() && + (desired_access & (FileAccess::kFileWriteData | FileAccess::kFileAppendData))) { + REXFS_ERROR("Attempting to open file for write access on read-only device"); + return X_STATUS_ACCESS_DENIED; + } + auto file_handle = rex::filesystem::FileHandle::OpenExisting(host_path_, desired_access); + if (!file_handle) { + // TODO(benvanik): pick correct response. + return X_STATUS_NO_SUCH_FILE; + } + *out_file = new HostPathFile(desired_access, this, std::move(file_handle)); + return X_STATUS_SUCCESS; +} + +std::unique_ptr HostPathEntry::OpenMapped(memory::MappedMemory::Mode mode, + size_t offset, size_t length) { + return memory::MappedMemory::Open(host_path_, mode, offset, length); +} + +bool HostPathEntry::Truncate() { + if (is_read_only() || (attributes_ & kFileAttributeDirectory)) { + return false; + } + auto file = rex::filesystem::OpenFile(host_path_, "wb"); + if (!file) { + return false; + } + fclose(file); + size_ = 0; + allocation_size_ = 0; + return true; +} + +std::unique_ptr HostPathEntry::CreateEntryInternal(const std::string_view name, + uint32_t attributes) { + auto full_path = host_path_ / rex::to_path(name); + if (attributes & kFileAttributeDirectory) { + if (!std::filesystem::create_directories(full_path)) { + return nullptr; + } + } else { + auto file = rex::filesystem::OpenFile(full_path, "wb"); + if (!file) { + return nullptr; + } + fclose(file); + } + rex::filesystem::FileInfo file_info; + if (!rex::filesystem::GetInfo(full_path, &file_info)) { + return nullptr; + } + return std::unique_ptr(HostPathEntry::Create(device_, this, full_path, file_info)); +} + +bool HostPathEntry::DeleteEntryInternal(Entry* entry) { + auto full_path = host_path_ / rex::to_path(entry->name()); + std::error_code ec; // avoid exception on remove/remove_all failure + if (entry->attributes() & kFileAttributeDirectory) { + // Delete entire directory and contents. + auto removed = std::filesystem::remove_all(full_path, ec); + return removed >= 1 && removed != static_cast(-1); + } else { + // Delete file. + return !std::filesystem::is_directory(full_path) && std::filesystem::remove(full_path, ec); + } +} + +void HostPathEntry::RenameEntryInternal(const std::vector& path_parts) { + auto new_host_path = static_cast(device_)->host_path(); + for (const auto& path_part : path_parts) { + new_host_path /= rex::to_path(path_part); + } + + std::error_code ec; + std::filesystem::rename(host_path_, new_host_path, ec); + if (ec) { + REXFS_ERROR("RenameEntryInternal: failed to rename '{}' to '{}': {}", + rex::path_to_utf8(host_path_), rex::path_to_utf8(new_host_path), ec.message()); + return; + } + + host_path_ = new_host_path; +} + +void HostPathEntry::update() { + rex::filesystem::FileInfo file_info; + if (!rex::filesystem::GetInfo(host_path_, &file_info)) { + return; + } + if (file_info.type == rex::filesystem::FileInfo::Type::kFile) { + size_ = file_info.total_size; + allocation_size_ = rex::round_up(file_info.total_size, device()->bytes_per_sector()); + } +} + +bool HostPathEntry::SetAttributes(uint64_t attributes) { + if (device_->is_read_only()) { + return false; + } + attributes_ = static_cast(attributes); + return true; +} + +bool HostPathEntry::SetCreateTimestamp(uint64_t timestamp) { + if (device_->is_read_only()) { + return false; + } + create_timestamp_ = timestamp; + return true; +} + +bool HostPathEntry::SetAccessTimestamp(uint64_t timestamp) { + if (device_->is_read_only()) { + return false; + } + access_timestamp_ = timestamp; + return true; +} + +bool HostPathEntry::SetWriteTimestamp(uint64_t timestamp) { + if (device_->is_read_only()) { + return false; + } + write_timestamp_ = timestamp; + return true; +} + +} // namespace rex::filesystem diff --git a/src/filesystem/devices/host_path_file.cpp b/src/filesystem/devices/host_path_file.cpp new file mode 100644 index 0000000..4c57a18 --- /dev/null +++ b/src/filesystem/devices/host_path_file.cpp @@ -0,0 +1,66 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +namespace rex::filesystem { + +HostPathFile::HostPathFile(uint32_t file_access, HostPathEntry* entry, + std::unique_ptr file_handle) + : File(file_access, entry), file_handle_(std::move(file_handle)) {} + +HostPathFile::~HostPathFile() = default; + +void HostPathFile::Destroy() { + delete this; +} + +X_STATUS HostPathFile::ReadSync(std::span buffer, size_t byte_offset, + size_t* out_bytes_read) { + if (!(file_access_ & (FileAccess::kGenericRead | FileAccess::kFileReadData))) { + return X_STATUS_ACCESS_DENIED; + } + + if (file_handle_->Read(byte_offset, buffer.data(), buffer.size(), out_bytes_read)) { + return X_STATUS_SUCCESS; + } else { + return X_STATUS_END_OF_FILE; + } +} + +X_STATUS HostPathFile::WriteSync(std::span buffer, size_t byte_offset, + size_t* out_bytes_written) { + if (!(file_access_ & + (FileAccess::kGenericWrite | FileAccess::kFileWriteData | FileAccess::kFileAppendData))) { + return X_STATUS_ACCESS_DENIED; + } + + if (file_handle_->Write(byte_offset, buffer.data(), buffer.size(), out_bytes_written)) { + return X_STATUS_SUCCESS; + } else { + return X_STATUS_END_OF_FILE; + } +} + +X_STATUS HostPathFile::SetLength(size_t length) { + if (!(file_access_ & (FileAccess::kGenericWrite | FileAccess::kFileWriteData))) { + return X_STATUS_ACCESS_DENIED; + } + + if (file_handle_->SetLength(length)) { + return X_STATUS_SUCCESS; + } else { + return X_STATUS_END_OF_FILE; + } +} + +} // namespace rex::filesystem diff --git a/src/filesystem/devices/null_device.cpp b/src/filesystem/devices/null_device.cpp new file mode 100644 index 0000000..aed2884 --- /dev/null +++ b/src/filesystem/devices/null_device.cpp @@ -0,0 +1,62 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include +#include + +namespace rex::filesystem { + +NullDevice::NullDevice(const std::string& mount_path, + const std::initializer_list& null_paths) + : Device(mount_path), null_paths_(null_paths), name_("NullDevice") {} + +NullDevice::~NullDevice() = default; + +bool NullDevice::Initialize() { + auto root_entry = new NullEntry(this, nullptr, ""); + root_entry->attributes_ = kFileAttributeDirectory; + root_entry_ = std::unique_ptr(root_entry); + + for (auto path : null_paths_) { + auto child = NullEntry::Create(this, root_entry, path); + root_entry->children_.push_back(std::unique_ptr(child)); + } + return true; +} + +void NullDevice::Dump(string::StringBuffer* string_buffer) { + auto global_lock = global_critical_region_.Acquire(); + root_entry_->Dump(string_buffer, 0); +} + +Entry* NullDevice::ResolvePath(const std::string_view path) { + REXFS_DEBUG("NullDevice::ResolvePath({})", path); + + auto root = root_entry_.get(); + if (path.empty()) { + return root_entry_.get(); + } + + for (auto& child : root->children()) { + if (!rex::string::compare_case(child->path().c_str(), path.data())) { + return child.get(); + } + } + + return nullptr; +} + +} // namespace rex::filesystem diff --git a/src/filesystem/devices/null_device.h b/src/filesystem/devices/null_device.h new file mode 100644 index 0000000..4068d34 --- /dev/null +++ b/src/filesystem/devices/null_device.h @@ -0,0 +1,53 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma once + +#include + +#include + +namespace rex::filesystem { + +class NullEntry; + +class NullDevice : public Device { + public: + NullDevice(const std::string& mount_path, const std::initializer_list& null_paths); + ~NullDevice() override; + + bool Initialize() override; + void Dump(string::StringBuffer* string_buffer) override; + Entry* ResolvePath(const std::string_view path) override; + + bool is_read_only() const override { return false; } + + const std::string& name() const override { return name_; } + uint32_t attributes() const override { return 0; } + uint32_t component_name_max_length() const override { return 40; } + + uint32_t total_allocation_units() const override { return 0x10; } + uint32_t available_allocation_units() const override { return 0x10; } + + // STFC/cache code seems to require the product of the next two to equal + // 0x10000 + uint32_t sectors_per_allocation_unit() const override { return 0x80; } + + // STFC requires <= 0x1000 + uint32_t bytes_per_sector() const override { return 0x200; } + + private: + std::string name_; + std::unique_ptr root_entry_; + std::vector null_paths_; +}; + +} // namespace rex::filesystem diff --git a/src/filesystem/devices/null_entry.cpp b/src/filesystem/devices/null_entry.cpp new file mode 100644 index 0000000..6112405 --- /dev/null +++ b/src/filesystem/devices/null_entry.cpp @@ -0,0 +1,54 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace rex::filesystem { + +NullEntry::NullEntry(Device* device, Entry* parent, std::string path) + : Entry(device, parent, path) {} + +NullEntry::~NullEntry() = default; + +NullEntry* NullEntry::Create(Device* device, Entry* parent, const std::string& path) { + auto entry = new NullEntry(device, parent, path); + + entry->create_timestamp_ = 0; + entry->access_timestamp_ = 0; + entry->write_timestamp_ = 0; + + entry->attributes_ = kFileAttributeNormal; + + entry->size_ = 0; + entry->allocation_size_ = 0; + return entry; +} + +X_STATUS NullEntry::Open(uint32_t desired_access, File** out_file) { + if (is_read_only() && + (desired_access & (FileAccess::kFileWriteData | FileAccess::kFileAppendData))) { + REXFS_ERROR("Attempting to open file for write access on read-only device"); + return X_STATUS_ACCESS_DENIED; + } + + *out_file = new NullFile(desired_access, this); + return X_STATUS_SUCCESS; +} + +} // namespace rex::filesystem diff --git a/src/filesystem/devices/null_file.cpp b/src/filesystem/devices/null_file.cpp new file mode 100644 index 0000000..68a63ce --- /dev/null +++ b/src/filesystem/devices/null_file.cpp @@ -0,0 +1,50 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +namespace rex::filesystem { + +NullFile::NullFile(uint32_t file_access, NullEntry* entry) : File(file_access, entry) {} + +NullFile::~NullFile() = default; + +void NullFile::Destroy() { + delete this; +} + +X_STATUS NullFile::ReadSync(std::span buffer, size_t byte_offset, size_t* out_bytes_read) { + if (!(file_access_ & FileAccess::kFileReadData)) { + return X_STATUS_ACCESS_DENIED; + } + + return X_STATUS_SUCCESS; +} + +X_STATUS NullFile::WriteSync(std::span buffer, size_t byte_offset, + size_t* out_bytes_written) { + if (!(file_access_ & (FileAccess::kFileWriteData | FileAccess::kFileAppendData))) { + return X_STATUS_ACCESS_DENIED; + } + + return X_STATUS_SUCCESS; +} + +X_STATUS NullFile::SetLength(size_t length) { + if (!(file_access_ & FileAccess::kFileWriteData)) { + return X_STATUS_ACCESS_DENIED; + } + + return X_STATUS_SUCCESS; +} + +} // namespace rex::filesystem diff --git a/src/filesystem/devices/stfs_container_device.cpp b/src/filesystem/devices/stfs_container_device.cpp new file mode 100644 index 0000000..7062520 --- /dev/null +++ b/src/filesystem/devices/stfs_container_device.cpp @@ -0,0 +1,834 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include + +#include +#include +#include + +namespace rex::filesystem { + +StfsContainerDevice::StfsContainerDevice(const std::string_view mount_path, + const std::filesystem::path& host_path) + : Device(mount_path), + name_("STFS"), + host_path_(host_path), + files_total_size_(), + svod_base_offset_(), + header_(), + svod_layout_(), + blocks_per_hash_table_(1), + block_step{0, 0} {} + +StfsContainerDevice::~StfsContainerDevice() { + CloseFiles(); +} + +std::unique_ptr StfsContainerDevice::ReadPackageHeader( + const std::filesystem::path& file_path) { + if (!std::filesystem::exists(file_path)) { + return nullptr; + } + + if (std::filesystem::file_size(file_path) < sizeof(StfsHeader)) { + return nullptr; + } + + auto file = rex::filesystem::OpenFile(file_path, "rb"); + if (!file) { + return nullptr; + } + + auto header = std::make_unique(); + if (fread(header.get(), sizeof(StfsHeader), 1, file) != 1) { + fclose(file); + return nullptr; + } + fclose(file); + + if (!header->header.is_magic_valid()) { + return nullptr; + } + + return header; +} + +bool StfsContainerDevice::Initialize() { + // Resolve a valid STFS file if a directory is given. + if (std::filesystem::is_directory(host_path_) && !ResolveFromFolder(host_path_)) { + REXFS_ERROR("Could not resolve an STFS container given path {}", rex::path_to_utf8(host_path_)); + return false; + } + + if (!std::filesystem::exists(host_path_)) { + REXFS_ERROR("Path to STFS container does not exist: {}", rex::path_to_utf8(host_path_)); + return false; + } + + // Open the data file(s) + auto open_result = OpenFiles(); + if (open_result != Error::kSuccess) { + REXFS_ERROR("Failed to open STFS container: {}", static_cast(open_result)); + return false; + } + + switch (header_.metadata.volume_type) { + case XContentVolumeType::kStfs: + return ReadSTFS() == Error::kSuccess; + break; + case XContentVolumeType::kSvod: + return ReadSVOD() == Error::kSuccess; + default: + REXFS_ERROR("Unknown XContent volume type: {}", + rex::byte_swap(uint32_t(header_.metadata.volume_type.value))); + return false; + } +} + +StfsContainerDevice::Error StfsContainerDevice::OpenFiles() { + // Map the file containing the STFS Header and read it. + REXFS_INFO("Loading STFS header file: {}", rex::path_to_utf8(host_path_)); + + auto header_file = rex::filesystem::OpenFile(host_path_, "rb"); + if (!header_file) { + REXFS_ERROR("Error opening STFS header file."); + return Error::kErrorReadError; + } + + auto header_result = ReadHeaderAndVerify(header_file); + if (header_result != Error::kSuccess) { + REXFS_ERROR("Error reading STFS header: {}", static_cast(header_result)); + fclose(header_file); + files_total_size_ = 0; + return header_result; + } + + // If the STFS package is a single file, the header is self contained and + // we don't need to map any extra files. + // NOTE: data_file_count is 0 for STFS and 1 for SVOD + if (header_.metadata.data_file_count <= 1) { + REXFS_INFO("STFS container is a single file."); + files_.emplace(std::make_pair(0, header_file)); + return Error::kSuccess; + } + + // If the STFS package is multi-file, it is an SVOD system. We need to map + // the files in the .data folder and can discard the header. + auto data_fragment_path = host_path_; + data_fragment_path += ".data"; + if (!std::filesystem::exists(data_fragment_path)) { + REXFS_ERROR("STFS container is multi-file, but path {} does not exist.", + rex::path_to_utf8(data_fragment_path)); + return Error::kErrorFileMismatch; + } + + // Ensure data fragment files are sorted + auto fragment_files = filesystem::ListFiles(data_fragment_path); + std::sort(fragment_files.begin(), fragment_files.end(), + [](filesystem::FileInfo& left, filesystem::FileInfo& right) { + return left.name < right.name; + }); + + if (fragment_files.size() != header_.metadata.data_file_count) { + REXFS_ERROR("SVOD expecting {} data fragments, but {} are present.", + header_.metadata.data_file_count.get(), fragment_files.size()); + return Error::kErrorFileMismatch; + } + + for (size_t i = 0; i < fragment_files.size(); i++) { + auto& fragment = fragment_files.at(i); + auto path = fragment.path / fragment.name; + auto file = rex::filesystem::OpenFile(path, "rb"); + if (!file) { + REXFS_INFO("Failed to map SVOD file {}.", rex::path_to_utf8(path)); + CloseFiles(); + return Error::kErrorReadError; + } + + rex::filesystem::Seek(file, 0L, SEEK_END); + files_total_size_ += rex::filesystem::Tell(file); + // no need to seek back, any reads from this file will seek first anyway + files_.emplace(std::make_pair(i, file)); + } + REXFS_INFO("SVOD successfully mapped {} files.", fragment_files.size()); + return Error::kSuccess; +} + +void StfsContainerDevice::CloseFiles() { + for (auto& file : files_) { + fclose(file.second); + } + files_.clear(); + files_total_size_ = 0; +} + +void StfsContainerDevice::Dump(string::StringBuffer* string_buffer) { + auto global_lock = global_critical_region_.Acquire(); + root_entry_->Dump(string_buffer, 0); +} + +Entry* StfsContainerDevice::ResolvePath(const std::string_view path) { + // The filesystem will have stripped our prefix off already, so the path will + // be in the form: + // some\PATH.foo + REXFS_DEBUG("StfsContainerDevice::ResolvePath({})", path); + return root_entry_->ResolvePath(path); +} + +StfsContainerDevice::Error StfsContainerDevice::ReadHeaderAndVerify(FILE* header_file) { + // Check size of the file is enough to store an STFS header + rex::filesystem::Seek(header_file, 0L, SEEK_END); + files_total_size_ = rex::filesystem::Tell(header_file); + rex::filesystem::Seek(header_file, 0L, SEEK_SET); + + if (sizeof(StfsHeader) > files_total_size_) { + return Error::kErrorTooSmall; + } + + // Read header & check signature + if (fread(&header_, sizeof(StfsHeader), 1, header_file) != 1) { + return Error::kErrorReadError; + } + + if (!header_.header.is_magic_valid()) { + // Unexpected format. + return Error::kErrorFileMismatch; + } + + // Pre-calculate some values used in block number calculations + if (header_.metadata.volume_type == XContentVolumeType::kStfs) { + blocks_per_hash_table_ = + header_.metadata.volume_descriptor.stfs.flags.bits.read_only_format ? 1 : 2; + + block_step[0] = kBlocksPerHashLevel[0] + blocks_per_hash_table_; + block_step[1] = + kBlocksPerHashLevel[1] + ((kBlocksPerHashLevel[0] + 1) * blocks_per_hash_table_); + } + + return Error::kSuccess; +} + +StfsContainerDevice::Error StfsContainerDevice::ReadSVOD() { + // SVOD Systems can have different layouts. The root block is + // denoted by the magic "MICROSOFT*XBOX*MEDIA" and is always in + // the first "actual" data fragment of the system. + auto& svod_header = files_.at(0); + const char* MEDIA_MAGIC = "MICROSOFT*XBOX*MEDIA"; + + uint8_t magic_buf[20]; + size_t magic_offset; + + // Check for EDGF layout + if (header_.metadata.volume_descriptor.svod.features.bits.enhanced_gdf_layout) { + // The STFS header has specified that this SVOD system uses the EGDF layout. + // We can expect the magic block to be located immediately after the hash + // blocks. We also offset block address calculation by 0x1000 by shifting + // block indices by +0x2. + rex::filesystem::Seek(svod_header, 0x2000, SEEK_SET); + if (fread(magic_buf, 1, countof(magic_buf), svod_header) != countof(magic_buf)) { + REXFS_ERROR("ReadSVOD failed to read SVOD magic at 0x2000"); + return Error::kErrorReadError; + } + + if (std::memcmp(magic_buf, MEDIA_MAGIC, 20) == 0) { + svod_base_offset_ = 0x0000; + magic_offset = 0x2000; + svod_layout_ = SvodLayoutType::kEnhancedGDF; + REXFS_INFO("SVOD uses an EGDF layout. Magic block present at 0x2000."); + } else { + REXFS_ERROR("SVOD uses an EGDF layout, but the magic block was not found."); + return Error::kErrorFileMismatch; + } + } else { + rex::filesystem::Seek(svod_header, 0x12000, SEEK_SET); + if (fread(magic_buf, 1, countof(magic_buf), svod_header) != countof(magic_buf)) { + REXFS_ERROR("ReadSVOD failed to read SVOD magic at 0x12000"); + return Error::kErrorReadError; + } + if (std::memcmp(magic_buf, MEDIA_MAGIC, 20) == 0) { + // If the SVOD's magic block is at 0x12000, it is likely using an XSF + // layout. This is usually due to converting the game using a third-party + // tool, as most of them use a nulled XSF as a template. + + svod_base_offset_ = 0x10000; + magic_offset = 0x12000; + + // Check for XSF Header + const char* XSF_MAGIC = "XSF"; + rex::filesystem::Seek(svod_header, 0x2000, SEEK_SET); + if (fread(magic_buf, 1, 3, svod_header) != 3) { + REXFS_ERROR("ReadSVOD failed to read SVOD XSF magic at 0x2000"); + return Error::kErrorReadError; + } + if (std::memcmp(magic_buf, XSF_MAGIC, 3) == 0) { + svod_layout_ = SvodLayoutType::kXSF; + REXFS_INFO("SVOD uses an XSF layout. Magic block present at 0x12000."); + REXFS_INFO("Game was likely converted using a third-party tool."); + } else { + svod_layout_ = SvodLayoutType::kUnknown; + REXFS_INFO("SVOD appears to use an XSF layout, but no header is present."); + REXFS_INFO("SVOD magic block found at 0x12000"); + } + } else { + rex::filesystem::Seek(svod_header, 0xD000, SEEK_SET); + if (fread(magic_buf, 1, countof(magic_buf), svod_header) != countof(magic_buf)) { + REXFS_ERROR("ReadSVOD failed to read SVOD magic at 0xD000"); + return Error::kErrorReadError; + } + if (std::memcmp(magic_buf, MEDIA_MAGIC, 20) == 0) { + // If the SVOD's magic block is at 0xD000, it most likely means that it + // is a single-file system. The STFS Header is 0xB000 bytes , and the + // remaining 0x2000 is from hash tables. In most cases, these will be + // STFS, not SVOD. + + svod_base_offset_ = 0xB000; + magic_offset = 0xD000; + + // Check for single file system + if (header_.metadata.data_file_count == 1) { + svod_layout_ = SvodLayoutType::kSingleFile; + REXFS_INFO("SVOD is a single file. Magic block present at 0xD000."); + } else { + svod_layout_ = SvodLayoutType::kUnknown; + REXFS_ERROR( + "SVOD is not a single file, but the magic block was found at " + "0xD000."); + } + } else { + REXFS_ERROR("Could not locate SVOD magic block."); + return Error::kErrorReadError; + } + } + } + + // Parse the root directory + rex::filesystem::Seek(svod_header, magic_offset + 0x14, SEEK_SET); + + struct { + uint32_t block; + uint32_t size; + uint32_t creation_date; + uint32_t creation_time; + } root_data; + static_assert_size(root_data, 0x10); + + if (fread(&root_data, sizeof(root_data), 1, svod_header) != 1) { + REXFS_ERROR("ReadSVOD failed to read root block data at 0x{:X}", magic_offset + 0x14); + return Error::kErrorReadError; + } + + uint64_t root_creation_timestamp = + decode_fat_timestamp(root_data.creation_date, root_data.creation_time); + + auto root_entry = new StfsContainerEntry(this, nullptr, "", &files_); + root_entry->attributes_ = kFileAttributeDirectory; + root_entry->access_timestamp_ = root_creation_timestamp; + root_entry->create_timestamp_ = root_creation_timestamp; + root_entry->write_timestamp_ = root_creation_timestamp; + root_entry_ = std::unique_ptr(root_entry); + + // Traverse all child entries + return ReadEntrySVOD(root_data.block, 0, root_entry); +} + +StfsContainerDevice::Error StfsContainerDevice::ReadEntrySVOD(uint32_t block, uint32_t ordinal, + StfsContainerEntry* parent) { + // For games with a large amount of files, the ordinal offset can overrun + // the current block and potentially hit a hash block. + size_t ordinal_offset = ordinal * 0x4; + size_t block_offset = ordinal_offset / 0x800; + size_t true_ordinal_offset = ordinal_offset % 0x800; + + // Calculate the file & address of the block + size_t entry_address, entry_file; + BlockToOffsetSVOD(block + block_offset, &entry_address, &entry_file); + entry_address += true_ordinal_offset; + + // Read directory entry + auto& file = files_.at(entry_file); + rex::filesystem::Seek(file, entry_address, SEEK_SET); + +#pragma pack(push, 1) + struct { + uint16_t node_l; + uint16_t node_r; + uint32_t data_block; + uint32_t length; + uint8_t attributes; + uint8_t name_length; + } dir_entry; + static_assert_size(dir_entry, 0xE); +#pragma pack(pop) + + if (fread(&dir_entry, sizeof(dir_entry), 1, file) != 1) { + REXFS_ERROR("ReadEntrySVOD failed to read directory entry at 0x{:X}", entry_address); + return Error::kErrorReadError; + } + + auto name_buffer = std::make_unique(dir_entry.name_length); + if (fread(name_buffer.get(), 1, dir_entry.name_length, file) != dir_entry.name_length) { + REXFS_ERROR("ReadEntrySVOD failed to read directory entry name at 0x{:X}", entry_address); + return Error::kErrorReadError; + } + + auto name = std::string(name_buffer.get(), dir_entry.name_length); + + // Read the left node + if (dir_entry.node_l) { + auto node_result = ReadEntrySVOD(block, dir_entry.node_l, parent); + if (node_result != Error::kSuccess) { + return node_result; + } + } + + // Read file & address of block's data + size_t data_address, data_file; + BlockToOffsetSVOD(dir_entry.data_block, &data_address, &data_file); + + // Create the entry + // NOTE: SVOD entries don't have timestamps for individual files, which can + // cause issues when decrypting games. Using the root entry's timestamp + // solves this issues. + auto entry = StfsContainerEntry::Create(this, parent, name, &files_); + if (dir_entry.attributes & kFileAttributeDirectory) { + // Entry is a directory + entry->attributes_ = kFileAttributeDirectory | kFileAttributeReadOnly; + entry->data_offset_ = 0; + entry->data_size_ = 0; + entry->block_ = block; + entry->access_timestamp_ = root_entry_->create_timestamp(); + entry->create_timestamp_ = root_entry_->create_timestamp(); + entry->write_timestamp_ = root_entry_->create_timestamp(); + + if (dir_entry.length) { + // If length is greater than 0, traverse the directory's children + auto directory_result = ReadEntrySVOD(dir_entry.data_block, 0, entry.get()); + if (directory_result != Error::kSuccess) { + return directory_result; + } + } + } else { + // Entry is a file + entry->attributes_ = kFileAttributeNormal | kFileAttributeReadOnly; + entry->size_ = dir_entry.length; + entry->allocation_size_ = rex::round_up(dir_entry.length, kBlockSize); + entry->data_offset_ = data_address; + entry->data_size_ = dir_entry.length; + entry->block_ = dir_entry.data_block; + entry->access_timestamp_ = root_entry_->create_timestamp(); + entry->create_timestamp_ = root_entry_->create_timestamp(); + entry->write_timestamp_ = root_entry_->create_timestamp(); + + // Fill in all block records, sector by sector. + if (entry->attributes() & system::X_FILE_ATTRIBUTE_NORMAL) { + uint32_t block_index = dir_entry.data_block; + size_t remaining_size = rex::round_up(dir_entry.length, 0x800); + + size_t last_record = -1; + size_t last_offset = -1; + while (remaining_size) { + const size_t BLOCK_SIZE = 0x800; + + size_t offset, file_index; + BlockToOffsetSVOD(block_index, &offset, &file_index); + + block_index++; + remaining_size -= BLOCK_SIZE; + + if (offset - last_offset == 0x800) { + // Consecutive, so append to last entry. + entry->block_list_[last_record].length += BLOCK_SIZE; + last_offset = offset; + continue; + } + + entry->block_list_.push_back({file_index, offset, BLOCK_SIZE}); + last_record = entry->block_list_.size() - 1; + last_offset = offset; + } + } + } + + parent->children_.emplace_back(std::move(entry)); + + // Read the right node. + if (dir_entry.node_r) { + auto node_result = ReadEntrySVOD(block, dir_entry.node_r, parent); + if (node_result != Error::kSuccess) { + return node_result; + } + } + + return Error::kSuccess; +} + +void StfsContainerDevice::BlockToOffsetSVOD(size_t block, size_t* out_address, + size_t* out_file_index) { + // SVOD Systems use hash blocks for integrity checks. These hash blocks + // cause blocks to be discontinuous in memory, and must be accounted for. + // - Each data block is 0x800 bytes in length + // - Every group of 0x198 data blocks is preceded a Level0 hash table. + // Level0 tables contain 0xCC hashes, each representing two data blocks. + // The total size of each Level0 hash table is 0x1000 bytes in length. + // - Every 0xA1C4 Level0 hash tables is preceded by a Level1 hash table. + // Level1 tables contain 0xCB hashes, each representing two Level0 hashes. + // The total size of each Level1 hash table is 0x1000 bytes in length. + // - Files are split into fragments of 0xA290000 bytes in length, + // consisting of 0x14388 data blocks, 0xCB Level0 hash tables, and 0x1 + // Level1 hash table. + + const size_t BLOCK_SIZE = 0x800; + const size_t HASH_BLOCK_SIZE = 0x1000; + const size_t BLOCKS_PER_L0_HASH = 0x198; + const size_t HASHES_PER_L1_HASH = 0xA1C4; + const size_t BLOCKS_PER_FILE = 0x14388; + const size_t MAX_FILE_SIZE = 0xA290000; + const size_t BLOCK_OFFSET = header_.metadata.volume_descriptor.svod.start_data_block(); + + // Resolve the true block address and file index + size_t true_block = block - (BLOCK_OFFSET * 2); + if (svod_layout_ == SvodLayoutType::kEnhancedGDF) { + // EGDF has an 0x1000 byte offset, which is two blocks + true_block += 0x2; + } + + size_t file_block = true_block % BLOCKS_PER_FILE; + size_t file_index = true_block / BLOCKS_PER_FILE; + size_t offset = 0; + + // Calculate offset caused by Level0 Hash Tables + size_t level0_table_count = (file_block / BLOCKS_PER_L0_HASH) + 1; + offset += level0_table_count * HASH_BLOCK_SIZE; + + // Calculate offset caused by Level1 Hash Tables + size_t level1_table_count = (level0_table_count / HASHES_PER_L1_HASH) + 1; + offset += level1_table_count * HASH_BLOCK_SIZE; + + // For single-file SVOD layouts, include the size of the header in the offset. + if (svod_layout_ == SvodLayoutType::kSingleFile) { + offset += svod_base_offset_; + } + + size_t block_address = (file_block * BLOCK_SIZE) + offset; + + // If the offset causes the block address to overrun the file, round it. + if (block_address >= MAX_FILE_SIZE) { + file_index += 1; + block_address %= MAX_FILE_SIZE; + block_address += 0x2000; + } + + *out_address = block_address; + *out_file_index = file_index; +} + +StfsContainerDevice::Error StfsContainerDevice::ReadSTFS() { + auto& file = files_.at(0); + + auto root_entry = new StfsContainerEntry(this, nullptr, "", &files_); + root_entry->attributes_ = kFileAttributeDirectory; + root_entry_ = std::unique_ptr(root_entry); + + std::vector all_entries; + + // Load all listings. + StfsDirectoryBlock directory; + + auto& descriptor = header_.metadata.volume_descriptor.stfs; + uint32_t table_block_index = descriptor.file_table_block_number(); + size_t n = 0; + for (n = 0; n < descriptor.file_table_block_count; n++) { + auto offset = BlockToOffsetSTFS(table_block_index); + rex::filesystem::Seek(file, offset, SEEK_SET); + + if (fread(&directory, sizeof(StfsDirectoryBlock), 1, file) != 1) { + REXFS_ERROR("ReadSTFS failed to read directory block at 0x{:X}", offset); + return Error::kErrorReadError; + } + + for (size_t m = 0; m < kEntriesPerDirectoryBlock; m++) { + auto& dir_entry = directory.entries[m]; + + if (dir_entry.name[0] == 0) { + // Done. + break; + } + + StfsContainerEntry* parent_entry = nullptr; + if (dir_entry.directory_index == 0xFFFF) { + parent_entry = root_entry; + } else { + parent_entry = all_entries[dir_entry.directory_index]; + } + + std::string name(reinterpret_cast(dir_entry.name), + dir_entry.flags.name_length & 0x3F); + auto entry = StfsContainerEntry::Create(this, parent_entry, name, &files_); + + if (dir_entry.flags.directory) { + entry->attributes_ = kFileAttributeDirectory; + } else { + entry->attributes_ = kFileAttributeNormal | kFileAttributeReadOnly; + entry->data_offset_ = BlockToOffsetSTFS(dir_entry.start_block_number()); + entry->data_size_ = dir_entry.length; + } + entry->size_ = dir_entry.length; + entry->allocation_size_ = rex::round_up(dir_entry.length, kBlockSize); + + entry->create_timestamp_ = decode_fat_timestamp(dir_entry.create_date, dir_entry.create_time); + entry->write_timestamp_ = + decode_fat_timestamp(dir_entry.modified_date, dir_entry.modified_time); + entry->access_timestamp_ = entry->write_timestamp_; + + all_entries.push_back(entry.get()); + + // Fill in all block records. + // It's easier to do this now and just look them up later, at the cost + // of some memory. Nasty chain walk. + // TODO(benvanik): optimize if flags.contiguous is set. + if (entry->attributes() & system::X_FILE_ATTRIBUTE_NORMAL) { + uint32_t block_index = dir_entry.start_block_number(); + size_t remaining_size = dir_entry.length; + while (remaining_size && block_index != kEndOfChain) { + size_t block_size = std::min(static_cast(kBlockSize), remaining_size); + size_t offset = BlockToOffsetSTFS(block_index); + entry->block_list_.push_back({0, offset, block_size}); + remaining_size -= block_size; + auto block_hash = GetBlockHash(block_index); + block_index = block_hash->level0_next_block(); + } + + if (remaining_size) { + // Loop above must have exited prematurely, bad hash tables? + REXFS_WARN( + "STFS file {} only found {} bytes for file, expected {} ({} " + "bytes missing)", + name, dir_entry.length.get() - remaining_size, dir_entry.length.get(), + remaining_size); + assert_always(); + } + + // Check that the number of blocks retrieved from hash entries matches + // the block count read from the file entry + if (entry->block_list_.size() != dir_entry.allocated_data_blocks()) { + REXFS_WARN( + "STFS failed to read correct block-chain for entry {}, read {} " + "blocks, expected {}", + entry->name_, entry->block_list_.size(), dir_entry.allocated_data_blocks()); + assert_always(); + } + } + + parent_entry->children_.emplace_back(std::move(entry)); + } + + auto block_hash = GetBlockHash(table_block_index); + table_block_index = block_hash->level0_next_block(); + if (table_block_index == kEndOfChain) { + break; + } + } + + if (n + 1 != descriptor.file_table_block_count) { + REXFS_WARN("STFS read {} file table blocks, but STFS headers expected {}!", n + 1, + descriptor.file_table_block_count); + assert_always(); + } + + return Error::kSuccess; +} + +size_t StfsContainerDevice::BlockToOffsetSTFS(uint64_t block_index) const { + // For every level there is a hash table + // Level 0: hash table of next 170 blocks + // Level 1: hash table of next 170 hash tables + // Level 2: hash table of next 170 level 1 hash tables + // And so on... + uint64_t base = kBlocksPerHashLevel[0]; + uint64_t block = block_index; + for (uint32_t i = 0; i < 3; i++) { + block += ((block_index + base) / base) * blocks_per_hash_table_; + if (block_index < base) { + break; + } + + base *= kBlocksPerHashLevel[0]; + } + + return rex::round_up(header_.header.header_size, kBlockSize) + (block << 12); +} + +uint32_t StfsContainerDevice::BlockToHashBlockNumberSTFS(uint32_t block_index, + uint32_t hash_level) const { + uint32_t block = 0; + if (hash_level == 0) { + if (block_index < kBlocksPerHashLevel[0]) { + return 0; + } + + block = (block_index / kBlocksPerHashLevel[0]) * block_step[0]; + block += ((block_index / kBlocksPerHashLevel[1]) + 1) * blocks_per_hash_table_; + + if (block_index < kBlocksPerHashLevel[1]) { + return block; + } + + return block + blocks_per_hash_table_; + } + + if (hash_level == 1) { + if (block_index < kBlocksPerHashLevel[1]) { + return block_step[0]; + } + + block = (block_index / kBlocksPerHashLevel[1]) * block_step[1]; + return block + blocks_per_hash_table_; + } + + // Level 2 is always at blockStep1 + return block_step[1]; +} + +size_t StfsContainerDevice::BlockToHashBlockOffsetSTFS(uint32_t block_index, + uint32_t hash_level) const { + uint64_t block = BlockToHashBlockNumberSTFS(block_index, hash_level); + return rex::round_up(header_.header.header_size, kBlockSize) + (block << 12); +} + +const StfsHashEntry* StfsContainerDevice::GetBlockHash(uint32_t block_index) { + auto& file = files_.at(0); + + auto& descriptor = header_.metadata.volume_descriptor.stfs; + + // Offset for selecting the secondary hash block, in packages that have them + uint32_t secondary_table_offset = descriptor.flags.bits.root_active_index ? kBlockSize : 0; + + auto hash_offset_lv0 = BlockToHashBlockOffsetSTFS(block_index, 0); + if (!cached_hash_tables_.count(hash_offset_lv0)) { + // If this is read_only_format then it doesn't contain secondary blocks, no + // need to check upper hash levels + if (descriptor.flags.bits.read_only_format) { + secondary_table_offset = 0; + } else { + // Not a read-only package, need to check each levels active index flag to + // see if we need to use secondary block or not + + // Check level1 table if package has it + if (descriptor.total_block_count > kBlocksPerHashLevel[0]) { + auto hash_offset_lv1 = BlockToHashBlockOffsetSTFS(block_index, 1); + + if (!cached_hash_tables_.count(hash_offset_lv1)) { + // Check level2 table if package has it + if (descriptor.total_block_count > kBlocksPerHashLevel[1]) { + auto hash_offset_lv2 = BlockToHashBlockOffsetSTFS(block_index, 2); + + if (!cached_hash_tables_.count(hash_offset_lv2)) { + rex::filesystem::Seek(file, hash_offset_lv2 + secondary_table_offset, SEEK_SET); + + StfsHashTable table_lv2; + if (fread(&table_lv2, sizeof(StfsHashTable), 1, file) != 1) { + REXFS_ERROR("GetBlockHash failed to read level2 hash table at 0x{:X}", + hash_offset_lv2 + secondary_table_offset); + return nullptr; + } + cached_hash_tables_[hash_offset_lv2] = table_lv2; + } + + auto record = (block_index / kBlocksPerHashLevel[1]) % kBlocksPerHashLevel[0]; + auto record_data = &cached_hash_tables_[hash_offset_lv2].entries[record]; + secondary_table_offset = record_data->levelN_active_index() ? kBlockSize : 0; + } + + rex::filesystem::Seek(file, hash_offset_lv1 + secondary_table_offset, SEEK_SET); + + StfsHashTable table_lv1; + if (fread(&table_lv1, sizeof(StfsHashTable), 1, file) != 1) { + REXFS_ERROR("GetBlockHash failed to read level1 hash table at 0x{:X}", + hash_offset_lv1 + secondary_table_offset); + return nullptr; + } + cached_hash_tables_[hash_offset_lv1] = table_lv1; + } + + auto record = (block_index / kBlocksPerHashLevel[0]) % kBlocksPerHashLevel[0]; + auto record_data = &cached_hash_tables_[hash_offset_lv1].entries[record]; + secondary_table_offset = record_data->levelN_active_index() ? kBlockSize : 0; + } + } + + rex::filesystem::Seek(file, hash_offset_lv0 + secondary_table_offset, SEEK_SET); + + StfsHashTable table_lv0; + if (fread(&table_lv0, sizeof(StfsHashTable), 1, file) != 1) { + REXFS_ERROR("GetBlockHash failed to read level0 hash table at 0x{:X}", + (hash_offset_lv0 + secondary_table_offset)); + return nullptr; + } + cached_hash_tables_[hash_offset_lv0] = table_lv0; + } + + auto record = block_index % kBlocksPerHashLevel[0]; + auto record_data = &cached_hash_tables_[hash_offset_lv0].entries[record]; + + return record_data; +} + +XContentPackageType StfsContainerDevice::ReadMagic(const std::filesystem::path& path) { + auto map = memory::MappedMemory::Open(path, memory::MappedMemory::Mode::kRead, 0, 4); + return XContentPackageType(memory::load_and_swap(map->data())); +} + +bool StfsContainerDevice::ResolveFromFolder(const std::filesystem::path& path) { + // Scan through folders until a file with magic is found + std::queue queue; + + filesystem::FileInfo folder; + filesystem::GetInfo(host_path_, &folder); + queue.push(folder); + + while (!queue.empty()) { + auto current_file = queue.front(); + queue.pop(); + + if (current_file.type == filesystem::FileInfo::Type::kDirectory) { + auto path = current_file.path / current_file.name; + auto child_files = filesystem::ListFiles(path); + for (auto file : child_files) { + queue.push(file); + } + } else { + // Try to read the file's magic + auto path = current_file.path / current_file.name; + auto magic = ReadMagic(path); + + if (magic == XContentPackageType::kCon || magic == XContentPackageType::kLive || + magic == XContentPackageType::kPirs) { + host_path_ = current_file.path / current_file.name; + REXFS_INFO("STFS Package found: {}", rex::path_to_utf8(host_path_)); + return true; + } + } + } + + if (host_path_ == path) { + // Could not find a suitable container file + return false; + } + return true; +} + +} // namespace rex::filesystem diff --git a/src/filesystem/devices/stfs_container_entry.cpp b/src/filesystem/devices/stfs_container_entry.cpp new file mode 100644 index 0000000..8535944 --- /dev/null +++ b/src/filesystem/devices/stfs_container_entry.cpp @@ -0,0 +1,41 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include + +#include + +namespace rex::filesystem { + +StfsContainerEntry::StfsContainerEntry(Device* device, Entry* parent, const std::string_view path, + MultiFileHandles* files) + : Entry(device, parent, path), files_(files), data_offset_(0), data_size_(0), block_(0) {} + +StfsContainerEntry::~StfsContainerEntry() = default; + +std::unique_ptr StfsContainerEntry::Create(Device* device, Entry* parent, + const std::string_view name, + MultiFileHandles* files) { + auto path = rex::string::utf8_join_guest_paths(parent->path(), name); + auto entry = std::make_unique(device, parent, path, files); + + return std::move(entry); +} + +X_STATUS StfsContainerEntry::Open(uint32_t desired_access, File** out_file) { + *out_file = new StfsContainerFile(desired_access, this); + return X_STATUS_SUCCESS; +} + +} // namespace rex::filesystem diff --git a/src/filesystem/devices/stfs_container_file.cpp b/src/filesystem/devices/stfs_container_file.cpp new file mode 100644 index 0000000..0dd13f3 --- /dev/null +++ b/src/filesystem/devices/stfs_container_file.cpp @@ -0,0 +1,69 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include + +#include + +namespace rex::filesystem { + +StfsContainerFile::StfsContainerFile(uint32_t file_access, StfsContainerEntry* entry) + : File(file_access, entry), entry_(entry) {} + +StfsContainerFile::~StfsContainerFile() = default; + +void StfsContainerFile::Destroy() { + delete this; +} + +X_STATUS StfsContainerFile::ReadSync(std::span buffer, size_t byte_offset, + size_t* out_bytes_read) { + if (byte_offset >= entry_->size()) { + return X_STATUS_END_OF_FILE; + } + + size_t src_offset = 0; + uint8_t* p = buffer.data(); + size_t remaining_length = std::min(buffer.size(), entry_->size() - byte_offset); + + *out_bytes_read = 0; + for (size_t i = 0; i < entry_->block_list().size(); i++) { + auto& record = entry_->block_list()[i]; + if (src_offset + record.length <= byte_offset) { + // Doesn't begin in this region. Skip it. + src_offset += record.length; + continue; + } + + size_t read_offset = (byte_offset > src_offset) ? byte_offset - src_offset : 0; + size_t read_length = std::min(record.length - read_offset, remaining_length); + + auto& file = entry_->files()->at(record.file); + rex::filesystem::Seek(file, record.offset + read_offset, SEEK_SET); + auto num_read = fread(p, 1, read_length, file); + + *out_bytes_read += num_read; + p += num_read; + src_offset += record.length; + remaining_length -= read_length; + if (remaining_length == 0) { + break; + } + } + + return X_STATUS_SUCCESS; +} + +} // namespace rex::filesystem diff --git a/src/filesystem/entry.cpp b/src/filesystem/entry.cpp new file mode 100644 index 0000000..850e00e --- /dev/null +++ b/src/filesystem/entry.cpp @@ -0,0 +1,156 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include + +namespace rex::filesystem { + +Entry::Entry(Device* device, Entry* parent, const std::string_view path) + : device_(device), + parent_(parent), + path_(path), + attributes_(0), + size_(0), + allocation_size_(0), + create_timestamp_(0), + access_timestamp_(0), + write_timestamp_(0) { + assert_not_null(device); + absolute_path_ = rex::string::utf8_join_guest_paths(device->mount_path(), path); + name_ = rex::string::utf8_find_name_from_guest_path(path); +} + +Entry::~Entry() = default; + +void Entry::Dump(rex::string::StringBuffer* string_buffer, int indent) { + for (int i = 0; i < indent; ++i) { + string_buffer->Append(' '); + } + string_buffer->Append(name()); + string_buffer->Append('\n'); + for (auto& child : children_) { + child->Dump(string_buffer, indent + 2); + } +} + +bool Entry::is_read_only() const { + return device_->is_read_only(); +} + +Entry* Entry::GetChild(const std::string_view name) { + auto global_lock = global_critical_region_.Acquire(); + auto it = std::find_if(children_.cbegin(), children_.cend(), [&](const auto& child) { + return rex::string::utf8_equal_case(child->name(), name); + }); + if (it == children_.cend()) { + return nullptr; + } + return (*it).get(); +} + +Entry* Entry::ResolvePath(const std::string_view path) { + // Walk the path, one separator at a time. + Entry* entry = this; + for (auto& part : rex::string::utf8_split_path(path)) { + entry = entry->GetChild(part); + if (!entry) { + // Not found. + return nullptr; + } + } + return entry; +} + +Entry* Entry::IterateChildren(const rex::filesystem::WildcardEngine& engine, + size_t* current_index) { + auto global_lock = global_critical_region_.Acquire(); + while (*current_index < children_.size()) { + auto& child = children_[*current_index]; + *current_index = *current_index + 1; + if (engine.Match(child->name())) { + return child.get(); + } + } + return nullptr; +} + +Entry* Entry::CreateEntry(const std::string_view name, uint32_t attributes) { + auto global_lock = global_critical_region_.Acquire(); + if (is_read_only()) { + return nullptr; + } + if (GetChild(name)) { + // Already exists. + return nullptr; + } + auto entry = CreateEntryInternal(name, attributes); + if (!entry) { + return nullptr; + } + children_.push_back(std::move(entry)); + // TODO(benvanik): resort? would break iteration? + Touch(); + return children_.back().get(); +} + +bool Entry::Delete(Entry* entry) { + auto global_lock = global_critical_region_.Acquire(); + if (is_read_only()) { + return false; + } + if (entry->parent() != this) { + return false; + } + if (!DeleteEntryInternal(entry)) { + return false; + } + for (auto it = children_.begin(); it != children_.end(); ++it) { + if (it->get() == entry) { + children_.erase(it); + break; + } + } + Touch(); + return true; +} + +bool Entry::Delete() { + assert_not_null(parent_); + return parent_->Delete(this); +} + +void Entry::Rename(const std::filesystem::path& file_path) { + // Store the string so split path string_views remain valid. + const std::string path_str = rex::path_to_utf8(file_path); + std::vector path_parts = rex::string::utf8_split_path(path_str); + if (!path_parts.empty()) { + // Drop root path (for example, "game:"). + path_parts.erase(path_parts.begin()); + } + + RenameEntryInternal(path_parts); + + const std::string guest_path = rex::string::utf8_join_guest_paths(path_parts); + absolute_path_ = rex::string::utf8_join_guest_paths(device_->mount_path(), guest_path); + path_ = guest_path; + name_ = rex::path_to_utf8(file_path.filename()); +} + +void Entry::Touch() { + // TODO(benvanik): update timestamps. +} + +} // namespace rex::filesystem diff --git a/src/filesystem/vfs_dump.cpp b/src/filesystem/vfs_dump.cpp new file mode 100644 index 0000000..b83fc1c --- /dev/null +++ b/src/filesystem/vfs_dump.cpp @@ -0,0 +1,119 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_STRING(dump_source, "", "Filesystem", "Specifies the file to dump from"); + +REXCVAR_DEFINE_STRING(dump_path, "", "Filesystem", "Specifies the directory to dump files to"); + +namespace rex::filesystem { + +using namespace rex::literals; + +int vfs_dump_main(const std::vector& args) { + if (REXCVAR_GET(dump_source).empty() || REXCVAR_GET(dump_path).empty()) { + REXFS_ERROR("Usage: {} [source] [dump_path]", rex::path_to_utf8(args[0])); + return 1; + } + + std::filesystem::path source = rex::to_path(REXCVAR_GET(dump_source)); + std::filesystem::path base_path = rex::to_path(REXCVAR_GET(dump_path)); + std::unique_ptr device; + + // TODO: Flags specifying the type of device. + device = std::make_unique("", source); + if (!device->Initialize()) { + REXFS_ERROR("Failed to initialize device"); + return 1; + } + + // Run through all the files, breadth-first style. + std::queue queue; + auto root = device->ResolvePath("/"); + queue.push(root); + + // Allocate a buffer when needed. + size_t buffer_size = 0; + uint8_t* buffer = nullptr; + + while (!queue.empty()) { + auto entry = queue.front(); + queue.pop(); + for (auto& entry : entry->children()) { + queue.push(entry.get()); + } + + REXFS_INFO("{}", entry->path()); + auto dest_name = base_path / rex::to_path(entry->path()); + if (entry->attributes() & kFileAttributeDirectory) { + std::filesystem::create_directories(dest_name); + continue; + } + + vfs::File* in_file = nullptr; + if (entry->Open(FileAccess::kFileReadData, &in_file) != X_STATUS_SUCCESS) { + continue; + } + + auto file = rex::filesystem::OpenFile(dest_name, "wb"); + if (!file) { + in_file->Destroy(); + continue; + } + + if (entry->can_map()) { + auto map = entry->OpenMapped(rex::memory::MappedMemory::Mode::kRead); + fwrite(map->data(), map->size(), 1, file); + map->Close(); + } else { + // Can't map the file into memory. Read it into a temporary buffer. + if (!buffer || entry->size() > buffer_size) { + // Resize the buffer. + if (buffer) { + delete[] buffer; + } + + // Allocate a buffer rounded up to the nearest 512MB. + buffer_size = rex::round_up(entry->size(), 512_MiB); + buffer = new uint8_t[buffer_size]; + } + + size_t bytes_read = 0; + in_file->ReadSync(std::span(buffer, entry->size()), 0, &bytes_read); + fwrite(buffer, bytes_read, 1, file); + } + + fclose(file); + in_file->Destroy(); + } + + if (buffer) { + delete[] buffer; + } + + return 0; +} + +} // namespace rex::filesystem + +// TODO: CONSOLE APP - XE_DEFINE_CONSOLE_APP("xenia-vfs-dump", rex::filesystem::vfs_dump_main, +// "[source] [dump_path]", "source", "dump_path"); diff --git a/src/filesystem/virtual_file_system.cpp b/src/filesystem/virtual_file_system.cpp new file mode 100644 index 0000000..1460174 --- /dev/null +++ b/src/filesystem/virtual_file_system.cpp @@ -0,0 +1,336 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include + +REXCVAR_DEFINE_BOOL(allow_game_relative_writes, false, "Filesystem", + "Not useful to non-developers. Allows code to write to paths " + "relative to game://. Used for " + "generating test data to compare with original hardware."); + +namespace rex::filesystem { + +VirtualFileSystem::VirtualFileSystem() {} + +VirtualFileSystem::~VirtualFileSystem() { + // Delete all devices. + // This will explode if anyone is still using data from them. + devices_.clear(); + symlinks_.clear(); +} + +bool VirtualFileSystem::RegisterDevice(std::unique_ptr device) { + auto global_lock = global_critical_region_.Acquire(); + devices_.emplace_back(std::move(device)); + return true; +} + +bool VirtualFileSystem::UnregisterDevice(const std::string_view path) { + auto global_lock = global_critical_region_.Acquire(); + for (auto it = devices_.begin(); it != devices_.end(); ++it) { + if ((*it)->mount_path() == path) { + REXFS_DEBUG("Unregistered device: {}", (*it)->mount_path()); + devices_.erase(it); + return true; + } + } + return false; +} + +bool VirtualFileSystem::RegisterSymbolicLink(const std::string_view path, + const std::string_view target) { + auto global_lock = global_critical_region_.Acquire(); + symlinks_.insert({std::string(path), std::string(target)}); + REXFS_DEBUG("Registered symbolic link: {} => {}", path, target); + + return true; +} + +bool VirtualFileSystem::UnregisterSymbolicLink(const std::string_view path) { + auto global_lock = global_critical_region_.Acquire(); + auto it = std::find_if(symlinks_.cbegin(), symlinks_.cend(), [&](const auto& s) { + return rex::string::utf8_equal_case(path, s.first); + }); + if (it == symlinks_.end()) { + return false; + } + REXFS_DEBUG("Unregistered symbolic link: {} => {}", it->first, it->second); + + symlinks_.erase(it); + return true; +} + +bool VirtualFileSystem::FindSymbolicLink(const std::string_view path, std::string& target) { + auto it = std::find_if(symlinks_.cbegin(), symlinks_.cend(), [&](const auto& s) { + return rex::string::utf8_starts_with_case(path, s.first); + }); + if (it == symlinks_.cend()) { + return false; + } + target = (*it).second; + return true; +} + +bool VirtualFileSystem::ResolveSymbolicLink(const std::string_view path, std::string& result) { + result = path; + bool was_resolved = false; + while (true) { + auto it = std::find_if(symlinks_.cbegin(), symlinks_.cend(), [&](const auto& s) { + return rex::string::utf8_starts_with_case(result, s.first); + }); + if (it == symlinks_.cend()) { + break; + } + // Found symlink! + auto target_path = (*it).second; + auto relative_path = result.substr((*it).first.size()); + result = target_path + relative_path; + was_resolved = true; + } + return was_resolved; +} + +Entry* VirtualFileSystem::ResolvePath(const std::string_view path) { + auto global_lock = global_critical_region_.Acquire(); + + // Resolve relative paths + auto normalized_path(rex::string::utf8_canonicalize_guest_path(path)); + + // Resolve symlinks. + std::string resolved_path; + bool had_symlink = ResolveSymbolicLink(normalized_path, resolved_path); + if (had_symlink) { + normalized_path = resolved_path; + } + + // Find the device. + auto it = std::find_if(devices_.cbegin(), devices_.cend(), [&](const auto& d) { + return rex::string::utf8_starts_with_case(normalized_path, d->mount_path()); + }); + if (it == devices_.cend()) { + REXFS_WARN("VFS: '{}' -> [no device]", path); + // Supress logging the error for ShaderDumpxe:\CompareBackEnds as this is + // not an actual problem nor something we care about. + if (path != "ShaderDumpxe:\\CompareBackEnds") { + REXFS_ERROR("ResolvePath({}) failed - device not found", path); + } + return nullptr; + } + + const auto& device = *it; + auto relative_path = normalized_path.substr(device->mount_path().size()); + auto* entry = device->ResolvePath(relative_path); + + if (entry) { + if (had_symlink) { + REXFS_TRACE("VFS resolved '{}' via symlink '{}' on device '{}' -> '{}'", path, + normalized_path, device->mount_path(), entry->absolute_path()); + } else { + REXFS_TRACE("VFS resolved '{}' on device '{}' -> '{}'", path, device->mount_path(), + entry->absolute_path()); + } + } else { + if (had_symlink) { + REXFS_WARN("VFS: entry not found for '{}' (via symlink '{}') on device '{}'", path, + normalized_path, device->mount_path()); + } else { + REXFS_WARN("VFS: entry not found for '{}' on device '{}'", path, device->mount_path()); + } + } + + return entry; +} + +Entry* VirtualFileSystem::CreatePath(const std::string_view path, uint32_t attributes) { + // Create all required directories recursively. + auto path_parts = rex::string::utf8_split_path(path); + if (path_parts.empty()) { + return nullptr; + } + auto partial_path = std::string(path_parts[0]); + auto partial_entry = ResolvePath(partial_path); + if (!partial_entry) { + return nullptr; + } + auto parent_entry = partial_entry; + for (size_t i = 1; i < path_parts.size() - 1; ++i) { + partial_path = rex::string::utf8_join_guest_paths(partial_path, path_parts[i]); + auto child_entry = ResolvePath(partial_path); + if (!child_entry) { + child_entry = parent_entry->CreateEntry(path_parts[i], kFileAttributeDirectory); + } + if (!child_entry) { + return nullptr; + } + parent_entry = child_entry; + } + return parent_entry->CreateEntry(path_parts[path_parts.size() - 1], attributes); +} + +bool VirtualFileSystem::DeletePath(const std::string_view path) { + auto entry = ResolvePath(path); + if (!entry) { + return false; + } + auto parent = entry->parent(); + if (!parent) { + // Can't delete root. + return false; + } + return parent->Delete(entry); +} + +X_STATUS VirtualFileSystem::OpenFile(Entry* root_entry, const std::string_view path, + FileDisposition creation_disposition, uint32_t desired_access, + bool is_directory, bool is_non_directory, File** out_file, + FileAction* out_action) { + // TODO(gibbed): should 'is_directory' remain as a bool or should it be + // flipped to a generic FileAttributeFlags? + + // Cleanup access. + if (desired_access & FileAccess::kGenericRead) { + desired_access |= FileAccess::kFileReadData; + } + if (desired_access & FileAccess::kGenericWrite) { + desired_access |= FileAccess::kFileWriteData; + } + if (desired_access & FileAccess::kGenericAll) { + desired_access |= FileAccess::kFileReadData | FileAccess::kFileWriteData; + } + + // Lookup host device/parent path. + // If no device or parent, fail. + Entry* parent_entry = nullptr; + Entry* entry = nullptr; + + auto base_path = rex::string::utf8_find_base_guest_path(path); + if (!base_path.empty()) { + parent_entry = !root_entry ? ResolvePath(base_path) : root_entry->ResolvePath(base_path); + if (!parent_entry) { + *out_action = FileAction::kDoesNotExist; + return X_STATUS_NO_SUCH_FILE; + } + + auto file_name = rex::string::utf8_find_name_from_guest_path(path); + entry = parent_entry->GetChild(file_name); + } else { + entry = !root_entry ? ResolvePath(path) : root_entry->GetChild(path); + } + + if (entry) { + if (entry->attributes() & kFileAttributeDirectory && is_non_directory) { + return X_STATUS_FILE_IS_A_DIRECTORY; + } + + // If the cached entry does not exist on host anymore, invalidate it. + if (parent_entry) { + const auto* host_path_entry = dynamic_cast(parent_entry); + if (host_path_entry) { + const auto file_path = host_path_entry->host_path() / rex::to_path(entry->name()); + if (!std::filesystem::exists(file_path)) { + entry->Delete(); + entry = nullptr; + } + } + } + } + + // Check if exists (if we need it to), or that it doesn't (if it shouldn't). + switch (creation_disposition) { + case FileDisposition::kOpen: + case FileDisposition::kOverwrite: + // Must exist. + if (!entry) { + *out_action = FileAction::kDoesNotExist; + return X_STATUS_NO_SUCH_FILE; + } + break; + case FileDisposition::kCreate: + // Must not exist. + if (entry) { + *out_action = FileAction::kExists; + return X_STATUS_OBJECT_NAME_COLLISION; + } + break; + default: + // Either way, ok. + break; + } + + // Verify permissions. + bool wants_write = + desired_access & FileAccess::kFileWriteData || desired_access & FileAccess::kFileAppendData; + if (wants_write && + ((parent_entry && parent_entry->is_read_only()) || (entry && entry->is_read_only()))) { + // Match Xenia behavior: downgrade to read access instead of failing. + REXFS_WARN("Attempted to open read-only file/dir for write: {}", path); + desired_access = FileAccess::kGenericRead | FileAccess::kFileReadData; + } + + bool created = false; + if (!entry) { + // Remember that we are creating this new, instead of replacing. + created = true; + *out_action = FileAction::kCreated; + } else { + // May need to delete, if it exists. + switch (creation_disposition) { + case FileDisposition::kCreate: + // Shouldn't be possible to hit this. + assert_always(); + return X_STATUS_ACCESS_DENIED; + case FileDisposition::kSuperscede: + // Replace (by delete + recreate). + if (!entry->Delete()) { + return X_STATUS_ACCESS_DENIED; + } + entry = nullptr; + *out_action = FileAction::kSuperseded; + break; + case FileDisposition::kOpen: + case FileDisposition::kOpenIf: + // Normal open. + *out_action = FileAction::kOpened; + break; + case FileDisposition::kOverwrite: + case FileDisposition::kOverwriteIf: + // Overwrite by delete + recreate, or truncate if delete fails + // (host file may be briefly locked by cloud sync, AV, etc.). + if (entry->Delete()) { + entry = nullptr; + } else if (!entry->Truncate()) { + return X_STATUS_ACCESS_DENIED; + } + *out_action = FileAction::kOverwritten; + break; + } + } + if (!entry) { + // Create if needed (either new or as a replacement). + entry = CreatePath(path, !is_directory ? kFileAttributeNormal : kFileAttributeDirectory); + if (!entry) { + return X_STATUS_ACCESS_DENIED; + } + } + + // Open. + auto result = entry->Open(desired_access, out_file); + if (XFAILED(result)) { + *out_action = FileAction::kDoesNotExist; + } + return result; +} + +} // namespace rex::filesystem diff --git a/src/graphics/CMakeLists.txt b/src/graphics/CMakeLists.txt new file mode 100644 index 0000000..8e898b6 --- /dev/null +++ b/src/graphics/CMakeLists.txt @@ -0,0 +1,151 @@ +# rexgraphics: GPU emulation core (ported from Xenia) +# Namespace: rex::graphics + +# Core GPU types - minimal dependencies, fully ported +set(REXGRAPHICS_CORE_SOURCES + flags.cpp + xenos.cpp + pipeline/texture/info.cpp + pipeline/texture/info_formats.cpp + register_file.cpp + registers.cpp + pipeline/shader/shader.cpp + format/ucode.cpp + sampler_info.cpp +) + +# GPU system files - full backend +set(REXGRAPHICS_SYSTEM_SOURCES + graphics_system.cpp + command_processor.cpp + trace_writer.cpp + pipeline/texture/extent.cpp + pipeline/texture/util.cpp + util/draw_extent_estimator.cpp + util/draw.cpp + packet_disassembler.cpp + primitive_processor.cpp + pipeline/render_target/cache.cpp + shared_memory.cpp + pipeline/texture/cache.cpp + pipeline/texture/conversion.cpp + pipeline/shader/interpreter.cpp + pipeline/shader/translator.cpp + pipeline/shader/translator_disasm.cpp +) + +# SPIR-V shader translation +set(REXGRAPHICS_SPIRV_SOURCES + pipeline/shader/spirv_builder.cpp + pipeline/shader/spirv.cpp + pipeline/shader/spirv_translator.cpp + pipeline/shader/spirv_translator_alu.cpp + pipeline/shader/spirv_translator_fetch.cpp + pipeline/shader/spirv_translator_memexport.cpp + pipeline/shader/spirv_translator_rb.cpp +) + +# Vulkan backend +set(REXGRAPHICS_VULKAN_SOURCES + vulkan/graphics_system.cpp + vulkan/deferred_command_buffer.cpp + vulkan/command_processor.cpp + vulkan/pipeline_cache.cpp + vulkan/primitive_processor.cpp + vulkan/render_target_cache.cpp + vulkan/shader.cpp + vulkan/shared_memory.cpp + vulkan/texture_cache.cpp +) + +# D3D12 backend +if(REXGLUE_USE_D3D12) + # DXBC third-party dependency + set(REXGRAPHICS_DXBC_THIRDPARTY_SOURCES + ${REXGLUE_ROOT}/thirdparty/dxbc/DXBCChecksum.cpp + ) + + # DXBC shader translation (required for D3D12) + set(REXGRAPHICS_DXBC_SOURCES + pipeline/shader/dxbc.cpp + pipeline/shader/dxbc_translator.cpp + pipeline/shader/dxbc_translator_alu.cpp + pipeline/shader/dxbc_translator_fetch.cpp + pipeline/shader/dxbc_translator_memexport.cpp + pipeline/shader/dxbc_translator_om.cpp + ) + + # D3D12 GPU backend + set(REXGRAPHICS_D3D12_SOURCES + d3d12/graphics_system.cpp + d3d12/command_processor.cpp + d3d12/primitive_processor.cpp + d3d12/render_target_cache.cpp + d3d12/shader.cpp + d3d12/shared_memory.cpp + d3d12/texture_cache.cpp + d3d12/deferred_command_list.cpp + d3d12/pipeline_cache.cpp + ) +endif() + +# Combine sources +set(REXGRAPHICS_SOURCES + ${REXGRAPHICS_CORE_SOURCES} + ${REXGRAPHICS_SYSTEM_SOURCES} +) + +if(REXGLUE_USE_VULKAN) + list(APPEND REXGRAPHICS_SOURCES ${REXGRAPHICS_SPIRV_SOURCES} ${REXGRAPHICS_VULKAN_SOURCES}) +endif() + +if(REXGLUE_USE_D3D12) + list(APPEND REXGRAPHICS_SOURCES ${REXGRAPHICS_DXBC_THIRDPARTY_SOURCES} ${REXGRAPHICS_DXBC_SOURCES} ${REXGRAPHICS_D3D12_SOURCES}) +endif() + +add_library(rexgraphics OBJECT ${REXGRAPHICS_SOURCES}) +add_library(rex::graphics ALIAS rexgraphics) + +target_include_directories(rexgraphics PUBLIC + $ + $ +) +target_include_directories(rexgraphics PRIVATE + ${REXGLUE_ROOT}/thirdparty/renderdoc + ${REXGLUE_ROOT} # For thirdparty/dxbc/DXBCChecksum.h include +) + +target_compile_options(rexgraphics PRIVATE -Wno-unused-variable) + +target_link_libraries(rexgraphics PUBLIC + rexcore + rexui + xxHash::xxhash + snappy +) + +if(REXGLUE_USE_VULKAN) + target_link_libraries(rexgraphics PUBLIC + volk::volk + glslang::SPIRV + GPUOpen::VulkanMemoryAllocator + ) + target_link_libraries(rexgraphics PRIVATE + glslang + MachineIndependent + GenericCodeGen + OSDependent + OGLCompiler + ) + target_compile_definitions(rexgraphics PUBLIC REX_HAS_VULKAN=1) +endif() + +if(REXGLUE_USE_D3D12) + target_link_libraries(rexgraphics PUBLIC + d3d12 + dxgi + dxguid + ) + target_compile_definitions(rexgraphics PUBLIC REX_HAS_D3D12=1) +endif() + diff --git a/src/graphics/command_processor.cpp b/src/graphics/command_processor.cpp new file mode 100644 index 0000000..60efcd3 --- /dev/null +++ b/src/graphics/command_processor.cpp @@ -0,0 +1,1775 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(vsync, true, "GPU", "Enable vertical sync"); + +REXCVAR_DEFINE_BOOL(clear_memory_page_state, true, "GPU", + "Refresh page-valid state from GPU-written memory at frame end. " + "Disable for minor CPU overhead reduction, but may break memory coherency.") + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +REXCVAR_DEFINE_BOOL(occlusion_query_enable, true, "GPU", "Enable host occlusion query handling") + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +REXCVAR_DEFINE_STRING(readback_resolve, "none", "GPU", + "Controls CPU readback of render-to-texture resolve results.\n" + " none: Disable readback (default)\n" + " fast: Read previous frame (delayed, copy every frame)\n" + " some: Read previous frame (delayed, copy on cache miss)\n" + " full: Immediate sync readback (accurate but stalls)") + .allowed({"none", "fast", "some", "full"}) + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +REXCVAR_DEFINE_BOOL(readback_resolve_half_pixel_offset, false, "GPU", + "When draw resolution scaling is active, sample from the center of each " + "scaled block during resolve readback downscale") + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +REXCVAR_DEFINE_BOOL(readback_memexport, true, "GPU", + "Enable CPU readback of shader memexport writes for guest memory " + "coherency (can reduce correctness issues, but may add GPU/CPU sync cost)") + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +REXCVAR_DEFINE_BOOL(readback_memexport_fast, true, "GPU", + "Use fast double-buffered memexport readback when possible, with " + "automatic fallback to full synchronous readback") + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +REXCVAR_DEFINE_INT32(query_occlusion_fake_sample_count, 1000, "GPU", + "Fake sample count for occlusion queries") + .range(1, 100000) + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +REXCVAR_DEFINE_BOOL(async_shader_compilation, true, "GPU", + "Compile shaders and create pipelines asynchronously in background " + "threads. This reduces stutter but may cause brief visual artifacts while " + "pipelines are being prepared.") + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +namespace rex::graphics { + +using namespace rex::graphics::xenos; + +namespace { + +ReadbackResolveMode ParseReadbackResolveMode(std::string_view value) { + if (value == "fast") { + return ReadbackResolveMode::kFast; + } + if (value == "some") { + return ReadbackResolveMode::kSome; + } + if (value == "full") { + return ReadbackResolveMode::kFull; + } + return ReadbackResolveMode::kDisabled; +} + +} // namespace + +CommandProcessor::CommandProcessor(GraphicsSystem* graphics_system, + system::KernelState* kernel_state) + : memory_(graphics_system->memory()), + kernel_state_(kernel_state), + graphics_system_(graphics_system), + register_file_(graphics_system_->register_file()), + trace_writer_(graphics_system->memory()->physical_membase()), + worker_running_(true), + write_ptr_index_event_(rex::thread::Event::CreateAutoResetEvent(false)), + write_ptr_index_(0) { + assert_not_null(write_ptr_index_event_); +} + +CommandProcessor::~CommandProcessor() = default; + +bool CommandProcessor::Initialize() { + // Initialize the gamma ramps to their default (linear) values - taken from + // what games set when starting with the sRGB (return value 1) + // VdGetCurrentDisplayGamma. + for (uint32_t i = 0; i < 256; ++i) { + uint32_t value = i * 0x3FF / 0xFF; + reg::DC_LUT_30_COLOR& gamma_ramp_entry = gamma_ramp_256_entry_table_[i]; + gamma_ramp_entry.color_10_blue = value; + gamma_ramp_entry.color_10_green = value; + gamma_ramp_entry.color_10_red = value; + } + for (uint32_t i = 0; i < 128; ++i) { + reg::DC_LUT_PWL_DATA gamma_ramp_entry = {}; + gamma_ramp_entry.base = (i * 0xFFFF / 0x7F) & ~UINT32_C(0x3F); + gamma_ramp_entry.delta = i < 0x7F ? 0x200 : 0; + for (uint32_t j = 0; j < 3; ++j) { + gamma_ramp_pwl_rgb_[i][j] = gamma_ramp_entry; + } + } + + worker_running_ = true; + worker_thread_ = system::object_ref( + new system::XHostThread(kernel_state_, 128 * 1024, 0, [this]() { + WorkerThreadMain(); + return 0; + })); + worker_thread_->set_name("GPU Commands"); + worker_thread_->Create(); + + return true; +} + +void CommandProcessor::Shutdown() { + EndTracing(); + + worker_running_ = false; + write_ptr_index_event_->Set(); + worker_thread_->Wait(0, 0, 0, nullptr); + worker_thread_.reset(); +} + +void CommandProcessor::InitializeShaderStorage(const std::filesystem::path& cache_root, + uint32_t title_id, bool blocking) {} + +void CommandProcessor::RequestFrameTrace(const std::filesystem::path& root_path) { + if (trace_state_ == TraceState::kStreaming) { + REXGPU_ERROR("Streaming trace; cannot also trace frame."); + return; + } + if (trace_state_ == TraceState::kSingleFrame) { + REXGPU_ERROR("Frame trace already pending; ignoring."); + return; + } + trace_state_ = TraceState::kSingleFrame; + trace_frame_path_ = root_path; +} + +void CommandProcessor::BeginTracing(const std::filesystem::path& root_path) { + if (trace_state_ == TraceState::kStreaming) { + REXGPU_ERROR("Streaming already active; ignoring request."); + return; + } + if (trace_state_ == TraceState::kSingleFrame) { + REXGPU_ERROR("Frame trace pending; ignoring streaming request."); + return; + } + // Streaming starts on the next primary buffer execute. + trace_state_ = TraceState::kStreaming; + trace_stream_path_ = root_path; +} + +void CommandProcessor::EndTracing() { + if (!trace_writer_.is_open()) { + return; + } + assert_true(trace_state_ == TraceState::kStreaming); + trace_state_ = TraceState::kDisabled; + trace_writer_.Close(); +} + +void CommandProcessor::RestoreRegisters(uint32_t first_register, const uint32_t* register_values, + uint32_t register_count, bool execute_callbacks) { + if (first_register > RegisterFile::kRegisterCount || + RegisterFile::kRegisterCount - first_register < register_count) { + REXGPU_WARN( + "CommandProcessor::RestoreRegisters out of bounds (0x{:X} registers " + "starting with 0x{:X}, while a total of 0x{:X} registers are stored)", + register_count, first_register, RegisterFile::kRegisterCount); + if (first_register > RegisterFile::kRegisterCount) { + return; + } + register_count = + std::min(uint32_t(RegisterFile::kRegisterCount) - first_register, register_count); + } + if (execute_callbacks) { + for (uint32_t i = 0; i < register_count; ++i) { + WriteRegister(first_register + i, register_values[i]); + } + } else { + std::memcpy(register_file_->values + first_register, register_values, + sizeof(uint32_t) * register_count); + } +} + +void CommandProcessor::RestoreGammaRamp(const reg::DC_LUT_30_COLOR* new_gamma_ramp_256_entry_table, + const reg::DC_LUT_PWL_DATA* new_gamma_ramp_pwl_rgb, + uint32_t new_gamma_ramp_rw_component) { + std::memcpy(gamma_ramp_256_entry_table_, new_gamma_ramp_256_entry_table, + sizeof(reg::DC_LUT_30_COLOR) * 256); + std::memcpy(gamma_ramp_pwl_rgb_, new_gamma_ramp_pwl_rgb, sizeof(reg::DC_LUT_PWL_DATA) * 3 * 128); + gamma_ramp_rw_component_ = new_gamma_ramp_rw_component; + OnGammaRamp256EntryTableValueWritten(); + OnGammaRampPWLValueWritten(); +} + +void CommandProcessor::CallInThread(std::function fn) { + if (pending_fns_.empty() && system::XThread::IsInThread(worker_thread_.get())) { + fn(); + } else { + pending_fns_.push(std::move(fn)); + } +} + +void CommandProcessor::ClearCaches() {} + +void CommandProcessor::InvalidateGpuMemory() {} + +ReadbackResolveMode CommandProcessor::GetReadbackResolveMode( + bool legacy_readback_resolve_enabled) const { + ReadbackResolveMode shared_mode = ParseReadbackResolveMode(REXCVAR_GET(readback_resolve)); + bool shared_mode_overrides_legacy = shared_mode != ReadbackResolveMode::kDisabled || + rex::cvar::HasNonDefaultValue("readback_resolve"); + if (shared_mode_overrides_legacy) { + return shared_mode; + } + return legacy_readback_resolve_enabled ? ReadbackResolveMode::kFast + : ReadbackResolveMode::kDisabled; +} + +bool CommandProcessor::IsReadbackMemexportEnabled(bool legacy_backend_flag) const { + if (legacy_readback_memexport_cvar_name_ && + rex::cvar::HasNonDefaultValue(legacy_readback_memexport_cvar_name_)) { + return legacy_backend_flag; + } + return REXCVAR_GET(readback_memexport); +} + +void CommandProcessor::SetDesiredSwapPostEffect(SwapPostEffect swap_post_effect) { + if (swap_post_effect_desired_ == swap_post_effect) { + return; + } + swap_post_effect_desired_ = swap_post_effect; + CallInThread([this, swap_post_effect]() { swap_post_effect_actual_ = swap_post_effect; }); +} + +void CommandProcessor::WorkerThreadMain() { + if (!SetupContext()) { + rex::FatalError("Unable to setup command processor internal state"); + return; + } + + while (worker_running_) { + while (!pending_fns_.empty()) { + auto fn = std::move(pending_fns_.front()); + pending_fns_.pop(); + fn(); + } + + uint32_t write_ptr_index = write_ptr_index_.load(); + if (write_ptr_index == 0xBAADF00D || read_ptr_index_ == write_ptr_index) { + SCOPE_profile_cpu_i("gpu", "rex::graphics::CommandProcessor::Stall"); + // We've run out of commands to execute. + // We spin here waiting for new ones, as the overhead of waiting on our + // event is too high. + PrepareForWait(); + uint32_t loop_count = 0; + do { + // If we spin around too much, revert to a "low-power" state. + if (loop_count > 500) { + const int wait_time_ms = 5; + rex::thread::Wait(write_ptr_index_event_.get(), true, + std::chrono::milliseconds(wait_time_ms)); + } + + rex::thread::MaybeYield(); + loop_count++; + write_ptr_index = write_ptr_index_.load(); + } while (worker_running_ && pending_fns_.empty() && + (write_ptr_index == 0xBAADF00D || read_ptr_index_ == write_ptr_index)); + ReturnFromWait(); + if (!worker_running_ || !pending_fns_.empty()) { + continue; + } + } + assert_true(read_ptr_index_ != write_ptr_index); + + // Execute. Note that we handle wraparound transparently. + read_ptr_index_ = ExecutePrimaryBuffer(read_ptr_index_, write_ptr_index); + + // TODO(benvanik): use reader->Read_update_freq_ and only issue after moving + // that many indices. + if (read_ptr_writeback_ptr_) { + memory::store_and_swap(memory_->TranslatePhysical(read_ptr_writeback_ptr_), + read_ptr_index_); + } + + // FIXME: We're supposed to process the WAIT_UNTIL register at this point, + // but no games seem to actually use it. + } + + ShutdownContext(); +} + +void CommandProcessor::Pause() { + if (paused_) { + return; + } + paused_ = true; + + thread::Fence fence; + CallInThread([&fence]() { + fence.Signal(); + thread::Thread::GetCurrentThread()->Suspend(); + }); + + fence.Wait(); +} + +void CommandProcessor::Resume() { + if (!paused_) { + return; + } + paused_ = false; + + worker_thread_->thread()->Resume(); +} + +bool CommandProcessor::Save(::rex::stream::ByteStream* stream) { + assert_true(paused_); + + stream->Write(primary_buffer_ptr_); + stream->Write(primary_buffer_size_); + stream->Write(read_ptr_index_); + stream->Write(read_ptr_update_freq_); + stream->Write(read_ptr_writeback_ptr_); + stream->Write(write_ptr_index_.load()); + + return true; +} + +bool CommandProcessor::Restore(::rex::stream::ByteStream* stream) { + assert_true(paused_); + + primary_buffer_ptr_ = stream->Read(); + primary_buffer_size_ = stream->Read(); + read_ptr_index_ = stream->Read(); + read_ptr_update_freq_ = stream->Read(); + read_ptr_writeback_ptr_ = stream->Read(); + write_ptr_index_.store(stream->Read()); + + return true; +} + +bool CommandProcessor::SetupContext() { + return true; +} + +void CommandProcessor::ShutdownContext() {} + +void CommandProcessor::InitializeRingBuffer(uint32_t ptr, uint32_t size_log2) { + read_ptr_index_ = 0; + primary_buffer_ptr_ = ptr; + primary_buffer_size_ = uint32_t(1) << (size_log2 + 3); +} + +void CommandProcessor::EnableReadPointerWriteBack(uint32_t ptr, uint32_t block_size_log2) { + // CP_RB_RPTR_ADDR Ring Buffer Read Pointer Address 0x70C + // ptr = RB_RPTR_ADDR, pointer to write back the address to. + read_ptr_writeback_ptr_ = ptr; + // CP_RB_CNTL Ring Buffer Control 0x704 + // block_size = RB_BLKSZ, log2 of number of quadwords read between updates of + // the read pointer. + read_ptr_update_freq_ = uint32_t(1) << block_size_log2 >> 2; +} + +void CommandProcessor::UpdateWritePointer(uint32_t value) { + write_ptr_index_ = value; + write_ptr_index_event_->Set(); +} + +uint32_t CommandProcessor::ReadRegisterValue(uint32_t index) const { + if (index < RegisterFile::kRegisterCount) { + return register_file_->values[index]; + } + auto it = extended_register_values_.find(index); + return it != extended_register_values_.end() ? it->second : 0; +} + +void CommandProcessor::WriteRegister(uint32_t index, uint32_t value) { + RegisterFile& regs = *register_file_; + if (index >= RegisterFile::kRegisterCount) { + auto [it, inserted] = extended_register_values_.insert_or_assign(index, value); + (void)it; + if (inserted) { + REXGPU_WARN( + "CommandProcessor::WriteRegister index out of bounds: {} (stored as extended register)", + index); + } + return; + } + + // Volatile for the WAIT_REG_MEM loop. + const_cast(regs.values[index]) = value; + if (!regs.GetRegisterInfo(index)) { + REXGPU_DEBUG("GPU: Write to unknown register ({:04X} = {:08X})", index, value); + } + + // Scratch register writeback. + if (index >= XE_GPU_REG_SCRATCH_REG0 && index <= XE_GPU_REG_SCRATCH_REG7) { + uint32_t scratch_reg = index - XE_GPU_REG_SCRATCH_REG0; + if ((1 << scratch_reg) & regs.values[XE_GPU_REG_SCRATCH_UMSK]) { + // Enabled - write to address. + uint32_t scratch_addr = regs.values[XE_GPU_REG_SCRATCH_ADDR]; + uint32_t mem_addr = scratch_addr + (scratch_reg * 4); + memory::store_and_swap(memory_->TranslatePhysical(mem_addr), value); + } + } else { + switch (index) { + // If this is a COHER register, set the dirty flag. + // This will block the command processor the next time it WAIT_REG_MEMs + // and allow us to synchronize the memory. + case XE_GPU_REG_COHER_STATUS_HOST: { + const_cast(regs.values[index]) |= UINT32_C(0x80000000); + } break; + + case XE_GPU_REG_DC_LUT_RW_INDEX: { + // Reset the sequential read / write component index (see the M56 + // DC_LUT_SEQ_COLOR documentation). + gamma_ramp_rw_component_ = 0; + } break; + + case XE_GPU_REG_DC_LUT_SEQ_COLOR: { + // Should be in the 256-entry table writing mode. + assert_zero(regs[XE_GPU_REG_DC_LUT_RW_MODE] & 0b1); + auto gamma_ramp_rw_index = regs.Get(); + // DC_LUT_SEQ_COLOR is in the red, green, blue order, but the write + // enable mask is blue, green, red. + bool write_gamma_ramp_component = (regs[XE_GPU_REG_DC_LUT_WRITE_EN_MASK] & + (UINT32_C(1) << (2 - gamma_ramp_rw_component_))) != 0; + if (write_gamma_ramp_component) { + reg::DC_LUT_30_COLOR& gamma_ramp_entry = + gamma_ramp_256_entry_table_[gamma_ramp_rw_index.rw_index]; + // Bits 0:5 are hardwired to zero. + uint32_t gamma_ramp_seq_color = regs.Get().seq_color >> 6; + switch (gamma_ramp_rw_component_) { + case 0: + gamma_ramp_entry.color_10_red = gamma_ramp_seq_color; + break; + case 1: + gamma_ramp_entry.color_10_green = gamma_ramp_seq_color; + break; + case 2: + gamma_ramp_entry.color_10_blue = gamma_ramp_seq_color; + break; + } + } + if (++gamma_ramp_rw_component_ >= 3) { + gamma_ramp_rw_component_ = 0; + reg::DC_LUT_RW_INDEX new_gamma_ramp_rw_index = gamma_ramp_rw_index; + ++new_gamma_ramp_rw_index.rw_index; + WriteRegister(XE_GPU_REG_DC_LUT_RW_INDEX, + rex::memory::Reinterpret(new_gamma_ramp_rw_index)); + } + if (write_gamma_ramp_component) { + OnGammaRamp256EntryTableValueWritten(); + } + } break; + + case XE_GPU_REG_DC_LUT_PWL_DATA: { + // Should be in the PWL writing mode. + assert_not_zero(regs[XE_GPU_REG_DC_LUT_RW_MODE] & 0b1); + auto gamma_ramp_rw_index = regs.Get(); + // Bit 7 of the index is ignored for PWL. + uint32_t gamma_ramp_rw_index_pwl = gamma_ramp_rw_index.rw_index & 0x7F; + // DC_LUT_PWL_DATA is likely in the red, green, blue order because + // DC_LUT_SEQ_COLOR is, but the write enable mask is blue, green, red. + bool write_gamma_ramp_component = (regs[XE_GPU_REG_DC_LUT_WRITE_EN_MASK] & + (UINT32_C(1) << (2 - gamma_ramp_rw_component_))) != 0; + if (write_gamma_ramp_component) { + reg::DC_LUT_PWL_DATA& gamma_ramp_entry = + gamma_ramp_pwl_rgb_[gamma_ramp_rw_index_pwl][gamma_ramp_rw_component_]; + auto gamma_ramp_value = regs.Get(); + // Bits 0:5 are hardwired to zero. + gamma_ramp_entry.base = gamma_ramp_value.base & ~UINT32_C(0x3F); + gamma_ramp_entry.delta = gamma_ramp_value.delta & ~UINT32_C(0x3F); + } + if (++gamma_ramp_rw_component_ >= 3) { + gamma_ramp_rw_component_ = 0; + reg::DC_LUT_RW_INDEX new_gamma_ramp_rw_index = gamma_ramp_rw_index; + // TODO(Triang3l): Should this increase beyond 7 bits for PWL? + // Direct3D 9 explicitly sets rw_index to 0x80 after writing the last + // PWL entry. However, the DC_LUT_RW_INDEX documentation says that for + // PWL, the bit 7 is ignored. + new_gamma_ramp_rw_index.rw_index = (gamma_ramp_rw_index.rw_index & ~UINT32_C(0x7F)) | + ((gamma_ramp_rw_index_pwl + 1) & 0x7F); + WriteRegister(XE_GPU_REG_DC_LUT_RW_INDEX, + rex::memory::Reinterpret(new_gamma_ramp_rw_index)); + } + if (write_gamma_ramp_component) { + OnGammaRampPWLValueWritten(); + } + } break; + + case XE_GPU_REG_DC_LUT_30_COLOR: { + // Should be in the 256-entry table writing mode. + assert_zero(regs[XE_GPU_REG_DC_LUT_RW_MODE] & 0b1); + auto gamma_ramp_rw_index = regs.Get(); + uint32_t gamma_ramp_write_enable_mask = regs[XE_GPU_REG_DC_LUT_WRITE_EN_MASK] & 0b111; + if (gamma_ramp_write_enable_mask) { + reg::DC_LUT_30_COLOR& gamma_ramp_entry = + gamma_ramp_256_entry_table_[gamma_ramp_rw_index.rw_index]; + auto gamma_ramp_value = regs.Get(); + if (gamma_ramp_write_enable_mask & 0b001) { + gamma_ramp_entry.color_10_blue = gamma_ramp_value.color_10_blue; + } + if (gamma_ramp_write_enable_mask & 0b010) { + gamma_ramp_entry.color_10_green = gamma_ramp_value.color_10_green; + } + if (gamma_ramp_write_enable_mask & 0b100) { + gamma_ramp_entry.color_10_red = gamma_ramp_value.color_10_red; + } + } + // TODO(Triang3l): Should this reset the component write index? If this + // increase is assumed to behave like a full DC_LUT_RW_INDEX write, it + // probably should. Currently this also calls WriteRegister for + // DC_LUT_RW_INDEX, which resets gamma_ramp_rw_component_ as well. + gamma_ramp_rw_component_ = 0; + reg::DC_LUT_RW_INDEX new_gamma_ramp_rw_index = gamma_ramp_rw_index; + ++new_gamma_ramp_rw_index.rw_index; + WriteRegister(XE_GPU_REG_DC_LUT_RW_INDEX, + rex::memory::Reinterpret(new_gamma_ramp_rw_index)); + if (gamma_ramp_write_enable_mask) { + OnGammaRamp256EntryTableValueWritten(); + } + } break; + } + } +} + +void CommandProcessor::WriteRegistersFromMem(uint32_t start_index, uint32_t* base, + uint32_t num_registers) { + for (uint32_t i = 0; i < num_registers; ++i) { + uint32_t data = memory::load_and_swap(base + i); + WriteRegister(start_index + i, data); + } +} + +void CommandProcessor::WriteRegisterRangeFromRing(memory::RingBuffer* ring, uint32_t base, + uint32_t num_registers) { + if (!num_registers) { + return; + } + memory::RingBuffer::ReadRange range = ring->BeginRead(size_t(num_registers) * sizeof(uint32_t)); + if (range.first_length != 0) { + uint32_t first_count = uint32_t(range.first_length / sizeof(uint32_t)); + WriteRegistersFromMem(base, reinterpret_cast(const_cast(range.first)), + first_count); + base += first_count; + } + if (range.second_length != 0) { + WriteRegistersFromMem(base, reinterpret_cast(const_cast(range.second)), + uint32_t(range.second_length / sizeof(uint32_t))); + } + ring->EndRead(range); +} + +void CommandProcessor::WriteALURangeFromRing(memory::RingBuffer* ring, uint32_t base, + uint32_t num_registers) { + WriteRegisterRangeFromRing(ring, base + 0x4000, num_registers); +} + +void CommandProcessor::WriteFetchRangeFromRing(memory::RingBuffer* ring, uint32_t base, + uint32_t num_registers) { + WriteRegisterRangeFromRing(ring, base + 0x4800, num_registers); +} + +void CommandProcessor::WriteBoolRangeFromRing(memory::RingBuffer* ring, uint32_t base, + uint32_t num_registers) { + WriteRegisterRangeFromRing(ring, base + 0x4900, num_registers); +} + +void CommandProcessor::WriteLoopRangeFromRing(memory::RingBuffer* ring, uint32_t base, + uint32_t num_registers) { + WriteRegisterRangeFromRing(ring, base + 0x4908, num_registers); +} + +void CommandProcessor::WriteREGISTERSRangeFromRing(memory::RingBuffer* ring, uint32_t base, + uint32_t num_registers) { + WriteRegisterRangeFromRing(ring, base + 0x2000, num_registers); +} + +void CommandProcessor::WriteALURangeFromMem(uint32_t start_index, uint32_t* base, + uint32_t num_registers) { + WriteRegistersFromMem(start_index + 0x4000, base, num_registers); +} + +void CommandProcessor::WriteFetchRangeFromMem(uint32_t start_index, uint32_t* base, + uint32_t num_registers) { + WriteRegistersFromMem(start_index + 0x4800, base, num_registers); +} + +void CommandProcessor::WriteBoolRangeFromMem(uint32_t start_index, uint32_t* base, + uint32_t num_registers) { + WriteRegistersFromMem(start_index + 0x4900, base, num_registers); +} + +void CommandProcessor::WriteLoopRangeFromMem(uint32_t start_index, uint32_t* base, + uint32_t num_registers) { + WriteRegistersFromMem(start_index + 0x4908, base, num_registers); +} + +void CommandProcessor::WriteREGISTERSRangeFromMem(uint32_t start_index, uint32_t* base, + uint32_t num_registers) { + WriteRegistersFromMem(start_index + 0x2000, base, num_registers); +} + +void CommandProcessor::MakeCoherent() { + SCOPE_profile_cpu_f("gpu"); + + // Status host often has 0x01000000 or 0x03000000. + // This is likely toggling VC (vertex cache) or TC (texture cache). + // Or, it also has a direction in here maybe - there is probably + // some way to check for dest coherency (what all the COHER_DEST_BASE_* + // registers are for). + // Best docs I've found on this are here: + // https://web.archive.org/web/20160711162346/https://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/10/R6xx_R7xx_3D.pdf + // https://cgit.freedesktop.org/xorg/driver/xf86-video-radeonhd/tree/src/r6xx_accel.c?id=3f8b6eccd9dba116cc4801e7f80ce21a879c67d2#n454 + + // Volatile because this may be called from the WAIT_REG_MEM loop. + volatile uint32_t* regs_volatile = register_file_->values; + auto status_host = rex::memory::Reinterpret( + uint32_t(regs_volatile[XE_GPU_REG_COHER_STATUS_HOST])); + uint32_t base_host = regs_volatile[XE_GPU_REG_COHER_BASE_HOST]; + uint32_t size_host = regs_volatile[XE_GPU_REG_COHER_SIZE_HOST]; + + if (!status_host.status) { + return; + } + + const char* action = "N/A"; + if (status_host.vc_action_ena && status_host.tc_action_ena) { + action = "VC | TC"; + } else if (status_host.tc_action_ena) { + action = "TC"; + } else if (status_host.vc_action_ena) { + action = "VC"; + } + + // TODO(benvanik): notify resource cache of base->size and type. + REXGPU_TRACE("Make {:08X} -> {:08X} ({}b) coherent, action = {}", base_host, + base_host + size_host, size_host, action); + + // Mark coherent. + regs_volatile[XE_GPU_REG_COHER_STATUS_HOST] = 0; +} + +void CommandProcessor::PrepareForWait() { + trace_writer_.Flush(); +} + +void CommandProcessor::ReturnFromWait() {} + +uint32_t CommandProcessor::ExecutePrimaryBuffer(uint32_t read_index, uint32_t write_index) { + SCOPE_profile_cpu_f("gpu"); + + // If we have a pending trace stream open it now. That way we ensure we get + // all commands. + if (!trace_writer_.is_open() && trace_state_ == TraceState::kStreaming) { + uint32_t title_id = + kernel_state_->GetExecutableModule() ? kernel_state_->GetExecutableModule()->title_id() : 0; + auto file_name = fmt::format("{:08X}_stream.xtr", title_id); + auto path = trace_stream_path_ / file_name; + trace_writer_.Open(path, title_id); + InitializeTrace(); + } + + // Adjust pointer base. + uint32_t start_ptr = primary_buffer_ptr_ + read_index * sizeof(uint32_t); + start_ptr = (primary_buffer_ptr_ & ~0x1FFFFFFF) | (start_ptr & 0x1FFFFFFF); + uint32_t end_ptr = primary_buffer_ptr_ + write_index * sizeof(uint32_t); + end_ptr = (primary_buffer_ptr_ & ~0x1FFFFFFF) | (end_ptr & 0x1FFFFFFF); + + trace_writer_.WritePrimaryBufferStart(start_ptr, write_index - read_index); + + // Execute commands! + memory::RingBuffer reader(memory_->TranslatePhysical(primary_buffer_ptr_), primary_buffer_size_); + reader.set_read_offset(read_index * sizeof(uint32_t)); + reader.set_write_offset(write_index * sizeof(uint32_t)); + do { + if (!ExecutePacket(&reader)) { + // This probably should be fatal - but we're going to continue anyways. + REXGPU_ERROR("**** PRIMARY RINGBUFFER: Failed to execute packet."); + assert_always(); + break; + } + } while (reader.read_count()); + + OnPrimaryBufferEnd(); + + trace_writer_.WritePrimaryBufferEnd(); + + return write_index; +} + +void CommandProcessor::ExecuteIndirectBuffer(uint32_t ptr, uint32_t count) { + SCOPE_profile_cpu_f("gpu"); + + trace_writer_.WriteIndirectBufferStart(ptr, count * sizeof(uint32_t)); + + // Execute commands! + memory::RingBuffer reader(memory_->TranslatePhysical(ptr), count * sizeof(uint32_t)); + reader.set_write_offset(count * sizeof(uint32_t)); + do { + if (!ExecutePacket(&reader)) { + // Return up a level if we encounter a bad packet. + REXGPU_ERROR("**** INDIRECT RINGBUFFER: Failed to execute packet."); + assert_always(); + break; + } + } while (reader.read_count()); + + trace_writer_.WriteIndirectBufferEnd(); +} + +void CommandProcessor::ExecutePacket(uint32_t ptr, uint32_t count) { + // Execute commands! + memory::RingBuffer reader(memory_->TranslatePhysical(ptr), count * sizeof(uint32_t)); + reader.set_write_offset(count * sizeof(uint32_t)); + do { + if (!ExecutePacket(&reader)) { + REXGPU_ERROR("**** ExecutePacket: Failed to execute packet."); + assert_always(); + break; + } + } while (reader.read_count()); +} + +bool CommandProcessor::ExecutePacket(memory::RingBuffer* reader) { + const uint32_t packet = reader->ReadAndSwap(); + const uint32_t packet_type = packet >> 30; + if (packet == 0) { + trace_writer_.WritePacketStart(uint32_t(reader->read_ptr() - 4), 1); + trace_writer_.WritePacketEnd(); + return true; + } + + if (packet == 0xCDCDCDCD) { + REXGPU_WARN("GPU packet is CDCDCDCD - probably read uninitialized memory!"); + } + + switch (packet_type) { + case 0x00: + return ExecutePacketType0(reader, packet); + case 0x01: + return ExecutePacketType1(reader, packet); + case 0x02: + return ExecutePacketType2(reader, packet); + case 0x03: + return ExecutePacketType3(reader, packet); + default: + assert_unhandled_case(packet_type); + return false; + } +} + +bool CommandProcessor::ExecutePacketType0(memory::RingBuffer* reader, uint32_t packet) { + // Type-0 packet. + // Write count registers in sequence to the registers starting at + // (base_index << 2). + + uint32_t count = ((packet >> 16) & 0x3FFF) + 1; + if (reader->read_count() < count * sizeof(uint32_t)) { + REXGPU_ERROR("ExecutePacketType0 overflow (read count {:08X}, packet count {:08X})", + reader->read_count(), count * sizeof(uint32_t)); + return false; + } + + trace_writer_.WritePacketStart(uint32_t(reader->read_ptr() - 4), 1 + count); + + uint32_t base_index = (packet & 0x7FFF); + uint32_t write_one_reg = (packet >> 15) & 0x1; + for (uint32_t m = 0; m < count; m++) { + uint32_t reg_data = reader->ReadAndSwap(); + uint32_t target_index = write_one_reg ? base_index : base_index + m; + WriteRegister(target_index, reg_data); + } + + trace_writer_.WritePacketEnd(); + return true; +} + +bool CommandProcessor::ExecutePacketType1(memory::RingBuffer* reader, uint32_t packet) { + // Type-1 packet. + // Contains two registers of data. Type-0 should be more common. + trace_writer_.WritePacketStart(uint32_t(reader->read_ptr() - 4), 3); + uint32_t reg_index_1 = packet & 0x7FF; + uint32_t reg_index_2 = (packet >> 11) & 0x7FF; + uint32_t reg_data_1 = reader->ReadAndSwap(); + uint32_t reg_data_2 = reader->ReadAndSwap(); + WriteRegister(reg_index_1, reg_data_1); + WriteRegister(reg_index_2, reg_data_2); + trace_writer_.WritePacketEnd(); + return true; +} + +bool CommandProcessor::ExecutePacketType2(memory::RingBuffer* reader, uint32_t packet) { + // Type-2 packet. + // No-op. Do nothing. + trace_writer_.WritePacketStart(uint32_t(reader->read_ptr() - 4), 1); + trace_writer_.WritePacketEnd(); + return true; +} + +bool CommandProcessor::ExecutePacketType3(memory::RingBuffer* reader, uint32_t packet) { + // Type-3 packet. + uint32_t opcode = (packet >> 8) & 0x7F; + uint32_t count = ((packet >> 16) & 0x3FFF) + 1; + auto data_start_offset = reader->read_offset(); + + if (reader->read_count() < count * sizeof(uint32_t)) { + REXGPU_ERROR("ExecutePacketType3 overflow (read count {:08X}, packet count {:08X})", + reader->read_count(), count * sizeof(uint32_t)); + return false; + } + + // To handle nesting behavior when tracing we special case indirect buffers. + if (opcode == PM4_INDIRECT_BUFFER) { + trace_writer_.WritePacketStart(uint32_t(reader->read_ptr() - 4), 2); + } else { + trace_writer_.WritePacketStart(uint32_t(reader->read_ptr() - 4), 1 + count); + } + + // & 1 == predicate - when set, we do bin check to see if we should execute + // the packet. Only type 3 packets are affected. + // We also skip predicated swaps, as they are never valid (probably?). + if (packet & 1) { + bool any_pass = (bin_select_ & bin_mask_) != 0; + if (!any_pass || opcode == PM4_XE_SWAP) { + reader->AdvanceRead(count * sizeof(uint32_t)); + trace_writer_.WritePacketEnd(); + return true; + } + } + + bool result = false; + switch (opcode) { + case PM4_ME_INIT: + result = ExecutePacketType3_ME_INIT(reader, packet, count); + break; + case PM4_NOP: + result = ExecutePacketType3_NOP(reader, packet, count); + break; + case PM4_INTERRUPT: + result = ExecutePacketType3_INTERRUPT(reader, packet, count); + break; + case PM4_XE_SWAP: + result = ExecutePacketType3_XE_SWAP(reader, packet, count); + break; + case PM4_INDIRECT_BUFFER: + case PM4_INDIRECT_BUFFER_PFD: + result = ExecutePacketType3_INDIRECT_BUFFER(reader, packet, count); + break; + case PM4_WAIT_REG_MEM: + result = ExecutePacketType3_WAIT_REG_MEM(reader, packet, count); + break; + case PM4_REG_RMW: + result = ExecutePacketType3_REG_RMW(reader, packet, count); + break; + case PM4_REG_TO_MEM: + result = ExecutePacketType3_REG_TO_MEM(reader, packet, count); + break; + case PM4_MEM_WRITE: + result = ExecutePacketType3_MEM_WRITE(reader, packet, count); + break; + case PM4_COND_WRITE: + result = ExecutePacketType3_COND_WRITE(reader, packet, count); + break; + case PM4_EVENT_WRITE: + result = ExecutePacketType3_EVENT_WRITE(reader, packet, count); + break; + case PM4_EVENT_WRITE_SHD: + result = ExecutePacketType3_EVENT_WRITE_SHD(reader, packet, count); + break; + case PM4_EVENT_WRITE_EXT: + result = ExecutePacketType3_EVENT_WRITE_EXT(reader, packet, count); + break; + case PM4_EVENT_WRITE_ZPD: + result = ExecutePacketType3_EVENT_WRITE_ZPD(reader, packet, count); + break; + case PM4_DRAW_INDX: + result = ExecutePacketType3_DRAW_INDX(reader, packet, count); + break; + case PM4_DRAW_INDX_2: + result = ExecutePacketType3_DRAW_INDX_2(reader, packet, count); + break; + case PM4_SET_CONSTANT: + result = ExecutePacketType3_SET_CONSTANT(reader, packet, count); + break; + case PM4_SET_CONSTANT2: + result = ExecutePacketType3_SET_CONSTANT2(reader, packet, count); + break; + case PM4_LOAD_ALU_CONSTANT: + result = ExecutePacketType3_LOAD_ALU_CONSTANT(reader, packet, count); + break; + case PM4_SET_SHADER_CONSTANTS: + result = ExecutePacketType3_SET_SHADER_CONSTANTS(reader, packet, count); + break; + case PM4_IM_LOAD: + result = ExecutePacketType3_IM_LOAD(reader, packet, count); + break; + case PM4_IM_LOAD_IMMEDIATE: + result = ExecutePacketType3_IM_LOAD_IMMEDIATE(reader, packet, count); + break; + case PM4_INVALIDATE_STATE: + result = ExecutePacketType3_INVALIDATE_STATE(reader, packet, count); + break; + case PM4_VIZ_QUERY: + result = ExecutePacketType3_VIZ_QUERY(reader, packet, count); + break; + + case PM4_SET_BIN_MASK_LO: { + uint32_t value = reader->ReadAndSwap(); + bin_mask_ = (bin_mask_ & 0xFFFFFFFF00000000ull) | value; + result = true; + } break; + case PM4_SET_BIN_MASK_HI: { + uint32_t value = reader->ReadAndSwap(); + bin_mask_ = (bin_mask_ & 0xFFFFFFFFull) | (static_cast(value) << 32); + result = true; + } break; + case PM4_SET_BIN_SELECT_LO: { + uint32_t value = reader->ReadAndSwap(); + bin_select_ = (bin_select_ & 0xFFFFFFFF00000000ull) | value; + result = true; + } break; + case PM4_SET_BIN_SELECT_HI: { + uint32_t value = reader->ReadAndSwap(); + bin_select_ = (bin_select_ & 0xFFFFFFFFull) | (static_cast(value) << 32); + result = true; + } break; + case PM4_SET_BIN_MASK: { + assert_true(count == 2); + uint64_t val_hi = reader->ReadAndSwap(); + uint64_t val_lo = reader->ReadAndSwap(); + bin_mask_ = (val_hi << 32) | val_lo; + result = true; + } break; + case PM4_SET_BIN_SELECT: { + assert_true(count == 2); + uint64_t val_hi = reader->ReadAndSwap(); + uint64_t val_lo = reader->ReadAndSwap(); + bin_select_ = (val_hi << 32) | val_lo; + result = true; + } break; + case PM4_CONTEXT_UPDATE: { + assert_true(count == 1); + uint32_t value = reader->ReadAndSwap(); + REXGPU_INFO("GPU context update = {:08X}", value); + assert_true(value == 0); + result = true; + break; + } + case PM4_WAIT_FOR_IDLE: { + // This opcode is used by 5454084E while going / being ingame. + assert_true(count == 1); + uint32_t value = reader->ReadAndSwap(); + REXGPU_INFO("GPU wait for idle = {:08X}", value); + result = true; + break; + } + + default: + REXGPU_INFO("Unimplemented GPU OPCODE: 0x{:02X}\t\tCOUNT: {}\n", opcode, count); + assert_always(); + reader->AdvanceRead(count * sizeof(uint32_t)); + break; + } + + trace_writer_.WritePacketEnd(); + if (opcode == PM4_XE_SWAP) { + // End the trace writer frame. + if (trace_writer_.is_open()) { + trace_writer_.WriteEvent(EventCommand::Type::kSwap); + trace_writer_.Flush(); + if (trace_state_ == TraceState::kSingleFrame) { + trace_state_ = TraceState::kDisabled; + trace_writer_.Close(); + } + } else if (trace_state_ == TraceState::kSingleFrame) { + // New trace request - we only start tracing at the beginning of a frame. + uint32_t title_id = kernel_state_->GetExecutableModule()->title_id(); + auto file_name = fmt::format("{:08X}_{}.xtr", title_id, counter_ - 1); + auto path = trace_frame_path_ / file_name; + trace_writer_.Open(path, title_id); + InitializeTrace(); + } + } + + assert_true(reader->read_offset() == + (data_start_offset + (count * sizeof(uint32_t))) % reader->capacity()); + return result; +} + +bool CommandProcessor::ExecutePacketType3_ME_INIT(memory::RingBuffer* reader, uint32_t packet, + uint32_t count) { + // initialize CP's micro-engine + me_bin_.clear(); + for (uint32_t i = 0; i < count; i++) { + me_bin_.push_back(reader->ReadAndSwap()); + } + + return true; +} + +bool CommandProcessor::ExecutePacketType3_NOP(memory::RingBuffer* reader, uint32_t packet, + uint32_t count) { + // skip N 32-bit words to get to the next packet + // No-op, ignore some data. + reader->AdvanceRead(count * sizeof(uint32_t)); + return true; +} + +bool CommandProcessor::ExecutePacketType3_INTERRUPT(memory::RingBuffer* reader, uint32_t packet, + uint32_t count) { + SCOPE_profile_cpu_f("gpu"); + + // generate interrupt from the command stream + uint32_t cpu_mask = reader->ReadAndSwap(); + for (int n = 0; n < 6; n++) { + if (cpu_mask & (1 << n)) { + if (graphics_system_) { + graphics_system_->DispatchInterruptCallback(1, n); + } + } + } + return true; +} + +bool CommandProcessor::ExecutePacketType3_XE_SWAP(memory::RingBuffer* reader, uint32_t packet, + uint32_t count) { + SCOPE_profile_cpu_f("gpu"); + +#ifdef REXGLUE_ENABLE_PERF_COUNTERS + { + static uint64_t last_frame_tick = 0; + uint64_t now = rex::chrono::Clock::QueryHostTickCount(); + if (last_frame_tick) { + uint64_t freq = rex::chrono::Clock::QueryHostTickFrequency(); + int64_t dt_us = static_cast((now - last_frame_tick) * 1000000 / freq); + PROFILE_FRAME_TIME_US(dt_us); + PROFILE_FPS(freq / (now - last_frame_tick)); + } + last_frame_tick = now; + } +#endif + rex::perf::Profiler::Flip(); + + // Xenia-specific VdSwap hook. + // VdSwap will post this to tell us we need to swap the screen/fire an + // interrupt. + // 63 words here, but only the first has any data. + uint32_t magic = reader->ReadAndSwap(); + assert_true(magic == kSwapSignature); + + // TODO(benvanik): only swap frontbuffer ptr. + uint32_t frontbuffer_ptr = reader->ReadAndSwap(); + uint32_t frontbuffer_width = reader->ReadAndSwap(); + uint32_t frontbuffer_height = reader->ReadAndSwap(); + reader->AdvanceRead((count - 4) * sizeof(uint32_t)); + + IssueSwap(frontbuffer_ptr, frontbuffer_width, frontbuffer_height); + + ++counter_; + return true; +} + +bool CommandProcessor::ExecutePacketType3_INDIRECT_BUFFER(memory::RingBuffer* reader, + uint32_t packet, uint32_t count) { + // indirect buffer dispatch + uint32_t list_ptr = CpuToGpu(reader->ReadAndSwap()); + uint32_t list_length = reader->ReadAndSwap(); + assert_zero(list_length & ~0xFFFFF); + list_length &= 0xFFFFF; + ExecuteIndirectBuffer(GpuToCpu(list_ptr), list_length); + return true; +} + +bool CommandProcessor::ExecutePacketType3_WAIT_REG_MEM(memory::RingBuffer* reader, uint32_t packet, + uint32_t count) { + SCOPE_profile_cpu_f("gpu"); + + // wait until a register or memory location is a specific value + + uint32_t wait_info = reader->ReadAndSwap(); + uint32_t poll_reg_addr = reader->ReadAndSwap(); + uint32_t ref = reader->ReadAndSwap(); + uint32_t mask = reader->ReadAndSwap(); + uint32_t wait = reader->ReadAndSwap(); + + bool is_memory = (wait_info & 0x10) != 0; + + bool matched = false; + do { + uint32_t value = 0; + if (is_memory) { + value = + *reinterpret_cast(memory_->TranslatePhysical(poll_reg_addr & ~uint32_t(0x3))); + trace_writer_.WriteMemoryRead(CpuToGpu(poll_reg_addr & ~uint32_t(0x3)), sizeof(uint32_t)); + value = xenos::GpuSwap(value, static_cast(poll_reg_addr & 0x3)); + } else { + value = ReadRegisterValue(poll_reg_addr); + if (poll_reg_addr == XE_GPU_REG_COHER_STATUS_HOST) { + MakeCoherent(); + value = ReadRegisterValue(poll_reg_addr); + } + } + switch (wait_info & 0x7) { + case 0x0: // Never. + matched = false; + break; + case 0x1: // Less than reference. + matched = (value & mask) < ref; + break; + case 0x2: // Less than or equal to reference. + matched = (value & mask) <= ref; + break; + case 0x3: // Equal to reference. + matched = (value & mask) == ref; + break; + case 0x4: // Not equal to reference. + matched = (value & mask) != ref; + break; + case 0x5: // Greater than or equal to reference. + matched = (value & mask) >= ref; + break; + case 0x6: // Greater than reference. + matched = (value & mask) > ref; + break; + case 0x7: // Always + matched = true; + break; + } + if (!matched) { + // Wait. + if (wait >= 0x100) { + PrepareForWait(); + if (!REXCVAR_GET(vsync)) { + // User wants it fast and dangerous. + rex::thread::MaybeYield(); + } else { + rex::thread::Sleep(std::chrono::milliseconds(wait / 0x100)); + } + rex::thread::SyncMemory(); + ReturnFromWait(); + + if (!worker_running_) { + // Short-circuited exit. + return false; + } + } else { + rex::thread::MaybeYield(); + } + } + } while (!matched); + + return true; +} + +bool CommandProcessor::ExecutePacketType3_REG_RMW(memory::RingBuffer* reader, uint32_t packet, + uint32_t count) { + // register read/modify/write + // ? (used during shader upload and edram setup) + uint32_t rmw_info = reader->ReadAndSwap(); + uint32_t and_mask = reader->ReadAndSwap(); + uint32_t or_mask = reader->ReadAndSwap(); + uint32_t value = register_file_->values[rmw_info & 0x1FFF]; + if ((rmw_info >> 31) & 0x1) { + // & reg + value &= register_file_->values[and_mask & 0x1FFF]; + } else { + // & imm + value &= and_mask; + } + if ((rmw_info >> 30) & 0x1) { + // | reg + value |= register_file_->values[or_mask & 0x1FFF]; + } else { + // | imm + value |= or_mask; + } + WriteRegister(rmw_info & 0x1FFF, value); + return true; +} + +bool CommandProcessor::ExecutePacketType3_REG_TO_MEM(memory::RingBuffer* reader, uint32_t packet, + uint32_t count) { + // Copy Register to Memory (?) + // Count is 2, assuming a Register Addr and a Memory Addr. + + uint32_t reg_addr = reader->ReadAndSwap(); + uint32_t mem_addr = reader->ReadAndSwap(); + + uint32_t reg_val = ReadRegisterValue(reg_addr); + + auto endianness = static_cast(mem_addr & 0x3); + mem_addr &= ~0x3; + reg_val = GpuSwap(reg_val, endianness); + memory::store(memory_->TranslatePhysical(mem_addr), reg_val); + trace_writer_.WriteMemoryWrite(CpuToGpu(mem_addr), 4); + + return true; +} + +bool CommandProcessor::ExecutePacketType3_MEM_WRITE(memory::RingBuffer* reader, uint32_t packet, + uint32_t count) { + uint32_t write_addr = reader->ReadAndSwap(); + for (uint32_t i = 0; i < count - 1; i++) { + uint32_t write_data = reader->ReadAndSwap(); + + auto endianness = static_cast(write_addr & 0x3); + auto addr = write_addr & ~0x3; + write_data = GpuSwap(write_data, endianness); + memory::store(memory_->TranslatePhysical(addr), write_data); + trace_writer_.WriteMemoryWrite(CpuToGpu(addr), 4); + write_addr += 4; + } + + return true; +} + +bool CommandProcessor::ExecutePacketType3_COND_WRITE(memory::RingBuffer* reader, uint32_t packet, + uint32_t count) { + // conditional write to memory or register + uint32_t wait_info = reader->ReadAndSwap(); + uint32_t poll_reg_addr = reader->ReadAndSwap(); + uint32_t ref = reader->ReadAndSwap(); + uint32_t mask = reader->ReadAndSwap(); + uint32_t write_reg_addr = reader->ReadAndSwap(); + uint32_t write_data = reader->ReadAndSwap(); + uint32_t value; + if (wait_info & 0x10) { + // Memory. + auto endianness = static_cast(poll_reg_addr & 0x3); + poll_reg_addr &= ~0x3; + trace_writer_.WriteMemoryRead(CpuToGpu(poll_reg_addr), 4); + value = memory::load(memory_->TranslatePhysical(poll_reg_addr)); + value = GpuSwap(value, endianness); + } else { + // Register. + value = ReadRegisterValue(poll_reg_addr); + } + bool matched = false; + switch (wait_info & 0x7) { + case 0x0: // Never. + matched = false; + break; + case 0x1: // Less than reference. + matched = (value & mask) < ref; + break; + case 0x2: // Less than or equal to reference. + matched = (value & mask) <= ref; + break; + case 0x3: // Equal to reference. + matched = (value & mask) == ref; + break; + case 0x4: // Not equal to reference. + matched = (value & mask) != ref; + break; + case 0x5: // Greater than or equal to reference. + matched = (value & mask) >= ref; + break; + case 0x6: // Greater than reference. + matched = (value & mask) > ref; + break; + case 0x7: // Always + matched = true; + break; + } + if (matched) { + // Write. + if (wait_info & 0x100) { + // Memory. + auto endianness = static_cast(write_reg_addr & 0x3); + write_reg_addr &= ~0x3; + write_data = GpuSwap(write_data, endianness); + memory::store(memory_->TranslatePhysical(write_reg_addr), write_data); + trace_writer_.WriteMemoryWrite(CpuToGpu(write_reg_addr), 4); + } else { + // Register. + WriteRegister(write_reg_addr, write_data); + } + } + return true; +} + +bool CommandProcessor::ExecutePacketType3_EVENT_WRITE(memory::RingBuffer* reader, uint32_t packet, + uint32_t count) { + // generate an event that creates a write to memory when completed + uint32_t initiator = reader->ReadAndSwap(); + // Writeback initiator. + WriteRegister(XE_GPU_REG_VGT_EVENT_INITIATOR, initiator & 0x3F); + if (count == 1) { + // Just an event flag? Where does this write? + } else { + // Write to an address. + assert_always(); + reader->AdvanceRead((count - 1) * sizeof(uint32_t)); + } + return true; +} + +bool CommandProcessor::ExecutePacketType3_EVENT_WRITE_SHD(memory::RingBuffer* reader, + uint32_t packet, uint32_t count) { + // generate a VS|PS_done event + uint32_t initiator = reader->ReadAndSwap(); + uint32_t address = reader->ReadAndSwap(); + uint32_t value = reader->ReadAndSwap(); + + // Writeback initiator. + WriteRegister(XE_GPU_REG_VGT_EVENT_INITIATOR, initiator & 0x3F); + uint32_t data_value; + if ((initiator >> 31) & 0x1) { + // Write counter (GPU vblank counter?). + data_value = counter_; + } else { + // Write value. + data_value = value; + } + auto endianness = static_cast(address & 0x3); + address &= ~0x3; + data_value = GpuSwap(data_value, endianness); + memory::store(memory_->TranslatePhysical(address), data_value); + trace_writer_.WriteMemoryWrite(CpuToGpu(address), 4); + return true; +} + +bool CommandProcessor::ExecutePacketType3_EVENT_WRITE_EXT(memory::RingBuffer* reader, + uint32_t packet, uint32_t count) { + // generate a screen extent event + uint32_t initiator = reader->ReadAndSwap(); + uint32_t address = reader->ReadAndSwap(); + // Writeback initiator. + WriteRegister(XE_GPU_REG_VGT_EVENT_INITIATOR, initiator & 0x3F); + auto endianness = static_cast(address & 0x3); + address &= ~0x3; + + // Let us hope we can fake this. + // This callback tells the driver the xy coordinates affected by a previous + // drawcall. + // https://www.google.com/patents/US20060055701 + uint16_t extents[] = { + 0 >> 3, // min x + xenos::kTexture2DCubeMaxWidthHeight >> 3, // max x + 0 >> 3, // min y + xenos::kTexture2DCubeMaxWidthHeight >> 3, // max y + 0, // min z + 1, // max z + }; + assert_true(endianness == xenos::Endian::k8in16); + memory::copy_and_swap_16_unaligned(memory_->TranslatePhysical(address), extents, + rex::countof(extents)); + trace_writer_.WriteMemoryWrite(CpuToGpu(address), sizeof(extents)); + return true; +} + +bool CommandProcessor::ExecutePacketType3_EVENT_WRITE_ZPD(memory::RingBuffer* reader, + uint32_t packet, uint32_t count) { + // Set by D3D as BE but struct ABI is LE + const uint32_t kQueryFinished = rex::byte_swap(0xFFFFFEED); + assert_true(count == 1); + uint32_t initiator = reader->ReadAndSwap(); + // Writeback initiator. + WriteRegister(XE_GPU_REG_VGT_EVENT_INITIATOR, initiator & 0x3F); + + // Occlusion queries: + // This command is send on query begin and end. + // As a workaround report some fixed amount of passed samples. + auto fake_sample_count = REXCVAR_GET(query_occlusion_fake_sample_count); + if (fake_sample_count >= 0) { + auto* pSampleCounts = memory_->TranslatePhysical( + register_file_->values[XE_GPU_REG_RB_SAMPLE_COUNT_ADDR]); + if (!pSampleCounts) { + return true; + } + // 0xFFFFFEED is written to this two locations by D3D only on D3DISSUE_END + // and used to detect a finished query. + bool is_end_via_z_pass = + pSampleCounts->ZPass_A == kQueryFinished && pSampleCounts->ZPass_B == kQueryFinished; + // Older versions of D3D also checks for ZFail (4D5307D5). + bool is_end_via_z_fail = + pSampleCounts->ZFail_A == kQueryFinished && pSampleCounts->ZFail_B == kQueryFinished; + std::memset(pSampleCounts, 0, sizeof(xe_gpu_depth_sample_counts)); + if (is_end_via_z_pass || is_end_via_z_fail) { + pSampleCounts->ZPass_A = fake_sample_count; + pSampleCounts->Total_A = fake_sample_count; + } + } + + return true; +} + +bool CommandProcessor::ExecutePacketType3Draw(memory::RingBuffer* reader, uint32_t packet, + const char* opcode_name, uint32_t viz_query_condition, + uint32_t count_remaining) { + // if viz_query_condition != 0, this is a conditional draw based on viz query. + // This ID matches the one issued in PM4_VIZ_QUERY + // uint32_t viz_id = viz_query_condition & 0x3F; + // when true, render conditionally based on query result + // uint32_t viz_use = viz_query_condition & 0x100; + + assert_not_zero(count_remaining); + if (!count_remaining) { + REXGPU_ERROR("{}: Packet too small, can't read VGT_DRAW_INITIATOR", opcode_name); + return false; + } + reg::VGT_DRAW_INITIATOR vgt_draw_initiator; + vgt_draw_initiator.value = reader->ReadAndSwap(); + --count_remaining; + WriteRegister(XE_GPU_REG_VGT_DRAW_INITIATOR, vgt_draw_initiator.value); + + bool draw_succeeded = true; + // TODO(Triang3l): Remove IndexBufferInfo and replace handling of all this + // with PrimitiveProcessor when the old Vulkan renderer is removed. + bool is_indexed = false; + IndexBufferInfo index_buffer_info; + switch (vgt_draw_initiator.source_select) { + case xenos::SourceSelect::kDMA: { + // Indexed draw. + is_indexed = true; + + // Two separate bounds checks so if there's only one missing register + // value out of two, one uint32_t will be skipped in the command buffer, + // not two. + assert_not_zero(count_remaining); + if (!count_remaining) { + REXGPU_ERROR("{}: Packet too small, can't read VGT_DMA_BASE", opcode_name); + return false; + } + uint32_t vgt_dma_base = reader->ReadAndSwap(); + --count_remaining; + WriteRegister(XE_GPU_REG_VGT_DMA_BASE, vgt_dma_base); + reg::VGT_DMA_SIZE vgt_dma_size; + assert_not_zero(count_remaining); + if (!count_remaining) { + REXGPU_ERROR("{}: Packet too small, can't read VGT_DMA_SIZE", opcode_name); + return false; + } + vgt_dma_size.value = reader->ReadAndSwap(); + --count_remaining; + WriteRegister(XE_GPU_REG_VGT_DMA_SIZE, vgt_dma_size.value); + + uint32_t index_size_bytes = vgt_draw_initiator.index_size == xenos::IndexFormat::kInt16 + ? sizeof(uint16_t) + : sizeof(uint32_t); + // The base address must already be word-aligned according to the R6xx + // documentation, but for safety. + index_buffer_info.guest_base = vgt_dma_base & ~(index_size_bytes - 1); + index_buffer_info.endianness = vgt_dma_size.swap_mode; + index_buffer_info.format = vgt_draw_initiator.index_size; + index_buffer_info.length = vgt_dma_size.num_words * index_size_bytes; + index_buffer_info.count = vgt_draw_initiator.num_indices; + } break; + case xenos::SourceSelect::kImmediate: { + // TODO(Triang3l): VGT_IMMED_DATA. + REXGPU_ERROR( + "{}: Using immediate vertex indices, which are not supported yet. " + "Report the game to Xenia developers!", + opcode_name, uint32_t(vgt_draw_initiator.source_select)); + draw_succeeded = false; + assert_always(); + } break; + case xenos::SourceSelect::kAutoIndex: { + // Auto draw. + index_buffer_info.guest_base = 0; + index_buffer_info.length = 0; + } break; + default: { + // Invalid source selection. + draw_succeeded = false; + assert_unhandled_case(vgt_draw_initiator.source_select); + } break; + } + + // Skip to the next command, for example, if there are immediate indexes that + // we don't support yet. + reader->AdvanceRead(count_remaining * sizeof(uint32_t)); + + if (draw_succeeded) { + auto viz_query = register_file_->Get(); + if (!(viz_query.viz_query_ena && viz_query.kill_pix_post_hi_z)) { + // TODO(Triang3l): Don't drop the draw call completely if the vertex + // shader has memexport. + // TODO(Triang3l || JoelLinn): Handle this properly in the render + // backends. + + bool major_mode_explicit = + xenos::IsMajorModeExplicit(vgt_draw_initiator.major_mode, vgt_draw_initiator.prim_type); + draw_succeeded = IssueDraw(vgt_draw_initiator.prim_type, vgt_draw_initiator.num_indices, + is_indexed ? &index_buffer_info : nullptr, major_mode_explicit); + if (!draw_succeeded) { + auto vgt_output_path_cntl = register_file_->Get(); + auto vgt_hos_cntl = register_file_->Get(); + auto rb_modecontrol = register_file_->Get(); + REXGPU_ERROR( + "{}({}, {}, {}): Failed in backend " + "(major_mode={}, explicit_major={}, path_select={}, tess_mode={}, edram_mode={})", + opcode_name, static_cast(vgt_draw_initiator.num_indices), + uint32_t(vgt_draw_initiator.prim_type), uint32_t(vgt_draw_initiator.source_select), + uint32_t(vgt_draw_initiator.major_mode), uint32_t(major_mode_explicit), + uint32_t(vgt_output_path_cntl.path_select), uint32_t(vgt_hos_cntl.tess_mode), + uint32_t(rb_modecontrol.edram_mode)); + } + } + } + + // If read the packed correctly, but merely couldn't execute it (because of, + // for instance, features not supported by the host), don't terminate command + // buffer processing as that would leave rendering in a way more inconsistent + // state than just a single dropped draw command. + return true; +} + +bool CommandProcessor::ExecutePacketType3_DRAW_INDX(memory::RingBuffer* reader, uint32_t packet, + uint32_t count) { + // "initiate fetch of index buffer and draw" + // Generally used by Xbox 360 Direct3D 9 for kDMA and kAutoIndex sources. + // With a viz query token as the first one. + uint32_t count_remaining = count; + assert_not_zero(count_remaining); + if (!count_remaining) { + REXGPU_ERROR("PM4_DRAW_INDX: Packet too small, can't read the viz query token"); + return false; + } + uint32_t viz_query_condition = reader->ReadAndSwap(); + --count_remaining; + return ExecutePacketType3Draw(reader, packet, "PM4_DRAW_INDX", viz_query_condition, + count_remaining); +} + +bool CommandProcessor::ExecutePacketType3_DRAW_INDX_2(memory::RingBuffer* reader, uint32_t packet, + uint32_t count) { + // "draw using supplied indices in packet" + // Generally used by Xbox 360 Direct3D 9 for kAutoIndex source. + // No viz query token. + return ExecutePacketType3Draw(reader, packet, "PM4_DRAW_INDX_2", 0, count); +} + +bool CommandProcessor::ExecutePacketType3_SET_CONSTANT(memory::RingBuffer* reader, uint32_t packet, + uint32_t count) { + // load constant into chip and to memory + // PM4_REG(reg) ((0x4 << 16) | (GSL_HAL_SUBBLOCK_OFFSET(reg))) + // reg - 0x2000 + uint32_t offset_type = reader->ReadAndSwap(); + uint32_t index = offset_type & 0x7FF; + uint32_t type = (offset_type >> 16) & 0xFF; + uint32_t count_registers = count - 1; + switch (type) { + case 0: // ALU + WriteALURangeFromRing(reader, index, count_registers); + break; + case 1: // FETCH + WriteFetchRangeFromRing(reader, index, count_registers); + break; + case 2: // BOOL + WriteBoolRangeFromRing(reader, index, count_registers); + break; + case 3: // LOOP + WriteLoopRangeFromRing(reader, index, count_registers); + break; + case 4: // REGISTERS + WriteREGISTERSRangeFromRing(reader, index, count_registers); + break; + default: + assert_always(); + reader->AdvanceRead((count - 1) * sizeof(uint32_t)); + return true; + } + return true; +} + +bool CommandProcessor::ExecutePacketType3_SET_CONSTANT2(memory::RingBuffer* reader, uint32_t packet, + uint32_t count) { + uint32_t offset_type = reader->ReadAndSwap(); + uint32_t index = offset_type & 0xFFFF; + WriteRegisterRangeFromRing(reader, index, count - 1); + return true; +} + +bool CommandProcessor::ExecutePacketType3_LOAD_ALU_CONSTANT(memory::RingBuffer* reader, + uint32_t packet, uint32_t count) { + // load constants from memory + uint32_t address = reader->ReadAndSwap(); + address &= 0x3FFFFFFF; + uint32_t offset_type = reader->ReadAndSwap(); + uint32_t index = offset_type & 0x7FF; + uint32_t size_dwords = reader->ReadAndSwap(); + size_dwords &= 0xFFF; + uint32_t type = (offset_type >> 16) & 0xFF; + uint32_t* xlat_address = memory_->TranslatePhysical(address); + switch (type) { + case 0: // ALU + trace_writer_.WriteMemoryRead(CpuToGpu(address), size_dwords * 4); + WriteALURangeFromMem(index, xlat_address, size_dwords); + break; + case 1: // FETCH + trace_writer_.WriteMemoryRead(CpuToGpu(address), size_dwords * 4); + WriteFetchRangeFromMem(index, xlat_address, size_dwords); + break; + case 2: // BOOL + trace_writer_.WriteMemoryRead(CpuToGpu(address), size_dwords * 4); + WriteBoolRangeFromMem(index, xlat_address, size_dwords); + break; + case 3: // LOOP + trace_writer_.WriteMemoryRead(CpuToGpu(address), size_dwords * 4); + WriteLoopRangeFromMem(index, xlat_address, size_dwords); + break; + case 4: // REGISTERS + trace_writer_.WriteMemoryRead(CpuToGpu(address), size_dwords * 4); + WriteREGISTERSRangeFromMem(index, xlat_address, size_dwords); + break; + default: + assert_always(); + return true; + } + return true; +} + +bool CommandProcessor::ExecutePacketType3_SET_SHADER_CONSTANTS(memory::RingBuffer* reader, + uint32_t packet, uint32_t count) { + uint32_t offset_type = reader->ReadAndSwap(); + uint32_t index = offset_type & 0xFFFF; + WriteRegisterRangeFromRing(reader, index, count - 1); + return true; +} + +bool CommandProcessor::ExecutePacketType3_IM_LOAD(memory::RingBuffer* reader, uint32_t packet, + uint32_t count) { + SCOPE_profile_cpu_f("gpu"); + + // load sequencer instruction memory (pointer-based) + uint32_t addr_type = reader->ReadAndSwap(); + auto shader_type = static_cast(addr_type & 0x3); + uint32_t addr = addr_type & ~0x3; + uint32_t start_size = reader->ReadAndSwap(); + uint32_t start = start_size >> 16; + uint32_t size_dwords = start_size & 0xFFFF; // dwords + assert_true(start == 0); + + trace_writer_.WriteMemoryRead(CpuToGpu(addr), size_dwords * 4); + auto shader = + LoadShader(shader_type, addr, memory_->TranslatePhysical(addr), size_dwords); + switch (shader_type) { + case xenos::ShaderType::kVertex: + active_vertex_shader_ = shader; + break; + case xenos::ShaderType::kPixel: + active_pixel_shader_ = shader; + break; + default: + assert_unhandled_case(shader_type); + return false; + } + return true; +} + +bool CommandProcessor::ExecutePacketType3_IM_LOAD_IMMEDIATE(memory::RingBuffer* reader, + uint32_t packet, uint32_t count) { + SCOPE_profile_cpu_f("gpu"); + + // load sequencer instruction memory (code embedded in packet) + uint32_t dword0 = reader->ReadAndSwap(); + uint32_t dword1 = reader->ReadAndSwap(); + auto shader_type = static_cast(dword0); + uint32_t start_size = dword1; + uint32_t start = start_size >> 16; + uint32_t size_dwords = start_size & 0xFFFF; // dwords + assert_true(start == 0); + assert_true(reader->read_count() >= size_dwords * 4); + assert_true(count - 2 >= size_dwords); + auto shader = LoadShader(shader_type, uint32_t(reader->read_ptr()), + reinterpret_cast(reader->read_ptr()), size_dwords); + switch (shader_type) { + case xenos::ShaderType::kVertex: + active_vertex_shader_ = shader; + break; + case xenos::ShaderType::kPixel: + active_pixel_shader_ = shader; + break; + default: + assert_unhandled_case(shader_type); + return false; + } + reader->AdvanceRead(size_dwords * sizeof(uint32_t)); + return true; +} + +bool CommandProcessor::ExecutePacketType3_INVALIDATE_STATE(memory::RingBuffer* reader, + uint32_t packet, uint32_t count) { + // selective invalidation of state pointers + /*uint32_t mask =*/reader->ReadAndSwap(); + // driver_->InvalidateState(mask); + return true; +} + +bool CommandProcessor::ExecutePacketType3_VIZ_QUERY(memory::RingBuffer* reader, uint32_t packet, + uint32_t count) { + // begin/end initiator for viz query extent processing + // https://www.google.com/patents/US20050195186 + assert_true(count == 1); + + uint32_t dword0 = reader->ReadAndSwap(); + + uint32_t id = dword0 & 0x3F; + uint32_t end = dword0 & 0x100; + if (!end) { + // begin a new viz query @ id + // On hardware this clears the internal state of the scan converter (which + // is different to the register) + WriteRegister(XE_GPU_REG_VGT_EVENT_INITIATOR, VIZQUERY_START); + REXGPU_INFO("Begin viz query ID {:02X}", id); + } else { + // end the viz query + WriteRegister(XE_GPU_REG_VGT_EVENT_INITIATOR, VIZQUERY_END); + REXGPU_INFO("End viz query ID {:02X}", id); + // The scan converter writes the internal result back to the register here. + // We just fake it and say it was visible in case it is read back. + if (id < 32) { + register_file_->values[XE_GPU_REG_PA_SC_VIZ_QUERY_STATUS_0] |= uint32_t(1) << id; + } else { + register_file_->values[XE_GPU_REG_PA_SC_VIZ_QUERY_STATUS_1] |= uint32_t(1) << (id - 32); + } + } + + return true; +} + +void CommandProcessor::InitializeTrace() { + // Write the initial register values, to be loaded directly into the + // RegisterFile since all registers, including those that may have side + // effects on setting, will be saved. + trace_writer_.WriteRegisters(0, register_file_->values, RegisterFile::kRegisterCount, false); + + trace_writer_.WriteGammaRamp(gamma_ramp_256_entry_table(), gamma_ramp_pwl_rgb(), + gamma_ramp_rw_component_); +} + +} // namespace rex::graphics diff --git a/src/graphics/d3d12/command_processor.cpp b/src/graphics/d3d12/command_processor.cpp new file mode 100644 index 0000000..efed1b7 --- /dev/null +++ b/src/graphics/d3d12/command_processor.cpp @@ -0,0 +1,5071 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(d3d12_bindless, true, "GPU/D3D12", "Use bindless resources where available") + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_BOOL(d3d12_readback_memexport, false, "GPU/D3D12", + "Read data written by memory export in shaders on the CPU") + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +REXCVAR_DEFINE_BOOL(d3d12_readback_resolve, false, "GPU/D3D12", + "Read render-to-texture results on the CPU") + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +REXCVAR_DEFINE_BOOL(d3d12_submit_on_primary_buffer_end, true, "GPU/D3D12", + "Submit command list when PM4 primary buffer ends") + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +namespace rex::graphics::d3d12 { + +// Generated with `xb buildshaders`. +namespace shaders { +#include "../shaders/bytecode/d3d12_5_1/apply_gamma_pwl_cs.h" +#include "../shaders/bytecode/d3d12_5_1/apply_gamma_pwl_fxaa_luma_cs.h" +#include "../shaders/bytecode/d3d12_5_1/apply_gamma_table_cs.h" +#include "../shaders/bytecode/d3d12_5_1/apply_gamma_table_fxaa_luma_cs.h" +#include "../shaders/bytecode/d3d12_5_1/fxaa_cs.h" +#include "../shaders/bytecode/d3d12_5_1/fxaa_extreme_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_downscale_cs.h" +} // namespace shaders + +D3D12CommandProcessor::D3D12CommandProcessor(D3D12GraphicsSystem* graphics_system, + system::KernelState* kernel_state) + : CommandProcessor(graphics_system, kernel_state), deferred_command_list_(*this) { + legacy_readback_memexport_cvar_name_ = "d3d12_readback_memexport"; +} +D3D12CommandProcessor::~D3D12CommandProcessor() = default; + +void D3D12CommandProcessor::UpdateDebugMarkersEnabled() { + debug_markers_enabled_ = IsGpuDebugMarkersEnabled(); +} + +void D3D12CommandProcessor::PushDebugMarker(const char* format, ...) { + if (!debug_markers_enabled_) { + return; + } + char label[256]; + va_list args; + va_start(args, format); + vsnprintf(label, sizeof(label), format, args); + va_end(args); + deferred_command_list_.BeginDebugMarker(label); +} + +void D3D12CommandProcessor::PopDebugMarker() { + if (!debug_markers_enabled_) { + return; + } + deferred_command_list_.EndDebugMarker(); +} + +void D3D12CommandProcessor::InsertDebugMarker(const char* format, ...) { + if (!debug_markers_enabled_) { + return; + } + char label[256]; + va_list args; + va_start(args, format); + vsnprintf(label, sizeof(label), format, args); + va_end(args); + deferred_command_list_.InsertDebugMarker(label); +} + +void D3D12CommandProcessor::ClearCaches() { + CommandProcessor::ClearCaches(); + InvalidateAllVertexBufferResidency(); + cache_clear_requested_ = true; +} + +void D3D12CommandProcessor::InvalidateGpuMemory() { + if (shared_memory_) { + shared_memory_->InvalidateAllPages(); + } +} + +void D3D12CommandProcessor::InvalidateAllVertexBufferResidency() { + vertex_buffers_in_sync_[0] = 0; + vertex_buffers_in_sync_[1] = 0; + for (VertexBufferState& state : vertex_buffer_states_) { + state.address = UINT32_MAX; + state.size = UINT32_MAX; + } +} + +void D3D12CommandProcessor::InvalidateVertexBufferResidency(uint32_t vfetch_index) { + if (vfetch_index >= vertex_buffer_states_.size()) { + return; + } + vertex_buffers_in_sync_[vfetch_index >> 6] &= ~(uint64_t(1) << (vfetch_index & 63)); +} + +void D3D12CommandProcessor::InvalidateVertexBufferResidencyRange(uint32_t first_vfetch, + uint32_t last_vfetch) { + if (first_vfetch > last_vfetch) { + std::swap(first_vfetch, last_vfetch); + } + if (first_vfetch >= vertex_buffer_states_.size()) { + return; + } + last_vfetch = std::min(last_vfetch, uint32_t(vertex_buffer_states_.size() - 1)); + for (uint32_t vfetch_index = first_vfetch; vfetch_index <= last_vfetch; ++vfetch_index) { + InvalidateVertexBufferResidency(vfetch_index); + } +} + +void D3D12CommandProcessor::InitializeShaderStorage(const std::filesystem::path& cache_root, + uint32_t title_id, bool blocking) { + CommandProcessor::InitializeShaderStorage(cache_root, title_id, blocking); + pipeline_cache_->InitializeShaderStorage(cache_root, title_id, blocking); +} + +void D3D12CommandProcessor::RequestFrameTrace(const std::filesystem::path& root_path) { + // Capture with PIX if attached. + if (GetD3D12Provider().GetGraphicsAnalysis() != nullptr) { + pix_capture_requested_.store(true, std::memory_order_relaxed); + return; + } + CommandProcessor::RequestFrameTrace(root_path); +} + +void D3D12CommandProcessor::TracePlaybackWroteMemory(uint32_t base_ptr, uint32_t length) { + shared_memory_->MemoryInvalidationCallback(base_ptr, length, true); + primitive_processor_->MemoryInvalidationCallback(base_ptr, length, true); +} + +void D3D12CommandProcessor::RestoreEdramSnapshot(const void* snapshot) { + // Starting a new frame because descriptors may be needed. + if (!BeginSubmission(true)) { + return; + } + render_target_cache_->RestoreEdramSnapshot(snapshot); +} + +bool D3D12CommandProcessor::ExecutePacketType3_EVENT_WRITE_ZPD(memory::RingBuffer* reader, + uint32_t packet, uint32_t count) { + if (!REXCVAR_GET(occlusion_query_enable) || !occlusion_query_resources_available_) { + return CommandProcessor::ExecutePacketType3_EVENT_WRITE_ZPD(reader, packet, count); + } + + const uint32_t kQueryFinished = rex::byte_swap(0xFFFFFEED); + assert_true(count == 1); + uint32_t initiator = reader->ReadAndSwap(); + WriteRegister(XE_GPU_REG_VGT_EVENT_INITIATOR, initiator & 0x3F); + + uint32_t sample_count_addr = register_file_->values[XE_GPU_REG_RB_SAMPLE_COUNT_ADDR]; + auto* sample_counts = + memory_->TranslatePhysical(sample_count_addr); + if (!sample_counts) { + DisableHostOcclusionQueries(); + return true; + } + + auto write_fallback_result = [sample_counts, kQueryFinished]() -> bool { + auto fake_sample_count = REXCVAR_GET(query_occlusion_fake_sample_count); + if (fake_sample_count < 0) { + return true; + } + bool is_end_via_z_pass = + sample_counts->ZPass_A == kQueryFinished && sample_counts->ZPass_B == kQueryFinished; + bool is_end_via_z_fail = + sample_counts->ZFail_A == kQueryFinished && sample_counts->ZFail_B == kQueryFinished; + std::memset(sample_counts, 0, sizeof(xenos::xe_gpu_depth_sample_counts)); + if (is_end_via_z_pass || is_end_via_z_fail) { + sample_counts->ZPass_A = fake_sample_count; + sample_counts->Total_A = fake_sample_count; + } + return true; + }; + + bool is_end_via_z_pass = + sample_counts->ZPass_A == kQueryFinished && sample_counts->ZPass_B == kQueryFinished; + bool is_end_via_z_fail = + sample_counts->ZFail_A == kQueryFinished && sample_counts->ZFail_B == kQueryFinished; + bool is_end = is_end_via_z_pass || is_end_via_z_fail; + + if (!is_end) { + if (active_occlusion_query_.valid && + active_occlusion_query_.sample_count_address != sample_count_addr) { + DisableHostOcclusionQueries(); + return write_fallback_result(); + } + if (!BeginGuestOcclusionQuery(sample_count_addr)) { + return write_fallback_result(); + } + return true; + } + + if (!active_occlusion_query_.valid || + active_occlusion_query_.sample_count_address != sample_count_addr) { + DisableHostOcclusionQueries(); + return write_fallback_result(); + } + + if (!EndGuestOcclusionQuery(sample_count_addr, sample_counts)) { + return write_fallback_result(); + } + + return true; +} + +bool D3D12CommandProcessor::PushTransitionBarrier(ID3D12Resource* resource, + D3D12_RESOURCE_STATES old_state, + D3D12_RESOURCE_STATES new_state, + UINT subresource) { + if (old_state == new_state) { + return false; + } + D3D12_RESOURCE_BARRIER barrier; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.Transition.pResource = resource; + barrier.Transition.Subresource = subresource; + barrier.Transition.StateBefore = old_state; + barrier.Transition.StateAfter = new_state; + barriers_.push_back(barrier); + return true; +} + +void D3D12CommandProcessor::PushAliasingBarrier(ID3D12Resource* old_resource, + ID3D12Resource* new_resource) { + D3D12_RESOURCE_BARRIER barrier; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.Aliasing.pResourceBefore = old_resource; + barrier.Aliasing.pResourceAfter = new_resource; + barriers_.push_back(barrier); +} + +void D3D12CommandProcessor::PushUAVBarrier(ID3D12Resource* resource) { + D3D12_RESOURCE_BARRIER barrier; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.UAV.pResource = resource; + barriers_.push_back(barrier); +} + +void D3D12CommandProcessor::SubmitBarriers() { + UINT barrier_count = UINT(barriers_.size()); + if (barrier_count != 0) { + deferred_command_list_.D3DResourceBarrier(barrier_count, barriers_.data()); + barriers_.clear(); + } +} + +ID3D12RootSignature* D3D12CommandProcessor::GetRootSignature(const DxbcShader* vertex_shader, + const DxbcShader* pixel_shader, + bool tessellated) { + if (bindless_resources_used_) { + return tessellated ? root_signature_bindless_ds_ : root_signature_bindless_vs_; + } + + D3D12_SHADER_VISIBILITY vertex_visibility = + tessellated ? D3D12_SHADER_VISIBILITY_DOMAIN : D3D12_SHADER_VISIBILITY_VERTEX; + + uint32_t texture_count_vertex = + uint32_t(vertex_shader->GetTextureBindingsAfterTranslation().size()); + uint32_t sampler_count_vertex = + uint32_t(vertex_shader->GetSamplerBindingsAfterTranslation().size()); + uint32_t texture_count_pixel = + pixel_shader ? uint32_t(pixel_shader->GetTextureBindingsAfterTranslation().size()) : 0; + uint32_t sampler_count_pixel = + pixel_shader ? uint32_t(pixel_shader->GetSamplerBindingsAfterTranslation().size()) : 0; + + // Better put the pixel texture/sampler in the lower bits probably because it + // changes often. + uint32_t index = 0; + uint32_t index_offset = 0; + index |= texture_count_pixel << index_offset; + index_offset += D3D12Shader::kMaxTextureBindingIndexBits; + index |= sampler_count_pixel << index_offset; + index_offset += D3D12Shader::kMaxSamplerBindingIndexBits; + index |= texture_count_vertex << index_offset; + index_offset += D3D12Shader::kMaxTextureBindingIndexBits; + index |= sampler_count_vertex << index_offset; + index_offset += D3D12Shader::kMaxSamplerBindingIndexBits; + index |= uint32_t(vertex_visibility == D3D12_SHADER_VISIBILITY_DOMAIN) << index_offset; + ++index_offset; + assert_true(index_offset <= 32); + + // Try an existing root signature. + auto it = root_signatures_bindful_.find(index); + if (it != root_signatures_bindful_.end()) { + return it->second; + } + + // Create a new one. + D3D12_ROOT_SIGNATURE_DESC desc; + D3D12_ROOT_PARAMETER parameters[kRootParameter_Bindful_Count_Max]; + desc.NumParameters = kRootParameter_Bindful_Count_Base; + desc.pParameters = parameters; + desc.NumStaticSamplers = 0; + desc.pStaticSamplers = nullptr; + desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; + + // Base parameters. + + // Fetch constants. + { + auto& parameter = parameters[kRootParameter_Bindful_FetchConstants]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + parameter.Descriptor.ShaderRegister = + uint32_t(DxbcShaderTranslator::CbufferRegister::kFetchConstants); + parameter.Descriptor.RegisterSpace = 0; + parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + + // Vertex float constants. + { + auto& parameter = parameters[kRootParameter_Bindful_FloatConstantsVertex]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + parameter.Descriptor.ShaderRegister = + uint32_t(DxbcShaderTranslator::CbufferRegister::kFloatConstants); + parameter.Descriptor.RegisterSpace = 0; + parameter.ShaderVisibility = vertex_visibility; + } + + // Pixel float constants. + { + auto& parameter = parameters[kRootParameter_Bindful_FloatConstantsPixel]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + parameter.Descriptor.ShaderRegister = + uint32_t(DxbcShaderTranslator::CbufferRegister::kFloatConstants); + parameter.Descriptor.RegisterSpace = 0; + parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + } + + // System constants. + { + auto& parameter = parameters[kRootParameter_Bindful_SystemConstants]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + parameter.Descriptor.ShaderRegister = + uint32_t(DxbcShaderTranslator::CbufferRegister::kSystemConstants); + parameter.Descriptor.RegisterSpace = 0; + parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + + // Bool and loop constants. + { + auto& parameter = parameters[kRootParameter_Bindful_BoolLoopConstants]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + parameter.Descriptor.ShaderRegister = + uint32_t(DxbcShaderTranslator::CbufferRegister::kBoolLoopConstants); + parameter.Descriptor.RegisterSpace = 0; + parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + + // Shared memory and, if ROVs are used, EDRAM. + D3D12_DESCRIPTOR_RANGE shared_memory_and_edram_ranges[3]; + { + auto& parameter = parameters[kRootParameter_Bindful_SharedMemoryAndEdram]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + parameter.DescriptorTable.NumDescriptorRanges = 2; + parameter.DescriptorTable.pDescriptorRanges = shared_memory_and_edram_ranges; + parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + shared_memory_and_edram_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + shared_memory_and_edram_ranges[0].NumDescriptors = 1; + shared_memory_and_edram_ranges[0].BaseShaderRegister = + uint32_t(DxbcShaderTranslator::SRVMainRegister::kSharedMemory); + shared_memory_and_edram_ranges[0].RegisterSpace = + uint32_t(DxbcShaderTranslator::SRVSpace::kMain); + shared_memory_and_edram_ranges[0].OffsetInDescriptorsFromTableStart = 0; + shared_memory_and_edram_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + shared_memory_and_edram_ranges[1].NumDescriptors = 1; + shared_memory_and_edram_ranges[1].BaseShaderRegister = + UINT(DxbcShaderTranslator::UAVRegister::kSharedMemory); + shared_memory_and_edram_ranges[1].RegisterSpace = 0; + shared_memory_and_edram_ranges[1].OffsetInDescriptorsFromTableStart = 1; + if (render_target_cache_->GetPath() == RenderTargetCache::Path::kPixelShaderInterlock) { + ++parameter.DescriptorTable.NumDescriptorRanges; + shared_memory_and_edram_ranges[2].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + shared_memory_and_edram_ranges[2].NumDescriptors = 1; + shared_memory_and_edram_ranges[2].BaseShaderRegister = + UINT(DxbcShaderTranslator::UAVRegister::kEdram); + shared_memory_and_edram_ranges[2].RegisterSpace = 0; + shared_memory_and_edram_ranges[2].OffsetInDescriptorsFromTableStart = 2; + } + } + + // Extra parameters. + + // Pixel textures. + D3D12_DESCRIPTOR_RANGE range_textures_pixel; + if (texture_count_pixel > 0) { + auto& parameter = parameters[desc.NumParameters]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + parameter.DescriptorTable.NumDescriptorRanges = 1; + parameter.DescriptorTable.pDescriptorRanges = &range_textures_pixel; + parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + range_textures_pixel.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + range_textures_pixel.NumDescriptors = texture_count_pixel; + range_textures_pixel.BaseShaderRegister = + uint32_t(DxbcShaderTranslator::SRVMainRegister::kBindfulTexturesStart); + range_textures_pixel.RegisterSpace = uint32_t(DxbcShaderTranslator::SRVSpace::kMain); + range_textures_pixel.OffsetInDescriptorsFromTableStart = 0; + ++desc.NumParameters; + } + + // Pixel samplers. + D3D12_DESCRIPTOR_RANGE range_samplers_pixel; + if (sampler_count_pixel > 0) { + auto& parameter = parameters[desc.NumParameters]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + parameter.DescriptorTable.NumDescriptorRanges = 1; + parameter.DescriptorTable.pDescriptorRanges = &range_samplers_pixel; + parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + range_samplers_pixel.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + range_samplers_pixel.NumDescriptors = sampler_count_pixel; + range_samplers_pixel.BaseShaderRegister = 0; + range_samplers_pixel.RegisterSpace = 0; + range_samplers_pixel.OffsetInDescriptorsFromTableStart = 0; + ++desc.NumParameters; + } + + // Vertex textures. + D3D12_DESCRIPTOR_RANGE range_textures_vertex; + if (texture_count_vertex > 0) { + auto& parameter = parameters[desc.NumParameters]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + parameter.DescriptorTable.NumDescriptorRanges = 1; + parameter.DescriptorTable.pDescriptorRanges = &range_textures_vertex; + parameter.ShaderVisibility = vertex_visibility; + range_textures_vertex.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + range_textures_vertex.NumDescriptors = texture_count_vertex; + range_textures_vertex.BaseShaderRegister = + uint32_t(DxbcShaderTranslator::SRVMainRegister::kBindfulTexturesStart); + range_textures_vertex.RegisterSpace = uint32_t(DxbcShaderTranslator::SRVSpace::kMain); + range_textures_vertex.OffsetInDescriptorsFromTableStart = 0; + ++desc.NumParameters; + } + + // Vertex samplers. + D3D12_DESCRIPTOR_RANGE range_samplers_vertex; + if (sampler_count_vertex > 0) { + auto& parameter = parameters[desc.NumParameters]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + parameter.DescriptorTable.NumDescriptorRanges = 1; + parameter.DescriptorTable.pDescriptorRanges = &range_samplers_vertex; + parameter.ShaderVisibility = vertex_visibility; + range_samplers_vertex.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + range_samplers_vertex.NumDescriptors = sampler_count_vertex; + range_samplers_vertex.BaseShaderRegister = 0; + range_samplers_vertex.RegisterSpace = 0; + range_samplers_vertex.OffsetInDescriptorsFromTableStart = 0; + ++desc.NumParameters; + } + + ID3D12RootSignature* root_signature = + ui::d3d12::util::CreateRootSignature(GetD3D12Provider(), desc); + if (root_signature == nullptr) { + REXGPU_ERROR( + "Failed to create a root signature with {} pixel textures, {} pixel " + "samplers, {} vertex textures and {} vertex samplers", + texture_count_pixel, sampler_count_pixel, texture_count_vertex, sampler_count_vertex); + return nullptr; + } + root_signatures_bindful_.emplace(index, root_signature); + return root_signature; +} + +uint32_t D3D12CommandProcessor::GetRootBindfulExtraParameterIndices( + const DxbcShader* vertex_shader, const DxbcShader* pixel_shader, + RootBindfulExtraParameterIndices& indices_out) { + uint32_t index = kRootParameter_Bindful_Count_Base; + if (pixel_shader && !pixel_shader->GetTextureBindingsAfterTranslation().empty()) { + indices_out.textures_pixel = index++; + } else { + indices_out.textures_pixel = RootBindfulExtraParameterIndices::kUnavailable; + } + if (pixel_shader && !pixel_shader->GetSamplerBindingsAfterTranslation().empty()) { + indices_out.samplers_pixel = index++; + } else { + indices_out.samplers_pixel = RootBindfulExtraParameterIndices::kUnavailable; + } + if (!vertex_shader->GetTextureBindingsAfterTranslation().empty()) { + indices_out.textures_vertex = index++; + } else { + indices_out.textures_vertex = RootBindfulExtraParameterIndices::kUnavailable; + } + if (!vertex_shader->GetSamplerBindingsAfterTranslation().empty()) { + indices_out.samplers_vertex = index++; + } else { + indices_out.samplers_vertex = RootBindfulExtraParameterIndices::kUnavailable; + } + return index; +} + +uint64_t D3D12CommandProcessor::RequestViewBindfulDescriptors( + uint64_t previous_heap_index, uint32_t count_for_partial_update, uint32_t count_for_full_update, + D3D12_CPU_DESCRIPTOR_HANDLE& cpu_handle_out, D3D12_GPU_DESCRIPTOR_HANDLE& gpu_handle_out) { + assert_false(bindless_resources_used_); + assert_true(submission_open_); + uint32_t descriptor_index; + uint64_t current_heap_index = view_bindful_heap_pool_->Request( + frame_current_, previous_heap_index, count_for_partial_update, count_for_full_update, + descriptor_index); + if (current_heap_index == ui::d3d12::D3D12DescriptorHeapPool::kHeapIndexInvalid) { + // There was an error. + return ui::d3d12::D3D12DescriptorHeapPool::kHeapIndexInvalid; + } + ID3D12DescriptorHeap* heap = view_bindful_heap_pool_->GetLastRequestHeap(); + if (view_bindful_heap_current_ != heap) { + view_bindful_heap_current_ = heap; + deferred_command_list_.SetDescriptorHeaps(view_bindful_heap_current_, + sampler_bindful_heap_current_); + } + const ui::d3d12::D3D12Provider& provider = GetD3D12Provider(); + cpu_handle_out = provider.OffsetViewDescriptor( + view_bindful_heap_pool_->GetLastRequestHeapCPUStart(), descriptor_index); + gpu_handle_out = provider.OffsetViewDescriptor( + view_bindful_heap_pool_->GetLastRequestHeapGPUStart(), descriptor_index); + return current_heap_index; +} + +uint32_t D3D12CommandProcessor::RequestPersistentViewBindlessDescriptor() { + assert_true(bindless_resources_used_); + if (!view_bindless_heap_free_.empty()) { + uint32_t descriptor_index = view_bindless_heap_free_.back(); + view_bindless_heap_free_.pop_back(); + return descriptor_index; + } + if (view_bindless_heap_allocated_ >= kViewBindlessHeapSize) { + return UINT32_MAX; + } + return view_bindless_heap_allocated_++; +} + +void D3D12CommandProcessor::ReleaseViewBindlessDescriptorImmediately(uint32_t descriptor_index) { + assert_true(bindless_resources_used_); + view_bindless_heap_free_.push_back(descriptor_index); +} + +bool D3D12CommandProcessor::RequestOneUseSingleViewDescriptors( + uint32_t count, ui::d3d12::util::DescriptorCpuGpuHandlePair* handles_out) { + assert_true(submission_open_); + if (!count) { + return true; + } + assert_not_null(handles_out); + const ui::d3d12::D3D12Provider& provider = GetD3D12Provider(); + if (bindless_resources_used_) { + // Request separate bindless descriptors that will be freed when this + // submission is completed by the GPU. + if (count > + kViewBindlessHeapSize - view_bindless_heap_allocated_ + view_bindless_heap_free_.size()) { + return false; + } + for (uint32_t i = 0; i < count; ++i) { + uint32_t descriptor_index; + if (!view_bindless_heap_free_.empty()) { + descriptor_index = view_bindless_heap_free_.back(); + view_bindless_heap_free_.pop_back(); + } else { + descriptor_index = view_bindless_heap_allocated_++; + } + view_bindless_one_use_descriptors_.push_back( + std::make_pair(descriptor_index, submission_current_)); + handles_out[i] = std::make_pair( + provider.OffsetViewDescriptor(view_bindless_heap_cpu_start_, descriptor_index), + provider.OffsetViewDescriptor(view_bindless_heap_gpu_start_, descriptor_index)); + } + } else { + // Request a range within the current heap for bindful resources path. + D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle_start; + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle_start; + if (RequestViewBindfulDescriptors(ui::d3d12::D3D12DescriptorHeapPool::kHeapIndexInvalid, count, + count, cpu_handle_start, gpu_handle_start) == + ui::d3d12::D3D12DescriptorHeapPool::kHeapIndexInvalid) { + return false; + } + for (uint32_t i = 0; i < count; ++i) { + handles_out[i] = std::make_pair(provider.OffsetViewDescriptor(cpu_handle_start, i), + provider.OffsetViewDescriptor(gpu_handle_start, i)); + } + } + return true; +} + +ui::d3d12::util::DescriptorCpuGpuHandlePair D3D12CommandProcessor::GetSystemBindlessViewHandlePair( + SystemBindlessView view) const { + assert_true(bindless_resources_used_); + const ui::d3d12::D3D12Provider& provider = GetD3D12Provider(); + return std::make_pair( + provider.OffsetViewDescriptor(view_bindless_heap_cpu_start_, uint32_t(view)), + provider.OffsetViewDescriptor(view_bindless_heap_gpu_start_, uint32_t(view))); +} + +ui::d3d12::util::DescriptorCpuGpuHandlePair +D3D12CommandProcessor::GetSharedMemoryUintPow2BindlessSRVHandlePair( + uint32_t element_size_bytes_pow2) const { + SystemBindlessView view; + switch (element_size_bytes_pow2) { + case 2: + view = SystemBindlessView::kSharedMemoryR32UintSRV; + break; + case 3: + view = SystemBindlessView::kSharedMemoryR32G32UintSRV; + break; + case 4: + view = SystemBindlessView::kSharedMemoryR32G32B32A32UintSRV; + break; + default: + assert_unhandled_case(element_size_bytes_pow2); + view = SystemBindlessView::kSharedMemoryR32UintSRV; + } + return GetSystemBindlessViewHandlePair(view); +} + +ui::d3d12::util::DescriptorCpuGpuHandlePair +D3D12CommandProcessor::GetSharedMemoryUintPow2BindlessUAVHandlePair( + uint32_t element_size_bytes_pow2) const { + SystemBindlessView view; + switch (element_size_bytes_pow2) { + case 2: + view = SystemBindlessView::kSharedMemoryR32UintUAV; + break; + case 3: + view = SystemBindlessView::kSharedMemoryR32G32UintUAV; + break; + case 4: + view = SystemBindlessView::kSharedMemoryR32G32B32A32UintUAV; + break; + default: + assert_unhandled_case(element_size_bytes_pow2); + view = SystemBindlessView::kSharedMemoryR32UintUAV; + } + return GetSystemBindlessViewHandlePair(view); +} + +ui::d3d12::util::DescriptorCpuGpuHandlePair +D3D12CommandProcessor::GetEdramUintPow2BindlessSRVHandlePair( + uint32_t element_size_bytes_pow2) const { + SystemBindlessView view; + switch (element_size_bytes_pow2) { + case 2: + view = SystemBindlessView::kEdramR32UintSRV; + break; + case 3: + view = SystemBindlessView::kEdramR32G32UintSRV; + break; + case 4: + view = SystemBindlessView::kEdramR32G32B32A32UintSRV; + break; + default: + assert_unhandled_case(element_size_bytes_pow2); + view = SystemBindlessView::kEdramR32UintSRV; + } + return GetSystemBindlessViewHandlePair(view); +} + +ui::d3d12::util::DescriptorCpuGpuHandlePair +D3D12CommandProcessor::GetEdramUintPow2BindlessUAVHandlePair( + uint32_t element_size_bytes_pow2) const { + SystemBindlessView view; + switch (element_size_bytes_pow2) { + case 2: + view = SystemBindlessView::kEdramR32UintUAV; + break; + case 3: + view = SystemBindlessView::kEdramR32G32UintUAV; + break; + case 4: + view = SystemBindlessView::kEdramR32G32B32A32UintUAV; + break; + default: + assert_unhandled_case(element_size_bytes_pow2); + view = SystemBindlessView::kEdramR32UintUAV; + } + return GetSystemBindlessViewHandlePair(view); +} + +uint64_t D3D12CommandProcessor::RequestSamplerBindfulDescriptors( + uint64_t previous_heap_index, uint32_t count_for_partial_update, uint32_t count_for_full_update, + D3D12_CPU_DESCRIPTOR_HANDLE& cpu_handle_out, D3D12_GPU_DESCRIPTOR_HANDLE& gpu_handle_out) { + assert_false(bindless_resources_used_); + assert_true(submission_open_); + uint32_t descriptor_index; + uint64_t current_heap_index = sampler_bindful_heap_pool_->Request( + frame_current_, previous_heap_index, count_for_partial_update, count_for_full_update, + descriptor_index); + if (current_heap_index == ui::d3d12::D3D12DescriptorHeapPool::kHeapIndexInvalid) { + // There was an error. + return ui::d3d12::D3D12DescriptorHeapPool::kHeapIndexInvalid; + } + ID3D12DescriptorHeap* heap = sampler_bindful_heap_pool_->GetLastRequestHeap(); + if (sampler_bindful_heap_current_ != heap) { + sampler_bindful_heap_current_ = heap; + deferred_command_list_.SetDescriptorHeaps(view_bindful_heap_current_, + sampler_bindful_heap_current_); + } + const ui::d3d12::D3D12Provider& provider = GetD3D12Provider(); + cpu_handle_out = provider.OffsetSamplerDescriptor( + sampler_bindful_heap_pool_->GetLastRequestHeapCPUStart(), descriptor_index); + gpu_handle_out = provider.OffsetSamplerDescriptor( + sampler_bindful_heap_pool_->GetLastRequestHeapGPUStart(), descriptor_index); + return current_heap_index; +} + +ID3D12Resource* D3D12CommandProcessor::RequestScratchGPUBuffer(uint32_t size, + D3D12_RESOURCE_STATES state) { + assert_true(submission_open_); + assert_false(scratch_buffer_used_); + if (!submission_open_ || scratch_buffer_used_ || size == 0) { + return nullptr; + } + + if (size <= scratch_buffer_size_) { + PushTransitionBarrier(scratch_buffer_, scratch_buffer_state_, state); + scratch_buffer_state_ = state; + scratch_buffer_used_ = true; + return scratch_buffer_; + } + + size = rex::align(size, kScratchBufferSizeIncrement); + + const ui::d3d12::D3D12Provider& provider = GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + D3D12_RESOURCE_DESC buffer_desc; + ui::d3d12::util::FillBufferResourceDesc(buffer_desc, size, + D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); + ID3D12Resource* buffer; + if (FAILED(device->CreateCommittedResource(&ui::d3d12::util::kHeapPropertiesDefault, + provider.GetHeapFlagCreateNotZeroed(), &buffer_desc, + state, nullptr, IID_PPV_ARGS(&buffer)))) { + REXGPU_ERROR("Failed to create a {} MB scratch GPU buffer", size >> 20); + return nullptr; + } + if (scratch_buffer_ != nullptr) { + resources_for_deletion_.emplace_back(submission_current_, scratch_buffer_); + } + scratch_buffer_ = buffer; + scratch_buffer_size_ = size; + scratch_buffer_state_ = state; + scratch_buffer_used_ = true; + return scratch_buffer_; +} + +void D3D12CommandProcessor::ReleaseScratchGPUBuffer(ID3D12Resource* buffer, + D3D12_RESOURCE_STATES new_state) { + assert_true(submission_open_); + assert_true(scratch_buffer_used_); + scratch_buffer_used_ = false; + if (buffer == scratch_buffer_) { + scratch_buffer_state_ = new_state; + } +} + +void D3D12CommandProcessor::SetExternalPipeline(ID3D12PipelineState* pipeline) { + if (current_external_pipeline_ != pipeline) { + current_external_pipeline_ = pipeline; + current_guest_pipeline_ = nullptr; + deferred_command_list_.D3DSetPipelineState(pipeline); + } +} + +void D3D12CommandProcessor::SetExternalGraphicsRootSignature(ID3D12RootSignature* root_signature) { + if (current_graphics_root_signature_ != root_signature) { + current_graphics_root_signature_ = root_signature; + deferred_command_list_.D3DSetGraphicsRootSignature(root_signature); + } + // Force-invalidate because setting a non-guest root signature. + current_graphics_root_up_to_date_ = 0; +} + +void D3D12CommandProcessor::SetViewport(const D3D12_VIEWPORT& viewport) { + ff_viewport_update_needed_ |= ff_viewport_.TopLeftX != viewport.TopLeftX; + ff_viewport_update_needed_ |= ff_viewport_.TopLeftY != viewport.TopLeftY; + ff_viewport_update_needed_ |= ff_viewport_.Width != viewport.Width; + ff_viewport_update_needed_ |= ff_viewport_.Height != viewport.Height; + ff_viewport_update_needed_ |= ff_viewport_.MinDepth != viewport.MinDepth; + ff_viewport_update_needed_ |= ff_viewport_.MaxDepth != viewport.MaxDepth; + if (ff_viewport_update_needed_) { + ff_viewport_ = viewport; + deferred_command_list_.RSSetViewport(ff_viewport_); + ff_viewport_update_needed_ = false; + } +} + +void D3D12CommandProcessor::SetScissorRect(const D3D12_RECT& scissor_rect) { + ff_scissor_update_needed_ |= ff_scissor_.left != scissor_rect.left; + ff_scissor_update_needed_ |= ff_scissor_.top != scissor_rect.top; + ff_scissor_update_needed_ |= ff_scissor_.right != scissor_rect.right; + ff_scissor_update_needed_ |= ff_scissor_.bottom != scissor_rect.bottom; + if (ff_scissor_update_needed_) { + ff_scissor_ = scissor_rect; + deferred_command_list_.RSSetScissorRect(ff_scissor_); + ff_scissor_update_needed_ = false; + } +} + +void D3D12CommandProcessor::SetStencilReference(uint32_t stencil_ref) { + ff_stencil_ref_update_needed_ |= ff_stencil_ref_ != stencil_ref; + if (ff_stencil_ref_update_needed_) { + ff_stencil_ref_ = stencil_ref; + deferred_command_list_.D3DOMSetStencilRef(stencil_ref); + ff_stencil_ref_update_needed_ = false; + } +} + +void D3D12CommandProcessor::SetPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY primitive_topology) { + if (primitive_topology_ != primitive_topology) { + primitive_topology_ = primitive_topology; + deferred_command_list_.D3DIASetPrimitiveTopology(primitive_topology); + } +} + +std::string D3D12CommandProcessor::GetWindowTitleText() const { + std::ostringstream title; + title << "Direct3D 12"; + if (render_target_cache_) { + // Rasterizer-ordered views are a feature very rarely used as of 2020 and + // that faces adoption complications (outside of Direct3D - on Vulkan - at + // least), but crucial to Xenia - raise awareness of its usage. + // https://github.com/KhronosGroup/Vulkan-Ecosystem/issues/27#issuecomment-455712319 + // "In Xenia's title bar "D3D12 ROV" can be seen, which was a surprise, as I + // wasn't aware that Xenia D3D12 backend was using Raster Order Views + // feature" - oscarbg in that issue. + switch (render_target_cache_->GetPath()) { + case RenderTargetCache::Path::kHostRenderTargets: + title << " - RTV/DSV"; + break; + case RenderTargetCache::Path::kPixelShaderInterlock: + title << " - ROV"; + break; + default: + break; + } + uint32_t draw_resolution_scale_x = + texture_cache_ ? texture_cache_->draw_resolution_scale_x() : 1; + uint32_t draw_resolution_scale_y = + texture_cache_ ? texture_cache_->draw_resolution_scale_y() : 1; + if (draw_resolution_scale_x > 1 || draw_resolution_scale_y > 1) { + title << ' ' << draw_resolution_scale_x << 'x' << draw_resolution_scale_y; + } + } + return title.str(); +} + +bool D3D12CommandProcessor::SetupContext() { + if (!CommandProcessor::SetupContext()) { + REXGPU_ERROR("Failed to initialize base command processor context"); + return false; + } + InvalidateAllVertexBufferResidency(); + UpdateDebugMarkersEnabled(); + + const ui::d3d12::D3D12Provider& provider = GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + ID3D12CommandQueue* direct_queue = provider.GetDirectQueue(); + + fence_completion_event_ = CreateEvent(nullptr, FALSE, FALSE, nullptr); + if (fence_completion_event_ == nullptr) { + REXGPU_ERROR("Failed to create the fence completion event"); + return false; + } + if (FAILED(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&submission_fence_)))) { + REXGPU_ERROR("Failed to create the submission fence"); + return false; + } + if (FAILED(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, + IID_PPV_ARGS(&queue_operations_since_submission_fence_)))) { + REXGPU_ERROR( + "Failed to create the fence for awaiting queue operations done since " + "the latest submission"); + return false; + } + + // Create the command list and one allocator because it's needed for a command + // list. + ID3D12CommandAllocator* command_allocator; + if (FAILED(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, + IID_PPV_ARGS(&command_allocator)))) { + REXGPU_ERROR("Failed to create a command allocator"); + return false; + } + command_allocator_writable_first_ = new CommandAllocator; + command_allocator_writable_first_->command_allocator = command_allocator; + command_allocator_writable_first_->last_usage_submission = 0; + command_allocator_writable_first_->next = nullptr; + command_allocator_writable_last_ = command_allocator_writable_first_; + if (FAILED(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, command_allocator, + nullptr, IID_PPV_ARGS(&command_list_)))) { + REXGPU_ERROR("Failed to create the graphics command list"); + return false; + } + // Initially in open state, wait until a deferred command list submission. + command_list_->Close(); + // Optional - added in Creators Update (SDK 10.0.15063.0). + command_list_->QueryInterface(IID_PPV_ARGS(&command_list_1_)); + + bindless_resources_used_ = REXCVAR_GET(d3d12_bindless) && + provider.GetResourceBindingTier() >= D3D12_RESOURCE_BINDING_TIER_2; + + // Get the draw resolution scale for the render target cache and the texture + // cache. + uint32_t draw_resolution_scale_x, draw_resolution_scale_y; + bool draw_resolution_scale_not_clamped = + TextureCache::GetConfigDrawResolutionScale(draw_resolution_scale_x, draw_resolution_scale_y); + if (!D3D12TextureCache::ClampDrawResolutionScaleToMaxSupported( + draw_resolution_scale_x, draw_resolution_scale_y, provider)) { + draw_resolution_scale_not_clamped = false; + } + if (!draw_resolution_scale_not_clamped) { + REXGPU_WARN( + "The requested draw resolution scale is not supported by the device or " + "the emulator, reducing to {}x{}", + draw_resolution_scale_x, draw_resolution_scale_y); + } + + shared_memory_ = std::make_unique(*this, *memory_, trace_writer_); + if (!shared_memory_->Initialize()) { + REXGPU_ERROR("Failed to initialize shared memory"); + return false; + } + + // Initialize the render target cache before configuring binding - need to + // know if using rasterizer-ordered views for the bindless root signature. + render_target_cache_ = std::make_unique( + *register_file_, *memory_, trace_writer_, draw_resolution_scale_x, draw_resolution_scale_y, + *this, bindless_resources_used_); + if (!render_target_cache_->Initialize()) { + REXGPU_ERROR("Failed to initialize the render target cache"); + return false; + } + + // Initialize resource binding. + constant_buffer_pool_ = std::make_unique( + provider, std::max(ui::d3d12::D3D12UploadBufferPool::kDefaultPageSize, + sizeof(float) * 4 * D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT)); + if (bindless_resources_used_) { + D3D12_DESCRIPTOR_HEAP_DESC view_bindless_heap_desc; + view_bindless_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + view_bindless_heap_desc.NumDescriptors = kViewBindlessHeapSize; + view_bindless_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + view_bindless_heap_desc.NodeMask = 0; + if (FAILED(device->CreateDescriptorHeap(&view_bindless_heap_desc, + IID_PPV_ARGS(&view_bindless_heap_)))) { + REXGPU_ERROR("Failed to create the bindless CBV/SRV/UAV descriptor heap"); + return false; + } + view_bindless_heap_cpu_start_ = view_bindless_heap_->GetCPUDescriptorHandleForHeapStart(); + view_bindless_heap_gpu_start_ = view_bindless_heap_->GetGPUDescriptorHandleForHeapStart(); + view_bindless_heap_allocated_ = uint32_t(SystemBindlessView::kCount); + + D3D12_DESCRIPTOR_HEAP_DESC sampler_bindless_heap_desc; + sampler_bindless_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; + sampler_bindless_heap_desc.NumDescriptors = kSamplerHeapSize; + sampler_bindless_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + sampler_bindless_heap_desc.NodeMask = 0; + if (FAILED(device->CreateDescriptorHeap(&sampler_bindless_heap_desc, + IID_PPV_ARGS(&sampler_bindless_heap_current_)))) { + REXGPU_ERROR("Failed to create the bindless sampler descriptor heap"); + return false; + } + sampler_bindless_heap_cpu_start_ = + sampler_bindless_heap_current_->GetCPUDescriptorHandleForHeapStart(); + sampler_bindless_heap_gpu_start_ = + sampler_bindless_heap_current_->GetGPUDescriptorHandleForHeapStart(); + sampler_bindless_heap_allocated_ = 0; + } else { + view_bindful_heap_pool_ = std::make_unique( + device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, kViewBindfulHeapSize); + sampler_bindful_heap_pool_ = std::make_unique( + device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, kSamplerHeapSize); + } + + if (bindless_resources_used_) { + // Global bindless resource root signatures. + // No CBV or UAV descriptor ranges with any descriptors to be allocated + // dynamically (via RequestPersistentViewBindlessDescriptor or + // RequestOneUseSingleViewDescriptors) should be here, because they would + // overlap the unbounded SRV range, which is not allowed on Nvidia Fermi! + D3D12_ROOT_SIGNATURE_DESC root_signature_bindless_desc; + D3D12_ROOT_PARAMETER + root_parameters_bindless[kRootParameter_Bindless_Count]; + root_signature_bindless_desc.NumParameters = kRootParameter_Bindless_Count; + root_signature_bindless_desc.pParameters = root_parameters_bindless; + root_signature_bindless_desc.NumStaticSamplers = 0; + root_signature_bindless_desc.pStaticSamplers = nullptr; + root_signature_bindless_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; + // Fetch constants. + { + auto& parameter = root_parameters_bindless[kRootParameter_Bindless_FetchConstants]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + parameter.Descriptor.ShaderRegister = + uint32_t(DxbcShaderTranslator::CbufferRegister::kFetchConstants); + parameter.Descriptor.RegisterSpace = 0; + parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + // Vertex float constants. + { + auto& parameter = root_parameters_bindless[kRootParameter_Bindless_FloatConstantsVertex]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + parameter.Descriptor.ShaderRegister = + uint32_t(DxbcShaderTranslator::CbufferRegister::kFloatConstants); + parameter.Descriptor.RegisterSpace = 0; + parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX; + } + // Pixel float constants. + { + auto& parameter = root_parameters_bindless[kRootParameter_Bindless_FloatConstantsPixel]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + parameter.Descriptor.ShaderRegister = + uint32_t(DxbcShaderTranslator::CbufferRegister::kFloatConstants); + parameter.Descriptor.RegisterSpace = 0; + parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + } + // Pixel shader descriptor indices. + { + auto& parameter = root_parameters_bindless[kRootParameter_Bindless_DescriptorIndicesPixel]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + parameter.Descriptor.ShaderRegister = + uint32_t(DxbcShaderTranslator::CbufferRegister::kDescriptorIndices); + parameter.Descriptor.RegisterSpace = 0; + parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + } + // Vertex shader descriptor indices. + { + auto& parameter = root_parameters_bindless[kRootParameter_Bindless_DescriptorIndicesVertex]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + parameter.Descriptor.ShaderRegister = + uint32_t(DxbcShaderTranslator::CbufferRegister::kDescriptorIndices); + parameter.Descriptor.RegisterSpace = 0; + parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX; + } + // System constants. + { + auto& parameter = root_parameters_bindless[kRootParameter_Bindless_SystemConstants]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + parameter.Descriptor.ShaderRegister = + uint32_t(DxbcShaderTranslator::CbufferRegister::kSystemConstants); + parameter.Descriptor.RegisterSpace = 0; + parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + // Bool and loop constants. + { + auto& parameter = root_parameters_bindless[kRootParameter_Bindless_BoolLoopConstants]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + parameter.Descriptor.ShaderRegister = + uint32_t(DxbcShaderTranslator::CbufferRegister::kBoolLoopConstants); + parameter.Descriptor.RegisterSpace = 0; + parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + // Shared memory SRV and UAV. + D3D12_DESCRIPTOR_RANGE root_shared_memory_view_ranges[2]; + { + auto& parameter = root_parameters_bindless[kRootParameter_Bindless_SharedMemory]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + parameter.DescriptorTable.NumDescriptorRanges = + uint32_t(rex::countof(root_shared_memory_view_ranges)); + parameter.DescriptorTable.pDescriptorRanges = root_shared_memory_view_ranges; + parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + { + auto& range = root_shared_memory_view_ranges[0]; + range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + range.NumDescriptors = 1; + range.BaseShaderRegister = UINT(DxbcShaderTranslator::SRVMainRegister::kSharedMemory); + range.RegisterSpace = UINT(DxbcShaderTranslator::SRVSpace::kMain); + range.OffsetInDescriptorsFromTableStart = 0; + } + { + auto& range = root_shared_memory_view_ranges[1]; + range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + range.NumDescriptors = 1; + range.BaseShaderRegister = UINT(DxbcShaderTranslator::UAVRegister::kSharedMemory); + range.RegisterSpace = 0; + range.OffsetInDescriptorsFromTableStart = 1; + } + } + // Sampler heap. + D3D12_DESCRIPTOR_RANGE root_bindless_sampler_range; + { + auto& parameter = root_parameters_bindless[kRootParameter_Bindless_SamplerHeap]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + // Will be appending. + parameter.DescriptorTable.NumDescriptorRanges = 1; + parameter.DescriptorTable.pDescriptorRanges = &root_bindless_sampler_range; + parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + root_bindless_sampler_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + root_bindless_sampler_range.NumDescriptors = UINT_MAX; + root_bindless_sampler_range.BaseShaderRegister = 0; + root_bindless_sampler_range.RegisterSpace = 0; + root_bindless_sampler_range.OffsetInDescriptorsFromTableStart = 0; + } + // View heap. + D3D12_DESCRIPTOR_RANGE root_bindless_view_ranges[4]; + { + auto& parameter = root_parameters_bindless[kRootParameter_Bindless_ViewHeap]; + parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + // Will be appending. + parameter.DescriptorTable.NumDescriptorRanges = 0; + parameter.DescriptorTable.pDescriptorRanges = root_bindless_view_ranges; + parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + // EDRAM. + if (render_target_cache_->GetPath() == RenderTargetCache::Path::kPixelShaderInterlock) { + assert_true(parameter.DescriptorTable.NumDescriptorRanges < + rex::countof(root_bindless_view_ranges)); + auto& range = root_bindless_view_ranges[parameter.DescriptorTable.NumDescriptorRanges++]; + range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + range.NumDescriptors = 1; + range.BaseShaderRegister = UINT(DxbcShaderTranslator::UAVRegister::kEdram); + range.RegisterSpace = 0; + range.OffsetInDescriptorsFromTableStart = UINT(SystemBindlessView::kEdramR32UintUAV); + } + // Used UAV and SRV ranges must not overlap on Nvidia Fermi, so textures + // have OffsetInDescriptorsFromTableStart after all static descriptors of + // other types. + // 2D array textures. + { + assert_true(parameter.DescriptorTable.NumDescriptorRanges < + rex::countof(root_bindless_view_ranges)); + auto& range = root_bindless_view_ranges[parameter.DescriptorTable.NumDescriptorRanges++]; + range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + range.NumDescriptors = UINT_MAX; + range.BaseShaderRegister = 0; + range.RegisterSpace = UINT(DxbcShaderTranslator::SRVSpace::kBindlessTextures2DArray); + range.OffsetInDescriptorsFromTableStart = UINT(SystemBindlessView::kUnboundedSRVsStart); + } + // 3D textures. + { + assert_true(parameter.DescriptorTable.NumDescriptorRanges < + rex::countof(root_bindless_view_ranges)); + auto& range = root_bindless_view_ranges[parameter.DescriptorTable.NumDescriptorRanges++]; + range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + range.NumDescriptors = UINT_MAX; + range.BaseShaderRegister = 0; + range.RegisterSpace = UINT(DxbcShaderTranslator::SRVSpace::kBindlessTextures3D); + range.OffsetInDescriptorsFromTableStart = UINT(SystemBindlessView::kUnboundedSRVsStart); + } + // Cube textures. + { + assert_true(parameter.DescriptorTable.NumDescriptorRanges < + rex::countof(root_bindless_view_ranges)); + auto& range = root_bindless_view_ranges[parameter.DescriptorTable.NumDescriptorRanges++]; + range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + range.NumDescriptors = UINT_MAX; + range.BaseShaderRegister = 0; + range.RegisterSpace = UINT(DxbcShaderTranslator::SRVSpace::kBindlessTexturesCube); + range.OffsetInDescriptorsFromTableStart = UINT(SystemBindlessView::kUnboundedSRVsStart); + } + } + root_signature_bindless_vs_ = + ui::d3d12::util::CreateRootSignature(provider, root_signature_bindless_desc); + if (!root_signature_bindless_vs_) { + REXGPU_ERROR( + "Failed to create the global root signature for bindless resources, " + "the version for use without tessellation"); + return false; + } + root_parameters_bindless[kRootParameter_Bindless_FloatConstantsVertex].ShaderVisibility = + D3D12_SHADER_VISIBILITY_DOMAIN; + root_parameters_bindless[kRootParameter_Bindless_DescriptorIndicesVertex].ShaderVisibility = + D3D12_SHADER_VISIBILITY_DOMAIN; + root_signature_bindless_ds_ = + ui::d3d12::util::CreateRootSignature(provider, root_signature_bindless_desc); + if (!root_signature_bindless_ds_) { + REXGPU_ERROR( + "Failed to create the global root signature for bindless resources, " + "the version for use with tessellation"); + return false; + } + } + + primitive_processor_ = std::make_unique( + *register_file_, *memory_, trace_writer_, *shared_memory_, *this); + if (!primitive_processor_->Initialize()) { + REXGPU_ERROR("Failed to initialize the geometric primitive processor"); + return false; + } + + texture_cache_ = + D3D12TextureCache::Create(*register_file_, *shared_memory_, draw_resolution_scale_x, + draw_resolution_scale_y, *this, bindless_resources_used_); + if (!texture_cache_) { + REXGPU_ERROR("Failed to initialize the texture cache"); + return false; + } + + pipeline_cache_ = std::make_unique( + *this, *register_file_, *render_target_cache_.get(), bindless_resources_used_); + if (!pipeline_cache_->Initialize()) { + REXGPU_ERROR("Failed to initialize the graphics pipeline cache"); + return false; + } + + D3D12_HEAP_FLAGS heap_flag_create_not_zeroed = provider.GetHeapFlagCreateNotZeroed(); + + // Create gamma ramp resources. + gamma_ramp_256_entry_table_up_to_date_ = false; + gamma_ramp_pwl_up_to_date_ = false; + D3D12_RESOURCE_DESC gamma_ramp_buffer_desc; + ui::d3d12::util::FillBufferResourceDesc(gamma_ramp_buffer_desc, (256 + 128 * 3) * 4, + D3D12_RESOURCE_FLAG_NONE); + // The first action will be uploading. + gamma_ramp_buffer_state_ = D3D12_RESOURCE_STATE_COPY_DEST; + if (FAILED(device->CreateCommittedResource(&ui::d3d12::util::kHeapPropertiesDefault, + heap_flag_create_not_zeroed, &gamma_ramp_buffer_desc, + gamma_ramp_buffer_state_, nullptr, + IID_PPV_ARGS(&gamma_ramp_buffer_)))) { + REXGPU_ERROR("Failed to create the gamma ramp buffer"); + return false; + } + // The upload buffer is frame-buffered. + gamma_ramp_buffer_desc.Width *= kQueueFrames; + if (FAILED(device->CreateCommittedResource(&ui::d3d12::util::kHeapPropertiesUpload, + heap_flag_create_not_zeroed, &gamma_ramp_buffer_desc, + D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, + IID_PPV_ARGS(&gamma_ramp_upload_buffer_)))) { + REXGPU_ERROR("Failed to create the gamma ramp upload buffer"); + return false; + } + if (FAILED(gamma_ramp_upload_buffer_->Map( + 0, nullptr, reinterpret_cast(&gamma_ramp_upload_buffer_mapping_)))) { + REXGPU_ERROR("Failed to map the gamma ramp upload buffer"); + gamma_ramp_upload_buffer_mapping_ = nullptr; + return false; + } + + // Initialize compute pipelines for output with gamma ramp. + D3D12_ROOT_PARAMETER + apply_gamma_root_parameters[UINT(ApplyGammaRootParameter::kCount)]; + { + D3D12_ROOT_PARAMETER& apply_gamma_root_parameter_constants = + apply_gamma_root_parameters[UINT(ApplyGammaRootParameter::kConstants)]; + apply_gamma_root_parameter_constants.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + apply_gamma_root_parameter_constants.Constants.ShaderRegister = 0; + apply_gamma_root_parameter_constants.Constants.RegisterSpace = 0; + apply_gamma_root_parameter_constants.Constants.Num32BitValues = + sizeof(ApplyGammaConstants) / sizeof(uint32_t); + apply_gamma_root_parameter_constants.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + D3D12_DESCRIPTOR_RANGE apply_gamma_root_descriptor_range_dest; + apply_gamma_root_descriptor_range_dest.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + apply_gamma_root_descriptor_range_dest.NumDescriptors = 1; + apply_gamma_root_descriptor_range_dest.BaseShaderRegister = 0; + apply_gamma_root_descriptor_range_dest.RegisterSpace = 0; + apply_gamma_root_descriptor_range_dest.OffsetInDescriptorsFromTableStart = 0; + { + D3D12_ROOT_PARAMETER& apply_gamma_root_parameter_dest = + apply_gamma_root_parameters[UINT(ApplyGammaRootParameter::kDestination)]; + apply_gamma_root_parameter_dest.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + apply_gamma_root_parameter_dest.DescriptorTable.NumDescriptorRanges = 1; + apply_gamma_root_parameter_dest.DescriptorTable.pDescriptorRanges = + &apply_gamma_root_descriptor_range_dest; + apply_gamma_root_parameter_dest.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + D3D12_DESCRIPTOR_RANGE apply_gamma_root_descriptor_range_source; + apply_gamma_root_descriptor_range_source.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + apply_gamma_root_descriptor_range_source.NumDescriptors = 1; + apply_gamma_root_descriptor_range_source.BaseShaderRegister = 1; + apply_gamma_root_descriptor_range_source.RegisterSpace = 0; + apply_gamma_root_descriptor_range_source.OffsetInDescriptorsFromTableStart = 0; + { + D3D12_ROOT_PARAMETER& apply_gamma_root_parameter_source = + apply_gamma_root_parameters[UINT(ApplyGammaRootParameter::kSource)]; + apply_gamma_root_parameter_source.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + apply_gamma_root_parameter_source.DescriptorTable.NumDescriptorRanges = 1; + apply_gamma_root_parameter_source.DescriptorTable.pDescriptorRanges = + &apply_gamma_root_descriptor_range_source; + apply_gamma_root_parameter_source.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + D3D12_DESCRIPTOR_RANGE apply_gamma_root_descriptor_range_ramp; + apply_gamma_root_descriptor_range_ramp.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + apply_gamma_root_descriptor_range_ramp.NumDescriptors = 1; + apply_gamma_root_descriptor_range_ramp.BaseShaderRegister = 0; + apply_gamma_root_descriptor_range_ramp.RegisterSpace = 0; + apply_gamma_root_descriptor_range_ramp.OffsetInDescriptorsFromTableStart = 0; + { + D3D12_ROOT_PARAMETER& apply_gamma_root_parameter_gamma_ramp = + apply_gamma_root_parameters[UINT(ApplyGammaRootParameter::kRamp)]; + apply_gamma_root_parameter_gamma_ramp.ParameterType = + D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + apply_gamma_root_parameter_gamma_ramp.DescriptorTable.NumDescriptorRanges = 1; + apply_gamma_root_parameter_gamma_ramp.DescriptorTable.pDescriptorRanges = + &apply_gamma_root_descriptor_range_ramp; + apply_gamma_root_parameter_gamma_ramp.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + D3D12_ROOT_SIGNATURE_DESC apply_gamma_root_signature_desc; + apply_gamma_root_signature_desc.NumParameters = UINT(ApplyGammaRootParameter::kCount); + apply_gamma_root_signature_desc.pParameters = apply_gamma_root_parameters; + apply_gamma_root_signature_desc.NumStaticSamplers = 0; + apply_gamma_root_signature_desc.pStaticSamplers = nullptr; + apply_gamma_root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; + *(apply_gamma_root_signature_.ReleaseAndGetAddressOf()) = + ui::d3d12::util::CreateRootSignature(provider, apply_gamma_root_signature_desc); + if (!apply_gamma_root_signature_) { + REXGPU_ERROR("Failed to create the gamma ramp application root signature"); + return false; + } + *(apply_gamma_table_pipeline_.ReleaseAndGetAddressOf()) = ui::d3d12::util::CreateComputePipeline( + device, shaders::apply_gamma_table_cs, sizeof(shaders::apply_gamma_table_cs), + apply_gamma_root_signature_.Get()); + if (!apply_gamma_table_pipeline_) { + REXGPU_ERROR( + "Failed to create the 256-entry table gamma ramp application compute " + "pipeline"); + return false; + } + *(apply_gamma_table_fxaa_luma_pipeline_.ReleaseAndGetAddressOf()) = + ui::d3d12::util::CreateComputePipeline(device, shaders::apply_gamma_table_fxaa_luma_cs, + sizeof(shaders::apply_gamma_table_fxaa_luma_cs), + apply_gamma_root_signature_.Get()); + if (!apply_gamma_table_fxaa_luma_pipeline_) { + REXGPU_ERROR( + "Failed to create the 256-entry table gamma ramp application compute " + "pipeline with perceptual luma output"); + return false; + } + *(apply_gamma_pwl_pipeline_.ReleaseAndGetAddressOf()) = ui::d3d12::util::CreateComputePipeline( + device, shaders::apply_gamma_pwl_cs, sizeof(shaders::apply_gamma_pwl_cs), + apply_gamma_root_signature_.Get()); + if (!apply_gamma_pwl_pipeline_) { + REXGPU_ERROR("Failed to create the PWL gamma ramp application compute pipeline"); + return false; + } + *(apply_gamma_pwl_fxaa_luma_pipeline_.ReleaseAndGetAddressOf()) = + ui::d3d12::util::CreateComputePipeline(device, shaders::apply_gamma_pwl_fxaa_luma_cs, + sizeof(shaders::apply_gamma_pwl_fxaa_luma_cs), + apply_gamma_root_signature_.Get()); + if (!apply_gamma_pwl_fxaa_luma_pipeline_) { + REXGPU_ERROR( + "Failed to create the PWL gamma ramp application compute pipeline with " + "perceptual luma output"); + return false; + } + + // Initialize compute pipelines for post-processing anti-aliasing. + D3D12_ROOT_PARAMETER fxaa_root_parameters[UINT(FxaaRootParameter::kCount)]; + { + D3D12_ROOT_PARAMETER& fxaa_root_parameter_constants = + fxaa_root_parameters[UINT(ApplyGammaRootParameter::kConstants)]; + fxaa_root_parameter_constants.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + fxaa_root_parameter_constants.Constants.ShaderRegister = 0; + fxaa_root_parameter_constants.Constants.RegisterSpace = 0; + fxaa_root_parameter_constants.Constants.Num32BitValues = + sizeof(FxaaConstants) / sizeof(uint32_t); + fxaa_root_parameter_constants.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + D3D12_DESCRIPTOR_RANGE fxaa_root_descriptor_range_dest; + fxaa_root_descriptor_range_dest.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + fxaa_root_descriptor_range_dest.NumDescriptors = 1; + fxaa_root_descriptor_range_dest.BaseShaderRegister = 0; + fxaa_root_descriptor_range_dest.RegisterSpace = 0; + fxaa_root_descriptor_range_dest.OffsetInDescriptorsFromTableStart = 0; + { + D3D12_ROOT_PARAMETER& fxaa_root_parameter_dest = + fxaa_root_parameters[UINT(FxaaRootParameter::kDestination)]; + fxaa_root_parameter_dest.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + fxaa_root_parameter_dest.DescriptorTable.NumDescriptorRanges = 1; + fxaa_root_parameter_dest.DescriptorTable.pDescriptorRanges = &fxaa_root_descriptor_range_dest; + fxaa_root_parameter_dest.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + D3D12_DESCRIPTOR_RANGE fxaa_root_descriptor_range_source; + fxaa_root_descriptor_range_source.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + fxaa_root_descriptor_range_source.NumDescriptors = 1; + fxaa_root_descriptor_range_source.BaseShaderRegister = 0; + fxaa_root_descriptor_range_source.RegisterSpace = 0; + fxaa_root_descriptor_range_source.OffsetInDescriptorsFromTableStart = 0; + { + D3D12_ROOT_PARAMETER& fxaa_root_parameter_source = + fxaa_root_parameters[UINT(FxaaRootParameter::kSource)]; + fxaa_root_parameter_source.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + fxaa_root_parameter_source.DescriptorTable.NumDescriptorRanges = 1; + fxaa_root_parameter_source.DescriptorTable.pDescriptorRanges = + &fxaa_root_descriptor_range_source; + fxaa_root_parameter_source.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + D3D12_STATIC_SAMPLER_DESC fxaa_root_sampler; + fxaa_root_sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; + fxaa_root_sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + fxaa_root_sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + fxaa_root_sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + fxaa_root_sampler.MipLODBias = 0.0f; + fxaa_root_sampler.MaxAnisotropy = 1; + fxaa_root_sampler.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER; + fxaa_root_sampler.BorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK; + fxaa_root_sampler.MinLOD = 0.0f; + fxaa_root_sampler.MaxLOD = 0.0f; + fxaa_root_sampler.ShaderRegister = 0; + fxaa_root_sampler.RegisterSpace = 0; + fxaa_root_sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + D3D12_ROOT_SIGNATURE_DESC fxaa_root_signature_desc; + fxaa_root_signature_desc.NumParameters = UINT(FxaaRootParameter::kCount); + fxaa_root_signature_desc.pParameters = fxaa_root_parameters; + fxaa_root_signature_desc.NumStaticSamplers = 1; + fxaa_root_signature_desc.pStaticSamplers = &fxaa_root_sampler; + fxaa_root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; + *(fxaa_root_signature_.ReleaseAndGetAddressOf()) = + ui::d3d12::util::CreateRootSignature(provider, fxaa_root_signature_desc); + if (!fxaa_root_signature_) { + REXGPU_ERROR("Failed to create the FXAA root signature"); + return false; + } + *(fxaa_pipeline_.ReleaseAndGetAddressOf()) = ui::d3d12::util::CreateComputePipeline( + device, shaders::fxaa_cs, sizeof(shaders::fxaa_cs), fxaa_root_signature_.Get()); + if (!fxaa_pipeline_) { + REXGPU_ERROR("Failed to create the FXAA compute pipeline"); + return false; + } + *(fxaa_extreme_pipeline_.ReleaseAndGetAddressOf()) = ui::d3d12::util::CreateComputePipeline( + device, shaders::fxaa_extreme_cs, sizeof(shaders::fxaa_extreme_cs), + fxaa_root_signature_.Get()); + if (!fxaa_pipeline_) { + REXGPU_ERROR("Failed to create the extreme-quality FXAA compute pipeline"); + return false; + } + + // Resolve downscale compute pipeline for scaled readback resolve. + D3D12_ROOT_PARAMETER + resolve_downscale_root_parameters[UINT(ResolveDownscaleRootParameter::kCount)]; + { + D3D12_ROOT_PARAMETER& constants_parameter = + resolve_downscale_root_parameters[UINT(ResolveDownscaleRootParameter::kConstants)]; + constants_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + constants_parameter.Constants.ShaderRegister = 0; + constants_parameter.Constants.RegisterSpace = 0; + constants_parameter.Constants.Num32BitValues = + sizeof(ResolveDownscaleConstants) / sizeof(uint32_t); + constants_parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + D3D12_DESCRIPTOR_RANGE resolve_downscale_source_range; + resolve_downscale_source_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + resolve_downscale_source_range.NumDescriptors = 1; + resolve_downscale_source_range.BaseShaderRegister = 0; + resolve_downscale_source_range.RegisterSpace = 0; + resolve_downscale_source_range.OffsetInDescriptorsFromTableStart = 0; + { + D3D12_ROOT_PARAMETER& source_parameter = + resolve_downscale_root_parameters[UINT(ResolveDownscaleRootParameter::kSource)]; + source_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + source_parameter.DescriptorTable.NumDescriptorRanges = 1; + source_parameter.DescriptorTable.pDescriptorRanges = &resolve_downscale_source_range; + source_parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + D3D12_DESCRIPTOR_RANGE resolve_downscale_destination_range; + resolve_downscale_destination_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + resolve_downscale_destination_range.NumDescriptors = 1; + resolve_downscale_destination_range.BaseShaderRegister = 0; + resolve_downscale_destination_range.RegisterSpace = 0; + resolve_downscale_destination_range.OffsetInDescriptorsFromTableStart = 0; + { + D3D12_ROOT_PARAMETER& destination_parameter = + resolve_downscale_root_parameters[UINT(ResolveDownscaleRootParameter::kDestination)]; + destination_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + destination_parameter.DescriptorTable.NumDescriptorRanges = 1; + destination_parameter.DescriptorTable.pDescriptorRanges = &resolve_downscale_destination_range; + destination_parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + D3D12_ROOT_SIGNATURE_DESC resolve_downscale_root_signature_desc; + resolve_downscale_root_signature_desc.NumParameters = UINT(ResolveDownscaleRootParameter::kCount); + resolve_downscale_root_signature_desc.pParameters = resolve_downscale_root_parameters; + resolve_downscale_root_signature_desc.NumStaticSamplers = 0; + resolve_downscale_root_signature_desc.pStaticSamplers = nullptr; + resolve_downscale_root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; + *(resolve_downscale_root_signature_.ReleaseAndGetAddressOf()) = + ui::d3d12::util::CreateRootSignature(provider, resolve_downscale_root_signature_desc); + if (resolve_downscale_root_signature_) { + *(resolve_downscale_pipeline_.ReleaseAndGetAddressOf()) = + ui::d3d12::util::CreateComputePipeline(device, shaders::resolve_downscale_cs, + sizeof(shaders::resolve_downscale_cs), + resolve_downscale_root_signature_.Get()); + } + if (!resolve_downscale_root_signature_ || !resolve_downscale_pipeline_) { + resolve_downscale_pipeline_.Reset(); + resolve_downscale_root_signature_.Reset(); + REXGPU_WARN("Failed to initialize D3D12 resolve-downscale readback pipeline"); + } + + if (bindless_resources_used_) { + // Create the system bindless descriptors once all resources are + // initialized. + // kNullRawSRV. + ui::d3d12::util::CreateBufferRawSRV( + device, + provider.OffsetViewDescriptor(view_bindless_heap_cpu_start_, + uint32_t(SystemBindlessView::kNullRawSRV)), + nullptr, 0); + // kNullRawUAV. + ui::d3d12::util::CreateBufferRawUAV( + device, + provider.OffsetViewDescriptor(view_bindless_heap_cpu_start_, + uint32_t(SystemBindlessView::kNullRawUAV)), + nullptr, 0); + // kNullTexture2DArray. + D3D12_SHADER_RESOURCE_VIEW_DESC null_srv_desc; + null_srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + null_srv_desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( + D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0, D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0, + D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0, D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0); + null_srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY; + null_srv_desc.Texture2DArray.MostDetailedMip = 0; + null_srv_desc.Texture2DArray.MipLevels = 1; + null_srv_desc.Texture2DArray.FirstArraySlice = 0; + null_srv_desc.Texture2DArray.ArraySize = 1; + null_srv_desc.Texture2DArray.PlaneSlice = 0; + null_srv_desc.Texture2DArray.ResourceMinLODClamp = 0.0f; + device->CreateShaderResourceView( + nullptr, &null_srv_desc, + provider.OffsetViewDescriptor(view_bindless_heap_cpu_start_, + uint32_t(SystemBindlessView::kNullTexture2DArray))); + // kNullTexture3D. + null_srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D; + null_srv_desc.Texture3D.MostDetailedMip = 0; + null_srv_desc.Texture3D.MipLevels = 1; + null_srv_desc.Texture3D.ResourceMinLODClamp = 0.0f; + device->CreateShaderResourceView( + nullptr, &null_srv_desc, + provider.OffsetViewDescriptor(view_bindless_heap_cpu_start_, + uint32_t(SystemBindlessView::kNullTexture3D))); + // kNullTextureCube. + null_srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE; + null_srv_desc.TextureCube.MostDetailedMip = 0; + null_srv_desc.TextureCube.MipLevels = 1; + null_srv_desc.TextureCube.ResourceMinLODClamp = 0.0f; + device->CreateShaderResourceView( + nullptr, &null_srv_desc, + provider.OffsetViewDescriptor(view_bindless_heap_cpu_start_, + uint32_t(SystemBindlessView::kNullTextureCube))); + // kSharedMemoryRawSRV. + shared_memory_->WriteRawSRVDescriptor(provider.OffsetViewDescriptor( + view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kSharedMemoryRawSRV))); + // kSharedMemoryR32UintSRV. + shared_memory_->WriteUintPow2SRVDescriptor( + provider.OffsetViewDescriptor(view_bindless_heap_cpu_start_, + uint32_t(SystemBindlessView::kSharedMemoryR32UintSRV)), + 2); + // kSharedMemoryR32G32UintSRV. + shared_memory_->WriteUintPow2SRVDescriptor( + provider.OffsetViewDescriptor(view_bindless_heap_cpu_start_, + uint32_t(SystemBindlessView::kSharedMemoryR32G32UintSRV)), + 3); + // kSharedMemoryR32G32B32A32UintSRV. + shared_memory_->WriteUintPow2SRVDescriptor( + provider.OffsetViewDescriptor( + view_bindless_heap_cpu_start_, + uint32_t(SystemBindlessView::kSharedMemoryR32G32B32A32UintSRV)), + 4); + // kSharedMemoryRawUAV. + shared_memory_->WriteRawUAVDescriptor(provider.OffsetViewDescriptor( + view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kSharedMemoryRawUAV))); + // kSharedMemoryR32UintUAV. + shared_memory_->WriteUintPow2UAVDescriptor( + provider.OffsetViewDescriptor(view_bindless_heap_cpu_start_, + uint32_t(SystemBindlessView::kSharedMemoryR32UintUAV)), + 2); + // kSharedMemoryR32G32UintUAV. + shared_memory_->WriteUintPow2UAVDescriptor( + provider.OffsetViewDescriptor(view_bindless_heap_cpu_start_, + uint32_t(SystemBindlessView::kSharedMemoryR32G32UintUAV)), + 3); + // kSharedMemoryR32G32B32A32UintUAV. + shared_memory_->WriteUintPow2UAVDescriptor( + provider.OffsetViewDescriptor( + view_bindless_heap_cpu_start_, + uint32_t(SystemBindlessView::kSharedMemoryR32G32B32A32UintUAV)), + 4); + // kEdramRawSRV. + render_target_cache_->WriteEdramRawSRVDescriptor(provider.OffsetViewDescriptor( + view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kEdramRawSRV))); + // kEdramR32UintSRV. + render_target_cache_->WriteEdramUintPow2SRVDescriptor( + provider.OffsetViewDescriptor(view_bindless_heap_cpu_start_, + uint32_t(SystemBindlessView::kEdramR32UintSRV)), + 2); + // kEdramR32G32UintSRV. + render_target_cache_->WriteEdramUintPow2SRVDescriptor( + provider.OffsetViewDescriptor(view_bindless_heap_cpu_start_, + uint32_t(SystemBindlessView::kEdramR32G32UintSRV)), + 3); + // kEdramR32G32B32A32UintSRV. + render_target_cache_->WriteEdramUintPow2SRVDescriptor( + provider.OffsetViewDescriptor(view_bindless_heap_cpu_start_, + uint32_t(SystemBindlessView::kEdramR32G32B32A32UintSRV)), + 4); + // kEdramRawUAV. + render_target_cache_->WriteEdramRawUAVDescriptor(provider.OffsetViewDescriptor( + view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kEdramRawUAV))); + // kEdramR32UintUAV. + render_target_cache_->WriteEdramUintPow2UAVDescriptor( + provider.OffsetViewDescriptor(view_bindless_heap_cpu_start_, + uint32_t(SystemBindlessView::kEdramR32UintUAV)), + 2); + // kEdramR32G32UintUAV. + render_target_cache_->WriteEdramUintPow2UAVDescriptor( + provider.OffsetViewDescriptor(view_bindless_heap_cpu_start_, + uint32_t(SystemBindlessView::kEdramR32G32UintUAV)), + 3); + // kEdramR32G32B32A32UintUAV. + render_target_cache_->WriteEdramUintPow2UAVDescriptor( + provider.OffsetViewDescriptor(view_bindless_heap_cpu_start_, + uint32_t(SystemBindlessView::kEdramR32G32B32A32UintUAV)), + 4); + // kGammaRampTableSRV. + WriteGammaRampSRV( + false, provider.OffsetViewDescriptor(view_bindless_heap_cpu_start_, + uint32_t(SystemBindlessView::kGammaRampTableSRV))); + // kGammaRampPWLSRV. + WriteGammaRampSRV( + true, provider.OffsetViewDescriptor(view_bindless_heap_cpu_start_, + uint32_t(SystemBindlessView::kGammaRampPWLSRV))); + } + + pix_capture_requested_.store(false, std::memory_order_relaxed); + pix_capturing_ = false; + occlusion_query_resources_available_ = InitializeOcclusionQueryResources(); + + // Just not to expose uninitialized memory. + std::memset(&system_constants_, 0, sizeof(system_constants_)); + + return true; +} + +void D3D12CommandProcessor::ShutdownContext() { + AwaitAllQueueOperationsCompletion(); + InvalidateAllVertexBufferResidency(); + ShutdownOcclusionQueryResources(); + + ui::d3d12::util::ReleaseAndNull(readback_buffer_); + readback_buffer_size_ = 0; + for (auto& resolve_readback_pair : readback_buffers_) { + auto& readback = resolve_readback_pair.second; + for (uint32_t i = 0; i < 2; ++i) { + if (readback.buffers[i]) { + if (readback.mapped_data[i]) { + readback.buffers[i]->Unmap(0, nullptr); + readback.mapped_data[i] = nullptr; + } + readback.buffers[i]->Release(); + readback.buffers[i] = nullptr; + } + readback.sizes[i] = 0; + readback.submission_written[i] = 0; + readback.written_size[i] = 0; + } + } + readback_buffers_.clear(); + for (auto& memexport_readback_pair : memexport_readback_buffers_) { + auto& readback = memexport_readback_pair.second; + for (uint32_t i = 0; i < 2; ++i) { + if (readback.buffers[i]) { + if (readback.mapped_data[i]) { + readback.buffers[i]->Unmap(0, nullptr); + readback.mapped_data[i] = nullptr; + } + readback.buffers[i]->Release(); + readback.buffers[i] = nullptr; + } + readback.sizes[i] = 0; + readback.submission_written[i] = 0; + readback.written_size[i] = 0; + } + } + memexport_readback_buffers_.clear(); + + ui::d3d12::util::ReleaseAndNull(scratch_buffer_); + scratch_buffer_size_ = 0; + resolve_downscale_buffer_size_ = 0; + resolve_downscale_buffer_.Reset(); + + for (const std::pair& resource_for_deletion : + resources_for_deletion_) { + resource_for_deletion.second->Release(); + } + resources_for_deletion_.clear(); + + fxaa_source_texture_submission_ = 0; + fxaa_source_texture_.Reset(); + + fxaa_extreme_pipeline_.Reset(); + fxaa_pipeline_.Reset(); + fxaa_root_signature_.Reset(); + resolve_downscale_pipeline_.Reset(); + resolve_downscale_root_signature_.Reset(); + + apply_gamma_pwl_fxaa_luma_pipeline_.Reset(); + apply_gamma_pwl_pipeline_.Reset(); + apply_gamma_table_fxaa_luma_pipeline_.Reset(); + apply_gamma_table_pipeline_.Reset(); + apply_gamma_root_signature_.Reset(); + + // Unmapping will be done implicitly by the destruction. + gamma_ramp_upload_buffer_mapping_ = nullptr; + gamma_ramp_upload_buffer_.Reset(); + gamma_ramp_buffer_.Reset(); + + texture_cache_.reset(); + + pipeline_cache_.reset(); + + primitive_processor_.reset(); + + // Shut down binding - bindless descriptors may be owned by subsystems like + // the texture cache. + + // Root signatures are used by pipelines, thus freed after the pipelines. + ui::d3d12::util::ReleaseAndNull(root_signature_bindless_ds_); + ui::d3d12::util::ReleaseAndNull(root_signature_bindless_vs_); + for (auto it : root_signatures_bindful_) { + it.second->Release(); + } + root_signatures_bindful_.clear(); + + if (bindless_resources_used_) { + texture_cache_bindless_sampler_map_.clear(); + for (const auto& sampler_bindless_heap_overflowed : sampler_bindless_heaps_overflowed_) { + sampler_bindless_heap_overflowed.first->Release(); + } + sampler_bindless_heaps_overflowed_.clear(); + sampler_bindless_heap_allocated_ = 0; + ui::d3d12::util::ReleaseAndNull(sampler_bindless_heap_current_); + view_bindless_one_use_descriptors_.clear(); + view_bindless_heap_free_.clear(); + ui::d3d12::util::ReleaseAndNull(view_bindless_heap_); + } else { + sampler_bindful_heap_pool_.reset(); + view_bindful_heap_pool_.reset(); + } + constant_buffer_pool_.reset(); + + render_target_cache_.reset(); + + shared_memory_.reset(); + + deferred_command_list_.Reset(); + ui::d3d12::util::ReleaseAndNull(command_list_1_); + ui::d3d12::util::ReleaseAndNull(command_list_); + ClearCommandAllocatorCache(); + + frame_open_ = false; + frame_current_ = 1; + frame_completed_ = 0; + std::memset(closed_frame_submissions_, 0, sizeof(closed_frame_submissions_)); + + // First release the fences since they may reference fence_completion_event_. + + queue_operations_done_since_submission_signal_ = false; + queue_operations_since_submission_fence_last_ = 0; + ui::d3d12::util::ReleaseAndNull(queue_operations_since_submission_fence_); + + ui::d3d12::util::ReleaseAndNull(submission_fence_); + submission_open_ = false; + submission_current_ = 1; + submission_completed_ = 0; + + if (fence_completion_event_) { + CloseHandle(fence_completion_event_); + fence_completion_event_ = nullptr; + } + + device_removed_ = false; + + CommandProcessor::ShutdownContext(); +} + +void D3D12CommandProcessor::WriteRegister(uint32_t index, uint32_t value) { + CommandProcessor::WriteRegister(index, value); + + if (index >= XE_GPU_REG_SHADER_CONSTANT_000_X && index <= XE_GPU_REG_SHADER_CONSTANT_511_W) { + if (frame_open_) { + uint32_t float_constant_index = (index - XE_GPU_REG_SHADER_CONSTANT_000_X) >> 2; + if (float_constant_index >= 256) { + float_constant_index -= 256; + if (current_float_constant_map_pixel_[float_constant_index >> 6] & + (1ull << (float_constant_index & 63))) { + cbuffer_binding_float_pixel_.up_to_date = false; + } + } else { + if (current_float_constant_map_vertex_[float_constant_index >> 6] & + (1ull << (float_constant_index & 63))) { + cbuffer_binding_float_vertex_.up_to_date = false; + } + } + } + } else if (index >= XE_GPU_REG_SHADER_CONSTANT_BOOL_000_031 && + index <= XE_GPU_REG_SHADER_CONSTANT_LOOP_31) { + cbuffer_binding_bool_loop_.up_to_date = false; + } else if (index >= XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 && + index <= XE_GPU_REG_SHADER_CONSTANT_FETCH_31_5) { + cbuffer_binding_fetch_.up_to_date = false; + if (texture_cache_ != nullptr) { + texture_cache_->TextureFetchConstantWritten((index - XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0) / + 6); + } + InvalidateVertexBufferResidency((index - XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0) / 2); + } +} + +void D3D12CommandProcessor::WriteRegistersFromMem(uint32_t start_index, uint32_t* base, + uint32_t num_registers) { + if (!num_registers) { + return; + } + uint32_t end_index = start_index + num_registers - 1; + + auto range_has_any_constant_usage = [](const uint64_t* usage_map, uint32_t first_constant, + uint32_t last_constant) -> bool { + if (first_constant > last_constant) { + return false; + } + uint32_t first_word = first_constant >> 6; + uint32_t last_word = last_constant >> 6; + uint32_t first_bit = first_constant & 63; + uint32_t last_bit = last_constant & 63; + if (first_word == last_word) { + uint32_t bit_count = last_bit - first_bit + 1; + uint64_t mask = bit_count == 64 ? UINT64_MAX : ((UINT64_C(1) << bit_count) - 1) << first_bit; + return (usage_map[first_word] & mask) != 0; + } + if (usage_map[first_word] & (UINT64_MAX << first_bit)) { + return true; + } + for (uint32_t word = first_word + 1; word < last_word; ++word) { + if (usage_map[word]) { + return true; + } + } + uint64_t last_mask = last_bit == 63 ? UINT64_MAX : ((UINT64_C(1) << (last_bit + 1)) - 1); + return (usage_map[last_word] & last_mask) != 0; + }; + + if (start_index >= XE_GPU_REG_SHADER_CONSTANT_000_X && + end_index <= XE_GPU_REG_SHADER_CONSTANT_511_W) { + memory::copy_and_swap(register_file_->values + start_index, base, num_registers); + if (frame_open_) { + uint32_t first_float_constant = (start_index - XE_GPU_REG_SHADER_CONSTANT_000_X) >> 2; + uint32_t last_float_constant = (end_index - XE_GPU_REG_SHADER_CONSTANT_000_X) >> 2; + if (first_float_constant < 256) { + uint32_t last_vertex_constant = std::min(last_float_constant, 255u); + if (range_has_any_constant_usage(current_float_constant_map_vertex_, first_float_constant, + last_vertex_constant)) { + cbuffer_binding_float_vertex_.up_to_date = false; + } + } + if (last_float_constant >= 256) { + uint32_t first_pixel_constant = + first_float_constant >= 256 ? first_float_constant - 256 : 0; + uint32_t last_pixel_constant = last_float_constant - 256; + if (range_has_any_constant_usage(current_float_constant_map_pixel_, first_pixel_constant, + last_pixel_constant)) { + cbuffer_binding_float_pixel_.up_to_date = false; + } + } + } + return; + } + + if (start_index >= XE_GPU_REG_SHADER_CONSTANT_BOOL_000_031 && + end_index <= XE_GPU_REG_SHADER_CONSTANT_LOOP_31) { + memory::copy_and_swap(register_file_->values + start_index, base, num_registers); + cbuffer_binding_bool_loop_.up_to_date = false; + return; + } + + if (start_index >= XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 && + end_index <= XE_GPU_REG_SHADER_CONSTANT_FETCH_31_5) { + memory::copy_and_swap(register_file_->values + start_index, base, num_registers); + cbuffer_binding_fetch_.up_to_date = false; + uint32_t first_fetch_dword = start_index - XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0; + uint32_t last_fetch_dword = end_index - XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0; + if (texture_cache_) { + texture_cache_->TextureFetchConstantsWritten(first_fetch_dword / 6, last_fetch_dword / 6); + } + InvalidateVertexBufferResidencyRange(first_fetch_dword / 2, last_fetch_dword / 2); + return; + } + + CommandProcessor::WriteRegistersFromMem(start_index, base, num_registers); +} + +void D3D12CommandProcessor::OnGammaRamp256EntryTableValueWritten() { + gamma_ramp_256_entry_table_up_to_date_ = false; +} + +void D3D12CommandProcessor::OnGammaRampPWLValueWritten() { + gamma_ramp_pwl_up_to_date_ = false; +} + +void D3D12CommandProcessor::IssueSwap(uint32_t frontbuffer_ptr, uint32_t frontbuffer_width, + uint32_t frontbuffer_height) { + SCOPE_profile_cpu_f("gpu"); + vertex_buffers_in_sync_[0] = 0; + vertex_buffers_in_sync_[1] = 0; + + if (!graphics_system_) + return; + ui::Presenter* presenter = graphics_system_->presenter(); + if (!presenter) { + REXGPU_ERROR("IssueSwap: presenter is null"); + return; + } + + // In case the swap command is the only one in the frame. + if (!BeginSubmission(true)) { + REXGPU_ERROR("IssueSwap: BeginSubmission failed"); + return; + } + + // Obtain the actual swap source texture size (resolution-scaled if it's a + // resolve destination, or not otherwise). + D3D12_SHADER_RESOURCE_VIEW_DESC swap_texture_srv_desc; + xenos::TextureFormat frontbuffer_format; + uint32_t frontbuffer_width_unscaled = 0, frontbuffer_height_unscaled = 0; + ID3D12Resource* swap_texture_resource = + texture_cache_->RequestSwapTexture(swap_texture_srv_desc, frontbuffer_format, + &frontbuffer_width_unscaled, &frontbuffer_height_unscaled); + if (!swap_texture_resource) { + // Dump texture fetch constant 0 for debugging + const auto& regs = *register_file_; + auto fetch = regs.GetTextureFetch(0); + REXGPU_ERROR( + "IssueSwap: RequestSwapTexture failed - fetch0: {:08X} {:08X} {:08X} {:08X} {:08X} {:08X}", + fetch.dword_0, fetch.dword_1, fetch.dword_2, fetch.dword_3, fetch.dword_4, fetch.dword_5); + return; + } + D3D12_RESOURCE_DESC swap_texture_desc = swap_texture_resource->GetDesc(); + // The swap gamma / FXAA pass samples source texels by pixel index, but swap + // textures may be allocation-padded. Prefer the active frontbuffer region + // from the swap packet, scaled proportionally to the actual source texture. + uint32_t source_width_scaled = uint32_t(swap_texture_desc.Width); + uint32_t source_height_scaled = uint32_t(swap_texture_desc.Height); + auto get_active_swap_dimension = [](uint32_t packet_unscaled, uint32_t source_unscaled, + uint32_t source_scaled) -> uint32_t { + if (!source_scaled) { + return 0; + } + uint32_t active_unscaled = packet_unscaled ? packet_unscaled : source_unscaled; + if (!active_unscaled) { + return source_scaled; + } + if (source_unscaled) { + active_unscaled = std::min(active_unscaled, source_unscaled); + uint64_t active_scaled = + (uint64_t(active_unscaled) * source_scaled + (source_unscaled >> 1)) / source_unscaled; + return uint32_t(std::clamp(active_scaled, 1, source_scaled)); + } + return std::min(active_unscaled, source_scaled); + }; + uint32_t guest_output_width = + get_active_swap_dimension(frontbuffer_width, frontbuffer_width_unscaled, source_width_scaled); + uint32_t guest_output_height = get_active_swap_dimension( + frontbuffer_height, frontbuffer_height_unscaled, source_height_scaled); + if (!guest_output_width) { + guest_output_width = source_width_scaled + ? source_width_scaled + : (frontbuffer_width ? frontbuffer_width : frontbuffer_width_unscaled); + } + if (!guest_output_height) { + guest_output_height = source_height_scaled ? source_height_scaled + : (frontbuffer_height ? frontbuffer_height + : frontbuffer_height_unscaled); + } + bool swap_source_scaled = frontbuffer_width_unscaled && frontbuffer_height_unscaled && + (source_width_scaled != frontbuffer_width_unscaled || + source_height_scaled != frontbuffer_height_unscaled); + if (texture_cache_->IsDrawResolutionScaled() && !swap_source_scaled) { + static bool draw_scale_swap_unscaled_logged = false; + if (!draw_scale_swap_unscaled_logged) { + draw_scale_swap_unscaled_logged = true; + REXGPU_WARN( + "D3D12 draw resolution scaling is enabled, but the swap source is " + "unscaled ({}x{}). This title may be presenting from an unscaled " + "resolve path.", + guest_output_width, guest_output_height); + } + } + + system::X_VIDEO_MODE video_mode; + kernel::xboxkrnl::VdQueryVideoMode(&video_mode); + uint32_t display_width = std::max(uint32_t(1), uint32_t(video_mode.display_width)); + uint32_t display_height = std::max(uint32_t(1), uint32_t(video_mode.display_height)); + + presenter->RefreshGuestOutput( + guest_output_width, guest_output_height, display_width, display_height, + [this, &swap_texture_srv_desc, frontbuffer_format, swap_texture_resource, guest_output_width, + guest_output_height](ui::Presenter::GuestOutputRefreshContext& context) -> bool { + const ui::d3d12::D3D12Provider& provider = GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + + SwapPostEffect swap_post_effect = GetActualSwapPostEffect(); + bool use_fxaa = swap_post_effect == SwapPostEffect::kFxaa || + swap_post_effect == SwapPostEffect::kFxaaExtreme; + if (use_fxaa) { + // Make sure the texture of the correct size is available for FXAA. + if (fxaa_source_texture_) { + D3D12_RESOURCE_DESC fxaa_source_texture_desc = fxaa_source_texture_->GetDesc(); + if (fxaa_source_texture_desc.Width != guest_output_width || + fxaa_source_texture_desc.Height != guest_output_height) { + if (submission_completed_ < fxaa_source_texture_submission_) { + fxaa_source_texture_->AddRef(); + resources_for_deletion_.emplace_back(fxaa_source_texture_submission_, + fxaa_source_texture_.Get()); + } + fxaa_source_texture_.Reset(); + fxaa_source_texture_submission_ = 0; + } + } + if (!fxaa_source_texture_) { + D3D12_RESOURCE_DESC fxaa_source_texture_desc; + fxaa_source_texture_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + fxaa_source_texture_desc.Alignment = 0; + fxaa_source_texture_desc.Width = guest_output_width; + fxaa_source_texture_desc.Height = guest_output_height; + fxaa_source_texture_desc.DepthOrArraySize = 1; + fxaa_source_texture_desc.MipLevels = 1; + fxaa_source_texture_desc.Format = kFxaaSourceTextureFormat; + fxaa_source_texture_desc.SampleDesc.Count = 1; + fxaa_source_texture_desc.SampleDesc.Quality = 0; + fxaa_source_texture_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + fxaa_source_texture_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; + if (FAILED(device->CreateCommittedResource( + &ui::d3d12::util::kHeapPropertiesDefault, provider.GetHeapFlagCreateNotZeroed(), + &fxaa_source_texture_desc, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, + nullptr, IID_PPV_ARGS(&fxaa_source_texture_)))) { + REXGPU_ERROR("Failed to create the FXAA input texture"); + swap_post_effect = SwapPostEffect::kNone; + use_fxaa = false; + } + } + } + + // This is according to D3D::InitializePresentationParameters from a + // game executable, which initializes the 256-entry table gamma ramp for + // 8_8_8_8 output and the PWL gamma ramp for 2_10_10_10. + // TODO(Triang3l): Choose between the table and PWL based on + // DC_LUTA_CONTROL, support both for all formats (and also different + // increments for PWL). + bool use_pwl_gamma_ramp = + frontbuffer_format == xenos::TextureFormat::k_2_10_10_10 || + frontbuffer_format == xenos::TextureFormat::k_2_10_10_10_AS_16_16_16_16; + + context.SetIs8bpc(!use_pwl_gamma_ramp && !use_fxaa); + + // Upload the new gamma ramp, using the upload buffer for the current + // frame (will close the frame after this anyway, so can't write + // multiple times per frame). + if (!(use_pwl_gamma_ramp ? gamma_ramp_pwl_up_to_date_ + : gamma_ramp_256_entry_table_up_to_date_)) { + uint32_t gamma_ramp_offset_bytes = use_pwl_gamma_ramp ? 256 * 4 : 0; + uint32_t gamma_ramp_upload_offset_bytes = + uint32_t(frame_current_ % kQueueFrames) * ((256 + 128 * 3) * 4) + + gamma_ramp_offset_bytes; + uint32_t gamma_ramp_size_bytes = (use_pwl_gamma_ramp ? 128 * 3 : 256) * 4; + if (std::endian::native != std::endian::little && use_pwl_gamma_ramp) { + // R16G16 is first R16, where the shader expects the base, and + // second G16, where the delta should be, but gamma_ramp_pwl_rgb() + // is an array of 32-bit DC_LUT_PWL_DATA registers - swap 16 bits in + // each 32. + auto gamma_ramp_pwl_upload_buffer = reinterpret_cast( + gamma_ramp_upload_buffer_mapping_ + gamma_ramp_upload_offset_bytes); + const reg::DC_LUT_PWL_DATA* gamma_ramp_pwl = gamma_ramp_pwl_rgb(); + for (size_t i = 0; i < 128 * 3; ++i) { + reg::DC_LUT_PWL_DATA& gamma_ramp_pwl_upload_buffer_entry = + gamma_ramp_pwl_upload_buffer[i]; + reg::DC_LUT_PWL_DATA gamma_ramp_pwl_entry = gamma_ramp_pwl[i]; + gamma_ramp_pwl_upload_buffer_entry.base = gamma_ramp_pwl_entry.delta; + gamma_ramp_pwl_upload_buffer_entry.delta = gamma_ramp_pwl_entry.base; + } + } else { + std::memcpy(gamma_ramp_upload_buffer_mapping_ + gamma_ramp_upload_offset_bytes, + use_pwl_gamma_ramp ? static_cast(gamma_ramp_pwl_rgb()) + : static_cast(gamma_ramp_256_entry_table()), + gamma_ramp_size_bytes); + } + PushTransitionBarrier(gamma_ramp_buffer_.Get(), gamma_ramp_buffer_state_, + D3D12_RESOURCE_STATE_COPY_DEST); + gamma_ramp_buffer_state_ = D3D12_RESOURCE_STATE_COPY_DEST; + SubmitBarriers(); + deferred_command_list_.D3DCopyBufferRegion( + gamma_ramp_buffer_.Get(), gamma_ramp_offset_bytes, gamma_ramp_upload_buffer_.Get(), + gamma_ramp_upload_offset_bytes, gamma_ramp_size_bytes); + (use_pwl_gamma_ramp ? gamma_ramp_pwl_up_to_date_ + : gamma_ramp_256_entry_table_up_to_date_) = true; + } + + // Destination, source, and if bindful, gamma ramp. + ui::d3d12::util::DescriptorCpuGpuHandlePair apply_gamma_descriptors[3]; + ui::d3d12::util::DescriptorCpuGpuHandlePair apply_gamma_descriptor_gamma_ramp; + if (!RequestOneUseSingleViewDescriptors(bindless_resources_used_ ? 2 : 3, + apply_gamma_descriptors)) { + return false; + } + // Must not call anything that can change the descriptor heap from now + // on! + if (bindless_resources_used_) { + apply_gamma_descriptor_gamma_ramp = GetSystemBindlessViewHandlePair( + use_pwl_gamma_ramp ? SystemBindlessView::kGammaRampPWLSRV + : SystemBindlessView::kGammaRampTableSRV); + } else { + apply_gamma_descriptor_gamma_ramp = apply_gamma_descriptors[2]; + WriteGammaRampSRV(use_pwl_gamma_ramp, apply_gamma_descriptor_gamma_ramp.first); + } + + ID3D12Resource* guest_output_resource = + static_cast(context) + .resource_uav_capable(); + + if (use_fxaa) { + fxaa_source_texture_submission_ = submission_current_; + } + + ID3D12Resource* apply_gamma_dest = + use_fxaa ? fxaa_source_texture_.Get() : guest_output_resource; + D3D12_RESOURCE_STATES apply_gamma_dest_initial_state = + use_fxaa ? D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE + : ui::d3d12::D3D12Presenter::kGuestOutputInternalState; + static_cast(context) + .resource_uav_capable(); + PushTransitionBarrier(apply_gamma_dest, apply_gamma_dest_initial_state, + D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + // From now on, even in case of failure, apply_gamma_dest must be + // transitioned back to apply_gamma_dest_initial_state! + D3D12_UNORDERED_ACCESS_VIEW_DESC apply_gamma_dest_uav_desc; + apply_gamma_dest_uav_desc.Format = + use_fxaa ? kFxaaSourceTextureFormat : ui::d3d12::D3D12Presenter::kGuestOutputFormat; + apply_gamma_dest_uav_desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D; + apply_gamma_dest_uav_desc.Texture2D.MipSlice = 0; + apply_gamma_dest_uav_desc.Texture2D.PlaneSlice = 0; + device->CreateUnorderedAccessView(apply_gamma_dest, nullptr, &apply_gamma_dest_uav_desc, + apply_gamma_descriptors[0].first); + + device->CreateShaderResourceView(swap_texture_resource, &swap_texture_srv_desc, + apply_gamma_descriptors[1].first); + + PushTransitionBarrier(gamma_ramp_buffer_.Get(), gamma_ramp_buffer_state_, + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + gamma_ramp_buffer_state_ = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; + + deferred_command_list_.D3DSetComputeRootSignature(apply_gamma_root_signature_.Get()); + ApplyGammaConstants apply_gamma_constants; + apply_gamma_constants.size[0] = guest_output_width; + apply_gamma_constants.size[1] = guest_output_height; + deferred_command_list_.D3DSetComputeRoot32BitConstants( + UINT(ApplyGammaRootParameter::kConstants), + sizeof(apply_gamma_constants) / sizeof(uint32_t), &apply_gamma_constants, 0); + deferred_command_list_.D3DSetComputeRootDescriptorTable( + UINT(ApplyGammaRootParameter::kDestination), apply_gamma_descriptors[0].second); + deferred_command_list_.D3DSetComputeRootDescriptorTable( + UINT(ApplyGammaRootParameter::kSource), apply_gamma_descriptors[1].second); + deferred_command_list_.D3DSetComputeRootDescriptorTable( + UINT(ApplyGammaRootParameter::kRamp), apply_gamma_descriptor_gamma_ramp.second); + ID3D12PipelineState* apply_gamma_pipeline; + if (use_pwl_gamma_ramp) { + apply_gamma_pipeline = use_fxaa ? apply_gamma_pwl_fxaa_luma_pipeline_.Get() + : apply_gamma_pwl_pipeline_.Get(); + } else { + apply_gamma_pipeline = use_fxaa ? apply_gamma_table_fxaa_luma_pipeline_.Get() + : apply_gamma_table_pipeline_.Get(); + } + SetExternalPipeline(apply_gamma_pipeline); + SubmitBarriers(); + uint32_t group_count_x = (guest_output_width + 15) / 16; + uint32_t group_count_y = (guest_output_height + 7) / 8; + deferred_command_list_.D3DDispatch(group_count_x, group_count_y, 1); + + // Apply FXAA. + if (use_fxaa) { + // Destination and source. + ui::d3d12::util::DescriptorCpuGpuHandlePair fxaa_descriptors[2]; + if (!RequestOneUseSingleViewDescriptors(uint32_t(rex::countof(fxaa_descriptors)), + fxaa_descriptors)) { + // Failed to obtain descriptors for FXAA - just copy after gamma + // ramp application without applying FXAA. + PushTransitionBarrier(apply_gamma_dest, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, + D3D12_RESOURCE_STATE_COPY_SOURCE); + PushTransitionBarrier(guest_output_resource, + ui::d3d12::D3D12Presenter::kGuestOutputInternalState, + D3D12_RESOURCE_STATE_COPY_DEST); + SubmitBarriers(); + deferred_command_list_.D3DCopyResource(guest_output_resource, apply_gamma_dest); + PushTransitionBarrier(apply_gamma_dest, D3D12_RESOURCE_STATE_COPY_SOURCE, + apply_gamma_dest_initial_state); + PushTransitionBarrier(guest_output_resource, D3D12_RESOURCE_STATE_COPY_DEST, + ui::d3d12::D3D12Presenter::kGuestOutputInternalState); + return false; + } else { + assert_true(apply_gamma_dest_initial_state == + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + PushTransitionBarrier(apply_gamma_dest, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, + apply_gamma_dest_initial_state); + PushTransitionBarrier(guest_output_resource, + ui::d3d12::D3D12Presenter::kGuestOutputInternalState, + D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + // From now on, even in case of failure, guest_output_resource must + // be transitioned back to kGuestOutputInternalState! + deferred_command_list_.D3DSetComputeRootSignature(fxaa_root_signature_.Get()); + FxaaConstants fxaa_constants; + fxaa_constants.size[0] = guest_output_width; + fxaa_constants.size[1] = guest_output_height; + fxaa_constants.size_inv[0] = 1.0f / float(fxaa_constants.size[0]); + fxaa_constants.size_inv[1] = 1.0f / float(fxaa_constants.size[1]); + deferred_command_list_.D3DSetComputeRoot32BitConstants( + UINT(FxaaRootParameter::kConstants), sizeof(fxaa_constants) / sizeof(uint32_t), + &fxaa_constants, 0); + D3D12_UNORDERED_ACCESS_VIEW_DESC fxaa_dest_uav_desc; + fxaa_dest_uav_desc.Format = ui::d3d12::D3D12Presenter::kGuestOutputFormat; + fxaa_dest_uav_desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D; + fxaa_dest_uav_desc.Texture2D.MipSlice = 0; + fxaa_dest_uav_desc.Texture2D.PlaneSlice = 0; + device->CreateUnorderedAccessView(guest_output_resource, nullptr, &fxaa_dest_uav_desc, + fxaa_descriptors[0].first); + deferred_command_list_.D3DSetComputeRootDescriptorTable( + UINT(FxaaRootParameter::kDestination), fxaa_descriptors[0].second); + D3D12_SHADER_RESOURCE_VIEW_DESC fxaa_source_srv_desc; + fxaa_source_srv_desc.Format = kFxaaSourceTextureFormat; + fxaa_source_srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + fxaa_source_srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + fxaa_source_srv_desc.Texture2D.MostDetailedMip = 0; + fxaa_source_srv_desc.Texture2D.MipLevels = 1; + fxaa_source_srv_desc.Texture2D.PlaneSlice = 0; + fxaa_source_srv_desc.Texture2D.ResourceMinLODClamp = 0.0f; + device->CreateShaderResourceView(fxaa_source_texture_.Get(), &fxaa_source_srv_desc, + fxaa_descriptors[1].first); + deferred_command_list_.D3DSetComputeRootDescriptorTable( + UINT(FxaaRootParameter::kSource), fxaa_descriptors[1].second); + SetExternalPipeline(swap_post_effect == SwapPostEffect::kFxaaExtreme + ? fxaa_extreme_pipeline_.Get() + : fxaa_pipeline_.Get()); + SubmitBarriers(); + deferred_command_list_.D3DDispatch(group_count_x, group_count_y, 1); + PushTransitionBarrier(guest_output_resource, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, + ui::d3d12::D3D12Presenter::kGuestOutputInternalState); + } + } else { + assert_true(apply_gamma_dest_initial_state == + ui::d3d12::D3D12Presenter::kGuestOutputInternalState); + PushTransitionBarrier(apply_gamma_dest, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, + apply_gamma_dest_initial_state); + } + + // Need to submit all the commands before giving the image back to the + // presenter so it can submit its own commands for displaying it to the + // queue. + SubmitBarriers(); + EndSubmission(true); + return true; + }); + + // End the frame even if did not present for any reason (the image refresher + // was not called), to prevent leaking per-frame resources. + EndSubmission(true); +} + +void D3D12CommandProcessor::OnPrimaryBufferEnd() { + if (REXCVAR_GET(d3d12_submit_on_primary_buffer_end) && submission_open_ && + CanEndSubmissionImmediately()) { + EndSubmission(false); + } +} + +Shader* D3D12CommandProcessor::LoadShader(xenos::ShaderType shader_type, uint32_t guest_address, + const uint32_t* host_address, uint32_t dword_count) { + return pipeline_cache_->LoadShader(shader_type, host_address, dword_count); +} + +bool D3D12CommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type, uint32_t index_count, + IndexBufferInfo* index_buffer_info, + bool major_mode_explicit) { +#if XE_GPU_FINE_GRAINED_DRAW_SCOPES + SCOPE_profile_cpu_f("gpu"); +#endif // XE_GPU_FINE_GRAINED_DRAW_SCOPES + + ID3D12Device* device = GetD3D12Provider().GetDevice(); + const RegisterFile& regs = *register_file_; + + xenos::EdramMode edram_mode = regs.Get().edram_mode; + if (edram_mode == xenos::EdramMode::kCopy) { + // Special copy handling. + return IssueCopy(); + } + + bool surface_pitch_is_zero = regs.Get().surface_pitch == 0; + + // Vertex shader analysis. + auto vertex_shader = static_cast(active_vertex_shader()); + if (!vertex_shader) { + // Always need a vertex shader. + return false; + } + pipeline_cache_->AnalyzeShaderUcode(*vertex_shader); + bool memexport_used_vertex = vertex_shader->memexport_eM_written() != 0; + + // Pixel shader analysis. + bool primitive_polygonal = draw_util::IsPrimitivePolygonal(regs); + bool is_rasterization_done = draw_util::IsRasterizationPotentiallyDone(regs, primitive_polygonal); + if (surface_pitch_is_zero && is_rasterization_done) { + // Doesn't actually draw. + // Unlikely that zero would even really be legal though. + return true; + } + D3D12Shader* pixel_shader = nullptr; + if (is_rasterization_done) { + // See xenos::EdramMode for explanation why the pixel shader is only used + // when it's kColorDepth here. + if (edram_mode == xenos::EdramMode::kColorDepth) { + pixel_shader = static_cast(active_pixel_shader()); + if (pixel_shader) { + pipeline_cache_->AnalyzeShaderUcode(*pixel_shader); + if (!draw_util::IsPixelShaderNeededWithRasterization(*pixel_shader, regs)) { + pixel_shader = nullptr; + } + } + } + } else { + // Disabling pixel shader for this case is also required by the pipeline + // cache. + if (!memexport_used_vertex) { + // This draw has no effect. + return true; + } + } + bool memexport_used_pixel = pixel_shader && (pixel_shader->memexport_eM_written() != 0); + bool memexport_used = memexport_used_vertex || memexport_used_pixel; + + if (!BeginSubmission(true)) { + return false; + } + + // Process primitives. + PrimitiveProcessor::ProcessingResult primitive_processing_result; + if (!primitive_processor_->Process(primitive_processing_result)) { + return false; + } + if (!primitive_processing_result.host_draw_vertex_count) { + // Nothing to draw. + return true; + } + + reg::RB_DEPTHCONTROL normalized_depth_control = draw_util::GetNormalizedDepthControl(regs); + + // Shader modifications. + uint32_t ps_param_gen_pos = UINT32_MAX; + uint32_t interpolator_mask = + pixel_shader ? (vertex_shader->writes_interpolators() & + pixel_shader->GetInterpolatorInputMask(regs.Get(), + regs.Get(), + ps_param_gen_pos)) + : 0; + DxbcShaderTranslator::Modification vertex_shader_modification = + pipeline_cache_->GetCurrentVertexShaderModification( + *vertex_shader, primitive_processing_result.host_vertex_shader_type, interpolator_mask); + DxbcShaderTranslator::Modification pixel_shader_modification = + pixel_shader + ? pipeline_cache_->GetCurrentPixelShaderModification( + *pixel_shader, interpolator_mask, ps_param_gen_pos, normalized_depth_control) + : DxbcShaderTranslator::Modification(0); + + // Set up the render targets - this may perform dispatches and draws. + uint32_t normalized_color_mask = + pixel_shader ? draw_util::GetNormalizedColorMask(regs, pixel_shader->writes_color_targets()) + : 0; + if (!render_target_cache_->Update(is_rasterization_done, normalized_depth_control, + normalized_color_mask, *vertex_shader)) { + return false; + } + + // Create the pipeline (for this, need the actually used render target formats + // from the render target cache), translating the shaders - doing this now to + // obtain the used textures. + D3D12Shader::D3D12Translation* vertex_shader_translation = + static_cast( + vertex_shader->GetOrCreateTranslation(vertex_shader_modification.value)); + D3D12Shader::D3D12Translation* pixel_shader_translation = + pixel_shader ? static_cast( + pixel_shader->GetOrCreateTranslation(pixel_shader_modification.value)) + : nullptr; + uint32_t bound_depth_and_color_render_target_bits; + uint32_t bound_depth_and_color_render_target_formats[1 + xenos::kMaxColorRenderTargets]; + bool host_render_targets_used = + render_target_cache_->GetPath() == RenderTargetCache::Path::kHostRenderTargets; + if (host_render_targets_used) { + bound_depth_and_color_render_target_bits = + render_target_cache_->GetLastUpdateBoundRenderTargets( + bound_depth_and_color_render_target_formats); + } else { + bound_depth_and_color_render_target_bits = 0; + } + void* pipeline_handle; + ID3D12RootSignature* root_signature; + if (!pipeline_cache_->ConfigurePipeline( + vertex_shader_translation, pixel_shader_translation, primitive_processing_result, + normalized_depth_control, normalized_color_mask, bound_depth_and_color_render_target_bits, + bound_depth_and_color_render_target_formats, &pipeline_handle, &root_signature)) { + return false; + } + if (REXCVAR_GET(async_shader_compilation) && + pipeline_cache_->GetD3D12PipelineByHandle(pipeline_handle) == nullptr) { + return true; + } + + // Update the textures - this may bind pipelines. + uint32_t used_texture_mask = + vertex_shader->GetUsedTextureMaskAfterTranslation() | + (pixel_shader != nullptr ? pixel_shader->GetUsedTextureMaskAfterTranslation() : 0); + texture_cache_->RequestTextures(used_texture_mask); + + // Bind the pipeline after configuring it and doing everything that may bind + // other pipelines. + if (current_guest_pipeline_ != pipeline_handle) { + deferred_command_list_.SetPipelineStateHandle(reinterpret_cast(pipeline_handle)); + current_guest_pipeline_ = pipeline_handle; + current_external_pipeline_ = nullptr; + } + + // Get dynamic rasterizer state. + uint32_t draw_resolution_scale_x = texture_cache_->draw_resolution_scale_x(); + uint32_t draw_resolution_scale_y = texture_cache_->draw_resolution_scale_y(); + + bool convert_z_to_float24 = + host_render_targets_used && render_target_cache_->depth_float24_convert_in_pixel_shader(); + bool ps_writes_depth = pixel_shader && pixel_shader->writes_depth(); + + // Build a cache key from all viewport-affecting state to skip redundant + // recalculation when the viewport registers haven't changed between draws. + ViewportCacheKey viewport_key; + viewport_key.pa_cl_clip_cntl = regs[XE_GPU_REG_PA_CL_CLIP_CNTL]; + viewport_key.pa_cl_vte_cntl = regs[XE_GPU_REG_PA_CL_VTE_CNTL]; + viewport_key.pa_su_sc_mode_cntl = regs[XE_GPU_REG_PA_SU_SC_MODE_CNTL]; + viewport_key.pa_su_vtx_cntl = regs[XE_GPU_REG_PA_SU_VTX_CNTL]; + viewport_key.pa_sc_window_offset = regs[XE_GPU_REG_PA_SC_WINDOW_OFFSET]; + viewport_key.normalized_depth_control = normalized_depth_control.value; + std::memcpy(viewport_key.vport_regs, ®s[XE_GPU_REG_PA_CL_VPORT_XSCALE], + sizeof(viewport_key.vport_regs)); + viewport_key.flags = (uint32_t(convert_z_to_float24) << 0) | + (uint32_t(host_render_targets_used) << 1) | (uint32_t(ps_writes_depth) << 2); + + draw_util::ViewportInfo viewport_info; + if (viewport_cache_valid_ && viewport_key == previous_viewport_key_) { + viewport_info = previous_viewport_info_; + } else { + draw_util::GetHostViewportInfo(regs, draw_resolution_scale_x, draw_resolution_scale_y, true, + D3D12_VIEWPORT_BOUNDS_MAX, D3D12_VIEWPORT_BOUNDS_MAX, false, + normalized_depth_control, convert_z_to_float24, + host_render_targets_used, ps_writes_depth, viewport_info); + previous_viewport_key_ = viewport_key; + previous_viewport_info_ = viewport_info; + viewport_cache_valid_ = true; + } + + draw_util::Scissor scissor; + draw_util::GetScissor(regs, scissor); + scissor.offset[0] *= draw_resolution_scale_x; + scissor.offset[1] *= draw_resolution_scale_y; + scissor.extent[0] *= draw_resolution_scale_x; + scissor.extent[1] *= draw_resolution_scale_y; + + // Update viewport, scissor, blend factor and stencil reference. + UpdateFixedFunctionState(viewport_info, scissor, primitive_polygonal, normalized_depth_control); + + // Update system constants before uploading them. + // TODO(Triang3l): With ROV, pass the disabled render target mask for safety. + UpdateSystemConstantValues(memexport_used, primitive_polygonal, + primitive_processing_result.line_loop_closing_index, + primitive_processing_result.host_shader_index_endian, viewport_info, + used_texture_mask, normalized_depth_control, normalized_color_mask); + + // Update constant buffers, descriptors and root parameters. + if (!UpdateBindings(vertex_shader, pixel_shader, root_signature, memexport_used)) { + return false; + } + // Must not call anything that can change the descriptor heap from now on! + + // Ensure vertex buffers are resident. + const Shader::ConstantRegisterMap& constant_map_vertex = vertex_shader->constant_register_map(); + for (uint32_t i = 0; i < rex::countof(constant_map_vertex.vertex_fetch_bitmap); ++i) { + uint32_t vfetch_bits_remaining = constant_map_vertex.vertex_fetch_bitmap[i]; + uint32_t j; + while (rex::bit_scan_forward(vfetch_bits_remaining, &j)) { + vfetch_bits_remaining &= ~(uint32_t(1) << j); + uint32_t vfetch_index = i * 32 + j; + uint64_t vfetch_bit = uint64_t(1) << (vfetch_index & 63); + if (vertex_buffers_in_sync_[vfetch_index >> 6] & vfetch_bit) { + continue; + } + xenos::xe_gpu_vertex_fetch_t vfetch_constant = regs.GetVertexFetch(vfetch_index); + switch (vfetch_constant.type) { + case xenos::FetchConstantType::kVertex: + break; + case xenos::FetchConstantType::kInvalidVertex: + if (REXCVAR_GET(gpu_allow_invalid_fetch_constants)) { + break; + } + REXGPU_WARN( + "Vertex fetch constant {} ({:08X} {:08X}) has \"invalid\" type! " + "This is incorrect behavior, but you can try bypassing this by " + "launching Xenia with --gpu_allow_invalid_fetch_constants=true.", + vfetch_index, vfetch_constant.dword_0, vfetch_constant.dword_1); + return false; + default: + REXGPU_WARN("Vertex fetch constant {} ({:08X} {:08X}) is completely invalid!", + vfetch_index, vfetch_constant.dword_0, vfetch_constant.dword_1); + return false; + } + VertexBufferState& state = vertex_buffer_states_[vfetch_index]; + if (state.address == vfetch_constant.address && state.size == vfetch_constant.size) { + vertex_buffers_in_sync_[vfetch_index >> 6] |= vfetch_bit; + continue; + } + if (!shared_memory_->RequestRange(vfetch_constant.address << 2, vfetch_constant.size << 2)) { + REXGPU_ERROR( + "Failed to request vertex buffer at 0x{:08X} (size {}) in the " + "shared memory", + vfetch_constant.address << 2, vfetch_constant.size << 2); + return false; + } + state.address = vfetch_constant.address; + state.size = vfetch_constant.size; + vertex_buffers_in_sync_[vfetch_index >> 6] |= vfetch_bit; + } + } + + // Gather memexport ranges and ensure the heaps for them are resident, and + // also load the data surrounding the export and to fill the regions that + // won't be modified by the shaders. + memexport_ranges_.clear(); + if (memexport_used_vertex) { + draw_util::AddMemExportRanges(regs, *vertex_shader, memexport_ranges_); + } + if (memexport_used_pixel) { + draw_util::AddMemExportRanges(regs, *pixel_shader, memexport_ranges_); + } + for (const draw_util::MemExportRange& memexport_range : memexport_ranges_) { + if (!shared_memory_->RequestRange(memexport_range.base_address_dwords << 2, + memexport_range.size_bytes)) { + REXGPU_ERROR( + "Failed to request memexport stream at 0x{:08X} (size {}) in the " + "shared memory", + memexport_range.base_address_dwords << 2, memexport_range.size_bytes); + return false; + } + } + if (memexport_used && memexport_ranges_.empty()) { + if (!shared_memory_->RequestRange(0, SharedMemory::kBufferSize)) { + REXGPU_ERROR( + "Failed to request full shared memory residency for unresolved " + "memexport destinations"); + return false; + } + } + + // Primitive topology. + D3D_PRIMITIVE_TOPOLOGY primitive_topology; + if (primitive_processing_result.IsTessellated()) { + switch (primitive_processing_result.host_primitive_type) { + // TODO(Triang3l): Support all primitive types. + case xenos::PrimitiveType::kTriangleList: + primitive_topology = D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST; + break; + case xenos::PrimitiveType::kQuadList: + primitive_topology = D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST; + break; + case xenos::PrimitiveType::kTrianglePatch: + primitive_topology = + (regs.Get().tess_mode == xenos::TessellationMode::kAdaptive) + ? D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST + : D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST; + break; + case xenos::PrimitiveType::kQuadPatch: + primitive_topology = + (regs.Get().tess_mode == xenos::TessellationMode::kAdaptive) + ? D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST + : D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST; + break; + default: + REXGPU_ERROR( + "Host tessellated primitive type {} returned by the primitive " + "processor is not supported by the Direct3D 12 command processor", + uint32_t(primitive_processing_result.host_primitive_type)); + assert_unhandled_case(primitive_processing_result.host_primitive_type); + return false; + } + } else { + switch (primitive_processing_result.host_primitive_type) { + case xenos::PrimitiveType::kPointList: + primitive_topology = D3D_PRIMITIVE_TOPOLOGY_POINTLIST; + break; + case xenos::PrimitiveType::kLineList: + primitive_topology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; + break; + case xenos::PrimitiveType::kLineStrip: + primitive_topology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; + break; + case xenos::PrimitiveType::kTriangleList: + case xenos::PrimitiveType::kRectangleList: + primitive_topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + break; + case xenos::PrimitiveType::kTriangleStrip: + primitive_topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; + break; + case xenos::PrimitiveType::kQuadList: + primitive_topology = D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ; + break; + default: + REXGPU_ERROR( + "Host primitive type {} returned by the primitive processor is not " + "supported by the Direct3D 12 command processor", + uint32_t(primitive_processing_result.host_primitive_type)); + assert_unhandled_case(primitive_processing_result.host_primitive_type); + return false; + } + } + SetPrimitiveTopology(primitive_topology); + // Must not call anything that may change the primitive topology from now on! + + // Draw. + if (primitive_processing_result.index_buffer_type == + PrimitiveProcessor::ProcessedIndexBufferType::kNone) { + if (memexport_used) { + shared_memory_->UseForWriting(); + } else { + shared_memory_->UseForReading(); + } + SubmitBarriers(); + PROFILE_DRAW_CALL(); + PROFILE_VERTICES(primitive_processing_result.host_draw_vertex_count); + deferred_command_list_.D3DDrawInstanced(primitive_processing_result.host_draw_vertex_count, 1, + 0, 0); + } else { + D3D12_INDEX_BUFFER_VIEW index_buffer_view; + index_buffer_view.SizeInBytes = primitive_processing_result.host_draw_vertex_count; + if (primitive_processing_result.host_index_format == xenos::IndexFormat::kInt16) { + index_buffer_view.SizeInBytes *= sizeof(uint16_t); + index_buffer_view.Format = DXGI_FORMAT_R16_UINT; + } else { + index_buffer_view.SizeInBytes *= sizeof(uint32_t); + index_buffer_view.Format = DXGI_FORMAT_R32_UINT; + } + ID3D12Resource* scratch_index_buffer = nullptr; + switch (primitive_processing_result.index_buffer_type) { + case PrimitiveProcessor::ProcessedIndexBufferType::kGuestDMA: { + if (memexport_used) { + // If the shared memory is a UAV, it can't be used as an index buffer + // (UAV is a read/write state, index buffer is a read-only state). + // Need to copy the indices to a buffer in the index buffer state. + scratch_index_buffer = RequestScratchGPUBuffer(index_buffer_view.SizeInBytes, + D3D12_RESOURCE_STATE_COPY_DEST); + if (scratch_index_buffer == nullptr) { + return false; + } + shared_memory_->UseAsCopySource(); + SubmitBarriers(); + deferred_command_list_.D3DCopyBufferRegion( + scratch_index_buffer, 0, shared_memory_->GetBuffer(), + primitive_processing_result.guest_index_base, index_buffer_view.SizeInBytes); + PushTransitionBarrier(scratch_index_buffer, D3D12_RESOURCE_STATE_COPY_DEST, + D3D12_RESOURCE_STATE_INDEX_BUFFER); + index_buffer_view.BufferLocation = scratch_index_buffer->GetGPUVirtualAddress(); + } else { + index_buffer_view.BufferLocation = + shared_memory_->GetGPUAddress() + primitive_processing_result.guest_index_base; + } + } break; + case PrimitiveProcessor::ProcessedIndexBufferType::kHostConverted: + index_buffer_view.BufferLocation = primitive_processor_->GetConvertedIndexBufferGpuAddress( + primitive_processing_result.host_index_buffer_handle); + break; + case PrimitiveProcessor::ProcessedIndexBufferType::kHostBuiltinForAuto: + case PrimitiveProcessor::ProcessedIndexBufferType::kHostBuiltinForDMA: + index_buffer_view.BufferLocation = primitive_processor_->GetBuiltinIndexBufferGpuAddress( + primitive_processing_result.host_index_buffer_handle); + break; + default: + assert_unhandled_case(primitive_processing_result.index_buffer_type); + return false; + } + deferred_command_list_.D3DIASetIndexBuffer(&index_buffer_view); + if (memexport_used) { + shared_memory_->UseForWriting(); + } else { + shared_memory_->UseForReading(); + } + SubmitBarriers(); + PROFILE_DRAW_CALL(); + PROFILE_VERTICES(primitive_processing_result.host_draw_vertex_count); + deferred_command_list_.D3DDrawIndexedInstanced( + primitive_processing_result.host_draw_vertex_count, 1, 0, 0, 0); + if (scratch_index_buffer != nullptr) { + ReleaseScratchGPUBuffer(scratch_index_buffer, D3D12_RESOURCE_STATE_INDEX_BUFFER); + } + } + + if (memexport_used) { + // Make sure this memexporting draw is ordered with other work using shared + // memory as a UAV. + // TODO(Triang3l): Find some PM4 command that can be used for indication of + // when memexports should be awaited? + shared_memory_->MarkUAVWritesCommitNeeded(); + // Invalidate textures in memexported memory and watch for changes. + if (!memexport_ranges_.empty()) { + for (const draw_util::MemExportRange& memexport_range : memexport_ranges_) { + shared_memory_->RangeWrittenByGpu(memexport_range.base_address_dwords << 2, + memexport_range.size_bytes); + } + } else { + // Stream constants can be invalid or dynamic, so exact destinations may + // be unknown. Keep invalidation conservative in this case. + shared_memory_->RangeWrittenByGpu(0, SharedMemory::kBufferSize); + } + if (IsReadbackMemexportEnabled(REXCVAR_GET(d3d12_readback_memexport)) && + !memexport_ranges_.empty()) { + uint32_t memexport_total_size = 0; + for (const draw_util::MemExportRange& memexport_range : memexport_ranges_) { + memexport_total_size += memexport_range.size_bytes; + } + if (memexport_total_size != 0) { + if (REXCVAR_GET(readback_memexport_fast)) { + IssueDraw_MemexportReadbackFastPath(memexport_total_size); + } else { + IssueDraw_MemexportReadbackFullPath(memexport_total_size); + } + } + } + } + + return true; +} + +bool D3D12CommandProcessor::IssueDraw_MemexportReadbackFullPath(uint32_t total_size) { + if (!total_size || memexport_ranges_.empty()) { + return true; + } + + ID3D12Resource* readback_buffer = RequestReadbackBuffer(total_size); + if (!readback_buffer) { + return true; + } + + shared_memory_->UseAsCopySource(); + SubmitBarriers(); + ID3D12Resource* shared_memory_buffer = shared_memory_->GetBuffer(); + uint32_t readback_buffer_offset = 0; + for (const draw_util::MemExportRange& memexport_range : memexport_ranges_) { + deferred_command_list_.D3DCopyBufferRegion( + readback_buffer, readback_buffer_offset, shared_memory_buffer, + memexport_range.base_address_dwords << 2, memexport_range.size_bytes); + readback_buffer_offset += memexport_range.size_bytes; + } + + if (!AwaitAllQueueOperationsCompletion()) { + return true; + } + + D3D12_RANGE readback_range = {}; + readback_range.Begin = 0; + readback_range.End = total_size; + void* readback_mapping = nullptr; + if (FAILED(readback_buffer->Map(0, &readback_range, &readback_mapping))) { + return true; + } + + const uint8_t* readback_bytes = reinterpret_cast(readback_mapping); + for (const draw_util::MemExportRange& memexport_range : memexport_ranges_) { + std::memcpy(memory_->TranslatePhysical(memexport_range.base_address_dwords << 2), + readback_bytes, memexport_range.size_bytes); + readback_bytes += memexport_range.size_bytes; + } + + D3D12_RANGE readback_write_range = {}; + readback_buffer->Unmap(0, &readback_write_range); + return true; +} + +bool D3D12CommandProcessor::IssueDraw_MemexportReadbackFastPath(uint32_t total_size) { + if (!total_size || memexport_ranges_.empty()) { + return true; + } + + const uint64_t readback_key = + MakeMemexportReadbackKey(memexport_ranges_.front().base_address_dwords, total_size); + ReadbackBuffer& readback = memexport_readback_buffers_[readback_key]; + readback.last_used_frame = frame_current_; + + auto ensure_readback_slot = [&](uint32_t index, uint32_t size) -> bool { + if (readback.buffers[index] && readback.mapped_data[index] && size <= readback.sizes[index]) { + return true; + } + + const ui::d3d12::D3D12Provider& provider = GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + D3D12_RESOURCE_DESC buffer_desc; + ui::d3d12::util::FillBufferResourceDesc(buffer_desc, size, D3D12_RESOURCE_FLAG_NONE); + ID3D12Resource* buffer = nullptr; + if (FAILED(device->CreateCommittedResource( + &ui::d3d12::util::kHeapPropertiesReadback, provider.GetHeapFlagCreateNotZeroed(), + &buffer_desc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&buffer)))) { + return false; + } + + D3D12_RANGE read_range = {0, size}; + void* mapped_data = nullptr; + if (FAILED(buffer->Map(0, &read_range, &mapped_data))) { + buffer->Release(); + return false; + } + + if (readback.buffers[index]) { + if (!AwaitAllQueueOperationsCompletion()) { + buffer->Unmap(0, nullptr); + buffer->Release(); + return false; + } + if (readback.mapped_data[index]) { + readback.buffers[index]->Unmap(0, nullptr); + } + readback.buffers[index]->Release(); + } + + readback.buffers[index] = buffer; + readback.mapped_data[index] = mapped_data; + readback.sizes[index] = size; + readback.submission_written[index] = 0; + readback.written_size[index] = 0; + return true; + }; + + const uint32_t write_index = readback.current_index; + const uint32_t read_index = 1 - write_index; + const uint32_t readback_size = AlignReadbackBufferSize(total_size); + if (!ensure_readback_slot(write_index, readback_size)) { + return IssueDraw_MemexportReadbackFullPath(total_size); + } + + shared_memory_->UseAsCopySource(); + SubmitBarriers(); + ID3D12Resource* shared_memory_buffer = shared_memory_->GetBuffer(); + uint32_t readback_offset = 0; + for (const draw_util::MemExportRange& memexport_range : memexport_ranges_) { + deferred_command_list_.D3DCopyBufferRegion( + readback.buffers[write_index], readback_offset, shared_memory_buffer, + memexport_range.base_address_dwords << 2, memexport_range.size_bytes); + readback_offset += memexport_range.size_bytes; + } + readback.submission_written[write_index] = submission_current_; + readback.written_size[write_index] = total_size; + + CheckSubmissionFence(0); + bool previous_slot_ready = readback.buffers[read_index] && readback.mapped_data[read_index] && + total_size <= readback.sizes[read_index] && + total_size <= readback.written_size[read_index] && + readback.submission_written[read_index] && + readback.submission_written[read_index] <= submission_completed_; + if (!previous_slot_ready) { + IssueDraw_MemexportReadbackFullPath(total_size); + readback.current_index = read_index; + return true; + } + + const uint8_t* readback_bytes = static_cast(readback.mapped_data[read_index]); + for (const draw_util::MemExportRange& memexport_range : memexport_ranges_) { + std::memcpy(memory_->TranslatePhysical(memexport_range.base_address_dwords << 2), + readback_bytes, memexport_range.size_bytes); + readback_bytes += memexport_range.size_bytes; + } + readback.current_index = read_index; + return true; +} + +void D3D12CommandProcessor::InitializeTrace() { + CommandProcessor::InitializeTrace(); + + if (!BeginSubmission(false)) { + return; + } + bool render_target_cache_submitted = render_target_cache_->InitializeTraceSubmitDownloads(); + bool shared_memory_submitted = shared_memory_->InitializeTraceSubmitDownloads(); + if (!render_target_cache_submitted && !shared_memory_submitted) { + return; + } + AwaitAllQueueOperationsCompletion(); + if (render_target_cache_submitted) { + render_target_cache_->InitializeTraceCompleteDownloads(); + } + if (shared_memory_submitted) { + shared_memory_->InitializeTraceCompleteDownloads(); + } +} + +bool D3D12CommandProcessor::IssueCopy() { +#if XE_GPU_FINE_GRAINED_DRAW_SCOPES + SCOPE_profile_cpu_f("gpu"); +#endif // XE_GPU_FINE_GRAINED_DRAW_SCOPES + if (!BeginSubmission(true)) { + return false; + } + ReadbackResolveMode readback_mode = GetReadbackResolveMode(REXCVAR_GET(d3d12_readback_resolve)); + if (readback_mode == ReadbackResolveMode::kDisabled) { + uint32_t written_address, written_length; + return render_target_cache_->Resolve(*memory_, *shared_memory_, *texture_cache_, + written_address, written_length); + } + return IssueCopy_ReadbackResolvePath(); +} + +bool D3D12CommandProcessor::IssueCopy_ReadbackResolvePath() { + uint32_t written_address, written_length; + if (!render_target_cache_->Resolve(*memory_, *shared_memory_, *texture_cache_, written_address, + written_length)) { + return false; + } + + if (!written_length) { + return true; + } + + if (!memory_->TranslatePhysical(written_address)) { + return true; + } + + bool is_scaled = texture_cache_->IsDrawResolutionScaled(); + uint64_t resolve_key = MakeReadbackResolveKey(written_address, written_length); + ReadbackBuffer& rb = readback_buffers_[resolve_key]; + rb.last_used_frame = frame_current_; + + uint32_t write_index = rb.current_index; + uint32_t size = AlignReadbackBufferSize(written_length); + + if (size > rb.sizes[write_index]) { + const ui::d3d12::D3D12Provider& provider = GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + D3D12_RESOURCE_DESC buffer_desc; + ui::d3d12::util::FillBufferResourceDesc(buffer_desc, size, D3D12_RESOURCE_FLAG_NONE); + ID3D12Resource* buffer = nullptr; + if (FAILED(device->CreateCommittedResource( + &ui::d3d12::util::kHeapPropertiesReadback, provider.GetHeapFlagCreateNotZeroed(), + &buffer_desc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&buffer)))) { + REXGPU_ERROR("Failed to create a {} MB readback buffer", size >> 20); + return true; + } + if (rb.buffers[write_index]) { + if (rb.mapped_data[write_index]) { + rb.buffers[write_index]->Unmap(0, nullptr); + rb.mapped_data[write_index] = nullptr; + } + rb.buffers[write_index]->Release(); + } + rb.buffers[write_index] = buffer; + rb.sizes[write_index] = size; + D3D12_RANGE read_range = {0, size}; + if (FAILED(buffer->Map(0, &read_range, &rb.mapped_data[write_index]))) { + REXGPU_ERROR("Failed to persistently map resolve readback buffer"); + rb.mapped_data[write_index] = nullptr; + } + } + + if (!rb.buffers[write_index]) { + return true; + } + + if (is_scaled) { + if (!resolve_downscale_pipeline_ || !resolve_downscale_root_signature_) { + return true; + } + + reg::RB_COPY_DEST_INFO copy_dest_info = register_file_->Get(); + const FormatInfo* format_info = FormatInfo::Get(uint32_t(copy_dest_info.copy_dest_format)); + uint32_t bits_per_pixel = format_info->bits_per_pixel; + if (bits_per_pixel != 8 && bits_per_pixel != 16 && bits_per_pixel != 32 && + bits_per_pixel != 64) { + return true; + } + + uint32_t pixel_size_log2; + if (!rex::bit_scan_forward(bits_per_pixel >> 3, &pixel_size_log2)) { + return true; + } + uint32_t tile_size_1x = 32 * 32 * (uint32_t(1) << pixel_size_log2); + uint32_t tile_count = written_length / tile_size_1x; + if (!tile_count) { + return true; + } + + uint32_t scaled_length = uint32_t(texture_cache_->GetCurrentScaledResolveRangeLengthScaled()); + uint64_t scaled_address = texture_cache_->GetCurrentScaledResolveRangeStartScaled(); + if (!scaled_length) { + return true; + } + + uint32_t downscale_buffer_size = AlignReadbackBufferSize(written_length); + if (downscale_buffer_size > resolve_downscale_buffer_size_) { + const ui::d3d12::D3D12Provider& provider = GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + D3D12_RESOURCE_DESC buffer_desc; + ui::d3d12::util::FillBufferResourceDesc(buffer_desc, downscale_buffer_size, + D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); + ID3D12Resource* buffer = nullptr; + if (FAILED(device->CreateCommittedResource( + &ui::d3d12::util::kHeapPropertiesDefault, provider.GetHeapFlagCreateNotZeroed(), + &buffer_desc, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, nullptr, + IID_PPV_ARGS(&buffer)))) { + REXGPU_ERROR("Failed to create a {} MB resolve downscale buffer", + downscale_buffer_size >> 20); + return true; + } + if (resolve_downscale_buffer_) { + resources_for_deletion_.emplace_back(GetCurrentSubmission(), + resolve_downscale_buffer_.Detach()); + } + resolve_downscale_buffer_.Attach(buffer); + resolve_downscale_buffer_size_ = downscale_buffer_size; + } + + if (!resolve_downscale_buffer_) { + return true; + } + + ID3D12Resource* scaled_resolve_buffer = texture_cache_->GetCurrentScaledResolveBufferResource(); + size_t scaled_resolve_buffer_index = texture_cache_->GetCurrentScaledResolveBufferIndexPublic(); + if (!scaled_resolve_buffer) { + return true; + } + uint64_t scaled_buffer_base = uint64_t(scaled_resolve_buffer_index) << 30; + if (scaled_address < scaled_buffer_base) { + return true; + } + uint64_t source_offset = scaled_address - scaled_buffer_base; + + ui::d3d12::util::DescriptorCpuGpuHandlePair downscale_descriptors[2]; + if (!RequestOneUseSingleViewDescriptors(2, downscale_descriptors)) { + return true; + } + + const ui::d3d12::D3D12Provider& provider = GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + uint32_t aligned_scaled_length = + rex::align(scaled_length, uint32_t(D3D12_RAW_UAV_SRV_BYTE_ALIGNMENT)); + ui::d3d12::util::CreateBufferRawSRV(device, downscale_descriptors[0].first, + scaled_resolve_buffer, aligned_scaled_length, + source_offset); + uint32_t aligned_written_length = + rex::align(written_length, uint32_t(D3D12_RAW_UAV_SRV_BYTE_ALIGNMENT)); + ui::d3d12::util::CreateBufferRawUAV(device, downscale_descriptors[1].first, + resolve_downscale_buffer_.Get(), aligned_written_length, 0); + + PushUAVBarrier(scaled_resolve_buffer); + texture_cache_->TransitionCurrentScaledResolveRange( + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + SubmitBarriers(); + + SetExternalPipeline(resolve_downscale_pipeline_.Get()); + deferred_command_list_.D3DSetComputeRootSignature(resolve_downscale_root_signature_.Get()); + ResolveDownscaleConstants constants; + constants.scale_x = texture_cache_->draw_resolution_scale_x(); + constants.scale_y = texture_cache_->draw_resolution_scale_y(); + constants.pixel_size_log2 = pixel_size_log2; + constants.tile_count = tile_count; + constants.half_pixel_offset = (REXCVAR_GET(readback_resolve_half_pixel_offset) && + (constants.scale_x > 1 || constants.scale_y > 1)) + ? 1u + : 0u; + deferred_command_list_.D3DSetComputeRoot32BitConstants( + UINT(ResolveDownscaleRootParameter::kConstants), sizeof(constants) / sizeof(uint32_t), + &constants, 0); + deferred_command_list_.D3DSetComputeRootDescriptorTable( + UINT(ResolveDownscaleRootParameter::kSource), downscale_descriptors[0].second); + deferred_command_list_.D3DSetComputeRootDescriptorTable( + UINT(ResolveDownscaleRootParameter::kDestination), downscale_descriptors[1].second); + deferred_command_list_.D3DDispatch(tile_count, 1, 1); + + PushUAVBarrier(resolve_downscale_buffer_.Get()); + PushTransitionBarrier(resolve_downscale_buffer_.Get(), D3D12_RESOURCE_STATE_UNORDERED_ACCESS, + D3D12_RESOURCE_STATE_COPY_SOURCE); + SubmitBarriers(); + deferred_command_list_.D3DCopyBufferRegion(rb.buffers[write_index], 0, + resolve_downscale_buffer_.Get(), 0, written_length); + PushTransitionBarrier(resolve_downscale_buffer_.Get(), D3D12_RESOURCE_STATE_COPY_SOURCE, + D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + texture_cache_->TransitionCurrentScaledResolveRange(D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + SubmitBarriers(); + } else { + shared_memory_->UseAsCopySource(); + SubmitBarriers(); + ID3D12Resource* shared_memory_buffer = shared_memory_->GetBuffer(); + deferred_command_list_.D3DCopyBufferRegion(rb.buffers[write_index], 0, shared_memory_buffer, + written_address, written_length); + } + + ReadbackResolveMode readback_mode = GetReadbackResolveMode(REXCVAR_GET(d3d12_readback_resolve)); + bool use_delayed_sync = + readback_mode == ReadbackResolveMode::kFast || readback_mode == ReadbackResolveMode::kSome; + uint32_t read_index = write_index; + if (use_delayed_sync) { + read_index = 1 - write_index; + } else if (!AwaitAllQueueOperationsCompletion()) { + return true; + } + + bool is_cache_miss = false; + if (use_delayed_sync && (!rb.buffers[read_index] || written_length > rb.sizes[read_index] || + !rb.mapped_data[read_index])) { + is_cache_miss = true; + read_index = write_index; + if (!AwaitAllQueueOperationsCompletion()) { + return true; + } + } + + bool should_copy = (readback_mode == ReadbackResolveMode::kSome) ? is_cache_miss : true; + if (should_copy && rb.buffers[read_index] && written_length <= rb.sizes[read_index] && + rb.mapped_data[read_index]) { + uint8_t* destination = memory_->TranslatePhysical(written_address); + if (destination) { + std::memcpy(destination, static_cast(rb.mapped_data[read_index]), written_length); + } + } + + rb.current_index = 1 - rb.current_index; + return true; +} + +void D3D12CommandProcessor::CheckSubmissionFence(uint64_t await_submission) { + if (await_submission >= submission_current_) { + if (submission_open_) { + EndSubmission(false); + } + // Ending an open submission should result in queue operations done directly + // (like UpdateTileMappings) to be tracked within the scope of that + // submission, but just in case of a failure, or queue operations being done + // outside of a submission, await explicitly. + if (queue_operations_done_since_submission_signal_) { + UINT64 fence_value = ++queue_operations_since_submission_fence_last_; + ID3D12CommandQueue* direct_queue = GetD3D12Provider().GetDirectQueue(); + if (SUCCEEDED(direct_queue->Signal(queue_operations_since_submission_fence_, fence_value) && + SUCCEEDED(queue_operations_since_submission_fence_->SetEventOnCompletion( + fence_value, fence_completion_event_)))) { + PROFILE_CMD_BUFFER_STALL(); + WaitForSingleObject(fence_completion_event_, INFINITE); + queue_operations_done_since_submission_signal_ = false; + } else { + REXGPU_ERROR( + "Failed to await an out-of-submission queue operation completion " + "Direct3D 12 fence"); + } + } + // A submission won't be ended if it hasn't been started, or if ending + // has failed - clamp the index. + await_submission = submission_current_ - 1; + } + + uint64_t submission_completed_before = submission_completed_; + submission_completed_ = submission_fence_->GetCompletedValue(); + if (submission_completed_ < await_submission) { + if (SUCCEEDED( + submission_fence_->SetEventOnCompletion(await_submission, fence_completion_event_))) { + PROFILE_CMD_BUFFER_STALL(); + WaitForSingleObject(fence_completion_event_, INFINITE); + submission_completed_ = submission_fence_->GetCompletedValue(); + } + } + if (submission_completed_ < await_submission) { + REXGPU_ERROR("Failed to await a submission completion Direct3D 12 fence"); + } + if (submission_completed_ <= submission_completed_before) { + // Not updated - no need to reclaim or download things. + return; + } + + // Reclaim command allocators. + while (command_allocator_submitted_first_) { + if (command_allocator_submitted_first_->last_usage_submission > submission_completed_) { + break; + } + if (command_allocator_writable_last_) { + command_allocator_writable_last_->next = command_allocator_submitted_first_; + } else { + command_allocator_writable_first_ = command_allocator_submitted_first_; + } + command_allocator_writable_last_ = command_allocator_submitted_first_; + command_allocator_submitted_first_ = command_allocator_submitted_first_->next; + command_allocator_writable_last_->next = nullptr; + } + if (!command_allocator_submitted_first_) { + command_allocator_submitted_last_ = nullptr; + } + + // Release single-use bindless descriptors. + while (!view_bindless_one_use_descriptors_.empty()) { + if (view_bindless_one_use_descriptors_.front().second > submission_completed_) { + break; + } + ReleaseViewBindlessDescriptorImmediately(view_bindless_one_use_descriptors_.front().first); + view_bindless_one_use_descriptors_.pop_front(); + } + + // Delete transient resources marked for deletion. + while (!resources_for_deletion_.empty()) { + if (resources_for_deletion_.front().first > submission_completed_) { + break; + } + resources_for_deletion_.front().second->Release(); + resources_for_deletion_.pop_front(); + } + + shared_memory_->CompletedSubmissionUpdated(); + + render_target_cache_->CompletedSubmissionUpdated(); + + primitive_processor_->CompletedSubmissionUpdated(); + + texture_cache_->CompletedSubmissionUpdated(submission_completed_); +} + +void D3D12CommandProcessor::LogDeviceRemovalDiagnostics(ID3D12Device* device, HRESULT reason) { + const char* reason_str = "Unknown"; + switch (reason) { + case DXGI_ERROR_DEVICE_HUNG: + reason_str = "DEVICE_HUNG (TDR - GPU command took too long)"; + break; + case DXGI_ERROR_DEVICE_REMOVED: + reason_str = "DEVICE_REMOVED (driver internal error or hot-unplug)"; + break; + case DXGI_ERROR_DEVICE_RESET: + reason_str = "DEVICE_RESET (bad GPU command)"; + break; + case DXGI_ERROR_DRIVER_INTERNAL_ERROR: + reason_str = "DRIVER_INTERNAL_ERROR"; + break; + case DXGI_ERROR_INVALID_CALL: + reason_str = "INVALID_CALL"; + break; + } + REXGPU_ERROR("D3D12 device removed: HRESULT 0x{:08X} - {}", static_cast(reason), + reason_str); + + Microsoft::WRL::ComPtr dred; + if (FAILED(device->QueryInterface(IID_PPV_ARGS(&dred)))) { + return; + } + + D3D12_DRED_AUTO_BREADCRUMBS_OUTPUT breadcrumbs = {}; + if (SUCCEEDED(dred->GetAutoBreadcrumbsOutput(&breadcrumbs))) { + for (const D3D12_AUTO_BREADCRUMB_NODE* node = breadcrumbs.pHeadAutoBreadcrumbNode; node; + node = node->pNext) { + if (!node->pLastBreadcrumbValue || !node->pCommandHistory || + *node->pLastBreadcrumbValue == 0) { + continue; + } + REXGPU_ERROR("DRED breadcrumb: completed {} of {} ops", *node->pLastBreadcrumbValue, + node->BreadcrumbCount); + uint32_t last = std::min(*node->pLastBreadcrumbValue, node->BreadcrumbCount); + uint32_t start = last > 3 ? last - 3 : 0; + uint32_t end = std::min(last + 1, node->BreadcrumbCount); + for (uint32_t i = start; i < end; i++) { + REXGPU_ERROR(" [{}] op type {}{}", i, static_cast(node->pCommandHistory[i]), + i == last ? " <-- FAULT" : ""); + } + } + } + + D3D12_DRED_PAGE_FAULT_OUTPUT page_fault = {}; + if (SUCCEEDED(dred->GetPageFaultAllocationOutput(&page_fault)) && page_fault.PageFaultVA != 0) { + REXGPU_ERROR("DRED page fault at VA 0x{:016X}", page_fault.PageFaultVA); + } +} + +bool D3D12CommandProcessor::BeginSubmission(bool is_guest_command) { +#if XE_GPU_FINE_GRAINED_DRAW_SCOPES + SCOPE_profile_cpu_f("gpu"); +#endif // XE_GPU_FINE_GRAINED_DRAW_SCOPES + + if (device_removed_) { + return false; + } + + bool is_opening_frame = is_guest_command && !frame_open_; + if (submission_open_ && !is_opening_frame) { + return true; + } + + // Check if the device is still available. + ID3D12Device* device = GetD3D12Provider().GetDevice(); + HRESULT device_removed_reason = device->GetDeviceRemovedReason(); + if (FAILED(device_removed_reason)) { + device_removed_ = true; + LogDeviceRemovalDiagnostics(device, device_removed_reason); + if (graphics_system_) { + graphics_system_->OnHostGpuLossFromAnyThread(device_removed_reason != + DXGI_ERROR_DEVICE_REMOVED); + } + return false; + } + + // Check the fence - needed for all kinds of submissions (to reclaim transient + // resources early) and specifically for frames (not to queue too many), and + // await the availability of the current frame. + CheckSubmissionFence(is_opening_frame ? closed_frame_submissions_[frame_current_ % kQueueFrames] + : 0); + // TODO(Triang3l): If failed to await (completed submission < awaited frame + // submission), do something like dropping the draw command that wanted to + // open the frame. + if (is_opening_frame) { + // Update the completed frame index, also obtaining the actual completed + // frame number (since the CPU may be actually less than 3 frames behind) + // before reclaiming resources tracked with the frame number. + frame_completed_ = std::max(frame_current_, uint64_t(kQueueFrames)) - kQueueFrames; + for (uint64_t frame = frame_completed_ + 1; frame < frame_current_; ++frame) { + if (closed_frame_submissions_[frame % kQueueFrames] > submission_completed_) { + break; + } + frame_completed_ = frame; + } + } + + if (!submission_open_) { + submission_open_ = true; + + // Start a new deferred command list - will submit it to the real one in the + // end of the submission (when async pipeline creation requests are + // fulfilled). + deferred_command_list_.Reset(); + + // Reset cached state of the command list. + ff_viewport_update_needed_ = true; + ff_scissor_update_needed_ = true; + ff_blend_factor_update_needed_ = true; + ff_stencil_ref_update_needed_ = true; + viewport_cache_valid_ = false; + current_guest_pipeline_ = nullptr; + current_external_pipeline_ = nullptr; + current_graphics_root_signature_ = nullptr; + current_graphics_root_up_to_date_ = 0; + if (bindless_resources_used_) { + deferred_command_list_.SetDescriptorHeaps(view_bindless_heap_, + sampler_bindless_heap_current_); + } else { + view_bindful_heap_current_ = nullptr; + sampler_bindful_heap_current_ = nullptr; + } + primitive_topology_ = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; + + render_target_cache_->BeginSubmission(); + + primitive_processor_->BeginSubmission(); + + texture_cache_->BeginSubmission(submission_current_); + } + + if (is_opening_frame) { + frame_open_ = true; + + // Reset bindings that depend on the data stored in the pools. + std::memset(current_float_constant_map_vertex_, 0, sizeof(current_float_constant_map_vertex_)); + std::memset(current_float_constant_map_pixel_, 0, sizeof(current_float_constant_map_pixel_)); + cbuffer_binding_system_.up_to_date = false; + cbuffer_binding_float_vertex_.up_to_date = false; + cbuffer_binding_float_pixel_.up_to_date = false; + cbuffer_binding_bool_loop_.up_to_date = false; + cbuffer_binding_fetch_.up_to_date = false; + current_shared_memory_binding_is_uav_.reset(); + if (bindless_resources_used_) { + cbuffer_binding_descriptor_indices_vertex_.up_to_date = false; + cbuffer_binding_descriptor_indices_pixel_.up_to_date = false; + } else { + draw_view_bindful_heap_index_ = ui::d3d12::D3D12DescriptorHeapPool::kHeapIndexInvalid; + draw_sampler_bindful_heap_index_ = ui::d3d12::D3D12DescriptorHeapPool::kHeapIndexInvalid; + bindful_textures_written_vertex_ = false; + bindful_textures_written_pixel_ = false; + bindful_samplers_written_vertex_ = false; + bindful_samplers_written_pixel_ = false; + } + + // Reclaim pool pages - no need to do this every small submission since some + // may be reused. + constant_buffer_pool_->Reclaim(frame_completed_); + if (!bindless_resources_used_) { + view_bindful_heap_pool_->Reclaim(frame_completed_); + sampler_bindful_heap_pool_->Reclaim(frame_completed_); + } + EvictOldReadbackBuffers(readback_buffers_); + EvictOldReadbackBuffers(memexport_readback_buffers_); + + pix_capturing_ = pix_capture_requested_.exchange(false, std::memory_order_relaxed); + if (pix_capturing_) { + IDXGraphicsAnalysis* graphics_analysis = GetD3D12Provider().GetGraphicsAnalysis(); + if (graphics_analysis != nullptr) { + graphics_analysis->BeginCapture(); + } + } + + primitive_processor_->BeginFrame(); + + texture_cache_->BeginFrame(); + } + + return true; +} + +bool D3D12CommandProcessor::EndSubmission(bool is_swap) { + const ui::d3d12::D3D12Provider& provider = GetD3D12Provider(); + + // Make sure there is a command allocator to write commands to. + if (submission_open_ && !command_allocator_writable_first_) { + ID3D12CommandAllocator* command_allocator; + if (FAILED(provider.GetDevice()->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, + IID_PPV_ARGS(&command_allocator)))) { + REXGPU_ERROR("Failed to create a command allocator"); + // Try to submit later. Completely dropping the submission is not + // permitted because resources would be left in an undefined state. + return false; + } + command_allocator_writable_first_ = new CommandAllocator; + command_allocator_writable_first_->command_allocator = command_allocator; + command_allocator_writable_first_->last_usage_submission = 0; + command_allocator_writable_first_->next = nullptr; + command_allocator_writable_last_ = command_allocator_writable_first_; + } + + bool is_closing_frame = is_swap && frame_open_; + + if (is_closing_frame) { + texture_cache_->EndFrame(); + + primitive_processor_->EndFrame(); + } + + if (submission_open_) { + assert_false(scratch_buffer_used_); + + if (active_occlusion_query_.valid && occlusion_query_heap_) { + deferred_command_list_.D3DEndQuery(occlusion_query_heap_.Get(), D3D12_QUERY_TYPE_OCCLUSION, + active_occlusion_query_.host_index); + active_occlusion_query_ = {}; + } + + pipeline_cache_->EndSubmission(); + + // Submit barriers now because resources with the queued barriers may be + // destroyed between frames. + SubmitBarriers(); + + ID3D12CommandQueue* direct_queue = provider.GetDirectQueue(); + + // Submit the deferred command list. + // Only one deferred command list must be executed in the same + // ExecuteCommandLists - the boundaries of ExecuteCommandLists are a full + // UAV and aliasing barrier, and subsystems of the emulator assume it + // happens between Xenia submissions. + ID3D12CommandAllocator* command_allocator = + command_allocator_writable_first_->command_allocator; + command_allocator->Reset(); + command_list_->Reset(command_allocator, nullptr); + deferred_command_list_.Execute(command_list_, command_list_1_); + command_list_->Close(); + ID3D12CommandList* execute_command_lists[] = {command_list_}; + direct_queue->ExecuteCommandLists(1, execute_command_lists); + command_allocator_writable_first_->last_usage_submission = submission_current_; + if (command_allocator_submitted_last_) { + command_allocator_submitted_last_->next = command_allocator_writable_first_; + } else { + command_allocator_submitted_first_ = command_allocator_writable_first_; + } + command_allocator_submitted_last_ = command_allocator_writable_first_; + command_allocator_writable_first_ = command_allocator_writable_first_->next; + command_allocator_submitted_last_->next = nullptr; + if (!command_allocator_writable_first_) { + command_allocator_writable_last_ = nullptr; + } + + direct_queue->Signal(submission_fence_, submission_current_++); + + submission_open_ = false; + + // Queue operations done directly (like UpdateTileMappings) will be awaited + // alongside the last submission if needed. + queue_operations_done_since_submission_signal_ = false; + } + + if (is_closing_frame) { + if (REXCVAR_GET(clear_memory_page_state) && shared_memory_) { + shared_memory_->SetSystemPageBlocksValidWithGpuDataWritten(); + } + // Close the capture after submitting. + if (pix_capturing_) { + IDXGraphicsAnalysis* graphics_analysis = provider.GetGraphicsAnalysis(); + if (graphics_analysis != nullptr) { + graphics_analysis->EndCapture(); + } + pix_capturing_ = false; + } + frame_open_ = false; + // Submission already closed now, so minus 1. + closed_frame_submissions_[(frame_current_++) % kQueueFrames] = submission_current_ - 1; + + if (cache_clear_requested_ && AwaitAllQueueOperationsCompletion()) { + cache_clear_requested_ = false; + + ClearCommandAllocatorCache(); + + ui::d3d12::util::ReleaseAndNull(scratch_buffer_); + scratch_buffer_size_ = 0; + + if (bindless_resources_used_) { + texture_cache_bindless_sampler_map_.clear(); + for (const auto& sampler_bindless_heap_overflowed : sampler_bindless_heaps_overflowed_) { + sampler_bindless_heap_overflowed.first->Release(); + } + sampler_bindless_heaps_overflowed_.clear(); + sampler_bindless_heap_allocated_ = 0; + } else { + sampler_bindful_heap_pool_->ClearCache(); + view_bindful_heap_pool_->ClearCache(); + } + constant_buffer_pool_->ClearCache(); + + texture_cache_->ClearCache(); + + // Not clearing the root signatures as they're referenced by pipelines, + // which are not destroyed. + + primitive_processor_->ClearCache(); + + render_target_cache_->ClearCache(); + + shared_memory_->ClearCache(); + } + } + + return true; +} + +bool D3D12CommandProcessor::CanEndSubmissionImmediately() const { + return !submission_open_ || !pipeline_cache_->IsCreatingPipelines(); +} + +void D3D12CommandProcessor::ClearCommandAllocatorCache() { + while (command_allocator_submitted_first_) { + auto next = command_allocator_submitted_first_->next; + command_allocator_submitted_first_->command_allocator->Release(); + delete command_allocator_submitted_first_; + command_allocator_submitted_first_ = next; + } + command_allocator_submitted_last_ = nullptr; + while (command_allocator_writable_first_) { + auto next = command_allocator_writable_first_->next; + command_allocator_writable_first_->command_allocator->Release(); + delete command_allocator_writable_first_; + command_allocator_writable_first_ = next; + } + command_allocator_writable_last_ = nullptr; +} + +void D3D12CommandProcessor::UpdateFixedFunctionState( + const draw_util::ViewportInfo& viewport_info, const draw_util::Scissor& scissor, + bool primitive_polygonal, reg::RB_DEPTHCONTROL normalized_depth_control) { +#if XE_GPU_FINE_GRAINED_DRAW_SCOPES + SCOPE_profile_cpu_f("gpu"); +#endif // XE_GPU_FINE_GRAINED_DRAW_SCOPES + + // Viewport. + D3D12_VIEWPORT viewport; + viewport.TopLeftX = float(viewport_info.xy_offset[0]); + viewport.TopLeftY = float(viewport_info.xy_offset[1]); + viewport.Width = float(viewport_info.xy_extent[0]); + viewport.Height = float(viewport_info.xy_extent[1]); + viewport.MinDepth = viewport_info.z_min; + viewport.MaxDepth = viewport_info.z_max; + SetViewport(viewport); + + // Scissor. + D3D12_RECT scissor_rect; + scissor_rect.left = LONG(scissor.offset[0]); + scissor_rect.top = LONG(scissor.offset[1]); + scissor_rect.right = LONG(scissor.offset[0] + scissor.extent[0]); + scissor_rect.bottom = LONG(scissor.offset[1] + scissor.extent[1]); + SetScissorRect(scissor_rect); + + if (render_target_cache_->GetPath() == RenderTargetCache::Path::kHostRenderTargets) { + const RegisterFile& regs = *register_file_; + + // Blend factor. + float blend_factor[] = { + regs.Get(XE_GPU_REG_RB_BLEND_RED), + regs.Get(XE_GPU_REG_RB_BLEND_GREEN), + regs.Get(XE_GPU_REG_RB_BLEND_BLUE), + regs.Get(XE_GPU_REG_RB_BLEND_ALPHA), + }; + // std::memcmp instead of != so in case of NaN, every draw won't be + // invalidating it. + ff_blend_factor_update_needed_ |= + std::memcmp(ff_blend_factor_, blend_factor, sizeof(float) * 4) != 0; + if (ff_blend_factor_update_needed_) { + std::memcpy(ff_blend_factor_, blend_factor, sizeof(float) * 4); + deferred_command_list_.D3DOMSetBlendFactor(ff_blend_factor_); + ff_blend_factor_update_needed_ = false; + } + + // Stencil reference value. Per-face reference not supported by Direct3D 12, + // choose the back face one only if drawing only back faces. + Register stencil_ref_mask_reg; + auto pa_su_sc_mode_cntl = regs.Get(); + if (primitive_polygonal && normalized_depth_control.backface_enable && + pa_su_sc_mode_cntl.cull_front && !pa_su_sc_mode_cntl.cull_back) { + stencil_ref_mask_reg = XE_GPU_REG_RB_STENCILREFMASK_BF; + } else { + stencil_ref_mask_reg = XE_GPU_REG_RB_STENCILREFMASK; + } + uint32_t stencil_ref = regs.Get(stencil_ref_mask_reg).stencilref; + ff_stencil_ref_update_needed_ |= ff_stencil_ref_ != stencil_ref; + if (ff_stencil_ref_update_needed_) { + ff_stencil_ref_ = stencil_ref; + deferred_command_list_.D3DOMSetStencilRef(ff_stencil_ref_); + ff_stencil_ref_update_needed_ = false; + } + } +} + +void D3D12CommandProcessor::UpdateSystemConstantValues( + bool shared_memory_is_uav, bool primitive_polygonal, uint32_t line_loop_closing_index, + xenos::Endian index_endian, const draw_util::ViewportInfo& viewport_info, + uint32_t used_texture_mask, reg::RB_DEPTHCONTROL normalized_depth_control, + uint32_t normalized_color_mask) { +#if XE_GPU_FINE_GRAINED_DRAW_SCOPES + SCOPE_profile_cpu_f("gpu"); +#endif // XE_GPU_FINE_GRAINED_DRAW_SCOPES + + const RegisterFile& regs = *register_file_; + auto pa_cl_clip_cntl = regs.Get(); + auto pa_cl_vte_cntl = regs.Get(); + auto pa_su_sc_mode_cntl = regs.Get(); + auto rb_alpha_ref = regs.Get(XE_GPU_REG_RB_ALPHA_REF); + auto rb_colorcontrol = regs.Get(); + auto rb_depth_info = regs.Get(); + auto rb_stencilrefmask = regs.Get(); + auto rb_stencilrefmask_bf = regs.Get(XE_GPU_REG_RB_STENCILREFMASK_BF); + auto rb_surface_info = regs.Get(); + auto sq_context_misc = regs.Get(); + auto sq_program_cntl = regs.Get(); + auto vgt_draw_initiator = regs.Get(); + uint32_t vgt_indx_offset = regs.Get().indx_offset; + uint32_t vgt_max_vtx_indx = regs.Get().max_indx; + uint32_t vgt_min_vtx_indx = regs.Get().min_indx; + + bool edram_rov_used = + render_target_cache_->GetPath() == RenderTargetCache::Path::kPixelShaderInterlock; + uint32_t draw_resolution_scale_x = texture_cache_->draw_resolution_scale_x(); + uint32_t draw_resolution_scale_y = texture_cache_->draw_resolution_scale_y(); + + // Get the color info register values for each render target. Also, for ROV, + // exclude components that don't exist in the format from the write mask. + // Don't exclude fully overlapping render targets, however - two render + // targets with the same base address are used in the lighting pass of + // 4D5307E6, for example, with the needed one picked with dynamic control + // flow. + reg::RB_COLOR_INFO color_infos[4]; + float rt_clamp[4][4]; + // Two UINT32_MAX if no components actually existing in the RT are written. + uint32_t rt_keep_masks[4][2]; + for (uint32_t i = 0; i < 4; ++i) { + auto color_info = regs.Get(reg::RB_COLOR_INFO::rt_register_indices[i]); + color_infos[i] = color_info; + if (edram_rov_used) { + RenderTargetCache::GetPSIColorFormatInfo( + color_info.color_format, (normalized_color_mask >> (i * 4)) & 0b1111, rt_clamp[i][0], + rt_clamp[i][1], rt_clamp[i][2], rt_clamp[i][3], rt_keep_masks[i][0], rt_keep_masks[i][1]); + } + } + + // Disable depth and stencil if it aliases a color render target (for + // instance, during the XBLA logo in 58410954, though depth writing is already + // disabled there). + bool depth_stencil_enabled = + normalized_depth_control.stencil_enable || normalized_depth_control.z_enable; + if (edram_rov_used && depth_stencil_enabled) { + for (uint32_t i = 0; i < 4; ++i) { + if (rb_depth_info.depth_base == color_infos[i].color_base && + (rt_keep_masks[i][0] != UINT32_MAX || rt_keep_masks[i][1] != UINT32_MAX)) { + depth_stencil_enabled = false; + break; + } + } + } + + bool dirty = false; + + // Flags. + uint32_t flags = 0; + // Whether shared memory is an SRV or a UAV. Because a resource can't be in a + // read-write (UAV) and a read-only (SRV, IBV) state at once, if any shader in + // the pipeline uses memexport, the shared memory buffer must be a UAV. + if (shared_memory_is_uav) { + flags |= DxbcShaderTranslator::kSysFlag_SharedMemoryIsUAV; + } + // W0 division control. + // http://www.x.org/docs/AMD/old/evergreen_3D_registers_v2.pdf + // 8: VTX_XY_FMT = true: the incoming XY have already been multiplied by 1/W0. + // = false: multiply the X, Y coordinates by 1/W0. + // 9: VTX_Z_FMT = true: the incoming Z has already been multiplied by 1/W0. + // = false: multiply the Z coordinate by 1/W0. + // 10: VTX_W0_FMT = true: the incoming W0 is not 1/W0. Perform the reciprocal + // to get 1/W0. + if (pa_cl_vte_cntl.vtx_xy_fmt) { + flags |= DxbcShaderTranslator::kSysFlag_XYDividedByW; + } + if (pa_cl_vte_cntl.vtx_z_fmt) { + flags |= DxbcShaderTranslator::kSysFlag_ZDividedByW; + } + if (pa_cl_vte_cntl.vtx_w0_fmt) { + flags |= DxbcShaderTranslator::kSysFlag_WNotReciprocal; + } + // Whether the primitive is polygonal and SV_IsFrontFace matters. + if (primitive_polygonal) { + flags |= DxbcShaderTranslator::kSysFlag_PrimitivePolygonal; + } + // Primitive type. + if (draw_util::IsPrimitiveLine(regs)) { + flags |= DxbcShaderTranslator::kSysFlag_PrimitiveLine; + } + // Depth format. + if (rb_depth_info.depth_format == xenos::DepthRenderTargetFormat::kD24FS8) { + flags |= DxbcShaderTranslator::kSysFlag_DepthFloat24; + } + // Alpha test. + xenos::CompareFunction alpha_test_function = rb_colorcontrol.alpha_test_enable + ? rb_colorcontrol.alpha_func + : xenos::CompareFunction::kAlways; + flags |= uint32_t(alpha_test_function) << DxbcShaderTranslator::kSysFlag_AlphaPassIfLess_Shift; + // Gamma writing. + if (!render_target_cache_->gamma_render_target_as_unorm16()) { + for (uint32_t i = 0; i < 4; ++i) { + if (color_infos[i].color_format == xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA) { + flags |= DxbcShaderTranslator::kSysFlag_ConvertColor0ToGamma << i; + } + } + } + if (edram_rov_used && depth_stencil_enabled) { + flags |= DxbcShaderTranslator::kSysFlag_ROVDepthStencil; + if (normalized_depth_control.z_enable) { + flags |= uint32_t(normalized_depth_control.zfunc) + << DxbcShaderTranslator::kSysFlag_ROVDepthPassIfLess_Shift; + if (normalized_depth_control.z_write_enable) { + flags |= DxbcShaderTranslator::kSysFlag_ROVDepthWrite; + } + } else { + // In case stencil is used without depth testing - always pass, and + // don't modify the stored depth. + flags |= DxbcShaderTranslator::kSysFlag_ROVDepthPassIfLess | + DxbcShaderTranslator::kSysFlag_ROVDepthPassIfEqual | + DxbcShaderTranslator::kSysFlag_ROVDepthPassIfGreater; + } + if (normalized_depth_control.stencil_enable) { + flags |= DxbcShaderTranslator::kSysFlag_ROVStencilTest; + } + // Hint - if not applicable to the shader, will not have effect. + if (alpha_test_function == xenos::CompareFunction::kAlways && + !rb_colorcontrol.alpha_to_mask_enable) { + flags |= DxbcShaderTranslator::kSysFlag_ROVDepthStencilEarlyWrite; + } + } + dirty |= system_constants_.flags != flags; + system_constants_.flags = flags; + + // Tessellation factor range, plus 1.0 according to the images in + // https://www.slideshare.net/blackdevilvikas/next-generation-graphics-programming-on-xbox-360 + float tessellation_factor_min = regs.Get(XE_GPU_REG_VGT_HOS_MIN_TESS_LEVEL) + 1.0f; + float tessellation_factor_max = regs.Get(XE_GPU_REG_VGT_HOS_MAX_TESS_LEVEL) + 1.0f; + dirty |= system_constants_.tessellation_factor_range_min != tessellation_factor_min; + system_constants_.tessellation_factor_range_min = tessellation_factor_min; + dirty |= system_constants_.tessellation_factor_range_max != tessellation_factor_max; + system_constants_.tessellation_factor_range_max = tessellation_factor_max; + + // Line loop closing index (or 0 when drawing other primitives or using an + // index buffer). + dirty |= system_constants_.line_loop_closing_index != line_loop_closing_index; + system_constants_.line_loop_closing_index = line_loop_closing_index; + + // Index or tessellation edge factor buffer endianness. + dirty |= system_constants_.vertex_index_endian != index_endian; + system_constants_.vertex_index_endian = index_endian; + + // Vertex index offset. + dirty |= system_constants_.vertex_index_offset != vgt_indx_offset; + system_constants_.vertex_index_offset = vgt_indx_offset; + + // Vertex index range. + dirty |= system_constants_.vertex_index_min != vgt_min_vtx_indx; + dirty |= system_constants_.vertex_index_max != vgt_max_vtx_indx; + system_constants_.vertex_index_min = vgt_min_vtx_indx; + system_constants_.vertex_index_max = vgt_max_vtx_indx; + + // User clip planes (UCP_ENA_#), when not CLIP_DISABLE. + // The shader knows only the total count - tightly packing the user clip + // planes that are actually used. + if (!pa_cl_clip_cntl.clip_disable) { + float* user_clip_plane_write_ptr = system_constants_.user_clip_planes[0]; + uint32_t user_clip_planes_remaining = pa_cl_clip_cntl.ucp_ena; + uint32_t user_clip_plane_index; + while (rex::bit_scan_forward(user_clip_planes_remaining, &user_clip_plane_index)) { + user_clip_planes_remaining &= ~(UINT32_C(1) << user_clip_plane_index); + const void* user_clip_plane_regs = + ®s[XE_GPU_REG_PA_CL_UCP_0_X + user_clip_plane_index * 4]; + if (std::memcmp(user_clip_plane_write_ptr, user_clip_plane_regs, 4 * sizeof(float))) { + dirty = true; + std::memcpy(user_clip_plane_write_ptr, user_clip_plane_regs, 4 * sizeof(float)); + } + user_clip_plane_write_ptr += 4; + } + } + + // Conversion to Direct3D 12 normalized device coordinates. + for (uint32_t i = 0; i < 3; ++i) { + dirty |= system_constants_.ndc_scale[i] != viewport_info.ndc_scale[i]; + dirty |= system_constants_.ndc_offset[i] != viewport_info.ndc_offset[i]; + system_constants_.ndc_scale[i] = viewport_info.ndc_scale[i]; + system_constants_.ndc_offset[i] = viewport_info.ndc_offset[i]; + } + + // Point size. + if (vgt_draw_initiator.prim_type == xenos::PrimitiveType::kPointList) { + auto pa_su_point_minmax = regs.Get(); + auto pa_su_point_size = regs.Get(); + float point_vertex_diameter_min = float(pa_su_point_minmax.min_size) * (2.0f / 16.0f); + float point_vertex_diameter_max = float(pa_su_point_minmax.max_size) * (2.0f / 16.0f); + float point_constant_diameter_x = float(pa_su_point_size.width) * (2.0f / 16.0f); + float point_constant_diameter_y = float(pa_su_point_size.height) * (2.0f / 16.0f); + dirty |= system_constants_.point_vertex_diameter_min != point_vertex_diameter_min; + dirty |= system_constants_.point_vertex_diameter_max != point_vertex_diameter_max; + dirty |= system_constants_.point_constant_diameter[0] != point_constant_diameter_x; + dirty |= system_constants_.point_constant_diameter[1] != point_constant_diameter_y; + system_constants_.point_vertex_diameter_min = point_vertex_diameter_min; + system_constants_.point_vertex_diameter_max = point_vertex_diameter_max; + system_constants_.point_constant_diameter[0] = point_constant_diameter_x; + system_constants_.point_constant_diameter[1] = point_constant_diameter_y; + // 2 because 1 in the NDC is half of the viewport's axis, 0.5 for diameter + // to radius conversion to avoid multiplying the per-vertex diameter by an + // additional constant in the shader. + float point_screen_diameter_to_ndc_radius_x = + (/* 0.5f * 2.0f * */ float(draw_resolution_scale_x)) / + std::max(viewport_info.xy_extent[0], uint32_t(1)); + float point_screen_diameter_to_ndc_radius_y = + (/* 0.5f * 2.0f * */ float(draw_resolution_scale_y)) / + std::max(viewport_info.xy_extent[1], uint32_t(1)); + dirty |= system_constants_.point_screen_diameter_to_ndc_radius[0] != + point_screen_diameter_to_ndc_radius_x; + dirty |= system_constants_.point_screen_diameter_to_ndc_radius[1] != + point_screen_diameter_to_ndc_radius_y; + system_constants_.point_screen_diameter_to_ndc_radius[0] = + point_screen_diameter_to_ndc_radius_x; + system_constants_.point_screen_diameter_to_ndc_radius[1] = + point_screen_diameter_to_ndc_radius_y; + } + + // Texture signedness / gamma. + uint32_t textures_resolution_scaled = 0; + uint32_t textures_remaining = used_texture_mask; + uint32_t texture_index; + while (rex::bit_scan_forward(textures_remaining, &texture_index)) { + textures_remaining &= ~(uint32_t(1) << texture_index); + uint32_t& texture_signs_uint = system_constants_.texture_swizzled_signs[texture_index >> 2]; + uint32_t texture_signs_shift = (texture_index & 3) * 8; + uint8_t texture_signs = texture_cache_->GetActiveTextureSwizzledSigns(texture_index); + uint32_t texture_signs_shifted = uint32_t(texture_signs) << texture_signs_shift; + uint32_t texture_signs_mask = uint32_t(0b11111111) << texture_signs_shift; + dirty |= (texture_signs_uint & texture_signs_mask) != texture_signs_shifted; + texture_signs_uint = (texture_signs_uint & ~texture_signs_mask) | texture_signs_shifted; + textures_resolution_scaled |= + uint32_t(texture_cache_->IsActiveTextureResolutionScaled(texture_index)) << texture_index; + } + dirty |= system_constants_.textures_resolution_scaled != textures_resolution_scaled; + system_constants_.textures_resolution_scaled = textures_resolution_scaled; + + // Log2 of sample count, for alpha to mask and with ROV, for EDRAM address + // calculation with MSAA. + uint32_t sample_count_log2_x = rb_surface_info.msaa_samples >= xenos::MsaaSamples::k4X ? 1 : 0; + uint32_t sample_count_log2_y = rb_surface_info.msaa_samples >= xenos::MsaaSamples::k2X ? 1 : 0; + dirty |= system_constants_.sample_count_log2[0] != sample_count_log2_x; + dirty |= system_constants_.sample_count_log2[1] != sample_count_log2_y; + system_constants_.sample_count_log2[0] = sample_count_log2_x; + system_constants_.sample_count_log2[1] = sample_count_log2_y; + + // Alpha test and alpha to coverage. + dirty |= system_constants_.alpha_test_reference != rb_alpha_ref; + system_constants_.alpha_test_reference = rb_alpha_ref; + uint32_t alpha_to_mask = + rb_colorcontrol.alpha_to_mask_enable ? (rb_colorcontrol.value >> 24) | (1 << 8) : 0; + dirty |= system_constants_.alpha_to_mask != alpha_to_mask; + system_constants_.alpha_to_mask = alpha_to_mask; + + uint32_t edram_tile_dwords_scaled = xenos::kEdramTileWidthSamples * + xenos::kEdramTileHeightSamples * + (draw_resolution_scale_x * draw_resolution_scale_y); + + // EDRAM pitch for ROV writing. + if (edram_rov_used) { + // Align, then multiply by 32bpp tile size in dwords. + uint32_t edram_32bpp_tile_pitch_dwords_scaled = + ((rb_surface_info.surface_pitch * + (rb_surface_info.msaa_samples >= xenos::MsaaSamples::k4X ? 2 : 1)) + + (xenos::kEdramTileWidthSamples - 1)) / + xenos::kEdramTileWidthSamples * edram_tile_dwords_scaled; + dirty |= system_constants_.edram_32bpp_tile_pitch_dwords_scaled != + edram_32bpp_tile_pitch_dwords_scaled; + system_constants_.edram_32bpp_tile_pitch_dwords_scaled = edram_32bpp_tile_pitch_dwords_scaled; + } + + // Color exponent bias and ROV render target writing. + for (uint32_t i = 0; i < 4; ++i) { + reg::RB_COLOR_INFO color_info = color_infos[i]; + // Exponent bias is in bits 20:25 of RB_COLOR_INFO. + int32_t color_exp_bias = color_info.color_exp_bias; + if (color_info.color_format == xenos::ColorRenderTargetFormat::k_16_16 || + color_info.color_format == xenos::ColorRenderTargetFormat::k_16_16_16_16) { + if (render_target_cache_->GetPath() == RenderTargetCache::Path::kHostRenderTargets && + !render_target_cache_->IsFixed16TruncatedToMinus1To1()) { + // Remap from -32...32 to -1...1 by dividing the output values by 32, + // losing blending correctness, but getting the full range. + color_exp_bias -= 5; + } + } + auto color_exp_bias_scale = + rex::memory::Reinterpret(int32_t(0x3F800000 + (color_exp_bias << 23))); + dirty |= system_constants_.color_exp_bias[i] != color_exp_bias_scale; + system_constants_.color_exp_bias[i] = color_exp_bias_scale; + if (edram_rov_used) { + dirty |= system_constants_.edram_rt_keep_mask[i][0] != rt_keep_masks[i][0]; + system_constants_.edram_rt_keep_mask[i][0] = rt_keep_masks[i][0]; + dirty |= system_constants_.edram_rt_keep_mask[i][1] != rt_keep_masks[i][1]; + system_constants_.edram_rt_keep_mask[i][1] = rt_keep_masks[i][1]; + if (rt_keep_masks[i][0] != UINT32_MAX || rt_keep_masks[i][1] != UINT32_MAX) { + uint32_t rt_base_dwords_scaled = color_info.color_base * edram_tile_dwords_scaled; + dirty |= system_constants_.edram_rt_base_dwords_scaled[i] != rt_base_dwords_scaled; + system_constants_.edram_rt_base_dwords_scaled[i] = rt_base_dwords_scaled; + uint32_t format_flags = RenderTargetCache::AddPSIColorFormatFlags(color_info.color_format); + dirty |= system_constants_.edram_rt_format_flags[i] != format_flags; + system_constants_.edram_rt_format_flags[i] = format_flags; + // Can't do float comparisons here because NaNs would result in always + // setting the dirty flag. + dirty |= + std::memcmp(system_constants_.edram_rt_clamp[i], rt_clamp[i], 4 * sizeof(float)) != 0; + std::memcpy(system_constants_.edram_rt_clamp[i], rt_clamp[i], 4 * sizeof(float)); + uint32_t blend_factors_ops = + regs[reg::RB_BLENDCONTROL::rt_register_indices[i]] & 0x1FFF1FFF; + dirty |= system_constants_.edram_rt_blend_factors_ops[i] != blend_factors_ops; + system_constants_.edram_rt_blend_factors_ops[i] = blend_factors_ops; + } + } + } + + if (edram_rov_used) { + uint32_t depth_base_dwords_scaled = rb_depth_info.depth_base * edram_tile_dwords_scaled; + dirty |= system_constants_.edram_depth_base_dwords_scaled != depth_base_dwords_scaled; + system_constants_.edram_depth_base_dwords_scaled = depth_base_dwords_scaled; + + // For non-polygons, front polygon offset is used, and it's enabled if + // POLY_OFFSET_PARA_ENABLED is set, for polygons, separate front and back + // are used. + float poly_offset_front_scale = 0.0f, poly_offset_front_offset = 0.0f; + float poly_offset_back_scale = 0.0f, poly_offset_back_offset = 0.0f; + if (primitive_polygonal) { + if (pa_su_sc_mode_cntl.poly_offset_front_enable) { + poly_offset_front_scale = regs.Get(XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_SCALE); + poly_offset_front_offset = regs.Get(XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_OFFSET); + } + if (pa_su_sc_mode_cntl.poly_offset_back_enable) { + poly_offset_back_scale = regs.Get(XE_GPU_REG_PA_SU_POLY_OFFSET_BACK_SCALE); + poly_offset_back_offset = regs.Get(XE_GPU_REG_PA_SU_POLY_OFFSET_BACK_OFFSET); + } + } else { + if (pa_su_sc_mode_cntl.poly_offset_para_enable) { + poly_offset_front_scale = regs.Get(XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_SCALE); + poly_offset_front_offset = regs.Get(XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_OFFSET); + poly_offset_back_scale = poly_offset_front_scale; + poly_offset_back_offset = poly_offset_front_offset; + } + } + // With non-square resolution scaling, make sure the worst-case impact is + // reverted (slope only along the scaled axis), thus max. More bias is + // better than less bias, because less bias means Z fighting with the + // background is more likely. + float poly_offset_scale_factor = xenos::kPolygonOffsetScaleSubpixelUnit * + std::max(draw_resolution_scale_x, draw_resolution_scale_y); + poly_offset_front_scale *= poly_offset_scale_factor; + poly_offset_back_scale *= poly_offset_scale_factor; + dirty |= system_constants_.edram_poly_offset_front_scale != poly_offset_front_scale; + system_constants_.edram_poly_offset_front_scale = poly_offset_front_scale; + dirty |= system_constants_.edram_poly_offset_front_offset != poly_offset_front_offset; + system_constants_.edram_poly_offset_front_offset = poly_offset_front_offset; + dirty |= system_constants_.edram_poly_offset_back_scale != poly_offset_back_scale; + system_constants_.edram_poly_offset_back_scale = poly_offset_back_scale; + dirty |= system_constants_.edram_poly_offset_back_offset != poly_offset_back_offset; + system_constants_.edram_poly_offset_back_offset = poly_offset_back_offset; + + if (depth_stencil_enabled && normalized_depth_control.stencil_enable) { + dirty |= system_constants_.edram_stencil_front_reference != rb_stencilrefmask.stencilref; + system_constants_.edram_stencil_front_reference = rb_stencilrefmask.stencilref; + dirty |= system_constants_.edram_stencil_front_read_mask != rb_stencilrefmask.stencilmask; + system_constants_.edram_stencil_front_read_mask = rb_stencilrefmask.stencilmask; + dirty |= + system_constants_.edram_stencil_front_write_mask != rb_stencilrefmask.stencilwritemask; + system_constants_.edram_stencil_front_write_mask = rb_stencilrefmask.stencilwritemask; + uint32_t stencil_func_ops = (normalized_depth_control.value >> 8) & ((1 << 12) - 1); + dirty |= system_constants_.edram_stencil_front_func_ops != stencil_func_ops; + system_constants_.edram_stencil_front_func_ops = stencil_func_ops; + + if (primitive_polygonal && normalized_depth_control.backface_enable) { + dirty |= system_constants_.edram_stencil_back_reference != rb_stencilrefmask_bf.stencilref; + system_constants_.edram_stencil_back_reference = rb_stencilrefmask_bf.stencilref; + dirty |= system_constants_.edram_stencil_back_read_mask != rb_stencilrefmask_bf.stencilmask; + system_constants_.edram_stencil_back_read_mask = rb_stencilrefmask_bf.stencilmask; + dirty |= system_constants_.edram_stencil_back_write_mask != + rb_stencilrefmask_bf.stencilwritemask; + system_constants_.edram_stencil_back_write_mask = rb_stencilrefmask_bf.stencilwritemask; + uint32_t stencil_func_ops_bf = (normalized_depth_control.value >> 20) & ((1 << 12) - 1); + dirty |= system_constants_.edram_stencil_back_func_ops != stencil_func_ops_bf; + system_constants_.edram_stencil_back_func_ops = stencil_func_ops_bf; + } else { + dirty |= std::memcmp(system_constants_.edram_stencil_back, + system_constants_.edram_stencil_front, 4 * sizeof(uint32_t)) != 0; + std::memcpy(system_constants_.edram_stencil_back, system_constants_.edram_stencil_front, + 4 * sizeof(uint32_t)); + } + } + + dirty |= system_constants_.edram_blend_constant[0] != regs.Get(XE_GPU_REG_RB_BLEND_RED); + system_constants_.edram_blend_constant[0] = regs.Get(XE_GPU_REG_RB_BLEND_RED); + dirty |= + system_constants_.edram_blend_constant[1] != regs.Get(XE_GPU_REG_RB_BLEND_GREEN); + system_constants_.edram_blend_constant[1] = regs.Get(XE_GPU_REG_RB_BLEND_GREEN); + dirty |= system_constants_.edram_blend_constant[2] != regs.Get(XE_GPU_REG_RB_BLEND_BLUE); + system_constants_.edram_blend_constant[2] = regs.Get(XE_GPU_REG_RB_BLEND_BLUE); + dirty |= + system_constants_.edram_blend_constant[3] != regs.Get(XE_GPU_REG_RB_BLEND_ALPHA); + system_constants_.edram_blend_constant[3] = regs.Get(XE_GPU_REG_RB_BLEND_ALPHA); + } + + cbuffer_binding_system_.up_to_date &= !dirty; +} + +bool D3D12CommandProcessor::UpdateBindings(const D3D12Shader* vertex_shader, + const D3D12Shader* pixel_shader, + ID3D12RootSignature* root_signature, + bool shared_memory_is_uav) { + const ui::d3d12::D3D12Provider& provider = GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + const RegisterFile& regs = *register_file_; + +#if XE_GPU_FINE_GRAINED_DRAW_SCOPES + SCOPE_profile_cpu_f("gpu"); +#endif // XE_GPU_FINE_GRAINED_DRAW_SCOPES + + // Set the new root signature. + if (current_graphics_root_signature_ != root_signature) { + current_graphics_root_signature_ = root_signature; + if (!bindless_resources_used_) { + GetRootBindfulExtraParameterIndices(vertex_shader, pixel_shader, + current_graphics_root_bindful_extras_); + } + // Changing the root signature invalidates all bindings. + current_graphics_root_up_to_date_ = 0; + deferred_command_list_.D3DSetGraphicsRootSignature(root_signature); + } + + // Select the root parameter indices depending on the used binding model. + uint32_t root_parameter_fetch_constants = bindless_resources_used_ + ? kRootParameter_Bindless_FetchConstants + : kRootParameter_Bindful_FetchConstants; + uint32_t root_parameter_float_constants_vertex = + bindless_resources_used_ ? kRootParameter_Bindless_FloatConstantsVertex + : kRootParameter_Bindful_FloatConstantsVertex; + uint32_t root_parameter_float_constants_pixel = bindless_resources_used_ + ? kRootParameter_Bindless_FloatConstantsPixel + : kRootParameter_Bindful_FloatConstantsPixel; + uint32_t root_parameter_system_constants = bindless_resources_used_ + ? kRootParameter_Bindless_SystemConstants + : kRootParameter_Bindful_SystemConstants; + uint32_t root_parameter_bool_loop_constants = bindless_resources_used_ + ? kRootParameter_Bindless_BoolLoopConstants + : kRootParameter_Bindful_BoolLoopConstants; + uint32_t root_parameter_shared_memory_and_bindful_edram = + bindless_resources_used_ ? kRootParameter_Bindless_SharedMemory + : kRootParameter_Bindful_SharedMemoryAndEdram; + + // + // Update root constant buffers that are common for bindful and bindless. + // + + // These are the constant base addresses/ranges for shaders. + // We have these hardcoded right now cause nothing seems to differ on the Xbox + // 360 (however, OpenGL ES on Adreno 200 on Android has different ranges). + assert_true(regs[XE_GPU_REG_SQ_VS_CONST] == 0x000FF000 || + regs[XE_GPU_REG_SQ_VS_CONST] == 0x00000000); + assert_true(regs[XE_GPU_REG_SQ_PS_CONST] == 0x000FF100 || + regs[XE_GPU_REG_SQ_PS_CONST] == 0x00000000); + // Check if the float constant layout is still the same and get the counts. + const Shader::ConstantRegisterMap& float_constant_map_vertex = + vertex_shader->constant_register_map(); + uint32_t float_constant_count_vertex = float_constant_map_vertex.float_count; + for (uint32_t i = 0; i < 4; ++i) { + if (current_float_constant_map_vertex_[i] != float_constant_map_vertex.float_bitmap[i]) { + current_float_constant_map_vertex_[i] = float_constant_map_vertex.float_bitmap[i]; + // If no float constants at all, we can reuse any buffer for them, so not + // invalidating. + if (float_constant_count_vertex) { + cbuffer_binding_float_vertex_.up_to_date = false; + } + } + } + uint32_t float_constant_count_pixel = 0; + if (pixel_shader != nullptr) { + const Shader::ConstantRegisterMap& float_constant_map_pixel = + pixel_shader->constant_register_map(); + float_constant_count_pixel = float_constant_map_pixel.float_count; + for (uint32_t i = 0; i < 4; ++i) { + if (current_float_constant_map_pixel_[i] != float_constant_map_pixel.float_bitmap[i]) { + current_float_constant_map_pixel_[i] = float_constant_map_pixel.float_bitmap[i]; + if (float_constant_count_pixel) { + cbuffer_binding_float_pixel_.up_to_date = false; + } + } + } + } else { + std::memset(current_float_constant_map_pixel_, 0, sizeof(current_float_constant_map_pixel_)); + } + + // Write the constant buffer data. + if (!cbuffer_binding_system_.up_to_date) { + uint8_t* system_constants = constant_buffer_pool_->Request( + frame_current_, sizeof(system_constants_), D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT, + nullptr, nullptr, &cbuffer_binding_system_.address); + if (system_constants == nullptr) { + return false; + } + std::memcpy(system_constants, &system_constants_, sizeof(system_constants_)); + cbuffer_binding_system_.up_to_date = true; + current_graphics_root_up_to_date_ &= ~(1u << root_parameter_system_constants); + } + if (!cbuffer_binding_float_vertex_.up_to_date) { + // Even if the shader doesn't need any float constants, a valid binding must + // still be provided, so if the first draw in the frame with the current + // root signature doesn't have float constants at all, still allocate an + // empty buffer. + uint8_t* float_constants = constant_buffer_pool_->Request( + frame_current_, sizeof(float) * 4 * std::max(float_constant_count_vertex, uint32_t(1)), + D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT, nullptr, nullptr, + &cbuffer_binding_float_vertex_.address); + if (float_constants == nullptr) { + return false; + } + for (uint32_t i = 0; i < 4; ++i) { + uint64_t float_constant_map_entry = float_constant_map_vertex.float_bitmap[i]; + uint32_t float_constant_index; + while (rex::bit_scan_forward(float_constant_map_entry, &float_constant_index)) { + float_constant_map_entry &= ~(1ull << float_constant_index); + std::memcpy( + float_constants, + ®s[XE_GPU_REG_SHADER_CONSTANT_000_X + (i << 8) + (float_constant_index << 2)], + 4 * sizeof(float)); + float_constants += 4 * sizeof(float); + } + } + cbuffer_binding_float_vertex_.up_to_date = true; + current_graphics_root_up_to_date_ &= ~(1u << root_parameter_float_constants_vertex); + } + if (!cbuffer_binding_float_pixel_.up_to_date) { + uint8_t* float_constants = constant_buffer_pool_->Request( + frame_current_, sizeof(float) * 4 * std::max(float_constant_count_pixel, uint32_t(1)), + D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT, nullptr, nullptr, + &cbuffer_binding_float_pixel_.address); + if (float_constants == nullptr) { + return false; + } + if (pixel_shader != nullptr) { + const Shader::ConstantRegisterMap& float_constant_map_pixel = + pixel_shader->constant_register_map(); + for (uint32_t i = 0; i < 4; ++i) { + uint64_t float_constant_map_entry = float_constant_map_pixel.float_bitmap[i]; + uint32_t float_constant_index; + while (rex::bit_scan_forward(float_constant_map_entry, &float_constant_index)) { + float_constant_map_entry &= ~(1ull << float_constant_index); + std::memcpy( + float_constants, + ®s[XE_GPU_REG_SHADER_CONSTANT_256_X + (i << 8) + (float_constant_index << 2)], + 4 * sizeof(float)); + float_constants += 4 * sizeof(float); + } + } + } + cbuffer_binding_float_pixel_.up_to_date = true; + current_graphics_root_up_to_date_ &= ~(1u << root_parameter_float_constants_pixel); + } + if (!cbuffer_binding_bool_loop_.up_to_date) { + constexpr uint32_t kBoolLoopConstantsSize = (8 + 32) * sizeof(uint32_t); + uint8_t* bool_loop_constants = constant_buffer_pool_->Request( + frame_current_, kBoolLoopConstantsSize, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT, + nullptr, nullptr, &cbuffer_binding_bool_loop_.address); + if (bool_loop_constants == nullptr) { + return false; + } + std::memcpy(bool_loop_constants, ®s[XE_GPU_REG_SHADER_CONSTANT_BOOL_000_031], + kBoolLoopConstantsSize); + cbuffer_binding_bool_loop_.up_to_date = true; + current_graphics_root_up_to_date_ &= ~(1u << root_parameter_bool_loop_constants); + } + if (!cbuffer_binding_fetch_.up_to_date) { + constexpr uint32_t kFetchConstantsSize = 32 * 6 * sizeof(uint32_t); + uint8_t* fetch_constants = constant_buffer_pool_->Request( + frame_current_, kFetchConstantsSize, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT, + nullptr, nullptr, &cbuffer_binding_fetch_.address); + if (fetch_constants == nullptr) { + return false; + } + std::memcpy(fetch_constants, ®s[XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0], kFetchConstantsSize); + cbuffer_binding_fetch_.up_to_date = true; + current_graphics_root_up_to_date_ &= ~(1u << root_parameter_fetch_constants); + } + + // + // Update descriptors. + // + + if (!current_shared_memory_binding_is_uav_.has_value() || + current_shared_memory_binding_is_uav_.value() != shared_memory_is_uav) { + current_shared_memory_binding_is_uav_ = shared_memory_is_uav; + current_graphics_root_up_to_date_ &= ~(1u << root_parameter_shared_memory_and_bindful_edram); + } + + // Get textures and samplers used by the vertex shader, check if the last used + // samplers are compatible and update them. + size_t texture_layout_uid_vertex = vertex_shader->GetTextureBindingLayoutUserUID(); + size_t sampler_layout_uid_vertex = vertex_shader->GetSamplerBindingLayoutUserUID(); + const std::vector& textures_vertex = + vertex_shader->GetTextureBindingsAfterTranslation(); + const std::vector& samplers_vertex = + vertex_shader->GetSamplerBindingsAfterTranslation(); + size_t texture_count_vertex = textures_vertex.size(); + size_t sampler_count_vertex = samplers_vertex.size(); + if (sampler_count_vertex) { + if (current_sampler_layout_uid_vertex_ != sampler_layout_uid_vertex) { + current_sampler_layout_uid_vertex_ = sampler_layout_uid_vertex; + cbuffer_binding_descriptor_indices_vertex_.up_to_date = false; + bindful_samplers_written_vertex_ = false; + } + current_samplers_vertex_.resize( + std::max(current_samplers_vertex_.size(), sampler_count_vertex)); + for (size_t i = 0; i < sampler_count_vertex; ++i) { + D3D12TextureCache::SamplerParameters parameters = + texture_cache_->GetSamplerParameters(samplers_vertex[i]); + if (current_samplers_vertex_[i] != parameters) { + cbuffer_binding_descriptor_indices_vertex_.up_to_date = false; + bindful_samplers_written_vertex_ = false; + current_samplers_vertex_[i] = parameters; + } + } + } + + // Get textures and samplers used by the pixel shader, check if the last used + // samplers are compatible and update them. + size_t texture_layout_uid_pixel, sampler_layout_uid_pixel; + const std::vector* textures_pixel; + const std::vector* samplers_pixel; + size_t texture_count_pixel, sampler_count_pixel; + if (pixel_shader != nullptr) { + texture_layout_uid_pixel = pixel_shader->GetTextureBindingLayoutUserUID(); + sampler_layout_uid_pixel = pixel_shader->GetSamplerBindingLayoutUserUID(); + textures_pixel = &pixel_shader->GetTextureBindingsAfterTranslation(); + texture_count_pixel = textures_pixel->size(); + samplers_pixel = &pixel_shader->GetSamplerBindingsAfterTranslation(); + sampler_count_pixel = samplers_pixel->size(); + if (sampler_count_pixel) { + if (current_sampler_layout_uid_pixel_ != sampler_layout_uid_pixel) { + current_sampler_layout_uid_pixel_ = sampler_layout_uid_pixel; + cbuffer_binding_descriptor_indices_pixel_.up_to_date = false; + bindful_samplers_written_pixel_ = false; + } + current_samplers_pixel_.resize( + std::max(current_samplers_pixel_.size(), size_t(sampler_count_pixel))); + for (uint32_t i = 0; i < sampler_count_pixel; ++i) { + D3D12TextureCache::SamplerParameters parameters = + texture_cache_->GetSamplerParameters((*samplers_pixel)[i]); + if (current_samplers_pixel_[i] != parameters) { + current_samplers_pixel_[i] = parameters; + cbuffer_binding_descriptor_indices_pixel_.up_to_date = false; + bindful_samplers_written_pixel_ = false; + } + } + } + } else { + texture_layout_uid_pixel = PipelineCache::kLayoutUIDEmpty; + sampler_layout_uid_pixel = PipelineCache::kLayoutUIDEmpty; + textures_pixel = nullptr; + texture_count_pixel = 0; + samplers_pixel = nullptr; + sampler_count_pixel = 0; + } + + assert_true(sampler_count_vertex + sampler_count_pixel <= kSamplerHeapSize); + + if (bindless_resources_used_) { + // + // Bindless descriptors path. + // + + // Check if need to write new descriptor indices. + // Samplers have already been checked. + if (texture_count_vertex && cbuffer_binding_descriptor_indices_vertex_.up_to_date && + (current_texture_layout_uid_vertex_ != texture_layout_uid_vertex || + !texture_cache_->AreActiveTextureSRVKeysUpToDate(current_texture_srv_keys_vertex_.data(), + textures_vertex.data(), + texture_count_vertex))) { + cbuffer_binding_descriptor_indices_vertex_.up_to_date = false; + } + if (texture_count_pixel && cbuffer_binding_descriptor_indices_pixel_.up_to_date && + (current_texture_layout_uid_pixel_ != texture_layout_uid_pixel || + !texture_cache_->AreActiveTextureSRVKeysUpToDate(current_texture_srv_keys_pixel_.data(), + textures_pixel->data(), + texture_count_pixel))) { + cbuffer_binding_descriptor_indices_pixel_.up_to_date = false; + } + + // Get sampler descriptor indices, write new samplers, and handle sampler + // heap overflow if it happens. + if ((sampler_count_vertex && !cbuffer_binding_descriptor_indices_vertex_.up_to_date) || + (sampler_count_pixel && !cbuffer_binding_descriptor_indices_pixel_.up_to_date)) { + for (uint32_t i = 0; i < 2; ++i) { + if (i) { + // Overflow happened - invalidate sampler bindings because their + // descriptor indices can't be used anymore (and even if heap creation + // fails, because current_sampler_bindless_indices_#_ are in an + // undefined state now) and switch to a new sampler heap. + cbuffer_binding_descriptor_indices_vertex_.up_to_date = false; + cbuffer_binding_descriptor_indices_pixel_.up_to_date = false; + ID3D12DescriptorHeap* sampler_heap_new; + if (!sampler_bindless_heaps_overflowed_.empty() && + sampler_bindless_heaps_overflowed_.front().second <= submission_completed_) { + sampler_heap_new = sampler_bindless_heaps_overflowed_.front().first; + sampler_bindless_heaps_overflowed_.pop_front(); + } else { + D3D12_DESCRIPTOR_HEAP_DESC sampler_heap_new_desc; + sampler_heap_new_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; + sampler_heap_new_desc.NumDescriptors = kSamplerHeapSize; + sampler_heap_new_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + sampler_heap_new_desc.NodeMask = 0; + if (FAILED(device->CreateDescriptorHeap(&sampler_heap_new_desc, + IID_PPV_ARGS(&sampler_heap_new)))) { + REXGPU_ERROR( + "Failed to create a new bindless sampler descriptor heap " + "after an overflow of the previous one"); + return false; + } + } + // Only change the heap if a new heap was created successfully, not to + // leave the values in an undefined state in case CreateDescriptorHeap + // has failed. + sampler_bindless_heaps_overflowed_.push_back( + std::make_pair(sampler_bindless_heap_current_, submission_current_)); + sampler_bindless_heap_current_ = sampler_heap_new; + sampler_bindless_heap_cpu_start_ = + sampler_bindless_heap_current_->GetCPUDescriptorHandleForHeapStart(); + sampler_bindless_heap_gpu_start_ = + sampler_bindless_heap_current_->GetGPUDescriptorHandleForHeapStart(); + sampler_bindless_heap_allocated_ = 0; + // The only thing the heap is used for now is texture cache samplers - + // invalidate all of them. + texture_cache_bindless_sampler_map_.clear(); + deferred_command_list_.SetDescriptorHeaps(view_bindless_heap_, + sampler_bindless_heap_current_); + current_graphics_root_up_to_date_ &= ~(1u << kRootParameter_Bindless_SamplerHeap); + } + bool samplers_overflowed = false; + if (sampler_count_vertex && !cbuffer_binding_descriptor_indices_vertex_.up_to_date) { + current_sampler_bindless_indices_vertex_.resize(std::max( + current_sampler_bindless_indices_vertex_.size(), size_t(sampler_count_vertex))); + for (uint32_t j = 0; j < sampler_count_vertex; ++j) { + D3D12TextureCache::SamplerParameters sampler_parameters = current_samplers_vertex_[j]; + uint32_t sampler_index; + auto it = texture_cache_bindless_sampler_map_.find(sampler_parameters.value); + if (it != texture_cache_bindless_sampler_map_.end()) { + sampler_index = it->second; + } else { + if (sampler_bindless_heap_allocated_ >= kSamplerHeapSize) { + samplers_overflowed = true; + break; + } + sampler_index = sampler_bindless_heap_allocated_++; + texture_cache_->WriteSampler(sampler_parameters, + provider.OffsetSamplerDescriptor( + sampler_bindless_heap_cpu_start_, sampler_index)); + texture_cache_bindless_sampler_map_.emplace(sampler_parameters.value, sampler_index); + } + current_sampler_bindless_indices_vertex_[j] = sampler_index; + } + } + if (samplers_overflowed) { + continue; + } + if (sampler_count_pixel && !cbuffer_binding_descriptor_indices_pixel_.up_to_date) { + current_sampler_bindless_indices_pixel_.resize(std::max( + current_sampler_bindless_indices_pixel_.size(), size_t(sampler_count_pixel))); + for (uint32_t j = 0; j < sampler_count_pixel; ++j) { + D3D12TextureCache::SamplerParameters sampler_parameters = current_samplers_pixel_[j]; + uint32_t sampler_index; + auto it = texture_cache_bindless_sampler_map_.find(sampler_parameters.value); + if (it != texture_cache_bindless_sampler_map_.end()) { + sampler_index = it->second; + } else { + if (sampler_bindless_heap_allocated_ >= kSamplerHeapSize) { + samplers_overflowed = true; + break; + } + sampler_index = sampler_bindless_heap_allocated_++; + texture_cache_->WriteSampler(sampler_parameters, + provider.OffsetSamplerDescriptor( + sampler_bindless_heap_cpu_start_, sampler_index)); + texture_cache_bindless_sampler_map_.emplace(sampler_parameters.value, sampler_index); + } + current_sampler_bindless_indices_pixel_[j] = sampler_index; + } + } + if (!samplers_overflowed) { + break; + } + } + } + + if (!cbuffer_binding_descriptor_indices_vertex_.up_to_date) { + uint32_t* descriptor_indices = reinterpret_cast(constant_buffer_pool_->Request( + frame_current_, + std::max(texture_count_vertex + sampler_count_vertex, size_t(1)) * sizeof(uint32_t), + D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT, nullptr, nullptr, + &cbuffer_binding_descriptor_indices_vertex_.address)); + if (!descriptor_indices) { + return false; + } + for (size_t i = 0; i < texture_count_vertex; ++i) { + const D3D12Shader::TextureBinding& texture = textures_vertex[i]; + descriptor_indices[texture.bindless_descriptor_index] = + texture_cache_->GetActiveTextureBindlessSRVIndex(texture) - + uint32_t(SystemBindlessView::kUnboundedSRVsStart); + } + current_texture_layout_uid_vertex_ = texture_layout_uid_vertex; + if (texture_count_vertex) { + current_texture_srv_keys_vertex_.resize( + std::max(current_texture_srv_keys_vertex_.size(), size_t(texture_count_vertex))); + texture_cache_->WriteActiveTextureSRVKeys(current_texture_srv_keys_vertex_.data(), + textures_vertex.data(), texture_count_vertex); + } + // Current samplers have already been updated. + for (size_t i = 0; i < sampler_count_vertex; ++i) { + descriptor_indices[samplers_vertex[i].bindless_descriptor_index] = + current_sampler_bindless_indices_vertex_[i]; + } + cbuffer_binding_descriptor_indices_vertex_.up_to_date = true; + current_graphics_root_up_to_date_ &= ~(1u << kRootParameter_Bindless_DescriptorIndicesVertex); + } + + if (!cbuffer_binding_descriptor_indices_pixel_.up_to_date) { + uint32_t* descriptor_indices = reinterpret_cast(constant_buffer_pool_->Request( + frame_current_, + std::max(texture_count_pixel + sampler_count_pixel, size_t(1)) * sizeof(uint32_t), + D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT, nullptr, nullptr, + &cbuffer_binding_descriptor_indices_pixel_.address)); + if (!descriptor_indices) { + return false; + } + for (size_t i = 0; i < texture_count_pixel; ++i) { + const D3D12Shader::TextureBinding& texture = (*textures_pixel)[i]; + descriptor_indices[texture.bindless_descriptor_index] = + texture_cache_->GetActiveTextureBindlessSRVIndex(texture) - + uint32_t(SystemBindlessView::kUnboundedSRVsStart); + } + current_texture_layout_uid_pixel_ = texture_layout_uid_pixel; + if (texture_count_pixel) { + current_texture_srv_keys_pixel_.resize( + std::max(current_texture_srv_keys_pixel_.size(), size_t(texture_count_pixel))); + texture_cache_->WriteActiveTextureSRVKeys(current_texture_srv_keys_pixel_.data(), + textures_pixel->data(), texture_count_pixel); + } + // Current samplers have already been updated. + for (size_t i = 0; i < sampler_count_pixel; ++i) { + descriptor_indices[(*samplers_pixel)[i].bindless_descriptor_index] = + current_sampler_bindless_indices_pixel_[i]; + } + cbuffer_binding_descriptor_indices_pixel_.up_to_date = true; + current_graphics_root_up_to_date_ &= ~(1u << kRootParameter_Bindless_DescriptorIndicesPixel); + } + } else { + // + // Bindful descriptors path. + // + + // See what descriptors need to be updated. + // Samplers have already been checked. + bool write_textures_vertex = + texture_count_vertex && (!bindful_textures_written_vertex_ || + current_texture_layout_uid_vertex_ != texture_layout_uid_vertex || + !texture_cache_->AreActiveTextureSRVKeysUpToDate( + current_texture_srv_keys_vertex_.data(), + textures_vertex.data(), texture_count_vertex)); + bool write_textures_pixel = + texture_count_pixel && + (!bindful_textures_written_pixel_ || + current_texture_layout_uid_pixel_ != texture_layout_uid_pixel || + !texture_cache_->AreActiveTextureSRVKeysUpToDate( + current_texture_srv_keys_pixel_.data(), textures_pixel->data(), texture_count_pixel)); + bool write_samplers_vertex = sampler_count_vertex && !bindful_samplers_written_vertex_; + bool write_samplers_pixel = sampler_count_pixel && !bindful_samplers_written_pixel_; + bool edram_rov_used = + render_target_cache_->GetPath() == RenderTargetCache::Path::kPixelShaderInterlock; + + // Allocate the descriptors. + size_t view_count_partial_update = 0; + if (write_textures_vertex) { + view_count_partial_update += texture_count_vertex; + } + if (write_textures_pixel) { + view_count_partial_update += texture_count_pixel; + } + // Shared memory SRV and null UAV + null SRV and shared memory UAV + + // textures. + size_t view_count_full_update = 4 + texture_count_vertex + texture_count_pixel; + if (edram_rov_used) { + // + EDRAM UAV in two tables (with the shared memory SRV and with the + // shared memory UAV). + view_count_full_update += 2; + } + D3D12_CPU_DESCRIPTOR_HANDLE view_cpu_handle; + D3D12_GPU_DESCRIPTOR_HANDLE view_gpu_handle; + uint32_t descriptor_size_view = provider.GetViewDescriptorSize(); + uint64_t view_heap_index = RequestViewBindfulDescriptors( + draw_view_bindful_heap_index_, uint32_t(view_count_partial_update), + uint32_t(view_count_full_update), view_cpu_handle, view_gpu_handle); + if (view_heap_index == ui::d3d12::D3D12DescriptorHeapPool::kHeapIndexInvalid) { + REXGPU_ERROR("Failed to allocate view descriptors"); + return false; + } + size_t sampler_count_partial_update = 0; + if (write_samplers_vertex) { + sampler_count_partial_update += sampler_count_vertex; + } + if (write_samplers_pixel) { + sampler_count_partial_update += sampler_count_pixel; + } + D3D12_CPU_DESCRIPTOR_HANDLE sampler_cpu_handle = {}; + D3D12_GPU_DESCRIPTOR_HANDLE sampler_gpu_handle = {}; + uint32_t descriptor_size_sampler = provider.GetSamplerDescriptorSize(); + uint64_t sampler_heap_index = ui::d3d12::D3D12DescriptorHeapPool::kHeapIndexInvalid; + if (sampler_count_vertex != 0 || sampler_count_pixel != 0) { + sampler_heap_index = RequestSamplerBindfulDescriptors( + draw_sampler_bindful_heap_index_, uint32_t(sampler_count_partial_update), + uint32_t(sampler_count_vertex + sampler_count_pixel), sampler_cpu_handle, + sampler_gpu_handle); + if (sampler_heap_index == ui::d3d12::D3D12DescriptorHeapPool::kHeapIndexInvalid) { + REXGPU_ERROR("Failed to allocate sampler descriptors"); + return false; + } + } + if (draw_view_bindful_heap_index_ != view_heap_index) { + // Need to update all view descriptors. + write_textures_vertex = texture_count_vertex != 0; + write_textures_pixel = texture_count_pixel != 0; + bindful_textures_written_vertex_ = false; + bindful_textures_written_pixel_ = false; + // If updating fully, write the shared memory SRV and UAV descriptors and, + // if needed, the EDRAM descriptor. + // SRV + null UAV + EDRAM. + gpu_handle_shared_memory_srv_and_edram_ = view_gpu_handle; + shared_memory_->WriteRawSRVDescriptor(view_cpu_handle); + view_cpu_handle.ptr += descriptor_size_view; + view_gpu_handle.ptr += descriptor_size_view; + ui::d3d12::util::CreateBufferRawUAV(device, view_cpu_handle, nullptr, 0); + view_cpu_handle.ptr += descriptor_size_view; + view_gpu_handle.ptr += descriptor_size_view; + if (edram_rov_used) { + render_target_cache_->WriteEdramUintPow2UAVDescriptor(view_cpu_handle, 2); + view_cpu_handle.ptr += descriptor_size_view; + view_gpu_handle.ptr += descriptor_size_view; + } + // Null SRV + UAV + EDRAM. + gpu_handle_shared_memory_uav_and_edram_ = view_gpu_handle; + ui::d3d12::util::CreateBufferRawSRV(device, view_cpu_handle, nullptr, 0); + view_cpu_handle.ptr += descriptor_size_view; + view_gpu_handle.ptr += descriptor_size_view; + shared_memory_->WriteRawUAVDescriptor(view_cpu_handle); + view_cpu_handle.ptr += descriptor_size_view; + view_gpu_handle.ptr += descriptor_size_view; + if (edram_rov_used) { + render_target_cache_->WriteEdramUintPow2UAVDescriptor(view_cpu_handle, 2); + view_cpu_handle.ptr += descriptor_size_view; + view_gpu_handle.ptr += descriptor_size_view; + } + current_graphics_root_up_to_date_ &= ~(1u << kRootParameter_Bindful_SharedMemoryAndEdram); + } + if (sampler_heap_index != ui::d3d12::D3D12DescriptorHeapPool::kHeapIndexInvalid && + draw_sampler_bindful_heap_index_ != sampler_heap_index) { + write_samplers_vertex = sampler_count_vertex != 0; + write_samplers_pixel = sampler_count_pixel != 0; + bindful_samplers_written_vertex_ = false; + bindful_samplers_written_pixel_ = false; + } + + // Write the descriptors. + if (write_textures_vertex) { + assert_true(current_graphics_root_bindful_extras_.textures_vertex != + RootBindfulExtraParameterIndices::kUnavailable); + gpu_handle_textures_vertex_ = view_gpu_handle; + for (size_t i = 0; i < texture_count_vertex; ++i) { + texture_cache_->WriteActiveTextureBindfulSRV(textures_vertex[i], view_cpu_handle); + view_cpu_handle.ptr += descriptor_size_view; + view_gpu_handle.ptr += descriptor_size_view; + } + current_texture_layout_uid_vertex_ = texture_layout_uid_vertex; + current_texture_srv_keys_vertex_.resize( + std::max(current_texture_srv_keys_vertex_.size(), size_t(texture_count_vertex))); + texture_cache_->WriteActiveTextureSRVKeys(current_texture_srv_keys_vertex_.data(), + textures_vertex.data(), texture_count_vertex); + bindful_textures_written_vertex_ = true; + current_graphics_root_up_to_date_ &= + ~(1u << current_graphics_root_bindful_extras_.textures_vertex); + } + if (write_textures_pixel) { + assert_true(current_graphics_root_bindful_extras_.textures_pixel != + RootBindfulExtraParameterIndices::kUnavailable); + gpu_handle_textures_pixel_ = view_gpu_handle; + for (size_t i = 0; i < texture_count_pixel; ++i) { + texture_cache_->WriteActiveTextureBindfulSRV((*textures_pixel)[i], view_cpu_handle); + view_cpu_handle.ptr += descriptor_size_view; + view_gpu_handle.ptr += descriptor_size_view; + } + current_texture_layout_uid_pixel_ = texture_layout_uid_pixel; + current_texture_srv_keys_pixel_.resize( + std::max(current_texture_srv_keys_pixel_.size(), size_t(texture_count_pixel))); + texture_cache_->WriteActiveTextureSRVKeys(current_texture_srv_keys_pixel_.data(), + textures_pixel->data(), texture_count_pixel); + bindful_textures_written_pixel_ = true; + current_graphics_root_up_to_date_ &= + ~(1u << current_graphics_root_bindful_extras_.textures_pixel); + } + if (write_samplers_vertex) { + assert_true(current_graphics_root_bindful_extras_.samplers_vertex != + RootBindfulExtraParameterIndices::kUnavailable); + gpu_handle_samplers_vertex_ = sampler_gpu_handle; + for (size_t i = 0; i < sampler_count_vertex; ++i) { + texture_cache_->WriteSampler(current_samplers_vertex_[i], sampler_cpu_handle); + sampler_cpu_handle.ptr += descriptor_size_sampler; + sampler_gpu_handle.ptr += descriptor_size_sampler; + } + // Current samplers have already been updated. + bindful_samplers_written_vertex_ = true; + current_graphics_root_up_to_date_ &= + ~(1u << current_graphics_root_bindful_extras_.samplers_vertex); + } + if (write_samplers_pixel) { + assert_true(current_graphics_root_bindful_extras_.samplers_pixel != + RootBindfulExtraParameterIndices::kUnavailable); + gpu_handle_samplers_pixel_ = sampler_gpu_handle; + for (size_t i = 0; i < sampler_count_pixel; ++i) { + texture_cache_->WriteSampler(current_samplers_pixel_[i], sampler_cpu_handle); + sampler_cpu_handle.ptr += descriptor_size_sampler; + sampler_gpu_handle.ptr += descriptor_size_sampler; + } + // Current samplers have already been updated. + bindful_samplers_written_pixel_ = true; + current_graphics_root_up_to_date_ &= + ~(1u << current_graphics_root_bindful_extras_.samplers_pixel); + } + + // Wrote new descriptors on the current page. + draw_view_bindful_heap_index_ = view_heap_index; + if (sampler_heap_index != ui::d3d12::D3D12DescriptorHeapPool::kHeapIndexInvalid) { + draw_sampler_bindful_heap_index_ = sampler_heap_index; + } + } + + // Update the root parameters. + if (!(current_graphics_root_up_to_date_ & (1u << root_parameter_fetch_constants))) { + deferred_command_list_.D3DSetGraphicsRootConstantBufferView(root_parameter_fetch_constants, + cbuffer_binding_fetch_.address); + current_graphics_root_up_to_date_ |= 1u << root_parameter_fetch_constants; + } + if (!(current_graphics_root_up_to_date_ & (1u << root_parameter_float_constants_vertex))) { + deferred_command_list_.D3DSetGraphicsRootConstantBufferView( + root_parameter_float_constants_vertex, cbuffer_binding_float_vertex_.address); + current_graphics_root_up_to_date_ |= 1u << root_parameter_float_constants_vertex; + } + if (!(current_graphics_root_up_to_date_ & (1u << root_parameter_float_constants_pixel))) { + deferred_command_list_.D3DSetGraphicsRootConstantBufferView( + root_parameter_float_constants_pixel, cbuffer_binding_float_pixel_.address); + current_graphics_root_up_to_date_ |= 1u << root_parameter_float_constants_pixel; + } + if (!(current_graphics_root_up_to_date_ & (1u << root_parameter_system_constants))) { + deferred_command_list_.D3DSetGraphicsRootConstantBufferView(root_parameter_system_constants, + cbuffer_binding_system_.address); + current_graphics_root_up_to_date_ |= 1u << root_parameter_system_constants; + } + if (!(current_graphics_root_up_to_date_ & (1u << root_parameter_bool_loop_constants))) { + deferred_command_list_.D3DSetGraphicsRootConstantBufferView(root_parameter_bool_loop_constants, + cbuffer_binding_bool_loop_.address); + current_graphics_root_up_to_date_ |= 1u << root_parameter_bool_loop_constants; + } + if (!(current_graphics_root_up_to_date_ & + (1u << root_parameter_shared_memory_and_bindful_edram))) { + assert_true(current_shared_memory_binding_is_uav_.has_value()); + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle_shared_memory_and_bindful_edram; + if (bindless_resources_used_) { + gpu_handle_shared_memory_and_bindful_edram = provider.OffsetViewDescriptor( + view_bindless_heap_gpu_start_, + uint32_t(current_shared_memory_binding_is_uav_.value() + ? SystemBindlessView ::kNullRawSRVAndSharedMemoryRawUAVStart + : SystemBindlessView ::kSharedMemoryRawSRVAndNullRawUAVStart)); + } else { + gpu_handle_shared_memory_and_bindful_edram = current_shared_memory_binding_is_uav_.value() + ? gpu_handle_shared_memory_uav_and_edram_ + : gpu_handle_shared_memory_srv_and_edram_; + } + deferred_command_list_.D3DSetGraphicsRootDescriptorTable( + root_parameter_shared_memory_and_bindful_edram, gpu_handle_shared_memory_and_bindful_edram); + current_graphics_root_up_to_date_ |= 1u << root_parameter_shared_memory_and_bindful_edram; + } + if (bindless_resources_used_) { + if (!(current_graphics_root_up_to_date_ & + (1u << kRootParameter_Bindless_DescriptorIndicesPixel))) { + deferred_command_list_.D3DSetGraphicsRootConstantBufferView( + kRootParameter_Bindless_DescriptorIndicesPixel, + cbuffer_binding_descriptor_indices_pixel_.address); + current_graphics_root_up_to_date_ |= 1u << kRootParameter_Bindless_DescriptorIndicesPixel; + } + if (!(current_graphics_root_up_to_date_ & + (1u << kRootParameter_Bindless_DescriptorIndicesVertex))) { + deferred_command_list_.D3DSetGraphicsRootConstantBufferView( + kRootParameter_Bindless_DescriptorIndicesVertex, + cbuffer_binding_descriptor_indices_vertex_.address); + current_graphics_root_up_to_date_ |= 1u << kRootParameter_Bindless_DescriptorIndicesVertex; + } + if (!(current_graphics_root_up_to_date_ & (1u << kRootParameter_Bindless_SamplerHeap))) { + deferred_command_list_.D3DSetGraphicsRootDescriptorTable(kRootParameter_Bindless_SamplerHeap, + sampler_bindless_heap_gpu_start_); + current_graphics_root_up_to_date_ |= 1u << kRootParameter_Bindless_SamplerHeap; + } + if (!(current_graphics_root_up_to_date_ & (1u << kRootParameter_Bindless_ViewHeap))) { + deferred_command_list_.D3DSetGraphicsRootDescriptorTable(kRootParameter_Bindless_ViewHeap, + view_bindless_heap_gpu_start_); + current_graphics_root_up_to_date_ |= 1u << kRootParameter_Bindless_ViewHeap; + } + } else { + uint32_t extra_index; + extra_index = current_graphics_root_bindful_extras_.textures_pixel; + if (extra_index != RootBindfulExtraParameterIndices::kUnavailable && + !(current_graphics_root_up_to_date_ & (1u << extra_index))) { + deferred_command_list_.D3DSetGraphicsRootDescriptorTable(extra_index, + gpu_handle_textures_pixel_); + current_graphics_root_up_to_date_ |= 1u << extra_index; + } + extra_index = current_graphics_root_bindful_extras_.samplers_pixel; + if (extra_index != RootBindfulExtraParameterIndices::kUnavailable && + !(current_graphics_root_up_to_date_ & (1u << extra_index))) { + deferred_command_list_.D3DSetGraphicsRootDescriptorTable(extra_index, + gpu_handle_samplers_pixel_); + current_graphics_root_up_to_date_ |= 1u << extra_index; + } + extra_index = current_graphics_root_bindful_extras_.textures_vertex; + if (extra_index != RootBindfulExtraParameterIndices::kUnavailable && + !(current_graphics_root_up_to_date_ & (1u << extra_index))) { + deferred_command_list_.D3DSetGraphicsRootDescriptorTable(extra_index, + gpu_handle_textures_vertex_); + current_graphics_root_up_to_date_ |= 1u << extra_index; + } + extra_index = current_graphics_root_bindful_extras_.samplers_vertex; + if (extra_index != RootBindfulExtraParameterIndices::kUnavailable && + !(current_graphics_root_up_to_date_ & (1u << extra_index))) { + deferred_command_list_.D3DSetGraphicsRootDescriptorTable(extra_index, + gpu_handle_samplers_vertex_); + current_graphics_root_up_to_date_ |= 1u << extra_index; + } + } + + return true; +} + +void D3D12CommandProcessor::EvictOldReadbackBuffers( + std::unordered_map& buffer_map) { + if (buffer_map.empty()) { + return; + } + const uint64_t eviction_frame_floor = (frame_current_ > kReadbackBufferEvictionAgeFrames) + ? (frame_current_ - kReadbackBufferEvictionAgeFrames) + : 0; + for (auto it = buffer_map.begin(); it != buffer_map.end();) { + ReadbackBuffer& readback = it->second; + bool evict = + buffer_map.size() > kMaxReadbackBuffers || readback.last_used_frame < eviction_frame_floor; + if (!evict) { + ++it; + continue; + } + for (uint32_t i = 0; i < 2; ++i) { + if (readback.buffers[i]) { + if (readback.mapped_data[i]) { + readback.buffers[i]->Unmap(0, nullptr); + } + readback.buffers[i]->Release(); + } + readback.buffers[i] = nullptr; + readback.mapped_data[i] = nullptr; + readback.sizes[i] = 0; + readback.submission_written[i] = 0; + readback.written_size[i] = 0; + } + it = buffer_map.erase(it); + } +} + +ID3D12Resource* D3D12CommandProcessor::RequestReadbackBuffer(uint32_t size) { + if (size == 0) { + return nullptr; + } + size = rex::align(size, kReadbackBufferSizeIncrement); + if (size > readback_buffer_size_) { + const ui::d3d12::D3D12Provider& provider = GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + D3D12_RESOURCE_DESC buffer_desc; + ui::d3d12::util::FillBufferResourceDesc(buffer_desc, size, D3D12_RESOURCE_FLAG_NONE); + ID3D12Resource* buffer; + if (FAILED(device->CreateCommittedResource( + &ui::d3d12::util::kHeapPropertiesReadback, provider.GetHeapFlagCreateNotZeroed(), + &buffer_desc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&buffer)))) { + REXGPU_ERROR("Failed to create a {} MB readback buffer", size >> 20); + return nullptr; + } + if (readback_buffer_ != nullptr) { + readback_buffer_->Release(); + } + readback_buffer_ = buffer; + readback_buffer_size_ = size; + } + return readback_buffer_; +} + +bool D3D12CommandProcessor::InitializeOcclusionQueryResources() { + active_occlusion_query_ = {}; + occlusion_query_cursor_ = 0; + occlusion_query_resources_available_ = false; + occlusion_query_heap_.Reset(); + occlusion_query_readback_.Reset(); + occlusion_query_readback_mapping_ = nullptr; + + ID3D12Device* device = GetD3D12Provider().GetDevice(); + if (!device) { + return false; + } + + D3D12_QUERY_HEAP_DESC heap_desc; + heap_desc.Type = D3D12_QUERY_HEAP_TYPE_OCCLUSION; + heap_desc.Count = kMaxOcclusionQueries; + heap_desc.NodeMask = 0; + if (FAILED(device->CreateQueryHeap(&heap_desc, IID_PPV_ARGS(&occlusion_query_heap_)))) { + REXGPU_WARN( + "D3D12CommandProcessor: Failed to create occlusion query heap, using fake sample counts"); + return false; + } + + D3D12_RESOURCE_DESC buffer_desc; + ui::d3d12::util::FillBufferResourceDesc(buffer_desc, sizeof(uint64_t) * kMaxOcclusionQueries, + D3D12_RESOURCE_FLAG_NONE); + if (FAILED(device->CreateCommittedResource(&ui::d3d12::util::kHeapPropertiesReadback, + GetD3D12Provider().GetHeapFlagCreateNotZeroed(), + &buffer_desc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, + IID_PPV_ARGS(&occlusion_query_readback_)))) { + REXGPU_WARN( + "D3D12CommandProcessor: Failed to allocate occlusion query readback buffer, using fake " + "sample counts"); + occlusion_query_heap_.Reset(); + return false; + } + + D3D12_RANGE read_range = {0, sizeof(uint64_t) * kMaxOcclusionQueries}; + void* mapping = nullptr; + if (FAILED(occlusion_query_readback_->Map(0, &read_range, &mapping))) { + REXGPU_WARN( + "D3D12CommandProcessor: Failed to map occlusion query readback buffer, using fake sample " + "counts"); + occlusion_query_readback_.Reset(); + occlusion_query_heap_.Reset(); + return false; + } + + occlusion_query_readback_mapping_ = reinterpret_cast(mapping); + occlusion_query_resources_available_ = true; + return true; +} + +void D3D12CommandProcessor::ShutdownOcclusionQueryResources() { + DisableHostOcclusionQueries(); + + if (occlusion_query_readback_ && occlusion_query_readback_mapping_) { + occlusion_query_readback_->Unmap(0, nullptr); + } + occlusion_query_readback_mapping_ = nullptr; + occlusion_query_readback_.Reset(); + occlusion_query_heap_.Reset(); +} + +bool D3D12CommandProcessor::AcquireOcclusionQueryIndex(uint32_t& host_index_out) { + if (occlusion_query_cursor_ >= kMaxOcclusionQueries) { + occlusion_query_cursor_ = 0; + } + host_index_out = occlusion_query_cursor_++; + return true; +} + +void D3D12CommandProcessor::DisableHostOcclusionQueries() { + if (active_occlusion_query_.valid && occlusion_query_heap_) { + uint32_t host_index = active_occlusion_query_.host_index; + // Clear before EndSubmission to prevent the EndSubmission safety net from issuing a second + // EndQuery for the same index. + active_occlusion_query_ = {}; + if (BeginSubmission(true)) { + deferred_command_list_.D3DEndQuery(occlusion_query_heap_.Get(), D3D12_QUERY_TYPE_OCCLUSION, + host_index); + EndSubmission(false); + } + } else { + active_occlusion_query_ = {}; + } + occlusion_query_cursor_ = 0; + occlusion_query_resources_available_ = false; +} + +bool D3D12CommandProcessor::BeginGuestOcclusionQuery(uint32_t sample_count_address) { + if (!REXCVAR_GET(occlusion_query_enable) || !occlusion_query_resources_available_) { + return false; + } + if (active_occlusion_query_.valid) { + REXGPU_WARN( + "D3D12CommandProcessor: Occlusion query begin issued while another query is active"); + DisableHostOcclusionQueries(); + return false; + } + + uint32_t host_index = 0; + if (!AcquireOcclusionQueryIndex(host_index)) { + return false; + } + if (!BeginSubmission(true)) { + return false; + } + + deferred_command_list_.D3DBeginQuery(occlusion_query_heap_.Get(), D3D12_QUERY_TYPE_OCCLUSION, + host_index); + active_occlusion_query_.sample_count_address = sample_count_address; + active_occlusion_query_.host_index = host_index; + active_occlusion_query_.valid = true; + return true; +} + +bool D3D12CommandProcessor::EndGuestOcclusionQuery( + uint32_t sample_count_address, xenos::xe_gpu_depth_sample_counts* sample_counts) { + if (!REXCVAR_GET(occlusion_query_enable) || !occlusion_query_resources_available_ || + !active_occlusion_query_.valid || !occlusion_query_heap_ || !occlusion_query_readback_) { + return false; + } + + uint32_t host_index = active_occlusion_query_.host_index; + active_occlusion_query_ = {}; + + if (!BeginSubmission(true)) { + return false; + } + + deferred_command_list_.D3DEndQuery(occlusion_query_heap_.Get(), D3D12_QUERY_TYPE_OCCLUSION, + host_index); + deferred_command_list_.D3DResolveQueryData( + occlusion_query_heap_.Get(), D3D12_QUERY_TYPE_OCCLUSION, host_index, 1, + occlusion_query_readback_.Get(), sizeof(uint64_t) * host_index); + + if (!EndSubmission(false)) { + return false; + } + + uint64_t query_submission = submission_current_ ? submission_current_ - 1 : 0; + CheckSubmissionFence(query_submission); + if (submission_completed_ < query_submission) { + return false; + } + if (!occlusion_query_readback_mapping_) { + return false; + } + + uint64_t samples = occlusion_query_readback_mapping_[host_index]; + samples = NormalizeOcclusionSamples(samples); + WriteGuestOcclusionResult(sample_counts, samples); + return true; +} + +uint64_t D3D12CommandProcessor::NormalizeOcclusionSamples(uint64_t samples) const { + if (samples == 0 || !texture_cache_) { + return samples; + } + uint64_t scale_x = texture_cache_->draw_resolution_scale_x(); + uint64_t scale_y = texture_cache_->draw_resolution_scale_y(); + uint64_t scale = scale_x * scale_y; + if (scale <= 1) { + return samples; + } + return (samples + (scale >> 1)) / scale; +} + +void D3D12CommandProcessor::WriteGuestOcclusionResult( + xenos::xe_gpu_depth_sample_counts* sample_counts, uint64_t samples) { + if (!sample_counts) { + return; + } + uint32_t clamped = samples > uint64_t(UINT32_MAX) ? UINT32_MAX : uint32_t(samples); + sample_counts->Total_A = clamped; + sample_counts->Total_B = 0; + sample_counts->ZPass_A = clamped; + sample_counts->ZPass_B = 0; + sample_counts->ZFail_A = 0; + sample_counts->ZFail_B = 0; + sample_counts->StencilFail_A = 0; + sample_counts->StencilFail_B = 0; +} + +void D3D12CommandProcessor::WriteGammaRampSRV(bool is_pwl, + D3D12_CPU_DESCRIPTOR_HANDLE handle) const { + ID3D12Device* device = GetD3D12Provider().GetDevice(); + D3D12_SHADER_RESOURCE_VIEW_DESC desc; + desc.Format = DXGI_FORMAT_R10G10B10A2_UNORM; + desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; + desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + desc.Buffer.StructureByteStride = 0; + desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE; + if (is_pwl) { + desc.Format = DXGI_FORMAT_R16G16_UINT; + desc.Buffer.FirstElement = 256 * 4 / 4; + desc.Buffer.NumElements = 128 * 3; + } else { + desc.Format = DXGI_FORMAT_R10G10B10A2_UNORM; + desc.Buffer.FirstElement = 0; + desc.Buffer.NumElements = 256; + } + device->CreateShaderResourceView(gamma_ramp_buffer_.Get(), &desc, handle); +} + +} // namespace rex::graphics::d3d12 diff --git a/src/graphics/d3d12/deferred_command_list.cpp b/src/graphics/d3d12/deferred_command_list.cpp new file mode 100644 index 0000000..e6d6277 --- /dev/null +++ b/src/graphics/d3d12/deferred_command_list.cpp @@ -0,0 +1,291 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2019 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include + +namespace rex::graphics::d3d12 { + +DeferredCommandList::DeferredCommandList(const D3D12CommandProcessor& command_processor, + size_t initial_size) + : command_processor_(command_processor) { + command_stream_.reserve(initial_size / sizeof(uintmax_t)); +} + +void DeferredCommandList::Reset() { + command_stream_.clear(); +} + +void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list, + ID3D12GraphicsCommandList1* command_list_1) { +#if XE_GPU_FINE_GRAINED_DRAW_SCOPES + SCOPE_profile_cpu_f("gpu"); +#endif // XE_GPU_FINE_GRAINED_DRAW_SCOPES + const uintmax_t* stream = command_stream_.data(); + size_t stream_remaining = command_stream_.size(); + ID3D12PipelineState* current_pipeline_state = nullptr; + while (stream_remaining != 0) { + const CommandHeader& header = *reinterpret_cast(stream); + stream += kCommandHeaderSizeElements; + stream_remaining -= kCommandHeaderSizeElements; + switch (header.command) { + case Command::kD3DClearDepthStencilView: { + auto& args = *reinterpret_cast(stream); + command_list->ClearDepthStencilView( + args.depth_stencil_view, args.clear_flags, args.depth, args.stencil, args.num_rects, + args.num_rects ? reinterpret_cast(&args + 1) : nullptr); + } break; + case Command::kD3DClearRenderTargetView: { + auto& args = *reinterpret_cast(stream); + command_list->ClearRenderTargetView( + args.render_target_view, args.color_rgba, args.num_rects, + args.num_rects ? reinterpret_cast(&args + 1) : nullptr); + } break; + case Command::kD3DClearUnorderedAccessViewUint: { + auto& args = *reinterpret_cast(stream); + command_list->ClearUnorderedAccessViewUint( + args.view_gpu_handle_in_current_heap, args.view_cpu_handle, args.resource, + args.values_uint, args.num_rects, + args.num_rects ? reinterpret_cast(&args + 1) : nullptr); + } break; + case Command::kD3DCopyBufferRegion: { + auto& args = *reinterpret_cast(stream); + command_list->CopyBufferRegion(args.dst_buffer, args.dst_offset, args.src_buffer, + args.src_offset, args.num_bytes); + } break; + case Command::kD3DCopyResource: { + auto& args = *reinterpret_cast(stream); + command_list->CopyResource(args.dst_resource, args.src_resource); + } break; + case Command::kCopyTexture: { + auto& args = *reinterpret_cast(stream); + command_list->CopyTextureRegion(&args.dst, 0, 0, 0, &args.src, nullptr); + } break; + case Command::kD3DCopyTextureRegion: { + auto& args = *reinterpret_cast(stream); + command_list->CopyTextureRegion(&args.dst, args.dst_x, args.dst_y, args.dst_z, &args.src, + args.has_src_box ? &args.src_box : nullptr); + } break; + case Command::kD3DDispatch: { + if (current_pipeline_state != nullptr) { + auto& args = *reinterpret_cast(stream); + command_list->Dispatch(args.thread_group_count_x, args.thread_group_count_y, + args.thread_group_count_z); + } + } break; + case Command::kD3DDrawIndexedInstanced: { + if (current_pipeline_state != nullptr) { + auto& args = *reinterpret_cast(stream); + command_list->DrawIndexedInstanced(args.index_count_per_instance, args.instance_count, + args.start_index_location, args.base_vertex_location, + args.start_instance_location); + } + } break; + case Command::kD3DDrawInstanced: { + if (current_pipeline_state != nullptr) { + auto& args = *reinterpret_cast(stream); + command_list->DrawInstanced(args.vertex_count_per_instance, args.instance_count, + args.start_vertex_location, args.start_instance_location); + } + } break; + case Command::kD3DBeginQuery: { + auto& args = *reinterpret_cast(stream); + command_list->BeginQuery(args.query_heap, args.type, args.index); + } break; + case Command::kD3DEndQuery: { + auto& args = *reinterpret_cast(stream); + command_list->EndQuery(args.query_heap, args.type, args.index); + } break; + case Command::kD3DResolveQueryData: { + auto& args = *reinterpret_cast(stream); + command_list->ResolveQueryData(args.query_heap, args.type, args.start_index, + args.num_queries, args.destination_buffer, + args.aligned_destination_buffer_offset); + } break; + case Command::kD3DIASetIndexBuffer: { + auto view = reinterpret_cast(stream); + command_list->IASetIndexBuffer(view->Format != DXGI_FORMAT_UNKNOWN ? view : nullptr); + } break; + case Command::kD3DIASetPrimitiveTopology: { + command_list->IASetPrimitiveTopology( + *reinterpret_cast(stream)); + } break; + case Command::kD3DIASetVertexBuffers: { + static_assert(alignof(D3D12_VERTEX_BUFFER_VIEW) <= alignof(uintmax_t)); + auto& args = *reinterpret_cast(stream); + command_list->IASetVertexBuffers(args.start_slot, args.num_views, + reinterpret_cast( + reinterpret_cast(stream) + + rex::align(sizeof(D3DIASetVertexBuffersHeader), + alignof(D3D12_VERTEX_BUFFER_VIEW)))); + } break; + case Command::kD3DOMSetBlendFactor: { + command_list->OMSetBlendFactor(reinterpret_cast(stream)); + } break; + case Command::kD3DOMSetRenderTargets: { + auto& args = *reinterpret_cast(stream); + command_list->OMSetRenderTargets( + args.num_render_target_descriptors, args.render_target_descriptors, + args.rts_single_handle_to_descriptor_range ? TRUE : FALSE, + args.depth_stencil ? &args.depth_stencil_descriptor : nullptr); + } break; + case Command::kD3DOMSetStencilRef: { + command_list->OMSetStencilRef(*reinterpret_cast(stream)); + } break; + case Command::kD3DResourceBarrier: { + static_assert(alignof(D3D12_RESOURCE_BARRIER) <= alignof(uintmax_t)); + command_list->ResourceBarrier( + *reinterpret_cast(stream), + reinterpret_cast( + reinterpret_cast(stream) + + rex::align(sizeof(UINT), alignof(D3D12_RESOURCE_BARRIER)))); + } break; + case Command::kRSSetScissorRect: { + command_list->RSSetScissorRects(1, reinterpret_cast(stream)); + } break; + case Command::kRSSetViewport: { + command_list->RSSetViewports(1, reinterpret_cast(stream)); + } break; + case Command::kD3DSetComputeRoot32BitConstants: { + auto args = reinterpret_cast(stream); + command_list->SetComputeRoot32BitConstants(args->root_parameter_index, + args->num_32bit_values_to_set, args + 1, + args->dest_offset_in_32bit_values); + } break; + case Command::kD3DSetGraphicsRoot32BitConstants: { + auto args = reinterpret_cast(stream); + command_list->SetGraphicsRoot32BitConstants(args->root_parameter_index, + args->num_32bit_values_to_set, args + 1, + args->dest_offset_in_32bit_values); + } break; + case Command::kD3DSetComputeRootConstantBufferView: { + auto& args = *reinterpret_cast(stream); + command_list->SetComputeRootConstantBufferView(args.root_parameter_index, + args.buffer_location); + } break; + case Command::kD3DSetGraphicsRootConstantBufferView: { + auto& args = *reinterpret_cast(stream); + command_list->SetGraphicsRootConstantBufferView(args.root_parameter_index, + args.buffer_location); + } break; + case Command::kD3DSetComputeRootDescriptorTable: { + auto& args = *reinterpret_cast(stream); + command_list->SetComputeRootDescriptorTable(args.root_parameter_index, + args.base_descriptor); + } break; + case Command::kD3DSetGraphicsRootDescriptorTable: { + auto& args = *reinterpret_cast(stream); + command_list->SetGraphicsRootDescriptorTable(args.root_parameter_index, + args.base_descriptor); + } break; + case Command::kD3DSetComputeRootShaderResourceView: { + auto& args = *reinterpret_cast(stream); + command_list->SetComputeRootShaderResourceView(args.root_parameter_index, + args.buffer_location); + } break; + case Command::kD3DSetGraphicsRootShaderResourceView: { + auto& args = *reinterpret_cast(stream); + command_list->SetGraphicsRootShaderResourceView(args.root_parameter_index, + args.buffer_location); + } break; + case Command::kD3DSetComputeRootSignature: { + command_list->SetComputeRootSignature( + *reinterpret_cast(stream)); + } break; + case Command::kD3DSetGraphicsRootSignature: { + command_list->SetGraphicsRootSignature( + *reinterpret_cast(stream)); + } break; + case Command::kD3DSetComputeRootUnorderedAccessView: { + auto& args = *reinterpret_cast(stream); + command_list->SetComputeRootUnorderedAccessView(args.root_parameter_index, + args.buffer_location); + } break; + case Command::kD3DSetGraphicsRootUnorderedAccessView: { + auto& args = *reinterpret_cast(stream); + command_list->SetGraphicsRootUnorderedAccessView(args.root_parameter_index, + args.buffer_location); + } break; + case Command::kSetDescriptorHeaps: { + auto& args = *reinterpret_cast(stream); + UINT num_descriptor_heaps = 0; + ID3D12DescriptorHeap* descriptor_heaps[2]; + if (args.cbv_srv_uav_descriptor_heap != nullptr) { + descriptor_heaps[num_descriptor_heaps++] = args.cbv_srv_uav_descriptor_heap; + } + if (args.sampler_descriptor_heap != nullptr) { + descriptor_heaps[num_descriptor_heaps++] = args.sampler_descriptor_heap; + } + command_list->SetDescriptorHeaps(num_descriptor_heaps, descriptor_heaps); + } break; + case Command::kD3DSetPipelineState: { + current_pipeline_state = *reinterpret_cast(stream); + if (current_pipeline_state) { + command_list->SetPipelineState(current_pipeline_state); + } + } break; + case Command::kSetPipelineStateHandle: { + current_pipeline_state = + command_processor_.GetD3D12PipelineByHandle(*reinterpret_cast(stream)); + if (current_pipeline_state) { + command_list->SetPipelineState(current_pipeline_state); + } + } break; + case Command::kD3DSetSamplePositions: { + if (command_list_1 != nullptr) { + auto& args = *reinterpret_cast(stream); + command_list_1->SetSamplePositions( + args.num_samples_per_pixel, args.num_pixels, + (args.num_samples_per_pixel && args.num_pixels) + ? const_cast(args.sample_positions) + : nullptr); + } + } break; + case Command::kBeginDebugMarker: { + auto& args = *reinterpret_cast(stream); + const char* label_name = reinterpret_cast( + reinterpret_cast(stream) + sizeof(DebugMarkerHeader)); + command_list->BeginEvent(1, label_name, static_cast(args.label_length + 1)); + } break; + case Command::kEndDebugMarker: { + command_list->EndEvent(); + } break; + case Command::kInsertDebugMarker: { + auto& args = *reinterpret_cast(stream); + const char* label_name = reinterpret_cast( + reinterpret_cast(stream) + sizeof(DebugMarkerHeader)); + command_list->SetMarker(1, label_name, static_cast(args.label_length + 1)); + } break; + default: + assert_unhandled_case(header.command); + break; + } + stream += header.arguments_size_elements; + stream_remaining -= header.arguments_size_elements; + } +} + +void* DeferredCommandList::WriteCommand(Command command, size_t arguments_size_bytes) { + size_t arguments_size_elements = + (arguments_size_bytes + sizeof(uintmax_t) - 1) / sizeof(uintmax_t); + size_t offset = command_stream_.size(); + command_stream_.resize(offset + kCommandHeaderSizeElements + arguments_size_elements); + CommandHeader& header = *reinterpret_cast(command_stream_.data() + offset); + header.command = command; + header.arguments_size_elements = uint32_t(arguments_size_elements); + return command_stream_.data() + (offset + kCommandHeaderSizeElements); +} + +} // namespace rex::graphics::d3d12 diff --git a/src/graphics/d3d12/graphics_system.cpp b/src/graphics/d3d12/graphics_system.cpp new file mode 100644 index 0000000..caa77cf --- /dev/null +++ b/src/graphics/d3d12/graphics_system.cpp @@ -0,0 +1,50 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace rex::graphics::d3d12 { + +D3D12GraphicsSystem::D3D12GraphicsSystem() {} + +D3D12GraphicsSystem::~D3D12GraphicsSystem() {} + +bool D3D12GraphicsSystem::IsAvailable() { + return rex::ui::d3d12::D3D12Provider::IsD3D12APIAvailable(); +} + +std::string D3D12GraphicsSystem::name() const { + auto d3d12_command_processor = static_cast(command_processor()); + if (d3d12_command_processor != nullptr) { + return d3d12_command_processor->GetWindowTitleText(); + } + return "Direct3D 12"; +} + +void D3D12GraphicsSystem::CreateProvider(bool /*with_presentation*/) { + // D3D12 doesn't differentiate headless vs. swapchain-capable providers; + // swapchains are created lazily per-window by the presenter. + provider_ = rex::ui::d3d12::D3D12Provider::Create(); +} + +std::unique_ptr D3D12GraphicsSystem::CreateCommandProcessor() { + return std::unique_ptr(new D3D12CommandProcessor(this, kernel_state_)); +} + +} // namespace rex::graphics::d3d12 diff --git a/src/graphics/d3d12/pipeline_cache.cpp b/src/graphics/d3d12/pipeline_cache.cpp new file mode 100644 index 0000000..8e6b854 --- /dev/null +++ b/src/graphics/d3d12/pipeline_cache.cpp @@ -0,0 +1,3268 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include "thirdparty/dxbc/DXBCChecksum.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(d3d12_dxbc_disasm, false, "GPU/D3D12", "Dump DXBC disassembly"); + +REXCVAR_DEFINE_BOOL(d3d12_dxbc_disasm_dxilconv, false, "GPU/D3D12", + "Dump DXIL conversion disassembly"); + +REXCVAR_DEFINE_INT32(d3d12_pipeline_creation_threads, -1, "GPU/D3D12", + "Number of pipeline creation threads (-1 for auto)") + .range(-1, 32) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_BOOL(d3d12_tessellation_wireframe, false, "GPU/D3D12", + "Render tessellation as wireframe"); + +namespace rex::graphics::d3d12 { + +// Generated with `xb buildshaders`. +namespace shaders { +#include "../shaders/bytecode/d3d12_5_1/adaptive_quad_hs.h" +#include "../shaders/bytecode/d3d12_5_1/adaptive_triangle_hs.h" +#include "../shaders/bytecode/d3d12_5_1/continuous_quad_1cp_hs.h" +#include "../shaders/bytecode/d3d12_5_1/continuous_quad_4cp_hs.h" +#include "../shaders/bytecode/d3d12_5_1/continuous_triangle_1cp_hs.h" +#include "../shaders/bytecode/d3d12_5_1/continuous_triangle_3cp_hs.h" +#include "../shaders/bytecode/d3d12_5_1/discrete_quad_1cp_hs.h" +#include "../shaders/bytecode/d3d12_5_1/discrete_quad_4cp_hs.h" +#include "../shaders/bytecode/d3d12_5_1/discrete_triangle_1cp_hs.h" +#include "../shaders/bytecode/d3d12_5_1/discrete_triangle_3cp_hs.h" +#include "../shaders/bytecode/d3d12_5_1/float24_round_ps.h" +#include "../shaders/bytecode/d3d12_5_1/float24_truncate_ps.h" +#include "../shaders/bytecode/d3d12_5_1/tessellation_adaptive_vs.h" +#include "../shaders/bytecode/d3d12_5_1/tessellation_indexed_vs.h" +} // namespace shaders + +PipelineCache::PipelineCache(D3D12CommandProcessor& command_processor, + const RegisterFile& register_file, + const D3D12RenderTargetCache& render_target_cache, + bool bindless_resources_used) + : command_processor_(command_processor), + register_file_(register_file), + render_target_cache_(render_target_cache), + bindless_resources_used_(bindless_resources_used) { + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + + bool edram_rov_used = + render_target_cache.GetPath() == RenderTargetCache::Path::kPixelShaderInterlock; + + shader_translator_ = std::make_unique( + provider.GetAdapterVendorID(), bindless_resources_used_, edram_rov_used, + !render_target_cache_.gamma_render_target_as_unorm16(), + render_target_cache_.msaa_2x_supported(), render_target_cache_.draw_resolution_scale_x(), + render_target_cache_.draw_resolution_scale_y(), provider.GetGraphicsAnalysis() != nullptr); + + if (edram_rov_used) { + depth_only_pixel_shader_ = std::move(shader_translator_->CreateDepthOnlyPixelShader()); + } +} + +PipelineCache::~PipelineCache() { + Shutdown(); +} + +bool PipelineCache::Initialize() { + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + + // Initialize the command processor thread DXIL objects. + dxbc_converter_ = nullptr; + dxc_utils_ = nullptr; + dxc_compiler_ = nullptr; + if (REXCVAR_GET(d3d12_dxbc_disasm_dxilconv)) { + if (FAILED(provider.DxbcConverterCreateInstance(CLSID_DxbcConverter, + IID_PPV_ARGS(&dxbc_converter_)))) { + REXGPU_ERROR( + "Failed to create DxbcConverter, converted DXIL disassembly for " + "debugging will be unavailable"); + } + if (FAILED(provider.DxcCreateInstance(CLSID_DxcUtils, IID_PPV_ARGS(&dxc_utils_)))) { + REXGPU_ERROR( + "Failed to create DxcUtils, converted DXIL disassembly for debugging " + "will be unavailable"); + } + if (FAILED(provider.DxcCreateInstance(CLSID_DxcCompiler, IID_PPV_ARGS(&dxc_compiler_)))) { + REXGPU_ERROR( + "Failed to create DxcCompiler, converted DXIL disassembly for " + "debugging will be unavailable"); + } + } + + uint32_t logical_processor_count = rex::thread::logical_processor_count(); + if (!logical_processor_count) { + // Pick some reasonable amount if couldn't determine the number of cores. + logical_processor_count = 6; + } + // Initialize creation thread synchronization data even if not using creation + // threads because they may be used anyway to create pipelines from the + // storage. + creation_threads_busy_ = 0; + creation_completion_event_ = rex::thread::Event::CreateManualResetEvent(true); + assert_not_null(creation_completion_event_); + creation_completion_set_event_ = false; + creation_threads_shutdown_from_ = SIZE_MAX; + if (REXCVAR_GET(d3d12_pipeline_creation_threads) != 0) { + size_t creation_thread_count; + if (REXCVAR_GET(d3d12_pipeline_creation_threads) < 0) { + creation_thread_count = std::max(logical_processor_count * 3 / 4, uint32_t(1)); + } else { + creation_thread_count = + std::min(uint32_t(REXCVAR_GET(d3d12_pipeline_creation_threads)), logical_processor_count); + } + for (size_t i = 0; i < creation_thread_count; ++i) { + std::unique_ptr creation_thread = + rex::thread::Thread::Create({}, [this, i]() { CreationThread(i); }); + assert_not_null(creation_thread); + creation_thread->set_name("D3D12 Pipelines"); + creation_threads_.push_back(std::move(creation_thread)); + } + } + return true; +} + +void PipelineCache::Shutdown() { + // Shut down all threads, before destroying the pipelines since they may be + // creating them. + if (!creation_threads_.empty()) { + { + std::lock_guard lock(creation_request_lock_); + creation_threads_shutdown_from_ = 0; + } + creation_request_cond_.notify_all(); + for (size_t i = 0; i < creation_threads_.size(); ++i) { + rex::thread::Wait(creation_threads_[i].get(), false); + } + creation_threads_.clear(); + } + creation_completion_event_.reset(); + + // Shut down the persistent shader / pipeline storage. + ShutdownShaderStorage(); + + // Destroy all pipelines. + current_pipeline_ = nullptr; + for (auto it : pipelines_) { + ID3D12PipelineState* state = it.second->state.load(std::memory_order_acquire); + if (state) { + state->Release(); + } + delete it.second; + } + pipelines_.clear(); + COUNT_profile_set("gpu/pipeline_cache/pipelines", 0); + + // Destroy all shaders. + if (bindless_resources_used_) { + bindless_sampler_layout_map_.clear(); + bindless_sampler_layouts_.clear(); + } + texture_binding_layout_map_.clear(); + texture_binding_layouts_.clear(); + for (auto it : shaders_) { + delete it.second; + } + shaders_.clear(); + shader_storage_index_ = 0; + + // Shut down shader translation. + ui::d3d12::util::ReleaseAndNull(dxc_compiler_); + ui::d3d12::util::ReleaseAndNull(dxc_utils_); + ui::d3d12::util::ReleaseAndNull(dxbc_converter_); +} + +void PipelineCache::InitializeShaderStorage(const std::filesystem::path& cache_root, + uint32_t title_id, bool blocking) { + ShutdownShaderStorage(); + + auto shader_storage_root = cache_root / "shaders"; + // For files that can be moved between different hosts. + // Host PSO blobs - if ever added - should be stored in shaders/local/ (they + // currently aren't used because because they may be not very practical - + // would need to invalidate them every commit likely, and additional I/O + // cost - though D3D's internal validation would possibly be enough to ensure + // they are up to date). + auto shader_storage_shareable_root = shader_storage_root / "shareable"; + if (!std::filesystem::exists(shader_storage_shareable_root)) { + if (!std::filesystem::create_directories(shader_storage_shareable_root)) { + REXGPU_ERROR( + "Failed to create the shareable shader storage directory, persistent " + "shader storage will be disabled: {}", + rex::path_to_utf8(shader_storage_shareable_root)); + return; + } + } + + bool edram_rov_used = + render_target_cache_.GetPath() == RenderTargetCache::Path::kPixelShaderInterlock; + + // Initialize the pipeline storage stream - read pipeline descriptions and + // collect used shader modifications to translate. + std::vector pipeline_stored_descriptions; + // . + std::set> shader_translations_needed; + auto pipeline_storage_file_path = + shader_storage_shareable_root / + fmt::format("{:08X}.{}.d3d12.xpso", title_id, edram_rov_used ? "rov" : "rtv"); + pipeline_storage_file_ = rex::filesystem::OpenFile(pipeline_storage_file_path, "a+b"); + if (!pipeline_storage_file_) { + REXGPU_ERROR( + "Failed to open the Direct3D 12 pipeline description storage file for " + "writing, persistent shader storage will be disabled: {}", + rex::path_to_utf8(pipeline_storage_file_path)); + return; + } + pipeline_storage_file_flush_needed_ = false; + // 'XEPS'. + const uint32_t pipeline_storage_magic = 0x53504558; + // 'DXRO' or 'DXRT'. + const uint32_t pipeline_storage_magic_api = edram_rov_used ? 0x4F525844 : 0x54525844; + const uint32_t pipeline_storage_version_swapped = rex::byte_swap( + std::max(PipelineDescription::kVersion, DxbcShaderTranslator::Modification::kVersion)); + struct { + uint32_t magic; + uint32_t magic_api; + uint32_t version_swapped; + } pipeline_storage_file_header; + if (fread(&pipeline_storage_file_header, sizeof(pipeline_storage_file_header), 1, + pipeline_storage_file_) && + pipeline_storage_file_header.magic == pipeline_storage_magic && + pipeline_storage_file_header.magic_api == pipeline_storage_magic_api && + pipeline_storage_file_header.version_swapped == pipeline_storage_version_swapped) { + rex::filesystem::Seek(pipeline_storage_file_, 0, SEEK_END); + int64_t pipeline_storage_told_end = rex::filesystem::Tell(pipeline_storage_file_); + size_t pipeline_storage_told_count = + size_t(pipeline_storage_told_end >= int64_t(sizeof(pipeline_storage_file_header)) + ? (uint64_t(pipeline_storage_told_end) - sizeof(pipeline_storage_file_header)) / + sizeof(PipelineStoredDescription) + : 0); + if (pipeline_storage_told_count && + rex::filesystem::Seek(pipeline_storage_file_, int64_t(sizeof(pipeline_storage_file_header)), + SEEK_SET)) { + pipeline_stored_descriptions.resize(pipeline_storage_told_count); + pipeline_stored_descriptions.resize( + fread(pipeline_stored_descriptions.data(), sizeof(PipelineStoredDescription), + pipeline_storage_told_count, pipeline_storage_file_)); + size_t pipeline_storage_read_count = pipeline_stored_descriptions.size(); + for (size_t i = 0; i < pipeline_storage_read_count; ++i) { + const PipelineStoredDescription& pipeline_stored_description = + pipeline_stored_descriptions[i]; + // Validate file integrity, stop and truncate the stream if data is + // corrupted. + if (XXH3_64bits(&pipeline_stored_description.description, + sizeof(pipeline_stored_description.description)) != + pipeline_stored_description.description_hash) { + pipeline_stored_descriptions.resize(i); + break; + } + // TODO(Triang3l): On Vulkan, skip pipelines requiring unsupported + // device features (to keep the cache files mostly shareable across + // devices). + // Mark the shader modifications as needed for translation. + shader_translations_needed.emplace( + pipeline_stored_description.description.vertex_shader_hash, + pipeline_stored_description.description.vertex_shader_modification); + if (pipeline_stored_description.description.pixel_shader_hash) { + shader_translations_needed.emplace( + pipeline_stored_description.description.pixel_shader_hash, + pipeline_stored_description.description.pixel_shader_modification); + } + } + } + } + + size_t logical_processor_count = rex::thread::logical_processor_count(); + if (!logical_processor_count) { + // Pick some reasonable amount if couldn't determine the number of cores. + logical_processor_count = 6; + } + + // Initialize the Xenos shader storage stream. + uint64_t shader_storage_initialization_start = rex::chrono::Clock::QueryHostTickCount(); + auto shader_storage_file_path = + shader_storage_shareable_root / fmt::format("{:08X}.xsh", title_id); + shader_storage_file_ = rex::filesystem::OpenFile(shader_storage_file_path, "a+b"); + if (!shader_storage_file_) { + REXGPU_ERROR( + "Failed to open the guest shader storage file for writing, persistent " + "shader storage will be disabled: {}", + rex::path_to_utf8(shader_storage_file_path)); + fclose(pipeline_storage_file_); + pipeline_storage_file_ = nullptr; + return; + } + ++shader_storage_index_; + shader_storage_file_flush_needed_ = false; + struct { + uint32_t magic; + uint32_t version_swapped; + } shader_storage_file_header; + // 'XESH'. + const uint32_t shader_storage_magic = 0x48534558; + if (fread(&shader_storage_file_header, sizeof(shader_storage_file_header), 1, + shader_storage_file_) && + shader_storage_file_header.magic == shader_storage_magic && + rex::byte_swap(shader_storage_file_header.version_swapped) == ShaderStoredHeader::kVersion) { + uint64_t shader_storage_valid_bytes = sizeof(shader_storage_file_header); + // Load and translate shaders written by previous Xenia executions until the + // end of the file or until a corrupted one is detected. + ShaderStoredHeader shader_header; + std::vector ucode_dwords; + ucode_dwords.reserve(0xFFFF); + size_t shaders_translated = 0; + + // Threads overlapping file reading. + std::mutex shaders_translation_thread_mutex; + std::condition_variable shaders_translation_thread_cond; + std::deque shaders_to_translate; + size_t shader_translation_threads_busy = 0; + bool shader_translation_threads_shutdown = false; + std::mutex shaders_failed_to_translate_mutex; + std::vector shaders_failed_to_translate; + auto shader_translation_thread_function = [&]() { + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + string::StringBuffer ucode_disasm_buffer; + DxbcShaderTranslator translator( + provider.GetAdapterVendorID(), bindless_resources_used_, edram_rov_used, + !render_target_cache_.gamma_render_target_as_unorm16(), + render_target_cache_.msaa_2x_supported(), render_target_cache_.draw_resolution_scale_x(), + render_target_cache_.draw_resolution_scale_y(), + provider.GetGraphicsAnalysis() != nullptr); + // If needed and possible, create objects needed for DXIL conversion and + // disassembly on this thread. + IDxbcConverter* dxbc_converter = nullptr; + IDxcUtils* dxc_utils = nullptr; + IDxcCompiler* dxc_compiler = nullptr; + if (REXCVAR_GET(d3d12_dxbc_disasm_dxilconv) && dxbc_converter_ && dxc_utils_ && + dxc_compiler_) { + provider.DxbcConverterCreateInstance(CLSID_DxbcConverter, IID_PPV_ARGS(&dxbc_converter)); + provider.DxcCreateInstance(CLSID_DxcUtils, IID_PPV_ARGS(&dxc_utils)); + provider.DxcCreateInstance(CLSID_DxcCompiler, IID_PPV_ARGS(&dxc_compiler)); + } + for (;;) { + D3D12Shader* shader_to_translate; + for (;;) { + std::unique_lock lock(shaders_translation_thread_mutex); + if (shaders_to_translate.empty()) { + if (shader_translation_threads_shutdown) { + return; + } + shaders_translation_thread_cond.wait(lock); + continue; + } + shader_to_translate = shaders_to_translate.front(); + shaders_to_translate.pop_front(); + ++shader_translation_threads_busy; + break; + } + shader_to_translate->AnalyzeUcode(ucode_disasm_buffer); + // Translate each needed modification on this thread after performing + // modification-independent analysis of the whole shader. + uint64_t ucode_data_hash = shader_to_translate->ucode_data_hash(); + for (auto modification_it = shader_translations_needed.lower_bound( + std::make_pair(ucode_data_hash, uint64_t(0))); + modification_it != shader_translations_needed.end() && + modification_it->first == ucode_data_hash; + ++modification_it) { + D3D12Shader::D3D12Translation* translation = static_cast( + shader_to_translate->GetOrCreateTranslation(modification_it->second)); + // Only try (and delete in case of failure) if it's a new translation. + // If it's a shader previously encountered in the game, translation of + // which has failed, and the shader storage is loaded later, keep it + // this way not to try to translate it again. + if (!translation->is_translated() && + !TranslateAnalyzedShader(translator, *translation, dxbc_converter, dxc_utils, + dxc_compiler)) { + std::lock_guard lock(shaders_failed_to_translate_mutex); + shaders_failed_to_translate.push_back(translation); + } + } + { + std::lock_guard lock(shaders_translation_thread_mutex); + --shader_translation_threads_busy; + } + } + if (dxc_compiler) { + dxc_compiler->Release(); + } + if (dxc_utils) { + dxc_utils->Release(); + } + if (dxbc_converter) { + dxbc_converter->Release(); + } + }; + std::vector> shader_translation_threads; + + while (true) { + if (!fread(&shader_header, sizeof(shader_header), 1, shader_storage_file_)) { + break; + } + size_t ucode_byte_count = shader_header.ucode_dword_count * sizeof(uint32_t); + ucode_dwords.resize(shader_header.ucode_dword_count); + if (shader_header.ucode_dword_count && + !fread(ucode_dwords.data(), ucode_byte_count, 1, shader_storage_file_)) { + break; + } + uint64_t ucode_data_hash = XXH3_64bits(ucode_dwords.data(), ucode_byte_count); + if (shader_header.ucode_data_hash != ucode_data_hash) { + // Validation failed. + break; + } + shader_storage_valid_bytes += sizeof(shader_header) + ucode_byte_count; + D3D12Shader* shader = LoadShader(shader_header.type, ucode_dwords.data(), + shader_header.ucode_dword_count, ucode_data_hash); + if (shader->ucode_storage_index() == shader_storage_index_) { + // Appeared twice in this file for some reason - skip, otherwise race + // condition will be caused by translating twice in parallel. + continue; + } + // Loaded from the current storage - don't write again. + shader->set_ucode_storage_index(shader_storage_index_); + // Create new threads if the currently existing threads can't keep up + // with file reading, but not more than the number of logical processors + // minus one. + size_t shader_translation_threads_needed; + { + std::lock_guard lock(shaders_translation_thread_mutex); + shader_translation_threads_needed = + std::min(shader_translation_threads_busy + shaders_to_translate.size() + size_t(1), + logical_processor_count - size_t(1)); + } + while (shader_translation_threads.size() < shader_translation_threads_needed) { + auto thread = rex::thread::Thread::Create({}, shader_translation_thread_function); + assert_not_null(thread); + thread->set_name("Shader Translation"); + shader_translation_threads.push_back(std::move(thread)); + } + // Request ucode information gathering and translation of all the needed + // shaders. + { + std::lock_guard lock(shaders_translation_thread_mutex); + shaders_to_translate.push_back(shader); + } + shaders_translation_thread_cond.notify_one(); + ++shaders_translated; + } + if (!shader_translation_threads.empty()) { + { + std::lock_guard lock(shaders_translation_thread_mutex); + shader_translation_threads_shutdown = true; + } + shaders_translation_thread_cond.notify_all(); + for (auto& shader_translation_thread : shader_translation_threads) { + rex::thread::Wait(shader_translation_thread.get(), false); + } + shader_translation_threads.clear(); + for (D3D12Shader::D3D12Translation* translation : shaders_failed_to_translate) { + D3D12Shader* shader = static_cast(&translation->shader()); + shader->DestroyTranslation(translation->modification()); + if (shader->translations().empty()) { + shaders_.erase(shader->ucode_data_hash()); + delete shader; + } + } + } + REXGPU_INFO("Translated {} shaders from the storage in {} milliseconds", shaders_translated, + (rex::chrono::Clock::QueryHostTickCount() - shader_storage_initialization_start) * + 1000 / rex::chrono::Clock::QueryHostTickFrequency()); + rex::filesystem::TruncateStdioFile(shader_storage_file_, shader_storage_valid_bytes); + } else { + rex::filesystem::TruncateStdioFile(shader_storage_file_, 0); + shader_storage_file_header.magic = shader_storage_magic; + shader_storage_file_header.version_swapped = rex::byte_swap(ShaderStoredHeader::kVersion); + fwrite(&shader_storage_file_header, sizeof(shader_storage_file_header), 1, + shader_storage_file_); + } + + // Create the pipelines. + if (!pipeline_stored_descriptions.empty()) { + uint64_t pipeline_creation_start_ = rex::chrono::Clock::QueryHostTickCount(); + + // Launch additional creation threads to use all cores to create + // pipelines faster. Will also be using the main thread, so minus 1. + size_t creation_thread_original_count = creation_threads_.size(); + size_t creation_thread_needed_count = + std::max(std::min(pipeline_stored_descriptions.size(), logical_processor_count) - size_t(1), + creation_thread_original_count); + while (creation_threads_.size() < creation_thread_original_count) { + size_t creation_thread_index = creation_threads_.size(); + std::unique_ptr creation_thread = rex::thread::Thread::Create( + {}, [this, creation_thread_index]() { CreationThread(creation_thread_index); }); + assert_not_null(creation_thread); + creation_thread->set_name("D3D12 Pipelines"); + creation_threads_.push_back(std::move(creation_thread)); + } + + size_t pipelines_created = 0; + for (const PipelineStoredDescription& pipeline_stored_description : + pipeline_stored_descriptions) { + const PipelineDescription& pipeline_description = pipeline_stored_description.description; + // TODO(Triang3l): On Vulkan, skip pipelines requiring unsupported device + // features (to keep the cache files mostly shareable across devices). + // Skip already known pipelines - those have already been enqueued. + auto found_range = pipelines_.equal_range(pipeline_stored_description.description_hash); + bool pipeline_found = false; + for (auto it = found_range.first; it != found_range.second; ++it) { + Pipeline* found_pipeline = it->second; + if (!std::memcmp(&found_pipeline->description.description, &pipeline_description, + sizeof(pipeline_description))) { + pipeline_found = true; + break; + } + } + if (pipeline_found) { + continue; + } + + PipelineRuntimeDescription pipeline_runtime_description; + auto vertex_shader_it = shaders_.find(pipeline_description.vertex_shader_hash); + if (vertex_shader_it == shaders_.end()) { + continue; + } + D3D12Shader* vertex_shader = vertex_shader_it->second; + pipeline_runtime_description.vertex_shader = static_cast( + vertex_shader->GetTranslation(pipeline_description.vertex_shader_modification)); + if (!pipeline_runtime_description.vertex_shader || + !pipeline_runtime_description.vertex_shader->is_translated() || + !pipeline_runtime_description.vertex_shader->is_valid()) { + continue; + } + D3D12Shader* pixel_shader; + if (pipeline_description.pixel_shader_hash) { + auto pixel_shader_it = shaders_.find(pipeline_description.pixel_shader_hash); + if (pixel_shader_it == shaders_.end()) { + continue; + } + pixel_shader = pixel_shader_it->second; + pipeline_runtime_description.pixel_shader = static_cast( + pixel_shader->GetTranslation(pipeline_description.pixel_shader_modification)); + if (!pipeline_runtime_description.pixel_shader || + !pipeline_runtime_description.pixel_shader->is_translated() || + !pipeline_runtime_description.pixel_shader->is_valid()) { + continue; + } + } else { + pixel_shader = nullptr; + pipeline_runtime_description.pixel_shader = nullptr; + } + GeometryShaderKey pipeline_geometry_shader_key; + pipeline_runtime_description.geometry_shader = + GetGeometryShaderKey( + pipeline_description.geometry_shader, + DxbcShaderTranslator::Modification(pipeline_description.vertex_shader_modification), + DxbcShaderTranslator::Modification(pipeline_description.pixel_shader_modification), + pipeline_geometry_shader_key) + ? &GetGeometryShader(pipeline_geometry_shader_key) + : nullptr; + pipeline_runtime_description.root_signature = command_processor_.GetRootSignature( + vertex_shader, pixel_shader, + Shader::IsHostVertexShaderTypeDomain( + DxbcShaderTranslator::Modification(pipeline_description.vertex_shader_modification) + .vertex.host_vertex_shader_type)); + if (!pipeline_runtime_description.root_signature) { + continue; + } + std::memcpy(&pipeline_runtime_description.description, &pipeline_description, + sizeof(pipeline_description)); + + Pipeline* new_pipeline = new Pipeline; + std::memcpy(&new_pipeline->description, &pipeline_runtime_description, + sizeof(pipeline_runtime_description)); + new_pipeline->root_signature.store(pipeline_runtime_description.root_signature, + std::memory_order_release); + uint32_t bound_rts = 0; + for (uint32_t i = 0; i < xenos::kMaxColorRenderTargets; ++i) { + if (pipeline_runtime_description.description.render_targets[i].used) { + bound_rts |= uint32_t(1) << i; + } + } + uint32_t shader_writes_color_targets = + pipeline_runtime_description.pixel_shader + ? pipeline_runtime_description.pixel_shader->shader().writes_color_targets() + : 0; + bool shader_writes_depth = + pipeline_runtime_description.pixel_shader + ? pipeline_runtime_description.pixel_shader->shader().writes_depth() + : pipeline_runtime_description.description.depth_write != 0; + new_pipeline->priority = pipeline_util::CalculatePipelinePriority( + bound_rts, shader_writes_color_targets, shader_writes_depth); + pipelines_.emplace(pipeline_stored_description.description_hash, new_pipeline); + COUNT_profile_set("gpu/pipeline_cache/pipelines", pipelines_.size()); + if (!creation_threads_.empty()) { + // Submit the pipeline for creation to any available thread. + { + std::lock_guard lock(creation_request_lock_); + creation_queue_.push(new_pipeline); + } + creation_request_cond_.notify_one(); + } else { + new_pipeline->state.store(CreateD3D12Pipeline(pipeline_runtime_description), + std::memory_order_release); + } + ++pipelines_created; + } + + if (!creation_threads_.empty()) { + CreateQueuedPipelinesOnProcessorThread(); + if (creation_threads_.size() > creation_thread_original_count) { + { + std::lock_guard lock(creation_request_lock_); + creation_threads_shutdown_from_ = creation_thread_original_count; + // Assuming the queue is empty because of + // CreateQueuedPipelinesOnProcessorThread. + } + creation_request_cond_.notify_all(); + while (creation_threads_.size() > creation_thread_original_count) { + rex::thread::Wait(creation_threads_.back().get(), false); + creation_threads_.pop_back(); + } + bool await_creation_completion_event; + { + // Cleanup so additional threads can be created later again. + std::lock_guard lock(creation_request_lock_); + creation_threads_shutdown_from_ = SIZE_MAX; + // If the invocation is blocking, all the shader storage + // initialization is expected to be done before proceeding, to avoid + // latency in the command processor after the invocation. + await_creation_completion_event = blocking && creation_threads_busy_ != 0; + if (await_creation_completion_event) { + creation_completion_event_->Reset(); + creation_completion_set_event_ = true; + } + } + if (await_creation_completion_event) { + creation_request_cond_.notify_one(); + rex::thread::Wait(creation_completion_event_.get(), false); + } + } + } + + REXGPU_INFO( + "Created {} graphics pipelines (not including reading the " + "descriptions) from the storage in {} milliseconds", + pipelines_created, + (rex::chrono::Clock::QueryHostTickCount() - pipeline_creation_start_) * 1000 / + rex::chrono::Clock::QueryHostTickFrequency()); + // If any pipeline descriptions were corrupted (or the whole file has excess + // bytes in the end), truncate to the last valid pipeline description. + rex::filesystem::TruncateStdioFile( + pipeline_storage_file_, + uint64_t(sizeof(pipeline_storage_file_header) + + sizeof(PipelineStoredDescription) * pipeline_stored_descriptions.size())); + } else { + rex::filesystem::TruncateStdioFile(pipeline_storage_file_, 0); + pipeline_storage_file_header.magic = pipeline_storage_magic; + pipeline_storage_file_header.magic_api = pipeline_storage_magic_api; + pipeline_storage_file_header.version_swapped = pipeline_storage_version_swapped; + fwrite(&pipeline_storage_file_header, sizeof(pipeline_storage_file_header), 1, + pipeline_storage_file_); + } + + shader_storage_cache_root_ = cache_root; + shader_storage_title_id_ = title_id; + + // Start the storage writing thread. + storage_write_flush_shaders_ = false; + storage_write_flush_pipelines_ = false; + storage_write_thread_shutdown_ = false; + storage_write_thread_ = rex::thread::Thread::Create({}, [this]() { StorageWriteThread(); }); + assert_not_null(storage_write_thread_); + storage_write_thread_->set_name("D3D12 Storage writer"); +} + +void PipelineCache::ShutdownShaderStorage() { + if (storage_write_thread_) { + { + std::lock_guard lock(storage_write_request_lock_); + storage_write_thread_shutdown_ = true; + } + storage_write_request_cond_.notify_all(); + rex::thread::Wait(storage_write_thread_.get(), false); + storage_write_thread_.reset(); + } + storage_write_shader_queue_.clear(); + storage_write_pipeline_queue_.clear(); + + if (pipeline_storage_file_) { + fclose(pipeline_storage_file_); + pipeline_storage_file_ = nullptr; + pipeline_storage_file_flush_needed_ = false; + } + + if (shader_storage_file_) { + fclose(shader_storage_file_); + shader_storage_file_ = nullptr; + shader_storage_file_flush_needed_ = false; + } + + shader_storage_cache_root_.clear(); + shader_storage_title_id_ = 0; +} + +void PipelineCache::EndSubmission() { + if (shader_storage_file_flush_needed_ || pipeline_storage_file_flush_needed_) { + { + std::lock_guard lock(storage_write_request_lock_); + if (shader_storage_file_flush_needed_) { + storage_write_flush_shaders_ = true; + } + if (pipeline_storage_file_flush_needed_) { + storage_write_flush_pipelines_ = true; + } + } + storage_write_request_cond_.notify_one(); + shader_storage_file_flush_needed_ = false; + pipeline_storage_file_flush_needed_ = false; + } + if (!creation_threads_.empty()) { + CreateQueuedPipelinesOnProcessorThread(); + // Await creation of all queued pipelines. + bool await_creation_completion_event; + { + std::lock_guard lock(creation_request_lock_); + // Assuming the creation queue is already empty (because the processor + // thread also worked on creating the leftover pipelines), so only check + // if there are threads with pipelines currently being created. + await_creation_completion_event = creation_threads_busy_ != 0; + if (await_creation_completion_event) { + creation_completion_event_->Reset(); + creation_completion_set_event_ = true; + } + } + if (await_creation_completion_event) { + creation_request_cond_.notify_one(); + rex::thread::Wait(creation_completion_event_.get(), false); + } + } +} + +bool PipelineCache::IsCreatingPipelines() { + if (creation_threads_.empty()) { + return false; + } + std::lock_guard lock(creation_request_lock_); + return !creation_queue_.empty() || creation_threads_busy_ != 0; +} + +D3D12Shader* PipelineCache::LoadShader(xenos::ShaderType shader_type, const uint32_t* host_address, + uint32_t dword_count) { + // Hash the input memory and lookup the shader. + return LoadShader(shader_type, host_address, dword_count, + XXH3_64bits(host_address, dword_count * sizeof(uint32_t))); +} + +D3D12Shader* PipelineCache::LoadShader(xenos::ShaderType shader_type, const uint32_t* host_address, + uint32_t dword_count, uint64_t data_hash) { + auto it = shaders_.find(data_hash); + if (it != shaders_.end()) { + // Shader has been previously loaded. + return it->second; + } + // Always create the shader and stash it away. + // We need to track it even if it fails translation so we know not to try + // again. + D3D12Shader* shader = new D3D12Shader(shader_type, data_hash, host_address, dword_count); + shaders_.emplace(data_hash, shader); + return shader; +} + +DxbcShaderTranslator::Modification PipelineCache::GetCurrentVertexShaderModification( + const Shader& shader, Shader::HostVertexShaderType host_vertex_shader_type, + uint32_t interpolator_mask) const { + assert_true(shader.type() == xenos::ShaderType::kVertex); + assert_true(shader.is_ucode_analyzed()); + const auto& regs = register_file_; + + DxbcShaderTranslator::Modification modification( + shader_translator_->GetDefaultVertexShaderModification( + shader.GetDynamicAddressableRegisterCount(regs.Get().vs_num_reg), + host_vertex_shader_type)); + + modification.vertex.interpolator_mask = interpolator_mask; + + auto pa_cl_clip_cntl = regs.Get(); + uint32_t user_clip_planes = pa_cl_clip_cntl.clip_disable ? 0 : pa_cl_clip_cntl.ucp_ena; + modification.vertex.user_clip_plane_count = rex::bit_count(user_clip_planes); + modification.vertex.user_clip_plane_cull = + uint32_t(user_clip_planes && pa_cl_clip_cntl.ucp_cull_only_ena); + modification.vertex.point_ps_ucp_mode = pa_cl_clip_cntl.ps_ucp_mode; + modification.vertex.vertex_kill_and = uint32_t( + (shader.writes_point_size_edge_flag_kill_vertex() & 0b100) && !pa_cl_clip_cntl.vtx_kill_or); + + modification.vertex.output_point_size = + uint32_t((shader.writes_point_size_edge_flag_kill_vertex() & 0b001) && + regs.Get().prim_type == xenos::PrimitiveType::kPointList); + + return modification; +} + +DxbcShaderTranslator::Modification PipelineCache::GetCurrentPixelShaderModification( + const Shader& shader, uint32_t interpolator_mask, uint32_t param_gen_pos, + reg::RB_DEPTHCONTROL normalized_depth_control) const { + assert_true(shader.type() == xenos::ShaderType::kPixel); + assert_true(shader.is_ucode_analyzed()); + const auto& regs = register_file_; + + DxbcShaderTranslator::Modification modification( + shader_translator_->GetDefaultPixelShaderModification( + shader.GetDynamicAddressableRegisterCount(regs.Get().ps_num_reg))); + + modification.pixel.interpolator_mask = interpolator_mask; + modification.pixel.interpolators_centroid = + interpolator_mask & ~xenos::GetInterpolatorSamplingPattern( + regs.Get().msaa_samples, + regs.Get().sc_sample_cntl, + regs.Get().sampling_pattern); + + if (param_gen_pos < xenos::kMaxInterpolators) { + modification.pixel.param_gen_enable = 1; + modification.pixel.param_gen_interpolator = param_gen_pos; + modification.pixel.param_gen_point = + uint32_t(regs.Get().prim_type == xenos::PrimitiveType::kPointList); + } else { + modification.pixel.param_gen_enable = 0; + modification.pixel.param_gen_interpolator = 0; + modification.pixel.param_gen_point = 0; + } + + if (render_target_cache_.GetPath() == RenderTargetCache::Path::kHostRenderTargets) { + using DepthStencilMode = DxbcShaderTranslator::Modification::DepthStencilMode; + if (render_target_cache_.depth_float24_convert_in_pixel_shader() && + normalized_depth_control.z_enable && + regs.Get().depth_format == xenos::DepthRenderTargetFormat::kD24FS8) { + modification.pixel.depth_stencil_mode = render_target_cache_.depth_float24_round() + ? DepthStencilMode::kFloat24Rounding + : DepthStencilMode::kFloat24Truncating; + } else { + if (shader.implicit_early_z_write_allowed() && + (!shader.writes_color_target(0) || + !draw_util::DoesCoverageDependOnAlpha(regs.Get()))) { + modification.pixel.depth_stencil_mode = DepthStencilMode::kEarlyHint; + } else { + modification.pixel.depth_stencil_mode = DepthStencilMode::kNoModifiers; + } + } + } + + return modification; +} + +bool PipelineCache::ConfigurePipeline( + D3D12Shader::D3D12Translation* vertex_shader, D3D12Shader::D3D12Translation* pixel_shader, + const PrimitiveProcessor::ProcessingResult& primitive_processing_result, + reg::RB_DEPTHCONTROL normalized_depth_control, uint32_t normalized_color_mask, + uint32_t bound_depth_and_color_render_target_bits, + const uint32_t* bound_depth_and_color_render_target_formats, void** pipeline_handle_out, + ID3D12RootSignature** root_signature_out) { +#if XE_GPU_FINE_GRAINED_DRAW_SCOPES + SCOPE_profile_cpu_f("gpu"); +#endif // XE_GPU_FINE_GRAINED_DRAW_SCOPES + + assert_not_null(pipeline_handle_out); + assert_not_null(root_signature_out); + + bool use_async = REXCVAR_GET(async_shader_compilation) && !creation_threads_.empty() && + pixel_shader != nullptr; + + // Ensure shaders are translated - needed now for GetCurrentStateDescription. + // Edge flags are not supported yet (because polygon primitives are not). + assert_true(register_file_.Get().vs_export_mode != + xenos::VertexShaderExportMode::kPosition2VectorsEdge && + register_file_.Get().vs_export_mode != + xenos::VertexShaderExportMode::kPosition2VectorsEdgeKill); + assert_false(register_file_.Get().gen_index_vtx); + // Ucode analysis is always needed on the main thread (for modification and + // hash computation). Translation can be deferred to background threads when + // async compilation is enabled. + if (!vertex_shader->shader().is_ucode_analyzed()) { + vertex_shader->shader().AnalyzeUcode(ucode_disasm_buffer_); + } + if (!vertex_shader->is_translated() && !use_async) { + std::lock_guard lock(translation_request_lock_); + if (!vertex_shader->is_translated()) { + if (!TranslateAnalyzedShader(*shader_translator_, *vertex_shader, dxbc_converter_, dxc_utils_, + dxc_compiler_)) { + REXGPU_ERROR("Failed to translate the vertex shader!"); + return false; + } + if (shader_storage_file_ && + vertex_shader->shader().ucode_storage_index() != shader_storage_index_) { + vertex_shader->shader().set_ucode_storage_index(shader_storage_index_); + assert_not_null(storage_write_thread_); + shader_storage_file_flush_needed_ = true; + { + std::lock_guard storage_lock(storage_write_request_lock_); + storage_write_shader_queue_.push_back(&vertex_shader->shader()); + } + storage_write_request_cond_.notify_all(); + } + } + } + if (!use_async && !vertex_shader->is_valid()) { + // Translation attempted previously, but not valid. + return false; + } + if (pixel_shader != nullptr) { + if (!pixel_shader->is_translated() && !use_async) { + std::lock_guard lock(translation_request_lock_); + if (!pixel_shader->is_translated()) { + pixel_shader->shader().AnalyzeUcode(ucode_disasm_buffer_); + if (!TranslateAnalyzedShader(*shader_translator_, *pixel_shader, dxbc_converter_, + dxc_utils_, dxc_compiler_)) { + REXGPU_ERROR("Failed to translate the pixel shader!"); + return false; + } + if (shader_storage_file_ && + pixel_shader->shader().ucode_storage_index() != shader_storage_index_) { + pixel_shader->shader().set_ucode_storage_index(shader_storage_index_); + assert_not_null(storage_write_thread_); + shader_storage_file_flush_needed_ = true; + { + std::lock_guard storage_lock(storage_write_request_lock_); + storage_write_shader_queue_.push_back(&pixel_shader->shader()); + } + storage_write_request_cond_.notify_all(); + } + } + } + if (pixel_shader->is_translated() && !pixel_shader->is_valid()) { + return false; + } + } + + PipelineRuntimeDescription runtime_description; + if (!GetCurrentStateDescription( + vertex_shader, pixel_shader, primitive_processing_result, normalized_depth_control, + normalized_color_mask, bound_depth_and_color_render_target_bits, + bound_depth_and_color_render_target_formats, runtime_description, use_async)) { + return false; + } + PipelineDescription& description = runtime_description.description; + + if (current_pipeline_ != nullptr && !std::memcmp(¤t_pipeline_->description.description, + &description, sizeof(description))) { + *pipeline_handle_out = current_pipeline_; + *root_signature_out = current_pipeline_->root_signature.load(std::memory_order_acquire); + return true; + } + + // Find an existing pipeline in the cache. + uint64_t hash = XXH3_64bits(&description, sizeof(description)); + auto found_range = pipelines_.equal_range(hash); + for (auto it = found_range.first; it != found_range.second; ++it) { + Pipeline* found_pipeline = it->second; + if (!std::memcmp(&found_pipeline->description.description, &description, sizeof(description))) { + PROFILE_PIPELINE_CACHE_HIT(); + current_pipeline_ = found_pipeline; + *pipeline_handle_out = found_pipeline; + *root_signature_out = found_pipeline->root_signature.load(std::memory_order_acquire); + return true; + } + } + PROFILE_PIPELINE_CACHE_MISS(); + + Pipeline* new_pipeline = new Pipeline; + std::memcpy(&new_pipeline->description, &runtime_description, sizeof(runtime_description)); + new_pipeline->root_signature.store(runtime_description.root_signature, std::memory_order_release); + pipelines_.emplace(hash, new_pipeline); + COUNT_profile_set("gpu/pipeline_cache/pipelines", pipelines_.size()); + + if (use_async) { + uint32_t bound_rts = + pipeline_util::GetBoundRTMaskFromNormalizedColorMask(normalized_color_mask); + uint32_t shader_writes_color_targets = + pixel_shader ? pixel_shader->shader().writes_color_targets() : 0; + bool shader_writes_depth = pixel_shader ? pixel_shader->shader().writes_depth() + : normalized_depth_control.z_write_enable != 0; + new_pipeline->priority = pipeline_util::CalculatePipelinePriority( + bound_rts, shader_writes_color_targets, shader_writes_depth); + new_pipeline->pending_vertex_shader = vertex_shader; + new_pipeline->pending_pixel_shader = pixel_shader; + // Submit the pipeline for creation to any available thread. + { + std::lock_guard lock(creation_request_lock_); + creation_queue_.push(new_pipeline); + } + creation_request_cond_.notify_one(); + } else { + new_pipeline->state.store(CreateD3D12Pipeline(runtime_description), std::memory_order_release); + } + + if (pipeline_storage_file_) { + assert_not_null(storage_write_thread_); + pipeline_storage_file_flush_needed_ = true; + { + std::lock_guard lock(storage_write_request_lock_); + storage_write_pipeline_queue_.emplace_back(); + PipelineStoredDescription& stored_description = storage_write_pipeline_queue_.back(); + stored_description.description_hash = hash; + std::memcpy(&stored_description.description, &description, sizeof(description)); + } + storage_write_request_cond_.notify_all(); + } + + current_pipeline_ = new_pipeline; + *pipeline_handle_out = new_pipeline; + *root_signature_out = new_pipeline->root_signature.load(std::memory_order_acquire); + return true; +} + +bool PipelineCache::TranslateAnalyzedShader(DxbcShaderTranslator& translator, + D3D12Shader::D3D12Translation& translation, + IDxbcConverter* dxbc_converter, IDxcUtils* dxc_utils, + IDxcCompiler* dxc_compiler) { + D3D12Shader& shader = static_cast(translation.shader()); + + // Perform translation. + // If this fails the shader will be marked as invalid and ignored later. + if (!translator.TranslateAnalyzedShader(translation)) { + REXGPU_ERROR("Shader {:016X} translation failed; marking as ignored", shader.ucode_data_hash()); + return false; + } + + const char* host_shader_type; + if (shader.type() == xenos::ShaderType::kVertex) { + DxbcShaderTranslator::Modification modification(translation.modification()); + switch (modification.vertex.host_vertex_shader_type) { + case Shader::HostVertexShaderType::kLineDomainCPIndexed: + host_shader_type = "control-point-indexed line domain"; + break; + case Shader::HostVertexShaderType::kLineDomainPatchIndexed: + host_shader_type = "patch-indexed line domain"; + break; + case Shader::HostVertexShaderType::kTriangleDomainCPIndexed: + host_shader_type = "control-point-indexed triangle domain"; + break; + case Shader::HostVertexShaderType::kTriangleDomainPatchIndexed: + host_shader_type = "patch-indexed triangle domain"; + break; + case Shader::HostVertexShaderType::kQuadDomainCPIndexed: + host_shader_type = "control-point-indexed quad domain"; + break; + case Shader::HostVertexShaderType::kQuadDomainPatchIndexed: + host_shader_type = "patch-indexed quad domain"; + break; + default: + assert(modification.vertex.host_vertex_shader_type == + Shader::HostVertexShaderType::kVertex); + host_shader_type = "vertex"; + } + } else { + host_shader_type = "pixel"; + } + REXGPU_NOISY_DEBUG("Generated {} shader ({}b) - hash {:016X}:\n{}\n", host_shader_type, + shader.ucode_dword_count() * sizeof(uint32_t), shader.ucode_data_hash(), + shader.ucode_disassembly().c_str()); + + // Set up texture and sampler binding layouts. + if (shader.EnterBindingLayoutUserUIDSetup()) { + const std::vector& texture_bindings = + shader.GetTextureBindingsAfterTranslation(); + size_t texture_binding_count = texture_bindings.size(); + const std::vector& sampler_bindings = + shader.GetSamplerBindingsAfterTranslation(); + size_t sampler_binding_count = sampler_bindings.size(); + assert_false(bindless_resources_used_ && texture_binding_count + sampler_binding_count > + D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * 4); + size_t texture_binding_layout_bytes = texture_binding_count * sizeof(*texture_bindings.data()); + uint64_t texture_binding_layout_hash = 0; + if (texture_binding_count) { + texture_binding_layout_hash = + XXH3_64bits(texture_bindings.data(), texture_binding_layout_bytes); + } + size_t bindless_sampler_count = bindless_resources_used_ ? sampler_binding_count : 0; + uint64_t bindless_sampler_layout_hash = 0; + if (bindless_sampler_count) { + XXH3_state_t hash_state; + XXH3_64bits_reset(&hash_state); + for (size_t i = 0; i < bindless_sampler_count; ++i) { + XXH3_64bits_update(&hash_state, &sampler_bindings[i].bindless_descriptor_index, + sizeof(sampler_bindings[i].bindless_descriptor_index)); + } + bindless_sampler_layout_hash = XXH3_64bits_digest(&hash_state); + } + // Obtain the unique IDs of binding layouts if there are any texture + // bindings or bindless samplers, for invalidation in the command processor. + size_t texture_binding_layout_uid = kLayoutUIDEmpty; + // Use sampler count for the bindful case because it's the only thing that + // must be the same for layouts to be compatible in this case + // (instruction-specified parameters are used as overrides for actual + // samplers). + static_assert(kLayoutUIDEmpty == 0, + "Empty layout UID is assumed to be 0 because for bindful samplers, the " + "UID is their count"); + size_t sampler_binding_layout_uid = + bindless_resources_used_ ? kLayoutUIDEmpty : sampler_binding_count; + if (texture_binding_count || bindless_sampler_count) { + std::lock_guard layouts_lock(layouts_mutex_); + if (texture_binding_count) { + auto found_range = texture_binding_layout_map_.equal_range(texture_binding_layout_hash); + for (auto it = found_range.first; it != found_range.second; ++it) { + if (it->second.vector_span_length == texture_binding_count && + !std::memcmp(texture_binding_layouts_.data() + it->second.vector_span_offset, + texture_bindings.data(), texture_binding_layout_bytes)) { + texture_binding_layout_uid = it->second.uid; + break; + } + } + if (texture_binding_layout_uid == kLayoutUIDEmpty) { + static_assert(kLayoutUIDEmpty == 0, + "Layout UID is size + 1 because it's assumed that 0 is the UID " + "for an empty layout"); + texture_binding_layout_uid = texture_binding_layout_map_.size() + 1; + LayoutUID new_uid; + new_uid.uid = texture_binding_layout_uid; + new_uid.vector_span_offset = texture_binding_layouts_.size(); + new_uid.vector_span_length = texture_binding_count; + texture_binding_layouts_.resize(new_uid.vector_span_offset + texture_binding_count); + std::memcpy(texture_binding_layouts_.data() + new_uid.vector_span_offset, + texture_bindings.data(), texture_binding_layout_bytes); + texture_binding_layout_map_.emplace(texture_binding_layout_hash, new_uid); + } + } + if (bindless_sampler_count) { + auto found_range = bindless_sampler_layout_map_.equal_range(sampler_binding_layout_uid); + for (auto it = found_range.first; it != found_range.second; ++it) { + if (it->second.vector_span_length != bindless_sampler_count) { + continue; + } + sampler_binding_layout_uid = it->second.uid; + const uint32_t* vector_bindless_sampler_layout = + bindless_sampler_layouts_.data() + it->second.vector_span_offset; + for (size_t i = 0; i < bindless_sampler_count; ++i) { + if (vector_bindless_sampler_layout[i] != + sampler_bindings[i].bindless_descriptor_index) { + sampler_binding_layout_uid = kLayoutUIDEmpty; + break; + } + } + if (sampler_binding_layout_uid != kLayoutUIDEmpty) { + break; + } + } + if (sampler_binding_layout_uid == kLayoutUIDEmpty) { + sampler_binding_layout_uid = bindless_sampler_layout_map_.size(); + LayoutUID new_uid; + static_assert(kLayoutUIDEmpty == 0, + "Layout UID is size + 1 because it's assumed that 0 is the UID " + "for an empty layout"); + new_uid.uid = sampler_binding_layout_uid + 1; + new_uid.vector_span_offset = bindless_sampler_layouts_.size(); + new_uid.vector_span_length = sampler_binding_count; + bindless_sampler_layouts_.resize(new_uid.vector_span_offset + sampler_binding_count); + uint32_t* vector_bindless_sampler_layout = + bindless_sampler_layouts_.data() + new_uid.vector_span_offset; + for (size_t i = 0; i < bindless_sampler_count; ++i) { + vector_bindless_sampler_layout[i] = sampler_bindings[i].bindless_descriptor_index; + } + bindless_sampler_layout_map_.emplace(bindless_sampler_layout_hash, new_uid); + } + } + } + shader.SetTextureBindingLayoutUserUID(texture_binding_layout_uid); + shader.SetSamplerBindingLayoutUserUID(sampler_binding_layout_uid); + } + + // Disassemble the shader for dumping. + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + if (REXCVAR_GET(d3d12_dxbc_disasm_dxilconv)) { + translation.DisassembleDxbcAndDxil(provider, REXCVAR_GET(d3d12_dxbc_disasm), dxbc_converter, + dxc_utils, dxc_compiler); + } else { + translation.DisassembleDxbcAndDxil(provider, REXCVAR_GET(d3d12_dxbc_disasm)); + } + + // Dump shader files if desired. + if (!REXCVAR_GET(dump_shaders).empty()) { + bool edram_rov_used = + render_target_cache_.GetPath() == RenderTargetCache::Path::kPixelShaderInterlock; + translation.Dump(REXCVAR_GET(dump_shaders), (shader.type() == xenos::ShaderType::kPixel) + ? (edram_rov_used ? "d3d12_rov" : "d3d12_rtv") + : "d3d12"); + } + + return translation.is_valid(); +} + +bool PipelineCache::GetCurrentStateDescription( + D3D12Shader::D3D12Translation* vertex_shader, D3D12Shader::D3D12Translation* pixel_shader, + const PrimitiveProcessor::ProcessingResult& primitive_processing_result, + reg::RB_DEPTHCONTROL normalized_depth_control, uint32_t normalized_color_mask, + uint32_t bound_depth_and_color_render_target_bits, + const uint32_t* bound_depth_and_color_render_target_formats, + PipelineRuntimeDescription& runtime_description_out, bool for_placeholder) { + // Translated shaders needed at least for the root signature, unless in + // placeholder mode (async compilation) where both VS and PS translation + // may be deferred to background threads. + assert_true(for_placeholder || (vertex_shader->is_translated() && vertex_shader->is_valid())); + assert_true(for_placeholder || !pixel_shader || + (pixel_shader->is_translated() && pixel_shader->is_valid())); + + PipelineDescription& description_out = runtime_description_out.description; + + const auto& regs = register_file_; + auto pa_su_sc_mode_cntl = regs.Get(); + + // Initialize all unused fields to zero for comparison/hashing. + std::memset(&runtime_description_out, 0, sizeof(runtime_description_out)); + + assert_true(DxbcShaderTranslator::Modification(vertex_shader->modification()) + .vertex.host_vertex_shader_type == + primitive_processing_result.host_vertex_shader_type); + bool tessellated = primitive_processing_result.IsTessellated(); + bool primitive_polygonal = draw_util::IsPrimitivePolygonal(regs); + bool rasterization_enabled = draw_util::IsRasterizationPotentiallyDone(regs, primitive_polygonal); + // In Direct3D, rasterization (along with pixel counting) is disabled by + // disabling the pixel shader and depth / stencil. However, if rasterization + // should be disabled, the pixel shader must be disabled externally, to ensure + // things like texture binding layout is correct for the shader actually being + // used (don't replace anything here). + if (!rasterization_enabled) { + assert_null(pixel_shader); + if (pixel_shader) { + return false; + } + } + + bool edram_rov_used = + render_target_cache_.GetPath() == RenderTargetCache::Path::kPixelShaderInterlock; + + // Root signature. + runtime_description_out.root_signature = command_processor_.GetRootSignature( + static_cast(&vertex_shader->shader()), + (pixel_shader && !for_placeholder) ? static_cast(&pixel_shader->shader()) + : nullptr, + tessellated); + if (runtime_description_out.root_signature == nullptr) { + return false; + } + + // Vertex shader. + runtime_description_out.vertex_shader = vertex_shader; + description_out.vertex_shader_hash = vertex_shader->shader().ucode_data_hash(); + description_out.vertex_shader_modification = vertex_shader->modification(); + + // Index buffer strip cut value. + if (primitive_processing_result.host_primitive_reset_enabled) { + description_out.strip_cut_index = + primitive_processing_result.host_index_format == xenos::IndexFormat::kInt16 + ? PipelineStripCutIndex::kFFFF + : PipelineStripCutIndex::kFFFFFFFF; + } else { + description_out.strip_cut_index = PipelineStripCutIndex::kNone; + } + + // Host vertex shader type and primitive topology. + if (tessellated) { + description_out.primitive_topology_type_or_tessellation_mode = + uint32_t(primitive_processing_result.tessellation_mode); + } else { + switch (primitive_processing_result.host_primitive_type) { + case xenos::PrimitiveType::kPointList: + description_out.primitive_topology_type_or_tessellation_mode = + uint32_t(PipelinePrimitiveTopologyType::kPoint); + break; + case xenos::PrimitiveType::kLineList: + case xenos::PrimitiveType::kLineStrip: + // Quads are emulated as line lists with adjacency. + case xenos::PrimitiveType::kQuadList: + case xenos::PrimitiveType::k2DLineStrip: + description_out.primitive_topology_type_or_tessellation_mode = + uint32_t(PipelinePrimitiveTopologyType::kLine); + break; + default: + description_out.primitive_topology_type_or_tessellation_mode = + uint32_t(PipelinePrimitiveTopologyType::kTriangle); + break; + } + switch (primitive_processing_result.host_primitive_type) { + case xenos::PrimitiveType::kPointList: + description_out.geometry_shader = PipelineGeometryShader::kPointList; + break; + case xenos::PrimitiveType::kRectangleList: + description_out.geometry_shader = PipelineGeometryShader::kRectangleList; + break; + case xenos::PrimitiveType::kQuadList: + description_out.geometry_shader = PipelineGeometryShader::kQuadList; + break; + default: + description_out.geometry_shader = PipelineGeometryShader::kNone; + break; + } + } + GeometryShaderKey geometry_shader_key; + runtime_description_out.geometry_shader = + GetGeometryShaderKey( + description_out.geometry_shader, + DxbcShaderTranslator::Modification(vertex_shader->modification()), + DxbcShaderTranslator::Modification(pixel_shader ? pixel_shader->modification() : 0), + geometry_shader_key) + ? &GetGeometryShader(geometry_shader_key) + : nullptr; + + // The rest doesn't matter when rasterization is disabled (thus no writing to + // anywhere from post-geometry stages and no samples are counted). + if (!rasterization_enabled) { + description_out.cull_mode = PipelineCullMode::kDisableRasterization; + return true; + } + + // Pixel shader. + if (pixel_shader) { + runtime_description_out.pixel_shader = pixel_shader; + description_out.pixel_shader_hash = pixel_shader->shader().ucode_data_hash(); + description_out.pixel_shader_modification = pixel_shader->modification(); + } + + // Rasterizer state. + // Because Direct3D 12 doesn't support per-side fill mode and depth bias, the + // values to use depends on the current culling state. + // If front faces are culled, use the ones for back faces. + // If back faces are culled, it's the other way around. + // If culling is not enabled, assume the developer wanted to draw things in a + // more special way - so if one side is wireframe or has a depth bias, then + // that's intentional (if both sides have a depth bias, the one for the front + // faces is used, though it's unlikely that they will ever be different - + // SetRenderState sets the same offset for both sides). + // Points fill mode (0) also isn't supported in Direct3D 12, but assume the + // developer didn't want to fill the whole primitive and use wireframe (like + // Xenos fill mode 1). + // Here we also assume that only one side is culled - if two sides are culled, + // rasterization will be disabled externally, or the draw call will be dropped + // early if the vertex shader doesn't export to memory. + bool cull_front, cull_back; + if (primitive_polygonal) { + description_out.front_counter_clockwise = pa_su_sc_mode_cntl.face == 0; + cull_front = pa_su_sc_mode_cntl.cull_front != 0; + cull_back = pa_su_sc_mode_cntl.cull_back != 0; + if (cull_front) { + // The case when both faces are culled should be handled by disabling + // rasterization. + assert_false(cull_back); + description_out.cull_mode = PipelineCullMode::kFront; + } else if (cull_back) { + description_out.cull_mode = PipelineCullMode::kBack; + } else { + description_out.cull_mode = PipelineCullMode::kNone; + } + // With ROV, the depth bias is applied in the pixel shader because + // per-sample depth is needed for MSAA. + if (!cull_front) { + // Front faces aren't culled. + // Direct3D 12, unfortunately, doesn't support point fill mode. + if (pa_su_sc_mode_cntl.polymode_front_ptype != xenos::PolygonType::kTriangles) { + description_out.fill_mode_wireframe = 1; + } + } + if (!cull_back) { + // Back faces aren't culled. + if (pa_su_sc_mode_cntl.polymode_back_ptype != xenos::PolygonType::kTriangles) { + description_out.fill_mode_wireframe = 1; + } + } + if (pa_su_sc_mode_cntl.poly_mode != xenos::PolygonModeEnable::kDualMode) { + description_out.fill_mode_wireframe = 0; + } + } else { + // Filled front faces only, without culling. + cull_front = false; + cull_back = false; + } + if (!edram_rov_used) { + float polygon_offset, polygon_offset_scale; + draw_util::GetPreferredFacePolygonOffset(regs, primitive_polygonal, polygon_offset_scale, + polygon_offset); + description_out.depth_bias = draw_util::GetD3D10IntegerPolygonOffset( + regs.Get().depth_format, polygon_offset); + description_out.depth_bias_slope_scaled = + polygon_offset_scale * xenos::kPolygonOffsetScaleSubpixelUnit; + } + if (tessellated && REXCVAR_GET(d3d12_tessellation_wireframe)) { + description_out.fill_mode_wireframe = 1; + } + description_out.depth_clip = !regs.Get().clip_disable; + bool depth_stencil_bound_and_used = false; + if (!edram_rov_used) { + // Depth/stencil. No stencil, always passing depth test and no depth writing + // means depth disabled. + if (bound_depth_and_color_render_target_bits & 1) { + if (normalized_depth_control.z_enable) { + description_out.depth_func = normalized_depth_control.zfunc; + description_out.depth_write = normalized_depth_control.z_write_enable; + } else { + description_out.depth_func = xenos::CompareFunction::kAlways; + } + if (normalized_depth_control.stencil_enable) { + description_out.stencil_enable = 1; + bool stencil_backface_enable = + primitive_polygonal && normalized_depth_control.backface_enable; + // Per-face masks not supported by Direct3D 12, choose the back face + // ones only if drawing only back faces. + Register stencil_ref_mask_reg; + if (stencil_backface_enable && cull_front) { + stencil_ref_mask_reg = XE_GPU_REG_RB_STENCILREFMASK_BF; + } else { + stencil_ref_mask_reg = XE_GPU_REG_RB_STENCILREFMASK; + } + auto stencil_ref_mask = regs.Get(stencil_ref_mask_reg); + description_out.stencil_read_mask = stencil_ref_mask.stencilmask; + description_out.stencil_write_mask = stencil_ref_mask.stencilwritemask; + description_out.stencil_front_fail_op = normalized_depth_control.stencilfail; + description_out.stencil_front_depth_fail_op = normalized_depth_control.stencilzfail; + description_out.stencil_front_pass_op = normalized_depth_control.stencilzpass; + description_out.stencil_front_func = normalized_depth_control.stencilfunc; + if (stencil_backface_enable) { + description_out.stencil_back_fail_op = normalized_depth_control.stencilfail_bf; + description_out.stencil_back_depth_fail_op = normalized_depth_control.stencilzfail_bf; + description_out.stencil_back_pass_op = normalized_depth_control.stencilzpass_bf; + description_out.stencil_back_func = normalized_depth_control.stencilfunc_bf; + } else { + description_out.stencil_back_fail_op = description_out.stencil_front_fail_op; + description_out.stencil_back_depth_fail_op = description_out.stencil_front_depth_fail_op; + description_out.stencil_back_pass_op = description_out.stencil_front_pass_op; + description_out.stencil_back_func = description_out.stencil_front_func; + } + } + // If not binding the DSV, ignore the format in the hash. + if (description_out.depth_func != xenos::CompareFunction::kAlways || + description_out.depth_write || description_out.stencil_enable) { + description_out.depth_format = + xenos::DepthRenderTargetFormat(bound_depth_and_color_render_target_formats[0]); + depth_stencil_bound_and_used = true; + } + } else { + description_out.depth_func = xenos::CompareFunction::kAlways; + } + + // Render targets and blending state. 32 because of 0x1F mask, for safety + // (all unknown to zero). + static const PipelineBlendFactor kBlendFactorMap[32] = { + /* 0 */ PipelineBlendFactor::kZero, + /* 1 */ PipelineBlendFactor::kOne, + /* 2 */ PipelineBlendFactor::kZero, // ? + /* 3 */ PipelineBlendFactor::kZero, // ? + /* 4 */ PipelineBlendFactor::kSrcColor, + /* 5 */ PipelineBlendFactor::kInvSrcColor, + /* 6 */ PipelineBlendFactor::kSrcAlpha, + /* 7 */ PipelineBlendFactor::kInvSrcAlpha, + /* 8 */ PipelineBlendFactor::kDestColor, + /* 9 */ PipelineBlendFactor::kInvDestColor, + /* 10 */ PipelineBlendFactor::kDestAlpha, + /* 11 */ PipelineBlendFactor::kInvDestAlpha, + // CONSTANT_COLOR + /* 12 */ PipelineBlendFactor::kBlendFactor, + // ONE_MINUS_CONSTANT_COLOR + /* 13 */ PipelineBlendFactor::kInvBlendFactor, + // CONSTANT_ALPHA + /* 14 */ PipelineBlendFactor::kBlendFactor, + // ONE_MINUS_CONSTANT_ALPHA + /* 15 */ PipelineBlendFactor::kInvBlendFactor, + /* 16 */ PipelineBlendFactor::kSrcAlphaSat, + }; + // Like kBlendFactorMap, but with color modes changed to alpha. Some + // pipelines aren't created in 545407E0 because a color mode is used for + // alpha. + static const PipelineBlendFactor kBlendFactorAlphaMap[32] = { + /* 0 */ PipelineBlendFactor::kZero, + /* 1 */ PipelineBlendFactor::kOne, + /* 2 */ PipelineBlendFactor::kZero, // ? + /* 3 */ PipelineBlendFactor::kZero, // ? + /* 4 */ PipelineBlendFactor::kSrcAlpha, + /* 5 */ PipelineBlendFactor::kInvSrcAlpha, + /* 6 */ PipelineBlendFactor::kSrcAlpha, + /* 7 */ PipelineBlendFactor::kInvSrcAlpha, + /* 8 */ PipelineBlendFactor::kDestAlpha, + /* 9 */ PipelineBlendFactor::kInvDestAlpha, + /* 10 */ PipelineBlendFactor::kDestAlpha, + /* 11 */ PipelineBlendFactor::kInvDestAlpha, + /* 12 */ PipelineBlendFactor::kBlendFactor, + // ONE_MINUS_CONSTANT_COLOR + /* 13 */ PipelineBlendFactor::kInvBlendFactor, + // CONSTANT_ALPHA + /* 14 */ PipelineBlendFactor::kBlendFactor, + // ONE_MINUS_CONSTANT_ALPHA + /* 15 */ PipelineBlendFactor::kInvBlendFactor, + /* 16 */ PipelineBlendFactor::kSrcAlphaSat, + }; + // While it's okay to specify fewer render targets in the pipeline state + // (even fewer than written by the shader) than actually bound to the + // command list (though this kind of truncation may only happen at the end - + // DXGI_FORMAT_UNKNOWN *requires* a null RTV descriptor to be bound), not + // doing that because sample counts of all render targets bound via + // OMSetRenderTargets, even those beyond NumRenderTargets, apparently must + // have their sample count matching the one set in the pipeline - however if + // we set NumRenderTargets to 0 and also disable depth / stencil, the sample + // count must be set to 1 - while the command list may still have + // multisampled render targets bound (happens in 4D5307E6 main menu). + // TODO(Triang3l): Investigate interaction of OMSetRenderTargets with + // non-null depth and DSVFormat DXGI_FORMAT_UNKNOWN in the same case. + for (uint32_t i = 0; i < 4; ++i) { + if (!(bound_depth_and_color_render_target_bits & (uint32_t(1) << (1 + i)))) { + continue; + } + PipelineRenderTarget& rt = description_out.render_targets[i]; + rt.used = 1; + auto color_info = regs.Get(reg::RB_COLOR_INFO::rt_register_indices[i]); + rt.format = + xenos::ColorRenderTargetFormat(bound_depth_and_color_render_target_formats[1 + i]); + rt.write_mask = (normalized_color_mask >> (i * 4)) & 0xF; + if (rt.write_mask) { + auto blendcontrol = + regs.Get(reg::RB_BLENDCONTROL::rt_register_indices[i]); + rt.src_blend = kBlendFactorMap[uint32_t(blendcontrol.color_srcblend)]; + rt.dest_blend = kBlendFactorMap[uint32_t(blendcontrol.color_destblend)]; + rt.blend_op = blendcontrol.color_comb_fcn; + rt.src_blend_alpha = kBlendFactorAlphaMap[uint32_t(blendcontrol.alpha_srcblend)]; + rt.dest_blend_alpha = kBlendFactorAlphaMap[uint32_t(blendcontrol.alpha_destblend)]; + rt.blend_op_alpha = blendcontrol.alpha_comb_fcn; + } else { + rt.src_blend = PipelineBlendFactor::kOne; + rt.dest_blend = PipelineBlendFactor::kZero; + rt.blend_op = xenos::BlendOp::kAdd; + rt.src_blend_alpha = PipelineBlendFactor::kOne; + rt.dest_blend_alpha = PipelineBlendFactor::kZero; + rt.blend_op_alpha = xenos::BlendOp::kAdd; + } + } + } + xenos::MsaaSamples host_msaa_samples = regs.Get().msaa_samples; + if (edram_rov_used) { + if (host_msaa_samples == xenos::MsaaSamples::k2X) { + // 2 is not supported in ForcedSampleCount on Nvidia. + host_msaa_samples = xenos::MsaaSamples::k4X; + } + } else { + if (!(bound_depth_and_color_render_target_bits & ~uint32_t(1)) && + !depth_stencil_bound_and_used) { + // Direct3D 12 requires the sample count to be 1 when no color or depth / + // stencil render targets are bound. + // FIXME(Triang3l): Use ForcedSampleCount or some other fallback for + // sample counting when needed, though with 2x it will be as incorrect as + // with 1x / 4x anyway; or bind a dummy depth / stencil buffer if really + // needed. + host_msaa_samples = xenos::MsaaSamples::k1X; + } + // TODO(Triang3l): 4x MSAA fallback when 2x isn't supported. + } + description_out.host_msaa_samples = host_msaa_samples; + + return true; +} + +bool PipelineCache::GetGeometryShaderKey( + PipelineGeometryShader geometry_shader_type, + DxbcShaderTranslator::Modification vertex_shader_modification, + DxbcShaderTranslator::Modification pixel_shader_modification, GeometryShaderKey& key_out) { + if (geometry_shader_type == PipelineGeometryShader::kNone) { + return false; + } + assert_true(vertex_shader_modification.vertex.interpolator_mask == + pixel_shader_modification.pixel.interpolator_mask); + GeometryShaderKey key; + key.type = geometry_shader_type; + key.interpolator_count = rex::bit_count(vertex_shader_modification.vertex.interpolator_mask); + key.user_clip_plane_count = vertex_shader_modification.vertex.user_clip_plane_count; + key.user_clip_plane_cull = vertex_shader_modification.vertex.user_clip_plane_cull; + key.has_vertex_kill_and = vertex_shader_modification.vertex.vertex_kill_and; + key.has_point_size = vertex_shader_modification.vertex.output_point_size; + key.has_point_coordinates = pixel_shader_modification.pixel.param_gen_point; + key.point_ps_ucp_mode = vertex_shader_modification.vertex.point_ps_ucp_mode; + key_out = key; + return true; +} + +void PipelineCache::CreateDxbcGeometryShader(GeometryShaderKey key, + std::vector& shader_out) { + shader_out.clear(); + uint32_t point_clip_distance_count = key.user_clip_plane_cull ? 0 : key.user_clip_plane_count; + uint32_t point_user_cull_distance_count = + key.type == PipelineGeometryShader::kPointList && key.user_clip_plane_cull + ? key.user_clip_plane_count + : 0; + bool point_recalculate_clip_distances = key.type == PipelineGeometryShader::kPointList && + point_clip_distance_count && key.point_ps_ucp_mode >= 2; + bool point_recalculate_cull_distances = key.type == PipelineGeometryShader::kPointList && + point_user_cull_distance_count && + key.point_ps_ucp_mode >= 3; + + // RDEF, ISGN, OSG5, SHEX, STAT. + constexpr uint32_t kBlobCount = 5; + + // Allocate space for the container header and the blob offsets. + shader_out.resize(sizeof(dxbc::ContainerHeader) / sizeof(uint32_t) + kBlobCount); + uint32_t blob_offset_position_dwords = sizeof(dxbc::ContainerHeader) / sizeof(uint32_t); + uint32_t blob_position_dwords = uint32_t(shader_out.size()); + constexpr uint32_t kBlobHeaderSizeDwords = sizeof(dxbc::BlobHeader) / sizeof(uint32_t); + + uint32_t name_ptr; + + // *************************************************************************** + // Resource definition + // *************************************************************************** + + shader_out[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + uint32_t rdef_position_dwords = blob_position_dwords + kBlobHeaderSizeDwords; + // Not needed, as the next operation done is resize, to allocate the space for + // both the blob header and the resource definition header. + // shader_out.resize(rdef_position_dwords); + + // RDEF header - the actual definitions will be written if needed. + shader_out.resize(rdef_position_dwords + sizeof(dxbc::RdefHeader) / sizeof(uint32_t)); + // Generator name. + dxbc::AppendAlignedString(shader_out, "Xenia"); + { + auto& rdef_header = + *reinterpret_cast(shader_out.data() + rdef_position_dwords); + rdef_header.shader_model = dxbc::RdefShaderModel::kGeometryShader5_1; + rdef_header.compile_flags = + dxbc::kCompileFlagNoPreshader | dxbc::kCompileFlagPreferFlowControl | + dxbc::kCompileFlagIeeeStrictness | dxbc::kCompileFlagAllResourcesBound; + // Generator name is right after the header. + rdef_header.generator_name_ptr = sizeof(dxbc::RdefHeader); + rdef_header.fourcc = dxbc::RdefHeader::FourCC::k5_1; + rdef_header.InitializeSizes(); + } + + uint32_t system_cbuffer_size_vector_aligned_bytes = 0; + + if (key.type == PipelineGeometryShader::kPointList) { + // Need point parameters from the system constants. + + // Constant types - float2 only. + // Names. + name_ptr = uint32_t((shader_out.size() - rdef_position_dwords) * sizeof(uint32_t)); + uint32_t rdef_name_ptr_float2 = name_ptr; + name_ptr += dxbc::AppendAlignedString(shader_out, "float2"); + // Types. + uint32_t rdef_type_float2_position_dwords = uint32_t(shader_out.size()); + uint32_t rdef_type_float2_ptr = + uint32_t((rdef_type_float2_position_dwords - rdef_position_dwords) * sizeof(uint32_t)); + shader_out.resize(rdef_type_float2_position_dwords + sizeof(dxbc::RdefType) / sizeof(uint32_t)); + { + auto& rdef_type_float2 = + *reinterpret_cast(shader_out.data() + rdef_type_float2_position_dwords); + rdef_type_float2.variable_class = dxbc::RdefVariableClass::kVector; + rdef_type_float2.variable_type = dxbc::RdefVariableType::kFloat; + rdef_type_float2.row_count = 1; + rdef_type_float2.column_count = 2; + rdef_type_float2.name_ptr = rdef_name_ptr_float2; + } + + // Constants: + // - float2 xe_point_constant_diameter + // - float2 xe_point_screen_diameter_to_ndc_radius + enum PointConstant : uint32_t { + kPointConstantConstantDiameter, + kPointConstantScreenDiameterToNDCRadius, + kPointConstantCount, + }; + // Names. + name_ptr = uint32_t((shader_out.size() - rdef_position_dwords) * sizeof(uint32_t)); + uint32_t rdef_name_ptr_xe_point_constant_diameter = name_ptr; + name_ptr += dxbc::AppendAlignedString(shader_out, "xe_point_constant_diameter"); + uint32_t rdef_name_ptr_xe_point_screen_diameter_to_ndc_radius = name_ptr; + name_ptr += dxbc::AppendAlignedString(shader_out, "xe_point_screen_diameter_to_ndc_radius"); + // Constants. + uint32_t rdef_constants_position_dwords = uint32_t(shader_out.size()); + uint32_t rdef_constants_ptr = + uint32_t((rdef_constants_position_dwords - rdef_position_dwords) * sizeof(uint32_t)); + shader_out.resize(rdef_constants_position_dwords + + sizeof(dxbc::RdefVariable) / sizeof(uint32_t) * kPointConstantCount); + { + auto rdef_constants = + reinterpret_cast(shader_out.data() + rdef_constants_position_dwords); + // float2 xe_point_constant_diameter + static_assert(sizeof(DxbcShaderTranslator::SystemConstants ::point_constant_diameter) == + sizeof(float) * 2, + "DxbcShaderTranslator point_constant_diameter system constant size " + "differs between the shader translator and geometry shader " + "generation"); + static_assert_size(DxbcShaderTranslator::SystemConstants::point_constant_diameter, + sizeof(float) * 2); + dxbc::RdefVariable& rdef_constant_point_constant_diameter = + rdef_constants[kPointConstantConstantDiameter]; + rdef_constant_point_constant_diameter.name_ptr = rdef_name_ptr_xe_point_constant_diameter; + rdef_constant_point_constant_diameter.start_offset_bytes = + offsetof(DxbcShaderTranslator::SystemConstants, point_constant_diameter); + rdef_constant_point_constant_diameter.size_bytes = sizeof(float) * 2; + rdef_constant_point_constant_diameter.flags = dxbc::kRdefVariableFlagUsed; + rdef_constant_point_constant_diameter.type_ptr = rdef_type_float2_ptr; + rdef_constant_point_constant_diameter.start_texture = UINT32_MAX; + rdef_constant_point_constant_diameter.start_sampler = UINT32_MAX; + // float2 xe_point_screen_diameter_to_ndc_radius + static_assert( + sizeof(DxbcShaderTranslator::SystemConstants ::point_screen_diameter_to_ndc_radius) == + sizeof(float) * 2, + "DxbcShaderTranslator point_screen_diameter_to_ndc_radius system " + "constant size differs between the shader translator and geometry " + "shader generation"); + dxbc::RdefVariable& rdef_constant_point_screen_diameter_to_ndc_radius = + rdef_constants[kPointConstantScreenDiameterToNDCRadius]; + rdef_constant_point_screen_diameter_to_ndc_radius.name_ptr = + rdef_name_ptr_xe_point_screen_diameter_to_ndc_radius; + rdef_constant_point_screen_diameter_to_ndc_radius.start_offset_bytes = + offsetof(DxbcShaderTranslator::SystemConstants, point_screen_diameter_to_ndc_radius); + rdef_constant_point_screen_diameter_to_ndc_radius.size_bytes = sizeof(float) * 2; + rdef_constant_point_screen_diameter_to_ndc_radius.flags = dxbc::kRdefVariableFlagUsed; + rdef_constant_point_screen_diameter_to_ndc_radius.type_ptr = rdef_type_float2_ptr; + rdef_constant_point_screen_diameter_to_ndc_radius.start_texture = UINT32_MAX; + rdef_constant_point_screen_diameter_to_ndc_radius.start_sampler = UINT32_MAX; + } + + // Constant buffers - xe_system_cbuffer only. + + // Names. + name_ptr = uint32_t((shader_out.size() - rdef_position_dwords) * sizeof(uint32_t)); + uint32_t rdef_name_ptr_xe_system_cbuffer = name_ptr; + name_ptr += dxbc::AppendAlignedString(shader_out, "xe_system_cbuffer"); + // Constant buffers. + uint32_t rdef_cbuffer_position_dwords = uint32_t(shader_out.size()); + shader_out.resize(rdef_cbuffer_position_dwords + sizeof(dxbc::RdefCbuffer) / sizeof(uint32_t)); + { + auto& rdef_cbuffer_system = + *reinterpret_cast(shader_out.data() + rdef_cbuffer_position_dwords); + rdef_cbuffer_system.name_ptr = rdef_name_ptr_xe_system_cbuffer; + rdef_cbuffer_system.variable_count = kPointConstantCount; + rdef_cbuffer_system.variables_ptr = rdef_constants_ptr; + auto rdef_constants = reinterpret_cast( + shader_out.data() + rdef_constants_position_dwords); + for (uint32_t i = 0; i < kPointConstantCount; ++i) { + system_cbuffer_size_vector_aligned_bytes = + std::max(system_cbuffer_size_vector_aligned_bytes, + rdef_constants[i].start_offset_bytes + rdef_constants[i].size_bytes); + } + if (point_recalculate_clip_distances || point_recalculate_cull_distances) { + system_cbuffer_size_vector_aligned_bytes = + std::max(system_cbuffer_size_vector_aligned_bytes, + uint32_t(offsetof(DxbcShaderTranslator::SystemConstants, ndc_scale) + + sizeof(float) * 3)); + system_cbuffer_size_vector_aligned_bytes = + std::max(system_cbuffer_size_vector_aligned_bytes, + uint32_t(offsetof(DxbcShaderTranslator::SystemConstants, ndc_offset) + + sizeof(float) * 3)); + system_cbuffer_size_vector_aligned_bytes = + std::max(system_cbuffer_size_vector_aligned_bytes, + uint32_t(offsetof(DxbcShaderTranslator::SystemConstants, user_clip_planes) + + sizeof(float) * 4 * 6)); + } + system_cbuffer_size_vector_aligned_bytes = + rex::align(system_cbuffer_size_vector_aligned_bytes, uint32_t(sizeof(uint32_t) * 4)); + rdef_cbuffer_system.size_vector_aligned_bytes = system_cbuffer_size_vector_aligned_bytes; + } + + // Bindings - xe_system_cbuffer only. + uint32_t rdef_binding_position_dwords = uint32_t(shader_out.size()); + shader_out.resize(rdef_binding_position_dwords + + sizeof(dxbc::RdefInputBind) / sizeof(uint32_t)); + { + auto& rdef_binding_cbuffer_system = + *reinterpret_cast(shader_out.data() + rdef_binding_position_dwords); + rdef_binding_cbuffer_system.name_ptr = rdef_name_ptr_xe_system_cbuffer; + rdef_binding_cbuffer_system.type = dxbc::RdefInputType::kCbuffer; + rdef_binding_cbuffer_system.bind_point = + uint32_t(DxbcShaderTranslator::CbufferRegister::kSystemConstants); + rdef_binding_cbuffer_system.bind_count = 1; + rdef_binding_cbuffer_system.flags = dxbc::kRdefInputFlagUserPacked; + } + + // Pointers in the header. + { + auto& rdef_header = + *reinterpret_cast(shader_out.data() + rdef_position_dwords); + rdef_header.cbuffer_count = 1; + rdef_header.cbuffers_ptr = + uint32_t((rdef_cbuffer_position_dwords - rdef_position_dwords) * sizeof(uint32_t)); + rdef_header.input_bind_count = 1; + rdef_header.input_binds_ptr = + uint32_t((rdef_binding_position_dwords - rdef_position_dwords) * sizeof(uint32_t)); + } + } + + { + auto& blob_header = + *reinterpret_cast(shader_out.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kResourceDefinition; + blob_position_dwords = uint32_t(shader_out.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + shader_out[blob_offset_position_dwords++]; + } + + // *************************************************************************** + // Input signature + // *************************************************************************** + + // Clip and cull distances are tightly packed together into registers, but + // have separate signature parameters with each being a vec4-aligned window. + uint32_t input_clip_distance_count = key.user_clip_plane_cull ? 0 : key.user_clip_plane_count; + uint32_t input_cull_distance_count = + (key.user_clip_plane_cull ? key.user_clip_plane_count : 0) + key.has_vertex_kill_and; + uint32_t input_clip_and_cull_distance_count = + input_clip_distance_count + input_cull_distance_count; + + // Interpolators, position, clip and cull distances (parameters containing + // only clip or cull distances, and also one parameter containing both if + // present), point size. + uint32_t isgn_parameter_count = + key.interpolator_count + 1 + ((input_clip_and_cull_distance_count + 3) / 4) + + uint32_t(input_cull_distance_count && (input_clip_distance_count & 3) != 0) + + key.has_point_size; + + // Reserve space for the header and the parameters. + shader_out[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + uint32_t isgn_position_dwords = blob_position_dwords + kBlobHeaderSizeDwords; + shader_out.resize(isgn_position_dwords + sizeof(dxbc::Signature) / sizeof(uint32_t) + + sizeof(dxbc::SignatureParameter) / sizeof(uint32_t) * isgn_parameter_count); + + // Names (after the parameters). + name_ptr = uint32_t((shader_out.size() - isgn_position_dwords) * sizeof(uint32_t)); + uint32_t isgn_name_ptr_texcoord = name_ptr; + if (key.interpolator_count) { + name_ptr += dxbc::AppendAlignedString(shader_out, "TEXCOORD"); + } + uint32_t isgn_name_ptr_sv_position = name_ptr; + name_ptr += dxbc::AppendAlignedString(shader_out, "SV_Position"); + uint32_t isgn_name_ptr_sv_clip_distance = name_ptr; + if (input_clip_distance_count) { + name_ptr += dxbc::AppendAlignedString(shader_out, "SV_ClipDistance"); + } + uint32_t isgn_name_ptr_sv_cull_distance = name_ptr; + if (input_cull_distance_count) { + name_ptr += dxbc::AppendAlignedString(shader_out, "SV_CullDistance"); + } + uint32_t isgn_name_ptr_xepsize = name_ptr; + if (key.has_point_size) { + name_ptr += dxbc::AppendAlignedString(shader_out, "XEPSIZE"); + } + + // Header and parameters. + uint32_t input_register_interpolators = UINT32_MAX; + uint32_t input_register_position; + uint32_t input_register_clip_and_cull_distances = UINT32_MAX; + uint32_t input_register_point_size = UINT32_MAX; + { + // Header. + auto& isgn_header = + *reinterpret_cast(shader_out.data() + isgn_position_dwords); + isgn_header.parameter_count = isgn_parameter_count; + isgn_header.parameter_info_ptr = sizeof(dxbc::Signature); + + // Parameters. + auto isgn_parameters = reinterpret_cast( + shader_out.data() + isgn_position_dwords + sizeof(dxbc::Signature) / sizeof(uint32_t)); + uint32_t isgn_parameter_index = 0; + uint32_t input_register_index = 0; + + // Interpolators (TEXCOORD#). + if (key.interpolator_count) { + input_register_interpolators = input_register_index; + for (uint32_t i = 0; i < key.interpolator_count; ++i) { + assert_true(isgn_parameter_index < isgn_parameter_count); + dxbc::SignatureParameter& isgn_interpolator = isgn_parameters[isgn_parameter_index++]; + isgn_interpolator.semantic_name_ptr = isgn_name_ptr_texcoord; + isgn_interpolator.semantic_index = i; + isgn_interpolator.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + isgn_interpolator.register_index = input_register_index++; + isgn_interpolator.mask = 0b1111; + isgn_interpolator.always_reads_mask = 0b1111; + } + } + + // Position (SV_Position). + input_register_position = input_register_index; + assert_true(isgn_parameter_index < isgn_parameter_count); + dxbc::SignatureParameter& isgn_sv_position = isgn_parameters[isgn_parameter_index++]; + isgn_sv_position.semantic_name_ptr = isgn_name_ptr_sv_position; + isgn_sv_position.system_value = dxbc::Name::kPosition; + isgn_sv_position.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + isgn_sv_position.register_index = input_register_index++; + isgn_sv_position.mask = 0b1111; + isgn_sv_position.always_reads_mask = 0b1111; + + // Clip and cull distances (SV_ClipDistance#, SV_CullDistance#). + if (input_clip_and_cull_distance_count) { + input_register_clip_and_cull_distances = input_register_index; + uint32_t isgn_cull_distance_semantic_index = 0; + for (uint32_t i = 0; i < input_clip_and_cull_distance_count; i += 4) { + if (i < input_clip_distance_count) { + dxbc::SignatureParameter& isgn_sv_clip_distance = isgn_parameters[isgn_parameter_index++]; + isgn_sv_clip_distance.semantic_name_ptr = isgn_name_ptr_sv_clip_distance; + isgn_sv_clip_distance.semantic_index = i / 4; + isgn_sv_clip_distance.system_value = dxbc::Name::kClipDistance; + isgn_sv_clip_distance.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + isgn_sv_clip_distance.register_index = input_register_index; + uint8_t isgn_sv_clip_distance_mask = + (UINT8_C(1) << std::min(input_clip_distance_count - i, UINT32_C(4))) - 1; + isgn_sv_clip_distance.mask = isgn_sv_clip_distance_mask; + isgn_sv_clip_distance.always_reads_mask = isgn_sv_clip_distance_mask; + } + if (input_cull_distance_count && i + 4 > input_clip_distance_count) { + dxbc::SignatureParameter& isgn_sv_cull_distance = isgn_parameters[isgn_parameter_index++]; + isgn_sv_cull_distance.semantic_name_ptr = isgn_name_ptr_sv_cull_distance; + isgn_sv_cull_distance.semantic_index = isgn_cull_distance_semantic_index++; + isgn_sv_cull_distance.system_value = dxbc::Name::kCullDistance; + isgn_sv_cull_distance.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + isgn_sv_cull_distance.register_index = input_register_index; + uint8_t isgn_sv_cull_distance_mask = + (UINT8_C(1) << std::min(input_clip_and_cull_distance_count - i, UINT32_C(4))) - 1; + if (i < input_clip_distance_count) { + isgn_sv_cull_distance_mask &= ~((UINT8_C(1) << (input_clip_distance_count - i)) - 1); + } + isgn_sv_cull_distance.mask = isgn_sv_cull_distance_mask; + isgn_sv_cull_distance.always_reads_mask = isgn_sv_cull_distance_mask; + } + ++input_register_index; + } + } + + // Point size (XEPSIZE). + if (key.has_point_size) { + input_register_point_size = input_register_index; + assert_true(isgn_parameter_index < isgn_parameter_count); + dxbc::SignatureParameter& isgn_point_size = isgn_parameters[isgn_parameter_index++]; + isgn_point_size.semantic_name_ptr = isgn_name_ptr_xepsize; + isgn_point_size.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + isgn_point_size.register_index = input_register_index++; + isgn_point_size.mask = 0b0001; + isgn_point_size.always_reads_mask = + key.type == PipelineGeometryShader::kPointList ? 0b0001 : 0; + } + + assert_true(isgn_parameter_index == isgn_parameter_count); + } + + { + auto& blob_header = + *reinterpret_cast(shader_out.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kInputSignature; + blob_position_dwords = uint32_t(shader_out.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + shader_out[blob_offset_position_dwords++]; + } + + // *************************************************************************** + // Output signature + // *************************************************************************** + + // Interpolators, point coordinates, position, clip distances. + uint32_t osgn_parameter_count = key.interpolator_count + key.has_point_coordinates + 1 + + ((input_clip_distance_count + 3) / 4); + + // Reserve space for the header and the parameters. + shader_out[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + uint32_t osgn_position_dwords = blob_position_dwords + kBlobHeaderSizeDwords; + shader_out.resize(osgn_position_dwords + sizeof(dxbc::Signature) / sizeof(uint32_t) + + sizeof(dxbc::SignatureParameterForGS) / sizeof(uint32_t) * + osgn_parameter_count); + + // Names (after the parameters). + name_ptr = uint32_t((shader_out.size() - osgn_position_dwords) * sizeof(uint32_t)); + uint32_t osgn_name_ptr_texcoord = name_ptr; + if (key.interpolator_count) { + name_ptr += dxbc::AppendAlignedString(shader_out, "TEXCOORD"); + } + uint32_t osgn_name_ptr_xespritetexcoord = name_ptr; + if (key.has_point_coordinates) { + name_ptr += dxbc::AppendAlignedString(shader_out, "XESPRITETEXCOORD"); + } + uint32_t osgn_name_ptr_sv_position = name_ptr; + name_ptr += dxbc::AppendAlignedString(shader_out, "SV_Position"); + uint32_t osgn_name_ptr_sv_clip_distance = name_ptr; + if (input_clip_distance_count) { + name_ptr += dxbc::AppendAlignedString(shader_out, "SV_ClipDistance"); + } + + // Header and parameters. + uint32_t output_register_interpolators = UINT32_MAX; + uint32_t output_register_point_coordinates = UINT32_MAX; + uint32_t output_register_position; + uint32_t output_register_clip_distances = UINT32_MAX; + { + // Header. + auto& osgn_header = + *reinterpret_cast(shader_out.data() + osgn_position_dwords); + osgn_header.parameter_count = osgn_parameter_count; + osgn_header.parameter_info_ptr = sizeof(dxbc::Signature); + + // Parameters. + auto osgn_parameters = reinterpret_cast( + shader_out.data() + osgn_position_dwords + sizeof(dxbc::Signature) / sizeof(uint32_t)); + uint32_t osgn_parameter_index = 0; + uint32_t output_register_index = 0; + + // Interpolators (TEXCOORD#). + if (key.interpolator_count) { + output_register_interpolators = output_register_index; + for (uint32_t i = 0; i < key.interpolator_count; ++i) { + assert_true(osgn_parameter_index < osgn_parameter_count); + dxbc::SignatureParameterForGS& osgn_interpolator = osgn_parameters[osgn_parameter_index++]; + osgn_interpolator.semantic_name_ptr = osgn_name_ptr_texcoord; + osgn_interpolator.semantic_index = i; + osgn_interpolator.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + osgn_interpolator.register_index = output_register_index++; + osgn_interpolator.mask = 0b1111; + } + } + + // Point coordinates (XESPRITETEXCOORD). + if (key.has_point_coordinates) { + output_register_point_coordinates = output_register_index; + assert_true(osgn_parameter_index < osgn_parameter_count); + dxbc::SignatureParameterForGS& osgn_point_coordinates = + osgn_parameters[osgn_parameter_index++]; + osgn_point_coordinates.semantic_name_ptr = osgn_name_ptr_xespritetexcoord; + osgn_point_coordinates.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + osgn_point_coordinates.register_index = output_register_index++; + osgn_point_coordinates.mask = 0b0011; + osgn_point_coordinates.never_writes_mask = 0b1100; + } + + // Position (SV_Position). + output_register_position = output_register_index; + assert_true(osgn_parameter_index < osgn_parameter_count); + dxbc::SignatureParameterForGS& osgn_sv_position = osgn_parameters[osgn_parameter_index++]; + osgn_sv_position.semantic_name_ptr = osgn_name_ptr_sv_position; + osgn_sv_position.system_value = dxbc::Name::kPosition; + osgn_sv_position.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + osgn_sv_position.register_index = output_register_index++; + osgn_sv_position.mask = 0b1111; + + // Clip distances (SV_ClipDistance#). + if (input_clip_distance_count) { + output_register_clip_distances = output_register_index; + for (uint32_t i = 0; i < input_clip_distance_count; i += 4) { + dxbc::SignatureParameterForGS& osgn_sv_clip_distance = + osgn_parameters[osgn_parameter_index++]; + osgn_sv_clip_distance.semantic_name_ptr = osgn_name_ptr_sv_clip_distance; + osgn_sv_clip_distance.semantic_index = i / 4; + osgn_sv_clip_distance.system_value = dxbc::Name::kClipDistance; + osgn_sv_clip_distance.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + osgn_sv_clip_distance.register_index = output_register_index++; + uint8_t osgn_sv_clip_distance_mask = + (UINT8_C(1) << std::min(input_clip_distance_count - i, UINT32_C(4))) - 1; + osgn_sv_clip_distance.mask = osgn_sv_clip_distance_mask; + osgn_sv_clip_distance.never_writes_mask = osgn_sv_clip_distance_mask ^ 0b1111; + } + } + + assert_true(osgn_parameter_index == osgn_parameter_count); + } + + { + auto& blob_header = + *reinterpret_cast(shader_out.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kOutputSignatureForGS; + blob_position_dwords = uint32_t(shader_out.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + shader_out[blob_offset_position_dwords++]; + } + + // *************************************************************************** + // Shader program + // *************************************************************************** + + shader_out[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + uint32_t shex_position_dwords = blob_position_dwords + kBlobHeaderSizeDwords; + shader_out.resize(shex_position_dwords); + + shader_out.push_back(dxbc::VersionToken(dxbc::ProgramType::kGeometryShader, 5, 1)); + // Reserve space for the length token. + shader_out.push_back(0); + + dxbc::Statistics stat; + std::memset(&stat, 0, sizeof(dxbc::Statistics)); + dxbc::Assembler a(shader_out, stat); + + a.OpDclGlobalFlags(dxbc::kGlobalFlagAllResourcesBound); + + if (system_cbuffer_size_vector_aligned_bytes) { + a.OpDclConstantBuffer( + dxbc::Src::CB(dxbc::Src::Dcl, 0, + uint32_t(DxbcShaderTranslator::CbufferRegister::kSystemConstants), + uint32_t(DxbcShaderTranslator::CbufferRegister::kSystemConstants)), + system_cbuffer_size_vector_aligned_bytes / (sizeof(uint32_t) * 4)); + } + + dxbc::Primitive input_primitive = dxbc::Primitive::kUndefined; + uint32_t input_primitive_vertex_count = 0; + dxbc::PrimitiveTopology output_primitive_topology = dxbc::PrimitiveTopology::kUndefined; + uint32_t max_output_vertex_count = 0; + switch (key.type) { + case PipelineGeometryShader::kPointList: + // Point to a strip of 2 triangles. + input_primitive = dxbc::Primitive::kPoint; + input_primitive_vertex_count = 1; + output_primitive_topology = dxbc::PrimitiveTopology::kTriangleStrip; + max_output_vertex_count = 4; + break; + case PipelineGeometryShader::kRectangleList: + // Triangle to a strip of 2 triangles. + input_primitive = dxbc::Primitive::kTriangle; + input_primitive_vertex_count = 3; + output_primitive_topology = dxbc::PrimitiveTopology::kTriangleStrip; + max_output_vertex_count = 4; + break; + case PipelineGeometryShader::kQuadList: + // 4 vertices passed via kLineWithAdjacency to a strip of 2 triangles. + input_primitive = dxbc::Primitive::kLineWithAdjacency; + input_primitive_vertex_count = 4; + output_primitive_topology = dxbc::PrimitiveTopology::kTriangleStrip; + max_output_vertex_count = 4; + break; + default: + assert_unhandled_case(key.type); + } + + assert_false(key.interpolator_count && input_register_interpolators == UINT32_MAX); + for (uint32_t i = 0; i < key.interpolator_count; ++i) { + a.OpDclInput(dxbc::Dest::V2D(input_primitive_vertex_count, input_register_interpolators + i)); + } + a.OpDclInputSIV(dxbc::Dest::V2D(input_primitive_vertex_count, input_register_position), + dxbc::Name::kPosition); + // Clip and cull plane declarations are separate in FXC-generated code even + // for a single register. + assert_false(input_clip_and_cull_distance_count && + input_register_clip_and_cull_distances == UINT32_MAX); + for (uint32_t i = 0; i < input_clip_and_cull_distance_count; i += 4) { + if (i < input_clip_distance_count) { + a.OpDclInput(dxbc::Dest::V2D( + input_primitive_vertex_count, input_register_clip_and_cull_distances + (i >> 2), + (UINT32_C(1) << std::min(input_clip_distance_count - i, UINT32_C(4))) - 1)); + } + if (input_cull_distance_count && i + 4 > input_clip_distance_count) { + uint32_t cull_distance_mask = + (UINT32_C(1) << std::min(input_clip_and_cull_distance_count - i, UINT32_C(4))) - 1; + if (i < input_clip_distance_count) { + cull_distance_mask &= ~((UINT32_C(1) << (input_clip_distance_count - i)) - 1); + } + a.OpDclInput(dxbc::Dest::V2D(input_primitive_vertex_count, + input_register_clip_and_cull_distances + (i >> 2), + cull_distance_mask)); + } + } + if (key.has_point_size && key.type == PipelineGeometryShader::kPointList) { + assert_true(input_register_point_size != UINT32_MAX); + a.OpDclInput(dxbc::Dest::V2D(input_primitive_vertex_count, input_register_point_size, 0b0001)); + } + + // At least 1 temporary register needed to discard primitives with NaN + // position. + size_t dcl_temps_count_position_dwords = a.OpDclTemps(1); + + a.OpDclInputPrimitive(input_primitive); + dxbc::Dest stream(dxbc::Dest::M(0)); + a.OpDclStream(stream); + a.OpDclOutputTopology(output_primitive_topology); + + assert_false(key.interpolator_count && output_register_interpolators == UINT32_MAX); + for (uint32_t i = 0; i < key.interpolator_count; ++i) { + a.OpDclOutput(dxbc::Dest::O(output_register_interpolators + i)); + } + if (key.has_point_coordinates) { + assert_true(output_register_point_coordinates != UINT32_MAX); + a.OpDclOutput(dxbc::Dest::O(output_register_point_coordinates, 0b0011)); + } + a.OpDclOutputSIV(dxbc::Dest::O(output_register_position), dxbc::Name::kPosition); + assert_false(input_clip_distance_count && output_register_clip_distances == UINT32_MAX); + for (uint32_t i = 0; i < input_clip_distance_count; i += 4) { + a.OpDclOutputSIV( + dxbc::Dest::O(output_register_clip_distances + (i >> 2), + (UINT32_C(1) << std::min(input_clip_distance_count - i, UINT32_C(4))) - 1), + dxbc::Name::kClipDistance); + } + + a.OpDclMaxOutputVertexCount(max_output_vertex_count); + + // Note that after every emit, all o# become initialized and must be written + // to again. + // Also, FXC generates only movs (from statically or dynamically indexed + // v[#][#], from r#, or from a literal) to o# for some reason. + // emit_then_cut_stream must not be used - it crashes the shader compiler of + // AMD Software: Adrenalin Edition 23.3.2 on RDNA 3 if it's conditional (after + // a `retc` or inside an `if`), and it doesn't seem to be generated by FXC or + // DXC at all. + + // Discard the whole primitive if any vertex has a NaN position (may also be + // set to NaN for emulation of vertex killing with the OR operator). + for (uint32_t i = 0; i < input_primitive_vertex_count; ++i) { + a.OpNE(dxbc::Dest::R(0), dxbc::Src::V2D(i, input_register_position), + dxbc::Src::V2D(i, input_register_position)); + a.OpOr(dxbc::Dest::R(0, 0b0011), dxbc::Src::R(0, 0b0100), dxbc::Src::R(0, 0b1110)); + a.OpOr(dxbc::Dest::R(0, 0b0001), dxbc::Src::R(0, dxbc::Src::kXXXX), + dxbc::Src::R(0, dxbc::Src::kYYYY)); + a.OpRetC(true, dxbc::Src::R(0, dxbc::Src::kXXXX)); + } + + // Cull the whole primitive if any cull distance for all vertices in the + // primitive is < 0. + // For point lists with ps_ucp_mode 3, user cull plane distances are + // calculated per expanded vertex later. + if (input_cull_distance_count) { + uint32_t cull_distance_start = + point_recalculate_cull_distances ? point_user_cull_distance_count : 0; + for (uint32_t i = cull_distance_start; i < input_cull_distance_count; ++i) { + uint32_t cull_distance_register = + input_register_clip_and_cull_distances + ((input_clip_distance_count + i) >> 2); + uint32_t cull_distance_component = (input_clip_distance_count + i) & 3; + a.OpLT(dxbc::Dest::R(0, 0b0001), + dxbc::Src::V2D(0, cull_distance_register).Select(cull_distance_component), + dxbc::Src::LF(0.0f)); + for (uint32_t j = 1; j < input_primitive_vertex_count; ++j) { + a.OpLT(dxbc::Dest::R(0, 0b0010), + dxbc::Src::V2D(j, cull_distance_register).Select(cull_distance_component), + dxbc::Src::LF(0.0f)); + a.OpAnd(dxbc::Dest::R(0, 0b0001), dxbc::Src::R(0, dxbc::Src::kXXXX), + dxbc::Src::R(0, dxbc::Src::kYYYY)); + } + a.OpRetC(true, dxbc::Src::R(0, dxbc::Src::kXXXX)); + } + } + + switch (key.type) { + case PipelineGeometryShader::kPointList: { + // Expand the point sprite, with left-to-right, top-to-bottom UVs. + dxbc::Src point_size_src(dxbc::Src::CB( + 0, uint32_t(DxbcShaderTranslator::CbufferRegister::kSystemConstants), + offsetof(DxbcShaderTranslator::SystemConstants, point_constant_diameter) >> 4, + ((offsetof(DxbcShaderTranslator::SystemConstants, point_constant_diameter[0]) >> 2) & 3) | + (((offsetof(DxbcShaderTranslator::SystemConstants, point_constant_diameter[1]) >> 2) & + 3) + << 2))); + if (key.has_point_size) { + // The vertex shader's header writes -1.0 to point_size by default, so + // any non-negative value means that it was overwritten by the + // translated vertex shader, and needs to be used instead of the + // constant size. The per-vertex diameter is already clamped in the + // vertex shader (combined with making it non-negative). + a.OpGE(dxbc::Dest::R(0, 0b0001), + dxbc::Src::V2D(0, input_register_point_size, dxbc::Src::kXXXX), dxbc::Src::LF(0.0f)); + a.OpMovC(dxbc::Dest::R(0, 0b0011), dxbc::Src::R(0, dxbc::Src::kXXXX), + dxbc::Src::V2D(0, input_register_point_size, dxbc::Src::kXXXX), point_size_src); + point_size_src = dxbc::Src::R(0, 0b0100); + } + // 4D5307F1 has zero-size snowflakes, drop them quicker, and also drop + // points with a constant size of zero since point lists may also be used + // as just "compute" with memexport. + // XY may contain the point size with the per-vertex override applied, use + // Z as temporary. + for (uint32_t i = 0; i < 2; ++i) { + a.OpLT(dxbc::Dest::R(0, 0b0100), dxbc::Src::LF(0.0f), point_size_src.SelectFromSwizzled(i)); + a.OpRetC(false, dxbc::Src::R(0, dxbc::Src::kZZZZ)); + } + // Transform the diameter in the guest screen coordinates to radius in the + // normalized device coordinates, and then to the clip space by + // multiplying by W. + a.OpMul(dxbc::Dest::R(0, 0b0011), point_size_src, + dxbc::Src::CB(0, uint32_t(DxbcShaderTranslator::CbufferRegister::kSystemConstants), + offsetof(DxbcShaderTranslator::SystemConstants, + point_screen_diameter_to_ndc_radius) >> + 4, + ((offsetof(DxbcShaderTranslator::SystemConstants, + point_screen_diameter_to_ndc_radius[0]) >> + 2) & + 3) | + (((offsetof(DxbcShaderTranslator::SystemConstants, + point_screen_diameter_to_ndc_radius[1]) >> + 2) & + 3) + << 2))); + point_size_src = dxbc::Src::R(0, 0b0100); + a.OpMul(dxbc::Dest::R(0, 0b0011), point_size_src, + dxbc::Src::V2D(0, input_register_position, dxbc::Src::kWWWW)); + dxbc::Src point_radius_x_src(point_size_src.SelectFromSwizzled(0)); + dxbc::Src point_radius_y_src(point_size_src.SelectFromSwizzled(1)); + + if (point_recalculate_cull_distances) { + stat.temp_register_count = std::max(UINT32_C(4), stat.temp_register_count); + dxbc::Src ndc_scale_xy(dxbc::Src::CB( + 0, uint32_t(DxbcShaderTranslator::CbufferRegister::kSystemConstants), + offsetof(DxbcShaderTranslator::SystemConstants, ndc_scale) >> 4, + ((offsetof(DxbcShaderTranslator::SystemConstants, ndc_scale[0]) >> 2) & 3) | + (((offsetof(DxbcShaderTranslator::SystemConstants, ndc_scale[1]) >> 2) & 3) << 2))); + dxbc::Src ndc_scale_z(dxbc::Src::CB( + 0, uint32_t(DxbcShaderTranslator::CbufferRegister::kSystemConstants), + offsetof(DxbcShaderTranslator::SystemConstants, ndc_scale) >> 4, dxbc::Src::kZZZZ)); + dxbc::Src ndc_offset_xy(dxbc::Src::CB( + 0, uint32_t(DxbcShaderTranslator::CbufferRegister::kSystemConstants), + offsetof(DxbcShaderTranslator::SystemConstants, ndc_offset) >> 4, + ((offsetof(DxbcShaderTranslator::SystemConstants, ndc_offset[0]) >> 2) & 3) | + (((offsetof(DxbcShaderTranslator::SystemConstants, ndc_offset[1]) >> 2) & 3) + << 2))); + dxbc::Src ndc_offset_z(dxbc::Src::CB( + 0, uint32_t(DxbcShaderTranslator::CbufferRegister::kSystemConstants), + offsetof(DxbcShaderTranslator::SystemConstants, ndc_offset) >> 4, dxbc::Src::kZZZZ)); + for (uint32_t j = 0; j < point_user_cull_distance_count; ++j) { + for (uint32_t i = 0; i < 4; ++i) { + a.OpAdd(dxbc::Dest::R(2, 0b0001), + dxbc::Src::V2D(0, input_register_position, dxbc::Src::kXXXX), + (i & 1) ? point_radius_x_src : -point_radius_x_src); + a.OpAdd(dxbc::Dest::R(2, 0b0010), + dxbc::Src::V2D(0, input_register_position, dxbc::Src::kYYYY), + (i >> 1) ? -point_radius_y_src : point_radius_y_src); + a.OpMov(dxbc::Dest::R(2, 0b0100), + dxbc::Src::V2D(0, input_register_position, dxbc::Src::kZZZZ)); + a.OpMov(dxbc::Dest::R(2, 0b1000), + dxbc::Src::V2D(0, input_register_position, dxbc::Src::kWWWW)); + a.OpMAd(dxbc::Dest::R(2, 0b0011), -ndc_offset_xy, dxbc::Src::R(2, dxbc::Src::kWWWW), + dxbc::Src::R(2, 0b0011)); + a.OpDiv(dxbc::Dest::R(2, 0b0011), dxbc::Src::R(2, 0b0011), ndc_scale_xy); + a.OpMAd(dxbc::Dest::R(2, 0b0100), -ndc_offset_z, dxbc::Src::R(2, dxbc::Src::kWWWW), + dxbc::Src::R(2, dxbc::Src::kZZZZ)); + a.OpDiv(dxbc::Dest::R(2, 0b0100), dxbc::Src::R(2, dxbc::Src::kZZZZ), ndc_scale_z); + a.OpDP4( + dxbc::Dest::R(2, 0b0001), dxbc::Src::R(2), + dxbc::Src::CB(0, uint32_t(DxbcShaderTranslator::CbufferRegister::kSystemConstants), + (offsetof(DxbcShaderTranslator::SystemConstants, user_clip_planes) + + sizeof(float) * 4 * j) >> + 4, + dxbc::Src::kXYZW)); + a.OpLT(dxbc::Dest::R(2, 0b0001), dxbc::Src::R(2, dxbc::Src::kXXXX), + dxbc::Src::LF(0.0f)); + if (i == 0) { + a.OpMov(dxbc::Dest::R(3, 0b0001), dxbc::Src::R(2, dxbc::Src::kXXXX)); + } else { + a.OpAnd(dxbc::Dest::R(3, 0b0001), dxbc::Src::R(3, dxbc::Src::kXXXX), + dxbc::Src::R(2, dxbc::Src::kXXXX)); + } + } + a.OpRetC(true, dxbc::Src::R(3, dxbc::Src::kXXXX)); + } + } + + for (uint32_t i = 0; i < 4; ++i) { + // Same interpolators for the entire sprite. + for (uint32_t j = 0; j < key.interpolator_count; ++j) { + a.OpMov(dxbc::Dest::O(output_register_interpolators + j), + dxbc::Src::V2D(0, input_register_interpolators + j)); + } + // Top-left, top-right, bottom-left, bottom-right order (chosen + // arbitrarily, simply based on clockwise meaning front with + // FrontCounterClockwise = FALSE, but faceness is ignored for + // non-polygon primitive types). + // Bottom is -Y in Direct3D NDC, +V in point sprite coordinates. + if (key.has_point_coordinates) { + a.OpMov(dxbc::Dest::O(output_register_point_coordinates, 0b0011), + dxbc::Src::LF(float(i & 1), float(i >> 1), 0.0f, 0.0f)); + } + // FXC generates only `mov`s for o#, use temporary registers (r0.zw, as + // r0.xy already used for the point size) for calculations. + a.OpAdd(dxbc::Dest::R(0, 0b0100), + dxbc::Src::V2D(0, input_register_position, dxbc::Src::kXXXX), + (i & 1) ? point_radius_x_src : -point_radius_x_src); + a.OpAdd(dxbc::Dest::R(0, 0b1000), + dxbc::Src::V2D(0, input_register_position, dxbc::Src::kYYYY), + (i >> 1) ? -point_radius_y_src : point_radius_y_src); + a.OpMov(dxbc::Dest::O(output_register_position, 0b0011), dxbc::Src::R(0, 0b1110)); + a.OpMov(dxbc::Dest::O(output_register_position, 0b1100), + dxbc::Src::V2D(0, input_register_position)); + if (point_recalculate_clip_distances) { + // Convert host clip space back to guest clip space before applying + // user clip planes. + dxbc::Src ndc_scale_xy(dxbc::Src::CB( + 0, uint32_t(DxbcShaderTranslator::CbufferRegister::kSystemConstants), + offsetof(DxbcShaderTranslator::SystemConstants, ndc_scale) >> 4, + ((offsetof(DxbcShaderTranslator::SystemConstants, ndc_scale[0]) >> 2) & 3) | + (((offsetof(DxbcShaderTranslator::SystemConstants, ndc_scale[1]) >> 2) & 3) + << 2))); + dxbc::Src ndc_scale_z(dxbc::Src::CB( + 0, uint32_t(DxbcShaderTranslator::CbufferRegister::kSystemConstants), + offsetof(DxbcShaderTranslator::SystemConstants, ndc_scale) >> 4, dxbc::Src::kZZZZ)); + dxbc::Src ndc_offset_xy(dxbc::Src::CB( + 0, uint32_t(DxbcShaderTranslator::CbufferRegister::kSystemConstants), + offsetof(DxbcShaderTranslator::SystemConstants, ndc_offset) >> 4, + ((offsetof(DxbcShaderTranslator::SystemConstants, ndc_offset[0]) >> 2) & 3) | + (((offsetof(DxbcShaderTranslator::SystemConstants, ndc_offset[1]) >> 2) & 3) + << 2))); + dxbc::Src ndc_offset_z(dxbc::Src::CB( + 0, uint32_t(DxbcShaderTranslator::CbufferRegister::kSystemConstants), + offsetof(DxbcShaderTranslator::SystemConstants, ndc_offset) >> 4, dxbc::Src::kZZZZ)); + a.OpMov(dxbc::Dest::R(1, 0b0011), dxbc::Src::R(0, 0b1110)); + a.OpMov(dxbc::Dest::R(1, 0b0100), + dxbc::Src::V2D(0, input_register_position, dxbc::Src::kZZZZ)); + a.OpMov(dxbc::Dest::R(1, 0b1000), + dxbc::Src::V2D(0, input_register_position, dxbc::Src::kWWWW)); + a.OpMAd(dxbc::Dest::R(1, 0b0011), -ndc_offset_xy, dxbc::Src::R(1, dxbc::Src::kWWWW), + dxbc::Src::R(1, 0b0100)); + a.OpDiv(dxbc::Dest::R(1, 0b0011), dxbc::Src::R(1, 0b0100), ndc_scale_xy); + a.OpMAd(dxbc::Dest::R(1, 0b0100), -ndc_offset_z, dxbc::Src::R(1, dxbc::Src::kWWWW), + dxbc::Src::R(1, dxbc::Src::kZZZZ)); + a.OpDiv(dxbc::Dest::R(1, 0b0100), dxbc::Src::R(1, dxbc::Src::kZZZZ), ndc_scale_z); + for (uint32_t j = 0; j < input_clip_distance_count; ++j) { + a.OpDP4( + dxbc::Dest::O(output_register_clip_distances + (j >> 2), UINT32_C(1) << (j & 3)), + dxbc::Src::R(1), + dxbc::Src::CB(0, uint32_t(DxbcShaderTranslator::CbufferRegister::kSystemConstants), + (offsetof(DxbcShaderTranslator::SystemConstants, user_clip_planes) + + sizeof(float) * 4 * j) >> + 4, + dxbc::Src::kXYZW)); + } + } else { + for (uint32_t j = 0; j < input_clip_distance_count; j += 4) { + a.OpMov(dxbc::Dest::O( + output_register_clip_distances + (j >> 2), + (UINT32_C(1) << std::min(input_clip_distance_count - j, UINT32_C(4))) - 1), + dxbc::Src::V2D(0, input_register_clip_and_cull_distances + (j >> 2))); + } + } + a.OpEmitStream(stream); + } + a.OpCutStream(stream); + } break; + + case PipelineGeometryShader::kRectangleList: { + // Construct a strip with the fourth vertex generated by mirroring a + // vertex across the longest edge (the diagonal). + // + // Possible options: + // + // 0---1 + // | /| + // | / | - 12 is the longest edge, strip 0123 (most commonly used) + // |/ | v3 = v0 + (v1 - v0) + (v2 - v0), or v3 = -v0 + v1 + v2 + // 2--[3] + // + // 1---2 + // | /| + // | / | - 20 is the longest edge, strip 1203 + // |/ | + // 0--[3] + // + // 2---0 + // | /| + // | / | - 01 is the longest edge, strip 2013 + // |/ | + // 1--[3] + // + // Input vertices are implicitly indexable, dcl_indexRange is not needed + // for the first dimension of a v[#][#] index. + + // Get squares of edge lengths into r0.xyz to choose the longest edge. + // r0.x = ||12||^2 + a.OpAdd(dxbc::Dest::R(0, 0b0011), dxbc::Src::V2D(2, input_register_position, 0b0100), + -dxbc::Src::V2D(1, input_register_position, 0b0100)); + a.OpDP2(dxbc::Dest::R(0, 0b0001), dxbc::Src::R(0, 0b0100), dxbc::Src::R(0, 0b0100)); + // r0.y = ||20||^2 + a.OpAdd(dxbc::Dest::R(0, 0b0110), dxbc::Src::V2D(0, input_register_position, 0b0100 << 2), + -dxbc::Src::V2D(2, input_register_position, 0b0100 << 2)); + a.OpDP2(dxbc::Dest::R(0, 0b0010), dxbc::Src::R(0, 0b1001), dxbc::Src::R(0, 0b1001)); + // r0.z = ||01||^2 + a.OpAdd(dxbc::Dest::R(0, 0b1100), dxbc::Src::V2D(1, input_register_position, 0b0100 << 4), + -dxbc::Src::V2D(0, input_register_position, 0b0100 << 4)); + a.OpDP2(dxbc::Dest::R(0, 0b0100), dxbc::Src::R(0, 0b1110), dxbc::Src::R(0, 0b1110)); + + // Find the longest edge, and select the strip vertex indices into r0.xyz. + // r0.w = 12 > 20 + a.OpLT(dxbc::Dest::R(0, 0b1000), dxbc::Src::R(0, dxbc::Src::kYYYY), + dxbc::Src::R(0, dxbc::Src::kXXXX)); + // r0.x = 12 > 01 + a.OpLT(dxbc::Dest::R(0, 0b0001), dxbc::Src::R(0, dxbc::Src::kZZZZ), + dxbc::Src::R(0, dxbc::Src::kXXXX)); + // r0.x = 12 > 20 && 12 > 01 + a.OpAnd(dxbc::Dest::R(0, 0b0001), dxbc::Src::R(0, dxbc::Src::kWWWW), + dxbc::Src::R(0, dxbc::Src::kXXXX)); + a.OpIf(true, dxbc::Src::R(0, dxbc::Src::kXXXX)); + { + // 12 is the longest edge, the first triangle in the strip is 012. + a.OpMov(dxbc::Dest::R(0, 0b0111), dxbc::Src::LU(0, 1, 2, 0)); + } + a.OpElse(); + { + // r0.x = 20 > 01 + a.OpLT(dxbc::Dest::R(0, 0b0001), dxbc::Src::R(0, dxbc::Src::kZZZZ), + dxbc::Src::R(0, dxbc::Src::kYYYY)); + // If 20 is the longest edge, the first triangle in the strip is 120. + // Otherwise, it's 201. + a.OpMovC(dxbc::Dest::R(0, 0b0111), dxbc::Src::R(0, dxbc::Src::kXXXX), + dxbc::Src::LU(1, 2, 0, 0), dxbc::Src::LU(2, 0, 1, 0)); + } + a.OpEndIf(); + + // Emit the triangle in the strip that consists of the original vertices. + for (uint32_t i = 0; i < 3; ++i) { + dxbc::Index input_vertex_index(0, i); + for (uint32_t j = 0; j < key.interpolator_count; ++j) { + a.OpMov(dxbc::Dest::O(output_register_interpolators + j), + dxbc::Src::V2D(input_vertex_index, input_register_interpolators + j)); + } + if (key.has_point_coordinates) { + a.OpMov(dxbc::Dest::O(output_register_point_coordinates, 0b0011), dxbc::Src::LF(0.0f)); + } + a.OpMov(dxbc::Dest::O(output_register_position), + dxbc::Src::V2D(input_vertex_index, input_register_position)); + for (uint32_t j = 0; j < input_clip_distance_count; j += 4) { + a.OpMov(dxbc::Dest::O( + output_register_clip_distances + (j >> 2), + (UINT32_C(1) << std::min(input_clip_distance_count - j, UINT32_C(4))) - 1), + dxbc::Src::V2D(input_vertex_index, + input_register_clip_and_cull_distances + (j >> 2))); + } + a.OpEmitStream(stream); + } + + // Construct the fourth vertex using r1 as temporary storage, including + // for the final operation as FXC generates only `mov`s for o#. + stat.temp_register_count = std::max(UINT32_C(2), stat.temp_register_count); + for (uint32_t j = 0; j < key.interpolator_count; ++j) { + uint32_t input_register_interpolator = input_register_interpolators + j; + a.OpAdd(dxbc::Dest::R(1), -dxbc::Src::V2D(dxbc::Index(0, 0), input_register_interpolator), + dxbc::Src::V2D(dxbc::Index(0, 1), input_register_interpolator)); + a.OpAdd(dxbc::Dest::R(1), dxbc::Src::R(1), + dxbc::Src::V2D(dxbc::Index(0, 2), input_register_interpolator)); + a.OpMov(dxbc::Dest::O(output_register_interpolators + j), dxbc::Src::R(1)); + } + if (key.has_point_coordinates) { + a.OpMov(dxbc::Dest::O(output_register_point_coordinates, 0b0011), dxbc::Src::LF(0.0f)); + } + a.OpAdd(dxbc::Dest::R(1), -dxbc::Src::V2D(dxbc::Index(0, 0), input_register_position), + dxbc::Src::V2D(dxbc::Index(0, 1), input_register_position)); + a.OpAdd(dxbc::Dest::R(1), dxbc::Src::R(1), + dxbc::Src::V2D(dxbc::Index(0, 2), input_register_position)); + a.OpMov(dxbc::Dest::O(output_register_position), dxbc::Src::R(1)); + for (uint32_t j = 0; j < input_clip_distance_count; j += 4) { + uint32_t clip_distance_mask = + (UINT32_C(1) << std::min(input_clip_distance_count - j, UINT32_C(4))) - 1; + uint32_t input_register_clip_distance = input_register_clip_and_cull_distances + (j >> 2); + a.OpAdd(dxbc::Dest::R(1, clip_distance_mask), + -dxbc::Src::V2D(dxbc::Index(0, 0), input_register_clip_distance), + dxbc::Src::V2D(dxbc::Index(0, 1), input_register_clip_distance)); + a.OpAdd(dxbc::Dest::R(1, clip_distance_mask), dxbc::Src::R(1), + dxbc::Src::V2D(dxbc::Index(0, 2), input_register_clip_distance)); + a.OpMov(dxbc::Dest::O(output_register_clip_distances + (j >> 2), clip_distance_mask), + dxbc::Src::R(1)); + } + a.OpEmitStream(stream); + a.OpCutStream(stream); + } break; + + case PipelineGeometryShader::kQuadList: { + // Build the triangle strip from the original quad vertices in the + // 0, 1, 3, 2 order (like specified for GL_QUAD_STRIP). + // TODO(Triang3l): Find the correct decomposition of quads into triangles + // on the real hardware. + for (uint32_t i = 0; i < 4; ++i) { + uint32_t input_vertex_index = i ^ (i >> 1); + for (uint32_t j = 0; j < key.interpolator_count; ++j) { + a.OpMov(dxbc::Dest::O(output_register_interpolators + j), + dxbc::Src::V2D(input_vertex_index, input_register_interpolators + j)); + } + if (key.has_point_coordinates) { + a.OpMov(dxbc::Dest::O(output_register_point_coordinates, 0b0011), dxbc::Src::LF(0.0f)); + } + a.OpMov(dxbc::Dest::O(output_register_position), + dxbc::Src::V2D(input_vertex_index, input_register_position)); + for (uint32_t j = 0; j < input_clip_distance_count; j += 4) { + a.OpMov(dxbc::Dest::O( + output_register_clip_distances + (j >> 2), + (UINT32_C(1) << std::min(input_clip_distance_count - j, UINT32_C(4))) - 1), + dxbc::Src::V2D(input_vertex_index, + input_register_clip_and_cull_distances + (j >> 2))); + } + a.OpEmitStream(stream); + } + a.OpCutStream(stream); + } break; + + default: + assert_unhandled_case(key.type); + } + + a.OpRet(); + + // Write the actual number of temporary registers used. + shader_out[dcl_temps_count_position_dwords] = stat.temp_register_count; + + // Write the shader program length in dwords. + shader_out[shex_position_dwords + 1] = uint32_t(shader_out.size()) - shex_position_dwords; + + { + auto& blob_header = + *reinterpret_cast(shader_out.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kShaderEx; + blob_position_dwords = uint32_t(shader_out.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + shader_out[blob_offset_position_dwords++]; + } + + // *************************************************************************** + // Statistics + // *************************************************************************** + + shader_out[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + uint32_t stat_position_dwords = blob_position_dwords + kBlobHeaderSizeDwords; + shader_out.resize(stat_position_dwords + sizeof(dxbc::Statistics) / sizeof(uint32_t)); + std::memcpy(shader_out.data() + stat_position_dwords, &stat, sizeof(dxbc::Statistics)); + + { + auto& blob_header = + *reinterpret_cast(shader_out.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kStatistics; + blob_position_dwords = uint32_t(shader_out.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + shader_out[blob_offset_position_dwords++]; + } + + // *************************************************************************** + // Container header + // *************************************************************************** + + uint32_t shader_size_bytes = uint32_t(shader_out.size() * sizeof(uint32_t)); + { + auto& container_header = *reinterpret_cast(shader_out.data()); + container_header.InitializeIdentification(); + container_header.size_bytes = shader_size_bytes; + container_header.blob_count = kBlobCount; + CalculateDXBCChecksum(reinterpret_cast(shader_out.data()), + static_cast(shader_size_bytes), + reinterpret_cast(&container_header.hash)); + } +} + +const std::vector& PipelineCache::GetGeometryShader(GeometryShaderKey key) { + auto it = geometry_shaders_.find(key); + if (it != geometry_shaders_.end()) { + return it->second; + } + std::vector shader; + CreateDxbcGeometryShader(key, shader); + return geometry_shaders_.emplace(key, std::move(shader)).first->second; +} + +ID3D12PipelineState* PipelineCache::CreateD3D12Pipeline( + const PipelineRuntimeDescription& runtime_description) { + const PipelineDescription& description = runtime_description.description; + + if (runtime_description.pixel_shader != nullptr) { + REXGPU_DEBUG("Creating graphics pipeline with VS {:016X}, PS {:016X}", + runtime_description.vertex_shader->shader().ucode_data_hash(), + runtime_description.pixel_shader->shader().ucode_data_hash()); + } else { + REXGPU_DEBUG("Creating graphics pipeline with VS {:016X}", + runtime_description.vertex_shader->shader().ucode_data_hash()); + } + + D3D12_GRAPHICS_PIPELINE_STATE_DESC state_desc; + std::memset(&state_desc, 0, sizeof(state_desc)); + + bool edram_rov_used = + render_target_cache_.GetPath() == RenderTargetCache::Path::kPixelShaderInterlock; + + // Root signature. + state_desc.pRootSignature = runtime_description.root_signature; + + // Index buffer strip cut value. + switch (description.strip_cut_index) { + case PipelineStripCutIndex::kFFFF: + state_desc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF; + break; + case PipelineStripCutIndex::kFFFFFFFF: + state_desc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF; + break; + default: + state_desc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED; + break; + } + + // Primitive topology, vertex, hull, domain and geometry shaders. + if (!runtime_description.vertex_shader->is_translated()) { + REXGPU_ERROR("Vertex shader {:016X} not translated", + runtime_description.vertex_shader->shader().ucode_data_hash()); + assert_always(); + return nullptr; + } + Shader::HostVertexShaderType host_vertex_shader_type = + DxbcShaderTranslator::Modification(runtime_description.vertex_shader->modification()) + .vertex.host_vertex_shader_type; + if (Shader::IsHostVertexShaderTypeDomain(host_vertex_shader_type)) { + state_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH; + xenos::TessellationMode tessellation_mode = + xenos::TessellationMode(description.primitive_topology_type_or_tessellation_mode); + if (tessellation_mode == xenos::TessellationMode::kAdaptive) { + state_desc.VS.pShaderBytecode = shaders::tessellation_adaptive_vs; + state_desc.VS.BytecodeLength = sizeof(shaders::tessellation_adaptive_vs); + } else { + state_desc.VS.pShaderBytecode = shaders::tessellation_indexed_vs; + state_desc.VS.BytecodeLength = sizeof(shaders::tessellation_indexed_vs); + } + switch (tessellation_mode) { + case xenos::TessellationMode::kDiscrete: + switch (host_vertex_shader_type) { + case Shader::HostVertexShaderType::kTriangleDomainCPIndexed: + state_desc.HS.pShaderBytecode = shaders::discrete_triangle_3cp_hs; + state_desc.HS.BytecodeLength = sizeof(shaders::discrete_triangle_3cp_hs); + break; + case Shader::HostVertexShaderType::kTriangleDomainPatchIndexed: + state_desc.HS.pShaderBytecode = shaders::discrete_triangle_1cp_hs; + state_desc.HS.BytecodeLength = sizeof(shaders::discrete_triangle_1cp_hs); + break; + case Shader::HostVertexShaderType::kQuadDomainCPIndexed: + state_desc.HS.pShaderBytecode = shaders::discrete_quad_4cp_hs; + state_desc.HS.BytecodeLength = sizeof(shaders::discrete_quad_4cp_hs); + break; + case Shader::HostVertexShaderType::kQuadDomainPatchIndexed: + state_desc.HS.pShaderBytecode = shaders::discrete_quad_1cp_hs; + state_desc.HS.BytecodeLength = sizeof(shaders::discrete_quad_1cp_hs); + break; + default: + assert_unhandled_case(host_vertex_shader_type); + return nullptr; + } + break; + case xenos::TessellationMode::kContinuous: + switch (host_vertex_shader_type) { + case Shader::HostVertexShaderType::kTriangleDomainCPIndexed: + state_desc.HS.pShaderBytecode = shaders::continuous_triangle_3cp_hs; + state_desc.HS.BytecodeLength = sizeof(shaders::continuous_triangle_3cp_hs); + break; + case Shader::HostVertexShaderType::kTriangleDomainPatchIndexed: + state_desc.HS.pShaderBytecode = shaders::continuous_triangle_1cp_hs; + state_desc.HS.BytecodeLength = sizeof(shaders::continuous_triangle_1cp_hs); + break; + case Shader::HostVertexShaderType::kQuadDomainCPIndexed: + state_desc.HS.pShaderBytecode = shaders::continuous_quad_4cp_hs; + state_desc.HS.BytecodeLength = sizeof(shaders::continuous_quad_4cp_hs); + break; + case Shader::HostVertexShaderType::kQuadDomainPatchIndexed: + state_desc.HS.pShaderBytecode = shaders::continuous_quad_1cp_hs; + state_desc.HS.BytecodeLength = sizeof(shaders::continuous_quad_1cp_hs); + break; + default: + assert_unhandled_case(host_vertex_shader_type); + return nullptr; + } + break; + case xenos::TessellationMode::kAdaptive: + switch (host_vertex_shader_type) { + case Shader::HostVertexShaderType::kTriangleDomainPatchIndexed: + state_desc.HS.pShaderBytecode = shaders::adaptive_triangle_hs; + state_desc.HS.BytecodeLength = sizeof(shaders::adaptive_triangle_hs); + break; + case Shader::HostVertexShaderType::kQuadDomainPatchIndexed: + state_desc.HS.pShaderBytecode = shaders::adaptive_quad_hs; + state_desc.HS.BytecodeLength = sizeof(shaders::adaptive_quad_hs); + break; + default: + assert_unhandled_case(host_vertex_shader_type); + return nullptr; + } + break; + default: + assert_unhandled_case(tessellation_mode); + return nullptr; + } + state_desc.DS.pShaderBytecode = runtime_description.vertex_shader->translated_binary().data(); + state_desc.DS.BytecodeLength = runtime_description.vertex_shader->translated_binary().size(); + } else { + assert_true(host_vertex_shader_type == Shader::HostVertexShaderType::kVertex); + if (host_vertex_shader_type != Shader::HostVertexShaderType::kVertex) { + // Fallback vertex shaders are not needed on Direct3D 12. + return nullptr; + } + state_desc.VS.pShaderBytecode = runtime_description.vertex_shader->translated_binary().data(); + state_desc.VS.BytecodeLength = runtime_description.vertex_shader->translated_binary().size(); + PipelinePrimitiveTopologyType primitive_topology_type = + PipelinePrimitiveTopologyType(description.primitive_topology_type_or_tessellation_mode); + switch (primitive_topology_type) { + case PipelinePrimitiveTopologyType::kPoint: + state_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT; + break; + case PipelinePrimitiveTopologyType::kLine: + state_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE; + break; + case PipelinePrimitiveTopologyType::kTriangle: + state_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + break; + default: + assert_unhandled_case(primitive_topology_type); + return nullptr; + } + } + + // Pixel shader. + if (runtime_description.pixel_shader != nullptr) { + if (!runtime_description.pixel_shader->is_translated()) { + REXGPU_ERROR("Pixel shader {:016X} not translated", + runtime_description.pixel_shader->shader().ucode_data_hash()); + assert_always(); + return nullptr; + } + state_desc.PS.pShaderBytecode = runtime_description.pixel_shader->translated_binary().data(); + state_desc.PS.BytecodeLength = runtime_description.pixel_shader->translated_binary().size(); + } else if (edram_rov_used) { + state_desc.PS.pShaderBytecode = depth_only_pixel_shader_.data(); + state_desc.PS.BytecodeLength = depth_only_pixel_shader_.size(); + } else { + if (render_target_cache_.depth_float24_convert_in_pixel_shader() && + (description.depth_func != xenos::CompareFunction::kAlways || description.depth_write) && + description.depth_format == xenos::DepthRenderTargetFormat::kD24FS8) { + if (render_target_cache_.depth_float24_round()) { + state_desc.PS.pShaderBytecode = shaders::float24_round_ps; + state_desc.PS.BytecodeLength = sizeof(shaders::float24_round_ps); + } else { + state_desc.PS.pShaderBytecode = shaders::float24_truncate_ps; + state_desc.PS.BytecodeLength = sizeof(shaders::float24_truncate_ps); + } + } + } + + // Geometry shader. + if (runtime_description.geometry_shader != nullptr) { + state_desc.GS.pShaderBytecode = runtime_description.geometry_shader->data(); + state_desc.GS.BytecodeLength = sizeof(*runtime_description.geometry_shader->data()) * + runtime_description.geometry_shader->size(); + } + + // Rasterizer state. + state_desc.RasterizerState.FillMode = + description.fill_mode_wireframe ? D3D12_FILL_MODE_WIREFRAME : D3D12_FILL_MODE_SOLID; + switch (description.cull_mode) { + case PipelineCullMode::kFront: + state_desc.RasterizerState.CullMode = D3D12_CULL_MODE_FRONT; + break; + case PipelineCullMode::kBack: + state_desc.RasterizerState.CullMode = D3D12_CULL_MODE_BACK; + break; + default: + assert_true(description.cull_mode == PipelineCullMode::kNone || + description.cull_mode == PipelineCullMode::kDisableRasterization); + state_desc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; + break; + } + state_desc.RasterizerState.FrontCounterClockwise = + description.front_counter_clockwise ? TRUE : FALSE; + state_desc.RasterizerState.DepthBias = description.depth_bias; + state_desc.RasterizerState.DepthBiasClamp = 0.0f; + // With non-square resolution scaling, make sure the worst-case impact is + // reverted (slope only along the scaled axis), thus max. More bias is better + // than less bias, because less bias means Z fighting with the background is + // more likely. + state_desc.RasterizerState.SlopeScaledDepthBias = + description.depth_bias_slope_scaled * + float(std::max(render_target_cache_.draw_resolution_scale_x(), + render_target_cache_.draw_resolution_scale_y())); + state_desc.RasterizerState.DepthClipEnable = description.depth_clip ? TRUE : FALSE; + uint32_t msaa_sample_count = uint32_t(1) << uint32_t(description.host_msaa_samples); + if (edram_rov_used) { + // Only 1, 4, 8 and (not on all GPUs) 16 are allowed, using sample 0 as 0 + // and 3 as 1 for 2x instead (not exactly the same sample positions, but + // still top-left and bottom-right - however, this can be adjusted with + // programmable sample positions). + assert_true(msaa_sample_count == 1 || msaa_sample_count == 4); + if (msaa_sample_count != 1 && msaa_sample_count != 4) { + return nullptr; + } + state_desc.RasterizerState.ForcedSampleCount = uint32_t(1) + << uint32_t(description.host_msaa_samples); + } + + // Sample mask and description. + state_desc.SampleMask = UINT_MAX; + // TODO(Triang3l): 4x MSAA fallback when 2x isn't supported without ROV. + if (edram_rov_used) { + state_desc.SampleDesc.Count = 1; + } else { + assert_true(msaa_sample_count <= 4); + if (msaa_sample_count > 4) { + return nullptr; + } + if (msaa_sample_count == 2 && !render_target_cache_.msaa_2x_supported()) { + // Using sample 0 as 0 and 3 as 1 for 2x instead (not exactly the same + // sample positions, but still top-left and bottom-right - however, this + // can be adjusted with programmable sample positions). + state_desc.SampleMask = 0b1001; + state_desc.SampleDesc.Count = 4; + } else { + state_desc.SampleDesc.Count = msaa_sample_count; + } + } + + if (!edram_rov_used) { + // Depth/stencil. + if (description.depth_func != xenos::CompareFunction::kAlways || description.depth_write) { + state_desc.DepthStencilState.DepthEnable = TRUE; + state_desc.DepthStencilState.DepthWriteMask = + description.depth_write ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO; + // Comparison functions are the same in Direct3D 12 but plus one (minus + // one, bit 0 for less, bit 1 for equal, bit 2 for greater). + state_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC( + uint32_t(D3D12_COMPARISON_FUNC_NEVER) + uint32_t(description.depth_func)); + } + if (description.stencil_enable) { + state_desc.DepthStencilState.StencilEnable = TRUE; + state_desc.DepthStencilState.StencilReadMask = description.stencil_read_mask; + state_desc.DepthStencilState.StencilWriteMask = description.stencil_write_mask; + // Stencil operations are the same in Direct3D 12 too but plus one. + state_desc.DepthStencilState.FrontFace.StencilFailOp = D3D12_STENCIL_OP( + uint32_t(D3D12_STENCIL_OP_KEEP) + uint32_t(description.stencil_front_fail_op)); + state_desc.DepthStencilState.FrontFace.StencilDepthFailOp = D3D12_STENCIL_OP( + uint32_t(D3D12_STENCIL_OP_KEEP) + uint32_t(description.stencil_front_depth_fail_op)); + state_desc.DepthStencilState.FrontFace.StencilPassOp = D3D12_STENCIL_OP( + uint32_t(D3D12_STENCIL_OP_KEEP) + uint32_t(description.stencil_front_pass_op)); + state_desc.DepthStencilState.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC( + uint32_t(D3D12_COMPARISON_FUNC_NEVER) + uint32_t(description.stencil_front_func)); + state_desc.DepthStencilState.BackFace.StencilFailOp = D3D12_STENCIL_OP( + uint32_t(D3D12_STENCIL_OP_KEEP) + uint32_t(description.stencil_back_fail_op)); + state_desc.DepthStencilState.BackFace.StencilDepthFailOp = D3D12_STENCIL_OP( + uint32_t(D3D12_STENCIL_OP_KEEP) + uint32_t(description.stencil_back_depth_fail_op)); + state_desc.DepthStencilState.BackFace.StencilPassOp = D3D12_STENCIL_OP( + uint32_t(D3D12_STENCIL_OP_KEEP) + uint32_t(description.stencil_back_pass_op)); + state_desc.DepthStencilState.BackFace.StencilFunc = D3D12_COMPARISON_FUNC( + uint32_t(D3D12_COMPARISON_FUNC_NEVER) + uint32_t(description.stencil_back_func)); + } + if (state_desc.DepthStencilState.DepthEnable || state_desc.DepthStencilState.StencilEnable) { + state_desc.DSVFormat = + D3D12RenderTargetCache::GetDepthDSVDXGIFormat(description.depth_format); + } + + // Render targets and blending. + state_desc.BlendState.IndependentBlendEnable = TRUE; + static const D3D12_BLEND kBlendFactorMap[] = { + D3D12_BLEND_ZERO, D3D12_BLEND_ONE, + D3D12_BLEND_SRC_COLOR, D3D12_BLEND_INV_SRC_COLOR, + D3D12_BLEND_SRC_ALPHA, D3D12_BLEND_INV_SRC_ALPHA, + D3D12_BLEND_DEST_COLOR, D3D12_BLEND_INV_DEST_COLOR, + D3D12_BLEND_DEST_ALPHA, D3D12_BLEND_INV_DEST_ALPHA, + D3D12_BLEND_BLEND_FACTOR, D3D12_BLEND_INV_BLEND_FACTOR, + D3D12_BLEND_SRC_ALPHA_SAT, + }; + // 8 entries for safety since 3 bits from the guest are passed directly. + static const D3D12_BLEND_OP kBlendOpMap[] = { + D3D12_BLEND_OP_ADD, D3D12_BLEND_OP_SUBTRACT, D3D12_BLEND_OP_MIN, + D3D12_BLEND_OP_MAX, D3D12_BLEND_OP_REV_SUBTRACT, D3D12_BLEND_OP_ADD, + D3D12_BLEND_OP_ADD, D3D12_BLEND_OP_ADD}; + for (uint32_t i = 0; i < xenos::kMaxColorRenderTargets; ++i) { + const PipelineRenderTarget& rt = description.render_targets[i]; + if (!rt.used) { + // Null RTV descriptors can be used for slots with DXGI_FORMAT_UNKNOWN + // in the pipeline state. + state_desc.RTVFormats[i] = DXGI_FORMAT_UNKNOWN; + continue; + } + state_desc.NumRenderTargets = i + 1; + state_desc.RTVFormats[i] = render_target_cache_.GetColorDrawDXGIFormat(rt.format); + if (state_desc.RTVFormats[i] == DXGI_FORMAT_UNKNOWN) { + assert_always(); + return nullptr; + } + D3D12_RENDER_TARGET_BLEND_DESC& blend_desc = state_desc.BlendState.RenderTarget[i]; + if (rt.src_blend != PipelineBlendFactor::kOne || + rt.dest_blend != PipelineBlendFactor::kZero || rt.blend_op != xenos::BlendOp::kAdd || + rt.src_blend_alpha != PipelineBlendFactor::kOne || + rt.dest_blend_alpha != PipelineBlendFactor::kZero || + rt.blend_op_alpha != xenos::BlendOp::kAdd) { + blend_desc.BlendEnable = TRUE; + blend_desc.SrcBlend = kBlendFactorMap[uint32_t(rt.src_blend)]; + blend_desc.DestBlend = kBlendFactorMap[uint32_t(rt.dest_blend)]; + blend_desc.BlendOp = kBlendOpMap[uint32_t(rt.blend_op)]; + blend_desc.SrcBlendAlpha = kBlendFactorMap[uint32_t(rt.src_blend_alpha)]; + blend_desc.DestBlendAlpha = kBlendFactorMap[uint32_t(rt.dest_blend_alpha)]; + blend_desc.BlendOpAlpha = kBlendOpMap[uint32_t(rt.blend_op_alpha)]; + } + blend_desc.RenderTargetWriteMask = rt.write_mask; + } + } + + // Disable rasterization if needed (parameter combinations that make no + // difference when rasterization is disabled have already been handled in + // GetCurrentStateDescription) the way it's disabled in Direct3D by design + // (disabling a pixel shader and depth / stencil). + // TODO(Triang3l): When it happens to be that a combination of parameters + // (no host pixel shader and depth / stencil without ROV) would disable + // rasterization when it's still needed (for occlusion query sample counting), + // ensure rasterization happens (by binding an empty pixel shader, or maybe + // via ForcedSampleCount when not using 2x MSAA - its requirements for + // OMSetRenderTargets need some investigation though). + if (description.cull_mode == PipelineCullMode::kDisableRasterization) { + state_desc.PS.pShaderBytecode = nullptr; + state_desc.PS.BytecodeLength = 0; + state_desc.DepthStencilState.DepthEnable = FALSE; + state_desc.DepthStencilState.StencilEnable = FALSE; + } + + // Create the D3D12 pipeline state object. + ID3D12Device* device = command_processor_.GetD3D12Provider().GetDevice(); + ID3D12PipelineState* state; + if (FAILED(device->CreateGraphicsPipelineState(&state_desc, IID_PPV_ARGS(&state)))) { + if (runtime_description.pixel_shader != nullptr) { + REXGPU_ERROR("Failed to create graphics pipeline with VS {:016X}, PS {:016X}", + runtime_description.vertex_shader->shader().ucode_data_hash(), + runtime_description.pixel_shader->shader().ucode_data_hash()); + } else { + REXGPU_ERROR("Failed to create graphics pipeline with VS {:016X}", + runtime_description.vertex_shader->shader().ucode_data_hash()); + } + return nullptr; + } + std::u16string name; + if (runtime_description.pixel_shader != nullptr) { + name = rex::string::to_utf16(fmt::format( + "VS {:016X}, PS {:016X}", runtime_description.vertex_shader->shader().ucode_data_hash(), + runtime_description.pixel_shader->shader().ucode_data_hash())); + } else { + name = rex::string::to_utf16( + fmt::format("VS {:016X}", runtime_description.vertex_shader->shader().ucode_data_hash())); + } + state->SetName(reinterpret_cast(name.c_str())); + return state; +} + +void PipelineCache::StorageWriteThread() { + ShaderStoredHeader shader_header; + // Don't leak anything in unused bits. + std::memset(&shader_header, 0, sizeof(shader_header)); + + std::vector ucode_guest_endian; + ucode_guest_endian.reserve(0xFFFF); + + bool flush_shaders = false; + bool flush_pipelines = false; + + while (true) { + if (flush_shaders) { + flush_shaders = false; + assert_not_null(shader_storage_file_); + fflush(shader_storage_file_); + } + if (flush_pipelines) { + flush_pipelines = false; + assert_not_null(pipeline_storage_file_); + fflush(pipeline_storage_file_); + } + + const Shader* shader = nullptr; + PipelineStoredDescription pipeline_description; + bool write_pipeline = false; + { + std::unique_lock lock(storage_write_request_lock_); + if (storage_write_thread_shutdown_) { + return; + } + if (!storage_write_shader_queue_.empty()) { + shader = storage_write_shader_queue_.front(); + storage_write_shader_queue_.pop_front(); + } else if (storage_write_flush_shaders_) { + storage_write_flush_shaders_ = false; + flush_shaders = true; + } + if (!storage_write_pipeline_queue_.empty()) { + std::memcpy(&pipeline_description, &storage_write_pipeline_queue_.front(), + sizeof(pipeline_description)); + storage_write_pipeline_queue_.pop_front(); + write_pipeline = true; + } else if (storage_write_flush_pipelines_) { + storage_write_flush_pipelines_ = false; + flush_pipelines = true; + } + if (!shader && !write_pipeline) { + storage_write_request_cond_.wait(lock); + continue; + } + } + + if (shader) { + shader_header.ucode_data_hash = shader->ucode_data_hash(); + shader_header.ucode_dword_count = shader->ucode_dword_count(); + shader_header.type = shader->type(); + assert_not_null(shader_storage_file_); + fwrite(&shader_header, sizeof(shader_header), 1, shader_storage_file_); + if (shader_header.ucode_dword_count) { + ucode_guest_endian.resize(shader_header.ucode_dword_count); + // Need to swap because the hash is calculated for the shader with guest + // endianness. + memory::copy_and_swap(ucode_guest_endian.data(), shader->ucode_dwords(), + shader_header.ucode_dword_count); + fwrite(ucode_guest_endian.data(), shader_header.ucode_dword_count * sizeof(uint32_t), 1, + shader_storage_file_); + } + } + + if (write_pipeline) { + assert_not_null(pipeline_storage_file_); + fwrite(&pipeline_description, sizeof(pipeline_description), 1, pipeline_storage_file_); + } + } +} + +bool PipelineCache::PrepareRuntimeDescriptionForQueuedCreation( + Pipeline* pipeline, PipelineRuntimeDescription& runtime_description) { + assert_not_null(pipeline); + std::memcpy(&runtime_description, &pipeline->description, sizeof(runtime_description)); + runtime_description.root_signature = pipeline->root_signature.load(std::memory_order_acquire); + + auto translate_pending_shader = [this](D3D12Shader::D3D12Translation* translation, + const char* shader_type) -> bool { + if (!translation) { + return true; + } + if (!translation->is_translated()) { + std::lock_guard lock(translation_request_lock_); + if (!translation->is_translated()) { + translation->shader().AnalyzeUcode(ucode_disasm_buffer_); + if (!TranslateAnalyzedShader(*shader_translator_, *translation, dxbc_converter_, dxc_utils_, + dxc_compiler_)) { + REXGPU_ERROR("Failed to translate queued {} shader", shader_type); + return false; + } + if (shader_storage_file_ && + translation->shader().ucode_storage_index() != shader_storage_index_) { + translation->shader().set_ucode_storage_index(shader_storage_index_); + assert_not_null(storage_write_thread_); + shader_storage_file_flush_needed_ = true; + { + std::lock_guard storage_lock(storage_write_request_lock_); + storage_write_shader_queue_.push_back(&translation->shader()); + } + storage_write_request_cond_.notify_all(); + } + } + } + return translation->is_valid(); + }; + + if (pipeline->pending_vertex_shader) { + D3D12Shader::D3D12Translation* pending_vertex = pipeline->pending_vertex_shader; + pipeline->pending_vertex_shader = nullptr; + if (!translate_pending_shader(pending_vertex, "vertex")) { + return false; + } + } + + if (pipeline->pending_pixel_shader) { + D3D12Shader::D3D12Translation* pending_pixel = pipeline->pending_pixel_shader; + pipeline->pending_pixel_shader = nullptr; + if (!translate_pending_shader(pending_pixel, "pixel")) { + return false; + } + bool tessellated = Shader::IsHostVertexShaderTypeDomain( + DxbcShaderTranslator::Modification(runtime_description.vertex_shader->modification()) + .vertex.host_vertex_shader_type); + ID3D12RootSignature* root_signature = command_processor_.GetRootSignature( + static_cast(&runtime_description.vertex_shader->shader()), + static_cast(&pending_pixel->shader()), tessellated); + if (!root_signature) { + return false; + } + runtime_description.root_signature = root_signature; + pipeline->root_signature.store(root_signature, std::memory_order_release); + } + + return true; +} + +void PipelineCache::CreationThread(size_t thread_index) { + while (true) { + Pipeline* pipeline_to_create = nullptr; + + // Check if need to shut down or set the completion event and dequeue the + // pipeline if there is any. + { + std::unique_lock lock(creation_request_lock_); + if (thread_index >= creation_threads_shutdown_from_ || creation_queue_.empty()) { + if (creation_completion_set_event_ && creation_threads_busy_ == 0) { + // Last pipeline in the queue created - signal the event if requested. + creation_completion_set_event_ = false; + creation_completion_event_->Set(); + } + if (thread_index >= creation_threads_shutdown_from_) { + return; + } + creation_request_cond_.wait(lock); + continue; + } + // Take the pipeline from the queue and increment the busy thread count + // until the pipeline is created - other threads must be able to dequeue + // requests, but can't set the completion event until the pipelines are + // fully created (rather than just started creating). + pipeline_to_create = creation_queue_.top(); + creation_queue_.pop(); + ++creation_threads_busy_; + } + + PipelineRuntimeDescription runtime_description; + if (!PrepareRuntimeDescriptionForQueuedCreation(pipeline_to_create, runtime_description)) { + pipeline_to_create->state.store(nullptr, std::memory_order_release); + } else { + pipeline_to_create->state.store(CreateD3D12Pipeline(runtime_description), + std::memory_order_release); + } + + // Pipeline created - the thread is not busy anymore, safe to set the + // completion event if needed (at the next iteration, or in some other + // thread). + { + std::lock_guard lock(creation_request_lock_); + --creation_threads_busy_; + } + } +} + +void PipelineCache::CreateQueuedPipelinesOnProcessorThread() { + assert_false(creation_threads_.empty()); + while (true) { + Pipeline* pipeline_to_create; + { + std::lock_guard lock(creation_request_lock_); + if (creation_queue_.empty()) { + break; + } + pipeline_to_create = creation_queue_.top(); + creation_queue_.pop(); + } + PipelineRuntimeDescription runtime_description; + if (!PrepareRuntimeDescriptionForQueuedCreation(pipeline_to_create, runtime_description)) { + pipeline_to_create->state.store(nullptr, std::memory_order_release); + continue; + } + pipeline_to_create->state.store(CreateD3D12Pipeline(runtime_description), + std::memory_order_release); + } +} + +} // namespace rex::graphics::d3d12 diff --git a/src/graphics/d3d12/primitive_processor.cpp b/src/graphics/d3d12/primitive_processor.cpp new file mode 100644 index 0000000..500924e --- /dev/null +++ b/src/graphics/d3d12/primitive_processor.cpp @@ -0,0 +1,161 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace rex::graphics::d3d12 { + +D3D12PrimitiveProcessor::~D3D12PrimitiveProcessor() { + Shutdown(true); +} + +bool D3D12PrimitiveProcessor::Initialize() { + if (!InitializeCommon(true, false, false, true, true, true)) { + Shutdown(); + return false; + } + frame_index_buffer_pool_ = std::make_unique( + command_processor_.GetD3D12Provider(), + std::max(size_t(kMinRequiredConvertedIndexBufferSize), + ui::GraphicsUploadBufferPool::kDefaultPageSize)); + return true; +} + +void D3D12PrimitiveProcessor::Shutdown(bool from_destructor) { + frame_index_buffers_.clear(); + frame_index_buffer_pool_.reset(); + builtin_index_buffer_upload_.Reset(); + builtin_index_buffer_gpu_address_ = 0; + builtin_index_buffer_.Reset(); + if (!from_destructor) { + ShutdownCommon(); + } +} + +void D3D12PrimitiveProcessor::CompletedSubmissionUpdated() { + if (builtin_index_buffer_upload_ && + command_processor_.GetCompletedSubmission() >= builtin_index_buffer_upload_submission_) { + builtin_index_buffer_upload_.Reset(); + } +} + +void D3D12PrimitiveProcessor::BeginSubmission() { + if (builtin_index_buffer_upload_ && builtin_index_buffer_upload_submission_ == UINT64_MAX) { + // No need to submit deferred barriers - builtin_index_buffer_ has never + // been used yet, so it's in the initial state, and + // builtin_index_buffer_upload_ is in an upload heap, so it's GENERIC_READ. + command_processor_.GetDeferredCommandList().D3DCopyResource(builtin_index_buffer_.Get(), + builtin_index_buffer_upload_.Get()); + command_processor_.PushTransitionBarrier(builtin_index_buffer_.Get(), + D3D12_RESOURCE_STATE_COPY_DEST, + D3D12_RESOURCE_STATE_INDEX_BUFFER); + builtin_index_buffer_upload_submission_ = command_processor_.GetCurrentSubmission(); + } +} + +void D3D12PrimitiveProcessor::BeginFrame() { + frame_index_buffer_pool_->Reclaim(command_processor_.GetCompletedFrame()); +} + +void D3D12PrimitiveProcessor::EndFrame() { + ClearPerFrameCache(); + frame_index_buffers_.clear(); +} + +bool D3D12PrimitiveProcessor::InitializeBuiltinIndexBuffer( + size_t size_bytes, std::function fill_callback) { + assert_not_zero(size_bytes); + assert_null(builtin_index_buffer_); + assert_null(builtin_index_buffer_upload_); + + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + + D3D12_RESOURCE_DESC resource_desc; + ui::d3d12::util::FillBufferResourceDesc(resource_desc, UINT64(size_bytes), + D3D12_RESOURCE_FLAG_NONE); + Microsoft::WRL::ComPtr draw_resource; + if (FAILED(device->CreateCommittedResource( + &ui::d3d12::util::kHeapPropertiesDefault, provider.GetHeapFlagCreateNotZeroed(), + &resource_desc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&draw_resource)))) { + REXGPU_ERROR( + "D3D12 primitive processor: Failed to create the built-in index " + "buffer GPU resource with {} bytes", + size_bytes); + return false; + } + Microsoft::WRL::ComPtr upload_resource; + if (FAILED(device->CreateCommittedResource(&ui::d3d12::util::kHeapPropertiesUpload, + provider.GetHeapFlagCreateNotZeroed(), &resource_desc, + D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, + IID_PPV_ARGS(&upload_resource)))) { + REXGPU_ERROR( + "D3D12 primitive processor: Failed to create the built-in index " + "buffer upload resource with {} bytes", + size_bytes); + return false; + } + + D3D12_RANGE upload_read_range = {}; + void* mapping; + if (FAILED(upload_resource->Map(0, &upload_read_range, &mapping))) { + REXGPU_ERROR( + "D3D12 primitive processor: Failed to map the built-in index buffer " + "upload resource with {} bytes", + size_bytes); + return false; + } + fill_callback(reinterpret_cast(mapping)); + upload_resource->Unmap(0, nullptr); + + // Successfully created the buffer and wrote the data to upload. + builtin_index_buffer_ = std::move(draw_resource); + builtin_index_buffer_gpu_address_ = builtin_index_buffer_->GetGPUVirtualAddress(); + builtin_index_buffer_upload_ = std::move(upload_resource); + // Schedule uploading in the first submission. + builtin_index_buffer_upload_submission_ = UINT64_MAX; + return true; +} + +void* D3D12PrimitiveProcessor::RequestHostConvertedIndexBufferForCurrentFrame( + xenos::IndexFormat format, uint32_t index_count, bool coalign_for_simd, + uint32_t coalignment_original_address, size_t& backend_handle_out) { + size_t index_size = format == xenos::IndexFormat::kInt16 ? sizeof(uint16_t) : sizeof(uint32_t); + D3D12_GPU_VIRTUAL_ADDRESS gpu_address; + uint8_t* mapping = frame_index_buffer_pool_->Request( + command_processor_.GetCurrentFrame(), + index_size * index_count + (coalign_for_simd ? XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE : 0), + index_size, nullptr, nullptr, &gpu_address); + if (!mapping) { + return nullptr; + } + if (coalign_for_simd) { + ptrdiff_t coalignment_offset = GetSimdCoalignmentOffset(mapping, coalignment_original_address); + mapping += coalignment_offset; + gpu_address = D3D12_GPU_VIRTUAL_ADDRESS(gpu_address + coalignment_offset); + } + backend_handle_out = frame_index_buffers_.size(); + frame_index_buffers_.push_back(gpu_address); + return mapping; +} + +} // namespace rex::graphics::d3d12 diff --git a/src/graphics/d3d12/render_target_cache.cpp b/src/graphics/d3d12/render_target_cache.cpp new file mode 100644 index 0000000..8e269c4 --- /dev/null +++ b/src/graphics/d3d12/render_target_cache.cpp @@ -0,0 +1,5957 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include "thirdparty/dxbc/DXBCChecksum.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(native_stencil_value_output_d3d12_intel, false, "GPU/D3D12", + "Native stencil value output for Intel D3D12"); + +REXCVAR_DEFINE_STRING(render_target_path_d3d12, "", "GPU/D3D12", + "D3D12 render target implementation path") + .lifecycle(rex::cvar::Lifecycle::kInitOnly); + +REXCVAR_DEFINE_BOOL(native_stencil_value_output, true, "GPU", "Enable native stencil value output"); + +namespace rex::graphics::d3d12 { + +// Generated with `xb buildshaders`. +namespace shaders { +#include "../shaders/bytecode/d3d12_5_1/clear_uint2_ps.h" +#include "../shaders/bytecode/d3d12_5_1/fullscreen_cw_vs.h" +#include "../shaders/bytecode/d3d12_5_1/host_depth_store_1xmsaa_cs.h" +#include "../shaders/bytecode/d3d12_5_1/host_depth_store_2xmsaa_cs.h" +#include "../shaders/bytecode/d3d12_5_1/host_depth_store_4xmsaa_cs.h" +#include "../shaders/bytecode/d3d12_5_1/passthrough_position_xy_vs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_clear_32bpp_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_clear_32bpp_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_clear_64bpp_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_clear_64bpp_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_fast_32bpp_1x2xmsaa_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_fast_32bpp_1x2xmsaa_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_fast_32bpp_4xmsaa_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_fast_32bpp_4xmsaa_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_fast_64bpp_1x2xmsaa_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_fast_64bpp_1x2xmsaa_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_fast_64bpp_4xmsaa_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_fast_64bpp_4xmsaa_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_full_128bpp_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_full_128bpp_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_full_16bpp_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_full_16bpp_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_full_32bpp_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_full_32bpp_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_full_64bpp_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_full_64bpp_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_full_8bpp_cs.h" +#include "../shaders/bytecode/d3d12_5_1/resolve_full_8bpp_scaled_cs.h" +} // namespace shaders + +const D3D12RenderTargetCache::ResolveCopyShaderCode + D3D12RenderTargetCache::kResolveCopyShaders[size_t( + draw_util::ResolveCopyShaderIndex::kCount)] = { + {shaders::resolve_fast_32bpp_1x2xmsaa_cs, sizeof(shaders::resolve_fast_32bpp_1x2xmsaa_cs), + shaders::resolve_fast_32bpp_1x2xmsaa_scaled_cs, + sizeof(shaders::resolve_fast_32bpp_1x2xmsaa_scaled_cs)}, + {shaders::resolve_fast_32bpp_4xmsaa_cs, sizeof(shaders::resolve_fast_32bpp_4xmsaa_cs), + shaders::resolve_fast_32bpp_4xmsaa_scaled_cs, + sizeof(shaders::resolve_fast_32bpp_4xmsaa_scaled_cs)}, + {shaders::resolve_fast_64bpp_1x2xmsaa_cs, sizeof(shaders::resolve_fast_64bpp_1x2xmsaa_cs), + shaders::resolve_fast_64bpp_1x2xmsaa_scaled_cs, + sizeof(shaders::resolve_fast_64bpp_1x2xmsaa_scaled_cs)}, + {shaders::resolve_fast_64bpp_4xmsaa_cs, sizeof(shaders::resolve_fast_64bpp_4xmsaa_cs), + shaders::resolve_fast_64bpp_4xmsaa_scaled_cs, + sizeof(shaders::resolve_fast_64bpp_4xmsaa_scaled_cs)}, + {shaders::resolve_full_8bpp_cs, sizeof(shaders::resolve_full_8bpp_cs), + shaders::resolve_full_8bpp_scaled_cs, sizeof(shaders::resolve_full_8bpp_scaled_cs)}, + {shaders::resolve_full_16bpp_cs, sizeof(shaders::resolve_full_16bpp_cs), + shaders::resolve_full_16bpp_scaled_cs, sizeof(shaders::resolve_full_16bpp_scaled_cs)}, + {shaders::resolve_full_32bpp_cs, sizeof(shaders::resolve_full_32bpp_cs), + shaders::resolve_full_32bpp_scaled_cs, sizeof(shaders::resolve_full_32bpp_scaled_cs)}, + {shaders::resolve_full_64bpp_cs, sizeof(shaders::resolve_full_64bpp_cs), + shaders::resolve_full_64bpp_scaled_cs, sizeof(shaders::resolve_full_64bpp_scaled_cs)}, + {shaders::resolve_full_128bpp_cs, sizeof(shaders::resolve_full_128bpp_cs), + shaders::resolve_full_128bpp_scaled_cs, sizeof(shaders::resolve_full_128bpp_scaled_cs)}, +}; + +const uint32_t D3D12RenderTargetCache::kTransferUsedRootParameters[size_t( + TransferRootSignatureIndex::kCount)] = { + // kColor + kTransferUsedRootParameterColorSRVBit | kTransferUsedRootParameterAddressConstantBit, + // kDepth + kTransferUsedRootParameterDepthSRVBit | kTransferUsedRootParameterAddressConstantBit, + // kDepthStencil + kTransferUsedRootParameterDepthSRVBit | kTransferUsedRootParameterStencilSRVBit | + kTransferUsedRootParameterAddressConstantBit, + // kColorToStencilBit + kTransferUsedRootParameterStencilMaskConstantBit | kTransferUsedRootParameterColorSRVBit | + kTransferUsedRootParameterAddressConstantBit, + // kStencilToStencilBit + kTransferUsedRootParameterStencilMaskConstantBit | kTransferUsedRootParameterStencilSRVBit | + kTransferUsedRootParameterAddressConstantBit, + // kColorAndHostDepth + kTransferUsedRootParameterColorSRVBit | kTransferUsedRootParameterAddressConstantBit | + kTransferUsedRootParameterHostDepthSRVBit | + kTransferUsedRootParameterHostDepthAddressConstantBit, + // kDepthAndHostDepth + kTransferUsedRootParameterDepthSRVBit | kTransferUsedRootParameterAddressConstantBit | + kTransferUsedRootParameterHostDepthSRVBit | + kTransferUsedRootParameterHostDepthAddressConstantBit, + // kDepthStencilAndHostDepth + kTransferUsedRootParameterDepthSRVBit | kTransferUsedRootParameterStencilSRVBit | + kTransferUsedRootParameterAddressConstantBit | kTransferUsedRootParameterHostDepthSRVBit | + kTransferUsedRootParameterHostDepthAddressConstantBit, +}; + +const D3D12RenderTargetCache::TransferModeInfo + D3D12RenderTargetCache::kTransferModes[size_t(TransferMode::kCount)] = { + // kColorToDepth + {TransferOutput::kDepth, TransferRootSignatureIndex::kColor, + TransferRootSignatureIndex::kColor}, + // kColorToColor + {TransferOutput::kColor, TransferRootSignatureIndex::kColor, + TransferRootSignatureIndex::kColor}, + // kDepthToDepth + {TransferOutput::kDepth, TransferRootSignatureIndex::kDepth, + TransferRootSignatureIndex::kDepthStencil}, + // kDepthToColor + {TransferOutput::kColor, TransferRootSignatureIndex::kDepthStencil, + TransferRootSignatureIndex::kDepthStencil}, + // kColorToStencilBit + {TransferOutput::kStencilBit, TransferRootSignatureIndex::kColorToStencilBit, + TransferRootSignatureIndex::kColorToStencilBit}, + // kDepthToStencilBit + {TransferOutput::kStencilBit, TransferRootSignatureIndex::kStencilToStencilBit, + TransferRootSignatureIndex::kStencilToStencilBit}, + // kColorAndHostDepthToDepth + {TransferOutput::kDepth, TransferRootSignatureIndex::kColorAndHostDepth, + TransferRootSignatureIndex::kColorAndHostDepth}, + // kDepthAndHostDepthToDepth + {TransferOutput::kDepth, TransferRootSignatureIndex::kDepthAndHostDepth, + TransferRootSignatureIndex::kDepthStencilAndHostDepth}, +}; + +D3D12RenderTargetCache::~D3D12RenderTargetCache() { + Shutdown(true); +} + +bool D3D12RenderTargetCache::Initialize() { + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + + if (REXCVAR_GET(render_target_path_d3d12) == "rtv") { + path_ = Path::kHostRenderTargets; + } else if (REXCVAR_GET(render_target_path_d3d12) == "rov") { + path_ = Path::kPixelShaderInterlock; + } else { + // As of April 2021 (driver version 27.20.0100.9316), on Intel (tested on + // UHD Graphics 630), the "always" stencil comparison function isn't working + // properly, so clears in the Xbox 360's Direct3D 9 don't work. Forcing ROV + // there. +#if 1 + // The ROV path is currently much slower generally. + // TODO(Triang3l): Make ROV the default when it's optimized better (for + // instance, using static shader modifications to pass render target + // parameters). + path_ = provider.GetAdapterVendorID() == ui::GraphicsProvider::GpuVendorID::kIntel + ? Path::kPixelShaderInterlock + : Path::kHostRenderTargets; +#else + // The AMD shader compiler crashes very often with Xenia's custom + // output-merger code as of March 2021. + path_ = provider.GetAdapterVendorID() == ui::GraphicsProvider::GpuVendorID::kAMD + ? Path::kHostRenderTargets + : Path::kPixelShaderInterlock; +#endif + } + if (path_ == Path::kPixelShaderInterlock && !provider.AreRasterizerOrderedViewsSupported()) { + path_ = Path::kHostRenderTargets; + } + + // Create the buffer for reinterpreting EDRAM contents. + uint32_t edram_buffer_size = + xenos::kEdramSizeBytes * (draw_resolution_scale_x() * draw_resolution_scale_y()); + D3D12_RESOURCE_DESC edram_buffer_desc; + ui::d3d12::util::FillBufferResourceDesc(edram_buffer_desc, edram_buffer_size, + D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); + // The first operation will likely be depth self-comparison with host render + // targets or drawing with ROV. + edram_buffer_state_ = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + // Creating zeroed for stable initial value with ROV (though on a real + // console it has to be cleared anyway probably) and not to leak irrelevant + // data to trace dumps when not covered by host render targets entirely. + if (FAILED(device->CreateCommittedResource( + &ui::d3d12::util::kHeapPropertiesDefault, D3D12_HEAP_FLAG_NONE, &edram_buffer_desc, + edram_buffer_state_, nullptr, IID_PPV_ARGS(&edram_buffer_)))) { + REXGPU_ERROR("D3D12RenderTargetCache: Failed to create the EDRAM buffer"); + Shutdown(); + return false; + } + edram_buffer_->SetName(L"EDRAM Buffer"); + edram_buffer_modification_status_ = EdramBufferModificationStatus::kUnmodified; + + // Create non-shader-visible descriptors of the EDRAM buffer for copying. + D3D12_DESCRIPTOR_HEAP_DESC edram_buffer_descriptor_heap_desc; + edram_buffer_descriptor_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + edram_buffer_descriptor_heap_desc.NumDescriptors = uint32_t(EdramBufferDescriptorIndex::kCount); + edram_buffer_descriptor_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + edram_buffer_descriptor_heap_desc.NodeMask = 0; + if (FAILED(device->CreateDescriptorHeap(&edram_buffer_descriptor_heap_desc, + IID_PPV_ARGS(&edram_buffer_descriptor_heap_)))) { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to create the descriptor heap for " + "EDRAM buffer views"); + Shutdown(); + return false; + } + edram_buffer_descriptor_heap_start_ = + edram_buffer_descriptor_heap_->GetCPUDescriptorHandleForHeapStart(); + ui::d3d12::util::CreateBufferRawSRV( + device, + provider.OffsetViewDescriptor(edram_buffer_descriptor_heap_start_, + uint32_t(EdramBufferDescriptorIndex::kRawSRV)), + edram_buffer_, edram_buffer_size); + ui::d3d12::util::CreateBufferTypedSRV( + device, + provider.OffsetViewDescriptor(edram_buffer_descriptor_heap_start_, + uint32_t(EdramBufferDescriptorIndex::kR32UintSRV)), + edram_buffer_, DXGI_FORMAT_R32_UINT, edram_buffer_size >> 2); + ui::d3d12::util::CreateBufferTypedSRV( + device, + provider.OffsetViewDescriptor(edram_buffer_descriptor_heap_start_, + uint32_t(EdramBufferDescriptorIndex::kR32G32UintSRV)), + edram_buffer_, DXGI_FORMAT_R32G32_UINT, edram_buffer_size >> 3); + ui::d3d12::util::CreateBufferTypedSRV( + device, + provider.OffsetViewDescriptor(edram_buffer_descriptor_heap_start_, + uint32_t(EdramBufferDescriptorIndex::kR32G32B32A32UintSRV)), + edram_buffer_, DXGI_FORMAT_R32G32B32A32_UINT, edram_buffer_size >> 4); + ui::d3d12::util::CreateBufferRawUAV( + device, + provider.OffsetViewDescriptor(edram_buffer_descriptor_heap_start_, + uint32_t(EdramBufferDescriptorIndex::kRawUAV)), + edram_buffer_, edram_buffer_size); + ui::d3d12::util::CreateBufferTypedUAV( + device, + provider.OffsetViewDescriptor(edram_buffer_descriptor_heap_start_, + uint32_t(EdramBufferDescriptorIndex::kR32UintUAV)), + edram_buffer_, DXGI_FORMAT_R32_UINT, edram_buffer_size >> 2); + ui::d3d12::util::CreateBufferTypedUAV( + device, + provider.OffsetViewDescriptor(edram_buffer_descriptor_heap_start_, + uint32_t(EdramBufferDescriptorIndex::kR32G32UintUAV)), + edram_buffer_, DXGI_FORMAT_R32G32_UINT, edram_buffer_size >> 3); + ui::d3d12::util::CreateBufferTypedUAV( + device, + provider.OffsetViewDescriptor(edram_buffer_descriptor_heap_start_, + uint32_t(EdramBufferDescriptorIndex::kR32G32B32A32UintUAV)), + edram_buffer_, DXGI_FORMAT_R32G32B32A32_UINT, edram_buffer_size >> 4); + + bool draw_resolution_scaled = IsDrawResolutionScaled(); + + // Create the resolve copying root signature. + std::array resolve_copy_root_parameters; + // Parameter 0 is constants. + resolve_copy_root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + resolve_copy_root_parameters[0].Constants.ShaderRegister = 0; + resolve_copy_root_parameters[0].Constants.RegisterSpace = 0; + // Binding all of the shared memory at 1x resolution, portions with scaled + // resolution. + resolve_copy_root_parameters[0].Constants.Num32BitValues = + (draw_resolution_scaled ? sizeof(draw_util::ResolveCopyShaderConstants::DestRelative) + : sizeof(draw_util::ResolveCopyShaderConstants)) / + sizeof(uint32_t); + resolve_copy_root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + // Parameter 1 is the destination (shared memory). + D3D12_DESCRIPTOR_RANGE resolve_copy_dest_range; + resolve_copy_dest_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + resolve_copy_dest_range.NumDescriptors = 1; + resolve_copy_dest_range.BaseShaderRegister = 0; + resolve_copy_dest_range.RegisterSpace = 0; + resolve_copy_dest_range.OffsetInDescriptorsFromTableStart = 0; + resolve_copy_root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + resolve_copy_root_parameters[1].DescriptorTable.NumDescriptorRanges = 1; + resolve_copy_root_parameters[1].DescriptorTable.pDescriptorRanges = &resolve_copy_dest_range; + resolve_copy_root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + // Parameter 2 is the source (EDRAM). + D3D12_DESCRIPTOR_RANGE resolve_copy_source_range; + resolve_copy_source_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + resolve_copy_source_range.NumDescriptors = 1; + resolve_copy_source_range.BaseShaderRegister = 0; + resolve_copy_source_range.RegisterSpace = 0; + resolve_copy_source_range.OffsetInDescriptorsFromTableStart = 0; + resolve_copy_root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + resolve_copy_root_parameters[2].DescriptorTable.NumDescriptorRanges = 1; + resolve_copy_root_parameters[2].DescriptorTable.pDescriptorRanges = &resolve_copy_source_range; + resolve_copy_root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + D3D12_ROOT_SIGNATURE_DESC resolve_copy_root_signature_desc; + resolve_copy_root_signature_desc.NumParameters = UINT(resolve_copy_root_parameters.size()); + resolve_copy_root_signature_desc.pParameters = resolve_copy_root_parameters.data(); + resolve_copy_root_signature_desc.NumStaticSamplers = 0; + resolve_copy_root_signature_desc.pStaticSamplers = nullptr; + resolve_copy_root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; + resolve_copy_root_signature_ = + ui::d3d12::util::CreateRootSignature(provider, resolve_copy_root_signature_desc); + if (resolve_copy_root_signature_ == nullptr) { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to create the resolve copy root " + "signature"); + Shutdown(); + return false; + } + // Direct resolve currently shares the root signature shape with the resolve + // copy pass (constants + destination UAV + source SRV) and may diverge later. + direct_resolve_root_signature_color_ = resolve_copy_root_signature_; + direct_resolve_root_signature_depth_ = resolve_copy_root_signature_; + direct_resolve_root_signature_color_->AddRef(); + direct_resolve_root_signature_depth_->AddRef(); + + // Create the resolve copying pipelines. + for (size_t i = 0; i < size_t(draw_util::ResolveCopyShaderIndex::kCount); ++i) { + const draw_util::ResolveCopyShaderInfo& resolve_copy_shader_info = + draw_util::resolve_copy_shader_info[i]; + const ResolveCopyShaderCode& resolve_copy_shader_code = kResolveCopyShaders[i]; + // Somewhat verification whether resolve_copy_shaders_ is up to date. + assert_true(resolve_copy_shader_code.unscaled && resolve_copy_shader_code.unscaled_size && + resolve_copy_shader_code.scaled && resolve_copy_shader_code.scaled_size); + ID3D12PipelineState* resolve_copy_pipeline = ui::d3d12::util::CreateComputePipeline( + device, + draw_resolution_scaled ? resolve_copy_shader_code.scaled + : resolve_copy_shader_code.unscaled, + draw_resolution_scaled ? resolve_copy_shader_code.scaled_size + : resolve_copy_shader_code.unscaled_size, + resolve_copy_root_signature_); + if (resolve_copy_pipeline == nullptr) { + REXGPU_ERROR("D3D12RenderTargetCache: Failed to create {} resolve copy pipeline", + resolve_copy_shader_info.debug_name); + Shutdown(); + return false; + } + std::u16string resolve_copy_pipeline_name = + rex::string::to_utf16(resolve_copy_shader_info.debug_name); + resolve_copy_pipeline->SetName(reinterpret_cast(resolve_copy_pipeline_name.c_str())); + resolve_copy_pipelines_[i] = resolve_copy_pipeline; + } + + // Using the cvar on emulator initialization so used pipelines are consistent + // across different titles launched in one emulator instance. + use_stencil_reference_output_ = + REXCVAR_GET(native_stencil_value_output) && + provider.IsPSSpecifiedStencilReferenceSupported() && + (REXCVAR_GET(native_stencil_value_output_d3d12_intel) || + provider.GetAdapterVendorID() != ui::GraphicsProvider::GpuVendorID::kIntel); + + if (path_ == Path::kHostRenderTargets) { + // Host render targets. + + gamma_render_target_as_unorm16_ = REXCVAR_GET(gamma_render_target_as_unorm16); + + depth_float24_round_ = REXCVAR_GET(depth_float24_round); + depth_float24_convert_in_pixel_shader_ = REXCVAR_GET(depth_float24_convert_in_pixel_shader); + + // Check if 2x MSAA is supported or needs to be emulated with 4x MSAA + // instead. + if (REXCVAR_GET(native_2x_msaa)) { + msaa_2x_supported_ = true; + static const DXGI_FORMAT kRenderTargetDXGIFormats[] = { + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_SNORM, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_D32_FLOAT_S8X24_UINT, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_R16G16_SNORM, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_D24_UNORM_S8_UINT, + // For ownership transfer. + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R32G32_UINT, + DXGI_FORMAT_R16G16_UINT, + DXGI_FORMAT_R32_UINT, + }; + D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS multisample_quality_levels; + multisample_quality_levels.SampleCount = 2; + multisample_quality_levels.Flags = D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE; + for (size_t i = 0; i < rex::countof(kRenderTargetDXGIFormats); ++i) { + multisample_quality_levels.Format = kRenderTargetDXGIFormats[i]; + multisample_quality_levels.NumQualityLevels = 0; + if (FAILED(device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, + &multisample_quality_levels, + sizeof(multisample_quality_levels))) || + !multisample_quality_levels.NumQualityLevels) { + msaa_2x_supported_ = false; + break; + } + } + } else { + msaa_2x_supported_ = false; + } + if (msaa_2x_supported_ && gamma_render_target_as_unorm16_) { + D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS multisample_quality_levels; + multisample_quality_levels.SampleCount = 2; + multisample_quality_levels.Flags = D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE; + multisample_quality_levels.Format = DXGI_FORMAT_R16G16B16A16_UNORM; + multisample_quality_levels.NumQualityLevels = 0; + if (FAILED(device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, + &multisample_quality_levels, + sizeof(multisample_quality_levels))) || + !multisample_quality_levels.NumQualityLevels) { + msaa_2x_supported_ = false; + } + } + if (!msaa_2x_supported_) { + REXGPU_WARN( + "2x MSAA is not supported, emulated via top-left and bottom-right " + "samples of 4x MSAA"); + } + + descriptor_pool_color_ = std::make_unique( + provider, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 11); + descriptor_pool_depth_ = std::make_unique( + provider, D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 11); + descriptor_pool_srv_ = std::make_unique( + provider, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 11); + + // Create null render target descriptors for gaps, must be fully typed + // (though in pipeline states, DXGI_FORMAT_UNKNOWN must be used instead - + // this would also cause a mismatching format error in the debug layer, but + // it's a bug in the debug layer itself - needs to be suppressed, and + // already fixed in some version of Windows). + null_rtv_descriptor_ss_ = descriptor_pool_color_->AllocateDescriptor(); + null_rtv_descriptor_ms_ = descriptor_pool_color_->AllocateDescriptor(); + if (!null_rtv_descriptor_ss_ || !null_rtv_descriptor_ms_) { + Shutdown(); + return false; + } + D3D12_RENDER_TARGET_VIEW_DESC null_rtv_desc; + // The format doesn't matter, but it must be bindable as a render target, + // not DXGI_FORMAT_UNKNOWN. + null_rtv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + null_rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + null_rtv_desc.Texture2D.MipSlice = 0; + null_rtv_desc.Texture2D.PlaneSlice = 0; + device->CreateRenderTargetView(nullptr, &null_rtv_desc, null_rtv_descriptor_ss_.GetHandle()); + null_rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMS; + device->CreateRenderTargetView(nullptr, &null_rtv_desc, null_rtv_descriptor_ms_.GetHandle()); + + // For host depth -> same depth transfers, host depth storing root signature + // and pipelines. + D3D12_ROOT_PARAMETER + host_depth_store_root_parameters[kHostDepthStoreRootParameterCount]; + // Constants. + D3D12_ROOT_PARAMETER& host_depth_store_root_constants = + host_depth_store_root_parameters[kHostDepthStoreRootParameterConstants]; + host_depth_store_root_constants.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + host_depth_store_root_constants.Constants.ShaderRegister = 0; + host_depth_store_root_constants.Constants.RegisterSpace = 0; + host_depth_store_root_constants.Constants.Num32BitValues = + sizeof(HostDepthStoreConstants) / sizeof(uint32_t); + host_depth_store_root_constants.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + // Source. + D3D12_DESCRIPTOR_RANGE host_depth_store_root_source_range; + host_depth_store_root_source_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + host_depth_store_root_source_range.NumDescriptors = 1; + host_depth_store_root_source_range.BaseShaderRegister = 0; + host_depth_store_root_source_range.RegisterSpace = 0; + host_depth_store_root_source_range.OffsetInDescriptorsFromTableStart = 0; + D3D12_ROOT_PARAMETER& host_depth_store_root_source = + host_depth_store_root_parameters[kHostDepthStoreRootParameterSource]; + host_depth_store_root_source.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + host_depth_store_root_source.DescriptorTable.NumDescriptorRanges = 1; + host_depth_store_root_source.DescriptorTable.pDescriptorRanges = + &host_depth_store_root_source_range; + host_depth_store_root_source.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + // Destination. + D3D12_DESCRIPTOR_RANGE host_depth_store_root_dest_range; + host_depth_store_root_dest_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + host_depth_store_root_dest_range.NumDescriptors = 1; + host_depth_store_root_dest_range.BaseShaderRegister = 0; + host_depth_store_root_dest_range.RegisterSpace = 0; + host_depth_store_root_dest_range.OffsetInDescriptorsFromTableStart = 0; + D3D12_ROOT_PARAMETER& host_depth_store_root_dest = + host_depth_store_root_parameters[kHostDepthStoreRootParameterDest]; + host_depth_store_root_dest.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + host_depth_store_root_dest.DescriptorTable.NumDescriptorRanges = 1; + host_depth_store_root_dest.DescriptorTable.pDescriptorRanges = + &host_depth_store_root_dest_range; + host_depth_store_root_dest.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + // Root signature. + D3D12_ROOT_SIGNATURE_DESC host_depth_store_root_desc; + host_depth_store_root_desc.NumParameters = UINT(rex::countof(host_depth_store_root_parameters)); + host_depth_store_root_desc.pParameters = host_depth_store_root_parameters; + host_depth_store_root_desc.NumStaticSamplers = 0; + host_depth_store_root_desc.pStaticSamplers = nullptr; + host_depth_store_root_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; + host_depth_store_root_signature_ = + ui::d3d12::util::CreateRootSignature(provider, host_depth_store_root_desc); + if (!host_depth_store_root_signature_) { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to create the host depth storing " + "root signature"); + Shutdown(); + return false; + } + // Pipelines. + // 1 sample. + host_depth_store_pipelines_[size_t(xenos::MsaaSamples::k1X)] = + ui::d3d12::util::CreateComputePipeline(device, shaders::host_depth_store_1xmsaa_cs, + sizeof(shaders::host_depth_store_1xmsaa_cs), + host_depth_store_root_signature_); + if (!host_depth_store_pipelines_[size_t(xenos::MsaaSamples::k1X)]) { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to create the 1-sample host depth " + "storing pipeline"); + Shutdown(); + return false; + } + host_depth_store_pipelines_[size_t(xenos::MsaaSamples::k1X)]->SetName( + L"Host Depth Store 1xMSAA"); + // 2 samples. + host_depth_store_pipelines_[size_t(xenos::MsaaSamples::k2X)] = + ui::d3d12::util::CreateComputePipeline(device, shaders::host_depth_store_2xmsaa_cs, + sizeof(shaders::host_depth_store_2xmsaa_cs), + host_depth_store_root_signature_); + if (!host_depth_store_pipelines_[size_t(xenos::MsaaSamples::k2X)]) { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to create the 2-sample host depth " + "storing pipeline"); + Shutdown(); + return false; + } + host_depth_store_pipelines_[size_t(xenos::MsaaSamples::k2X)]->SetName( + L"Host Depth Store 2xMSAA"); + // 4 samples. + host_depth_store_pipelines_[size_t(xenos::MsaaSamples::k4X)] = + ui::d3d12::util::CreateComputePipeline(device, shaders::host_depth_store_4xmsaa_cs, + sizeof(shaders::host_depth_store_4xmsaa_cs), + host_depth_store_root_signature_); + if (!host_depth_store_pipelines_[size_t(xenos::MsaaSamples::k4X)]) { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to create the 4-sample host depth " + "storing pipeline"); + Shutdown(); + return false; + } + host_depth_store_pipelines_[size_t(xenos::MsaaSamples::k4X)]->SetName( + L"Host Depth Store 4xMSAA"); + + // Transfer and clear vertex buffer, for quads of up to tile granularity. + transfer_vertex_buffer_pool_ = std::make_unique( + provider, std::max(ui::d3d12::D3D12UploadBufferPool::kDefaultPageSize, + sizeof(float) * 2 * 6 * Transfer::kMaxCutoutBorderRectangles * + xenos::kEdramTileCount)); + + // Transfer root signatures. + D3D12_DESCRIPTOR_RANGE transfer_root_color_srv_range; + transfer_root_color_srv_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + transfer_root_color_srv_range.NumDescriptors = 1; + transfer_root_color_srv_range.BaseShaderRegister = kTransferSRVRegisterColor; + transfer_root_color_srv_range.RegisterSpace = 0; + transfer_root_color_srv_range.OffsetInDescriptorsFromTableStart = 0; + D3D12_DESCRIPTOR_RANGE transfer_root_depth_srv_range; + transfer_root_depth_srv_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + transfer_root_depth_srv_range.NumDescriptors = 1; + transfer_root_depth_srv_range.BaseShaderRegister = kTransferSRVRegisterDepth; + transfer_root_depth_srv_range.RegisterSpace = 0; + transfer_root_depth_srv_range.OffsetInDescriptorsFromTableStart = 0; + D3D12_DESCRIPTOR_RANGE transfer_root_stencil_srv_range; + transfer_root_stencil_srv_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + transfer_root_stencil_srv_range.NumDescriptors = 1; + transfer_root_stencil_srv_range.BaseShaderRegister = kTransferSRVRegisterStencil; + transfer_root_stencil_srv_range.RegisterSpace = 0; + transfer_root_stencil_srv_range.OffsetInDescriptorsFromTableStart = 0; + D3D12_DESCRIPTOR_RANGE transfer_root_host_depth_srv_range; + transfer_root_host_depth_srv_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + transfer_root_host_depth_srv_range.NumDescriptors = 1; + transfer_root_host_depth_srv_range.BaseShaderRegister = kTransferSRVRegisterHostDepth; + transfer_root_host_depth_srv_range.RegisterSpace = 0; + transfer_root_host_depth_srv_range.OffsetInDescriptorsFromTableStart = 0; + D3D12_ROOT_PARAMETER + transfer_root_parameters[kTransferUsedRootParameterCount]; + D3D12_ROOT_SIGNATURE_DESC transfer_root_desc; + transfer_root_desc.pParameters = transfer_root_parameters; + transfer_root_desc.NumStaticSamplers = 0; + transfer_root_desc.pStaticSamplers = nullptr; + transfer_root_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + for (size_t i = 0; i < size_t(TransferRootSignatureIndex::kCount); ++i) { + uint32_t transfer_root_mask = kTransferUsedRootParameters[i]; + // Stencil mask constant. + if (transfer_root_mask & kTransferUsedRootParameterStencilMaskConstantBit) { + D3D12_ROOT_PARAMETER& transfer_root_stencil_mask_constant = + transfer_root_parameters[rex::bit_count( + transfer_root_mask & (kTransferUsedRootParameterStencilMaskConstantBit - 1))]; + transfer_root_stencil_mask_constant.ParameterType = + D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + transfer_root_stencil_mask_constant.Constants.ShaderRegister = + kTransferCBVRegisterStencilMask; + transfer_root_stencil_mask_constant.Constants.RegisterSpace = 0; + transfer_root_stencil_mask_constant.Constants.Num32BitValues = 1; + transfer_root_stencil_mask_constant.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + } + // Color SRV. + if (transfer_root_mask & kTransferUsedRootParameterColorSRVBit) { + D3D12_ROOT_PARAMETER& transfer_root_color_srv = transfer_root_parameters[rex::bit_count( + transfer_root_mask & (kTransferUsedRootParameterColorSRVBit - 1))]; + transfer_root_color_srv.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + transfer_root_color_srv.DescriptorTable.NumDescriptorRanges = 1; + transfer_root_color_srv.DescriptorTable.pDescriptorRanges = &transfer_root_color_srv_range; + transfer_root_color_srv.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + } + // Depth SRV. + if (transfer_root_mask & kTransferUsedRootParameterDepthSRVBit) { + D3D12_ROOT_PARAMETER& transfer_root_depth_srv = transfer_root_parameters[rex::bit_count( + transfer_root_mask & (kTransferUsedRootParameterDepthSRVBit - 1))]; + transfer_root_depth_srv.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + transfer_root_depth_srv.DescriptorTable.NumDescriptorRanges = 1; + transfer_root_depth_srv.DescriptorTable.pDescriptorRanges = &transfer_root_depth_srv_range; + transfer_root_depth_srv.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + } + // Stencil SRV. + if (transfer_root_mask & kTransferUsedRootParameterStencilSRVBit) { + D3D12_ROOT_PARAMETER& transfer_root_stencil_srv = transfer_root_parameters[rex::bit_count( + transfer_root_mask & (kTransferUsedRootParameterStencilSRVBit - 1))]; + transfer_root_stencil_srv.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + transfer_root_stencil_srv.DescriptorTable.NumDescriptorRanges = 1; + transfer_root_stencil_srv.DescriptorTable.pDescriptorRanges = + &transfer_root_stencil_srv_range; + transfer_root_stencil_srv.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + } + // Address constant. + if (transfer_root_mask & kTransferUsedRootParameterAddressConstantBit) { + D3D12_ROOT_PARAMETER& transfer_root_address_constant = + transfer_root_parameters[rex::bit_count( + transfer_root_mask & (kTransferUsedRootParameterAddressConstantBit - 1))]; + transfer_root_address_constant.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + transfer_root_address_constant.Constants.ShaderRegister = kTransferCBVRegisterAddress; + transfer_root_address_constant.Constants.RegisterSpace = 0; + transfer_root_address_constant.Constants.Num32BitValues = + sizeof(TransferAddressConstant) / sizeof(uint32_t); + transfer_root_address_constant.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + } + // Host depth SRV. + if (transfer_root_mask & kTransferUsedRootParameterHostDepthSRVBit) { + D3D12_ROOT_PARAMETER& transfer_root_host_depth_srv = + transfer_root_parameters[rex::bit_count( + transfer_root_mask & (kTransferUsedRootParameterHostDepthSRVBit - 1))]; + transfer_root_host_depth_srv.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + transfer_root_host_depth_srv.DescriptorTable.NumDescriptorRanges = 1; + transfer_root_host_depth_srv.DescriptorTable.pDescriptorRanges = + &transfer_root_host_depth_srv_range; + transfer_root_host_depth_srv.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + } + // Host depth address constant. + if (transfer_root_mask & kTransferUsedRootParameterHostDepthAddressConstantBit) { + D3D12_ROOT_PARAMETER& transfer_root_host_address_constant = + transfer_root_parameters[rex::bit_count( + transfer_root_mask & (kTransferUsedRootParameterHostDepthAddressConstantBit - 1))]; + transfer_root_host_address_constant.ParameterType = + D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + transfer_root_host_address_constant.Constants.ShaderRegister = + kTransferCBVRegisterHostDepthAddress; + transfer_root_host_address_constant.Constants.RegisterSpace = 0; + transfer_root_host_address_constant.Constants.Num32BitValues = + sizeof(TransferAddressConstant) / sizeof(uint32_t); + transfer_root_host_address_constant.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + } + transfer_root_desc.NumParameters = rex::bit_count(transfer_root_mask); + assert_true(transfer_root_desc.NumParameters <= kTransferUsedRootParameterCount); + transfer_root_signatures_[i] = + ui::d3d12::util::CreateRootSignature(provider, transfer_root_desc); + if (!transfer_root_signatures_[i]) { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to create the render target " + "ownership transfer root signature {:X}", + transfer_root_mask); + Shutdown(); + return false; + } + } + + // Dumping root signatures. + D3D12_DESCRIPTOR_RANGE dump_root_source_range; + dump_root_source_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + dump_root_source_range.NumDescriptors = 1; + dump_root_source_range.BaseShaderRegister = 0; + dump_root_source_range.RegisterSpace = 0; + dump_root_source_range.OffsetInDescriptorsFromTableStart = 0; + D3D12_DESCRIPTOR_RANGE dump_root_stencil_range; + dump_root_stencil_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + dump_root_stencil_range.NumDescriptors = 1; + dump_root_stencil_range.BaseShaderRegister = 1; + dump_root_stencil_range.RegisterSpace = 0; + dump_root_stencil_range.OffsetInDescriptorsFromTableStart = 0; + D3D12_DESCRIPTOR_RANGE dump_root_edram_range; + dump_root_edram_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + dump_root_edram_range.NumDescriptors = 1; + dump_root_edram_range.BaseShaderRegister = 0; + dump_root_edram_range.RegisterSpace = 0; + dump_root_edram_range.OffsetInDescriptorsFromTableStart = 0; + D3D12_ROOT_PARAMETER + dump_root_color_parameters[kDumpRootParameterColorCount]; + D3D12_ROOT_PARAMETER + dump_root_depth_parameters[kDumpRootParameterDepthCount]; + for (uint32_t i = 0; i < 2; ++i) { + // Offsets. + D3D12_ROOT_PARAMETER& dump_root_offsets = + i ? dump_root_depth_parameters[kDumpRootParameterOffsets] + : dump_root_color_parameters[kDumpRootParameterOffsets]; + dump_root_offsets.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + dump_root_offsets.Constants.ShaderRegister = kDumpCbufferOffsets; + dump_root_offsets.Constants.RegisterSpace = 0; + dump_root_offsets.Constants.Num32BitValues = sizeof(DumpOffsets) / sizeof(uint32_t); + dump_root_offsets.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + // Source. + D3D12_ROOT_PARAMETER& dump_root_source = + i ? dump_root_depth_parameters[kDumpRootParameterSource] + : dump_root_color_parameters[kDumpRootParameterSource]; + dump_root_source.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + dump_root_source.DescriptorTable.NumDescriptorRanges = 1; + dump_root_source.DescriptorTable.pDescriptorRanges = &dump_root_source_range; + dump_root_source.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + // Stencil. + if (i) { + D3D12_ROOT_PARAMETER& dump_root_stencil = + dump_root_depth_parameters[kDumpRootParameterDepthStencil]; + dump_root_stencil.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + dump_root_stencil.DescriptorTable.NumDescriptorRanges = 1; + dump_root_stencil.DescriptorTable.pDescriptorRanges = &dump_root_stencil_range; + dump_root_stencil.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + // Pitches. + D3D12_ROOT_PARAMETER& dump_root_pitches = + i ? dump_root_depth_parameters[kDumpRootParameterDepthPitches] + : dump_root_color_parameters[kDumpRootParameterColorPitches]; + dump_root_pitches.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + dump_root_pitches.Constants.ShaderRegister = kDumpCbufferPitches; + dump_root_pitches.Constants.RegisterSpace = 0; + dump_root_pitches.Constants.Num32BitValues = sizeof(DumpPitches) / sizeof(uint32_t); + dump_root_pitches.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + // EDRAM. + D3D12_ROOT_PARAMETER& dump_root_edram = + i ? dump_root_depth_parameters[kDumpRootParameterDepthEdram] + : dump_root_color_parameters[kDumpRootParameterColorEdram]; + dump_root_edram.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + dump_root_edram.DescriptorTable.NumDescriptorRanges = 1; + dump_root_edram.DescriptorTable.pDescriptorRanges = &dump_root_edram_range; + dump_root_edram.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + D3D12_ROOT_SIGNATURE_DESC dump_root_desc; + dump_root_desc.NumParameters = UINT(rex::countof(dump_root_color_parameters)); + dump_root_desc.pParameters = dump_root_color_parameters; + dump_root_desc.NumStaticSamplers = 0; + dump_root_desc.pStaticSamplers = nullptr; + dump_root_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; + dump_root_signature_color_ = ui::d3d12::util::CreateRootSignature(provider, dump_root_desc); + if (!dump_root_signature_color_) { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to create the color render target " + "dumping root signature"); + Shutdown(); + return false; + } + dump_root_desc.NumParameters = UINT(rex::countof(dump_root_depth_parameters)); + dump_root_desc.pParameters = dump_root_depth_parameters; + dump_root_signature_depth_ = ui::d3d12::util::CreateRootSignature(provider, dump_root_desc); + if (!dump_root_signature_depth_) { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to create the depth render target " + "dumping root signature"); + Shutdown(); + return false; + } + + // k_32_FLOAT and k_32_32_FLOAT clear root signature and pipelines. + D3D12_ROOT_PARAMETER uint32_rtv_clear_root_constants; + uint32_rtv_clear_root_constants.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + uint32_rtv_clear_root_constants.Constants.ShaderRegister = 0; + uint32_rtv_clear_root_constants.Constants.RegisterSpace = 0; + uint32_rtv_clear_root_constants.Constants.Num32BitValues = 2; + uint32_rtv_clear_root_constants.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + D3D12_ROOT_SIGNATURE_DESC uint32_rtv_clear_root_desc; + uint32_rtv_clear_root_desc.NumParameters = 1; + uint32_rtv_clear_root_desc.pParameters = &uint32_rtv_clear_root_constants; + uint32_rtv_clear_root_desc.NumStaticSamplers = 0; + uint32_rtv_clear_root_desc.pStaticSamplers = nullptr; + uint32_rtv_clear_root_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; + uint32_rtv_clear_root_signature_ = + ui::d3d12::util::CreateRootSignature(provider, uint32_rtv_clear_root_desc); + if (!uint32_rtv_clear_root_signature_) { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to create the k_32_FLOAT / " + "k_32_32_FLOAT render target clearing root signature"); + Shutdown(); + return false; + } + D3D12_GRAPHICS_PIPELINE_STATE_DESC uint32_rtv_clear_pipeline_desc = {}; + uint32_rtv_clear_pipeline_desc.pRootSignature = uint32_rtv_clear_root_signature_; + uint32_rtv_clear_pipeline_desc.VS.pShaderBytecode = shaders::fullscreen_cw_vs; + uint32_rtv_clear_pipeline_desc.VS.BytecodeLength = sizeof(shaders::fullscreen_cw_vs); + uint32_rtv_clear_pipeline_desc.PS.pShaderBytecode = shaders::clear_uint2_ps; + uint32_rtv_clear_pipeline_desc.PS.BytecodeLength = sizeof(shaders::clear_uint2_ps); + uint32_rtv_clear_pipeline_desc.BlendState.RenderTarget[0].RenderTargetWriteMask = + D3D12_COLOR_WRITE_ENABLE_ALL; + uint32_rtv_clear_pipeline_desc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; + uint32_rtv_clear_pipeline_desc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; + uint32_rtv_clear_pipeline_desc.RasterizerState.DepthClipEnable = TRUE; + uint32_rtv_clear_pipeline_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + uint32_rtv_clear_pipeline_desc.NumRenderTargets = 1; + for (size_t i = 0; i < 2; ++i) { + uint32_rtv_clear_pipeline_desc.RTVFormats[0] = + GetColorOwnershipTransferDXGIFormat(i ? xenos::ColorRenderTargetFormat::k_32_32_FLOAT + : xenos::ColorRenderTargetFormat::k_32_FLOAT); + for (size_t j = size_t(xenos::MsaaSamples::k1X); j <= size_t(xenos::MsaaSamples::k4X); ++j) { + if (xenos::MsaaSamples(j) == xenos::MsaaSamples::k2X && !msaa_2x_supported_) { + // Using sample 0 as 0 and 3 as 1 for 2x instead. + uint32_rtv_clear_pipeline_desc.SampleMask = 0b1001; + uint32_rtv_clear_pipeline_desc.SampleDesc.Count = 4; + } else { + uint32_rtv_clear_pipeline_desc.SampleMask = UINT_MAX; + uint32_rtv_clear_pipeline_desc.SampleDesc.Count = 1 << j; + } + ID3D12PipelineState* uint32_rtv_clear_pipeline; + if (FAILED(device->CreateGraphicsPipelineState(&uint32_rtv_clear_pipeline_desc, + IID_PPV_ARGS(&uint32_rtv_clear_pipeline)))) { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to create the {} {}-sample " + "render target clearing pipeline", + i ? "k_32_32_FLOAT" : "k_32_FLOAT", uint32_t(1) << j); + Shutdown(); + return false; + } + uint32_rtv_clear_pipelines_[i][j] = uint32_rtv_clear_pipeline; + auto uint32_rtv_clear_pipeline_name = rex::string::to_utf16(fmt::format( + "Resolve Clear {} {}xMSAA", i ? "k_32_32_FLOAT" : "k_32_FLOAT", uint32_t(1) << j)); + uint32_rtv_clear_pipeline->SetName( + reinterpret_cast(uint32_rtv_clear_pipeline_name.c_str())); + } + } + + // FXC-compiled depth / stencil dumping shader is ~2 KB, reserve 4 KB for + // some additional space. + built_shader_.reserve(1024); + } else if (path_ == Path::kPixelShaderInterlock) { + // Pixel shader interlock (rasterizer-ordered view). + + // Blending is done in linear space directly in shaders. + gamma_render_target_as_unorm16_ = false; + + // Always true float24 depth rounded to the nearest even. + depth_float24_round_ = true; + depth_float24_convert_in_pixel_shader_ = true; + + // Only ForcedSampleCount, which doesn't support 2x. + msaa_2x_supported_ = false; + + // Create the resolve EDRAM buffer clearing root signature. + std::array resolve_rov_clear_root_parameters; + // Parameter 0 is constants. + resolve_rov_clear_root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + resolve_rov_clear_root_parameters[0].Constants.ShaderRegister = 0; + resolve_rov_clear_root_parameters[0].Constants.RegisterSpace = 0; + // Binding all of the shared memory at 1x resolution, portions with scaled + // resolution. + resolve_rov_clear_root_parameters[0].Constants.Num32BitValues = + sizeof(draw_util::ResolveClearShaderConstants) / sizeof(uint32_t); + resolve_rov_clear_root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + // Parameter 1 is the destination (EDRAM). + D3D12_DESCRIPTOR_RANGE resolve_rov_clear_dest_range; + resolve_rov_clear_dest_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + resolve_rov_clear_dest_range.NumDescriptors = 1; + resolve_rov_clear_dest_range.BaseShaderRegister = 0; + resolve_rov_clear_dest_range.RegisterSpace = 0; + resolve_rov_clear_dest_range.OffsetInDescriptorsFromTableStart = 0; + resolve_rov_clear_root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + resolve_rov_clear_root_parameters[1].DescriptorTable.NumDescriptorRanges = 1; + resolve_rov_clear_root_parameters[1].DescriptorTable.pDescriptorRanges = + &resolve_rov_clear_dest_range; + resolve_rov_clear_root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + D3D12_ROOT_SIGNATURE_DESC resolve_rov_clear_root_signature_desc; + resolve_rov_clear_root_signature_desc.NumParameters = + UINT(resolve_rov_clear_root_parameters.size()); + resolve_rov_clear_root_signature_desc.pParameters = resolve_rov_clear_root_parameters.data(); + resolve_rov_clear_root_signature_desc.NumStaticSamplers = 0; + resolve_rov_clear_root_signature_desc.pStaticSamplers = nullptr; + resolve_rov_clear_root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; + resolve_rov_clear_root_signature_ = + ui::d3d12::util::CreateRootSignature(provider, resolve_rov_clear_root_signature_desc); + if (resolve_rov_clear_root_signature_ == nullptr) { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to create the resolve EDRAM buffer " + "clear root signature"); + Shutdown(); + return false; + } + + // Create the resolve EDRAM buffer clearing pipelines. + resolve_rov_clear_32bpp_pipeline_ = ui::d3d12::util::CreateComputePipeline( + device, + draw_resolution_scaled ? shaders::resolve_clear_32bpp_scaled_cs + : shaders::resolve_clear_32bpp_cs, + draw_resolution_scaled ? sizeof(shaders::resolve_clear_32bpp_scaled_cs) + : sizeof(shaders::resolve_clear_32bpp_cs), + resolve_rov_clear_root_signature_); + if (resolve_rov_clear_32bpp_pipeline_ == nullptr) { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to create the 32bpp resolve EDRAM " + "buffer clear pipeline"); + Shutdown(); + return false; + } + resolve_rov_clear_32bpp_pipeline_->SetName(L"Resolve Clear 32bpp"); + resolve_rov_clear_64bpp_pipeline_ = ui::d3d12::util::CreateComputePipeline( + device, + draw_resolution_scaled ? shaders::resolve_clear_64bpp_scaled_cs + : shaders::resolve_clear_64bpp_cs, + draw_resolution_scaled ? sizeof(shaders::resolve_clear_64bpp_scaled_cs) + : sizeof(shaders::resolve_clear_64bpp_cs), + resolve_rov_clear_root_signature_); + if (resolve_rov_clear_64bpp_pipeline_ == nullptr) { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to create the 64bpp resolve EDRAM " + "buffer clear pipeline"); + Shutdown(); + return false; + } + resolve_rov_clear_64bpp_pipeline_->SetName(L"Resolve Clear 64bpp"); + } else { + assert_unhandled_case(path_); + Shutdown(); + return false; + } + + InitializeCommon(); + + return true; +} + +void D3D12RenderTargetCache::Shutdown(bool from_destructor) { + ui::d3d12::util::ReleaseAndNull(resolve_rov_clear_64bpp_pipeline_); + ui::d3d12::util::ReleaseAndNull(resolve_rov_clear_32bpp_pipeline_); + ui::d3d12::util::ReleaseAndNull(resolve_rov_clear_root_signature_); + + for (size_t i = 0; i < 2; ++i) { + for (size_t j = size_t(xenos::MsaaSamples::k1X); j <= size_t(xenos::MsaaSamples::k4X); ++j) { + ui::d3d12::util::ReleaseAndNull(uint32_rtv_clear_pipelines_[i][j]); + } + } + ui::d3d12::util::ReleaseAndNull(uint32_rtv_clear_root_signature_); + + for (const auto& dump_pipeline_pair : dump_pipelines_) { + if (dump_pipeline_pair.second) { + dump_pipeline_pair.second->Release(); + } + } + dump_pipelines_.clear(); + for (const auto& direct_resolve_pipeline_pair : direct_resolve_pipelines_) { + bool aliased_resolve_copy_pipeline = false; + for (ID3D12PipelineState* resolve_copy_pipeline : resolve_copy_pipelines_) { + if (direct_resolve_pipeline_pair.second == resolve_copy_pipeline) { + aliased_resolve_copy_pipeline = true; + break; + } + } + if (direct_resolve_pipeline_pair.second && !aliased_resolve_copy_pipeline) { + direct_resolve_pipeline_pair.second->Release(); + } + } + direct_resolve_pipelines_.clear(); + ui::d3d12::util::ReleaseAndNull(direct_resolve_root_signature_depth_); + ui::d3d12::util::ReleaseAndNull(direct_resolve_root_signature_color_); + ui::d3d12::util::ReleaseAndNull(dump_root_signature_depth_); + ui::d3d12::util::ReleaseAndNull(dump_root_signature_color_); + + for (const auto& transfer_pipeline_array_pair : transfer_stencil_bit_pipelines_) { + for (ID3D12PipelineState* transfer_pipeline : transfer_pipeline_array_pair.second) { + if (transfer_pipeline) { + transfer_pipeline->Release(); + } + } + } + transfer_stencil_bit_pipelines_.clear(); + for (const auto& transfer_pipeline_pair : transfer_pipelines_) { + if (transfer_pipeline_pair.second) { + transfer_pipeline_pair.second->Release(); + } + } + transfer_pipelines_.clear(); + for (size_t i = 0; i < rex::countof(transfer_root_signatures_); ++i) { + ui::d3d12::util::ReleaseAndNull(transfer_root_signatures_[i]); + } + + transfer_vertex_buffer_pool_.reset(); + + for (size_t i = 0; i < rex::countof(host_depth_store_pipelines_); ++i) { + ui::d3d12::util::ReleaseAndNull(host_depth_store_pipelines_[i]); + } + ui::d3d12::util::ReleaseAndNull(host_depth_store_root_signature_); + + null_rtv_descriptor_ms_.Free(); + null_rtv_descriptor_ss_.Free(); + descriptor_pool_srv_.reset(); + descriptor_pool_depth_.reset(); + descriptor_pool_color_.reset(); + + for (size_t i = 0; i < rex::countof(resolve_copy_pipelines_); ++i) { + ui::d3d12::util::ReleaseAndNull(resolve_copy_pipelines_[i]); + } + ui::d3d12::util::ReleaseAndNull(resolve_copy_root_signature_); + + edram_snapshot_restore_pool_.reset(); + ui::d3d12::util::ReleaseAndNull(edram_snapshot_download_buffer_); + + ui::d3d12::util::ReleaseAndNull(edram_buffer_descriptor_heap_); + ui::d3d12::util::ReleaseAndNull(edram_buffer_); + + if (!from_destructor) { + ShutdownCommon(); + } +} + +void D3D12RenderTargetCache::CompletedSubmissionUpdated() { + if (edram_snapshot_restore_pool_) { + edram_snapshot_restore_pool_->Reclaim(command_processor_.GetCompletedSubmission()); + } + if (transfer_vertex_buffer_pool_) { + transfer_vertex_buffer_pool_->Reclaim(command_processor_.GetCompletedSubmission()); + } +} + +void D3D12RenderTargetCache::BeginSubmission() { + // New command list - render targets not bound. + InvalidateCommandListRenderTargets(); + // ExecuteCommandLists is a full UAV barrier. + if (edram_buffer_modification_status_ != EdramBufferModificationStatus::kUnmodified) { + assert_true(edram_buffer_state_ == D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + edram_buffer_modification_status_ = EdramBufferModificationStatus::kUnmodified; + PixelShaderInterlockFullEdramBarrierPlaced(); + } +} + +bool D3D12RenderTargetCache::Update(bool is_rasterization_done, + reg::RB_DEPTHCONTROL normalized_depth_control, + uint32_t normalized_color_mask, const Shader& vertex_shader) { + if (!RenderTargetCache::Update(is_rasterization_done, normalized_depth_control, + normalized_color_mask, vertex_shader)) { + return false; + } + switch (GetPath()) { + case Path::kHostRenderTargets: { + RenderTarget* const* depth_and_color_render_targets = + last_update_accumulated_render_targets(); + PerformTransfersAndResolveClears(1 + xenos::kMaxColorRenderTargets, + depth_and_color_render_targets, last_update_transfers()); + SetCommandListRenderTargets(depth_and_color_render_targets); + } break; + case Path::kPixelShaderInterlock: { + // For ROV, only the barrier is needed - already scheduled if required. + // But the buffer will be used for ROV drawing now. + TransitionEdramBuffer(D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + // Commit preceding UAV (but not ROV) writes like clears as they aren't + // synchronized with ROV accesses. + CommitEdramBufferUAVWrites(EdramBufferModificationStatus::kAsUAV); + // TODO(Triang3l): Check if this draw call modifies color or depth / + // stencil, at least coarsely, to prevent useless barriers. + MarkEdramBufferModified(EdramBufferModificationStatus::kAsROV); + } break; + default: + assert_unhandled_case(GetPath()); + return false; + } + return true; +} + +void D3D12RenderTargetCache::WriteEdramRawSRVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle) { + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + device->CopyDescriptorsSimple( + 1, handle, + provider.OffsetViewDescriptor(edram_buffer_descriptor_heap_start_, + uint32_t(EdramBufferDescriptorIndex::kRawSRV)), + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); +} + +void D3D12RenderTargetCache::WriteEdramRawUAVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle) { + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + device->CopyDescriptorsSimple( + 1, handle, + provider.OffsetViewDescriptor(edram_buffer_descriptor_heap_start_, + uint32_t(EdramBufferDescriptorIndex::kRawUAV)), + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); +} + +void D3D12RenderTargetCache::WriteEdramUintPow2SRVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle, + uint32_t element_size_bytes_pow2) { + EdramBufferDescriptorIndex descriptor_index; + switch (element_size_bytes_pow2) { + case 2: + descriptor_index = EdramBufferDescriptorIndex::kR32UintSRV; + break; + case 3: + descriptor_index = EdramBufferDescriptorIndex::kR32G32UintSRV; + break; + case 4: + descriptor_index = EdramBufferDescriptorIndex::kR32G32B32A32UintSRV; + break; + default: + assert_unhandled_case(element_size_bytes_pow2); + return; + } + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + device->CopyDescriptorsSimple(1, handle, + provider.OffsetViewDescriptor(edram_buffer_descriptor_heap_start_, + uint32_t(descriptor_index)), + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); +} + +void D3D12RenderTargetCache::WriteEdramUintPow2UAVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle, + uint32_t element_size_bytes_pow2) { + EdramBufferDescriptorIndex descriptor_index; + switch (element_size_bytes_pow2) { + case 2: + descriptor_index = EdramBufferDescriptorIndex::kR32UintUAV; + break; + case 3: + descriptor_index = EdramBufferDescriptorIndex::kR32G32UintUAV; + break; + case 4: + descriptor_index = EdramBufferDescriptorIndex::kR32G32B32A32UintUAV; + break; + default: + assert_unhandled_case(element_size_bytes_pow2); + return; + } + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + device->CopyDescriptorsSimple(1, handle, + provider.OffsetViewDescriptor(edram_buffer_descriptor_heap_start_, + uint32_t(descriptor_index)), + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); +} + +bool D3D12RenderTargetCache::Resolve(const memory::Memory& memory, D3D12SharedMemory& shared_memory, + D3D12TextureCache& texture_cache, + uint32_t& written_address_out, uint32_t& written_length_out) { + written_address_out = 0; + written_length_out = 0; + + bool draw_resolution_scaled = IsDrawResolutionScaled(); + + draw_util::ResolveInfo resolve_info; + bool fixed_16_truncated_to_minus_1_to_1 = IsFixed16TruncatedToMinus1To1(); + if (!draw_util::GetResolveInfo(register_file(), memory, trace_writer_, draw_resolution_scale_x(), + draw_resolution_scale_y(), fixed_16_truncated_to_minus_1_to_1, + fixed_16_truncated_to_minus_1_to_1, resolve_info)) { + return false; + } + + // Nothing to copy/clear. + if (!resolve_info.coordinate_info.width_div_8 || !resolve_info.height_div_8) { + return true; + } + + DeferredCommandList& command_list = command_processor_.GetDeferredCommandList(); + + // Copying. + bool copied = false; + if (resolve_info.copy_dest_extent_length) { + draw_util::ResolveCopyShaderConstants copy_shader_constants; + uint32_t copy_group_count_x, copy_group_count_y; + draw_util::ResolveCopyShaderIndex copy_shader = + resolve_info.GetCopyShader(draw_resolution_scale_x(), draw_resolution_scale_y(), + copy_shader_constants, copy_group_count_x, copy_group_count_y); + assert_true(copy_group_count_x && copy_group_count_y); + if (copy_shader != draw_util::ResolveCopyShaderIndex::kUnknown) { + const draw_util::ResolveCopyShaderInfo& copy_shader_info = + draw_util::resolve_copy_shader_info[size_t(copy_shader)]; + bool direct_resolved = false; + if (GetPath() == Path::kHostRenderTargets) { + if (REXCVAR_GET(direct_host_resolve)) { + direct_resolved = + TryResolveCopyDirectly(resolve_info, copy_shader, draw_resolution_scaled); + if (direct_resolved) { + ++direct_resolve_success_count_; + } else { + ++direct_resolve_fallback_count_; + } + } + if (!direct_resolved) { + // Dump the current contents of the render targets owning the affected + // range to edram_buffer_. + uint32_t dump_base; + uint32_t dump_row_length_used; + uint32_t dump_rows; + uint32_t dump_pitch; + resolve_info.GetCopyEdramTileSpan(dump_base, dump_row_length_used, dump_rows, dump_pitch); + if (!DumpRenderTargets(dump_base, dump_row_length_used, dump_rows, dump_pitch)) { + REXGPU_ERROR("D3D12RenderTargetCache: Failed to dump host render targets for resolve"); + return false; + } + } + } + + // Make sure there is memory to write to. + bool copy_dest_committed; + if (draw_resolution_scaled) { + // Committing starting with the beginning of the potentially written + // extent, but making the buffer containing the base current as the + // beginning of the bound buffer is the base. + copy_dest_committed = + texture_cache.EnsureScaledResolveMemoryCommitted( + resolve_info.copy_dest_extent_start, resolve_info.copy_dest_extent_length) && + texture_cache.MakeScaledResolveRangeCurrent(resolve_info.copy_dest_base, + resolve_info.copy_dest_extent_start - + resolve_info.copy_dest_base + + resolve_info.copy_dest_extent_length); + } else { + copy_dest_committed = shared_memory.RequestRange(resolve_info.copy_dest_extent_start, + resolve_info.copy_dest_extent_length); + } + if (copy_dest_committed) { + // Write the descriptors and transition the resources. + // Full shared memory without resolution scaling, range of the scaled + // resolve buffer with scaling because only at least 128 * 2^20 R32 + // elements must be addressable + // (D3D12_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP). + ui::d3d12::util::DescriptorCpuGpuHandlePair descriptor_dest; + ui::d3d12::util::DescriptorCpuGpuHandlePair descriptor_source; + ui::d3d12::util::DescriptorCpuGpuHandlePair descriptors[2]; + if (command_processor_.RequestOneUseSingleViewDescriptors( + bindless_resources_used_ ? uint32_t(draw_resolution_scaled) : 2, descriptors)) { + if (bindless_resources_used_) { + if (draw_resolution_scaled) { + descriptor_dest = descriptors[0]; + } else { + descriptor_dest = command_processor_.GetSharedMemoryUintPow2BindlessUAVHandlePair( + copy_shader_info.dest_bpe_log2); + } + if (copy_shader_info.source_is_raw) { + descriptor_source = command_processor_.GetSystemBindlessViewHandlePair( + D3D12CommandProcessor::SystemBindlessView::kEdramRawSRV); + } else { + descriptor_source = command_processor_.GetEdramUintPow2BindlessSRVHandlePair( + copy_shader_info.source_bpe_log2); + } + } else { + descriptor_dest = descriptors[0]; + if (!draw_resolution_scaled) { + shared_memory.WriteUintPow2UAVDescriptor(descriptor_dest.first, + copy_shader_info.dest_bpe_log2); + } + descriptor_source = descriptors[1]; + if (copy_shader_info.source_is_raw) { + WriteEdramRawSRVDescriptor(descriptor_source.first); + } else { + WriteEdramUintPow2SRVDescriptor(descriptor_source.first, + copy_shader_info.source_bpe_log2); + } + } + if (draw_resolution_scaled) { + texture_cache.CreateCurrentScaledResolveRangeUintPow2UAV( + descriptor_dest.first, copy_shader_info.dest_bpe_log2); + texture_cache.TransitionCurrentScaledResolveRange( + D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + } else { + shared_memory.UseForWriting(); + } + TransitionEdramBuffer(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + + // Submit the resolve. + command_list.D3DSetComputeRootSignature(resolve_copy_root_signature_); + command_list.D3DSetComputeRootDescriptorTable(2, descriptor_source.second); + command_list.D3DSetComputeRootDescriptorTable(1, descriptor_dest.second); + if (draw_resolution_scaled) { + command_list.D3DSetComputeRoot32BitConstants( + 0, sizeof(copy_shader_constants.dest_relative) / sizeof(uint32_t), + ©_shader_constants.dest_relative, 0); + } else { + command_list.D3DSetComputeRoot32BitConstants( + 0, sizeof(copy_shader_constants) / sizeof(uint32_t), ©_shader_constants, 0); + } + command_processor_.SetExternalPipeline(resolve_copy_pipelines_[size_t(copy_shader)]); + command_processor_.SubmitBarriers(); + command_list.D3DDispatch(copy_group_count_x, copy_group_count_y, 1); + + // Order the resolve with other work using the destination as a UAV. + if (draw_resolution_scaled) { + texture_cache.MarkCurrentScaledResolveRangeUAVWritesCommitNeeded(); + } else { + shared_memory.MarkUAVWritesCommitNeeded(); + } + + // Invalidate textures and mark the range as scaled if needed. + texture_cache.MarkRangeAsResolved(resolve_info.copy_dest_extent_start, + resolve_info.copy_dest_extent_length); + written_address_out = resolve_info.copy_dest_extent_start; + written_length_out = resolve_info.copy_dest_extent_length; + copied = true; + } + } else { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to obtain the resolve destination " + "memory region"); + } + } + } else { + copied = true; + } + + // Clearing. + bool cleared = false; + bool clear_depth = resolve_info.IsClearingDepth(); + bool clear_color = resolve_info.IsClearingColor(); + if (clear_depth || clear_color) { + switch (GetPath()) { + case Path::kHostRenderTargets: { + Transfer::Rectangle clear_rectangle; + RenderTarget* clear_render_targets[2]; + // If PrepareHostRenderTargetsResolveClear returns false, may be just an + // empty region (success) or an error - don't care. + if (PrepareHostRenderTargetsResolveClear(resolve_info, clear_rectangle, + clear_render_targets[0], clear_transfers_[0], + clear_render_targets[1], clear_transfers_[1])) { + uint64_t clear_values[2]; + clear_values[0] = resolve_info.rb_depth_clear; + clear_values[1] = + resolve_info.rb_color_clear | (uint64_t(resolve_info.rb_color_clear_lo) << 32); + PerformTransfersAndResolveClears(2, clear_render_targets, clear_transfers_, clear_values, + &clear_rectangle); + } + cleared = true; + } break; + case Path::kPixelShaderInterlock: { + ui::d3d12::util::DescriptorCpuGpuHandlePair descriptor_edram; + bool descriptor_edram_obtained; + if (bindless_resources_used_) { + descriptor_edram = command_processor_.GetSystemBindlessViewHandlePair( + D3D12CommandProcessor::SystemBindlessView ::kEdramR32G32B32A32UintUAV); + descriptor_edram_obtained = true; + } else { + descriptor_edram_obtained = + command_processor_.RequestOneUseSingleViewDescriptors(1, &descriptor_edram); + if (descriptor_edram_obtained) { + WriteEdramUintPow2UAVDescriptor(descriptor_edram.first, 4); + } + } + if (descriptor_edram_obtained) { + TransitionEdramBuffer(D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + // Should be safe to only commit once (if was UAV / ROV previously - + // if there was nothing to copy, only to clear, for some reason, for + // instance), overlap of the depth and the color ranges is highly + // unlikely. + CommitEdramBufferUAVWrites(); + command_list.D3DSetComputeRootSignature(resolve_rov_clear_root_signature_); + command_list.D3DSetComputeRootDescriptorTable(1, descriptor_edram.second); + std::pair clear_group_count = resolve_info.GetClearShaderGroupCount( + draw_resolution_scale_x(), draw_resolution_scale_y()); + assert_true(clear_group_count.first && clear_group_count.second); + if (clear_depth) { + draw_util::ResolveClearShaderConstants depth_clear_constants; + resolve_info.GetDepthClearShaderConstants(depth_clear_constants); + command_list.D3DSetComputeRoot32BitConstants( + 0, sizeof(depth_clear_constants) / sizeof(uint32_t), &depth_clear_constants, 0); + command_processor_.SetExternalPipeline(resolve_rov_clear_32bpp_pipeline_); + command_processor_.SubmitBarriers(); + command_list.D3DDispatch(clear_group_count.first, clear_group_count.second, 1); + } + if (clear_color) { + draw_util::ResolveClearShaderConstants color_clear_constants; + resolve_info.GetColorClearShaderConstants(color_clear_constants); + if (clear_depth) { + // Non-RT-specific constants have already been set. + command_list.D3DSetComputeRoot32BitConstants( + 0, sizeof(color_clear_constants.rt_specific) / sizeof(uint32_t), + &color_clear_constants.rt_specific, + offsetof(draw_util::ResolveClearShaderConstants, rt_specific) / sizeof(uint32_t)); + } else { + command_list.D3DSetComputeRoot32BitConstants( + 0, sizeof(color_clear_constants) / sizeof(uint32_t), &color_clear_constants, 0); + } + command_processor_.SetExternalPipeline(resolve_info.color_edram_info.format_is_64bpp + ? resolve_rov_clear_64bpp_pipeline_ + : resolve_rov_clear_32bpp_pipeline_); + command_processor_.SubmitBarriers(); + command_list.D3DDispatch(clear_group_count.first, clear_group_count.second, 1); + } + MarkEdramBufferModified(); + cleared = true; + } + } break; + default: + assert_unhandled_case(GetPath()); + } + } else { + cleared = true; + } + + return copied && cleared; +} + +bool D3D12RenderTargetCache::InitializeTraceSubmitDownloads() { + if (IsDrawResolutionScaled()) { + // No 1:1 mapping. + return false; + } + if (!edram_snapshot_download_buffer_) { + D3D12_RESOURCE_DESC edram_snapshot_download_buffer_desc; + ui::d3d12::util::FillBufferResourceDesc(edram_snapshot_download_buffer_desc, + xenos::kEdramSizeBytes, D3D12_RESOURCE_FLAG_NONE); + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + if (FAILED(device->CreateCommittedResource( + &ui::d3d12::util::kHeapPropertiesReadback, provider.GetHeapFlagCreateNotZeroed(), + &edram_snapshot_download_buffer_desc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, + IID_PPV_ARGS(&edram_snapshot_download_buffer_)))) { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to create a EDRAM snapshot download " + "buffer"); + return false; + } + } + if (GetPath() == Path::kHostRenderTargets) { + // Dump all host render targets to edram_buffer_. + if (!DumpRenderTargets(0, xenos::kEdramTileCount, 1, xenos::kEdramTileCount)) { + REXGPU_ERROR("D3D12RenderTargetCache: Failed to dump host render targets for trace"); + return false; + } + } + TransitionEdramBuffer(D3D12_RESOURCE_STATE_COPY_SOURCE); + command_processor_.SubmitBarriers(); + command_processor_.GetDeferredCommandList().D3DCopyBufferRegion( + edram_snapshot_download_buffer_, 0, edram_buffer_, 0, xenos::kEdramSizeBytes); + return true; +} + +void D3D12RenderTargetCache::InitializeTraceCompleteDownloads() { + if (!edram_snapshot_download_buffer_) { + return; + } + void* download_mapping; + if (SUCCEEDED(edram_snapshot_download_buffer_->Map(0, nullptr, &download_mapping))) { + trace_writer_.WriteEdramSnapshot(download_mapping); + D3D12_RANGE download_write_range = {}; + edram_snapshot_download_buffer_->Unmap(0, &download_write_range); + } else { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to map the EDRAM snapshot download " + "buffer"); + } + edram_snapshot_download_buffer_->Release(); + edram_snapshot_download_buffer_ = nullptr; +} + +void D3D12RenderTargetCache::RestoreEdramSnapshot(const void* snapshot) { + if (IsDrawResolutionScaled()) { + // No 1:1 mapping. + return; + } + + // Create the buffer - will be used for copying to either a 32-bit 1280x2048 + // render target or the EDRAM buffer. + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + if (!edram_snapshot_restore_pool_) { + edram_snapshot_restore_pool_ = + std::make_unique(provider, xenos::kEdramSizeBytes); + } + ID3D12Resource* upload_buffer; + size_t upload_buffer_offset; + void* upload_buffer_mapping = edram_snapshot_restore_pool_->Request( + command_processor_.GetCurrentSubmission(), xenos::kEdramSizeBytes, 1, &upload_buffer, + &upload_buffer_offset, nullptr); + if (!upload_buffer_mapping) { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to get a buffer for restoring a EDRAM " + "snapshot"); + return; + } + + DeferredCommandList& command_list = command_processor_.GetDeferredCommandList(); + + switch (GetPath()) { + case Path::kHostRenderTargets: { + // k_32_FLOAT because it's unambiguous (not effected by something like + // DXGI_FORMAT_R8G8B8A8 vs. DXGI_FORMAT_B8G8R8A8). + D3D12RenderTarget* full_edram_render_target = + static_cast(PrepareFullEdram1280xRenderTargetForSnapshotRestoration( + xenos::ColorRenderTargetFormat::k_32_FLOAT)); + if (!full_edram_render_target) { + return; + } + D3D12_TEXTURE_COPY_LOCATION copy_source_location; + copy_source_location.pResource = upload_buffer; + copy_source_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + UINT64 copy_total_bytes; + D3D12_RESOURCE_DESC full_edram_render_target_desc = + full_edram_render_target->resource()->GetDesc(); + provider.GetDevice()->GetCopyableFootprints(&full_edram_render_target_desc, 0, 1, 0, + ©_source_location.PlacedFootprint, nullptr, + nullptr, ©_total_bytes); + // 1280 width * sizeof(uint32_t) is aligned to + // D3D12_TEXTURE_DATA_PITCH_ALIGNMENT (256). + assert_true(copy_total_bytes <= xenos::kEdramSizeBytes); + assert_false(full_edram_render_target->key().Is64bpp()); + uint32_t pitch_tiles = full_edram_render_target->key().pitch_tiles_at_32bpp; + uint32_t tile_rows = xenos::kEdramTileCount / pitch_tiles; + assert_true(pitch_tiles * tile_rows == xenos::kEdramTileCount); + const uint8_t* snapshot_sample_row = reinterpret_cast(snapshot); + for (uint32_t y_tile = 0; y_tile < tile_rows; ++y_tile) { + uint8_t* upload_buffer_tile_row_origin = + reinterpret_cast(upload_buffer_mapping) + + copy_source_location.PlacedFootprint.Offset + + xenos::kEdramTileHeightSamples * y_tile * + copy_source_location.PlacedFootprint.Footprint.RowPitch; + for (uint32_t x_tile = 0; x_tile < pitch_tiles; ++x_tile) { + uint8_t* upload_buffer_sample_row = + upload_buffer_tile_row_origin + + sizeof(uint32_t) * xenos::kEdramTileWidthSamples * x_tile; + for (uint32_t sample_row = 0; sample_row < xenos::kEdramTileHeightSamples; ++sample_row) { + std::memcpy(upload_buffer_sample_row, snapshot_sample_row, + sizeof(uint32_t) * xenos::kEdramTileWidthSamples); + snapshot_sample_row += sizeof(uint32_t) * xenos::kEdramTileWidthSamples; + upload_buffer_sample_row += copy_source_location.PlacedFootprint.Footprint.RowPitch; + } + } + } + command_processor_.PushTransitionBarrier( + full_edram_render_target->resource(), + full_edram_render_target->SetResourceState(D3D12_RESOURCE_STATE_COPY_DEST), + D3D12_RESOURCE_STATE_COPY_DEST); + command_processor_.SubmitBarriers(); + D3D12_TEXTURE_COPY_LOCATION copy_dest_location; + copy_dest_location.pResource = full_edram_render_target->resource(); + copy_dest_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + copy_dest_location.SubresourceIndex = 0; + command_list.D3DCopyTextureRegion(©_dest_location, 0, 0, 0, ©_source_location, + nullptr); + } break; + + case Path::kPixelShaderInterlock: { + std::memcpy(upload_buffer_mapping, snapshot, xenos::kEdramSizeBytes); + TransitionEdramBuffer(D3D12_RESOURCE_STATE_COPY_DEST); + command_processor_.SubmitBarriers(); + command_list.D3DCopyBufferRegion(edram_buffer_, 0, upload_buffer, + UINT64(upload_buffer_offset), xenos::kEdramSizeBytes); + } break; + + default: + assert_unhandled_case(GetPath()); + } +} + +DXGI_FORMAT D3D12RenderTargetCache::GetColorResourceDXGIFormat( + xenos::ColorRenderTargetFormat format) const { + // Typed should be preferred over typeless so there are more opportunities for + // compression. + switch (format) { + case xenos::ColorRenderTargetFormat::k_8_8_8_8: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA: + return gamma_render_target_as_unorm16_ ? DXGI_FORMAT_R16G16B16A16_UNORM + : DXGI_FORMAT_R8G8B8A8_UNORM; + case xenos::ColorRenderTargetFormat::k_2_10_10_10: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: + return DXGI_FORMAT_R10G10B10A2_UNORM; + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16: + return DXGI_FORMAT_R16G16B16A16_FLOAT; + // SNORM has two representations of -1. + case xenos::ColorRenderTargetFormat::k_16_16: + return DXGI_FORMAT_R16G16_TYPELESS; + case xenos::ColorRenderTargetFormat::k_16_16_16_16: + return DXGI_FORMAT_R16G16B16A16_TYPELESS; + // Floating-point - ensure NaN propagation during ownership transfer for + // unmodified data. + case xenos::ColorRenderTargetFormat::k_16_16_FLOAT: + return DXGI_FORMAT_R16G16_TYPELESS; + case xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT: + return DXGI_FORMAT_R16G16B16A16_TYPELESS; + // TODO(Triang3l): Check if NaN propagation defined in the D3D11.3 + // specification can be relied on for 32-bit float render targets. + case xenos::ColorRenderTargetFormat::k_32_FLOAT: + return DXGI_FORMAT_R32_TYPELESS; + case xenos::ColorRenderTargetFormat::k_32_32_FLOAT: + return DXGI_FORMAT_R32G32_TYPELESS; + default: + assert_unhandled_case(format); + return DXGI_FORMAT_UNKNOWN; + } +} + +DXGI_FORMAT D3D12RenderTargetCache::GetColorDrawDXGIFormat( + xenos::ColorRenderTargetFormat format) const { + switch (format) { + case xenos::ColorRenderTargetFormat::k_16_16: + return DXGI_FORMAT_R16G16_SNORM; + case xenos::ColorRenderTargetFormat::k_16_16_16_16: + return DXGI_FORMAT_R16G16B16A16_SNORM; + case xenos::ColorRenderTargetFormat::k_16_16_FLOAT: + return DXGI_FORMAT_R16G16_FLOAT; + case xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT: + return DXGI_FORMAT_R16G16B16A16_FLOAT; + case xenos::ColorRenderTargetFormat::k_32_FLOAT: + return DXGI_FORMAT_R32_FLOAT; + case xenos::ColorRenderTargetFormat::k_32_32_FLOAT: + return DXGI_FORMAT_R32G32_FLOAT; + default: + return GetColorResourceDXGIFormat(format); + } +} + +DXGI_FORMAT D3D12RenderTargetCache::GetColorOwnershipTransferDXGIFormat( + xenos::ColorRenderTargetFormat format, bool* is_integer_out) const { + if (is_integer_out) { + *is_integer_out = true; + } + switch (format) { + case xenos::ColorRenderTargetFormat::k_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_FLOAT: + return DXGI_FORMAT_R16G16_UINT; + case xenos::ColorRenderTargetFormat::k_16_16_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT: + return DXGI_FORMAT_R16G16B16A16_UINT; + case xenos::ColorRenderTargetFormat::k_32_FLOAT: + return DXGI_FORMAT_R32_UINT; + case xenos::ColorRenderTargetFormat::k_32_32_FLOAT: + return DXGI_FORMAT_R32G32_UINT; + default: + if (is_integer_out) { + *is_integer_out = false; + } + return GetColorDrawDXGIFormat(format); + } +} + +DXGI_FORMAT D3D12RenderTargetCache::GetDepthResourceDXGIFormat( + xenos::DepthRenderTargetFormat format) { + switch (format) { + case xenos::DepthRenderTargetFormat::kD24S8: + return DXGI_FORMAT_R24G8_TYPELESS; + case xenos::DepthRenderTargetFormat::kD24FS8: + return DXGI_FORMAT_R32G8X24_TYPELESS; + default: + assert_unhandled_case(format); + return DXGI_FORMAT_UNKNOWN; + } +} + +DXGI_FORMAT D3D12RenderTargetCache::GetDepthDSVDXGIFormat(xenos::DepthRenderTargetFormat format) { + switch (format) { + case xenos::DepthRenderTargetFormat::kD24S8: + return DXGI_FORMAT_D24_UNORM_S8_UINT; + case xenos::DepthRenderTargetFormat::kD24FS8: + return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + default: + assert_unhandled_case(format); + return DXGI_FORMAT_UNKNOWN; + } +} + +DXGI_FORMAT D3D12RenderTargetCache::GetDepthSRVDepthDXGIFormat( + xenos::DepthRenderTargetFormat format) { + switch (format) { + case xenos::DepthRenderTargetFormat::kD24S8: + return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + case xenos::DepthRenderTargetFormat::kD24FS8: + return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; + default: + assert_unhandled_case(format); + return DXGI_FORMAT_UNKNOWN; + } +} + +DXGI_FORMAT D3D12RenderTargetCache::GetDepthSRVStencilDXGIFormat( + xenos::DepthRenderTargetFormat format) { + switch (format) { + case xenos::DepthRenderTargetFormat::kD24S8: + return DXGI_FORMAT_X24_TYPELESS_G8_UINT; + case xenos::DepthRenderTargetFormat::kD24FS8: + return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; + default: + assert_unhandled_case(format); + return DXGI_FORMAT_UNKNOWN; + } +} + +RenderTargetCache::RenderTarget* D3D12RenderTargetCache::CreateRenderTarget(RenderTargetKey key) { + ID3D12Device* device = command_processor_.GetD3D12Provider().GetDevice(); + + D3D12_RESOURCE_DESC resource_desc; + resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + resource_desc.Alignment = 0; + resource_desc.Width = key.GetWidth() * draw_resolution_scale_x(); + resource_desc.Height = + GetRenderTargetHeight(key.pitch_tiles_at_32bpp, key.msaa_samples) * draw_resolution_scale_y(); + resource_desc.DepthOrArraySize = 1; + resource_desc.MipLevels = 1; + if (key.is_depth) { + resource_desc.Format = GetDepthResourceDXGIFormat(key.GetDepthFormat()); + } else { + resource_desc.Format = GetColorResourceDXGIFormat(key.GetColorFormat()); + } + assert_true(resource_desc.Format != DXGI_FORMAT_UNKNOWN); + if (resource_desc.Format == DXGI_FORMAT_UNKNOWN) { + REXGPU_ERROR("D3D12RenderTargetCache: Unknown {} render target format {}", + key.is_depth ? "depth" : "color", uint32_t(key.resource_format)); + return nullptr; + } + if (key.msaa_samples == xenos::MsaaSamples::k2X && !msaa_2x_supported()) { + resource_desc.SampleDesc.Count = 4; + } else { + resource_desc.SampleDesc.Count = UINT(1) << UINT(key.msaa_samples); + } + resource_desc.SampleDesc.Quality = 0; + resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + resource_desc.Flags = key.is_depth ? D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL + : D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + // The first access will be ownership transfer into this render target or + // starting to draw directly. + D3D12_RESOURCE_STATES resource_state = + key.is_depth ? D3D12_RESOURCE_STATE_DEPTH_WRITE : D3D12_RESOURCE_STATE_RENDER_TARGET; + D3D12_CLEAR_VALUE optimized_clear_value; + if (key.is_depth) { + optimized_clear_value.Format = GetDepthDSVDXGIFormat(key.GetDepthFormat()); + // Fixed-point depth is generally direct (1 being the farthest), + // floating-point is used for more uniform precision across the range (0 + // being the farthest). + optimized_clear_value.DepthStencil.Depth = + key.GetDepthFormat() == xenos::DepthRenderTargetFormat::kD24S8 ? 1.0f : 0.0f; + optimized_clear_value.DepthStencil.Stencil = 0; + } else { + optimized_clear_value.Format = GetColorDrawDXGIFormat(key.GetColorFormat()); + optimized_clear_value.Color[0] = 0.0f; + optimized_clear_value.Color[1] = 0.0f; + optimized_clear_value.Color[2] = 0.0f; + optimized_clear_value.Color[3] = 0.0f; + } + // Create zeroed for more determinism, primarily with respect to compression + // and depth float24 / float32 mirroring. + Microsoft::WRL::ComPtr resource; + if (FAILED(device->CreateCommittedResource(&ui::d3d12::util::kHeapPropertiesDefault, + D3D12_HEAP_FLAG_NONE, &resource_desc, resource_state, + &optimized_clear_value, IID_PPV_ARGS(&resource)))) { + return nullptr; + } + { + std::u16string resource_name = rex::string::to_utf16(key.GetDebugName()); + resource->SetName(reinterpret_cast(resource_name.c_str())); + } + + ui::d3d12::D3D12CpuDescriptorPool& descriptor_pool = + key.is_depth ? *descriptor_pool_depth_ : *descriptor_pool_color_; + ui::d3d12::D3D12CpuDescriptorPool::Descriptor descriptor_draw = + descriptor_pool.AllocateDescriptor(); + ui::d3d12::D3D12CpuDescriptorPool::Descriptor descriptor_srv = + descriptor_pool_srv_->AllocateDescriptor(); + if (!descriptor_draw.IsValid() || !descriptor_srv.IsValid()) { + return nullptr; + } + D3D12_CPU_DESCRIPTOR_HANDLE descriptor_draw_handle = descriptor_draw.GetHandle(); + ui::d3d12::D3D12CpuDescriptorPool::Descriptor descriptor_load_separate; + ui::d3d12::D3D12CpuDescriptorPool::Descriptor descriptor_srv_stencil; + D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc; + srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + if (resource_desc.SampleDesc.Count > 1) { + srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DMS; + } else { + srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + srv_desc.Texture2D.MostDetailedMip = 0; + srv_desc.Texture2D.MipLevels = 1; + srv_desc.Texture2D.PlaneSlice = 0; + srv_desc.Texture2D.ResourceMinLODClamp = 0.0f; + } + if (key.is_depth) { + // DSV and stencil SRV. + descriptor_srv_stencil = descriptor_pool_srv_->AllocateDescriptor(); + if (!descriptor_srv_stencil.IsValid()) { + return nullptr; + } + D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc; + dsv_desc.Format = optimized_clear_value.Format; + dsv_desc.Flags = D3D12_DSV_FLAG_NONE; + D3D12_SHADER_RESOURCE_VIEW_DESC stencil_srv_desc; + stencil_srv_desc.Format = GetDepthSRVStencilDXGIFormat(key.GetDepthFormat()); + stencil_srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + if (resource_desc.SampleDesc.Count > 1) { + dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DMS; + stencil_srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DMS; + } else { + dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; + dsv_desc.Texture2D.MipSlice = 0; + stencil_srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + stencil_srv_desc.Texture2D.MostDetailedMip = 0; + stencil_srv_desc.Texture2D.MipLevels = 1; + stencil_srv_desc.Texture2D.PlaneSlice = 1; + stencil_srv_desc.Texture2D.ResourceMinLODClamp = 0.0f; + } + device->CreateDepthStencilView(resource.Get(), &dsv_desc, descriptor_draw_handle); + device->CreateShaderResourceView(resource.Get(), &stencil_srv_desc, + descriptor_srv_stencil.GetHandle()); + // Depth SRV. + srv_desc.Format = GetDepthSRVDepthDXGIFormat(key.GetDepthFormat()); + } else { + // Drawing RTV. + D3D12_RENDER_TARGET_VIEW_DESC rtv_desc; + rtv_desc.Format = optimized_clear_value.Format; + if (resource_desc.SampleDesc.Count > 1) { + rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMS; + } else { + rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + rtv_desc.Texture2D.MipSlice = 0; + rtv_desc.Texture2D.PlaneSlice = 0; + } + device->CreateRenderTargetView(resource.Get(), &rtv_desc, descriptor_draw_handle); + // Ownership transfer RTV. + DXGI_FORMAT load_format = GetColorOwnershipTransferDXGIFormat(key.GetColorFormat()); + if (rtv_desc.Format != load_format) { + descriptor_load_separate = descriptor_pool.AllocateDescriptor(); + if (!descriptor_load_separate.IsValid()) { + return nullptr; + } + rtv_desc.Format = load_format; + device->CreateRenderTargetView(resource.Get(), &rtv_desc, + descriptor_load_separate.GetHandle()); + } + // SRV for ownership transfer and dumping. + srv_desc.Format = load_format; + } + device->CreateShaderResourceView(resource.Get(), &srv_desc, descriptor_srv.GetHandle()); + + return new D3D12RenderTarget(key, resource.Get(), std::move(descriptor_draw), + std::move(descriptor_load_separate), std::move(descriptor_srv), + std::move(descriptor_srv_stencil), resource_state); +} + +bool D3D12RenderTargetCache::IsHostDepthEncodingDifferent( + xenos::DepthRenderTargetFormat format) const { + if (format == xenos::DepthRenderTargetFormat::kD24FS8) { + return !depth_float24_convert_in_pixel_shader_; + } + return false; +} + +bool D3D12RenderTargetCache::IsGammaFormatHostStorageSeparate() const { + return gamma_render_target_as_unorm16_; +} + +void D3D12RenderTargetCache::RequestPixelShaderInterlockBarrier() { + CommitEdramBufferUAVWrites(); +} + +void D3D12RenderTargetCache::TransitionEdramBuffer(D3D12_RESOURCE_STATES new_state) { + if (command_processor_.PushTransitionBarrier(edram_buffer_, edram_buffer_state_, new_state)) { + // Resetting edram_buffer_modification_status_ only if the barrier has been + // truly inserted - in particular, not resetting it for UAV > UAV as + // barriers are dropped if the state hasn't been changed. + edram_buffer_modification_status_ = EdramBufferModificationStatus::kUnmodified; + } + edram_buffer_state_ = new_state; +} + +void D3D12RenderTargetCache::MarkEdramBufferModified( + EdramBufferModificationStatus modification_status) { + assert_true(modification_status != EdramBufferModificationStatus::kUnmodified); + assert_true(edram_buffer_state_ == D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + if (edram_buffer_state_ != D3D12_RESOURCE_STATE_UNORDERED_ACCESS) { + return; + } + // max because being modified as a UAV requires stricter synchronization than + // as ROV. + edram_buffer_modification_status_ = + std::max(edram_buffer_modification_status_, modification_status); +} + +void D3D12RenderTargetCache::CommitEdramBufferUAVWrites( + EdramBufferModificationStatus commit_status) { + assert_true(commit_status != EdramBufferModificationStatus::kUnmodified); + if (edram_buffer_modification_status_ < commit_status) { + return; + } + assert_true(edram_buffer_state_ == D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + if (edram_buffer_state_ == D3D12_RESOURCE_STATE_UNORDERED_ACCESS) { + command_processor_.PushUAVBarrier(edram_buffer_); + } + edram_buffer_modification_status_ = EdramBufferModificationStatus::kUnmodified; + PixelShaderInterlockFullEdramBarrierPlaced(); +} + +ID3D12PipelineState* const* D3D12RenderTargetCache::GetOrCreateTransferPipelines( + TransferShaderKey key) { + const TransferModeInfo& mode = kTransferModes[size_t(key.mode)]; + bool dest_is_stencil_bit = (mode.output == TransferOutput::kStencilBit); + + if (dest_is_stencil_bit) { + auto pipelines_it = transfer_stencil_bit_pipelines_.find(key); + if (pipelines_it != transfer_stencil_bit_pipelines_.end()) { + return pipelines_it->second[0] ? pipelines_it->second.data() : nullptr; + } + } else { + auto pipeline_it = transfer_pipelines_.find(key); + if (pipeline_it != transfer_pipelines_.end()) { + return pipeline_it->second ? &pipeline_it->second : nullptr; + } + } + + uint32_t rs = kTransferUsedRootParameters[size_t(use_stencil_reference_output_ + ? mode.root_signature_with_stencil_ref + : mode.root_signature_no_stencil_ref)]; + + // If not dest_is_color, it's depth, or stencil bit - 40-sample columns are + // swapped as opposed to color source. + bool dest_is_color = (mode.output == TransferOutput::kColor); + + xenos::ColorRenderTargetFormat dest_color_format = + xenos::ColorRenderTargetFormat(key.dest_resource_format); + xenos::DepthRenderTargetFormat dest_depth_format = + xenos::DepthRenderTargetFormat(key.dest_resource_format); + bool dest_is_64bpp = dest_is_color && xenos::IsColorRenderTargetFormat64bpp(dest_color_format); + + xenos::ColorRenderTargetFormat source_color_format = + xenos::ColorRenderTargetFormat(key.source_resource_format); + xenos::DepthRenderTargetFormat source_depth_format = + xenos::DepthRenderTargetFormat(key.source_resource_format); + // If not source_is_color, it's depth / stencil - 40-sample columns are + // swapped as opposed to color destination. + bool source_is_color = (rs & kTransferUsedRootParameterColorSRVBit) != 0; + bool source_is_64bpp; + uint32_t source_color_format_component_count; + uint32_t source_color_srv_component_mask; + bool source_color_is_uint; + if (source_is_color) { + assert_zero(rs & kTransferUsedRootParameterDepthSRVBit); + assert_zero(rs & kTransferUsedRootParameterStencilSRVBit); + source_is_64bpp = xenos::IsColorRenderTargetFormat64bpp(source_color_format); + source_color_format_component_count = + xenos::GetColorRenderTargetFormatComponentCount(source_color_format); + if (dest_is_stencil_bit) { + if (source_is_64bpp && !dest_is_64bpp) { + // Need one component, but choosing from the two 32bpp halves of the + // 64bpp sample. + source_color_srv_component_mask = 0b1 | (0b1 << (source_color_format_component_count >> 1)); + } else { + // Red is at least 8 bits per component in all formats. + source_color_srv_component_mask = 0b1; + } + } else { + source_color_srv_component_mask = (uint32_t(1) << source_color_format_component_count) - 1; + } + GetColorOwnershipTransferDXGIFormat(source_color_format, &source_color_is_uint); + } else { + source_is_64bpp = false; + source_color_format_component_count = 0; + source_color_srv_component_mask = 0; + source_color_is_uint = false; + } + + bool shader_uses_stencil_reference_output = + mode.output == TransferOutput::kDepth && use_stencil_reference_output_; + + // Because of built_shader_.resize(), pointers can't be kept persistently + // here! Resizing also zeroes the memory. + + built_shader_.clear(); + + // RDEF, ISGN, OSGN, SHEX, optionally SFI0, STAT. + uint32_t blob_count = 5 + uint32_t(shader_uses_stencil_reference_output); + + // Allocate space for the container header and the blob offsets. + built_shader_.resize(sizeof(dxbc::ContainerHeader) / sizeof(uint32_t) + blob_count); + uint32_t blob_offset_position_dwords = sizeof(dxbc::ContainerHeader) / sizeof(uint32_t); + uint32_t blob_position_dwords = uint32_t(built_shader_.size()); + constexpr uint32_t kBlobHeaderSizeDwords = sizeof(dxbc::BlobHeader) / sizeof(uint32_t); + + uint32_t name_ptr; + + // *************************************************************************** + // Resource definition + // *************************************************************************** + + built_shader_[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + uint32_t rdef_position_dwords = blob_position_dwords + kBlobHeaderSizeDwords; + // Not needed, as the next operation done is resize, to allocate the space for + // both the blob header and the resource definition header. + // built_shader_.resize(rdef_position_dwords); + + // Allocate space for the RDEF header. + built_shader_.resize(rdef_position_dwords + sizeof(dxbc::RdefHeader) / sizeof(uint32_t)); + // Generator name. + dxbc::AppendAlignedString(built_shader_, "Xenia"); + + // Constant types - uint (aka "dword" when it's scalar) only. + // Names. + name_ptr = uint32_t((built_shader_.size() - rdef_position_dwords) * sizeof(uint32_t)); + uint32_t rdef_dword_name_ptr = name_ptr; + name_ptr += dxbc::AppendAlignedString(built_shader_, "dword"); + // Types. + uint32_t rdef_type_uint_position_dwords = uint32_t(built_shader_.size()); + uint32_t rdef_type_uint_ptr = + uint32_t((rdef_type_uint_position_dwords - rdef_position_dwords) * sizeof(uint32_t)); + built_shader_.resize(rdef_type_uint_position_dwords + sizeof(dxbc::RdefType) / sizeof(uint32_t)); + { + auto& rdef_type_uint = + *reinterpret_cast(built_shader_.data() + rdef_type_uint_position_dwords); + rdef_type_uint.variable_class = dxbc::RdefVariableClass::kScalar; + rdef_type_uint.variable_type = dxbc::RdefVariableType::kUInt; + rdef_type_uint.row_count = 1; + rdef_type_uint.column_count = 1; + rdef_type_uint.name_ptr = rdef_dword_name_ptr; + } + + // Constants, if needed: + // - uint xe_transfer_stencil_mask + // - uint xe_transfer_address + // - uint xe_transfer_host_depth_address + uint32_t rdef_constant_count = 0; + uint32_t rdef_constant_index_stencil_mask = + (rs & kTransferUsedRootParameterStencilMaskConstantBit) ? rdef_constant_count++ : UINT32_MAX; + assert_false(dest_is_stencil_bit && rdef_constant_index_stencil_mask == UINT32_MAX); + uint32_t rdef_constant_index_address = + (rs & kTransferUsedRootParameterAddressConstantBit) ? rdef_constant_count++ : UINT32_MAX; + assert_true(rdef_constant_index_address != UINT32_MAX); + uint32_t rdef_constant_index_host_depth_address = + (rs & kTransferUsedRootParameterHostDepthAddressConstantBit) ? rdef_constant_count++ + : UINT32_MAX; + // Names. + name_ptr = uint32_t((built_shader_.size() - rdef_position_dwords) * sizeof(uint32_t)); + uint32_t rdef_xe_transfer_stencil_mask_name_ptr = name_ptr; + if (rdef_constant_index_stencil_mask != UINT32_MAX) { + name_ptr += dxbc::AppendAlignedString(built_shader_, "xe_transfer_stencil_mask"); + } + uint32_t rdef_xe_transfer_address_name_ptr = name_ptr; + if (rdef_constant_index_address != UINT32_MAX) { + name_ptr += dxbc::AppendAlignedString(built_shader_, "xe_transfer_address"); + } + uint32_t rdef_xe_transfer_host_depth_address_name_ptr = name_ptr; + if (rdef_constant_index_host_depth_address != UINT32_MAX) { + name_ptr += dxbc::AppendAlignedString(built_shader_, "xe_transfer_host_depth_address"); + } + // Constants. + uint32_t rdef_constants_position_dwords = uint32_t(built_shader_.size()); + uint32_t rdef_constants_ptr = + uint32_t((rdef_constants_position_dwords - rdef_position_dwords) * sizeof(uint32_t)); + built_shader_.resize(rdef_constants_position_dwords + + sizeof(dxbc::RdefVariable) / sizeof(uint32_t) * rdef_constant_count); + { + auto rdef_constants = reinterpret_cast(built_shader_.data() + + rdef_constants_position_dwords); + // uint xe_transfer_stencil_mask + if (rdef_constant_index_stencil_mask != UINT32_MAX) { + dxbc::RdefVariable& rdef_constant_stencil_mask = + rdef_constants[rdef_constant_index_stencil_mask]; + rdef_constant_stencil_mask.name_ptr = rdef_xe_transfer_stencil_mask_name_ptr; + rdef_constant_stencil_mask.size_bytes = sizeof(uint32_t); + rdef_constant_stencil_mask.flags = dxbc::kRdefVariableFlagUsed; + rdef_constant_stencil_mask.type_ptr = rdef_type_uint_ptr; + rdef_constant_stencil_mask.start_texture = UINT32_MAX; + rdef_constant_stencil_mask.start_sampler = UINT32_MAX; + } + // uint xe_transfer_address + if (rdef_constant_index_address != UINT32_MAX) { + dxbc::RdefVariable& rdef_constant_address = rdef_constants[rdef_constant_index_address]; + rdef_constant_address.name_ptr = rdef_xe_transfer_address_name_ptr; + rdef_constant_address.size_bytes = sizeof(uint32_t); + rdef_constant_address.flags = dxbc::kRdefVariableFlagUsed; + rdef_constant_address.type_ptr = rdef_type_uint_ptr; + rdef_constant_address.start_texture = UINT32_MAX; + rdef_constant_address.start_sampler = UINT32_MAX; + } + // uint xe_transfer_host_depth_address + if (rdef_constant_index_host_depth_address != UINT32_MAX) { + dxbc::RdefVariable& rdef_constant_host_depth_address = + rdef_constants[rdef_constant_index_host_depth_address]; + rdef_constant_host_depth_address.name_ptr = rdef_xe_transfer_host_depth_address_name_ptr; + rdef_constant_host_depth_address.size_bytes = sizeof(uint32_t); + rdef_constant_host_depth_address.flags = dxbc::kRdefVariableFlagUsed; + rdef_constant_host_depth_address.type_ptr = rdef_type_uint_ptr; + rdef_constant_host_depth_address.start_texture = UINT32_MAX; + rdef_constant_host_depth_address.start_sampler = UINT32_MAX; + } + } + + // Constant buffers, if needed: + // - xe_transfer_stencil_mask { uint xe_transfer_stencil_mask; } + // - xe_transfer_address { uint xe_transfer_address; } + // - xe_transfer_host_depth_address { uint xe_transfer_host_depth_address; } + // Reusing the constant names for constant buffers. + uint32_t rdef_cbuffer_count = 0; + uint32_t cbuffer_index_stencil_mask = + rdef_constant_index_stencil_mask != UINT32_MAX ? rdef_cbuffer_count++ : UINT32_MAX; + uint32_t cbuffer_index_address = + rdef_constant_index_address != UINT32_MAX ? rdef_cbuffer_count++ : UINT32_MAX; + uint32_t cbuffer_index_host_depth_address = + rdef_constant_index_host_depth_address != UINT32_MAX ? rdef_cbuffer_count++ : UINT32_MAX; + uint32_t rdef_cbuffer_position_dwords = uint32_t(built_shader_.size()); + built_shader_.resize(rdef_cbuffer_position_dwords + + sizeof(dxbc::RdefCbuffer) / sizeof(uint32_t) * rdef_cbuffer_count); + { + auto rdef_cbuffers = + reinterpret_cast(built_shader_.data() + rdef_cbuffer_position_dwords); + // xe_transfer_stencil_mask + if (cbuffer_index_stencil_mask != UINT32_MAX) { + dxbc::RdefCbuffer& rdef_cbuffer_stencil_mask = rdef_cbuffers[cbuffer_index_stencil_mask]; + rdef_cbuffer_stencil_mask.name_ptr = rdef_xe_transfer_stencil_mask_name_ptr; + rdef_cbuffer_stencil_mask.variable_count = 1; + rdef_cbuffer_stencil_mask.variables_ptr = uint32_t( + rdef_constants_ptr + sizeof(dxbc::RdefVariable) * rdef_constant_index_stencil_mask); + rdef_cbuffer_stencil_mask.size_vector_aligned_bytes = sizeof(uint32_t) * 4; + } + // xe_transfer_address + if (cbuffer_index_address != UINT32_MAX) { + dxbc::RdefCbuffer& rdef_cbuffer_address = rdef_cbuffers[cbuffer_index_address]; + rdef_cbuffer_address.name_ptr = rdef_xe_transfer_address_name_ptr; + rdef_cbuffer_address.variable_count = 1; + rdef_cbuffer_address.variables_ptr = + uint32_t(rdef_constants_ptr + sizeof(dxbc::RdefVariable) * rdef_constant_index_address); + rdef_cbuffer_address.size_vector_aligned_bytes = sizeof(uint32_t) * 4; + } + // xe_transfer_host_depth_address + if (cbuffer_index_host_depth_address != UINT32_MAX) { + dxbc::RdefCbuffer& rdef_cbuffer_host_depth_address = + rdef_cbuffers[cbuffer_index_host_depth_address]; + rdef_cbuffer_host_depth_address.name_ptr = rdef_xe_transfer_host_depth_address_name_ptr; + rdef_cbuffer_host_depth_address.variable_count = 1; + rdef_cbuffer_host_depth_address.variables_ptr = uint32_t( + rdef_constants_ptr + sizeof(dxbc::RdefVariable) * rdef_constant_index_host_depth_address); + rdef_cbuffer_host_depth_address.size_vector_aligned_bytes = sizeof(uint32_t) * 4; + } + } + + // Bindings. + // - Texture2D/Texture2DMS xe_transfer_color + // - Texture2D/Texture2DMS xe_transfer_depth + // - Texture2D/Texture2DMS xe_transfer_stencil + // - Texture2D/Texture2DMS/Buffer xe_transfer_host_depth + // - Constant buffers + uint32_t rdef_srv_count = 0; + uint32_t srv_index_color = + (rs & kTransferUsedRootParameterColorSRVBit) ? rdef_srv_count++ : UINT32_MAX; + uint32_t srv_index_depth = + (rs & kTransferUsedRootParameterDepthSRVBit) ? rdef_srv_count++ : UINT32_MAX; + uint32_t srv_index_stencil = + (rs & kTransferUsedRootParameterStencilSRVBit) ? rdef_srv_count++ : UINT32_MAX; + uint32_t srv_index_host_depth = + (rs & kTransferUsedRootParameterHostDepthSRVBit) ? rdef_srv_count++ : UINT32_MAX; + uint32_t rdef_binding_count = rdef_srv_count + rdef_cbuffer_count; + // Names. + name_ptr = uint32_t((built_shader_.size() - rdef_position_dwords) * sizeof(uint32_t)); + uint32_t rdef_xe_transfer_color_name_ptr = name_ptr; + if (srv_index_color != UINT32_MAX) { + name_ptr += dxbc::AppendAlignedString(built_shader_, "xe_transfer_color"); + } + uint32_t rdef_xe_transfer_depth_name_ptr = name_ptr; + if (srv_index_depth != UINT32_MAX) { + name_ptr += dxbc::AppendAlignedString(built_shader_, "xe_transfer_depth"); + } + uint32_t rdef_xe_transfer_stencil_name_ptr = name_ptr; + if (srv_index_stencil != UINT32_MAX) { + name_ptr += dxbc::AppendAlignedString(built_shader_, "xe_transfer_stencil"); + } + uint32_t rdef_xe_transfer_host_depth_name_ptr = name_ptr; + if (srv_index_host_depth != UINT32_MAX) { + name_ptr += dxbc::AppendAlignedString(built_shader_, "xe_transfer_host_depth"); + } + // Bindings. + uint32_t rdef_binding_position_dwords = uint32_t(built_shader_.size()); + built_shader_.resize(rdef_binding_position_dwords + + sizeof(dxbc::RdefInputBind) / sizeof(uint32_t) * rdef_binding_count); + { + auto rdef_bindings = + reinterpret_cast(built_shader_.data() + rdef_binding_position_dwords); + uint32_t rdef_binding_index = 0; + // xe_transfer_color + if (srv_index_color != UINT32_MAX) { + dxbc::RdefInputBind& rdef_binding_color = rdef_bindings[rdef_binding_index++]; + rdef_binding_color.name_ptr = rdef_xe_transfer_color_name_ptr; + rdef_binding_color.type = dxbc::RdefInputType::kTexture; + rdef_binding_color.return_type = + source_color_is_uint ? dxbc::ResourceReturnType::kUInt : dxbc::ResourceReturnType::kFloat; + if (key.source_msaa_samples != xenos::MsaaSamples::k1X) { + rdef_binding_color.dimension = dxbc::RdefDimension::kSRVTexture2DMS; + } else { + rdef_binding_color.dimension = dxbc::RdefDimension::kSRVTexture2D; + rdef_binding_color.sample_count = UINT32_MAX; + } + rdef_binding_color.bind_point = kTransferSRVRegisterColor; + rdef_binding_color.bind_count = 1; + assert_not_zero(source_color_srv_component_mask); + rdef_binding_color.flags = (32 - rex::lzcnt(source_color_srv_component_mask) - 1) + << dxbc::kRdefInputFlagsComponentsShift; + rdef_binding_color.id = srv_index_color; + } + // xe_transfer_depth + if (srv_index_depth != UINT32_MAX) { + dxbc::RdefInputBind& rdef_binding_depth = rdef_bindings[rdef_binding_index++]; + rdef_binding_depth.name_ptr = rdef_xe_transfer_depth_name_ptr; + rdef_binding_depth.type = dxbc::RdefInputType::kTexture; + rdef_binding_depth.return_type = dxbc::ResourceReturnType::kFloat; + if (key.source_msaa_samples != xenos::MsaaSamples::k1X) { + rdef_binding_depth.dimension = dxbc::RdefDimension::kSRVTexture2DMS; + } else { + rdef_binding_depth.dimension = dxbc::RdefDimension::kSRVTexture2D; + rdef_binding_depth.sample_count = UINT32_MAX; + } + rdef_binding_depth.bind_point = kTransferSRVRegisterDepth; + rdef_binding_depth.bind_count = 1; + rdef_binding_depth.id = srv_index_depth; + } + // xe_transfer_stencil + if (srv_index_stencil != UINT32_MAX) { + dxbc::RdefInputBind& rdef_binding_stencil = rdef_bindings[rdef_binding_index++]; + rdef_binding_stencil.name_ptr = rdef_xe_transfer_stencil_name_ptr; + rdef_binding_stencil.type = dxbc::RdefInputType::kTexture; + rdef_binding_stencil.return_type = dxbc::ResourceReturnType::kUInt; + if (key.source_msaa_samples != xenos::MsaaSamples::k1X) { + rdef_binding_stencil.dimension = dxbc::RdefDimension::kSRVTexture2DMS; + } else { + rdef_binding_stencil.dimension = dxbc::RdefDimension::kSRVTexture2D; + rdef_binding_stencil.sample_count = UINT32_MAX; + } + rdef_binding_stencil.bind_point = kTransferSRVRegisterStencil; + rdef_binding_stencil.bind_count = 1; + rdef_binding_stencil.flags = dxbc::kRdefInputFlags2Component; + rdef_binding_stencil.id = srv_index_stencil; + } + // xe_transfer_host_depth + if (srv_index_host_depth != UINT32_MAX) { + dxbc::RdefInputBind& rdef_binding_host_depth = rdef_bindings[rdef_binding_index++]; + rdef_binding_host_depth.name_ptr = rdef_xe_transfer_host_depth_name_ptr; + rdef_binding_host_depth.type = dxbc::RdefInputType::kTexture; + if (key.host_depth_source_is_copy) { + // Float as uint. + rdef_binding_host_depth.return_type = dxbc::ResourceReturnType::kUInt; + rdef_binding_host_depth.dimension = dxbc::RdefDimension::kSRVBuffer; + rdef_binding_host_depth.sample_count = UINT32_MAX; + } else { + rdef_binding_host_depth.return_type = dxbc::ResourceReturnType::kFloat; + if (key.host_depth_source_msaa_samples != xenos::MsaaSamples::k1X) { + rdef_binding_host_depth.dimension = dxbc::RdefDimension::kSRVTexture2DMS; + } else { + rdef_binding_host_depth.dimension = dxbc::RdefDimension::kSRVTexture2D; + rdef_binding_host_depth.sample_count = UINT32_MAX; + } + } + rdef_binding_host_depth.bind_point = kTransferSRVRegisterHostDepth; + rdef_binding_host_depth.bind_count = 1; + rdef_binding_host_depth.id = srv_index_host_depth; + } + // xe_transfer_stencil_mask + if (cbuffer_index_stencil_mask != UINT32_MAX) { + dxbc::RdefInputBind& rdef_binding_stencil_mask = rdef_bindings[rdef_binding_index++]; + rdef_binding_stencil_mask.name_ptr = rdef_xe_transfer_stencil_mask_name_ptr; + rdef_binding_stencil_mask.type = dxbc::RdefInputType::kCbuffer; + rdef_binding_stencil_mask.bind_point = kTransferCBVRegisterStencilMask; + rdef_binding_stencil_mask.bind_count = 1; + rdef_binding_stencil_mask.flags = dxbc::kRdefInputFlagUserPacked; + rdef_binding_stencil_mask.id = cbuffer_index_stencil_mask; + } + // xe_transfer_address + if (cbuffer_index_address != UINT32_MAX) { + dxbc::RdefInputBind& rdef_binding_address = rdef_bindings[rdef_binding_index++]; + rdef_binding_address.name_ptr = rdef_xe_transfer_address_name_ptr; + rdef_binding_address.type = dxbc::RdefInputType::kCbuffer; + rdef_binding_address.bind_point = kTransferCBVRegisterAddress; + rdef_binding_address.bind_count = 1; + rdef_binding_address.flags = dxbc::kRdefInputFlagUserPacked; + rdef_binding_address.id = cbuffer_index_address; + } + // xe_transfer_host_depth_address + if (cbuffer_index_host_depth_address != UINT32_MAX) { + dxbc::RdefInputBind& rdef_binding_host_depth_address = rdef_bindings[rdef_binding_index++]; + rdef_binding_host_depth_address.name_ptr = rdef_xe_transfer_host_depth_address_name_ptr; + rdef_binding_host_depth_address.type = dxbc::RdefInputType::kCbuffer; + rdef_binding_host_depth_address.bind_point = kTransferCBVRegisterHostDepthAddress; + rdef_binding_host_depth_address.bind_count = 1; + rdef_binding_host_depth_address.flags = dxbc::kRdefInputFlagUserPacked; + rdef_binding_host_depth_address.id = cbuffer_index_host_depth_address; + } + } + + // Header. + { + auto& rdef_header = + *reinterpret_cast(built_shader_.data() + rdef_position_dwords); + rdef_header.cbuffer_count = rdef_cbuffer_count; + rdef_header.cbuffers_ptr = + uint32_t((rdef_cbuffer_position_dwords - rdef_position_dwords) * sizeof(uint32_t)); + rdef_header.input_bind_count = rdef_binding_count; + rdef_header.input_binds_ptr = + uint32_t((rdef_binding_position_dwords - rdef_position_dwords) * sizeof(uint32_t)); + rdef_header.shader_model = dxbc::RdefShaderModel::kPixelShader5_1; + rdef_header.compile_flags = + dxbc::kCompileFlagNoPreshader | dxbc::kCompileFlagPreferFlowControl | + dxbc::kCompileFlagIeeeStrictness | dxbc::kCompileFlagAllResourcesBound; + // Generator name is right after the header. + rdef_header.generator_name_ptr = sizeof(dxbc::RdefHeader); + rdef_header.fourcc = dxbc::RdefHeader::FourCC::k5_1; + rdef_header.InitializeSizes(); + } + + { + auto& blob_header = + *reinterpret_cast(built_shader_.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kResourceDefinition; + blob_position_dwords = uint32_t(built_shader_.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + built_shader_[blob_offset_position_dwords++]; + } + + // *************************************************************************** + // Input signature + // *************************************************************************** + + // Registers for accessing in the shader code - multiple inputs may be packed + // into the same register. + enum InputRegister : uint32_t { + kInputRegisterPosition, + kInputRegisterSampleIndex, + kInputRegisterCount, + }; + + // Position, and for multisampled, sample index. + uint32_t isgn_parameter_count = 1 + uint32_t(key.dest_msaa_samples != xenos::MsaaSamples::k1X); + + // Reserve space for the header and the parameters. + built_shader_[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + uint32_t isgn_position_dwords = blob_position_dwords + kBlobHeaderSizeDwords; + built_shader_.resize(isgn_position_dwords + sizeof(dxbc::Signature) / sizeof(uint32_t) + + sizeof(dxbc::SignatureParameter) / sizeof(uint32_t) * isgn_parameter_count); + + // Names (after the parameters). + name_ptr = uint32_t((built_shader_.size() - isgn_position_dwords) * sizeof(uint32_t)); + uint32_t isgn_sv_position_name_ptr = name_ptr; + name_ptr += dxbc::AppendAlignedString(built_shader_, "SV_Position"); + uint32_t isgn_sv_sample_index_name_ptr = name_ptr; + if (key.dest_msaa_samples != xenos::MsaaSamples::k1X) { + name_ptr += dxbc::AppendAlignedString(built_shader_, "SV_SampleIndex"); + } + + // Header and parameters. + { + // Header. + auto& isgn_header = + *reinterpret_cast(built_shader_.data() + isgn_position_dwords); + isgn_header.parameter_count = isgn_parameter_count; + isgn_header.parameter_info_ptr = sizeof(dxbc::Signature); + // Parameters. + auto isgn_parameters = reinterpret_cast( + built_shader_.data() + isgn_position_dwords + sizeof(dxbc::Signature) / sizeof(uint32_t)); + uint32_t isgn_parameter_index = 0; + // SV_Position.xy + dxbc::SignatureParameter& isgn_sv_position = isgn_parameters[isgn_parameter_index++]; + isgn_sv_position.semantic_name_ptr = isgn_sv_position_name_ptr; + isgn_sv_position.system_value = dxbc::Name::kPosition; + isgn_sv_position.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + isgn_sv_position.register_index = kInputRegisterPosition; + isgn_sv_position.mask = 0b1111; + isgn_sv_position.always_reads_mask = 0b0011; + // SV_SampleIndex + if (key.dest_msaa_samples != xenos::MsaaSamples::k1X) { + dxbc::SignatureParameter& isgn_sv_sample_index = isgn_parameters[isgn_parameter_index++]; + isgn_sv_sample_index.semantic_name_ptr = isgn_sv_sample_index_name_ptr; + isgn_sv_sample_index.system_value = dxbc::Name::kSampleIndex; + isgn_sv_sample_index.component_type = dxbc::SignatureRegisterComponentType::kUInt32; + isgn_sv_sample_index.register_index = kInputRegisterSampleIndex; + isgn_sv_sample_index.mask = 0b0001; + isgn_sv_sample_index.always_reads_mask = 0b0001; + } + } + + { + auto& blob_header = + *reinterpret_cast(built_shader_.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kInputSignature; + blob_position_dwords = uint32_t(built_shader_.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + built_shader_[blob_offset_position_dwords++]; + } + + // *************************************************************************** + // Output signature + // *************************************************************************** + + // Color or depth. + uint32_t osgn_parameter_count = 0; + uint32_t osgn_parameter_index_sv_target = + mode.output == TransferOutput::kColor ? osgn_parameter_count++ : UINT32_MAX; + uint32_t osgn_parameter_index_sv_depth = + mode.output == TransferOutput::kDepth ? osgn_parameter_count++ : UINT32_MAX; + uint32_t osgn_parameter_index_sv_stencil_ref = + shader_uses_stencil_reference_output ? osgn_parameter_count++ : UINT32_MAX; + + // Reserve space for the header and the parameters. + built_shader_[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + uint32_t osgn_position_dwords = blob_position_dwords + kBlobHeaderSizeDwords; + built_shader_.resize(osgn_position_dwords + sizeof(dxbc::Signature) / sizeof(uint32_t) + + sizeof(dxbc::SignatureParameter) / sizeof(uint32_t) * osgn_parameter_count); + + // Names (after the parameters). + name_ptr = uint32_t((built_shader_.size() - osgn_position_dwords) * sizeof(uint32_t)); + uint32_t osgn_sv_target_name_ptr = name_ptr; + if (osgn_parameter_index_sv_target != UINT32_MAX) { + name_ptr += dxbc::AppendAlignedString(built_shader_, "SV_Target"); + } + uint32_t osgn_sv_depth_name_ptr = name_ptr; + if (osgn_parameter_index_sv_depth != UINT32_MAX) { + name_ptr += dxbc::AppendAlignedString(built_shader_, "SV_Depth"); + } + uint32_t osgn_sv_stencil_ref_name_ptr = name_ptr; + if (osgn_parameter_index_sv_stencil_ref != UINT32_MAX) { + name_ptr += dxbc::AppendAlignedString(built_shader_, "SV_StencilRef"); + } + + bool dest_color_is_uint; + if (mode.output == TransferOutput::kColor) { + GetColorOwnershipTransferDXGIFormat(dest_color_format, &dest_color_is_uint); + } else { + dest_color_is_uint = false; + } + + // Header and parameters. + { + // Header. + auto& osgn_header = + *reinterpret_cast(built_shader_.data() + osgn_position_dwords); + osgn_header.parameter_count = osgn_parameter_count; + osgn_header.parameter_info_ptr = sizeof(dxbc::Signature); + // Parameters. + auto osgn_parameters = reinterpret_cast( + built_shader_.data() + osgn_position_dwords + sizeof(dxbc::Signature) / sizeof(uint32_t)); + // SV_Target + if (osgn_parameter_index_sv_target != UINT32_MAX) { + dxbc::SignatureParameter& osgn_sv_target = osgn_parameters[osgn_parameter_index_sv_target]; + osgn_sv_target.semantic_name_ptr = osgn_sv_target_name_ptr; + osgn_sv_target.component_type = dest_color_is_uint + ? dxbc::SignatureRegisterComponentType::kUInt32 + : dxbc::SignatureRegisterComponentType::kFloat32; + osgn_sv_target.register_index = 0; + osgn_sv_target.mask = 0b1111; + } + // SV_Depth + if (osgn_parameter_index_sv_depth != UINT32_MAX) { + dxbc::SignatureParameter& osgn_sv_depth = osgn_parameters[osgn_parameter_index_sv_depth]; + osgn_sv_depth.semantic_name_ptr = osgn_sv_depth_name_ptr; + osgn_sv_depth.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + osgn_sv_depth.register_index = UINT32_MAX; + osgn_sv_depth.mask = 0b0001; + osgn_sv_depth.never_writes_mask = 0b1110; + } + // SV_StencilRef + if (osgn_parameter_index_sv_stencil_ref != UINT32_MAX) { + dxbc::SignatureParameter& osgn_sv_stencil_ref = + osgn_parameters[osgn_parameter_index_sv_stencil_ref]; + osgn_sv_stencil_ref.semantic_name_ptr = osgn_sv_stencil_ref_name_ptr; + // Older versions of FXC incorrectly expect SV_StencilRef to be float, + // it's always uint in DXC and also in the latest versions of FXC. + osgn_sv_stencil_ref.component_type = dxbc::SignatureRegisterComponentType::kUInt32; + osgn_sv_stencil_ref.register_index = UINT32_MAX; + osgn_sv_stencil_ref.mask = 0b0001; + osgn_sv_stencil_ref.never_writes_mask = 0b1110; + } + } + + { + auto& blob_header = + *reinterpret_cast(built_shader_.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kOutputSignature; + blob_position_dwords = uint32_t(built_shader_.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + built_shader_[blob_offset_position_dwords++]; + } + + // *************************************************************************** + // Shader program + // *************************************************************************** + + built_shader_[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + uint32_t shex_position_dwords = blob_position_dwords + kBlobHeaderSizeDwords; + built_shader_.resize(shex_position_dwords); + + built_shader_.push_back(dxbc::VersionToken(dxbc::ProgramType::kPixelShader, 5, 1)); + // Reserve space for the length token. + built_shader_.push_back(0); + + dxbc::Statistics stat; + std::memset(&stat, 0, sizeof(dxbc::Statistics)); + dxbc::Assembler a(built_shader_, stat); + + a.OpDclGlobalFlags(dxbc::kGlobalFlagAllResourcesBound); + if (cbuffer_index_stencil_mask != UINT32_MAX) { + a.OpDclConstantBuffer( + dxbc::Src::CB(dxbc::Src::Dcl, cbuffer_index_stencil_mask, kTransferCBVRegisterStencilMask, + kTransferCBVRegisterStencilMask), + 1); + } + if (cbuffer_index_address != UINT32_MAX) { + a.OpDclConstantBuffer(dxbc::Src::CB(dxbc::Src::Dcl, cbuffer_index_address, + kTransferCBVRegisterAddress, kTransferCBVRegisterAddress), + 1); + } + if (cbuffer_index_host_depth_address != UINT32_MAX) { + a.OpDclConstantBuffer( + dxbc::Src::CB(dxbc::Src::Dcl, cbuffer_index_host_depth_address, + kTransferCBVRegisterHostDepthAddress, kTransferCBVRegisterHostDepthAddress), + 1); + } + if (srv_index_color != UINT32_MAX) { + a.OpDclResource( + key.source_msaa_samples != xenos::MsaaSamples::k1X ? dxbc::ResourceDimension::kTexture2DMS + : dxbc::ResourceDimension::kTexture2D, + dxbc::ResourceReturnTypeX4Token(source_color_is_uint ? dxbc::ResourceReturnType::kUInt + : dxbc::ResourceReturnType::kFloat), + dxbc::Src::T(dxbc::Src::Dcl, srv_index_color, kTransferSRVRegisterColor, + kTransferSRVRegisterColor)); + } + if (srv_index_depth != UINT32_MAX) { + a.OpDclResource(key.source_msaa_samples != xenos::MsaaSamples::k1X + ? dxbc::ResourceDimension::kTexture2DMS + : dxbc::ResourceDimension::kTexture2D, + dxbc::ResourceReturnTypeX4Token(dxbc::ResourceReturnType::kFloat), + dxbc::Src::T(dxbc::Src::Dcl, srv_index_depth, kTransferSRVRegisterDepth, + kTransferSRVRegisterDepth)); + } + if (srv_index_stencil != UINT32_MAX) { + a.OpDclResource(key.source_msaa_samples != xenos::MsaaSamples::k1X + ? dxbc::ResourceDimension::kTexture2DMS + : dxbc::ResourceDimension::kTexture2D, + dxbc::ResourceReturnTypeX4Token(dxbc::ResourceReturnType::kUInt), + dxbc::Src::T(dxbc::Src::Dcl, srv_index_stencil, kTransferSRVRegisterStencil, + kTransferSRVRegisterStencil)); + } + if (srv_index_host_depth != UINT32_MAX) { + a.OpDclResource(key.host_depth_source_is_copy + ? dxbc::ResourceDimension::kBuffer + : (key.host_depth_source_msaa_samples != xenos::MsaaSamples::k1X + ? dxbc::ResourceDimension::kTexture2DMS + : dxbc::ResourceDimension::kTexture2D), + dxbc::ResourceReturnTypeX4Token(dxbc::ResourceReturnType::kFloat), + dxbc::Src::T(dxbc::Src::Dcl, srv_index_host_depth, + kTransferSRVRegisterHostDepth, kTransferSRVRegisterHostDepth)); + } + a.OpDclInputPSSIV(dxbc::InterpolationMode::kLinearNoPerspective, + dxbc::Dest::V1D(kInputRegisterPosition, 0b0011), dxbc::Name::kPosition); + if (key.dest_msaa_samples != xenos::MsaaSamples::k1X) { + a.OpDclInputPSSGV(dxbc::Dest::V1D(kInputRegisterSampleIndex, 0b0001), dxbc::Name::kSampleIndex); + } + if (osgn_parameter_index_sv_target != UINT32_MAX) { + a.OpDclOutput(dxbc::Dest::O(0)); + } + if (osgn_parameter_index_sv_depth != UINT32_MAX) { + a.OpDclOutput(dxbc::Dest::ODepth()); + } + if (osgn_parameter_index_sv_stencil_ref != UINT32_MAX) { + a.OpDclOutput(dxbc::Dest::OStencilRef()); + } + // r0:r2 are involved at least in common addressing code. Texture loads + // usually can overwrite some of the addressing temps as they are only needed + // for the coordinates for that load. Currently 3 temps are enough. + a.OpDclTemps(3); + + uint32_t draw_resolution_scale_x = this->draw_resolution_scale_x(); + uint32_t draw_resolution_scale_y = this->draw_resolution_scale_y(); + + uint32_t tile_width_samples = xenos::kEdramTileWidthSamples * draw_resolution_scale_x; + uint32_t tile_height_samples = xenos::kEdramTileHeightSamples * draw_resolution_scale_y; + + // Split the destination pixel index into 32bpp tile in r0.zw and + // 32bpp-tile-relative pixel index in r0.xy. + // r0.xy = pixel XY as uint + a.OpFToU(dxbc::Dest::R(0, 0b0011), dxbc::Src::V1D(kInputRegisterPosition)); + uint32_t dest_tile_width_pixels = + tile_width_samples >> + (uint32_t(dest_is_64bpp) + uint32_t(key.dest_msaa_samples >= xenos::MsaaSamples::k4X)); + uint32_t dest_tile_height_pixels = + tile_height_samples >> uint32_t(key.dest_msaa_samples >= xenos::MsaaSamples::k2X); + // r0.xy = destination pixel XY index within the 32bpp tile + // r0.zw = 32bpp tile XY index + a.OpUDiv(dxbc::Dest::R(0, 0b1100), dxbc::Dest::R(0, 0b0011), dxbc::Src::R(0, 0b01000100), + dxbc::Src::LU(dest_tile_width_pixels, dest_tile_height_pixels, dest_tile_width_pixels, + dest_tile_height_pixels)); + + // r1.x = destination pitch in 32bpp tiles + a.OpUBFE(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(xenos::kEdramPitchTilesBits), dxbc::Src::LU(0), + dxbc::Src::CB(cbuffer_index_address, kTransferCBVRegisterAddress, 0, dxbc::Src::kXXXX)); + // r0.z = 32bpp tile index relative to the destination base + // r0.w = free + // r1.x = free + a.OpUMAd(dxbc::Dest::R(0, 0b0100), dxbc::Src::R(1, dxbc::Src::kXXXX), + dxbc::Src::R(0, dxbc::Src::kWWWW), dxbc::Src::R(0, dxbc::Src::kZZZZ)); + + // Now the tile index doesn't have any dependencies on the destination. The + // dword index within the source tile, however, is calculated from both the + // source and the destination pixel size, sample count and color vs. depth. + + // Source can be 64bpp or 32bpp - depth if only depth is available, color in + // all other cases. + + // Load the source to r1 (or low to r0, high to r1 if need 64bpp color as the + // result, as the address is loaded to r1). + + // Source pixel and sample index within the 32bpp tile. + // X to r1.x (or keep r0.x if not modifying). + // Y to r1.y (or keep r0.y if not modifying). + // Sample index to r1.z (or use v# if not modifying); r1.z will also be set + // to 0 before sampling for the LOD of the single-sampled source (needs to + // be in the register). + // If 64bpp -> 32bpp, also the needed half in r0.w. + + dxbc::Src dest_sample(dxbc::Src::V1D(kInputRegisterSampleIndex, dxbc::Src::kXXXX)); + dxbc::Src source_sample(dest_sample); + uint32_t source_tile_pixel_x_reg = 0; + uint32_t source_tile_pixel_y_reg = 0; + + // First sample bit at 4x in Direct3D 10.1+ - horizontal sample. + // Second sample bit at 4x in Direct3D 10.1+ - vertical sample. + // At 2x: + // - Native 2x: top is 1 in Direct3D 10.1+, bottom is 0. + // - 2x as 4x: top is 0, bottom is 3. + + if (!source_is_64bpp && dest_is_64bpp) { + // 32bpp -> 64bpp, need two samples of the source. + if (key.source_msaa_samples >= xenos::MsaaSamples::k4X) { + // 32bpp -> 64bpp, 4x ->. + // Source has 32bpp halves in two adjacent samples. + if (key.dest_msaa_samples >= xenos::MsaaSamples::k4X) { + // 32bpp -> 64bpp, 4x -> 4x. + // 1 destination horizontal sample = 2 source horizontal samples. + // D p0,0 s0,0 = S p0,0 s0,0 | S p0,0 s1,0 + // D p0,0 s1,0 = S p1,0 s0,0 | S p1,0 s1,0 + // D p0,0 s0,1 = S p0,0 s0,1 | S p0,0 s1,1 + // D p0,0 s1,1 = S p1,0 s0,1 | S p1,0 s1,1 + // Thus destination horizontal sample -> source horizontal pixel, + // vertical samples are 1:1. + a.OpAnd(dxbc::Dest::R(1, 0b0100), dest_sample, dxbc::Src::LU(0b10)); + source_sample = dxbc::Src::R(1, dxbc::Src::kZZZZ); + a.OpBFI(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(31), dxbc::Src::LU(1), + dxbc::Src::R(0, dxbc::Src::kXXXX), + dxbc::Src::V1D(kInputRegisterSampleIndex, dxbc::Src::kXXXX)); + source_tile_pixel_x_reg = 1; + } else if (key.dest_msaa_samples == xenos::MsaaSamples::k2X) { + // 32bpp -> 64bpp, 4x -> 2x. + // 1 destination horizontal pixel = 2 source horizontal samples. + // D p0,0 s0 = S p0,0 s0,0 | S p0,0 s1,0 + // D p0,0 s1 = S p0,0 s0,1 | S p0,0 s1,1 + // D p1,0 s0 = S p1,0 s0,0 | S p1,0 s1,0 + // D p1,0 s1 = S p1,0 s0,1 | S p1,0 s1,1 + // Pixel index can be reused. Sample 1 (for native 2x) or 0 (for 2x as + // 4x) should become samples 01, sample 0 or 3 should become samples 23. + source_sample = dxbc::Src::R(1, dxbc::Src::kZZZZ); + if (msaa_2x_supported_) { + a.OpXOr(dxbc::Dest::R(1, 0b0100), dest_sample, dxbc::Src::LU(1)); + a.OpIShL(dxbc::Dest::R(1, 0b0100), source_sample, dxbc::Src::LU(1)); + } else { + a.OpAnd(dxbc::Dest::R(1, 0b0100), dest_sample, dxbc::Src::LU(0b10)); + } + } else { + // 32bpp -> 64bpp, 4x -> 1x. + // 1 destination horizontal pixel = 2 source horizontal samples. + // D p0,0 = S p0,0 s0,0 | S p0,0 s1,0 + // D p0,1 = S p0,0 s0,1 | S p0,0 s1,1 + // Horizontal pixel index can be reused. Vertical pixel 1 should + // become sample 2. + a.OpBFI(dxbc::Dest::R(1, 0b0100), dxbc::Src::LU(1), dxbc::Src::LU(1), + dxbc::Src::R(0, dxbc::Src::kYYYY), dxbc::Src::LU(0)); + source_sample = dxbc::Src::R(1, dxbc::Src::kZZZZ); + a.OpUShR(dxbc::Dest::R(1, 0b0010), dxbc::Src::R(0, dxbc::Src::kYYYY), dxbc::Src::LU(1)); + source_tile_pixel_y_reg = 1; + } + } else { + // 32bpp -> 64bpp, 1x/2x ->. + // Source has 32bpp halves in two adjacent pixels. + if (key.dest_msaa_samples >= xenos::MsaaSamples::k4X) { + // 32bpp -> 64bpp, 1x/2x -> 4x. + // The X part. + // 1 destination horizontal sample = 2 source horizontal pixels. + a.OpIShL(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(0, dxbc::Src::kXXXX), dxbc::Src::LU(2)); + a.OpBFI(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(1), dxbc::Src::LU(1), + dxbc::Src::V1D(kInputRegisterSampleIndex, dxbc::Src::kXXXX), + dxbc::Src::R(1, dxbc::Src::kXXXX)); + source_tile_pixel_x_reg = 1; + // Y is handled by common code. + } else { + // 32bpp -> 64bpp, 1x/2x -> 1x/2x. + // The X part. + // 1 destination horizontal pixel = 2 source horizontal pixels. + a.OpIShL(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(0, dxbc::Src::kXXXX), dxbc::Src::LU(1)); + source_tile_pixel_x_reg = 1; + // Y is handled by common code. + } + } + } else if (source_is_64bpp && !dest_is_64bpp) { + // 64bpp -> 32bpp, also the half to r0.w. + if (key.dest_msaa_samples >= xenos::MsaaSamples::k4X) { + // 64bpp -> 32bpp, -> 4x. + // The needed half is in the destination horizontal sample index. + if (key.source_msaa_samples >= xenos::MsaaSamples::k4X) { + // 64bpp -> 32bpp, 4x -> 4x. + // D p0,0 s0,0 = S s0,0 low + // D p0,0 s1,0 = S s0,0 high + // D p1,0 s0,0 = S s1,0 low + // D p1,0 s1,0 = S s1,0 high + // Vertical pixel and sample (second bit) addressing is the same. + // However, 1 horizontal destination pixel = 1 horizontal source sample. + a.OpBFI(dxbc::Dest::R(1, 0b0100), dxbc::Src::LU(1), dxbc::Src::LU(0), + dxbc::Src::R(0, dxbc::Src::kXXXX), dest_sample); + source_sample = dxbc::Src::R(1, dxbc::Src::kZZZZ); + // 2 destination horizontal samples = 1 source horizontal sample, thus + // 2 destination horizontal pixels = 1 source horizontal pixel. + a.OpUShR(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(0, dxbc::Src::kXXXX), dxbc::Src::LU(1)); + source_tile_pixel_x_reg = 1; + } else { + // 64bpp -> 32bpp, 1x/2x -> 4x. + // 2 destination horizontal samples = 1 source horizontal pixel, thus + // 1 destination horizontal pixel = 1 source horizontal pixel. Can reuse + // horizontal pixel index. + // Y is handled by common code. + } + // Half in r0.w from the destination horizontal sample index. + a.OpAnd(dxbc::Dest::R(0, 0b1000), dest_sample, dxbc::Src::LU(1)); + } else { + // 64bpp -> 32bpp, -> 1x/2x. + // The needed half is in the destination horizontal pixel index. + if (key.source_msaa_samples >= xenos::MsaaSamples::k4X) { + // 64bpp -> 32bpp, 4x -> 1x/2x. + // (Destination horizontal pixel >> 1) & 1 = source horizontal sample + // (first bit). + a.OpUBFE(dxbc::Dest::R(1, 0b0100), dxbc::Src::LU(1), dxbc::Src::LU(1), + dxbc::Src::R(0, dxbc::Src::kXXXX)); + source_sample = dxbc::Src::R(1, dxbc::Src::kZZZZ); + if (key.dest_msaa_samples == xenos::MsaaSamples::k2X) { + // 64bpp -> 32bpp, 4x -> 2x. + // Destination vertical samples (1/0 in the first bit for native 2x or + // 0/1 in the second bit for 2x as 4x) = source vertical samples + // (second bit). + if (msaa_2x_supported_) { + a.OpBFI(dxbc::Dest::R(1, 0b0100), dxbc::Src::LU(1), dxbc::Src::LU(1), dest_sample, + source_sample); + a.OpXOr(dxbc::Dest::R(1, 0b0100), source_sample, dxbc::Src::LU(1 << 1)); + } else { + a.OpBFI(dxbc::Dest::R(1, 0b0100), dxbc::Src::LU(1), dxbc::Src::LU(0), source_sample, + dest_sample); + } + } else { + // 64bpp -> 32bpp, 4x -> 1x. + // 1 destination vertical pixel = 1 source vertical sample. + a.OpBFI(dxbc::Dest::R(1, 0b0100), dxbc::Src::LU(1), dxbc::Src::LU(1), + dxbc::Src::R(0, dxbc::Src::kYYYY), source_sample); + a.OpUShR(dxbc::Dest::R(1, 0b0010), dxbc::Src::R(0, dxbc::Src::kYYYY), dxbc::Src::LU(1)); + source_tile_pixel_y_reg = 1; + } + // 2 destination horizontal pixels = 1 source horizontal sample. + // 4 destination horizontal pixels = 1 source horizontal pixel. + a.OpUShR(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(0, dxbc::Src::kXXXX), dxbc::Src::LU(2)); + source_tile_pixel_x_reg = 1; + } else { + // 64bpp -> 32bpp, 1x/2x -> 1x/2x. + // The X part. + // 2 destination horizontal pixels = 1 destination source pixel. + a.OpUShR(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(0, dxbc::Src::kXXXX), dxbc::Src::LU(1)); + source_tile_pixel_x_reg = 1; + // Y is handled by common code. + } + // Half in r0.w from the destination horizontal pixel index. + a.OpAnd(dxbc::Dest::R(0, 0b1000), dxbc::Src::R(0, dxbc::Src::kXXXX), dxbc::Src::LU(1)); + } + } else { + // Same bit count. + if (key.source_msaa_samples != key.dest_msaa_samples) { + if (key.source_msaa_samples >= xenos::MsaaSamples::k4X) { + // Same BPP, 4x -> 1x/2x. + if (key.dest_msaa_samples == xenos::MsaaSamples::k2X) { + // Same BPP, 4x -> 2x. + // Horizontal pixels to samples. Vertical sample (1/0 in the first bit + // for native 2x or 0/1 in the second bit for 2x as 4x) to second + // sample bit. + source_sample = dxbc::Src::R(1, dxbc::Src::kZZZZ); + if (msaa_2x_supported_) { + a.OpBFI(dxbc::Dest::R(1, 0b0100), dxbc::Src::LU(31), dxbc::Src::LU(1), dest_sample, + dxbc::Src::R(0, dxbc::Src::kXXXX)); + a.OpXOr(dxbc::Dest::R(1, 0b0100), source_sample, dxbc::Src::LU(1 << 1)); + } else { + a.OpBFI(dxbc::Dest::R(1, 0b0100), dxbc::Src::LU(1), dxbc::Src::LU(0), + dxbc::Src::R(0, dxbc::Src::kXXXX), dest_sample); + } + a.OpUShR(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(0, dxbc::Src::kXXXX), dxbc::Src::LU(1)); + source_tile_pixel_x_reg = 1; + } else { + // Same BPP, 4x -> 1x. + // Pixels to samples. + a.OpAnd(dxbc::Dest::R(1, 0b0100), dxbc::Src::R(0, dxbc::Src::kXXXX), dxbc::Src::LU(1)); + source_sample = dxbc::Src::R(1, dxbc::Src::kZZZZ); + a.OpBFI(dxbc::Dest::R(1, 0b0100), dxbc::Src::LU(1), dxbc::Src::LU(1), + dxbc::Src::R(0, dxbc::Src::kYYYY), source_sample); + a.OpUShR(dxbc::Dest::R(1, 0b0011), dxbc::Src::R(0), dxbc::Src::LU(1)); + source_tile_pixel_x_reg = 1; + source_tile_pixel_y_reg = 1; + } + } else { + // Same BPP, 1x/2x -> 1x/2x/4x (as long as they're different). + // Only the X part - Y is handled by common code. + if (key.dest_msaa_samples >= xenos::MsaaSamples::k4X) { + // Horizontal samples to pixels. + a.OpBFI(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(31), dxbc::Src::LU(1), + dxbc::Src::R(0, dxbc::Src::kXXXX), dest_sample); + source_tile_pixel_x_reg = 1; + } + } + } + } + // Common source Y and sample index for 1x/2x AA sources, independent of bits + // per sample. + if (key.source_msaa_samples < xenos::MsaaSamples::k4X && + key.source_msaa_samples != key.dest_msaa_samples) { + if (key.dest_msaa_samples >= xenos::MsaaSamples::k4X) { + // 1x/2x -> 4x. + if (key.source_msaa_samples == xenos::MsaaSamples::k2X) { + // 2x -> 4x. + // Vertical samples (second bit) of 4x destination to vertical sample + // (1, 0 for native 2x, or 0, 3 for 2x as 4x) of 2x source. + a.OpUShR(dxbc::Dest::R(1, 0b0100), dest_sample, dxbc::Src::LU(1)); + source_sample = dxbc::Src::R(1, dxbc::Src::kZZZZ); + if (msaa_2x_supported_) { + a.OpXOr(dxbc::Dest::R(1, 0b0100), source_sample, dxbc::Src::LU(1)); + } else { + a.OpBFI(dxbc::Dest::R(1, 0b0100), dxbc::Src::LU(1), dxbc::Src::LU(1), source_sample, + source_sample); + } + } else { + // 1x -> 4x. + // Vertical samples (second bit) to Y pixels. + a.OpUShR(dxbc::Dest::R(1, 0b0010), dest_sample, dxbc::Src::LU(1)); + a.OpBFI(dxbc::Dest::R(1, 0b0010), dxbc::Src::LU(31), dxbc::Src::LU(1), + dxbc::Src::R(0, dxbc::Src::kYYYY), dxbc::Src::R(1, dxbc::Src::kYYYY)); + source_tile_pixel_y_reg = 1; + } + } else { + // 1x/2x -> different 1x/2x. + if (key.source_msaa_samples == xenos::MsaaSamples::k2X) { + // 2x -> 1x. + // Vertical pixels of 2x destination to vertical samples (1, 0 for + // native 2x, or 0, 3 for 2x as 4x) of 1x source. + a.OpAnd(dxbc::Dest::R(1, 0b0100), dxbc::Src::R(0, dxbc::Src::kYYYY), dxbc::Src::LU(1)); + source_sample = dxbc::Src::R(1, dxbc::Src::kZZZZ); + if (msaa_2x_supported_) { + a.OpXOr(dxbc::Dest::R(1, 0b0100), source_sample, dxbc::Src::LU(1)); + } else { + a.OpBFI(dxbc::Dest::R(1, 0b0100), dxbc::Src::LU(1), dxbc::Src::LU(1), source_sample, + source_sample); + } + a.OpUShR(dxbc::Dest::R(1, 0b0010), dxbc::Src::R(0, dxbc::Src::kYYYY), dxbc::Src::LU(1)); + source_tile_pixel_y_reg = 1; + } else { + // 1x -> 2x. + // Vertical samples (1/0 in the first bit for native 2x or 0/1 in the + // second bit for 2x as 4x) of 2x destination to vertical pixels of 1x + // source. + if (msaa_2x_supported_) { + a.OpBFI(dxbc::Dest::R(1, 0b0010), dxbc::Src::LU(31), dxbc::Src::LU(1), + dxbc::Src::R(0, dxbc::Src::kYYYY), dest_sample); + a.OpXOr(dxbc::Dest::R(1, 0b0010), dxbc::Src::R(1, dxbc::Src::kYYYY), dxbc::Src::LU(1)); + } else { + a.OpUShR(dxbc::Dest::R(1, 0b0010), dest_sample, dxbc::Src::LU(1)); + a.OpBFI(dxbc::Dest::R(1, 0b0010), dxbc::Src::LU(31), dxbc::Src::LU(1), + dxbc::Src::R(0, dxbc::Src::kYYYY), dxbc::Src::R(1, dxbc::Src::kYYYY)); + } + source_tile_pixel_y_reg = 1; + } + } + } + + uint32_t source_pixel_width_dwords_log2 = + uint32_t(key.source_msaa_samples >= xenos::MsaaSamples::k4X) + uint32_t(source_is_64bpp); + + if (source_is_color != dest_is_color) { + // Copying between color and depth / stencil - swap 40-32bpp-sample columns + // in the pixel index within the source 32bpp tile using r1.w as temporary. + uint32_t source_32bpp_tile_half_pixels = + tile_width_samples >> (1 + source_pixel_width_dwords_log2); + a.OpULT(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(source_tile_pixel_x_reg, dxbc::Src::kXXXX), + dxbc::Src::LU(source_32bpp_tile_half_pixels)); + a.OpMovC(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(1, dxbc::Src::kWWWW), + dxbc::Src::LI(int32_t(source_32bpp_tile_half_pixels)), + dxbc::Src::LI(-int32_t(source_32bpp_tile_half_pixels))); + a.OpIAdd(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(source_tile_pixel_x_reg, dxbc::Src::kXXXX), + dxbc::Src::R(1, dxbc::Src::kWWWW)); + source_tile_pixel_x_reg = 1; + // r1.w = free + } + + // Current register allocation: + // r0.xy = pixel index within the destination 32bpp tile + // r0.z = 32bpp tile index relative to the destination base + // r0.w for 64bpp -> 32bpp - needed 32bpp half index of 64bpp data + // r1.xy = pixel index within the source 32bpp tile + // r1.z for 2x/4x -> = sample index within the source pixel + + // Apply the source 32bpp tile index. + // r1.w = destination to source EDRAM tile adjustment + a.OpIBFE(dxbc::Dest::R(1, 0b1000), dxbc::Src::LU(xenos::kEdramBaseTilesBits + 1), + dxbc::Src::LU(xenos::kEdramPitchTilesBits * 2), + dxbc::Src::CB(cbuffer_index_address, kTransferCBVRegisterAddress, 0, dxbc::Src::kXXXX)); + // r1.w = 32bpp tile index within the source, or the tile index within the + // source minus the EDRAM tile count if transferring across addressing + // wrapping (if negative) + a.OpIAdd(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(0, dxbc::Src::kZZZZ), + dxbc::Src::R(1, dxbc::Src::kWWWW)); + // r1.w = 32bpp tile index within the source + a.OpAnd(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(1, dxbc::Src::kWWWW), + dxbc::Src::LU(xenos::kEdramTileCount - 1)); + // r2.x = source pitch in 32bpp tiles + a.OpUBFE(dxbc::Dest::R(2, 0b0001), dxbc::Src::LU(xenos::kEdramPitchTilesBits), + dxbc::Src::LU(xenos::kEdramPitchTilesBits), + dxbc::Src::CB(cbuffer_index_address, kTransferCBVRegisterAddress, 0, dxbc::Src::kXXXX)); + // r1.w = source tile row + // r2.x = source 32bpp tile within the row + a.OpUDiv(dxbc::Dest::R(1, 0b1000), dxbc::Dest::R(2, 0b0001), dxbc::Src::R(1, dxbc::Src::kWWWW), + dxbc::Src::R(2, dxbc::Src::kXXXX)); + // r1.x = pixel X within the source texture + // r2.x = free + a.OpUMAd( + dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(tile_width_samples >> source_pixel_width_dwords_log2), + dxbc::Src::R(2, dxbc::Src::kXXXX), dxbc::Src::R(source_tile_pixel_x_reg, dxbc::Src::kXXXX)); + // r1.y = pixel Y within the source texture + // r1.w = free + a.OpUMAd(dxbc::Dest::R(1, 0b0010), + dxbc::Src::LU(tile_height_samples >> + uint32_t(key.source_msaa_samples >= xenos::MsaaSamples::k2X)), + dxbc::Src::R(1, dxbc::Src::kWWWW), + dxbc::Src::R(source_tile_pixel_y_reg, dxbc::Src::kYYYY)); + + // Load the source to r1, or, for 32bpp | 32bpp -> 64bpp, the first dword to + // r0 since addressing will not be needed anymore for color, and the second + // dword to r1. + // Depth will be loaded to w before loading stencil (so it doesn't overwrite + // the coordinates needed for stencil loading). + // Stencil will be loaded to x. + // Color will be loaded to x...w. + bool source_load_is_two_dwords = !source_is_64bpp && dest_is_64bpp; + if (key.source_msaa_samples != xenos::MsaaSamples::k1X) { + for (uint32_t i = 0; i <= uint32_t(source_load_is_two_dwords); ++i) { + uint32_t source_load_register = source_load_is_two_dwords ? i : 1; + if (srv_index_depth != UINT32_MAX) { + a.OpLdMS(dxbc::Dest::R(source_load_register, 0b1000), dxbc::Src::R(1), 0b0011, + dxbc::Src::T(srv_index_depth, kTransferSRVRegisterDepth, dxbc::Src::kXXXX), + source_sample); + } + if (srv_index_stencil != UINT32_MAX) { + a.OpLdMS(dxbc::Dest::R(source_load_register, 0b0001), dxbc::Src::R(1), 0b0011, + dxbc::Src::T(srv_index_stencil, kTransferSRVRegisterStencil, dxbc::Src::kYYYY), + source_sample); + } else if (srv_index_color != UINT32_MAX) { + a.OpLdMS(dxbc::Dest::R(source_load_register, source_color_srv_component_mask), + dxbc::Src::R(1), 0b0011, dxbc::Src::T(srv_index_color, kTransferSRVRegisterColor), + source_sample); + } + if (source_load_is_two_dwords && !i) { + // Go to the next sample or pixel along X if need to load two dwords. + if (key.source_msaa_samples >= xenos::MsaaSamples::k4X) { + a.OpOr(dxbc::Dest::R(1, 0b0100), source_sample, dxbc::Src::LU(1)); + source_sample = dxbc::Src::R(1, dxbc::Src::kZZZZ); + } else { + a.OpOr(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(1, dxbc::Src::kXXXX), dxbc::Src::LU(1)); + } + } + } + } else { + // Write zero to the LOD index in r1.z. + a.OpMov(dxbc::Dest::R(1, 0b0100), dxbc::Src::LU(0)); + dxbc::Src source_coordinates(dxbc::Src::R(1, 0b10000100)); + for (uint32_t i = 0; i <= uint32_t(source_load_is_two_dwords); ++i) { + uint32_t source_load_register = source_load_is_two_dwords ? i : 1; + if (srv_index_depth != UINT32_MAX) { + a.OpLd(dxbc::Dest::R(source_load_register, 0b1000), source_coordinates, 0b1011, + dxbc::Src::T(srv_index_depth, kTransferSRVRegisterDepth, dxbc::Src::kXXXX)); + } + if (srv_index_stencil != UINT32_MAX) { + a.OpLd(dxbc::Dest::R(source_load_register, 0b0001), source_coordinates, 0b1011, + dxbc::Src::T(srv_index_stencil, kTransferSRVRegisterStencil, dxbc::Src::kYYYY)); + } else if (srv_index_color != UINT32_MAX) { + a.OpLd(dxbc::Dest::R(source_load_register, source_color_srv_component_mask), + source_coordinates, 0b1011, + dxbc::Src::T(srv_index_color, kTransferSRVRegisterColor)); + } + if (source_load_is_two_dwords && !i) { + // Go to the next pixel along X if need to load two dwords. + a.OpOr(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(1, dxbc::Src::kXXXX), dxbc::Src::LU(1)); + } + } + } + // Pick the needed 32bpp half of the 64bpp color based on r0.w. + if (source_is_64bpp && !dest_is_64bpp) { + uint32_t source_color_half_component_count = source_color_format_component_count >> 1; + if (dest_is_stencil_bit) { + a.OpMovC(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(0, dxbc::Src::kWWWW), + dxbc::Src::R(1).Select(source_color_half_component_count), + dxbc::Src::R(1, dxbc::Src::kXXXX)); + } else { + uint32_t color_high_dword_swizzle = + (source_color_half_component_count * 0b01010101) & + ~((uint32_t(1) << (source_color_half_component_count * 2)) - 1); + for (uint32_t i = 0; i < source_color_half_component_count; ++i) { + color_high_dword_swizzle |= (source_color_half_component_count + i) << (i * 2); + } + a.OpMovC(dxbc::Dest::R(1, (1 << source_color_half_component_count) - 1), + dxbc::Src::R(0, dxbc::Src::kWWWW), dxbc::Src::R(1, color_high_dword_swizzle), + dxbc::Src::R(1)); + } + } + + if (osgn_parameter_index_sv_stencil_ref != UINT32_MAX && srv_index_stencil != UINT32_MAX) { + // For the depth -> depth case, write the stencil loaded to r1.x directly to + // the output. + assert_true(mode.output == TransferOutput::kDepth); + a.OpMov(dxbc::Dest::OStencilRef(), dxbc::Src::R(1, dxbc::Src::kXXXX)); + } + + if (dest_is_64bpp) { + // Handle construction of 64bpp color, either from two 32-bit samples in r0 + // and r1, or from one 64bpp sample in r1. Using r2.x as temporary when + // needed. + // If color_packed_in_r0x_and_r1x, use the generic path for combining two + // 32-bit samples - as raw in r0.x and r1.x - into the destination. + bool color_packed_in_r0x_and_r1x = false; + if (source_is_color) { + switch (source_color_format) { + case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA: { + // 8_8_8_8_GAMMA is represented by linear stored in + // R16G16B16A16_UNORM. + for (uint32_t i = 0; i < 2; ++i) { + for (uint32_t j = 0; j < 3; ++j) { + DxbcShaderTranslator::PreSaturatedLinearToPWLGamma(a, i, j, i, j, 2, 0, 2, 1); + } + } + } + [[fallthrough]]; + case xenos::ColorRenderTargetFormat::k_8_8_8_8: { + color_packed_in_r0x_and_r1x = true; + for (uint32_t i = 0; i < 2; ++i) { + a.OpMAd(dxbc::Dest::R(i), dxbc::Src::R(i), dxbc::Src::LF(255.0f), dxbc::Src::LF(0.5f)); + a.OpFToU(dxbc::Dest::R(i), dxbc::Src::R(i)); + for (uint32_t j = 1; j < 4; ++j) { + a.OpBFI(dxbc::Dest::R(i, 0b0001), dxbc::Src::LU(8), dxbc::Src::LU(j * 8), + dxbc::Src::R(i).Select(j), dxbc::Src::R(i, dxbc::Src::kXXXX)); + } + } + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: { + color_packed_in_r0x_and_r1x = true; + for (uint32_t i = 0; i < 2; ++i) { + a.OpMAd(dxbc::Dest::R(i), dxbc::Src::R(i), + dxbc::Src::LF(1023.0f, 1023.0f, 1023.0f, 3.0f), dxbc::Src::LF(0.5f)); + a.OpFToU(dxbc::Dest::R(i), dxbc::Src::R(i)); + for (uint32_t j = 1; j < 4; ++j) { + a.OpBFI(dxbc::Dest::R(i, 0b0001), dxbc::Src::LU(j == 3 ? 2 : 10), + dxbc::Src::LU(j * 10), dxbc::Src::R(i).Select(j), + dxbc::Src::R(i, dxbc::Src::kXXXX)); + } + } + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16: { + color_packed_in_r0x_and_r1x = true; + for (uint32_t i = 0; i < 2; ++i) { + // Float16 has a wider range for both color and alpha, also NaNs - + // clamp and convert. + for (uint32_t j = 0; j < 3; ++j) { + DxbcShaderTranslator::UnclampedFloat32To7e3(a, i, j, i, j, 2, 0); + if (j) { + a.OpBFI(dxbc::Dest::R(i, 0b0001), dxbc::Src::LU(10), dxbc::Src::LU(j * 10), + dxbc::Src::R(i).Select(j), dxbc::Src::R(i, dxbc::Src::kXXXX)); + } + } + // Saturate and convert the alpha. + a.OpMov(dxbc::Dest::R(i, 0b1000), dxbc::Src::R(i, dxbc::Src::kWWWW), true); + a.OpMAd(dxbc::Dest::R(i, 0b1000), dxbc::Src::R(i, dxbc::Src::kWWWW), + dxbc::Src::LF(3.0f), dxbc::Src::LF(0.5f)); + a.OpFToU(dxbc::Dest::R(i, 0b1000), dxbc::Src::R(i, dxbc::Src::kWWWW)); + a.OpBFI(dxbc::Dest::R(i, 0b0001), dxbc::Src::LU(2), dxbc::Src::LU(30), + dxbc::Src::R(i, dxbc::Src::kWWWW), dxbc::Src::R(i, dxbc::Src::kXXXX)); + } + } break; + // All 64bpp formats, and all 16 bits per component formats, are + // represented as integers in ownership transfer for safe handling of + // NaNs and -32768 / -32767. + case xenos::ColorRenderTargetFormat::k_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_FLOAT: { + if (dest_color_format == xenos::ColorRenderTargetFormat::k_32_32_FLOAT) { + for (uint32_t i = 0; i < 2; ++i) { + a.OpBFI(dxbc::Dest::O(0, 1 << i), dxbc::Src::LU(16), dxbc::Src::LU(16), + dxbc::Src::R(i, dxbc::Src::kYYYY), dxbc::Src::R(i, dxbc::Src::kXXXX)); + } + } else { + a.OpMov(dxbc::Dest::O(0, 0b0011), dxbc::Src::R(0)); + a.OpMov(dxbc::Dest::O(0, 0b1100), dxbc::Src::R(1, 0b0100 << 4)); + } + } break; + case xenos::ColorRenderTargetFormat::k_16_16_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT: { + if (dest_color_format == xenos::ColorRenderTargetFormat::k_32_32_FLOAT) { + a.OpBFI(dxbc::Dest::O(0, 0b0011), dxbc::Src::LU(16), dxbc::Src::LU(16), + dxbc::Src::R(1, 0b1101), dxbc::Src::R(1, 0b1000)); + } else { + a.OpMov(dxbc::Dest::O(0), dxbc::Src::R(1)); + } + } break; + case xenos::ColorRenderTargetFormat::k_32_FLOAT: { + color_packed_in_r0x_and_r1x = true; + } break; + case xenos::ColorRenderTargetFormat::k_32_32_FLOAT: { + if (dest_color_format == xenos::ColorRenderTargetFormat::k_32_32_FLOAT) { + a.OpMov(dxbc::Dest::O(0, 0b0011), dxbc::Src::R(1)); + } else { + a.OpUBFE(dxbc::Dest::O(0), dxbc::Src::LU(16), dxbc::Src::LU(0, 16, 0, 16), + dxbc::Src::R(1, 0b01010000)); + } + } break; + } + } else { + assert_not_zero(rs & kTransferUsedRootParameterDepthSRVBit); + color_packed_in_r0x_and_r1x = true; + for (uint32_t i = 0; i < 2; ++i) { + switch (source_depth_format) { + case xenos::DepthRenderTargetFormat::kD24S8: { + // Round to the nearest even integer. This seems to be the correct + // conversion, adding +0.5 and rounding towards zero results in red + // instead of black in the 4D5307E6 clear shader. + a.OpMul(dxbc::Dest::R(i, 0b1000), dxbc::Src::R(i, dxbc::Src::kWWWW), + dxbc::Src::LF(float(0xFFFFFF))); + a.OpRoundNE(dxbc::Dest::R(i, 0b1000), dxbc::Src::R(i, dxbc::Src::kWWWW)); + a.OpFToU(dxbc::Dest::R(i, 0b1000), dxbc::Src::R(i, dxbc::Src::kWWWW)); + } break; + case xenos::DepthRenderTargetFormat::kD24FS8: { + // Convert using r1.y as temporary. + // When converting the depth in pixel shaders, it's always exact, + // truncating not to insert additional rounding instructions. + DxbcShaderTranslator::PreClampedDepthTo20e4( + a, i, 3, i, 3, 1, 1, + !depth_float24_convert_in_pixel_shader() && depth_float24_round(), true); + } break; + } + // Merge depth and stencil into r0/r1.x. + a.OpBFI(dxbc::Dest::R(i, 0b0001), dxbc::Src::LU(24), dxbc::Src::LU(8), + dxbc::Src::R(i, dxbc::Src::kWWWW), dxbc::Src::R(i, dxbc::Src::kXXXX)); + } + } + if (color_packed_in_r0x_and_r1x) { + if (dest_color_format == xenos::ColorRenderTargetFormat::k_32_32_FLOAT) { + a.OpMov(dxbc::Dest::O(0, 0b0001), dxbc::Src::R(0, dxbc::Src::kXXXX)); + a.OpMov(dxbc::Dest::O(0, 0b0010), dxbc::Src::R(1, dxbc::Src::kXXXX)); + } else { + for (uint32_t i = 0; i < 2; ++i) { + a.OpUBFE(dxbc::Dest::O(0, 0b11 << (i * 2)), dxbc::Src::LU(16), + dxbc::Src::LU(0, 16, 0, 16), dxbc::Src::R(i, dxbc::Src::kXXXX)); + } + } + } + } else { + // Handle a 32bpp destination (32bpp color, or depth / stencil). If + // color_packed_in_r1x is true, a raw 32bpp color value was written, and + // common handling will be done. + bool color_packed_in_r1x = false; + bool depth_loaded_in_guest_format = false; + if (source_is_color) { + switch (source_color_format) { + case xenos::ColorRenderTargetFormat::k_8_8_8_8: + case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA: { + if (dest_is_stencil_bit) { + if (source_color_format == xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA) { + DxbcShaderTranslator::PreSaturatedLinearToPWLGamma(a, 1, 0, 1, 0, 2, 0, 2, 1); + } + a.OpMAd(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(1, dxbc::Src::kXXXX), + dxbc::Src::LF(255.0f), dxbc::Src::LF(0.5f)); + a.OpFToU(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(1, dxbc::Src::kXXXX)); + } else if (dest_is_color && + (dest_color_format == xenos::ColorRenderTargetFormat::k_8_8_8_8 || + dest_color_format == xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA)) { + if (source_color_format != dest_color_format) { + // Color space conversion between k_8_8_8_8 and + // k_8_8_8_8_GAMMA. + if (dest_color_format != xenos::ColorRenderTargetFormat::k_8_8_8_8) { + for (uint32_t i = 0; i < 3; ++i) { + DxbcShaderTranslator::PreSaturatedLinearToPWLGamma(a, 1, i, 1, i, 2, 0, 2, 1); + } + } else { + for (uint32_t i = 0; i < 3; ++i) { + DxbcShaderTranslator::PWLGammaToLinear(a, 1, i, 1, i, true, 2, 0, 2, 1); + } + } + } + // Same or converted format - passthrough. + a.OpMov(dxbc::Dest::O(0), dxbc::Src::R(1)); + } else if (mode.output == TransferOutput::kDepth) { + if (source_color_format == xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA) { + for (uint32_t i = osgn_parameter_index_sv_stencil_ref != UINT32_MAX ? 0 : 1; i < 3; + ++i) { + DxbcShaderTranslator::PreSaturatedLinearToPWLGamma(a, 1, i, 1, i, 2, 0, 2, 1); + } + } + // When need only depth, not stencil, skip the red component. + a.OpMAd(dxbc::Dest::R( + 1, osgn_parameter_index_sv_stencil_ref != UINT32_MAX ? 0b1111 : 0b1110), + dxbc::Src::R(1), dxbc::Src::LF(255.0f), dxbc::Src::LF(0.5f)); + a.OpFToU(dxbc::Dest::R(1, 0b1110), dxbc::Src::R(1)); + if (osgn_parameter_index_sv_stencil_ref != UINT32_MAX) { + // Write the red component to the stencil reference. + a.OpFToU(dxbc::Dest::OStencilRef(), dxbc::Src::R(1, dxbc::Src::kXXXX)); + } + // Put depth in 0:23 of r1.w. + // r1.y = 0xGGBB0000. + a.OpBFI(dxbc::Dest::R(1, 0b0010), dxbc::Src::LU(8), dxbc::Src::LU(8), + dxbc::Src::R(1, dxbc::Src::kZZZZ), dxbc::Src::R(1, dxbc::Src::kYYYY)); + // r1.w = 0xGGBBAA00. + a.OpBFI(dxbc::Dest::R(1, 0b1000), dxbc::Src::LU(8), dxbc::Src::LU(16), + dxbc::Src::R(1, dxbc::Src::kWWWW), dxbc::Src::R(1, dxbc::Src::kYYYY)); + } else { + if (source_color_format == xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA) { + for (uint32_t i = 0; i < 3; ++i) { + DxbcShaderTranslator::PreSaturatedLinearToPWLGamma(a, 1, i, 1, i, 2, 0, 2, 1); + } + } + color_packed_in_r1x = true; + a.OpMAd(dxbc::Dest::R(1), dxbc::Src::R(1), dxbc::Src::LF(255.0f), dxbc::Src::LF(0.5f)); + a.OpFToU(dxbc::Dest::R(1), dxbc::Src::R(1)); + for (uint32_t i = 1; i < 4; ++i) { + a.OpBFI(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(8), dxbc::Src::LU(i * 8), + dxbc::Src::R(1).Select(i), dxbc::Src::R(1, dxbc::Src::kXXXX)); + } + } + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: { + if (dest_is_stencil_bit) { + a.OpMAd(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(1, dxbc::Src::kXXXX), + dxbc::Src::LF(1023.0f), dxbc::Src::LF(0.5f)); + a.OpFToU(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(1, dxbc::Src::kXXXX)); + } else if (dest_is_color && + (dest_color_format == xenos::ColorRenderTargetFormat::k_2_10_10_10 || + dest_color_format == + xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10)) { + a.OpMov(dxbc::Dest::O(0), dxbc::Src::R(1)); + } else { + color_packed_in_r1x = true; + a.OpMAd(dxbc::Dest::R(1), dxbc::Src::R(1), + dxbc::Src::LF(1023.0f, 1023.0f, 1023.0f, 3.0f), dxbc::Src::LF(0.5f)); + a.OpFToU(dxbc::Dest::R(1), dxbc::Src::R(1)); + for (uint32_t i = 1; i < 4; ++i) { + a.OpBFI(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(i == 3 ? 2 : 10), + dxbc::Src::LU(i * 10), dxbc::Src::R(1).Select(i), + dxbc::Src::R(1, dxbc::Src::kXXXX)); + } + } + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16: { + if (dest_is_stencil_bit) { + DxbcShaderTranslator::UnclampedFloat32To7e3(a, 1, 0, 1, 0, 2, 0); + } else if (dest_is_color && + (dest_color_format == xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT || + dest_color_format == + xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16)) { + a.OpMov(dxbc::Dest::O(0), dxbc::Src::R(1)); + } else { + color_packed_in_r1x = true; + // Float16 has a wider range for both color and alpha, also NaNs - + // clamp and convert. + for (uint32_t i = 0; i < 3; ++i) { + DxbcShaderTranslator::UnclampedFloat32To7e3(a, 1, i, 1, i, 2, 0); + if (i) { + a.OpBFI(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(10), dxbc::Src::LU(i * 10), + dxbc::Src::R(1).Select(i), dxbc::Src::R(1, dxbc::Src::kXXXX)); + } + } + // Saturate and convert the alpha. + a.OpMov(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(1, dxbc::Src::kWWWW), true); + a.OpMAd(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(1, dxbc::Src::kWWWW), + dxbc::Src::LF(3.0f), dxbc::Src::LF(0.5f)); + a.OpFToU(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(1, dxbc::Src::kWWWW)); + a.OpBFI(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(2), dxbc::Src::LU(30), + dxbc::Src::R(1, dxbc::Src::kWWWW), dxbc::Src::R(1, dxbc::Src::kXXXX)); + } + } break; + case xenos::ColorRenderTargetFormat::k_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_FLOAT: + case xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT: { + // All 16 bits per component formats are represented as integers in + // ownership transfer for safe handling of NaNs and -32768 / -32767. + if (dest_is_stencil_bit) { + // High bits are not important for discarding, as only one bit is + // checked - already loaded to red. + } else if (dest_is_color && + (dest_color_format == xenos::ColorRenderTargetFormat::k_16_16 || + dest_color_format == xenos::ColorRenderTargetFormat::k_16_16_FLOAT)) { + a.OpMov(dxbc::Dest::O(0, 0b0011), dxbc::Src::R(1)); + } else { + color_packed_in_r1x = true; + a.OpBFI(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(16), dxbc::Src::LU(16), + dxbc::Src::R(1, dxbc::Src::kYYYY), dxbc::Src::R(1, dxbc::Src::kXXXX)); + } + } break; + case xenos::ColorRenderTargetFormat::k_32_FLOAT: + case xenos::ColorRenderTargetFormat::k_32_32_FLOAT: { + color_packed_in_r1x = true; + } break; + } + } else if (rs & kTransferUsedRootParameterDepthSRVBit) { + if (dest_is_color || dest_depth_format != source_depth_format) { + // Need to reinterpret the depth value as color or as a different depth + // format. Convert the depth within r1.w. + depth_loaded_in_guest_format = true; + switch (source_depth_format) { + case xenos::DepthRenderTargetFormat::kD24S8: { + // Round to the nearest even integer. This seems to be the correct + // conversion, adding +0.5 and rounding towards zero results in red + // instead of black in the 4D5307E6 clear shader. + a.OpMul(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(1, dxbc::Src::kWWWW), + dxbc::Src::LF(float(0xFFFFFF))); + a.OpRoundNE(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(1, dxbc::Src::kWWWW)); + a.OpFToU(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(1, dxbc::Src::kWWWW)); + } break; + case xenos::DepthRenderTargetFormat::kD24FS8: { + // Convert using r1.y as temporary. + // When converting the depth in pixel shaders, it's always exact, + // truncating not to insert additional rounding instructions. + DxbcShaderTranslator::PreClampedDepthTo20e4( + a, 1, 3, 1, 3, 1, 1, + !depth_float24_convert_in_pixel_shader() && depth_float24_round(), true); + } break; + } + if (dest_is_color) { + // Merge depth and stencil into r1.x for reinterpretation as color. + color_packed_in_r1x = true; + a.OpBFI(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(24), dxbc::Src::LU(8), + dxbc::Src::R(1, dxbc::Src::kWWWW), dxbc::Src::R(1, dxbc::Src::kXXXX)); + } + } + } + switch (mode.output) { + case TransferOutput::kColor: + // Unless a special path was taken, unpack the raw 32bpp value into the + // 32bpp color output. Any register can be used as temporary if needed - + // this is the end of the shader. + if (color_packed_in_r1x) { + switch (dest_color_format) { + case xenos::ColorRenderTargetFormat::k_8_8_8_8: { + a.OpUBFE(dxbc::Dest::R(1), dxbc::Src::LU(8), dxbc::Src::LU(0, 8, 16, 24), + dxbc::Src::R(1, dxbc::Src::kXXXX)); + a.OpUToF(dxbc::Dest::R(1), dxbc::Src::R(1)); + a.OpMul(dxbc::Dest::O(0), dxbc::Src::R(1), dxbc::Src::LF(1.0f / 255.0f)); + } break; + case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA: { + // 8_8_8_8_GAMMA is represented by linear stored in + // R16G16B16A16_UNORM. + a.OpUBFE(dxbc::Dest::R(1), dxbc::Src::LU(8), dxbc::Src::LU(0, 8, 16, 24), + dxbc::Src::R(1, dxbc::Src::kXXXX)); + a.OpUToF(dxbc::Dest::R(1), dxbc::Src::R(1)); + a.OpMul(dxbc::Dest::R(1, 0b0111), dxbc::Src::R(1), dxbc::Src::LF(1.0f / 255.0f)); + a.OpMul(dxbc::Dest::O(0, 0b1000), dxbc::Src::R(1), dxbc::Src::LF(1.0f / 255.0f)); + for (uint32_t i = 0; i < 3; ++i) { + DxbcShaderTranslator::PWLGammaToLinear(a, 1, i, 1, i, true, 0, 0, 0, 1); + } + a.OpMov(dxbc::Dest::O(0, 0b0111), dxbc::Src::R(1)); + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: { + a.OpUBFE(dxbc::Dest::R(1), dxbc::Src::LU(10, 10, 10, 2), dxbc::Src::LU(0, 10, 20, 30), + dxbc::Src::R(1, dxbc::Src::kXXXX)); + a.OpUToF(dxbc::Dest::R(1), dxbc::Src::R(1)); + a.OpMul(dxbc::Dest::O(0), dxbc::Src::R(1), + dxbc::Src::LF(1.0f / 1023.0f, 1.0f / 1023.0f, 1.0f / 1023.0f, 1.0f / 3.0f)); + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16: { + // Color using r1.yz as temporary. + for (uint32_t i = 0; i < 3; ++i) { + DxbcShaderTranslator::Float7e3To32(a, dxbc::Dest::O(0, 1 << i), 1, 0, i * 10, 1, 1, + 1, 2); + } + // Alpha. + a.OpUBFE(dxbc::Dest::R(1, 0b1000), dxbc::Src::LU(2), dxbc::Src::LU(30), + dxbc::Src::R(1, dxbc::Src::kXXXX)); + a.OpUToF(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(1, dxbc::Src::kWWWW)); + a.OpMul(dxbc::Dest::O(0, 0b1000), dxbc::Src::R(1, dxbc::Src::kWWWW), + dxbc::Src::LF(1.0f / 3.0f)); + } break; + case xenos::ColorRenderTargetFormat::k_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_FLOAT: { + // All 16 bits per component formats are represented as integers + // in ownership transfer for safe handling of NaNs and + // -32768 / -32767. + a.OpUBFE(dxbc::Dest::O(0, 0b0011), dxbc::Src::LU(16), dxbc::Src::LU(0, 16, 0, 0), + dxbc::Src::R(1, dxbc::Src::kXXXX)); + } break; + case xenos::ColorRenderTargetFormat::k_32_FLOAT: { + // Already as a 32-bit value. + a.OpMov(dxbc::Dest::O(0, 0b0001), dxbc::Src::R(1, dxbc::Src::kXXXX)); + } break; + default: + // A 64bpp format (handled separately) or an invalid one. + assert_unhandled_case(dest_color_format); + } + } + break; + case TransferOutput::kDepth: + if (source_is_color || depth_loaded_in_guest_format) { + if (color_packed_in_r1x) { + // Extract the depth bits to r1.w. + a.OpUBFE(dxbc::Dest::R(1, 0b1000), dxbc::Src::LU(24), dxbc::Src::LU(8), + dxbc::Src::R(1, dxbc::Src::kXXXX)); + if (osgn_parameter_index_sv_stencil_ref != UINT32_MAX) { + // Extract the stencil bits to the stencil reference. + // The depth -> depth case is handled earlier, not long after + // loading the stencil, for simplicity. + a.OpUBFE(dxbc::Dest::OStencilRef(), dxbc::Src::LU(8), dxbc::Src::LU(0), + dxbc::Src::R(1, dxbc::Src::kXXXX)); + } + } + // r1.w contains the depth in the guest format. If a host depth source + // is available, need to check if it's up to date - if it is, the host + // precision value needs to be written. Otherwise, the new guest value + // needs to be converted to the host format. Using `if` here because + // it's likely that the values will either be the same - if not + // modified - or different - if cleared or totally overwritten - in + // large amounts of samples, usually whole waves, at once. + if (rs & kTransferUsedRootParameterHostDepthSRVBit) { + // Load the host float32 depth to r0.x, check if, when converted to + // the guest format, it's the same as the guest source, thus up to + // date, and if it is, write host float32 depth to r1.w, otherwise + // do the guest -> host conversion on the `else` path. + + // Current register allocation: + // r0.xy = pixel index within the destination 32bpp tile + // r0.z = 32bpp tile index relative to the destination base + // r1.w = depth in guest format + + if (key.host_depth_source_is_copy) { + // Get the address in the EDRAM scratch buffer and load from + // there. + // The beginning of the buffer is (0, 0) of the destination. + // 40-sample columns are not swapped for addressing simplicity + // (because this is used for depth -> depth transfers, where + // swapping isn't needed). + // Convert samples to pixels. + assert_true(key.host_depth_source_msaa_samples == xenos::MsaaSamples::k1X); + if (key.dest_msaa_samples >= xenos::MsaaSamples::k2X) { + if (key.dest_msaa_samples >= xenos::MsaaSamples::k4X) { + // Horizontal sample index in bit 0. + a.OpBFI(dxbc::Dest::R(0, 0b0001), dxbc::Src::LU(31), dxbc::Src::LU(1), + dxbc::Src::R(0, dxbc::Src::kXXXX), dest_sample); + } + // Vertical sample index as 1 or 0 in bit 0 for true 2x or as 0 + // or 1 in bit 1 for 4x or for 2x emulated as 4x. + if (key.dest_msaa_samples == xenos::MsaaSamples::k2X && msaa_2x_supported_) { + a.OpBFI(dxbc::Dest::R(0, 0b0010), dxbc::Src::LU(31), dxbc::Src::LU(1), + dxbc::Src::R(0, dxbc::Src::kYYYY), dest_sample); + a.OpXOr(dxbc::Dest::R(0, 0b0010), dxbc::Src::R(0, dxbc::Src::kYYYY), + dxbc::Src::LU(1)); + } else { + // Using r0.w as a temporary. + a.OpUShR(dxbc::Dest::R(0, 0b1000), dest_sample, dxbc::Src::LU(1)); + a.OpBFI(dxbc::Dest::R(0, 0b0010), dxbc::Src::LU(31), dxbc::Src::LU(1), + dxbc::Src::R(0, dxbc::Src::kYYYY), dxbc::Src::R(0, dxbc::Src::kWWWW)); + } + } + // Combine the tile sample index and the tile index into buffer + // address to r0.x. + // The tile index doesn't need to be wrapped, as the host depth is + // written to the beginning of the buffer, without the base + // offset. + a.OpUMAd(dxbc::Dest::R(0, 0b0001), dxbc::Src::LU(tile_width_samples), + dxbc::Src::R(0, dxbc::Src::kYYYY), dxbc::Src::R(0, dxbc::Src::kXXXX)); + a.OpUMAd(dxbc::Dest::R(0, 0b0001), + dxbc::Src::LU(tile_width_samples * tile_height_samples), + dxbc::Src::R(0, dxbc::Src::kZZZZ), dxbc::Src::R(0, dxbc::Src::kXXXX)); + // Load from the buffer. + a.OpLd(dxbc::Dest::R(0, 0b0001), dxbc::Src::R(0, dxbc::Src::kXXXX), 0b0001, + dxbc::Src::T(srv_index_host_depth, kTransferSRVRegisterHostDepth, + dxbc::Src::kXXXX)); + } else { + // Adjust the tile index from the destination to the host depth + // source. + // r0.w = destination to host depth source EDRAM tile adjustment + a.OpIBFE(dxbc::Dest::R(0, 0b1000), dxbc::Src::LU(xenos::kEdramBaseTilesBits + 1), + dxbc::Src::LU(xenos::kEdramPitchTilesBits * 2), + dxbc::Src::CB(cbuffer_index_host_depth_address, + kTransferCBVRegisterHostDepthAddress, 0, dxbc::Src::kXXXX)); + // r0.z = tile index relative to the host depth source base, or + // the tile index within the host depth source minus the + // EDRAM tile count if transferring across addressing + // wrapping (if negative) + // r0.w = free + a.OpIAdd(dxbc::Dest::R(0, 0b0100), dxbc::Src::R(0, dxbc::Src::kZZZZ), + dxbc::Src::R(0, dxbc::Src::kWWWW)); + // r0.z = tile index relative to the host depth source base + a.OpAnd(dxbc::Dest::R(0, 0b0100), dxbc::Src::R(0, dxbc::Src::kZZZZ), + dxbc::Src::LU(xenos::kEdramTileCount - 1)); + // Convert position and sample index from within the destination + // tile to within the host depth source tile, like for the guest + // render target, but for 32bpp -> 32bpp only. + dxbc::Src host_depth_source_sample(dest_sample); + if (key.host_depth_source_msaa_samples != key.dest_msaa_samples) { + if (key.host_depth_source_msaa_samples >= xenos::MsaaSamples::k4X) { + // 4x -> 1x/2x. + if (key.dest_msaa_samples == xenos::MsaaSamples::k2X) { + // 4x -> 2x. + // Horizontal pixels to samples. Vertical sample (1, 0 in + // the first bit for native 2x or 0, 1 in the second bit for + // 2x as 4x) to second sample bit. + host_depth_source_sample = dxbc::Src::R(0, dxbc::Src::kWWWW); + if (msaa_2x_supported_) { + a.OpBFI(dxbc::Dest::R(0, 0b1000), dxbc::Src::LU(31), dxbc::Src::LU(1), + dest_sample, dxbc::Src::R(0, dxbc::Src::kXXXX)); + a.OpXOr(dxbc::Dest::R(0, 0b1000), host_depth_source_sample, + dxbc::Src::LU(1 << 1)); + } else { + a.OpBFI(dxbc::Dest::R(0, 0b1000), dxbc::Src::LU(1), dxbc::Src::LU(0), + dxbc::Src::R(0, dxbc::Src::kXXXX), dest_sample); + } + a.OpUShR(dxbc::Dest::R(0, 0b0001), dxbc::Src::R(0, dxbc::Src::kXXXX), + dxbc::Src::LU(1)); + } else { + // 4x -> 1x. + // Pixels to samples. + a.OpAnd(dxbc::Dest::R(0, 0b1000), dxbc::Src::R(0, dxbc::Src::kXXXX), + dxbc::Src::LU(1)); + host_depth_source_sample = dxbc::Src::R(0, dxbc::Src::kWWWW); + a.OpBFI(dxbc::Dest::R(0, 0b1000), dxbc::Src::LU(1), dxbc::Src::LU(1), + dxbc::Src::R(0, dxbc::Src::kYYYY), host_depth_source_sample); + a.OpUShR(dxbc::Dest::R(0, 0b0011), dxbc::Src::R(0), dxbc::Src::LU(1)); + } + } else { + // 1x/2x -> 1x/2x/4x (as long as they're different). + // Only the X part - Y is handled by common code. + if (key.dest_msaa_samples >= xenos::MsaaSamples::k4X) { + // Horizontal samples to pixels. + a.OpBFI(dxbc::Dest::R(0, 0b0001), dxbc::Src::LU(31), dxbc::Src::LU(1), + dxbc::Src::R(0, dxbc::Src::kXXXX), dest_sample); + } + } + // Host depth source Y and sample index for 1x/2x AA sources. + if (key.host_depth_source_msaa_samples < xenos::MsaaSamples::k4X) { + if (key.dest_msaa_samples >= xenos::MsaaSamples::k4X) { + // 1x/2x -> 4x. + if (key.host_depth_source_msaa_samples == xenos::MsaaSamples::k2X) { + // 2x -> 4x. + // Vertical samples (second bit) of 4x destination to + // vertical sample (1, 0 for native 2x, or 0, 3 for 2x as + // 4x) of 2x source. + a.OpUShR(dxbc::Dest::R(0, 0b1000), dest_sample, dxbc::Src::LU(1)); + host_depth_source_sample = dxbc::Src::R(0, dxbc::Src::kWWWW); + if (msaa_2x_supported_) { + a.OpXOr(dxbc::Dest::R(0, 0b1000), host_depth_source_sample, + dxbc::Src::LU(1)); + } else { + a.OpBFI(dxbc::Dest::R(0, 0b1000), dxbc::Src::LU(1), dxbc::Src::LU(1), + host_depth_source_sample, host_depth_source_sample); + } + } else { + // 1x -> 4x. + // Vertical samples (second bit) to Y pixels, using r0.w + // (not needed without source MSAA) as a temporary. + a.OpUShR(dxbc::Dest::R(0, 0b1000), dest_sample, dxbc::Src::LU(1)); + a.OpBFI(dxbc::Dest::R(0, 0b0010), dxbc::Src::LU(31), dxbc::Src::LU(1), + dxbc::Src::R(0, dxbc::Src::kYYYY), dxbc::Src::R(0, dxbc::Src::kWWWW)); + } + } else { + // 1x/2x -> different 1x/2x. + if (key.host_depth_source_msaa_samples == xenos::MsaaSamples::k2X) { + // 2x -> 1x. + // Vertical pixels of 2x destination to vertical samples + // (1, 0 for native 2x, or 0, 3 for 2x as 4x) of 1x + // source. + a.OpAnd(dxbc::Dest::R(0, 0b1000), dxbc::Src::R(0, dxbc::Src::kYYYY), + dxbc::Src::LU(1)); + host_depth_source_sample = dxbc::Src::R(0, dxbc::Src::kWWWW); + if (msaa_2x_supported_) { + a.OpXOr(dxbc::Dest::R(0, 0b1000), host_depth_source_sample, + dxbc::Src::LU(1)); + } else { + a.OpBFI(dxbc::Dest::R(0, 0b1000), dxbc::Src::LU(1), dxbc::Src::LU(1), + host_depth_source_sample, host_depth_source_sample); + } + a.OpUShR(dxbc::Dest::R(0, 0b0010), dxbc::Src::R(0, dxbc::Src::kYYYY), + dxbc::Src::LU(1)); + } else { + // 1x -> 2x. + // Vertical samples (1, 0 in the first bit for native 2x + // or 0, 1 in the second bit for 2x as 4x) of 2x + // destination to vertical pixels of 1x source. + // Using r0.w (not needed without source MSAA) as a + // temporary. + if (msaa_2x_supported_) { + a.OpBFI(dxbc::Dest::R(0, 0b0010), dxbc::Src::LU(31), dxbc::Src::LU(1), + dxbc::Src::R(0, dxbc::Src::kYYYY), dest_sample); + a.OpXOr(dxbc::Dest::R(0, 0b0010), dxbc::Src::R(0, dxbc::Src::kYYYY), + dxbc::Src::LU(1)); + } else { + a.OpUShR(dxbc::Dest::R(0, 0b1000), dest_sample, dxbc::Src::LU(1)); + a.OpBFI(dxbc::Dest::R(0, 0b0010), dxbc::Src::LU(31), dxbc::Src::LU(1), + dxbc::Src::R(0, dxbc::Src::kYYYY), + dxbc::Src::R(0, dxbc::Src::kWWWW)); + } + } + } + } + } + // r1.x = host depth source pitch in tiles + a.OpUBFE(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(xenos::kEdramPitchTilesBits), + dxbc::Src::LU(xenos::kEdramPitchTilesBits), + dxbc::Src::CB(cbuffer_index_host_depth_address, + kTransferCBVRegisterHostDepthAddress, 0, dxbc::Src::kXXXX)); + // r0.z = host depth source tile row + // r1.x = host depth source tile within the row + a.OpUDiv(dxbc::Dest::R(0, 0b0100), dxbc::Dest::R(1, 0b0001), + dxbc::Src::R(0, dxbc::Src::kZZZZ), dxbc::Src::R(1, dxbc::Src::kXXXX)); + // r0.x = pixel X within the host depth source texture + // r1.x = free + a.OpUMAd( + dxbc::Dest::R(0, 0b0001), + dxbc::Src::LU(tile_width_samples >> uint32_t(key.host_depth_source_msaa_samples >= + xenos::MsaaSamples::k4X)), + dxbc::Src::R(1, dxbc::Src::kXXXX), dxbc::Src::R(0, dxbc::Src::kXXXX)); + // r0.y = pixel Y within the host depth source texture + // r0.z = free + a.OpUMAd(dxbc::Dest::R(0, 0b0010), + dxbc::Src::LU( + tile_height_samples >> + uint32_t(key.host_depth_source_msaa_samples >= xenos::MsaaSamples::k2X)), + dxbc::Src::R(0, dxbc::Src::kZZZZ), dxbc::Src::R(0, dxbc::Src::kYYYY)); + // Load from the host depth texture. + if (key.host_depth_source_msaa_samples != xenos::MsaaSamples::k1X) { + a.OpLdMS(dxbc::Dest::R(0, 0b0001), dxbc::Src::R(0), 0b0011, + dxbc::Src::T(srv_index_host_depth, kTransferSRVRegisterHostDepth, + dxbc::Src::kXXXX), + host_depth_source_sample); + } else { + // Write zero to the LOD index in r0.z. + a.OpMov(dxbc::Dest::R(0, 0b0100), dxbc::Src::LU(0)); + a.OpLd(dxbc::Dest::R(0, 0b0001), dxbc::Src::R(0, 0b10000100), 0b1011, + dxbc::Src::T(srv_index_host_depth, kTransferSRVRegisterHostDepth, + dxbc::Src::kXXXX)); + } + } + // Convert the host depth value in r0.x to the guest format in r0.y + // using r0.z as a temporary and check if it matches the value in + // the currently owning guest render target. + switch (dest_depth_format) { + case xenos::DepthRenderTargetFormat::kD24S8: { + // Round to the nearest even integer. This seems to be the + // correct, adding +0.5 and rounding towards zero results in red + // instead of black in the 4D5307E6 clear shader. + a.OpMul(dxbc::Dest::R(0, 0b0010), dxbc::Src::R(0, dxbc::Src::kXXXX), + dxbc::Src::LF(float(0xFFFFFF))); + a.OpRoundNE(dxbc::Dest::R(0, 0b0010), dxbc::Src::R(0, dxbc::Src::kYYYY)); + a.OpFToU(dxbc::Dest::R(0, 0b0010), dxbc::Src::R(0, dxbc::Src::kYYYY)); + } break; + case xenos::DepthRenderTargetFormat::kD24FS8: { + // When converting the depth in pixel shaders, it's always + // exact, truncating not to insert additional rounding + // instructions. + DxbcShaderTranslator::PreClampedDepthTo20e4( + a, 0, 1, 0, 0, 0, 2, + !depth_float24_convert_in_pixel_shader() && depth_float24_round(), true); + } break; + } + a.OpIEq(dxbc::Dest::R(0, 0b0010), dxbc::Src::R(0, dxbc::Src::kYYYY), + dxbc::Src::R(1, dxbc::Src::kWWWW)); + a.OpIf(true, dxbc::Src::R(0, dxbc::Src::kYYYY)); + // If the host depth is up to date, write it to oDepth at the host + // precision instead of converting the guest depth. + a.OpMov(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(0, dxbc::Src::kXXXX)); + a.OpElse(); + } + // Convert using r0.x as a temporary. + switch (dest_depth_format) { + case xenos::DepthRenderTargetFormat::kD24S8: { + // Multiplying by 1.0 / 0xFFFFFF produces an incorrect result (for + // 0xC00000, for instance - which is 2_10_10_10 clear to 0001) - + // rescale from 0...0xFFFFFF to 0...0x1000000 doing what true + // float division followed by multiplication does (on x86-64 MSVC + // with default SSE rounding) - values starting from 0x800000 + // become bigger by 1; then accurately bias the result's exponent. + a.OpUShR(dxbc::Dest::R(0, 0b0001), dxbc::Src::R(1, dxbc::Src::kWWWW), + dxbc::Src::LU(23)); + a.OpIAdd(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(1, dxbc::Src::kWWWW), + dxbc::Src::R(0, dxbc::Src::kXXXX)); + a.OpUToF(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(1, dxbc::Src::kWWWW)); + a.OpMul(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(1, dxbc::Src::kWWWW), + dxbc::Src::LF(1.0f / float(1 << 24))); + } break; + case xenos::DepthRenderTargetFormat::kD24FS8: { + DxbcShaderTranslator::Depth20e4To32(a, dxbc::Dest::R(1, 0b1000), 1, 3, 0, 1, 3, 0, 0, + true); + } break; + } + // Host depth is different, or not available - convert the guest depth + // to the destination format. + if (rs & kTransferUsedRootParameterHostDepthSRVBit) { + // Close the conditional for the host / guest depth. + a.OpEndIf(); + } + } + a.OpMov(dxbc::Dest::ODepth(), dxbc::Src::R(1, dxbc::Src::kWWWW)); + break; + case TransferOutput::kStencilBit: + // Discard the sample if the needed stencil bit is not set. + assert_true(cbuffer_index_stencil_mask != UINT32_MAX); + a.OpAnd(dxbc::Dest::R(0, 0b0001), dxbc::Src::R(1, dxbc::Src::kXXXX), + dxbc::Src::CB(cbuffer_index_stencil_mask, kTransferCBVRegisterStencilMask, 0, + dxbc::Src::kXXXX)); + a.OpDiscard(false, dxbc::Src::R(0, dxbc::Src::kXXXX)); + break; + } + } + + if (dest_is_color) { + // Fill the unused components of the color result. + uint32_t dest_color_component_count = + xenos::GetColorRenderTargetFormatComponentCount(dest_color_format); + uint32_t dest_color_unwritten_mask = 0b1111 & ~uint32_t((1 << dest_color_component_count) - 1); + if (dest_color_component_count < 4) { + a.OpMov(dxbc::Dest::O(0, dest_color_unwritten_mask), dxbc::Src::LU(0)); + } + } + + a.OpRet(); + + // Write the shader program length in dwords. + built_shader_[shex_position_dwords + 1] = uint32_t(built_shader_.size()) - shex_position_dwords; + + { + auto& blob_header = + *reinterpret_cast(built_shader_.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kShaderEx; + blob_position_dwords = uint32_t(built_shader_.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + built_shader_[blob_offset_position_dwords++]; + } + + // *************************************************************************** + // Shader feature info + // *************************************************************************** + + if (shader_uses_stencil_reference_output) { + built_shader_[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + uint32_t sfi0_position_dwords = blob_position_dwords + kBlobHeaderSizeDwords; + built_shader_.resize(sfi0_position_dwords + sizeof(dxbc::ShaderFeatureInfo) / sizeof(uint32_t)); + auto& shader_feature_info = + *reinterpret_cast(built_shader_.data() + sfi0_position_dwords); + shader_feature_info.feature_flags[0] |= dxbc::kShaderFeature0_StencilRef; + { + auto& blob_header = + *reinterpret_cast(built_shader_.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kShaderFeatureInfo; + blob_position_dwords = uint32_t(built_shader_.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + built_shader_[blob_offset_position_dwords++]; + } + } + + // *************************************************************************** + // Statistics + // *************************************************************************** + + built_shader_[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + uint32_t stat_position_dwords = blob_position_dwords + kBlobHeaderSizeDwords; + built_shader_.resize(stat_position_dwords + sizeof(dxbc::Statistics) / sizeof(uint32_t)); + std::memcpy(built_shader_.data() + stat_position_dwords, &stat, sizeof(dxbc::Statistics)); + { + auto& blob_header = + *reinterpret_cast(built_shader_.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kStatistics; + blob_position_dwords = uint32_t(built_shader_.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + built_shader_[blob_offset_position_dwords++]; + } + + // *************************************************************************** + // Container header + // *************************************************************************** + + uint32_t built_shader_size_bytes = uint32_t(built_shader_.size() * sizeof(uint32_t)); + { + auto& container_header = *reinterpret_cast(built_shader_.data()); + container_header.InitializeIdentification(); + container_header.size_bytes = built_shader_size_bytes; + container_header.blob_count = blob_count; + CalculateDXBCChecksum(reinterpret_cast(built_shader_.data()), + static_cast(built_shader_size_bytes), + reinterpret_cast(&container_header.hash)); + } + + // *************************************************************************** + // Pipeline + // *************************************************************************** + + ID3D12PipelineState* const* pipelines; + ID3D12Device* device = command_processor_.GetD3D12Provider().GetDevice(); + D3D12_INPUT_ELEMENT_DESC pipeline_input_element_desc; + pipeline_input_element_desc.SemanticName = "POSITION"; + pipeline_input_element_desc.SemanticIndex = 0; + pipeline_input_element_desc.Format = DXGI_FORMAT_R32G32_FLOAT; + pipeline_input_element_desc.InputSlot = 0; + pipeline_input_element_desc.AlignedByteOffset = 0; + pipeline_input_element_desc.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA; + pipeline_input_element_desc.InstanceDataStepRate = 0; + D3D12_GRAPHICS_PIPELINE_STATE_DESC pipeline_desc = {}; + pipeline_desc.pRootSignature = transfer_root_signatures_[size_t( + use_stencil_reference_output_ ? mode.root_signature_with_stencil_ref + : mode.root_signature_no_stencil_ref)]; + pipeline_desc.VS.pShaderBytecode = shaders::passthrough_position_xy_vs; + pipeline_desc.VS.BytecodeLength = sizeof(shaders::passthrough_position_xy_vs); + pipeline_desc.PS.pShaderBytecode = built_shader_.data(); + pipeline_desc.PS.BytecodeLength = built_shader_size_bytes; + if (key.dest_msaa_samples == xenos::MsaaSamples::k2X && !msaa_2x_supported_) { + // Using sample 0 as 0 and 3 as 1 for 2x instead. + pipeline_desc.SampleMask = 0b1001; + pipeline_desc.SampleDesc.Count = 4; + } else { + pipeline_desc.SampleMask = UINT_MAX; + pipeline_desc.SampleDesc.Count = UINT(1) << UINT(key.dest_msaa_samples); + } + pipeline_desc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; + pipeline_desc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; + pipeline_desc.RasterizerState.DepthClipEnable = TRUE; + pipeline_desc.InputLayout.pInputElementDescs = &pipeline_input_element_desc; + pipeline_desc.InputLayout.NumElements = 1; + pipeline_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + if (dest_is_stencil_bit) { + pipeline_desc.DepthStencilState.StencilEnable = TRUE; + pipeline_desc.DepthStencilState.FrontFace.StencilFailOp = D3D12_STENCIL_OP_KEEP; + pipeline_desc.DepthStencilState.FrontFace.StencilDepthFailOp = D3D12_STENCIL_OP_KEEP; + pipeline_desc.DepthStencilState.FrontFace.StencilPassOp = D3D12_STENCIL_OP_REPLACE; + pipeline_desc.DepthStencilState.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS; + pipeline_desc.DepthStencilState.BackFace = pipeline_desc.DepthStencilState.FrontFace; + pipeline_desc.DSVFormat = GetDepthDSVDXGIFormat(dest_depth_format); + // Even if creation fails, still store the null pointers not to try to + // create again. + std::array& stencil_bit_pipelines = + transfer_stencil_bit_pipelines_ + .emplace(std::piecewise_construct, std::make_tuple(key), std::make_tuple()) + .first->second; + bool stencil_pipelines_created = true; + for (uint32_t i = 0; i < 8; ++i) { + pipeline_desc.DepthStencilState.StencilWriteMask = UINT8(1) << i; + if (SUCCEEDED(device->CreateGraphicsPipelineState(&pipeline_desc, + IID_PPV_ARGS(&stencil_bit_pipelines[i])))) { + continue; + } + stencil_pipelines_created = false; + for (uint32_t j = 0; j < i; ++j) { + stencil_bit_pipelines[j]->Release(); + stencil_bit_pipelines[j] = nullptr; + } + break; + } + pipelines = stencil_pipelines_created ? stencil_bit_pipelines.data() : nullptr; + } else { + if (dest_is_color) { + pipeline_desc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + pipeline_desc.NumRenderTargets = 1; + pipeline_desc.RTVFormats[0] = GetColorOwnershipTransferDXGIFormat(dest_color_format); + } else { + pipeline_desc.DepthStencilState.DepthEnable = TRUE; + pipeline_desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + pipeline_desc.DepthStencilState.DepthFunc = REXCVAR_GET(depth_transfer_not_equal_test) + ? D3D12_COMPARISON_FUNC_NOT_EQUAL + : D3D12_COMPARISON_FUNC_ALWAYS; + if (use_stencil_reference_output_) { + pipeline_desc.DepthStencilState.StencilEnable = TRUE; + pipeline_desc.DepthStencilState.StencilWriteMask = UINT8_MAX; + pipeline_desc.DepthStencilState.FrontFace.StencilFailOp = D3D12_STENCIL_OP_KEEP; + pipeline_desc.DepthStencilState.FrontFace.StencilDepthFailOp = + REXCVAR_GET(depth_transfer_not_equal_test) ? D3D12_STENCIL_OP_REPLACE + : D3D12_STENCIL_OP_KEEP; + pipeline_desc.DepthStencilState.FrontFace.StencilPassOp = D3D12_STENCIL_OP_REPLACE; + // Using ALWAYS, not NOT_EQUAL, so depth writing is unaffected by + // stencil being different. + pipeline_desc.DepthStencilState.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS; + pipeline_desc.DepthStencilState.BackFace = pipeline_desc.DepthStencilState.FrontFace; + } + pipeline_desc.DSVFormat = GetDepthDSVDXGIFormat(dest_depth_format); + } + ID3D12PipelineState* pipeline; + if (FAILED(device->CreateGraphicsPipelineState(&pipeline_desc, IID_PPV_ARGS(&pipeline)))) { + pipeline = nullptr; + } + // Even if creation fails, still store the null pointer not to try to create + // again. + // Return a pointer to the persistent location. + ID3D12PipelineState*& inserted_pipeline = + transfer_pipelines_.emplace(key, pipeline).first->second; + pipelines = inserted_pipeline ? &inserted_pipeline : nullptr; + } + // TODO(Triang3l): Pipeline state name debug names (lots of variables - but + // not very important since everything can be derived from the bindings and + // outputs in a debugger). + + if (!pipelines) { + // Stencil bit copying uses only the stencil SRV for depth / stencil source, + // can't use srv_index_depth for checking. + const char* source_format_name = + (rs & kTransferUsedRootParameterColorSRVBit) + ? xenos::GetColorRenderTargetFormatName(source_color_format) + : xenos::GetDepthRenderTargetFormatName(source_depth_format); + const char* dest_format_name = mode.output == TransferOutput::kColor + ? xenos::GetColorRenderTargetFormatName(dest_color_format) + : xenos::GetDepthRenderTargetFormatName(dest_depth_format); + if (srv_index_host_depth != UINT32_MAX) { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to create a render target ownership " + "transfer pipeline for {}-sample {} + {}-sample host depth{} -> " + "{}-sample {} for mode {}", + uint32_t(1) << uint32_t(key.source_msaa_samples), source_format_name, + uint32_t(1) << uint32_t(key.host_depth_source_msaa_samples), + key.host_depth_source_is_copy ? " copy" : "", + uint32_t(1) << uint32_t(key.dest_msaa_samples), dest_format_name, uint32_t(key.mode)); + } else { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to create a render target ownership " + "transfer pipeline for {}-sample {} -> {}-sample {} for mode {}", + uint32_t(1) << uint32_t(key.source_msaa_samples), source_format_name, + uint32_t(1) << uint32_t(key.dest_msaa_samples), dest_format_name, uint32_t(key.mode)); + } + } + return pipelines; +} + +void D3D12RenderTargetCache::PerformTransfersAndResolveClears( + uint32_t render_target_count, RenderTarget* const* render_targets, + const std::vector* render_target_transfers, + const uint64_t* render_target_resolve_clear_values, + const Transfer::Rectangle* resolve_clear_rectangle) { + assert_true(GetPath() == Path::kHostRenderTargets); + + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + uint64_t current_submission = command_processor_.GetCurrentSubmission(); + DeferredCommandList& command_list = command_processor_.GetDeferredCommandList(); + + bool resolve_clear_needed = render_target_resolve_clear_values && resolve_clear_rectangle; + D3D12_RECT clear_rect; + if (resolve_clear_needed) { + // Assuming the rectangle is already clamped by the setup function from the + // common render target cache. + clear_rect.left = LONG(resolve_clear_rectangle->x_pixels * draw_resolution_scale_x()); + clear_rect.top = LONG(resolve_clear_rectangle->y_pixels * draw_resolution_scale_y()); + clear_rect.right = + LONG((resolve_clear_rectangle->x_pixels + resolve_clear_rectangle->width_pixels) * + draw_resolution_scale_x()); + clear_rect.bottom = + LONG((resolve_clear_rectangle->y_pixels + resolve_clear_rectangle->height_pixels) * + draw_resolution_scale_y()); + } + + // Do host depth storing for the depth destination (assuming there can be only + // one depth destination) where depth destination == host depth source. + bool host_depth_store_set_up = false; + for (uint32_t i = 0; i < render_target_count; ++i) { + RenderTarget* dest_rt = render_targets[i]; + if (!dest_rt) { + continue; + } + auto& dest_d3d12_rt = *static_cast(dest_rt); + RenderTargetKey dest_rt_key = dest_d3d12_rt.key(); + if (!dest_rt_key.is_depth) { + continue; + } + const std::vector& depth_transfers = render_target_transfers[i]; + for (const Transfer& transfer : depth_transfers) { + if (transfer.host_depth_source != dest_rt) { + continue; + } + if (!host_depth_store_set_up) { + // Bindings. + // 0 - source. + // 1 - EDRAM if bindful. + ui::d3d12::util::DescriptorCpuGpuHandlePair host_depth_store_descriptors[2]; + if (!command_processor_.RequestOneUseSingleViewDescriptors( + 1 + uint32_t(!bindless_resources_used_), host_depth_store_descriptors)) { + continue; + } + command_list.D3DSetComputeRootSignature(host_depth_store_root_signature_); + // Destination (EDRAM uint4 buffer). + if (bindless_resources_used_) { + command_list.D3DSetComputeRootDescriptorTable( + kHostDepthStoreRootParameterDest, + command_processor_.GetEdramUintPow2BindlessUAVHandlePair(4).second); + } else { + const ui::d3d12::util::DescriptorCpuGpuHandlePair& host_depth_store_descriptor_dest = + host_depth_store_descriptors[1]; + WriteEdramUintPow2UAVDescriptor(host_depth_store_descriptor_dest.first, 4); + command_list.D3DSetComputeRootDescriptorTable(kHostDepthStoreRootParameterDest, + host_depth_store_descriptor_dest.second); + } + // Depth source texture. + const ui::d3d12::util::DescriptorCpuGpuHandlePair& host_depth_store_descriptor_source = + host_depth_store_descriptors[0]; + device->CopyDescriptorsSimple(1, host_depth_store_descriptor_source.first, + dest_d3d12_rt.descriptor_srv().GetHandle(), + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + command_list.D3DSetComputeRootDescriptorTable(kHostDepthStoreRootParameterSource, + host_depth_store_descriptor_source.second); + // Render target constant. + HostDepthStoreRenderTargetConstant host_depth_store_render_target_constant = + GetHostDepthStoreRenderTargetConstant(dest_rt_key.pitch_tiles_at_32bpp, + msaa_2x_supported_); + command_list.D3DSetComputeRoot32BitConstants( + kHostDepthStoreRootParameterConstants, + sizeof(host_depth_store_render_target_constant) / sizeof(uint32_t), + &host_depth_store_render_target_constant, + offsetof(HostDepthStoreConstants, render_target) / sizeof(uint32_t)); + // Barriers - don't need to try to combine them with the rest of + // render target transfer barriers now - if this happens, after host + // depth storing, NON_PIXEL_SHADER_RESOURCE -> DEPTH_WRITE will be done + // anyway even in the best case, so it's not possible to have all the + // barriers in one place here. + TransitionEdramBuffer(D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + command_processor_.PushTransitionBarrier( + dest_d3d12_rt.resource(), + dest_d3d12_rt.SetResourceState(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE), + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + // Pipeline. + command_processor_.SetExternalPipeline( + host_depth_store_pipelines_[size_t(dest_rt_key.msaa_samples)]); + host_depth_store_set_up = true; + } + Transfer::Rectangle transfer_rectangles[Transfer::kMaxRectanglesWithCutout]; + uint32_t transfer_rectangle_count = transfer.GetRectangles( + dest_rt_key.base_tiles, dest_rt_key.pitch_tiles_at_32bpp, dest_rt_key.msaa_samples, false, + transfer_rectangles, resolve_clear_rectangle); + assert_not_zero(transfer_rectangle_count); + HostDepthStoreRectangleConstant host_depth_store_rectangle_constant; + for (uint32_t j = 0; j < transfer_rectangle_count; ++j) { + uint32_t group_count_x, group_count_y; + GetHostDepthStoreRectangleInfo(transfer_rectangles[j], dest_rt_key.msaa_samples, + host_depth_store_rectangle_constant, group_count_x, + group_count_y); + command_list.D3DSetComputeRoot32BitConstants( + kHostDepthStoreRootParameterConstants, + sizeof(host_depth_store_rectangle_constant) / sizeof(uint32_t), + &host_depth_store_rectangle_constant, + offsetof(HostDepthStoreConstants, rectangle) / sizeof(uint32_t)); + command_processor_.SubmitBarriers(); + command_list.D3DDispatch(group_count_x, group_count_y, 1); + MarkEdramBufferModified(); + } + } + break; + } + + // Try to insert as many barriers as possible in one place, hoping that in the + // best case (no cross-copying between current render targets), barriers will + // need to be only inserted here, not between transfers. In case of + // cross-copying, if the destination use is going to happen before the source + // use, choose the destination state, otherwise the source state - to match + // the order in which transfers will actually happen (otherwise there will be + // just a useless switch back and forth). + for (uint32_t i = 0; i < render_target_count; ++i) { + RenderTarget* dest_rt = render_targets[i]; + if (!dest_rt) { + continue; + } + auto& dest_d3d12_rt = *static_cast(dest_rt); + const std::vector& dest_transfers = render_target_transfers[i]; + if (!resolve_clear_needed && dest_transfers.empty()) { + continue; + } + // Transition the sources, only if not going to be used as destinations + // earlier. + for (const Transfer& transfer : render_target_transfers[i]) { + bool source_previously_used_as_dest = false; + bool host_depth_source_previously_used_as_dest = false; + for (uint32_t j = 0; j < i; ++j) { + if (render_target_transfers[j].empty()) { + continue; + } + const RenderTarget* previous_rt = render_targets[j]; + if (transfer.source == previous_rt) { + source_previously_used_as_dest = true; + } + if (transfer.host_depth_source == previous_rt) { + host_depth_source_previously_used_as_dest = true; + } + } + if (!source_previously_used_as_dest) { + auto& source_d3d12_rt = *static_cast(transfer.source); + command_processor_.PushTransitionBarrier( + source_d3d12_rt.resource(), + source_d3d12_rt.SetResourceState(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE), + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + } + // transfer.host_depth_source == dest_rt means the EDRAM buffer will be + // used instead, no need to transition. + if (transfer.host_depth_source && transfer.host_depth_source != dest_rt && + !host_depth_source_previously_used_as_dest) { + auto& host_depth_source_d3d12_rt = + *static_cast(transfer.host_depth_source); + command_processor_.PushTransitionBarrier( + host_depth_source_d3d12_rt.resource(), + host_depth_source_d3d12_rt.SetResourceState(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE), + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + } + } + // Transition the destination, only if not going to be used as a source + // earlier. + bool dest_used_previously_as_source = false; + for (uint32_t j = 0; j < i; ++j) { + for (const Transfer& previous_transfer : render_target_transfers[j]) { + if (previous_transfer.source == dest_rt || previous_transfer.host_depth_source == dest_rt) { + dest_used_previously_as_source = true; + break; + } + } + } + if (!dest_used_previously_as_source) { + D3D12_RESOURCE_STATES dest_state = dest_d3d12_rt.key().is_depth + ? D3D12_RESOURCE_STATE_DEPTH_WRITE + : D3D12_RESOURCE_STATE_RENDER_TARGET; + command_processor_.PushTransitionBarrier( + dest_d3d12_rt.resource(), dest_d3d12_rt.SetResourceState(dest_state), dest_state); + } + } + if (host_depth_store_set_up) { + // Will be reading copied host depth from the EDRAM buffer. + TransitionEdramBuffer(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + } + + // Copy source descriptors to the shader-visible heap. + // Clear previously set shader-visible descriptor indices. + for (uint32_t i = 0; i < render_target_count; ++i) { + RenderTarget* dest_rt = render_targets[i]; + if (!dest_rt) { + continue; + } + for (const Transfer& transfer : render_target_transfers[i]) { + assert_not_null(transfer.source); + auto& source_d3d12_rt = *static_cast(transfer.source); + source_d3d12_rt.SetTemporarySRVDescriptorIndex(UINT32_MAX); + source_d3d12_rt.SetTemporarySRVDescriptorIndexStencil(UINT32_MAX); + auto* host_depth_source_d3d12_rt = + static_cast(transfer.host_depth_source); + if (host_depth_source_d3d12_rt) { + host_depth_source_d3d12_rt->SetTemporarySRVDescriptorIndex(UINT32_MAX); + host_depth_source_d3d12_rt->SetTemporarySRVDescriptorIndexStencil(UINT32_MAX); + } + } + } + current_temporary_descriptors_cpu_.clear(); + uint32_t host_depth_copy_srv_index; + if (host_depth_store_set_up && !bindless_resources_used_) { + host_depth_copy_srv_index = uint32_t(current_temporary_descriptors_cpu_.size()); + current_temporary_descriptors_cpu_.push_back(provider.OffsetViewDescriptor( + edram_buffer_descriptor_heap_start_, uint32_t(EdramBufferDescriptorIndex::kR32UintSRV))); + } else { + host_depth_copy_srv_index = UINT32_MAX; + } + for (uint32_t i = 0; i < render_target_count; ++i) { + RenderTarget* dest_rt = render_targets[i]; + if (!dest_rt) { + continue; + } + bool dest_is_depth = dest_rt->key().is_depth; + for (const Transfer& transfer : render_target_transfers[i]) { + assert_not_null(transfer.source); + auto& source_d3d12_rt = *static_cast(transfer.source); + if (source_d3d12_rt.temporary_srv_descriptor_index() == UINT32_MAX) { + source_d3d12_rt.SetTemporarySRVDescriptorIndex( + uint32_t(current_temporary_descriptors_cpu_.size())); + current_temporary_descriptors_cpu_.push_back(source_d3d12_rt.descriptor_srv().GetHandle()); + } + if (source_d3d12_rt.key().is_depth && + source_d3d12_rt.temporary_srv_descriptor_index_stencil() == UINT32_MAX) { + source_d3d12_rt.SetTemporarySRVDescriptorIndexStencil( + uint32_t(current_temporary_descriptors_cpu_.size())); + current_temporary_descriptors_cpu_.push_back( + source_d3d12_rt.descriptor_srv_stencil().GetHandle()); + } + bool source_is_depth = source_d3d12_rt.key().is_depth; + auto* host_depth_source_d3d12_rt = + static_cast(transfer.host_depth_source); + // The host_depth_source_d3d12_rt == dest_rt case would use the EDRAM + // buffer instead. + if (host_depth_source_d3d12_rt && host_depth_source_d3d12_rt != dest_rt && + host_depth_source_d3d12_rt->temporary_srv_descriptor_index() == UINT32_MAX) { + host_depth_source_d3d12_rt->SetTemporarySRVDescriptorIndex( + uint32_t(current_temporary_descriptors_cpu_.size())); + current_temporary_descriptors_cpu_.push_back( + host_depth_source_d3d12_rt->descriptor_srv().GetHandle()); + } + } + } + uint32_t descriptor_count = uint32_t(current_temporary_descriptors_cpu_.size()); + current_temporary_descriptors_gpu_.resize(descriptor_count); + if (!command_processor_.RequestOneUseSingleViewDescriptors( + descriptor_count, current_temporary_descriptors_gpu_.data())) { + return; + } + for (uint32_t i = 0; i < descriptor_count; ++i) { + device->CopyDescriptorsSimple(1, current_temporary_descriptors_gpu_[i].first, + current_temporary_descriptors_cpu_[i], + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + } + + // Perform the transfers and clears. + + bool transfer_viewport_set = false; + float pixels_to_ndc_unscaled = 2.0f / float(D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION); + float pixels_to_ndc_x = pixels_to_ndc_unscaled * draw_resolution_scale_x(); + float pixels_to_ndc_y = pixels_to_ndc_unscaled * draw_resolution_scale_y(); + + TransferRootSignatureIndex last_transfer_root_signature_index = + TransferRootSignatureIndex::kCount; + uint32_t transfer_root_parameters_set = 0; + uint32_t last_descriptor_index_color = UINT32_MAX; + uint32_t last_descriptor_index_depth = UINT32_MAX; + uint32_t last_descriptor_index_stencil = UINT32_MAX; + uint32_t last_descriptor_index_host_depth_non_copy = UINT32_MAX; + bool last_descriptor_host_depth_is_copy = false; + TransferAddressConstant last_address_constant; + TransferAddressConstant last_host_depth_address_constant; + + for (uint32_t i = 0; i < render_target_count; ++i) { + RenderTarget* dest_rt = render_targets[i]; + if (!dest_rt) { + continue; + } + + const std::vector& current_transfers = render_target_transfers[i]; + if (current_transfers.empty() && !resolve_clear_needed) { + continue; + } + + auto& dest_d3d12_rt = *static_cast(dest_rt); + RenderTargetKey dest_rt_key = dest_d3d12_rt.key(); + + // Late barrier in case there was cross-copying that prevented merging of + // barriers. + D3D12_RESOURCE_STATES dest_state = dest_rt_key.is_depth ? D3D12_RESOURCE_STATE_DEPTH_WRITE + : D3D12_RESOURCE_STATE_RENDER_TARGET; + command_processor_.PushTransitionBarrier( + dest_d3d12_rt.resource(), dest_d3d12_rt.SetResourceState(dest_state), dest_state); + + if (!current_transfers.empty()) { + are_current_command_list_render_targets_valid_ = false; + if (dest_rt_key.is_depth) { + D3D12_CPU_DESCRIPTOR_HANDLE dsv_handle = dest_d3d12_rt.descriptor_draw().GetHandle(); + command_list.D3DOMSetRenderTargets(0, nullptr, FALSE, &dsv_handle); + if (!use_stencil_reference_output_) { + command_processor_.SetStencilReference(UINT8_MAX); + } + } else { + D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle = + dest_d3d12_rt.descriptor_load_separate().IsValid() + ? dest_d3d12_rt.descriptor_load_separate().GetHandle() + : dest_d3d12_rt.descriptor_draw().GetHandle(); + command_list.D3DOMSetRenderTargets(1, &rtv_handle, FALSE, nullptr); + } + + uint32_t dest_pitch_tiles = dest_rt_key.GetPitchTiles(); + bool dest_is_64bpp = dest_rt_key.Is64bpp(); + + // Gather shader keys and sort to reduce pipeline state and binding + // switches. Also gather stencil rectangles to clear if needed. + bool need_stencil_bit_draws = dest_rt_key.is_depth && !use_stencil_reference_output_; + current_transfer_invocations_.clear(); + current_transfer_invocations_.reserve(current_transfers.size() + << uint32_t(need_stencil_bit_draws)); + uint32_t rt_sort_index = 0; + TransferShaderKey new_transfer_shader_key; + new_transfer_shader_key.dest_msaa_samples = dest_rt_key.msaa_samples; + new_transfer_shader_key.dest_resource_format = dest_rt_key.resource_format; + uint32_t stencil_clear_rectangle_count = 0; + for (uint32_t j = 0; j <= uint32_t(need_stencil_bit_draws); ++j) { + // j == 0 - color or depth. + // j == 1 - stencil bits. + // Stencil bit writing always requires a different root signature, + // handle these separately. Stencil never has a host depth source. + // Clear previously set sort indices. + for (const Transfer& transfer : current_transfers) { + auto* host_depth_source_d3d12_rt = + static_cast(transfer.host_depth_source); + if (host_depth_source_d3d12_rt) { + host_depth_source_d3d12_rt->SetTemporarySortIndex(UINT32_MAX); + } + assert_not_null(transfer.source); + auto& source_d3d12_rt = *static_cast(transfer.source); + source_d3d12_rt.SetTemporarySortIndex(UINT32_MAX); + } + for (const Transfer& transfer : current_transfers) { + assert_not_null(transfer.source); + auto& source_d3d12_rt = *static_cast(transfer.source); + D3D12RenderTarget* host_depth_source_d3d12_rt = + j ? nullptr : static_cast(transfer.host_depth_source); + if (host_depth_source_d3d12_rt && + host_depth_source_d3d12_rt->temporary_sort_index() == UINT32_MAX) { + host_depth_source_d3d12_rt->SetTemporarySortIndex(rt_sort_index++); + } + if (source_d3d12_rt.temporary_sort_index() == UINT32_MAX) { + source_d3d12_rt.SetTemporarySortIndex(rt_sort_index++); + } + RenderTargetKey source_rt_key = source_d3d12_rt.key(); + new_transfer_shader_key.source_msaa_samples = source_rt_key.msaa_samples; + new_transfer_shader_key.source_resource_format = source_rt_key.resource_format; + bool host_depth_source_is_copy = host_depth_source_d3d12_rt == &dest_d3d12_rt; + new_transfer_shader_key.host_depth_source_is_copy = host_depth_source_is_copy; + // The host depth copy buffer has only raw samples. + new_transfer_shader_key.host_depth_source_msaa_samples = + (host_depth_source_d3d12_rt && !host_depth_source_is_copy) + ? host_depth_source_d3d12_rt->key().msaa_samples + : xenos::MsaaSamples::k1X; + if (j) { + new_transfer_shader_key.mode = source_rt_key.is_depth + ? TransferMode::kDepthToStencilBit + : TransferMode::kColorToStencilBit; + stencil_clear_rectangle_count += transfer.GetRectangles( + dest_rt_key.base_tiles, dest_pitch_tiles, dest_rt_key.msaa_samples, dest_is_64bpp, + nullptr, resolve_clear_rectangle); + } else { + if (dest_rt_key.is_depth) { + if (host_depth_source_d3d12_rt) { + new_transfer_shader_key.mode = source_rt_key.is_depth + ? TransferMode::kDepthAndHostDepthToDepth + : TransferMode::kColorAndHostDepthToDepth; + } else { + new_transfer_shader_key.mode = source_rt_key.is_depth ? TransferMode::kDepthToDepth + : TransferMode::kColorToDepth; + } + } else { + new_transfer_shader_key.mode = source_rt_key.is_depth ? TransferMode::kDepthToColor + : TransferMode::kColorToColor; + } + } + current_transfer_invocations_.emplace_back(transfer, new_transfer_shader_key); + if (j) { + current_transfer_invocations_.back().transfer.host_depth_source = nullptr; + } + } + } + std::sort(current_transfer_invocations_.begin(), current_transfer_invocations_.end()); + + // Clear the stencil to 0 where it will be loaded - will be setting the + // bits that need to be 1 by discarding samples. Clearing everything here + // to reduce context switches internally in the driver if clear causes + // them. + if (stencil_clear_rectangle_count) { + command_processor_.SubmitBarriers(); + D3D12_RECT* stencil_clear_rect_write_ptr = command_list.ClearDepthStencilViewAllocatedRects( + dest_d3d12_rt.descriptor_draw().GetHandle(), D3D12_CLEAR_FLAG_STENCIL, 0.0f, 0, + stencil_clear_rectangle_count); + assert_not_null(stencil_clear_rect_write_ptr); + for (const Transfer& transfer : current_transfers) { + Transfer::Rectangle transfer_stencil_clear_rectangles[Transfer::kMaxRectanglesWithCutout]; + uint32_t transfer_stencil_clear_rectangle_count = transfer.GetRectangles( + dest_rt_key.base_tiles, dest_pitch_tiles, dest_rt_key.msaa_samples, dest_is_64bpp, + transfer_stencil_clear_rectangles, resolve_clear_rectangle); + for (uint32_t j = 0; j < transfer_stencil_clear_rectangle_count; ++j) { + const Transfer::Rectangle& stencil_clear_rectangle = + transfer_stencil_clear_rectangles[j]; + stencil_clear_rect_write_ptr->left = + LONG(stencil_clear_rectangle.x_pixels * draw_resolution_scale_x()); + stencil_clear_rect_write_ptr->top = + LONG(stencil_clear_rectangle.y_pixels * draw_resolution_scale_y()); + stencil_clear_rect_write_ptr->right = + LONG((stencil_clear_rectangle.x_pixels + stencil_clear_rectangle.width_pixels) * + draw_resolution_scale_x()); + stencil_clear_rect_write_ptr->bottom = + LONG((stencil_clear_rectangle.y_pixels + stencil_clear_rectangle.height_pixels) * + draw_resolution_scale_y()); + ++stencil_clear_rect_write_ptr; + } + } + } + + // Perform the transfers for the render target. + + if (!transfer_viewport_set) { + transfer_viewport_set = true; + // Will be passing NDC directly, set the viewport to the maximum host + // render target size for simplicity. Using a power-of-two scale for + // exact pixel coordinates. + D3D12_VIEWPORT transfer_viewport; + transfer_viewport.TopLeftX = 0.0f; + transfer_viewport.TopLeftY = 0.0f; + transfer_viewport.Width = float(D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION); + transfer_viewport.Height = float(D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION); + transfer_viewport.MinDepth = 0.0f; + transfer_viewport.MaxDepth = 1.0f; + command_processor_.SetViewport(transfer_viewport); + // TODO(Triang3l): Reduce scissor to the smallest transfer region for + // more tiling friendliness. + D3D12_RECT transfer_scissor; + transfer_scissor.left = 0; + transfer_scissor.top = 0; + transfer_scissor.right = LONG(D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION); + transfer_scissor.bottom = LONG(D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION); + command_processor_.SetScissorRect(transfer_scissor); + } + + for (auto it = current_transfer_invocations_.cbegin(); + it != current_transfer_invocations_.cend(); ++it) { + const TransferInvocation& transfer_invocation_first = *it; + // Will be merging transfers from the same source into one mesh. + auto it_merged_first = it, it_merged_last = it; + uint32_t transfer_rectangle_count = transfer_invocation_first.transfer.GetRectangles( + dest_rt_key.base_tiles, dest_pitch_tiles, dest_rt_key.msaa_samples, dest_is_64bpp, + nullptr, resolve_clear_rectangle); + for (auto it_merge = std::next(it_merged_first); + it_merge != current_transfer_invocations_.cend(); ++it_merge) { + if (!transfer_invocation_first.CanBeMergedIntoOneDraw(*it_merge)) { + break; + } + transfer_rectangle_count += it_merge->transfer.GetRectangles( + dest_rt_key.base_tiles, dest_pitch_tiles, dest_rt_key.msaa_samples, dest_is_64bpp, + nullptr, resolve_clear_rectangle); + it_merged_last = it_merge; + } + assert_not_zero(transfer_rectangle_count); + // Skip the merged transfers in the subsequent iterations. + it = it_merged_last; + + assert_not_null(it->transfer.source); + auto& source_d3d12_rt = *static_cast(it->transfer.source); + auto* host_depth_source_d3d12_rt = + static_cast(it->transfer.host_depth_source); + TransferShaderKey transfer_shader_key = it->shader_key; + const TransferModeInfo& transfer_mode_info = + kTransferModes[size_t(transfer_shader_key.mode)]; + TransferRootSignatureIndex transfer_root_signature_index = + use_stencil_reference_output_ ? transfer_mode_info.root_signature_with_stencil_ref + : transfer_mode_info.root_signature_no_stencil_ref; + uint32_t transfer_root_parameters_used = + kTransferUsedRootParameters[size_t(transfer_root_signature_index)]; + bool is_stencil_bit = + (transfer_root_parameters_used & kTransferUsedRootParameterStencilMaskConstantBit) != 0; + + // Late barriers in case there was cross-copying that prevented merging + // of barriers. + command_processor_.PushTransitionBarrier( + source_d3d12_rt.resource(), + source_d3d12_rt.SetResourceState(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE), + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + if (host_depth_source_d3d12_rt) { + if (transfer_shader_key.host_depth_source_is_copy) { + // Reading copied host depth from the EDRAM buffer. + TransitionEdramBuffer(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + } else { + // Reading host depth from the texture. + command_processor_.PushTransitionBarrier( + host_depth_source_d3d12_rt->resource(), + host_depth_source_d3d12_rt->SetResourceState( + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE), + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + } + } + + uint32_t transfer_vertex_count = 6 * transfer_rectangle_count; + D3D12_VERTEX_BUFFER_VIEW transfer_rectangle_buffer_view; + transfer_rectangle_buffer_view.StrideInBytes = sizeof(float) * 2; + transfer_rectangle_buffer_view.SizeInBytes = + transfer_rectangle_buffer_view.StrideInBytes * transfer_vertex_count; + float* transfer_rectangle_write_ptr = + reinterpret_cast(transfer_vertex_buffer_pool_->Request( + current_submission, transfer_rectangle_buffer_view.SizeInBytes, sizeof(float), + nullptr, nullptr, &transfer_rectangle_buffer_view.BufferLocation)); + if (!transfer_rectangle_write_ptr) { + continue; + } + for (auto it_merged = it_merged_first; it_merged <= it_merged_last; ++it_merged) { + Transfer::Rectangle transfer_invocation_rectangles[Transfer::kMaxRectanglesWithCutout]; + uint32_t transfer_invocation_rectangle_count = it_merged->transfer.GetRectangles( + dest_rt_key.base_tiles, dest_pitch_tiles, dest_rt_key.msaa_samples, dest_is_64bpp, + transfer_invocation_rectangles, resolve_clear_rectangle); + assert_not_zero(transfer_invocation_rectangle_count); + for (uint32_t j = 0; j < transfer_invocation_rectangle_count; ++j) { + const Transfer::Rectangle& transfer_rectangle = transfer_invocation_rectangles[j]; + float transfer_rectangle_x0 = -1.0f + transfer_rectangle.x_pixels * pixels_to_ndc_x; + float transfer_rectangle_y0 = 1.0f - transfer_rectangle.y_pixels * pixels_to_ndc_y; + float transfer_rectangle_x1 = + transfer_rectangle_x0 + transfer_rectangle.width_pixels * pixels_to_ndc_x; + float transfer_rectangle_y1 = + transfer_rectangle_y0 - transfer_rectangle.height_pixels * pixels_to_ndc_y; + // O-* + // |/ + // * + *(transfer_rectangle_write_ptr++) = transfer_rectangle_x0; + *(transfer_rectangle_write_ptr++) = transfer_rectangle_y0; + // *-O + // |/ + // * + *(transfer_rectangle_write_ptr++) = transfer_rectangle_x1; + *(transfer_rectangle_write_ptr++) = transfer_rectangle_y0; + // *-* + // |/ + // O + *(transfer_rectangle_write_ptr++) = transfer_rectangle_x0; + *(transfer_rectangle_write_ptr++) = transfer_rectangle_y1; + // * + // /| + // O-* + *(transfer_rectangle_write_ptr++) = transfer_rectangle_x0; + *(transfer_rectangle_write_ptr++) = transfer_rectangle_y1; + // O + // /| + // *-* + *(transfer_rectangle_write_ptr++) = transfer_rectangle_x1; + *(transfer_rectangle_write_ptr++) = transfer_rectangle_y0; + // * + // /| + // *-O + *(transfer_rectangle_write_ptr++) = transfer_rectangle_x1; + *(transfer_rectangle_write_ptr++) = transfer_rectangle_y1; + } + } + command_processor_.SetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + command_list.D3DIASetVertexBuffers(0, 1, &transfer_rectangle_buffer_view); + + ID3D12PipelineState* const* transfer_pipelines = + GetOrCreateTransferPipelines(transfer_shader_key); + if (!transfer_pipelines) { + continue; + } + if (last_transfer_root_signature_index != transfer_root_signature_index) { + last_transfer_root_signature_index = transfer_root_signature_index; + command_processor_.SetExternalGraphicsRootSignature( + transfer_root_signatures_[size_t(transfer_root_signature_index)]); + transfer_root_parameters_set = 0; + } + + // Invalidate outdated bindings. + if (transfer_root_parameters_used & kTransferUsedRootParameterColorSRVBit) { + uint32_t descriptor_index_color = source_d3d12_rt.temporary_srv_descriptor_index(); + assert_true(descriptor_index_color != UINT32_MAX); + if (last_descriptor_index_color != descriptor_index_color) { + last_descriptor_index_color = descriptor_index_color; + transfer_root_parameters_set &= ~kTransferUsedRootParameterColorSRVBit; + } + } + if (transfer_root_parameters_used & kTransferUsedRootParameterDepthSRVBit) { + uint32_t descriptor_index_depth = source_d3d12_rt.temporary_srv_descriptor_index(); + assert_true(descriptor_index_depth != UINT32_MAX); + if (last_descriptor_index_depth != descriptor_index_depth) { + last_descriptor_index_depth = descriptor_index_depth; + transfer_root_parameters_set &= ~kTransferUsedRootParameterDepthSRVBit; + } + } + if (transfer_root_parameters_used & kTransferUsedRootParameterStencilSRVBit) { + uint32_t descriptor_index_stencil = + source_d3d12_rt.temporary_srv_descriptor_index_stencil(); + assert_true(descriptor_index_stencil != UINT32_MAX); + if (last_descriptor_index_stencil != descriptor_index_stencil) { + last_descriptor_index_stencil = descriptor_index_stencil; + transfer_root_parameters_set &= ~kTransferUsedRootParameterStencilSRVBit; + } + } + if (transfer_root_parameters_used & kTransferUsedRootParameterHostDepthSRVBit) { + if (transfer_shader_key.host_depth_source_is_copy) { + if (!last_descriptor_host_depth_is_copy) { + last_descriptor_host_depth_is_copy = true; + transfer_root_parameters_set &= ~kTransferUsedRootParameterHostDepthSRVBit; + } + } else { + assert_not_null(host_depth_source_d3d12_rt); + uint32_t descriptor_index_host_depth = + host_depth_source_d3d12_rt->temporary_srv_descriptor_index(); + assert_true(descriptor_index_host_depth != UINT32_MAX); + if (last_descriptor_host_depth_is_copy || + last_descriptor_index_host_depth_non_copy != descriptor_index_host_depth) { + transfer_root_parameters_set &= ~kTransferUsedRootParameterHostDepthSRVBit; + } + last_descriptor_host_depth_is_copy = false; + last_descriptor_index_host_depth_non_copy = descriptor_index_host_depth; + } + } + if (transfer_root_parameters_used & kTransferUsedRootParameterAddressConstantBit) { + RenderTargetKey source_rt_key = source_d3d12_rt.key(); + TransferAddressConstant address_constant; + address_constant.dest_pitch = dest_pitch_tiles; + address_constant.source_pitch = source_rt_key.GetPitchTiles(); + address_constant.source_to_dest = + int32_t(dest_rt_key.base_tiles) - int32_t(source_rt_key.base_tiles); + if (last_address_constant != address_constant) { + last_address_constant = address_constant; + transfer_root_parameters_set &= ~kTransferUsedRootParameterAddressConstantBit; + } + } + if (transfer_root_parameters_used & kTransferUsedRootParameterHostDepthAddressConstantBit) { + assert_not_null(host_depth_source_d3d12_rt); + RenderTargetKey host_depth_source_rt_key = host_depth_source_d3d12_rt->key(); + TransferAddressConstant host_depth_address_constant; + host_depth_address_constant.dest_pitch = dest_pitch_tiles; + host_depth_address_constant.source_pitch = host_depth_source_rt_key.GetPitchTiles(); + host_depth_address_constant.source_to_dest = + int32_t(dest_rt_key.base_tiles) - int32_t(host_depth_source_rt_key.base_tiles); + if (last_host_depth_address_constant != host_depth_address_constant) { + last_host_depth_address_constant = host_depth_address_constant; + transfer_root_parameters_set &= ~kTransferUsedRootParameterHostDepthAddressConstantBit; + } + } + + // Apply the new bindings. + uint32_t transfer_root_parameters_unset = + transfer_root_parameters_used & ~transfer_root_parameters_set; + if (transfer_root_parameters_unset & + kTransferUsedRootParameterHostDepthAddressConstantBit) { + command_list.D3DSetGraphicsRoot32BitConstants( + rex::bit_count(transfer_root_parameters_used & + (kTransferUsedRootParameterHostDepthAddressConstantBit - 1)), + sizeof(last_host_depth_address_constant) / sizeof(uint32_t), + &last_host_depth_address_constant, 0); + transfer_root_parameters_set |= kTransferUsedRootParameterHostDepthAddressConstantBit; + } + if (transfer_root_parameters_unset & kTransferUsedRootParameterHostDepthSRVBit) { + D3D12_GPU_DESCRIPTOR_HANDLE descriptor_gpu_handle; + if (last_descriptor_host_depth_is_copy) { + if (bindless_resources_used_) { + descriptor_gpu_handle = + command_processor_ + .GetSystemBindlessViewHandlePair( + D3D12CommandProcessor::SystemBindlessView ::kEdramR32UintSRV) + .second; + } else { + assert_true(host_depth_copy_srv_index != UINT32_MAX); + descriptor_gpu_handle = + current_temporary_descriptors_gpu_[host_depth_copy_srv_index].second; + } + } else { + assert_true(last_descriptor_index_host_depth_non_copy != UINT32_MAX); + descriptor_gpu_handle = + current_temporary_descriptors_gpu_[last_descriptor_index_host_depth_non_copy] + .second; + } + command_list.D3DSetGraphicsRootDescriptorTable( + rex::bit_count(transfer_root_parameters_used & + (kTransferUsedRootParameterHostDepthSRVBit - 1)), + descriptor_gpu_handle); + transfer_root_parameters_set |= kTransferUsedRootParameterHostDepthSRVBit; + } + if (transfer_root_parameters_unset & kTransferUsedRootParameterAddressConstantBit) { + command_list.D3DSetGraphicsRoot32BitConstants( + rex::bit_count(transfer_root_parameters_used & + (kTransferUsedRootParameterAddressConstantBit - 1)), + sizeof(last_address_constant) / sizeof(uint32_t), &last_address_constant, 0); + transfer_root_parameters_set |= kTransferUsedRootParameterAddressConstantBit; + } + if (transfer_root_parameters_unset & kTransferUsedRootParameterStencilSRVBit) { + assert_true(last_descriptor_index_stencil != UINT32_MAX); + command_list.D3DSetGraphicsRootDescriptorTable( + rex::bit_count(transfer_root_parameters_used & + (kTransferUsedRootParameterStencilSRVBit - 1)), + current_temporary_descriptors_gpu_[last_descriptor_index_stencil].second); + transfer_root_parameters_set |= kTransferUsedRootParameterStencilSRVBit; + } + if (transfer_root_parameters_unset & kTransferUsedRootParameterDepthSRVBit) { + assert_true(last_descriptor_index_depth != UINT32_MAX); + command_list.D3DSetGraphicsRootDescriptorTable( + rex::bit_count(transfer_root_parameters_used & + (kTransferUsedRootParameterDepthSRVBit - 1)), + current_temporary_descriptors_gpu_[last_descriptor_index_depth].second); + transfer_root_parameters_set |= kTransferUsedRootParameterDepthSRVBit; + } + if (transfer_root_parameters_unset & kTransferUsedRootParameterColorSRVBit) { + assert_true(last_descriptor_index_color != UINT32_MAX); + command_list.D3DSetGraphicsRootDescriptorTable( + rex::bit_count(transfer_root_parameters_used & + (kTransferUsedRootParameterColorSRVBit - 1)), + current_temporary_descriptors_gpu_[last_descriptor_index_color].second); + transfer_root_parameters_set |= kTransferUsedRootParameterColorSRVBit; + } + + // Draw the transfer rectangles. + command_processor_.SubmitBarriers(); + for (uint32_t j = 0; j <= uint32_t(is_stencil_bit) * 7; ++j) { + if (is_stencil_bit) { + uint32_t transfer_stencil_bit = uint32_t(1) << j; + command_list.D3DSetGraphicsRoot32BitConstants( + rex::bit_count(transfer_root_parameters_used & + (kTransferUsedRootParameterStencilMaskConstantBit - 1)), + sizeof(transfer_stencil_bit) / sizeof(uint32_t), &transfer_stencil_bit, 0); + } + command_processor_.SetExternalPipeline(transfer_pipelines[j]); + command_list.D3DDrawInstanced(transfer_vertex_count, 1, 0, 0); + } + } + } + + // Perform the clear. + if (resolve_clear_needed) { + uint64_t clear_value = render_target_resolve_clear_values[i]; + if (dest_rt_key.is_depth) { + uint32_t depth_guest_clear_value = (uint32_t(clear_value) >> 8) & 0xFFFFFF; + float depth_host_clear_value = 0.0f; + switch (dest_rt_key.GetDepthFormat()) { + case xenos::DepthRenderTargetFormat::kD24S8: + depth_host_clear_value = xenos::UNorm24To32(depth_guest_clear_value); + break; + case xenos::DepthRenderTargetFormat::kD24FS8: + // Taking [0, 2) -> [0, 1) remapping into account. + depth_host_clear_value = xenos::Float20e4To32(depth_guest_clear_value) * 0.5f; + break; + } + command_processor_.PushTransitionBarrier( + dest_d3d12_rt.resource(), + dest_d3d12_rt.SetResourceState(D3D12_RESOURCE_STATE_DEPTH_WRITE), + D3D12_RESOURCE_STATE_DEPTH_WRITE); + command_processor_.SubmitBarriers(); + command_list.D3DClearDepthStencilView(dest_d3d12_rt.descriptor_draw().GetHandle(), + D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, + depth_host_clear_value, UINT(clear_value) & 0xFF, 1, + &clear_rect); + } else { + float color_clear_value[4] = {}; + bool clear_via_drawing = false; + switch (dest_rt_key.GetColorFormat()) { + case xenos::ColorRenderTargetFormat::k_8_8_8_8: { + for (uint32_t j = 0; j < 4; ++j) { + color_clear_value[j] = ((clear_value >> (j * 8)) & 0xFF) * (1.0f / 0xFF); + } + } break; + case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA: { + // 8_8_8_8_GAMMA is represented by linear stored in + // R16G16B16A16_UNORM. + for (uint32_t j = 0; j < 4; ++j) { + color_clear_value[j] = ((clear_value >> (j * 8)) & 0xFF) * (1.0f / 0xFF); + } + for (uint32_t j = 0; j < 3; ++j) { + color_clear_value[j] = xenos::PWLGammaToLinear(color_clear_value[j]); + } + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: { + for (uint32_t j = 0; j < 3; ++j) { + color_clear_value[j] = ((clear_value >> (j * 10)) & 0x3FF) * (1.0f / 0x3FF); + } + color_clear_value[3] = ((clear_value >> 30) & 0x3) * (1.0f / 0x3); + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16: { + for (uint32_t j = 0; j < 3; ++j) { + color_clear_value[j] = xenos::Float7e3To32((clear_value >> (j * 10)) & 0x3FF); + } + color_clear_value[3] = ((clear_value >> 30) & 0x3) * (1.0f / 0x3); + } break; + case xenos::ColorRenderTargetFormat::k_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_FLOAT: { + // Using uint for loading both. Disregarding the current -32...32 + // vs. -1...1 settings for consistency with color clear via depth + // aliasing. + for (uint32_t j = 0; j < 2; ++j) { + color_clear_value[j] = float((clear_value >> (j * 16)) & 0xFFFF); + } + } break; + case xenos::ColorRenderTargetFormat::k_16_16_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT: { + // Using uint for loading both. Disregarding the current -32...32 + // vs. -1...1 settings for consistency with color clear via depth + // aliasing. + for (uint32_t j = 0; j < 4; ++j) { + color_clear_value[j] = float((clear_value >> (j * 16)) & 0xFFFF); + } + } break; + case xenos::ColorRenderTargetFormat::k_32_FLOAT: { + // Using uint for proper denormal and NaN handling. + color_clear_value[0] = float(uint32_t(clear_value)); + // Numbers > 2^24 can't be represented with a step of 1 as floats, + // need to clear by drawing a uint rectangle. + if (uint64_t(color_clear_value[0]) != uint32_t(clear_value)) { + clear_via_drawing = true; + } + } break; + case xenos::ColorRenderTargetFormat::k_32_32_FLOAT: { + // Using uint for proper denormal and NaN handling. + color_clear_value[0] = float(uint32_t(clear_value)); + color_clear_value[1] = float(uint32_t(clear_value >> 32)); + // Numbers > 2^24 can't be represented with a step of 1 as floats, + // need to clear by drawing a uint rectangle. + if (uint64_t(color_clear_value[0]) != uint32_t(clear_value) || + uint64_t(color_clear_value[1]) != uint32_t(clear_value >> 32)) { + clear_via_drawing = true; + } + } break; + } + command_processor_.PushTransitionBarrier( + dest_d3d12_rt.resource(), + dest_d3d12_rt.SetResourceState(D3D12_RESOURCE_STATE_RENDER_TARGET), + D3D12_RESOURCE_STATE_RENDER_TARGET); + if (clear_via_drawing) { + D3D12_CPU_DESCRIPTOR_HANDLE clear_rtv_handle = + dest_d3d12_rt.descriptor_load_separate().IsValid() + ? dest_d3d12_rt.descriptor_load_separate().GetHandle() + : dest_d3d12_rt.descriptor_draw().GetHandle(); + command_list.D3DOMSetRenderTargets(1, &clear_rtv_handle, FALSE, nullptr); + are_current_command_list_render_targets_valid_ = true; + D3D12_VIEWPORT clear_viewport; + clear_viewport.TopLeftX = float(clear_rect.left); + clear_viewport.TopLeftY = float(clear_rect.top); + clear_viewport.Width = float(clear_rect.right - clear_rect.left); + clear_viewport.Height = float(clear_rect.bottom - clear_rect.top); + clear_viewport.MinDepth = 0.0f; + clear_viewport.MaxDepth = 1.0f; + command_processor_.SetViewport(clear_viewport); + command_processor_.SetScissorRect(clear_rect); + command_processor_.SetExternalGraphicsRootSignature(uint32_rtv_clear_root_signature_); + uint32_t clear_via_drawing_value[2] = {uint32_t(clear_value), + uint32_t(clear_value >> 32)}; + command_list.D3DSetGraphicsRoot32BitConstants(0, 2, clear_via_drawing_value, 0); + command_processor_.SetExternalPipeline(uint32_rtv_clear_pipelines_[size_t( + dest_rt_key.GetColorFormat() == + xenos::ColorRenderTargetFormat::k_32_32_FLOAT)][size_t(dest_rt_key.msaa_samples)]); + command_processor_.SetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + command_list.D3DDrawInstanced(3, 1, 0, 0); + } else { + command_processor_.SubmitBarriers(); + command_list.D3DClearRenderTargetView( + dest_d3d12_rt.descriptor_load_separate().IsValid() + ? dest_d3d12_rt.descriptor_load_separate().GetHandle() + : dest_d3d12_rt.descriptor_draw().GetHandle(), + color_clear_value, 1, &clear_rect); + } + } + } + } +} + +void D3D12RenderTargetCache::SetCommandListRenderTargets( + RenderTarget* const* depth_and_color_render_targets) { + assert_true(GetPath() == Path::kHostRenderTargets); + + // Ensure the render targets are in the needed resource state. + if (depth_and_color_render_targets[0]) { + auto& d3d12_rt = *static_cast(depth_and_color_render_targets[0]); + command_processor_.PushTransitionBarrier( + d3d12_rt.resource(), d3d12_rt.SetResourceState(D3D12_RESOURCE_STATE_DEPTH_WRITE), + D3D12_RESOURCE_STATE_DEPTH_WRITE); + } + for (uint32_t i = 0; i < xenos::kMaxColorRenderTargets; ++i) { + RenderTarget* render_target = depth_and_color_render_targets[1 + i]; + if (!render_target) { + continue; + } + auto& d3d12_rt = *static_cast(render_target); + command_processor_.PushTransitionBarrier( + d3d12_rt.resource(), d3d12_rt.SetResourceState(D3D12_RESOURCE_STATE_RENDER_TARGET), + D3D12_RESOURCE_STATE_RENDER_TARGET); + } + + // Bind the render targets. + if (are_current_command_list_render_targets_valid_ && + std::memcmp(current_command_list_render_targets_, depth_and_color_render_targets, + sizeof(current_command_list_render_targets_))) { + are_current_command_list_render_targets_valid_ = false; + } + if (!are_current_command_list_render_targets_valid_) { + std::memcpy(current_command_list_render_targets_, depth_and_color_render_targets, + sizeof(current_command_list_render_targets_)); + D3D12_CPU_DESCRIPTOR_HANDLE dsv_handle; + if (depth_and_color_render_targets[0]) { + dsv_handle = static_cast(depth_and_color_render_targets[0]) + ->descriptor_draw() + .GetHandle(); + } + D3D12_CPU_DESCRIPTOR_HANDLE rtv_handles[xenos::kMaxColorRenderTargets]; + uint32_t rtv_count = 0; + for (uint32_t i = 0; i < xenos::kMaxColorRenderTargets; ++i) { + const RenderTarget* render_target = depth_and_color_render_targets[1 + i]; + if (!render_target) { + continue; + } + // Fill the gaps with a null descriptor. + while (rtv_count < i) { + rtv_handles[rtv_count++] = render_target->key().msaa_samples != xenos::MsaaSamples::k1X + ? null_rtv_descriptor_ms_.GetHandle() + : null_rtv_descriptor_ss_.GetHandle(); + } + auto& d3d12_rt = *static_cast(render_target); + rtv_handles[rtv_count++] = d3d12_rt.descriptor_draw().GetHandle(); + } + command_processor_.GetDeferredCommandList().D3DOMSetRenderTargets( + rtv_count, rtv_handles, FALSE, depth_and_color_render_targets[0] ? &dsv_handle : nullptr); + are_current_command_list_render_targets_valid_ = true; + } +} + +ID3D12PipelineState* D3D12RenderTargetCache::GetOrCreateDumpPipeline(DumpPipelineKey key) { + auto pipeline_it = dump_pipelines_.find(key); + if (pipeline_it != dump_pipelines_.end()) { + return pipeline_it->second; + } + + // Because of built_shader_.resize(), pointers can't be kept persistently + // here! Resizing also zeroes the memory. + + built_shader_.clear(); + + // RDEF, ISGN, OSGN, SHEX, STAT. + constexpr uint32_t kBlobCount = 5; + + // Allocate space for the container header and the blob offsets. + built_shader_.resize(sizeof(dxbc::ContainerHeader) / sizeof(uint32_t) + kBlobCount); + uint32_t blob_offset_position_dwords = sizeof(dxbc::ContainerHeader) / sizeof(uint32_t); + uint32_t blob_position_dwords = uint32_t(built_shader_.size()); + constexpr uint32_t kBlobHeaderSizeDwords = sizeof(dxbc::BlobHeader) / sizeof(uint32_t); + + uint32_t name_ptr; + + // *************************************************************************** + // Resource definition + // *************************************************************************** + + built_shader_[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + uint32_t rdef_position_dwords = blob_position_dwords + kBlobHeaderSizeDwords; + // Not needed, as the next operation done is resize, to allocate the space for + // both the blob header and the resource definition header. + // built_shader_.resize(rdef_position_dwords); + + // Allocate space for the RDEF header. + built_shader_.resize(rdef_position_dwords + sizeof(dxbc::RdefHeader) / sizeof(uint32_t)); + // Generator name. + dxbc::AppendAlignedString(built_shader_, "Xenia"); + + // Constant types - uint (aka "dword" when it's scalar) only. + // Names. + name_ptr = uint32_t((built_shader_.size() - rdef_position_dwords) * sizeof(uint32_t)); + uint32_t rdef_dword_name_ptr = name_ptr; + name_ptr += dxbc::AppendAlignedString(built_shader_, "dword"); + // Types. + uint32_t rdef_type_uint_position_dwords = uint32_t(built_shader_.size()); + uint32_t rdef_type_uint_ptr = + uint32_t((rdef_type_uint_position_dwords - rdef_position_dwords) * sizeof(uint32_t)); + built_shader_.resize(rdef_type_uint_position_dwords + sizeof(dxbc::RdefType) / sizeof(uint32_t)); + { + auto& rdef_type_uint = + *reinterpret_cast(built_shader_.data() + rdef_type_uint_position_dwords); + rdef_type_uint.variable_class = dxbc::RdefVariableClass::kScalar; + rdef_type_uint.variable_type = dxbc::RdefVariableType::kUInt; + rdef_type_uint.row_count = 1; + rdef_type_uint.column_count = 1; + rdef_type_uint.name_ptr = rdef_dword_name_ptr; + } + + // Constants: + // - uint xe_edram_dump_offsets + // - uint xe_edram_dump_pitches + enum Constant : uint32_t { + kConstantOffsets, + kConstantPitches, + kConstantCount, + }; + // Names. + name_ptr = uint32_t((built_shader_.size() - rdef_position_dwords) * sizeof(uint32_t)); + uint32_t rdef_xe_edram_dump_offsets_name_ptr = name_ptr; + name_ptr += dxbc::AppendAlignedString(built_shader_, "xe_edram_dump_offsets"); + uint32_t rdef_xe_edram_dump_pitches_name_ptr = name_ptr; + name_ptr += dxbc::AppendAlignedString(built_shader_, "xe_edram_dump_pitches"); + // Constants. + uint32_t rdef_constants_position_dwords = uint32_t(built_shader_.size()); + uint32_t rdef_constants_ptr = + uint32_t((rdef_constants_position_dwords - rdef_position_dwords) * sizeof(uint32_t)); + built_shader_.resize(rdef_constants_position_dwords + + sizeof(dxbc::RdefVariable) / sizeof(uint32_t) * kConstantCount); + { + auto rdef_constants = reinterpret_cast(built_shader_.data() + + rdef_constants_position_dwords); + // uint xe_edram_dump_offsets + dxbc::RdefVariable& rdef_constant_offsets = rdef_constants[kConstantOffsets]; + rdef_constant_offsets.name_ptr = rdef_xe_edram_dump_offsets_name_ptr; + rdef_constant_offsets.size_bytes = sizeof(uint32_t); + rdef_constant_offsets.flags = dxbc::kRdefVariableFlagUsed; + rdef_constant_offsets.type_ptr = rdef_type_uint_ptr; + rdef_constant_offsets.start_texture = UINT32_MAX; + rdef_constant_offsets.start_sampler = UINT32_MAX; + // uint xe_edram_dump_pitches + dxbc::RdefVariable& rdef_constant_pitches = rdef_constants[kConstantPitches]; + rdef_constant_pitches.name_ptr = rdef_xe_edram_dump_pitches_name_ptr; + rdef_constant_pitches.size_bytes = sizeof(uint32_t); + rdef_constant_pitches.flags = dxbc::kRdefVariableFlagUsed; + rdef_constant_pitches.type_ptr = rdef_type_uint_ptr; + rdef_constant_pitches.start_texture = UINT32_MAX; + rdef_constant_pitches.start_sampler = UINT32_MAX; + } + + // Constant buffers: + // - xe_edram_dump_offsets : b0 { uint xe_edram_dump_offsets; } + // - xe_edram_dump_pitches : b1 { uint xe_edram_dump_pitches; } + // Reusing the constant names for constant buffers. + uint32_t rdef_cbuffer_position_dwords = uint32_t(built_shader_.size()); + built_shader_.resize(rdef_cbuffer_position_dwords + + sizeof(dxbc::RdefCbuffer) / sizeof(uint32_t) * kDumpCbufferCount); + { + auto rdef_cbuffers = + reinterpret_cast(built_shader_.data() + rdef_cbuffer_position_dwords); + // xe_edram_dump_offsets + dxbc::RdefCbuffer& rdef_cbuffer_offsets = rdef_cbuffers[kDumpCbufferOffsets]; + rdef_cbuffer_offsets.name_ptr = rdef_xe_edram_dump_offsets_name_ptr; + rdef_cbuffer_offsets.variable_count = 1; + rdef_cbuffer_offsets.variables_ptr = + uint32_t(rdef_constants_ptr + sizeof(dxbc::RdefVariable) * kConstantOffsets); + rdef_cbuffer_offsets.size_vector_aligned_bytes = sizeof(uint32_t) * 4; + // xe_edram_dump_pitches + dxbc::RdefCbuffer& rdef_cbuffer_pitches = rdef_cbuffers[kDumpCbufferPitches]; + rdef_cbuffer_pitches.name_ptr = rdef_xe_edram_dump_pitches_name_ptr; + rdef_cbuffer_pitches.variable_count = 1; + rdef_cbuffer_pitches.variables_ptr = + uint32_t(rdef_constants_ptr + sizeof(dxbc::RdefVariable) * kConstantPitches); + rdef_cbuffer_pitches.size_vector_aligned_bytes = sizeof(uint32_t) * 4; + } + + // Bindings. + // - Texture2D/Texture2DMS xe_edram_dump_source : t0 + // - Optionally, Texture2D/Texture2DMS xe_edram_dump_stencil : t1 + // - RWBuffer xe_edram : u0 + // - Constant buffers + uint32_t rdef_binding_count = 1 + key.is_depth + 1 + kDumpCbufferCount; + // Names. + name_ptr = uint32_t((built_shader_.size() - rdef_position_dwords) * sizeof(uint32_t)); + uint32_t rdef_xe_edram_dump_source_name_ptr = name_ptr; + name_ptr += dxbc::AppendAlignedString(built_shader_, "xe_edram_dump_source"); + uint32_t rdef_xe_edram_dump_stencil_name_ptr = name_ptr; + if (key.is_depth) { + name_ptr += dxbc::AppendAlignedString(built_shader_, "xe_edram_dump_stencil"); + } + uint32_t rdef_xe_edram_name_ptr = name_ptr; + name_ptr += dxbc::AppendAlignedString(built_shader_, "xe_edram"); + // Bindings. + uint32_t rdef_binding_position_dwords = uint32_t(built_shader_.size()); + built_shader_.resize(rdef_binding_position_dwords + + sizeof(dxbc::RdefInputBind) / sizeof(uint32_t) * rdef_binding_count); + bool source_is_uint; + if (key.is_depth) { + source_is_uint = false; + } else { + GetColorOwnershipTransferDXGIFormat(key.GetColorFormat(), &source_is_uint); + } + dxbc::ResourceReturnType source_return_type = + source_is_uint ? dxbc::ResourceReturnType::kUInt : dxbc::ResourceReturnType::kFloat; + uint32_t source_component_count = + key.is_depth ? 1 : xenos::GetColorRenderTargetFormatComponentCount(key.GetColorFormat()); + bool format_is_64bpp = + !key.is_depth && xenos::IsColorRenderTargetFormat64bpp(key.GetColorFormat()); + { + auto rdef_bindings = + reinterpret_cast(built_shader_.data() + rdef_binding_position_dwords); + uint32_t rdef_binding_index = 0; + // xe_edram_dump_source + dxbc::RdefInputBind& rdef_binding_source = rdef_bindings[rdef_binding_index++]; + rdef_binding_source.name_ptr = rdef_xe_edram_dump_source_name_ptr; + rdef_binding_source.type = dxbc::RdefInputType::kTexture; + rdef_binding_source.return_type = source_return_type; + if (key.msaa_samples != xenos::MsaaSamples::k1X) { + rdef_binding_source.dimension = dxbc::RdefDimension::kSRVTexture2DMS; + // Sample count is dynamic on Shader Model 5. + } else { + rdef_binding_source.dimension = dxbc::RdefDimension::kSRVTexture2D; + rdef_binding_source.sample_count = UINT32_MAX; + } + rdef_binding_source.bind_count = 1; + rdef_binding_source.flags = (source_component_count - 1) + << dxbc::kRdefInputFlagsComponentsShift; + // xe_edram_dump_stencil + if (key.is_depth) { + dxbc::RdefInputBind& rdef_binding_stencil = rdef_bindings[rdef_binding_index++]; + rdef_binding_stencil.name_ptr = rdef_xe_edram_dump_stencil_name_ptr; + rdef_binding_stencil.type = dxbc::RdefInputType::kTexture; + rdef_binding_stencil.return_type = dxbc::ResourceReturnType::kUInt; + rdef_binding_stencil.dimension = rdef_binding_source.dimension; + rdef_binding_stencil.sample_count = rdef_binding_source.sample_count; + rdef_binding_stencil.bind_point = 1; + rdef_binding_stencil.bind_count = 1; + rdef_binding_stencil.flags = dxbc::kRdefInputFlags2Component; + rdef_binding_stencil.id = 1; + } + // xe_edram + dxbc::RdefInputBind& rdef_binding_edram = rdef_bindings[rdef_binding_index++]; + rdef_binding_edram.name_ptr = rdef_xe_edram_name_ptr; + rdef_binding_edram.type = dxbc::RdefInputType::kUAVRWTyped; + rdef_binding_edram.return_type = dxbc::ResourceReturnType::kUInt; + rdef_binding_edram.dimension = dxbc::RdefDimension::kUAVBuffer; + rdef_binding_edram.sample_count = UINT32_MAX; + rdef_binding_edram.bind_count = 1; + rdef_binding_edram.flags = format_is_64bpp ? dxbc::kRdefInputFlags2Component : 0; + // xe_edram_dump_offsets + dxbc::RdefInputBind& rdef_binding_offsets = rdef_bindings[rdef_binding_index++]; + rdef_binding_offsets.name_ptr = rdef_xe_edram_dump_offsets_name_ptr; + rdef_binding_offsets.type = dxbc::RdefInputType::kCbuffer; + rdef_binding_offsets.bind_point = kDumpCbufferOffsets; + rdef_binding_offsets.bind_count = 1; + rdef_binding_offsets.flags = dxbc::kRdefInputFlagUserPacked; + rdef_binding_offsets.id = kDumpCbufferOffsets; + // xe_edram_dump_pitches + dxbc::RdefInputBind& rdef_binding_pitches = rdef_bindings[rdef_binding_index++]; + rdef_binding_pitches.name_ptr = rdef_xe_edram_dump_pitches_name_ptr; + rdef_binding_pitches.type = dxbc::RdefInputType::kCbuffer; + rdef_binding_pitches.bind_point = kDumpCbufferPitches; + rdef_binding_pitches.bind_count = 1; + rdef_binding_pitches.flags = dxbc::kRdefInputFlagUserPacked; + rdef_binding_pitches.id = kDumpCbufferPitches; + } + + // Header. + { + auto& rdef_header = + *reinterpret_cast(built_shader_.data() + rdef_position_dwords); + rdef_header.cbuffer_count = kDumpCbufferCount; + rdef_header.cbuffers_ptr = + uint32_t((rdef_cbuffer_position_dwords - rdef_position_dwords) * sizeof(uint32_t)); + rdef_header.input_bind_count = rdef_binding_count; + rdef_header.input_binds_ptr = + uint32_t((rdef_binding_position_dwords - rdef_position_dwords) * sizeof(uint32_t)); + rdef_header.shader_model = dxbc::RdefShaderModel::kComputeShader5_1; + rdef_header.compile_flags = + dxbc::kCompileFlagNoPreshader | dxbc::kCompileFlagPreferFlowControl | + dxbc::kCompileFlagIeeeStrictness | dxbc::kCompileFlagAllResourcesBound; + // Generator name is right after the header. + rdef_header.generator_name_ptr = sizeof(dxbc::RdefHeader); + rdef_header.fourcc = dxbc::RdefHeader::FourCC::k5_1; + rdef_header.InitializeSizes(); + } + + { + auto& blob_header = + *reinterpret_cast(built_shader_.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kResourceDefinition; + blob_position_dwords = uint32_t(built_shader_.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + built_shader_[blob_offset_position_dwords++]; + } + + // *************************************************************************** + // Input and output signatures (empty) + // *************************************************************************** + + for (uint32_t i = 0; i < 2; ++i) { + built_shader_[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + uint32_t signature_position_dwords = blob_position_dwords + kBlobHeaderSizeDwords; + built_shader_.resize(signature_position_dwords + sizeof(dxbc::Signature) / sizeof(uint32_t)); + { + auto& signature = + *reinterpret_cast(built_shader_.data() + signature_position_dwords); + // Empty - just set parameter pointer to the end. + signature.parameter_info_ptr = sizeof(dxbc::Signature); + } + { + auto& blob_header = + *reinterpret_cast(built_shader_.data() + blob_position_dwords); + blob_header.fourcc = i ? dxbc::BlobHeader::FourCC::kOutputSignature + : dxbc::BlobHeader::FourCC::kInputSignature; + blob_position_dwords = uint32_t(built_shader_.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + built_shader_[blob_offset_position_dwords++]; + } + } + + // *************************************************************************** + // Shader program + // *************************************************************************** + + built_shader_[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + uint32_t shex_position_dwords = blob_position_dwords + kBlobHeaderSizeDwords; + built_shader_.resize(shex_position_dwords); + + built_shader_.push_back(dxbc::VersionToken(dxbc::ProgramType::kComputeShader, 5, 1)); + // Reserve space for the length token. + built_shader_.push_back(0); + + dxbc::Statistics stat; + std::memset(&stat, 0, sizeof(dxbc::Statistics)); + dxbc::Assembler a(built_shader_, stat); + + a.OpDclGlobalFlags(dxbc::kGlobalFlagAllResourcesBound); + a.OpDclConstantBuffer( + dxbc::Src::CB(dxbc::Src::Dcl, kDumpCbufferOffsets, kDumpCbufferOffsets, kDumpCbufferOffsets), + 1); + a.OpDclConstantBuffer( + dxbc::Src::CB(dxbc::Src::Dcl, kDumpCbufferPitches, kDumpCbufferPitches, kDumpCbufferPitches), + 1); + // Source texture. + dxbc::ResourceDimension source_dimension = key.msaa_samples != xenos::MsaaSamples::k1X + ? dxbc::ResourceDimension::kTexture2DMS + : dxbc::ResourceDimension::kTexture2D; + a.OpDclResource( + source_dimension, + dxbc::ResourceReturnTypeX4Token(source_is_uint ? dxbc::ResourceReturnType::kUInt + : dxbc::ResourceReturnType::kFloat), + dxbc::Src::T(dxbc::Src::Dcl, 0, 0, 0)); + // Source stencil texture. + if (key.is_depth) { + a.OpDclResource(source_dimension, + dxbc::ResourceReturnTypeX4Token(dxbc::ResourceReturnType::kUInt), + dxbc::Src::T(dxbc::Src::Dcl, 1, 1, 1)); + } + // EDRAM buffer. + a.OpDclUnorderedAccessViewTyped(dxbc::ResourceDimension::kBuffer, 0, + dxbc::ResourceReturnTypeX4Token(dxbc::ResourceReturnType::kUInt), + dxbc::Src::U(dxbc::Src::Dcl, 0, 0, 0)); + a.OpDclInput(dxbc::Dest::VThreadID(0b0011)); + // r0 - addressing before the load, then addressing and conversion scratch + // r1 - addressing scratch before the load, then data + stat.temp_register_count = 2; + a.OpDclTemps(stat.temp_register_count); + // There's no strict dependency on the group size here, for simplicity of + // calculations especially with resolution scaling, dividing manually (as the + // group size is not unlimited). The only restriction is that an integer + // multiple of it must be 80x16 samples (and no larger than that) for 32bpp, + // or 40x16 samples for 64bpp (because only a half of the pair of tiles may + // need to be dumped). The group size limit in Direct3D 11 is 1024, and 40x16 + // fits in it, while 80x16 doesn't. + a.OpDclThreadGroup(40, 16, 1); + + uint32_t draw_resolution_scale_x = this->draw_resolution_scale_x(); + uint32_t draw_resolution_scale_y = this->draw_resolution_scale_y(); + + // For now, as the exact addressing in 64bpp render targets relatively to + // 32bpp is unknown, treating 64bpp tiles as storing 40x16 samples rather than + // 80x16 for simplicity of addressing into the texture. + + uint32_t tile_width = + (xenos::kEdramTileWidthSamples * draw_resolution_scale_x) >> uint32_t(format_is_64bpp); + uint32_t tile_height = xenos::kEdramTileHeightSamples * draw_resolution_scale_y; + + // Get the parts of the address - tile row index within the dispatch to r0.zw, + // sample Y within the tile to r0.xy. + // r0.x = X sample position within the tile + // r0.y = Y sample position within the tile + // r0.z = X tile position + // r0.w = Y tile position + a.OpUDiv(dxbc::Dest::R(0, 0b1100), dxbc::Dest::R(0, 0b0011), dxbc::Src::VThreadID(0b01000100), + dxbc::Src::LU(tile_width, tile_height, tile_width, tile_height)); + + // Extract the dump rectangle tile row pitch to r1.x. + // r0.x = X sample position within the tile + // r0.y = Y sample position within the tile + // r0.z = X tile position + // r0.w = Y tile position + // r1.x = dump rectangle pitch in tiles + a.OpUBFE(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(xenos::kEdramPitchTilesBits), dxbc::Src::LU(0), + dxbc::Src::CB(kDumpCbufferPitches, kDumpCbufferPitches, 0, dxbc::Src::kXXXX)); + // Get the tile index in the EDRAM relative to the dump rectangle base tile to + // r0.w. + // r0.x = X sample position within the tile + // r0.y = Y sample position within the tile + // r0.z = free + // r0.w = tile index relative to the dump rectangle base + // r1.x = free + a.OpUMAd(dxbc::Dest::R(0, 0b1000), dxbc::Src::R(0, dxbc::Src::kWWWW), + dxbc::Src::R(1, dxbc::Src::kXXXX), dxbc::Src::R(0, dxbc::Src::kZZZZ)); + + // Extract the index of the first tile (taking EDRAM addressing wrapping into + // account) of the dispatch in the EDRAM to r0.z. + // r0.x = X sample position within the tile + // r0.y = Y sample position within the tile + // r0.z = first EDRAM tile index in the dispatch + // r0.w = tile index relative to the dump rectangle base + a.OpUBFE(dxbc::Dest::R(0, 0b0100), dxbc::Src::LU(xenos::kEdramBaseTilesBits + 1), + dxbc::Src::LU(0), + dxbc::Src::CB(kDumpCbufferOffsets, kDumpCbufferOffsets, 0, dxbc::Src::kXXXX)); + // Add the base tile in the dispatch to the dispatch-local tile index to r0.w, + // not wrapping yet so in case of a wraparound, the address relative to the + // base in the texture after subtraction of the base won't be negative. + // r0.x = X sample position within the tile + // r0.y = Y sample position within the tile + // r0.z = free + // r0.w = non-wrapped tile index in the EDRAM + a.OpIAdd(dxbc::Dest::R(0, 0b1000), dxbc::Src::R(0, dxbc::Src::kWWWW), + dxbc::Src::R(0, dxbc::Src::kZZZZ)); + // Wrap the address of the tile in the EDRAM to r0.z. + // r0.x = X sample position within the tile + // r0.y = Y sample position within the tile + // r0.z = wrapped tile index in the EDRAM + // r0.w = non-wrapped tile index in the EDRAM + a.OpAnd(dxbc::Dest::R(0, 0b0100), dxbc::Src::R(0, dxbc::Src::kWWWW), + dxbc::Src::LU(xenos::kEdramTileCount - 1)); + // Convert the tile index to samples and add the X sample index to it to r0.z. + // r0.x = X sample position within the tile + // r0.y = Y sample position within the tile + // r0.z = tile sample offset in the EDRAM plus X sample offset + // r0.w = non-wrapped tile index in the EDRAM + a.OpUMAd(dxbc::Dest::R(0, 0b0100), dxbc::Src::R(0, dxbc::Src::kZZZZ), + dxbc::Src::LU(draw_resolution_scale_x * draw_resolution_scale_y * + (xenos::kEdramTileWidthSamples >> uint32_t(format_is_64bpp)) * + xenos::kEdramTileHeightSamples), + dxbc::Src::R(0, dxbc::Src::kXXXX)); + // Add the contribution of the Y sample position within the tile to the sample + // address in the EDRAM to r0.z. + // r0.x = X sample position within the tile + // r0.y = Y sample position within the tile + // r0.z = sample offset in the EDRAM without the depth column swapping + // r0.w = non-wrapped tile index in the EDRAM + a.OpUMAd(dxbc::Dest::R(0, 0b0100), dxbc::Src::R(0, dxbc::Src::kYYYY), dxbc::Src::LU(tile_width), + dxbc::Src::R(0, dxbc::Src::kZZZZ)); + if (key.is_depth) { + uint32_t tile_width_half = tile_width >> 1; + // Get which 40-sample half within the tile is being processed to r1.x. + // r0.x = X sample position within the tile + // r0.y = Y sample position within the tile + // r0.z = sample offset in the EDRAM without the depth column swapping + // r0.w = non-wrapped tile index in the EDRAM + // r1.x = 0xFFFFFFFF if in the right 40-sample half, 0 otherwise + a.OpUGE(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(0, dxbc::Src::kXXXX), + dxbc::Src::LU(tile_width_half)); + // Get the offset needed to swap 40-sample halves for depth. + // r0.x = X sample position within the tile + // r0.y = Y sample position within the tile + // r0.z = sample offset in the EDRAM without the depth column swapping + // r0.w = non-wrapped tile index in the EDRAM + // r1.x = depth half-tile flipping offset + a.OpMovC(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(1, dxbc::Src::kXXXX), + dxbc::Src::LI(-int32_t(tile_width_half)), dxbc::Src::LI(int32_t(tile_width_half))); + // Swap 40-sample columns in the depth buffer in the destination address in + // r0.w to get the final address of the sample in EDRAM. + // r0.x = X sample position within the tile + // r0.y = Y sample position within the tile + // r0.z = sample offset in the EDRAM + // r0.w = non-wrapped tile index in the EDRAM + // r1.x = free + a.OpIAdd(dxbc::Dest::R(0, 0b0100), dxbc::Src::R(0, dxbc::Src::kZZZZ), + dxbc::Src::R(1, dxbc::Src::kXXXX)); + } + + // Extract the source texture base tile index to r1.x. + // r0.x = X sample position within the tile + // r0.y = Y sample position within the tile + // r0.z = sample offset in the EDRAM + // r0.w = non-wrapped tile index in the EDRAM + // r1.x = source texture base tile index + a.OpUBFE(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(xenos::kEdramBaseTilesBits), + dxbc::Src::LU(xenos::kEdramBaseTilesBits + 1), + dxbc::Src::CB(kDumpCbufferOffsets, kDumpCbufferOffsets, 0, dxbc::Src::kXXXX)); + // Get the linear tile index within the source texture to r0.w. + // r0.x = X sample position within the tile + // r0.y = Y sample position within the tile + // r0.z = sample offset in the EDRAM + // r0.w = linear tile index in the source texture + // r1.x = free + a.OpIAdd(dxbc::Dest::R(0, 0b1000), dxbc::Src::R(0, dxbc::Src::kWWWW), + -dxbc::Src::R(1, dxbc::Src::kXXXX)); + // Get the source texture pitch in tiles to r1.x. + // r0.x = X sample position within the tile + // r0.y = Y sample position within the tile + // r0.z = sample offset in the EDRAM + // r0.w = linear tile index in the source texture + // r1.x = source texture pitch in tiles + a.OpUBFE(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(xenos::kEdramPitchTilesBits), + dxbc::Src::LU(xenos::kEdramPitchTilesBits), + dxbc::Src::CB(kDumpCbufferPitches, kDumpCbufferPitches, 0, dxbc::Src::kXXXX)); + // Split the linear tile index in the source texture into X and Y in tiles. + // r0.x = X sample position within the tile + // r0.y = Y sample position within the tile + // r0.z = sample offset in the EDRAM + // r0.w = X tile index within the tile row in the source texture + // r1.x = Y tile row index within the source texture + a.OpUDiv(dxbc::Dest::R(1, 0b0001), dxbc::Dest::R(0, 0b1000), dxbc::Src::R(0, dxbc::Src::kWWWW), + dxbc::Src::R(1, dxbc::Src::kXXXX)); + // Add the source texture tile X offset to the source texture sample X + // coordinate. + // r0.x = X sample position within the source texture + // r0.y = Y sample position within the tile + // r0.z = sample offset in the EDRAM + // r0.w = free + // r1.x = Y tile row index within the source texture + a.OpUMAd(dxbc::Dest::R(0, 0b0001), dxbc::Src::R(0, dxbc::Src::kWWWW), dxbc::Src::LU(tile_width), + dxbc::Src::R(0, dxbc::Src::kXXXX)); + // Add the source texture tile Y offset to the source texture sample Y + // coordinate. + // r0.x = X sample position within the source texture + // r0.y = Y sample position within the source texture + // r0.z = sample offset in the EDRAM + // r1.x = free + a.OpUMAd(dxbc::Dest::R(0, 0b0010), dxbc::Src::R(1, dxbc::Src::kXXXX), + dxbc::Src::LU(xenos::kEdramTileHeightSamples * draw_resolution_scale_y), + dxbc::Src::R(0, dxbc::Src::kYYYY)); + // Will be using the source texture coordinates from r0.xy, and for + // single-sampled source, LOD from r0.w. + dxbc::Src source_address_src(dxbc::Src::R(0, 0b11000100)); + if (key.msaa_samples >= xenos::MsaaSamples::k2X) { + if (key.msaa_samples >= xenos::MsaaSamples::k4X) { + // 4x MSAA source texture sample index - bit 0 for horizontal, bit 1 for + // vertical. + // Extract the horizontal sample index to r0.w. + // r0.x = X sample position within the source texture + // r0.y = Y sample position within the source texture + // r0.z = sample offset in the EDRAM + // r0.w = horizontal sample index within the source pixel + a.OpAnd(dxbc::Dest::R(0, 0b1000), dxbc::Src::R(0, dxbc::Src::kXXXX), dxbc::Src::LU(1)); + // Insert the vertical sample index to r0.w. + // r0.x = X sample position within the source texture + // r0.y = Y sample position within the source texture + // r0.z = sample offset in the EDRAM + // r0.w = sample index within the source pixel + a.OpBFI(dxbc::Dest::R(0, 0b1000), dxbc::Src::LU(1), dxbc::Src::LU(1), + dxbc::Src::R(0, dxbc::Src::kYYYY), dxbc::Src::R(0, dxbc::Src::kWWWW)); + // Convert sample to pixel coordinates in the source texture to r0.xy. + // r0.x = X pixel position within the source texture + // r0.y = Y pixel position within the source texture + // r0.z = sample offset in the EDRAM + // r0.w = sample index within the source pixel + a.OpUShR(dxbc::Dest::R(0, 0b0011), dxbc::Src::R(0), dxbc::Src::LU(1)); + } else { + // 2x MSAA source texture sample index. + // Extract the vertical sample index to r0.w. + // r0.x = X pixel position within the source texture + // r0.y = Y sample position within the source texture + // r0.z = sample offset in the EDRAM + // r0.w = vertical sample index within the destination pixel + a.OpAnd(dxbc::Dest::R(0, 0b1000), dxbc::Src::R(0, dxbc::Src::kYYYY), dxbc::Src::LU(1)); + // Convert the 2x MSAA sample index from the guest to Direct3D 10.1+. + // r0.x = X pixel position within the source texture + // r0.y = Y sample position within the source texture + // r0.z = sample offset in the EDRAM + // r0.w = sample index within the source pixel + a.OpMovC(dxbc::Dest::R(0, 0b1000), dxbc::Src::R(0, dxbc::Src::kWWWW), + dxbc::Src::LU(draw_util::GetD3D10SampleIndexForGuest2xMSAA(1, msaa_2x_supported_)), + dxbc::Src::LU(draw_util::GetD3D10SampleIndexForGuest2xMSAA(0, msaa_2x_supported_))); + // Convert sample Y to pixel Y in the source texture to r0.y. + // r0.x = X pixel position within the source texture + // r0.y = Y pixel position within the source texture + // r0.z = sample offset in the EDRAM + // r0.w = sample index within the source pixel + a.OpUShR(dxbc::Dest::R(0, 0b0010), dxbc::Src::R(0, dxbc::Src::kYYYY), dxbc::Src::LU(1)); + } + // Load the source to r1. + // r0.x = X pixel position within the source texture if stencil is needed + // r0.y = Y pixel position within the source texture if stencil is needed + // r0.z = sample offset in the EDRAM + // r0.w = sample index within the source pixel if stencil is needed + // r1 = source texel value + a.OpLdMS(dxbc::Dest::R(1, (1 << source_component_count) - 1), source_address_src, 0b0011, + dxbc::Src::T(0, 0), dxbc::Src::R(0, dxbc::Src::kWWWW)); + if (key.is_depth) { + // Load the source stencil to r1.y. + // r0.x = free + // r0.y = free + // r0.z = sample offset in the EDRAM + // r0.w = free + // r1.x = source depth value + // r1.y = source stencil value + a.OpLdMS(dxbc::Dest::R(1, 0b0010), source_address_src, 0b0011, dxbc::Src::T(1, 1), + dxbc::Src::R(0, dxbc::Src::kWWWW)); + } + } else { + // Write the LOD index (0) to the register with texture coordinates for + // loading from the single-sampled source texture. + // r0.x = X pixel position within the source texture + // r0.y = Y pixel position within the source texture + // r0.z = sample offset in the EDRAM + // r0.w = LOD for the texture load (zero) + a.OpMov(dxbc::Dest::R(0, 0b1000), dxbc::Src::LF(0.0f)); + // Load the source to r1. + // r0.x = X pixel position within the source texture if stencil is needed + // r0.y = Y pixel position within the source texture if stencil is needed + // r0.z = sample offset in the EDRAM + // r0.w = LOD for the texture load (zero) + // r1 = source texel value + a.OpLd(dxbc::Dest::R(1, (1 << source_component_count) - 1), source_address_src, 0b1011, + dxbc::Src::T(0, 0)); + if (key.is_depth) { + // Load the source stencil to r1.y. + // r0.x = free + // r0.y = free + // r0.z = sample offset in the EDRAM + // r0.w = free + // r1.x = source depth value + // r1.y = source stencil value + a.OpLd(dxbc::Dest::R(1, 0b0010), source_address_src, 0b1011, dxbc::Src::T(1, 1)); + } + } + + // Pack in the needed format, writing the result to r1.x for 32bpp or r1.xy + // for 64bpp. + // r0.xyw are usable as temporary storage. + if (key.is_depth) { + switch (key.GetDepthFormat()) { + case xenos::DepthRenderTargetFormat::kD24S8: + // Round to the nearest even integer. This seems to be the correct + // conversion, adding +0.5 and rounding towards zero results in red + // instead of black in the 4D5307E6 clear shader. + a.OpMul(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(1, dxbc::Src::kXXXX), + dxbc::Src::LF(float(0xFFFFFF))); + a.OpRoundNE(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(1, dxbc::Src::kXXXX)); + a.OpFToU(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(1, dxbc::Src::kXXXX)); + break; + case xenos::DepthRenderTargetFormat::kD24FS8: + // Convert to [0, 2) float24 from [0, 1) float32, using r0.x as + // temporary. + // When converting the depth in pixel shaders, it's always exact, + // truncating not to insert additional rounding instructions. + DxbcShaderTranslator::PreClampedDepthTo20e4( + a, 1, 0, 1, 0, 0, 0, !depth_float24_convert_in_pixel_shader() && depth_float24_round(), + true); + break; + } + // Combine 24-bit depth and stencil into r1.x. + a.OpBFI(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(24), dxbc::Src::LU(8), + dxbc::Src::R(1, dxbc::Src::kXXXX), dxbc::Src::R(1, dxbc::Src::kYYYY)); + } else { + switch (key.GetColorFormat()) { + case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA: + // 8_8_8_8_GAMMA is represented by linear stored in + // R16G16B16A16_UNORM. + assert_false(source_is_uint); + for (uint32_t i = 0; i < 3; ++i) { + DxbcShaderTranslator::PreSaturatedLinearToPWLGamma(a, 1, i, 1, i, 0, 0, 0, 1); + } + a.OpMAd(dxbc::Dest::R(1), dxbc::Src::R(1), dxbc::Src::LF(255.0f), dxbc::Src::LF(0.5f)); + a.OpFToU(dxbc::Dest::R(1), dxbc::Src::R(1)); + for (uint32_t i = 1; i < 4; ++i) { + a.OpBFI(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(8), dxbc::Src::LU(i * 8), + dxbc::Src::R(1).Select(i), dxbc::Src::R(1, dxbc::Src::kXXXX)); + } + break; + case xenos::ColorRenderTargetFormat::k_8_8_8_8: + if (!source_is_uint) { + a.OpMAd(dxbc::Dest::R(1), dxbc::Src::R(1), dxbc::Src::LF(255.0f), dxbc::Src::LF(0.5f)); + a.OpFToU(dxbc::Dest::R(1), dxbc::Src::R(1)); + } + for (uint32_t i = 1; i < 4; ++i) { + a.OpBFI(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(8), dxbc::Src::LU(i * 8), + dxbc::Src::R(1).Select(i), dxbc::Src::R(1, dxbc::Src::kXXXX)); + } + break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: + if (!source_is_uint) { + a.OpMAd(dxbc::Dest::R(1), dxbc::Src::R(1), dxbc::Src::LF(1023.0f, 1023.0f, 1023.0f, 3.0f), + dxbc::Src::LF(0.5f)); + a.OpFToU(dxbc::Dest::R(1), dxbc::Src::R(1)); + } + for (uint32_t i = 1; i < 4; ++i) { + a.OpBFI(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(i == 3 ? 2 : 10), dxbc::Src::LU(i * 10), + dxbc::Src::R(1).Select(i), dxbc::Src::R(1, dxbc::Src::kXXXX)); + } + break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16: + // Float16 has a wider range for both color and alpha, also NaNs. + // Color - clamp and convert. + // Convert red in r1.x to the result register r1.x - the same, but + // UnclampedFloat32To7e3 allows that - using r0.x as a temporary. + DxbcShaderTranslator::UnclampedFloat32To7e3(a, 1, 0, 1, 0, 0, 0); + for (uint32_t i = 1; i < 3; ++i) { + // Convert green and blue to a temporary register r0.x using r0.y + // as an internal temporary, then insert them into the result in + // r1.x. + DxbcShaderTranslator::UnclampedFloat32To7e3(a, 0, 0, 1, i, 0, 1); + a.OpBFI(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(10), dxbc::Src::LU(i * 10), + dxbc::Src::R(0, dxbc::Src::kXXXX), dxbc::Src::R(1, dxbc::Src::kXXXX)); + } + // Alpha - saturate and convert. + a.OpMov(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(1, dxbc::Src::kWWWW), true); + a.OpMAd(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(1, dxbc::Src::kWWWW), dxbc::Src::LF(3.0f), + dxbc::Src::LF(0.5f)); + a.OpFToU(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(1, dxbc::Src::kWWWW)); + a.OpBFI(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(2), dxbc::Src::LU(30), + dxbc::Src::R(1, dxbc::Src::kWWWW), dxbc::Src::R(1, dxbc::Src::kXXXX)); + break; + case xenos::ColorRenderTargetFormat::k_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_FLOAT: + assert_true(source_is_uint); + a.OpBFI(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(16), dxbc::Src::LU(16), + dxbc::Src::R(1, dxbc::Src::kYYYY), dxbc::Src::R(1, dxbc::Src::kXXXX)); + break; + case xenos::ColorRenderTargetFormat::k_16_16_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT: + assert_true(source_is_uint); + a.OpBFI(dxbc::Dest::R(1, 0b0011), dxbc::Src::LU(16), dxbc::Src::LU(16), + dxbc::Src::R(1, 0b1101), dxbc::Src::R(1, 0b1000)); + break; + case xenos::ColorRenderTargetFormat::k_32_FLOAT: + case xenos::ColorRenderTargetFormat::k_32_32_FLOAT: + assert_true(source_is_uint); + // Already has the needed representation. + break; + } + } + + // Write the sample to the destination address stored in r0.z. + a.OpStoreUAVTyped(dxbc::Dest::U(0, 0), dxbc::Src::R(0, dxbc::Src::kZZZZ), 1, + dxbc::Src::R(1, format_is_64bpp ? 0b0100 : dxbc::Src::kXXXX)); + + a.OpRet(); + + // Write the shader program length in dwords. + built_shader_[shex_position_dwords + 1] = uint32_t(built_shader_.size()) - shex_position_dwords; + + { + auto& blob_header = + *reinterpret_cast(built_shader_.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kShaderEx; + blob_position_dwords = uint32_t(built_shader_.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + built_shader_[blob_offset_position_dwords++]; + } + + // *************************************************************************** + // Statistics + // *************************************************************************** + + built_shader_[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + uint32_t stat_position_dwords = blob_position_dwords + kBlobHeaderSizeDwords; + built_shader_.resize(stat_position_dwords + sizeof(dxbc::Statistics) / sizeof(uint32_t)); + std::memcpy(built_shader_.data() + stat_position_dwords, &stat, sizeof(dxbc::Statistics)); + { + auto& blob_header = + *reinterpret_cast(built_shader_.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kStatistics; + blob_position_dwords = uint32_t(built_shader_.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + built_shader_[blob_offset_position_dwords++]; + } + + // *************************************************************************** + // Container header + // *************************************************************************** + + uint32_t built_shader_size_bytes = uint32_t(built_shader_.size() * sizeof(uint32_t)); + { + auto& container_header = *reinterpret_cast(built_shader_.data()); + container_header.InitializeIdentification(); + container_header.size_bytes = built_shader_size_bytes; + container_header.blob_count = kBlobCount; + CalculateDXBCChecksum(reinterpret_cast(built_shader_.data()), + static_cast(built_shader_size_bytes), + reinterpret_cast(&container_header.hash)); + } + + // *************************************************************************** + // Pipeline + // *************************************************************************** + ID3D12PipelineState* pipeline = ui::d3d12::util::CreateComputePipeline( + command_processor_.GetD3D12Provider().GetDevice(), built_shader_.data(), + built_shader_size_bytes, + key.is_depth ? dump_root_signature_depth_ : dump_root_signature_color_); + const char* format_name = key.is_depth + ? xenos::GetDepthRenderTargetFormatName(key.GetDepthFormat()) + : xenos::GetColorRenderTargetFormatName(key.GetColorFormat()); + if (pipeline) { + std::u16string pipeline_name = rex::string::to_utf16( + fmt::format("RT Dump {} {}xMSAA", format_name, uint32_t(1) << uint32_t(key.msaa_samples))); + pipeline->SetName(reinterpret_cast(pipeline_name.c_str())); + } else { + REXGPU_ERROR( + "D3D12RenderTargetCache: Failed to create a render target dumping " + "pipeline for {}-sample render targets with format {}", + uint32_t(1) << uint32_t(key.msaa_samples), format_name); + } + // Even if creation fails, still store the null pointer not to try to create + // again. + dump_pipelines_.emplace(key, pipeline); + return pipeline; +} + +ID3D12PipelineState* D3D12RenderTargetCache::GetOrCreateDirectResolvePipeline( + DirectResolvePipelineKey key) { + auto pipeline_it = direct_resolve_pipelines_.find(key); + if (pipeline_it != direct_resolve_pipelines_.end()) { + return pipeline_it->second; + } + ID3D12PipelineState* pipeline = nullptr; + // Until dedicated direct host RT -> shared memory shaders are added, reuse + // the resolve copy pipelines to keep all resolve shader modes wired for the + // direct preflight path. + size_t copy_shader_index = size_t(key.copy_shader); + if (copy_shader_index < size_t(draw_util::ResolveCopyShaderIndex::kCount)) { + pipeline = resolve_copy_pipelines_[copy_shader_index]; + } + direct_resolve_pipelines_.emplace(key, pipeline); + return pipeline; +} + +bool D3D12RenderTargetCache::TryResolveCopyDirectly(const draw_util::ResolveInfo& resolve_info, + draw_util::ResolveCopyShaderIndex copy_shader, + bool draw_resolution_scaled) { + ++direct_resolve_attempt_count_; + (void)copy_shader; + (void)draw_resolution_scaled; + if (!direct_resolve_root_signature_color_ || !direct_resolve_root_signature_depth_) { + return false; + } + + uint32_t dump_base; + uint32_t dump_row_length_used; + uint32_t dump_rows; + uint32_t dump_pitch; + resolve_info.GetCopyEdramTileSpan(dump_base, dump_row_length_used, dump_rows, dump_pitch); + GetResolveCopyDispatchesToDump(dump_base, dump_row_length_used, dump_rows, dump_pitch, + dump_rectangles_, direct_resolve_dispatches_); + if (direct_resolve_dispatches_.empty()) { + return false; + } + + for (const ResolveCopyDumpRectangle& rectangle : dump_rectangles_) { + const auto* render_target = static_cast(rectangle.render_target); + if (render_target == nullptr) { + return false; + } + DumpPipelineKey dump_pipeline_key; + dump_pipeline_key.msaa_samples = render_target->key().msaa_samples; + dump_pipeline_key.resource_format = render_target->key().resource_format; + dump_pipeline_key.is_depth = render_target->key().is_depth; + if (!GetOrCreateDumpPipeline(dump_pipeline_key)) { + return false; + } + DirectResolvePipelineKey direct_pipeline_key; + direct_pipeline_key.dump_pipeline_key = dump_pipeline_key; + direct_pipeline_key.copy_shader = copy_shader; + direct_pipeline_key.draw_resolution_scaled = draw_resolution_scaled; + if (!GetOrCreateDirectResolvePipeline(direct_pipeline_key)) { + return false; + } + } + + // Dedicated direct resolve dispatches are staged behind the same preflight; + // keep using the existing dump path until source-image direct shaders land. + return DumpRenderTargets(dump_base, dump_row_length_used, dump_rows, dump_pitch); +} + +bool D3D12RenderTargetCache::DumpRenderTargets(uint32_t dump_base, uint32_t dump_row_length_used, + uint32_t dump_rows, uint32_t dump_pitch) { + assert_true(GetPath() == Path::kHostRenderTargets); + + GetResolveCopyRectanglesToDump(dump_base, dump_row_length_used, dump_rows, dump_pitch, + dump_rectangles_); + if (dump_rectangles_.empty()) { + return true; + } + + // Clear previously set temporary indices. + for (const ResolveCopyDumpRectangle& rectangle : dump_rectangles_) { + auto& d3d12_rt = *static_cast(rectangle.render_target); + d3d12_rt.SetTemporarySortIndex(UINT32_MAX); + d3d12_rt.SetTemporarySRVDescriptorIndex(UINT32_MAX); + d3d12_rt.SetTemporarySRVDescriptorIndexStencil(UINT32_MAX); + } + // Gather all needed barriers and info needed to create descriptors and to + // sort the invocations. + TransitionEdramBuffer(D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + dump_invocations_.clear(); + dump_invocations_.reserve(dump_rectangles_.size()); + current_temporary_descriptors_cpu_.clear(); + bool any_sources_32bpp_64bpp[2] = {}; + uint32_t rt_sort_index = 0; + for (const ResolveCopyDumpRectangle& rectangle : dump_rectangles_) { + auto& d3d12_rt = *static_cast(rectangle.render_target); + command_processor_.PushTransitionBarrier( + d3d12_rt.resource(), + d3d12_rt.SetResourceState(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE), + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + if (d3d12_rt.temporary_sort_index() == UINT32_MAX) { + d3d12_rt.SetTemporarySortIndex(rt_sort_index++); + } + if (d3d12_rt.temporary_srv_descriptor_index() == UINT32_MAX) { + d3d12_rt.SetTemporarySRVDescriptorIndex(uint32_t(current_temporary_descriptors_cpu_.size())); + current_temporary_descriptors_cpu_.push_back(d3d12_rt.descriptor_srv().GetHandle()); + } + RenderTargetKey rt_key = d3d12_rt.key(); + if (rt_key.is_depth && d3d12_rt.temporary_srv_descriptor_index_stencil() == UINT32_MAX) { + d3d12_rt.SetTemporarySRVDescriptorIndexStencil( + uint32_t(current_temporary_descriptors_cpu_.size())); + current_temporary_descriptors_cpu_.push_back(d3d12_rt.descriptor_srv_stencil().GetHandle()); + } + any_sources_32bpp_64bpp[size_t(rt_key.Is64bpp())] = true; + DumpPipelineKey pipeline_key; + pipeline_key.msaa_samples = rt_key.msaa_samples; + pipeline_key.resource_format = rt_key.resource_format; + pipeline_key.is_depth = rt_key.is_depth; + dump_invocations_.emplace_back(rectangle, pipeline_key); + } + // 32bpp and 64bpp. + size_t edram_uav_indices[2] = {SIZE_MAX, SIZE_MAX}; + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + if (!bindless_resources_used_) { + if (any_sources_32bpp_64bpp[0]) { + edram_uav_indices[0] = current_temporary_descriptors_cpu_.size(); + current_temporary_descriptors_cpu_.push_back(provider.OffsetViewDescriptor( + edram_buffer_descriptor_heap_start_, uint32_t(EdramBufferDescriptorIndex::kR32UintUAV))); + } + if (any_sources_32bpp_64bpp[1]) { + edram_uav_indices[1] = current_temporary_descriptors_cpu_.size(); + current_temporary_descriptors_cpu_.push_back( + provider.OffsetViewDescriptor(edram_buffer_descriptor_heap_start_, + uint32_t(EdramBufferDescriptorIndex::kR32G32UintUAV))); + } + } + + // Copy source descriptors to a shader-visible heap. + ID3D12Device* device = provider.GetDevice(); + uint32_t descriptor_count = uint32_t(current_temporary_descriptors_cpu_.size()); + current_temporary_descriptors_gpu_.resize(descriptor_count); + if (!command_processor_.RequestOneUseSingleViewDescriptors( + descriptor_count, current_temporary_descriptors_gpu_.data())) { + return false; + } + for (uint32_t i = 0; i < descriptor_count; ++i) { + device->CopyDescriptorsSimple(1, current_temporary_descriptors_gpu_[i].first, + current_temporary_descriptors_cpu_[i], + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + } + + // Sort the invocations to reduce context and binding switches. + std::sort(dump_invocations_.begin(), dump_invocations_.end()); + + // Dump the render targets. + DeferredCommandList& command_list = command_processor_.GetDeferredCommandList(); + ID3D12RootSignature* last_root_signature = nullptr; + uint32_t root_parameters_set = 0; + uint32_t last_descriptor_index_source = UINT32_MAX; + uint32_t last_descriptor_index_stencil = UINT32_MAX; + bool last_edram_uav_is_64bpp = false; + DumpOffsets last_offsets; + DumpPitches last_pitches; + bool all_pipelines_available = true; + for (const DumpInvocation& invocation : dump_invocations_) { + const ResolveCopyDumpRectangle& rectangle = invocation.rectangle; + auto& d3d12_rt = *static_cast(rectangle.render_target); + RenderTargetKey rt_key = d3d12_rt.key(); + DumpPipelineKey pipeline_key = invocation.pipeline_key; + ID3D12PipelineState* pipeline = GetOrCreateDumpPipeline(pipeline_key); + if (!pipeline) { + all_pipelines_available = false; + continue; + } + command_processor_.SetExternalPipeline(pipeline); + + ID3D12RootSignature* root_signature = + pipeline_key.is_depth ? dump_root_signature_depth_ : dump_root_signature_color_; + if (last_root_signature != root_signature) { + last_root_signature = root_signature; + command_list.D3DSetComputeRootSignature(root_signature); + root_parameters_set = 0; + } + + DumpRootParameter root_parameter_edram = + pipeline_key.is_depth ? kDumpRootParameterDepthEdram : kDumpRootParameterColorEdram; + uint32_t root_parameter_edram_bit = uint32_t(1) << root_parameter_edram; + bool format_is_64bpp = rt_key.Is64bpp(); + if (last_edram_uav_is_64bpp != format_is_64bpp) { + last_edram_uav_is_64bpp = format_is_64bpp; + root_parameters_set &= ~root_parameter_edram_bit; + } + if (!(root_parameters_set & root_parameter_edram_bit)) { + D3D12_GPU_DESCRIPTOR_HANDLE descriptor_handle_edram; + if (bindless_resources_used_) { + descriptor_handle_edram = + command_processor_ + .GetEdramUintPow2BindlessUAVHandlePair(2 + uint32_t(last_edram_uav_is_64bpp)) + .second; + } else { + assert_true(edram_uav_indices[size_t(last_edram_uav_is_64bpp)] != SIZE_MAX); + descriptor_handle_edram = + current_temporary_descriptors_gpu_[edram_uav_indices[size_t(last_edram_uav_is_64bpp)]] + .second; + } + command_list.D3DSetComputeRootDescriptorTable(root_parameter_edram, descriptor_handle_edram); + root_parameters_set |= root_parameter_edram_bit; + } + + DumpRootParameter root_parameter_pitches = + pipeline_key.is_depth ? kDumpRootParameterDepthPitches : kDumpRootParameterColorPitches; + uint32_t root_parameter_pitches_bit = uint32_t(1) << root_parameter_pitches; + DumpPitches pitches; + pitches.dest_pitch = dump_pitch; + pitches.source_pitch = rt_key.GetPitchTiles(); + if (last_pitches != pitches) { + last_pitches = pitches; + root_parameters_set &= ~root_parameter_pitches_bit; + } + if (!(root_parameters_set & root_parameter_pitches_bit)) { + command_list.D3DSetComputeRoot32BitConstants( + root_parameter_pitches, sizeof(last_pitches) / sizeof(uint32_t), &last_pitches, 0); + root_parameters_set |= root_parameter_pitches_bit; + } + + if (pipeline_key.is_depth) { + constexpr uint32_t kDumpRootParameterDepthStencilBit = uint32_t(1) + << kDumpRootParameterDepthStencil; + uint32_t descriptor_index_stencil = d3d12_rt.temporary_srv_descriptor_index_stencil(); + assert_true(descriptor_index_stencil != UINT32_MAX); + if (last_descriptor_index_stencil != descriptor_index_stencil) { + last_descriptor_index_stencil = descriptor_index_stencil; + root_parameters_set &= ~kDumpRootParameterDepthStencilBit; + } + if (!(root_parameters_set & kDumpRootParameterDepthStencilBit)) { + command_list.D3DSetComputeRootDescriptorTable( + kDumpRootParameterDepthStencil, + current_temporary_descriptors_gpu_[last_descriptor_index_stencil].second); + root_parameters_set |= kDumpRootParameterDepthStencilBit; + } + } + + constexpr uint32_t kDumpRootParameterSourceBit = uint32_t(1) << kDumpRootParameterSource; + uint32_t descriptor_index_source = d3d12_rt.temporary_srv_descriptor_index(); + assert_true(descriptor_index_source != UINT32_MAX); + if (last_descriptor_index_source != descriptor_index_source) { + last_descriptor_index_source = descriptor_index_source; + root_parameters_set &= ~kDumpRootParameterSourceBit; + } + if (!(root_parameters_set & kDumpRootParameterSourceBit)) { + command_list.D3DSetComputeRootDescriptorTable( + kDumpRootParameterSource, + current_temporary_descriptors_gpu_[last_descriptor_index_source].second); + root_parameters_set |= kDumpRootParameterSourceBit; + } + + constexpr uint32_t kDumpRootParameterOffsetsBit = uint32_t(1) << kDumpRootParameterOffsets; + DumpOffsets offsets; + offsets.source_base_tiles = rt_key.base_tiles; + ResolveCopyDumpRectangle::Dispatch dispatches[ResolveCopyDumpRectangle::kMaxDispatches]; + uint32_t dispatch_count = rectangle.GetDispatches(dump_pitch, dump_row_length_used, dispatches); + for (uint32_t i = 0; i < dispatch_count; ++i) { + const ResolveCopyDumpRectangle::Dispatch& dispatch = dispatches[i]; + offsets.dispatch_first_tile = dump_base + dispatch.offset; + if (last_offsets != offsets) { + last_offsets = offsets; + root_parameters_set &= ~kDumpRootParameterOffsetsBit; + } + if (!(root_parameters_set & kDumpRootParameterOffsetsBit)) { + command_list.D3DSetComputeRoot32BitConstants( + kDumpRootParameterOffsets, sizeof(last_offsets) / sizeof(uint32_t), &last_offsets, 0); + root_parameters_set |= kDumpRootParameterOffsetsBit; + } + command_processor_.SubmitBarriers(); + // Processing 40 x 16 x scale samples per dispatch (a 32bpp tile in two + // dispatches at 1x1 scale, 64bpp in one dispatch). + command_list.D3DDispatch((dispatch.width_tiles * draw_resolution_scale_x()) + << uint32_t(!format_is_64bpp), + dispatch.height_tiles * draw_resolution_scale_y(), 1); + } + MarkEdramBufferModified(); + } + return all_pipelines_available; +} + +} // namespace rex::graphics::d3d12 diff --git a/src/graphics/d3d12/shader.cpp b/src/graphics/d3d12/shader.cpp new file mode 100644 index 0000000..e581616 --- /dev/null +++ b/src/graphics/d3d12/shader.cpp @@ -0,0 +1,100 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2018 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace rex::graphics::d3d12 { + +D3D12Shader::D3D12Shader(xenos::ShaderType shader_type, uint64_t ucode_data_hash, + const uint32_t* ucode_dwords, size_t ucode_dword_count, + std::endian ucode_source_endian) + : DxbcShader(shader_type, ucode_data_hash, ucode_dwords, ucode_dword_count, + ucode_source_endian) {} + +void D3D12Shader::D3D12Translation::DisassembleDxbcAndDxil(const ui::d3d12::D3D12Provider& provider, + bool disassemble_dxbc, + IDxbcConverter* dxbc_converter, + IDxcUtils* dxc_utils, + IDxcCompiler* dxc_compiler) { + std::string disassembly; + bool is_first_disassembly = true; + if (disassemble_dxbc) { + ID3DBlob* dxbc_disassembly; + if (SUCCEEDED(provider.Disassemble( + translated_binary().data(), translated_binary().size(), + D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING | D3D_DISASM_ENABLE_INSTRUCTION_OFFSET, nullptr, + &dxbc_disassembly))) { + assert_true(is_first_disassembly); + is_first_disassembly = false; + disassembly.append(reinterpret_cast(dxbc_disassembly->GetBufferPointer())); + dxbc_disassembly->Release(); + } else { + REXGPU_ERROR("Failed to disassemble DXBC shader {:016X}", shader().ucode_data_hash()); + } + } + if (dxbc_converter && dxc_utils && dxc_compiler) { + void* dxil; + UINT32 dxil_size; + if (SUCCEEDED(dxbc_converter->Convert(translated_binary().data(), + UINT32(translated_binary().size()), nullptr, &dxil, + &dxil_size, nullptr)) && + dxil != nullptr) { + IDxcBlobEncoding* dxil_blob; + if (SUCCEEDED(dxc_utils->CreateBlobFromPinned(dxil, dxil_size, DXC_CP_ACP, &dxil_blob))) { + IDxcBlobEncoding* dxil_disassembly; + bool dxil_disassembled = SUCCEEDED(dxc_compiler->Disassemble(dxil_blob, &dxil_disassembly)); + dxil_blob->Release(); + CoTaskMemFree(dxil); + if (dxil_disassembled) { + IDxcBlobUtf8* dxil_disassembly_utf8; + bool dxil_disassembly_got_utf8 = + SUCCEEDED(dxc_utils->GetBlobAsUtf8(dxil_disassembly, &dxil_disassembly_utf8)); + dxil_disassembly->Release(); + if (dxil_disassembly_got_utf8) { + if (!is_first_disassembly) { + disassembly.append("\n\n"); + } + is_first_disassembly = false; + disassembly.append( + reinterpret_cast(dxil_disassembly_utf8->GetStringPointer())); + dxil_disassembly_utf8->Release(); + } else { + REXGPU_ERROR("Failed to get DXIL shader {:016X} disassembly as UTF-8", + shader().ucode_data_hash()); + } + } else { + REXGPU_ERROR("Failed to disassemble DXIL shader {:016X}", shader().ucode_data_hash()); + } + } else { + REXGPU_ERROR("Failed to create a blob with DXIL shader {:016X}", + shader().ucode_data_hash()); + CoTaskMemFree(dxil); + } + } else { + REXGPU_ERROR("Failed to convert shader {:016X} to DXIL", shader().ucode_data_hash()); + } + } + set_host_disassembly(std::move(disassembly)); +} + +Shader::Translation* D3D12Shader::CreateTranslationInstance(uint64_t modification) { + return new D3D12Translation(*this, modification); +} + +} // namespace rex::graphics::d3d12 diff --git a/src/graphics/d3d12/shared_memory.cpp b/src/graphics/d3d12/shared_memory.cpp new file mode 100644 index 0000000..8637a62 --- /dev/null +++ b/src/graphics/d3d12/shared_memory.cpp @@ -0,0 +1,407 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(d3d12_tiled_shared_memory, true, "GPU/D3D12", + "Use tiled shared memory on D3D12") + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +namespace rex::graphics::d3d12 { + +D3D12SharedMemory::D3D12SharedMemory(D3D12CommandProcessor& command_processor, + memory::Memory& memory, TraceWriter& trace_writer) + : SharedMemory(memory), command_processor_(command_processor), trace_writer_(trace_writer) {} + +D3D12SharedMemory::~D3D12SharedMemory() { + Shutdown(true); +} + +bool D3D12SharedMemory::Initialize() { + InitializeCommon(); + + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + + D3D12_RESOURCE_DESC buffer_desc; + ui::d3d12::util::FillBufferResourceDesc(buffer_desc, kBufferSize, + D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); + buffer_state_ = D3D12_RESOURCE_STATE_COPY_DEST; + if (REXCVAR_GET(d3d12_tiled_shared_memory) && + provider.GetTiledResourcesTier() != D3D12_TILED_RESOURCES_TIER_NOT_SUPPORTED && + !provider.GetGraphicsAnalysis()) { + if (FAILED(device->CreateReservedResource(&buffer_desc, buffer_state_, nullptr, + IID_PPV_ARGS(&buffer_)))) { + REXGPU_ERROR("Shared memory: Failed to create the {} MB tiled buffer", kBufferSize >> 20); + Shutdown(); + return false; + } + static_assert(D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES == (1 << 16)); + InitializeSparseHostGpuMemory( + std::max(kHostGpuMemoryOptimalSparseAllocationLog2, uint32_t(16))); + } else { + REXGPU_INFO( + "Direct3D 12 tiled resources are not used for shared memory " + "emulation - video memory usage may increase significantly " + "because a full {} MB buffer will be created", + kBufferSize >> 20); + if (provider.GetGraphicsAnalysis()) { + // As of October 8th, 2018, PIX doesn't support tiled buffers. + // FIXME(Triang3l): Re-enable tiled resources with PIX once fixed. + REXGPU_INFO( + "This is caused by PIX being attached, which doesn't support tiled " + "resources yet."); + } + if (FAILED(device->CreateCommittedResource(&ui::d3d12::util::kHeapPropertiesDefault, + provider.GetHeapFlagCreateNotZeroed(), &buffer_desc, + buffer_state_, nullptr, IID_PPV_ARGS(&buffer_)))) { + REXGPU_ERROR("Shared memory: Failed to create the {} MB buffer", kBufferSize >> 20); + Shutdown(); + return false; + } + } + buffer_gpu_address_ = buffer_->GetGPUVirtualAddress(); + buffer_uav_writes_commit_needed_ = false; + + D3D12_DESCRIPTOR_HEAP_DESC buffer_descriptor_heap_desc; + buffer_descriptor_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + buffer_descriptor_heap_desc.NumDescriptors = uint32_t(BufferDescriptorIndex::kCount); + buffer_descriptor_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + buffer_descriptor_heap_desc.NodeMask = 0; + if (FAILED(device->CreateDescriptorHeap(&buffer_descriptor_heap_desc, + IID_PPV_ARGS(&buffer_descriptor_heap_)))) { + REXGPU_ERROR("Shared memory: Failed to create the descriptor heap for buffer views"); + Shutdown(); + return false; + } + buffer_descriptor_heap_start_ = buffer_descriptor_heap_->GetCPUDescriptorHandleForHeapStart(); + ui::d3d12::util::CreateBufferRawSRV( + device, + provider.OffsetViewDescriptor(buffer_descriptor_heap_start_, + uint32_t(BufferDescriptorIndex::kRawSRV)), + buffer_, kBufferSize); + ui::d3d12::util::CreateBufferTypedSRV( + device, + provider.OffsetViewDescriptor(buffer_descriptor_heap_start_, + uint32_t(BufferDescriptorIndex::kR32UintSRV)), + buffer_, DXGI_FORMAT_R32_UINT, kBufferSize >> 2); + ui::d3d12::util::CreateBufferTypedSRV( + device, + provider.OffsetViewDescriptor(buffer_descriptor_heap_start_, + uint32_t(BufferDescriptorIndex::kR32G32UintSRV)), + buffer_, DXGI_FORMAT_R32G32_UINT, kBufferSize >> 3); + ui::d3d12::util::CreateBufferTypedSRV( + device, + provider.OffsetViewDescriptor(buffer_descriptor_heap_start_, + uint32_t(BufferDescriptorIndex::kR32G32B32A32UintSRV)), + buffer_, DXGI_FORMAT_R32G32B32A32_UINT, kBufferSize >> 4); + ui::d3d12::util::CreateBufferRawUAV( + device, + provider.OffsetViewDescriptor(buffer_descriptor_heap_start_, + uint32_t(BufferDescriptorIndex::kRawUAV)), + buffer_, kBufferSize); + ui::d3d12::util::CreateBufferTypedUAV( + device, + provider.OffsetViewDescriptor(buffer_descriptor_heap_start_, + uint32_t(BufferDescriptorIndex::kR32UintUAV)), + buffer_, DXGI_FORMAT_R32_UINT, kBufferSize >> 2); + ui::d3d12::util::CreateBufferTypedUAV( + device, + provider.OffsetViewDescriptor(buffer_descriptor_heap_start_, + uint32_t(BufferDescriptorIndex::kR32G32UintUAV)), + buffer_, DXGI_FORMAT_R32G32_UINT, kBufferSize >> 3); + ui::d3d12::util::CreateBufferTypedUAV( + device, + provider.OffsetViewDescriptor(buffer_descriptor_heap_start_, + uint32_t(BufferDescriptorIndex::kR32G32B32A32UintUAV)), + buffer_, DXGI_FORMAT_R32G32B32A32_UINT, kBufferSize >> 4); + + upload_buffer_pool_ = std::make_unique( + provider, rex::align(ui::d3d12::D3D12UploadBufferPool::kDefaultPageSize, + size_t(1) << page_size_log2())); + + return true; +} + +void D3D12SharedMemory::Shutdown(bool from_destructor) { + ResetTraceDownload(); + + upload_buffer_pool_.reset(); + + ui::d3d12::util::ReleaseAndNull(buffer_descriptor_heap_); + + // First free the buffer to detach it from the heaps. + ui::d3d12::util::ReleaseAndNull(buffer_); + + for (ID3D12Heap* heap : buffer_tiled_heaps_) { + heap->Release(); + } + buffer_tiled_heaps_.clear(); + + // If calling from the destructor, the SharedMemory destructor will call + // ShutdownCommon. + if (!from_destructor) { + ShutdownCommon(); + } +} + +void D3D12SharedMemory::ClearCache() { + SharedMemory::ClearCache(); + + upload_buffer_pool_->ClearCache(); +} + +void D3D12SharedMemory::CompletedSubmissionUpdated() { + upload_buffer_pool_->Reclaim(command_processor_.GetCompletedSubmission()); +} + +void D3D12SharedMemory::BeginSubmission() { + // ExecuteCommandLists is a full UAV barrier. + buffer_uav_writes_commit_needed_ = false; +} + +void D3D12SharedMemory::CommitUAVWritesAndTransitionBuffer(D3D12_RESOURCE_STATES new_state) { + if (buffer_state_ == new_state) { + if (new_state == D3D12_RESOURCE_STATE_UNORDERED_ACCESS && buffer_uav_writes_commit_needed_) { + command_processor_.PushUAVBarrier(buffer_); + buffer_uav_writes_commit_needed_ = false; + } + return; + } + command_processor_.PushTransitionBarrier(buffer_, buffer_state_, new_state); + buffer_state_ = new_state; + // "UAV -> anything" transition commits the writes implicitly. + buffer_uav_writes_commit_needed_ = false; +} + +void D3D12SharedMemory::WriteRawSRVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle) { + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + device->CopyDescriptorsSimple( + 1, handle, + provider.OffsetViewDescriptor(buffer_descriptor_heap_start_, + uint32_t(BufferDescriptorIndex::kRawSRV)), + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); +} + +void D3D12SharedMemory::WriteRawUAVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle) { + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + device->CopyDescriptorsSimple( + 1, handle, + provider.OffsetViewDescriptor(buffer_descriptor_heap_start_, + uint32_t(BufferDescriptorIndex::kRawUAV)), + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); +} + +void D3D12SharedMemory::WriteUintPow2SRVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle, + uint32_t element_size_bytes_pow2) { + BufferDescriptorIndex descriptor_index; + switch (element_size_bytes_pow2) { + case 2: + descriptor_index = BufferDescriptorIndex::kR32UintSRV; + break; + case 3: + descriptor_index = BufferDescriptorIndex::kR32G32UintSRV; + break; + case 4: + descriptor_index = BufferDescriptorIndex::kR32G32B32A32UintSRV; + break; + default: + assert_unhandled_case(element_size_bytes_pow2); + return; + } + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + device->CopyDescriptorsSimple( + 1, handle, + provider.OffsetViewDescriptor(buffer_descriptor_heap_start_, uint32_t(descriptor_index)), + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); +} + +void D3D12SharedMemory::WriteUintPow2UAVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle, + uint32_t element_size_bytes_pow2) { + BufferDescriptorIndex descriptor_index; + switch (element_size_bytes_pow2) { + case 2: + descriptor_index = BufferDescriptorIndex::kR32UintUAV; + break; + case 3: + descriptor_index = BufferDescriptorIndex::kR32G32UintUAV; + break; + case 4: + descriptor_index = BufferDescriptorIndex::kR32G32B32A32UintUAV; + break; + default: + assert_unhandled_case(element_size_bytes_pow2); + return; + } + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + device->CopyDescriptorsSimple( + 1, handle, + provider.OffsetViewDescriptor(buffer_descriptor_heap_start_, uint32_t(descriptor_index)), + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); +} + +bool D3D12SharedMemory::InitializeTraceSubmitDownloads() { + ResetTraceDownload(); + PrepareForTraceDownload(); + uint32_t download_page_count = trace_download_page_count(); + if (!download_page_count) { + return false; + } + D3D12_RESOURCE_DESC download_buffer_desc; + ui::d3d12::util::FillBufferResourceDesc( + download_buffer_desc, download_page_count << page_size_log2(), D3D12_RESOURCE_FLAG_NONE); + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + if (FAILED(device->CreateCommittedResource(&ui::d3d12::util::kHeapPropertiesReadback, + provider.GetHeapFlagCreateNotZeroed(), + &download_buffer_desc, D3D12_RESOURCE_STATE_COPY_DEST, + nullptr, IID_PPV_ARGS(&trace_download_buffer_)))) { + REXGPU_ERROR( + "Shared memory: Failed to create a {} KB GPU-written memory download " + "buffer for frame tracing", + download_page_count << page_size_log2() >> 10); + ResetTraceDownload(); + return false; + } + auto& command_list = command_processor_.GetDeferredCommandList(); + UseAsCopySource(); + command_processor_.SubmitBarriers(); + uint32_t download_buffer_offset = 0; + for (const auto& download_range : trace_download_ranges()) { + command_list.D3DCopyBufferRegion(trace_download_buffer_, download_buffer_offset, buffer_, + download_range.first, download_range.second); + download_buffer_offset += download_range.second; + } + return true; +} + +void D3D12SharedMemory::InitializeTraceCompleteDownloads() { + if (!trace_download_buffer_) { + return; + } + void* download_mapping; + if (SUCCEEDED(trace_download_buffer_->Map(0, nullptr, &download_mapping))) { + uint32_t download_buffer_offset = 0; + for (const auto& download_range : trace_download_ranges()) { + trace_writer_.WriteMemoryRead( + download_range.first, download_range.second, + reinterpret_cast(download_mapping) + download_buffer_offset); + } + D3D12_RANGE download_write_range = {}; + trace_download_buffer_->Unmap(0, &download_write_range); + } else { + REXGPU_ERROR( + "Shared memory: Failed to map the GPU-written memory download buffer " + "for frame tracing"); + } + ResetTraceDownload(); +} + +void D3D12SharedMemory::ResetTraceDownload() { + ui::d3d12::util::ReleaseAndNull(trace_download_buffer_); + ReleaseTraceDownloadRanges(); +} + +bool D3D12SharedMemory::AllocateSparseHostGpuMemoryRange(uint32_t offset_allocations, + uint32_t length_allocations) { + if (!length_allocations) { + return true; + } + + uint32_t offset_bytes = offset_allocations << host_gpu_memory_sparse_granularity_log2(); + uint32_t length_bytes = length_allocations << host_gpu_memory_sparse_granularity_log2(); + + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + ID3D12CommandQueue* direct_queue = provider.GetDirectQueue(); + + D3D12_HEAP_DESC heap_desc = {}; + heap_desc.SizeInBytes = length_bytes; + heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT; + heap_desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS | provider.GetHeapFlagCreateNotZeroed(); + ID3D12Heap* heap; + if (FAILED(device->CreateHeap(&heap_desc, IID_PPV_ARGS(&heap)))) { + REXGPU_ERROR("Shared memory: Failed to create a tile heap"); + return false; + } + buffer_tiled_heaps_.push_back(heap); + + D3D12_TILED_RESOURCE_COORDINATE region_start_coordinates; + region_start_coordinates.X = offset_bytes / D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES; + region_start_coordinates.Y = 0; + region_start_coordinates.Z = 0; + region_start_coordinates.Subresource = 0; + D3D12_TILE_REGION_SIZE region_size; + region_size.NumTiles = length_bytes / D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES; + region_size.UseBox = FALSE; + D3D12_TILE_RANGE_FLAGS range_flags = D3D12_TILE_RANGE_FLAG_NONE; + UINT heap_range_start_offset = 0; + direct_queue->UpdateTileMappings(buffer_, 1, ®ion_start_coordinates, ®ion_size, heap, 1, + &range_flags, &heap_range_start_offset, ®ion_size.NumTiles, + D3D12_TILE_MAPPING_FLAG_NONE); + command_processor_.NotifyQueueOperationsDoneDirectly(); + return true; +} + +bool D3D12SharedMemory::UploadRanges( + const std::vector>& upload_page_ranges) { + if (upload_page_ranges.empty()) { + return true; + } + CommitUAVWritesAndTransitionBuffer(D3D12_RESOURCE_STATE_COPY_DEST); + command_processor_.SubmitBarriers(); + auto& command_list = command_processor_.GetDeferredCommandList(); + for (auto upload_range : upload_page_ranges) { + uint32_t upload_range_start = upload_range.first; + uint32_t upload_range_length = upload_range.second; + trace_writer_.WriteMemoryRead(upload_range_start << page_size_log2(), + upload_range_length << page_size_log2()); + while (upload_range_length != 0) { + ID3D12Resource* upload_buffer; + size_t upload_buffer_offset, upload_buffer_size; + uint8_t* upload_buffer_mapping = upload_buffer_pool_->RequestPartial( + command_processor_.GetCurrentSubmission(), upload_range_length << page_size_log2(), + size_t(1) << page_size_log2(), &upload_buffer, &upload_buffer_offset, &upload_buffer_size, + nullptr); + if (upload_buffer_mapping == nullptr) { + REXGPU_ERROR("Shared memory: Failed to get an upload buffer"); + return false; + } + MakeRangeValid(upload_range_start << page_size_log2(), uint32_t(upload_buffer_size), false); + std::memcpy(upload_buffer_mapping, + memory().TranslatePhysical(upload_range_start << page_size_log2()), + upload_buffer_size); + command_list.D3DCopyBufferRegion(buffer_, upload_range_start << page_size_log2(), + upload_buffer, UINT64(upload_buffer_offset), + UINT64(upload_buffer_size)); + uint32_t upload_buffer_pages = uint32_t(upload_buffer_size >> page_size_log2()); + upload_range_start += upload_buffer_pages; + upload_range_length -= upload_buffer_pages; + } + } + return true; +} + +} // namespace rex::graphics::d3d12 diff --git a/src/graphics/d3d12/texture_cache.cpp b/src/graphics/d3d12/texture_cache.cpp new file mode 100644 index 0000000..2be0e8e --- /dev/null +++ b/src/graphics/d3d12/texture_cache.cpp @@ -0,0 +1,2207 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::graphics::d3d12 { + +// Generated with `xb buildshaders`. +namespace shaders { +#include "../shaders/bytecode/d3d12_5_1/texture_load_128bpb_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_128bpb_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_16bpb_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_16bpb_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_32bpb_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_32bpb_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_64bpb_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_64bpb_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_8bpb_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_8bpb_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_bgrg8_rgb8_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_bgrg8_rgbg8_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_ctx1_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_depth_float_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_depth_float_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_depth_unorm_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_depth_unorm_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_dxn_rg8_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_dxt1_rgba8_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_dxt3_rgba8_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_dxt3a_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_dxt3aas1111_bgra4_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_dxt5_rgba8_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_dxt5a_r8_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_gbgr8_grgb8_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_gbgr8_rgb8_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_r10g11b11_rgba16_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_r10g11b11_rgba16_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_r10g11b11_rgba16_snorm_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_r10g11b11_rgba16_snorm_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_r11g11b10_rgba16_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_r11g11b10_rgba16_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_r11g11b10_rgba16_snorm_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_r11g11b10_rgba16_snorm_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_r4g4b4a4_b4g4r4a4_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_r4g4b4a4_b4g4r4a4_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_r5g5b5a1_b5g5r5a1_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_r5g5b5a1_b5g5r5a1_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_r5g5b6_b5g6r5_swizzle_rbga_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_r5g5b6_b5g6r5_swizzle_rbga_scaled_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_r5g6b5_b5g6r5_cs.h" +#include "../shaders/bytecode/d3d12_5_1/texture_load_r5g6b5_b5g6r5_scaled_cs.h" +} // namespace shaders + +const D3D12TextureCache::HostFormat D3D12TextureCache::host_formats_[64] = { + // k_1_REVERSE + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_1 + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_8 + {DXGI_FORMAT_R8_TYPELESS, DXGI_FORMAT_R8_UNORM, kLoadShaderIndex8bpb, DXGI_FORMAT_R8_SNORM, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_1_5_5_5 + // Red and blue swapped in the load shader for simplicity. + {DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_B5G5R5A1_UNORM, kLoadShaderIndexR5G5B5A1ToB5G5R5A1, + DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_5_6_5 + // Red and blue swapped in the load shader for simplicity. + {DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_B5G6R5_UNORM, kLoadShaderIndexR5G6B5ToB5G6R5, + DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, + // k_6_5_5 + // On the host, green bits in blue, blue bits in green. + {DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_B5G6R5_UNORM, + kLoadShaderIndexR5G5B6ToB5G6R5WithRBGASwizzle, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, XE_GPU_MAKE_TEXTURE_SWIZZLE(R, B, G, G)}, + // k_8_8_8_8 + {DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndex32bpb, + DXGI_FORMAT_R8G8B8A8_SNORM, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_2_10_10_10 + {DXGI_FORMAT_R10G10B10A2_TYPELESS, DXGI_FORMAT_R10G10B10A2_UNORM, kLoadShaderIndex32bpb, + DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_8_A + {DXGI_FORMAT_R8_TYPELESS, DXGI_FORMAT_R8_UNORM, kLoadShaderIndex8bpb, DXGI_FORMAT_R8_SNORM, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_8_B + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_8_8 + {DXGI_FORMAT_R8G8_TYPELESS, DXGI_FORMAT_R8G8_UNORM, kLoadShaderIndex16bpb, + DXGI_FORMAT_R8G8_SNORM, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_Cr_Y1_Cb_Y0_REP + // Red and blue swapped in the load shader for simplicity. + // TODO(Triang3l): The DXGI_FORMAT_R8G8B8A8_U/SNORM conversion is usable for + // the signed version, separate unsigned and signed load shaders completely + // (as one doesn't need decompression for this format, while another does). + {DXGI_FORMAT_G8R8_G8B8_UNORM, DXGI_FORMAT_G8R8_G8B8_UNORM, kLoadShaderIndexGBGR8ToGRGB8, + DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM, + kLoadShaderIndexGBGR8ToRGB8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, + // k_Y1_Cr_Y0_Cb_REP + // Red and blue swapped in the load shader for simplicity. + // TODO(Triang3l): The DXGI_FORMAT_R8G8B8A8_U/SNORM conversion is usable for + // the signed version, separate unsigned and signed load shaders completely + // (as one doesn't need decompression for this format, while another does). + {DXGI_FORMAT_R8G8_B8G8_UNORM, DXGI_FORMAT_R8G8_B8G8_UNORM, kLoadShaderIndexBGRG8ToRGBG8, + DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM, + kLoadShaderIndexBGRG8ToRGB8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, + // k_16_16_EDRAM + // Not usable as a texture, also has -32...32 range. + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_8_8_8_8_A + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_4_4_4_4 + // Red and blue swapped in the load shader for simplicity. + {DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_B4G4R4A4_UNORM, kLoadShaderIndexRGBA4ToBGRA4, + DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_10_11_11 + {DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM, + kLoadShaderIndexR11G11B10ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM, + kLoadShaderIndexR11G11B10ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, + // k_11_11_10 + {DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM, + kLoadShaderIndexR10G11B11ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM, + kLoadShaderIndexR10G11B11ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, + // k_DXT1 + {DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, kLoadShaderIndex64bpb, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT1ToRGBA8, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_DXT2_3 + {DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, kLoadShaderIndex128bpb, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT3ToRGBA8, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_DXT4_5 + {DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, kLoadShaderIndex128bpb, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT5ToRGBA8, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_16_16_16_16_EDRAM + // Not usable as a texture, also has -32...32 range. + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // R32_FLOAT for depth because shaders would require an additional SRV to + // sample stencil, which we don't provide. + // k_24_8 + {DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, kLoadShaderIndexDepthUnorm, + DXGI_FORMAT_R32_FLOAT, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_24_8_FLOAT + {DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, kLoadShaderIndexDepthFloat, + DXGI_FORMAT_R32_FLOAT, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_16 + {DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, kLoadShaderIndex16bpb, DXGI_FORMAT_R16_SNORM, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_16_16 + {DXGI_FORMAT_R16G16_TYPELESS, DXGI_FORMAT_R16G16_UNORM, kLoadShaderIndex32bpb, + DXGI_FORMAT_R16G16_SNORM, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_16_16_16_16 + {DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM, kLoadShaderIndex64bpb, + DXGI_FORMAT_R16G16B16A16_SNORM, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_16_EXPAND + {DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, kLoadShaderIndex16bpb, DXGI_FORMAT_R16_FLOAT, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_16_16_EXPAND + {DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, kLoadShaderIndex32bpb, + DXGI_FORMAT_R16G16_FLOAT, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_16_16_16_16_EXPAND + {DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, kLoadShaderIndex64bpb, + DXGI_FORMAT_R16G16B16A16_FLOAT, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_16_FLOAT + {DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, kLoadShaderIndex16bpb, DXGI_FORMAT_R16_FLOAT, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_16_16_FLOAT + {DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, kLoadShaderIndex32bpb, + DXGI_FORMAT_R16G16_FLOAT, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_16_16_16_16_FLOAT + {DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, kLoadShaderIndex64bpb, + DXGI_FORMAT_R16G16B16A16_FLOAT, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_32 + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_32_32 + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_32_32_32_32 + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_32_FLOAT + {DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, kLoadShaderIndex32bpb, DXGI_FORMAT_R32_FLOAT, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_32_32_FLOAT + {DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, kLoadShaderIndex64bpb, + DXGI_FORMAT_R32G32_FLOAT, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_32_32_32_32_FLOAT + {DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, kLoadShaderIndex128bpb, + DXGI_FORMAT_R32G32B32A32_FLOAT, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_32_AS_8 + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_32_AS_8_8 + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_16_MPEG + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_16_16_MPEG + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_8_INTERLACED + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_32_AS_8_INTERLACED + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_32_AS_8_8_INTERLACED + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_16_INTERLACED + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_16_MPEG_INTERLACED + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_16_16_MPEG_INTERLACED + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_DXN + {DXGI_FORMAT_BC5_UNORM, DXGI_FORMAT_BC5_UNORM, kLoadShaderIndex128bpb, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, true, DXGI_FORMAT_R8G8_UNORM, kLoadShaderIndexDXNToRG8, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_8_8_8_8_AS_16_16_16_16 + {DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndex32bpb, + DXGI_FORMAT_R8G8B8A8_SNORM, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_DXT1_AS_16_16_16_16 + {DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, kLoadShaderIndex64bpb, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT1ToRGBA8, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_DXT2_3_AS_16_16_16_16 + {DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, kLoadShaderIndex128bpb, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT3ToRGBA8, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_DXT4_5_AS_16_16_16_16 + {DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, kLoadShaderIndex128bpb, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT5ToRGBA8, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_2_10_10_10_AS_16_16_16_16 + {DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM, kLoadShaderIndex32bpb, + DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_10_11_11_AS_16_16_16_16 + {DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM, + kLoadShaderIndexR11G11B10ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM, + kLoadShaderIndexR11G11B10ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, + // k_11_11_10_AS_16_16_16_16 + {DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM, + kLoadShaderIndexR10G11B11ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM, + kLoadShaderIndexR10G11B11ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, + // k_32_32_32_FLOAT + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, + // k_DXT3A + // R8_UNORM has the same size as BC2, but doesn't have the 4x4 size + // alignment requirement. + {DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, kLoadShaderIndexDXT3A, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_DXT5A + {DXGI_FORMAT_BC4_UNORM, DXGI_FORMAT_BC4_UNORM, kLoadShaderIndex64bpb, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, true, DXGI_FORMAT_R8_UNORM, kLoadShaderIndexDXT5AToR8, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_CTX1 + {DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, kLoadShaderIndexCTX1, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_DXT3A_AS_1_1_1_1 + {DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_B4G4R4A4_UNORM, kLoadShaderIndexDXT3AAs1111ToBGRA4, + DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_8_8_8_8_GAMMA_EDRAM + // Not usable as a texture. + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_2_10_10_10_FLOAT_EDRAM + // Not usable as a texture. + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, DXGI_FORMAT_UNKNOWN, + kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, +}; + +D3D12TextureCache::D3D12TextureCache(const RegisterFile& register_file, + D3D12SharedMemory& shared_memory, + uint32_t draw_resolution_scale_x, + uint32_t draw_resolution_scale_y, + D3D12CommandProcessor& command_processor, + bool bindless_resources_used) + : TextureCache(register_file, shared_memory, draw_resolution_scale_x, draw_resolution_scale_y), + command_processor_(command_processor), + bindless_resources_used_(bindless_resources_used) {} + +D3D12TextureCache::~D3D12TextureCache() { + // While the texture descriptor cache still exists (referenced by + // ~D3D12Texture), destroy all textures. + DestroyAllTextures(true); + + // First release the buffers to detach them from the heaps. + for (std::unique_ptr& scaled_resolve_buffer_ptr : + scaled_resolve_2gb_buffers_) { + scaled_resolve_buffer_ptr.reset(); + } + scaled_resolve_heaps_.clear(); + COUNT_profile_set("gpu/texture_cache/scaled_resolve_buffer_used_mb", 0); +} + +bool D3D12TextureCache::Initialize() { + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + + if (IsDrawResolutionScaled()) { + // Buffers not used yet - no need aliasing barriers to change ownership of + // gigabytes between even and odd buffers. + std::memset(scaled_resolve_1gb_buffer_indices_, UINT8_MAX, + sizeof(scaled_resolve_1gb_buffer_indices_)); + assert_true(scaled_resolve_heaps_.empty()); + uint64_t scaled_resolve_address_space_size = + uint64_t(SharedMemory::kBufferSize) * + (draw_resolution_scale_x() * draw_resolution_scale_y()); + scaled_resolve_heaps_.resize( + size_t(scaled_resolve_address_space_size >> kScaledResolveHeapSizeLog2)); + } + scaled_resolve_heap_count_ = 0; + + // Create the loading root signature. + D3D12_ROOT_PARAMETER root_parameters[3]; + // Parameter 0 is constants (changed multiple times when untiling). + root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + root_parameters[0].Constants.ShaderRegister = 0; + root_parameters[0].Constants.RegisterSpace = 0; + root_parameters[0].Constants.Num32BitValues = sizeof(LoadConstants) / sizeof(uint32_t); + root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + // Parameter 1 is the source (may be changed multiple times for the same + // destination). + D3D12_DESCRIPTOR_RANGE root_dest_range; + root_dest_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + root_dest_range.NumDescriptors = 1; + root_dest_range.BaseShaderRegister = 0; + root_dest_range.RegisterSpace = 0; + root_dest_range.OffsetInDescriptorsFromTableStart = 0; + root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + root_parameters[1].DescriptorTable.NumDescriptorRanges = 1; + root_parameters[1].DescriptorTable.pDescriptorRanges = &root_dest_range; + root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + // Parameter 2 is the destination. + D3D12_DESCRIPTOR_RANGE root_source_range; + root_source_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + root_source_range.NumDescriptors = 1; + root_source_range.BaseShaderRegister = 0; + root_source_range.RegisterSpace = 0; + root_source_range.OffsetInDescriptorsFromTableStart = 0; + root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + root_parameters[2].DescriptorTable.NumDescriptorRanges = 1; + root_parameters[2].DescriptorTable.pDescriptorRanges = &root_source_range; + root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + D3D12_ROOT_SIGNATURE_DESC root_signature_desc; + root_signature_desc.NumParameters = UINT(rex::countof(root_parameters)); + root_signature_desc.pParameters = root_parameters; + root_signature_desc.NumStaticSamplers = 0; + root_signature_desc.pStaticSamplers = nullptr; + root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; + *(load_root_signature_.ReleaseAndGetAddressOf()) = + ui::d3d12::util::CreateRootSignature(provider, root_signature_desc); + if (!load_root_signature_) { + REXGPU_ERROR( + "D3D12TextureCache: Failed to create the texture loading root " + "signature"); + return false; + } + + // Specify the load shader code. + D3D12_SHADER_BYTECODE load_shader_code[kLoadShaderCount] = {}; + load_shader_code[kLoadShaderIndex8bpb] = + D3D12_SHADER_BYTECODE{shaders::texture_load_8bpb_cs, sizeof(shaders::texture_load_8bpb_cs)}; + load_shader_code[kLoadShaderIndex16bpb] = + D3D12_SHADER_BYTECODE{shaders::texture_load_16bpb_cs, sizeof(shaders::texture_load_16bpb_cs)}; + load_shader_code[kLoadShaderIndex32bpb] = + D3D12_SHADER_BYTECODE{shaders::texture_load_32bpb_cs, sizeof(shaders::texture_load_32bpb_cs)}; + load_shader_code[kLoadShaderIndex64bpb] = + D3D12_SHADER_BYTECODE{shaders::texture_load_64bpb_cs, sizeof(shaders::texture_load_64bpb_cs)}; + load_shader_code[kLoadShaderIndex128bpb] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_128bpb_cs, sizeof(shaders::texture_load_128bpb_cs)}; + load_shader_code[kLoadShaderIndexR5G5B5A1ToB5G5R5A1] = + D3D12_SHADER_BYTECODE{shaders::texture_load_r5g5b5a1_b5g5r5a1_cs, + sizeof(shaders::texture_load_r5g5b5a1_b5g5r5a1_cs)}; + load_shader_code[kLoadShaderIndexR5G6B5ToB5G6R5] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_r5g6b5_b5g6r5_cs, sizeof(shaders::texture_load_r5g6b5_b5g6r5_cs)}; + load_shader_code[kLoadShaderIndexR5G5B6ToB5G6R5WithRBGASwizzle] = + D3D12_SHADER_BYTECODE{shaders::texture_load_r5g5b6_b5g6r5_swizzle_rbga_cs, + sizeof(shaders::texture_load_r5g5b6_b5g6r5_swizzle_rbga_cs)}; + load_shader_code[kLoadShaderIndexRGBA4ToBGRA4] = + D3D12_SHADER_BYTECODE{shaders::texture_load_r4g4b4a4_b4g4r4a4_cs, + sizeof(shaders::texture_load_r4g4b4a4_b4g4r4a4_cs)}; + load_shader_code[kLoadShaderIndexGBGR8ToGRGB8] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_gbgr8_grgb8_cs, sizeof(shaders::texture_load_gbgr8_grgb8_cs)}; + load_shader_code[kLoadShaderIndexGBGR8ToRGB8] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_gbgr8_rgb8_cs, sizeof(shaders::texture_load_gbgr8_rgb8_cs)}; + load_shader_code[kLoadShaderIndexBGRG8ToRGBG8] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_bgrg8_rgbg8_cs, sizeof(shaders::texture_load_bgrg8_rgbg8_cs)}; + load_shader_code[kLoadShaderIndexBGRG8ToRGB8] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_bgrg8_rgb8_cs, sizeof(shaders::texture_load_bgrg8_rgb8_cs)}; + load_shader_code[kLoadShaderIndexR10G11B11ToRGBA16] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_r10g11b11_rgba16_cs, sizeof(shaders::texture_load_r10g11b11_rgba16_cs)}; + load_shader_code[kLoadShaderIndexR10G11B11ToRGBA16SNorm] = + D3D12_SHADER_BYTECODE{shaders::texture_load_r10g11b11_rgba16_snorm_cs, + sizeof(shaders::texture_load_r10g11b11_rgba16_snorm_cs)}; + load_shader_code[kLoadShaderIndexR11G11B10ToRGBA16] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_r11g11b10_rgba16_cs, sizeof(shaders::texture_load_r11g11b10_rgba16_cs)}; + load_shader_code[kLoadShaderIndexR11G11B10ToRGBA16SNorm] = + D3D12_SHADER_BYTECODE{shaders::texture_load_r11g11b10_rgba16_snorm_cs, + sizeof(shaders::texture_load_r11g11b10_rgba16_snorm_cs)}; + load_shader_code[kLoadShaderIndexDXT1ToRGBA8] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_dxt1_rgba8_cs, sizeof(shaders::texture_load_dxt1_rgba8_cs)}; + load_shader_code[kLoadShaderIndexDXT3ToRGBA8] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_dxt3_rgba8_cs, sizeof(shaders::texture_load_dxt3_rgba8_cs)}; + load_shader_code[kLoadShaderIndexDXT5ToRGBA8] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_dxt5_rgba8_cs, sizeof(shaders::texture_load_dxt5_rgba8_cs)}; + load_shader_code[kLoadShaderIndexDXNToRG8] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_dxn_rg8_cs, sizeof(shaders::texture_load_dxn_rg8_cs)}; + load_shader_code[kLoadShaderIndexDXT3A] = + D3D12_SHADER_BYTECODE{shaders::texture_load_dxt3a_cs, sizeof(shaders::texture_load_dxt3a_cs)}; + load_shader_code[kLoadShaderIndexDXT3AAs1111ToBGRA4] = + D3D12_SHADER_BYTECODE{shaders::texture_load_dxt3aas1111_bgra4_cs, + sizeof(shaders::texture_load_dxt3aas1111_bgra4_cs)}; + load_shader_code[kLoadShaderIndexDXT5AToR8] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_dxt5a_r8_cs, sizeof(shaders::texture_load_dxt5a_r8_cs)}; + load_shader_code[kLoadShaderIndexCTX1] = + D3D12_SHADER_BYTECODE{shaders::texture_load_ctx1_cs, sizeof(shaders::texture_load_ctx1_cs)}; + load_shader_code[kLoadShaderIndexDepthUnorm] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_depth_unorm_cs, sizeof(shaders::texture_load_depth_unorm_cs)}; + load_shader_code[kLoadShaderIndexDepthFloat] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_depth_float_cs, sizeof(shaders::texture_load_depth_float_cs)}; + D3D12_SHADER_BYTECODE load_shader_code_scaled[kLoadShaderCount] = {}; + if (IsDrawResolutionScaled()) { + load_shader_code_scaled[kLoadShaderIndex8bpb] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_8bpb_scaled_cs, sizeof(shaders::texture_load_8bpb_scaled_cs)}; + load_shader_code_scaled[kLoadShaderIndex16bpb] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_16bpb_scaled_cs, sizeof(shaders::texture_load_16bpb_scaled_cs)}; + load_shader_code_scaled[kLoadShaderIndex32bpb] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_32bpb_scaled_cs, sizeof(shaders::texture_load_32bpb_scaled_cs)}; + load_shader_code_scaled[kLoadShaderIndex64bpb] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_64bpb_scaled_cs, sizeof(shaders::texture_load_64bpb_scaled_cs)}; + load_shader_code_scaled[kLoadShaderIndex128bpb] = D3D12_SHADER_BYTECODE{ + shaders::texture_load_128bpb_scaled_cs, sizeof(shaders::texture_load_128bpb_scaled_cs)}; + load_shader_code_scaled[kLoadShaderIndexR5G5B5A1ToB5G5R5A1] = + D3D12_SHADER_BYTECODE{shaders::texture_load_r5g5b5a1_b5g5r5a1_scaled_cs, + sizeof(shaders::texture_load_r5g5b5a1_b5g5r5a1_scaled_cs)}; + load_shader_code_scaled[kLoadShaderIndexR5G6B5ToB5G6R5] = + D3D12_SHADER_BYTECODE{shaders::texture_load_r5g6b5_b5g6r5_scaled_cs, + sizeof(shaders::texture_load_r5g6b5_b5g6r5_scaled_cs)}; + load_shader_code_scaled[kLoadShaderIndexR5G5B6ToB5G6R5WithRBGASwizzle] = + D3D12_SHADER_BYTECODE{shaders::texture_load_r5g5b6_b5g6r5_swizzle_rbga_scaled_cs, + sizeof(shaders::texture_load_r5g5b6_b5g6r5_swizzle_rbga_scaled_cs)}; + load_shader_code_scaled[kLoadShaderIndexRGBA4ToBGRA4] = + D3D12_SHADER_BYTECODE{shaders::texture_load_r4g4b4a4_b4g4r4a4_scaled_cs, + sizeof(shaders::texture_load_r4g4b4a4_b4g4r4a4_scaled_cs)}; + load_shader_code_scaled[kLoadShaderIndexR10G11B11ToRGBA16] = + D3D12_SHADER_BYTECODE{shaders::texture_load_r10g11b11_rgba16_scaled_cs, + sizeof(shaders::texture_load_r10g11b11_rgba16_scaled_cs)}; + load_shader_code_scaled[kLoadShaderIndexR10G11B11ToRGBA16SNorm] = + D3D12_SHADER_BYTECODE{shaders::texture_load_r10g11b11_rgba16_snorm_scaled_cs, + sizeof(shaders::texture_load_r10g11b11_rgba16_snorm_scaled_cs)}; + load_shader_code_scaled[kLoadShaderIndexR11G11B10ToRGBA16] = + D3D12_SHADER_BYTECODE{shaders::texture_load_r11g11b10_rgba16_scaled_cs, + sizeof(shaders::texture_load_r11g11b10_rgba16_scaled_cs)}; + load_shader_code_scaled[kLoadShaderIndexR11G11B10ToRGBA16SNorm] = + D3D12_SHADER_BYTECODE{shaders::texture_load_r11g11b10_rgba16_snorm_scaled_cs, + sizeof(shaders::texture_load_r11g11b10_rgba16_snorm_scaled_cs)}; + load_shader_code_scaled[kLoadShaderIndexDepthUnorm] = + D3D12_SHADER_BYTECODE{shaders::texture_load_depth_unorm_scaled_cs, + sizeof(shaders::texture_load_depth_unorm_scaled_cs)}; + load_shader_code_scaled[kLoadShaderIndexDepthFloat] = + D3D12_SHADER_BYTECODE{shaders::texture_load_depth_float_scaled_cs, + sizeof(shaders::texture_load_depth_float_scaled_cs)}; + } + + // Create the loading pipelines. + for (size_t i = 0; i < kLoadShaderCount; ++i) { + const D3D12_SHADER_BYTECODE& current_load_shader_code = load_shader_code[i]; + if (!current_load_shader_code.pShaderBytecode) { + continue; + } + *(load_pipelines_[i].ReleaseAndGetAddressOf()) = ui::d3d12::util::CreateComputePipeline( + device, current_load_shader_code.pShaderBytecode, current_load_shader_code.BytecodeLength, + load_root_signature_.Get()); + if (!load_pipelines_[i]) { + REXGPU_ERROR( + "D3D12TextureCache: Failed to create the texture loading pipeline " + "for shader {}", + i); + return false; + } + if (IsDrawResolutionScaled()) { + const D3D12_SHADER_BYTECODE& current_load_shader_code_scaled = load_shader_code_scaled[i]; + if (current_load_shader_code_scaled.pShaderBytecode) { + *(load_pipelines_scaled_[i].ReleaseAndGetAddressOf()) = + ui::d3d12::util::CreateComputePipeline( + device, current_load_shader_code_scaled.pShaderBytecode, + current_load_shader_code_scaled.BytecodeLength, load_root_signature_.Get()); + if (!load_pipelines_scaled_[i]) { + REXGPU_ERROR( + "D3D12TextureCache: Failed to create the resolution-scaled " + "texture loading pipeline for shader {}", + i); + return false; + } + } + } + } + + srv_descriptor_cache_allocated_ = 0; + + // Create a heap with null SRV descriptors, since it's faster to copy a + // descriptor than to create an SRV, and null descriptors are used a lot (for + // the signed version when only unsigned is used, for instance). + D3D12_DESCRIPTOR_HEAP_DESC null_srv_descriptor_heap_desc; + null_srv_descriptor_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + null_srv_descriptor_heap_desc.NumDescriptors = uint32_t(NullSRVDescriptorIndex::kCount); + null_srv_descriptor_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + null_srv_descriptor_heap_desc.NodeMask = 0; + if (FAILED(device->CreateDescriptorHeap(&null_srv_descriptor_heap_desc, + IID_PPV_ARGS(&null_srv_descriptor_heap_)))) { + REXGPU_ERROR( + "D3D12TextureCache: Failed to create the descriptor heap for null " + "SRVs"); + return false; + } + null_srv_descriptor_heap_start_ = null_srv_descriptor_heap_->GetCPUDescriptorHandleForHeapStart(); + D3D12_SHADER_RESOURCE_VIEW_DESC null_srv_desc; + null_srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + null_srv_desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( + D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0, D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0, + D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0, D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0); + null_srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY; + null_srv_desc.Texture2DArray.MostDetailedMip = 0; + null_srv_desc.Texture2DArray.MipLevels = 1; + null_srv_desc.Texture2DArray.FirstArraySlice = 0; + null_srv_desc.Texture2DArray.ArraySize = 1; + null_srv_desc.Texture2DArray.PlaneSlice = 0; + null_srv_desc.Texture2DArray.ResourceMinLODClamp = 0.0f; + device->CreateShaderResourceView( + nullptr, &null_srv_desc, + provider.OffsetViewDescriptor(null_srv_descriptor_heap_start_, + uint32_t(NullSRVDescriptorIndex::k2DArray))); + null_srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D; + null_srv_desc.Texture3D.MostDetailedMip = 0; + null_srv_desc.Texture3D.MipLevels = 1; + null_srv_desc.Texture3D.ResourceMinLODClamp = 0.0f; + device->CreateShaderResourceView( + nullptr, &null_srv_desc, + provider.OffsetViewDescriptor(null_srv_descriptor_heap_start_, + uint32_t(NullSRVDescriptorIndex::k3D))); + null_srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE; + null_srv_desc.TextureCube.MostDetailedMip = 0; + null_srv_desc.TextureCube.MipLevels = 1; + null_srv_desc.TextureCube.ResourceMinLODClamp = 0.0f; + device->CreateShaderResourceView( + nullptr, &null_srv_desc, + provider.OffsetViewDescriptor(null_srv_descriptor_heap_start_, + uint32_t(NullSRVDescriptorIndex::kCube))); + + return true; +} + +void D3D12TextureCache::ClearCache() { + TextureCache::ClearCache(); + + // Clear texture descriptor cache. + srv_descriptor_cache_free_.clear(); + srv_descriptor_cache_allocated_ = 0; + srv_descriptor_cache_.clear(); +} + +void D3D12TextureCache::BeginSubmission(uint64_t new_submission_index) { + TextureCache::BeginSubmission(new_submission_index); + + // ExecuteCommandLists is a full UAV and aliasing barrier. + if (IsDrawResolutionScaled()) { + size_t scaled_resolve_buffer_count = GetScaledResolveBufferCount(); + for (size_t i = 0; i < scaled_resolve_buffer_count; ++i) { + ScaledResolveVirtualBuffer* scaled_resolve_buffer = scaled_resolve_2gb_buffers_[i].get(); + if (scaled_resolve_buffer) { + scaled_resolve_buffer->ClearUAVBarrierPending(); + } + } + std::memset(scaled_resolve_1gb_buffer_indices_, UINT8_MAX, + sizeof(scaled_resolve_1gb_buffer_indices_)); + } +} + +void D3D12TextureCache::BeginFrame() { + TextureCache::BeginFrame(); + + std::memset(unsupported_format_features_used_, 0, sizeof(unsupported_format_features_used_)); +} + +void D3D12TextureCache::EndFrame() { + // Report used unsupported texture formats. + bool unsupported_header_written = false; + for (uint32_t i = 0; i < 64; ++i) { + uint32_t unsupported_features = unsupported_format_features_used_[i]; + if (unsupported_features == 0) { + continue; + } + if (!unsupported_header_written) { + REXGPU_ERROR("Unsupported texture formats used in the frame:"); + unsupported_header_written = true; + } + REXGPU_ERROR("* {}{}{}{}", FormatInfo::Get(xenos::TextureFormat(i))->name, + unsupported_features & kUnsupportedResourceBit ? " resource" : "", + unsupported_features & kUnsupportedUnormBit ? " unsigned" : "", + unsupported_features & kUnsupportedSnormBit ? " signed" : ""); + unsupported_format_features_used_[i] = 0; + } +} + +void D3D12TextureCache::RequestTextures(uint32_t used_texture_mask) { +#if XE_GPU_FINE_GRAINED_DRAW_SCOPES + SCOPE_profile_cpu_f("gpu"); +#endif // XE_GPU_FINE_GRAINED_DRAW_SCOPES + + TextureCache::RequestTextures(used_texture_mask); + + // Pre-create 3D-as-2D wrappers before draw setup. Wrapper loading may bind + // compute pipelines and must happen in the texture request phase. + if (REXCVAR_GET(gpu_3d_to_2d_texture)) { + uint32_t textures_3d = used_texture_mask; + uint32_t index_3d; + while (rex::bit_scan_forward(textures_3d, &index_3d)) { + textures_3d &= ~(uint32_t(1) << index_3d); + const TextureBinding* binding = GetValidTextureBinding(index_3d); + if (!binding || binding->key.dimension != xenos::DataDimension::k3D) { + continue; + } + D3D12Texture* texture = static_cast(binding->texture); + if (texture) { + texture->GetOrCreate3DAs2DResource(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + } + D3D12Texture* texture_signed = static_cast(binding->texture_signed); + if (texture_signed) { + texture_signed->GetOrCreate3DAs2DResource(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + } + } + } + + // Transition the textures to the needed usage - always in + // NON_PIXEL_SHADER_RESOURCE | PIXEL_SHADER_RESOURCE states because barriers + // between read-only stages, if needed, are discouraged (also if these were + // tracked separately, checks would be needed to make sure, if the same + // texture is bound through different fetch constants to both VS and PS, it + // would be in both states). + uint32_t textures_remaining = used_texture_mask; + uint32_t index; + while (rex::bit_scan_forward(textures_remaining, &index)) { + textures_remaining &= ~(uint32_t(1) << index); + const TextureBinding* binding = GetValidTextureBinding(index); + if (!binding) { + continue; + } + D3D12Texture* binding_texture = static_cast(binding->texture); + if (binding_texture != nullptr) { + // Will be referenced by the command list, so mark as used. + binding_texture->MarkAsUsed(); + command_processor_.PushTransitionBarrier( + binding_texture->resource(), + binding_texture->SetResourceState(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE), + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + } + D3D12Texture* binding_texture_signed = static_cast(binding->texture_signed); + if (binding_texture_signed != nullptr) { + binding_texture_signed->MarkAsUsed(); + command_processor_.PushTransitionBarrier( + binding_texture_signed->resource(), + binding_texture_signed->SetResourceState(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE), + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + } + } +} + +bool D3D12TextureCache::AreActiveTextureSRVKeysUpToDate( + const TextureSRVKey* keys, const D3D12Shader::TextureBinding* host_shader_bindings, + size_t host_shader_binding_count) const { + for (size_t i = 0; i < host_shader_binding_count; ++i) { + const TextureSRVKey& key = keys[i]; + const TextureBinding* binding = GetValidTextureBinding(host_shader_bindings[i].fetch_constant); + if (!binding) { + if (key.key.is_valid) { + return false; + } + continue; + } + if (key.key != binding->key || key.host_swizzle != binding->host_swizzle || + key.swizzled_signs != binding->swizzled_signs) { + return false; + } + } + return true; +} + +void D3D12TextureCache::WriteActiveTextureSRVKeys( + TextureSRVKey* keys, const D3D12Shader::TextureBinding* host_shader_bindings, + size_t host_shader_binding_count) const { + for (size_t i = 0; i < host_shader_binding_count; ++i) { + TextureSRVKey& key = keys[i]; + const TextureBinding* binding = GetValidTextureBinding(host_shader_bindings[i].fetch_constant); + if (!binding) { + key.key.MakeInvalid(); + key.host_swizzle = xenos::XE_GPU_TEXTURE_SWIZZLE_0000; + key.swizzled_signs = kSwizzledSignsUnsigned; + continue; + } + key.key = binding->key; + key.host_swizzle = binding->host_swizzle; + key.swizzled_signs = binding->swizzled_signs; + } +} + +void D3D12TextureCache::WriteActiveTextureBindfulSRV( + const D3D12Shader::TextureBinding& host_shader_binding, D3D12_CPU_DESCRIPTOR_HANDLE handle) { + assert_false(bindless_resources_used_); + uint32_t descriptor_index = UINT32_MAX; + Texture* texture = nullptr; + uint32_t fetch_constant_index = host_shader_binding.fetch_constant; + const TextureBinding* binding = GetValidTextureBinding(fetch_constant_index); + if (binding && AreDimensionsCompatible(host_shader_binding.dimension, binding->key.dimension)) { + bool force_special_view = binding->key.dimension == xenos::DataDimension::k3D && + (host_shader_binding.dimension == xenos::FetchOpDimension::k1D || + host_shader_binding.dimension == xenos::FetchOpDimension::k2D); + const D3D12TextureBinding& d3d12_binding = d3d12_texture_bindings_[fetch_constant_index]; + if (host_shader_binding.is_signed) { + // Not supporting signed compressed textures - hopefully DXN and DXT5A are + // not used as signed. + if (texture_util::IsAnySignSigned(binding->swizzled_signs)) { + texture = IsSignedVersionSeparateForFormat(binding->key) ? binding->texture_signed + : binding->texture; + if (force_special_view && texture) { + descriptor_index = FindOrCreateTextureDescriptor(*static_cast(texture), + xenos::DataDimension::k2DOrStacked, true, + binding->host_swizzle); + } else { + descriptor_index = d3d12_binding.descriptor_index_signed; + } + } + } else { + if (texture_util::IsAnySignNotSigned(binding->swizzled_signs)) { + texture = binding->texture; + if (force_special_view && texture) { + descriptor_index = FindOrCreateTextureDescriptor(*static_cast(texture), + xenos::DataDimension::k2DOrStacked, + false, binding->host_swizzle); + } else { + descriptor_index = d3d12_binding.descriptor_index; + } + } + } + } + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + D3D12_CPU_DESCRIPTOR_HANDLE source_handle; + if (descriptor_index != UINT32_MAX) { + assert_not_null(texture); + texture->MarkAsUsed(); + source_handle = GetTextureDescriptorCPUHandle(descriptor_index); + } else { + NullSRVDescriptorIndex null_descriptor_index; + switch (host_shader_binding.dimension) { + case xenos::FetchOpDimension::k3DOrStacked: + null_descriptor_index = NullSRVDescriptorIndex::k3D; + break; + case xenos::FetchOpDimension::kCube: + null_descriptor_index = NullSRVDescriptorIndex::kCube; + break; + default: + assert_true(host_shader_binding.dimension == xenos::FetchOpDimension::k1D || + host_shader_binding.dimension == xenos::FetchOpDimension::k2D); + null_descriptor_index = NullSRVDescriptorIndex::k2DArray; + } + source_handle = provider.OffsetViewDescriptor(null_srv_descriptor_heap_start_, + uint32_t(null_descriptor_index)); + } + auto device = provider.GetDevice(); + { +#if XE_GPU_FINE_GRAINED_DRAW_SCOPES + SCOPE_profile_cpu_i("gpu", + "rex::graphics::d3d12::D3D12TextureCache::WriteActiveTextureBindfulSRV->" + "CopyDescriptorsSimple"); +#endif // XE_GPU_FINE_GRAINED_DRAW_SCOPES + device->CopyDescriptorsSimple(1, handle, source_handle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + } +} + +uint32_t D3D12TextureCache::GetActiveTextureBindlessSRVIndex( + const D3D12Shader::TextureBinding& host_shader_binding) { + assert_true(bindless_resources_used_); + uint32_t descriptor_index = UINT32_MAX; + uint32_t fetch_constant_index = host_shader_binding.fetch_constant; + const TextureBinding* binding = GetValidTextureBinding(fetch_constant_index); + if (binding && AreDimensionsCompatible(host_shader_binding.dimension, binding->key.dimension)) { + bool force_special_view = binding->key.dimension == xenos::DataDimension::k3D && + (host_shader_binding.dimension == xenos::FetchOpDimension::k1D || + host_shader_binding.dimension == xenos::FetchOpDimension::k2D); + const D3D12TextureBinding& d3d12_binding = d3d12_texture_bindings_[fetch_constant_index]; + if (force_special_view) { + Texture* texture = nullptr; + bool use_signed = + host_shader_binding.is_signed && texture_util::IsAnySignSigned(binding->swizzled_signs); + if (use_signed) { + texture = IsSignedVersionSeparateForFormat(binding->key) ? binding->texture_signed + : binding->texture; + } else { + texture = binding->texture; + } + if (texture) { + descriptor_index = FindOrCreateTextureDescriptor(*static_cast(texture), + xenos::DataDimension::k2DOrStacked, + use_signed, binding->host_swizzle); + } + } else { + descriptor_index = host_shader_binding.is_signed ? d3d12_binding.descriptor_index_signed + : d3d12_binding.descriptor_index; + } + } + if (descriptor_index == UINT32_MAX) { + switch (host_shader_binding.dimension) { + case xenos::FetchOpDimension::k3DOrStacked: + descriptor_index = uint32_t(D3D12CommandProcessor::SystemBindlessView::kNullTexture3D); + break; + case xenos::FetchOpDimension::kCube: + descriptor_index = uint32_t(D3D12CommandProcessor::SystemBindlessView::kNullTextureCube); + break; + default: + assert_true(host_shader_binding.dimension == xenos::FetchOpDimension::k1D || + host_shader_binding.dimension == xenos::FetchOpDimension::k2D); + descriptor_index = uint32_t(D3D12CommandProcessor::SystemBindlessView::kNullTexture2DArray); + } + } + return descriptor_index; +} + +D3D12TextureCache::SamplerParameters D3D12TextureCache::GetSamplerParameters( + const D3D12Shader::SamplerBinding& binding) const { + const auto& regs = register_file(); + xenos::xe_gpu_texture_fetch_t fetch = regs.GetTextureFetch(binding.fetch_constant); + + SamplerParameters parameters; + + xenos::ClampMode fetch_clamp_x, fetch_clamp_y, fetch_clamp_z; + texture_util::GetClampModesForDimension(fetch, fetch_clamp_x, fetch_clamp_y, fetch_clamp_z); + parameters.clamp_x = NormalizeClampMode(fetch_clamp_x); + parameters.clamp_y = NormalizeClampMode(fetch_clamp_y); + parameters.clamp_z = NormalizeClampMode(fetch_clamp_z); + if (xenos::ClampModeUsesBorder(parameters.clamp_x) || + xenos::ClampModeUsesBorder(parameters.clamp_y) || + xenos::ClampModeUsesBorder(parameters.clamp_z)) { + parameters.border_color = fetch.border_color; + } else { + parameters.border_color = xenos::BorderColor::k_ABGR_Black; + } + + uint32_t mip_min_level, mip_max_level; + texture_util::GetSubresourcesFromFetchConstant(fetch, nullptr, nullptr, nullptr, nullptr, nullptr, + &mip_min_level, &mip_max_level); + parameters.mip_min_level = mip_min_level; + bool has_mips = mip_max_level > mip_min_level; + + xenos::TextureFilter mag_filter = binding.mag_filter == xenos::TextureFilter::kUseFetchConst + ? fetch.mag_filter + : binding.mag_filter; + xenos::TextureFilter min_filter = binding.min_filter == xenos::TextureFilter::kUseFetchConst + ? fetch.min_filter + : binding.min_filter; + xenos::TextureFilter mip_filter = binding.mip_filter == xenos::TextureFilter::kUseFetchConst + ? fetch.mip_filter + : binding.mip_filter; + bool min_mag_linear = (mag_filter == xenos::TextureFilter::kLinear) && + (min_filter == xenos::TextureFilter::kLinear); + bool mip_filter_bilinear_or_trilinear = + mip_filter == xenos::TextureFilter::kPoint || mip_filter == xenos::TextureFilter::kLinear; + bool mip_base_map = mip_filter == xenos::TextureFilter::kBaseMap; + + // TODO(Triang3l): Disable filtering for texture formats not supporting it. + xenos::AnisoFilter aniso_filter = binding.aniso_filter == xenos::AnisoFilter::kUseFetchConst + ? fetch.aniso_filter + : binding.aniso_filter; + int32_t anisotropic_override = REXCVAR_GET(anisotropic_override); + if (anisotropic_override > -1 && anisotropic_override < 6 && has_mips && !mip_base_map && + min_mag_linear && mip_filter_bilinear_or_trilinear) { + aniso_filter = xenos::AnisoFilter(anisotropic_override); + } + aniso_filter = std::min(aniso_filter, xenos::AnisoFilter::kMax_16_1); + parameters.aniso_filter = aniso_filter; + if (aniso_filter != xenos::AnisoFilter::kDisabled) { + parameters.mag_linear = 1; + parameters.min_linear = 1; + parameters.mip_linear = 1; + } else { + parameters.mag_linear = mag_filter == xenos::TextureFilter::kLinear; + parameters.min_linear = min_filter == xenos::TextureFilter::kLinear; + parameters.mip_linear = mip_filter == xenos::TextureFilter::kLinear; + } + parameters.mip_base_map = mip_base_map; + + return parameters; +} + +void D3D12TextureCache::WriteSampler(SamplerParameters parameters, + D3D12_CPU_DESCRIPTOR_HANDLE handle) const { + D3D12_SAMPLER_DESC desc; + if (parameters.aniso_filter != xenos::AnisoFilter::kDisabled) { + desc.Filter = D3D12_FILTER_ANISOTROPIC; + desc.MaxAnisotropy = 1u << (uint32_t(parameters.aniso_filter) - 1); + } else { + D3D12_FILTER_TYPE d3d_filter_min = + parameters.min_linear ? D3D12_FILTER_TYPE_LINEAR : D3D12_FILTER_TYPE_POINT; + D3D12_FILTER_TYPE d3d_filter_mag = + parameters.mag_linear ? D3D12_FILTER_TYPE_LINEAR : D3D12_FILTER_TYPE_POINT; + D3D12_FILTER_TYPE d3d_filter_mip = + parameters.mip_linear ? D3D12_FILTER_TYPE_LINEAR : D3D12_FILTER_TYPE_POINT; + desc.Filter = D3D12_ENCODE_BASIC_FILTER(d3d_filter_min, d3d_filter_mag, d3d_filter_mip, + D3D12_FILTER_REDUCTION_TYPE_STANDARD); + desc.MaxAnisotropy = 1; + } + static const D3D12_TEXTURE_ADDRESS_MODE kAddressModeMap[] = { + /* kRepeat */ D3D12_TEXTURE_ADDRESS_MODE_WRAP, + /* kMirroredRepeat */ D3D12_TEXTURE_ADDRESS_MODE_MIRROR, + /* kClampToEdge */ D3D12_TEXTURE_ADDRESS_MODE_CLAMP, + /* kMirrorClampToEdge */ D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE, + // No GL_CLAMP (clamp to half edge, half border) equivalent in Direct3D + // 12, but there's no Direct3D 9 equivalent anyway, and too weird to be + // suitable for intentional real usage. + /* kClampToHalfway */ D3D12_TEXTURE_ADDRESS_MODE_CLAMP, + // No mirror and clamp to border equivalents in Direct3D 12, but they + // aren't there in Direct3D 9 either. + /* kMirrorClampToHalfway */ D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE, + /* kClampToBorder */ D3D12_TEXTURE_ADDRESS_MODE_BORDER, + /* kMirrorClampToBorder */ D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE, + }; + desc.AddressU = kAddressModeMap[uint32_t(parameters.clamp_x)]; + desc.AddressV = kAddressModeMap[uint32_t(parameters.clamp_y)]; + desc.AddressW = kAddressModeMap[uint32_t(parameters.clamp_z)]; + // LOD biasing is performed in shaders. + desc.MipLODBias = 0.0f; + desc.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER; + switch (parameters.border_color) { + case xenos::BorderColor::k_ABGR_White: + desc.BorderColor[0] = 1.0f; + desc.BorderColor[1] = 1.0f; + desc.BorderColor[2] = 1.0f; + desc.BorderColor[3] = 1.0f; + break; + case xenos::BorderColor::k_ACBYCR_Black: + desc.BorderColor[0] = 0.5f; + desc.BorderColor[1] = 0.0f; + desc.BorderColor[2] = 0.5f; + desc.BorderColor[3] = 0.0f; + break; + case xenos::BorderColor::k_ACBCRY_Black: + desc.BorderColor[0] = 0.0f; + desc.BorderColor[1] = 0.5f; + desc.BorderColor[2] = 0.5f; + desc.BorderColor[3] = 0.0f; + break; + default: + assert_true(parameters.border_color == xenos::BorderColor::k_ABGR_Black); + desc.BorderColor[0] = 0.0f; + desc.BorderColor[1] = 0.0f; + desc.BorderColor[2] = 0.0f; + desc.BorderColor[3] = 0.0f; + break; + } + desc.MinLOD = float(parameters.mip_min_level); + if (parameters.mip_base_map) { + // "It is undefined whether LOD clamping based on MinLOD and MaxLOD Sampler + // states should happen before or after deciding if magnification is + // occuring" - Direct3D 11.3 Functional Specification. + // Using the GL_NEAREST / GL_LINEAR minification filter emulation logic + // described in the Vulkan VkSamplerCreateInfo specification, preserving + // magnification vs. minification - point mip sampling (usable only without + // anisotropic filtering on Direct3D 12) and MaxLOD 0.25. With anisotropic + // filtering, magnification vs. minification doesn't matter as the filter is + // always linear for both on Direct3D 12 - but linear filtering specifically + // is what must not be done for kBaseMap, so setting MaxLOD to MinLOD. + desc.MaxLOD = desc.MinLOD; + if (parameters.aniso_filter == xenos::AnisoFilter::kDisabled) { + assert_false(parameters.mip_linear); + desc.MaxLOD += 0.25f; + } + } else { + // Maximum mip level is in the texture resource itself. + desc.MaxLOD = FLT_MAX; + } + ID3D12Device* device = command_processor_.GetD3D12Provider().GetDevice(); + device->CreateSampler(&desc, handle); +} + +bool D3D12TextureCache::ClampDrawResolutionScaleToMaxSupported( + uint32_t& scale_x, uint32_t& scale_y, const ui::d3d12::D3D12Provider& provider) { + bool was_clamped; + if (provider.GetTiledResourcesTier() < D3D12_TILED_RESOURCES_TIER_1) { + was_clamped = scale_x > 1 || scale_y > 1; + scale_x = 1; + scale_y = 1; + return !was_clamped; + } + // Limit to the virtual address space available for a resource. + was_clamped = false; + uint32_t virtual_address_bits_per_resource = provider.GetVirtualAddressBitsPerResource(); + while (scale_x > 1 || scale_y > 1) { + uint64_t highest_scaled_address = uint64_t(SharedMemory::kBufferSize) * (scale_x * scale_y) - 1; + if (uint32_t(64) - rex::lzcnt(highest_scaled_address) <= virtual_address_bits_per_resource) { + break; + } + // When reducing from a square size, prefer decreasing the horizontal + // resolution as vertical resolution difference is visible more clearly in + // perspective. + was_clamped = true; + if (scale_x >= scale_y) { + --scale_x; + } else { + --scale_y; + } + } + return !was_clamped; +} + +bool D3D12TextureCache::EnsureScaledResolveMemoryCommitted(uint32_t start_unscaled, + uint32_t length_unscaled, + uint32_t length_scaled_alignment_log2) { + assert_true(IsDrawResolutionScaled()); + + if (length_unscaled == 0) { + return true; + } + if (start_unscaled > SharedMemory::kBufferSize || + (SharedMemory::kBufferSize - start_unscaled) < length_unscaled) { + // Exceeds the physical address space. + return false; + } + + uint32_t draw_resolution_scale_area = draw_resolution_scale_x() * draw_resolution_scale_y(); + uint64_t first_scaled = uint64_t(start_unscaled) * draw_resolution_scale_area; + uint64_t length_scaled_alignment_bits = (UINT64_C(1) << length_scaled_alignment_log2) - 1; + uint64_t last_scaled = + (uint64_t(start_unscaled + (length_unscaled - 1)) * draw_resolution_scale_area + + length_scaled_alignment_bits) & + ~length_scaled_alignment_bits; + + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + + // Ensure GPU virtual memory for buffers that may be used to access the range + // is allocated - buffers are created. Always creating both buffers for all + // addresses before creating the heaps so when creating a new buffer, it can + // be safely assumed that no existing heaps should be mapped to it. + std::array possible_buffers_first = + GetPossibleScaledResolveBufferIndices(first_scaled); + std::array possible_buffers_last = GetPossibleScaledResolveBufferIndices(last_scaled); + size_t possible_buffer_first = std::min(possible_buffers_first[0], possible_buffers_first[1]); + size_t possible_buffer_last = std::max(possible_buffers_last[0], possible_buffers_last[1]); + for (size_t i = possible_buffer_first; i <= possible_buffer_last; ++i) { + if (scaled_resolve_2gb_buffers_[i]) { + continue; + } + D3D12_RESOURCE_DESC scaled_resolve_buffer_desc; + // Buffer indices are gigabytes. + ui::d3d12::util::FillBufferResourceDesc( + scaled_resolve_buffer_desc, + std::min( + uint64_t(1) << 31, + uint64_t(SharedMemory::kBufferSize) * draw_resolution_scale_area - (uint64_t(i) << 30)), + D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); + // The first access will be a resolve. + constexpr D3D12_RESOURCE_STATES kScaledResolveVirtualBufferInitialState = + D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + ID3D12Resource* scaled_resolve_buffer_resource; + if (FAILED(device->CreateReservedResource(&scaled_resolve_buffer_desc, + kScaledResolveVirtualBufferInitialState, nullptr, + IID_PPV_ARGS(&scaled_resolve_buffer_resource)))) { + REXGPU_ERROR( + "D3D12TextureCache: Failed to create a 2 GB tiled buffer for draw " + "resolution scaling"); + return false; + } + scaled_resolve_2gb_buffers_[i] = + std::unique_ptr(new ScaledResolveVirtualBuffer( + scaled_resolve_buffer_resource, kScaledResolveVirtualBufferInitialState)); + scaled_resolve_buffer_resource->Release(); + } + + uint32_t heap_first = uint32_t(first_scaled >> kScaledResolveHeapSizeLog2); + uint32_t heap_last = uint32_t(last_scaled >> kScaledResolveHeapSizeLog2); + for (uint32_t i = heap_first; i <= heap_last; ++i) { + if (scaled_resolve_heaps_[i]) { + continue; + } + auto direct_queue = provider.GetDirectQueue(); + D3D12_HEAP_DESC heap_desc = {}; + heap_desc.SizeInBytes = kScaledResolveHeapSize; + heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT; + heap_desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS | provider.GetHeapFlagCreateNotZeroed(); + Microsoft::WRL::ComPtr scaled_resolve_heap; + if (FAILED(device->CreateHeap(&heap_desc, IID_PPV_ARGS(&scaled_resolve_heap)))) { + REXGPU_ERROR("D3D12TextureCache: Failed to create a scaled resolve tile heap"); + return false; + } + scaled_resolve_heaps_[i] = scaled_resolve_heap; + ++scaled_resolve_heap_count_; + COUNT_profile_set("gpu/texture_cache/scaled_resolve_buffer_used_mb", + scaled_resolve_heap_count_ << (kScaledResolveHeapSizeLog2 - 20)); + D3D12_TILED_RESOURCE_COORDINATE region_start_coordinates; + region_start_coordinates.Y = 0; + region_start_coordinates.Z = 0; + region_start_coordinates.Subresource = 0; + D3D12_TILE_REGION_SIZE region_size; + region_size.NumTiles = kScaledResolveHeapSize / D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES; + region_size.UseBox = FALSE; + D3D12_TILE_RANGE_FLAGS range_flags = D3D12_TILE_RANGE_FLAG_NONE; + UINT heap_range_start_offset = 0; + UINT range_tile_count = kScaledResolveHeapSize / D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES; + std::array buffer_indices = + GetPossibleScaledResolveBufferIndices(uint64_t(i) << kScaledResolveHeapSizeLog2); + for (size_t j = 0; j < 2; ++j) { + size_t buffer_index = buffer_indices[j]; + if (j && buffer_index == buffer_indices[0]) { + break; + } + region_start_coordinates.X = + UINT(((uint64_t(i) << kScaledResolveHeapSizeLog2) - (uint64_t(buffer_index) << 30)) / + D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES); + direct_queue->UpdateTileMappings( + scaled_resolve_2gb_buffers_[buffer_index]->resource(), 1, ®ion_start_coordinates, + ®ion_size, scaled_resolve_heap.Get(), 1, &range_flags, &heap_range_start_offset, + &range_tile_count, D3D12_TILE_MAPPING_FLAG_NONE); + } + command_processor_.NotifyQueueOperationsDoneDirectly(); + } + return true; +} + +bool D3D12TextureCache::MakeScaledResolveRangeCurrent(uint32_t start_unscaled, + uint32_t length_unscaled, + uint32_t length_scaled_alignment_log2) { + assert_true(IsDrawResolutionScaled()); + + if (!length_unscaled || start_unscaled >= SharedMemory::kBufferSize || + (SharedMemory::kBufferSize - start_unscaled) < length_unscaled) { + // If length is 0, the needed buffer can't be chosen because no buffer is + // needed. + return false; + } + + uint32_t draw_resolution_scale_area = draw_resolution_scale_x() * draw_resolution_scale_y(); + uint64_t start_scaled = uint64_t(start_unscaled) * draw_resolution_scale_area; + uint64_t length_scaled_alignment_bits = (UINT64_C(1) << length_scaled_alignment_log2) - 1; + uint64_t length_scaled = + (uint64_t(length_unscaled) * draw_resolution_scale_area + length_scaled_alignment_bits) & + ~length_scaled_alignment_bits; + uint64_t last_scaled = start_scaled + (length_scaled - 1); + + // Get one or two buffers that can hold the whole range. + std::array possible_buffer_indices_first = + GetPossibleScaledResolveBufferIndices(start_scaled); + std::array possible_buffer_indices_last = + GetPossibleScaledResolveBufferIndices(last_scaled); + size_t possible_buffer_indices_common[2]; + size_t possible_buffer_indices_common_count = 0; + for (size_t i = 0; + i <= size_t(possible_buffer_indices_first[0] != possible_buffer_indices_first[1]); ++i) { + size_t possible_buffer_index_first = possible_buffer_indices_first[i]; + for (size_t j = 0; + j <= size_t(possible_buffer_indices_last[0] != possible_buffer_indices_last[1]); ++j) { + if (possible_buffer_indices_last[j] == possible_buffer_index_first) { + bool possible_buffer_index_already_added = false; + for (size_t k = 0; k < possible_buffer_indices_common_count; ++k) { + if (possible_buffer_indices_common[k] == possible_buffer_index_first) { + possible_buffer_index_already_added = true; + break; + } + } + if (!possible_buffer_index_already_added) { + assert_true(possible_buffer_indices_common_count < 2); + possible_buffer_indices_common[possible_buffer_indices_common_count++] = + possible_buffer_index_first; + } + } + } + } + if (!possible_buffer_indices_common_count) { + // Too wide range requested - no buffer that contains both the start and the + // end. + return false; + } + + size_t gigabyte_first = size_t(start_scaled >> 30); + size_t gigabyte_last = size_t(last_scaled >> 30); + + // Choose the buffer that the range will be accessed through. + size_t new_buffer_index; + if (possible_buffer_indices_common_count >= 2) { + // Prefer the buffer that is already used to make less aliasing barriers. + assert_true(gigabyte_first + 1 >= gigabyte_last); + size_t possible_buffer_indices_already_used[2] = {}; + for (size_t i = gigabyte_first; i <= gigabyte_last; ++i) { + size_t gigabyte_current_buffer_index = scaled_resolve_1gb_buffer_indices_[i]; + for (size_t j = 0; j < possible_buffer_indices_common_count; ++j) { + if (possible_buffer_indices_common[j] == gigabyte_current_buffer_index) { + ++possible_buffer_indices_already_used[j]; + } + } + } + new_buffer_index = possible_buffer_indices_common[size_t( + possible_buffer_indices_already_used[1] > possible_buffer_indices_already_used[0])]; + } else { + // The range can be accessed only by one buffer. + new_buffer_index = possible_buffer_indices_common[0]; + } + + // Switch the current buffer for the range. + const ScaledResolveVirtualBuffer* new_buffer = + scaled_resolve_2gb_buffers_[new_buffer_index].get(); + assert_not_null(new_buffer); + ID3D12Resource* new_buffer_resource = new_buffer->resource(); + for (size_t i = gigabyte_first; i <= gigabyte_last; ++i) { + size_t gigabyte_current_buffer_index = scaled_resolve_1gb_buffer_indices_[i]; + if (gigabyte_current_buffer_index == new_buffer_index) { + continue; + } + if (gigabyte_current_buffer_index != SIZE_MAX) { + ScaledResolveVirtualBuffer* gigabyte_current_buffer = + scaled_resolve_2gb_buffers_[gigabyte_current_buffer_index].get(); + assert_not_null(gigabyte_current_buffer); + command_processor_.PushAliasingBarrier(gigabyte_current_buffer->resource(), + new_buffer_resource); + // An aliasing barrier synchronizes and flushes everything. + gigabyte_current_buffer->ClearUAVBarrierPending(); + } + scaled_resolve_1gb_buffer_indices_[i] = new_buffer_index; + } + + scaled_resolve_current_range_start_scaled_ = start_scaled; + scaled_resolve_current_range_length_scaled_ = length_scaled; + return true; +} + +void D3D12TextureCache::TransitionCurrentScaledResolveRange(D3D12_RESOURCE_STATES new_state) { + assert_true(IsDrawResolutionScaled()); + ScaledResolveVirtualBuffer& buffer = GetCurrentScaledResolveBuffer(); + command_processor_.PushTransitionBarrier(buffer.resource(), buffer.SetResourceState(new_state), + new_state); +} + +void D3D12TextureCache::CreateCurrentScaledResolveRangeUintPow2SRV( + D3D12_CPU_DESCRIPTOR_HANDLE handle, uint32_t element_size_bytes_pow2) { + assert_true(IsDrawResolutionScaled()); + size_t buffer_index = GetCurrentScaledResolveBufferIndex(); + const ScaledResolveVirtualBuffer* buffer = scaled_resolve_2gb_buffers_[buffer_index].get(); + assert_not_null(buffer); + ui::d3d12::util::CreateBufferTypedSRV( + command_processor_.GetD3D12Provider().GetDevice(), handle, buffer->resource(), + ui::d3d12::util::GetUintPow2DXGIFormat(element_size_bytes_pow2), + uint32_t(scaled_resolve_current_range_length_scaled_ >> element_size_bytes_pow2), + (scaled_resolve_current_range_start_scaled_ - (uint64_t(buffer_index) << 30)) >> + element_size_bytes_pow2); +} + +void D3D12TextureCache::CreateCurrentScaledResolveRangeUintPow2UAV( + D3D12_CPU_DESCRIPTOR_HANDLE handle, uint32_t element_size_bytes_pow2) { + assert_true(IsDrawResolutionScaled()); + size_t buffer_index = GetCurrentScaledResolveBufferIndex(); + const ScaledResolveVirtualBuffer* buffer = scaled_resolve_2gb_buffers_[buffer_index].get(); + assert_not_null(buffer); + ui::d3d12::util::CreateBufferTypedUAV( + command_processor_.GetD3D12Provider().GetDevice(), handle, buffer->resource(), + ui::d3d12::util::GetUintPow2DXGIFormat(element_size_bytes_pow2), + uint32_t(scaled_resolve_current_range_length_scaled_ >> element_size_bytes_pow2), + (scaled_resolve_current_range_start_scaled_ - (uint64_t(buffer_index) << 30)) >> + element_size_bytes_pow2); +} + +ID3D12Resource* D3D12TextureCache::RequestSwapTexture(D3D12_SHADER_RESOURCE_VIEW_DESC& srv_desc_out, + xenos::TextureFormat& format_out, + uint32_t* width_unscaled_out, + uint32_t* height_unscaled_out) { + const auto& regs = register_file(); + xenos::xe_gpu_texture_fetch_t fetch = regs.GetTextureFetch(0); + TextureKey key; + BindingInfoFromFetchConstant(fetch, key, nullptr); + if (!key.is_valid || key.base_page == 0 || key.dimension != xenos::DataDimension::k2DOrStacked) { + return nullptr; + } + D3D12Texture* texture = static_cast(FindOrCreateTexture(key)); + if (texture == nullptr || !LoadTextureData(*texture)) { + return nullptr; + } + texture->MarkAsUsed(); + // The swap texture is likely to be used only for the presentation compute + // shader, and not during emulation, where it'd be NON_PIXEL_SHADER_RESOURCE | + // PIXEL_SHADER_RESOURCE. + ID3D12Resource* texture_resource = texture->resource(); + command_processor_.PushTransitionBarrier( + texture_resource, texture->SetResourceState(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE), + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + srv_desc_out.Format = GetDXGIUnormFormat(key); + srv_desc_out.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + srv_desc_out.Shader4ComponentMapping = + GuestToHostSwizzle(fetch.swizzle, GetHostFormatSwizzle(key)) | + D3D12_SHADER_COMPONENT_MAPPING_ALWAYS_SET_BIT_AVOIDING_ZEROMEM_MISTAKES; + srv_desc_out.Texture2D.MostDetailedMip = 0; + srv_desc_out.Texture2D.MipLevels = 1; + srv_desc_out.Texture2D.PlaneSlice = 0; + srv_desc_out.Texture2D.ResourceMinLODClamp = 0.0f; + // Only texture->key, not the result of BindingInfoFromFetchConstant, contains + // whether the texture is scaled. + key = texture->key(); + if (width_unscaled_out) { + *width_unscaled_out = key.GetWidth(); + } + if (height_unscaled_out) { + *height_unscaled_out = key.GetHeight(); + } + format_out = key.format; + return texture_resource; +} + +D3D12TextureCache::D3D12Texture::D3D12Texture(D3D12TextureCache& texture_cache, + const TextureKey& key, ID3D12Resource* resource, + D3D12_RESOURCE_STATES resource_state, + bool track_usage) + : Texture(texture_cache, key, track_usage), + resource_(resource), + resource_state_(resource_state) { + ID3D12Device* device = texture_cache.command_processor_.GetD3D12Provider().GetDevice(); + D3D12_RESOURCE_DESC resource_desc = resource_->GetDesc(); + SetHostMemoryUsage(device->GetResourceAllocationInfo(0, 1, &resource_desc).SizeInBytes); +} + +D3D12TextureCache::D3D12Texture::~D3D12Texture() { + auto& d3d12_texture_cache = static_cast(texture_cache()); + for (const auto& descriptor_pair : srv_descriptors_) { + d3d12_texture_cache.ReleaseTextureDescriptor(descriptor_pair.second); + } +} + +bool D3D12TextureCache::IsDecompressionNeeded(xenos::TextureFormat format, uint32_t width, + uint32_t height) const { + DXGI_FORMAT dxgi_format_uncompressed = host_formats_[uint32_t(format)].dxgi_format_uncompressed; + if (dxgi_format_uncompressed == DXGI_FORMAT_UNKNOWN) { + return false; + } + const FormatInfo* format_info = FormatInfo::Get(format); + if (!(width & (format_info->block_width - 1)) && !(height & (format_info->block_height - 1))) { + return false; + } + // UnalignedBlockTexturesSupported is for block-compressed textures with the + // block size of 4x4, but not for 2x1 (4:2:2) subsampled formats. + if (format_info->block_width == 4 && format_info->block_height == 4 && + command_processor_.GetD3D12Provider().AreUnalignedBlockTexturesSupported()) { + return false; + } + return true; +} + +TextureCache::LoadShaderIndex D3D12TextureCache::GetLoadShaderIndex(TextureKey key) const { + const HostFormat& host_format = host_formats_[uint32_t(key.format)]; + if (key.signed_separate) { + return host_format.load_shader_signed; + } + if (IsDecompressionNeeded(key.format, key.GetWidth(), key.GetHeight())) { + return host_format.load_shader_decompress; + } + return host_format.load_shader; +} + +bool D3D12TextureCache::IsSignedVersionSeparateForFormat(TextureKey key) const { + const HostFormat& host_format = host_formats_[uint32_t(key.format)]; + return host_format.load_shader_signed != kLoadShaderIndexUnknown && + host_format.load_shader_signed != host_format.load_shader; +} + +bool D3D12TextureCache::IsScaledResolveSupportedForFormat(TextureKey key) const { + LoadShaderIndex load_shader = GetLoadShaderIndex(key); + return load_shader != kLoadShaderIndexUnknown && load_pipelines_scaled_[load_shader] != nullptr; +} + +uint32_t D3D12TextureCache::GetHostFormatSwizzle(TextureKey key) const { + // Dense cache-line-aligned swizzle array avoids cache misses from accessing + // the full HostFormat struct on every texture fetch. + alignas(64) static const auto swizzle_cache = []() { + std::array arr{}; + for (int i = 0; i < 64; ++i) { + arr[i] = static_cast(host_formats_[i].swizzle); + } + return arr; + }(); + return swizzle_cache[uint32_t(key.format)]; +} + +uint32_t D3D12TextureCache::GetMaxHostTextureWidthHeight(xenos::DataDimension dimension) const { + switch (dimension) { + case xenos::DataDimension::k1D: + case xenos::DataDimension::k2DOrStacked: + // 1D and 2D are emulated as 2D arrays. + return D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; + case xenos::DataDimension::k3D: + return D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; + case xenos::DataDimension::kCube: + return D3D12_REQ_TEXTURECUBE_DIMENSION; + default: + assert_unhandled_case(dimension); + return 0; + } +} + +uint32_t D3D12TextureCache::GetMaxHostTextureDepthOrArraySize( + xenos::DataDimension dimension) const { + switch (dimension) { + case xenos::DataDimension::k1D: + case xenos::DataDimension::k2DOrStacked: + // 1D and 2D are emulated as 2D arrays. + return D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; + case xenos::DataDimension::k3D: + return D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; + case xenos::DataDimension::kCube: + return D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION / 6 * 6; + default: + assert_unhandled_case(dimension); + return 0; + } +} + +std::unique_ptr D3D12TextureCache::CreateTexture(TextureKey key) { + D3D12_RESOURCE_DESC desc; + desc.Format = GetDXGIResourceFormat(key); + if (desc.Format == DXGI_FORMAT_UNKNOWN) { + unsupported_format_features_used_[uint32_t(key.format)] |= kUnsupportedResourceBit; + return nullptr; + } + if (key.dimension == xenos::DataDimension::k3D) { + desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE3D; + } else { + // 1D textures are treated as 2D for simplicity. + desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + } + desc.Alignment = 0; + desc.Width = key.GetWidth(); + desc.Height = key.GetHeight(); + if (key.scaled_resolve) { + desc.Width *= draw_resolution_scale_x(); + desc.Height *= draw_resolution_scale_y(); + } + desc.DepthOrArraySize = key.GetDepthOrArraySize(); + desc.MipLevels = key.mip_max_level + 1; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + // Untiling through a buffer instead of using unordered access because copying + // is not done that often. + desc.Flags = D3D12_RESOURCE_FLAG_NONE; + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + // Assuming untiling will be the next operation. + D3D12_RESOURCE_STATES resource_state = D3D12_RESOURCE_STATE_COPY_DEST; + Microsoft::WRL::ComPtr resource; + if (FAILED(device->CreateCommittedResource(&ui::d3d12::util::kHeapPropertiesDefault, + provider.GetHeapFlagCreateNotZeroed(), &desc, + resource_state, nullptr, IID_PPV_ARGS(&resource)))) { + return nullptr; + } + return std::unique_ptr(new D3D12Texture(*this, key, resource.Get(), resource_state)); +} + +bool D3D12TextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture, bool load_base, + bool load_mips) { + D3D12Texture& d3d12_texture = static_cast(texture); + TextureKey texture_key = d3d12_texture.key(); + + DeferredCommandList& command_list = command_processor_.GetDeferredCommandList(); + ID3D12Device* device = command_processor_.GetD3D12Provider().GetDevice(); + + // Get the pipeline. + LoadShaderIndex load_shader = GetLoadShaderIndex(texture_key); + if (load_shader == kLoadShaderIndexUnknown) { + return false; + } + bool texture_resolution_scaled = texture_key.scaled_resolve; + ID3D12PipelineState* pipeline = texture_resolution_scaled + ? load_pipelines_scaled_[load_shader].Get() + : load_pipelines_[load_shader].Get(); + if (pipeline == nullptr) { + return false; + } + const LoadShaderInfo& load_shader_info = GetLoadShaderInfo(load_shader); + + // Get the guest layout. + const texture_util::TextureGuestLayout& guest_layout = d3d12_texture.guest_layout(); + xenos::DataDimension dimension = texture_key.dimension; + bool is_3d = dimension == xenos::DataDimension::k3D; + bool is_3d_tiling = is_3d || d3d12_texture.force_load_3d_tiling(); + uint32_t width = texture_key.GetWidth(); + uint32_t height = texture_key.GetHeight(); + uint32_t depth_or_array_size = texture_key.GetDepthOrArraySize(); + uint32_t depth = is_3d ? depth_or_array_size : 1; + uint32_t array_size = is_3d ? 1 : depth_or_array_size; + xenos::TextureFormat guest_format = texture_key.format; + const FormatInfo* guest_format_info = FormatInfo::Get(guest_format); + uint32_t block_width = guest_format_info->block_width; + uint32_t block_height = guest_format_info->block_height; + uint32_t bytes_per_block = guest_format_info->bytes_per_block(); + uint32_t level_first = load_base ? 0 : 1; + uint32_t level_last = load_mips ? texture_key.mip_max_level : 0; + assert_true(level_first <= level_last); + uint32_t level_packed = guest_layout.packed_level; + uint32_t level_stored_first = std::min(level_first, level_packed); + uint32_t level_stored_last = std::min(level_last, level_packed); + uint32_t texture_resolution_scale_x = texture_resolution_scaled ? draw_resolution_scale_x() : 1; + uint32_t texture_resolution_scale_y = texture_resolution_scaled ? draw_resolution_scale_y() : 1; + + // The loop counter can mean two things depending on whether the packed mip + // tail is stored as mip 0, because in this case, it would be ambiguous since + // both the base and the mips would be on "level 0", but stored in separate + // places. + uint32_t loop_level_first, loop_level_last; + if (level_packed == 0) { + // Packed mip tail is the level 0 - may need to load mip tails for the base, + // the mips, or both. + // Loop iteration 0 - base packed mip tail. + // Loop iteration 1 - mips packed mip tail. + loop_level_first = uint32_t(level_first != 0); + loop_level_last = uint32_t(level_last != 0); + } else { + // Packed mip tail is not the level 0. + // Loop iteration is the actual level being loaded. + loop_level_first = level_stored_first; + loop_level_last = level_stored_last; + } + + // Get the host layout and the buffer. + bool host_block_compressed = host_formats_[uint32_t(guest_format)].is_block_compressed && + !IsDecompressionNeeded(guest_format, width, height); + uint32_t host_block_width = host_block_compressed ? block_width : 1; + uint32_t host_block_height = host_block_compressed ? block_height : 1; + uint32_t host_x_blocks_per_thread = UINT32_C(1) + << load_shader_info.guest_x_blocks_per_thread_log2; + if (!host_block_compressed) { + // Decompressing guest blocks. + host_x_blocks_per_thread *= block_width; + } + UINT64 copy_buffer_size = 0; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT host_slice_layout_base; + UINT64 host_slice_size_base; + // Indexing is the same as for guest stored mips: + // 1...min(level_last, level_packed) if level_packed is not 0, or only 0 if + // level_packed == 0. + D3D12_PLACED_SUBRESOURCE_FOOTPRINT + host_slice_layouts_mips[xenos::kTextureMaxMips]; + UINT64 host_slice_sizes_mips[xenos::kTextureMaxMips]; + // Using custom calculations instead of GetCopyableFootprints because + // shaders may unconditionally copy multiple blocks along X per thread for + // simplicity, to make sure all rows (also including the last one - + // GetCopyableFootprints aligns row offsets, but not the total size) are + // properly padded to the number of blocks copied in an invocation without + // implicit assumptions about D3D12_TEXTURE_DATA_PITCH_ALIGNMENT. + DXGI_FORMAT host_copy_format = GetDXGIResourceFormat(guest_format, width, height); + for (uint32_t loop_level = loop_level_first; loop_level <= loop_level_last; ++loop_level) { + bool is_base = loop_level == 0; + uint32_t level = (level_packed == 0) ? 0 : loop_level; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT& level_host_slice_layout = + is_base ? host_slice_layout_base : host_slice_layouts_mips[level]; + level_host_slice_layout.Offset = copy_buffer_size; + level_host_slice_layout.Footprint.Format = host_copy_format; + if (level == level_packed) { + // Loading the packed tail for the base or the mips - load the whole tail + // to copy regions out of it. + const texture_util::TextureGuestLayout::Level& guest_layout_packed = + is_base ? guest_layout.base : guest_layout.mips[level]; + level_host_slice_layout.Footprint.Width = guest_layout_packed.x_extent_blocks * block_width; + level_host_slice_layout.Footprint.Height = guest_layout_packed.y_extent_blocks * block_height; + level_host_slice_layout.Footprint.Depth = guest_layout_packed.z_extent; + } else { + level_host_slice_layout.Footprint.Width = std::max(width >> level, uint32_t(1)); + level_host_slice_layout.Footprint.Height = std::max(height >> level, uint32_t(1)); + level_host_slice_layout.Footprint.Depth = std::max(depth >> level, uint32_t(1)); + } + level_host_slice_layout.Footprint.Width = + rex::round_up(level_host_slice_layout.Footprint.Width * texture_resolution_scale_x, + UINT(host_block_width)); + level_host_slice_layout.Footprint.Height = + rex::round_up(level_host_slice_layout.Footprint.Height * texture_resolution_scale_y, + UINT(host_block_height)); + level_host_slice_layout.Footprint.RowPitch = + rex::align(rex::round_up(level_host_slice_layout.Footprint.Width / host_block_width, + host_x_blocks_per_thread) * + load_shader_info.bytes_per_host_block, + uint32_t(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT)); + UINT64 level_host_slice_size = + rex::align(UINT64(level_host_slice_layout.Footprint.RowPitch) * + (level_host_slice_layout.Footprint.Height / host_block_height) * + level_host_slice_layout.Footprint.Depth, + UINT64(D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT)); + (is_base ? host_slice_size_base : host_slice_sizes_mips[level]) = level_host_slice_size; + copy_buffer_size += level_host_slice_size * array_size; + } + D3D12_RESOURCE_STATES copy_buffer_state = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + ID3D12Resource* copy_buffer = + command_processor_.RequestScratchGPUBuffer(uint32_t(copy_buffer_size), copy_buffer_state); + if (copy_buffer == nullptr) { + return false; + } + + // Begin loading. + // May use different buffers for scaled base and mips, and also addressability + // of more than 128 * 2^20 (2^D3D12_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP) + // texels is not mandatory - need two separate UAV descriptors for base and + // mips. + // Destination. + uint32_t descriptor_count = 1; + if (texture_resolution_scaled) { + // Source - base and mips, one or both. + descriptor_count += (level_first == 0 && level_last != 0) ? 2 : 1; + } else { + // Source - shared memory. + if (!bindless_resources_used_) { + ++descriptor_count; + } + } + ui::d3d12::util::DescriptorCpuGpuHandlePair descriptors_allocated[3]; + if (!command_processor_.RequestOneUseSingleViewDescriptors(descriptor_count, + descriptors_allocated)) { + command_processor_.ReleaseScratchGPUBuffer(copy_buffer, copy_buffer_state); + return false; + } + uint32_t descriptor_write_index = 0; + command_processor_.SetExternalPipeline(pipeline); + command_list.D3DSetComputeRootSignature(load_root_signature_.Get()); + // Set up the destination descriptor. + assert_true(descriptor_write_index < descriptor_count); + ui::d3d12::util::DescriptorCpuGpuHandlePair descriptor_dest = + descriptors_allocated[descriptor_write_index++]; + ui::d3d12::util::CreateBufferTypedUAV( + device, descriptor_dest.first, copy_buffer, + ui::d3d12::util::GetUintPow2DXGIFormat(load_shader_info.dest_bpe_log2), + uint32_t(copy_buffer_size) >> load_shader_info.dest_bpe_log2); + command_list.D3DSetComputeRootDescriptorTable(2, descriptor_dest.second); + // Set up the unscaled source descriptor (scaled needs two descriptors that + // depend on the buffer being current, so they will be set later - for mips, + // after loading the base is done). + if (!texture_resolution_scaled) { + D3D12SharedMemory& d3d12_shared_memory = static_cast(shared_memory()); + d3d12_shared_memory.UseForReading(); + ui::d3d12::util::DescriptorCpuGpuHandlePair descriptor_unscaled_source; + if (bindless_resources_used_) { + descriptor_unscaled_source = command_processor_.GetSharedMemoryUintPow2BindlessSRVHandlePair( + load_shader_info.source_bpe_log2); + } else { + assert_true(descriptor_write_index < descriptor_count); + descriptor_unscaled_source = descriptors_allocated[descriptor_write_index++]; + d3d12_shared_memory.WriteUintPow2SRVDescriptor(descriptor_unscaled_source.first, + load_shader_info.source_bpe_log2); + } + command_list.D3DSetComputeRootDescriptorTable(1, descriptor_unscaled_source.second); + } + + // Submit the copy buffer population commands. + + auto& cbuffer_pool = command_processor_.GetConstantBufferPool(); + LoadConstants load_constants; + // 3 bits for each. + assert_true(texture_resolution_scale_x <= 7); + assert_true(texture_resolution_scale_y <= 7); + load_constants.is_tiled_3d_endian_scale = + uint32_t(texture_key.tiled) | (uint32_t(is_3d_tiling) << 1) | + (uint32_t(texture_key.endianness) << 2) | (texture_resolution_scale_x << 4) | + (texture_resolution_scale_y << 7); + + // The loop is slices within levels because the base and the levels may need + // different portions of the scaled resolve virtual address space to be + // available through buffers, and to create a descriptor, the buffer start + // address is required - which may be different for base and mips. + bool scaled_mips_source_set_up = false; + uint32_t guest_x_blocks_per_group_log2 = load_shader_info.GetGuestXBlocksPerGroupLog2(); + for (uint32_t loop_level = loop_level_first; loop_level <= loop_level_last; ++loop_level) { + bool is_base = loop_level == 0; + uint32_t level = (level_packed == 0) ? 0 : loop_level; + + uint32_t guest_address = (is_base ? texture_key.base_page : texture_key.mip_page) << 12; + + // Set up the base or mips source, also making it accessible if loading from + // scaled resolve memory. + if (texture_resolution_scaled && (is_base || !scaled_mips_source_set_up)) { + uint32_t guest_size_unscaled = + is_base ? d3d12_texture.GetGuestBaseSize() : d3d12_texture.GetGuestMipsSize(); + if (!MakeScaledResolveRangeCurrent(guest_address, guest_size_unscaled, + load_shader_info.source_bpe_log2)) { + command_processor_.ReleaseScratchGPUBuffer(copy_buffer, copy_buffer_state); + return false; + } + TransitionCurrentScaledResolveRange(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + assert_true(descriptor_write_index < descriptor_count); + ui::d3d12::util::DescriptorCpuGpuHandlePair descriptor_scaled_source = + descriptors_allocated[descriptor_write_index++]; + CreateCurrentScaledResolveRangeUintPow2SRV(descriptor_scaled_source.first, + load_shader_info.source_bpe_log2); + command_list.D3DSetComputeRootDescriptorTable(1, descriptor_scaled_source.second); + if (!is_base) { + scaled_mips_source_set_up = true; + } + } + + if (texture_resolution_scaled) { + // Offset already applied in the buffer because more than 512 MB can't be + // directly addresses as R32 on some hardware (above + // 2^D3D12_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP). + load_constants.guest_offset = 0; + } else { + load_constants.guest_offset = guest_address; + } + if (!is_base) { + load_constants.guest_offset += guest_layout.mip_offsets_bytes[level] * + (texture_resolution_scale_x * texture_resolution_scale_y); + } + const texture_util::TextureGuestLayout::Level& level_guest_layout = + is_base ? guest_layout.base : guest_layout.mips[level]; + uint32_t level_guest_pitch = level_guest_layout.row_pitch_bytes; + if (texture_key.tiled) { + // Shaders expect pitch in blocks for tiled textures. + level_guest_pitch /= bytes_per_block; + assert_zero(level_guest_pitch & (xenos::kTextureTileWidthHeight - 1)); + } + load_constants.guest_pitch_aligned = level_guest_pitch; + load_constants.guest_z_stride_block_rows_aligned = level_guest_layout.z_slice_stride_block_rows; + assert_true(!is_3d_tiling || !(load_constants.guest_z_stride_block_rows_aligned & + (xenos::kTextureTileWidthHeight - 1))); + + uint32_t level_width, level_height, level_depth; + if (level == level_packed) { + // This is the packed mip tail, containing not only the specified level, + // but also other levels at different offsets - load the entire needed + // extents. + level_width = level_guest_layout.x_extent_blocks * block_width; + level_height = level_guest_layout.y_extent_blocks * block_height; + level_depth = level_guest_layout.z_extent; + } else { + level_width = std::max(width >> level, uint32_t(1)); + level_height = std::max(height >> level, uint32_t(1)); + level_depth = std::max(depth >> level, uint32_t(1)); + } + load_constants.size_blocks[0] = + (level_width + (block_width - 1)) / block_width * texture_resolution_scale_x; + load_constants.size_blocks[1] = + (level_height + (block_height - 1)) / block_height * texture_resolution_scale_y; + load_constants.size_blocks[2] = level_depth; + load_constants.height_texels = level_height; + + uint32_t group_count_x = + (load_constants.size_blocks[0] + ((UINT32_C(1) << guest_x_blocks_per_group_log2) - 1)) >> + guest_x_blocks_per_group_log2; + uint32_t group_count_y = + (load_constants.size_blocks[1] + ((UINT32_C(1) << kLoadGuestYBlocksPerGroupLog2) - 1)) >> + kLoadGuestYBlocksPerGroupLog2; + + const D3D12_PLACED_SUBRESOURCE_FOOTPRINT& level_host_slice_layout = + is_base ? host_slice_layout_base : host_slice_layouts_mips[level]; + uint32_t host_slice_size = + uint32_t(is_base ? host_slice_size_base : host_slice_sizes_mips[level]); + load_constants.host_offset = uint32_t(level_host_slice_layout.Offset); + load_constants.host_pitch = level_host_slice_layout.Footprint.RowPitch; + + command_list.D3DSetComputeRoot32BitConstants(0, sizeof(load_constants) / sizeof(uint32_t), + &load_constants, 0); + + uint32_t level_array_slice_stride_bytes_scaled = + level_guest_layout.array_slice_stride_bytes * + (texture_resolution_scale_x * texture_resolution_scale_y); + for (uint32_t slice = 0; slice < array_size; ++slice) { + if (slice != 0) { + command_list.D3DSetComputeRoot32BitConstants( + 0, sizeof(load_constants.guest_offset) / sizeof(uint32_t), &load_constants.guest_offset, + offsetof(LoadConstants, guest_offset) / sizeof(uint32_t)); + command_list.D3DSetComputeRoot32BitConstants( + 0, sizeof(load_constants.host_offset) / sizeof(uint32_t), &load_constants.host_offset, + offsetof(LoadConstants, host_offset) / sizeof(uint32_t)); + } + assert_true(copy_buffer_state == D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + command_processor_.SubmitBarriers(); + command_list.D3DDispatch(group_count_x, group_count_y, load_constants.size_blocks[2]); + load_constants.guest_offset += level_array_slice_stride_bytes_scaled; + load_constants.host_offset += host_slice_size; + } + } + + // Update LRU caching because the texture will be used by the command list. + d3d12_texture.MarkAsUsed(); + + // Submit copying from the copy buffer to the host texture. + ID3D12Resource* texture_resource = d3d12_texture.resource(); + command_processor_.PushTransitionBarrier( + texture_resource, d3d12_texture.SetResourceState(D3D12_RESOURCE_STATE_COPY_DEST), + D3D12_RESOURCE_STATE_COPY_DEST); + command_processor_.PushTransitionBarrier(copy_buffer, copy_buffer_state, + D3D12_RESOURCE_STATE_COPY_SOURCE); + copy_buffer_state = D3D12_RESOURCE_STATE_COPY_SOURCE; + command_processor_.SubmitBarriers(); + uint32_t texture_level_count = texture_key.mip_max_level + 1; + D3D12_TEXTURE_COPY_LOCATION location_source, location_dest; + location_source.pResource = copy_buffer; + location_source.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + location_dest.pResource = texture_resource; + location_dest.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + for (uint32_t level = level_first; level <= level_last; ++level) { + uint32_t guest_level = std::min(level, level_packed); + location_source.PlacedFootprint = + level ? host_slice_layouts_mips[guest_level] : host_slice_layout_base; + location_dest.SubresourceIndex = level; + UINT64 host_slice_size = level ? host_slice_sizes_mips[guest_level] : host_slice_size_base; + D3D12_BOX source_box; + const D3D12_BOX* source_box_ptr; + if (level >= level_packed) { + uint32_t level_offset_blocks_x, level_offset_blocks_y, level_offset_z; + texture_util::GetPackedMipOffset(width, height, depth, guest_format, level, + level_offset_blocks_x, level_offset_blocks_y, + level_offset_z); + source_box.left = level_offset_blocks_x * block_width * texture_resolution_scale_x; + source_box.top = level_offset_blocks_y * block_height * texture_resolution_scale_y; + source_box.front = level_offset_z; + source_box.right = + source_box.left + + rex::align(std::max((width * texture_resolution_scale_x) >> level, uint32_t(1)), + host_block_width); + source_box.bottom = + source_box.top + + rex::align(std::max((height * texture_resolution_scale_y) >> level, uint32_t(1)), + host_block_height); + source_box.back = source_box.front + std::max(depth >> level, uint32_t(1)); + source_box_ptr = &source_box; + } else { + source_box_ptr = nullptr; + } + for (uint32_t slice = 0; slice < array_size; ++slice) { + command_list.D3DCopyTextureRegion(&location_dest, 0, 0, 0, &location_source, source_box_ptr); + location_dest.SubresourceIndex += texture_level_count; + location_source.PlacedFootprint.Offset += host_slice_size; + } + } + + command_processor_.ReleaseScratchGPUBuffer(copy_buffer, copy_buffer_state); + + return true; +} + +void D3D12TextureCache::UpdateTextureBindingsImpl(uint32_t fetch_constant_mask) { + uint32_t bindings_remaining = fetch_constant_mask; + uint32_t binding_index; + while (rex::bit_scan_forward(bindings_remaining, &binding_index)) { + bindings_remaining &= ~(UINT32_C(1) << binding_index); + D3D12TextureBinding& d3d12_binding = d3d12_texture_bindings_[binding_index]; + d3d12_binding.Reset(); + const TextureBinding* binding = GetValidTextureBinding(binding_index); + if (!binding) { + continue; + } + if (IsSignedVersionSeparateForFormat(binding->key)) { + if (binding->texture && texture_util::IsAnySignNotSigned(binding->swizzled_signs)) { + d3d12_binding.descriptor_index = + FindOrCreateTextureDescriptor(*static_cast(binding->texture), + binding->key.dimension, false, binding->host_swizzle); + } + if (binding->texture_signed && texture_util::IsAnySignSigned(binding->swizzled_signs)) { + d3d12_binding.descriptor_index_signed = + FindOrCreateTextureDescriptor(*static_cast(binding->texture_signed), + binding->key.dimension, true, binding->host_swizzle); + } + } else { + D3D12Texture* texture = static_cast(binding->texture); + if (texture) { + if (texture_util::IsAnySignNotSigned(binding->swizzled_signs)) { + d3d12_binding.descriptor_index = FindOrCreateTextureDescriptor( + *texture, binding->key.dimension, false, binding->host_swizzle); + } + if (texture_util::IsAnySignSigned(binding->swizzled_signs)) { + d3d12_binding.descriptor_index_signed = FindOrCreateTextureDescriptor( + *texture, binding->key.dimension, true, binding->host_swizzle); + } + } + } + } +} + +ID3D12Resource* D3D12TextureCache::D3D12Texture::GetOrCreate3DAs2DResource( + D3D12_RESOURCE_STATES end_state) { + if (!REXCVAR_GET(gpu_3d_to_2d_texture)) { + return nullptr; + } + + auto& d3d12_cache = static_cast(texture_cache()); + + if (texture_3d_as_2d_) { + d3d12_cache.command_processor_.PushTransitionBarrier( + texture_3d_as_2d_->resource(), texture_3d_as_2d_->SetResourceState(end_state), end_state); + return texture_3d_as_2d_->resource(); + } + + const ui::d3d12::D3D12Provider& provider = d3d12_cache.command_processor_.GetD3D12Provider(); + ID3D12Device* device = provider.GetDevice(); + + D3D12_RESOURCE_DESC desc = {}; + desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + desc.Alignment = 0; + desc.Width = key().GetWidth(); + desc.Height = key().GetHeight(); + desc.DepthOrArraySize = 1; + desc.MipLevels = 1; + desc.Format = d3d12_cache.GetDXGIResourceFormat(key()); + if (desc.Format == DXGI_FORMAT_UNKNOWN) { + return nullptr; + } + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + desc.Flags = D3D12_RESOURCE_FLAG_NONE; + + D3D12_RESOURCE_STATES initial_state = D3D12_RESOURCE_STATE_COPY_DEST; + Microsoft::WRL::ComPtr resource_2d; + if (FAILED(device->CreateCommittedResource(&ui::d3d12::util::kHeapPropertiesDefault, + provider.GetHeapFlagCreateNotZeroed(), &desc, + initial_state, nullptr, IID_PPV_ARGS(&resource_2d)))) { + REXGPU_ERROR("D3D12TextureCache: Failed to create 3D-as-2D wrapper resource"); + return nullptr; + } + + TextureKey key_2d = key(); + key_2d.depth_or_array_size_minus_1 = 0; + key_2d.mip_max_level = 0; + texture_3d_as_2d_.reset( + new D3D12Texture(d3d12_cache, key_2d, resource_2d.Get(), initial_state, false)); + texture_3d_as_2d_->SetForceLoad3DTiling(true); + + if (!d3d12_cache.LoadTextureData(*texture_3d_as_2d_)) { + REXGPU_ERROR("D3D12TextureCache: Failed to load 3D-as-2D wrapper data"); + texture_3d_as_2d_.reset(); + return nullptr; + } + + d3d12_cache.command_processor_.PushTransitionBarrier( + texture_3d_as_2d_->resource(), texture_3d_as_2d_->SetResourceState(end_state), end_state); + return texture_3d_as_2d_->resource(); +} + +uint32_t D3D12TextureCache::FindOrCreateTextureDescriptor(D3D12Texture& texture, + xenos::DataDimension dimension, + bool is_signed, uint32_t host_swizzle) { + D3D12Texture::SRVDescriptorKey descriptor_key; + descriptor_key.key = 0; + descriptor_key.is_signed = uint32_t(is_signed); + descriptor_key.host_swizzle = host_swizzle; + descriptor_key.dimension = uint32_t(dimension); + + // Try to find an existing descriptor. + uint32_t existing_descriptor_index = texture.GetSRVDescriptorIndex(descriptor_key); + if (existing_descriptor_index != UINT32_MAX) { + PROFILE_TEXTURE_CACHE_HIT(); + return existing_descriptor_index; + } + PROFILE_TEXTURE_CACHE_MISS(); + + TextureKey texture_key = texture.key(); + + // Create a new bindless or cached descriptor if supported. + D3D12_SHADER_RESOURCE_VIEW_DESC desc = {}; + + if (IsSignedVersionSeparateForFormat(texture_key) && + texture_key.signed_separate != uint32_t(is_signed)) { + // Not the version with the needed signedness. + return UINT32_MAX; + } + xenos::TextureFormat format = texture_key.format; + if (is_signed) { + // Not supporting signed compressed textures - hopefully DXN and DXT5A are + // not used as signed. + desc.Format = host_formats_[uint32_t(format)].dxgi_format_signed; + } else { + desc.Format = GetDXGIUnormFormat(texture_key); + } + if (desc.Format == DXGI_FORMAT_UNKNOWN) { + unsupported_format_features_used_[uint32_t(format)] |= + is_signed ? kUnsupportedSnormBit : kUnsupportedUnormBit; + return UINT32_MAX; + } + + uint32_t mip_levels = texture_key.mip_max_level + 1; + ID3D12Resource* resource_for_view = texture.resource(); + switch (dimension) { + case xenos::DataDimension::k3D: + desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D; + desc.Texture3D.MostDetailedMip = 0; + desc.Texture3D.MipLevels = mip_levels; + desc.Texture3D.ResourceMinLODClamp = 0.0f; + break; + case xenos::DataDimension::kCube: + desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE; + desc.TextureCube.MostDetailedMip = 0; + desc.TextureCube.MipLevels = mip_levels; + desc.TextureCube.ResourceMinLODClamp = 0.0f; + break; + case xenos::DataDimension::k1D: + case xenos::DataDimension::k2DOrStacked: + desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY; + if (texture_key.dimension == xenos::DataDimension::k3D) { + resource_for_view = + texture.GetOrCreate3DAs2DResource(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + if (!resource_for_view) { + return UINT32_MAX; + } + desc.Texture2DArray.MostDetailedMip = 0; + desc.Texture2DArray.MipLevels = 1; + desc.Texture2DArray.FirstArraySlice = 0; + desc.Texture2DArray.ArraySize = 1; + desc.Texture2DArray.PlaneSlice = 0; + desc.Texture2DArray.ResourceMinLODClamp = 0.0f; + } else { + desc.Texture2DArray.MostDetailedMip = 0; + desc.Texture2DArray.MipLevels = mip_levels; + desc.Texture2DArray.FirstArraySlice = 0; + desc.Texture2DArray.ArraySize = texture_key.GetDepthOrArraySize(); + desc.Texture2DArray.PlaneSlice = 0; + desc.Texture2DArray.ResourceMinLODClamp = 0.0f; + } + break; + default: + assert_unhandled_case(dimension); + return UINT32_MAX; + } + + desc.Shader4ComponentMapping = + host_swizzle | D3D12_SHADER_COMPONENT_MAPPING_ALWAYS_SET_BIT_AVOIDING_ZEROMEM_MISTAKES; + + ID3D12Device* device = command_processor_.GetD3D12Provider().GetDevice(); + uint32_t descriptor_index; + if (bindless_resources_used_) { + descriptor_index = command_processor_.RequestPersistentViewBindlessDescriptor(); + if (descriptor_index == UINT32_MAX) { + REXGPU_ERROR( + "Failed to create a texture descriptor - no free bindless view " + "descriptors"); + return UINT32_MAX; + } + } else { + if (!srv_descriptor_cache_free_.empty()) { + descriptor_index = srv_descriptor_cache_free_.back(); + srv_descriptor_cache_free_.pop_back(); + } else { + // Allocated + 1 (including the descriptor that is being added), rounded + // up to kSRVDescriptorCachePageSize, (allocated + 1 + size - 1). + uint32_t cache_pages_needed = + (srv_descriptor_cache_allocated_ + kSRVDescriptorCachePageSize) / + kSRVDescriptorCachePageSize; + if (srv_descriptor_cache_.size() < cache_pages_needed) { + D3D12_DESCRIPTOR_HEAP_DESC cache_heap_desc; + cache_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + cache_heap_desc.NumDescriptors = kSRVDescriptorCachePageSize; + cache_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + cache_heap_desc.NodeMask = 0; + while (srv_descriptor_cache_.size() < cache_pages_needed) { + Microsoft::WRL::ComPtr cache_heap; + if (FAILED(device->CreateDescriptorHeap(&cache_heap_desc, IID_PPV_ARGS(&cache_heap)))) { + REXGPU_ERROR( + "D3D12TextureCache: Failed to create a texture descriptor - " + "couldn't create a descriptor cache heap"); + return UINT32_MAX; + } + srv_descriptor_cache_.emplace_back(cache_heap.Get()); + } + } + descriptor_index = srv_descriptor_cache_allocated_++; + } + } + device->CreateShaderResourceView(resource_for_view, &desc, + GetTextureDescriptorCPUHandle(descriptor_index)); + texture.AddSRVDescriptorIndex(descriptor_key, descriptor_index); + return descriptor_index; +} + +void D3D12TextureCache::ReleaseTextureDescriptor(uint32_t descriptor_index) { + if (bindless_resources_used_) { + command_processor_.ReleaseViewBindlessDescriptorImmediately(descriptor_index); + } else { + srv_descriptor_cache_free_.push_back(descriptor_index); + } +} + +D3D12_CPU_DESCRIPTOR_HANDLE D3D12TextureCache::GetTextureDescriptorCPUHandle( + uint32_t descriptor_index) const { + const ui::d3d12::D3D12Provider& provider = command_processor_.GetD3D12Provider(); + if (bindless_resources_used_) { + return provider.OffsetViewDescriptor(command_processor_.GetViewBindlessHeapCPUStart(), + descriptor_index); + } + D3D12_CPU_DESCRIPTOR_HANDLE heap_start = + srv_descriptor_cache_[descriptor_index / kSRVDescriptorCachePageSize].heap_start(); + uint32_t heap_offset = descriptor_index % kSRVDescriptorCachePageSize; + return provider.OffsetViewDescriptor(heap_start, heap_offset); +} + +xenos::ClampMode D3D12TextureCache::NormalizeClampMode(xenos::ClampMode clamp_mode) const { + if (clamp_mode == xenos::ClampMode::kClampToHalfway) { + // No GL_CLAMP (clamp to half edge, half border) equivalent in Direct3D 12, + // but there's no Direct3D 9 equivalent anyway, and too weird to be suitable + // for intentional real usage. + return xenos::ClampMode::kClampToEdge; + } + if (clamp_mode == xenos::ClampMode::kMirrorClampToHalfway || + clamp_mode == xenos::ClampMode::kMirrorClampToBorder) { + // No Direct3D 12 equivalents. + return xenos::ClampMode::kMirrorClampToEdge; + } + return clamp_mode; +} + +} // namespace rex::graphics::d3d12 diff --git a/src/graphics/flags.cpp b/src/graphics/flags.cpp new file mode 100644 index 0000000..e2983a4 --- /dev/null +++ b/src/graphics/flags.cpp @@ -0,0 +1,53 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +REXCVAR_DEFINE_BOOL(gpu_allow_invalid_fetch_constants, false, "GPU", + "Allow invalid fetch constants"); +REXCVAR_DEFINE_BOOL(native_2x_msaa, true, "GPU", "Enable native 2x MSAA"); +REXCVAR_DEFINE_BOOL(depth_float24_round, false, "GPU", "Round float24 depth values"); +REXCVAR_DEFINE_BOOL(depth_float24_convert_in_pixel_shader, false, "GPU", + "Convert float24 depth in pixel shader"); +REXCVAR_DEFINE_BOOL(depth_transfer_not_equal_test, true, "GPU", + "Use not-equal test for depth transfer"); +REXCVAR_DEFINE_BOOL(gamma_render_target_as_unorm16, true, "GPU", + "Use R16G16B16A16_UNORM for gamma render targets (more accurate than sRGB)") + .lifecycle(rex::cvar::Lifecycle::kHotReload); +REXCVAR_DEFINE_STRING(dump_shaders, "", "GPU", "Path to dump shaders to"); +REXCVAR_DEFINE_BOOL(use_fuzzy_alpha_epsilon, false, "GPU", + "Use approximate compare for alpha test values to prevent " + "flickering on NVIDIA graphics cards"); +REXCVAR_DEFINE_BOOL(gpu_debug_markers, false, "GPU", + "Insert debug markers into GPU command streams for tools " + "like PIX and RenderDoc. Automatically enabled when " + "RenderDoc is detected."); + +bool IsGpuDebugMarkersEnabled() { + static bool cached = false; + static bool result = false; + if (!cached) { + cached = true; + if (REXCVAR_GET(gpu_debug_markers)) { + result = true; + REXLOG_INFO("GPU debug markers enabled via CVar"); + } else { + auto renderdoc_api = rex::ui::RenderDocAPI::CreateIfConnected(); + if (renderdoc_api) { + result = true; + REXLOG_INFO("GPU debug markers auto-enabled (RenderDoc detected)"); + } + } + } + return result; +} diff --git a/src/graphics/format/ucode.cpp b/src/graphics/format/ucode.cpp new file mode 100644 index 0000000..dec23e6 --- /dev/null +++ b/src/graphics/format/ucode.cpp @@ -0,0 +1,118 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +namespace rex::graphics::ucode { + +const AluScalarOpcodeInfo kAluScalarOpcodeInfos[64] = { + {"adds", 1, true, kAluOpChangedStateNone}, + {"adds_prev", 1, false, kAluOpChangedStateNone}, + {"muls", 1, true, kAluOpChangedStateNone}, + {"muls_prev", 1, false, kAluOpChangedStateNone}, + {"muls_prev2", 1, true, kAluOpChangedStateNone}, + {"maxs", 1, true, kAluOpChangedStateNone}, + {"mins", 1, true, kAluOpChangedStateNone}, + {"seqs", 1, false, kAluOpChangedStateNone}, + {"sgts", 1, false, kAluOpChangedStateNone}, + {"sges", 1, false, kAluOpChangedStateNone}, + {"snes", 1, false, kAluOpChangedStateNone}, + {"frcs", 1, false, kAluOpChangedStateNone}, + {"truncs", 1, false, kAluOpChangedStateNone}, + {"floors", 1, false, kAluOpChangedStateNone}, + {"exp", 1, false, kAluOpChangedStateNone}, + {"logc", 1, false, kAluOpChangedStateNone}, + {"log", 1, false, kAluOpChangedStateNone}, + {"rcpc", 1, false, kAluOpChangedStateNone}, + {"rcpf", 1, false, kAluOpChangedStateNone}, + {"rcp", 1, false, kAluOpChangedStateNone}, + {"rsqc", 1, false, kAluOpChangedStateNone}, + {"rsqf", 1, false, kAluOpChangedStateNone}, + {"rsq", 1, false, kAluOpChangedStateNone}, + {"maxas", 1, true, kAluOpChangedStateAddressRegister}, + {"maxasf", 1, true, kAluOpChangedStateAddressRegister}, + {"subs", 1, true, kAluOpChangedStateNone}, + {"subs_prev", 1, false, kAluOpChangedStateNone}, + {"setp_eq", 1, false, kAluOpChangedStatePredicate}, + {"setp_ne", 1, false, kAluOpChangedStatePredicate}, + {"setp_gt", 1, false, kAluOpChangedStatePredicate}, + {"setp_ge", 1, false, kAluOpChangedStatePredicate}, + {"setp_inv", 1, false, kAluOpChangedStatePredicate}, + {"setp_pop", 1, false, kAluOpChangedStatePredicate}, + {"setp_clr", 0, false, kAluOpChangedStatePredicate}, + {"setp_rstr", 1, false, kAluOpChangedStatePredicate}, + {"kills_eq", 1, false, kAluOpChangedStatePixelKill}, + {"kills_gt", 1, false, kAluOpChangedStatePixelKill}, + {"kills_ge", 1, false, kAluOpChangedStatePixelKill}, + {"kills_ne", 1, false, kAluOpChangedStatePixelKill}, + {"kills_one", 1, false, kAluOpChangedStatePixelKill}, + {"sqrt", 1, false, kAluOpChangedStateNone}, + {"opcode_41", 0, false, kAluOpChangedStateNone}, + {"mulsc", 2, false, kAluOpChangedStateNone}, + {"mulsc", 2, false, kAluOpChangedStateNone}, + {"addsc", 2, false, kAluOpChangedStateNone}, + {"addsc", 2, false, kAluOpChangedStateNone}, + {"subsc", 2, false, kAluOpChangedStateNone}, + {"subsc", 2, false, kAluOpChangedStateNone}, + {"sin", 1, false, kAluOpChangedStateNone}, + {"cos", 1, false, kAluOpChangedStateNone}, + {"retain_prev", 0, false, kAluOpChangedStateNone}, + {"opcode_51", 0, false, kAluOpChangedStateNone}, + {"opcode_52", 0, false, kAluOpChangedStateNone}, + {"opcode_53", 0, false, kAluOpChangedStateNone}, + {"opcode_54", 0, false, kAluOpChangedStateNone}, + {"opcode_55", 0, false, kAluOpChangedStateNone}, + {"opcode_56", 0, false, kAluOpChangedStateNone}, + {"opcode_57", 0, false, kAluOpChangedStateNone}, + {"opcode_58", 0, false, kAluOpChangedStateNone}, + {"opcode_59", 0, false, kAluOpChangedStateNone}, + {"opcode_60", 0, false, kAluOpChangedStateNone}, + {"opcode_61", 0, false, kAluOpChangedStateNone}, + {"opcode_62", 0, false, kAluOpChangedStateNone}, + {"opcode_63", 0, false, kAluOpChangedStateNone}, +}; + +const AluVectorOpcodeInfo kAluVectorOpcodeInfos[32] = { + {"add", {0b1111, 0b1111}, kAluOpChangedStateNone}, + {"mul", {0b1111, 0b1111}, kAluOpChangedStateNone}, + {"max", {0b1111, 0b1111}, kAluOpChangedStateNone}, + {"min", {0b1111, 0b1111}, kAluOpChangedStateNone}, + {"seq", {0b1111, 0b1111}, kAluOpChangedStateNone}, + {"sgt", {0b1111, 0b1111}, kAluOpChangedStateNone}, + {"sge", {0b1111, 0b1111}, kAluOpChangedStateNone}, + {"sne", {0b1111, 0b1111}, kAluOpChangedStateNone}, + {"frc", {0b1111}, kAluOpChangedStateNone}, + {"trunc", {0b1111}, kAluOpChangedStateNone}, + {"floor", {0b1111}, kAluOpChangedStateNone}, + {"mad", {0b1111, 0b1111, 0b1111}, kAluOpChangedStateNone}, + {"cndeq", {0b1111, 0b1111, 0b1111}, kAluOpChangedStateNone}, + {"cndge", {0b1111, 0b1111, 0b1111}, kAluOpChangedStateNone}, + {"cndgt", {0b1111, 0b1111, 0b1111}, kAluOpChangedStateNone}, + {"dp4", {0b1111, 0b1111}, kAluOpChangedStateNone}, + {"dp3", {0b0111, 0b0111}, kAluOpChangedStateNone}, + {"dp2add", {0b0011, 0b0011, 0b0001}, kAluOpChangedStateNone}, + {"cube", {0b1111, 0b1111}, kAluOpChangedStateNone}, + {"max4", {0b1111}, kAluOpChangedStateNone}, + {"setp_eq_push", {0b1001, 0b1001}, kAluOpChangedStatePredicate}, + {"setp_ne_push", {0b1001, 0b1001}, kAluOpChangedStatePredicate}, + {"setp_gt_push", {0b1001, 0b1001}, kAluOpChangedStatePredicate}, + {"setp_ge_push", {0b1001, 0b1001}, kAluOpChangedStatePredicate}, + {"kill_eq", {0b1111, 0b1111}, kAluOpChangedStatePixelKill}, + {"kill_gt", {0b1111, 0b1111}, kAluOpChangedStatePixelKill}, + {"kill_ge", {0b1111, 0b1111}, kAluOpChangedStatePixelKill}, + {"kill_ne", {0b1111, 0b1111}, kAluOpChangedStatePixelKill}, + {"dst", {0b0110, 0b1010}, kAluOpChangedStateNone}, + {"maxa", {0b1111, 0b1111}, kAluOpChangedStateAddressRegister}, + {"opcode_30", {}, kAluOpChangedStateNone}, + {"opcode_31", {}, kAluOpChangedStateNone}, +}; + +} // namespace rex::graphics::ucode diff --git a/src/graphics/graphics_system.cpp b/src/graphics/graphics_system.cpp new file mode 100644 index 0000000..3877b1a --- /dev/null +++ b/src/graphics/graphics_system.cpp @@ -0,0 +1,410 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_STRING(trace_gpu_prefix, "", "GPU", "GPU trace file prefix"); + +REXCVAR_DEFINE_BOOL(trace_gpu_stream, false, "GPU", "Enable GPU trace streaming"); + +REXCVAR_DEFINE_STRING(swap_post_effect, "none", "GPU", "Swap post effect: none, fxaa, fxaa_extreme") + .allowed({"none", "fxaa", "fxaa_extreme"}) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_BOOL(store_shaders, true, "GPU", + "Store shaders persistently and load them when loading games to avoid " + "runtime spikes and freezes when playing the game not for the first time."); + +namespace { + +rex::graphics::CommandProcessor::SwapPostEffect ParseSwapPostEffect( + const std::string& effect_name) { + std::string lowered = effect_name; + std::transform(lowered.begin(), lowered.end(), lowered.begin(), [](unsigned char c) { + c = static_cast(std::tolower(c)); + return c == '-' ? '_' : char(c); + }); + if (lowered == "fxaa") { + return rex::graphics::CommandProcessor::SwapPostEffect::kFxaa; + } + if (lowered == "fxaa_extreme" || lowered == "extreme") { + return rex::graphics::CommandProcessor::SwapPostEffect::kFxaaExtreme; + } + return rex::graphics::CommandProcessor::SwapPostEffect::kNone; +} +} // namespace + +namespace rex::graphics { + +// Nvidia Optimus/AMD PowerXpress support. +// These exports force the process to trigger the discrete GPU in multi-GPU +// systems. +// https://developer.download.nvidia.com/devzone/devcenter/gamegraphics/files/OptimusRenderingPolicies.pdf +// https://stackoverflow.com/questions/17458803/amd-equivalent-to-nvoptimusenablement +#if REX_PLATFORM_WIN32 +extern "C" { +__declspec(dllexport) uint32_t NvOptimusEnablement = 0x00000001; +__declspec(dllexport) uint32_t AmdPowerXpressRequestHighPerformance = 1; +} // extern "C" +#endif // REX_PLATFORM_WIN32 + +GraphicsSystem::GraphicsSystem() : vsync_worker_running_(false) {} + +GraphicsSystem::~GraphicsSystem() = default; + +X_STATUS GraphicsSystem::SetupPresentation(ui::WindowedAppContext* app_context) { + if (presenter_) { + return X_STATUS_SUCCESS; + } + + if (!provider_) { + CreateProvider(true); + if (!provider_) { + REXGPU_ERROR("Unable to create graphics provider"); + return X_STATUS_UNSUCCESSFUL; + } + provider_supports_presentation_ = true; + } else if (!provider_supports_presentation_) { + // A prior SetupGuestGpu built a headless provider; backends like Vulkan + // need swapchain support baked in at provider creation time. + REXGPU_ERROR("SetupPresentation called after headless SetupGuestGpu; call order is reversed"); + return X_STATUS_UNSUCCESSFUL; + } + + app_context_ = app_context; + auto loss_cb = [this](bool is_responsible, bool statically_from_ui_thread) { + OnHostGpuLossFromAnyThread(is_responsible); + }; + if (app_context_) { + // Presenter creation must happen on the UI thread. + app_context_->CallInUIThreadSynchronous( + [this, loss_cb]() { presenter_ = provider_->CreatePresenter(loss_cb); }); + } else { + // Offscreen path (e.g. capturing guest output without a window). + presenter_ = provider_->CreatePresenter(loss_cb); + } + + if (!presenter_) { + REXGPU_ERROR("Unable to create presenter"); + return X_STATUS_UNSUCCESSFUL; + } + return X_STATUS_SUCCESS; +} + +X_STATUS GraphicsSystem::SetupGuestGpu(runtime::FunctionDispatcher* function_dispatcher, + system::KernelState* kernel_state) { + memory_ = function_dispatcher->memory(); + function_dispatcher_ = function_dispatcher; + kernel_state_ = kernel_state; + + // Headless path: no one set up presentation, so build a no-presentation + // provider just for the command processor. + if (!provider_) { + CreateProvider(false); + provider_supports_presentation_ = false; + } + + // Create command processor. This will spin up a thread to process all + // incoming ringbuffer packets. + command_processor_ = CreateCommandProcessor(); + if (!command_processor_->Initialize()) { + REXGPU_ERROR("Unable to initialize command processor"); + return X_STATUS_UNSUCCESSFUL; + } + command_processor_->SetDesiredSwapPostEffect(ParseSwapPostEffect(REXCVAR_GET(swap_post_effect))); + + // Register GPU MMIO handlers + // GPU registers are at 0x7FC80000-0x7FCFFFFF + memory_->AddVirtualMappedRange(0x7FC80000, // base address + 0xFFFF0000, // mask + 0x0000FFFF, // size (64KB) + this, // context (GraphicsSystem*) + reinterpret_cast(ReadRegisterThunk), + reinterpret_cast(WriteRegisterThunk)); + + // Guest vblank timer based on the configured guest video mode. + vsync_worker_running_ = true; + vsync_worker_thread_ = system::object_ref( + new system::XHostThread(kernel_state_, 128 * 1024, 0, [this]() { + system::X_VIDEO_MODE video_mode; + kernel::xboxkrnl::VdQueryVideoMode(&video_mode); + double refresh_rate_hz = std::max(1.0, double(float(video_mode.refresh_rate))); + uint64_t guest_tick_frequency = chrono::Clock::guest_tick_frequency(); + uint64_t vsync_interval_ticks = + std::max(uint64_t(1), uint64_t(double(guest_tick_frequency) / refresh_rate_hz)); + uint64_t no_vsync_interval_ticks = std::max(uint64_t(1), guest_tick_frequency / 1000); + uint64_t last_frame_time = chrono::Clock::QueryGuestTickCount(); + while (vsync_worker_running_) { + uint64_t current_time = chrono::Clock::QueryGuestTickCount(); + uint64_t interval_ticks = + REXCVAR_GET(vsync) ? vsync_interval_ticks : no_vsync_interval_ticks; + while (current_time - last_frame_time >= interval_ticks) { + MarkVblank(); + last_frame_time += interval_ticks; + } + rex::thread::Sleep(std::chrono::milliseconds(1)); + } + return 0; + })); + // TODO: set_can_debugger_suspend not yet ported + // vsync_worker_thread_->set_can_debugger_suspend(true); + vsync_worker_thread_->set_name("GPU VSync"); + vsync_worker_thread_->Create(); + + if (REXCVAR_GET(trace_gpu_stream)) { + BeginTracing(); + } + + return X_STATUS_SUCCESS; +} + +void GraphicsSystem::Shutdown() { + if (command_processor_) { + EndTracing(); + command_processor_->Shutdown(); + command_processor_.reset(); + } + + if (vsync_worker_thread_) { + vsync_worker_running_ = false; + vsync_worker_thread_->Wait(0, 0, 0, nullptr); + vsync_worker_thread_.reset(); + } + + if (presenter_) { + if (app_context_) { + app_context_->CallInUIThreadSynchronous([this]() { presenter_.reset(); }); + } + // If there's no app context (thus the presenter is owned by the thread that + // initialized the GraphicsSystem) or can't be queueing UI thread calls + // anymore, shutdown anyway. + presenter_.reset(); + } + + provider_.reset(); +} + +void GraphicsSystem::OnHostGpuLossFromAnyThread([[maybe_unused]] bool is_responsible) { + // TODO(Triang3l): Somehow gain exclusive ownership of the Provider (may be + // used by the command processor, the presenter, and possibly anything else, + // it's considered free-threaded, except for lifetime management which will be + // involved in this case) and reset it so a new host GPU API device is + // created. Then ask the command processor to reset itself in its thread, and + // ask the UI thread to reset the Presenter (the UI thread manages its + // lifetime - but if there's no WindowedAppContext, either don't reset it as + // in this case there's no user who needs uninterrupted gameplay, or somehow + // protect it with a mutex so any thread can be considered a UI thread and + // reset). + if (host_gpu_loss_reported_.test_and_set(std::memory_order_relaxed)) { + return; + } + rex::FatalError("Graphics device lost (probably due to an internal error)"); +} + +uint32_t GraphicsSystem::ReadRegisterThunk(void* ppc_context, GraphicsSystem* gs, uint32_t addr) { + return gs->ReadRegister(addr); +} + +void GraphicsSystem::WriteRegisterThunk(void* ppc_context, GraphicsSystem* gs, uint32_t addr, + uint32_t value) { + gs->WriteRegister(addr, value); +} + +uint32_t GraphicsSystem::ReadRegister(uint32_t addr) { + uint32_t r = (addr & 0xFFFF) / 4; + + switch (r) { + case 0x0F00: // RB_EDRAM_TIMING + return 0x08100748; + case 0x0F01: // RB_BC_CONTROL + return 0x0000200E; + case 0x194C: { // R500_D1MODE_V_COUNTER + system::X_VIDEO_MODE video_mode; + kernel::xboxkrnl::VdQueryVideoMode(&video_mode); + return std::min(uint32_t(video_mode.display_height), uint32_t(0x0FFF)); + } + case 0x1951: // interrupt status + return 1; // vblank + case 0x1961: { // AVIVO_D1MODE_VIEWPORT_SIZE + // Maximum [width(0x0FFF), height(0x0FFF)]. + system::X_VIDEO_MODE video_mode; + kernel::xboxkrnl::VdQueryVideoMode(&video_mode); + uint32_t viewport_width = std::min(uint32_t(video_mode.display_width), uint32_t(0x0FFF)); + uint32_t viewport_height = std::min(uint32_t(video_mode.display_height), uint32_t(0x0FFF)); + return (viewport_width << 16) | viewport_height; + } + default: + if (!register_file_.GetRegisterInfo(r)) { + REXGPU_DEBUG("GPU: Read from unknown register ({:04X})", r); + } + } + + assert_true(r < RegisterFile::kRegisterCount); + return register_file_.values[r]; +} + +void GraphicsSystem::WriteRegister(uint32_t addr, uint32_t value) { + uint32_t r = (addr & 0xFFFF) / 4; + + switch (r) { + case 0x01C5: // CP_RB_WPTR + command_processor_->UpdateWritePointer(value); + break; + case 0x1844: // AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + break; + default: + REXGPU_WARN("Unknown GPU register {:04X} write: {:08X}", r, value); + break; + } + + assert_true(r < RegisterFile::kRegisterCount); + register_file_.values[r] = value; +} + +void GraphicsSystem::InitializeRingBuffer(uint32_t ptr, uint32_t size_log2) { + command_processor_->InitializeRingBuffer(ptr, size_log2); +} + +void GraphicsSystem::EnableReadPointerWriteBack(uint32_t ptr, uint32_t block_size_log2) { + command_processor_->EnableReadPointerWriteBack(ptr, block_size_log2); +} + +void GraphicsSystem::SetInterruptCallback(uint32_t callback, uint32_t user_data) { + interrupt_callback_ = callback; + interrupt_callback_data_ = user_data; + REXGPU_INFO("SetInterruptCallback({:08X}, {:08X})", callback, user_data); +} + +void GraphicsSystem::DispatchInterruptCallback(uint32_t source, uint32_t cpu) { + if (!interrupt_callback_) { + return; + } + + auto thread = system::XThread::GetCurrentThread(); + assert_not_null(thread); + + // Pick a CPU, if needed. We're going to guess 2. Because. + if (cpu == 0xFFFFFFFF) { + cpu = 2; + } + thread->SetActiveCpu(cpu); + + // REXGPU_INFO("Dispatching GPU interrupt at {:08X} w/ mode {} on cpu {}", + // interrupt_callback_, source, cpu); + + uint64_t args[] = {source, interrupt_callback_data_}; + function_dispatcher_->ExecuteInterrupt(thread->thread_state(), interrupt_callback_, args, + rex::countof(args)); +} + +void GraphicsSystem::MarkVblank() { + // TODO: Enable profiling once ported + // SCOPE_profile_cpu_f("gpu"); + + // Increment vblank counter (so the game sees us making progress). + if (command_processor_) { + command_processor_->increment_counter(); + } + + // TODO(benvanik): we shouldn't need to do the dispatch here, but there's + // something wrong and the CP will block waiting for code that + // needs to be run in the interrupt. + DispatchInterruptCallback(0, 2); +} + +void GraphicsSystem::ClearCaches() { + command_processor_->CallInThread([&]() { command_processor_->ClearCaches(); }); +} + +void GraphicsSystem::InvalidateGpuMemory() { + command_processor_->CallInThread([&]() { command_processor_->InvalidateGpuMemory(); }); +} + +void GraphicsSystem::InitializeShaderStorage(const std::filesystem::path& cache_root, + uint32_t title_id, bool blocking) { + if (!REXCVAR_GET(store_shaders)) { + return; + } + if (blocking) { + if (command_processor_->is_paused()) { + // Safe to run on any thread while the command processor is paused, no + // race condition. + command_processor_->InitializeShaderStorage(cache_root, title_id, true); + } else { + rex::thread::Fence fence; + command_processor_->CallInThread([this, cache_root, title_id, &fence]() { + command_processor_->InitializeShaderStorage(cache_root, title_id, true); + fence.Signal(); + }); + fence.Wait(); + } + } else { + command_processor_->CallInThread([this, cache_root, title_id]() { + command_processor_->InitializeShaderStorage(cache_root, title_id, false); + }); + } +} + +void GraphicsSystem::RequestFrameTrace() { + command_processor_->RequestFrameTrace(REXCVAR_GET(trace_gpu_prefix)); +} + +void GraphicsSystem::BeginTracing() { + command_processor_->BeginTracing(REXCVAR_GET(trace_gpu_prefix)); +} + +void GraphicsSystem::EndTracing() { + command_processor_->EndTracing(); +} + +void GraphicsSystem::Pause() { + paused_ = true; + command_processor_->Pause(); +} + +void GraphicsSystem::Resume() { + paused_ = false; + command_processor_->Resume(); +} + +bool GraphicsSystem::Save(::rex::stream::ByteStream* stream) { + stream->Write(interrupt_callback_); + stream->Write(interrupt_callback_data_); + return command_processor_->Save(stream); +} + +bool GraphicsSystem::Restore(::rex::stream::ByteStream* stream) { + interrupt_callback_ = stream->Read(); + interrupt_callback_data_ = stream->Read(); + return command_processor_->Restore(stream); +} + +} // namespace rex::graphics diff --git a/src/graphics/packet_disassembler.cpp b/src/graphics/packet_disassembler.cpp new file mode 100644 index 0000000..7cea2cc --- /dev/null +++ b/src/graphics/packet_disassembler.cpp @@ -0,0 +1,456 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +namespace rex::graphics { + +using namespace rex::graphics::xenos; + +PacketCategory PacketDisassembler::GetPacketCategory(const uint8_t* base_ptr) { + const uint32_t packet = memory::load_and_swap(base_ptr); + const uint32_t packet_type = packet >> 30; + switch (packet_type) { + case 0x00: + case 0x01: + case 0x02: { + return PacketCategory::kGeneric; + } + case 0x03: { + uint32_t opcode = (packet >> 8) & 0x7F; + switch (opcode) { + case PM4_DRAW_INDX: + case PM4_DRAW_INDX_2: + return PacketCategory::kDraw; + case PM4_XE_SWAP: + return PacketCategory::kSwap; + default: + return PacketCategory::kGeneric; + } + } + default: { + assert_unhandled_case(packet_type); + return PacketCategory::kGeneric; + } + } +} + +bool PacketDisassembler::DisasmPacketType0(const uint8_t* base_ptr, uint32_t packet, + PacketInfo* out_info) { + static const PacketTypeInfo type_0_info = {PacketCategory::kGeneric, "PM4_TYPE0"}; + out_info->type_info = &type_0_info; + + uint32_t count = ((packet >> 16) & 0x3FFF) + 1; + out_info->count = 1 + count; + auto ptr = base_ptr + 4; + + uint32_t base_index = (packet & 0x7FFF); + uint32_t write_one_reg = (packet >> 15) & 0x1; + for (uint32_t m = 0; m < count; m++) { + uint32_t reg_data = memory::load_and_swap(ptr); + uint32_t target_index = write_one_reg ? base_index : base_index + m; + out_info->actions.emplace_back(PacketAction::RegisterWrite(target_index, reg_data)); + ptr += 4; + } + + return true; +} + +bool PacketDisassembler::DisasmPacketType1(const uint8_t* base_ptr, uint32_t packet, + PacketInfo* out_info) { + static const PacketTypeInfo type_1_info = {PacketCategory::kGeneric, "PM4_TYPE1"}; + out_info->type_info = &type_1_info; + + out_info->count = 1 + 2; + auto ptr = base_ptr + 4; + + uint32_t reg_index_1 = packet & 0x7FF; + uint32_t reg_index_2 = (packet >> 11) & 0x7FF; + uint32_t reg_data_1 = memory::load_and_swap(ptr); + uint32_t reg_data_2 = memory::load_and_swap(ptr + 4); + out_info->actions.emplace_back(PacketAction::RegisterWrite(reg_index_1, reg_data_1)); + out_info->actions.emplace_back(PacketAction::RegisterWrite(reg_index_2, reg_data_2)); + + return true; +} + +bool PacketDisassembler::DisasmPacketType2(const uint8_t* base_ptr, uint32_t packet, + PacketInfo* out_info) { + static const PacketTypeInfo type_2_info = {PacketCategory::kGeneric, "PM4_TYPE2"}; + out_info->type_info = &type_2_info; + + out_info->count = 1; + + return true; +} + +bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr, uint32_t packet, + PacketInfo* out_info) { + static const PacketTypeInfo type_3_unknown_info = {PacketCategory::kGeneric, "PM4_TYPE3_UNKNOWN"}; + out_info->type_info = &type_3_unknown_info; + + uint32_t opcode = (packet >> 8) & 0x7F; + uint32_t count = ((packet >> 16) & 0x3FFF) + 1; + out_info->count = 1 + count; + auto ptr = base_ptr + 4; + + if (packet & 1) { + out_info->predicated = true; + } + + bool result = true; + switch (opcode) { + case PM4_ME_INIT: { + // initialize CP's micro-engine + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_ME_INIT"}; + out_info->type_info = &op_info; + break; + } + case PM4_NOP: { + // skip N 32-bit words to get to the next packet + // No-op, ignore some data. + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_NOP"}; + out_info->type_info = &op_info; + break; + } + case PM4_INTERRUPT: { + // generate interrupt from the command stream + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_INTERRUPT"}; + out_info->type_info = &op_info; + uint32_t cpu_mask = memory::load_and_swap(ptr + 0); + for (int n = 0; n < 6; n++) { + if (cpu_mask & (1 << n)) { + // graphics_system_->DispatchInterruptCallback(1, n); + } + } + break; + } + case PM4_XE_SWAP: { + // Xenia-specific VdSwap hook. + // VdSwap will post this to tell us we need to swap the screen/fire an + // interrupt. + // 63 words here, but only the first has any data. + static const PacketTypeInfo op_info = {PacketCategory::kSwap, "PM4_XE_SWAP"}; + out_info->type_info = &op_info; + uint32_t frontbuffer_ptr = memory::load_and_swap(ptr + 0); + break; + } + case PM4_INDIRECT_BUFFER: + case PM4_INDIRECT_BUFFER_PFD: { + // indirect buffer dispatch + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_INDIRECT_BUFFER"}; + out_info->type_info = &op_info; + uint32_t list_ptr = memory::load_and_swap(ptr + 0); + uint32_t list_length = memory::load_and_swap(ptr + 4); + break; + } + case PM4_WAIT_REG_MEM: { + // wait until a register or memory location is a specific value + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_WAIT_REG_MEM"}; + out_info->type_info = &op_info; + uint32_t wait_info = memory::load_and_swap(ptr + 0); + uint32_t poll_reg_addr = memory::load_and_swap(ptr + 4); + uint32_t ref = memory::load_and_swap(ptr + 8); + uint32_t mask = memory::load_and_swap(ptr + 12); + uint32_t wait = memory::load_and_swap(ptr + 16); + break; + } + case PM4_REG_RMW: { + // register read/modify/write + // ? (used during shader upload and edram setup) + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_REG_RMW"}; + out_info->type_info = &op_info; + uint32_t rmw_info = memory::load_and_swap(ptr + 0); + uint32_t and_mask = memory::load_and_swap(ptr + 4); + uint32_t or_mask = memory::load_and_swap(ptr + 8); + break; + } + case PM4_COND_WRITE: { + // conditional write to memory or register + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_COND_WRITE"}; + out_info->type_info = &op_info; + uint32_t wait_info = memory::load_and_swap(ptr + 0); + uint32_t poll_reg_addr = memory::load_and_swap(ptr + 4); + uint32_t ref = memory::load_and_swap(ptr + 8); + uint32_t mask = memory::load_and_swap(ptr + 12); + uint32_t write_reg_addr = memory::load_and_swap(ptr + 16); + uint32_t write_data = memory::load_and_swap(ptr + 20); + break; + } + case PM4_EVENT_WRITE: { + // generate an event that creates a write to memory when completed + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_EVENT_WRITE"}; + out_info->type_info = &op_info; + uint32_t initiator = memory::load_and_swap(ptr + 0); + break; + } + case PM4_EVENT_WRITE_SHD: { + // generate a VS|PS_done event + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_EVENT_WRITE_SHD"}; + out_info->type_info = &op_info; + uint32_t initiator = memory::load_and_swap(ptr + 0); + uint32_t address = memory::load_and_swap(ptr + 4); + uint32_t value = memory::load_and_swap(ptr + 8); + break; + } + case PM4_EVENT_WRITE_EXT: { + // generate a screen extent event + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_EVENT_WRITE_EXT"}; + out_info->type_info = &op_info; + uint32_t unk0 = memory::load_and_swap(ptr + 0); + uint32_t unk1 = memory::load_and_swap(ptr + 4); + break; + } + case PM4_DRAW_INDX: { + // initiate fetch of index buffer and draw + // dword0 = viz query info + static const PacketTypeInfo op_info = {PacketCategory::kDraw, "PM4_DRAW_INDX"}; + out_info->type_info = &op_info; + uint32_t dword0 = memory::load_and_swap(ptr + 0); + uint32_t dword1 = memory::load_and_swap(ptr + 4); + uint32_t index_count = dword1 >> 16; + auto prim_type = static_cast(dword1 & 0x3F); + uint32_t src_sel = (dword1 >> 6) & 0x3; + if (src_sel == 0x0) { + // Indexed draw. + uint32_t guest_base = memory::load_and_swap(ptr + 8); + uint32_t index_size = memory::load_and_swap(ptr + 12); + auto endianness = static_cast(index_size >> 30); + index_size &= 0x00FFFFFF; + bool index_32bit = (dword1 >> 11) & 0x1; + index_size *= index_32bit ? 4 : 2; + } else if (src_sel == 0x2) { + // Auto draw. + } else { + // Unknown source select. + assert_always(); + } + break; + } + case PM4_DRAW_INDX_2: { + // draw using supplied indices in packet + static const PacketTypeInfo op_info = {PacketCategory::kDraw, "PM4_DRAW_INDX_2"}; + out_info->type_info = &op_info; + uint32_t dword0 = memory::load_and_swap(ptr + 0); + uint32_t index_count = dword0 >> 16; + auto prim_type = static_cast(dword0 & 0x3F); + uint32_t src_sel = (dword0 >> 6) & 0x3; + assert_true(src_sel == 0x2); // 'SrcSel=AutoIndex' + bool index_32bit = (dword0 >> 11) & 0x1; + uint32_t indices_size = index_count * (index_32bit ? 4 : 2); + auto index_ptr = ptr + 4; + break; + } + case PM4_SET_CONSTANT: { + // load constant into chip and to memory + // PM4_REG(reg) ((0x4 << 16) | (GSL_HAL_SUBBLOCK_OFFSET(reg))) + // reg - 0x2000 + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_SET_CONSTANT"}; + out_info->type_info = &op_info; + uint32_t offset_type = memory::load_and_swap(ptr + 0); + uint32_t index = offset_type & 0x7FF; + uint32_t type = (offset_type >> 16) & 0xFF; + switch (type) { + case 0: // ALU + index += 0x4000; + break; + case 1: // FETCH + index += 0x4800; + break; + case 2: // BOOL + index += 0x4900; + break; + case 3: // LOOP + index += 0x4908; + break; + case 4: // REGISTERS + index += 0x2000; + break; + default: + assert_always(); + result = false; + break; + } + for (uint32_t n = 0; n < count - 1; n++, index++) { + uint32_t data = memory::load_and_swap(ptr + 4 + n * 4); + out_info->actions.emplace_back(PacketAction::RegisterWrite(index, data)); + } + break; + } + case PM4_SET_CONSTANT2: { + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_SET_CONSTANT2"}; + out_info->type_info = &op_info; + uint32_t offset_type = memory::load_and_swap(ptr + 0); + uint32_t index = offset_type & 0xFFFF; + for (uint32_t n = 0; n < count - 1; n++, index++) { + uint32_t data = memory::load_and_swap(ptr + 4 + n * 4); + out_info->actions.emplace_back(PacketAction::RegisterWrite(index, data)); + } + return true; + break; + } + case PM4_LOAD_ALU_CONSTANT: { + // load constants from memory + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_LOAD_ALU_CONSTANT"}; + out_info->type_info = &op_info; + uint32_t address = memory::load_and_swap(ptr + 0); + address &= 0x3FFFFFFF; + uint32_t offset_type = memory::load_and_swap(ptr + 4); + uint32_t index = offset_type & 0x7FF; + uint32_t size_dwords = memory::load_and_swap(ptr + 8); + size_dwords &= 0xFFF; + uint32_t type = (offset_type >> 16) & 0xFF; + switch (type) { + case 0: // ALU + index += 0x4000; + break; + case 1: // FETCH + index += 0x4800; + break; + case 2: // BOOL + index += 0x4900; + break; + case 3: // LOOP + index += 0x4908; + break; + case 4: // REGISTERS + index += 0x2000; + break; + default: + assert_always(); + return true; + } + for (uint32_t n = 0; n < size_dwords; n++, index++) { + // Hrm, ? + // memory::load_and_swap(membase_ + GpuToCpu(address + n * 4)); + uint32_t data = 0xDEADBEEF; + out_info->actions.emplace_back(PacketAction::RegisterWrite(index, data)); + } + break; + } + case PM4_SET_SHADER_CONSTANTS: { + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_SET_SHADER_CONSTANTS"}; + out_info->type_info = &op_info; + uint32_t offset_type = memory::load_and_swap(ptr + 0); + uint32_t index = offset_type & 0xFFFF; + for (uint32_t n = 0; n < count - 1; n++, index++) { + uint32_t data = memory::load_and_swap(ptr + 4 + n * 4); + out_info->actions.emplace_back(PacketAction::RegisterWrite(index, data)); + } + return true; + } + case PM4_IM_LOAD: { + // load sequencer instruction memory (pointer-based) + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_IM_LOAD"}; + out_info->type_info = &op_info; + uint32_t addr_type = memory::load_and_swap(ptr + 0); + auto shader_type = static_cast(addr_type & 0x3); + uint32_t addr = addr_type & ~0x3; + uint32_t start_size = memory::load_and_swap(ptr + 4); + uint32_t start = start_size >> 16; + uint32_t size_dwords = start_size & 0xFFFF; // dwords + assert_true(start == 0); + break; + } + case PM4_IM_LOAD_IMMEDIATE: { + // load sequencer instruction memory (code embedded in packet) + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_IM_LOAD_IMMEDIATE"}; + out_info->type_info = &op_info; + uint32_t dword0 = memory::load_and_swap(ptr + 0); + uint32_t dword1 = memory::load_and_swap(ptr + 4); + auto shader_type = static_cast(dword0); + uint32_t start_size = dword1; + uint32_t start = start_size >> 16; + uint32_t size_dwords = start_size & 0xFFFF; // dwords + assert_true(start == 0); + break; + } + case PM4_INVALIDATE_STATE: { + // selective invalidation of state pointers + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_INVALIDATE_STATE"}; + out_info->type_info = &op_info; + uint32_t mask = memory::load_and_swap(ptr + 0); + break; + } + case PM4_SET_BIN_MASK_LO: { + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_SET_BIN_MASK_LO"}; + out_info->type_info = &op_info; + uint32_t value = memory::load_and_swap(ptr); + // bin_mask_ = (bin_mask_ & 0xFFFFFFFF00000000ull) | value; + out_info->actions.emplace_back(PacketAction::SetBinMask(value)); + break; + } + case PM4_SET_BIN_MASK_HI: { + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_SET_BIN_MASK_HI"}; + out_info->type_info = &op_info; + uint32_t value = memory::load_and_swap(ptr); + // bin_mask_ = + // (bin_mask_ & 0xFFFFFFFFull) | (static_cast(value) << 32); + break; + } + case PM4_SET_BIN_SELECT_LO: { + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_SET_BIN_SELECT_LO"}; + out_info->type_info = &op_info; + uint32_t value = memory::load_and_swap(ptr); + // bin_select_ = (bin_select_ & 0xFFFFFFFF00000000ull) | value; + out_info->actions.emplace_back(PacketAction::SetBinSelect(value)); + break; + } + case PM4_SET_BIN_SELECT_HI: { + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_SET_BIN_SELECT_HI"}; + out_info->type_info = &op_info; + uint32_t value = memory::load_and_swap(ptr); + // bin_select_ = + // (bin_select_ & 0xFFFFFFFFull) | (static_cast(value) << + // 32); + break; + } + + // Ignored packets - useful if breaking on the default handler below. + case 0x50: { // 0xC0015000 usually 2 words, 0xFFFFFFFF / 0x00000000 + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_TYPE3_0x50"}; + out_info->type_info = &op_info; + break; + } + case 0x51: { // 0xC0015100 usually 2 words, 0xFFFFFFFF / 0xFFFFFFFF + static const PacketTypeInfo op_info = {PacketCategory::kGeneric, "PM4_TYPE3_0x51"}; + out_info->type_info = &op_info; + break; + } + default: { + result = false; + break; + } + } + + return result; +} + +bool PacketDisassembler::DisasmPacket(const uint8_t* base_ptr, PacketInfo* out_info) { + const uint32_t packet = memory::load_and_swap(base_ptr); + const uint32_t packet_type = packet >> 30; + switch (packet_type) { + case 0x00: + return DisasmPacketType0(base_ptr, packet, out_info); + case 0x01: + return DisasmPacketType1(base_ptr, packet, out_info); + case 0x02: + return DisasmPacketType2(base_ptr, packet, out_info); + case 0x03: + return DisasmPacketType3(base_ptr, packet, out_info); + default: + assert_unhandled_case(packet_type); + return false; + } +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/render_target/cache.cpp b/src/graphics/pipeline/render_target/cache.cpp new file mode 100644 index 0000000..382b0b2 --- /dev/null +++ b/src/graphics/pipeline/render_target/cache.cpp @@ -0,0 +1,1426 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(mrt_edram_used_range_clamp_to_min, true, "GPU", + "Clamp MRT EDRAM used range to minimum"); + +REXCVAR_DEFINE_BOOL(execute_unclipped_draw_vs_on_cpu_for_psi_render_backend, true, "GPU", + "Execute unclipped draw VS on CPU for PSI render backend"); + +REXCVAR_DEFINE_BOOL(snorm16_render_target_full_range, true, "GPU", + "Use full range for SNORM16 render targets"); + +REXCVAR_DEFINE_BOOL(direct_host_resolve, true, "GPU", + "Resolve from host render targets directly to shared memory when possible") + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +namespace rex::graphics { + +void RenderTargetCache::GetPSIColorFormatInfo(xenos::ColorRenderTargetFormat format, + uint32_t write_mask, float& clamp_rgb_low, + float& clamp_alpha_low, float& clamp_rgb_high, + float& clamp_alpha_high, uint32_t& keep_mask_low, + uint32_t& keep_mask_high) { + keep_mask_low = keep_mask_high = 0; + switch (format) { + case xenos::ColorRenderTargetFormat::k_8_8_8_8: + case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA: { + clamp_rgb_low = clamp_alpha_low = 0.0f; + clamp_rgb_high = clamp_alpha_high = 1.0f; + for (uint32_t i = 0; i < 4; ++i) { + if (!(write_mask & (1 << i))) { + keep_mask_low |= uint32_t(0xFF) << (i * 8); + } + } + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: { + clamp_rgb_low = clamp_alpha_low = 0.0f; + clamp_rgb_high = clamp_alpha_high = 1.0f; + for (uint32_t i = 0; i < 3; ++i) { + if (!(write_mask & (1 << i))) { + keep_mask_low |= uint32_t(0x3FF) << (i * 10); + } + } + if (!(write_mask & 0b1000)) { + keep_mask_low |= uint32_t(3) << 30; + } + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16: { + clamp_rgb_low = clamp_alpha_low = 0.0f; + clamp_rgb_high = 31.875f; + clamp_alpha_high = 1.0f; + for (uint32_t i = 0; i < 3; ++i) { + if (!(write_mask & (1 << i))) { + keep_mask_low |= uint32_t(0x3FF) << (i * 10); + } + } + if (!(write_mask & 0b1000)) { + keep_mask_low |= uint32_t(3) << 30; + } + } break; + case xenos::ColorRenderTargetFormat::k_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_16_16: + // Alpha clamping affects blending source, so it's non-zero for alpha for + // k_16_16 (the render target is fixed-point). There's one deviation from + // how Direct3D 11.3 functional specification defines SNorm conversion + // (NaN should be 0, not the lowest negative number), and that needs to be + // handled separately. + clamp_rgb_low = clamp_alpha_low = -32.0f; + clamp_rgb_high = clamp_alpha_high = 32.0f; + if (!(write_mask & 0b0001)) { + keep_mask_low |= 0xFFFFu; + } + if (!(write_mask & 0b0010)) { + keep_mask_low |= 0xFFFF0000u; + } + if (format == xenos::ColorRenderTargetFormat::k_16_16_16_16) { + if (!(write_mask & 0b0100)) { + keep_mask_high |= 0xFFFFu; + } + if (!(write_mask & 0b1000)) { + keep_mask_high |= 0xFFFF0000u; + } + } else { + write_mask &= 0b0011; + } + break; + case xenos::ColorRenderTargetFormat::k_16_16_FLOAT: + case xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT: + // No NaNs on the Xbox 360 GPU, though can't use the extended range with + // Direct3D and Vulkan conversions. + // TODO(Triang3l): Use the extended-range encoding in all implementations. + clamp_rgb_low = clamp_alpha_low = -65504.0f; + clamp_rgb_high = clamp_alpha_high = 65504.0f; + if (!(write_mask & 0b0001)) { + keep_mask_low |= 0xFFFFu; + } + if (!(write_mask & 0b0010)) { + keep_mask_low |= 0xFFFF0000u; + } + if (format == xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT) { + if (!(write_mask & 0b0100)) { + keep_mask_high |= 0xFFFFu; + } + if (!(write_mask & 0b1000)) { + keep_mask_high |= 0xFFFF0000u; + } + } else { + write_mask &= 0b0011; + } + break; + case xenos::ColorRenderTargetFormat::k_32_FLOAT: + // No clamping - let min/max always pick the original value. + clamp_rgb_low = clamp_alpha_low = clamp_rgb_high = clamp_alpha_high = std::nanf(""); + write_mask &= 0b0001; + if (!(write_mask & 0b0001)) { + keep_mask_low = ~uint32_t(0); + } + break; + case xenos::ColorRenderTargetFormat::k_32_32_FLOAT: + // No clamping - let min/max always pick the original value. + clamp_rgb_low = clamp_alpha_low = clamp_rgb_high = clamp_alpha_high = std::nanf(""); + write_mask &= 0b0011; + if (!(write_mask & 0b0001)) { + keep_mask_low = ~uint32_t(0); + } + if (!(write_mask & 0b0010)) { + keep_mask_high = ~uint32_t(0); + } + break; + default: + assert_unhandled_case(format); + // Disable invalid render targets. + write_mask = 0; + break; + } + // Special case handled in the shaders for empty write mask to completely skip + // a disabled render target: all keep bits are set. + if (!write_mask) { + keep_mask_low = keep_mask_high = ~uint32_t(0); + } +} + +uint32_t RenderTargetCache::Transfer::GetRangeRectangles(uint32_t start_tiles, uint32_t end_tiles, + uint32_t base_tiles, uint32_t pitch_tiles, + xenos::MsaaSamples msaa_samples, + bool is_64bpp, Rectangle* rectangles_out, + const Rectangle* cutout) { + // EDRAM addressing wrapping must be handled by doing GetRangeRectangles for + // two clamped ranges, in this case start_tiles == end_tiles will also + // unambiguously mean an empty range rather than the entire EDRAM. + assert_true(start_tiles < xenos::kEdramTileCount); + assert_true(end_tiles <= xenos::kEdramTileCount); + assert_true(start_tiles <= end_tiles); + // If start_tiles < base_tiles, this is the tail after EDRAM addressing + // wrapping. + assert_true(start_tiles >= base_tiles || end_tiles <= base_tiles); + assert_not_zero(pitch_tiles); + if (start_tiles == end_tiles) { + return 0; + } + uint32_t tile_width = xenos::kEdramTileWidthSamples >> + (uint32_t(msaa_samples >= xenos::MsaaSamples::k4X) + uint32_t(is_64bpp)); + uint32_t tile_height = + xenos::kEdramTileHeightSamples >> uint32_t(msaa_samples >= xenos::MsaaSamples::k2X); + // If the first and / or the last rows have the same X spans as the middle + // part, merge them with it. + uint32_t rectangle_count = 0; + // If start_tiles < base_tiles, this is the tail after EDRAM addressing + // wrapping. + uint32_t local_offset = start_tiles < base_tiles ? xenos::kEdramTileCount : 0; + uint32_t local_start = local_offset + start_tiles - base_tiles; + uint32_t local_end = local_offset + end_tiles - base_tiles; + // Inclusive. + uint32_t rows_start = local_start / pitch_tiles; + // Exclusive. + uint32_t rows_end = (local_end + (pitch_tiles - 1)) / pitch_tiles; + uint32_t row_first_start = local_start - rows_start * pitch_tiles; + uint32_t row_last_end = pitch_tiles - (rows_end * pitch_tiles - local_end); + uint32_t rows = rows_end - rows_start; + if (rows == 1 || row_first_start) { + Rectangle rectangle_first; + rectangle_first.x_pixels = row_first_start * tile_width; + rectangle_first.y_pixels = rows_start * tile_height; + rectangle_first.width_pixels = + ((rows == 1 ? row_last_end : pitch_tiles) - row_first_start) * tile_width; + rectangle_first.height_pixels = tile_height; + rectangle_count += AddRectangle( + rectangle_first, rectangles_out ? rectangles_out + rectangle_count : nullptr, cutout); + if (rows == 1) { + return rectangle_count; + } + } + uint32_t mid_rows_start = rows_start + 1; + uint32_t mid_rows = rows - 2; + if (!row_first_start) { + --mid_rows_start; + ++mid_rows; + } + if (row_last_end == pitch_tiles) { + ++mid_rows; + } + if (mid_rows) { + Rectangle rectangle_mid; + rectangle_mid.x_pixels = 0; + rectangle_mid.y_pixels = mid_rows_start * tile_height; + rectangle_mid.width_pixels = pitch_tiles * tile_width; + rectangle_mid.height_pixels = mid_rows * tile_height; + rectangle_count += AddRectangle( + rectangle_mid, rectangles_out ? rectangles_out + rectangle_count : nullptr, cutout); + } + if (row_last_end != pitch_tiles) { + Rectangle rectangle_last; + rectangle_last.x_pixels = 0; + rectangle_last.y_pixels = (rows_end - 1) * tile_height; + rectangle_last.width_pixels = row_last_end * tile_width; + rectangle_last.height_pixels = tile_height; + rectangle_count += AddRectangle( + rectangle_last, rectangles_out ? rectangles_out + rectangle_count : nullptr, cutout); + } + assert_true(rectangle_count <= (cutout ? kMaxRectanglesWithCutout : kMaxRectanglesWithoutCutout)); + return rectangle_count; +} + +uint32_t RenderTargetCache::Transfer::AddRectangle(const Rectangle& rectangle, + Rectangle* rectangles_out, + const Rectangle* cutout) { + uint32_t rectangle_right = rectangle.x_pixels + rectangle.width_pixels; + uint32_t rectangle_bottom = rectangle.y_pixels + rectangle.height_pixels; + // If nothing to cut out (no region specified, or no intersection - if the + // cutout region is in the middle on Y, but completely to the left / right on + // X, don't split), add the whole rectangle. + if (!cutout || !cutout->width_pixels || !cutout->height_pixels || + cutout->x_pixels >= rectangle_right || + cutout->x_pixels + cutout->width_pixels <= rectangle.x_pixels || + cutout->y_pixels >= rectangle_bottom || + cutout->y_pixels + cutout->height_pixels <= rectangle.y_pixels) { + if (rectangles_out) { + rectangles_out[0] = rectangle; + } + return 1; + } + uint32_t rectangle_count = 0; + uint32_t cutout_right = cutout->x_pixels + cutout->width_pixels; + uint32_t cutout_bottom = cutout->y_pixels + cutout->height_pixels; + // Upper part after cutout. + if (cutout->y_pixels > rectangle.y_pixels) { + // The completely outside case has already been checked. + assert_true(cutout->y_pixels < rectangle_bottom); + if (rectangles_out) { + Rectangle& rectangle_upper = rectangles_out[rectangle_count]; + rectangle_upper.x_pixels = rectangle.x_pixels; + rectangle_upper.y_pixels = rectangle.y_pixels; + rectangle_upper.width_pixels = rectangle.width_pixels; + // cutout->y_pixels is already known to be < rectangle_bottom, no need for + // min(cutout->y_pixels - rectangle.y_pixels, rectangle.height_pixels). + rectangle_upper.height_pixels = cutout->y_pixels - rectangle.y_pixels; + } + ++rectangle_count; + } + // Middle part after cutout. + uint32_t middle_top = std::max(cutout->y_pixels, rectangle.y_pixels); + uint32_t middle_height = std::min(cutout_bottom, rectangle_bottom) - middle_top; + // Middle left. + if (cutout->x_pixels > rectangle.x_pixels) { + assert_true(cutout->x_pixels < rectangle_right); + if (rectangles_out) { + Rectangle& rectangle_middle_left = rectangles_out[rectangle_count]; + rectangle_middle_left.x_pixels = rectangle.x_pixels; + rectangle_middle_left.y_pixels = middle_top; + rectangle_middle_left.width_pixels = cutout->x_pixels - rectangle.x_pixels; + rectangle_middle_left.height_pixels = middle_height; + } + ++rectangle_count; + } + // Middle right. + if (cutout_right < rectangle_right) { + assert_true(cutout_right > rectangle.x_pixels); + if (rectangles_out) { + Rectangle& rectangle_middle_right = rectangles_out[rectangle_count]; + rectangle_middle_right.x_pixels = cutout_right; + rectangle_middle_right.y_pixels = middle_top; + rectangle_middle_right.width_pixels = rectangle_right - cutout_right; + rectangle_middle_right.height_pixels = middle_height; + } + ++rectangle_count; + } + // Lower part after cutout. + if (cutout_bottom < rectangle_bottom) { + assert_true(cutout_bottom > rectangle.y_pixels); + if (rectangles_out) { + Rectangle& rectangle_upper = rectangles_out[rectangle_count]; + rectangle_upper.x_pixels = rectangle.x_pixels; + rectangle_upper.y_pixels = cutout_bottom; + rectangle_upper.width_pixels = rectangle.width_pixels; + rectangle_upper.height_pixels = rectangle_bottom - cutout_bottom; + } + ++rectangle_count; + } + assert_true(rectangle_count <= kMaxCutoutBorderRectangles); + return rectangle_count; +} + +RenderTargetCache::~RenderTargetCache() { + ShutdownCommon(); +} + +void RenderTargetCache::InitializeCommon() { + assert_true(ownership_ranges_.empty()); + ownership_ranges_.emplace(std::piecewise_construct, std::forward_as_tuple(uint32_t(0)), + std::forward_as_tuple(xenos::kEdramTileCount, RenderTargetKey(), + RenderTargetKey(), RenderTargetKey())); +} + +void RenderTargetCache::DestroyAllRenderTargets(bool shutting_down) { + ownership_ranges_.clear(); + if (!shutting_down) { + ownership_ranges_.emplace(std::piecewise_construct, std::forward_as_tuple(uint32_t(0)), + std::forward_as_tuple(xenos::kEdramTileCount, RenderTargetKey(), + RenderTargetKey(), RenderTargetKey())); + } + + for (const auto& render_target_pair : render_targets_) { + if (render_target_pair.second) { + delete render_target_pair.second; + } + } + render_targets_.clear(); +} + +void RenderTargetCache::ShutdownCommon() { + DestroyAllRenderTargets(true); +} + +void RenderTargetCache::ClearCache() { + // Keep only render targets currently owning any EDRAM data. + if (!render_targets_.empty()) { + std::unordered_set used_render_targets; + for (const auto& ownership_range_pair : ownership_ranges_) { + const OwnershipRange& ownership_range = ownership_range_pair.second; + if (!ownership_range.render_target.IsEmpty()) { + used_render_targets.emplace(ownership_range.render_target); + } + if (!ownership_range.host_depth_render_target_unorm24.IsEmpty()) { + used_render_targets.emplace(ownership_range.host_depth_render_target_unorm24); + } + if (!ownership_range.host_depth_render_target_float24.IsEmpty()) { + used_render_targets.emplace(ownership_range.host_depth_render_target_float24); + } + } + if (render_targets_.size() != used_render_targets.size()) { + typename decltype(render_targets_)::iterator it_next; + for (auto it = render_targets_.begin(); it != render_targets_.end(); it = it_next) { + it_next = std::next(it); + if (!it->second) { + render_targets_.erase(it); + continue; + } + if (used_render_targets.find(it->second->key()) == used_render_targets.end()) { + delete it->second; + render_targets_.erase(it); + } + } + } + } +} + +void RenderTargetCache::BeginFrame() { + ResetAccumulatedRenderTargets(); +} + +bool RenderTargetCache::Update(bool is_rasterization_done, + reg::RB_DEPTHCONTROL normalized_depth_control, + uint32_t normalized_color_mask, const Shader& vertex_shader) { + const RegisterFile& regs = register_file(); + bool interlock_barrier_only = GetPath() == Path::kPixelShaderInterlock; + + auto rb_surface_info = regs.Get(); + xenos::MsaaSamples msaa_samples = rb_surface_info.msaa_samples; + assert_true(msaa_samples <= xenos::MsaaSamples::k4X); + if (msaa_samples > xenos::MsaaSamples::k4X) { + // Safety check because a lot of code assumes up to 4x. + assert_always(); + REXGPU_ERROR("{}x MSAA requested by the guest, Xenos only supports up to 4x", + uint32_t(1) << uint32_t(msaa_samples)); + return false; + } + uint32_t msaa_samples_x_log2 = uint32_t(msaa_samples >= xenos::MsaaSamples::k4X); + uint32_t pitch_pixels = rb_surface_info.surface_pitch; + // surface_pitch 0 should be handled in disabling rasterization (hopefully + // it's safe to assume that). + assert_true(pitch_pixels || !is_rasterization_done); + if (!pitch_pixels) { + is_rasterization_done = false; + } else if (pitch_pixels > xenos::kTexture2DCubeMaxWidthHeight) { + REXGPU_ERROR( + "Surface pitch {} larger than the maximum texture width {} specified " + "by the guest", + pitch_pixels, xenos::kTexture2DCubeMaxWidthHeight); + return false; + } + uint32_t pitch_tiles_at_32bpp = + ((pitch_pixels << msaa_samples_x_log2) + (xenos::kEdramTileWidthSamples - 1)) / + xenos::kEdramTileWidthSamples; + if (!interlock_barrier_only) { + uint32_t pitch_pixels_tile_aligned_scaled = + pitch_tiles_at_32bpp * (xenos::kEdramTileWidthSamples >> msaa_samples_x_log2) * + draw_resolution_scale_x(); + uint32_t max_render_target_width = GetMaxRenderTargetWidth(); + if (pitch_pixels_tile_aligned_scaled > max_render_target_width) { + // TODO(Triang3l): If really needed for some game on some device, clamp + // the pitch and generate multiple ranges (each for every row of tiles) + // with gaps for padding. Very few PowerVR GPUs have 4096, not 8192, as + // the limit, though with 8192 (on Mali) the actual limit for Xenia is + // 8160 because tile padding is stored - but 8192 should be extremely rare + // anyway. + REXGPU_ERROR( + "Surface pitch aligned to EDRAM tiles and resolution-scaled {} " + "larger than the maximum host render target width {}", + pitch_pixels_tile_aligned_scaled, max_render_target_width); + return false; + } + } + + // Get used render targets. + // [0] is depth / stencil where relevant, [1...4] is color. + // Depth / stencil testing / writing is before color in the pipeline. + uint32_t depth_and_color_rts_used_bits = 0; + // depth_and_color_rts_used_bits -> EDRAM base. + uint32_t edram_bases[1 + xenos::kMaxColorRenderTargets]; + uint32_t resource_formats[1 + xenos::kMaxColorRenderTargets]; + uint32_t rts_are_64bpp = 0; + if (is_rasterization_done) { + if (normalized_depth_control.z_enable || normalized_depth_control.stencil_enable) { + depth_and_color_rts_used_bits |= 1; + auto rb_depth_info = regs.Get(); + edram_bases[0] = rb_depth_info.depth_base; + // With pixel shader interlock, always the same addressing disregarding + // the format. + resource_formats[0] = interlock_barrier_only ? 0 : uint32_t(rb_depth_info.depth_format); + } + for (uint32_t i = 0; i < xenos::kMaxColorRenderTargets; ++i) { + if (!(normalized_color_mask & (uint32_t(0b1111) << (4 * i)))) { + continue; + } + auto color_info = regs.Get(reg::RB_COLOR_INFO::rt_register_indices[i]); + uint32_t rt_bit_index = 1 + i; + depth_and_color_rts_used_bits |= uint32_t(1) << rt_bit_index; + edram_bases[rt_bit_index] = color_info.color_base; + xenos::ColorRenderTargetFormat color_format = + regs.Get(reg::RB_COLOR_INFO::rt_register_indices[i]).color_format; + bool is_64bpp = xenos::IsColorRenderTargetFormat64bpp(color_format); + if (is_64bpp) { + rts_are_64bpp |= uint32_t(1) << rt_bit_index; + } + xenos::ColorRenderTargetFormat color_resource_format; + if (interlock_barrier_only) { + // Only changes in mapping between coordinates and addresses are + // interesting (along with access overlap between draw calls), thus only + // pixel size is relevant. + color_resource_format = is_64bpp ? xenos::ColorRenderTargetFormat::k_16_16_16_16 + : xenos::ColorRenderTargetFormat::k_8_8_8_8; + } else { + color_resource_format = GetColorResourceFormat(xenos::GetStorageColorFormat(color_format)); + } + resource_formats[rt_bit_index] = uint32_t(color_resource_format); + } + } + + uint32_t rts_remaining; + uint32_t rt_index; + + // Eliminate other bound render targets if their EDRAM base conflicts with + // another render target - it's an error in most host implementations to bind + // the same render target into multiple slots, also the behavior would be + // unpredictable if that happens. + // Depth is considered the least important as it's earlier in the pipeline + // (issues caused by color and depth render target collisions haven't been + // found yet), but render targets with smaller index are considered more + // important - specifically, because of the usage in the lighting pass of + // 4D5307E6, which can be checked in the vertical look calibration sequence in + // the beginning of the game: if render target 0 is removed in favor of 1, the + // characters and the world will be too dark, like fully in shadow - + // especially prominent on the helmet. This happens because the shader picks + // between two render targets to write dynamically (though with a static, bool + // constant condition), but all other state is set up in a way that implies + // the same render target being bound twice. On Direct3D 9, if you don't write + // to a color pixel shader output on the control flow that was taken, the + // render target will not be written to. However, this has been relaxed in + // Direct3D 10, where if the shader declares an output, it's assumed to be + // always written (or with an undefined value otherwise). + rts_remaining = depth_and_color_rts_used_bits & ~(uint32_t(1)); + while (rex::bit_scan_forward(rts_remaining, &rt_index)) { + rts_remaining &= ~(uint32_t(1) << rt_index); + uint32_t edram_base = edram_bases[rt_index]; + uint32_t rts_other_remaining = + depth_and_color_rts_used_bits & (~((uint32_t(1) << (rt_index + 1)) - 1) | uint32_t(1)); + uint32_t rt_other_index; + while (rex::bit_scan_forward(rts_other_remaining, &rt_other_index)) { + rts_other_remaining &= ~(uint32_t(1) << rt_other_index); + if (edram_bases[rt_other_index] == edram_base) { + depth_and_color_rts_used_bits &= ~(uint32_t(1) << rt_other_index); + } + } + } + + // Clear ownership transfers before adding any. + if (!interlock_barrier_only) { + for (size_t i = 0; i < rex::countof(last_update_transfers_); ++i) { + last_update_transfers_[i].clear(); + } + } + + if (!depth_and_color_rts_used_bits) { + // Nothing to bind, don't waste time on things like memexport-only draws - + // just check if old bindings can still be used. + std::memset(last_update_used_render_targets_, 0, sizeof(last_update_used_render_targets_)); + if (are_accumulated_render_targets_valid_) { + for (size_t i = 0; i < rex::countof(last_update_accumulated_render_targets_); ++i) { + const RenderTarget* render_target = last_update_accumulated_render_targets_[i]; + if (!render_target) { + continue; + } + RenderTargetKey rt_key = render_target->key(); + if (rt_key.pitch_tiles_at_32bpp != pitch_tiles_at_32bpp || + rt_key.msaa_samples != msaa_samples) { + are_accumulated_render_targets_valid_ = false; + break; + } + } + } + if (!are_accumulated_render_targets_valid_) { + std::memset(last_update_accumulated_render_targets_, 0, + sizeof(last_update_accumulated_render_targets_)); + } + return true; + } + + // Estimate height used by render targets (for color for writes, for depth / + // stencil for both reads and writes) from various sources. + uint32_t height_used = + std::min(GetRenderTargetHeight(pitch_tiles_at_32bpp, msaa_samples), + draw_extent_estimator_.EstimateMaxY( + interlock_barrier_only + ? REXCVAR_GET(execute_unclipped_draw_vs_on_cpu_for_psi_render_backend) + : true, + vertex_shader)); + + // Sorted by EDRAM base and then by index in the pipeline - for simplicity, + // treat render targets placed closer to the end of the EDRAM as truncating + // the previous one (and in case multiple render targets are placed at the + // same EDRAM base, though normally this shouldn't happen, treat the color + // ones as more important than the depth one, which may be not needed and just + // a leftover if the draw, for instance, has depth / stencil happening to be + // always passing and never writing with the current state, and also because + // depth testing has to happen before the color is written). Overall it's + // normal for estimated EDRAM ranges of render targets to intersect if drawing + // without a viewport (as there's nothing to clamp the estimated height) and + // multiple render targets are bound. + std::pair edram_bases_sorted[1 + xenos::kMaxColorRenderTargets]; + uint32_t edram_bases_sorted_count = 0; + rts_remaining = depth_and_color_rts_used_bits; + while (rex::bit_scan_forward(rts_remaining, &rt_index)) { + rts_remaining &= ~(uint32_t(1) << rt_index); + edram_bases_sorted[edram_bases_sorted_count++] = + std::make_pair(edram_bases[rt_index], rt_index); + } + std::sort(edram_bases_sorted, edram_bases_sorted + edram_bases_sorted_count); + // "As if it was 64bpp" (contribution of 32bpp render targets multiplied by 2, + // and clamping for 32bpp render targets divides this by 2) because 32bpp + // render targets can be combined with twice as long 64bpp render targets. An + // example is the 4541099D menu background (1-sample 1152x720, or 1200x720 + // after rounding to tiles, with a 32bpp depth buffer at 0 requiring 675 + // tiles, and a 64bpp color buffer at 675 requiring 1350 tiles, but the + // smallest distance between two render target bases is 675 tiles). + uint32_t rt_max_distance_tiles_at_64bpp = xenos::kEdramTileCount * 2; + if (REXCVAR_GET(mrt_edram_used_range_clamp_to_min) && edram_bases_sorted_count >= 2) { + for (uint32_t i = 1; i < edram_bases_sorted_count; ++i) { + const std::pair& rt_base_prev = edram_bases_sorted[i - 1]; + rt_max_distance_tiles_at_64bpp = + std::min(rt_max_distance_tiles_at_64bpp, + (edram_bases_sorted[i].first - rt_base_prev.first) + << (((rts_are_64bpp >> rt_base_prev.second) & 1) ^ 1)); + } + // Clamp to the distance from the last render target to the first with + // EDRAM addressing wrapping. + const std::pair& rt_base_last = + edram_bases_sorted[edram_bases_sorted_count - 1]; + rt_max_distance_tiles_at_64bpp = + std::min(rt_max_distance_tiles_at_64bpp, + (xenos::kEdramTileCount + edram_bases_sorted[0].first - rt_base_last.first) + << (((rts_are_64bpp >> rt_base_last.second) & 1) ^ 1)); + } + + // Make sure all the needed render targets are created, and gather lengths of + // ranges used by each render target. + RenderTargetKey rt_keys[1 + xenos::kMaxColorRenderTargets]; + RenderTarget* rts[1 + xenos::kMaxColorRenderTargets]; + uint32_t rt_lengths_tiles[1 + xenos::kMaxColorRenderTargets]; + uint32_t length_used_tiles_at_32bpp = + ((height_used << uint32_t(msaa_samples >= xenos::MsaaSamples::k2X)) + + (xenos::kEdramTileHeightSamples - 1)) / + xenos::kEdramTileHeightSamples * pitch_tiles_at_32bpp; + for (uint32_t i = 0; i < edram_bases_sorted_count; ++i) { + const std::pair& rt_base_index = edram_bases_sorted[i]; + uint32_t rt_base = rt_base_index.first; + uint32_t rt_bit_index = rt_base_index.second; + RenderTargetKey& rt_key = rt_keys[rt_bit_index]; + rt_key.base_tiles = rt_base; + rt_key.pitch_tiles_at_32bpp = pitch_tiles_at_32bpp; + rt_key.msaa_samples = msaa_samples; + rt_key.is_depth = rt_bit_index == 0; + rt_key.resource_format = resource_formats[rt_bit_index]; + if (!interlock_barrier_only) { + RenderTarget* render_target = GetOrCreateRenderTarget(rt_key); + if (!render_target) { + return false; + } + rts[rt_bit_index] = render_target; + } + uint32_t rt_is_64bpp = (rts_are_64bpp >> rt_bit_index) & 1; + // The last render target can occupy the EDRAM until the base of the first + // render target (itself in case of 1 render target) with EDRAM addressing + // wrapping. + rt_lengths_tiles[i] = std::min(std::min(length_used_tiles_at_32bpp << rt_is_64bpp, + rt_max_distance_tiles_at_64bpp >> (rt_is_64bpp ^ 1)), + ((i + 1 < edram_bases_sorted_count) + ? edram_bases_sorted[i + 1].first + : (xenos::kEdramTileCount + edram_bases_sorted[0].first)) - + rt_base); + } + + if (interlock_barrier_only) { + // Because a full pixel shader interlock barrier may clear the ownership map + // (since it flushes all previous writes, and there's no need for another + // barrier if an overlap is encountered later between pre-barrier and + // post-barrier usages), check if any overlap requiring a barrier happens, + // and then insert the barrier if needed. + bool interlock_barrier_needed = false; + for (uint32_t i = 0; i < edram_bases_sorted_count; ++i) { + const std::pair& rt_base_index = edram_bases_sorted[i]; + if (WouldOwnershipChangeRequireTransfers(rt_keys[rt_base_index.second], 0, + rt_lengths_tiles[i])) { + interlock_barrier_needed = true; + break; + } + } + if (interlock_barrier_needed) { + RequestPixelShaderInterlockBarrier(); + } + } + + // From now on ownership transfers should succeed for simplicity and + // consistency, even if they fail in the implementation (just ignore that and + // draw with whatever contents currently are in the render target in this + // case). + + for (uint32_t i = 0; i < edram_bases_sorted_count; ++i) { + const std::pair& rt_base_index = edram_bases_sorted[i]; + uint32_t rt_bit_index = rt_base_index.second; + ChangeOwnership(rt_keys[rt_bit_index], 0, rt_lengths_tiles[i], + interlock_barrier_only ? nullptr : &last_update_transfers_[rt_bit_index]); + } + + if (interlock_barrier_only) { + // No copying transfers or render target bindings - only needed the barrier. + return true; + } + + // If everything succeeded, update the used render targets. + for (uint32_t i = 0; i < 1 + xenos::kMaxColorRenderTargets; ++i) { + last_update_used_render_targets_[i] = + (depth_and_color_rts_used_bits & (uint32_t(1) << i)) ? rts[i] : nullptr; + } + if (are_accumulated_render_targets_valid_) { + // Check if the only re-enabling a previously bound render target. + for (uint32_t i = 0; i < 1 + xenos::kMaxColorRenderTargets; ++i) { + RenderTarget* current_rt = + (depth_and_color_rts_used_bits & (uint32_t(1) << i)) ? rts[i] : nullptr; + const RenderTarget* accumulated_rt = last_update_accumulated_render_targets_[i]; + if (!accumulated_rt) { + if (current_rt) { + // Binding a totally new render target - won't keep the existing + // render pass anyway, no much need to try to re-enable previously + // disabled render targets in other slots as well, even though that + // would be valid. + are_accumulated_render_targets_valid_ = false; + break; + } + // Append the new render target. + last_update_accumulated_render_targets_[i] = current_rt; + continue; + } + if (current_rt) { + if (current_rt != accumulated_rt) { + // Changing a render target in a slot. + are_accumulated_render_targets_valid_ = false; + break; + } + } else { + RenderTargetKey accumulated_rt_key = accumulated_rt->key(); + if (accumulated_rt_key.pitch_tiles_at_32bpp != pitch_tiles_at_32bpp || + accumulated_rt_key.msaa_samples != msaa_samples) { + // The previously bound render target is incompatible with the + // current surface info. + are_accumulated_render_targets_valid_ = false; + break; + } + } + } + // Make sure the same render target isn't bound into two different slots + // over time. + for (uint32_t i = 1; + are_accumulated_render_targets_valid_ && i < 1 + xenos::kMaxColorRenderTargets; ++i) { + const RenderTarget* render_target = last_update_accumulated_render_targets_[i]; + if (!render_target) { + continue; + } + for (uint32_t j = 0; j < i; ++j) { + if (last_update_accumulated_render_targets_[j] == render_target) { + are_accumulated_render_targets_valid_ = false; + break; + } + } + } + } + if (!are_accumulated_render_targets_valid_) { + std::memcpy(last_update_accumulated_render_targets_, last_update_used_render_targets_, + sizeof(last_update_accumulated_render_targets_)); + are_accumulated_render_targets_valid_ = true; + } + + return true; +} + +uint32_t RenderTargetCache::GetLastUpdateBoundRenderTargets( + uint32_t* depth_and_color_formats_out) const { + if (GetPath() != Path::kHostRenderTargets) { + if (depth_and_color_formats_out) { + std::memset(depth_and_color_formats_out, 0, + sizeof(uint32_t) * (1 + xenos::kMaxColorRenderTargets)); + } + return 0; + } + uint32_t rts_used = 0; + for (uint32_t i = 0; i < 1 + xenos::kMaxColorRenderTargets; ++i) { + const RenderTarget* render_target = last_update_accumulated_render_targets_[i]; + if (!render_target) { + if (depth_and_color_formats_out) { + depth_and_color_formats_out[i] = 0; + } + continue; + } + rts_used |= uint32_t(1) << i; + if (depth_and_color_formats_out) { + depth_and_color_formats_out[i] = render_target->key().resource_format; + } + } + return rts_used; +} + +uint32_t RenderTargetCache::GetRenderTargetHeight(uint32_t pitch_tiles_at_32bpp, + xenos::MsaaSamples msaa_samples) const { + if (!pitch_tiles_at_32bpp) { + return 0; + } + // Down to the beginning of the render target in the next 11-bit EDRAM + // addressing period. + uint32_t tile_rows = (xenos::kEdramTileCount + (pitch_tiles_at_32bpp - 1)) / pitch_tiles_at_32bpp; + // Clamp to the guest limit (tile padding should exceed it) and to the host + // limit (tile padding mustn't exceed it). + static_assert(!(xenos::kTexture2DCubeMaxWidthHeight % xenos::kEdramTileHeightSamples), + "Maximum guest render target height is assumed to always be a multiple " + "of an EDRAM tile height"); + uint32_t max_height_scaled = std::min( + xenos::kTexture2DCubeMaxWidthHeight * draw_resolution_scale_y(), GetMaxRenderTargetHeight()); + uint32_t msaa_samples_y_log2 = uint32_t(msaa_samples >= xenos::MsaaSamples::k2X); + uint32_t tile_height_samples_scaled = xenos::kEdramTileHeightSamples * draw_resolution_scale_y(); + tile_rows = + std::min(tile_rows, (max_height_scaled << msaa_samples_y_log2) / tile_height_samples_scaled); + assert_not_zero(tile_rows); + return tile_rows * (xenos::kEdramTileHeightSamples >> msaa_samples_y_log2); +} + +void RenderTargetCache::GetHostDepthStoreRectangleInfo( + const Transfer::Rectangle& transfer_rectangle, xenos::MsaaSamples msaa_samples, + HostDepthStoreRectangleConstant& rectangle_constant_out, uint32_t& group_count_x_out, + uint32_t& group_count_y_out) const { + // Initialize to all bits zeroed. + HostDepthStoreRectangleConstant rectangle_constant; + // 8 pixels is the resolve granularity, both clearing and tile size are + // aligned to 8. + assert_zero(transfer_rectangle.x_pixels & 7); + assert_zero(transfer_rectangle.y_pixels & 7); + assert_zero(transfer_rectangle.width_pixels & 7); + assert_zero(transfer_rectangle.height_pixels & 7); + assert_not_zero(transfer_rectangle.width_pixels); + rectangle_constant.x_pixels_div_8 = transfer_rectangle.x_pixels >> 3; + rectangle_constant.y_pixels_div_8 = transfer_rectangle.y_pixels >> 3; + rectangle_constant.width_pixels_div_8_minus_1 = (transfer_rectangle.width_pixels >> 3) - 1; + rectangle_constant_out = rectangle_constant; + // 1 thread group = 64x8 host samples. + uint32_t pixel_size_x = draw_resolution_scale_x() + << uint32_t(msaa_samples >= xenos::MsaaSamples::k4X); + uint32_t pixel_size_y = draw_resolution_scale_y() + << uint32_t(msaa_samples >= xenos::MsaaSamples::k2X); + group_count_x_out = (transfer_rectangle.width_pixels * pixel_size_x + 63) >> 6; + group_count_y_out = (transfer_rectangle.height_pixels * pixel_size_y) >> 3; +} + +void RenderTargetCache::GetResolveCopyRectanglesToDump( + uint32_t base, uint32_t row_length, uint32_t rows, uint32_t pitch, + std::vector& rectangles_out) const { + rectangles_out.clear(); + assert_true(row_length <= pitch); + row_length = std::min(row_length, pitch); + if (!row_length || !rows) { + return; + } + auto get_rectangles_in_extent = [&](uint32_t extent_start, uint32_t extent_end, + uint32_t range_local_offset) { + // Collect render targets owning ranges within the specified rectangle. The + // first render target in the range may be before the lower_bound, only + // being in the range with its tail. + auto it = ownership_ranges_.lower_bound(extent_start); + if (it != ownership_ranges_.cbegin()) { + auto it_pre = std::prev(it); + if (it_pre->second.end_tiles > extent_start) { + it = it_pre; + } + } + for (; it != ownership_ranges_.cend(); ++it) { + uint32_t range_global_start = std::max(it->first, extent_start); + if (range_global_start >= extent_end) { + break; + } + RenderTargetKey rt_key = it->second.render_target; + if (rt_key.IsEmpty()) { + continue; + } + // Merge with other render target ranges with the same current ownership, + // but different depth ownership, since it's not relevant to resolving. + while (it != ownership_ranges_.cend()) { + auto it_next = std::next(it); + if (it_next == ownership_ranges_.cend() || it_next->first >= extent_end || + it_next->second.render_target != rt_key) { + break; + } + it = it_next; + } + + uint32_t range_local_start = + range_local_offset + std::max(range_global_start, extent_start) - base; + uint32_t range_local_end = + range_local_offset + std::min(it->second.end_tiles, extent_end) - base; + assert_true(range_local_start < range_local_end); + + uint32_t rows_start = range_local_start / pitch; + uint32_t rows_end = (range_local_end + (pitch - 1)) / pitch; + uint32_t row_first_start = range_local_start - rows_start * pitch; + if (row_first_start >= row_length) { + // The first row starts within the pitch padding. + if (rows_start + 1 < rows_end) { + // Multiple rows - start at the second. + ++rows_start; + row_first_start = 0; + } else { + // Single row - nothing to dump. + continue; + } + } + + auto it_rt = render_targets_.find(rt_key); + assert_true(it_rt != render_targets_.cend()); + assert_not_null(it_rt->second); + // Don't include pitch padding in the last row. + rectangles_out.emplace_back( + it_rt->second, rows_start, rows_end - rows_start, row_first_start, + std::min(pitch - (rows_end * pitch - range_local_end), row_length)); + } + }; + uint32_t resolve_area_end = base + (rows - 1) * pitch + row_length; + get_rectangles_in_extent(base, std::min(resolve_area_end, xenos::kEdramTileCount), 0); + if (resolve_area_end > xenos::kEdramTileCount) { + // The resolve area goes to the next EDRAM addressing period. + get_rectangles_in_extent(0, std::min(resolve_area_end & (xenos::kEdramTileCount - 1), base), + xenos::kEdramTileCount); + } +} + +void RenderTargetCache::GetResolveCopyDispatchesToDump( + uint32_t base, uint32_t row_length, uint32_t rows, uint32_t pitch, + std::vector& rectangles_out, + std::vector& dispatches_out) const { + GetResolveCopyRectanglesToDump(base, row_length, rows, pitch, rectangles_out); + dispatches_out.clear(); + for (uint32_t rectangle_index = 0; rectangle_index < uint32_t(rectangles_out.size()); + ++rectangle_index) { + const ResolveCopyDumpRectangle& rectangle = rectangles_out[rectangle_index]; + ResolveCopyDumpRectangle::Dispatch + rectangle_dispatches[ResolveCopyDumpRectangle::kMaxDispatches]; + uint32_t dispatch_count = rectangle.GetDispatches(pitch, row_length, rectangle_dispatches); + for (uint32_t i = 0; i < dispatch_count; ++i) { + dispatches_out.emplace_back(rectangle_index, rectangle_dispatches[i]); + } + } +} + +bool RenderTargetCache::PrepareHostRenderTargetsResolveClear( + const draw_util::ResolveInfo& resolve_info, Transfer::Rectangle& clear_rectangle_out, + RenderTarget*& depth_render_target_out, std::vector& depth_transfers_out, + RenderTarget*& color_render_target_out, std::vector& color_transfers_out) { + assert_true(GetPath() == Path::kHostRenderTargets); + + uint32_t pitch_tiles_at_32bpp; + uint32_t base_offset_tiles_at_32bpp; + xenos::MsaaSamples msaa_samples; + if (resolve_info.IsClearingDepth()) { + pitch_tiles_at_32bpp = resolve_info.depth_edram_info.pitch_tiles; + base_offset_tiles_at_32bpp = + resolve_info.depth_edram_info.base_tiles - resolve_info.depth_original_base; + msaa_samples = resolve_info.depth_edram_info.msaa_samples; + } else if (resolve_info.IsClearingColor()) { + pitch_tiles_at_32bpp = resolve_info.color_edram_info.pitch_tiles; + base_offset_tiles_at_32bpp = + resolve_info.color_edram_info.base_tiles - resolve_info.color_original_base; + if (resolve_info.color_edram_info.format_is_64bpp) { + assert_zero(pitch_tiles_at_32bpp & 1); + pitch_tiles_at_32bpp >>= 1; + assert_zero(base_offset_tiles_at_32bpp & 1); + base_offset_tiles_at_32bpp >>= 1; + } + msaa_samples = resolve_info.color_edram_info.msaa_samples; + } else { + return false; + } + assert_true(msaa_samples <= xenos::MsaaSamples::k4X); + if (!pitch_tiles_at_32bpp) { + return false; + } + uint32_t msaa_samples_x_log2 = uint32_t(msaa_samples >= xenos::MsaaSamples::k4X); + uint32_t msaa_samples_y_log2 = uint32_t(msaa_samples >= xenos::MsaaSamples::k2X); + if (pitch_tiles_at_32bpp > ((xenos::kTexture2DCubeMaxWidthHeight << msaa_samples_x_log2) + + (xenos::kEdramTileWidthSamples - 1)) / + xenos::kEdramTileWidthSamples) { + REXGPU_ERROR( + "Surface pitch in 80-sample groups {} at {}x MSAA larger than the " + "maximum texture width {} specified by the guest in a resolve", + pitch_tiles_at_32bpp, uint32_t(1) << uint32_t(msaa_samples), + xenos::kTexture2DCubeMaxWidthHeight); + return false; + } + uint32_t pitch_pixels = + pitch_tiles_at_32bpp * (xenos::kEdramTileWidthSamples >> msaa_samples_x_log2); + uint32_t pitch_pixels_scaled = pitch_pixels * draw_resolution_scale_x(); + uint32_t max_render_target_width = GetMaxRenderTargetWidth(); + if (pitch_pixels_scaled > max_render_target_width) { + // TODO(Triang3l): If really needed for some game on some device, clamp the + // pitch the same way as explained in the comment in Update. + REXGPU_ERROR( + "Surface pitch aligned to EDRAM tiles and resolution-scaled {} larger " + "than the maximum host render target width {} in a resolve", + pitch_pixels_scaled, max_render_target_width); + return false; + } + + uint32_t render_target_height_pixels = GetRenderTargetHeight(pitch_tiles_at_32bpp, msaa_samples); + uint32_t base_offset_rows_at_32bpp = base_offset_tiles_at_32bpp / pitch_tiles_at_32bpp; + Transfer::Rectangle clear_rectangle; + clear_rectangle.x_pixels = + std::min((base_offset_tiles_at_32bpp - base_offset_rows_at_32bpp * pitch_tiles_at_32bpp) * + (xenos::kEdramTileWidthSamples >> msaa_samples_x_log2) + + (uint32_t(resolve_info.coordinate_info.edram_offset_x_div_8) << 3), + pitch_pixels); + clear_rectangle.y_pixels = + std::min(base_offset_rows_at_32bpp * (xenos::kEdramTileHeightSamples >> msaa_samples_y_log2) + + (uint32_t(resolve_info.coordinate_info.edram_offset_y_div_8) << 3), + render_target_height_pixels); + clear_rectangle.width_pixels = std::min(uint32_t(resolve_info.coordinate_info.width_div_8) << 3, + pitch_pixels - clear_rectangle.x_pixels); + clear_rectangle.height_pixels = std::min(uint32_t(resolve_info.height_div_8) << 3, + render_target_height_pixels - clear_rectangle.y_pixels); + if (!clear_rectangle.width_pixels || !clear_rectangle.height_pixels) { + // Outside the pitch / height (or initially specified as 0). + return false; + } + + // Change ownership of the tiles containing the area to be cleared, so the + // up-to-date host render target for the cleared range will be the cleared + // one. + uint32_t clear_start_tiles_at_32bpp = + ((clear_rectangle.y_pixels << msaa_samples_y_log2) / xenos::kEdramTileHeightSamples) * + pitch_tiles_at_32bpp + + (clear_rectangle.x_pixels << msaa_samples_x_log2) / xenos::kEdramTileWidthSamples; + uint32_t clear_length_tiles_at_32bpp = + (((clear_rectangle.y_pixels + clear_rectangle.height_pixels - 1) << msaa_samples_y_log2) / + xenos::kEdramTileHeightSamples) * + pitch_tiles_at_32bpp + + ((clear_rectangle.x_pixels + clear_rectangle.width_pixels - 1) << msaa_samples_x_log2) / + xenos::kEdramTileWidthSamples + + 1 - clear_start_tiles_at_32bpp; + // Up to the range from the base in the current 11 tile index bits to the base + // in the next 11 tile index bits after wrapping can be cleared. + uint32_t depth_clear_start_tiles_base_relative = 0; + uint32_t depth_clear_length_tiles = 0; + if (resolve_info.IsClearingDepth()) { + depth_clear_start_tiles_base_relative = + std::min(clear_start_tiles_at_32bpp, xenos::kEdramTileCount); + depth_clear_length_tiles = + std::min(clear_start_tiles_at_32bpp + clear_length_tiles_at_32bpp, xenos::kEdramTileCount) - + depth_clear_start_tiles_base_relative; + } + uint32_t color_clear_start_tiles_base_relative = 0; + uint32_t color_clear_length_tiles = 0; + if (resolve_info.IsClearingColor()) { + color_clear_start_tiles_base_relative = + std::min(clear_start_tiles_at_32bpp << resolve_info.color_edram_info.format_is_64bpp, + xenos::kEdramTileCount); + color_clear_length_tiles = std::min((clear_start_tiles_at_32bpp + clear_length_tiles_at_32bpp) + << resolve_info.color_edram_info.format_is_64bpp, + xenos::kEdramTileCount) - + color_clear_start_tiles_base_relative; + } + if (depth_clear_length_tiles && color_clear_length_tiles) { + // Prevent overlap - clear the depth only until the color, the color only + // until the depth, in the current or the next 11 bits of the tile index. + uint32_t depth_clear_start_tiles_wrapped = + (resolve_info.depth_original_base + depth_clear_start_tiles_base_relative) & + (xenos::kEdramTileCount - 1); + uint32_t color_clear_start_tiles_wrapped = + (resolve_info.color_original_base + color_clear_start_tiles_base_relative) & + (xenos::kEdramTileCount - 1); + depth_clear_length_tiles = + std::min(depth_clear_length_tiles, + ((color_clear_start_tiles_wrapped < depth_clear_start_tiles_wrapped) + ? xenos::kEdramTileCount + : 0) + + color_clear_start_tiles_wrapped - depth_clear_start_tiles_wrapped); + color_clear_length_tiles = + std::min(color_clear_length_tiles, + ((depth_clear_start_tiles_wrapped < color_clear_start_tiles_wrapped) + ? xenos::kEdramTileCount + : 0) + + depth_clear_start_tiles_wrapped - color_clear_start_tiles_wrapped); + } + + RenderTargetKey depth_render_target_key; + RenderTarget* depth_render_target = nullptr; + if (depth_clear_length_tiles) { + depth_render_target_key.base_tiles = resolve_info.depth_original_base; + depth_render_target_key.pitch_tiles_at_32bpp = pitch_tiles_at_32bpp; + depth_render_target_key.msaa_samples = msaa_samples; + depth_render_target_key.is_depth = 1; + depth_render_target_key.resource_format = resolve_info.depth_edram_info.format; + depth_render_target = GetOrCreateRenderTarget(depth_render_target_key); + if (!depth_render_target) { + // Failed to create the depth render target, don't clear it. + depth_render_target_key = RenderTargetKey(); + depth_clear_length_tiles = 0; + } + } + RenderTargetKey color_render_target_key; + RenderTarget* color_render_target = nullptr; + if (color_clear_length_tiles) { + color_render_target_key.base_tiles = resolve_info.color_original_base; + color_render_target_key.pitch_tiles_at_32bpp = pitch_tiles_at_32bpp; + color_render_target_key.msaa_samples = msaa_samples; + color_render_target_key.is_depth = 0; + color_render_target_key.resource_format = uint32_t(GetColorResourceFormat( + xenos::ColorRenderTargetFormat(resolve_info.color_edram_info.format))); + color_render_target = GetOrCreateRenderTarget(color_render_target_key); + if (!color_render_target) { + // Failed to create the color render target, don't clear it. + color_render_target_key = RenderTargetKey(); + color_clear_length_tiles = 0; + } + } + if (!depth_clear_length_tiles && !color_clear_length_tiles) { + // Complete overlap, or failed to create all the render targets. + return false; + } + + clear_rectangle_out = clear_rectangle; + depth_render_target_out = depth_render_target; + depth_transfers_out.clear(); + if (depth_render_target) { + ChangeOwnership(depth_render_target_key, depth_clear_start_tiles_base_relative, + depth_clear_length_tiles, &depth_transfers_out, &clear_rectangle); + } + color_render_target_out = color_render_target; + color_transfers_out.clear(); + if (color_render_target) { + ChangeOwnership(color_render_target_key, color_clear_start_tiles_base_relative, + color_clear_length_tiles, &color_transfers_out, &clear_rectangle); + } + return true; +} + +RenderTargetCache::RenderTarget* +RenderTargetCache::PrepareFullEdram1280xRenderTargetForSnapshotRestoration( + xenos::ColorRenderTargetFormat color_format) { + assert_true(GetPath() == Path::kHostRenderTargets); + constexpr uint32_t kPitchTilesAt32bpp = 16; + constexpr uint32_t kWidth = kPitchTilesAt32bpp * xenos::kEdramTileWidthSamples; + if (kWidth * draw_resolution_scale_x() > GetMaxRenderTargetWidth()) { + return nullptr; + } + // Same render target height is used for 32bpp and 64bpp to allow mixing them. + constexpr uint32_t kHeightTileRows = xenos::kEdramTileCount / kPitchTilesAt32bpp; + static_assert(kPitchTilesAt32bpp * kHeightTileRows == xenos::kEdramTileCount, + "Using width of the render target for EDRAM snapshot restoration that is " + "expected to result in the last row being fully utilized."); + constexpr uint32_t kHeight = kHeightTileRows * xenos::kEdramTileHeightSamples; + static_assert(kHeight <= xenos::kTexture2DCubeMaxWidthHeight, + "Using width of the render target for EDRAM snapshot restoration that is " + "expect to fully cover the EDRAM without exceeding the maximum guest " + "render target height."); + if (kHeight * draw_resolution_scale_y() > GetMaxRenderTargetHeight()) { + return nullptr; + } + RenderTargetKey render_target_key; + render_target_key.pitch_tiles_at_32bpp = kPitchTilesAt32bpp; + render_target_key.resource_format = uint32_t(GetColorResourceFormat(color_format)); + RenderTarget* render_target = GetOrCreateRenderTarget(render_target_key); + if (!render_target) { + return nullptr; + } + // Change ownership, but don't transfer the contents - they will be replaced + // anyway. + ownership_ranges_.clear(); + ownership_ranges_.emplace(std::piecewise_construct, std::forward_as_tuple(uint32_t(0)), + std::forward_as_tuple(xenos::kEdramTileCount, render_target_key, + RenderTargetKey(), RenderTargetKey())); + return render_target; +} + +void RenderTargetCache::PixelShaderInterlockFullEdramBarrierPlaced() { + assert_true(GetPath() == Path::kPixelShaderInterlock); + // Clear ownership - any overlap of data written before the barrier is safe. + OwnershipRange empty_range(xenos::kEdramTileCount, RenderTargetKey(), RenderTargetKey(), + RenderTargetKey()); + if (ownership_ranges_.size() == 1) { + // Do not reallocate map elements if not needed (either nothing drawn since + // the last barrier, or all of the EDRAM is owned by one render target). + // The ownership map contains no gaps - the first element should always be + // at 0. + assert_true(!ownership_ranges_.begin()->first); + OwnershipRange& all_edram_range = ownership_ranges_.begin()->second; + assert_true(all_edram_range.end_tiles == xenos::kEdramTileCount); + all_edram_range = empty_range; + return; + } + ownership_ranges_.clear(); + ownership_ranges_.emplace(0, empty_range); +} + +RenderTargetCache::RenderTarget* RenderTargetCache::GetOrCreateRenderTarget(RenderTargetKey key) { + assert_true(GetPath() == Path::kHostRenderTargets); + auto it_rt = render_targets_.find(key); + RenderTarget* render_target; + if (it_rt != render_targets_.end()) { + render_target = it_rt->second; + } else { + render_target = CreateRenderTarget(key); + uint32_t width = key.GetWidth(); + uint32_t height = GetRenderTargetHeight(key.pitch_tiles_at_32bpp, key.msaa_samples); + if (render_target) { + REXGPU_DEBUG( + "Created a {}x{} {}xMSAA {} render target with guest format {} at " + "EDRAM base {}", + width, height, uint32_t(1) << uint32_t(key.msaa_samples), + key.is_depth ? "depth" : "color", static_cast(key.resource_format), + static_cast(key.base_tiles)); + } else { + REXGPU_ERROR( + "Failed to create a {}x{} {}xMSAA {} render target with guest format " + "{} at EDRAM base {}", + width, height, uint32_t(1) << uint32_t(key.msaa_samples), + key.is_depth ? "depth" : "color", static_cast(key.resource_format), + static_cast(key.base_tiles)); + } + // Insert even if failed to create, not to try to create again. + render_targets_.emplace(key, render_target); + } + return render_target; +} + +bool RenderTargetCache::WouldOwnershipChangeRequireTransfers(RenderTargetKey dest, + uint32_t start_tiles_base_relative, + uint32_t length_tiles) const { + // xenos::kEdramTileCount with length 0 is fine if both the start and the end + // are clamped to xenos::kEdramTileCount. + assert_true(start_tiles_base_relative <= (xenos::kEdramTileCount - uint32_t(length_tiles != 0))); + assert_true(length_tiles <= xenos::kEdramTileCount); + if (length_tiles == 0) { + return false; + } + bool host_depth_encoding_different = dest.is_depth && GetPath() == Path::kHostRenderTargets && + IsHostDepthEncodingDifferent(dest.GetDepthFormat()); + auto would_require_transfers_in_extent = [&](uint32_t extent_start, uint32_t extent_end) -> bool { + // The map contains consecutive ranges, merged if the adjacent ones are the + // same. Find the range starting at >= the start. A portion of the range + // preceding it may be intersecting the render target's range (or even fully + // contain it). + auto it = ownership_ranges_.lower_bound(extent_start); + if (it != ownership_ranges_.begin()) { + auto it_pre = std::prev(it); + if (it_pre->second.end_tiles > extent_start) { + it = it_pre; + } + } + for (; it != ownership_ranges_.end(); ++it) { + if (it->first >= extent_end) { + // Outside the touched extent already. + break; + } + if (it->second.IsOwnedBy(dest, host_depth_encoding_different)) { + // Already owned by the needed render target - no need to transfer + // anything. + continue; + } + RenderTargetKey transfer_source = it->second.render_target; + // Only perform the transfer when actually changing the latest owner, not + // just the latest host depth owner - the transfer source is expected to + // be different than the destination. + if (!transfer_source.IsEmpty() && transfer_source != dest) { + return true; + } + } + return false; + }; + // start_tiles_base_relative may already be in the next 11 bits - wrap the + // start tile index to use the same code as if that was not the case. + uint32_t start_tiles = + (dest.base_tiles + start_tiles_base_relative) & (xenos::kEdramTileCount - 1); + uint32_t end_tiles = start_tiles + length_tiles; + if (would_require_transfers_in_extent(start_tiles, std::min(end_tiles, xenos::kEdramTileCount))) { + return true; + } + if (end_tiles > xenos::kEdramTileCount) { + // The check extent goes to the next EDRAM addressing period. + if (would_require_transfers_in_extent( + 0, std::min(end_tiles & (xenos::kEdramTileCount - 1), start_tiles))) { + return true; + } + } + return false; +} + +void RenderTargetCache::ChangeOwnership(RenderTargetKey dest, uint32_t start_tiles_base_relative, + uint32_t length_tiles, + std::vector* transfers_append_out, + const Transfer::Rectangle* resolve_clear_cutout) { + // xenos::kEdramTileCount with length 0 is fine if both the start and the end + // are clamped to xenos::kEdramTileCount. + assert_true(start_tiles_base_relative <= (xenos::kEdramTileCount - uint32_t(length_tiles != 0))); + assert_true(length_tiles <= xenos::kEdramTileCount); + if (length_tiles == 0) { + return; + } + uint32_t dest_pitch_tiles = dest.GetPitchTiles(); + bool dest_is_64bpp = dest.Is64bpp(); + bool host_depth_encoding_different = dest.is_depth && GetPath() == Path::kHostRenderTargets && + IsHostDepthEncodingDifferent(dest.GetDepthFormat()); + auto change_ownership_in_extent = [&](uint32_t extent_start, uint32_t extent_end) { + // The map contains consecutive ranges, merged if the adjacent ones are the + // same. Find the range starting at >= the start. A portion of the range + // preceding it may be intersecting the render target's range (or even fully + // contain it) - split it into the untouched head and the claimed tail if + // needed. + auto it = ownership_ranges_.lower_bound(extent_start); + if (it != ownership_ranges_.begin()) { + auto it_pre = std::prev(it); + if (it_pre->second.end_tiles > extent_start && + !it_pre->second.IsOwnedBy(dest, host_depth_encoding_different)) { + // Different render target overlapping the range - split the head. + ownership_ranges_.emplace(extent_start, it_pre->second); + it_pre->second.end_tiles = extent_start; + // Let the next loop do the transfer and needed merging and splitting + // starting from the added tail. + it = std::next(it_pre); + } + } + while (it != ownership_ranges_.end()) { + if (it->first >= extent_end) { + // Outside the touched extent already. + break; + } + if (it->second.IsOwnedBy(dest, host_depth_encoding_different)) { + // Already owned by the needed render target - no need to transfer + // anything. + ++it; + continue; + } + // Take over the current range. Handle the tail - may be outside the range + // (split in this case) or within it. + if (it->second.end_tiles > extent_end) { + // Split the tail. + ownership_ranges_.emplace(extent_end, it->second); + it->second.end_tiles = extent_end; + } + if (transfers_append_out) { + RenderTargetKey transfer_source = it->second.render_target; + // Only perform the copying when actually changing the latest owner, not + // just the latest host depth owner - the transfer source is expected to + // be different than the destination. + if (!transfer_source.IsEmpty() && transfer_source != dest) { + uint32_t transfer_end_tiles = std::min(it->second.end_tiles, extent_end); + if (!resolve_clear_cutout || + Transfer::GetRangeRectangles(it->first, transfer_end_tiles, dest.base_tiles, + dest_pitch_tiles, dest.msaa_samples, dest_is_64bpp, + nullptr, resolve_clear_cutout)) { + RenderTargetKey transfer_host_depth_source = + host_depth_encoding_different + ? it->second.GetHostDepthRenderTarget(dest.GetDepthFormat()) + : RenderTargetKey(); + if (transfer_host_depth_source == transfer_source) { + // Same render target, don't provide a separate host depth source. + transfer_host_depth_source = RenderTargetKey(); + } + if (!transfers_append_out->empty() && + transfers_append_out->back().end_tiles == it->first && + transfers_append_out->back().source->key() == transfer_source && + ((transfers_append_out->back().host_depth_source == nullptr) == + transfer_host_depth_source.IsEmpty()) && + (transfer_host_depth_source.IsEmpty() || + transfers_append_out->back().host_depth_source->key() == + transfer_host_depth_source)) { + // Extend the last transfer if, for example, transferring color, + // but host depth is different. + transfers_append_out->back().end_tiles = transfer_end_tiles; + } else { + auto transfer_source_rt_it = render_targets_.find(transfer_source); + if (transfer_source_rt_it != render_targets_.end()) { + assert_not_null(transfer_source_rt_it->second); + auto transfer_host_depth_source_rt_it = + !transfer_host_depth_source.IsEmpty() + ? render_targets_.find(transfer_host_depth_source) + : render_targets_.end(); + if (transfer_host_depth_source.IsEmpty() || + transfer_host_depth_source_rt_it != render_targets_.end()) { + assert_false(transfer_host_depth_source_rt_it != render_targets_.end() && + !transfer_host_depth_source_rt_it->second); + transfers_append_out->emplace_back( + it->first, transfer_end_tiles, transfer_source_rt_it->second, + transfer_host_depth_source_rt_it != render_targets_.end() + ? transfer_host_depth_source_rt_it->second + : nullptr); + } + } + } + } + } + } + // Claim the current range. + it->second.render_target = dest; + if (host_depth_encoding_different) { + it->second.GetHostDepthRenderTarget(dest.GetDepthFormat()) = dest; + } + // Check if can merge with the next range after claiming. + std::map::iterator it_next; + if (it != ownership_ranges_.end()) { + it_next = std::next(it); + if (it_next != ownership_ranges_.end() && it_next->second.AreOwnersSame(it->second)) { + // Merge with the next range. + it->second.end_tiles = it_next->second.end_tiles; + auto it_after = std::next(it_next); + ownership_ranges_.erase(it_next); + it_next = it_after; + } + } else { + it_next = ownership_ranges_.end(); + } + // Check if can merge with the previous range after claiming and merging + // with the next (thus obtaining the correct end pointer). + if (it != ownership_ranges_.begin()) { + auto it_prev = std::prev(it); + if (it_prev->second.AreOwnersSame(it->second)) { + it_prev->second.end_tiles = it->second.end_tiles; + ownership_ranges_.erase(it); + } + } + it = it_next; + } + }; + // start_tiles_base_relative may already be in the next 11 bits - wrap the + // start tile index to use the same code as if that was not the case. + uint32_t start_tiles = + (dest.base_tiles + start_tiles_base_relative) & (xenos::kEdramTileCount - 1); + uint32_t end_tiles = start_tiles + length_tiles; + change_ownership_in_extent(start_tiles, std::min(end_tiles, xenos::kEdramTileCount)); + if (end_tiles > xenos::kEdramTileCount) { + // The ownership change extent goes to the next EDRAM addressing period. + change_ownership_in_extent(0, std::min(end_tiles & (xenos::kEdramTileCount - 1), start_tiles)); + } +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/shader/dxbc.cpp b/src/graphics/pipeline/shader/dxbc.cpp new file mode 100644 index 0000000..07e6010 --- /dev/null +++ b/src/graphics/pipeline/shader/dxbc.cpp @@ -0,0 +1,27 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include + +namespace rex::graphics { + +DxbcShader::DxbcShader(xenos::ShaderType shader_type, uint64_t ucode_data_hash, + const uint32_t* ucode_dwords, size_t ucode_dword_count, + std::endian ucode_source_endian) + : Shader(shader_type, ucode_data_hash, ucode_dwords, ucode_dword_count, ucode_source_endian) {} + +Shader::Translation* DxbcShader::CreateTranslationInstance(uint64_t modification) { + return new DxbcTranslation(*this, modification); +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/shader/dxbc_translator.cpp b/src/graphics/pipeline/shader/dxbc_translator.cpp new file mode 100644 index 0000000..2c31a0e --- /dev/null +++ b/src/graphics/pipeline/shader/dxbc_translator.cpp @@ -0,0 +1,3417 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2018 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include "thirdparty/dxbc/DXBCChecksum.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(dxbc_switch, true, "GPU/Shader", "Use switch statements in DXBC"); + +REXCVAR_DEFINE_BOOL(dxbc_source_map, false, "GPU/Shader", "Generate source maps for DXBC"); + +namespace rex::graphics { +using namespace ucode; + +// Notes about operands: +// +// Reading and writing: +// - r# (temporary registers) are 4-component and can be used anywhere. +// - v# (inputs) are 4-component and read-only. +// - o# (outputs) are 4-component and write-only. +// - oDepth (pixel shader depth output) is 1-component and write-only. +// - x# (indexable temporary registers) are 4-component and can be accessed +// either via a mov load or a mov store (and those movs are counted as +// ArrayInstructions in STAT, not as MovInstructions), even though the D3D11.3 +// functional specification says x# can be used wherever r# can be used, but +// FXC emits only mov load/store in simple tests. +// +// Indexing: +// - Constant buffers use 3D indices in CBx[y][z] format, where x is the ID of +// the binding (CB#), y is the register to access within its space, z is the +// 4-component vector to access within the register binding. +// For example, if the requested vector is located in the beginning of the +// second buffer in the descriptor array at b2, which is assigned to CB1, the +// index would be CB1[3][0]. +// - Resources and samplers use 2D indices, where the first dimension is the +// S#/T#/U# binding index, and the second is the s#/t#/u# register index +// within its space. + +DxbcShaderTranslator::DxbcShaderTranslator(ui::GraphicsProvider::GpuVendorID vendor_id, + bool bindless_resources_used, bool edram_rov_used, + bool gamma_render_target_as_unorm8, + bool msaa_2x_supported, uint32_t draw_resolution_scale_x, + uint32_t draw_resolution_scale_y, + bool force_emit_source_map) + : a_(shader_code_, statistics_), + ao_(shader_object_, statistics_), + vendor_id_(vendor_id), + bindless_resources_used_(bindless_resources_used), + edram_rov_used_(edram_rov_used), + gamma_render_target_as_unorm8_(gamma_render_target_as_unorm8), + msaa_2x_supported_(msaa_2x_supported), + draw_resolution_scale_x_(draw_resolution_scale_x), + draw_resolution_scale_y_(draw_resolution_scale_y), + emit_source_map_(force_emit_source_map || REXCVAR_GET(dxbc_source_map)) { + assert_not_zero(draw_resolution_scale_x); + assert_not_zero(draw_resolution_scale_y); + // Don't allocate again and again for the first shader. + shader_code_.reserve(8192); + shader_object_.reserve(16384); +} +DxbcShaderTranslator::~DxbcShaderTranslator() = default; + +std::vector DxbcShaderTranslator::CreateDepthOnlyPixelShader() { + is_depth_only_pixel_shader_ = true; + // TODO(Triang3l): Handle in a nicer way (is_depth_only_pixel_shader_ is a + // leftover from when a Shader object wasn't used during translation). + Shader shader(xenos::ShaderType::kPixel, 0, nullptr, 0); + shader.AnalyzeUcode(instruction_disassembly_buffer_); + Shader::Translation& translation = *shader.GetOrCreateTranslation(0); + TranslateAnalyzedShader(translation); + is_depth_only_pixel_shader_ = false; + return translation.translated_binary(); +} + +uint64_t DxbcShaderTranslator::GetDefaultVertexShaderModification( + uint32_t dynamic_addressable_register_count, + Shader::HostVertexShaderType host_vertex_shader_type) const { + Modification shader_modification; + shader_modification.vertex.dynamic_addressable_register_count = + dynamic_addressable_register_count; + shader_modification.vertex.host_vertex_shader_type = host_vertex_shader_type; + shader_modification.vertex.interpolator_mask = (UINT32_C(1) << xenos::kMaxInterpolators) - 1; + return shader_modification.value; +} + +uint64_t DxbcShaderTranslator::GetDefaultPixelShaderModification( + uint32_t dynamic_addressable_register_count) const { + Modification shader_modification; + shader_modification.pixel.dynamic_addressable_register_count = dynamic_addressable_register_count; + shader_modification.pixel.interpolator_mask = (UINT32_C(1) << xenos::kMaxInterpolators) - 1; + shader_modification.pixel.depth_stencil_mode = Modification::DepthStencilMode::kNoModifiers; + return shader_modification.value; +} + +void DxbcShaderTranslator::Reset() { + ShaderTranslator::Reset(); + + shader_code_.clear(); + + cbuffer_count_ = 0; + // System constants always used in prologues/epilogues. + cbuffer_index_system_constants_ = cbuffer_count_++; + cbuffer_index_float_constants_ = kBindingIndexUnallocated; + cbuffer_index_bool_loop_constants_ = kBindingIndexUnallocated; + cbuffer_index_fetch_constants_ = kBindingIndexUnallocated; + cbuffer_index_descriptor_indices_ = kBindingIndexUnallocated; + + system_constants_used_ = 0; + + out_reg_vs_interpolators_ = UINT32_MAX; + out_reg_vs_position_ = UINT32_MAX; + out_reg_vs_clip_cull_distances_ = UINT32_MAX; + out_reg_vs_point_size_ = UINT32_MAX; + in_reg_ps_interpolators_ = UINT32_MAX; + in_reg_ps_point_coordinates_ = UINT32_MAX; + in_reg_ps_position_ = UINT32_MAX; + in_reg_ps_front_face_sample_index_ = UINT32_MAX; + + in_domain_location_used_ = 0; + in_control_point_index_used_ = false; + in_position_used_ = 0; + in_front_face_used_ = false; + + system_temp_count_current_ = 0; + system_temp_count_max_ = 0; + + cf_exec_bool_constant_ = kCfExecBoolConstantNone; + cf_exec_predicated_ = false; + cf_instruction_predicate_if_open_ = false; + cf_exec_predicate_written_ = false; + + srv_count_ = 0; + srv_index_shared_memory_ = kBindingIndexUnallocated; + srv_index_bindless_textures_2d_ = kBindingIndexUnallocated; + srv_index_bindless_textures_3d_ = kBindingIndexUnallocated; + srv_index_bindless_textures_cube_ = kBindingIndexUnallocated; + + texture_bindings_.clear(); + texture_bindings_for_bindful_srv_indices_.clear(); + + uav_count_ = 0; + uav_index_shared_memory_ = kBindingIndexUnallocated; + uav_index_edram_ = kBindingIndexUnallocated; + + sampler_bindings_.clear(); + + std::memset(&shader_feature_info_, 0, sizeof(shader_feature_info_)); + std::memset(&statistics_, 0, sizeof(statistics_)); +} + +uint32_t DxbcShaderTranslator::GetModificationRegisterCount() const { + Modification modification = GetDxbcShaderModification(); + return is_vertex_shader() ? modification.vertex.dynamic_addressable_register_count + : modification.pixel.dynamic_addressable_register_count; +} + +bool DxbcShaderTranslator::UseSwitchForControlFlow() const { + // Xenia crashes on Intel HD Graphics 4000 with switch. + return REXCVAR_GET(dxbc_switch) && vendor_id_ != ui::GraphicsProvider::GpuVendorID::kIntel; +} + +uint32_t DxbcShaderTranslator::PushSystemTemp(uint32_t zero_mask, uint32_t count) { + uint32_t register_index = system_temp_count_current_; + if (!is_depth_only_pixel_shader_ && !current_shader().uses_register_dynamic_addressing()) { + // Guest shader registers first if they're not in x0. Depth-only pixel + // shader is a special case of the DXBC translator usage, where there are no + // GPRs because there's no shader to translate, and a guest shader is not + // loaded. + register_index += register_count(); + } + system_temp_count_current_ += count; + system_temp_count_max_ = std::max(system_temp_count_max_, system_temp_count_current_); + zero_mask &= 0b1111; + if (zero_mask) { + for (uint32_t i = 0; i < count; ++i) { + a_.OpMov(dxbc::Dest::R(register_index + i, zero_mask), dxbc::Src::LU(0)); + } + } + return register_index; +} + +void DxbcShaderTranslator::PopSystemTemp(uint32_t count) { + assert_true(count <= system_temp_count_current_); + system_temp_count_current_ -= std::min(count, system_temp_count_current_); +} + +void DxbcShaderTranslator::PWLGammaToLinear(dxbc::Assembler& a, uint32_t target_temp, + uint32_t target_temp_component, uint32_t source_temp, + uint32_t source_temp_component, + bool source_pre_saturated, uint32_t temp1, + uint32_t temp1_component, uint32_t temp2, + uint32_t temp2_component) { + // The source is needed only once to begin building the result, so it can be + // the same as the destination. + assert_true(temp1 != target_temp || temp1_component != target_temp_component); + assert_true(temp1 != source_temp || temp1_component != source_temp_component); + assert_true(temp2 != target_temp || temp2_component != target_temp_component); + assert_true(temp2 != source_temp || temp2_component != source_temp_component); + assert_true(temp1 != temp2 || temp1_component != temp2_component); + dxbc::Dest target_dest(dxbc::Dest::R(target_temp, UINT32_C(1) << target_temp_component)); + dxbc::Src target_src(dxbc::Src::R(target_temp).Select(target_temp_component)); + dxbc::Src source_src(dxbc::Src::R(source_temp).Select(source_temp_component)); + dxbc::Dest temp1_dest(dxbc::Dest::R(temp1, UINT32_C(1) << temp1_component)); + dxbc::Src temp1_src(dxbc::Src::R(temp1).Select(temp1_component)); + dxbc::Dest temp2_dest(dxbc::Dest::R(temp2, UINT32_C(1) << temp2_component)); + dxbc::Src temp2_src(dxbc::Src::R(temp2).Select(temp2_component)); + + // Get the scale (into temp1) and the offset (into temp2) for the piece. + // Using `source >= threshold` comparisons because the input might have not + // been saturated yet, and thus it may be NaN - since it will be saturated to + // 0 later, the 0...64/255 case should be selected for it. + a.OpGE(temp2_dest, source_src, dxbc::Src::LF(96.0f / 255.0f)); + a.OpIf(true, temp2_src); + // [96/255 ... 1 + a.OpGE(temp2_dest, source_src, dxbc::Src::LF(192.0f / 255.0f)); + a.OpMovC(temp1_dest, temp2_src, dxbc::Src::LF(8.0f / 1024.0f), dxbc::Src::LF(4.0f / 1024.0f)); + a.OpMovC(temp2_dest, temp2_src, dxbc::Src::LF(-1024.0f), dxbc::Src::LF(-256.0f)); + a.OpElse(); + // 0 ... 96/255) + a.OpGE(temp2_dest, source_src, dxbc::Src::LF(64.0f / 255.0f)); + a.OpMovC(temp1_dest, temp2_src, dxbc::Src::LF(2.0f / 1024.0f), dxbc::Src::LF(1.0f / 1024.0f)); + a.OpMovC(temp2_dest, temp2_src, dxbc::Src::LF(-64.0f), dxbc::Src::LF(0.0f)); + a.OpEndIf(); + + if (!source_pre_saturated) { + // Saturate the input, and flush NaN to 0. + a.OpMov(target_dest, source_src, true); + } + // linear = gamma * (255 * 1024) * scale + offset + // As both 1024 and the scale are powers of 2, and 1024 * scale is not smaller + // than 1, it's not important if it's (gamma * 255) * 1024 * scale, + // (gamma * 255 * 1024) * scale, gamma * 255 * (1024 * scale), or + // gamma * (255 * 1024 * scale) - or the option chosen here, as long as + // 1024 is applied before the scale since the scale is < 1 (specifically at + // least 1/1024), and it may make very small values denormal. + a.OpMul(target_dest, source_pre_saturated ? source_src : target_src, + dxbc::Src::LF(255.0f * 1024.0f)); + a.OpMAd(target_dest, target_src, temp1_src, temp2_src); + // linear += trunc(linear * scale) + a.OpMul(temp1_dest, target_src, temp1_src); + a.OpRoundZ(temp1_dest, temp1_src); + a.OpAdd(target_dest, target_src, temp1_src); + // linear *= 1/1023 + a.OpMul(target_dest, target_src, dxbc::Src::LF(1.0f / 1023.0f)); +} + +void DxbcShaderTranslator::PreSaturatedLinearToPWLGamma( + dxbc::Assembler& a, uint32_t target_temp, uint32_t target_temp_component, uint32_t source_temp, + uint32_t source_temp_component, uint32_t temp_or_target, uint32_t temp_or_target_component, + uint32_t temp_non_target, uint32_t temp_non_target_component) { + // The source may be the same as the target, but in this case it can't also be + // used as a temporary variable. + assert_true(target_temp != source_temp || target_temp_component != source_temp_component || + target_temp != temp_or_target || target_temp_component != temp_or_target_component); + assert_true(temp_or_target != source_temp || temp_or_target_component != source_temp_component); + assert_true(temp_non_target != target_temp || temp_non_target_component != target_temp_component); + assert_true(temp_non_target != source_temp || temp_non_target_component != source_temp_component); + assert_true(temp_or_target != temp_non_target || + temp_or_target_component != temp_non_target_component); + dxbc::Dest target_dest(dxbc::Dest::R(target_temp, UINT32_C(1) << target_temp_component)); + dxbc::Src target_src(dxbc::Src::R(target_temp).Select(target_temp_component)); + dxbc::Src source_src(dxbc::Src::R(source_temp).Select(source_temp_component)); + dxbc::Dest temp_or_target_dest( + dxbc::Dest::R(temp_or_target, UINT32_C(1) << temp_or_target_component)); + dxbc::Src temp_or_target_src(dxbc::Src::R(temp_or_target).Select(temp_or_target_component)); + dxbc::Dest temp_non_target_dest( + dxbc::Dest::R(temp_non_target, UINT32_C(1) << temp_non_target_component)); + dxbc::Src temp_non_target_src(dxbc::Src::R(temp_non_target).Select(temp_non_target_component)); + + // Get the scale (into temp_or_target) and the offset (into temp_non_target) + // for the piece. + a.OpGE(temp_non_target_dest, source_src, dxbc::Src::LF(128.0f / 1023.0f)); + a.OpIf(true, temp_non_target_src); + // [128/1023 ... 1 + a.OpGE(temp_non_target_dest, source_src, dxbc::Src::LF(512.0f / 1023.0f)); + a.OpMovC(temp_or_target_dest, temp_non_target_src, dxbc::Src::LF(1023.0f / 8.0f), + dxbc::Src::LF(1023.0f / 4.0f)); + a.OpMovC(temp_non_target_dest, temp_non_target_src, dxbc::Src::LF(128.0f / 255.0f), + dxbc::Src::LF(64.0f / 255.0f)); + a.OpElse(); + // 0 ... 128/1023) + a.OpGE(temp_non_target_dest, source_src, dxbc::Src::LF(64.0f / 1023.0f)); + a.OpMovC(temp_or_target_dest, temp_non_target_src, dxbc::Src::LF(1023.0f / 2.0f), + dxbc::Src::LF(1023.0f)); + a.OpMovC(temp_non_target_dest, temp_non_target_src, dxbc::Src::LF(32.0f / 255.0f), + dxbc::Src::LF(0.0f)); + a.OpEndIf(); + + // gamma = trunc(linear * scale) * (1.0 / 255.0) + offset + a.OpMul(target_dest, source_src, temp_or_target_src); + a.OpRoundZ(target_dest, target_src); + a.OpMAd(target_dest, target_src, dxbc::Src::LF(1.0f / 255.0f), temp_non_target_src); +} + +void DxbcShaderTranslator::RemapAndConvertVertexIndices(uint32_t dest_temp, + uint32_t dest_temp_components, + const dxbc::Src& src) { + dxbc::Dest dest(dxbc::Dest::R(dest_temp, dest_temp_components)); + dxbc::Src dest_src(dxbc::Src::R(dest_temp)); + + // Add the base vertex index. + a_.OpIAdd(dest, src, + LoadSystemConstant(SystemConstants::Index::kVertexIndexOffset, + offsetof(SystemConstants, vertex_index_offset), dxbc::Src::kXXXX)); + + // Mask since the GPU only uses the lower 24 bits of the vertex index (tested + // on an Adreno 200 phone). `((index & 0xFFFFFF) + offset) & 0xFFFFFF` is the + // same as `(index + offset) & 0xFFFFFF`. + a_.OpAnd(dest, dest_src, dxbc::Src::LU(xenos::kVertexIndexMask)); + + // Clamp after offsetting. + a_.OpUMax(dest, dest_src, + LoadSystemConstant(SystemConstants::Index::kVertexIndexMinMax, + offsetof(SystemConstants, vertex_index_min), dxbc::Src::kXXXX)); + a_.OpUMin(dest, dest_src, + LoadSystemConstant(SystemConstants::Index::kVertexIndexMinMax, + offsetof(SystemConstants, vertex_index_max), dxbc::Src::kXXXX)); + + // Convert to float. + a_.OpUToF(dest, dest_src); +} + +void DxbcShaderTranslator::StartVertexShader_LoadVertexIndex() { + if (register_count() < 1) { + return; + } + + bool uses_register_dynamic_addressing = current_shader().uses_register_dynamic_addressing(); + + // Writing the index to X of GPR 0 - either directly if not using indexable + // registers, or via a system temporary register. + uint32_t reg; + if (uses_register_dynamic_addressing) { + reg = PushSystemTemp(); + } else { + reg = 0; + } + + dxbc::Dest index_dest(dxbc::Dest::R(reg, 0b0001)); + dxbc::Src index_src(dxbc::Src::R(reg, dxbc::Src::kXXXX)); + + // Check if the closing vertex of a non-indexed line loop is being processed. + a_.OpINE( + index_dest, dxbc::Src::V1D(kInRegisterVSVertexIndex, dxbc::Src::kXXXX), + LoadSystemConstant(SystemConstants::Index::kLineLoopClosingIndex, + offsetof(SystemConstants, line_loop_closing_index), dxbc::Src::kXXXX)); + // Zero the index if processing the closing vertex of a line loop, or do + // nothing (replace 0 with 0) if not needed. + a_.OpAnd(index_dest, dxbc::Src::V1D(kInRegisterVSVertexIndex, dxbc::Src::kXXXX), index_src); + + { + // Swap the vertex index's endianness. + dxbc::Src endian_src(LoadSystemConstant(SystemConstants::Index::kVertexIndexEndian, + offsetof(SystemConstants, vertex_index_endian), + dxbc::Src::kXXXX)); + dxbc::Dest swap_temp_dest(dxbc::Dest::R(reg, 0b0010)); + dxbc::Src swap_temp_src(dxbc::Src::R(reg, dxbc::Src::kYYYY)); + + // 8-in-16 or one half of 8-in-32. + a_.OpSwitch(endian_src); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::Endian::k8in16))); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::Endian::k8in32))); + // Temp = X0Z0. + a_.OpAnd(swap_temp_dest, index_src, dxbc::Src::LU(0x00FF00FF)); + // Index = YZW0. + a_.OpUShR(index_dest, index_src, dxbc::Src::LU(8)); + // Index = Y0W0. + a_.OpAnd(index_dest, index_src, dxbc::Src::LU(0x00FF00FF)); + // Index = YXWZ. + a_.OpUMAd(index_dest, swap_temp_src, dxbc::Src::LU(256), index_src); + a_.OpBreak(); + a_.OpEndSwitch(); + + // 16-in-32 or another half of 8-in-32. + a_.OpSwitch(endian_src); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::Endian::k8in32))); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::Endian::k16in32))); + // Temp = ZW00. + a_.OpUShR(swap_temp_dest, index_src, dxbc::Src::LU(16)); + // Index = ZWXY. + a_.OpBFI(index_dest, dxbc::Src::LU(16), dxbc::Src::LU(16), index_src, swap_temp_src); + a_.OpBreak(); + a_.OpEndSwitch(); + + if (!uses_register_dynamic_addressing) { + // Break register dependency. + a_.OpMov(swap_temp_dest, dxbc::Src::LF(0.0f)); + } + } + + // Remap the index to the needed range and convert it to floating-point. + RemapAndConvertVertexIndices(index_dest.index_1d_.index_, index_dest.write_mask_, index_src); + + if (uses_register_dynamic_addressing) { + // Store to indexed GPR 0 in x0[0]. + a_.OpMov(dxbc::Dest::X(0, 0, 0b0001), index_src); + PopSystemTemp(); + } +} + +void DxbcShaderTranslator::StartVertexOrDomainShader() { + bool uses_register_dynamic_addressing = current_shader().uses_register_dynamic_addressing(); + + // Zero general-purpose registers to prevent crashes when the game + // references them after only initializing them conditionally. + for (uint32_t i = 0; i < register_count(); ++i) { + a_.OpMov(uses_register_dynamic_addressing ? dxbc::Dest::X(0, i) : dxbc::Dest::R(i), + dxbc::Src::LF(0.0f)); + } + + // Zero the interpolators. + uint32_t interpolator_count = rex::bit_count(GetModificationInterpolatorMask()); + for (uint32_t i = 0; i < interpolator_count; ++i) { + a_.OpMov(dxbc::Dest::O(out_reg_vs_interpolators_ + i), dxbc::Src::LF(0.0f)); + } + + // Remember that x# are only accessible via mov load or store - use a + // temporary variable if need to do any computations! + Shader::HostVertexShaderType host_vertex_shader_type = + GetDxbcShaderModification().vertex.host_vertex_shader_type; + switch (host_vertex_shader_type) { + case Shader::HostVertexShaderType::kVertex: + StartVertexShader_LoadVertexIndex(); + break; + + case Shader::HostVertexShaderType::kTriangleDomainCPIndexed: + assert_true(register_count() >= 2); + if (register_count() >= 1) { + // Copy the domain location to r0.xyz. + // ZYX swizzle according to 415607E1 and 4D5307F2. + in_domain_location_used_ |= 0b0111; + a_.OpMov(uses_register_dynamic_addressing ? dxbc::Dest::X(0, 0, 0b0111) + : dxbc::Dest::R(0, 0b0111), + dxbc::Src::VDomain(0b000110)); + if (register_count() >= 2) { + // Copy the control point indices (already swapped and converted to + // float by the host vertex and hull shaders) to r1.xyz. + dxbc::Dest control_point_index_dest(uses_register_dynamic_addressing ? dxbc::Dest::X(0, 1) + : dxbc::Dest::R(1)); + in_control_point_index_used_ = true; + for (uint32_t i = 0; i < 3; ++i) { + a_.OpMov(control_point_index_dest.Mask(1 << i), + dxbc::Src::VICP(i, kInRegisterDSControlPointIndex, dxbc::Src::kXXXX)); + } + } + } + break; + + case Shader::HostVertexShaderType::kTriangleDomainPatchIndexed: + assert_true(register_count() >= 2); + if (register_count() >= 1) { + // Copy the domain location to r0.xyz. + // ZYX swizzle with r1.y == 0, according to the water shader in + // 4D5307ED. + in_domain_location_used_ |= 0b0111; + a_.OpMov(uses_register_dynamic_addressing ? dxbc::Dest::X(0, 0, 0b0111) + : dxbc::Dest::R(0, 0b0111), + dxbc::Src::VDomain(0b000110)); + if (register_count() >= 2) { + // Copy the patch index (already swapped and converted to float by the + // host vertex and hull shaders) to r1.x. + in_control_point_index_used_ = true; + a_.OpMov(uses_register_dynamic_addressing ? dxbc::Dest::X(0, 1, 0b0001) + : dxbc::Dest::R(1, 0b0001), + dxbc::Src::VICP(0, kInRegisterDSControlPointIndex, dxbc::Src::kXXXX)); + // Write the swizzle of the barycentric coordinates to r1.y. It + // appears that the tessellator offloads the reordering of coordinates + // for edges to game shaders. + // + // In 4D5307ED, the water shader multiplies the first control point's + // position by r0.z, the second CP's by r0.y, and the third CP's by + // r0.x. But before doing that it swizzles r0.xyz the following way + // depending on the value in r1.y: + // - ZXY for 1.0. + // - YZX for 2.0. + // - XZY for 4.0. + // - YXZ for 5.0. + // - ZYX for 6.0. + // Possibly, the logic here is that the value itself is the amount of + // rotation of the swizzle to the right, and 1 << 2 is set when the + // swizzle needs to be flipped before rotating. + // + // Direct3D 12 passes the coordinates in a consistent order, so can + // just use the identity swizzle. + a_.OpMov(uses_register_dynamic_addressing ? dxbc::Dest::X(0, 1, 0b0010) + : dxbc::Dest::R(1, 0b0010), + dxbc::Src::LF(0.0f)); + } + } + break; + + case Shader::HostVertexShaderType::kQuadDomainCPIndexed: + assert_true(register_count() >= 2); + if (register_count() >= 1) { + // Copy the domain location to r0.xy. + in_domain_location_used_ |= 0b0011; + a_.OpMov(uses_register_dynamic_addressing ? dxbc::Dest::X(0, 0, 0b0011) + : dxbc::Dest::R(0, 0b0011), + dxbc::Src::VDomain()); + // Control point indices according the main menu of 58410823, with + // `cndeq r2, c255.xxxy, r1.xyzz, r0.zzzz` in the prologue of the + // shader, where c255.x is 0, and c255.y is 1. + // r0.z for (1 - r0.x) * (1 - r0.y) + // r1.x for r0.x * (1 - r0.y) + // r1.y for r0.x * r0.y + // r1.z for (1 - r0.x) * r0.y + in_control_point_index_used_ = true; + a_.OpMov(uses_register_dynamic_addressing ? dxbc::Dest::X(0, 0, 0b0100) + : dxbc::Dest::R(0, 0b0100), + dxbc::Src::VICP(0, kInRegisterDSControlPointIndex, dxbc::Src::kXXXX)); + if (register_count() >= 2) { + dxbc::Dest r1_dest(uses_register_dynamic_addressing ? dxbc::Dest::X(0, 1) + : dxbc::Dest::R(1)); + for (uint32_t i = 0; i < 3; ++i) { + a_.OpMov(r1_dest.Mask(1 << i), + dxbc::Src::VICP(1 + i, kInRegisterDSControlPointIndex, dxbc::Src::kXXXX)); + } + } + } + break; + + case Shader::HostVertexShaderType::kQuadDomainPatchIndexed: + assert_true(register_count() >= 2); + if (register_count() >= 1) { + // Copy the domain location to r0.yz. + // XY swizzle according to the ground shader in 4D5307F2. + in_domain_location_used_ |= 0b0011; + a_.OpMov(uses_register_dynamic_addressing ? dxbc::Dest::X(0, 0, 0b0110) + : dxbc::Dest::R(0, 0b0110), + dxbc::Src::VDomain(0b010000)); + // Copy the patch index (already swapped and converted to float by the + // host vertex and hull shaders) to r0.x. + in_control_point_index_used_ = true; + a_.OpMov(uses_register_dynamic_addressing ? dxbc::Dest::X(0, 0, 0b0001) + : dxbc::Dest::R(0, 0b0001), + dxbc::Src::VICP(0, kInRegisterDSControlPointIndex, dxbc::Src::kXXXX)); + if (register_count() >= 2) { + // Write the swizzle of the UV coordinates to r1.x. It appears that + // the tessellator offloads the reordering of coordinates for edges to + // game shaders. + // + // In 4D5307F2, if we assume that r0.y is U and r0.z is V, the factors + // each control point value is multiplied by are the following: + // - (1-u)*(1-v), u*(1-v), (1-u)*v, u*v for 0.0 (identity swizzle). + // - u*(1-v), (1-u)*(1-v), u*v, (1-u)*v for 1.0 (YXWZ). + // - u*v, (1-u)*v, u*(1-v), (1-u)*(1-v) for 2.0 (WZYX). + // - (1-u)*v, u*v, (1-u)*(1-v), u*(1-v) for 3.0 (ZWXY). + // + // Direct3D 12 passes the coordinates in a consistent order, so can + // just use the identity swizzle. + a_.OpMov(uses_register_dynamic_addressing ? dxbc::Dest::X(0, 1, 0b0001) + : dxbc::Dest::R(1, 0b0001), + dxbc::Src::LF(0.0f)); + } + } + break; + + default: + // TODO(Triang3l): Support line and non-adaptive quad patches. + assert_unhandled_case(host_vertex_shader_type); + EmitTranslationError("Unsupported host vertex shader type in StartVertexOrDomainShader"); + break; + } +} + +void DxbcShaderTranslator::StartPixelShader() { + if (edram_rov_used_) { + // Load the EDRAM addresses and the coverage. + StartPixelShader_LoadROVParameters(); + + if (ROV_IsDepthStencilEarly()) { + // Do early 2x2 quad rejection if it's safe. + ROV_DepthStencilTest(); + } else { + if (!current_shader().writes_depth()) { + // Get the derivatives of the screen-space (but not clamped to the + // viewport depth bounds yet - this happens after the pixel shader in + // Direct3D 11+; also linear within the triangle - thus constant + // derivatives along the triangle) Z for calculating per-sample depth + // values and the slope-scaled polygon offset to + // system_temp_depth_stencil_ before any return statement is possibly + // reached. + assert_true(system_temp_depth_stencil_ != UINT32_MAX); + dxbc::Src in_position_z(dxbc::Src::V1D(in_reg_ps_position_, dxbc::Src::kZZZZ)); + in_position_used_ |= 0b0100; + a_.OpDerivRTXCoarse(dxbc::Dest::R(system_temp_depth_stencil_, 0b0001), in_position_z); + a_.OpDerivRTYCoarse(dxbc::Dest::R(system_temp_depth_stencil_, 0b0010), in_position_z); + } + } + } + + // If not translating anything, we only need the depth. + if (is_depth_only_pixel_shader_) { + return; + } + + bool uses_register_dynamic_addressing = current_shader().uses_register_dynamic_addressing(); + Modification shader_modification = GetDxbcShaderModification(); + + // param_gen_interpolator is already 4 bits, no need for an interpolator count + // safety check. + uint32_t param_gen_interpolator = + (shader_modification.pixel.param_gen_enable && + shader_modification.pixel.param_gen_interpolator < register_count()) + ? shader_modification.pixel.param_gen_interpolator + : UINT32_MAX; + + // Zero general-purpose registers to prevent crashes when the game + // references them after only initializing them conditionally, and copy + // interpolants to GPRs. + uint32_t interpolator_mask = GetModificationInterpolatorMask(); + for (uint32_t i = 0; i < register_count(); ++i) { + if (i == param_gen_interpolator) { + continue; + } + a_.OpMov(uses_register_dynamic_addressing ? dxbc::Dest::X(0, i) : dxbc::Dest::R(i), + (i < xenos::kMaxInterpolators && (interpolator_mask & (UINT32_C(1) << i))) + ? dxbc::Src::V1D(in_reg_ps_interpolators_ + + rex::bit_count(interpolator_mask & ((UINT32_C(1) << i) - 1))) + : dxbc::Src::LF(0.0f)); + } + + // Write the pixel parameters to the specified interpolator register + // (PsParamGen). The negate modified in DXBC flips the sign bit, so it can be + // used to write the flags. + if (param_gen_interpolator != UINT32_MAX) { + uint32_t param_gen_temp = + uses_register_dynamic_addressing ? PushSystemTemp() : param_gen_interpolator; + // X - pixel X .0 in the magnitude, is back-facing in the sign bit. + // Y - pixel Y .0 in the magnitude, is point in the sign bit. + // Pixel position. + // Get the XY address of the current host pixel as float (no matter whether + // the position is pixel-rate or sample-rate also due to float24 depth + // conversion requirements, it will be rounded the same). Rounding down, and + // taking the absolute value (because the sign bit of X stores the + // faceness), so in case the host GPU for some reason has quads used for + // derivative calculation at odd locations, the left and top edges will have + // correct derivative magnitude and LODs. + in_position_used_ |= 0b0011; + a_.OpRoundNI(dxbc::Dest::R(param_gen_temp, 0b0011), dxbc::Src::V1D(in_reg_ps_position_)); + uint32_t resolution_scaled_axes = + uint32_t(draw_resolution_scale_x_ > 1) | (uint32_t(draw_resolution_scale_y_ > 1) << 1); + if (resolution_scaled_axes) { + // Revert resolution scale - after truncating, so if the pixel position + // is passed to tfetch (assuming the game doesn't round it by itself), + // it will be sampled with higher resolution too. + a_.OpMul(dxbc::Dest::R(param_gen_temp, resolution_scaled_axes), dxbc::Src::R(param_gen_temp), + dxbc::Src::LF(1.0f / draw_resolution_scale_x_, 1.0f / draw_resolution_scale_y_, 1.0f, + 1.0f)); + } + if (shader_modification.pixel.param_gen_point) { + // A point - always front-facing (the upper bit of X is 0), not a line + // (the upper bit of Z is 0). + // Take the absolute value of the position and apply the point flag. + a_.OpMov(dxbc::Dest::R(param_gen_temp, 0b0001), + dxbc::Src::R(param_gen_temp, dxbc::Src::kXXXX).Abs()); + a_.OpMov(dxbc::Dest::R(param_gen_temp, 0b0010), + -(dxbc::Src::R(param_gen_temp, dxbc::Src::kYYYY).Abs())); + // ZW - point sprite coordinates. + // Saturate to avoid negative point coordinates if the center of the pixel + // is not covered, and extrapolation is done. + assert_true(in_reg_ps_point_coordinates_ != UINT32_MAX); + a_.OpMov(dxbc::Dest::R(param_gen_temp, 0b1100), + dxbc::Src::V1D(in_reg_ps_point_coordinates_, 0b0100 << 4), true); + } else { + // Take the absolute value of the position and apply the point flag. + a_.OpMov(dxbc::Dest::R(param_gen_temp, 0b0011), dxbc::Src::R(param_gen_temp).Abs()); + // Faceness. + // Check if faceness applies to the current primitive type. + // Using Z as a temporary (not written yet). + a_.OpAnd(dxbc::Dest::R(param_gen_temp, 0b0100), LoadFlagsSystemConstant(), + dxbc::Src::LU(kSysFlag_PrimitivePolygonal)); + a_.OpIf(true, dxbc::Src::R(param_gen_temp, dxbc::Src::kZZZZ)); + { + // Negate modifier flips the sign bit even for 0 - set it to minus for + // backfaces. + in_front_face_used_ = true; + a_.OpMovC(dxbc::Dest::R(param_gen_temp, 0b0001), + dxbc::Src::V1D(in_reg_ps_front_face_sample_index_, dxbc::Src::kXXXX), + dxbc::Src::R(param_gen_temp, dxbc::Src::kXXXX), + -dxbc::Src::R(param_gen_temp, dxbc::Src::kXXXX)); + } + a_.OpEndIf(); + // No point coordinates. + // Z - is line in the sign bit. + // W - nothing. + a_.OpUBFE(dxbc::Dest::R(param_gen_temp, 0b0100), dxbc::Src::LU(1), + dxbc::Src::LU(kSysFlag_PrimitiveLine_Shift), LoadFlagsSystemConstant()); + a_.OpIShL(dxbc::Dest::R(param_gen_temp, 0b0100), + dxbc::Src::R(param_gen_temp, dxbc::Src::kZZZZ), dxbc::Src::LU(31)); + a_.OpMov(dxbc::Dest::R(param_gen_temp, 0b1000), dxbc::Src::LF(0.0f)); + } + // With dynamic register addressing, write the PsParamGen to the GPR. + if (uses_register_dynamic_addressing) { + a_.OpMov(dxbc::Dest::X(0, param_gen_interpolator), dxbc::Src::R(param_gen_temp)); + // Release param_gen_temp. + PopSystemTemp(); + } + } + + if (current_shader().memexport_eM_written()) { + // Make sure memexport is done only once for a guest pixel. + dxbc::Dest memexport_enabled_dest( + dxbc::Dest::R(system_temp_memexport_enabled_and_eM_written_, 0b0001)); + dxbc::Src memexport_enabled_src( + dxbc::Src::R(system_temp_memexport_enabled_and_eM_written_, dxbc::Src::kXXXX)); + uint32_t resolution_scaled_axes = + uint32_t(draw_resolution_scale_x_ > 1) | (uint32_t(draw_resolution_scale_y_ > 1) << 1); + if (resolution_scaled_axes) { + uint32_t memexport_condition_temp = PushSystemTemp(); + // Only do memexport for one host pixel in a guest pixel - prefer the + // host pixel closer to the center of the guest pixel, but one that's + // covered with the half-pixel offset according to the top-left rule (1 + // for 2x because 0 isn't covered with the half-pixel offset, 1 for 3x + // because it's the center and is covered with the half-pixel offset too). + in_position_used_ |= resolution_scaled_axes; + a_.OpFToU(dxbc::Dest::R(memexport_condition_temp, resolution_scaled_axes), + dxbc::Src::V1D(in_reg_ps_position_)); + a_.OpUDiv(dxbc::Dest::Null(), dxbc::Dest::R(memexport_condition_temp, resolution_scaled_axes), + dxbc::Src::R(memexport_condition_temp), + dxbc::Src::LU(draw_resolution_scale_x_, draw_resolution_scale_y_, 0, 0)); + a_.OpIEq(dxbc::Dest::R(memexport_condition_temp, resolution_scaled_axes), + dxbc::Src::R(memexport_condition_temp), + dxbc::Src::LU(draw_resolution_scale_x_ >> 1, draw_resolution_scale_y_ >> 1, 0, 0)); + for (uint32_t i = 0; i < 2; ++i) { + if (!(resolution_scaled_axes & (1 << i))) { + continue; + } + a_.OpAnd(memexport_enabled_dest, memexport_enabled_src, + dxbc::Src::R(memexport_condition_temp).Select(i)); + } + // Release memexport_condition_temp. + PopSystemTemp(); + } + // With sample-rate shading (with float24 conversion), only do memexport + // from one sample (as the shader is invoked multiple times for a pixel), + // if SV_SampleIndex == firstbit_lo(SV_Coverage). For zero coverage, + // firstbit_lo returns 0xFFFFFFFF. + if (IsSampleRate()) { + uint32_t memexport_condition_temp = PushSystemTemp(); + a_.OpFirstBitLo(dxbc::Dest::R(memexport_condition_temp, 0b0001), dxbc::Src::VCoverage()); + a_.OpIEq(dxbc::Dest::R(memexport_condition_temp, 0b0001), + dxbc::Src::V1D(in_reg_ps_front_face_sample_index_, dxbc::Src::kYYYY), + dxbc::Src::R(memexport_condition_temp, dxbc::Src::kXXXX)); + a_.OpAnd(memexport_enabled_dest, memexport_enabled_src, + dxbc::Src::R(memexport_condition_temp, dxbc::Src::kXXXX)); + // Release memexport_condition_temp. + PopSystemTemp(); + } + } +} + +void DxbcShaderTranslator::StartTranslation() { + // Set up the input and output registers. + Modification shader_modification = GetDxbcShaderModification(); + uint32_t interpolator_register_mask = GetModificationInterpolatorMask(); + uint32_t interpolator_register_count = rex::bit_count(interpolator_register_mask); + if (is_vertex_shader()) { + uint32_t out_reg_index = 0; + // Interpolators. + if (interpolator_register_count) { + out_reg_vs_interpolators_ = out_reg_index; + out_reg_index += interpolator_register_count; + } + // Position. + out_reg_vs_position_ = out_reg_index; + ++out_reg_index; + // Clip and cull distances. + uint32_t clip_and_cull_distance_count = shader_modification.GetVertexClipDistanceCount() + + shader_modification.GetVertexCullDistanceCount(); + if (clip_and_cull_distance_count) { + out_reg_vs_clip_cull_distances_ = out_reg_index; + out_reg_index += (clip_and_cull_distance_count + 3) >> 2; + } + // Point size. + if (shader_modification.vertex.output_point_size) { + out_reg_vs_point_size_ = out_reg_index; + ++out_reg_index; + } + } else if (is_pixel_shader()) { + uint32_t in_reg_index = 0; + // Interpolators. + if (interpolator_register_count) { + in_reg_ps_interpolators_ = in_reg_index; + in_reg_index += interpolator_register_count; + } + // Point coordinates. + if (shader_modification.pixel.param_gen_point) { + in_reg_ps_point_coordinates_ = in_reg_index; + ++in_reg_index; + } + // Position. + in_reg_ps_position_ = in_reg_index; + ++in_reg_index; + // System inputs. + in_reg_ps_front_face_sample_index_ = in_reg_index; + ++in_reg_index; + } + + // Allocate global system temporary registers that may also be used in the + // epilogue. + if (is_vertex_shader()) { + system_temp_position_ = PushSystemTemp(0b1111); + system_temp_point_size_edge_flag_kill_vertex_ = PushSystemTemp(0b0100); + // Set the point size to a negative value to tell the geometry shader that + // it should use the default point size if the vertex shader does not + // override it. + a_.OpMov(dxbc::Dest::R(system_temp_point_size_edge_flag_kill_vertex_, 0b0001), + dxbc::Src::LF(-1.0f)); + } else if (is_pixel_shader()) { + if (edram_rov_used_) { + // Will be initialized unconditionally. + system_temp_rov_params_ = PushSystemTemp(); + } + if (IsDepthStencilSystemTempUsed()) { + uint32_t depth_stencil_temp_zero_mask; + if (current_shader().writes_depth()) { + // X holds the guest oDepth - make sure it's always initialized because + // assumptions can't be made about the integrity of the guest code. + depth_stencil_temp_zero_mask = 0b0001; + } else { + assert_true(edram_rov_used_); + if (ROV_IsDepthStencilEarly()) { + // XYZW hold per-sample depth / stencil after the early test - written + // conditionally based on the coverage, ensure registers are + // initialized unconditionally for safety. + depth_stencil_temp_zero_mask = 0b1111; + } else { + // XY hold Z gradients, written unconditionally in the beginning. + depth_stencil_temp_zero_mask = 0b0000; + } + } + system_temp_depth_stencil_ = PushSystemTemp(depth_stencil_temp_zero_mask); + } + uint32_t shader_writes_color_targets = current_shader().writes_color_targets(); + for (uint32_t i = 0; i < 4; ++i) { + if (shader_writes_color_targets & (1 << i)) { + system_temps_color_[i] = PushSystemTemp(0b1111); + } + } + } + + // Allocate temporary registers for memexport. + uint8_t memexport_eM_written = current_shader().memexport_eM_written(); + if (memexport_eM_written) { + system_temp_memexport_enabled_and_eM_written_ = PushSystemTemp(0b0010); + // Initialize the memexport conditional to whether the shared memory is + // currently bound as UAV (to 0 or UINT32_MAX). It can be made narrower + // later. + a_.OpIBFE(dxbc::Dest::R(system_temp_memexport_enabled_and_eM_written_, 0b0001), + dxbc::Src::LU(1), dxbc::Src::LU(kSysFlag_SharedMemoryIsUAV_Shift), + LoadFlagsSystemConstant()); + system_temp_memexport_address_ = PushSystemTemp(0b1111); + uint8_t memexport_eM_remaining = memexport_eM_written; + uint32_t memexport_eM_index; + while (rex::bit_scan_forward(memexport_eM_remaining, &memexport_eM_index)) { + memexport_eM_remaining &= ~(uint8_t(1) << memexport_eM_index); + system_temps_memexport_data_[memexport_eM_index] = PushSystemTemp(0b1111); + } + } + + if (!is_depth_only_pixel_shader_) { + // Allocate system temporary variables for the translated code. Since access + // depends on the guest code (thus no guarantees), initialize everything + // now (except for pv, it's an internal temporary variable, not accessible + // by the guest). + system_temp_result_ = PushSystemTemp(); + system_temp_ps_pc_p0_a0_ = PushSystemTemp(0b1111); + system_temp_aL_ = PushSystemTemp(0b1111); + system_temp_loop_count_ = PushSystemTemp(0b1111); + system_temp_grad_h_lod_ = PushSystemTemp(0b1111); + system_temp_grad_v_vfetch_address_ = PushSystemTemp(0b1111); + } + + // Write stage-specific prologue. + if (is_vertex_shader()) { + StartVertexOrDomainShader(); + } else if (is_pixel_shader()) { + StartPixelShader(); + } + + // If not translating anything, don't start the main loop. + if (is_depth_only_pixel_shader_) { + return; + } + + // Start the main loop (for jumping to labels by setting pc and continuing). + a_.OpLoop(); + // Switch and the first label (pc == 0). + if (UseSwitchForControlFlow()) { + a_.OpSwitch(dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kYYYY)); + a_.OpCase(dxbc::Src::LU(0)); + } else { + a_.OpIf(false, dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kYYYY)); + } +} + +void DxbcShaderTranslator::CompleteVertexOrDomainShader() { + uint32_t temp = PushSystemTemp(); + dxbc::Dest temp_x_dest(dxbc::Dest::R(temp, 0b0001)); + dxbc::Src temp_x_src(dxbc::Src::R(temp, dxbc::Src::kXXXX)); + + dxbc::Src flags_src(LoadFlagsSystemConstant()); + + // Check if the shader already returns W, not 1/W, and if it doesn't, turn 1/W + // into W. Using div rather than relaxed-precision rcp for safety. + a_.OpAnd(temp_x_dest, flags_src, dxbc::Src::LU(kSysFlag_WNotReciprocal)); + a_.OpIf(false, temp_x_src); + a_.OpDiv(dxbc::Dest::R(system_temp_position_, 0b1000), dxbc::Src::LF(1.0f), + dxbc::Src::R(system_temp_position_, dxbc::Src::kWWWW)); + a_.OpEndIf(); + + // Check if the shader returns XY/W rather than XY, and if it does, revert + // that. + a_.OpAnd(temp_x_dest, flags_src, dxbc::Src::LU(kSysFlag_XYDividedByW)); + a_.OpIf(true, temp_x_src); + a_.OpMul(dxbc::Dest::R(system_temp_position_, 0b0011), dxbc::Src::R(system_temp_position_), + dxbc::Src::R(system_temp_position_, dxbc::Src::kWWWW)); + a_.OpEndIf(); + + // Check if the shader returns Z/W rather than Z, and if it does, revert that. + a_.OpAnd(temp_x_dest, flags_src, dxbc::Src::LU(kSysFlag_ZDividedByW)); + a_.OpIf(true, temp_x_src); + a_.OpMul(dxbc::Dest::R(system_temp_position_, 0b0100), + dxbc::Src::R(system_temp_position_, dxbc::Src::kZZZZ), + dxbc::Src::R(system_temp_position_, dxbc::Src::kWWWW)); + a_.OpEndIf(); + + Modification shader_modification = GetDxbcShaderModification(); + uint32_t clip_distance_next_component = 0; + uint32_t cull_distance_next_component = shader_modification.GetVertexClipDistanceCount(); + + // Clip against user clip planes. + uint32_t& ucp_clip_cull_distance_next_component_ref = + shader_modification.vertex.user_clip_plane_cull ? cull_distance_next_component + : clip_distance_next_component; + for (uint32_t i = 0; i < shader_modification.vertex.user_clip_plane_count; ++i) { + a_.OpDP4(dxbc::Dest::O( + out_reg_vs_clip_cull_distances_ + (ucp_clip_cull_distance_next_component_ref >> 2), + UINT32_C(1) << (ucp_clip_cull_distance_next_component_ref & 3)), + dxbc::Src::R(system_temp_position_), + LoadSystemConstant(SystemConstants::Index::kUserClipPlanes, + offsetof(SystemConstants, user_clip_planes) + sizeof(float) * 4 * i, + dxbc::Src::kXYZW)); + ++ucp_clip_cull_distance_next_component_ref; + } + + // Apply scale for guest to host viewport and clip space conversion. Also, if + // the vertex shader is multipass, the NDC scale constant can be used to set + // position to NaN to kill all primitives. + a_.OpMul(dxbc::Dest::R(system_temp_position_, 0b0111), dxbc::Src::R(system_temp_position_), + LoadSystemConstant(SystemConstants::Index::kNDCScale, + offsetof(SystemConstants, ndc_scale), 0b100100)); + + // Apply offset (multiplied by W) used for the same purposes. + a_.OpMAd(dxbc::Dest::R(system_temp_position_, 0b0111), + LoadSystemConstant(SystemConstants::Index::kNDCOffset, + offsetof(SystemConstants, ndc_offset), 0b100100), + dxbc::Src::R(system_temp_position_, dxbc::Src::kWWWW), + dxbc::Src::R(system_temp_position_)); + + // Kill the primitive if needed - check if the shader wants to kill (bits + // 0:30 of the vertex kill register are not zero - using `and`, not abs or + // especially 0.0f comparison, to avoid potential denormal flushing). + bool shader_writes_vertex_kill = + (current_shader().writes_point_size_edge_flag_kill_vertex() & 0b100) != 0; + if (shader_writes_vertex_kill) { + a_.OpAnd(temp_x_dest, + dxbc::Src::R(system_temp_point_size_edge_flag_kill_vertex_, dxbc::Src::kZZZZ), + dxbc::Src::LU(UINT32_C(0x7FFFFFFF))); + } + if (shader_modification.vertex.vertex_kill_and) { + // AND operator - write an SV_CullDistance. + dxbc::Dest vertex_kill_dest( + dxbc::Dest::O(out_reg_vs_clip_cull_distances_ + (cull_distance_next_component >> 2), + UINT32_C(1) << (cull_distance_next_component & 3))); + if (shader_writes_vertex_kill) { + a_.OpMovC(vertex_kill_dest, temp_x_src, dxbc::Src::LF(-1.0f), dxbc::Src::LF(0.0f)); + } else { + a_.OpMov(vertex_kill_dest, dxbc::Src::LF(0.0f)); + } + ++cull_distance_next_component; + } else { + // OR operator - set the position to NaN. + if (shader_writes_vertex_kill) { + a_.OpMovC(dxbc::Dest::R(system_temp_position_, 0b1000), temp_x_src, + dxbc::Src::LF(std::nanf("")), + dxbc::Src::R(system_temp_position_, dxbc::Src::kWWWW)); + } + } + + // Write the position to the output. + a_.OpMov(dxbc::Dest::O(out_reg_vs_position_), dxbc::Src::R(system_temp_position_)); + + // Write the point size. + if (out_reg_vs_point_size_ != UINT32_MAX) { + a_.OpMov(dxbc::Dest::O(out_reg_vs_point_size_, 0b0001), + dxbc::Src::R(system_temp_point_size_edge_flag_kill_vertex_, dxbc::Src::kXXXX)); + } + + // Release temp. + PopSystemTemp(); +} + +void DxbcShaderTranslator::CompleteShaderCode() { + if (!is_depth_only_pixel_shader_) { + // Close the last exec, there's nothing to merge it with anymore, and we're + // closing upper-level flow control blocks. + CloseExecConditionals(); + // Close the last label and the switch. + if (UseSwitchForControlFlow()) { + a_.OpBreak(); + a_.OpEndSwitch(); + } else { + a_.OpEndIf(); + } + // End the main loop. + a_.OpBreak(); + a_.OpEndLoop(); + + // Release the following system temporary values so epilogue can reuse them: + // - system_temp_result_. + // - system_temp_ps_pc_p0_a0_. + // - system_temp_aL_. + // - system_temp_loop_count_. + // - system_temp_grad_h_lod_. + // - system_temp_grad_v_vfetch_address_. + PopSystemTemp(6); + } + + uint8_t memexport_eM_written = current_shader().memexport_eM_written(); + if (memexport_eM_written) { + // Write data for the last memexport. + ExportToMemory(current_shader().memexport_eM_potentially_written_before_end()); + + // Release memexport temporary registers: + // - system_temp_memexport_enabled_and_eM_written_. + // - system_temp_memexport_address_. + // - system_temps_memexport_data_. + PopSystemTemp(rex::bit_count(uint32_t(memexport_eM_written)) + 2); + } + + // Write stage-specific epilogue. + if (is_vertex_shader()) { + CompleteVertexOrDomainShader(); + } else if (is_pixel_shader()) { + CompletePixelShader(); + } + + // Return from `main`. + a_.OpRet(); + + if (is_vertex_shader()) { + // Release system_temp_position_ and + // system_temp_point_size_edge_flag_kill_vertex_. + PopSystemTemp(2); + } else if (is_pixel_shader()) { + // Release system_temps_color_. + uint32_t shader_writes_color_targets = current_shader().writes_color_targets(); + for (int32_t i = 3; i >= 0; --i) { + if (shader_writes_color_targets & (1 << i)) { + PopSystemTemp(); + } + } + if (IsDepthStencilSystemTempUsed()) { + // Release system_temp_depth_stencil_. + PopSystemTemp(); + } + if (edram_rov_used_) { + // Release system_temp_rov_params_. + PopSystemTemp(); + } + } +} + +std::vector DxbcShaderTranslator::CompleteTranslation() { + // Because of shader_object_.resize(), pointers can't be kept persistently + // here! Resizing also zeroes the memory. + + // Write the code epilogue. + CompleteShaderCode(); + + shader_object_.clear(); + + // 6 or 7 blobs - RDEF, ISGN, optionally PCSG, OSGN, SHEX, SFI0, STAT. + // Whether SFI0 is needed at this point is not known, always writing it. + uint32_t blob_count = 6 + uint32_t(IsDxbcDomainShader()); + // Allocate space for the header and the blob offsets. + shader_object_.resize(sizeof(dxbc::ContainerHeader) / sizeof(uint32_t) + blob_count); + + uint32_t blob_offset_position_dwords = sizeof(dxbc::ContainerHeader) / sizeof(uint32_t); + uint32_t blob_position_dwords = uint32_t(shader_object_.size()); + constexpr uint32_t kBlobHeaderSizeDwords = sizeof(dxbc::BlobHeader) / sizeof(uint32_t); + + // Resource definition. + shader_object_[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + shader_object_.resize(blob_position_dwords + kBlobHeaderSizeDwords); + WriteResourceDefinition(); + { + auto& blob_header = + *reinterpret_cast(shader_object_.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kResourceDefinition; + blob_position_dwords = uint32_t(shader_object_.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + shader_object_[blob_offset_position_dwords++]; + } + + // Input signature. + shader_object_[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + shader_object_.resize(blob_position_dwords + kBlobHeaderSizeDwords); + WriteInputSignature(); + { + auto& blob_header = + *reinterpret_cast(shader_object_.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kInputSignature; + blob_position_dwords = uint32_t(shader_object_.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + shader_object_[blob_offset_position_dwords++]; + } + + // Patch constant signature. + if (IsDxbcDomainShader()) { + shader_object_[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + shader_object_.resize(blob_position_dwords + kBlobHeaderSizeDwords); + WritePatchConstantSignature(); + { + auto& blob_header = + *reinterpret_cast(shader_object_.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kPatchConstantSignature; + blob_position_dwords = uint32_t(shader_object_.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + shader_object_[blob_offset_position_dwords++]; + } + } + + // Output signature. + shader_object_[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + shader_object_.resize(blob_position_dwords + kBlobHeaderSizeDwords); + WriteOutputSignature(); + { + auto& blob_header = + *reinterpret_cast(shader_object_.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kOutputSignature; + blob_position_dwords = uint32_t(shader_object_.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + shader_object_[blob_offset_position_dwords++]; + } + + // Shader program. + shader_object_[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + shader_object_.resize(blob_position_dwords + kBlobHeaderSizeDwords); + WriteShaderCode(); + { + auto& blob_header = + *reinterpret_cast(shader_object_.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kShaderEx; + blob_position_dwords = uint32_t(shader_object_.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + shader_object_[blob_offset_position_dwords++]; + } + + // Shader feature info. + shader_object_[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + shader_object_.resize(blob_position_dwords + kBlobHeaderSizeDwords + + sizeof(dxbc::ShaderFeatureInfo) / sizeof(uint32_t)); + std::memcpy(shader_object_.data() + blob_position_dwords + kBlobHeaderSizeDwords, + &shader_feature_info_, sizeof(shader_feature_info_)); + { + auto& blob_header = + *reinterpret_cast(shader_object_.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kShaderFeatureInfo; + blob_position_dwords = uint32_t(shader_object_.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + shader_object_[blob_offset_position_dwords++]; + } + + // Statistics. + shader_object_[blob_offset_position_dwords] = uint32_t(blob_position_dwords * sizeof(uint32_t)); + shader_object_.resize(blob_position_dwords + kBlobHeaderSizeDwords + + sizeof(dxbc::Statistics) / sizeof(uint32_t)); + std::memcpy(shader_object_.data() + blob_position_dwords + kBlobHeaderSizeDwords, &statistics_, + sizeof(statistics_)); + { + auto& blob_header = + *reinterpret_cast(shader_object_.data() + blob_position_dwords); + blob_header.fourcc = dxbc::BlobHeader::FourCC::kStatistics; + blob_position_dwords = uint32_t(shader_object_.size()); + blob_header.size_bytes = (blob_position_dwords - kBlobHeaderSizeDwords) * sizeof(uint32_t) - + shader_object_[blob_offset_position_dwords++]; + } + + // Header. + uint32_t shader_object_size_bytes = uint32_t(shader_object_.size() * sizeof(uint32_t)); + { + auto& container_header = *reinterpret_cast(shader_object_.data()); + container_header.InitializeIdentification(); + container_header.size_bytes = shader_object_size_bytes; + container_header.blob_count = blob_count; + CalculateDXBCChecksum(reinterpret_cast(shader_object_.data()), + static_cast(shader_object_size_bytes), + reinterpret_cast(&container_header.hash)); + } + + // TODO(Triang3l): Avoid copy? + std::vector shader_object_bytes; + shader_object_bytes.resize(shader_object_size_bytes); + std::memcpy(shader_object_bytes.data(), shader_object_.data(), shader_object_size_bytes); + return shader_object_bytes; +} + +void DxbcShaderTranslator::PostTranslation() { + Shader::Translation& translation = current_translation(); + if (!translation.is_valid()) { + return; + } + DxbcShader* dxbc_shader = dynamic_cast(&translation.shader()); + if (dxbc_shader && + !dxbc_shader->bindings_setup_entered_.test_and_set(std::memory_order_relaxed)) { + dxbc_shader->texture_bindings_.clear(); + dxbc_shader->texture_bindings_.reserve(texture_bindings_.size()); + dxbc_shader->used_texture_mask_ = 0; + for (const TextureBinding& translator_binding : texture_bindings_) { + DxbcShader::TextureBinding& shader_binding = dxbc_shader->texture_bindings_.emplace_back(); + // For a stable hash. + std::memset(&shader_binding, 0, sizeof(shader_binding)); + shader_binding.bindless_descriptor_index = translator_binding.bindless_descriptor_index; + shader_binding.fetch_constant = translator_binding.fetch_constant; + shader_binding.dimension = translator_binding.dimension; + shader_binding.is_signed = translator_binding.is_signed; + dxbc_shader->used_texture_mask_ |= 1u << translator_binding.fetch_constant; + } + dxbc_shader->sampler_bindings_.clear(); + dxbc_shader->sampler_bindings_.reserve(sampler_bindings_.size()); + for (const SamplerBinding& translator_binding : sampler_bindings_) { + DxbcShader::SamplerBinding& shader_binding = dxbc_shader->sampler_bindings_.emplace_back(); + shader_binding.bindless_descriptor_index = translator_binding.bindless_descriptor_index; + shader_binding.fetch_constant = translator_binding.fetch_constant; + shader_binding.mag_filter = translator_binding.mag_filter; + shader_binding.min_filter = translator_binding.min_filter; + shader_binding.mip_filter = translator_binding.mip_filter; + shader_binding.aniso_filter = translator_binding.aniso_filter; + } + } +} + +void DxbcShaderTranslator::EmitInstructionDisassembly() { + if (!emit_source_map_) { + return; + } + const char* source = instruction_disassembly_buffer_.buffer(); + uint32_t length = uint32_t(instruction_disassembly_buffer_.length()); + // Trim leading spaces and trailing new line. + while (length != 0 && source[0] == ' ') { + ++source; + --length; + } + while (length != 0 && source[length - 1] == '\n') { + --length; + } + if (length == 0) { + return; + } + char* dest = + reinterpret_cast(a_.OpCustomData(dxbc::CustomDataClass::kComment, length + 1)); + std::memcpy(dest, source, length); + dest[length] = '\0'; +} + +dxbc::Src DxbcShaderTranslator::LoadOperand(const InstructionOperand& operand, + uint32_t needed_components, bool& temp_pushed_out) { + temp_pushed_out = false; + + uint32_t first_needed_component; + if (!rex::bit_scan_forward(needed_components, &first_needed_component)) { + return dxbc::Src::LF(0.0f); + } + + dxbc::Index index(operand.storage_index); + switch (operand.storage_addressing_mode) { + case InstructionStorageAddressingMode::kAbsolute: + break; + case InstructionStorageAddressingMode::kAddressRegisterRelative: + index = dxbc::Index(system_temp_ps_pc_p0_a0_, 3, operand.storage_index); + break; + case InstructionStorageAddressingMode::kLoopRelative: + index = dxbc::Index(system_temp_aL_, 0, operand.storage_index); + break; + } + + dxbc::Src src(dxbc::Src::LF(0.0f)); + switch (operand.storage_source) { + case InstructionStorageSource::kRegister: { + if (current_shader().uses_register_dynamic_addressing()) { + // Load x#[#] to r# because x#[#] can be used only with mov. + uint32_t temp = PushSystemTemp(); + temp_pushed_out = true; + uint32_t used_swizzle_components = 0; + for (uint32_t i = 0; i < uint32_t(operand.component_count); ++i) { + if (!(needed_components & (1 << i))) { + continue; + } + SwizzleSource component = operand.GetComponent(i); + assert_true(component >= SwizzleSource::kX && component <= SwizzleSource::kW); + used_swizzle_components |= 1 << (uint32_t(component) - uint32_t(SwizzleSource::kX)); + } + assert_not_zero(used_swizzle_components); + a_.OpMov(dxbc::Dest::R(temp, used_swizzle_components), dxbc::Src::X(0, index)); + src = dxbc::Src::R(temp); + } else { + assert_true(operand.storage_addressing_mode == InstructionStorageAddressingMode::kAbsolute); + src = dxbc::Src::R(index.index_); + } + } break; + case InstructionStorageSource::kConstantFloat: { + if (cbuffer_index_float_constants_ == kBindingIndexUnallocated) { + cbuffer_index_float_constants_ = cbuffer_count_++; + } + const Shader::ConstantRegisterMap& constant_register_map = + current_shader().constant_register_map(); + if (operand.storage_addressing_mode == InstructionStorageAddressingMode::kAbsolute) { + uint32_t float_constant_index = + constant_register_map.GetPackedFloatConstantIndex(operand.storage_index); + assert_true(float_constant_index != UINT32_MAX); + if (float_constant_index == UINT32_MAX) { + return dxbc::Src::LF(0.0f); + } + index.index_ = float_constant_index; + } else { + assert_true(constant_register_map.float_dynamic_addressing); + } + src = dxbc::Src::CB(cbuffer_index_float_constants_, + uint32_t(CbufferRegister::kFloatConstants), index); + } break; + default: + assert_unhandled_case(operand.storage_source); + return dxbc::Src::LF(0.0f); + } + + // Swizzle, skipping unneeded components similar to how FXC skips components, + // by replacing them with the leftmost used one. + uint32_t swizzle = 0; + for (uint32_t i = 0; i < 4; ++i) { + SwizzleSource component = + operand.GetComponent((needed_components & (1 << i)) ? i : first_needed_component); + assert_true(component >= SwizzleSource::kX && component <= SwizzleSource::kW); + swizzle |= (uint32_t(component) - uint32_t(SwizzleSource::kX)) << (i * 2); + } + src = src.Swizzle(swizzle); + + return src.WithModifiers(operand.is_absolute_value, operand.is_negated); +} + +void DxbcShaderTranslator::StoreResult(const InstructionResult& result, const dxbc::Src& src, + bool can_store_memexport_address) { + uint32_t used_write_mask = result.GetUsedWriteMask(); + if (!used_write_mask) { + return; + } + + // Get the destination address and type. + dxbc::Dest dest(dxbc::Dest::Null()); + bool is_clamped = result.is_clamped; + switch (result.storage_target) { + case InstructionStorageTarget::kNone: + return; + case InstructionStorageTarget::kRegister: + if (current_shader().uses_register_dynamic_addressing()) { + dxbc::Index register_index(result.storage_index); + switch (result.storage_addressing_mode) { + case InstructionStorageAddressingMode::kAbsolute: + break; + case InstructionStorageAddressingMode::kAddressRegisterRelative: + register_index = dxbc::Index(system_temp_ps_pc_p0_a0_, 3, result.storage_index); + break; + case InstructionStorageAddressingMode::kLoopRelative: + register_index = dxbc::Index(system_temp_aL_, 0, result.storage_index); + break; + } + dest = dxbc::Dest::X(0, register_index); + } else { + assert_true(result.storage_addressing_mode == InstructionStorageAddressingMode::kAbsolute); + dest = dxbc::Dest::R(result.storage_index); + } + break; + case InstructionStorageTarget::kInterpolator: { + uint32_t interpolator_mask = GetModificationInterpolatorMask(); + uint32_t interpolator_bit = UINT32_C(1) << result.storage_index; + if (interpolator_mask & interpolator_bit) { + dest = dxbc::Dest::O(out_reg_vs_interpolators_ + + rex::bit_count(interpolator_mask & (interpolator_bit - 1))); + } + } break; + case InstructionStorageTarget::kPosition: + dest = dxbc::Dest::R(system_temp_position_); + break; + case InstructionStorageTarget::kPointSizeEdgeFlagKillVertex: + assert_zero(used_write_mask & 0b1000); + dest = dxbc::Dest::R(system_temp_point_size_edge_flag_kill_vertex_); + break; + case InstructionStorageTarget::kExportAddress: + if (!can_store_memexport_address) { + return; + } + if (!current_shader().memexport_eM_written()) { + return; + } + dest = dxbc::Dest::R(system_temp_memexport_address_); + break; + case InstructionStorageTarget::kExportData: { + assert_not_zero(current_shader().memexport_eM_written() & + (uint8_t(1) << result.storage_index)); + dest = dxbc::Dest::R(system_temps_memexport_data_[result.storage_index]); + // Mark that the eM# has been written to and needs to be exported. + assert_not_zero(used_write_mask); + a_.OpOr(dxbc::Dest::R(system_temp_memexport_enabled_and_eM_written_, 0b0010), + dxbc::Src::R(system_temp_memexport_enabled_and_eM_written_, dxbc::Src::kYYYY), + dxbc::Src::LU(uint8_t(1) << result.storage_index)); + } break; + case InstructionStorageTarget::kColor: + assert_not_zero(used_write_mask); + assert_true(current_shader().writes_color_target(result.storage_index)); + dest = dxbc::Dest::R(system_temps_color_[result.storage_index]); + if (edram_rov_used_) { + // For ROV output, mark that the color has been written to. + // According to: + // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx9-graphics-reference-asm-ps-registers-output-color + // if a color target hasn't been written to - including due to flow + // control - the render target must not be modified (the unwritten + // components of a written target are undefined, not sure if this + // behavior is respected on the real GPU, but the ROV code currently + // doesn't preserve unmodified components). + a_.OpOr(dxbc::Dest::R(system_temp_rov_params_, 0b0001), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), + dxbc::Src::LU(uint32_t(1) << (8 + result.storage_index))); + } + break; + case InstructionStorageTarget::kDepth: + // Writes X to scalar oDepth or to X of system_temp_depth_stencil_, no + // additional swizzling needed. + assert_true(used_write_mask == 0b0001); + assert_true(current_shader().writes_depth()); + if (IsDepthStencilSystemTempUsed()) { + dest = dxbc::Dest::R(system_temp_depth_stencil_); + } else { + dest = dxbc::Dest::ODepth(); + } + // Depth outside [0, 1] is not safe for use with the ROV code, with + // 20e4-as-32 conversion and with 0...1 to 0...0.5 float24 remapping. + // Though 20e4 float depth can store values between 1 and 2, it's a very + // unusual case. Direct3D 10+ SV_Depth, however, can accept any values, + // including specials, when the depth buffer is floating-point. + is_clamped = true; + break; + } + if (dest.type_ == dxbc::OperandType::kNull) { + return; + } + + // Write. + uint32_t src_additional_swizzle = 0; + uint32_t constant_mask = 0, constant_1_mask = 0; + for (uint32_t i = 0; i < 4; ++i) { + if (!(used_write_mask & (1 << i))) { + continue; + } + SwizzleSource component = result.components[i]; + if (component >= SwizzleSource::kX && component <= SwizzleSource::kW) { + src_additional_swizzle |= (uint32_t(component) - uint32_t(SwizzleSource::kX)) << (i * 2); + } else { + constant_mask |= 1 << i; + if (component == SwizzleSource::k1) { + constant_1_mask |= 1 << i; + } + } + } + if (used_write_mask != constant_mask) { + a_.OpMov(dest.Mask(used_write_mask & ~constant_mask), + src.SwizzleSwizzled(src_additional_swizzle), is_clamped); + } + if (constant_mask) { + a_.OpMov(dest.Mask(constant_mask), + dxbc::Src::LF(float(constant_1_mask & 1), float((constant_1_mask >> 1) & 1), + float((constant_1_mask >> 2) & 1), float((constant_1_mask >> 3) & 1))); + } + + // Make the point size non-negative as negative is used to indicate that the + // default size must be used, and also clamp it to the bounds the way the R400 + // (Adreno 200, to be more precise) hardware clamps it (functionally like a + // signed 32-bit integer, -NaN and -Infinity...-0 to the minimum, +NaN to the + // maximum). + if (result.storage_target == InstructionStorageTarget::kPointSizeEdgeFlagKillVertex && + (used_write_mask & 0b0001)) { + a_.OpIMax( + dxbc::Dest::R(system_temp_point_size_edge_flag_kill_vertex_, 0b0001), + LoadSystemConstant(SystemConstants::Index::kPointVertexDiameterMin, + offsetof(SystemConstants, point_vertex_diameter_min), dxbc::Src::kXXXX), + dxbc::Src::R(system_temp_point_size_edge_flag_kill_vertex_, dxbc::Src::kXXXX)); + a_.OpIMin( + dxbc::Dest::R(system_temp_point_size_edge_flag_kill_vertex_, 0b0001), + LoadSystemConstant(SystemConstants::Index::kPointVertexDiameterMax, + offsetof(SystemConstants, point_vertex_diameter_max), dxbc::Src::kXXXX), + dxbc::Src::R(system_temp_point_size_edge_flag_kill_vertex_, dxbc::Src::kXXXX)); + } +} + +void DxbcShaderTranslator::UpdateExecConditionalsAndEmitDisassembly( + ParsedExecInstruction::Type type, uint32_t bool_constant_index, bool condition) { + // Check if we can merge the new exec with the previous one, or the jump with + // the previous exec. The instruction-level predicate check is also merged in + // this case. + bool merge = false; + if (type == ParsedExecInstruction::Type::kConditional) { + // Can merge conditional with conditional, as long as the bool constant and + // the expected values are the same. + if (cf_exec_bool_constant_ == bool_constant_index && + cf_exec_bool_constant_condition_ == condition) { + merge = true; + } + } else if (type == ParsedExecInstruction::Type::kPredicated) { + // Can merge predicated with predicated if the conditions are the same and + // the previous exec hasn't modified the predicate register. + if (!cf_exec_predicate_written_ && cf_exec_predicated_ && + cf_exec_predicate_condition_ == condition) { + merge = true; + } + } else { + // Can merge unconditional with unconditional. + if (cf_exec_bool_constant_ == kCfExecBoolConstantNone && !cf_exec_predicated_) { + merge = true; + } + } + + if (merge) { + // Emit the disassembly for the exec/jump merged with the previous one. + EmitInstructionDisassembly(); + return; + } + + CloseExecConditionals(); + + // Emit the disassembly for the new exec/jump. + EmitInstructionDisassembly(); + + if (type == ParsedExecInstruction::Type::kConditional) { + uint32_t bool_constant_test_temp = PushSystemTemp(); + // Check the bool constant value. + if (cbuffer_index_bool_loop_constants_ == kBindingIndexUnallocated) { + cbuffer_index_bool_loop_constants_ = cbuffer_count_++; + } + a_.OpAnd(dxbc::Dest::R(bool_constant_test_temp, 0b0001), + dxbc::Src::CB(cbuffer_index_bool_loop_constants_, + uint32_t(CbufferRegister::kBoolLoopConstants), bool_constant_index >> 7) + .Select((bool_constant_index >> 5) & 3), + dxbc::Src::LU(uint32_t(1) << (bool_constant_index & 31))); + // Open the new `if`. + a_.OpIf(condition, dxbc::Src::R(bool_constant_test_temp, dxbc::Src::kXXXX)); + // Release bool_constant_test_temp. + PopSystemTemp(); + cf_exec_bool_constant_ = bool_constant_index; + cf_exec_bool_constant_condition_ = condition; + } else if (type == ParsedExecInstruction::Type::kPredicated) { + a_.OpIf(condition, dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kZZZZ)); + cf_exec_predicated_ = true; + cf_exec_predicate_condition_ = condition; + } +} + +void DxbcShaderTranslator::CloseExecConditionals() { + // Within the exec - instruction-level predicate check. + CloseInstructionPredication(); + // Exec level. + if (cf_exec_bool_constant_ != kCfExecBoolConstantNone || cf_exec_predicated_) { + a_.OpEndIf(); + cf_exec_bool_constant_ = kCfExecBoolConstantNone; + cf_exec_predicated_ = false; + } + // Nothing relies on the predicate value being unchanged now. + cf_exec_predicate_written_ = false; +} + +void DxbcShaderTranslator::UpdateInstructionPredicationAndEmitDisassembly(bool predicated, + bool condition) { + if (!predicated) { + CloseInstructionPredication(); + EmitInstructionDisassembly(); + return; + } + + if (cf_instruction_predicate_if_open_) { + if (cf_instruction_predicate_condition_ == condition) { + // Already in the needed instruction-level `if`. + EmitInstructionDisassembly(); + return; + } + CloseInstructionPredication(); + } + + // Emit the disassembly before opening (or not opening) the new conditional. + EmitInstructionDisassembly(); + + // If the instruction predicate condition is the same as the exec predicate + // condition, no need to open a check. However, if there was a `setp` prior + // to this instruction, the predicate value now may be different than it was + // in the beginning of the exec. + if (!cf_exec_predicate_written_ && cf_exec_predicated_ && + cf_exec_predicate_condition_ == condition) { + return; + } + + a_.OpIf(condition, dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kZZZZ)); + cf_instruction_predicate_if_open_ = true; + cf_instruction_predicate_condition_ = condition; +} + +void DxbcShaderTranslator::CloseInstructionPredication() { + if (cf_instruction_predicate_if_open_) { + a_.OpEndIf(); + cf_instruction_predicate_if_open_ = false; + } +} + +void DxbcShaderTranslator::JumpToLabel(uint32_t address) { + a_.OpMov(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b0010), dxbc::Src::LU(address)); + a_.OpContinue(); +} + +void DxbcShaderTranslator::ProcessLabel(uint32_t cf_index) { + if (cf_index == 0) { + // 0 already added in the beginning. + return; + } + // Close flow control on the deeper levels below - prevent attempts to merge + // execs across labels. + CloseExecConditionals(); + if (UseSwitchForControlFlow()) { + // Fallthrough to the label from the previous one on the next iteration if + // no `continue` was done. Can't simply fallthrough because in DXBC, a + // non-empty switch case must end with a break. + JumpToLabel(cf_index); + // Close the previous label. + a_.OpBreak(); + // Go to the next label. + a_.OpCase(dxbc::Src::LU(cf_index)); + } else { + // Close the previous label. + a_.OpEndIf(); + // if (pc <= cf_index) + uint32_t test_temp = PushSystemTemp(); + a_.OpUGE(dxbc::Dest::R(test_temp, 0b0001), dxbc::Src::LU(cf_index), + dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kYYYY)); + a_.OpIf(true, dxbc::Src::R(test_temp, dxbc::Src::kXXXX)); + // Release test_temp. + PopSystemTemp(); + } +} + +void DxbcShaderTranslator::ProcessExecInstructionBegin(const ParsedExecInstruction& instr) { + if (emit_source_map_) { + instruction_disassembly_buffer_.Reset(); + instr.Disassemble(&instruction_disassembly_buffer_); + } + UpdateExecConditionalsAndEmitDisassembly(instr.type, instr.bool_constant_index, instr.condition); +} + +void DxbcShaderTranslator::ProcessExecInstructionEnd(const ParsedExecInstruction& instr) { + if (instr.is_end) { + // Break out of the main loop. + CloseInstructionPredication(); + if (UseSwitchForControlFlow()) { + // Write an invalid value to pc. + a_.OpMov(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b0010), dxbc::Src::LU(UINT32_MAX)); + // Go to the next iteration, where switch cases won't be reached. + a_.OpContinue(); + } else { + a_.OpBreak(); + } + } +} + +void DxbcShaderTranslator::ProcessLoopStartInstruction(const ParsedLoopStartInstruction& instr) { + // loop il, L - loop with loop data il, end @ L + + // Loop control is outside execs - actually close the last exec. + CloseExecConditionals(); + + if (emit_source_map_) { + instruction_disassembly_buffer_.Reset(); + instr.Disassemble(&instruction_disassembly_buffer_); + EmitInstructionDisassembly(); + } + + // Count (unsigned) in bits 0:7 of the loop constant, initial aL (unsigned) in + // 8:15. Starting from vector 2 because of bool constants. + if (cbuffer_index_bool_loop_constants_ == kBindingIndexUnallocated) { + cbuffer_index_bool_loop_constants_ = cbuffer_count_++; + } + dxbc::Src loop_constant_src(dxbc::Src::CB(cbuffer_index_bool_loop_constants_, + uint32_t(CbufferRegister::kBoolLoopConstants), + 2 + (instr.loop_constant_index >> 2)) + .Select(instr.loop_constant_index & 3)); + + { + uint32_t loop_count_temp = PushSystemTemp(); + a_.OpAnd(dxbc::Dest::R(loop_count_temp, 0b0001), loop_constant_src, dxbc::Src::LU(UINT8_MAX)); + + // Skip the loop without pushing if the count is zero from the beginning. + a_.OpIf(false, dxbc::Src::R(loop_count_temp, dxbc::Src::kXXXX)); + JumpToLabel(instr.loop_skip_address); + a_.OpEndIf(); + + // Push the count to the loop count stack - move XYZ to YZW and set X to the + // new loop count. + a_.OpMov(dxbc::Dest::R(system_temp_loop_count_, 0b1110), + dxbc::Src::R(system_temp_loop_count_, 0b10010000)); + a_.OpMov(dxbc::Dest::R(system_temp_loop_count_, 0b0001), + dxbc::Src::R(loop_count_temp, dxbc::Src::kXXXX)); + + // Release loop_count_temp. + PopSystemTemp(); + } + + // Push aL - keep the same value as in the previous loop if repeating, or the + // new one otherwise. + a_.OpMov(dxbc::Dest::R(system_temp_aL_, instr.is_repeat ? 0b1111 : 0b1110), + dxbc::Src::R(system_temp_aL_, 0b10010000)); + if (!instr.is_repeat) { + a_.OpUBFE(dxbc::Dest::R(system_temp_aL_, 0b0001), dxbc::Src::LU(8), dxbc::Src::LU(8), + loop_constant_src); + } +} + +void DxbcShaderTranslator::ProcessLoopEndInstruction(const ParsedLoopEndInstruction& instr) { + // endloop il, L - end loop w/ data il, head @ L + + // Loop control is outside execs - actually close the last exec. + CloseExecConditionals(); + + if (emit_source_map_) { + instruction_disassembly_buffer_.Reset(); + instr.Disassemble(&instruction_disassembly_buffer_); + EmitInstructionDisassembly(); + } + + // Subtract 1 from the loop counter. + a_.OpIAdd(dxbc::Dest::R(system_temp_loop_count_, 0b0001), + dxbc::Src::R(system_temp_loop_count_, dxbc::Src::kXXXX), dxbc::Src::LI(-1)); + + if (instr.is_predicated_break) { + // if (loop_count.x == 0 || [!]p0) + uint32_t break_case_temp = PushSystemTemp(); + if (instr.predicate_condition) { + // If p0 is non-zero, set the test value to 0 (since if_z is used, + // otherwise check if the loop counter is zero). + a_.OpMovC(dxbc::Dest::R(break_case_temp, 0b0001), + dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kZZZZ), dxbc::Src::LU(0), + dxbc::Src::R(system_temp_loop_count_, dxbc::Src::kXXXX)); + } else { + // If p0 is zero, set the test value to 0 (since if_z is used, otherwise + // check if the loop counter is zero). + a_.OpMovC(dxbc::Dest::R(break_case_temp, 0b0001), + dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kZZZZ), + dxbc::Src::R(system_temp_loop_count_, dxbc::Src::kXXXX), dxbc::Src::LU(0)); + } + a_.OpIf(false, dxbc::Src::R(break_case_temp, dxbc::Src::kXXXX)); + // Release break_case_temp. + PopSystemTemp(); + } else { + // if (loop_count.x == 0) + a_.OpIf(false, dxbc::Src::R(system_temp_loop_count_, dxbc::Src::kXXXX)); + } + { + // Break case. + // Pop the current loop off the loop counter and the relative address + // stacks - move YZW to XYZ and set W to 0. + a_.OpMov(dxbc::Dest::R(system_temp_loop_count_, 0b0111), + dxbc::Src::R(system_temp_loop_count_, 0b111001)); + a_.OpMov(dxbc::Dest::R(system_temp_loop_count_, 0b1000), dxbc::Src::LU(0)); + a_.OpMov(dxbc::Dest::R(system_temp_aL_, 0b0111), dxbc::Src::R(system_temp_aL_, 0b111001)); + a_.OpMov(dxbc::Dest::R(system_temp_aL_, 0b1000), dxbc::Src::LI(0)); + // Now going to fall through to the next exec (no need to jump). + } + a_.OpElse(); + { + // Continue case. + uint32_t aL_add_temp = PushSystemTemp(); + // Extract the value to add to aL (signed, in bits 16:23 of the loop + // constant). Starting from vector 2 because of bool constants. + if (cbuffer_index_bool_loop_constants_ == kBindingIndexUnallocated) { + cbuffer_index_bool_loop_constants_ = cbuffer_count_++; + } + a_.OpIBFE(dxbc::Dest::R(aL_add_temp, 0b0001), dxbc::Src::LU(8), dxbc::Src::LU(16), + dxbc::Src::CB(cbuffer_index_bool_loop_constants_, + uint32_t(CbufferRegister::kBoolLoopConstants), + 2 + (instr.loop_constant_index >> 2)) + .Select(instr.loop_constant_index & 3)); + // Add the needed value to aL. + a_.OpIAdd(dxbc::Dest::R(system_temp_aL_, 0b0001), + dxbc::Src::R(system_temp_aL_, dxbc::Src::kXXXX), + dxbc::Src::R(aL_add_temp, dxbc::Src::kXXXX)); + // Release aL_add_temp. + PopSystemTemp(); + // Jump back to the beginning of the loop body. + JumpToLabel(instr.loop_body_address); + } + a_.OpEndIf(); +} + +void DxbcShaderTranslator::ProcessJumpInstruction(const ParsedJumpInstruction& instr) { + if (emit_source_map_) { + instruction_disassembly_buffer_.Reset(); + instr.Disassemble(&instruction_disassembly_buffer_); + } + + // Treat like exec, merge with execs if possible, since it's an if too. + ParsedExecInstruction::Type type; + if (instr.type == ParsedJumpInstruction::Type::kConditional) { + type = ParsedExecInstruction::Type::kConditional; + } else if (instr.type == ParsedJumpInstruction::Type::kPredicated) { + type = ParsedExecInstruction::Type::kPredicated; + } else { + type = ParsedExecInstruction::Type::kUnconditional; + } + UpdateExecConditionalsAndEmitDisassembly(type, instr.bool_constant_index, instr.condition); + + // UpdateExecConditionalsAndEmitDisassembly may not necessarily close the + // instruction-level predicate check (it's not necessary if the execs are + // merged), but here the instruction itself is on the flow control level, so + // the predicate check is on the flow control level too. + CloseInstructionPredication(); + + JumpToLabel(instr.target_address); +} + +void DxbcShaderTranslator::ProcessAllocInstruction(const ParsedAllocInstruction& instr, + uint8_t export_eM) { + bool start_memexport = + instr.type == AllocType::kMemory && current_shader().memexport_eM_written(); + if (export_eM || start_memexport) { + CloseExecConditionals(); + } + + if (emit_source_map_) { + instruction_disassembly_buffer_.Reset(); + instr.Disassemble(&instruction_disassembly_buffer_); + EmitInstructionDisassembly(); + } + + if (export_eM) { + ExportToMemory(export_eM); + // Reset which eM# elements have been written. + a_.OpMov(dxbc::Dest::R(system_temp_memexport_enabled_and_eM_written_, 0b0010), + dxbc::Src::LU(0)); + // Break dependencies from the previous memexport. + uint8_t export_eM_remaining = export_eM; + uint32_t eM_index; + while (rex::bit_scan_forward(export_eM_remaining, &eM_index)) { + export_eM_remaining &= ~(uint8_t(1) << eM_index); + a_.OpMov(dxbc::Dest::R(system_temps_memexport_data_[eM_index]), dxbc::Src::LF(0.0f)); + } + } + + if (start_memexport) { + // Initialize eA to an invalid address. + a_.OpMov(dxbc::Dest::R(system_temp_memexport_address_), dxbc::Src::LU(0)); + } +} + +const DxbcShaderTranslator::ShaderRdefType + DxbcShaderTranslator::rdef_types_[size_t(DxbcShaderTranslator::ShaderRdefTypeIndex::kCount)] = { + // kFloat + {"float", dxbc::RdefVariableClass::kScalar, dxbc::RdefVariableType::kFloat, 1, 1, 0, + ShaderRdefTypeIndex::kUnknown}, + // kFloat2 + {"float2", dxbc::RdefVariableClass::kVector, dxbc::RdefVariableType::kFloat, 1, 2, 0, + ShaderRdefTypeIndex::kUnknown}, + // kFloat3 + {"float3", dxbc::RdefVariableClass::kVector, dxbc::RdefVariableType::kFloat, 1, 3, 0, + ShaderRdefTypeIndex::kUnknown}, + // kFloat4 + {"float4", dxbc::RdefVariableClass::kVector, dxbc::RdefVariableType::kFloat, 1, 4, 0, + ShaderRdefTypeIndex::kUnknown}, + // kUint + {"dword", dxbc::RdefVariableClass::kScalar, dxbc::RdefVariableType::kUInt, 1, 1, 0, + ShaderRdefTypeIndex::kUnknown}, + // kUint2 + {"uint2", dxbc::RdefVariableClass::kVector, dxbc::RdefVariableType::kUInt, 1, 2, 0, + ShaderRdefTypeIndex::kUnknown}, + // kUint4 + {"uint4", dxbc::RdefVariableClass::kVector, dxbc::RdefVariableType::kUInt, 1, 4, 0, + ShaderRdefTypeIndex::kUnknown}, + // kFloat4Array4 + {nullptr, dxbc::RdefVariableClass::kVector, dxbc::RdefVariableType::kFloat, 1, 4, 4, + ShaderRdefTypeIndex::kFloat4}, + // kFloat4Array6 + {nullptr, dxbc::RdefVariableClass::kVector, dxbc::RdefVariableType::kFloat, 1, 4, 6, + ShaderRdefTypeIndex::kFloat4}, + // kFloat4ConstantArray - float constants - size written dynamically. + {nullptr, dxbc::RdefVariableClass::kVector, dxbc::RdefVariableType::kFloat, 1, 4, 0, + ShaderRdefTypeIndex::kFloat4}, + // kUint4Array2 + {nullptr, dxbc::RdefVariableClass::kVector, dxbc::RdefVariableType::kUInt, 1, 4, 2, + ShaderRdefTypeIndex::kUint4}, + // kUint4Array8 + {nullptr, dxbc::RdefVariableClass::kVector, dxbc::RdefVariableType::kUInt, 1, 4, 8, + ShaderRdefTypeIndex::kUint4}, + // kUint4Array48 + {nullptr, dxbc::RdefVariableClass::kVector, dxbc::RdefVariableType::kUInt, 1, 4, 48, + ShaderRdefTypeIndex::kUint4}, + // kUint4DescriptorIndexArray - bindless descriptor indices - size + // written + // dynamically. + {nullptr, dxbc::RdefVariableClass::kVector, dxbc::RdefVariableType::kUInt, 1, 4, 0, + ShaderRdefTypeIndex::kUint4}, +}; + +const DxbcShaderTranslator::SystemConstantRdef DxbcShaderTranslator::system_constant_rdef_[size_t( + DxbcShaderTranslator::SystemConstants::Index::kCount)] = { + {"xe_flags", ShaderRdefTypeIndex::kUint, sizeof(uint32_t)}, + {"xe_tessellation_factor_range", ShaderRdefTypeIndex::kFloat2, sizeof(float) * 2}, + {"xe_line_loop_closing_index", ShaderRdefTypeIndex::kUint, sizeof(uint32_t)}, + + {"xe_vertex_index_endian", ShaderRdefTypeIndex::kUint, sizeof(uint32_t)}, + {"xe_vertex_index_offset", ShaderRdefTypeIndex::kUint, sizeof(int32_t)}, + {"xe_vertex_index_min_max", ShaderRdefTypeIndex::kUint2, sizeof(uint32_t) * 2}, + + {"xe_user_clip_planes", ShaderRdefTypeIndex::kFloat4Array6, sizeof(float) * 4 * 6}, + + {"xe_ndc_scale", ShaderRdefTypeIndex::kFloat3, sizeof(float) * 3}, + {"xe_point_vertex_diameter_min", ShaderRdefTypeIndex::kFloat, sizeof(float)}, + + {"xe_ndc_offset", ShaderRdefTypeIndex::kFloat3, sizeof(float) * 3}, + {"xe_point_vertex_diameter_max", ShaderRdefTypeIndex::kFloat, sizeof(float)}, + + {"xe_point_constant_diameter", ShaderRdefTypeIndex::kFloat2, sizeof(float) * 2}, + {"xe_point_screen_diameter_to_ndc_radius", ShaderRdefTypeIndex::kFloat2, sizeof(float) * 2}, + + {"xe_texture_swizzled_signs", ShaderRdefTypeIndex::kUint4Array2, sizeof(uint32_t) * 4 * 2}, + + {"xe_textures_resolution_scaled", ShaderRdefTypeIndex::kUint, sizeof(uint32_t)}, + {"xe_sample_count_log2", ShaderRdefTypeIndex::kUint2, sizeof(uint32_t) * 2}, + {"xe_alpha_test_reference", ShaderRdefTypeIndex::kFloat, sizeof(float)}, + + {"xe_alpha_to_mask", ShaderRdefTypeIndex::kUint, sizeof(uint32_t)}, + {"xe_edram_32bpp_tile_pitch_dwords_scaled", ShaderRdefTypeIndex::kUint, sizeof(uint32_t)}, + {"xe_edram_depth_base_dwords_scaled", ShaderRdefTypeIndex::kUint, sizeof(uint32_t), + sizeof(uint32_t)}, + + {"xe_color_exp_bias", ShaderRdefTypeIndex::kFloat4, sizeof(float) * 4}, + + {"xe_edram_poly_offset_front", ShaderRdefTypeIndex::kFloat2, sizeof(float) * 2}, + {"xe_edram_poly_offset_back", ShaderRdefTypeIndex::kFloat2, sizeof(float) * 2}, + + {"xe_edram_stencil", ShaderRdefTypeIndex::kUint4Array2, sizeof(uint32_t) * 4 * 2}, + + {"xe_edram_rt_base_dwords_scaled", ShaderRdefTypeIndex::kUint4, sizeof(uint32_t) * 4}, + + {"xe_edram_rt_format_flags", ShaderRdefTypeIndex::kUint4, sizeof(uint32_t) * 4}, + + {"xe_edram_rt_clamp", ShaderRdefTypeIndex::kFloat4Array4, sizeof(float) * 4 * 4}, + + {"xe_edram_rt_keep_mask", ShaderRdefTypeIndex::kUint4Array2, sizeof(uint32_t) * 4 * 2}, + + {"xe_edram_rt_blend_factors_ops", ShaderRdefTypeIndex::kUint4, sizeof(uint32_t) * 4}, + + {"xe_edram_blend_constant", ShaderRdefTypeIndex::kFloat4, sizeof(float) * 4}, +}; + +void DxbcShaderTranslator::WriteResourceDefinition() { + // Because of shader_object_.resize(), pointers can't be kept persistently + // here! Resizing also zeroes the memory. + + uint32_t blob_position_dwords = uint32_t(shader_object_.size()); + uint32_t name_ptr; + + const Shader::ConstantRegisterMap& constant_register_map = + current_shader().constant_register_map(); + + // Allocate space for the header, will fill when all pointers and counts are + // known. + shader_object_.resize(shader_object_.size() + sizeof(dxbc::RdefHeader) / sizeof(uint32_t)); + // Generator name. + dxbc::AppendAlignedString(shader_object_, "Xenia"); + + // *************************************************************************** + // Constant types + // *************************************************************************** + + // Type names. + name_ptr = (uint32_t(shader_object_.size()) - blob_position_dwords) * sizeof(uint32_t); + uint32_t type_name_ptrs[size_t(ShaderRdefTypeIndex::kCount)]; + for (uint32_t i = 0; i < uint32_t(ShaderRdefTypeIndex::kCount); ++i) { + const ShaderRdefType& type = rdef_types_[i]; + if (type.name == nullptr) { + // Array - use the name of the element type. + assert_true(uint32_t(type.array_element_type) < i); + type_name_ptrs[i] = type_name_ptrs[uint32_t(type.array_element_type)]; + continue; + } + type_name_ptrs[i] = name_ptr; + name_ptr += dxbc::AppendAlignedString(shader_object_, type.name); + } + // Types. + uint32_t types_position_dwords = uint32_t(shader_object_.size()); + uint32_t types_ptr = (types_position_dwords - blob_position_dwords) * sizeof(uint32_t); + shader_object_.resize(types_position_dwords + sizeof(dxbc::RdefType) / sizeof(uint32_t) * + uint32_t(ShaderRdefTypeIndex::kCount)); + { + auto types = reinterpret_cast(shader_object_.data() + types_position_dwords); + for (uint32_t i = 0; i < uint32_t(ShaderRdefTypeIndex::kCount); ++i) { + dxbc::RdefType& type = types[i]; + const ShaderRdefType& translator_type = rdef_types_[i]; + type.variable_class = translator_type.variable_class; + type.variable_type = translator_type.variable_type; + type.row_count = translator_type.row_count; + type.column_count = translator_type.column_count; + switch (ShaderRdefTypeIndex(i)) { + case ShaderRdefTypeIndex::kFloat4ConstantArray: + // Declaring a 0-sized array may not be safe, so write something valid + // even if they aren't used. + type.element_count = std::max(uint16_t(constant_register_map.float_count), uint16_t(1)); + break; + case ShaderRdefTypeIndex::kUint4DescriptorIndexArray: + type.element_count = + std::max(uint16_t((GetBindlessResourceCount() + 3) >> 2), uint16_t(1)); + break; + default: + type.element_count = translator_type.element_count; + } + type.name_ptr = type_name_ptrs[i]; + } + } + + // *************************************************************************** + // Constants + // *************************************************************************** + + // Names. + name_ptr = (uint32_t(shader_object_.size()) - blob_position_dwords) * sizeof(uint32_t); + uint32_t constant_name_ptrs_system[size_t(SystemConstants::Index::kCount)]; + if (cbuffer_index_system_constants_ != kBindingIndexUnallocated) { + for (size_t i = 0; i < size_t(SystemConstants::Index::kCount); ++i) { + constant_name_ptrs_system[i] = name_ptr; + name_ptr += dxbc::AppendAlignedString(shader_object_, system_constant_rdef_[i].name); + } + } + uint32_t constant_name_ptr_float = name_ptr; + if (cbuffer_index_float_constants_ != kBindingIndexUnallocated) { + name_ptr += dxbc::AppendAlignedString(shader_object_, "xe_float_constants"); + } + uint32_t constant_name_ptr_bool = name_ptr; + uint32_t constant_name_ptr_loop = name_ptr; + if (cbuffer_index_bool_loop_constants_ != kBindingIndexUnallocated) { + name_ptr += dxbc::AppendAlignedString(shader_object_, "xe_bool_constants"); + constant_name_ptr_loop = name_ptr; + name_ptr += dxbc::AppendAlignedString(shader_object_, "xe_loop_constants"); + } + uint32_t constant_name_ptr_fetch = name_ptr; + if (cbuffer_index_fetch_constants_ != kBindingIndexUnallocated) { + name_ptr += dxbc::AppendAlignedString(shader_object_, "xe_fetch_constants"); + } + uint32_t constant_name_ptr_descriptor_indices = name_ptr; + if (cbuffer_index_descriptor_indices_ != kBindingIndexUnallocated) { + name_ptr += dxbc::AppendAlignedString(shader_object_, "xe_descriptor_indices"); + } + + // System constants. + uint32_t constant_position_dwords_system = uint32_t(shader_object_.size()); + if (cbuffer_index_system_constants_ != kBindingIndexUnallocated) { + shader_object_.resize(constant_position_dwords_system + + sizeof(dxbc::RdefVariable) / sizeof(uint32_t) * + size_t(SystemConstants::Index::kCount)); + auto constants_system = reinterpret_cast(shader_object_.data() + + constant_position_dwords_system); + uint32_t constant_offset_system = 0; + for (size_t i = 0; i < size_t(SystemConstants::Index::kCount); ++i) { + dxbc::RdefVariable& constant_system = constants_system[i]; + const SystemConstantRdef& translator_constant_system = system_constant_rdef_[i]; + constant_system.name_ptr = constant_name_ptrs_system[i]; + constant_system.start_offset_bytes = constant_offset_system; + constant_system.size_bytes = translator_constant_system.size; + constant_system.flags = + (system_constants_used_ & (uint64_t(1) << i)) ? dxbc::kRdefVariableFlagUsed : 0; + constant_system.type_ptr = + types_ptr + sizeof(dxbc::RdefType) * uint32_t(translator_constant_system.type); + constant_system.start_texture = UINT32_MAX; + constant_system.start_sampler = UINT32_MAX; + constant_offset_system += + translator_constant_system.size + translator_constant_system.padding_after; + } + } + + // Float constants. + uint32_t constant_position_dwords_float = uint32_t(shader_object_.size()); + if (cbuffer_index_float_constants_ != kBindingIndexUnallocated) { + assert_not_zero(constant_register_map.float_count); + shader_object_.resize(constant_position_dwords_float + + sizeof(dxbc::RdefVariable) / sizeof(uint32_t)); + auto& constant_float = *reinterpret_cast(shader_object_.data() + + constant_position_dwords_float); + constant_float.name_ptr = constant_name_ptr_float; + constant_float.size_bytes = sizeof(float) * 4 * constant_register_map.float_count; + constant_float.flags = dxbc::kRdefVariableFlagUsed; + constant_float.type_ptr = + types_ptr + sizeof(dxbc::RdefType) * uint32_t(ShaderRdefTypeIndex::kFloat4ConstantArray); + constant_float.start_texture = UINT32_MAX; + constant_float.start_sampler = UINT32_MAX; + } + + // Bool and loop constants. + uint32_t constant_position_dwords_bool_loop = uint32_t(shader_object_.size()); + if (cbuffer_index_bool_loop_constants_ != kBindingIndexUnallocated) { + shader_object_.resize(constant_position_dwords_bool_loop + + sizeof(dxbc::RdefVariable) / sizeof(uint32_t) * 2); + auto constants_bool_loop = reinterpret_cast( + shader_object_.data() + constant_position_dwords_bool_loop); + + constants_bool_loop[0].name_ptr = constant_name_ptr_bool; + constants_bool_loop[0].size_bytes = sizeof(uint32_t) * 4 * 2; + for (size_t i = 0; i < rex::countof(constant_register_map.bool_bitmap); ++i) { + if (constant_register_map.bool_bitmap[i]) { + constants_bool_loop[0].flags |= dxbc::kRdefVariableFlagUsed; + break; + } + } + constants_bool_loop[0].type_ptr = + types_ptr + sizeof(dxbc::RdefType) * uint32_t(ShaderRdefTypeIndex::kUint4Array2); + constants_bool_loop[0].start_texture = UINT32_MAX; + constants_bool_loop[0].start_sampler = UINT32_MAX; + + constants_bool_loop[1].name_ptr = constant_name_ptr_loop; + constants_bool_loop[1].start_offset_bytes = sizeof(uint32_t) * 4 * 2; + constants_bool_loop[1].size_bytes = sizeof(uint32_t) * 4 * 8; + constants_bool_loop[1].flags = + constant_register_map.loop_bitmap ? dxbc::kRdefVariableFlagUsed : 0; + constants_bool_loop[1].type_ptr = + types_ptr + sizeof(dxbc::RdefType) * uint32_t(ShaderRdefTypeIndex::kUint4Array8); + constants_bool_loop[1].start_texture = UINT32_MAX; + constants_bool_loop[1].start_sampler = UINT32_MAX; + } + + // Fetch constants. + uint32_t constant_position_dwords_fetch = uint32_t(shader_object_.size()); + if (cbuffer_index_fetch_constants_ != kBindingIndexUnallocated) { + shader_object_.resize(constant_position_dwords_fetch + + sizeof(dxbc::RdefVariable) / sizeof(uint32_t)); + auto& constant_fetch = *reinterpret_cast(shader_object_.data() + + constant_position_dwords_fetch); + constant_fetch.name_ptr = constant_name_ptr_fetch; + constant_fetch.size_bytes = sizeof(uint32_t) * 6 * 32; + constant_fetch.flags = dxbc::kRdefVariableFlagUsed; + constant_fetch.type_ptr = + types_ptr + sizeof(dxbc::RdefType) * uint32_t(ShaderRdefTypeIndex::kUint4Array48); + constant_fetch.start_texture = UINT32_MAX; + constant_fetch.start_sampler = UINT32_MAX; + } + + // Bindless description indices. + uint32_t constant_position_dwords_descriptor_indices = uint32_t(shader_object_.size()); + if (cbuffer_index_descriptor_indices_ != kBindingIndexUnallocated) { + assert_not_zero(GetBindlessResourceCount()); + shader_object_.resize(constant_position_dwords_descriptor_indices + + sizeof(dxbc::RdefVariable) / sizeof(uint32_t)); + auto& constant_descriptor_indices = *reinterpret_cast( + shader_object_.data() + constant_position_dwords_descriptor_indices); + constant_descriptor_indices.name_ptr = constant_name_ptr_descriptor_indices; + constant_descriptor_indices.size_bytes = + sizeof(uint32_t) * rex::align(GetBindlessResourceCount(), uint32_t(4)); + constant_descriptor_indices.flags = dxbc::kRdefVariableFlagUsed; + constant_descriptor_indices.type_ptr = + types_ptr + + sizeof(dxbc::RdefType) * uint32_t(ShaderRdefTypeIndex::kUint4DescriptorIndexArray); + constant_descriptor_indices.start_texture = UINT32_MAX; + constant_descriptor_indices.start_sampler = UINT32_MAX; + } + + // *************************************************************************** + // Constant buffers + // *************************************************************************** + + // Names. + name_ptr = (uint32_t(shader_object_.size()) - blob_position_dwords) * sizeof(uint32_t); + uint32_t cbuffer_name_ptr_system = name_ptr; + if (cbuffer_index_system_constants_ != kBindingIndexUnallocated) { + name_ptr += dxbc::AppendAlignedString(shader_object_, "xe_system_cbuffer"); + } + uint32_t cbuffer_name_ptr_float = name_ptr; + if (cbuffer_index_float_constants_ != kBindingIndexUnallocated) { + name_ptr += dxbc::AppendAlignedString(shader_object_, "xe_float_cbuffer"); + } + uint32_t cbuffer_name_ptr_bool_loop = name_ptr; + if (cbuffer_index_bool_loop_constants_ != kBindingIndexUnallocated) { + name_ptr += dxbc::AppendAlignedString(shader_object_, "xe_bool_loop_cbuffer"); + } + uint32_t cbuffer_name_ptr_fetch = name_ptr; + if (cbuffer_index_fetch_constants_ != kBindingIndexUnallocated) { + name_ptr += dxbc::AppendAlignedString(shader_object_, "xe_fetch_cbuffer"); + } + uint32_t cbuffer_name_ptr_descriptor_indices = name_ptr; + if (cbuffer_index_descriptor_indices_ != kBindingIndexUnallocated) { + name_ptr += dxbc::AppendAlignedString(shader_object_, "xe_descriptor_indices_cbuffer"); + } + + // All the constant buffers, sorted by their binding index. + uint32_t cbuffers_position_dwords = uint32_t(shader_object_.size()); + shader_object_.resize(cbuffers_position_dwords + + sizeof(dxbc::RdefCbuffer) / sizeof(uint32_t) * cbuffer_count_); + { + auto cbuffers = + reinterpret_cast(shader_object_.data() + cbuffers_position_dwords); + for (uint32_t i = 0; i < cbuffer_count_; ++i) { + dxbc::RdefCbuffer& cbuffer = cbuffers[i]; + cbuffer.type = dxbc::RdefCbufferType::kCbuffer; + if (i == cbuffer_index_system_constants_) { + cbuffer.name_ptr = cbuffer_name_ptr_system; + cbuffer.variable_count = uint32_t(SystemConstants::Index::kCount); + cbuffer.variables_ptr = + (constant_position_dwords_system - blob_position_dwords) * sizeof(uint32_t); + cbuffer.size_vector_aligned_bytes = + uint32_t(rex::align(sizeof(SystemConstants), sizeof(uint32_t) * 4)); + } else if (i == cbuffer_index_float_constants_) { + assert_not_zero(constant_register_map.float_count); + cbuffer.name_ptr = cbuffer_name_ptr_float; + cbuffer.variable_count = 1; + cbuffer.variables_ptr = + (constant_position_dwords_float - blob_position_dwords) * sizeof(uint32_t); + cbuffer.size_vector_aligned_bytes = sizeof(float) * 4 * constant_register_map.float_count; + } else if (i == cbuffer_index_bool_loop_constants_) { + cbuffer.name_ptr = cbuffer_name_ptr_bool_loop; + cbuffer.variable_count = 2; + cbuffer.variables_ptr = + (constant_position_dwords_bool_loop - blob_position_dwords) * sizeof(uint32_t); + cbuffer.size_vector_aligned_bytes = sizeof(uint32_t) * 4 * (2 + 8); + } else if (i == cbuffer_index_fetch_constants_) { + cbuffer.name_ptr = cbuffer_name_ptr_fetch; + cbuffer.variable_count = 1; + cbuffer.variables_ptr = + (constant_position_dwords_fetch - blob_position_dwords) * sizeof(uint32_t); + cbuffer.size_vector_aligned_bytes = sizeof(uint32_t) * 6 * 32; + } else if (i == cbuffer_index_descriptor_indices_) { + assert_not_zero(GetBindlessResourceCount()); + cbuffer.name_ptr = cbuffer_name_ptr_descriptor_indices; + cbuffer.variable_count = 1; + cbuffer.variables_ptr = + (constant_position_dwords_descriptor_indices - blob_position_dwords) * sizeof(uint32_t); + cbuffer.size_vector_aligned_bytes = + sizeof(uint32_t) * rex::align(GetBindlessResourceCount(), uint32_t(4)); + } else { + assert_unhandled_case(i); + } + } + } + + // *************************************************************************** + // Bindings, in s#, t#, u#, cb# order + // *************************************************************************** + + // Names, except for constant buffers because their names are written already. + name_ptr = (uint32_t(shader_object_.size()) - blob_position_dwords) * sizeof(uint32_t); + uint32_t sampler_name_ptr = name_ptr; + if (!sampler_bindings_.empty()) { + if (bindless_resources_used_) { + name_ptr += dxbc::AppendAlignedString(shader_object_, "xe_samplers"); + } else { + for (uint32_t i = 0; i < uint32_t(sampler_bindings_.size()); ++i) { + name_ptr += + dxbc::AppendAlignedString(shader_object_, sampler_bindings_[i].bindful_name.c_str()); + } + } + } + uint32_t shared_memory_srv_name_ptr = name_ptr; + if (srv_index_shared_memory_ != kBindingIndexUnallocated) { + name_ptr += dxbc::AppendAlignedString(shader_object_, "xe_shared_memory_srv"); + } + uint32_t bindless_textures_2d_name_ptr = name_ptr; + uint32_t bindless_textures_3d_name_ptr = name_ptr; + uint32_t bindless_textures_cube_name_ptr = name_ptr; + if (bindless_resources_used_) { + if (srv_index_bindless_textures_2d_ != kBindingIndexUnallocated) { + bindless_textures_2d_name_ptr = name_ptr; + name_ptr += dxbc::AppendAlignedString(shader_object_, "xe_textures_2d"); + } + if (srv_index_bindless_textures_3d_ != kBindingIndexUnallocated) { + bindless_textures_3d_name_ptr = name_ptr; + name_ptr += dxbc::AppendAlignedString(shader_object_, "xe_textures_3d"); + } + if (srv_index_bindless_textures_cube_ != kBindingIndexUnallocated) { + bindless_textures_cube_name_ptr = name_ptr; + name_ptr += dxbc::AppendAlignedString(shader_object_, "xe_textures_cube"); + } + } else { + for (TextureBinding& texture_binding : texture_bindings_) { + texture_binding.bindful_srv_rdef_name_ptr = name_ptr; + name_ptr += dxbc::AppendAlignedString(shader_object_, texture_binding.bindful_name.c_str()); + } + } + uint32_t shared_memory_uav_name_ptr = name_ptr; + if (uav_index_shared_memory_ != kBindingIndexUnallocated) { + name_ptr += dxbc::AppendAlignedString(shader_object_, "xe_shared_memory_uav"); + } + uint32_t edram_name_ptr = name_ptr; + if (uav_index_edram_ != kBindingIndexUnallocated) { + name_ptr += dxbc::AppendAlignedString(shader_object_, "xe_edram"); + } + + uint32_t bindings_position_dwords = uint32_t(shader_object_.size()); + + // Samplers. + if (!sampler_bindings_.empty()) { + uint32_t samplers_position_dwords = uint32_t(shader_object_.size()); + shader_object_.resize(samplers_position_dwords + + sizeof(dxbc::RdefInputBind) / sizeof(uint32_t) * + (bindless_resources_used_ ? 1 : sampler_bindings_.size())); + auto samplers = + reinterpret_cast(shader_object_.data() + samplers_position_dwords); + if (bindless_resources_used_) { + // Bindless sampler heap. + samplers[0].name_ptr = sampler_name_ptr; + samplers[0].type = dxbc::RdefInputType::kSampler; + } else { + // Bindful samplers. + uint32_t sampler_current_name_ptr = sampler_name_ptr; + for (size_t i = 0; i < sampler_bindings_.size(); ++i) { + dxbc::RdefInputBind& sampler = samplers[i]; + sampler.name_ptr = sampler_current_name_ptr; + sampler.type = dxbc::RdefInputType::kSampler; + sampler.bind_point = uint32_t(i); + sampler.bind_count = 1; + sampler.id = uint32_t(i); + sampler_current_name_ptr += + dxbc::GetAlignedStringLength(sampler_bindings_[i].bindful_name.c_str()); + } + } + } + + // Shader resource views, sorted by binding index. + uint32_t srvs_position_dwords = uint32_t(shader_object_.size()); + shader_object_.resize(srvs_position_dwords + + sizeof(dxbc::RdefInputBind) / sizeof(uint32_t) * srv_count_); + { + auto srvs = + reinterpret_cast(shader_object_.data() + srvs_position_dwords); + for (uint32_t i = 0; i < srv_count_; ++i) { + dxbc::RdefInputBind& srv = srvs[i]; + srv.id = i; + if (i == srv_index_shared_memory_) { + // Shared memory (when memexport isn't used in the pipeline). + srv.name_ptr = shared_memory_srv_name_ptr; + srv.type = dxbc::RdefInputType::kByteAddress; + srv.return_type = dxbc::ResourceReturnType::kMixed; + srv.dimension = dxbc::RdefDimension::kSRVBuffer; + srv.bind_point = uint32_t(SRVMainRegister::kSharedMemory); + srv.bind_count = 1; + srv.bind_point_space = uint32_t(SRVSpace::kMain); + } else { + // Bindful texture or bindless textures. + srv.type = dxbc::RdefInputType::kTexture; + srv.return_type = dxbc::ResourceReturnType::kFloat; + srv.sample_count = UINT32_MAX; + srv.flags = dxbc::kRdefInputFlags4Component; + if (bindless_resources_used_) { + // Bindless texture heap. + if (i == srv_index_bindless_textures_3d_) { + srv.name_ptr = bindless_textures_3d_name_ptr; + srv.dimension = dxbc::RdefDimension::kSRVTexture3D; + srv.bind_point_space = uint32_t(SRVSpace::kBindlessTextures3D); + } else if (i == srv_index_bindless_textures_cube_) { + srv.name_ptr = bindless_textures_cube_name_ptr; + srv.dimension = dxbc::RdefDimension::kSRVTextureCube; + srv.bind_point_space = uint32_t(SRVSpace::kBindlessTexturesCube); + } else { + assert_true(i == srv_index_bindless_textures_2d_); + srv.name_ptr = bindless_textures_2d_name_ptr; + srv.dimension = dxbc::RdefDimension::kSRVTexture2DArray; + srv.bind_point_space = uint32_t(SRVSpace::kBindlessTextures2DArray); + } + } else { + // Bindful texture. + auto it = texture_bindings_for_bindful_srv_indices_.find(i); + assert_true(it != texture_bindings_for_bindful_srv_indices_.end()); + uint32_t texture_binding_index = it->second; + const TextureBinding& texture_binding = texture_bindings_[texture_binding_index]; + srv.name_ptr = texture_binding.bindful_srv_rdef_name_ptr; + switch (texture_binding.dimension) { + case xenos::FetchOpDimension::k3DOrStacked: + srv.dimension = dxbc::RdefDimension::kSRVTexture3D; + break; + case xenos::FetchOpDimension::kCube: + srv.dimension = dxbc::RdefDimension::kSRVTextureCube; + break; + default: + assert_true(texture_binding.dimension == xenos::FetchOpDimension::k2D); + srv.dimension = dxbc::RdefDimension::kSRVTexture2DArray; + } + srv.bind_point = uint32_t(SRVMainRegister::kBindfulTexturesStart) + texture_binding_index; + srv.bind_count = 1; + srv.bind_point_space = uint32_t(SRVSpace::kMain); + } + } + } + } + + // Unordered access views, sorted by binding index. + uint32_t uavs_position_dwords = uint32_t(shader_object_.size()); + shader_object_.resize(uavs_position_dwords + + sizeof(dxbc::RdefInputBind) / sizeof(uint32_t) * uav_count_); + { + auto uavs = + reinterpret_cast(shader_object_.data() + uavs_position_dwords); + for (uint32_t i = 0; i < uav_count_; ++i) { + dxbc::RdefInputBind& uav = uavs[i]; + uav.bind_count = 1; + uav.id = i; + if (i == uav_index_shared_memory_) { + // Shared memory (when memexport is used in the pipeline). + uav.name_ptr = shared_memory_uav_name_ptr; + uav.type = dxbc::RdefInputType::kUAVRWByteAddress; + uav.return_type = dxbc::ResourceReturnType::kMixed; + uav.dimension = dxbc::RdefDimension::kUAVBuffer; + uav.bind_point = uint32_t(UAVRegister::kSharedMemory); + } else if (i == uav_index_edram_) { + // EDRAM R32_UINT buffer. + uav.name_ptr = edram_name_ptr; + uav.type = dxbc::RdefInputType::kUAVRWTyped; + uav.return_type = dxbc::ResourceReturnType::kUInt; + uav.dimension = dxbc::RdefDimension::kUAVBuffer; + uav.sample_count = UINT32_MAX; + uav.bind_point = uint32_t(UAVRegister::kEdram); + } else { + assert_unhandled_case(i); + } + } + } + + // Constant buffers. + uint32_t cbuffer_binding_position_dwords = uint32_t(shader_object_.size()); + shader_object_.resize(cbuffer_binding_position_dwords + + sizeof(dxbc::RdefInputBind) / sizeof(uint32_t) * cbuffer_count_); + { + auto cbuffers = reinterpret_cast(shader_object_.data() + + cbuffer_binding_position_dwords); + for (uint32_t i = 0; i < cbuffer_count_; ++i) { + dxbc::RdefInputBind& cbuffer = cbuffers[i]; + cbuffer.type = dxbc::RdefInputType::kCbuffer; + cbuffer.bind_count = 1; + // Like `cbuffer`, don't need `ConstantBuffer` properties. + cbuffer.flags = dxbc::kRdefInputFlagUserPacked; + cbuffer.id = i; + if (i == cbuffer_index_system_constants_) { + cbuffer.name_ptr = cbuffer_name_ptr_system; + cbuffer.bind_point = uint32_t(CbufferRegister::kSystemConstants); + } else if (i == cbuffer_index_float_constants_) { + cbuffer.name_ptr = cbuffer_name_ptr_float; + cbuffer.bind_point = uint32_t(CbufferRegister::kFloatConstants); + } else if (i == cbuffer_index_bool_loop_constants_) { + cbuffer.name_ptr = cbuffer_name_ptr_bool_loop; + cbuffer.bind_point = uint32_t(CbufferRegister::kBoolLoopConstants); + } else if (i == cbuffer_index_fetch_constants_) { + cbuffer.name_ptr = cbuffer_name_ptr_fetch; + cbuffer.bind_point = uint32_t(CbufferRegister::kFetchConstants); + } else if (i == cbuffer_index_descriptor_indices_) { + cbuffer.name_ptr = cbuffer_name_ptr_descriptor_indices; + cbuffer.bind_point = uint32_t(CbufferRegister::kDescriptorIndices); + } else { + assert_unhandled_case(i); + } + } + } + + uint32_t bindings_end_position_dwords = uint32_t(shader_object_.size()); + + // *************************************************************************** + // Header + // *************************************************************************** + + { + auto& header = + *reinterpret_cast(shader_object_.data() + blob_position_dwords); + header.cbuffer_count = cbuffer_count_; + header.cbuffers_ptr = (cbuffers_position_dwords - blob_position_dwords) * sizeof(uint32_t); + header.input_bind_count = (bindings_end_position_dwords - bindings_position_dwords) * + sizeof(uint32_t) / sizeof(dxbc::RdefInputBind); + header.input_binds_ptr = (bindings_position_dwords - blob_position_dwords) * sizeof(uint32_t); + if (IsDxbcVertexShader()) { + header.shader_model = dxbc::RdefShaderModel::kVertexShader5_1; + } else if (IsDxbcDomainShader()) { + header.shader_model = dxbc::RdefShaderModel::kDomainShader5_1; + } else { + assert_true(is_pixel_shader()); + header.shader_model = dxbc::RdefShaderModel::kPixelShader5_1; + } + header.compile_flags = dxbc::kCompileFlagNoPreshader | dxbc::kCompileFlagPreferFlowControl | + dxbc::kCompileFlagIeeeStrictness; + if (bindless_resources_used_) { + header.compile_flags |= dxbc::kCompileFlagEnableUnboundedDescriptorTables; + } + // Generator name placed directly after the header. + header.generator_name_ptr = sizeof(dxbc::RdefHeader); + header.fourcc = dxbc::RdefHeader::FourCC::k5_1; + header.InitializeSizes(); + } +} + +void DxbcShaderTranslator::WriteInputSignature() { + // Because of shader_object_.resize(), pointers can't be kept persistently + // here! Resizing also zeroes the memory. + uint32_t blob_position = uint32_t(shader_object_.size()); + // Reserve space for the header. + shader_object_.resize(shader_object_.size() + sizeof(dxbc::Signature) / sizeof(uint32_t)); + uint32_t parameter_count = 0; + constexpr size_t kParameterDwords = sizeof(dxbc::SignatureParameter) / sizeof(uint32_t); + + if (IsDxbcVertexShader()) { + // Unswapped vertex index (SV_VertexID). + size_t vertex_id_position = shader_object_.size(); + shader_object_.resize(shader_object_.size() + kParameterDwords); + ++parameter_count; + { + auto& vertex_id = + *reinterpret_cast(shader_object_.data() + vertex_id_position); + vertex_id.system_value = dxbc::Name::kVertexID; + vertex_id.component_type = dxbc::SignatureRegisterComponentType::kUInt32; + vertex_id.register_index = kInRegisterVSVertexIndex; + vertex_id.mask = 0b0001; + vertex_id.always_reads_mask = (register_count() >= 1) ? 0b0001 : 0b0000; + } + + // Semantic names. + uint32_t semantic_offset = uint32_t((shader_object_.size() - blob_position) * sizeof(uint32_t)); + { + auto& vertex_id = + *reinterpret_cast(shader_object_.data() + vertex_id_position); + vertex_id.semantic_name_ptr = semantic_offset; + } + semantic_offset += dxbc::AppendAlignedString(shader_object_, "SV_VertexID"); + } else if (IsDxbcDomainShader()) { + // Control point indices, byte-swapped, biased according to the base index + // and converted to float by the host vertex and hull shaders + // (XEVERTEXID). + size_t control_point_index_position = shader_object_.size(); + shader_object_.resize(shader_object_.size() + kParameterDwords); + ++parameter_count; + { + auto& control_point_index = *reinterpret_cast( + shader_object_.data() + control_point_index_position); + control_point_index.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + control_point_index.register_index = kInRegisterDSControlPointIndex; + control_point_index.mask = 0b0001; + control_point_index.always_reads_mask = in_control_point_index_used_ ? 0b0001 : 0b0000; + } + + // Semantic names. + uint32_t semantic_offset = uint32_t((shader_object_.size() - blob_position) * sizeof(uint32_t)); + { + auto& control_point_index = *reinterpret_cast( + shader_object_.data() + control_point_index_position); + control_point_index.semantic_name_ptr = semantic_offset; + } + semantic_offset += dxbc::AppendAlignedString(shader_object_, "XEVERTEXID"); + } else if (is_pixel_shader()) { + // Intepolators (TEXCOORD#). + size_t interpolator_position = shader_object_.size(); + uint32_t interpolator_mask = GetModificationInterpolatorMask(); + uint32_t interpolator_count = rex::bit_count(interpolator_mask); + shader_object_.resize(shader_object_.size() + interpolator_count * kParameterDwords); + parameter_count += interpolator_count; + { + auto interpolators = reinterpret_cast(shader_object_.data() + + interpolator_position); + uint32_t used_interpolator_index = 0; + uint32_t interpolators_remaining = interpolator_mask; + uint32_t interpolator_index; + while (rex::bit_scan_forward(interpolators_remaining, &interpolator_index)) { + interpolators_remaining &= ~(UINT32_C(1) << interpolator_index); + dxbc::SignatureParameter& interpolator = interpolators[used_interpolator_index]; + interpolator.semantic_index = used_interpolator_index; + interpolator.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + interpolator.register_index = in_reg_ps_interpolators_ + used_interpolator_index; + interpolator.mask = 0b1111; + interpolator.always_reads_mask = interpolator_index < register_count() ? 0b1111 : 0b0000; + ++used_interpolator_index; + } + } + + // Point coordinates for PsParamGen (XESPRITETEXCOORD). + size_t point_coordinates_position = shader_object_.size(); + if (in_reg_ps_point_coordinates_ != UINT32_MAX) { + shader_object_.resize(shader_object_.size() + kParameterDwords); + ++parameter_count; + { + auto& point_coordinates = *reinterpret_cast( + shader_object_.data() + point_coordinates_position); + point_coordinates.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + point_coordinates.register_index = in_reg_ps_point_coordinates_; + point_coordinates.mask = 0b0011; + point_coordinates.always_reads_mask = 0b0011; + } + } + + // Pixel position (SV_Position). + size_t position_position = shader_object_.size(); + shader_object_.resize(shader_object_.size() + kParameterDwords); + ++parameter_count; + { + auto& position = + *reinterpret_cast(shader_object_.data() + position_position); + position.system_value = dxbc::Name::kPosition; + position.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + position.register_index = in_reg_ps_position_; + position.mask = 0b1111; + position.always_reads_mask = in_position_used_; + } + + // Is front face (SV_IsFrontFace). + size_t is_front_face_position = shader_object_.size(); + shader_object_.resize(shader_object_.size() + kParameterDwords); + ++parameter_count; + { + auto& is_front_face = *reinterpret_cast(shader_object_.data() + + is_front_face_position); + is_front_face.system_value = dxbc::Name::kIsFrontFace; + is_front_face.component_type = dxbc::SignatureRegisterComponentType::kUInt32; + is_front_face.register_index = in_reg_ps_front_face_sample_index_; + is_front_face.mask = 0b0001; + is_front_face.always_reads_mask = in_front_face_used_ ? 0b0001 : 0b0000; + } + + // Sample index (SV_SampleIndex) for safe memexport with sample-rate + // shading. + size_t sample_index_position = SIZE_MAX; + if (current_shader().memexport_eM_written() && IsSampleRate()) { + size_t sample_index_position = shader_object_.size(); + shader_object_.resize(shader_object_.size() + kParameterDwords); + ++parameter_count; + { + auto& sample_index = *reinterpret_cast(shader_object_.data() + + sample_index_position); + sample_index.system_value = dxbc::Name::kSampleIndex; + sample_index.component_type = dxbc::SignatureRegisterComponentType::kUInt32; + sample_index.register_index = in_reg_ps_front_face_sample_index_; + sample_index.mask = 0b0010; + sample_index.always_reads_mask = 0b0010; + } + } + + // Semantic names. + uint32_t semantic_offset = uint32_t((shader_object_.size() - blob_position) * sizeof(uint32_t)); + if (interpolator_count) { + auto interpolators = reinterpret_cast(shader_object_.data() + + interpolator_position); + for (uint32_t i = 0; i < interpolator_count; ++i) { + interpolators[i].semantic_name_ptr = semantic_offset; + } + semantic_offset += dxbc::AppendAlignedString(shader_object_, "TEXCOORD"); + } + if (in_reg_ps_point_coordinates_ != UINT32_MAX) { + auto& point_coordinates = *reinterpret_cast( + shader_object_.data() + point_coordinates_position); + point_coordinates.semantic_name_ptr = semantic_offset; + semantic_offset += dxbc::AppendAlignedString(shader_object_, "XESPRITETEXCOORD"); + } + { + auto& position = + *reinterpret_cast(shader_object_.data() + position_position); + position.semantic_name_ptr = semantic_offset; + } + semantic_offset += dxbc::AppendAlignedString(shader_object_, "SV_Position"); + { + auto& is_front_face = *reinterpret_cast(shader_object_.data() + + is_front_face_position); + is_front_face.semantic_name_ptr = semantic_offset; + } + semantic_offset += dxbc::AppendAlignedString(shader_object_, "SV_IsFrontFace"); + if (sample_index_position != SIZE_MAX) { + { + auto& sample_index = *reinterpret_cast(shader_object_.data() + + sample_index_position); + sample_index.semantic_name_ptr = semantic_offset; + } + semantic_offset += dxbc::AppendAlignedString(shader_object_, "SV_SampleIndex"); + } + } + + // Header. + { + auto& header = *reinterpret_cast(shader_object_.data() + blob_position); + header.parameter_count = parameter_count; + header.parameter_info_ptr = sizeof(dxbc::Signature); + } +} + +void DxbcShaderTranslator::WritePatchConstantSignature() { + assert_true(IsDxbcDomainShader()); + // Because of shader_object_.resize(), pointers can't be kept persistently + // here! Resizing also zeroes the memory. + uint32_t blob_position = uint32_t(shader_object_.size()); + // Reserve space for the header. + shader_object_.resize(shader_object_.size() + sizeof(dxbc::Signature) / sizeof(uint32_t)); + uint32_t parameter_count = 0; + constexpr size_t kParameterDwords = sizeof(dxbc::SignatureParameter) / sizeof(uint32_t); + + // FXC always compiles with SV_TessFactor and SV_InsideTessFactor input, so + // this is required even if not referenced (HS and DS have very strict + // linkage, by the way, everything that HS outputs must be listed in DS + // inputs). + uint32_t tess_factor_edge_count = 0; + dxbc::Name tess_factor_edge_system_value = dxbc::Name::kUndefined; + uint32_t tess_factor_inside_count = 0; + dxbc::Name tess_factor_inside_system_value = dxbc::Name::kUndefined; + Shader::HostVertexShaderType host_vertex_shader_type = + GetDxbcShaderModification().vertex.host_vertex_shader_type; + switch (host_vertex_shader_type) { + case Shader::HostVertexShaderType::kTriangleDomainCPIndexed: + case Shader::HostVertexShaderType::kTriangleDomainPatchIndexed: + tess_factor_edge_count = 3; + tess_factor_edge_system_value = dxbc::Name::kFinalTriEdgeTessFactor; + tess_factor_inside_count = 1; + tess_factor_inside_system_value = dxbc::Name::kFinalTriInsideTessFactor; + break; + case Shader::HostVertexShaderType::kQuadDomainCPIndexed: + case Shader::HostVertexShaderType::kQuadDomainPatchIndexed: + tess_factor_edge_count = 4; + tess_factor_edge_system_value = dxbc::Name::kFinalQuadEdgeTessFactor; + tess_factor_inside_count = 2; + tess_factor_inside_system_value = dxbc::Name::kFinalQuadInsideTessFactor; + break; + default: + // TODO(Triang3l): Support line patches. + assert_unhandled_case(host_vertex_shader_type); + EmitTranslationError("Unsupported host vertex shader type in WritePatchConstantSignature"); + } + + // Edge tessellation factors (SV_TessFactor). + size_t tess_factor_edge_position = shader_object_.size(); + shader_object_.resize(shader_object_.size() + tess_factor_edge_count * kParameterDwords); + parameter_count += tess_factor_edge_count; + { + auto tess_factors_edge = reinterpret_cast(shader_object_.data() + + tess_factor_edge_position); + for (uint32_t i = 0; i < tess_factor_edge_count; ++i) { + dxbc::SignatureParameter& tess_factor_edge = tess_factors_edge[i]; + tess_factor_edge.semantic_index = i; + tess_factor_edge.system_value = tess_factor_edge_system_value; + tess_factor_edge.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + // Not using any of these, just assigning consecutive registers. + tess_factor_edge.register_index = i; + tess_factor_edge.mask = 0b0001; + } + } + + // Inside tessellation factors (SV_InsideTessFactor). + size_t tess_factor_inside_position = shader_object_.size(); + shader_object_.resize(shader_object_.size() + tess_factor_inside_count * kParameterDwords); + parameter_count += tess_factor_inside_count; + { + auto tess_factors_inside = reinterpret_cast( + shader_object_.data() + tess_factor_inside_position); + for (uint32_t i = 0; i < tess_factor_inside_count; ++i) { + dxbc::SignatureParameter& tess_factor_inside = tess_factors_inside[i]; + tess_factor_inside.semantic_index = i; + tess_factor_inside.system_value = tess_factor_inside_system_value; + tess_factor_inside.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + // Not using any of these, just assigning consecutive registers. + tess_factor_inside.register_index = tess_factor_edge_count + i; + tess_factor_inside.mask = 0b0001; + } + } + + // Semantic names. + uint32_t semantic_offset = uint32_t((shader_object_.size() - blob_position) * sizeof(uint32_t)); + { + auto tess_factors_edge = reinterpret_cast(shader_object_.data() + + tess_factor_edge_position); + for (uint32_t i = 0; i < tess_factor_edge_count; ++i) { + tess_factors_edge[i].semantic_name_ptr = semantic_offset; + } + } + semantic_offset += dxbc::AppendAlignedString(shader_object_, "SV_TessFactor"); + { + auto tess_factors_inside = reinterpret_cast( + shader_object_.data() + tess_factor_inside_position); + for (uint32_t i = 0; i < tess_factor_inside_count; ++i) { + tess_factors_inside[i].semantic_name_ptr = semantic_offset; + } + } + semantic_offset += dxbc::AppendAlignedString(shader_object_, "SV_InsideTessFactor"); + + // Header. + { + auto& header = *reinterpret_cast(shader_object_.data() + blob_position); + header.parameter_count = parameter_count; + header.parameter_info_ptr = sizeof(dxbc::Signature); + } +} + +void DxbcShaderTranslator::WriteOutputSignature() { + // Because of shader_object_.resize(), pointers can't be kept persistently + // here! Resizing also zeroes the memory. + uint32_t blob_position = uint32_t(shader_object_.size()); + // Reserve space for the header. + shader_object_.resize(shader_object_.size() + sizeof(dxbc::Signature) / sizeof(uint32_t)); + uint32_t parameter_count = 0; + constexpr size_t kParameterDwords = sizeof(dxbc::SignatureParameter) / sizeof(uint32_t); + + Modification shader_modification = GetDxbcShaderModification(); + + if (is_vertex_shader()) { + // Intepolators (TEXCOORD#). + size_t interpolator_position = shader_object_.size(); + uint32_t interpolator_count = rex::bit_count(GetModificationInterpolatorMask()); + shader_object_.resize(shader_object_.size() + interpolator_count * kParameterDwords); + parameter_count += interpolator_count; + { + auto interpolators = reinterpret_cast(shader_object_.data() + + interpolator_position); + for (uint32_t i = 0; i < interpolator_count; ++i) { + dxbc::SignatureParameter& interpolator = interpolators[i]; + interpolator.semantic_index = i; + interpolator.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + interpolator.register_index = out_reg_vs_interpolators_ + i; + interpolator.mask = 0b1111; + } + } + + // Position (SV_Position). + size_t position_position = shader_object_.size(); + shader_object_.resize(shader_object_.size() + kParameterDwords); + ++parameter_count; + { + auto& position = + *reinterpret_cast(shader_object_.data() + position_position); + position.system_value = dxbc::Name::kPosition; + position.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + position.register_index = out_reg_vs_position_; + position.mask = 0b1111; + } + + // Clip (SV_ClipDistance) and cull (SV_CullDistance) distances. + size_t clip_and_cull_distance_position = shader_object_.size(); + uint32_t clip_distance_count = shader_modification.GetVertexClipDistanceCount(); + uint32_t cull_distance_count = shader_modification.GetVertexCullDistanceCount(); + uint32_t clip_and_cull_distance_count = clip_distance_count + cull_distance_count; + uint32_t clip_distance_parameter_count = 0; + uint32_t cull_distance_parameter_count = 0; + for (uint32_t i = 0; i < clip_and_cull_distance_count; i += 4) { + uint32_t clip_cull_distance_register = out_reg_vs_clip_cull_distances_ + (i >> 2); + if (i < clip_distance_count) { + shader_object_.resize(shader_object_.size() + kParameterDwords); + ++parameter_count; + { + auto& clip_distance = *reinterpret_cast( + shader_object_.data() + (shader_object_.size() - kParameterDwords)); + clip_distance.semantic_index = clip_distance_parameter_count; + clip_distance.system_value = dxbc::Name::kClipDistance; + clip_distance.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + clip_distance.register_index = clip_cull_distance_register; + uint8_t clip_distance_mask = + (UINT8_C(1) << std::min(clip_distance_count - i, UINT32_C(4))) - 1; + clip_distance.mask = clip_distance_mask; + clip_distance.never_writes_mask = clip_distance_mask ^ 0b1111; + } + ++clip_distance_parameter_count; + } + if (cull_distance_count && i + 4 > clip_distance_count) { + shader_object_.resize(shader_object_.size() + kParameterDwords); + ++parameter_count; + { + auto& cull_distance = *reinterpret_cast( + shader_object_.data() + (shader_object_.size() - kParameterDwords)); + cull_distance.semantic_index = cull_distance_parameter_count; + cull_distance.system_value = dxbc::Name::kCullDistance; + cull_distance.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + cull_distance.register_index = clip_cull_distance_register; + uint8_t cull_distance_mask = + (UINT8_C(1) << std::min(cull_distance_count - i, UINT32_C(4))) - 1; + if (i < clip_distance_count) { + cull_distance_mask &= ~((UINT8_C(1) << (clip_distance_count - i)) - 1); + } + cull_distance.mask = cull_distance_mask; + cull_distance.never_writes_mask = cull_distance_mask ^ 0b1111; + } + ++cull_distance_parameter_count; + } + } + + // Point size (XEPSIZE). Always used because reset to -1. + size_t point_size_position = shader_object_.size(); + if (out_reg_vs_point_size_ != UINT32_MAX) { + shader_object_.resize(shader_object_.size() + kParameterDwords); + ++parameter_count; + { + auto& point_size = *reinterpret_cast(shader_object_.data() + + point_size_position); + point_size.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + point_size.register_index = out_reg_vs_point_size_; + point_size.mask = 0b0001; + point_size.never_writes_mask = 0b1110; + } + } + + // Semantic names. + uint32_t semantic_offset = uint32_t((shader_object_.size() - blob_position) * sizeof(uint32_t)); + if (interpolator_count) { + { + auto interpolators = reinterpret_cast(shader_object_.data() + + interpolator_position); + for (uint32_t i = 0; i < interpolator_count; ++i) { + interpolators[i].semantic_name_ptr = semantic_offset; + } + } + semantic_offset += dxbc::AppendAlignedString(shader_object_, "TEXCOORD"); + } + { + auto& position = + *reinterpret_cast(shader_object_.data() + position_position); + position.semantic_name_ptr = semantic_offset; + } + semantic_offset += dxbc::AppendAlignedString(shader_object_, "SV_Position"); + if (clip_distance_parameter_count) { + { + auto clip_distances = reinterpret_cast( + shader_object_.data() + clip_and_cull_distance_position); + for (uint32_t i = 0; i < clip_distance_parameter_count; ++i) { + clip_distances[i].semantic_name_ptr = semantic_offset; + } + } + semantic_offset += dxbc::AppendAlignedString(shader_object_, "SV_ClipDistance"); + } + if (cull_distance_parameter_count) { + { + auto cull_distances = reinterpret_cast( + shader_object_.data() + clip_and_cull_distance_position) + + clip_distance_parameter_count; + for (uint32_t i = 0; i < cull_distance_parameter_count; ++i) { + cull_distances[i].semantic_name_ptr = semantic_offset; + } + } + semantic_offset += dxbc::AppendAlignedString(shader_object_, "SV_CullDistance"); + } + if (out_reg_vs_point_size_ != UINT32_MAX) { + { + auto& point_size = *reinterpret_cast(shader_object_.data() + + point_size_position); + point_size.semantic_name_ptr = semantic_offset; + } + semantic_offset += dxbc::AppendAlignedString(shader_object_, "XEPSIZE"); + } + } else if (is_pixel_shader()) { + if (!edram_rov_used_) { + uint32_t color_targets_written = current_shader().writes_color_targets(); + + // Color render targets (SV_Target#). + size_t target_position = SIZE_MAX; + uint32_t color_targets_written_count = rex::bit_count(color_targets_written); + if (color_targets_written) { + target_position = shader_object_.size(); + shader_object_.resize(shader_object_.size() + + color_targets_written_count * kParameterDwords); + parameter_count += color_targets_written_count; + auto targets = + reinterpret_cast(shader_object_.data() + target_position); + uint32_t target_index = 0; + for (uint32_t i = 0; i < xenos::kMaxColorRenderTargets; ++i) { + if (!(color_targets_written & (uint32_t(1) << i))) { + continue; + } + dxbc::SignatureParameter& target = targets[target_index++]; + target.semantic_index = i; + target.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + target.register_index = i; + target.mask = 0b1111; + } + } + + // Coverage output for alpha to mask (SV_Coverage). + size_t coverage_position = SIZE_MAX; + if ((color_targets_written & 0b1) && !IsForceEarlyDepthStencilGlobalFlagEnabled()) { + coverage_position = shader_object_.size(); + shader_object_.resize(shader_object_.size() + kParameterDwords); + ++parameter_count; + auto& coverage = + *reinterpret_cast(shader_object_.data() + coverage_position); + coverage.component_type = dxbc::SignatureRegisterComponentType::kUInt32; + coverage.register_index = UINT32_MAX; + coverage.mask = 0b0001; + coverage.never_writes_mask = 0b1110; + } + + // Depth (SV_Depth or SV_DepthLessEqual). + size_t depth_position = SIZE_MAX; + if (current_shader().writes_depth() || DSV_IsWritingFloat24Depth()) { + depth_position = shader_object_.size(); + shader_object_.resize(shader_object_.size() + kParameterDwords); + ++parameter_count; + auto& depth = + *reinterpret_cast(shader_object_.data() + depth_position); + depth.component_type = dxbc::SignatureRegisterComponentType::kFloat32; + depth.register_index = UINT32_MAX; + depth.mask = 0b0001; + depth.never_writes_mask = 0b1110; + } + + // Semantic names. + uint32_t semantic_offset = + uint32_t((shader_object_.size() - blob_position) * sizeof(uint32_t)); + if (target_position != SIZE_MAX) { + { + auto targets = + reinterpret_cast(shader_object_.data() + target_position); + for (uint32_t i = 0; i < color_targets_written_count; ++i) { + targets[i].semantic_name_ptr = semantic_offset; + } + } + semantic_offset += dxbc::AppendAlignedString(shader_object_, "SV_Target"); + } + if (coverage_position != SIZE_MAX) { + { + auto& coverage = *reinterpret_cast(shader_object_.data() + + coverage_position); + coverage.semantic_name_ptr = semantic_offset; + } + semantic_offset += dxbc::AppendAlignedString(shader_object_, "SV_Coverage"); + } + if (depth_position != SIZE_MAX) { + { + auto& depth = + *reinterpret_cast(shader_object_.data() + depth_position); + depth.semantic_name_ptr = semantic_offset; + } + const char* depth_semantic_name; + if (!current_shader().writes_depth() && + shader_modification.pixel.depth_stencil_mode == + Modification::DepthStencilMode::kFloat24Truncating) { + depth_semantic_name = "SV_DepthLessEqual"; + } else { + depth_semantic_name = "SV_Depth"; + } + semantic_offset += dxbc::AppendAlignedString(shader_object_, depth_semantic_name); + } + } + } + + // Header. + { + auto& header = *reinterpret_cast(shader_object_.data() + blob_position); + header.parameter_count = parameter_count; + header.parameter_info_ptr = sizeof(dxbc::Signature); + } +} + +void DxbcShaderTranslator::WriteShaderCode() { + uint32_t blob_position_dwords = uint32_t(shader_object_.size()); + + dxbc::ProgramType program_type; + if (IsDxbcVertexShader()) { + program_type = dxbc::ProgramType::kVertexShader; + } else if (IsDxbcDomainShader()) { + program_type = dxbc::ProgramType::kDomainShader; + } else { + assert_true(is_pixel_shader()); + program_type = dxbc::ProgramType::kPixelShader; + } + shader_object_.push_back(dxbc::VersionToken(program_type, 5, 1)); + // Reserve space for the length token. + shader_object_.push_back(0); + + Modification shader_modification = GetDxbcShaderModification(); + + uint32_t control_point_count = 1; + if (IsDxbcDomainShader()) { + dxbc::TessellatorDomain tessellator_domain = dxbc::TessellatorDomain::kTriangle; + switch (shader_modification.vertex.host_vertex_shader_type) { + case Shader::HostVertexShaderType::kTriangleDomainCPIndexed: + control_point_count = 3; + tessellator_domain = dxbc::TessellatorDomain::kTriangle; + break; + case Shader::HostVertexShaderType::kTriangleDomainPatchIndexed: + control_point_count = 1; + tessellator_domain = dxbc::TessellatorDomain::kTriangle; + break; + case Shader::HostVertexShaderType::kQuadDomainCPIndexed: + control_point_count = 4; + tessellator_domain = dxbc::TessellatorDomain::kQuad; + break; + case Shader::HostVertexShaderType::kQuadDomainPatchIndexed: + control_point_count = 1; + tessellator_domain = dxbc::TessellatorDomain::kQuad; + break; + default: + // TODO(Triang3l): Support line patches. + assert_unhandled_case(shader_modification.vertex.host_vertex_shader_type); + EmitTranslationError("Unsupported host vertex shader type in WriteShaderCode"); + } + ao_.OpDclInputControlPointCount(control_point_count); + ao_.OpDclTessDomain(tessellator_domain); + } + + // Don't allow refactoring when converting to native code to maintain position + // invariance (needed even in pixel shaders for oDepth invariance). + bool global_flag_force_early_depth_stencil = IsForceEarlyDepthStencilGlobalFlagEnabled(); + ao_.OpDclGlobalFlags( + global_flag_force_early_depth_stencil ? dxbc::kGlobalFlagForceEarlyDepthStencil : 0); + + // Constant buffers, from most frequenly accessed to least frequently accessed + // (the order is a hint to the driver according to the DXBC header). + if (cbuffer_index_float_constants_ != kBindingIndexUnallocated) { + const Shader::ConstantRegisterMap& constant_register_map = + current_shader().constant_register_map(); + assert_not_zero(constant_register_map.float_count); + ao_.OpDclConstantBuffer(dxbc::Src::CB(dxbc::Src::Dcl, cbuffer_index_float_constants_, + uint32_t(CbufferRegister::kFloatConstants), + uint32_t(CbufferRegister::kFloatConstants)), + constant_register_map.float_count, + constant_register_map.float_dynamic_addressing + ? dxbc::ConstantBufferAccessPattern::kDynamicIndexed + : dxbc::ConstantBufferAccessPattern::kImmediateIndexed); + } + if (cbuffer_index_system_constants_ != kBindingIndexUnallocated) { + ao_.OpDclConstantBuffer(dxbc::Src::CB(dxbc::Src::Dcl, cbuffer_index_system_constants_, + uint32_t(CbufferRegister::kSystemConstants), + uint32_t(CbufferRegister::kSystemConstants)), + (sizeof(SystemConstants) + 15) >> 4); + } + if (cbuffer_index_fetch_constants_ != kBindingIndexUnallocated) { + ao_.OpDclConstantBuffer(dxbc::Src::CB(dxbc::Src::Dcl, cbuffer_index_fetch_constants_, + uint32_t(CbufferRegister::kFetchConstants), + uint32_t(CbufferRegister::kFetchConstants)), + 48); + } + if (cbuffer_index_descriptor_indices_ != kBindingIndexUnallocated) { + assert_not_zero(GetBindlessResourceCount()); + ao_.OpDclConstantBuffer(dxbc::Src::CB(dxbc::Src::Dcl, cbuffer_index_descriptor_indices_, + uint32_t(CbufferRegister::kDescriptorIndices), + uint32_t(CbufferRegister::kDescriptorIndices)), + (GetBindlessResourceCount() + 3) >> 2); + } + if (cbuffer_index_bool_loop_constants_ != kBindingIndexUnallocated) { + ao_.OpDclConstantBuffer(dxbc::Src::CB(dxbc::Src::Dcl, cbuffer_index_bool_loop_constants_, + uint32_t(CbufferRegister::kBoolLoopConstants), + uint32_t(CbufferRegister::kBoolLoopConstants)), + 2 + 8); + } + + // Samplers. + if (!sampler_bindings_.empty()) { + if (bindless_resources_used_) { + // Bindless sampler heap. + ao_.OpDclSampler(dxbc::Src::S(dxbc::Src::Dcl, 0, 0, UINT32_MAX)); + } else { + // Bindful samplers. + for (uint32_t i = 0; i < uint32_t(sampler_bindings_.size()); ++i) { + const SamplerBinding& sampler_binding = sampler_bindings_[i]; + ao_.OpDclSampler(dxbc::Src::S(dxbc::Src::Dcl, i, i, i)); + } + } + } + + // Shader resource views, sorted by binding index. + for (uint32_t i = 0; i < srv_count_; ++i) { + if (i == srv_index_shared_memory_) { + // Shared memory ByteAddressBuffer. + ao_.OpDclResourceRaw(dxbc::Src::T(dxbc::Src::Dcl, srv_index_shared_memory_, + uint32_t(SRVMainRegister::kSharedMemory), + uint32_t(SRVMainRegister::kSharedMemory)), + uint32_t(SRVSpace::kMain)); + } else { + // Texture or texture heap. + dxbc::ResourceDimension texture_dimension; + uint32_t texture_register_lower_bound, texture_register_upper_bound; + SRVSpace texture_register_space; + if (bindless_resources_used_) { + // Bindless texture heap. + texture_register_lower_bound = 0; + texture_register_upper_bound = UINT32_MAX; + if (i == srv_index_bindless_textures_3d_) { + texture_dimension = dxbc::ResourceDimension::kTexture3D; + texture_register_space = SRVSpace::kBindlessTextures3D; + } else if (i == srv_index_bindless_textures_cube_) { + texture_dimension = dxbc::ResourceDimension::kTextureCube; + texture_register_space = SRVSpace::kBindlessTexturesCube; + } else { + assert_true(i == srv_index_bindless_textures_2d_); + texture_dimension = dxbc::ResourceDimension::kTexture2DArray; + texture_register_space = SRVSpace::kBindlessTextures2DArray; + } + } else { + // Bindful texture. + auto it = texture_bindings_for_bindful_srv_indices_.find(i); + assert_true(it != texture_bindings_for_bindful_srv_indices_.end()); + uint32_t texture_binding_index = it->second; + const TextureBinding& texture_binding = texture_bindings_[texture_binding_index]; + switch (texture_binding.dimension) { + case xenos::FetchOpDimension::k3DOrStacked: + texture_dimension = dxbc::ResourceDimension::kTexture3D; + break; + case xenos::FetchOpDimension::kCube: + texture_dimension = dxbc::ResourceDimension::kTextureCube; + break; + default: + assert_true(texture_binding.dimension == xenos::FetchOpDimension::k2D); + texture_dimension = dxbc::ResourceDimension::kTexture2DArray; + } + texture_register_lower_bound = + uint32_t(SRVMainRegister::kBindfulTexturesStart) + texture_binding_index; + texture_register_upper_bound = texture_register_lower_bound; + texture_register_space = SRVSpace::kMain; + } + ao_.OpDclResource(texture_dimension, + dxbc::ResourceReturnTypeX4Token(dxbc::ResourceReturnType::kFloat), + dxbc::Src::T(dxbc::Src::Dcl, i, texture_register_lower_bound, + texture_register_upper_bound), + uint32_t(texture_register_space)); + } + } + + // Unordered access views, sorted by binding index. + for (uint32_t i = 0; i < uav_count_; ++i) { + if (i == uav_index_shared_memory_) { + // Shared memory RWByteAddressBuffer. + if (!is_pixel_shader()) { + shader_feature_info_.feature_flags[0] |= dxbc::kShaderFeature0_UAVsAtEveryStage; + } + ao_.OpDclUnorderedAccessViewRaw(0, dxbc::Src::U(dxbc::Src::Dcl, uav_index_shared_memory_, + uint32_t(UAVRegister::kSharedMemory), + uint32_t(UAVRegister::kSharedMemory))); + } else if (i == uav_index_edram_) { + // EDRAM buffer R32_UINT rasterizer-ordered view. + shader_feature_info_.feature_flags[0] |= dxbc::kShaderFeature0_ROVs; + ao_.OpDclUnorderedAccessViewTyped( + dxbc::ResourceDimension::kBuffer, dxbc::kUAVFlagRasterizerOrderedAccess, + dxbc::ResourceReturnTypeX4Token(dxbc::ResourceReturnType::kUInt), + dxbc::Src::U(dxbc::Src::Dcl, uav_index_edram_, uint32_t(UAVRegister::kEdram), + uint32_t(UAVRegister::kEdram))); + } else { + assert_unhandled_case(i); + } + } + + // Inputs and outputs. + if (is_vertex_shader()) { + if (IsDxbcDomainShader()) { + if (in_domain_location_used_) { + // Domain location input. + ao_.OpDclInput(dxbc::Dest::VDomain(in_domain_location_used_)); + } + if (in_control_point_index_used_) { + ao_.OpDclInput( + dxbc::Dest::VICP(control_point_count, kInRegisterDSControlPointIndex, 0b0001)); + } + } else { + if (register_count()) { + // Unswapped vertex index input (only X component). + ao_.OpDclInputSGV(dxbc::Dest::V1D(kInRegisterVSVertexIndex, 0b0001), dxbc::Name::kVertexID); + } + } + // Interpolator output. + uint32_t interpolator_count = rex::bit_count(GetModificationInterpolatorMask()); + for (uint32_t i = 0; i < interpolator_count; ++i) { + ao_.OpDclOutput(dxbc::Dest::O(out_reg_vs_interpolators_ + i)); + } + // Position output. + ao_.OpDclOutputSIV(dxbc::Dest::O(out_reg_vs_position_), dxbc::Name::kPosition); + // Clip and cull distance outputs. + uint32_t clip_distance_count = shader_modification.GetVertexClipDistanceCount(); + uint32_t cull_distance_count = shader_modification.GetVertexCullDistanceCount(); + uint32_t clip_and_cull_distance_count = clip_distance_count + cull_distance_count; + for (uint32_t i = 0; i < clip_and_cull_distance_count; i += 4) { + if (i < clip_distance_count) { + ao_.OpDclOutputSIV( + dxbc::Dest::O(out_reg_vs_clip_cull_distances_ + (i >> 2), + (UINT32_C(1) << std::min(clip_distance_count - i, UINT32_C(4))) - 1), + dxbc::Name::kClipDistance); + } + if (cull_distance_count && i + 4 > clip_distance_count) { + uint32_t cull_distance_mask = + (UINT32_C(1) << std::min(clip_and_cull_distance_count - i, UINT32_C(4))) - 1; + if (i < clip_distance_count) { + cull_distance_mask &= ~((UINT32_C(1) << (clip_distance_count - i)) - 1); + } + ao_.OpDclOutputSIV( + dxbc::Dest::O(out_reg_vs_clip_cull_distances_ + (i >> 2), cull_distance_mask), + dxbc::Name::kCullDistance); + } + } + // Point size output. + if (out_reg_vs_point_size_ != UINT32_MAX) { + ao_.OpDclOutput(dxbc::Dest::O(out_reg_vs_point_size_, 0b0001)); + } + } else if (is_pixel_shader()) { + bool is_writing_float24_depth = DSV_IsWritingFloat24Depth(); + bool shader_writes_depth = current_shader().writes_depth(); + // Interpolator input. + uint32_t interpolator_register_index = in_reg_ps_interpolators_; + uint32_t interpolators_remaining = GetModificationInterpolatorMask(); + uint32_t interpolator_index; + while (rex::bit_scan_forward(interpolators_remaining, &interpolator_index)) { + interpolators_remaining &= ~(UINT32_C(1) << interpolator_index); + if (interpolator_index >= register_count()) { + break; + } + ao_.OpDclInputPS( + (shader_modification.pixel.interpolators_centroid & (UINT32_C(1) << interpolator_index)) + ? dxbc::InterpolationMode::kLinearCentroid + : dxbc::InterpolationMode::kLinear, + dxbc::Dest::V1D(interpolator_register_index)); + ++interpolator_register_index; + } + if (in_reg_ps_point_coordinates_ != UINT32_MAX) { + // Point coordinates input. + ao_.OpDclInputPS(dxbc::InterpolationMode::kLinear, + dxbc::Dest::V1D(in_reg_ps_point_coordinates_, 0b0011)); + } + if (in_position_used_) { + // Position input (XY needed for ps_param_gen, Z needed for non-ROV + // float24 conversion; the ROV depth code calculates the depth the from + // clip space Z and W with pull-mode per-sample interpolation instead). + // At the cost of possibility of MSAA with pixel-rate shading, need + // per-sample depth - otherwise intersections cannot be antialiased, and + // with SV_DepthLessEqual, per-sample (or centroid, but this isn't + // applicable here) position is mandatory. However, with depth output, on + // the guest, there's only one depth value for the whole pixel. + ao_.OpDclInputPSSIV((is_writing_float24_depth && !shader_writes_depth) + ? dxbc::InterpolationMode::kLinearNoPerspectiveSample + : dxbc::InterpolationMode::kLinearNoPerspective, + dxbc::Dest::V1D(in_reg_ps_position_, in_position_used_), + dxbc::Name::kPosition); + } + bool sample_rate_memexport = current_shader().memexport_eM_written() && IsSampleRate(); + // Sample-rate shading can't be done with UAV-only rendering (sample-rate + // shading is only needed for float24 depth conversion when using a float32 + // host depth buffer). + assert_false(sample_rate_memexport && edram_rov_used_); + uint32_t front_face_and_sample_index_mask = + uint32_t(in_front_face_used_) | (uint32_t(sample_rate_memexport) << 1); + if (front_face_and_sample_index_mask) { + // Is front face, sample index. + ao_.OpDclInputPSSGV( + dxbc::Dest::V1D(in_reg_ps_front_face_sample_index_, front_face_and_sample_index_mask), + dxbc::Name::kIsFrontFace); + } + if (edram_rov_used_) { + // Sample coverage input. + ao_.OpDclInput(dxbc::Dest::VCoverage()); + } else { + if (sample_rate_memexport) { + // Sample coverage input. + ao_.OpDclInput(dxbc::Dest::VCoverage()); + } + // Color output. + uint32_t color_targets_written = current_shader().writes_color_targets(); + for (uint32_t i = 0; i < xenos::kMaxColorRenderTargets; ++i) { + if (color_targets_written & (uint32_t(1) << i)) { + ao_.OpDclOutput(dxbc::Dest::O(i)); + } + } + // Coverage output for alpha to mask. + if ((color_targets_written & 0b1) && !global_flag_force_early_depth_stencil) { + ao_.OpDclOutput(dxbc::Dest::OMask()); + } + // Depth output. + if (is_writing_float24_depth || shader_writes_depth) { + if (!shader_writes_depth && GetDxbcShaderModification().pixel.depth_stencil_mode == + Modification::DepthStencilMode::kFloat24Truncating) { + ao_.OpDclOutput(dxbc::Dest::ODepthLE()); + } else { + ao_.OpDclOutput(dxbc::Dest::ODepth()); + } + } + } + } + + // Temporary registers - guest general-purpose registers if not using dynamic + // indexing and Xenia internal registers. + uint32_t temp_register_count = system_temp_count_max_; + if (!is_depth_only_pixel_shader_ && !current_shader().uses_register_dynamic_addressing()) { + temp_register_count += register_count(); + } + if (temp_register_count) { + ao_.OpDclTemps(temp_register_count); + } + // General-purpose registers if using dynamic indexing (x0). + if (!is_depth_only_pixel_shader_ && current_shader().uses_register_dynamic_addressing()) { + assert_not_zero(register_count()); + ao_.OpDclIndexableTemp(0, register_count(), 4); + } + + // Write the translated shader code. + size_t code_size_dwords = shader_code_.size(); + if (code_size_dwords) { + shader_object_.resize(shader_object_.size() + code_size_dwords); + std::memcpy(shader_object_.data() + (shader_object_.size() - code_size_dwords), + shader_code_.data(), code_size_dwords * sizeof(uint32_t)); + } + + // Write the length. + shader_object_[blob_position_dwords + 1] = uint32_t(shader_object_.size()) - blob_position_dwords; +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/shader/dxbc_translator_alu.cpp b/src/graphics/pipeline/shader/dxbc_translator_alu.cpp new file mode 100644 index 0000000..66834e5 --- /dev/null +++ b/src/graphics/pipeline/shader/dxbc_translator_alu.cpp @@ -0,0 +1,965 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2018 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include + +namespace rex::graphics { +using namespace ucode; + +void DxbcShaderTranslator::KillPixel(bool condition, const dxbc::Src& condition_src, + uint8_t memexport_eM_potentially_written_before) { + a_.OpIf(condition, condition_src); + // Perform outstanding memory exports before the invocation becomes inactive + // and UAV writes are disabled. + ExportToMemory(memexport_eM_potentially_written_before); + // Discard the pixel, but continue execution if other lanes in the quad need + // this lane for derivatives. The driver may also perform early exiting + // internally if all lanes are discarded if deemed beneficial. + a_.OpDiscard(true, dxbc::Src::LU(UINT32_MAX)); + if (edram_rov_used_) { + // Even though discarding disables all subsequent UAV/ROV writes, also skip + // as much of the Render Backend emulation logic as possible by setting the + // coverage and the mask of the written render targets to zero. + a_.OpMov(dxbc::Dest::R(system_temp_rov_params_, 0b0001), dxbc::Src::LU(0)); + } + a_.OpEndIf(); +} + +void DxbcShaderTranslator::ProcessVectorAluOperation( + const ParsedAluInstruction& instr, uint8_t memexport_eM_potentially_written_before, + uint32_t& result_swizzle, bool& predicate_written) { + result_swizzle = dxbc::Src::kXYZW; + predicate_written = false; + + uint32_t used_result_components = instr.vector_and_constant_result.GetUsedResultComponents(); + if (!used_result_components && + !ucode::GetAluVectorOpcodeInfo(instr.vector_opcode).changed_state) { + return; + } + + // Load operands. + // A small shortcut, operands of cube are the same, but swizzled. + uint32_t operand_count; + if (instr.vector_opcode == AluVectorOpcode::kCube) { + operand_count = 1; + } else { + operand_count = instr.vector_operand_count; + } + uint32_t operand_needed_components[3]; + for (uint32_t i = 0; i < operand_count; ++i) { + operand_needed_components[i] = ucode::GetAluVectorOpNeededSourceComponents( + instr.vector_opcode, i + 1, used_result_components); + } + // .zzxy - don't need duplicated Z. + if (instr.vector_opcode == AluVectorOpcode::kCube) { + operand_needed_components[0] &= 0b1101; + } + dxbc::Src operands[3]{dxbc::Src::LF(0.0f), dxbc::Src::LF(0.0f), dxbc::Src::LF(0.0f)}; + uint32_t operand_temps = 0; + for (uint32_t i = 0; i < operand_count; ++i) { + bool operand_temp_pushed = false; + operands[i] = + LoadOperand(instr.vector_operands[i], operand_needed_components[i], operand_temp_pushed); + operand_temps += uint32_t(operand_temp_pushed); + } + // Don't return without PopSystemTemp(operand_temps) from now on! + + dxbc::Dest per_component_dest(dxbc::Dest::R(system_temp_result_, used_result_components)); + switch (instr.vector_opcode) { + case AluVectorOpcode::kAdd: + a_.OpAdd(per_component_dest, operands[0], operands[1]); + break; + case AluVectorOpcode::kMul: + case AluVectorOpcode::kMad: { + // Not using DXBC mad to prevent fused multiply-add (mul followed by add + // may be optimized into non-fused mad by the driver in the identical + // operands case also). + a_.OpMul(per_component_dest, operands[0], operands[1]); + uint32_t multiplicands_different = + used_result_components & + ~instr.vector_operands[0].GetIdenticalComponents(instr.vector_operands[1]); + if (multiplicands_different) { + // Shader Model 3: +-0 or denormal * anything = +0. + uint32_t is_zero_temp = PushSystemTemp(); + a_.OpMin(dxbc::Dest::R(is_zero_temp, multiplicands_different), operands[0].Abs(), + operands[1].Abs()); + // min isn't required to flush denormals, eq is. + a_.OpEq(dxbc::Dest::R(is_zero_temp, multiplicands_different), dxbc::Src::R(is_zero_temp), + dxbc::Src::LF(0.0f)); + // Not replacing true `0 + term` with movc of the term because +0 + -0 + // should result in +0, not -0. + a_.OpMovC(dxbc::Dest::R(system_temp_result_, multiplicands_different), + dxbc::Src::R(is_zero_temp), dxbc::Src::LF(0.0f), + dxbc::Src::R(system_temp_result_)); + // Release is_zero_temp. + PopSystemTemp(); + } + if (instr.vector_opcode == AluVectorOpcode::kMad) { + a_.OpAdd(per_component_dest, dxbc::Src::R(system_temp_result_), operands[2]); + } + } break; + + case AluVectorOpcode::kMax: + case AluVectorOpcode::kMin: { + // max is commonly used as mov. + uint32_t identical = + instr.vector_operands[0].GetIdenticalComponents(instr.vector_operands[1]) & + used_result_components; + uint32_t different = used_result_components & ~identical; + if (different) { + // Shader Model 3 NaN behavior (a op b ? a : b, not fmax/fmin). + if (instr.vector_opcode == AluVectorOpcode::kMin) { + a_.OpLT(dxbc::Dest::R(system_temp_result_, different), operands[0], operands[1]); + } else { + a_.OpGE(dxbc::Dest::R(system_temp_result_, different), operands[0], operands[1]); + } + a_.OpMovC(dxbc::Dest::R(system_temp_result_, different), dxbc::Src::R(system_temp_result_), + operands[0], operands[1]); + } + if (identical) { + a_.OpMov(dxbc::Dest::R(system_temp_result_, identical), operands[0]); + } + } break; + + case AluVectorOpcode::kSeq: + a_.OpEq(per_component_dest, operands[0], operands[1]); + a_.OpAnd(per_component_dest, dxbc::Src::R(system_temp_result_), dxbc::Src::LF(1.0f)); + break; + case AluVectorOpcode::kSgt: + a_.OpLT(per_component_dest, operands[1], operands[0]); + a_.OpAnd(per_component_dest, dxbc::Src::R(system_temp_result_), dxbc::Src::LF(1.0f)); + break; + case AluVectorOpcode::kSge: + a_.OpGE(per_component_dest, operands[0], operands[1]); + a_.OpAnd(per_component_dest, dxbc::Src::R(system_temp_result_), dxbc::Src::LF(1.0f)); + break; + case AluVectorOpcode::kSne: + a_.OpNE(per_component_dest, operands[0], operands[1]); + a_.OpAnd(per_component_dest, dxbc::Src::R(system_temp_result_), dxbc::Src::LF(1.0f)); + break; + + case AluVectorOpcode::kFrc: + a_.OpFrc(per_component_dest, operands[0]); + break; + case AluVectorOpcode::kTrunc: + a_.OpRoundZ(per_component_dest, operands[0]); + break; + case AluVectorOpcode::kFloor: + a_.OpRoundNI(per_component_dest, operands[0]); + break; + + case AluVectorOpcode::kCndEq: + a_.OpEq(per_component_dest, operands[0], dxbc::Src::LF(0.0f)); + a_.OpMovC(per_component_dest, dxbc::Src::R(system_temp_result_), operands[1], operands[2]); + break; + case AluVectorOpcode::kCndGe: + a_.OpGE(per_component_dest, operands[0], dxbc::Src::LF(0.0f)); + a_.OpMovC(per_component_dest, dxbc::Src::R(system_temp_result_), operands[1], operands[2]); + break; + case AluVectorOpcode::kCndGt: + a_.OpLT(per_component_dest, dxbc::Src::LF(0.0f), operands[0]); + a_.OpMovC(per_component_dest, dxbc::Src::R(system_temp_result_), operands[1], operands[2]); + break; + + case AluVectorOpcode::kDp4: + case AluVectorOpcode::kDp3: + case AluVectorOpcode::kDp2Add: { + uint32_t component_count; + if (instr.vector_opcode == AluVectorOpcode::kDp2Add) { + component_count = 2; + } else if (instr.vector_opcode == AluVectorOpcode::kDp3) { + component_count = 3; + } else { + component_count = 4; + } + result_swizzle = dxbc::Src::kXXXX; + uint32_t different = + uint32_t((1 << component_count) - 1) & + ~instr.vector_operands[0].GetIdenticalComponents(instr.vector_operands[1]); + for (uint32_t i = 0; i < component_count; ++i) { + a_.OpMul(dxbc::Dest::R(system_temp_result_, i ? 0b0010 : 0b0001), + operands[0].SelectFromSwizzled(i), operands[1].SelectFromSwizzled(i)); + if ((different & (1 << i)) != 0) { + // Shader Model 3: +-0 or denormal * anything = +0 (also not replacing + // true `0 + term` with movc of the term because +0 + -0 should result + // in +0, not -0). + a_.OpMin(dxbc::Dest::R(system_temp_result_, 0b0100), + operands[0].SelectFromSwizzled(i).Abs(), + operands[1].SelectFromSwizzled(i).Abs()); + a_.OpEq(dxbc::Dest::R(system_temp_result_, 0b0100), + dxbc::Src::R(system_temp_result_, dxbc::Src::kZZZZ), dxbc::Src::LF(0.0f)); + a_.OpMovC(dxbc::Dest::R(system_temp_result_, i ? 0b0010 : 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kZZZZ), dxbc::Src::LF(0.0f), + dxbc::Src::R(system_temp_result_, i ? dxbc::Src::kYYYY : dxbc::Src::kXXXX)); + } + if (i) { + // Not using DXBC dp# to avoid fused multiply-add, PC GPUs are scalar + // as of 2020 anyway, and not using mad for the same reason (mul + // followed by add may be optimized into non-fused mad by the driver + // in the identical operands case also). + a_.OpAdd(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), + dxbc::Src::R(system_temp_result_, dxbc::Src::kYYYY)); + } + } + if (component_count == 2) { + a_.OpAdd(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), + operands[2].SelectFromSwizzled(0)); + } + } break; + + case AluVectorOpcode::kCube: { + // operands[0] is .z_xy. + // Result is T coordinate, S coordinate, 2 * major axis, face ID. + constexpr uint32_t kCubeX = 2, kCubeY = 3, kCubeZ = 0; + dxbc::Src cube_x_src(operands[0].SelectFromSwizzled(kCubeX)); + dxbc::Src cube_y_src(operands[0].SelectFromSwizzled(kCubeY)); + dxbc::Src cube_z_src(operands[0].SelectFromSwizzled(kCubeZ)); + // result.xy = bool2(abs(z) >= abs(x), abs(z) >= abs(y)) + a_.OpGE(dxbc::Dest::R(system_temp_result_, 0b0011), cube_z_src.Abs(), + operands[0].SwizzleSwizzled(kCubeX | (kCubeY << 2)).Abs()); + // result.x = abs(z) >= abs(x) && abs(z) >= abs(y) + a_.OpAnd(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), + dxbc::Src::R(system_temp_result_, dxbc::Src::kYYYY)); + dxbc::Dest tc_dest(dxbc::Dest::R(system_temp_result_, 0b0001)); + dxbc::Dest sc_dest(dxbc::Dest::R(system_temp_result_, 0b0010)); + dxbc::Dest ma_dest(dxbc::Dest::R(system_temp_result_, 0b0100)); + dxbc::Dest id_dest(dxbc::Dest::R(system_temp_result_, 0b1000)); + a_.OpIf(true, dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX)); + { + // Z is the major axis. + // z < 0 needed for SC and ID, but the last to use is ID. + uint32_t ma_neg_component = (used_result_components & 0b1000) ? 3 : 1; + if (used_result_components & 0b1010) { + a_.OpLT(dxbc::Dest::R(system_temp_result_, 1 << ma_neg_component), cube_z_src, + dxbc::Src::LF(0.0f)); + } + if (used_result_components & 0b0001) { + a_.OpMov(tc_dest, -cube_y_src); + } + if (used_result_components & 0b0010) { + a_.OpMovC(sc_dest, dxbc::Src::R(system_temp_result_).Select(ma_neg_component), + -cube_x_src, cube_x_src); + } + if (used_result_components & 0b0100) { + a_.OpMul(ma_dest, dxbc::Src::LF(2.0f), cube_z_src); + } + if (used_result_components & 0b1000) { + a_.OpMovC(id_dest, dxbc::Src::R(system_temp_result_).Select(ma_neg_component), + dxbc::Src::LF(5.0f), dxbc::Src::LF(4.0f)); + } + } + a_.OpElse(); + { + // result.x = abs(y) >= abs(x) + a_.OpGE(dxbc::Dest::R(system_temp_result_, 0b0001), cube_y_src.Abs(), cube_x_src.Abs()); + a_.OpIf(true, dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX)); + { + // Y is the major axis. + // y < 0 needed for TC and ID, but the last to use is ID. + uint32_t ma_neg_component = (used_result_components & 0b1000) ? 3 : 0; + if (used_result_components & 0b1001) { + a_.OpLT(dxbc::Dest::R(system_temp_result_, 1 << ma_neg_component), cube_y_src, + dxbc::Src::LF(0.0f)); + } + if (used_result_components & 0b0001) { + a_.OpMovC(tc_dest, dxbc::Src::R(system_temp_result_).Select(ma_neg_component), + -cube_z_src, cube_z_src); + } + if (used_result_components & 0b0010) { + a_.OpMov(sc_dest, cube_x_src); + } + if (used_result_components & 0b0100) { + a_.OpMul(ma_dest, dxbc::Src::LF(2.0f), cube_y_src); + } + if (used_result_components & 0b1000) { + a_.OpMovC(id_dest, dxbc::Src::R(system_temp_result_).Select(ma_neg_component), + dxbc::Src::LF(3.0f), dxbc::Src::LF(2.0f)); + } + } + a_.OpElse(); + { + // X is the major axis. + // x < 0 needed for SC and ID, but the last to use is ID. + uint32_t ma_neg_component = (used_result_components & 0b1000) ? 3 : 1; + if (used_result_components & 0b1010) { + a_.OpLT(dxbc::Dest::R(system_temp_result_, 1 << ma_neg_component), cube_x_src, + dxbc::Src::LF(0.0f)); + } + if (used_result_components & 0b0001) { + a_.OpMov(tc_dest, -cube_y_src); + } + if (used_result_components & 0b0010) { + a_.OpMovC(sc_dest, dxbc::Src::R(system_temp_result_).Select(ma_neg_component), + cube_z_src, -cube_z_src); + } + if (used_result_components & 0b0100) { + a_.OpMul(ma_dest, dxbc::Src::LF(2.0f), cube_x_src); + } + if (used_result_components & 0b1000) { + a_.OpAnd(id_dest, dxbc::Src::R(system_temp_result_).Select(ma_neg_component), + dxbc::Src::LF(1.0f)); + } + } + a_.OpEndIf(); + } + a_.OpEndIf(); + } break; + + case AluVectorOpcode::kMax4: { + result_swizzle = dxbc::Src::kXXXX; + // Find max of all different components of the first operand. + // FIXME(Triang3l): Not caring about NaN because no info about the + // correct order, just using SM4 max here, which replaces them with the + // non-NaN component (however, there's one nice thing about it is that it + // may be compiled into max3 + max on GCN). + uint32_t remaining_components = 0; + for (uint32_t i = 0; i < 4; ++i) { + remaining_components |= 1 << ((operands[0].swizzle_ >> (i * 2)) & 3); + } + uint32_t unique_component_0; + rex::bit_scan_forward(remaining_components, &unique_component_0); + remaining_components &= ~uint32_t(1 << unique_component_0); + if (remaining_components) { + uint32_t unique_component_1; + rex::bit_scan_forward(remaining_components, &unique_component_1); + remaining_components &= ~uint32_t(1 << unique_component_1); + a_.OpMax(dxbc::Dest::R(system_temp_result_, 0b0001), operands[0].Select(unique_component_0), + operands[0].Select(unique_component_1)); + while (remaining_components) { + uint32_t unique_component; + rex::bit_scan_forward(remaining_components, &unique_component); + remaining_components &= ~uint32_t(1 << unique_component); + a_.OpMax(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), + operands[0].Select(unique_component)); + } + } else { + a_.OpMov(dxbc::Dest::R(system_temp_result_, 0b0001), + operands[0].Select(unique_component_0)); + } + } break; + + case AluVectorOpcode::kSetpEqPush: + predicate_written = true; + result_swizzle = dxbc::Src::kXXXX; + // result.xy = src0.xw == 0.0 (x only if needed). + a_.OpEq(dxbc::Dest::R(system_temp_result_, used_result_components ? 0b0011 : 0b0010), + operands[0].SwizzleSwizzled(0b1100), dxbc::Src::LF(0.0f)); + // result.zw = src1.xw == 0.0 (z only if needed). + a_.OpEq(dxbc::Dest::R(system_temp_result_, used_result_components ? 0b1100 : 0b1000), + operands[1].SwizzleSwizzled(0b11000000), dxbc::Src::LF(0.0f)); + // p0 = src0.w == 0.0 && src1.w == 0.0 + a_.OpAnd(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b0100), + dxbc::Src::R(system_temp_result_, dxbc::Src::kYYYY), + dxbc::Src::R(system_temp_result_, dxbc::Src::kWWWW)); + if (used_result_components) { + // result = (src0.x == 0.0 && src1.x == 0.0) ? 0.0 : src0.x + 1.0 + a_.OpAnd(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), + dxbc::Src::R(system_temp_result_, dxbc::Src::kZZZZ)); + // If the condition is true, 1 will be added to make it 0. + a_.OpMovC(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), dxbc::Src::LF(-1.0f), + operands[0].SelectFromSwizzled(0)); + a_.OpAdd(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), dxbc::Src::LF(1.0f)); + } + break; + case AluVectorOpcode::kSetpNePush: + predicate_written = true; + result_swizzle = dxbc::Src::kXXXX; + // result.xy = src0.xw == 0.0 (x only if needed). + a_.OpEq(dxbc::Dest::R(system_temp_result_, used_result_components ? 0b0011 : 0b0010), + operands[0].SwizzleSwizzled(0b1100), dxbc::Src::LF(0.0f)); + // result.zw = src1.xw != 0.0 (z only if needed). + a_.OpNE(dxbc::Dest::R(system_temp_result_, used_result_components ? 0b1100 : 0b1000), + operands[1].SwizzleSwizzled(0b11000000), dxbc::Src::LF(0.0f)); + // p0 = src0.w == 0.0 && src1.w != 0.0 + a_.OpAnd(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b0100), + dxbc::Src::R(system_temp_result_, dxbc::Src::kYYYY), + dxbc::Src::R(system_temp_result_, dxbc::Src::kWWWW)); + if (used_result_components) { + // result = (src0.x == 0.0 && src1.x != 0.0) ? 0.0 : src0.x + 1.0 + a_.OpAnd(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), + dxbc::Src::R(system_temp_result_, dxbc::Src::kZZZZ)); + // If the condition is true, 1 will be added to make it 0. + a_.OpMovC(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), dxbc::Src::LF(-1.0f), + operands[0].SelectFromSwizzled(0)); + a_.OpAdd(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), dxbc::Src::LF(1.0f)); + } + break; + case AluVectorOpcode::kSetpGtPush: + predicate_written = true; + result_swizzle = dxbc::Src::kXXXX; + // result.xy = src0.xw == 0.0 (x only if needed). + a_.OpEq(dxbc::Dest::R(system_temp_result_, used_result_components ? 0b0011 : 0b0010), + operands[0].SwizzleSwizzled(0b1100), dxbc::Src::LF(0.0f)); + // result.zw = src1.xw > 0.0 (z only if needed). + a_.OpLT(dxbc::Dest::R(system_temp_result_, used_result_components ? 0b1100 : 0b1000), + dxbc::Src::LF(0.0f), operands[1].SwizzleSwizzled(0b11000000)); + // p0 = src0.w == 0.0 && src1.w > 0.0 + a_.OpAnd(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b0100), + dxbc::Src::R(system_temp_result_, dxbc::Src::kYYYY), + dxbc::Src::R(system_temp_result_, dxbc::Src::kWWWW)); + if (used_result_components) { + // result = (src0.x == 0.0 && src1.x > 0.0) ? 0.0 : src0.x + 1.0 + a_.OpAnd(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), + dxbc::Src::R(system_temp_result_, dxbc::Src::kZZZZ)); + // If the condition is true, 1 will be added to make it 0. + a_.OpMovC(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), dxbc::Src::LF(-1.0f), + operands[0].SelectFromSwizzled(0)); + a_.OpAdd(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), dxbc::Src::LF(1.0f)); + } + break; + case AluVectorOpcode::kSetpGePush: + predicate_written = true; + result_swizzle = dxbc::Src::kXXXX; + // result.xy = src0.xw == 0.0 (x only if needed). + a_.OpEq(dxbc::Dest::R(system_temp_result_, used_result_components ? 0b0011 : 0b0010), + operands[0].SwizzleSwizzled(0b1100), dxbc::Src::LF(0.0f)); + // result.zw = src1.xw >= 0.0 (z only if needed). + a_.OpGE(dxbc::Dest::R(system_temp_result_, used_result_components ? 0b1100 : 0b1000), + operands[1].SwizzleSwizzled(0b11000000), dxbc::Src::LF(0.0f)); + // p0 = src0.w == 0.0 && src1.w >= 0.0 + a_.OpAnd(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b0100), + dxbc::Src::R(system_temp_result_, dxbc::Src::kYYYY), + dxbc::Src::R(system_temp_result_, dxbc::Src::kWWWW)); + if (used_result_components) { + // result = (src0.x == 0.0 && src1.x >= 0.0) ? 0.0 : src0.x + 1.0 + a_.OpAnd(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), + dxbc::Src::R(system_temp_result_, dxbc::Src::kZZZZ)); + // If the condition is true, 1 will be added to make it 0. + a_.OpMovC(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), dxbc::Src::LF(-1.0f), + operands[0].SelectFromSwizzled(0)); + a_.OpAdd(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), dxbc::Src::LF(1.0f)); + } + break; + + case AluVectorOpcode::kKillEq: + result_swizzle = dxbc::Src::kXXXX; + a_.OpEq(dxbc::Dest::R(system_temp_result_), operands[0], operands[1]); + a_.OpOr(dxbc::Dest::R(system_temp_result_, 0b0011), dxbc::Src::R(system_temp_result_, 0b0100), + dxbc::Src::R(system_temp_result_, 0b1110)); + a_.OpOr(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), + dxbc::Src::R(system_temp_result_, dxbc::Src::kYYYY)); + KillPixel(true, dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), + memexport_eM_potentially_written_before); + if (used_result_components) { + a_.OpAnd(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), dxbc::Src::LF(1.0f)); + } + break; + case AluVectorOpcode::kKillGt: + result_swizzle = dxbc::Src::kXXXX; + a_.OpLT(dxbc::Dest::R(system_temp_result_), operands[1], operands[0]); + a_.OpOr(dxbc::Dest::R(system_temp_result_, 0b0011), dxbc::Src::R(system_temp_result_, 0b0100), + dxbc::Src::R(system_temp_result_, 0b1110)); + a_.OpOr(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), + dxbc::Src::R(system_temp_result_, dxbc::Src::kYYYY)); + KillPixel(true, dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), + memexport_eM_potentially_written_before); + if (used_result_components) { + a_.OpAnd(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), dxbc::Src::LF(1.0f)); + } + break; + case AluVectorOpcode::kKillGe: + result_swizzle = dxbc::Src::kXXXX; + a_.OpGE(dxbc::Dest::R(system_temp_result_), operands[0], operands[1]); + a_.OpOr(dxbc::Dest::R(system_temp_result_, 0b0011), dxbc::Src::R(system_temp_result_, 0b0100), + dxbc::Src::R(system_temp_result_, 0b1110)); + a_.OpOr(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), + dxbc::Src::R(system_temp_result_, dxbc::Src::kYYYY)); + KillPixel(true, dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), + memexport_eM_potentially_written_before); + if (used_result_components) { + a_.OpAnd(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), dxbc::Src::LF(1.0f)); + } + break; + case AluVectorOpcode::kKillNe: + result_swizzle = dxbc::Src::kXXXX; + a_.OpNE(dxbc::Dest::R(system_temp_result_), operands[0], operands[1]); + a_.OpOr(dxbc::Dest::R(system_temp_result_, 0b0011), dxbc::Src::R(system_temp_result_, 0b0100), + dxbc::Src::R(system_temp_result_, 0b1110)); + a_.OpOr(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), + dxbc::Src::R(system_temp_result_, dxbc::Src::kYYYY)); + KillPixel(true, dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), + memexport_eM_potentially_written_before); + if (used_result_components) { + a_.OpAnd(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX), dxbc::Src::LF(1.0f)); + } + break; + + case AluVectorOpcode::kDst: + if (used_result_components & 0b0001) { + a_.OpMov(dxbc::Dest::R(system_temp_result_, 0b0001), dxbc::Src::LF(1.0f)); + } + if (used_result_components & 0b0010) { + a_.OpMul(dxbc::Dest::R(system_temp_result_, 0b0010), operands[0].SelectFromSwizzled(1), + operands[1].SelectFromSwizzled(1)); + if (!(instr.vector_operands[0].GetIdenticalComponents(instr.vector_operands[1]) & 0b0010)) { + // Shader Model 3: +-0 or denormal * anything = +0. + a_.OpMin(dxbc::Dest::R(system_temp_result_, 0b0100), + operands[0].SelectFromSwizzled(1).Abs(), + operands[1].SelectFromSwizzled(1).Abs()); + // min isn't required to flush denormals, eq is. + a_.OpEq(dxbc::Dest::R(system_temp_result_, 0b0100), + dxbc::Src::R(system_temp_result_, dxbc::Src::kZZZZ), dxbc::Src::LF(0.0f)); + a_.OpMovC(dxbc::Dest::R(system_temp_result_, 0b0010), + dxbc::Src::R(system_temp_result_, dxbc::Src::kZZZZ), dxbc::Src::LF(0.0f), + dxbc::Src::R(system_temp_result_, dxbc::Src::kYYYY)); + } + } + if (used_result_components & 0b0100) { + a_.OpMov(dxbc::Dest::R(system_temp_result_, 0b0100), operands[0].SelectFromSwizzled(2)); + } + if (used_result_components & 0b1000) { + a_.OpMov(dxbc::Dest::R(system_temp_result_, 0b1000), operands[1].SelectFromSwizzled(2)); + } + break; + + case AluVectorOpcode::kMaxA: + a_.OpAdd(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b1000), operands[0].SelectFromSwizzled(3), + dxbc::Src::LF(0.5f)); + a_.OpRoundNI(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b1000), + dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kWWWW)); + a_.OpMax(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b1000), + dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kWWWW), dxbc::Src::LF(-256.0f)); + a_.OpMin(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b1000), + dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kWWWW), dxbc::Src::LF(255.0f)); + a_.OpFToI(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b1000), + dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kWWWW)); + if (used_result_components) { + uint32_t identical = + instr.vector_operands[0].GetIdenticalComponents(instr.vector_operands[1]) & + used_result_components; + uint32_t different = used_result_components & ~identical; + if (different) { + // Shader Model 3 NaN behavior (a >= b ? a : b, not fmax). + a_.OpGE(dxbc::Dest::R(system_temp_result_, different), operands[0], operands[1]); + a_.OpMovC(dxbc::Dest::R(system_temp_result_, different), + dxbc::Src::R(system_temp_result_), operands[0], operands[1]); + } + if (identical) { + a_.OpMov(dxbc::Dest::R(system_temp_result_, identical), operands[0]); + } + } + break; + + default: + assert_unhandled_case(instr.vector_opcode); + EmitTranslationError("Unknown ALU vector operation"); + a_.OpMov(dxbc::Dest::R(system_temp_result_), dxbc::Src::LF(0.0f)); + } + + PopSystemTemp(operand_temps); +} + +void DxbcShaderTranslator::ProcessScalarAluOperation( + const ParsedAluInstruction& instr, uint8_t memexport_eM_potentially_written_before, + bool& predicate_written) { + predicate_written = false; + + if (instr.scalar_opcode == ucode::AluScalarOpcode::kRetainPrev) { + return; + } + + // Load operands. + dxbc::Src operands_loaded[2]{dxbc::Src::LF(0.0f), dxbc::Src::LF(0.0f)}; + uint32_t operand_temps = 0; + for (uint32_t i = 0; i < instr.scalar_operand_count; ++i) { + bool operand_temp_pushed = false; + operands_loaded[i] = + LoadOperand(instr.scalar_operands[i], (1 << instr.scalar_operands[i].component_count) - 1, + operand_temp_pushed); + operand_temps += uint32_t(operand_temp_pushed); + } + // Don't return without PopSystemTemp(operand_temps) from now on! + dxbc::Src operand_0_a(operands_loaded[0].SelectFromSwizzled(0)); + dxbc::Src operand_0_b(operands_loaded[0].SelectFromSwizzled(1)); + dxbc::Src operand_1(operands_loaded[1].SelectFromSwizzled(0)); + + dxbc::Dest ps_dest(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b0001)); + dxbc::Src ps_src(dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kXXXX)); + switch (instr.scalar_opcode) { + case AluScalarOpcode::kAdds: + a_.OpAdd(ps_dest, operand_0_a, operand_0_b); + break; + case AluScalarOpcode::kAddsPrev: + a_.OpAdd(ps_dest, operand_0_a, ps_src); + break; + case AluScalarOpcode::kMuls: + a_.OpMul(ps_dest, operand_0_a, operand_0_b); + if (instr.scalar_operands[0].components[0] != instr.scalar_operands[0].components[1]) { + // Shader Model 3: +-0 or denormal * anything = +0. + uint32_t is_zero_temp = PushSystemTemp(); + a_.OpMin(dxbc::Dest::R(is_zero_temp, 0b0001), operand_0_a.Abs(), operand_0_b.Abs()); + // min isn't required to flush denormals, eq is. + a_.OpEq(dxbc::Dest::R(is_zero_temp, 0b0001), dxbc::Src::R(is_zero_temp, dxbc::Src::kXXXX), + dxbc::Src::LF(0.0f)); + a_.OpMovC(ps_dest, dxbc::Src::R(is_zero_temp, dxbc::Src::kXXXX), dxbc::Src::LF(0.0f), + ps_src); + // Release is_zero_temp. + PopSystemTemp(); + } + break; + case AluScalarOpcode::kMulsPrev: + case AluScalarOpcode::kMulsPrev2: { + uint32_t test_temp = PushSystemTemp(); + if (instr.scalar_opcode == AluScalarOpcode::kMulsPrev2) { + // Check if need to select the src0.a * ps case. + // ps != -FLT_MAX. + a_.OpNE(dxbc::Dest::R(test_temp, 0b0001), ps_src, dxbc::Src::LF(-FLT_MAX)); + // isfinite(ps), or |ps| <= FLT_MAX, or -|ps| >= -FLT_MAX, since + // -FLT_MAX is already loaded to an SGPR, this is also false if it's + // NaN. + a_.OpGE(dxbc::Dest::R(test_temp, 0b0010), -ps_src.Abs(), dxbc::Src::LF(-FLT_MAX)); + a_.OpAnd(dxbc::Dest::R(test_temp, 0b0001), dxbc::Src::R(test_temp, dxbc::Src::kXXXX), + dxbc::Src::R(test_temp, dxbc::Src::kYYYY)); + // isfinite(src0.b). + a_.OpGE(dxbc::Dest::R(test_temp, 0b0010), -operand_0_b.Abs(), dxbc::Src::LF(-FLT_MAX)); + a_.OpAnd(dxbc::Dest::R(test_temp, 0b0001), dxbc::Src::R(test_temp, dxbc::Src::kXXXX), + dxbc::Src::R(test_temp, dxbc::Src::kYYYY)); + // src0.b > 0 (need !(src0.b <= 0), but src0.b has already been checked + // for NaN). + a_.OpLT(dxbc::Dest::R(test_temp, 0b0010), dxbc::Src::LF(0.0f), operand_0_b); + a_.OpAnd(dxbc::Dest::R(test_temp, 0b0001), dxbc::Src::R(test_temp, dxbc::Src::kXXXX), + dxbc::Src::R(test_temp, dxbc::Src::kYYYY)); + a_.OpIf(true, dxbc::Src::R(test_temp, dxbc::Src::kXXXX)); + } + // Shader Model 3: +-0 or denormal * anything = +0. + a_.OpMin(dxbc::Dest::R(test_temp, 0b0001), operand_0_a.Abs(), ps_src.Abs()); + // min isn't required to flush denormals, eq is. + a_.OpEq(dxbc::Dest::R(test_temp, 0b0001), dxbc::Src::R(test_temp, dxbc::Src::kXXXX), + dxbc::Src::LF(0.0f)); + a_.OpMul(ps_dest, operand_0_a, ps_src); + a_.OpMovC(ps_dest, dxbc::Src::R(test_temp, dxbc::Src::kXXXX), dxbc::Src::LF(0.0f), ps_src); + if (instr.scalar_opcode == AluScalarOpcode::kMulsPrev2) { + a_.OpElse(); + a_.OpMov(ps_dest, dxbc::Src::LF(-FLT_MAX)); + a_.OpEndIf(); + } + // Release test_temp. + PopSystemTemp(); + } break; + + case AluScalarOpcode::kMaxs: + case AluScalarOpcode::kMins: + // max is commonly used as mov. + if (instr.scalar_operands[0].components[0] == instr.scalar_operands[0].components[1]) { + a_.OpMov(ps_dest, operand_0_a); + } else { + // Shader Model 3 NaN behavior (a op b ? a : b, not fmax/fmin). + if (instr.scalar_opcode == AluScalarOpcode::kMins) { + a_.OpLT(ps_dest, operand_0_a, operand_0_b); + } else { + a_.OpGE(ps_dest, operand_0_a, operand_0_b); + } + a_.OpMovC(ps_dest, ps_src, operand_0_a, operand_0_b); + } + break; + + case AluScalarOpcode::kSeqs: + a_.OpEq(ps_dest, operand_0_a, dxbc::Src::LF(0.0f)); + a_.OpAnd(ps_dest, ps_src, dxbc::Src::LF(1.0f)); + break; + case AluScalarOpcode::kSgts: + a_.OpLT(ps_dest, dxbc::Src::LF(0.0f), operand_0_a); + a_.OpAnd(ps_dest, ps_src, dxbc::Src::LF(1.0f)); + break; + case AluScalarOpcode::kSges: + a_.OpGE(ps_dest, operand_0_a, dxbc::Src::LF(0.0f)); + a_.OpAnd(ps_dest, ps_src, dxbc::Src::LF(1.0f)); + break; + case AluScalarOpcode::kSnes: + a_.OpNE(ps_dest, operand_0_a, dxbc::Src::LF(0.0f)); + a_.OpAnd(ps_dest, ps_src, dxbc::Src::LF(1.0f)); + break; + + case AluScalarOpcode::kFrcs: + a_.OpFrc(ps_dest, operand_0_a); + break; + case AluScalarOpcode::kTruncs: + a_.OpRoundZ(ps_dest, operand_0_a); + break; + case AluScalarOpcode::kFloors: + a_.OpRoundNI(ps_dest, operand_0_a); + break; + + case AluScalarOpcode::kExp: + a_.OpExp(ps_dest, operand_0_a); + break; + case AluScalarOpcode::kLogc: { + a_.OpLog(ps_dest, operand_0_a); + uint32_t is_neg_infinity_temp = PushSystemTemp(); + a_.OpEq(dxbc::Dest::R(is_neg_infinity_temp, 0b0001), ps_src, dxbc::Src::LF(-INFINITY)); + a_.OpMovC(ps_dest, dxbc::Src::R(is_neg_infinity_temp, dxbc::Src::kXXXX), + dxbc::Src::LF(-FLT_MAX), ps_src); + // Release is_neg_infinity_temp. + PopSystemTemp(); + } break; + case AluScalarOpcode::kLog: + a_.OpLog(ps_dest, operand_0_a); + break; + case AluScalarOpcode::kRcpc: + case AluScalarOpcode::kRsqc: { + if (instr.scalar_opcode == AluScalarOpcode::kRsqc) { + a_.OpRSq(ps_dest, operand_0_a); + } else { + a_.OpRcp(ps_dest, operand_0_a); + } + uint32_t is_infinity_temp = PushSystemTemp(); + a_.OpEq(dxbc::Dest::R(is_infinity_temp, 0b0001), ps_src.Abs(), dxbc::Src::LF(INFINITY)); + // If +-Infinity (0x7F800000 or 0xFF800000), add -1 (0xFFFFFFFF) to turn + // into +-FLT_MAX (0x7F7FFFFF or 0xFF7FFFFF). + a_.OpIAdd(ps_dest, ps_src, dxbc::Src::R(is_infinity_temp, dxbc::Src::kXXXX)); + // Release is_infinity_temp. + PopSystemTemp(); + } break; + case AluScalarOpcode::kRcpf: + case AluScalarOpcode::kRsqf: { + if (instr.scalar_opcode == AluScalarOpcode::kRsqf) { + a_.OpRSq(ps_dest, operand_0_a); + } else { + a_.OpRcp(ps_dest, operand_0_a); + } + uint32_t is_not_infinity_temp = PushSystemTemp(); + a_.OpNE(dxbc::Dest::R(is_not_infinity_temp, 0b0001), ps_src.Abs(), dxbc::Src::LF(INFINITY)); + // Keep the sign bit if infinity. + a_.OpOr(dxbc::Dest::R(is_not_infinity_temp, 0b0001), + dxbc::Src::R(is_not_infinity_temp, dxbc::Src::kXXXX), + dxbc::Src::LU(uint32_t(1) << 31)); + a_.OpAnd(ps_dest, ps_src, dxbc::Src::R(is_not_infinity_temp, dxbc::Src::kXXXX)); + // Release is_not_infinity_temp. + PopSystemTemp(); + } break; + case AluScalarOpcode::kRcp: + a_.OpRcp(ps_dest, operand_0_a); + break; + case AluScalarOpcode::kRsq: + a_.OpRSq(ps_dest, operand_0_a); + break; + + case AluScalarOpcode::kMaxAs: + case AluScalarOpcode::kMaxAsf: + if (instr.scalar_opcode == AluScalarOpcode::kMaxAsf) { + a_.OpRoundNI(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b1000), operand_0_a); + } else { + a_.OpAdd(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b1000), operand_0_a, dxbc::Src::LF(0.5f)); + a_.OpRoundNI(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b1000), + dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kWWWW)); + } + a_.OpMax(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b1000), + dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kWWWW), dxbc::Src::LF(-256.0f)); + a_.OpMin(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b1000), + dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kWWWW), dxbc::Src::LF(255.0f)); + a_.OpFToI(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b1000), + dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kWWWW)); + if (instr.scalar_operands[0].components[0] == instr.scalar_operands[0].components[1]) { + a_.OpMov(ps_dest, operand_0_a); + } else { + // Shader Model 3 NaN behavior (a >= b ? a : b, not fmax). + a_.OpGE(ps_dest, operand_0_a, operand_0_b); + a_.OpMovC(ps_dest, ps_src, operand_0_a, operand_0_b); + } + break; + + case AluScalarOpcode::kSubs: + a_.OpAdd(ps_dest, operand_0_a, -operand_0_b); + break; + case AluScalarOpcode::kSubsPrev: + a_.OpAdd(ps_dest, operand_0_a, -ps_src); + break; + + case AluScalarOpcode::kSetpEq: + predicate_written = true; + a_.OpEq(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b0100), operand_0_a, dxbc::Src::LF(0.0f)); + a_.OpMovC(ps_dest, dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kZZZZ), + dxbc::Src::LF(0.0f), dxbc::Src::LF(1.0f)); + break; + case AluScalarOpcode::kSetpNe: + predicate_written = true; + a_.OpNE(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b0100), operand_0_a, dxbc::Src::LF(0.0f)); + a_.OpMovC(ps_dest, dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kZZZZ), + dxbc::Src::LF(0.0f), dxbc::Src::LF(1.0f)); + break; + case AluScalarOpcode::kSetpGt: + predicate_written = true; + a_.OpLT(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b0100), dxbc::Src::LF(0.0f), operand_0_a); + a_.OpMovC(ps_dest, dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kZZZZ), + dxbc::Src::LF(0.0f), dxbc::Src::LF(1.0f)); + break; + case AluScalarOpcode::kSetpGe: + predicate_written = true; + a_.OpGE(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b0100), operand_0_a, dxbc::Src::LF(0.0f)); + a_.OpMovC(ps_dest, dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kZZZZ), + dxbc::Src::LF(0.0f), dxbc::Src::LF(1.0f)); + break; + case AluScalarOpcode::kSetpInv: + predicate_written = true; + // Calculate ps as if src0.a != 1.0 (the false predicate value case). + a_.OpEq(ps_dest, operand_0_a, dxbc::Src::LF(0.0f)); + a_.OpMovC(ps_dest, ps_src, dxbc::Src::LF(1.0f), operand_0_a); + // Set the predicate to src0.a == 1.0, and, if it's true, zero ps. + a_.OpEq(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b0100), operand_0_a, dxbc::Src::LF(1.0f)); + a_.OpMovC(ps_dest, dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kZZZZ), + dxbc::Src::LF(0.0f), ps_src); + break; + case AluScalarOpcode::kSetpPop: + predicate_written = true; + a_.OpAdd(ps_dest, operand_0_a, dxbc::Src::LF(-1.0f)); + a_.OpGE(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b0100), dxbc::Src::LF(0.0f), ps_src); + a_.OpMovC(ps_dest, dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kZZZZ), + dxbc::Src::LF(0.0f), ps_src); + break; + case AluScalarOpcode::kSetpClr: + predicate_written = true; + a_.OpMov(ps_dest, dxbc::Src::LF(FLT_MAX)); + a_.OpMov(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b0100), dxbc::Src::LU(0)); + break; + case AluScalarOpcode::kSetpRstr: + predicate_written = true; + a_.OpEq(dxbc::Dest::R(system_temp_ps_pc_p0_a0_, 0b0100), operand_0_a, dxbc::Src::LF(0.0f)); + // Just copying src0.a to ps (since it's set to 0 if it's 0) could work, + // but flush denormals and zero sign just for safety. + a_.OpMovC(ps_dest, dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kZZZZ), + dxbc::Src::LF(0.0f), operand_0_a); + break; + + case AluScalarOpcode::kKillsEq: + a_.OpEq(ps_dest, operand_0_a, dxbc::Src::LF(0.0f)); + KillPixel(true, ps_src, memexport_eM_potentially_written_before); + a_.OpAnd(ps_dest, ps_src, dxbc::Src::LF(1.0f)); + break; + case AluScalarOpcode::kKillsGt: + a_.OpLT(ps_dest, dxbc::Src::LF(0.0f), operand_0_a); + KillPixel(true, ps_src, memexport_eM_potentially_written_before); + a_.OpAnd(ps_dest, ps_src, dxbc::Src::LF(1.0f)); + break; + case AluScalarOpcode::kKillsGe: + a_.OpGE(ps_dest, operand_0_a, dxbc::Src::LF(0.0f)); + KillPixel(true, ps_src, memexport_eM_potentially_written_before); + a_.OpAnd(ps_dest, ps_src, dxbc::Src::LF(1.0f)); + break; + case AluScalarOpcode::kKillsNe: + a_.OpNE(ps_dest, operand_0_a, dxbc::Src::LF(0.0f)); + KillPixel(true, ps_src, memexport_eM_potentially_written_before); + a_.OpAnd(ps_dest, ps_src, dxbc::Src::LF(1.0f)); + break; + case AluScalarOpcode::kKillsOne: + a_.OpEq(ps_dest, operand_0_a, dxbc::Src::LF(1.0f)); + KillPixel(true, ps_src, memexport_eM_potentially_written_before); + a_.OpAnd(ps_dest, ps_src, dxbc::Src::LF(1.0f)); + break; + + case AluScalarOpcode::kSqrt: + a_.OpSqRt(ps_dest, operand_0_a); + break; + + case AluScalarOpcode::kMulsc0: + case AluScalarOpcode::kMulsc1: + a_.OpMul(ps_dest, operand_0_a, operand_1); + if (!(instr.scalar_operands[0].GetIdenticalComponents(instr.scalar_operands[1]) & 0b0001)) { + // Shader Model 3: +-0 or denormal * anything = +0. + uint32_t is_zero_temp = PushSystemTemp(); + a_.OpMin(dxbc::Dest::R(is_zero_temp, 0b0001), operand_0_a.Abs(), operand_1.Abs()); + // min isn't required to flush denormals, eq is. + a_.OpEq(dxbc::Dest::R(is_zero_temp, 0b0001), dxbc::Src::R(is_zero_temp, dxbc::Src::kXXXX), + dxbc::Src::LF(0.0f)); + a_.OpMovC(ps_dest, dxbc::Src::R(is_zero_temp, dxbc::Src::kXXXX), dxbc::Src::LF(0.0f), + ps_src); + // Release is_zero_temp. + PopSystemTemp(); + } + break; + case AluScalarOpcode::kAddsc0: + case AluScalarOpcode::kAddsc1: + a_.OpAdd(ps_dest, operand_0_a, operand_1); + break; + case AluScalarOpcode::kSubsc0: + case AluScalarOpcode::kSubsc1: + a_.OpAdd(ps_dest, operand_0_a, -operand_1); + break; + + case AluScalarOpcode::kSin: + a_.OpSinCos(ps_dest, dxbc::Dest::Null(), operand_0_a); + break; + case AluScalarOpcode::kCos: + a_.OpSinCos(dxbc::Dest::Null(), ps_dest, operand_0_a); + break; + + default: + assert_unhandled_case(instr.scalar_opcode); + EmitTranslationError("Unknown ALU scalar operation"); + a_.OpMov(ps_dest, dxbc::Src::LF(0.0f)); + } + + PopSystemTemp(operand_temps); +} + +void DxbcShaderTranslator::ProcessAluInstruction(const ParsedAluInstruction& instr, + uint8_t memexport_eM_potentially_written_before) { + if (instr.IsNop()) { + // Don't even disassemble or update predication. + return; + } + + if (emit_source_map_) { + instruction_disassembly_buffer_.Reset(); + instr.Disassemble(&instruction_disassembly_buffer_); + } + UpdateInstructionPredicationAndEmitDisassembly(instr.is_predicated, instr.predicate_condition); + + // Whether the instruction has changed the predicate, and it needs to be + // checked again later. + bool predicate_written_vector = false; + uint32_t vector_result_swizzle = dxbc::Src::kXYZW; + ProcessVectorAluOperation(instr, memexport_eM_potentially_written_before, vector_result_swizzle, + predicate_written_vector); + bool predicate_written_scalar = false; + ProcessScalarAluOperation(instr, memexport_eM_potentially_written_before, + predicate_written_scalar); + + StoreResult(instr.vector_and_constant_result, + dxbc::Src::R(system_temp_result_, vector_result_swizzle), + instr.GetMemExportStreamConstant() != UINT32_MAX); + StoreResult(instr.scalar_result, dxbc::Src::R(system_temp_ps_pc_p0_a0_, dxbc::Src::kXXXX)); + + if (predicate_written_vector || predicate_written_scalar) { + cf_exec_predicate_written_ = true; + CloseInstructionPredication(); + } +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/shader/dxbc_translator_fetch.cpp b/src/graphics/pipeline/shader/dxbc_translator_fetch.cpp new file mode 100644 index 0000000..31de175 --- /dev/null +++ b/src/graphics/pipeline/shader/dxbc_translator_fetch.cpp @@ -0,0 +1,1975 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(draw_resolution_scaled_texture_offsets, true, "GPU/Shader", + "Scale texture offsets with draw resolution"); + +namespace rex::graphics { +using namespace ucode; + +void DxbcShaderTranslator::ProcessVertexFetchInstruction( + const ParsedVertexFetchInstruction& instr) { + if (emit_source_map_) { + instruction_disassembly_buffer_.Reset(); + instr.Disassemble(&instruction_disassembly_buffer_); + } + UpdateInstructionPredicationAndEmitDisassembly(instr.is_predicated, instr.predicate_condition); + + uint32_t used_result_components = instr.result.GetUsedResultComponents(); + uint32_t needed_words = + xenos::GetVertexFormatNeededWords(instr.attributes.data_format, used_result_components); + // If this is vfetch_full, the address may still be needed for vfetch_mini - + // don't exit before calculating the address. + if (!needed_words && instr.is_mini_fetch) { + // Nothing to load - just constant 0/1 writes, or the swizzle includes only + // components that don't exist in the format (writing zero instead of them). + // Unpacking assumes at least some word is needed. + StoreResult(instr.result, dxbc::Src::LF(0.0f)); + return; + } + + // Create a 2-component dxbc::Src for the fetch constant (vf0 is in [0].xy of + // the fetch constants array, vf1 is in [0].zw, vf2 is in [1].xy). + if (cbuffer_index_fetch_constants_ == kBindingIndexUnallocated) { + cbuffer_index_fetch_constants_ = cbuffer_count_++; + } + dxbc::Src fetch_constant_src( + dxbc::Src::CB(cbuffer_index_fetch_constants_, uint32_t(CbufferRegister::kFetchConstants), + instr.operands[1].storage_index >> 1, + (instr.operands[1].storage_index & 1) ? 0b10101110 : 0b00000100)); + + // TODO(Triang3l): Verify the fetch constant type (that it's a vertex fetch, + // not a texture fetch), here instead of dropping draws with invalid vertex + // fetch constants on the CPU when proper bound checks are added - vfetch may + // be conditional, so fetch constants may also be used conditionally. + + // - Load the part of the byte address in the physical memory that is the same + // in vfetch_full and vfetch_mini to system_temp_grad_v_vfetch_address_.w + // (the index operand GPR must not be reloaded in vfetch_mini because it + // might have been overwritten previously, but that shouldn't have effect on + // vfetch_mini). + + dxbc::Src address_src(dxbc::Src::R(system_temp_grad_v_vfetch_address_, dxbc::Src::kWWWW)); + if (!instr.is_mini_fetch) { + dxbc::Dest address_dest(dxbc::Dest::R(system_temp_grad_v_vfetch_address_, 0b1000)); + if (instr.attributes.stride) { + // Convert the index to an integer by flooring or by rounding to the + // nearest (as floor(index + 0.5) because rounding to the nearest even + // makes no sense for addressing, both 1.5 and 2.5 would be 2). + { + bool index_operand_temp_pushed = false; + dxbc::Src index_operand(LoadOperand(instr.operands[0], 0b0001, index_operand_temp_pushed) + .SelectFromSwizzled(0)); + if (instr.attributes.is_index_rounded) { + a_.OpAdd(address_dest, index_operand, dxbc::Src::LF(0.5f)); + a_.OpRoundNI(address_dest, address_src); + } else { + a_.OpRoundNI(address_dest, index_operand); + } + if (index_operand_temp_pushed) { + PopSystemTemp(); + } + } + a_.OpFToI(address_dest, address_src); + // Extract the byte address from the fetch constant to + // system_temp_result_.w (which is not used yet). + a_.OpAnd(dxbc::Dest::R(system_temp_result_, 0b1000), fetch_constant_src.SelectFromSwizzled(0), + dxbc::Src::LU(~uint32_t(3))); + // Merge the index and the base address. + a_.OpIMAd(address_dest, address_src, + dxbc::Src::LU(instr.attributes.stride * sizeof(uint32_t)), + dxbc::Src::R(system_temp_result_, dxbc::Src::kWWWW)); + } else { + // Fetching from the same location - extract the byte address of the + // beginning of the buffer. + a_.OpAnd(address_dest, fetch_constant_src.SelectFromSwizzled(0), dxbc::Src::LU(~uint32_t(3))); + } + } + + if (!needed_words) { + // The vfetch_full address has been loaded for the subsequent vfetch_mini, + // but there's no data to load. + StoreResult(instr.result, dxbc::Src::LF(0.0f)); + return; + } + + dxbc::Dest address_temp_dest(dxbc::Dest::R(system_temp_result_, 0b1000)); + dxbc::Src address_temp_src(dxbc::Src::R(system_temp_result_, dxbc::Src::kWWWW)); + + // - From now on, if any additional offset must be applied to the + // `base + index * stride` part of the address, it must be done by writing + // to system_temp_result_.w (address_temp_dest) instead of + // system_temp_grad_v_vfetch_address_.w (since it must stay the same for the + // vfetch_full and all its vfetch_mini invocations), and changing + // address_src to address_temp_src afterwards. system_temp_result_.w can be + // used for this purpose safely because it won't be overwritten until the + // last dword is loaded (after which the address won't be needed anymore). + + // Add the word offset from the instruction (signed), plus the offset of the + // first needed word within the element. + uint32_t first_word_index; + rex::bit_scan_forward(needed_words, &first_word_index); + int32_t first_word_buffer_offset = instr.attributes.offset + int32_t(first_word_index); + if (first_word_buffer_offset) { + // Add the constant word offset. + a_.OpIAdd(address_temp_dest, address_src, + dxbc::Src::LI(first_word_buffer_offset * sizeof(uint32_t))); + address_src = address_temp_src; + } + + // - Load needed words to system_temp_result_, words 0, 1, 2, 3 to X, Y, Z, W + // respectively. + + // FIXME(Triang3l): Bound checking is not done here, but haven't encountered + // any games relying on out-of-bounds access. On Adreno 200 on Android (LG + // P705), however, words (not full elements) out of glBufferData bounds + // contain 0. + + // Loading the FXC way, Load4.xyw becomes Load2 and Load - would be a + // compromise between AMD, where there are load_dwordx2/3/4, and Nvidia, where + // a ByteAddressBuffer is more like an R32_UINT buffer. + + // Depending on whether the shared memory is bound as an SRV or as a UAV (if + // memexport is used), fetch from the appropriate binding. Extract whether + // shared memory is a UAV to system_temp_result_.x and check. In the `if`, put + // the more likely case (SRV), in the `else`, the less likely one (UAV). + a_.OpAnd(dxbc::Dest::R(system_temp_result_, 0b0001), LoadFlagsSystemConstant(), + dxbc::Src::LU(kSysFlag_SharedMemoryIsUAV)); + a_.OpIf(false, dxbc::Src::R(system_temp_result_, dxbc::Src::kXXXX)); + if (srv_index_shared_memory_ == kBindingIndexUnallocated) { + srv_index_shared_memory_ = srv_count_++; + } + if (uav_index_shared_memory_ == kBindingIndexUnallocated) { + uav_index_shared_memory_ = uav_count_++; + } + for (uint32_t i = 0; i < 2; ++i) { + if (i) { + a_.OpElse(); + } + dxbc::Src shared_memory_src( + i ? dxbc::Src::U(uav_index_shared_memory_, uint32_t(UAVRegister::kSharedMemory)) + : dxbc::Src::T(srv_index_shared_memory_, uint32_t(SRVMainRegister::kSharedMemory))); + uint32_t needed_words_remaining = needed_words; + uint32_t word_index_previous = first_word_index; + while (needed_words_remaining) { + uint32_t word_index; + rex::bit_scan_forward(needed_words_remaining, &word_index); + uint32_t word_count; + rex::bit_scan_forward(~(needed_words_remaining >> word_index), &word_count); + needed_words_remaining &= ~((uint32_t(1) << (word_index + word_count)) - uint32_t(1)); + if (word_index != word_index_previous) { + // Go to the word in the buffer. + a_.OpIAdd(address_temp_dest, address_src, + dxbc::Src::LU((word_index - word_index_previous) * sizeof(uint32_t))); + address_src = address_temp_src; + word_index_previous = word_index; + } + // Can ld_raw either to the first multiple components, or to any scalar + // component. + dxbc::Dest words_result_dest( + dxbc::Dest::R(system_temp_result_, ((1 << word_count) - 1) << word_index)); + if (!word_index || word_count == 1) { + // Read directly to system_temp_result_. + a_.OpLdRaw(words_result_dest, address_src, shared_memory_src); + } else { + // Read to the first components of a temporary register. + uint32_t load_temp = PushSystemTemp(); + a_.OpLdRaw(dxbc::Dest::R(load_temp, (1 << word_count) - 1), address_src, shared_memory_src); + // Copy to system_temp_result_. + a_.OpMov(words_result_dest, + dxbc::Src::R(load_temp, (dxbc::Src::kXYZW & ((1 << (word_count * 2)) - 1)) + << (word_index * 2))); + // Release load_temp. + PopSystemTemp(); + } + } + } + a_.OpEndIf(); + + dxbc::Src result_src(dxbc::Src::R(system_temp_result_)); + + // - Endian swap the words. + + { + uint32_t swap_temp = PushSystemTemp(); + + // Extract the endianness from the fetch constant. + uint32_t endian_temp, endian_temp_component; + if (needed_words == 0b1111) { + endian_temp = PushSystemTemp(); + endian_temp_component = 0; + } else { + endian_temp = swap_temp; + rex::bit_scan_forward(~needed_words, &endian_temp_component); + } + a_.OpAnd(dxbc::Dest::R(endian_temp, 1 << endian_temp_component), + fetch_constant_src.SelectFromSwizzled(1), dxbc::Src::LU(0b11)); + dxbc::Src endian_src(dxbc::Src::R(endian_temp).Select(endian_temp_component)); + + dxbc::Dest swap_temp_dest(dxbc::Dest::R(swap_temp, needed_words)); + dxbc::Src swap_temp_src(dxbc::Src::R(swap_temp)); + dxbc::Dest swap_result_dest(dxbc::Dest::R(system_temp_result_, needed_words)); + + // 8-in-16 or one half of 8-in-32. + a_.OpSwitch(endian_src); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::Endian128::k8in16))); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::Endian128::k8in32))); + // Temp = X0Z0. + a_.OpAnd(swap_temp_dest, result_src, dxbc::Src::LU(0x00FF00FF)); + // Result = YZW0. + a_.OpUShR(swap_result_dest, result_src, dxbc::Src::LU(8)); + // Result = Y0W0. + a_.OpAnd(swap_result_dest, result_src, dxbc::Src::LU(0x00FF00FF)); + // Result = YXWZ. + a_.OpUMAd(swap_result_dest, swap_temp_src, dxbc::Src::LU(256), result_src); + a_.OpBreak(); + a_.OpEndSwitch(); + + // 16-in-32 or another half of 8-in-32. + a_.OpSwitch(endian_src); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::Endian128::k8in32))); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::Endian128::k16in32))); + // Temp = ZW00. + a_.OpUShR(swap_temp_dest, result_src, dxbc::Src::LU(16)); + // Result = ZWXY. + a_.OpBFI(swap_result_dest, dxbc::Src::LU(16), dxbc::Src::LU(16), result_src, swap_temp_src); + a_.OpBreak(); + a_.OpEndSwitch(); + + // Release endian_temp (if allocated) and swap_temp. + PopSystemTemp((endian_temp != swap_temp) ? 2 : 1); + } + + // - Unpack the format. + + uint32_t used_format_components = + used_result_components & + ((1 << xenos::GetVertexFormatComponentCount(instr.attributes.data_format)) - 1); + dxbc::Dest result_unpacked_dest(dxbc::Dest::R(system_temp_result_, used_format_components)); + // If needed_words is not zero (checked in the beginning), this must not be + // zero too. For simplicity, it's assumed that something will be unpacked + // here. + assert_not_zero(used_format_components); + uint32_t packed_widths[4] = {}, packed_offsets[4] = {}; + uint32_t packed_swizzle = dxbc::Src::kXXXX; + switch (instr.attributes.data_format) { + case xenos::VertexFormat::k_8_8_8_8: + packed_widths[0] = packed_widths[1] = packed_widths[2] = packed_widths[3] = 8; + packed_offsets[1] = 8; + packed_offsets[2] = 16; + packed_offsets[3] = 24; + break; + case xenos::VertexFormat::k_2_10_10_10: + packed_widths[0] = packed_widths[1] = packed_widths[2] = 10; + packed_widths[3] = 2; + packed_offsets[1] = 10; + packed_offsets[2] = 20; + packed_offsets[3] = 30; + break; + case xenos::VertexFormat::k_10_11_11: + packed_widths[0] = packed_widths[1] = 11; + packed_widths[2] = 10; + packed_offsets[1] = 11; + packed_offsets[2] = 22; + break; + case xenos::VertexFormat::k_11_11_10: + packed_widths[0] = 10; + packed_widths[1] = packed_widths[2] = 11; + packed_offsets[1] = 10; + packed_offsets[2] = 21; + break; + case xenos::VertexFormat::k_16_16: + packed_widths[0] = packed_widths[1] = 16; + packed_offsets[1] = 16; + break; + case xenos::VertexFormat::k_16_16_16_16: + packed_widths[0] = packed_widths[1] = packed_widths[2] = packed_widths[3] = 16; + packed_offsets[1] = packed_offsets[3] = 16; + packed_swizzle = 0b01010000; + break; + default: + // Not a packed integer format. + break; + } + if (packed_widths[0]) { + // Handle packed integer formats. + if (instr.attributes.is_signed) { + a_.OpIBFE(result_unpacked_dest, dxbc::Src::LP(packed_widths), dxbc::Src::LP(packed_offsets), + dxbc::Src::R(system_temp_result_, packed_swizzle)); + a_.OpIToF(result_unpacked_dest, result_src); + if (!instr.attributes.is_integer) { + float packed_scales[4] = {}; + switch (instr.attributes.signed_rf_mode) { + case xenos::SignedRepeatingFractionMode::kZeroClampMinusOne: { + uint32_t packed_scales_mask = 0b0000; + for (uint32_t i = 0; i < 4; ++i) { + if (!(used_format_components & (1 << i))) { + continue; + } + if (packed_widths[i] > 2) { + packed_scales[i] = 1.0f / float((uint32_t(1) << (packed_widths[i] - 1)) - 1); + packed_scales_mask |= 1 << i; + } + } + if (packed_scales_mask) { + a_.OpMul(dxbc::Dest::R(system_temp_result_, packed_scales_mask), result_src, + dxbc::Src::LP(packed_scales)); + } + // Treat both -(2^(n-1)) and -(2^(n-1)-1) as -1. + a_.OpMax(result_unpacked_dest, result_src, dxbc::Src::LF(-1.0f)); + } break; + case xenos::SignedRepeatingFractionMode::kNoZero: { + float packed_zeros[4] = {}; + for (uint32_t i = 0; i < 4; ++i) { + if (!(used_format_components & (1 << i))) { + continue; + } + assert_not_zero(packed_widths[i]); + packed_zeros[i] = 1.0f / float((uint32_t(1) << packed_widths[i]) - 1); + packed_scales[i] = 2.0f * packed_zeros[i]; + } + a_.OpMAd(result_unpacked_dest, result_src, dxbc::Src::LP(packed_scales), + dxbc::Src::LP(packed_zeros)); + } break; + default: + assert_unhandled_case(instr.attributes.signed_rf_mode); + } + } + } else { + a_.OpUBFE(result_unpacked_dest, dxbc::Src::LP(packed_widths), dxbc::Src::LP(packed_offsets), + dxbc::Src::R(system_temp_result_, packed_swizzle)); + a_.OpUToF(result_unpacked_dest, result_src); + if (!instr.attributes.is_integer) { + float packed_scales[4] = {}; + uint32_t packed_scales_mask = 0b0000; + for (uint32_t i = 0; i < 4; ++i) { + if (!(used_format_components & (1 << i))) { + continue; + } + if (packed_widths[i] > 1) { + packed_scales[i] = 1.0f / float((uint32_t(1) << packed_widths[i]) - 1); + packed_scales_mask |= 1 << i; + } + } + if (packed_scales_mask) { + a_.OpMul(dxbc::Dest::R(system_temp_result_, packed_scales_mask), result_src, + dxbc::Src::LP(packed_scales)); + } + } + } + } else { + switch (instr.attributes.data_format) { + case xenos::VertexFormat::k_16_16_FLOAT: + case xenos::VertexFormat::k_16_16_16_16_FLOAT: + // FIXME(Triang3l): This converts from D3D10+ float16 with NaNs instead + // of Xbox 360 float16 with extended range. However, haven't encountered + // games relying on that yet. + a_.OpUBFE(result_unpacked_dest, dxbc::Src::LU(16), dxbc::Src::LU(0, 16, 0, 16), + dxbc::Src::R(system_temp_result_, 0b01010000)); + a_.OpF16ToF32(result_unpacked_dest, result_src); + break; + case xenos::VertexFormat::k_32: + case xenos::VertexFormat::k_32_32: + case xenos::VertexFormat::k_32_32_32_32: + if (instr.attributes.is_signed) { + a_.OpIToF(result_unpacked_dest, result_src); + } else { + a_.OpUToF(result_unpacked_dest, result_src); + } + if (!instr.attributes.is_integer) { + if (instr.attributes.is_signed) { + switch (instr.attributes.signed_rf_mode) { + case xenos::SignedRepeatingFractionMode::kZeroClampMinusOne: + a_.OpMul(result_unpacked_dest, result_src, dxbc::Src::LF(1.0f / 2147483647.0f)); + // No need to clamp to -1 if signed - 1/(2^31-1) is rounded to + // 1/(2^31) as float32. + break; + case xenos::SignedRepeatingFractionMode::kNoZero: + a_.OpMAd(result_unpacked_dest, result_src, dxbc::Src::LF(1.0f / 2147483647.5f), + dxbc::Src::LF(0.5f / 2147483647.5f)); + break; + default: + assert_unhandled_case(instr.attributes.signed_rf_mode); + } + } else { + a_.OpMul(result_unpacked_dest, result_src, dxbc::Src::LF(1.0f / 4294967295.0f)); + } + } + break; + case xenos::VertexFormat::k_32_FLOAT: + case xenos::VertexFormat::k_32_32_FLOAT: + case xenos::VertexFormat::k_32_32_32_32_FLOAT: + case xenos::VertexFormat::k_32_32_32_FLOAT: + // Already in the needed result components. + break; + default: + // Packed integer or unknown format. + assert_not_zero(packed_widths[0]); + break; + } + } + + // - Apply the exponent bias. + + if (instr.attributes.exp_adjust) { + a_.OpMul(result_unpacked_dest, result_src, + dxbc::Src::LF(std::ldexp(1.0f, instr.attributes.exp_adjust))); + } + + // - Write zeros to components not present in the format. + + uint32_t used_missing_components = used_result_components & ~used_format_components; + if (used_missing_components) { + a_.OpMov(dxbc::Dest::R(system_temp_result_, used_missing_components), dxbc::Src::LF(0.0f)); + } + + StoreResult(instr.result, dxbc::Src::R(system_temp_result_)); +} + +uint32_t DxbcShaderTranslator::FindOrAddTextureBinding(uint32_t fetch_constant, + xenos::FetchOpDimension dimension, + bool is_signed) { + // 1D and 2D textures (including stacked ones) are treated as 2D arrays for + // binding and coordinate simplicity. + if (dimension == xenos::FetchOpDimension::k1D) { + dimension = xenos::FetchOpDimension::k2D; + } + uint32_t srv_index = UINT32_MAX; + for (uint32_t i = 0; i < uint32_t(texture_bindings_.size()); ++i) { + const TextureBinding& texture_binding = texture_bindings_[i]; + if (texture_binding.fetch_constant == fetch_constant && + texture_binding.dimension == dimension && texture_binding.is_signed == is_signed) { + return i; + } + } + if (texture_bindings_.size() >= kMaxTextureBindings) { + assert_always(); + return kMaxTextureBindings - 1; + } + uint32_t texture_binding_index = uint32_t(texture_bindings_.size()); + TextureBinding& new_texture_binding = texture_bindings_.emplace_back(); + if (!bindless_resources_used_) { + new_texture_binding.bindful_srv_index = srv_count_++; + texture_bindings_for_bindful_srv_indices_.insert( + {new_texture_binding.bindful_srv_index, texture_binding_index}); + const char* dimension_name; + switch (dimension) { + case xenos::FetchOpDimension::k3DOrStacked: + dimension_name = "3d"; + break; + case xenos::FetchOpDimension::kCube: + dimension_name = "cube"; + break; + default: + dimension_name = "2d"; + } + new_texture_binding.bindful_name = + fmt::format("xe_texture{}_{}_{}", fetch_constant, dimension_name, is_signed ? 's' : 'u'); + } else { + new_texture_binding.bindful_srv_index = kBindingIndexUnallocated; + } + new_texture_binding.bindful_srv_rdef_name_ptr = 0; + // Consistently 0 if not bindless as it may be used for hashing. + new_texture_binding.bindless_descriptor_index = + bindless_resources_used_ ? GetBindlessResourceCount() : 0; + new_texture_binding.fetch_constant = fetch_constant; + new_texture_binding.dimension = dimension; + new_texture_binding.is_signed = is_signed; + return texture_binding_index; +} + +uint32_t DxbcShaderTranslator::FindOrAddSamplerBinding(uint32_t fetch_constant, + xenos::TextureFilter mag_filter, + xenos::TextureFilter min_filter, + xenos::TextureFilter mip_filter, + xenos::AnisoFilter aniso_filter) { + // In Direct3D 12, anisotropic filtering implies linear filtering. + if (aniso_filter != xenos::AnisoFilter::kDisabled && + aniso_filter != xenos::AnisoFilter::kUseFetchConst) { + mag_filter = xenos::TextureFilter::kLinear; + min_filter = xenos::TextureFilter::kLinear; + mip_filter = xenos::TextureFilter::kLinear; + aniso_filter = std::min(aniso_filter, xenos::AnisoFilter::kMax_16_1); + } + uint32_t sampler_index = UINT32_MAX; + for (uint32_t i = 0; i < uint32_t(sampler_bindings_.size()); ++i) { + const SamplerBinding& sampler_binding = sampler_bindings_[i]; + if (sampler_binding.fetch_constant == fetch_constant && + sampler_binding.mag_filter == mag_filter && sampler_binding.min_filter == min_filter && + sampler_binding.mip_filter == mip_filter && sampler_binding.aniso_filter == aniso_filter) { + return i; + } + } + if (sampler_bindings_.size() >= kMaxSamplerBindings) { + assert_always(); + return kMaxSamplerBindings - 1; + } + SamplerBinding& new_sampler_binding = sampler_bindings_.emplace_back(); + // Consistently 0 if not bindless as it may be used for hashing. + new_sampler_binding.bindless_descriptor_index = + bindless_resources_used_ ? GetBindlessResourceCount() : 0; + new_sampler_binding.fetch_constant = fetch_constant; + new_sampler_binding.mag_filter = mag_filter; + new_sampler_binding.min_filter = min_filter; + new_sampler_binding.mip_filter = mip_filter; + new_sampler_binding.aniso_filter = aniso_filter; + if (!bindless_resources_used_) { + std::ostringstream name; + name << "xe_sampler" << fetch_constant; + if (aniso_filter == xenos::AnisoFilter::kDisabled || + aniso_filter == xenos::AnisoFilter::kUseFetchConst) { + static const char kFilterSuffixes[] = {'p', 'l', 'b', 'f'}; + name << '_' << kFilterSuffixes[uint32_t(mag_filter)] << kFilterSuffixes[uint32_t(min_filter)] + << kFilterSuffixes[uint32_t(mip_filter)]; + } + if (aniso_filter != xenos::AnisoFilter::kUseFetchConst) { + if (aniso_filter == xenos::AnisoFilter::kDisabled) { + name << "_a0"; + } else { + name << "_a" << (UINT32_C(1) << (uint32_t(aniso_filter) - 1)); + } + } + new_sampler_binding.bindful_name = name.str(); + } + return uint32_t(sampler_bindings_.size() - 1); +} + +void DxbcShaderTranslator::ProcessTextureFetchInstruction( + const ParsedTextureFetchInstruction& instr) { + if (emit_source_map_) { + instruction_disassembly_buffer_.Reset(); + instr.Disassemble(&instruction_disassembly_buffer_); + } + UpdateInstructionPredicationAndEmitDisassembly(instr.is_predicated, instr.predicate_condition); + + // Handle instructions for setting register LOD. + switch (instr.opcode) { + case FetchOpcode::kSetTextureLod: { + bool lod_operand_temp_pushed = false; + a_.OpMov( + dxbc::Dest::R(system_temp_grad_h_lod_, 0b1000), + LoadOperand(instr.operands[0], 0b0001, lod_operand_temp_pushed).SelectFromSwizzled(0)); + if (lod_operand_temp_pushed) { + PopSystemTemp(); + } + return; + } + case FetchOpcode::kSetTextureGradientsHorz: { + bool grad_operand_temp_pushed = false; + a_.OpMov(dxbc::Dest::R(system_temp_grad_h_lod_, 0b0111), + LoadOperand(instr.operands[0], 0b0111, grad_operand_temp_pushed)); + if (grad_operand_temp_pushed) { + PopSystemTemp(); + } + return; + } + case FetchOpcode::kSetTextureGradientsVert: { + bool grad_operand_temp_pushed = false; + a_.OpMov(dxbc::Dest::R(system_temp_grad_v_vfetch_address_, 0b0111), + LoadOperand(instr.operands[0], 0b0111, grad_operand_temp_pushed)); + if (grad_operand_temp_pushed) { + PopSystemTemp(); + } + return; + } + default: + break; + } + + // Handle instructions that store something. + uint32_t used_result_components = instr.result.GetUsedResultComponents(); + uint32_t used_result_nonzero_components = instr.GetNonZeroResultComponents(); + // FIXME(Triang3l): Currently disregarding the LOD completely in getWeights + // because the needed code would be very complicated, while getWeights is + // mostly used for things like PCF of shadow maps, that don't have mips. The + // LOD would be needed for the mip lerp factor in W of the return value and to + // choose the LOD where interpolation would take place for XYZ. That would + // require either implementing the LOD calculation algorithm using the ALU + // (since the `lod` instruction is limited to pixel shaders and can't be used + // when there's control flow divergence, unlike explicit gradients), or + // sampling a texture filled with LOD numbers (easier and more consistent - + // unclamped LOD doesn't make sense for getWeights anyway). The same applies + // to offsets. + if (instr.opcode == FetchOpcode::kGetTextureWeights) { + used_result_nonzero_components &= ~uint32_t(0b1000); + } + if (!used_result_nonzero_components) { + // Nothing to fetch, only constant 0/1 writes. + StoreResult(instr.result, dxbc::Src::LF(0.0f)); + return; + } + + if (instr.opcode == FetchOpcode::kGetTextureGradients) { + // Handle before doing anything that actually needs the texture. + bool grad_operand_temp_pushed = false; + dxbc::Src grad_operand = + LoadOperand(instr.operands[0], + ((used_result_nonzero_components & 0b0011) ? 0b0001 : 0) | + ((used_result_nonzero_components & 0b1100) ? 0b0010 : 0), + grad_operand_temp_pushed); + if (used_result_nonzero_components & 0b0101) { + a_.OpDerivRTXCoarse( + dxbc::Dest::R(system_temp_result_, used_result_nonzero_components & 0b0101), + grad_operand.SwizzleSwizzled(0b010000)); + } + if (used_result_nonzero_components & 0b1010) { + a_.OpDerivRTYCoarse( + dxbc::Dest::R(system_temp_result_, used_result_nonzero_components & 0b1010), + grad_operand.SwizzleSwizzled(0b01000000)); + } + if (grad_operand_temp_pushed) { + PopSystemTemp(); + } + StoreResult(instr.result, dxbc::Src::R(system_temp_result_)); + return; + } + + // Handle instructions that need the coordinates, the fetch constant, the LOD + // and possibly the SRV - kTextureFetch, kGetTextureBorderColorFrac, + // kGetTextureComputedLod, kGetTextureWeights. + + if (instr.opcode == FetchOpcode::kGetTextureBorderColorFrac) { + // TODO(Triang3l): Bind a black texture with a white border to calculate the + // border color fraction (in the X component of the result). + assert_always(); + EmitTranslationError("getBCF is unimplemented", false); + StoreResult(instr.result, dxbc::Src::LF(0.0f)); + return; + } + + if (instr.opcode != FetchOpcode::kTextureFetch && + instr.opcode != FetchOpcode::kGetTextureBorderColorFrac && + instr.opcode != FetchOpcode::kGetTextureComputedLod && + instr.opcode != FetchOpcode::kGetTextureWeights) { + assert_unhandled_case(instr.opcode); + EmitTranslationError("Unknown texture fetch operation"); + StoreResult(instr.result, dxbc::Src::LF(0.0f)); + return; + } + + uint32_t tfetch_index = instr.operands[1].storage_index; + + // Whether to use gradients (implicit or explicit) for LOD calculation. + bool use_computed_lod = instr.attributes.use_computed_lod && + (is_pixel_shader() || instr.attributes.use_register_gradients); + if (instr.opcode == FetchOpcode::kGetTextureComputedLod && + (!use_computed_lod || instr.attributes.use_register_gradients)) { + assert_always(); + EmitTranslationError("getCompTexLOD used with explicit LOD or gradients - contradicts MSDN", + false); + StoreResult(instr.result, dxbc::Src::LF(0.0f)); + return; + } + + // Get offsets applied to the coordinates before sampling. + // `offsets` is used for float4 literal construction, + // FIXME(Triang3l): Offsets need to be applied at the LOD being fetched, not + // at LOD 0. However, since offsets have granularity of 0.5, not 1, on the + // Xbox 360, they can't be passed directly as AOffImmI to the `sample` + // instruction (plus-minus 0.5 offsets are very common in games). But + // offsetting at mip levels is a rare usage case, mostly offsets are used for + // things like shadow maps and blur, where there are no mips. + float offsets[3] = {}; + // MSDN doesn't list offsets as getCompTexLOD parameters. + if (instr.opcode != FetchOpcode::kGetTextureComputedLod) { + // Add a small epsilon to the offset (1.5/4 the fixed-point texture + // coordinate ULP - shouldn't significantly effect the fixed-point + // conversion; 1/4 is also not enough with 3x resolution scaling very + // noticeably on the weapon in 4D5307E6) to resolve ambiguity when fetching + // point-sampled textures between texels. This applies to both normalized + // (58410954 Xbox Live Arcade logo, coordinates interpolated between + // vertices with half-pixel offset) and unnormalized (4D5307E6 lighting + // G-buffer reading, ps_param_gen pixels) coordinates. On Nvidia Pascal, + // without this adjustment, blockiness is visible in both cases. Possibly + // there is a better way, however, an attempt was made to error-correct + // division by adding the difference between original and re-denormalized + // coordinates, but on Nvidia, `mul` and internal multiplication in texture + // sampling apparently round differently, so `mul` gives a value that would + // be floored as expected, but the left/upper pixel is still sampled + // instead. + const float rounding_offset = 1.5f / 1024.0f; + switch (instr.dimension) { + case xenos::FetchOpDimension::k1D: + offsets[0] = instr.attributes.offset_x + rounding_offset; + if (instr.opcode == FetchOpcode::kGetTextureWeights) { + // For coordinate lerp factors. This needs to be done separately for + // point mag/min filters, but they're currently not handled here + // anyway. + offsets[0] -= 0.5f; + } + break; + case xenos::FetchOpDimension::k2D: + offsets[0] = instr.attributes.offset_x + rounding_offset; + offsets[1] = instr.attributes.offset_y + rounding_offset; + if (instr.opcode == FetchOpcode::kGetTextureWeights) { + offsets[0] -= 0.5f; + offsets[1] -= 0.5f; + } + break; + case xenos::FetchOpDimension::k3DOrStacked: + offsets[0] = instr.attributes.offset_x + rounding_offset; + offsets[1] = instr.attributes.offset_y + rounding_offset; + offsets[2] = instr.attributes.offset_z + rounding_offset; + if (instr.opcode == FetchOpcode::kGetTextureWeights) { + offsets[0] -= 0.5f; + offsets[1] -= 0.5f; + offsets[2] -= 0.5f; + } + break; + case xenos::FetchOpDimension::kCube: + // Applying the rounding epsilon to cube maps too for potential game + // passes processing cube map faces themselves. + offsets[0] = instr.attributes.offset_x + rounding_offset; + offsets[1] = instr.attributes.offset_y + rounding_offset; + if (instr.opcode == FetchOpcode::kGetTextureWeights) { + offsets[0] -= 0.5f; + offsets[1] -= 0.5f; + // The logic for ST weights is the same for all faces. + // FIXME(Triang3l): If LOD calculation is added to getWeights, face + // offset probably will need to be handled too (if the hardware + // supports it at all, though MSDN lists OffsetZ in tfetchCube). + } else { + offsets[2] = instr.attributes.offset_z; + } + break; + } + } + uint32_t offsets_not_zero = 0b000; + for (uint32_t i = 0; i < 3; ++i) { + if (offsets[i]) { + offsets_not_zero |= 1 << i; + } + } + dxbc::Src offsets_src(dxbc::Src::LF(offsets[0], offsets[1], offsets[2], 0.0f)); + + // Load the texture size if needed. + // 1D: X - width. + // 2D, cube: X - width, Y - height (cube maps probably can be only square, but + // for simplicity). + // 3D: X - width, Y - height, Z - depth, W - 0 if stacked 2D, 1 if 3D. + uint32_t size_needed_components = 0b0000; + if (instr.opcode == FetchOpcode::kGetTextureWeights) { + // Size needed for denormalization for coordinate lerp factor. + // FIXME(Triang3l): Currently disregarding the LOD completely in getWeights. + // However, if the LOD lerp factor and the LOD where filtering would happen + // are ever calculated, all components of the size may be needed for ALU LOD + // calculation with normalized coordinates (or, if a texture filled with LOD + // indices is used, coordinates will need to be normalized as normally). + if (!instr.attributes.unnormalized_coordinates) { + switch (instr.dimension) { + case xenos::FetchOpDimension::k1D: + // Always need size for 1D textures to support wide 1D textures. + size_needed_components |= 0b0001; + break; + case xenos::FetchOpDimension::k2D: + case xenos::FetchOpDimension::kCube: + size_needed_components |= used_result_nonzero_components & 0b0011; + break; + case xenos::FetchOpDimension::k3DOrStacked: + size_needed_components |= used_result_nonzero_components & 0b0111; + break; + } + } + } else { + // Size needed for normalization (or, for stacked texture layers, + // denormalization) and for offsets. + size_needed_components |= offsets_not_zero; + switch (instr.dimension) { + case xenos::FetchOpDimension::k1D: + if (instr.attributes.unnormalized_coordinates) { + size_needed_components |= 0b0001; + } + break; + case xenos::FetchOpDimension::k2D: + if (instr.attributes.unnormalized_coordinates) { + size_needed_components |= 0b0011; + } + break; + case xenos::FetchOpDimension::k3DOrStacked: + // Stacked and 3D textures are fetched from different SRVs - the check + // is always needed. + size_needed_components |= 0b1000; + if (instr.attributes.unnormalized_coordinates) { + // Need to normalize all (if 3D). + size_needed_components |= 0b0111; + } else { + // Need to denormalize Z (if stacked). + size_needed_components |= 0b0100; + } + break; + case xenos::FetchOpDimension::kCube: + if (instr.attributes.unnormalized_coordinates) { + size_needed_components |= 0b0011; + } + // The size is not needed for face ID offset. + size_needed_components &= 0b0011; + break; + } + } + if (instr.dimension == xenos::FetchOpDimension::k3DOrStacked && size_needed_components) { + // Stacked and 3D textures have different size packing - need to get whether + // the texture is 3D unconditionally. + size_needed_components |= 0b1000; + } + uint32_t size_and_is_3d_temp = size_needed_components ? PushSystemTemp() : UINT32_MAX; + if (size_needed_components) { + switch (instr.dimension) { + case xenos::FetchOpDimension::k1D: + a_.OpUBFE(dxbc::Dest::R(size_and_is_3d_temp, 0b0001), dxbc::Src::LU(24), dxbc::Src::LU(0), + RequestTextureFetchConstantWord(tfetch_index, 2)); + break; + case xenos::FetchOpDimension::k2D: + case xenos::FetchOpDimension::kCube: + a_.OpUBFE(dxbc::Dest::R(size_and_is_3d_temp, size_needed_components), + dxbc::Src::LU(13, 13, 0, 0), dxbc::Src::LU(0, 13, 0, 0), + RequestTextureFetchConstantWord(tfetch_index, 2)); + break; + case xenos::FetchOpDimension::k3DOrStacked: + // tfetch3D is used for both stacked and 3D - first, check if 3D. + a_.OpUBFE(dxbc::Dest::R(size_and_is_3d_temp, 0b1000), dxbc::Src::LU(2), dxbc::Src::LU(9), + RequestTextureFetchConstantWord(tfetch_index, 5)); + a_.OpIEq(dxbc::Dest::R(size_and_is_3d_temp, 0b1000), + dxbc::Src::R(size_and_is_3d_temp, dxbc::Src::kWWWW), + dxbc::Src::LU(uint32_t(xenos::DataDimension::k3D))); + if (size_needed_components & 0b0111) { + // Even if depth isn't needed specifically for stacked or specifically + // for 3D later, load both cases anyway to make sure the register is + // always initialized. + a_.OpIf(true, dxbc::Src::R(size_and_is_3d_temp, dxbc::Src::kWWWW)); + // Load the 3D texture size. + a_.OpUBFE(dxbc::Dest::R(size_and_is_3d_temp, size_needed_components & 0b0111), + dxbc::Src::LU(11, 11, 10, 0), dxbc::Src::LU(0, 11, 22, 0), + RequestTextureFetchConstantWord(tfetch_index, 2)); + a_.OpElse(); + // Load the 2D stacked texture size. + a_.OpUBFE(dxbc::Dest::R(size_and_is_3d_temp, size_needed_components & 0b0111), + dxbc::Src::LU(13, 13, 6, 0), dxbc::Src::LU(0, 13, 26, 0), + RequestTextureFetchConstantWord(tfetch_index, 2)); + a_.OpEndIf(); + } + break; + } + if (size_needed_components & 0b0111) { + // Fetch constants store size minus 1 - add 1. + a_.OpIAdd(dxbc::Dest::R(size_and_is_3d_temp, size_needed_components & 0b0111), + dxbc::Src::R(size_and_is_3d_temp), dxbc::Src::LU(1)); + // Convert the size to float for multiplication/division. + a_.OpUToF(dxbc::Dest::R(size_and_is_3d_temp, size_needed_components & 0b0111), + dxbc::Src::R(size_and_is_3d_temp)); + } + } + uint32_t revert_resolution_scale_axes = + REXCVAR_GET(draw_resolution_scaled_texture_offsets) + ? uint32_t(draw_resolution_scale_x_ > 1) | (uint32_t(draw_resolution_scale_y_ > 1) << 1) + : 0; + + if (instr.opcode == FetchOpcode::kGetTextureWeights) { + // FIXME(Triang3l): Mip lerp factor needs to be calculated, and the + // coordinate lerp factors should be calculated at the mip level texels + // would be sampled from. That would require some way of calculating the LOD + // that would be applicable to explicit gradients and vertex shaders. Also, + // with point sampling, possibly lerp factors need to be 0. W (mip lerp + // factor) should have been masked out previously because it's not supported + // currently. + assert_zero(used_result_nonzero_components & 0b1000); + + // FIXME(Triang3l): Filtering modes should possibly be taken into account, + // but for simplicity, not doing that - from a high level point of view, + // would be useless to get weights that will always be zero. + + // Need unnormalized coordinates. + bool coord_operand_temp_pushed = false; + dxbc::Src coord_operand = + LoadOperand(instr.operands[0], used_result_nonzero_components, coord_operand_temp_pushed); + dxbc::Src coord_src(coord_operand); + // If needed, apply the resolution scale to the width / height and the + // unnormalized coordinates. + uint32_t resolution_scaled_result_components = + used_result_nonzero_components & revert_resolution_scale_axes; + uint32_t resolution_scaled_coord_components = + instr.attributes.unnormalized_coordinates ? resolution_scaled_result_components : 0b0000; + uint32_t resolution_scaled_size_components = + size_needed_components & resolution_scaled_result_components; + if (resolution_scaled_coord_components || resolution_scaled_size_components) { + if (resolution_scaled_coord_components && + (coord_src.type_ != dxbc::OperandType::kTemp || + coord_src.index_1d_.index_ != system_temp_result_)) { + // Use system_temp_result_ as a temporary for conditionally + // resolution-scaled coordinates. + a_.OpMov(dxbc::Dest::R(system_temp_result_, used_result_nonzero_components), coord_src); + coord_src = dxbc::Src::R(system_temp_result_); + } + // Using system_temp_result_.w as a temporary for the flag indicating + // whether the texture is resolution-scaled - not involved in coordinate + // calculations. + assert_zero(used_result_nonzero_components & 0b1000); + a_.OpAnd(dxbc::Dest::R(system_temp_result_, 0b1000), + LoadSystemConstant(SystemConstants::Index::kTexturesResolutionScaled, + offsetof(SystemConstants, textures_resolution_scaled), + dxbc::Src::kXXXX), + dxbc::Src::LU(uint32_t(1) << tfetch_index)); + a_.OpIf(true, dxbc::Src::R(system_temp_result_, dxbc::Src::kWWWW)); + // The texture is resolution-scaled - scale the coordinates and the size. + dxbc::Src resolution_scale_src(dxbc::Src::LF(float(draw_resolution_scale_x_), + float(draw_resolution_scale_y_), 1.0f, 1.0f)); + if (resolution_scaled_coord_components) { + a_.OpMul(dxbc::Dest::R(system_temp_result_, resolution_scaled_coord_components), coord_src, + resolution_scale_src); + } + if (resolution_scaled_size_components) { + a_.OpMul(dxbc::Dest::R(size_and_is_3d_temp, resolution_scaled_size_components), + dxbc::Src::R(size_and_is_3d_temp), resolution_scale_src); + } + a_.OpEndIf(); + } + uint32_t offsets_needed = offsets_not_zero & used_result_nonzero_components; + if (!instr.attributes.unnormalized_coordinates || offsets_needed) { + // Using system_temp_result_ as a temporary for coordinate denormalization + // and offsetting. May already contain the coordinates loaded if + // resolution scaling was applied to the coordinates. + coord_src = dxbc::Src::R(system_temp_result_); + dxbc::Dest coord_dest(dxbc::Dest::R(system_temp_result_, used_result_nonzero_components)); + if (instr.attributes.unnormalized_coordinates) { + if (offsets_needed) { + a_.OpAdd(coord_dest, coord_operand, offsets_src); + } + } else { + assert_true((size_needed_components & used_result_nonzero_components) == + used_result_nonzero_components); + if (offsets_needed) { + a_.OpMAd(coord_dest, coord_operand, dxbc::Src::R(size_and_is_3d_temp), offsets_src); + } else { + a_.OpMul(coord_dest, coord_operand, dxbc::Src::R(size_and_is_3d_temp)); + } + } + } + // 0.5 has already been subtracted via offsets previously. + a_.OpFrc(dxbc::Dest::R(system_temp_result_, used_result_nonzero_components), coord_src); + if (coord_operand_temp_pushed) { + PopSystemTemp(); + } + } else { + // - Component signedness, for selecting the SRV, and if data is needed. + + dxbc::Src signs_uint_src(GetSystemConstantSrc( + offsetof(SystemConstants, texture_swizzled_signs) + sizeof(uint32_t) * (tfetch_index >> 2), + dxbc::Src::kXXXX)); + uint32_t signs_shift = (tfetch_index & 3) * 8; + uint32_t signs_temp = UINT32_MAX; + if (instr.opcode == FetchOpcode::kTextureFetch) { + signs_temp = PushSystemTemp(); + MarkSystemConstantUsed(SystemConstants::Index::kTextureSwizzledSigns); + a_.OpUBFE(dxbc::Dest::R(signs_temp, used_result_nonzero_components), dxbc::Src::LU(2), + dxbc::Src::LU(signs_shift, signs_shift + 2, signs_shift + 4, signs_shift + 6), + signs_uint_src); + } + + // - Coordinates. + + // Will need a temporary in all cases: + // - 1D, 2D array - need to be padded to 2D array coordinates. + // - 3D - Z needs to be unnormalized for stacked and normalized for 3D. + // - Cube - coordinates need to be transformed into the cube space. + // Bindless sampler index will be loaded to W after loading the coordinates + // (so W can be used as a temporary for coordinate loading). + uint32_t coord_and_sampler_temp = PushSystemTemp(); + + // Need normalized coordinates (except for Z - keep it as is, will be + // converted later according to whether the texture is 3D). For cube maps, + // coordinates need to be transformed back into the cube space. + bool coord_operand_temp_pushed = false; + dxbc::Src coord_operand = LoadOperand( + instr.operands[0], (1 << xenos::GetFetchOpDimensionComponentCount(instr.dimension)) - 1, + coord_operand_temp_pushed); + uint32_t normalized_components = 0b0000; + switch (instr.dimension) { + case xenos::FetchOpDimension::k1D: + normalized_components = 0b0001; + break; + case xenos::FetchOpDimension::k2D: + case xenos::FetchOpDimension::kCube: + normalized_components = 0b0011; + break; + case xenos::FetchOpDimension::k3DOrStacked: + normalized_components = 0b0111; + break; + } + uint32_t normalized_components_with_offsets = normalized_components & offsets_not_zero; + uint32_t normalized_components_with_scaled_offsets = + normalized_components_with_offsets & revert_resolution_scale_axes; + uint32_t normalized_components_with_unscaled_offsets = + normalized_components_with_offsets & ~normalized_components_with_scaled_offsets; + uint32_t normalized_components_without_offsets = + normalized_components & ~normalized_components_with_offsets; + if (instr.attributes.unnormalized_coordinates) { + // Unnormalized coordinates - normalize XY, and if 3D, normalize Z. + assert_not_zero(normalized_components); + assert_true((size_needed_components & normalized_components) == normalized_components); + if (normalized_components_with_offsets) { + // Apply the offsets to components to normalize where needed, or just + // copy the components to coord_and_sampler_temp where not. + // FIXME(Triang3l): Offsets need to be applied at the LOD being fetched. + if (normalized_components_with_scaled_offsets) { + // Using coord_and_sampler_temp.w as a temporary for the needed + // resolution scale inverse - sampler not loaded yet. + a_.OpAnd(dxbc::Dest::R(coord_and_sampler_temp, 0b1000), + LoadSystemConstant(SystemConstants::Index::kTexturesResolutionScaled, + offsetof(SystemConstants, textures_resolution_scaled), + dxbc::Src::kXXXX), + dxbc::Src::LU(uint32_t(1) << tfetch_index)); + a_.OpIf(true, dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kWWWW)); + a_.OpAdd(dxbc::Dest::R(coord_and_sampler_temp, normalized_components_with_scaled_offsets), + coord_operand, + dxbc::Src::LF(offsets[0] / draw_resolution_scale_x_, + offsets[1] / draw_resolution_scale_y_, 0.0f, 0.0f)); + a_.OpElse(); + a_.OpAdd(dxbc::Dest::R(coord_and_sampler_temp, normalized_components_with_scaled_offsets), + coord_operand, offsets_src); + a_.OpEndIf(); + } + if (normalized_components_with_unscaled_offsets) { + a_.OpAdd( + dxbc::Dest::R(coord_and_sampler_temp, normalized_components_with_unscaled_offsets), + coord_operand, offsets_src); + } + if (normalized_components_without_offsets) { + a_.OpMov(dxbc::Dest::R(coord_and_sampler_temp, normalized_components_without_offsets), + coord_operand); + } + assert_not_zero(normalized_components & 0b011); + a_.OpDiv(dxbc::Dest::R(coord_and_sampler_temp, normalized_components & 0b011), + dxbc::Src::R(coord_and_sampler_temp), dxbc::Src::R(size_and_is_3d_temp)); + if (instr.dimension == xenos::FetchOpDimension::k3DOrStacked) { + // Normalize if 3D. + assert_true((size_needed_components & 0b1100) == 0b1100); + a_.OpIf(true, dxbc::Src::R(size_and_is_3d_temp, dxbc::Src::kWWWW)); + a_.OpDiv(dxbc::Dest::R(coord_and_sampler_temp, 0b0100), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kZZZZ), + dxbc::Src::R(size_and_is_3d_temp, dxbc::Src::kZZZZ)); + a_.OpEndIf(); + } + } else { + a_.OpDiv(dxbc::Dest::R(coord_and_sampler_temp, normalized_components), coord_operand, + dxbc::Src::R(size_and_is_3d_temp)); + if (instr.dimension == xenos::FetchOpDimension::k3DOrStacked) { + // Don't normalize if stacked. + assert_true((size_needed_components & 0b1000) == 0b1000); + a_.OpMovC(dxbc::Dest::R(coord_and_sampler_temp, 0b0100), + dxbc::Src::R(size_and_is_3d_temp, dxbc::Src::kWWWW), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kZZZZ), + coord_operand.SelectFromSwizzled(2)); + } + } + } else { + // Normalized coordinates - apply offsets to XY or copy them to + // coord_and_sampler_temp, and if stacked, denormalize Z. + if (normalized_components_with_offsets) { + // FIXME(Triang3l): Offsets need to be applied at the LOD being fetched. + assert_true((size_needed_components & normalized_components_with_offsets) == + normalized_components_with_offsets); + a_.OpDiv(dxbc::Dest::R(coord_and_sampler_temp, normalized_components_with_offsets), + offsets_src, dxbc::Src::R(size_and_is_3d_temp)); + if (normalized_components_with_scaled_offsets) { + // Using coord_and_sampler_temp.w as a temporary for the needed + // resolution scale inverse - sampler not loaded yet. + a_.OpAnd(dxbc::Dest::R(coord_and_sampler_temp, 0b1000), + LoadSystemConstant(SystemConstants::Index::kTexturesResolutionScaled, + offsetof(SystemConstants, textures_resolution_scaled), + dxbc::Src::kXXXX), + dxbc::Src::LU(uint32_t(1) << tfetch_index)); + a_.OpIf(true, dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kWWWW)); + a_.OpMAd(dxbc::Dest::R(coord_and_sampler_temp, normalized_components_with_scaled_offsets), + dxbc::Src::R(coord_and_sampler_temp), + dxbc::Src::LF(1.0f / draw_resolution_scale_x_, 1.0f / draw_resolution_scale_y_, + 1.0f, 1.0f), + coord_operand); + a_.OpElse(); + a_.OpAdd(dxbc::Dest::R(coord_and_sampler_temp, normalized_components_with_scaled_offsets), + coord_operand, dxbc::Src::R(coord_and_sampler_temp)); + a_.OpEndIf(); + } + if (normalized_components_with_unscaled_offsets) { + a_.OpAdd( + dxbc::Dest::R(coord_and_sampler_temp, normalized_components_with_unscaled_offsets), + coord_operand, dxbc::Src::R(coord_and_sampler_temp)); + } + } + // 3D/stacked without offset is handled separately. + if (normalized_components_without_offsets & 0b011) { + a_.OpMov( + dxbc::Dest::R(coord_and_sampler_temp, normalized_components_without_offsets & 0b011), + coord_operand); + } + if (instr.dimension == xenos::FetchOpDimension::k3DOrStacked) { + assert_true((size_needed_components & 0b1100) == 0b1100); + if (normalized_components_with_offsets & 0b100) { + // Denormalize and offset Z (re-apply the offset not to lose precision + // as a result of division) if stacked. + a_.OpIf(false, dxbc::Src::R(size_and_is_3d_temp, dxbc::Src::kWWWW)); + a_.OpMAd(dxbc::Dest::R(coord_and_sampler_temp, 0b0100), + coord_operand.SelectFromSwizzled(2), + dxbc::Src::R(size_and_is_3d_temp, dxbc::Src::kZZZZ), dxbc::Src::LF(offsets[2])); + a_.OpEndIf(); + } else { + // Denormalize Z if stacked, and revert to normalized if 3D. + a_.OpMul(dxbc::Dest::R(coord_and_sampler_temp, 0b0100), + coord_operand.SelectFromSwizzled(2), + dxbc::Src::R(size_and_is_3d_temp, dxbc::Src::kZZZZ)); + a_.OpMovC(dxbc::Dest::R(coord_and_sampler_temp, 0b0100), + dxbc::Src::R(size_and_is_3d_temp, dxbc::Src::kWWWW), + coord_operand.SelectFromSwizzled(2), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kZZZZ)); + } + } + } + switch (instr.dimension) { + case xenos::FetchOpDimension::k1D: + // Pad to 2D array coordinates. + a_.OpMov(dxbc::Dest::R(coord_and_sampler_temp, 0b0110), dxbc::Src::LF(0.0f)); + break; + case xenos::FetchOpDimension::k2D: + // Pad to 2D array coordinates. + a_.OpMov(dxbc::Dest::R(coord_and_sampler_temp, 0b0100), dxbc::Src::LF(0.0f)); + break; + case xenos::FetchOpDimension::kCube: { + // Transform from the major axis SC/TC plus 1 into cube coordinates. + // Move SC/TC from 1...2 to -1...1. + a_.OpMAd(dxbc::Dest::R(coord_and_sampler_temp, 0b0011), + dxbc::Src::R(coord_and_sampler_temp), dxbc::Src::LF(2.0f), dxbc::Src::LF(-3.0f)); + // Get the face index (floored, within 0...5) as an integer to + // coord_and_sampler_temp.z. + if (offsets[2]) { + a_.OpAdd(dxbc::Dest::R(coord_and_sampler_temp, 0b0100), + coord_operand.SelectFromSwizzled(2), dxbc::Src::LF(offsets[2])); + a_.OpFToU(dxbc::Dest::R(coord_and_sampler_temp, 0b0100), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kZZZZ)); + } else { + a_.OpFToU(dxbc::Dest::R(coord_and_sampler_temp, 0b0100), + coord_operand.SelectFromSwizzled(2)); + } + a_.OpUMin(dxbc::Dest::R(coord_and_sampler_temp, 0b0100), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kZZZZ), dxbc::Src::LU(5)); + // Split the face index into axis and sign (0 - positive, 1 - negative) + // to coord_and_sampler_temp.zw (sign in W so it won't be overwritten). + // Fine to overwrite W at this point, the sampler index hasn't been + // loaded yet. + a_.OpUBFE(dxbc::Dest::R(coord_and_sampler_temp, 0b1100), dxbc::Src::LU(0, 0, 2, 1), + dxbc::Src::LU(0, 0, 1, 0), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kZZZZ)); + // Remap the axes in a way opposite to the ALU cube instruction. + a_.OpSwitch(dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kZZZZ)); + a_.OpCase(dxbc::Src::LU(0)); + { + // X is the major axis. + // Y = -TC (TC overwritten). + a_.OpMov(dxbc::Dest::R(coord_and_sampler_temp, 0b0010), + -dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kYYYY)); + // Z = neg ? SC : -SC. + a_.OpMovC(dxbc::Dest::R(coord_and_sampler_temp, 0b0100), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kWWWW), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kXXXX), + -dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kXXXX)); + // X = neg ? -1 : 1 (SC overwritten). + a_.OpMovC(dxbc::Dest::R(coord_and_sampler_temp, 0b0001), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kWWWW), dxbc::Src::LF(-1.0f), + dxbc::Src::LF(1.0f)); + } + a_.OpBreak(); + a_.OpCase(dxbc::Src::LU(1)); + { + // Y is the major axis. + // X = SC (already there). + // Z = neg ? -TC : TC. + a_.OpMovC(dxbc::Dest::R(coord_and_sampler_temp, 0b0100), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kWWWW), + -dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kYYYY), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kYYYY)); + // Y = neg ? -1 : 1 (TC overwritten). + a_.OpMovC(dxbc::Dest::R(coord_and_sampler_temp, 0b0010), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kWWWW), dxbc::Src::LF(-1.0f), + dxbc::Src::LF(1.0f)); + } + a_.OpBreak(); + a_.OpDefault(); + { + // Z is the major axis. + // X = neg ? -SC : SC (SC overwritten). + a_.OpMovC(dxbc::Dest::R(coord_and_sampler_temp, 0b0001), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kWWWW), + -dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kXXXX), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kXXXX)); + // Y = -TC (TC overwritten). + a_.OpMov(dxbc::Dest::R(coord_and_sampler_temp, 0b0010), + -dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kYYYY)); + // Z = neg ? -1 : 1. + a_.OpMovC(dxbc::Dest::R(coord_and_sampler_temp, 0b0100), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kWWWW), dxbc::Src::LF(-1.0f), + dxbc::Src::LF(1.0f)); + } + a_.OpBreak(); + a_.OpEndSwitch(); + } break; + default: + break; + } + if (coord_operand_temp_pushed) { + PopSystemTemp(); + } + + if (instr.opcode == FetchOpcode::kGetTextureComputedLod) { + // Because the `lod` instruction is not defined for point sampling, and + // since the return value can be used with bias later, forcing linear mip + // filtering (the XNA assembler also doesn't accept MipFilter overrides + // for getCompTexLOD). + uint32_t sampler_binding_index = FindOrAddSamplerBinding( + tfetch_index, instr.attributes.mag_filter, instr.attributes.min_filter, + xenos::TextureFilter::kLinear, instr.attributes.aniso_filter); + dxbc::Src sampler(dxbc::Src::S(sampler_binding_index, sampler_binding_index)); + if (bindless_resources_used_) { + // Load the sampler index to coord_and_sampler_temp.w and use relative + // sampler indexing. + if (cbuffer_index_descriptor_indices_ == kBindingIndexUnallocated) { + cbuffer_index_descriptor_indices_ = cbuffer_count_++; + } + uint32_t sampler_bindless_descriptor_index = + sampler_bindings_[sampler_binding_index].bindless_descriptor_index; + a_.OpMov(dxbc::Dest::R(coord_and_sampler_temp, 0b1000), + dxbc::Src::CB(cbuffer_index_descriptor_indices_, + uint32_t(CbufferRegister::kDescriptorIndices), + sampler_bindless_descriptor_index >> 2) + .Select(sampler_bindless_descriptor_index & 3)); + sampler = dxbc::Src::S(0, dxbc::Index(coord_and_sampler_temp, 3)); + } + // Check which SRV needs to be accessed - signed or unsigned. If there is + // at least one non-signed component, will be using the unsigned one. + uint32_t is_unsigned_temp = PushSystemTemp(); + MarkSystemConstantUsed(SystemConstants::Index::kTextureSwizzledSigns); + a_.OpUBFE(dxbc::Dest::R(is_unsigned_temp, 0b0001), dxbc::Src::LU(8), + dxbc::Src::LU(signs_shift), signs_uint_src); + a_.OpINE(dxbc::Dest::R(is_unsigned_temp, 0b0001), + dxbc::Src::R(is_unsigned_temp, dxbc::Src::kXXXX), + dxbc::Src::LU(uint32_t(xenos::TextureSign::kSigned) * 0b01010101)); + if (bindless_resources_used_) { + // Bindless path - select the SRV index between unsigned and signed to + // query. + if (instr.dimension == xenos::FetchOpDimension::k3DOrStacked) { + // Check if 3D. + assert_true((size_needed_components & 0b1000) == 0b1000); + a_.OpIf(true, dxbc::Src::R(size_and_is_3d_temp, dxbc::Src::kWWWW)); + } + for (uint32_t is_stacked = 0; + is_stacked < (instr.dimension == xenos::FetchOpDimension::k3DOrStacked ? 2u : 1u); + ++is_stacked) { + xenos::FetchOpDimension srv_dimension = instr.dimension; + if (is_stacked) { + srv_dimension = xenos::FetchOpDimension::k2D; + a_.OpElse(); + } + uint32_t texture_binding_index_unsigned = + FindOrAddTextureBinding(tfetch_index, srv_dimension, false); + uint32_t texture_binding_index_signed = + FindOrAddTextureBinding(tfetch_index, srv_dimension, true); + uint32_t texture_bindless_descriptor_index_unsigned = + texture_bindings_[texture_binding_index_unsigned].bindless_descriptor_index; + uint32_t texture_bindless_descriptor_index_signed = + texture_bindings_[texture_binding_index_signed].bindless_descriptor_index; + if (cbuffer_index_descriptor_indices_ == kBindingIndexUnallocated) { + cbuffer_index_descriptor_indices_ = cbuffer_count_++; + } + a_.OpMovC(dxbc::Dest::R(is_unsigned_temp, 0b0001), + dxbc::Src::R(is_unsigned_temp, dxbc::Src::kXXXX), + dxbc::Src::CB(cbuffer_index_descriptor_indices_, + uint32_t(CbufferRegister::kDescriptorIndices), + texture_bindless_descriptor_index_unsigned >> 2) + .Select(texture_bindless_descriptor_index_unsigned & 3), + dxbc::Src::CB(cbuffer_index_descriptor_indices_, + uint32_t(CbufferRegister::kDescriptorIndices), + texture_bindless_descriptor_index_signed >> 2) + .Select(texture_bindless_descriptor_index_signed & 3)); + // Always 3 coordinate components (1D and 2D are padded to 2D + // arrays, 3D and cube have 3 coordinate dimensions). Not caring + // about normalization of the array layer because it doesn't + // participate in LOD calculation in Direct3D 12. + // The `lod` instruction returns the unclamped LOD (probably need + // unclamped so it can be biased back into the range later) in the Y + // component, and the resource swizzle is the return value swizzle. + // FIXME(Triang3l): Gradient exponent adjustment from the fetch + // constant needs to be applied here, would require math involving + // SV_Position parity, replacing coordinates for one pixel with 0 + // and for another with the adjusted gradient, but possibly not used + // by any games. + assert_true(used_result_nonzero_components == 0b0001); + uint32_t* bindless_srv_index = nullptr; + switch (srv_dimension) { + case xenos::FetchOpDimension::k1D: + case xenos::FetchOpDimension::k2D: + bindless_srv_index = &srv_index_bindless_textures_2d_; + break; + case xenos::FetchOpDimension::k3DOrStacked: + bindless_srv_index = &srv_index_bindless_textures_3d_; + break; + case xenos::FetchOpDimension::kCube: + bindless_srv_index = &srv_index_bindless_textures_cube_; + break; + } + assert_not_null(bindless_srv_index); + if (*bindless_srv_index == kBindingIndexUnallocated) { + *bindless_srv_index = srv_count_++; + } + a_.OpLOD( + dxbc::Dest::R(system_temp_result_, 0b0001), dxbc::Src::R(coord_and_sampler_temp), 3, + dxbc::Src::T(*bindless_srv_index, dxbc::Index(is_unsigned_temp, 0), dxbc::Src::kYYYY), + sampler); + } + if (instr.dimension == xenos::FetchOpDimension::k3DOrStacked) { + // Close the 3D/stacked check. + a_.OpEndIf(); + } + } else { + // Bindful path - conditionally query one of the SRVs. + a_.OpIf(true, dxbc::Src::R(is_unsigned_temp, dxbc::Src::kXXXX)); + for (uint32_t is_signed = 0; is_signed < 2; ++is_signed) { + if (is_signed) { + a_.OpElse(); + } + if (instr.dimension == xenos::FetchOpDimension::k3DOrStacked) { + // Check if 3D. + assert_true((size_needed_components & 0b1000) == 0b1000); + a_.OpIf(true, dxbc::Src::R(size_and_is_3d_temp, dxbc::Src::kWWWW)); + } + for (uint32_t is_stacked = 0; + is_stacked < (instr.dimension == xenos::FetchOpDimension::k3DOrStacked ? 2u : 1u); + ++is_stacked) { + if (is_stacked) { + a_.OpElse(); + } + assert_true(used_result_nonzero_components == 0b0001); + uint32_t texture_binding_index = FindOrAddTextureBinding( + tfetch_index, is_stacked ? xenos::FetchOpDimension::k2D : instr.dimension, + is_signed != 0); + a_.OpLOD(dxbc::Dest::R(system_temp_result_, 0b0001), + dxbc::Src::R(coord_and_sampler_temp), 3, + dxbc::Src::T( + texture_bindings_[texture_binding_index].bindful_srv_index, + uint32_t(SRVMainRegister::kBindfulTexturesStart) + texture_binding_index, + dxbc::Src::kYYYY), + sampler); + } + if (instr.dimension == xenos::FetchOpDimension::k3DOrStacked) { + // Close the 3D/stacked check. + a_.OpEndIf(); + } + } + // Close the signedness check. + a_.OpEndIf(); + } + // Release is_unsigned_temp. + PopSystemTemp(); + } else { + // - Gradients or LOD to be passed to the sample_d/sample_l. + + dxbc::Src lod_src(dxbc::Src::LF(0.0f)); + uint32_t grad_component_count = 0; + // Will be allocated for both explicit and computed LOD. + uint32_t grad_h_lod_temp = UINT32_MAX; + // Will be allocated for computed LOD only, and if not using basemap mip + // filter. + uint32_t grad_v_temp = UINT32_MAX; + if (instr.attributes.mip_filter != xenos::TextureFilter::kBaseMap) { + grad_h_lod_temp = PushSystemTemp(); + lod_src = dxbc::Src::R(grad_h_lod_temp, dxbc::Src::kWWWW); + // Accumulate the explicit LOD sources (in D3D11.3 specification order: + // specified LOD + sampler LOD bias + instruction LOD bias). + dxbc::Dest lod_dest(dxbc::Dest::R(grad_h_lod_temp, 0b1000)); + // Fetch constant LOD bias * 32. + a_.OpIBFE(lod_dest, dxbc::Src::LU(10), dxbc::Src::LU(12), + RequestTextureFetchConstantWord(tfetch_index, 4)); + a_.OpIToF(lod_dest, lod_src); + if (instr.attributes.use_register_lod) { + // Divide the fetch constant LOD bias by 32, and add the register LOD + // and the instruction LOD bias. + a_.OpMAd(lod_dest, lod_src, dxbc::Src::LF(1.0f / 32.0f), + dxbc::Src::R(system_temp_grad_h_lod_, dxbc::Src::kWWWW)); + if (instr.attributes.lod_bias) { + a_.OpAdd(lod_dest, lod_src, dxbc::Src::LF(instr.attributes.lod_bias)); + } + } else { + // Divide the fetch constant LOD by 32, and add the instruction LOD + // bias. + if (instr.attributes.lod_bias) { + a_.OpMAd(lod_dest, lod_src, dxbc::Src::LF(1.0f / 32.0f), + dxbc::Src::LF(instr.attributes.lod_bias)); + } else { + a_.OpMul(lod_dest, lod_src, dxbc::Src::LF(1.0f / 32.0f)); + } + } + if (use_computed_lod) { + grad_v_temp = PushSystemTemp(); + switch (instr.dimension) { + case xenos::FetchOpDimension::k1D: + grad_component_count = 1; + break; + case xenos::FetchOpDimension::k2D: + grad_component_count = 2; + break; + case xenos::FetchOpDimension::k3DOrStacked: + case xenos::FetchOpDimension::kCube: + grad_component_count = 3; + break; + } + assert_not_zero(grad_component_count); + uint32_t grad_mask = (1 << grad_component_count) - 1; + // Convert the bias to a gradient scale. + a_.OpExp(lod_dest, lod_src); + // FIXME(Triang3l): Gradient exponent adjustment is currently not done + // in getCompTexLOD, so don't do it here too. +#if 0 + // Extract gradient exponent biases from the fetch constant and merge + // them with the LOD bias. + a_.OpIBFE(dxbc::Dest::R(grad_h_lod_temp, 0b0011), dxbc::Src::LU(5), + dxbc::Src::LU(22, 27, 0, 0), + RequestTextureFetchConstantWord(tfetch_index, 4)); + a_.OpIMAd(dxbc::Dest::R(grad_h_lod_temp, 0b0011), + dxbc::Src::R(grad_h_lod_temp), + dxbc::Src::LI(int32_t(1) << 23), dxbc::Src::LF(1.0f)); + a_.OpMul(dxbc::Dest::R(grad_v_temp, 0b1000), lod_src, + dxbc::Src::R(grad_h_lod_temp, dxbc::Src::kYYYY)); + a_.OpMul(lod_dest, lod_src, + dxbc::Src::R(grad_h_lod_temp, dxbc::Src::kXXXX)); +#endif + // Obtain the gradients and apply biases to them. + if (instr.attributes.use_register_gradients) { + // Register gradients are already in the cube space for cube maps. + a_.OpMul(dxbc::Dest::R(grad_h_lod_temp, grad_mask), + dxbc::Src::R(system_temp_grad_h_lod_), lod_src); + // FIXME(Triang3l): Gradient exponent adjustment is currently not + // done in getCompTexLOD, so don't do it here too. +#if 0 + a_.OpMul(dxbc::Dest::R(grad_v_temp, grad_mask), + dxbc::Src::R(system_temp_grad_v_vfetch_address_), + dxbc::Src::R(grad_v_temp, dxbc::Src::kWWWW)); +#else + a_.OpMul(dxbc::Dest::R(grad_v_temp, grad_mask), + dxbc::Src::R(system_temp_grad_v_vfetch_address_), lod_src); +#endif + // TODO(Triang3l): Are cube map register gradients unnormalized if + // the coordinates themselves are unnormalized? + if (instr.attributes.unnormalized_coordinates && + instr.dimension != xenos::FetchOpDimension::kCube) { + uint32_t grad_norm_mask = grad_mask; + if (instr.dimension == xenos::FetchOpDimension::k3DOrStacked) { + grad_norm_mask &= 0b0011; + } + assert_true((size_needed_components & grad_norm_mask) == grad_norm_mask); + a_.OpDiv(dxbc::Dest::R(grad_h_lod_temp, grad_norm_mask), + dxbc::Src::R(grad_h_lod_temp), dxbc::Src::R(size_and_is_3d_temp)); + a_.OpDiv(dxbc::Dest::R(grad_v_temp, grad_norm_mask), dxbc::Src::R(grad_v_temp), + dxbc::Src::R(size_and_is_3d_temp)); + // Normalize Z of the gradients for fetching from the 3D texture. + assert_true((size_needed_components & 0b1100) == 0b1100); + a_.OpIf(true, dxbc::Src::R(size_and_is_3d_temp, dxbc::Src::kWWWW)); + a_.OpDiv(dxbc::Dest::R(grad_h_lod_temp, 0b0100), + dxbc::Src::R(grad_h_lod_temp, dxbc::Src::kZZZZ), + dxbc::Src::R(size_and_is_3d_temp, dxbc::Src::kZZZZ)); + a_.OpDiv(dxbc::Dest::R(grad_v_temp, 0b0100), + dxbc::Src::R(grad_v_temp, dxbc::Src::kZZZZ), + dxbc::Src::R(size_and_is_3d_temp, dxbc::Src::kZZZZ)); + a_.OpEndIf(); + } + } else { + // Coarse is according to the Direct3D 11.3 specification. + a_.OpDerivRTXCoarse(dxbc::Dest::R(grad_h_lod_temp, grad_mask), + dxbc::Src::R(coord_and_sampler_temp)); + a_.OpMul(dxbc::Dest::R(grad_h_lod_temp, grad_mask), dxbc::Src::R(grad_h_lod_temp), + lod_src); + a_.OpDerivRTYCoarse(dxbc::Dest::R(grad_v_temp, grad_mask), + dxbc::Src::R(coord_and_sampler_temp)); + // FIXME(Triang3l): Gradient exponent adjustment is currently not + // done in getCompTexLOD, so don't do it here too. +#if 0 + a_.OpMul(dxbc::Dest::R(grad_v_temp, grad_mask), + dxbc::Src::R(grad_v_temp), + dxbc::Src::R(grad_v_temp, dxbc::Src::kWWWW)); +#else + a_.OpMul(dxbc::Dest::R(grad_v_temp, grad_mask), dxbc::Src::R(grad_v_temp), lod_src); +#endif + } + if (instr.dimension == xenos::FetchOpDimension::k1D) { + // Pad the gradients to 2D because 1D textures are fetched as 2D + // arrays. + a_.OpMov(dxbc::Dest::R(grad_h_lod_temp, 0b0010), dxbc::Src::LF(0.0f)); + a_.OpMov(dxbc::Dest::R(grad_v_temp, 0b0010), dxbc::Src::LF(0.0f)); + grad_component_count = 2; + } + } + } + + // - Data. + + // 4D5307F2 uses vertex displacement map textures for tessellated models + // like the beehive tree with explicit LOD with point sampling (they store + // values packed in two components), however, the fetch constant has + // anisotropic filtering enabled. However, Direct3D 12 doesn't allow + // mixing anisotropic and point filtering. Possibly anistropic filtering + // should be disabled when explicit LOD is used - do this here. + uint32_t sampler_binding_index = FindOrAddSamplerBinding( + tfetch_index, instr.attributes.mag_filter, instr.attributes.min_filter, + instr.attributes.mip_filter, + use_computed_lod ? instr.attributes.aniso_filter : xenos::AnisoFilter::kDisabled); + dxbc::Src sampler(dxbc::Src::S(sampler_binding_index, sampler_binding_index)); + if (bindless_resources_used_) { + // Load the sampler index to coord_and_sampler_temp.w and use relative + // sampler indexing. + if (cbuffer_index_descriptor_indices_ == kBindingIndexUnallocated) { + cbuffer_index_descriptor_indices_ = cbuffer_count_++; + } + uint32_t sampler_bindless_descriptor_index = + sampler_bindings_[sampler_binding_index].bindless_descriptor_index; + a_.OpMov(dxbc::Dest::R(coord_and_sampler_temp, 0b1000), + dxbc::Src::CB(cbuffer_index_descriptor_indices_, + uint32_t(CbufferRegister::kDescriptorIndices), + sampler_bindless_descriptor_index >> 2) + .Select(sampler_bindless_descriptor_index & 3)); + sampler = dxbc::Src::S(0, dxbc::Index(coord_and_sampler_temp, 3)); + } + + // Break result register dependencies because textures will be sampled + // conditionally, including the primary signs. + a_.OpMov(dxbc::Dest::R(system_temp_result_, used_result_nonzero_components), + dxbc::Src::LF(0.0f)); + + // Extract whether each component is signed. + uint32_t is_signed_temp = PushSystemTemp(); + a_.OpIEq(dxbc::Dest::R(is_signed_temp, used_result_nonzero_components), + dxbc::Src::R(signs_temp), dxbc::Src::LU(uint32_t(xenos::TextureSign::kSigned))); + + // Calculate the lerp factor between stacked texture layers if needed (or + // 0 if point-sampled), and check which signedness SRVs need to be + // sampled. + // As a result, if srv_selection_temp is allocated at all: + // - srv_selection_temp.x - if multiple components, whether all components + // are signed, wrapped by is_all_signed_src with a fallback for the + // single component case. If false, the unsigned SRV needs to be + // sampled. + // - srv_selection_temp.y - if multiple components, whether any component + // is signed, wrapped by is_any_signed_src with a fallback for the + // single component case. If true, the signed SRV needs to be sampled. + // - srv_selection_temp.z - if stacked and not forced to be point-sampled, + // the lerp factor between two layers, wrapped by layer_lerp_factor_src + // with l(0.0) fallback for the point sampling case. + // - srv_selection_temp.w - first, scratch for calculations involving + // these, then, unsigned or signed SRV description index. + dxbc::Src layer_lerp_factor_src(dxbc::Src::LF(0.0f)); + // W is always needed for bindless. + uint32_t srv_selection_temp = bindless_resources_used_ ? PushSystemTemp() : UINT32_MAX; + if (instr.dimension == xenos::FetchOpDimension::k3DOrStacked) { + bool vol_mag_filter_is_fetch_const = + instr.attributes.vol_mag_filter == xenos::TextureFilter::kUseFetchConst; + bool vol_min_filter_is_fetch_const = + instr.attributes.vol_min_filter == xenos::TextureFilter::kUseFetchConst; + bool vol_mag_filter_is_linear = + instr.attributes.vol_mag_filter == xenos::TextureFilter::kLinear; + bool vol_min_filter_is_linear = + instr.attributes.vol_min_filter == xenos::TextureFilter::kLinear; + if (grad_v_temp != UINT32_MAX && + (vol_mag_filter_is_fetch_const || vol_min_filter_is_fetch_const || + vol_mag_filter_is_linear != vol_min_filter_is_linear)) { + if (srv_selection_temp == UINT32_MAX) { + srv_selection_temp = PushSystemTemp(); + } + layer_lerp_factor_src = dxbc::Src::R(srv_selection_temp, dxbc::Src::kZZZZ); + // Initialize to point sampling, and break register dependency for 3D. + a_.OpMov(dxbc::Dest::R(srv_selection_temp, 0b0100), dxbc::Src::LF(0.0f)); + assert_true((size_needed_components & 0b1000) == 0b1000); + a_.OpIf(false, dxbc::Src::R(size_and_is_3d_temp, dxbc::Src::kWWWW)); + // Check if minifying along layers (derivative > 1 along any axis). + a_.OpMax(dxbc::Dest::R(srv_selection_temp, 0b1000), + dxbc::Src::R(grad_h_lod_temp, dxbc::Src::kZZZZ), + dxbc::Src::R(grad_v_temp, dxbc::Src::kZZZZ)); + if (!instr.attributes.unnormalized_coordinates) { + // Denormalize the gradient if provided as normalized. + assert_true((size_needed_components & 0b0100) == 0b0100); + a_.OpMul(dxbc::Dest::R(srv_selection_temp, 0b1000), + dxbc::Src::R(srv_selection_temp, dxbc::Src::kWWWW), + dxbc::Src::R(size_and_is_3d_temp, dxbc::Src::kZZZZ)); + } + // For NaN, considering that magnification is being done. Zero + // srv_selection_temp.w means magnifying, non-zero means minifying. + a_.OpLT(dxbc::Dest::R(srv_selection_temp, 0b1000), dxbc::Src::LF(1.0f), + dxbc::Src::R(srv_selection_temp, dxbc::Src::kWWWW)); + if (vol_mag_filter_is_fetch_const || vol_min_filter_is_fetch_const) { + a_.OpIf(false, dxbc::Src::R(srv_selection_temp, dxbc::Src::kWWWW)); + // Write the magnification filter to srv_selection_temp.w. In the + // "if" rather than "else" because this is more likely to happen if + // the layer is constant. + if (vol_mag_filter_is_fetch_const) { + a_.OpAnd(dxbc::Dest::R(srv_selection_temp, 0b1000), + RequestTextureFetchConstantWord(tfetch_index, 4), dxbc::Src::LU(1)); + } else { + a_.OpMov(dxbc::Dest::R(srv_selection_temp, 0b1000), + dxbc::Src::LU(uint32_t(vol_mag_filter_is_linear))); + } + a_.OpElse(); + // Write the minification filter to srv_selection_temp.w. + if (vol_min_filter_is_fetch_const) { + a_.OpUBFE(dxbc::Dest::R(srv_selection_temp, 0b1000), dxbc::Src::LU(1), + dxbc::Src::LU(1), RequestTextureFetchConstantWord(tfetch_index, 4)); + } else { + a_.OpMov(dxbc::Dest::R(srv_selection_temp, 0b1000), + dxbc::Src::LU(uint32_t(vol_min_filter_is_linear))); + } + // Close the magnification check. + a_.OpEndIf(); + // Check if the filter is linear. + a_.OpIf(true, dxbc::Src::R(srv_selection_temp, dxbc::Src::kWWWW)); + } else if (vol_mag_filter_is_linear) { + assert_false(vol_min_filter_is_linear); + // Both overridden, one (magnification) is linear, another + // (minification) is not - handle linear filtering if magnifying. + a_.OpIf(false, dxbc::Src::R(srv_selection_temp, dxbc::Src::kWWWW)); + } else { + assert_true(vol_min_filter_is_linear); + assert_false(vol_mag_filter_is_linear); + // Both overridden, one (minification) is linear, another + // (magnification) is not - handle linear filtering if minifying. + a_.OpIf(true, dxbc::Src::R(srv_selection_temp, dxbc::Src::kWWWW)); + } + // For linear filtering, subtract 0.5 from the coordinates and store + // the lerp factor. Flooring will be done later. + a_.OpAdd(dxbc::Dest::R(coord_and_sampler_temp, 0b0100), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kZZZZ), dxbc::Src::LF(-0.5f)); + a_.OpFrc(dxbc::Dest::R(srv_selection_temp, 0b0100), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kZZZZ)); + // Close the linear check. + a_.OpEndIf(); + // Close the stacked check. + a_.OpEndIf(); + } else { + // No gradients, or using the same filter overrides for magnifying and + // minifying. Assume always magnifying if no gradients (LOD 0, always + // <= 0). LOD is within 2D layers, not between them (unlike in 3D + // textures, which have mips with depth reduced). + if (vol_mag_filter_is_fetch_const || vol_mag_filter_is_linear) { + if (srv_selection_temp == UINT32_MAX) { + srv_selection_temp = PushSystemTemp(); + } + layer_lerp_factor_src = dxbc::Src::R(srv_selection_temp, dxbc::Src::kZZZZ); + // Initialize to point sampling, and break register dependency for + // 3D. + a_.OpMov(dxbc::Dest::R(srv_selection_temp, 0b0100), dxbc::Src::LF(0.0f)); + assert_true((size_needed_components & 0b1000) == 0b1000); + a_.OpIf(false, dxbc::Src::R(size_and_is_3d_temp, dxbc::Src::kWWWW)); + if (vol_mag_filter_is_fetch_const) { + // Extract the magnification filtering mode from the fetch + // constant. + a_.OpAnd(dxbc::Dest::R(srv_selection_temp, 0b1000), + RequestTextureFetchConstantWord(tfetch_index, 4), dxbc::Src::LU(1)); + // Check if it's linear. + a_.OpIf(true, dxbc::Src::R(srv_selection_temp, dxbc::Src::kWWWW)); + } + // For linear filtering, subtract 0.5 from the coordinates and store + // the lerp factor. Flooring will be done later. + a_.OpAdd(dxbc::Dest::R(coord_and_sampler_temp, 0b0100), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kZZZZ), dxbc::Src::LF(-0.5f)); + a_.OpFrc(dxbc::Dest::R(srv_selection_temp, 0b0100), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kZZZZ)); + if (vol_mag_filter_is_fetch_const) { + // Close the fetch constant linear filtering mode check. + a_.OpEndIf(); + } + // Close the stacked check. + a_.OpEndIf(); + } + } + } + // Check if any component is not signed, and if any component is signed. + uint32_t result_first_component; + rex::bit_scan_forward(used_result_nonzero_components, &result_first_component); + dxbc::Src is_all_signed_src(dxbc::Src::R(is_signed_temp).Select(result_first_component)); + dxbc::Src is_any_signed_src(dxbc::Src::R(is_signed_temp).Select(result_first_component)); + if (used_result_nonzero_components != (1 << result_first_component)) { + // Multiple components fetched - need to merge. + if (srv_selection_temp == UINT32_MAX) { + srv_selection_temp = PushSystemTemp(); + } + dxbc::Dest is_all_signed_dest(dxbc::Dest::R(srv_selection_temp, 0b0001)); + dxbc::Dest is_any_signed_dest(dxbc::Dest::R(srv_selection_temp, 0b0010)); + uint32_t result_remaining_components = + used_result_nonzero_components & ~(uint32_t(1) << result_first_component); + uint32_t result_component; + while (rex::bit_scan_forward(result_remaining_components, &result_component)) { + result_remaining_components &= ~(uint32_t(1) << result_component); + a_.OpAnd(is_all_signed_dest, is_all_signed_src, + dxbc::Src::R(is_signed_temp).Select(result_component)); + a_.OpOr(is_any_signed_dest, is_any_signed_src, + dxbc::Src::R(is_signed_temp).Select(result_component)); + // For the first component, both sources must both be two is_signed + // components, to initialize. + is_all_signed_src = dxbc::Src::R(srv_selection_temp, dxbc::Src::kXXXX); + is_any_signed_src = dxbc::Src::R(srv_selection_temp, dxbc::Src::kYYYY); + } + } + + // Sample the texture - choose between 3D and stacked, and then sample + // unsigned and signed SRVs and choose between them. + + if (instr.dimension == xenos::FetchOpDimension::k3DOrStacked) { + assert_true((size_needed_components & 0b1000) == 0b1000); + // The first fetch attempt will be for the 3D SRV. + a_.OpIf(true, dxbc::Src::R(size_and_is_3d_temp, dxbc::Src::kWWWW)); + } + for (uint32_t is_stacked = 0; + is_stacked < (instr.dimension == xenos::FetchOpDimension::k3DOrStacked ? 2u : 1u); + ++is_stacked) { + // i == 0 - 1D/2D/3D/cube. + // i == 1 - 2D stacked. + xenos::FetchOpDimension srv_dimension = instr.dimension; + uint32_t srv_grad_component_count = grad_component_count; + bool layer_lerp_needed = false; + if (is_stacked) { + srv_dimension = xenos::FetchOpDimension::k2D; + srv_grad_component_count = 2; + layer_lerp_needed = layer_lerp_factor_src.type_ != dxbc::OperandType::kImmediate32; + a_.OpElse(); + // Floor the array layer (Direct3D 12 does rounding to nearest even + // for the layer index, but on the Xbox 360, addressing is similar to + // that of 3D textures). This is needed for both point and linear + // filtering (with linear, 0.5 was subtracted previously). + a_.OpRoundNI(dxbc::Dest::R(coord_and_sampler_temp, 0b0100), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kZZZZ)); + } + uint32_t texture_binding_index_unsigned = + FindOrAddTextureBinding(tfetch_index, srv_dimension, false); + uint32_t texture_binding_index_signed = + FindOrAddTextureBinding(tfetch_index, srv_dimension, true); + const TextureBinding& texture_binding_unsigned = + texture_bindings_[texture_binding_index_unsigned]; + const TextureBinding& texture_binding_signed = + texture_bindings_[texture_binding_index_signed]; + dxbc::Src srv_unsigned(dxbc::Src::LF(0.0f)), srv_signed(dxbc::Src::LF(0.0f)); + if (bindless_resources_used_) { + uint32_t* bindless_srv_index = nullptr; + switch (srv_dimension) { + case xenos::FetchOpDimension::k1D: + case xenos::FetchOpDimension::k2D: + bindless_srv_index = &srv_index_bindless_textures_2d_; + break; + case xenos::FetchOpDimension::k3DOrStacked: + bindless_srv_index = &srv_index_bindless_textures_3d_; + break; + case xenos::FetchOpDimension::kCube: + bindless_srv_index = &srv_index_bindless_textures_cube_; + break; + } + assert_not_null(bindless_srv_index); + if (*bindless_srv_index == kBindingIndexUnallocated) { + *bindless_srv_index = srv_count_++; + } + assert_true(srv_selection_temp != UINT32_MAX); + srv_unsigned = dxbc::Src::T(*bindless_srv_index, dxbc::Index(srv_selection_temp, 3)); + srv_signed = srv_unsigned; + } else { + srv_unsigned = dxbc::Src::T( + texture_binding_unsigned.bindful_srv_index, + uint32_t(SRVMainRegister::kBindfulTexturesStart) + texture_binding_index_unsigned); + srv_signed = dxbc::Src::T( + texture_binding_signed.bindful_srv_index, + uint32_t(SRVMainRegister::kBindfulTexturesStart) + texture_binding_index_signed); + } + for (uint32_t layer = 0; layer < (layer_lerp_needed ? 2u : 1u); ++layer) { + uint32_t layer_value_temp = system_temp_result_; + if (layer) { + layer_value_temp = PushSystemTemp(); + // Check if the lerp factor is not zero (or NaN). + a_.OpNE(dxbc::Dest::R(layer_value_temp, 0b0001), layer_lerp_factor_src, + dxbc::Src::LF(0.0f)); + // If the lerp factor is not zero, sample the next layer. + a_.OpIf(true, dxbc::Src::R(layer_value_temp, dxbc::Src::kXXXX)); + // Go to the next layer. + a_.OpAdd(dxbc::Dest::R(coord_and_sampler_temp, 0b0100), + dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kZZZZ), dxbc::Src::LF(1.0f)); + } + // Always 3 coordinate components (1D and 2D are padded to 2D arrays, + // 3D and cube have 3 coordinate dimensions). + a_.OpIf(false, is_all_signed_src); + { + // Sample the unsigned texture. + if (bindless_resources_used_) { + // Load the unsigned texture descriptor index. + assert_true(srv_selection_temp != UINT32_MAX); + if (cbuffer_index_descriptor_indices_ == kBindingIndexUnallocated) { + cbuffer_index_descriptor_indices_ = cbuffer_count_++; + } + uint32_t texture_bindless_descriptor_index = + texture_binding_unsigned.bindless_descriptor_index; + a_.OpMov(dxbc::Dest::R(srv_selection_temp, 0b1000), + dxbc::Src::CB(cbuffer_index_descriptor_indices_, + uint32_t(CbufferRegister::kDescriptorIndices), + texture_bindless_descriptor_index >> 2) + .Select(texture_bindless_descriptor_index & 3)); + } + if (grad_v_temp != UINT32_MAX) { + assert_not_zero(grad_component_count); + a_.OpSampleD(dxbc::Dest::R(layer_value_temp, used_result_nonzero_components), + dxbc::Src::R(coord_and_sampler_temp), 3, srv_unsigned, sampler, + dxbc::Src::R(grad_h_lod_temp), dxbc::Src::R(grad_v_temp), + srv_grad_component_count); + } else { + a_.OpSampleL(dxbc::Dest::R(layer_value_temp, used_result_nonzero_components), + dxbc::Src::R(coord_and_sampler_temp), 3, srv_unsigned, sampler, lod_src); + } + } + a_.OpEndIf(); + a_.OpIf(true, is_any_signed_src); + { + // Sample the signed texture. + uint32_t signed_temp = PushSystemTemp(); + if (bindless_resources_used_) { + // Load the signed texture descriptor index. + assert_true(srv_selection_temp != UINT32_MAX); + if (cbuffer_index_descriptor_indices_ == kBindingIndexUnallocated) { + cbuffer_index_descriptor_indices_ = cbuffer_count_++; + } + uint32_t texture_bindless_descriptor_index = + texture_binding_signed.bindless_descriptor_index; + a_.OpMov(dxbc::Dest::R(srv_selection_temp, 0b1000), + dxbc::Src::CB(cbuffer_index_descriptor_indices_, + uint32_t(CbufferRegister::kDescriptorIndices), + texture_bindless_descriptor_index >> 2) + .Select(texture_bindless_descriptor_index & 3)); + } + if (grad_v_temp != UINT32_MAX) { + assert_not_zero(grad_component_count); + a_.OpSampleD(dxbc::Dest::R(signed_temp, used_result_nonzero_components), + dxbc::Src::R(coord_and_sampler_temp), 3, srv_signed, sampler, + dxbc::Src::R(grad_h_lod_temp), dxbc::Src::R(grad_v_temp), + srv_grad_component_count); + } else { + a_.OpSampleL(dxbc::Dest::R(signed_temp, used_result_nonzero_components), + dxbc::Src::R(coord_and_sampler_temp), 3, srv_signed, sampler, lod_src); + } + a_.OpMovC(dxbc::Dest::R(layer_value_temp, used_result_nonzero_components), + dxbc::Src::R(is_signed_temp), dxbc::Src::R(signed_temp), + dxbc::Src::R(layer_value_temp)); + // Release signed_temp. + PopSystemTemp(); + } + a_.OpEndIf(); + if (layer) { + assert_true(layer_value_temp != system_temp_result_); + // Interpolate between the two layers. + a_.OpAdd(dxbc::Dest::R(layer_value_temp, used_result_nonzero_components), + dxbc::Src::R(layer_value_temp), -dxbc::Src::R(system_temp_result_)); + a_.OpMAd(dxbc::Dest::R(system_temp_result_, used_result_nonzero_components), + dxbc::Src::R(layer_value_temp), layer_lerp_factor_src, + dxbc::Src::R(system_temp_result_)); + // Close the linear filtering check. + a_.OpEndIf(); + // Release the allocated layer_value_temp. + PopSystemTemp(); + } + } + } + if (instr.dimension == xenos::FetchOpDimension::k3DOrStacked) { + // Close the stacked/3D check. + a_.OpEndIf(); + } + + if (srv_selection_temp != UINT32_MAX) { + PopSystemTemp(); + } + // Release is_signed_temp. + PopSystemTemp(); + + // Release grad_h_lod_temp and grad_v_temp. + if (grad_v_temp != UINT32_MAX) { + PopSystemTemp(); + } + if (grad_h_lod_temp != UINT32_MAX) { + PopSystemTemp(); + } + } + + // Release coord_and_sampler_temp. + PopSystemTemp(); + + // Apply the bias and gamma correction (gamma is after filtering here, + // likely should be before, but it's outside Xenia's control for host + // sampler filtering). + if (instr.opcode == FetchOpcode::kTextureFetch) { + assert_true(signs_temp != UINT32_MAX); + for (uint32_t i = 0; i < 4; ++i) { + if (!(used_result_nonzero_components & (1 << i))) { + continue; + } + dxbc::Dest component_dest(dxbc::Dest::R(system_temp_result_, 1 << i)); + dxbc::Src component_src(dxbc::Src::R(system_temp_result_).Select(i)); + a_.OpSwitch(dxbc::Src::R(signs_temp).Select(i)); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::TextureSign::kUnsignedBiased))); + a_.OpMAd(component_dest, component_src, dxbc::Src::LF(2.0f), dxbc::Src::LF(-1.0f)); + a_.OpBreak(); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::TextureSign::kGamma))); + uint32_t gamma_temp = PushSystemTemp(); + // Convert from piecewise linear. + PWLGammaToLinear(a_, system_temp_result_, i, system_temp_result_, i, false, gamma_temp, 0, + gamma_temp, 1); + // Release gamma_temp. + PopSystemTemp(); + a_.OpBreak(); + a_.OpEndSwitch(); + } + } + if (signs_temp != UINT32_MAX) { + PopSystemTemp(); + } + } + + if (size_and_is_3d_temp != UINT32_MAX) { + PopSystemTemp(); + } + + if (instr.opcode == FetchOpcode::kTextureFetch) { + // Apply the result exponent bias. + uint32_t exp_adjust_temp = PushSystemTemp(); + a_.OpIBFE(dxbc::Dest::R(exp_adjust_temp, 0b0001), dxbc::Src::LU(6), dxbc::Src::LU(13), + RequestTextureFetchConstantWord(tfetch_index, 3)); + a_.OpIMAd(dxbc::Dest::R(exp_adjust_temp, 0b0001), + dxbc::Src::R(exp_adjust_temp, dxbc::Src::kXXXX), dxbc::Src::LI(int32_t(1) << 23), + dxbc::Src::LF(1.0f)); + a_.OpMul(dxbc::Dest::R(system_temp_result_, used_result_nonzero_components), + dxbc::Src::R(system_temp_result_), dxbc::Src::R(exp_adjust_temp, dxbc::Src::kXXXX)); + // Release exp_adjust_temp. + PopSystemTemp(); + } + + uint32_t used_result_zero_components = used_result_components & ~used_result_nonzero_components; + if (used_result_zero_components) { + a_.OpMov(dxbc::Dest::R(system_temp_result_, used_result_zero_components), dxbc::Src::LF(0.0f)); + } + StoreResult(instr.result, dxbc::Src::R(system_temp_result_)); +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/shader/dxbc_translator_memexport.cpp b/src/graphics/pipeline/shader/dxbc_translator_memexport.cpp new file mode 100644 index 0000000..e90a622 --- /dev/null +++ b/src/graphics/pipeline/shader/dxbc_translator_memexport.cpp @@ -0,0 +1,785 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2023 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include +#include + +namespace rex::graphics { +using namespace ucode; + +void DxbcShaderTranslator::ExportToMemory(uint8_t export_eM) { + if (!export_eM) { + return; + } + + assert_zero(export_eM & ~current_shader().memexport_eM_written()); + + // Check if memory export is allowed in this invocation. + a_.OpIf(true, dxbc::Src::R(system_temp_memexport_enabled_and_eM_written_, dxbc::Src::kXXXX)); + + // Check if the address with the correct sign and exponent was written, and + // that the index doesn't overflow the mantissa bits. + { + uint32_t address_check_temp = PushSystemTemp(); + a_.OpUShR(dxbc::Dest::R(address_check_temp), dxbc::Src::R(system_temp_memexport_address_), + dxbc::Src::LU(30, 23, 23, 23)); + a_.OpIEq(dxbc::Dest::R(address_check_temp), dxbc::Src::R(address_check_temp), + dxbc::Src::LU(0x1, 0x96, 0x96, 0x96)); + a_.OpAnd(dxbc::Dest::R(address_check_temp, 0b0011), dxbc::Src::R(address_check_temp), + dxbc::Src::R(address_check_temp, 0b1110)); + a_.OpAnd(dxbc::Dest::R(address_check_temp, 0b0001), + dxbc::Src::R(address_check_temp, dxbc::Src::kXXXX), + dxbc::Src::R(address_check_temp, dxbc::Src::kYYYY)); + a_.OpIf(true, dxbc::Src::R(address_check_temp, dxbc::Src::kXXXX)); + // Release address_check_temp. + PopSystemTemp(); + } + + uint8_t eM_remaining; + uint32_t eM_index; + + // Swap red and blue components if needed. + { + uint32_t red_blue_swap_temp = PushSystemTemp(); + a_.OpIBFE(dxbc::Dest::R(red_blue_swap_temp, 0b0001), dxbc::Src::LU(1), dxbc::Src::LU(19), + dxbc::Src::R(system_temp_memexport_address_, dxbc::Src::kZZZZ)); + a_.OpIf(true, dxbc::Src::R(red_blue_swap_temp, dxbc::Src::kXXXX)); + // Release red_blue_swap_temp. + PopSystemTemp(); + + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + a_.OpMov(dxbc::Dest::R(system_temps_memexport_data_[eM_index], 0b0101), + dxbc::Src::R(system_temps_memexport_data_[eM_index], 0b11000110)); + } + + // Close the red/blue swap conditional. + a_.OpEndIf(); + } + + uint32_t temp = PushSystemTemp(); + + // Extract the color format and the numeric format. + // temp.x = color format. + // temp.y = numeric format is signed. + // temp.z = numeric format is integer. + a_.OpUBFE(dxbc::Dest::R(temp, 0b0111), dxbc::Src::LU(6, 1, 1, 0), dxbc::Src::LU(8, 16, 17, 0), + dxbc::Src::R(system_temp_memexport_address_, dxbc::Src::kZZZZ)); + + // Perform format packing. + // After the switch, temp.x must contain log2 of the number of bytes in an + // element, of UINT32_MAX if the format is unknown. + a_.OpSwitch(dxbc::Src::R(temp, dxbc::Src::kXXXX)); + { + dxbc::Dest element_size_dest(dxbc::Dest::R(temp, 0b0001)); + dxbc::Src num_format_signed(dxbc::Src::R(temp, dxbc::Src::kYYYY)); + dxbc::Src num_format_integer(dxbc::Src::R(temp, dxbc::Src::kZZZZ)); + + auto flush_nan = [this, export_eM](uint32_t components) { + uint8_t eM_remaining = export_eM; + uint32_t eM_index; + uint32_t is_nan_temp = PushSystemTemp(); + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + a_.OpNE(dxbc::Dest::R(is_nan_temp, components), dxbc::Src::R(eM), dxbc::Src::R(eM)); + a_.OpMovC(dxbc::Dest::R(eM, components), dxbc::Src::R(is_nan_temp), dxbc::Src::LF(0.0f), + dxbc::Src::R(eM)); + } + // Release is_nan_temp. + PopSystemTemp(); + }; + + // The result will be in eM#.x. The widths must be without holes (R, RG, + // RGB, RGBA), and expecting the widths to add up to the size of the stored + // texel (8, 16 or 32 bits), as the unused upper bits will contain junk from + // the sign extension of X if the number is signed. + auto pack_8_16_32 = [&](std::array widths) { + uint8_t eM_remaining; + uint32_t eM_index; + + uint32_t components = 0; + std::array offsets = {}; + for (uint32_t i = 0; i < 4; ++i) { + if (widths[i]) { + // Only formats for which max + 0.5 can be represented exactly. + assert(widths[i] <= 23); + components |= uint32_t(1) << i; + } + if (i) { + offsets[i] = offsets[i - 1] + widths[i - 1]; + } + } + // Will be packing components into eM#.x starting from green, assume red + // will already be there after the conversion. + assert_not_zero(components & 0b1); + + flush_nan(components); + + a_.OpIf(true, num_format_signed); + { + // Signed. + a_.OpIf(true, num_format_integer); + { + // Signed integer. + float min_value[4] = {}, max_value[4] = {}; + for (uint32_t i = 0; i < 4; ++i) { + if (widths[i]) { + max_value[i] = float((uint32_t(1) << (widths[i] - 1)) - 1); + min_value[i] = -1.0f - max_value[i]; + } + } + dxbc::Src min_value_src(dxbc::Src::LP(min_value)); + dxbc::Src max_value_src(dxbc::Src::LP(max_value)); + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + a_.OpMax(dxbc::Dest::R(eM, components), min_value_src, dxbc::Src::R(eM)); + a_.OpMin(dxbc::Dest::R(eM, components), max_value_src, dxbc::Src::R(eM)); + } + } + a_.OpElse(); + { + // Signed normalized. + uint32_t scale_components = 0; + float scale[4] = {}; + for (uint32_t i = 0; i < 4; ++i) { + if (widths[i] > 2) { + scale_components |= uint32_t(1) << i; + scale[i] = float((uint32_t(1) << (widths[i] - 1)) - 1); + } + } + dxbc::Src scale_src(dxbc::Src::LP(scale)); + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + a_.OpMax(dxbc::Dest::R(eM, components), dxbc::Src::LF(-1.0f), dxbc::Src::R(eM)); + a_.OpMin(dxbc::Dest::R(eM, components), dxbc::Src::LF(1.0f), dxbc::Src::R(eM)); + if (scale_components) { + a_.OpMul(dxbc::Dest::R(eM, scale_components), dxbc::Src::R(eM), scale_src); + } + } + } + a_.OpEndIf(); + + // Add plus/minus 0.5 before truncating according to the Direct3D format + // conversion rules, and convert to signed integers. + uint32_t round_bias_temp = PushSystemTemp(); + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + a_.OpBFI(dxbc::Dest::R(eM, components), dxbc::Src::LU(31), dxbc::Src::LU(0), + dxbc::Src::LF(0.5f), dxbc::Src::R(eM)); + a_.OpAdd(dxbc::Dest::R(eM, components), dxbc::Src::R(eM), dxbc::Src::R(round_bias_temp)); + a_.OpFToI(dxbc::Dest::R(eM, components), dxbc::Src::R(eM)); + } + // Release round_bias_temp. + PopSystemTemp(); + } + a_.OpElse(); + { + // Unsigned. + a_.OpIf(true, num_format_integer); + { + // Unsigned integer. + float max_value[4]; + for (uint32_t i = 0; i < 4; ++i) { + max_value[i] = float((uint32_t(1) << widths[i]) - 1); + } + dxbc::Src max_value_src(dxbc::Src::LP(max_value)); + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + a_.OpMax(dxbc::Dest::R(eM, components), dxbc::Src::LF(0.0f), dxbc::Src::R(eM)); + a_.OpMin(dxbc::Dest::R(eM, components), max_value_src, dxbc::Src::R(eM)); + } + } + a_.OpElse(); + { + // Unsigned normalized. + uint32_t scale_components = 0; + float scale[4] = {}; + for (uint32_t i = 0; i < 4; ++i) { + if (widths[i] > 1) { + scale_components |= uint32_t(1) << i; + scale[i] = float((uint32_t(1) << widths[i]) - 1); + } + } + dxbc::Src scale_src(dxbc::Src::LP(scale)); + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + // Saturate. + a_.OpMov(dxbc::Dest::R(eM, components), dxbc::Src::R(eM), true); + if (scale_components) { + a_.OpMul(dxbc::Dest::R(eM, scale_components), dxbc::Src::R(eM), scale_src); + } + } + } + a_.OpEndIf(); + + // Add 0.5 before truncating according to the Direct3D format conversion + // rules, and convert to unsigned integers. + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + a_.OpAdd(dxbc::Dest::R(eM, components), dxbc::Src::R(eM), dxbc::Src::LF(0.5f)); + a_.OpFToU(dxbc::Dest::R(eM, components), dxbc::Src::R(eM)); + } + } + a_.OpEndIf(); + + // Pack into 32 bits. + for (uint32_t i = 0; i < 4; ++i) { + if (!widths[i]) { + continue; + } + dxbc::Src width_src(dxbc::Src::LU(widths[i])); + dxbc::Src offset_src(dxbc::Src::LU(offsets[i])); + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + a_.OpBFI(dxbc::Dest::R(eM, 0b0001), width_src, offset_src, dxbc::Src::R(eM).Select(i), + dxbc::Src::R(eM, dxbc::Src::kXXXX)); + } + } + }; + + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_8))); + // TODO(Triang3l): Investigate how input should be treated for k_8_A, k_8_B, + // k_8_8_8_8_A. + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_8_A))); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_8_B))); + { + pack_8_16_32({8}); + a_.OpMov(element_size_dest, dxbc::Src::LU(0)); + } + a_.OpBreak(); + + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_1_5_5_5))); + { + pack_8_16_32({5, 5, 5, 1}); + a_.OpMov(element_size_dest, dxbc::Src::LU(1)); + } + a_.OpBreak(); + + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_5_6_5))); + { + pack_8_16_32({5, 6, 5}); + a_.OpMov(element_size_dest, dxbc::Src::LU(1)); + } + a_.OpBreak(); + + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_6_5_5))); + { + pack_8_16_32({5, 5, 6}); + a_.OpMov(element_size_dest, dxbc::Src::LU(1)); + } + a_.OpBreak(); + + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_8_8_8_8))); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_8_8_8_8_A))); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_8_8_8_8_AS_16_16_16_16))); + { + pack_8_16_32({8, 8, 8, 8}); + a_.OpMov(element_size_dest, dxbc::Src::LU(2)); + } + a_.OpBreak(); + + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_2_10_10_10))); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_2_10_10_10_AS_16_16_16_16))); + { + pack_8_16_32({10, 10, 10, 2}); + a_.OpMov(element_size_dest, dxbc::Src::LU(2)); + } + a_.OpBreak(); + + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_8_8))); + { + pack_8_16_32({8, 8}); + a_.OpMov(element_size_dest, dxbc::Src::LU(1)); + } + a_.OpBreak(); + + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_4_4_4_4))); + { + pack_8_16_32({4, 4, 4, 4}); + a_.OpMov(element_size_dest, dxbc::Src::LU(1)); + } + a_.OpBreak(); + + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_10_11_11))); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_10_11_11_AS_16_16_16_16))); + { + pack_8_16_32({11, 11, 10}); + a_.OpMov(element_size_dest, dxbc::Src::LU(2)); + } + a_.OpBreak(); + + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_11_11_10))); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_11_11_10_AS_16_16_16_16))); + { + pack_8_16_32({10, 11, 11}); + a_.OpMov(element_size_dest, dxbc::Src::LU(2)); + } + a_.OpBreak(); + + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_16))); + { + pack_8_16_32({16}); + a_.OpMov(element_size_dest, dxbc::Src::LU(1)); + } + a_.OpBreak(); + + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_16_16))); + { + pack_8_16_32({16, 16}); + a_.OpMov(element_size_dest, dxbc::Src::LU(2)); + } + a_.OpBreak(); + + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_16_16_16_16))); + { + flush_nan(0b1111); + + a_.OpIf(true, num_format_signed); + { + // Signed. + a_.OpIf(true, num_format_integer); + { + // Signed integer. + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + a_.OpMax(dxbc::Dest::R(eM), dxbc::Src::LF(float(INT16_MIN)), dxbc::Src::R(eM)); + a_.OpMin(dxbc::Dest::R(eM), dxbc::Src::LF(float(INT16_MAX)), dxbc::Src::R(eM)); + } + } + a_.OpElse(); + { + // Signed normalized. + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + a_.OpMax(dxbc::Dest::R(eM), dxbc::Src::LF(-1.0f), dxbc::Src::R(eM)); + a_.OpMin(dxbc::Dest::R(eM), dxbc::Src::LF(1.0f), dxbc::Src::R(eM)); + a_.OpMul(dxbc::Dest::R(eM), dxbc::Src::R(eM), dxbc::Src::LF(float(INT16_MAX))); + } + } + a_.OpEndIf(); + + // Add plus/minus 0.5 before truncating according to the Direct3D format + // conversion rules, and convert to signed integers. + uint32_t round_bias_temp = PushSystemTemp(); + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + a_.OpBFI(dxbc::Dest::R(eM), dxbc::Src::LU(31), dxbc::Src::LU(0), dxbc::Src::LF(0.5f), + dxbc::Src::R(eM)); + a_.OpAdd(dxbc::Dest::R(eM), dxbc::Src::R(eM), dxbc::Src::R(round_bias_temp)); + a_.OpFToI(dxbc::Dest::R(eM), dxbc::Src::R(eM)); + } + // Release round_bias_temp. + PopSystemTemp(); + } + a_.OpElse(); + { + // Unsigned. + a_.OpIf(true, num_format_integer); + { + // Unsigned integer. + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + a_.OpMax(dxbc::Dest::R(eM), dxbc::Src::LF(0.0f), dxbc::Src::R(eM)); + a_.OpMin(dxbc::Dest::R(eM), dxbc::Src::LF(float(UINT16_MAX)), dxbc::Src::R(eM)); + } + } + a_.OpElse(); + { + // Unsigned normalized. + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + // Saturate. + a_.OpMov(dxbc::Dest::R(eM), dxbc::Src::R(eM), true); + a_.OpMul(dxbc::Dest::R(eM), dxbc::Src::R(eM), dxbc::Src::LF(float(UINT16_MAX))); + } + } + a_.OpEndIf(); + + // Add 0.5 before truncating according to the Direct3D format conversion + // rules, and convert to unsigned integers. + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + a_.OpAdd(dxbc::Dest::R(eM), dxbc::Src::R(eM), dxbc::Src::LF(0.5f)); + a_.OpFToU(dxbc::Dest::R(eM), dxbc::Src::R(eM)); + } + } + a_.OpEndIf(); + + // Pack. + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + a_.OpBFI(dxbc::Dest::R(eM, 0b0011), dxbc::Src::LU(16), dxbc::Src::LU(16), + dxbc::Src::R(eM, 0b1101), dxbc::Src::R(eM, 0b1000)); + } + + a_.OpMov(element_size_dest, dxbc::Src::LU(3)); + } + a_.OpBreak(); + + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_16_FLOAT))); + { + // TODO(Triang3l): Use extended range conversion. + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + a_.OpF32ToF16(dxbc::Dest::R(eM, 0b0001), dxbc::Src::R(eM, dxbc::Src::kXXXX)); + } + a_.OpMov(element_size_dest, dxbc::Src::LU(1)); + } + a_.OpBreak(); + + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_16_16_FLOAT))); + { + // TODO(Triang3l): Use extended range conversion. + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + a_.OpF32ToF16(dxbc::Dest::R(eM, 0b0011), dxbc::Src::R(eM)); + a_.OpBFI(dxbc::Dest::R(eM, 0b0001), dxbc::Src::LU(16), dxbc::Src::LU(16), + dxbc::Src::R(eM, dxbc::Src::kYYYY), dxbc::Src::R(eM, dxbc::Src::kXXXX)); + } + a_.OpMov(element_size_dest, dxbc::Src::LU(2)); + } + a_.OpBreak(); + + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_16_16_16_16_FLOAT))); + { + // TODO(Triang3l): Use extended range conversion. + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + a_.OpF32ToF16(dxbc::Dest::R(eM), dxbc::Src::R(eM)); + a_.OpBFI(dxbc::Dest::R(eM, 0b0011), dxbc::Src::LU(16), dxbc::Src::LU(16), + dxbc::Src::R(eM, 0b1101), dxbc::Src::R(eM, 0b1000)); + } + a_.OpMov(element_size_dest, dxbc::Src::LU(3)); + } + a_.OpBreak(); + + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_32_FLOAT))); + { + // Already in eM#. + a_.OpMov(element_size_dest, dxbc::Src::LU(2)); + } + a_.OpBreak(); + + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_32_32_FLOAT))); + { + // Already in eM#. + a_.OpMov(element_size_dest, dxbc::Src::LU(3)); + } + a_.OpBreak(); + + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::ColorFormat::k_32_32_32_32_FLOAT))); + { + // Already in eM#. + a_.OpMov(element_size_dest, dxbc::Src::LU(4)); + } + a_.OpBreak(); + + a_.OpDefault(); + a_.OpMov(element_size_dest, dxbc::Src::LU(UINT32_MAX)); + a_.OpBreak(); + } + // Close the color format switch. + a_.OpEndSwitch(); + + dxbc::Src element_size_src(dxbc::Src::R(temp, dxbc::Src::kXXXX)); + + // Only temp.x is used currently (for the element size log2). + + // Do endian swap, using temp.y for the endianness value, and temp.z as a + // temporary value. + { + dxbc::Dest endian_dest(dxbc::Dest::R(temp, 0b0010)); + dxbc::Src endian_src(dxbc::Src::R(temp, dxbc::Src::kYYYY)); + // Extract endianness into temp.y. + a_.OpUBFE(endian_dest, dxbc::Src::LU(3), dxbc::Src::LU(0), + dxbc::Src::R(system_temp_memexport_address_, dxbc::Src::kZZZZ)); + + // Change 8-in-64 and 8-in-128 to 8-in-32. + for (uint32_t i = 0; i < 2; ++i) { + a_.OpIEq(dxbc::Dest::R(temp, 0b0100), endian_src, + dxbc::Src::LU(uint32_t(i ? xenos::Endian128::k8in128 : xenos::Endian128::k8in64))); + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + a_.OpMovC(dxbc::Dest::R(eM), dxbc::Src::R(temp, dxbc::Src::kZZZZ), + dxbc::Src::R(eM, i ? 0b00011011 : 0b10110001), dxbc::Src::R(eM)); + } + a_.OpMovC(endian_dest, dxbc::Src::R(temp, dxbc::Src::kZZZZ), + dxbc::Src::LU(uint32_t(xenos::Endian128::k8in32)), endian_src); + } + + uint32_t swap_temp = PushSystemTemp(); + dxbc::Dest swap_temp_dest(dxbc::Dest::R(swap_temp)); + dxbc::Src swap_temp_src(dxbc::Src::R(swap_temp)); + + // 8-in-16 or one half of 8-in-32. + a_.OpSwitch(endian_src); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::Endian128::k8in16))); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::Endian128::k8in32))); + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + dxbc::Dest eM_dest(dxbc::Dest::R(eM)); + dxbc::Src eM_src(dxbc::Src::R(eM)); + // Temp = X0Z0. + a_.OpAnd(swap_temp_dest, eM_src, dxbc::Src::LU(0x00FF00FF)); + // eM = YZW0. + a_.OpUShR(eM_dest, eM_src, dxbc::Src::LU(8)); + // eM = Y0W0. + a_.OpAnd(eM_dest, eM_src, dxbc::Src::LU(0x00FF00FF)); + // eM = YXWZ. + a_.OpUMAd(eM_dest, swap_temp_src, dxbc::Src::LU(256), eM_src); + } + a_.OpBreak(); + a_.OpEndSwitch(); + + // 16-in-32 or another half of 8-in-32. + a_.OpSwitch(endian_src); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::Endian128::k8in32))); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::Endian128::k16in32))); + eM_remaining = export_eM; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + uint32_t eM = system_temps_memexport_data_[eM_index]; + dxbc::Dest eM_dest(dxbc::Dest::R(eM)); + dxbc::Src eM_src(dxbc::Src::R(eM)); + // Temp = ZW00. + a_.OpUShR(swap_temp_dest, eM_src, dxbc::Src::LU(16)); + // eM = ZWXY. + a_.OpBFI(eM_dest, dxbc::Src::LU(16), dxbc::Src::LU(16), eM_src, swap_temp_src); + } + a_.OpBreak(); + a_.OpEndSwitch(); + + // Release swap_temp. + PopSystemTemp(); + } + + // Extract the base index to temp.y and the index upper bound to temp.z. + a_.OpUBFE(dxbc::Dest::R(temp, 0b0110), dxbc::Src::LU(23), dxbc::Src::LU(0), + dxbc::Src::R(system_temp_memexport_address_, 0b1101 << 2)); + dxbc::Dest eM0_address_dest(dxbc::Dest::R(temp, 0b0010)); + dxbc::Src eM0_address_src(dxbc::Src::R(temp, dxbc::Src::kYYYY)); + dxbc::Src index_count_src(dxbc::Src::R(temp, dxbc::Src::kZZZZ)); + + // Check if eM0 isn't out of bounds via temp.w - if it is, eM1...4 also are + // (the base index can't be negative). + a_.OpILT(dxbc::Dest::R(temp, 0b1000), eM0_address_src, index_count_src); + a_.OpIf(true, dxbc::Src::R(temp, dxbc::Src::kWWWW)); + + // Extract the base address to temp.w as bytes (30 lower bits to 30 upper bits + // with 0 below). + a_.OpIShL(dxbc::Dest::R(temp, 0b1000), + dxbc::Src::R(system_temp_memexport_address_, dxbc::Src::kXXXX), dxbc::Src::LU(2)); + dxbc::Src base_address_src(dxbc::Src::R(temp, dxbc::Src::kWWWW)); + + uint8_t export_eM14 = export_eM >> 1; + assert_zero(export_eM14 >> 4); + uint32_t eM14_address_temp = UINT32_MAX, store_eM14_temp = UINT32_MAX; + if (export_eM14) { + // Get eM1...4 indices and check if they're in bounds. + eM14_address_temp = PushSystemTemp(); + dxbc::Dest eM14_address_dest(dxbc::Dest::R(eM14_address_temp, export_eM14)); + dxbc::Src eM14_address_src(dxbc::Src::R(eM14_address_temp)); + store_eM14_temp = PushSystemTemp(); + dxbc::Dest store_eM14_dest(dxbc::Dest::R(store_eM14_temp, export_eM14)); + dxbc::Src store_eM14_src(dxbc::Src::R(store_eM14_temp)); + a_.OpIAdd(eM14_address_dest, eM0_address_src, dxbc::Src::LU(1, 2, 3, 4)); + a_.OpILT(store_eM14_dest, eM14_address_src, index_count_src); + // Check if eM1...4 were actually written by the invocation and merge the + // result with store_eM14_temp. + uint32_t eM14_written_temp = PushSystemTemp(); + a_.OpIBFE(dxbc::Dest::R(eM14_written_temp, export_eM14), dxbc::Src::LU(1), + dxbc::Src::LU(1, 2, 3, 4), + dxbc::Src::R(system_temp_memexport_enabled_and_eM_written_, dxbc::Src::kYYYY)); + a_.OpAnd(store_eM14_dest, store_eM14_src, dxbc::Src::R(eM14_written_temp)); + // Release eM14_written_temp. + PopSystemTemp(); + // Convert eM1...4 indices to global byte addresses. + a_.OpIShL(eM14_address_dest, eM14_address_src, element_size_src); + a_.OpIAdd(eM14_address_dest, base_address_src, eM14_address_src); + } + if (export_eM & 0b1) { + // Convert eM0 index to a global byte address if it's needed. + a_.OpIShL(eM0_address_dest, eM0_address_src, element_size_src); + a_.OpIAdd(eM0_address_dest, base_address_src, eM0_address_src); + // base_address_src and index_count_src are deallocated at this point (even + // if eM0 isn't potentially written), temp.zw are now free. + // Extract if eM0 was actually written by the invocation to temp.z. + a_.OpIBFE(dxbc::Dest::R(temp, 0b0100), dxbc::Src::LU(1), dxbc::Src::LU(0), + dxbc::Src::R(system_temp_memexport_enabled_and_eM_written_, dxbc::Src::kYYYY)); + } + dxbc::Src eM0_written_src(dxbc::Src::R(temp, dxbc::Src::kZZZZ)); + + // Write depending on the element size. + // No switch case will be entered for an unknown format (UINT32_MAX size + // written), so writing won't be attempted for it. + if (uav_index_shared_memory_ == kBindingIndexUnallocated) { + uav_index_shared_memory_ = uav_count_++; + } + uint8_t eM14_remaining; + uint32_t eM14_index; + a_.OpSwitch(element_size_src); + + // 8bpp, 16bpp. + dxbc::Dest atomic_dest( + dxbc::Dest::U(uav_index_shared_memory_, uint32_t(UAVRegister::kSharedMemory), 0)); + for (uint32_t i = 0; i <= 1; ++i) { + a_.OpCase(dxbc::Src::LU(i)); + dxbc::Src width_src(dxbc::Src::LU(8 << i)); + uint32_t sub_dword_temp = PushSystemTemp(); + if (export_eM & 0b1) { + a_.OpIf(true, eM0_written_src); + // sub_dword_temp.x = eM0 offset in the dword (8 << (byte_address & 3)) + // (assuming a little-endian host). + a_.OpBFI(dxbc::Dest::R(sub_dword_temp, 0b0001), dxbc::Src::LU(2), dxbc::Src::LU(3), + eM0_address_src, dxbc::Src::LU(0)); + // Keep only the dword part of the address. + a_.OpAnd(eM0_address_dest, eM0_address_src, dxbc::Src::LU(~uint32_t(3))); + // Erase the bits that will be replaced with eM0 via sub_dword_temp.y. + a_.OpBFI(dxbc::Dest::R(sub_dword_temp, 0b0010), width_src, + dxbc::Src::R(sub_dword_temp, dxbc::Src::kXXXX), dxbc::Src::LU(0), + dxbc::Src::LU(UINT32_MAX)); + a_.OpAtomicAnd(atomic_dest, eM0_address_src, 0b0001, + dxbc::Src::R(sub_dword_temp, dxbc::Src::kYYYY)); + // Add the eM0 bits via sub_dword_temp.y. + a_.OpBFI(dxbc::Dest::R(sub_dword_temp, 0b0010), width_src, + dxbc::Src::R(sub_dword_temp, dxbc::Src::kXXXX), + dxbc::Src::R(system_temps_memexport_data_[0], dxbc::Src::kXXXX), dxbc::Src::LU(0)); + a_.OpAtomicOr(atomic_dest, eM0_address_src, 0b0001, + dxbc::Src::R(sub_dword_temp, dxbc::Src::kYYYY)); + a_.OpEndIf(); + } + if (export_eM14) { + // sub_dword_temp = eM# offset in the dword (8 << (byte_address & 3)) + // (assuming a little-endian host). + a_.OpBFI(dxbc::Dest::R(sub_dword_temp, export_eM14), dxbc::Src::LU(2), dxbc::Src::LU(3), + dxbc::Src::R(eM14_address_temp), dxbc::Src::LU(0)); + // Keep only the dword part of the address. + a_.OpAnd(dxbc::Dest::R(eM14_address_temp, export_eM14), dxbc::Src::R(eM14_address_temp), + dxbc::Src::LU(~uint32_t(3))); + uint32_t sub_dword_data_temp = PushSystemTemp(); + eM14_remaining = export_eM14; + while (rex::bit_scan_forward(eM14_remaining, &eM14_index)) { + eM14_remaining &= ~(uint8_t(1) << eM14_index); + a_.OpIf(true, dxbc::Src::R(store_eM14_temp).Select(eM14_index)); + // Erase the bits that will be replaced with eM# via + // sub_dword_data_temp.x. + a_.OpBFI(dxbc::Dest::R(sub_dword_data_temp, 0b0001), width_src, + dxbc::Src::R(sub_dword_temp).Select(eM14_index), dxbc::Src::LU(0), + dxbc::Src::LU(UINT32_MAX)); + a_.OpAtomicAnd(atomic_dest, dxbc::Src::R(eM14_address_temp).Select(eM14_index), 0b0001, + dxbc::Src::R(sub_dword_data_temp, dxbc::Src::kXXXX)); + // Add the eM# bits via sub_dword_temp.y. + a_.OpBFI(dxbc::Dest::R(sub_dword_data_temp, 0b0001), width_src, + dxbc::Src::R(sub_dword_temp).Select(eM14_index), + dxbc::Src::R(system_temps_memexport_data_[1 + eM14_index], dxbc::Src::kXXXX), + dxbc::Src::LU(0)); + a_.OpAtomicOr(atomic_dest, dxbc::Src::R(eM14_address_temp).Select(eM14_index), 0b0001, + dxbc::Src::R(sub_dword_data_temp, dxbc::Src::kXXXX)); + a_.OpEndIf(); + } + // Release sub_dword_data_temp. + PopSystemTemp(); + } + // Release sub_dword_temp. + PopSystemTemp(); + a_.OpBreak(); + } + + // 32bpp, 64bpp, 128bpp. + for (uint32_t i = 2; i <= 4; ++i) { + a_.OpCase(dxbc::Src::LU(i)); + // Store (0b0001), Store2 (0b0011), Store4 (0b1111). + uint32_t store_mask = (uint32_t(1) << (uint32_t(1) << (i - 2))) - 1; + dxbc::Dest store_dest( + dxbc::Dest::U(uav_index_shared_memory_, uint32_t(UAVRegister::kSharedMemory), store_mask)); + if (export_eM & 0b1) { + a_.OpIf(true, eM0_written_src); + a_.OpStoreRaw(store_dest, eM0_address_src, dxbc::Src::R(system_temps_memexport_data_[0])); + a_.OpEndIf(); + } + eM14_remaining = export_eM14; + while (rex::bit_scan_forward(eM14_remaining, &eM14_index)) { + eM14_remaining &= ~(uint8_t(1) << eM14_index); + a_.OpIf(true, dxbc::Src::R(store_eM14_temp).Select(eM14_index)); + a_.OpStoreRaw(store_dest, dxbc::Src::R(eM14_address_temp).Select(eM14_index), + dxbc::Src::R(system_temps_memexport_data_[1 + eM14_index])); + a_.OpEndIf(); + } + a_.OpBreak(); + } + + // Close the element size switch. + a_.OpEndSwitch(); + + if (export_eM14) { + // Release eM14_address_temp and store_eM14_temp. + PopSystemTemp(2); + } + + // Close the eM0 bounds check. + a_.OpEndIf(); + + // Release temp. + PopSystemTemp(); + + // Close the address correctness conditional. + a_.OpEndIf(); + + // Close the memory export allowed conditional. + a_.OpEndIf(); +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/shader/dxbc_translator_om.cpp b/src/graphics/pipeline/shader/dxbc_translator_om.cpp new file mode 100644 index 0000000..a7d508a --- /dev/null +++ b/src/graphics/pipeline/shader/dxbc_translator_om.cpp @@ -0,0 +1,3081 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace rex::graphics { +using namespace ucode; + +void DxbcShaderTranslator::StartPixelShader_LoadROVParameters() { + bool any_color_targets_written = current_shader().writes_color_targets() != 0; + + // *************************************************************************** + // Get EDRAM offsets for the pixel: + // system_temp_rov_params_.y - for depth (absolute). + // system_temp_rov_params_.z - for 32bpp color (base-relative). + // system_temp_rov_params_.w - for 64bpp color (base-relative). + // *************************************************************************** + + // For now, while we don't know the encoding of 64bpp render targets when + // interpreted as 32bpp (no game has been seen reinterpreting between the two + // yet), for consistency with the conventional render target logic and to have + // the same resolve logic for both, storing 64bpp color as 40x16 samples + // (multiplied by the resolution scale) per 1280-byte tile. It's also + // convenient to use 40x16 granularity in the calculations here because depth + // render targets have 40-sample halves swapped as opposed to color in each + // tile, and reinterpretation between depth and color is common for depth / + // stencil reloading into the EDRAM (such as in the background of the main + // menu of 4D5307E6). + + // Convert the host pixel position to integer to system_temp_rov_params_.xy. + // system_temp_rov_params_.x = X host pixel position as uint + // system_temp_rov_params_.y = Y host pixel position as uint + in_position_used_ |= 0b0011; + a_.OpFToU(dxbc::Dest::R(system_temp_rov_params_, 0b0011), dxbc::Src::V1D(in_reg_ps_position_)); + // Convert the position from pixels to samples. + // system_temp_rov_params_.x = X sample 0 position + // system_temp_rov_params_.y = Y sample 0 position + a_.OpIShL(dxbc::Dest::R(system_temp_rov_params_, 0b0011), dxbc::Src::R(system_temp_rov_params_), + LoadSystemConstant(SystemConstants::Index::kSampleCountLog2, + offsetof(SystemConstants, sample_count_log2), 0b0100)); + // For cases of both color and depth: + // Get 40 x 16 x resolution scale 32bpp half-tile or 40x16 64bpp tile index + // to system_temp_rov_params_.zw, and put the sample index within such a + // region in system_temp_rov_params_.xy. + // Working with 40x16-sample portions for 64bpp and for swapping for depth - + // dividing by 40, not by 80. + // For depth-only: + // Same, but for full 80x16 tiles, not 40x16 half-tiles. + uint32_t tile_width = xenos::kEdramTileWidthSamples * draw_resolution_scale_x_; + uint32_t tile_or_tile_half_width = tile_width >> uint32_t(any_color_targets_written); + uint32_t tile_height = xenos::kEdramTileHeightSamples * draw_resolution_scale_y_; + // system_temp_rov_params_.x = X sample 0 position within the half-tile or + // tile + // system_temp_rov_params_.y = Y sample 0 position within the (half-)tile + // system_temp_rov_params_.z = X half-tile or tile position + // system_temp_rov_params_.w = Y tile position + a_.OpUDiv( + dxbc::Dest::R(system_temp_rov_params_, 0b1100), + dxbc::Dest::R(system_temp_rov_params_, 0b0011), + dxbc::Src::R(system_temp_rov_params_, 0b01000100), + dxbc::Src::LU(tile_or_tile_half_width, tile_height, tile_or_tile_half_width, tile_height)); + + // Convert the Y sample 0 position within the half-tile or tile to the dword + // offset of the row within a 80x16 32bpp tile or a 40x16 64bpp half-tile to + // system_temp_rov_params_.y. + // system_temp_rov_params_.x = X sample 0 position within the half-tile or + // tile + // system_temp_rov_params_.y = Y sample 0 row dword offset within the + // 80x16-dword tile + // system_temp_rov_params_.z = X half-tile position + // system_temp_rov_params_.w = Y tile position + a_.OpUMul(dxbc::Dest::Null(), dxbc::Dest::R(system_temp_rov_params_, 0b0010), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), dxbc::Src::LU(tile_width)); + + uint32_t tile_size = tile_width * tile_height; + uint32_t tile_half_width = tile_width >> 1; + if (any_color_targets_written) { + // Depth, 32bpp color, 64bpp color are all needed. + + // X sample 0 position within in the half-tile in system_temp_rov_params_.x, + // for 64bpp, will be used directly as sample X the within the 80x16-dword + // region, but for 32bpp color and depth, 40x16 half-tile index within the + // 80x16 tile - system_temp_rov_params_.z & 1 - will also be taken into + // account when calculating the X (directly for color, flipped for depth). + + uint32_t rov_address_temp = PushSystemTemp(); + + // Multiply the Y tile position by the surface tile pitch in dwords to get + // the address of the origin of the row of tiles within a 32bpp surface in + // dwords (later it needs to be multiplied by 2 for 64bpp). + // system_temp_rov_params_.x = X sample 0 position within the half-tile + // system_temp_rov_params_.y = Y sample 0 row dword offset within the + // 80x16-dword tile + // system_temp_rov_params_.z = X half-tile position + // system_temp_rov_params_.w = Y tile row dword origin in a 32bpp surface + a_.OpUMul(dxbc::Dest::Null(), dxbc::Dest::R(system_temp_rov_params_, 0b1000), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kWWWW), + LoadSystemConstant(SystemConstants::Index::kEdram32bppTilePitchDwordsScaled, + offsetof(SystemConstants, edram_32bpp_tile_pitch_dwords_scaled), + dxbc::Src::kXXXX)); + + // Get the 32bpp tile X position within the row of tiles to + // rov_address_temp.x. + // system_temp_rov_params_.x = X sample 0 position within the half-tile + // system_temp_rov_params_.y = Y sample 0 row dword offset within the + // 80x16-dword tile + // system_temp_rov_params_.z = X half-tile position + // system_temp_rov_params_.w = Y tile row dword origin in a 32bpp surface + // rov_address_temp.x = X 32bpp tile position + a_.OpUShR(dxbc::Dest::R(rov_address_temp, 0b0001), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kZZZZ), dxbc::Src::LU(1)); + // Get the dword offset of the beginning of the row of samples within a row + // of 32bpp 80x16 tiles to rov_address_temp.x. + // system_temp_rov_params_.x = X sample 0 position within the half-tile + // system_temp_rov_params_.y = Y sample 0 row dword offset within the + // 80x16-dword tile + // system_temp_rov_params_.z = X half-tile position + // system_temp_rov_params_.w = Y tile row dword origin in a 32bpp surface + // rov_address_temp.x = dword offset of the beginning of the row of samples + // within a row of 32bpp tiles + a_.OpUMAd(dxbc::Dest::R(rov_address_temp, 0b0001), + dxbc::Src::R(rov_address_temp, dxbc::Src::kXXXX), dxbc::Src::LU(tile_size), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY)); + // Get the dword offset of the beginning of the row of samples within a + // 32bpp surface to rov_address_temp.x. + // system_temp_rov_params_.x = X sample 0 position within the half-tile + // system_temp_rov_params_.y = Y sample 0 row dword offset within the + // 80x16-dword tile + // system_temp_rov_params_.z = X half-tile position + // system_temp_rov_params_.w = Y tile row dword origin in a 32bpp surface + // rov_address_temp.x = dword offset of the beginning of the row of samples + // within a 32bpp surface + a_.OpIAdd(dxbc::Dest::R(rov_address_temp, 0b0001), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kWWWW), + dxbc::Src::R(rov_address_temp, dxbc::Src::kXXXX)); + + // Get the dword offset of the beginning of the row of samples within a row + // of 64bpp 80x16 tiles to system_temp_rov_params_.y (last time the + // tile-local Y offset is needed). + // system_temp_rov_params_.x = X sample 0 position within the half-tile + // system_temp_rov_params_.y = dword offset of the beginning of the row of + // samples within a row of 64bpp tiles + // system_temp_rov_params_.z = X half-tile position + // system_temp_rov_params_.w = Y tile row dword origin in a 32bpp surface + // rov_address_temp.x = dword offset of the beginning of the row of samples + // within a 32bpp surface + a_.OpUMAd(dxbc::Dest::R(system_temp_rov_params_, 0b0010), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kZZZZ), dxbc::Src::LU(tile_size), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY)); + // Get the dword offset of the beginning of the row of samples within a + // 64bpp surface to system_temp_rov_params_.w (last time the Y tile row + // offset is needed). + // system_temp_rov_params_.x = X sample 0 position within the half-tile + // system_temp_rov_params_.y = free + // system_temp_rov_params_.z = X half-tile position + // system_temp_rov_params_.w = dword offset of the beginning of the row of + // samples within a 64bpp surface + // rov_address_temp.x = dword offset of the beginning of the row of samples + // within a 32bpp surface + a_.OpUMAd(dxbc::Dest::R(system_temp_rov_params_, 0b1000), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kWWWW), dxbc::Src::LU(2), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY)); + + // Get the final offset of the sample 0 within a 64bpp surface to + // system_temp_rov_params_.w. + // system_temp_rov_params_.x = X sample 0 position within the half-tile + // system_temp_rov_params_.z = X half-tile position + // system_temp_rov_params_.w = dword sample 0 offset within a 64bpp surface + // rov_address_temp.x = dword offset of the beginning of the row of samples + // within a 32bpp surface + a_.OpUMAd(dxbc::Dest::R(system_temp_rov_params_, 0b1000), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), dxbc::Src::LU(2), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kWWWW)); + + // Get the half-tile index within the tile to system_temp_rov_params_.y + // (last time the X half-tile position is needed). + // system_temp_rov_params_.x = X sample 0 position within the half-tile + // system_temp_rov_params_.y = half-tile index within the tile + // system_temp_rov_params_.z = free + // system_temp_rov_params_.w = dword sample 0 offset within a 64bpp surface + // rov_address_temp.x = dword offset of the beginning of the row of samples + // within a 32bpp surface + a_.OpAnd(dxbc::Dest::R(system_temp_rov_params_, 0b0010), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kZZZZ), dxbc::Src::LU(1)); + + // Get the X position within the 32bpp tile to system_temp_rov_params_.z + // (last time the X position within the half-tile is needed). + // system_temp_rov_params_.x = free + // system_temp_rov_params_.y = half-tile index within the tile + // system_temp_rov_params_.z = X sample 0 position within the tile + // system_temp_rov_params_.w = dword sample 0 offset within a 64bpp surface + // rov_address_temp.x = dword offset of the beginning of the row of samples + // within a 32bpp surface + a_.OpUMAd(dxbc::Dest::R(system_temp_rov_params_, 0b0100), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), + dxbc::Src::LU(tile_half_width), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX)); + // Get the final offset of the sample 0 within a 32bpp color surface to + // system_temp_rov_params_.z (last time the 32bpp row offset is needed). + // system_temp_rov_params_.y = half-tile index within the tile + // system_temp_rov_params_.z = dword sample 0 offset within a 32bpp surface + // system_temp_rov_params_.w = dword sample 0 offset within a 64bpp surface + // rov_address_temp.x = free + a_.OpIAdd(dxbc::Dest::R(system_temp_rov_params_, 0b0100), + dxbc::Src::R(rov_address_temp, dxbc::Src::kXXXX), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kZZZZ)); + + // Flip the 40x16 half-tiles for depth / stencil as opposed to 32bpp color - + // get the dword offset to add for flipping to system_temp_rov_params_.y. + // system_temp_rov_params_.y = depth half-tile flipping offset + // system_temp_rov_params_.z = dword sample 0 offset within a 32bpp surface + // system_temp_rov_params_.w = dword sample 0 offset within a 64bpp surface + a_.OpMovC(dxbc::Dest::R(system_temp_rov_params_, 0b0010), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), + dxbc::Src::LI(-int32_t(tile_half_width)), dxbc::Src::LI(int32_t(tile_half_width))); + // Flip the 40x16 half-tiles for depth / stencil as opposed to 32bpp color - + // get the final offset of the sample 0 within a 32bpp depth / stencil + // surface to system_temp_rov_params_.y. + // system_temp_rov_params_.y = dword sample 0 offset within depth / stencil + // system_temp_rov_params_.z = dword sample 0 offset within a 32bpp surface + // system_temp_rov_params_.w = dword sample 0 offset within a 64bpp surface + a_.OpIAdd(dxbc::Dest::R(system_temp_rov_params_, 0b0010), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kZZZZ), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY)); + + // Release rov_address_temp. + PopSystemTemp(); + } else { + // Simpler logic for depth-only, not involving half-tile indices (flipping + // half-tiles via comparison). + + // Get the dword offset of the beginning of the row of samples within a row + // of 32bpp 80x16 tiles to system_temp_rov_params_.z (last time the X tile + // position is needed). + // system_temp_rov_params_.x = X sample 0 position within the tile + // system_temp_rov_params_.y = Y sample 0 row dword offset within the + // 80x16-dword tile + // system_temp_rov_params_.z = dword offset of the beginning of the row of + // samples within a row of 32bpp tiles + // system_temp_rov_params_.w = Y tile position + a_.OpUMAd(dxbc::Dest::R(system_temp_rov_params_, 0b0100), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kZZZZ), dxbc::Src::LU(tile_size), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY)); + // Get the dword offset of the beginning of the row of samples within a + // 32bpp surface to system_temp_rov_params_.y (last time anything Y-related + // is needed, as well as the sample row offset within the tile row). + // system_temp_rov_params_.x = X sample 0 position within the tile + // system_temp_rov_params_.y = dword offset of the beginning of the row of + // samples within a 32bpp surface + // system_temp_rov_params_.z = free + // system_temp_rov_params_.w = free + a_.OpUMAd(dxbc::Dest::R(system_temp_rov_params_, 0b0010), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kWWWW), + LoadSystemConstant(SystemConstants::Index::kEdram32bppTilePitchDwordsScaled, + offsetof(SystemConstants, edram_32bpp_tile_pitch_dwords_scaled), + dxbc::Src::kXXXX), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kZZZZ)); + // Add the tile-local X to the depth offset in system_temp_rov_params_.y. + // system_temp_rov_params_.x = X sample 0 position within the tile + // system_temp_rov_params_.y = dword sample 0 offset within a 32bpp surface + a_.OpIAdd(dxbc::Dest::R(system_temp_rov_params_, 0b0010), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX)); + // Flip the 40x16 half-tiles for depth / stencil as opposed to 32bpp color - + // check in which half-tile the pixel is in to system_temp_rov_params_.x. + // system_temp_rov_params_.x = free + // system_temp_rov_params_.y = dword sample 0 offset within a 32bpp surface + // system_temp_rov_params_.z = 0xFFFFFFFF if in the right half-tile, 0 + // otherwise + a_.OpUGE(dxbc::Dest::R(system_temp_rov_params_, 0b0001), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), + dxbc::Src::LU(tile_half_width)); + // Flip the 40x16 half-tiles for depth / stencil as opposed to 32bpp color - + // get the dword offset to add for flipping to system_temp_rov_params_.x. + // system_temp_rov_params_.x = depth half-tile flipping offset + // system_temp_rov_params_.y = dword sample 0 offset within a 32bpp surface + a_.OpMovC(dxbc::Dest::R(system_temp_rov_params_, 0b0001), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), + dxbc::Src::LI(-int32_t(tile_half_width)), dxbc::Src::LI(int32_t(tile_half_width))); + // Flip the 40x16 half-tiles for depth / stencil as opposed to 32bpp color - + // get the final offset of the sample 0 within a 32bpp depth / stencil + // surface to system_temp_rov_params_.y. + // system_temp_rov_params_.x = free + // system_temp_rov_params_.y = dword sample 0 offset within depth / stencil + a_.OpIAdd(dxbc::Dest::R(system_temp_rov_params_, 0b0010), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX)); + } + + // Add the EDRAM base for depth/stencil. + // system_temp_rov_params_.y = non-wrapped EDRAM depth / stencil address + // system_temp_rov_params_.z = dword sample 0 offset within a 32bpp surface if + // needed + // system_temp_rov_params_.w = dword sample 0 offset within a 64bpp surface if + // needed + a_.OpIAdd(dxbc::Dest::R(system_temp_rov_params_, 0b0010), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), + LoadSystemConstant(SystemConstants::Index::kEdramDepthBaseDwordsScaled, + offsetof(SystemConstants, edram_depth_base_dwords_scaled), + dxbc::Src::kXXXX)); + // Wrap EDRAM addressing for depth/stencil. + // system_temp_rov_params_.y = EDRAM depth / stencil address + // system_temp_rov_params_.z = dword sample 0 offset within a 32bpp surface if + // needed + // system_temp_rov_params_.w = dword sample 0 offset within a 64bpp surface if + // needed + a_.OpUDiv(dxbc::Dest::Null(), dxbc::Dest::R(system_temp_rov_params_, 0b0010), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), + dxbc::Src::LU(tile_size * xenos::kEdramTileCount)); + + // *************************************************************************** + // Sample coverage to system_temp_rov_params_.x. + // *************************************************************************** + + // Using ForcedSampleCount of 4 (2 is not supported on Nvidia), so for 2x + // MSAA, handling samples 0 and 3 (upper-left and lower-right) as 0 and 1. + + // Check if 4x MSAA is enabled. + a_.OpIf(true, LoadSystemConstant(SystemConstants::Index::kSampleCountLog2, + offsetof(SystemConstants, sample_count_log2), dxbc::Src::kXXXX)); + { + // Copy the 4x AA coverage to system_temp_rov_params_.x, making top-right + // the sample [2] and bottom-left the sample [1] (the opposite of Direct3D + // 12), because on the Xbox 360, 2x MSAA doubles the storage height, 4x MSAA + // doubles the storage width. + // Flip samples in bits 0:1 to bits 29:30. + a_.OpBFRev(dxbc::Dest::R(system_temp_rov_params_, 0b0001), dxbc::Src::VCoverage()); + a_.OpUShR(dxbc::Dest::R(system_temp_rov_params_, 0b0001), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), dxbc::Src::LU(29)); + a_.OpBFI(dxbc::Dest::R(system_temp_rov_params_, 0b0001), dxbc::Src::LU(2), dxbc::Src::LU(1), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), dxbc::Src::VCoverage()); + } + // Handle 1 or 2 samples. + a_.OpElse(); + { + // Extract sample 3 coverage, which will be used as sample 1. + a_.OpUBFE(dxbc::Dest::R(system_temp_rov_params_, 0b0001), dxbc::Src::LU(1), dxbc::Src::LU(3), + dxbc::Src::VCoverage()); + // Combine coverage of samples 0 (in bit 0 of vCoverage) and 3 (in bit 0 of + // system_temp_rov_params_.x). + a_.OpBFI(dxbc::Dest::R(system_temp_rov_params_, 0b0001), dxbc::Src::LU(31), dxbc::Src::LU(1), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), dxbc::Src::VCoverage()); + } + // Close the 4x MSAA conditional. + a_.OpEndIf(); +} + +void DxbcShaderTranslator::ROV_DepthStencilTest() { + uint32_t temp = PushSystemTemp(); + dxbc::Dest temp_x_dest(dxbc::Dest::R(temp, 0b0001)); + dxbc::Src temp_x_src(dxbc::Src::R(temp, dxbc::Src::kXXXX)); + dxbc::Dest temp_y_dest(dxbc::Dest::R(temp, 0b0010)); + dxbc::Src temp_y_src(dxbc::Src::R(temp, dxbc::Src::kYYYY)); + dxbc::Dest temp_z_dest(dxbc::Dest::R(temp, 0b0100)); + dxbc::Src temp_z_src(dxbc::Src::R(temp, dxbc::Src::kZZZZ)); + dxbc::Dest temp_w_dest(dxbc::Dest::R(temp, 0b1000)); + dxbc::Src temp_w_src(dxbc::Src::R(temp, dxbc::Src::kWWWW)); + + // Check whether depth/stencil is enabled. + // temp.x = kSysFlag_ROVDepthStencil + a_.OpAnd(temp_x_dest, LoadFlagsSystemConstant(), dxbc::Src::LU(kSysFlag_ROVDepthStencil)); + // Open the depth/stencil enabled conditional. + // temp.x = free + a_.OpIf(true, temp_x_src); + + bool shader_writes_depth = current_shader().writes_depth(); + bool depth_stencil_early = ROV_IsDepthStencilEarly(); + + dxbc::Src z_ddx_src(dxbc::Src::LF(0.0f)), z_ddy_src(dxbc::Src::LF(0.0f)); + + if (shader_writes_depth) { + // Convert the shader-generated depth to 24-bit, using temp.x as + // temporary. oDepth is already written by StoreResult with saturation, + // no need to clamp here. Adreno 200 doesn't have PA_SC_VPORT_ZMIN/ZMAX, + // so likely there's no need to clamp to the viewport depth bounds. + ROV_DepthTo24Bit(system_temp_depth_stencil_, 0, system_temp_depth_stencil_, 0, temp, 0); + } else { + dxbc::Src in_position_z(dxbc::Src::V1D(in_reg_ps_position_, dxbc::Src::kZZZZ)); + // Get the derivatives of the screen-space (but not clamped to the viewport + // depth bounds yet - this happens after the pixel shader in Direct3D 11+; + // also linear within the triangle - thus constant derivatives along the + // triangle) Z for calculating per-sample depth values and the slope-scaled + // polygon offset. + // We're using derivatives instead of eval_sample_index for various reasons: + // - eval_sample_index doesn't work with SV_Position - need to use an + // additional interpolant. + // - On AMD, eval_sample_index is actually implemented via calculation and + // scaling of derivatives of barycentric coordinates, therefore there's no + // advantage of using it there. + // - eval_sample_index is (inconsistently, but often) one of the sources of + // the infamous AMD shader compiler crashes when ROV is used in Xenia, in + // addition to shader compiler crashes on WARP. + if (depth_stencil_early) { + z_ddx_src = dxbc::Src::R(temp, dxbc::Src::kXXXX); + z_ddy_src = dxbc::Src::R(temp, dxbc::Src::kYYYY); + // temp.x = ddx(z) + // temp.y = ddy(z) + in_position_used_ |= 0b0100; + a_.OpDerivRTXCoarse(temp_x_dest, in_position_z); + a_.OpDerivRTYCoarse(temp_y_dest, in_position_z); + } else { + // For late depth / stencil testing, derivatives are calculated in the + // beginning of the shader before any return statement is possibly + // reached, and written to system_temp_depth_stencil_.xy. + assert_true(system_temp_depth_stencil_ != UINT32_MAX); + z_ddx_src = dxbc::Src::R(system_temp_depth_stencil_, dxbc::Src::kXXXX); + z_ddy_src = dxbc::Src::R(system_temp_depth_stencil_, dxbc::Src::kYYYY); + } + // Get the maximum depth slope for polygon offset. + // https://docs.microsoft.com/en-us/windows/desktop/direct3d9/depth-bias + // temp.x if early = ddx(z) + // temp.y if early = ddy(z) + // temp.z = max(|ddx(z)|, |ddy(z)|) + a_.OpMax(temp_z_dest, z_ddx_src.Abs(), z_ddy_src.Abs()); + // Calculate the depth bias for the needed faceness. + in_front_face_used_ = true; + a_.OpIf(true, dxbc::Src::V1D(in_reg_ps_front_face_sample_index_, dxbc::Src::kXXXX)); + // temp.x if early = ddx(z) + // temp.y if early = ddy(z) + // temp.z = front face polygon offset + // temp.w = free + a_.OpMAd( + temp_z_dest, temp_z_src, + LoadSystemConstant(SystemConstants::Index::kEdramPolyOffsetFront, + offsetof(SystemConstants, edram_poly_offset_front), dxbc::Src::kXXXX), + LoadSystemConstant(SystemConstants::Index::kEdramPolyOffsetFront, + offsetof(SystemConstants, edram_poly_offset_front), dxbc::Src::kYYYY)); + a_.OpElse(); + // temp.x if early = ddx(z) + // temp.y if early = ddy(z) + // temp.z = back face polygon offset + // temp.w = free + a_.OpMAd( + temp_z_dest, temp_z_src, + LoadSystemConstant(SystemConstants::Index::kEdramPolyOffsetBack, + offsetof(SystemConstants, edram_poly_offset_back), dxbc::Src::kXXXX), + LoadSystemConstant(SystemConstants::Index::kEdramPolyOffsetBack, + offsetof(SystemConstants, edram_poly_offset_back), dxbc::Src::kYYYY)); + a_.OpEndIf(); + // Apply the post-clip and post-viewport polygon offset to the fragment's + // depth. Not clamping yet as this is at the center, which is not + // necessarily covered and not necessarily inside the bounds - derivatives + // scaled by sample positions will be added to this value, and it must be + // linear. + // temp.x if early = ddx(z) + // temp.y if early = ddy(z) + // temp.z = biased depth in the center + in_position_used_ |= 0b0100; + a_.OpAdd(temp_z_dest, temp_z_src, in_position_z); + } + + for (uint32_t i = 0; i < 4; ++i) { + // With early depth/stencil, depth/stencil writing may be deferred to the + // end of the shader to prevent writing in case something (like alpha test, + // which is dynamic GPU state) discards the pixel. So, write directly to the + // persistent register, system_temp_depth_stencil_, instead of a local + // temporary register. + dxbc::Dest sample_depth_stencil_dest( + depth_stencil_early ? dxbc::Dest::R(system_temp_depth_stencil_, 1 << i) : temp_w_dest); + dxbc::Src sample_depth_stencil_src( + depth_stencil_early ? dxbc::Src::R(system_temp_depth_stencil_).Select(i) : temp_w_src); + + // Get if the current sample is covered. + // temp.x if no oDepth and early = ddx(z) + // temp.y if no oDepth and early = ddy(z) + // temp.z if no oDepth = biased depth in the center + // temp.w = coverage of the current sample + a_.OpAnd(temp_w_dest, dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), + dxbc::Src::LU(1 << i)); + // Check if the current sample is covered. + // temp.x if no oDepth and early = ddx(z) + // temp.y if no oDepth and early = ddy(z) + // temp.z if no oDepth = biased depth in the center + // temp.w = free + a_.OpIf(true, temp_w_src); + + uint32_t sample_temp = PushSystemTemp(); + dxbc::Dest sample_temp_x_dest(dxbc::Dest::R(sample_temp, 0b0001)); + dxbc::Src sample_temp_x_src(dxbc::Src::R(sample_temp, dxbc::Src::kXXXX)); + dxbc::Dest sample_temp_y_dest(dxbc::Dest::R(sample_temp, 0b0010)); + dxbc::Src sample_temp_y_src(dxbc::Src::R(sample_temp, dxbc::Src::kYYYY)); + dxbc::Dest sample_temp_z_dest(dxbc::Dest::R(sample_temp, 0b0100)); + dxbc::Src sample_temp_z_src(dxbc::Src::R(sample_temp, dxbc::Src::kZZZZ)); + dxbc::Dest sample_temp_w_dest(dxbc::Dest::R(sample_temp, 0b1000)); + dxbc::Src sample_temp_w_src(dxbc::Src::R(sample_temp, dxbc::Src::kWWWW)); + + if (shader_writes_depth) { + // Copy the 24-bit depth common to all samples to sample_depth_stencil. + // temp.w = shader-generated 24-bit depth + assert_false(depth_stencil_early); + a_.OpMov(sample_depth_stencil_dest, + dxbc::Src::R(system_temp_depth_stencil_, dxbc::Src::kXXXX)); + } else { + // Adreno 200 doesn't have PA_SC_VPORT_ZMIN/ZMAX, so likely there's no + // need to clamp to the viewport depth bounds, just to 0...1 - thus only + // saturating in the end of the per-sample depth calculation. + switch (i) { + case 0: + // First sample - off-center for MSAA, in the center without it. + // Using ForcedSampleCount 4 for both 2x and 4x MSAA because + // ForcedSampleCount 2 is not supported on Nvidia, thus the position + // of the top-left sample (0 in Xenia) is always that of the top-left + // sample of host 4x MSAA. + // Calculate the depth in the sample 0 for 2x or 4x MSAA. + // temp.x if early = ddx(z) + // temp.y if early = ddy(z) + // temp.z = biased depth in the center + // temp.w if late = unsaturated sample 0 depth at 4x MSAA + a_.OpMAd(sample_depth_stencil_dest, z_ddx_src, + dxbc::Src::LF(draw_util::kD3D10StandardSamplePositions4x[0][0] * (1.0f / 16.0f)), + temp_z_src); + a_.OpMAd(sample_depth_stencil_dest, z_ddy_src, + dxbc::Src::LF(draw_util::kD3D10StandardSamplePositions4x[0][1] * (1.0f / 16.0f)), + sample_depth_stencil_src); + // Choose between the sample and the center depth depending on whether + // at least 2x MSAA is enabled and saturate. + // temp.x if early = ddx(z) + // temp.y if early = ddy(z) + // temp.z = biased depth in the center + // temp.w if late = sample 0 depth + a_.OpMovC( + sample_depth_stencil_dest, + LoadSystemConstant(SystemConstants::Index::kSampleCountLog2, + offsetof(SystemConstants, sample_count_log2), dxbc::Src::kYYYY), + sample_depth_stencil_src, temp_z_src, true); + break; + case 1: + // - 2x MSAA: Bottom sample -> bottom-right (3) with Direct3D 11's + // ForcedSampleCount 4. + // - 4x MSAA: Bottom-left Xenia sample -> Direct3D 11 sample 2. + // Check if 4x MSAA is used. + a_.OpIf(true, LoadSystemConstant(SystemConstants::Index::kSampleCountLog2, + offsetof(SystemConstants, sample_count_log2), + dxbc::Src::kXXXX)); + // 4x MSAA. + // temp.x if early = ddx(z) + // temp.y if early = ddy(z) + // temp.z = biased depth in the center + // temp.w if late = saturated sample 1 depth at 4x MSAA + a_.OpMAd(sample_depth_stencil_dest, z_ddx_src, + dxbc::Src::LF(draw_util::kD3D10StandardSamplePositions4x[2][0] * (1.0f / 16.0f)), + temp_z_src); + a_.OpMAd(sample_depth_stencil_dest, z_ddy_src, + dxbc::Src::LF(draw_util::kD3D10StandardSamplePositions4x[2][1] * (1.0f / 16.0f)), + sample_depth_stencil_src, true); + a_.OpElse(); + // 2x MSAA as ForcedSampleCount 4 on the host. + // temp.x if early = ddx(z) + // temp.y if early = ddy(z) + // temp.z = biased depth in the center + // temp.w if late = saturated sample 1 depth at 2x MSAA + a_.OpMAd(sample_depth_stencil_dest, z_ddx_src, + dxbc::Src::LF(draw_util::kD3D10StandardSamplePositions4x[3][0] * (1.0f / 16.0f)), + temp_z_src); + a_.OpMAd(sample_depth_stencil_dest, z_ddy_src, + dxbc::Src::LF(draw_util::kD3D10StandardSamplePositions4x[3][1] * (1.0f / 16.0f)), + sample_depth_stencil_src, true); + a_.OpEndIf(); + break; + default: { + // Xenia samples 2 and 3 (top-right and bottom-right) -> Direct3D 11 + // samples 1 and 3. + // temp.x if early = ddx(z) + // temp.y if early = ddy(z) + // temp.z = biased depth in the center + // temp.w if late = saturated sample 2 or 3 depth + const int8_t* sample_position = + draw_util::kD3D10StandardSamplePositions4x[i ^ (((i & 1) ^ (i >> 1)) * 0b11)]; + a_.OpMAd(sample_depth_stencil_dest, z_ddx_src, + dxbc::Src::LF(sample_position[0] * (1.0f / 16.0f)), temp_z_src); + a_.OpMAd(sample_depth_stencil_dest, z_ddy_src, + dxbc::Src::LF(sample_position[1] * (1.0f / 16.0f)), sample_depth_stencil_src, + true); + } break; + } + // Convert the sample's depth to 24-bit, using sample_temp.x as a + // temporary. + // temp.x if early = ddx(z) + // temp.y if early = ddy(z) + // temp.z = biased depth in the center + // temp.w if late = sample's 24-bit Z + ROV_DepthTo24Bit(sample_depth_stencil_src.index_1d_.index_, + sample_depth_stencil_src.swizzle_ & 3, + sample_depth_stencil_src.index_1d_.index_, + sample_depth_stencil_src.swizzle_ & 3, sample_temp, 0); + } + + // Load the old depth/stencil value. + // sample_temp.x = old depth/stencil + if (uav_index_edram_ == kBindingIndexUnallocated) { + uav_index_edram_ = uav_count_++; + } + a_.OpLdUAVTyped( + sample_temp_x_dest, dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), 1, + dxbc::Src::U(uav_index_edram_, uint32_t(UAVRegister::kEdram), dxbc::Src::kXXXX)); + + // Depth test. + + // Extract the old depth part to sample_depth_stencil. + // sample_temp.x = old depth/stencil + // sample_temp.y = old depth + a_.OpUShR(sample_temp_y_dest, sample_temp_x_src, dxbc::Src::LU(8)); + // Get the difference between the new and the old depth, > 0 - greater, + // == 0 - equal, < 0 - less. + // sample_temp.x = old depth/stencil + // sample_temp.y = old depth + // sample_temp.z = depth difference + a_.OpIAdd(sample_temp_z_dest, sample_depth_stencil_src, -sample_temp_y_src); + // Check if the depth is "less" or "greater or equal". + // sample_temp.x = old depth/stencil + // sample_temp.y = old depth + // sample_temp.z = depth difference + // sample_temp.w = depth difference less than 0 + a_.OpILT(sample_temp_w_dest, sample_temp_z_src, dxbc::Src::LI(0)); + // Choose the passed depth function bits for "less" or for "greater". + // sample_temp.x = old depth/stencil + // sample_temp.y = old depth + // sample_temp.z = depth difference + // sample_temp.w = depth function passed bits for "less" or "greater" + a_.OpMovC(sample_temp_w_dest, sample_temp_w_src, dxbc::Src::LU(kSysFlag_ROVDepthPassIfLess), + dxbc::Src::LU(kSysFlag_ROVDepthPassIfGreater)); + // Do the "equal" testing. + // sample_temp.x = old depth/stencil + // sample_temp.y = old depth + // sample_temp.z = depth function passed bits + // sample_temp.w = free + a_.OpMovC(sample_temp_z_dest, sample_temp_z_src, sample_temp_w_src, + dxbc::Src::LU(kSysFlag_ROVDepthPassIfEqual)); + // Mask the resulting bits with the ones that should pass. + // sample_temp.x = old depth/stencil + // sample_temp.y = old depth + // sample_temp.z = masked depth function passed bits + a_.OpAnd(sample_temp_z_dest, sample_temp_z_src, LoadFlagsSystemConstant()); + // Check if depth test has passed. + // sample_temp.x = old depth/stencil + // sample_temp.y = old depth + // sample_temp.z = free + a_.OpIf(true, sample_temp_z_src); + { + // Extract the depth write flag. + // sample_temp.x = old depth/stencil + // sample_temp.y = old depth + // sample_temp.z = depth write mask + a_.OpAnd(sample_temp_z_dest, LoadFlagsSystemConstant(), + dxbc::Src::LU(kSysFlag_ROVDepthWrite)); + // If depth writing is disabled, don't change the depth. + // temp.x if no oDepth and early = ddx(z) + // temp.y if no oDepth and early = ddy(z) + // temp.z if no oDepth = biased depth in the center + // temp.w if late = resulting sample depth after the depth test + // sample_temp.x = old depth/stencil + // sample_temp.y = free + // sample_temp.z = free + a_.OpMovC(sample_depth_stencil_dest, sample_temp_z_src, sample_depth_stencil_src, + sample_temp_y_src); + } + // Depth test has failed. + a_.OpElse(); + { + // Exclude the bit from the covered sample mask. + // sample_temp.x = old depth/stencil + // sample_temp.y = old depth + a_.OpAnd(dxbc::Dest::R(system_temp_rov_params_, 0b0001), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), + dxbc::Src::LU(~uint32_t(1 << i))); + } + a_.OpEndIf(); + // Create packed depth/stencil, with the stencil value unchanged at this + // point. + // temp.x if no oDepth and early = ddx(z) + // temp.y if no oDepth and early = ddy(z) + // temp.z if no oDepth = biased depth in the center + // temp.w if late = resulting sample depth, current resulting stencil + // sample_temp.x = old depth/stencil + a_.OpBFI(sample_depth_stencil_dest, dxbc::Src::LU(24), dxbc::Src::LU(8), + sample_depth_stencil_src, sample_temp_x_src); + + // Stencil test. + + // Extract the stencil test bit. + // sample_temp.x = old depth/stencil + // sample_temp.y = stencil test enabled + a_.OpAnd(sample_temp_y_dest, LoadFlagsSystemConstant(), dxbc::Src::LU(kSysFlag_ROVStencilTest)); + // Check if stencil test is enabled. + // sample_temp.x = old depth/stencil + // sample_temp.y = free + a_.OpIf(true, sample_temp_y_src); + { + // Check the current face to get the reference and apply the read mask. + in_front_face_used_ = true; + a_.OpIf(true, dxbc::Src::V1D(in_reg_ps_front_face_sample_index_, dxbc::Src::kXXXX)); + for (uint32_t j = 0; j < 2; ++j) { + if (j) { + // Go to the back face. + a_.OpElse(); + } + dxbc::Src stencil_read_mask_src( + LoadSystemConstant(SystemConstants::Index::kEdramStencil, + j ? offsetof(SystemConstants, edram_stencil_back_read_mask) + : offsetof(SystemConstants, edram_stencil_front_read_mask), + dxbc::Src::kXXXX)); + // Read-mask the stencil reference. + // sample_temp.x = old depth/stencil + // sample_temp.y = read-masked stencil reference + a_.OpAnd(sample_temp_y_dest, + LoadSystemConstant(SystemConstants::Index::kEdramStencil, + j ? offsetof(SystemConstants, edram_stencil_back_reference) + : offsetof(SystemConstants, edram_stencil_front_reference), + dxbc::Src::kXXXX), + stencil_read_mask_src); + // Read-mask the old stencil value (also dropping the depth bits). + // sample_temp.x = old depth/stencil + // sample_temp.y = read-masked stencil reference + // sample_temp.z = read-masked old stencil + a_.OpAnd(sample_temp_z_dest, sample_temp_x_src, stencil_read_mask_src); + } + // Close the face check. + a_.OpEndIf(); + // Get the difference between the stencil reference and the old stencil, + // > 0 - greater, == 0 - equal, < 0 - less. + // sample_temp.x = old depth/stencil + // sample_temp.y = stencil difference + // sample_temp.z = free + a_.OpIAdd(sample_temp_y_dest, sample_temp_y_src, -sample_temp_z_src); + // Check if the stencil is "less" or "greater or equal". + // sample_temp.x = old depth/stencil + // sample_temp.y = stencil difference + // sample_temp.z = stencil difference less than 0 + a_.OpILT(sample_temp_z_dest, sample_temp_y_src, dxbc::Src::LI(0)); + // Choose the passed depth function bits for "less" or for "greater". + // sample_temp.x = old depth/stencil + // sample_temp.y = stencil difference + // sample_temp.z = stencil function passed bits for "less" or "greater" + a_.OpMovC(sample_temp_z_dest, sample_temp_z_src, + dxbc::Src::LU(uint32_t(xenos::CompareFunction::kLess)), + dxbc::Src::LU(uint32_t(xenos::CompareFunction::kGreater))); + // Do the "equal" testing. + // sample_temp.x = old depth/stencil + // sample_temp.y = stencil function passed bits + // sample_temp.z = free + a_.OpMovC(sample_temp_y_dest, sample_temp_y_src, sample_temp_z_src, + dxbc::Src::LU(uint32_t(xenos::CompareFunction::kEqual))); + // Get the comparison function and the operations for the current face. + // sample_temp.x = old depth/stencil + // sample_temp.y = stencil function passed bits + // sample_temp.z = stencil function and operations + in_front_face_used_ = true; + a_.OpMovC(sample_temp_z_dest, + dxbc::Src::V1D(in_reg_ps_front_face_sample_index_, dxbc::Src::kXXXX), + LoadSystemConstant(SystemConstants::Index::kEdramStencil, + offsetof(SystemConstants, edram_stencil_front_func_ops), + dxbc::Src::kXXXX), + LoadSystemConstant(SystemConstants::Index::kEdramStencil, + offsetof(SystemConstants, edram_stencil_back_func_ops), + dxbc::Src::kXXXX)); + // Mask the resulting bits with the ones that should pass (the comparison + // function is in the low 3 bits of the constant, and only ANDing 3-bit + // values with it, so safe not to UBFE the function). + // sample_temp.x = old depth/stencil + // sample_temp.y = stencil test result + // sample_temp.z = stencil function and operations + a_.OpAnd(sample_temp_y_dest, sample_temp_y_src, sample_temp_z_src); + // Handle passing and failure of the stencil test, to choose the operation + // and to discard the sample. + // sample_temp.x = old depth/stencil + // sample_temp.y = free + // sample_temp.z = stencil function and operations + a_.OpIf(true, sample_temp_y_src); + { + // Check if depth test has passed for this sample (the sample will only + // be processed if it's covered, so the only thing that could unset the + // bit at this point that matters is the depth test). + // sample_temp.x = old depth/stencil + // sample_temp.y = depth test result + // sample_temp.z = stencil function and operations + a_.OpAnd(sample_temp_y_dest, dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), + dxbc::Src::LU(1 << i)); + // Choose the bit offset of the stencil operation. + // sample_temp.x = old depth/stencil + // sample_temp.y = sample operation offset + // sample_temp.z = stencil function and operations + a_.OpMovC(sample_temp_y_dest, sample_temp_y_src, dxbc::Src::LU(6), dxbc::Src::LU(9)); + // Extract the stencil operation. + // sample_temp.x = old depth/stencil + // sample_temp.y = stencil operation + // sample_temp.z = free + a_.OpUBFE(sample_temp_y_dest, dxbc::Src::LU(3), sample_temp_y_src, sample_temp_z_src); + } + // Stencil test has failed. + a_.OpElse(); + { + // Extract the stencil fail operation. + // sample_temp.x = old depth/stencil + // sample_temp.y = stencil operation + // sample_temp.z = free + a_.OpUBFE(sample_temp_y_dest, dxbc::Src::LU(3), dxbc::Src::LU(3), sample_temp_z_src); + // Exclude the bit from the covered sample mask. + // sample_temp.x = old depth/stencil + // sample_temp.y = stencil operation + a_.OpAnd(dxbc::Dest::R(system_temp_rov_params_, 0b0001), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), + dxbc::Src::LU(~uint32_t(1 << i))); + } + // Close the stencil pass check. + a_.OpEndIf(); + + // Open the stencil operation switch for writing the new stencil (not + // caring about bits 8:31). + // sample_temp.x = old depth/stencil + // sample_temp.y = will contain unmasked new stencil in 0:7 and junk above + a_.OpSwitch(sample_temp_y_src); + { + // Zero. + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::StencilOp::kZero))); + a_.OpMov(sample_temp_y_dest, dxbc::Src::LU(0)); + a_.OpBreak(); + // Replace. + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::StencilOp::kReplace))); + in_front_face_used_ = true; + a_.OpMovC(sample_temp_y_dest, + dxbc::Src::V1D(in_reg_ps_front_face_sample_index_, dxbc::Src::kXXXX), + LoadSystemConstant(SystemConstants::Index::kEdramStencil, + offsetof(SystemConstants, edram_stencil_front_reference), + dxbc::Src::kXXXX), + LoadSystemConstant(SystemConstants::Index::kEdramStencil, + offsetof(SystemConstants, edram_stencil_back_reference), + dxbc::Src::kXXXX)); + a_.OpBreak(); + // Increment and clamp. + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::StencilOp::kIncrementClamp))); + { + // Clear the upper bits for saturation. + a_.OpAnd(sample_temp_y_dest, sample_temp_x_src, dxbc::Src::LU(UINT8_MAX)); + // Increment. + a_.OpIAdd(sample_temp_y_dest, sample_temp_y_src, dxbc::Src::LI(1)); + // Clamp. + a_.OpIMin(sample_temp_y_dest, sample_temp_y_src, dxbc::Src::LI(UINT8_MAX)); + } + a_.OpBreak(); + // Decrement and clamp. + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::StencilOp::kDecrementClamp))); + { + // Clear the upper bits for saturation. + a_.OpAnd(sample_temp_y_dest, sample_temp_x_src, dxbc::Src::LU(UINT8_MAX)); + // Increment. + a_.OpIAdd(sample_temp_y_dest, sample_temp_y_src, dxbc::Src::LI(-1)); + // Clamp. + a_.OpIMax(sample_temp_y_dest, sample_temp_y_src, dxbc::Src::LI(0)); + } + a_.OpBreak(); + // Invert. + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::StencilOp::kInvert))); + a_.OpNot(sample_temp_y_dest, sample_temp_x_src); + a_.OpBreak(); + // Increment and wrap. + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::StencilOp::kIncrementWrap))); + a_.OpIAdd(sample_temp_y_dest, sample_temp_x_src, dxbc::Src::LI(1)); + a_.OpBreak(); + // Decrement and wrap. + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::StencilOp::kDecrementWrap))); + a_.OpIAdd(sample_temp_y_dest, sample_temp_x_src, dxbc::Src::LI(-1)); + a_.OpBreak(); + // Keep. + a_.OpDefault(); + a_.OpMov(sample_temp_y_dest, sample_temp_x_src); + a_.OpBreak(); + } + // Close the new stencil switch. + a_.OpEndSwitch(); + + // Select the stencil write mask for the face. + // sample_temp.x = old depth/stencil + // sample_temp.y = unmasked new stencil in 0:7 and junk above + // sample_temp.z = stencil write mask + in_front_face_used_ = true; + a_.OpMovC(sample_temp_z_dest, + dxbc::Src::V1D(in_reg_ps_front_face_sample_index_, dxbc::Src::kXXXX), + LoadSystemConstant(SystemConstants::Index::kEdramStencil, + offsetof(SystemConstants, edram_stencil_front_write_mask), + dxbc::Src::kXXXX), + LoadSystemConstant(SystemConstants::Index::kEdramStencil, + offsetof(SystemConstants, edram_stencil_back_write_mask), + dxbc::Src::kXXXX)); + // Apply the write mask to the new stencil, also dropping the upper 24 + // bits. + // sample_temp.x = old depth/stencil + // sample_temp.y = masked new stencil + // sample_temp.z = stencil write mask + a_.OpAnd(sample_temp_y_dest, sample_temp_y_src, sample_temp_z_src); + // Invert the write mask for keeping the old stencil and the depth bits. + // sample_temp.x = old depth/stencil + // sample_temp.y = masked new stencil + // sample_temp.z = inverted stencil write mask + a_.OpNot(sample_temp_z_dest, sample_temp_z_src); + // Remove the bits that will be replaced from the combined depth/stencil + // before inserting their new values. + // sample_temp.x = old depth/stencil + // sample_temp.y = masked new stencil + // sample_temp.z = free + // temp.x if no oDepth and early = ddx(z) + // temp.y if no oDepth and early = ddy(z) + // temp.z if no oDepth = biased depth in the center + // temp.w if late = resulting sample depth, inverse-write-masked old + // stencil + a_.OpAnd(sample_depth_stencil_dest, sample_depth_stencil_src, sample_temp_z_src); + // Merge the old and the new stencil. + // temp.x if no oDepth and early = ddx(z) + // temp.y if no oDepth and early = ddy(z) + // temp.z if no oDepth = biased depth in the center + // temp.w if late = resulting sample depth/stencil + // sample_temp.x = old depth/stencil + // sample_temp.y = free + a_.OpOr(sample_depth_stencil_dest, sample_depth_stencil_src, sample_temp_y_src); + } + // Close the stencil test check. + a_.OpEndIf(); + + // Check if the depth/stencil has failed not to modify the depth if it has. + // sample_temp.x = old depth/stencil + // sample_temp.y = whether depth/stencil has passed for this sample + a_.OpAnd(sample_temp_y_dest, dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), + dxbc::Src::LU(1 << i)); + // If the depth/stencil test has failed, don't change the depth. + // sample_temp.x = old depth/stencil + // sample_temp.y = free + a_.OpIf(false, sample_temp_y_src); + { + // Copy the new stencil over the old depth. + // temp.x if no oDepth and early = ddx(z) + // temp.y if no oDepth and early = ddy(z) + // temp.z if no oDepth = biased depth in the center + // temp.w if late = resulting sample depth/stencil + a_.OpBFI(sample_depth_stencil_dest, dxbc::Src::LU(8), dxbc::Src::LU(0), + sample_depth_stencil_src, sample_temp_x_src); + } + // Close the depth/stencil passing check. + a_.OpEndIf(); + // Check if the new depth/stencil is different, and thus needs to be + // written. + // sample_temp.x = old depth/stencil + a_.OpINE(sample_temp_x_dest, sample_depth_stencil_src, sample_temp_x_src); + if (depth_stencil_early && !current_shader().implicit_early_z_write_allowed()) { + // Set the sample bit in bits 4:7 of system_temp_rov_params_.x - always + // need to write late in this shader, as it may do something like + // explicitly killing pixels. + a_.OpBFI(dxbc::Dest::R(system_temp_rov_params_, 0b0001), dxbc::Src::LU(1), + dxbc::Src::LU(4 + i), sample_temp_x_src, + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX)); + } else { + // Check if need to write. + // sample_temp.x = free + a_.OpIf(true, sample_temp_x_src); + { + if (depth_stencil_early) { + // Get if early depth/stencil write is enabled. + // sample_temp.x = whether early depth/stencil write is enabled + a_.OpAnd(sample_temp_x_dest, LoadFlagsSystemConstant(), + dxbc::Src::LU(kSysFlag_ROVDepthStencilEarlyWrite)); + // Check if need to write early. + // sample_temp.x = free + a_.OpIf(true, sample_temp_x_src); + } + // Write the new depth/stencil. + if (uav_index_edram_ == kBindingIndexUnallocated) { + uav_index_edram_ = uav_count_++; + } + a_.OpStoreUAVTyped(dxbc::Dest::U(uav_index_edram_, uint32_t(UAVRegister::kEdram)), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), 1, + sample_depth_stencil_src); + if (depth_stencil_early) { + // Need to still run the shader to know whether to write the + // depth/stencil value. + a_.OpElse(); + // Set the sample bit in bits 4:7 of system_temp_rov_params_.x if need + // to write later (after checking if the sample is not discarded by a + // kill instruction, alphatest or alpha-to-coverage). + a_.OpOr(dxbc::Dest::R(system_temp_rov_params_, 0b0001), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), + dxbc::Src::LU(1 << (4 + i))); + // Close the early depth/stencil check. + a_.OpEndIf(); + } + } + // Close the write check. + a_.OpEndIf(); + } + + // Release sample_temp. + PopSystemTemp(); + + // Close the sample conditional. + a_.OpEndIf(); + + // Go to the next sample (samples are at +0, +(80*scale_x), +1, + // +(80*scale_x+1), so need to do +(80*scale_x), -(80*scale_x-1), + // +(80*scale_x) and -(80*scale_x+1) after each sample). + uint32_t tile_width = xenos::kEdramTileWidthSamples * draw_resolution_scale_x_; + a_.OpIAdd(dxbc::Dest::R(system_temp_rov_params_, 0b0010), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), + dxbc::Src::LI((i & 1) ? -int32_t(tile_width) + 2 - i : int32_t(tile_width))); + } + + if (ROV_IsDepthStencilEarly()) { + // Check if safe to discard the whole 2x2 quad early, without running the + // translated pixel shader, by checking if coverage is 0 in all pixels in + // the quad and if there are no samples which failed the depth test, but + // where stencil was modified and needs to be written in the end. Must + // reject at 2x2 quad granularity because texture fetches need derivatives. + + // temp.x = coverage | deferred depth/stencil write + a_.OpAnd(dxbc::Dest::R(temp, 0b0001), dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), + dxbc::Src::LU(0b11111111)); + // temp.x = 1.0 if any sample is covered or potentially needs stencil write + // in the end of the shader in the current pixel + a_.OpMovC(dxbc::Dest::R(temp, 0b0001), dxbc::Src::R(temp, dxbc::Src::kXXXX), + dxbc::Src::LF(1.0f), dxbc::Src::LF(0.0f)); + // temp.x = 1.0 if any sample is covered or potentially needs stencil write + // in the end of the shader in the current pixel + // temp.y = non-zero if anything is covered in the pixel across X + a_.OpDerivRTXFine(dxbc::Dest::R(temp, 0b0010), dxbc::Src::R(temp, dxbc::Src::kXXXX)); + // temp.x = 1.0 if anything is covered in the current half of the quad + // temp.y = free + a_.OpMovC(dxbc::Dest::R(temp, 0b0001), dxbc::Src::R(temp, dxbc::Src::kYYYY), + dxbc::Src::LF(1.0f), dxbc::Src::R(temp, dxbc::Src::kXXXX)); + // temp.x = 1.0 if anything is covered in the current half of the quad + // temp.y = non-zero if anything is covered in the two pixels across Y + a_.OpDerivRTYCoarse(dxbc::Dest::R(temp, 0b0010), dxbc::Src::R(temp, dxbc::Src::kXXXX)); + // temp.x = 1.0 if anything is covered in the current whole quad + // temp.y = free + a_.OpMovC(dxbc::Dest::R(temp, 0b0001), dxbc::Src::R(temp, dxbc::Src::kYYYY), + dxbc::Src::LF(1.0f), dxbc::Src::R(temp, dxbc::Src::kXXXX)); + // End the shader if nothing is covered in the 2x2 quad after early + // depth/stencil. + // temp.x = free + a_.OpRetC(false, dxbc::Src::R(temp, dxbc::Src::kXXXX)); + } + + // Close the large depth/stencil conditional. + a_.OpEndIf(); + + // Release temp. + PopSystemTemp(); +} + +void DxbcShaderTranslator::ROV_UnpackColor(uint32_t rt_index, uint32_t packed_temp, + uint32_t packed_temp_components, uint32_t color_temp, + uint32_t temp1, uint32_t temp1_component, uint32_t temp2, + uint32_t temp2_component) { + assert_true(color_temp != packed_temp || packed_temp_components == 0); + + dxbc::Src packed_temp_low(dxbc::Src::R(packed_temp).Select(packed_temp_components)); + dxbc::Dest temp1_dest(dxbc::Dest::R(temp1, 1 << temp1_component)); + dxbc::Src temp1_src(dxbc::Src::R(temp1).Select(temp1_component)); + dxbc::Dest temp2_dest(dxbc::Dest::R(temp2, 1 << temp2_component)); + dxbc::Src temp2_src(dxbc::Src::R(temp2).Select(temp2_component)); + + // Break register dependencies and initialize if there are not enough + // components. The rest of the function will write at least RG (k_32_FLOAT and + // k_32_32_FLOAT handled with the same default label), and if packed_temp is + // the same as color_temp, the packed color won't be touched. + a_.OpMov(dxbc::Dest::R(color_temp, 0b1100), dxbc::Src::LF(0.0f, 0.0f, 0.0f, 1.0f)); + + // Choose the packing based on the render target's format. + a_.OpSwitch(LoadSystemConstant( + SystemConstants::Index::kEdramRTFormatFlags, + offsetof(SystemConstants, edram_rt_format_flags) + sizeof(uint32_t) * rt_index, + dxbc::Src::kXXXX)); + + // *************************************************************************** + // k_8_8_8_8 + // k_8_8_8_8_GAMMA + // *************************************************************************** + for (uint32_t i = 0; i < 2; ++i) { + a_.OpCase(dxbc::Src::LU(RenderTargetCache::AddPSIColorFormatFlags( + i ? xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA + : xenos::ColorRenderTargetFormat::k_8_8_8_8))); + // Unpack the components. + a_.OpUBFE(dxbc::Dest::R(color_temp), dxbc::Src::LU(8), dxbc::Src::LU(0, 8, 16, 24), + packed_temp_low); + // Convert from fixed-point. + a_.OpUToF(dxbc::Dest::R(color_temp), dxbc::Src::R(color_temp)); + // Normalize. + a_.OpMul(dxbc::Dest::R(color_temp), dxbc::Src::R(color_temp), dxbc::Src::LF(1.0f / 255.0f)); + if (i) { + for (uint32_t j = 0; j < 3; ++j) { + PWLGammaToLinear(a_, color_temp, j, color_temp, j, true, temp1, temp1_component, temp2, + temp2_component); + } + } + a_.OpBreak(); + } + + // *************************************************************************** + // k_2_10_10_10 + // k_2_10_10_10_AS_10_10_10_10 + // *************************************************************************** + a_.OpCase(dxbc::Src::LU( + RenderTargetCache::AddPSIColorFormatFlags(xenos::ColorRenderTargetFormat::k_2_10_10_10))); + a_.OpCase(dxbc::Src::LU(RenderTargetCache::AddPSIColorFormatFlags( + xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10))); + { + // Unpack the components. + a_.OpUBFE(dxbc::Dest::R(color_temp), dxbc::Src::LU(10, 10, 10, 2), dxbc::Src::LU(0, 10, 20, 30), + packed_temp_low); + // Convert from fixed-point. + a_.OpUToF(dxbc::Dest::R(color_temp), dxbc::Src::R(color_temp)); + // Normalize. + a_.OpMul(dxbc::Dest::R(color_temp), dxbc::Src::R(color_temp), + dxbc::Src::LF(1.0f / 1023.0f, 1.0f / 1023.0f, 1.0f / 1023.0f, 1.0f / 3.0f)); + } + a_.OpBreak(); + + // *************************************************************************** + // k_2_10_10_10_FLOAT + // k_2_10_10_10_FLOAT_AS_16_16_16_16 + // https://github.com/Microsoft/DirectXTex/blob/master/DirectXTex/DirectXTexConvert.cpp + // *************************************************************************** + a_.OpCase(dxbc::Src::LU(RenderTargetCache::AddPSIColorFormatFlags( + xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT))); + a_.OpCase(dxbc::Src::LU(RenderTargetCache::AddPSIColorFormatFlags( + xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16))); + { + // Unpack the alpha. + a_.OpUBFE(dxbc::Dest::R(color_temp, 0b1000), dxbc::Src::LU(2), dxbc::Src::LU(30), + packed_temp_low); + // Convert the alpha from fixed-point. + a_.OpUToF(dxbc::Dest::R(color_temp, 0b1000), dxbc::Src::R(color_temp, dxbc::Src::kWWWW)); + // Normalize the alpha. + a_.OpMul(dxbc::Dest::R(color_temp, 0b1000), dxbc::Src::R(color_temp, dxbc::Src::kWWWW), + dxbc::Src::LF(1.0f / 3.0f)); + // Process the components in reverse order because color_temp.r stores the + // packed color which shouldn't be touched until G and B are converted if + // packed_temp and color_temp are the same. + for (int32_t i = 2; i >= 0; --i) { + Float7e3To32(a_, dxbc::Dest::R(color_temp, 1 << i), packed_temp, packed_temp_components, + i * 10, color_temp, i, temp1, temp1_component); + } + } + a_.OpBreak(); + + // *************************************************************************** + // k_16_16 + // k_16_16_16_16 (64bpp) + // *************************************************************************** + for (uint32_t i = 0; i < 2; ++i) { + a_.OpCase(dxbc::Src::LU( + RenderTargetCache::AddPSIColorFormatFlags(i ? xenos::ColorRenderTargetFormat::k_16_16_16_16 + : xenos::ColorRenderTargetFormat::k_16_16))); + dxbc::Dest color_components_dest(dxbc::Dest::R(color_temp, i ? 0b1111 : 0b0011)); + // Unpack the components. + a_.OpIBFE(color_components_dest, dxbc::Src::LU(16), dxbc::Src::LU(0, 16, 0, 16), + dxbc::Src::R(packed_temp, 0b01010000 + packed_temp_components * 0b01010101)); + // Convert from fixed-point. + a_.OpIToF(color_components_dest, dxbc::Src::R(color_temp)); + // Normalize. + a_.OpMul(color_components_dest, dxbc::Src::R(color_temp), dxbc::Src::LF(32.0f / 32767.0f)); + a_.OpBreak(); + } + + // *************************************************************************** + // k_16_16_FLOAT + // k_16_16_16_16_FLOAT (64bpp) + // *************************************************************************** + for (uint32_t i = 0; i < 2; ++i) { + a_.OpCase(dxbc::Src::LU(RenderTargetCache::AddPSIColorFormatFlags( + i ? xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT + : xenos::ColorRenderTargetFormat::k_16_16_FLOAT))); + dxbc::Dest color_components_dest(dxbc::Dest::R(color_temp, i ? 0b1111 : 0b0011)); + // Unpack the components. + a_.OpUBFE(color_components_dest, dxbc::Src::LU(16), dxbc::Src::LU(0, 16, 0, 16), + dxbc::Src::R(packed_temp, 0b01010000 + packed_temp_components * 0b01010101)); + // Convert from 16-bit float. + a_.OpF16ToF32(color_components_dest, dxbc::Src::R(color_temp)); + a_.OpBreak(); + } + + if (packed_temp != color_temp) { + // Assume k_32_FLOAT or k_32_32_FLOAT for the rest. + a_.OpDefault(); + a_.OpMov(dxbc::Dest::R(color_temp, 0b0011), + dxbc::Src::R(packed_temp, 0b0100 + packed_temp_components * 0b0101)); + a_.OpBreak(); + } + + a_.OpEndSwitch(); +} + +void DxbcShaderTranslator::ROV_PackPreClampedColor(uint32_t rt_index, uint32_t color_temp, + uint32_t packed_temp, + uint32_t packed_temp_components, uint32_t temp1, + uint32_t temp1_component, uint32_t temp2, + uint32_t temp2_component) { + // Packing normalized formats according to the Direct3D 11.3 functional + // specification, but assuming clamping was done by the caller. + + assert_true(color_temp != packed_temp || packed_temp_components == 0); + + dxbc::Dest packed_dest_low(dxbc::Dest::R(packed_temp, 1 << packed_temp_components)); + dxbc::Src packed_src_low(dxbc::Src::R(packed_temp).Select(packed_temp_components)); + dxbc::Dest temp1_dest(dxbc::Dest::R(temp1, 1 << temp1_component)); + dxbc::Src temp1_src(dxbc::Src::R(temp1).Select(temp1_component)); + dxbc::Dest temp2_dest(dxbc::Dest::R(temp2, 1 << temp2_component)); + dxbc::Src temp2_src(dxbc::Src::R(temp2).Select(temp2_component)); + + // Break register dependency after 32bpp cases. + a_.OpMov(dxbc::Dest::R(packed_temp, 1 << (packed_temp_components + 1)), dxbc::Src::LU(0)); + + // Choose the packing based on the render target's format. + a_.OpSwitch(LoadSystemConstant( + SystemConstants::Index::kEdramRTFormatFlags, + offsetof(SystemConstants, edram_rt_format_flags) + sizeof(uint32_t) * rt_index, + dxbc::Src::kXXXX)); + + // *************************************************************************** + // k_8_8_8_8 + // k_8_8_8_8_GAMMA + // *************************************************************************** + for (uint32_t i = 0; i < 2; ++i) { + a_.OpCase(dxbc::Src::LU(RenderTargetCache::AddPSIColorFormatFlags( + i ? xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA + : xenos::ColorRenderTargetFormat::k_8_8_8_8))); + for (uint32_t j = 0; j < 4; ++j) { + if (i && j < 3) { + PreSaturatedLinearToPWLGamma(a_, temp1, temp1_component, color_temp, j, temp1, + temp1_component, temp2, temp2_component); + // Denormalize and add 0.5 for rounding. + a_.OpMAd(temp1_dest, temp1_src, dxbc::Src::LF(255.0f), dxbc::Src::LF(0.5f)); + } else { + // Denormalize and add 0.5 for rounding. + a_.OpMAd(temp1_dest, dxbc::Src::R(color_temp).Select(j), dxbc::Src::LF(255.0f), + dxbc::Src::LF(0.5f)); + } + // Convert to fixed-point. + a_.OpFToU(j ? temp1_dest : packed_dest_low, temp1_src); + // Pack the upper components. + if (j) { + a_.OpBFI(packed_dest_low, dxbc::Src::LU(8), dxbc::Src::LU(j * 8), temp1_src, + packed_src_low); + } + } + a_.OpBreak(); + } + + // *************************************************************************** + // k_2_10_10_10 + // k_2_10_10_10_AS_10_10_10_10 + // *************************************************************************** + a_.OpCase(dxbc::Src::LU( + RenderTargetCache::AddPSIColorFormatFlags(xenos::ColorRenderTargetFormat::k_2_10_10_10))); + a_.OpCase(dxbc::Src::LU(RenderTargetCache::AddPSIColorFormatFlags( + xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10))); + for (uint32_t i = 0; i < 4; ++i) { + // Denormalize and convert to fixed-point. + a_.OpMAd(temp1_dest, dxbc::Src::R(color_temp).Select(i), dxbc::Src::LF(i < 3 ? 1023.0f : 3.0f), + dxbc::Src::LF(0.5f)); + a_.OpFToU(i ? temp1_dest : packed_dest_low, temp1_src); + // Pack the upper components. + if (i) { + a_.OpBFI(packed_dest_low, dxbc::Src::LU(i < 3 ? 10 : 2), dxbc::Src::LU(i * 10), temp1_src, + packed_src_low); + } + } + a_.OpBreak(); + + // *************************************************************************** + // k_2_10_10_10_FLOAT + // k_2_10_10_10_FLOAT_AS_16_16_16_16 + // https://github.com/Microsoft/DirectXTex/blob/master/DirectXTex/DirectXTexConvert.cpp + // *************************************************************************** + a_.OpCase(dxbc::Src::LU(RenderTargetCache::AddPSIColorFormatFlags( + xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT))); + a_.OpCase(dxbc::Src::LU(RenderTargetCache::AddPSIColorFormatFlags( + xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16))); + { + // Convert red directly to the destination, which may be the same as the + // source, but PreClampedFloat32To7e3 allows that. + PreClampedFloat32To7e3(a_, packed_temp, packed_temp_components, color_temp, 0, temp1, + temp1_component); + for (uint32_t i = 1; i < 3; ++i) { + // Convert green and blue to a temporary register and insert them into the + // result. + PreClampedFloat32To7e3(a_, temp1, temp1_component, color_temp, i, temp2, temp2_component); + a_.OpBFI(packed_dest_low, dxbc::Src::LU(10), dxbc::Src::LU(i * 10), temp1_src, + packed_src_low); + } + // Denormalize the alpha and convert it to fixed-point. + a_.OpMAd(temp1_dest, dxbc::Src::R(color_temp, dxbc::Src::kWWWW), dxbc::Src::LF(3.0f), + dxbc::Src::LF(0.5f)); + a_.OpFToU(temp1_dest, temp1_src); + // Pack the alpha. + a_.OpBFI(packed_dest_low, dxbc::Src::LU(2), dxbc::Src::LU(30), temp1_src, packed_src_low); + } + a_.OpBreak(); + + // *************************************************************************** + // k_16_16 + // k_16_16_16_16 (64bpp) + // *************************************************************************** + for (uint32_t i = 0; i < 2; ++i) { + a_.OpCase(dxbc::Src::LU( + RenderTargetCache::AddPSIColorFormatFlags(i ? xenos::ColorRenderTargetFormat::k_16_16_16_16 + : xenos::ColorRenderTargetFormat::k_16_16))); + for (uint32_t j = 0; j < (uint32_t(2) << i); ++j) { + // Denormalize and convert to fixed-point, making 0.5 with the proper sign + // in temp2. + a_.OpGE(temp2_dest, dxbc::Src::R(color_temp).Select(j), dxbc::Src::LF(0.0f)); + a_.OpMovC(temp2_dest, temp2_src, dxbc::Src::LF(0.5f), dxbc::Src::LF(-0.5f)); + a_.OpMAd(temp1_dest, dxbc::Src::R(color_temp).Select(j), dxbc::Src::LF(32767.0f / 32.0f), + temp2_src); + dxbc::Dest packed_dest_half( + dxbc::Dest::R(packed_temp, 1 << (packed_temp_components + (j >> 1)))); + // Convert to fixed-point. + a_.OpFToI((j & 1) ? temp1_dest : packed_dest_half, temp1_src); + // Pack green or alpha. + if (j & 1) { + a_.OpBFI(packed_dest_half, dxbc::Src::LU(16), dxbc::Src::LU(16), temp1_src, + dxbc::Src::R(packed_temp).Select(packed_temp_components + (j >> 1))); + } + } + a_.OpBreak(); + } + + // *************************************************************************** + // k_16_16_FLOAT + // k_16_16_16_16_FLOAT (64bpp) + // *************************************************************************** + for (uint32_t i = 0; i < 2; ++i) { + a_.OpCase(dxbc::Src::LU(RenderTargetCache::AddPSIColorFormatFlags( + i ? xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT + : xenos::ColorRenderTargetFormat::k_16_16_FLOAT))); + for (uint32_t j = 0; j < (uint32_t(2) << i); ++j) { + dxbc::Dest packed_dest_half( + dxbc::Dest::R(packed_temp, 1 << (packed_temp_components + (j >> 1)))); + // Convert to 16-bit float. + a_.OpF32ToF16((j & 1) ? temp1_dest : packed_dest_half, dxbc::Src::R(color_temp).Select(j)); + // Pack green or alpha. + if (j & 1) { + a_.OpBFI(packed_dest_half, dxbc::Src::LU(16), dxbc::Src::LU(16), temp1_src, + dxbc::Src::R(packed_temp).Select(packed_temp_components + (j >> 1))); + } + } + a_.OpBreak(); + } + + if (packed_temp != color_temp) { + // Assume k_32_FLOAT or k_32_32_FLOAT for the rest. + a_.OpDefault(); + a_.OpMov(dxbc::Dest::R(packed_temp, 0b11 << packed_temp_components), + dxbc::Src::R(color_temp, 0b0100 << (packed_temp_components * 2))); + a_.OpBreak(); + } + + a_.OpEndSwitch(); +} + +void DxbcShaderTranslator::ROV_HandleColorBlendFactorCases(uint32_t src_temp, uint32_t dst_temp, + uint32_t factor_temp) { + dxbc::Dest factor_dest(dxbc::Dest::R(factor_temp, 0b0111)); + dxbc::Src one_src(dxbc::Src::LF(1.0f)); + + // kOne. + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kOne))); + a_.OpMov(factor_dest, one_src); + a_.OpBreak(); + + // kSrcColor + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kSrcColor))); + if (factor_temp != src_temp) { + a_.OpMov(factor_dest, dxbc::Src::R(src_temp)); + } + a_.OpBreak(); + + // kOneMinusSrcColor + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kOneMinusSrcColor))); + a_.OpAdd(factor_dest, one_src, -dxbc::Src::R(src_temp)); + a_.OpBreak(); + + // kSrcAlpha + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kSrcAlpha))); + a_.OpMov(factor_dest, dxbc::Src::R(src_temp, dxbc::Src::kWWWW)); + a_.OpBreak(); + + // kOneMinusSrcAlpha + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kOneMinusSrcAlpha))); + a_.OpAdd(factor_dest, one_src, -dxbc::Src::R(src_temp, dxbc::Src::kWWWW)); + a_.OpBreak(); + + // kDstColor + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kDstColor))); + if (factor_temp != dst_temp) { + a_.OpMov(factor_dest, dxbc::Src::R(dst_temp)); + } + a_.OpBreak(); + + // kOneMinusDstColor + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kOneMinusDstColor))); + a_.OpAdd(factor_dest, one_src, -dxbc::Src::R(dst_temp)); + a_.OpBreak(); + + // kDstAlpha + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kDstAlpha))); + a_.OpMov(factor_dest, dxbc::Src::R(dst_temp, dxbc::Src::kWWWW)); + a_.OpBreak(); + + // kOneMinusDstAlpha + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kOneMinusDstAlpha))); + a_.OpAdd(factor_dest, one_src, -dxbc::Src::R(dst_temp, dxbc::Src::kWWWW)); + a_.OpBreak(); + + // Factors involving the constant. + + // kConstantColor + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kConstantColor))); + a_.OpMov(factor_dest, + LoadSystemConstant(SystemConstants::Index::kEdramBlendConstant, + offsetof(SystemConstants, edram_blend_constant), dxbc::Src::kXYZW)); + a_.OpBreak(); + + // kOneMinusConstantColor + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kOneMinusConstantColor))); + a_.OpAdd(factor_dest, one_src, + -LoadSystemConstant(SystemConstants::Index::kEdramBlendConstant, + offsetof(SystemConstants, edram_blend_constant), dxbc::Src::kXYZW)); + a_.OpBreak(); + + // kConstantAlpha + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kConstantAlpha))); + a_.OpMov(factor_dest, + LoadSystemConstant(SystemConstants::Index::kEdramBlendConstant, + offsetof(SystemConstants, edram_blend_constant), dxbc::Src::kWWWW)); + a_.OpBreak(); + + // kOneMinusConstantAlpha + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kOneMinusConstantAlpha))); + a_.OpAdd(factor_dest, one_src, + -LoadSystemConstant(SystemConstants::Index::kEdramBlendConstant, + offsetof(SystemConstants, edram_blend_constant), dxbc::Src::kWWWW)); + a_.OpBreak(); + + // kSrcAlphaSaturate + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kSrcAlphaSaturate))); + a_.OpAdd(dxbc::Dest::R(factor_temp, 0b0001), one_src, -dxbc::Src::R(dst_temp, dxbc::Src::kWWWW)); + a_.OpMin(factor_dest, dxbc::Src::R(src_temp, dxbc::Src::kWWWW), + dxbc::Src::R(factor_temp, dxbc::Src::kXXXX)); + a_.OpBreak(); + + // kZero default. + a_.OpDefault(); + a_.OpMov(factor_dest, dxbc::Src::LF(0.0f)); + a_.OpBreak(); +} + +void DxbcShaderTranslator::ROV_HandleAlphaBlendFactorCases(uint32_t src_temp, uint32_t dst_temp, + uint32_t factor_temp, + uint32_t factor_component) { + dxbc::Dest factor_dest(dxbc::Dest::R(factor_temp, 1 << factor_component)); + dxbc::Src one_src(dxbc::Src::LF(1.0f)); + + // kOne, kSrcAlphaSaturate. + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kOne))); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kSrcAlphaSaturate))); + a_.OpMov(factor_dest, one_src); + a_.OpBreak(); + + // kSrcColor, kSrcAlpha. + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kSrcColor))); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kSrcAlpha))); + if (factor_temp != src_temp || factor_component != 3) { + a_.OpMov(factor_dest, dxbc::Src::R(src_temp, dxbc::Src::kWWWW)); + } + a_.OpBreak(); + + // kOneMinusSrcColor, kOneMinusSrcAlpha. + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kOneMinusSrcColor))); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kOneMinusSrcAlpha))); + a_.OpAdd(factor_dest, one_src, -dxbc::Src::R(src_temp, dxbc::Src::kWWWW)); + a_.OpBreak(); + + // kDstColor, kDstAlpha. + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kDstColor))); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kDstAlpha))); + if (factor_temp != dst_temp || factor_component != 3) { + a_.OpMov(factor_dest, dxbc::Src::R(dst_temp, dxbc::Src::kWWWW)); + } + a_.OpBreak(); + + // kOneMinusDstColor, kOneMinusDstAlpha. + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kOneMinusDstColor))); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kOneMinusDstAlpha))); + a_.OpAdd(factor_dest, one_src, -dxbc::Src::R(dst_temp, dxbc::Src::kWWWW)); + a_.OpBreak(); + + // Factors involving the constant. + + // kConstantColor, kConstantAlpha. + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kConstantColor))); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kConstantAlpha))); + a_.OpMov(factor_dest, + LoadSystemConstant(SystemConstants::Index::kEdramBlendConstant, + offsetof(SystemConstants, edram_blend_constant), dxbc::Src::kWWWW)); + a_.OpBreak(); + + // kOneMinusConstantColor, kOneMinusConstantAlpha. + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kOneMinusConstantColor))); + a_.OpCase(dxbc::Src::LU(uint32_t(xenos::BlendFactor::kOneMinusConstantAlpha))); + a_.OpAdd(factor_dest, one_src, + -LoadSystemConstant(SystemConstants::Index::kEdramBlendConstant, + offsetof(SystemConstants, edram_blend_constant), dxbc::Src::kWWWW)); + a_.OpBreak(); + + // kZero default. + a_.OpDefault(); + a_.OpMov(factor_dest, dxbc::Src::LF(0.0f)); + a_.OpBreak(); +} + +void DxbcShaderTranslator::CompletePixelShader_WriteToRTVs() { + uint32_t shader_writes_color_targets = current_shader().writes_color_targets(); + if (!shader_writes_color_targets) { + return; + } + + uint32_t gamma_temp = PushSystemTemp(); + for (uint32_t i = 0; i < 4; ++i) { + if (!(shader_writes_color_targets & (1 << i))) { + continue; + } + uint32_t system_temp_color = system_temps_color_[i]; + // Apply the exponent bias after alpha to coverage because it needs the + // unbiased alpha from the shader. + a_.OpMul(dxbc::Dest::R(system_temp_color), dxbc::Src::R(system_temp_color), + LoadSystemConstant(SystemConstants::Index::kColorExpBias, + offsetof(SystemConstants, color_exp_bias) + sizeof(float) * i, + dxbc::Src::kXXXX)); + if (gamma_render_target_as_unorm8_) { + // Convert to gamma space - this is incorrect, since it must be done after + // blending on the Xbox 360, but this is just one of many blending issues + // in the RTV path. + a_.OpAnd(dxbc::Dest::R(gamma_temp, 0b0001), LoadFlagsSystemConstant(), + dxbc::Src::LU(kSysFlag_ConvertColor0ToGamma << i)); + a_.OpIf(true, dxbc::Src::R(gamma_temp, dxbc::Src::kXXXX)); + // Saturate before the gamma conversion. + a_.OpMov(dxbc::Dest::R(system_temp_color, 0b0111), dxbc::Src::R(system_temp_color), true); + for (uint32_t j = 0; j < 3; ++j) { + PreSaturatedLinearToPWLGamma(a_, system_temp_color, j, system_temp_color, j, gamma_temp, 0, + gamma_temp, 1); + } + a_.OpEndIf(); + } + // Copy the color from a readable temp register to an output register. + a_.OpMov(dxbc::Dest::O(i), dxbc::Src::R(system_temp_color)); + } + // Release gamma_temp. + PopSystemTemp(); +} + +void DxbcShaderTranslator::CompletePixelShader_DSV_DepthTo24Bit() { + bool shader_writes_depth = current_shader().writes_depth(); + + if (!DSV_IsWritingFloat24Depth()) { + if (shader_writes_depth) { + // If not converting, but the shader writes depth explicitly, for float24, + // need to scale it from guest 0...1 to host 0...0.5 to support + // reinterpretation round trips as viewport scaling doesn't apply to + // oDepth. + a_.OpAnd(dxbc::Dest::R(system_temp_depth_stencil_, 0b0010), LoadFlagsSystemConstant(), + dxbc::Src::LU(kSysFlag_DepthFloat24)); + a_.OpIf(true, dxbc::Src::R(system_temp_depth_stencil_, dxbc::Src::kYYYY)); + a_.OpMul(dxbc::Dest::R(system_temp_depth_stencil_, 0b0001), + dxbc::Src::R(system_temp_depth_stencil_, dxbc::Src::kXXXX), dxbc::Src::LF(0.5f)); + a_.OpEndIf(); + // Write the depth from the temporary to the system depth output. + a_.OpMov(dxbc::Dest::ODepth(), dxbc::Src::R(system_temp_depth_stencil_, dxbc::Src::kXXXX)); + } + return; + } + + uint32_t temp; + if (shader_writes_depth) { + // The depth is already written to system_temp_depth_stencil_.x and clamped + // to 0...1 with NaNs dropped (saturating in StoreResult); yzw are free. + temp = system_temp_depth_stencil_; + } else { + // Need a temporary variable; remap the sample's depth input from host + // 0...0.5 back to guest 0...1 for conversion purposes to it and saturate it + // (in Direct3D 11, depth is clamped to the viewport bounds after the pixel + // shader, and SV_Position.z contains the unclamped depth, which may be + // outside the viewport's depth range if it's biased); though it will be + // clamped to the viewport bounds anyway, but to be able to make the + // assumption of it being clamped while working with the bit representation. + temp = PushSystemTemp(); + in_position_used_ |= 0b0100; + a_.OpMul(dxbc::Dest::R(temp, 0b0001), dxbc::Src::V1D(in_reg_ps_position_, dxbc::Src::kZZZZ), + dxbc::Src::LF(2.0f), true); + } + + dxbc::Dest temp_x_dest(dxbc::Dest::R(temp, 0b0001)); + dxbc::Src temp_x_src(dxbc::Src::R(temp, dxbc::Src::kXXXX)); + dxbc::Dest temp_y_dest(dxbc::Dest::R(temp, 0b0010)); + dxbc::Src temp_y_src(dxbc::Src::R(temp, dxbc::Src::kYYYY)); + + if (GetDxbcShaderModification().pixel.depth_stencil_mode == + Modification::DepthStencilMode::kFloat24Truncating) { + // Simplified conversion, always less than or equal to the original value - + // just drop the lower bits. + // The float32 exponent bias is 127. + // After saturating, the exponent range is -127...0. + // The smallest normalized 20e4 exponent is -14 - should drop 3 mantissa + // bits at -14 or above. + // The smallest denormalized 20e4 number is -34 - should drop 23 mantissa + // bits at -34. + // Anything smaller than 2^-34 becomes 0. + dxbc::Dest truncate_dest(shader_writes_depth ? dxbc::Dest::ODepth() : dxbc::Dest::ODepthLE()); + // Check if the number is representable as a float24 after truncation - the + // exponent is at least -34. + a_.OpUGE(temp_y_dest, temp_x_src, dxbc::Src::LU(0x2E800000)); + a_.OpIf(true, temp_y_src); + { + // Extract the biased float32 exponent to temp.y. + // temp.y = 113+ at exponent -14+. + // temp.y = 93 at exponent -34. + a_.OpUBFE(temp_y_dest, dxbc::Src::LU(8), dxbc::Src::LU(23), temp_x_src); + // Convert exponent to the unclamped number of bits to truncate. + // 116 - 113 = 3. + // 116 - 93 = 23. + // temp.y = 3+ at exponent -14+. + // temp.y = 23 at exponent -34. + a_.OpIAdd(temp_y_dest, dxbc::Src::LI(116), -temp_y_src); + // Clamp the truncated bit count to drop 3 bits of any normal number. + // Exponents below -34 are handled separately. + // temp.y = 3 at exponent -14. + // temp.y = 23 at exponent -34. + a_.OpIMax(temp_y_dest, temp_y_src, dxbc::Src::LI(3)); + // Truncate the mantissa - fill the low bits with zeros. + // temp.x = result in 0...1 range + a_.OpBFI(temp_x_dest, temp_y_src, dxbc::Src::LU(0), dxbc::Src::LU(0), temp_x_src); + // Remap from guest 0...1 to host 0...0.5. + a_.OpMul(truncate_dest, temp_x_src, dxbc::Src::LF(0.5f)); + } + // The number is not representable as float24 after truncation - zero. + a_.OpElse(); + a_.OpMov(truncate_dest, dxbc::Src::LF(0.0f)); + // Close the non-zero result check. + a_.OpEndIf(); + } else { + // Properly convert to 20e4, with rounding to the nearest even (the bias was + // pre-applied by multiplying by 2), then convert back restoring the bias. + PreClampedDepthTo20e4(a_, temp, 0, temp, 0, temp, 1, true, false); + Depth20e4To32(a_, dxbc::Dest::ODepth(), temp, 0, 0, temp, 0, temp, 1, true); + } + + if (!shader_writes_depth) { + // Release temp. + PopSystemTemp(); + } +} + +void DxbcShaderTranslator::CompletePixelShader_AlphaToMaskSample( + bool initialize, uint32_t sample_index, float threshold_base, dxbc::Src threshold_offset, + float threshold_offset_scale, uint32_t coverage_temp, uint32_t coverage_temp_component, + uint32_t temp, uint32_t temp_component) { + dxbc::Dest temp_dest(dxbc::Dest::R(temp, 1 << temp_component)); + dxbc::Src temp_src(dxbc::Src::R(temp).Select(temp_component)); + // Calculate the threshold. + a_.OpMAd(temp_dest, threshold_offset, dxbc::Src::LF(-threshold_offset_scale), + dxbc::Src::LF(threshold_base)); + // Check if alpha of oC0 is at or greater than the threshold (handling NaN + // according to the Direct3D 11.3 functional specification, as not covered). + a_.OpGE(temp_dest, dxbc::Src::R(system_temps_color_[0], dxbc::Src::kWWWW), temp_src); + dxbc::Dest coverage_dest(dxbc::Dest::R(coverage_temp, 1 << coverage_temp_component)); + dxbc::Src coverage_src(dxbc::Src::R(coverage_temp).Select(coverage_temp_component)); + if (edram_rov_used_) { + assert_true(coverage_temp != temp || coverage_temp_component != temp_component); + // Keep all bits in but the ones that need to be removed in case of failure. + // For ROV, the test must effect not only the coverage bits, but also the + // deferred depth/stencil write bits since the coverage is zeroed for + // samples that have failed the depth/stencil test, but stencil may still + // require writing - but if the sample is discarded by alpha to coverage, it + // must not be written at all. + a_.OpOr(temp_dest, temp_src, dxbc::Src::LU(~(uint32_t(0b00010001) << sample_index))); + // Clear the coverage for samples that have failed the test. + a_.OpAnd(coverage_dest, coverage_src, temp_src); + } else { + if (initialize) { + // First sample tested - initialize. + assert_true(coverage_temp != temp || coverage_temp_component != temp_component); + a_.OpAnd(coverage_dest, temp_src, dxbc::Src::LU(uint32_t(1) << sample_index)); + } else { + // Not first sample tested - add. + a_.OpAnd(temp_dest, temp_src, dxbc::Src::LU(uint32_t(1) << sample_index)); + a_.OpOr(coverage_dest, coverage_src, temp_src); + } + } +} + +void DxbcShaderTranslator::CompletePixelShader_AlphaToMask() { + // Check if alpha to coverage can be done at all in this shader. + if (!current_shader().writes_color_target(0) || IsForceEarlyDepthStencilGlobalFlagEnabled()) { + return; + } + + if (!edram_rov_used_) { + // Initialize the output coverage for the case if alpha to mask is not + // enabled - it needs to be written on every execution path. + a_.OpMov(dxbc::Dest::OMask(), dxbc::Src::LU(UINT32_MAX)); + } + + // Check if alpha to coverage is enabled. + dxbc::Src alpha_to_mask_constant_src(LoadSystemConstant(SystemConstants::Index::kAlphaToMask, + offsetof(SystemConstants, alpha_to_mask), + dxbc::Src::kXXXX)); + a_.OpIf(true, alpha_to_mask_constant_src); + + uint32_t temp = PushSystemTemp(); + dxbc::Dest temp_x_dest(dxbc::Dest::R(temp, 0b0001)); + dxbc::Src temp_x_src(dxbc::Src::R(temp, dxbc::Src::kXXXX)); + + // Get the dithering threshold offset index for the pixel, Y - low bit of + // offset index, X - high bit, and extract the offset and convert it to + // floating-point. With resolution scaling, still using host pixels, to + // preserve the idea of dithering. + // temp.x = alpha to coverage offset as float 0.0...3.0. + in_position_used_ |= 0b0011; + a_.OpFToU(dxbc::Dest::R(temp, 0b0011), dxbc::Src::V1D(in_reg_ps_position_)); + a_.OpAnd(dxbc::Dest::R(temp, 0b0010), dxbc::Src::R(temp, dxbc::Src::kYYYY), dxbc::Src::LU(1)); + a_.OpBFI(temp_x_dest, dxbc::Src::LU(1), dxbc::Src::LU(1), temp_x_src, + dxbc::Src::R(temp, dxbc::Src::kYYYY)); + a_.OpIShL(temp_x_dest, temp_x_src, dxbc::Src::LU(1)); + a_.OpUBFE(temp_x_dest, dxbc::Src::LU(2), temp_x_src, alpha_to_mask_constant_src); + a_.OpUToF(temp_x_dest, temp_x_src); + + // Write the result to temp.z for RTV or to system_temp_rov_params_.x for ROV. + // temp.x = alpha to coverage offset as float 0.0...3.0. + // temp.z = without ROV, accumulated coverage. + uint32_t coverage_temp = edram_rov_used_ ? system_temp_rov_params_ : temp; + uint32_t coverage_temp_component = edram_rov_used_ ? 0 : 2; + + // Check if MSAA is enabled. + a_.OpIf(true, LoadSystemConstant(SystemConstants::Index::kSampleCountLog2, + offsetof(SystemConstants, sample_count_log2), dxbc::Src::kYYYY)); + { + // Check if MSAA is 4x or 2x. + a_.OpIf(true, + LoadSystemConstant(SystemConstants::Index::kSampleCountLog2, + offsetof(SystemConstants, sample_count_log2), dxbc::Src::kXXXX)); + // 4x MSAA. + // Sample 0 must be checked first - CompletePixelShader_AlphaToMaskSample + // initializes the result for sample index 0. + CompletePixelShader_AlphaToMaskSample(true, 0, 0.75f, temp_x_src, 1.0f / 16.0f, coverage_temp, + coverage_temp_component, temp, 1); + CompletePixelShader_AlphaToMaskSample(false, 1, 0.25f, temp_x_src, 1.0f / 16.0f, coverage_temp, + coverage_temp_component, temp, 1); + CompletePixelShader_AlphaToMaskSample(false, 2, 0.5f, temp_x_src, 1.0f / 16.0f, coverage_temp, + coverage_temp_component, temp, 1); + CompletePixelShader_AlphaToMaskSample(false, 3, 1.0f, temp_x_src, 1.0f / 16.0f, coverage_temp, + coverage_temp_component, temp, 1); + // 2x MSAA. + // With ROV, using guest sample indices. + // Without ROV: + // - Native 2x: top (0 in Xenia) is 1 in D3D10.1+, bottom (1 in Xenia) is 0. + // - 2x as 4x: top is 0, bottom is 3. + a_.OpElse(); + CompletePixelShader_AlphaToMaskSample(true, (!edram_rov_used_ && msaa_2x_supported_) ? 1 : 0, + 0.5f, temp_x_src, 1.0f / 8.0f, coverage_temp, + coverage_temp_component, temp, 1); + CompletePixelShader_AlphaToMaskSample(false, edram_rov_used_ ? 1 : (msaa_2x_supported_ ? 0 : 3), + 1.0f, temp_x_src, 1.0f / 8.0f, coverage_temp, + coverage_temp_component, temp, 1); + // Close the 4x check. + a_.OpEndIf(); + } + // MSAA is disabled. + a_.OpElse(); + CompletePixelShader_AlphaToMaskSample(true, 0, 1.0f, temp_x_src, 1.0f / 4.0f, coverage_temp, + coverage_temp_component, temp, 1); + // Close the 2x/4x check. + a_.OpEndIf(); + + // Check if any sample is still covered and return to avoid unneeded work (the + // driver's shader compiler may place return after a discard, but it will + // likely not place one during SV_Coverage assignment - that's what the AMD + // compiler does, at least). Then, if needed, write the coverage value. + if (edram_rov_used_) { + // The mask includes both 0:3 and 4:7 parts because there may be samples + // which passed alpha to coverage, but not stencil test, and the stencil + // buffer needs to be modified - in this case, samples would be dropped in + // 0:3, but not in 4:7). + a_.OpAnd(temp_x_dest, dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), + dxbc::Src::LU(0b11111111)); + a_.OpRetC(false, temp_x_src); + } else { + dxbc::Src coverage_src(dxbc::Src::R(coverage_temp, coverage_temp_component)); + a_.OpDiscard(false, coverage_src); + a_.OpMov(dxbc::Dest::OMask(), coverage_src); + } + + // Release temp. + PopSystemTemp(); + + // Close the alpha to coverage check. + a_.OpEndIf(); +} + +void DxbcShaderTranslator::CompletePixelShader_WriteToROV() { + uint32_t temp = PushSystemTemp(); + dxbc::Dest temp_x_dest(dxbc::Dest::R(temp, 0b0001)); + dxbc::Src temp_x_src(dxbc::Src::R(temp, dxbc::Src::kXXXX)); + dxbc::Dest temp_y_dest(dxbc::Dest::R(temp, 0b0010)); + dxbc::Src temp_y_src(dxbc::Src::R(temp, dxbc::Src::kYYYY)); + dxbc::Dest temp_z_dest(dxbc::Dest::R(temp, 0b0100)); + dxbc::Src temp_z_src(dxbc::Src::R(temp, dxbc::Src::kZZZZ)); + dxbc::Dest temp_w_dest(dxbc::Dest::R(temp, 0b1000)); + dxbc::Src temp_w_src(dxbc::Src::R(temp, dxbc::Src::kWWWW)); + + uint32_t tile_width = xenos::kEdramTileWidthSamples * draw_resolution_scale_x_; + + // Do late depth/stencil test (which includes writing) if needed or deferred + // depth writing. + if (ROV_IsDepthStencilEarly()) { + // Write modified depth/stencil. + for (uint32_t i = 0; i < 4; ++i) { + // Get if need to write to temp.x. + // temp.x = whether the depth sample needs to be written. + a_.OpAnd(temp_x_dest, dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), + dxbc::Src::LU(1 << (4 + i))); + // Check if need to write. + // temp.x = free. + a_.OpIf(true, temp_x_src); + { + // Write the new depth/stencil. + if (uav_index_edram_ == kBindingIndexUnallocated) { + uav_index_edram_ = uav_count_++; + } + a_.OpStoreUAVTyped(dxbc::Dest::U(uav_index_edram_, uint32_t(UAVRegister::kEdram)), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), 1, + dxbc::Src::R(system_temp_depth_stencil_).Select(i)); + } + // Close the write check. + a_.OpEndIf(); + // Go to the next sample (samples are at +0, +(80*scale_x), +1, + // +(80*scale_x+1), so need to do +(80*scale_x), -(80*scale_x-1), + // +(80*scale_x) and -(80*scale_x+1) after each sample). + if (i < 3) { + a_.OpIAdd(dxbc::Dest::R(system_temp_rov_params_, 0b0010), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), + dxbc::Src::LI((i & 1) ? -int32_t(tile_width) + 2 - i : int32_t(tile_width))); + } + } + } else { + ROV_DepthStencilTest(); + } + + // system_temp_rov_params_.y (the depth / stencil sample address) is not + // needed anymore, can be used for color writing. + + if (!is_depth_only_pixel_shader_) { + // Check if any sample is still covered after depth testing and writing, + // skip color writing completely in this case. + // temp.x = whether any sample is still covered. + a_.OpAnd(temp_x_dest, dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), + dxbc::Src::LU(0b1111)); + // temp.x = free. + a_.OpRetC(false, temp_x_src); + } + + // Write color values. + uint32_t shader_writes_color_targets = current_shader().writes_color_targets(); + uint32_t edram_size_32bpp_samples = (xenos::kEdramTileHeightSamples * draw_resolution_scale_y_) * + tile_width * xenos::kEdramTileCount; + for (uint32_t i = 0; i < 4; ++i) { + if (!(shader_writes_color_targets & (1 << i))) { + continue; + } + + // This includes a swizzle to choose XY for even render targets or ZW for + // odd ones - use SelectFromSwizzled and SwizzleSwizzled. + dxbc::Src keep_mask_src(LoadSystemConstant( + SystemConstants::Index::kEdramRTKeepMask, + offsetof(SystemConstants, edram_rt_keep_mask) + sizeof(uint32_t) * 2 * i, 0b0100)); + + // Check if color writing is disabled - special keep mask constant case, + // both 32bpp parts are forced UINT32_MAX, but also check whether the shader + // has written anything to this target at all. + + // Combine both parts of the keep mask to check if both are 0xFFFFFFFF. + // temp.x = whether all bits need to be kept. + a_.OpAnd(temp_x_dest, keep_mask_src.SelectFromSwizzled(0), keep_mask_src.SelectFromSwizzled(1)); + // Flip the bits so both UINT32_MAX would result in 0 - not writing. + // temp.x = whether any bits need to be written. + a_.OpNot(temp_x_dest, temp_x_src); + // Get the bits that will be used for checking wherther the render target + // has been written to on the taken execution path - if the write mask is + // empty, AND zero with the test bit to always get zero. + // temp.x = bits for checking whether the render target has been written to. + a_.OpMovC(temp_x_dest, temp_x_src, dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), + dxbc::Src::LU(0)); + // Check if the render target was written to on the execution path. + // temp.x = whether anything was written and needs to be stored. + a_.OpAnd(temp_x_dest, temp_x_src, dxbc::Src::LU(1 << (8 + i))); + // Check if need to write anything to the render target. + // temp.x = free. + a_.OpIf(true, temp_x_src); + + // Apply the exponent bias after alpha to coverage because it needs the + // unbiased alpha from the shader. + a_.OpMul(dxbc::Dest::R(system_temps_color_[i]), dxbc::Src::R(system_temps_color_[i]), + LoadSystemConstant(SystemConstants::Index::kColorExpBias, + offsetof(SystemConstants, color_exp_bias) + sizeof(float) * i, + dxbc::Src::kXXXX)); + + dxbc::Src rt_format_flags_src(LoadSystemConstant( + SystemConstants::Index::kEdramRTFormatFlags, + offsetof(SystemConstants, edram_rt_format_flags) + sizeof(uint32_t) * i, dxbc::Src::kXXXX)); + + // Load whether the render target is 64bpp to system_temp_rov_params_.y to + // get the needed relative sample address. + a_.OpAnd(dxbc::Dest::R(system_temp_rov_params_, 0b0010), rt_format_flags_src, + dxbc::Src::LU(RenderTargetCache::kPSIColorFormatFlag_64bpp)); + // Choose the relative sample address for the render target to + // system_temp_rov_params_.y. + a_.OpMovC(dxbc::Dest::R(system_temp_rov_params_, 0b0010), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kWWWW), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kZZZZ)); + // Add the EDRAM base of the render target to system_temp_rov_params_.y. + a_.OpIAdd(dxbc::Dest::R(system_temp_rov_params_, 0b0010), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), + LoadSystemConstant( + SystemConstants::Index::kEdramRTBaseDwordsScaled, + offsetof(SystemConstants, edram_rt_base_dwords_scaled) + sizeof(uint32_t) * i, + dxbc::Src::kXXXX)); + // Wrap EDRAM addressing for the color render target to get the final sample + // address in the EDRAM to system_temp_rov_params_.y. + a_.OpUDiv(dxbc::Dest::Null(), dxbc::Dest::R(system_temp_rov_params_, 0b0010), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), + dxbc::Src::LU(edram_size_32bpp_samples)); + + dxbc::Src rt_blend_factors_ops_src(LoadSystemConstant( + SystemConstants::Index::kEdramRTBlendFactorsOps, + offsetof(SystemConstants, edram_rt_blend_factors_ops) + sizeof(uint32_t) * i, + dxbc::Src::kXXXX)); + dxbc::Src rt_clamp_vec_src(LoadSystemConstant( + SystemConstants::Index::kEdramRTClamp, + offsetof(SystemConstants, edram_rt_clamp) + sizeof(float) * 4 * i, dxbc::Src::kXYZW)); + // Get if not blending to pack the color once for all 4 samples. + // temp.x = whether blending is disabled. + a_.OpIEq(temp_x_dest, rt_blend_factors_ops_src, dxbc::Src::LU(0x00010001)); + // Check if not blending. + // temp.x = free. + a_.OpIf(true, temp_x_src); + { + // Clamp the color to the render target's representable range - will be + // packed. + a_.OpMax(dxbc::Dest::R(system_temps_color_[i]), dxbc::Src::R(system_temps_color_[i]), + rt_clamp_vec_src.Swizzle(0b01000000)); + a_.OpMin(dxbc::Dest::R(system_temps_color_[i]), dxbc::Src::R(system_temps_color_[i]), + rt_clamp_vec_src.Swizzle(0b11101010)); + // Pack the color once if blending. + // temp.xy = packed color. + ROV_PackPreClampedColor(i, system_temps_color_[i], temp, 0, temp, 2, temp, 3); + } + // Blending is enabled. + a_.OpElse(); + { + // Get if the blending source color is fixed-point for clamping if it is. + // temp.x = whether color is fixed-point. + a_.OpAnd(temp_x_dest, rt_format_flags_src, + dxbc::Src::LU(RenderTargetCache::kPSIColorFormatFlag_FixedPointColor)); + // Check if the blending source color is fixed-point and needs clamping. + // temp.x = free. + a_.OpIf(true, temp_x_src); + { + // Clamp the blending source color if needed. + a_.OpMax(dxbc::Dest::R(system_temps_color_[i], 0b0111), + dxbc::Src::R(system_temps_color_[i]), rt_clamp_vec_src.Select(0)); + a_.OpMin(dxbc::Dest::R(system_temps_color_[i], 0b0111), + dxbc::Src::R(system_temps_color_[i]), rt_clamp_vec_src.Select(2)); + } + // Close the fixed-point color check. + a_.OpEndIf(); + + // Get if the blending source alpha is fixed-point for clamping if it is. + // temp.x = whether alpha is fixed-point. + a_.OpAnd(temp_x_dest, rt_format_flags_src, + dxbc::Src::LU(RenderTargetCache::kPSIColorFormatFlag_FixedPointAlpha)); + // Check if the blending source alpha is fixed-point and needs clamping. + // temp.x = free. + a_.OpIf(true, temp_x_src); + { + // Clamp the blending source alpha if needed. + a_.OpMax(dxbc::Dest::R(system_temps_color_[i], 0b1000), + dxbc::Src::R(system_temps_color_[i], dxbc::Src::kWWWW), + rt_clamp_vec_src.Select(1)); + a_.OpMin(dxbc::Dest::R(system_temps_color_[i], 0b1000), + dxbc::Src::R(system_temps_color_[i], dxbc::Src::kWWWW), + rt_clamp_vec_src.Select(3)); + } + // Close the fixed-point alpha check. + a_.OpEndIf(); + // Break register dependency in the color sample raster operation. + // temp.xy = 0 instead of packed color. + a_.OpMov(dxbc::Dest::R(temp, 0b0011), dxbc::Src::LU(0)); + } + a_.OpEndIf(); + + // Blend, mask and write all samples. + for (uint32_t j = 0; j < 4; ++j) { + // Get if the sample is covered. + // temp.z = whether the sample is covered. + a_.OpAnd(temp_z_dest, dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), + dxbc::Src::LU(1 << j)); + + // Check if the sample is covered. + // temp.z = free. + a_.OpIf(true, temp_z_src); + + // Only temp.xy are used at this point (containing the packed color from + // the shader if not blending). + + // *********************************************************************** + // Color sample raster operation. + // *********************************************************************** + + // *********************************************************************** + // Checking if color loading must be done - if any component needs to be + // kept or if blending is enabled. + // *********************************************************************** + + // Get if need to keep any components to temp.z. + // temp.z = whether any components must be kept (OR of keep masks). + a_.OpOr(temp_z_dest, keep_mask_src.SelectFromSwizzled(0), + keep_mask_src.SelectFromSwizzled(1)); + // Blending isn't done if it's 1 * source + 0 * destination. But since the + // previous color also needs to be loaded if any original components need + // to be kept, force the blend control to something with blending in this + // case in temp.z. + // temp.z = blending mode used to check if need to load. + a_.OpMovC(temp_z_dest, temp_z_src, dxbc::Src::LU(0), rt_blend_factors_ops_src); + // Get if the blend control register requires loading the color to temp.z. + // temp.z = whether need to load the color. + a_.OpINE(temp_z_dest, temp_z_src, dxbc::Src::LU(0x00010001)); + // Check if need to do something with the previous color. + // temp.z = free. + a_.OpIf(true, temp_z_src); + { + // ********************************************************************* + // Loading the previous color to temp.zw. + // ********************************************************************* + + // Load the 32bpp color, or the lower 32 bits of the 64bpp color, to + // temp.z. + // temp.z = 32-bit packed color or lower 32 bits of the packed color. + if (uav_index_edram_ == kBindingIndexUnallocated) { + uav_index_edram_ = uav_count_++; + } + a_.OpLdUAVTyped( + temp_z_dest, dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), 1, + dxbc::Src::U(uav_index_edram_, uint32_t(UAVRegister::kEdram), dxbc::Src::kXXXX)); + // Get if the format is 64bpp to temp.w. + // temp.w = whether the render target is 64bpp. + a_.OpAnd(temp_w_dest, rt_format_flags_src, + dxbc::Src::LU(RenderTargetCache::kPSIColorFormatFlag_64bpp)); + // Check if the format is 64bpp. + // temp.w = free. + a_.OpIf(true, temp_w_src); + { + // Get the address of the upper 32 bits of the color to temp.w. + // temp.w = address of the upper 32 bits of the packed color. + a_.OpIAdd(temp_w_dest, dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), + dxbc::Src::LU(1)); + // Load the upper 32 bits of the 64bpp color to temp.w. + // temp.zw = packed destination color/alpha. + if (uav_index_edram_ == kBindingIndexUnallocated) { + uav_index_edram_ = uav_count_++; + } + a_.OpLdUAVTyped( + temp_w_dest, temp_w_src, 1, + dxbc::Src::U(uav_index_edram_, uint32_t(UAVRegister::kEdram), dxbc::Src::kXXXX)); + } + // The color is 32bpp. + a_.OpElse(); + { + // Break register dependency in temp.w if the color is 32bpp. + // temp.zw = packed destination color/alpha. + a_.OpMov(temp_w_dest, dxbc::Src::LU(0)); + } + // Close the color format check. + a_.OpEndIf(); + + uint32_t color_temp = PushSystemTemp(); + dxbc::Dest color_temp_rgb_dest(dxbc::Dest::R(color_temp, 0b0111)); + dxbc::Dest color_temp_a_dest(dxbc::Dest::R(color_temp, 0b1000)); + dxbc::Src color_temp_src(dxbc::Src::R(color_temp)); + dxbc::Src color_temp_a_src(dxbc::Src::R(color_temp, dxbc::Src::kWWWW)); + + // Get if blending is enabled to color_temp.x. + // color_temp.x = whether blending is enabled. + a_.OpINE(dxbc::Dest::R(color_temp, 0b0001), rt_blend_factors_ops_src, + dxbc::Src::LU(0x00010001)); + // Check if need to blend. + // color_temp.x = free. + a_.OpIf(true, dxbc::Src::R(color_temp, dxbc::Src::kXXXX)); + { + // Now, when blending is enabled, temp.xy are used as scratch since + // the color is packed after blending. + + // Unpack the destination color to color_temp, using temp.xy as temps. + // The destination color never needs clamping because out-of-range + // values can't be loaded. + // color_temp.xyzw = destination color/alpha. + ROV_UnpackColor(i, temp, 2, color_temp, temp, 0, temp, 1); + + // ******************************************************************* + // Color blending. + // ******************************************************************* + + // Extract the color min/max bit to temp.x. + // temp.x = whether min/max should be used for color. + a_.OpAnd(temp_x_dest, rt_blend_factors_ops_src, dxbc::Src::LU(1 << (5 + 1))); + // Check if need to do blend the color with factors. + // temp.x = free. + a_.OpIf(false, temp_x_src); + { + uint32_t blend_src_temp = PushSystemTemp(); + dxbc::Dest blend_src_temp_rgb_dest(dxbc::Dest::R(blend_src_temp, 0b0111)); + dxbc::Src blend_src_temp_src(dxbc::Src::R(blend_src_temp)); + + // Extract the source color factor to temp.x. + // temp.x = source color factor index. + a_.OpAnd(temp_x_dest, rt_blend_factors_ops_src, dxbc::Src::LU((1 << 5) - 1)); + // Check if the source color factor is not zero - if it is, the + // source must be ignored completely, and Infinity and NaN in it + // shouldn't affect blending. + a_.OpIf(true, temp_x_src); + { + // Open the switch for choosing the source color blend factor. + // temp.x = free. + a_.OpSwitch(temp_x_src); + // Write the source color factor to blend_src_temp.xyz. + // blend_src_temp.xyz = unclamped source color factor. + ROV_HandleColorBlendFactorCases(system_temps_color_[i], color_temp, blend_src_temp); + // Close the source color factor switch. + a_.OpEndSwitch(); + // Get if the render target color is fixed-point and the source + // color factor needs clamping to temp.x. + // temp.x = whether color is fixed-point. + a_.OpAnd(temp_x_dest, rt_format_flags_src, + dxbc::Src::LU(RenderTargetCache::kPSIColorFormatFlag_FixedPointColor)); + // Check if the source color factor needs clamping. + a_.OpIf(true, temp_x_src); + { + // Clamp the source color factor in blend_src_temp.xyz. + // blend_src_temp.xyz = source color factor. + a_.OpMax(blend_src_temp_rgb_dest, blend_src_temp_src, rt_clamp_vec_src.Select(0)); + a_.OpMin(blend_src_temp_rgb_dest, blend_src_temp_src, rt_clamp_vec_src.Select(2)); + } + // Close the source color factor clamping check. + a_.OpEndIf(); + // Apply the factor to the source color. + // blend_src_temp.xyz = unclamped source color part without + // addition sign. + a_.OpMul(blend_src_temp_rgb_dest, dxbc::Src::R(system_temps_color_[i]), + blend_src_temp_src); + // Check if the source color part needs clamping after the + // multiplication. + // temp.x = free. + a_.OpIf(true, temp_x_src); + { + // Clamp the source color part. + // blend_src_temp.xyz = source color part without addition sign. + a_.OpMax(blend_src_temp_rgb_dest, blend_src_temp_src, rt_clamp_vec_src.Select(0)); + a_.OpMin(blend_src_temp_rgb_dest, blend_src_temp_src, rt_clamp_vec_src.Select(2)); + } + // Close the source color part clamping check. + a_.OpEndIf(); + // Extract the source color sign to temp.x. + // temp.x = source color sign as zero for 1 and non-zero for -1. + a_.OpAnd(temp_x_dest, rt_blend_factors_ops_src, dxbc::Src::LU(1 << (5 + 2))); + // Apply the source color sign. + // blend_src_temp.xyz = source color part. + // temp.x = free. + a_.OpMovC(blend_src_temp_rgb_dest, temp_x_src, -blend_src_temp_src, + blend_src_temp_src); + } + // The source color factor is zero. + a_.OpElse(); + { + // Write zero to the source color part. + // blend_src_temp.xyz = source color part. + // temp.x = free. + a_.OpMov(blend_src_temp_rgb_dest, dxbc::Src::LF(0.0f)); + } + // Close the source color factor zero check. + a_.OpEndIf(); + + // Extract the destination color factor to temp.x. + // temp.x = destination color factor index. + a_.OpUBFE(temp_x_dest, dxbc::Src::LU(5), dxbc::Src::LU(8), rt_blend_factors_ops_src); + // Check if the destination color factor is not zero. + a_.OpIf(true, temp_x_src); + { + uint32_t blend_dest_factor_temp = PushSystemTemp(); + dxbc::Src blend_dest_factor_temp_src(dxbc::Src::R(blend_dest_factor_temp)); + // Open the switch for choosing the destination color blend + // factor. + // temp.x = free. + a_.OpSwitch(temp_x_src); + // Write the destination color factor to + // blend_dest_factor_temp.xyz. + // blend_dest_factor_temp.xyz = unclamped destination color + // factor. + ROV_HandleColorBlendFactorCases(system_temps_color_[i], color_temp, + blend_dest_factor_temp); + // Close the destination color factor switch. + a_.OpEndSwitch(); + // Get if the render target color is fixed-point and the + // destination color factor needs clamping to temp.x. + // temp.x = whether color is fixed-point. + a_.OpAnd(temp_x_dest, rt_format_flags_src, + dxbc::Src::LU(RenderTargetCache::kPSIColorFormatFlag_FixedPointColor)); + // Check if the destination color factor needs clamping. + a_.OpIf(true, temp_x_src); + { + // Clamp the destination color factor in + // blend_dest_factor_temp.xyz. + // blend_dest_factor_temp.xyz = destination color factor. + a_.OpMax(dxbc::Dest::R(blend_dest_factor_temp, 0b0111), blend_dest_factor_temp_src, + rt_clamp_vec_src.Select(0)); + a_.OpMin(dxbc::Dest::R(blend_dest_factor_temp, 0b0111), blend_dest_factor_temp_src, + rt_clamp_vec_src.Select(2)); + } + // Close the destination color factor clamping check. + a_.OpEndIf(); + // Apply the factor to the destination color in color_temp.xyz. + // color_temp.xyz = unclamped destination color part without + // addition sign. + // blend_dest_temp.xyz = free. + a_.OpMul(color_temp_rgb_dest, color_temp_src, blend_dest_factor_temp_src); + // Release blend_dest_factor_temp. + PopSystemTemp(); + // Check if the destination color part needs clamping after the + // multiplication. + // temp.x = free. + a_.OpIf(true, temp_x_src); + { + // Clamp the destination color part. + // color_temp.xyz = destination color part without addition + // sign. + a_.OpMax(color_temp_rgb_dest, color_temp_src, rt_clamp_vec_src.Select(0)); + a_.OpMin(color_temp_rgb_dest, color_temp_src, rt_clamp_vec_src.Select(2)); + } + // Close the destination color part clamping check. + a_.OpEndIf(); + // Extract the destination color sign to temp.x. + // temp.x = destination color sign as zero for 1 and non-zero for + // -1. + a_.OpAnd(temp_x_dest, rt_blend_factors_ops_src, dxbc::Src::LU(1 << 5)); + // Select the sign for destination multiply-add as 1.0 or -1.0 to + // temp.x. + // temp.x = destination color sign as float. + a_.OpMovC(temp_x_dest, temp_x_src, dxbc::Src::LF(-1.0f), dxbc::Src::LF(1.0f)); + // Perform color blending to color_temp.xyz. + // color_temp.xyz = unclamped blended color. + // blend_src_temp.xyz = free. + // temp.x = free. + a_.OpMAd(color_temp_rgb_dest, color_temp_src, temp_x_src, blend_src_temp_src); + } + // The destination color factor is zero. + a_.OpElse(); + { + // Write the source color part without applying the destination + // color. + // color_temp.xyz = unclamped blended color. + // blend_src_temp.xyz = free. + // temp.x = free. + a_.OpMov(color_temp_rgb_dest, blend_src_temp_src); + } + // Close the destination color factor zero check. + a_.OpEndIf(); + + // Release blend_src_temp. + PopSystemTemp(); + + // Clamp the color in color_temp.xyz before packing. + // color_temp.xyz = blended color. + a_.OpMax(color_temp_rgb_dest, color_temp_src, rt_clamp_vec_src.Select(0)); + a_.OpMin(color_temp_rgb_dest, color_temp_src, rt_clamp_vec_src.Select(2)); + } + // Need to do min/max for color. + a_.OpElse(); + { + // Extract the color min (0) or max (1) bit to temp.x + // temp.x = whether min or max should be used for color. + a_.OpAnd(temp_x_dest, rt_blend_factors_ops_src, dxbc::Src::LU(1 << 5)); + // Check if need to do min or max for color. + // temp.x = free. + a_.OpIf(true, temp_x_src); + { + // Choose max of the colors without applying the factors to + // color_temp.xyz. + // color_temp.xyz = blended color. + a_.OpMax(color_temp_rgb_dest, dxbc::Src::R(system_temps_color_[i]), color_temp_src); + } + // Need to do min. + a_.OpElse(); + { + // Choose min of the colors without applying the factors to + // color_temp.xyz. + // color_temp.xyz = blended color. + a_.OpMin(color_temp_rgb_dest, dxbc::Src::R(system_temps_color_[i]), color_temp_src); + } + // Close the min or max check. + a_.OpEndIf(); + } + // Close the color factor blending or min/max check. + a_.OpEndIf(); + + // ******************************************************************* + // Alpha blending. + // ******************************************************************* + + // Extract the alpha min/max bit to temp.x. + // temp.x = whether min/max should be used for alpha. + a_.OpAnd(temp_x_dest, rt_blend_factors_ops_src, dxbc::Src::LU(1 << (21 + 1))); + // Check if need to do blend the color with factors. + // temp.x = free. + a_.OpIf(false, temp_x_src); + { + // Extract the source alpha factor to temp.x. + // temp.x = source alpha factor index. + a_.OpUBFE(temp_x_dest, dxbc::Src::LU(5), dxbc::Src::LU(16), rt_blend_factors_ops_src); + // Check if the source alpha factor is not zero. + a_.OpIf(true, temp_x_src); + { + // Open the switch for choosing the source alpha blend factor. + // temp.x = free. + a_.OpSwitch(temp_x_src); + // Write the source alpha factor to temp.x. + // temp.x = unclamped source alpha factor. + ROV_HandleAlphaBlendFactorCases(system_temps_color_[i], color_temp, temp, 0); + // Close the source alpha factor switch. + a_.OpEndSwitch(); + // Get if the render target alpha is fixed-point and the source + // alpha factor needs clamping to temp.y. + // temp.y = whether alpha is fixed-point. + a_.OpAnd(temp_y_dest, rt_format_flags_src, + dxbc::Src::LU(RenderTargetCache::kPSIColorFormatFlag_FixedPointAlpha)); + // Check if the source alpha factor needs clamping. + a_.OpIf(true, temp_y_src); + { + // Clamp the source alpha factor in temp.x. + // temp.x = source alpha factor. + a_.OpMax(temp_x_dest, temp_x_src, rt_clamp_vec_src.Select(1)); + a_.OpMin(temp_x_dest, temp_x_src, rt_clamp_vec_src.Select(3)); + } + // Close the source alpha factor clamping check. + a_.OpEndIf(); + // Apply the factor to the source alpha. + // temp.x = unclamped source alpha part without addition sign. + a_.OpMul(temp_x_dest, dxbc::Src::R(system_temps_color_[i], dxbc::Src::kWWWW), + temp_x_src); + // Check if the source alpha part needs clamping after the + // multiplication. + // temp.y = free. + a_.OpIf(true, temp_y_src); + { + // Clamp the source alpha part. + // temp.x = source alpha part without addition sign. + a_.OpMax(temp_x_dest, temp_x_src, rt_clamp_vec_src.Select(1)); + a_.OpMin(temp_x_dest, temp_x_src, rt_clamp_vec_src.Select(3)); + } + // Close the source alpha part clamping check. + a_.OpEndIf(); + // Extract the source alpha sign to temp.y. + // temp.y = source alpha sign as zero for 1 and non-zero for -1. + a_.OpAnd(temp_y_dest, rt_blend_factors_ops_src, dxbc::Src::LU(1 << (21 + 2))); + // Apply the source alpha sign. + // temp.x = source alpha part. + a_.OpMovC(temp_x_dest, temp_y_src, -temp_x_src, temp_x_src); + } + // The source alpha factor is zero. + a_.OpElse(); + { + // Write zero to the source alpha part. + // temp.x = source alpha part. + a_.OpMov(temp_x_dest, dxbc::Src::LF(0.0f)); + } + // Close the source alpha factor zero check. + a_.OpEndIf(); + + // Extract the destination alpha factor to temp.y. + // temp.y = destination alpha factor index. + a_.OpUBFE(temp_y_dest, dxbc::Src::LU(5), dxbc::Src::LU(24), rt_blend_factors_ops_src); + // Check if the destination alpha factor is not zero. + a_.OpIf(true, temp_y_src); + { + // Open the switch for choosing the destination alpha blend + // factor. + // temp.y = free. + a_.OpSwitch(temp_y_src); + // Write the destination alpha factor to temp.y. + // temp.y = unclamped destination alpha factor. + ROV_HandleAlphaBlendFactorCases(system_temps_color_[i], color_temp, temp, 1); + // Close the destination alpha factor switch. + a_.OpEndSwitch(); + // Get if the render target alpha is fixed-point and the + // destination alpha factor needs clamping. + // alpha_is_fixed_temp.x = whether alpha is fixed-point. + uint32_t alpha_is_fixed_temp = PushSystemTemp(); + a_.OpAnd(dxbc::Dest::R(alpha_is_fixed_temp, 0b0001), rt_format_flags_src, + dxbc::Src::LU(RenderTargetCache::kPSIColorFormatFlag_FixedPointAlpha)); + // Check if the destination alpha factor needs clamping. + a_.OpIf(true, dxbc::Src::R(alpha_is_fixed_temp, dxbc::Src::kXXXX)); + { + // Clamp the destination alpha factor in temp.y. + // temp.y = destination alpha factor. + a_.OpMax(temp_y_dest, temp_y_src, rt_clamp_vec_src.Select(1)); + a_.OpMin(temp_y_dest, temp_y_src, rt_clamp_vec_src.Select(3)); + } + // Close the destination alpha factor clamping check. + a_.OpEndIf(); + // Apply the factor to the destination alpha in color_temp.w. + // color_temp.w = unclamped destination alpha part without + // addition sign. + a_.OpMul(color_temp_a_dest, color_temp_a_src, temp_y_src); + // Check if the destination alpha part needs clamping after the + // multiplication. + // alpha_is_fixed_temp.x = free. + a_.OpIf(true, dxbc::Src::R(alpha_is_fixed_temp, dxbc::Src::kXXXX)); + // Release alpha_is_fixed_temp. + PopSystemTemp(); + { + // Clamp the destination alpha part. + // color_temp.w = destination alpha part without addition sign. + a_.OpMax(color_temp_a_dest, color_temp_a_src, rt_clamp_vec_src.Select(1)); + a_.OpMin(color_temp_a_dest, color_temp_a_src, rt_clamp_vec_src.Select(3)); + } + // Close the destination alpha factor clamping check. + a_.OpEndIf(); + // Extract the destination alpha sign to temp.y. + // temp.y = destination alpha sign as zero for 1 and non-zero for + // -1. + a_.OpAnd(temp_y_dest, rt_blend_factors_ops_src, dxbc::Src::LU(1 << 21)); + // Select the sign for destination multiply-add as 1.0 or -1.0 to + // temp.y. + // temp.y = destination alpha sign as float. + a_.OpMovC(temp_y_dest, temp_y_src, dxbc::Src::LF(-1.0f), dxbc::Src::LF(1.0f)); + // Perform alpha blending to color_temp.w. + // color_temp.w = unclamped blended alpha. + // temp.xy = free. + a_.OpMAd(color_temp_a_dest, color_temp_a_src, temp_y_src, temp_x_src); + } + // The destination alpha factor is zero. + a_.OpElse(); + { + // Write the source alpha part without applying the destination + // alpha. + // color_temp.w = unclamped blended alpha. + // temp.xy = free. + a_.OpMov(color_temp_a_dest, temp_x_src); + } + // Close the destination alpha factor zero check. + a_.OpEndIf(); + + // Clamp the alpha in color_temp.w before packing. + // color_temp.w = blended alpha. + a_.OpMax(color_temp_a_dest, color_temp_a_src, rt_clamp_vec_src.Select(1)); + a_.OpMin(color_temp_a_dest, color_temp_a_src, rt_clamp_vec_src.Select(3)); + } + // Need to do min/max for alpha. + a_.OpElse(); + { + // Extract the alpha min (0) or max (1) bit to temp.x. + // temp.x = whether min or max should be used for alpha. + a_.OpAnd(temp_x_dest, rt_blend_factors_ops_src, dxbc::Src::LU(1 << 21)); + // Check if need to do min or max for alpha. + // temp.x = free. + a_.OpIf(true, temp_x_src); + { + // Choose max of the alphas without applying the factors to + // color_temp.w. + // color_temp.w = blended alpha. + a_.OpMax(color_temp_a_dest, dxbc::Src::R(system_temps_color_[i], dxbc::Src::kWWWW), + color_temp_a_src); + } + // Need to do min. + a_.OpElse(); + { + // Choose min of the alphas without applying the factors to + // color_temp.w. + // color_temp.w = blended alpha. + a_.OpMin(color_temp_a_dest, dxbc::Src::R(system_temps_color_[i], dxbc::Src::kWWWW), + color_temp_a_src); + } + // Close the min or max check. + a_.OpEndIf(); + } + // Close the alpha factor blending or min/max check. + a_.OpEndIf(); + + // Pack the new color/alpha to temp.xy. + // temp.xy = packed new color/alpha. + uint32_t color_pack_temp = PushSystemTemp(); + ROV_PackPreClampedColor(i, color_temp, temp, 0, color_pack_temp, 0, color_pack_temp, 1); + // Release color_pack_temp. + PopSystemTemp(); + } + // Close the blending check. + a_.OpEndIf(); + + // ********************************************************************* + // Write mask application + // ********************************************************************* + + // Apply the keep mask to the previous packed color/alpha in temp.zw. + // temp.zw = masked packed old color/alpha. + a_.OpAnd(dxbc::Dest::R(temp, 0b1100), dxbc::Src::R(temp), + keep_mask_src.SwizzleSwizzled(0b0100 << 4)); + // Invert the keep mask into color_temp.xy. + // color_temp.xy = inverted keep mask (write mask). + a_.OpNot(dxbc::Dest::R(color_temp, 0b0011), keep_mask_src); + // Release color_temp. + PopSystemTemp(); + // Apply the write mask to the new color/alpha in temp.xy. + // temp.xy = masked packed new color/alpha. + a_.OpAnd(dxbc::Dest::R(temp, 0b0011), dxbc::Src::R(temp), dxbc::Src::R(color_temp)); + // Combine the masked colors into temp.xy. + // temp.xy = packed resulting color/alpha. + // temp.zw = free. + a_.OpOr(dxbc::Dest::R(temp, 0b0011), dxbc::Src::R(temp), dxbc::Src::R(temp, 0b1110)); + } + // Close the previous color load check. + a_.OpEndIf(); + + // *********************************************************************** + // Writing the color + // *********************************************************************** + + // Store the 32bpp color or the lower 32 bits of the 64bpp color. + if (uav_index_edram_ == kBindingIndexUnallocated) { + uav_index_edram_ = uav_count_++; + } + a_.OpStoreUAVTyped(dxbc::Dest::U(uav_index_edram_, uint32_t(UAVRegister::kEdram)), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), 1, temp_x_src); + // Get if the format is 64bpp to temp.z. + // temp.z = whether the render target is 64bpp. + a_.OpAnd(temp_z_dest, rt_format_flags_src, + dxbc::Src::LU(RenderTargetCache::kPSIColorFormatFlag_64bpp)); + // Check if the format is 64bpp. + // temp.z = free. + a_.OpIf(true, temp_z_src); + { + // Get the address of the upper 32 bits of the color to temp.z (can't + // use temp.x because components when not blending, packing is done once + // for all samples, so it has to be preserved). + a_.OpIAdd(temp_z_dest, dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), + dxbc::Src::LU(1)); + // Store the upper 32 bits of the 64bpp color. + if (uav_index_edram_ == kBindingIndexUnallocated) { + uav_index_edram_ = uav_count_++; + } + a_.OpStoreUAVTyped(dxbc::Dest::U(uav_index_edram_, uint32_t(UAVRegister::kEdram)), + temp_z_src, 1, temp_y_src); + } + // Close the 64bpp conditional. + a_.OpEndIf(); + + // *********************************************************************** + // End of color sample raster operation. + // *********************************************************************** + + // Close the sample covered check. + a_.OpEndIf(); + + // Go to the next sample (samples are at +0, +(80*scale_x), +dwpp, + // +(80*scale_x+dwpp), so need to do +(80*scale_x), -(80*scale_x-dwpp), + // +(80*scale_x) and -(80*scale_x+dwpp) after each sample). + // Though no need to do this for the last sample as for the next render + // target, the address will be recalculated. + if (j < 3) { + if (j & 1) { + // temp.z = whether the render target is 64bpp. + a_.OpAnd(temp_z_dest, rt_format_flags_src, + dxbc::Src::LU(RenderTargetCache::kPSIColorFormatFlag_64bpp)); + // temp.z = offset from the current sample to the next. + a_.OpMovC(temp_z_dest, temp_z_src, + dxbc::Src::LI(-int32_t(tile_width) + 2 * (2 - int32_t(j))), + dxbc::Src::LI(-int32_t(tile_width) + (2 - int32_t(j)))); + // temp.z = free. + a_.OpIAdd(dxbc::Dest::R(system_temp_rov_params_, 0b0010), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), temp_z_src); + } else { + a_.OpIAdd(dxbc::Dest::R(system_temp_rov_params_, 0b0010), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kYYYY), + dxbc::Src::LU(tile_width)); + } + } + } + + // Close the render target write check. + a_.OpEndIf(); + } + + // Release temp. + PopSystemTemp(); +} + +void DxbcShaderTranslator::CompletePixelShader() { + if (is_depth_only_pixel_shader_) { + // The depth-only shader only needs to do the depth test and to write the + // depth to the ROV. + if (edram_rov_used_) { + CompletePixelShader_WriteToROV(); + } + return; + } + + if (current_shader().writes_color_target(0) && !IsForceEarlyDepthStencilGlobalFlagEnabled()) { + if (edram_rov_used_) { + // Check if the render target 0 was written to on the execution path. + uint32_t rt_0_written_temp = PushSystemTemp(); + a_.OpAnd(dxbc::Dest::R(rt_0_written_temp, 0b0001), + dxbc::Src::R(system_temp_rov_params_, dxbc::Src::kXXXX), dxbc::Src::LU(1 << 8)); + a_.OpIf(true, dxbc::Src::R(rt_0_written_temp, dxbc::Src::kXXXX)); + // Release rt_0_written_temp. + PopSystemTemp(); + } + + // Alpha test. + // X - mask, then masked result (SGPR for loading, VGPR for masking). + // Y - operation result (SGPR for mask operations, VGPR for alpha + // operations). + // Z - fuzzy diff (alpha - reference), used when fuzzy epsilon is enabled. + uint32_t alpha_test_temp = PushSystemTemp(); + dxbc::Dest alpha_test_mask_dest(dxbc::Dest::R(alpha_test_temp, 0b0001)); + dxbc::Src alpha_test_mask_src(dxbc::Src::R(alpha_test_temp, dxbc::Src::kXXXX)); + dxbc::Dest alpha_test_op_dest(dxbc::Dest::R(alpha_test_temp, 0b0010)); + dxbc::Src alpha_test_op_src(dxbc::Src::R(alpha_test_temp, dxbc::Src::kYYYY)); + dxbc::Dest alpha_test_fuzzy_diff_dest(dxbc::Dest::R(alpha_test_temp, 0b0100)); + dxbc::Src alpha_test_fuzzy_diff_src(dxbc::Src::R(alpha_test_temp, dxbc::Src::kZZZZ)); + // Extract the comparison mask to check if the test needs to be done at all. + // Don't care about flow control being somewhat dynamic - early Z is forced + // using a special version of the shader anyway. + a_.OpUBFE(alpha_test_mask_dest, dxbc::Src::LU(3), dxbc::Src::LU(kSysFlag_AlphaPassIfLess_Shift), + LoadFlagsSystemConstant()); + // Compare the mask to ALWAYS to check if the test shouldn't be done (will + // pass even for NaNs, though the expected behavior in this case hasn't been + // checked, but let's assume this means "always", not "less, equal or + // greater". + // TODO(Triang3l): Check how alpha test works with NaN on Direct3D 9. + a_.OpINE(alpha_test_op_dest, alpha_test_mask_src, + dxbc::Src::LU(uint32_t(xenos::CompareFunction::kAlways))); + // Don't do the test if the mode is "always". + a_.OpIf(true, alpha_test_op_src); + { + // Do the test. + dxbc::Src alpha_src(dxbc::Src::R(system_temps_color_[0], dxbc::Src::kWWWW)); + dxbc::Src alpha_test_reference_src( + LoadSystemConstant(SystemConstants::Index::kAlphaTestReference, + offsetof(SystemConstants, alpha_test_reference), dxbc::Src::kXXXX)); + // Epsilon for fuzzy alpha checks (prevents flickering on NVIDIA GPUs). + dxbc::Src fuzzy_epsilon = dxbc::Src::LF(1e-3f); + // Handle "not equal" specially (specifically as "not equal" so it's true + // for NaN, not "less or greater" which is false for NaN). + a_.OpIEq(alpha_test_op_dest, alpha_test_mask_src, + dxbc::Src::LU(uint32_t(xenos::CompareFunction::kNotEqual))); + a_.OpIf(true, alpha_test_op_src); + { + if (REXCVAR_GET(use_fuzzy_alpha_epsilon)) { + a_.OpAdd(alpha_test_fuzzy_diff_dest, alpha_src, -alpha_test_reference_src); + // Check if distance to desired value is less than epsilon (false for + // NaN) and write the negated result. + a_.OpLT(alpha_test_mask_dest, alpha_test_fuzzy_diff_src.Abs(), fuzzy_epsilon); + a_.OpNot(alpha_test_mask_dest, alpha_test_mask_src); + } else { + a_.OpNE(alpha_test_mask_dest, alpha_src, alpha_test_reference_src); + } + } + a_.OpElse(); + { + if (REXCVAR_GET(use_fuzzy_alpha_epsilon)) { + // Less than. + a_.OpAdd(alpha_test_fuzzy_diff_dest, alpha_src, -fuzzy_epsilon); + a_.OpLT(alpha_test_op_dest, alpha_test_fuzzy_diff_src, alpha_test_reference_src); + a_.OpOr(alpha_test_op_dest, alpha_test_op_src, dxbc::Src::LU(~uint32_t(1 << 0))); + a_.OpAnd(alpha_test_mask_dest, alpha_test_mask_src, alpha_test_op_src); + // "Equals" to. + a_.OpAdd(alpha_test_fuzzy_diff_dest, alpha_src, -alpha_test_reference_src); + a_.OpLT(alpha_test_op_dest, alpha_test_fuzzy_diff_src.Abs(), fuzzy_epsilon); + a_.OpOr(alpha_test_op_dest, alpha_test_op_src, dxbc::Src::LU(~uint32_t(1 << 1))); + a_.OpAnd(alpha_test_mask_dest, alpha_test_mask_src, alpha_test_op_src); + // Greater than. + a_.OpAdd(alpha_test_fuzzy_diff_dest, alpha_src, fuzzy_epsilon); + a_.OpLT(alpha_test_op_dest, alpha_test_reference_src, alpha_test_fuzzy_diff_src); + a_.OpOr(alpha_test_op_dest, alpha_test_op_src, dxbc::Src::LU(~uint32_t(1 << 2))); + a_.OpAnd(alpha_test_mask_dest, alpha_test_mask_src, alpha_test_op_src); + } else { + // Less than. + a_.OpLT(alpha_test_op_dest, alpha_src, alpha_test_reference_src); + a_.OpOr(alpha_test_op_dest, alpha_test_op_src, dxbc::Src::LU(~uint32_t(1 << 0))); + a_.OpAnd(alpha_test_mask_dest, alpha_test_mask_src, alpha_test_op_src); + // Equals to. + a_.OpEq(alpha_test_op_dest, alpha_src, alpha_test_reference_src); + a_.OpOr(alpha_test_op_dest, alpha_test_op_src, dxbc::Src::LU(~uint32_t(1 << 1))); + a_.OpAnd(alpha_test_mask_dest, alpha_test_mask_src, alpha_test_op_src); + // Greater than. + a_.OpLT(alpha_test_op_dest, alpha_test_reference_src, alpha_src); + a_.OpOr(alpha_test_op_dest, alpha_test_op_src, dxbc::Src::LU(~uint32_t(1 << 2))); + a_.OpAnd(alpha_test_mask_dest, alpha_test_mask_src, alpha_test_op_src); + } + } + // Close the "not equal" check. + a_.OpEndIf(); + // Discard the pixel if it has failed the test. + if (edram_rov_used_) { + a_.OpRetC(false, alpha_test_mask_src); + } else { + a_.OpDiscard(false, alpha_test_mask_src); + } + } + // Close the "not always" check. + a_.OpEndIf(); + // Release alpha_test_temp. + PopSystemTemp(); + + // Discard samples with alpha to coverage. + CompletePixelShader_AlphaToMask(); + + if (edram_rov_used_) { + // Close the render target 0 written check. + a_.OpEndIf(); + } + } + + // Write the values to the render targets. Not applying the exponent bias yet + // because the original 0 to 1 alpha value is needed for alpha to coverage, + // which is done differently for ROV and RTV/DSV. + if (edram_rov_used_) { + CompletePixelShader_WriteToROV(); + } else { + CompletePixelShader_WriteToRTVs(); + CompletePixelShader_DSV_DepthTo24Bit(); + } +} + +void DxbcShaderTranslator::PreClampedFloat32To7e3(dxbc::Assembler& a, uint32_t f10_temp, + uint32_t f10_temp_component, uint32_t f32_temp, + uint32_t f32_temp_component, uint32_t temp_temp, + uint32_t temp_temp_component) { + assert_true(temp_temp != f10_temp || temp_temp_component != f10_temp_component); + assert_true(temp_temp != f32_temp || temp_temp_component != f32_temp_component); + // Source and destination may be the same. + dxbc::Dest f10_dest(dxbc::Dest::R(f10_temp, 1 << f10_temp_component)); + dxbc::Src f10_src(dxbc::Src::R(f10_temp).Select(f10_temp_component)); + dxbc::Src f32_src(dxbc::Src::R(f32_temp).Select(f32_temp_component)); + dxbc::Dest temp_dest(dxbc::Dest::R(temp_temp, 1 << temp_temp_component)); + dxbc::Src temp_src(dxbc::Src::R(temp_temp).Select(temp_temp_component)); + + // https://github.com/Microsoft/DirectXTex/blob/master/DirectXTex/DirectXTexConvert.cpp + // Assuming the color is already clamped to [0, 31.875]. + + // Check if the number is too small to be represented as normalized 7e3. + // temp = f32 < 2^-2 + a.OpULT(temp_dest, f32_src, dxbc::Src::LU(0x3E800000)); + // Handle denormalized numbers separately. + a.OpIf(true, temp_src); + { + // temp = f32 >> 23 + a.OpUShR(temp_dest, f32_src, dxbc::Src::LU(23)); + // temp = 125 - (f32 >> 23) + a.OpIAdd(temp_dest, dxbc::Src::LI(125), -temp_src); + // Don't allow the shift to overflow, since in DXBC the lower 5 bits of the + // shift amount are used. + // temp = min(125 - (f32 >> 23), 24) + a.OpUMin(temp_dest, temp_src, dxbc::Src::LU(24)); + // biased_f32 = (f32 & 0x7FFFFF) | 0x800000 + a.OpBFI(f10_dest, dxbc::Src::LU(9), dxbc::Src::LU(23), dxbc::Src::LU(1), f32_src); + // biased_f32 = ((f32 & 0x7FFFFF) | 0x800000) >> min(125 - (f32 >> 23), 24) + a.OpUShR(f10_dest, f10_src, temp_src); + } + // Not denormalized? + a.OpElse(); + { + // Bias the exponent. + // biased_f32 = f32 + (-124 << 23) + // (left shift of a negative value is undefined behavior) + a.OpIAdd(f10_dest, f32_src, dxbc::Src::LU(0xC2000000u)); + } + // Close the denormal check. + a.OpEndIf(); + // Build the 7e3 number. + // temp = (biased_f32 >> 16) & 1 + a.OpUBFE(temp_dest, dxbc::Src::LU(1), dxbc::Src::LU(16), f10_src); + // f10 = biased_f32 + 0x7FFF + a.OpIAdd(f10_dest, f10_src, dxbc::Src::LU(0x7FFF)); + // f10 = biased_f32 + 0x7FFF + ((biased_f32 >> 16) & 1) + a.OpIAdd(f10_dest, f10_src, temp_src); + // f24 = ((biased_f32 + 0x7FFF + ((biased_f32 >> 16) & 1)) >> 16) & 0x3FF + a.OpUBFE(f10_dest, dxbc::Src::LU(10), dxbc::Src::LU(16), f10_src); +} + +void DxbcShaderTranslator::UnclampedFloat32To7e3(dxbc::Assembler& a, uint32_t f10_temp, + uint32_t f10_temp_component, uint32_t f32_temp, + uint32_t f32_temp_component, uint32_t temp_temp, + uint32_t temp_temp_component) { + // Source and destination might be the same or different, just like in + // PreClampedFloat32To7e3 - clamp to the destination and use it as source. + a.OpMax(dxbc::Dest::R(f10_temp, 1 << f10_temp_component), + dxbc::Src::R(f32_temp).Select(f32_temp_component), dxbc::Src::LF(0.0f)); + a.OpMin(dxbc::Dest::R(f10_temp, 1 << f10_temp_component), + dxbc::Src::R(f10_temp).Select(f10_temp_component), dxbc::Src::LF(31.875f)); + PreClampedFloat32To7e3(a, f10_temp, f10_temp_component, f10_temp, f10_temp_component, temp_temp, + temp_temp_component); +} + +void DxbcShaderTranslator::Float7e3To32(dxbc::Assembler& a, const dxbc::Dest& f32, + uint32_t f10_temp, uint32_t f10_temp_component, + uint32_t f10_shift, uint32_t temp1_temp, + uint32_t temp1_temp_component, uint32_t temp2_temp, + uint32_t temp2_temp_component) { + assert_true(f10_shift <= (32 - 10)); + assert_true(temp1_temp != temp2_temp || temp1_temp_component != temp2_temp_component); + // Source may be the same as temp1 or temp2. + dxbc::Dest exponent_dest(dxbc::Dest::R(temp1_temp, 1 << temp1_temp_component)); + dxbc::Src exponent_src(dxbc::Src::R(temp1_temp).Select(temp1_temp_component)); + dxbc::Dest mantissa_dest(dxbc::Dest::R(temp2_temp, 1 << temp2_temp_component)); + dxbc::Src mantissa_src(dxbc::Src::R(temp2_temp).Select(temp2_temp_component)); + + // https://github.com/Microsoft/DirectXTex/blob/master/DirectXTex/DirectXTexConvert.cpp + + if (!(f10_temp == temp1_temp && f10_temp_component == temp1_temp_component)) { + // Unpack the exponent before the mantissa if that doesn't overwrite the + // source. + a.OpUBFE(exponent_dest, dxbc::Src::LU(3), dxbc::Src::LU(f10_shift + 7), + dxbc::Src::R(f10_temp).Select(f10_temp_component)); + } + // Unpack the mantissa. + a.OpUBFE(mantissa_dest, dxbc::Src::LU(7), dxbc::Src::LU(f10_shift), + dxbc::Src::R(f10_temp).Select(f10_temp_component)); + if (f10_temp == temp1_temp && f10_temp_component == temp1_temp_component) { + // Unpack the exponent after the mantissa if doing that before the mantissa + // would overwrite the source. + a.OpUBFE(exponent_dest, dxbc::Src::LU(3), dxbc::Src::LU(f10_shift + 7), + dxbc::Src::R(f10_temp).Select(f10_temp_component)); + } + // Check if the number is denormalized. + a.OpIf(false, exponent_src); + { + // Check if the number is non-zero (if the mantissa isn't zero - the + // exponent is known to be zero at this point). + a.OpIf(true, mantissa_src); + { + // Normalize the mantissa. + // Note that HLSL firstbithigh(x) is compiled to DXBC like: + // `x ? 31 - firstbit_hi(x) : -1` + // (returns the index from the LSB, not the MSB, but -1 for zero too). + // exponent = firstbit_hi(mantissa) + a.OpFirstBitHi(exponent_dest, mantissa_src); + // exponent = 7 - firstbithigh(mantissa) + // Or: + // exponent = 7 - (31 - firstbit_hi(mantissa)) + a.OpIAdd(exponent_dest, exponent_src, dxbc::Src::LI(7 - 31)); + // mantissa = mantissa << (7 - firstbithigh(mantissa)) + // AND 0x7F not needed after this - BFI will do it. + a.OpIShL(mantissa_dest, mantissa_src, exponent_src); + // Get the normalized exponent. + // exponent = 1 - (7 - firstbithigh(mantissa)) + a.OpIAdd(exponent_dest, dxbc::Src::LI(1), -exponent_src); + } + // The number is zero. + a.OpElse(); + { + // Set the unbiased exponent to -124 for zero - 124 will be added later, + // resulting in zero float32. + a.OpMov(exponent_dest, dxbc::Src::LI(-124)); + } + // Close the non-zero check. + a.OpEndIf(); + } + // Close the denormal check. + a.OpEndIf(); + // Bias the exponent and move it to the correct location in f32. + a.OpIMAd(exponent_dest, exponent_src, dxbc::Src::LI(1 << 23), dxbc::Src::LI(124 << 23)); + // Combine the mantissa and the exponent. + a.OpBFI(f32, dxbc::Src::LU(7), dxbc::Src::LU(23 - 7), mantissa_src, exponent_src); +} + +void DxbcShaderTranslator::PreClampedDepthTo20e4(dxbc::Assembler& a, uint32_t f24_temp, + uint32_t f24_temp_component, uint32_t f32_temp, + uint32_t f32_temp_component, uint32_t temp_temp, + uint32_t temp_temp_component, + bool round_to_nearest_even, + bool remap_from_0_to_0_5) { + assert_true(temp_temp != f24_temp || temp_temp_component != f24_temp_component); + assert_true(temp_temp != f32_temp || temp_temp_component != f32_temp_component); + // Source and destination may be the same. + dxbc::Dest f24_dest(dxbc::Dest::R(f24_temp, 1 << f24_temp_component)); + dxbc::Src f24_src(dxbc::Src::R(f24_temp).Select(f24_temp_component)); + dxbc::Src f32_src(dxbc::Src::R(f32_temp).Select(f32_temp_component)); + dxbc::Dest temp_dest(dxbc::Dest::R(temp_temp, 1 << temp_temp_component)); + dxbc::Src temp_src(dxbc::Src::R(temp_temp).Select(temp_temp_component)); + + // CFloat24 from d3dref9.dll + + // https://github.com/Microsoft/DirectXTex/blob/master/DirectXTex/DirectXTexConvert.cpp + // Assuming the depth is already clamped to [0, 2) (in all places, the depth + // is written with the saturate flag set). + + uint32_t remap_bias = uint32_t(remap_from_0_to_0_5); + + // Check if the number is too small to be represented as normalized 20e4. + // temp = f32 < 2^-14 + a.OpULT(temp_dest, f32_src, dxbc::Src::LU(0x38800000 - (remap_bias << 23))); + // Handle denormalized numbers separately. + a.OpIf(true, temp_src); + { + // temp = f32 >> 23 + a.OpUShR(temp_dest, f32_src, dxbc::Src::LU(23)); + // temp = 113 - (f32 >> 23) + a.OpIAdd(temp_dest, dxbc::Src::LI(113 - remap_bias), -temp_src); + // Don't allow the shift to overflow, since in DXBC the lower 5 bits of the + // shift amount are used (otherwise 0 becomes 8). + // temp = min(113 - (f32 >> 23), 24) + a.OpUMin(temp_dest, temp_src, dxbc::Src::LU(24)); + // biased_f32 = (f32 & 0x7FFFFF) | 0x800000 + a.OpBFI(f24_dest, dxbc::Src::LU(9), dxbc::Src::LU(23), dxbc::Src::LU(1), f32_src); + // biased_f32 = ((f32 & 0x7FFFFF) | 0x800000) >> min(113 - (f32 >> 23), 24) + a.OpUShR(f24_dest, f24_src, temp_src); + } + // Not denormalized? + a.OpElse(); + { + // Bias the exponent. + // biased_f32 = f32 + (-112 << 23) + // (left shift of a negative value is undefined behavior) + a.OpIAdd(f24_dest, f32_src, dxbc::Src::LU(0xC8000000u + (remap_bias << 23))); + } + // Close the denormal check. + a.OpEndIf(); + // Build the 20e4 number. + if (round_to_nearest_even) { + // temp = (biased_f32 >> 3) & 1 + a.OpUBFE(temp_dest, dxbc::Src::LU(1), dxbc::Src::LU(3), f24_src); + // f24 = biased_f32 + 3 + a.OpIAdd(f24_dest, f24_src, dxbc::Src::LU(3)); + // f24 = biased_f32 + 3 + ((biased_f32 >> 3) & 1) + a.OpIAdd(f24_dest, f24_src, temp_src); + } + // For rounding to the nearest even: + // f24 = ((biased_f32 + 3 + ((biased_f32 >> 3) & 1)) >> 3) & 0xFFFFFF + // For rounding towards zero: + // f24 = (biased_f32 >> 3) & 0xFFFFFF + a.OpUBFE(f24_dest, dxbc::Src::LU(24), dxbc::Src::LU(3), f24_src); +} + +void DxbcShaderTranslator::Depth20e4To32(dxbc::Assembler& a, const dxbc::Dest& f32, + uint32_t f24_temp, uint32_t f24_temp_component, + uint32_t f24_shift, uint32_t temp1_temp, + uint32_t temp1_temp_component, uint32_t temp2_temp, + uint32_t temp2_temp_component, bool remap_to_0_to_0_5) { + assert_true(f24_shift <= (32 - 24)); + assert_true(temp1_temp != temp2_temp || temp1_temp_component != temp2_temp_component); + // Source may be the same as temp1 or temp2. + dxbc::Dest exponent_dest(dxbc::Dest::R(temp1_temp, 1 << temp1_temp_component)); + dxbc::Src exponent_src(dxbc::Src::R(temp1_temp).Select(temp1_temp_component)); + dxbc::Dest mantissa_dest(dxbc::Dest::R(temp2_temp, 1 << temp2_temp_component)); + dxbc::Src mantissa_src(dxbc::Src::R(temp2_temp).Select(temp2_temp_component)); + + // CFloat24 from d3dref9.dll + + // https://github.com/Microsoft/DirectXTex/blob/master/DirectXTex/DirectXTexConvert.cpp + + uint32_t remap_bias = uint32_t(remap_to_0_to_0_5); + + if (!(f24_temp == temp1_temp && f24_temp_component == temp1_temp_component)) { + // Unpack the exponent before the mantissa if that doesn't overwrite the + // source. + a.OpUBFE(exponent_dest, dxbc::Src::LU(4), dxbc::Src::LU(f24_shift + 20), + dxbc::Src::R(f24_temp).Select(f24_temp_component)); + } + // Unpack the mantissa. + a.OpUBFE(mantissa_dest, dxbc::Src::LU(20), dxbc::Src::LU(f24_shift), + dxbc::Src::R(f24_temp).Select(f24_temp_component)); + if (f24_temp == temp1_temp && f24_temp_component == temp1_temp_component) { + // Unpack the exponent after the mantissa if doing that before the mantissa + // would overwrite the source. + a.OpUBFE(exponent_dest, dxbc::Src::LU(4), dxbc::Src::LU(f24_shift + 20), + dxbc::Src::R(f24_temp).Select(f24_temp_component)); + } + // Check if the number is denormalized. + a.OpIf(false, exponent_src); + { + // Check if the number is non-zero (if the mantissa isn't zero - the + // exponent is known to be zero at this point). + a.OpIf(true, mantissa_src); + { + // Normalize the mantissa. + // Note that HLSL firstbithigh(x) is compiled to DXBC like: + // `x ? 31 - firstbit_hi(x) : -1` + // (returns the index from the LSB, not the MSB, but -1 for zero too). + // exponent = firstbit_hi(mantissa) + a.OpFirstBitHi(exponent_dest, mantissa_src); + // exponent = 20 - firstbithigh(mantissa) + // Or: + // exponent = 20 - (31 - firstbit_hi(mantissa)) + a.OpIAdd(exponent_dest, exponent_src, dxbc::Src::LI(20 - 31)); + // mantissa = mantissa << (20 - firstbithigh(mantissa)) + // AND 0xFFFFF not needed after this - BFI will do it. + a.OpIShL(mantissa_dest, mantissa_src, exponent_src); + // Get the normalized exponent. + // exponent = 1 - (20 - firstbithigh(mantissa)) + a.OpIAdd(exponent_dest, dxbc::Src::LI(1), -exponent_src); + } + // The number is zero. + a.OpElse(); + { + // Set the unbiased exponent to -112 for zero - 112 will be added later + // (taking the range remap bias into account), resulting in zero float32. + a.OpMov(exponent_dest, dxbc::Src::LI(-int32_t(112 - remap_bias))); + } + // Close the non-zero check. + a.OpEndIf(); + } + // Close the denormal check. + a.OpEndIf(); + // Bias the exponent and move it to the correct location in f32, and also + // remap from guest 0...1 to host 0...0.5 if needed. + a.OpIMAd(exponent_dest, exponent_src, dxbc::Src::LI(1 << 23), + dxbc::Src::LI((112 - remap_bias) << 23)); + // Combine the mantissa and the exponent. + a.OpBFI(f32, dxbc::Src::LU(20), dxbc::Src::LU(23 - 20), mantissa_src, exponent_src); +} + +void DxbcShaderTranslator::ROV_DepthTo24Bit(uint32_t d24_temp, uint32_t d24_temp_component, + uint32_t d32_temp, uint32_t d32_temp_component, + uint32_t temp_temp, uint32_t temp_temp_component) { + assert_true(temp_temp != d32_temp || temp_temp_component != d32_temp_component); + // Source and destination may be the same. + + a_.OpAnd(dxbc::Dest::R(temp_temp, 1 << temp_temp_component), LoadFlagsSystemConstant(), + dxbc::Src::LU(kSysFlag_DepthFloat24)); + // Convert according to the format. + a_.OpIf(true, dxbc::Src::R(temp_temp).Select(temp_temp_component)); + { + // 20e4 conversion. + PreClampedDepthTo20e4(a_, d24_temp, d24_temp_component, d32_temp, d32_temp_component, temp_temp, + temp_temp_component, true, false); + } + a_.OpElse(); + { + // Unorm24 conversion. + dxbc::Dest d24_dest(dxbc::Dest::R(d24_temp, 1 << d24_temp_component)); + dxbc::Src d24_src(dxbc::Src::R(d24_temp).Select(d24_temp_component)); + a_.OpMul(d24_dest, dxbc::Src::R(d32_temp).Select(d32_temp_component), + dxbc::Src::LF(float(0xFFFFFF))); + // Round to the nearest even integer. This seems to be the correct way: + // rounding towards zero gives 0xFF instead of 0x100 in clear shaders in, + // for instance, 4D5307E6, but other clear shaders in it are also broken if + // 0.5 is added before ftou instead of round_ne. + a_.OpRoundNE(d24_dest, d24_src); + // Convert to fixed-point. + a_.OpFToU(d24_dest, d24_src); + } + a_.OpEndIf(); +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/shader/interpreter.cpp b/src/graphics/pipeline/shader/interpreter.cpp new file mode 100644 index 0000000..157e5a2 --- /dev/null +++ b/src/graphics/pipeline/shader/interpreter.cpp @@ -0,0 +1,1139 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace rex::graphics { + +void ShaderInterpreter::Execute() { + // For more consistency between invocations in case of a malformed shader. + state_.Reset(); + + const uint32_t* bool_constants = ®ister_file_[XE_GPU_REG_SHADER_CONSTANT_BOOL_000_031]; + + bool exec_ended = false; + uint32_t cf_index_next = 1; + for (uint32_t cf_index = 0; !exec_ended; cf_index = cf_index_next) { + cf_index_next = cf_index + 1; + + const uint32_t* cf_pair = &ucode_[3 * (cf_index >> 1)]; + ucode::ControlFlowInstruction cf_instr; + if (cf_index & 1) { + cf_instr.dword_0 = (cf_pair[1] >> 16) | (cf_pair[2] << 16); + cf_instr.dword_1 = cf_pair[2] >> 16; + } else { + cf_instr.dword_0 = cf_pair[0]; + cf_instr.dword_1 = cf_pair[1] & 0xFFFF; + } + + ucode::ControlFlowOpcode cf_opcode = cf_instr.opcode(); + switch (cf_opcode) { + case ucode::ControlFlowOpcode::kNop: { + } break; + + case ucode::ControlFlowOpcode::kExec: + case ucode::ControlFlowOpcode::kExecEnd: + case ucode::ControlFlowOpcode::kCondExec: + case ucode::ControlFlowOpcode::kCondExecEnd: + case ucode::ControlFlowOpcode::kCondExecPred: + case ucode::ControlFlowOpcode::kCondExecPredEnd: + case ucode::ControlFlowOpcode::kCondExecPredClean: + case ucode::ControlFlowOpcode::kCondExecPredCleanEnd: { + ucode::ControlFlowExecInstruction cf_exec = + *reinterpret_cast(&cf_instr); + + switch (cf_opcode) { + case ucode::ControlFlowOpcode::kCondExec: + case ucode::ControlFlowOpcode::kCondExecEnd: + case ucode::ControlFlowOpcode::kCondExecPredClean: + case ucode::ControlFlowOpcode::kCondExecPredCleanEnd: { + const ucode::ControlFlowCondExecInstruction cf_cond_exec = + *reinterpret_cast(&cf_exec); + uint32_t bool_address = cf_cond_exec.bool_address(); + if (cf_cond_exec.condition() != + ((bool_constants[bool_address >> 5] & (UINT32_C(1) << (bool_address & 31))) != 0)) { + continue; + } + } break; + case ucode::ControlFlowOpcode::kCondExecPred: + case ucode::ControlFlowOpcode::kCondExecPredEnd: { + const ucode::ControlFlowCondExecPredInstruction cf_cond_exec_pred = + *reinterpret_cast(&cf_exec); + if (cf_cond_exec_pred.condition() != state_.predicate) { + continue; + } + } break; + default: + break; + } + + for (uint32_t exec_index = 0; exec_index < cf_exec.count(); ++exec_index) { + const uint32_t* exec_instruction = &ucode_[3 * (cf_exec.address() + exec_index)]; + if ((cf_exec.sequence() >> (exec_index << 1)) & 0b01) { + const ucode::FetchInstruction& fetch_instr = + *reinterpret_cast(exec_instruction); + if (fetch_instr.is_predicated() && + fetch_instr.predicate_condition() != state_.predicate) { + continue; + } + if (fetch_instr.opcode() == ucode::FetchOpcode::kVertexFetch) { + ExecuteVertexFetchInstruction(fetch_instr.vertex_fetch()); + } else { + // Not supporting texture fetching (very complex). + float zero_result[4] = {}; + StoreFetchResult(fetch_instr.dest(), fetch_instr.is_dest_relative(), + fetch_instr.dest_swizzle(), zero_result); + } + } else { + const ucode::AluInstruction& alu_instr = + *reinterpret_cast(exec_instruction); + if (alu_instr.is_predicated() && alu_instr.predicate_condition() != state_.predicate) { + continue; + } + ExecuteAluInstruction(alu_instr); + } + } + + if (ucode::DoesControlFlowOpcodeEndShader(cf_opcode)) { + exec_ended = true; + } + } break; + + case ucode::ControlFlowOpcode::kLoopStart: { + ucode::ControlFlowLoopStartInstruction cf_loop_start = + *reinterpret_cast(&cf_instr); + assert_true(state_.loop_stack_depth < 4); + if (++state_.loop_stack_depth > 4) { + cf_index_next = cf_loop_start.address(); + continue; + } + auto loop_constant = register_file_.Get( + XE_GPU_REG_SHADER_CONSTANT_LOOP_00 + cf_loop_start.loop_id()); + state_.loop_constants[state_.loop_stack_depth] = loop_constant; + uint32_t& loop_iterator_ref = state_.loop_iterators[state_.loop_stack_depth]; + if (!cf_loop_start.is_repeat()) { + loop_iterator_ref = 0; + } + if (loop_iterator_ref >= loop_constant.count) { + cf_index_next = cf_loop_start.address(); + continue; + } + ++state_.loop_stack_depth; + } break; + + case ucode::ControlFlowOpcode::kLoopEnd: { + assert_not_zero(state_.loop_stack_depth); + if (!state_.loop_stack_depth) { + continue; + } + assert_true(state_.loop_stack_depth <= 4); + if (state_.loop_stack_depth > 4) { + --state_.loop_stack_depth; + continue; + } + ucode::ControlFlowLoopEndInstruction cf_loop_end = + *reinterpret_cast(&cf_instr); + xenos::LoopConstant loop_constant = state_.loop_constants[state_.loop_stack_depth - 1]; + assert_zero( + std::memcmp(&loop_constant, + ®ister_file_[XE_GPU_REG_SHADER_CONSTANT_LOOP_00 + cf_loop_end.loop_id()], + sizeof(loop_constant))); + uint32_t loop_iterator = ++state_.loop_iterators[state_.loop_stack_depth - 1]; + if (loop_iterator < loop_constant.count && + (!cf_loop_end.is_predicated_break() || cf_loop_end.condition() != state_.predicate)) { + cf_index_next = cf_loop_end.address(); + continue; + } + --state_.loop_stack_depth; + } break; + + case ucode::ControlFlowOpcode::kCondCall: { + assert_true(state_.call_stack_depth < 4); + if (state_.call_stack_depth >= 4) { + continue; + } + const ucode::ControlFlowCondCallInstruction cf_cond_call = + *reinterpret_cast(&cf_instr); + if (!cf_cond_call.is_unconditional()) { + if (cf_cond_call.is_predicated()) { + if (cf_cond_call.condition() != state_.predicate) { + continue; + } + } else { + uint32_t bool_address = cf_cond_call.bool_address(); + if (cf_cond_call.condition() != + ((bool_constants[bool_address >> 5] & (UINT32_C(1) << (bool_address & 31))) != 0)) { + continue; + } + } + } + state_.call_return_addresses[state_.call_stack_depth++] = cf_index + 1; + cf_index_next = cf_cond_call.address(); + } break; + + case ucode::ControlFlowOpcode::kReturn: { + // No stack depth assertion - skipping the return is a well-defined + // behavior for `return` outside a function call. + if (!state_.call_stack_depth) { + continue; + } + cf_index_next = state_.call_return_addresses[--state_.call_stack_depth]; + } break; + + case ucode::ControlFlowOpcode::kCondJmp: { + const ucode::ControlFlowCondJmpInstruction cf_cond_jmp = + *reinterpret_cast(&cf_instr); + if (!cf_cond_jmp.is_unconditional()) { + if (cf_cond_jmp.is_predicated()) { + if (cf_cond_jmp.condition() != state_.predicate) { + continue; + } + } else { + uint32_t bool_address = cf_cond_jmp.bool_address(); + if (cf_cond_jmp.condition() != + ((bool_constants[bool_address >> 5] & (UINT32_C(1) << (bool_address & 31))) != 0)) { + continue; + } + } + } + cf_index_next = cf_cond_jmp.address(); + } break; + + case ucode::ControlFlowOpcode::kAlloc: { + if (export_sink_) { + const ucode::ControlFlowAllocInstruction& cf_alloc = + *reinterpret_cast(&cf_instr); + export_sink_->AllocExport(cf_alloc.alloc_type(), cf_alloc.size()); + } + } break; + + case ucode::ControlFlowOpcode::kMarkVsFetchDone: { + } break; + + default: + assert_unhandled_case(cf_opcode); + } + } +} + +const std::array ShaderInterpreter::GetFloatConstant(uint32_t address, bool is_relative, + bool relative_address_is_a0) const { + int32_t index = int32_t(address); + if (is_relative) { + index += relative_address_is_a0 ? state_.address_register : state_.GetLoopAddress(); + } + if (index < 0) { + return std::array(); + } + auto base_and_size_minus_1 = register_file_.Get( + shader_type_ == xenos::ShaderType::kVertex ? XE_GPU_REG_SQ_VS_CONST : XE_GPU_REG_SQ_PS_CONST); + if (uint32_t(index) > base_and_size_minus_1.size) { + return std::array(); + } + index += base_and_size_minus_1.base; + if (index >= 512) { + return std::array(); + } + std::array value; + std::memcpy(value.data(), ®ister_file_[XE_GPU_REG_SHADER_CONSTANT_000_X + 4 * index], + sizeof(float) * 4); + return value; +} + +void ShaderInterpreter::ExecuteAluInstruction(ucode::AluInstruction instr) { + // Vector operation. + float vector_result[4] = {}; + ucode::AluVectorOpcode vector_opcode = instr.vector_opcode(); + const ucode::AluVectorOpcodeInfo& vector_opcode_info = + ucode::GetAluVectorOpcodeInfo(vector_opcode); + uint32_t vector_result_write_mask = instr.GetVectorOpResultWriteMask(); + if (vector_result_write_mask || vector_opcode_info.changed_state) { + float vector_operands[3][4]; + for (uint32_t i = 0; i < 3; ++i) { + if (!vector_opcode_info.operand_components_used[i]) { + continue; + } + const float* vector_src_ptr; + uint32_t vector_src_register = instr.src_reg(1 + i); + bool vector_src_absolute = false; + std::array vector_src_float_constant; + if (instr.src_is_temp(1 + i)) { + vector_src_ptr = + GetTempRegister(ucode::AluInstruction::src_temp_reg(vector_src_register), + ucode::AluInstruction::is_src_temp_relative(vector_src_register)); + vector_src_absolute = + ucode::AluInstruction::is_src_temp_value_absolute(vector_src_register); + } else { + vector_src_float_constant = + GetFloatConstant(vector_src_register, instr.src_const_is_addressed(1 + i), + instr.is_const_address_register_relative()); + vector_src_ptr = vector_src_float_constant.data(); + } + uint32_t vector_src_absolute_mask = ~(uint32_t(vector_src_absolute) << 31); + uint32_t vector_src_negate_bit = uint32_t(instr.src_negate(1 + i)) << 31; + uint32_t vector_src_swizzle = instr.src_swizzle(1 + i); + for (uint32_t j = 0; j < 4; ++j) { + float vector_src_component = + FlushDenormal(vector_src_ptr[ucode::AluInstruction::GetSwizzledComponentIndex( + vector_src_swizzle, j)]); + *reinterpret_cast(&vector_src_component) = + (*reinterpret_cast(&vector_src_component) & vector_src_absolute_mask) ^ + vector_src_negate_bit; + vector_operands[i][j] = vector_src_component; + } + } + + bool replicate_vector_result_x = false; + switch (vector_opcode) { + case ucode::AluVectorOpcode::kAdd: { + for (uint32_t i = 0; i < 4; ++i) { + vector_result[i] = vector_operands[0][i] + vector_operands[1][i]; + } + } break; + case ucode::AluVectorOpcode::kMul: { + for (uint32_t i = 0; i < 4; ++i) { + // Direct3D 9 behavior (0 or denormal * anything = +0). + vector_result[i] = (vector_operands[0][i] && vector_operands[1][i]) + ? vector_operands[0][i] * vector_operands[1][i] + : 0.0f; + } + } break; + case ucode::AluVectorOpcode::kMax: { + for (uint32_t i = 0; i < 4; ++i) { + vector_result[i] = std::isgreaterequal(vector_operands[0][i], vector_operands[1][i]) + ? vector_operands[0][i] + : vector_operands[1][i]; + } + } break; + case ucode::AluVectorOpcode::kMin: { + for (uint32_t i = 0; i < 4; ++i) { + vector_result[i] = std::isless(vector_operands[0][i], vector_operands[1][i]) + ? vector_operands[0][i] + : vector_operands[1][i]; + } + } break; + case ucode::AluVectorOpcode::kSeq: { + for (uint32_t i = 0; i < 4; ++i) { + vector_result[i] = float(vector_operands[0][i] == vector_operands[1][i]); + } + } break; + case ucode::AluVectorOpcode::kSgt: { + for (uint32_t i = 0; i < 4; ++i) { + vector_result[i] = float(std::isgreater(vector_operands[0][i], vector_operands[1][i])); + } + } break; + case ucode::AluVectorOpcode::kSge: { + for (uint32_t i = 0; i < 4; ++i) { + vector_result[i] = + float(std::isgreaterequal(vector_operands[0][i], vector_operands[1][i])); + } + } break; + case ucode::AluVectorOpcode::kSne: { + for (uint32_t i = 0; i < 4; ++i) { + vector_result[i] = float(vector_operands[0][i] != vector_operands[1][i]); + } + } break; + case ucode::AluVectorOpcode::kFrc: { + for (uint32_t i = 0; i < 4; ++i) { + vector_result[i] = vector_operands[0][i] - std::floor(vector_operands[0][i]); + } + } break; + case ucode::AluVectorOpcode::kTrunc: { + for (uint32_t i = 0; i < 4; ++i) { + vector_result[i] = std::trunc(vector_operands[0][i]); + } + } break; + case ucode::AluVectorOpcode::kFloor: { + for (uint32_t i = 0; i < 4; ++i) { + vector_result[i] = std::floor(vector_operands[0][i]); + } + } break; + case ucode::AluVectorOpcode::kMad: { + for (uint32_t i = 0; i < 4; ++i) { + // Direct3D 9 behavior (0 or denormal * anything = +0). + // Doing the addition rather than conditional assignment even for zero + // operands because +0 + -0 must be +0. + vector_result[i] = ((vector_operands[0][i] && vector_operands[1][i]) + ? vector_operands[0][i] * vector_operands[1][i] + : 0.0f) + + vector_operands[2][i]; + } + } break; + case ucode::AluVectorOpcode::kCndEq: { + for (uint32_t i = 0; i < 4; ++i) { + vector_result[i] = + vector_operands[0][i] == 0.0f ? vector_operands[1][i] : vector_operands[2][i]; + } + } break; + case ucode::AluVectorOpcode::kCndGe: { + for (uint32_t i = 0; i < 4; ++i) { + vector_result[i] = std::isgreaterequal(vector_operands[0][i], 0.0f) + ? vector_operands[1][i] + : vector_operands[2][i]; + } + } break; + case ucode::AluVectorOpcode::kCndGt: { + for (uint32_t i = 0; i < 4; ++i) { + vector_result[i] = std::isgreater(vector_operands[0][i], 0.0f) ? vector_operands[1][i] + : vector_operands[2][i]; + } + } break; + case ucode::AluVectorOpcode::kDp4: { + vector_result[0] = 0.0f; + for (uint32_t i = 0; i < 4; ++i) { + // Direct3D 9 behavior (0 or denormal * anything = +0). + // Doing the addition even for zero operands because +0 + -0 must be + // +0. + vector_result[0] += (vector_operands[0][i] && vector_operands[1][i]) + ? vector_operands[0][i] * vector_operands[1][i] + : 0.0f; + } + replicate_vector_result_x = true; + } break; + case ucode::AluVectorOpcode::kDp3: { + vector_result[0] = 0.0f; + for (uint32_t i = 0; i < 3; ++i) { + // Direct3D 9 behavior (0 or denormal * anything = +0). + // Doing the addition even for zero operands because +0 + -0 must be + // +0. + vector_result[0] += (vector_operands[0][i] && vector_operands[1][i]) + ? vector_operands[0][i] * vector_operands[1][i] + : 0.0f; + } + replicate_vector_result_x = true; + } break; + case ucode::AluVectorOpcode::kDp2Add: { + // Doing the addition even for zero operands because +0 + -0 must be +0. + vector_result[0] = 0.0f; + for (uint32_t i = 0; i < 2; ++i) { + // Direct3D 9 behavior (0 or denormal * anything = +0). + vector_result[0] += (vector_operands[0][i] && vector_operands[1][i]) + ? vector_operands[0][i] * vector_operands[1][i] + : 0.0f; + } + vector_result[0] += vector_operands[2][0]; + replicate_vector_result_x = true; + } break; + case ucode::AluVectorOpcode::kCube: { + // Operand [0] is .z_xy. + float x = vector_operands[0][2]; + float y = vector_operands[0][3]; + float z = vector_operands[0][0]; + float x_abs = std::abs(x), y_abs = std::abs(y), z_abs = std::abs(z); + // Result is T coordinate, S coordinate, 2 * major axis, face ID. + if (z_abs >= x_abs && z_abs >= y_abs) { + bool z_negative = std::isless(z, 0.0f); + vector_result[0] = -y; + vector_result[1] = z_negative ? -x : x; + vector_result[2] = z; + vector_result[3] = z_negative ? 5.0f : 4.0f; + } else if (y_abs >= x_abs) { + bool y_negative = std::isless(y, 0.0f); + vector_result[0] = y_negative ? -z : z; + vector_result[1] = x; + vector_result[2] = y; + vector_result[3] = y_negative ? 3.0f : 2.0f; + } else { + bool x_negative = std::isless(x, 0.0f); + vector_result[0] = -y; + vector_result[1] = x_negative ? z : -z; + vector_result[2] = x; + vector_result[3] = x_negative ? 1.0f : 0.0f; + } + vector_result[2] *= 2.0f; + } break; + case ucode::AluVectorOpcode::kMax4: { + if (std::isgreaterequal(vector_operands[0][0], vector_operands[0][1]) && + std::isgreaterequal(vector_operands[0][0], vector_operands[0][2]) && + std::isgreaterequal(vector_operands[0][0], vector_operands[0][3])) { + vector_result[0] = vector_operands[0][0]; + } else if (std::isgreaterequal(vector_operands[0][1], vector_operands[0][2]) && + std::isgreaterequal(vector_operands[0][1], vector_operands[0][3])) { + vector_result[0] = vector_operands[0][1]; + } else if (std::isgreaterequal(vector_operands[0][2], vector_operands[0][3])) { + vector_result[0] = vector_operands[0][2]; + } else { + vector_result[0] = vector_operands[0][3]; + } + replicate_vector_result_x = true; + } break; + case ucode::AluVectorOpcode::kSetpEqPush: { + state_.predicate = vector_operands[0][3] == 0.0f && vector_operands[1][3] == 0.0f; + vector_result[0] = (vector_operands[0][0] == 0.0f && vector_operands[1][0] == 0.0f) + ? 0.0f + : vector_operands[0][0] + 1.0f; + replicate_vector_result_x = true; + } break; + case ucode::AluVectorOpcode::kSetpNePush: { + state_.predicate = vector_operands[0][3] == 0.0f && vector_operands[1][3] != 0.0f; + vector_result[0] = (vector_operands[0][0] == 0.0f && vector_operands[1][0] != 0.0f) + ? 0.0f + : vector_operands[0][0] + 1.0f; + replicate_vector_result_x = true; + } break; + case ucode::AluVectorOpcode::kSetpGtPush: { + state_.predicate = + vector_operands[0][3] == 0.0f && std::isgreater(vector_operands[1][3], 0.0f); + vector_result[0] = + (vector_operands[0][0] == 0.0f && std::isgreater(vector_operands[1][0], 0.0f)) + ? 0.0f + : vector_operands[0][0] + 1.0f; + replicate_vector_result_x = true; + } break; + case ucode::AluVectorOpcode::kSetpGePush: { + state_.predicate = + vector_operands[0][3] == 0.0f && std::isgreaterequal(vector_operands[1][3], 0.0f); + vector_result[0] = + (vector_operands[0][0] == 0.0f && std::isgreaterequal(vector_operands[1][0], 0.0f)) + ? 0.0f + : vector_operands[0][0] + 1.0f; + replicate_vector_result_x = true; + } break; + // Not implementing pixel kill currently, the interpreter is currently + // used only for vertex shaders. + case ucode::AluVectorOpcode::kKillEq: { + vector_result[0] = float(vector_operands[0][0] == vector_operands[1][0] || + vector_operands[0][1] == vector_operands[1][1] || + vector_operands[0][2] == vector_operands[1][2] || + vector_operands[0][3] == vector_operands[1][3]); + replicate_vector_result_x = true; + } break; + case ucode::AluVectorOpcode::kKillGt: { + vector_result[0] = float(std::isgreater(vector_operands[0][0], vector_operands[1][0]) || + std::isgreater(vector_operands[0][1], vector_operands[1][1]) || + std::isgreater(vector_operands[0][2], vector_operands[1][2]) || + std::isgreater(vector_operands[0][3], vector_operands[1][3])); + replicate_vector_result_x = true; + } break; + case ucode::AluVectorOpcode::kKillGe: { + vector_result[0] = + float(std::isgreaterequal(vector_operands[0][0], vector_operands[1][0]) || + std::isgreaterequal(vector_operands[0][1], vector_operands[1][1]) || + std::isgreaterequal(vector_operands[0][2], vector_operands[1][2]) || + std::isgreaterequal(vector_operands[0][3], vector_operands[1][3])); + replicate_vector_result_x = true; + } break; + case ucode::AluVectorOpcode::kKillNe: { + vector_result[0] = float(vector_operands[0][0] != vector_operands[1][0] || + vector_operands[0][1] != vector_operands[1][1] || + vector_operands[0][2] != vector_operands[1][2] || + vector_operands[0][3] != vector_operands[1][3]); + replicate_vector_result_x = true; + } break; + case ucode::AluVectorOpcode::kDst: { + vector_result[0] = 1.0f; + // Direct3D 9 behavior (0 or denormal * anything = +0). + vector_result[1] = (vector_operands[0][1] && vector_operands[1][1]) + ? vector_operands[0][1] * vector_operands[1][1] + : 0.0f; + vector_result[2] = vector_operands[0][2]; + vector_result[3] = vector_operands[1][3]; + } break; + case ucode::AluVectorOpcode::kMaxA: { + state_.address_register = + int32_t(std::floor(rex::clamp_float(vector_operands[0][3], -256.0f, 255.0f) + 0.5f)); + for (uint32_t i = 0; i < 4; ++i) { + vector_result[i] = std::isgreaterequal(vector_operands[0][i], vector_operands[1][i]) + ? vector_operands[0][i] + : vector_operands[1][i]; + } + } break; + default: { + assert_unhandled_case(vector_opcode); + } + } + if (replicate_vector_result_x) { + for (uint32_t i = 1; i < 4; ++i) { + vector_result[i] = vector_result[0]; + } + } + } + + // Scalar operation. + ucode::AluScalarOpcode scalar_opcode = instr.scalar_opcode(); + const ucode::AluScalarOpcodeInfo& scalar_opcode_info = + ucode::GetAluScalarOpcodeInfo(scalar_opcode); + float scalar_operands[2]; + uint32_t scalar_operand_component_count = 0; + bool scalar_src_absolute = false; + switch (scalar_opcode_info.operand_count) { + case 1: { + // r#/c#.w or r#/c#.wx. + const float* scalar_src_ptr; + uint32_t scalar_src_register = instr.src_reg(3); + std::array scalar_src_float_constant; + if (instr.src_is_temp(3)) { + scalar_src_ptr = + GetTempRegister(ucode::AluInstruction::src_temp_reg(scalar_src_register), + ucode::AluInstruction::is_src_temp_relative(scalar_src_register)); + scalar_src_absolute = + ucode::AluInstruction::is_src_temp_value_absolute(scalar_src_register); + } else { + scalar_src_float_constant = + GetFloatConstant(scalar_src_register, instr.src_const_is_addressed(3), + instr.is_const_address_register_relative()); + scalar_src_ptr = scalar_src_float_constant.data(); + } + uint32_t scalar_src_swizzle = instr.src_swizzle(3); + scalar_operand_component_count = scalar_opcode_info.single_operand_is_two_component ? 2 : 1; + for (uint32_t i = 0; i < scalar_operand_component_count; ++i) { + scalar_operands[i] = scalar_src_ptr[ucode::AluInstruction::GetSwizzledComponentIndex( + scalar_src_swizzle, (3 + i) & 3)]; + } + } break; + case 2: { + scalar_operand_component_count = 2; + uint32_t scalar_src_absolute_mask = ~(uint32_t(instr.abs_constants()) << 31); + uint32_t scalar_src_negate_bit = uint32_t(instr.src_negate(3)) << 31; + uint32_t scalar_src_swizzle = instr.src_swizzle(3); + // c#.w. + scalar_operands[0] = GetFloatConstant(instr.src_reg(3), instr.src_const_is_addressed(3), + instr.is_const_address_register_relative()) + [ucode::AluInstruction::GetSwizzledComponentIndex(scalar_src_swizzle, 3)]; + // r#.x. + scalar_operands[1] = GetTempRegister( + instr.scalar_const_reg_op_src_temp_reg(), + false)[ucode::AluInstruction::GetSwizzledComponentIndex(scalar_src_swizzle, 0)]; + } break; + } + if (scalar_operand_component_count) { + uint32_t scalar_src_absolute_mask = ~(uint32_t(scalar_src_absolute) << 31); + uint32_t scalar_src_negate_bit = uint32_t(instr.src_negate(3)) << 31; + for (uint32_t i = 0; i < scalar_operand_component_count; ++i) { + float scalar_operand = FlushDenormal(scalar_operands[i]); + *reinterpret_cast(&scalar_operand) = + (*reinterpret_cast(&scalar_operand) & scalar_src_absolute_mask) ^ + scalar_src_negate_bit; + scalar_operands[i] = scalar_operand; + } + } + switch (scalar_opcode) { + case ucode::AluScalarOpcode::kAdds: + case ucode::AluScalarOpcode::kAddsc0: + case ucode::AluScalarOpcode::kAddsc1: { + state_.previous_scalar = scalar_operands[0] + scalar_operands[1]; + } break; + case ucode::AluScalarOpcode::kAddsPrev: { + state_.previous_scalar = scalar_operands[0] + state_.previous_scalar; + } break; + case ucode::AluScalarOpcode::kMuls: + case ucode::AluScalarOpcode::kMulsc0: + case ucode::AluScalarOpcode::kMulsc1: { + // Direct3D 9 behavior (0 or denormal * anything = +0). + state_.previous_scalar = (scalar_operands[0] && scalar_operands[1]) + ? scalar_operands[0] * scalar_operands[1] + : 0.0f; + } break; + case ucode::AluScalarOpcode::kMulsPrev: { + // Direct3D 9 behavior (0 or denormal * anything = +0). + state_.previous_scalar = (scalar_operands[0] && state_.previous_scalar) + ? scalar_operands[0] * state_.previous_scalar + : 0.0f; + } break; + case ucode::AluScalarOpcode::kMulsPrev2: { + if (state_.previous_scalar == -FLT_MAX || !std::isfinite(state_.previous_scalar) || + !std::isfinite(scalar_operands[1]) || std::islessequal(scalar_operands[1], 0.0f)) { + state_.previous_scalar = -FLT_MAX; + } else { + // Direct3D 9 behavior (0 or denormal * anything = +0). + state_.previous_scalar = (scalar_operands[0] && state_.previous_scalar) + ? scalar_operands[0] * state_.previous_scalar + : 0.0f; + } + } break; + case ucode::AluScalarOpcode::kMaxs: { + state_.previous_scalar = std::isgreaterequal(scalar_operands[0], scalar_operands[1]) + ? scalar_operands[0] + : scalar_operands[1]; + } break; + case ucode::AluScalarOpcode::kMins: { + state_.previous_scalar = std::isless(scalar_operands[0], scalar_operands[1]) + ? scalar_operands[0] + : scalar_operands[1]; + } break; + case ucode::AluScalarOpcode::kSeqs: { + state_.previous_scalar = float(scalar_operands[0] == 0.0f); + } break; + case ucode::AluScalarOpcode::kSgts: { + state_.previous_scalar = float(std::isgreater(scalar_operands[0], 0.0f)); + } break; + case ucode::AluScalarOpcode::kSges: { + state_.previous_scalar = float(std::isgreaterequal(scalar_operands[0], 0.0f)); + } break; + case ucode::AluScalarOpcode::kSnes: { + state_.previous_scalar = float(scalar_operands[0] != 0.0f); + } break; + case ucode::AluScalarOpcode::kFrcs: { + state_.previous_scalar = scalar_operands[0] - std::floor(scalar_operands[0]); + } break; + case ucode::AluScalarOpcode::kTruncs: { + state_.previous_scalar = std::trunc(scalar_operands[0]); + } break; + case ucode::AluScalarOpcode::kFloors: { + state_.previous_scalar = std::floor(scalar_operands[0]); + } break; + case ucode::AluScalarOpcode::kExp: { + state_.previous_scalar = std::exp2(scalar_operands[0]); + } break; + case ucode::AluScalarOpcode::kLogc: { + state_.previous_scalar = std::log2(scalar_operands[0]); + if (state_.previous_scalar == -INFINITY) { + state_.previous_scalar = -FLT_MAX; + } + } break; + case ucode::AluScalarOpcode::kLog: { + state_.previous_scalar = std::log2(scalar_operands[0]); + } break; + case ucode::AluScalarOpcode::kRcpc: { + state_.previous_scalar = 1.0f / scalar_operands[0]; + if (state_.previous_scalar == -INFINITY) { + state_.previous_scalar = -FLT_MAX; + } else if (state_.previous_scalar == INFINITY) { + state_.previous_scalar = FLT_MAX; + } + } break; + case ucode::AluScalarOpcode::kRcpf: { + state_.previous_scalar = 1.0f / scalar_operands[0]; + if (state_.previous_scalar == -INFINITY) { + state_.previous_scalar = -0.0f; + } else if (state_.previous_scalar == INFINITY) { + state_.previous_scalar = 0.0f; + } + } break; + case ucode::AluScalarOpcode::kRcp: { + state_.previous_scalar = 1.0f / scalar_operands[0]; + } break; + case ucode::AluScalarOpcode::kRsqc: { + state_.previous_scalar = 1.0f / std::sqrt(scalar_operands[0]); + if (state_.previous_scalar == -INFINITY) { + state_.previous_scalar = -FLT_MAX; + } else if (state_.previous_scalar == INFINITY) { + state_.previous_scalar = FLT_MAX; + } + } break; + case ucode::AluScalarOpcode::kRsqf: { + state_.previous_scalar = 1.0f / std::sqrt(scalar_operands[0]); + if (state_.previous_scalar == -INFINITY) { + state_.previous_scalar = -0.0f; + } else if (state_.previous_scalar == INFINITY) { + state_.previous_scalar = 0.0f; + } + } break; + case ucode::AluScalarOpcode::kRsq: { + state_.previous_scalar = 1.0f / std::sqrt(scalar_operands[0]); + } break; + case ucode::AluScalarOpcode::kMaxAs: { + state_.address_register = + int32_t(std::floor(rex::clamp_float(scalar_operands[0], -256.0f, 255.0f) + 0.5f)); + state_.previous_scalar = std::isgreaterequal(scalar_operands[0], scalar_operands[1]) + ? scalar_operands[0] + : scalar_operands[1]; + } break; + case ucode::AluScalarOpcode::kMaxAsf: { + state_.address_register = + int32_t(std::floor(rex::clamp_float(scalar_operands[0], -256.0f, 255.0f))); + state_.previous_scalar = std::isgreaterequal(scalar_operands[0], scalar_operands[1]) + ? scalar_operands[0] + : scalar_operands[1]; + } break; + case ucode::AluScalarOpcode::kSubs: + case ucode::AluScalarOpcode::kSubsc0: + case ucode::AluScalarOpcode::kSubsc1: { + state_.previous_scalar = scalar_operands[0] - scalar_operands[1]; + } break; + case ucode::AluScalarOpcode::kSubsPrev: { + state_.previous_scalar = scalar_operands[0] - state_.previous_scalar; + } break; + case ucode::AluScalarOpcode::kSetpEq: { + state_.predicate = scalar_operands[0] == 0.0f; + state_.previous_scalar = float(!state_.predicate); + } break; + case ucode::AluScalarOpcode::kSetpNe: { + state_.predicate = scalar_operands[0] != 0.0f; + state_.previous_scalar = float(!state_.predicate); + } break; + case ucode::AluScalarOpcode::kSetpGt: { + state_.predicate = std::isgreater(scalar_operands[0], 0.0f); + state_.previous_scalar = float(!state_.predicate); + } break; + case ucode::AluScalarOpcode::kSetpGe: { + state_.predicate = std::isgreaterequal(scalar_operands[0], 0.0f); + state_.previous_scalar = float(!state_.predicate); + } break; + case ucode::AluScalarOpcode::kSetpInv: { + state_.predicate = scalar_operands[0] == 1.0f; + state_.previous_scalar = + state_.predicate ? 0.0f : (scalar_operands[0] == 0.0f ? 1.0f : scalar_operands[0]); + } break; + case ucode::AluScalarOpcode::kSetpPop: { + float new_counter = scalar_operands[0] - 1.0f; + state_.predicate = std::islessequal(new_counter, 0.0f); + state_.previous_scalar = state_.predicate ? 0.0f : new_counter; + } break; + case ucode::AluScalarOpcode::kSetpClr: { + state_.predicate = false; + state_.previous_scalar = FLT_MAX; + } break; + case ucode::AluScalarOpcode::kSetpRstr: { + state_.predicate = scalar_operands[0] == 0.0f; + state_.previous_scalar = state_.predicate ? 0.0f : scalar_operands[0]; + } break; + // Not implementing pixel kill currently, the interpreter is currently used + // only for vertex shaders. + case ucode::AluScalarOpcode::kKillsEq: { + state_.previous_scalar = float(scalar_operands[0] == 0.0f); + } break; + case ucode::AluScalarOpcode::kKillsGt: { + state_.previous_scalar = float(std::isgreater(scalar_operands[0], 0.0f)); + } break; + case ucode::AluScalarOpcode::kKillsGe: { + state_.previous_scalar = float(std::isgreaterequal(scalar_operands[0], 0.0f)); + } break; + case ucode::AluScalarOpcode::kKillsNe: { + state_.previous_scalar = float(scalar_operands[0] != 0.0f); + } break; + case ucode::AluScalarOpcode::kKillsOne: { + state_.previous_scalar = float(scalar_operands[0] == 1.0f); + } break; + case ucode::AluScalarOpcode::kSqrt: { + state_.previous_scalar = std::sqrt(scalar_operands[0]); + } break; + case ucode::AluScalarOpcode::kSin: { + state_.previous_scalar = std::sin(scalar_operands[0]); + } break; + case ucode::AluScalarOpcode::kCos: { + state_.previous_scalar = std::cos(scalar_operands[0]); + } break; + case ucode::AluScalarOpcode::kRetainPrev: { + } break; + default: { + assert_unhandled_case(scalar_opcode); + } + } + + if (instr.vector_clamp()) { + for (uint32_t i = 0; i < 4; ++i) { + vector_result[i] = rex::saturate(vector_result[i]); + } + } + float scalar_result = + instr.scalar_clamp() ? rex::saturate(state_.previous_scalar) : state_.previous_scalar; + + uint32_t scalar_result_write_mask = instr.GetScalarOpResultWriteMask(); + if (instr.is_export()) { + if (export_sink_) { + float export_value[4]; + uint32_t export_constant_1_mask = instr.GetConstant1WriteMask(); + uint32_t export_mask = vector_result_write_mask | scalar_result_write_mask | + instr.GetConstant0WriteMask() | export_constant_1_mask; + for (uint32_t i = 0; i < 4; ++i) { + uint32_t export_component_bit = UINT32_C(1) << i; + float export_component = 0.0f; + if (vector_result_write_mask & export_component_bit) { + export_component = vector_result[i]; + } else if (scalar_result_write_mask & export_component_bit) { + export_component = scalar_result; + } else if (export_constant_1_mask & export_component_bit) { + export_component = 1.0f; + } else { + export_component = 0.0f; + } + export_value[i] = export_component; + } + export_sink_->Export(ucode::ExportRegister(instr.vector_dest()), export_value, + vector_result_write_mask | scalar_result_write_mask | + instr.GetConstant0WriteMask() | export_constant_1_mask); + } + } else { + if (vector_result_write_mask) { + float* vector_dest = GetTempRegister(instr.vector_dest(), instr.is_vector_dest_relative()); + for (uint32_t i = 0; i < 4; ++i) { + if (vector_result_write_mask & (UINT32_C(1) << i)) { + vector_dest[i] = vector_result[i]; + } + } + } + if (scalar_result_write_mask) { + float* scalar_dest = GetTempRegister(instr.scalar_dest(), instr.is_scalar_dest_relative()); + for (uint32_t i = 0; i < 4; ++i) { + if (scalar_result_write_mask & (UINT32_C(1) << i)) { + scalar_dest[i] = scalar_result; + } + } + } + } +} + +void ShaderInterpreter::StoreFetchResult(uint32_t dest, bool is_dest_relative, uint32_t swizzle, + const float* value) { + float* dest_data = GetTempRegister(dest, is_dest_relative); + for (uint32_t i = 0; i < 4; ++i) { + ucode::FetchDestinationSwizzle component_swizzle = + ucode::GetFetchDestinationComponentSwizzle(swizzle, i); + switch (component_swizzle) { + case ucode::FetchDestinationSwizzle::kX: + dest_data[i] = value[0]; + break; + case ucode::FetchDestinationSwizzle::kY: + dest_data[i] = value[1]; + break; + case ucode::FetchDestinationSwizzle::kZ: + dest_data[i] = value[2]; + break; + case ucode::FetchDestinationSwizzle::kW: + dest_data[i] = value[3]; + break; + case ucode::FetchDestinationSwizzle::k1: + dest_data[i] = 1.0f; + break; + case ucode::FetchDestinationSwizzle::kKeep: + break; + default: + // ucode::FetchDestinationSwizzle::k0 or the invalid swizzle 6. + // TODO(Triang3l): Find the correct handling of the invalid swizzle 6. + assert_true(component_swizzle == ucode::FetchDestinationSwizzle::k0); + dest_data[i] = 0.0f; + break; + } + } +} + +void ShaderInterpreter::ExecuteVertexFetchInstruction(ucode::VertexFetchInstruction instr) { + // FIXME(Triang3l): Bit scan loops over components cause a link-time + // optimization internal error in Visual Studio 2019, mainly in the format + // unpacking. Using loops with up to 4 iterations here instead. + + if (!instr.is_mini_fetch()) { + state_.vfetch_full_last = instr; + } + + xenos::xe_gpu_vertex_fetch_t fetch_constant = + register_file_.GetVertexFetch(state_.vfetch_full_last.fetch_constant_index()); + + if (!instr.is_mini_fetch()) { + // Get the part of the address that depends on vfetch_full data. + uint32_t vertex_index = uint32_t( + std::floor(GetTempRegister(instr.src(), instr.is_src_relative())[instr.src_swizzle()] + + (instr.is_index_rounded() ? 0.5f : 0.0f))); + state_.vfetch_address_dwords = instr.stride() * vertex_index + fetch_constant.address; + } + + // TODO(Triang3l): Find the default values for unused components. + float result[4] = {}; + uint32_t dest_swizzle = instr.dest_swizzle(); + uint32_t used_result_components = 0b0000; + for (uint32_t i = 0; i < 4; ++i) { + uint32_t dest_component_swizzle = (dest_swizzle >> (3 * i)) & 0b111; + if (dest_component_swizzle <= 3) { + used_result_components |= UINT32_C(1) << dest_component_swizzle; + } + } + uint32_t needed_dwords = + xenos::GetVertexFormatNeededWords(instr.data_format(), used_result_components); + if (needed_dwords) { + uint32_t data[4] = {}; + const uint32_t* memory_dwords = reinterpret_cast(memory_.physical_membase()); + uint32_t buffer_end_dwords = fetch_constant.address + fetch_constant.size; + uint32_t dword_0_address_dwords = + uint32_t(int32_t(state_.vfetch_address_dwords) + instr.offset()); + for (uint32_t i = 0; i < 4; ++i) { + if (!(needed_dwords & (UINT32_C(1) << i))) { + continue; + } + uint32_t dword_value = 0; + uint32_t dword_address_dwords = dword_0_address_dwords + i; + if (dword_address_dwords >= fetch_constant.address && + dword_address_dwords < buffer_end_dwords) { + if (trace_writer_) { + trace_writer_->WriteMemoryRead(sizeof(uint32_t) * dword_address_dwords, sizeof(uint32_t)); + } + dword_value = xenos::GpuSwap(memory_dwords[dword_address_dwords], fetch_constant.endian); + } + data[i] = dword_value; + } + + uint32_t packed_components = 0b0000; + uint32_t packed_widths[4], packed_offsets[4]; + uint32_t packed_dwords[] = {data[0], data[0]}; + switch (instr.data_format()) { + case xenos::VertexFormat::k_8_8_8_8: { + packed_components = 0b1111; + packed_widths[0] = packed_widths[1] = packed_widths[2] = packed_widths[3] = 8; + packed_offsets[1] = 8; + packed_offsets[2] = 16; + packed_offsets[3] = 24; + } break; + case xenos::VertexFormat::k_2_10_10_10: { + packed_components = 0b1111; + packed_widths[0] = packed_widths[1] = packed_widths[2] = 10; + packed_widths[3] = 2; + packed_offsets[1] = 10; + packed_offsets[2] = 20; + packed_offsets[3] = 30; + } break; + case xenos::VertexFormat::k_10_11_11: { + packed_components = 0b0111; + packed_widths[0] = packed_widths[1] = 11; + packed_widths[2] = 10; + packed_offsets[1] = 11; + packed_offsets[2] = 22; + } break; + case xenos::VertexFormat::k_11_11_10: { + packed_components = 0b0111; + packed_widths[0] = 10; + packed_widths[1] = packed_widths[2] = 11; + packed_offsets[1] = 10; + packed_offsets[2] = 21; + } break; + case xenos::VertexFormat::k_16_16: { + packed_components = 0b0011; + packed_widths[0] = packed_widths[1] = 16; + packed_offsets[1] = 16; + } break; + case xenos::VertexFormat::k_16_16_16_16: { + packed_components = 0b1111; + packed_widths[0] = packed_widths[1] = packed_widths[2] = packed_widths[3] = 16; + packed_offsets[1] = packed_offsets[3] = 16; + packed_dwords[1] = data[1]; + } break; + case xenos::VertexFormat::k_16_16_16_16_FLOAT: { + if (used_result_components & 0b1000) { + result[3] = rex::xenos_half_to_float(uint16_t(data[1] >> 16)); + } + if (used_result_components & 0b0100) { + result[2] = rex::xenos_half_to_float(uint16_t(data[1])); + } + } + [[fallthrough]]; + case xenos::VertexFormat::k_16_16_FLOAT: { + if (used_result_components & 0b0010) { + result[1] = rex::xenos_half_to_float(uint16_t(data[0] >> 16)); + } + if (used_result_components & 0b0001) { + result[0] = rex::xenos_half_to_float(uint16_t(data[0])); + } + } break; + case xenos::VertexFormat::k_32: + case xenos::VertexFormat::k_32_32: + case xenos::VertexFormat::k_32_32_32_32: { + if (instr.is_signed()) { + for (uint32_t i = 0; i < 4; ++i) { + result[i] = float(int32_t(data[i])); + } + if (instr.is_normalized()) { + if (instr.signed_rf_mode() == xenos::SignedRepeatingFractionMode::kNoZero) { + for (uint32_t i = 0; i < 4; ++i) { + result[i] = (result[i] + 0.5f) / 2147483647.5f; + } + } else { + for (uint32_t i = 0; i < 4; ++i) { + result[i] /= 2147483647.0f; + // No need to clamp to -1 if signed - the smallest value will be + // -2^23 / 2^23 due to rounding. + } + } + } + } else { + for (uint32_t i = 0; i < 4; ++i) { + result[i] = float(data[i]); + } + if (instr.is_normalized()) { + for (uint32_t i = 0; i < 4; ++i) { + result[i] /= 4294967295.0f; + } + } + } + } break; + case xenos::VertexFormat::k_32_FLOAT: + case xenos::VertexFormat::k_32_32_FLOAT: + case xenos::VertexFormat::k_32_32_32_32_FLOAT: + case xenos::VertexFormat::k_32_32_32_FLOAT: { + for (uint32_t i = 0; i < 4; ++i) { + result[i] = *reinterpret_cast(&data[i]); + } + } break; + default: + assert_unhandled_case(instr.data_format()); + break; + } + + packed_components &= used_result_components; + if (packed_components) { + if (instr.is_signed()) { + for (uint32_t i = 0; i < 4; ++i) { + if (!(packed_components & (UINT32_C(1) << i))) { + continue; + } + uint32_t packed_width = packed_widths[i]; + result[i] = + float(int32_t(packed_dwords[i >> 1]) << (32 - (packed_width + packed_offsets[i])) >> + (32 - packed_width)); + } + if (instr.is_normalized()) { + if (instr.signed_rf_mode() == xenos::SignedRepeatingFractionMode::kNoZero) { + for (uint32_t i = 0; i < 4; ++i) { + if (!(packed_components & (UINT32_C(1) << i))) { + continue; + } + result[i] = (result[i] + 0.5f) * 2.0f / float((UINT32_C(1) << packed_widths[i]) - 1); + } + } else { + for (uint32_t i = 0; i < 4; ++i) { + if (!(packed_components & (UINT32_C(1) << i))) { + continue; + } + result[i] = + std::max(-1.0f, result[i] / float((UINT32_C(1) << (packed_widths[i] - 1)) - 1)); + } + } + } + } else { + for (uint32_t i = 0; i < 4; ++i) { + if (!(packed_components & (UINT32_C(1) << i))) { + continue; + } + uint32_t packed_width = packed_widths[i]; + result[i] = float(packed_dwords[i >> 1] & ((UINT32_C(1) << packed_widths[i]) - 1)); + } + if (instr.is_normalized()) { + for (uint32_t i = 0; i < 4; ++i) { + if (!(packed_components & (UINT32_C(1) << i))) { + continue; + } + result[i] /= float((UINT32_C(1) << packed_widths[i]) - 1); + } + } + } + } + } + + int32_t exp_adjust = instr.exp_adjust(); + if (exp_adjust) { + float exp_adjust_factor = std::ldexp(1.0f, exp_adjust); + for (uint32_t i = 0; i < 4; ++i) { + result[i] *= exp_adjust_factor; + } + } + + StoreFetchResult(instr.dest(), instr.is_dest_relative(), instr.dest_swizzle(), result); +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/shader/shader.cpp b/src/graphics/pipeline/shader/shader.cpp new file mode 100644 index 0000000..a53a222 --- /dev/null +++ b/src/graphics/pipeline/shader/shader.cpp @@ -0,0 +1,161 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace rex::graphics { +using namespace ucode; + +Shader::Shader(xenos::ShaderType shader_type, uint64_t ucode_data_hash, + const uint32_t* ucode_dwords, size_t ucode_dword_count, + std::endian ucode_source_endian) + : shader_type_(shader_type), ucode_data_hash_(ucode_data_hash) { + // We keep ucode data in host native format so it's easier to work with. + ucode_data_.resize(ucode_dword_count); + if (std::endian::native != ucode_source_endian) { + memory::copy_and_swap(ucode_data_.data(), ucode_dwords, ucode_dword_count); + } else { + std::memcpy(ucode_data_.data(), ucode_dwords, sizeof(uint32_t) * ucode_dword_count); + } +} + +Shader::~Shader() { + for (auto it : translations_) { + delete it.second; + } +} + +std::string Shader::Translation::GetTranslatedBinaryString() const { + std::string result; + result.resize(translated_binary_.size()); + std::memcpy(const_cast(result.data()), translated_binary_.data(), + translated_binary_.size()); + return result; +} + +std::pair Shader::Translation::Dump( + const std::filesystem::path& base_path, const char* path_prefix) const { + if (!is_valid()) { + return std::make_pair(std::filesystem::path(), std::filesystem::path()); + } + + std::filesystem::path path = base_path; + // Ensure target path exists. + std::filesystem::path target_path = base_path; + if (!target_path.empty()) { + target_path = std::filesystem::absolute(target_path); + std::filesystem::create_directories(target_path); + } + + const char* type_extension = shader().type() == xenos::ShaderType::kVertex ? "vert" : "frag"; + + std::filesystem::path binary_path = + target_path / fmt::format("shader_{:016X}_{:016X}.{}.bin.{}", shader().ucode_data_hash(), + modification(), path_prefix, type_extension); + FILE* binary_file = filesystem::OpenFile(binary_path, "wb"); + if (binary_file) { + fwrite(translated_binary_.data(), sizeof(*translated_binary_.data()), translated_binary_.size(), + binary_file); + fclose(binary_file); + } + + std::filesystem::path disasm_path; + if (!host_disassembly_.empty()) { + disasm_path = + target_path / fmt::format("shader_{:016X}_{:016X}.{}.{}", shader().ucode_data_hash(), + modification(), path_prefix, type_extension); + FILE* disasm_file = filesystem::OpenFile(disasm_path, "w"); + if (disasm_file) { + fwrite(host_disassembly_.data(), sizeof(*host_disassembly_.data()), host_disassembly_.size(), + disasm_file); + fclose(disasm_file); + } + } + + return std::make_pair(std::move(binary_path), std::move(disasm_path)); +} + +Shader::Translation* Shader::GetOrCreateTranslation(uint64_t modification, bool* is_new) { + auto it = translations_.find(modification); + if (it != translations_.end()) { + if (is_new) { + *is_new = false; + } + return it->second; + } + Translation* translation = CreateTranslationInstance(modification); + translations_.emplace(modification, translation); + if (is_new) { + *is_new = true; + } + return translation; +} + +void Shader::DestroyTranslation(uint64_t modification) { + auto it = translations_.find(modification); + if (it == translations_.end()) { + return; + } + delete it->second; + translations_.erase(it); +} + +std::pair Shader::DumpUcode( + const std::filesystem::path& base_path) const { + // Ensure target path exists. + std::filesystem::path target_path = base_path; + if (!target_path.empty()) { + target_path = std::filesystem::absolute(target_path); + std::filesystem::create_directories(target_path); + } + + const char* type_extension = type() == xenos::ShaderType::kVertex ? "vert" : "frag"; + + std::filesystem::path binary_path = + target_path / fmt::format("shader_{:016X}.ucode.bin.{}", ucode_data_hash(), type_extension); + FILE* binary_file = filesystem::OpenFile(binary_path, "wb"); + if (binary_file) { + fwrite(ucode_data().data(), sizeof(*ucode_data().data()), ucode_data().size(), binary_file); + fclose(binary_file); + } + + std::filesystem::path disasm_path; + if (is_ucode_analyzed()) { + disasm_path = + target_path / fmt::format("shader_{:016X}.ucode.{}", ucode_data_hash(), type_extension); + FILE* disasm_file = filesystem::OpenFile(disasm_path, "w"); + if (disasm_file) { + fwrite(ucode_disassembly().data(), sizeof(*ucode_disassembly().data()), + ucode_disassembly().size(), disasm_file); + fclose(disasm_file); + } + } + + return std::make_pair(std::move(binary_path), std::move(disasm_path)); +} + +Shader::Translation* Shader::CreateTranslationInstance(uint64_t modification) { + // Default implementation for simple cases like ucode disassembly. + return new Translation(*this, modification); +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/shader/spirv.cpp b/src/graphics/pipeline/shader/spirv.cpp new file mode 100644 index 0000000..6b68a16 --- /dev/null +++ b/src/graphics/pipeline/shader/spirv.cpp @@ -0,0 +1,27 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include + +namespace rex::graphics { + +SpirvShader::SpirvShader(xenos::ShaderType shader_type, uint64_t ucode_data_hash, + const uint32_t* ucode_dwords, size_t ucode_dword_count, + std::endian ucode_source_endian) + : Shader(shader_type, ucode_data_hash, ucode_dwords, ucode_dword_count, ucode_source_endian) {} + +Shader::Translation* SpirvShader::CreateTranslationInstance(uint64_t modification) { + return new SpirvTranslation(*this, modification); +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/shader/spirv_builder.cpp b/src/graphics/pipeline/shader/spirv_builder.cpp new file mode 100644 index 0000000..d7e1c97 --- /dev/null +++ b/src/graphics/pipeline/shader/spirv_builder.cpp @@ -0,0 +1,279 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2023 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include + +namespace rex::graphics { + +spv::Id SpirvBuilder::createQuadOp(spv::Op op_code, spv::Id type_id, spv::Id operand1, + spv::Id operand2, spv::Id operand3, spv::Id operand4) { + if (generatingOpCodeForSpecConst) { + std::vector operands(4); + operands[0] = operand1; + operands[1] = operand2; + operands[2] = operand3; + operands[3] = operand4; + return createSpecConstantOp(op_code, type_id, operands, std::vector()); + } + std::unique_ptr op = + std::make_unique(getUniqueId(), type_id, op_code); + op->addIdOperand(operand1); + op->addIdOperand(operand2); + op->addIdOperand(operand3); + op->addIdOperand(operand4); + spv::Id result = op->getResultId(); + buildPoint->addInstruction(std::move(op)); + return result; +} + +spv::Id SpirvBuilder::createNoContractionUnaryOp(spv::Op op_code, spv::Id type_id, + spv::Id operand) { + spv::Id result = createUnaryOp(op_code, type_id, operand); + addDecoration(result, spv::DecorationNoContraction); + return result; +} + +spv::Id SpirvBuilder::createNoContractionBinOp(spv::Op op_code, spv::Id type_id, spv::Id operand1, + spv::Id operand2) { + spv::Id result = createBinOp(op_code, type_id, operand1, operand2); + addDecoration(result, spv::DecorationNoContraction); + return result; +} + +spv::Id SpirvBuilder::createUnaryBuiltinCall(spv::Id result_type, spv::Id builtins, int entry_point, + spv::Id operand) { + std::unique_ptr instruction = + std::make_unique(getUniqueId(), result_type, spv::OpExtInst); + instruction->addIdOperand(builtins); + instruction->addImmediateOperand(entry_point); + instruction->addIdOperand(operand); + spv::Id result = instruction->getResultId(); + getBuildPoint()->addInstruction(std::move(instruction)); + return result; +} + +spv::Id SpirvBuilder::createBinBuiltinCall(spv::Id result_type, spv::Id builtins, int entry_point, + spv::Id operand1, spv::Id operand2) { + std::unique_ptr instruction = + std::make_unique(getUniqueId(), result_type, spv::OpExtInst); + instruction->addIdOperand(builtins); + instruction->addImmediateOperand(entry_point); + instruction->addIdOperand(operand1); + instruction->addIdOperand(operand2); + spv::Id result = instruction->getResultId(); + getBuildPoint()->addInstruction(std::move(instruction)); + return result; +} + +spv::Id SpirvBuilder::createTriBuiltinCall(spv::Id result_type, spv::Id builtins, int entry_point, + spv::Id operand1, spv::Id operand2, spv::Id operand3) { + std::unique_ptr instruction = + std::make_unique(getUniqueId(), result_type, spv::OpExtInst); + instruction->addIdOperand(builtins); + instruction->addImmediateOperand(entry_point); + instruction->addIdOperand(operand1); + instruction->addIdOperand(operand2); + instruction->addIdOperand(operand3); + spv::Id result = instruction->getResultId(); + getBuildPoint()->addInstruction(std::move(instruction)); + return result; +} + +SpirvBuilder::IfBuilder::IfBuilder(spv::Id condition, unsigned int control, SpirvBuilder& builder, + unsigned int thenWeight, unsigned int elseWeight) + : builder(builder), + condition(condition), + control(control), + thenWeight(thenWeight), + elseWeight(elseWeight), + function(builder.getBuildPoint()->getParent()) { + // Make the blocks, but only put the then-block into the function, the + // else-block and merge-block will be added later, in order, after earlier + // code is emitted. + thenBlock = new spv::Block(builder.getUniqueId(), function); + elseBlock = nullptr; + mergeBlock = new spv::Block(builder.getUniqueId(), function); + + // Save the current block, so that we can add in the flow control split when + // makeEndIf is called. + headerBlock = builder.getBuildPoint(); + + spv::Id headerBlockId = headerBlock->getId(); + thenPhiParent = headerBlockId; + elsePhiParent = headerBlockId; + + function.addBlock(thenBlock); + builder.setBuildPoint(thenBlock); +} + +void SpirvBuilder::IfBuilder::makeBeginElse(bool branchToMerge) { +#ifndef NDEBUG + assert_true(currentBranch == Branch::kThen); +#endif + + if (branchToMerge) { + // Close out the "then" by having it jump to the mergeBlock. + thenPhiParent = builder.getBuildPoint()->getId(); + builder.createBranch(mergeBlock); + } + + // Make the first else block and add it to the function. + elseBlock = new spv::Block(builder.getUniqueId(), function); + function.addBlock(elseBlock); + + // Start building the else block. + builder.setBuildPoint(elseBlock); + +#ifndef NDEBUG + currentBranch = Branch::kElse; +#endif +} + +void SpirvBuilder::IfBuilder::makeEndIf(bool branchToMerge) { +#ifndef NDEBUG + assert_true(currentBranch == Branch::kThen || currentBranch == Branch::kElse); +#endif + + if (branchToMerge) { + // Jump to the merge block. + (elseBlock ? elsePhiParent : thenPhiParent) = builder.getBuildPoint()->getId(); + builder.createBranch(mergeBlock); + } + + // Go back to the headerBlock and make the flow control split. + builder.setBuildPoint(headerBlock); + builder.createSelectionMerge(mergeBlock, control); + { + spv::Block* falseBlock = elseBlock ? elseBlock : mergeBlock; + std::unique_ptr branch = + std::make_unique(spv::OpBranchConditional); + branch->addIdOperand(condition); + branch->addIdOperand(thenBlock->getId()); + branch->addIdOperand(falseBlock->getId()); + if (thenWeight || elseWeight) { + branch->addImmediateOperand(thenWeight); + branch->addImmediateOperand(elseWeight); + } + builder.getBuildPoint()->addInstruction(std::move(branch)); + thenBlock->addPredecessor(builder.getBuildPoint()); + falseBlock->addPredecessor(builder.getBuildPoint()); + } + + // Add the merge block to the function. + function.addBlock(mergeBlock); + builder.setBuildPoint(mergeBlock); + +#ifndef NDEBUG + currentBranch = Branch::kMerge; +#endif +} + +spv::Id SpirvBuilder::IfBuilder::createMergePhi(spv::Id then_variable, + spv::Id else_variable) const { + assert_true(builder.getBuildPoint() == mergeBlock); + return builder.createQuadOp(spv::OpPhi, builder.getTypeId(then_variable), then_variable, + getThenPhiParent(), else_variable, getElsePhiParent()); +} + +SpirvBuilder::SwitchBuilder::SwitchBuilder(spv::Id selector, unsigned int selection_control, + SpirvBuilder& builder) + : builder_(builder), + selector_(selector), + selection_control_(selection_control), + function_(builder.getBuildPoint()->getParent()), + header_block_(builder.getBuildPoint()), + default_phi_parent_(builder.getBuildPoint()->getId()) { + merge_block_ = new spv::Block(builder_.getUniqueId(), function_); +} + +void SpirvBuilder::SwitchBuilder::makeBeginDefault() { + assert_null(default_block_); + + endSegment(); + + default_block_ = new spv::Block(builder_.getUniqueId(), function_); + function_.addBlock(default_block_); + default_block_->addPredecessor(header_block_); + builder_.setBuildPoint(default_block_); + + current_branch_ = Branch::kDefault; +} + +void SpirvBuilder::SwitchBuilder::makeBeginCase(unsigned int literal) { + endSegment(); + + auto case_block = new spv::Block(builder_.getUniqueId(), function_); + function_.addBlock(case_block); + cases_.emplace_back(literal, case_block->getId()); + case_block->addPredecessor(header_block_); + builder_.setBuildPoint(case_block); + + current_branch_ = Branch::kCase; +} + +void SpirvBuilder::SwitchBuilder::addCurrentCaseLiteral(unsigned int literal) { + assert_true(current_branch_ == Branch::kCase); + + cases_.emplace_back(literal, cases_.back().second); +} + +void SpirvBuilder::SwitchBuilder::makeEndSwitch() { + endSegment(); + + builder_.setBuildPoint(header_block_); + + builder_.createSelectionMerge(merge_block_, selection_control_); + + std::unique_ptr switch_instruction = + std::make_unique(spv::OpSwitch); + switch_instruction->addIdOperand(selector_); + if (default_block_) { + switch_instruction->addIdOperand(default_block_->getId()); + } else { + switch_instruction->addIdOperand(merge_block_->getId()); + merge_block_->addPredecessor(header_block_); + } + for (const std::pair& case_pair : cases_) { + switch_instruction->addImmediateOperand(case_pair.first); + switch_instruction->addIdOperand(case_pair.second); + } + builder_.getBuildPoint()->addInstruction(std::move(switch_instruction)); + + function_.addBlock(merge_block_); + builder_.setBuildPoint(merge_block_); + + current_branch_ = Branch::kMerge; +} + +void SpirvBuilder::SwitchBuilder::endSegment() { + assert_true(current_branch_ == Branch::kSelection || current_branch_ == Branch::kDefault || + current_branch_ == Branch::kCase); + + if (current_branch_ == Branch::kSelection) { + return; + } + + if (!builder_.getBuildPoint()->isTerminated()) { + builder_.createBranch(merge_block_); + if (current_branch_ == Branch::kDefault) { + default_phi_parent_ = builder_.getBuildPoint()->getId(); + } + } + + current_branch_ = Branch::kSelection; +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/shader/spirv_translator.cpp b/src/graphics/pipeline/shader/spirv_translator.cpp new file mode 100644 index 0000000..c709705 --- /dev/null +++ b/src/graphics/pipeline/shader/spirv_translator.cpp @@ -0,0 +1,4276 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +namespace rex::graphics { + +SpirvShaderTranslator::Features::Features(bool all) + : spirv_version(all ? spv::Spv_1_5 : spv::Spv_1_0), + max_storage_buffer_range(all ? UINT32_MAX : (128 * 1024 * 1024)), + full_draw_index_uint32(all), + vertex_pipeline_stores_and_atomics(all), + fragment_stores_and_atomics(all), + clip_distance(all), + cull_distance(all), + image_view_format_swizzle(all), + signed_zero_inf_nan_preserve_float32(all), + denorm_flush_to_zero_float32(all), + rounding_mode_rte_float32(all), + fragment_shader_sample_interlock(all), + demote_to_helper_invocation(all), + sample_rate_shading(all) {} + +SpirvShaderTranslator::Features::Features(const ui::vulkan::VulkanDevice* const vulkan_device) + : max_storage_buffer_range(vulkan_device->properties().maxStorageBufferRange), + full_draw_index_uint32(vulkan_device->properties().fullDrawIndexUint32), + vertex_pipeline_stores_and_atomics( + vulkan_device->properties().vertexPipelineStoresAndAtomics), + fragment_stores_and_atomics(vulkan_device->properties().fragmentStoresAndAtomics), + clip_distance(vulkan_device->properties().shaderClipDistance), + cull_distance(vulkan_device->properties().shaderCullDistance), + image_view_format_swizzle(vulkan_device->properties().imageViewFormatSwizzle), + signed_zero_inf_nan_preserve_float32( + vulkan_device->properties().shaderSignedZeroInfNanPreserveFloat32), + denorm_flush_to_zero_float32(vulkan_device->properties().shaderDenormFlushToZeroFloat32), + rounding_mode_rte_float32(vulkan_device->properties().shaderRoundingModeRTEFloat32), + fragment_shader_sample_interlock(vulkan_device->properties().fragmentShaderSampleInterlock), + demote_to_helper_invocation(vulkan_device->properties().shaderDemoteToHelperInvocation), + sample_rate_shading(vulkan_device->properties().sampleRateShading) { + const uint32_t vulkan_api_version = vulkan_device->properties().apiVersion; + if (vulkan_api_version >= VK_MAKE_API_VERSION(0, 1, 2, 0)) { + spirv_version = spv::Spv_1_5; + } else if (vulkan_device->extensions().ext_1_2_KHR_spirv_1_4) { + spirv_version = spv::Spv_1_4; + } else if (vulkan_api_version >= VK_MAKE_API_VERSION(0, 1, 1, 0)) { + spirv_version = spv::Spv_1_3; + } else { + spirv_version = spv::Spv_1_0; + } +} + +uint64_t SpirvShaderTranslator::GetDefaultVertexShaderModification( + uint32_t dynamic_addressable_register_count, + Shader::HostVertexShaderType host_vertex_shader_type) const { + Modification shader_modification; + shader_modification.vertex.dynamic_addressable_register_count = + dynamic_addressable_register_count; + shader_modification.vertex.host_vertex_shader_type = host_vertex_shader_type; + return shader_modification.value; +} + +uint64_t SpirvShaderTranslator::GetDefaultPixelShaderModification( + uint32_t dynamic_addressable_register_count) const { + Modification shader_modification; + shader_modification.pixel.dynamic_addressable_register_count = dynamic_addressable_register_count; + return shader_modification.value; +} + +std::vector SpirvShaderTranslator::CreateDepthOnlyFragmentShader( + Modification::DepthStencilMode depth_stencil_mode) { + is_depth_only_fragment_shader_ = true; + // TODO(Triang3l): Handle in a nicer way (is_depth_only_fragment_shader_ is a + // leftover from when a Shader object wasn't used during translation). + Shader shader(xenos::ShaderType::kPixel, 0, nullptr, 0); + string::StringBuffer instruction_disassembly_buffer; + shader.AnalyzeUcode(instruction_disassembly_buffer); + Modification modification(GetDefaultPixelShaderModification(0)); + modification.pixel.depth_stencil_mode = depth_stencil_mode; + Shader::Translation& translation = *shader.GetOrCreateTranslation(modification.value); + TranslateAnalyzedShader(translation); + is_depth_only_fragment_shader_ = false; + return translation.translated_binary(); +} + +void SpirvShaderTranslator::Reset() { + ShaderTranslator::Reset(); + + builder_.reset(); + + uniform_float_constants_ = spv::NoResult; + + input_vertex_index_ = spv::NoResult; + input_primitive_id_ = spv::NoResult; + input_tess_coord_ = spv::NoResult; + input_patch_control_point_indices_ = spv::NoResult; + input_point_coordinates_ = spv::NoResult; + input_fragment_coordinates_ = spv::NoResult; + input_front_facing_ = spv::NoResult; + input_sample_id_ = spv::NoResult; + input_sample_mask_ = spv::NoResult; + std::fill(input_output_interpolators_.begin(), input_output_interpolators_.end(), spv::NoResult); + output_point_coordinates_ = spv::NoResult; + output_point_size_ = spv::NoResult; + output_per_vertex_member_count_ = 0; + output_per_vertex_member_clip_distance_ = UINT32_MAX; + output_per_vertex_member_cull_distance_ = UINT32_MAX; + type_output_per_vertex_ = spv::NoResult; + output_per_vertex_ = spv::NoResult; + output_fragment_depth_ = spv::NoResult; + output_fragment_sample_mask_ = spv::NoResult; + + sampler_bindings_.clear(); + texture_bindings_.clear(); + + main_interface_.clear(); + var_main_registers_ = spv::NoResult; + var_main_memexport_address_ = spv::NoResult; + for (size_t memexport_eM_index = 0; memexport_eM_index < rex::countof(var_main_memexport_data_); + ++memexport_eM_index) { + var_main_memexport_data_[memexport_eM_index] = spv::NoResult; + } + var_main_memexport_data_written_ = spv::NoResult; + main_memexport_allowed_ = spv::NoResult; + var_main_rectangle_guest_vertex_index_ = spv::NoResult; + var_main_rectangle_per_vertex_ = spv::NoResult; + std::fill(var_main_rectangle_interpolators_.begin(), var_main_rectangle_interpolators_.end(), + spv::NoResult); + var_main_point_size_edge_flag_kill_vertex_ = spv::NoResult; + var_main_kill_pixel_ = spv::NoResult; + var_main_fragment_depth_ = spv::NoResult; + var_main_fsi_color_written_ = spv::NoResult; + + main_switch_op_.reset(); + main_switch_next_pc_phi_operands_.clear(); + main_loop_exit_ = nullptr; + + cf_exec_conditional_merge_ = nullptr; + cf_instruction_predicate_merge_ = nullptr; +} + +uint32_t SpirvShaderTranslator::GetModificationRegisterCount() const { + Modification modification = GetSpirvShaderModification(); + return is_vertex_shader() ? modification.vertex.dynamic_addressable_register_count + : modification.pixel.dynamic_addressable_register_count; +} + +void SpirvShaderTranslator::StartTranslation() { + // TODO(Triang3l): Logger. + builder_ = std::make_unique(features_.spirv_version, (kSpirvMagicToolId << 16) | 1, + nullptr); + + builder_->addCapability(IsSpirvTessEvalShader() ? spv::CapabilityTessellation + : spv::CapabilityShader); + if (features_.spirv_version < spv::Spv_1_4) { + if (features_.signed_zero_inf_nan_preserve_float32 || features_.denorm_flush_to_zero_float32 || + features_.rounding_mode_rte_float32) { + builder_->addExtension("SPV_KHR_float_controls"); + } + } + ext_inst_glsl_std_450_ = builder_->import("GLSL.std.450"); + builder_->setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450); + builder_->setSource(spv::SourceLanguageUnknown, 0); + + type_void_ = builder_->makeVoidType(); + type_bool_ = builder_->makeBoolType(); + type_bool2_ = builder_->makeVectorType(type_bool_, 2); + type_bool3_ = builder_->makeVectorType(type_bool_, 3); + type_bool4_ = builder_->makeVectorType(type_bool_, 4); + type_int_ = builder_->makeIntType(32); + type_int2_ = builder_->makeVectorType(type_int_, 2); + type_int3_ = builder_->makeVectorType(type_int_, 3); + type_int4_ = builder_->makeVectorType(type_int_, 4); + type_uint_ = builder_->makeUintType(32); + type_uint2_ = builder_->makeVectorType(type_uint_, 2); + type_uint3_ = builder_->makeVectorType(type_uint_, 3); + type_uint4_ = builder_->makeVectorType(type_uint_, 4); + type_float_ = builder_->makeFloatType(32); + type_float2_ = builder_->makeVectorType(type_float_, 2); + type_float3_ = builder_->makeVectorType(type_float_, 3); + type_float4_ = builder_->makeVectorType(type_float_, 4); + + const_int_0_ = builder_->makeIntConstant(0); + id_vector_temp_.clear(); + for (uint32_t i = 0; i < 4; ++i) { + id_vector_temp_.push_back(const_int_0_); + } + const_int4_0_ = builder_->makeCompositeConstant(type_int4_, id_vector_temp_); + const_uint_0_ = builder_->makeUintConstant(0); + id_vector_temp_.clear(); + for (uint32_t i = 0; i < 4; ++i) { + id_vector_temp_.push_back(const_uint_0_); + } + const_uint4_0_ = builder_->makeCompositeConstant(type_uint4_, id_vector_temp_); + const_float_0_ = builder_->makeFloatConstant(0.0f); + id_vector_temp_.clear(); + id_vector_temp_.push_back(const_float_0_); + for (uint32_t i = 1; i < 4; ++i) { + id_vector_temp_.push_back(const_float_0_); + const_float_vectors_0_[i] = + builder_->makeCompositeConstant(type_float_vectors_[i], id_vector_temp_); + } + const_float_1_ = builder_->makeFloatConstant(1.0f); + id_vector_temp_.clear(); + id_vector_temp_.push_back(const_float_1_); + for (uint32_t i = 1; i < 4; ++i) { + id_vector_temp_.push_back(const_float_1_); + const_float_vectors_1_[i] = + builder_->makeCompositeConstant(type_float_vectors_[i], id_vector_temp_); + } + id_vector_temp_.clear(); + id_vector_temp_.push_back(const_float_0_); + id_vector_temp_.push_back(const_float_1_); + const_float2_0_1_ = builder_->makeCompositeConstant(type_float2_, id_vector_temp_); + + // Common uniform buffer - system constants. + struct SystemConstant { + const char* name; + size_t offset; + spv::Id type; + }; + spv::Id type_float4_array_4 = + builder_->makeArrayType(type_float4_, builder_->makeUintConstant(4), sizeof(float) * 4); + builder_->addDecoration(type_float4_array_4, spv::DecorationArrayStride, sizeof(float) * 4); + spv::Id type_float4_array_6 = + builder_->makeArrayType(type_float4_, builder_->makeUintConstant(6), sizeof(float) * 4); + builder_->addDecoration(type_float4_array_6, spv::DecorationArrayStride, sizeof(float) * 4); + spv::Id type_uint4_array_2 = + builder_->makeArrayType(type_uint4_, builder_->makeUintConstant(2), sizeof(uint32_t) * 4); + builder_->addDecoration(type_uint4_array_2, spv::DecorationArrayStride, sizeof(uint32_t) * 4); + spv::Id type_uint4_array_4 = + builder_->makeArrayType(type_uint4_, builder_->makeUintConstant(4), sizeof(uint32_t) * 4); + builder_->addDecoration(type_uint4_array_4, spv::DecorationArrayStride, sizeof(uint32_t) * 4); + const SystemConstant system_constants[] = { + {"flags", offsetof(SystemConstants, flags), type_uint_}, + {"vertex_index_load_address", offsetof(SystemConstants, vertex_index_load_address), + type_uint_}, + {"vertex_index_endian", offsetof(SystemConstants, vertex_index_endian), type_uint_}, + {"line_loop_closing_index", offsetof(SystemConstants, line_loop_closing_index), type_uint_}, + {"vertex_base_index", offsetof(SystemConstants, vertex_base_index), type_int_}, + {"vertex_index_reset", offsetof(SystemConstants, vertex_index_reset), type_uint_}, + {"compute_memexport_vertex_count", offsetof(SystemConstants, compute_memexport_vertex_count), + type_uint_}, + {"user_clip_planes", offsetof(SystemConstants, user_clip_planes), type_float4_array_6}, + {"vertex_index_min", offsetof(SystemConstants, vertex_index_min), type_uint_}, + {"vertex_index_max", offsetof(SystemConstants, vertex_index_max), type_uint_}, + {"ndc_scale", offsetof(SystemConstants, ndc_scale), type_float3_}, + {"point_vertex_diameter_min", offsetof(SystemConstants, point_vertex_diameter_min), + type_float_}, + {"ndc_offset", offsetof(SystemConstants, ndc_offset), type_float3_}, + {"point_vertex_diameter_max", offsetof(SystemConstants, point_vertex_diameter_max), + type_float_}, + {"point_constant_diameter", offsetof(SystemConstants, point_constant_diameter), type_float2_}, + {"point_screen_diameter_to_ndc_radius", + offsetof(SystemConstants, point_screen_diameter_to_ndc_radius), type_float2_}, + {"textures_resolution_scaled", offsetof(SystemConstants, textures_resolution_scaled), + type_uint_}, + {"texture_swizzled_signs", offsetof(SystemConstants, texture_swizzled_signs), + type_uint4_array_2}, + {"texture_swizzles", offsetof(SystemConstants, texture_swizzles), type_uint4_array_4}, + {"alpha_test_reference", offsetof(SystemConstants, alpha_test_reference), type_float_}, + {"alpha_to_mask", offsetof(SystemConstants, alpha_to_mask), type_uint_}, + {"edram_32bpp_tile_pitch_dwords_scaled", + offsetof(SystemConstants, edram_32bpp_tile_pitch_dwords_scaled), type_uint_}, + {"edram_depth_base_dwords_scaled", offsetof(SystemConstants, edram_depth_base_dwords_scaled), + type_uint_}, + {"color_exp_bias", offsetof(SystemConstants, color_exp_bias), type_float4_}, + {"edram_poly_offset_front_scale", offsetof(SystemConstants, edram_poly_offset_front_scale), + type_float_}, + {"edram_poly_offset_back_scale", offsetof(SystemConstants, edram_poly_offset_back_scale), + type_float_}, + {"edram_poly_offset_front_offset", offsetof(SystemConstants, edram_poly_offset_front_offset), + type_float_}, + {"edram_poly_offset_back_offset", offsetof(SystemConstants, edram_poly_offset_back_offset), + type_float_}, + {"edram_stencil_front", offsetof(SystemConstants, edram_stencil_front), type_uint2_}, + {"edram_stencil_back", offsetof(SystemConstants, edram_stencil_back), type_uint2_}, + {"edram_rt_base_dwords_scaled", offsetof(SystemConstants, edram_rt_base_dwords_scaled), + type_uint4_}, + {"edram_rt_format_flags", offsetof(SystemConstants, edram_rt_format_flags), type_uint4_}, + {"edram_rt_blend_factors_ops", offsetof(SystemConstants, edram_rt_blend_factors_ops), + type_uint4_}, + {"edram_rt_keep_mask", offsetof(SystemConstants, edram_rt_keep_mask), type_uint4_array_2}, + {"edram_rt_clamp", offsetof(SystemConstants, edram_rt_clamp), type_float4_array_4}, + {"edram_blend_constant", offsetof(SystemConstants, edram_blend_constant), type_float4_}, + }; + id_vector_temp_.clear(); + id_vector_temp_.reserve(rex::countof(system_constants)); + for (size_t i = 0; i < rex::countof(system_constants); ++i) { + id_vector_temp_.push_back(system_constants[i].type); + } + spv::Id type_system_constants = builder_->makeStructType(id_vector_temp_, "XeSystemConstants"); + for (size_t i = 0; i < rex::countof(system_constants); ++i) { + const SystemConstant& system_constant = system_constants[i]; + builder_->addMemberName(type_system_constants, static_cast(i), + system_constant.name); + builder_->addMemberDecoration(type_system_constants, static_cast(i), + spv::DecorationOffset, int(system_constant.offset)); + } + builder_->addDecoration(type_system_constants, spv::DecorationBlock); + uniform_system_constants_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassUniform, type_system_constants, + "xe_uniform_system_constants"); + builder_->addDecoration(uniform_system_constants_, spv::DecorationDescriptorSet, + int(kDescriptorSetConstants)); + builder_->addDecoration(uniform_system_constants_, spv::DecorationBinding, + int(kConstantBufferSystem)); + if (features_.spirv_version >= spv::Spv_1_4) { + main_interface_.push_back(uniform_system_constants_); + } + + bool memexport_used = IsMemoryExportUsed(); + + if (!is_depth_only_fragment_shader_) { + // Common uniform buffer - float constants. + uint32_t float_constant_count = current_shader().constant_register_map().float_count; + if (float_constant_count) { + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeArrayType( + type_float4_, builder_->makeUintConstant(float_constant_count), sizeof(float) * 4)); + // Currently (as of October 24, 2020) makeArrayType only uses the stride + // to check if deduplication can be done - the array stride decoration + // needs to be applied explicitly. + builder_->addDecoration(id_vector_temp_.back(), spv::DecorationArrayStride, + sizeof(float) * 4); + spv::Id type_float_constants = builder_->makeStructType(id_vector_temp_, "XeFloatConstants"); + builder_->addMemberName(type_float_constants, 0, "float_constants"); + builder_->addMemberDecoration(type_float_constants, 0, spv::DecorationOffset, 0); + builder_->addDecoration(type_float_constants, spv::DecorationBlock); + uniform_float_constants_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassUniform, type_float_constants, + "xe_uniform_float_constants"); + builder_->addDecoration(uniform_float_constants_, spv::DecorationDescriptorSet, + int(kDescriptorSetConstants)); + builder_->addDecoration( + uniform_float_constants_, spv::DecorationBinding, + int(is_pixel_shader() ? kConstantBufferFloatPixel : kConstantBufferFloatVertex)); + if (features_.spirv_version >= spv::Spv_1_4) { + main_interface_.push_back(uniform_float_constants_); + } + } + + // Common uniform buffer - bool and loop constants. + // Uniform buffers must have std140 packing, so using arrays of 4-component + // vectors instead of scalar arrays because the latter would have padding to + // 16 bytes in each element. + id_vector_temp_.clear(); + // 256 bool constants. + id_vector_temp_.push_back( + builder_->makeArrayType(type_uint4_, builder_->makeUintConstant(2), sizeof(uint32_t) * 4)); + builder_->addDecoration(id_vector_temp_.back(), spv::DecorationArrayStride, + sizeof(uint32_t) * 4); + // 32 loop constants. + id_vector_temp_.push_back( + builder_->makeArrayType(type_uint4_, builder_->makeUintConstant(8), sizeof(uint32_t) * 4)); + builder_->addDecoration(id_vector_temp_.back(), spv::DecorationArrayStride, + sizeof(uint32_t) * 4); + spv::Id type_bool_loop_constants = + builder_->makeStructType(id_vector_temp_, "XeBoolLoopConstants"); + builder_->addMemberName(type_bool_loop_constants, 0, "bool_constants"); + builder_->addMemberDecoration(type_bool_loop_constants, 0, spv::DecorationOffset, 0); + builder_->addMemberName(type_bool_loop_constants, 1, "loop_constants"); + builder_->addMemberDecoration(type_bool_loop_constants, 1, spv::DecorationOffset, + sizeof(uint32_t) * 8); + builder_->addDecoration(type_bool_loop_constants, spv::DecorationBlock); + uniform_bool_loop_constants_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassUniform, + type_bool_loop_constants, "xe_uniform_bool_loop_constants"); + builder_->addDecoration(uniform_bool_loop_constants_, spv::DecorationDescriptorSet, + int(kDescriptorSetConstants)); + builder_->addDecoration(uniform_bool_loop_constants_, spv::DecorationBinding, + int(kConstantBufferBoolLoop)); + if (features_.spirv_version >= spv::Spv_1_4) { + main_interface_.push_back(uniform_bool_loop_constants_); + } + + // Common uniform buffer - fetch constants (32 x 6 uints packed in std140 as + // 4-component vectors). + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeArrayType( + type_uint4_, builder_->makeUintConstant(32 * 6 / 4), sizeof(uint32_t) * 4)); + builder_->addDecoration(id_vector_temp_.back(), spv::DecorationArrayStride, + sizeof(uint32_t) * 4); + spv::Id type_fetch_constants = builder_->makeStructType(id_vector_temp_, "XeFetchConstants"); + builder_->addMemberName(type_fetch_constants, 0, "fetch_constants"); + builder_->addMemberDecoration(type_fetch_constants, 0, spv::DecorationOffset, 0); + builder_->addDecoration(type_fetch_constants, spv::DecorationBlock); + uniform_fetch_constants_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassUniform, type_fetch_constants, + "xe_uniform_fetch_constants"); + builder_->addDecoration(uniform_fetch_constants_, spv::DecorationDescriptorSet, + int(kDescriptorSetConstants)); + builder_->addDecoration(uniform_fetch_constants_, spv::DecorationBinding, + int(kConstantBufferFetch)); + if (features_.spirv_version >= spv::Spv_1_4) { + main_interface_.push_back(uniform_fetch_constants_); + } + + // Common storage buffers - shared memory uint[], each 128 MB or larger, + // depending on what's possible on the device. + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeRuntimeArray(type_uint_)); + // Storage buffers have std430 packing, no padding to 4-component vectors. + builder_->addDecoration(id_vector_temp_.back(), spv::DecorationArrayStride, sizeof(uint32_t)); + spv::Id type_shared_memory = builder_->makeStructType(id_vector_temp_, "XeSharedMemory"); + builder_->addMemberName(type_shared_memory, 0, "shared_memory"); + builder_->addMemberDecoration(type_shared_memory, 0, spv::DecorationRestrict); + if (!memexport_used) { + builder_->addMemberDecoration(type_shared_memory, 0, spv::DecorationNonWritable); + } + builder_->addMemberDecoration(type_shared_memory, 0, spv::DecorationOffset, 0); + builder_->addDecoration(type_shared_memory, features_.spirv_version >= spv::Spv_1_3 + ? spv::DecorationBlock + : spv::DecorationBufferBlock); + unsigned int shared_memory_binding_count = 1 << GetSharedMemoryStorageBufferCountLog2(); + if (shared_memory_binding_count > 1) { + type_shared_memory = builder_->makeArrayType( + type_shared_memory, builder_->makeUintConstant(shared_memory_binding_count), 0); + } + buffers_shared_memory_ = builder_->createVariable(spv::NoPrecision, + features_.spirv_version >= spv::Spv_1_3 + ? spv::StorageClassStorageBuffer + : spv::StorageClassUniform, + type_shared_memory, "xe_shared_memory"); + builder_->addDecoration(buffers_shared_memory_, spv::DecorationDescriptorSet, + int(kDescriptorSetSharedMemoryAndEdram)); + builder_->addDecoration(buffers_shared_memory_, spv::DecorationBinding, 0); + if (features_.spirv_version >= spv::Spv_1_4) { + main_interface_.push_back(buffers_shared_memory_); + } + } + + if (is_vertex_shader()) { + StartVertexOrTessEvalShaderBeforeMain(); + } else if (is_pixel_shader()) { + StartFragmentShaderBeforeMain(); + } + + // Begin the main function. + std::vector main_param_types; + std::vector> main_precisions; + spv::Block* function_main_entry; + function_main_ = + builder_->makeFunctionEntry(spv::NoPrecision, type_void_, "main", main_param_types, + main_precisions, &function_main_entry); + + // Load the flags system constant since it may be used in many places. + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantFlags)); + main_system_constant_flags_ = + builder_->createLoad(builder_->createAccessChain(spv::StorageClassUniform, + uniform_system_constants_, id_vector_temp_), + spv::NoPrecision); + + if (!is_depth_only_fragment_shader_) { + // Begin ucode translation. Initialize everything, even without defined + // defaults, for safety. + var_main_predicate_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassFunction, type_bool_, + "xe_var_predicate", builder_->makeBoolConstant(false)); + var_main_loop_count_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassFunction, type_uint4_, + "xe_var_loop_count", const_uint4_0_); + var_main_address_register_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassFunction, type_int_, + "xe_var_address_register", const_int_0_); + var_main_loop_address_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassFunction, type_int4_, + "xe_var_loop_address", const_int4_0_); + var_main_previous_scalar_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassFunction, type_float_, + "xe_var_previous_scalar", const_float_0_); + var_main_vfetch_address_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassFunction, type_int_, + "xe_var_vfetch_address", const_int_0_); + var_main_tfetch_lod_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassFunction, type_float_, + "xe_var_tfetch_lod", const_float_0_); + var_main_tfetch_gradients_h_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassFunction, type_float3_, + "xe_var_tfetch_gradients_h", const_float3_0_); + var_main_tfetch_gradients_v_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassFunction, type_float3_, + "xe_var_tfetch_gradients_v", const_float3_0_); + if (register_count()) { + spv::Id type_register_array = + builder_->makeArrayType(type_float4_, builder_->makeUintConstant(register_count()), 1); + var_main_registers_ = builder_->createVariable(spv::NoPrecision, spv::StorageClassFunction, + type_register_array, "xe_var_registers"); + } + if (IsSpirvRectangleListVertexLoopEnabled()) { + var_main_rectangle_guest_vertex_index_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassFunction, type_uint_, + "xe_var_rectangle_guest_vertex_index", const_uint_0_); + spv::Id type_rectangle_per_vertex_array = + builder_->makeArrayType(type_output_per_vertex_, builder_->makeUintConstant(3), 0); + var_main_rectangle_per_vertex_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassFunction, + type_rectangle_per_vertex_array, "xe_var_rectangle_per_vertex"); + uint32_t interpolators_remaining = GetModificationInterpolatorMask(); + uint32_t interpolator_index; + while (rex::bit_scan_forward(interpolators_remaining, &interpolator_index)) { + interpolators_remaining &= ~(UINT32_C(1) << interpolator_index); + spv::Id type_rectangle_interpolator_array = + builder_->makeArrayType(type_float4_, builder_->makeUintConstant(3), 0); + var_main_rectangle_interpolators_[interpolator_index] = builder_->createVariable( + spv::NoPrecision, spv::StorageClassFunction, type_rectangle_interpolator_array, + fmt::format("xe_var_rectangle_interpolator_{}", interpolator_index).c_str()); + } + } + if (memexport_used) { + var_main_memexport_address_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassFunction, type_float4_, + "xe_var_memexport_address", const_float4_0_); + uint8_t memexport_eM_remaining = current_shader().memexport_eM_written(); + uint32_t memexport_eM_index; + while (rex::bit_scan_forward(memexport_eM_remaining, &memexport_eM_index)) { + memexport_eM_remaining &= ~(uint8_t(1) << memexport_eM_index); + var_main_memexport_data_[memexport_eM_index] = builder_->createVariable( + spv::NoPrecision, spv::StorageClassFunction, type_float4_, + fmt::format("xe_var_memexport_data_{}", memexport_eM_index).c_str(), const_float4_0_); + } + var_main_memexport_data_written_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassFunction, type_uint_, + "xe_var_memexport_data_written", const_uint_0_); + } + } + + // Write the execution model-specific prologue with access to variables in the + // main function. + if (is_vertex_shader()) { + StartVertexOrTessEvalShaderInMain(); + } else if (is_pixel_shader()) { + StartFragmentShaderInMain(); + } + + if (is_depth_only_fragment_shader_) { + return; + } + + // Open the main loop. + spv::Block& main_loop_pre_header = *builder_->getBuildPoint(); + main_loop_header_ = &builder_->makeNewBlock(); + spv::Block& main_loop_body = builder_->makeNewBlock(); + // Added later because the body has nested control flow, but according to the + // specification: + // "The order of blocks in a function must satisfy the rule that blocks appear + // before all blocks they dominate." + main_loop_continue_ = new spv::Block(builder_->getUniqueId(), *function_main_); + main_loop_merge_ = new spv::Block(builder_->getUniqueId(), *function_main_); + main_loop_exit_ = main_loop_merge_; + if (IsSpirvRectangleListVertexLoopEnabled()) { + // Need a block in the loop body to converge exits and to decide whether to + // continue with the next guest rectangle vertex. + main_loop_exit_ = new spv::Block(builder_->getUniqueId(), *function_main_); + } + builder_->createBranch(main_loop_header_); + + // If no jumps, don't create a switch, but still create a loop so exece can + // break. + bool has_main_switch = !current_shader().label_addresses().empty(); + + // Main loop header - based on whether it's the first iteration (entered from + // the function or from the continuation), choose the program counter. + builder_->setBuildPoint(main_loop_header_); + spv::Id main_loop_pc_current = spv::NoResult; + if (has_main_switch) { + // OpPhi must be the first in the block. + id_vector_temp_.clear(); + id_vector_temp_.push_back(const_int_0_); + id_vector_temp_.push_back(main_loop_pre_header.getId()); + main_loop_pc_next_ = builder_->getUniqueId(); + id_vector_temp_.push_back(main_loop_pc_next_); + id_vector_temp_.push_back(main_loop_continue_->getId()); + main_loop_pc_current = builder_->createOp(spv::OpPhi, type_int_, id_vector_temp_); + } + uint_vector_temp_.clear(); + builder_->createLoopMerge(main_loop_exit_, main_loop_continue_, spv::LoopControlDontUnrollMask, + uint_vector_temp_); + builder_->createBranch(&main_loop_body); + + // Main loop body. + builder_->setBuildPoint(&main_loop_body); + if (has_main_switch) { + // Create the program counter switch with cases for every label and for + // label 0. + main_switch_header_ = builder_->getBuildPoint(); + main_switch_merge_ = new spv::Block(builder_->getUniqueId(), *function_main_); + builder_->createSelectionMerge(main_switch_merge_, spv::SelectionControlDontFlattenMask); + main_switch_op_ = std::make_unique(spv::OpSwitch); + main_switch_op_->addIdOperand(main_loop_pc_current); + main_switch_op_->addIdOperand(main_switch_merge_->getId()); + // The default case (the merge here) must have the header as a predecessor. + main_switch_merge_->addPredecessor(main_switch_header_); + // The instruction will be inserted later, when all cases are filled. + // Insert and enter case 0. + spv::Block* main_switch_case_0_block = new spv::Block(builder_->getUniqueId(), *function_main_); + main_switch_op_->addImmediateOperand(0); + main_switch_op_->addIdOperand(main_switch_case_0_block->getId()); + // Every switch case must have the OpSelectionMerge/OpSwitch block as a + // predecessor. + main_switch_case_0_block->addPredecessor(main_switch_header_); + function_main_->addBlock(main_switch_case_0_block); + builder_->setBuildPoint(main_switch_case_0_block); + } +} + +std::vector SpirvShaderTranslator::CompleteTranslation() { + bool rectangle_vertex_loop = IsSpirvRectangleListVertexLoopEnabled(); + if (!is_depth_only_fragment_shader_) { + // Close flow control within the last switch case. + CloseExecConditionals(); + bool has_main_switch = !current_shader().label_addresses().empty(); + // After the final exec (if it happened to be not exece, which would already + // have a break branch), break from the switch if it exists, or from the + // loop it doesn't. + if (!builder_->getBuildPoint()->isTerminated()) { + builder_->createBranch(has_main_switch ? main_switch_merge_ : main_loop_merge_); + } + if (has_main_switch) { + // Insert the switch instruction with all cases added as operands. + builder_->setBuildPoint(main_switch_header_); + builder_->getBuildPoint()->addInstruction(std::move(main_switch_op_)); + // Build the main switch merge, breaking out of the loop after falling + // through the end or breaking from exece (only continuing if a jump - + // from a guest loop or from jmp/call - was made). + function_main_->addBlock(main_switch_merge_); + builder_->setBuildPoint(main_switch_merge_); + builder_->createBranch(main_loop_merge_); + } + + // Main loop continuation - choose the program counter based on the path + // taken (-1 if not from a jump as a safe fallback, which would result in + // not hitting any switch case and reaching the final break in the body). + function_main_->addBlock(main_loop_continue_); + builder_->setBuildPoint(main_loop_continue_); + if (has_main_switch) { + // OpPhi, if added, must be the first in the block. + // If labels were added, but not jumps (for example, due to the call + // instruction not being implemented as of October 18, 2020), send an + // impossible program counter value (-1) to the OpPhi at the next + // iteration. + if (main_switch_next_pc_phi_operands_.empty()) { + main_switch_next_pc_phi_operands_.push_back(builder_->makeIntConstant(-1)); + } + std::unique_ptr main_loop_pc_next_op = std::make_unique( + main_loop_pc_next_, type_int_, + main_switch_next_pc_phi_operands_.size() >= 2 ? spv::OpPhi : spv::OpCopyObject); + for (spv::Id operand : main_switch_next_pc_phi_operands_) { + main_loop_pc_next_op->addIdOperand(operand); + } + builder_->getBuildPoint()->addInstruction(std::move(main_loop_pc_next_op)); + } + builder_->createBranch(main_loop_header_); + + // Add the main loop merge block and go back to the function. + function_main_->addBlock(main_loop_merge_); + builder_->setBuildPoint(main_loop_merge_); + if (rectangle_vertex_loop) { + // For rectangle-list fallback without geometry shaders, run the guest + // vertex shader 3 times (for all source vertices), then choose or + // synthesize the output for the current host strip vertex. + Modification shader_modification = GetSpirvShaderModification(); + uint32_t clip_distance_count = shader_modification.GetVertexClipDistanceCount(); + uint32_t cull_distance_count = shader_modification.GetVertexCullDistanceCount(); + + CompleteVertexOrTessEvalShaderInMain(); + + spv::Id rectangle_guest_vertex_index = + builder_->createLoad(var_main_rectangle_guest_vertex_index_, spv::NoPrecision); + spv::Id rectangle_guest_vertex_index_int = + builder_->createUnaryOp(spv::OpBitcast, type_int_, rectangle_guest_vertex_index); + + // Store current iteration outputs. + id_vector_temp_.clear(); + id_vector_temp_.push_back(rectangle_guest_vertex_index_int); + builder_->createStore( + builder_->createLoad(output_per_vertex_, spv::NoPrecision), + builder_->createAccessChain(spv::StorageClassFunction, var_main_rectangle_per_vertex_, + id_vector_temp_)); + uint32_t interpolators_remaining = GetModificationInterpolatorMask(); + uint32_t interpolator_index; + while (rex::bit_scan_forward(interpolators_remaining, &interpolator_index)) { + interpolators_remaining &= ~(UINT32_C(1) << interpolator_index); + id_vector_temp_.clear(); + id_vector_temp_.push_back(rectangle_guest_vertex_index_int); + builder_->createStore( + builder_->createLoad(input_output_interpolators_[interpolator_index], spv::NoPrecision), + builder_->createAccessChain(spv::StorageClassFunction, + var_main_rectangle_interpolators_[interpolator_index], + id_vector_temp_)); + } + + spv::Id rectangle_guest_vertex_is_last = builder_->createBinOp( + spv::OpIEqual, type_bool_, rectangle_guest_vertex_index, builder_->makeUintConstant(2)); + SpirvBuilder::IfBuilder if_not_last_guest_vertex( + builder_->createUnaryOp(spv::OpLogicalNot, type_bool_, rectangle_guest_vertex_is_last), + spv::SelectionControlDontFlattenMask, *builder_); + { + spv::Id rectangle_guest_vertex_index_next = builder_->createBinOp( + spv::OpIAdd, type_uint_, rectangle_guest_vertex_index, builder_->makeUintConstant(1)); + builder_->createStore(rectangle_guest_vertex_index_next, + var_main_rectangle_guest_vertex_index_); + + // Reinitialize per-vertex execution state before running the translated + // guest shader for the next rectangle vertex. + builder_->createStore(builder_->makeBoolConstant(false), var_main_predicate_); + builder_->createStore(const_uint4_0_, var_main_loop_count_); + builder_->createStore(const_int_0_, var_main_address_register_); + builder_->createStore(const_int4_0_, var_main_loop_address_); + builder_->createStore(const_float_0_, var_main_previous_scalar_); + builder_->createStore(const_int_0_, var_main_vfetch_address_); + builder_->createStore(const_float_0_, var_main_tfetch_lod_); + builder_->createStore(const_float3_0_, var_main_tfetch_gradients_h_); + builder_->createStore(const_float3_0_, var_main_tfetch_gradients_v_); + for (uint32_t i = 0; i < register_count(); ++i) { + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(int(i))); + builder_->createStore(const_float4_0_, + builder_->createAccessChain(spv::StorageClassFunction, + var_main_registers_, id_vector_temp_)); + } + uint32_t iteration_interpolators_remaining = GetModificationInterpolatorMask(); + while (rex::bit_scan_forward(iteration_interpolators_remaining, &interpolator_index)) { + iteration_interpolators_remaining &= ~(UINT32_C(1) << interpolator_index); + builder_->createStore(const_float4_0_, input_output_interpolators_[interpolator_index]); + } + if (var_main_point_size_edge_flag_kill_vertex_ != spv::NoResult) { + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeFloatConstant(-1.0f)); + id_vector_temp_.push_back(const_float_0_); + id_vector_temp_.push_back(const_float_0_); + builder_->createStore(builder_->makeCompositeConstant(type_float3_, id_vector_temp_), + var_main_point_size_edge_flag_kill_vertex_); + } + if (IsMemoryExportUsed()) { + // Flush and reinitialize memexport state for the next guest rectangle + // vertex iteration in this host invocation. + ExportToMemory(current_shader().memexport_eM_potentially_written_before_end()); + builder_->createStore(const_float4_0_, var_main_memexport_address_); + uint8_t memexport_eM_remaining = current_shader().memexport_eM_written(); + uint32_t memexport_eM_index; + while (rex::bit_scan_forward(memexport_eM_remaining, &memexport_eM_index)) { + memexport_eM_remaining &= ~(uint8_t(1) << memexport_eM_index); + builder_->createStore(const_float4_0_, var_main_memexport_data_[memexport_eM_index]); + } + builder_->createStore(const_uint_0_, var_main_memexport_data_written_); + } + + // Load the next guest vertex index into r0.x. + if (register_count()) { + spv::Id rectangle_two_triangle_strip_vertex_index = + builder_->createUnaryOp(spv::OpBitcast, type_uint_, + builder_->createLoad(input_vertex_index_, spv::NoPrecision)); + spv::Id rectangle_primitive_index = builder_->createBinOp( + spv::OpShiftRightLogical, type_uint_, rectangle_two_triangle_strip_vertex_index, + builder_->makeUintConstant(2)); + spv::Id rectangle_vertex_index = builder_->createBinOp( + spv::OpIAdd, type_uint_, + builder_->createBinOp(spv::OpIMul, type_uint_, rectangle_primitive_index, + builder_->makeUintConstant(3)), + rectangle_guest_vertex_index_next); + spv::Id rectangle_load_vertex_index = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(static_cast( + kSysFlag_ComputeOrPrimitiveVertexIndexLoad))), + const_uint_0_); + SpirvBuilder::IfBuilder rectangle_load_vertex_index_if( + rectangle_load_vertex_index, spv::SelectionControlDontFlattenMask, *builder_); + spv::Id rectangle_loaded_vertex_index; + { + spv::Id rectangle_vertex_index_is_32bit = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(static_cast( + kSysFlag_ComputeOrPrimitiveVertexIndexLoad32Bit))), + const_uint_0_); + id_vector_temp_.clear(); + id_vector_temp_.push_back( + builder_->makeIntConstant(kSystemConstantVertexIndexLoadAddress)); + spv::Id rectangle_vertex_index_address = builder_->createBinOp( + spv::OpIAdd, type_uint_, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision), + builder_->createBinOp(spv::OpShiftLeftLogical, type_uint_, rectangle_vertex_index, + builder_->createTriOp(spv::OpSelect, type_uint_, + rectangle_vertex_index_is_32bit, + builder_->makeUintConstant(2), + builder_->makeUintConstant(1)))); + rectangle_loaded_vertex_index = LoadUint32FromSharedMemory( + builder_->createUnaryOp(spv::OpBitcast, type_int_, + builder_->createBinOp(spv::OpShiftRightLogical, type_uint_, + rectangle_vertex_index_address, + builder_->makeUintConstant(2)))); + rectangle_loaded_vertex_index = builder_->createTriOp( + spv::OpSelect, type_uint_, rectangle_vertex_index_is_32bit, + rectangle_loaded_vertex_index, + builder_->createTriOp( + spv::OpBitFieldUExtract, type_uint_, rectangle_loaded_vertex_index, + builder_->createBinOp(spv::OpShiftLeftLogical, type_uint_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, + rectangle_vertex_index_address, + builder_->makeUintConstant(2)), + builder_->makeUintConstant(3)), + builder_->makeUintConstant(16))); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantVertexIndexEndian)); + rectangle_loaded_vertex_index = EndianSwap32Uint( + rectangle_loaded_vertex_index, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision)); + } + rectangle_load_vertex_index_if.makeEndIf(); + rectangle_vertex_index = rectangle_load_vertex_index_if.createMergePhi( + rectangle_loaded_vertex_index, rectangle_vertex_index); + + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantVertexBaseIndex)); + spv::Id rectangle_vertex_base_index = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantVertexIndexMin)); + spv::Id rectangle_vertex_index_min = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantVertexIndexMax)); + spv::Id rectangle_vertex_index_max = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + rectangle_vertex_index = builder_->createBinOp( + spv::OpIAdd, type_uint_, rectangle_vertex_index, + builder_->createUnaryOp(spv::OpBitcast, type_uint_, rectangle_vertex_base_index)); + rectangle_vertex_index = + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, rectangle_vertex_index, + builder_->makeUintConstant(xenos::kVertexIndexMask)); + rectangle_vertex_index = builder_->createTriBuiltinCall( + type_uint_, ext_inst_glsl_std_450_, GLSLstd450UClamp, rectangle_vertex_index, + rectangle_vertex_index_min, rectangle_vertex_index_max); + spv::Id rectangle_vertex_index_float = + builder_->createUnaryOp(spv::OpConvertUToF, type_float_, rectangle_vertex_index); + id_vector_temp_.clear(); + id_vector_temp_.push_back(const_int_0_); + id_vector_temp_.push_back(const_int_0_); + builder_->createStore(rectangle_vertex_index_float, + builder_->createAccessChain(spv::StorageClassFunction, + var_main_registers_, id_vector_temp_)); + } + + if (has_main_switch) { + main_switch_next_pc_phi_operands_.push_back(const_int_0_); + main_switch_next_pc_phi_operands_.push_back(builder_->getBuildPoint()->getId()); + } + builder_->createBranch(main_loop_continue_); + } + if_not_last_guest_vertex.makeBeginElse(); + { + spv::Id rectangle_host_vertex_in_primitive = builder_->createBinOp( + spv::OpBitwiseAnd, type_uint_, + builder_->createUnaryOp(spv::OpBitcast, type_uint_, + builder_->createLoad(input_vertex_index_, spv::NoPrecision)), + builder_->makeUintConstant(3)); + spv::Id rectangle_host_vertex_is_synthetic = + builder_->createBinOp(spv::OpIEqual, type_bool_, rectangle_host_vertex_in_primitive, + builder_->makeUintConstant(3)); + spv::Id rectangle_host_vertex_is_0 = builder_->createBinOp( + spv::OpIEqual, type_bool_, rectangle_host_vertex_in_primitive, const_uint_0_); + spv::Id rectangle_host_vertex_is_1 = + builder_->createBinOp(spv::OpIEqual, type_bool_, rectangle_host_vertex_in_primitive, + builder_->makeUintConstant(1)); + + auto load_rectangle_position_xy = [this](spv::Id vertex_index, uint32_t component) { + id_vector_temp_.clear(); + id_vector_temp_.push_back(vertex_index); + id_vector_temp_.push_back(builder_->makeIntConstant(kOutputPerVertexMemberPosition)); + id_vector_temp_.push_back(builder_->makeIntConstant(int(component))); + return builder_->createLoad( + builder_->createAccessChain(spv::StorageClassFunction, var_main_rectangle_per_vertex_, + id_vector_temp_), + spv::NoPrecision); + }; + + spv::Id const_int_0 = builder_->makeIntConstant(0); + spv::Id const_int_1 = builder_->makeIntConstant(1); + spv::Id const_int_2 = builder_->makeIntConstant(2); + spv::Id const_int_3 = builder_->makeIntConstant(3); + + spv::Id edge_lengths[3]; + for (uint32_t i = 0; i < 3; ++i) { + spv::Id edge_0 = builder_->makeIntConstant(int((1 + i) % 3)); + spv::Id edge_1 = builder_->makeIntConstant(int((2 + i) % 3)); + spv::Id edge_x = + builder_->createBinOp(spv::OpFSub, type_float_, load_rectangle_position_xy(edge_1, 0), + load_rectangle_position_xy(edge_0, 0)); + spv::Id edge_y = + builder_->createBinOp(spv::OpFSub, type_float_, load_rectangle_position_xy(edge_1, 1), + load_rectangle_position_xy(edge_0, 1)); + edge_lengths[i] = builder_->createBinOp( + spv::OpFAdd, type_float_, + builder_->createBinOp(spv::OpFMul, type_float_, edge_x, edge_x), + builder_->createBinOp(spv::OpFMul, type_float_, edge_y, edge_y)); + } + + spv::Id rectangle_vertex_indices[3]; + rectangle_vertex_indices[0] = builder_->createTriOp( + spv::OpSelect, type_int_, + builder_->createBinOp(spv::OpLogicalAnd, type_bool_, + builder_->createBinOp(spv::OpFOrdGreaterThan, type_bool_, + edge_lengths[0], edge_lengths[1]), + builder_->createBinOp(spv::OpFOrdGreaterThan, type_bool_, + edge_lengths[0], edge_lengths[2])), + const_int_0, + builder_->createTriOp(spv::OpSelect, type_int_, + builder_->createBinOp(spv::OpFOrdGreaterThan, type_bool_, + edge_lengths[1], edge_lengths[2]), + const_int_1, const_int_2)); + for (uint32_t i = 1; i < 3; ++i) { + spv::Id vertex_index_without_wrapping = + builder_->createBinOp(spv::OpIAdd, type_int_, rectangle_vertex_indices[0], + builder_->makeIntConstant(int(i))); + rectangle_vertex_indices[i] = builder_->createTriOp( + spv::OpSelect, type_int_, + builder_->createBinOp(spv::OpSLessThan, type_bool_, vertex_index_without_wrapping, + const_int_3), + vertex_index_without_wrapping, + builder_->createBinOp(spv::OpISub, type_int_, vertex_index_without_wrapping, + const_int_3)); + } + + auto select_rectangle_vertex_component = + [this, rectangle_host_vertex_is_0, rectangle_host_vertex_is_1]( + spv::Id value_0, spv::Id value_1, spv::Id value_2, spv::Id type) { + return builder_->createTriOp( + spv::OpSelect, type, rectangle_host_vertex_is_0, value_0, + builder_->createTriOp(spv::OpSelect, type, rectangle_host_vertex_is_1, value_1, + value_2)); + }; + + interpolators_remaining = GetModificationInterpolatorMask(); + while (rex::bit_scan_forward(interpolators_remaining, &interpolator_index)) { + interpolators_remaining &= ~(UINT32_C(1) << interpolator_index); + id_vector_temp_.clear(); + id_vector_temp_.push_back(rectangle_vertex_indices[0]); + spv::Id interpolator_0 = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassFunction, + var_main_rectangle_interpolators_[interpolator_index], + id_vector_temp_), + spv::NoPrecision); + id_vector_temp_[0] = rectangle_vertex_indices[1]; + spv::Id interpolator_1 = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassFunction, + var_main_rectangle_interpolators_[interpolator_index], + id_vector_temp_), + spv::NoPrecision); + id_vector_temp_[0] = rectangle_vertex_indices[2]; + spv::Id interpolator_2 = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassFunction, + var_main_rectangle_interpolators_[interpolator_index], + id_vector_temp_), + spv::NoPrecision); + spv::Id interpolator_original = select_rectangle_vertex_component( + interpolator_0, interpolator_1, interpolator_2, type_float4_); + spv::Id interpolator_synthetic = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float4_, + builder_->createNoContractionBinOp(spv::OpFSub, type_float4_, interpolator_1, + interpolator_0), + interpolator_2); + builder_->createStore( + builder_->createTriOp(spv::OpSelect, type_float4_, rectangle_host_vertex_is_synthetic, + interpolator_synthetic, interpolator_original), + input_output_interpolators_[interpolator_index]); + } + + auto load_rectangle_per_vertex_component = + [this](spv::Id vertex_index, uint32_t member_index, spv::Id component_index) { + id_vector_temp_.clear(); + id_vector_temp_.push_back(vertex_index); + id_vector_temp_.push_back(builder_->makeIntConstant(int(member_index))); + if (component_index != spv::NoResult) { + id_vector_temp_.push_back(component_index); + } + return builder_->createLoad( + builder_->createAccessChain(spv::StorageClassFunction, + var_main_rectangle_per_vertex_, id_vector_temp_), + spv::NoPrecision); + }; + + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kOutputPerVertexMemberPosition)); + spv::Id rectangle_position_ptr = builder_->createAccessChain( + spv::StorageClassOutput, output_per_vertex_, id_vector_temp_); + spv::Id position_0 = load_rectangle_per_vertex_component( + rectangle_vertex_indices[0], kOutputPerVertexMemberPosition, spv::NoResult); + spv::Id position_1 = load_rectangle_per_vertex_component( + rectangle_vertex_indices[1], kOutputPerVertexMemberPosition, spv::NoResult); + spv::Id position_2 = load_rectangle_per_vertex_component( + rectangle_vertex_indices[2], kOutputPerVertexMemberPosition, spv::NoResult); + spv::Id position_original = + select_rectangle_vertex_component(position_0, position_1, position_2, type_float4_); + spv::Id position_synthetic = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float4_, + builder_->createNoContractionBinOp(spv::OpFSub, type_float4_, position_1, position_0), + position_2); + builder_->createStore( + builder_->createTriOp(spv::OpSelect, type_float4_, rectangle_host_vertex_is_synthetic, + position_synthetic, position_original), + rectangle_position_ptr); + + auto write_rectangle_distance_member = + [this, &select_rectangle_vertex_component, rectangle_host_vertex_is_synthetic, + &load_rectangle_per_vertex_component, + rectangle_vertex_indices](uint32_t member_index, uint32_t component_count) { + for (uint32_t i = 0; i < component_count; ++i) { + spv::Id component_index = builder_->makeIntConstant(int(i)); + spv::Id value_0 = load_rectangle_per_vertex_component( + rectangle_vertex_indices[0], member_index, component_index); + spv::Id value_1 = load_rectangle_per_vertex_component( + rectangle_vertex_indices[1], member_index, component_index); + spv::Id value_2 = load_rectangle_per_vertex_component( + rectangle_vertex_indices[2], member_index, component_index); + spv::Id value_original = + select_rectangle_vertex_component(value_0, value_1, value_2, type_float_); + spv::Id value_synthetic = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, + builder_->createNoContractionBinOp(spv::OpFSub, type_float_, value_1, value_0), + value_2); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(int(member_index))); + id_vector_temp_.push_back(component_index); + builder_->createStore( + builder_->createTriOp(spv::OpSelect, type_float_, + rectangle_host_vertex_is_synthetic, value_synthetic, + value_original), + builder_->createAccessChain(spv::StorageClassOutput, output_per_vertex_, + id_vector_temp_)); + } + }; + + if (clip_distance_count && output_per_vertex_member_clip_distance_ != UINT32_MAX) { + write_rectangle_distance_member(output_per_vertex_member_clip_distance_, + clip_distance_count); + } + if (cull_distance_count && output_per_vertex_member_cull_distance_ != UINT32_MAX) { + write_rectangle_distance_member(output_per_vertex_member_cull_distance_, + cull_distance_count); + } + } + if_not_last_guest_vertex.makeEndIf(); + } + if (main_loop_exit_ != main_loop_merge_) { + if (!builder_->getBuildPoint()->isTerminated()) { + builder_->createBranch(main_loop_exit_); + } + function_main_->addBlock(main_loop_exit_); + builder_->setBuildPoint(main_loop_exit_); + } + } + + // Write data for the last memexport. + ExportToMemory(current_shader().memexport_eM_potentially_written_before_end()); + + if (is_vertex_shader() && !IsSpirvComputeShader() && !rectangle_vertex_loop) { + CompleteVertexOrTessEvalShaderInMain(); + } else if (is_pixel_shader()) { + CompleteFragmentShaderInMain(); + } + + // End the main function. + builder_->leaveFunction(); + + // Make the main function the entry point. + spv::ExecutionModel execution_model; + if (is_pixel_shader()) { + execution_model = spv::ExecutionModelFragment; + builder_->addExecutionMode(function_main_, spv::ExecutionModeOriginUpperLeft); + if (output_fragment_depth_ != spv::NoResult) { + builder_->addExecutionMode(function_main_, spv::ExecutionModeDepthReplacing); + if (!current_shader().writes_depth() && + GetSpirvShaderModification().pixel.depth_stencil_mode == + Modification::DepthStencilMode::kFloat24Truncating) { + builder_->addExecutionMode(function_main_, spv::ExecutionModeDepthLess); + } + } + if (IsExecutionModeEarlyFragmentTests()) { + builder_->addExecutionMode(function_main_, spv::ExecutionModeEarlyFragmentTests); + } + if (edram_fragment_shader_interlock_) { + // Accessing per-sample values, so interlocking just when there's common + // coverage is enough if the device exposes that. + if (features_.fragment_shader_sample_interlock) { + builder_->addCapability(spv::CapabilityFragmentShaderSampleInterlockEXT); + builder_->addExecutionMode(function_main_, spv::ExecutionModeSampleInterlockOrderedEXT); + } else { + builder_->addCapability(spv::CapabilityFragmentShaderPixelInterlockEXT); + builder_->addExecutionMode(function_main_, spv::ExecutionModePixelInterlockOrderedEXT); + } + } + } else { + assert_true(is_vertex_shader()); + bool is_compute_shader = IsSpirvComputeShader(); + bool is_tess_eval_shader = IsSpirvTessEvalShader(); + execution_model = is_compute_shader + ? spv::ExecutionModelGLCompute + : (is_tess_eval_shader ? spv::ExecutionModelTessellationEvaluation + : spv::ExecutionModelVertex); + if (is_compute_shader) { + builder_->addExecutionMode(function_main_, spv::ExecutionModeLocalSize, 1, 1, 1); + } else if (is_tess_eval_shader) { + Modification shader_modification = GetSpirvShaderModification(); + switch (shader_modification.vertex.host_vertex_shader_type) { + case Shader::HostVertexShaderType::kLineDomainCPIndexed: + case Shader::HostVertexShaderType::kLineDomainPatchIndexed: + builder_->addExecutionMode(function_main_, spv::ExecutionModeIsolines); + break; + case Shader::HostVertexShaderType::kTriangleDomainCPIndexed: + case Shader::HostVertexShaderType::kTriangleDomainPatchIndexed: + builder_->addExecutionMode(function_main_, spv::ExecutionModeTriangles); + break; + case Shader::HostVertexShaderType::kQuadDomainCPIndexed: + case Shader::HostVertexShaderType::kQuadDomainPatchIndexed: + builder_->addExecutionMode(function_main_, spv::ExecutionModeQuads); + break; + default: + assert_unhandled_case(shader_modification.vertex.host_vertex_shader_type); + break; + } + builder_->addExecutionMode(function_main_, (shader_modification.vertex.tessellation_mode == + uint32_t(xenos::TessellationMode::kDiscrete)) + ? spv::ExecutionModeSpacingEqual + : spv::ExecutionModeSpacingFractionalEven); + builder_->addExecutionMode(function_main_, spv::ExecutionModeVertexOrderCw); + } + } + if (features_.denorm_flush_to_zero_float32) { + // Flush to zero, similar to the real hardware, also for things like Shader + // Model 3 multiplication emulation. + builder_->addCapability(spv::CapabilityDenormFlushToZero); + builder_->addExecutionMode(function_main_, spv::ExecutionModeDenormFlushToZero, 32); + } + if (features_.signed_zero_inf_nan_preserve_float32) { + // Signed zero used to get VFACE from ps_param_gen, also special behavior + // for infinity in certain instructions (such as logarithm, reciprocal, + // muls_prev2). + builder_->addCapability(spv::CapabilitySignedZeroInfNanPreserve); + builder_->addExecutionMode(function_main_, spv::ExecutionModeSignedZeroInfNanPreserve, 32); + } + if (features_.rounding_mode_rte_float32) { + builder_->addCapability(spv::CapabilityRoundingModeRTE); + builder_->addExecutionMode(function_main_, spv::ExecutionModeRoundingModeRTE, 32); + } + spv::Instruction* entry_point = builder_->addEntryPoint(execution_model, function_main_, "main"); + for (spv::Id interface_id : main_interface_) { + entry_point->addIdOperand(interface_id); + } + + if (!is_depth_only_fragment_shader_) { + // Specify the binding indices for samplers when the number of textures is + // known, as samplers are located after images in the texture descriptor + // set. + size_t texture_binding_count = texture_bindings_.size(); + size_t sampler_binding_count = sampler_bindings_.size(); + for (size_t i = 0; i < sampler_binding_count; ++i) { + builder_->addDecoration(sampler_bindings_[i].variable, spv::DecorationBinding, + int(texture_binding_count + i)); + } + } + + // TODO(Triang3l): Avoid copy? + std::vector module_uints; + builder_->dump(module_uints); + std::vector module_bytes; + module_bytes.reserve(sizeof(unsigned int) * module_uints.size()); + module_bytes.insert(module_bytes.cend(), reinterpret_cast(module_uints.data()), + reinterpret_cast(module_uints.data()) + + sizeof(unsigned int) * module_uints.size()); + return module_bytes; +} + +void SpirvShaderTranslator::PostTranslation() { + Shader::Translation& translation = current_translation(); + if (!translation.is_valid()) { + return; + } + SpirvShader* spirv_shader = dynamic_cast(&translation.shader()); + if (spirv_shader && + !spirv_shader->bindings_setup_entered_.test_and_set(std::memory_order_relaxed)) { + spirv_shader->texture_bindings_.clear(); + spirv_shader->texture_bindings_.reserve(texture_bindings_.size()); + for (const TextureBinding& translator_binding : texture_bindings_) { + SpirvShader::TextureBinding& shader_binding = spirv_shader->texture_bindings_.emplace_back(); + // For a stable hash. + std::memset(&shader_binding, 0, sizeof(shader_binding)); + shader_binding.fetch_constant = translator_binding.fetch_constant; + shader_binding.dimension = translator_binding.dimension; + shader_binding.is_signed = translator_binding.is_signed; + spirv_shader->used_texture_mask_ |= UINT32_C(1) << translator_binding.fetch_constant; + } + spirv_shader->sampler_bindings_.clear(); + spirv_shader->sampler_bindings_.reserve(sampler_bindings_.size()); + for (const SamplerBinding& translator_binding : sampler_bindings_) { + SpirvShader::SamplerBinding& shader_binding = spirv_shader->sampler_bindings_.emplace_back(); + shader_binding.fetch_constant = translator_binding.fetch_constant; + shader_binding.mag_filter = translator_binding.mag_filter; + shader_binding.min_filter = translator_binding.min_filter; + shader_binding.mip_filter = translator_binding.mip_filter; + shader_binding.aniso_filter = translator_binding.aniso_filter; + } + } +} + +void SpirvShaderTranslator::ProcessLabel(uint32_t cf_index) { + if (cf_index == 0) { + // 0 already added in the beginning. + return; + } + + assert_false(current_shader().label_addresses().empty()); + + // Close flow control within the previous switch case. + CloseExecConditionals(); + + spv::Function& function = builder_->getBuildPoint()->getParent(); + // Create the next switch case and fallthrough to it. + spv::Block* new_case = new spv::Block(builder_->getUniqueId(), function); + main_switch_op_->addImmediateOperand(cf_index); + main_switch_op_->addIdOperand(new_case->getId()); + // Every switch case must have the OpSelectionMerge/OpSwitch block as a + // predecessor. + new_case->addPredecessor(main_switch_header_); + // The previous block may have already been terminated if was exece. + if (!builder_->getBuildPoint()->isTerminated()) { + builder_->createBranch(new_case); + } + function.addBlock(new_case); + builder_->setBuildPoint(new_case); +} + +void SpirvShaderTranslator::ProcessExecInstructionBegin(const ParsedExecInstruction& instr) { + UpdateExecConditionals(instr.type, instr.bool_constant_index, instr.condition); +} + +void SpirvShaderTranslator::ProcessExecInstructionEnd(const ParsedExecInstruction& instr) { + if (instr.is_end) { + // Break out of the main switch (if exists) and the main loop. + CloseInstructionPredication(); + if (!builder_->getBuildPoint()->isTerminated()) { + builder_->createBranch(current_shader().label_addresses().empty() ? main_loop_merge_ + : main_switch_merge_); + } + } + UpdateExecConditionals(instr.type, instr.bool_constant_index, instr.condition); +} + +void SpirvShaderTranslator::ProcessLoopStartInstruction(const ParsedLoopStartInstruction& instr) { + // loop il, L - loop with loop data il, end @ L + + // Loop control is outside execs - actually close the last exec. + CloseExecConditionals(); + + EnsureBuildPointAvailable(); + + id_vector_temp_.clear(); + // Loop constants (member 1). + id_vector_temp_.push_back(builder_->makeIntConstant(1)); + // 4-component vector. + id_vector_temp_.push_back(builder_->makeIntConstant(int(instr.loop_constant_index >> 2))); + // Scalar within the vector. + id_vector_temp_.push_back(builder_->makeIntConstant(int(instr.loop_constant_index & 3))); + // Count (unsigned) in bits 0:7 of the loop constant (struct member 1), + // initial aL (unsigned) in 8:15. + spv::Id loop_constant = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_bool_loop_constants_, + id_vector_temp_), + spv::NoPrecision); + + spv::Id const_int_8 = builder_->makeIntConstant(8); + + // Push the count to the loop count stack - move XYZ to YZW and set X to the + // new iteration count (swizzling the way glslang does it for similar GLSL). + spv::Id loop_count_stack_old = builder_->createLoad(var_main_loop_count_, spv::NoPrecision); + spv::Id loop_count_new = builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, loop_constant, + const_int_0_, const_int_8); + id_vector_temp_.clear(); + id_vector_temp_.push_back(loop_count_new); + for (unsigned int i = 0; i < 3; ++i) { + id_vector_temp_.push_back( + builder_->createCompositeExtract(loop_count_stack_old, type_uint_, i)); + } + builder_->createStore(builder_->createCompositeConstruct(type_uint4_, id_vector_temp_), + var_main_loop_count_); + + // Push aL - keep the same value as in the previous loop if repeating, or the + // new one otherwise. + spv::Id address_relative_stack_old = + builder_->createLoad(var_main_loop_address_, spv::NoPrecision); + id_vector_temp_.clear(); + if (instr.is_repeat) { + id_vector_temp_.emplace_back(); + } else { + id_vector_temp_.push_back( + builder_->createUnaryOp(spv::OpBitcast, type_int_, + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, + loop_constant, const_int_8, const_int_8))); + } + for (unsigned int i = 0; i < 3; ++i) { + id_vector_temp_.push_back( + builder_->createCompositeExtract(address_relative_stack_old, type_int_, i)); + } + if (instr.is_repeat) { + id_vector_temp_[0] = id_vector_temp_[1]; + } + builder_->createStore(builder_->createCompositeConstruct(type_int4_, id_vector_temp_), + var_main_loop_address_); + + // Break (jump to the skip label) if the loop counter is 0 (since the + // condition is checked in the end). + spv::Block& head_block = *builder_->getBuildPoint(); + spv::Id loop_count_zero = + builder_->createBinOp(spv::OpIEqual, type_bool_, loop_count_new, const_uint_0_); + spv::Block& skip_block = builder_->makeNewBlock(); + spv::Block& body_block = builder_->makeNewBlock(); + builder_->createSelectionMerge(&body_block, spv::SelectionControlMaskNone); + { + std::unique_ptr branch_conditional_op = + std::make_unique(spv::OpBranchConditional); + branch_conditional_op->addIdOperand(loop_count_zero); + branch_conditional_op->addIdOperand(skip_block.getId()); + branch_conditional_op->addIdOperand(body_block.getId()); + // More likely to enter than to skip. + branch_conditional_op->addImmediateOperand(1); + branch_conditional_op->addImmediateOperand(2); + head_block.addInstruction(std::move(branch_conditional_op)); + } + skip_block.addPredecessor(&head_block); + body_block.addPredecessor(&head_block); + builder_->setBuildPoint(&skip_block); + main_switch_next_pc_phi_operands_.push_back( + builder_->makeIntConstant(int(instr.loop_skip_address))); + main_switch_next_pc_phi_operands_.push_back(builder_->getBuildPoint()->getId()); + builder_->createBranch(main_loop_continue_); + builder_->setBuildPoint(&body_block); +} + +void SpirvShaderTranslator::ProcessLoopEndInstruction(const ParsedLoopEndInstruction& instr) { + // endloop il, L - end loop w/ data il, head @ L + + // Loop control is outside execs - actually close the last exec. + CloseExecConditionals(); + + EnsureBuildPointAvailable(); + + // Subtract 1 from the loop counter (will store later). + spv::Id loop_count_stack_old = builder_->createLoad(var_main_loop_count_, spv::NoPrecision); + spv::Id loop_count = + builder_->createBinOp(spv::OpISub, type_uint_, + builder_->createCompositeExtract(loop_count_stack_old, type_uint_, 0), + builder_->makeUintConstant(1)); + spv::Id address_relative_stack_old = + builder_->createLoad(var_main_loop_address_, spv::NoPrecision); + + // Predicated break works like break if (loop_count == 0 || [!]p0). + // Three options, due to logical operations usage (so OpLogicalNot is not + // required): + // - Continue if (loop_count != 0). + // - Continue if (loop_count != 0 && p0), if breaking if !p0. + // - Break if (loop_count == 0 || p0), if breaking if p0. + bool break_is_true = instr.is_predicated_break && instr.predicate_condition; + spv::Id condition = builder_->createBinOp(break_is_true ? spv::OpIEqual : spv::OpINotEqual, + type_bool_, loop_count, const_uint_0_); + if (instr.is_predicated_break) { + condition = builder_->createBinOp( + instr.predicate_condition ? spv::OpLogicalOr : spv::OpLogicalAnd, type_bool_, condition, + builder_->createLoad(var_main_predicate_, spv::NoPrecision)); + } + + spv::Block& body_block = *builder_->getBuildPoint(); + spv::Block& continue_block = builder_->makeNewBlock(); + spv::Block& break_block = builder_->makeNewBlock(); + builder_->createSelectionMerge(&break_block, spv::SelectionControlMaskNone); + { + std::unique_ptr branch_conditional_op = + std::make_unique(spv::OpBranchConditional); + branch_conditional_op->addIdOperand(condition); + // More likely to continue than to break. + if (break_is_true) { + branch_conditional_op->addIdOperand(break_block.getId()); + branch_conditional_op->addIdOperand(continue_block.getId()); + branch_conditional_op->addImmediateOperand(1); + branch_conditional_op->addImmediateOperand(2); + } else { + branch_conditional_op->addIdOperand(continue_block.getId()); + branch_conditional_op->addIdOperand(break_block.getId()); + branch_conditional_op->addImmediateOperand(2); + branch_conditional_op->addImmediateOperand(1); + } + body_block.addInstruction(std::move(branch_conditional_op)); + } + continue_block.addPredecessor(&body_block); + break_block.addPredecessor(&body_block); + + // Continue case. + builder_->setBuildPoint(&continue_block); + // Store the loop count with 1 subtracted. + builder_->createStore( + builder_->createCompositeInsert(loop_count, loop_count_stack_old, type_uint4_, 0), + var_main_loop_count_); + // Extract the value to add to aL (signed, in bits 16:23 of the loop + // constant). + id_vector_temp_.clear(); + // Loop constants (member 1). + id_vector_temp_.push_back(builder_->makeIntConstant(1)); + // 4-component vector. + id_vector_temp_.push_back(builder_->makeIntConstant(int(instr.loop_constant_index >> 2))); + // Scalar within the vector. + id_vector_temp_.push_back(builder_->makeIntConstant(int(instr.loop_constant_index & 3))); + spv::Id loop_constant = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_bool_loop_constants_, + id_vector_temp_), + spv::NoPrecision); + spv::Id address_relative_old = + builder_->createCompositeExtract(address_relative_stack_old, type_int_, 0); + builder_->createStore( + builder_->createCompositeInsert( + builder_->createBinOp( + spv::OpIAdd, type_int_, address_relative_old, + builder_->createTriOp( + spv::OpBitFieldSExtract, type_int_, + builder_->createUnaryOp(spv::OpBitcast, type_int_, loop_constant), + builder_->makeIntConstant(16), builder_->makeIntConstant(8))), + address_relative_stack_old, type_int4_, 0), + var_main_loop_address_); + // Jump back to the beginning of the loop body. + main_switch_next_pc_phi_operands_.push_back( + builder_->makeIntConstant(int(instr.loop_body_address))); + main_switch_next_pc_phi_operands_.push_back(builder_->getBuildPoint()->getId()); + builder_->createBranch(main_loop_continue_); + + // Break case. + builder_->setBuildPoint(&break_block); + // Pop the current loop off the loop counter and the relative address stacks - + // move YZW to XYZ and set W to 0. + id_vector_temp_.clear(); + for (unsigned int i = 1; i < 4; ++i) { + id_vector_temp_.push_back( + builder_->createCompositeExtract(loop_count_stack_old, type_uint_, i)); + } + id_vector_temp_.push_back(const_uint_0_); + builder_->createStore(builder_->createCompositeConstruct(type_uint4_, id_vector_temp_), + var_main_loop_count_); + id_vector_temp_.clear(); + for (unsigned int i = 1; i < 4; ++i) { + id_vector_temp_.push_back( + builder_->createCompositeExtract(address_relative_stack_old, type_int_, i)); + } + id_vector_temp_.push_back(const_int_0_); + builder_->createStore(builder_->createCompositeConstruct(type_int4_, id_vector_temp_), + var_main_loop_address_); + // Now going to fall through to the next control flow instruction. +} + +void SpirvShaderTranslator::ProcessJumpInstruction(const ParsedJumpInstruction& instr) { + // Treat like exec, merge with execs if possible, since it's an if too. + ParsedExecInstruction::Type type; + if (instr.type == ParsedJumpInstruction::Type::kConditional) { + type = ParsedExecInstruction::Type::kConditional; + } else if (instr.type == ParsedJumpInstruction::Type::kPredicated) { + type = ParsedExecInstruction::Type::kPredicated; + } else { + type = ParsedExecInstruction::Type::kUnconditional; + } + UpdateExecConditionals(type, instr.bool_constant_index, instr.condition); + + // UpdateExecConditionals may not necessarily close the instruction-level + // predicate check (it's not necessary if the execs are merged), but here the + // instruction itself is on the control flow level, so the predicate check is + // on the control flow level too. + CloseInstructionPredication(); + + if (builder_->getBuildPoint()->isTerminated()) { + // Unreachable for some reason. + return; + } + main_switch_next_pc_phi_operands_.push_back(builder_->makeIntConstant(int(instr.target_address))); + main_switch_next_pc_phi_operands_.push_back(builder_->getBuildPoint()->getId()); + builder_->createBranch(main_loop_continue_); +} + +void SpirvShaderTranslator::ProcessAllocInstruction(const ParsedAllocInstruction& instr, + uint8_t export_eM) { + bool start_memexport = + instr.type == ucode::AllocType::kMemory && current_shader().memexport_eM_written(); + if (export_eM || start_memexport) { + CloseExecConditionals(); + } + + if (export_eM) { + ExportToMemory(export_eM); + // Reset which eM# elements have been written. + builder_->createStore(const_uint_0_, var_main_memexport_data_written_); + // Break dependencies from the previous memexport. + uint8_t export_eM_remaining = export_eM; + uint32_t eM_index; + while (rex::bit_scan_forward(export_eM_remaining, &eM_index)) { + export_eM_remaining &= ~(uint8_t(1) << eM_index); + builder_->createStore(const_float4_0_, var_main_memexport_data_[eM_index]); + } + } + + if (start_memexport) { + // Initialize eA to an invalid address. + builder_->createStore(const_float4_0_, var_main_memexport_address_); + } +} + +spv::Id SpirvShaderTranslator::SpirvSmearScalarResultOrConstant(spv::Id scalar, + spv::Id vector_type) { + bool is_constant = builder_->isConstant(scalar); + bool is_spec_constant = builder_->isSpecConstant(scalar); + if (!is_constant && !is_spec_constant) { + return builder_->smearScalar(spv::NoPrecision, scalar, vector_type); + } + assert_true(builder_->getTypeClass(builder_->getTypeId(scalar)) == + builder_->getTypeClass(builder_->getScalarTypeId(vector_type))); + if (!builder_->isVectorType(vector_type)) { + assert_true(builder_->isScalarType(vector_type)); + return scalar; + } + int num_components = builder_->getNumTypeComponents(vector_type); + id_vector_temp_util_.clear(); + for (int i = 0; i < num_components; ++i) { + id_vector_temp_util_.push_back(scalar); + } + return builder_->makeCompositeConstant(vector_type, id_vector_temp_util_, is_spec_constant); +} + +uint32_t SpirvShaderTranslator::GetPsParamGenInterpolator() const { + assert_true(is_pixel_shader()); + Modification modification = GetSpirvShaderModification(); + // param_gen_interpolator is already 4 bits, no need for an interpolator count + // safety check. + return (modification.pixel.param_gen_enable && + modification.pixel.param_gen_interpolator < register_count()) + ? modification.pixel.param_gen_interpolator + : UINT32_MAX; +} + +void SpirvShaderTranslator::EnsureBuildPointAvailable() { + if (!builder_->getBuildPoint()->isTerminated()) { + return; + } + spv::Block& new_block = builder_->makeNewBlock(); + new_block.setUnreachable(); + builder_->setBuildPoint(&new_block); +} + +void SpirvShaderTranslator::StartVertexOrTessEvalShaderBeforeMain() { + if (IsSpirvComputeShader()) { + // For memexport fallback execution, each invocation corresponds to one + // guest vertex processing index. + input_vertex_index_ = builder_->createVariable(spv::NoPrecision, spv::StorageClassInput, + type_uint3_, "gl_GlobalInvocationID"); + builder_->addDecoration(input_vertex_index_, spv::DecorationBuiltIn, + spv::BuiltInGlobalInvocationId); + main_interface_.push_back(input_vertex_index_); + return; + } + + // Create the inputs. + if (IsSpirvTessEvalShader()) { + input_primitive_id_ = builder_->createVariable(spv::NoPrecision, spv::StorageClassInput, + type_int_, "gl_PrimitiveID"); + builder_->addDecoration(input_primitive_id_, spv::DecorationBuiltIn, spv::BuiltInPrimitiveId); + main_interface_.push_back(input_primitive_id_); + input_tess_coord_ = builder_->createVariable(spv::NoPrecision, spv::StorageClassInput, + type_float3_, "gl_TessCoord"); + builder_->addDecoration(input_tess_coord_, spv::DecorationBuiltIn, spv::BuiltInTessCoord); + main_interface_.push_back(input_tess_coord_); + input_patch_control_point_indices_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassInput, type_float4_, + "xe_in_patch_control_point_indices"); + builder_->addDecoration(input_patch_control_point_indices_, spv::DecorationLocation, 0); + builder_->addDecoration(input_patch_control_point_indices_, spv::DecorationPatch); + main_interface_.push_back(input_patch_control_point_indices_); + } else { + input_vertex_index_ = builder_->createVariable(spv::NoPrecision, spv::StorageClassInput, + type_int_, "gl_VertexIndex"); + builder_->addDecoration(input_vertex_index_, spv::DecorationBuiltIn, spv::BuiltInVertexIndex); + main_interface_.push_back(input_vertex_index_); + } + + uint32_t output_location = 0; + + // Create the interpolator outputs. + { + uint32_t interpolators_remaining = GetModificationInterpolatorMask(); + uint32_t interpolator_index; + while (rex::bit_scan_forward(interpolators_remaining, &interpolator_index)) { + interpolators_remaining &= ~(UINT32_C(1) << interpolator_index); + spv::Id interpolator = builder_->createVariable( + spv::NoPrecision, spv::StorageClassOutput, type_float4_, + fmt::format("xe_out_interpolator_{}", interpolator_index).c_str()); + input_output_interpolators_[interpolator_index] = interpolator; + builder_->addDecoration(interpolator, spv::DecorationLocation, int(output_location)); + builder_->addDecoration(interpolator, spv::DecorationInvariant); + main_interface_.push_back(interpolator); + ++output_location; + } + } + + Modification shader_modification = GetSpirvShaderModification(); + + if (shader_modification.vertex.output_point_parameters) { + if (shader_modification.vertex.host_vertex_shader_type == + Shader::HostVertexShaderType::kPointListAsTriangleStrip) { + // Create the point coordinates output. + output_point_coordinates_ = builder_->createVariable( + spv::NoPrecision, spv::StorageClassOutput, type_float2_, "xe_out_point_coordinates"); + builder_->addDecoration(output_point_coordinates_, spv::DecorationLocation, + int(output_location)); + builder_->addDecoration(output_point_coordinates_, spv::DecorationInvariant); + main_interface_.push_back(output_point_coordinates_); + ++output_location; + } else { + // Create the point size output. Not using gl_PointSize from gl_PerVertex + // not to rely on the shaderTessellationAndGeometryPointSize feature, and + // also because the value written to gl_PointSize must be greater than + // zero. + output_point_size_ = builder_->createVariable(spv::NoPrecision, spv::StorageClassOutput, + type_float_, "xe_out_point_size"); + builder_->addDecoration(output_point_size_, spv::DecorationLocation, int(output_location)); + builder_->addDecoration(output_point_size_, spv::DecorationInvariant); + main_interface_.push_back(output_point_size_); + ++output_location; + } + } + + // Create the gl_PerVertex output for used system outputs. + uint32_t clip_distance_count = shader_modification.GetVertexClipDistanceCount(); + uint32_t cull_distance_count = shader_modification.GetVertexCullDistanceCount(); + std::vector struct_per_vertex_members; + struct_per_vertex_members.reserve(kOutputPerVertexMemberCountMax); + struct_per_vertex_members.push_back(type_float4_); + output_per_vertex_member_count_ = uint32_t(struct_per_vertex_members.size()); + output_per_vertex_member_clip_distance_ = UINT32_MAX; + output_per_vertex_member_cull_distance_ = UINT32_MAX; + if (clip_distance_count) { + assert_true(features_.clip_distance); + builder_->addCapability(spv::CapabilityClipDistance); + spv::Id type_clip_distance = + builder_->makeArrayType(type_float_, builder_->makeUintConstant(clip_distance_count), 0); + builder_->addDecoration(type_clip_distance, spv::DecorationArrayStride, sizeof(float)); + output_per_vertex_member_clip_distance_ = uint32_t(struct_per_vertex_members.size()); + struct_per_vertex_members.push_back(type_clip_distance); + output_per_vertex_member_count_ = uint32_t(struct_per_vertex_members.size()); + } + if (cull_distance_count) { + assert_true(features_.cull_distance); + builder_->addCapability(spv::CapabilityCullDistance); + spv::Id type_cull_distance = + builder_->makeArrayType(type_float_, builder_->makeUintConstant(cull_distance_count), 0); + builder_->addDecoration(type_cull_distance, spv::DecorationArrayStride, sizeof(float)); + output_per_vertex_member_cull_distance_ = uint32_t(struct_per_vertex_members.size()); + struct_per_vertex_members.push_back(type_cull_distance); + output_per_vertex_member_count_ = uint32_t(struct_per_vertex_members.size()); + } + spv::Id type_struct_per_vertex = + builder_->makeStructType(struct_per_vertex_members, "gl_PerVertex"); + builder_->addMemberName(type_struct_per_vertex, kOutputPerVertexMemberPosition, "gl_Position"); + builder_->addMemberDecoration(type_struct_per_vertex, kOutputPerVertexMemberPosition, + spv::DecorationBuiltIn, spv::BuiltInPosition); + if (output_per_vertex_member_clip_distance_ != UINT32_MAX) { + builder_->addMemberName(type_struct_per_vertex, output_per_vertex_member_clip_distance_, + "gl_ClipDistance"); + builder_->addMemberDecoration(type_struct_per_vertex, output_per_vertex_member_clip_distance_, + spv::DecorationBuiltIn, spv::BuiltInClipDistance); + } + if (output_per_vertex_member_cull_distance_ != UINT32_MAX) { + builder_->addMemberName(type_struct_per_vertex, output_per_vertex_member_cull_distance_, + "gl_CullDistance"); + builder_->addMemberDecoration(type_struct_per_vertex, output_per_vertex_member_cull_distance_, + spv::DecorationBuiltIn, spv::BuiltInCullDistance); + } + builder_->addDecoration(type_struct_per_vertex, spv::DecorationBlock); + type_output_per_vertex_ = type_struct_per_vertex; + output_per_vertex_ = builder_->createVariable(spv::NoPrecision, spv::StorageClassOutput, + type_struct_per_vertex, ""); + builder_->addDecoration(output_per_vertex_, spv::DecorationInvariant); + main_interface_.push_back(output_per_vertex_); +} + +void SpirvShaderTranslator::StartVertexOrTessEvalShaderInMain() { + Modification shader_modification = GetSpirvShaderModification(); + Shader::HostVertexShaderType host_vertex_shader_type = + shader_modification.vertex.host_vertex_shader_type; + + // The edge flag isn't used for any purpose by the translator. + if (current_shader().writes_point_size_edge_flag_kill_vertex() & 0b101) { + id_vector_temp_.clear(); + // Set the point size to a negative value to tell the point sprite expansion + // that it should use the default point size if the vertex shader does not + // override it. + id_vector_temp_.push_back(builder_->makeFloatConstant(-1.0f)); + // The edge flag is ignored. + id_vector_temp_.push_back(const_float_0_); + // Don't kill by default (zero bits 0:30). + id_vector_temp_.push_back(const_float_0_); + var_main_point_size_edge_flag_kill_vertex_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassFunction, type_float3_, + "xe_var_point_size_edge_flag_kill_vertex", + builder_->makeCompositeConstant(type_float3_, id_vector_temp_)); + } + + // Zero general-purpose registers to prevent crashes when the game + // references them after only initializing them conditionally. + for (uint32_t i = 0; i < register_count(); ++i) { + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(int(i))); + builder_->createStore( + const_float4_0_, builder_->createAccessChain(spv::StorageClassFunction, var_main_registers_, + id_vector_temp_)); + } + + if (!IsSpirvComputeShader()) { + // Zero the interpolators. + uint32_t interpolators_remaining = GetModificationInterpolatorMask(); + uint32_t interpolator_index; + while (rex::bit_scan_forward(interpolators_remaining, &interpolator_index)) { + interpolators_remaining &= ~(UINT32_C(1) << interpolator_index); + builder_->createStore(const_float4_0_, input_output_interpolators_[interpolator_index]); + } + } + + // For rectangle-list fallback without geometry shaders, additional guest + // vertex iterations are driven from CompleteTranslation via main_loop_merge_. + + // Check if memory export should be allowed for this host vertex of the guest + // primitive to make sure export is done only once for each guest vertex. + if (IsMemoryExportUsed()) { + spv::Id memexport_allowed_for_host_vertex_of_guest_primitive = spv::NoResult; + if (host_vertex_shader_type == Shader::HostVertexShaderType::kPointListAsTriangleStrip || + host_vertex_shader_type == Shader::HostVertexShaderType::kRectangleListAsTriangleStrip) { + spv::Id host_vertex_in_guest_primitive = builder_->createBinOp( + spv::OpBitwiseAnd, type_uint_, + builder_->createUnaryOp(spv::OpBitcast, type_uint_, + builder_->createLoad(input_vertex_index_, spv::NoPrecision)), + builder_->makeUintConstant(3)); + if (host_vertex_shader_type == Shader::HostVertexShaderType::kPointListAsTriangleStrip) { + // Only for one host vertex for the point. + memexport_allowed_for_host_vertex_of_guest_primitive = builder_->createBinOp( + spv::OpIEqual, type_bool_, host_vertex_in_guest_primitive, const_uint_0_); + } else { + if (IsSpirvRectangleListVertexLoopEnabled()) { + // In the rectangle guest-vertex loop mode, one host invocation + // processes all 3 guest vertices, so memexport must be done only from + // one host strip vertex. + memexport_allowed_for_host_vertex_of_guest_primitive = builder_->createBinOp( + spv::OpIEqual, type_bool_, host_vertex_in_guest_primitive, const_uint_0_); + } else { + // The synthetic fourth host vertex must not duplicate export for + // guest vertex 2 of the rectangle. + memexport_allowed_for_host_vertex_of_guest_primitive = + builder_->createBinOp(spv::OpINotEqual, type_bool_, host_vertex_in_guest_primitive, + builder_->makeUintConstant(3)); + } + } + } + + if (memexport_allowed_for_host_vertex_of_guest_primitive != spv::NoResult) { + main_memexport_allowed_ = + main_memexport_allowed_ != spv::NoResult + ? builder_->createBinOp(spv::OpLogicalAnd, type_bool_, main_memexport_allowed_, + memexport_allowed_for_host_vertex_of_guest_primitive) + : memexport_allowed_for_host_vertex_of_guest_primitive; + } + } + + // Load the vertex index or the tessellation parameters. + if (register_count()) { + auto store_register_component = [this](uint32_t register_index, uint32_t component, + spv::Id value) { + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(int(register_index))); + id_vector_temp_.push_back(builder_->makeIntConstant(int(component))); + builder_->createStore( + value, builder_->createAccessChain(spv::StorageClassFunction, var_main_registers_, + id_vector_temp_)); + }; + if (IsSpirvTessEvalShader()) { + auto load_tess_coord_component = [this](uint32_t component) { + return builder_->createCompositeExtract( + builder_->createLoad(input_tess_coord_, spv::NoPrecision), type_float_, component); + }; + auto load_patch_control_point_index = [this](uint32_t component) { + return builder_->createCompositeExtract( + builder_->createLoad(input_patch_control_point_indices_, spv::NoPrecision), type_float_, + component); + }; + switch (shader_modification.vertex.host_vertex_shader_type) { + case Shader::HostVertexShaderType::kTriangleDomainCPIndexed: + // r0.xyz = domain location zyx, r1.xyz = control point indices. + store_register_component(0, 0, load_tess_coord_component(2)); + store_register_component(0, 1, load_tess_coord_component(1)); + store_register_component(0, 2, load_tess_coord_component(0)); + if (register_count() >= 2) { + store_register_component(1, 0, load_patch_control_point_index(0)); + store_register_component(1, 1, load_patch_control_point_index(1)); + store_register_component(1, 2, load_patch_control_point_index(2)); + } + break; + case Shader::HostVertexShaderType::kTriangleDomainPatchIndexed: + // r0.xyz = domain location zyx, r1.x = patch index, r1.y = swizzle. + store_register_component(0, 0, load_tess_coord_component(2)); + store_register_component(0, 1, load_tess_coord_component(1)); + store_register_component(0, 2, load_tess_coord_component(0)); + if (register_count() >= 2) { + store_register_component(1, 0, load_patch_control_point_index(0)); + store_register_component(1, 1, const_float_0_); + } + break; + case Shader::HostVertexShaderType::kQuadDomainCPIndexed: + // r0.xy = domain location xy, r0.z/r1.xyz = control point indices. + store_register_component(0, 0, load_tess_coord_component(0)); + store_register_component(0, 1, load_tess_coord_component(1)); + store_register_component(0, 2, load_patch_control_point_index(0)); + if (register_count() >= 2) { + store_register_component(1, 0, load_patch_control_point_index(1)); + store_register_component(1, 1, load_patch_control_point_index(2)); + store_register_component(1, 2, load_patch_control_point_index(3)); + } + break; + case Shader::HostVertexShaderType::kQuadDomainPatchIndexed: + // r0.x = patch index, r0.yz = domain location xy, r1.x = swizzle. + store_register_component(0, 0, load_patch_control_point_index(0)); + store_register_component(0, 1, load_tess_coord_component(0)); + store_register_component(0, 2, load_tess_coord_component(1)); + if (register_count() >= 2) { + store_register_component(1, 0, const_float_0_); + } + break; + default: + break; + } + } + if (IsSpirvVertexShader() || IsSpirvComputeShader()) { + spv::Id vertex_index; + spv::Id compute_vertex_processing_index = spv::NoResult; + spv::Id compute_load_vertex_index = spv::NoResult; + spv::Id compute_vertex_index_is_32bit = spv::NoResult; + if (IsSpirvComputeShader()) { + spv::Id global_invocation_id = builder_->createLoad(input_vertex_index_, spv::NoPrecision); + spv::Id global_invocation_x = + builder_->createCompositeExtract(global_invocation_id, type_uint_, 0); + spv::Id global_invocation_y = + builder_->createCompositeExtract(global_invocation_id, type_uint_, 1); + spv::Id global_invocation_z = + builder_->createCompositeExtract(global_invocation_id, type_uint_, 2); + compute_vertex_processing_index = builder_->createBinOp( + spv::OpIAdd, type_uint_, global_invocation_x, + builder_->createBinOp( + spv::OpIAdd, type_uint_, + builder_->createBinOp(spv::OpIMul, type_uint_, global_invocation_y, + builder_->makeUintConstant(kMemExportComputeDispatchX)), + builder_->createBinOp(spv::OpIMul, type_uint_, global_invocation_z, + builder_->makeUintConstant(kMemExportComputeDispatchX * + kMemExportComputeDispatchY)))); + + id_vector_temp_.clear(); + id_vector_temp_.push_back( + builder_->makeIntConstant(kSystemConstantComputeMemExportVertexCount)); + spv::Id compute_memexport_vertex_count = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + spv::Id compute_vertex_in_range = + builder_->createBinOp(spv::OpULessThan, type_bool_, compute_vertex_processing_index, + compute_memexport_vertex_count); + main_memexport_allowed_ = + main_memexport_allowed_ != spv::NoResult + ? builder_->createBinOp(spv::OpLogicalAnd, type_bool_, main_memexport_allowed_, + compute_vertex_in_range) + : compute_vertex_in_range; + vertex_index = builder_->createTriOp(spv::OpSelect, type_uint_, compute_vertex_in_range, + compute_vertex_processing_index, const_uint_0_); + compute_vertex_processing_index = vertex_index; + } else { + vertex_index = + builder_->createUnaryOp(spv::OpBitcast, type_uint_, + builder_->createLoad(input_vertex_index_, spv::NoPrecision)); + } + if (IsSpirvVertexShader()) { + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantLineLoopClosingIndex)); + spv::Id line_loop_closing_index = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + vertex_index = + builder_->createTriOp(spv::OpSelect, type_uint_, + builder_->createBinOp(spv::OpINotEqual, type_bool_, vertex_index, + line_loop_closing_index), + vertex_index, const_uint_0_); + } + if (IsSpirvVertexShader() && + (host_vertex_shader_type == Shader::HostVertexShaderType::kPointListAsTriangleStrip || + host_vertex_shader_type == + Shader::HostVertexShaderType::kRectangleListAsTriangleStrip)) { + spv::Id const_uint_2 = builder_->makeUintConstant(2); + spv::Id two_triangle_strip_vertex_index = vertex_index; + // Extract the primitive index from the two-triangle strip vertex index. + vertex_index = builder_->createBinOp(spv::OpShiftRightLogical, type_uint_, + two_triangle_strip_vertex_index, const_uint_2); + if (host_vertex_shader_type == + Shader::HostVertexShaderType::kRectangleListAsTriangleStrip) { + spv::Id const_uint_3 = builder_->makeUintConstant(3); + spv::Id guest_vertex_in_guest_primitive; + if (IsSpirvRectangleListVertexLoopEnabled()) { + // In the rectangle VS fallback loop, process guest vertices 0, 1 and + // 2 in every host invocation. + guest_vertex_in_guest_primitive = + builder_->createLoad(var_main_rectangle_guest_vertex_index_, spv::NoPrecision); + } else { + // Rectangle lists consume 3 guest vertices per primitive. Clamp the + // synthetic fourth host vertex to guest vertex 2. + spv::Id host_vertex_in_guest_primitive = builder_->createBinOp( + spv::OpBitwiseAnd, type_uint_, two_triangle_strip_vertex_index, const_uint_3); + guest_vertex_in_guest_primitive = builder_->createTriOp( + spv::OpSelect, type_uint_, + builder_->createBinOp(spv::OpIEqual, type_bool_, host_vertex_in_guest_primitive, + const_uint_3), + const_uint_2, host_vertex_in_guest_primitive); + } + vertex_index = builder_->createBinOp( + spv::OpIAdd, type_uint_, + builder_->createBinOp(spv::OpIMul, type_uint_, vertex_index, const_uint_3), + guest_vertex_in_guest_primitive); + } + // Check if the index needs to be loaded from the index buffer. + spv::Id load_vertex_index = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(static_cast( + kSysFlag_ComputeOrPrimitiveVertexIndexLoad))), + const_uint_0_); + SpirvBuilder::IfBuilder load_vertex_index_if( + load_vertex_index, spv::SelectionControlDontFlattenMask, *builder_); + spv::Id loaded_vertex_index; + { + // Check if the index is 32-bit. + spv::Id vertex_index_is_32bit = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(static_cast( + kSysFlag_ComputeOrPrimitiveVertexIndexLoad32Bit))), + const_uint_0_); + // Calculate the vertex index address in the shared memory. + id_vector_temp_.clear(); + id_vector_temp_.push_back( + builder_->makeIntConstant(kSystemConstantVertexIndexLoadAddress)); + spv::Id vertex_index_address = builder_->createBinOp( + spv::OpIAdd, type_uint_, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision), + builder_->createBinOp( + spv::OpShiftLeftLogical, type_uint_, vertex_index, + builder_->createTriOp(spv::OpSelect, type_uint_, vertex_index_is_32bit, + const_uint_2, builder_->makeUintConstant(1)))); + // Load the 32 bits containing the whole vertex index or two 16-bit + // vertex indices. + // TODO(Triang3l): Bounds checking. + loaded_vertex_index = LoadUint32FromSharedMemory( + builder_->createUnaryOp(spv::OpBitcast, type_int_, + builder_->createBinOp(spv::OpShiftRightLogical, type_uint_, + vertex_index_address, const_uint_2))); + // Extract the 16-bit index from the loaded 32 bits if needed. + loaded_vertex_index = builder_->createTriOp( + spv::OpSelect, type_uint_, vertex_index_is_32bit, loaded_vertex_index, + builder_->createTriOp( + spv::OpBitFieldUExtract, type_uint_, loaded_vertex_index, + builder_->createBinOp(spv::OpShiftLeftLogical, type_uint_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, + vertex_index_address, const_uint_2), + builder_->makeUintConstant(4 - 1)), + builder_->makeUintConstant(16))); + // Endian-swap the loaded index. + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantVertexIndexEndian)); + loaded_vertex_index = EndianSwap32Uint( + loaded_vertex_index, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision)); + } + load_vertex_index_if.makeEndIf(); + // Select between the loaded index and the original index from Vulkan. + vertex_index = load_vertex_index_if.createMergePhi(loaded_vertex_index, vertex_index); + } else { + if (IsSpirvComputeShader()) { + // For memexport compute fallback, optionally load the original index + // from guest DMA (16-bit or 32-bit), unless emulating adaptive + // tessellation patch indexing (the patch index comes from invocation + // ID in that mode). + spv::Id patch_index_from_invocation = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(static_cast( + kSysFlag_ComputeMemExportPatchIndexFromInvocation))), + const_uint_0_); + compute_load_vertex_index = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(static_cast( + kSysFlag_ComputeOrPrimitiveVertexIndexLoad))), + const_uint_0_); + compute_load_vertex_index = builder_->createBinOp( + spv::OpLogicalAnd, type_bool_, compute_load_vertex_index, + builder_->createUnaryOp(spv::OpLogicalNot, type_bool_, patch_index_from_invocation)); + compute_vertex_index_is_32bit = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(static_cast( + kSysFlag_ComputeOrPrimitiveVertexIndexLoad32Bit))), + const_uint_0_); + SpirvBuilder::IfBuilder load_vertex_index_if( + compute_load_vertex_index, spv::SelectionControlDontFlattenMask, *builder_); + spv::Id loaded_vertex_index; + { + id_vector_temp_.clear(); + id_vector_temp_.push_back( + builder_->makeIntConstant(kSystemConstantVertexIndexLoadAddress)); + spv::Id vertex_index_address = builder_->createBinOp( + spv::OpIAdd, type_uint_, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision), + builder_->createBinOp( + spv::OpShiftLeftLogical, type_uint_, vertex_index, + builder_->createTriOp(spv::OpSelect, type_uint_, compute_vertex_index_is_32bit, + builder_->makeUintConstant(2), + builder_->makeUintConstant(1)))); + loaded_vertex_index = LoadUint32FromSharedMemory(builder_->createUnaryOp( + spv::OpBitcast, type_int_, + builder_->createBinOp(spv::OpShiftRightLogical, type_uint_, vertex_index_address, + builder_->makeUintConstant(2)))); + loaded_vertex_index = builder_->createTriOp( + spv::OpSelect, type_uint_, compute_vertex_index_is_32bit, loaded_vertex_index, + builder_->createTriOp( + spv::OpBitFieldUExtract, type_uint_, loaded_vertex_index, + builder_->createBinOp( + spv::OpShiftLeftLogical, type_uint_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, vertex_index_address, + builder_->makeUintConstant(2)), + builder_->makeUintConstant(3)), + builder_->makeUintConstant(16))); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantVertexIndexEndian)); + loaded_vertex_index = EndianSwap32Uint( + loaded_vertex_index, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision)); + } + load_vertex_index_if.makeEndIf(); + vertex_index = load_vertex_index_if.createMergePhi(loaded_vertex_index, vertex_index); + } else { + // Load the unswapped index as uint for swapping, or for indirect + // loading if needed. + if (!features_.full_draw_index_uint32) { + // Check if the full 32-bit index needs to be loaded indirectly. + spv::Id load_vertex_index = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant( + static_cast(kSysFlag_VertexIndexLoad))), + const_uint_0_); + SpirvBuilder::IfBuilder load_vertex_index_if( + load_vertex_index, spv::SelectionControlDontFlattenMask, *builder_); + spv::Id loaded_vertex_index; + { + // Load the 32-bit index. + // TODO(Triang3l): Bounds checking. + id_vector_temp_.clear(); + id_vector_temp_.push_back( + builder_->makeIntConstant(kSystemConstantVertexIndexLoadAddress)); + loaded_vertex_index = LoadUint32FromSharedMemory(builder_->createUnaryOp( + spv::OpBitcast, type_int_, + builder_->createBinOp( + spv::OpIAdd, type_uint_, + builder_->createBinOp( + spv::OpShiftRightLogical, type_uint_, + builder_->createLoad(builder_->createAccessChain( + spv::StorageClassUniform, + uniform_system_constants_, id_vector_temp_), + spv::NoPrecision), + builder_->makeUintConstant(2)), + vertex_index))); + } + load_vertex_index_if.makeEndIf(); + // Select between the loaded index and the original index from Vulkan. + vertex_index = load_vertex_index_if.createMergePhi(loaded_vertex_index, vertex_index); + } + // Endian-swap the index. + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantVertexIndexEndian)); + vertex_index = EndianSwap32Uint( + vertex_index, builder_->createLoad(builder_->createAccessChain( + spv::StorageClassUniform, + uniform_system_constants_, id_vector_temp_), + spv::NoPrecision)); + } + } + if (IsSpirvComputeShader() && IsMemoryExportUsed()) { + // Primitive reset must suppress memexport for reset-index invocations + // in the compute fallback path. + spv::Id primitive_reset_enabled = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(static_cast( + kSysFlag_ComputeOrPrimitiveVertexIndexReset))), + const_uint_0_); + spv::Id vertex_index_is_32bit = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(static_cast( + kSysFlag_ComputeOrPrimitiveVertexIndexLoad32Bit))), + const_uint_0_); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantVertexIndexReset)); + spv::Id vertex_index_reset = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + spv::Id vertex_index_not_reset_16 = + builder_->createBinOp(spv::OpINotEqual, type_bool_, vertex_index, vertex_index_reset); + spv::Id vertex_index_not_reset_32 = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, vertex_index, + builder_->makeUintConstant(xenos::kVertexIndexMask)), + vertex_index_reset); + spv::Id vertex_index_not_reset = + builder_->createTriOp(spv::OpSelect, type_bool_, vertex_index_is_32bit, + vertex_index_not_reset_32, vertex_index_not_reset_16); + spv::Id memexport_allowed_for_non_reset_index = builder_->createBinOp( + spv::OpLogicalOr, type_bool_, + builder_->createUnaryOp(spv::OpLogicalNot, type_bool_, primitive_reset_enabled), + vertex_index_not_reset); + main_memexport_allowed_ = + main_memexport_allowed_ != spv::NoResult + ? builder_->createBinOp(spv::OpLogicalAnd, type_bool_, main_memexport_allowed_, + memexport_allowed_for_non_reset_index) + : memexport_allowed_for_non_reset_index; + } + // Add the base index, apply the 24-bit index mask and clamp to the + // draw's index range similarly to the Direct3D path. + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantVertexBaseIndex)); + spv::Id vertex_base_index = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantVertexIndexMin)); + spv::Id vertex_index_min = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantVertexIndexMax)); + spv::Id vertex_index_max = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + auto remap_vertex_index_to_float = [this, vertex_base_index, vertex_index_min, + vertex_index_max](spv::Id index) { + index = builder_->createBinOp( + spv::OpIAdd, type_uint_, index, + builder_->createUnaryOp(spv::OpBitcast, type_uint_, vertex_base_index)); + index = builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, index, + builder_->makeUintConstant(xenos::kVertexIndexMask)); + index = builder_->createTriBuiltinCall(type_uint_, ext_inst_glsl_std_450_, GLSLstd450UClamp, + index, vertex_index_min, vertex_index_max); + return builder_->createUnaryOp(spv::OpConvertUToF, type_float_, index); + }; + // Write the index to the register expected by the current host vertex + // shader mode. + spv::Id vertex_index_float = remap_vertex_index_to_float(vertex_index); + if (IsSpirvComputeShader()) { + auto load_compute_vertex_index_float = [this, compute_load_vertex_index, + compute_vertex_index_is_32bit, + &remap_vertex_index_to_float]( + spv::Id vertex_processing_index) { + spv::Id index = vertex_processing_index; + SpirvBuilder::IfBuilder load_vertex_index_if( + compute_load_vertex_index, spv::SelectionControlDontFlattenMask, *builder_); + spv::Id loaded_vertex_index; + { + id_vector_temp_.clear(); + id_vector_temp_.push_back( + builder_->makeIntConstant(kSystemConstantVertexIndexLoadAddress)); + spv::Id vertex_index_address = builder_->createBinOp( + spv::OpIAdd, type_uint_, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision), + builder_->createBinOp( + spv::OpShiftLeftLogical, type_uint_, vertex_processing_index, + builder_->createTriOp(spv::OpSelect, type_uint_, compute_vertex_index_is_32bit, + builder_->makeUintConstant(2), + builder_->makeUintConstant(1)))); + loaded_vertex_index = LoadUint32FromSharedMemory(builder_->createUnaryOp( + spv::OpBitcast, type_int_, + builder_->createBinOp(spv::OpShiftRightLogical, type_uint_, vertex_index_address, + builder_->makeUintConstant(2)))); + loaded_vertex_index = builder_->createTriOp( + spv::OpSelect, type_uint_, compute_vertex_index_is_32bit, loaded_vertex_index, + builder_->createTriOp( + spv::OpBitFieldUExtract, type_uint_, loaded_vertex_index, + builder_->createBinOp( + spv::OpShiftLeftLogical, type_uint_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, vertex_index_address, + builder_->makeUintConstant(2)), + builder_->makeUintConstant(3)), + builder_->makeUintConstant(16))); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantVertexIndexEndian)); + loaded_vertex_index = EndianSwap32Uint( + loaded_vertex_index, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision)); + } + load_vertex_index_if.makeEndIf(); + index = load_vertex_index_if.createMergePhi(loaded_vertex_index, index); + return remap_vertex_index_to_float(index); + }; + spv::Id triangle_cp_indexed = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(static_cast( + kSysFlag_ComputeMemExportTriangleCPIndexed))), + const_uint_0_); + spv::Id quad_cp_indexed = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(static_cast( + kSysFlag_ComputeMemExportQuadCPIndexed))), + const_uint_0_); + spv::Id cp_indexed = builder_->createBinOp(spv::OpLogicalOr, type_bool_, + triangle_cp_indexed, quad_cp_indexed); + SpirvBuilder::IfBuilder if_cp_indexed(cp_indexed, spv::SelectionControlDontFlattenMask, + *builder_); + { + spv::Id cp_count = + builder_->createTriOp(spv::OpSelect, type_uint_, triangle_cp_indexed, + builder_->makeUintConstant(3), builder_->makeUintConstant(4)); + spv::Id cp_in_patch = builder_->createBinOp(spv::OpUMod, type_uint_, + compute_vertex_processing_index, cp_count); + spv::Id patch_first_vertex_processing_index = builder_->createBinOp( + spv::OpISub, type_uint_, compute_vertex_processing_index, cp_in_patch); + spv::Id cp_index_0 = load_compute_vertex_index_float(patch_first_vertex_processing_index); + spv::Id cp_index_1 = load_compute_vertex_index_float( + builder_->createBinOp(spv::OpIAdd, type_uint_, patch_first_vertex_processing_index, + builder_->makeUintConstant(1))); + spv::Id cp_index_2 = load_compute_vertex_index_float( + builder_->createBinOp(spv::OpIAdd, type_uint_, patch_first_vertex_processing_index, + builder_->makeUintConstant(2))); + + SpirvBuilder::IfBuilder if_triangle_cp(triangle_cp_indexed, + spv::SelectionControlDontFlattenMask, *builder_); + { + // Emulate barycentric corner selection for the current control + // point in the patch: r0.xyz = domain location zyx. + spv::Id cp_is_0 = + builder_->createBinOp(spv::OpIEqual, type_bool_, cp_in_patch, const_uint_0_); + spv::Id cp_is_1 = builder_->createBinOp(spv::OpIEqual, type_bool_, cp_in_patch, + builder_->makeUintConstant(1)); + spv::Id cp_is_2 = builder_->createBinOp(spv::OpIEqual, type_bool_, cp_in_patch, + builder_->makeUintConstant(2)); + spv::Id domain_z = builder_->createTriOp(spv::OpSelect, type_float_, cp_is_2, + const_float_1_, const_float_0_); + spv::Id domain_y = builder_->createTriOp(spv::OpSelect, type_float_, cp_is_1, + const_float_1_, const_float_0_); + spv::Id domain_x = builder_->createTriOp(spv::OpSelect, type_float_, cp_is_0, + const_float_1_, const_float_0_); + store_register_component(0, 0, domain_z); + store_register_component(0, 1, domain_y); + store_register_component(0, 2, domain_x); + if (register_count() >= 2) { + store_register_component(1, 0, cp_index_0); + store_register_component(1, 1, cp_index_1); + store_register_component(1, 2, cp_index_2); + } + } + if_triangle_cp.makeBeginElse(); + { + // Emulate quad corner selection for the current control point: + // r0.xy = domain location xy. + spv::Id cp_is_1 = builder_->createBinOp(spv::OpIEqual, type_bool_, cp_in_patch, + builder_->makeUintConstant(1)); + spv::Id cp_is_2 = builder_->createBinOp(spv::OpIEqual, type_bool_, cp_in_patch, + builder_->makeUintConstant(2)); + spv::Id cp_is_3 = builder_->createBinOp(spv::OpIEqual, type_bool_, cp_in_patch, + builder_->makeUintConstant(3)); + spv::Id domain_x = builder_->createTriOp( + spv::OpSelect, type_float_, + builder_->createBinOp(spv::OpLogicalOr, type_bool_, cp_is_1, cp_is_2), + const_float_1_, const_float_0_); + spv::Id domain_y = builder_->createTriOp( + spv::OpSelect, type_float_, + builder_->createBinOp(spv::OpLogicalOr, type_bool_, cp_is_2, cp_is_3), + const_float_1_, const_float_0_); + store_register_component(0, 0, domain_x); + store_register_component(0, 1, domain_y); + store_register_component(0, 2, cp_index_0); + if (register_count() >= 2) { + spv::Id cp_index_3 = load_compute_vertex_index_float(builder_->createBinOp( + spv::OpIAdd, type_uint_, patch_first_vertex_processing_index, + builder_->makeUintConstant(3))); + store_register_component(1, 0, cp_index_1); + store_register_component(1, 1, cp_index_2); + store_register_component(1, 2, cp_index_3); + } + } + if_triangle_cp.makeEndIf(); + } + if_cp_indexed.makeBeginElse(); + if (register_count() >= 2) { + spv::Id patch_index_in_register_1 = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(static_cast( + kSysFlag_ComputeMemExportPatchIndexInRegister1))), + const_uint_0_); + SpirvBuilder::IfBuilder if_patch_index_in_register_1( + patch_index_in_register_1, spv::SelectionControlDontFlattenMask, *builder_); + store_register_component(1, 0, vertex_index_float); + if_patch_index_in_register_1.makeBeginElse(); + store_register_component(0, 0, vertex_index_float); + if_patch_index_in_register_1.makeEndIf(); + } else { + store_register_component(0, 0, vertex_index_float); + } + if_cp_indexed.makeEndIf(); + } else { + store_register_component(0, 0, vertex_index_float); + } + } + } +} + +void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() { + Modification shader_modification = GetSpirvShaderModification(); + + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kOutputPerVertexMemberPosition)); + spv::Id position_ptr = + builder_->createAccessChain(spv::StorageClassOutput, output_per_vertex_, id_vector_temp_); + spv::Id guest_position = builder_->createLoad(position_ptr, spv::NoPrecision); + + // Check if the shader already returns W, not 1/W, and if it doesn't, turn 1/W + // into W. + spv::Id position_w = builder_->createCompositeExtract(guest_position, type_float_, 3); + spv::Id is_w_not_reciprocal = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp( + spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(static_cast(kSysFlag_WNotReciprocal))), + const_uint_0_); + spv::Id guest_position_w_inv = + builder_->createNoContractionBinOp(spv::OpFDiv, type_float_, const_float_1_, position_w); + position_w = builder_->createTriOp(spv::OpSelect, type_float_, is_w_not_reciprocal, position_w, + guest_position_w_inv); + + spv::Id position_xyz; + + // Open a scope since position_xy and position_z won't be synchronized anymore + // after position_xyz is built and modified later. + { + // Check if the shader returns XY/W rather than XY, and if it does, revert + // that. + uint_vector_temp_.clear(); + uint_vector_temp_.push_back(0); + uint_vector_temp_.push_back(1); + spv::Id position_xy = builder_->createRvalueSwizzle(spv::NoPrecision, type_float2_, + guest_position, uint_vector_temp_); + spv::Id is_xy_divided_by_w = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp( + spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(static_cast(kSysFlag_XYDividedByW))), + const_uint_0_); + spv::Id guest_position_xy_mul_w = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float2_, position_xy, position_w); + position_xy = builder_->createTriOp( + spv::OpSelect, type_float2_, + builder_->smearScalar(spv::NoPrecision, is_xy_divided_by_w, type_bool2_), + guest_position_xy_mul_w, position_xy); + + // Check if the shader returns Z/W rather than Z, and if it does, revert + // that. + spv::Id position_z = builder_->createCompositeExtract(guest_position, type_float_, 2); + spv::Id is_z_divided_by_w = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp( + spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(static_cast(kSysFlag_ZDividedByW))), + const_uint_0_); + spv::Id guest_position_z_mul_w = + builder_->createNoContractionBinOp(spv::OpFMul, type_float_, position_z, position_w); + position_z = builder_->createTriOp(spv::OpSelect, type_float_, is_z_divided_by_w, + guest_position_z_mul_w, position_z); + + // Build XYZ of the position with W format handled. + { + std::unique_ptr composite_construct_op = std::make_unique( + builder_->getUniqueId(), type_float3_, spv::OpCompositeConstruct); + composite_construct_op->addIdOperand(position_xy); + composite_construct_op->addIdOperand(position_z); + position_xyz = composite_construct_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(composite_construct_op)); + } + } + + uint32_t clip_distance_next_component = 0; + uint32_t cull_distance_next_component = 0; + // Clip against user clip planes. + if (shader_modification.vertex.user_clip_plane_count) { + uint32_t output_per_vertex_member_clip_or_cull_distance = + shader_modification.vertex.user_clip_plane_cull ? output_per_vertex_member_cull_distance_ + : output_per_vertex_member_clip_distance_; + assert_true(output_per_vertex_member_clip_or_cull_distance != UINT32_MAX); + // Position with W format handled, but before guest-to-host NDC transform. + spv::Id guest_position_formatted; + { + // Bypass the `getNumTypeConstituents(typeId) == (int)constituents.size()` + // assertion in createCompositeConstruct, OpCompositeConstruct can + // construct vectors not only from scalars, but also from other vectors. + std::unique_ptr composite_construct_op = std::make_unique( + builder_->getUniqueId(), type_float4_, spv::OpCompositeConstruct); + composite_construct_op->addIdOperand(position_xyz); + composite_construct_op->addIdOperand(position_w); + guest_position_formatted = composite_construct_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(composite_construct_op)); + } + uint32_t& user_clip_plane_next_component = shader_modification.vertex.user_clip_plane_cull + ? cull_distance_next_component + : clip_distance_next_component; + for (uint32_t i = 0; i < shader_modification.vertex.user_clip_plane_count; ++i) { + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantUserClipPlanes)); + id_vector_temp_.push_back(builder_->makeIntConstant(int(i))); + spv::Id user_clip_plane = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + spv::Id user_clip_distance = + builder_->createBinOp(spv::OpDot, type_float_, guest_position_formatted, user_clip_plane); + id_vector_temp_.clear(); + id_vector_temp_.push_back( + builder_->makeIntConstant(int(output_per_vertex_member_clip_or_cull_distance))); + id_vector_temp_.push_back(builder_->makeIntConstant(int(user_clip_plane_next_component))); + builder_->createStore(user_clip_distance, + builder_->createAccessChain(spv::StorageClassOutput, output_per_vertex_, + id_vector_temp_)); + ++user_clip_plane_next_component; + } + } + + // Apply the NDC scale and offset for guest to host viewport transformation. + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantNdcScale)); + spv::Id ndc_scale = + builder_->createLoad(builder_->createAccessChain(spv::StorageClassUniform, + uniform_system_constants_, id_vector_temp_), + spv::NoPrecision); + position_xyz = + builder_->createNoContractionBinOp(spv::OpFMul, type_float3_, position_xyz, ndc_scale); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantNdcOffset)); + spv::Id ndc_offset = + builder_->createLoad(builder_->createAccessChain(spv::StorageClassUniform, + uniform_system_constants_, id_vector_temp_), + spv::NoPrecision); + spv::Id ndc_offset_mul_w = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float3_, ndc_offset, position_w); + position_xyz = + builder_->createNoContractionBinOp(spv::OpFAdd, type_float3_, position_xyz, ndc_offset_mul_w); + + spv::Id kill_vertex = spv::NoResult; + if (current_shader().writes_point_size_edge_flag_kill_vertex() & 0b100) { + assert_true(var_main_point_size_edge_flag_kill_vertex_ != spv::NoResult); + id_vector_temp_.clear(); + // Z component. + id_vector_temp_.push_back(builder_->makeIntConstant(2)); + spv::Id kill_vertex_bits = builder_->createUnaryOp( + spv::OpBitcast, type_uint_, + builder_->createLoad(builder_->createAccessChain(spv::StorageClassFunction, + var_main_point_size_edge_flag_kill_vertex_, + id_vector_temp_), + spv::NoPrecision)); + kill_vertex = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, kill_vertex_bits, + builder_->makeUintConstant(UINT32_C(0x7FFFFFFF))), + const_uint_0_); + } + if (kill_vertex != spv::NoResult && shader_modification.vertex.vertex_kill_and && + output_per_vertex_member_cull_distance_ != UINT32_MAX) { + // In AND mode, kill via cull distance so the primitive is culled only if + // all vertices request kill. + id_vector_temp_.clear(); + id_vector_temp_.push_back( + builder_->makeIntConstant(int(output_per_vertex_member_cull_distance_))); + id_vector_temp_.push_back(builder_->makeIntConstant(int(cull_distance_next_component))); + builder_->createStore( + builder_->createTriOp(spv::OpSelect, type_float_, kill_vertex, + builder_->makeFloatConstant(-1.0f), const_float_0_), + builder_->createAccessChain(spv::StorageClassOutput, output_per_vertex_, id_vector_temp_)); + ++cull_distance_next_component; + } else if (kill_vertex != spv::NoResult) { + // OR mode - kill the primitive by setting W to NaN. + position_w = builder_->createTriOp( + spv::OpSelect, type_float_, kill_vertex, + builder_->createUnaryOp(spv::OpBitcast, type_float_, + builder_->makeUintConstant(UINT32_C(0x7FC00000))), + position_w); + } + + // Write the point size. + if (output_point_size_ != spv::NoResult) { + spv::Id point_size; + if (current_shader().writes_point_size_edge_flag_kill_vertex() & 0b001) { + assert_true(var_main_point_size_edge_flag_kill_vertex_ != spv::NoResult); + id_vector_temp_.clear(); + // X vector component. + id_vector_temp_.push_back(const_int_0_); + point_size = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassFunction, + var_main_point_size_edge_flag_kill_vertex_, id_vector_temp_), + spv::NoPrecision); + } else { + // Not statically overridden - write a negative value. + point_size = builder_->makeFloatConstant(-1.0f); + } + builder_->createStore(point_size, output_point_size_); + } + + // Expand the point sprite. + if (shader_modification.vertex.host_vertex_shader_type == + Shader::HostVertexShaderType::kPointListAsTriangleStrip) { + // Top-left, bottom-left, top-right, bottom-right order (chosen arbitrarily, + // simply based on counterclockwise meaning front with + // frontFace = VkFrontFace(0), but faceness is ignored for non-polygon + // primitive types). + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeUintConstant(0b10)); + id_vector_temp_.push_back(builder_->makeUintConstant(0b01)); + spv::Id point_vertex_positive = builder_->createBinOp( + spv::OpINotEqual, type_bool2_, + builder_->createBinOp( + spv::OpBitwiseAnd, type_uint2_, + builder_->smearScalar(spv::NoPrecision, + builder_->createUnaryOp( + spv::OpBitcast, type_uint_, + builder_->createLoad(input_vertex_index_, spv::NoPrecision)), + type_uint2_), + builder_->createCompositeConstruct(type_uint2_, id_vector_temp_)), + SpirvSmearScalarResultOrConstant(const_uint_0_, type_uint2_)); + + // Load the point diameter in guest pixels, with the override from the + // vertex shader if provided. + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantPointConstantDiameter)); + spv::Id point_guest_diameter = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + if (current_shader().writes_point_size_edge_flag_kill_vertex() & 0b001) { + assert_true(var_main_point_size_edge_flag_kill_vertex_ != spv::NoResult); + id_vector_temp_.clear(); + id_vector_temp_.push_back(const_int_0_); + spv::Id point_vertex_diameter = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassFunction, + var_main_point_size_edge_flag_kill_vertex_, id_vector_temp_), + spv::NoPrecision); + // The vertex shader's header writes -1.0 to point_size by default, so any + // non-negative value means that it was overwritten by the translated + // vertex shader, and needs to be used instead of the constant size. The + // per-vertex diameter has already been clamped earlier in translation + // (combined with making it non-negative). + point_guest_diameter = builder_->createTriOp( + spv::OpSelect, type_float2_, + builder_->smearScalar(spv::NoPrecision, + builder_->createBinOp(spv::OpFOrdGreaterThanEqual, type_bool_, + point_vertex_diameter, const_float_0_), + type_bool2_), + builder_->smearScalar(spv::NoPrecision, point_vertex_diameter, type_float2_), + point_guest_diameter); + } + // Transform the diameter in the guest screen coordinates to radius in the + // normalized device coordinates. + id_vector_temp_.clear(); + id_vector_temp_.push_back( + builder_->makeIntConstant(kSystemConstantPointScreenDiameterToNdcRadius)); + spv::Id point_radius = builder_->createNoContractionBinOp( + spv::OpFMul, type_float2_, point_guest_diameter, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision)); + // Transform the radius from the normalized device coordinates to the clip + // space. + point_radius = builder_->createNoContractionBinOp(spv::OpVectorTimesScalar, type_float2_, + point_radius, position_w); + + // Expand the point sprite in the direction for the current host vertex. + uint_vector_temp_.clear(); + uint_vector_temp_.push_back(0); + uint_vector_temp_.push_back(1); + spv::Id point_position_xy = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float2_, + builder_->createRvalueSwizzle(spv::NoPrecision, type_float2_, position_xyz, + uint_vector_temp_), + builder_->createTriOp( + spv::OpSelect, type_float2_, point_vertex_positive, point_radius, + builder_->createNoContractionUnaryOp(spv::OpFNegate, type_float2_, point_radius))); + spv::Id point_position_z = builder_->createCompositeExtract(position_xyz, type_float_, 2); + + // Store the position. + spv::Id position; + { + // Bypass the `getNumTypeConstituents(typeId) == (int)constituents.size()` + // assertion in createCompositeConstruct, OpCompositeConstruct can + // construct vectors not only from scalars, but also from other vectors. + std::unique_ptr composite_construct_op = std::make_unique( + builder_->getUniqueId(), type_float4_, spv::OpCompositeConstruct); + composite_construct_op->addIdOperand(point_position_xy); + composite_construct_op->addIdOperand(point_position_z); + composite_construct_op->addIdOperand(position_w); + position = composite_construct_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(composite_construct_op)); + } + builder_->createStore(position, position_ptr); + + // Write the point coordinates. + if (output_point_coordinates_ != spv::NoResult) { + builder_->createStore( + builder_->createTriOp(spv::OpSelect, type_float2_, point_vertex_positive, const_float2_1_, + const_float2_0_), + output_point_coordinates_); + } + + bool point_recalculate_clip_distances = shader_modification.vertex.user_clip_plane_count && + !shader_modification.vertex.user_clip_plane_cull && + shader_modification.vertex.point_ps_ucp_mode >= 2; + bool point_recalculate_cull_distances = shader_modification.vertex.user_clip_plane_count && + shader_modification.vertex.user_clip_plane_cull && + shader_modification.vertex.point_ps_ucp_mode >= 3; + if (point_recalculate_clip_distances || point_recalculate_cull_distances) { + uint32_t output_per_vertex_member_user_clip_distance = + point_recalculate_cull_distances ? output_per_vertex_member_cull_distance_ + : output_per_vertex_member_clip_distance_; + assert_true(output_per_vertex_member_user_clip_distance != UINT32_MAX); + + // Convert host clip space back to guest clip space before applying user + // clip planes. + spv::Id point_position_xyz; + { + std::unique_ptr composite_construct_op = + std::make_unique(builder_->getUniqueId(), type_float3_, + spv::OpCompositeConstruct); + composite_construct_op->addIdOperand(point_position_xy); + composite_construct_op->addIdOperand(point_position_z); + point_position_xyz = composite_construct_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(composite_construct_op)); + } + spv::Id point_guest_position_xyz = builder_->createNoContractionBinOp( + spv::OpFSub, type_float3_, point_position_xyz, + builder_->createNoContractionBinOp(spv::OpVectorTimesScalar, type_float3_, ndc_offset, + position_w)); + point_guest_position_xyz = builder_->createNoContractionBinOp( + spv::OpFDiv, type_float3_, point_guest_position_xyz, ndc_scale); + spv::Id point_guest_position; + { + std::unique_ptr composite_construct_op = + std::make_unique(builder_->getUniqueId(), type_float4_, + spv::OpCompositeConstruct); + composite_construct_op->addIdOperand(point_guest_position_xyz); + composite_construct_op->addIdOperand(position_w); + point_guest_position = composite_construct_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(composite_construct_op)); + } + + for (uint32_t i = 0; i < shader_modification.vertex.user_clip_plane_count; ++i) { + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantUserClipPlanes)); + id_vector_temp_.push_back(builder_->makeIntConstant(int(i))); + spv::Id user_clip_plane = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + spv::Id user_clip_distance = + builder_->createBinOp(spv::OpDot, type_float_, point_guest_position, user_clip_plane); + id_vector_temp_.clear(); + id_vector_temp_.push_back( + builder_->makeIntConstant(int(output_per_vertex_member_user_clip_distance))); + id_vector_temp_.push_back(builder_->makeIntConstant(int(i))); + builder_->createStore(user_clip_distance, + builder_->createAccessChain(spv::StorageClassOutput, + output_per_vertex_, id_vector_temp_)); + } + } + } else { + // Store the position converted to the host. + spv::Id position; + { + // Bypass the `getNumTypeConstituents(typeId) == (int)constituents.size()` + // assertion in createCompositeConstruct, OpCompositeConstruct can + // construct vectors not only from scalars, but also from other vectors. + std::unique_ptr composite_construct_op = std::make_unique( + builder_->getUniqueId(), type_float4_, spv::OpCompositeConstruct); + composite_construct_op->addIdOperand(position_xyz); + composite_construct_op->addIdOperand(position_w); + position = composite_construct_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(composite_construct_op)); + } + builder_->createStore(position, position_ptr); + } +} + +void SpirvShaderTranslator::StartFragmentShaderBeforeMain() { + Modification shader_modification = GetSpirvShaderModification(); + + if (edram_fragment_shader_interlock_) { + builder_->addExtension("SPV_EXT_fragment_shader_interlock"); + + // EDRAM buffer uint[]. + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeRuntimeArray(type_uint_)); + // Storage buffers have std430 packing, no padding to 4-component vectors. + builder_->addDecoration(id_vector_temp_.back(), spv::DecorationArrayStride, sizeof(uint32_t)); + spv::Id type_edram = builder_->makeStructType(id_vector_temp_, "XeEdram"); + builder_->addMemberName(type_edram, 0, "edram"); + builder_->addMemberDecoration(type_edram, 0, spv::DecorationCoherent); + builder_->addMemberDecoration(type_edram, 0, spv::DecorationRestrict); + builder_->addMemberDecoration(type_edram, 0, spv::DecorationOffset, 0); + builder_->addDecoration(type_edram, features_.spirv_version >= spv::Spv_1_3 + ? spv::DecorationBlock + : spv::DecorationBufferBlock); + buffer_edram_ = builder_->createVariable(spv::NoPrecision, + features_.spirv_version >= spv::Spv_1_3 + ? spv::StorageClassStorageBuffer + : spv::StorageClassUniform, + type_edram, "xe_edram"); + builder_->addDecoration(buffer_edram_, spv::DecorationDescriptorSet, + int(kDescriptorSetSharedMemoryAndEdram)); + builder_->addDecoration(buffer_edram_, spv::DecorationBinding, 1); + if (features_.spirv_version >= spv::Spv_1_4) { + main_interface_.push_back(buffer_edram_); + } + } + + bool param_gen_needed = + !is_depth_only_fragment_shader_ && GetPsParamGenInterpolator() != UINT32_MAX; + + if (!is_depth_only_fragment_shader_) { + uint32_t input_location = 0; + + // Interpolator inputs. + { + uint32_t interpolators_remaining = GetModificationInterpolatorMask(); + uint32_t interpolator_index; + while (rex::bit_scan_forward(interpolators_remaining, &interpolator_index)) { + interpolators_remaining &= ~(UINT32_C(1) << interpolator_index); + spv::Id interpolator = builder_->createVariable( + spv::NoPrecision, spv::StorageClassInput, type_float4_, + fmt::format("xe_in_interpolator_{}", interpolator_index).c_str()); + input_output_interpolators_[interpolator_index] = interpolator; + builder_->addDecoration(interpolator, spv::DecorationLocation, int(input_location)); + if (shader_modification.pixel.interpolators_centroid & + (UINT32_C(1) << interpolator_index)) { + builder_->addDecoration(interpolator, spv::DecorationCentroid); + } + main_interface_.push_back(interpolator); + ++input_location; + } + } + + // Point coordinate input. + if (shader_modification.pixel.param_gen_point) { + if (param_gen_needed) { + input_point_coordinates_ = builder_->createVariable( + spv::NoPrecision, spv::StorageClassInput, type_float2_, "xe_in_point_coordinates"); + builder_->addDecoration(input_point_coordinates_, spv::DecorationLocation, + int(input_location)); + main_interface_.push_back(input_point_coordinates_); + } + ++input_location; + } + } + + bool float24_depth_conversion = IsWritingFloat24Depth(); + bool float24_depth_from_fragment_coordinates = + float24_depth_conversion && !current_shader().writes_depth(); + bool alpha_to_coverage_possible = !is_depth_only_fragment_shader_ && + current_shader().writes_color_target(0) && + !IsExecutionModeEarlyFragmentTests(); + + // Fragment coordinates. + // TODO(Triang3l): More conditions - alpha to coverage (if RT 0 is written, + // and there's no early depth / stencil), depth writing in the fragment shader + // (per-sample if supported). + bool memexport_resolution_scaled = current_shader().memexport_eM_written() && + (draw_resolution_scale_x_ > 1 || draw_resolution_scale_y_ > 1); + if (edram_fragment_shader_interlock_ || param_gen_needed || memexport_resolution_scaled || + float24_depth_from_fragment_coordinates || alpha_to_coverage_possible) { + input_fragment_coordinates_ = builder_->createVariable(spv::NoPrecision, spv::StorageClassInput, + type_float4_, "gl_FragCoord"); + builder_->addDecoration(input_fragment_coordinates_, spv::DecorationBuiltIn, + spv::BuiltInFragCoord); + main_interface_.push_back(input_fragment_coordinates_); + } + + // Is front facing. + if (edram_fragment_shader_interlock_ || + (param_gen_needed && !GetSpirvShaderModification().pixel.param_gen_point)) { + input_front_facing_ = builder_->createVariable(spv::NoPrecision, spv::StorageClassInput, + type_bool_, "gl_FrontFacing"); + builder_->addDecoration(input_front_facing_, spv::DecorationBuiltIn, spv::BuiltInFrontFacing); + main_interface_.push_back(input_front_facing_); + } + + // Sample mask input. + if (edram_fragment_shader_interlock_ || IsSampleRate() || + (alpha_to_coverage_possible && features_.sample_rate_shading)) { + // SampleMask depends on SampleRateShading in some SPIR-V revisions. + builder_->addCapability(spv::CapabilitySampleRateShading); + } + if (IsSampleRate()) { + input_sample_id_ = builder_->createVariable(spv::NoPrecision, spv::StorageClassInput, type_int_, + "gl_SampleID"); + builder_->addDecoration(input_sample_id_, spv::DecorationFlat); + builder_->addDecoration(input_sample_id_, spv::DecorationBuiltIn, spv::BuiltInSampleId); + main_interface_.push_back(input_sample_id_); + } + if (edram_fragment_shader_interlock_) { + input_sample_mask_ = builder_->createVariable( + spv::NoPrecision, spv::StorageClassInput, + builder_->makeArrayType(type_int_, builder_->makeUintConstant(1), 0), "gl_SampleMaskIn"); + builder_->addDecoration(input_sample_mask_, spv::DecorationFlat); + builder_->addDecoration(input_sample_mask_, spv::DecorationBuiltIn, spv::BuiltInSampleMask); + main_interface_.push_back(input_sample_mask_); + } + + if (!edram_fragment_shader_interlock_) { + // Framebuffer color attachment outputs. + std::fill(output_or_var_fragment_data_.begin(), output_or_var_fragment_data_.end(), + spv::NoResult); + if (!is_depth_only_fragment_shader_) { + static const char* const kFragmentDataOutputNames[] = { + "xe_out_fragment_data_0", + "xe_out_fragment_data_1", + "xe_out_fragment_data_2", + "xe_out_fragment_data_3", + }; + uint32_t color_targets_remaining = current_shader().writes_color_targets(); + uint32_t color_target_index; + while (rex::bit_scan_forward(color_targets_remaining, &color_target_index)) { + color_targets_remaining &= ~(UINT32_C(1) << color_target_index); + spv::Id output_fragment_data_rt = + builder_->createVariable(spv::NoPrecision, spv::StorageClassOutput, type_float4_, + kFragmentDataOutputNames[color_target_index]); + output_or_var_fragment_data_[color_target_index] = output_fragment_data_rt; + builder_->addDecoration(output_fragment_data_rt, spv::DecorationLocation, + int(color_target_index)); + // Make invariant as pixel shaders may be used for various precise + // computations. + builder_->addDecoration(output_fragment_data_rt, spv::DecorationInvariant); + main_interface_.push_back(output_fragment_data_rt); + } + } + output_fragment_depth_ = spv::NoResult; + output_fragment_sample_mask_ = spv::NoResult; + if (current_shader().writes_depth() || float24_depth_conversion) { + output_fragment_depth_ = builder_->createVariable(spv::NoPrecision, spv::StorageClassOutput, + type_float_, "gl_FragDepth"); + builder_->addDecoration(output_fragment_depth_, spv::DecorationBuiltIn, + spv::BuiltInFragDepth); + main_interface_.push_back(output_fragment_depth_); + } + if (alpha_to_coverage_possible && features_.sample_rate_shading) { + output_fragment_sample_mask_ = builder_->createVariable( + spv::NoPrecision, spv::StorageClassOutput, + builder_->makeArrayType(type_int_, builder_->makeUintConstant(1), 0), "gl_SampleMask"); + builder_->addDecoration(output_fragment_sample_mask_, spv::DecorationBuiltIn, + spv::BuiltInSampleMask); + main_interface_.push_back(output_fragment_sample_mask_); + } + } +} + +void SpirvShaderTranslator::StartFragmentShaderInMain() { + // Set up pixel killing from within the translated shader without affecting + // the control flow (unlike with OpKill), similarly to how pixel killing works + // on the Xenos, and also keeping a single critical section exit and return + // for safety across different Vulkan implementations with fragment shader + // interlock. + if (current_shader().kills_pixels()) { + if (features_.demote_to_helper_invocation) { + // TODO(Triang3l): Promoted to SPIR-V 1.6 - don't add the extension there. + builder_->addExtension("SPV_EXT_demote_to_helper_invocation"); + builder_->addCapability(spv::CapabilityDemoteToHelperInvocationEXT); + } else { + var_main_kill_pixel_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassFunction, type_bool_, + "xe_var_kill_pixel", builder_->makeBoolConstant(false)); + } + // For killing with fragment shader interlock when demotion is supported, + // using OpIsHelperInvocationEXT to avoid allocating a variable in addition + // to the execution mask GPUs naturally have. + } + + if (edram_fragment_shader_interlock_) { + // Initialize color output variables with fragment shader interlock. + std::fill(output_or_var_fragment_data_.begin(), output_or_var_fragment_data_.end(), + spv::NoResult); + var_main_fragment_depth_ = spv::NoResult; + var_main_fsi_color_written_ = spv::NoResult; + if (current_shader().writes_depth()) { + var_main_fragment_depth_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassFunction, type_float_, + "xe_var_fragment_depth", const_float_0_); + } + uint32_t color_targets_written = current_shader().writes_color_targets(); + if (color_targets_written) { + static const char* const kFragmentDataVariableNames[] = { + "xe_var_fragment_data_0", + "xe_var_fragment_data_1", + "xe_var_fragment_data_2", + "xe_var_fragment_data_3", + }; + uint32_t color_targets_remaining = color_targets_written; + uint32_t color_target_index; + while (rex::bit_scan_forward(color_targets_remaining, &color_target_index)) { + color_targets_remaining &= ~(UINT32_C(1) << color_target_index); + output_or_var_fragment_data_[color_target_index] = builder_->createVariable( + spv::NoPrecision, spv::StorageClassFunction, type_float4_, + kFragmentDataVariableNames[color_target_index], const_float4_0_); + } + var_main_fsi_color_written_ = + builder_->createVariable(spv::NoPrecision, spv::StorageClassFunction, type_uint_, + "xe_var_fsi_color_written", const_uint_0_); + } + } + + if (edram_fragment_shader_interlock_ && FSI_IsDepthStencilEarly()) { + spv::Id msaa_samples = LoadMsaaSamplesFromFlags(); + FSI_LoadSampleMask(msaa_samples); + FSI_LoadEdramOffsets(msaa_samples); + builder_->createNoResultOp(spv::OpBeginInvocationInterlockEXT); + FSI_DepthStencilTest(msaa_samples, false); + if (!is_depth_only_fragment_shader_) { + // Skip the rest of the shader if the whole quad (due to derivatives) has + // failed the depth / stencil test, and there are no depth and stencil + // values to conditionally write after running the shader to check if + // samples don't additionally need to be discarded. + spv::Id quad_needs_execution = + builder_->createBinOp(spv::OpINotEqual, type_bool_, main_fsi_sample_mask_, const_uint_0_); + // TODO(Triang3l): Use GroupNonUniformQuad operations where supported. + // If none of the pixels in the quad passed the depth / stencil test, the + // value of (any samples covered ? 1.0f : 0.0f) for the current pixel will + // be 0.0f, and since it will be 0.0f in other pixels too, the derivatives + // will be zero as well. + builder_->addCapability(spv::CapabilityDerivativeControl); + // Query the horizontally adjacent pixel. + quad_needs_execution = builder_->createBinOp( + spv::OpLogicalOr, type_bool_, quad_needs_execution, + builder_->createBinOp( + spv::OpFOrdNotEqual, type_bool_, + builder_->createUnaryOp( + spv::OpDPdxFine, type_float_, + builder_->createTriOp(spv::OpSelect, type_float_, quad_needs_execution, + const_float_1_, const_float_0_)), + const_float_0_)); + // Query the vertically adjacent pair of pixels. + quad_needs_execution = builder_->createBinOp( + spv::OpLogicalOr, type_bool_, quad_needs_execution, + builder_->createBinOp( + spv::OpFOrdNotEqual, type_bool_, + builder_->createUnaryOp( + spv::OpDPdyCoarse, type_float_, + builder_->createTriOp(spv::OpSelect, type_float_, quad_needs_execution, + const_float_1_, const_float_0_)), + const_float_0_)); + spv::Block& main_fsi_early_depth_stencil_execute_quad = builder_->makeNewBlock(); + main_fsi_early_depth_stencil_execute_quad_merge_ = &builder_->makeNewBlock(); + builder_->createSelectionMerge(main_fsi_early_depth_stencil_execute_quad_merge_, + spv::SelectionControlDontFlattenMask); + builder_->createConditionalBranch(quad_needs_execution, + &main_fsi_early_depth_stencil_execute_quad, + main_fsi_early_depth_stencil_execute_quad_merge_); + builder_->setBuildPoint(&main_fsi_early_depth_stencil_execute_quad); + } + } + + if (is_depth_only_fragment_shader_) { + return; + } + + if (current_shader().memexport_eM_written()) { + // Make sure memexport is done only once for a guest pixel. + uint32_t resolution_scaled_axes = + uint32_t(draw_resolution_scale_x_ > 1) | (uint32_t(draw_resolution_scale_y_ > 1) << 1); + if (resolution_scaled_axes) { + assert_true(input_fragment_coordinates_ != spv::NoResult); + spv::Id memexport_allowed = spv::NoResult; + for (uint32_t i = 0; i < 2; ++i) { + if (!(resolution_scaled_axes & (UINT32_C(1) << i))) { + continue; + } + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(int(i))); + spv::Id position = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassInput, input_fragment_coordinates_, + id_vector_temp_), + spv::NoPrecision); + spv::Id position_mod = builder_->createBinOp( + spv::OpUMod, type_uint_, + builder_->createUnaryOp(spv::OpConvertFToU, type_uint_, position), + builder_->makeUintConstant(i ? draw_resolution_scale_y_ : draw_resolution_scale_x_)); + spv::Id position_is_center = + builder_->createBinOp(spv::OpIEqual, type_bool_, position_mod, + builder_->makeUintConstant(i ? (draw_resolution_scale_y_ >> 1) + : (draw_resolution_scale_x_ >> 1))); + memexport_allowed = memexport_allowed != spv::NoResult + ? builder_->createBinOp(spv::OpLogicalAnd, type_bool_, + memexport_allowed, position_is_center) + : position_is_center; + } + assert_true(memexport_allowed != spv::NoResult); + main_memexport_allowed_ = + main_memexport_allowed_ != spv::NoResult + ? builder_->createBinOp(spv::OpLogicalAnd, type_bool_, main_memexport_allowed_, + memexport_allowed) + : memexport_allowed; + } + if (IsSampleRate()) { + assert_true(input_sample_id_ != spv::NoResult); + spv::Id sample_id = builder_->createUnaryOp( + spv::OpBitcast, type_uint_, builder_->createLoad(input_sample_id_, spv::NoPrecision)); + spv::Id msaa_samples = LoadMsaaSamplesFromFlags(); + spv::Id preferred_sample = builder_->createTriOp( + spv::OpSelect, type_uint_, + builder_->createBinOp(spv::OpUGreaterThanEqual, type_bool_, msaa_samples, + builder_->makeUintConstant(uint32_t(xenos::MsaaSamples::k4X))), + builder_->makeUintConstant(3), + builder_->createTriOp( + spv::OpSelect, type_uint_, + builder_->createBinOp(spv::OpUGreaterThanEqual, type_bool_, msaa_samples, + builder_->makeUintConstant(uint32_t(xenos::MsaaSamples::k2X))), + builder_->makeUintConstant(native_2x_msaa_with_attachments_ ? 1u : 3u), + const_uint_0_)); + // gl_SampleMaskIn on Vulkan may not include coverage bits for other + // sample invocations, unlike Direct3D SV_Coverage - use the sample + // that's the most friendly to the half-pixel offset. + spv::Id sample_preferred = + builder_->createBinOp(spv::OpIEqual, type_bool_, sample_id, preferred_sample); + main_memexport_allowed_ = + main_memexport_allowed_ != spv::NoResult + ? builder_->createBinOp(spv::OpLogicalAnd, type_bool_, main_memexport_allowed_, + sample_preferred) + : sample_preferred; + } + } + + uint32_t param_gen_interpolator = GetPsParamGenInterpolator(); + + // Zero general-purpose registers to prevent crashes when the game + // references them after only initializing them conditionally, and copy + // interpolants to GPRs. + uint32_t interpolator_mask = GetModificationInterpolatorMask(); + for (uint32_t i = 0; i < register_count(); ++i) { + if (i == param_gen_interpolator) { + continue; + } + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(int(i))); + builder_->createStore( + (i < xenos::kMaxInterpolators && (interpolator_mask & (UINT32_C(1) << i))) + ? builder_->createLoad(input_output_interpolators_[i], spv::NoPrecision) + : const_float4_0_, + builder_->createAccessChain(spv::StorageClassFunction, var_main_registers_, + id_vector_temp_)); + } + + // Pixel parameters. + if (param_gen_interpolator != UINT32_MAX) { + Modification modification = GetSpirvShaderModification(); + // Rounding the position down, and taking the absolute value, so in case the + // host GPU for some reason has quads used for derivative calculation at odd + // locations, the left and top edges will have correct derivative magnitude + // and LODs. + // Assuming that if PsParamGen is needed at all, param_gen_point is always + // set for point primitives, and is always disabled for other primitive + // types. + // OpFNegate requires sign bit flipping even for 0.0 (in this case, the + // first column or row of pixels) only since SPIR-V 1.5 revision 2 (not the + // base 1.5). + // TODO(Triang3l): When SPIR-V 1.6 is used in Xenia, see if OpFNegate can be + // used there, should be cheaper because it may be implemented as a hardware + // instruction modifier, though it respects the rule for subnormal numbers - + // see the actual hardware instructions in both OpBitwiseXor and OpFNegate + // cases. + spv::Id const_sign_bit = builder_->makeUintConstant(UINT32_C(1) << 31); + // X - pixel X .0 in the magnitude, is back-facing in the sign bit. + assert_true(input_fragment_coordinates_ != spv::NoResult); + id_vector_temp_.clear(); + id_vector_temp_.push_back(const_int_0_); + spv::Id param_gen_x = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450Floor, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassInput, input_fragment_coordinates_, + id_vector_temp_), + spv::NoPrecision)); + if (draw_resolution_scale_x_ > 1) { + param_gen_x = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, param_gen_x, + builder_->makeFloatConstant(1.0f / float(draw_resolution_scale_x_))); + } + param_gen_x = builder_->createUnaryBuiltinCall(type_float_, ext_inst_glsl_std_450_, + GLSLstd450FAbs, param_gen_x); + if (!modification.pixel.param_gen_point) { + assert_true(input_front_facing_ != spv::NoResult); + param_gen_x = builder_->createTriOp( + spv::OpSelect, type_float_, + builder_->createBinOp( + spv::OpLogicalOr, type_bool_, + builder_->createBinOp( + spv::OpIEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(kSysFlag_PrimitivePolygonal)), + const_uint_0_), + builder_->createLoad(input_front_facing_, spv::NoPrecision)), + param_gen_x, + builder_->createUnaryOp( + spv::OpBitcast, type_float_, + builder_->createBinOp( + spv::OpBitwiseXor, type_uint_, + builder_->createUnaryOp(spv::OpBitcast, type_uint_, param_gen_x), + const_sign_bit))); + } + // Y - pixel Y .0 in the magnitude, is point in the sign bit. + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(1)); + spv::Id param_gen_y = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450Floor, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassInput, input_fragment_coordinates_, + id_vector_temp_), + spv::NoPrecision)); + if (draw_resolution_scale_y_ > 1) { + param_gen_y = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, param_gen_y, + builder_->makeFloatConstant(1.0f / float(draw_resolution_scale_y_))); + } + param_gen_y = builder_->createUnaryBuiltinCall(type_float_, ext_inst_glsl_std_450_, + GLSLstd450FAbs, param_gen_y); + if (modification.pixel.param_gen_point) { + param_gen_y = builder_->createUnaryOp( + spv::OpBitcast, type_float_, + builder_->createBinOp(spv::OpBitwiseXor, type_uint_, + builder_->createUnaryOp(spv::OpBitcast, type_uint_, param_gen_y), + const_sign_bit)); + } + // Z - point S in the magnitude, is line in the sign bit. + // W - point T in the magnitude. + spv::Id param_gen_z, param_gen_w; + if (modification.pixel.param_gen_point) { + assert_true(input_point_coordinates_ != spv::NoResult); + // Saturate to avoid negative point coordinates if the center of the pixel + // is not covered, and extrapolation is done. + spv::Id param_gen_point_coordinates = builder_->createTriBuiltinCall( + type_float2_, ext_inst_glsl_std_450_, GLSLstd450NClamp, + builder_->createLoad(input_point_coordinates_, spv::NoPrecision), const_float2_0_, + const_float2_1_); + param_gen_z = builder_->createCompositeExtract(param_gen_point_coordinates, type_float_, 0); + param_gen_w = builder_->createCompositeExtract(param_gen_point_coordinates, type_float_, 1); + } else { + param_gen_z = builder_->createUnaryOp( + spv::OpBitcast, type_float_, + builder_->createTriOp( + spv::OpSelect, type_uint_, + builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(kSysFlag_PrimitiveLine)), + const_uint_0_), + const_sign_bit, const_uint_0_)); + param_gen_w = const_float_0_; + } + // Store the pixel parameters. + id_vector_temp_.clear(); + id_vector_temp_.push_back(param_gen_x); + id_vector_temp_.push_back(param_gen_y); + id_vector_temp_.push_back(param_gen_z); + id_vector_temp_.push_back(param_gen_w); + spv::Id param_gen = builder_->createCompositeConstruct(type_float4_, id_vector_temp_); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(int(param_gen_interpolator))); + builder_->createStore( + param_gen, builder_->createAccessChain(spv::StorageClassFunction, var_main_registers_, + id_vector_temp_)); + } + + if (!edram_fragment_shader_interlock_) { + // Initialize the colors for safety. + for (uint32_t i = 0; i < xenos::kMaxColorRenderTargets; ++i) { + spv::Id output_fragment_data_rt = output_or_var_fragment_data_[i]; + if (output_fragment_data_rt != spv::NoResult) { + builder_->createStore(const_float4_0_, output_fragment_data_rt); + } + } + if (output_fragment_depth_ != spv::NoResult) { + // Keep output deterministic if oDepth is not written on a control flow + // path. + builder_->createStore(const_float_0_, output_fragment_depth_); + } + } +} + +void SpirvShaderTranslator::UpdateExecConditionals(ParsedExecInstruction::Type type, + uint32_t bool_constant_index, bool condition) { + // Check if we can merge the new exec with the previous one, or the jump with + // the previous exec. The instruction-level predicate check is also merged in + // this case. + if (type == ParsedExecInstruction::Type::kConditional) { + // Can merge conditional with conditional, as long as the bool constant and + // the expected values are the same. + if (cf_exec_conditional_merge_ && cf_exec_bool_constant_or_predicate_ == bool_constant_index && + cf_exec_condition_ == condition) { + return; + } + } else if (type == ParsedExecInstruction::Type::kPredicated) { + // Can merge predicated with predicated if the conditions are the same and + // the previous exec hasn't modified the predicate register. + if (!cf_exec_predicate_written_ && cf_exec_conditional_merge_ && + cf_exec_bool_constant_or_predicate_ == kCfExecBoolConstantPredicate && + cf_exec_condition_ == condition) { + return; + } + } else { + // Can merge unconditional with unconditional. + assert_true(type == ParsedExecInstruction::Type::kUnconditional); + if (!cf_exec_conditional_merge_) { + return; + } + } + + CloseExecConditionals(); + + if (type == ParsedExecInstruction::Type::kUnconditional) { + return; + } + + EnsureBuildPointAvailable(); + spv::Id condition_id; + if (type == ParsedExecInstruction::Type::kConditional) { + id_vector_temp_.clear(); + // Bool constants (member 0). + id_vector_temp_.push_back(const_int_0_); + // 128-bit vector. + id_vector_temp_.push_back(builder_->makeIntConstant(int(bool_constant_index >> 7))); + // 32-bit scalar of a 128-bit vector. + id_vector_temp_.push_back(builder_->makeIntConstant(int((bool_constant_index >> 5) & 3))); + spv::Id bool_constant_scalar = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_bool_loop_constants_, + id_vector_temp_), + spv::NoPrecision); + condition_id = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp( + spv::OpBitwiseAnd, type_uint_, bool_constant_scalar, + builder_->makeUintConstant(uint32_t(1) << (bool_constant_index & 31))), + const_uint_0_); + cf_exec_bool_constant_or_predicate_ = bool_constant_index; + } else if (type == ParsedExecInstruction::Type::kPredicated) { + condition_id = builder_->createLoad(var_main_predicate_, spv::NoPrecision); + cf_exec_bool_constant_or_predicate_ = kCfExecBoolConstantPredicate; + } else { + assert_unhandled_case(type); + return; + } + cf_exec_condition_ = condition; + cf_exec_conditional_merge_ = + new spv::Block(builder_->getUniqueId(), builder_->getBuildPoint()->getParent()); + builder_->createSelectionMerge(cf_exec_conditional_merge_, spv::SelectionControlDontFlattenMask); + spv::Block& inner_block = builder_->makeNewBlock(); + builder_->createConditionalBranch(condition_id, + condition ? &inner_block : cf_exec_conditional_merge_, + condition ? cf_exec_conditional_merge_ : &inner_block); + builder_->setBuildPoint(&inner_block); +} + +void SpirvShaderTranslator::UpdateInstructionPredication(bool predicated, bool condition) { + if (!predicated) { + CloseInstructionPredication(); + return; + } + + if (cf_instruction_predicate_merge_) { + if (cf_instruction_predicate_condition_ == condition) { + // Already in the needed instruction-level conditional. + return; + } + CloseInstructionPredication(); + } + + // If the instruction predicate condition is the same as the exec predicate + // condition, no need to open a check. However, if there was a `setp` prior + // to this instruction, the predicate value now may be different than it was + // in the beginning of the exec. + if (!cf_exec_predicate_written_ && cf_exec_conditional_merge_ && + cf_exec_bool_constant_or_predicate_ == kCfExecBoolConstantPredicate && + cf_exec_condition_ == condition) { + return; + } + + cf_instruction_predicate_condition_ = condition; + EnsureBuildPointAvailable(); + spv::Id predicate_id = builder_->createLoad(var_main_predicate_, spv::NoPrecision); + spv::Block& predicated_block = builder_->makeNewBlock(); + cf_instruction_predicate_merge_ = + new spv::Block(builder_->getUniqueId(), builder_->getBuildPoint()->getParent()); + builder_->createSelectionMerge(cf_instruction_predicate_merge_, spv::SelectionControlMaskNone); + builder_->createConditionalBranch( + predicate_id, condition ? &predicated_block : cf_instruction_predicate_merge_, + condition ? cf_instruction_predicate_merge_ : &predicated_block); + builder_->setBuildPoint(&predicated_block); +} + +void SpirvShaderTranslator::CloseInstructionPredication() { + if (!cf_instruction_predicate_merge_) { + return; + } + spv::Block& inner_block = *builder_->getBuildPoint(); + if (!inner_block.isTerminated()) { + builder_->createBranch(cf_instruction_predicate_merge_); + } + inner_block.getParent().addBlock(cf_instruction_predicate_merge_); + builder_->setBuildPoint(cf_instruction_predicate_merge_); + cf_instruction_predicate_merge_ = nullptr; +} + +void SpirvShaderTranslator::CloseExecConditionals() { + // Within the exec - instruction-level predicate check. + CloseInstructionPredication(); + // Exec level. + if (cf_exec_conditional_merge_) { + spv::Block& inner_block = *builder_->getBuildPoint(); + if (!inner_block.isTerminated()) { + builder_->createBranch(cf_exec_conditional_merge_); + } + inner_block.getParent().addBlock(cf_exec_conditional_merge_); + builder_->setBuildPoint(cf_exec_conditional_merge_); + cf_exec_conditional_merge_ = nullptr; + } + // Nothing relies on the predicate value being unchanged now. + cf_exec_predicate_written_ = false; +} + +spv::Id SpirvShaderTranslator::GetStorageAddressingIndex( + InstructionStorageAddressingMode addressing_mode, uint32_t storage_index, + bool is_float_constant) { + const Shader::ConstantRegisterMap& constant_register_map = + current_shader().constant_register_map(); + EnsureBuildPointAvailable(); + spv::Id base_pointer = spv::NoResult; + switch (addressing_mode) { + case InstructionStorageAddressingMode::kAbsolute: { + uint32_t static_storage_index = storage_index; + if (is_float_constant) { + static_storage_index = constant_register_map.GetPackedFloatConstantIndex(storage_index); + assert_true(static_storage_index != UINT32_MAX); + if (static_storage_index == UINT32_MAX) { + static_storage_index = 0; + } + } + return builder_->makeIntConstant(int(static_storage_index)); + } + case InstructionStorageAddressingMode::kAddressRegisterRelative: + base_pointer = var_main_address_register_; + break; + case InstructionStorageAddressingMode::kLoopRelative: + // Load X component. + id_vector_temp_util_.clear(); + id_vector_temp_util_.push_back(const_int_0_); + base_pointer = builder_->createAccessChain(spv::StorageClassFunction, var_main_loop_address_, + id_vector_temp_util_); + break; + } + assert_true(!is_float_constant || constant_register_map.float_dynamic_addressing); + assert_true(base_pointer != spv::NoResult); + spv::Id index = builder_->createLoad(base_pointer, spv::NoPrecision); + if (storage_index) { + index = builder_->createBinOp(spv::OpIAdd, type_int_, index, + builder_->makeIntConstant(int(storage_index))); + } + return index; +} + +spv::Id SpirvShaderTranslator::LoadOperandStorage(const InstructionOperand& operand) { + spv::Id index = + GetStorageAddressingIndex(operand.storage_addressing_mode, operand.storage_index, + operand.storage_source == InstructionStorageSource::kConstantFloat); + EnsureBuildPointAvailable(); + spv::Id vec4_pointer = spv::NoResult; + switch (operand.storage_source) { + case InstructionStorageSource::kRegister: + assert_true(var_main_registers_ != spv::NoResult); + id_vector_temp_util_.clear(); + // Array element. + id_vector_temp_util_.push_back(index); + vec4_pointer = builder_->createAccessChain(spv::StorageClassFunction, var_main_registers_, + id_vector_temp_util_); + break; + case InstructionStorageSource::kConstantFloat: + assert_true(uniform_float_constants_ != spv::NoResult); + id_vector_temp_util_.clear(); + // The first and the only structure member. + id_vector_temp_util_.push_back(const_int_0_); + // Array element. + id_vector_temp_util_.push_back(index); + vec4_pointer = builder_->createAccessChain(spv::StorageClassUniform, uniform_float_constants_, + id_vector_temp_util_); + break; + default: + assert_unhandled_case(operand.storage_source); + } + assert_true(vec4_pointer != spv::NoResult); + return builder_->createLoad(vec4_pointer, spv::NoPrecision); +} + +spv::Id SpirvShaderTranslator::ApplyOperandModifiers(spv::Id operand_value, + const InstructionOperand& original_operand, + bool invert_negate, bool force_absolute) { + spv::Id type = builder_->getTypeId(operand_value); + assert_true(type != spv::NoType); + if (type == spv::NoType) { + return operand_value; + } + if (original_operand.is_absolute_value || force_absolute) { + EnsureBuildPointAvailable(); + operand_value = builder_->createUnaryBuiltinCall(type, ext_inst_glsl_std_450_, GLSLstd450FAbs, + operand_value); + } + if (original_operand.is_negated != invert_negate) { + EnsureBuildPointAvailable(); + operand_value = builder_->createNoContractionUnaryOp(spv::OpFNegate, type, operand_value); + } + return operand_value; +} + +spv::Id SpirvShaderTranslator::GetUnmodifiedOperandComponents( + spv::Id operand_storage, const InstructionOperand& original_operand, uint32_t components) { + assert_not_zero(components); + if (!components) { + return spv::NoResult; + } + assert_true(components <= 0b1111); + if (components == 0b1111 && original_operand.IsStandardSwizzle()) { + return operand_storage; + } + EnsureBuildPointAvailable(); + uint32_t component_count = rex::bit_count(components); + if (component_count == 1) { + uint32_t scalar_index; + rex::bit_scan_forward(components, &scalar_index); + return builder_->createCompositeExtract( + operand_storage, type_float_, + static_cast(original_operand.GetComponent(scalar_index)) - + static_cast(SwizzleSource::kX)); + } + uint_vector_temp_util_.clear(); + uint32_t components_remaining = components; + uint32_t component_index; + while (rex::bit_scan_forward(components_remaining, &component_index)) { + components_remaining &= ~(uint32_t(1) << component_index); + uint_vector_temp_util_.push_back( + static_cast(original_operand.GetComponent(component_index)) - + static_cast(SwizzleSource::kX)); + } + return builder_->createRvalueSwizzle(spv::NoPrecision, type_float_vectors_[component_count - 1], + operand_storage, uint_vector_temp_util_); +} + +void SpirvShaderTranslator::GetOperandScalarXY(spv::Id operand_storage, + const InstructionOperand& original_operand, + spv::Id& a_out, spv::Id& b_out, bool invert_negate, + bool force_absolute) { + spv::Id a = GetOperandComponents(operand_storage, original_operand, 0b0001, invert_negate, + force_absolute); + a_out = a; + b_out = original_operand.GetComponent(0) != original_operand.GetComponent(1) + ? GetOperandComponents(operand_storage, original_operand, 0b0010, invert_negate, + force_absolute) + : a; +} + +spv::Id SpirvShaderTranslator::GetAbsoluteOperand(spv::Id operand_storage, + const InstructionOperand& original_operand) { + if (original_operand.is_absolute_value && !original_operand.is_negated) { + return operand_storage; + } + EnsureBuildPointAvailable(); + return builder_->createUnaryBuiltinCall(builder_->getTypeId(operand_storage), + ext_inst_glsl_std_450_, GLSLstd450FAbs, operand_storage); +} + +void SpirvShaderTranslator::StoreResult(const InstructionResult& result, spv::Id value, + bool can_store_memexport_address) { + uint32_t used_write_mask = result.GetUsedWriteMask(); + if (!used_write_mask) { + return; + } + bool is_clamped = result.is_clamped; + + EnsureBuildPointAvailable(); + + spv::Id target_pointer = spv::NoResult; + switch (result.storage_target) { + case InstructionStorageTarget::kNone: + break; + case InstructionStorageTarget::kRegister: { + assert_true(var_main_registers_ != spv::NoResult); + // Must call GetStorageAddressingIndex first because of + // id_vector_temp_util_ usage in it. + spv::Id register_index = + GetStorageAddressingIndex(result.storage_addressing_mode, result.storage_index); + id_vector_temp_util_.clear(); + // Array element. + id_vector_temp_util_.push_back(register_index); + target_pointer = builder_->createAccessChain(spv::StorageClassFunction, var_main_registers_, + id_vector_temp_util_); + } break; + case InstructionStorageTarget::kInterpolator: { + assert_true(is_vertex_shader()); + target_pointer = input_output_interpolators_[result.storage_index]; + // Unused interpolators are spv::NoResult in input_output_interpolators_. + } break; + case InstructionStorageTarget::kPosition: { + assert_true(is_vertex_shader()); + id_vector_temp_util_.clear(); + id_vector_temp_util_.push_back(builder_->makeIntConstant(kOutputPerVertexMemberPosition)); + target_pointer = builder_->createAccessChain(spv::StorageClassOutput, output_per_vertex_, + id_vector_temp_util_); + } break; + case InstructionStorageTarget::kPointSizeEdgeFlagKillVertex: { + assert_true(is_vertex_shader()); + assert_zero(used_write_mask & 0b1000); + target_pointer = var_main_point_size_edge_flag_kill_vertex_; + } break; + case InstructionStorageTarget::kColor: { + assert_true(is_pixel_shader()); + assert_not_zero(used_write_mask); + assert_true(current_shader().writes_color_target(result.storage_index)); + target_pointer = output_or_var_fragment_data_[result.storage_index]; + if (edram_fragment_shader_interlock_) { + assert_true(var_main_fsi_color_written_ != spv::NoResult); + builder_->createStore( + builder_->createBinOp( + spv::OpBitwiseOr, type_uint_, + builder_->createLoad(var_main_fsi_color_written_, spv::NoPrecision), + builder_->makeUintConstant(uint32_t(1) << result.storage_index)), + var_main_fsi_color_written_); + } + } break; + case InstructionStorageTarget::kDepth: { + assert_true(is_pixel_shader()); + // Writes X to scalar gl_FragDepth. + assert_true(used_write_mask == 0b0001); + assert_true(current_shader().writes_depth()); + target_pointer = + edram_fragment_shader_interlock_ ? var_main_fragment_depth_ : output_fragment_depth_; + // Guest depth output is expected to be [0, 1]. + is_clamped = true; + } break; + case InstructionStorageTarget::kExportAddress: { + if (!can_store_memexport_address) { + return; + } + if (!current_shader().memexport_eM_written()) { + return; + } + // spv::NoResult if memory export usage is unsupported or invalid. + target_pointer = var_main_memexport_address_; + } break; + case InstructionStorageTarget::kExportData: { + assert_not_zero(current_shader().memexport_eM_written() & + (uint8_t(1) << result.storage_index)); + // spv::NoResult if memory export usage is unsupported or invalid. + target_pointer = var_main_memexport_data_[result.storage_index]; + if (target_pointer != spv::NoResult) { + // Mark that the eM# has been written to and needs to be exported. + assert_true(var_main_memexport_data_written_ != spv::NoResult); + builder_->createStore( + builder_->createBinOp( + spv::OpBitwiseOr, type_uint_, + builder_->createLoad(var_main_memexport_data_written_, spv::NoPrecision), + builder_->makeUintConstant(uint32_t(1) << result.storage_index)), + var_main_memexport_data_written_); + } + } break; + default: + assert_unhandled_case(result.storage_target); + return; + } + if (target_pointer == spv::NoResult) { + return; + } + + uint32_t constant_values; + uint32_t constant_components = result.GetUsedConstantComponents(constant_values); + if (value == spv::NoResult) { + // The instruction processing function decided that nothing useful needs to + // be stored for some reason, however, some components still need to be + // written on the guest side - fill them with zeros. + constant_components = used_write_mask; + } + uint32_t non_constant_components = used_write_mask & ~constant_components; + + unsigned int value_num_components = + value != spv::NoResult ? static_cast(builder_->getNumComponents(value)) : 0; + + if (is_clamped && non_constant_components) { + // Apply the saturation modifier to the result. + value = builder_->createTriBuiltinCall(type_float_vectors_[value_num_components - 1], + ext_inst_glsl_std_450_, GLSLstd450NClamp, value, + const_float_vectors_0_[value_num_components - 1], + const_float_vectors_1_[value_num_components - 1]); + } + + // The value contains either result.GetUsedResultComponents() in a condensed + // way, or a scalar to be replicated. Decompress them to create a mapping from + // guest result components to the ones in the value vector. + uint32_t used_result_components = result.GetUsedResultComponents(); + unsigned int result_unswizzled_value_components[4] = {}; + if (value_num_components > 1) { + unsigned int value_component = 0; + uint32_t used_result_components_remaining = used_result_components; + uint32_t result_component; + while (rex::bit_scan_forward(used_result_components_remaining, &result_component)) { + used_result_components_remaining &= ~(uint32_t(1) << result_component); + result_unswizzled_value_components[result_component] = + std::min(value_component++, value_num_components - 1); + } + } + + // Get swizzled mapping of non-constant components to the components of + // `value`. + unsigned int result_swizzled_value_components[4] = {}; + for (uint32_t i = 0; i < 4; ++i) { + if (!(non_constant_components & (1 << i))) { + continue; + } + SwizzleSource swizzle = result.components[i]; + assert_true(swizzle >= SwizzleSource::kX && swizzle <= SwizzleSource::kW); + result_swizzled_value_components[i] = + result_unswizzled_value_components[uint32_t(swizzle) - uint32_t(SwizzleSource::kX)]; + } + + spv::Id target_type = builder_->getDerefTypeId(target_pointer); + unsigned int target_num_components = builder_->getNumTypeComponents(target_type); + assert_true(target_num_components == + GetInstructionStorageTargetUsedComponentCount(result.storage_target)); + uint32_t target_component_mask = (1 << target_num_components) - 1; + assert_zero(used_write_mask & ~target_component_mask); + + spv::Id value_to_store; + if (target_component_mask == used_write_mask) { + // All components are overwritten - no need to load the original value. + // Possible cases: + // * Non-constants only. + // * Vector target. + // * Vector source. + // * Identity swizzle - store directly. + // * Non-identity swizzle - shuffle. + // * Scalar source - smear. + // * Scalar target. + // * Vector source - extract. + // * Scalar source - store directly. + // * Constants only. + // * Vector target - make composite constant. + // * Scalar target - store directly. + // * Mixed non-constants and constants (only for vector targets - scalar + // targets fully covered by the previous cases). + // * Vector source - shuffle with {0, 1} also applying swizzle. + // * Scalar source - construct composite. + if (!constant_components) { + if (target_num_components > 1) { + if (value_num_components > 1) { + // Non-constants only - vector target, vector source. + bool is_identity_swizzle = target_num_components == value_num_components; + for (uint32_t i = 0; is_identity_swizzle && i < target_num_components; ++i) { + is_identity_swizzle &= result_swizzled_value_components[i] == i; + } + if (is_identity_swizzle) { + value_to_store = value; + } else { + uint_vector_temp_util_.clear(); + uint_vector_temp_util_.insert(uint_vector_temp_util_.cend(), + result_swizzled_value_components, + result_swizzled_value_components + target_num_components); + value_to_store = builder_->createRvalueSwizzle(spv::NoPrecision, target_type, value, + uint_vector_temp_util_); + } + } else { + // Non-constants only - vector target, scalar source. + value_to_store = builder_->smearScalar(spv::NoPrecision, value, target_type); + } + } else { + if (value_num_components > 1) { + // Non-constants only - scalar target, vector source. + value_to_store = builder_->createCompositeExtract(value, type_float_, + result_swizzled_value_components[0]); + } else { + // Non-constants only - scalar target, scalar source. + value_to_store = value; + } + } + } else if (!non_constant_components) { + if (target_num_components > 1) { + // Constants only - vector target. + id_vector_temp_util_.clear(); + for (uint32_t i = 0; i < target_num_components; ++i) { + id_vector_temp_util_.push_back((constant_values & (1 << i)) ? const_float_1_ + : const_float_0_); + } + value_to_store = builder_->makeCompositeConstant(target_type, id_vector_temp_util_); + } else { + // Constants only - scalar target. + value_to_store = (constant_values & 0b0001) ? const_float_1_ : const_float_0_; + } + } else { + assert_true(target_num_components > 1); + if (value_num_components > 1) { + // Mixed non-constants and constants - vector source. + std::unique_ptr shuffle_op = std::make_unique( + builder_->getUniqueId(), target_type, spv::OpVectorShuffle); + shuffle_op->addIdOperand(value); + shuffle_op->addIdOperand(const_float2_0_1_); + for (uint32_t i = 0; i < target_num_components; ++i) { + shuffle_op->addImmediateOperand((constant_components & (1 << i)) + ? value_num_components + ((constant_values >> i) & 1) + : result_swizzled_value_components[i]); + } + value_to_store = shuffle_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(shuffle_op)); + } else { + // Mixed non-constants and constants - scalar source. + id_vector_temp_util_.clear(); + for (uint32_t i = 0; i < target_num_components; ++i) { + if (constant_components & (1 << i)) { + id_vector_temp_util_.push_back((constant_values & (1 << i)) ? const_float_1_ + : const_float_0_); + } else { + id_vector_temp_util_.push_back(value); + } + } + value_to_store = builder_->createCompositeConstruct(target_type, id_vector_temp_util_); + } + } + } else { + // Only certain components are overwritten. + // Scalar targets are always overwritten fully, can't reach this case for + // them. + assert_true(target_num_components > 1); + value_to_store = builder_->createLoad(target_pointer, spv::NoPrecision); + // Two steps: + // 1) Insert constants by shuffling (first so dependency chain of step 2 is + // simpler if constants are written first). + // 2) Insert value components - via shuffling for vector source, via + // composite inserts for scalar value. + if (constant_components) { + std::unique_ptr shuffle_op = std::make_unique( + builder_->getUniqueId(), target_type, spv::OpVectorShuffle); + shuffle_op->addIdOperand(value_to_store); + shuffle_op->addIdOperand(const_float2_0_1_); + for (uint32_t i = 0; i < target_num_components; ++i) { + shuffle_op->addImmediateOperand((constant_components & (1 << i)) + ? target_num_components + ((constant_values >> i) & 1) + : i); + } + value_to_store = shuffle_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(shuffle_op)); + } + if (non_constant_components) { + if (value_num_components > 1) { + std::unique_ptr shuffle_op = std::make_unique( + builder_->getUniqueId(), target_type, spv::OpVectorShuffle); + shuffle_op->addIdOperand(value_to_store); + shuffle_op->addIdOperand(value); + for (uint32_t i = 0; i < target_num_components; ++i) { + shuffle_op->addImmediateOperand((non_constant_components & (1 << i)) + ? target_num_components + + result_swizzled_value_components[i] + : i); + } + value_to_store = shuffle_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(shuffle_op)); + } else { + for (uint32_t i = 0; i < target_num_components; ++i) { + if (non_constant_components & (1 << i)) { + value_to_store = builder_->createCompositeInsert(value, value_to_store, target_type, i); + } + } + } + } + } + + if (result.storage_target == InstructionStorageTarget::kPointSizeEdgeFlagKillVertex && + used_write_mask & 0b001) { + // Make the point size non-negative as negative is used to indicate that the + // default size must be used, and also clamp it to the bounds the way the + // R400 (Adreno 200, to be more precise) hardware clamps it (functionally + // like a signed 32-bit integer, -NaN and -Infinity...-0 to the minimum, + // +NaN to the maximum). + spv::Id point_size = + builder_->createUnaryOp(spv::OpBitcast, type_int_, + builder_->createCompositeExtract(value_to_store, type_float_, 0)); + id_vector_temp_util_.clear(); + id_vector_temp_util_.push_back( + builder_->makeIntConstant(kSystemConstantPointVertexDiameterMin)); + spv::Id point_vertex_diameter_min = builder_->createUnaryOp( + spv::OpBitcast, type_int_, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_util_), + spv::NoPrecision)); + point_size = builder_->createBinBuiltinCall(type_int_, ext_inst_glsl_std_450_, GLSLstd450SMax, + point_vertex_diameter_min, point_size); + id_vector_temp_util_.clear(); + id_vector_temp_util_.push_back( + builder_->makeIntConstant(kSystemConstantPointVertexDiameterMax)); + spv::Id point_vertex_diameter_max = builder_->createUnaryOp( + spv::OpBitcast, type_int_, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_util_), + spv::NoPrecision)); + point_size = builder_->createBinBuiltinCall(type_int_, ext_inst_glsl_std_450_, GLSLstd450SMin, + point_vertex_diameter_max, point_size); + value_to_store = builder_->createCompositeInsert( + builder_->createUnaryOp(spv::OpBitcast, type_float_, point_size), value_to_store, + type_float3_, 0); + } + + builder_->createStore(value_to_store, target_pointer); +} + +spv::Id SpirvShaderTranslator::EndianSwap32Uint(spv::Id value, spv::Id endian) { + spv::Id type = builder_->getTypeId(value); + spv::Id const_uint_8_scalar = builder_->makeUintConstant(8); + spv::Id const_uint_00ff00ff_scalar = builder_->makeUintConstant(0x00FF00FF); + spv::Id const_uint_16_scalar = builder_->makeUintConstant(16); + spv::Id const_uint_8_typed, const_uint_00ff00ff_typed, const_uint_16_typed; + int num_components = builder_->getNumTypeComponents(type); + if (num_components > 1) { + id_vector_temp_.clear(); + id_vector_temp_.insert(id_vector_temp_.cend(), num_components, const_uint_8_scalar); + const_uint_8_typed = builder_->makeCompositeConstant(type, id_vector_temp_); + id_vector_temp_.clear(); + id_vector_temp_.insert(id_vector_temp_.cend(), num_components, const_uint_00ff00ff_scalar); + const_uint_00ff00ff_typed = builder_->makeCompositeConstant(type, id_vector_temp_); + id_vector_temp_.clear(); + id_vector_temp_.insert(id_vector_temp_.cend(), num_components, const_uint_16_scalar); + const_uint_16_typed = builder_->makeCompositeConstant(type, id_vector_temp_); + } else { + const_uint_8_typed = const_uint_8_scalar; + const_uint_00ff00ff_typed = const_uint_00ff00ff_scalar; + const_uint_16_typed = const_uint_16_scalar; + } + + // 8-in-16 or one half of 8-in-32 (doing 8-in-16 swap). + spv::Id is_8in16 = builder_->createBinOp( + spv::OpIEqual, type_bool_, endian, + builder_->makeUintConstant(static_cast(xenos::Endian::k8in16))); + spv::Id is_8in32 = builder_->createBinOp( + spv::OpIEqual, type_bool_, endian, + builder_->makeUintConstant(static_cast(xenos::Endian::k8in32))); + spv::Id is_8in16_or_8in32 = + builder_->createBinOp(spv::OpLogicalOr, type_bool_, is_8in16, is_8in32); + SpirvBuilder::IfBuilder if_8in16(is_8in16_or_8in32, spv::SelectionControlMaskNone, *builder_); + spv::Id swapped_8in16; + { + swapped_8in16 = builder_->createBinOp( + spv::OpBitwiseOr, type, + builder_->createBinOp( + spv::OpBitwiseAnd, type, + builder_->createBinOp(spv::OpShiftRightLogical, type, value, const_uint_8_typed), + const_uint_00ff00ff_typed), + builder_->createBinOp( + spv::OpShiftLeftLogical, type, + builder_->createBinOp(spv::OpBitwiseAnd, type, value, const_uint_00ff00ff_typed), + const_uint_8_typed)); + } + if_8in16.makeEndIf(); + value = if_8in16.createMergePhi(swapped_8in16, value); + + // 16-in-32 or another half of 8-in-32 (doing 16-in-32 swap). + spv::Id is_16in32 = builder_->createBinOp( + spv::OpIEqual, type_bool_, endian, + builder_->makeUintConstant(static_cast(xenos::Endian::k16in32))); + spv::Id is_8in32_or_16in32 = + builder_->createBinOp(spv::OpLogicalOr, type_bool_, is_8in32, is_16in32); + SpirvBuilder::IfBuilder if_16in32(is_8in32_or_16in32, spv::SelectionControlMaskNone, *builder_); + spv::Id swapped_16in32; + { + swapped_16in32 = builder_->createQuadOp( + spv::OpBitFieldInsert, type, + builder_->createBinOp(spv::OpShiftRightLogical, type, value, const_uint_16_typed), value, + builder_->makeIntConstant(16), builder_->makeIntConstant(16)); + } + if_16in32.makeEndIf(); + value = if_16in32.createMergePhi(swapped_16in32, value); + + return value; +} + +spv::Id SpirvShaderTranslator::EndianSwap128Uint4(spv::Id value, spv::Id endian) { + // Change 8-in-64 and 8-in-128 to 8-in-32, and then swap within 32 bits. + + spv::Id is_8in64 = builder_->createBinOp( + spv::OpIEqual, type_bool_, endian, + builder_->makeUintConstant(static_cast(xenos::Endian128::k8in64))); + uint_vector_temp_.clear(); + uint_vector_temp_.push_back(1); + uint_vector_temp_.push_back(0); + uint_vector_temp_.push_back(3); + uint_vector_temp_.push_back(2); + value = builder_->createTriOp( + spv::OpSelect, type_uint4_, is_8in64, + builder_->createRvalueSwizzle(spv::NoPrecision, type_uint4_, value, uint_vector_temp_), + value); + + spv::Id is_8in128 = builder_->createBinOp( + spv::OpIEqual, type_bool_, endian, + builder_->makeUintConstant(static_cast(xenos::Endian128::k8in128))); + uint_vector_temp_.clear(); + uint_vector_temp_.push_back(3); + uint_vector_temp_.push_back(2); + uint_vector_temp_.push_back(1); + uint_vector_temp_.push_back(0); + value = builder_->createTriOp( + spv::OpSelect, type_uint4_, is_8in128, + builder_->createRvalueSwizzle(spv::NoPrecision, type_uint4_, value, uint_vector_temp_), + value); + + endian = builder_->createTriOp( + spv::OpSelect, type_uint_, + builder_->createBinOp(spv::OpLogicalOr, type_bool_, is_8in64, is_8in128), + builder_->makeUintConstant(static_cast(xenos::Endian128::k8in32)), endian); + + return EndianSwap32Uint(value, endian); +} + +spv::Id SpirvShaderTranslator::LoadUint32FromSharedMemory(spv::Id address_dwords_int) { + spv::StorageClass storage_class = features_.spirv_version >= spv::Spv_1_3 + ? spv::StorageClassStorageBuffer + : spv::StorageClassUniform; + + uint32_t binding_count_log2 = GetSharedMemoryStorageBufferCountLog2(); + + if (!binding_count_log2) { + // Single binding - load directly. + id_vector_temp_.clear(); + // The only SSBO struct member. + id_vector_temp_.push_back(const_int_0_); + id_vector_temp_.push_back(address_dwords_int); + return builder_->createLoad( + builder_->createAccessChain(storage_class, buffers_shared_memory_, id_vector_temp_), + spv::NoPrecision); + } + + // The memory is split into multiple bindings - check which binding to load + // from. 29 is log2(512 MB), but addressing in dwords (4 B). Not indexing the + // array with the variable itself because it needs non-uniform storage buffer + // indexing. + + uint32_t binding_address_bits = (29 - 2) - binding_count_log2; + spv::Id binding_index = + builder_->createBinOp(spv::OpShiftRightLogical, type_uint_, + builder_->createUnaryOp(spv::OpBitcast, type_uint_, address_dwords_int), + builder_->makeUintConstant(binding_address_bits)); + spv::Id binding_address = builder_->createBinOp( + spv::OpBitwiseAnd, type_int_, address_dwords_int, + builder_->makeIntConstant(int((uint32_t(1) << binding_address_bits) - 1))); + + auto value_phi_op = + std::make_unique(builder_->getUniqueId(), type_uint_, spv::OpPhi); + // Zero if out of bounds. + value_phi_op->addIdOperand(const_uint_0_); + value_phi_op->addIdOperand(builder_->getBuildPoint()->getId()); + + SpirvBuilder::SwitchBuilder binding_switch(binding_index, spv::SelectionControlDontFlattenMask, + *builder_); + uint32_t binding_count = uint32_t(1) << binding_count_log2; + + id_vector_temp_.clear(); + id_vector_temp_.push_back(spv::NoResult); + // The only SSBO struct member. + id_vector_temp_.push_back(const_int_0_); + id_vector_temp_.push_back(binding_address); + + for (uint32_t i = 0; i < binding_count; ++i) { + binding_switch.makeBeginCase(i); + id_vector_temp_[0] = builder_->makeIntConstant(int(i)); + value_phi_op->addIdOperand(builder_->createLoad( + builder_->createAccessChain(storage_class, buffers_shared_memory_, id_vector_temp_), + spv::NoPrecision)); + value_phi_op->addIdOperand(builder_->getBuildPoint()->getId()); + } + + binding_switch.makeEndSwitch(); + + spv::Id value_phi_result = value_phi_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(value_phi_op)); + return value_phi_result; +} + +void SpirvShaderTranslator::StoreUint32ToSharedMemory(spv::Id value, spv::Id address_dwords_int, + spv::Id replace_mask) { + spv::StorageClass storage_class = features_.spirv_version >= spv::Spv_1_3 + ? spv::StorageClassStorageBuffer + : spv::StorageClassUniform; + + spv::Id keep_mask = spv::NoResult; + if (replace_mask != spv::NoResult) { + keep_mask = builder_->createUnaryOp(spv::OpNot, type_uint_, replace_mask); + value = builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, value, replace_mask); + } + + auto store = [&](spv::Id pointer) { + if (replace_mask != spv::NoResult) { + // Don't touch the other bits in the buffer, just modify the needed bits + // in the most up to date uint32 at the address. + spv::Id const_scope_device = + builder_->makeUintConstant(static_cast(spv::ScopeDevice)); + spv::Id const_semantics_relaxed = const_uint_0_; + builder_->createQuadOp(spv::OpAtomicAnd, type_uint_, pointer, const_scope_device, + const_semantics_relaxed, keep_mask); + builder_->createQuadOp(spv::OpAtomicOr, type_uint_, pointer, const_scope_device, + const_semantics_relaxed, value); + } else { + builder_->createStore(value, pointer); + } + }; + + uint32_t binding_count_log2 = GetSharedMemoryStorageBufferCountLog2(); + + if (!binding_count_log2) { + // Single binding - store directly. + id_vector_temp_.clear(); + // The only SSBO struct member. + id_vector_temp_.push_back(const_int_0_); + id_vector_temp_.push_back(address_dwords_int); + store(builder_->createAccessChain(storage_class, buffers_shared_memory_, id_vector_temp_)); + return; + } + + // The memory is split into multiple bindings - check which binding to store + // to. 29 is log2(512 MB), but addressing in dwords (4 B). Not indexing the + // array with the variable itself because it needs non-uniform storage buffer + // indexing. + + uint32_t binding_address_bits = (29 - 2) - binding_count_log2; + spv::Id binding_index = + builder_->createBinOp(spv::OpShiftRightLogical, type_uint_, + builder_->createUnaryOp(spv::OpBitcast, type_uint_, address_dwords_int), + builder_->makeUintConstant(binding_address_bits)); + spv::Id binding_address = builder_->createBinOp( + spv::OpBitwiseAnd, type_int_, address_dwords_int, + builder_->makeIntConstant(int((uint32_t(1) << binding_address_bits) - 1))); + + SpirvBuilder::SwitchBuilder binding_switch(binding_index, spv::SelectionControlDontFlattenMask, + *builder_); + uint32_t binding_count = uint32_t(1) << binding_count_log2; + + id_vector_temp_.clear(); + id_vector_temp_.push_back(spv::NoResult); + // The only SSBO struct member. + id_vector_temp_.push_back(const_int_0_); + id_vector_temp_.push_back(binding_address); + + for (uint32_t i = 0; i < binding_count; ++i) { + binding_switch.makeBeginCase(i); + id_vector_temp_[0] = builder_->makeIntConstant(int(i)); + store(builder_->createAccessChain(storage_class, buffers_shared_memory_, id_vector_temp_)); + } + + binding_switch.makeEndSwitch(); +} + +spv::Id SpirvShaderTranslator::PWLGammaToLinear(spv::Id gamma, bool gamma_pre_saturated) { + spv::Id value_type = builder_->getTypeId(gamma); + assert_true(builder_->isFloatType(builder_->getScalarTypeId(value_type))); + bool is_vector = builder_->isVectorType(value_type); + assert_true(is_vector || builder_->isFloatType(value_type)); + int num_components = builder_->getNumTypeComponents(value_type); + assert_true(num_components < 4); + spv::Id bool_type = type_bool_vectors_[num_components - 1]; + + spv::Id const_vector_0 = const_float_vectors_0_[num_components - 1]; + spv::Id const_vector_1 = + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(1.0f), value_type); + + if (!gamma_pre_saturated) { + // Saturate, flushing NaN to 0. + gamma = builder_->createTriBuiltinCall(value_type, ext_inst_glsl_std_450_, GLSLstd450NClamp, + gamma, const_vector_0, const_vector_1); + } + + spv::Id is_piece_at_least_3 = builder_->createBinOp( + spv::OpFOrdGreaterThanEqual, bool_type, gamma, + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(192.0f / 255.0f), value_type)); + spv::Id scale_3_or_2 = builder_->createTriOp( + spv::OpSelect, value_type, is_piece_at_least_3, + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(8.0f / 1024.0f), value_type), + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(4.0f / 1024.0f), value_type)); + spv::Id offset_3_or_2 = builder_->createTriOp( + spv::OpSelect, value_type, is_piece_at_least_3, + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(-1024.0f), value_type), + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(-256.0f), value_type)); + + spv::Id is_piece_at_least_1 = builder_->createBinOp( + spv::OpFOrdGreaterThanEqual, bool_type, gamma, + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(64.0f / 255.0f), value_type)); + spv::Id scale_1_or_0 = builder_->createTriOp( + spv::OpSelect, value_type, is_piece_at_least_1, + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(2.0f / 1024.0f), value_type), + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(1.0f / 1024.0f), value_type)); + spv::Id offset_1_or_0 = builder_->createTriOp( + spv::OpSelect, value_type, is_piece_at_least_1, + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(-64.0f), value_type), + const_vector_0); + + spv::Id is_piece_at_least_2 = builder_->createBinOp( + spv::OpFOrdGreaterThanEqual, bool_type, gamma, + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(96.0f / 255.0f), value_type)); + spv::Id scale = builder_->createTriOp(spv::OpSelect, value_type, is_piece_at_least_2, + scale_3_or_2, scale_1_or_0); + spv::Id offset = builder_->createTriOp(spv::OpSelect, value_type, is_piece_at_least_2, + offset_3_or_2, offset_1_or_0); + + spv::Op value_times_scalar_opcode = is_vector ? spv::OpVectorTimesScalar : spv::OpFMul; + // linear = gamma * (255.0f * 1024.0f) * scale + offset + spv::Id linear = builder_->createNoContractionBinOp( + spv::OpFAdd, value_type, + builder_->createNoContractionBinOp( + spv::OpFMul, value_type, + builder_->createNoContractionBinOp(value_times_scalar_opcode, value_type, gamma, + builder_->makeFloatConstant(255.0f * 1024.0f)), + scale), + offset); + // linear += trunc(linear * scale) + linear = builder_->createNoContractionBinOp( + spv::OpFAdd, value_type, linear, + builder_->createUnaryBuiltinCall( + value_type, ext_inst_glsl_std_450_, GLSLstd450Trunc, + builder_->createNoContractionBinOp(spv::OpFMul, value_type, linear, scale))); + // linear *= 1.0f / 1023.0f + linear = builder_->createNoContractionBinOp(value_times_scalar_opcode, value_type, linear, + builder_->makeFloatConstant(1.0f / 1023.0f)); + return linear; +} + +spv::Id SpirvShaderTranslator::LinearToPWLGamma(spv::Id linear, bool linear_pre_saturated) { + spv::Id value_type = builder_->getTypeId(linear); + assert_true(builder_->isFloatType(builder_->getScalarTypeId(value_type))); + bool is_vector = builder_->isVectorType(value_type); + assert_true(is_vector || builder_->isFloatType(value_type)); + int num_components = builder_->getNumTypeComponents(value_type); + assert_true(num_components < 4); + spv::Id bool_type = type_bool_vectors_[num_components - 1]; + + spv::Id const_vector_0 = const_float_vectors_0_[num_components - 1]; + spv::Id const_vector_1 = + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(1.0f), value_type); + + if (!linear_pre_saturated) { + // Saturate, flushing NaN to 0. + linear = builder_->createTriBuiltinCall(value_type, ext_inst_glsl_std_450_, GLSLstd450NClamp, + linear, const_vector_0, const_vector_1); + } + + spv::Id is_piece_at_least_3 = builder_->createBinOp( + spv::OpFOrdGreaterThanEqual, bool_type, linear, + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(512.0f / 1023.0f), value_type)); + spv::Id scale_3_or_2 = builder_->createTriOp( + spv::OpSelect, value_type, is_piece_at_least_3, + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(1023.0f / 8.0f), value_type), + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(1023.0f / 4.0f), value_type)); + spv::Id offset_3_or_2 = builder_->createTriOp( + spv::OpSelect, value_type, is_piece_at_least_3, + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(128.0f / 255.0f), value_type), + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(64.0f / 255.0f), value_type)); + + spv::Id is_piece_at_least_1 = builder_->createBinOp( + spv::OpFOrdGreaterThanEqual, bool_type, linear, + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(64.0f / 1023.0f), value_type)); + spv::Id scale_1_or_0 = builder_->createTriOp( + spv::OpSelect, value_type, is_piece_at_least_1, + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(1023.0f / 2.0f), value_type), + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(1023.0f), value_type)); + spv::Id offset_1_or_0 = builder_->createTriOp( + spv::OpSelect, value_type, is_piece_at_least_1, + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(32.0f / 255.0f), value_type), + const_vector_0); + + spv::Id is_piece_at_least_2 = builder_->createBinOp( + spv::OpFOrdGreaterThanEqual, bool_type, linear, + SpirvSmearScalarResultOrConstant(builder_->makeFloatConstant(128.0f / 1023.0f), value_type)); + spv::Id scale = builder_->createTriOp(spv::OpSelect, value_type, is_piece_at_least_2, + scale_3_or_2, scale_1_or_0); + spv::Id offset = builder_->createTriOp(spv::OpSelect, value_type, is_piece_at_least_2, + offset_3_or_2, offset_1_or_0); + + // gamma = trunc(linear * scale) * (1.0f / 255.0f) + offset + return builder_->createNoContractionBinOp( + spv::OpFAdd, value_type, + builder_->createNoContractionBinOp( + is_vector ? spv::OpVectorTimesScalar : spv::OpFMul, value_type, + builder_->createUnaryBuiltinCall( + value_type, ext_inst_glsl_std_450_, GLSLstd450Trunc, + builder_->createNoContractionBinOp(spv::OpFMul, value_type, linear, scale)), + builder_->makeFloatConstant(1.0f / 255.0f)), + offset); +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/shader/spirv_translator_alu.cpp b/src/graphics/pipeline/shader/spirv_translator_alu.cpp new file mode 100644 index 0000000..706ac7e --- /dev/null +++ b/src/graphics/pipeline/shader/spirv_translator_alu.cpp @@ -0,0 +1,1201 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include + +namespace rex::graphics { + +spv::Id SpirvShaderTranslator::ZeroIfAnyOperandIsZero(spv::Id value, spv::Id operand_0_abs, + spv::Id operand_1_abs) { + EnsureBuildPointAvailable(); + int num_components = builder_->getNumComponents(value); + assert_true(builder_->getNumComponents(operand_0_abs) == num_components); + assert_true(builder_->getNumComponents(operand_1_abs) == num_components); + return builder_->createTriOp( + spv::OpSelect, type_float_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_vectors_[num_components - 1], + builder_->createBinBuiltinCall(type_float_vectors_[num_components - 1], + ext_inst_glsl_std_450_, GLSLstd450NMin, + operand_0_abs, operand_1_abs), + const_float_vectors_0_[num_components - 1]), + const_float_vectors_0_[num_components - 1], value); +} + +void SpirvShaderTranslator::KillPixel(spv::Id condition, + uint8_t memexport_eM_potentially_written_before) { + SpirvBuilder::IfBuilder kill_if(condition, spv::SelectionControlMaskNone, *builder_); + { + // Perform outstanding memory exports before the invocation becomes inactive + // and storage writes are disabled. + ExportToMemory(memexport_eM_potentially_written_before); + if (var_main_kill_pixel_ != spv::NoResult) { + builder_->createStore(builder_->makeBoolConstant(true), var_main_kill_pixel_); + } + if (features_.demote_to_helper_invocation) { + builder_->createNoResultOp(spv::OpDemoteToHelperInvocationEXT); + } + } + kill_if.makeEndIf(); +} + +void SpirvShaderTranslator::ProcessAluInstruction(const ParsedAluInstruction& instr, + uint8_t memexport_eM_potentially_written_before) { + if (instr.IsNop()) { + // Don't even disassemble or update predication. + return; + } + + UpdateInstructionPredication(instr.is_predicated, instr.predicate_condition); + + // Floating-point arithmetic operations (addition, subtraction, negation, + // multiplication, division, modulo - see isArithmeticOperation in + // propagateNoContraction of glslang; though for some reason it's not applied + // to SPIR-V OpDot, at least in the February 16, 2020 version installed on + // http://shader-playground.timjones.io/) must have the NoContraction + // decoration to prevent reordering to make sure floating-point calculations + // are optimized predictably and exactly the same in different shaders to + // allow for multipass rendering (in addition to the Invariant decoration on + // outputs). + + // Whether the instruction has changed the predicate, and it needs to be + // checked again later. + bool predicate_written_vector = false; + spv::Id vector_result = ProcessVectorAluOperation(instr, memexport_eM_potentially_written_before, + predicate_written_vector); + + bool predicate_written_scalar = false; + spv::Id scalar_result = ProcessScalarAluOperation(instr, memexport_eM_potentially_written_before, + predicate_written_scalar); + if (scalar_result != spv::NoResult) { + EnsureBuildPointAvailable(); + builder_->createStore(scalar_result, var_main_previous_scalar_); + } else { + // Special retain_prev case - load ps only if needed and don't store the + // same value back to ps. + if (instr.scalar_result.GetUsedWriteMask()) { + EnsureBuildPointAvailable(); + scalar_result = builder_->createLoad(var_main_previous_scalar_, spv::NoPrecision); + } + } + + StoreResult(instr.vector_and_constant_result, vector_result, + instr.GetMemExportStreamConstant() != UINT32_MAX); + StoreResult(instr.scalar_result, scalar_result); + + if (predicate_written_vector || predicate_written_scalar) { + cf_exec_predicate_written_ = true; + CloseInstructionPredication(); + } +} + +spv::Id SpirvShaderTranslator::ProcessVectorAluOperation( + const ParsedAluInstruction& instr, uint8_t memexport_eM_potentially_written_before, + bool& predicate_written) { + predicate_written = false; + + uint32_t used_result_components = instr.vector_and_constant_result.GetUsedResultComponents(); + if (!used_result_components && + !ucode::GetAluVectorOpcodeInfo(instr.vector_opcode).changed_state) { + return spv::NoResult; + } + uint32_t used_result_component_count = rex::bit_count(used_result_components); + + // Load operand storage without swizzle and sign modifiers. + // A small shortcut, operands of cube are the same, but swizzled. + uint32_t operand_count; + if (instr.vector_opcode == ucode::AluVectorOpcode::kCube) { + operand_count = 1; + } else { + operand_count = instr.vector_operand_count; + } + spv::Id operand_storage[3] = {}; + for (uint32_t i = 0; i < operand_count; ++i) { + operand_storage[i] = LoadOperandStorage(instr.vector_operands[i]); + } + spv::Id result_type = used_result_component_count + ? type_float_vectors_[used_result_component_count - 1] + : spv::NoType; + + // In case the paired scalar instruction (if processed first) terminates the + // block. + EnsureBuildPointAvailable(); + + // Lookup table for variants of instructions with similar structure. + static const unsigned int kOps[] = { + static_cast(spv::OpNop), // kAdd + static_cast(spv::OpNop), // kMul + static_cast(spv::OpFOrdGreaterThanEqual), // kMax + static_cast(spv::OpFOrdLessThan), // kMin + static_cast(spv::OpFOrdEqual), // kSeq + static_cast(spv::OpFOrdGreaterThan), // kSgt + static_cast(spv::OpFOrdGreaterThanEqual), // kSge + static_cast(spv::OpFUnordNotEqual), // kSne + static_cast(GLSLstd450Fract), // kFrc + static_cast(GLSLstd450Trunc), // kTrunc + static_cast(GLSLstd450Floor), // kFloor + static_cast(spv::OpNop), // kMad + static_cast(spv::OpFOrdEqual), // kCndEq + static_cast(spv::OpFOrdGreaterThanEqual), // kCndGe + static_cast(spv::OpFOrdGreaterThan), // kCndGt + static_cast(spv::OpNop), // kDp4 + static_cast(spv::OpNop), // kDp3 + static_cast(spv::OpNop), // kDp2Add + static_cast(spv::OpNop), // kCube + static_cast(spv::OpNop), // kMax4 + static_cast(spv::OpFOrdEqual), // kSetpEqPush + static_cast(spv::OpFUnordNotEqual), // kSetpNePush + static_cast(spv::OpFOrdGreaterThan), // kSetpGtPush + static_cast(spv::OpFOrdGreaterThanEqual), // kSetpGePush + static_cast(spv::OpFOrdEqual), // kKillEq + static_cast(spv::OpFOrdGreaterThan), // kKillGt + static_cast(spv::OpFOrdGreaterThanEqual), // kKillGe + static_cast(spv::OpFUnordNotEqual), // kKillNe + static_cast(spv::OpNop), // kDst + static_cast(spv::OpFOrdGreaterThanEqual), // kMaxA + }; + + switch (instr.vector_opcode) { + case ucode::AluVectorOpcode::kAdd: { + return builder_->createNoContractionBinOp( + spv::OpFAdd, result_type, + GetOperandComponents(operand_storage[0], instr.vector_operands[0], + used_result_components), + GetOperandComponents(operand_storage[1], instr.vector_operands[1], + used_result_components)); + } + case ucode::AluVectorOpcode::kMul: + case ucode::AluVectorOpcode::kMad: { + spv::Id multiplicands[2]; + for (uint32_t i = 0; i < 2; ++i) { + multiplicands[i] = GetOperandComponents(operand_storage[i], instr.vector_operands[i], + used_result_components); + } + spv::Id result = builder_->createNoContractionBinOp(spv::OpFMul, result_type, + multiplicands[0], multiplicands[1]); + uint32_t multiplicands_different = + used_result_components & + ~instr.vector_operands[0].GetIdenticalComponents(instr.vector_operands[1]); + if (multiplicands_different) { + // Shader Model 3: +0 or denormal * anything = +-0. + spv::Id different_operands[2] = {multiplicands[0], multiplicands[1]}; + spv::Id different_result = result; + uint32_t different_count = rex::bit_count(multiplicands_different); + spv::Id different_type = type_float_vectors_[different_count - 1]; + // Extract the different components, if not all are different. + if (multiplicands_different != used_result_components) { + uint_vector_temp_.clear(); + uint32_t components_remaining = used_result_components; + for (uint32_t i = 0; i < used_result_component_count; ++i) { + uint32_t component; + rex::bit_scan_forward(components_remaining, &component); + components_remaining &= ~(uint32_t(1) << component); + if (multiplicands_different & (1 << component)) { + uint_vector_temp_.push_back(i); + } + } + assert_true(uint_vector_temp_.size() == different_count); + if (different_count > 1) { + for (uint32_t i = 0; i < 2; ++i) { + different_operands[i] = builder_->createRvalueSwizzle( + spv::NoPrecision, different_type, different_operands[i], uint_vector_temp_); + } + different_result = builder_->createRvalueSwizzle(spv::NoPrecision, different_type, + different_result, uint_vector_temp_); + } else { + for (uint32_t i = 0; i < 2; ++i) { + different_operands[i] = builder_->createCompositeExtract( + different_operands[i], different_type, uint_vector_temp_[0]); + } + different_result = builder_->createCompositeExtract(different_result, different_type, + uint_vector_temp_[0]); + } + } + // Check if the different components in any of the operands are zero, + // even if the other is NaN - if min(|a|, |b|) is 0. + for (uint32_t i = 0; i < 2; ++i) { + different_operands[i] = + GetAbsoluteOperand(different_operands[i], instr.vector_operands[i]); + } + spv::Id different_zero = builder_->createBinOp( + spv::OpFOrdEqual, type_bool_vectors_[different_count - 1], + builder_->createBinBuiltinCall(different_type, ext_inst_glsl_std_450_, GLSLstd450NMin, + different_operands[0], different_operands[1]), + const_float_vectors_0_[different_count - 1]); + // Replace with +0. + different_result = + builder_->createTriOp(spv::OpSelect, different_type, different_zero, + const_float_vectors_0_[different_count - 1], different_result); + // Insert the different components back to the result. + if (multiplicands_different != used_result_components) { + if (different_count > 1) { + std::unique_ptr shuffle_op = std::make_unique( + builder_->getUniqueId(), result_type, spv::OpVectorShuffle); + shuffle_op->addIdOperand(result); + shuffle_op->addIdOperand(different_result); + uint32_t components_remaining = used_result_components; + unsigned int different_shuffle_index = used_result_component_count; + for (uint32_t i = 0; i < used_result_component_count; ++i) { + uint32_t component; + rex::bit_scan_forward(components_remaining, &component); + components_remaining &= ~(uint32_t(1) << component); + shuffle_op->addImmediateOperand( + (multiplicands_different & (1 << component)) ? different_shuffle_index++ : i); + } + result = shuffle_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(shuffle_op)); + } else { + result = builder_->createCompositeInsert( + different_result, result, result_type, + rex::bit_count(used_result_components & (multiplicands_different - 1))); + } + } else { + result = different_result; + } + } + if (instr.vector_opcode == ucode::AluVectorOpcode::kMad) { + // Not replacing true `0 + term` with conditional selection of the term + // because +0 + -0 should result in +0, not -0. + result = builder_->createNoContractionBinOp( + spv::OpFAdd, result_type, result, + GetOperandComponents(operand_storage[2], instr.vector_operands[2], + used_result_components)); + } + return result; + } + + case ucode::AluVectorOpcode::kMax: + case ucode::AluVectorOpcode::kMin: + case ucode::AluVectorOpcode::kMaxA: { + bool is_maxa = instr.vector_opcode == ucode::AluVectorOpcode::kMaxA; + spv::Id operand_0 = + GetOperandComponents(operand_storage[0], instr.vector_operands[0], + used_result_components | (is_maxa ? 0b1000 : 0b0000)); + spv::Id maxa_operand_0_w = spv::NoResult; + if (is_maxa) { + // a0 = (int)clamp(floor(src0.w + 0.5), -256.0, 255.0) + int operand_0_num_components = builder_->getNumComponents(operand_0); + if (operand_0_num_components > 1) { + maxa_operand_0_w = builder_->createCompositeExtract( + operand_0, type_float_, static_cast(operand_0_num_components - 1)); + } else { + maxa_operand_0_w = operand_0; + } + builder_->createStore( + builder_->createUnaryOp( + spv::OpConvertFToS, type_int_, + builder_->createTriBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450NClamp, + builder_->createUnaryBuiltinCall(type_float_, ext_inst_glsl_std_450_, + GLSLstd450Floor, + builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, maxa_operand_0_w, + builder_->makeFloatConstant(0.5f))), + builder_->makeFloatConstant(-256.0f), builder_->makeFloatConstant(255.0f))), + var_main_address_register_); + } + if (!used_result_components) { + // maxa returning nothing - can't load src1. + return spv::NoResult; + } + // max is commonly used as mov. + uint32_t identical = + instr.vector_operands[0].GetIdenticalComponents(instr.vector_operands[1]) & + used_result_components; + spv::Id operand_0_per_component; + if (is_maxa && !(used_result_components & 0b1000) && + (identical == used_result_components || !identical)) { + // operand_0 and operand_1 have different lengths though if src0.w is + // forced without W being in the write mask for maxa purposes - + // shuffle/extract the needed part if src0.w is only needed for setting + // a0. + // This is only needed for cases without mixed identical and different + // components - the mixed case uses CompositeExtract, which works fine. + if (used_result_component_count > 1) { + // Need all but the last (W) element of operand_0 as a vector. + uint_vector_temp_.clear(); + for (unsigned int i = 0; i < used_result_component_count; ++i) { + uint_vector_temp_.push_back(i); + } + operand_0_per_component = builder_->createRvalueSwizzle( + spv::NoPrecision, type_float_vectors_[used_result_component_count - 1], operand_0, + uint_vector_temp_); + } else { + // Need the non-W component as scalar. + operand_0_per_component = builder_->createCompositeExtract(operand_0, type_float_, 0); + } + } else { + operand_0_per_component = operand_0; + } + if (identical == used_result_components) { + // All components are identical - mov (with the correct length in case + // of maxa). Don't access operand_1 at all in this case (operand_0 is + // already accessed for W in case of maxa). + assert_true(builder_->getNumComponents(operand_0_per_component) == + used_result_component_count); + return operand_0_per_component; + } + spv::Id operand_1 = GetOperandComponents(operand_storage[1], instr.vector_operands[1], + used_result_components); + // Shader Model 3 NaN behavior (a op b ? a : b, not SPIR-V FMax/FMin which + // are undefined for NaN or NMax/NMin which return the non-NaN operand). + spv::Op op = spv::Op(kOps[size_t(instr.vector_opcode)]); + if (!identical) { + // All components are different - max/min of the scalars or the entire + // vectors (with the correct length in case of maxa). + assert_true(builder_->getNumComponents(operand_0_per_component) == + used_result_component_count); + return builder_->createTriOp( + spv::OpSelect, result_type, + builder_->createBinOp(op, type_bool_vectors_[used_result_component_count - 1], + operand_0_per_component, operand_1), + operand_0_per_component, operand_1); + } + // Mixed identical and different components. + assert_true(used_result_component_count > 1); + id_vector_temp_.clear(); + uint32_t components_remaining = used_result_components; + for (uint32_t i = 0; i < used_result_component_count; ++i) { + // Composite extraction of operand_0[i] works fine even it's maxa with + // src0.w forced without W being in the write mask - src0.w would be the + // last, so all indices before it are still valid. Don't extract twice + // if already extracted though. + spv::Id result_component = + ((used_result_components & 0b1000) && i + 1 >= used_result_component_count && + maxa_operand_0_w != spv::NoResult) + ? maxa_operand_0_w + : builder_->createCompositeExtract(operand_0, type_float_, i); + uint32_t component_index; + rex::bit_scan_forward(components_remaining, &component_index); + components_remaining &= ~(uint32_t(1) << component_index); + if (!(identical & (1 << component_index))) { + spv::Id operand_1_component = builder_->createCompositeExtract(operand_1, type_float_, i); + result_component = builder_->createTriOp( + spv::OpSelect, type_float_, + builder_->createBinOp(op, type_bool_, result_component, operand_1_component), + result_component, operand_1_component); + } + id_vector_temp_.push_back(result_component); + } + return builder_->createCompositeConstruct(result_type, id_vector_temp_); + } + + case ucode::AluVectorOpcode::kSeq: + case ucode::AluVectorOpcode::kSgt: + case ucode::AluVectorOpcode::kSge: + case ucode::AluVectorOpcode::kSne: + return builder_->createTriOp( + spv::OpSelect, result_type, + builder_->createBinOp(spv::Op(kOps[size_t(instr.vector_opcode)]), + type_bool_vectors_[used_result_component_count - 1], + GetOperandComponents(operand_storage[0], instr.vector_operands[0], + used_result_components), + GetOperandComponents(operand_storage[1], instr.vector_operands[1], + used_result_components)), + const_float_vectors_1_[used_result_component_count - 1], + const_float_vectors_0_[used_result_component_count - 1]); + + case ucode::AluVectorOpcode::kFrc: + case ucode::AluVectorOpcode::kTrunc: + case ucode::AluVectorOpcode::kFloor: + return builder_->createUnaryBuiltinCall( + result_type, ext_inst_glsl_std_450_, GLSLstd450(kOps[size_t(instr.vector_opcode)]), + GetOperandComponents(operand_storage[0], instr.vector_operands[0], + used_result_components)); + + case ucode::AluVectorOpcode::kCndEq: + case ucode::AluVectorOpcode::kCndGe: + case ucode::AluVectorOpcode::kCndGt: + return builder_->createTriOp( + spv::OpSelect, result_type, + builder_->createBinOp(spv::Op(kOps[size_t(instr.vector_opcode)]), + type_bool_vectors_[used_result_component_count - 1], + GetOperandComponents(operand_storage[0], instr.vector_operands[0], + used_result_components), + const_float_vectors_0_[used_result_component_count - 1]), + GetOperandComponents(operand_storage[1], instr.vector_operands[1], + used_result_components), + GetOperandComponents(operand_storage[2], instr.vector_operands[2], + used_result_components)); + + case ucode::AluVectorOpcode::kDp4: + case ucode::AluVectorOpcode::kDp3: + case ucode::AluVectorOpcode::kDp2Add: { + // Not using OpDot for predictable optimization (especially addition + // order) and NoContraction (which, for some reason, isn't placed on dot + // in glslang as of the February 16, 2020 version). + uint32_t component_count; + if (instr.vector_opcode == ucode::AluVectorOpcode::kDp2Add) { + component_count = 2; + } else if (instr.vector_opcode == ucode::AluVectorOpcode::kDp3) { + component_count = 3; + } else { + component_count = 4; + } + uint32_t component_mask = (1 << component_count) - 1; + spv::Id operands[2]; + for (uint32_t i = 0; i < 2; ++i) { + operands[i] = + GetOperandComponents(operand_storage[i], instr.vector_operands[i], component_mask); + } + uint32_t different = component_mask & ~instr.vector_operands[0].GetIdenticalComponents( + instr.vector_operands[1]); + spv::Id result = spv::NoResult; + for (uint32_t i = 0; i < component_count; ++i) { + spv::Id operand_components[2]; + for (unsigned int j = 0; j < 2; ++j) { + operand_components[j] = builder_->createCompositeExtract(operands[j], type_float_, i); + } + spv::Id product = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, operand_components[0], operand_components[1]); + if (different & (1 << i)) { + // Shader Model 3: +0 or denormal * anything = +-0. + product = ZeroIfAnyOperandIsZero( + product, GetAbsoluteOperand(operand_components[0], instr.vector_operands[0]), + GetAbsoluteOperand(operand_components[1], instr.vector_operands[1])); + } + if (!i) { + result = product; + continue; + } + result = builder_->createNoContractionBinOp(spv::OpFAdd, type_float_, result, product); + } + if (instr.vector_opcode == ucode::AluVectorOpcode::kDp2Add) { + result = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, result, + GetOperandComponents(operand_storage[2], instr.vector_operands[2], 0b0001)); + } + return result; + } + + case ucode::AluVectorOpcode::kCube: { + // operands[0] is .z_xy. + // Result is T coordinate, S coordinate, 2 * major axis, face ID. + // Skipping the second component of the operand, so 120, not 230. + spv::Id operand_vector = + GetOperandComponents(operand_storage[0], instr.vector_operands[0], 0b1101); + // Remapped from ZXY (Z_XY without the skipped component) to XYZ. + spv::Id operand[3]; + for (unsigned int i = 0; i < 3; ++i) { + operand[i] = builder_->createCompositeExtract(operand_vector, type_float_, (i + 1) % 3); + } + spv::Id operand_abs[3]; + if (!instr.vector_operands[0].is_absolute_value || instr.vector_operands[0].is_negated) { + for (unsigned int i = 0; i < 3; ++i) { + operand_abs[i] = builder_->createUnaryBuiltinCall(type_float_, ext_inst_glsl_std_450_, + GLSLstd450FAbs, operand[i]); + } + } else { + for (unsigned int i = 0; i < 3; ++i) { + operand_abs[i] = operand[i]; + } + } + spv::Id operand_neg[3] = {}; + if (used_result_components & 0b0001) { + operand_neg[1] = + builder_->createNoContractionUnaryOp(spv::OpFNegate, type_float_, operand[1]); + } + if (used_result_components & 0b0010) { + operand_neg[0] = + builder_->createNoContractionUnaryOp(spv::OpFNegate, type_float_, operand[0]); + operand_neg[2] = + builder_->createNoContractionUnaryOp(spv::OpFNegate, type_float_, operand[2]); + } + + spv::Id ma_z_result[4] = {}, ma_yx_result[4] = {}; + + // Check if the major axis is Z (abs(z) >= abs(x) && abs(z) >= abs(y)). + SpirvBuilder::IfBuilder ma_z_if( + builder_->createBinOp(spv::OpLogicalAnd, type_bool_, + builder_->createBinOp(spv::OpFOrdGreaterThanEqual, type_bool_, + operand_abs[2], operand_abs[0]), + builder_->createBinOp(spv::OpFOrdGreaterThanEqual, type_bool_, + operand_abs[2], operand_abs[1])), + spv::SelectionControlMaskNone, *builder_); + { + // The major axis is Z. + // tc = -y + ma_z_result[0] = operand_neg[1]; + // ma/2 = z + ma_z_result[2] = operand[2]; + if (used_result_components & 0b1010) { + spv::Id z_is_neg = + builder_->createBinOp(spv::OpFOrdLessThan, type_bool_, operand[2], const_float_0_); + if (used_result_components & 0b0010) { + // sc = z < 0.0 ? -x : x + ma_z_result[1] = builder_->createTriOp(spv::OpSelect, type_float_, z_is_neg, + operand_neg[0], operand[0]); + } + if (used_result_components & 0b1000) { + // id = z < 0.0 ? 5.0 : 4.0 + ma_z_result[3] = builder_->createTriOp(spv::OpSelect, type_float_, z_is_neg, + builder_->makeFloatConstant(5.0f), + builder_->makeFloatConstant(4.0f)); + } + } + } + ma_z_if.makeBeginElse(); + { + spv::Id ma_y_result[4] = {}, ma_x_result[4] = {}; + + // The major axis is not Z - create an inner conditional to check if the + // major axis is Y (abs(y) >= abs(x)). + SpirvBuilder::IfBuilder ma_y_if( + builder_->createBinOp(spv::OpFOrdGreaterThanEqual, type_bool_, operand_abs[1], + operand_abs[0]), + spv::SelectionControlMaskNone, *builder_); + { + // The major axis is Y. + // sc = x + ma_y_result[1] = operand[0]; + // ma/2 = y + ma_y_result[2] = operand[1]; + if (used_result_components & 0b1001) { + spv::Id y_is_neg = + builder_->createBinOp(spv::OpFOrdLessThan, type_bool_, operand[1], const_float_0_); + if (used_result_components & 0b0001) { + // tc = y < 0.0 ? -z : z + ma_y_result[0] = builder_->createTriOp(spv::OpSelect, type_float_, y_is_neg, + operand_neg[2], operand[2]); + // id = y < 0.0 ? 3.0 : 2.0 + ma_y_result[3] = builder_->createTriOp(spv::OpSelect, type_float_, y_is_neg, + builder_->makeFloatConstant(3.0f), + builder_->makeFloatConstant(2.0f)); + } + } + } + ma_y_if.makeBeginElse(); + { + // The major axis is X. + // tc = -y + ma_x_result[0] = operand_neg[1]; + // ma/2 = x + ma_x_result[2] = operand[0]; + if (used_result_components & 0b1010) { + spv::Id x_is_neg = + builder_->createBinOp(spv::OpFOrdLessThan, type_bool_, operand[0], const_float_0_); + if (used_result_components & 0b0010) { + // sc = x < 0.0 ? z : -z + ma_x_result[1] = builder_->createTriOp(spv::OpSelect, type_float_, x_is_neg, + operand[2], operand_neg[2]); + } + if (used_result_components & 0b1000) { + // id = x < 0.0 ? 1.0 : 0.0 + ma_x_result[3] = builder_->createTriOp(spv::OpSelect, type_float_, x_is_neg, + const_float_1_, const_float_0_); + } + } + } + ma_y_if.makeEndIf(); + + // The major axis is Y or X - choose the options of the result from Y + // and X. + for (uint32_t i = 0; i < 4; ++i) { + if (!(used_result_components & (1 << i))) { + continue; + } + ma_yx_result[i] = ma_y_if.createMergePhi(ma_y_result[i], ma_x_result[i]); + } + } + ma_z_if.makeEndIf(); + + // Choose the result options from Z and YX cases. + id_vector_temp_.clear(); + for (uint32_t i = 0; i < 4; ++i) { + if (!(used_result_components & (1 << i))) { + continue; + } + id_vector_temp_.push_back(ma_z_if.createMergePhi(ma_z_result[i], ma_yx_result[i])); + } + assert_true(id_vector_temp_.size() == used_result_component_count); + if (used_result_components & 0b0100) { + // Multiply the major axis by 2. + spv::Id& ma2 = id_vector_temp_[rex::bit_count(used_result_components & ((1 << 2) - 1))]; + ma2 = builder_->createNoContractionBinOp(spv::OpFMul, type_float_, + builder_->makeFloatConstant(2.0f), ma2); + } + if (used_result_component_count == 1) { + // Only one component - not composite. + return id_vector_temp_[0]; + } + return builder_->createCompositeConstruct( + type_float_vectors_[used_result_component_count - 1], id_vector_temp_); + } + + case ucode::AluVectorOpcode::kMax4: { + // Find max of all different components of the first operand. + // FIXME(Triang3l): Not caring about NaN because no info about the + // correct order, just using NMax here, which replaces them with the + // non-NaN component (however, there's one nice thing about it is that it + // may be compiled into max3 + max on GCN). + uint32_t components_remaining = 0b0000; + for (uint32_t i = 0; i < 4; ++i) { + SwizzleSource swizzle_source = instr.vector_operands[0].GetComponent(i); + assert_true(swizzle_source >= SwizzleSource::kX && swizzle_source <= SwizzleSource::kW); + components_remaining |= 1 << (uint32_t(swizzle_source) - uint32_t(SwizzleSource::kX)); + } + assert_not_zero(components_remaining); + spv::Id operand = ApplyOperandModifiers(operand_storage[0], instr.vector_operands[0]); + uint32_t component; + rex::bit_scan_forward(components_remaining, &component); + components_remaining &= ~(uint32_t(1) << component); + spv::Id result = builder_->createCompositeExtract(operand, type_float_, + static_cast(component)); + while (rex::bit_scan_forward(components_remaining, &component)) { + components_remaining &= ~(uint32_t(1) << component); + result = builder_->createBinBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450NMax, result, + builder_->createCompositeExtract(operand, type_float_, + static_cast(component))); + } + return result; + } + + case ucode::AluVectorOpcode::kSetpEqPush: + case ucode::AluVectorOpcode::kSetpNePush: + case ucode::AluVectorOpcode::kSetpGtPush: + case ucode::AluVectorOpcode::kSetpGePush: { + // X is only needed for the result, W is needed for the predicate. + spv::Id operands[2]; + spv::Id operands_w[2]; + for (uint32_t i = 0; i < 2; ++i) { + operands[i] = GetOperandComponents(operand_storage[i], instr.vector_operands[i], + used_result_components ? 0b1001 : 0b1000); + if (used_result_components) { + operands_w[i] = builder_->createCompositeExtract(operands[i], type_float_, 1); + } else { + operands_w[i] = operands[i]; + } + } + spv::Op op = spv::Op(kOps[size_t(instr.vector_opcode)]); + // p0 = src0.w == 0.0 && src1.w op 0.0 + builder_->createStore( + builder_->createBinOp( + spv::OpLogicalAnd, type_bool_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, operands_w[0], const_float_0_), + builder_->createBinOp(op, type_bool_, operands_w[1], const_float_0_)), + var_main_predicate_); + predicate_written = true; + if (!used_result_components) { + return spv::NoResult; + } + // result = (src0.x == 0.0 && src1.x op 0.0) ? 0.0 : src0.x + 1.0 + // Or: + // result = ((src0.x == 0.0 && src1.x op 0.0) ? -1.0 : src0.x) + 1.0 + spv::Id operands_x[2]; + for (uint32_t i = 0; i < 2; ++i) { + operands_x[i] = builder_->createCompositeExtract(operands[i], type_float_, 0); + } + spv::Id condition = builder_->createBinOp( + spv::OpLogicalAnd, type_bool_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, operands_x[0], const_float_0_), + builder_->createBinOp(op, type_bool_, operands_x[1], const_float_0_)); + return builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, + builder_->createTriOp(spv::OpSelect, type_float_, condition, + builder_->makeFloatConstant(-1.0f), operands_x[0]), + const_float_1_); + } + + case ucode::AluVectorOpcode::kKillEq: + case ucode::AluVectorOpcode::kKillGt: + case ucode::AluVectorOpcode::kKillGe: + case ucode::AluVectorOpcode::kKillNe: { + KillPixel( + builder_->createUnaryOp( + spv::OpAny, type_bool_, + builder_->createBinOp( + spv::Op(kOps[size_t(instr.vector_opcode)]), type_bool4_, + GetOperandComponents(operand_storage[0], instr.vector_operands[0], 0b1111), + GetOperandComponents(operand_storage[1], instr.vector_operands[1], 0b1111))), + memexport_eM_potentially_written_before); + return const_float_0_; + } + + case ucode::AluVectorOpcode::kDst: { + spv::Id operands[2] = {}; + if (used_result_components & 0b0110) { + // result.yz is needed: [0] = y, [1] = z. + // resuly.y is needed: scalar = y. + // resuly.z is needed: scalar = z. + operands[0] = GetOperandComponents(operand_storage[0], instr.vector_operands[0], + used_result_components & 0b0110); + } + if (used_result_components & 0b1010) { + // result.yw is needed: [0] = y, [1] = w. + // resuly.y is needed: scalar = y. + // resuly.w is needed: scalar = w. + operands[1] = GetOperandComponents(operand_storage[1], instr.vector_operands[1], + used_result_components & 0b1010); + } + // y = src0.y * src1.y + spv::Id result_y = spv::NoResult; + if (used_result_components & 0b0010) { + spv::Id operands_y[2]; + operands_y[0] = (used_result_components & 0b0100) + ? builder_->createCompositeExtract(operands[0], type_float_, 0) + : operands[0]; + operands_y[1] = (used_result_components & 0b1000) + ? builder_->createCompositeExtract(operands[1], type_float_, 0) + : operands[1]; + result_y = builder_->createNoContractionBinOp(spv::OpFMul, type_float_, operands_y[0], + operands_y[1]); + if (!(instr.vector_operands[0].GetIdenticalComponents(instr.vector_operands[1]) & 0b0010)) { + // Shader Model 3: +0 or denormal * anything = +-0. + result_y = ZeroIfAnyOperandIsZero( + result_y, GetAbsoluteOperand(operands_y[0], instr.vector_operands[0]), + GetAbsoluteOperand(operands_y[1], instr.vector_operands[1])); + } + } + id_vector_temp_.clear(); + if (used_result_components & 0b0001) { + // x = 1.0 + id_vector_temp_.push_back(const_float_1_); + } + if (used_result_components & 0b0010) { + // y = src0.y * src1.y + id_vector_temp_.push_back(result_y); + } + if (used_result_components & 0b0100) { + // z = src0.z + id_vector_temp_.push_back( + (used_result_components & 0b0010) + ? builder_->createCompositeExtract(operands[0], type_float_, 1) + : operands[0]); + } + if (used_result_components & 0b1000) { + // w = src1.w + id_vector_temp_.push_back( + (used_result_components & 0b0010) + ? builder_->createCompositeExtract(operands[1], type_float_, 1) + : operands[1]); + } + assert_true(id_vector_temp_.size() == used_result_component_count); + if (used_result_component_count == 1) { + // Only one component - not composite. + return id_vector_temp_[0]; + } + return builder_->createCompositeConstruct( + type_float_vectors_[used_result_component_count - 1], id_vector_temp_); + } + } + + assert_unhandled_case(instr.vector_opcode); + EmitTranslationError("Unknown ALU vector operation"); + return spv::NoResult; +} + +spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( + const ParsedAluInstruction& instr, uint8_t memexport_eM_potentially_written_before, + bool& predicate_written) { + predicate_written = false; + + spv::Id operand_storage[2] = {}; + for (uint32_t i = 0; i < instr.scalar_operand_count; ++i) { + operand_storage[i] = LoadOperandStorage(instr.scalar_operands[i]); + } + + // In case the paired vector instruction (if processed first) terminates the + // block. + EnsureBuildPointAvailable(); + + // Lookup table for variants of instructions with similar structure. + static const unsigned int kOps[] = { + static_cast(spv::OpFAdd), // kAdds + static_cast(spv::OpFAdd), // kAddsPrev + static_cast(spv::OpNop), // kMuls + static_cast(spv::OpNop), // kMulsPrev + static_cast(spv::OpNop), // kMulsPrev2 + static_cast(spv::OpFOrdGreaterThanEqual), // kMaxs + static_cast(spv::OpFOrdLessThan), // kMins + static_cast(spv::OpFOrdEqual), // kSeqs + static_cast(spv::OpFOrdGreaterThan), // kSgts + static_cast(spv::OpFOrdGreaterThanEqual), // kSges + static_cast(spv::OpFUnordNotEqual), // kSnes + static_cast(GLSLstd450Fract), // kFrcs + static_cast(GLSLstd450Trunc), // kTruncs + static_cast(GLSLstd450Floor), // kFloors + static_cast(GLSLstd450Exp2), // kExp + static_cast(spv::OpNop), // kLogc + static_cast(GLSLstd450Log2), // kLog + static_cast(spv::OpNop), // kRcpc + static_cast(spv::OpNop), // kRcpf + static_cast(spv::OpNop), // kRcp + static_cast(spv::OpNop), // kRsqc + static_cast(spv::OpNop), // kRsqf + static_cast(GLSLstd450InverseSqrt), // kRsq + static_cast(spv::OpFOrdGreaterThanEqual), // kMaxAs + static_cast(spv::OpFOrdGreaterThanEqual), // kMaxAsf + static_cast(spv::OpFSub), // kSubs + static_cast(spv::OpFSub), // kSubsPrev + static_cast(spv::OpFOrdEqual), // kSetpEq + static_cast(spv::OpFUnordNotEqual), // kSetpNe + static_cast(spv::OpFOrdGreaterThan), // kSetpGt + static_cast(spv::OpFOrdGreaterThanEqual), // kSetpGe + static_cast(spv::OpNop), // kSetpInv + static_cast(spv::OpNop), // kSetpPop + static_cast(spv::OpNop), // kSetpClr + static_cast(spv::OpNop), // kSetpRstr + static_cast(spv::OpFOrdEqual), // kKillsEq + static_cast(spv::OpFOrdGreaterThan), // kKillsGt + static_cast(spv::OpFOrdGreaterThanEqual), // kKillsGe + static_cast(spv::OpFUnordNotEqual), // kKillsNe + static_cast(spv::OpFOrdEqual), // kKillsOne + static_cast(GLSLstd450Sqrt), // kSqrt + static_cast(spv::OpNop), // Invalid + static_cast(spv::OpNop), // kMulsc0 + static_cast(spv::OpNop), // kMulsc1 + static_cast(spv::OpFAdd), // kAddsc0 + static_cast(spv::OpFAdd), // kAddsc1 + static_cast(spv::OpFSub), // kSubsc0 + static_cast(spv::OpFSub), // kSubsc1 + static_cast(GLSLstd450Sin), // kSin + static_cast(GLSLstd450Cos), // kCos + static_cast(spv::OpNop), // kRetainPrev + }; + + switch (instr.scalar_opcode) { + case ucode::AluScalarOpcode::kAdds: + case ucode::AluScalarOpcode::kSubs: { + spv::Id a, b; + GetOperandScalarXY(operand_storage[0], instr.scalar_operands[0], a, b); + return builder_->createNoContractionBinOp(spv::Op(kOps[size_t(instr.scalar_opcode)]), + type_float_, a, b); + } + case ucode::AluScalarOpcode::kAddsPrev: + case ucode::AluScalarOpcode::kSubsPrev: { + return builder_->createNoContractionBinOp( + spv::Op(kOps[size_t(instr.scalar_opcode)]), type_float_, + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001), + builder_->createLoad(var_main_previous_scalar_, spv::NoPrecision)); + } + case ucode::AluScalarOpcode::kMuls: { + spv::Id a, b; + GetOperandScalarXY(operand_storage[0], instr.scalar_operands[0], a, b); + spv::Id result = builder_->createNoContractionBinOp(spv::OpFMul, type_float_, a, b); + if (a != b) { + // Shader Model 3: +0 or denormal * anything = +-0. + result = ZeroIfAnyOperandIsZero(result, GetAbsoluteOperand(a, instr.scalar_operands[0]), + GetAbsoluteOperand(b, instr.scalar_operands[0])); + } + return result; + } + case ucode::AluScalarOpcode::kMulsPrev: { + spv::Id a = GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001); + spv::Id ps = builder_->createLoad(var_main_previous_scalar_, spv::NoPrecision); + spv::Id result = builder_->createNoContractionBinOp(spv::OpFMul, type_float_, a, ps); + // Shader Model 3: +0 or denormal * anything = +-0. + return ZeroIfAnyOperandIsZero(result, GetAbsoluteOperand(a, instr.scalar_operands[0]), + builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450FAbs, ps)); + } + case ucode::AluScalarOpcode::kMulsPrev2: { + // Check if need to select the src0.a * ps case. + // Selection merge must be the penultimate instruction in the block, check + // the condition before it. + spv::Id ps = builder_->createLoad(var_main_previous_scalar_, spv::NoPrecision); + // ps != -FLT_MAX. + spv::Id const_float_max_neg = builder_->makeFloatConstant(-FLT_MAX); + spv::Id condition = + builder_->createBinOp(spv::OpFUnordNotEqual, type_bool_, ps, const_float_max_neg); + // isfinite(ps), or |ps| <= FLT_MAX, or -|ps| >= -FLT_MAX, since -FLT_MAX + // is already loaded to an SGPR, this is also false if it's NaN. + spv::Id ps_abs = + builder_->createUnaryBuiltinCall(type_float_, ext_inst_glsl_std_450_, GLSLstd450FAbs, ps); + spv::Id ps_abs_neg = + builder_->createNoContractionUnaryOp(spv::OpFNegate, type_float_, ps_abs); + condition = + builder_->createBinOp(spv::OpLogicalAnd, type_bool_, condition, + builder_->createBinOp(spv::OpFOrdGreaterThanEqual, type_bool_, + ps_abs_neg, const_float_max_neg)); + // isfinite(src0.b), or -|src0.b| >= -FLT_MAX for the same reason. + spv::Id b = GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0010); + spv::Id b_abs_neg = b; + if (!instr.scalar_operands[0].is_absolute_value) { + b_abs_neg = builder_->createUnaryBuiltinCall(type_float_, ext_inst_glsl_std_450_, + GLSLstd450FAbs, b_abs_neg); + } + if (!instr.scalar_operands[0].is_absolute_value || !instr.scalar_operands[0].is_negated) { + b_abs_neg = builder_->createNoContractionUnaryOp(spv::OpFNegate, type_float_, b_abs_neg); + } + condition = + builder_->createBinOp(spv::OpLogicalAnd, type_bool_, condition, + builder_->createBinOp(spv::OpFOrdGreaterThanEqual, type_bool_, + b_abs_neg, const_float_max_neg)); + // src0.b > 0 (need !(src0.b <= 0), but src0.b has already been checked + // for NaN). + condition = builder_->createBinOp( + spv::OpLogicalAnd, type_bool_, condition, + builder_->createBinOp(spv::OpFOrdGreaterThan, type_bool_, b, const_float_0_)); + SpirvBuilder::IfBuilder multiply_if(condition, spv::SelectionControlMaskNone, *builder_); + spv::Id product; + { + // Multiplication case. + spv::Id a = + instr.scalar_operands[0].GetComponent(0) != instr.scalar_operands[0].GetComponent(1) + ? GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001) + : b; + product = builder_->createNoContractionBinOp(spv::OpFMul, type_float_, a, ps); + // Shader Model 3: +0 or denormal * anything = +-0. + product = ZeroIfAnyOperandIsZero(product, GetAbsoluteOperand(a, instr.scalar_operands[0]), + ps_abs); + } + multiply_if.makeEndIf(); + // Merge - choose between the product and -FLT_MAX. + return multiply_if.createMergePhi(product, const_float_max_neg); + } + + case ucode::AluScalarOpcode::kMaxs: + case ucode::AluScalarOpcode::kMins: + case ucode::AluScalarOpcode::kMaxAs: + case ucode::AluScalarOpcode::kMaxAsf: { + spv::Id a, b; + GetOperandScalarXY(operand_storage[0], instr.scalar_operands[0], a, b); + if (instr.scalar_opcode == ucode::AluScalarOpcode::kMaxAs || + instr.scalar_opcode == ucode::AluScalarOpcode::kMaxAsf) { + // maxas: a0 = (int)clamp(floor(src0.a + 0.5), -256.0, 255.0) + // maxasf: a0 = (int)clamp(floor(src0.a), -256.0, 255.0) + spv::Id maxa_address; + if (instr.scalar_opcode == ucode::AluScalarOpcode::kMaxAs) { + maxa_address = builder_->createNoContractionBinOp(spv::OpFAdd, type_float_, a, + builder_->makeFloatConstant(0.5f)); + } else { + maxa_address = a; + } + builder_->createStore( + builder_->createUnaryOp( + spv::OpConvertFToS, type_int_, + builder_->createTriBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450NClamp, + builder_->createUnaryBuiltinCall(type_float_, ext_inst_glsl_std_450_, + GLSLstd450Floor, maxa_address), + builder_->makeFloatConstant(-256.0f), builder_->makeFloatConstant(255.0f))), + var_main_address_register_); + } + if (a == b) { + // max is commonly used as mov. + return a; + } + // Shader Model 3 NaN behavior (a op b ? a : b, not SPIR-V FMax/FMin which + // are undefined for NaN or NMax/NMin which return the non-NaN operand). + return builder_->createTriOp( + spv::OpSelect, type_float_, + builder_->createBinOp(spv::Op(kOps[size_t(instr.scalar_opcode)]), type_bool_, a, b), a, + b); + } + + case ucode::AluScalarOpcode::kSeqs: + case ucode::AluScalarOpcode::kSgts: + case ucode::AluScalarOpcode::kSges: + case ucode::AluScalarOpcode::kSnes: + return builder_->createTriOp( + spv::OpSelect, type_float_, + builder_->createBinOp( + spv::Op(kOps[size_t(instr.scalar_opcode)]), type_bool_, + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001), + const_float_0_), + const_float_1_, const_float_0_); + + case ucode::AluScalarOpcode::kFrcs: + case ucode::AluScalarOpcode::kTruncs: + case ucode::AluScalarOpcode::kFloors: + case ucode::AluScalarOpcode::kExp: + case ucode::AluScalarOpcode::kLog: + case ucode::AluScalarOpcode::kRsq: + case ucode::AluScalarOpcode::kSqrt: + case ucode::AluScalarOpcode::kSin: + case ucode::AluScalarOpcode::kCos: + return builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450(kOps[size_t(instr.scalar_opcode)]), + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001)); + case ucode::AluScalarOpcode::kLogc: { + spv::Id result = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450Log2, + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001)); + return builder_->createTriOp(spv::OpSelect, type_float_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, + builder_->makeFloatConstant(-INFINITY)), + builder_->makeFloatConstant(-FLT_MAX), result); + } + case ucode::AluScalarOpcode::kRcpc: { + spv::Id result = builder_->createNoContractionBinOp( + spv::OpFDiv, type_float_, const_float_1_, + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001)); + result = builder_->createTriOp(spv::OpSelect, type_float_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, + builder_->makeFloatConstant(-INFINITY)), + builder_->makeFloatConstant(-FLT_MAX), result); + return builder_->createTriOp(spv::OpSelect, type_float_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, + builder_->makeFloatConstant(INFINITY)), + builder_->makeFloatConstant(FLT_MAX), result); + } + case ucode::AluScalarOpcode::kRcpf: { + spv::Id result = builder_->createNoContractionBinOp( + spv::OpFDiv, type_float_, const_float_1_, + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001)); + result = builder_->createTriOp(spv::OpSelect, type_float_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, + builder_->makeFloatConstant(INFINITY)), + const_float_0_, result); + // Can't create -0.0f with makeFloatConstant due to float comparison + // internally, cast to bit pattern. + result = builder_->createTriOp(spv::OpSelect, type_uint_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, + builder_->makeFloatConstant(-INFINITY)), + builder_->makeUintConstant(uint32_t(INT32_MIN)), + builder_->createUnaryOp(spv::OpBitcast, type_uint_, result)); + return builder_->createUnaryOp(spv::OpBitcast, type_float_, result); + } + case ucode::AluScalarOpcode::kRcp: { + return builder_->createNoContractionBinOp( + spv::OpFDiv, type_float_, const_float_1_, + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001)); + } + case ucode::AluScalarOpcode::kRsqc: { + spv::Id result = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450InverseSqrt, + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001)); + result = builder_->createTriOp(spv::OpSelect, type_float_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, + builder_->makeFloatConstant(-INFINITY)), + builder_->makeFloatConstant(-FLT_MAX), result); + return builder_->createTriOp(spv::OpSelect, type_float_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, + builder_->makeFloatConstant(INFINITY)), + builder_->makeFloatConstant(FLT_MAX), result); + } + case ucode::AluScalarOpcode::kRsqf: { + spv::Id result = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450InverseSqrt, + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001)); + result = builder_->createTriOp(spv::OpSelect, type_float_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, + builder_->makeFloatConstant(INFINITY)), + const_float_0_, result); + // Can't create -0.0f with makeFloatConstant due to float comparison + // internally, cast to bit pattern. + result = builder_->createTriOp(spv::OpSelect, type_uint_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, + builder_->makeFloatConstant(-INFINITY)), + builder_->makeUintConstant(uint32_t(INT32_MIN)), + builder_->createUnaryOp(spv::OpBitcast, type_uint_, result)); + return builder_->createUnaryOp(spv::OpBitcast, type_float_, result); + } + + case ucode::AluScalarOpcode::kSetpEq: + case ucode::AluScalarOpcode::kSetpNe: + case ucode::AluScalarOpcode::kSetpGt: + case ucode::AluScalarOpcode::kSetpGe: { + spv::Id predicate = builder_->createBinOp( + spv::Op(kOps[size_t(instr.scalar_opcode)]), type_bool_, + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001), + const_float_0_); + builder_->createStore(predicate, var_main_predicate_); + predicate_written = true; + return builder_->createTriOp(spv::OpSelect, type_float_, predicate, const_float_0_, + const_float_1_); + } + case ucode::AluScalarOpcode::kSetpInv: { + spv::Id a = GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001); + spv::Id predicate = builder_->createBinOp(spv::OpFOrdEqual, type_bool_, a, const_float_1_); + builder_->createStore(predicate, var_main_predicate_); + predicate_written = true; + return builder_->createTriOp( + spv::OpSelect, type_float_, predicate, const_float_0_, + builder_->createTriOp( + spv::OpSelect, type_float_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, a, const_float_0_), + const_float_1_, a)); + } + case ucode::AluScalarOpcode::kSetpPop: { + spv::Id a_minus_1 = builder_->createNoContractionBinOp( + spv::OpFSub, type_float_, + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001), + const_float_1_); + spv::Id predicate = + builder_->createBinOp(spv::OpFOrdLessThanEqual, type_bool_, a_minus_1, const_float_0_); + builder_->createStore(predicate, var_main_predicate_); + predicate_written = true; + return builder_->createTriOp(spv::OpSelect, type_float_, predicate, const_float_0_, + a_minus_1); + } + case ucode::AluScalarOpcode::kSetpClr: + builder_->createStore(builder_->makeBoolConstant(false), var_main_predicate_); + return builder_->makeFloatConstant(FLT_MAX); + case ucode::AluScalarOpcode::kSetpRstr: { + spv::Id a = GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001); + spv::Id predicate = builder_->createBinOp(spv::OpFOrdEqual, type_bool_, a, const_float_0_); + builder_->createStore(predicate, var_main_predicate_); + predicate_written = true; + return builder_->createTriOp(spv::OpSelect, type_float_, predicate, const_float_0_, a); + } + + case ucode::AluScalarOpcode::kKillsEq: + case ucode::AluScalarOpcode::kKillsGt: + case ucode::AluScalarOpcode::kKillsGe: + case ucode::AluScalarOpcode::kKillsNe: + case ucode::AluScalarOpcode::kKillsOne: { + KillPixel(builder_->createBinOp( + spv::Op(kOps[size_t(instr.scalar_opcode)]), type_bool_, + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001), + instr.scalar_opcode == ucode::AluScalarOpcode::kKillsOne ? const_float_1_ + : const_float_0_), + memexport_eM_potentially_written_before); + return const_float_0_; + } + + case ucode::AluScalarOpcode::kMulsc0: + case ucode::AluScalarOpcode::kMulsc1: { + spv::Id operand_0 = + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001); + spv::Id operand_1 = + GetOperandComponents(operand_storage[1], instr.scalar_operands[1], 0b0001); + spv::Id result = + builder_->createNoContractionBinOp(spv::OpFMul, type_float_, operand_0, operand_1); + if (!(instr.scalar_operands[0].GetIdenticalComponents(instr.scalar_operands[1]) & 0b0001)) { + // Shader Model 3: +0 or denormal * anything = +-0. + result = + ZeroIfAnyOperandIsZero(result, GetAbsoluteOperand(operand_0, instr.scalar_operands[0]), + GetAbsoluteOperand(operand_1, instr.scalar_operands[1])); + } + return result; + } + case ucode::AluScalarOpcode::kAddsc0: + case ucode::AluScalarOpcode::kAddsc1: + case ucode::AluScalarOpcode::kSubsc0: + case ucode::AluScalarOpcode::kSubsc1: { + return builder_->createNoContractionBinOp( + spv::Op(kOps[size_t(instr.scalar_opcode)]), type_float_, + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001), + GetOperandComponents(operand_storage[1], instr.scalar_operands[1], 0b0001)); + } + + case ucode::AluScalarOpcode::kRetainPrev: + // Special case in ProcessAluInstruction - loading ps only if writing to + // anywhere. + return spv::NoResult; + } + + assert_unhandled_case(instr.scalar_opcode); + EmitTranslationError("Unknown ALU scalar operation"); + return spv::NoResult; +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/shader/spirv_translator_fetch.cpp b/src/graphics/pipeline/shader/spirv_translator_fetch.cpp new file mode 100644 index 0000000..9ce3bb4 --- /dev/null +++ b/src/graphics/pipeline/shader/spirv_translator_fetch.cpp @@ -0,0 +1,2249 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +namespace rex::graphics { + +void SpirvShaderTranslator::ProcessVertexFetchInstruction( + const ParsedVertexFetchInstruction& instr) { + UpdateInstructionPredication(instr.is_predicated, instr.predicate_condition); + + uint32_t used_result_components = instr.result.GetUsedResultComponents(); + uint32_t needed_words = + xenos::GetVertexFormatNeededWords(instr.attributes.data_format, used_result_components); + // If this is vfetch_full, the address may still be needed for vfetch_mini - + // don't exit before calculating the address. + if (!needed_words && instr.is_mini_fetch) { + // Nothing to load - just constant 0/1 writes, or the swizzle includes only + // components that don't exist in the format (writing zero instead of them). + // Unpacking assumes at least some word is needed. + StoreResult(instr.result, spv::NoResult); + return; + } + + EnsureBuildPointAvailable(); + + uint32_t fetch_constant_word_0_index = instr.operands[1].storage_index << 1; + + spv::Id address; + if (instr.is_mini_fetch) { + // `base + index * stride` loaded by vfetch_full. + address = builder_->createLoad(var_main_vfetch_address_, spv::NoPrecision); + } else { + // Get the base address in dwords from the bits 2:31 of the first fetch + // constant word. + id_vector_temp_.clear(); + // The only element of the fetch constant buffer. + id_vector_temp_.push_back(const_int_0_); + // Vector index. + id_vector_temp_.push_back(builder_->makeIntConstant(int(fetch_constant_word_0_index >> 2))); + // Component index. + id_vector_temp_.push_back(builder_->makeIntConstant(int(fetch_constant_word_0_index & 3))); + spv::Id fetch_constant_word_0 = + builder_->createLoad(builder_->createAccessChain(spv::StorageClassUniform, + uniform_fetch_constants_, id_vector_temp_), + spv::NoPrecision); + // TODO(Triang3l): Verify the fetch constant type (that it's a vertex fetch, + // not a texture fetch) here instead of dropping draws with invalid vertex + // fetch constants on the CPU when proper bound checks are added - vfetch + // may be conditional, so fetch constants may also be used conditionally. + address = builder_->createUnaryOp( + spv::OpBitcast, type_int_, + builder_->createBinOp(spv::OpShiftRightLogical, type_uint_, fetch_constant_word_0, + builder_->makeUintConstant(2))); + if (instr.attributes.stride) { + // Convert the index to an integer by flooring or by rounding to the + // nearest (as floor(index + 0.5) because rounding to the nearest even + // makes no sense for addressing, both 1.5 and 2.5 would be 2). + spv::Id index = + GetOperandComponents(LoadOperandStorage(instr.operands[0]), instr.operands[0], 0b0001); + if (instr.attributes.is_index_rounded) { + index = builder_->createNoContractionBinOp(spv::OpFAdd, type_float_, index, + builder_->makeFloatConstant(0.5f)); + } + index = + builder_->createUnaryOp(spv::OpConvertFToS, type_int_, + builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450Floor, index)); + if (instr.attributes.stride > 1) { + index = builder_->createBinOp(spv::OpIMul, type_int_, index, + builder_->makeIntConstant(int(instr.attributes.stride))); + } + address = builder_->createBinOp(spv::OpIAdd, type_int_, address, index); + } + // Store the address for the subsequent vfetch_mini. + builder_->createStore(address, var_main_vfetch_address_); + } + + if (!needed_words) { + // The vfetch_full address has been loaded for the subsequent vfetch_mini, + // but there's no data to load. + StoreResult(instr.result, spv::NoResult); + return; + } + + // Load the needed words. + unsigned int word_composite_indices[4] = {}; + spv::Id word_composite_constituents[4]; + uint32_t word_count = 0; + uint32_t words_remaining = needed_words; + uint32_t word_index; + while (rex::bit_scan_forward(words_remaining, &word_index)) { + words_remaining &= ~(1 << word_index); + spv::Id word_address = address; + // Add the word offset from the instruction (signed), plus the offset of the + // word within the element. + int32_t word_offset = instr.attributes.offset + word_index; + if (word_offset) { + word_address = builder_->createBinOp(spv::OpIAdd, type_int_, word_address, + builder_->makeIntConstant(int(word_offset))); + } + word_composite_indices[word_index] = word_count; + // FIXME(Triang3l): Bound checking is not done here, but haven't encountered + // any games relying on out-of-bounds access. On Adreno 200 on Android (LG + // P705), however, words (not full elements) out of glBufferData bounds + // contain 0. + word_composite_constituents[word_count++] = LoadUint32FromSharedMemory(word_address); + } + spv::Id words; + if (word_count > 1) { + // Copying from the array to id_vector_temp_ now, not in the loop above, + // because of the LoadUint32FromSharedMemory call (potentially using + // id_vector_temp_ internally). + id_vector_temp_.clear(); + id_vector_temp_.insert(id_vector_temp_.cend(), word_composite_constituents, + word_composite_constituents + word_count); + words = builder_->createCompositeConstruct(type_uint_vectors_[word_count - 1], id_vector_temp_); + } else { + words = word_composite_constituents[0]; + } + + // Endian swap the words, getting the endianness from bits 0:1 of the second + // fetch constant word. + uint32_t fetch_constant_word_1_index = fetch_constant_word_0_index + 1; + id_vector_temp_.clear(); + // The only element of the fetch constant buffer. + id_vector_temp_.push_back(const_int_0_); + // Vector index. + id_vector_temp_.push_back(builder_->makeIntConstant(int(fetch_constant_word_1_index >> 2))); + // Component index. + id_vector_temp_.push_back(builder_->makeIntConstant(int(fetch_constant_word_1_index & 3))); + spv::Id fetch_constant_word_1 = + builder_->createLoad(builder_->createAccessChain(spv::StorageClassUniform, + uniform_fetch_constants_, id_vector_temp_), + spv::NoPrecision); + words = EndianSwap32Uint( + words, builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, fetch_constant_word_1, + builder_->makeUintConstant(0b11))); + + spv::Id result = spv::NoResult; + + // Convert the format. + uint32_t used_format_components = + used_result_components & + ((1 << xenos::GetVertexFormatComponentCount(instr.attributes.data_format)) - 1); + // If needed_words is not zero (checked in the beginning), this must not be + // zero too. For simplicity, it's assumed that something will be unpacked + // here. + assert_not_zero(used_format_components); + uint32_t used_format_component_count = rex::bit_count(used_format_components); + spv::Id result_type = type_float_vectors_[used_format_component_count - 1]; + bool format_is_packed = false; + int packed_widths[4] = {}, packed_offsets[4] = {}; + uint32_t packed_words[4] = {}; + switch (instr.attributes.data_format) { + case xenos::VertexFormat::k_8_8_8_8: + format_is_packed = true; + packed_widths[0] = packed_widths[1] = packed_widths[2] = packed_widths[3] = 8; + packed_offsets[1] = 8; + packed_offsets[2] = 16; + packed_offsets[3] = 24; + break; + case xenos::VertexFormat::k_2_10_10_10: + format_is_packed = true; + packed_widths[0] = packed_widths[1] = packed_widths[2] = 10; + packed_widths[3] = 2; + packed_offsets[1] = 10; + packed_offsets[2] = 20; + packed_offsets[3] = 30; + break; + case xenos::VertexFormat::k_10_11_11: + format_is_packed = true; + packed_widths[0] = packed_widths[1] = 11; + packed_widths[2] = 10; + packed_offsets[1] = 11; + packed_offsets[2] = 22; + break; + case xenos::VertexFormat::k_11_11_10: + format_is_packed = true; + packed_widths[0] = 10; + packed_widths[1] = packed_widths[2] = 11; + packed_offsets[1] = 10; + packed_offsets[2] = 21; + break; + case xenos::VertexFormat::k_16_16: + format_is_packed = true; + packed_widths[0] = packed_widths[1] = 16; + packed_offsets[1] = 16; + break; + case xenos::VertexFormat::k_16_16_16_16: + format_is_packed = true; + packed_widths[0] = packed_widths[1] = packed_widths[2] = packed_widths[3] = 16; + packed_offsets[1] = packed_offsets[3] = 16; + packed_words[2] = packed_words[3] = 1; + break; + + case xenos::VertexFormat::k_16_16_FLOAT: + case xenos::VertexFormat::k_16_16_16_16_FLOAT: { + // FIXME(Triang3l): This converts from GLSL float16 with NaNs instead of + // Xbox 360 float16 with extended range. However, haven't encountered + // games relying on that yet. + spv::Id word_needed_component_values[2] = {}; + for (uint32_t i = 0; i < 2; ++i) { + uint32_t word_needed_components = (used_format_components >> (i * 2)) & 0b11; + if (!word_needed_components) { + continue; + } + spv::Id word; + if (word_count > 1) { + word = builder_->createCompositeExtract(words, type_uint_, word_composite_indices[i]); + } else { + word = words; + } + word = builder_->createUnaryBuiltinCall(type_float2_, ext_inst_glsl_std_450_, + GLSLstd450UnpackHalf2x16, word); + if (word_needed_components != 0b11) { + // If only one of two components is needed, extract it. + word = builder_->createCompositeExtract(word, type_float_, + (word_needed_components & 0b01) ? 0 : 1); + } + word_needed_component_values[i] = word; + } + if (word_needed_component_values[1] == spv::NoResult) { + result = word_needed_component_values[0]; + } else if (word_needed_component_values[0] == spv::NoResult) { + result = word_needed_component_values[1]; + } else { + // Bypassing the assertion in spv::Builder::createCompositeConstruct as + // of November 5, 2020 - can construct vectors by concatenating vectors, + // not just from individual scalars. + std::unique_ptr composite_construct_op = + std::make_unique(builder_->getUniqueId(), result_type, + spv::OpCompositeConstruct); + composite_construct_op->addIdOperand(word_needed_component_values[0]); + composite_construct_op->addIdOperand(word_needed_component_values[1]); + result = composite_construct_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(composite_construct_op)); + } + } break; + + case xenos::VertexFormat::k_32: + case xenos::VertexFormat::k_32_32: + case xenos::VertexFormat::k_32_32_32_32: + assert_true(used_format_components == needed_words); + if (instr.attributes.is_signed) { + result = builder_->createUnaryOp(spv::OpBitcast, + type_int_vectors_[used_format_component_count - 1], words); + result = builder_->createUnaryOp(spv::OpConvertSToF, result_type, result); + } else { + result = builder_->createUnaryOp(spv::OpConvertUToF, result_type, words); + } + if (!instr.attributes.is_integer) { + if (instr.attributes.is_signed) { + switch (instr.attributes.signed_rf_mode) { + case xenos::SignedRepeatingFractionMode::kZeroClampMinusOne: + result = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, result_type, result, + builder_->makeFloatConstant(1.0f / 2147483647.0f)); + // No need to clamp to -1 if signed - 1/(2^31-1) is rounded to + // 1/(2^31) as float32. + break; + case xenos::SignedRepeatingFractionMode::kNoZero: { + result = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, result_type, result, + builder_->makeFloatConstant(1.0f / 2147483647.5f)); + spv::Id const_no_zero = builder_->makeFloatConstant(0.5f / 2147483647.5f); + if (used_format_component_count > 1) { + id_vector_temp_.clear(); + id_vector_temp_.insert(id_vector_temp_.cend(), used_format_component_count, + const_no_zero); + const_no_zero = builder_->makeCompositeConstant(result_type, id_vector_temp_); + } + result = builder_->createNoContractionBinOp(spv::OpFAdd, result_type, result, + const_no_zero); + } break; + default: + assert_unhandled_case(instr.attributes.signed_rf_mode); + } + } else { + result = + builder_->createNoContractionBinOp(spv::OpVectorTimesScalar, result_type, result, + builder_->makeFloatConstant(1.0f / 4294967295.0f)); + } + } + break; + + case xenos::VertexFormat::k_32_FLOAT: + case xenos::VertexFormat::k_32_32_FLOAT: + case xenos::VertexFormat::k_32_32_32_32_FLOAT: + case xenos::VertexFormat::k_32_32_32_FLOAT: + assert_true(used_format_components == needed_words); + result = builder_->createUnaryOp(spv::OpBitcast, type_float_vectors_[word_count - 1], words); + break; + + default: + assert_unhandled_case(instr.attributes.data_format); + } + + if (format_is_packed) { + assert_true(result == spv::NoResult); + // Extract the components from the words as individual ints or uints. + if (instr.attributes.is_signed) { + // Sign-extending extraction - in GLSL the sign-extending overload accepts + // int. + words = builder_->createUnaryOp(spv::OpBitcast, type_int_vectors_[word_count - 1], words); + } + int extracted_widths[4] = {}; + spv::Id extracted_components[4] = {}; + uint32_t extracted_component_count = 0; + unsigned int extraction_word_current_index = UINT_MAX; + // Default is `words` itself if 1 word loaded. + spv::Id extraction_word_current = words; + for (uint32_t i = 0; i < 4; ++i) { + if (!(used_format_components & (1 << i))) { + continue; + } + if (word_count > 1) { + unsigned int extraction_word_new_index = word_composite_indices[packed_words[i]]; + if (extraction_word_current_index != extraction_word_new_index) { + extraction_word_current_index = extraction_word_new_index; + extraction_word_current = builder_->createCompositeExtract( + words, instr.attributes.is_signed ? type_int_ : type_uint_, + extraction_word_new_index); + } + } + int extraction_width = packed_widths[i]; + assert_not_zero(extraction_width); + extracted_widths[extracted_component_count] = extraction_width; + extracted_components[extracted_component_count] = builder_->createTriOp( + instr.attributes.is_signed ? spv::OpBitFieldSExtract : spv::OpBitFieldUExtract, + instr.attributes.is_signed ? type_int_ : type_uint_, extraction_word_current, + builder_->makeIntConstant(packed_offsets[i]), + builder_->makeIntConstant(extraction_width)); + ++extracted_component_count; + } + // Combine extracted components into a vector. + assert_true(extracted_component_count == used_format_component_count); + if (used_format_component_count > 1) { + id_vector_temp_.clear(); + id_vector_temp_.insert(id_vector_temp_.cend(), extracted_components, + extracted_components + used_format_component_count); + result = builder_->createCompositeConstruct( + instr.attributes.is_signed ? type_int_vectors_[used_format_component_count - 1] + : type_uint_vectors_[used_format_component_count - 1], + id_vector_temp_); + } else { + result = extracted_components[0]; + } + // Convert to floating-point. + result = builder_->createUnaryOp( + instr.attributes.is_signed ? spv::OpConvertSToF : spv::OpConvertUToF, result_type, result); + // Normalize. + if (!instr.attributes.is_integer) { + float packed_scales[4]; + bool packed_scales_same = true; + for (uint32_t i = 0; i < used_format_component_count; ++i) { + int extracted_width = extracted_widths[i]; + // The signed case would result in 1.0 / 0.0 for 1-bit components, but + // there are no Xenos formats with them. + assert_true(extracted_width >= 2); + packed_scales_same &= extracted_width != extracted_widths[0]; + float packed_scale_inv; + if (instr.attributes.is_signed) { + packed_scale_inv = float((uint32_t(1) << (extracted_width - 1)) - 1); + if (instr.attributes.signed_rf_mode == xenos::SignedRepeatingFractionMode::kNoZero) { + packed_scale_inv += 0.5f; + } + } else { + packed_scale_inv = float((uint32_t(1) << extracted_width) - 1); + } + packed_scales[i] = 1.0f / packed_scale_inv; + } + spv::Id const_packed_scale = builder_->makeFloatConstant(packed_scales[0]); + spv::Op packed_scale_mul_op; + if (used_format_component_count > 1) { + if (packed_scales_same) { + packed_scale_mul_op = spv::OpVectorTimesScalar; + } else { + packed_scale_mul_op = spv::OpFMul; + id_vector_temp_.clear(); + id_vector_temp_.push_back(const_packed_scale); + for (uint32_t i = 1; i < used_format_component_count; ++i) { + id_vector_temp_.push_back(builder_->makeFloatConstant(packed_scales[i])); + } + const_packed_scale = builder_->makeCompositeConstant(result_type, id_vector_temp_); + } + } else { + packed_scale_mul_op = spv::OpFMul; + } + result = builder_->createNoContractionBinOp(packed_scale_mul_op, result_type, result, + const_packed_scale); + if (instr.attributes.is_signed) { + switch (instr.attributes.signed_rf_mode) { + case xenos::SignedRepeatingFractionMode::kZeroClampMinusOne: { + // Treat both -(2^(n-1)) and -(2^(n-1)-1) as -1. Using regular FMax, + // not NMax, because the number is known not to be NaN. + spv::Id const_minus_1 = builder_->makeFloatConstant(-1.0f); + if (used_format_component_count > 1) { + id_vector_temp_.clear(); + id_vector_temp_.resize(used_format_component_count, const_minus_1); + const_minus_1 = builder_->makeCompositeConstant(result_type, id_vector_temp_); + } + result = builder_->createBinBuiltinCall(result_type, ext_inst_glsl_std_450_, + GLSLstd450FMax, result, const_minus_1); + } break; + case xenos::SignedRepeatingFractionMode::kNoZero: + id_vector_temp_.clear(); + for (uint32_t i = 0; i < used_format_component_count; ++i) { + id_vector_temp_.push_back(builder_->makeFloatConstant(0.5f * packed_scales[i])); + } + result = builder_->createNoContractionBinOp( + spv::OpFAdd, result_type, result, + used_format_component_count > 1 + ? builder_->makeCompositeConstant(result_type, id_vector_temp_) + : id_vector_temp_[0]); + break; + default: + assert_unhandled_case(instr.attributes.signed_rf_mode); + } + } + } + } + + if (result != spv::NoResult) { + // Apply the exponent bias. + if (instr.attributes.exp_adjust) { + result = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, builder_->getTypeId(result), result, + builder_->makeFloatConstant(std::ldexp(1.0f, instr.attributes.exp_adjust))); + } + + // If any components not present in the format were requested, pad the + // resulting vector with zeros. + uint32_t used_missing_components = used_result_components & ~used_format_components; + if (used_missing_components) { + // Bypassing the assertion in spv::Builder::createCompositeConstruct as of + // November 5, 2020 - can construct vectors by concatenating vectors, not + // just from individual scalars. + std::unique_ptr composite_construct_op = std::make_unique( + builder_->getUniqueId(), type_float_vectors_[rex::bit_count(used_result_components) - 1], + spv::OpCompositeConstruct); + composite_construct_op->addIdOperand(result); + composite_construct_op->addIdOperand( + const_float_vectors_0_[rex::bit_count(used_missing_components) - 1]); + result = composite_construct_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(composite_construct_op)); + } + } + StoreResult(instr.result, result); +} + +void SpirvShaderTranslator::ProcessTextureFetchInstruction( + const ParsedTextureFetchInstruction& instr) { + UpdateInstructionPredication(instr.is_predicated, instr.predicate_condition); + + EnsureBuildPointAvailable(); + + // Handle the instructions for setting the register LOD. + switch (instr.opcode) { + case ucode::FetchOpcode::kSetTextureLod: + builder_->createStore( + GetOperandComponents(LoadOperandStorage(instr.operands[0]), instr.operands[0], 0b0001), + var_main_tfetch_lod_); + return; + case ucode::FetchOpcode::kSetTextureGradientsHorz: + builder_->createStore( + GetOperandComponents(LoadOperandStorage(instr.operands[0]), instr.operands[0], 0b0111), + var_main_tfetch_gradients_h_); + return; + case ucode::FetchOpcode::kSetTextureGradientsVert: + builder_->createStore( + GetOperandComponents(LoadOperandStorage(instr.operands[0]), instr.operands[0], 0b0111), + var_main_tfetch_gradients_v_); + return; + default: + break; + } + + // Handle instructions that store something. + uint32_t used_result_components = instr.result.GetUsedResultComponents(); + uint32_t used_result_nonzero_components = instr.GetNonZeroResultComponents(); + switch (instr.opcode) { + case ucode::FetchOpcode::kTextureFetch: + break; + case ucode::FetchOpcode::kGetTextureBorderColorFrac: + // TODO(Triang3l): Bind a black texture with a white border to calculate + // the border color fraction (in the X component of the result). + assert_always(); + EmitTranslationError("getBCF is unimplemented", false); + used_result_nonzero_components = 0; + break; + case ucode::FetchOpcode::kGetTextureComputedLod: + break; + case ucode::FetchOpcode::kGetTextureGradients: + break; + case ucode::FetchOpcode::kGetTextureWeights: + // FIXME(Triang3l): Currently disregarding the LOD completely in + // getWeights because the needed code would be very complicated, while + // getWeights is mostly used for things like PCF of shadow maps, that + // don't have mips. The LOD would be needed for the mip lerp factor in W + // of the return value and to choose the LOD where interpolation would + // take place for XYZ. That would require either implementing the LOD + // calculation algorithm using the ALU (since the `lod` instruction is + // limited to pixel shaders and can't be used when there's control flow + // divergence, unlike explicit gradients), or sampling a texture filled + // with LOD numbers (easier and more consistent - unclamped LOD doesn't + // make sense for getWeights anyway). The same applies to offsets. + used_result_nonzero_components &= ~uint32_t(0b1000); + break; + default: + assert_unhandled_case(instr.opcode); + EmitTranslationError("Unknown texture fetch operation"); + used_result_nonzero_components = 0; + } + uint32_t used_result_component_count = rex::bit_count(used_result_components); + if (!used_result_nonzero_components) { + // Nothing to fetch, only constant 0/1 writes - simplify the rest of the + // function so it doesn't have to handle this case. + if (used_result_components) { + StoreResult(instr.result, const_float_vectors_0_[used_result_component_count - 1]); + } + return; + } + + spv::Id result[] = {const_float_0_, const_float_0_, const_float_0_, const_float_0_}; + + if (instr.opcode == ucode::FetchOpcode::kGetTextureGradients) { + // Doesn't need the texture, handle separately. + spv::Id operand_0_storage = LoadOperandStorage(instr.operands[0]); + bool derivative_function_x_used = (used_result_nonzero_components & 0b0011) != 0; + bool derivative_function_y_used = (used_result_nonzero_components & 0b1100) != 0; + spv::Id derivative_function_x = spv::NoResult; + spv::Id derivative_function_y = spv::NoResult; + if (derivative_function_x_used && derivative_function_y_used) { + spv::Id derivative_function = + GetOperandComponents(operand_0_storage, instr.operands[0], 0b0011); + derivative_function_x = builder_->createCompositeExtract(derivative_function, type_float_, 0); + derivative_function_y = builder_->createCompositeExtract(derivative_function, type_float_, 1); + } else { + if (derivative_function_x_used) { + derivative_function_x = GetOperandComponents(operand_0_storage, instr.operands[0], 0b0001); + } + if (derivative_function_y_used) { + derivative_function_y = GetOperandComponents(operand_0_storage, instr.operands[0], 0b0010); + } + } + builder_->addCapability(spv::CapabilityDerivativeControl); + uint32_t derivative_components_remaining = used_result_nonzero_components; + uint32_t derivative_component_index; + while (rex::bit_scan_forward(derivative_components_remaining, &derivative_component_index)) { + derivative_components_remaining &= ~(UINT32_C(1) << derivative_component_index); + result[derivative_component_index] = builder_->createUnaryOp( + (derivative_component_index & 0b01) ? spv::OpDPdyCoarse : spv::OpDPdxCoarse, type_float_, + (derivative_component_index & 0b10) ? derivative_function_y : derivative_function_x); + } + } else { + // kTextureFetch, kGetTextureComputedLod or kGetTextureWeights. + + // Whether to use gradients (implicit or explicit) for LOD calculation. + bool use_computed_lod = instr.attributes.use_computed_lod && + (is_pixel_shader() || instr.attributes.use_register_gradients); + if (instr.opcode == ucode::FetchOpcode::kGetTextureComputedLod && + (!use_computed_lod || instr.attributes.use_register_gradients)) { + assert_always(); + EmitTranslationError( + "getCompTexLOD used with explicit LOD or gradients - contradicts " + "MSDN", + false); + StoreResult(instr.result, const_float_vectors_0_[used_result_component_count - 1]); + return; + } + + uint32_t fetch_constant_index = instr.operands[1].storage_index; + uint32_t fetch_constant_word_0_index = 6 * fetch_constant_index; + + spv::Id sampler = spv::NoResult; + spv::Id image_2d_array_or_cube_unsigned = spv::NoResult; + spv::Id image_2d_array_or_cube_signed = spv::NoResult; + spv::Id image_3d_unsigned = spv::NoResult; + spv::Id image_3d_signed = spv::NoResult; + if (instr.opcode != ucode::FetchOpcode::kGetTextureWeights) { + bool bindings_set_up = true; + // While GL_ARB_texture_query_lod specifies the value for + // GL_NEAREST_MIPMAP_NEAREST and GL_LINEAR_MIPMAP_NEAREST minifying + // functions as rounded (unlike the `lod` instruction in Direct3D 10.1+, + // which is not defined for point sampling), the XNA assembler doesn't + // accept MipFilter overrides for getCompTexLOD - probably should be + // linear only, though not known exactly. + // + // 4D5307F2 uses vertex displacement map textures for tessellated models + // like the beehive tree with explicit LOD with point sampling (they store + // values packed in two components), however, the fetch constant has + // anisotropic filtering enabled. However, Direct3D 12 doesn't allow + // mixing anisotropic and point filtering. Possibly anistropic filtering + // should be disabled when explicit LOD is used - do this here. + size_t sampler_index = FindOrAddSamplerBinding( + fetch_constant_index, instr.attributes.mag_filter, instr.attributes.min_filter, + instr.opcode == ucode::FetchOpcode::kGetTextureComputedLod ? xenos::TextureFilter::kLinear + : instr.attributes.mip_filter, + use_computed_lod ? instr.attributes.aniso_filter : xenos::AnisoFilter::kDisabled); + xenos::FetchOpDimension dimension_2d_array_or_cube = + instr.dimension == xenos::FetchOpDimension::k3DOrStacked ? xenos::FetchOpDimension::k2D + : instr.dimension; + size_t image_2d_array_or_cube_unsigned_index = + FindOrAddTextureBinding(fetch_constant_index, dimension_2d_array_or_cube, false); + size_t image_2d_array_or_cube_signed_index = + FindOrAddTextureBinding(fetch_constant_index, dimension_2d_array_or_cube, true); + if (sampler_index == SIZE_MAX || image_2d_array_or_cube_unsigned_index == SIZE_MAX || + image_2d_array_or_cube_signed_index == SIZE_MAX) { + bindings_set_up = false; + } + size_t image_3d_unsigned_index = SIZE_MAX; + size_t image_3d_signed_index = SIZE_MAX; + if (instr.dimension == xenos::FetchOpDimension::k3DOrStacked) { + image_3d_unsigned_index = FindOrAddTextureBinding( + fetch_constant_index, xenos::FetchOpDimension::k3DOrStacked, false); + image_3d_signed_index = FindOrAddTextureBinding( + fetch_constant_index, xenos::FetchOpDimension::k3DOrStacked, true); + if (image_3d_unsigned_index == SIZE_MAX || image_3d_signed_index == SIZE_MAX) { + bindings_set_up = false; + } + } + if (!bindings_set_up) { + // Too many image or sampler bindings used. + StoreResult(instr.result, const_float_vectors_0_[used_result_component_count - 1]); + return; + } + sampler = builder_->createLoad(sampler_bindings_[sampler_index].variable, spv::NoPrecision); + const TextureBinding& image_2d_array_or_cube_unsigned_binding = + texture_bindings_[image_2d_array_or_cube_unsigned_index]; + image_2d_array_or_cube_unsigned = + builder_->createLoad(image_2d_array_or_cube_unsigned_binding.variable, spv::NoPrecision); + const TextureBinding& image_2d_array_or_cube_signed_binding = + texture_bindings_[image_2d_array_or_cube_signed_index]; + image_2d_array_or_cube_signed = + builder_->createLoad(image_2d_array_or_cube_signed_binding.variable, spv::NoPrecision); + if (image_3d_unsigned_index != SIZE_MAX) { + const TextureBinding& image_3d_unsigned_binding = + texture_bindings_[image_3d_unsigned_index]; + image_3d_unsigned = + builder_->createLoad(image_3d_unsigned_binding.variable, spv::NoPrecision); + } + if (image_3d_signed_index != SIZE_MAX) { + const TextureBinding& image_3d_signed_binding = texture_bindings_[image_3d_signed_index]; + image_3d_signed = builder_->createLoad(image_3d_signed_binding.variable, spv::NoPrecision); + } + } + + // Get offsets applied to the coordinates before sampling. + // FIXME(Triang3l): Offsets need to be applied at the LOD being fetched, not + // at LOD 0. However, since offsets have granularity of 0.5, not 1, on the + // Xenos, they can't be passed directly as ConstOffset to the image sample + // instruction (plus-minus 0.5 offsets are very common in games). But + // offsetting at mip levels is a rare usage case, mostly offsets are used + // for things like shadow maps and blur, where there are no mips. + float offset_values[3] = {}; + // MSDN doesn't list offsets as getCompTexLOD parameters. + if (instr.opcode != ucode::FetchOpcode::kGetTextureComputedLod) { + // Add a small epsilon to the offset (1.5/4 the fixed-point texture + // coordinate ULP with 8-bit subtexel precision - shouldn't significantly + // effect the fixed-point conversion; 1/4 is also not enough with 3x + // resolution scaling very noticeably on the weapon in 4D5307E6, at least + // on the Direct3D 12 backend) to resolve ambiguity when fetching + // point-sampled textures between texels. This applies to both normalized + // (58410954 Xbox Live Arcade logo, coordinates interpolated between + // vertices with half-pixel offset) and unnormalized (4D5307E6 lighting + // G-buffer reading, ps_param_gen pixels) coordinates. On Nvidia Pascal, + // without this adjustment, blockiness is visible in both cases. Possibly + // there is a better way, however, an attempt was made to error-correct + // division by adding the difference between original and re-denormalized + // coordinates, but on Nvidia, `mul` (on Direct3D 12) and internal + // multiplication in texture sampling apparently round differently, so + // `mul` gives a value that would be floored as expected, but the + // left/upper pixel is still sampled instead. + const float kRoundingOffset = 1.5f / 1024.0f; + switch (instr.dimension) { + case xenos::FetchOpDimension::k1D: + offset_values[0] = instr.attributes.offset_x + kRoundingOffset; + if (instr.opcode == ucode::FetchOpcode::kGetTextureWeights) { + // For coordinate lerp factors. This needs to be done separately for + // point mag/min filters, but they're currently not handled here + // anyway. + offset_values[0] -= 0.5f; + } + break; + case xenos::FetchOpDimension::k2D: + offset_values[0] = instr.attributes.offset_x + kRoundingOffset; + offset_values[1] = instr.attributes.offset_y + kRoundingOffset; + if (instr.opcode == ucode::FetchOpcode::kGetTextureWeights) { + offset_values[0] -= 0.5f; + offset_values[1] -= 0.5f; + } + break; + case xenos::FetchOpDimension::k3DOrStacked: + offset_values[0] = instr.attributes.offset_x + kRoundingOffset; + offset_values[1] = instr.attributes.offset_y + kRoundingOffset; + offset_values[2] = instr.attributes.offset_z + kRoundingOffset; + if (instr.opcode == ucode::FetchOpcode::kGetTextureWeights) { + offset_values[0] -= 0.5f; + offset_values[1] -= 0.5f; + offset_values[2] -= 0.5f; + } + break; + case xenos::FetchOpDimension::kCube: + // Applying the rounding epsilon to cube maps too for potential game + // passes processing cube map faces themselves. + offset_values[0] = instr.attributes.offset_x + kRoundingOffset; + offset_values[1] = instr.attributes.offset_y + kRoundingOffset; + if (instr.opcode == ucode::FetchOpcode::kGetTextureWeights) { + offset_values[0] -= 0.5f; + offset_values[1] -= 0.5f; + // The logic for ST weights is the same for all faces. + // FIXME(Triang3l): If LOD calculation is added to getWeights, face + // offset probably will need to be handled too (if the hardware + // supports it at all, though MSDN lists OffsetZ in tfetchCube). + } else { + offset_values[2] = instr.attributes.offset_z; + } + break; + } + } + uint32_t offsets_not_zero = 0b000; + for (uint32_t i = 0; i < 3; ++i) { + if (offset_values[i]) { + offsets_not_zero |= 1 << i; + } + } + + // Fetch constant word usage: + // - 2: Size (needed only once). + // - 3: Exponent adjustment (needed only once). + // - 4: Conditionally for 3D kTextureFetch: stacked texture filtering modes. + // Unconditionally LOD kTextureFetch: LOD and gradient exponent bias, + // result exponent bias. + // - 5: Dimensionality (3D or 2D stacked - needed only once). + + // Load the texture size and whether it's 3D or stacked if needed. + // 1D: X - width. + // 2D, cube: X - width, Y - height (cube maps probably can be only square, + // but for simplicity). + // 3D: X - width, Y - height, Z - depth. + uint32_t size_needed_components = 0b000; + bool data_is_3d_needed = false; + if (instr.opcode == ucode::FetchOpcode::kGetTextureWeights) { + // Size needed for denormalization for coordinate lerp factor. + // FIXME(Triang3l): Currently disregarding the LOD completely in + // getWeights. However, if the LOD lerp factor and the LOD where filtering + // would happen are ever calculated, all components of the size may be + // needed for ALU LOD calculation with normalized coordinates (or, if a + // texture filled with LOD indices is used, coordinates will need to be + // normalized as normally). + if (!instr.attributes.unnormalized_coordinates) { + switch (instr.dimension) { + case xenos::FetchOpDimension::k1D: + size_needed_components |= used_result_nonzero_components & 0b0001; + break; + case xenos::FetchOpDimension::k2D: + case xenos::FetchOpDimension::kCube: + size_needed_components |= used_result_nonzero_components & 0b0011; + break; + case xenos::FetchOpDimension::k3DOrStacked: + size_needed_components |= used_result_nonzero_components & 0b0111; + break; + } + } + } else { + // Size needed for normalization (or, for stacked texture layers, + // denormalization) and for offsets. + size_needed_components |= offsets_not_zero; + switch (instr.dimension) { + case xenos::FetchOpDimension::k1D: + if (instr.attributes.unnormalized_coordinates) { + size_needed_components |= 0b0001; + } + break; + case xenos::FetchOpDimension::k2D: + if (instr.attributes.unnormalized_coordinates) { + size_needed_components |= 0b0011; + } + break; + case xenos::FetchOpDimension::k3DOrStacked: + // Stacked and 3D textures are fetched from different bindings - the + // check is always needed. + data_is_3d_needed = true; + if (instr.attributes.unnormalized_coordinates) { + // Need to normalize all (if 3D). + size_needed_components |= 0b0111; + } else { + // Need to denormalize Z (if stacked). + size_needed_components |= 0b0100; + } + break; + case xenos::FetchOpDimension::kCube: + if (instr.attributes.unnormalized_coordinates) { + size_needed_components |= 0b0011; + } + // The size is not needed for face ID offset. + size_needed_components &= 0b0011; + break; + } + } + if (instr.dimension == xenos::FetchOpDimension::k3DOrStacked && size_needed_components) { + // Stacked and 3D textures have different size packing - need to get + // whether the texture is 3D unconditionally. + data_is_3d_needed = true; + } + spv::Id data_is_3d = spv::NoResult; + if (data_is_3d_needed) { + // Get the data dimensionality from the bits 9:10 of the fetch constant + // word 5. + id_vector_temp_.clear(); + id_vector_temp_.push_back(const_int_0_); + id_vector_temp_.push_back( + builder_->makeIntConstant(int((fetch_constant_word_0_index + 5) >> 2))); + id_vector_temp_.push_back( + builder_->makeIntConstant(int((fetch_constant_word_0_index + 5) & 3))); + spv::Id fetch_constant_word_5 = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_fetch_constants_, + id_vector_temp_), + spv::NoPrecision); + spv::Id data_dimension = + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, fetch_constant_word_5, + builder_->makeUintConstant(9), builder_->makeUintConstant(2)); + data_is_3d = builder_->createBinOp( + spv::OpIEqual, type_bool_, data_dimension, + builder_->makeUintConstant(static_cast(xenos::DataDimension::k3D))); + } + spv::Id size[3] = {}; + if (size_needed_components) { + // Get the size from the fetch constant word 2. + id_vector_temp_.clear(); + id_vector_temp_.push_back(const_int_0_); + id_vector_temp_.push_back( + builder_->makeIntConstant(int((fetch_constant_word_0_index + 2) >> 2))); + id_vector_temp_.push_back( + builder_->makeIntConstant(int((fetch_constant_word_0_index + 2) & 3))); + spv::Id fetch_constant_word_2 = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_fetch_constants_, + id_vector_temp_), + spv::NoPrecision); + switch (instr.dimension) { + case xenos::FetchOpDimension::k1D: { + if (size_needed_components & 0b1) { + size[0] = builder_->createTriOp( + spv::OpBitFieldUExtract, type_uint_, fetch_constant_word_2, const_uint_0_, + builder_->makeUintConstant(xenos::kTexture1DMaxWidthLog2)); + } + assert_zero(size_needed_components & 0b110); + } break; + case xenos::FetchOpDimension::k2D: + case xenos::FetchOpDimension::kCube: { + if (size_needed_components & 0b1) { + size[0] = builder_->createTriOp( + spv::OpBitFieldUExtract, type_uint_, fetch_constant_word_2, const_uint_0_, + builder_->makeUintConstant(xenos::kTexture2DCubeMaxWidthHeightLog2)); + } + if (size_needed_components & 0b10) { + spv::Id width_height_bit_count = + builder_->makeUintConstant(xenos::kTexture2DCubeMaxWidthHeightLog2); + size[1] = + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, fetch_constant_word_2, + width_height_bit_count, width_height_bit_count); + } + assert_zero(size_needed_components & 0b100); + } break; + case xenos::FetchOpDimension::k3DOrStacked: { + if (size_needed_components & 0b1) { + spv::Id size_3d = builder_->createTriOp( + spv::OpBitFieldUExtract, type_uint_, fetch_constant_word_2, const_uint_0_, + builder_->makeUintConstant(xenos::kTexture3DMaxWidthHeightLog2)); + spv::Id size_2d = builder_->createTriOp( + spv::OpBitFieldUExtract, type_uint_, fetch_constant_word_2, const_uint_0_, + builder_->makeUintConstant(xenos::kTexture2DCubeMaxWidthHeightLog2)); + assert_true(data_is_3d != spv::NoResult); + size[0] = + builder_->createTriOp(spv::OpSelect, type_uint_, data_is_3d, size_3d, size_2d); + } + if (size_needed_components & 0b10) { + spv::Id width_height_bit_count_3d = + builder_->makeUintConstant(xenos::kTexture3DMaxWidthHeightLog2); + spv::Id size_3d = + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, fetch_constant_word_2, + width_height_bit_count_3d, width_height_bit_count_3d); + spv::Id width_height_bit_count_2d = + builder_->makeUintConstant(xenos::kTexture2DCubeMaxWidthHeightLog2); + spv::Id size_2d = + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, fetch_constant_word_2, + width_height_bit_count_2d, width_height_bit_count_2d); + assert_true(data_is_3d != spv::NoResult); + size[1] = + builder_->createTriOp(spv::OpSelect, type_uint_, data_is_3d, size_3d, size_2d); + } + if (size_needed_components & 0b100) { + spv::Id size_3d = builder_->createTriOp( + spv::OpBitFieldUExtract, type_uint_, fetch_constant_word_2, + builder_->makeUintConstant(xenos::kTexture3DMaxWidthHeightLog2 * 2), + builder_->makeUintConstant(xenos::kTexture3DMaxDepthLog2)); + spv::Id size_2d = builder_->createTriOp( + spv::OpBitFieldUExtract, type_uint_, fetch_constant_word_2, + builder_->makeUintConstant(xenos::kTexture2DCubeMaxWidthHeightLog2 * 2), + builder_->makeUintConstant(xenos::kTexture2DMaxStackDepthLog2)); + assert_true(data_is_3d != spv::NoResult); + size[2] = + builder_->createTriOp(spv::OpSelect, type_uint_, data_is_3d, size_3d, size_2d); + } + } break; + } + { + uint32_t size_remaining_components = size_needed_components; + uint32_t size_component_index; + while (rex::bit_scan_forward(size_remaining_components, &size_component_index)) { + size_remaining_components &= ~(UINT32_C(1) << size_component_index); + spv::Id& size_component_ref = size[size_component_index]; + // Fetch constants store size minus 1 - add 1. + size_component_ref = builder_->createBinOp(spv::OpIAdd, type_uint_, size_component_ref, + builder_->makeUintConstant(1)); + // Convert the size to float for multiplication or division. + size_component_ref = + builder_->createUnaryOp(spv::OpConvertUToF, type_float_, size_component_ref); + } + } + } + + // FIXME(Triang3l): Mip lerp factor needs to be calculated, and the + // coordinate lerp factors should be calculated at the mip level texels + // would be sampled from. That would require some way of calculating the + // LOD that would be applicable to explicit gradients and vertex shaders. + // Also, with point sampling, possibly lerp factors need to be 0. W (mip + // lerp factor) should have been masked out previously because it's not + // supported currently. + assert_false(instr.opcode == ucode::FetchOpcode::kGetTextureWeights && + (used_result_nonzero_components & 0b1000)); + + // Load the needed original values of the coordinates operand. + uint32_t coordinates_needed_components = + instr.opcode == ucode::FetchOpcode::kGetTextureWeights + ? used_result_nonzero_components + : ((UINT32_C(1) << xenos::GetFetchOpDimensionComponentCount(instr.dimension)) - 1); + assert_not_zero(coordinates_needed_components); + spv::Id coordinates_operand = GetOperandComponents( + LoadOperandStorage(instr.operands[0]), instr.operands[0], coordinates_needed_components); + spv::Id coordinates[] = {const_float_0_, const_float_0_, const_float_0_}; + if (rex::bit_count(coordinates_needed_components) > 1) { + uint32_t coordinates_remaining_components = coordinates_needed_components; + uint32_t coordinate_component_index; + uint32_t coordinate_operand_component_index = 0; + while (rex::bit_scan_forward(coordinates_remaining_components, &coordinate_component_index)) { + coordinates_remaining_components &= ~(UINT32_C(1) << coordinate_component_index); + coordinates[coordinate_component_index] = builder_->createCompositeExtract( + coordinates_operand, type_float_, coordinate_operand_component_index++); + } + } else { + uint32_t coordinate_component_index; + rex::bit_scan_forward(coordinates_needed_components, &coordinate_component_index); + coordinates[coordinate_component_index] = coordinates_operand; + } + spv::Id texture_resolution_scaled = spv::NoResult; + uint32_t revert_resolution_scale_axes = + uint32_t(draw_resolution_scale_x_ > 1) | (uint32_t(draw_resolution_scale_y_ > 1) << 1); + spv::Id const_texture_resolution_scale[] = {spv::NoResult, spv::NoResult}; + spv::Id const_texture_resolution_scale_reciprocal[] = {spv::NoResult, spv::NoResult}; + if (revert_resolution_scale_axes) { + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantTexturesResolutionScaled)); + spv::Id textures_resolution_scaled = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + texture_resolution_scaled = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, textures_resolution_scaled, + builder_->makeUintConstant(UINT32_C(1) << fetch_constant_index)), + const_uint_0_); + if (revert_resolution_scale_axes & 0b001) { + const_texture_resolution_scale[0] = + builder_->makeFloatConstant(float(draw_resolution_scale_x_)); + const_texture_resolution_scale_reciprocal[0] = + builder_->makeFloatConstant(1.0f / float(draw_resolution_scale_x_)); + } + if (revert_resolution_scale_axes & 0b010) { + const_texture_resolution_scale[1] = + builder_->makeFloatConstant(float(draw_resolution_scale_y_)); + const_texture_resolution_scale_reciprocal[1] = + builder_->makeFloatConstant(1.0f / float(draw_resolution_scale_y_)); + } + } + + if (instr.opcode == ucode::FetchOpcode::kGetTextureWeights) { + uint32_t resolution_scaled_result_components = + used_result_nonzero_components & revert_resolution_scale_axes; + uint32_t resolution_scaled_coord_components = + instr.attributes.unnormalized_coordinates ? resolution_scaled_result_components : 0b000; + uint32_t resolution_scaled_size_components = + size_needed_components & resolution_scaled_result_components; + if (texture_resolution_scaled != spv::NoResult && + (resolution_scaled_coord_components || resolution_scaled_size_components)) { + for (uint32_t i = 0; i < 2; ++i) { + if (resolution_scaled_coord_components & (UINT32_C(1) << i)) { + coordinates[i] = builder_->createTriOp( + spv::OpSelect, type_float_, texture_resolution_scaled, + builder_->createNoContractionBinOp(spv::OpFMul, type_float_, coordinates[i], + const_texture_resolution_scale[i]), + coordinates[i]); + } + if (resolution_scaled_size_components & (UINT32_C(1) << i)) { + assert_true(size[i] != spv::NoResult); + size[i] = builder_->createTriOp( + spv::OpSelect, type_float_, texture_resolution_scaled, + builder_->createNoContractionBinOp(spv::OpFMul, type_float_, size[i], + const_texture_resolution_scale[i]), + size[i]); + } + } + } + + // FIXME(Triang3l): Filtering modes should possibly be taken into account, + // but for simplicity, not doing that - from a high level point of view, + // would be useless to get weights that will always be zero. + uint32_t coordinates_remaining_components = coordinates_needed_components; + uint32_t coordinate_component_index; + while (rex::bit_scan_forward(coordinates_remaining_components, &coordinate_component_index)) { + coordinates_remaining_components &= ~(UINT32_C(1) << coordinate_component_index); + spv::Id result_component = coordinates[coordinate_component_index]; + // Need unnormalized coordinates. + if (!instr.attributes.unnormalized_coordinates) { + spv::Id size_component = size[coordinate_component_index]; + assert_true(size_component != spv::NoResult); + result_component = builder_->createNoContractionBinOp(spv::OpFMul, type_float_, + result_component, size_component); + } + float component_offset = offset_values[coordinate_component_index]; + if (component_offset) { + result_component = + builder_->createNoContractionBinOp(spv::OpFAdd, type_float_, result_component, + builder_->makeFloatConstant(component_offset)); + } + // 0.5 has already been subtracted via offsets previously. + result_component = builder_->createUnaryBuiltinCall(type_float_, ext_inst_glsl_std_450_, + GLSLstd450Fract, result_component); + result[coordinate_component_index] = result_component; + } + } else { + // kTextureFetch or kGetTextureComputedLod. + + // Normalize the XY coordinates, and apply the offset. + for (uint32_t i = 0; i <= uint32_t(instr.dimension != xenos::FetchOpDimension::k1D); ++i) { + spv::Id& coordinate_ref = coordinates[i]; + spv::Id component_offset = + offset_values[i] ? builder_->makeFloatConstant(offset_values[i]) : spv::NoResult; + if (component_offset != spv::NoResult && texture_resolution_scaled != spv::NoResult && + (revert_resolution_scale_axes & (UINT32_C(1) << i))) { + spv::Id component_offset_resolution_scaled = + builder_->createNoContractionBinOp(spv::OpFMul, type_float_, component_offset, + const_texture_resolution_scale_reciprocal[i]); + component_offset = + builder_->createTriOp(spv::OpSelect, type_float_, texture_resolution_scaled, + component_offset_resolution_scaled, component_offset); + } + spv::Id size_component = size[i]; + if (instr.attributes.unnormalized_coordinates) { + if (component_offset != spv::NoResult) { + coordinate_ref = builder_->createNoContractionBinOp(spv::OpFAdd, type_float_, + coordinate_ref, component_offset); + } + assert_true(size_component != spv::NoResult); + coordinate_ref = builder_->createNoContractionBinOp(spv::OpFDiv, type_float_, + coordinate_ref, size_component); + } else { + if (component_offset != spv::NoResult) { + assert_true(size_component != spv::NoResult); + spv::Id component_offset_normalized = builder_->createNoContractionBinOp( + spv::OpFDiv, type_float_, component_offset, size_component); + coordinate_ref = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, coordinate_ref, component_offset_normalized); + } + } + } + if (instr.dimension == xenos::FetchOpDimension::k3DOrStacked) { + spv::Id& z_coordinate_ref = coordinates[2]; + spv::Id z_offset = + offset_values[2] ? builder_->makeFloatConstant(offset_values[2]) : spv::NoResult; + spv::Id z_size = size[2]; + if (instr.attributes.unnormalized_coordinates) { + // Apply the offset, and normalize the Z coordinate for a 3D texture. + if (z_offset != spv::NoResult) { + z_coordinate_ref = builder_->createNoContractionBinOp(spv::OpFAdd, type_float_, + z_coordinate_ref, z_offset); + } + assert_true(data_is_3d != spv::NoResult); + SpirvBuilder::IfBuilder if_data_is_3d(data_is_3d, spv::SelectionControlDontFlattenMask, + *builder_); + spv::Id z_3d; + { + assert_true(z_size != spv::NoResult); + z_3d = builder_->createNoContractionBinOp(spv::OpFDiv, type_float_, z_coordinate_ref, + z_size); + } + if_data_is_3d.makeEndIf(); + z_coordinate_ref = if_data_is_3d.createMergePhi(z_3d, z_coordinate_ref); + } else { + // Denormalize the Z coordinate for a stacked texture, and apply the + // offset. + spv::Block& block_dimension_head = *builder_->getBuildPoint(); + spv::Block& block_dimension_merge = builder_->makeNewBlock(); + spv::Block* block_dimension_3d = + z_offset != spv::NoResult ? &builder_->makeNewBlock() : nullptr; + spv::Block& block_dimension_stacked = builder_->makeNewBlock(); + builder_->createSelectionMerge(&block_dimension_merge, + spv::SelectionControlDontFlattenMask); + assert_true(data_is_3d != spv::NoResult); + builder_->createConditionalBranch( + data_is_3d, block_dimension_3d ? block_dimension_3d : &block_dimension_merge, + &block_dimension_stacked); + // 3D case. + spv::Id z_3d = z_coordinate_ref; + if (block_dimension_3d) { + builder_->setBuildPoint(block_dimension_3d); + if (z_offset != spv::NoResult) { + assert_true(z_size != spv::NoResult); + spv::Id z_offset_normalized = + builder_->createNoContractionBinOp(spv::OpFDiv, type_float_, z_offset, z_size); + z_3d = builder_->createNoContractionBinOp(spv::OpFAdd, type_float_, z_3d, + z_offset_normalized); + } + builder_->createBranch(&block_dimension_merge); + } + // Stacked case. + builder_->setBuildPoint(&block_dimension_stacked); + spv::Id z_stacked = z_coordinate_ref; + assert_true(z_size != spv::NoResult); + z_stacked = + builder_->createNoContractionBinOp(spv::OpFMul, type_float_, z_stacked, z_size); + if (z_offset != spv::NoResult) { + z_stacked = + builder_->createNoContractionBinOp(spv::OpFAdd, type_float_, z_stacked, z_offset); + } + builder_->createBranch(&block_dimension_merge); + // Select one of the two. + builder_->setBuildPoint(&block_dimension_merge); + { + std::unique_ptr z_phi_op = std::make_unique( + builder_->getUniqueId(), type_float_, spv::OpPhi); + z_phi_op->addIdOperand(z_3d); + z_phi_op->addIdOperand( + (block_dimension_3d ? *block_dimension_3d : block_dimension_head).getId()); + z_phi_op->addIdOperand(z_stacked); + z_phi_op->addIdOperand(block_dimension_stacked.getId()); + z_coordinate_ref = z_phi_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(z_phi_op)); + } + } + } else if (instr.dimension == xenos::FetchOpDimension::kCube) { + // Transform the cube coordinates from 2D to 3D. + // Move SC/TC from 1...2 to -1...1. + spv::Id const_float_2 = builder_->makeFloatConstant(2.0f); + spv::Id const_float_minus_3 = builder_->makeFloatConstant(-3.0f); + for (uint32_t i = 0; i < 2; ++i) { + coordinates[i] = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, + builder_->createNoContractionBinOp(spv::OpFMul, type_float_, coordinates[i], + const_float_2), + const_float_minus_3); + } + // Get the face index (floored, within 0...5 - OpConvertFToU is + // undefined for out-of-range values, so clamping from both sides + // manually). + spv::Id face = coordinates[2]; + if (offset_values[2]) { + face = builder_->createNoContractionBinOp(spv::OpFAdd, type_float_, face, + builder_->makeFloatConstant(offset_values[2])); + } + face = + builder_->createUnaryOp(spv::OpConvertFToU, type_uint_, + builder_->createTriBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450NClamp, face, + const_float_0_, builder_->makeFloatConstant(5.0f))); + // Split the face index into the axis and the sign. + spv::Id const_uint_1 = builder_->makeUintConstant(1); + spv::Id face_axis = + builder_->createBinOp(spv::OpShiftRightLogical, type_uint_, face, const_uint_1); + spv::Id face_is_negative = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, face, const_uint_1), + const_uint_0_); + spv::Id face_sign = builder_->createTriOp(spv::OpSelect, type_float_, face_is_negative, + builder_->makeFloatConstant(-1.0f), + builder_->makeFloatConstant(1.0f)); + // Remap the axes in a way opposite to the ALU cube instruction. + spv::Id sc_negated = + builder_->createNoContractionUnaryOp(spv::OpFNegate, type_float_, coordinates[0]); + spv::Id tc_negated = + builder_->createNoContractionUnaryOp(spv::OpFNegate, type_float_, coordinates[1]); + spv::Block& block_ma_head = *builder_->getBuildPoint(); + spv::Block& block_ma_x = builder_->makeNewBlock(); + spv::Block& block_ma_y = builder_->makeNewBlock(); + spv::Block& block_ma_z = builder_->makeNewBlock(); + spv::Block& block_ma_merge = builder_->makeNewBlock(); + builder_->createSelectionMerge(&block_ma_merge, spv::SelectionControlMaskNone); + { + std::unique_ptr ma_switch_op = + std::make_unique(spv::OpSwitch); + ma_switch_op->addIdOperand(face_axis); + // Make Z the default. + ma_switch_op->addIdOperand(block_ma_z.getId()); + ma_switch_op->addImmediateOperand(0); + ma_switch_op->addIdOperand(block_ma_x.getId()); + ma_switch_op->addImmediateOperand(1); + ma_switch_op->addIdOperand(block_ma_y.getId()); + builder_->getBuildPoint()->addInstruction(std::move(ma_switch_op)); + } + block_ma_x.addPredecessor(&block_ma_head); + block_ma_y.addPredecessor(&block_ma_head); + block_ma_z.addPredecessor(&block_ma_head); + // X is the major axis case. + builder_->setBuildPoint(&block_ma_x); + spv::Id ma_x_y = tc_negated; + spv::Id ma_x_z = builder_->createTriOp(spv::OpSelect, type_float_, face_is_negative, + coordinates[0], sc_negated); + builder_->createBranch(&block_ma_merge); + // Y is the major axis case. + builder_->setBuildPoint(&block_ma_y); + spv::Id ma_y_x = coordinates[0]; + spv::Id ma_y_z = builder_->createTriOp(spv::OpSelect, type_float_, face_is_negative, + tc_negated, coordinates[1]); + builder_->createBranch(&block_ma_merge); + // Z is the major axis case. + builder_->setBuildPoint(&block_ma_z); + spv::Id ma_z_x = builder_->createTriOp(spv::OpSelect, type_float_, face_is_negative, + sc_negated, coordinates[0]); + spv::Id ma_z_y = tc_negated; + builder_->createBranch(&block_ma_merge); + // Gather the coordinate components from the branches. + builder_->setBuildPoint(&block_ma_merge); + { + std::unique_ptr x_phi_op = + std::make_unique(builder_->getUniqueId(), type_float_, spv::OpPhi); + x_phi_op->addIdOperand(face_sign); + x_phi_op->addIdOperand(block_ma_x.getId()); + x_phi_op->addIdOperand(ma_y_x); + x_phi_op->addIdOperand(block_ma_y.getId()); + x_phi_op->addIdOperand(ma_z_x); + x_phi_op->addIdOperand(block_ma_z.getId()); + coordinates[0] = x_phi_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(x_phi_op)); + } + { + std::unique_ptr y_phi_op = + std::make_unique(builder_->getUniqueId(), type_float_, spv::OpPhi); + y_phi_op->addIdOperand(ma_x_y); + y_phi_op->addIdOperand(block_ma_x.getId()); + y_phi_op->addIdOperand(face_sign); + y_phi_op->addIdOperand(block_ma_y.getId()); + y_phi_op->addIdOperand(ma_z_y); + y_phi_op->addIdOperand(block_ma_z.getId()); + coordinates[1] = y_phi_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(y_phi_op)); + } + { + std::unique_ptr z_phi_op = + std::make_unique(builder_->getUniqueId(), type_float_, spv::OpPhi); + z_phi_op->addIdOperand(ma_x_z); + z_phi_op->addIdOperand(block_ma_x.getId()); + z_phi_op->addIdOperand(ma_y_z); + z_phi_op->addIdOperand(block_ma_y.getId()); + z_phi_op->addIdOperand(face_sign); + z_phi_op->addIdOperand(block_ma_z.getId()); + coordinates[2] = z_phi_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(z_phi_op)); + } + } + + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantTextureSwizzledSigns)); + id_vector_temp_.push_back(builder_->makeIntConstant(fetch_constant_index >> 4)); + id_vector_temp_.push_back(builder_->makeIntConstant((fetch_constant_index >> 2) & 3)); + // All 32 bits containing the values for 4 fetch constants (use + // OpBitFieldUExtract to get the signednesses for the specific components + // of this texture). + spv::Id swizzled_signs_word = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + uint32_t swizzled_signs_word_offset = 8 * (fetch_constant_index & 3); + + spv::Builder::TextureParameters texture_parameters = {}; + + if (instr.opcode == ucode::FetchOpcode::kGetTextureComputedLod) { + // kGetTextureComputedLod. + + // Check if the signed binding is needs to be accessed rather than the + // unsigned (if all signednesses are signed). + spv::Id swizzled_signs_all_signed = builder_->createBinOp( + spv::OpIEqual, type_bool_, + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, swizzled_signs_word, + builder_->makeUintConstant(swizzled_signs_word_offset), + builder_->makeUintConstant(8)), + builder_->makeUintConstant(uint32_t(xenos::TextureSign::kSigned) * 0b01010101)); + + // OpImageQueryLod doesn't need the array layer component. + // So, 3 coordinate components for 3D cube, 2 in other cases (including + // 1D, which are emulated as 2D arrays). + // OpSampledImage must be in the same block as where its result is used. + if (instr.dimension == xenos::FetchOpDimension::k3DOrStacked) { + // Check if the texture is 3D or stacked. + assert_true(data_is_3d != spv::NoResult); + SpirvBuilder::IfBuilder if_data_is_3d(data_is_3d, spv::SelectionControlDontFlattenMask, + *builder_); + spv::Id lod_3d; + { + // 3D. + id_vector_temp_.clear(); + for (uint32_t i = 0; i < 3; ++i) { + id_vector_temp_.push_back(coordinates[i]); + } + texture_parameters.coords = + builder_->createCompositeConstruct(type_float3_, id_vector_temp_); + lod_3d = QueryTextureLod(texture_parameters, image_3d_unsigned, image_3d_signed, + sampler, swizzled_signs_all_signed); + } + if_data_is_3d.makeBeginElse(); + spv::Id lod_stacked; + { + // 2D stacked. + id_vector_temp_.clear(); + for (uint32_t i = 0; i < 2; ++i) { + id_vector_temp_.push_back(coordinates[i]); + } + texture_parameters.coords = + builder_->createCompositeConstruct(type_float2_, id_vector_temp_); + lod_stacked = + QueryTextureLod(texture_parameters, image_2d_array_or_cube_unsigned, + image_2d_array_or_cube_signed, sampler, swizzled_signs_all_signed); + } + if_data_is_3d.makeEndIf(); + result[0] = if_data_is_3d.createMergePhi(lod_3d, lod_stacked); + } else { + uint32_t lod_query_coordinate_component_count = + instr.dimension == xenos::FetchOpDimension::kCube ? 3 : 2; + id_vector_temp_.clear(); + for (uint32_t i = 0; i < lod_query_coordinate_component_count; ++i) { + id_vector_temp_.push_back(coordinates[i]); + } + texture_parameters.coords = builder_->createCompositeConstruct( + type_float_vectors_[lod_query_coordinate_component_count - 1], id_vector_temp_); + result[0] = + QueryTextureLod(texture_parameters, image_2d_array_or_cube_unsigned, + image_2d_array_or_cube_signed, sampler, swizzled_signs_all_signed); + } + } else { + // kTextureFetch. + assert_true(instr.opcode == ucode::FetchOpcode::kTextureFetch); + + // Extract the signedness for each component of the swizzled result, and + // get which bindings (unsigned and signed) are needed. + spv::Id swizzled_signs[4] = {}; + spv::Id result_is_signed[4] = {}; + spv::Id is_all_signed = spv::NoResult; + spv::Id is_any_signed = spv::NoResult; + spv::Id const_uint_2 = builder_->makeUintConstant(2); + spv::Id const_uint_sign_signed = + builder_->makeUintConstant(uint32_t(xenos::TextureSign::kSigned)); + { + uint32_t result_remaining_components = used_result_nonzero_components; + uint32_t result_component_index; + while (rex::bit_scan_forward(result_remaining_components, &result_component_index)) { + result_remaining_components &= ~(UINT32_C(1) << result_component_index); + spv::Id result_component_sign = builder_->createTriOp( + spv::OpBitFieldUExtract, type_uint_, swizzled_signs_word, + builder_->makeUintConstant(swizzled_signs_word_offset + 2 * result_component_index), + const_uint_2); + swizzled_signs[result_component_index] = result_component_sign; + spv::Id is_component_signed = builder_->createBinOp( + spv::OpIEqual, type_bool_, result_component_sign, const_uint_sign_signed); + result_is_signed[result_component_index] = is_component_signed; + if (is_all_signed != spv::NoResult) { + is_all_signed = builder_->createBinOp(spv::OpLogicalAnd, type_bool_, is_all_signed, + is_component_signed); + } else { + is_all_signed = is_component_signed; + } + if (is_any_signed != spv::NoResult) { + is_any_signed = builder_->createBinOp(spv::OpLogicalOr, type_bool_, is_any_signed, + is_component_signed); + } else { + is_any_signed = is_component_signed; + } + } + } + spv::Id is_any_unsigned = + builder_->createUnaryOp(spv::OpLogicalNot, type_bool_, is_all_signed); + + // Load the fetch constant word 4, needed unconditionally for LOD + // biasing, for result exponent biasing, and conditionally for stacked + // texture filtering. + id_vector_temp_.clear(); + id_vector_temp_.push_back(const_int_0_); + id_vector_temp_.push_back( + builder_->makeIntConstant(int((fetch_constant_word_0_index + 4) >> 2))); + id_vector_temp_.push_back( + builder_->makeIntConstant(int((fetch_constant_word_0_index + 4) & 3))); + spv::Id fetch_constant_word_4 = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_fetch_constants_, + id_vector_temp_), + spv::NoPrecision); + spv::Id fetch_constant_word_4_signed = + builder_->createUnaryOp(spv::OpBitcast, type_int_, fetch_constant_word_4); + + // Accumulate the explicit LOD (or LOD bias) sources (in D3D11.3 + // specification order: specified LOD + sampler LOD bias + instruction + // LOD bias). + // Fetch constant LOD (bits 12:21 of the word 4). + spv::Id lod = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, + builder_->createUnaryOp( + spv::OpConvertSToF, type_float_, + builder_->createTriOp(spv::OpBitFieldSExtract, type_int_, + fetch_constant_word_4_signed, builder_->makeUintConstant(12), + builder_->makeUintConstant(10))), + builder_->makeFloatConstant(1.0f / 32.0f)); + // Register LOD. + if (instr.attributes.use_register_lod) { + lod = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, + builder_->createLoad(var_main_tfetch_lod_, spv::NoPrecision), lod); + } + // Instruction LOD bias. + if (instr.attributes.lod_bias) { + lod = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, lod, + builder_->makeFloatConstant(instr.attributes.lod_bias)); + } + + // Calculate the gradients for sampling the texture if needed. + // 2D vectors for k1D (because 1D images are emulated as 2D arrays), + // k2D. + // 3D vectors for k3DOrStacked, kCube. + spv::Id gradients_h = spv::NoResult, gradients_v = spv::NoResult; + if (use_computed_lod) { + // TODO(Triang3l): Gradient exponent adjustment is currently not done + // in getCompTexLOD, so not doing it here too for now. Apply the + // gradient exponent biases from the word 4 of the fetch constant in + // the future when it's handled in getCompTexLOD somehow. + spv::Id lod_gradient_scale = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450Exp2, lod); + switch (instr.dimension) { + case xenos::FetchOpDimension::k1D: { + spv::Id gradient_h_1d, gradient_v_1d; + if (instr.attributes.use_register_gradients) { + id_vector_temp_.clear(); + // First component. + id_vector_temp_.push_back(const_int_0_); + gradient_h_1d = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassFunction, + var_main_tfetch_gradients_h_, id_vector_temp_), + spv::NoPrecision); + gradient_v_1d = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassFunction, + var_main_tfetch_gradients_v_, id_vector_temp_), + spv::NoPrecision); + if (instr.attributes.unnormalized_coordinates) { + // Normalize the gradients. + assert_true(size[0] != spv::NoResult); + gradient_h_1d = builder_->createNoContractionBinOp(spv::OpFDiv, type_float_, + gradient_h_1d, size[0]); + gradient_v_1d = builder_->createNoContractionBinOp(spv::OpFDiv, type_float_, + gradient_v_1d, size[0]); + } + } else { + builder_->addCapability(spv::CapabilityDerivativeControl); + gradient_h_1d = + builder_->createUnaryOp(spv::OpDPdxCoarse, type_float_, coordinates[0]); + gradient_v_1d = + builder_->createUnaryOp(spv::OpDPdyCoarse, type_float_, coordinates[0]); + } + gradient_h_1d = builder_->createNoContractionBinOp(spv::OpFMul, type_float_, + gradient_h_1d, lod_gradient_scale); + gradient_v_1d = builder_->createNoContractionBinOp(spv::OpFMul, type_float_, + gradient_v_1d, lod_gradient_scale); + // 1D textures are sampled as 2D arrays - need 2-component + // gradients. + id_vector_temp_.clear(); + id_vector_temp_.push_back(gradient_h_1d); + id_vector_temp_.push_back(const_float_0_); + gradients_h = builder_->createCompositeConstruct(type_float2_, id_vector_temp_); + id_vector_temp_[0] = gradient_v_1d; + gradients_v = builder_->createCompositeConstruct(type_float2_, id_vector_temp_); + } break; + case xenos::FetchOpDimension::k2D: { + if (instr.attributes.use_register_gradients) { + for (uint32_t i = 0; i < 2; ++i) { + spv::Id register_gradient_3d = builder_->createLoad( + i ? var_main_tfetch_gradients_h_ : var_main_tfetch_gradients_v_, + spv::NoPrecision); + spv::Id register_gradient_x = + builder_->createCompositeExtract(register_gradient_3d, type_float_, 0); + spv::Id register_gradient_y = + builder_->createCompositeExtract(register_gradient_3d, type_float_, 1); + if (instr.attributes.unnormalized_coordinates) { + // Normalize the gradients. + assert_true(size[0] != spv::NoResult); + register_gradient_x = builder_->createNoContractionBinOp( + spv::OpFDiv, type_float_, register_gradient_x, size[0]); + assert_true(size[1] != spv::NoResult); + register_gradient_y = builder_->createNoContractionBinOp( + spv::OpFDiv, type_float_, register_gradient_y, size[1]); + } + id_vector_temp_.clear(); + id_vector_temp_.push_back(register_gradient_x); + id_vector_temp_.push_back(register_gradient_y); + (i ? gradients_v : gradients_h) = + builder_->createCompositeConstruct(type_float2_, id_vector_temp_); + } + } else { + id_vector_temp_.clear(); + for (uint32_t i = 0; i < 2; ++i) { + id_vector_temp_.push_back(coordinates[i]); + } + spv::Id gradient_coordinate_vector = + builder_->createCompositeConstruct(type_float2_, id_vector_temp_); + builder_->addCapability(spv::CapabilityDerivativeControl); + gradients_h = builder_->createUnaryOp(spv::OpDPdxCoarse, type_float2_, + gradient_coordinate_vector); + gradients_v = builder_->createUnaryOp(spv::OpDPdyCoarse, type_float2_, + gradient_coordinate_vector); + } + gradients_h = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float2_, gradients_h, lod_gradient_scale); + gradients_v = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float2_, gradients_v, lod_gradient_scale); + } break; + case xenos::FetchOpDimension::k3DOrStacked: { + if (instr.attributes.use_register_gradients) { + gradients_h = builder_->createLoad(var_main_tfetch_gradients_h_, spv::NoPrecision); + gradients_v = builder_->createLoad(var_main_tfetch_gradients_v_, spv::NoPrecision); + if (instr.attributes.unnormalized_coordinates) { + // Normalize the gradients. + for (uint32_t i = 0; i < 2; ++i) { + spv::Id& gradient_ref = i ? gradients_v : gradients_h; + id_vector_temp_.clear(); + for (uint32_t j = 0; j < 3; ++j) { + assert_true(size[j] != spv::NoResult); + id_vector_temp_.push_back(builder_->createNoContractionBinOp( + spv::OpFDiv, type_float_, + builder_->createCompositeExtract(gradient_ref, type_float_, j), size[j])); + } + gradient_ref = + builder_->createCompositeConstruct(type_float3_, id_vector_temp_); + } + } + } else { + id_vector_temp_.clear(); + for (uint32_t i = 0; i < 3; ++i) { + id_vector_temp_.push_back(coordinates[i]); + } + spv::Id gradient_coordinate_vector = + builder_->createCompositeConstruct(type_float3_, id_vector_temp_); + builder_->addCapability(spv::CapabilityDerivativeControl); + gradients_h = builder_->createUnaryOp(spv::OpDPdxCoarse, type_float3_, + gradient_coordinate_vector); + gradients_v = builder_->createUnaryOp(spv::OpDPdyCoarse, type_float3_, + gradient_coordinate_vector); + } + gradients_h = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float3_, gradients_h, lod_gradient_scale); + gradients_v = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float3_, gradients_v, lod_gradient_scale); + } break; + case xenos::FetchOpDimension::kCube: { + if (instr.attributes.use_register_gradients) { + // Register gradients are already in the cube space for cube + // maps. + // TODO(Triang3l): Are cube map register gradients unnormalized + // if the coordinates themselves are unnormalized? + gradients_h = builder_->createLoad(var_main_tfetch_gradients_h_, spv::NoPrecision); + gradients_v = builder_->createLoad(var_main_tfetch_gradients_v_, spv::NoPrecision); + } else { + id_vector_temp_.clear(); + for (uint32_t i = 0; i < 3; ++i) { + id_vector_temp_.push_back(coordinates[i]); + } + spv::Id gradient_coordinate_vector = + builder_->createCompositeConstruct(type_float3_, id_vector_temp_); + builder_->addCapability(spv::CapabilityDerivativeControl); + gradients_h = builder_->createUnaryOp(spv::OpDPdxCoarse, type_float3_, + gradient_coordinate_vector); + gradients_v = builder_->createUnaryOp(spv::OpDPdyCoarse, type_float3_, + gradient_coordinate_vector); + } + gradients_h = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float3_, gradients_h, lod_gradient_scale); + gradients_v = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float3_, gradients_v, lod_gradient_scale); + } break; + } + } + + // Sample the texture. + spv::ImageOperandsMask image_operands_mask = + use_computed_lod ? spv::ImageOperandsGradMask : spv::ImageOperandsLodMask; + spv::Id sample_result_unsigned, sample_result_signed; + if (!use_computed_lod) { + texture_parameters.lod = lod; + } + if (instr.dimension == xenos::FetchOpDimension::k3DOrStacked) { + // 3D (3 coordinate components, 3 gradient components, single fetch) + // or 2D stacked (2 coordinate components + 1 array layer coordinate + // component, 2 gradient components, two fetches if the Z axis is + // linear-filtered). + + assert_true(data_is_3d != spv::NoResult); + SpirvBuilder::IfBuilder if_data_is_3d(data_is_3d, spv::SelectionControlDontFlattenMask, + *builder_); + spv::Id sample_result_unsigned_3d, sample_result_signed_3d; + { + // 3D. + if (use_computed_lod) { + texture_parameters.gradX = gradients_h; + texture_parameters.gradY = gradients_v; + } + id_vector_temp_.clear(); + for (uint32_t i = 0; i < 3; ++i) { + id_vector_temp_.push_back(coordinates[i]); + } + texture_parameters.coords = + builder_->createCompositeConstruct(type_float3_, id_vector_temp_); + SampleTexture(texture_parameters, image_operands_mask, image_3d_unsigned, + image_3d_signed, sampler, is_any_unsigned, is_any_signed, + sample_result_unsigned_3d, sample_result_signed_3d); + } + if_data_is_3d.makeBeginElse(); + spv::Id sample_result_unsigned_stacked, sample_result_signed_stacked; + { + // 2D stacked. + if (use_computed_lod) { + // Extract 2D gradients for stacked textures which are 2D arrays. + uint_vector_temp_.clear(); + uint_vector_temp_.push_back(0); + uint_vector_temp_.push_back(1); + texture_parameters.gradX = builder_->createRvalueSwizzle( + spv::NoPrecision, type_float2_, gradients_h, uint_vector_temp_); + texture_parameters.gradY = builder_->createRvalueSwizzle( + spv::NoPrecision, type_float2_, gradients_v, uint_vector_temp_); + } + // Check if linear filtering is needed. + bool vol_mag_filter_is_fetch_const = + instr.attributes.vol_mag_filter == xenos::TextureFilter::kUseFetchConst; + bool vol_min_filter_is_fetch_const = + instr.attributes.vol_min_filter == xenos::TextureFilter::kUseFetchConst; + bool vol_mag_filter_is_linear = + instr.attributes.vol_mag_filter == xenos::TextureFilter::kLinear; + bool vol_min_filter_is_linear = + instr.attributes.vol_min_filter == xenos::TextureFilter::kLinear; + spv::Id vol_filter_is_linear = spv::NoResult; + if (use_computed_lod && + (vol_mag_filter_is_fetch_const || vol_min_filter_is_fetch_const || + vol_mag_filter_is_linear != vol_min_filter_is_linear)) { + // Check if minifying along layers (derivative > 1 along any + // axis). + spv::Id layer_max_gradient = builder_->createBinBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450NMax, + builder_->createCompositeExtract(gradients_h, type_float_, 2), + builder_->createCompositeExtract(gradients_v, type_float_, 2)); + if (!instr.attributes.unnormalized_coordinates) { + // Denormalize the gradient if provided as normalized. + assert_true(size[2] != spv::NoResult); + layer_max_gradient = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, layer_max_gradient, size[2]); + } + // For NaN, considering that magnification is being done. + spv::Id is_minifying_z = + builder_->createBinOp(spv::OpFOrdLessThan, type_bool_, layer_max_gradient, + builder_->makeFloatConstant(1.0f)); + // Choose what filter is actually used, the minification or the + // magnification one. + spv::Id vol_mag_filter_is_linear_loaded = + vol_mag_filter_is_fetch_const + ? builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, + fetch_constant_word_4, + builder_->makeUintConstant(UINT32_C(1) << 0)), + const_uint_0_) + : builder_->makeBoolConstant(vol_mag_filter_is_linear); + spv::Id vol_min_filter_is_linear_loaded = + vol_min_filter_is_fetch_const + ? builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, + fetch_constant_word_4, + builder_->makeUintConstant(UINT32_C(1) << 1)), + const_uint_0_) + : builder_->makeBoolConstant(vol_min_filter_is_linear); + vol_filter_is_linear = builder_->createTriOp( + spv::OpSelect, type_bool_, is_minifying_z, vol_min_filter_is_linear_loaded, + vol_mag_filter_is_linear_loaded); + } else { + // No gradients, or using the same filter overrides for magnifying + // and minifying. Assume always magnifying if no gradients (LOD 0, + // always <= 0). LOD is within 2D layers, not between them (unlike + // in 3D textures, which have mips with depth reduced), so it + // shouldn't have effect on filtering between layers. + if (vol_mag_filter_is_fetch_const) { + vol_filter_is_linear = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, fetch_constant_word_4, + builder_->makeUintConstant(UINT32_C(1) << 0)), + const_uint_0_); + } + } + spv::Id layer_coordinate = coordinates[2]; + // Linear filtering may be needed either based on a dynamic + // condition (the filtering mode is taken from the fetch constant, + // or it's different for magnification and minification), or on a + // static one (with gradients - specified in the instruction for + // both magnification and minification as linear, without + // gradients - specified for magnification as linear). + // If the filter is linear, subtract 0.5 from the Z coordinate of + // the first layer in filtering because 0.5 is in the middle of it. + if (vol_filter_is_linear != spv::NoResult) { + layer_coordinate = builder_->createTriOp( + spv::OpSelect, type_float_, vol_filter_is_linear, + builder_->createNoContractionBinOp(spv::OpFSub, type_float_, layer_coordinate, + builder_->makeFloatConstant(0.5f)), + layer_coordinate); + } else if (vol_mag_filter_is_linear) { + layer_coordinate = builder_->createNoContractionBinOp( + spv::OpFSub, type_float_, layer_coordinate, builder_->makeFloatConstant(0.5f)); + } + // Sample the first layer, needed regardless of whether filtering is + // needed. + // Floor the array layer (Vulkan does rounding to nearest or + 0.5 + // and floor even for the layer index, but on the Xenos, addressing + // is similar to that of 3D textures). This is needed for both point + // and linear filtering (with linear, 0.5 was subtracted + // previously). + spv::Id layer_0_coordinate = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450Floor, layer_coordinate); + id_vector_temp_.clear(); + id_vector_temp_.push_back(coordinates[0]); + id_vector_temp_.push_back(coordinates[1]); + id_vector_temp_.push_back(layer_0_coordinate); + texture_parameters.coords = + builder_->createCompositeConstruct(type_float3_, id_vector_temp_); + SampleTexture(texture_parameters, image_operands_mask, image_2d_array_or_cube_unsigned, + image_2d_array_or_cube_signed, sampler, is_any_unsigned, is_any_signed, + sample_result_unsigned_stacked, sample_result_signed_stacked); + // Sample the second layer if linear filtering is potentially needed + // (conditionally or unconditionally, depending on whether the + // filter needs to be chosen at runtime), and filter. + if (vol_filter_is_linear != spv::NoResult || vol_mag_filter_is_linear) { + spv::Block& block_z_head = *builder_->getBuildPoint(); + spv::Block& block_z_linear = + (vol_filter_is_linear != spv::NoResult) ? builder_->makeNewBlock() : block_z_head; + spv::Block& block_z_merge = + (vol_filter_is_linear != spv::NoResult) ? builder_->makeNewBlock() : block_z_head; + if (vol_filter_is_linear != spv::NoResult) { + builder_->createSelectionMerge(&block_z_merge, + spv::SelectionControlDontFlattenMask); + builder_->createConditionalBranch(vol_filter_is_linear, &block_z_linear, + &block_z_merge); + builder_->setBuildPoint(&block_z_linear); + } + spv::Id layer_1_coordinate = builder_->createBinOp( + spv::OpFAdd, type_float_, layer_0_coordinate, builder_->makeFloatConstant(1.0f)); + id_vector_temp_.clear(); + id_vector_temp_.push_back(coordinates[0]); + id_vector_temp_.push_back(coordinates[1]); + id_vector_temp_.push_back(layer_1_coordinate); + texture_parameters.coords = + builder_->createCompositeConstruct(type_float3_, id_vector_temp_); + spv::Id layer_lerp_factor = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450Fract, layer_coordinate); + spv::Id sample_result_unsigned_stacked_filtered; + spv::Id sample_result_signed_stacked_filtered; + SampleTexture(texture_parameters, image_operands_mask, + image_2d_array_or_cube_unsigned, image_2d_array_or_cube_signed, sampler, + is_any_unsigned, is_any_signed, sample_result_unsigned_stacked_filtered, + sample_result_signed_stacked_filtered, layer_lerp_factor, + sample_result_unsigned_stacked, sample_result_signed_stacked); + if (vol_filter_is_linear != spv::NoResult) { + // Get the actual build point after the SampleTexture call for + // phi. + spv::Block& block_z_linear_end = *builder_->getBuildPoint(); + builder_->createBranch(&block_z_merge); + builder_->setBuildPoint(&block_z_merge); + { + std::unique_ptr filter_phi_op = + std::make_unique(builder_->getUniqueId(), type_float4_, + spv::OpPhi); + filter_phi_op->addIdOperand(sample_result_unsigned_stacked_filtered); + filter_phi_op->addIdOperand(block_z_linear_end.getId()); + filter_phi_op->addIdOperand(sample_result_unsigned_stacked); + filter_phi_op->addIdOperand(block_z_head.getId()); + sample_result_unsigned_stacked = filter_phi_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(filter_phi_op)); + } + { + std::unique_ptr filter_phi_op = + std::make_unique(builder_->getUniqueId(), type_float4_, + spv::OpPhi); + filter_phi_op->addIdOperand(sample_result_signed_stacked_filtered); + filter_phi_op->addIdOperand(block_z_linear_end.getId()); + filter_phi_op->addIdOperand(sample_result_signed_stacked); + filter_phi_op->addIdOperand(block_z_head.getId()); + sample_result_signed_stacked = filter_phi_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(filter_phi_op)); + } + } else { + sample_result_unsigned_stacked = sample_result_unsigned_stacked_filtered; + sample_result_signed_stacked = sample_result_signed_stacked_filtered; + } + } + } + if_data_is_3d.makeEndIf(); + + sample_result_unsigned = if_data_is_3d.createMergePhi(sample_result_unsigned_3d, + sample_result_unsigned_stacked); + sample_result_signed = + if_data_is_3d.createMergePhi(sample_result_signed_3d, sample_result_signed_stacked); + } else { + if (use_computed_lod) { + texture_parameters.gradX = gradients_h; + texture_parameters.gradY = gradients_v; + } + id_vector_temp_.clear(); + for (uint32_t i = 0; i < 3; ++i) { + id_vector_temp_.push_back(coordinates[i]); + } + texture_parameters.coords = + builder_->createCompositeConstruct(type_float3_, id_vector_temp_); + SampleTexture(texture_parameters, image_operands_mask, image_2d_array_or_cube_unsigned, + image_2d_array_or_cube_signed, sampler, is_any_unsigned, is_any_signed, + sample_result_unsigned, sample_result_signed); + } + + // Swizzle the result components manually if needed, to `result`. + // Because the same host format component may be replicated into + // multiple guest components (such as for formats with less than 4 + // components), yet the signedness is per-guest-component, it's not + // possible to apply the signedness to host components before swizzling, + // so doing it during (for unsigned vs. signed) and after (for biased + // and gamma) swizzling. + if (!features_.image_view_format_swizzle) { + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantTextureSwizzles)); + id_vector_temp_.push_back(builder_->makeIntConstant(fetch_constant_index >> 3)); + id_vector_temp_.push_back(builder_->makeIntConstant((fetch_constant_index >> 1) & 3)); + // All 32 bits containing the values (24 bits) for 2 fetch constants. + spv::Id swizzle_word = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + uint32_t swizzle_word_offset = 3 * 4 * (fetch_constant_index & 1); + spv::Id const_float_1 = builder_->makeFloatConstant(1.0f); + uint32_t result_remaining_components = used_result_nonzero_components; + uint32_t result_component_index; + while (rex::bit_scan_forward(result_remaining_components, &result_component_index)) { + result_remaining_components &= ~(UINT32_C(1) << result_component_index); + uint32_t swizzle_bit_0_value = UINT32_C(1) + << (swizzle_word_offset + 3 * result_component_index); + spv::Id swizzle_bit_0 = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, swizzle_word, + builder_->makeUintConstant(swizzle_bit_0_value)), + const_uint_0_); + // Bit 2 - X/Y/Z/W or 0/1. + spv::Id swizzle_bit_2 = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, swizzle_word, + builder_->makeUintConstant(swizzle_bit_0_value << 2)), + const_uint_0_); + SpirvBuilder::IfBuilder if_swizzle_constant( + swizzle_bit_2, spv::SelectionControlDontFlattenMask, *builder_); + spv::Id swizzle_result_constant; + { + // Constant values. + // Bit 0 - 0 or 1. + swizzle_result_constant = builder_->createTriOp( + spv::OpSelect, type_float_, swizzle_bit_0, const_float_1, const_float_0_); + } + if_swizzle_constant.makeBeginElse(); + spv::Id swizzle_result_component; + { + // Fetched components. + // Select whether the result is signed or unsigned (or biased or + // gamma-corrected) based on the post-swizzle signedness. + spv::Id swizzle_sample_result = builder_->createTriOp( + spv::OpSelect, type_float4_, + builder_->smearScalar(spv::NoPrecision, result_is_signed[result_component_index], + type_bool4_), + sample_result_signed, sample_result_unsigned); + // Bit 0 - X or Y, Z or W, 0 or 1. + spv::Id swizzle_x_or_y = builder_->createTriOp( + spv::OpSelect, type_float_, swizzle_bit_0, + builder_->createCompositeExtract(swizzle_sample_result, type_float_, 1), + builder_->createCompositeExtract(swizzle_sample_result, type_float_, 0)); + spv::Id swizzle_z_or_w = builder_->createTriOp( + spv::OpSelect, type_float_, swizzle_bit_0, + builder_->createCompositeExtract(swizzle_sample_result, type_float_, 3), + builder_->createCompositeExtract(swizzle_sample_result, type_float_, 2)); + // Bit 1 - X/Y or Z/W. + spv::Id swizzle_bit_1 = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, swizzle_word, + builder_->makeUintConstant(swizzle_bit_0_value << 1)), + const_uint_0_); + swizzle_result_component = builder_->createTriOp( + spv::OpSelect, type_float_, swizzle_bit_1, swizzle_z_or_w, swizzle_x_or_y); + } + if_swizzle_constant.makeEndIf(); + // Select between the constants and the fetched components. + result[result_component_index] = if_swizzle_constant.createMergePhi( + swizzle_result_constant, swizzle_result_component); + } + } + + // Apply the signednesses to all the needed components. If swizzling is + // done in the shader rather than via the image view, unsigned or signed + // source has already been selected into `result` - only need to bias or + // to gamma-correct. + spv::Id const_float_2 = builder_->makeFloatConstant(2.0f); + spv::Id const_float_minus_1 = builder_->makeFloatConstant(-1.0f); + { + uint32_t result_remaining_components = used_result_nonzero_components; + uint32_t result_component_index; + while (rex::bit_scan_forward(result_remaining_components, &result_component_index)) { + result_remaining_components &= ~(UINT32_C(1) << result_component_index); + spv::Id sample_result_component_unsigned = + features_.image_view_format_swizzle + ? builder_->createCompositeExtract(sample_result_unsigned, type_float_, + result_component_index) + : result[result_component_index]; + spv::Block& block_sign_head = *builder_->getBuildPoint(); + spv::Block* block_sign_signed = + features_.image_view_format_swizzle ? &builder_->makeNewBlock() : nullptr; + spv::Block& block_sign_unsigned_biased = builder_->makeNewBlock(); + spv::Block& block_sign_gamma_start = builder_->makeNewBlock(); + spv::Block& block_sign_merge = builder_->makeNewBlock(); + builder_->createSelectionMerge(&block_sign_merge, spv::SelectionControlDontFlattenMask); + { + std::unique_ptr sign_switch_op = + std::make_unique(spv::OpSwitch); + sign_switch_op->addIdOperand(swizzled_signs[result_component_index]); + // Make unsigned (do nothing, take the unsigned component in the + // phi) the default, and also, if unsigned or signed has already + // been selected in swizzling, make signed the default to since + // it, just like unsigned, doesn't need any transformations. + sign_switch_op->addIdOperand(block_sign_merge.getId()); + if (block_sign_signed) { + sign_switch_op->addImmediateOperand(uint32_t(xenos::TextureSign::kSigned)); + sign_switch_op->addIdOperand(block_sign_signed->getId()); + } + sign_switch_op->addImmediateOperand(uint32_t(xenos::TextureSign::kUnsignedBiased)); + sign_switch_op->addIdOperand(block_sign_unsigned_biased.getId()); + sign_switch_op->addImmediateOperand(uint32_t(xenos::TextureSign::kGamma)); + sign_switch_op->addIdOperand(block_sign_gamma_start.getId()); + builder_->getBuildPoint()->addInstruction(std::move(sign_switch_op)); + } + if (block_sign_signed) { + block_sign_signed->addPredecessor(&block_sign_head); + } + block_sign_unsigned_biased.addPredecessor(&block_sign_head); + block_sign_gamma_start.addPredecessor(&block_sign_head); + block_sign_merge.addPredecessor(&block_sign_head); + // Signed. + spv::Id sample_result_component_signed = sample_result_component_unsigned; + if (block_sign_signed) { + builder_->setBuildPoint(block_sign_signed); + sample_result_component_signed = builder_->createCompositeExtract( + sample_result_signed, type_float_, result_component_index); + builder_->createBranch(&block_sign_merge); + } + // Unsigned biased. + builder_->setBuildPoint(&block_sign_unsigned_biased); + spv::Id sample_result_component_unsigned_biased = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, sample_result_component_unsigned, const_float_2); + sample_result_component_unsigned_biased = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, sample_result_component_unsigned_biased, + const_float_minus_1); + builder_->createBranch(&block_sign_merge); + // Gamma. + builder_->setBuildPoint(&block_sign_gamma_start); + // Keep parity with D3D12 by applying explicit Xenos PWL + // gamma-to-linear conversion in shader code rather than relying on + // host sRGB sampling semantics. + spv::Id sample_result_component_gamma = + PWLGammaToLinear(sample_result_component_unsigned, false); + // Get the current build point for the phi operation not to assume + // that it will be the same as before PWLGammaToLinear. + spv::Block& block_sign_gamma_end = *builder_->getBuildPoint(); + builder_->createBranch(&block_sign_merge); + // Merge. + builder_->setBuildPoint(&block_sign_merge); + { + std::unique_ptr sign_phi_op = std::make_unique( + builder_->getUniqueId(), type_float_, spv::OpPhi); + if (block_sign_signed) { + sign_phi_op->addIdOperand(sample_result_component_signed); + sign_phi_op->addIdOperand(block_sign_signed->getId()); + } + sign_phi_op->addIdOperand(sample_result_component_unsigned_biased); + sign_phi_op->addIdOperand(block_sign_unsigned_biased.getId()); + sign_phi_op->addIdOperand(sample_result_component_gamma); + sign_phi_op->addIdOperand(block_sign_gamma_end.getId()); + sign_phi_op->addIdOperand(sample_result_component_unsigned); + sign_phi_op->addIdOperand(block_sign_head.getId()); + result[result_component_index] = sign_phi_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(sign_phi_op)); + } + } + } + + // Apply the exponent bias from the bits 13:18 of the fetch constant + // word 4. + spv::Id result_exponent_bias = builder_->createBinBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450Ldexp, const_float_1_, + builder_->createTriOp(spv::OpBitFieldSExtract, type_int_, fetch_constant_word_4_signed, + builder_->makeUintConstant(13), builder_->makeUintConstant(6))); + { + uint32_t result_remaining_components = used_result_nonzero_components; + uint32_t result_component_index; + while (rex::bit_scan_forward(result_remaining_components, &result_component_index)) { + result_remaining_components &= ~(UINT32_C(1) << result_component_index); + result[result_component_index] = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, result[result_component_index], result_exponent_bias); + } + } + } + } + } + + // Store the needed components of the result. + spv::Id result_vector; + if (used_result_component_count > 1) { + id_vector_temp_.clear(); + uint32_t result_components_remaining = used_result_components; + uint32_t result_component_index; + while (rex::bit_scan_forward(result_components_remaining, &result_component_index)) { + result_components_remaining &= ~(UINT32_C(1) << result_component_index); + id_vector_temp_.push_back(result[result_component_index]); + } + result_vector = builder_->createCompositeConstruct( + type_float_vectors_[used_result_component_count - 1], id_vector_temp_); + } else { + uint32_t result_component_index; + rex::bit_scan_forward(used_result_components, &result_component_index); + result_vector = result[result_component_index]; + } + StoreResult(instr.result, result_vector); +} + +size_t SpirvShaderTranslator::FindOrAddTextureBinding(uint32_t fetch_constant, + xenos::FetchOpDimension dimension, + bool is_signed) { + // 1D and 2D textures (including stacked ones) are treated as 2D arrays for + // binding and coordinate simplicity. + if (dimension == xenos::FetchOpDimension::k1D) { + dimension = xenos::FetchOpDimension::k2D; + } + for (size_t i = 0; i < texture_bindings_.size(); ++i) { + const TextureBinding& texture_binding = texture_bindings_[i]; + if (texture_binding.fetch_constant == fetch_constant && + texture_binding.dimension == dimension && texture_binding.is_signed == is_signed) { + return i; + } + } + // TODO(Triang3l): Limit the total count to that actually supported by the + // implementation. + size_t new_texture_binding_index = texture_bindings_.size(); + TextureBinding& new_texture_binding = texture_bindings_.emplace_back(); + new_texture_binding.fetch_constant = fetch_constant; + new_texture_binding.dimension = dimension; + new_texture_binding.is_signed = is_signed; + spv::Dim type_dimension; + bool is_array; + const char* dimension_name; + switch (dimension) { + case xenos::FetchOpDimension::k3DOrStacked: + type_dimension = spv::Dim3D; + is_array = false; + dimension_name = "3d"; + break; + case xenos::FetchOpDimension::kCube: + type_dimension = spv::DimCube; + is_array = false; + dimension_name = "cube"; + break; + default: + type_dimension = spv::Dim2D; + is_array = true; + dimension_name = "2d"; + } + new_texture_binding.variable = builder_->createVariable( + spv::NoPrecision, spv::StorageClassUniformConstant, + builder_->makeImageType(type_float_, type_dimension, false, is_array, false, 1, + spv::ImageFormatUnknown), + fmt::format("xe_texture{}_{}_{}", fetch_constant, dimension_name, is_signed ? 's' : 'u') + .c_str()); + builder_->addDecoration( + new_texture_binding.variable, spv::DecorationDescriptorSet, + int(is_vertex_shader() ? kDescriptorSetTexturesVertex : kDescriptorSetTexturesPixel)); + builder_->addDecoration(new_texture_binding.variable, spv::DecorationBinding, + int(new_texture_binding_index)); + if (features_.spirv_version >= spv::Spv_1_4) { + main_interface_.push_back(new_texture_binding.variable); + } + return new_texture_binding_index; +} + +size_t SpirvShaderTranslator::FindOrAddSamplerBinding(uint32_t fetch_constant, + xenos::TextureFilter mag_filter, + xenos::TextureFilter min_filter, + xenos::TextureFilter mip_filter, + xenos::AnisoFilter aniso_filter) { + if (aniso_filter != xenos::AnisoFilter::kUseFetchConst) { + // TODO(Triang3l): Limit to what's actually supported by the implementation. + aniso_filter = std::min(aniso_filter, xenos::AnisoFilter::kMax_16_1); + } + for (size_t i = 0; i < sampler_bindings_.size(); ++i) { + const SamplerBinding& sampler_binding = sampler_bindings_[i]; + if (sampler_binding.fetch_constant == fetch_constant && + sampler_binding.mag_filter == mag_filter && sampler_binding.min_filter == min_filter && + sampler_binding.mip_filter == mip_filter && sampler_binding.aniso_filter == aniso_filter) { + return i; + } + } + // TODO(Triang3l): Limit the total count to that actually supported by the + // implementation. + size_t new_sampler_binding_index = sampler_bindings_.size(); + SamplerBinding& new_sampler_binding = sampler_bindings_.emplace_back(); + new_sampler_binding.fetch_constant = fetch_constant; + new_sampler_binding.mag_filter = mag_filter; + new_sampler_binding.min_filter = min_filter; + new_sampler_binding.mip_filter = mip_filter; + new_sampler_binding.aniso_filter = aniso_filter; + std::ostringstream name; + static const char kFilterSuffixes[] = {'p', 'l', 'b', 'f'}; + name << "xe_sampler" << fetch_constant << '_' << kFilterSuffixes[uint32_t(mag_filter)] + << kFilterSuffixes[uint32_t(min_filter)] << kFilterSuffixes[uint32_t(mip_filter)]; + if (aniso_filter != xenos::AnisoFilter::kUseFetchConst) { + if (aniso_filter == xenos::AnisoFilter::kDisabled) { + name << "_a0"; + } else { + name << "_a" << (UINT32_C(1) << (uint32_t(aniso_filter) - 1)); + } + } + new_sampler_binding.variable = + builder_->createVariable(spv::NoPrecision, spv::StorageClassUniformConstant, + builder_->makeSamplerType(), name.str().c_str()); + builder_->addDecoration( + new_sampler_binding.variable, spv::DecorationDescriptorSet, + int(is_vertex_shader() ? kDescriptorSetTexturesVertex : kDescriptorSetTexturesPixel)); + // The binding indices will be specified later after all textures are added as + // samplers are located after images in the descriptor set. + if (features_.spirv_version >= spv::Spv_1_4) { + main_interface_.push_back(new_sampler_binding.variable); + } + return new_sampler_binding_index; +} + +void SpirvShaderTranslator::SampleTexture(spv::Builder::TextureParameters& texture_parameters, + spv::ImageOperandsMask image_operands_mask, + spv::Id image_unsigned, spv::Id image_signed, + spv::Id sampler, spv::Id is_any_unsigned, + spv::Id is_any_signed, spv::Id& result_unsigned_out, + spv::Id& result_signed_out, spv::Id lerp_factor, + spv::Id lerp_first_unsigned, spv::Id lerp_first_signed) { + for (uint32_t i = 0; i < 2; ++i) { + SpirvBuilder::IfBuilder sign_if(i ? is_any_signed : is_any_unsigned, + spv::SelectionControlDontFlattenMask, *builder_); + spv::Id sign_result; + { + spv::Id image = i ? image_signed : image_unsigned; + // OpSampledImage must be in the same block as where its result is used. + texture_parameters.sampler = builder_->createBinOp( + spv::OpSampledImage, builder_->makeSampledImageType(builder_->getTypeId(image)), image, + sampler); + sign_result = + builder_->createTextureCall(spv::NoPrecision, type_float4_, false, false, false, false, + false, texture_parameters, image_operands_mask); + if (lerp_factor != spv::NoResult) { + spv::Id lerp_first = i ? lerp_first_signed : lerp_first_unsigned; + if (lerp_first != spv::NoResult) { + spv::Id lerp_difference = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float4_, + builder_->createNoContractionBinOp(spv::OpFSub, type_float4_, sign_result, + lerp_first), + lerp_factor); + sign_result = builder_->createNoContractionBinOp(spv::OpFAdd, type_float4_, sign_result, + lerp_difference); + } + } + } + sign_if.makeEndIf(); + // This may overwrite the first lerp endpoint for the sign (such usage of + // this function is allowed). + (i ? result_signed_out : result_unsigned_out) = + sign_if.createMergePhi(sign_result, const_float4_0_); + } +} + +spv::Id SpirvShaderTranslator::QueryTextureLod(spv::Builder::TextureParameters& texture_parameters, + spv::Id image_unsigned, spv::Id image_signed, + spv::Id sampler, spv::Id is_all_signed) { + // OpSampledImage must be in the same block as where its result is used. + SpirvBuilder::IfBuilder if_signed(is_all_signed, spv::SelectionControlDontFlattenMask, *builder_); + spv::Id lod_signed; + { + texture_parameters.sampler = builder_->createBinOp( + spv::OpSampledImage, builder_->makeSampledImageType(builder_->getTypeId(image_signed)), + image_signed, sampler); + lod_signed = builder_->createCompositeExtract( + builder_->createTextureQueryCall(spv::OpImageQueryLod, texture_parameters, false), + type_float_, 1); + } + if_signed.makeBeginElse(); + spv::Id lod_unsigned; + { + texture_parameters.sampler = builder_->createBinOp( + spv::OpSampledImage, builder_->makeSampledImageType(builder_->getTypeId(image_unsigned)), + image_unsigned, sampler); + lod_unsigned = builder_->createCompositeExtract( + builder_->createTextureQueryCall(spv::OpImageQueryLod, texture_parameters, false), + type_float_, 1); + } + if_signed.makeEndIf(); + return if_signed.createMergePhi(lod_signed, lod_unsigned); +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/shader/spirv_translator_memexport.cpp b/src/graphics/pipeline/shader/spirv_translator_memexport.cpp new file mode 100644 index 0000000..14c0ea9 --- /dev/null +++ b/src/graphics/pipeline/shader/spirv_translator_memexport.cpp @@ -0,0 +1,853 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2024 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +namespace rex::graphics { + +void SpirvShaderTranslator::ExportToMemory(uint8_t export_eM) { + if (!export_eM) { + return; + } + + assert_zero(export_eM & ~current_shader().memexport_eM_written()); + + if (!IsMemoryExportSupported()) { + return; + } + + // Check if memory export is allowed in this guest shader invocation. + std::optional if_memexport_allowed; + if (main_memexport_allowed_ != spv::NoResult) { + if_memexport_allowed.emplace(main_memexport_allowed_, spv::SelectionControlDontFlattenMask, + *builder_); + } + + // If the pixel was killed (but the actual killing on the SPIR-V side has not + // been performed yet because the device doesn't support demotion to helper + // invocation that doesn't interfere with control flow), the current + // invocation is not considered active anymore. + std::optional if_pixel_not_killed; + if (var_main_kill_pixel_ != spv::NoResult) { + if_pixel_not_killed.emplace( + builder_->createUnaryOp(spv::OpLogicalNot, type_bool_, + builder_->createLoad(var_main_kill_pixel_, spv::NoPrecision)), + spv::SelectionControlDontFlattenMask, *builder_); + } + + // Check if the address with the correct sign and exponent was written, and + // that the index doesn't overflow the mantissa bits. + // all((eA_vector >> uvec4(30, 23, 23, 23)) == uvec4(0x1, 0x96, 0x96, 0x96)) + spv::Id eA_vector = + builder_->createUnaryOp(spv::OpBitcast, type_uint4_, + builder_->createLoad(var_main_memexport_address_, spv::NoPrecision)); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeUintConstant(30)); + id_vector_temp_.push_back(builder_->makeUintConstant(23)); + id_vector_temp_.push_back(id_vector_temp_.back()); + id_vector_temp_.push_back(id_vector_temp_.back()); + spv::Id address_validation_shift = builder_->makeCompositeConstant(type_uint4_, id_vector_temp_); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeUintConstant(0x1)); + id_vector_temp_.push_back(builder_->makeUintConstant(0x96)); + id_vector_temp_.push_back(id_vector_temp_.back()); + id_vector_temp_.push_back(id_vector_temp_.back()); + spv::Id address_validation_value = builder_->makeCompositeConstant(type_uint4_, id_vector_temp_); + SpirvBuilder::IfBuilder if_address_valid( + builder_->createUnaryOp( + spv::OpAll, type_bool_, + builder_->createBinOp(spv::OpIEqual, type_bool4_, + builder_->createBinOp(spv::OpShiftRightLogical, type_uint4_, + eA_vector, address_validation_shift), + address_validation_value)), + spv::SelectionControlDontFlattenMask, *builder_, 2, 1); + + using EMIdArray = std::array; + + auto for_each_eM = [&](std::function fn) { + uint8_t eM_remaining = export_eM; + uint32_t eM_index; + while (rex::bit_scan_forward(eM_remaining, &eM_index)) { + eM_remaining &= ~(uint8_t(1) << eM_index); + fn(eM_index); + } + }; + + // Load the original eM. + EMIdArray eM_original; + for_each_eM([&](uint32_t eM_index) { + eM_original[eM_index] = + builder_->createLoad(var_main_memexport_data_[eM_index], spv::NoPrecision); + }); + + // Swap red and blue if needed. + spv::Id format_info = builder_->createCompositeExtract(eA_vector, type_uint_, 2); + spv::Id swap_red_blue = + builder_->createBinOp(spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, format_info, + builder_->makeUintConstant(uint32_t(1) << 19)), + const_uint_0_); + EMIdArray eM_swapped; + uint_vector_temp_.clear(); + uint_vector_temp_.push_back(2); + uint_vector_temp_.push_back(1); + uint_vector_temp_.push_back(0); + uint_vector_temp_.push_back(3); + for_each_eM([&](uint32_t eM_index) { + eM_swapped[eM_index] = builder_->createTriOp( + spv::OpSelect, type_float4_, swap_red_blue, + builder_->createRvalueSwizzle(spv::NoPrecision, type_float4_, eM_original[eM_index], + uint_vector_temp_), + eM_original[eM_index]); + }); + + // Extract the numeric format. + spv::Id is_signed = + builder_->createBinOp(spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, format_info, + builder_->makeUintConstant(uint32_t(1) << 16)), + const_uint_0_); + spv::Id is_norm = + builder_->createBinOp(spv::OpIEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, format_info, + builder_->makeUintConstant(uint32_t(1) << 17)), + const_uint_0_); + + // Perform format packing. + + auto flush_nan = [&](const EMIdArray& eM) -> EMIdArray { + EMIdArray eM_flushed; + for_each_eM([&](uint32_t eM_index) { + spv::Id element_unflushed = eM[eM_index]; + unsigned int component_count = builder_->getNumComponents(element_unflushed); + eM_flushed[eM_index] = builder_->createTriOp( + spv::OpSelect, type_float_vectors_[component_count - 1], + builder_->createUnaryOp(spv::OpIsNan, type_bool_vectors_[component_count - 1], + element_unflushed), + const_float_vectors_0_[component_count - 1], element_unflushed); + }); + return eM_flushed; + }; + + auto make_float_constant_vectors = [&](float value) -> std::array { + std::array const_vectors; + const_vectors[0] = builder_->makeFloatConstant(value); + id_vector_temp_.clear(); + id_vector_temp_.push_back(const_vectors[0]); + for (unsigned int component_count_minus_1 = 1; component_count_minus_1 < 4; + ++component_count_minus_1) { + id_vector_temp_.push_back(const_vectors[0]); + const_vectors[component_count_minus_1] = builder_->makeCompositeConstant( + type_float_vectors_[component_count_minus_1], id_vector_temp_); + } + return const_vectors; + }; + std::array const_float_vectors_minus_1 = make_float_constant_vectors(-1.0f); + std::array const_float_vectors_minus_0_5 = make_float_constant_vectors(-0.5f); + std::array const_float_vectors_0_5 = make_float_constant_vectors(0.5f); + + // The widths must be without holes (R, RG, RGB, RGBA), and expecting the + // widths to add up to the size of the stored texel (8, 16 or 32 bits), as the + // unused upper bits will contain junk from the sign extension of X if the + // number is signed. + auto pack_8_16_32 = [&](std::array widths) -> EMIdArray { + unsigned int component_count; + std::array offsets{}; + for (component_count = 0; component_count < widths.size(); ++component_count) { + if (!widths[component_count]) { + break; + } + // Only formats for which max + 0.5 can be represented exactly. + assert(widths[component_count] <= 23); + if (component_count) { + offsets[component_count] = offsets[component_count - 1] + widths[component_count - 1]; + } + } + assert_not_zero(component_count); + + // Extract the needed components. + EMIdArray eM_unflushed = eM_swapped; + if (component_count < 4) { + if (component_count == 1) { + for_each_eM([&](uint32_t eM_index) { + eM_unflushed[eM_index] = + builder_->createCompositeExtract(eM_unflushed[eM_index], type_float_, 0); + }); + } else { + uint_vector_temp_.clear(); + for (unsigned int component_index = 0; component_index < component_count; + ++component_index) { + uint_vector_temp_.push_back(component_index); + } + for_each_eM([&](uint32_t eM_index) { + eM_unflushed[eM_index] = builder_->createRvalueSwizzle( + spv::NoPrecision, type_float_vectors_[component_count - 1], eM_unflushed[eM_index], + uint_vector_temp_); + }); + } + } + + // Flush NaNs. + EMIdArray eM_flushed = flush_nan(eM_unflushed); + + // Convert to integers. + SpirvBuilder::IfBuilder if_signed(is_signed, spv::SelectionControlDontFlattenMask, *builder_); + EMIdArray eM_signed; + { + // Signed. + SpirvBuilder::IfBuilder if_norm(is_norm, spv::SelectionControlDontFlattenMask, *builder_); + EMIdArray eM_norm; + { + // Signed normalized. + id_vector_temp_.clear(); + for (unsigned int component_index = 0; component_index < component_count; + ++component_index) { + id_vector_temp_.push_back(builder_->makeFloatConstant( + float((uint32_t(1) << (widths[component_index] - 1)) - 1))); + } + spv::Id const_max_value = + component_count > 1 ? builder_->makeCompositeConstant( + type_float_vectors_[component_count - 1], id_vector_temp_) + : id_vector_temp_.front(); + for_each_eM([&](uint32_t eM_index) { + eM_norm[eM_index] = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_vectors_[component_count - 1], + builder_->createTriBuiltinCall(type_float_vectors_[component_count - 1], + ext_inst_glsl_std_450_, GLSLstd450FClamp, + eM_flushed[eM_index], + const_float_vectors_minus_1[component_count - 1], + const_float_vectors_1_[component_count - 1]), + const_max_value); + }); + } + if_norm.makeEndIf(); + // All phi instructions must be in the beginning of the block. + for_each_eM([&](uint32_t eM_index) { + eM_signed[eM_index] = if_norm.createMergePhi(eM_norm[eM_index], eM_flushed[eM_index]); + }); + // Convert to signed integer, adding plus/minus 0.5 before truncating + // according to the Direct3D format conversion rules. + for_each_eM([&](uint32_t eM_index) { + eM_signed[eM_index] = builder_->createUnaryOp( + spv::OpBitcast, type_uint_vectors_[component_count - 1], + builder_->createUnaryOp( + spv::OpConvertFToS, type_int_vectors_[component_count - 1], + builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_vectors_[component_count - 1], eM_signed[eM_index], + builder_->createTriOp( + spv::OpSelect, type_float_vectors_[component_count - 1], + builder_->createBinOp( + spv::OpFOrdLessThan, type_bool_vectors_[component_count - 1], + eM_signed[eM_index], const_float_vectors_0_[component_count - 1]), + const_float_vectors_minus_0_5[component_count - 1], + const_float_vectors_0_5[component_count - 1])))); + }); + } + if_signed.makeBeginElse(); + EMIdArray eM_unsigned; + { + SpirvBuilder::IfBuilder if_norm(is_norm, spv::SelectionControlDontFlattenMask, *builder_); + EMIdArray eM_norm; + { + // Unsigned normalized. + id_vector_temp_.clear(); + for (unsigned int component_index = 0; component_index < component_count; + ++component_index) { + id_vector_temp_.push_back( + builder_->makeFloatConstant(float((uint32_t(1) << widths[component_index]) - 1))); + } + spv::Id const_max_value = + component_count > 1 ? builder_->makeCompositeConstant( + type_float_vectors_[component_count - 1], id_vector_temp_) + : id_vector_temp_.front(); + for_each_eM([&](uint32_t eM_index) { + eM_norm[eM_index] = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_vectors_[component_count - 1], + builder_->createTriBuiltinCall(type_float_vectors_[component_count - 1], + ext_inst_glsl_std_450_, GLSLstd450FClamp, + eM_flushed[eM_index], + const_float_vectors_0_[component_count - 1], + const_float_vectors_1_[component_count - 1]), + const_max_value); + }); + } + if_norm.makeEndIf(); + // All phi instructions must be in the beginning of the block. + for_each_eM([&](uint32_t eM_index) { + eM_unsigned[eM_index] = if_norm.createMergePhi(eM_norm[eM_index], eM_flushed[eM_index]); + }); + // Convert to unsigned integer, adding 0.5 before truncating according to + // the Direct3D format conversion rules. + for_each_eM([&](uint32_t eM_index) { + eM_unsigned[eM_index] = builder_->createUnaryOp( + spv::OpConvertFToU, type_uint_vectors_[component_count - 1], + builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_vectors_[component_count - 1], eM_unsigned[eM_index], + const_float_vectors_0_5[component_count - 1])); + }); + } + if_signed.makeEndIf(); + EMIdArray eM_unpacked; + for_each_eM([&](uint32_t eM_index) { + eM_unpacked[eM_index] = if_signed.createMergePhi(eM_signed[eM_index], eM_unsigned[eM_index]); + }); + + // Pack into a 32-bit value, and pad to a 4-component vector for the phi. + EMIdArray eM_packed; + for_each_eM([&](uint32_t eM_index) { + spv::Id element_unpacked = eM_unpacked[eM_index]; + eM_packed[eM_index] = component_count > 1 + ? builder_->createCompositeExtract(element_unpacked, type_uint_, 0) + : element_unpacked; + for (unsigned int component_index = 1; component_index < component_count; ++component_index) { + eM_packed[eM_index] = builder_->createQuadOp( + spv::OpBitFieldInsert, type_uint_, eM_packed[eM_index], + builder_->createCompositeExtract(element_unpacked, type_uint_, component_index), + builder_->makeUintConstant(offsets[component_index]), + builder_->makeUintConstant(widths[component_index])); + } + id_vector_temp_.clear(); + id_vector_temp_.resize(4, const_uint_0_); + id_vector_temp_.front() = eM_packed[eM_index]; + eM_packed[eM_index] = builder_->createCompositeConstruct(type_uint4_, id_vector_temp_); + }); + + return eM_packed; + }; + + SpirvBuilder::SwitchBuilder format_switch( + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, format_info, + builder_->makeUintConstant(8), builder_->makeUintConstant(6)), + spv::SelectionControlDontFlattenMask, *builder_); + + struct FormatCase { + EMIdArray eM_packed; + uint32_t element_bytes_log2; + spv::Id phi_parent; + }; + std::vector format_cases; + // Must be called at the end of the switch case segment for the correct phi + // parent. + auto add_format_case = [&](const EMIdArray& eM_packed, uint32_t element_bytes_log2) { + FormatCase& format_case = format_cases.emplace_back(); + format_case.eM_packed = eM_packed; + format_case.element_bytes_log2 = element_bytes_log2; + format_case.phi_parent = builder_->getBuildPoint()->getId(); + }; + + // k_8, k_8_A, k_8_B + format_switch.makeBeginCase(static_cast(xenos::ColorFormat::k_8)); + // TODO(Triang3l): Investigate how input should be treated for k_8_A, k_8_B. + format_switch.addCurrentCaseLiteral(static_cast(xenos::ColorFormat::k_8_A)); + format_switch.addCurrentCaseLiteral(static_cast(xenos::ColorFormat::k_8_B)); + add_format_case(pack_8_16_32({8}), 0); + + // k_1_5_5_5 + format_switch.makeBeginCase(static_cast(xenos::ColorFormat::k_1_5_5_5)); + add_format_case(pack_8_16_32({5, 5, 5, 1}), 1); + + // k_5_6_5 + format_switch.makeBeginCase(static_cast(xenos::ColorFormat::k_5_6_5)); + add_format_case(pack_8_16_32({5, 6, 5}), 1); + + // k_6_5_5 + format_switch.makeBeginCase(static_cast(xenos::ColorFormat::k_6_5_5)); + add_format_case(pack_8_16_32({5, 5, 6}), 1); + + // k_8_8_8_8, k_8_8_8_8_A, k_8_8_8_8_AS_16_16_16_16 + format_switch.makeBeginCase(static_cast(xenos::ColorFormat::k_8_8_8_8)); + // TODO(Triang3l): Investigate how input should be treated for k_8_8_8_8_A. + format_switch.addCurrentCaseLiteral(static_cast(xenos::ColorFormat::k_8_8_8_8_A)); + format_switch.addCurrentCaseLiteral( + static_cast(xenos::ColorFormat::k_8_8_8_8_AS_16_16_16_16)); + add_format_case(pack_8_16_32({8, 8, 8, 8}), 2); + + // k_2_10_10_10, k_2_10_10_10_AS_16_16_16_16 + format_switch.makeBeginCase(static_cast(xenos::ColorFormat::k_2_10_10_10)); + format_switch.addCurrentCaseLiteral( + static_cast(xenos::ColorFormat::k_2_10_10_10_AS_16_16_16_16)); + add_format_case(pack_8_16_32({10, 10, 10, 2}), 2); + + // k_8_8 + format_switch.makeBeginCase(static_cast(xenos::ColorFormat::k_8_8)); + add_format_case(pack_8_16_32({8, 8}), 1); + + // k_4_4_4_4 + format_switch.makeBeginCase(static_cast(xenos::ColorFormat::k_4_4_4_4)); + add_format_case(pack_8_16_32({4, 4, 4, 4}), 1); + + // k_10_11_11, k_10_11_11_AS_16_16_16_16 + format_switch.makeBeginCase(static_cast(xenos::ColorFormat::k_10_11_11)); + format_switch.addCurrentCaseLiteral( + static_cast(xenos::ColorFormat::k_10_11_11_AS_16_16_16_16)); + add_format_case(pack_8_16_32({11, 11, 10}), 2); + + // k_11_11_10, k_11_11_10_AS_16_16_16_16 + format_switch.makeBeginCase(static_cast(xenos::ColorFormat::k_11_11_10)); + format_switch.addCurrentCaseLiteral( + static_cast(xenos::ColorFormat::k_11_11_10_AS_16_16_16_16)); + add_format_case(pack_8_16_32({10, 11, 11}), 2); + + // k_16 + format_switch.makeBeginCase(static_cast(xenos::ColorFormat::k_16)); + add_format_case(pack_8_16_32({16}), 1); + + // k_16_16 + format_switch.makeBeginCase(static_cast(xenos::ColorFormat::k_16_16)); + add_format_case(pack_8_16_32({16, 16}), 2); + + // k_16_16_16_16 + format_switch.makeBeginCase(static_cast(xenos::ColorFormat::k_16_16_16_16)); + { + // Flush NaNs. + EMIdArray fixed16_flushed = flush_nan(eM_swapped); + + // Convert to integers. + SpirvBuilder::IfBuilder if_signed(is_signed, spv::SelectionControlDontFlattenMask, *builder_); + EMIdArray fixed16_signed; + { + // Signed. + SpirvBuilder::IfBuilder if_norm(is_norm, spv::SelectionControlDontFlattenMask, *builder_); + EMIdArray fixed16_norm; + { + // Signed normalized. + id_vector_temp_.clear(); + id_vector_temp_.resize(4, + builder_->makeFloatConstant(float((uint32_t(1) << (16 - 1)) - 1))); + spv::Id const_snorm16_max_value = + builder_->makeCompositeConstant(type_float4_, id_vector_temp_); + for_each_eM([&](uint32_t eM_index) { + fixed16_norm[eM_index] = builder_->createNoContractionBinOp( + spv::OpFMul, type_float4_, + builder_->createTriBuiltinCall(type_float4_, ext_inst_glsl_std_450_, GLSLstd450FClamp, + fixed16_flushed[eM_index], + const_float_vectors_minus_1[3], const_float4_1_), + const_snorm16_max_value); + }); + } + if_norm.makeEndIf(); + // All phi instructions must be in the beginning of the block. + for_each_eM([&](uint32_t eM_index) { + fixed16_signed[eM_index] = + if_norm.createMergePhi(fixed16_norm[eM_index], fixed16_flushed[eM_index]); + }); + // Convert to signed integer, adding plus/minus 0.5 before truncating + // according to the Direct3D format conversion rules. + for_each_eM([&](uint32_t eM_index) { + fixed16_signed[eM_index] = builder_->createUnaryOp( + spv::OpBitcast, type_uint4_, + builder_->createUnaryOp( + spv::OpConvertFToS, type_int4_, + builder_->createNoContractionBinOp( + spv::OpFAdd, type_float4_, fixed16_signed[eM_index], + builder_->createTriOp( + spv::OpSelect, type_float4_, + builder_->createBinOp(spv::OpFOrdLessThan, type_bool4_, + fixed16_signed[eM_index], const_float4_0_), + const_float_vectors_minus_0_5[3], const_float_vectors_0_5[3])))); + }); + } + if_signed.makeBeginElse(); + EMIdArray fixed16_unsigned; + { + // Unsigned. + SpirvBuilder::IfBuilder if_norm(is_norm, spv::SelectionControlDontFlattenMask, *builder_); + EMIdArray fixed16_norm; + { + // Unsigned normalized. + id_vector_temp_.clear(); + id_vector_temp_.resize(4, builder_->makeFloatConstant(float((uint32_t(1) << 16) - 1))); + spv::Id const_unorm16_max_value = + builder_->makeCompositeConstant(type_float4_, id_vector_temp_); + for_each_eM([&](uint32_t eM_index) { + fixed16_norm[eM_index] = builder_->createNoContractionBinOp( + spv::OpFMul, type_float4_, + builder_->createTriBuiltinCall(type_float4_, ext_inst_glsl_std_450_, GLSLstd450FClamp, + fixed16_flushed[eM_index], const_float4_0_, + const_float4_1_), + const_unorm16_max_value); + }); + } + if_norm.makeEndIf(); + // All phi instructions must be in the beginning of the block. + for_each_eM([&](uint32_t eM_index) { + fixed16_unsigned[eM_index] = + if_norm.createMergePhi(fixed16_norm[eM_index], fixed16_flushed[eM_index]); + }); + // Convert to unsigned integer, adding 0.5 before truncating according to + // the Direct3D format conversion rules. + for_each_eM([&](uint32_t eM_index) { + fixed16_unsigned[eM_index] = builder_->createUnaryOp( + spv::OpConvertFToU, type_uint4_, + builder_->createNoContractionBinOp( + spv::OpFAdd, type_float4_, fixed16_unsigned[eM_index], const_float_vectors_0_5[3])); + }); + } + if_signed.makeEndIf(); + EMIdArray fixed16_unpacked; + for_each_eM([&](uint32_t eM_index) { + fixed16_unpacked[eM_index] = + if_signed.createMergePhi(fixed16_signed[eM_index], fixed16_unsigned[eM_index]); + }); + + // Pack into two 32-bit values, and pad to a 4-component vector for the phi. + EMIdArray fixed16_packed; + spv::Id const_uint_16 = builder_->makeUintConstant(16); + for_each_eM([&](uint32_t eM_index) { + spv::Id fixed16_element_unpacked = fixed16_unpacked[eM_index]; + id_vector_temp_.clear(); + for (uint32_t component_index = 0; component_index < 2; ++component_index) { + id_vector_temp_.push_back(builder_->createQuadOp( + spv::OpBitFieldInsert, type_uint_, + builder_->createCompositeExtract(fixed16_element_unpacked, type_uint_, + 2 * component_index), + builder_->createCompositeExtract(fixed16_element_unpacked, type_uint_, + 2 * component_index + 1), + const_uint_16, const_uint_16)); + } + for (uint32_t component_index = 2; component_index < 4; ++component_index) { + id_vector_temp_.push_back(const_uint_0_); + } + fixed16_packed[eM_index] = builder_->createCompositeConstruct(type_uint4_, id_vector_temp_); + }); + + add_format_case(fixed16_packed, 3); + } + + // TODO(Triang3l): Use the extended range float16 conversion. + + // k_16_FLOAT + format_switch.makeBeginCase(static_cast(xenos::ColorFormat::k_16_FLOAT)); + { + EMIdArray format_packed_16_float; + for_each_eM([&](uint32_t eM_index) { + id_vector_temp_.clear(); + id_vector_temp_.push_back( + builder_->createCompositeExtract(eM_swapped[eM_index], type_float_, 0)); + id_vector_temp_.push_back(const_float_0_); + spv::Id format_packed_16_float_x = builder_->createUnaryBuiltinCall( + type_uint_, ext_inst_glsl_std_450_, GLSLstd450PackHalf2x16, + builder_->createCompositeConstruct(type_float2_, id_vector_temp_)); + id_vector_temp_.clear(); + id_vector_temp_.resize(4, const_uint_0_); + id_vector_temp_.front() = format_packed_16_float_x; + format_packed_16_float[eM_index] = + builder_->createCompositeConstruct(type_uint4_, id_vector_temp_); + }); + add_format_case(format_packed_16_float, 1); + } + + // k_16_16_FLOAT + format_switch.makeBeginCase(static_cast(xenos::ColorFormat::k_16_16_FLOAT)); + { + EMIdArray format_packed_16_16_float; + for_each_eM([&](uint32_t eM_index) { + uint_vector_temp_.clear(); + uint_vector_temp_.push_back(0); + uint_vector_temp_.push_back(1); + spv::Id format_packed_16_16_float_xy = builder_->createUnaryBuiltinCall( + type_uint_, ext_inst_glsl_std_450_, GLSLstd450PackHalf2x16, + builder_->createRvalueSwizzle(spv::NoPrecision, type_float2_, eM_swapped[eM_index], + uint_vector_temp_)); + id_vector_temp_.clear(); + id_vector_temp_.resize(4, const_uint_0_); + id_vector_temp_.front() = format_packed_16_16_float_xy; + format_packed_16_16_float[eM_index] = + builder_->createCompositeConstruct(type_uint4_, id_vector_temp_); + }); + add_format_case(format_packed_16_16_float, 2); + } + + // k_16_16_16_16_FLOAT + format_switch.makeBeginCase(static_cast(xenos::ColorFormat::k_16_16_16_16_FLOAT)); + { + EMIdArray format_packed_16_16_16_16_float; + for_each_eM([&](uint32_t eM_index) { + spv::Id format_packed_16_16_16_16_float_xy_zw[2]; + for (uint32_t component_index = 0; component_index < 2; ++component_index) { + uint_vector_temp_.clear(); + uint_vector_temp_.push_back(2 * component_index); + uint_vector_temp_.push_back(2 * component_index + 1); + format_packed_16_16_16_16_float_xy_zw[component_index] = builder_->createUnaryBuiltinCall( + type_uint_, ext_inst_glsl_std_450_, GLSLstd450PackHalf2x16, + builder_->createRvalueSwizzle(spv::NoPrecision, type_float2_, eM_swapped[eM_index], + uint_vector_temp_)); + } + id_vector_temp_.clear(); + id_vector_temp_.push_back(format_packed_16_16_16_16_float_xy_zw[0]); + id_vector_temp_.push_back(format_packed_16_16_16_16_float_xy_zw[1]); + id_vector_temp_.push_back(const_uint_0_); + id_vector_temp_.push_back(const_uint_0_); + format_packed_16_16_16_16_float[eM_index] = + builder_->createCompositeConstruct(type_uint4_, id_vector_temp_); + }); + add_format_case(format_packed_16_16_16_16_float, 3); + } + + // k_32_FLOAT + format_switch.makeBeginCase(static_cast(xenos::ColorFormat::k_32_FLOAT)); + { + EMIdArray format_packed_32_float; + for_each_eM([&](uint32_t eM_index) { + format_packed_32_float[eM_index] = + builder_->createUnaryOp(spv::OpBitcast, type_uint4_, eM_swapped[eM_index]); + }); + add_format_case(format_packed_32_float, 2); + } + + // k_32_32_FLOAT + format_switch.makeBeginCase(static_cast(xenos::ColorFormat::k_32_32_FLOAT)); + { + EMIdArray format_packed_32_32_float; + for_each_eM([&](uint32_t eM_index) { + format_packed_32_32_float[eM_index] = + builder_->createUnaryOp(spv::OpBitcast, type_uint4_, eM_swapped[eM_index]); + }); + add_format_case(format_packed_32_32_float, 3); + } + + // k_32_32_32_32_FLOAT + format_switch.makeBeginCase(static_cast(xenos::ColorFormat::k_32_32_32_32_FLOAT)); + { + EMIdArray format_packed_32_32_32_32_float; + for_each_eM([&](uint32_t eM_index) { + format_packed_32_32_32_32_float[eM_index] = + builder_->createUnaryOp(spv::OpBitcast, type_uint4_, eM_swapped[eM_index]); + }); + add_format_case(format_packed_32_32_32_32_float, 4); + } + + format_switch.makeEndSwitch(); + + // Select the result and the element size based on the format. + // Phi must be the first instructions in a block. + EMIdArray eM_packed; + for_each_eM([&](uint32_t eM_index) { + auto eM_packed_phi = + std::make_unique(builder_->getUniqueId(), type_uint4_, spv::OpPhi); + // Default case for an invalid format. + eM_packed_phi->addIdOperand(const_uint4_0_); + eM_packed_phi->addIdOperand(format_switch.getDefaultPhiParent()); + for (const FormatCase& format_case : format_cases) { + eM_packed_phi->addIdOperand(format_case.eM_packed[eM_index]); + eM_packed_phi->addIdOperand(format_case.phi_parent); + } + eM_packed[eM_index] = eM_packed_phi->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(eM_packed_phi)); + }); + spv::Id element_bytes_log2; + { + auto element_bytes_log2_phi = + std::make_unique(builder_->getUniqueId(), type_uint_, spv::OpPhi); + // Default case for an invalid format (doesn't enter any element size + // conditional, skipped). + element_bytes_log2_phi->addIdOperand(builder_->makeUintConstant(5)); + element_bytes_log2_phi->addIdOperand(format_switch.getDefaultPhiParent()); + for (const FormatCase& format_case : format_cases) { + element_bytes_log2_phi->addIdOperand( + builder_->makeUintConstant(format_case.element_bytes_log2)); + element_bytes_log2_phi->addIdOperand(format_case.phi_parent); + } + element_bytes_log2 = element_bytes_log2_phi->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(element_bytes_log2_phi)); + } + + // Endian-swap. + spv::Id endian = builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, format_info, + const_uint_0_, builder_->makeUintConstant(3)); + for_each_eM([&](uint32_t eM_index) { + eM_packed[eM_index] = EndianSwap128Uint4(eM_packed[eM_index], endian); + }); + + // Load the index of eM0 in the stream. + spv::Id eM0_index = + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, + builder_->createCompositeExtract(eA_vector, type_uint_, 1), + const_uint_0_, builder_->makeUintConstant(23)); + + // Check how many elements starting from eM0 are within the bounds of the + // stream, and from the eM# that were written, exclude the out-of-bounds ones. + // The index can't be negative, and the index and the count are limited to 23 + // bits, so it's safe to use 32-bit signed subtraction and clamping to get the + // remaining eM# count. + spv::Id eM_indices_to_store = builder_->createTriOp( + spv::OpBitFieldUExtract, type_uint_, + builder_->createLoad(var_main_memexport_data_written_, spv::NoPrecision), const_uint_0_, + builder_->createUnaryOp( + spv::OpBitcast, type_uint_, + builder_->createTriBuiltinCall( + type_int_, ext_inst_glsl_std_450_, GLSLstd450SClamp, + builder_->createBinOp( + spv::OpISub, type_int_, + builder_->createUnaryOp( + spv::OpBitcast, type_int_, + builder_->createTriOp( + spv::OpBitFieldUExtract, type_uint_, + builder_->createCompositeExtract(eA_vector, type_uint_, 3), const_uint_0_, + builder_->makeUintConstant(23))), + builder_->createUnaryOp(spv::OpBitcast, type_int_, eM0_index)), + const_int_0_, builder_->makeIntConstant(ucode::kMaxMemExportElementCount)))); + + // Get the eM0 address in bytes. + // Left-shift the stream base address by 2 to both convert it from dwords to + // bytes and drop the upper bits. + spv::Id const_uint_2 = builder_->makeUintConstant(2); + spv::Id eM0_address_bytes = builder_->createBinOp( + spv::OpIAdd, type_uint_, + builder_->createBinOp(spv::OpShiftLeftLogical, type_uint_, + builder_->createCompositeExtract(eA_vector, type_uint_, 0), + const_uint_2), + builder_->createBinOp(spv::OpShiftLeftLogical, type_uint_, eM0_index, element_bytes_log2)); + + // Store based on the element size. + auto store_needed_eM = [&](std::function fn) { + for_each_eM([&](uint32_t eM_index) { + SpirvBuilder::IfBuilder if_eM_needed( + builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, eM_indices_to_store, + builder_->makeUintConstant(1u << eM_index)), + const_uint_0_), + spv::SelectionControlDontFlattenMask, *builder_, 2, 1); + fn(eM_index); + if_eM_needed.makeEndIf(); + }); + }; + SpirvBuilder::SwitchBuilder element_size_switch(element_bytes_log2, + spv::SelectionControlDontFlattenMask, *builder_); + element_size_switch.makeBeginCase(0); + { + store_needed_eM([&](uint32_t eM_index) { + spv::Id element_address_bytes = + eM_index != 0 ? builder_->createBinOp(spv::OpIAdd, type_uint_, eM0_address_bytes, + builder_->makeUintConstant(eM_index)) + : eM0_address_bytes; + // replace_shift = 8 * (element_address_bytes & 3) + spv::Id replace_shift = builder_->createQuadOp(spv::OpBitFieldInsert, type_uint_, + const_uint_0_, element_address_bytes, + builder_->makeUintConstant(3), const_uint_2); + StoreUint32ToSharedMemory( + builder_->createBinOp( + spv::OpShiftLeftLogical, type_uint_, + builder_->createCompositeExtract(eM_packed[eM_index], type_uint_, 0), replace_shift), + builder_->createUnaryOp(spv::OpBitcast, type_int_, + builder_->createBinOp(spv::OpShiftRightLogical, type_uint_, + element_address_bytes, const_uint_2)), + builder_->createBinOp(spv::OpShiftLeftLogical, type_uint_, + builder_->makeUintConstant(0xFFu), replace_shift)); + }); + } + element_size_switch.makeBeginCase(1); + { + spv::Id const_uint_1 = builder_->makeUintConstant(1); + spv::Id eM0_address_words = builder_->createBinOp(spv::OpShiftRightLogical, type_uint_, + eM0_address_bytes, const_uint_1); + store_needed_eM([&](uint32_t eM_index) { + spv::Id element_address_words = + eM_index != 0 ? builder_->createBinOp(spv::OpIAdd, type_uint_, eM0_address_words, + builder_->makeUintConstant(eM_index)) + : eM0_address_words; + // replace_shift = 16 * (element_address_words & 1) + spv::Id replace_shift = builder_->createQuadOp(spv::OpBitFieldInsert, type_uint_, + const_uint_0_, element_address_words, + builder_->makeUintConstant(4), const_uint_1); + StoreUint32ToSharedMemory( + builder_->createBinOp( + spv::OpShiftLeftLogical, type_uint_, + builder_->createCompositeExtract(eM_packed[eM_index], type_uint_, 0), replace_shift), + builder_->createUnaryOp(spv::OpBitcast, type_int_, + builder_->createBinOp(spv::OpShiftRightLogical, type_uint_, + element_address_words, const_uint_1)), + builder_->createBinOp(spv::OpShiftLeftLogical, type_uint_, + builder_->makeUintConstant(0xFFFFu), replace_shift)); + }); + } + element_size_switch.makeBeginCase(2); + { + spv::Id eM0_address_dwords = builder_->createBinOp(spv::OpShiftRightLogical, type_uint_, + eM0_address_bytes, const_uint_2); + store_needed_eM([&](uint32_t eM_index) { + StoreUint32ToSharedMemory( + builder_->createCompositeExtract(eM_packed[eM_index], type_uint_, 0), + builder_->createUnaryOp( + spv::OpBitcast, type_int_, + eM_index != 0 ? builder_->createBinOp(spv::OpIAdd, type_uint_, eM0_address_dwords, + builder_->makeUintConstant(eM_index)) + : eM0_address_dwords)); + }); + } + element_size_switch.makeBeginCase(3); + { + spv::Id eM0_address_dwords = builder_->createBinOp(spv::OpShiftRightLogical, type_uint_, + eM0_address_bytes, const_uint_2); + store_needed_eM([&](uint32_t eM_index) { + spv::Id element_value = eM_packed[eM_index]; + spv::Id element_address_dwords_int = builder_->createUnaryOp( + spv::OpBitcast, type_int_, + eM_index != 0 ? builder_->createBinOp(spv::OpIAdd, type_uint_, eM0_address_dwords, + builder_->makeUintConstant(2 * eM_index)) + : eM0_address_dwords); + StoreUint32ToSharedMemory(builder_->createCompositeExtract(element_value, type_uint_, 0), + element_address_dwords_int); + StoreUint32ToSharedMemory( + builder_->createCompositeExtract(element_value, type_uint_, 1), + builder_->createBinOp(spv::OpIAdd, type_int_, element_address_dwords_int, + builder_->makeIntConstant(1))); + }); + } + element_size_switch.makeBeginCase(4); + { + spv::Id eM0_address_dwords = builder_->createBinOp(spv::OpShiftRightLogical, type_uint_, + eM0_address_bytes, const_uint_2); + store_needed_eM([&](uint32_t eM_index) { + spv::Id element_value = eM_packed[eM_index]; + spv::Id element_address_dwords_int = builder_->createUnaryOp( + spv::OpBitcast, type_int_, + eM_index != 0 ? builder_->createBinOp(spv::OpIAdd, type_uint_, eM0_address_dwords, + builder_->makeUintConstant(4 * eM_index)) + : eM0_address_dwords); + StoreUint32ToSharedMemory(builder_->createCompositeExtract(element_value, type_uint_, 0), + element_address_dwords_int); + for (uint32_t element_dword_index = 1; element_dword_index < 4; ++element_dword_index) { + StoreUint32ToSharedMemory( + builder_->createCompositeExtract(element_value, type_uint_, element_dword_index), + builder_->createBinOp( + spv::OpIAdd, type_int_, element_address_dwords_int, + builder_->makeIntConstant(static_cast(element_dword_index)))); + } + }); + } + element_size_switch.makeEndSwitch(); + + // Close the conditionals for whether memory export is allowed in this + // invocation. + if_address_valid.makeEndIf(); + if (if_pixel_not_killed.has_value()) { + if_pixel_not_killed->makeEndIf(); + } + if (if_memexport_allowed.has_value()) { + if_memexport_allowed->makeEndIf(); + } +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/shader/spirv_translator_rb.cpp b/src/graphics/pipeline/shader/spirv_translator_rb.cpp new file mode 100644 index 0000000..765c141 --- /dev/null +++ b/src/graphics/pipeline/shader/spirv_translator_rb.cpp @@ -0,0 +1,3412 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +namespace rex::graphics { + +spv::Id SpirvShaderTranslator::PreClampedFloat32To7e3(SpirvBuilder& builder, spv::Id f32_scalar, + spv::Id ext_inst_glsl_std_450) { + // https://github.com/Microsoft/DirectXTex/blob/master/DirectXTex/DirectXTexConvert.cpp + // Assuming the value is already clamped to [0, 31.875]. + + spv::Id type_uint = builder.makeUintType(32); + + // Need the source as uint for bit operations. + { + spv::Id source_type = builder.getTypeId(f32_scalar); + assert_true(builder.isScalarType(source_type)); + if (!builder.isUintType(source_type)) { + f32_scalar = builder.createUnaryOp(spv::OpBitcast, type_uint, f32_scalar); + } + } + + // The denormal 7e3 case. + // denormal_biased_f32 = (f32 & 0x7FFFFF) | 0x800000 + spv::Id denormal_biased_f32; + { + spv::Instruction* denormal_insert_instruction = + new spv::Instruction(builder.getUniqueId(), type_uint, spv::OpBitFieldInsert); + denormal_insert_instruction->addIdOperand(f32_scalar); + denormal_insert_instruction->addIdOperand(builder.makeUintConstant(1)); + denormal_insert_instruction->addIdOperand(builder.makeUintConstant(23)); + denormal_insert_instruction->addIdOperand(builder.makeUintConstant(9)); + builder.getBuildPoint()->addInstruction( + std::unique_ptr(denormal_insert_instruction)); + denormal_biased_f32 = denormal_insert_instruction->getResultId(); + } + // denormal_biased_f32_shift_amount = min(125 - (f32 >> 23), 24) + // Not allowing the shift to overflow as that's undefined in SPIR-V. + spv::Id denormal_biased_f32_shift_amount; + { + spv::Instruction* denormal_shift_amount_instruction = + new spv::Instruction(builder.getUniqueId(), type_uint, spv::OpExtInst); + denormal_shift_amount_instruction->addIdOperand(ext_inst_glsl_std_450); + denormal_shift_amount_instruction->addImmediateOperand(GLSLstd450UMin); + denormal_shift_amount_instruction->addIdOperand( + builder.createBinOp(spv::OpISub, type_uint, builder.makeUintConstant(125), + builder.createBinOp(spv::OpShiftRightLogical, type_uint, f32_scalar, + builder.makeUintConstant(23)))); + denormal_shift_amount_instruction->addIdOperand(builder.makeUintConstant(24)); + builder.getBuildPoint()->addInstruction( + std::unique_ptr(denormal_shift_amount_instruction)); + denormal_biased_f32_shift_amount = denormal_shift_amount_instruction->getResultId(); + } + // denormal_biased_f32 = + // ((f32 & 0x7FFFFF) | 0x800000) >> min(125 - (f32 >> 23), 24) + denormal_biased_f32 = builder.createBinOp(spv::OpShiftRightLogical, type_uint, + denormal_biased_f32, denormal_biased_f32_shift_amount); + + // The normal 7e3 case. + // Bias the exponent. + // normal_biased_f32 = f32 - (124 << 23) + spv::Id normal_biased_f32 = builder.createBinOp(spv::OpISub, type_uint, f32_scalar, + builder.makeUintConstant(UINT32_C(124) << 23)); + + // Select the needed conversion depending on whether the number is too small + // to be represented as normalized 7e3. + spv::Id biased_f32 = + builder.createTriOp(spv::OpSelect, type_uint, + builder.createBinOp(spv::OpULessThan, builder.makeBoolType(), f32_scalar, + builder.makeUintConstant(0x3E800000)), + denormal_biased_f32, normal_biased_f32); + + // Build the 7e3 number rounding to the nearest even. + // ((biased_f32 + 0x7FFF + ((biased_f32 >> 16) & 1)) >> 16) & 0x3FF + return builder.createTriOp( + spv::OpBitFieldUExtract, type_uint, + builder.createBinOp( + spv::OpIAdd, type_uint, + builder.createBinOp(spv::OpIAdd, type_uint, biased_f32, builder.makeUintConstant(0x7FFF)), + builder.createTriOp(spv::OpBitFieldUExtract, type_uint, biased_f32, + builder.makeUintConstant(16), builder.makeUintConstant(1))), + builder.makeUintConstant(16), builder.makeUintConstant(10)); +} + +spv::Id SpirvShaderTranslator::UnclampedFloat32To7e3(SpirvBuilder& builder, spv::Id f32_scalar, + spv::Id ext_inst_glsl_std_450) { + spv::Id type_float = builder.makeFloatType(32); + + // Need the source as float for clamping. + { + spv::Id source_type = builder.getTypeId(f32_scalar); + assert_true(builder.isScalarType(source_type)); + if (!builder.isFloatType(source_type)) { + f32_scalar = builder.createUnaryOp(spv::OpBitcast, type_float, f32_scalar); + } + } + + { + spv::Instruction* clamp_instruction = + new spv::Instruction(builder.getUniqueId(), type_float, spv::OpExtInst); + clamp_instruction->addIdOperand(ext_inst_glsl_std_450); + clamp_instruction->addImmediateOperand(GLSLstd450NClamp); + clamp_instruction->addIdOperand(f32_scalar); + clamp_instruction->addIdOperand(builder.makeFloatConstant(0.0f)); + clamp_instruction->addIdOperand(builder.makeFloatConstant(31.875f)); + builder.getBuildPoint()->addInstruction(std::unique_ptr(clamp_instruction)); + f32_scalar = clamp_instruction->getResultId(); + } + + return PreClampedFloat32To7e3(builder, f32_scalar, ext_inst_glsl_std_450); +} + +spv::Id SpirvShaderTranslator::Float7e3To32(SpirvBuilder& builder, spv::Id f10_uint_scalar, + uint32_t f10_shift, bool result_as_uint, + spv::Id ext_inst_glsl_std_450) { + // https://github.com/Microsoft/DirectXTex/blob/master/DirectXTex/DirectXTexConvert.cpp + + assert_true(builder.isUintType(builder.getTypeId(f10_uint_scalar))); + assert_true(f10_shift <= (32 - 10)); + + spv::Id type_bool = builder.makeBoolType(); + spv::Id type_int = builder.makeIntType(32); + spv::Id type_uint = builder.makeUintType(32); + + spv::Id f10_unbiased_exponent = + builder.createTriOp(spv::OpBitFieldUExtract, type_uint, f10_uint_scalar, + builder.makeUintConstant(f10_shift + 7), builder.makeUintConstant(3)); + spv::Id f10_mantissa = + builder.createTriOp(spv::OpBitFieldUExtract, type_uint, f10_uint_scalar, + builder.makeUintConstant(f10_shift), builder.makeUintConstant(7)); + + // The denormal nonzero 7e3 case. + // denormal_mantissa_msb = findMSB(f10_mantissa) + spv::Id denormal_mantissa_msb; + { + spv::Instruction* denormal_mantissa_msb_instruction = + new spv::Instruction(builder.getUniqueId(), type_int, spv::OpExtInst); + denormal_mantissa_msb_instruction->addIdOperand(ext_inst_glsl_std_450); + denormal_mantissa_msb_instruction->addImmediateOperand(GLSLstd450FindUMsb); + denormal_mantissa_msb_instruction->addIdOperand(f10_mantissa); + builder.getBuildPoint()->addInstruction( + std::unique_ptr(denormal_mantissa_msb_instruction)); + denormal_mantissa_msb = denormal_mantissa_msb_instruction->getResultId(); + } + denormal_mantissa_msb = builder.createUnaryOp(spv::OpBitcast, type_uint, denormal_mantissa_msb); + // denormal_f32_unbiased_exponent = 1 - (7 - findMSB(f10_mantissa)) + // Or: + // denormal_f32_unbiased_exponent = findMSB(f10_mantissa) - 6 + spv::Id denormal_f32_unbiased_exponent = builder.createBinOp( + spv::OpISub, type_uint, denormal_mantissa_msb, builder.makeUintConstant(6)); + // Normalize the mantissa. + // denormal_f32_mantissa = f10_mantissa << (7 - findMSB(f10_mantissa)) + spv::Id denormal_f32_mantissa = + builder.createBinOp(spv::OpShiftLeftLogical, type_uint, f10_mantissa, + builder.createBinOp(spv::OpISub, type_uint, builder.makeUintConstant(7), + denormal_mantissa_msb)); + // If the 7e3 number is zero, make sure the float32 number is zero too. + spv::Id f10_mantissa_is_nonzero = + builder.createBinOp(spv::OpINotEqual, type_bool, f10_mantissa, builder.makeUintConstant(0)); + // Set the unbiased exponent to -124 for zero - 124 will be added later, + // resulting in zero float32. + denormal_f32_unbiased_exponent = + builder.createTriOp(spv::OpSelect, type_uint, f10_mantissa_is_nonzero, + denormal_f32_unbiased_exponent, builder.makeUintConstant(uint32_t(-124))); + denormal_f32_mantissa = builder.createTriOp(spv::OpSelect, type_uint, f10_mantissa_is_nonzero, + denormal_f32_mantissa, builder.makeUintConstant(0)); + + // Select the needed conversion depending on whether the number is normal. + spv::Id f10_is_normal = builder.createBinOp(spv::OpINotEqual, type_bool, f10_unbiased_exponent, + builder.makeUintConstant(0)); + spv::Id f32_unbiased_exponent = + builder.createTriOp(spv::OpSelect, type_uint, f10_is_normal, f10_unbiased_exponent, + denormal_f32_unbiased_exponent); + spv::Id f32_mantissa = builder.createTriOp(spv::OpSelect, type_uint, f10_is_normal, f10_mantissa, + denormal_f32_mantissa); + + // Bias the exponent and construct the build the float32 number. + spv::Id f32_shifted; + { + spv::Instruction* f32_insert_instruction = + new spv::Instruction(builder.getUniqueId(), type_uint, spv::OpBitFieldInsert); + f32_insert_instruction->addIdOperand(f32_mantissa); + f32_insert_instruction->addIdOperand(builder.createBinOp( + spv::OpIAdd, type_uint, f32_unbiased_exponent, builder.makeUintConstant(124))); + f32_insert_instruction->addIdOperand(builder.makeUintConstant(7)); + f32_insert_instruction->addIdOperand(builder.makeUintConstant(8)); + builder.getBuildPoint()->addInstruction( + std::unique_ptr(f32_insert_instruction)); + f32_shifted = f32_insert_instruction->getResultId(); + } + spv::Id f32 = builder.createBinOp(spv::OpShiftLeftLogical, type_uint, f32_shifted, + builder.makeUintConstant(23 - 7)); + + if (!result_as_uint) { + f32 = builder.createUnaryOp(spv::OpBitcast, builder.makeFloatType(32), f32); + } + + return f32; +} + +spv::Id SpirvShaderTranslator::PreClampedDepthTo20e4(SpirvBuilder& builder, spv::Id f32_scalar, + bool round_to_nearest_even, + bool remap_from_0_to_0_5, + spv::Id ext_inst_glsl_std_450) { + // CFloat24 from d3dref9.dll + + // https://github.com/Microsoft/DirectXTex/blob/master/DirectXTex/DirectXTexConvert.cpp + // Assuming the value is already clamped to [0, 2) (in all places, the depth + // is written with saturation). + + uint32_t remap_bias = uint32_t(remap_from_0_to_0_5); + + spv::Id type_uint = builder.makeUintType(32); + + // Need the source as uint for bit operations. + { + spv::Id source_type = builder.getTypeId(f32_scalar); + assert_true(builder.isScalarType(source_type)); + if (!builder.isUintType(source_type)) { + f32_scalar = builder.createUnaryOp(spv::OpBitcast, type_uint, f32_scalar); + } + } + + // The denormal 20e4 case. + // denormal_biased_f32 = (f32 & 0x7FFFFF) | 0x800000 + spv::Id denormal_biased_f32; + { + spv::Instruction* denormal_insert_instruction = + new spv::Instruction(builder.getUniqueId(), type_uint, spv::OpBitFieldInsert); + denormal_insert_instruction->addIdOperand(f32_scalar); + denormal_insert_instruction->addIdOperand(builder.makeUintConstant(1)); + denormal_insert_instruction->addIdOperand(builder.makeUintConstant(23)); + denormal_insert_instruction->addIdOperand(builder.makeUintConstant(9)); + builder.getBuildPoint()->addInstruction( + std::unique_ptr(denormal_insert_instruction)); + denormal_biased_f32 = denormal_insert_instruction->getResultId(); + } + // denormal_biased_f32_shift_amount = min(113 - (f32 >> 23), 24) + // Not allowing the shift to overflow as that's undefined in SPIR-V. + spv::Id denormal_biased_f32_shift_amount; + { + spv::Instruction* denormal_shift_amount_instruction = + new spv::Instruction(builder.getUniqueId(), type_uint, spv::OpExtInst); + denormal_shift_amount_instruction->addIdOperand(ext_inst_glsl_std_450); + denormal_shift_amount_instruction->addImmediateOperand(GLSLstd450UMin); + denormal_shift_amount_instruction->addIdOperand( + builder.createBinOp(spv::OpISub, type_uint, builder.makeUintConstant(113 - remap_bias), + builder.createBinOp(spv::OpShiftRightLogical, type_uint, f32_scalar, + builder.makeUintConstant(23)))); + denormal_shift_amount_instruction->addIdOperand(builder.makeUintConstant(24)); + builder.getBuildPoint()->addInstruction( + std::unique_ptr(denormal_shift_amount_instruction)); + denormal_biased_f32_shift_amount = denormal_shift_amount_instruction->getResultId(); + } + // denormal_biased_f32 = + // ((f32 & 0x7FFFFF) | 0x800000) >> min(113 - (f32 >> 23), 24) + denormal_biased_f32 = builder.createBinOp(spv::OpShiftRightLogical, type_uint, + denormal_biased_f32, denormal_biased_f32_shift_amount); + + // The normal 20e4 case. + // Bias the exponent. + // normal_biased_f32 = f32 - (112 << 23) + spv::Id normal_biased_f32 = + builder.createBinOp(spv::OpISub, type_uint, f32_scalar, + builder.makeUintConstant((UINT32_C(112) - remap_bias) << 23)); + + // Select the needed conversion depending on whether the number is too small + // to be represented as normalized 20e4. + spv::Id biased_f32 = builder.createTriOp( + spv::OpSelect, type_uint, + builder.createBinOp(spv::OpULessThan, builder.makeBoolType(), f32_scalar, + builder.makeUintConstant(0x38800000 - (remap_bias << 23))), + denormal_biased_f32, normal_biased_f32); + + // Build the 20e4 number rounding to the nearest even or towards zero. + if (round_to_nearest_even) { + // biased_f32 += 3 + ((biased_f32 >> 3) & 1) + biased_f32 = builder.createBinOp( + spv::OpIAdd, type_uint, + builder.createBinOp(spv::OpIAdd, type_uint, biased_f32, builder.makeUintConstant(3)), + builder.createTriOp(spv::OpBitFieldUExtract, type_uint, biased_f32, + builder.makeUintConstant(3), builder.makeUintConstant(1))); + } + return builder.createTriOp(spv::OpBitFieldUExtract, type_uint, biased_f32, + builder.makeUintConstant(3), builder.makeUintConstant(24)); +} + +spv::Id SpirvShaderTranslator::Depth20e4To32(SpirvBuilder& builder, spv::Id f24_uint_scalar, + uint32_t f24_shift, bool remap_to_0_to_0_5, + bool result_as_uint, spv::Id ext_inst_glsl_std_450) { + // CFloat24 from d3dref9.dll + + // https://github.com/Microsoft/DirectXTex/blob/master/DirectXTex/DirectXTexConvert.cpp + + assert_true(builder.isUintType(builder.getTypeId(f24_uint_scalar))); + assert_true(f24_shift <= (32 - 24)); + + uint32_t remap_bias = uint32_t(remap_to_0_to_0_5); + + spv::Id type_bool = builder.makeBoolType(); + spv::Id type_int = builder.makeIntType(32); + spv::Id type_uint = builder.makeUintType(32); + + spv::Id f24_unbiased_exponent = + builder.createTriOp(spv::OpBitFieldUExtract, type_uint, f24_uint_scalar, + builder.makeUintConstant(f24_shift + 20), builder.makeUintConstant(4)); + spv::Id f24_mantissa = + builder.createTriOp(spv::OpBitFieldUExtract, type_uint, f24_uint_scalar, + builder.makeUintConstant(f24_shift), builder.makeUintConstant(20)); + + // The denormal nonzero 20e4 case. + // denormal_mantissa_msb = findMSB(f24_mantissa) + spv::Id denormal_mantissa_msb; + { + spv::Instruction* denormal_mantissa_msb_instruction = + new spv::Instruction(builder.getUniqueId(), type_int, spv::OpExtInst); + denormal_mantissa_msb_instruction->addIdOperand(ext_inst_glsl_std_450); + denormal_mantissa_msb_instruction->addImmediateOperand(GLSLstd450FindUMsb); + denormal_mantissa_msb_instruction->addIdOperand(f24_mantissa); + builder.getBuildPoint()->addInstruction( + std::unique_ptr(denormal_mantissa_msb_instruction)); + denormal_mantissa_msb = denormal_mantissa_msb_instruction->getResultId(); + } + denormal_mantissa_msb = builder.createUnaryOp(spv::OpBitcast, type_uint, denormal_mantissa_msb); + // denormal_f32_unbiased_exponent = 1 - (20 - findMSB(f24_mantissa)) + // Or: + // denormal_f32_unbiased_exponent = findMSB(f24_mantissa) - 19 + spv::Id denormal_f32_unbiased_exponent = builder.createBinOp( + spv::OpISub, type_uint, denormal_mantissa_msb, builder.makeUintConstant(19)); + // Normalize the mantissa. + // denormal_f32_mantissa = f24_mantissa << (20 - findMSB(f24_mantissa)) + spv::Id denormal_f32_mantissa = + builder.createBinOp(spv::OpShiftLeftLogical, type_uint, f24_mantissa, + builder.createBinOp(spv::OpISub, type_uint, builder.makeUintConstant(20), + denormal_mantissa_msb)); + // If the 20e4 number is zero, make sure the float32 number is zero too. + spv::Id f24_mantissa_is_nonzero = + builder.createBinOp(spv::OpINotEqual, type_bool, f24_mantissa, builder.makeUintConstant(0)); + // Set the unbiased exponent to -112 for zero - 112 will be added later, + // resulting in zero float32. + denormal_f32_unbiased_exponent = builder.createTriOp( + spv::OpSelect, type_uint, f24_mantissa_is_nonzero, denormal_f32_unbiased_exponent, + builder.makeUintConstant(uint32_t(-int32_t(112 - remap_bias)))); + denormal_f32_mantissa = builder.createTriOp(spv::OpSelect, type_uint, f24_mantissa_is_nonzero, + denormal_f32_mantissa, builder.makeUintConstant(0)); + + // Select the needed conversion depending on whether the number is normal. + spv::Id f24_is_normal = builder.createBinOp(spv::OpINotEqual, type_bool, f24_unbiased_exponent, + builder.makeUintConstant(0)); + spv::Id f32_unbiased_exponent = + builder.createTriOp(spv::OpSelect, type_uint, f24_is_normal, f24_unbiased_exponent, + denormal_f32_unbiased_exponent); + spv::Id f32_mantissa = builder.createTriOp(spv::OpSelect, type_uint, f24_is_normal, f24_mantissa, + denormal_f32_mantissa); + + // Bias the exponent and construct the build the float32 number. + spv::Id f32_shifted; + { + spv::Instruction* f32_insert_instruction = + new spv::Instruction(builder.getUniqueId(), type_uint, spv::OpBitFieldInsert); + f32_insert_instruction->addIdOperand(f32_mantissa); + f32_insert_instruction->addIdOperand(builder.createBinOp( + spv::OpIAdd, type_uint, f32_unbiased_exponent, builder.makeUintConstant(112 - remap_bias))); + f32_insert_instruction->addIdOperand(builder.makeUintConstant(20)); + f32_insert_instruction->addIdOperand(builder.makeUintConstant(8)); + builder.getBuildPoint()->addInstruction( + std::unique_ptr(f32_insert_instruction)); + f32_shifted = f32_insert_instruction->getResultId(); + } + spv::Id f32 = builder.createBinOp(spv::OpShiftLeftLogical, type_uint, f32_shifted, + builder.makeUintConstant(23 - 20)); + + if (!result_as_uint) { + f32 = builder.createUnaryOp(spv::OpBitcast, builder.makeFloatType(32), f32); + } + + return f32; +} + +void SpirvShaderTranslator::CompleteFragmentShaderInMain() { + // Loaded if needed. + spv::Id msaa_samples = spv::NoResult; + + if (edram_fragment_shader_interlock_ && !FSI_IsDepthStencilEarly()) { + if (msaa_samples == spv::NoResult) { + msaa_samples = LoadMsaaSamplesFromFlags(); + } + // Load the sample mask, which may be modified later by killing from + // different sources, if not loaded already. + FSI_LoadSampleMask(msaa_samples); + } + + bool fsi_pixel_potentially_killed = false; + + if (current_shader().kills_pixels()) { + if (edram_fragment_shader_interlock_) { + fsi_pixel_potentially_killed = true; + if (!features_.demote_to_helper_invocation) { + assert_true(var_main_kill_pixel_ != spv::NoResult); + main_fsi_sample_mask_ = builder_->createTriOp( + spv::OpSelect, type_uint_, builder_->createLoad(var_main_kill_pixel_, spv::NoPrecision), + const_uint_0_, main_fsi_sample_mask_); + } + } else { + if (!features_.demote_to_helper_invocation) { + // Kill the pixel once the guest control flow and derivatives are not + // needed anymore. + assert_true(var_main_kill_pixel_ != spv::NoResult); + SpirvBuilder::IfBuilder kill_pixel_if( + builder_->createLoad(var_main_kill_pixel_, spv::NoPrecision), + spv::SelectionControlMaskNone, *builder_); + // TODO(Triang3l): Use OpTerminateInvocation when SPIR-V 1.6 is + // targeted. + builder_->createNoResultOp(spv::OpKill); + // OpKill terminates the block. + kill_pixel_if.makeEndIf(false); + } + } + } + + uint32_t color_targets_written = current_shader().writes_color_targets(); + + if ((color_targets_written & 0b1) && !IsExecutionModeEarlyFragmentTests()) { + spv::Id fsi_sample_mask_in_rt_0_alpha_tests = spv::NoResult; + spv::Block* block_fsi_rt_0_alpha_tests_rt_written_head = nullptr; + spv::Block* block_fsi_rt_0_alpha_tests_rt_written_merge = nullptr; + if (!edram_fragment_shader_interlock_ && output_fragment_sample_mask_ != spv::NoResult) { + // If alpha to coverage is disabled, output full coverage. + id_vector_temp_.clear(); + id_vector_temp_.push_back(const_int_0_); + builder_->createStore( + builder_->createUnaryOp(spv::OpBitcast, type_int_, + builder_->makeUintConstant(UINT32_MAX)), + builder_->createAccessChain(spv::StorageClassOutput, output_fragment_sample_mask_, + id_vector_temp_)); + } + builder_->makeNewBlock(); + if (edram_fragment_shader_interlock_) { + // Skip the alpha test and alpha to coverage if the render target 0 is not + // written to dynamically. + fsi_sample_mask_in_rt_0_alpha_tests = main_fsi_sample_mask_; + spv::Id rt_0_written = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, + builder_->createLoad(var_main_fsi_color_written_, spv::NoPrecision), + builder_->makeUintConstant(0b1)), + const_uint_0_); + block_fsi_rt_0_alpha_tests_rt_written_head = builder_->getBuildPoint(); + spv::Block& block_fsi_rt_0_alpha_tests_rt_written = builder_->makeNewBlock(); + block_fsi_rt_0_alpha_tests_rt_written_merge = &builder_->makeNewBlock(); + builder_->createSelectionMerge(block_fsi_rt_0_alpha_tests_rt_written_merge, + spv::SelectionControlDontFlattenMask); + { + std::unique_ptr rt_0_written_branch_conditional_op = + std::make_unique(spv::OpBranchConditional); + rt_0_written_branch_conditional_op->addIdOperand(rt_0_written); + rt_0_written_branch_conditional_op->addIdOperand( + block_fsi_rt_0_alpha_tests_rt_written.getId()); + rt_0_written_branch_conditional_op->addIdOperand( + block_fsi_rt_0_alpha_tests_rt_written_merge->getId()); + // More likely to write to the render target 0 than not. + rt_0_written_branch_conditional_op->addImmediateOperand(2); + rt_0_written_branch_conditional_op->addImmediateOperand(1); + builder_->getBuildPoint()->addInstruction(std::move(rt_0_written_branch_conditional_op)); + } + block_fsi_rt_0_alpha_tests_rt_written.addPredecessor( + block_fsi_rt_0_alpha_tests_rt_written_head); + block_fsi_rt_0_alpha_tests_rt_written_merge->addPredecessor( + block_fsi_rt_0_alpha_tests_rt_written_head); + builder_->setBuildPoint(&block_fsi_rt_0_alpha_tests_rt_written); + } + + // Alpha test. + // TODO(Triang3l): Check how alpha test works with NaN on Direct3D 9. + // Extract the comparison function (less, equal, greater bits). + spv::Id alpha_test_function = builder_->createTriOp( + spv::OpBitFieldUExtract, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(kSysFlag_AlphaPassIfLess_Shift), builder_->makeUintConstant(3)); + // Check if the comparison function is not "always" - that should pass even + // for NaN likely, unlike "less, equal or greater". + SpirvBuilder::IfBuilder if_alpha_test_function_is_non_always( + builder_->createBinOp( + spv::OpINotEqual, type_bool_, alpha_test_function, + builder_->makeUintConstant(uint32_t(xenos::CompareFunction::kAlways))), + spv::SelectionControlDontFlattenMask, *builder_); + { + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(3)); + spv::Id alpha_test_alpha = builder_->createLoad( + builder_->createAccessChain(edram_fragment_shader_interlock_ ? spv::StorageClassFunction + : spv::StorageClassOutput, + output_or_var_fragment_data_[0], id_vector_temp_), + spv::NoPrecision); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantAlphaTestReference)); + spv::Id alpha_test_reference = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + // The comparison function is not "always" - perform the alpha test. + // Handle "not equal" specially (specifically as "not equal" so it's true + // for NaN, not "less or greater" which is false for NaN). + SpirvBuilder::IfBuilder if_alpha_test_function_is_not_equal( + builder_->createBinOp( + spv::OpIEqual, type_bool_, alpha_test_function, + builder_->makeUintConstant(uint32_t(xenos::CompareFunction::kNotEqual))), + spv::SelectionControlDontFlattenMask, *builder_, 1, 2); + spv::Id alpha_test_result_not_equal; + { + // "Not equal" function. + alpha_test_result_not_equal = builder_->createBinOp(spv::OpFUnordNotEqual, type_bool_, + alpha_test_alpha, alpha_test_reference); + } + if_alpha_test_function_is_not_equal.makeBeginElse(); + spv::Id alpha_test_result_non_not_equal; + { + // Function other than "not equal". + static const spv::Op kAlphaTestOps[] = {spv::OpFOrdLessThan, spv::OpFOrdEqual, + spv::OpFOrdGreaterThan}; + for (uint32_t i = 0; i < 3; ++i) { + spv::Id alpha_test_comparison_result = builder_->createBinOp( + spv::OpLogicalAnd, type_bool_, + builder_->createBinOp(kAlphaTestOps[i], type_bool_, alpha_test_alpha, + alpha_test_reference), + builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, alpha_test_function, + builder_->makeUintConstant(UINT32_C(1) << i)), + const_uint_0_)); + if (i) { + alpha_test_result_non_not_equal = + builder_->createBinOp(spv::OpLogicalOr, type_bool_, alpha_test_result_non_not_equal, + alpha_test_comparison_result); + } else { + alpha_test_result_non_not_equal = alpha_test_comparison_result; + } + } + } + if_alpha_test_function_is_not_equal.makeEndIf(); + spv::Id alpha_test_result = if_alpha_test_function_is_not_equal.createMergePhi( + alpha_test_result_not_equal, alpha_test_result_non_not_equal); + // Discard the pixel if the alpha test has failed. + if (edram_fragment_shader_interlock_ && !features_.demote_to_helper_invocation) { + fsi_pixel_potentially_killed = true; + fsi_sample_mask_in_rt_0_alpha_tests = + builder_->createTriOp(spv::OpSelect, type_uint_, alpha_test_result, + fsi_sample_mask_in_rt_0_alpha_tests, const_uint_0_); + } else { + SpirvBuilder::IfBuilder alpha_test_kill_if( + builder_->createUnaryOp(spv::OpLogicalNot, type_bool_, alpha_test_result), + spv::SelectionControlDontFlattenMask, *builder_); + bool branch_to_alpha_test_kill_merge = true; + if (edram_fragment_shader_interlock_) { + assert_true(features_.demote_to_helper_invocation); + fsi_pixel_potentially_killed = true; + // TODO(Triang3l): Promoted to SPIR-V 1.6 - don't add the extension + // there. + builder_->addExtension("SPV_EXT_demote_to_helper_invocation"); + builder_->addCapability(spv::CapabilityDemoteToHelperInvocationEXT); + builder_->createNoResultOp(spv::OpDemoteToHelperInvocationEXT); + } else { + // TODO(Triang3l): Use OpTerminateInvocation when SPIR-V 1.6 is + // targeted. + builder_->createNoResultOp(spv::OpKill); + // OpKill terminates the block. + branch_to_alpha_test_kill_merge = false; + } + alpha_test_kill_if.makeEndIf(branch_to_alpha_test_kill_merge); + } + } + if_alpha_test_function_is_non_always.makeEndIf(); + + // Alpha to coverage. + if (edram_fragment_shader_interlock_ || output_fragment_sample_mask_ != spv::NoResult) { + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantAlphaToMask)); + spv::Id alpha_to_mask = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + SpirvBuilder::IfBuilder if_alpha_to_coverage_enabled( + builder_->createBinOp(spv::OpINotEqual, type_bool_, alpha_to_mask, const_uint_0_), + spv::SelectionControlDontFlattenMask, *builder_); + { + if (edram_fragment_shader_interlock_) { + fsi_pixel_potentially_killed = true; + } + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(3)); + spv::Id alpha_to_coverage_alpha = builder_->createLoad( + builder_->createAccessChain(edram_fragment_shader_interlock_ ? spv::StorageClassFunction + : spv::StorageClassOutput, + output_or_var_fragment_data_[0], id_vector_temp_), + spv::NoPrecision); + assert_true(input_fragment_coordinates_ != spv::NoResult); + spv::Id const_uint_1 = builder_->makeUintConstant(1); + spv::Id const_uint_2 = builder_->makeUintConstant(2); + id_vector_temp_.clear(); + id_vector_temp_.push_back(const_int_0_); + spv::Id alpha_to_coverage_position_x = builder_->createUnaryOp( + spv::OpConvertFToU, type_uint_, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassInput, input_fragment_coordinates_, + id_vector_temp_), + spv::NoPrecision)); + id_vector_temp_.back() = builder_->makeIntConstant(1); + spv::Id alpha_to_coverage_position_y = builder_->createUnaryOp( + spv::OpConvertFToU, type_uint_, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassInput, input_fragment_coordinates_, + id_vector_temp_), + spv::NoPrecision)); + spv::Id alpha_to_coverage_offset = builder_->createTriOp( + spv::OpBitFieldUExtract, type_uint_, alpha_to_mask, + builder_->createBinOp( + spv::OpShiftLeftLogical, type_uint_, + builder_->createBinOp( + spv::OpBitwiseOr, type_uint_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, + alpha_to_coverage_position_x, const_uint_1), + builder_->createBinOp( + spv::OpShiftLeftLogical, type_uint_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, + alpha_to_coverage_position_y, const_uint_1), + const_uint_1)), + const_uint_1), + const_uint_2); + spv::Id alpha_to_coverage_offset_float = + builder_->createUnaryOp(spv::OpConvertUToF, type_float_, alpha_to_coverage_offset); + if (msaa_samples == spv::NoResult) { + msaa_samples = LoadMsaaSamplesFromFlags(); + } + auto alpha_to_coverage_apply_sample = [&](spv::Id sample_mask, uint32_t guest_sample_index, + uint32_t host_sample_index, float threshold_base, + float threshold_offset_scale) -> spv::Id { + spv::Id sample_threshold = builder_->createBinOp( + spv::OpFSub, type_float_, builder_->makeFloatConstant(threshold_base), + builder_->createBinOp(spv::OpFMul, type_float_, alpha_to_coverage_offset_float, + builder_->makeFloatConstant(threshold_offset_scale))); + spv::Id sample_covered = builder_->createBinOp(spv::OpFOrdGreaterThanEqual, type_bool_, + alpha_to_coverage_alpha, sample_threshold); + if (edram_fragment_shader_interlock_) { + return builder_->createTriOp( + spv::OpSelect, type_uint_, sample_covered, sample_mask, + builder_->createBinOp( + spv::OpBitwiseAnd, type_uint_, sample_mask, + builder_->makeUintConstant(~((UINT32_C(1) << guest_sample_index) | + (UINT32_C(1) << (guest_sample_index + 4)))))); + } + return builder_->createTriOp( + spv::OpSelect, type_uint_, sample_covered, + builder_->createBinOp(spv::OpBitwiseOr, type_uint_, sample_mask, + builder_->makeUintConstant(UINT32_C(1) << host_sample_index)), + sample_mask); + }; + spv::Id alpha_to_coverage_mask = + edram_fragment_shader_interlock_ ? fsi_sample_mask_in_rt_0_alpha_tests : const_uint_0_; + spv::Block& block_alpha_to_coverage_msaa_head = *builder_->getBuildPoint(); + spv::Block& block_alpha_to_coverage_msaa_1x = builder_->makeNewBlock(); + spv::Block& block_alpha_to_coverage_msaa_2x = builder_->makeNewBlock(); + spv::Block& block_alpha_to_coverage_msaa_4x = builder_->makeNewBlock(); + spv::Block& block_alpha_to_coverage_msaa_merge = builder_->makeNewBlock(); + builder_->createSelectionMerge(&block_alpha_to_coverage_msaa_merge, + spv::SelectionControlDontFlattenMask); + { + std::unique_ptr alpha_to_coverage_msaa_switch_op = + std::make_unique(spv::OpSwitch); + alpha_to_coverage_msaa_switch_op->addIdOperand(msaa_samples); + // Make 1x the default. + alpha_to_coverage_msaa_switch_op->addIdOperand(block_alpha_to_coverage_msaa_1x.getId()); + alpha_to_coverage_msaa_switch_op->addImmediateOperand(int32_t(xenos::MsaaSamples::k2X)); + alpha_to_coverage_msaa_switch_op->addIdOperand(block_alpha_to_coverage_msaa_2x.getId()); + alpha_to_coverage_msaa_switch_op->addImmediateOperand(int32_t(xenos::MsaaSamples::k4X)); + alpha_to_coverage_msaa_switch_op->addIdOperand(block_alpha_to_coverage_msaa_4x.getId()); + builder_->getBuildPoint()->addInstruction(std::move(alpha_to_coverage_msaa_switch_op)); + } + block_alpha_to_coverage_msaa_1x.addPredecessor(&block_alpha_to_coverage_msaa_head); + block_alpha_to_coverage_msaa_2x.addPredecessor(&block_alpha_to_coverage_msaa_head); + block_alpha_to_coverage_msaa_4x.addPredecessor(&block_alpha_to_coverage_msaa_head); + // 1x. + builder_->setBuildPoint(&block_alpha_to_coverage_msaa_1x); + spv::Id alpha_to_coverage_mask_1x = + alpha_to_coverage_apply_sample(alpha_to_coverage_mask, 0, 0, 1.0f, 1.0f / 4.0f); + builder_->createBranch(&block_alpha_to_coverage_msaa_merge); + // 2x. + builder_->setBuildPoint(&block_alpha_to_coverage_msaa_2x); + uint32_t alpha_to_coverage_host_sample_0 = 0; + uint32_t alpha_to_coverage_host_sample_1 = 1; + if (!edram_fragment_shader_interlock_) { + if (native_2x_msaa_with_attachments_) { + // Guest top and bottom to Vulkan sample 1 and 0. + alpha_to_coverage_host_sample_0 = 1; + alpha_to_coverage_host_sample_1 = 0; + } else { + // Guest top and bottom to samples 0 and 3 in the 4x fallback. + alpha_to_coverage_host_sample_0 = 0; + alpha_to_coverage_host_sample_1 = 3; + } + } + spv::Id alpha_to_coverage_mask_2x = alpha_to_coverage_apply_sample( + alpha_to_coverage_mask, 0, alpha_to_coverage_host_sample_0, 0.5f, 1.0f / 8.0f); + alpha_to_coverage_mask_2x = alpha_to_coverage_apply_sample( + alpha_to_coverage_mask_2x, 1, alpha_to_coverage_host_sample_1, 1.0f, 1.0f / 8.0f); + builder_->createBranch(&block_alpha_to_coverage_msaa_merge); + // 4x. + builder_->setBuildPoint(&block_alpha_to_coverage_msaa_4x); + uint32_t alpha_to_coverage_host_sample_4x_0 = 0; + uint32_t alpha_to_coverage_host_sample_4x_1 = 1; + uint32_t alpha_to_coverage_host_sample_4x_2 = 2; + uint32_t alpha_to_coverage_host_sample_4x_3 = 3; + if (!edram_fragment_shader_interlock_) { + // Guest TL, BL, TR, BR to Vulkan TL, TR, BL, BR sample indices. + alpha_to_coverage_host_sample_4x_0 = 0; + alpha_to_coverage_host_sample_4x_1 = 2; + alpha_to_coverage_host_sample_4x_2 = 1; + alpha_to_coverage_host_sample_4x_3 = 3; + } + spv::Id alpha_to_coverage_mask_4x = alpha_to_coverage_apply_sample( + alpha_to_coverage_mask, 0, alpha_to_coverage_host_sample_4x_0, 0.75f, 1.0f / 16.0f); + alpha_to_coverage_mask_4x = alpha_to_coverage_apply_sample( + alpha_to_coverage_mask_4x, 1, alpha_to_coverage_host_sample_4x_1, 0.25f, 1.0f / 16.0f); + alpha_to_coverage_mask_4x = alpha_to_coverage_apply_sample( + alpha_to_coverage_mask_4x, 2, alpha_to_coverage_host_sample_4x_2, 0.5f, 1.0f / 16.0f); + alpha_to_coverage_mask_4x = alpha_to_coverage_apply_sample( + alpha_to_coverage_mask_4x, 3, alpha_to_coverage_host_sample_4x_3, 1.0f, 1.0f / 16.0f); + builder_->createBranch(&block_alpha_to_coverage_msaa_merge); + // Select depending on the MSAA sample count. + builder_->setBuildPoint(&block_alpha_to_coverage_msaa_merge); + id_vector_temp_.clear(); + id_vector_temp_.reserve(2 * 3); + id_vector_temp_.push_back(alpha_to_coverage_mask_1x); + id_vector_temp_.push_back(block_alpha_to_coverage_msaa_1x.getId()); + id_vector_temp_.push_back(alpha_to_coverage_mask_2x); + id_vector_temp_.push_back(block_alpha_to_coverage_msaa_2x.getId()); + id_vector_temp_.push_back(alpha_to_coverage_mask_4x); + id_vector_temp_.push_back(block_alpha_to_coverage_msaa_4x.getId()); + alpha_to_coverage_mask = builder_->createOp(spv::OpPhi, type_uint_, id_vector_temp_); + if (edram_fragment_shader_interlock_) { + fsi_sample_mask_in_rt_0_alpha_tests = alpha_to_coverage_mask; + } else { + SpirvBuilder::IfBuilder alpha_to_coverage_kill_if( + builder_->createBinOp(spv::OpIEqual, type_bool_, alpha_to_coverage_mask, + const_uint_0_), + spv::SelectionControlDontFlattenMask, *builder_); + // TODO(Triang3l): Use OpTerminateInvocation when SPIR-V 1.6 is + // targeted. + builder_->createNoResultOp(spv::OpKill); + // OpKill terminates the block. + alpha_to_coverage_kill_if.makeEndIf(false); + id_vector_temp_.clear(); + id_vector_temp_.push_back(const_int_0_); + builder_->createStore( + builder_->createUnaryOp(spv::OpBitcast, type_int_, alpha_to_coverage_mask), + builder_->createAccessChain(spv::StorageClassOutput, output_fragment_sample_mask_, + id_vector_temp_)); + } + } + if_alpha_to_coverage_enabled.makeEndIf(); + } + + if (edram_fragment_shader_interlock_) { + // Close the render target 0 written check. + builder_->createBranch(block_fsi_rt_0_alpha_tests_rt_written_merge); + spv::Block& block_fsi_rt_0_alpha_tests_rt_written_end = *builder_->getBuildPoint(); + builder_->setBuildPoint(block_fsi_rt_0_alpha_tests_rt_written_merge); + if (!features_.demote_to_helper_invocation) { + // The tests might have modified the sample mask via + // fsi_sample_mask_in_rt_0_alpha_tests. + id_vector_temp_.clear(); + id_vector_temp_.push_back(fsi_sample_mask_in_rt_0_alpha_tests); + id_vector_temp_.push_back(block_fsi_rt_0_alpha_tests_rt_written_end.getId()); + id_vector_temp_.push_back(main_fsi_sample_mask_); + id_vector_temp_.push_back(block_fsi_rt_0_alpha_tests_rt_written_head->getId()); + main_fsi_sample_mask_ = builder_->createOp(spv::OpPhi, type_uint_, id_vector_temp_); + } + } + } + + spv::Block* block_fsi_if_after_kill = nullptr; + spv::Block* block_fsi_if_after_kill_merge = nullptr; + + spv::Block* block_fsi_if_after_depth_stencil = nullptr; + spv::Block* block_fsi_if_after_depth_stencil_merge = nullptr; + + if (edram_fragment_shader_interlock_) { + if (fsi_pixel_potentially_killed) { + if (features_.demote_to_helper_invocation) { + // Don't do anything related to writing to the EDRAM if the pixel was + // killed. + id_vector_temp_.clear(); + // TODO(Triang3l): Use HelperInvocation volatile load on SPIR-V 1.6. + main_fsi_sample_mask_ = builder_->createTriOp( + spv::OpSelect, type_uint_, + builder_->createOp(spv::OpIsHelperInvocationEXT, type_bool_, id_vector_temp_), + const_uint_0_, main_fsi_sample_mask_); + } + // Check the condition before the OpSelectionMerge, which must be the + // penultimate instruction in a block. + spv::Id pixel_not_killed = + builder_->createBinOp(spv::OpINotEqual, type_bool_, main_fsi_sample_mask_, const_uint_0_); + block_fsi_if_after_kill = &builder_->makeNewBlock(); + block_fsi_if_after_kill_merge = &builder_->makeNewBlock(); + builder_->createSelectionMerge(block_fsi_if_after_kill_merge, + spv::SelectionControlDontFlattenMask); + builder_->createConditionalBranch(pixel_not_killed, block_fsi_if_after_kill, + block_fsi_if_after_kill_merge); + builder_->setBuildPoint(block_fsi_if_after_kill); + } + + spv::Id color_write_depth_stencil_condition = spv::NoResult; + if (FSI_IsDepthStencilEarly()) { + // Perform late depth / stencil writes for samples not discarded. + for (uint32_t i = 0; i < 4; ++i) { + spv::Id sample_late_depth_stencil_write_needed = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_fsi_sample_mask_, + builder_->makeUintConstant(uint32_t(1) << (4 + i))), + const_uint_0_); + SpirvBuilder::IfBuilder if_sample_late_depth_stencil_write_needed( + sample_late_depth_stencil_write_needed, spv::SelectionControlDontFlattenMask, + *builder_); + spv::Id depth_stencil_sample_address = FSI_AddSampleOffset(main_fsi_address_depth_, i); + id_vector_temp_.clear(); + // First SSBO structure element. + id_vector_temp_.push_back(const_int_0_); + id_vector_temp_.push_back(depth_stencil_sample_address); + builder_->createStore(main_fsi_late_write_depth_stencil_[i], + builder_->createAccessChain(features_.spirv_version >= spv::Spv_1_3 + ? spv::StorageClassStorageBuffer + : spv::StorageClassUniform, + buffer_edram_, id_vector_temp_)); + if_sample_late_depth_stencil_write_needed.makeEndIf(); + } + if (color_targets_written) { + // Only take the remaining coverage bits, not the late depth / stencil + // write bits, into account in the check whether anything needs to be + // done for the color targets. + color_write_depth_stencil_condition = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_fsi_sample_mask_, + builder_->makeUintConstant((uint32_t(1) << 4) - 1)), + const_uint_0_); + } + } else { + if (msaa_samples == spv::NoResult) { + msaa_samples = LoadMsaaSamplesFromFlags(); + } + FSI_LoadEdramOffsets(msaa_samples); + // Begin the critical section on the outermost control flow level so it's + // entered exactly once on any control flow path as required by the SPIR-V + // extension specification. + builder_->createNoResultOp(spv::OpBeginInvocationInterlockEXT); + // Do the depth / stencil test. + // The sample mask might have been made narrower than the initially loaded + // mask by various conditions that discard the whole pixel, as well as by + // alpha to coverage. + FSI_DepthStencilTest(msaa_samples, + fsi_pixel_potentially_killed || (color_targets_written & 0b1)); + if (color_targets_written) { + // Only bits 0:3 of main_fsi_sample_mask_ are written by the late + // depth / stencil test. + color_write_depth_stencil_condition = builder_->createBinOp( + spv::OpINotEqual, type_bool_, main_fsi_sample_mask_, const_uint_0_); + } + } + + if (color_write_depth_stencil_condition != spv::NoResult) { + // Skip all color operations if the pixel has failed the tests entirely. + block_fsi_if_after_depth_stencil = &builder_->makeNewBlock(); + block_fsi_if_after_depth_stencil_merge = &builder_->makeNewBlock(); + builder_->createSelectionMerge(block_fsi_if_after_depth_stencil_merge, + spv::SelectionControlDontFlattenMask); + builder_->createConditionalBranch(color_write_depth_stencil_condition, + block_fsi_if_after_depth_stencil, + block_fsi_if_after_depth_stencil_merge); + builder_->setBuildPoint(block_fsi_if_after_depth_stencil); + } + } + + if (color_targets_written) { + spv::Id fsi_color_targets_written = spv::NoResult; + spv::Id fsi_const_int_1 = spv::NoResult; + spv::Id fsi_const_edram_size_dwords = spv::NoResult; + spv::Id fsi_samples_covered[4] = {}; + if (edram_fragment_shader_interlock_) { + fsi_color_targets_written = + builder_->createLoad(var_main_fsi_color_written_, spv::NoPrecision); + fsi_const_int_1 = builder_->makeIntConstant(1); + uint32_t tile_width = xenos::kEdramTileWidthSamples * draw_resolution_scale_x_; + uint32_t tile_height = xenos::kEdramTileHeightSamples * draw_resolution_scale_y_; + fsi_const_edram_size_dwords = + builder_->makeUintConstant(tile_width * tile_height * xenos::kEdramTileCount); + for (uint32_t i = 0; i < 4; ++i) { + fsi_samples_covered[i] = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_fsi_sample_mask_, + builder_->makeUintConstant(uint32_t(1) << i)), + const_uint_0_); + } + } + uint32_t color_targets_remaining = color_targets_written; + uint32_t color_target_index; + while (rex::bit_scan_forward(color_targets_remaining, &color_target_index)) { + color_targets_remaining &= ~(UINT32_C(1) << color_target_index); + spv::Id color_variable = output_or_var_fragment_data_[color_target_index]; + spv::Id color = builder_->createLoad(color_variable, spv::NoPrecision); + + // Apply the exponent bias after the alpha test and alpha to coverage + // because they need the unbiased alpha from the shader. + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantColorExpBias)); + id_vector_temp_.push_back(builder_->makeIntConstant(int32_t(color_target_index))); + color = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float4_, color, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision)); + + if (edram_fragment_shader_interlock_) { + // Write the color to the target in the EDRAM only it was written on the + // shader's execution path, according to the Direct3D 9 rules that games + // rely on. + spv::Id fsi_color_written = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, fsi_color_targets_written, + builder_->makeUintConstant(uint32_t(1) << color_target_index)), + const_uint_0_); + // More likely to write to the render target than not. + SpirvBuilder::IfBuilder if_fsi_color_written( + fsi_color_written, spv::SelectionControlDontFlattenMask, *builder_, 2, 1); + + // For accessing uint2 arrays of per-render-target data which are passed + // as uint4 arrays due to std140 array element alignment. + spv::Id rt_uint2_index_array = builder_->makeIntConstant(color_target_index >> 1); + spv::Id rt_uint2_index_element[] = { + builder_->makeIntConstant((color_target_index & 1) << 1), + builder_->makeIntConstant(((color_target_index & 1) << 1) + 1), + }; + + // Load the mask of the bits of the destination color that should be + // preserved (in 32-bit halves), which are 0, 0 if the color is fully + // overwritten, or UINT32_MAX, UINT32_MAX if writing to the target is + // disabled completely. + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantEdramRTKeepMask)); + id_vector_temp_.push_back(rt_uint2_index_array); + id_vector_temp_.push_back(rt_uint2_index_element[0]); + spv::Id rt_keep_mask[2]; + rt_keep_mask[0] = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + id_vector_temp_.back() = rt_uint2_index_element[1]; + rt_keep_mask[1] = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + + // Check if writing to the render target is not disabled completely. + spv::Id const_uint32_max = builder_->makeUintConstant(UINT32_MAX); + spv::Id rt_write_mask_not_empty = builder_->createBinOp( + spv::OpLogicalOr, type_bool_, + builder_->createBinOp(spv::OpINotEqual, type_bool_, rt_keep_mask[0], const_uint32_max), + builder_->createBinOp(spv::OpINotEqual, type_bool_, rt_keep_mask[1], const_uint32_max)); + SpirvBuilder::IfBuilder if_rt_write_mask_not_empty( + rt_write_mask_not_empty, spv::SelectionControlDontFlattenMask, *builder_); + + spv::Id const_int_rt_index = builder_->makeIntConstant(color_target_index); + + // Load the information about the render target. + + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantEdramRTFormatFlags)); + id_vector_temp_.push_back(const_int_rt_index); + spv::Id rt_format_with_flags = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + + spv::Id rt_is_64bpp = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp( + spv::OpBitwiseAnd, type_uint_, rt_format_with_flags, + builder_->makeUintConstant(RenderTargetCache::kPSIColorFormatFlag_64bpp)), + const_uint_0_); + + id_vector_temp_.clear(); + id_vector_temp_.push_back( + builder_->makeIntConstant(kSystemConstantEdramRTBaseDwordsScaled)); + id_vector_temp_.push_back(const_int_rt_index); + // EDRAM addresses are wrapped on the Xenos (modulo the EDRAM size). + spv::Id rt_sample_0_address = builder_->createUnaryOp( + spv::OpBitcast, type_int_, + builder_->createBinOp( + spv::OpUMod, type_uint_, + builder_->createBinOp( + spv::OpIAdd, type_uint_, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, + uniform_system_constants_, id_vector_temp_), + spv::NoPrecision), + builder_->createTriOp(spv::OpSelect, type_uint_, rt_is_64bpp, + main_fsi_offset_64bpp_, main_fsi_offset_32bpp_)), + fsi_const_edram_size_dwords)); + + // Load the blending parameters for the render target. + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantEdramRTBlendFactorsOps)); + id_vector_temp_.push_back(const_int_rt_index); + spv::Id rt_blend_factors_equations = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + + // Check if blending (the blending is not 1 * source + 0 * destination). + spv::Id rt_blend_enabled = + builder_->createBinOp(spv::OpINotEqual, type_bool_, rt_blend_factors_equations, + builder_->makeUintConstant(0x00010001)); + SpirvBuilder::IfBuilder if_rt_blend_enabled( + rt_blend_enabled, spv::SelectionControlDontFlattenMask, *builder_); + { + // Blending path. + + // Get various parameters used in blending. + spv::Id rt_color_is_fixed_point = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, rt_format_with_flags, + builder_->makeUintConstant( + RenderTargetCache::kPSIColorFormatFlag_FixedPointColor)), + const_uint_0_); + spv::Id rt_alpha_is_fixed_point = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, rt_format_with_flags, + builder_->makeUintConstant( + RenderTargetCache::kPSIColorFormatFlag_FixedPointAlpha)), + const_uint_0_); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantEdramRTClamp)); + id_vector_temp_.push_back(const_int_rt_index); + spv::Id rt_clamp = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + spv::Id rt_clamp_color_min = builder_->smearScalar( + spv::NoPrecision, builder_->createCompositeExtract(rt_clamp, type_float_, 0), + type_float3_); + spv::Id rt_clamp_alpha_min = builder_->createCompositeExtract(rt_clamp, type_float_, 1); + spv::Id rt_clamp_color_max = builder_->smearScalar( + spv::NoPrecision, builder_->createCompositeExtract(rt_clamp, type_float_, 2), + type_float3_); + spv::Id rt_clamp_alpha_max = builder_->createCompositeExtract(rt_clamp, type_float_, 3); + + spv::Id blend_factor_width = builder_->makeUintConstant(5); + spv::Id blend_equation_width = builder_->makeUintConstant(3); + spv::Id rt_color_source_factor = + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, rt_blend_factors_equations, + const_uint_0_, blend_factor_width); + spv::Id rt_color_equation = + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, rt_blend_factors_equations, + blend_factor_width, blend_equation_width); + spv::Id rt_color_dest_factor = + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, rt_blend_factors_equations, + builder_->makeUintConstant(8), blend_factor_width); + spv::Id rt_alpha_source_factor = + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, rt_blend_factors_equations, + builder_->makeUintConstant(16), blend_factor_width); + spv::Id rt_alpha_equation = + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, rt_blend_factors_equations, + builder_->makeUintConstant(21), blend_equation_width); + spv::Id rt_alpha_dest_factor = + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, rt_blend_factors_equations, + builder_->makeUintConstant(24), blend_factor_width); + + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantEdramBlendConstant)); + spv::Id blend_constant_unclamped = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + uint_vector_temp_.clear(); + uint_vector_temp_.push_back(0); + uint_vector_temp_.push_back(1); + uint_vector_temp_.push_back(2); + spv::Id blend_constant_color_unclamped = builder_->createRvalueSwizzle( + spv::NoPrecision, type_float3_, blend_constant_unclamped, uint_vector_temp_); + spv::Id blend_constant_color_clamped = FSI_FlushNaNClampAndInBlending( + blend_constant_color_unclamped, rt_color_is_fixed_point, rt_clamp_color_min, + rt_clamp_color_max); + spv::Id blend_constant_alpha_clamped = FSI_FlushNaNClampAndInBlending( + builder_->createCompositeExtract(blend_constant_unclamped, type_float_, 3), + rt_alpha_is_fixed_point, rt_clamp_alpha_min, rt_clamp_alpha_max); + + uint_vector_temp_.clear(); + uint_vector_temp_.push_back(0); + uint_vector_temp_.push_back(1); + uint_vector_temp_.push_back(2); + spv::Id source_color_unclamped = builder_->createRvalueSwizzle( + spv::NoPrecision, type_float3_, color, uint_vector_temp_); + spv::Id source_color_clamped = + FSI_FlushNaNClampAndInBlending(source_color_unclamped, rt_color_is_fixed_point, + rt_clamp_color_min, rt_clamp_color_max); + spv::Id source_alpha_clamped = FSI_FlushNaNClampAndInBlending( + builder_->createCompositeExtract(color, type_float_, 3), rt_alpha_is_fixed_point, + rt_clamp_alpha_min, rt_clamp_alpha_max); + + std::array rt_replace_mask; + for (uint32_t i = 0; i < 2; ++i) { + rt_replace_mask[i] = builder_->createUnaryOp(spv::OpNot, type_uint_, rt_keep_mask[i]); + } + + // Blend and mask each sample. + for (uint32_t i = 0; i < 4; ++i) { + SpirvBuilder::IfBuilder if_sample_covered( + fsi_samples_covered[i], spv::SelectionControlDontFlattenMask, *builder_); + + spv::Id rt_sample_address = FSI_AddSampleOffset(rt_sample_0_address, i, rt_is_64bpp); + id_vector_temp_.clear(); + // First SSBO structure element. + id_vector_temp_.push_back(const_int_0_); + id_vector_temp_.push_back(rt_sample_address); + spv::Id rt_access_chain_0 = builder_->createAccessChain( + features_.spirv_version >= spv::Spv_1_3 ? spv::StorageClassStorageBuffer + : spv::StorageClassUniform, + buffer_edram_, id_vector_temp_); + id_vector_temp_.back() = + builder_->createBinOp(spv::OpIAdd, type_int_, rt_sample_address, fsi_const_int_1); + spv::Id rt_access_chain_1 = builder_->createAccessChain( + features_.spirv_version >= spv::Spv_1_3 ? spv::StorageClassStorageBuffer + : spv::StorageClassUniform, + buffer_edram_, id_vector_temp_); + + // Load the destination color. + std::array dest_packed; + dest_packed[0] = builder_->createLoad(rt_access_chain_0, spv::NoPrecision); + { + SpirvBuilder::IfBuilder if_64bpp(rt_is_64bpp, spv::SelectionControlDontFlattenMask, + *builder_); + spv::Id dest_packed_64bpp_high = + builder_->createLoad(rt_access_chain_1, spv::NoPrecision); + if_64bpp.makeEndIf(); + dest_packed[1] = if_64bpp.createMergePhi(dest_packed_64bpp_high, const_uint_0_); + } + std::array dest_unpacked = + FSI_UnpackColor(dest_packed, rt_format_with_flags); + id_vector_temp_.clear(); + id_vector_temp_.push_back(dest_unpacked[0]); + id_vector_temp_.push_back(dest_unpacked[1]); + id_vector_temp_.push_back(dest_unpacked[2]); + spv::Id dest_color = builder_->createCompositeConstruct(type_float3_, id_vector_temp_); + + // Blend the components. + spv::Id result_color = FSI_BlendColorOrAlphaWithUnclampedResult( + rt_color_is_fixed_point, rt_clamp_color_min, rt_clamp_color_max, + source_color_clamped, source_alpha_clamped, dest_color, dest_unpacked[3], + blend_constant_color_clamped, blend_constant_alpha_clamped, rt_color_equation, + rt_color_source_factor, rt_color_dest_factor); + spv::Id result_alpha = FSI_BlendColorOrAlphaWithUnclampedResult( + rt_alpha_is_fixed_point, rt_clamp_alpha_min, rt_clamp_alpha_max, spv::NoResult, + source_alpha_clamped, spv::NoResult, dest_unpacked[3], spv::NoResult, + blend_constant_alpha_clamped, rt_alpha_equation, rt_alpha_source_factor, + rt_alpha_dest_factor); + + // Pack and store the result. + // Bypass the `getNumTypeConstituents(typeId) == + // (int)constituents.size()` assertion in createCompositeConstruct, + // OpCompositeConstruct can construct vectors not only from scalars, + // but also from other vectors. + spv::Id result_float4; + { + std::unique_ptr result_composite_construct_op = + std::make_unique(builder_->getUniqueId(), type_float4_, + spv::OpCompositeConstruct); + result_composite_construct_op->addIdOperand(result_color); + result_composite_construct_op->addIdOperand(result_alpha); + result_float4 = result_composite_construct_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(result_composite_construct_op)); + } + std::array result_packed = + FSI_ClampAndPackColor(result_float4, rt_format_with_flags); + builder_->createStore( + builder_->createBinOp(spv::OpBitwiseOr, type_uint_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, + dest_packed[0], rt_keep_mask[0]), + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, + result_packed[0], rt_replace_mask[0])), + rt_access_chain_0); + SpirvBuilder::IfBuilder if_64bpp(rt_is_64bpp, spv::SelectionControlDontFlattenMask, + *builder_); + { + builder_->createStore( + builder_->createBinOp( + spv::OpBitwiseOr, type_uint_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, dest_packed[1], + rt_keep_mask[1]), + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, result_packed[1], + rt_replace_mask[1])), + rt_access_chain_1); + } + if_64bpp.makeEndIf(); + + if_sample_covered.makeEndIf(); + } + } + if_rt_blend_enabled.makeBeginElse(); + { + // Non-blending paths. + + // Pack the new color for all samples. + std::array color_packed = FSI_ClampAndPackColor(color, rt_format_with_flags); + + // Check if need to load the original contents. + spv::Id rt_keep_mask_not_empty = builder_->createBinOp( + spv::OpLogicalOr, type_bool_, + builder_->createBinOp(spv::OpINotEqual, type_bool_, rt_keep_mask[0], const_uint_0_), + builder_->createBinOp(spv::OpINotEqual, type_bool_, rt_keep_mask[1], const_uint_0_)); + + SpirvBuilder::IfBuilder if_rt_keep_mask_not_empty( + rt_keep_mask_not_empty, spv::SelectionControlDontFlattenMask, *builder_); + { + // Loading and masking path. + std::array color_packed_masked; + for (uint32_t i = 0; i < 2; ++i) { + color_packed_masked[i] = builder_->createBinOp( + spv::OpBitwiseAnd, type_uint_, color_packed[i], + builder_->createUnaryOp(spv::OpNot, type_uint_, rt_keep_mask[i])); + } + for (uint32_t i = 0; i < 4; ++i) { + SpirvBuilder::IfBuilder if_sample_covered( + fsi_samples_covered[i], spv::SelectionControlDontFlattenMask, *builder_); + spv::Id rt_sample_address = FSI_AddSampleOffset(rt_sample_0_address, i, rt_is_64bpp); + id_vector_temp_.clear(); + // First SSBO structure element. + id_vector_temp_.push_back(const_int_0_); + id_vector_temp_.push_back(rt_sample_address); + spv::Id rt_access_chain_0 = builder_->createAccessChain( + features_.spirv_version >= spv::Spv_1_3 ? spv::StorageClassStorageBuffer + : spv::StorageClassUniform, + buffer_edram_, id_vector_temp_); + builder_->createStore( + builder_->createBinOp( + spv::OpBitwiseOr, type_uint_, + builder_->createBinOp( + spv::OpBitwiseAnd, type_uint_, + builder_->createLoad(rt_access_chain_0, spv::NoPrecision), + rt_keep_mask[0]), + color_packed_masked[0]), + rt_access_chain_0); + SpirvBuilder::IfBuilder if_64bpp(rt_is_64bpp, spv::SelectionControlDontFlattenMask, + *builder_); + { + id_vector_temp_.back() = builder_->createBinOp(spv::OpIAdd, type_int_, + rt_sample_address, fsi_const_int_1); + spv::Id rt_access_chain_1 = builder_->createAccessChain( + features_.spirv_version >= spv::Spv_1_3 ? spv::StorageClassStorageBuffer + : spv::StorageClassUniform, + buffer_edram_, id_vector_temp_); + builder_->createStore( + builder_->createBinOp( + spv::OpBitwiseOr, type_uint_, + builder_->createBinOp( + spv::OpBitwiseAnd, type_uint_, + builder_->createLoad(rt_access_chain_1, spv::NoPrecision), + rt_keep_mask[1]), + color_packed_masked[1]), + rt_access_chain_1); + } + if_64bpp.makeEndIf(); + if_sample_covered.makeEndIf(); + } + } + if_rt_keep_mask_not_empty.makeBeginElse(); + { + // Fully overwriting path. + for (uint32_t i = 0; i < 4; ++i) { + SpirvBuilder::IfBuilder if_sample_covered( + fsi_samples_covered[i], spv::SelectionControlDontFlattenMask, *builder_); + spv::Id rt_sample_address = FSI_AddSampleOffset(rt_sample_0_address, i, rt_is_64bpp); + id_vector_temp_.clear(); + // First SSBO structure element. + id_vector_temp_.push_back(const_int_0_); + id_vector_temp_.push_back(rt_sample_address); + builder_->createStore(color_packed[0], builder_->createAccessChain( + features_.spirv_version >= spv::Spv_1_3 + ? spv::StorageClassStorageBuffer + : spv::StorageClassUniform, + buffer_edram_, id_vector_temp_)); + SpirvBuilder::IfBuilder if_64bpp(rt_is_64bpp, spv::SelectionControlDontFlattenMask, + *builder_); + { + id_vector_temp_.back() = builder_->createBinOp( + spv::OpIAdd, type_int_, id_vector_temp_.back(), fsi_const_int_1); + builder_->createStore(color_packed[1], builder_->createAccessChain( + features_.spirv_version >= spv::Spv_1_3 + ? spv::StorageClassStorageBuffer + : spv::StorageClassUniform, + buffer_edram_, id_vector_temp_)); + } + if_64bpp.makeEndIf(); + if_sample_covered.makeEndIf(); + } + } + if_rt_keep_mask_not_empty.makeEndIf(); + } + if_rt_blend_enabled.makeEndIf(); + + if_rt_write_mask_not_empty.makeEndIf(); + if_fsi_color_written.makeEndIf(); + } else { + // Convert to gamma space - this is incorrect, since it must be done + // after blending on the Xbox 360, but this is just one of many blending + // issues in the host render target path. + // Keep parity with D3D12: use explicit Xenos PWL gamma conversion in + // shader code for gamma render targets in this path, rather than host + // sRGB attachment conversion behavior. + uint_vector_temp_.clear(); + uint_vector_temp_.push_back(0); + uint_vector_temp_.push_back(1); + uint_vector_temp_.push_back(2); + spv::Id color_rgb = + builder_->createRvalueSwizzle(spv::NoPrecision, type_float3_, color, uint_vector_temp_); + spv::Id is_gamma = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp( + spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(kSysFlag_ConvertColor0ToGamma << color_target_index)), + const_uint_0_); + SpirvBuilder::IfBuilder if_gamma(is_gamma, spv::SelectionControlDontFlattenMask, *builder_); + spv::Id color_rgb_gamma = LinearToPWLGamma(color_rgb, false); + if_gamma.makeEndIf(); + color_rgb = if_gamma.createMergePhi(color_rgb_gamma, color_rgb); + { + std::unique_ptr color_rgba_shuffle_op = + std::make_unique(builder_->getUniqueId(), type_float4_, + spv::OpVectorShuffle); + color_rgba_shuffle_op->addIdOperand(color_rgb); + color_rgba_shuffle_op->addIdOperand(color); + color_rgba_shuffle_op->addImmediateOperand(0); + color_rgba_shuffle_op->addImmediateOperand(1); + color_rgba_shuffle_op->addImmediateOperand(2); + color_rgba_shuffle_op->addImmediateOperand(3 + 3); + color = color_rgba_shuffle_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(color_rgba_shuffle_op)); + } + + builder_->createStore(color, color_variable); + } + } + } + + if (!edram_fragment_shader_interlock_ && output_fragment_depth_ != spv::NoResult) { + Modification::DepthStencilMode depth_stencil_mode = + GetSpirvShaderModification().pixel.depth_stencil_mode; + if (depth_stencil_mode == Modification::DepthStencilMode::kFloat24Truncating || + depth_stencil_mode == Modification::DepthStencilMode::kFloat24Rounding) { + // For oDepth, depth is already in guest [0, 1]. + // Without oDepth, reconstruct guest [0, 1] from host [0, 0.5] by + // doubling gl_FragCoord.z and saturating. + spv::Id depth; + if (current_shader().writes_depth()) { + depth = builder_->createLoad(output_fragment_depth_, spv::NoPrecision); + } else { + assert_true(input_fragment_coordinates_ != spv::NoResult); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(2)); + depth = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassInput, input_fragment_coordinates_, + id_vector_temp_), + spv::NoPrecision); + if (IsSampleRate()) { + // Statically use gl_SampleID to keep this path at sample frequency. + assert_true(input_sample_id_ != spv::NoResult); + builder_->createLoad(input_sample_id_, spv::NoPrecision); + } + depth = builder_->createTriBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450NClamp, + builder_->createNoContractionBinOp(spv::OpFMul, type_float_, depth, + builder_->makeFloatConstant(2.0f)), + const_float_0_, const_float_1_); + } + // Convert guest [0, 1] float32 to float24 and back to host [0, 0.5]. + spv::Id depth_float24 = SpirvShaderTranslator::PreClampedDepthTo20e4( + *builder_, depth, depth_stencil_mode == Modification::DepthStencilMode::kFloat24Rounding, + false, ext_inst_glsl_std_450_); + depth = SpirvShaderTranslator::Depth20e4To32(*builder_, depth_float24, 0, true, false, + ext_inst_glsl_std_450_); + builder_->createStore(depth, output_fragment_depth_); + } + } + + if (edram_fragment_shader_interlock_) { + if (block_fsi_if_after_depth_stencil_merge) { + builder_->createBranch(block_fsi_if_after_depth_stencil_merge); + builder_->setBuildPoint(block_fsi_if_after_depth_stencil_merge); + } + + if (block_fsi_if_after_kill_merge) { + builder_->createBranch(block_fsi_if_after_kill_merge); + builder_->setBuildPoint(block_fsi_if_after_kill_merge); + } + + if (FSI_IsDepthStencilEarly()) { + builder_->createBranch(main_fsi_early_depth_stencil_execute_quad_merge_); + builder_->setBuildPoint(main_fsi_early_depth_stencil_execute_quad_merge_); + } + + builder_->createNoResultOp(spv::OpEndInvocationInterlockEXT); + } +} + +spv::Id SpirvShaderTranslator::LoadMsaaSamplesFromFlags() { + return builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(kSysFlag_MsaaSamples_Shift), + builder_->makeUintConstant(2)); +} + +void SpirvShaderTranslator::FSI_LoadSampleMask(spv::Id msaa_samples) { + // On the Xbox 360, 2x MSAA doubles the storage height, 4x MSAA doubles the + // storage width. + // Vulkan standard 2x samples are bottom, top. + // Vulkan standard 4x samples are TL, TR, BL, BR. + // Remap to T, B for 2x, and to TL, BL, TR, BR for 4x. + // 2x corresponds to 1, 0 with native 2x MSAA on Vulkan, 0, 3 with 2x as 4x. + // 4x corresponds to 0, 2, 1, 3 on Vulkan. + + spv::Id const_uint_1 = builder_->makeUintConstant(1); + spv::Id const_uint_2 = builder_->makeUintConstant(2); + + assert_true(input_sample_mask_ != spv::NoResult); + id_vector_temp_.clear(); + id_vector_temp_.push_back(const_int_0_); + spv::Id input_sample_mask_value = builder_->createUnaryOp( + spv::OpBitcast, type_uint_, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassInput, input_sample_mask_, id_vector_temp_), + spv::NoPrecision)); + + spv::Block& block_msaa_head = *builder_->getBuildPoint(); + spv::Block& block_msaa_1x = builder_->makeNewBlock(); + spv::Block& block_msaa_2x = builder_->makeNewBlock(); + spv::Block& block_msaa_4x = builder_->makeNewBlock(); + spv::Block& block_msaa_merge = builder_->makeNewBlock(); + builder_->createSelectionMerge(&block_msaa_merge, spv::SelectionControlDontFlattenMask); + { + std::unique_ptr msaa_switch_op = + std::make_unique(spv::OpSwitch); + msaa_switch_op->addIdOperand(msaa_samples); + // Make 1x the default. + msaa_switch_op->addIdOperand(block_msaa_1x.getId()); + msaa_switch_op->addImmediateOperand(int32_t(xenos::MsaaSamples::k2X)); + msaa_switch_op->addIdOperand(block_msaa_2x.getId()); + msaa_switch_op->addImmediateOperand(int32_t(xenos::MsaaSamples::k4X)); + msaa_switch_op->addIdOperand(block_msaa_4x.getId()); + builder_->getBuildPoint()->addInstruction(std::move(msaa_switch_op)); + } + block_msaa_1x.addPredecessor(&block_msaa_head); + block_msaa_2x.addPredecessor(&block_msaa_head); + block_msaa_4x.addPredecessor(&block_msaa_head); + + // 1x MSAA - pass input_sample_mask_value through. + builder_->setBuildPoint(&block_msaa_1x); + builder_->createBranch(&block_msaa_merge); + + // 2x MSAA. + builder_->setBuildPoint(&block_msaa_2x); + spv::Id sample_mask_2x; + if (native_2x_msaa_no_attachments_) { + // 1 and 0 to 0 and 1. + sample_mask_2x = builder_->createBinOp( + spv::OpShiftRightLogical, type_uint_, + builder_->createUnaryOp(spv::OpBitReverse, type_uint_, input_sample_mask_value), + builder_->makeUintConstant(32 - 2)); + } else { + // 0 and 3 to 0 and 1. + sample_mask_2x = builder_->createQuadOp( + spv::OpBitFieldInsert, type_uint_, input_sample_mask_value, + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, input_sample_mask_value, + const_uint_2, const_uint_1), + const_uint_1, builder_->makeUintConstant(32 - 1)); + } + builder_->createBranch(&block_msaa_merge); + + // 4x MSAA. + builder_->setBuildPoint(&block_msaa_4x); + // Flip samples in bits 0:1 by reversing the whole coverage mask and inserting + // the reversing bits. + spv::Id sample_mask_4x = builder_->createQuadOp( + spv::OpBitFieldInsert, type_uint_, input_sample_mask_value, + builder_->createBinOp( + spv::OpShiftRightLogical, type_uint_, + builder_->createUnaryOp(spv::OpBitReverse, type_uint_, input_sample_mask_value), + builder_->makeUintConstant(32 - 1 - 2)), + const_uint_1, const_uint_2); + builder_->createBranch(&block_msaa_merge); + + // Select the result depending on the MSAA sample count. + builder_->setBuildPoint(&block_msaa_merge); + id_vector_temp_.clear(); + id_vector_temp_.reserve(2 * 3); + id_vector_temp_.push_back(input_sample_mask_value); + id_vector_temp_.push_back(block_msaa_1x.getId()); + id_vector_temp_.push_back(sample_mask_2x); + id_vector_temp_.push_back(block_msaa_2x.getId()); + id_vector_temp_.push_back(sample_mask_4x); + id_vector_temp_.push_back(block_msaa_4x.getId()); + main_fsi_sample_mask_ = builder_->createOp(spv::OpPhi, type_uint_, id_vector_temp_); +} + +void SpirvShaderTranslator::FSI_LoadEdramOffsets(spv::Id msaa_samples) { + // Convert the floating-point pixel coordinates to integer sample 0 + // coordinates. + assert_true(input_fragment_coordinates_ != spv::NoResult); + spv::Id axes_have_two_msaa_samples[2]; + spv::Id sample_coordinates[2]; + spv::Id const_uint_1 = builder_->makeUintConstant(1); + for (uint32_t i = 0; i < 2; ++i) { + spv::Id axis_has_two_msaa_samples = + builder_->createBinOp(spv::OpUGreaterThanEqual, type_bool_, msaa_samples, + builder_->makeUintConstant( + uint32_t(i ? xenos::MsaaSamples::k2X : xenos::MsaaSamples::k4X))); + axes_have_two_msaa_samples[i] = axis_has_two_msaa_samples; + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(int32_t(i))); + sample_coordinates[i] = builder_->createBinOp( + spv::OpShiftLeftLogical, type_uint_, + builder_->createUnaryOp( + spv::OpConvertFToU, type_uint_, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassInput, input_fragment_coordinates_, + id_vector_temp_), + spv::NoPrecision)), + builder_->createTriOp(spv::OpSelect, type_uint_, axis_has_two_msaa_samples, const_uint_1, + const_uint_0_)); + } + + // Get 40 x 16 x resolution scale 32bpp half-tile or 40x16 64bpp tile index. + // Working with 40x16-sample portions for 64bpp and for swapping for depth - + // dividing by 40, not by 80. + uint32_t tile_width = xenos::kEdramTileWidthSamples * draw_resolution_scale_x_; + spv::Id const_tile_half_width = builder_->makeUintConstant(tile_width >> 1); + uint32_t tile_height = xenos::kEdramTileHeightSamples * draw_resolution_scale_y_; + spv::Id const_tile_height = builder_->makeUintConstant(tile_height); + spv::Id tile_half_index[2], tile_half_sample_coordinates[2]; + for (uint32_t i = 0; i < 2; ++i) { + spv::Id sample_x_or_y = sample_coordinates[i]; + spv::Id tile_half_width_or_height = i ? const_tile_height : const_tile_half_width; + tile_half_index[i] = + builder_->createBinOp(spv::OpUDiv, type_uint_, sample_x_or_y, tile_half_width_or_height); + tile_half_sample_coordinates[i] = + builder_->createBinOp(spv::OpUMod, type_uint_, sample_x_or_y, tile_half_width_or_height); + } + + // Convert the Y sample 0 position within the half-tile or tile to the dword + // offset of the row within a 80x16 32bpp tile or a 40x16 64bpp half-tile. + spv::Id const_tile_width = builder_->makeUintConstant(tile_width); + spv::Id row_offset_in_tile_at_32bpp = builder_->createBinOp( + spv::OpIMul, type_uint_, tile_half_sample_coordinates[1], const_tile_width); + + // Multiply the Y tile position by the surface tile pitch in dwords at 32bpp + // to get the address of the origin of the row of tiles within a 32bpp surface + // in dwords (later it needs to be multiplied by 2 for 64bpp). + id_vector_temp_.clear(); + id_vector_temp_.push_back( + builder_->makeIntConstant(kSystemConstantEdram32bppTilePitchDwordsScaled)); + spv::Id tile_row_offset_at_32bpp = builder_->createBinOp( + spv::OpIMul, type_uint_, + builder_->createLoad(builder_->createAccessChain(spv::StorageClassUniform, + uniform_system_constants_, id_vector_temp_), + spv::NoPrecision), + tile_half_index[1]); + + uint32_t tile_size = tile_width * tile_height; + spv::Id const_tile_size = builder_->makeUintConstant(tile_size); + + // Get the dword offset of the sample 0 in the first half-tile in the tile + // within a 32bpp surface. + spv::Id offset_in_first_tile_half_at_32bpp = builder_->createBinOp( + spv::OpIAdd, type_uint_, + builder_->createBinOp( + spv::OpIAdd, type_uint_, tile_row_offset_at_32bpp, + builder_->createBinOp( + spv::OpIAdd, type_uint_, + builder_->createBinOp(spv::OpIMul, type_uint_, const_tile_size, + builder_->createBinOp(spv::OpShiftRightLogical, type_uint_, + tile_half_index[0], const_uint_1)), + row_offset_in_tile_at_32bpp)), + tile_half_sample_coordinates[0]); + + // Get whether the sample is in the second half-tile in a 32bpp surface. + spv::Id is_second_tile_half = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, tile_half_index[0], const_uint_1), + const_uint_0_); + + // Get the offset of the sample 0 within a depth / stencil surface, with + // samples 40...79 in the first half-tile, 0...39 in the second (flipped as + // opposed to color). Then add the EDRAM base for depth / stencil, and wrap + // addressing. + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantEdramDepthBaseDwordsScaled)); + main_fsi_address_depth_ = builder_->createBinOp( + spv::OpUMod, type_uint_, + builder_->createBinOp( + spv::OpIAdd, type_uint_, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision), + builder_->createBinOp( + spv::OpIAdd, type_uint_, offset_in_first_tile_half_at_32bpp, + builder_->createTriOp(spv::OpSelect, type_uint_, is_second_tile_half, const_uint_0_, + const_tile_half_width))), + builder_->makeUintConstant(tile_size * xenos::kEdramTileCount)); + + if (current_shader().writes_color_targets()) { + // Get the offset of the sample 0 within a 32bpp surface, with samples + // 0...39 in the first half-tile, 40...79 in the second. + main_fsi_offset_32bpp_ = + builder_->createBinOp(spv::OpIAdd, type_uint_, offset_in_first_tile_half_at_32bpp, + builder_->createTriOp(spv::OpSelect, type_uint_, is_second_tile_half, + const_tile_half_width, const_uint_0_)); + + // Get the offset of the sample 0 within a 64bpp surface. + main_fsi_offset_64bpp_ = builder_->createBinOp( + spv::OpIAdd, type_uint_, + builder_->createBinOp( + spv::OpIAdd, type_uint_, + builder_->createBinOp(spv::OpShiftLeftLogical, type_uint_, tile_row_offset_at_32bpp, + const_uint_1), + builder_->createBinOp( + spv::OpIAdd, type_uint_, + builder_->createBinOp(spv::OpIMul, type_uint_, const_tile_size, tile_half_index[0]), + row_offset_in_tile_at_32bpp)), + builder_->createBinOp(spv::OpShiftLeftLogical, type_uint_, tile_half_sample_coordinates[0], + const_uint_1)); + } +} + +spv::Id SpirvShaderTranslator::FSI_AddSampleOffset(spv::Id sample_0_address, uint32_t sample_index, + spv::Id is_64bpp) { + if (!sample_index) { + return sample_0_address; + } + spv::Id sample_offset; + uint32_t tile_width = xenos::kEdramTileWidthSamples * draw_resolution_scale_x_; + if (sample_index == 1) { + sample_offset = builder_->makeIntConstant(tile_width); + } else { + spv::Id sample_offset_32bpp = + builder_->makeIntConstant(tile_width * (sample_index & 1) + (sample_index >> 1)); + if (is_64bpp != spv::NoResult) { + sample_offset = builder_->createTriOp( + spv::OpSelect, type_int_, is_64bpp, + builder_->makeIntConstant(tile_width * (sample_index & 1) + 2 * (sample_index >> 1)), + sample_offset_32bpp); + } else { + sample_offset = sample_offset_32bpp; + } + } + return builder_->createBinOp(spv::OpIAdd, type_int_, sample_0_address, sample_offset); +} + +void SpirvShaderTranslator::FSI_DepthStencilTest(spv::Id msaa_samples, + bool sample_mask_potentially_narrowed_previouly) { + bool is_early = FSI_IsDepthStencilEarly(); + bool shader_writes_depth = current_shader().writes_depth(); + bool implicit_early_z_write_allowed = current_shader().implicit_early_z_write_allowed(); + spv::Id const_uint_1 = builder_->makeUintConstant(1); + spv::Id const_uint_8 = builder_->makeUintConstant(8); + + // Check if depth or stencil testing is needed. + spv::Id depth_stencil_enabled = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(kSysFlag_FSIDepthStencil)), + const_uint_0_); + SpirvBuilder::IfBuilder if_depth_stencil_enabled(depth_stencil_enabled, + spv::SelectionControlDontFlattenMask, *builder_); + + // Load the center depth and, if needed, derivatives for per-sample depth + // reconstruction. + spv::Id center_depth32_unbiased; + std::array depth_dxy = {const_float_0_, const_float_0_}; + if (shader_writes_depth) { + assert_true(var_main_fragment_depth_ != spv::NoResult); + center_depth32_unbiased = builder_->createLoad(var_main_fragment_depth_, spv::NoPrecision); + } else { + assert_true(input_fragment_coordinates_ != spv::NoResult); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(2)); + center_depth32_unbiased = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassInput, input_fragment_coordinates_, + id_vector_temp_), + spv::NoPrecision); + builder_->addCapability(spv::CapabilityDerivativeControl); + depth_dxy[0] = builder_->createUnaryOp(spv::OpDPdxCoarse, type_float_, center_depth32_unbiased); + depth_dxy[1] = builder_->createUnaryOp(spv::OpDPdyCoarse, type_float_, center_depth32_unbiased); + } + + // Skip everything if potentially discarded all the samples previously in the + // shader. + spv::Block* block_any_sample_covered_head = nullptr; + spv::Block* block_any_sample_covered = nullptr; + spv::Block* block_any_sample_covered_merge = nullptr; + if (sample_mask_potentially_narrowed_previouly) { + spv::Id any_sample_covered = + builder_->createBinOp(spv::OpINotEqual, type_bool_, main_fsi_sample_mask_, const_uint_0_); + block_any_sample_covered_head = builder_->getBuildPoint(); + block_any_sample_covered = &builder_->makeNewBlock(); + block_any_sample_covered_merge = &builder_->makeNewBlock(); + builder_->createSelectionMerge(block_any_sample_covered_merge, + spv::SelectionControlDontFlattenMask); + builder_->createConditionalBranch(any_sample_covered, block_any_sample_covered, + block_any_sample_covered_merge); + builder_->setBuildPoint(block_any_sample_covered); + } + + // Load values involved in depth and stencil testing. + spv::Id msaa_is_2x_4x = + builder_->createBinOp(spv::OpUGreaterThanEqual, type_bool_, msaa_samples, + builder_->makeUintConstant(uint32_t(xenos::MsaaSamples::k2X))); + spv::Id msaa_is_4x = + builder_->createBinOp(spv::OpUGreaterThanEqual, type_bool_, msaa_samples, + builder_->makeUintConstant(uint32_t(xenos::MsaaSamples::k4X))); + spv::Id depth_is_float24 = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(kSysFlag_DepthFloat24)), + const_uint_0_); + spv::Id depth_pass_if_less = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(kSysFlag_FSIDepthPassIfLess)), + const_uint_0_); + spv::Id depth_pass_if_equal = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(kSysFlag_FSIDepthPassIfEqual)), + const_uint_0_); + spv::Id depth_pass_if_greater = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(kSysFlag_FSIDepthPassIfGreater)), + const_uint_0_); + spv::Id depth_write = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(kSysFlag_FSIDepthWrite)), + const_uint_0_); + spv::Id stencil_enabled = builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(kSysFlag_FSIStencilTest)), + const_uint_0_); + spv::Id early_write = + (is_early && implicit_early_z_write_allowed) + ? builder_->createBinOp( + spv::OpINotEqual, type_bool_, + builder_->createBinOp( + spv::OpBitwiseAnd, type_uint_, main_system_constant_flags_, + builder_->makeUintConstant(kSysFlag_FSIDepthStencilEarlyWrite)), + const_uint_0_) + : spv::NoResult; + spv::Id not_early_write = + (is_early && implicit_early_z_write_allowed) + ? builder_->createUnaryOp(spv::OpLogicalNot, type_bool_, early_write) + : spv::NoResult; + assert_true(input_front_facing_ != spv::NoResult); + spv::Id front_facing = builder_->createLoad(input_front_facing_, spv::NoPrecision); + spv::Id poly_offset_scale, poly_offset_offset, stencil_parameters; + { + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantEdramPolyOffsetFrontScale)); + spv::Id poly_offset_front_scale = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantEdramPolyOffsetBackScale)); + spv::Id poly_offset_back_scale = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + poly_offset_scale = builder_->createTriOp(spv::OpSelect, type_float_, front_facing, + poly_offset_front_scale, poly_offset_back_scale); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantEdramPolyOffsetFrontOffset)); + spv::Id poly_offset_front_offset = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantEdramPolyOffsetBackOffset)); + spv::Id poly_offset_back_offset = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + poly_offset_offset = builder_->createTriOp(spv::OpSelect, type_float_, front_facing, + poly_offset_front_offset, poly_offset_back_offset); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantEdramStencilFront)); + spv::Id stencil_parameters_front = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + id_vector_temp_.clear(); + id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantEdramStencilBack)); + spv::Id stencil_parameters_back = builder_->createLoad( + builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, + id_vector_temp_), + spv::NoPrecision); + stencil_parameters = + builder_->createTriOp(spv::OpSelect, type_uint2_, + builder_->smearScalar(spv::NoPrecision, front_facing, type_bool2_), + stencil_parameters_front, stencil_parameters_back); + } + spv::Id stencil_reference_masks = + builder_->createCompositeExtract(stencil_parameters, type_uint_, 0); + spv::Id stencil_reference = builder_->createTriOp( + spv::OpBitFieldUExtract, type_uint_, stencil_reference_masks, const_uint_0_, const_uint_8); + spv::Id stencil_read_mask = builder_->createTriOp( + spv::OpBitFieldUExtract, type_uint_, stencil_reference_masks, const_uint_8, const_uint_8); + spv::Id stencil_reference_read_masked = + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, stencil_reference, stencil_read_mask); + spv::Id stencil_write_mask = + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, stencil_reference_masks, + builder_->makeUintConstant(16), const_uint_8); + spv::Id stencil_write_keep_mask = + builder_->createUnaryOp(spv::OpNot, type_uint_, stencil_write_mask); + spv::Id stencil_func_ops = builder_->createCompositeExtract(stencil_parameters, type_uint_, 1); + spv::Id stencil_pass_if_less = + builder_->createBinOp(spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, stencil_func_ops, + builder_->makeUintConstant(uint32_t(1) << 0)), + const_uint_0_); + spv::Id stencil_pass_if_equal = + builder_->createBinOp(spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, stencil_func_ops, + builder_->makeUintConstant(uint32_t(1) << 1)), + const_uint_0_); + spv::Id stencil_pass_if_greater = + builder_->createBinOp(spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, stencil_func_ops, + builder_->makeUintConstant(uint32_t(1) << 2)), + const_uint_0_); + + spv::Id center_depth32_biased = center_depth32_unbiased; + if (!shader_writes_depth) { + // Get the maximum depth slope for the polygon offset. + // https://docs.microsoft.com/en-us/windows/desktop/direct3d9/depth-bias + std::array depth_dxy_abs; + for (uint32_t i = 0; i < 2; ++i) { + depth_dxy_abs[i] = builder_->createUnaryBuiltinCall(type_float_, ext_inst_glsl_std_450_, + GLSLstd450FAbs, depth_dxy[i]); + } + spv::Id depth_max_slope = builder_->createBinBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450FMax, depth_dxy_abs[0], depth_dxy_abs[1]); + // Calculate the polygon offset. + spv::Id slope_scaled_poly_offset = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, poly_offset_scale, depth_max_slope); + spv::Id poly_offset = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, slope_scaled_poly_offset, poly_offset_offset); + // Apply the post-clip and post-viewport polygon offset to the fragment's + // depth. Not clamping yet as this is at the center, which is not + // necessarily covered and not necessarily inside the bounds - derivatives + // scaled by sample locations will be added to this value, and it must be + // linear. + center_depth32_biased = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, center_depth32_unbiased, poly_offset); + } + + // Perform depth and stencil testing for each covered sample. + spv::Id new_sample_mask = main_fsi_sample_mask_; + std::array late_write_depth_stencil{}; + for (uint32_t i = 0; i < 4; ++i) { + spv::Id sample_covered = + builder_->createBinOp(spv::OpINotEqual, type_bool_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, new_sample_mask, + builder_->makeUintConstant(uint32_t(1) << i)), + const_uint_0_); + SpirvBuilder::IfBuilder if_sample_covered(sample_covered, spv::SelectionControlDontFlattenMask, + *builder_); + + // Load the original depth and stencil for the sample. + spv::Id sample_address = FSI_AddSampleOffset(main_fsi_address_depth_, i); + id_vector_temp_.clear(); + // First SSBO structure element. + id_vector_temp_.push_back(const_int_0_); + id_vector_temp_.push_back(sample_address); + spv::Id sample_access_chain = builder_->createAccessChain( + features_.spirv_version >= spv::Spv_1_3 ? spv::StorageClassStorageBuffer + : spv::StorageClassUniform, + buffer_edram_, id_vector_temp_); + spv::Id old_depth_stencil = builder_->createLoad(sample_access_chain, spv::NoPrecision); + + spv::Id sample_depth32; + if (shader_writes_depth) { + // One guest oDepth value is shared between all samples. + sample_depth32 = + builder_->createTriBuiltinCall(type_float_, ext_inst_glsl_std_450_, GLSLstd450NClamp, + center_depth32_biased, const_float_0_, const_float_1_); + } else { + // Calculate the new depth at the sample. + // interpolateAtSample(gl_FragCoord) is not valid in GLSL because + // gl_FragCoord is not an interpolator, calculating the depths at the + // samples manually. + std::array sample_location; + switch (i) { + case 0: { + // Center sample for no MSAA. + // Top-left sample for native 2x (top - 1 in Vulkan), 2x as 4x, 4x + // (0 in Vulkan). + // 4x on the host case. + for (uint32_t j = 0; j < 2; ++j) { + sample_location[j] = builder_->makeFloatConstant( + draw_util::kD3D10StandardSamplePositions4x[0][j] * (1.0f / 16.0f)); + } + if (native_2x_msaa_no_attachments_) { + // 2x on the host case. + for (uint32_t j = 0; j < 2; ++j) { + sample_location[j] = builder_->createTriOp( + spv::OpSelect, type_float_, msaa_is_4x, sample_location[j], + builder_->makeFloatConstant(draw_util::kD3D10StandardSamplePositions2x[1][j] * + (1.0f / 16.0f))); + } + } + // 1x case. + for (uint32_t j = 0; j < 2; ++j) { + sample_location[j] = builder_->createTriOp(spv::OpSelect, type_float_, msaa_is_2x_4x, + sample_location[j], const_float_0_); + } + } break; + case 1: { + // For guest 2x: bottom-right sample (bottom - 0 in Vulkan - for + // native 2x, bottom-right - 3 in Vulkan - for 2x as 4x). + // For guest 4x: bottom-left sample (2 in Vulkan). + for (uint32_t j = 0; j < 2; ++j) { + sample_location[j] = builder_->createTriOp( + spv::OpSelect, type_float_, msaa_is_4x, + builder_->makeFloatConstant(draw_util::kD3D10StandardSamplePositions4x[2][j] * + (1.0f / 16.0f)), + builder_->makeFloatConstant( + (native_2x_msaa_no_attachments_ + ? draw_util::kD3D10StandardSamplePositions2x[0][j] + : draw_util::kD3D10StandardSamplePositions4x[3][j]) * + (1.0f / 16.0f))); + } + } break; + default: { + // Xenia samples 2 and 3 (top-right and bottom-right) -> Vulkan + // samples 1 and 3. + const int8_t* sample_location_int = + draw_util::kD3D10StandardSamplePositions4x[i ^ (((i & 1) ^ (i >> 1)) * 0b11)]; + for (uint32_t j = 0; j < 2; ++j) { + sample_location[j] = + builder_->makeFloatConstant(sample_location_int[j] * (1.0f / 16.0f)); + } + } break; + } + std::array sample_depth_dxy; + for (uint32_t j = 0; j < 2; ++j) { + sample_depth_dxy[j] = builder_->createNoContractionBinOp(spv::OpFMul, type_float_, + sample_location[j], depth_dxy[j]); + } + sample_depth32 = builder_->createTriBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450NClamp, + builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, center_depth32_biased, + builder_->createNoContractionBinOp(spv::OpFAdd, type_float_, sample_depth_dxy[0], + sample_depth_dxy[1])), + const_float_0_, const_float_1_); + } + + // Convert the new depth to 24-bit. + SpirvBuilder::IfBuilder depth_format_if(depth_is_float24, spv::SelectionControlDontFlattenMask, + *builder_); + spv::Id sample_depth_float24 = SpirvShaderTranslator::PreClampedDepthTo20e4( + *builder_, sample_depth32, true, false, ext_inst_glsl_std_450_); + depth_format_if.makeBeginElse(); + // Round to the nearest even integer. This seems to be the correct + // conversion, adding +0.5 and rounding towards zero results in red instead + // of black in the 4D5307E6 clear shader. + spv::Id sample_depth_unorm24 = builder_->createUnaryOp( + spv::OpConvertFToU, type_uint_, + builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450RoundEven, + builder_->createNoContractionBinOp(spv::OpFMul, type_float_, sample_depth32, + builder_->makeFloatConstant(float(0xFFFFFF))))); + depth_format_if.makeEndIf(); + // Merge between the two formats. + spv::Id sample_depth24 = + depth_format_if.createMergePhi(sample_depth_float24, sample_depth_unorm24); + + // Perform the depth test. + spv::Id old_depth = builder_->createBinOp(spv::OpShiftRightLogical, type_uint_, + old_depth_stencil, const_uint_8); + spv::Id depth_passed = builder_->createBinOp( + spv::OpLogicalAnd, type_bool_, depth_pass_if_less, + builder_->createBinOp(spv::OpULessThan, type_bool_, sample_depth24, old_depth)); + depth_passed = builder_->createBinOp( + spv::OpLogicalOr, type_bool_, depth_passed, + builder_->createBinOp( + spv::OpLogicalAnd, type_bool_, depth_pass_if_equal, + builder_->createBinOp(spv::OpIEqual, type_bool_, sample_depth24, old_depth))); + depth_passed = builder_->createBinOp( + spv::OpLogicalOr, type_bool_, depth_passed, + builder_->createBinOp( + spv::OpLogicalAnd, type_bool_, depth_pass_if_greater, + builder_->createBinOp(spv::OpUGreaterThan, type_bool_, sample_depth24, old_depth))); + + // Perform the stencil test if enabled. + SpirvBuilder::IfBuilder stencil_if(stencil_enabled, spv::SelectionControlDontFlattenMask, + *builder_); + spv::Id stencil_passed_if_enabled; + spv::Id new_stencil_and_old_depth_if_stencil_enabled; + { + // The read mask has zeros in the upper bits, applying it to the combined + // stencil and depth will remove the depth part. + spv::Id old_stencil_read_masked = builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, + old_depth_stencil, stencil_read_mask); + stencil_passed_if_enabled = builder_->createBinOp( + spv::OpLogicalAnd, type_bool_, stencil_pass_if_less, + builder_->createBinOp(spv::OpULessThan, type_bool_, stencil_reference_read_masked, + old_stencil_read_masked)); + stencil_passed_if_enabled = builder_->createBinOp( + spv::OpLogicalOr, type_bool_, stencil_passed_if_enabled, + builder_->createBinOp( + spv::OpLogicalAnd, type_bool_, stencil_pass_if_equal, + builder_->createBinOp(spv::OpIEqual, type_bool_, stencil_reference_read_masked, + old_stencil_read_masked))); + stencil_passed_if_enabled = builder_->createBinOp( + spv::OpLogicalOr, type_bool_, stencil_passed_if_enabled, + builder_->createBinOp( + spv::OpLogicalAnd, type_bool_, stencil_pass_if_greater, + builder_->createBinOp(spv::OpUGreaterThan, type_bool_, stencil_reference_read_masked, + old_stencil_read_masked))); + spv::Id stencil_op = builder_->createTriOp( + spv::OpBitFieldUExtract, type_uint_, stencil_func_ops, + builder_->createTriOp( + spv::OpSelect, type_uint_, stencil_passed_if_enabled, + builder_->createTriOp(spv::OpSelect, type_uint_, depth_passed, + builder_->makeUintConstant(6), builder_->makeUintConstant(9)), + builder_->makeUintConstant(3)), + builder_->makeUintConstant(3)); + spv::Block& block_stencil_op_head = *builder_->getBuildPoint(); + spv::Block& block_stencil_op_keep = builder_->makeNewBlock(); + spv::Block& block_stencil_op_zero = builder_->makeNewBlock(); + spv::Block& block_stencil_op_replace = builder_->makeNewBlock(); + spv::Block& block_stencil_op_increment_clamp = builder_->makeNewBlock(); + spv::Block& block_stencil_op_decrement_clamp = builder_->makeNewBlock(); + spv::Block& block_stencil_op_invert = builder_->makeNewBlock(); + spv::Block& block_stencil_op_increment_wrap = builder_->makeNewBlock(); + spv::Block& block_stencil_op_decrement_wrap = builder_->makeNewBlock(); + spv::Block& block_stencil_op_merge = builder_->makeNewBlock(); + builder_->createSelectionMerge(&block_stencil_op_merge, spv::SelectionControlDontFlattenMask); + { + std::unique_ptr stencil_op_switch_op = + std::make_unique(spv::OpSwitch); + stencil_op_switch_op->addIdOperand(stencil_op); + // Make keep the default. + stencil_op_switch_op->addIdOperand(block_stencil_op_keep.getId()); + stencil_op_switch_op->addImmediateOperand(int32_t(xenos::StencilOp::kZero)); + stencil_op_switch_op->addIdOperand(block_stencil_op_zero.getId()); + stencil_op_switch_op->addImmediateOperand(int32_t(xenos::StencilOp::kReplace)); + stencil_op_switch_op->addIdOperand(block_stencil_op_replace.getId()); + stencil_op_switch_op->addImmediateOperand(int32_t(xenos::StencilOp::kIncrementClamp)); + stencil_op_switch_op->addIdOperand(block_stencil_op_increment_clamp.getId()); + stencil_op_switch_op->addImmediateOperand(int32_t(xenos::StencilOp::kDecrementClamp)); + stencil_op_switch_op->addIdOperand(block_stencil_op_decrement_clamp.getId()); + stencil_op_switch_op->addImmediateOperand(int32_t(xenos::StencilOp::kInvert)); + stencil_op_switch_op->addIdOperand(block_stencil_op_invert.getId()); + stencil_op_switch_op->addImmediateOperand(int32_t(xenos::StencilOp::kIncrementWrap)); + stencil_op_switch_op->addIdOperand(block_stencil_op_increment_wrap.getId()); + stencil_op_switch_op->addImmediateOperand(int32_t(xenos::StencilOp::kDecrementWrap)); + stencil_op_switch_op->addIdOperand(block_stencil_op_decrement_wrap.getId()); + builder_->getBuildPoint()->addInstruction(std::move(stencil_op_switch_op)); + } + block_stencil_op_keep.addPredecessor(&block_stencil_op_head); + block_stencil_op_zero.addPredecessor(&block_stencil_op_head); + block_stencil_op_replace.addPredecessor(&block_stencil_op_head); + block_stencil_op_increment_clamp.addPredecessor(&block_stencil_op_head); + block_stencil_op_decrement_clamp.addPredecessor(&block_stencil_op_head); + block_stencil_op_invert.addPredecessor(&block_stencil_op_head); + block_stencil_op_increment_wrap.addPredecessor(&block_stencil_op_head); + block_stencil_op_decrement_wrap.addPredecessor(&block_stencil_op_head); + // Keep - will use the old stencil in the phi. + builder_->setBuildPoint(&block_stencil_op_keep); + builder_->createBranch(&block_stencil_op_merge); + // Zero - will use the zero constant in the phi. + builder_->setBuildPoint(&block_stencil_op_zero); + builder_->createBranch(&block_stencil_op_merge); + // Replace - will use the stencil reference in the phi. + builder_->setBuildPoint(&block_stencil_op_replace); + builder_->createBranch(&block_stencil_op_merge); + // Increment and clamp. + builder_->setBuildPoint(&block_stencil_op_increment_clamp); + spv::Id new_stencil_in_low_bits_increment_clamp = builder_->createBinOp( + spv::OpIAdd, type_uint_, + builder_->createBinBuiltinCall( + type_uint_, ext_inst_glsl_std_450_, GLSLstd450UMin, + builder_->makeUintConstant(UINT8_MAX - 1), + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, old_depth_stencil, + builder_->makeUintConstant(UINT8_MAX))), + const_uint_1); + builder_->createBranch(&block_stencil_op_merge); + // Decrement and clamp. + builder_->setBuildPoint(&block_stencil_op_decrement_clamp); + spv::Id new_stencil_in_low_bits_decrement_clamp = builder_->createBinOp( + spv::OpISub, type_uint_, + builder_->createBinBuiltinCall( + type_uint_, ext_inst_glsl_std_450_, GLSLstd450UMax, const_uint_1, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, old_depth_stencil, + builder_->makeUintConstant(UINT8_MAX))), + const_uint_1); + builder_->createBranch(&block_stencil_op_merge); + // Invert. + builder_->setBuildPoint(&block_stencil_op_invert); + spv::Id new_stencil_in_low_bits_invert = + builder_->createUnaryOp(spv::OpNot, type_uint_, old_depth_stencil); + builder_->createBranch(&block_stencil_op_merge); + // Increment and wrap. + // The upper bits containing the old depth have no effect on the behavior. + builder_->setBuildPoint(&block_stencil_op_increment_wrap); + spv::Id new_stencil_in_low_bits_increment_wrap = + builder_->createBinOp(spv::OpIAdd, type_uint_, old_depth_stencil, const_uint_1); + builder_->createBranch(&block_stencil_op_merge); + // Decrement and wrap. + // The upper bits containing the old depth have no effect on the behavior. + builder_->setBuildPoint(&block_stencil_op_decrement_wrap); + spv::Id new_stencil_in_low_bits_decrement_wrap = + builder_->createBinOp(spv::OpISub, type_uint_, old_depth_stencil, const_uint_1); + builder_->createBranch(&block_stencil_op_merge); + // Select the new stencil (with undefined data in bits starting from 8) + // based on the stencil operation. + builder_->setBuildPoint(&block_stencil_op_merge); + id_vector_temp_.clear(); + id_vector_temp_.reserve(2 * 8); + id_vector_temp_.push_back(old_depth_stencil); + id_vector_temp_.push_back(block_stencil_op_keep.getId()); + id_vector_temp_.push_back(const_uint_0_); + id_vector_temp_.push_back(block_stencil_op_zero.getId()); + id_vector_temp_.push_back(stencil_reference); + id_vector_temp_.push_back(block_stencil_op_replace.getId()); + id_vector_temp_.push_back(new_stencil_in_low_bits_increment_clamp); + id_vector_temp_.push_back(block_stencil_op_increment_clamp.getId()); + id_vector_temp_.push_back(new_stencil_in_low_bits_decrement_clamp); + id_vector_temp_.push_back(block_stencil_op_decrement_clamp.getId()); + id_vector_temp_.push_back(new_stencil_in_low_bits_invert); + id_vector_temp_.push_back(block_stencil_op_invert.getId()); + id_vector_temp_.push_back(new_stencil_in_low_bits_increment_wrap); + id_vector_temp_.push_back(block_stencil_op_increment_wrap.getId()); + id_vector_temp_.push_back(new_stencil_in_low_bits_decrement_wrap); + id_vector_temp_.push_back(block_stencil_op_decrement_wrap.getId()); + spv::Id new_stencil_in_low_bits_if_enabled = + builder_->createOp(spv::OpPhi, type_uint_, id_vector_temp_); + // Merge the old depth / stencil (old depth kept from the old depth / + // stencil so the separate old depth register is not needed anymore after + // the depth test) and the new stencil based on the write mask. + new_stencil_and_old_depth_if_stencil_enabled = builder_->createBinOp( + spv::OpBitwiseOr, type_uint_, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, old_depth_stencil, + stencil_write_keep_mask), + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, new_stencil_in_low_bits_if_enabled, + stencil_write_mask)); + } + stencil_if.makeEndIf(); + // Choose the result based on whether the stencil test was done. + // All phi operations must be the first in the block. + spv::Id stencil_passed = + stencil_if.createMergePhi(stencil_passed_if_enabled, builder_->makeBoolConstant(true)); + spv::Id new_stencil_and_old_depth = + stencil_if.createMergePhi(new_stencil_and_old_depth_if_stencil_enabled, old_depth_stencil); + + // Check whether the tests have passed, and exclude the bit from the + // coverage if not. + spv::Id depth_stencil_passed = + builder_->createBinOp(spv::OpLogicalAnd, type_bool_, depth_passed, stencil_passed); + spv::Id new_sample_mask_after_sample = builder_->createTriOp( + spv::OpSelect, type_uint_, depth_stencil_passed, new_sample_mask, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, new_sample_mask, + builder_->makeUintConstant(~(uint32_t(1) << i)))); + + // Combine the new depth and the new stencil taking into account whether the + // new depth should be written. + spv::Id new_stencil_and_unconditional_new_depth = + builder_->createQuadOp(spv::OpBitFieldInsert, type_uint_, new_stencil_and_old_depth, + sample_depth24, const_uint_8, builder_->makeUintConstant(24)); + spv::Id new_depth_stencil = builder_->createTriOp( + spv::OpSelect, type_uint_, + builder_->createBinOp(spv::OpLogicalAnd, type_bool_, depth_stencil_passed, depth_write), + new_stencil_and_unconditional_new_depth, new_stencil_and_old_depth); + + // Write (or defer writing if the test is early, but may discard samples + // later still) the new depth and stencil if they're different. + spv::Id new_depth_stencil_different = + builder_->createBinOp(spv::OpINotEqual, type_bool_, new_depth_stencil, old_depth_stencil); + spv::Id new_depth_stencil_write_condition = spv::NoResult; + if (is_early) { + if (implicit_early_z_write_allowed) { + new_sample_mask_after_sample = builder_->createTriOp( + spv::OpSelect, type_uint_, + builder_->createBinOp(spv::OpLogicalAnd, type_bool_, new_depth_stencil_different, + not_early_write), + builder_->createBinOp(spv::OpBitwiseOr, type_uint_, new_sample_mask_after_sample, + builder_->makeUintConstant(uint32_t(1) << (4 + i))), + new_sample_mask_after_sample); + new_depth_stencil_write_condition = builder_->createBinOp( + spv::OpLogicalAnd, type_bool_, new_depth_stencil_different, early_write); + } else { + // Always need to write late in this shader, as it may do something like + // explicitly killing pixels. + new_sample_mask_after_sample = builder_->createTriOp( + spv::OpSelect, type_uint_, new_depth_stencil_different, + builder_->createBinOp(spv::OpBitwiseOr, type_uint_, new_sample_mask_after_sample, + builder_->makeUintConstant(uint32_t(1) << (4 + i))), + new_sample_mask_after_sample); + } + } else { + new_depth_stencil_write_condition = new_depth_stencil_different; + } + if (new_depth_stencil_write_condition != spv::NoResult) { + SpirvBuilder::IfBuilder new_depth_stencil_write_if( + new_depth_stencil_write_condition, spv::SelectionControlDontFlattenMask, *builder_); + builder_->createStore(new_depth_stencil, sample_access_chain); + new_depth_stencil_write_if.makeEndIf(); + } + + if_sample_covered.makeEndIf(); + new_sample_mask = + if_sample_covered.createMergePhi(new_sample_mask_after_sample, new_sample_mask); + if (is_early) { + late_write_depth_stencil[i] = + if_sample_covered.createMergePhi(new_depth_stencil, const_uint_0_); + } + } + + // Close the conditionals for whether depth / stencil testing is needed. + if (block_any_sample_covered_merge) { + builder_->createBranch(block_any_sample_covered_merge); + spv::Block& block_any_sample_covered_end = *builder_->getBuildPoint(); + builder_->setBuildPoint(block_any_sample_covered_merge); + id_vector_temp_.clear(); + id_vector_temp_.push_back(new_sample_mask); + id_vector_temp_.push_back(block_any_sample_covered_end.getId()); + id_vector_temp_.push_back(main_fsi_sample_mask_); + id_vector_temp_.push_back(block_any_sample_covered_head->getId()); + new_sample_mask = builder_->createOp(spv::OpPhi, type_uint_, id_vector_temp_); + if (is_early) { + for (uint32_t i = 0; i < 4; ++i) { + id_vector_temp_.clear(); + id_vector_temp_.push_back(late_write_depth_stencil[i]); + id_vector_temp_.push_back(block_any_sample_covered_end.getId()); + id_vector_temp_.push_back(const_uint_0_); + id_vector_temp_.push_back(block_any_sample_covered_head->getId()); + late_write_depth_stencil[i] = builder_->createOp(spv::OpPhi, type_uint_, id_vector_temp_); + } + } + } + if_depth_stencil_enabled.makeEndIf(); + main_fsi_sample_mask_ = + if_depth_stencil_enabled.createMergePhi(new_sample_mask, main_fsi_sample_mask_); + if (is_early) { + for (uint32_t i = 0; i < 4; ++i) { + main_fsi_late_write_depth_stencil_[i] = + if_depth_stencil_enabled.createMergePhi(late_write_depth_stencil[i], const_uint_0_); + } + } +} + +std::array SpirvShaderTranslator::FSI_ClampAndPackColor(spv::Id color_float4, + spv::Id format_with_flags) { + spv::Block& block_format_head = *builder_->getBuildPoint(); + spv::Block& block_format_8_8_8_8 = builder_->makeNewBlock(); + spv::Block& block_format_8_8_8_8_gamma = builder_->makeNewBlock(); + spv::Block& block_format_2_10_10_10 = builder_->makeNewBlock(); + spv::Block& block_format_2_10_10_10_float = builder_->makeNewBlock(); + spv::Block& block_format_16 = builder_->makeNewBlock(); + spv::Block& block_format_16_float = builder_->makeNewBlock(); + spv::Block& block_format_32_float = builder_->makeNewBlock(); + spv::Block& block_format_merge = builder_->makeNewBlock(); + builder_->createSelectionMerge(&block_format_merge, spv::SelectionControlDontFlattenMask); + { + std::unique_ptr format_switch_op = + std::make_unique(spv::OpSwitch); + format_switch_op->addIdOperand(format_with_flags); + // Make k_32_FLOAT or k_32_32_FLOAT the default. + format_switch_op->addIdOperand(block_format_32_float.getId()); + format_switch_op->addImmediateOperand(int32_t( + RenderTargetCache::AddPSIColorFormatFlags(xenos::ColorRenderTargetFormat::k_8_8_8_8))); + format_switch_op->addIdOperand(block_format_8_8_8_8.getId()); + format_switch_op->addImmediateOperand(int32_t(RenderTargetCache::AddPSIColorFormatFlags( + xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA))); + format_switch_op->addIdOperand(block_format_8_8_8_8_gamma.getId()); + format_switch_op->addImmediateOperand(int32_t( + RenderTargetCache::AddPSIColorFormatFlags(xenos::ColorRenderTargetFormat::k_2_10_10_10))); + format_switch_op->addIdOperand(block_format_2_10_10_10.getId()); + format_switch_op->addImmediateOperand(int32_t(RenderTargetCache::AddPSIColorFormatFlags( + xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10))); + format_switch_op->addIdOperand(block_format_2_10_10_10.getId()); + format_switch_op->addImmediateOperand(int32_t(RenderTargetCache::AddPSIColorFormatFlags( + xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT))); + format_switch_op->addIdOperand(block_format_2_10_10_10_float.getId()); + format_switch_op->addImmediateOperand(int32_t(RenderTargetCache::AddPSIColorFormatFlags( + xenos::ColorRenderTargetFormat ::k_2_10_10_10_FLOAT_AS_16_16_16_16))); + format_switch_op->addIdOperand(block_format_2_10_10_10_float.getId()); + format_switch_op->addImmediateOperand(int32_t( + RenderTargetCache::AddPSIColorFormatFlags(xenos::ColorRenderTargetFormat::k_16_16))); + format_switch_op->addIdOperand(block_format_16.getId()); + format_switch_op->addImmediateOperand(int32_t( + RenderTargetCache::AddPSIColorFormatFlags(xenos::ColorRenderTargetFormat::k_16_16_16_16))); + format_switch_op->addIdOperand(block_format_16.getId()); + format_switch_op->addImmediateOperand(int32_t( + RenderTargetCache::AddPSIColorFormatFlags(xenos::ColorRenderTargetFormat::k_16_16_FLOAT))); + format_switch_op->addIdOperand(block_format_16_float.getId()); + format_switch_op->addImmediateOperand(int32_t(RenderTargetCache::AddPSIColorFormatFlags( + xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT))); + format_switch_op->addIdOperand(block_format_16_float.getId()); + builder_->getBuildPoint()->addInstruction(std::move(format_switch_op)); + } + block_format_8_8_8_8.addPredecessor(&block_format_head); + block_format_8_8_8_8_gamma.addPredecessor(&block_format_head); + block_format_2_10_10_10.addPredecessor(&block_format_head); + block_format_2_10_10_10_float.addPredecessor(&block_format_head); + block_format_16.addPredecessor(&block_format_head); + block_format_16_float.addPredecessor(&block_format_head); + block_format_32_float.addPredecessor(&block_format_head); + + spv::Id unorm_round_offset_float = builder_->makeFloatConstant(0.5f); + id_vector_temp_.clear(); + id_vector_temp_.resize(4, unorm_round_offset_float); + spv::Id unorm_round_offset_float4 = + builder_->makeCompositeConstant(type_float4_, id_vector_temp_); + + // *************************************************************************** + // k_8_8_8_8 + // *************************************************************************** + spv::Id packed_8_8_8_8; + { + builder_->setBuildPoint(&block_format_8_8_8_8); + spv::Id color_scaled = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float4_, + builder_->createTriBuiltinCall(type_float4_, ext_inst_glsl_std_450_, GLSLstd450NClamp, + color_float4, const_float4_0_, const_float4_1_), + builder_->makeFloatConstant(255.0f)); + spv::Id color_offset = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float4_, color_scaled, unorm_round_offset_float4); + spv::Id color_uint4 = builder_->createUnaryOp(spv::OpConvertFToU, type_uint4_, color_offset); + packed_8_8_8_8 = builder_->createCompositeExtract(color_uint4, type_uint_, 0); + spv::Id component_width = builder_->makeUintConstant(8); + for (uint32_t i = 1; i < 4; ++i) { + packed_8_8_8_8 = + builder_->createQuadOp(spv::OpBitFieldInsert, type_uint_, packed_8_8_8_8, + builder_->createCompositeExtract(color_uint4, type_uint_, i), + builder_->makeUintConstant(8 * i), component_width); + } + builder_->createBranch(&block_format_merge); + } + spv::Block& block_format_8_8_8_8_end = *builder_->getBuildPoint(); + + // *************************************************************************** + // k_8_8_8_8_GAMMA + // *************************************************************************** + spv::Id packed_8_8_8_8_gamma; + { + builder_->setBuildPoint(&block_format_8_8_8_8_gamma); + uint_vector_temp_.clear(); + uint_vector_temp_.push_back(0); + uint_vector_temp_.push_back(1); + uint_vector_temp_.push_back(2); + spv::Id color_rgb = builder_->createRvalueSwizzle(spv::NoPrecision, type_float3_, color_float4, + uint_vector_temp_); + spv::Id rgb_gamma = + LinearToPWLGamma(builder_->createRvalueSwizzle(spv::NoPrecision, type_float3_, color_float4, + uint_vector_temp_), + false); + spv::Id alpha_clamped = builder_->createTriBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450NClamp, + builder_->createCompositeExtract(color_float4, type_float_, 3), const_float_0_, + const_float_1_); + // Bypass the `getNumTypeConstituents(typeId) == (int)constituents.size()` + // assertion in createCompositeConstruct, OpCompositeConstruct can + // construct vectors not only from scalars, but also from other vectors. + spv::Id color_gamma; + { + std::unique_ptr color_gamma_composite_construct_op = + std::make_unique(builder_->getUniqueId(), type_float4_, + spv::OpCompositeConstruct); + color_gamma_composite_construct_op->addIdOperand(rgb_gamma); + color_gamma_composite_construct_op->addIdOperand(alpha_clamped); + color_gamma = color_gamma_composite_construct_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(color_gamma_composite_construct_op)); + } + spv::Id color_scaled = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float4_, color_gamma, builder_->makeFloatConstant(255.0f)); + spv::Id color_offset = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float4_, color_scaled, unorm_round_offset_float4); + spv::Id color_uint4 = builder_->createUnaryOp(spv::OpConvertFToU, type_uint4_, color_offset); + packed_8_8_8_8_gamma = builder_->createCompositeExtract(color_uint4, type_uint_, 0); + spv::Id component_width = builder_->makeUintConstant(8); + for (uint32_t i = 1; i < 4; ++i) { + packed_8_8_8_8_gamma = + builder_->createQuadOp(spv::OpBitFieldInsert, type_uint_, packed_8_8_8_8_gamma, + builder_->createCompositeExtract(color_uint4, type_uint_, i), + builder_->makeUintConstant(8 * i), component_width); + } + builder_->createBranch(&block_format_merge); + } + spv::Block& block_format_8_8_8_8_gamma_end = *builder_->getBuildPoint(); + + // *************************************************************************** + // k_2_10_10_10 + // k_2_10_10_10_AS_10_10_10_10 + // *************************************************************************** + spv::Id packed_2_10_10_10; + { + builder_->setBuildPoint(&block_format_2_10_10_10); + spv::Id color_clamped = + builder_->createTriBuiltinCall(type_float4_, ext_inst_glsl_std_450_, GLSLstd450NClamp, + color_float4, const_float4_0_, const_float4_1_); + id_vector_temp_.clear(); + id_vector_temp_.resize(3, builder_->makeFloatConstant(1023.0f)); + id_vector_temp_.push_back(builder_->makeFloatConstant(3.0f)); + spv::Id color_scaled = builder_->createNoContractionBinOp( + spv::OpFMul, type_float4_, color_clamped, + builder_->makeCompositeConstant(type_float4_, id_vector_temp_)); + spv::Id color_offset = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float4_, color_scaled, unorm_round_offset_float4); + spv::Id color_uint4 = builder_->createUnaryOp(spv::OpConvertFToU, type_uint4_, color_offset); + packed_2_10_10_10 = builder_->createCompositeExtract(color_uint4, type_uint_, 0); + spv::Id rgb_width = builder_->makeUintConstant(10); + spv::Id alpha_width = builder_->makeUintConstant(2); + for (uint32_t i = 1; i < 4; ++i) { + packed_2_10_10_10 = builder_->createQuadOp( + spv::OpBitFieldInsert, type_uint_, packed_2_10_10_10, + builder_->createCompositeExtract(color_uint4, type_uint_, i), + builder_->makeUintConstant(10 * i), i == 3 ? alpha_width : rgb_width); + } + builder_->createBranch(&block_format_merge); + } + spv::Block& block_format_2_10_10_10_end = *builder_->getBuildPoint(); + + // *************************************************************************** + // k_2_10_10_10_FLOAT + // k_2_10_10_10_FLOAT_AS_16_16_16_16 + // *************************************************************************** + spv::Id packed_2_10_10_10_float; + { + builder_->setBuildPoint(&block_format_2_10_10_10_float); + std::array color_components; + // RGB. + for (uint32_t i = 0; i < 3; ++i) { + color_components[i] = UnclampedFloat32To7e3( + *builder_, builder_->createCompositeExtract(color_float4, type_float_, i), + ext_inst_glsl_std_450_); + } + // Alpha. + spv::Id alpha_scaled = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, + builder_->createTriBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450NClamp, + builder_->createCompositeExtract(color_float4, type_float_, 3), const_float_0_, + const_float_1_), + builder_->makeFloatConstant(3.0f)); + spv::Id alpha_offset = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, alpha_scaled, unorm_round_offset_float); + color_components[3] = builder_->createUnaryOp(spv::OpConvertFToU, type_uint_, alpha_offset); + // Pack. + packed_2_10_10_10_float = color_components[0]; + spv::Id rgb_width = builder_->makeUintConstant(10); + for (uint32_t i = 1; i < 3; ++i) { + packed_2_10_10_10_float = builder_->createQuadOp( + spv::OpBitFieldInsert, type_uint_, packed_2_10_10_10_float, color_components[i], + builder_->makeUintConstant(10 * i), rgb_width); + } + packed_2_10_10_10_float = builder_->createQuadOp( + spv::OpBitFieldInsert, type_uint_, packed_2_10_10_10_float, color_components[3], + builder_->makeUintConstant(30), builder_->makeUintConstant(2)); + builder_->createBranch(&block_format_merge); + } + spv::Block& block_format_2_10_10_10_float_end = *builder_->getBuildPoint(); + + // *************************************************************************** + // k_16_16 + // k_16_16_16_16 + // *************************************************************************** + std::array packed_16; + { + builder_->setBuildPoint(&block_format_16); + id_vector_temp_.clear(); + id_vector_temp_.resize(4, builder_->makeFloatConstant(-32.0f)); + spv::Id const_float4_minus_32 = builder_->makeCompositeConstant(type_float4_, id_vector_temp_); + id_vector_temp_.clear(); + id_vector_temp_.resize(4, builder_->makeFloatConstant(32.0f)); + spv::Id const_float4_32 = builder_->makeCompositeConstant(type_float4_, id_vector_temp_); + id_vector_temp_.clear(); + // NaN to 0, not to -32. + spv::Id color_scaled = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float4_, + builder_->createTriBuiltinCall( + type_float4_, ext_inst_glsl_std_450_, GLSLstd450FClamp, + builder_->createTriOp(spv::OpSelect, type_float4_, + builder_->createUnaryOp(spv::OpIsNan, type_bool4_, color_float4), + const_float4_0_, color_float4), + const_float4_minus_32, const_float4_32), + builder_->makeFloatConstant(32767.0f / 32.0f)); + id_vector_temp_.clear(); + id_vector_temp_.resize(4, builder_->makeFloatConstant(-0.5f)); + spv::Id unorm_round_offset_negative_float4 = + builder_->makeCompositeConstant(type_float4_, id_vector_temp_); + spv::Id color_offset = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float4_, color_scaled, + builder_->createTriOp( + spv::OpSelect, type_float4_, + builder_->createBinOp(spv::OpFOrdLessThan, type_bool4_, color_scaled, const_float4_0_), + unorm_round_offset_negative_float4, unorm_round_offset_float4)); + spv::Id color_uint4 = builder_->createUnaryOp( + spv::OpBitcast, type_uint4_, + builder_->createUnaryOp(spv::OpConvertFToS, type_int4_, color_offset)); + spv::Id component_offset_width = builder_->makeUintConstant(16); + for (uint32_t i = 0; i < 2; ++i) { + packed_16[i] = builder_->createQuadOp( + spv::OpBitFieldInsert, type_uint_, + builder_->createCompositeExtract(color_uint4, type_uint_, 2 * i), + builder_->createCompositeExtract(color_uint4, type_uint_, 2 * i + 1), + component_offset_width, component_offset_width); + } + builder_->createBranch(&block_format_merge); + } + spv::Block& block_format_16_end = *builder_->getBuildPoint(); + + // *************************************************************************** + // k_16_16_FLOAT + // k_16_16_16_16_FLOAT + // *************************************************************************** + std::array packed_16_float; + { + builder_->setBuildPoint(&block_format_16_float); + // TODO(Triang3l): Xenos extended-range float16. + id_vector_temp_.clear(); + id_vector_temp_.resize(4, builder_->makeFloatConstant(-65504.0f)); + spv::Id const_float4_minus_float16_max = + builder_->makeCompositeConstant(type_float4_, id_vector_temp_); + id_vector_temp_.clear(); + id_vector_temp_.resize(4, builder_->makeFloatConstant(65504.0f)); + spv::Id const_float4_float16_max = + builder_->makeCompositeConstant(type_float4_, id_vector_temp_); + // NaN to 0, not to -max. + spv::Id color_clamped = builder_->createTriBuiltinCall( + type_float4_, ext_inst_glsl_std_450_, GLSLstd450FClamp, + builder_->createTriOp(spv::OpSelect, type_float4_, + builder_->createUnaryOp(spv::OpIsNan, type_bool4_, color_float4), + const_float4_0_, color_float4), + const_float4_minus_float16_max, const_float4_float16_max); + for (uint32_t i = 0; i < 2; ++i) { + uint_vector_temp_.clear(); + uint_vector_temp_.push_back(2 * i); + uint_vector_temp_.push_back(2 * i + 1); + packed_16_float[i] = builder_->createUnaryBuiltinCall( + type_uint_, ext_inst_glsl_std_450_, GLSLstd450PackHalf2x16, + builder_->createRvalueSwizzle(spv::NoPrecision, type_float2_, color_clamped, + uint_vector_temp_)); + } + builder_->createBranch(&block_format_merge); + } + spv::Block& block_format_16_float_end = *builder_->getBuildPoint(); + + // *************************************************************************** + // k_32_FLOAT + // k_32_32_FLOAT + // *************************************************************************** + std::array packed_32_float; + { + builder_->setBuildPoint(&block_format_32_float); + for (uint32_t i = 0; i < 2; ++i) { + packed_32_float[i] = + builder_->createUnaryOp(spv::OpBitcast, type_uint_, + builder_->createCompositeExtract(color_float4, type_float_, i)); + } + builder_->createBranch(&block_format_merge); + } + spv::Block& block_format_32_float_end = *builder_->getBuildPoint(); + + // *************************************************************************** + // Selection of the result depending on the format. + // *************************************************************************** + + builder_->setBuildPoint(&block_format_merge); + std::array packed; + id_vector_temp_.reserve(2 * 7); + // Low 32 bits. + id_vector_temp_.clear(); + id_vector_temp_.push_back(packed_8_8_8_8); + id_vector_temp_.push_back(block_format_8_8_8_8_end.getId()); + id_vector_temp_.push_back(packed_8_8_8_8_gamma); + id_vector_temp_.push_back(block_format_8_8_8_8_gamma_end.getId()); + id_vector_temp_.push_back(packed_2_10_10_10); + id_vector_temp_.push_back(block_format_2_10_10_10_end.getId()); + id_vector_temp_.push_back(packed_2_10_10_10_float); + id_vector_temp_.push_back(block_format_2_10_10_10_float_end.getId()); + id_vector_temp_.push_back(packed_16[0]); + id_vector_temp_.push_back(block_format_16_end.getId()); + id_vector_temp_.push_back(packed_16_float[0]); + id_vector_temp_.push_back(block_format_16_float_end.getId()); + id_vector_temp_.push_back(packed_32_float[0]); + id_vector_temp_.push_back(block_format_32_float_end.getId()); + packed[0] = builder_->createOp(spv::OpPhi, type_uint_, id_vector_temp_); + // High 32 bits. + id_vector_temp_.clear(); + id_vector_temp_.push_back(const_uint_0_); + id_vector_temp_.push_back(block_format_8_8_8_8_end.getId()); + id_vector_temp_.push_back(const_uint_0_); + id_vector_temp_.push_back(block_format_8_8_8_8_gamma_end.getId()); + id_vector_temp_.push_back(const_uint_0_); + id_vector_temp_.push_back(block_format_2_10_10_10_end.getId()); + id_vector_temp_.push_back(const_uint_0_); + id_vector_temp_.push_back(block_format_2_10_10_10_float_end.getId()); + id_vector_temp_.push_back(packed_16[1]); + id_vector_temp_.push_back(block_format_16_end.getId()); + id_vector_temp_.push_back(packed_16_float[1]); + id_vector_temp_.push_back(block_format_16_float_end.getId()); + id_vector_temp_.push_back(packed_32_float[1]); + id_vector_temp_.push_back(block_format_32_float_end.getId()); + packed[1] = builder_->createOp(spv::OpPhi, type_uint_, id_vector_temp_); + return packed; +} + +std::array SpirvShaderTranslator::FSI_UnpackColor(std::array color_packed, + spv::Id format_with_flags) { + spv::Block& block_format_head = *builder_->getBuildPoint(); + spv::Block& block_format_8_8_8_8 = builder_->makeNewBlock(); + spv::Block& block_format_8_8_8_8_gamma = builder_->makeNewBlock(); + spv::Block& block_format_2_10_10_10 = builder_->makeNewBlock(); + spv::Block& block_format_2_10_10_10_float = builder_->makeNewBlock(); + spv::Block& block_format_16_16 = builder_->makeNewBlock(); + spv::Block& block_format_16_16_16_16 = builder_->makeNewBlock(); + spv::Block& block_format_16_16_float = builder_->makeNewBlock(); + spv::Block& block_format_16_16_16_16_float = builder_->makeNewBlock(); + spv::Block& block_format_32_float = builder_->makeNewBlock(); + spv::Block& block_format_32_32_float = builder_->makeNewBlock(); + spv::Block& block_format_merge = builder_->makeNewBlock(); + builder_->createSelectionMerge(&block_format_merge, spv::SelectionControlDontFlattenMask); + { + std::unique_ptr format_switch_op = + std::make_unique(spv::OpSwitch); + format_switch_op->addIdOperand(format_with_flags); + // Make k_32_FLOAT the default. + format_switch_op->addIdOperand(block_format_32_float.getId()); + format_switch_op->addImmediateOperand(int32_t( + RenderTargetCache::AddPSIColorFormatFlags(xenos::ColorRenderTargetFormat::k_8_8_8_8))); + format_switch_op->addIdOperand(block_format_8_8_8_8.getId()); + format_switch_op->addImmediateOperand(int32_t(RenderTargetCache::AddPSIColorFormatFlags( + xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA))); + format_switch_op->addIdOperand(block_format_8_8_8_8_gamma.getId()); + format_switch_op->addImmediateOperand(int32_t( + RenderTargetCache::AddPSIColorFormatFlags(xenos::ColorRenderTargetFormat::k_2_10_10_10))); + format_switch_op->addIdOperand(block_format_2_10_10_10.getId()); + format_switch_op->addImmediateOperand(int32_t(RenderTargetCache::AddPSIColorFormatFlags( + xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10))); + format_switch_op->addIdOperand(block_format_2_10_10_10.getId()); + format_switch_op->addImmediateOperand(int32_t(RenderTargetCache::AddPSIColorFormatFlags( + xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT))); + format_switch_op->addIdOperand(block_format_2_10_10_10_float.getId()); + format_switch_op->addImmediateOperand(int32_t(RenderTargetCache::AddPSIColorFormatFlags( + xenos::ColorRenderTargetFormat ::k_2_10_10_10_FLOAT_AS_16_16_16_16))); + format_switch_op->addIdOperand(block_format_2_10_10_10_float.getId()); + format_switch_op->addImmediateOperand(int32_t( + RenderTargetCache::AddPSIColorFormatFlags(xenos::ColorRenderTargetFormat::k_16_16))); + format_switch_op->addIdOperand(block_format_16_16.getId()); + format_switch_op->addImmediateOperand(int32_t( + RenderTargetCache::AddPSIColorFormatFlags(xenos::ColorRenderTargetFormat::k_16_16_16_16))); + format_switch_op->addIdOperand(block_format_16_16_16_16.getId()); + format_switch_op->addImmediateOperand(int32_t( + RenderTargetCache::AddPSIColorFormatFlags(xenos::ColorRenderTargetFormat::k_16_16_FLOAT))); + format_switch_op->addIdOperand(block_format_16_16_float.getId()); + format_switch_op->addImmediateOperand(int32_t(RenderTargetCache::AddPSIColorFormatFlags( + xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT))); + format_switch_op->addIdOperand(block_format_16_16_16_16_float.getId()); + format_switch_op->addImmediateOperand(int32_t( + RenderTargetCache::AddPSIColorFormatFlags(xenos::ColorRenderTargetFormat::k_32_32_FLOAT))); + format_switch_op->addIdOperand(block_format_32_32_float.getId()); + builder_->getBuildPoint()->addInstruction(std::move(format_switch_op)); + } + block_format_8_8_8_8.addPredecessor(&block_format_head); + block_format_8_8_8_8_gamma.addPredecessor(&block_format_head); + block_format_2_10_10_10.addPredecessor(&block_format_head); + block_format_2_10_10_10_float.addPredecessor(&block_format_head); + block_format_16_16.addPredecessor(&block_format_head); + block_format_16_16_16_16.addPredecessor(&block_format_head); + block_format_16_16_float.addPredecessor(&block_format_head); + block_format_16_16_16_16_float.addPredecessor(&block_format_head); + block_format_32_float.addPredecessor(&block_format_head); + block_format_32_32_float.addPredecessor(&block_format_head); + + // *************************************************************************** + // k_8_8_8_8 + // k_8_8_8_8_GAMMA + // *************************************************************************** + + std::array, 2> unpacked_8_8_8_8_and_gamma; + std::array block_format_8_8_8_8_and_gamma_end; + { + spv::Id component_width = builder_->makeUintConstant(8); + spv::Id component_scale = builder_->makeFloatConstant(1.0f / 255.0f); + for (uint32_t i = 0; i < 2; ++i) { + builder_->setBuildPoint(i ? &block_format_8_8_8_8_gamma : &block_format_8_8_8_8); + for (uint32_t j = 0; j < 4; ++j) { + spv::Id component = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, + builder_->createUnaryOp( + spv::OpConvertUToF, type_float_, + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, color_packed[0], + builder_->makeUintConstant(8 * j), component_width)), + component_scale); + if (i && j <= 2) { + component = PWLGammaToLinear(component, true); + } + unpacked_8_8_8_8_and_gamma[i][j] = component; + } + builder_->createBranch(&block_format_merge); + block_format_8_8_8_8_and_gamma_end[i] = builder_->getBuildPoint(); + } + } + + // *************************************************************************** + // k_2_10_10_10 + // k_2_10_10_10_AS_10_10_10_10 + // *************************************************************************** + + std::array unpacked_2_10_10_10; + { + builder_->setBuildPoint(&block_format_2_10_10_10); + spv::Id rgb_width = builder_->makeUintConstant(10); + spv::Id alpha_width = builder_->makeUintConstant(2); + spv::Id rgb_scale = builder_->makeFloatConstant(1.0f / 1023.0f); + spv::Id alpha_scale = builder_->makeFloatConstant(1.0f / 3.0f); + for (uint32_t i = 0; i < 4; ++i) { + unpacked_2_10_10_10[i] = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, + builder_->createUnaryOp( + spv::OpConvertUToF, type_float_, + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, color_packed[0], + builder_->makeUintConstant(10 * i), + i == 3 ? alpha_width : rgb_width)), + i == 3 ? alpha_scale : rgb_scale); + } + builder_->createBranch(&block_format_merge); + } + spv::Block& block_format_2_10_10_10_end = *builder_->getBuildPoint(); + + // *************************************************************************** + // k_2_10_10_10_FLOAT + // k_2_10_10_10_FLOAT_AS_16_16_16_16 + // *************************************************************************** + + std::array unpacked_2_10_10_10_float; + { + builder_->setBuildPoint(&block_format_2_10_10_10_float); + spv::Id rgb_width = builder_->makeUintConstant(10); + for (uint32_t i = 0; i < 3; ++i) { + unpacked_2_10_10_10_float[i] = + Float7e3To32(*builder_, + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, color_packed[0], + builder_->makeUintConstant(10 * i), rgb_width), + 0, false, ext_inst_glsl_std_450_); + } + unpacked_2_10_10_10_float[3] = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, + builder_->createUnaryOp( + spv::OpConvertUToF, type_float_, + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, color_packed[0], + builder_->makeUintConstant(30), builder_->makeUintConstant(2))), + builder_->makeFloatConstant(1.0f / 3.0f)); + builder_->createBranch(&block_format_merge); + } + spv::Block& block_format_2_10_10_10_float_end = *builder_->getBuildPoint(); + + // *************************************************************************** + // k_16_16 + // k_16_16_16_16 + // *************************************************************************** + + std::array, 2> unpacked_16; + unpacked_16[0][2] = const_float_0_; + unpacked_16[0][3] = const_float_1_; + std::array block_format_16_end; + { + spv::Id component_width = builder_->makeUintConstant(16); + spv::Id component_scale = builder_->makeFloatConstant(32.0f / 32767.0f); + spv::Id component_min = builder_->makeFloatConstant(-1.0f); + for (uint32_t i = 0; i < 2; ++i) { + builder_->setBuildPoint(i ? &block_format_16_16_16_16 : &block_format_16_16); + std::array color_packed_signed; + for (uint32_t j = 0; j <= i; ++j) { + color_packed_signed[j] = + builder_->createUnaryOp(spv::OpBitcast, type_int_, color_packed[j]); + } + for (uint32_t j = 0; j < uint32_t(i ? 4 : 2); ++j) { + spv::Id component = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, + builder_->createUnaryOp( + spv::OpConvertSToF, type_float_, + builder_->createTriOp(spv::OpBitFieldSExtract, type_int_, + color_packed_signed[j >> 1], + builder_->makeUintConstant(16 * (j & 1)), component_width)), + component_scale); + component = builder_->createBinBuiltinCall(type_float_, ext_inst_glsl_std_450_, + GLSLstd450FMax, component_min, component); + unpacked_16[i][j] = component; + } + builder_->createBranch(&block_format_merge); + block_format_16_end[i] = builder_->getBuildPoint(); + } + } + + // *************************************************************************** + // k_16_16_FLOAT + // k_16_16_16_16_FLOAT + // *************************************************************************** + + std::array, 2> unpacked_16_float; + unpacked_16_float[0][2] = const_float_0_; + unpacked_16_float[0][3] = const_float_1_; + std::array block_format_16_float_end; + { + for (uint32_t i = 0; i < 2; ++i) { + builder_->setBuildPoint(i ? &block_format_16_16_16_16_float : &block_format_16_16_float); + // TODO(Triang3l): Xenos extended-range float16. + for (uint32_t j = 0; j <= i; ++j) { + spv::Id components_float2 = builder_->createUnaryBuiltinCall( + type_float2_, ext_inst_glsl_std_450_, GLSLstd450UnpackHalf2x16, color_packed[j]); + for (uint32_t k = 0; k < 2; ++k) { + unpacked_16_float[i][2 * j + k] = + builder_->createCompositeExtract(components_float2, type_float_, k); + } + } + builder_->createBranch(&block_format_merge); + block_format_16_float_end[i] = builder_->getBuildPoint(); + } + } + + // *************************************************************************** + // k_32_FLOAT + // k_32_32_FLOAT + // *************************************************************************** + + std::array, 2> unpacked_32_float; + unpacked_32_float[0][1] = const_float_0_; + unpacked_32_float[0][2] = const_float_0_; + unpacked_32_float[0][3] = const_float_1_; + unpacked_32_float[1][2] = const_float_0_; + unpacked_32_float[1][3] = const_float_1_; + std::array block_format_32_float_end; + { + for (uint32_t i = 0; i < 2; ++i) { + builder_->setBuildPoint(i ? &block_format_32_32_float : &block_format_32_float); + for (uint32_t j = 0; j <= i; ++j) { + unpacked_32_float[i][j] = + builder_->createUnaryOp(spv::OpBitcast, type_float_, color_packed[j]); + } + builder_->createBranch(&block_format_merge); + block_format_32_float_end[i] = builder_->getBuildPoint(); + } + } + + // *************************************************************************** + // Selection of the result depending on the format. + // *************************************************************************** + + builder_->setBuildPoint(&block_format_merge); + std::array unpacked; + id_vector_temp_.reserve(2 * 10); + for (uint32_t i = 0; i < 4; ++i) { + id_vector_temp_.clear(); + id_vector_temp_.push_back(unpacked_8_8_8_8_and_gamma[0][i]); + id_vector_temp_.push_back(block_format_8_8_8_8_and_gamma_end[0]->getId()); + id_vector_temp_.push_back(unpacked_8_8_8_8_and_gamma[1][i]); + id_vector_temp_.push_back(block_format_8_8_8_8_and_gamma_end[1]->getId()); + id_vector_temp_.push_back(unpacked_2_10_10_10[i]); + id_vector_temp_.push_back(block_format_2_10_10_10_end.getId()); + id_vector_temp_.push_back(unpacked_2_10_10_10_float[i]); + id_vector_temp_.push_back(block_format_2_10_10_10_float_end.getId()); + id_vector_temp_.push_back(unpacked_16[0][i]); + id_vector_temp_.push_back(block_format_16_end[0]->getId()); + id_vector_temp_.push_back(unpacked_16[1][i]); + id_vector_temp_.push_back(block_format_16_end[1]->getId()); + id_vector_temp_.push_back(unpacked_16_float[0][i]); + id_vector_temp_.push_back(block_format_16_float_end[0]->getId()); + id_vector_temp_.push_back(unpacked_16_float[1][i]); + id_vector_temp_.push_back(block_format_16_float_end[1]->getId()); + id_vector_temp_.push_back(unpacked_32_float[0][i]); + id_vector_temp_.push_back(block_format_32_float_end[0]->getId()); + id_vector_temp_.push_back(unpacked_32_float[1][i]); + id_vector_temp_.push_back(block_format_32_float_end[1]->getId()); + unpacked[i] = builder_->createOp(spv::OpPhi, type_float_, id_vector_temp_); + } + return unpacked; +} + +spv::Id SpirvShaderTranslator::FSI_FlushNaNClampAndInBlending(spv::Id color_or_alpha, + spv::Id is_fixed_point, + spv::Id min_value, + spv::Id max_value) { + spv::Id color_or_alpha_type = builder_->getTypeId(color_or_alpha); + uint32_t component_count = uint32_t(builder_->getNumTypeConstituents(color_or_alpha_type)); + assert_true(builder_->isScalarType(color_or_alpha_type) || + builder_->isVectorType(color_or_alpha_type)); + assert_true(builder_->isFloatType(builder_->getScalarTypeId(color_or_alpha_type))); + assert_true(builder_->getTypeId(min_value) == color_or_alpha_type); + assert_true(builder_->getTypeId(max_value) == color_or_alpha_type); + + SpirvBuilder::IfBuilder if_fixed_point(is_fixed_point, spv::SelectionControlDontFlattenMask, + *builder_); + spv::Id color_or_alpha_clamped; + { + // Flush NaN to 0 even for signed (NMax would flush it to the minimum + // value). + color_or_alpha_clamped = builder_->createTriBuiltinCall( + color_or_alpha_type, ext_inst_glsl_std_450_, GLSLstd450FClamp, + builder_->createTriOp( + spv::OpSelect, color_or_alpha_type, + builder_->createUnaryOp(spv::OpIsNan, type_bool_vectors_[component_count - 1], + color_or_alpha), + const_float_vectors_0_[component_count - 1], color_or_alpha), + min_value, max_value); + } + if_fixed_point.makeEndIf(); + + return if_fixed_point.createMergePhi(color_or_alpha_clamped, color_or_alpha); +} + +spv::Id SpirvShaderTranslator::FSI_ApplyColorBlendFactor( + spv::Id value, spv::Id is_fixed_point, spv::Id clamp_min_value, spv::Id clamp_max_value, + spv::Id factor, spv::Id source_color, spv::Id source_alpha, spv::Id dest_color, + spv::Id dest_alpha, spv::Id constant_color, spv::Id constant_alpha) { + // If the factor is zero, don't use it in the multiplication at all, so that + // infinity and NaN are not potentially involved in the multiplication. + // Calculate the condition before the selection merge, which must be the + // penultimate instruction in the block. + SpirvBuilder::IfBuilder factor_not_zero_if( + builder_->createBinOp(spv::OpINotEqual, type_bool_, factor, + builder_->makeUintConstant(uint32_t(xenos::BlendFactor::kZero))), + spv::SelectionControlDontFlattenMask, *builder_); + + // Non-zero factor case. + + spv::Block& block_factor_head = *builder_->getBuildPoint(); + spv::Block& block_factor_one = builder_->makeNewBlock(); + std::array color_factor_blocks; + std::array one_minus_color_factor_blocks; + std::array alpha_factor_blocks; + std::array one_minus_alpha_factor_blocks; + color_factor_blocks[0] = &builder_->makeNewBlock(); + one_minus_color_factor_blocks[0] = &builder_->makeNewBlock(); + alpha_factor_blocks[0] = &builder_->makeNewBlock(); + one_minus_alpha_factor_blocks[0] = &builder_->makeNewBlock(); + color_factor_blocks[1] = &builder_->makeNewBlock(); + one_minus_color_factor_blocks[1] = &builder_->makeNewBlock(); + alpha_factor_blocks[1] = &builder_->makeNewBlock(); + one_minus_alpha_factor_blocks[1] = &builder_->makeNewBlock(); + color_factor_blocks[2] = &builder_->makeNewBlock(); + one_minus_color_factor_blocks[2] = &builder_->makeNewBlock(); + alpha_factor_blocks[2] = &builder_->makeNewBlock(); + one_minus_alpha_factor_blocks[2] = &builder_->makeNewBlock(); + spv::Block& block_factor_source_alpha_saturate = builder_->makeNewBlock(); + spv::Block& block_factor_merge = builder_->makeNewBlock(); + builder_->createSelectionMerge(&block_factor_merge, spv::SelectionControlDontFlattenMask); + { + std::unique_ptr factor_switch_op = + std::make_unique(spv::OpSwitch); + factor_switch_op->addIdOperand(factor); + // Make one the default factor. + factor_switch_op->addIdOperand(block_factor_one.getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kSrcColor)); + factor_switch_op->addIdOperand(color_factor_blocks[0]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kOneMinusSrcColor)); + factor_switch_op->addIdOperand(one_minus_color_factor_blocks[0]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kSrcAlpha)); + factor_switch_op->addIdOperand(alpha_factor_blocks[0]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kOneMinusSrcAlpha)); + factor_switch_op->addIdOperand(one_minus_alpha_factor_blocks[0]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kDstColor)); + factor_switch_op->addIdOperand(color_factor_blocks[1]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kOneMinusDstColor)); + factor_switch_op->addIdOperand(one_minus_color_factor_blocks[1]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kDstAlpha)); + factor_switch_op->addIdOperand(alpha_factor_blocks[1]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kOneMinusDstAlpha)); + factor_switch_op->addIdOperand(one_minus_alpha_factor_blocks[1]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kConstantColor)); + factor_switch_op->addIdOperand(color_factor_blocks[2]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kOneMinusConstantColor)); + factor_switch_op->addIdOperand(one_minus_color_factor_blocks[2]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kConstantAlpha)); + factor_switch_op->addIdOperand(alpha_factor_blocks[2]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kOneMinusConstantAlpha)); + factor_switch_op->addIdOperand(one_minus_alpha_factor_blocks[2]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kSrcAlphaSaturate)); + factor_switch_op->addIdOperand(block_factor_source_alpha_saturate.getId()); + builder_->getBuildPoint()->addInstruction(std::move(factor_switch_op)); + } + block_factor_one.addPredecessor(&block_factor_head); + for (uint32_t i = 0; i < 3; ++i) { + color_factor_blocks[i]->addPredecessor(&block_factor_head); + one_minus_color_factor_blocks[i]->addPredecessor(&block_factor_head); + alpha_factor_blocks[i]->addPredecessor(&block_factor_head); + one_minus_alpha_factor_blocks[i]->addPredecessor(&block_factor_head); + } + block_factor_source_alpha_saturate.addPredecessor(&block_factor_head); + + // kOne + builder_->setBuildPoint(&block_factor_one); + // The result is the value itself. + builder_->createBranch(&block_factor_merge); + + // k[OneMinus]Src/Dest/ConstantColor/Alpha + std::array color_factors = { + source_color, + dest_color, + constant_color, + }; + std::array alpha_factors = { + source_alpha, + dest_alpha, + constant_alpha, + }; + std::array color_factor_results; + std::array one_minus_color_factor_results; + std::array alpha_factor_results; + std::array one_minus_alpha_factor_results; + for (uint32_t i = 0; i < 3; ++i) { + spv::Id color_factor = color_factors[i]; + spv::Id alpha_factor = alpha_factors[i]; + + // kSrc/Dst/ConstantColor + { + builder_->setBuildPoint(color_factor_blocks[i]); + color_factor_results[i] = + builder_->createNoContractionBinOp(spv::OpFMul, type_float3_, value, color_factor); + builder_->createBranch(&block_factor_merge); + } + + // kOneMinusSrc/Dst/ConstantColor + { + builder_->setBuildPoint(one_minus_color_factor_blocks[i]); + one_minus_color_factor_results[i] = builder_->createNoContractionBinOp( + spv::OpFMul, type_float3_, value, + builder_->createNoContractionBinOp(spv::OpFSub, type_float3_, const_float3_1_, + color_factor)); + builder_->createBranch(&block_factor_merge); + } + + // kSrc/Dst/ConstantAlpha + { + builder_->setBuildPoint(alpha_factor_blocks[i]); + alpha_factor_results[i] = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float3_, value, alpha_factor); + builder_->createBranch(&block_factor_merge); + } + + // kOneMinusSrc/Dst/ConstantAlpha + { + builder_->setBuildPoint(one_minus_alpha_factor_blocks[i]); + one_minus_alpha_factor_results[i] = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float3_, value, + builder_->createNoContractionBinOp(spv::OpFSub, type_float_, const_float_1_, + alpha_factor)); + builder_->createBranch(&block_factor_merge); + } + } + + // kSrcAlphaSaturate + spv::Id result_source_alpha_saturate; + { + builder_->setBuildPoint(&block_factor_source_alpha_saturate); + result_source_alpha_saturate = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float3_, value, + builder_->createBinBuiltinCall(type_float_, ext_inst_glsl_std_450_, GLSLstd450NMin, + source_alpha, + builder_->createNoContractionBinOp( + spv::OpFSub, type_float_, const_float_1_, dest_alpha))); + builder_->createBranch(&block_factor_merge); + } + + // Select the term for the non-zero factor. + builder_->setBuildPoint(&block_factor_merge); + id_vector_temp_.clear(); + id_vector_temp_.reserve(2 * 14); + id_vector_temp_.push_back(value); + id_vector_temp_.push_back(block_factor_one.getId()); + for (uint32_t i = 0; i < 3; ++i) { + id_vector_temp_.push_back(color_factor_results[i]); + id_vector_temp_.push_back(color_factor_blocks[i]->getId()); + id_vector_temp_.push_back(one_minus_color_factor_results[i]); + id_vector_temp_.push_back(one_minus_color_factor_blocks[i]->getId()); + id_vector_temp_.push_back(alpha_factor_results[i]); + id_vector_temp_.push_back(alpha_factor_blocks[i]->getId()); + id_vector_temp_.push_back(one_minus_alpha_factor_results[i]); + id_vector_temp_.push_back(one_minus_alpha_factor_blocks[i]->getId()); + } + id_vector_temp_.push_back(result_source_alpha_saturate); + id_vector_temp_.push_back(block_factor_source_alpha_saturate.getId()); + spv::Id result_unclamped = builder_->createOp(spv::OpPhi, type_float3_, id_vector_temp_); + spv::Id result = FSI_FlushNaNClampAndInBlending(result_unclamped, is_fixed_point, clamp_min_value, + clamp_max_value); + + factor_not_zero_if.makeEndIf(); + + // Make the result zero if the factor is zero. + return factor_not_zero_if.createMergePhi(result, const_float3_0_); +} + +spv::Id SpirvShaderTranslator::FSI_ApplyAlphaBlendFactor(spv::Id value, spv::Id is_fixed_point, + spv::Id clamp_min_value, + spv::Id clamp_max_value, spv::Id factor, + spv::Id source_alpha, spv::Id dest_alpha, + spv::Id constant_alpha) { + // If the factor is zero, don't use it in the multiplication at all, so that + // infinity and NaN are not potentially involved in the multiplication. + // Calculate the condition before the selection merge, which must be the + // penultimate instruction in the block. + SpirvBuilder::IfBuilder factor_not_zero_if( + builder_->createBinOp(spv::OpINotEqual, type_bool_, factor, + builder_->makeUintConstant(uint32_t(xenos::BlendFactor::kZero))), + spv::SelectionControlDontFlattenMask, *builder_); + + // Non-zero factor case. + + spv::Block& block_factor_head = *builder_->getBuildPoint(); + spv::Block& block_factor_one = builder_->makeNewBlock(); + std::array alpha_factor_blocks; + std::array one_minus_alpha_factor_blocks; + alpha_factor_blocks[0] = &builder_->makeNewBlock(); + one_minus_alpha_factor_blocks[0] = &builder_->makeNewBlock(); + alpha_factor_blocks[1] = &builder_->makeNewBlock(); + one_minus_alpha_factor_blocks[1] = &builder_->makeNewBlock(); + alpha_factor_blocks[2] = &builder_->makeNewBlock(); + one_minus_alpha_factor_blocks[2] = &builder_->makeNewBlock(); + spv::Block& block_factor_source_alpha_saturate = builder_->makeNewBlock(); + spv::Block& block_factor_merge = builder_->makeNewBlock(); + builder_->createSelectionMerge(&block_factor_merge, spv::SelectionControlDontFlattenMask); + { + std::unique_ptr factor_switch_op = + std::make_unique(spv::OpSwitch); + factor_switch_op->addIdOperand(factor); + // Make one the default factor. + factor_switch_op->addIdOperand(block_factor_one.getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kSrcColor)); + factor_switch_op->addIdOperand(alpha_factor_blocks[0]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kOneMinusSrcColor)); + factor_switch_op->addIdOperand(one_minus_alpha_factor_blocks[0]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kSrcAlpha)); + factor_switch_op->addIdOperand(alpha_factor_blocks[0]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kOneMinusSrcAlpha)); + factor_switch_op->addIdOperand(one_minus_alpha_factor_blocks[0]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kDstColor)); + factor_switch_op->addIdOperand(alpha_factor_blocks[1]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kOneMinusDstColor)); + factor_switch_op->addIdOperand(one_minus_alpha_factor_blocks[1]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kDstAlpha)); + factor_switch_op->addIdOperand(alpha_factor_blocks[1]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kOneMinusDstAlpha)); + factor_switch_op->addIdOperand(one_minus_alpha_factor_blocks[1]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kConstantColor)); + factor_switch_op->addIdOperand(alpha_factor_blocks[2]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kOneMinusConstantColor)); + factor_switch_op->addIdOperand(one_minus_alpha_factor_blocks[2]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kConstantAlpha)); + factor_switch_op->addIdOperand(alpha_factor_blocks[2]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kOneMinusConstantAlpha)); + factor_switch_op->addIdOperand(one_minus_alpha_factor_blocks[2]->getId()); + factor_switch_op->addImmediateOperand(int32_t(xenos::BlendFactor::kSrcAlphaSaturate)); + factor_switch_op->addIdOperand(block_factor_source_alpha_saturate.getId()); + builder_->getBuildPoint()->addInstruction(std::move(factor_switch_op)); + } + block_factor_one.addPredecessor(&block_factor_head); + for (uint32_t i = 0; i < 3; ++i) { + alpha_factor_blocks[i]->addPredecessor(&block_factor_head); + one_minus_alpha_factor_blocks[i]->addPredecessor(&block_factor_head); + } + block_factor_source_alpha_saturate.addPredecessor(&block_factor_head); + + // kOne + builder_->setBuildPoint(&block_factor_one); + // The result is the value itself. + builder_->createBranch(&block_factor_merge); + + // k[OneMinus]Src/Dest/ConstantColor/Alpha + std::array alpha_factors = { + source_alpha, + dest_alpha, + constant_alpha, + }; + std::array alpha_factor_results; + std::array one_minus_alpha_factor_results; + for (uint32_t i = 0; i < 3; ++i) { + spv::Id alpha_factor = alpha_factors[i]; + + // kSrc/Dst/ConstantColor/Alpha + { + builder_->setBuildPoint(alpha_factor_blocks[i]); + alpha_factor_results[i] = + builder_->createNoContractionBinOp(spv::OpFMul, type_float_, value, alpha_factor); + builder_->createBranch(&block_factor_merge); + } + + // kOneMinusSrc/Dst/ConstantColor/Alpha + { + builder_->setBuildPoint(one_minus_alpha_factor_blocks[i]); + one_minus_alpha_factor_results[i] = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, value, + builder_->createNoContractionBinOp(spv::OpFSub, type_float_, const_float_1_, + alpha_factor)); + builder_->createBranch(&block_factor_merge); + } + } + + // kSrcAlphaSaturate + spv::Id result_source_alpha_saturate; + { + builder_->setBuildPoint(&block_factor_source_alpha_saturate); + result_source_alpha_saturate = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, value, + builder_->createBinBuiltinCall(type_float_, ext_inst_glsl_std_450_, GLSLstd450NMin, + source_alpha, + builder_->createNoContractionBinOp( + spv::OpFSub, type_float_, const_float_1_, dest_alpha))); + builder_->createBranch(&block_factor_merge); + } + + // Select the term for the non-zero factor. + builder_->setBuildPoint(&block_factor_merge); + id_vector_temp_.clear(); + id_vector_temp_.reserve(2 * 8); + id_vector_temp_.push_back(value); + id_vector_temp_.push_back(block_factor_one.getId()); + for (uint32_t i = 0; i < 3; ++i) { + id_vector_temp_.push_back(alpha_factor_results[i]); + id_vector_temp_.push_back(alpha_factor_blocks[i]->getId()); + id_vector_temp_.push_back(one_minus_alpha_factor_results[i]); + id_vector_temp_.push_back(one_minus_alpha_factor_blocks[i]->getId()); + } + id_vector_temp_.push_back(result_source_alpha_saturate); + id_vector_temp_.push_back(block_factor_source_alpha_saturate.getId()); + spv::Id result_unclamped = builder_->createOp(spv::OpPhi, type_float_, id_vector_temp_); + spv::Id result = FSI_FlushNaNClampAndInBlending(result_unclamped, is_fixed_point, clamp_min_value, + clamp_max_value); + + factor_not_zero_if.makeEndIf(); + + // Make the result zero if the factor is zero. + return factor_not_zero_if.createMergePhi(result, const_float_0_); +} + +spv::Id SpirvShaderTranslator::FSI_BlendColorOrAlphaWithUnclampedResult( + spv::Id is_fixed_point, spv::Id clamp_min_value, spv::Id clamp_max_value, + spv::Id source_color_clamped, spv::Id source_alpha_clamped, spv::Id dest_color, + spv::Id dest_alpha, spv::Id constant_color_clamped, spv::Id constant_alpha_clamped, + spv::Id equation, spv::Id source_factor, spv::Id dest_factor) { + bool is_alpha = source_color_clamped == spv::NoResult; + assert_false(!is_alpha && + (dest_color == spv::NoResult || constant_color_clamped == spv::NoResult)); + assert_false(is_alpha && + (dest_color != spv::NoResult || constant_color_clamped != spv::NoResult)); + spv::Id value_type = is_alpha ? type_float_ : type_float3_; + + // Handle min and max blend operations, which don't involve the factors. + spv::Block& block_min_max_head = *builder_->getBuildPoint(); + spv::Block& block_min_max_min = builder_->makeNewBlock(); + spv::Block& block_min_max_max = builder_->makeNewBlock(); + spv::Block& block_min_max_default = builder_->makeNewBlock(); + spv::Block& block_min_max_merge = builder_->makeNewBlock(); + builder_->createSelectionMerge(&block_min_max_merge, spv::SelectionControlDontFlattenMask); + { + std::unique_ptr min_max_switch_op = + std::make_unique(spv::OpSwitch); + min_max_switch_op->addIdOperand(equation); + min_max_switch_op->addIdOperand(block_min_max_default.getId()); + min_max_switch_op->addImmediateOperand(int32_t(xenos::BlendOp::kMin)); + min_max_switch_op->addIdOperand(block_min_max_min.getId()); + min_max_switch_op->addImmediateOperand(int32_t(xenos::BlendOp::kMax)); + min_max_switch_op->addIdOperand(block_min_max_max.getId()); + builder_->getBuildPoint()->addInstruction(std::move(min_max_switch_op)); + } + block_min_max_default.addPredecessor(&block_min_max_head); + block_min_max_min.addPredecessor(&block_min_max_head); + block_min_max_max.addPredecessor(&block_min_max_head); + + // Min case. + builder_->setBuildPoint(&block_min_max_min); + spv::Id result_min = builder_->createBinBuiltinCall( + value_type, ext_inst_glsl_std_450_, GLSLstd450FMin, + is_alpha ? source_alpha_clamped : source_color_clamped, is_alpha ? dest_alpha : dest_color); + builder_->createBranch(&block_min_max_merge); + + // Max case. + builder_->setBuildPoint(&block_min_max_max); + spv::Id result_max = builder_->createBinBuiltinCall( + value_type, ext_inst_glsl_std_450_, GLSLstd450FMax, + is_alpha ? source_alpha_clamped : source_color_clamped, is_alpha ? dest_alpha : dest_color); + builder_->createBranch(&block_min_max_merge); + + // Blending with factors. + spv::Id result_factors; + { + builder_->setBuildPoint(&block_min_max_default); + + spv::Id term_source, term_dest; + if (is_alpha) { + term_source = FSI_ApplyAlphaBlendFactor(source_alpha_clamped, is_fixed_point, clamp_min_value, + clamp_max_value, source_factor, source_alpha_clamped, + dest_alpha, constant_alpha_clamped); + term_dest = FSI_ApplyAlphaBlendFactor(dest_alpha, is_fixed_point, clamp_min_value, + clamp_max_value, dest_factor, source_alpha_clamped, + dest_alpha, constant_alpha_clamped); + } else { + term_source = FSI_ApplyColorBlendFactor(source_color_clamped, is_fixed_point, clamp_min_value, + clamp_max_value, source_factor, source_color_clamped, + source_alpha_clamped, dest_color, dest_alpha, + constant_color_clamped, constant_alpha_clamped); + term_dest = FSI_ApplyColorBlendFactor(dest_color, is_fixed_point, clamp_min_value, + clamp_max_value, dest_factor, source_color_clamped, + source_alpha_clamped, dest_color, dest_alpha, + constant_color_clamped, constant_alpha_clamped); + } + + spv::Block& block_signs_head = *builder_->getBuildPoint(); + spv::Block& block_signs_add = builder_->makeNewBlock(); + spv::Block& block_signs_subtract = builder_->makeNewBlock(); + spv::Block& block_signs_reverse_subtract = builder_->makeNewBlock(); + spv::Block& block_signs_merge = builder_->makeNewBlock(); + builder_->createSelectionMerge(&block_signs_merge, spv::SelectionControlDontFlattenMask); + { + std::unique_ptr signs_switch_op = + std::make_unique(spv::OpSwitch); + signs_switch_op->addIdOperand(equation); + // Make addition the default. + signs_switch_op->addIdOperand(block_signs_add.getId()); + signs_switch_op->addImmediateOperand(int32_t(xenos::BlendOp::kSubtract)); + signs_switch_op->addIdOperand(block_signs_subtract.getId()); + signs_switch_op->addImmediateOperand(int32_t(xenos::BlendOp::kRevSubtract)); + signs_switch_op->addIdOperand(block_signs_reverse_subtract.getId()); + builder_->getBuildPoint()->addInstruction(std::move(signs_switch_op)); + } + block_signs_add.addPredecessor(&block_signs_head); + block_signs_subtract.addPredecessor(&block_signs_head); + block_signs_reverse_subtract.addPredecessor(&block_signs_head); + + // Addition case. + builder_->setBuildPoint(&block_signs_add); + spv::Id result_add = + builder_->createNoContractionBinOp(spv::OpFAdd, value_type, term_source, term_dest); + builder_->createBranch(&block_signs_merge); + + // Subtraction case. + builder_->setBuildPoint(&block_signs_subtract); + spv::Id result_subtract = + builder_->createNoContractionBinOp(spv::OpFSub, value_type, term_source, term_dest); + builder_->createBranch(&block_signs_merge); + + // Reverse subtraction case. + builder_->setBuildPoint(&block_signs_reverse_subtract); + spv::Id result_reverse_subtract = + builder_->createNoContractionBinOp(spv::OpFSub, value_type, term_dest, term_source); + builder_->createBranch(&block_signs_merge); + + // Selection between the signs involved in the addition. + builder_->setBuildPoint(&block_signs_merge); + id_vector_temp_.clear(); + id_vector_temp_.reserve(2 * 3); + id_vector_temp_.push_back(result_add); + id_vector_temp_.push_back(block_signs_add.getId()); + id_vector_temp_.push_back(result_subtract); + id_vector_temp_.push_back(block_signs_subtract.getId()); + id_vector_temp_.push_back(result_reverse_subtract); + id_vector_temp_.push_back(block_signs_reverse_subtract.getId()); + result_factors = builder_->createOp(spv::OpPhi, value_type, id_vector_temp_); + builder_->createBranch(&block_min_max_merge); + } + // Get the latest block for blending with factors after all the control flow. + spv::Block& block_min_max_default_end = *builder_->getBuildPoint(); + + builder_->setBuildPoint(&block_min_max_merge); + // Choose out of min, max, and blending with factors. + id_vector_temp_.clear(); + id_vector_temp_.reserve(2 * 3); + id_vector_temp_.push_back(result_min); + id_vector_temp_.push_back(block_min_max_min.getId()); + id_vector_temp_.push_back(result_max); + id_vector_temp_.push_back(block_min_max_max.getId()); + id_vector_temp_.push_back(result_factors); + id_vector_temp_.push_back(block_min_max_default_end.getId()); + return builder_->createOp(spv::OpPhi, value_type, id_vector_temp_); +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/shader/translator.cpp b/src/graphics/pipeline/shader/translator.cpp new file mode 100644 index 0000000..e472251 --- /dev/null +++ b/src/graphics/pipeline/shader/translator.cpp @@ -0,0 +1,1427 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace rex::graphics { + +using namespace ucode; + +// The Xbox 360 GPU is effectively an Adreno A200: +// https://github.com/freedreno/freedreno/wiki/A2XX-Shader-Instruction-Set-Architecture +// +// A lot of this information is derived from the freedreno drivers, AMD's +// documentation, publicly available Xbox presentations (from GDC/etc), and +// other reverse engineering. +// +// Naming has been matched as closely as possible to the real thing by using the +// publicly available XNA Game Studio shader assembler. +// You can find a tool for exploring this under tools/shader-playground/, +// allowing interative assembling/disassembling of shader code. +// +// Though the 360's GPU is similar to the Adreno r200, the microcode format is +// slightly different. Though this is a great guide it cannot be assumed it +// matches the 360 in all areas: +// https://github.com/freedreno/freedreno/blob/master/util/disasm-a2xx.c +// +// Lots of naming comes from the disassembly spit out by the XNA GS compiler +// and dumps of d3dcompiler and games: https://pastebin.com/i4kAv7bB + +void Shader::AnalyzeUcode(string::StringBuffer& ucode_disasm_buffer) { + if (is_ucode_analyzed_) { + return; + } + + // Control flow instructions come paired in blocks of 3 dwords and all are + // listed at the top of the ucode. + // Each control flow instruction is executed sequentially until the final + // ending instruction. + // Gather the upper bound of the control flow instructions, and label + // addresses, which are needed for disassembly. + cf_pair_index_bound_ = uint32_t(ucode_data_.size() / 3); + for (uint32_t i = 0; i < cf_pair_index_bound_; ++i) { + ControlFlowInstruction cf_ab[2]; + UnpackControlFlowInstructions(ucode_data_.data() + i * 3, cf_ab); + for (uint32_t j = 0; j < 2; ++j) { + // Guess how long the control flow program is by scanning for the first + // kExec-ish and instruction and using its address as the upper bound. + // This is what freedreno does. + const ControlFlowInstruction& cf = cf_ab[j]; + if (IsControlFlowOpcodeExec(cf.opcode())) { + cf_pair_index_bound_ = std::min(cf_pair_index_bound_, cf.exec.address()); + } + switch (cf.opcode()) { + case ControlFlowOpcode::kCondCall: + label_addresses_.insert(cf.cond_call.address()); + break; + case ControlFlowOpcode::kCondJmp: + label_addresses_.insert(cf.cond_jmp.address()); + break; + case ControlFlowOpcode::kLoopStart: + label_addresses_.insert(cf.loop_start.address()); + break; + case ControlFlowOpcode::kLoopEnd: + label_addresses_.insert(cf.loop_end.address()); + break; + default: + break; + } + } + } + + // Disassemble and gather information. + ucode_disasm_buffer.Reset(); + VertexFetchInstruction previous_vfetch_full; + std::memset(&previous_vfetch_full, 0, sizeof(previous_vfetch_full)); + uint32_t unique_texture_bindings = 0; + for (uint32_t i = 0; i < cf_pair_index_bound_; ++i) { + ControlFlowInstruction cf_ab[2]; + UnpackControlFlowInstructions(ucode_data_.data() + i * 3, cf_ab); + for (uint32_t j = 0; j < 2; ++j) { + uint32_t cf_index = i * 2 + j; + if (label_addresses_.find(cf_index) != label_addresses_.end()) { + ucode_disasm_buffer.AppendFormat(" label L{}\n", cf_index); + } + ucode_disasm_buffer.AppendFormat("/* {:4d}.{} */ ", i, j); + + const ControlFlowInstruction& cf = cf_ab[j]; + uint32_t bool_constant_index = UINT32_MAX; + switch (cf.opcode()) { + case ControlFlowOpcode::kNop: + ucode_disasm_buffer.Append(" cnop\n"); + break; + case ControlFlowOpcode::kExec: + case ControlFlowOpcode::kExecEnd: { + ParsedExecInstruction instr; + ParseControlFlowExec(cf.exec, cf_index, instr); + GatherExecInformation(instr, previous_vfetch_full, unique_texture_bindings, + ucode_disasm_buffer); + } break; + case ControlFlowOpcode::kCondExec: + case ControlFlowOpcode::kCondExecEnd: + case ControlFlowOpcode::kCondExecPredClean: + case ControlFlowOpcode::kCondExecPredCleanEnd: { + bool_constant_index = cf.cond_exec.bool_address(); + ParsedExecInstruction instr; + ParseControlFlowCondExec(cf.cond_exec, cf_index, instr); + GatherExecInformation(instr, previous_vfetch_full, unique_texture_bindings, + ucode_disasm_buffer); + } break; + case ControlFlowOpcode::kCondExecPred: + case ControlFlowOpcode::kCondExecPredEnd: { + ParsedExecInstruction instr; + ParseControlFlowCondExecPred(cf.cond_exec_pred, cf_index, instr); + GatherExecInformation(instr, previous_vfetch_full, unique_texture_bindings, + ucode_disasm_buffer); + } break; + case ControlFlowOpcode::kLoopStart: { + ParsedLoopStartInstruction instr; + ParseControlFlowLoopStart(cf.loop_start, cf_index, instr); + instr.Disassemble(&ucode_disasm_buffer); + constant_register_map_.loop_bitmap |= uint32_t(1) << instr.loop_constant_index; + } break; + case ControlFlowOpcode::kLoopEnd: { + ParsedLoopEndInstruction instr; + ParseControlFlowLoopEnd(cf.loop_end, cf_index, instr); + instr.Disassemble(&ucode_disasm_buffer); + constant_register_map_.loop_bitmap |= uint32_t(1) << instr.loop_constant_index; + } break; + case ControlFlowOpcode::kCondCall: { + ParsedCallInstruction instr; + ParseControlFlowCondCall(cf.cond_call, cf_index, instr); + instr.Disassemble(&ucode_disasm_buffer); + if (instr.type == ParsedCallInstruction::Type::kConditional) { + bool_constant_index = instr.bool_constant_index; + } + } break; + case ControlFlowOpcode::kReturn: { + ParsedReturnInstruction instr; + ParseControlFlowReturn(cf.ret, cf_index, instr); + instr.Disassemble(&ucode_disasm_buffer); + } break; + case ControlFlowOpcode::kCondJmp: { + ParsedJumpInstruction instr; + ParseControlFlowCondJmp(cf.cond_jmp, cf_index, instr); + instr.Disassemble(&ucode_disasm_buffer); + if (instr.type == ParsedJumpInstruction::Type::kConditional) { + bool_constant_index = instr.bool_constant_index; + } + } break; + case ControlFlowOpcode::kAlloc: { + ParsedAllocInstruction instr; + ParseControlFlowAlloc(cf.alloc, cf_index, type() == xenos::ShaderType::kVertex, instr); + instr.Disassemble(&ucode_disasm_buffer); + } break; + case ControlFlowOpcode::kMarkVsFetchDone: + break; + default: + assert_unhandled_case(cf.opcode); + break; + } + if (bool_constant_index != UINT32_MAX) { + constant_register_map_.bool_bitmap[bool_constant_index / 32] |= + uint32_t(1) << (bool_constant_index % 32); + } + } + } + ucode_disassembly_ = ucode_disasm_buffer.to_string(); + + if (constant_register_map_.float_dynamic_addressing) { + // All potentially can be referenced. + constant_register_map_.float_count = 256; + memset(constant_register_map_.float_bitmap, UINT8_MAX, + sizeof(constant_register_map_.float_bitmap)); + } else { + constant_register_map_.float_count = 0; + for (int i = 0; i < 4; ++i) { + // Each bit indicates a vec4 (4 floats). + constant_register_map_.float_count += rex::bit_count(constant_register_map_.float_bitmap[i]); + } + } + + if (!cf_memexport_info_.empty()) { + // Gather potentially "dirty" memexport elements before each control flow + // instruction. `alloc` (any, not only `export`) flushes the previous memory + // export. On the guest GPU, yielding / serializing also terminates memory + // exports, but for simplicity disregarding that, as that functionally does + // nothing compared to flushing the previous memory export only at `alloc` + // or even only specifically at `alloc export`, Microsoft's validator checks + // if eM# aren't written after a `serialize`. + std::vector successor_stack; + for (uint32_t i = 0; i < cf_pair_index_bound_; ++i) { + ControlFlowInstruction eM_writing_cf_ab[2]; + UnpackControlFlowInstructions(ucode_data_.data() + i * 3, eM_writing_cf_ab); + for (uint32_t j = 0; j < 2; ++j) { + uint32_t eM_writing_cf_index = i * 2 + j; + uint32_t eM_written_by_cf_instr = + cf_memexport_info_[eM_writing_cf_index].eM_potentially_written_by_exec; + if (eM_writing_cf_ab[j].opcode() == ControlFlowOpcode::kCondCall) { + // Until subroutine calls are handled accurately, assume that all eM# + // have potentially been written by the subroutine for simplicity. + eM_written_by_cf_instr = memexport_eM_written_; + } + if (!eM_written_by_cf_instr) { + continue; + } + + // If the control flow instruction potentially results in any eM# being + // written, mark those eM# as potentially written before each successor. + bool is_successor_graph_head = true; + successor_stack.push_back(eM_writing_cf_index); + while (!successor_stack.empty()) { + uint32_t successor_cf_index = successor_stack.back(); + successor_stack.pop_back(); + + ControlFlowMemExportInfo& successor_memexport_info = + cf_memexport_info_[successor_cf_index]; + if ((successor_memexport_info.eM_potentially_written_before & eM_written_by_cf_instr) == + eM_written_by_cf_instr) { + // Already marked as written before this instruction (and thus + // before all its successors too). Possibly this instruction is in a + // loop, in this case an instruction may succeed itself. + break; + } + // The first instruction in the traversal is the writing instruction + // itself, not its successor. However, if it has been visited by the + // traversal twice, it's in a loop, so it succeeds itself, and thus + // writes from it are potentially done before it too. + if (!is_successor_graph_head) { + successor_memexport_info.eM_potentially_written_before |= eM_written_by_cf_instr; + } + is_successor_graph_head = false; + + ControlFlowInstruction successor_cf_ab[2]; + UnpackControlFlowInstructions(ucode_data_.data() + (successor_cf_index >> 1) * 3, + successor_cf_ab); + const ControlFlowInstruction& successor_cf = successor_cf_ab[successor_cf_index & 1]; + + bool next_instr_is_new_successor = true; + switch (successor_cf.opcode()) { + case ControlFlowOpcode::kExecEnd: + // One successor: end. + memexport_eM_potentially_written_before_end_ |= eM_written_by_cf_instr; + next_instr_is_new_successor = false; + break; + case ControlFlowOpcode::kCondExecEnd: + case ControlFlowOpcode::kCondExecPredEnd: + case ControlFlowOpcode::kCondExecPredCleanEnd: + // Two successors: next, end. + memexport_eM_potentially_written_before_end_ |= eM_written_by_cf_instr; + break; + case ControlFlowOpcode::kLoopStart: + // Two successors: next, skip. + successor_stack.push_back(successor_cf.loop_start.address()); + break; + case ControlFlowOpcode::kLoopEnd: + // Two successors: next, repeat. + successor_stack.push_back(successor_cf.loop_end.address()); + break; + case ControlFlowOpcode::kCondCall: + // Two successors: next, target. + successor_stack.push_back(successor_cf.cond_call.address()); + break; + case ControlFlowOpcode::kReturn: + // Currently treating all subroutine calls as potentially writing + // all eM# for simplicity, so just exit the subroutine. + next_instr_is_new_successor = false; + break; + case ControlFlowOpcode::kCondJmp: + // One or two successors: next if conditional, target. + successor_stack.push_back(successor_cf.cond_jmp.address()); + if (successor_cf.cond_jmp.is_unconditional()) { + next_instr_is_new_successor = false; + } + break; + case ControlFlowOpcode::kAlloc: + // Any `alloc` ends the previous export. + next_instr_is_new_successor = false; + break; + default: + break; + } + if (next_instr_is_new_successor) { + if (successor_cf_index < (cf_pair_index_bound_ << 1)) { + successor_stack.push_back(successor_cf_index + 1); + } else { + memexport_eM_potentially_written_before_end_ |= eM_written_by_cf_instr; + } + } + } + } + } + } + + is_ucode_analyzed_ = true; + + // An empty shader can be created internally by shader translators as a dummy, + // don't dump it. + if (!REXCVAR_GET(dump_shaders).empty() && !ucode_data().empty()) { + DumpUcode(REXCVAR_GET(dump_shaders)); + } +} + +uint32_t Shader::GetInterpolatorInputMask(reg::SQ_PROGRAM_CNTL sq_program_cntl, + reg::SQ_CONTEXT_MISC sq_context_misc, + uint32_t& param_gen_pos_out) const { + assert_true(type() == xenos::ShaderType::kPixel); + uint32_t interpolator_count = + std::min(xenos::kMaxInterpolators, + std::max(register_static_address_bound(), + GetDynamicAddressableRegisterCount(sq_program_cntl.ps_num_reg))); + uint32_t interpolator_mask = (UINT32_C(1) << interpolator_count) - 1; + if (sq_program_cntl.param_gen && sq_context_misc.param_gen_pos < interpolator_count) { + // Will be overwritten by PsParamGen. + interpolator_mask &= ~(UINT32_C(1) << sq_context_misc.param_gen_pos); + param_gen_pos_out = sq_context_misc.param_gen_pos; + } else { + param_gen_pos_out = UINT32_MAX; + } + return interpolator_mask; +} + +void Shader::GatherExecInformation(const ParsedExecInstruction& instr, + ucode::VertexFetchInstruction& previous_vfetch_full, + uint32_t& unique_texture_bindings, + string::StringBuffer& ucode_disasm_buffer) { + instr.Disassemble(&ucode_disasm_buffer); + uint32_t sequence = instr.sequence; + for (uint32_t instr_offset = instr.instruction_address; + instr_offset < instr.instruction_address + instr.instruction_count; + ++instr_offset, sequence >>= 2) { + ucode_disasm_buffer.AppendFormat("/* {:4d} */ ", instr_offset); + if (sequence & 0b10) { + ucode_disasm_buffer.Append(" serialize\n "); + } + const uint32_t* op_ptr = ucode_data_.data() + instr_offset * 3; + if (sequence & 0b01) { + auto& op = *reinterpret_cast(op_ptr); + if (op.opcode() == FetchOpcode::kVertexFetch) { + GatherVertexFetchInformation(op.vertex_fetch(), previous_vfetch_full, ucode_disasm_buffer); + } else { + GatherTextureFetchInformation(op.texture_fetch(), unique_texture_bindings, + ucode_disasm_buffer); + } + } else { + auto& op = *reinterpret_cast(op_ptr); + GatherAluInstructionInformation(op, instr.dword_index, ucode_disasm_buffer); + } + } +} + +void Shader::GatherVertexFetchInformation(const VertexFetchInstruction& op, + VertexFetchInstruction& previous_vfetch_full, + string::StringBuffer& ucode_disasm_buffer) { + ParsedVertexFetchInstruction fetch_instr; + if (ParseVertexFetchInstruction(op, previous_vfetch_full, fetch_instr)) { + previous_vfetch_full = op; + } + fetch_instr.Disassemble(&ucode_disasm_buffer); + + GatherFetchResultInformation(fetch_instr.result); + + // Mini-fetches inherit the operands from full fetches. + if (!fetch_instr.is_mini_fetch) { + for (size_t i = 0; i < fetch_instr.operand_count; ++i) { + GatherOperandInformation(fetch_instr.operands[i]); + } + } + + // Don't bother setting up a binding for an instruction that fetches nothing. + // In case of vfetch_full, however, it may still be used to set up addressing + // for the subsequent vfetch_mini, so operand information must still be + // gathered. + if (!fetch_instr.result.GetUsedResultComponents()) { + return; + } + + // Try to allocate an attribute on an existing binding. + // If no binding for this fetch slot is found create it. + using VertexBinding = Shader::VertexBinding; + VertexBinding::Attribute* attrib = nullptr; + for (auto& vertex_binding : vertex_bindings_) { + if (vertex_binding.fetch_constant == op.fetch_constant_index()) { + // It may not hold that all strides are equal, but I hope it does. + assert_true(!fetch_instr.attributes.stride || + vertex_binding.stride_words == fetch_instr.attributes.stride); + vertex_binding.attributes.push_back({}); + attrib = &vertex_binding.attributes.back(); + break; + } + } + if (!attrib) { + assert_not_zero(fetch_instr.attributes.stride); + VertexBinding vertex_binding; + vertex_binding.binding_index = int(vertex_bindings_.size()); + vertex_binding.fetch_constant = op.fetch_constant_index(); + vertex_binding.stride_words = fetch_instr.attributes.stride; + vertex_binding.attributes.push_back({}); + vertex_bindings_.emplace_back(std::move(vertex_binding)); + attrib = &vertex_bindings_.back().attributes.back(); + } + + // Populate attribute. + attrib->fetch_instr = fetch_instr; +} + +void Shader::GatherTextureFetchInformation(const TextureFetchInstruction& op, + uint32_t& unique_texture_bindings, + string::StringBuffer& ucode_disasm_buffer) { + TextureBinding binding; + ParseTextureFetchInstruction(op, binding.fetch_instr); + binding.fetch_instr.Disassemble(&ucode_disasm_buffer); + + GatherFetchResultInformation(binding.fetch_instr.result); + for (size_t i = 0; i < binding.fetch_instr.operand_count; ++i) { + GatherOperandInformation(binding.fetch_instr.operands[i]); + } + + if (binding.fetch_instr.result.GetUsedResultComponents()) { + uses_texture_fetch_instruction_results_ = true; + } + + switch (op.opcode()) { + case FetchOpcode::kSetTextureLod: + case FetchOpcode::kSetTextureGradientsHorz: + case FetchOpcode::kSetTextureGradientsVert: + // Doesn't use bindings. + return; + default: + // Continue. + break; + } + binding.binding_index = -1; + binding.fetch_constant = binding.fetch_instr.operands[1].storage_index; + + // Check and see if this fetch constant was previously used... + for (auto& tex_binding : texture_bindings_) { + if (tex_binding.fetch_constant == binding.fetch_constant) { + binding.binding_index = tex_binding.binding_index; + break; + } + } + + if (binding.binding_index == -1) { + // Assign a unique binding index. + binding.binding_index = unique_texture_bindings++; + } + + texture_bindings_.emplace_back(std::move(binding)); +} + +void Shader::GatherAluInstructionInformation(const AluInstruction& op, uint32_t exec_cf_index, + string::StringBuffer& ucode_disasm_buffer) { + ParsedAluInstruction instr; + ParseAluInstruction(op, type(), instr); + instr.Disassemble(&ucode_disasm_buffer); + + kills_pixels_ = kills_pixels_ || + (ucode::GetAluVectorOpcodeInfo(op.vector_opcode()).changed_state & + ucode::kAluOpChangedStatePixelKill) || + (ucode::GetAluScalarOpcodeInfo(op.scalar_opcode()).changed_state & + ucode::kAluOpChangedStatePixelKill); + + GatherAluResultInformation(instr.vector_and_constant_result, exec_cf_index); + GatherAluResultInformation(instr.scalar_result, exec_cf_index); + for (size_t i = 0; i < instr.vector_operand_count; ++i) { + GatherOperandInformation(instr.vector_operands[i]); + } + for (size_t i = 0; i < instr.scalar_operand_count; ++i) { + GatherOperandInformation(instr.scalar_operands[i]); + } + + // Store used memexport constants because CPU code needs addresses and sizes. + // eA is (hopefully) always written to using: + // mad eA, r#, const0100, c# + // (though there are some exceptions, shaders in 4D5307E6 for some reason set + // eA to zeros, but the swizzle of the constant is not .xyzw in this case, and + // they don't write to eM#). + // Export is done to vector_dest of the ucode instruction for both vector and + // scalar operations - no need to check separately. + if (instr.vector_and_constant_result.storage_target == InstructionStorageTarget::kExportAddress) { + uint32_t memexport_stream_constant = instr.GetMemExportStreamConstant(); + if (memexport_stream_constant != UINT32_MAX) { + memexport_stream_constants_.insert(memexport_stream_constant); + } else { + REXGPU_ERROR( + "ShaderTranslator::GatherAluInstructionInformation: Couldn't extract " + "memexport stream constant index"); + } + } +} + +void Shader::GatherOperandInformation(const InstructionOperand& operand) { + switch (operand.storage_source) { + case InstructionStorageSource::kRegister: + if (operand.storage_addressing_mode == InstructionStorageAddressingMode::kAbsolute) { + register_static_address_bound_ = + std::max(register_static_address_bound_, operand.storage_index + uint32_t(1)); + } else { + uses_register_dynamic_addressing_ = true; + } + break; + case InstructionStorageSource::kConstantFloat: + if (operand.storage_addressing_mode == InstructionStorageAddressingMode::kAbsolute) { + // Store used float constants before translating so the + // translator can use tightly packed indices if not dynamically + // indexed. + constant_register_map_.float_bitmap[operand.storage_index >> 6] |= + uint64_t(1) << (operand.storage_index & 63); + } else { + constant_register_map_.float_dynamic_addressing = true; + } + break; + case InstructionStorageSource::kVertexFetchConstant: + constant_register_map_.vertex_fetch_bitmap[operand.storage_index >> 5] |= + uint32_t(1) << (operand.storage_index & 31); + break; + default: + break; + } +} + +void Shader::GatherFetchResultInformation(const InstructionResult& result) { + if (!result.GetUsedWriteMask()) { + return; + } + // Fetch instructions can't export - don't need the current memexport count + // operand. + assert_true(result.storage_target == InstructionStorageTarget::kRegister); + if (result.storage_addressing_mode == InstructionStorageAddressingMode::kAbsolute) { + register_static_address_bound_ = + std::max(register_static_address_bound_, result.storage_index + uint32_t(1)); + } else { + uses_register_dynamic_addressing_ = true; + } +} + +void Shader::GatherAluResultInformation(const InstructionResult& result, uint32_t exec_cf_index) { + uint32_t used_write_mask = result.GetUsedWriteMask(); + if (!used_write_mask) { + return; + } + switch (result.storage_target) { + case InstructionStorageTarget::kRegister: + if (result.storage_addressing_mode == InstructionStorageAddressingMode::kAbsolute) { + register_static_address_bound_ = + std::max(register_static_address_bound_, result.storage_index + uint32_t(1)); + } else { + uses_register_dynamic_addressing_ = true; + } + break; + case InstructionStorageTarget::kInterpolator: + writes_interpolators_ |= uint32_t(1) << result.storage_index; + break; + case InstructionStorageTarget::kPointSizeEdgeFlagKillVertex: + writes_point_size_edge_flag_kill_vertex_ |= used_write_mask; + break; + case InstructionStorageTarget::kExportData: + memexport_eM_written_ |= uint8_t(1) << result.storage_index; + if (cf_memexport_info_.empty()) { + cf_memexport_info_.resize(2 * cf_pair_index_bound_); + } + cf_memexport_info_[exec_cf_index].eM_potentially_written_by_exec |= uint32_t(1) + << result.storage_index; + break; + case InstructionStorageTarget::kColor: + writes_color_targets_ |= uint32_t(1) << result.storage_index; + break; + case InstructionStorageTarget::kDepth: + writes_depth_ = true; + break; + default: + break; + } +} + +ShaderTranslator::ShaderTranslator() = default; + +ShaderTranslator::~ShaderTranslator() = default; + +void ShaderTranslator::Reset() { + errors_.clear(); + std::memset(&previous_vfetch_full_, 0, sizeof(previous_vfetch_full_)); +} + +bool ShaderTranslator::TranslateAnalyzedShader(Shader::Translation& translation) { + const Shader& shader = translation.shader(); + assert_true(shader.is_ucode_analyzed()); + if (!shader.is_ucode_analyzed()) { + REXGPU_ERROR("AnalyzeUcode must be done on the shader before translation"); + return false; + } + translation_ = &translation; + + Reset(); + + register_count_ = shader.register_static_address_bound(); + if (shader.uses_register_dynamic_addressing()) { + // An array of registers at the end of the r# space may be dynamically + // addressable - ensure enough space, as specified in SQ_PROGRAM_CNTL, is + // allocated. + register_count_ = std::max(register_count_, GetModificationRegisterCount()); + } + + StartTranslation(); + + const uint32_t* ucode_dwords = shader.ucode_data().data(); + + // TODO(Triang3l): Remove when the old SPIR-V shader translator is deleted. + uint32_t cf_pair_index_bound = shader.cf_pair_index_bound(); + std::vector cf_instructions; + for (uint32_t i = 0; i < cf_pair_index_bound; ++i) { + ControlFlowInstruction cf_ab[2]; + UnpackControlFlowInstructions(ucode_dwords + i * 3, cf_ab); + cf_instructions.push_back(cf_ab[0]); + cf_instructions.push_back(cf_ab[1]); + } + PreProcessControlFlowInstructions(cf_instructions); + + // Translate all instructions. + const std::set& label_addresses = shader.label_addresses(); + for (uint32_t i = 0; i < cf_pair_index_bound; ++i) { + ControlFlowInstruction cf_ab[2]; + UnpackControlFlowInstructions(ucode_dwords + i * 3, cf_ab); + for (uint32_t j = 0; j < 2; ++j) { + uint32_t cf_index = i * 2 + j; + cf_index_ = cf_index; + if (label_addresses.find(cf_index) != label_addresses.end()) { + ProcessLabel(cf_index); + } + ProcessControlFlowInstructionBegin(cf_index); + TranslateControlFlowInstruction(cf_ab[j]); + ProcessControlFlowInstructionEnd(cf_index); + } + } + + translation.errors_ = std::move(errors_); + translation.translated_binary_ = CompleteTranslation(); + translation.is_translated_ = true; + + bool is_valid = true; + for (const auto& error : translation.errors_) { + if (error.is_fatal) { + is_valid = false; + break; + } + } + translation.is_valid_ = is_valid; + + PostTranslation(); + + // In case is_valid_ is modified by PostTranslation, reload. + return translation.is_valid_; +} + +void ShaderTranslator::EmitTranslationError(const char* message, bool is_fatal) { + Shader::Error error; + error.is_fatal = is_fatal; + error.message = message; + // TODO(benvanik): location information. + errors_.push_back(std::move(error)); + REXGPU_ERROR("Shader translation {}error: {}", is_fatal ? "fatal " : "", message); +} + +void ShaderTranslator::TranslateControlFlowInstruction(const ControlFlowInstruction& cf) { + switch (cf.opcode()) { + case ControlFlowOpcode::kNop: + ProcessControlFlowNopInstruction(cf_index_); + break; + case ControlFlowOpcode::kExec: + case ControlFlowOpcode::kExecEnd: { + ParsedExecInstruction instr; + ParseControlFlowExec(cf.exec, cf_index_, instr); + TranslateExecInstructions(instr); + } break; + case ControlFlowOpcode::kCondExec: + case ControlFlowOpcode::kCondExecEnd: + case ControlFlowOpcode::kCondExecPredClean: + case ControlFlowOpcode::kCondExecPredCleanEnd: { + ParsedExecInstruction instr; + ParseControlFlowCondExec(cf.cond_exec, cf_index_, instr); + TranslateExecInstructions(instr); + } break; + case ControlFlowOpcode::kCondExecPred: + case ControlFlowOpcode::kCondExecPredEnd: { + ParsedExecInstruction instr; + ParseControlFlowCondExecPred(cf.cond_exec_pred, cf_index_, instr); + TranslateExecInstructions(instr); + } break; + case ControlFlowOpcode::kLoopStart: { + ParsedLoopStartInstruction instr; + ParseControlFlowLoopStart(cf.loop_start, cf_index_, instr); + ProcessLoopStartInstruction(instr); + } break; + case ControlFlowOpcode::kLoopEnd: { + ParsedLoopEndInstruction instr; + ParseControlFlowLoopEnd(cf.loop_end, cf_index_, instr); + ProcessLoopEndInstruction(instr); + } break; + case ControlFlowOpcode::kCondCall: { + ParsedCallInstruction instr; + ParseControlFlowCondCall(cf.cond_call, cf_index_, instr); + ProcessCallInstruction(instr); + } break; + case ControlFlowOpcode::kReturn: { + ParsedReturnInstruction instr; + ParseControlFlowReturn(cf.ret, cf_index_, instr); + ProcessReturnInstruction(instr); + } break; + case ControlFlowOpcode::kCondJmp: { + ParsedJumpInstruction instr; + ParseControlFlowCondJmp(cf.cond_jmp, cf_index_, instr); + ProcessJumpInstruction(instr); + } break; + case ControlFlowOpcode::kAlloc: { + ParsedAllocInstruction instr; + ParseControlFlowAlloc(cf.alloc, cf_index_, is_vertex_shader(), instr); + const std::vector& cf_memexport_info = + current_shader().cf_memexport_info(); + ProcessAllocInstruction( + instr, instr.dword_index < cf_memexport_info.size() + ? cf_memexport_info[instr.dword_index].eM_potentially_written_before + : 0); + } break; + case ControlFlowOpcode::kMarkVsFetchDone: + break; + default: + assert_unhandled_case(cf.opcode); + break; + } + // TODO(benvanik): return if (DoesControlFlowOpcodeEndShader(cf.opcode()))? +} + +void ParseControlFlowExec(const ControlFlowExecInstruction& cf, uint32_t cf_index, + ParsedExecInstruction& instr) { + instr.dword_index = cf_index; + instr.opcode = cf.opcode(); + instr.opcode_name = cf.opcode() == ControlFlowOpcode::kExecEnd ? "exece" : "exec"; + instr.instruction_address = cf.address(); + instr.instruction_count = cf.count(); + instr.type = ParsedExecInstruction::Type::kUnconditional; + instr.is_end = cf.opcode() == ControlFlowOpcode::kExecEnd; + instr.is_predicate_clean = cf.is_predicate_clean(); + instr.is_yield = cf.is_yield(); + instr.sequence = cf.sequence(); +} + +void ParseControlFlowCondExec(const ControlFlowCondExecInstruction& cf, uint32_t cf_index, + ParsedExecInstruction& instr) { + instr.dword_index = cf_index; + instr.opcode = cf.opcode(); + instr.opcode_name = "cexec"; + switch (cf.opcode()) { + case ControlFlowOpcode::kCondExecEnd: + case ControlFlowOpcode::kCondExecPredCleanEnd: + instr.opcode_name = "cexece"; + instr.is_end = true; + break; + default: + break; + } + instr.instruction_address = cf.address(); + instr.instruction_count = cf.count(); + instr.type = ParsedExecInstruction::Type::kConditional; + instr.bool_constant_index = cf.bool_address(); + instr.condition = cf.condition(); + switch (cf.opcode()) { + case ControlFlowOpcode::kCondExec: + case ControlFlowOpcode::kCondExecEnd: + instr.is_predicate_clean = false; + break; + default: + break; + } + instr.is_yield = cf.is_yield(); + instr.sequence = cf.sequence(); +} + +void ParseControlFlowCondExecPred(const ControlFlowCondExecPredInstruction& cf, uint32_t cf_index, + ParsedExecInstruction& instr) { + instr.dword_index = cf_index; + instr.opcode = cf.opcode(); + instr.opcode_name = cf.opcode() == ControlFlowOpcode::kCondExecPredEnd ? "exece" : "exec"; + instr.instruction_address = cf.address(); + instr.instruction_count = cf.count(); + instr.type = ParsedExecInstruction::Type::kPredicated; + instr.condition = cf.condition(); + instr.is_end = cf.opcode() == ControlFlowOpcode::kCondExecPredEnd; + instr.is_predicate_clean = cf.is_predicate_clean(); + instr.is_yield = cf.is_yield(); + instr.sequence = cf.sequence(); +} + +void ParseControlFlowLoopStart(const ControlFlowLoopStartInstruction& cf, uint32_t cf_index, + ParsedLoopStartInstruction& instr) { + instr.dword_index = cf_index; + instr.loop_constant_index = cf.loop_id(); + instr.is_repeat = cf.is_repeat(); + instr.loop_skip_address = cf.address(); +} + +void ParseControlFlowLoopEnd(const ControlFlowLoopEndInstruction& cf, uint32_t cf_index, + ParsedLoopEndInstruction& instr) { + instr.dword_index = cf_index; + instr.is_predicated_break = cf.is_predicated_break(); + instr.predicate_condition = cf.condition(); + instr.loop_constant_index = cf.loop_id(); + instr.loop_body_address = cf.address(); +} + +void ParseControlFlowCondCall(const ControlFlowCondCallInstruction& cf, uint32_t cf_index, + ParsedCallInstruction& instr) { + instr.dword_index = cf_index; + instr.target_address = cf.address(); + if (cf.is_unconditional()) { + instr.type = ParsedCallInstruction::Type::kUnconditional; + } else if (cf.is_predicated()) { + instr.type = ParsedCallInstruction::Type::kPredicated; + instr.condition = cf.condition(); + } else { + instr.type = ParsedCallInstruction::Type::kConditional; + instr.bool_constant_index = cf.bool_address(); + instr.condition = cf.condition(); + } +} + +void ParseControlFlowReturn(const ControlFlowReturnInstruction& cf, uint32_t cf_index, + ParsedReturnInstruction& instr) { + instr.dword_index = cf_index; +} + +void ParseControlFlowCondJmp(const ControlFlowCondJmpInstruction& cf, uint32_t cf_index, + ParsedJumpInstruction& instr) { + instr.dword_index = cf_index; + instr.target_address = cf.address(); + if (cf.is_unconditional()) { + instr.type = ParsedJumpInstruction::Type::kUnconditional; + } else if (cf.is_predicated()) { + instr.type = ParsedJumpInstruction::Type::kPredicated; + instr.condition = cf.condition(); + } else { + instr.type = ParsedJumpInstruction::Type::kConditional; + instr.bool_constant_index = cf.bool_address(); + instr.condition = cf.condition(); + } +} + +void ParseControlFlowAlloc(const ControlFlowAllocInstruction& cf, uint32_t cf_index, + bool is_vertex_shader, ParsedAllocInstruction& instr) { + instr.dword_index = cf_index; + instr.type = cf.alloc_type(); + instr.count = cf.size(); + instr.is_vertex_shader = is_vertex_shader; +} + +void ShaderTranslator::TranslateExecInstructions(const ParsedExecInstruction& instr) { + ProcessExecInstructionBegin(instr); + + const std::vector& cf_memexport_info = + current_shader().cf_memexport_info(); + uint8_t eM_potentially_written_before = + instr.dword_index < cf_memexport_info.size() + ? cf_memexport_info[instr.dword_index].eM_potentially_written_before + : 0; + + const uint32_t* ucode_dwords = current_shader().ucode_data().data(); + uint32_t sequence = instr.sequence; + for (uint32_t instr_offset = instr.instruction_address; + instr_offset < instr.instruction_address + instr.instruction_count; + ++instr_offset, sequence >>= 2) { + const uint32_t* op_ptr = ucode_dwords + instr_offset * 3; + if (sequence & 0b01) { + auto& op = *reinterpret_cast(op_ptr); + if (op.opcode() == FetchOpcode::kVertexFetch) { + const VertexFetchInstruction& vfetch_op = op.vertex_fetch(); + ParsedVertexFetchInstruction vfetch_instr; + if (ParseVertexFetchInstruction(vfetch_op, previous_vfetch_full_, vfetch_instr)) { + previous_vfetch_full_ = vfetch_op; + } + ProcessVertexFetchInstruction(vfetch_instr); + } else { + ParsedTextureFetchInstruction tfetch_instr; + ParseTextureFetchInstruction(op.texture_fetch(), tfetch_instr); + ProcessTextureFetchInstruction(tfetch_instr); + } + } else { + auto& op = *reinterpret_cast(op_ptr); + ParsedAluInstruction alu_instr; + ParseAluInstruction(op, current_shader().type(), alu_instr); + ProcessAluInstruction(alu_instr, eM_potentially_written_before); + if (alu_instr.vector_and_constant_result.storage_target == + InstructionStorageTarget::kExportData && + alu_instr.vector_and_constant_result.GetUsedWriteMask()) { + eM_potentially_written_before |= uint8_t(1) + << alu_instr.vector_and_constant_result.storage_index; + } + if (alu_instr.scalar_result.storage_target == InstructionStorageTarget::kExportData && + alu_instr.scalar_result.GetUsedWriteMask()) { + eM_potentially_written_before |= uint8_t(1) << alu_instr.scalar_result.storage_index; + } + } + } + + ProcessExecInstructionEnd(instr); +} + +static void ParseFetchInstructionResult(uint32_t dest, uint32_t swizzle, bool is_relative, + InstructionResult& result) { + result.storage_target = InstructionStorageTarget::kRegister; + result.storage_index = dest; + result.is_clamped = false; + result.storage_addressing_mode = is_relative ? InstructionStorageAddressingMode::kLoopRelative + : InstructionStorageAddressingMode::kAbsolute; + result.original_write_mask = 0b1111; + for (int i = 0; i < 4; ++i) { + SwizzleSource component_source = SwizzleSource::k0; + ucode::FetchDestinationSwizzle component_swizzle = + ucode::GetFetchDestinationComponentSwizzle(swizzle, i); + switch (component_swizzle) { + case ucode::FetchDestinationSwizzle::kX: + component_source = SwizzleSource::kX; + break; + case ucode::FetchDestinationSwizzle::kY: + component_source = SwizzleSource::kY; + break; + case ucode::FetchDestinationSwizzle::kZ: + component_source = SwizzleSource::kZ; + break; + case ucode::FetchDestinationSwizzle::kW: + component_source = SwizzleSource::kW; + break; + case ucode::FetchDestinationSwizzle::k1: + component_source = SwizzleSource::k1; + break; + case ucode::FetchDestinationSwizzle::kKeep: + result.original_write_mask &= ~(UINT32_C(1) << i); + break; + default: + // ucode::FetchDestinationSwizzle::k0 or the invalid swizzle 6. + // TODO(Triang3l): Find the correct handling of the invalid swizzle 6. + assert_true(component_swizzle == ucode::FetchDestinationSwizzle::k0); + component_source = SwizzleSource::k0; + break; + } + result.components[i] = component_source; + } +} + +bool ParseVertexFetchInstruction(const VertexFetchInstruction& op, + const VertexFetchInstruction& previous_full_op, + ParsedVertexFetchInstruction& instr) { + instr.opcode = FetchOpcode::kVertexFetch; + instr.opcode_name = op.is_mini_fetch() ? "vfetch_mini" : "vfetch_full"; + instr.is_mini_fetch = op.is_mini_fetch(); + instr.is_predicated = op.is_predicated(); + instr.predicate_condition = op.predicate_condition(); + + ParseFetchInstructionResult(op.dest(), op.dest_swizzle(), op.is_dest_relative(), instr.result); + + // Reuse previous vfetch_full if this is a mini. + const auto& full_op = op.is_mini_fetch() ? previous_full_op : op; + auto& src_op = instr.operands[instr.operand_count++]; + src_op.storage_source = InstructionStorageSource::kRegister; + src_op.storage_index = full_op.src(); + src_op.storage_addressing_mode = full_op.is_src_relative() + ? InstructionStorageAddressingMode::kLoopRelative + : InstructionStorageAddressingMode::kAbsolute; + src_op.is_negated = false; + src_op.is_absolute_value = false; + src_op.component_count = 1; + uint32_t swizzle = full_op.src_swizzle(); + for (uint32_t j = 0; j < src_op.component_count; ++j, swizzle >>= 2) { + src_op.components[j] = GetSwizzleFromComponentIndex(swizzle & 0x3); + } + + auto& const_op = instr.operands[instr.operand_count++]; + const_op.storage_source = InstructionStorageSource::kVertexFetchConstant; + const_op.storage_index = full_op.fetch_constant_index(); + + instr.attributes.data_format = op.data_format(); + instr.attributes.offset = op.offset(); + instr.attributes.stride = full_op.stride(); + instr.attributes.exp_adjust = op.exp_adjust(); + instr.attributes.prefetch_count = op.prefetch_count(); + instr.attributes.is_index_rounded = full_op.is_index_rounded(); + instr.attributes.is_signed = op.is_signed(); + instr.attributes.is_integer = !op.is_normalized(); + instr.attributes.signed_rf_mode = op.signed_rf_mode(); + + return !op.is_mini_fetch(); +} + +void ParseTextureFetchInstruction(const TextureFetchInstruction& op, + ParsedTextureFetchInstruction& instr) { + struct TextureFetchOpcodeInfo { + const char* name; + bool has_dest; + bool has_const; + bool has_attributes; + uint32_t override_component_count; + } opcode_info; + switch (op.opcode()) { + case FetchOpcode::kTextureFetch: { + static const char* kNames[] = {"tfetch1D", "tfetch2D", "tfetch3D", "tfetchCube"}; + opcode_info = {kNames[static_cast(op.dimension())], true, true, true, 0}; + } break; + case FetchOpcode::kGetTextureBorderColorFrac: { + static const char* kNames[] = {"getBCF1D", "getBCF2D", "getBCF3D", "getBCFCube"}; + opcode_info = {kNames[static_cast(op.dimension())], true, true, true, 0}; + } break; + case FetchOpcode::kGetTextureComputedLod: { + static const char* kNames[] = {"getCompTexLOD1D", "getCompTexLOD2D", "getCompTexLOD3D", + "getCompTexLODCube"}; + opcode_info = {kNames[static_cast(op.dimension())], true, true, true, 0}; + } break; + case FetchOpcode::kGetTextureGradients: + opcode_info = {"getGradients", true, true, true, 2}; + break; + case FetchOpcode::kGetTextureWeights: { + static const char* kNames[] = {"getWeights1D", "getWeights2D", "getWeights3D", + "getWeightsCube"}; + opcode_info = {kNames[static_cast(op.dimension())], true, true, true, 0}; + } break; + case FetchOpcode::kSetTextureLod: + opcode_info = {"setTexLOD", false, false, false, 1}; + break; + case FetchOpcode::kSetTextureGradientsHorz: + opcode_info = {"setGradientH", false, false, false, 3}; + break; + case FetchOpcode::kSetTextureGradientsVert: + opcode_info = {"setGradientV", false, false, false, 3}; + break; + default: + assert_unhandled_case(fetch_opcode); + return; + } + + instr.opcode = op.opcode(); + instr.opcode_name = opcode_info.name; + instr.dimension = op.dimension(); + instr.is_predicated = op.is_predicated(); + instr.predicate_condition = op.predicate_condition(); + + if (opcode_info.has_dest) { + ParseFetchInstructionResult(op.dest(), op.dest_swizzle(), op.is_dest_relative(), instr.result); + } else { + instr.result.storage_target = InstructionStorageTarget::kNone; + } + + auto& src_op = instr.operands[instr.operand_count++]; + src_op.storage_source = InstructionStorageSource::kRegister; + src_op.storage_index = op.src(); + src_op.storage_addressing_mode = op.is_src_relative() + ? InstructionStorageAddressingMode::kLoopRelative + : InstructionStorageAddressingMode::kAbsolute; + src_op.is_negated = false; + src_op.is_absolute_value = false; + src_op.component_count = opcode_info.override_component_count + ? opcode_info.override_component_count + : xenos::GetFetchOpDimensionComponentCount(op.dimension()); + uint32_t swizzle = op.src_swizzle(); + for (uint32_t j = 0; j < src_op.component_count; ++j, swizzle >>= 2) { + src_op.components[j] = GetSwizzleFromComponentIndex(swizzle & 0x3); + } + + if (opcode_info.has_const) { + auto& const_op = instr.operands[instr.operand_count++]; + const_op.storage_source = InstructionStorageSource::kTextureFetchConstant; + const_op.storage_index = op.fetch_constant_index(); + } + + if (opcode_info.has_attributes) { + instr.attributes.fetch_valid_only = op.fetch_valid_only(); + instr.attributes.unnormalized_coordinates = op.unnormalized_coordinates(); + instr.attributes.mag_filter = op.mag_filter(); + instr.attributes.min_filter = op.min_filter(); + instr.attributes.mip_filter = op.mip_filter(); + instr.attributes.aniso_filter = op.aniso_filter(); + instr.attributes.vol_mag_filter = op.vol_mag_filter(); + instr.attributes.vol_min_filter = op.vol_min_filter(); + instr.attributes.use_computed_lod = op.use_computed_lod(); + instr.attributes.use_register_lod = op.use_register_lod(); + instr.attributes.use_register_gradients = op.use_register_gradients(); + instr.attributes.lod_bias = op.lod_bias(); + instr.attributes.offset_x = op.offset_x(); + instr.attributes.offset_y = op.offset_y(); + instr.attributes.offset_z = op.offset_z(); + } +} + +uint32_t ParsedTextureFetchInstruction::GetNonZeroResultComponents() const { + uint32_t components = 0b0000; + switch (opcode) { + case FetchOpcode::kTextureFetch: + case FetchOpcode::kGetTextureGradients: + components = 0b1111; + break; + case FetchOpcode::kGetTextureBorderColorFrac: + components = 0b0001; + break; + case FetchOpcode::kGetTextureComputedLod: + // Not checking if the MipFilter is basemap because XNA doesn't accept + // MipFilter for getCompTexLOD. + components = 0b0001; + break; + case FetchOpcode::kGetTextureWeights: + // FIXME(Triang3l): Not caring about mag/min filters currently for + // simplicity. It's very unlikely that this instruction is ever seriously + // used to retrieve weights of zero though. + switch (dimension) { + case xenos::FetchOpDimension::k1D: + components = 0b1001; + break; + case xenos::FetchOpDimension::k2D: + case xenos::FetchOpDimension::kCube: + // TODO(Triang3l): Is the depth lerp factor always 0 for cube maps? + components = 0b1011; + break; + case xenos::FetchOpDimension::k3DOrStacked: + components = 0b1111; + break; + } + if (attributes.mip_filter == xenos::TextureFilter::kBaseMap || + attributes.mip_filter == xenos::TextureFilter::kPoint) { + components &= ~uint32_t(0b1000); + } + break; + case FetchOpcode::kSetTextureLod: + case FetchOpcode::kSetTextureGradientsHorz: + case FetchOpcode::kSetTextureGradientsVert: + components = 0b0000; + break; + default: + assert_unhandled_case(opcode); + } + return result.GetUsedResultComponents() & components; +} + +static void ParseAluInstructionOperand(const AluInstruction& op, uint32_t i, + uint32_t swizzle_component_count, + InstructionOperand& out_op) { + out_op.is_negated = op.src_negate(i); + uint32_t reg = op.src_reg(i); + if (op.src_is_temp(i)) { + out_op.storage_source = InstructionStorageSource::kRegister; + out_op.storage_index = AluInstruction::src_temp_reg(reg); + out_op.is_absolute_value = AluInstruction::is_src_temp_value_absolute(reg); + out_op.storage_addressing_mode = AluInstruction::is_src_temp_relative(reg) + ? InstructionStorageAddressingMode::kLoopRelative + : InstructionStorageAddressingMode::kAbsolute; + } else { + out_op.storage_source = InstructionStorageSource::kConstantFloat; + out_op.storage_index = reg; + if (op.src_const_is_addressed(i)) { + if (op.is_const_address_register_relative()) { + out_op.storage_addressing_mode = InstructionStorageAddressingMode::kAddressRegisterRelative; + } else { + out_op.storage_addressing_mode = InstructionStorageAddressingMode::kLoopRelative; + } + } else { + out_op.storage_addressing_mode = InstructionStorageAddressingMode::kAbsolute; + } + out_op.is_absolute_value = op.abs_constants(); + } + out_op.component_count = swizzle_component_count; + uint32_t swizzle = op.src_swizzle(i); + if (swizzle_component_count == 1) { + // Scalar `a` (W). + out_op.components[0] = GetSwizzledAluSourceComponent(swizzle, 3); + } else if (swizzle_component_count == 2) { + // Scalar left-hand `a` (W) and right-hand `b` (X). + out_op.components[0] = GetSwizzledAluSourceComponent(swizzle, 3); + out_op.components[1] = GetSwizzledAluSourceComponent(swizzle, 0); + } else if (swizzle_component_count == 3) { + assert_always(); + } else if (swizzle_component_count == 4) { + for (uint32_t j = 0; j < swizzle_component_count; ++j) { + out_op.components[j] = GetSwizzledAluSourceComponent(swizzle, j); + } + } +} + +bool ParsedAluInstruction::IsVectorOpDefaultNop() const { + if (vector_opcode != ucode::AluVectorOpcode::kMax || + vector_and_constant_result.original_write_mask || vector_and_constant_result.is_clamped || + vector_operands[0].storage_source != InstructionStorageSource::kRegister || + vector_operands[0].storage_index != 0 || + vector_operands[0].storage_addressing_mode != InstructionStorageAddressingMode::kAbsolute || + vector_operands[0].is_negated || vector_operands[0].is_absolute_value || + !vector_operands[0].IsStandardSwizzle() || + vector_operands[1].storage_source != InstructionStorageSource::kRegister || + vector_operands[1].storage_index != 0 || + vector_operands[1].storage_addressing_mode != InstructionStorageAddressingMode::kAbsolute || + vector_operands[1].is_negated || vector_operands[1].is_absolute_value || + !vector_operands[1].IsStandardSwizzle()) { + return false; + } + if (vector_and_constant_result.storage_target == InstructionStorageTarget::kRegister) { + if (vector_and_constant_result.storage_index != 0 || + vector_and_constant_result.storage_addressing_mode != + InstructionStorageAddressingMode::kAbsolute) { + return false; + } + } else { + // In case both vector and scalar operations are nop, still need to write + // somewhere that it's an export, not mov r0._, r0 + retain_prev r0._. + // Accurate round trip is possible only if the target is o0 or oC0, because + // if the total write mask is empty, the XNA assembler forces the + // destination to be o0/oC0, but this doesn't really matter in this case. + if (IsScalarOpDefaultNop()) { + return false; + } + } + return true; +} + +void ParseAluInstruction(const AluInstruction& op, xenos::ShaderType shader_type, + ParsedAluInstruction& instr) { + instr.is_predicated = op.is_predicated(); + instr.predicate_condition = op.predicate_condition(); + + bool is_export = op.is_export(); + + InstructionStorageTarget storage_target = InstructionStorageTarget::kRegister; + uint32_t storage_index_export = 0; + if (is_export) { + storage_target = InstructionStorageTarget::kNone; + // Both vector and scalar operation export to vector_dest. + ExportRegister export_register = ExportRegister(op.vector_dest()); + if (export_register == ExportRegister::kExportAddress) { + storage_target = InstructionStorageTarget::kExportAddress; + } else if (export_register >= ExportRegister::kExportData0 && + export_register <= ExportRegister::kExportData4) { + storage_target = InstructionStorageTarget::kExportData; + storage_index_export = uint32_t(export_register) - uint32_t(ExportRegister::kExportData0); + } else if (shader_type == xenos::ShaderType::kVertex) { + if (export_register >= ExportRegister::kVSInterpolator0 && + export_register <= ExportRegister::kVSInterpolator15) { + storage_target = InstructionStorageTarget::kInterpolator; + storage_index_export = + uint32_t(export_register) - uint32_t(ExportRegister::kVSInterpolator0); + } else if (export_register == ExportRegister::kVSPosition) { + storage_target = InstructionStorageTarget::kPosition; + } else if (export_register == ExportRegister::kVSPointSizeEdgeFlagKillVertex) { + storage_target = InstructionStorageTarget::kPointSizeEdgeFlagKillVertex; + } + } else if (shader_type == xenos::ShaderType::kPixel) { + if (export_register >= ExportRegister::kPSColor0 && + export_register <= ExportRegister::kPSColor3) { + storage_target = InstructionStorageTarget::kColor; + storage_index_export = uint32_t(export_register) - uint32_t(ExportRegister::kPSColor0); + } else if (export_register == ExportRegister::kPSDepth) { + storage_target = InstructionStorageTarget::kDepth; + } + } + if (storage_target == InstructionStorageTarget::kNone) { + assert_always(); + REXGPU_ERROR( + "ShaderTranslator::ParseAluInstruction: Unsupported write to export " + "{}", + uint32_t(export_register)); + } + } + + // Vector operation and constant 0/1 writes. + + ucode::AluVectorOpcode vector_opcode = op.vector_opcode(); + instr.vector_opcode = vector_opcode; + const ucode::AluVectorOpcodeInfo& vector_opcode_info = + ucode::GetAluVectorOpcodeInfo(vector_opcode); + instr.vector_opcode_name = vector_opcode_info.name; + + instr.vector_and_constant_result.storage_target = storage_target; + instr.vector_and_constant_result.storage_addressing_mode = + InstructionStorageAddressingMode::kAbsolute; + if (is_export) { + instr.vector_and_constant_result.storage_index = storage_index_export; + } else { + instr.vector_and_constant_result.storage_index = op.vector_dest(); + if (op.is_vector_dest_relative()) { + instr.vector_and_constant_result.storage_addressing_mode = + InstructionStorageAddressingMode::kLoopRelative; + } + } + instr.vector_and_constant_result.is_clamped = op.vector_clamp(); + uint32_t constant_0_mask = op.GetConstant0WriteMask(); + uint32_t constant_1_mask = op.GetConstant1WriteMask(); + instr.vector_and_constant_result.original_write_mask = + op.GetVectorOpResultWriteMask() | constant_0_mask | constant_1_mask; + for (uint32_t i = 0; i < 4; ++i) { + SwizzleSource component = GetSwizzleFromComponentIndex(i); + if (constant_0_mask & (1 << i)) { + component = SwizzleSource::k0; + } else if (constant_1_mask & (1 << i)) { + component = SwizzleSource::k1; + } + instr.vector_and_constant_result.components[i] = component; + } + + instr.vector_operand_count = vector_opcode_info.GetOperandCount(); + for (uint32_t i = 0; i < instr.vector_operand_count; ++i) { + InstructionOperand& vector_operand = instr.vector_operands[i]; + ParseAluInstructionOperand(op, i + 1, 4, vector_operand); + } + + // Scalar operation. + + ucode::AluScalarOpcode scalar_opcode = op.scalar_opcode(); + instr.scalar_opcode = scalar_opcode; + const ucode::AluScalarOpcodeInfo& scalar_opcode_info = + ucode::GetAluScalarOpcodeInfo(scalar_opcode); + instr.scalar_opcode_name = scalar_opcode_info.name; + + instr.scalar_result.storage_target = storage_target; + instr.scalar_result.storage_addressing_mode = InstructionStorageAddressingMode::kAbsolute; + if (is_export) { + instr.scalar_result.storage_index = storage_index_export; + } else { + instr.scalar_result.storage_index = op.scalar_dest(); + if (op.is_scalar_dest_relative()) { + instr.scalar_result.storage_addressing_mode = InstructionStorageAddressingMode::kLoopRelative; + } + } + instr.scalar_result.is_clamped = op.scalar_clamp(); + instr.scalar_result.original_write_mask = op.GetScalarOpResultWriteMask(); + for (uint32_t i = 0; i < 4; ++i) { + instr.scalar_result.components[i] = GetSwizzleFromComponentIndex(i); + } + + instr.scalar_operand_count = scalar_opcode_info.operand_count; + if (instr.scalar_operand_count) { + if (instr.scalar_operand_count == 1) { + ParseAluInstructionOperand(op, 3, scalar_opcode_info.single_operand_is_two_component ? 2 : 1, + instr.scalar_operands[0]); + } else { + // Constant and temporary register. + + bool src3_negate = op.src_negate(3); + uint32_t src3_swizzle = op.src_swizzle(3); + + // Left-hand constant operand (`a` - W swizzle). + InstructionOperand& const_op = instr.scalar_operands[0]; + const_op.is_negated = src3_negate; + const_op.is_absolute_value = op.abs_constants(); + const_op.storage_source = InstructionStorageSource::kConstantFloat; + const_op.storage_index = op.src_reg(3); + if (op.src_const_is_addressed(3)) { + if (op.is_const_address_register_relative()) { + const_op.storage_addressing_mode = + InstructionStorageAddressingMode::kAddressRegisterRelative; + } else { + const_op.storage_addressing_mode = InstructionStorageAddressingMode::kLoopRelative; + } + } else { + const_op.storage_addressing_mode = InstructionStorageAddressingMode::kAbsolute; + } + const_op.component_count = 1; + const_op.components[0] = GetSwizzledAluSourceComponent(src3_swizzle, 3); + + // Right-hand temporary register operand (`b` - X swizzle). + InstructionOperand& temp_op = instr.scalar_operands[1]; + temp_op.is_negated = src3_negate; + temp_op.is_absolute_value = op.abs_constants(); + temp_op.storage_source = InstructionStorageSource::kRegister; + temp_op.storage_index = op.scalar_const_reg_op_src_temp_reg(); + temp_op.storage_addressing_mode = InstructionStorageAddressingMode::kAbsolute; + temp_op.component_count = 1; + temp_op.components[0] = GetSwizzledAluSourceComponent(src3_swizzle, 0); + } + } +} + +bool ParsedAluInstruction::IsScalarOpDefaultNop() const { + if (scalar_opcode != ucode::AluScalarOpcode::kRetainPrev || scalar_result.original_write_mask || + scalar_result.is_clamped) { + return false; + } + if (scalar_result.storage_target == InstructionStorageTarget::kRegister) { + if (scalar_result.storage_index != 0 || + scalar_result.storage_addressing_mode != InstructionStorageAddressingMode::kAbsolute) { + return false; + } + } + // For exports, if both are nop, the vector operation will be kept to state in + // the microcode that the destination in the microcode is an export. + return true; +} + +bool ParsedAluInstruction::IsNop() const { + return scalar_opcode == ucode::AluScalarOpcode::kRetainPrev && + !scalar_result.GetUsedWriteMask() && !vector_and_constant_result.GetUsedWriteMask() && + !ucode::GetAluVectorOpcodeInfo(vector_opcode).changed_state; +} + +uint32_t ParsedAluInstruction::GetMemExportStreamConstant() const { + if (vector_and_constant_result.storage_target == InstructionStorageTarget::kExportAddress && + vector_opcode == ucode::AluVectorOpcode::kMad && + vector_and_constant_result.GetUsedResultComponents() == 0b1111 && + !vector_and_constant_result.is_clamped && + vector_operands[2].storage_source == InstructionStorageSource::kConstantFloat && + vector_operands[2].storage_addressing_mode == InstructionStorageAddressingMode::kAbsolute && + vector_operands[2].IsStandardSwizzle() && !vector_operands[2].is_negated && + !vector_operands[2].is_absolute_value) { + return vector_operands[2].storage_index; + } + return UINT32_MAX; +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/shader/translator_disasm.cpp b/src/graphics/pipeline/shader/translator_disasm.cpp new file mode 100644 index 0000000..c403010 --- /dev/null +++ b/src/graphics/pipeline/shader/translator_disasm.cpp @@ -0,0 +1,507 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include + +namespace rex::graphics { + +using namespace ucode; + +void DisassembleResultOperand(const InstructionResult& result, string::StringBuffer* out) { + bool uses_storage_index = false; + switch (result.storage_target) { + case InstructionStorageTarget::kRegister: + out->Append('r'); + uses_storage_index = true; + break; + case InstructionStorageTarget::kInterpolator: + out->Append('o'); + uses_storage_index = true; + break; + case InstructionStorageTarget::kPosition: + out->Append("oPos"); + break; + case InstructionStorageTarget::kPointSizeEdgeFlagKillVertex: + out->Append("oPts"); + break; + case InstructionStorageTarget::kExportAddress: + out->Append("eA"); + break; + case InstructionStorageTarget::kExportData: + out->Append("eM"); + uses_storage_index = true; + break; + case InstructionStorageTarget::kColor: + out->Append("oC"); + uses_storage_index = true; + break; + case InstructionStorageTarget::kDepth: + out->Append("oDepth"); + break; + case InstructionStorageTarget::kNone: + break; + } + if (uses_storage_index) { + switch (result.storage_addressing_mode) { + case InstructionStorageAddressingMode::kAbsolute: + out->AppendFormat("{}", result.storage_index); + break; + case InstructionStorageAddressingMode::kAddressRegisterRelative: + out->AppendFormat("[{}+a0]", result.storage_index); + break; + case InstructionStorageAddressingMode::kLoopRelative: + out->AppendFormat("[{}+aL]", result.storage_index); + break; + } + } + // Not using GetUsedWriteMask/IsStandardSwizzle because they filter out + // components not having any runtime effect, but those components are still + // present in the microcode. + if (!result.original_write_mask) { + out->Append("._"); + } else if (result.original_write_mask != 0b1111 || result.components[0] != SwizzleSource::kX || + result.components[1] != SwizzleSource::kY || + result.components[2] != SwizzleSource::kZ || + result.components[3] != SwizzleSource::kW) { + out->Append('.'); + for (int i = 0; i < 4; ++i) { + if (result.original_write_mask & (1 << i)) { + out->Append(GetCharForSwizzle(result.components[i])); + } else { + out->Append('_'); + } + } + } +} + +void DisassembleSourceOperand(const InstructionOperand& op, string::StringBuffer* out) { + if (op.is_negated) { + out->Append('-'); + } + switch (op.storage_source) { + case InstructionStorageSource::kRegister: + out->Append('r'); + break; + case InstructionStorageSource::kConstantFloat: + out->Append('c'); + break; + case InstructionStorageSource::kTextureFetchConstant: + case InstructionStorageSource::kVertexFetchConstant: + assert_always(); + break; + } + if (op.is_absolute_value) { + out->Append("_abs"); + } + switch (op.storage_addressing_mode) { + case InstructionStorageAddressingMode::kAbsolute: + if (op.is_absolute_value) { + out->AppendFormat("[{}]", op.storage_index); + } else { + out->AppendFormat("{}", op.storage_index); + } + break; + case InstructionStorageAddressingMode::kAddressRegisterRelative: + out->AppendFormat("[{}+a0]", op.storage_index); + break; + case InstructionStorageAddressingMode::kLoopRelative: + out->AppendFormat("[{}+aL]", op.storage_index); + break; + } + if (!op.IsStandardSwizzle()) { + out->Append('.'); + if (op.component_count == 1) { + out->Append(GetCharForSwizzle(op.components[0])); + } else if (op.component_count == 2) { + out->Append(GetCharForSwizzle(op.components[0])); + out->Append(GetCharForSwizzle(op.components[1])); + } else { + for (uint32_t j = 0; j < op.component_count; ++j) { + out->Append(GetCharForSwizzle(op.components[j])); + } + } + } +} + +void ParsedExecInstruction::Disassemble(string::StringBuffer* out) const { + switch (type) { + case Type::kUnconditional: + out->AppendFormat(" {}", opcode_name); + break; + case Type::kPredicated: + out->Append(condition ? " (p0) " : "(!p0) "); + out->AppendFormat("{}", opcode_name); + break; + case Type::kConditional: + out->AppendFormat(" {} {}b{}", opcode_name, condition ? "" : "!", bool_constant_index); + break; + } + if (is_yield) { + if (type == Type::kConditional) { + // For `exec` or `(p0) exec` (but not `cexec`), "unexpected token ','" if + // preceded by a comma. + out->Append(','); + } + out->Append(" Yield=true"); + } + if (!is_predicate_clean) { + out->Append(" // PredicateClean=false"); + } + out->Append('\n'); +} + +void ParsedLoopStartInstruction::Disassemble(string::StringBuffer* out) const { + out->Append(" loop "); + out->AppendFormat("i{}, L{}", loop_constant_index, loop_skip_address); + if (is_repeat) { + out->Append(", Repeat=true"); + } + out->Append('\n'); +} + +void ParsedLoopEndInstruction::Disassemble(string::StringBuffer* out) const { + if (is_predicated_break) { + out->Append(predicate_condition ? " (p0) " : "(!p0) "); + } else { + out->Append(" "); + } + out->AppendFormat("endloop i{}, L{}", loop_constant_index, loop_body_address); + out->Append('\n'); +} + +void ParsedCallInstruction::Disassemble(string::StringBuffer* out) const { + switch (type) { + case Type::kUnconditional: + out->Append(" call "); + break; + case Type::kPredicated: + out->Append(condition ? " (p0) " : "(!p0) "); + out->Append("call "); + break; + case Type::kConditional: + out->Append(" ccall "); + if (!condition) { + out->Append('!'); + } + out->AppendFormat("b{}, ", bool_constant_index); + break; + } + out->AppendFormat("L{}", target_address); + out->Append('\n'); +} + +void ParsedReturnInstruction::Disassemble(string::StringBuffer* out) const { + out->Append(" ret\n"); +} + +void ParsedJumpInstruction::Disassemble(string::StringBuffer* out) const { + switch (type) { + case Type::kUnconditional: + out->Append(" jmp "); + break; + case Type::kPredicated: + out->Append(condition ? " (p0) " : "(!p0) "); + out->Append("jmp "); + break; + case Type::kConditional: + out->Append(" cjmp "); + if (!condition) { + out->Append('!'); + } + out->AppendFormat("b{}, ", bool_constant_index); + break; + } + out->AppendFormat("L{}", target_address); + out->Append('\n'); +} + +void ParsedAllocInstruction::Disassemble(string::StringBuffer* out) const { + out->Append(" alloc "); + switch (type) { + case AllocType::kNone: + break; + case AllocType::kVsPosition: + out->Append("position"); + break; + case AllocType::kVsInterpolators: // or AllocType::kPsColors + if (is_vertex_shader) { + out->Append("interpolators"); + } else { + out->Append("colors"); + } + break; + case AllocType::kMemory: + out->AppendFormat("export = {}", count); + break; + } + out->Append('\n'); +} + +void ParsedVertexFetchInstruction::Disassemble(string::StringBuffer* out) const { + static const struct { + const char* name; + } kVertexFetchDataFormats[0xff] = { +#define TYPE(id) \ + { #id } + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + TYPE(FMT_8_8_8_8), // 6 + TYPE(FMT_2_10_10_10), // 7 + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + TYPE(FMT_10_11_11), // 16 + TYPE(FMT_11_11_10), // 17 + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + TYPE(FMT_16_16), // 25 + TYPE(FMT_16_16_16_16), // 26 + {0}, + {0}, + {0}, + {0}, + TYPE(FMT_16_16_FLOAT), // 31 + TYPE(FMT_16_16_16_16_FLOAT), // 32 + TYPE(FMT_32), // 33 + TYPE(FMT_32_32), // 34 + TYPE(FMT_32_32_32_32), // 35 + TYPE(FMT_32_FLOAT), // 36 + TYPE(FMT_32_32_FLOAT), // 37 + TYPE(FMT_32_32_32_32_FLOAT), // 38 + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + TYPE(FMT_32_32_32_FLOAT), // 57 +#undef TYPE + }; + out->Append(" "); + if (is_predicated) { + out->Append(predicate_condition ? " (p0) " : "(!p0) "); + } else { + out->Append(" "); + } + out->Append(opcode_name); + out->Append(' '); + DisassembleResultOperand(result, out); + if (!is_mini_fetch) { + out->Append(", "); + DisassembleSourceOperand(operands[0], out); + out->AppendFormat(", vf{}", 95 - operands[1].storage_index); + if (attributes.is_index_rounded) { + out->Append(", RoundIndex=true"); + } + } + + if (attributes.exp_adjust) { + out->AppendFormat(", ExpAdjust={}", attributes.exp_adjust); + } + if (attributes.offset) { + out->AppendFormat(", Offset={}", attributes.offset); + } + if (attributes.data_format != xenos::VertexFormat::kUndefined) { + out->AppendFormat(", DataFormat={}", + kVertexFetchDataFormats[static_cast(attributes.data_format)].name); + } + if (!is_mini_fetch && attributes.stride) { + out->AppendFormat(", Stride={}", attributes.stride); + } + if (attributes.is_signed) { + out->Append(", Signed=true"); + } + if (attributes.is_integer) { + out->Append(", NumFormat=integer"); + } + if (attributes.prefetch_count) { + out->AppendFormat(", PrefetchCount={}", attributes.prefetch_count + 1); + } + + out->Append('\n'); +} + +void ParsedTextureFetchInstruction::Disassemble(string::StringBuffer* out) const { + static const char* kTextureFilterNames[] = { + "point", + "linear", + "basemap", + "keep", + }; + static const char* kAnisoFilterNames[] = { + "disabled", "max1to1", "max2to1", "max4to1", "max8to1", "max16to1", "keep", + }; + + out->Append(" "); + if (is_predicated) { + out->Append(predicate_condition ? " (p0) " : "(!p0) "); + } else { + out->Append(" "); + } + out->Append(opcode_name); + out->Append(' '); + bool needs_comma = false; + if (has_result()) { + DisassembleResultOperand(result, out); + needs_comma = true; + } + if (needs_comma) { + out->Append(", "); + } + DisassembleSourceOperand(operands[0], out); + if (operand_count > 1) { + if (needs_comma) { + out->Append(", "); + } + out->AppendFormat("tf{}", operands[1].storage_index); + } + + if (!attributes.fetch_valid_only) { + out->Append(", FetchValidOnly=false"); + } + if (attributes.unnormalized_coordinates) { + out->Append(", UnnormalizedTextureCoords=true"); + } + if (attributes.mag_filter != xenos::TextureFilter::kUseFetchConst) { + out->AppendFormat(", MagFilter={}", + kTextureFilterNames[static_cast(attributes.mag_filter)]); + } + if (attributes.min_filter != xenos::TextureFilter::kUseFetchConst) { + out->AppendFormat(", MinFilter={}", + kTextureFilterNames[static_cast(attributes.min_filter)]); + } + if (attributes.mip_filter != xenos::TextureFilter::kUseFetchConst) { + out->AppendFormat(", MipFilter={}", + kTextureFilterNames[static_cast(attributes.mip_filter)]); + } + if (attributes.aniso_filter != xenos::AnisoFilter::kUseFetchConst) { + out->AppendFormat(", AnisoFilter={}", + kAnisoFilterNames[static_cast(attributes.aniso_filter)]); + } + if (attributes.vol_mag_filter != xenos::TextureFilter::kUseFetchConst) { + out->AppendFormat(", VolMagFilter={}", + kTextureFilterNames[static_cast(attributes.vol_mag_filter)]); + } + if (attributes.vol_min_filter != xenos::TextureFilter::kUseFetchConst) { + out->AppendFormat(", VolMinFilter={}", + kTextureFilterNames[static_cast(attributes.vol_min_filter)]); + } + if (!attributes.use_computed_lod) { + out->Append(", UseComputedLOD=false"); + } + if (attributes.use_register_lod) { + out->Append(", UseRegisterLOD=true"); + } + if (attributes.use_register_gradients) { + out->Append(", UseRegisterGradients=true"); + } + if (attributes.lod_bias != 0.0f) { + out->AppendFormat(", LODBias={:g}", attributes.lod_bias); + } + int component_count = xenos::GetFetchOpDimensionComponentCount(dimension); + if (attributes.offset_x != 0.0f) { + out->AppendFormat(", OffsetX={:g}", attributes.offset_x); + } + if (component_count > 1 && attributes.offset_y != 0.0f) { + out->AppendFormat(", OffsetY={:g}", attributes.offset_y); + } + if (component_count > 2 && attributes.offset_z != 0.0f) { + out->AppendFormat(", OffsetZ={:g}", attributes.offset_z); + } + + out->Append('\n'); +} + +void ParsedAluInstruction::Disassemble(string::StringBuffer* out) const { + bool is_vector_op_default_nop = IsVectorOpDefaultNop(); + bool is_scalar_op_default_nop = IsScalarOpDefaultNop(); + if (is_vector_op_default_nop && is_scalar_op_default_nop) { + out->Append(" "); + if (is_predicated) { + out->Append(predicate_condition ? " (p0) " : "(!p0) "); + } else { + out->Append(" "); + } + out->Append("nop\n"); + return; + } + if (!is_vector_op_default_nop) { + out->Append(" "); + if (is_predicated) { + out->Append(predicate_condition ? " (p0) " : "(!p0) "); + } else { + out->Append(" "); + } + out->Append(vector_opcode_name); + if (vector_and_constant_result.is_clamped) { + out->Append("_sat"); + } + out->Append(' '); + DisassembleResultOperand(vector_and_constant_result, out); + for (uint32_t i = 0; i < vector_operand_count; ++i) { + out->Append(", "); + DisassembleSourceOperand(vector_operands[i], out); + } + out->Append('\n'); + } + if (!is_scalar_op_default_nop) { + out->Append(is_vector_op_default_nop ? " " : " + "); + if (is_predicated) { + out->Append(predicate_condition ? " (p0) " : "(!p0) "); + } else { + out->Append(" "); + } + out->Append(scalar_opcode_name); + if (scalar_result.is_clamped) { + out->Append("_sat"); + } + out->Append(' '); + DisassembleResultOperand(scalar_result, out); + for (uint32_t i = 0; i < scalar_operand_count; ++i) { + out->Append(", "); + DisassembleSourceOperand(scalar_operands[i], out); + } + out->Append('\n'); + } +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/texture/cache.cpp b/src/graphics/pipeline/texture/cache.cpp new file mode 100644 index 0000000..c7c824e --- /dev/null +++ b/src/graphics/pipeline/texture/cache.cpp @@ -0,0 +1,1116 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_INT32(texture_cache_memory_limit_render_to_texture, 24, "GPU", + "Texture cache memory limit for render-to-texture (MB)") + .range(1, 256) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_INT32(texture_cache_memory_limit_soft, 384, "GPU", + "Soft texture cache memory limit (MB)") + .range(64, 4096) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_INT32(texture_cache_memory_limit_hard, 768, "GPU", + "Hard texture cache memory limit (MB)") + .range(128, 8192) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_INT32(texture_cache_memory_limit_soft_lifetime, 30, "GPU", + "Soft texture cache memory limit lifetime (seconds)") + .range(1, 3600); + +REXCVAR_DEFINE_BOOL(gpu_3d_to_2d_texture, true, "GPU", + "Sample problematic 3D textures through 2D-compatible wrappers") + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +REXCVAR_DEFINE_INT32(anisotropic_override, 3, "GPU", + "Forces anisotropic filtering for eligible textures.\n" + "Higher values keep textures sharper at oblique angles, but increase texture " + "sampling cost.\n" + " -1 = No override\n" + " 0 = Disable anisotropic filtering\n" + " 1 = Force 1x anisotropic filtering\n" + " 2 = Force 2x anisotropic filtering\n" + " 3 = Force 4x anisotropic filtering\n" + " 4 = Force 8x anisotropic filtering\n" + " 5 = Force 16x anisotropic filtering") + .range(-1, 5) + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +REXCVAR_DEFINE_INT32(draw_resolution_scale_x, 1, "GPU", "Draw resolution scale X (1 = no scaling)") + .range(1, 8) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_INT32(draw_resolution_scale_y, 1, "GPU", "Draw resolution scale Y (1 = no scaling)") + .range(1, 8) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_INT32(resolution_scale, 1, "GPU", + "Draw resolution scale for both X and Y axes (same as setting " + "draw_resolution_scale_x and draw_resolution_scale_y)") + .range(1, 8) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_BOOL(pre_mask_resolve_l2_block, true, "GPU", + "Pre-mask scaled resolve L2 blocks to the write range before iterating"); + +// DEFINE_int32( +// draw_resolution_scale_x, 1, +// "Integer pixel width scale used for scaling the rendering resolution " +// "opaquely to the game.\n" +// "1, 2 and 3 may be supported, but support of anything above 1 depends on " +// "the device properties, such as whether it supports sparse binding / tiled " +// "resources, the number of virtual address bits per resource, and other " +// "factors.\n" +// "Various effects and parts of game rendering pipelines may work " +// "incorrectly as pixels become ambiguous from the game's perspective and " +// "because half-pixel offset (which normally doesn't affect coverage when " +// "MSAA isn't used) becomes full-pixel.", +// "GPU"); +// DEFINE_int32( +// draw_resolution_scale_y, 1, +// "Integer pixel width scale used for scaling the rendering resolution " +// "opaquely to the game.\n" +// "See draw_resolution_scale_x for more information.", +// "GPU"); +// DEFINE_uint32( +// texture_cache_memory_limit_soft, 384, +// "Maximum host texture memory usage (in megabytes) above which old textures " +// "will be destroyed.", +// "GPU"); +// DEFINE_uint32( +// texture_cache_memory_limit_soft_lifetime, 30, +// "Seconds a texture should be unused to be considered old enough to be " +// "deleted if texture memory usage exceeds texture_cache_memory_limit_soft.", +// "GPU"); +// DEFINE_uint32( +// texture_cache_memory_limit_hard, 768, +// "Maximum host texture memory usage (in megabytes) above which textures " +// "will be destroyed as soon as possible.", +// "GPU"); +// DEFINE_uint32( +// texture_cache_memory_limit_render_to_texture, 24, +// "Part of the host texture memory budget (in megabytes) that will be scaled " +// "by the current drawing resolution scale.\n" +// "If texture_cache_memory_limit_soft, for instance, is 384, and this is 24, " +// "it will be assumed that the game will be using roughly 24 MB of " +// "render-to-texture (resolve) targets and 384 - 24 = 360 MB of regular " +// "textures - so with 2x2 resolution scaling, the soft limit will be 360 + " +// "96 MB, and with 3x3, it will be 360 + 216 MB.", +// "GPU"); + +namespace rex::graphics { + +const TextureCache::LoadShaderInfo TextureCache::load_shader_info_[kLoadShaderCount] = { + // k8bpb + {3, 4, 1, 4}, + // k16bpb + {4, 4, 2, 4}, + // k32bpb + {4, 4, 4, 3}, + // k64bpb + {4, 4, 8, 2}, + // k128bpb + {4, 4, 16, 1}, + // kR5G5B5A1ToB5G5R5A1 + {4, 4, 2, 4}, + // kR5G6B5ToB5G6R5 + {4, 4, 2, 4}, + // kR5G5B6ToB5G6R5WithRBGASwizzle + {4, 4, 2, 4}, + // kRGBA4ToBGRA4 + {4, 4, 2, 4}, + // kRGBA4ToARGB4 + {4, 4, 2, 4}, + // kGBGR8ToGRGB8 + {4, 4, 4, 3}, + // kGBGR8ToRGB8 + {4, 4, 8, 3}, + // kBGRG8ToRGBG8 + {4, 4, 4, 3}, + // kBGRG8ToRGB8 + {4, 4, 8, 3}, + // kR10G11B11ToRGBA16 + {4, 4, 8, 3}, + // kR10G11B11ToRGBA16SNorm + {4, 4, 8, 3}, + // kR11G11B10ToRGBA16 + {4, 4, 8, 3}, + // kR11G11B10ToRGBA16SNorm + {4, 4, 8, 3}, + // kR16UNormToFloat + {4, 4, 2, 4}, + // kR16SNormToFloat + {4, 4, 2, 4}, + // kRG16UNormToFloat + {4, 4, 4, 3}, + // kRG16SNormToFloat + {4, 4, 4, 3}, + // kRGBA16UNormToFloat + {4, 4, 8, 2}, + // kRGBA16SNormToFloat + {4, 4, 8, 2}, + // kDXT1ToRGBA8 + {4, 4, 4, 2}, + // kDXT3ToRGBA8 + {4, 4, 4, 1}, + // kDXT5ToRGBA8 + {4, 4, 4, 1}, + // kDXNToRG8 + {4, 4, 2, 1}, + // kDXT3A + {4, 4, 1, 2}, + // kDXT3AAs1111ToBGRA4 + {4, 4, 2, 2}, + // kDXT3AAs1111ToARGB4 + {4, 4, 2, 2}, + // kDXT5AToR8 + {4, 4, 1, 2}, + // kCTX1 + {4, 4, 2, 2}, + // kDepthUnorm + {4, 4, 4, 3}, + // kDepthFloat + {4, 4, 4, 3}, +}; + +TextureCache::TextureCache(const RegisterFile& register_file, SharedMemory& shared_memory, + uint32_t draw_resolution_scale_x, uint32_t draw_resolution_scale_y) + : register_file_(register_file), + shared_memory_(shared_memory), + draw_resolution_scale_x_(draw_resolution_scale_x), + draw_resolution_scale_y_(draw_resolution_scale_y) { + assert_true(draw_resolution_scale_x >= 1); + assert_true(draw_resolution_scale_x <= kMaxDrawResolutionScaleAlongAxis); + assert_true(draw_resolution_scale_y >= 1); + assert_true(draw_resolution_scale_y <= kMaxDrawResolutionScaleAlongAxis); + + if (draw_resolution_scale_x > 1 || draw_resolution_scale_y > 1) { + constexpr uint32_t kScaledResolvePageDwordCount = SharedMemory::kBufferSize / 4096 / 32; + scaled_resolve_pages_ = std::unique_ptr(new uint32_t[kScaledResolvePageDwordCount]); + std::memset(scaled_resolve_pages_.get(), 0, kScaledResolvePageDwordCount * sizeof(uint32_t)); + std::memset(scaled_resolve_pages_l2_, 0, sizeof(scaled_resolve_pages_l2_)); + scaled_resolve_global_watch_handle_ = + shared_memory.RegisterGlobalWatch(ScaledResolveGlobalWatchCallbackThunk, this); + } +} + +TextureCache::~TextureCache() { + DestroyAllTextures(true); + + if (scaled_resolve_global_watch_handle_) { + shared_memory().UnregisterGlobalWatch(scaled_resolve_global_watch_handle_); + } +} + +bool TextureCache::GetConfigDrawResolutionScale(uint32_t& x_out, uint32_t& y_out) { + uint32_t shared_scale = uint32_t(std::max(INT32_C(1), REXCVAR_GET(resolution_scale))); + bool use_shared_scale = rex::cvar::HasNonDefaultValue("resolution_scale"); + uint32_t config_x = use_shared_scale && !rex::cvar::HasNonDefaultValue("draw_resolution_scale_x") + ? shared_scale + : uint32_t(std::max(INT32_C(1), REXCVAR_GET(draw_resolution_scale_x))); + uint32_t config_y = use_shared_scale && !rex::cvar::HasNonDefaultValue("draw_resolution_scale_y") + ? shared_scale + : uint32_t(std::max(INT32_C(1), REXCVAR_GET(draw_resolution_scale_y))); + uint32_t clamped_x = std::min(kMaxDrawResolutionScaleAlongAxis, config_x); + uint32_t clamped_y = std::min(kMaxDrawResolutionScaleAlongAxis, config_y); + x_out = clamped_x; + y_out = clamped_y; + return clamped_x == config_x && clamped_y == config_y; +} + +void TextureCache::ClearCache() { + DestroyAllTextures(); +} + +void TextureCache::CompletedSubmissionUpdated(uint64_t completed_submission_index) { + // If memory usage is too high, destroy unused textures. + uint64_t current_time = rex::chrono::Clock::QueryHostUptimeMillis(); + // texture_cache_memory_limit_render_to_texture is assumed to be included in + // texture_cache_memory_limit_soft and texture_cache_memory_limit_hard, at 1x, + // so subtracting 1 from the scale. + uint32_t limit_scaled_resolve_add_mb = + REXCVAR_GET(texture_cache_memory_limit_render_to_texture) * + (draw_resolution_scale_x() * draw_resolution_scale_y() - 1); + uint32_t limit_soft_mb = + REXCVAR_GET(texture_cache_memory_limit_soft) + limit_scaled_resolve_add_mb; + uint32_t limit_hard_mb = + REXCVAR_GET(texture_cache_memory_limit_hard) + limit_scaled_resolve_add_mb; + uint32_t limit_soft_lifetime = REXCVAR_GET(texture_cache_memory_limit_soft_lifetime) * 1000; + bool destroyed_any = false; + while (texture_used_first_ != nullptr) { + uint64_t total_host_memory_usage_mb = + (textures_total_host_memory_usage_ + ((UINT32_C(1) << 20) - 1)) >> 20; + bool limit_hard_exceeded = total_host_memory_usage_mb > limit_hard_mb; + if (total_host_memory_usage_mb <= limit_soft_mb && !limit_hard_exceeded) { + break; + } + Texture* texture = texture_used_first_; + if (texture->last_usage_submission_index() > completed_submission_index) { + break; + } + if (!limit_hard_exceeded && (texture->last_usage_time() + limit_soft_lifetime) > current_time) { + break; + } + if (!destroyed_any) { + destroyed_any = true; + // The texture being destroyed might have been bound in the previous + // submissions, and nothing has overwritten the binding yet, so completion + // of the submission where the texture was last actually used on the GPU + // doesn't imply that it's not bound currently. Reset bindings if + // any texture has been destroyed. + ResetTextureBindings(); + } + // Remove the texture from the map and destroy it via its unique_ptr. + auto found_texture_it = textures_.find(texture->key()); + assert_true(found_texture_it != textures_.end()); + if (found_texture_it != textures_.end()) { + assert_true(found_texture_it->second.get() == texture); + textures_.erase(found_texture_it); + // `texture` is invalid now. + } + } + if (destroyed_any) { + COUNT_profile_set("gpu/texture_cache/textures", textures_.size()); + } +} + +void TextureCache::BeginSubmission(uint64_t new_submission_index) { + assert_true(new_submission_index > current_submission_index_); + current_submission_index_ = new_submission_index; + current_submission_time_ = rex::chrono::Clock::QueryHostUptimeMillis(); +} + +void TextureCache::BeginFrame() { + // In case there was a failure to create something in the previous frame, make + // sure bindings are reset so a new attempt will surely be made if the texture + // is requested again. + ResetTextureBindings(); +} + +void TextureCache::MarkRangeAsResolved(uint32_t start_unscaled, uint32_t length_unscaled) { + if (length_unscaled == 0) { + return; + } + start_unscaled &= 0x1FFFFFFF; + length_unscaled = std::min(length_unscaled, 0x20000000 - start_unscaled); + + if (IsDrawResolutionScaled()) { + uint32_t page_first = start_unscaled >> 12; + uint32_t page_last = (start_unscaled + length_unscaled - 1) >> 12; + uint32_t block_first = page_first >> 5; + uint32_t block_last = page_last >> 5; + auto global_lock = global_critical_region_.Acquire(); + for (uint32_t i = block_first; i <= block_last; ++i) { + uint32_t add_bits = UINT32_MAX; + if (i == block_first) { + add_bits &= ~((UINT32_C(1) << (page_first & 31)) - 1); + } + if (i == block_last && (page_last & 31) != 31) { + add_bits &= (UINT32_C(1) << ((page_last & 31) + 1)) - 1; + } + scaled_resolve_pages_[i] |= add_bits; + scaled_resolve_pages_l2_[i >> 6] |= UINT64_C(1) << (i & 63); + } + } + + // Invalidate textures. Toggling individual textures between scaled and + // unscaled also relies on invalidation through shared memory. + shared_memory().RangeWrittenByGpu(start_unscaled, length_unscaled); +} + +uint32_t TextureCache::GuestToHostSwizzle(uint32_t guest_swizzle, uint32_t host_format_swizzle) { + uint32_t host_swizzle = 0; + for (uint32_t i = 0; i < 4; ++i) { + uint32_t guest_swizzle_component = (guest_swizzle >> (3 * i)) & 0b111; + uint32_t host_swizzle_component; + if (guest_swizzle_component >= xenos::XE_GPU_TEXTURE_SWIZZLE_0) { + // Get rid of 6 and 7 values (to prevent host GPU errors if the game has + // something broken) the simple way - by changing them to 4 (0) and 5 (1). + host_swizzle_component = guest_swizzle_component & 0b101; + } else { + host_swizzle_component = (host_format_swizzle >> (3 * guest_swizzle_component)) & 0b111; + } + host_swizzle |= host_swizzle_component << (3 * i); + } + return host_swizzle; +} + +bool TextureCache::PrepareTextureLoad(Texture& texture, PendingTextureLoad& pending_load_out, + PendingSharedMemoryRange* pending_ranges_out, + size_t& pending_range_count_out) { + uint32_t outdated_mask = texture.outdated_mask(); + if (!outdated_mask) { + return false; + } + + bool base_outdated = false; + bool mips_outdated = false; + { + auto global_lock = global_critical_region_.Acquire(); + if (outdated_mask & Texture::kOutdatedBitBase) { + base_outdated = texture.base_outdated(global_lock); + } + if (outdated_mask & Texture::kOutdatedBitMips) { + mips_outdated = texture.mips_outdated(global_lock); + } + } + if (!base_outdated && !mips_outdated) { + return false; + } + + pending_load_out.texture = &texture; + pending_load_out.load_base = base_outdated; + pending_load_out.load_mips = mips_outdated; + pending_range_count_out = 0; + + TextureKey texture_key = texture.key(); + if (base_outdated) { + PendingSharedMemoryRange pending_range; + pending_range.start = texture_key.base_page << 12; + pending_range.length = + static_cast(rex::align(texture.GetGuestBaseSize(), UINT32_C(16))); + pending_ranges_out[pending_range_count_out++] = pending_range; + } + if (mips_outdated) { + PendingSharedMemoryRange pending_range; + pending_range.start = texture_key.mip_page << 12; + pending_range.length = + static_cast(rex::align(texture.GetGuestMipsSize(), UINT32_C(16))); + pending_ranges_out[pending_range_count_out++] = pending_range; + } + + return true; +} + +bool TextureCache::CommitPreparedTextureLoad(const PendingTextureLoad& pending_load) { + if (!pending_load.texture || (!pending_load.load_base && !pending_load.load_mips)) { + return true; + } + + Texture& texture = *pending_load.texture; + TextureKey texture_key = texture.key(); + if (texture_key.scaled_resolve) { + // Make sure all the scaled resolve memory is resident and accessible from + // the shader, including any possible padding that hasn't yet been touched + // by an actual resolve, but is still included in the texture size, so the + // GPU won't be trying to access unmapped memory. + if (pending_load.load_base && !EnsureScaledResolveMemoryCommitted( + texture_key.base_page << 12, texture.GetGuestBaseSize(), 4)) { + return false; + } + if (pending_load.load_mips && !EnsureScaledResolveMemoryCommitted( + texture_key.mip_page << 12, texture.GetGuestMipsSize(), 4)) { + return false; + } + } + + if (!LoadTextureDataFromResidentMemoryImpl(texture, pending_load.load_base, + pending_load.load_mips)) { + return false; + } + + // Mark the ranges as uploaded and watch them. This is needed for scaled + // resolves as well to detect when the CPU wants to reuse the memory for a + // regular texture or a vertex buffer, and thus the scaled resolve version is + // not up to date anymore. + texture.MakeUpToDateAndWatch(global_critical_region_.Acquire()); + texture.LogAction("Loaded"); + + return true; +} + +void TextureCache::RequestTextures(uint32_t used_texture_mask) { + const auto& regs = register_file(); + + if (texture_became_outdated_.exchange(false, std::memory_order_acquire)) { + // A texture has become outdated - make sure whether textures are outdated + // is rechecked in this draw and in subsequent ones to reload the new data + // if needed. + ResetTextureBindings(); + } + + // Update the texture keys and the textures. + uint32_t bindings_changed = 0; + std::vector pending_texture_loads; + std::vector pending_shared_memory_ranges; + auto queue_pending_texture_load = [&](Texture* texture) { + if (texture == nullptr) { + return; + } + for (const PendingTextureLoad& pending_load : pending_texture_loads) { + if (pending_load.texture == texture) { + return; + } + } + PendingTextureLoad pending_load; + PendingSharedMemoryRange pending_ranges[2]; + size_t pending_range_count = 0; + if (!PrepareTextureLoad(*texture, pending_load, pending_ranges, pending_range_count)) { + return; + } + pending_texture_loads.push_back(pending_load); + for (size_t i = 0; i < pending_range_count; ++i) { + pending_shared_memory_ranges.push_back(pending_ranges[i]); + } + }; + uint32_t textures_remaining = used_texture_mask & ~texture_bindings_in_sync_; + uint32_t index = 0; + while (rex::bit_scan_forward(textures_remaining, &index)) { + uint32_t index_bit = UINT32_C(1) << index; + textures_remaining &= ~index_bit; + TextureBinding& binding = texture_bindings_[index]; + xenos::xe_gpu_texture_fetch_t fetch = regs.GetTextureFetch(index); + TextureKey old_key = binding.key; + uint8_t old_swizzled_signs = binding.swizzled_signs; + BindingInfoFromFetchConstant(fetch, binding.key, &binding.swizzled_signs); + texture_bindings_in_sync_ |= index_bit; + if (!binding.key.is_valid) { + if (old_key.is_valid) { + bindings_changed |= index_bit; + } + binding.Reset(); + continue; + } + uint32_t old_host_swizzle = binding.host_swizzle; + binding.host_swizzle = GuestToHostSwizzle(fetch.swizzle, GetHostFormatSwizzle(binding.key)); + + // Check if need to load the unsigned and the signed versions of the texture + // (if the format is emulated with different host bit representations for + // signed and unsigned - otherwise only the unsigned one is loaded). + bool key_changed = binding.key != old_key; + bool any_sign_was_not_signed = texture_util::IsAnySignNotSigned(old_swizzled_signs); + bool any_sign_was_signed = texture_util::IsAnySignSigned(old_swizzled_signs); + bool any_sign_is_not_signed = texture_util::IsAnySignNotSigned(binding.swizzled_signs); + bool any_sign_is_signed = texture_util::IsAnySignSigned(binding.swizzled_signs); + if (key_changed || binding.host_swizzle != old_host_swizzle || + any_sign_is_not_signed != any_sign_was_not_signed || + any_sign_is_signed != any_sign_was_signed) { + bindings_changed |= index_bit; + } + bool load_unsigned_data = false, load_signed_data = false; + if (IsSignedVersionSeparateForFormat(binding.key)) { + // Can reuse previously loaded unsigned/signed versions if the key is the + // same and the texture was previously bound as unsigned/signed + // respectively (checking the previous values of signedness rather than + // binding.texture != nullptr and binding.texture_signed != nullptr also + // prevents repeated attempts to load the texture if it has failed to + // load). + if (any_sign_is_not_signed) { + if (key_changed || !any_sign_was_not_signed) { + binding.texture = FindOrCreateTexture(binding.key); + load_unsigned_data = true; + } + } else { + binding.texture = nullptr; + } + if (any_sign_is_signed) { + if (key_changed || !any_sign_was_signed) { + TextureKey signed_key = binding.key; + signed_key.signed_separate = 1; + binding.texture_signed = FindOrCreateTexture(signed_key); + load_signed_data = true; + } + } else { + binding.texture_signed = nullptr; + } + } else { + // Same resource for both unsigned and signed, but descriptor formats may + // be different. + if (key_changed) { + binding.texture = FindOrCreateTexture(binding.key); + load_unsigned_data = true; + } + binding.texture_signed = nullptr; + } + if (load_unsigned_data) { + queue_pending_texture_load(binding.texture); + } + if (load_signed_data) { + queue_pending_texture_load(binding.texture_signed); + } + } + + COUNT_profile_set("gpu/texture_cache/request_textures_pending_load_count", + uint32_t(pending_texture_loads.size())); + COUNT_profile_set("gpu/texture_cache/request_textures_pending_range_count", + uint32_t(pending_shared_memory_ranges.size())); + + bool batched_shared_memory_request_succeeded = true; + std::vector> pending_shared_memory_range_pairs; + if (!pending_shared_memory_ranges.empty()) { + pending_shared_memory_range_pairs.reserve(pending_shared_memory_ranges.size()); + for (const PendingSharedMemoryRange& pending_range : pending_shared_memory_ranges) { + pending_shared_memory_range_pairs.emplace_back(pending_range.start, pending_range.length); + } + batched_shared_memory_request_succeeded = shared_memory().RequestRanges( + pending_shared_memory_range_pairs.data(), pending_shared_memory_range_pairs.size()); + } + + if (batched_shared_memory_request_succeeded) { + for (const PendingTextureLoad& pending_load : pending_texture_loads) { + CommitPreparedTextureLoad(pending_load); + } + } else { + for (const PendingTextureLoad& pending_load : pending_texture_loads) { + if (pending_load.texture != nullptr) { + LoadTextureData(*pending_load.texture); + } + } + } + if (bindings_changed) { + UpdateTextureBindingsImpl(bindings_changed); + } +} + +const char* TextureCache::TextureKey::GetLogDimensionName(xenos::DataDimension dimension) { + switch (dimension) { + case xenos::DataDimension::k1D: + return "1D"; + case xenos::DataDimension::k2DOrStacked: + return "2D"; + case xenos::DataDimension::k3D: + return "3D"; + case xenos::DataDimension::kCube: + return "cube"; + default: + assert_unhandled_case(dimension); + return "unknown"; + } +} + +void TextureCache::TextureKey::LogAction(const char* action) const { + REXGPU_TRACE( + "{} {} {}{}x{}x{} {} {} texture with {} {}packed mip level{}, " + "base at 0x{:08X} (pitch {}), mips at 0x{:08X}", + action, tiled ? "tiled" : "linear", scaled_resolve ? "scaled " : "", GetWidth(), GetHeight(), + GetDepthOrArraySize(), GetLogDimensionName(), FormatInfo::Get(format)->name, + mip_max_level + 1, packed_mips ? "" : "un", mip_max_level != 0 ? "s" : "", base_page << 12, + pitch << 5, mip_page << 12); +} + +void TextureCache::Texture::LogAction(const char* action) const { + REXGPU_TRACE( + "{} {} {}{}x{}x{} {} {} texture with {} {}packed mip level{}, " + "base at 0x{:08X} (pitch {}, size 0x{:08X}), mips at 0x{:08X} (size " + "0x{:08X})", + action, key_.tiled ? "tiled" : "linear", key_.scaled_resolve ? "scaled " : "", + key_.GetWidth(), key_.GetHeight(), key_.GetDepthOrArraySize(), key_.GetLogDimensionName(), + FormatInfo::Get(key_.format)->name, key_.mip_max_level + 1, key_.packed_mips ? "" : "un", + key_.mip_max_level != 0 ? "s" : "", key_.base_page << 12, key_.pitch << 5, GetGuestBaseSize(), + key_.mip_page << 12, GetGuestMipsSize()); +} + +// The texture must be in the recent usage list. Place it in front now because +// after creation, the texture will likely be used immediately, and it should +// not be destroyed immediately after creation if dropping of old textures is +// performed somehow. The list is maintained by the Texture, not the +// TextureCache itself (unlike the `textures_` container). +TextureCache::Texture::Texture(TextureCache& texture_cache, const TextureKey& key, bool track_usage) + : texture_cache_(texture_cache), + key_(key), + guest_layout_(key.GetGuestLayout()), + last_usage_submission_index_(texture_cache.current_submission_index_), + last_usage_time_(texture_cache.current_submission_time_), + used_previous_(track_usage ? texture_cache.texture_used_last_ : nullptr), + used_next_(nullptr), + in_usage_list_(track_usage) { + if (track_usage) { + if (texture_cache.texture_used_last_) { + texture_cache.texture_used_last_->used_next_ = this; + } else { + texture_cache.texture_used_first_ = this; + } + texture_cache.texture_used_last_ = this; + } + + // Never try to upload data that doesn't exist. + base_outdated_ = guest_layout().base.level_data_extent_bytes != 0; + mips_outdated_ = guest_layout().mips_total_extent_bytes != 0; + outdated_mask_.store( + (base_outdated_ ? kOutdatedBitBase : 0) | (mips_outdated_ ? kOutdatedBitMips : 0), + std::memory_order_relaxed); +} + +TextureCache::Texture::~Texture() { + if (mips_watch_handle_) { + texture_cache().shared_memory().UnwatchMemoryRange(mips_watch_handle_); + } + if (base_watch_handle_) { + texture_cache().shared_memory().UnwatchMemoryRange(base_watch_handle_); + } + + if (in_usage_list_) { + if (used_previous_) { + used_previous_->used_next_ = used_next_; + } else { + texture_cache_.texture_used_first_ = used_next_; + } + if (used_next_) { + used_next_->used_previous_ = used_previous_; + } else { + texture_cache_.texture_used_last_ = used_previous_; + } + } + + texture_cache_.UpdateTexturesTotalHostMemoryUsage(0, host_memory_usage_); +} + +void TextureCache::Texture::MakeUpToDateAndWatch( + const std::unique_lock& global_lock) { + SharedMemory& shared_memory = texture_cache().shared_memory(); + if (base_outdated_) { + assert_not_zero(GetGuestBaseSize()); + base_outdated_ = false; + base_watch_handle_ = shared_memory.WatchMemoryRange( + key().base_page << 12, GetGuestBaseSize(), TextureCache::WatchCallback, this, nullptr, 0); + outdated_mask_.fetch_and(~kOutdatedBitBase, std::memory_order_release); + } + if (mips_outdated_) { + assert_not_zero(GetGuestMipsSize()); + mips_outdated_ = false; + mips_watch_handle_ = shared_memory.WatchMemoryRange( + key().mip_page << 12, GetGuestMipsSize(), TextureCache::WatchCallback, this, nullptr, 1); + outdated_mask_.fetch_and(~kOutdatedBitMips, std::memory_order_release); + } +} + +void TextureCache::Texture::MarkAsUsed() { + if (!in_usage_list_) { + return; + } + assert_true(last_usage_submission_index_ <= texture_cache_.current_submission_index_); + // This is called very frequently, don't relink unless needed for caching. + if (last_usage_submission_index_ >= texture_cache_.current_submission_index_) { + return; + } + last_usage_submission_index_ = texture_cache_.current_submission_index_; + last_usage_time_ = texture_cache_.current_submission_time_; + if (used_next_ == nullptr) { + // Already the most recently used. + return; + } + if (used_previous_ != nullptr) { + used_previous_->used_next_ = used_next_; + } else { + texture_cache_.texture_used_first_ = used_next_; + } + used_next_->used_previous_ = used_previous_; + used_previous_ = texture_cache_.texture_used_last_; + used_next_ = nullptr; + texture_cache_.texture_used_last_->used_next_ = this; + texture_cache_.texture_used_last_ = this; +} + +void TextureCache::Texture::WatchCallback( + [[maybe_unused]] const std::unique_lock& global_lock, bool is_mip) { + if (is_mip) { + assert_not_zero(GetGuestMipsSize()); + mips_outdated_ = true; + mips_watch_handle_ = nullptr; + outdated_mask_.fetch_or(kOutdatedBitMips, std::memory_order_release); + } else { + assert_not_zero(GetGuestBaseSize()); + base_outdated_ = true; + base_watch_handle_ = nullptr; + outdated_mask_.fetch_or(kOutdatedBitBase, std::memory_order_release); + } +} + +void TextureCache::WatchCallback(const std::unique_lock& global_lock, + void* context, void* data, uint64_t argument, + bool invalidated_by_gpu) { + Texture& texture = *static_cast(context); + texture.WatchCallback(global_lock, argument != 0); + texture.texture_cache().texture_became_outdated_.store(true, std::memory_order_release); +} + +void TextureCache::DestroyAllTextures(bool from_destructor) { + ResetTextureBindings(from_destructor); + textures_.clear(); + COUNT_profile_set("gpu/texture_cache/textures", 0); +} + +TextureCache::Texture* TextureCache::FindOrCreateTexture(TextureKey key) { + // Check if the texture is a scaled resolve texture. + if (IsDrawResolutionScaled() && key.tiled && IsScaledResolveSupportedForFormat(key)) { + texture_util::TextureGuestLayout scaled_resolve_guest_layout = key.GetGuestLayout(); + if ((scaled_resolve_guest_layout.base.level_data_extent_bytes && + IsRangeScaledResolved(key.base_page << 12, + scaled_resolve_guest_layout.base.level_data_extent_bytes)) || + (scaled_resolve_guest_layout.mips_total_extent_bytes && + IsRangeScaledResolved(key.mip_page << 12, + scaled_resolve_guest_layout.mips_total_extent_bytes))) { + key.scaled_resolve = 1; + } + } + + auto get_host_extent = [this, &key](uint32_t& host_width_out, uint32_t& host_height_out, + uint32_t& host_depth_or_array_size_out) { + host_width_out = key.GetWidth(); + host_height_out = key.GetHeight(); + if (key.scaled_resolve) { + host_width_out *= draw_resolution_scale_x(); + host_height_out *= draw_resolution_scale_y(); + } + host_depth_or_array_size_out = key.GetDepthOrArraySize(); + }; + auto try_drop_top_level = [&key]() { + if (!key.mip_page || !key.mip_max_level) { + return false; + } + uint32_t old_width = key.GetWidth(); + uint32_t old_height = key.GetHeight(); + uint32_t old_depth_or_array_size = key.GetDepthOrArraySize(); + uint32_t new_width = std::max(old_width >> 1, UINT32_C(1)); + uint32_t new_height = std::max(old_height >> 1, UINT32_C(1)); + uint32_t new_depth_or_array_size = key.dimension == xenos::DataDimension::k3D + ? std::max(old_depth_or_array_size >> 1, UINT32_C(1)) + : old_depth_or_array_size; + if (new_width == old_width && new_height == old_height && + new_depth_or_array_size == old_depth_or_array_size) { + return false; + } + const FormatInfo* format_info = FormatInfo::Get(key.format); + uint32_t rebased_pitch_texels = std::max(rex::next_pow2(old_width) >> 1, UINT32_C(1)); + rebased_pitch_texels = rex::align(rebased_pitch_texels, format_info->block_width); + rebased_pitch_texels = rex::align(rebased_pitch_texels, xenos::kTextureTileWidthHeight); + if (!key.tiled) { + uint32_t rebased_pitch_blocks = rebased_pitch_texels / format_info->block_width; + uint32_t rebased_row_pitch_bytes = rebased_pitch_blocks * format_info->bytes_per_block(); + rebased_row_pitch_bytes = + rex::align(rebased_row_pitch_bytes, xenos::kTextureLinearRowAlignmentBytes); + rebased_pitch_blocks = rebased_row_pitch_bytes / format_info->bytes_per_block(); + rebased_pitch_texels = rebased_pitch_blocks * format_info->block_width; + } + uint32_t rebased_pitch = std::max(rebased_pitch_texels >> 5, UINT32_C(1)); + if (rebased_pitch > ((UINT32_C(1) << 9) - 1)) { + return false; + } + key.width_minus_1 = new_width - 1; + key.height_minus_1 = new_height - 1; + key.depth_or_array_size_minus_1 = new_depth_or_array_size - 1; + key.base_page = key.mip_page; + key.mip_page = 0; + key.pitch = rebased_pitch; + key.mip_max_level = 0; + key.packed_mips = 0; + return true; + }; + uint32_t host_width, host_height, host_depth_or_array_size; + get_host_extent(host_width, host_height, host_depth_or_array_size); + // If the host can't support the full texture extent, first try using the + // unscaled version of a scaled resolve texture, then fall back to the first + // stored mip level only. + uint32_t max_host_width_height = GetMaxHostTextureWidthHeight(key.dimension); + uint32_t max_host_depth_or_array_size = GetMaxHostTextureDepthOrArraySize(key.dimension); + while (true) { + bool width_height_too_large = + host_width > max_host_width_height || host_height > max_host_width_height; + bool depth_or_array_too_large = host_depth_or_array_size > max_host_depth_or_array_size; + if (!width_height_too_large && !depth_or_array_too_large) { + break; + } + bool size_adjusted = false; + if (key.scaled_resolve) { + key.scaled_resolve = 0; + size_adjusted = true; + } else if ((width_height_too_large || + (depth_or_array_too_large && key.dimension == xenos::DataDimension::k3D)) && + try_drop_top_level()) { + size_adjusted = true; + } + if (!size_adjusted) { + return nullptr; + } + get_host_extent(host_width, host_height, host_depth_or_array_size); + } + + // Try to find an existing texture. + // TODO(Triang3l): Reuse a texture with mip_page unchanged, but base_page + // previously 0, now not 0, to save memory - common case in streaming. + auto found_texture_it = textures_.find(key); + if (found_texture_it != textures_.end()) { + return found_texture_it->second.get(); + } + + // Create the texture and add it to the map. + Texture* texture; + { + std::unique_ptr new_texture = CreateTexture(key); + if (!new_texture) { + key.LogAction("Failed to create"); + return nullptr; + } + assert_true(new_texture->key() == key); + texture = textures_.emplace(key, std::move(new_texture)).first->second.get(); + } + COUNT_profile_set("gpu/texture_cache/textures", textures_.size()); + texture->LogAction("Created"); + return texture; +} + +bool TextureCache::LoadTextureData(Texture& texture) { + PendingTextureLoad pending_load; + PendingSharedMemoryRange pending_ranges[2]; + size_t pending_range_count = 0; + if (!PrepareTextureLoad(texture, pending_load, pending_ranges, pending_range_count)) { + return true; + } + + std::pair pending_range_pairs[2]; + for (size_t i = 0; i < pending_range_count; ++i) { + pending_range_pairs[i] = std::make_pair(pending_ranges[i].start, pending_ranges[i].length); + } + if (!shared_memory().RequestRanges(pending_range_pairs, pending_range_count)) { + return false; + } + + return CommitPreparedTextureLoad(pending_load); +} + +void TextureCache::BindingInfoFromFetchConstant(const xenos::xe_gpu_texture_fetch_t& fetch, + TextureKey& key_out, uint8_t* swizzled_signs_out) { + // Reset the key and the signedness. + key_out.MakeInvalid(); + if (swizzled_signs_out != nullptr) { + *swizzled_signs_out = uint8_t(xenos::TextureSign::kUnsigned) * uint8_t(0b01010101); + } + + switch (fetch.type) { + case xenos::FetchConstantType::kTexture: + break; + case xenos::FetchConstantType::kInvalidTexture: + if (REXCVAR_GET(gpu_allow_invalid_fetch_constants)) { + break; + } + REXGPU_WARN( + "Texture fetch constant ({:08X} {:08X} {:08X} {:08X} {:08X} {:08X}) " + "has \"invalid\" type! This is incorrect behavior, but you can try " + "bypassing this by launching Xenia with " + "--gpu_allow_invalid_fetch_constants=true.", + fetch.dword_0, fetch.dword_1, fetch.dword_2, fetch.dword_3, fetch.dword_4, fetch.dword_5); + return; + default: + REXGPU_WARN( + "Texture fetch constant ({:08X} {:08X} {:08X} {:08X} {:08X} {:08X}) " + "is completely invalid!", + fetch.dword_0, fetch.dword_1, fetch.dword_2, fetch.dword_3, fetch.dword_4, fetch.dword_5); + return; + } + + uint32_t width_minus_1, height_minus_1, depth_or_array_size_minus_1; + uint32_t base_page, mip_page, mip_max_level; + texture_util::GetSubresourcesFromFetchConstant(fetch, &width_minus_1, &height_minus_1, + &depth_or_array_size_minus_1, &base_page, + &mip_page, nullptr, &mip_max_level); + if (base_page == 0 && mip_page == 0) { + // No texture data at all. + return; + } + if (fetch.dimension == xenos::DataDimension::k1D) { + bool is_invalid_1d = false; + // TODO(Triang3l): Support long 1D textures. + if (width_minus_1 >= xenos::kTexture2DCubeMaxWidthHeight) { + REXGPU_ERROR( + "1D texture is too wide ({}) - ignoring! Report the game to Xenia " + "developers", + width_minus_1 + 1); + is_invalid_1d = true; + } + assert_false(fetch.tiled); + if (fetch.tiled) { + REXGPU_ERROR( + "1D texture has tiling enabled in the fetch constant, but this " + "appears to be completely wrong - ignoring! Report the game to Xenia " + "developers"); + is_invalid_1d = true; + } + assert_false(fetch.packed_mips); + if (fetch.packed_mips) { + REXGPU_ERROR( + "1D texture has packed mips enabled in the fetch constant, but this " + "appears to be completely wrong - ignoring! Report the game to Xenia " + "developers"); + is_invalid_1d = true; + } + if (is_invalid_1d) { + return; + } + } + + xenos::TextureFormat format = GetBaseFormat(fetch.format); + + key_out.base_page = base_page; + key_out.mip_page = mip_page; + key_out.dimension = fetch.dimension; + key_out.width_minus_1 = width_minus_1; + key_out.height_minus_1 = height_minus_1; + key_out.depth_or_array_size_minus_1 = depth_or_array_size_minus_1; + key_out.pitch = fetch.pitch; + key_out.mip_max_level = mip_max_level; + key_out.tiled = fetch.tiled; + key_out.packed_mips = fetch.packed_mips; + key_out.format = format; + key_out.endianness = fetch.endianness; + + key_out.is_valid = 1; + + if (swizzled_signs_out != nullptr) { + *swizzled_signs_out = texture_util::SwizzleSigns(fetch); + } +} + +void TextureCache::ResetTextureBindings(bool from_destructor) { + uint32_t bindings_reset = 0; + for (size_t i = 0; i < texture_bindings_.size(); ++i) { + TextureBinding& binding = texture_bindings_[i]; + if (!binding.key.is_valid) { + continue; + } + binding.Reset(); + bindings_reset |= UINT32_C(1) << i; + } + texture_bindings_in_sync_ &= ~bindings_reset; + if (!from_destructor && bindings_reset) { + UpdateTextureBindingsImpl(bindings_reset); + } +} + +void TextureCache::UpdateTexturesTotalHostMemoryUsage(uint64_t add, uint64_t subtract) { + textures_total_host_memory_usage_ = textures_total_host_memory_usage_ - subtract + add; + COUNT_profile_set( + "gpu/texture_cache/total_host_memory_usage_mb", + uint32_t((textures_total_host_memory_usage_ + ((UINT32_C(1) << 20) - 1)) >> 20)); +} + +bool TextureCache::IsRangeScaledResolved(uint32_t start_unscaled, uint32_t length_unscaled) { + if (!IsDrawResolutionScaled()) { + return false; + } + + start_unscaled = std::min(start_unscaled, SharedMemory::kBufferSize); + length_unscaled = std::min(length_unscaled, SharedMemory::kBufferSize - start_unscaled); + if (!length_unscaled) { + return false; + } + + // Two-level check for faster rejection since resolve targets are usually + // placed in relatively small and localized memory portions (confirmed by + // testing - pretty much all times the deeper level was entered, the texture + // was a resolve target). + uint32_t page_first = start_unscaled >> 12; + uint32_t page_last = (start_unscaled + length_unscaled - 1) >> 12; + uint32_t block_first = page_first >> 5; + uint32_t block_last = page_last >> 5; + uint32_t l2_block_first = block_first >> 6; + uint32_t l2_block_last = block_last >> 6; + auto global_lock = global_critical_region_.Acquire(); + for (uint32_t i = l2_block_first; i <= l2_block_last; ++i) { + uint64_t l2_block = scaled_resolve_pages_l2_[i]; + if (i == l2_block_first) { + l2_block &= ~((UINT64_C(1) << (block_first & 63)) - 1); + } + if (i == l2_block_last && (block_last & 63) != 63) { + l2_block &= (UINT64_C(1) << ((block_last & 63) + 1)) - 1; + } + uint32_t block_relative_index; + while (rex::bit_scan_forward(l2_block, &block_relative_index)) { + l2_block &= ~(UINT64_C(1) << block_relative_index); + uint32_t block_index = (i << 6) + block_relative_index; + uint32_t check_bits = UINT32_MAX; + if (block_index == block_first) { + check_bits &= ~((UINT32_C(1) << (page_first & 31)) - 1); + } + if (block_index == block_last && (page_last & 31) != 31) { + check_bits &= (UINT32_C(1) << ((page_last & 31) + 1)) - 1; + } + if (scaled_resolve_pages_[block_index] & check_bits) { + return true; + } + } + } + return false; +} + +void TextureCache::ScaledResolveGlobalWatchCallbackThunk( + const std::unique_lock& global_lock, void* context, + uint32_t address_first, uint32_t address_last, bool invalidated_by_gpu) { + TextureCache* texture_cache = reinterpret_cast(context); + texture_cache->ScaledResolveGlobalWatchCallback(global_lock, address_first, address_last, + invalidated_by_gpu); +} + +void TextureCache::ScaledResolveGlobalWatchCallback( + const std::unique_lock& global_lock, uint32_t address_first, + uint32_t address_last, bool invalidated_by_gpu) { + assert_true(IsDrawResolutionScaled()); + if (invalidated_by_gpu) { + // Resolves themselves do exactly the opposite of what this should do. + return; + } + // Mark scaled resolve ranges as non-scaled. Textures themselves will be + // invalidated by their shared memory watches. + uint32_t resolve_page_first = address_first >> 12; + uint32_t resolve_page_last = address_last >> 12; + uint32_t resolve_block_first = resolve_page_first >> 5; + uint32_t resolve_block_last = resolve_page_last >> 5; + uint32_t resolve_l2_block_first = resolve_block_first >> 6; + uint32_t resolve_l2_block_last = resolve_block_last >> 6; + for (uint32_t i = resolve_l2_block_first; i <= resolve_l2_block_last; ++i) { + uint64_t resolve_l2_block = scaled_resolve_pages_l2_[i]; + if (REXCVAR_GET(pre_mask_resolve_l2_block)) { + // Pre-mask to only process blocks within the write range. + if (i == resolve_l2_block_first) { + resolve_l2_block &= ~((UINT64_C(1) << (resolve_block_first & 63)) - 1); + } + if (i == resolve_l2_block_last && (resolve_block_last & 63) != 63) { + resolve_l2_block &= (UINT64_C(1) << ((resolve_block_last & 63) + 1)) - 1; + } + } + uint32_t resolve_block_relative_index; + while (rex::bit_scan_forward(resolve_l2_block, &resolve_block_relative_index)) { + resolve_l2_block &= ~(UINT64_C(1) << resolve_block_relative_index); + uint32_t resolve_block_index = (i << 6) + resolve_block_relative_index; + uint32_t resolve_keep_bits = 0; + if (resolve_block_index == resolve_block_first) { + resolve_keep_bits |= (UINT32_C(1) << (resolve_page_first & 31)) - 1; + } + if (resolve_block_index == resolve_block_last && (resolve_page_last & 31) != 31) { + resolve_keep_bits |= ~((UINT32_C(1) << ((resolve_page_last & 31) + 1)) - 1); + } + scaled_resolve_pages_[resolve_block_index] &= resolve_keep_bits; + if (scaled_resolve_pages_[resolve_block_index] == 0) { + scaled_resolve_pages_l2_[i] &= ~(UINT64_C(1) << resolve_block_relative_index); + } + } + } +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/texture/conversion.cpp b/src/graphics/pipeline/texture/conversion.cpp new file mode 100644 index 0000000..608b9a0 --- /dev/null +++ b/src/graphics/pipeline/texture/conversion.cpp @@ -0,0 +1,143 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace rex::graphics::texture_conversion { + +using namespace rex::graphics::xenos; + +void CopySwapBlock(xenos::Endian endian, void* output, const void* input, size_t length) { + switch (endian) { + case xenos::Endian::k8in16: + memory::copy_and_swap_16_unaligned(output, input, length / 2); + break; + case xenos::Endian::k8in32: + memory::copy_and_swap_32_unaligned(output, input, length / 4); + break; + case xenos::Endian::k16in32: // Swap high and low 16 bits within a 32 bit + // word + memory::copy_and_swap_16_in_32_unaligned(output, input, length); + break; + default: + case xenos::Endian::kNone: + std::memcpy(output, input, length); + break; + } +} + +void ConvertTexelCTX1ToR8G8(xenos::Endian endian, void* output, const void* input, size_t length) { + // https://fileadmin.cs.lth.se/cs/Personal/Michael_Doggett/talks/unc-xenos-doggett.pdf + // (R is in the higher bits, according to how this format is used in + // 4D5307E6). + union { + uint8_t data[8]; + struct { + uint8_t g0, r0, g1, r1; + uint32_t xx; + }; + } block; + static_assert(sizeof(block) == 8, "CTX1 block mismatch"); + + const uint32_t bytes_per_block = 8; + CopySwapBlock(endian, block.data, input, bytes_per_block); + + uint8_t cr[4] = {block.r0, block.r1, + static_cast(2.f / 3.f * block.r0 + 1.f / 3.f * block.r1), + static_cast(1.f / 3.f * block.r0 + 2.f / 3.f * block.r1)}; + uint8_t cg[4] = {block.g0, block.g1, + static_cast(2.f / 3.f * block.g0 + 1.f / 3.f * block.g1), + static_cast(1.f / 3.f * block.g0 + 2.f / 3.f * block.g1)}; + + auto output_bytes = static_cast(output); + for (uint32_t oy = 0; oy < 4; ++oy) { + for (uint32_t ox = 0; ox < 4; ++ox) { + uint8_t xx = (block.xx >> (((ox + (oy * 4)) * 2))) & 3; + output_bytes[(oy * length) + (ox * 2) + 0] = cr[xx]; + output_bytes[(oy * length) + (ox * 2) + 1] = cg[xx]; + } + } +} + +void ConvertTexelDXT3AToDXT3(xenos::Endian endian, void* output, const void* input, size_t length) { + const uint32_t bytes_per_block = 16; + auto output_bytes = static_cast(output); + CopySwapBlock(endian, &output_bytes[0], input, 8); + std::memset(&output_bytes[8], 0, 8); +} + +// https://github.com/BinomialLLC/crunch/blob/ea9b8d8c00c8329791256adafa8cf11e4e7942a2/inc/crn_decomp.h#L4108 +static uint32_t TiledOffset2DRow(uint32_t y, uint32_t width, uint32_t log2_bpp) { + uint32_t macro = ((y / 32) * (width / 32)) << (log2_bpp + 7); + uint32_t micro = ((y & 6) << 2) << log2_bpp; + return macro + ((micro & ~0xF) << 1) + (micro & 0xF) + ((y & 8) << (3 + log2_bpp)) + + ((y & 1) << 4); +} + +static uint32_t TiledOffset2DColumn(uint32_t x, uint32_t y, uint32_t log2_bpp, + uint32_t base_offset) { + uint32_t macro = (x / 32) << (log2_bpp + 7); + uint32_t micro = (x & 7) << log2_bpp; + uint32_t offset = base_offset + (macro + ((micro & ~0xF) << 1) + (micro & 0xF)); + return ((offset & ~0x1FF) << 3) + ((offset & 0x1C0) << 2) + (offset & 0x3F) + ((y & 16) << 7) + + (((((y & 8) >> 2) + (x >> 3)) & 3) << 6); +} + +void Untile(uint8_t* output_buffer, const uint8_t* input_buffer, const UntileInfo* untile_info) { + SCOPE_profile_cpu_f("gpu"); + assert_not_null(untile_info); + assert_not_null(untile_info->input_format_info); + assert_not_null(untile_info->output_format_info); + + uint32_t input_bytes_per_block = untile_info->input_format_info->bytes_per_block(); + uint32_t output_bytes_per_block = untile_info->output_format_info->bytes_per_block(); + uint32_t output_pitch = untile_info->output_pitch * output_bytes_per_block; + + // Bytes per pixel + auto log2_bpp = + (input_bytes_per_block / 4) + ((input_bytes_per_block / 2) >> (input_bytes_per_block / 4)); + + // Offset to the current row, in bytes. + uint32_t output_row_offset = 0; + for (uint32_t y = 0; y < untile_info->height; y++) { + auto input_row_offset = + TiledOffset2DRow(untile_info->offset_y + y, untile_info->input_pitch, log2_bpp); + + // Go block-by-block on this row. + uint32_t output_offset = output_row_offset; + + for (uint32_t x = 0; x < untile_info->width; x++) { + auto input_offset = TiledOffset2DColumn(untile_info->offset_x + x, untile_info->offset_y + y, + log2_bpp, input_row_offset); + input_offset >>= log2_bpp; + + untile_info->copy_callback(&output_buffer[output_offset], + &input_buffer[input_offset * input_bytes_per_block], + output_bytes_per_block); + + output_offset += output_bytes_per_block; + } + + output_row_offset += output_pitch; + } +} + +} // namespace rex::graphics::texture_conversion diff --git a/src/graphics/pipeline/texture/extent.cpp b/src/graphics/pipeline/texture/extent.cpp new file mode 100644 index 0000000..09f5b40 --- /dev/null +++ b/src/graphics/pipeline/texture/extent.cpp @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include + +namespace rex::graphics { + +using namespace rex::graphics::xenos; + +static TextureExtent CalculateExtent(const FormatInfo* format_info, uint32_t pitch, uint32_t height, + uint32_t depth, bool is_tiled, bool is_guest) { + TextureExtent extent; + + extent.pitch = pitch; + extent.height = height; + extent.block_width = + rex::round_up(extent.pitch, format_info->block_width) / format_info->block_width; + extent.block_height = + rex::round_up(extent.height, format_info->block_height) / format_info->block_height; + extent.block_pitch_h = extent.block_width; + extent.block_pitch_v = extent.block_height; + extent.depth = depth; + + if (is_guest) { + // Texture dimensions must be a multiple of tile + // dimensions (32x32 blocks). + extent.block_pitch_h = rex::round_up(extent.block_pitch_h, 32); + extent.block_pitch_v = rex::round_up(extent.block_pitch_v, 32); + + extent.pitch = extent.block_pitch_h * format_info->block_width; + extent.height = extent.block_pitch_v * format_info->block_height; + + uint32_t bytes_per_block = format_info->bytes_per_block(); + uint32_t byte_pitch = extent.block_pitch_h * bytes_per_block; + + if (!is_tiled) { + // Each row must be a multiple of 256 bytes in linear textures. + byte_pitch = rex::round_up(byte_pitch, 256); + extent.block_pitch_h = byte_pitch / bytes_per_block; + extent.pitch = extent.block_pitch_h * format_info->block_width; + } + + // Is depth special? + extent.depth = extent.depth; + } else { + extent.pitch = extent.block_pitch_h * format_info->block_width; + extent.height = extent.block_pitch_v * format_info->block_height; + } + + return extent; +} + +TextureExtent TextureExtent::Calculate(const FormatInfo* format_info, uint32_t pitch, + uint32_t height, uint32_t depth, bool is_tiled, + bool is_guest) { + return CalculateExtent(format_info, pitch, height, depth, is_tiled, is_guest); +} + +TextureExtent TextureExtent::Calculate(const TextureInfo* info, bool is_guest) { + assert_not_null(info); + return CalculateExtent(info->format_info(), info->pitch, info->height + 1, info->depth + 1, + info->is_tiled, is_guest); +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/texture/info.cpp b/src/graphics/pipeline/texture/info.cpp new file mode 100644 index 0000000..73acf56 --- /dev/null +++ b/src/graphics/pipeline/texture/info.cpp @@ -0,0 +1,366 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace rex::graphics { + +using namespace rex::graphics::xenos; + +bool TextureInfo::Prepare(const xe_gpu_texture_fetch_t& fetch, TextureInfo* out_info) { + // https://msdn.microsoft.com/en-us/library/windows/desktop/cc308051(v=vs.85).aspx + // a2xx_sq_surfaceformat + + std::memset(out_info, 0, sizeof(TextureInfo)); + + auto& info = *out_info; + + info.format = fetch.format; + info.endianness = fetch.endianness; + + info.dimension = fetch.dimension; + info.width = info.height = info.depth = 0; + info.is_stacked = false; + switch (info.dimension) { + case xenos::DataDimension::k1D: + // we treat 1D textures as 2D + info.dimension = DataDimension::k2DOrStacked; + info.width = fetch.size_1d.width; + assert_true(!fetch.stacked); + break; + case xenos::DataDimension::k2DOrStacked: + info.width = fetch.size_2d.width; + info.height = fetch.size_2d.height; + if (fetch.stacked) { + info.depth = fetch.size_2d.stack_depth; + info.is_stacked = true; + } + break; + case xenos::DataDimension::k3D: + info.width = fetch.size_3d.width; + info.height = fetch.size_3d.height; + info.depth = fetch.size_3d.depth; + assert_true(!fetch.stacked); + break; + case xenos::DataDimension::kCube: + info.width = fetch.size_2d.width; + info.height = fetch.size_2d.height; + assert_true(fetch.size_2d.stack_depth == 5); + info.depth = fetch.size_2d.stack_depth; + assert_true(!fetch.stacked); + break; + default: + assert_unhandled_case(info.dimension); + break; + } + info.pitch = fetch.pitch << 5; + + info.mip_min_level = fetch.mip_min_level; + info.mip_max_level = std::max(uint32_t(fetch.mip_min_level), uint32_t(fetch.mip_max_level)); + + info.is_tiled = fetch.tiled; + info.has_packed_mips = fetch.packed_mips; + + info.extent = TextureExtent::Calculate(out_info, true); + info.SetupMemoryInfo(fetch.base_address << 12, fetch.mip_address << 12); + + // We've gotten this far and mip_address is zero, assume no extra mips. + if (info.mip_max_level > 0 && !info.memory.mip_address) { + info.mip_max_level = 0; + } + + assert_true(info.mip_min_level <= info.mip_max_level); + + return true; +} + +bool TextureInfo::PrepareResolve(uint32_t physical_address, xenos::TextureFormat format, + xenos::Endian endian, uint32_t pitch, uint32_t width, + uint32_t height, uint32_t depth, TextureInfo* out_info) { + assert_true(width > 0); + assert_true(height > 0); + + std::memset(out_info, 0, sizeof(TextureInfo)); + + auto& info = *out_info; + info.format = format; + info.endianness = endian; + + info.dimension = xenos::DataDimension::k2DOrStacked; + info.width = width - 1; + info.height = height - 1; + info.depth = depth - 1; + + info.pitch = pitch; + info.mip_min_level = 0; + info.mip_max_level = 0; + + info.is_tiled = true; + info.has_packed_mips = false; + + info.extent = TextureExtent::Calculate(out_info, true); + info.SetupMemoryInfo(physical_address, 0); + return true; +} + +uint32_t TextureInfo::GetMaxMipLevels() const { + return 1 + rex::log2_floor(std::max({width + 1, height + 1, depth + 1})); +} + +const TextureExtent TextureInfo::GetMipExtent(uint32_t mip, bool is_guest) const { + if (mip == 0) { + return extent; + } + uint32_t mip_width, mip_height; + if (is_guest) { + mip_width = rex::next_pow2(width + 1) >> mip; + mip_height = rex::next_pow2(height + 1) >> mip; + } else { + mip_width = std::max(1u, (width + 1) >> mip); + mip_height = std::max(1u, (height + 1) >> mip); + } + return TextureExtent::Calculate(format_info(), mip_width, mip_height, depth + 1, is_tiled, + is_guest); +} + +void TextureInfo::GetMipSize(uint32_t mip, uint32_t* out_width, uint32_t* out_height) const { + assert_not_null(out_width); + assert_not_null(out_height); + if (mip == 0) { + *out_width = width + 1; + *out_height = height + 1; + return; + } + uint32_t width_pow2 = rex::next_pow2(width + 1); + uint32_t height_pow2 = rex::next_pow2(height + 1); + *out_width = std::max(width_pow2 >> mip, 1u); + *out_height = std::max(height_pow2 >> mip, 1u); +} + +uint32_t TextureInfo::GetMipLocation(uint32_t mip, uint32_t* offset_x, uint32_t* offset_y, + bool is_guest) const { + if (mip == 0) { + // Short-circuit. Mip 0 is always stored in base_address. + if (!has_packed_mips) { + *offset_x = 0; + *offset_y = 0; + } else { + GetPackedTileOffset(0, offset_x, offset_y); + } + return memory.base_address; + } + + if (!memory.mip_address) { + // Short-circuit. There is no mip data. + *offset_x = 0; + *offset_y = 0; + return 0; + } + + uint32_t address_base, address_offset; + address_base = memory.mip_address; + address_offset = 0; + + auto bytes_per_block = format_info()->bytes_per_block(); + + if (!has_packed_mips) { + for (uint32_t i = 1; i < mip; i++) { + address_offset += GetMipExtent(i, is_guest).all_blocks() * bytes_per_block; + } + *offset_x = 0; + *offset_y = 0; + return address_base + address_offset; + } + + uint32_t width_pow2 = rex::next_pow2(width + 1); + uint32_t height_pow2 = rex::next_pow2(height + 1); + + // Walk forward to find the address of the mip. + uint32_t packed_mip_base = 1; + for (uint32_t i = packed_mip_base; i < mip; i++, packed_mip_base++) { + uint32_t mip_width = std::max(width_pow2 >> i, 1u); + uint32_t mip_height = std::max(height_pow2 >> i, 1u); + if (std::min(mip_width, mip_height) <= 16) { + // We've reached the point where the mips are packed into a single tile. + break; + } + address_offset += GetMipExtent(i, is_guest).all_blocks() * bytes_per_block; + } + + // Now, check if the mip is packed at an offset. + GetPackedTileOffset(width_pow2 >> mip, height_pow2 >> mip, format_info(), mip - packed_mip_base, + offset_x, offset_y); + return address_base + address_offset; +} + +bool TextureInfo::GetPackedTileOffset(uint32_t width, uint32_t height, + const FormatInfo* format_info, int packed_tile, + uint32_t* offset_x, uint32_t* offset_y) { + // Tile size is 32x32, and once textures go <=16 they are packed into a + // single tile together. The math here is insane. Most sourced + // from graph paper and looking at dds dumps. + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // 0 +.4x4.+ +.....8x8.....+ +............16x16............+ + // 1 +.4x4.+ +.....8x8.....+ +............16x16............+ + // 2 +.4x4.+ +.....8x8.....+ +............16x16............+ + // 3 +.4x4.+ +.....8x8.....+ +............16x16............+ + // 4 x +.....8x8.....+ +............16x16............+ + // 5 +.....8x8.....+ +............16x16............+ + // 6 +.....8x8.....+ +............16x16............+ + // 7 +.....8x8.....+ +............16x16............+ + // 8 2x2 +............16x16............+ + // 9 2x2 +............16x16............+ + // 0 +............16x16............+ + // ... ..... + // This only works for square textures, or textures that are some non-pot + // <= square. As soon as the aspect ratio goes weird, the textures start to + // stretch across tiles. + // + // The 2x2 and 1x1 squares are packed in their specific positions because + // each square is the size of at least one block (which is 4x4 pixels max) + // + // if (tile_aligned(w) > tile_aligned(h)) { + // // wider than tall, so packed horizontally + // } else if (tile_aligned(w) < tile_aligned(h)) { + // // taller than wide, so packed vertically + // } else { + // square + // } + // It's important to use logical sizes here, as the input sizes will be + // for the entire packed tile set, not the actual texture. + // The minimum dimension is what matters most: if either width or height + // is <= 16 this mode kicks in. + + uint32_t log2_width = rex::log2_ceil(width); + uint32_t log2_height = rex::log2_ceil(height); + if (std::min(log2_width, log2_height) > 4) { + // Too big, not packed. + *offset_x = 0; + *offset_y = 0; + return false; + } + + // Find the block offset of the mip. + if (packed_tile < 3) { + if (log2_width > log2_height) { + // Wider than tall. Laid out vertically. + *offset_x = 0; + *offset_y = 16 >> packed_tile; + } else { + // Taller than wide. Laid out horizontally. + *offset_x = 16 >> packed_tile; + *offset_y = 0; + } + } else { + if (log2_width > log2_height) { + // Wider than tall. Laid out vertically. + *offset_x = 16 >> (packed_tile - 2); + *offset_y = 0; + } else { + // Taller than wide. Laid out horizontally. + *offset_x = 0; + *offset_y = 16 >> (packed_tile - 2); + } + } + + *offset_x /= format_info->block_width; + *offset_y /= format_info->block_height; + return true; +} + +bool TextureInfo::GetPackedTileOffset(int packed_tile, uint32_t* offset_x, + uint32_t* offset_y) const { + if (!has_packed_mips) { + *offset_x = 0; + *offset_y = 0; + return false; + } + return GetPackedTileOffset(rex::next_pow2(width + 1), rex::next_pow2(height + 1), format_info(), + packed_tile, offset_x, offset_y); +} + +uint64_t TextureInfo::hash() const { + return XXH3_64bits(this, sizeof(TextureInfo)); +} + +void TextureInfo::SetupMemoryInfo(uint32_t base_address, uint32_t mip_address) { + uint32_t bytes_per_block = format_info()->bytes_per_block(); + + memory.base_address = 0; + memory.base_size = 0; + memory.mip_address = 0; + memory.mip_size = 0; + + if (mip_min_level == 0 && base_address) { + // There is a base mip level. + memory.base_address = base_address; + memory.base_size = GetMipExtent(0, true).visible_blocks() * bytes_per_block; + } + + if (mip_min_level == 0 && mip_max_level == 0) { + // Sort circuit. Only one mip. + return; + } + + if (mip_min_level == 0 && base_address == mip_address) { + // TODO(gibbed): This doesn't actually make any sense. Force only one mip. + // Offending title issues: #26, #45 + return; + } + + if (mip_min_level > 0) { + if ((base_address && !mip_address) || (base_address == mip_address)) { + // Mip data is actually at base address? + mip_address = base_address; + base_address = 0; + } else if (!base_address && mip_address) { + // Nothing needs to be done. + } else { + // WTF? + assert_always(); + } + } + + memory.mip_address = mip_address; + + if (!has_packed_mips) { + for (uint32_t mip = std::max(1u, mip_min_level); mip < mip_max_level; mip++) { + memory.mip_size += GetMipExtent(mip, true).all_blocks() * bytes_per_block; + } + memory.mip_size += GetMipExtent(mip_max_level, true).visible_blocks() * bytes_per_block; + return; + } + + uint32_t width_pow2 = rex::next_pow2(width + 1); + uint32_t height_pow2 = rex::next_pow2(height + 1); + + // Walk forward to find the address of the mip. + uint32_t packed_mip_base = std::max(1u, mip_min_level); + for (uint32_t mip = packed_mip_base; mip < mip_max_level; mip++, packed_mip_base++) { + uint32_t mip_width = std::max(width_pow2 >> mip, 1u); + uint32_t mip_height = std::max(height_pow2 >> mip, 1u); + if (std::min(mip_width, mip_height) <= 16) { + // We've reached the point where the mips are packed into a single tile. + break; + } + memory.mip_size += GetMipExtent(mip, true).all_blocks() * bytes_per_block; + } +} + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/texture/info_formats.cpp b/src/graphics/pipeline/texture/info_formats.cpp new file mode 100644 index 0000000..c456e1e --- /dev/null +++ b/src/graphics/pipeline/texture/info_formats.cpp @@ -0,0 +1,93 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// clang-format off + +#include + +namespace rex::graphics { + +using namespace rex::graphics::xenos; + +#define FORMAT_INFO(texture_format, format, block_width, block_height, bits_per_pixel) \ + {xenos::TextureFormat::texture_format, #texture_format, FormatType::format, block_width, block_height, bits_per_pixel} +const FormatInfo* FormatInfo::Get(uint32_t gpu_format) { + static const FormatInfo format_infos[64] = { + FORMAT_INFO(k_1_REVERSE , kUncompressed, 1, 1, 1), + FORMAT_INFO(k_1 , kUncompressed, 1, 1, 1), + FORMAT_INFO(k_8 , kResolvable, 1, 1, 8), + FORMAT_INFO(k_1_5_5_5 , kResolvable, 1, 1, 16), + FORMAT_INFO(k_5_6_5 , kResolvable, 1, 1, 16), + FORMAT_INFO(k_6_5_5 , kResolvable, 1, 1, 16), + FORMAT_INFO(k_8_8_8_8 , kResolvable, 1, 1, 32), + FORMAT_INFO(k_2_10_10_10 , kResolvable, 1, 1, 32), + FORMAT_INFO(k_8_A , kResolvable, 1, 1, 8), + FORMAT_INFO(k_8_B , kResolvable, 1, 1, 8), + FORMAT_INFO(k_8_8 , kResolvable, 1, 1, 16), + FORMAT_INFO(k_Cr_Y1_Cb_Y0_REP , kCompressed, 2, 1, 16), + FORMAT_INFO(k_Y1_Cr_Y0_Cb_REP , kCompressed, 2, 1, 16), + FORMAT_INFO(k_16_16_EDRAM , kUncompressed, 1, 1, 32), + FORMAT_INFO(k_8_8_8_8_A , kResolvable, 1, 1, 32), + FORMAT_INFO(k_4_4_4_4 , kResolvable, 1, 1, 16), + FORMAT_INFO(k_10_11_11 , kResolvable, 1, 1, 32), + FORMAT_INFO(k_11_11_10 , kResolvable, 1, 1, 32), + FORMAT_INFO(k_DXT1 , kCompressed, 4, 4, 4), + FORMAT_INFO(k_DXT2_3 , kCompressed, 4, 4, 8), + FORMAT_INFO(k_DXT4_5 , kCompressed, 4, 4, 8), + FORMAT_INFO(k_16_16_16_16_EDRAM , kUncompressed, 1, 1, 64), + FORMAT_INFO(k_24_8 , kUncompressed, 1, 1, 32), + FORMAT_INFO(k_24_8_FLOAT , kUncompressed, 1, 1, 32), + FORMAT_INFO(k_16 , kResolvable, 1, 1, 16), + FORMAT_INFO(k_16_16 , kResolvable, 1, 1, 32), + FORMAT_INFO(k_16_16_16_16 , kResolvable, 1, 1, 64), + FORMAT_INFO(k_16_EXPAND , kUncompressed, 1, 1, 16), + FORMAT_INFO(k_16_16_EXPAND , kUncompressed, 1, 1, 32), + FORMAT_INFO(k_16_16_16_16_EXPAND , kUncompressed, 1, 1, 64), + FORMAT_INFO(k_16_FLOAT , kResolvable, 1, 1, 16), + FORMAT_INFO(k_16_16_FLOAT , kResolvable, 1, 1, 32), + FORMAT_INFO(k_16_16_16_16_FLOAT , kResolvable, 1, 1, 64), + FORMAT_INFO(k_32 , kUncompressed, 1, 1, 32), + FORMAT_INFO(k_32_32 , kUncompressed, 1, 1, 64), + FORMAT_INFO(k_32_32_32_32 , kUncompressed, 1, 1, 128), + FORMAT_INFO(k_32_FLOAT , kResolvable, 1, 1, 32), + FORMAT_INFO(k_32_32_FLOAT , kResolvable, 1, 1, 64), + FORMAT_INFO(k_32_32_32_32_FLOAT , kResolvable, 1, 1, 128), + FORMAT_INFO(k_32_AS_8 , kCompressed, 4, 1, 8), + FORMAT_INFO(k_32_AS_8_8 , kCompressed, 2, 1, 16), + FORMAT_INFO(k_16_MPEG , kUncompressed, 1, 1, 16), + FORMAT_INFO(k_16_16_MPEG , kUncompressed, 1, 1, 32), + FORMAT_INFO(k_8_INTERLACED , kUncompressed, 1, 1, 8), + FORMAT_INFO(k_32_AS_8_INTERLACED , kCompressed, 4, 1, 8), + FORMAT_INFO(k_32_AS_8_8_INTERLACED , kCompressed, 1, 1, 16), + FORMAT_INFO(k_16_INTERLACED , kUncompressed, 1, 1, 16), + FORMAT_INFO(k_16_MPEG_INTERLACED , kUncompressed, 1, 1, 16), + FORMAT_INFO(k_16_16_MPEG_INTERLACED , kUncompressed, 1, 1, 32), + FORMAT_INFO(k_DXN , kCompressed, 4, 4, 8), + FORMAT_INFO(k_8_8_8_8_AS_16_16_16_16 , kResolvable, 1, 1, 32), + FORMAT_INFO(k_DXT1_AS_16_16_16_16 , kCompressed, 4, 4, 4), + FORMAT_INFO(k_DXT2_3_AS_16_16_16_16 , kCompressed, 4, 4, 8), + FORMAT_INFO(k_DXT4_5_AS_16_16_16_16 , kCompressed, 4, 4, 8), + FORMAT_INFO(k_2_10_10_10_AS_16_16_16_16, kResolvable, 1, 1, 32), + FORMAT_INFO(k_10_11_11_AS_16_16_16_16 , kResolvable, 1, 1, 32), + FORMAT_INFO(k_11_11_10_AS_16_16_16_16 , kResolvable, 1, 1, 32), + FORMAT_INFO(k_32_32_32_FLOAT , kUncompressed, 1, 1, 96), + FORMAT_INFO(k_DXT3A , kCompressed, 4, 4, 4), + FORMAT_INFO(k_DXT5A , kCompressed, 4, 4, 4), + FORMAT_INFO(k_CTX1 , kCompressed, 4, 4, 4), + FORMAT_INFO(k_DXT3A_AS_1_1_1_1 , kCompressed, 4, 4, 4), + FORMAT_INFO(k_8_8_8_8_GAMMA_EDRAM , kUncompressed, 1, 1, 32), + FORMAT_INFO(k_2_10_10_10_FLOAT_EDRAM , kUncompressed, 1, 1, 32), + }; + return &format_infos[gpu_format]; +} +#undef FORMAT_INFO + +} // namespace rex::graphics diff --git a/src/graphics/pipeline/texture/util.cpp b/src/graphics/pipeline/texture/util.cpp new file mode 100644 index 0000000..26d554c --- /dev/null +++ b/src/graphics/pipeline/texture/util.cpp @@ -0,0 +1,581 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include + +namespace rex::graphics::texture_util { + +void GetSubresourcesFromFetchConstant(const xenos::xe_gpu_texture_fetch_t& fetch, + uint32_t* width_minus_1_out, uint32_t* height_minus_1_out, + uint32_t* depth_or_array_size_minus_1_out, + uint32_t* base_page_out, uint32_t* mip_page_out, + uint32_t* mip_min_level_out, uint32_t* mip_max_level_out) { + uint32_t width_minus_1 = 0; + uint32_t height_minus_1 = 0; + uint32_t depth_or_array_size_minus_1 = 0; + switch (fetch.dimension) { + case xenos::DataDimension::k1D: + assert_false(fetch.stacked); + assert_false(fetch.tiled); + assert_false(fetch.packed_mips); + width_minus_1 = fetch.size_1d.width; + break; + case xenos::DataDimension::k2DOrStacked: + width_minus_1 = fetch.size_2d.width; + height_minus_1 = fetch.size_2d.height; + depth_or_array_size_minus_1 = fetch.stacked ? fetch.size_2d.stack_depth : 0; + break; + case xenos::DataDimension::k3D: + assert_false(fetch.stacked); + width_minus_1 = fetch.size_3d.width; + height_minus_1 = fetch.size_3d.height; + depth_or_array_size_minus_1 = fetch.size_3d.depth; + break; + case xenos::DataDimension::kCube: + assert_false(fetch.stacked); + assert_true(fetch.size_2d.stack_depth == 5); + width_minus_1 = fetch.size_2d.width; + height_minus_1 = fetch.size_2d.height; + depth_or_array_size_minus_1 = 5; + break; + } + if (width_minus_1_out) { + *width_minus_1_out = width_minus_1; + } + if (height_minus_1_out) { + *height_minus_1_out = height_minus_1; + } + if (depth_or_array_size_minus_1_out) { + *depth_or_array_size_minus_1_out = depth_or_array_size_minus_1; + } + + uint32_t longest_axis_minus_1 = std::max(width_minus_1, height_minus_1); + if (fetch.dimension == xenos::DataDimension::k3D) { + longest_axis_minus_1 = std::max(longest_axis_minus_1, depth_or_array_size_minus_1); + } + uint32_t size_mip_max_level = rex::log2_floor(longest_axis_minus_1 + uint32_t(1)); + + uint32_t base_page = fetch.base_address & 0x1FFFF; + uint32_t mip_page = fetch.mip_address & 0x1FFFF; + + uint32_t mip_min_level, mip_max_level; + // Not taking mip_filter == kBaseMap into account for mip_max_level because + // the mip filter may be overridden by shader fetch instructions. + if (mip_page == 0) { + mip_min_level = 0; + mip_max_level = 0; + } else { + mip_min_level = std::min(uint32_t(fetch.mip_min_level), size_mip_max_level); + mip_max_level = + std::max(std::min(uint32_t(fetch.mip_max_level), size_mip_max_level), mip_min_level); + } + if (mip_max_level != 0) { + if (base_page == 0) { + mip_min_level = std::max(mip_min_level, uint32_t(1)); + } + if (mip_min_level != 0) { + base_page = 0; + } + } else { + mip_page = 0; + } + + if (base_page_out) { + *base_page_out = base_page; + } + if (mip_page_out) { + *mip_page_out = mip_page; + } + if (mip_min_level_out) { + *mip_min_level_out = mip_min_level; + } + if (mip_max_level_out) { + *mip_max_level_out = mip_max_level; + } +} + +bool GetPackedMipOffset(uint32_t width, uint32_t height, uint32_t depth, + xenos::TextureFormat format, uint32_t mip, uint32_t& x_blocks, + uint32_t& y_blocks, uint32_t& z_blocks) { + // Tile size is 32x32, and once textures go <=16 they are packed into a + // single tile together. The math here is insane. Most sourced from + // graph paper, looking at dds dumps and executable reverse engineering. + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // 0 +.4x4.+ +.....8x8.....+ +............16x16............+ + // 1 +.4x4.+ +.....8x8.....+ +............16x16............+ + // 2 +.4x4.+ +.....8x8.....+ +............16x16............+ + // 3 +.4x4.+ +.....8x8.....+ +............16x16............+ + // 4 x +.....8x8.....+ +............16x16............+ + // 5 +.....8x8.....+ +............16x16............+ + // 6 +.....8x8.....+ +............16x16............+ + // 7 +.....8x8.....+ +............16x16............+ + // 8 2x2 +............16x16............+ + // 9 2x2 +............16x16............+ + // 0 +............16x16............+ + // ... ..... + // + // The 2x2 and 1x1 squares are packed in their specific positions because + // each square is the size of at least one block (which is 4x4 pixels max) + // + // if (tile_aligned(w) > tile_aligned(h)) { + // // wider than tall, so packed horizontally + // } else if (tile_aligned(w) < tile_aligned(h)) { + // // taller than wide, so packed vertically + // } else { + // square + // } + // It's important to use logical sizes here, as the input sizes will be + // for the entire packed tile set, not the actual texture. + // The minimum dimension is what matters most: if either width or height + // is <= 16 this mode kicks in. + + uint32_t log2_width = rex::log2_ceil(width); + uint32_t log2_height = rex::log2_ceil(height); + uint32_t log2_size = std::min(log2_width, log2_height); + if (log2_size > 4 + mip) { + // The shortest dimension is bigger than 16, not packed. + x_blocks = 0; + y_blocks = 0; + z_blocks = 0; + return false; + } + uint32_t packed_mip_base = (log2_size > 4) ? (log2_size - 4) : 0; + uint32_t packed_mip = mip - packed_mip_base; + + // Find the block offset of the mip. + if (packed_mip < 3) { + if (log2_width > log2_height) { + // Wider than tall. Laid out vertically. + x_blocks = 0; + y_blocks = 16 >> packed_mip; + } else { + // Taller than wide. Laid out horizontally. + x_blocks = 16 >> packed_mip; + y_blocks = 0; + } + z_blocks = 0; + } else { + uint32_t offset; + if (log2_width > log2_height) { + // Wider than tall. Laid out horizontally. + offset = (1 << (log2_width - packed_mip_base)) >> (packed_mip - 2); + x_blocks = offset; + y_blocks = 0; + } else { + // Taller than wide. Laid out vertically. + x_blocks = 0; + offset = (1 << (log2_height - packed_mip_base)) >> (packed_mip - 2); + y_blocks = offset; + } + if (offset < 4) { + // Pack 1x1 Z mipmaps along Z - not reached for 2D. + uint32_t log2_depth = rex::log2_ceil(depth); + if (log2_depth > 1 + packed_mip) { + z_blocks = (log2_depth - packed_mip) * 4; + } else { + z_blocks = 4; + } + } else { + z_blocks = 0; + } + } + + const FormatInfo* format_info = FormatInfo::Get(format); + x_blocks /= format_info->block_width; + y_blocks /= format_info->block_height; + return true; +} + +TextureGuestLayout GetGuestTextureLayout(xenos::DataDimension dimension, + uint32_t base_pitch_texels_div_32, uint32_t width_texels, + uint32_t height_texels, uint32_t depth_or_array_size, + bool is_tiled, xenos::TextureFormat format, + bool has_packed_levels, bool has_base, + uint32_t max_level) { + TextureGuestLayout layout; + + if (dimension == xenos::DataDimension::k1D) { + assert_false(is_tiled); + // GetPackedMipOffset may result in packing along Y for `width > height` + // textures. + assert_false(has_packed_levels); + height_texels = 1; + } + uint32_t depth = dimension == xenos::DataDimension::k3D ? depth_or_array_size : 1; + switch (dimension) { + case xenos::DataDimension::k2DOrStacked: + layout.array_size = depth_or_array_size; + break; + case xenos::DataDimension::kCube: + layout.array_size = 6; + break; + default: + layout.array_size = 1; + } + + // For safety, for instance, with empty resolve regions (extents calculation + // may overflow otherwise due to the assumption of at least one row, for + // example, but an empty texture is empty anyway). + if (!width_texels || !height_texels || !depth || !layout.array_size) { + std::memset(&layout, 0, sizeof(layout)); + return layout; + } + + // For safety, clamp the maximum level. + uint32_t max_level_for_dimensions = + rex::log2_floor(std::max(std::max(width_texels, height_texels), depth)); + assert_true(max_level <= max_level_for_dimensions); + max_level = std::min(max_level, max_level_for_dimensions); + layout.max_level = max_level; + + layout.packed_level = + has_packed_levels ? GetPackedMipLevel(width_texels, height_texels) : UINT32_MAX; + + // Clear unused level layouts to zero strides/sizes. + if (!has_base) { + std::memset(&layout.base, 0, sizeof(layout.base)); + } + if (layout.packed_level != 0) { + std::memset(&layout.mips[0], 0, sizeof(layout.mips[0])); + } + uint32_t max_stored_level = std::min(max_level, uint32_t(layout.packed_level)); + { + uint32_t mips_end = max_stored_level + 1; + assert_true(mips_end <= rex::countof(layout.mips)); + uint32_t mips_unused_count = uint32_t(rex::countof(layout.mips)) - mips_end; + if (mips_unused_count) { + std::memset(&layout.mips[mips_end], 0, sizeof(layout.mips[0]) * mips_unused_count); + std::memset(&layout.mip_offsets_bytes[mips_end], 0, + sizeof(layout.mip_offsets_bytes[0]) * mips_unused_count); + } + } + layout.mips_total_extent_bytes = 0; + + const FormatInfo* format_info = FormatInfo::Get(format); + uint32_t bytes_per_block = format_info->bytes_per_block(); + + // The loop counter can mean two things depending on whether the packed mip + // tail is stored as mip 0, because in this case, it would be ambiguous since + // both the base and the mips would be on "level 0", but stored separately and + // possibly with a different layout. + uint32_t loop_level_last; + if (layout.packed_level == 0) { + // Packed mip tail is the level 0 - may need to load mip tails for the base, + // the mips, or both. + // Loop iteration 0 - base packed mip tail. + // Loop iteration 1 - mips packed mip tail. + loop_level_last = uint32_t(max_level != 0); + } else { + // Packed mip tail is not the level 0. + // Loop iteration is the actual level being loaded. + loop_level_last = max_stored_level; + } + uint32_t mip_offset_bytes = 0; + for (uint32_t loop_level = has_base ? 0 : 1; loop_level <= loop_level_last; ++loop_level) { + bool is_base = loop_level == 0; + uint32_t level = (layout.packed_level == 0) ? 0 : loop_level; + TextureGuestLayout::Level& level_layout = is_base ? layout.base : layout.mips[level]; + + // Calculate the strides. + // Mips have row / depth slice strides calculated from a mip of a texture + // whose base size is a power of two. + // The base mip has tightly packed depth slices, and takes the row pitch + // from the fetch constant. + // For stride calculation purposes, mip dimensions are always aligned to + // 32x32x4 blocks (or x1 for the missing dimensions), including for linear + // textures. + // Linear texture rows are 256-byte-aligned. + uint32_t row_pitch_texels_unaligned; + uint32_t z_slice_stride_texel_rows_unaligned; + if (is_base) { + row_pitch_texels_unaligned = base_pitch_texels_div_32 << 5; + z_slice_stride_texel_rows_unaligned = height_texels; + } else { + row_pitch_texels_unaligned = std::max(rex::next_pow2(width_texels) >> level, uint32_t(1)); + z_slice_stride_texel_rows_unaligned = + std::max(rex::next_pow2(height_texels) >> level, uint32_t(1)); + } + uint32_t row_pitch_blocks_tile_aligned = rex::align( + rex::align(row_pitch_texels_unaligned, format_info->block_width) / format_info->block_width, + xenos::kTextureTileWidthHeight); + level_layout.row_pitch_bytes = row_pitch_blocks_tile_aligned * bytes_per_block; + // Assuming the provided pitch is already 256-byte-aligned for linear, but + // considering the guest-provided pitch more important (no information about + // how the GPU actually handles unaligned rows). + if (!is_tiled && !is_base) { + level_layout.row_pitch_bytes = + rex::align(level_layout.row_pitch_bytes, xenos::kTextureLinearRowAlignmentBytes); + } + level_layout.z_slice_stride_block_rows = + dimension != xenos::DataDimension::k1D + ? rex::align( + rex::align(z_slice_stride_texel_rows_unaligned, format_info->block_height) / + format_info->block_height, + xenos::kTextureTileWidthHeight) + : 1; + level_layout.array_slice_stride_bytes = + level_layout.row_pitch_bytes * level_layout.z_slice_stride_block_rows; + uint32_t z_stride_bytes = level_layout.array_slice_stride_bytes; + if (dimension == xenos::DataDimension::k3D) { + level_layout.array_slice_stride_bytes *= + rex::align(depth_or_array_size, xenos::kTextureTileDepth); + } + level_layout.array_slice_stride_bytes = + rex::align(level_layout.array_slice_stride_bytes, xenos::kTextureSubresourceAlignmentBytes); + + // Estimate the memory amount actually referenced by the texture, which may + // be smaller (especially in the 1280x720 linear k_8_8_8_8 case in 4E4D083E, + // for which memory exactly for 1280x720 is allocated, and aligning the + // height to 32 would cause access of an unallocated page) or bigger than + // the stride. + if (level == layout.packed_level) { + // Calculate the portion of the mip tail actually used by the needed mips. + // The actually used region may be significantly smaller than the full + // 32x32-texel-aligned (and, for mips, calculated from the base dimensions + // rounded to powers of two - 58410A7A has an 80x260 tiled texture with + // packed mips at level 3 containing a mip ending at Y = 36, while + // 260 >> 3 == 32, but 512 >> 3 == 64) tail. A 2x2 texture (for example, + // in 494707D4, there's a 2x2 k_8_8_8_8 linear texture with packed mips), + // for instance, would have its 2x2 base at (16, 0) and its 1x1 mip at + // (8, 0) - and we need 2 or 1 rows in these cases, not 32 - the 32 rows + // in a linear texture (with 256-byte pitch alignment) would span two 4 KB + // pages rather than one. + level_layout.x_extent_blocks = 0; + level_layout.y_extent_blocks = 0; + level_layout.z_extent = 0; + uint32_t packed_sublevel_last = is_base ? 0 : max_level; + for (uint32_t packed_sublevel = layout.packed_level; packed_sublevel <= packed_sublevel_last; + ++packed_sublevel) { + uint32_t packed_sublevel_x_blocks; + uint32_t packed_sublevel_y_blocks; + uint32_t packed_sublevel_z; + GetPackedMipOffset(width_texels, height_texels, depth, format, packed_sublevel, + packed_sublevel_x_blocks, packed_sublevel_y_blocks, packed_sublevel_z); + level_layout.x_extent_blocks = + std::max(level_layout.x_extent_blocks, + packed_sublevel_x_blocks + + rex::align(std::max(width_texels >> packed_sublevel, uint32_t(1)), + format_info->block_width) / + format_info->block_width); + level_layout.y_extent_blocks = + std::max(level_layout.y_extent_blocks, + packed_sublevel_y_blocks + + rex::align(std::max(height_texels >> packed_sublevel, uint32_t(1)), + format_info->block_height) / + format_info->block_height); + level_layout.z_extent = + std::max(level_layout.z_extent, + packed_sublevel_z + std::max(depth >> packed_sublevel, uint32_t(1))); + } + } else { + level_layout.x_extent_blocks = + rex::align(std::max(width_texels >> level, uint32_t(1)), format_info->block_width) / + format_info->block_width; + level_layout.y_extent_blocks = + rex::align(std::max(height_texels >> level, uint32_t(1)), format_info->block_height) / + format_info->block_height; + level_layout.z_extent = std::max(depth >> level, uint32_t(1)); + } + if (is_tiled) { + uint32_t bytes_per_block_log2 = rex::log2_floor(bytes_per_block); + if (dimension == xenos::DataDimension::k3D) { + level_layout.array_slice_data_extent_bytes = GetTiledAddressUpperBound3D( + level_layout.x_extent_blocks, level_layout.y_extent_blocks, level_layout.z_extent, + row_pitch_blocks_tile_aligned, level_layout.y_extent_blocks, bytes_per_block_log2); + } else { + level_layout.array_slice_data_extent_bytes = + GetTiledAddressUpperBound2D(level_layout.x_extent_blocks, level_layout.y_extent_blocks, + row_pitch_blocks_tile_aligned, bytes_per_block_log2); + } + } else { + level_layout.array_slice_data_extent_bytes = + z_stride_bytes * (level_layout.z_extent - 1) + + level_layout.row_pitch_bytes * (level_layout.y_extent_blocks - 1) + + bytes_per_block * level_layout.x_extent_blocks; + } + level_layout.level_data_extent_bytes = + level_layout.array_slice_stride_bytes * (layout.array_size - 1) + + level_layout.array_slice_data_extent_bytes; + + if (!is_base) { + layout.mip_offsets_bytes[level] = mip_offset_bytes; + layout.mips_total_extent_bytes = std::max( + layout.mips_total_extent_bytes, mip_offset_bytes + level_layout.level_data_extent_bytes); + mip_offset_bytes += level_layout.array_slice_stride_bytes * layout.array_size; + } + } + + return layout; +} + +int32_t GetTiledOffset2D(int32_t x, int32_t y, uint32_t pitch, uint32_t bytes_per_block_log2) { + // https://github.com/gildor2/UModel/blob/de8fbd3bc922427ea056b7340202dcdcc19ccff5/Unreal/UnTexture.cpp#L489 + pitch = rex::align(pitch, xenos::kTextureTileWidthHeight); + // Top bits of coordinates. + int32_t macro = ((x >> 5) + (y >> 5) * int32_t(pitch >> 5)) << (bytes_per_block_log2 + 7); + // Lower bits of coordinates (result is 6-bit value). + int32_t micro = ((x & 7) + ((y & 0xE) << 2)) << bytes_per_block_log2; + // Mix micro/macro + add few remaining x/y bits. + int32_t offset = macro + ((micro & ~0xF) << 1) + (micro & 0xF) + ((y & 1) << 4); + // Mix bits again. + return ((offset & ~0x1FF) << 3) + ((y & 16) << 7) + ((offset & 0x1C0) << 2) + + (((((y & 8) >> 2) + (x >> 3)) & 3) << 6) + (offset & 0x3F); +} + +int32_t GetTiledOffset3D(int32_t x, int32_t y, int32_t z, uint32_t pitch, uint32_t height, + uint32_t bytes_per_block_log2) { + // Reconstructed from disassembly of XGRAPHICS::TileVolume. + pitch = rex::align(pitch, xenos::kTextureTileWidthHeight); + height = rex::align(height, xenos::kTextureTileWidthHeight); + int32_t macro_outer = ((y >> 4) + (z >> 2) * int32_t(height >> 4)) * int32_t(pitch >> 5); + int32_t macro = ((((x >> 5) + macro_outer) << (bytes_per_block_log2 + 6)) & 0xFFFFFFF) << 1; + int32_t micro = (((x & 7) + ((y & 6) << 2)) << (bytes_per_block_log2 + 6)) >> 6; + int32_t offset_outer = ((y >> 3) + (z >> 2)) & 1; + int32_t offset1 = offset_outer + ((((x >> 3) + (offset_outer << 1)) & 3) << 1); + int32_t offset2 = ((macro + (micro & ~15)) << 1) + (micro & 15) + + ((z & 3) << (bytes_per_block_log2 + 6)) + ((y & 1) << 4); + int32_t address = (offset1 & 1) << 3; + address += (offset2 >> 6) & 7; + address <<= 3; + address += offset1 & ~1; + address <<= 2; + address += offset2 & ~511; + address <<= 3; + address += offset2 & 63; + return address; +} + +uint32_t GetTiledAddressUpperBound2D(uint32_t right, uint32_t bottom, uint32_t pitch, + uint32_t bytes_per_block_log2) { + if (!right || !bottom) { + return 0; + } + // Get the origin of the 32x32 tile containing the last texel. + uint32_t upper_bound = uint32_t(GetTiledOffset2D( + int32_t((right - 1) & ~(xenos::kTextureTileWidthHeight - 1)), + int32_t((bottom - 1) & ~(xenos::kTextureTileWidthHeight - 1)), pitch, bytes_per_block_log2)); + switch (bytes_per_block_log2) { + case 0: + // Independent addressing within 128x128 portions, but the extent is 0xA00 + // bytes from the 32x32 tile origin. + upper_bound += 0xA00; + break; + case 1: + // Independent addressing within 64x64 portions, but the extent is 0xC00 + // bytes from the 32x32 tile origin. + upper_bound += 0xC00; + break; + default: + upper_bound += UINT32_C(0x400) << bytes_per_block_log2; + break; + } + return upper_bound; +} + +uint32_t GetTiledAddressUpperBound3D(uint32_t right, uint32_t bottom, uint32_t back, uint32_t pitch, + uint32_t height, uint32_t bytes_per_block_log2) { + if (!right || !bottom || !back) { + return 0; + } + // Get the origin of the 32x32x4 tile containing the last texel. + uint32_t upper_bound = uint32_t(GetTiledOffset3D( + int32_t((right - 1) & ~(xenos::kTextureTileWidthHeight - 1)), + int32_t((bottom - 1) & ~(xenos::kTextureTileWidthHeight - 1)), + int32_t((back - 1) & ~(xenos::kTextureTileDepth - 1)), pitch, height, bytes_per_block_log2)); + uint32_t pitch_aligned = rex::align(pitch, xenos::kTextureTileWidthHeight); + switch (bytes_per_block_log2) { + case 0: + // 64x32x8 portions have independent addressing. + // Extent relative to the 32x32x4 tile origin: + // - Pitch = 32, 96, 160...: (Pitch / 64) * 0x1000 + 0x1000 + // - Pitch = 64, 128, 192...: (Pitch / 64) * 0x1000 + 0xC00 + upper_bound += + ((pitch_aligned >> 6) << 12) + 0xC00 + ((pitch_aligned & (1 << 5)) << (10 - 5)); + break; + default: + // 32x32x8 portions have independent addressing. + // Extent: ((Pitch / 32) * 0x1000 + 0x1000) * (BPB / 2) + // Or: ((Pitch / 32) * 0x1000 / 2 + 0x1000 / 2) * BPB + upper_bound += ((pitch_aligned << (12 - 5 - 1)) + (0x1000 >> 1)) << bytes_per_block_log2; + break; + } + return upper_bound; +} + +uint8_t SwizzleSigns(const xenos::xe_gpu_texture_fetch_t& fetch) { + uint8_t signs = 0; + bool any_not_signed = false, any_signed = false; + // 0b00 or 0b01 for each component, whether it's constant 0/1. + uint8_t constant_mask = 0b00000000; + for (uint32_t i = 0; i < 4; ++i) { + uint32_t swizzle = (fetch.swizzle >> (i * 3)) & 0b111; + if (swizzle & 0b100) { + constant_mask |= uint8_t(1) << (i * 2); + } else { + xenos::TextureSign sign = xenos::TextureSign((fetch.dword_0 >> (2 + swizzle * 2)) & 0b11); + signs |= uint8_t(sign) << (i * 2); + if (sign == xenos::TextureSign::kSigned) { + any_signed = true; + } else { + any_not_signed = true; + } + } + } + xenos::TextureSign constants_sign = xenos::TextureSign::kUnsigned; + if (constant_mask == 0b01010101) { + // If only constant components, choose according to the original format + // (what would more likely be loaded if there were non-constant components). + // If all components would be signed, use signed. + // Textures with only constant components must still be bound to shaders for + // various queries (such as filtering weights) not involving the color data + // itself. + if (((fetch.dword_0 >> 2) & 0b11111111) == uint32_t(xenos::TextureSign::kSigned) * 0b01010101) { + constants_sign = xenos::TextureSign::kSigned; + } + } else { + // If only signed and constant components, reading just from the signed host + // view is enough. + if (any_signed && !any_not_signed) { + constants_sign = xenos::TextureSign::kSigned; + } + } + signs |= uint8_t(constants_sign) * constant_mask; + return signs; +} + +void GetClampModesForDimension(const xenos::xe_gpu_texture_fetch_t& fetch, + xenos::ClampMode& clamp_x_out, xenos::ClampMode& clamp_y_out, + xenos::ClampMode& clamp_z_out) { + clamp_x_out = xenos::ClampMode::kClampToEdge; + clamp_y_out = xenos::ClampMode::kClampToEdge; + clamp_z_out = xenos::ClampMode::kClampToEdge; + switch (fetch.dimension) { + case xenos::DataDimension::k3D: + clamp_z_out = fetch.clamp_z; + [[fallthrough]]; + case xenos::DataDimension::k2DOrStacked: + clamp_y_out = fetch.clamp_y; + [[fallthrough]]; + case xenos::DataDimension::k1D: + clamp_x_out = fetch.clamp_x; + break; + default: + // Not applicable to cube textures. + break; + } +} + +} // namespace rex::graphics::texture_util diff --git a/src/graphics/primitive_processor.cpp b/src/graphics/primitive_processor.cpp new file mode 100644 index 0000000..19ee54a --- /dev/null +++ b/src/graphics/primitive_processor.cpp @@ -0,0 +1,1579 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(force_convert_line_loops_to_strips, false, "GPU", + "Force convert line loops to strips"); + +REXCVAR_DEFINE_BOOL(force_convert_quad_lists_to_triangle_lists, false, "GPU", + "Force convert quad lists to triangle lists"); + +REXCVAR_DEFINE_BOOL(force_convert_triangle_fans_to_lists, false, "GPU", + "Force convert triangle fans to lists"); + +REXCVAR_DEFINE_INT32(primitive_processor_cache_min_indices, 0, "GPU", + "Minimum indices for primitive processor cache") + .range(0, 1000000); + +// All these overrides are always safe to use as all backends are expected to +// support triangle lists and line strips. +// DEFINE_bool( +// force_convert_triangle_fans_to_lists, false, +// "For host graphics API downlevel support testing only, force CPU " +// "conversion of triangle fans to triangle lists even if the host supports " +// "triangle fan primitives natively.", +// "GPU"); +// DEFINE_bool( +// force_convert_line_loops_to_strips, false, +// "For host graphics API downlevel support testing only, force CPU " +// "conversion of line loops to line strips even if the host supports line " +// "loop primitives natively.", +// "GPU"); +// DEFINE_bool( +// force_convert_quad_lists_to_triangle_lists, false, +// "For host graphics API downlevel support testing only, force CPU " +// "conversion of quad lists to quad strips even if the host supports quad " +// "list primitives natively or via geometry shader emulation.\n" +// "May also be useful for graphics debugging when the debugger doesn't " +// "display the geometry generated by geometry shaders properly.", +// "GPU"); +// DEFINE_bool( +// ignore_32bit_vertex_index_support, false, +// "For host graphics API downlevel testing only (useful only for Qualcomm " +// "Adreno 4xx-level host GPU testing), force indirection or pre-masking and " +// "pre-swapping of 32-bit vertex indices as if the host only supports 24-bit " +// "indices.", +// "GPU"); +// TODO(Triang3l): More investigation of the cache threshold as cache lookups +// and insertions require global critical region locking, and insertions also +// require protecting pages. At 1024, the cache only made the performance worse +// (415607D4, 16-bit primitive reset index replacement). +// DEFINE_int32( +// primitive_processor_cache_min_indices, 4096, +// "Smallest number of guest indices to store in the cache to try reusing " +// "later in the same frame if processing (such as primitive type conversion " +// "or reset index replacement) is performed.\n" +// "Setting this to a very high value may result in excessive CPU processing, " +// "while a very low value may result in excessive locking and lookups.\n" +// "Negative values disable caching.", +// "GPU"); + +namespace rex::graphics { + +// SIMD processing here assumes that alignment is not required (neither AVX nor +// Neon requires it) and there's no punishment for using an unaligned access +// instruction when the data is actually aligned (AVX has separate aligned / +// unaligned movs, but they have the same performance nowadays; Neon dropped the +// alignment specifier in AArch64), but truly unaligned access may result in two +// hardware memory operations if some boundary that is >= vector size is +// crossed. +// +// Therefore, to minimize unaligned access (primarily reads - since we depend on +// the data immediately), SIMD usage here is performed according to the +// following pattern (though we try to co-align the destination and the source +// prior to calling, but still doing all the operations for more code +// correctness and fewer unobvious conditions): +// - Until the source pointer is vector-aligned, process the first indices +// without SIMD. +// - The best possible outcome of this is that both the source and the +// destination will be vector-aligned (if they were co-aligned prior to the +// call), in this case, neither load nor store instructions will be crossing +// cache lines. +// - The other possible outcome is that the source will be aligned (1 memory +// read per load), while the destination will be unaligned (1-2 memory +// writes per store). +// - Process whole vectors with SIMD. +// - If there are less elements than a vector can hold remaining, process them +// without SIMD. +// +// We assume that indices are at least aligned to their natural alignment (2 or +// 4 bytes depending on the format) - the R6xx documentation says that in +// DRAW_INDEX, INDEX_BASE_LO is word-aligned, and that's required by host +// graphics APIs. + +PrimitiveProcessor::~PrimitiveProcessor() { + ShutdownCommon(); +} + +bool PrimitiveProcessor::InitializeCommon(bool full_32bit_vertex_indices_supported, + bool triangle_fans_supported, bool line_loops_supported, + bool quad_lists_supported, + bool point_sprites_supported_without_vs_expansion, + bool rectangle_lists_supported_without_vs_expansion) { + full_32bit_vertex_indices_used_ = full_32bit_vertex_indices_supported; + convert_triangle_fans_to_lists_ = + !triangle_fans_supported || REXCVAR_GET(force_convert_triangle_fans_to_lists); + convert_line_loops_to_strips_ = + !line_loops_supported || REXCVAR_GET(force_convert_line_loops_to_strips); + convert_quad_lists_to_triangle_lists_ = + !quad_lists_supported || REXCVAR_GET(force_convert_quad_lists_to_triangle_lists); + // No override cvars as hosts are not required to support the fallback paths + // since they require different vertex shader structure (for the fallback + // HostVertexShaderTypes). + expand_point_sprites_in_vs_ = !point_sprites_supported_without_vs_expansion; + expand_rectangle_lists_in_vs_ = !rectangle_lists_supported_without_vs_expansion; + + // Initialize the index buffer for conversion of auto-indexed primitive types. + size_t builtin_index_buffer_size = 0; + // 32-bit, before 16-bit due to alignment (for primitive expansion - when the + // indices encode not only the guest vertex index, but also a part needed for + // host expansion, thus may contain values above UINT16_MAX, such as up to + // (UINT16_MAX - 1) * 4 + 3 for point sprites). + // Using an index buffer for point sprite and rectangle list expansion instead + // of instancing as how instancing is implemented may vary wildly between + // GPUs, potentially slowly (like no different instances in the same + // wavefront) with small vertex counts per instance. Also using triangle + // strips with primitive restart, not triangle lists, so the vertex shader may + // be invoked once for the inner edge vertices, which is important for memory + // export in guest shaders, not to write to the same location from two + // invocations. + uint32_t builtin_ib_two_triangle_strip_count = 0; + if (expand_point_sprites_in_vs_) { + builtin_ib_two_triangle_strip_count = + std::max(uint32_t(UINT16_MAX), builtin_ib_two_triangle_strip_count); + } + if (expand_rectangle_lists_in_vs_) { + builtin_ib_two_triangle_strip_count = + std::max(uint32_t(UINT16_MAX / 3), builtin_ib_two_triangle_strip_count); + } + if (builtin_ib_two_triangle_strip_count) { + builtin_ib_offset_two_triangle_strips_ = builtin_index_buffer_size; + builtin_index_buffer_size += + sizeof(uint32_t) * GetTwoTriangleStripIndexCount(builtin_ib_two_triangle_strip_count); + } else { + builtin_ib_offset_two_triangle_strips_ = SIZE_MAX; + } + // 16-bit (for indirection on top of single auto-indexed vertices) - enough + // even if the backend has primitive reset enabled all the time (Metal) as + // auto-indexed draws are limited to UINT16_MAX vertices, not UINT16_MAX + 1. + if (convert_triangle_fans_to_lists_) { + builtin_ib_offset_triangle_fans_to_lists_ = builtin_index_buffer_size; + builtin_index_buffer_size += sizeof(uint16_t) * GetTriangleFanListIndexCount(UINT16_MAX); + } else { + builtin_ib_offset_triangle_fans_to_lists_ = SIZE_MAX; + } + if (convert_quad_lists_to_triangle_lists_) { + builtin_ib_offset_quad_lists_to_triangle_lists_ = builtin_index_buffer_size; + builtin_index_buffer_size += sizeof(uint16_t) * GetQuadListTriangleListIndexCount(UINT16_MAX); + } else { + builtin_ib_offset_quad_lists_to_triangle_lists_ = SIZE_MAX; + } + if (builtin_index_buffer_size) { + if (!InitializeBuiltinIndexBuffer( + builtin_index_buffer_size, [this, builtin_ib_two_triangle_strip_count](void* mapping) { + uint32_t* mapping_32bit = reinterpret_cast(mapping); + if (builtin_ib_offset_two_triangle_strips_ != SIZE_MAX) { + // Two-triangle strips. + uint32_t* two_triangle_strip_ptr = + mapping_32bit + builtin_ib_offset_two_triangle_strips_ / sizeof(uint32_t); + for (uint32_t i = 0; i < builtin_ib_two_triangle_strip_count; ++i) { + if (i) { + // Primitive restart. + *(two_triangle_strip_ptr++) = UINT32_MAX; + } + // Host vertex index within the pair in the lower 2 bits, + // guest primitive index in the rest. + uint32_t two_triangle_strip_first_index = i << 2; + for (uint32_t j = 0; j < 4; ++j) { + *(two_triangle_strip_ptr++) = two_triangle_strip_first_index + j; + } + } + } + uint16_t* mapping_16bit = reinterpret_cast(mapping); + if (builtin_ib_offset_triangle_fans_to_lists_ != SIZE_MAX) { + // Triangle fans as triangle lists. + // Ordered as (v1, v2, v0), (v2, v3, v0) in Direct3D. + // https://docs.microsoft.com/en-us/windows/desktop/direct3d9/triangle-fans + uint16_t* triangle_list_ptr = + mapping_16bit + builtin_ib_offset_triangle_fans_to_lists_ / sizeof(uint16_t); + for (uint32_t i = 2; i < UINT16_MAX; ++i) { + *(triangle_list_ptr++) = uint16_t(i - 1); + *(triangle_list_ptr++) = uint16_t(i); + *(triangle_list_ptr++) = 0; + } + } + if (builtin_ib_offset_quad_lists_to_triangle_lists_ != SIZE_MAX) { + uint16_t* triangle_list_ptr = + mapping_16bit + + builtin_ib_offset_quad_lists_to_triangle_lists_ / sizeof(uint16_t); + // TODO(Triang3l): SIMD for faster initialization? + for (uint32_t i = 0; i < UINT16_MAX / 4; ++i) { + uint16_t quad_first_index = uint16_t(i * 4); + // TODO(Triang3l): Find the correct order. + // v0, v1, v2. + *(triangle_list_ptr++) = quad_first_index; + *(triangle_list_ptr++) = quad_first_index + 1; + *(triangle_list_ptr++) = quad_first_index + 2; + // v0, v2, v3. + *(triangle_list_ptr++) = quad_first_index; + *(triangle_list_ptr++) = quad_first_index + 2; + *(triangle_list_ptr++) = quad_first_index + 3; + } + } + })) { + ShutdownCommon(); + return false; + } + } + + return true; +} + +void PrimitiveProcessor::ShutdownCommon() { + if (memory_invalidation_callback_handle_) { + // Clear the cache if it has ever been used and unregister the invalidation + // callback. + { + std::lock_guard cache_lock(cache_mutex_); + cache_map_.clear(); + cache_bucket_free_first_entry_ = SIZE_MAX; + std::memset(cache_buckets_non_empty_l1_, 0, sizeof(cache_buckets_non_empty_l1_)); + std::memset(cache_buckets_non_empty_l2_, 0, sizeof(cache_buckets_non_empty_l2_)); + } + memory_.UnregisterPhysicalMemoryInvalidationCallback(memory_invalidation_callback_handle_); + memory_invalidation_callback_handle_ = nullptr; + cache_entry_pool_.clear(); + } +} + +void PrimitiveProcessor::ClearPerFrameCache() { + if (!memory_invalidation_callback_handle_) { + // Only do clearing if cache has ever been used. + return; + } + std::lock_guard cache_lock(cache_mutex_); + for (const std::pair& cache_map_entry : cache_map_) { + cache_entry_pool_[cache_map_entry.second].free_next = cache_bucket_free_first_entry_; + cache_bucket_free_first_entry_ = cache_map_entry.second; + } + cache_map_.clear(); + std::memset(cache_buckets_non_empty_l1_, 0, sizeof(cache_buckets_non_empty_l1_)); + std::memset(cache_buckets_non_empty_l2_, 0, sizeof(cache_buckets_non_empty_l2_)); +} + +bool PrimitiveProcessor::Process(ProcessingResult& result_out) { + SCOPE_profile_cpu_f("gpu"); + + const RegisterFile& regs = register_file_; + auto vgt_draw_initiator = regs.Get(); + + // Parse the primitive type and the tessellation state (VGT_OUTPUT_PATH_CNTL + // is only used in the explicit major mode) - there are cases in games when + // this register is left over after usage of tessellation in draws that don't + // need it. + xenos::PrimitiveType guest_primitive_type = vgt_draw_initiator.prim_type; + xenos::PrimitiveType host_primitive_type = guest_primitive_type; + bool tessellation_enabled = + xenos::IsMajorModeExplicit(vgt_draw_initiator.major_mode, vgt_draw_initiator.prim_type) && + regs.Get().path_select == + xenos::VGTOutputPath::kTessellationEnable; + xenos::TessellationMode tessellation_mode = regs.Get().tess_mode; + Shader::HostVertexShaderType host_vertex_shader_type; + if (tessellation_enabled) { + // Currently only supporting tessellation in known cases for safety, and not + // yet converting patch strips / fans to patch lists until games using them + // are found for easier debugging when it actually happens. + // TODO(Triang3l): Conversion of patch strips / fans if found. + host_vertex_shader_type = Shader::HostVertexShaderType(-1); + switch (guest_primitive_type) { + case xenos::PrimitiveType::kTriangleList: + // Also supported by triangle strips and fans according to: + // https://www.khronos.org/registry/OpenGL/extensions/AMD/AMD_vertex_shader_tessellator.txt + // Would need to convert those to triangle lists, but haven't seen any + // games using tessellated strips / fans so far. + switch (tessellation_mode) { + case xenos::TessellationMode::kDiscrete: + // - 415607E1 - nets above barrels in the beginning of the first + // mission (turn right after the end of the intro) - + // kTriangleList. + host_vertex_shader_type = Shader::HostVertexShaderType::kTriangleDomainCPIndexed; + break; + case xenos::TessellationMode::kContinuous: + // - 4D5307F2 - tree building with a beehive in the beginning + // (visible on the start screen behind the logo), waterfall in the + // beginning - kTriangleList. + host_vertex_shader_type = Shader::HostVertexShaderType::kTriangleDomainCPIndexed; + break; + default: + break; + } + break; + case xenos::PrimitiveType::kQuadList: + switch (tessellation_mode) { + // Also supported by quad strips according to: + // https://www.khronos.org/registry/OpenGL/extensions/AMD/AMD_vertex_shader_tessellator.txt + // Would need to convert those to quad lists, but haven't seen any + // games using tessellated strips so far. + case xenos::TessellationMode::kDiscrete: + // Not seen in games so far. + host_vertex_shader_type = Shader::HostVertexShaderType::kQuadDomainCPIndexed; + break; + case xenos::TessellationMode::kContinuous: + // - 58410823 - retro screen and beams in the main menu - kQuadList. + host_vertex_shader_type = Shader::HostVertexShaderType::kQuadDomainCPIndexed; + break; + default: + break; + } + break; + case xenos::PrimitiveType::kTrianglePatch: + // - 4D5307E6 - water - adaptive. + // - 4D5307ED - water - adaptive. + host_vertex_shader_type = Shader::HostVertexShaderType::kTriangleDomainPatchIndexed; + break; + case xenos::PrimitiveType::kQuadPatch: + // - 4D5307F1 - ground - continuous. + // - 4D5307F2 - garden ground - adaptive. + host_vertex_shader_type = Shader::HostVertexShaderType::kQuadDomainPatchIndexed; + break; + default: + // TODO(Triang3l): Support line patches. + break; + } + if (host_vertex_shader_type == Shader::HostVertexShaderType(-1)) { + REXGPU_ERROR( + "Primitive processor: Unsupported tessellation mode {} for primitive " + "type {}. Report the game to Xenia developers!", + uint32_t(tessellation_mode), uint32_t(guest_primitive_type)); + assert_always(); + return false; + } + } else { + host_vertex_shader_type = Shader::HostVertexShaderType::kVertex; + switch (guest_primitive_type) { + case xenos::PrimitiveType::kPointList: + if (expand_point_sprites_in_vs_) { + host_primitive_type = xenos::PrimitiveType::kTriangleStrip; + host_vertex_shader_type = Shader::HostVertexShaderType::kPointListAsTriangleStrip; + } + break; + case xenos::PrimitiveType::kLineList: + case xenos::PrimitiveType::kLineStrip: + case xenos::PrimitiveType::kTriangleList: + case xenos::PrimitiveType::kTriangleStrip: + // Supported natively on all backends. + break; + case xenos::PrimitiveType::kRectangleList: + if (expand_rectangle_lists_in_vs_) { + host_primitive_type = xenos::PrimitiveType::kTriangleStrip; + host_vertex_shader_type = Shader::HostVertexShaderType::kRectangleListAsTriangleStrip; + } + break; + case xenos::PrimitiveType::kTriangleFan: + if (convert_triangle_fans_to_lists_) { + host_primitive_type = xenos::PrimitiveType::kTriangleList; + } + break; + case xenos::PrimitiveType::kLineLoop: + if (convert_line_loops_to_strips_) { + host_primitive_type = xenos::PrimitiveType::kLineStrip; + } + break; + case xenos::PrimitiveType::kQuadList: + if (convert_quad_lists_to_triangle_lists_) { + host_primitive_type = xenos::PrimitiveType::kTriangleList; + } + break; + default: + REXGPU_ERROR( + "Primitive processor: Unsupported primitive type {}. Report the " + "game to Xenia developers!", + uint32_t(guest_primitive_type)); + assert_always(); + return false; + } + } + + // Process the indices. + uint32_t guest_draw_vertex_count = vgt_draw_initiator.num_indices; + auto vgt_dma_size = regs.Get(); + if (vgt_draw_initiator.source_select == xenos::SourceSelect::kDMA && + guest_draw_vertex_count > vgt_dma_size.num_words) { + REXGPU_WARN( + "Primitive processor: {} vertices attempted to be drawn with an index " + "buffer only containing {}. Should be fetching zero indices instead of " + "overflowing ones, but this is a rare situation, so not handled yet. " + "Report the game to Xenia developers!", + guest_draw_vertex_count, static_cast(vgt_dma_size.num_words)); + guest_draw_vertex_count = vgt_dma_size.num_words; + } + uint32_t line_loop_closing_index = 0; + uint32_t guest_index_base = 0, guest_index_buffer_needed_bytes = 0; + CachedResult cacheable; + cacheable.host_draw_vertex_count = guest_draw_vertex_count; + cacheable.host_primitive_reset_enabled = false; + cacheable.host_index_buffer_handle = SIZE_MAX; + if (host_vertex_shader_type == Shader::HostVertexShaderType::kPointListAsTriangleStrip || + host_vertex_shader_type == Shader::HostVertexShaderType::kRectangleListAsTriangleStrip) { + // As two-triangle strips, with guest indices being either autogenerated or + // fetched via DMA. + uint32_t primitive_count = guest_draw_vertex_count; + if (host_vertex_shader_type == Shader::HostVertexShaderType::kRectangleListAsTriangleStrip) { + primitive_count /= 3; + } + cacheable.host_draw_vertex_count = GetTwoTriangleStripIndexCount(primitive_count); + cacheable.host_index_format = xenos::IndexFormat::kInt32; + cacheable.host_primitive_reset_enabled = true; + assert_true(builtin_ib_offset_two_triangle_strips_ != SIZE_MAX); + cacheable.host_index_buffer_handle = builtin_ib_offset_two_triangle_strips_; + if (vgt_draw_initiator.source_select == xenos::SourceSelect::kAutoIndex) { + cacheable.index_buffer_type = ProcessedIndexBufferType::kHostBuiltinForAuto; + cacheable.host_shader_index_endian = xenos::Endian::kNone; + } else { + // There is an index buffer. + assert_true(vgt_draw_initiator.source_select == xenos::SourceSelect::kDMA); + if (vgt_draw_initiator.source_select != xenos::SourceSelect::kDMA) { + // TODO(Triang3l): Support immediate-indexed vertices. + REXGPU_ERROR( + "Primitive processor: Unsupported vertex index source {}. Report " + "the game to Xenia developers!", + uint32_t(vgt_draw_initiator.source_select)); + return false; + } + xenos::IndexFormat guest_index_format = vgt_draw_initiator.index_size; + // Normalize the endian. + cacheable.index_buffer_type = ProcessedIndexBufferType::kHostBuiltinForDMA; + xenos::Endian guest_index_endian = vgt_dma_size.swap_mode; + if (guest_index_format == xenos::IndexFormat::kInt16 && + (guest_index_endian != xenos::Endian::kNone && + guest_index_endian != xenos::Endian::k8in16)) { + REXGPU_WARN( + "Primitive processor: 32-bit endian swap mode {} is used for " + "16-bit indices. This shouldn't normally be happening, but report " + "the game to Xenia developers for investigation of the intended " + "behavior (ignore or actually swap across adjacent indices)! " + "Currently disabling the swap for 16-and-32 and replacing 8-in-32 " + "with 8-in-16.", + uint32_t(guest_index_endian)); + guest_index_endian = guest_index_endian == xenos::Endian::k8in32 ? xenos::Endian::k8in16 + : xenos::Endian::kNone; + } + cacheable.host_shader_index_endian = guest_index_endian; + // Get the index buffer memory range. + uint32_t index_size_log2 = guest_index_format == xenos::IndexFormat::kInt16 ? 1 : 2; + // The base should already be aligned, but aligning here too for safety. + guest_index_base = regs[XE_GPU_REG_VGT_DMA_BASE] & ~uint32_t((1 << index_size_log2) - 1); + guest_index_buffer_needed_bytes = guest_draw_vertex_count << index_size_log2; + if (guest_index_base > SharedMemory::kBufferSize || + SharedMemory::kBufferSize - guest_index_base < guest_index_buffer_needed_bytes) { + REXGPU_ERROR( + "Primitive processor: Index buffer at 0x{:08X}, 0x{:X} bytes " + "required, is out of the physical memory bounds", + guest_index_base, guest_index_buffer_needed_bytes); + assert_always(); + return false; + } + } + } else if (vgt_draw_initiator.source_select == xenos::SourceSelect::kAutoIndex) { + // Auto-indexed - use a remapping index buffer if needed to change the + // primitive type. + if (tessellation_enabled && tessellation_mode == xenos::TessellationMode::kAdaptive) { + REXGPU_ERROR( + "Primitive processor: Adaptive tessellation requires 32-bit " + "floating-point edge tessellation factors in the index buffer, but " + "no index buffer is provided by the guest."); + assert_always(); + return false; + } + cacheable.host_index_format = xenos::IndexFormat::kInt16; + cacheable.host_shader_index_endian = xenos::Endian::kNone; + cacheable.host_primitive_reset_enabled = false; + cacheable.index_buffer_type = ProcessedIndexBufferType::kNone; + if (host_primitive_type != guest_primitive_type) { + switch (guest_primitive_type) { + case xenos::PrimitiveType::kTriangleFan: + assert_true(host_primitive_type == xenos::PrimitiveType::kTriangleList); + cacheable.host_draw_vertex_count = + GetTriangleFanListIndexCount(cacheable.host_draw_vertex_count); + cacheable.index_buffer_type = ProcessedIndexBufferType::kHostBuiltinForAuto; + assert_true(builtin_ib_offset_triangle_fans_to_lists_ != SIZE_MAX); + cacheable.host_index_buffer_handle = builtin_ib_offset_triangle_fans_to_lists_; + break; + case xenos::PrimitiveType::kLineLoop: + // Plus 1 element (if there's anything to draw) in the strip, still + // auto-indexed, but the added excess index should be treated as 0 by + // the vertex shaders. + assert_true(host_primitive_type == xenos::PrimitiveType::kLineStrip); + cacheable.host_draw_vertex_count = + GetLineLoopStripIndexCount(cacheable.host_draw_vertex_count); + if (cacheable.host_draw_vertex_count) { + line_loop_closing_index = cacheable.host_draw_vertex_count - 1; + } + break; + case xenos::PrimitiveType::kQuadList: + assert_true(host_primitive_type == xenos::PrimitiveType::kTriangleList); + cacheable.host_draw_vertex_count = + GetQuadListTriangleListIndexCount(cacheable.host_draw_vertex_count); + cacheable.index_buffer_type = ProcessedIndexBufferType::kHostBuiltinForAuto; + assert_true(builtin_ib_offset_quad_lists_to_triangle_lists_ != SIZE_MAX); + cacheable.host_index_buffer_handle = builtin_ib_offset_quad_lists_to_triangle_lists_; + break; + default: + assert_always(); + return false; + } + } + } else { + // There is an index buffer. + assert_true(vgt_draw_initiator.source_select == xenos::SourceSelect::kDMA); + if (vgt_draw_initiator.source_select != xenos::SourceSelect::kDMA) { + // TODO(Triang3l): Support immediate-indexed vertices. + REXGPU_ERROR( + "Primitive processor: Unsupported vertex index source {}. Report the " + "game to Xenia developers!", + uint32_t(vgt_draw_initiator.source_select)); + return false; + } + xenos::IndexFormat guest_index_format = vgt_draw_initiator.index_size; + cacheable.host_index_format = guest_index_format; + // Normalize the endian and the reset index. + xenos::Endian guest_index_endian = vgt_dma_size.swap_mode; + if (guest_index_format == xenos::IndexFormat::kInt16 && + (guest_index_endian != xenos::Endian::kNone && + guest_index_endian != xenos::Endian::k8in16)) { + REXGPU_WARN( + "Primitive processor: 32-bit endian swap mode {} is used for 16-bit " + "indices. This shouldn't normally be happening, but report the game " + "to Xenia developers for investigation of the intended behavior " + "(ignore or actually swap across adjacent indices)! Currently " + "disabling the swap for 16-and-32 and replacing 8-in-32 with " + "8-in-16.", + uint32_t(guest_index_endian)); + guest_index_endian = guest_index_endian == xenos::Endian::k8in32 ? xenos::Endian::k8in16 + : xenos::Endian::kNone; + } + bool guest_primitive_reset_enabled = false; + uint32_t guest_primitive_reset_index_guest_endian = 0; + if (tessellation_enabled && tessellation_mode == xenos::TessellationMode::kAdaptive) { + // Adaptive tessellation uses the index buffer not for indices, but for + // 32-bit floating-point edge factors - no primitive reset. + if (guest_index_format != xenos::IndexFormat::kInt32) { + REXGPU_ERROR( + "Primitive processor: Adaptive tessellation requires 32-bit " + "floating-point edge tessellation factors in the index buffer, but " + "16-bit index buffer is provided by the guest."); + assert_always(); + return false; + } + } else { + if (regs.Get().multi_prim_ib_ena) { + switch (guest_primitive_type) { + case xenos::PrimitiveType::kLineStrip: + case xenos::PrimitiveType::kTriangleFan: + case xenos::PrimitiveType::kTriangleStrip: + case xenos::PrimitiveType::kLineLoop: + case xenos::PrimitiveType::kQuadStrip: + case xenos::PrimitiveType::kPolygon: + case xenos::PrimitiveType::k2DLineStrip: + case xenos::PrimitiveType::k2DTriStrip: + guest_primitive_reset_index_guest_endian = xenos::GpuSwap( + regs.Get().reset_indx, guest_index_endian); + // - VGT, what does the guest say about its primitive reset index? + // - It's over 0xFFFF!!! + // - What!? 0xFFFF!? There's no way that can be stored in 16 bits! + guest_primitive_reset_enabled = + guest_index_format == xenos::IndexFormat::kInt16 + ? guest_primitive_reset_index_guest_endian <= UINT16_MAX + : true; + break; + default: + // Vulkan explicitly disallows primitive restart index for "list" + // topologies. In Direct3D 12, it's valid for non-strips, but has + // implementation-defined behavior. Make backend usage simpler by + // explicitly filtering lists out, and hope the guest never uses + // primitive reset for lists. + break; + } + } + } + + // Get the index buffer memory range. + uint32_t index_size_log2 = guest_index_format == xenos::IndexFormat::kInt16 ? 1 : 2; + // The base should already be aligned, but aligning here too for safety. + guest_index_base = regs[XE_GPU_REG_VGT_DMA_BASE] & ~uint32_t((1 << index_size_log2) - 1); + guest_index_buffer_needed_bytes = guest_draw_vertex_count << index_size_log2; + if (guest_index_base > SharedMemory::kBufferSize || + SharedMemory::kBufferSize - guest_index_base < guest_index_buffer_needed_bytes) { + REXGPU_ERROR( + "Primitive processor: Index buffer at 0x{:08X}, 0x{:X} bytes " + "required, is out of the physical memory bounds", + guest_index_base, guest_index_buffer_needed_bytes); + assert_always(); + return false; + } + + cacheable.host_index_format = guest_index_format; + cacheable.host_shader_index_endian = guest_index_endian; + uint32_t guest_index_mask_guest_endian = + guest_index_format == xenos::IndexFormat::kInt16 + ? UINT16_MAX + : GpuSwap(xenos::kVertexIndexMask, guest_index_endian); + if (host_primitive_type != guest_primitive_type) { + // Already converting to a different index type - primitive reset is + // performed during conversion here. Also doing the endian swap here for + // hosts not supporting 32-bit indices because indirection is only used + // for the shared memory buffer. + // Writing to the trace irrespective of the cache lookup result because + // cache behavior depends on runtime configuration and state. + trace_writer_.WriteMemoryRead(guest_index_base, guest_index_buffer_needed_bytes); + CacheTransaction cache_transaction( + *this, CacheKey(guest_index_base, guest_draw_vertex_count, guest_index_format, + guest_index_endian, guest_primitive_reset_enabled, guest_primitive_type)); + if (cache_transaction.GetFoundResult()) { + cacheable = *cache_transaction.GetFoundResult(); + } else { + const void* guest_indices_ptr = memory_.TranslatePhysical(guest_index_base); + cacheable.index_buffer_type = ProcessedIndexBufferType::kHostConverted; + cacheable.host_primitive_reset_enabled = false; + std::function host_index_count_getter; + switch (guest_primitive_type) { + case xenos::PrimitiveType::kTriangleFan: + host_index_count_getter = GetTriangleFanListIndexCount; + break; + case xenos::PrimitiveType::kLineLoop: + host_index_count_getter = GetLineLoopStripIndexCount; + break; + case xenos::PrimitiveType::kQuadList: + host_index_count_getter = GetQuadListTriangleListIndexCount; + break; + default: + assert_unhandled_case(guest_primitive_type); + return false; + } + single_primitive_ranges_.clear(); + if (guest_index_format == xenos::IndexFormat::kInt16) { + // 16-bit indices - just convert the primitive (or multiple + // primitives) to the host topology. + // TODO(Triang3l): 16-bit > 32-bit primitive type conversion for + // Metal, where primitive reset is always enabled, if UINT16_MAX is + // used as a real vertex index. + auto guest_indices = reinterpret_cast(guest_indices_ptr); + if (guest_primitive_reset_enabled && + IsResetUsed(guest_indices, guest_draw_vertex_count, + guest_primitive_reset_index_guest_endian)) { + // Multiple primitives in the index buffer - gather all single + // primitives. + cacheable.host_draw_vertex_count = GetMultiPrimitiveHostIndexCountAndRanges( + host_index_count_getter, guest_indices, guest_draw_vertex_count, + guest_primitive_reset_index_guest_endian, single_primitive_ranges_); + } else { + cacheable.host_draw_vertex_count = host_index_count_getter(guest_draw_vertex_count); + single_primitive_ranges_.emplace_back(0, guest_draw_vertex_count, + cacheable.host_draw_vertex_count); + } + auto host_indices = + reinterpret_cast(RequestHostConvertedIndexBufferForCurrentFrame( + xenos::IndexFormat::kInt16, cacheable.host_draw_vertex_count, false, + guest_index_base, cacheable.host_index_buffer_handle)); + if (!host_indices) { + return false; + } + ConvertSinglePrimitiveRanges( + host_indices, guest_indices, guest_primitive_type, PassthroughIndexTransform(), + single_primitive_ranges_.cbegin(), single_primitive_ranges_.cend()); + } else { + // 32-bit indices - may need to pre-swap and pre-mask also if the host + // doesn't support full 32-bit vertex indices. + auto guest_indices = reinterpret_cast(guest_indices_ptr); + if (guest_primitive_reset_enabled && IsResetUsed(guest_indices, guest_draw_vertex_count, + guest_primitive_reset_index_guest_endian, + guest_index_mask_guest_endian)) { + // Multiple primitives in the index buffer - gather all single + // primitives. + cacheable.host_draw_vertex_count = GetMultiPrimitiveHostIndexCountAndRanges( + host_index_count_getter, guest_indices, guest_draw_vertex_count, + guest_primitive_reset_index_guest_endian, guest_index_mask_guest_endian, + single_primitive_ranges_); + } else { + cacheable.host_draw_vertex_count = host_index_count_getter(guest_draw_vertex_count); + single_primitive_ranges_.emplace_back(0, guest_draw_vertex_count, + cacheable.host_draw_vertex_count); + } + auto host_indices = + reinterpret_cast(RequestHostConvertedIndexBufferForCurrentFrame( + xenos::IndexFormat::kInt32, cacheable.host_draw_vertex_count, false, + guest_index_base, cacheable.host_index_buffer_handle)); + if (!host_indices) { + return false; + } + auto single_primitive_ranges_beginning = single_primitive_ranges_.cbegin(); + auto single_primitive_ranges_end = single_primitive_ranges_.cend(); + if (full_32bit_vertex_indices_used_) { + ConvertSinglePrimitiveRanges( + host_indices, guest_indices, guest_primitive_type, PassthroughIndexTransform(), + single_primitive_ranges_beginning, single_primitive_ranges_end); + } else { + switch (guest_index_endian) { + case xenos::Endian::kNone: + ConvertSinglePrimitiveRanges(host_indices, guest_indices, guest_primitive_type, + To24NonSwappingIndexTransform(), + single_primitive_ranges_beginning, + single_primitive_ranges_end); + break; + case xenos::Endian::k8in16: + ConvertSinglePrimitiveRanges(host_indices, guest_indices, guest_primitive_type, + To24Swapping8In16IndexTransform(), + single_primitive_ranges_beginning, + single_primitive_ranges_end); + break; + case xenos::Endian::k8in32: + ConvertSinglePrimitiveRanges(host_indices, guest_indices, guest_primitive_type, + To24Swapping8In32IndexTransform(), + single_primitive_ranges_beginning, + single_primitive_ranges_end); + break; + case xenos::Endian::k16in32: + ConvertSinglePrimitiveRanges(host_indices, guest_indices, guest_primitive_type, + To24Swapping16In32IndexTransform(), + single_primitive_ranges_beginning, + single_primitive_ranges_end); + break; + default: + assert_unhandled_case(guest_index_endian); + return false; + } + cacheable.host_shader_index_endian = xenos::Endian::kNone; + } + } + cache_transaction.SetNewResult(cacheable); + } + } else { + // Using the same indices on the host as on the guest, either directly or + // (for backends not supporting full 32-bit indices, thus unable to + // endian-swap, or even to safely drop the upper 8 bits if no swap is even + // needed) indirectly. + cacheable.host_draw_vertex_count = guest_draw_vertex_count; + cacheable.index_buffer_type = ProcessedIndexBufferType::kGuestDMA; + cacheable.host_primitive_reset_enabled = guest_primitive_reset_enabled; + if (guest_primitive_reset_enabled) { + if (guest_index_format == xenos::IndexFormat::kInt16) { + // The whole 16-bit index is compared to the primitive reset index. + // Does not need indirection on backends not supporting full 32-bit + // indices. + if (guest_primitive_reset_index_guest_endian != UINT16_MAX) { + // If primitive reset with a non-0xFFFF index is used, replace with + // 0xFFFF if 0xFFFF is not used as a real index, or with 0xFFFFFFFF + // if it is. + // Writing to the trace irrespective of the cache lookup result + // because cache behavior depends on runtime configuration and + // state. + // Example of 16-bit reset index replacement: 415607D4. + trace_writer_.WriteMemoryRead(guest_index_base, guest_index_buffer_needed_bytes); + // Not specifying the primitive type in the cache key because not + // replacing it, only the reset index in a type-independent way. + CacheTransaction cache_transaction( + *this, CacheKey(guest_index_base, guest_draw_vertex_count, guest_index_format, + guest_index_endian, guest_primitive_reset_enabled)); + if (cache_transaction.GetFoundResult()) { + cacheable = *cache_transaction.GetFoundResult(); + } else { + auto guest_indices = memory_.TranslatePhysical(guest_index_base); + bool is_reset_index_used, is_ffff_used_as_vertex_index; + Get16BitResetIndexUsage(guest_indices, guest_draw_vertex_count, + guest_primitive_reset_index_guest_endian, is_reset_index_used, + is_ffff_used_as_vertex_index); + if (is_reset_index_used) { + cacheable.index_buffer_type = ProcessedIndexBufferType::kHostConverted; + cacheable.host_index_format = is_ffff_used_as_vertex_index + ? xenos::IndexFormat::kInt32 + : xenos::IndexFormat::kInt16; + void* host_indices_ptr = RequestHostConvertedIndexBufferForCurrentFrame( + cacheable.host_index_format, guest_draw_vertex_count, true, guest_index_base, + cacheable.host_index_buffer_handle); + if (!host_indices_ptr) { + return false; + } + if (is_ffff_used_as_vertex_index) { + ReplaceResetIndex16To24(reinterpret_cast(host_indices_ptr), + guest_indices, guest_draw_vertex_count, + guest_primitive_reset_index_guest_endian); + } else { + ReplaceResetIndex16To16(reinterpret_cast(host_indices_ptr), + guest_indices, guest_draw_vertex_count, + guest_primitive_reset_index_guest_endian); + } + } + cache_transaction.SetNewResult(cacheable); + } + } + } else { + // Low 24 bits of the guest index are compared to the primitive reset + // index. If the backend doesn't support full 32-bit indices, for + // ProcessedIndexBufferType::kGuestDMA, the host needs to read the + // buffer indirectly in the vertex shaders and swap, and for + // ProcessedIndexBufferType::kHostConverted (if primitive reset is + // actually used, thus exactly 0xFFFFFFFF must be sent to the host for + // it in a true index buffer), no indirection is done, but + // pre-swapping and pre-masking is done here. + // Writing to the trace irrespective of the cache lookup result + // because cache behavior depends on runtime configuration and state. + trace_writer_.WriteMemoryRead(guest_index_base, guest_index_buffer_needed_bytes); + // Not specifying the primitive type in the cache key because not + // replacing it, only the reset index in a type-independent way. + CacheTransaction cache_transaction( + *this, CacheKey(guest_index_base, guest_draw_vertex_count, guest_index_format, + guest_index_endian, guest_primitive_reset_enabled)); + if (cache_transaction.GetFoundResult()) { + cacheable = *cache_transaction.GetFoundResult(); + } else { + auto guest_indices = memory_.TranslatePhysical(guest_index_base); + if (IsResetUsed(guest_indices, guest_draw_vertex_count, + guest_primitive_reset_index_guest_endian, + guest_index_mask_guest_endian)) { + cacheable.index_buffer_type = ProcessedIndexBufferType::kHostConverted; + auto host_indices = + reinterpret_cast(RequestHostConvertedIndexBufferForCurrentFrame( + xenos::IndexFormat::kInt32, guest_draw_vertex_count, true, guest_index_base, + cacheable.host_index_buffer_handle)); + if (!host_indices) { + return false; + } + if (full_32bit_vertex_indices_used_ || guest_index_endian == xenos::Endian::kNone) { + ReplaceResetIndex32To24( + host_indices, guest_indices, guest_draw_vertex_count, + guest_primitive_reset_index_guest_endian, guest_index_mask_guest_endian); + } else if (guest_index_endian == xenos::Endian::k8in16) { + ReplaceResetIndex32To24( + host_indices, guest_indices, guest_draw_vertex_count, + guest_primitive_reset_index_guest_endian, guest_index_mask_guest_endian); + } else if (guest_index_endian == xenos::Endian::k8in32) { + ReplaceResetIndex32To24( + host_indices, guest_indices, guest_draw_vertex_count, + guest_primitive_reset_index_guest_endian, guest_index_mask_guest_endian); + } else if (guest_index_endian == xenos::Endian::k16in32) { + ReplaceResetIndex32To24( + host_indices, guest_indices, guest_draw_vertex_count, + guest_primitive_reset_index_guest_endian, guest_index_mask_guest_endian); + } else { + assert_unhandled_case(guest_index_endian); + return false; + } + cacheable.host_shader_index_endian = + full_32bit_vertex_indices_used_ ? guest_index_endian : xenos::Endian::kNone; + } + cache_transaction.SetNewResult(cacheable); + } + } + } + + // For host vertex shader types that don't support manually reading 32-bit + // guest DMA indices in the shader path on some backends (notably Vulkan + // without fullDrawIndexUint32), pre-convert to host-endian 24-bit indices. + if (cacheable.index_buffer_type == ProcessedIndexBufferType::kGuestDMA && + guest_index_format == xenos::IndexFormat::kInt32 && !full_32bit_vertex_indices_used_ && + host_vertex_shader_type != Shader::HostVertexShaderType::kVertex) { + trace_writer_.WriteMemoryRead(guest_index_base, guest_index_buffer_needed_bytes); + // No primitive-type conversion, just index normalization. + CacheTransaction cache_transaction( + *this, CacheKey(guest_index_base, guest_draw_vertex_count, guest_index_format, + guest_index_endian, guest_primitive_reset_enabled, + xenos::PrimitiveType::kNone, true)); + if (cache_transaction.GetFoundResult()) { + cacheable = *cache_transaction.GetFoundResult(); + } else { + auto guest_indices = memory_.TranslatePhysical(guest_index_base); + auto host_indices = + reinterpret_cast(RequestHostConvertedIndexBufferForCurrentFrame( + xenos::IndexFormat::kInt32, guest_draw_vertex_count, true, guest_index_base, + cacheable.host_index_buffer_handle)); + if (!host_indices) { + return false; + } + for (uint32_t i = 0; i < guest_draw_vertex_count; ++i) { + host_indices[i] = + xenos::GpuSwap(guest_indices[i], guest_index_endian) & xenos::kVertexIndexMask; + } + cacheable.index_buffer_type = ProcessedIndexBufferType::kHostConverted; + cacheable.host_shader_index_endian = xenos::Endian::kNone; + cache_transaction.SetNewResult(cacheable); + } + } + } + } + + // Request the indices in the shared memory if they need to be accessed from + // there on the GPU. + if (cacheable.index_buffer_type == ProcessedIndexBufferType::kGuestDMA || + cacheable.index_buffer_type == ProcessedIndexBufferType::kHostBuiltinForDMA) { + // Request the index buffer memory. + // TODO(Triang3l): Shared memory request cache. + if (!shared_memory_.RequestRange(guest_index_base, guest_index_buffer_needed_bytes)) { + REXGPU_ERROR( + "PrimitiveProcessor: Failed to request index buffer 0x{:08X}, 0x{:X} " + "bytes needed, in the shared memory", + guest_index_base, guest_index_buffer_needed_bytes); + return false; + } + } + + result_out.guest_primitive_type = guest_primitive_type; + result_out.host_primitive_type = host_primitive_type; + result_out.host_vertex_shader_type = host_vertex_shader_type; + result_out.tessellation_mode = tessellation_mode; + result_out.guest_draw_vertex_count = guest_draw_vertex_count; + result_out.host_draw_vertex_count = cacheable.host_draw_vertex_count; + result_out.line_loop_closing_index = line_loop_closing_index; + result_out.index_buffer_type = cacheable.index_buffer_type; + result_out.guest_index_base = guest_index_base; + result_out.host_index_format = cacheable.host_index_format; + result_out.host_shader_index_endian = cacheable.host_shader_index_endian; + result_out.host_primitive_reset_enabled = cacheable.host_primitive_reset_enabled; + result_out.host_index_buffer_handle = cacheable.host_index_buffer_handle; + return true; +} + +bool PrimitiveProcessor::IsResetUsed(const uint16_t* source, uint32_t count, + uint16_t reset_index_guest_endian) { +#if XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE + while (count && + (reinterpret_cast(source) & (XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE - 1))) { + --count; + if (*(source++) == reset_index_guest_endian) { + return true; + } + } + if (count >= kSimdVectorU16Elements) { + SimdVectorU16 reset_index_guest_endian_simd = ReplicateU16(reset_index_guest_endian); + while (count >= kSimdVectorU16Elements) { + count -= kSimdVectorU16Elements; + SimdVectorU16 source_simd = LoadAlignedVectorU16(source); + source += kSimdVectorU16Elements; +#if REX_ARCH_AMD64 + if (_mm_movemask_epi8(_mm_cmpeq_epi16(source_simd, reset_index_guest_endian_simd))) { + return true; + } +#elif REX_ARCH_ARM64 + uint64x1_t is_any = vreinterpret_u64_u32( + vqmovn_u64(vreinterpretq_u64_u16(vceqq_u16(source_simd, reset_index_guest_endian_simd)))); + if (*reinterpret_cast(&is_any)) { + return true; + } +#else +#error SIMD 16-bit IsResetUsed not implemented. +#endif // XE_ARCH + } + } +#endif // XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE + while (count--) { + if (*(source++) == reset_index_guest_endian) { + return true; + } + } + return false; +} + +void PrimitiveProcessor::Get16BitResetIndexUsage(const uint16_t* source, uint32_t count, + uint16_t reset_index_guest_endian, + bool& is_reset_index_used_out, + bool& is_ffff_used_as_vertex_index_out) { + // Optimized for the more common case (reset index not used at all), therefore + // not doing early-outs if both conditions are true for a simpler loop body. + // Using the index 0xFFFF is likely not that common in general. + // TODO(Triang3l): Revisit this - maybe the early-out will be free if this + // function is bandwidth-bound. + is_ffff_used_as_vertex_index_out = false; + if (reset_index_guest_endian == UINT16_MAX) { + is_reset_index_used_out = IsResetUsed(source, count, reset_index_guest_endian); + return; + } + is_reset_index_used_out = false; +#if XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE + while (count && + (reinterpret_cast(source) & (XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE - 1))) { + --count; + uint16_t index = *(source++); + if (index == reset_index_guest_endian) { + is_reset_index_used_out = true; + } + if (index == UINT16_MAX) { + is_ffff_used_as_vertex_index_out = true; + } + } + if (count >= kSimdVectorU16Elements) { + SimdVectorU16 reset_index_guest_endian_simd = ReplicateU16(reset_index_guest_endian); + SimdVectorU16 ffff_simd = ReplicateU16(UINT16_MAX); + SimdVectorU16 is_reset_simd = ReplicateU16(0); + SimdVectorU16 is_ffff_simd = ReplicateU16(0); + while (count >= kSimdVectorU16Elements) { + count -= kSimdVectorU16Elements; + SimdVectorU16 source_simd = LoadAlignedVectorU16(source); + source += kSimdVectorU16Elements; +#if REX_ARCH_AMD64 + is_reset_simd = + _mm_or_si128(is_reset_simd, _mm_cmpeq_epi16(source_simd, reset_index_guest_endian_simd)); + is_ffff_simd = _mm_or_si128(is_ffff_simd, _mm_cmpeq_epi16(source_simd, ffff_simd)); +#elif REX_ARCH_ARM64 + is_reset_simd = + vorrq_u16(is_reset_simd, vceqq_u16(source_simd, reset_index_guest_endian_simd)); + is_ffff_simd = vmaxq_u16(is_ffff_simd, source_simd); +#else +#error SIMD Get16BitResetIndexUsage not implemented. +#endif // XE_ARCH + } +#if REX_ARCH_AMD64 + if (_mm_movemask_epi8(is_reset_simd)) { + is_reset_index_used_out = true; + } + if (_mm_movemask_epi8(is_ffff_simd)) { + is_ffff_used_as_vertex_index_out = true; + } +#elif REX_ARCH_ARM64 + uint64x1_t is_reset_any = + vreinterpret_u64_u32(vqmovn_u64(vreinterpretq_u64_u16(is_reset_simd))); + if (*reinterpret_cast(&is_reset_any)) { + is_reset_index_used_out = true; + } + uint64x1_t is_ffff_any = + vreinterpret_u64_u32(vqmovn_u64(vreinterpretq_u64_u16(vceqq_u16(is_ffff_simd, ffff_simd)))); + if (*reinterpret_cast(&is_ffff_any)) { + is_ffff_used_as_vertex_index_out = true; + } +#else +#error SIMD Get16BitResetIndexUsage not implemented. +#endif // XE_ARCH + } +#endif // XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE + while (count--) { + uint16_t index = *(source++); + if (index == reset_index_guest_endian) { + is_reset_index_used_out = true; + } + if (index == UINT16_MAX) { + is_ffff_used_as_vertex_index_out = true; + } + } +} + +bool PrimitiveProcessor::IsResetUsed(const uint32_t* source, uint32_t count, + uint32_t reset_index_guest_endian, + uint32_t low_bits_mask_guest_endian) { + // The Xbox 360's GPU only uses the low 24 bits of the index - masking before + // comparing. +#if XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE + while (count && + (reinterpret_cast(source) & (XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE - 1))) { + --count; + if ((*(source++) & low_bits_mask_guest_endian) == reset_index_guest_endian) { + return true; + } + } + if (count >= kSimdVectorU32Elements) { + SimdVectorU32 reset_index_guest_endian_simd = ReplicateU32(reset_index_guest_endian); + while (count >= kSimdVectorU32Elements) { + count -= kSimdVectorU32Elements; + SimdVectorU32 source_simd = LoadAlignedVectorU32(source); + source += kSimdVectorU32Elements; + SimdVectorU32 low_bits_mask_guest_endian_simd = ReplicateU32(low_bits_mask_guest_endian); +#if REX_ARCH_AMD64 + source_simd = _mm_and_si128(source_simd, low_bits_mask_guest_endian_simd); + if (_mm_movemask_epi8(_mm_cmpeq_epi32(source_simd, reset_index_guest_endian_simd))) { + return true; + } +#elif REX_ARCH_ARM64 + source_simd = vandq_u32(source_simd, low_bits_mask_guest_endian_simd); + uint64x1_t is_any = vreinterpret_u64_u32( + vqmovn_u64(vreinterpretq_u64_u32(vceqq_u32(source_simd, reset_index_guest_endian_simd)))); + if (*reinterpret_cast(&is_any)) { + return true; + } +#else +#error SIMD 32-bit IsResetUsed not implemented. +#endif // XE_ARCH + } + } +#endif // XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE + while (count--) { + if ((*(source++) & low_bits_mask_guest_endian) == reset_index_guest_endian) { + return true; + } + } + return false; +} + +void PrimitiveProcessor::ReplaceResetIndex16To16(uint16_t* dest, const uint16_t* source, + uint32_t count, + uint16_t reset_index_guest_endian) { +#if XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE + while (count && + (reinterpret_cast(source) & (XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE - 1))) { + --count; + uint16_t index = *(source++); + *(dest++) = index != reset_index_guest_endian ? index : UINT16_MAX; + } + if (count >= kSimdVectorU16Elements) { + SimdVectorU16 reset_index_guest_endian_simd = ReplicateU16(reset_index_guest_endian); + while (count >= kSimdVectorU16Elements) { + count -= kSimdVectorU16Elements; + // Comparison produces 0 or 0xFFFF on AVX and Neon - we need 0xFFFF as the + // result for the primitive reset indices, so the result is + // `index | (index == reset_index)`. + SimdVectorU16 source_simd = LoadAlignedVectorU16(source); + source += kSimdVectorU16Elements; + SimdVectorU16 result_simd; +#if REX_ARCH_AMD64 + result_simd = + _mm_or_si128(source_simd, _mm_cmpeq_epi16(source_simd, reset_index_guest_endian_simd)); +#elif REX_ARCH_ARM64 + result_simd = vorrq_u16(source_simd, vceqq_u16(source_simd, reset_index_guest_endian_simd)); +#else +#error SIMD ReplaceResetIndex16To16 not implemented. +#endif // XE_ARCH + StoreUnalignedVectorU16(dest, result_simd); + dest += kSimdVectorU16Elements; + } + } +#endif // XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE + while (count--) { + uint16_t index = *(source++); + *(dest++) = index != reset_index_guest_endian ? index : UINT16_MAX; + } +} + +void PrimitiveProcessor::ReplaceResetIndex16To24(uint32_t* dest, const uint16_t* source, + uint32_t count, + uint16_t reset_index_guest_endian) { +#if XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE + while (count && + (reinterpret_cast(source) & (XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE - 1))) { + --count; + uint16_t index = *(source++); + *(dest++) = index != reset_index_guest_endian ? index : UINT32_MAX; + } + if (count >= kSimdVectorU16Elements) { + SimdVectorU16 reset_index_guest_endian_simd = ReplicateU16(reset_index_guest_endian); + while (count >= kSimdVectorU16Elements) { + count -= kSimdVectorU16Elements; + SimdVectorU16 source_simd = LoadAlignedVectorU16(source); + source += kSimdVectorU16Elements; + // 1) Compare to the reset index as uint16, getting 0 or 0xFFFF. + // 2) For primitive reset indices, replace the lower 16 bits with 0xFFFF + // via OR with the comparison result. + // 3) Expand to 32-bit, putting 0xFFFF in the upper 16 bits where + // the comparison has passed, creating 0xFFFFFFFF for primitive reset + // or 0x0000#### for non-primitive-reset indices (including + // 0x0000FFFF if the original index buffer had 0xFFFF, but the + // primitive reset index is different). + // 4) Store. +#if REX_ARCH_AMD64 + __m128i are_reset = _mm_cmpeq_epi16(source_simd, reset_index_guest_endian_simd); + __m128i result = _mm_or_si128(source_simd, are_reset); + StoreUnalignedVectorU32(dest, _mm_unpacklo_epi16(result, are_reset)); + // Expecting kSimdVectorU16Elements / 2 to be in the immediate offset + // part of the address. + StoreUnalignedVectorU32(dest + kSimdVectorU16Elements / 2, + _mm_unpackhi_epi16(result, are_reset)); +#elif REX_ARCH_ARM64 + // Interleaving the indices and 0 / 0xFFFF via st2. + uint16x8x2_t result; + result.val[1] = vceqq_u16(source_simd, reset_index_guest_endian_simd); + result.val[0] = vorrq_u16(source_simd, result.val[1]); + vst2q_u16(reinterpret_cast(dest), result); +#else +#error SIMD ReplaceResetIndex16To24 not implemented. +#endif // XE_ARCH + dest += kSimdVectorU16Elements; + } + } +#endif // XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE + while (count--) { + uint16_t index = *(source++); + *(dest++) = index != reset_index_guest_endian ? index : UINT32_MAX; + } +} + +template void PrimitiveProcessor::ReplaceResetIndex32To24( + uint32_t* dest, const uint32_t* source, uint32_t count, uint32_t reset_index_guest_endian, + uint32_t low_bits_mask_guest_endian); +template void PrimitiveProcessor::ReplaceResetIndex32To24( + uint32_t* dest, const uint32_t* source, uint32_t count, uint32_t reset_index_guest_endian, + uint32_t low_bits_mask_guest_endian); +template void PrimitiveProcessor::ReplaceResetIndex32To24( + uint32_t* dest, const uint32_t* source, uint32_t count, uint32_t reset_index_guest_endian, + uint32_t low_bits_mask_guest_endian); +template void PrimitiveProcessor::ReplaceResetIndex32To24( + uint32_t* dest, const uint32_t* source, uint32_t count, uint32_t reset_index_guest_endian, + uint32_t low_bits_mask_guest_endian); + +#define XE_GPU_PRIMITIVE_PROCESSOR_INSTANTIATE_CONVERSION_NO_PASSTHROUGH(ConverterName) \ + template void PrimitiveProcessor::ConverterName( \ + uint32_t* dest, const uint32_t* source, uint32_t source_index_count, \ + const To24NonSwappingIndexTransform& index_transform); \ + template void PrimitiveProcessor::ConverterName( \ + uint32_t* dest, const uint32_t* source, uint32_t source_index_count, \ + const To24Swapping8In16IndexTransform& index_transform); \ + template void PrimitiveProcessor::ConverterName( \ + uint32_t* dest, const uint32_t* source, uint32_t source_index_count, \ + const To24Swapping8In32IndexTransform& index_transform); \ + template void PrimitiveProcessor::ConverterName( \ + uint32_t* dest, const uint32_t* source, uint32_t source_index_count, \ + const To24Swapping16In32IndexTransform& index_transform); +#define XE_GPU_PRIMITIVE_PROCESSOR_INSTANTIATE_CONVERSION(ConverterName) \ + template void PrimitiveProcessor::ConverterName( \ + uint16_t* dest, const uint16_t* source, uint32_t source_index_count, \ + const PassthroughIndexTransform& index_transform); \ + template void PrimitiveProcessor::ConverterName( \ + uint32_t* dest, const uint32_t* source, uint32_t source_index_count, \ + const PassthroughIndexTransform& index_transform); \ + XE_GPU_PRIMITIVE_PROCESSOR_INSTANTIATE_CONVERSION_NO_PASSTHROUGH(ConverterName) +XE_GPU_PRIMITIVE_PROCESSOR_INSTANTIATE_CONVERSION(TriangleFanToList) +XE_GPU_PRIMITIVE_PROCESSOR_INSTANTIATE_CONVERSION_NO_PASSTHROUGH(LineLoopToStrip) +// TODO(Triang3l): SIMD quad conversion maybe - 2 vectors to 3 vectors (though +// multiple quads are rarely drawn anyway). +XE_GPU_PRIMITIVE_PROCESSOR_INSTANTIATE_CONVERSION(QuadListToTriangleList) +#undef XE_GPU_PRIMITIVE_PROCESSOR_INSTANTIATE_CONVERSION_NO_PASSTHROUGH +#undef XE_GPU_PRIMITIVE_PROCESSOR_INSTANTIATE_CONVERSION + +void PrimitiveProcessor::LineLoopToStrip(uint16_t* dest, const uint16_t* source, + uint32_t source_index_count, + const PassthroughIndexTransform& index_transform) { + if (source_index_count <= 1) { + // To match GetLineLoopStripIndexCount. + return; + } + std::memcpy(dest, source, sizeof(*source) * source_index_count); + dest[source_index_count] = source[0]; +} +void PrimitiveProcessor::LineLoopToStrip(uint32_t* dest, const uint32_t* source, + uint32_t source_index_count, + const PassthroughIndexTransform& index_transform) { + if (source_index_count <= 1) { + // To match GetLineLoopStripIndexCount. + return; + } + std::memcpy(dest, source, sizeof(*source) * source_index_count); + dest[source_index_count] = source[0]; +} + +uint32_t PrimitiveProcessor::GetMultiPrimitiveHostIndexCountAndRanges( + std::function single_primitive_guest_to_host_count, const uint16_t* source, + uint32_t source_index_count, uint16_t reset_index_guest_endian, + std::deque& ranges_append_out) { + uint32_t host_total_index_count = 0; + uint32_t guest_index_offset = 0; + for (;;) { + uint32_t guest_primitive_offset = guest_index_offset; + while (guest_index_offset < source_index_count) { + if (source[guest_index_offset] == reset_index_guest_endian) { + break; + } + ++guest_index_offset; + } + // Reset encountered or end of the index buffer - add the range. + uint32_t guest_primitive_index_count = guest_index_offset - guest_primitive_offset; + uint32_t host_primitive_index_count = + single_primitive_guest_to_host_count(guest_primitive_index_count); + if (host_primitive_index_count) { + ranges_append_out.emplace_back(guest_primitive_offset, guest_primitive_index_count, + host_primitive_index_count); + host_total_index_count += host_primitive_index_count; + } + if (guest_index_offset >= source_index_count) { + // End of the index buffer. + break; + } + // Reset index encountered - skip. + ++guest_index_offset; + } + return host_total_index_count; +} + +uint32_t PrimitiveProcessor::GetMultiPrimitiveHostIndexCountAndRanges( + std::function single_primitive_guest_to_host_count, const uint32_t* source, + uint32_t source_index_count, uint32_t reset_index_guest_endian, + uint32_t low_bits_mask_guest_endian, std::deque& ranges_append_out) { + uint32_t host_total_index_count = 0; + uint32_t guest_index_offset = 0; + for (;;) { + uint32_t guest_primitive_offset = guest_index_offset; + while (guest_index_offset < source_index_count) { + if ((source[guest_index_offset] & low_bits_mask_guest_endian) == reset_index_guest_endian) { + break; + } + ++guest_index_offset; + } + // Reset encountered or end of the index buffer - add the range. + uint32_t guest_primitive_index_count = guest_index_offset - guest_primitive_offset; + uint32_t host_primitive_index_count = + single_primitive_guest_to_host_count(guest_primitive_index_count); + if (host_primitive_index_count) { + ranges_append_out.emplace_back(guest_primitive_offset, guest_primitive_index_count, + host_primitive_index_count); + host_total_index_count += host_primitive_index_count; + } + if (guest_index_offset >= source_index_count) { + // End of the index buffer. + break; + } + // Reset index encountered - skip. + ++guest_index_offset; + } + return host_total_index_count; +} + +PrimitiveProcessor::CacheTransaction::CacheTransaction(PrimitiveProcessor& processor, CacheKey key) + : processor_(processor), key_(key) { + assert_zero(processor_.cache_currently_processing_size_bytes_); + if (REXCVAR_GET(primitive_processor_cache_min_indices) < 0 || + key_.count < uint32_t(REXCVAR_GET(primitive_processor_cache_min_indices))) { + // Don't cache if the vertex count is too small. + key_.key = 0; + } + if (!key_.count) { + return; + } + uint32_t size_bytes = + (key_.format == xenos::IndexFormat::kInt16 ? sizeof(uint16_t) : sizeof(uint32_t)) * + key_.count; + { + std::lock_guard cache_lock(processor_.cache_mutex_); + auto cache_map_it = processor_.cache_map_.find(key_); + if (cache_map_it != processor_.cache_map_.end()) { + result_ = processor_.cache_entry_pool_[cache_map_it->second].result; + result_type_ = ResultType::kExisting; + } else { + // Inhibit writing the new result if the range happens to be modified + // during the processing outside the lock. + processor_.cache_currently_processing_base_ = key_.base; + processor_.cache_currently_processing_size_bytes_ = size_bytes; + } + } + if (result_type_ != ResultType::kExisting) { + // Enable the invalidation callback before reading the indices. + // Also, only enable invalidation callbacks if anything needed processing at + // all - don't waste time in the access violation handler doing nothing if + // the guest doesn't use anything requiring host conversion. + if (!processor_.memory_invalidation_callback_handle_) { + processor_.memory_invalidation_callback_handle_ = + processor_.memory_.RegisterPhysicalMemoryInvalidationCallback( + MemoryInvalidationCallbackThunk, &processor_); + } + processor_.memory_.EnablePhysicalMemoryAccessCallbacks(key_.base, size_bytes, true, false); + } +} + +PrimitiveProcessor::CacheTransaction::~CacheTransaction() { + if (!key_.count || result_type_ == ResultType::kExisting) { + return; + } + + std::lock_guard cache_lock(processor_.cache_mutex_); + + processor_.cache_currently_processing_base_ = 0; + processor_.cache_currently_processing_size_bytes_ = 0; + + if (result_type_ == ResultType::kNewSet) { + size_t new_entry_index; + if (processor_.cache_bucket_free_first_entry_ != SIZE_MAX) { + new_entry_index = processor_.cache_bucket_free_first_entry_; + processor_.cache_bucket_free_first_entry_ = + processor_.cache_entry_pool_[new_entry_index].free_next; + } else { + new_entry_index = processor_.cache_entry_pool_.size(); + processor_.cache_entry_pool_.emplace_back(); + } + CacheEntry& new_entry = processor_.cache_entry_pool_[new_entry_index]; + + // Put the entry in 1 or 2 buckets. + uint32_t bucket_start_index = key_.base >> kCacheBucketSizeBytesLog2; + uint32_t bucket_count = CacheEntry::GetBucketCount(key_); + for (uint32_t link_index = 0; link_index < bucket_count; ++link_index) { + new_entry.buckets_prev[link_index] = SIZE_MAX; + uint32_t bucket_index = bucket_start_index + link_index; + uint64_t& bucket_non_empty_l1_ref = processor_.cache_buckets_non_empty_l1_[bucket_index >> 6]; + uint64_t bucket_non_empty_l1_bit = uint64_t(1) << (bucket_index & 63); + size_t& bucket_first_entry_ref = processor_.cache_bucket_first_entries_[bucket_index]; + if (bucket_non_empty_l1_ref & bucket_non_empty_l1_bit) { + // There is at least one entry already in the bucket - link to the + // first. + new_entry.buckets_next[link_index] = bucket_first_entry_ref; + CacheEntry& bucket_first_entry = processor_.cache_entry_pool_[bucket_first_entry_ref]; + // If the start ([0]) bucket of bucket_first_entry is bucket_index, + // update its link [0]. Otherwise, since a cache entry may belong only + // to at most 2 buckets, bucket_index must be its [1] bucket. + bucket_first_entry.buckets_prev[size_t( + (bucket_first_entry.key.base >> kCacheBucketSizeBytesLog2) != bucket_index)] = + new_entry_index; + } else { + new_entry.buckets_next[link_index] = SIZE_MAX; + bucket_non_empty_l1_ref |= bucket_non_empty_l1_bit; + processor_.UpdateCacheBucketsNonEmptyL2(bucket_index >> 6, cache_lock); + } + bucket_first_entry_ref = new_entry_index; + } + + new_entry.key = key_; + new_entry.result = result_; + + processor_.cache_map_.emplace(key_, new_entry_index); + } +} + +std::pair PrimitiveProcessor::MemoryInvalidationCallback( + uint32_t physical_address_start, uint32_t length, bool exact_range) { + if (length == 0 || physical_address_start >= SharedMemory::kBufferSize) { + return std::make_pair(uint32_t(0), UINT32_MAX); + } + length = std::min(length, SharedMemory::kBufferSize - physical_address_start); + uint32_t physical_address_end = physical_address_start + length; + if (!exact_range) { + // Invalidate entire buckets if this is an access callback rather than + // something like a file read to disable access violation handling for a + // bigger range for higher performance. + physical_address_start &= ~(kCacheBucketSizeBytes - 1); + physical_address_end = rex::align(physical_address_end, kCacheBucketSizeBytes); + } + bool any_invalidated = false; + uint32_t bucket_index_first = physical_address_start >> kCacheBucketSizeBytesLog2; + uint32_t bucket_index_last = (physical_address_end - 1) >> kCacheBucketSizeBytesLog2; + uint32_t bucket_l1_bits_index_first = bucket_index_first >> 6; + uint32_t bucket_l1_bits_index_last = bucket_index_last >> 6; + uint32_t bucket_l2_bits_index_first = bucket_index_first >> 12; + uint32_t bucket_l2_bits_index_last = bucket_index_last >> 12; + std::lock_guard cache_lock(cache_mutex_); + for (uint32_t bucket_l2_bits_index = bucket_l2_bits_index_first; + bucket_l2_bits_index <= bucket_l2_bits_index_last; ++bucket_l2_bits_index) { + uint64_t bucket_l2_bits_mask = UINT64_MAX; + if (bucket_l2_bits_index == bucket_l2_bits_index_first) { + bucket_l2_bits_mask &= ~((uint64_t(1) << (bucket_l1_bits_index_first & 63)) - 1); + } + if (bucket_l2_bits_index == bucket_l2_bits_index_last && + (bucket_l1_bits_index_last & 63) != 63) { + bucket_l2_bits_mask &= (uint64_t(1) << ((bucket_l1_bits_index_last & 63) + 1)) - 1; + } + // Not caching L2 bits because they may be modified by unlinking. + // Loop until any bits in the 64-bit portion of the L2 bit set are left. + while (bucket_l2_bits_mask) { + uint32_t bucket_l2_bit_shift; + if (!rex::bit_scan_forward( + cache_buckets_non_empty_l2_[bucket_l2_bits_index] & bucket_l2_bits_mask, + &bucket_l2_bit_shift)) { + break; + } + bucket_l2_bits_mask &= ~(uint64_t(1) << bucket_l2_bit_shift); + uint32_t bucket_l1_bits_index = (bucket_l2_bits_index << 6) | bucket_l2_bit_shift; + uint64_t bucket_l1_bits_mask = UINT64_MAX; + if (bucket_l1_bits_index == bucket_l1_bits_index_first) { + bucket_l1_bits_mask &= ~((uint64_t(1) << (bucket_index_first & 63)) - 1); + } + if (bucket_l1_bits_index == bucket_l1_bits_index_last && (bucket_index_last & 63) != 63) { + bucket_l1_bits_mask &= (uint64_t(1) << ((bucket_index_last & 63) + 1)) - 1; + } + // Not caching L1 bits because they may be modified by unlinking. + // Loop over buckets until any bits in the 64-bit portion of the L1 bit + // set are left. + while (bucket_l1_bits_mask) { + uint32_t bucket_l1_bit_shift; + if (!rex::bit_scan_forward( + cache_buckets_non_empty_l1_[bucket_l1_bits_index] & bucket_l1_bits_mask, + &bucket_l1_bit_shift)) { + break; + } + bucket_l1_bits_mask &= ~(uint64_t(1) << bucket_l1_bit_shift); + uint32_t bucket_index = (bucket_l1_bits_index << 6) | bucket_l1_bit_shift; + // Invalidate the entries in the bucket, fully or partially. + size_t entry_index = cache_bucket_first_entries_[bucket_index]; + do { + CacheEntry& entry = cache_entry_pool_[entry_index]; + CacheKey entry_key = entry.key; + // If the start ([0]) bucket of the entry is bucket_index, the link + // within this bucket is its link [0]. Otherwise, since a cache entry + // may belong only to at most 2 buckets, bucket_index must be its [1] + // bucket. + uint32_t entry_bucket_index_first = entry_key.base >> kCacheBucketSizeBytesLog2; + assert_true((bucket_index - entry_bucket_index_first) <= 1, + "Cache entries only store list links within two buckets"); + size_t next_entry_index = entry.buckets_next[bucket_index - entry_bucket_index_first]; + // For exact_range, don't invalidate bucket entries that are outside + // the specified range. + if (entry_key.base < physical_address_end) { + uint32_t entry_end = entry_key.base + entry_key.GetSizeBytes(); + if (entry_end > physical_address_end) { + // Invalidate the entry. + any_invalidated = true; + // Remove the entry from the cache map. + auto entry_map_it = cache_map_.find(entry_key); + assert_true(entry_map_it != cache_map_.end()); + if (entry_map_it != cache_map_.end()) { + cache_map_.erase(entry_map_it); + } + // Unlink the entry from the bucket's list. + uint32_t entry_link_index_last = + ((entry_end - 1) >> kCacheBucketSizeBytesLog2) - entry_bucket_index_first; + assert_true(entry_link_index_last <= 1, + "Cache entries only store list links within two buckets"); + for (uint32_t entry_link_index = 0; entry_link_index <= entry_link_index_last; + ++entry_link_index) { + uint32_t entry_bucket_index = entry_bucket_index_first + entry_link_index; + size_t entry_link_prev = entry.buckets_prev[entry_link_index]; + size_t entry_link_next = entry.buckets_next[entry_link_index]; + if (entry_link_prev != SIZE_MAX) { + CacheEntry& entry_prev = cache_entry_pool_[entry_link_prev]; + entry_prev.buckets_next[size_t( + (entry_prev.key.base >> kCacheBucketSizeBytesLog2) != entry_bucket_index)] = + entry_link_next; + } else { + if (entry_link_next != SIZE_MAX) { + cache_bucket_first_entries_[entry_bucket_index] = entry_link_next; + } else { + // The only entry that was remaining in the bucket - it's + // empty now. + cache_buckets_non_empty_l1_[entry_bucket_index >> 6] &= + ~(uint64_t(1) << (entry_bucket_index & 63)); + UpdateCacheBucketsNonEmptyL2(entry_bucket_index >> 6, cache_lock); + } + } + if (entry_link_next != SIZE_MAX) { + CacheEntry& entry_next = cache_entry_pool_[entry_link_next]; + entry_next.buckets_prev[size_t( + (entry_next.key.base >> kCacheBucketSizeBytesLog2) != entry_bucket_index)] = + entry_link_prev; + } + } + // Make the entry free for reuse. + entry.free_next = cache_bucket_free_first_entry_; + cache_bucket_free_first_entry_ = entry_index; + } + } + entry_index = next_entry_index; + } while (entry_index != SIZE_MAX); + } + } + } + return any_invalidated + ? std::make_pair(physical_address_start, physical_address_end - physical_address_start) + : std::make_pair(uint32_t(0), UINT32_MAX); +} + +std::pair PrimitiveProcessor::MemoryInvalidationCallbackThunk( + void* context_ptr, uint32_t physical_address_start, uint32_t length, bool exact_range) { + return reinterpret_cast(context_ptr) + ->MemoryInvalidationCallback(physical_address_start, length, exact_range); +} + +} // namespace rex::graphics diff --git a/src/graphics/register_file.cpp b/src/graphics/register_file.cpp new file mode 100644 index 0000000..03ce18c --- /dev/null +++ b/src/graphics/register_file.cpp @@ -0,0 +1,40 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include + +namespace rex::graphics { + +RegisterFile::RegisterFile() { + std::memset(values, 0, sizeof(values)); +} + +const RegisterInfo* RegisterFile::GetRegisterInfo(uint32_t index) { + switch (index) { +#define XE_GPU_REGISTER(index, type, name) \ + case index: { \ + static const RegisterInfo reg_info = { \ + RegisterInfo::Type::type, \ + #name, \ + }; \ + return ®_info; \ + } +#include +#undef XE_GPU_REGISTER + default: + return nullptr; + } +} + +} // namespace rex::graphics diff --git a/src/graphics/registers.cpp b/src/graphics/registers.cpp new file mode 100644 index 0000000..e39088b --- /dev/null +++ b/src/graphics/registers.cpp @@ -0,0 +1,32 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2019 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +namespace rex::graphics { +namespace reg { + +const Register RB_COLOR_INFO::rt_register_indices[4] = { + XE_GPU_REG_RB_COLOR_INFO, + XE_GPU_REG_RB_COLOR1_INFO, + XE_GPU_REG_RB_COLOR2_INFO, + XE_GPU_REG_RB_COLOR3_INFO, +}; + +const Register RB_BLENDCONTROL::rt_register_indices[4] = { + XE_GPU_REG_RB_BLENDCONTROL0, + XE_GPU_REG_RB_BLENDCONTROL1, + XE_GPU_REG_RB_BLENDCONTROL2, + XE_GPU_REG_RB_BLENDCONTROL3, +}; + +} // namespace reg +} // namespace rex::graphics diff --git a/src/graphics/sampler_info.cpp b/src/graphics/sampler_info.cpp new file mode 100644 index 0000000..2d0c707 --- /dev/null +++ b/src/graphics/sampler_info.cpp @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include + +namespace rex::graphics { + +bool SamplerInfo::Prepare(const xenos::xe_gpu_texture_fetch_t& fetch, + const ParsedTextureFetchInstruction& fetch_instr, SamplerInfo* out_info) { + std::memset(out_info, 0, sizeof(SamplerInfo)); + + out_info->min_filter = fetch_instr.attributes.min_filter == xenos::TextureFilter::kUseFetchConst + ? fetch.min_filter + : fetch_instr.attributes.min_filter; + out_info->mag_filter = fetch_instr.attributes.mag_filter == xenos::TextureFilter::kUseFetchConst + ? fetch.mag_filter + : fetch_instr.attributes.mag_filter; + out_info->mip_filter = fetch_instr.attributes.mip_filter == xenos::TextureFilter::kUseFetchConst + ? fetch.mip_filter + : fetch_instr.attributes.mip_filter; + out_info->clamp_u = fetch.clamp_x; + out_info->clamp_v = fetch.clamp_y; + out_info->clamp_w = fetch.clamp_z; + out_info->aniso_filter = fetch_instr.attributes.aniso_filter == xenos::AnisoFilter::kUseFetchConst + ? fetch.aniso_filter + : fetch_instr.attributes.aniso_filter; + + out_info->border_color = fetch.border_color; + out_info->lod_bias = (fetch.lod_bias) / 32.f; + out_info->mip_min_level = fetch.mip_min_level; + out_info->mip_max_level = fetch.mip_max_level; + + return true; +} + +uint64_t SamplerInfo::hash() const { + return XXH3_64bits(this, sizeof(SamplerInfo)); +} + +} // namespace rex::graphics diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/adaptive_quad_hs.h b/src/graphics/shaders/bytecode/d3d12_5_1/adaptive_quad_hs.h new file mode 100644 index 0000000..17d193c --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/adaptive_quad_hs.h @@ -0,0 +1,343 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer xe_system_cbuffer +// { +// +// uint xe_flags; // Offset: 0 Size: 4 [unused] +// float2 xe_tessellation_factor_range;// Offset: 4 Size: 8 [unused] +// uint xe_line_loop_closing_index; // Offset: 12 Size: 4 [unused] +// uint xe_vertex_index_endian; // Offset: 16 Size: 4 [unused] +// uint xe_vertex_index_offset; // Offset: 20 Size: 4 +// uint2 xe_vertex_index_min_max; // Offset: 24 Size: 8 +// float4 xe_user_clip_planes[6]; // Offset: 32 Size: 96 [unused] +// float3 xe_ndc_scale; // Offset: 128 Size: 12 [unused] +// float xe_point_vertex_diameter_min;// Offset: 140 Size: 4 [unused] +// float3 xe_ndc_offset; // Offset: 144 Size: 12 [unused] +// float xe_point_vertex_diameter_max;// Offset: 156 Size: 4 [unused] +// float2 xe_point_constant_diameter; // Offset: 160 Size: 8 [unused] +// float2 xe_point_screen_diameter_to_ndc_radius;// Offset: 168 Size: 8 [unused] +// uint4 xe_texture_swizzled_signs[2];// Offset: 176 Size: 32 [unused] +// uint xe_textures_resolved; // Offset: 208 Size: 4 [unused] +// uint2 xe_sample_count_log2; // Offset: 212 Size: 8 [unused] +// float xe_alpha_test_reference; // Offset: 220 Size: 4 [unused] +// uint xe_alpha_to_mask; // Offset: 224 Size: 4 [unused] +// uint xe_edram_32bpp_tile_pitch_dwords_scaled;// Offset: 228 Size: 4 [unused] +// uint xe_edram_depth_base_dwords_scaled;// Offset: 232 Size: 4 [unused] +// float4 xe_color_exp_bias; // Offset: 240 Size: 16 [unused] +// float2 xe_edram_poly_offset_front; // Offset: 256 Size: 8 [unused] +// float2 xe_edram_poly_offset_back; // Offset: 264 Size: 8 [unused] +// uint4 xe_edram_stencil[2]; // Offset: 272 Size: 32 [unused] +// uint4 xe_edram_rt_base_dwords_scaled;// Offset: 304 Size: 16 [unused] +// uint4 xe_edram_rt_format_flags; // Offset: 320 Size: 16 [unused] +// float4 xe_edram_rt_clamp[4]; // Offset: 336 Size: 64 [unused] +// uint4 xe_edram_rt_keep_mask[2]; // Offset: 400 Size: 32 [unused] +// uint4 xe_edram_rt_blend_factors_ops;// Offset: 432 Size: 16 [unused] +// float4 xe_edram_blend_constant; // Offset: 448 Size: 16 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_system_cbuffer cbuffer NA NA CB0 cb0 1 +// +// +// +// Patch Constant signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TessFactor 0 x 0 QUADEDGE float x +// SV_TessFactor 1 x 1 QUADEDGE float x +// SV_TessFactor 2 x 2 QUADEDGE float x +// SV_TessFactor 3 x 3 QUADEDGE float x +// SV_InsideTessFactor 0 x 4 QUADINT float x +// SV_InsideTessFactor 1 x 5 QUADINT float x +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XETESSFACTOR 0 x 0 NONE float x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE float x +// +// Tessellation Domain # of control points +// -------------------- -------------------- +// Quadrilateral 1 +// +// Tessellation Output Primitive Partitioning Type +// ------------------------------ ------------------ +// Clockwise Triangles Even Fractional +// +hs_5_1 +hs_decls +dcl_input_control_point_count 4 +dcl_output_control_point_count 1 +dcl_tessellator_domain domain_quad +dcl_tessellator_partitioning partitioning_fractional_even +dcl_tessellator_output_primitive output_triangle_cw +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][2], immediateIndexed, space=0 +hs_control_point_phase +dcl_input vPrim +dcl_output o0.x +dcl_temps 1 +iadd r0.x, vPrim, CB0[0][1].y +and r0.x, r0.x, l(0x00ffffff) +umax r0.x, r0.x, CB0[0][1].z +umin r0.x, r0.x, CB0[0][1].w +utof o0.x, r0.x +ret +hs_fork_phase +dcl_hs_fork_phase_instance_count 4 +dcl_input vForkInstanceID +dcl_input vicp[4][0].x +dcl_output_siv o0.x, finalQuadUeq0EdgeTessFactor +dcl_output_siv o1.x, finalQuadVeq0EdgeTessFactor +dcl_output_siv o2.x, finalQuadUeq1EdgeTessFactor +dcl_output_siv o3.x, finalQuadVeq1EdgeTessFactor +dcl_temps 1 +dcl_indexrange o0.x 4 +iadd r0.x, vForkInstanceID.x, l(3) +and r0.x, r0.x, l(3) +mov r0.y, vForkInstanceID.x +mov o[r0.y + 0].x, vicp[r0.x + 0][0].x +ret +hs_fork_phase +dcl_hs_fork_phase_instance_count 2 +dcl_input vForkInstanceID +dcl_input vicp[4][0].x +dcl_output_siv o4.x, finalQuadUInsideTessFactor +dcl_output_siv o5.x, finalQuadVInsideTessFactor +dcl_temps 1 +dcl_indexrange o4.x 2 +ult r0.x, vForkInstanceID.x, l(1) +movc r0.x, r0.x, l(0), l(3) +ineg r0.y, vForkInstanceID.x +min r0.x, vicp[r0.y + 2][0].x, vicp[r0.x + 0][0].x +mov r0.y, vForkInstanceID.x +mov o[r0.y + 4].x, r0.x +ret +// Approximately 18 instruction slots used +#endif + +const BYTE adaptive_quad_hs[] = { + 68, 88, 66, 67, 239, 150, 141, 161, 148, 167, 208, 252, 147, 2, 216, 119, 8, 207, 171, + 137, 1, 0, 0, 0, 40, 15, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 108, 10, + 0, 0, 164, 10, 0, 0, 216, 10, 0, 0, 156, 11, 0, 0, 140, 14, 0, 0, 82, + 68, 69, 70, 44, 10, 0, 0, 1, 0, 0, 0, 120, 0, 0, 0, 1, 0, 0, 0, + 60, 0, 0, 0, 1, 5, 83, 72, 0, 5, 0, 0, 2, 10, 0, 0, 19, 19, 68, + 37, 60, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 115, 121, 115, 116, + 101, 109, 95, 99, 98, 117, 102, 102, 101, 114, 0, 171, 171, 100, 0, 0, 0, 30, 0, + 0, 0, 144, 0, 0, 0, 208, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, + 5, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 116, 5, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, 5, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 188, 5, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 215, 5, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 238, 5, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 5, 6, 0, 0, 24, 0, 0, 0, 8, 0, + 0, 0, 2, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 72, 6, 0, 0, 32, 0, 0, 0, + 96, 0, 0, 0, 0, 0, 0, 0, 100, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 136, 6, 0, 0, 128, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 6, 0, 0, + 140, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 8, 7, + 0, 0, 144, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 22, 7, 0, 0, 156, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 51, 7, 0, 0, 160, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, + 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 78, 7, 0, 0, 168, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 117, 7, 0, 0, 176, 0, 0, 0, 32, 0, 0, 0, 0, + 0, 0, 0, 152, 7, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 188, 7, 0, 0, 208, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 209, 7, 0, 0, 212, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 230, 7, 0, 0, 220, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 254, 7, 0, 0, 224, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 8, 0, + 0, 228, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 55, + 8, 0, 0, 232, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 89, 8, 0, 0, 240, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 144, 8, 0, 0, 0, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 171, 8, 0, 0, 8, 1, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 197, 8, 0, 0, 16, 1, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 216, 8, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 252, 8, 0, 0, 48, 1, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 64, 9, 0, 0, 64, 1, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 89, 9, 0, 0, 80, 1, + 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 108, 9, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 144, 9, 0, 0, + 144, 1, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 168, 9, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 204, 9, + 0, 0, 176, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 234, 9, 0, 0, 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 120, 101, 95, 102, 108, 97, 103, 115, 0, 100, 119, 111, 114, 100, 0, 171, 0, + 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 5, 0, 0, 120, 101, 95, + 116, 101, 115, 115, 101, 108, 108, 97, 116, 105, 111, 110, 95, 102, 97, 99, 116, 111, 114, + 95, 114, 97, 110, 103, 101, 0, 102, 108, 111, 97, 116, 50, 0, 1, 0, 3, 0, 1, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 145, 5, 0, 0, 120, 101, 95, 108, 105, 110, 101, + 95, 108, 111, 111, 112, 95, 99, 108, 111, 115, 105, 110, 103, 95, 105, 110, 100, 101, 120, + 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, 120, 95, 101, 110, + 100, 105, 97, 110, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, + 120, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, + 105, 110, 100, 101, 120, 95, 109, 105, 110, 95, 109, 97, 120, 0, 117, 105, 110, 116, 50, + 0, 171, 1, 0, 19, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 6, 0, 0, + 120, 101, 95, 117, 115, 101, 114, 95, 99, 108, 105, 112, 95, 112, 108, 97, 110, 101, 115, + 0, 102, 108, 111, 97, 116, 52, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 110, 100, 99, 95, 115, 99, 97, 108, 101, + 0, 102, 108, 111, 97, 116, 51, 0, 1, 0, 3, 0, 1, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 149, 6, 0, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, + 101, 120, 95, 100, 105, 97, 109, 101, 116, 101, 114, 95, 109, 105, 110, 0, 102, 108, 111, + 97, 116, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 6, + 0, 0, 120, 101, 95, 110, 100, 99, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, 101, 120, 95, 100, 105, 97, 109, 101, 116, + 101, 114, 95, 109, 97, 120, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 99, 111, 110, + 115, 116, 97, 110, 116, 95, 100, 105, 97, 109, 101, 116, 101, 114, 0, 120, 101, 95, 112, + 111, 105, 110, 116, 95, 115, 99, 114, 101, 101, 110, 95, 100, 105, 97, 109, 101, 116, 101, + 114, 95, 116, 111, 95, 110, 100, 99, 95, 114, 97, 100, 105, 117, 115, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 115, 119, 105, 122, 122, 108, 101, 100, 95, 115, 105, + 103, 110, 115, 0, 117, 105, 110, 116, 52, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, + 4, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, + 114, 101, 115, 95, 114, 101, 115, 111, 108, 118, 101, 100, 0, 120, 101, 95, 115, 97, 109, + 112, 108, 101, 95, 99, 111, 117, 110, 116, 95, 108, 111, 103, 50, 0, 120, 101, 95, 97, + 108, 112, 104, 97, 95, 116, 101, 115, 116, 95, 114, 101, 102, 101, 114, 101, 110, 99, 101, + 0, 120, 101, 95, 97, 108, 112, 104, 97, 95, 116, 111, 95, 109, 97, 115, 107, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 51, 50, 98, 112, 112, 95, 116, 105, 108, 101, 95, + 112, 105, 116, 99, 104, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 100, 101, 112, 116, 104, 95, 98, 97, 115, + 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, 0, 120, 101, 95, + 99, 111, 108, 111, 114, 95, 101, 120, 112, 95, 98, 105, 97, 115, 0, 171, 1, 0, 3, + 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 101, 100, + 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, 102, 115, 101, 116, 95, 102, 114, 111, + 110, 116, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, + 102, 115, 101, 116, 95, 98, 97, 99, 107, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, + 115, 116, 101, 110, 99, 105, 108, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, + 95, 98, 97, 115, 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, + 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 102, 111, 114, 109, 97, 116, 95, + 102, 108, 97, 103, 115, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 99, + 108, 97, 109, 112, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 92, 6, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 107, 101, 101, + 112, 95, 109, 97, 115, 107, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, + 98, 108, 101, 110, 100, 95, 102, 97, 99, 116, 111, 114, 115, 95, 111, 112, 115, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 98, 108, 101, 110, 100, 95, 99, 111, 110, 115, 116, + 97, 110, 116, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, + 32, 49, 48, 46, 49, 0, 171, 171, 73, 83, 71, 78, 48, 0, 0, 0, 1, 0, 0, + 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 88, 69, 84, 69, 83, 83, 70, 65, 67, + 84, 79, 82, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, + 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 1, 14, 0, 0, 88, 69, 86, 69, 82, 84, 69, 88, 73, 68, + 0, 171, 80, 67, 83, 71, 188, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 152, + 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 1, 14, 0, 0, 152, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, + 0, 1, 0, 0, 0, 1, 14, 0, 0, 152, 0, 0, 0, 2, 0, 0, 0, 11, 0, + 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 14, 0, 0, 152, 0, 0, 0, 3, + 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 14, 0, 0, + 166, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, + 0, 1, 14, 0, 0, 166, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 3, 0, + 0, 0, 5, 0, 0, 0, 1, 14, 0, 0, 83, 86, 95, 84, 101, 115, 115, 70, 97, + 99, 116, 111, 114, 0, 83, 86, 95, 73, 110, 115, 105, 100, 101, 84, 101, 115, 115, 70, + 97, 99, 116, 111, 114, 0, 171, 171, 83, 72, 69, 88, 232, 2, 0, 0, 81, 0, 3, + 0, 186, 0, 0, 0, 113, 0, 0, 1, 147, 32, 0, 1, 148, 8, 0, 1, 149, 24, + 0, 1, 150, 32, 0, 1, 151, 24, 0, 1, 106, 8, 0, 1, 89, 0, 0, 7, 70, + 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 114, 0, 0, 1, 95, 0, 0, 2, 0, 176, 0, 0, 101, 0, 0, + 3, 18, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 30, 0, + 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 1, 176, 0, 0, 26, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, + 0, 83, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 84, + 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 86, 0, 0, + 5, 18, 32, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 62, 0, + 0, 1, 115, 0, 0, 1, 153, 0, 0, 2, 4, 0, 0, 0, 95, 0, 0, 2, 0, + 112, 1, 0, 95, 0, 0, 4, 18, 144, 33, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 103, 0, 0, 4, 18, 32, 16, 0, 0, 0, 0, 0, 11, 0, 0, 0, 103, 0, 0, + 4, 18, 32, 16, 0, 1, 0, 0, 0, 12, 0, 0, 0, 103, 0, 0, 4, 18, 32, + 16, 0, 2, 0, 0, 0, 13, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 3, + 0, 0, 0, 14, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 91, 0, 0, 4, + 18, 32, 16, 0, 0, 0, 0, 0, 4, 0, 0, 0, 30, 0, 0, 6, 18, 0, 16, + 0, 0, 0, 0, 0, 10, 112, 1, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, + 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 0, 0, 0, 0, + 10, 112, 1, 0, 54, 0, 0, 8, 18, 32, 144, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 10, 144, 161, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, + 0, 1, 115, 0, 0, 1, 153, 0, 0, 2, 2, 0, 0, 0, 95, 0, 0, 2, 0, + 112, 1, 0, 95, 0, 0, 4, 18, 144, 33, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 103, 0, 0, 4, 18, 32, 16, 0, 4, 0, 0, 0, 15, 0, 0, 0, 103, 0, 0, + 4, 18, 32, 16, 0, 5, 0, 0, 0, 16, 0, 0, 0, 104, 0, 0, 2, 1, 0, + 0, 0, 91, 0, 0, 4, 18, 32, 16, 0, 4, 0, 0, 0, 2, 0, 0, 0, 79, + 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 112, 1, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 55, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, + 0, 0, 40, 0, 0, 4, 34, 0, 16, 0, 0, 0, 0, 0, 10, 112, 1, 0, 51, + 0, 0, 12, 18, 0, 16, 0, 0, 0, 0, 0, 10, 144, 225, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 144, 161, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 0, 0, + 0, 0, 10, 112, 1, 0, 54, 0, 0, 7, 18, 32, 208, 0, 4, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 148, 0, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, + 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/adaptive_triangle_hs.h b/src/graphics/shaders/bytecode/d3d12_5_1/adaptive_triangle_hs.h new file mode 100644 index 0000000..f8ad47c --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/adaptive_triangle_hs.h @@ -0,0 +1,321 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer xe_system_cbuffer +// { +// +// uint xe_flags; // Offset: 0 Size: 4 [unused] +// float2 xe_tessellation_factor_range;// Offset: 4 Size: 8 [unused] +// uint xe_line_loop_closing_index; // Offset: 12 Size: 4 [unused] +// uint xe_vertex_index_endian; // Offset: 16 Size: 4 [unused] +// uint xe_vertex_index_offset; // Offset: 20 Size: 4 +// uint2 xe_vertex_index_min_max; // Offset: 24 Size: 8 +// float4 xe_user_clip_planes[6]; // Offset: 32 Size: 96 [unused] +// float3 xe_ndc_scale; // Offset: 128 Size: 12 [unused] +// float xe_point_vertex_diameter_min;// Offset: 140 Size: 4 [unused] +// float3 xe_ndc_offset; // Offset: 144 Size: 12 [unused] +// float xe_point_vertex_diameter_max;// Offset: 156 Size: 4 [unused] +// float2 xe_point_constant_diameter; // Offset: 160 Size: 8 [unused] +// float2 xe_point_screen_diameter_to_ndc_radius;// Offset: 168 Size: 8 [unused] +// uint4 xe_texture_swizzled_signs[2];// Offset: 176 Size: 32 [unused] +// uint xe_textures_resolved; // Offset: 208 Size: 4 [unused] +// uint2 xe_sample_count_log2; // Offset: 212 Size: 8 [unused] +// float xe_alpha_test_reference; // Offset: 220 Size: 4 [unused] +// uint xe_alpha_to_mask; // Offset: 224 Size: 4 [unused] +// uint xe_edram_32bpp_tile_pitch_dwords_scaled;// Offset: 228 Size: 4 [unused] +// uint xe_edram_depth_base_dwords_scaled;// Offset: 232 Size: 4 [unused] +// float4 xe_color_exp_bias; // Offset: 240 Size: 16 [unused] +// float2 xe_edram_poly_offset_front; // Offset: 256 Size: 8 [unused] +// float2 xe_edram_poly_offset_back; // Offset: 264 Size: 8 [unused] +// uint4 xe_edram_stencil[2]; // Offset: 272 Size: 32 [unused] +// uint4 xe_edram_rt_base_dwords_scaled;// Offset: 304 Size: 16 [unused] +// uint4 xe_edram_rt_format_flags; // Offset: 320 Size: 16 [unused] +// float4 xe_edram_rt_clamp[4]; // Offset: 336 Size: 64 [unused] +// uint4 xe_edram_rt_keep_mask[2]; // Offset: 400 Size: 32 [unused] +// uint4 xe_edram_rt_blend_factors_ops;// Offset: 432 Size: 16 [unused] +// float4 xe_edram_blend_constant; // Offset: 448 Size: 16 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_system_cbuffer cbuffer NA NA CB0 cb0 1 +// +// +// +// Patch Constant signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TessFactor 0 x 0 TRIEDGE float x +// SV_TessFactor 1 x 1 TRIEDGE float x +// SV_TessFactor 2 x 2 TRIEDGE float x +// SV_InsideTessFactor 0 x 3 TRIINT float x +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XETESSFACTOR 0 x 0 NONE float x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE float x +// +// Tessellation Domain # of control points +// -------------------- -------------------- +// Triangle 1 +// +// Tessellation Output Primitive Partitioning Type +// ------------------------------ ------------------ +// Clockwise Triangles Even Fractional +// +hs_5_1 +hs_decls +dcl_input_control_point_count 3 +dcl_output_control_point_count 1 +dcl_tessellator_domain domain_tri +dcl_tessellator_partitioning partitioning_fractional_even +dcl_tessellator_output_primitive output_triangle_cw +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][2], immediateIndexed, space=0 +hs_control_point_phase +dcl_input vPrim +dcl_output o0.x +dcl_temps 1 +iadd r0.x, vPrim, CB0[0][1].y +and r0.x, r0.x, l(0x00ffffff) +umax r0.x, r0.x, CB0[0][1].z +umin r0.x, r0.x, CB0[0][1].w +utof o0.x, r0.x +ret +hs_fork_phase +dcl_hs_fork_phase_instance_count 3 +dcl_input vForkInstanceID +dcl_input vicp[3][0].x +dcl_output_siv o0.x, finalTriUeq0EdgeTessFactor +dcl_output_siv o1.x, finalTriVeq0EdgeTessFactor +dcl_output_siv o2.x, finalTriWeq0EdgeTessFactor +dcl_temps 1 +dcl_indexrange o0.x 3 +iadd r0.x, vForkInstanceID.x, l(1) +udiv null, r0.x, r0.x, l(3) +mov r0.y, vForkInstanceID.x +mov o[r0.y + 0].x, vicp[r0.x + 0][0].x +ret +hs_fork_phase +dcl_input vicp[3][0].x +dcl_output_siv o3.x, finalTriInsideTessFactor +dcl_temps 1 +min r0.x, vicp[2][0].x, vicp[1][0].x +min o3.x, r0.x, vicp[0][0].x +ret +// Approximately 14 instruction slots used +#endif + +const BYTE adaptive_triangle_hs[] = { + 68, 88, 66, 67, 213, 151, 26, 214, 48, 115, 215, 10, 67, 36, 129, 21, 5, 111, 231, + 249, 1, 0, 0, 0, 88, 14, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 108, 10, + 0, 0, 164, 10, 0, 0, 216, 10, 0, 0, 108, 11, 0, 0, 188, 13, 0, 0, 82, + 68, 69, 70, 44, 10, 0, 0, 1, 0, 0, 0, 120, 0, 0, 0, 1, 0, 0, 0, + 60, 0, 0, 0, 1, 5, 83, 72, 0, 5, 0, 0, 2, 10, 0, 0, 19, 19, 68, + 37, 60, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 115, 121, 115, 116, + 101, 109, 95, 99, 98, 117, 102, 102, 101, 114, 0, 171, 171, 100, 0, 0, 0, 30, 0, + 0, 0, 144, 0, 0, 0, 208, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, + 5, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 116, 5, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, 5, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 188, 5, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 215, 5, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 238, 5, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 5, 6, 0, 0, 24, 0, 0, 0, 8, 0, + 0, 0, 2, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 72, 6, 0, 0, 32, 0, 0, 0, + 96, 0, 0, 0, 0, 0, 0, 0, 100, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 136, 6, 0, 0, 128, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 6, 0, 0, + 140, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 8, 7, + 0, 0, 144, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 22, 7, 0, 0, 156, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 51, 7, 0, 0, 160, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, + 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 78, 7, 0, 0, 168, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 117, 7, 0, 0, 176, 0, 0, 0, 32, 0, 0, 0, 0, + 0, 0, 0, 152, 7, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 188, 7, 0, 0, 208, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 209, 7, 0, 0, 212, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 230, 7, 0, 0, 220, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 254, 7, 0, 0, 224, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 8, 0, + 0, 228, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 55, + 8, 0, 0, 232, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 89, 8, 0, 0, 240, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 144, 8, 0, 0, 0, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 171, 8, 0, 0, 8, 1, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 197, 8, 0, 0, 16, 1, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 216, 8, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 252, 8, 0, 0, 48, 1, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 64, 9, 0, 0, 64, 1, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 89, 9, 0, 0, 80, 1, + 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 108, 9, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 144, 9, 0, 0, + 144, 1, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 168, 9, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 204, 9, + 0, 0, 176, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 234, 9, 0, 0, 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 120, 101, 95, 102, 108, 97, 103, 115, 0, 100, 119, 111, 114, 100, 0, 171, 0, + 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 5, 0, 0, 120, 101, 95, + 116, 101, 115, 115, 101, 108, 108, 97, 116, 105, 111, 110, 95, 102, 97, 99, 116, 111, 114, + 95, 114, 97, 110, 103, 101, 0, 102, 108, 111, 97, 116, 50, 0, 1, 0, 3, 0, 1, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 145, 5, 0, 0, 120, 101, 95, 108, 105, 110, 101, + 95, 108, 111, 111, 112, 95, 99, 108, 111, 115, 105, 110, 103, 95, 105, 110, 100, 101, 120, + 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, 120, 95, 101, 110, + 100, 105, 97, 110, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, + 120, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, + 105, 110, 100, 101, 120, 95, 109, 105, 110, 95, 109, 97, 120, 0, 117, 105, 110, 116, 50, + 0, 171, 1, 0, 19, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 6, 0, 0, + 120, 101, 95, 117, 115, 101, 114, 95, 99, 108, 105, 112, 95, 112, 108, 97, 110, 101, 115, + 0, 102, 108, 111, 97, 116, 52, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 110, 100, 99, 95, 115, 99, 97, 108, 101, + 0, 102, 108, 111, 97, 116, 51, 0, 1, 0, 3, 0, 1, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 149, 6, 0, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, + 101, 120, 95, 100, 105, 97, 109, 101, 116, 101, 114, 95, 109, 105, 110, 0, 102, 108, 111, + 97, 116, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 6, + 0, 0, 120, 101, 95, 110, 100, 99, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, 101, 120, 95, 100, 105, 97, 109, 101, 116, + 101, 114, 95, 109, 97, 120, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 99, 111, 110, + 115, 116, 97, 110, 116, 95, 100, 105, 97, 109, 101, 116, 101, 114, 0, 120, 101, 95, 112, + 111, 105, 110, 116, 95, 115, 99, 114, 101, 101, 110, 95, 100, 105, 97, 109, 101, 116, 101, + 114, 95, 116, 111, 95, 110, 100, 99, 95, 114, 97, 100, 105, 117, 115, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 115, 119, 105, 122, 122, 108, 101, 100, 95, 115, 105, + 103, 110, 115, 0, 117, 105, 110, 116, 52, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, + 4, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, + 114, 101, 115, 95, 114, 101, 115, 111, 108, 118, 101, 100, 0, 120, 101, 95, 115, 97, 109, + 112, 108, 101, 95, 99, 111, 117, 110, 116, 95, 108, 111, 103, 50, 0, 120, 101, 95, 97, + 108, 112, 104, 97, 95, 116, 101, 115, 116, 95, 114, 101, 102, 101, 114, 101, 110, 99, 101, + 0, 120, 101, 95, 97, 108, 112, 104, 97, 95, 116, 111, 95, 109, 97, 115, 107, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 51, 50, 98, 112, 112, 95, 116, 105, 108, 101, 95, + 112, 105, 116, 99, 104, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 100, 101, 112, 116, 104, 95, 98, 97, 115, + 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, 0, 120, 101, 95, + 99, 111, 108, 111, 114, 95, 101, 120, 112, 95, 98, 105, 97, 115, 0, 171, 1, 0, 3, + 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 101, 100, + 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, 102, 115, 101, 116, 95, 102, 114, 111, + 110, 116, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, + 102, 115, 101, 116, 95, 98, 97, 99, 107, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, + 115, 116, 101, 110, 99, 105, 108, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, + 95, 98, 97, 115, 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, + 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 102, 111, 114, 109, 97, 116, 95, + 102, 108, 97, 103, 115, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 99, + 108, 97, 109, 112, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 92, 6, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 107, 101, 101, + 112, 95, 109, 97, 115, 107, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, + 98, 108, 101, 110, 100, 95, 102, 97, 99, 116, 111, 114, 115, 95, 111, 112, 115, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 98, 108, 101, 110, 100, 95, 99, 111, 110, 115, 116, + 97, 110, 116, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, + 32, 49, 48, 46, 49, 0, 171, 171, 73, 83, 71, 78, 48, 0, 0, 0, 1, 0, 0, + 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 88, 69, 84, 69, 83, 83, 70, 65, 67, + 84, 79, 82, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, + 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 1, 14, 0, 0, 88, 69, 86, 69, 82, 84, 69, 88, 73, 68, + 0, 171, 80, 67, 83, 71, 140, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, + 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 1, 14, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, + 0, 1, 0, 0, 0, 1, 14, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 13, 0, + 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 14, 0, 0, 118, 0, 0, 0, 0, + 0, 0, 0, 14, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 14, 0, 0, + 83, 86, 95, 84, 101, 115, 115, 70, 97, 99, 116, 111, 114, 0, 83, 86, 95, 73, 110, + 115, 105, 100, 101, 84, 101, 115, 115, 70, 97, 99, 116, 111, 114, 0, 171, 171, 83, 72, + 69, 88, 72, 2, 0, 0, 81, 0, 3, 0, 146, 0, 0, 0, 113, 0, 0, 1, 147, + 24, 0, 1, 148, 8, 0, 1, 149, 16, 0, 1, 150, 32, 0, 1, 151, 24, 0, 1, + 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 114, 0, 0, 1, 95, 0, + 0, 2, 0, 176, 0, 0, 101, 0, 0, 3, 18, 32, 16, 0, 0, 0, 0, 0, 104, + 0, 0, 2, 1, 0, 0, 0, 30, 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, + 1, 176, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 255, 255, 255, 0, 83, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 84, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 86, 0, 0, 5, 18, 32, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 115, 0, 0, 1, 153, 0, 0, 2, + 3, 0, 0, 0, 95, 0, 0, 2, 0, 112, 1, 0, 95, 0, 0, 4, 18, 144, 33, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 0, 0, + 0, 0, 17, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 1, 0, 0, 0, 18, + 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 2, 0, 0, 0, 19, 0, 0, 0, + 104, 0, 0, 2, 1, 0, 0, 0, 91, 0, 0, 4, 18, 32, 16, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 30, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 112, + 1, 0, 1, 64, 0, 0, 1, 0, 0, 0, 78, 0, 0, 8, 0, 208, 0, 0, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 0, 0, 0, 0, 10, 112, 1, + 0, 54, 0, 0, 8, 18, 32, 144, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 144, + 161, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 115, + 0, 0, 1, 95, 0, 0, 4, 18, 144, 33, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 103, 0, 0, 4, 18, 32, 16, 0, 3, 0, 0, 0, 20, 0, 0, 0, 104, 0, 0, + 2, 1, 0, 0, 0, 51, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 144, + 33, 0, 2, 0, 0, 0, 0, 0, 0, 0, 10, 144, 33, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 51, 0, 0, 8, 18, 32, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 10, 144, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 148, 0, 0, 0, 14, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_pwl_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_pwl_cs.h new file mode 100644 index 0000000..421e6f4 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_pwl_cs.h @@ -0,0 +1,188 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint2 xe_apply_gamma_size; // Offset: 0 Size: 8 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_apply_gamma_ramp texture uint4 buf T0 t0 1 +// xe_apply_gamma_source texture float4 2d T1 t1 1 +// xe_apply_gamma_dest UAV unorm4 2d U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_resource_texture2d (float,float,float,float) T1[1:1], space=0 +dcl_uav_typed_texture2d (unorm,unorm,unorm,unorm) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 3 +dcl_thread_group 16, 8, 1 +uge r0.xy, vThreadID.xyxx, CB0[0][0].xyxx +or r0.x, r0.y, r0.x +if_nz r0.x + ret +endif +mov r0.xy, vThreadID.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyz, r0.xyzw, T1[1].xyzw +mad r0.xyz, r0.xyzx, l(1023.000000, 1023.000000, 1023.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) +ftou r0.xyz, r0.xyzx +ushr r1.xyz, r0.xyzx, l(3, 3, 3, 0) +imul null, r0.w, r1.x, l(3) +ld r1.xw, r0.wwww, T0[0].xzwy +utof r0.w, r1.x +and r0.xyz, r0.xyzx, l(7, 7, 7, 0) +imul null, r0.x, r1.w, r0.x +utof r0.x, r0.x +mad r0.x, r0.x, l(0.125000), r0.w +mul r0.x, r0.x, l(0.000015) +min r2.x, r0.x, l(1.000000) +imad r0.xw, r1.yyyz, l(3, 0, 0, 3), l(1, 0, 0, 2) +ld r1.xy, r0.xxxx, T0[0].xyzw +utof r0.x, r1.x +imul null, r0.y, r0.y, r1.y +utof r0.y, r0.y +mad r0.x, r0.y, l(0.125000), r0.x +mul r0.x, r0.x, l(0.000015) +min r2.y, r0.x, l(1.000000) +ld r0.xy, r0.wwww, T0[0].xyzw +imul null, r0.y, r0.y, r0.z +utof r0.xy, r0.xyxx +mad r0.x, r0.y, l(0.125000), r0.x +mul r0.x, r0.x, l(0.000015) +min r2.z, r0.x, l(1.000000) +mov r2.w, l(1.000000) +store_uav_typed U0[0].xyzw, vThreadID.xyyy, r2.xyzw +ret +// Approximately 37 instruction slots used +#endif + +const BYTE apply_gamma_pwl_cs[] = { + 68, 88, 66, 67, 92, 6, 102, 66, 107, 123, 97, 185, 70, 227, 155, 50, 177, 34, 170, + 181, 1, 0, 0, 0, 120, 7, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 16, 2, + 0, 0, 32, 2, 0, 0, 48, 2, 0, 0, 220, 6, 0, 0, 82, 68, 69, 70, 212, + 1, 0, 0, 1, 0, 0, 0, 44, 1, 0, 0, 4, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 172, 1, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, + 0, 4, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 97, 112, + 112, 108, 121, 95, 103, 97, 109, 109, 97, 95, 114, 97, 109, 112, 0, 120, 101, 95, 97, + 112, 112, 108, 121, 95, 103, 97, 109, 109, 97, 95, 115, 111, 117, 114, 99, 101, 0, 120, + 101, 95, 97, 112, 112, 108, 121, 95, 103, 97, 109, 109, 97, 95, 100, 101, 115, 116, 0, + 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 171, 171, 26, + 1, 0, 0, 1, 0, 0, 0, 68, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 108, 1, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, + 0, 136, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 120, 101, 95, 97, 112, 112, 108, 121, 95, 103, 97, 109, 109, + 97, 95, 115, 105, 122, 101, 0, 117, 105, 110, 116, 50, 0, 171, 171, 1, 0, 19, 0, + 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 1, 0, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, + 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 164, 4, 0, 0, 81, 0, + 5, 0, 41, 1, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 68, 68, 0, 0, 0, 0, 0, 0, 88, 24, 0, 7, 70, 126, 48, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 85, 85, 0, 0, 0, 0, 0, 0, 156, + 24, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 17, 17, 0, 0, 0, 0, 0, 0, 95, 0, 0, 2, 50, 0, 2, 0, 104, 0, 0, + 2, 3, 0, 0, 0, 155, 0, 0, 4, 16, 0, 0, 0, 8, 0, 0, 0, 1, 0, + 0, 0, 80, 0, 0, 8, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 2, 0, 70, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, + 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 62, 0, + 0, 1, 21, 0, 0, 1, 54, 0, 0, 4, 50, 0, 16, 0, 0, 0, 0, 0, 70, + 0, 2, 0, 54, 0, 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, + 8, 114, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, + 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 192, 127, 68, + 0, 192, 127, 68, 0, 192, 127, 68, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 28, 0, 0, 5, 114, 0, + 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 114, + 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 45, 0, 0, 8, 146, 0, 16, 0, 1, + 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 134, 119, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 18, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 86, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 62, 58, 0, 16, 0, 0, 0, 0, 0, + 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 8, 32, 128, 55, 51, 0, 0, 7, 18, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 35, + 0, 0, 15, 146, 0, 16, 0, 0, 0, 0, 0, 86, 9, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 45, 0, 0, 8, 50, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, + 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 86, 0, 0, 5, 34, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 62, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 32, 128, 55, 51, + 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 128, 63, 45, 0, 0, 8, 50, 0, 16, 0, 0, 0, 0, + 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 86, 0, 0, 5, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, + 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 62, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 8, 32, 128, 55, 51, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 54, 0, 0, 5, 130, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 164, 0, 0, 7, 242, + 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 5, 2, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 37, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 10, 0, 0, 0, 5, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_pwl_fxaa_luma_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_pwl_fxaa_luma_cs.h new file mode 100644 index 0000000..e40fdb8 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_pwl_fxaa_luma_cs.h @@ -0,0 +1,189 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint2 xe_apply_gamma_size; // Offset: 0 Size: 8 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_apply_gamma_ramp texture uint4 buf T0 t0 1 +// xe_apply_gamma_source texture float4 2d T1 t1 1 +// xe_apply_gamma_dest UAV float4 2d U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_resource_texture2d (float,float,float,float) T1[1:1], space=0 +dcl_uav_typed_texture2d (float,float,float,float) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 3 +dcl_thread_group 16, 8, 1 +uge r0.xy, vThreadID.xyxx, CB0[0][0].xyxx +or r0.x, r0.y, r0.x +if_nz r0.x + ret +endif +mov r0.xy, vThreadID.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyz, r0.xyzw, T1[1].xyzw +mad r0.xyz, r0.xyzx, l(1023.000000, 1023.000000, 1023.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) +ftou r0.xyz, r0.xyzx +ushr r1.xyz, r0.xyzx, l(3, 3, 3, 0) +imul null, r0.w, r1.x, l(3) +ld r1.xw, r0.wwww, T0[0].xzwy +utof r0.w, r1.x +and r0.xyz, r0.xyzx, l(7, 7, 7, 0) +imul null, r0.x, r1.w, r0.x +utof r0.x, r0.x +mad r0.x, r0.x, l(0.125000), r0.w +mul r0.x, r0.x, l(0.000015) +min r2.x, r0.x, l(1.000000) +imad r0.xw, r1.yyyz, l(3, 0, 0, 3), l(1, 0, 0, 2) +ld r1.xy, r0.xxxx, T0[0].xyzw +utof r0.x, r1.x +imul null, r0.y, r0.y, r1.y +utof r0.y, r0.y +mad r0.x, r0.y, l(0.125000), r0.x +mul r0.x, r0.x, l(0.000015) +min r2.y, r0.x, l(1.000000) +ld r0.xy, r0.wwww, T0[0].xyzw +imul null, r0.y, r0.y, r0.z +utof r0.xy, r0.xyxx +mad r0.x, r0.y, l(0.125000), r0.x +mul r0.x, r0.x, l(0.000015) +min r2.z, r0.x, l(1.000000) +dp3 r2.w, r2.xyzx, l(0.299000, 0.587000, 0.114000, 0.000000) +store_uav_typed U0[0].xyzw, vThreadID.xyyy, r2.xyzw +ret +// Approximately 37 instruction slots used +#endif + +const BYTE apply_gamma_pwl_fxaa_luma_cs[] = { + 68, 88, 66, 67, 96, 224, 168, 165, 77, 202, 54, 14, 176, 64, 7, 12, 228, 221, 231, + 44, 1, 0, 0, 0, 140, 7, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 16, 2, + 0, 0, 32, 2, 0, 0, 48, 2, 0, 0, 240, 6, 0, 0, 82, 68, 69, 70, 212, + 1, 0, 0, 1, 0, 0, 0, 44, 1, 0, 0, 4, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 172, 1, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, + 0, 4, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 5, + 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 97, 112, + 112, 108, 121, 95, 103, 97, 109, 109, 97, 95, 114, 97, 109, 112, 0, 120, 101, 95, 97, + 112, 112, 108, 121, 95, 103, 97, 109, 109, 97, 95, 115, 111, 117, 114, 99, 101, 0, 120, + 101, 95, 97, 112, 112, 108, 121, 95, 103, 97, 109, 109, 97, 95, 100, 101, 115, 116, 0, + 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 171, 171, 26, + 1, 0, 0, 1, 0, 0, 0, 68, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 108, 1, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, + 0, 136, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 120, 101, 95, 97, 112, 112, 108, 121, 95, 103, 97, 109, 109, + 97, 95, 115, 105, 122, 101, 0, 117, 105, 110, 116, 50, 0, 171, 171, 1, 0, 19, 0, + 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 1, 0, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, + 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 184, 4, 0, 0, 81, 0, + 5, 0, 46, 1, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 68, 68, 0, 0, 0, 0, 0, 0, 88, 24, 0, 7, 70, 126, 48, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 85, 85, 0, 0, 0, 0, 0, 0, 156, + 24, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 85, 0, 0, 0, 0, 0, 0, 95, 0, 0, 2, 50, 0, 2, 0, 104, 0, 0, + 2, 3, 0, 0, 0, 155, 0, 0, 4, 16, 0, 0, 0, 8, 0, 0, 0, 1, 0, + 0, 0, 80, 0, 0, 8, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 2, 0, 70, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, + 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 62, 0, + 0, 1, 21, 0, 0, 1, 54, 0, 0, 4, 50, 0, 16, 0, 0, 0, 0, 0, 70, + 0, 2, 0, 54, 0, 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, + 8, 114, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, + 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 192, 127, 68, + 0, 192, 127, 68, 0, 192, 127, 68, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 28, 0, 0, 5, 114, 0, + 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 114, + 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 45, 0, 0, 8, 146, 0, 16, 0, 1, + 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 134, 119, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 18, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 86, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 62, 58, 0, 16, 0, 0, 0, 0, 0, + 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 8, 32, 128, 55, 51, 0, 0, 7, 18, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 35, + 0, 0, 15, 146, 0, 16, 0, 0, 0, 0, 0, 86, 9, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 45, 0, 0, 8, 50, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, + 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 86, 0, 0, 5, 34, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 62, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 32, 128, 55, 51, + 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 128, 63, 45, 0, 0, 8, 50, 0, 16, 0, 0, 0, 0, + 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 86, 0, 0, 5, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, + 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 62, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 8, 32, 128, 55, 51, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 16, 0, 0, 10, 130, 0, + 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 135, + 22, 153, 62, 162, 69, 22, 63, 213, 120, 233, 61, 0, 0, 0, 0, 164, 0, 0, 7, + 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 5, 2, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 37, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 5, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_pwl_fxaa_luma_ps.h b/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_pwl_fxaa_luma_ps.h new file mode 100644 index 0000000..efe9711 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_pwl_fxaa_luma_ps.h @@ -0,0 +1,156 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_apply_gamma_ramp texture uint4 buf T0 t0 1 +// xe_apply_gamma_source texture float4 2d T1 t1 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// +ps_5_1 +dcl_globalFlags refactoringAllowed +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_resource_texture2d (float,float,float,float) T1[1:1], space=0 +dcl_input_ps_siv linear noperspective v0.xy, position +dcl_output o0.xyzw +dcl_temps 3 +ftou r0.xy, v0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyz, r0.xyzw, T1[1].xyzw +mad r0.xyz, r0.xyzx, l(1023.000000, 1023.000000, 1023.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) +ftou r0.xyz, r0.xyzx +ushr r1.xyz, r0.xyzx, l(3, 3, 3, 0) +imul null, r0.w, r1.x, l(3) +ld r1.xw, r0.wwww, T0[0].xzwy +utof r0.w, r1.x +and r0.xyz, r0.xyzx, l(7, 7, 7, 0) +imul null, r0.x, r1.w, r0.x +utof r0.x, r0.x +mad r0.x, r0.x, l(0.125000), r0.w +mul r0.x, r0.x, l(0.000015) +min r2.x, r0.x, l(1.000000) +imad r0.xw, r1.yyyz, l(3, 0, 0, 3), l(1, 0, 0, 2) +ld r1.xy, r0.xxxx, T0[0].xyzw +utof r0.x, r1.x +imul null, r0.y, r0.y, r1.y +utof r0.y, r0.y +mad r0.x, r0.y, l(0.125000), r0.x +mul r0.x, r0.x, l(0.000015) +min r2.y, r0.x, l(1.000000) +ld r0.xy, r0.wwww, T0[0].xyzw +imul null, r0.y, r0.y, r0.z +utof r0.xy, r0.xyxx +mad r0.x, r0.y, l(0.125000), r0.x +mul r0.x, r0.x, l(0.000015) +min r2.z, r0.x, l(1.000000) +dp3 o0.w, r2.xyzx, l(0.299000, 0.587000, 0.114000, 0.000000) +mov o0.xyz, r2.xyzx +ret +// Approximately 32 instruction slots used +#endif + +const BYTE apply_gamma_pwl_fxaa_luma_ps[] = { + 68, 88, 66, 67, 202, 241, 49, 179, 160, 182, 197, 116, 174, 174, 57, 216, 126, 205, 210, + 129, 1, 0, 0, 0, 88, 6, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 28, 1, + 0, 0, 80, 1, 0, 0, 132, 1, 0, 0, 188, 5, 0, 0, 82, 68, 69, 70, 224, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 255, 255, 0, 5, 0, 0, 182, 0, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, + 0, 4, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 120, 101, 95, 97, 112, 112, 108, 121, 95, + 103, 97, 109, 109, 97, 95, 114, 97, 109, 112, 0, 120, 101, 95, 97, 112, 112, 108, 121, + 95, 103, 97, 109, 109, 97, 95, 115, 111, 117, 114, 99, 101, 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, + 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 73, + 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 3, 0, + 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 79, 83, 71, 78, 44, 0, + 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, + 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 69, 88, 48, 4, 0, 0, 81, 0, 0, + 0, 12, 1, 0, 0, 106, 8, 0, 1, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 88, + 24, 0, 7, 70, 126, 48, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 85, 85, 0, 0, 0, 0, 0, 0, 100, 32, 0, 4, 50, 16, 16, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 3, 0, 0, 0, 28, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, + 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 45, 0, 0, 8, 114, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 70, 126, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 50, 0, 0, 15, 114, + 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 192, 127, 68, 0, 192, 127, 68, 0, 192, 127, 68, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 28, 0, + 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 85, + 0, 0, 10, 114, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 45, 0, 0, 8, 146, + 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 134, 119, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 0, 0, + 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 86, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 62, 58, 0, 16, 0, + 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 32, 128, 55, 51, 0, 0, 7, 18, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 128, 63, 35, 0, 0, 15, 146, 0, 16, 0, 0, 0, 0, 0, 86, 9, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 45, 0, 0, 8, 50, 0, 16, 0, 1, 0, 0, 0, 6, + 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, + 0, 38, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 86, 0, 0, 5, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 62, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, + 32, 128, 55, 51, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 45, 0, 0, 8, 50, 0, 16, + 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 86, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, + 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 62, 10, 0, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 8, 32, 128, 55, 51, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 16, 0, + 0, 10, 130, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 135, 22, 153, 62, 162, 69, 22, 63, 213, 120, 233, 61, 0, 0, 0, 0, + 54, 0, 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, + 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 32, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 2, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_pwl_ps.h b/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_pwl_ps.h new file mode 100644 index 0000000..1535265 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_pwl_ps.h @@ -0,0 +1,153 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_apply_gamma_ramp texture uint4 buf T0 t0 1 +// xe_apply_gamma_source texture float4 2d T1 t1 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// +ps_5_1 +dcl_globalFlags refactoringAllowed +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_resource_texture2d (float,float,float,float) T1[1:1], space=0 +dcl_input_ps_siv linear noperspective v0.xy, position +dcl_output o0.xyzw +dcl_temps 2 +ftou r0.xy, v0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyz, r0.xyzw, T1[1].xyzw +mad r0.xyz, r0.xyzx, l(1023.000000, 1023.000000, 1023.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) +ftou r0.xyz, r0.xyzx +ushr r1.xyz, r0.xyzx, l(3, 3, 3, 0) +imul null, r0.w, r1.x, l(3) +ld r1.xw, r0.wwww, T0[0].xzwy +utof r0.w, r1.x +and r0.xyz, r0.xyzx, l(7, 7, 7, 0) +imul null, r0.x, r1.w, r0.x +utof r0.x, r0.x +mad r0.x, r0.x, l(0.125000), r0.w +mul r0.x, r0.x, l(0.000015) +min o0.x, r0.x, l(1.000000) +imad r0.xw, r1.yyyz, l(3, 0, 0, 3), l(1, 0, 0, 2) +ld r1.xy, r0.xxxx, T0[0].xyzw +utof r0.x, r1.x +imul null, r0.y, r0.y, r1.y +utof r0.y, r0.y +mad r0.x, r0.y, l(0.125000), r0.x +mul r0.x, r0.x, l(0.000015) +min o0.y, r0.x, l(1.000000) +ld r0.xy, r0.wwww, T0[0].xyzw +imul null, r0.y, r0.y, r0.z +utof r0.xy, r0.xyxx +mad r0.x, r0.y, l(0.125000), r0.x +mul r0.x, r0.x, l(0.000015) +min o0.z, r0.x, l(1.000000) +mov o0.w, l(1.000000) +ret +// Approximately 31 instruction slots used +#endif + +const BYTE apply_gamma_pwl_ps[] = { + 68, 88, 66, 67, 197, 255, 198, 206, 158, 112, 94, 186, 5, 215, 2, 4, 116, 239, 1, + 249, 1, 0, 0, 0, 48, 6, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 28, 1, + 0, 0, 80, 1, 0, 0, 132, 1, 0, 0, 148, 5, 0, 0, 82, 68, 69, 70, 224, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 255, 255, 0, 5, 0, 0, 182, 0, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, + 0, 4, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 120, 101, 95, 97, 112, 112, 108, 121, 95, + 103, 97, 109, 109, 97, 95, 114, 97, 109, 112, 0, 120, 101, 95, 97, 112, 112, 108, 121, + 95, 103, 97, 109, 109, 97, 95, 115, 111, 117, 114, 99, 101, 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, + 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 73, + 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 3, 0, + 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 79, 83, 71, 78, 44, 0, + 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, + 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 69, 88, 8, 4, 0, 0, 81, 0, 0, + 0, 2, 1, 0, 0, 106, 8, 0, 1, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 88, + 24, 0, 7, 70, 126, 48, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 85, 85, 0, 0, 0, 0, 0, 0, 100, 32, 0, 4, 50, 16, 16, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 2, 0, 0, 0, 28, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, + 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 45, 0, 0, 8, 114, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 70, 126, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 50, 0, 0, 15, 114, + 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 192, 127, 68, 0, 192, 127, 68, 0, 192, 127, 68, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 28, 0, + 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 85, + 0, 0, 10, 114, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 45, 0, 0, 8, 146, + 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 134, 119, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 0, 0, + 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 86, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 62, 58, 0, 16, 0, + 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 32, 128, 55, 51, 0, 0, 7, 18, 32, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 128, 63, 35, 0, 0, 15, 146, 0, 16, 0, 0, 0, 0, 0, 86, 9, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 45, 0, 0, 8, 50, 0, 16, 0, 1, 0, 0, 0, 6, + 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, + 0, 38, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 86, 0, 0, 5, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 62, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, + 32, 128, 55, 51, 0, 0, 7, 34, 32, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 45, 0, 0, 8, 50, 0, 16, + 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 86, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, + 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 62, 10, 0, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 8, 32, 128, 55, 51, 0, 0, 7, 66, 32, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 54, 0, + 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, + 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 31, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_table_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_table_cs.h new file mode 100644 index 0000000..3bbeec9 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_table_cs.h @@ -0,0 +1,133 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint2 xe_apply_gamma_size; // Offset: 0 Size: 8 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_apply_gamma_ramp texture float4 buf T0 t0 1 +// xe_apply_gamma_source texture float4 2d T1 t1 1 +// xe_apply_gamma_dest UAV unorm4 2d U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_buffer (float,float,float,float) T0[0:0], space=0 +dcl_resource_texture2d (float,float,float,float) T1[1:1], space=0 +dcl_uav_typed_texture2d (unorm,unorm,unorm,unorm) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 2 +dcl_thread_group 16, 8, 1 +uge r0.xy, vThreadID.xyxx, CB0[0][0].xyxx +or r0.x, r0.y, r0.x +if_nz r0.x + ret +endif +mov r0.xy, vThreadID.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyz, r0.xyzw, T1[1].xyzw +mad r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) +ftou r0.xyz, r0.xyzx +ld r1.x, r0.xxxx, T0[0].zxyw +ld r1.y, r0.yyyy, T0[0].xyzw +ld r1.z, r0.zzzz, T0[0].yzxw +mov r1.w, l(1.000000) +store_uav_typed U0[0].xyzw, vThreadID.xyyy, r1.xyzw +ret +// Approximately 16 instruction slots used +#endif + +const BYTE apply_gamma_table_cs[] = { + 68, 88, 66, 67, 224, 187, 208, 232, 174, 162, 162, 142, 57, 39, 145, 206, 92, 198, 122, + 202, 1, 0, 0, 0, 244, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 16, 2, + 0, 0, 32, 2, 0, 0, 48, 2, 0, 0, 88, 4, 0, 0, 82, 68, 69, 70, 212, + 1, 0, 0, 1, 0, 0, 0, 44, 1, 0, 0, 4, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 172, 1, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, + 0, 4, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 97, 112, + 112, 108, 121, 95, 103, 97, 109, 109, 97, 95, 114, 97, 109, 112, 0, 120, 101, 95, 97, + 112, 112, 108, 121, 95, 103, 97, 109, 109, 97, 95, 115, 111, 117, 114, 99, 101, 0, 120, + 101, 95, 97, 112, 112, 108, 121, 95, 103, 97, 109, 109, 97, 95, 100, 101, 115, 116, 0, + 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 171, 171, 26, + 1, 0, 0, 1, 0, 0, 0, 68, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 108, 1, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, + 0, 136, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 120, 101, 95, 97, 112, 112, 108, 121, 95, 103, 97, 109, 109, + 97, 95, 115, 105, 122, 101, 0, 117, 105, 110, 116, 50, 0, 171, 171, 1, 0, 19, 0, + 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 1, 0, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, + 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 32, 2, 0, 0, 81, 0, + 5, 0, 136, 0, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 85, 85, 0, 0, 0, 0, 0, 0, 88, 24, 0, 7, 70, 126, 48, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 85, 85, 0, 0, 0, 0, 0, 0, 156, + 24, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 17, 17, 0, 0, 0, 0, 0, 0, 95, 0, 0, 2, 50, 0, 2, 0, 104, 0, 0, + 2, 2, 0, 0, 0, 155, 0, 0, 4, 16, 0, 0, 0, 8, 0, 0, 0, 1, 0, + 0, 0, 80, 0, 0, 8, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 2, 0, 70, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, + 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 62, 0, + 0, 1, 21, 0, 0, 1, 54, 0, 0, 4, 50, 0, 16, 0, 0, 0, 0, 0, 70, + 0, 2, 0, 54, 0, 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, + 8, 114, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, + 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, + 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 28, 0, 0, 5, 114, 0, + 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 18, + 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 38, 125, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 34, 0, 16, 0, 1, 0, 0, + 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 8, 66, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, + 0, 0, 0, 150, 124, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 164, 0, 0, + 7, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 5, 2, 0, 70, 14, + 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 16, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_table_fxaa_luma_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_table_fxaa_luma_cs.h new file mode 100644 index 0000000..cecdbe4 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_table_fxaa_luma_cs.h @@ -0,0 +1,134 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint2 xe_apply_gamma_size; // Offset: 0 Size: 8 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_apply_gamma_ramp texture float4 buf T0 t0 1 +// xe_apply_gamma_source texture float4 2d T1 t1 1 +// xe_apply_gamma_dest UAV float4 2d U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_buffer (float,float,float,float) T0[0:0], space=0 +dcl_resource_texture2d (float,float,float,float) T1[1:1], space=0 +dcl_uav_typed_texture2d (float,float,float,float) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 2 +dcl_thread_group 16, 8, 1 +uge r0.xy, vThreadID.xyxx, CB0[0][0].xyxx +or r0.x, r0.y, r0.x +if_nz r0.x + ret +endif +mov r0.xy, vThreadID.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyz, r0.xyzw, T1[1].xyzw +mad r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) +ftou r0.xyz, r0.xyzx +ld r1.x, r0.xxxx, T0[0].zxyw +ld r1.y, r0.yyyy, T0[0].xyzw +ld r1.z, r0.zzzz, T0[0].yzxw +dp3 r1.w, r1.xyzx, l(0.299000, 0.587000, 0.114000, 0.000000) +store_uav_typed U0[0].xyzw, vThreadID.xyyy, r1.xyzw +ret +// Approximately 16 instruction slots used +#endif + +const BYTE apply_gamma_table_fxaa_luma_cs[] = { + 68, 88, 66, 67, 128, 162, 66, 16, 174, 83, 136, 225, 62, 54, 160, 145, 249, 15, 149, + 77, 1, 0, 0, 0, 8, 5, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 16, 2, + 0, 0, 32, 2, 0, 0, 48, 2, 0, 0, 108, 4, 0, 0, 82, 68, 69, 70, 212, + 1, 0, 0, 1, 0, 0, 0, 44, 1, 0, 0, 4, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 172, 1, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, + 0, 4, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 5, + 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 97, 112, + 112, 108, 121, 95, 103, 97, 109, 109, 97, 95, 114, 97, 109, 112, 0, 120, 101, 95, 97, + 112, 112, 108, 121, 95, 103, 97, 109, 109, 97, 95, 115, 111, 117, 114, 99, 101, 0, 120, + 101, 95, 97, 112, 112, 108, 121, 95, 103, 97, 109, 109, 97, 95, 100, 101, 115, 116, 0, + 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 171, 171, 26, + 1, 0, 0, 1, 0, 0, 0, 68, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 108, 1, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, + 0, 136, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 120, 101, 95, 97, 112, 112, 108, 121, 95, 103, 97, 109, 109, + 97, 95, 115, 105, 122, 101, 0, 117, 105, 110, 116, 50, 0, 171, 171, 1, 0, 19, 0, + 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 1, 0, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, + 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 52, 2, 0, 0, 81, 0, + 5, 0, 141, 0, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 85, 85, 0, 0, 0, 0, 0, 0, 88, 24, 0, 7, 70, 126, 48, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 85, 85, 0, 0, 0, 0, 0, 0, 156, + 24, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 85, 0, 0, 0, 0, 0, 0, 95, 0, 0, 2, 50, 0, 2, 0, 104, 0, 0, + 2, 2, 0, 0, 0, 155, 0, 0, 4, 16, 0, 0, 0, 8, 0, 0, 0, 1, 0, + 0, 0, 80, 0, 0, 8, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 2, 0, 70, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, + 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 62, 0, + 0, 1, 21, 0, 0, 1, 54, 0, 0, 4, 50, 0, 16, 0, 0, 0, 0, 0, 70, + 0, 2, 0, 54, 0, 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, + 8, 114, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, + 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, + 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 28, 0, 0, 5, 114, 0, + 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 18, + 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 38, 125, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 34, 0, 16, 0, 1, 0, 0, + 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 8, 66, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, + 0, 0, 0, 150, 124, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, + 130, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 135, 22, 153, 62, 162, 69, 22, 63, 213, 120, 233, 61, 0, 0, 0, 0, 164, 0, + 0, 7, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 5, 2, 0, 70, + 14, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, + 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_table_fxaa_luma_ps.h b/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_table_fxaa_luma_ps.h new file mode 100644 index 0000000..5b0d716 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_table_fxaa_luma_ps.h @@ -0,0 +1,101 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_apply_gamma_ramp texture float4 buf T0 t0 1 +// xe_apply_gamma_source texture float4 2d T1 t1 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// +ps_5_1 +dcl_globalFlags refactoringAllowed +dcl_resource_buffer (float,float,float,float) T0[0:0], space=0 +dcl_resource_texture2d (float,float,float,float) T1[1:1], space=0 +dcl_input_ps_siv linear noperspective v0.xy, position +dcl_output o0.xyzw +dcl_temps 2 +ftou r0.xy, v0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyz, r0.xyzw, T1[1].xyzw +mad r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) +ftou r0.xyz, r0.xyzx +ld r1.x, r0.xxxx, T0[0].zxyw +ld r1.y, r0.yyyy, T0[0].xyzw +ld r1.z, r0.zzzz, T0[0].yzxw +dp3 o0.w, r1.xyzx, l(0.299000, 0.587000, 0.114000, 0.000000) +mov o0.xyz, r1.xyzx +ret +// Approximately 11 instruction slots used +#endif + +const BYTE apply_gamma_table_fxaa_luma_ps[] = { + 68, 88, 66, 67, 99, 93, 21, 205, 152, 99, 210, 93, 126, 200, 23, 156, 88, 34, 136, + 17, 1, 0, 0, 0, 212, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 28, 1, + 0, 0, 80, 1, 0, 0, 132, 1, 0, 0, 56, 3, 0, 0, 82, 68, 69, 70, 224, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 255, 255, 0, 5, 0, 0, 182, 0, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, + 0, 4, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 120, 101, 95, 97, 112, 112, 108, 121, 95, + 103, 97, 109, 109, 97, 95, 114, 97, 109, 112, 0, 120, 101, 95, 97, 112, 112, 108, 121, + 95, 103, 97, 109, 109, 97, 95, 115, 111, 117, 114, 99, 101, 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, + 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 73, + 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 3, 0, + 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 79, 83, 71, 78, 44, 0, + 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, + 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 69, 88, 172, 1, 0, 0, 81, 0, 0, + 0, 107, 0, 0, 0, 106, 8, 0, 1, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 0, 0, 0, 0, 0, 0, 88, + 24, 0, 7, 70, 126, 48, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 85, 85, 0, 0, 0, 0, 0, 0, 100, 32, 0, 4, 50, 16, 16, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 2, 0, 0, 0, 28, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, + 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 45, 0, 0, 8, 114, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 70, 126, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 50, 0, 0, 15, 114, + 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 28, 0, + 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 45, + 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, + 38, 125, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 34, 0, 16, + 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 66, 0, 16, 0, 1, 0, 0, 0, 166, + 10, 16, 0, 0, 0, 0, 0, 150, 124, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 10, 130, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 135, 22, 153, 62, 162, 69, 22, 63, 213, 120, 233, 61, 0, 0, + 0, 0, 54, 0, 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 1, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 11, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_table_ps.h b/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_table_ps.h new file mode 100644 index 0000000..f702254 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/apply_gamma_table_ps.h @@ -0,0 +1,100 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_apply_gamma_ramp texture float4 buf T0 t0 1 +// xe_apply_gamma_source texture float4 2d T1 t1 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// +ps_5_1 +dcl_globalFlags refactoringAllowed +dcl_resource_buffer (float,float,float,float) T0[0:0], space=0 +dcl_resource_texture2d (float,float,float,float) T1[1:1], space=0 +dcl_input_ps_siv linear noperspective v0.xy, position +dcl_output o0.xyzw +dcl_temps 1 +ftou r0.xy, v0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyz, r0.xyzw, T1[1].xyzw +mad r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) +ftou r0.xyz, r0.xyzx +ld r0.x, r0.xxxx, T0[0].zxyw +ld r0.y, r0.yyyy, T0[0].xyzw +ld r0.z, r0.zzzz, T0[0].yzxw +mov o0.xyz, r0.xyzx +mov o0.w, l(1.000000) +ret +// Approximately 11 instruction slots used +#endif + +const BYTE apply_gamma_table_ps[] = { + 68, 88, 66, 67, 74, 64, 188, 148, 1, 73, 166, 187, 95, 221, 233, 140, 224, 9, 117, + 169, 1, 0, 0, 0, 192, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 28, 1, + 0, 0, 80, 1, 0, 0, 132, 1, 0, 0, 36, 3, 0, 0, 82, 68, 69, 70, 224, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 255, 255, 0, 5, 0, 0, 182, 0, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, + 0, 4, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 120, 101, 95, 97, 112, 112, 108, 121, 95, + 103, 97, 109, 109, 97, 95, 114, 97, 109, 112, 0, 120, 101, 95, 97, 112, 112, 108, 121, + 95, 103, 97, 109, 109, 97, 95, 115, 111, 117, 114, 99, 101, 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, + 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 73, + 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 3, 0, + 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 79, 83, 71, 78, 44, 0, + 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, + 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 69, 88, 152, 1, 0, 0, 81, 0, 0, + 0, 102, 0, 0, 0, 106, 8, 0, 1, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 0, 0, 0, 0, 0, 0, 88, + 24, 0, 7, 70, 126, 48, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 85, 85, 0, 0, 0, 0, 0, 0, 100, 32, 0, 4, 50, 16, 16, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 28, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, + 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 45, 0, 0, 8, 114, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 70, 126, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 50, 0, 0, 15, 114, + 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 28, 0, + 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 45, + 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, + 38, 125, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 34, 0, 16, + 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 166, + 10, 16, 0, 0, 0, 0, 0, 150, 124, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, + 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 11, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/clear_uint2_ps.h b/src/graphics/shaders/bytecode/d3d12_5_1/clear_uint2_ps.h new file mode 100644 index 0000000..598e3a7 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/clear_uint2_ps.h @@ -0,0 +1,80 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer XeClearConstants +// { +// +// uint2 xe_clear_value; // Offset: 0 Size: 8 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// XeClearConstants cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xy 0 TARGET uint xy +// +ps_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_output o0.xy +mov o0.xy, CB0[0][0].xyxx +ret +// Approximately 2 instruction slots used +#endif + +const BYTE clear_uint2_ps[] = { + 68, 88, 66, 67, 90, 79, 67, 15, 17, 175, 210, 170, 189, 222, 209, 228, 62, 31, 153, + 246, 1, 0, 0, 0, 148, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 88, 1, + 0, 0, 104, 1, 0, 0, 156, 1, 0, 0, 248, 1, 0, 0, 82, 68, 69, 70, 28, + 1, 0, 0, 1, 0, 0, 0, 120, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 255, 255, 0, 5, 0, 0, 244, 0, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 88, 101, 67, 108, 101, 97, 114, 67, 111, 110, 115, + 116, 97, 110, 116, 115, 0, 171, 171, 171, 100, 0, 0, 0, 1, 0, 0, 0, 144, 0, + 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 184, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 208, 0, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, + 99, 108, 101, 97, 114, 95, 118, 97, 108, 117, 101, 0, 117, 105, 110, 116, 50, 0, 171, + 171, 171, 1, 0, 19, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 199, 0, 0, 0, + 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, + 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, + 49, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, + 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, + 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 69, 88, 84, 0, + 0, 0, 81, 0, 0, 0, 21, 0, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, + 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 7, 50, 32, 16, 0, 0, 0, 0, 0, 70, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/continuous_quad_1cp_hs.h b/src/graphics/shaders/bytecode/d3d12_5_1/continuous_quad_1cp_hs.h new file mode 100644 index 0000000..61c9042 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/continuous_quad_1cp_hs.h @@ -0,0 +1,312 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer xe_system_cbuffer +// { +// +// uint xe_flags; // Offset: 0 Size: 4 [unused] +// float2 xe_tessellation_factor_range;// Offset: 4 Size: 8 +// uint xe_line_loop_closing_index; // Offset: 12 Size: 4 [unused] +// uint xe_vertex_index_endian; // Offset: 16 Size: 4 [unused] +// uint xe_vertex_index_offset; // Offset: 20 Size: 4 [unused] +// uint2 xe_vertex_index_min_max; // Offset: 24 Size: 8 [unused] +// float4 xe_user_clip_planes[6]; // Offset: 32 Size: 96 [unused] +// float3 xe_ndc_scale; // Offset: 128 Size: 12 [unused] +// float xe_point_vertex_diameter_min;// Offset: 140 Size: 4 [unused] +// float3 xe_ndc_offset; // Offset: 144 Size: 12 [unused] +// float xe_point_vertex_diameter_max;// Offset: 156 Size: 4 [unused] +// float2 xe_point_constant_diameter; // Offset: 160 Size: 8 [unused] +// float2 xe_point_screen_diameter_to_ndc_radius;// Offset: 168 Size: 8 [unused] +// uint4 xe_texture_swizzled_signs[2];// Offset: 176 Size: 32 [unused] +// uint xe_textures_resolved; // Offset: 208 Size: 4 [unused] +// uint2 xe_sample_count_log2; // Offset: 212 Size: 8 [unused] +// float xe_alpha_test_reference; // Offset: 220 Size: 4 [unused] +// uint xe_alpha_to_mask; // Offset: 224 Size: 4 [unused] +// uint xe_edram_32bpp_tile_pitch_dwords_scaled;// Offset: 228 Size: 4 [unused] +// uint xe_edram_depth_base_dwords_scaled;// Offset: 232 Size: 4 [unused] +// float4 xe_color_exp_bias; // Offset: 240 Size: 16 [unused] +// float2 xe_edram_poly_offset_front; // Offset: 256 Size: 8 [unused] +// float2 xe_edram_poly_offset_back; // Offset: 264 Size: 8 [unused] +// uint4 xe_edram_stencil[2]; // Offset: 272 Size: 32 [unused] +// uint4 xe_edram_rt_base_dwords_scaled;// Offset: 304 Size: 16 [unused] +// uint4 xe_edram_rt_format_flags; // Offset: 320 Size: 16 [unused] +// float4 xe_edram_rt_clamp[4]; // Offset: 336 Size: 64 [unused] +// uint4 xe_edram_rt_keep_mask[2]; // Offset: 400 Size: 32 [unused] +// uint4 xe_edram_rt_blend_factors_ops;// Offset: 432 Size: 16 [unused] +// float4 xe_edram_blend_constant; // Offset: 448 Size: 16 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_system_cbuffer cbuffer NA NA CB0 cb0 1 +// +// +// +// Patch Constant signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TessFactor 0 x 0 QUADEDGE float x +// SV_TessFactor 1 x 1 QUADEDGE float x +// SV_TessFactor 2 x 2 QUADEDGE float x +// SV_TessFactor 3 x 3 QUADEDGE float x +// SV_InsideTessFactor 0 x 4 QUADINT float x +// SV_InsideTessFactor 1 x 5 QUADINT float x +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE float x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE float x +// +// Tessellation Domain # of control points +// -------------------- -------------------- +// Quadrilateral 1 +// +// Tessellation Output Primitive Partitioning Type +// ------------------------------ ------------------ +// Clockwise Triangles Even Fractional +// +hs_5_1 +hs_decls +dcl_input_control_point_count 1 +dcl_output_control_point_count 1 +dcl_tessellator_domain domain_quad +dcl_tessellator_partitioning partitioning_fractional_even +dcl_tessellator_output_primitive output_triangle_cw +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +hs_control_point_phase +dcl_input v[1][0].x +dcl_output o0.x +mov o0.x, v[0][0].x +ret +hs_fork_phase +dcl_hs_fork_phase_instance_count 4 +dcl_input vForkInstanceID +dcl_output_siv o0.x, finalQuadUeq0EdgeTessFactor +dcl_output_siv o1.x, finalQuadVeq0EdgeTessFactor +dcl_output_siv o2.x, finalQuadUeq1EdgeTessFactor +dcl_output_siv o3.x, finalQuadVeq1EdgeTessFactor +dcl_temps 1 +dcl_indexrange o0.x 4 +mov r0.x, vForkInstanceID.x +mov o[r0.x + 0].x, CB0[0][0].z +ret +hs_fork_phase +dcl_hs_fork_phase_instance_count 2 +dcl_input vForkInstanceID +dcl_output_siv o4.x, finalQuadUInsideTessFactor +dcl_output_siv o5.x, finalQuadVInsideTessFactor +dcl_temps 1 +dcl_indexrange o4.x 2 +mov r0.x, vForkInstanceID.x +mov o[r0.x + 4].x, CB0[0][0].z +ret +// Approximately 8 instruction slots used +#endif + +const BYTE continuous_quad_1cp_hs[] = { + 68, 88, 66, 67, 255, 166, 36, 40, 167, 89, 99, 45, 74, 91, 165, 30, 112, 56, 14, + 246, 1, 0, 0, 0, 220, 13, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 108, 10, + 0, 0, 160, 10, 0, 0, 212, 10, 0, 0, 152, 11, 0, 0, 64, 13, 0, 0, 82, + 68, 69, 70, 44, 10, 0, 0, 1, 0, 0, 0, 120, 0, 0, 0, 1, 0, 0, 0, + 60, 0, 0, 0, 1, 5, 83, 72, 0, 5, 0, 0, 2, 10, 0, 0, 19, 19, 68, + 37, 60, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 115, 121, 115, 116, + 101, 109, 95, 99, 98, 117, 102, 102, 101, 114, 0, 171, 171, 100, 0, 0, 0, 30, 0, + 0, 0, 144, 0, 0, 0, 208, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, + 5, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 116, 5, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 152, 5, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 188, 5, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 215, 5, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 238, 5, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 5, 6, 0, 0, 24, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 72, 6, 0, 0, 32, 0, 0, 0, + 96, 0, 0, 0, 0, 0, 0, 0, 100, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 136, 6, 0, 0, 128, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 6, 0, 0, + 140, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 8, 7, + 0, 0, 144, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 22, 7, 0, 0, 156, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 51, 7, 0, 0, 160, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, + 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 78, 7, 0, 0, 168, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 117, 7, 0, 0, 176, 0, 0, 0, 32, 0, 0, 0, 0, + 0, 0, 0, 152, 7, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 188, 7, 0, 0, 208, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 209, 7, 0, 0, 212, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 230, 7, 0, 0, 220, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 254, 7, 0, 0, 224, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 8, 0, + 0, 228, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 55, + 8, 0, 0, 232, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 89, 8, 0, 0, 240, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 144, 8, 0, 0, 0, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 171, 8, 0, 0, 8, 1, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 197, 8, 0, 0, 16, 1, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 216, 8, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 252, 8, 0, 0, 48, 1, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 64, 9, 0, 0, 64, 1, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 89, 9, 0, 0, 80, 1, + 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 108, 9, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 144, 9, 0, 0, + 144, 1, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 168, 9, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 204, 9, + 0, 0, 176, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 234, 9, 0, 0, 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 120, 101, 95, 102, 108, 97, 103, 115, 0, 100, 119, 111, 114, 100, 0, 171, 0, + 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 5, 0, 0, 120, 101, 95, + 116, 101, 115, 115, 101, 108, 108, 97, 116, 105, 111, 110, 95, 102, 97, 99, 116, 111, 114, + 95, 114, 97, 110, 103, 101, 0, 102, 108, 111, 97, 116, 50, 0, 1, 0, 3, 0, 1, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 145, 5, 0, 0, 120, 101, 95, 108, 105, 110, 101, + 95, 108, 111, 111, 112, 95, 99, 108, 111, 115, 105, 110, 103, 95, 105, 110, 100, 101, 120, + 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, 120, 95, 101, 110, + 100, 105, 97, 110, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, + 120, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, + 105, 110, 100, 101, 120, 95, 109, 105, 110, 95, 109, 97, 120, 0, 117, 105, 110, 116, 50, + 0, 171, 1, 0, 19, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 6, 0, 0, + 120, 101, 95, 117, 115, 101, 114, 95, 99, 108, 105, 112, 95, 112, 108, 97, 110, 101, 115, + 0, 102, 108, 111, 97, 116, 52, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 110, 100, 99, 95, 115, 99, 97, 108, 101, + 0, 102, 108, 111, 97, 116, 51, 0, 1, 0, 3, 0, 1, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 149, 6, 0, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, + 101, 120, 95, 100, 105, 97, 109, 101, 116, 101, 114, 95, 109, 105, 110, 0, 102, 108, 111, + 97, 116, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 6, + 0, 0, 120, 101, 95, 110, 100, 99, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, 101, 120, 95, 100, 105, 97, 109, 101, 116, + 101, 114, 95, 109, 97, 120, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 99, 111, 110, + 115, 116, 97, 110, 116, 95, 100, 105, 97, 109, 101, 116, 101, 114, 0, 120, 101, 95, 112, + 111, 105, 110, 116, 95, 115, 99, 114, 101, 101, 110, 95, 100, 105, 97, 109, 101, 116, 101, + 114, 95, 116, 111, 95, 110, 100, 99, 95, 114, 97, 100, 105, 117, 115, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 115, 119, 105, 122, 122, 108, 101, 100, 95, 115, 105, + 103, 110, 115, 0, 117, 105, 110, 116, 52, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, + 4, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, + 114, 101, 115, 95, 114, 101, 115, 111, 108, 118, 101, 100, 0, 120, 101, 95, 115, 97, 109, + 112, 108, 101, 95, 99, 111, 117, 110, 116, 95, 108, 111, 103, 50, 0, 120, 101, 95, 97, + 108, 112, 104, 97, 95, 116, 101, 115, 116, 95, 114, 101, 102, 101, 114, 101, 110, 99, 101, + 0, 120, 101, 95, 97, 108, 112, 104, 97, 95, 116, 111, 95, 109, 97, 115, 107, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 51, 50, 98, 112, 112, 95, 116, 105, 108, 101, 95, + 112, 105, 116, 99, 104, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 100, 101, 112, 116, 104, 95, 98, 97, 115, + 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, 0, 120, 101, 95, + 99, 111, 108, 111, 114, 95, 101, 120, 112, 95, 98, 105, 97, 115, 0, 171, 1, 0, 3, + 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 101, 100, + 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, 102, 115, 101, 116, 95, 102, 114, 111, + 110, 116, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, + 102, 115, 101, 116, 95, 98, 97, 99, 107, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, + 115, 116, 101, 110, 99, 105, 108, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, + 95, 98, 97, 115, 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, + 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 102, 111, 114, 109, 97, 116, 95, + 102, 108, 97, 103, 115, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 99, + 108, 97, 109, 112, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 92, 6, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 107, 101, 101, + 112, 95, 109, 97, 115, 107, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, + 98, 108, 101, 110, 100, 95, 102, 97, 99, 116, 111, 114, 115, 95, 111, 112, 115, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 98, 108, 101, 110, 100, 95, 99, 111, 110, 115, 116, + 97, 110, 116, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, + 32, 49, 48, 46, 49, 0, 171, 171, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, + 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 88, 69, 86, 69, 82, 84, 69, 88, 73, + 68, 0, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 1, 14, 0, 0, 88, 69, 86, 69, 82, 84, 69, 88, 73, 68, 0, 171, 80, 67, + 83, 71, 188, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 152, 0, 0, 0, 0, + 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 14, 0, 0, + 152, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, + 0, 1, 14, 0, 0, 152, 0, 0, 0, 2, 0, 0, 0, 11, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 1, 14, 0, 0, 152, 0, 0, 0, 3, 0, 0, 0, 11, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 14, 0, 0, 166, 0, 0, 0, + 0, 0, 0, 0, 12, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 14, 0, + 0, 166, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 3, 0, 0, 0, 5, 0, + 0, 0, 1, 14, 0, 0, 83, 86, 95, 84, 101, 115, 115, 70, 97, 99, 116, 111, 114, + 0, 83, 86, 95, 73, 110, 115, 105, 100, 101, 84, 101, 115, 115, 70, 97, 99, 116, 111, + 114, 0, 171, 171, 83, 72, 69, 88, 160, 1, 0, 0, 81, 0, 3, 0, 104, 0, 0, + 0, 113, 0, 0, 1, 147, 8, 0, 1, 148, 8, 0, 1, 149, 24, 0, 1, 150, 32, + 0, 1, 151, 24, 0, 1, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 114, 0, 0, 1, 95, 0, 0, 4, 18, 16, 32, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 101, 0, 0, 3, 18, 32, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 32, + 16, 0, 0, 0, 0, 0, 10, 16, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, + 0, 0, 1, 115, 0, 0, 1, 153, 0, 0, 2, 4, 0, 0, 0, 95, 0, 0, 2, + 0, 112, 1, 0, 103, 0, 0, 4, 18, 32, 16, 0, 0, 0, 0, 0, 11, 0, 0, + 0, 103, 0, 0, 4, 18, 32, 16, 0, 1, 0, 0, 0, 12, 0, 0, 0, 103, 0, + 0, 4, 18, 32, 16, 0, 2, 0, 0, 0, 13, 0, 0, 0, 103, 0, 0, 4, 18, + 32, 16, 0, 3, 0, 0, 0, 14, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, + 91, 0, 0, 4, 18, 32, 16, 0, 0, 0, 0, 0, 4, 0, 0, 0, 54, 0, 0, + 4, 18, 0, 16, 0, 0, 0, 0, 0, 10, 112, 1, 0, 54, 0, 0, 8, 18, 32, + 144, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 115, 0, 0, 1, 153, 0, 0, 2, + 2, 0, 0, 0, 95, 0, 0, 2, 0, 112, 1, 0, 103, 0, 0, 4, 18, 32, 16, + 0, 4, 0, 0, 0, 15, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 5, 0, + 0, 0, 16, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 91, 0, 0, 4, 18, + 32, 16, 0, 4, 0, 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 112, 1, 0, 54, 0, 0, 9, 18, 32, 208, 0, 4, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/continuous_quad_4cp_hs.h b/src/graphics/shaders/bytecode/d3d12_5_1/continuous_quad_4cp_hs.h new file mode 100644 index 0000000..a01e1f3 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/continuous_quad_4cp_hs.h @@ -0,0 +1,304 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer xe_system_cbuffer +// { +// +// uint xe_flags; // Offset: 0 Size: 4 [unused] +// float2 xe_tessellation_factor_range;// Offset: 4 Size: 8 +// uint xe_line_loop_closing_index; // Offset: 12 Size: 4 [unused] +// uint xe_vertex_index_endian; // Offset: 16 Size: 4 [unused] +// uint xe_vertex_index_offset; // Offset: 20 Size: 4 [unused] +// uint2 xe_vertex_index_min_max; // Offset: 24 Size: 8 [unused] +// float4 xe_user_clip_planes[6]; // Offset: 32 Size: 96 [unused] +// float3 xe_ndc_scale; // Offset: 128 Size: 12 [unused] +// float xe_point_vertex_diameter_min;// Offset: 140 Size: 4 [unused] +// float3 xe_ndc_offset; // Offset: 144 Size: 12 [unused] +// float xe_point_vertex_diameter_max;// Offset: 156 Size: 4 [unused] +// float2 xe_point_constant_diameter; // Offset: 160 Size: 8 [unused] +// float2 xe_point_screen_diameter_to_ndc_radius;// Offset: 168 Size: 8 [unused] +// uint4 xe_texture_swizzled_signs[2];// Offset: 176 Size: 32 [unused] +// uint xe_textures_resolved; // Offset: 208 Size: 4 [unused] +// uint2 xe_sample_count_log2; // Offset: 212 Size: 8 [unused] +// float xe_alpha_test_reference; // Offset: 220 Size: 4 [unused] +// uint xe_alpha_to_mask; // Offset: 224 Size: 4 [unused] +// uint xe_edram_32bpp_tile_pitch_dwords_scaled;// Offset: 228 Size: 4 [unused] +// uint xe_edram_depth_base_dwords_scaled;// Offset: 232 Size: 4 [unused] +// float4 xe_color_exp_bias; // Offset: 240 Size: 16 [unused] +// float2 xe_edram_poly_offset_front; // Offset: 256 Size: 8 [unused] +// float2 xe_edram_poly_offset_back; // Offset: 264 Size: 8 [unused] +// uint4 xe_edram_stencil[2]; // Offset: 272 Size: 32 [unused] +// uint4 xe_edram_rt_base_dwords_scaled;// Offset: 304 Size: 16 [unused] +// uint4 xe_edram_rt_format_flags; // Offset: 320 Size: 16 [unused] +// float4 xe_edram_rt_clamp[4]; // Offset: 336 Size: 64 [unused] +// uint4 xe_edram_rt_keep_mask[2]; // Offset: 400 Size: 32 [unused] +// uint4 xe_edram_rt_blend_factors_ops;// Offset: 432 Size: 16 [unused] +// float4 xe_edram_blend_constant; // Offset: 448 Size: 16 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_system_cbuffer cbuffer NA NA CB0 cb0 1 +// +// +// +// Patch Constant signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TessFactor 0 x 0 QUADEDGE float x +// SV_TessFactor 1 x 1 QUADEDGE float x +// SV_TessFactor 2 x 2 QUADEDGE float x +// SV_TessFactor 3 x 3 QUADEDGE float x +// SV_InsideTessFactor 0 x 4 QUADINT float x +// SV_InsideTessFactor 1 x 5 QUADINT float x +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE float x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE float x +// +// Tessellation Domain # of control points +// -------------------- -------------------- +// Quadrilateral 4 +// +// Tessellation Output Primitive Partitioning Type +// ------------------------------ ------------------ +// Clockwise Triangles Even Fractional +// +hs_5_1 +hs_decls +dcl_input_control_point_count 4 +dcl_output_control_point_count 4 +dcl_tessellator_domain domain_quad +dcl_tessellator_partitioning partitioning_fractional_even +dcl_tessellator_output_primitive output_triangle_cw +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +hs_fork_phase +dcl_hs_fork_phase_instance_count 4 +dcl_input vForkInstanceID +dcl_output_siv o0.x, finalQuadUeq0EdgeTessFactor +dcl_output_siv o1.x, finalQuadVeq0EdgeTessFactor +dcl_output_siv o2.x, finalQuadUeq1EdgeTessFactor +dcl_output_siv o3.x, finalQuadVeq1EdgeTessFactor +dcl_temps 1 +dcl_indexrange o0.x 4 +mov r0.x, vForkInstanceID.x +mov o[r0.x + 0].x, CB0[0][0].z +ret +hs_fork_phase +dcl_hs_fork_phase_instance_count 2 +dcl_input vForkInstanceID +dcl_output_siv o4.x, finalQuadUInsideTessFactor +dcl_output_siv o5.x, finalQuadVInsideTessFactor +dcl_temps 1 +dcl_indexrange o4.x 2 +mov r0.x, vForkInstanceID.x +mov o[r0.x + 4].x, CB0[0][0].z +ret +// Approximately 6 instruction slots used +#endif + +const BYTE continuous_quad_4cp_hs[] = { + 68, 88, 66, 67, 196, 234, 51, 156, 242, 124, 98, 132, 34, 110, 229, 40, 64, 181, 146, + 55, 1, 0, 0, 0, 160, 13, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 108, 10, + 0, 0, 160, 10, 0, 0, 212, 10, 0, 0, 152, 11, 0, 0, 4, 13, 0, 0, 82, + 68, 69, 70, 44, 10, 0, 0, 1, 0, 0, 0, 120, 0, 0, 0, 1, 0, 0, 0, + 60, 0, 0, 0, 1, 5, 83, 72, 0, 5, 0, 0, 2, 10, 0, 0, 19, 19, 68, + 37, 60, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 115, 121, 115, 116, + 101, 109, 95, 99, 98, 117, 102, 102, 101, 114, 0, 171, 171, 100, 0, 0, 0, 30, 0, + 0, 0, 144, 0, 0, 0, 208, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, + 5, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 116, 5, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 152, 5, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 188, 5, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 215, 5, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 238, 5, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 5, 6, 0, 0, 24, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 72, 6, 0, 0, 32, 0, 0, 0, + 96, 0, 0, 0, 0, 0, 0, 0, 100, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 136, 6, 0, 0, 128, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 6, 0, 0, + 140, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 8, 7, + 0, 0, 144, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 22, 7, 0, 0, 156, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 51, 7, 0, 0, 160, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, + 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 78, 7, 0, 0, 168, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 117, 7, 0, 0, 176, 0, 0, 0, 32, 0, 0, 0, 0, + 0, 0, 0, 152, 7, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 188, 7, 0, 0, 208, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 209, 7, 0, 0, 212, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 230, 7, 0, 0, 220, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 254, 7, 0, 0, 224, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 8, 0, + 0, 228, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 55, + 8, 0, 0, 232, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 89, 8, 0, 0, 240, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 144, 8, 0, 0, 0, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 171, 8, 0, 0, 8, 1, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 197, 8, 0, 0, 16, 1, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 216, 8, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 252, 8, 0, 0, 48, 1, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 64, 9, 0, 0, 64, 1, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 89, 9, 0, 0, 80, 1, + 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 108, 9, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 144, 9, 0, 0, + 144, 1, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 168, 9, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 204, 9, + 0, 0, 176, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 234, 9, 0, 0, 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 120, 101, 95, 102, 108, 97, 103, 115, 0, 100, 119, 111, 114, 100, 0, 171, 0, + 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 5, 0, 0, 120, 101, 95, + 116, 101, 115, 115, 101, 108, 108, 97, 116, 105, 111, 110, 95, 102, 97, 99, 116, 111, 114, + 95, 114, 97, 110, 103, 101, 0, 102, 108, 111, 97, 116, 50, 0, 1, 0, 3, 0, 1, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 145, 5, 0, 0, 120, 101, 95, 108, 105, 110, 101, + 95, 108, 111, 111, 112, 95, 99, 108, 111, 115, 105, 110, 103, 95, 105, 110, 100, 101, 120, + 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, 120, 95, 101, 110, + 100, 105, 97, 110, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, + 120, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, + 105, 110, 100, 101, 120, 95, 109, 105, 110, 95, 109, 97, 120, 0, 117, 105, 110, 116, 50, + 0, 171, 1, 0, 19, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 6, 0, 0, + 120, 101, 95, 117, 115, 101, 114, 95, 99, 108, 105, 112, 95, 112, 108, 97, 110, 101, 115, + 0, 102, 108, 111, 97, 116, 52, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 110, 100, 99, 95, 115, 99, 97, 108, 101, + 0, 102, 108, 111, 97, 116, 51, 0, 1, 0, 3, 0, 1, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 149, 6, 0, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, + 101, 120, 95, 100, 105, 97, 109, 101, 116, 101, 114, 95, 109, 105, 110, 0, 102, 108, 111, + 97, 116, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 6, + 0, 0, 120, 101, 95, 110, 100, 99, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, 101, 120, 95, 100, 105, 97, 109, 101, 116, + 101, 114, 95, 109, 97, 120, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 99, 111, 110, + 115, 116, 97, 110, 116, 95, 100, 105, 97, 109, 101, 116, 101, 114, 0, 120, 101, 95, 112, + 111, 105, 110, 116, 95, 115, 99, 114, 101, 101, 110, 95, 100, 105, 97, 109, 101, 116, 101, + 114, 95, 116, 111, 95, 110, 100, 99, 95, 114, 97, 100, 105, 117, 115, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 115, 119, 105, 122, 122, 108, 101, 100, 95, 115, 105, + 103, 110, 115, 0, 117, 105, 110, 116, 52, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, + 4, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, + 114, 101, 115, 95, 114, 101, 115, 111, 108, 118, 101, 100, 0, 120, 101, 95, 115, 97, 109, + 112, 108, 101, 95, 99, 111, 117, 110, 116, 95, 108, 111, 103, 50, 0, 120, 101, 95, 97, + 108, 112, 104, 97, 95, 116, 101, 115, 116, 95, 114, 101, 102, 101, 114, 101, 110, 99, 101, + 0, 120, 101, 95, 97, 108, 112, 104, 97, 95, 116, 111, 95, 109, 97, 115, 107, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 51, 50, 98, 112, 112, 95, 116, 105, 108, 101, 95, + 112, 105, 116, 99, 104, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 100, 101, 112, 116, 104, 95, 98, 97, 115, + 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, 0, 120, 101, 95, + 99, 111, 108, 111, 114, 95, 101, 120, 112, 95, 98, 105, 97, 115, 0, 171, 1, 0, 3, + 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 101, 100, + 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, 102, 115, 101, 116, 95, 102, 114, 111, + 110, 116, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, + 102, 115, 101, 116, 95, 98, 97, 99, 107, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, + 115, 116, 101, 110, 99, 105, 108, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, + 95, 98, 97, 115, 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, + 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 102, 111, 114, 109, 97, 116, 95, + 102, 108, 97, 103, 115, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 99, + 108, 97, 109, 112, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 92, 6, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 107, 101, 101, + 112, 95, 109, 97, 115, 107, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, + 98, 108, 101, 110, 100, 95, 102, 97, 99, 116, 111, 114, 115, 95, 111, 112, 115, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 98, 108, 101, 110, 100, 95, 99, 111, 110, 115, 116, + 97, 110, 116, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, + 32, 49, 48, 46, 49, 0, 171, 171, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, + 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 88, 69, 86, 69, 82, 84, 69, 88, 73, + 68, 0, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 1, 14, 0, 0, 88, 69, 86, 69, 82, 84, 69, 88, 73, 68, 0, 171, 80, 67, + 83, 71, 188, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 152, 0, 0, 0, 0, + 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 14, 0, 0, + 152, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, + 0, 1, 14, 0, 0, 152, 0, 0, 0, 2, 0, 0, 0, 11, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 1, 14, 0, 0, 152, 0, 0, 0, 3, 0, 0, 0, 11, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 14, 0, 0, 166, 0, 0, 0, + 0, 0, 0, 0, 12, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 14, 0, + 0, 166, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 3, 0, 0, 0, 5, 0, + 0, 0, 1, 14, 0, 0, 83, 86, 95, 84, 101, 115, 115, 70, 97, 99, 116, 111, 114, + 0, 83, 86, 95, 73, 110, 115, 105, 100, 101, 84, 101, 115, 115, 70, 97, 99, 116, 111, + 114, 0, 171, 171, 83, 72, 69, 88, 100, 1, 0, 0, 81, 0, 3, 0, 89, 0, 0, + 0, 113, 0, 0, 1, 147, 32, 0, 1, 148, 32, 0, 1, 149, 24, 0, 1, 150, 32, + 0, 1, 151, 24, 0, 1, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 115, 0, 0, 1, 153, 0, 0, 2, 4, 0, 0, 0, 95, 0, 0, 2, 0, 112, 1, + 0, 103, 0, 0, 4, 18, 32, 16, 0, 0, 0, 0, 0, 11, 0, 0, 0, 103, 0, + 0, 4, 18, 32, 16, 0, 1, 0, 0, 0, 12, 0, 0, 0, 103, 0, 0, 4, 18, + 32, 16, 0, 2, 0, 0, 0, 13, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, + 3, 0, 0, 0, 14, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 91, 0, 0, + 4, 18, 32, 16, 0, 0, 0, 0, 0, 4, 0, 0, 0, 54, 0, 0, 4, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 112, 1, 0, 54, 0, 0, 8, 18, 32, 144, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 62, 0, 0, 1, 115, 0, 0, 1, 153, 0, 0, 2, 2, 0, 0, + 0, 95, 0, 0, 2, 0, 112, 1, 0, 103, 0, 0, 4, 18, 32, 16, 0, 4, 0, + 0, 0, 15, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 5, 0, 0, 0, 16, + 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 91, 0, 0, 4, 18, 32, 16, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 112, 1, 0, 54, 0, 0, 9, 18, 32, 208, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 6, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/continuous_triangle_1cp_hs.h b/src/graphics/shaders/bytecode/d3d12_5_1/continuous_triangle_1cp_hs.h new file mode 100644 index 0000000..d115d9e --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/continuous_triangle_1cp_hs.h @@ -0,0 +1,296 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer xe_system_cbuffer +// { +// +// uint xe_flags; // Offset: 0 Size: 4 [unused] +// float2 xe_tessellation_factor_range;// Offset: 4 Size: 8 +// uint xe_line_loop_closing_index; // Offset: 12 Size: 4 [unused] +// uint xe_vertex_index_endian; // Offset: 16 Size: 4 [unused] +// uint xe_vertex_index_offset; // Offset: 20 Size: 4 [unused] +// uint2 xe_vertex_index_min_max; // Offset: 24 Size: 8 [unused] +// float4 xe_user_clip_planes[6]; // Offset: 32 Size: 96 [unused] +// float3 xe_ndc_scale; // Offset: 128 Size: 12 [unused] +// float xe_point_vertex_diameter_min;// Offset: 140 Size: 4 [unused] +// float3 xe_ndc_offset; // Offset: 144 Size: 12 [unused] +// float xe_point_vertex_diameter_max;// Offset: 156 Size: 4 [unused] +// float2 xe_point_constant_diameter; // Offset: 160 Size: 8 [unused] +// float2 xe_point_screen_diameter_to_ndc_radius;// Offset: 168 Size: 8 [unused] +// uint4 xe_texture_swizzled_signs[2];// Offset: 176 Size: 32 [unused] +// uint xe_textures_resolved; // Offset: 208 Size: 4 [unused] +// uint2 xe_sample_count_log2; // Offset: 212 Size: 8 [unused] +// float xe_alpha_test_reference; // Offset: 220 Size: 4 [unused] +// uint xe_alpha_to_mask; // Offset: 224 Size: 4 [unused] +// uint xe_edram_32bpp_tile_pitch_dwords_scaled;// Offset: 228 Size: 4 [unused] +// uint xe_edram_depth_base_dwords_scaled;// Offset: 232 Size: 4 [unused] +// float4 xe_color_exp_bias; // Offset: 240 Size: 16 [unused] +// float2 xe_edram_poly_offset_front; // Offset: 256 Size: 8 [unused] +// float2 xe_edram_poly_offset_back; // Offset: 264 Size: 8 [unused] +// uint4 xe_edram_stencil[2]; // Offset: 272 Size: 32 [unused] +// uint4 xe_edram_rt_base_dwords_scaled;// Offset: 304 Size: 16 [unused] +// uint4 xe_edram_rt_format_flags; // Offset: 320 Size: 16 [unused] +// float4 xe_edram_rt_clamp[4]; // Offset: 336 Size: 64 [unused] +// uint4 xe_edram_rt_keep_mask[2]; // Offset: 400 Size: 32 [unused] +// uint4 xe_edram_rt_blend_factors_ops;// Offset: 432 Size: 16 [unused] +// float4 xe_edram_blend_constant; // Offset: 448 Size: 16 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_system_cbuffer cbuffer NA NA CB0 cb0 1 +// +// +// +// Patch Constant signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TessFactor 0 x 0 TRIEDGE float x +// SV_TessFactor 1 x 1 TRIEDGE float x +// SV_TessFactor 2 x 2 TRIEDGE float x +// SV_InsideTessFactor 0 x 3 TRIINT float x +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE float x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE float x +// +// Tessellation Domain # of control points +// -------------------- -------------------- +// Triangle 1 +// +// Tessellation Output Primitive Partitioning Type +// ------------------------------ ------------------ +// Clockwise Triangles Even Fractional +// +hs_5_1 +hs_decls +dcl_input_control_point_count 1 +dcl_output_control_point_count 1 +dcl_tessellator_domain domain_tri +dcl_tessellator_partitioning partitioning_fractional_even +dcl_tessellator_output_primitive output_triangle_cw +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +hs_control_point_phase +dcl_input v[1][0].x +dcl_output o0.x +mov o0.x, v[0][0].x +ret +hs_fork_phase +dcl_hs_fork_phase_instance_count 3 +dcl_input vForkInstanceID +dcl_output_siv o0.x, finalTriUeq0EdgeTessFactor +dcl_output_siv o1.x, finalTriVeq0EdgeTessFactor +dcl_output_siv o2.x, finalTriWeq0EdgeTessFactor +dcl_temps 1 +dcl_indexrange o0.x 3 +mov r0.x, vForkInstanceID.x +mov o[r0.x + 0].x, CB0[0][0].z +ret +hs_fork_phase +dcl_output_siv o3.x, finalTriInsideTessFactor +mov o3.x, CB0[0][0].z +ret +// Approximately 7 instruction slots used +#endif + +const BYTE continuous_triangle_1cp_hs[] = { + 68, 88, 66, 67, 90, 24, 246, 119, 168, 170, 239, 21, 106, 76, 181, 188, 133, 81, 250, + 172, 1, 0, 0, 0, 76, 13, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 108, 10, + 0, 0, 160, 10, 0, 0, 212, 10, 0, 0, 104, 11, 0, 0, 176, 12, 0, 0, 82, + 68, 69, 70, 44, 10, 0, 0, 1, 0, 0, 0, 120, 0, 0, 0, 1, 0, 0, 0, + 60, 0, 0, 0, 1, 5, 83, 72, 0, 5, 0, 0, 2, 10, 0, 0, 19, 19, 68, + 37, 60, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 115, 121, 115, 116, + 101, 109, 95, 99, 98, 117, 102, 102, 101, 114, 0, 171, 171, 100, 0, 0, 0, 30, 0, + 0, 0, 144, 0, 0, 0, 208, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, + 5, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 116, 5, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 152, 5, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 188, 5, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 215, 5, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 238, 5, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 5, 6, 0, 0, 24, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 72, 6, 0, 0, 32, 0, 0, 0, + 96, 0, 0, 0, 0, 0, 0, 0, 100, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 136, 6, 0, 0, 128, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 6, 0, 0, + 140, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 8, 7, + 0, 0, 144, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 22, 7, 0, 0, 156, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 51, 7, 0, 0, 160, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, + 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 78, 7, 0, 0, 168, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 117, 7, 0, 0, 176, 0, 0, 0, 32, 0, 0, 0, 0, + 0, 0, 0, 152, 7, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 188, 7, 0, 0, 208, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 209, 7, 0, 0, 212, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 230, 7, 0, 0, 220, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 254, 7, 0, 0, 224, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 8, 0, + 0, 228, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 55, + 8, 0, 0, 232, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 89, 8, 0, 0, 240, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 144, 8, 0, 0, 0, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 171, 8, 0, 0, 8, 1, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 197, 8, 0, 0, 16, 1, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 216, 8, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 252, 8, 0, 0, 48, 1, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 64, 9, 0, 0, 64, 1, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 89, 9, 0, 0, 80, 1, + 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 108, 9, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 144, 9, 0, 0, + 144, 1, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 168, 9, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 204, 9, + 0, 0, 176, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 234, 9, 0, 0, 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 120, 101, 95, 102, 108, 97, 103, 115, 0, 100, 119, 111, 114, 100, 0, 171, 0, + 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 5, 0, 0, 120, 101, 95, + 116, 101, 115, 115, 101, 108, 108, 97, 116, 105, 111, 110, 95, 102, 97, 99, 116, 111, 114, + 95, 114, 97, 110, 103, 101, 0, 102, 108, 111, 97, 116, 50, 0, 1, 0, 3, 0, 1, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 145, 5, 0, 0, 120, 101, 95, 108, 105, 110, 101, + 95, 108, 111, 111, 112, 95, 99, 108, 111, 115, 105, 110, 103, 95, 105, 110, 100, 101, 120, + 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, 120, 95, 101, 110, + 100, 105, 97, 110, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, + 120, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, + 105, 110, 100, 101, 120, 95, 109, 105, 110, 95, 109, 97, 120, 0, 117, 105, 110, 116, 50, + 0, 171, 1, 0, 19, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 6, 0, 0, + 120, 101, 95, 117, 115, 101, 114, 95, 99, 108, 105, 112, 95, 112, 108, 97, 110, 101, 115, + 0, 102, 108, 111, 97, 116, 52, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 110, 100, 99, 95, 115, 99, 97, 108, 101, + 0, 102, 108, 111, 97, 116, 51, 0, 1, 0, 3, 0, 1, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 149, 6, 0, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, + 101, 120, 95, 100, 105, 97, 109, 101, 116, 101, 114, 95, 109, 105, 110, 0, 102, 108, 111, + 97, 116, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 6, + 0, 0, 120, 101, 95, 110, 100, 99, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, 101, 120, 95, 100, 105, 97, 109, 101, 116, + 101, 114, 95, 109, 97, 120, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 99, 111, 110, + 115, 116, 97, 110, 116, 95, 100, 105, 97, 109, 101, 116, 101, 114, 0, 120, 101, 95, 112, + 111, 105, 110, 116, 95, 115, 99, 114, 101, 101, 110, 95, 100, 105, 97, 109, 101, 116, 101, + 114, 95, 116, 111, 95, 110, 100, 99, 95, 114, 97, 100, 105, 117, 115, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 115, 119, 105, 122, 122, 108, 101, 100, 95, 115, 105, + 103, 110, 115, 0, 117, 105, 110, 116, 52, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, + 4, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, + 114, 101, 115, 95, 114, 101, 115, 111, 108, 118, 101, 100, 0, 120, 101, 95, 115, 97, 109, + 112, 108, 101, 95, 99, 111, 117, 110, 116, 95, 108, 111, 103, 50, 0, 120, 101, 95, 97, + 108, 112, 104, 97, 95, 116, 101, 115, 116, 95, 114, 101, 102, 101, 114, 101, 110, 99, 101, + 0, 120, 101, 95, 97, 108, 112, 104, 97, 95, 116, 111, 95, 109, 97, 115, 107, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 51, 50, 98, 112, 112, 95, 116, 105, 108, 101, 95, + 112, 105, 116, 99, 104, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 100, 101, 112, 116, 104, 95, 98, 97, 115, + 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, 0, 120, 101, 95, + 99, 111, 108, 111, 114, 95, 101, 120, 112, 95, 98, 105, 97, 115, 0, 171, 1, 0, 3, + 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 101, 100, + 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, 102, 115, 101, 116, 95, 102, 114, 111, + 110, 116, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, + 102, 115, 101, 116, 95, 98, 97, 99, 107, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, + 115, 116, 101, 110, 99, 105, 108, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, + 95, 98, 97, 115, 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, + 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 102, 111, 114, 109, 97, 116, 95, + 102, 108, 97, 103, 115, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 99, + 108, 97, 109, 112, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 92, 6, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 107, 101, 101, + 112, 95, 109, 97, 115, 107, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, + 98, 108, 101, 110, 100, 95, 102, 97, 99, 116, 111, 114, 115, 95, 111, 112, 115, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 98, 108, 101, 110, 100, 95, 99, 111, 110, 115, 116, + 97, 110, 116, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, + 32, 49, 48, 46, 49, 0, 171, 171, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, + 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 88, 69, 86, 69, 82, 84, 69, 88, 73, + 68, 0, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 1, 14, 0, 0, 88, 69, 86, 69, 82, 84, 69, 88, 73, 68, 0, 171, 80, 67, + 83, 71, 140, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, + 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 14, 0, 0, + 104, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, + 0, 1, 14, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 13, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 1, 14, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 14, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 14, 0, 0, 83, 86, 95, 84, + 101, 115, 115, 70, 97, 99, 116, 111, 114, 0, 83, 86, 95, 73, 110, 115, 105, 100, 101, + 84, 101, 115, 115, 70, 97, 99, 116, 111, 114, 0, 171, 171, 83, 72, 69, 88, 64, 1, + 0, 0, 81, 0, 3, 0, 80, 0, 0, 0, 113, 0, 0, 1, 147, 8, 0, 1, 148, + 8, 0, 1, 149, 16, 0, 1, 150, 32, 0, 1, 151, 24, 0, 1, 106, 8, 0, 1, + 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 114, 0, 0, 1, 95, 0, 0, 4, 18, 16, + 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, 3, 18, 32, 16, 0, 0, + 0, 0, 0, 54, 0, 0, 6, 18, 32, 16, 0, 0, 0, 0, 0, 10, 16, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 115, 0, 0, 1, 153, 0, 0, + 2, 3, 0, 0, 0, 95, 0, 0, 2, 0, 112, 1, 0, 103, 0, 0, 4, 18, 32, + 16, 0, 0, 0, 0, 0, 17, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 1, + 0, 0, 0, 18, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 2, 0, 0, 0, + 19, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 91, 0, 0, 4, 18, 32, 16, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 18, 0, 16, 0, 0, 0, + 0, 0, 10, 112, 1, 0, 54, 0, 0, 8, 18, 32, 144, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 62, 0, 0, 1, 115, 0, 0, 1, 103, 0, 0, 4, 18, 32, 16, 0, 3, 0, 0, + 0, 20, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 3, 0, 0, 0, 42, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, + 84, 65, 84, 148, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/continuous_triangle_3cp_hs.h b/src/graphics/shaders/bytecode/d3d12_5_1/continuous_triangle_3cp_hs.h new file mode 100644 index 0000000..128fcfb --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/continuous_triangle_3cp_hs.h @@ -0,0 +1,287 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer xe_system_cbuffer +// { +// +// uint xe_flags; // Offset: 0 Size: 4 [unused] +// float2 xe_tessellation_factor_range;// Offset: 4 Size: 8 +// uint xe_line_loop_closing_index; // Offset: 12 Size: 4 [unused] +// uint xe_vertex_index_endian; // Offset: 16 Size: 4 [unused] +// uint xe_vertex_index_offset; // Offset: 20 Size: 4 [unused] +// uint2 xe_vertex_index_min_max; // Offset: 24 Size: 8 [unused] +// float4 xe_user_clip_planes[6]; // Offset: 32 Size: 96 [unused] +// float3 xe_ndc_scale; // Offset: 128 Size: 12 [unused] +// float xe_point_vertex_diameter_min;// Offset: 140 Size: 4 [unused] +// float3 xe_ndc_offset; // Offset: 144 Size: 12 [unused] +// float xe_point_vertex_diameter_max;// Offset: 156 Size: 4 [unused] +// float2 xe_point_constant_diameter; // Offset: 160 Size: 8 [unused] +// float2 xe_point_screen_diameter_to_ndc_radius;// Offset: 168 Size: 8 [unused] +// uint4 xe_texture_swizzled_signs[2];// Offset: 176 Size: 32 [unused] +// uint xe_textures_resolved; // Offset: 208 Size: 4 [unused] +// uint2 xe_sample_count_log2; // Offset: 212 Size: 8 [unused] +// float xe_alpha_test_reference; // Offset: 220 Size: 4 [unused] +// uint xe_alpha_to_mask; // Offset: 224 Size: 4 [unused] +// uint xe_edram_32bpp_tile_pitch_dwords_scaled;// Offset: 228 Size: 4 [unused] +// uint xe_edram_depth_base_dwords_scaled;// Offset: 232 Size: 4 [unused] +// float4 xe_color_exp_bias; // Offset: 240 Size: 16 [unused] +// float2 xe_edram_poly_offset_front; // Offset: 256 Size: 8 [unused] +// float2 xe_edram_poly_offset_back; // Offset: 264 Size: 8 [unused] +// uint4 xe_edram_stencil[2]; // Offset: 272 Size: 32 [unused] +// uint4 xe_edram_rt_base_dwords_scaled;// Offset: 304 Size: 16 [unused] +// uint4 xe_edram_rt_format_flags; // Offset: 320 Size: 16 [unused] +// float4 xe_edram_rt_clamp[4]; // Offset: 336 Size: 64 [unused] +// uint4 xe_edram_rt_keep_mask[2]; // Offset: 400 Size: 32 [unused] +// uint4 xe_edram_rt_blend_factors_ops;// Offset: 432 Size: 16 [unused] +// float4 xe_edram_blend_constant; // Offset: 448 Size: 16 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_system_cbuffer cbuffer NA NA CB0 cb0 1 +// +// +// +// Patch Constant signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TessFactor 0 x 0 TRIEDGE float x +// SV_TessFactor 1 x 1 TRIEDGE float x +// SV_TessFactor 2 x 2 TRIEDGE float x +// SV_InsideTessFactor 0 x 3 TRIINT float x +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE float x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE float x +// +// Tessellation Domain # of control points +// -------------------- -------------------- +// Triangle 3 +// +// Tessellation Output Primitive Partitioning Type +// ------------------------------ ------------------ +// Clockwise Triangles Even Fractional +// +hs_5_1 +hs_decls +dcl_input_control_point_count 3 +dcl_output_control_point_count 3 +dcl_tessellator_domain domain_tri +dcl_tessellator_partitioning partitioning_fractional_even +dcl_tessellator_output_primitive output_triangle_cw +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +hs_fork_phase +dcl_hs_fork_phase_instance_count 3 +dcl_input vForkInstanceID +dcl_output_siv o0.x, finalTriUeq0EdgeTessFactor +dcl_output_siv o1.x, finalTriVeq0EdgeTessFactor +dcl_output_siv o2.x, finalTriWeq0EdgeTessFactor +dcl_temps 1 +dcl_indexrange o0.x 3 +mov r0.x, vForkInstanceID.x +mov o[r0.x + 0].x, CB0[0][0].z +ret +hs_fork_phase +dcl_output_siv o3.x, finalTriInsideTessFactor +mov o3.x, CB0[0][0].z +ret +// Approximately 5 instruction slots used +#endif + +const BYTE continuous_triangle_3cp_hs[] = { + 68, 88, 66, 67, 40, 16, 64, 130, 119, 149, 137, 0, 58, 149, 234, 138, 51, 145, 29, + 76, 1, 0, 0, 0, 16, 13, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 108, 10, + 0, 0, 160, 10, 0, 0, 212, 10, 0, 0, 104, 11, 0, 0, 116, 12, 0, 0, 82, + 68, 69, 70, 44, 10, 0, 0, 1, 0, 0, 0, 120, 0, 0, 0, 1, 0, 0, 0, + 60, 0, 0, 0, 1, 5, 83, 72, 0, 5, 0, 0, 2, 10, 0, 0, 19, 19, 68, + 37, 60, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 115, 121, 115, 116, + 101, 109, 95, 99, 98, 117, 102, 102, 101, 114, 0, 171, 171, 100, 0, 0, 0, 30, 0, + 0, 0, 144, 0, 0, 0, 208, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, + 5, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 116, 5, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 152, 5, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 188, 5, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 215, 5, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 238, 5, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 5, 6, 0, 0, 24, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 72, 6, 0, 0, 32, 0, 0, 0, + 96, 0, 0, 0, 0, 0, 0, 0, 100, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 136, 6, 0, 0, 128, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 6, 0, 0, + 140, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 8, 7, + 0, 0, 144, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 22, 7, 0, 0, 156, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 51, 7, 0, 0, 160, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, + 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 78, 7, 0, 0, 168, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 117, 7, 0, 0, 176, 0, 0, 0, 32, 0, 0, 0, 0, + 0, 0, 0, 152, 7, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 188, 7, 0, 0, 208, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 209, 7, 0, 0, 212, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 230, 7, 0, 0, 220, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 254, 7, 0, 0, 224, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 8, 0, + 0, 228, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 55, + 8, 0, 0, 232, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 89, 8, 0, 0, 240, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 144, 8, 0, 0, 0, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 171, 8, 0, 0, 8, 1, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 197, 8, 0, 0, 16, 1, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 216, 8, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 252, 8, 0, 0, 48, 1, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 64, 9, 0, 0, 64, 1, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 89, 9, 0, 0, 80, 1, + 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 108, 9, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 144, 9, 0, 0, + 144, 1, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 168, 9, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 204, 9, + 0, 0, 176, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 234, 9, 0, 0, 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 120, 101, 95, 102, 108, 97, 103, 115, 0, 100, 119, 111, 114, 100, 0, 171, 0, + 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 5, 0, 0, 120, 101, 95, + 116, 101, 115, 115, 101, 108, 108, 97, 116, 105, 111, 110, 95, 102, 97, 99, 116, 111, 114, + 95, 114, 97, 110, 103, 101, 0, 102, 108, 111, 97, 116, 50, 0, 1, 0, 3, 0, 1, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 145, 5, 0, 0, 120, 101, 95, 108, 105, 110, 101, + 95, 108, 111, 111, 112, 95, 99, 108, 111, 115, 105, 110, 103, 95, 105, 110, 100, 101, 120, + 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, 120, 95, 101, 110, + 100, 105, 97, 110, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, + 120, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, + 105, 110, 100, 101, 120, 95, 109, 105, 110, 95, 109, 97, 120, 0, 117, 105, 110, 116, 50, + 0, 171, 1, 0, 19, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 6, 0, 0, + 120, 101, 95, 117, 115, 101, 114, 95, 99, 108, 105, 112, 95, 112, 108, 97, 110, 101, 115, + 0, 102, 108, 111, 97, 116, 52, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 110, 100, 99, 95, 115, 99, 97, 108, 101, + 0, 102, 108, 111, 97, 116, 51, 0, 1, 0, 3, 0, 1, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 149, 6, 0, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, + 101, 120, 95, 100, 105, 97, 109, 101, 116, 101, 114, 95, 109, 105, 110, 0, 102, 108, 111, + 97, 116, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 6, + 0, 0, 120, 101, 95, 110, 100, 99, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, 101, 120, 95, 100, 105, 97, 109, 101, 116, + 101, 114, 95, 109, 97, 120, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 99, 111, 110, + 115, 116, 97, 110, 116, 95, 100, 105, 97, 109, 101, 116, 101, 114, 0, 120, 101, 95, 112, + 111, 105, 110, 116, 95, 115, 99, 114, 101, 101, 110, 95, 100, 105, 97, 109, 101, 116, 101, + 114, 95, 116, 111, 95, 110, 100, 99, 95, 114, 97, 100, 105, 117, 115, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 115, 119, 105, 122, 122, 108, 101, 100, 95, 115, 105, + 103, 110, 115, 0, 117, 105, 110, 116, 52, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, + 4, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, + 114, 101, 115, 95, 114, 101, 115, 111, 108, 118, 101, 100, 0, 120, 101, 95, 115, 97, 109, + 112, 108, 101, 95, 99, 111, 117, 110, 116, 95, 108, 111, 103, 50, 0, 120, 101, 95, 97, + 108, 112, 104, 97, 95, 116, 101, 115, 116, 95, 114, 101, 102, 101, 114, 101, 110, 99, 101, + 0, 120, 101, 95, 97, 108, 112, 104, 97, 95, 116, 111, 95, 109, 97, 115, 107, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 51, 50, 98, 112, 112, 95, 116, 105, 108, 101, 95, + 112, 105, 116, 99, 104, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 100, 101, 112, 116, 104, 95, 98, 97, 115, + 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, 0, 120, 101, 95, + 99, 111, 108, 111, 114, 95, 101, 120, 112, 95, 98, 105, 97, 115, 0, 171, 1, 0, 3, + 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 101, 100, + 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, 102, 115, 101, 116, 95, 102, 114, 111, + 110, 116, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, + 102, 115, 101, 116, 95, 98, 97, 99, 107, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, + 115, 116, 101, 110, 99, 105, 108, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, + 95, 98, 97, 115, 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, + 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 102, 111, 114, 109, 97, 116, 95, + 102, 108, 97, 103, 115, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 99, + 108, 97, 109, 112, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 92, 6, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 107, 101, 101, + 112, 95, 109, 97, 115, 107, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, + 98, 108, 101, 110, 100, 95, 102, 97, 99, 116, 111, 114, 115, 95, 111, 112, 115, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 98, 108, 101, 110, 100, 95, 99, 111, 110, 115, 116, + 97, 110, 116, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, + 32, 49, 48, 46, 49, 0, 171, 171, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, + 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 88, 69, 86, 69, 82, 84, 69, 88, 73, + 68, 0, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 1, 14, 0, 0, 88, 69, 86, 69, 82, 84, 69, 88, 73, 68, 0, 171, 80, 67, + 83, 71, 140, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, + 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 14, 0, 0, + 104, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, + 0, 1, 14, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 13, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 1, 14, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 14, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 14, 0, 0, 83, 86, 95, 84, + 101, 115, 115, 70, 97, 99, 116, 111, 114, 0, 83, 86, 95, 73, 110, 115, 105, 100, 101, + 84, 101, 115, 115, 70, 97, 99, 116, 111, 114, 0, 171, 171, 83, 72, 69, 88, 4, 1, + 0, 0, 81, 0, 3, 0, 65, 0, 0, 0, 113, 0, 0, 1, 147, 24, 0, 1, 148, + 24, 0, 1, 149, 16, 0, 1, 150, 32, 0, 1, 151, 24, 0, 1, 106, 8, 0, 1, + 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 115, 0, 0, 1, 153, 0, 0, 2, 3, 0, + 0, 0, 95, 0, 0, 2, 0, 112, 1, 0, 103, 0, 0, 4, 18, 32, 16, 0, 0, + 0, 0, 0, 17, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 1, 0, 0, 0, + 18, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 2, 0, 0, 0, 19, 0, 0, + 0, 104, 0, 0, 2, 1, 0, 0, 0, 91, 0, 0, 4, 18, 32, 16, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 112, 1, 0, 54, 0, 0, 8, 18, 32, 144, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, + 1, 115, 0, 0, 1, 103, 0, 0, 4, 18, 32, 16, 0, 3, 0, 0, 0, 20, 0, + 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 3, 0, 0, 0, 42, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, + 148, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/discrete_quad_1cp_hs.h b/src/graphics/shaders/bytecode/d3d12_5_1/discrete_quad_1cp_hs.h new file mode 100644 index 0000000..dc86217 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/discrete_quad_1cp_hs.h @@ -0,0 +1,312 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer xe_system_cbuffer +// { +// +// uint xe_flags; // Offset: 0 Size: 4 [unused] +// float2 xe_tessellation_factor_range;// Offset: 4 Size: 8 +// uint xe_line_loop_closing_index; // Offset: 12 Size: 4 [unused] +// uint xe_vertex_index_endian; // Offset: 16 Size: 4 [unused] +// uint xe_vertex_index_offset; // Offset: 20 Size: 4 [unused] +// uint2 xe_vertex_index_min_max; // Offset: 24 Size: 8 [unused] +// float4 xe_user_clip_planes[6]; // Offset: 32 Size: 96 [unused] +// float3 xe_ndc_scale; // Offset: 128 Size: 12 [unused] +// float xe_point_vertex_diameter_min;// Offset: 140 Size: 4 [unused] +// float3 xe_ndc_offset; // Offset: 144 Size: 12 [unused] +// float xe_point_vertex_diameter_max;// Offset: 156 Size: 4 [unused] +// float2 xe_point_constant_diameter; // Offset: 160 Size: 8 [unused] +// float2 xe_point_screen_diameter_to_ndc_radius;// Offset: 168 Size: 8 [unused] +// uint4 xe_texture_swizzled_signs[2];// Offset: 176 Size: 32 [unused] +// uint xe_textures_resolved; // Offset: 208 Size: 4 [unused] +// uint2 xe_sample_count_log2; // Offset: 212 Size: 8 [unused] +// float xe_alpha_test_reference; // Offset: 220 Size: 4 [unused] +// uint xe_alpha_to_mask; // Offset: 224 Size: 4 [unused] +// uint xe_edram_32bpp_tile_pitch_dwords_scaled;// Offset: 228 Size: 4 [unused] +// uint xe_edram_depth_base_dwords_scaled;// Offset: 232 Size: 4 [unused] +// float4 xe_color_exp_bias; // Offset: 240 Size: 16 [unused] +// float2 xe_edram_poly_offset_front; // Offset: 256 Size: 8 [unused] +// float2 xe_edram_poly_offset_back; // Offset: 264 Size: 8 [unused] +// uint4 xe_edram_stencil[2]; // Offset: 272 Size: 32 [unused] +// uint4 xe_edram_rt_base_dwords_scaled;// Offset: 304 Size: 16 [unused] +// uint4 xe_edram_rt_format_flags; // Offset: 320 Size: 16 [unused] +// float4 xe_edram_rt_clamp[4]; // Offset: 336 Size: 64 [unused] +// uint4 xe_edram_rt_keep_mask[2]; // Offset: 400 Size: 32 [unused] +// uint4 xe_edram_rt_blend_factors_ops;// Offset: 432 Size: 16 [unused] +// float4 xe_edram_blend_constant; // Offset: 448 Size: 16 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_system_cbuffer cbuffer NA NA CB0 cb0 1 +// +// +// +// Patch Constant signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TessFactor 0 x 0 QUADEDGE float x +// SV_TessFactor 1 x 1 QUADEDGE float x +// SV_TessFactor 2 x 2 QUADEDGE float x +// SV_TessFactor 3 x 3 QUADEDGE float x +// SV_InsideTessFactor 0 x 4 QUADINT float x +// SV_InsideTessFactor 1 x 5 QUADINT float x +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE float x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE float x +// +// Tessellation Domain # of control points +// -------------------- -------------------- +// Quadrilateral 1 +// +// Tessellation Output Primitive Partitioning Type +// ------------------------------ ------------------ +// Clockwise Triangles Integer +// +hs_5_1 +hs_decls +dcl_input_control_point_count 1 +dcl_output_control_point_count 1 +dcl_tessellator_domain domain_quad +dcl_tessellator_partitioning partitioning_integer +dcl_tessellator_output_primitive output_triangle_cw +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +hs_control_point_phase +dcl_input v[1][0].x +dcl_output o0.x +mov o0.x, v[0][0].x +ret +hs_fork_phase +dcl_hs_fork_phase_instance_count 4 +dcl_input vForkInstanceID +dcl_output_siv o0.x, finalQuadUeq0EdgeTessFactor +dcl_output_siv o1.x, finalQuadVeq0EdgeTessFactor +dcl_output_siv o2.x, finalQuadUeq1EdgeTessFactor +dcl_output_siv o3.x, finalQuadVeq1EdgeTessFactor +dcl_temps 1 +dcl_indexrange o0.x 4 +mov r0.x, vForkInstanceID.x +mov o[r0.x + 0].x, CB0[0][0].z +ret +hs_fork_phase +dcl_hs_fork_phase_instance_count 2 +dcl_input vForkInstanceID +dcl_output_siv o4.x, finalQuadUInsideTessFactor +dcl_output_siv o5.x, finalQuadVInsideTessFactor +dcl_temps 1 +dcl_indexrange o4.x 2 +mov r0.x, vForkInstanceID.x +mov o[r0.x + 4].x, CB0[0][0].z +ret +// Approximately 8 instruction slots used +#endif + +const BYTE discrete_quad_1cp_hs[] = { + 68, 88, 66, 67, 166, 226, 56, 134, 119, 149, 47, 144, 135, 3, 42, 236, 243, 129, 164, + 56, 1, 0, 0, 0, 220, 13, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 108, 10, + 0, 0, 160, 10, 0, 0, 212, 10, 0, 0, 152, 11, 0, 0, 64, 13, 0, 0, 82, + 68, 69, 70, 44, 10, 0, 0, 1, 0, 0, 0, 120, 0, 0, 0, 1, 0, 0, 0, + 60, 0, 0, 0, 1, 5, 83, 72, 0, 5, 0, 0, 2, 10, 0, 0, 19, 19, 68, + 37, 60, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 115, 121, 115, 116, + 101, 109, 95, 99, 98, 117, 102, 102, 101, 114, 0, 171, 171, 100, 0, 0, 0, 30, 0, + 0, 0, 144, 0, 0, 0, 208, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, + 5, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 116, 5, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 152, 5, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 188, 5, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 215, 5, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 238, 5, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 5, 6, 0, 0, 24, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 72, 6, 0, 0, 32, 0, 0, 0, + 96, 0, 0, 0, 0, 0, 0, 0, 100, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 136, 6, 0, 0, 128, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 6, 0, 0, + 140, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 8, 7, + 0, 0, 144, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 22, 7, 0, 0, 156, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 51, 7, 0, 0, 160, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, + 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 78, 7, 0, 0, 168, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 117, 7, 0, 0, 176, 0, 0, 0, 32, 0, 0, 0, 0, + 0, 0, 0, 152, 7, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 188, 7, 0, 0, 208, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 209, 7, 0, 0, 212, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 230, 7, 0, 0, 220, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 254, 7, 0, 0, 224, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 8, 0, + 0, 228, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 55, + 8, 0, 0, 232, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 89, 8, 0, 0, 240, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 144, 8, 0, 0, 0, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 171, 8, 0, 0, 8, 1, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 197, 8, 0, 0, 16, 1, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 216, 8, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 252, 8, 0, 0, 48, 1, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 64, 9, 0, 0, 64, 1, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 89, 9, 0, 0, 80, 1, + 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 108, 9, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 144, 9, 0, 0, + 144, 1, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 168, 9, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 204, 9, + 0, 0, 176, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 234, 9, 0, 0, 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 120, 101, 95, 102, 108, 97, 103, 115, 0, 100, 119, 111, 114, 100, 0, 171, 0, + 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 5, 0, 0, 120, 101, 95, + 116, 101, 115, 115, 101, 108, 108, 97, 116, 105, 111, 110, 95, 102, 97, 99, 116, 111, 114, + 95, 114, 97, 110, 103, 101, 0, 102, 108, 111, 97, 116, 50, 0, 1, 0, 3, 0, 1, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 145, 5, 0, 0, 120, 101, 95, 108, 105, 110, 101, + 95, 108, 111, 111, 112, 95, 99, 108, 111, 115, 105, 110, 103, 95, 105, 110, 100, 101, 120, + 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, 120, 95, 101, 110, + 100, 105, 97, 110, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, + 120, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, + 105, 110, 100, 101, 120, 95, 109, 105, 110, 95, 109, 97, 120, 0, 117, 105, 110, 116, 50, + 0, 171, 1, 0, 19, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 6, 0, 0, + 120, 101, 95, 117, 115, 101, 114, 95, 99, 108, 105, 112, 95, 112, 108, 97, 110, 101, 115, + 0, 102, 108, 111, 97, 116, 52, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 110, 100, 99, 95, 115, 99, 97, 108, 101, + 0, 102, 108, 111, 97, 116, 51, 0, 1, 0, 3, 0, 1, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 149, 6, 0, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, + 101, 120, 95, 100, 105, 97, 109, 101, 116, 101, 114, 95, 109, 105, 110, 0, 102, 108, 111, + 97, 116, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 6, + 0, 0, 120, 101, 95, 110, 100, 99, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, 101, 120, 95, 100, 105, 97, 109, 101, 116, + 101, 114, 95, 109, 97, 120, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 99, 111, 110, + 115, 116, 97, 110, 116, 95, 100, 105, 97, 109, 101, 116, 101, 114, 0, 120, 101, 95, 112, + 111, 105, 110, 116, 95, 115, 99, 114, 101, 101, 110, 95, 100, 105, 97, 109, 101, 116, 101, + 114, 95, 116, 111, 95, 110, 100, 99, 95, 114, 97, 100, 105, 117, 115, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 115, 119, 105, 122, 122, 108, 101, 100, 95, 115, 105, + 103, 110, 115, 0, 117, 105, 110, 116, 52, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, + 4, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, + 114, 101, 115, 95, 114, 101, 115, 111, 108, 118, 101, 100, 0, 120, 101, 95, 115, 97, 109, + 112, 108, 101, 95, 99, 111, 117, 110, 116, 95, 108, 111, 103, 50, 0, 120, 101, 95, 97, + 108, 112, 104, 97, 95, 116, 101, 115, 116, 95, 114, 101, 102, 101, 114, 101, 110, 99, 101, + 0, 120, 101, 95, 97, 108, 112, 104, 97, 95, 116, 111, 95, 109, 97, 115, 107, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 51, 50, 98, 112, 112, 95, 116, 105, 108, 101, 95, + 112, 105, 116, 99, 104, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 100, 101, 112, 116, 104, 95, 98, 97, 115, + 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, 0, 120, 101, 95, + 99, 111, 108, 111, 114, 95, 101, 120, 112, 95, 98, 105, 97, 115, 0, 171, 1, 0, 3, + 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 101, 100, + 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, 102, 115, 101, 116, 95, 102, 114, 111, + 110, 116, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, + 102, 115, 101, 116, 95, 98, 97, 99, 107, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, + 115, 116, 101, 110, 99, 105, 108, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, + 95, 98, 97, 115, 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, + 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 102, 111, 114, 109, 97, 116, 95, + 102, 108, 97, 103, 115, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 99, + 108, 97, 109, 112, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 92, 6, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 107, 101, 101, + 112, 95, 109, 97, 115, 107, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, + 98, 108, 101, 110, 100, 95, 102, 97, 99, 116, 111, 114, 115, 95, 111, 112, 115, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 98, 108, 101, 110, 100, 95, 99, 111, 110, 115, 116, + 97, 110, 116, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, + 32, 49, 48, 46, 49, 0, 171, 171, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, + 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 88, 69, 86, 69, 82, 84, 69, 88, 73, + 68, 0, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 1, 14, 0, 0, 88, 69, 86, 69, 82, 84, 69, 88, 73, 68, 0, 171, 80, 67, + 83, 71, 188, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 152, 0, 0, 0, 0, + 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 14, 0, 0, + 152, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, + 0, 1, 14, 0, 0, 152, 0, 0, 0, 2, 0, 0, 0, 11, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 1, 14, 0, 0, 152, 0, 0, 0, 3, 0, 0, 0, 11, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 14, 0, 0, 166, 0, 0, 0, + 0, 0, 0, 0, 12, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 14, 0, + 0, 166, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 3, 0, 0, 0, 5, 0, + 0, 0, 1, 14, 0, 0, 83, 86, 95, 84, 101, 115, 115, 70, 97, 99, 116, 111, 114, + 0, 83, 86, 95, 73, 110, 115, 105, 100, 101, 84, 101, 115, 115, 70, 97, 99, 116, 111, + 114, 0, 171, 171, 83, 72, 69, 88, 160, 1, 0, 0, 81, 0, 3, 0, 104, 0, 0, + 0, 113, 0, 0, 1, 147, 8, 0, 1, 148, 8, 0, 1, 149, 24, 0, 1, 150, 8, + 0, 1, 151, 24, 0, 1, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 114, 0, 0, 1, 95, 0, 0, 4, 18, 16, 32, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 101, 0, 0, 3, 18, 32, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 32, + 16, 0, 0, 0, 0, 0, 10, 16, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, + 0, 0, 1, 115, 0, 0, 1, 153, 0, 0, 2, 4, 0, 0, 0, 95, 0, 0, 2, + 0, 112, 1, 0, 103, 0, 0, 4, 18, 32, 16, 0, 0, 0, 0, 0, 11, 0, 0, + 0, 103, 0, 0, 4, 18, 32, 16, 0, 1, 0, 0, 0, 12, 0, 0, 0, 103, 0, + 0, 4, 18, 32, 16, 0, 2, 0, 0, 0, 13, 0, 0, 0, 103, 0, 0, 4, 18, + 32, 16, 0, 3, 0, 0, 0, 14, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, + 91, 0, 0, 4, 18, 32, 16, 0, 0, 0, 0, 0, 4, 0, 0, 0, 54, 0, 0, + 4, 18, 0, 16, 0, 0, 0, 0, 0, 10, 112, 1, 0, 54, 0, 0, 8, 18, 32, + 144, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 115, 0, 0, 1, 153, 0, 0, 2, + 2, 0, 0, 0, 95, 0, 0, 2, 0, 112, 1, 0, 103, 0, 0, 4, 18, 32, 16, + 0, 4, 0, 0, 0, 15, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 5, 0, + 0, 0, 16, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 91, 0, 0, 4, 18, + 32, 16, 0, 4, 0, 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 112, 1, 0, 54, 0, 0, 9, 18, 32, 208, 0, 4, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/discrete_quad_4cp_hs.h b/src/graphics/shaders/bytecode/d3d12_5_1/discrete_quad_4cp_hs.h new file mode 100644 index 0000000..f9f935c --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/discrete_quad_4cp_hs.h @@ -0,0 +1,304 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer xe_system_cbuffer +// { +// +// uint xe_flags; // Offset: 0 Size: 4 [unused] +// float2 xe_tessellation_factor_range;// Offset: 4 Size: 8 +// uint xe_line_loop_closing_index; // Offset: 12 Size: 4 [unused] +// uint xe_vertex_index_endian; // Offset: 16 Size: 4 [unused] +// uint xe_vertex_index_offset; // Offset: 20 Size: 4 [unused] +// uint2 xe_vertex_index_min_max; // Offset: 24 Size: 8 [unused] +// float4 xe_user_clip_planes[6]; // Offset: 32 Size: 96 [unused] +// float3 xe_ndc_scale; // Offset: 128 Size: 12 [unused] +// float xe_point_vertex_diameter_min;// Offset: 140 Size: 4 [unused] +// float3 xe_ndc_offset; // Offset: 144 Size: 12 [unused] +// float xe_point_vertex_diameter_max;// Offset: 156 Size: 4 [unused] +// float2 xe_point_constant_diameter; // Offset: 160 Size: 8 [unused] +// float2 xe_point_screen_diameter_to_ndc_radius;// Offset: 168 Size: 8 [unused] +// uint4 xe_texture_swizzled_signs[2];// Offset: 176 Size: 32 [unused] +// uint xe_textures_resolved; // Offset: 208 Size: 4 [unused] +// uint2 xe_sample_count_log2; // Offset: 212 Size: 8 [unused] +// float xe_alpha_test_reference; // Offset: 220 Size: 4 [unused] +// uint xe_alpha_to_mask; // Offset: 224 Size: 4 [unused] +// uint xe_edram_32bpp_tile_pitch_dwords_scaled;// Offset: 228 Size: 4 [unused] +// uint xe_edram_depth_base_dwords_scaled;// Offset: 232 Size: 4 [unused] +// float4 xe_color_exp_bias; // Offset: 240 Size: 16 [unused] +// float2 xe_edram_poly_offset_front; // Offset: 256 Size: 8 [unused] +// float2 xe_edram_poly_offset_back; // Offset: 264 Size: 8 [unused] +// uint4 xe_edram_stencil[2]; // Offset: 272 Size: 32 [unused] +// uint4 xe_edram_rt_base_dwords_scaled;// Offset: 304 Size: 16 [unused] +// uint4 xe_edram_rt_format_flags; // Offset: 320 Size: 16 [unused] +// float4 xe_edram_rt_clamp[4]; // Offset: 336 Size: 64 [unused] +// uint4 xe_edram_rt_keep_mask[2]; // Offset: 400 Size: 32 [unused] +// uint4 xe_edram_rt_blend_factors_ops;// Offset: 432 Size: 16 [unused] +// float4 xe_edram_blend_constant; // Offset: 448 Size: 16 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_system_cbuffer cbuffer NA NA CB0 cb0 1 +// +// +// +// Patch Constant signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TessFactor 0 x 0 QUADEDGE float x +// SV_TessFactor 1 x 1 QUADEDGE float x +// SV_TessFactor 2 x 2 QUADEDGE float x +// SV_TessFactor 3 x 3 QUADEDGE float x +// SV_InsideTessFactor 0 x 4 QUADINT float x +// SV_InsideTessFactor 1 x 5 QUADINT float x +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE float x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE float x +// +// Tessellation Domain # of control points +// -------------------- -------------------- +// Quadrilateral 4 +// +// Tessellation Output Primitive Partitioning Type +// ------------------------------ ------------------ +// Clockwise Triangles Integer +// +hs_5_1 +hs_decls +dcl_input_control_point_count 4 +dcl_output_control_point_count 4 +dcl_tessellator_domain domain_quad +dcl_tessellator_partitioning partitioning_integer +dcl_tessellator_output_primitive output_triangle_cw +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +hs_fork_phase +dcl_hs_fork_phase_instance_count 4 +dcl_input vForkInstanceID +dcl_output_siv o0.x, finalQuadUeq0EdgeTessFactor +dcl_output_siv o1.x, finalQuadVeq0EdgeTessFactor +dcl_output_siv o2.x, finalQuadUeq1EdgeTessFactor +dcl_output_siv o3.x, finalQuadVeq1EdgeTessFactor +dcl_temps 1 +dcl_indexrange o0.x 4 +mov r0.x, vForkInstanceID.x +mov o[r0.x + 0].x, CB0[0][0].z +ret +hs_fork_phase +dcl_hs_fork_phase_instance_count 2 +dcl_input vForkInstanceID +dcl_output_siv o4.x, finalQuadUInsideTessFactor +dcl_output_siv o5.x, finalQuadVInsideTessFactor +dcl_temps 1 +dcl_indexrange o4.x 2 +mov r0.x, vForkInstanceID.x +mov o[r0.x + 4].x, CB0[0][0].z +ret +// Approximately 6 instruction slots used +#endif + +const BYTE discrete_quad_4cp_hs[] = { + 68, 88, 66, 67, 192, 34, 77, 20, 70, 107, 155, 33, 163, 40, 168, 219, 244, 3, 133, + 198, 1, 0, 0, 0, 160, 13, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 108, 10, + 0, 0, 160, 10, 0, 0, 212, 10, 0, 0, 152, 11, 0, 0, 4, 13, 0, 0, 82, + 68, 69, 70, 44, 10, 0, 0, 1, 0, 0, 0, 120, 0, 0, 0, 1, 0, 0, 0, + 60, 0, 0, 0, 1, 5, 83, 72, 0, 5, 0, 0, 2, 10, 0, 0, 19, 19, 68, + 37, 60, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 115, 121, 115, 116, + 101, 109, 95, 99, 98, 117, 102, 102, 101, 114, 0, 171, 171, 100, 0, 0, 0, 30, 0, + 0, 0, 144, 0, 0, 0, 208, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, + 5, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 116, 5, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 152, 5, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 188, 5, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 215, 5, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 238, 5, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 5, 6, 0, 0, 24, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 72, 6, 0, 0, 32, 0, 0, 0, + 96, 0, 0, 0, 0, 0, 0, 0, 100, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 136, 6, 0, 0, 128, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 6, 0, 0, + 140, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 8, 7, + 0, 0, 144, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 22, 7, 0, 0, 156, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 51, 7, 0, 0, 160, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, + 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 78, 7, 0, 0, 168, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 117, 7, 0, 0, 176, 0, 0, 0, 32, 0, 0, 0, 0, + 0, 0, 0, 152, 7, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 188, 7, 0, 0, 208, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 209, 7, 0, 0, 212, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 230, 7, 0, 0, 220, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 254, 7, 0, 0, 224, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 8, 0, + 0, 228, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 55, + 8, 0, 0, 232, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 89, 8, 0, 0, 240, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 144, 8, 0, 0, 0, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 171, 8, 0, 0, 8, 1, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 197, 8, 0, 0, 16, 1, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 216, 8, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 252, 8, 0, 0, 48, 1, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 64, 9, 0, 0, 64, 1, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 89, 9, 0, 0, 80, 1, + 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 108, 9, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 144, 9, 0, 0, + 144, 1, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 168, 9, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 204, 9, + 0, 0, 176, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 234, 9, 0, 0, 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 120, 101, 95, 102, 108, 97, 103, 115, 0, 100, 119, 111, 114, 100, 0, 171, 0, + 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 5, 0, 0, 120, 101, 95, + 116, 101, 115, 115, 101, 108, 108, 97, 116, 105, 111, 110, 95, 102, 97, 99, 116, 111, 114, + 95, 114, 97, 110, 103, 101, 0, 102, 108, 111, 97, 116, 50, 0, 1, 0, 3, 0, 1, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 145, 5, 0, 0, 120, 101, 95, 108, 105, 110, 101, + 95, 108, 111, 111, 112, 95, 99, 108, 111, 115, 105, 110, 103, 95, 105, 110, 100, 101, 120, + 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, 120, 95, 101, 110, + 100, 105, 97, 110, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, + 120, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, + 105, 110, 100, 101, 120, 95, 109, 105, 110, 95, 109, 97, 120, 0, 117, 105, 110, 116, 50, + 0, 171, 1, 0, 19, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 6, 0, 0, + 120, 101, 95, 117, 115, 101, 114, 95, 99, 108, 105, 112, 95, 112, 108, 97, 110, 101, 115, + 0, 102, 108, 111, 97, 116, 52, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 110, 100, 99, 95, 115, 99, 97, 108, 101, + 0, 102, 108, 111, 97, 116, 51, 0, 1, 0, 3, 0, 1, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 149, 6, 0, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, + 101, 120, 95, 100, 105, 97, 109, 101, 116, 101, 114, 95, 109, 105, 110, 0, 102, 108, 111, + 97, 116, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 6, + 0, 0, 120, 101, 95, 110, 100, 99, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, 101, 120, 95, 100, 105, 97, 109, 101, 116, + 101, 114, 95, 109, 97, 120, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 99, 111, 110, + 115, 116, 97, 110, 116, 95, 100, 105, 97, 109, 101, 116, 101, 114, 0, 120, 101, 95, 112, + 111, 105, 110, 116, 95, 115, 99, 114, 101, 101, 110, 95, 100, 105, 97, 109, 101, 116, 101, + 114, 95, 116, 111, 95, 110, 100, 99, 95, 114, 97, 100, 105, 117, 115, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 115, 119, 105, 122, 122, 108, 101, 100, 95, 115, 105, + 103, 110, 115, 0, 117, 105, 110, 116, 52, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, + 4, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, + 114, 101, 115, 95, 114, 101, 115, 111, 108, 118, 101, 100, 0, 120, 101, 95, 115, 97, 109, + 112, 108, 101, 95, 99, 111, 117, 110, 116, 95, 108, 111, 103, 50, 0, 120, 101, 95, 97, + 108, 112, 104, 97, 95, 116, 101, 115, 116, 95, 114, 101, 102, 101, 114, 101, 110, 99, 101, + 0, 120, 101, 95, 97, 108, 112, 104, 97, 95, 116, 111, 95, 109, 97, 115, 107, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 51, 50, 98, 112, 112, 95, 116, 105, 108, 101, 95, + 112, 105, 116, 99, 104, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 100, 101, 112, 116, 104, 95, 98, 97, 115, + 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, 0, 120, 101, 95, + 99, 111, 108, 111, 114, 95, 101, 120, 112, 95, 98, 105, 97, 115, 0, 171, 1, 0, 3, + 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 101, 100, + 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, 102, 115, 101, 116, 95, 102, 114, 111, + 110, 116, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, + 102, 115, 101, 116, 95, 98, 97, 99, 107, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, + 115, 116, 101, 110, 99, 105, 108, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, + 95, 98, 97, 115, 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, + 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 102, 111, 114, 109, 97, 116, 95, + 102, 108, 97, 103, 115, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 99, + 108, 97, 109, 112, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 92, 6, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 107, 101, 101, + 112, 95, 109, 97, 115, 107, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, + 98, 108, 101, 110, 100, 95, 102, 97, 99, 116, 111, 114, 115, 95, 111, 112, 115, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 98, 108, 101, 110, 100, 95, 99, 111, 110, 115, 116, + 97, 110, 116, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, + 32, 49, 48, 46, 49, 0, 171, 171, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, + 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 88, 69, 86, 69, 82, 84, 69, 88, 73, + 68, 0, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 1, 14, 0, 0, 88, 69, 86, 69, 82, 84, 69, 88, 73, 68, 0, 171, 80, 67, + 83, 71, 188, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 152, 0, 0, 0, 0, + 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 14, 0, 0, + 152, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, + 0, 1, 14, 0, 0, 152, 0, 0, 0, 2, 0, 0, 0, 11, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 1, 14, 0, 0, 152, 0, 0, 0, 3, 0, 0, 0, 11, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 14, 0, 0, 166, 0, 0, 0, + 0, 0, 0, 0, 12, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 14, 0, + 0, 166, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 3, 0, 0, 0, 5, 0, + 0, 0, 1, 14, 0, 0, 83, 86, 95, 84, 101, 115, 115, 70, 97, 99, 116, 111, 114, + 0, 83, 86, 95, 73, 110, 115, 105, 100, 101, 84, 101, 115, 115, 70, 97, 99, 116, 111, + 114, 0, 171, 171, 83, 72, 69, 88, 100, 1, 0, 0, 81, 0, 3, 0, 89, 0, 0, + 0, 113, 0, 0, 1, 147, 32, 0, 1, 148, 32, 0, 1, 149, 24, 0, 1, 150, 8, + 0, 1, 151, 24, 0, 1, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 115, 0, 0, 1, 153, 0, 0, 2, 4, 0, 0, 0, 95, 0, 0, 2, 0, 112, 1, + 0, 103, 0, 0, 4, 18, 32, 16, 0, 0, 0, 0, 0, 11, 0, 0, 0, 103, 0, + 0, 4, 18, 32, 16, 0, 1, 0, 0, 0, 12, 0, 0, 0, 103, 0, 0, 4, 18, + 32, 16, 0, 2, 0, 0, 0, 13, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, + 3, 0, 0, 0, 14, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 91, 0, 0, + 4, 18, 32, 16, 0, 0, 0, 0, 0, 4, 0, 0, 0, 54, 0, 0, 4, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 112, 1, 0, 54, 0, 0, 8, 18, 32, 144, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 62, 0, 0, 1, 115, 0, 0, 1, 153, 0, 0, 2, 2, 0, 0, + 0, 95, 0, 0, 2, 0, 112, 1, 0, 103, 0, 0, 4, 18, 32, 16, 0, 4, 0, + 0, 0, 15, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 5, 0, 0, 0, 16, + 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 91, 0, 0, 4, 18, 32, 16, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 112, 1, 0, 54, 0, 0, 9, 18, 32, 208, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 6, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/discrete_triangle_1cp_hs.h b/src/graphics/shaders/bytecode/d3d12_5_1/discrete_triangle_1cp_hs.h new file mode 100644 index 0000000..aab583b --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/discrete_triangle_1cp_hs.h @@ -0,0 +1,296 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer xe_system_cbuffer +// { +// +// uint xe_flags; // Offset: 0 Size: 4 [unused] +// float2 xe_tessellation_factor_range;// Offset: 4 Size: 8 +// uint xe_line_loop_closing_index; // Offset: 12 Size: 4 [unused] +// uint xe_vertex_index_endian; // Offset: 16 Size: 4 [unused] +// uint xe_vertex_index_offset; // Offset: 20 Size: 4 [unused] +// uint2 xe_vertex_index_min_max; // Offset: 24 Size: 8 [unused] +// float4 xe_user_clip_planes[6]; // Offset: 32 Size: 96 [unused] +// float3 xe_ndc_scale; // Offset: 128 Size: 12 [unused] +// float xe_point_vertex_diameter_min;// Offset: 140 Size: 4 [unused] +// float3 xe_ndc_offset; // Offset: 144 Size: 12 [unused] +// float xe_point_vertex_diameter_max;// Offset: 156 Size: 4 [unused] +// float2 xe_point_constant_diameter; // Offset: 160 Size: 8 [unused] +// float2 xe_point_screen_diameter_to_ndc_radius;// Offset: 168 Size: 8 [unused] +// uint4 xe_texture_swizzled_signs[2];// Offset: 176 Size: 32 [unused] +// uint xe_textures_resolved; // Offset: 208 Size: 4 [unused] +// uint2 xe_sample_count_log2; // Offset: 212 Size: 8 [unused] +// float xe_alpha_test_reference; // Offset: 220 Size: 4 [unused] +// uint xe_alpha_to_mask; // Offset: 224 Size: 4 [unused] +// uint xe_edram_32bpp_tile_pitch_dwords_scaled;// Offset: 228 Size: 4 [unused] +// uint xe_edram_depth_base_dwords_scaled;// Offset: 232 Size: 4 [unused] +// float4 xe_color_exp_bias; // Offset: 240 Size: 16 [unused] +// float2 xe_edram_poly_offset_front; // Offset: 256 Size: 8 [unused] +// float2 xe_edram_poly_offset_back; // Offset: 264 Size: 8 [unused] +// uint4 xe_edram_stencil[2]; // Offset: 272 Size: 32 [unused] +// uint4 xe_edram_rt_base_dwords_scaled;// Offset: 304 Size: 16 [unused] +// uint4 xe_edram_rt_format_flags; // Offset: 320 Size: 16 [unused] +// float4 xe_edram_rt_clamp[4]; // Offset: 336 Size: 64 [unused] +// uint4 xe_edram_rt_keep_mask[2]; // Offset: 400 Size: 32 [unused] +// uint4 xe_edram_rt_blend_factors_ops;// Offset: 432 Size: 16 [unused] +// float4 xe_edram_blend_constant; // Offset: 448 Size: 16 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_system_cbuffer cbuffer NA NA CB0 cb0 1 +// +// +// +// Patch Constant signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TessFactor 0 x 0 TRIEDGE float x +// SV_TessFactor 1 x 1 TRIEDGE float x +// SV_TessFactor 2 x 2 TRIEDGE float x +// SV_InsideTessFactor 0 x 3 TRIINT float x +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE float x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE float x +// +// Tessellation Domain # of control points +// -------------------- -------------------- +// Triangle 1 +// +// Tessellation Output Primitive Partitioning Type +// ------------------------------ ------------------ +// Clockwise Triangles Integer +// +hs_5_1 +hs_decls +dcl_input_control_point_count 1 +dcl_output_control_point_count 1 +dcl_tessellator_domain domain_tri +dcl_tessellator_partitioning partitioning_integer +dcl_tessellator_output_primitive output_triangle_cw +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +hs_control_point_phase +dcl_input v[1][0].x +dcl_output o0.x +mov o0.x, v[0][0].x +ret +hs_fork_phase +dcl_hs_fork_phase_instance_count 3 +dcl_input vForkInstanceID +dcl_output_siv o0.x, finalTriUeq0EdgeTessFactor +dcl_output_siv o1.x, finalTriVeq0EdgeTessFactor +dcl_output_siv o2.x, finalTriWeq0EdgeTessFactor +dcl_temps 1 +dcl_indexrange o0.x 3 +mov r0.x, vForkInstanceID.x +mov o[r0.x + 0].x, CB0[0][0].z +ret +hs_fork_phase +dcl_output_siv o3.x, finalTriInsideTessFactor +mov o3.x, CB0[0][0].z +ret +// Approximately 7 instruction slots used +#endif + +const BYTE discrete_triangle_1cp_hs[] = { + 68, 88, 66, 67, 227, 140, 35, 65, 156, 178, 224, 139, 122, 75, 128, 231, 90, 78, 65, + 91, 1, 0, 0, 0, 76, 13, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 108, 10, + 0, 0, 160, 10, 0, 0, 212, 10, 0, 0, 104, 11, 0, 0, 176, 12, 0, 0, 82, + 68, 69, 70, 44, 10, 0, 0, 1, 0, 0, 0, 120, 0, 0, 0, 1, 0, 0, 0, + 60, 0, 0, 0, 1, 5, 83, 72, 0, 5, 0, 0, 2, 10, 0, 0, 19, 19, 68, + 37, 60, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 115, 121, 115, 116, + 101, 109, 95, 99, 98, 117, 102, 102, 101, 114, 0, 171, 171, 100, 0, 0, 0, 30, 0, + 0, 0, 144, 0, 0, 0, 208, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, + 5, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 116, 5, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 152, 5, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 188, 5, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 215, 5, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 238, 5, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 5, 6, 0, 0, 24, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 72, 6, 0, 0, 32, 0, 0, 0, + 96, 0, 0, 0, 0, 0, 0, 0, 100, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 136, 6, 0, 0, 128, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 6, 0, 0, + 140, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 8, 7, + 0, 0, 144, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 22, 7, 0, 0, 156, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 51, 7, 0, 0, 160, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, + 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 78, 7, 0, 0, 168, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 117, 7, 0, 0, 176, 0, 0, 0, 32, 0, 0, 0, 0, + 0, 0, 0, 152, 7, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 188, 7, 0, 0, 208, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 209, 7, 0, 0, 212, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 230, 7, 0, 0, 220, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 254, 7, 0, 0, 224, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 8, 0, + 0, 228, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 55, + 8, 0, 0, 232, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 89, 8, 0, 0, 240, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 144, 8, 0, 0, 0, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 171, 8, 0, 0, 8, 1, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 197, 8, 0, 0, 16, 1, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 216, 8, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 252, 8, 0, 0, 48, 1, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 64, 9, 0, 0, 64, 1, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 89, 9, 0, 0, 80, 1, + 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 108, 9, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 144, 9, 0, 0, + 144, 1, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 168, 9, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 204, 9, + 0, 0, 176, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 234, 9, 0, 0, 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 120, 101, 95, 102, 108, 97, 103, 115, 0, 100, 119, 111, 114, 100, 0, 171, 0, + 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 5, 0, 0, 120, 101, 95, + 116, 101, 115, 115, 101, 108, 108, 97, 116, 105, 111, 110, 95, 102, 97, 99, 116, 111, 114, + 95, 114, 97, 110, 103, 101, 0, 102, 108, 111, 97, 116, 50, 0, 1, 0, 3, 0, 1, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 145, 5, 0, 0, 120, 101, 95, 108, 105, 110, 101, + 95, 108, 111, 111, 112, 95, 99, 108, 111, 115, 105, 110, 103, 95, 105, 110, 100, 101, 120, + 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, 120, 95, 101, 110, + 100, 105, 97, 110, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, + 120, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, + 105, 110, 100, 101, 120, 95, 109, 105, 110, 95, 109, 97, 120, 0, 117, 105, 110, 116, 50, + 0, 171, 1, 0, 19, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 6, 0, 0, + 120, 101, 95, 117, 115, 101, 114, 95, 99, 108, 105, 112, 95, 112, 108, 97, 110, 101, 115, + 0, 102, 108, 111, 97, 116, 52, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 110, 100, 99, 95, 115, 99, 97, 108, 101, + 0, 102, 108, 111, 97, 116, 51, 0, 1, 0, 3, 0, 1, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 149, 6, 0, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, + 101, 120, 95, 100, 105, 97, 109, 101, 116, 101, 114, 95, 109, 105, 110, 0, 102, 108, 111, + 97, 116, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 6, + 0, 0, 120, 101, 95, 110, 100, 99, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, 101, 120, 95, 100, 105, 97, 109, 101, 116, + 101, 114, 95, 109, 97, 120, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 99, 111, 110, + 115, 116, 97, 110, 116, 95, 100, 105, 97, 109, 101, 116, 101, 114, 0, 120, 101, 95, 112, + 111, 105, 110, 116, 95, 115, 99, 114, 101, 101, 110, 95, 100, 105, 97, 109, 101, 116, 101, + 114, 95, 116, 111, 95, 110, 100, 99, 95, 114, 97, 100, 105, 117, 115, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 115, 119, 105, 122, 122, 108, 101, 100, 95, 115, 105, + 103, 110, 115, 0, 117, 105, 110, 116, 52, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, + 4, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, + 114, 101, 115, 95, 114, 101, 115, 111, 108, 118, 101, 100, 0, 120, 101, 95, 115, 97, 109, + 112, 108, 101, 95, 99, 111, 117, 110, 116, 95, 108, 111, 103, 50, 0, 120, 101, 95, 97, + 108, 112, 104, 97, 95, 116, 101, 115, 116, 95, 114, 101, 102, 101, 114, 101, 110, 99, 101, + 0, 120, 101, 95, 97, 108, 112, 104, 97, 95, 116, 111, 95, 109, 97, 115, 107, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 51, 50, 98, 112, 112, 95, 116, 105, 108, 101, 95, + 112, 105, 116, 99, 104, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 100, 101, 112, 116, 104, 95, 98, 97, 115, + 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, 0, 120, 101, 95, + 99, 111, 108, 111, 114, 95, 101, 120, 112, 95, 98, 105, 97, 115, 0, 171, 1, 0, 3, + 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 101, 100, + 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, 102, 115, 101, 116, 95, 102, 114, 111, + 110, 116, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, + 102, 115, 101, 116, 95, 98, 97, 99, 107, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, + 115, 116, 101, 110, 99, 105, 108, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, + 95, 98, 97, 115, 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, + 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 102, 111, 114, 109, 97, 116, 95, + 102, 108, 97, 103, 115, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 99, + 108, 97, 109, 112, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 92, 6, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 107, 101, 101, + 112, 95, 109, 97, 115, 107, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, + 98, 108, 101, 110, 100, 95, 102, 97, 99, 116, 111, 114, 115, 95, 111, 112, 115, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 98, 108, 101, 110, 100, 95, 99, 111, 110, 115, 116, + 97, 110, 116, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, + 32, 49, 48, 46, 49, 0, 171, 171, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, + 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 88, 69, 86, 69, 82, 84, 69, 88, 73, + 68, 0, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 1, 14, 0, 0, 88, 69, 86, 69, 82, 84, 69, 88, 73, 68, 0, 171, 80, 67, + 83, 71, 140, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, + 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 14, 0, 0, + 104, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, + 0, 1, 14, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 13, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 1, 14, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 14, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 14, 0, 0, 83, 86, 95, 84, + 101, 115, 115, 70, 97, 99, 116, 111, 114, 0, 83, 86, 95, 73, 110, 115, 105, 100, 101, + 84, 101, 115, 115, 70, 97, 99, 116, 111, 114, 0, 171, 171, 83, 72, 69, 88, 64, 1, + 0, 0, 81, 0, 3, 0, 80, 0, 0, 0, 113, 0, 0, 1, 147, 8, 0, 1, 148, + 8, 0, 1, 149, 16, 0, 1, 150, 8, 0, 1, 151, 24, 0, 1, 106, 8, 0, 1, + 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 114, 0, 0, 1, 95, 0, 0, 4, 18, 16, + 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, 3, 18, 32, 16, 0, 0, + 0, 0, 0, 54, 0, 0, 6, 18, 32, 16, 0, 0, 0, 0, 0, 10, 16, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 115, 0, 0, 1, 153, 0, 0, + 2, 3, 0, 0, 0, 95, 0, 0, 2, 0, 112, 1, 0, 103, 0, 0, 4, 18, 32, + 16, 0, 0, 0, 0, 0, 17, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 1, + 0, 0, 0, 18, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 2, 0, 0, 0, + 19, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 91, 0, 0, 4, 18, 32, 16, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 18, 0, 16, 0, 0, 0, + 0, 0, 10, 112, 1, 0, 54, 0, 0, 8, 18, 32, 144, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 62, 0, 0, 1, 115, 0, 0, 1, 103, 0, 0, 4, 18, 32, 16, 0, 3, 0, 0, + 0, 20, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 3, 0, 0, 0, 42, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, + 84, 65, 84, 148, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/discrete_triangle_3cp_hs.h b/src/graphics/shaders/bytecode/d3d12_5_1/discrete_triangle_3cp_hs.h new file mode 100644 index 0000000..d33d303 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/discrete_triangle_3cp_hs.h @@ -0,0 +1,287 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer xe_system_cbuffer +// { +// +// uint xe_flags; // Offset: 0 Size: 4 [unused] +// float2 xe_tessellation_factor_range;// Offset: 4 Size: 8 +// uint xe_line_loop_closing_index; // Offset: 12 Size: 4 [unused] +// uint xe_vertex_index_endian; // Offset: 16 Size: 4 [unused] +// uint xe_vertex_index_offset; // Offset: 20 Size: 4 [unused] +// uint2 xe_vertex_index_min_max; // Offset: 24 Size: 8 [unused] +// float4 xe_user_clip_planes[6]; // Offset: 32 Size: 96 [unused] +// float3 xe_ndc_scale; // Offset: 128 Size: 12 [unused] +// float xe_point_vertex_diameter_min;// Offset: 140 Size: 4 [unused] +// float3 xe_ndc_offset; // Offset: 144 Size: 12 [unused] +// float xe_point_vertex_diameter_max;// Offset: 156 Size: 4 [unused] +// float2 xe_point_constant_diameter; // Offset: 160 Size: 8 [unused] +// float2 xe_point_screen_diameter_to_ndc_radius;// Offset: 168 Size: 8 [unused] +// uint4 xe_texture_swizzled_signs[2];// Offset: 176 Size: 32 [unused] +// uint xe_textures_resolved; // Offset: 208 Size: 4 [unused] +// uint2 xe_sample_count_log2; // Offset: 212 Size: 8 [unused] +// float xe_alpha_test_reference; // Offset: 220 Size: 4 [unused] +// uint xe_alpha_to_mask; // Offset: 224 Size: 4 [unused] +// uint xe_edram_32bpp_tile_pitch_dwords_scaled;// Offset: 228 Size: 4 [unused] +// uint xe_edram_depth_base_dwords_scaled;// Offset: 232 Size: 4 [unused] +// float4 xe_color_exp_bias; // Offset: 240 Size: 16 [unused] +// float2 xe_edram_poly_offset_front; // Offset: 256 Size: 8 [unused] +// float2 xe_edram_poly_offset_back; // Offset: 264 Size: 8 [unused] +// uint4 xe_edram_stencil[2]; // Offset: 272 Size: 32 [unused] +// uint4 xe_edram_rt_base_dwords_scaled;// Offset: 304 Size: 16 [unused] +// uint4 xe_edram_rt_format_flags; // Offset: 320 Size: 16 [unused] +// float4 xe_edram_rt_clamp[4]; // Offset: 336 Size: 64 [unused] +// uint4 xe_edram_rt_keep_mask[2]; // Offset: 400 Size: 32 [unused] +// uint4 xe_edram_rt_blend_factors_ops;// Offset: 432 Size: 16 [unused] +// float4 xe_edram_blend_constant; // Offset: 448 Size: 16 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_system_cbuffer cbuffer NA NA CB0 cb0 1 +// +// +// +// Patch Constant signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TessFactor 0 x 0 TRIEDGE float x +// SV_TessFactor 1 x 1 TRIEDGE float x +// SV_TessFactor 2 x 2 TRIEDGE float x +// SV_InsideTessFactor 0 x 3 TRIINT float x +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE float x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE float x +// +// Tessellation Domain # of control points +// -------------------- -------------------- +// Triangle 3 +// +// Tessellation Output Primitive Partitioning Type +// ------------------------------ ------------------ +// Clockwise Triangles Integer +// +hs_5_1 +hs_decls +dcl_input_control_point_count 3 +dcl_output_control_point_count 3 +dcl_tessellator_domain domain_tri +dcl_tessellator_partitioning partitioning_integer +dcl_tessellator_output_primitive output_triangle_cw +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +hs_fork_phase +dcl_hs_fork_phase_instance_count 3 +dcl_input vForkInstanceID +dcl_output_siv o0.x, finalTriUeq0EdgeTessFactor +dcl_output_siv o1.x, finalTriVeq0EdgeTessFactor +dcl_output_siv o2.x, finalTriWeq0EdgeTessFactor +dcl_temps 1 +dcl_indexrange o0.x 3 +mov r0.x, vForkInstanceID.x +mov o[r0.x + 0].x, CB0[0][0].z +ret +hs_fork_phase +dcl_output_siv o3.x, finalTriInsideTessFactor +mov o3.x, CB0[0][0].z +ret +// Approximately 5 instruction slots used +#endif + +const BYTE discrete_triangle_3cp_hs[] = { + 68, 88, 66, 67, 159, 101, 17, 163, 1, 25, 162, 203, 87, 30, 32, 90, 1, 126, 212, + 108, 1, 0, 0, 0, 16, 13, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 108, 10, + 0, 0, 160, 10, 0, 0, 212, 10, 0, 0, 104, 11, 0, 0, 116, 12, 0, 0, 82, + 68, 69, 70, 44, 10, 0, 0, 1, 0, 0, 0, 120, 0, 0, 0, 1, 0, 0, 0, + 60, 0, 0, 0, 1, 5, 83, 72, 0, 5, 0, 0, 2, 10, 0, 0, 19, 19, 68, + 37, 60, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 115, 121, 115, 116, + 101, 109, 95, 99, 98, 117, 102, 102, 101, 114, 0, 171, 171, 100, 0, 0, 0, 30, 0, + 0, 0, 144, 0, 0, 0, 208, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, + 5, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 116, 5, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 152, 5, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 188, 5, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 215, 5, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 238, 5, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 5, 6, 0, 0, 24, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 72, 6, 0, 0, 32, 0, 0, 0, + 96, 0, 0, 0, 0, 0, 0, 0, 100, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 136, 6, 0, 0, 128, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 6, 0, 0, + 140, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 8, 7, + 0, 0, 144, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 22, 7, 0, 0, 156, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 51, 7, 0, 0, 160, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, + 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 78, 7, 0, 0, 168, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 117, 7, 0, 0, 176, 0, 0, 0, 32, 0, 0, 0, 0, + 0, 0, 0, 152, 7, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 188, 7, 0, 0, 208, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 209, 7, 0, 0, 212, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 230, 7, 0, 0, 220, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 254, 7, 0, 0, 224, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 8, 0, + 0, 228, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 55, + 8, 0, 0, 232, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 89, 8, 0, 0, 240, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 144, 8, 0, 0, 0, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 171, 8, 0, 0, 8, 1, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 152, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 197, 8, 0, 0, 16, 1, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 216, 8, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 252, 8, 0, 0, 48, 1, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 64, 9, 0, 0, 64, 1, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 89, 9, 0, 0, 80, 1, + 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 108, 9, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 144, 9, 0, 0, + 144, 1, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 168, 9, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 204, 9, + 0, 0, 176, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 234, 9, 0, 0, 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 120, 101, 95, 102, 108, 97, 103, 115, 0, 100, 119, 111, 114, 100, 0, 171, 0, + 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 5, 0, 0, 120, 101, 95, + 116, 101, 115, 115, 101, 108, 108, 97, 116, 105, 111, 110, 95, 102, 97, 99, 116, 111, 114, + 95, 114, 97, 110, 103, 101, 0, 102, 108, 111, 97, 116, 50, 0, 1, 0, 3, 0, 1, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 145, 5, 0, 0, 120, 101, 95, 108, 105, 110, 101, + 95, 108, 111, 111, 112, 95, 99, 108, 111, 115, 105, 110, 103, 95, 105, 110, 100, 101, 120, + 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, 120, 95, 101, 110, + 100, 105, 97, 110, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, + 120, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, + 105, 110, 100, 101, 120, 95, 109, 105, 110, 95, 109, 97, 120, 0, 117, 105, 110, 116, 50, + 0, 171, 1, 0, 19, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 6, 0, 0, + 120, 101, 95, 117, 115, 101, 114, 95, 99, 108, 105, 112, 95, 112, 108, 97, 110, 101, 115, + 0, 102, 108, 111, 97, 116, 52, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 110, 100, 99, 95, 115, 99, 97, 108, 101, + 0, 102, 108, 111, 97, 116, 51, 0, 1, 0, 3, 0, 1, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 149, 6, 0, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, + 101, 120, 95, 100, 105, 97, 109, 101, 116, 101, 114, 95, 109, 105, 110, 0, 102, 108, 111, + 97, 116, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 6, + 0, 0, 120, 101, 95, 110, 100, 99, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, 101, 120, 95, 100, 105, 97, 109, 101, 116, + 101, 114, 95, 109, 97, 120, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 99, 111, 110, + 115, 116, 97, 110, 116, 95, 100, 105, 97, 109, 101, 116, 101, 114, 0, 120, 101, 95, 112, + 111, 105, 110, 116, 95, 115, 99, 114, 101, 101, 110, 95, 100, 105, 97, 109, 101, 116, 101, + 114, 95, 116, 111, 95, 110, 100, 99, 95, 114, 97, 100, 105, 117, 115, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 115, 119, 105, 122, 122, 108, 101, 100, 95, 115, 105, + 103, 110, 115, 0, 117, 105, 110, 116, 52, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, + 4, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, + 114, 101, 115, 95, 114, 101, 115, 111, 108, 118, 101, 100, 0, 120, 101, 95, 115, 97, 109, + 112, 108, 101, 95, 99, 111, 117, 110, 116, 95, 108, 111, 103, 50, 0, 120, 101, 95, 97, + 108, 112, 104, 97, 95, 116, 101, 115, 116, 95, 114, 101, 102, 101, 114, 101, 110, 99, 101, + 0, 120, 101, 95, 97, 108, 112, 104, 97, 95, 116, 111, 95, 109, 97, 115, 107, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 51, 50, 98, 112, 112, 95, 116, 105, 108, 101, 95, + 112, 105, 116, 99, 104, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 100, 101, 112, 116, 104, 95, 98, 97, 115, + 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, 0, 120, 101, 95, + 99, 111, 108, 111, 114, 95, 101, 120, 112, 95, 98, 105, 97, 115, 0, 171, 1, 0, 3, + 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 101, 100, + 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, 102, 115, 101, 116, 95, 102, 114, 111, + 110, 116, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, + 102, 115, 101, 116, 95, 98, 97, 99, 107, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, + 115, 116, 101, 110, 99, 105, 108, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, + 95, 98, 97, 115, 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, + 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, + 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 102, 111, 114, 109, 97, 116, 95, + 102, 108, 97, 103, 115, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 99, + 108, 97, 109, 112, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 92, 6, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 107, 101, 101, + 112, 95, 109, 97, 115, 107, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, + 98, 108, 101, 110, 100, 95, 102, 97, 99, 116, 111, 114, 115, 95, 111, 112, 115, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 98, 108, 101, 110, 100, 95, 99, 111, 110, 115, 116, + 97, 110, 116, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, + 32, 49, 48, 46, 49, 0, 171, 171, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, + 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 88, 69, 86, 69, 82, 84, 69, 88, 73, + 68, 0, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 1, 14, 0, 0, 88, 69, 86, 69, 82, 84, 69, 88, 73, 68, 0, 171, 80, 67, + 83, 71, 140, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, + 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 14, 0, 0, + 104, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, + 0, 1, 14, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 13, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 1, 14, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 14, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 14, 0, 0, 83, 86, 95, 84, + 101, 115, 115, 70, 97, 99, 116, 111, 114, 0, 83, 86, 95, 73, 110, 115, 105, 100, 101, + 84, 101, 115, 115, 70, 97, 99, 116, 111, 114, 0, 171, 171, 83, 72, 69, 88, 4, 1, + 0, 0, 81, 0, 3, 0, 65, 0, 0, 0, 113, 0, 0, 1, 147, 24, 0, 1, 148, + 24, 0, 1, 149, 16, 0, 1, 150, 8, 0, 1, 151, 24, 0, 1, 106, 8, 0, 1, + 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 115, 0, 0, 1, 153, 0, 0, 2, 3, 0, + 0, 0, 95, 0, 0, 2, 0, 112, 1, 0, 103, 0, 0, 4, 18, 32, 16, 0, 0, + 0, 0, 0, 17, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 1, 0, 0, 0, + 18, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 2, 0, 0, 0, 19, 0, 0, + 0, 104, 0, 0, 2, 1, 0, 0, 0, 91, 0, 0, 4, 18, 32, 16, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 112, 1, 0, 54, 0, 0, 8, 18, 32, 144, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, + 1, 115, 0, 0, 1, 103, 0, 0, 4, 18, 32, 16, 0, 3, 0, 0, 0, 20, 0, + 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 3, 0, 0, 0, 42, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, + 148, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/float24_round_ps.h b/src/graphics/shaders/bytecode/d3d12_5_1/float24_round_ps.h new file mode 100644 index 0000000..8d3ca96 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/float24_round_ps.h @@ -0,0 +1,172 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// TEXCOORD 0 xyzw 0 NONE float +// TEXCOORD 1 xyzw 1 NONE float +// TEXCOORD 2 xyzw 2 NONE float +// TEXCOORD 3 xyzw 3 NONE float +// TEXCOORD 4 xyzw 4 NONE float +// TEXCOORD 5 xyzw 5 NONE float +// TEXCOORD 6 xyzw 6 NONE float +// TEXCOORD 7 xyzw 7 NONE float +// TEXCOORD 8 xyzw 8 NONE float +// TEXCOORD 9 xyzw 9 NONE float +// TEXCOORD 10 xyzw 10 NONE float +// TEXCOORD 11 xyzw 11 NONE float +// TEXCOORD 12 xyzw 12 NONE float +// TEXCOORD 13 xyzw 13 NONE float +// TEXCOORD 14 xyzw 14 NONE float +// TEXCOORD 15 xyzw 15 NONE float +// TEXCOORD 16 xyz 16 NONE float +// SV_Position 0 xyzw 17 POS float z +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Depth 0 N/A oDepth DEPTH float YES +// +// Pixel Shader runs at sample frequency +// +ps_5_1 +dcl_globalFlags refactoringAllowed +dcl_input_ps_siv linear noperspective sample v17.z, position +dcl_output oDepth +dcl_temps 2 +mul_sat [precise(x)] r0.x, v17.z, l(2.000000) +uge [precise(y)] r0.y, l(0x7fffffff), r0.x +and [precise(x)] r0.x, r0.x, r0.y +umin [precise(x)] r0.x, r0.x, l(0x3ffffff8) +bfi [precise(y)] r0.y, l(23), l(0), r0.x, l(0x00800000) +ushr [precise(z)] r0.z, r0.x, l(23) +iadd [precise(z)] r0.z, -r0.z, l(113) +umin [precise(z)] r0.z, r0.z, l(24) +ushr [precise(y)] r0.y, r0.y, r0.z +ult [precise(z)] r0.z, r0.x, l(0x38800000) +iadd [precise(x)] r0.x, r0.x, l(0xc8000000) +movc [precise(x)] r0.x, r0.z, r0.y, r0.x +ubfe [precise(y)] r0.y, l(1), l(3), r0.x +iadd [precise(x)] r0.x, r0.y, r0.x +iadd [precise(x)] r0.x, r0.x, l(3) +ubfe [precise(xyz)] r0.xyz, l(24, 20, 4, 0), l(3, 3, 23, 0), r0.xxxx +firstbit_hi [precise(w)] r0.w, r0.y +iadd [precise(w)] r0.w, r0.w, l(-11) +movc [precise(w)] r0.w, r0.y, r0.w, l(21) +iadd [precise(x)] r1.x, -r0.w, l(1) +movc [precise(x)] r1.x, r0.z, r0.z, r1.x +ishl [precise(w)] r0.w, r0.y, r0.w +and [precise(w)] r0.w, r0.w, l(0x000fffff) +movc [precise(y)] r0.y, r0.z, r0.y, r0.w +ishl [precise(z)] r0.z, r1.x, l(23) +iadd [precise(z)] r0.z, r0.z, l(0x37800000) +ishl [precise(y)] r0.y, r0.y, l(3) +iadd [precise(y)] r0.y, r0.z, r0.y +movc [precise(x)] oDepth, r0.x, r0.y, l(0) +ret +// Approximately 30 instruction slots used +#endif + +const BYTE float24_round_ps[] = { + 68, 88, 66, 67, 110, 79, 84, 202, 151, 165, 237, 180, 64, 17, 0, 132, 236, 126, 142, + 105, 1, 0, 0, 0, 8, 7, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 160, 0, + 0, 0, 120, 2, 0, 0, 172, 2, 0, 0, 108, 6, 0, 0, 82, 68, 69, 70, 100, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 255, 255, 0, 5, 0, 0, 60, 0, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, + 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, + 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 208, 1, 0, 0, 18, 0, 0, + 0, 8, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 184, 1, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 184, 1, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, + 0, 184, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 15, 0, 0, 0, 184, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 184, 1, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 184, 1, 0, + 0, 6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 15, 0, + 0, 0, 184, 1, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 7, + 0, 0, 0, 15, 0, 0, 0, 184, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 184, 1, 0, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 9, 0, 0, 0, 15, 0, 0, 0, 184, 1, + 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 10, 0, 0, 0, 15, + 0, 0, 0, 184, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 11, 0, 0, 0, 15, 0, 0, 0, 184, 1, 0, 0, 12, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 184, 1, 0, 0, 13, 0, + 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 13, 0, 0, 0, 15, 0, 0, 0, 184, + 1, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 14, 0, 0, 0, + 15, 0, 0, 0, 184, 1, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 15, 0, 0, 0, 15, 0, 0, 0, 184, 1, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 193, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 17, 0, 0, 0, 15, 4, 0, 0, + 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, + 110, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, + 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, + 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 68, 101, 112, 116, 104, 0, 171, 171, 171, + 83, 72, 69, 88, 184, 3, 0, 0, 81, 0, 0, 0, 238, 0, 0, 0, 106, 8, 0, + 1, 100, 56, 0, 4, 66, 16, 16, 0, 17, 0, 0, 0, 1, 0, 0, 0, 101, 0, + 0, 2, 1, 192, 0, 0, 104, 0, 0, 2, 2, 0, 0, 0, 56, 32, 8, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 42, 16, 16, 0, 17, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 64, 80, 0, 16, 7, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 255, 255, 255, 127, 10, 0, 16, 0, 0, 0, 0, 0, 1, 0, 8, 7, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 84, 0, 8, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 248, 255, 255, 63, 140, 0, 16, 11, 34, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 0, 85, + 0, 32, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, 32, 8, 66, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 113, 0, + 0, 0, 84, 0, 32, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 85, 0, 16, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 79, 0, 32, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 128, 56, 30, 0, 8, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 200, + 55, 0, 8, 9, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 138, 0, + 16, 9, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 30, 0, 8, 7, + 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 30, 0, 8, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 138, 0, 56, 15, 114, + 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, 20, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 23, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 135, 0, + 64, 5, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, + 0, 64, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 245, 255, 255, 255, 55, 0, 64, 9, 130, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 21, 0, 0, 0, 30, 0, 8, 8, 18, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 55, 0, 8, 9, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, + 64, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 1, 0, 64, 7, 130, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 255, 15, 0, 55, 0, 16, + 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 32, 7, 66, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 23, 0, 0, 0, 30, 0, 32, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 55, 41, 0, 16, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, + 0, 0, 0, 30, 0, 16, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 55, 0, 8, 8, 1, 192, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 30, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, + 11, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/float24_truncate_ps.h b/src/graphics/shaders/bytecode/d3d12_5_1/float24_truncate_ps.h new file mode 100644 index 0000000..50660e4 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/float24_truncate_ps.h @@ -0,0 +1,121 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// TEXCOORD 0 xyzw 0 NONE float +// TEXCOORD 1 xyzw 1 NONE float +// TEXCOORD 2 xyzw 2 NONE float +// TEXCOORD 3 xyzw 3 NONE float +// TEXCOORD 4 xyzw 4 NONE float +// TEXCOORD 5 xyzw 5 NONE float +// TEXCOORD 6 xyzw 6 NONE float +// TEXCOORD 7 xyzw 7 NONE float +// TEXCOORD 8 xyzw 8 NONE float +// TEXCOORD 9 xyzw 9 NONE float +// TEXCOORD 10 xyzw 10 NONE float +// TEXCOORD 11 xyzw 11 NONE float +// TEXCOORD 12 xyzw 12 NONE float +// TEXCOORD 13 xyzw 13 NONE float +// TEXCOORD 14 xyzw 14 NONE float +// TEXCOORD 15 xyzw 15 NONE float +// TEXCOORD 16 xyz 16 NONE float +// SV_Position 0 xyzw 17 POS float z +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_DepthLessEqual 0 N/A oDepthLE DEPTHLE float YES +// +// Pixel Shader runs at sample frequency +// +ps_5_1 +dcl_globalFlags refactoringAllowed +dcl_input_ps_siv linear noperspective sample v17.z, position +dcl_output oDepthLE +dcl_temps 1 +mul_sat [precise(x)] r0.x, v17.z, l(2.000000) +uge [precise(y)] r0.y, r0.x, l(0x2e800000) +if_nz r0.y + ubfe [precise(y)] r0.y, l(8), l(23), r0.x + iadd [precise(y)] r0.y, -r0.y, l(116) + imax [precise(y)] r0.y, r0.y, l(3) + bfi [precise(x)] r0.x, r0.y, l(0), l(0), r0.x +else + mov [precise(x)] r0.x, l(0) +endif +mul [precise(x)] oDepthLE, r0.x, l(0.500000) +ret +// Approximately 12 instruction slots used +#endif + +const BYTE float24_truncate_ps[] = { + 68, 88, 66, 67, 234, 72, 187, 196, 185, 155, 10, 179, 119, 204, 17, 88, 131, 142, 107, + 205, 1, 0, 0, 0, 140, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 160, 0, + 0, 0, 120, 2, 0, 0, 180, 2, 0, 0, 240, 3, 0, 0, 82, 68, 69, 70, 100, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 255, 255, 0, 5, 0, 0, 60, 0, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, + 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, + 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 208, 1, 0, 0, 18, 0, 0, + 0, 8, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 184, 1, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 184, 1, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, + 0, 184, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 15, 0, 0, 0, 184, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 184, 1, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 184, 1, 0, + 0, 6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 15, 0, + 0, 0, 184, 1, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 7, + 0, 0, 0, 15, 0, 0, 0, 184, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 184, 1, 0, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 9, 0, 0, 0, 15, 0, 0, 0, 184, 1, + 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 10, 0, 0, 0, 15, + 0, 0, 0, 184, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 11, 0, 0, 0, 15, 0, 0, 0, 184, 1, 0, 0, 12, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 184, 1, 0, 0, 13, 0, + 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 13, 0, 0, 0, 15, 0, 0, 0, 184, + 1, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 14, 0, 0, 0, + 15, 0, 0, 0, 184, 1, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 15, 0, 0, 0, 15, 0, 0, 0, 184, 1, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 193, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 17, 0, 0, 0, 15, 4, 0, 0, + 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, + 110, 0, 171, 171, 171, 79, 83, 71, 78, 52, 0, 0, 0, 1, 0, 0, 0, 8, 0, + 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, + 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, + 69, 113, 117, 97, 108, 0, 171, 171, 83, 72, 69, 88, 52, 1, 0, 0, 81, 0, 0, + 0, 77, 0, 0, 0, 106, 8, 0, 1, 100, 56, 0, 4, 66, 16, 16, 0, 17, 0, + 0, 0, 1, 0, 0, 0, 101, 0, 0, 2, 1, 112, 2, 0, 104, 0, 0, 2, 1, + 0, 0, 0, 56, 32, 8, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 16, 16, 0, + 17, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 80, 0, 16, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 128, 46, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 138, 0, 16, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 1, 64, 0, 0, + 23, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 30, 0, 16, 8, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 116, 0, 0, 0, 36, 0, 16, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 140, 0, 8, 11, + 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 18, 0, 0, 1, 54, 0, 8, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 56, 0, 8, 6, 1, 112, 2, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 62, 0, 0, + 1, 83, 84, 65, 84, 148, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/fullscreen_cw_vs.h b/src/graphics/shaders/bytecode/d3d12_5_1/fullscreen_cw_vs.h new file mode 100644 index 0000000..90e417b --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/fullscreen_cw_vs.h @@ -0,0 +1,71 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_VertexID 0 x 0 VERTID uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xyzw +// +vs_5_1 +dcl_globalFlags refactoringAllowed +dcl_input_sgv v0.x, vertex_id +dcl_output_siv o0.xyzw, position +dcl_temps 1 +ushr r0.y, v0.x, l(1) +mov r0.x, v0.x +and r0.xy, r0.xyxx, l(1, 1, 0, 0) +utof r0.xy, r0.xyxx +mad o0.xy, r0.xyxx, l(4.000000, -4.000000, 0.000000, 0.000000), l(-1.000000, 1.000000, 0.000000, 0.000000) +mov o0.zw, l(0,0,0,1.000000) +ret +// Approximately 7 instruction slots used +#endif + +const BYTE fullscreen_cw_vs[] = { + 68, 88, 66, 67, 38, 212, 32, 171, 28, 206, 206, 51, 24, 105, 112, 99, 117, 136, 1, + 11, 1, 0, 0, 0, 172, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 160, 0, + 0, 0, 212, 0, 0, 0, 8, 1, 0, 0, 16, 2, 0, 0, 82, 68, 69, 70, 100, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 254, 255, 0, 5, 0, 0, 60, 0, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, + 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, + 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, + 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 83, 86, 95, 86, 101, 114, 116, 101, 120, + 73, 68, 0, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 15, 0, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 83, 72, + 69, 88, 0, 1, 0, 0, 81, 0, 1, 0, 64, 0, 0, 0, 106, 8, 0, 1, 96, + 0, 0, 4, 18, 16, 16, 0, 0, 0, 0, 0, 6, 0, 0, 0, 103, 0, 0, 4, + 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, + 0, 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 16, 16, 0, 0, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 50, 0, + 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 15, 50, + 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 64, 0, 0, 128, 192, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 32, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, + 148, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/fxaa_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/fxaa_cs.h new file mode 100644 index 0000000..451e28a --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/fxaa_cs.h @@ -0,0 +1,576 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer XeApplyGammaRampConstants +// { +// +// uint2 xe_fxaa_size; // Offset: 0 Size: 8 +// float2 xe_fxaa_size_inv; // Offset: 8 Size: 8 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_sampler_linear_clamp sampler NA NA S0 s0 1 +// xe_fxaa_source texture float4 2d T0 t0 1 +// xe_fxaa_dest UAV unorm4 2d U0 u0 1 +// XeApplyGammaRampConstants cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_sampler S0[0:0], mode_default, space=0 +dcl_resource_texture2d (float,float,float,float) T0[0:0], space=0 +dcl_uav_typed_texture2d (unorm,unorm,unorm,unorm) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 7 +dcl_thread_group 16, 8, 1 +uge r0.xy, vThreadID.xyxx, CB0[0][0].xyxx +or r0.x, r0.y, r0.x +if_nz r0.x + ret +endif +utof r0.xy, vThreadID.xyxx +add r0.xy, r0.xyxx, l(0.500000, 0.500000, 0.000000, 0.000000) +mul r0.zw, r0.xxxy, CB0[0][0].zzzw +sample_l r1.xyzw, r0.zwzz, T0[0].xyzw, S0[0], l(0.000000) +gather4 r2.xyz, r0.zwzz, T0[0].xyzw, S0[0].w +gather4_aoffimmi(-1,-1,0) r3.xyz, r0.zwzz, T0[0].zxwy, S0[0].w +max r2.w, r1.w, r2.x +min r3.w, r1.w, r2.x +max r2.w, r2.w, r2.z +min r3.w, r2.z, r3.w +max r4.x, r3.y, r3.x +min r4.y, r3.y, r3.x +max r2.w, r2.w, r4.x +min r3.w, r3.w, r4.y +mul r4.x, r2.w, l(0.166000) +add r2.w, r2.w, -r3.w +max r3.w, r4.x, l(0.083300) +lt r3.w, r2.w, r3.w +if_z r3.w +endif +if_z r3.w + sample_l_aoffimmi(1,-1,0) r3.w, r0.zwzz, T0[0].xyzw, S0[0], l(0.000000) + sample_l_aoffimmi(-1,1,0) r4.x, r0.zwzz, T0[0].wxyz, S0[0], l(0.000000) + add r4.yz, r2.xxzx, r3.xxyx + div r2.w, l(1.000000, 1.000000, 1.000000, 1.000000), r2.w + add r4.w, r4.z, r4.y + mad r4.yz, r1.wwww, l(0.000000, -2.000000, -2.000000, 0.000000), r4.yyzy + add r5.x, r2.y, r3.w + add r3.w, r3.w, r3.z + mad r5.y, r2.z, l(-2.000000), r5.x + mad r3.w, r3.x, l(-2.000000), r3.w + add r3.z, r3.z, r4.x + add r2.y, r2.y, r4.x + mad r4.x, |r4.y|, l(2.000000), |r5.y| + mad r3.w, |r4.z|, l(2.000000), |r3.w| + mad r4.y, r3.y, l(-2.000000), r3.z + mad r2.y, r2.x, l(-2.000000), r2.y + add r4.x, r4.x, |r4.y| + add r2.y, r3.w, |r2.y| + add r3.z, r5.x, r3.z + ge r2.y, r4.x, r2.y + mad r3.z, r4.w, l(2.000000), r3.z + if_z r2.y + mov r3.x, r3.y + mov r2.x, r2.z + endif + if_nz r2.y + mov r2.z, CB0[0][0].w + else + mov r2.z, CB0[0][0].z + endif + mad r3.y, r3.z, l(0.083333), -r1.w + add r3.z, -r1.w, r3.x + add r3.w, -r1.w, r2.x + ge r4.x, |r3.z|, |r3.w| + max r3.z, |r3.w|, |r3.z| + if_nz r4.x + mov r2.z, -r2.z + endif + mul_sat r2.w, r2.w, |r3.y| + and r3.y, r2.y, CB0[0][0].z + movc r3.w, r2.y, l(0), CB0[0][0].w + if_z r2.y + mad r4.y, r2.z, l(0.500000), r0.z + else + mov r4.y, r0.z + endif + if_nz r2.y + mad r4.z, r2.z, l(0.500000), r0.w + else + mov r4.z, r0.w + endif + add r5.xy, -r3.ywyy, r4.yzyy + add r4.yw, r3.yyyw, r4.yyyz + mad r4.z, r2.w, l(-2.000000), l(3.000000) + sample_l r5.z, r5.xyxx, T0[0].xywz, S0[0], l(0.000000) + mul r2.w, r2.w, r2.w + sample_l r5.w, r4.ywyy, T0[0].xyzw, S0[0], l(0.000000) + if_z r4.x + add r3.x, r1.w, r2.x + else + add r3.x, r1.w, r3.x + endif + mul r2.x, r3.z, l(0.250000) + mad r3.z, -r3.x, l(0.500000), r1.w + mul r2.w, r2.w, r4.z + lt r3.z, r3.z, l(0.000000) + mad r6.x, -r3.x, l(0.500000), r5.z + mad r6.y, -r3.x, l(0.500000), r5.w + lt r4.xz, |r6.xxyx|, r2.xxxx + if_nz r4.x + mad r5.x, -r3.y, l(1.500000), r5.x + mad r5.y, -r3.w, l(1.500000), r5.y + endif + or r5.z, r4.z, r4.x + if_nz r4.z + mad r4.y, r3.y, l(1.500000), r4.y + mad r4.w, r3.w, l(1.500000), r4.w + endif + if_nz r5.z + if_nz r4.x + sample_l r6.x, r5.xyxx, T0[0].wxyz, S0[0], l(0.000000) + endif + if_nz r4.z + sample_l r6.y, r4.ywyy, T0[0].xwyz, S0[0], l(0.000000) + endif + if_nz r4.x + mad r6.x, -r3.x, l(0.500000), r6.x + endif + if_nz r4.z + mad r6.y, -r3.x, l(0.500000), r6.y + endif + lt r4.xz, |r6.xxyx|, r2.xxxx + if_nz r4.x + mad r5.x, -r3.y, l(2.000000), r5.x + mad r5.y, -r3.w, l(2.000000), r5.y + endif + or r5.z, r4.z, r4.x + if_nz r4.z + mad r4.y, r3.y, l(2.000000), r4.y + mad r4.w, r3.w, l(2.000000), r4.w + endif + if_nz r5.z + if_nz r4.x + sample_l r6.x, r5.xyxx, T0[0].wxyz, S0[0], l(0.000000) + endif + if_nz r4.z + sample_l r6.y, r4.ywyy, T0[0].xwyz, S0[0], l(0.000000) + endif + if_nz r4.x + mad r6.x, -r3.x, l(0.500000), r6.x + endif + if_nz r4.z + mad r6.y, -r3.x, l(0.500000), r6.y + endif + lt r4.xz, |r6.xxyx|, r2.xxxx + if_nz r4.x + mad r5.x, -r3.y, l(4.000000), r5.x + mad r5.y, -r3.w, l(4.000000), r5.y + endif + or r5.z, r4.z, r4.x + if_nz r4.z + mad r4.y, r3.y, l(4.000000), r4.y + mad r4.w, r3.w, l(4.000000), r4.w + endif + if_nz r5.z + if_nz r4.x + sample_l r6.x, r5.xyxx, T0[0].wxyz, S0[0], l(0.000000) + endif + if_nz r4.z + sample_l r6.y, r4.ywyy, T0[0].xwyz, S0[0], l(0.000000) + endif + if_nz r4.x + mad r6.x, -r3.x, l(0.500000), r6.x + endif + if_nz r4.z + mad r6.y, -r3.x, l(0.500000), r6.y + endif + lt r4.xz, |r6.xxyx|, r2.xxxx + if_nz r4.x + mad r5.x, -r3.y, l(12.000000), r5.x + mad r5.y, -r3.w, l(12.000000), r5.y + endif + if_nz r4.z + mad r4.y, r3.y, l(12.000000), r4.y + mad r4.w, r3.w, l(12.000000), r4.w + endif + endif + endif + endif + if_z r2.y + mad r2.x, r0.y, CB0[0][0].w, -r5.y + mad r0.x, -r0.y, CB0[0][0].w, r4.w + else + mad r2.x, r0.x, CB0[0][0].z, -r5.x + mad r0.x, -r0.x, CB0[0][0].z, r4.y + endif + lt r3.xy, r6.xyxx, l(0.000000, 0.000000, 0.000000, 0.000000) + add r0.y, r2.x, r0.x + ine r3.xy, r3.zzzz, r3.xyxx + div r0.y, l(1.000000, 1.000000, 1.000000, 1.000000), r0.y + lt r3.z, r2.x, r0.x + min r0.x, r0.x, r2.x + movc r2.x, r3.z, r3.x, r3.y + mul r2.w, r2.w, r2.w + mad r0.x, r0.x, -r0.y, l(0.500000) + mul r0.y, r2.w, l(0.750000) + and r0.x, r0.x, r2.x + max r0.x, r0.y, r0.x + if_z r2.y + mad r0.z, r0.x, r2.z, r0.z + endif + if_nz r2.y + mad r0.w, r0.x, r2.z, r0.w + endif + sample_l r1.xyz, r0.zwzz, T0[0].xyzw, S0[0], l(0.000000) +endif +mov r1.w, l(1.000000) +store_uav_typed U0[0].xyzw, vThreadID.xyyy, r1.xyzw +ret +// Approximately 205 instruction slots used +#endif + +const BYTE fxaa_cs[] = { + 68, 88, 66, 67, 166, 45, 113, 211, 255, 20, 36, 199, 11, 156, 236, 21, 81, 60, 246, + 32, 1, 0, 0, 0, 184, 23, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 108, 2, + 0, 0, 124, 2, 0, 0, 140, 2, 0, 0, 28, 23, 0, 0, 82, 68, 69, 70, 48, + 2, 0, 0, 1, 0, 0, 0, 44, 1, 0, 0, 4, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 8, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 244, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, + 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 115, 97, + 109, 112, 108, 101, 114, 95, 108, 105, 110, 101, 97, 114, 95, 99, 108, 97, 109, 112, 0, + 120, 101, 95, 102, 120, 97, 97, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, 102, + 120, 97, 97, 95, 100, 101, 115, 116, 0, 88, 101, 65, 112, 112, 108, 121, 71, 97, 109, + 109, 97, 82, 97, 109, 112, 67, 111, 110, 115, 116, 97, 110, 116, 115, 0, 171, 171, 16, + 1, 0, 0, 2, 0, 0, 0, 68, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 148, 1, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, + 0, 168, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 204, 1, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, + 0, 0, 0, 228, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, 102, 120, 97, 97, 95, 115, 105, 122, + 101, 0, 117, 105, 110, 116, 50, 0, 171, 1, 0, 19, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 161, 1, 0, 0, 120, 101, 95, 102, 120, 97, 97, 95, 115, 105, 122, 101, + 95, 105, 110, 118, 0, 102, 108, 111, 97, 116, 50, 0, 1, 0, 3, 0, 1, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 221, 1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, + 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, + 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 8, 0, 0, + 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 136, 20, 0, 0, 81, 0, 5, 0, 34, + 5, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, + 6, 70, 110, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 88, 24, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 0, 0, 0, 0, 156, 24, 0, 7, 70, 238, 49, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, + 0, 95, 0, 0, 2, 50, 0, 2, 0, 104, 0, 0, 2, 7, 0, 0, 0, 155, 0, + 0, 4, 16, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 80, 0, 0, 8, 50, + 0, 16, 0, 0, 0, 0, 0, 70, 0, 2, 0, 70, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, + 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 86, + 0, 0, 4, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 2, 0, 0, 0, 0, 10, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, + 0, 9, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, 166, + 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 13, + 242, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 70, 126, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 109, 0, 0, 11, 114, 0, 16, 0, 2, + 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 58, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, + 140, 1, 254, 1, 0, 114, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 0, 0, + 0, 0, 38, 119, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 96, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 51, 0, 0, + 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 51, 0, 0, 7, + 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, + 0, 3, 0, 0, 0, 52, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, + 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 51, 0, 0, 7, 34, + 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, + 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 51, 0, 0, 7, 130, 0, + 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 4, + 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 231, 251, 41, 62, 0, 0, 0, 8, 130, 0, 16, + 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 128, 65, 0, + 0, 0, 3, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 10, + 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 49, 153, 170, 61, 49, 0, 0, 7, + 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, + 0, 3, 0, 0, 0, 31, 0, 0, 3, 58, 0, 16, 0, 3, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 0, 3, 58, 0, 16, 0, 3, 0, 0, 0, 72, 0, 0, 142, 1, + 226, 1, 0, 130, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, + 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 72, 0, 0, 142, 1, 62, + 0, 0, 18, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 54, + 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 98, 0, 16, + 0, 4, 0, 0, 0, 6, 2, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 3, 0, + 0, 0, 14, 0, 0, 10, 130, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 58, 0, 16, 0, + 2, 0, 0, 0, 0, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 12, 98, 0, + 16, 0, 4, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 192, 0, 0, 0, 0, 86, 6, 16, 0, + 4, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, + 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 0, 0, 0, 7, 130, 0, + 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, + 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 192, 10, 0, 16, 0, 5, 0, 0, + 0, 50, 0, 0, 9, 130, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 192, 58, 0, 16, 0, 3, 0, 0, 0, 0, + 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 0, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 50, 0, + 0, 11, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 128, 129, 0, 0, 0, 4, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 26, 0, 16, 128, 129, 0, 0, 0, + 5, 0, 0, 0, 50, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, + 128, 129, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 58, 0, + 16, 128, 129, 0, 0, 0, 3, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 4, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 192, + 42, 0, 16, 0, 3, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 2, 0, 0, + 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 192, 26, 0, + 16, 0, 2, 0, 0, 0, 0, 0, 0, 8, 18, 0, 16, 0, 4, 0, 0, 0, 10, + 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 128, 129, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 8, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, + 0, 26, 0, 16, 128, 129, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 7, 66, 0, + 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 3, + 0, 0, 0, 29, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, + 4, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 50, 0, 0, 9, 66, 0, 16, + 0, 3, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 64, 42, 0, 16, 0, 3, 0, 0, 0, 31, 0, 0, 3, 26, 0, 16, 0, 2, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, + 3, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, + 0, 0, 54, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 7, + 66, 0, 16, 0, 2, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 21, 0, 0, 1, 50, 0, 0, 10, 34, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 171, 170, 170, 61, 58, + 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 8, 66, 0, 16, 0, + 3, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 10, 0, 16, + 0, 3, 0, 0, 0, 0, 0, 0, 8, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, + 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 29, + 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 128, 129, 0, 0, 0, + 3, 0, 0, 0, 58, 0, 16, 128, 129, 0, 0, 0, 3, 0, 0, 0, 52, 0, 0, + 9, 66, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 128, 129, 0, 0, 0, 3, 0, + 0, 0, 42, 0, 16, 128, 129, 0, 0, 0, 3, 0, 0, 0, 31, 0, 4, 3, 10, + 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 128, 65, 0, 0, 0, 2, 0, 0, 0, 21, 0, 0, 1, 56, 32, 0, + 8, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, + 16, 128, 129, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 9, 34, 0, 16, 0, 3, + 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, + 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 3, 26, + 0, 16, 0, 2, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 42, 0, 16, + 0, 0, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 34, 0, 16, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, + 0, 16, 0, 2, 0, 0, 0, 50, 0, 0, 9, 66, 0, 16, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 58, 0, 16, + 0, 0, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 0, 0, 0, 8, 50, + 0, 16, 0, 5, 0, 0, 0, 214, 5, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, + 150, 5, 16, 0, 4, 0, 0, 0, 0, 0, 0, 7, 162, 0, 16, 0, 4, 0, 0, + 0, 86, 13, 16, 0, 3, 0, 0, 0, 86, 9, 16, 0, 4, 0, 0, 0, 50, 0, + 0, 9, 66, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 192, 1, 64, 0, 0, 0, 0, 64, 64, 72, 0, 0, 13, + 66, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 70, 123, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 72, 0, 0, 13, 130, 0, 16, 0, 5, 0, 0, 0, 214, 5, 16, 0, 4, 0, 0, + 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 31, 0, 0, 3, 10, + 0, 16, 0, 4, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 18, 0, 0, + 1, 0, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 56, 0, 0, 7, 18, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 128, 62, 50, 0, 0, 10, 66, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, + 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 58, 0, + 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 49, 0, 0, 7, + 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 50, 0, 0, 10, 18, 0, 16, 0, 6, 0, 0, 0, 10, 0, + 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 42, + 0, 16, 0, 5, 0, 0, 0, 50, 0, 0, 10, 34, 0, 16, 0, 6, 0, 0, 0, + 10, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 63, 58, 0, 16, 0, 5, 0, 0, 0, 49, 0, 0, 8, 82, 0, 16, 0, 4, 0, + 0, 0, 6, 1, 16, 128, 129, 0, 0, 0, 6, 0, 0, 0, 6, 0, 16, 0, 2, + 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 10, + 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 192, 63, 10, 0, 16, 0, 5, 0, 0, 0, 50, 0, + 0, 10, 34, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 192, 63, 26, 0, 16, 0, 5, 0, 0, 0, + 21, 0, 0, 1, 60, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, + 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 42, 0, + 16, 0, 4, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 4, 0, 0, 0, 26, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 192, 63, 26, 0, 16, 0, + 4, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, + 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 192, 63, 58, 0, 16, 0, 4, 0, + 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 5, 0, 0, 0, 31, + 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 72, 0, 0, 13, 18, 0, 16, 0, + 6, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 54, 121, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 4, + 0, 0, 0, 72, 0, 0, 13, 34, 0, 16, 0, 6, 0, 0, 0, 214, 5, 16, 0, + 4, 0, 0, 0, 198, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 10, 18, + 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 63, 10, 0, 16, 0, 6, 0, 0, 0, 21, 0, 0, + 1, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 10, 34, 0, + 16, 0, 6, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 63, 26, 0, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, + 49, 0, 0, 8, 82, 0, 16, 0, 4, 0, 0, 0, 6, 1, 16, 128, 129, 0, 0, + 0, 6, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, + 16, 0, 4, 0, 0, 0, 50, 0, 0, 10, 18, 0, 16, 0, 5, 0, 0, 0, 26, + 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, + 10, 0, 16, 0, 5, 0, 0, 0, 50, 0, 0, 10, 34, 0, 16, 0, 5, 0, 0, + 0, 58, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 64, 26, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 60, 0, 0, 7, 66, + 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, + 9, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 64, 26, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 9, 130, + 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 64, 58, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, + 3, 42, 0, 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, + 0, 0, 72, 0, 0, 13, 18, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 5, + 0, 0, 0, 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, + 1, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 72, 0, 0, 13, 34, 0, + 16, 0, 6, 0, 0, 0, 214, 5, 16, 0, 4, 0, 0, 0, 198, 121, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, + 0, 4, 0, 0, 0, 50, 0, 0, 10, 18, 0, 16, 0, 6, 0, 0, 0, 10, 0, + 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 10, + 0, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, + 4, 0, 0, 0, 50, 0, 0, 10, 34, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, + 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 26, 0, + 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 49, 0, 0, 8, 82, 0, 16, 0, 4, + 0, 0, 0, 6, 1, 16, 128, 129, 0, 0, 0, 6, 0, 0, 0, 6, 0, 16, 0, + 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, + 10, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 128, 64, 10, 0, 16, 0, 5, 0, 0, 0, 50, + 0, 0, 10, 34, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, + 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 64, 26, 0, 16, 0, 5, 0, 0, + 0, 21, 0, 0, 1, 60, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 42, + 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 4, 0, 0, 0, + 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 64, 26, 0, 16, + 0, 4, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 64, 58, 0, 16, 0, 4, + 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 5, 0, 0, 0, + 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 72, 0, 0, 13, 18, 0, 16, + 0, 6, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 54, 121, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, + 4, 0, 0, 0, 72, 0, 0, 13, 34, 0, 16, 0, 6, 0, 0, 0, 214, 5, 16, + 0, 4, 0, 0, 0, 198, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 10, + 18, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 63, 10, 0, 16, 0, 6, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 10, 34, + 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 63, 26, 0, 16, 0, 6, 0, 0, 0, 21, 0, 0, + 1, 49, 0, 0, 8, 82, 0, 16, 0, 4, 0, 0, 0, 6, 1, 16, 128, 129, 0, + 0, 0, 6, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, + 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 10, 18, 0, 16, 0, 5, 0, 0, 0, + 26, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 64, + 65, 10, 0, 16, 0, 5, 0, 0, 0, 50, 0, 0, 10, 34, 0, 16, 0, 5, 0, + 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 64, 65, 26, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, + 42, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 4, 0, 0, + 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 64, 65, 26, 0, + 16, 0, 4, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 4, 0, 0, 0, 58, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 64, 65, 58, 0, 16, 0, + 4, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, + 1, 31, 0, 0, 3, 26, 0, 16, 0, 2, 0, 0, 0, 50, 0, 0, 12, 18, 0, + 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, + 5, 0, 0, 0, 50, 0, 0, 12, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 128, 65, 0, 0, 0, 0, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 18, 0, 0, 1, 50, + 0, 0, 12, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, + 128, 65, 0, 0, 0, 5, 0, 0, 0, 50, 0, 0, 12, 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 42, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, + 21, 0, 0, 1, 49, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, + 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 39, 0, 0, 7, + 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 3, 0, 0, 0, 70, 0, 16, + 0, 3, 0, 0, 0, 14, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 26, + 0, 16, 0, 0, 0, 0, 0, 49, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 51, 0, 0, + 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, + 3, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, + 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 50, 0, 0, 10, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 128, 65, + 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 56, 0, 0, 7, + 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 64, 63, 1, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 52, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 31, 0, 0, 3, 26, 0, 16, 0, 2, 0, 0, 0, 50, 0, 0, + 9, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, + 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 72, 0, 0, 13, 114, 0, + 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 54, 0, 0, 5, 130, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 164, 0, 0, 7, 242, 224, + 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 5, 2, 0, 70, 14, 16, 0, 1, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 205, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 94, 0, 0, 0, 1, 0, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, + 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/fxaa_extreme_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/fxaa_extreme_cs.h new file mode 100644 index 0000000..41c889f --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/fxaa_extreme_cs.h @@ -0,0 +1,901 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer XeApplyGammaRampConstants +// { +// +// uint2 xe_fxaa_size; // Offset: 0 Size: 8 +// float2 xe_fxaa_size_inv; // Offset: 8 Size: 8 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_sampler_linear_clamp sampler NA NA S0 s0 1 +// xe_fxaa_source texture float4 2d T0 t0 1 +// xe_fxaa_dest UAV unorm4 2d U0 u0 1 +// XeApplyGammaRampConstants cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_sampler S0[0:0], mode_default, space=0 +dcl_resource_texture2d (float,float,float,float) T0[0:0], space=0 +dcl_uav_typed_texture2d (unorm,unorm,unorm,unorm) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 7 +dcl_thread_group 16, 8, 1 +uge r0.xy, vThreadID.xyxx, CB0[0][0].xyxx +or r0.x, r0.y, r0.x +if_nz r0.x + ret +endif +utof r0.xy, vThreadID.xyxx +add r0.xy, r0.xyxx, l(0.500000, 0.500000, 0.000000, 0.000000) +mul r0.zw, r0.xxxy, CB0[0][0].zzzw +sample_l r1.xyzw, r0.zwzz, T0[0].xyzw, S0[0], l(0.000000) +gather4 r2.xyz, r0.zwzz, T0[0].xyzw, S0[0].w +gather4_aoffimmi(-1,-1,0) r3.xyz, r0.zwzz, T0[0].zxwy, S0[0].w +max r2.w, r1.w, r2.x +min r3.w, r1.w, r2.x +max r2.w, r2.w, r2.z +min r3.w, r2.z, r3.w +max r4.x, r3.y, r3.x +min r4.y, r3.y, r3.x +max r2.w, r2.w, r4.x +min r3.w, r3.w, r4.y +mul r4.x, r2.w, l(0.063000) +add r2.w, r2.w, -r3.w +max r3.w, r4.x, l(0.031200) +lt r3.w, r2.w, r3.w +if_z r3.w +endif +if_z r3.w + sample_l_aoffimmi(1,-1,0) r3.w, r0.zwzz, T0[0].xyzw, S0[0], l(0.000000) + sample_l_aoffimmi(-1,1,0) r4.x, r0.zwzz, T0[0].wxyz, S0[0], l(0.000000) + add r4.yz, r2.xxzx, r3.xxyx + div r2.w, l(1.000000, 1.000000, 1.000000, 1.000000), r2.w + add r4.w, r4.z, r4.y + mad r4.yz, r1.wwww, l(0.000000, -2.000000, -2.000000, 0.000000), r4.yyzy + add r5.x, r2.y, r3.w + add r3.w, r3.w, r3.z + mad r5.y, r2.z, l(-2.000000), r5.x + mad r3.w, r3.x, l(-2.000000), r3.w + add r3.z, r3.z, r4.x + add r2.y, r2.y, r4.x + mad r4.x, |r4.y|, l(2.000000), |r5.y| + mad r3.w, |r4.z|, l(2.000000), |r3.w| + mad r4.y, r3.y, l(-2.000000), r3.z + mad r2.y, r2.x, l(-2.000000), r2.y + add r4.x, r4.x, |r4.y| + add r2.y, r3.w, |r2.y| + add r3.z, r5.x, r3.z + ge r2.y, r4.x, r2.y + mad r3.z, r4.w, l(2.000000), r3.z + if_z r2.y + mov r3.x, r3.y + mov r2.x, r2.z + endif + if_nz r2.y + mov r2.z, CB0[0][0].w + else + mov r2.z, CB0[0][0].z + endif + mad r3.y, r3.z, l(0.083333), -r1.w + add r3.z, -r1.w, r3.x + add r3.w, -r1.w, r2.x + ge r4.x, |r3.z|, |r3.w| + max r3.z, |r3.w|, |r3.z| + if_nz r4.x + mov r2.z, -r2.z + endif + mul_sat r2.w, r2.w, |r3.y| + and r3.y, r2.y, CB0[0][0].z + movc r3.w, r2.y, l(0), CB0[0][0].w + if_z r2.y + mad r4.y, r2.z, l(0.500000), r0.z + else + mov r4.y, r0.z + endif + if_nz r2.y + mad r4.z, r2.z, l(0.500000), r0.w + else + mov r4.z, r0.w + endif + add r5.xy, -r3.ywyy, r4.yzyy + add r4.yw, r3.yyyw, r4.yyyz + mad r4.z, r2.w, l(-2.000000), l(3.000000) + sample_l r5.z, r5.xyxx, T0[0].xywz, S0[0], l(0.000000) + mul r2.w, r2.w, r2.w + sample_l r5.w, r4.ywyy, T0[0].xyzw, S0[0], l(0.000000) + if_z r4.x + add r3.x, r1.w, r2.x + else + add r3.x, r1.w, r3.x + endif + mul r2.x, r3.z, l(0.250000) + mad r3.z, -r3.x, l(0.500000), r1.w + mul r2.w, r2.w, r4.z + lt r3.z, r3.z, l(0.000000) + mad r6.x, -r3.x, l(0.500000), r5.z + mad r6.y, -r3.x, l(0.500000), r5.w + lt r4.xz, |r6.xxyx|, r2.xxxx + if_nz r4.x + add r5.xy, -r3.ywyy, r5.xyxx + endif + or r5.z, r4.z, r4.x + if_nz r4.z + add r4.yw, r3.yyyw, r4.yyyw + endif + if_nz r5.z + if_nz r4.x + sample_l r6.x, r5.xyxx, T0[0].wxyz, S0[0], l(0.000000) + endif + if_nz r4.z + sample_l r6.y, r4.ywyy, T0[0].xwyz, S0[0], l(0.000000) + endif + if_nz r4.x + mad r6.x, -r3.x, l(0.500000), r6.x + endif + if_nz r4.z + mad r6.y, -r3.x, l(0.500000), r6.y + endif + lt r4.xz, |r6.xxyx|, r2.xxxx + if_nz r4.x + add r5.xy, -r3.ywyy, r5.xyxx + endif + or r5.z, r4.z, r4.x + if_nz r4.z + add r4.yw, r3.yyyw, r4.yyyw + endif + if_nz r5.z + if_nz r4.x + sample_l r6.x, r5.xyxx, T0[0].wxyz, S0[0], l(0.000000) + endif + if_nz r4.z + sample_l r6.y, r4.ywyy, T0[0].xwyz, S0[0], l(0.000000) + endif + if_nz r4.x + mad r6.x, -r3.x, l(0.500000), r6.x + endif + if_nz r4.z + mad r6.y, -r3.x, l(0.500000), r6.y + endif + lt r4.xz, |r6.xxyx|, r2.xxxx + if_nz r4.x + add r5.xy, -r3.ywyy, r5.xyxx + endif + or r5.z, r4.z, r4.x + if_nz r4.z + add r4.yw, r3.yyyw, r4.yyyw + endif + if_nz r5.z + if_nz r4.x + sample_l r6.x, r5.xyxx, T0[0].wxyz, S0[0], l(0.000000) + endif + if_nz r4.z + sample_l r6.y, r4.ywyy, T0[0].xwyz, S0[0], l(0.000000) + endif + if_nz r4.x + mad r6.x, -r3.x, l(0.500000), r6.x + endif + if_nz r4.z + mad r6.y, -r3.x, l(0.500000), r6.y + endif + lt r4.xz, |r6.xxyx|, r2.xxxx + if_nz r4.x + add r5.xy, -r3.ywyy, r5.xyxx + endif + or r5.z, r4.z, r4.x + if_nz r4.z + add r4.yw, r3.yyyw, r4.yyyw + endif + if_nz r5.z + if_nz r4.x + sample_l r6.x, r5.xyxx, T0[0].wxyz, S0[0], l(0.000000) + endif + if_nz r4.z + sample_l r6.y, r4.ywyy, T0[0].xwyz, S0[0], l(0.000000) + endif + if_nz r4.x + mad r6.x, -r3.x, l(0.500000), r6.x + endif + if_nz r4.z + mad r6.y, -r3.x, l(0.500000), r6.y + endif + lt r4.xz, |r6.xxyx|, r2.xxxx + if_nz r4.x + mad r5.x, -r3.y, l(1.500000), r5.x + mad r5.y, -r3.w, l(1.500000), r5.y + endif + or r5.z, r4.z, r4.x + if_nz r4.z + mad r4.y, r3.y, l(1.500000), r4.y + mad r4.w, r3.w, l(1.500000), r4.w + endif + if_nz r5.z + if_nz r4.x + sample_l r6.x, r5.xyxx, T0[0].wxyz, S0[0], l(0.000000) + endif + if_nz r4.z + sample_l r6.y, r4.ywyy, T0[0].xwyz, S0[0], l(0.000000) + endif + if_nz r4.x + mad r6.x, -r3.x, l(0.500000), r6.x + endif + if_nz r4.z + mad r6.y, -r3.x, l(0.500000), r6.y + endif + lt r4.xz, |r6.xxyx|, r2.xxxx + if_nz r4.x + mad r5.x, -r3.y, l(2.000000), r5.x + mad r5.y, -r3.w, l(2.000000), r5.y + endif + or r5.z, r4.z, r4.x + if_nz r4.z + mad r4.y, r3.y, l(2.000000), r4.y + mad r4.w, r3.w, l(2.000000), r4.w + endif + if_nz r5.z + if_nz r4.x + sample_l r6.x, r5.xyxx, T0[0].wxyz, S0[0], l(0.000000) + endif + if_nz r4.z + sample_l r6.y, r4.ywyy, T0[0].xwyz, S0[0], l(0.000000) + endif + if_nz r4.x + mad r6.x, -r3.x, l(0.500000), r6.x + endif + if_nz r4.z + mad r6.y, -r3.x, l(0.500000), r6.y + endif + lt r4.xz, |r6.xxyx|, r2.xxxx + if_nz r4.x + mad r5.x, -r3.y, l(2.000000), r5.x + mad r5.y, -r3.w, l(2.000000), r5.y + endif + or r5.z, r4.z, r4.x + if_nz r4.z + mad r4.y, r3.y, l(2.000000), r4.y + mad r4.w, r3.w, l(2.000000), r4.w + endif + if_nz r5.z + if_nz r4.x + sample_l r6.x, r5.xyxx, T0[0].wxyz, S0[0], l(0.000000) + endif + if_nz r4.z + sample_l r6.y, r4.ywyy, T0[0].xwyz, S0[0], l(0.000000) + endif + if_nz r4.x + mad r6.x, -r3.x, l(0.500000), r6.x + endif + if_nz r4.z + mad r6.y, -r3.x, l(0.500000), r6.y + endif + lt r4.xz, |r6.xxyx|, r2.xxxx + if_nz r4.x + mad r5.x, -r3.y, l(2.000000), r5.x + mad r5.y, -r3.w, l(2.000000), r5.y + endif + or r5.z, r4.z, r4.x + if_nz r4.z + mad r4.y, r3.y, l(2.000000), r4.y + mad r4.w, r3.w, l(2.000000), r4.w + endif + if_nz r5.z + if_nz r4.x + sample_l r6.x, r5.xyxx, T0[0].wxyz, S0[0], l(0.000000) + endif + if_nz r4.z + sample_l r6.y, r4.ywyy, T0[0].xwyz, S0[0], l(0.000000) + endif + if_nz r4.x + mad r6.x, -r3.x, l(0.500000), r6.x + endif + if_nz r4.z + mad r6.y, -r3.x, l(0.500000), r6.y + endif + lt r4.xz, |r6.xxyx|, r2.xxxx + if_nz r4.x + mad r5.x, -r3.y, l(2.000000), r5.x + mad r5.y, -r3.w, l(2.000000), r5.y + endif + or r5.z, r4.z, r4.x + if_nz r4.z + mad r4.y, r3.y, l(2.000000), r4.y + mad r4.w, r3.w, l(2.000000), r4.w + endif + if_nz r5.z + if_nz r4.x + sample_l r6.x, r5.xyxx, T0[0].wxyz, S0[0], l(0.000000) + endif + if_nz r4.z + sample_l r6.y, r4.ywyy, T0[0].xwyz, S0[0], l(0.000000) + endif + if_nz r4.x + mad r6.x, -r3.x, l(0.500000), r6.x + endif + if_nz r4.z + mad r6.y, -r3.x, l(0.500000), r6.y + endif + lt r4.xz, |r6.xxyx|, r2.xxxx + if_nz r4.x + mad r5.x, -r3.y, l(4.000000), r5.x + mad r5.y, -r3.w, l(4.000000), r5.y + endif + or r5.z, r4.z, r4.x + if_nz r4.z + mad r4.y, r3.y, l(4.000000), r4.y + mad r4.w, r3.w, l(4.000000), r4.w + endif + if_nz r5.z + if_nz r4.x + sample_l r6.x, r5.xyxx, T0[0].wxyz, S0[0], l(0.000000) + endif + if_nz r4.z + sample_l r6.y, r4.ywyy, T0[0].xwyz, S0[0], l(0.000000) + endif + if_nz r4.x + mad r6.x, -r3.x, l(0.500000), r6.x + endif + if_nz r4.z + mad r6.y, -r3.x, l(0.500000), r6.y + endif + lt r4.xz, |r6.xxyx|, r2.xxxx + if_nz r4.x + mad r5.x, -r3.y, l(8.000000), r5.x + mad r5.y, -r3.w, l(8.000000), r5.y + endif + if_nz r4.z + mad r4.y, r3.y, l(8.000000), r4.y + mad r4.w, r3.w, l(8.000000), r4.w + endif + endif + endif + endif + endif + endif + endif + endif + endif + endif + endif + if_z r2.y + mad r2.x, r0.y, CB0[0][0].w, -r5.y + mad r0.x, -r0.y, CB0[0][0].w, r4.w + else + mad r2.x, r0.x, CB0[0][0].z, -r5.x + mad r0.x, -r0.x, CB0[0][0].z, r4.y + endif + lt r3.xy, r6.xyxx, l(0.000000, 0.000000, 0.000000, 0.000000) + add r0.y, r2.x, r0.x + ine r3.xy, r3.zzzz, r3.xyxx + div r0.y, l(1.000000, 1.000000, 1.000000, 1.000000), r0.y + lt r3.z, r2.x, r0.x + min r0.x, r0.x, r2.x + movc r2.x, r3.z, r3.x, r3.y + mul r2.w, r2.w, r2.w + mad r0.x, r0.x, -r0.y, l(0.500000) + and r0.x, r0.x, r2.x + max r0.x, r2.w, r0.x + if_z r2.y + mad r0.z, r0.x, r2.z, r0.z + endif + if_nz r2.y + mad r0.w, r0.x, r2.z, r0.w + endif + sample_l r1.xyz, r0.zwzz, T0[0].xyzw, S0[0], l(0.000000) +endif +mov r1.w, l(1.000000) +store_uav_typed U0[0].xyzw, vThreadID.xyyy, r1.xyzw +ret +// Approximately 364 instruction slots used +#endif + +const BYTE fxaa_extreme_cs[] = { + 68, 88, 66, 67, 201, 241, 80, 129, 142, 182, 61, 91, 66, 45, 161, 133, 204, 62, 115, + 180, 1, 0, 0, 0, 16, 36, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 108, 2, + 0, 0, 124, 2, 0, 0, 140, 2, 0, 0, 116, 35, 0, 0, 82, 68, 69, 70, 48, + 2, 0, 0, 1, 0, 0, 0, 44, 1, 0, 0, 4, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 8, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 244, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, + 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 115, 97, + 109, 112, 108, 101, 114, 95, 108, 105, 110, 101, 97, 114, 95, 99, 108, 97, 109, 112, 0, + 120, 101, 95, 102, 120, 97, 97, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, 102, + 120, 97, 97, 95, 100, 101, 115, 116, 0, 88, 101, 65, 112, 112, 108, 121, 71, 97, 109, + 109, 97, 82, 97, 109, 112, 67, 111, 110, 115, 116, 97, 110, 116, 115, 0, 171, 171, 16, + 1, 0, 0, 2, 0, 0, 0, 68, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 148, 1, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, + 0, 168, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 204, 1, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, + 0, 0, 0, 228, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, 102, 120, 97, 97, 95, 115, 105, 122, + 101, 0, 117, 105, 110, 116, 50, 0, 171, 1, 0, 19, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 161, 1, 0, 0, 120, 101, 95, 102, 120, 97, 97, 95, 115, 105, 122, 101, + 95, 105, 110, 118, 0, 102, 108, 111, 97, 116, 50, 0, 1, 0, 3, 0, 1, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 221, 1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, + 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, + 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 8, 0, 0, + 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 224, 32, 0, 0, 81, 0, 5, 0, 56, + 8, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, + 6, 70, 110, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 88, 24, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 0, 0, 0, 0, 156, 24, 0, 7, 70, 238, 49, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, + 0, 95, 0, 0, 2, 50, 0, 2, 0, 104, 0, 0, 2, 7, 0, 0, 0, 155, 0, + 0, 4, 16, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 80, 0, 0, 8, 50, + 0, 16, 0, 0, 0, 0, 0, 70, 0, 2, 0, 70, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, + 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 86, + 0, 0, 4, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 2, 0, 0, 0, 0, 10, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, + 0, 9, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, 166, + 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 13, + 242, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 70, 126, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 109, 0, 0, 11, 114, 0, 16, 0, 2, + 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 58, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, + 140, 1, 254, 1, 0, 114, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 0, 0, + 0, 0, 38, 119, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 96, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 51, 0, 0, + 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 51, 0, 0, 7, + 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, + 0, 3, 0, 0, 0, 52, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, + 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 51, 0, 0, 7, 34, + 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, + 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 51, 0, 0, 7, 130, 0, + 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 4, + 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 37, 6, 129, 61, 0, 0, 0, 8, 130, 0, 16, + 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 128, 65, 0, + 0, 0, 3, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 10, + 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 36, 151, 255, 60, 49, 0, 0, 7, + 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, + 0, 3, 0, 0, 0, 31, 0, 0, 3, 58, 0, 16, 0, 3, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 0, 3, 58, 0, 16, 0, 3, 0, 0, 0, 72, 0, 0, 142, 1, + 226, 1, 0, 130, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, + 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 72, 0, 0, 142, 1, 62, + 0, 0, 18, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 54, + 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 98, 0, 16, + 0, 4, 0, 0, 0, 6, 2, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 3, 0, + 0, 0, 14, 0, 0, 10, 130, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 58, 0, 16, 0, + 2, 0, 0, 0, 0, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 12, 98, 0, + 16, 0, 4, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 192, 0, 0, 0, 0, 86, 6, 16, 0, + 4, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, + 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 0, 0, 0, 7, 130, 0, + 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, + 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 192, 10, 0, 16, 0, 5, 0, 0, + 0, 50, 0, 0, 9, 130, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 192, 58, 0, 16, 0, 3, 0, 0, 0, 0, + 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 0, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 50, 0, + 0, 11, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 128, 129, 0, 0, 0, 4, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 26, 0, 16, 128, 129, 0, 0, 0, + 5, 0, 0, 0, 50, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, + 128, 129, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 58, 0, + 16, 128, 129, 0, 0, 0, 3, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 4, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 192, + 42, 0, 16, 0, 3, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 2, 0, 0, + 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 192, 26, 0, + 16, 0, 2, 0, 0, 0, 0, 0, 0, 8, 18, 0, 16, 0, 4, 0, 0, 0, 10, + 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 128, 129, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 8, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, + 0, 26, 0, 16, 128, 129, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 7, 66, 0, + 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 3, + 0, 0, 0, 29, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, + 4, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 50, 0, 0, 9, 66, 0, 16, + 0, 3, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 64, 42, 0, 16, 0, 3, 0, 0, 0, 31, 0, 0, 3, 26, 0, 16, 0, 2, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, + 3, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, + 0, 0, 54, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 7, + 66, 0, 16, 0, 2, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 21, 0, 0, 1, 50, 0, 0, 10, 34, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 171, 170, 170, 61, 58, + 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 8, 66, 0, 16, 0, + 3, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 10, 0, 16, + 0, 3, 0, 0, 0, 0, 0, 0, 8, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, + 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 29, + 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 128, 129, 0, 0, 0, + 3, 0, 0, 0, 58, 0, 16, 128, 129, 0, 0, 0, 3, 0, 0, 0, 52, 0, 0, + 9, 66, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 128, 129, 0, 0, 0, 3, 0, + 0, 0, 42, 0, 16, 128, 129, 0, 0, 0, 3, 0, 0, 0, 31, 0, 4, 3, 10, + 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 128, 65, 0, 0, 0, 2, 0, 0, 0, 21, 0, 0, 1, 56, 32, 0, + 8, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, + 16, 128, 129, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 9, 34, 0, 16, 0, 3, + 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, + 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 3, 26, + 0, 16, 0, 2, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 42, 0, 16, + 0, 0, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 34, 0, 16, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, + 0, 16, 0, 2, 0, 0, 0, 50, 0, 0, 9, 66, 0, 16, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 58, 0, 16, + 0, 0, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 0, 0, 0, 8, 50, + 0, 16, 0, 5, 0, 0, 0, 214, 5, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, + 150, 5, 16, 0, 4, 0, 0, 0, 0, 0, 0, 7, 162, 0, 16, 0, 4, 0, 0, + 0, 86, 13, 16, 0, 3, 0, 0, 0, 86, 9, 16, 0, 4, 0, 0, 0, 50, 0, + 0, 9, 66, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 192, 1, 64, 0, 0, 0, 0, 64, 64, 72, 0, 0, 13, + 66, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 70, 123, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 72, 0, 0, 13, 130, 0, 16, 0, 5, 0, 0, 0, 214, 5, 16, 0, 4, 0, 0, + 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 31, 0, 0, 3, 10, + 0, 16, 0, 4, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 18, 0, 0, + 1, 0, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 56, 0, 0, 7, 18, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 128, 62, 50, 0, 0, 10, 66, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, + 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 58, 0, + 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 49, 0, 0, 7, + 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 50, 0, 0, 10, 18, 0, 16, 0, 6, 0, 0, 0, 10, 0, + 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 42, + 0, 16, 0, 5, 0, 0, 0, 50, 0, 0, 10, 34, 0, 16, 0, 6, 0, 0, 0, + 10, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 63, 58, 0, 16, 0, 5, 0, 0, 0, 49, 0, 0, 8, 82, 0, 16, 0, 4, 0, + 0, 0, 6, 1, 16, 128, 129, 0, 0, 0, 6, 0, 0, 0, 6, 0, 16, 0, 2, + 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 0, 0, 0, 8, + 50, 0, 16, 0, 5, 0, 0, 0, 214, 5, 16, 128, 65, 0, 0, 0, 3, 0, 0, + 0, 70, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 60, 0, 0, 7, 66, 0, + 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, + 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 0, 0, 0, 7, + 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 3, 0, 0, 0, 86, 13, 16, + 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 5, 0, + 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 72, 0, 0, 13, 18, + 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 54, 121, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, + 16, 0, 4, 0, 0, 0, 72, 0, 0, 13, 34, 0, 16, 0, 6, 0, 0, 0, 214, + 5, 16, 0, 4, 0, 0, 0, 198, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 21, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 50, 0, + 0, 10, 18, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 10, 0, 16, 0, 6, 0, 0, 0, + 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, + 10, 34, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 26, 0, 16, 0, 6, 0, 0, 0, 21, + 0, 0, 1, 49, 0, 0, 8, 82, 0, 16, 0, 4, 0, 0, 0, 6, 1, 16, 128, + 129, 0, 0, 0, 6, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 4, 0, 0, 0, 0, 0, 0, 8, 50, 0, 16, 0, 5, 0, + 0, 0, 214, 5, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 70, 0, 16, 0, 5, + 0, 0, 0, 21, 0, 0, 1, 60, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, + 42, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, + 3, 42, 0, 16, 0, 4, 0, 0, 0, 0, 0, 0, 7, 162, 0, 16, 0, 4, 0, + 0, 0, 86, 13, 16, 0, 3, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, + 10, 0, 16, 0, 4, 0, 0, 0, 72, 0, 0, 13, 18, 0, 16, 0, 6, 0, 0, + 0, 70, 0, 16, 0, 5, 0, 0, 0, 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, + 72, 0, 0, 13, 34, 0, 16, 0, 6, 0, 0, 0, 214, 5, 16, 0, 4, 0, 0, + 0, 198, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, + 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 10, 18, 0, 16, 0, + 6, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 63, 10, 0, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, + 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 10, 34, 0, 16, 0, 6, + 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 63, 26, 0, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 49, 0, 0, + 8, 82, 0, 16, 0, 4, 0, 0, 0, 6, 1, 16, 128, 129, 0, 0, 0, 6, 0, + 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, + 0, 0, 0, 0, 0, 0, 8, 50, 0, 16, 0, 5, 0, 0, 0, 214, 5, 16, 128, + 65, 0, 0, 0, 3, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, + 1, 60, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, + 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 4, + 0, 0, 0, 0, 0, 0, 7, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, + 3, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, + 3, 42, 0, 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, + 0, 0, 72, 0, 0, 13, 18, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 5, + 0, 0, 0, 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, + 1, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 72, 0, 0, 13, 34, 0, + 16, 0, 6, 0, 0, 0, 214, 5, 16, 0, 4, 0, 0, 0, 198, 121, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, + 0, 4, 0, 0, 0, 50, 0, 0, 10, 18, 0, 16, 0, 6, 0, 0, 0, 10, 0, + 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 10, + 0, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, + 4, 0, 0, 0, 50, 0, 0, 10, 34, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, + 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 26, 0, + 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 49, 0, 0, 8, 82, 0, 16, 0, 4, + 0, 0, 0, 6, 1, 16, 128, 129, 0, 0, 0, 6, 0, 0, 0, 6, 0, 16, 0, + 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 0, 0, 0, + 8, 50, 0, 16, 0, 5, 0, 0, 0, 214, 5, 16, 128, 65, 0, 0, 0, 3, 0, + 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 60, 0, 0, 7, 66, + 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 0, 0, 0, + 7, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 3, 0, 0, 0, 86, 13, + 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 5, + 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 72, 0, 0, 13, + 18, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 54, 121, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, + 0, 16, 0, 4, 0, 0, 0, 72, 0, 0, 13, 34, 0, 16, 0, 6, 0, 0, 0, + 214, 5, 16, 0, 4, 0, 0, 0, 198, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 50, + 0, 0, 10, 18, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, + 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 10, 0, 16, 0, 6, 0, 0, + 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 50, 0, + 0, 10, 34, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 26, 0, 16, 0, 6, 0, 0, 0, + 21, 0, 0, 1, 49, 0, 0, 8, 82, 0, 16, 0, 4, 0, 0, 0, 6, 1, 16, + 128, 129, 0, 0, 0, 6, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 31, 0, + 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 10, 18, 0, 16, 0, 5, + 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 192, 63, 10, 0, 16, 0, 5, 0, 0, 0, 50, 0, 0, 10, 34, 0, 16, + 0, 5, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 192, 63, 26, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 60, + 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, + 0, 50, 0, 0, 9, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 192, 63, 26, 0, 16, 0, 4, 0, 0, 0, 50, + 0, 0, 9, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 192, 63, 58, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, + 1, 31, 0, 4, 3, 42, 0, 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 10, 0, + 16, 0, 4, 0, 0, 0, 72, 0, 0, 13, 18, 0, 16, 0, 6, 0, 0, 0, 70, + 0, 16, 0, 5, 0, 0, 0, 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 72, 0, + 0, 13, 34, 0, 16, 0, 6, 0, 0, 0, 214, 5, 16, 0, 4, 0, 0, 0, 198, + 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, + 3, 10, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 10, 18, 0, 16, 0, 6, 0, + 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 63, 10, 0, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, + 42, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 10, 34, 0, 16, 0, 6, 0, 0, + 0, 10, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 63, 26, 0, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 49, 0, 0, 8, 82, + 0, 16, 0, 4, 0, 0, 0, 6, 1, 16, 128, 129, 0, 0, 0, 6, 0, 0, 0, + 6, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, + 0, 50, 0, 0, 10, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 128, 65, 0, + 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 10, 0, 16, 0, 5, + 0, 0, 0, 50, 0, 0, 10, 34, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 128, + 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 26, 0, 16, + 0, 5, 0, 0, 0, 21, 0, 0, 1, 60, 0, 0, 7, 66, 0, 16, 0, 5, 0, + 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 31, + 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, + 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 64, 26, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 58, + 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, + 5, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 72, 0, 0, + 13, 18, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 54, 121, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, + 42, 0, 16, 0, 4, 0, 0, 0, 72, 0, 0, 13, 34, 0, 16, 0, 6, 0, 0, + 0, 214, 5, 16, 0, 4, 0, 0, 0, 198, 121, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, + 50, 0, 0, 10, 18, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, + 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 10, 0, 16, 0, 6, 0, + 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 50, + 0, 0, 10, 34, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, + 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 26, 0, 16, 0, 6, 0, 0, + 0, 21, 0, 0, 1, 49, 0, 0, 8, 82, 0, 16, 0, 4, 0, 0, 0, 6, 1, + 16, 128, 129, 0, 0, 0, 6, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 31, + 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 10, 18, 0, 16, 0, + 5, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 64, 10, 0, 16, 0, 5, 0, 0, 0, 50, 0, 0, 10, 34, 0, + 16, 0, 5, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 64, 26, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, + 60, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, + 0, 10, 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, + 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 26, 0, 16, 0, 4, 0, 0, 0, + 50, 0, 0, 9, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 64, 58, 0, 16, 0, 4, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 10, + 0, 16, 0, 4, 0, 0, 0, 72, 0, 0, 13, 18, 0, 16, 0, 6, 0, 0, 0, + 70, 0, 16, 0, 5, 0, 0, 0, 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 72, + 0, 0, 13, 34, 0, 16, 0, 6, 0, 0, 0, 214, 5, 16, 0, 4, 0, 0, 0, + 198, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, + 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 10, 18, 0, 16, 0, 6, + 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 63, 10, 0, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, + 3, 42, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 10, 34, 0, 16, 0, 6, 0, + 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 63, 26, 0, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 49, 0, 0, 8, + 82, 0, 16, 0, 4, 0, 0, 0, 6, 1, 16, 128, 129, 0, 0, 0, 6, 0, 0, + 0, 6, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, + 0, 0, 50, 0, 0, 10, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 128, 65, + 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 10, 0, 16, 0, + 5, 0, 0, 0, 50, 0, 0, 10, 34, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, + 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 26, 0, + 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 60, 0, 0, 7, 66, 0, 16, 0, 5, + 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, + 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, + 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 64, 26, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 4, + 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, + 58, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, + 0, 5, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 72, 0, + 0, 13, 18, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 54, + 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, + 3, 42, 0, 16, 0, 4, 0, 0, 0, 72, 0, 0, 13, 34, 0, 16, 0, 6, 0, + 0, 0, 214, 5, 16, 0, 4, 0, 0, 0, 198, 121, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, + 0, 50, 0, 0, 10, 18, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 128, 65, 0, + 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 10, 0, 16, 0, 6, + 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, + 50, 0, 0, 10, 34, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, + 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 26, 0, 16, 0, 6, 0, + 0, 0, 21, 0, 0, 1, 49, 0, 0, 8, 82, 0, 16, 0, 4, 0, 0, 0, 6, + 1, 16, 128, 129, 0, 0, 0, 6, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, + 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 10, 18, 0, 16, + 0, 5, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 64, 10, 0, 16, 0, 5, 0, 0, 0, 50, 0, 0, 10, 34, + 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 64, 26, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, + 1, 60, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, + 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 4, + 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, + 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 26, 0, 16, 0, 4, 0, 0, + 0, 50, 0, 0, 9, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 58, 0, 16, 0, 4, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, + 10, 0, 16, 0, 4, 0, 0, 0, 72, 0, 0, 13, 18, 0, 16, 0, 6, 0, 0, + 0, 70, 0, 16, 0, 5, 0, 0, 0, 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, + 72, 0, 0, 13, 34, 0, 16, 0, 6, 0, 0, 0, 214, 5, 16, 0, 4, 0, 0, + 0, 198, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, + 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 10, 18, 0, 16, 0, + 6, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 63, 10, 0, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, + 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 10, 34, 0, 16, 0, 6, + 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 63, 26, 0, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 49, 0, 0, + 8, 82, 0, 16, 0, 4, 0, 0, 0, 6, 1, 16, 128, 129, 0, 0, 0, 6, 0, + 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, + 0, 0, 0, 50, 0, 0, 10, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 128, + 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 64, 10, 0, 16, + 0, 5, 0, 0, 0, 50, 0, 0, 10, 34, 0, 16, 0, 5, 0, 0, 0, 58, 0, + 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 64, 26, + 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 60, 0, 0, 7, 66, 0, 16, 0, + 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, + 0, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 9, 34, 0, + 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 128, 64, 26, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, + 4, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, + 64, 58, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, + 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 72, + 0, 0, 13, 18, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, + 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, + 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 72, 0, 0, 13, 34, 0, 16, 0, 6, + 0, 0, 0, 214, 5, 16, 0, 4, 0, 0, 0, 198, 121, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, + 0, 0, 50, 0, 0, 10, 18, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 128, 65, + 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 10, 0, 16, 0, + 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, + 0, 50, 0, 0, 10, 34, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 128, 65, 0, + 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 26, 0, 16, 0, 6, + 0, 0, 0, 21, 0, 0, 1, 49, 0, 0, 8, 82, 0, 16, 0, 4, 0, 0, 0, + 6, 1, 16, 128, 129, 0, 0, 0, 6, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, + 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 10, 18, 0, + 16, 0, 5, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 65, 10, 0, 16, 0, 5, 0, 0, 0, 50, 0, 0, 10, + 34, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 65, 26, 0, 16, 0, 5, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 9, 34, + 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 65, 26, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, + 0, 4, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 65, 58, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 21, + 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, + 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 0, + 3, 26, 0, 16, 0, 2, 0, 0, 0, 50, 0, 0, 12, 18, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 5, 0, 0, 0, + 50, 0, 0, 12, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, + 0, 0, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 18, 0, 0, 1, 50, 0, 0, 12, 18, + 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, + 0, 5, 0, 0, 0, 50, 0, 0, 12, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, + 49, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 6, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 39, 0, 0, 7, 50, 0, 16, 0, + 3, 0, 0, 0, 166, 10, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, + 0, 14, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 26, 0, 16, 0, 0, + 0, 0, 0, 49, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 51, 0, 0, 7, 18, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 55, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, + 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, + 56, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 50, 0, 0, 10, 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 1, 0, 0, 7, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 52, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 0, 3, 26, 0, 16, 0, 2, + 0, 0, 0, 50, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 50, 0, + 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 72, 0, 0, 13, 114, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, + 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 54, + 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, + 164, 0, 0, 7, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 5, 2, + 0, 70, 14, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, + 0, 0, 108, 1, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 134, + 0, 0, 0, 1, 0, 0, 0, 14, 0, 0, 0, 7, 0, 0, 0, 84, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/host_depth_store_1xmsaa_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/host_depth_store_1xmsaa_cs.h new file mode 100644 index 0000000..1511f11 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/host_depth_store_1xmsaa_cs.h @@ -0,0 +1,226 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_host_depth_store_rectangle;// Offset: 0 Size: 4 +// uint xe_host_depth_store_render_target;// Offset: 4 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_host_depth_store_source texture float4 2d T0 t0 1 +// xe_host_depth_store_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_texture2d (float,float,float,float) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 5 +dcl_thread_group 8, 8, 1 +ubfe r0.xyz, l(3, 3, 10, 0), l(10, 13, 20, 0), CB0[0][0].yyxy +iadd r0.z, r0.z, l(1) +imul null, r0.z, r0.x, r0.z +uge r0.z, vThreadID.x, r0.z +if_nz r0.z + ret +endif +ushr r1.y, CB0[0][0].x, l(10) +mov r1.x, CB0[0][0].x +bfi r0.zw, l(0, 0, 10, 10), l(0, 0, 3, 3), r1.xxxy, l(0, 0, 0, 0) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +imad r1.xy, r0.zwzz, r0.xyxx, r1.xyxx +and r0.z, CB0[0][0].y, l(1023) +imul null, r0.xy, r0.xyxx, l(80, 16, 0, 0) +udiv r2.xy, null, r1.xyxx, r0.xyxx +imad r0.z, r2.y, r0.z, r2.x +imad r2.xy, -r2.xyxx, r0.xyxx, r1.xyxx +imul null, r0.y, r0.y, r0.x +imad r0.x, r2.y, r0.x, r2.x +imad r0.x, r0.z, r0.y, r0.x +ushr r0.x, r0.x, l(2) +mov r1.zw, l(0,0,0,0) +ld r2.x, r1.xyzw, T0[0].xyzw +iadd r3.xyzw, r1.xyxy, l(2, 0, 1, 0) +mov r4.xy, r3.zwzz +mov r4.zw, l(0,0,0,0) +ld r2.y, r4.xyzw, T0[0].yxzw +mov r3.zw, l(0,0,0,0) +ld r2.z, r3.xyzw, T0[0].yzxw +iadd r3.xyzw, r1.xyxy, l(4, 0, 3, 0) +mov r4.xy, r3.zwzz +mov r4.zw, l(0,0,0,0) +ld r2.w, r4.xyzw, T0[0].yzwx +store_uav_typed U0[0].xyzw, r0.xxxx, r2.xyzw +iadd r0.y, r0.x, l(1) +mov r3.zw, l(0,0,0,0) +ld r2.x, r3.xyzw, T0[0].xyzw +iadd r3.xyzw, r1.xyxy, l(6, 0, 5, 0) +mov r4.xy, r3.zwzz +mov r4.zw, l(0,0,0,0) +ld r2.y, r4.xyzw, T0[0].yxzw +mov r3.zw, l(0,0,0,0) +ld r2.z, r3.xyzw, T0[0].yzxw +iadd r1.xy, r1.xyxx, l(7, 0, 0, 0) +mov r1.zw, l(0,0,0,0) +ld r2.w, r1.xyzw, T0[0].yzwx +store_uav_typed U0[0].xyzw, r0.yyyy, r2.xyzw +ret +// Approximately 49 instruction slots used +#endif + +const BYTE host_depth_store_1xmsaa_cs[] = { + 68, 88, 66, 67, 249, 1, 88, 144, 104, 118, 47, 144, 121, 3, 160, 190, 176, 193, 78, + 101, 1, 0, 0, 0, 120, 9, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 48, 2, + 0, 0, 64, 2, 0, 0, 80, 2, 0, 0, 220, 8, 0, 0, 82, 68, 69, 70, 244, + 1, 0, 0, 1, 0, 0, 0, 248, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 202, 1, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 207, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 104, 111, 115, 116, + 95, 100, 101, 112, 116, 104, 95, 115, 116, 111, 114, 101, 95, 115, 111, 117, 114, 99, 101, + 0, 120, 101, 95, 104, 111, 115, 116, 95, 100, 101, 112, 116, 104, 95, 115, 116, 111, 114, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 171, 232, 0, 0, 0, 2, 0, 0, 0, 16, 1, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 1, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 2, 0, 0, 0, 132, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 168, 1, 0, 0, 4, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 132, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, 104, 111, 115, + 116, 95, 100, 101, 112, 116, 104, 95, 115, 116, 111, 114, 101, 95, 114, 101, 99, 116, 97, + 110, 103, 108, 101, 0, 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 126, 1, 0, 0, 120, 101, 95, 104, 111, 115, 116, 95, 100, 101, + 112, 116, 104, 95, 115, 116, 111, 114, 101, 95, 114, 101, 110, 100, 101, 114, 95, 116, 97, + 114, 103, 101, 116, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, + 114, 32, 49, 48, 46, 49, 0, 171, 171, 73, 83, 71, 78, 8, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 83, 72, 69, 88, 132, 6, 0, 0, 81, 0, 5, 0, 161, 1, 0, 0, + 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 88, 24, 0, 7, 70, 126, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 0, 0, 0, + 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 95, 0, 0, 2, 50, 0, 2, + 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, 0, 0, 4, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 0, 138, 0, 0, 17, 114, 0, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, + 0, 86, 132, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 80, 0, 0, 6, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 2, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 62, + 0, 0, 1, 21, 0, 0, 1, 85, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, + 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 10, 0, 0, 0, 54, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 20, 194, + 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, + 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, + 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, + 0, 35, 0, 0, 9, 50, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 1, + 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 3, 0, 0, 38, 0, 0, + 11, 0, 208, 0, 0, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 80, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 78, 0, 0, 8, 50, 0, 16, 0, 2, 0, 0, 0, 0, 208, 0, 0, + 70, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 10, 50, + 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 128, 65, 0, 0, 0, 2, 0, 0, 0, + 70, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 54, 0, 0, 8, + 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 18, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 4, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, + 16, 0, 3, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 8, 34, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 22, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 66, 0, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 150, 124, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 4, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, + 3, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, + 0, 8, 130, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 150, + 115, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 8, 194, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 4, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, + 0, 3, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, + 0, 0, 8, 34, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 22, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 66, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 150, 124, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, + 130, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 150, 115, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 49, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, + 0, 5, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/host_depth_store_2xmsaa_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/host_depth_store_2xmsaa_cs.h new file mode 100644 index 0000000..59841cb --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/host_depth_store_2xmsaa_cs.h @@ -0,0 +1,249 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_host_depth_store_rectangle;// Offset: 0 Size: 4 +// uint xe_host_depth_store_render_target;// Offset: 4 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_host_depth_store_source texture float4 2dMS T0 t0 1 +// xe_host_depth_store_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_texture2dms(0) (float,float,float,float) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 5 +dcl_thread_group 8, 8, 1 +ubfe r0.xyz, l(3, 3, 10, 0), l(10, 13, 20, 0), CB0[0][0].yyxy +iadd r0.z, r0.z, l(1) +imul null, r0.z, r0.x, r0.z +uge r0.z, vThreadID.x, r0.z +if_nz r0.z + ret +endif +ushr r1.y, CB0[0][0].x, l(10) +mov r1.x, CB0[0][0].x +bfi r0.zw, l(0, 0, 10, 10), l(0, 0, 3, 3), r1.xxxy, l(0, 0, 0, 0) +ishl r1.x, vThreadID.x, l(3) +ushr r1.y, vThreadID.y, l(1) +imad r1.xy, r0.zwzz, r0.xyxx, r1.xyxx +and r2.y, vThreadID.y, l(1) +and r0.z, CB0[0][0].y, l(1023) +ishl r1.z, r1.y, l(1) +mov r2.x, l(0) +iadd r2.xz, r1.xxzx, r2.xxyx +imul null, r0.xy, r0.xyxx, l(80, 16, 0, 0) +udiv r3.xy, null, r2.xzxx, r0.xyxx +imad r0.z, r3.y, r0.z, r3.x +imad r2.xz, -r3.xxyx, r0.xxyx, r2.xxzx +imul null, r0.y, r0.y, r0.x +imad r0.x, r2.z, r0.x, r2.x +imad r0.x, r0.z, r0.y, r0.x +ushr r0.x, r0.x, l(2) +ubfe r0.y, l(1), l(16), CB0[0][0].y +movc r0.zw, r2.yyyy, l(0,0,0,3), l(0,0,1,0) +movc r0.y, r0.y, r0.z, r0.w +mov r1.w, l(0) +ldms r2.x, r1.xyww, T0[0].xyzw, r0.y +iadd r3.xyzw, r1.xyxy, l(2, 0, 1, 0) +mov r4.xy, r3.zwzz +mov r4.zw, l(0,0,0,0) +ldms r2.y, r4.xyzw, T0[0].yxzw, r0.y +mov r3.zw, l(0,0,0,0) +ldms r2.z, r3.xyzw, T0[0].yzxw, r0.y +iadd r3.xyzw, r1.xyxy, l(4, 0, 3, 0) +mov r4.xy, r3.zwzz +mov r4.zw, l(0,0,0,0) +ldms r2.w, r4.xyzw, T0[0].yzwx, r0.y +store_uav_typed U0[0].xyzw, r0.xxxx, r2.xyzw +iadd r0.z, r0.x, l(1) +mov r3.zw, l(0,0,0,0) +ldms r2.x, r3.xyzw, T0[0].xyzw, r0.y +iadd r3.xyzw, r1.xyxy, l(6, 0, 5, 0) +mov r4.xy, r3.zwzz +mov r4.zw, l(0,0,0,0) +ldms r2.y, r4.xyzw, T0[0].yxzw, r0.y +mov r3.zw, l(0,0,0,0) +ldms r2.z, r3.xyzw, T0[0].yzxw, r0.y +iadd r1.xy, r1.xyxx, l(7, 0, 0, 0) +mov r1.zw, l(0,0,0,0) +ldms r2.w, r1.xyzw, T0[0].yzwx, r0.y +store_uav_typed U0[0].xyzw, r0.zzzz, r2.xyzw +ret +// Approximately 56 instruction slots used +#endif + +const BYTE host_depth_store_2xmsaa_cs[] = { + 68, 88, 66, 67, 246, 86, 236, 189, 39, 9, 109, 187, 49, 108, 144, 221, 210, 109, 200, + 52, 1, 0, 0, 0, 164, 10, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 48, 2, + 0, 0, 64, 2, 0, 0, 80, 2, 0, 0, 8, 10, 0, 0, 82, 68, 69, 70, 244, + 1, 0, 0, 1, 0, 0, 0, 248, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 202, 1, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 207, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 104, 111, 115, 116, + 95, 100, 101, 112, 116, 104, 95, 115, 116, 111, 114, 101, 95, 115, 111, 117, 114, 99, 101, + 0, 120, 101, 95, 104, 111, 115, 116, 95, 100, 101, 112, 116, 104, 95, 115, 116, 111, 114, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 171, 232, 0, 0, 0, 2, 0, 0, 0, 16, 1, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 1, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 2, 0, 0, 0, 132, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 168, 1, 0, 0, 4, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 132, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, 104, 111, 115, + 116, 95, 100, 101, 112, 116, 104, 95, 115, 116, 111, 114, 101, 95, 114, 101, 99, 116, 97, + 110, 103, 108, 101, 0, 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 126, 1, 0, 0, 120, 101, 95, 104, 111, 115, 116, 95, 100, 101, + 112, 116, 104, 95, 115, 116, 111, 114, 101, 95, 114, 101, 110, 100, 101, 114, 95, 116, 97, + 114, 103, 101, 116, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, + 114, 32, 49, 48, 46, 49, 0, 171, 171, 73, 83, 71, 78, 8, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 83, 72, 69, 88, 176, 7, 0, 0, 81, 0, 5, 0, 236, 1, 0, 0, + 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 88, 32, 0, 7, 70, 126, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 0, 0, 0, + 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 95, 0, 0, 2, 50, 0, 2, + 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, 0, 0, 4, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 0, 138, 0, 0, 17, 114, 0, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, + 0, 86, 132, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 80, 0, 0, 6, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 2, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 62, + 0, 0, 1, 21, 0, 0, 1, 85, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, + 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 10, 0, 0, 0, 54, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 20, 194, + 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, + 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, + 3, 0, 0, 0, 85, 0, 0, 6, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 35, 0, 0, 9, 50, 0, 16, 0, 1, 0, + 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, + 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 6, 34, 0, 16, 0, 2, 0, 0, 0, + 26, 0, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, 66, 0, 16, + 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 255, 3, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 82, 0, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 1, 0, + 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, 11, 0, 208, 0, 0, 50, + 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 80, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 0, 0, + 8, 50, 0, 16, 0, 3, 0, 0, 0, 0, 208, 0, 0, 134, 0, 16, 0, 2, 0, + 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 3, 0, 0, 0, 35, 0, 0, 10, 82, 0, 16, 0, 2, 0, 0, + 0, 6, 1, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 6, 1, 16, 0, 0, 0, + 0, 0, 6, 2, 16, 0, 2, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 138, 0, 0, 11, 34, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 26, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 15, + 194, 0, 16, 0, 0, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 46, 0, + 0, 10, 18, 0, 16, 0, 2, 0, 0, 0, 70, 15, 16, 0, 1, 0, 0, 0, 70, + 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 30, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 4, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 3, + 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, + 10, 34, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 22, 126, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 194, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 10, 66, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 150, 124, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 10, 130, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 150, 115, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 164, 0, 0, 8, 242, 224, + 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, + 8, 194, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 10, 18, 0, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, + 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 54, 0, 0, 8, + 194, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 10, 34, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 22, 126, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 46, 0, 0, 10, 66, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 150, 124, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, + 70, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 46, 0, 0, 10, 130, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 1, 0, 0, 0, 150, 115, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 62, + 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 56, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, + 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/host_depth_store_4xmsaa_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/host_depth_store_4xmsaa_cs.h new file mode 100644 index 0000000..c6c2971 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/host_depth_store_4xmsaa_cs.h @@ -0,0 +1,219 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_host_depth_store_rectangle;// Offset: 0 Size: 4 +// uint xe_host_depth_store_render_target;// Offset: 4 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_host_depth_store_source texture float4 2dMS T0 t0 1 +// xe_host_depth_store_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_texture2dms(0) (float,float,float,float) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 5 +dcl_thread_group 8, 8, 1 +ushr r0.x, vThreadID.x, l(1) +ubfe r0.yzw, l(0, 3, 3, 10), l(0, 10, 13, 20), CB0[0][0].yyyx +iadd r0.w, r0.w, l(1) +imul null, r0.w, r0.y, r0.w +uge r0.x, r0.x, r0.w +if_nz r0.x + ret +endif +ushr r1.y, CB0[0][0].x, l(10) +mov r1.x, CB0[0][0].x +bfi r0.xw, l(10, 0, 0, 10), l(3, 0, 0, 3), r1.xxxy, l(0, 0, 0, 0) +ishl r1.x, vThreadID.x, l(2) +ushr r1.y, vThreadID.y, l(1) +imad r1.xy, r0.xwxx, r0.yzyy, r1.xyxx +bfi r0.xw, l(31, 0, 0, 31), l(1, 0, 0, 1), r1.xxxy, vThreadID.xxxy +and r2.x, CB0[0][0].y, l(1023) +imul null, r0.yz, r0.yyzy, l(0, 80, 16, 0) +udiv r2.yz, null, r0.xxwx, r0.yyzy +imad r2.x, r2.z, r2.x, r2.y +imad r0.xw, -r2.yyyz, r0.yyyz, r0.xxxw +imul null, r0.z, r0.z, r0.y +imad r0.x, r0.w, r0.y, r0.x +imad r0.x, r2.x, r0.z, r0.x +ushr r0.x, r0.x, l(2) +bfi r0.y, l(1), l(1), vThreadID.y, l(0) +iadd r0.zw, r0.yyyx, l(0, 0, 1, 1) +mov r1.zw, l(0,0,0,0) +ldms r2.x, r1.xyww, T0[0].xyzw, r0.y +ldms r2.y, r1.xyzw, T0[0].yxzw, r0.z +iadd r3.xyzw, r1.xyxy, l(2, 0, 1, 0) +mov r4.xy, r3.zwzz +mov r4.zw, l(0,0,0,0) +ldms r2.z, r4.xyww, T0[0].yzxw, r0.y +ldms r2.w, r4.xyzw, T0[0].yzwx, r0.z +store_uav_typed U0[0].xyzw, r0.xxxx, r2.xyzw +mov r3.zw, l(0,0,0,0) +ldms r2.x, r3.xyww, T0[0].xyzw, r0.y +ldms r2.y, r3.xyzw, T0[0].yxzw, r0.z +iadd r1.xy, r1.xyxx, l(3, 0, 0, 0) +mov r1.zw, l(0,0,0,0) +ldms r2.z, r1.xyww, T0[0].yzxw, r0.y +ldms r2.w, r1.xyzw, T0[0].yzwx, r0.z +store_uav_typed U0[0].xyzw, r0.wwww, r2.xyzw +ret +// Approximately 44 instruction slots used +#endif + +const BYTE host_depth_store_4xmsaa_cs[] = { + 68, 88, 66, 67, 138, 4, 177, 77, 64, 213, 191, 16, 252, 179, 74, 32, 169, 202, 77, + 56, 1, 0, 0, 0, 88, 9, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 48, 2, + 0, 0, 64, 2, 0, 0, 80, 2, 0, 0, 188, 8, 0, 0, 82, 68, 69, 70, 244, + 1, 0, 0, 1, 0, 0, 0, 248, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 202, 1, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 207, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 104, 111, 115, 116, + 95, 100, 101, 112, 116, 104, 95, 115, 116, 111, 114, 101, 95, 115, 111, 117, 114, 99, 101, + 0, 120, 101, 95, 104, 111, 115, 116, 95, 100, 101, 112, 116, 104, 95, 115, 116, 111, 114, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 171, 232, 0, 0, 0, 2, 0, 0, 0, 16, 1, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 1, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 2, 0, 0, 0, 132, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 168, 1, 0, 0, 4, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 132, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, 104, 111, 115, + 116, 95, 100, 101, 112, 116, 104, 95, 115, 116, 111, 114, 101, 95, 114, 101, 99, 116, 97, + 110, 103, 108, 101, 0, 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 126, 1, 0, 0, 120, 101, 95, 104, 111, 115, 116, 95, 100, 101, + 112, 116, 104, 95, 115, 116, 111, 114, 101, 95, 114, 101, 110, 100, 101, 114, 95, 116, 97, + 114, 103, 101, 116, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, + 114, 32, 49, 48, 46, 49, 0, 171, 171, 73, 83, 71, 78, 8, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 83, 72, 69, 88, 100, 6, 0, 0, 81, 0, 5, 0, 153, 1, 0, 0, + 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 88, 32, 0, 7, 70, 126, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 0, 0, 0, + 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 95, 0, 0, 2, 50, 0, 2, + 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, 0, 0, 4, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 0, 85, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 138, 0, 0, 17, 226, 0, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, 0, + 0, 0, 20, 0, 0, 0, 86, 129, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, + 0, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 80, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 10, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 85, 0, 0, + 9, 34, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 54, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 140, 0, 0, 20, 146, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 6, + 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 6, 34, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 35, + 0, 0, 9, 50, 0, 16, 0, 1, 0, 0, 0, 198, 0, 16, 0, 0, 0, 0, 0, + 150, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 16, 146, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 31, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, + 6, 4, 2, 0, 1, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 3, + 0, 0, 38, 0, 0, 11, 0, 208, 0, 0, 98, 0, 16, 0, 0, 0, 0, 0, 86, + 6, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 78, 0, 0, 8, 98, 0, 16, 0, 2, 0, 0, + 0, 0, 208, 0, 0, 6, 3, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, 0, 0, + 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, + 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, + 35, 0, 0, 10, 146, 0, 16, 0, 0, 0, 0, 0, 86, 9, 16, 128, 65, 0, 0, + 0, 2, 0, 0, 0, 86, 9, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 140, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 86, 1, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, + 0, 0, 10, 18, 0, 16, 0, 2, 0, 0, 0, 70, 15, 16, 0, 1, 0, 0, 0, + 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 46, 0, 0, 10, 34, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 1, 0, + 0, 0, 22, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 4, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, + 16, 0, 3, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 46, 0, 0, 10, 66, 0, 16, 0, 2, 0, 0, 0, 70, 15, 16, 0, 4, 0, 0, + 0, 150, 124, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 46, 0, 0, 10, 130, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, + 0, 0, 0, 150, 115, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 10, 18, 0, 16, 0, + 2, 0, 0, 0, 70, 15, 16, 0, 3, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 46, 0, 0, 10, 34, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 22, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 10, + 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 10, 66, 0, 16, 0, + 2, 0, 0, 0, 70, 15, 16, 0, 1, 0, 0, 0, 150, 124, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 46, 0, 0, 10, 130, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 150, 115, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 164, 0, 0, 8, + 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, + 0, 0, 44, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 13, 0, 0, 0, 7, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/passthrough_position_xy_vs.h b/src/graphics/shaders/bytecode/d3d12_5_1/passthrough_position_xy_vs.h new file mode 100644 index 0000000..fdcfdb7 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/passthrough_position_xy_vs.h @@ -0,0 +1,58 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// POSITION 0 xy 0 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xyzw +// +vs_5_1 +dcl_globalFlags refactoringAllowed +dcl_input v0.xy +dcl_output_siv o0.xyzw, position +mov o0.xy, v0.xyxx +mov o0.zw, l(0,0,0,1.000000) +ret +// Approximately 3 instruction slots used +#endif + +const BYTE passthrough_position_xy_vs[] = { + 68, 88, 66, 67, 92, 220, 0, 199, 190, 67, 183, 153, 171, 192, 4, 39, 67, 55, 215, + 255, 1, 0, 0, 0, 12, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 160, 0, + 0, 0, 212, 0, 0, 0, 8, 1, 0, 0, 112, 1, 0, 0, 82, 68, 69, 70, 100, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 254, 255, 0, 5, 0, 0, 60, 0, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, + 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, + 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, + 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, + 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 15, 0, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 83, 72, + 69, 88, 96, 0, 0, 0, 81, 0, 1, 0, 24, 0, 0, 0, 106, 8, 0, 1, 95, + 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, + 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 32, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_clear_32bpp_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_clear_32bpp_cs.h new file mode 100644 index 0000000..0bf2aef --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_clear_32bpp_cs.h @@ -0,0 +1,185 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint2 xe_resolve_clear_value; // Offset: 0 Size: 8 +// uint xe_resolve_edram_info; // Offset: 8 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 12 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 3 +dcl_thread_group 8, 8, 1 +and r0.xy, CB0[0][0].zzzz, l(1023, 4096, 0, 0) +ushr r1.y, CB0[0][0].w, l(4) +ubfe r0.zw, l(0, 0, 2, 11), l(0, 0, 10, 5), CB0[0][0].zzzw +uge r1.zw, r0.zzzz, l(0, 0, 2, 1) +and r0.z, r1.z, l(1) +ishl r0.z, r0.w, r0.z +uge r0.z, vThreadID.x, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(11), l(13), CB0[0][0].z +ishl r2.x, vThreadID.x, l(3) +movc r1.zw, r1.zzzw, l(0,0,4,4), l(0,0,3,3) +mov r1.x, CB0[0][0].w +bfi r1.xy, l(4, 1, 0, 0), r1.zwzz, r1.xyxx, l(0, 0, 0, 0) +mov r2.y, vThreadID.y +iadd r1.xy, r1.xyxx, r2.xyxx +udiv r1.zw, null, r1.xxxy, l(0, 0, 80, 16) +imad r0.x, r1.w, r0.x, r1.z +iadd r0.x, r0.x, r0.z +imad r0.zw, -r1.zzzw, l(0, 0, 80, 16), r1.xxxy +if_nz r0.y + uge r0.y, r0.z, l(40) + movc r0.y, r0.y, l(-40), l(40) + iadd r0.z, r0.y, r0.z +endif +imad r0.y, r0.w, l(80), r0.z +imad r0.x, r0.x, l(1280), r0.y +udiv null, r0.x, r0.x, l(0x00280000) +ushr r0.x, r0.x, l(2) +store_uav_typed U0[0].xyzw, r0.xxxx, CB0[0][0].xxxx +iadd r0.y, r0.x, l(1) +store_uav_typed U0[0].xyzw, r0.yyyy, CB0[0][0].xxxx +ret +// Approximately 34 instruction slots used +#endif + +const BYTE resolve_clear_32bpp_cs[] = { + 68, 88, 66, 67, 151, 0, 134, 61, 129, 80, 182, 152, 119, 11, 63, 144, 63, 10, 180, + 65, 1, 0, 0, 0, 152, 7, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 64, 2, + 0, 0, 80, 2, 0, 0, 96, 2, 0, 0, 252, 6, 0, 0, 82, 68, 69, 70, 4, + 2, 0, 0, 1, 0, 0, 0, 172, 0, 0, 0, 2, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 219, 1, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 101, 100, 114, 97, 109, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, + 95, 120, 101, 0, 157, 0, 0, 0, 3, 0, 0, 0, 196, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 1, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 2, 0, 0, 0, 92, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 128, 1, 0, 0, 8, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 156, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 1, 0, 0, 12, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 156, 1, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, 114, + 101, 115, 111, 108, 118, 101, 95, 99, 108, 101, 97, 114, 95, 118, 97, 108, 117, 101, 0, + 117, 105, 110, 116, 50, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 83, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 101, + 100, 114, 97, 109, 95, 105, 110, 102, 111, 0, 100, 119, 111, 114, 100, 0, 0, 0, 19, + 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 1, 0, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 99, 111, 111, 114, 100, 105, 110, 97, 116, 101, 95, 105, 110, + 102, 111, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, + 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, + 49, 48, 46, 49, 0, 171, 73, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, + 83, 72, 69, 88, 148, 4, 0, 0, 81, 0, 5, 0, 37, 1, 0, 0, 106, 8, 0, + 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, + 95, 0, 0, 2, 50, 0, 2, 0, 104, 0, 0, 2, 3, 0, 0, 0, 155, 0, 0, + 4, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, 50, 0, + 16, 0, 0, 0, 0, 0, 166, 138, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 138, 0, 0, 17, 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 166, 142, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 10, 194, 0, + 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, + 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 80, 0, 0, 6, 66, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 2, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, + 1, 138, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, + 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 2, 0, 0, 0, + 10, 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 55, 0, 0, 15, 194, 0, 16, + 0, 1, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 54, 0, 0, 7, + 18, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, + 10, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 2, 0, 30, 0, 0, 7, 50, 0, + 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 2, + 0, 0, 0, 78, 0, 0, 11, 194, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 80, 0, 0, 0, 16, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, + 13, 194, 0, 16, 0, 0, 0, 0, 0, 166, 14, 16, 128, 65, 0, 0, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 16, + 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, + 0, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 40, 0, 0, 0, 55, 0, 0, 9, 34, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 216, + 255, 255, 255, 1, 64, 0, 0, 40, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 21, 0, 0, 1, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 80, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 5, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 78, 0, 0, 8, 0, 208, 0, 0, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 40, 0, 85, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 164, 0, 0, 10, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 164, 0, 0, 10, + 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, + 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 34, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, + 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_clear_32bpp_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_clear_32bpp_scaled_cs.h new file mode 100644 index 0000000..7d11600 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_clear_32bpp_scaled_cs.h @@ -0,0 +1,201 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint2 xe_resolve_clear_value; // Offset: 0 Size: 8 +// uint xe_resolve_edram_info; // Offset: 8 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 12 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 4 +dcl_thread_group 8, 8, 1 +and r0.xy, CB0[0][0].zzzz, l(1023, 4096, 0, 0) +ushr r1.y, CB0[0][0].w, l(4) +ubfe r2.xyzw, l(2, 3, 3, 11), l(10, 16, 19, 5), CB0[0][0].zwww +imul null, r0.z, r2.y, r2.w +uge r1.zw, r2.xxxx, l(0, 0, 2, 1) +and r1.zw, r1.zzzw, l(0, 0, 1, 1) +ishl r0.z, r0.z, r1.z +uge r0.z, vThreadID.x, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(11), l(13), CB0[0][0].z +mov r1.x, CB0[0][0].w +bfi r1.xy, l(4, 1, 0, 0), l(3, 3, 0, 0), r1.xyxx, l(0, 0, 0, 0) +imul null, r1.xy, r2.yzyy, r1.xyxx +ishl r3.x, vThreadID.x, l(3) +ishl r1.xy, r1.xyxx, r1.zwzz +mov r3.y, vThreadID.y +iadd r1.xy, r1.xyxx, r3.xyxx +imul null, r1.zw, r2.yyyz, l(0, 0, 80, 16) +udiv r2.xy, null, r1.xyxx, r1.zwzz +imad r0.x, r2.y, r0.x, r2.x +iadd r0.x, r0.x, r0.z +imad r0.zw, -r2.xxxy, r1.zzzw, r1.xxxy +if_nz r0.y + ushr r0.y, r1.z, l(1) + uge r1.x, r0.z, r0.y + ineg r1.y, r0.y + movc r0.y, r1.x, r1.y, r0.y + iadd r0.z, r0.y, r0.z +endif +imul null, r0.y, r1.w, r1.z +imad r0.z, r0.w, r1.z, r0.z +imad r0.x, r0.x, r0.y, r0.z +ishl r0.y, r0.y, l(11) +udiv null, r0.x, r0.x, r0.y +ushr r0.x, r0.x, l(2) +store_uav_typed U0[0].xyzw, r0.xxxx, CB0[0][0].xxxx +iadd r0.y, r0.x, l(1) +store_uav_typed U0[0].xyzw, r0.yyyy, CB0[0][0].xxxx +ret +// Approximately 41 instruction slots used +#endif + +const BYTE resolve_clear_32bpp_scaled_cs[] = { + 68, 88, 66, 67, 152, 212, 249, 105, 95, 201, 221, 225, 213, 139, 20, 140, 156, 235, 246, + 183, 1, 0, 0, 0, 80, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 64, 2, + 0, 0, 80, 2, 0, 0, 96, 2, 0, 0, 180, 7, 0, 0, 82, 68, 69, 70, 4, + 2, 0, 0, 1, 0, 0, 0, 172, 0, 0, 0, 2, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 219, 1, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 101, 100, 114, 97, 109, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, + 95, 120, 101, 0, 157, 0, 0, 0, 3, 0, 0, 0, 196, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 1, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 2, 0, 0, 0, 92, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 128, 1, 0, 0, 8, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 156, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 1, 0, 0, 12, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 156, 1, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, 114, + 101, 115, 111, 108, 118, 101, 95, 99, 108, 101, 97, 114, 95, 118, 97, 108, 117, 101, 0, + 117, 105, 110, 116, 50, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 83, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 101, + 100, 114, 97, 109, 95, 105, 110, 102, 111, 0, 100, 119, 111, 114, 100, 0, 0, 0, 19, + 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 1, 0, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 99, 111, 111, 114, 100, 105, 110, 97, 116, 101, 95, 105, 110, + 102, 111, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, + 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, + 49, 48, 46, 49, 0, 171, 73, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, + 83, 72, 69, 88, 76, 5, 0, 0, 81, 0, 5, 0, 83, 1, 0, 0, 106, 8, 0, + 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, + 95, 0, 0, 2, 50, 0, 2, 0, 104, 0, 0, 2, 4, 0, 0, 0, 155, 0, 0, + 4, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, 50, 0, + 16, 0, 0, 0, 0, 0, 166, 138, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 138, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 2, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 10, 0, 0, 0, 16, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 230, 143, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, + 0, 0, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 80, 0, 0, 10, 194, 0, 16, 0, 1, 0, 0, 0, + 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 1, 0, + 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 80, 0, 0, 6, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 2, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 62, + 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 11, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 42, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 0, + 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, + 1, 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 6, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 2, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 70, + 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 54, 0, 0, 4, + 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 2, 0, 30, 0, 0, 7, 50, 0, 16, + 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 3, 0, + 0, 0, 38, 0, 0, 11, 0, 208, 0, 0, 194, 0, 16, 0, 1, 0, 0, 0, 86, + 9, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 80, 0, 0, 0, 16, 0, 0, 0, 78, 0, 0, 8, 50, 0, 16, 0, 2, 0, 0, + 0, 0, 208, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 1, 0, + 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 10, 194, 0, 16, 0, 0, 0, + 0, 0, 6, 4, 16, 128, 65, 0, 0, 0, 2, 0, 0, 0, 166, 14, 16, 0, 1, + 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, + 0, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 80, 0, 0, 7, 18, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 40, 0, 0, 5, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 38, 0, 0, 8, + 0, 208, 0, 0, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 78, 0, 0, 8, 0, + 208, 0, 0, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 164, 0, + 0, 10, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, + 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 164, 0, 0, 10, 242, 224, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, + 148, 0, 0, 0, 41, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 17, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_clear_64bpp_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_clear_64bpp_cs.h new file mode 100644 index 0000000..10580c7 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_clear_64bpp_cs.h @@ -0,0 +1,185 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint2 xe_resolve_clear_value; // Offset: 0 Size: 8 +// uint xe_resolve_edram_info; // Offset: 8 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 12 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 3 +dcl_thread_group 8, 8, 1 +and r0.x, CB0[0][0].z, l(1023) +ushr r1.y, CB0[0][0].w, l(4) +ubfe r0.yz, l(0, 2, 11, 0), l(0, 10, 5, 0), CB0[0][0].zzwz +uge r0.yw, r0.yyyy, l(0, 2, 0, 1) +and r1.z, r0.y, l(1) +ishl r0.z, r0.z, r1.z +uge r0.z, vThreadID.x, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(11), l(13), CB0[0][0].z +ishl r2.x, vThreadID.x, l(3) +movc r0.yw, r0.yyyw, l(0,4,0,4), l(0,3,0,3) +mov r1.x, CB0[0][0].w +bfi r0.yw, l(0, 4, 0, 1), r0.yyyw, r1.xxxy, l(0, 0, 0, 0) +mov r2.y, vThreadID.y +iadd r0.yw, r0.yyyw, r2.xxxy +udiv r1.xy, null, r0.ywyy, l(40, 16, 0, 0) +imad r0.x, r1.y, r0.x, r1.x +iadd r0.x, r0.x, r0.z +imad r0.yz, -r1.xxyx, l(0, 40, 16, 0), r0.yywy +imad r0.y, r0.z, l(40), r0.y +ishl r0.y, r0.y, l(1) +imad r0.x, r0.x, l(1280), r0.y +udiv null, r0.x, r0.x, l(0x00280000) +ushr r0.x, r0.x, l(2) +store_uav_typed U0[0].xyzw, r0.xxxx, CB0[0][0].xyxy +iadd r0.yz, r0.xxxx, l(0, 1, 3, 0) +store_uav_typed U0[0].xyzw, r0.yyyy, CB0[0][0].xyxy +iadd r0.y, r0.x, l(2) +store_uav_typed U0[0].xyzw, r0.yyyy, CB0[0][0].xyxy +store_uav_typed U0[0].xyzw, r0.zzzz, CB0[0][0].xyxy +ret +// Approximately 33 instruction slots used +#endif + +const BYTE resolve_clear_64bpp_cs[] = { + 68, 88, 66, 67, 16, 64, 178, 139, 19, 215, 227, 50, 35, 42, 169, 197, 244, 123, 191, + 106, 1, 0, 0, 0, 180, 7, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 64, 2, + 0, 0, 80, 2, 0, 0, 96, 2, 0, 0, 24, 7, 0, 0, 82, 68, 69, 70, 4, + 2, 0, 0, 1, 0, 0, 0, 172, 0, 0, 0, 2, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 219, 1, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 101, 100, 114, 97, 109, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, + 95, 120, 101, 0, 157, 0, 0, 0, 3, 0, 0, 0, 196, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 1, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 2, 0, 0, 0, 92, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 128, 1, 0, 0, 8, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 156, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 1, 0, 0, 12, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 156, 1, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, 114, + 101, 115, 111, 108, 118, 101, 95, 99, 108, 101, 97, 114, 95, 118, 97, 108, 117, 101, 0, + 117, 105, 110, 116, 50, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 83, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 101, + 100, 114, 97, 109, 95, 105, 110, 102, 111, 0, 100, 119, 111, 114, 100, 0, 0, 0, 19, + 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 1, 0, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 99, 111, 111, 114, 100, 105, 110, 97, 116, 101, 95, 105, 110, + 102, 111, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, + 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, + 49, 48, 46, 49, 0, 171, 73, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, + 83, 72, 69, 88, 176, 4, 0, 0, 81, 0, 5, 0, 44, 1, 0, 0, 106, 8, 0, + 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, + 95, 0, 0, 2, 50, 0, 2, 0, 104, 0, 0, 2, 3, 0, 0, 0, 155, 0, 0, + 4, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, 18, 0, + 16, 0, 0, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 255, 3, 0, 0, 85, 0, 0, 9, 34, 0, 16, 0, + 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 138, 0, 0, 17, 98, 0, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 11, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 166, 139, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 80, 0, 0, 10, 162, 0, 16, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 80, 0, 0, 6, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 2, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, + 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 42, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, + 0, 16, 0, 2, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 55, 0, 0, 15, 162, 0, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 54, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 162, 0, 16, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 86, 13, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 2, + 0, 30, 0, 0, 7, 162, 0, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 0, 0, + 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, 0, 1, + 0, 0, 0, 0, 208, 0, 0, 214, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 40, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 35, 0, 0, 13, 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, + 128, 65, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 40, 0, + 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 86, 7, 16, 0, 0, 0, 0, 0, 35, + 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 40, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 5, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 78, 0, 0, 8, 0, 208, 0, 0, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 40, 0, 85, 0, + 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 164, 0, 0, 10, 242, 224, 33, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 132, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 98, 0, 16, 0, 0, 0, + 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 10, 242, 224, 33, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 132, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 164, 0, 0, 10, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 70, 132, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 164, 0, 0, 10, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 132, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, + 33, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 11, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_clear_64bpp_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_clear_64bpp_scaled_cs.h new file mode 100644 index 0000000..aab5b1a --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_clear_64bpp_scaled_cs.h @@ -0,0 +1,200 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint2 xe_resolve_clear_value; // Offset: 0 Size: 8 +// uint xe_resolve_edram_info; // Offset: 8 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 12 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 4 +dcl_thread_group 8, 8, 1 +and r0.x, CB0[0][0].z, l(1023) +ushr r1.y, CB0[0][0].w, l(4) +ubfe r2.xyzw, l(2, 3, 3, 11), l(10, 16, 19, 5), CB0[0][0].zwww +imul null, r0.y, r2.y, r2.w +uge r0.zw, r2.xxxx, l(0, 0, 2, 1) +and r0.zw, r0.zzzw, l(0, 0, 1, 1) +ishl r0.y, r0.y, r0.z +uge r0.y, vThreadID.x, r0.y +if_nz r0.y + ret +endif +ubfe r0.y, l(11), l(13), CB0[0][0].z +mov r1.x, CB0[0][0].w +bfi r1.xy, l(4, 1, 0, 0), l(3, 3, 0, 0), r1.xyxx, l(0, 0, 0, 0) +imul null, r1.xy, r2.yzyy, r1.xyxx +ishl r3.x, vThreadID.x, l(3) +ishl r0.zw, r1.xxxy, r0.zzzw +mov r3.y, vThreadID.y +iadd r0.zw, r0.zzzw, r3.xxxy +imul null, r1.yz, r2.yyzy, l(0, 80, 16, 0) +ushr r1.x, r1.y, l(1) +udiv r2.xy, null, r0.zwzz, r1.xzxx +imad r0.x, r2.y, r0.x, r2.x +iadd r0.x, r0.x, r0.y +imad r0.yz, -r2.xxyx, r1.xxzx, r0.zzwz +imul null, r0.w, r1.z, r1.y +imad r0.y, r0.z, r1.x, r0.y +ishl r0.y, r0.y, l(1) +imad r0.x, r0.x, r0.w, r0.y +ishl r0.y, r0.w, l(11) +udiv null, r0.x, r0.x, r0.y +ushr r0.x, r0.x, l(2) +store_uav_typed U0[0].xyzw, r0.xxxx, CB0[0][0].xyxy +iadd r0.yz, r0.xxxx, l(0, 1, 3, 0) +store_uav_typed U0[0].xyzw, r0.yyyy, CB0[0][0].xyxy +iadd r0.y, r0.x, l(2) +store_uav_typed U0[0].xyzw, r0.yyyy, CB0[0][0].xyxy +store_uav_typed U0[0].xyzw, r0.zzzz, CB0[0][0].xyxy +ret +// Approximately 39 instruction slots used +#endif + +const BYTE resolve_clear_64bpp_scaled_cs[] = { + 68, 88, 66, 67, 86, 138, 138, 194, 54, 150, 164, 145, 227, 0, 160, 39, 109, 131, 74, + 23, 1, 0, 0, 0, 88, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 64, 2, + 0, 0, 80, 2, 0, 0, 96, 2, 0, 0, 188, 7, 0, 0, 82, 68, 69, 70, 4, + 2, 0, 0, 1, 0, 0, 0, 172, 0, 0, 0, 2, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 219, 1, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 101, 100, 114, 97, 109, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, + 95, 120, 101, 0, 157, 0, 0, 0, 3, 0, 0, 0, 196, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 1, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 2, 0, 0, 0, 92, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 128, 1, 0, 0, 8, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 156, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 1, 0, 0, 12, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 156, 1, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, 114, + 101, 115, 111, 108, 118, 101, 95, 99, 108, 101, 97, 114, 95, 118, 97, 108, 117, 101, 0, + 117, 105, 110, 116, 50, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 83, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 101, + 100, 114, 97, 109, 95, 105, 110, 102, 111, 0, 100, 119, 111, 114, 100, 0, 0, 0, 19, + 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 1, 0, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 99, 111, 111, 114, 100, 105, 110, 97, 116, 101, 95, 105, 110, + 102, 111, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, + 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, + 49, 48, 46, 49, 0, 171, 73, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, + 83, 72, 69, 88, 84, 5, 0, 0, 81, 0, 5, 0, 85, 1, 0, 0, 106, 8, 0, + 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, + 95, 0, 0, 2, 50, 0, 2, 0, 104, 0, 0, 2, 4, 0, 0, 0, 155, 0, 0, + 4, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, 18, 0, + 16, 0, 0, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 255, 3, 0, 0, 85, 0, 0, 9, 34, 0, 16, 0, + 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 138, 0, 0, 17, 242, 0, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 16, 0, 0, 0, 19, 0, 0, 0, + 5, 0, 0, 0, 230, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 38, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 80, 0, 0, 10, 194, + 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 10, 194, 0, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 41, + 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 80, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 2, 0, 26, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, + 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, 11, 34, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 64, 0, 0, + 13, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, + 208, 0, 0, 50, 0, 16, 0, 1, 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, + 70, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 3, 0, 0, + 0, 10, 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 194, 0, + 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 0, + 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 2, 0, + 30, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 3, 0, 0, 0, 38, 0, 0, 11, 0, 208, 0, 0, 98, 0, + 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 80, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, + 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 78, 0, 0, 8, 50, 0, 16, 0, 2, 0, 0, 0, 0, 208, + 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 35, + 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, + 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 35, 0, 0, 10, 98, 0, 16, 0, 0, 0, 0, 0, 6, + 1, 16, 128, 65, 0, 0, 0, 2, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, + 166, 11, 16, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 41, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 78, 0, 0, + 8, 0, 208, 0, 0, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 164, 0, 0, 10, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, + 0, 0, 0, 0, 0, 70, 132, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 10, 98, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 164, 0, 0, 10, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 164, 0, 0, 10, + 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, + 0, 70, 132, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, + 0, 10, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, + 0, 0, 0, 70, 132, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 39, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 9, 0, + 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_downscale_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_downscale_cs.h new file mode 100644 index 0000000..da071c5 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_downscale_cs.h @@ -0,0 +1,227 @@ +#if 0 +// +// Generated by Microsoft (R) D3D Shader Disassembler +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed | allResourcesBound +dcl_constantbuffer CB0[0:0][2], immediateIndexed, space=0 +dcl_resource_raw T0[0:0], space=0 +dcl_uav_raw U0[0:0], space=0 +dcl_input vThreadGroupID.x +dcl_input vThreadIDInGroup.xy +dcl_temps 2 +dcl_tgsm_structured g0, 4, 1024 +dcl_thread_group 32, 32, 1 +uge r0.x, vThreadGroupID.x, CB0[0][0].w +if_nz r0.x + ret +endif +imad r0.x, vThreadIDInGroup.y, l(32), vThreadIDInGroup.x +ishl r0.yz, l(0, 1, 1024, 0), CB0[0][0].zzzz +imul null, r0.w, CB0[0][0].y, CB0[0][0].x +ine r1.y, CB0[0][1].x, l(0) +ult r1.z, l(1), r0.w +and r1.y, r1.z, r1.y +if_nz r1.y + ushr r1.yz, CB0[0][0].xxyx, l(0, 1, 1, 0) + imad r1.y, r1.z, CB0[0][0].x, r1.y +else + mov r1.y, l(0) +endif +imul null, r1.xz, r0.wwyw, r0.zzxz +imul null, r0.w, r0.w, r1.z +imad r0.w, vThreadGroupID.x, r1.x, r0.w +imad r0.y, r1.y, r0.y, r0.w +ult r0.w, CB0[0][0].z, l(2) +if_nz r0.w + if_z CB0[0][0].z + and r0.w, r0.y, l(-4) + ld_raw r0.w, r0.w, T0[0].xxxx + bfi r1.xw, l(2, 0, 0, 2), l(3, 0, 0, 3), r0.yyyx, l(0, 0, 0, 0) + ushr r0.w, r0.w, r1.x + ushr r1.x, r0.x, l(2) + and r1.z, r0.x, l(3) + bfi r0.w, l(8), r1.w, r0.w, l(0) + if_z r1.z + store_structured g0.x, r1.x, l(0), r0.w + endif + sync_g_t + if_nz r1.z + mov r1.y, l(0) + atomic_or g0, r1.xyxx, r0.w + endif + sync_g_t + if_z r1.z + and r0.w, r0.x, l(1020) + imad r0.w, vThreadGroupID.x, l(1024), r0.w + ld_structured r1.x, r1.x, l(0), g0.xxxx + store_raw U0[0].x, r0.w, r1.x + endif + else + and r0.w, r0.y, l(-4) + ld_raw r0.w, r0.w, T0[0].xxxx + ishl r1.x, r0.y, l(3) + and r1.x, r1.x, l(16) + ushr r0.w, r0.w, r1.x + ushr r1.x, r0.x, l(1) + and r1.z, r0.x, l(1) + bfi r0.x, l(1), l(4), r0.x, l(0) + bfi r0.x, l(16), r0.x, r0.w, l(0) + if_z r1.z + store_structured g0.x, r1.x, l(0), r0.x + endif + sync_g_t + if_nz r1.z + mov r1.y, l(0) + atomic_or g0, r1.xyxx, r0.x + endif + sync_g_t + if_z r1.z + ishl r0.x, r1.x, l(2) + imad r0.x, vThreadGroupID.x, l(2048), r0.x + ld_structured r0.w, r1.x, l(0), g0.xxxx + store_raw U0[0].x, r0.x, r0.w + endif + endif +else + imad r0.z, vThreadGroupID.x, r0.z, r1.z + ieq r0.x, CB0[0][0].z, l(2) + if_nz r0.x + ld_raw r0.x, r0.y, T0[0].xxxx + store_raw U0[0].x, r0.z, r0.x + else + ieq r0.x, CB0[0][0].z, l(3) + if_nz r0.x + ld_raw r0.xy, r0.y, T0[0].xyxx + store_raw U0[0].xy, r0.z, r0.xyxx + endif + endif +endif +ret +// Approximately 0 instruction slots used +#endif + +const BYTE resolve_downscale_cs[] = { + 68, 88, 66, 67, 235, 139, 102, 94, 189, 150, 220, 235, 94, 229, 59, 205, 74, 78, 159, 167, + 1, 0, 0, 0, 164, 8, 0, 0, 3, 0, 0, 0, 44, 0, 0, 0, 60, 0, 0, 0, + 76, 0, 0, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, + 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, + 80, 8, 0, 0, 81, 0, 5, 0, 20, 2, 0, 0, 106, 8, 8, 1, 89, 0, 0, 7, + 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 161, 0, 0, 6, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 157, 0, 0, 6, 70, 238, 49, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 2, 18, 16, 2, 0, + 95, 0, 0, 2, 50, 32, 2, 0, 104, 0, 0, 2, 2, 0, 0, 0, 160, 0, 0, 5, + 0, 240, 17, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 4, 0, 0, 155, 0, 0, 4, + 32, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 80, 0, 0, 8, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 16, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 35, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 32, 2, 0, + 1, 64, 0, 0, 32, 0, 0, 0, 10, 32, 2, 0, 41, 0, 0, 12, 98, 0, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 166, 138, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 38, 0, 0, 12, 0, 208, 0, 0, 130, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, + 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 12, 98, 0, 16, 0, + 1, 0, 0, 0, 6, 129, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 34, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 38, 0, 0, 8, 0, 208, 0, 0, + 82, 0, 16, 0, 1, 0, 0, 0, 246, 13, 16, 0, 0, 0, 0, 0, 166, 8, 16, 0, + 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 8, + 130, 0, 16, 0, 0, 0, 0, 0, 10, 16, 2, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 79, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 42, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 31, 0, 0, 5, 42, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 252, 255, 255, 255, + 165, 0, 0, 8, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 20, 146, 0, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 86, 1, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 85, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 31, 0, 0, 3, 42, 0, 16, 0, 1, 0, 0, 0, 168, 0, 0, 9, 18, 240, 17, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 190, 24, 0, 1, 31, 0, 4, 3, + 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 170, 0, 0, 7, 0, 240, 17, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 190, 24, 0, 1, 31, 0, 0, 3, 42, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, + 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 252, 3, 0, 0, 35, 0, 0, 8, 130, 0, 16, 0, 0, 0, 0, 0, 10, 16, 2, 0, + 1, 64, 0, 0, 0, 4, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, + 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 166, 0, 0, 8, 18, 224, 33, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 1, 0, 0, 7, 130, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 252, 255, 255, 255, + 165, 0, 0, 8, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 16, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 7, + 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, + 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 31, 0, 0, 3, 42, 0, 16, 0, 1, 0, 0, 0, 168, 0, 0, 9, 18, 240, 17, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 190, 24, 0, 1, 31, 0, 4, 3, + 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 170, 0, 0, 7, 0, 240, 17, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 190, 24, 0, 1, 31, 0, 0, 3, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 35, 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 10, 16, 2, 0, + 1, 64, 0, 0, 0, 8, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, + 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 166, 0, 0, 8, 18, 224, 33, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 18, 0, 0, 1, 35, 0, 0, 8, + 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 2, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 32, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, + 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 165, 0, 0, 8, + 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 166, 0, 0, 8, 18, 224, 33, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 18, 0, 0, 1, 32, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 42, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 166, 0, 0, 8, 50, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 21, 0, 0, 1, 21, 0, 0, 1, 62, 0, 0, 1}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_32bpp_1x2xmsaa_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_32bpp_1x2xmsaa_cs.h new file mode 100644 index 0000000..65d1e30 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_32bpp_1x2xmsaa_cs.h @@ -0,0 +1,543 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_resolve_edram_info; // Offset: 0 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 4 Size: 4 +// uint xe_resolve_dest_info; // Offset: 8 Size: 4 +// uint xe_resolve_dest_coordinate_info;// Offset: 12 Size: 4 +// uint xe_resolve_dest_base; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram texture uint4 buf T0 t0 1 +// xe_resolve_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][2], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 9 +dcl_thread_group 8, 8, 1 +ubfe r0.x, l(11), l(5), CB0[0][0].y +and r1.xyzw, CB0[0][0].xxzz, l(1023, 4096, 7, 8) +and r0.y, CB0[0][0].z, l(0x01000000) +ushr r2.xyzw, CB0[0][0].ywww, l(4, 10, 20, 24) +uge r0.x, vThreadID.x, r0.x +if_nz r0.x + ret +endif +mov r3.x, CB0[0][0].y +mov r3.y, r2.x +bfi r0.xz, l(4, 0, 1, 0), l(3, 0, 3, 0), r3.xxyx, l(0, 0, 0, 0) +bfi r0.w, l(10), l(5), CB0[0][0].w, l(0) +bfi r3.xyzw, l(4, 4, 4, 4), l(3, 3, 3, 3), r2.zwwz, l(0, 0, 0, 0) +ubfe r2.xzw, l(2, 0, 3, 11), l(10, 0, 28, 13), CB0[0][0].xxwx +ishl r4.xw, vThreadID.xxxx, l(3, 0, 0, 3) +mov r4.yz, vThreadID.yyyy +iadd r0.xz, r0.xxzx, r4.wwzw +uge r5.x, l(3), r2.z +if_z r5.x + ieq r5.x, r2.z, l(5) + if_nz r5.x + mov r2.z, l(2) + else + mov r2.z, l(0) + endif +endif +uge r5.xy, r2.xxxx, l(2, 1, 0, 0) +and r5.xy, r5.xyxx, l(1, 1, 0, 0) +ishl r0.xz, r0.xxzx, r5.xxyx +ushr r2.x, r2.z, l(1) +and r2.xz, r2.xxzx, l(1, 0, 1, 0) +iadd r0.xz, r0.xxzx, r2.xxzx +udiv r2.xz, null, r0.xxzx, l(80, 0, 16, 0) +imad r1.x, r2.z, r1.x, r2.x +iadd r1.x, r1.x, r2.w +imad r0.xz, -r2.xxzx, l(80, 0, 16, 0), r0.xxzx +if_nz r1.y + uge r1.y, r0.x, l(40) + movc r1.y, r1.y, l(-40), l(40) + iadd r0.x, r0.x, r1.y +endif +imad r0.x, r0.z, l(80), r0.x +imad r0.x, r1.x, l(1280), r0.x +udiv null, r0.x, r0.x, l(0x00280000) +ushr r0.x, r0.x, l(2) +ld r5.xyzw, r0.xxxx, T0[0].xyzw +iadd r0.x, r0.x, l(1) +ld r6.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.y + ubfe r0.x, l(4), l(24), CB0[0][0].x + switch r0.x + case l(0) + case l(1) + and r7.xyzw, r5.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + bfi r7.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r5.xyzw, r7.xyzw + ubfe r8.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r5.xyzw + iadd r5.xyzw, r7.xyzw, r8.xyzw + and r7.xyzw, r6.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + bfi r7.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r6.xyzw, r7.xyzw + ubfe r8.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r6.xyzw + iadd r6.xyzw, r7.xyzw, r8.xyzw + break + case l(2) + case l(3) + case l(10) + case l(12) + and r7.xyzw, r5.xyzw, l(0xc00ffc00, 0xc00ffc00, 0xc00ffc00, 0xc00ffc00) + bfi r7.xyzw, l(10, 10, 10, 10), l(20, 20, 20, 20), r5.xyzw, r7.xyzw + ubfe r8.xyzw, l(10, 10, 10, 10), l(20, 20, 20, 20), r5.xyzw + iadd r5.xyzw, r7.xyzw, r8.xyzw + and r7.xyzw, r6.xyzw, l(0xc00ffc00, 0xc00ffc00, 0xc00ffc00, 0xc00ffc00) + bfi r7.xyzw, l(10, 10, 10, 10), l(20, 20, 20, 20), r6.xyzw, r7.xyzw + ubfe r8.xyzw, l(10, 10, 10, 10), l(20, 20, 20, 20), r6.xyzw + iadd r6.xyzw, r7.xyzw, r8.xyzw + break + default + break + endswitch +endif +iadd r3.xyzw, r3.xyzw, r4.xyzw +if_nz r1.w + ubfe r0.x, l(3), l(4), CB0[0][0].z + ishl r0.y, r2.y, l(5) + ishr r2.xyzw, r3.zwzw, l(4, 5, 3, 3) + ishr r0.z, r0.x, l(2) + ushr r0.y, r0.y, l(4) + and r0.y, r0.y, l(2046) + imad r0.y, r0.z, r0.y, r2.x + ushr r1.x, r0.w, l(5) + imad r0.y, r0.y, r1.x, r2.y + ishl r1.x, r3.z, l(10) + ishr r1.x, r1.x, l(6) + and r1.x, r1.x, l(96) + iadd r0.z, r0.z, r2.z + bfi r1.y, l(1), l(1), r0.z, l(0) + iadd r1.y, r1.y, r2.w + bfi r1.y, l(2), l(1), r1.y, l(0) + bfi r0.z, l(1), l(0), r0.z, r1.y + bfi r1.yw, l(0, 20, 0, 20), l(0, 10, 0, 13), r0.yyyy, l(0, 0, 0, 0) + imad r1.xy, r1.xxxx, l(2, 16, 0, 0), r1.ywyy + bfi r0.xy, l(2, 2, 0, 0), l(8, 11, 0, 0), r0.xxxx, r1.xyxx + bfi r1.x, l(1), l(4), r3.z, l(0) + ubfe r1.y, l(3), l(6), r0.x + and r1.w, r0.z, l(6) + bfi r0.z, l(1), l(8), r0.z, l(0) + imad r0.z, r1.y, l(32), r0.z + imad r0.z, r1.w, l(4), r0.z + bfi r0.xy, l(6, 6, 0, 0), l(0, 3, 0, 0), r1.xxxx, r0.xyxx + bfi r0.y, l(9), l(3), r0.z, r0.y + bfi r0.x, l(6), l(0), r0.x, r0.y +else + ishr r2.xyzw, r3.xyzw, l(5, 5, 2, 3) + ushr r0.y, r0.w, l(5) + imad r0.y, r2.y, r0.y, r2.x + ishl r0.zw, r3.zzzz, l(0, 0, 5, 7) + and r0.zw, r0.zzzw, l(0, 0, 448, 2048) + bfi r1.x, l(23), l(9), r0.y, r0.z + bfi r1.y, l(1), l(4), r3.z, l(0) + iadd r1.x, r1.x, r1.y + ishl r2.xy, r0.zzzz, l(3, 2, 0, 0) + bfi r0.yz, l(0, 23, 23, 0), l(0, 12, 11, 0), r0.yyyy, r2.xxyx + imad r0.yz, r1.yyyy, l(0, 8, 4, 0), r0.yyzy + bfi r0.y, l(12), l(0), r0.w, r0.y + and r0.z, r0.z, l(1792) + iadd r0.y, r0.y, r0.z + and r0.z, r2.z, l(2) + iadd r0.z, r2.w, r0.z + bfi r0.z, l(2), l(6), r0.z, l(0) + iadd r0.y, r0.y, r0.z + bfi r0.x, l(6), l(0), r1.x, r0.y +endif +iadd r0.x, r0.x, CB0[0][1].x +ushr r0.x, r0.x, l(4) +ieq r0.yzw, r1.zzzz, l(0, 1, 2, 3) +or r0.yz, r0.zzwz, r0.yyzy +if_nz r0.y + ishl r1.xyzw, r5.xyzw, l(8, 8, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r2.xyzw, r5.xyzw, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r5.xyzw, r1.xyzw, r2.xyzw +endif +if_nz r0.z + ushr r1.xyzw, r5.xyzw, l(16, 16, 16, 16) + bfi r5.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r5.xyzw, r1.xyzw +endif +store_uav_typed U0[0].xyzw, r0.xxxx, r5.xyzw +iadd r0.x, r0.x, l(2) +if_nz r0.y + ishl r1.xyzw, r6.xyzw, l(8, 8, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r2.xyzw, r6.xyzw, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r6.xyzw, r1.xyzw, r2.xyzw +endif +if_nz r0.z + ushr r1.xyzw, r6.xyzw, l(16, 16, 16, 16) + bfi r6.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r6.xyzw, r1.xyzw +endif +store_uav_typed U0[0].xyzw, r0.xxxx, r6.xyzw +ret +// Approximately 161 instruction slots used +#endif + +const BYTE resolve_fast_32bpp_1x2xmsaa_cs[] = { + 68, 88, 66, 67, 32, 82, 137, 1, 142, 147, 101, 222, 227, 175, 35, 40, 173, 176, 139, + 73, 1, 0, 0, 0, 108, 24, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 208, 2, + 0, 0, 224, 2, 0, 0, 240, 2, 0, 0, 208, 23, 0, 0, 82, 68, 69, 70, 148, + 2, 0, 0, 1, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 105, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 101, 100, 114, 97, 109, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 213, 0, 0, 0, 5, 0, 0, 0, 252, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 196, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 4, 2, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 31, 2, 0, 0, 8, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 52, 2, 0, 0, 12, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 84, 2, 0, + 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, + 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 101, 100, 114, 97, 109, 95, 105, 110, 102, + 111, 0, 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 218, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 99, 111, + 111, 114, 100, 105, 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 105, 110, 102, 111, 0, 120, 101, 95, + 114, 101, 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 99, 111, 111, 114, 100, 105, + 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 95, 98, 97, 115, 101, 0, 77, 105, 99, 114, 111, 115, 111, + 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, + 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, + 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 216, 20, 0, 0, + 81, 0, 5, 0, 54, 5, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, + 0, 95, 0, 0, 2, 50, 0, 2, 0, 104, 0, 0, 2, 9, 0, 0, 0, 155, 0, + 0, 4, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 138, 0, 0, 11, 18, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 64, 0, 0, + 5, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 12, 242, 0, 16, 0, 1, 0, 0, 0, 6, 138, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 0, + 16, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 9, 34, 0, 16, 0, + 0, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 1, 85, 0, 0, 12, 242, 0, 16, 0, 2, 0, + 0, 0, 214, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, + 80, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 2, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 62, 0, + 0, 1, 21, 0, 0, 1, 54, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 26, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 34, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 20, 82, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 140, 0, 0, 13, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, + 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 20, + 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 230, 11, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 138, 0, 0, 17, 210, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, 0, 10, 0, + 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 13, 0, 0, 0, 6, 131, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 9, 146, 0, 16, 0, + 4, 0, 0, 0, 6, 0, 2, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 98, 0, 16, 0, 4, 0, + 0, 0, 86, 5, 2, 0, 30, 0, 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 6, + 2, 16, 0, 0, 0, 0, 0, 246, 14, 16, 0, 4, 0, 0, 0, 80, 0, 0, 7, + 18, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 31, 0, 0, 3, 10, 0, 16, 0, 5, 0, 0, 0, 32, 0, + 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 5, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 5, 0, 0, 0, + 54, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 80, 0, 0, 10, 50, + 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, + 0, 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 6, 2, 16, 0, 0, 0, 0, 0, + 6, 1, 16, 0, 5, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 6, 2, 16, 0, 0, 0, 0, + 0, 6, 2, 16, 0, 2, 0, 0, 0, 78, 0, 0, 11, 82, 0, 16, 0, 2, 0, + 0, 0, 0, 208, 0, 0, 6, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 80, + 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, + 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, + 0, 0, 0, 35, 0, 0, 13, 82, 0, 16, 0, 0, 0, 0, 0, 6, 2, 16, 128, + 65, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, 0, 80, 0, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 6, 2, 16, 0, 0, 0, 0, 0, 31, 0, + 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 40, 0, 0, 0, + 55, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 216, 255, 255, 255, 1, 64, 0, 0, 40, 0, 0, 0, 30, 0, + 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 35, 0, 0, 9, 18, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 80, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 5, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 78, 0, 0, 8, 0, 208, 0, 0, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 40, + 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 5, + 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 45, 0, 0, 8, 242, 0, + 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, + 138, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 1, 64, 0, 0, 24, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 76, 0, 0, 3, 10, 0, 16, 0, 0, 0, 0, 0, 6, + 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 140, 0, 0, 17, 242, 0, 16, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 138, 0, + 0, 15, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 140, 0, 0, 17, 242, 0, 16, + 0, 7, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, + 14, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 0, 0, + 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, + 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 6, + 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 7, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 252, 15, + 192, 0, 252, 15, 192, 0, 252, 15, 192, 0, 252, 15, 192, 140, 0, 0, 17, 242, 0, + 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 20, 0, 0, 0, 20, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, + 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 0, 252, 15, 192, 0, 252, 15, 192, 0, 252, 15, 192, 0, 252, 15, 192, + 140, 0, 0, 17, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 70, 14, 16, 0, 6, + 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 242, + 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, + 8, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 2, 0, 0, 1, 23, 0, 0, + 1, 21, 0, 0, 1, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 58, + 0, 16, 0, 1, 0, 0, 0, 138, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 230, 14, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 254, 7, 0, 0, 35, 0, 0, 9, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, + 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 41, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 0, + 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 96, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, + 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 140, 0, 0, 20, 162, 0, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 1, 0, + 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 16, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 5, 16, 0, 1, 0, 0, 0, + 140, 0, 0, 17, 50, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, + 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 140, + 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, + 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 42, 0, 0, 10, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 85, 0, + 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 166, 10, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, + 166, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 192, 1, 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, + 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, + 2, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, + 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, + 11, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 6, 1, 16, + 0, 2, 0, 0, 0, 35, 0, 0, 12, 98, 0, 16, 0, 0, 0, 0, 0, 86, 5, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, + 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, + 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, + 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 32, 0, 0, 10, 226, 0, + 16, 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, + 98, 0, 16, 0, 0, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 86, 6, 16, + 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, + 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, + 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, + 0, 1, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, + 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, + 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, + 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, + 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, + 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, + 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, + 84, 148, 0, 0, 0, 161, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 36, 0, 0, 0, 7, 0, 0, 0, 11, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_32bpp_1x2xmsaa_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_32bpp_1x2xmsaa_scaled_cs.h new file mode 100644 index 0000000..8f6c6f7 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_32bpp_1x2xmsaa_scaled_cs.h @@ -0,0 +1,674 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_resolve_edram_info; // Offset: 0 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 4 Size: 4 +// uint xe_resolve_dest_info; // Offset: 8 Size: 4 +// uint xe_resolve_dest_coordinate_info;// Offset: 12 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram texture uint4 buf T0 t0 1 +// xe_resolve_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 9 +dcl_thread_group 8, 8, 1 +and r0.xyzw, CB0[0][0].xxxz, l(1023, 4096, 0x20000000, 7) +if_nz r0.z + ubfe r1.xy, l(2, 2, 0, 0), l(17, 20, 0, 0), CB0[0][0].yyyy +else + mov r1.xy, l(0,0,0,0) +endif +ubfe r2.xyz, l(3, 3, 11, 0), l(16, 19, 5, 0), CB0[0][0].yyyy +imul null, r0.z, r2.x, r2.z +and r1.zw, CB0[0][0].zzzz, l(0, 0, 8, 0x01000000) +ushr r3.xyzw, CB0[0][0].ywww, l(4, 10, 20, 24) +uge r0.z, vThreadID.x, r0.z +if_nz r0.z + ret +endif +mov r4.x, CB0[0][0].y +mov r4.y, r3.x +bfi r2.zw, l(0, 0, 4, 1), l(0, 0, 3, 3), r4.xxxy, l(0, 0, 0, 0) +bfi r0.z, l(10), l(5), CB0[0][0].w, l(0) +bfi r3.xz, l(4, 0, 4, 0), l(3, 0, 3, 0), r3.zzwz, l(0, 0, 0, 0) +ubfe r4.xyz, l(2, 3, 11, 0), l(10, 28, 13, 0), CB0[0][0].xwxx +ishl r5.x, vThreadID.x, l(3) +umax r5.y, r1.y, vThreadID.y +imad r2.zw, r2.zzzw, r2.xxxy, r5.xxxy +uge r1.y, l(3), r4.y +if_z r1.y + ieq r1.y, r4.y, l(5) + if_nz r1.y + mov r4.y, l(2) + else + mov r4.y, l(0) + endif +endif +uge r5.yw, r4.xxxx, l(0, 2, 0, 1) +and r5.yw, r5.yyyw, l(0, 1, 0, 1) +ishl r2.zw, r2.zzzw, r5.yyyw +ushr r4.x, r4.y, l(1) +and r4.xy, r4.xyxx, l(1, 1, 0, 0) +iadd r2.zw, r2.zzzw, r4.xxxy +imul null, r4.xy, r2.xyxx, l(80, 16, 0, 0) +udiv r5.yw, null, r2.zzzw, r4.xxxy +imad r0.x, r5.w, r0.x, r5.y +iadd r0.x, r0.x, r4.z +imad r2.zw, -r5.yyyw, r4.xxxy, r2.zzzw +if_nz r0.y + ushr r0.y, r4.x, l(1) + uge r1.y, r2.z, r0.y + ineg r3.w, r0.y + movc r0.y, r1.y, r3.w, r0.y + iadd r2.z, r0.y, r2.z +endif +imul null, r0.y, r4.y, r4.x +imad r1.y, r2.w, r4.x, r2.z +imad r0.x, r0.x, r0.y, r1.y +ishl r0.y, r0.y, l(11) +udiv null, r0.x, r0.x, r0.y +ushr r0.x, r0.x, l(2) +ld r4.xyzw, r0.xxxx, T0[0].zxyw +iadd r0.x, r0.x, l(1) +ld r6.xyzw, r0.xxxx, T0[0].xyzw +ieq r0.x, r5.x, l(0) +ine r0.y, r1.x, l(0) +and r0.x, r0.y, r0.x +if_nz r0.x + uge r0.x, r1.x, l(2) + if_nz r0.x + uge r0.x, r1.x, l(3) + if_nz r0.x + mov r4.x, r4.w + endif + mov r4.xz, r4.xxxx + endif + mov r4.xyz, r4.xzzx +endif +if_nz r1.w + ubfe r0.x, l(4), l(24), CB0[0][0].x + switch r0.x + case l(0) + case l(1) + and r7.xyzw, r4.yzxw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + bfi r7.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r4.yzxw, r7.xyzw + ubfe r8.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r4.yzxw + iadd r4.xyzw, r7.zxyw, r8.zxyw + and r7.xyzw, r6.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + bfi r7.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r6.xyzw, r7.xyzw + ubfe r8.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r6.xyzw + iadd r6.xyzw, r7.xyzw, r8.xyzw + break + case l(2) + case l(3) + case l(10) + case l(12) + and r7.xyzw, r4.yzxw, l(0xc00ffc00, 0xc00ffc00, 0xc00ffc00, 0xc00ffc00) + bfi r7.xyzw, l(10, 10, 10, 10), l(20, 20, 20, 20), r4.yzxw, r7.xyzw + ubfe r8.xyzw, l(10, 10, 10, 10), l(20, 20, 20, 20), r4.yzxw + iadd r4.xyzw, r7.zxyw, r8.zxyw + and r7.xyzw, r6.xyzw, l(0xc00ffc00, 0xc00ffc00, 0xc00ffc00, 0xc00ffc00) + bfi r7.xyzw, l(10, 10, 10, 10), l(20, 20, 20, 20), r6.xyzw, r7.xyzw + ubfe r8.xyzw, l(10, 10, 10, 10), l(20, 20, 20, 20), r6.xyzw + iadd r6.xyzw, r7.xyzw, r8.xyzw + break + default + break + endswitch +endif +mov r5.z, vThreadID.y +imad r7.yz, r3.xxzx, r2.xxyx, r5.xxzx +ushr r7.x, r7.y, l(2) +udiv r0.xy, null, r7.xzxx, r2.xyxx +ishl r1.x, r0.x, l(2) +if_nz r1.z + ubfe r1.y, l(3), l(4), CB0[0][0].z + ishl r1.z, r3.y, l(5) + ishr r2.zw, r0.yyyy, l(0, 0, 4, 3) + ishr r1.w, r1.y, l(2) + ushr r1.z, r1.z, l(4) + and r1.z, r1.z, l(2046) + imad r1.z, r1.w, r1.z, r2.z + ushr r2.z, r0.z, l(5) + ibfe r3.xy, l(27, 29, 0, 0), l(3, 1, 0, 0), r0.xxxx + imad r1.z, r1.z, r2.z, r3.x + ishl r2.z, r0.y, l(10) + and r2.z, r2.z, l(6144) + bfi r2.z, l(3), l(8), r1.x, r2.z + ishr r2.z, r2.z, l(6) + iadd r1.w, r1.w, r2.w + bfi r2.w, l(1), l(1), r1.w, l(0) + iadd r2.w, r2.w, r3.y + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r1.w, l(1), l(0), r1.w, r2.w + bfi r3.xy, l(20, 20, 0, 0), l(10, 13, 0, 0), r1.zzzz, l(0, 0, 0, 0) + imad r2.zw, r2.zzzz, l(0, 0, 2, 16), r3.xxxy + bfi r1.yz, l(0, 2, 2, 0), l(0, 8, 11, 0), r1.yyyy, r2.zzwz + bfi r2.z, l(1), l(4), r0.y, l(0) + ubfe r2.w, l(3), l(6), r1.y + and r3.x, r1.w, l(6) + bfi r1.w, l(1), l(8), r1.w, l(0) + imad r1.w, r2.w, l(32), r1.w + imad r1.w, r3.x, l(4), r1.w + bfi r1.yz, l(0, 5, 5, 0), l(0, 0, 3, 0), r2.zzzz, r1.yyzy + bfi r1.z, l(9), l(3), r1.w, r1.z + bfi r1.y, l(6), l(0), r1.y, r1.z +else + ibfe r1.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), r0.xxxx + ishr r2.zw, r0.yyyy, l(0, 0, 5, 2) + ushr r0.z, r0.z, l(5) + imad r0.z, r2.z, r0.z, r1.z + ishl r3.xy, r0.yyyy, l(5, 7, 0, 0) + and r3.xy, r3.xyxx, l(448, 2048, 0, 0) + bfi r1.z, l(3), l(3), r1.x, r3.x + bfi r1.z, l(23), l(9), r0.z, r1.z + bfi r2.z, l(1), l(4), r0.y, l(0) + iadd r1.z, r1.z, r2.z + ishl r3.xz, r3.xxxx, l(3, 0, 2, 0) + bfi r3.xz, l(3, 0, 3, 0), l(6, 0, 5, 0), r1.xxxx, r3.xxzx + bfi r3.xz, l(23, 0, 23, 0), l(12, 0, 11, 0), r0.zzzz, r3.xxzx + imad r3.xz, r2.zzzz, l(8, 0, 4, 0), r3.xxzx + bfi r0.z, l(12), l(0), r3.y, r3.x + and r1.x, r3.z, l(1792) + iadd r0.z, r0.z, r1.x + and r1.x, r2.w, l(2) + iadd r1.x, r1.w, r1.x + bfi r1.x, l(2), l(6), r1.x, l(0) + iadd r0.z, r0.z, r1.x + bfi r1.y, l(6), l(0), r1.z, r0.z +endif +imad r0.xy, -r0.xyxx, r2.xyxx, r7.xzxx +imul null, r0.z, r2.y, r2.x +imad r0.x, r0.x, r2.y, r0.y +ishl r0.x, r0.x, l(4) +imad r0.x, r1.y, r0.z, r0.x +ushr r0.x, r0.x, l(4) +ieq r0.yzw, r0.wwww, l(0, 1, 2, 3) +or r0.yz, r0.zzwz, r0.yyzy +if_nz r0.y + ishl r1.xyzw, r4.yzxw, l(8, 8, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r3.xyzw, r4.yzxw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r4.xyzw, r1.zxyw, r3.zxyw +endif +if_nz r0.z + ushr r1.xyzw, r4.yzxw, l(16, 16, 16, 16) + bfi r4.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r4.xyzw, r1.zxyw +endif +store_uav_typed U0[0].xyzw, r0.xxxx, r4.yzxw +ult r0.w, l(1), r2.x +if_nz r0.w + ushr r0.w, r5.x, l(2) + udiv r1.x, null, r0.w, r2.x + imad r0.w, -r1.x, r2.x, r0.w + iadd r1.x, r0.w, l(1) + ieq r1.x, r2.x, r1.x + if_nz r1.x + ishl r1.x, r2.x, l(5) + ishl r0.w, r0.w, l(4) + iadd r0.w, -r0.w, r1.x + else + mov r0.w, l(16) + endif +else + mov r0.w, l(32) +endif +imul null, r0.w, r2.y, r0.w +ushr r0.w, r0.w, l(4) +iadd r0.x, r0.w, r0.x +if_nz r0.y + ishl r1.xyzw, r6.xyzw, l(8, 8, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r2.xyzw, r6.xyzw, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r6.xyzw, r1.xyzw, r2.xyzw +endif +if_nz r0.z + ushr r1.xyzw, r6.xyzw, l(16, 16, 16, 16) + bfi r6.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r6.xyzw, r1.xyzw +endif +store_uav_typed U0[0].xyzw, r0.xxxx, r6.xyzw +ret +// Approximately 218 instruction slots used +#endif + +const BYTE resolve_fast_32bpp_1x2xmsaa_scaled_cs[] = { + 68, 88, 66, 67, 67, 67, 160, 27, 39, 242, 138, 81, 247, 239, 31, 104, 237, 117, 48, + 90, 1, 0, 0, 0, 12, 30, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 144, 2, + 0, 0, 160, 2, 0, 0, 176, 2, 0, 0, 112, 29, 0, 0, 82, 68, 69, 70, 84, + 2, 0, 0, 1, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 44, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 101, 100, 114, 97, 109, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 213, 0, 0, 0, 4, 0, 0, 0, 252, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 156, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 220, 1, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 247, 1, 0, 0, 8, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 12, 2, 0, 0, 12, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, + 114, 101, 115, 111, 108, 118, 101, 95, 101, 100, 114, 97, 109, 95, 105, 110, 102, 111, 0, + 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 178, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 99, 111, 111, 114, + 100, 105, 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 100, 101, 115, 116, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 99, 111, 111, 114, 100, 105, 110, 97, + 116, 101, 95, 105, 110, 102, 111, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 83, 72, 69, 88, 184, 26, 0, 0, 81, 0, 5, 0, 174, 6, 0, + 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 88, 8, 0, 7, 70, + 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, + 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 95, 0, 0, 2, 50, 0, + 2, 0, 104, 0, 0, 2, 9, 0, 0, 0, 155, 0, 0, 4, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, 0, + 6, 136, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 255, 3, 0, 0, 0, 16, 0, 0, 0, 0, 0, 32, 7, 0, 0, 0, 31, 0, + 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 17, 50, 0, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 17, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 86, 133, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 18, 0, 0, 1, 54, 0, 0, 8, 50, 0, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 1, 138, 0, 0, 17, 114, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 86, + 133, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, + 0, 208, 0, 0, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 12, 194, 0, 16, 0, 1, 0, + 0, 0, 166, 138, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, + 85, 0, 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, 214, 143, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 10, 0, + 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 80, 0, 0, 6, 66, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 2, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 54, 0, 0, + 7, 18, 0, 16, 0, 4, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 4, 0, 0, 0, 10, + 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 20, 194, 0, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 13, 66, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, + 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 20, 82, 0, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 166, 11, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 17, 114, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 28, 0, 0, 0, 13, 0, 0, + 0, 0, 0, 0, 0, 198, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 2, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 83, 0, 0, 6, 34, 0, 16, 0, 5, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 9, 194, 0, 16, + 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 2, 0, + 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, + 31, 0, 0, 3, 26, 0, 16, 0, 1, 0, 0, 0, 32, 0, 0, 7, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, + 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, + 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 18, 0, 0, 1, + 54, 0, 0, 5, 34, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 21, 0, 0, 1, 21, 0, 0, 1, 80, 0, 0, 10, 162, 0, 16, 0, 5, 0, + 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 162, 0, 16, 0, + 5, 0, 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 194, 0, + 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 86, 13, 16, 0, 5, + 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, + 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, + 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 194, + 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, + 4, 0, 0, 0, 38, 0, 0, 11, 0, 208, 0, 0, 50, 0, 16, 0, 4, 0, 0, + 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 80, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 0, 0, 8, 162, 0, 16, 0, 5, + 0, 0, 0, 0, 208, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, + 4, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, + 0, 5, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, + 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 35, 0, 0, 10, 194, 0, 16, 0, + 2, 0, 0, 0, 86, 13, 16, 128, 65, 0, 0, 0, 5, 0, 0, 0, 6, 4, 16, + 0, 4, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, + 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 80, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 40, 0, 0, 5, 130, 0, 16, 0, 3, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 38, 0, + 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, + 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 78, 0, 0, + 8, 0, 208, 0, 0, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 45, 0, 0, 8, 242, 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, + 0, 38, 125, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 39, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, + 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 80, 0, + 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, + 80, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 4, + 0, 0, 0, 21, 0, 0, 1, 54, 0, 0, 5, 82, 0, 16, 0, 4, 0, 0, 0, + 6, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 54, 0, 0, 5, 114, 0, 16, + 0, 4, 0, 0, 0, 134, 2, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, + 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 138, 0, 0, 11, 18, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, + 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 0, + 3, 10, 0, 16, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, 0, + 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 7, 0, 0, 0, 150, 12, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 140, 0, 0, + 17, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 150, 12, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 150, 12, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 4, 0, 0, 0, 38, 13, 16, 0, 7, 0, 0, 0, 38, 13, 16, 0, 8, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 140, 0, 0, 17, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, + 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 30, 0, + 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, + 14, 16, 0, 8, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, + 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, + 3, 1, 64, 0, 0, 10, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 150, 12, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 252, 15, 192, 0, 252, 15, 192, 0, 252, 15, 192, + 0, 252, 15, 192, 140, 0, 0, 17, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 150, + 12, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 138, 0, 0, 15, + 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 150, 12, 16, 0, 4, 0, 0, 0, 30, + 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 38, 13, 16, 0, 7, 0, 0, 0, + 38, 13, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 252, 15, 192, 0, 252, + 15, 192, 0, 252, 15, 192, 0, 252, 15, 192, 140, 0, 0, 17, 242, 0, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, + 0, 20, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, + 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 10, + 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 0, 0, 1, 10, + 0, 0, 1, 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, 54, 0, 0, 4, + 66, 0, 16, 0, 5, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 9, 98, 0, 16, + 0, 7, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 6, 1, 16, 0, 2, 0, + 0, 0, 6, 2, 16, 0, 5, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 7, + 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 78, 0, 0, 8, 50, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, 134, 0, 16, + 0, 7, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 138, 0, 0, 11, + 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 10, 194, 0, 16, 0, + 2, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 254, 7, + 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 85, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 5, 0, 0, 0, 139, 0, 0, 15, 50, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, + 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 0, 24, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 0, 7, + 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 20, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 10, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, 0, 2, 0, 0, 0, + 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 16, 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 140, 0, + 0, 17, 98, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, + 0, 166, 11, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 18, 0, + 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 166, 10, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 15, 194, 0, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, + 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, + 10, 194, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 85, + 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 86, + 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, + 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 192, 1, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, + 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 64, + 0, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, + 0, 0, 10, 82, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 140, 0, 0, 17, 82, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 6, + 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, + 1, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, 82, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 23, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 11, + 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 6, 2, 16, 0, + 3, 0, 0, 0, 35, 0, 0, 12, 82, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 66, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 140, + 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 21, 0, 0, 1, 35, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, + 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 134, + 0, 16, 0, 7, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, + 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 32, 0, 0, 10, + 226, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 0, + 0, 7, 98, 0, 16, 0, 0, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 86, + 6, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 150, 12, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 150, 12, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, + 0, 38, 13, 16, 0, 1, 0, 0, 0, 38, 13, 16, 0, 3, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 1, 0, 0, 0, 150, 12, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 38, 13, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 150, 12, + 16, 0, 4, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, + 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 78, 0, + 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 10, 130, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, + 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 130, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 30, 0, 0, 8, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, + 128, 65, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 18, 0, + 0, 1, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, + 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 54, 0, 0, 5, 130, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 21, 0, 0, 1, 38, 0, 0, + 8, 0, 208, 0, 0, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, + 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 6, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, + 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, + 0, 0, 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, + 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, + 0, 218, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 64, 0, 0, 0, 47, 0, 0, 0, 10, 0, 0, 0, 17, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 11, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_32bpp_4xmsaa_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_32bpp_4xmsaa_cs.h new file mode 100644 index 0000000..c3436f7 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_32bpp_4xmsaa_cs.h @@ -0,0 +1,574 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_resolve_edram_info; // Offset: 0 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 4 Size: 4 +// uint xe_resolve_dest_info; // Offset: 8 Size: 4 +// uint xe_resolve_dest_coordinate_info;// Offset: 12 Size: 4 +// uint xe_resolve_dest_base; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram texture uint4 buf T0 t0 1 +// xe_resolve_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][2], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 9 +dcl_thread_group 8, 8, 1 +ubfe r0.x, l(11), l(5), CB0[0][0].y +and r1.xyzw, CB0[0][0].xxzz, l(1023, 4096, 7, 8) +and r0.y, CB0[0][0].z, l(0x01000000) +ushr r2.xyzw, CB0[0][0].ywww, l(4, 10, 20, 24) +uge r0.x, vThreadID.x, r0.x +if_nz r0.x + ret +endif +mov r3.x, CB0[0][0].y +mov r3.y, r2.x +bfi r0.xz, l(4, 0, 1, 0), l(3, 0, 3, 0), r3.xxyx, l(0, 0, 0, 0) +bfi r0.w, l(10), l(5), CB0[0][0].w, l(0) +bfi r3.xyzw, l(4, 4, 4, 4), l(3, 3, 3, 3), r2.zwwz, l(0, 0, 0, 0) +ubfe r2.xz, l(11, 0, 3, 0), l(13, 0, 28, 0), CB0[0][0].xxwx +ishl r4.xw, vThreadID.xxxx, l(3, 0, 0, 3) +mov r4.yz, vThreadID.yyyy +iadd r0.xz, r0.xxzx, r4.wwzw +uge r2.w, l(3), r2.z +if_nz r2.w + mov r5.y, r2.z +else + ieq r2.w, r2.z, l(5) + if_nz r2.w + mov r5.y, l(2) + else + mov r5.y, l(0) + endif +endif +ishl r0.xz, r0.xxzx, l(1, 0, 1, 0) +ushr r5.x, r5.y, l(1) +bfi r0.xz, l(4, 0, 1, 0), l(0, 0, 0, 0), r5.xxyx, r0.xxzx +udiv r5.xy, null, r0.xzxx, l(80, 16, 0, 0) +imad r1.x, r5.y, r1.x, r5.x +iadd r1.x, r1.x, r2.x +imad r0.xz, -r5.xxyx, l(80, 0, 16, 0), r0.xxzx +if_nz r1.y + uge r1.y, r0.x, l(40) + movc r1.y, r1.y, l(-40), l(40) + iadd r0.x, r0.x, r1.y +endif +imad r0.x, r0.z, l(80), r0.x +imad r0.x, r1.x, l(1280), r0.x +udiv null, r0.x, r0.x, l(0x00280000) +ushr r0.x, r0.x, l(2) +ine r1.xy, r2.zzzz, l(2, 3, 0, 0) +and r0.z, r1.y, r1.x +if_nz r0.z + ld r5.xy, r0.xxxx, T0[0].xzyw + iadd r0.z, r0.x, l(1) + ld r5.zw, r0.zzzz, T0[0].ywxz + iadd r1.xy, r0.xxxx, l(2, 3, 0, 0) + ld r6.xy, r1.xxxx, T0[0].xzyw + ld r6.zw, r1.yyyy, T0[0].ywxz +else + ld r5.xy, r0.xxxx, T0[0].ywxz + iadd r0.z, r0.x, l(1) + ld r5.zw, r0.zzzz, T0[0].xzyw + iadd r0.xz, r0.xxxx, l(2, 0, 3, 0) + ld r6.xy, r0.xxxx, T0[0].ywxz + ld r6.zw, r0.zzzz, T0[0].xzyw +endif +if_nz r0.y + ubfe r0.x, l(4), l(24), CB0[0][0].x + switch r0.x + case l(0) + case l(1) + and r7.xyzw, r5.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + bfi r7.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r5.xyzw, r7.xyzw + ubfe r8.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r5.xyzw + iadd r5.xyzw, r7.xyzw, r8.xyzw + and r7.xyzw, r6.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + bfi r7.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r6.xyzw, r7.xyzw + ubfe r8.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r6.xyzw + iadd r6.xyzw, r7.xyzw, r8.xyzw + break + case l(2) + case l(3) + case l(10) + case l(12) + and r7.xyzw, r5.xyzw, l(0xc00ffc00, 0xc00ffc00, 0xc00ffc00, 0xc00ffc00) + bfi r7.xyzw, l(10, 10, 10, 10), l(20, 20, 20, 20), r5.xyzw, r7.xyzw + ubfe r8.xyzw, l(10, 10, 10, 10), l(20, 20, 20, 20), r5.xyzw + iadd r5.xyzw, r7.xyzw, r8.xyzw + and r7.xyzw, r6.xyzw, l(0xc00ffc00, 0xc00ffc00, 0xc00ffc00, 0xc00ffc00) + bfi r7.xyzw, l(10, 10, 10, 10), l(20, 20, 20, 20), r6.xyzw, r7.xyzw + ubfe r8.xyzw, l(10, 10, 10, 10), l(20, 20, 20, 20), r6.xyzw + iadd r6.xyzw, r7.xyzw, r8.xyzw + break + default + break + endswitch +endif +iadd r3.xyzw, r3.xyzw, r4.xyzw +if_nz r1.w + ubfe r0.x, l(3), l(4), CB0[0][0].z + ishl r0.y, r2.y, l(5) + ishr r2.xyzw, r3.zwzw, l(4, 5, 3, 3) + ishr r0.z, r0.x, l(2) + ushr r0.y, r0.y, l(4) + and r0.y, r0.y, l(2046) + imad r0.y, r0.z, r0.y, r2.x + ushr r1.x, r0.w, l(5) + imad r0.y, r0.y, r1.x, r2.y + ishl r1.x, r3.z, l(10) + ishr r1.x, r1.x, l(6) + and r1.x, r1.x, l(96) + iadd r0.z, r0.z, r2.z + bfi r1.y, l(1), l(1), r0.z, l(0) + iadd r1.y, r1.y, r2.w + bfi r1.y, l(2), l(1), r1.y, l(0) + bfi r0.z, l(1), l(0), r0.z, r1.y + bfi r1.yw, l(0, 20, 0, 20), l(0, 10, 0, 13), r0.yyyy, l(0, 0, 0, 0) + imad r1.xy, r1.xxxx, l(2, 16, 0, 0), r1.ywyy + bfi r0.xy, l(2, 2, 0, 0), l(8, 11, 0, 0), r0.xxxx, r1.xyxx + bfi r1.x, l(1), l(4), r3.z, l(0) + ubfe r1.y, l(3), l(6), r0.x + and r1.w, r0.z, l(6) + bfi r0.z, l(1), l(8), r0.z, l(0) + imad r0.z, r1.y, l(32), r0.z + imad r0.z, r1.w, l(4), r0.z + bfi r0.xy, l(6, 6, 0, 0), l(0, 3, 0, 0), r1.xxxx, r0.xyxx + bfi r0.y, l(9), l(3), r0.z, r0.y + bfi r0.x, l(6), l(0), r0.x, r0.y +else + ishr r2.xyzw, r3.xyzw, l(5, 5, 2, 3) + ushr r0.y, r0.w, l(5) + imad r0.y, r2.y, r0.y, r2.x + ishl r0.zw, r3.zzzz, l(0, 0, 5, 7) + and r0.zw, r0.zzzw, l(0, 0, 448, 2048) + bfi r1.x, l(23), l(9), r0.y, r0.z + bfi r1.y, l(1), l(4), r3.z, l(0) + iadd r1.x, r1.x, r1.y + ishl r2.xy, r0.zzzz, l(3, 2, 0, 0) + bfi r0.yz, l(0, 23, 23, 0), l(0, 12, 11, 0), r0.yyyy, r2.xxyx + imad r0.yz, r1.yyyy, l(0, 8, 4, 0), r0.yyzy + bfi r0.y, l(12), l(0), r0.w, r0.y + and r0.z, r0.z, l(1792) + iadd r0.y, r0.y, r0.z + and r0.z, r2.z, l(2) + iadd r0.z, r2.w, r0.z + bfi r0.z, l(2), l(6), r0.z, l(0) + iadd r0.y, r0.y, r0.z + bfi r0.x, l(6), l(0), r1.x, r0.y +endif +iadd r0.x, r0.x, CB0[0][1].x +ushr r0.x, r0.x, l(4) +ieq r0.yzw, r1.zzzz, l(0, 1, 2, 3) +or r0.yz, r0.zzwz, r0.yyzy +if_nz r0.y + ishl r1.xyzw, r5.xyzw, l(8, 8, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r2.xyzw, r5.xyzw, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r5.xyzw, r1.xyzw, r2.xyzw +endif +if_nz r0.z + ushr r1.xyzw, r5.xyzw, l(16, 16, 16, 16) + bfi r5.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r5.xyzw, r1.xyzw +endif +store_uav_typed U0[0].xyzw, r0.xxxx, r5.xyzw +iadd r0.x, r0.x, l(2) +if_nz r0.y + ishl r1.xyzw, r6.xyzw, l(8, 8, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r2.xyzw, r6.xyzw, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r6.xyzw, r1.xyzw, r2.xyzw +endif +if_nz r0.z + ushr r1.xyzw, r6.xyzw, l(16, 16, 16, 16) + bfi r6.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r6.xyzw, r1.xyzw +endif +store_uav_typed U0[0].xyzw, r0.xxxx, r6.xyzw +ret +// Approximately 174 instruction slots used +#endif + +const BYTE resolve_fast_32bpp_4xmsaa_cs[] = { + 68, 88, 66, 67, 132, 174, 232, 97, 226, 183, 91, 228, 46, 127, 168, 138, 25, 76, 175, + 117, 1, 0, 0, 0, 196, 25, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 208, 2, + 0, 0, 224, 2, 0, 0, 240, 2, 0, 0, 40, 25, 0, 0, 82, 68, 69, 70, 148, + 2, 0, 0, 1, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 105, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 101, 100, 114, 97, 109, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 213, 0, 0, 0, 5, 0, 0, 0, 252, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 196, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 4, 2, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 31, 2, 0, 0, 8, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 52, 2, 0, 0, 12, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 84, 2, 0, + 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, + 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 101, 100, 114, 97, 109, 95, 105, 110, 102, + 111, 0, 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 218, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 99, 111, + 111, 114, 100, 105, 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 105, 110, 102, 111, 0, 120, 101, 95, + 114, 101, 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 99, 111, 111, 114, 100, 105, + 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 95, 98, 97, 115, 101, 0, 77, 105, 99, 114, 111, 115, 111, + 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, + 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, + 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 48, 22, 0, 0, + 81, 0, 5, 0, 140, 5, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, + 0, 95, 0, 0, 2, 50, 0, 2, 0, 104, 0, 0, 2, 9, 0, 0, 0, 155, 0, + 0, 4, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 138, 0, 0, 11, 18, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 64, 0, 0, + 5, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 12, 242, 0, 16, 0, 1, 0, 0, 0, 6, 138, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 0, + 16, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 9, 34, 0, 16, 0, + 0, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 1, 85, 0, 0, 12, 242, 0, 16, 0, 2, 0, + 0, 0, 214, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, + 80, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 2, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 62, 0, + 0, 1, 21, 0, 0, 1, 54, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 26, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 34, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 20, 82, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 140, 0, 0, 13, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, + 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 20, + 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 230, 11, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 138, 0, 0, 17, 82, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 13, 0, + 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 6, 131, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 9, 146, 0, 16, 0, + 4, 0, 0, 0, 6, 0, 2, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 98, 0, 16, 0, 4, 0, + 0, 0, 86, 5, 2, 0, 30, 0, 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 6, + 2, 16, 0, 0, 0, 0, 0, 246, 14, 16, 0, 4, 0, 0, 0, 80, 0, 0, 7, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 2, 0, 0, 0, 54, 0, + 0, 5, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 18, + 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, + 0, 2, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 5, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 34, 0, 16, 0, 5, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, + 41, 0, 0, 10, 82, 0, 16, 0, 0, 0, 0, 0, 6, 2, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 5, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 140, 0, 0, 17, 82, 0, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 1, 16, 0, 5, 0, 0, 0, 6, 2, 16, 0, 0, + 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, 0, 5, 0, 0, 0, 0, 208, 0, 0, + 134, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 80, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, + 13, 82, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 128, 65, 0, 0, 0, 5, 0, + 0, 0, 2, 64, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 6, 2, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, + 1, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 40, 0, 0, 0, 55, 0, 0, 9, 34, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 216, + 255, 255, 255, 1, 64, 0, 0, 40, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 21, 0, 0, 1, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 80, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 5, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 78, 0, 0, 8, 0, 208, 0, 0, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 40, 0, 85, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 39, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 50, 0, 16, 0, 5, 0, 0, + 0, 6, 0, 16, 0, 0, 0, 0, 0, 134, 125, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 45, 0, 0, 8, 194, 0, 16, 0, + 5, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 214, 120, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 6, 0, + 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 50, 0, 16, 0, 6, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 134, 125, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 45, 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, 0, 86, 5, 16, 0, 1, 0, + 0, 0, 214, 120, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 45, + 0, 0, 8, 50, 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, + 214, 120, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 45, 0, 0, 8, 194, 0, 16, 0, 5, 0, 0, 0, 166, 10, 16, 0, 0, + 0, 0, 0, 134, 125, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, + 82, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 45, 0, + 0, 8, 50, 0, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 214, + 120, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 194, 0, 16, 0, + 6, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 134, 125, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, + 0, 0, 138, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 0, 3, 10, 0, 16, 0, 0, 0, 0, + 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 140, 0, 0, 17, 242, 0, 16, 0, 7, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 138, 0, 0, 15, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 140, 0, 0, 17, 242, + 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, + 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, + 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, + 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, + 252, 15, 192, 0, 252, 15, 192, 0, 252, 15, 192, 0, 252, 15, 192, 140, 0, 0, 17, + 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, + 0, 2, 64, 0, 0, 0, 252, 15, 192, 0, 252, 15, 192, 0, 252, 15, 192, 0, 252, + 15, 192, 140, 0, 0, 17, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 10, + 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 20, 0, 0, 0, 20, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, + 16, 0, 8, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 2, 0, 0, 1, 23, + 0, 0, 1, 21, 0, 0, 1, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 31, 0, 4, + 3, 58, 0, 16, 0, 1, 0, 0, 0, 138, 0, 0, 11, 18, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 5, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 230, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, + 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 254, 7, 0, 0, 35, 0, 0, 9, + 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 7, 18, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, + 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, + 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 96, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, + 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 34, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 140, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 20, 162, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 13, 0, + 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, + 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 5, 16, 0, 1, 0, + 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 2, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 8, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, + 0, 0, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 18, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 138, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, + 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 42, 0, + 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, + 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, + 166, 10, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, + 0, 0, 166, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 192, 1, 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 140, 0, + 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 50, 0, + 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, + 98, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 23, 0, 0, + 0, 23, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 12, 0, + 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 6, + 1, 16, 0, 2, 0, 0, 0, 35, 0, 0, 12, 98, 0, 16, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 140, 0, + 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 140, 0, + 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 32, 0, 0, 10, + 226, 0, 16, 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 0, + 0, 7, 98, 0, 16, 0, 0, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 86, + 6, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, + 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, + 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 1, + 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 0, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 21, 0, 0, + 1, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, + 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 62, 0, 0, 1, 83, + 84, 65, 84, 148, 0, 0, 0, 174, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, + 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_32bpp_4xmsaa_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_32bpp_4xmsaa_scaled_cs.h new file mode 100644 index 0000000..b6d5a36 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_32bpp_4xmsaa_scaled_cs.h @@ -0,0 +1,710 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_resolve_edram_info; // Offset: 0 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 4 Size: 4 +// uint xe_resolve_dest_info; // Offset: 8 Size: 4 +// uint xe_resolve_dest_coordinate_info;// Offset: 12 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram texture uint4 buf T0 t0 1 +// xe_resolve_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 9 +dcl_thread_group 8, 8, 1 +and r0.xyzw, CB0[0][0].xxxz, l(1023, 4096, 0x20000000, 7) +if_nz r0.z + ubfe r1.xy, l(2, 2, 0, 0), l(17, 20, 0, 0), CB0[0][0].yyyy +else + mov r1.xy, l(0,0,0,0) +endif +ubfe r2.xyz, l(3, 3, 11, 0), l(16, 19, 5, 0), CB0[0][0].yyyy +imul null, r0.z, r2.x, r2.z +and r1.zw, CB0[0][0].zzzz, l(0, 0, 8, 0x01000000) +ushr r3.xyzw, CB0[0][0].ywww, l(4, 10, 20, 24) +uge r0.z, vThreadID.x, r0.z +if_nz r0.z + ret +endif +mov r4.x, CB0[0][0].y +mov r4.y, r3.x +bfi r2.zw, l(0, 0, 4, 1), l(0, 0, 3, 3), r4.xxxy, l(0, 0, 0, 0) +bfi r0.z, l(10), l(5), CB0[0][0].w, l(0) +bfi r3.xz, l(4, 0, 4, 0), l(3, 0, 3, 0), r3.zzwz, l(0, 0, 0, 0) +ubfe r4.xy, l(11, 3, 0, 0), l(13, 28, 0, 0), CB0[0][0].xwxx +ishl r5.x, vThreadID.x, l(3) +umax r5.y, r1.y, vThreadID.y +imad r2.zw, r2.zzzw, r2.xxxy, r5.xxxy +uge r1.y, l(3), r4.y +if_nz r1.y + mov r6.y, r4.y +else + ieq r1.y, r4.y, l(5) + if_nz r1.y + mov r6.y, l(2) + else + mov r6.y, l(0) + endif +endif +ishl r2.zw, r2.zzzw, l(0, 0, 1, 1) +ushr r6.x, r6.y, l(1) +bfi r2.zw, l(0, 0, 4, 1), l(0, 0, 0, 0), r6.xxxy, r2.zzzw +imul null, r4.zw, r2.xxxy, l(0, 0, 80, 16) +udiv r5.yw, null, r2.zzzw, r4.zzzw +imad r0.x, r5.w, r0.x, r5.y +iadd r0.x, r0.x, r4.x +imad r2.zw, -r5.yyyw, r4.zzzw, r2.zzzw +if_nz r0.y + ushr r0.y, r4.z, l(1) + uge r1.y, r2.z, r0.y + ineg r3.w, r0.y + movc r0.y, r1.y, r3.w, r0.y + iadd r2.z, r0.y, r2.z +endif +imul null, r0.y, r4.w, r4.z +imad r1.y, r2.w, r4.z, r2.z +imad r0.x, r0.x, r0.y, r1.y +ishl r0.y, r0.y, l(11) +udiv null, r0.x, r0.x, r0.y +ushr r0.x, r0.x, l(2) +ine r2.zw, r4.yyyy, l(0, 0, 2, 3) +and r0.y, r2.w, r2.z +if_nz r0.y + ld r4.yz, r0.xxxx, T0[0].yxzw + iadd r0.y, r0.x, l(1) + ld r2.zw, r0.yyyy, T0[0].ywxz + iadd r5.yw, r0.xxxx, l(0, 2, 0, 3) + ld r6.xy, r5.yyyy, T0[0].xzyw + ld r6.zw, r5.wwww, T0[0].ywxz + mov r4.xw, r2.zzzw +else + ld r5.yw, r0.xxxx, T0[0].xyzw + iadd r0.y, r0.x, l(1) + ld r4.xw, r0.yyyy, T0[0].yxzw + iadd r0.xy, r0.xxxx, l(2, 3, 0, 0) + ld r6.xy, r0.xxxx, T0[0].ywxz + ld r6.zw, r0.yyyy, T0[0].xzyw + mov r4.yz, r5.yywy +endif +ieq r0.x, r5.x, l(0) +ine r0.y, r1.x, l(0) +and r0.x, r0.y, r0.x +if_nz r0.x + uge r0.x, r1.x, l(2) + if_nz r0.x + uge r0.x, r1.x, l(3) + if_nz r0.x + mov r4.x, r4.w + endif + mov r4.xz, r4.xxxx + endif + mov r4.xyz, r4.xzzx +endif +if_nz r1.w + ubfe r0.x, l(4), l(24), CB0[0][0].x + switch r0.x + case l(0) + case l(1) + and r7.xyzw, r4.yzxw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + bfi r7.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r4.yzxw, r7.xyzw + ubfe r8.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r4.yzxw + iadd r4.xyzw, r7.zxyw, r8.zxyw + and r7.xyzw, r6.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + bfi r7.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r6.xyzw, r7.xyzw + ubfe r8.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r6.xyzw + iadd r6.xyzw, r7.xyzw, r8.xyzw + break + case l(2) + case l(3) + case l(10) + case l(12) + and r7.xyzw, r4.yzxw, l(0xc00ffc00, 0xc00ffc00, 0xc00ffc00, 0xc00ffc00) + bfi r7.xyzw, l(10, 10, 10, 10), l(20, 20, 20, 20), r4.yzxw, r7.xyzw + ubfe r8.xyzw, l(10, 10, 10, 10), l(20, 20, 20, 20), r4.yzxw + iadd r4.xyzw, r7.zxyw, r8.zxyw + and r7.xyzw, r6.xyzw, l(0xc00ffc00, 0xc00ffc00, 0xc00ffc00, 0xc00ffc00) + bfi r7.xyzw, l(10, 10, 10, 10), l(20, 20, 20, 20), r6.xyzw, r7.xyzw + ubfe r8.xyzw, l(10, 10, 10, 10), l(20, 20, 20, 20), r6.xyzw + iadd r6.xyzw, r7.xyzw, r8.xyzw + break + default + break + endswitch +endif +mov r5.z, vThreadID.y +imad r7.yz, r3.xxzx, r2.xxyx, r5.xxzx +ushr r7.x, r7.y, l(2) +udiv r0.xy, null, r7.xzxx, r2.xyxx +ishl r1.x, r0.x, l(2) +if_nz r1.z + ubfe r1.y, l(3), l(4), CB0[0][0].z + ishl r1.z, r3.y, l(5) + ishr r2.zw, r0.yyyy, l(0, 0, 4, 3) + ishr r1.w, r1.y, l(2) + ushr r1.z, r1.z, l(4) + and r1.z, r1.z, l(2046) + imad r1.z, r1.w, r1.z, r2.z + ushr r2.z, r0.z, l(5) + ibfe r3.xy, l(27, 29, 0, 0), l(3, 1, 0, 0), r0.xxxx + imad r1.z, r1.z, r2.z, r3.x + ishl r2.z, r0.y, l(10) + and r2.z, r2.z, l(6144) + bfi r2.z, l(3), l(8), r1.x, r2.z + ishr r2.z, r2.z, l(6) + iadd r1.w, r1.w, r2.w + bfi r2.w, l(1), l(1), r1.w, l(0) + iadd r2.w, r2.w, r3.y + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r1.w, l(1), l(0), r1.w, r2.w + bfi r3.xy, l(20, 20, 0, 0), l(10, 13, 0, 0), r1.zzzz, l(0, 0, 0, 0) + imad r2.zw, r2.zzzz, l(0, 0, 2, 16), r3.xxxy + bfi r1.yz, l(0, 2, 2, 0), l(0, 8, 11, 0), r1.yyyy, r2.zzwz + bfi r2.z, l(1), l(4), r0.y, l(0) + ubfe r2.w, l(3), l(6), r1.y + and r3.x, r1.w, l(6) + bfi r1.w, l(1), l(8), r1.w, l(0) + imad r1.w, r2.w, l(32), r1.w + imad r1.w, r3.x, l(4), r1.w + bfi r1.yz, l(0, 5, 5, 0), l(0, 0, 3, 0), r2.zzzz, r1.yyzy + bfi r1.z, l(9), l(3), r1.w, r1.z + bfi r1.y, l(6), l(0), r1.y, r1.z +else + ibfe r1.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), r0.xxxx + ishr r2.zw, r0.yyyy, l(0, 0, 5, 2) + ushr r0.z, r0.z, l(5) + imad r0.z, r2.z, r0.z, r1.z + ishl r3.xy, r0.yyyy, l(5, 7, 0, 0) + and r3.xy, r3.xyxx, l(448, 2048, 0, 0) + bfi r1.z, l(3), l(3), r1.x, r3.x + bfi r1.z, l(23), l(9), r0.z, r1.z + bfi r2.z, l(1), l(4), r0.y, l(0) + iadd r1.z, r1.z, r2.z + ishl r3.xz, r3.xxxx, l(3, 0, 2, 0) + bfi r3.xz, l(3, 0, 3, 0), l(6, 0, 5, 0), r1.xxxx, r3.xxzx + bfi r3.xz, l(23, 0, 23, 0), l(12, 0, 11, 0), r0.zzzz, r3.xxzx + imad r3.xz, r2.zzzz, l(8, 0, 4, 0), r3.xxzx + bfi r0.z, l(12), l(0), r3.y, r3.x + and r1.x, r3.z, l(1792) + iadd r0.z, r0.z, r1.x + and r1.x, r2.w, l(2) + iadd r1.x, r1.w, r1.x + bfi r1.x, l(2), l(6), r1.x, l(0) + iadd r0.z, r0.z, r1.x + bfi r1.y, l(6), l(0), r1.z, r0.z +endif +imad r0.xy, -r0.xyxx, r2.xyxx, r7.xzxx +imul null, r0.z, r2.y, r2.x +imad r0.x, r0.x, r2.y, r0.y +ishl r0.x, r0.x, l(4) +imad r0.x, r1.y, r0.z, r0.x +ushr r0.x, r0.x, l(4) +ieq r0.yzw, r0.wwww, l(0, 1, 2, 3) +or r0.yz, r0.zzwz, r0.yyzy +if_nz r0.y + ishl r1.xyzw, r4.yzxw, l(8, 8, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r3.xyzw, r4.yzxw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r4.xyzw, r1.zxyw, r3.zxyw +endif +if_nz r0.z + ushr r1.xyzw, r4.yzxw, l(16, 16, 16, 16) + bfi r4.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r4.xyzw, r1.zxyw +endif +store_uav_typed U0[0].xyzw, r0.xxxx, r4.yzxw +ult r0.w, l(1), r2.x +if_nz r0.w + ushr r0.w, r5.x, l(2) + udiv r1.x, null, r0.w, r2.x + imad r0.w, -r1.x, r2.x, r0.w + iadd r1.x, r0.w, l(1) + ieq r1.x, r2.x, r1.x + if_nz r1.x + ishl r1.x, r2.x, l(5) + ishl r0.w, r0.w, l(4) + iadd r0.w, -r0.w, r1.x + else + mov r0.w, l(16) + endif +else + mov r0.w, l(32) +endif +imul null, r0.w, r2.y, r0.w +ushr r0.w, r0.w, l(4) +iadd r0.x, r0.w, r0.x +if_nz r0.y + ishl r1.xyzw, r6.xyzw, l(8, 8, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r2.xyzw, r6.xyzw, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r6.xyzw, r1.xyzw, r2.xyzw +endif +if_nz r0.z + ushr r1.xyzw, r6.xyzw, l(16, 16, 16, 16) + bfi r6.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r6.xyzw, r1.xyzw +endif +store_uav_typed U0[0].xyzw, r0.xxxx, r6.xyzw +ret +// Approximately 233 instruction slots used +#endif + +const BYTE resolve_fast_32bpp_4xmsaa_scaled_cs[] = { + 68, 88, 66, 67, 162, 209, 122, 185, 76, 164, 251, 46, 181, 104, 113, 8, 123, 104, 64, + 162, 1, 0, 0, 0, 140, 31, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 144, 2, + 0, 0, 160, 2, 0, 0, 176, 2, 0, 0, 240, 30, 0, 0, 82, 68, 69, 70, 84, + 2, 0, 0, 1, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 44, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 101, 100, 114, 97, 109, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 213, 0, 0, 0, 4, 0, 0, 0, 252, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 156, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 220, 1, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 247, 1, 0, 0, 8, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 12, 2, 0, 0, 12, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, + 114, 101, 115, 111, 108, 118, 101, 95, 101, 100, 114, 97, 109, 95, 105, 110, 102, 111, 0, + 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 178, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 99, 111, 111, 114, + 100, 105, 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 100, 101, 115, 116, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 99, 111, 111, 114, 100, 105, 110, 97, + 116, 101, 95, 105, 110, 102, 111, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 83, 72, 69, 88, 56, 28, 0, 0, 81, 0, 5, 0, 14, 7, 0, + 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 88, 8, 0, 7, 70, + 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, + 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 95, 0, 0, 2, 50, 0, + 2, 0, 104, 0, 0, 2, 9, 0, 0, 0, 155, 0, 0, 4, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, 0, + 6, 136, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 255, 3, 0, 0, 0, 16, 0, 0, 0, 0, 0, 32, 7, 0, 0, 0, 31, 0, + 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 17, 50, 0, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 17, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 86, 133, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 18, 0, 0, 1, 54, 0, 0, 8, 50, 0, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 1, 138, 0, 0, 17, 114, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 86, + 133, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, + 0, 208, 0, 0, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 12, 194, 0, 16, 0, 1, 0, + 0, 0, 166, 138, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, + 85, 0, 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, 214, 143, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 10, 0, + 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 80, 0, 0, 6, 66, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 2, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 54, 0, 0, + 7, 18, 0, 16, 0, 4, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 4, 0, 0, 0, 10, + 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 20, 194, 0, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 13, 66, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, + 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 20, 82, 0, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 166, 11, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 17, 50, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 13, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 198, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 2, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 83, 0, 0, 6, 34, 0, 16, 0, 5, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 9, 194, 0, 16, + 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 2, 0, + 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, + 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, + 0, 6, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 18, 0, 0, 1, 32, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, + 64, 0, 0, 5, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 18, 0, 0, 1, 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 41, 0, 0, 10, 194, + 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 6, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 38, 0, + 0, 11, 0, 208, 0, 0, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, + 16, 0, 0, 0, 78, 0, 0, 8, 162, 0, 16, 0, 5, 0, 0, 0, 0, 208, 0, + 0, 166, 14, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 35, 0, + 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 4, 0, 0, 0, 35, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 86, 13, + 16, 128, 65, 0, 0, 0, 5, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 166, + 14, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, + 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 40, + 0, 0, 5, 130, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 38, 0, 0, 8, 0, 208, 0, 0, + 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 4, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, + 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 78, 0, 0, 8, 0, 208, 0, 0, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 39, 0, 0, 10, 194, 0, + 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 7, + 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, + 0, 8, 98, 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 22, + 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 45, 0, 0, 8, 194, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, 0, + 0, 0, 214, 120, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 162, + 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 45, 0, 0, + 8, 50, 0, 16, 0, 6, 0, 0, 0, 86, 5, 16, 0, 5, 0, 0, 0, 134, 125, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 194, 0, 16, 0, 6, + 0, 0, 0, 246, 15, 16, 0, 5, 0, 0, 0, 214, 120, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 146, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, + 0, 2, 0, 0, 0, 18, 0, 0, 1, 45, 0, 0, 8, 162, 0, 16, 0, 5, 0, + 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 45, 0, 0, 8, 146, 0, 16, + 0, 4, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 22, 126, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 6, + 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 50, 0, 16, 0, 6, 0, 0, + 0, 6, 0, 16, 0, 0, 0, 0, 0, 214, 120, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, 0, 86, 5, 16, 0, 0, + 0, 0, 0, 134, 125, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 98, 0, 16, 0, 4, 0, 0, 0, 86, 7, 16, 0, 5, 0, 0, 0, 21, 0, 0, + 1, 32, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 39, 0, 0, 7, 34, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, + 0, 0, 80, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, + 0, 0, 0, 0, 80, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 31, 0, 4, 3, 10, 0, + 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 4, 0, 0, 0, 58, + 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 54, 0, 0, 5, 82, 0, 16, 0, + 4, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 54, 0, 0, + 5, 114, 0, 16, 0, 4, 0, 0, 0, 134, 2, 16, 0, 4, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 138, 0, 0, 11, 18, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, + 24, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 76, 0, 0, 3, 10, 0, 16, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, + 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 150, 12, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 140, 0, 0, 17, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 150, 12, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 150, 12, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, + 242, 0, 16, 0, 4, 0, 0, 0, 38, 13, 16, 0, 7, 0, 0, 0, 38, 13, 16, + 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 140, 0, 0, 17, 242, 0, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 138, + 0, 0, 15, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 6, 0, + 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, + 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, + 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, + 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 6, 0, 0, 3, 1, 64, + 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 150, + 12, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 252, 15, 192, 0, 252, 15, 192, + 0, 252, 15, 192, 0, 252, 15, 192, 140, 0, 0, 17, 242, 0, 16, 0, 7, 0, 0, + 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, + 0, 0, 0, 150, 12, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 138, 0, 0, 15, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 150, 12, 16, 0, 4, + 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 38, 13, 16, 0, + 7, 0, 0, 0, 38, 13, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 252, + 15, 192, 0, 252, 15, 192, 0, 252, 15, 192, 0, 252, 15, 192, 140, 0, 0, 17, 242, + 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, + 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, + 0, 20, 0, 0, 0, 20, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, + 0, 0, 1, 10, 0, 0, 1, 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, + 54, 0, 0, 4, 66, 0, 16, 0, 5, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, + 9, 98, 0, 16, 0, 7, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 6, 1, + 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 5, 0, 0, 0, 85, 0, 0, 7, 18, + 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 78, 0, 0, 8, 50, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, + 0, 134, 0, 16, 0, 7, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 41, 0, + 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, + 138, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 10, + 194, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 42, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 254, 7, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 139, 0, 0, 15, 50, 0, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, + 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 10, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 24, 0, 0, 140, 0, 0, 11, 66, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 8, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, + 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, + 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, 0, + 2, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 6, 4, 16, 0, 3, 0, + 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, + 0, 1, 0, 0, 0, 166, 11, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 138, 0, 0, 9, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 0, + 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 32, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 139, 0, + 0, 15, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 2, + 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, + 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 192, 1, + 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 3, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 23, 0, + 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, + 0, 0, 0, 41, 0, 0, 10, 82, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 140, 0, 0, 17, 82, 0, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 140, 0, 0, + 17, 82, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 0, 0, + 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 0, + 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, + 6, 2, 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 82, 0, 16, 0, 3, 0, 0, + 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 140, + 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, + 0, 3, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 66, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 140, + 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 21, 0, 0, 1, 35, 0, 0, 10, 50, 0, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, + 0, 0, 0, 134, 0, 16, 0, 7, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 32, 0, 0, 10, 226, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, + 0, 0, 60, 0, 0, 7, 98, 0, 16, 0, 0, 0, 0, 0, 166, 11, 16, 0, 0, + 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, + 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 150, 12, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, + 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 150, 12, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 4, 0, 0, 0, 38, 13, 16, 0, 1, 0, 0, 0, 38, 13, 16, 0, 3, 0, + 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 150, 12, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 140, 0, 0, 17, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 38, 13, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, + 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, + 0, 0, 150, 12, 16, 0, 4, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 78, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 10, + 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, + 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 8, 130, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 54, 0, 0, 5, + 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 21, 0, 0, + 1, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 130, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, + 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, + 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, + 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, + 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, + 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, + 84, 148, 0, 0, 0, 233, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 45, 0, 0, 0, 12, 0, 0, 0, 18, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 14, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_64bpp_1x2xmsaa_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_64bpp_1x2xmsaa_cs.h new file mode 100644 index 0000000..2d8e4f3 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_64bpp_1x2xmsaa_cs.h @@ -0,0 +1,512 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_resolve_edram_info; // Offset: 0 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 4 Size: 4 +// uint xe_resolve_dest_info; // Offset: 8 Size: 4 +// uint xe_resolve_dest_coordinate_info;// Offset: 12 Size: 4 +// uint xe_resolve_dest_base; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram texture uint4 buf T0 t0 1 +// xe_resolve_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][2], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 6 +dcl_thread_group 8, 8, 1 +and r0.xyzw, CB0[0][0].zxzz, l(7, 1023, 8, 0x01000000) +ushr r1.xyz, CB0[0][0].yywy, l(4, 5, 10, 0) +ushr r2.xyzw, CB0[0][0].wwww, l(20, 24, 24, 20) +ishl r3.xw, vThreadID.xxxx, l(2, 0, 0, 2) +bfi r1.y, l(11), l(3), r1.y, l(0) +uge r1.y, r3.w, r1.y +if_nz r1.y + ret +endif +mov r1.w, CB0[0][0].y +bfi r1.xy, l(4, 1, 0, 0), l(3, 3, 0, 0), r1.wxww, l(0, 0, 0, 0) +bfi r1.w, l(10), l(5), CB0[0][0].w, l(0) +bfi r2.xyzw, l(4, 4, 4, 4), l(3, 3, 3, 3), r2.xyzw, l(0, 0, 0, 0) +ubfe r4.xyz, l(2, 3, 11, 0), l(10, 28, 13, 0), CB0[0][0].xwxx +mov r3.yz, vThreadID.yyyy +iadd r1.xy, r1.xyxx, r3.wzww +uge r4.w, l(3), r4.y +if_z r4.w + ieq r4.w, r4.y, l(5) + if_nz r4.w + mov r4.y, l(2) + else + mov r4.y, l(0) + endif +endif +uge r5.xy, r4.xxxx, l(2, 1, 0, 0) +and r5.xy, r5.xyxx, l(1, 1, 0, 0) +ishl r1.xy, r1.xyxx, r5.xyxx +ushr r4.x, r4.y, l(1) +and r4.xy, r4.xyxx, l(1, 1, 0, 0) +iadd r1.xy, r1.xyxx, r4.xyxx +udiv r4.xy, null, r1.xyxx, l(40, 16, 0, 0) +imad r0.y, r4.y, r0.y, r4.x +iadd r0.y, r0.y, r4.z +imad r1.xy, -r4.xyxx, l(40, 16, 0, 0), r1.xyxx +imad r1.x, r1.y, l(40), r1.x +ishl r1.x, r1.x, l(1) +imad r0.y, r0.y, l(1280), r1.x +udiv null, r0.y, r0.y, l(0x00280000) +ushr r0.y, r0.y, l(2) +ld r4.xyzw, r0.yyyy, T0[0].xyzw +iadd r0.y, r0.y, l(1) +ld r5.xyzw, r0.yyyy, T0[0].xyzw +if_nz r0.w + ubfe r0.y, l(4), l(24), CB0[0][0].x + ieq r0.yw, r0.yyyy, l(0, 5, 0, 7) + or r0.y, r0.w, r0.y + if_nz r0.y + bfi r4.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r4.yxwz, r4.xyzw + bfi r5.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r5.yxwz, r5.xyzw + endif +endif +iadd r2.xyzw, r2.xyzw, r3.xyzw +if_nz r0.z + ubfe r0.y, l(3), l(4), CB0[0][0].z + ishl r0.z, r1.z, l(5) + ishr r3.xyzw, r2.zwzw, l(4, 5, 3, 3) + ishr r0.w, r0.y, l(2) + ushr r0.z, r0.z, l(4) + and r0.z, r0.z, l(2046) + imad r0.z, r0.w, r0.z, r3.x + ushr r1.x, r1.w, l(5) + imad r0.z, r0.z, r1.x, r3.y + ishl r1.x, r2.z, l(11) + and r1.x, r1.x, l(0x00003000) + bfi r1.x, l(3), l(9), r2.w, r1.x + ishr r1.x, r1.x, l(6) + iadd r0.w, r0.w, r3.z + bfi r1.y, l(1), l(1), r0.w, l(0) + iadd r1.y, r1.y, r3.w + bfi r1.y, l(2), l(1), r1.y, l(0) + bfi r0.w, l(1), l(0), r0.w, r1.y + bfi r1.yz, l(0, 19, 19, 0), l(0, 11, 14, 0), r0.zzzz, l(0, 0, 0, 0) + imad r1.xy, r1.xxxx, l(2, 16, 0, 0), r1.yzyy + bfi r0.yz, l(0, 2, 2, 0), l(0, 9, 12, 0), r0.yyyy, r1.xxyx + bfi r1.x, l(1), l(4), r2.z, l(0) + ubfe r1.y, l(3), l(6), r0.y + and r1.z, r0.w, l(6) + bfi r0.w, l(1), l(8), r0.w, l(0) + imad r0.w, r1.y, l(32), r0.w + imad r0.w, r1.z, l(4), r0.w + bfi r0.yz, l(0, 6, 6, 0), l(0, 0, 3, 0), r1.xxxx, r0.yyzy + bfi r0.z, l(9), l(3), r0.w, r0.z + bfi r0.y, l(6), l(0), r0.y, r0.z +else + ishr r3.xyzw, r2.xyzw, l(5, 5, 2, 3) + ushr r0.z, r1.w, l(5) + imad r0.z, r3.y, r0.z, r3.x + ishl r1.xy, r2.zzzz, l(6, 7, 0, 0) + and r1.xy, r1.xyxx, l(896, 2048, 0, 0) + bfi r0.w, l(3), l(4), r2.w, r1.x + bfi r0.w, l(22), l(10), r0.z, r0.w + bfi r1.z, l(1), l(4), r2.z, l(0) + iadd r0.w, r0.w, r1.z + ishl r1.xw, r1.xxxx, l(3, 0, 0, 2) + bfi r1.xw, l(3, 0, 0, 3), l(7, 0, 0, 6), r2.wwww, r1.xxxw + bfi r1.xw, l(22, 0, 0, 22), l(13, 0, 0, 12), r0.zzzz, r1.xxxw + imad r1.xz, r1.zzzz, l(8, 0, 4, 0), r1.xxwx + bfi r0.z, l(12), l(0), r1.y, r1.x + and r1.x, r1.z, l(1792) + iadd r0.z, r0.z, r1.x + and r1.x, r3.z, l(2) + iadd r1.x, r3.w, r1.x + bfi r1.x, l(2), l(6), r1.x, l(0) + iadd r0.z, r0.z, r1.x + bfi r0.y, l(6), l(0), r0.w, r0.z +endif +iadd r0.y, r0.y, CB0[0][1].x +ushr r0.y, r0.y, l(4) +ieq r0.z, r0.x, l(4) +if_nz r0.z + mov r4.xyzw, r4.yxwz + mov r0.w, l(2) +else + mov r0.w, r0.x +endif +ieq r1.xyz, r0.wwww, l(1, 2, 3, 0) +or r1.xy, r1.yzyy, r1.xyxx +if_nz r1.x + ishl r2.xyzw, r4.xyzw, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r3.xyzw, r4.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r4.xyzw, r2.xyzw, r3.xyzw +endif +if_nz r1.y + ushr r1.xyzw, r4.xyzw, l(16, 16, 16, 16) + bfi r4.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r4.xyzw, r1.xyzw +endif +store_uav_typed U0[0].xyzw, r0.yyyy, r4.xyzw +iadd r0.y, r0.y, l(2) +if_nz r0.z + mov r5.xyzw, r5.yxwz + mov r0.x, l(2) +endif +ieq r0.xzw, r0.xxxx, l(1, 0, 2, 3) +or r0.xz, r0.zzwz, r0.xxzx +if_nz r0.x + ishl r1.xyzw, r5.xyzw, l(8, 8, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r2.xyzw, r5.xyzw, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r5.xyzw, r1.xyzw, r2.xyzw +endif +if_nz r0.z + ushr r1.xyzw, r5.xyzw, l(16, 16, 16, 16) + bfi r5.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r5.xyzw, r1.xyzw +endif +store_uav_typed U0[0].xyzw, r0.yyyy, r5.xyzw +ret +// Approximately 150 instruction slots used +#endif + +const BYTE resolve_fast_64bpp_1x2xmsaa_cs[] = { + 68, 88, 66, 67, 72, 24, 139, 103, 64, 0, 156, 217, 10, 65, 226, 91, 157, 5, 131, + 37, 1, 0, 0, 0, 0, 23, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 208, 2, + 0, 0, 224, 2, 0, 0, 240, 2, 0, 0, 100, 22, 0, 0, 82, 68, 69, 70, 148, + 2, 0, 0, 1, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 105, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 101, 100, 114, 97, 109, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 213, 0, 0, 0, 5, 0, 0, 0, 252, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 196, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 4, 2, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 31, 2, 0, 0, 8, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 52, 2, 0, 0, 12, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 84, 2, 0, + 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, + 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 101, 100, 114, 97, 109, 95, 105, 110, 102, + 111, 0, 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 218, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 99, 111, + 111, 114, 100, 105, 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 105, 110, 102, 111, 0, 120, 101, 95, + 114, 101, 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 99, 111, 111, 114, 100, 105, + 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 95, 98, 97, 115, 101, 0, 77, 105, 99, 114, 111, 115, 111, + 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, + 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, + 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 108, 19, 0, 0, + 81, 0, 5, 0, 219, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, + 0, 95, 0, 0, 2, 50, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, 0, + 0, 4, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, 242, + 0, 16, 0, 0, 0, 0, 0, 38, 138, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 255, 3, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 1, 85, 0, 0, 12, 114, 0, 16, 0, 1, 0, 0, 0, 86, 135, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, + 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, + 242, 0, 16, 0, 2, 0, 0, 0, 246, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 24, 0, + 0, 0, 20, 0, 0, 0, 41, 0, 0, 9, 146, 0, 16, 0, 3, 0, 0, 0, 6, + 0, 2, 0, 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 11, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, + 1, 54, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 13, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 64, 0, 0, + 5, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 17, 114, 0, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 11, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 28, 0, 0, 0, + 13, 0, 0, 0, 0, 0, 0, 0, 198, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 4, 98, 0, 16, 0, 3, 0, 0, 0, 86, 5, + 2, 0, 30, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, + 0, 0, 0, 182, 15, 16, 0, 3, 0, 0, 0, 80, 0, 0, 7, 130, 0, 16, 0, + 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, + 0, 31, 0, 0, 3, 58, 0, 16, 0, 4, 0, 0, 0, 32, 0, 0, 7, 130, 0, + 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, + 34, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 18, 0, 0, + 1, 54, 0, 0, 5, 34, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 80, 0, 0, 10, 50, 0, 16, 0, 5, + 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, + 0, 5, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 50, + 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, + 5, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, + 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 50, 0, + 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, 0, 4, 0, 0, 0, 0, 208, + 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 40, 0, 0, 0, 16, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 35, + 0, 0, 13, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 128, 65, 0, 0, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 40, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 18, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 40, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 5, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 78, + 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 40, 0, 85, 0, 0, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 0, + 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 5, 0, 0, 0, 86, 5, + 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, + 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 11, 34, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, + 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, + 0, 10, 162, 0, 16, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, + 60, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, + 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 11, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 140, 0, 0, 17, 242, 0, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 22, 11, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 30, 0, 0, 7, 242, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 11, + 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, + 3, 0, 0, 0, 230, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, + 0, 5, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 254, 7, + 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, + 85, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, + 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 48, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, + 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 140, 0, 0, 20, 98, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 19, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 11, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 98, + 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 9, 0, 0, + 0, 12, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 6, 1, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, + 0, 1, 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 42, 0, 0, 10, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, + 5, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, + 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, + 41, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 128, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 58, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, + 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 146, 0, 16, + 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 140, 0, 0, 17, 146, + 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 6, 12, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 146, 0, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, + 2, 64, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, + 0, 166, 10, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 1, 0, 0, 0, 35, 0, + 0, 12, 82, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 6, 3, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 7, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 18, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 30, + 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, + 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 4, 0, 0, + 0, 22, 11, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 130, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 32, 0, 0, 10, 114, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 150, 5, 16, 0, 1, + 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, + 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 140, 0, 0, 17, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, + 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, + 0, 5, 0, 0, 0, 22, 11, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 18, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 21, 0, 0, 1, 32, + 0, 0, 10, 210, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, + 0, 60, 0, 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 166, 11, 16, 0, 0, 0, + 0, 0, 6, 2, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 5, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, + 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 140, 0, 0, 17, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, + 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, + 0, 0, 150, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 44, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_64bpp_1x2xmsaa_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_64bpp_1x2xmsaa_scaled_cs.h new file mode 100644 index 0000000..b43f965 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_64bpp_1x2xmsaa_scaled_cs.h @@ -0,0 +1,636 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_resolve_edram_info; // Offset: 0 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 4 Size: 4 +// uint xe_resolve_dest_info; // Offset: 8 Size: 4 +// uint xe_resolve_dest_coordinate_info;// Offset: 12 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram texture uint4 buf T0 t0 1 +// xe_resolve_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 8 +dcl_thread_group 8, 8, 1 +and r0.xyzw, CB0[0][0].zxxz, l(7, 1023, 0x20000000, 8) +if_nz r0.z + ubfe r1.xy, l(2, 2, 0, 0), l(17, 20, 0, 0), CB0[0][0].yyyy +else + mov r1.xy, l(0,0,0,0) +endif +ubfe r2.xyz, l(3, 3, 11, 0), l(16, 19, 5, 0), CB0[0][0].yyyy +imul null, r0.z, r2.x, r2.z +and r1.z, CB0[0][0].z, l(0x01000000) +ushr r3.xyzw, CB0[0][0].ywww, l(4, 10, 20, 24) +ishl r4.x, vThreadID.x, l(2) +ishl r0.z, r0.z, l(3) +uge r0.z, r4.x, r0.z +if_nz r0.z + ret +endif +mov r5.x, CB0[0][0].y +mov r5.y, r3.x +bfi r2.zw, l(0, 0, 4, 1), l(0, 0, 3, 3), r5.xxxy, l(0, 0, 0, 0) +bfi r0.z, l(10), l(5), CB0[0][0].w, l(0) +bfi r3.xz, l(4, 0, 4, 0), l(3, 0, 3, 0), r3.zzwz, l(0, 0, 0, 0) +ubfe r5.xyz, l(2, 3, 11, 0), l(10, 28, 13, 0), CB0[0][0].xwxx +umax r4.y, r1.y, vThreadID.y +imad r1.yw, r2.zzzw, r2.xxxy, r4.xxxy +uge r2.z, l(3), r5.y +if_z r2.z + ieq r2.z, r5.y, l(5) + if_nz r2.z + mov r5.y, l(2) + else + mov r5.y, l(0) + endif +endif +uge r2.zw, r5.xxxx, l(0, 0, 2, 1) +and r2.zw, r2.zzzw, l(0, 0, 1, 1) +ishl r1.yw, r1.yyyw, r2.zzzw +ushr r5.x, r5.y, l(1) +and r2.zw, r5.xxxy, l(0, 0, 1, 1) +iadd r1.yw, r1.yyyw, r2.zzzw +imul null, r6.yz, r2.xxyx, l(0, 80, 16, 0) +ushr r6.x, r6.y, l(1) +udiv r2.zw, null, r1.yyyw, r6.xxxz +imad r0.y, r2.w, r0.y, r2.z +iadd r0.y, r0.y, r5.z +imad r1.yw, -r2.zzzw, r6.xxxz, r1.yyyw +imul null, r2.z, r6.z, r6.y +imad r1.y, r1.w, r6.x, r1.y +ishl r1.y, r1.y, l(1) +imad r0.y, r0.y, r2.z, r1.y +ishl r1.y, r2.z, l(11) +udiv null, r0.y, r0.y, r1.y +ushr r0.y, r0.y, l(2) +ld r5.xyzw, r0.yyyy, T0[0].zwxy +iadd r0.y, r0.y, l(1) +ld r6.xyzw, r0.yyyy, T0[0].xyzw +ieq r0.y, r4.x, l(0) +ine r1.y, r1.x, l(0) +and r0.y, r0.y, r1.y +if_nz r0.y + uge r0.y, r1.x, l(2) + if_nz r0.y + uge r0.y, r1.x, l(3) + if_nz r0.y + mov r6.xy, r6.zwzz + endif + mov r5.xy, r6.xyxx + endif + mov r5.xyzw, r5.xyxy +endif +if_nz r1.z + ubfe r0.y, l(4), l(24), CB0[0][0].x + ieq r1.xy, r0.yyyy, l(5, 7, 0, 0) + or r0.y, r1.y, r1.x + if_nz r0.y + bfi r5.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r5.yxwz, r5.xyzw + mov r6.zw, r6.wwwz + bfi r6.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r6.yxzw, r6.xywz + endif +endif +mov r4.z, vThreadID.y +imad r1.yz, r3.xxzx, r2.xxyx, r4.xxzx +ushr r1.x, r1.y, l(1) +udiv r1.yw, null, r1.xxxz, r2.xxxy +ishl r0.y, r1.y, l(1) +if_nz r0.w + ubfe r0.w, l(3), l(4), CB0[0][0].z + ishl r2.z, r3.y, l(5) + ishr r3.xy, r1.wwww, l(4, 3, 0, 0) + ishr r2.w, r0.w, l(2) + ushr r2.z, r2.z, l(4) + and r2.z, r2.z, l(2046) + imad r2.z, r2.w, r2.z, r3.x + ushr r3.x, r0.z, l(5) + ibfe r3.zw, l(0, 0, 27, 29), l(0, 0, 4, 2), r1.yyyy + imad r2.z, r2.z, r3.x, r3.z + ishl r3.x, r1.w, l(11) + and r3.x, r3.x, l(0x00003000) + bfi r3.x, l(3), l(9), r0.y, r3.x + ishr r3.x, r3.x, l(6) + iadd r2.w, r2.w, r3.y + bfi r3.y, l(1), l(1), r2.w, l(0) + iadd r3.y, r3.y, r3.w + bfi r3.y, l(2), l(1), r3.y, l(0) + bfi r2.w, l(1), l(0), r2.w, r3.y + bfi r3.yz, l(0, 19, 19, 0), l(0, 11, 14, 0), r2.zzzz, l(0, 0, 0, 0) + imad r3.xy, r3.xxxx, l(2, 16, 0, 0), r3.yzyy + bfi r3.xy, l(2, 2, 0, 0), l(9, 12, 0, 0), r0.wwww, r3.xyxx + bfi r0.w, l(1), l(4), r1.w, l(0) + ubfe r2.z, l(3), l(6), r3.x + and r3.z, r2.w, l(6) + bfi r2.w, l(1), l(8), r2.w, l(0) + imad r2.z, r2.z, l(32), r2.w + imad r2.z, r3.z, l(4), r2.z + bfi r3.xy, l(5, 5, 0, 0), l(0, 3, 0, 0), r0.wwww, r3.xyxx + bfi r0.w, l(9), l(3), r2.z, r3.y + bfi r0.w, l(6), l(0), r3.x, r0.w +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 4, 2), r1.yyyy + ishr r3.xy, r1.wwww, l(5, 2, 0, 0) + ushr r0.z, r0.z, l(5) + imad r0.z, r3.x, r0.z, r2.z + ishl r3.xz, r1.wwww, l(6, 0, 7, 0) + and r3.xz, r3.xxzx, l(896, 0, 2048, 0) + bfi r2.z, l(3), l(4), r0.y, r3.x + bfi r2.z, l(22), l(10), r0.z, r2.z + bfi r3.w, l(1), l(4), r1.w, l(0) + iadd r2.z, r2.z, r3.w + ishl r4.yz, r3.xxxx, l(0, 3, 2, 0) + bfi r4.yz, l(0, 3, 3, 0), l(0, 7, 6, 0), r0.yyyy, r4.yyzy + bfi r0.yz, l(0, 22, 22, 0), l(0, 13, 12, 0), r0.zzzz, r4.yyzy + imad r0.yz, r3.wwww, l(0, 8, 4, 0), r0.yyzy + bfi r0.y, l(12), l(0), r3.z, r0.y + and r0.z, r0.z, l(1792) + iadd r0.y, r0.y, r0.z + and r0.z, r3.y, l(2) + iadd r0.z, r2.w, r0.z + bfi r0.z, l(2), l(6), r0.z, l(0) + iadd r0.y, r0.y, r0.z + bfi r0.w, l(6), l(0), r2.z, r0.y +endif +imad r0.yz, -r1.yywy, r2.xxyx, r1.xxzx +imul null, r1.x, r2.y, r2.x +imad r0.y, r0.y, r2.y, r0.z +ishl r0.y, r0.y, l(4) +imad r0.y, r0.w, r1.x, r0.y +ushr r0.y, r0.y, l(4) +ieq r0.z, r0.x, l(4) +if_nz r0.z + mov r5.xyzw, r5.yxwz + mov r0.w, l(2) +else + mov r0.w, r0.x +endif +ieq r1.xyz, r0.wwww, l(1, 2, 3, 0) +or r1.xy, r1.yzyy, r1.xyxx +if_nz r1.x + ishl r3.xyzw, r5.zwxy, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r7.xyzw, r5.zwxy, l(8, 8, 8, 8) + and r7.xyzw, r7.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r5.xyzw, r3.zwxy, r7.zwxy +endif +if_nz r1.y + ushr r1.xyzw, r5.zwxy, l(16, 16, 16, 16) + bfi r5.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r5.xyzw, r1.zwxy +endif +store_uav_typed U0[0].xyzw, r0.yyyy, r5.zwxy +ult r0.w, l(1), r2.x +if_nz r0.w + ushr r0.w, r4.x, l(1) + udiv r1.x, null, r0.w, r2.x + imad r0.w, -r1.x, r2.x, r0.w + iadd r1.x, r0.w, l(1) + ieq r1.x, r2.x, r1.x + if_nz r1.x + ishl r1.x, r2.x, l(5) + ishl r0.w, r0.w, l(4) + iadd r0.w, -r0.w, r1.x + else + mov r0.w, l(16) + endif +else + mov r0.w, l(32) +endif +imul null, r0.w, r2.y, r0.w +ushr r0.w, r0.w, l(4) +iadd r0.y, r0.w, r0.y +if_nz r0.z + mov r6.xyzw, r6.yxwz + mov r0.x, l(2) +endif +ieq r0.xzw, r0.xxxx, l(1, 0, 2, 3) +or r0.xz, r0.zzwz, r0.xxzx +if_nz r0.x + ishl r1.xyzw, r6.xyzw, l(8, 8, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r2.xyzw, r6.xyzw, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r6.xyzw, r1.xyzw, r2.xyzw +endif +if_nz r0.z + ushr r1.xyzw, r6.xyzw, l(16, 16, 16, 16) + bfi r6.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r6.xyzw, r1.xyzw +endif +store_uav_typed U0[0].xyzw, r0.yyyy, r6.xyzw +ret +// Approximately 206 instruction slots used +#endif + +const BYTE resolve_fast_64bpp_1x2xmsaa_scaled_cs[] = { + 68, 88, 66, 67, 182, 29, 21, 169, 251, 52, 51, 246, 117, 184, 56, 229, 69, 116, 78, + 124, 1, 0, 0, 0, 28, 28, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 144, 2, + 0, 0, 160, 2, 0, 0, 176, 2, 0, 0, 128, 27, 0, 0, 82, 68, 69, 70, 84, + 2, 0, 0, 1, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 44, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 101, 100, 114, 97, 109, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 213, 0, 0, 0, 4, 0, 0, 0, 252, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 156, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 220, 1, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 247, 1, 0, 0, 8, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 12, 2, 0, 0, 12, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, + 114, 101, 115, 111, 108, 118, 101, 95, 101, 100, 114, 97, 109, 95, 105, 110, 102, 111, 0, + 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 178, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 99, 111, 111, 114, + 100, 105, 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 100, 101, 115, 116, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 99, 111, 111, 114, 100, 105, 110, 97, + 116, 101, 95, 105, 110, 102, 111, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 83, 72, 69, 88, 200, 24, 0, 0, 81, 0, 5, 0, 50, 6, 0, + 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 88, 8, 0, 7, 70, + 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, + 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 95, 0, 0, 2, 50, 0, + 2, 0, 104, 0, 0, 2, 8, 0, 0, 0, 155, 0, 0, 4, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, 0, + 38, 136, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 255, 3, 0, 0, 0, 0, 0, 32, 8, 0, 0, 0, 31, 0, + 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 17, 50, 0, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 17, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 86, 133, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 18, 0, 0, 1, 54, 0, 0, 8, 50, 0, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 1, 138, 0, 0, 17, 114, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 86, + 133, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, + 0, 208, 0, 0, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 9, 66, 0, 16, 0, 1, 0, + 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 1, 85, 0, 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, + 214, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 4, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 41, 0, + 0, 6, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 80, 0, 0, 7, 66, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, + 0, 0, 1, 54, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 26, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, + 0, 5, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 20, 194, 0, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, + 0, 13, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, + 64, 0, 0, 5, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 20, 82, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 166, 11, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 17, 114, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, + 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 28, + 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 198, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 6, 34, 0, 16, 0, 4, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 9, 162, 0, + 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 2, + 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 80, 0, 0, 7, 66, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, + 0, 31, 0, 0, 3, 42, 0, 16, 0, 2, 0, 0, 0, 32, 0, 0, 7, 66, 0, + 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, + 34, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 18, 0, 0, + 1, 54, 0, 0, 5, 34, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 80, 0, 0, 10, 194, 0, 16, 0, 2, + 0, 0, 0, 6, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, + 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 162, + 0, 16, 0, 1, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, + 2, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, + 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, + 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, + 162, 0, 16, 0, 1, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 166, 14, 16, + 0, 2, 0, 0, 0, 38, 0, 0, 11, 0, 208, 0, 0, 98, 0, 16, 0, 6, 0, + 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 80, + 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, + 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 78, 0, 0, 8, 194, 0, 16, 0, 2, 0, 0, 0, 0, 208, 0, 0, 86, 13, + 16, 0, 1, 0, 0, 0, 6, 8, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, + 0, 0, 35, 0, 0, 10, 162, 0, 16, 0, 1, 0, 0, 0, 166, 14, 16, 128, 65, + 0, 0, 0, 2, 0, 0, 0, 6, 8, 16, 0, 6, 0, 0, 0, 86, 13, 16, 0, + 1, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, 2, 0, 0, + 0, 42, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 78, 0, 0, 8, 0, 208, 0, + 0, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 45, 0, 0, 8, + 242, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 230, 116, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 45, + 0, 0, 8, 242, 0, 16, 0, 6, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, + 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 39, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 80, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 80, 0, 0, 7, + 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 50, 0, 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, 6, 0, 0, 0, 21, + 0, 0, 1, 54, 0, 0, 5, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, + 6, 0, 0, 0, 21, 0, 0, 1, 54, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, + 0, 70, 4, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, + 16, 0, 1, 0, 0, 0, 138, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 10, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, + 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 11, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 194, 0, 16, 0, 6, 0, 0, + 0, 246, 11, 16, 0, 6, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 22, 14, 16, 0, 6, 0, 0, 0, 70, 11, 16, 0, 6, 0, 0, + 0, 21, 0, 0, 1, 21, 0, 0, 1, 54, 0, 0, 4, 66, 0, 16, 0, 4, 0, + 0, 0, 26, 0, 2, 0, 35, 0, 0, 9, 98, 0, 16, 0, 1, 0, 0, 0, 6, + 2, 16, 0, 3, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, + 4, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 78, 0, 0, 8, 162, 0, + 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 6, 8, 16, 0, 1, 0, 0, 0, 6, + 4, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, + 3, 58, 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 11, 130, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 5, 0, 0, 0, 42, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 246, 15, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, + 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 254, 7, 0, 0, 35, 0, 0, 9, + 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 85, 0, 0, 7, 18, 0, + 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 139, 0, 0, 15, 194, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 86, 5, + 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, + 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, 7, 18, 0, + 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, + 48, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 3, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, + 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, + 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, + 20, 98, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 19, 0, + 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 11, + 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 35, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 150, 5, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 3, + 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, 66, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, + 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, + 0, 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, + 0, 0, 17, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 15, 194, 0, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 42, 0, 0, 10, 50, 0, 16, 0, 3, + 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, + 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 41, 0, 0, 10, 82, 0, 16, 0, 3, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 128, 3, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, + 0, 4, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, + 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 86, 6, + 16, 0, 4, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, + 0, 166, 10, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, 4, 0, 0, 0, 35, 0, + 0, 12, 98, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 86, 6, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 7, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 35, + 0, 0, 10, 98, 0, 16, 0, 0, 0, 0, 0, 86, 7, 16, 128, 65, 0, 0, 0, + 1, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, + 0, 38, 0, 0, 8, 0, 208, 0, 0, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, + 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, + 5, 0, 0, 0, 22, 11, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 18, 0, 0, 1, 54, 0, + 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 21, + 0, 0, 1, 32, 0, 0, 10, 114, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 150, 5, + 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, + 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 230, 4, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, + 7, 0, 0, 0, 230, 4, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, + 242, 0, 16, 0, 5, 0, 0, 0, 230, 4, 16, 0, 3, 0, 0, 0, 230, 4, 16, + 0, 7, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 230, 4, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 230, 4, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, + 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, + 0, 0, 0, 0, 0, 230, 4, 16, 0, 5, 0, 0, 0, 79, 0, 0, 7, 130, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, + 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 78, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 0, 208, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 35, + 0, 0, 10, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, 0, + 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 8, 130, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 54, + 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, + 21, 0, 0, 1, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, + 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 6, 0, + 0, 0, 22, 11, 16, 0, 6, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 21, 0, 0, 1, 32, 0, 0, 10, + 210, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 0, + 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 6, + 2, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, + 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 206, + 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 63, 0, 0, 0, 44, 0, 0, 0, 8, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_64bpp_4xmsaa_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_64bpp_4xmsaa_cs.h new file mode 100644 index 0000000..3753ca5 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_64bpp_4xmsaa_cs.h @@ -0,0 +1,519 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_resolve_edram_info; // Offset: 0 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 4 Size: 4 +// uint xe_resolve_dest_info; // Offset: 8 Size: 4 +// uint xe_resolve_dest_coordinate_info;// Offset: 12 Size: 4 +// uint xe_resolve_dest_base; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram texture uint2 buf T0 t0 1 +// xe_resolve_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][2], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 7 +dcl_thread_group 8, 8, 1 +and r0.xyzw, CB0[0][0].zxzz, l(7, 1023, 8, 0x01000000) +ushr r1.xyz, CB0[0][0].yywy, l(4, 5, 10, 0) +ushr r2.xyzw, CB0[0][0].wwww, l(20, 24, 24, 20) +ishl r3.xw, vThreadID.xxxx, l(2, 0, 0, 2) +bfi r1.y, l(11), l(3), r1.y, l(0) +uge r1.y, r3.w, r1.y +if_nz r1.y + ret +endif +mov r1.w, CB0[0][0].y +bfi r1.xy, l(4, 1, 0, 0), l(3, 3, 0, 0), r1.wxww, l(0, 0, 0, 0) +bfi r1.w, l(10), l(5), CB0[0][0].w, l(0) +bfi r2.xyzw, l(4, 4, 4, 4), l(3, 3, 3, 3), r2.xyzw, l(0, 0, 0, 0) +ubfe r4.xy, l(11, 3, 0, 0), l(13, 28, 0, 0), CB0[0][0].xwxx +mov r3.yz, vThreadID.yyyy +iadd r1.xy, r1.xyxx, r3.wzww +uge r4.z, l(3), r4.y +if_nz r4.z + mov r5.y, r4.y +else + ieq r4.z, r4.y, l(5) + if_nz r4.z + mov r5.y, l(2) + else + mov r5.y, l(0) + endif +endif +ishl r1.xy, r1.xyxx, l(1, 1, 0, 0) +ushr r5.x, r5.y, l(1) +bfi r1.xy, l(3, 1, 0, 0), l(0, 0, 0, 0), r5.xyxx, r1.xyxx +udiv r4.yz, null, r1.xxyx, l(0, 40, 16, 0) +imad r0.y, r4.z, r0.y, r4.y +iadd r0.y, r0.y, r4.x +imad r1.xy, -r4.yzyy, l(40, 16, 0, 0), r1.xyxx +imad r1.x, r1.y, l(40), r1.x +ishl r1.x, r1.x, l(1) +imad r0.y, r0.y, l(1280), r1.x +udiv null, r0.y, r0.y, l(0x00280000) +ushr r0.y, r0.y, l(1) +ld r4.xy, r0.yyyy, T0[0].xywz +iadd r5.xyz, r0.yyyy, l(2, 4, 6, 0) +ld r4.zw, r5.xxxx, T0[0].zwyx +ld r6.xy, r5.yyyy, T0[0].xywz +ld r6.zw, r5.zzzz, T0[0].zwyx +if_nz r0.w + ubfe r0.y, l(4), l(24), CB0[0][0].x + ieq r0.yw, r0.yyyy, l(0, 5, 0, 7) + or r0.y, r0.w, r0.y + if_nz r0.y + mov r4.xyzw, r4.yxzw + bfi r4.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r4.xywz, r4.yxzw + mov r6.xyzw, r6.yxzw + bfi r6.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r6.xywz, r6.yxzw + endif +endif +iadd r2.xyzw, r2.xyzw, r3.xyzw +if_nz r0.z + ubfe r0.y, l(3), l(4), CB0[0][0].z + ishl r0.z, r1.z, l(5) + ishr r3.xyzw, r2.zwzw, l(4, 5, 3, 3) + ishr r0.w, r0.y, l(2) + ushr r0.z, r0.z, l(4) + and r0.z, r0.z, l(2046) + imad r0.z, r0.w, r0.z, r3.x + ushr r1.x, r1.w, l(5) + imad r0.z, r0.z, r1.x, r3.y + ishl r1.x, r2.z, l(11) + and r1.x, r1.x, l(0x00003000) + bfi r1.x, l(3), l(9), r2.w, r1.x + ishr r1.x, r1.x, l(6) + iadd r0.w, r0.w, r3.z + bfi r1.y, l(1), l(1), r0.w, l(0) + iadd r1.y, r1.y, r3.w + bfi r1.y, l(2), l(1), r1.y, l(0) + bfi r0.w, l(1), l(0), r0.w, r1.y + bfi r1.yz, l(0, 19, 19, 0), l(0, 11, 14, 0), r0.zzzz, l(0, 0, 0, 0) + imad r1.xy, r1.xxxx, l(2, 16, 0, 0), r1.yzyy + bfi r0.yz, l(0, 2, 2, 0), l(0, 9, 12, 0), r0.yyyy, r1.xxyx + bfi r1.x, l(1), l(4), r2.z, l(0) + ubfe r1.y, l(3), l(6), r0.y + and r1.z, r0.w, l(6) + bfi r0.w, l(1), l(8), r0.w, l(0) + imad r0.w, r1.y, l(32), r0.w + imad r0.w, r1.z, l(4), r0.w + bfi r0.yz, l(0, 6, 6, 0), l(0, 0, 3, 0), r1.xxxx, r0.yyzy + bfi r0.z, l(9), l(3), r0.w, r0.z + bfi r0.y, l(6), l(0), r0.y, r0.z +else + ishr r3.xyzw, r2.xyzw, l(5, 5, 2, 3) + ushr r0.z, r1.w, l(5) + imad r0.z, r3.y, r0.z, r3.x + ishl r1.xy, r2.zzzz, l(6, 7, 0, 0) + and r1.xy, r1.xyxx, l(896, 2048, 0, 0) + bfi r0.w, l(3), l(4), r2.w, r1.x + bfi r0.w, l(22), l(10), r0.z, r0.w + bfi r1.z, l(1), l(4), r2.z, l(0) + iadd r0.w, r0.w, r1.z + ishl r1.xw, r1.xxxx, l(3, 0, 0, 2) + bfi r1.xw, l(3, 0, 0, 3), l(7, 0, 0, 6), r2.wwww, r1.xxxw + bfi r1.xw, l(22, 0, 0, 22), l(13, 0, 0, 12), r0.zzzz, r1.xxxw + imad r1.xz, r1.zzzz, l(8, 0, 4, 0), r1.xxwx + bfi r0.z, l(12), l(0), r1.y, r1.x + and r1.x, r1.z, l(1792) + iadd r0.z, r0.z, r1.x + and r1.x, r3.z, l(2) + iadd r1.x, r3.w, r1.x + bfi r1.x, l(2), l(6), r1.x, l(0) + iadd r0.z, r0.z, r1.x + bfi r0.y, l(6), l(0), r0.w, r0.z +endif +iadd r0.y, r0.y, CB0[0][1].x +ushr r0.y, r0.y, l(4) +ieq r0.z, r0.x, l(4) +if_nz r0.z + mov r4.xyzw, r4.yxwz + mov r0.w, l(2) +else + mov r0.w, r0.x +endif +ieq r1.xyz, r0.wwww, l(1, 2, 3, 0) +or r1.xy, r1.yzyy, r1.xyxx +if_nz r1.x + ishl r2.xyzw, r4.xywz, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r3.xyzw, r4.xywz, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r4.xyzw, r2.xywz, r3.xywz +endif +if_nz r1.y + ushr r1.xyzw, r4.xywz, l(16, 16, 16, 16) + bfi r4.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r4.xyzw, r1.xywz +endif +store_uav_typed U0[0].xyzw, r0.yyyy, r4.xywz +iadd r0.y, r0.y, l(2) +if_nz r0.z + mov r6.xyzw, r6.yxwz + mov r0.x, l(2) +endif +ieq r0.xzw, r0.xxxx, l(1, 0, 2, 3) +or r0.xz, r0.zzwz, r0.xxzx +if_nz r0.x + ishl r1.xyzw, r6.xywz, l(8, 8, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r2.xyzw, r6.xywz, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r6.xyzw, r1.xywz, r2.xywz +endif +if_nz r0.z + ushr r1.xyzw, r6.xywz, l(16, 16, 16, 16) + bfi r6.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r6.xyzw, r1.xywz +endif +store_uav_typed U0[0].xyzw, r0.yyyy, r6.xywz +ret +// Approximately 153 instruction slots used +#endif + +const BYTE resolve_fast_64bpp_4xmsaa_cs[] = { + 68, 88, 66, 67, 173, 139, 27, 149, 157, 84, 81, 87, 190, 67, 71, 120, 194, 234, 127, + 141, 1, 0, 0, 0, 72, 23, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 208, 2, + 0, 0, 224, 2, 0, 0, 240, 2, 0, 0, 172, 22, 0, 0, 82, 68, 69, 70, 148, + 2, 0, 0, 1, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 105, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 101, 100, 114, 97, 109, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 213, 0, 0, 0, 5, 0, 0, 0, 252, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 196, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 4, 2, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 31, 2, 0, 0, 8, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 52, 2, 0, 0, 12, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 84, 2, 0, + 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, + 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 101, 100, 114, 97, 109, 95, 105, 110, 102, + 111, 0, 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 218, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 99, 111, + 111, 114, 100, 105, 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 105, 110, 102, 111, 0, 120, 101, 95, + 114, 101, 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 99, 111, 111, 114, 100, 105, + 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 95, 98, 97, 115, 101, 0, 77, 105, 99, 114, 111, 115, 111, + 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, + 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, + 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 180, 19, 0, 0, + 81, 0, 5, 0, 237, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, + 0, 95, 0, 0, 2, 50, 0, 2, 0, 104, 0, 0, 2, 7, 0, 0, 0, 155, 0, + 0, 4, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, 242, + 0, 16, 0, 0, 0, 0, 0, 38, 138, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 255, 3, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 1, 85, 0, 0, 12, 114, 0, 16, 0, 1, 0, 0, 0, 86, 135, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, + 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, + 242, 0, 16, 0, 2, 0, 0, 0, 246, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 24, 0, + 0, 0, 20, 0, 0, 0, 41, 0, 0, 9, 146, 0, 16, 0, 3, 0, 0, 0, 6, + 0, 2, 0, 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 11, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, + 1, 54, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 13, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 64, 0, 0, + 5, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 17, 50, 0, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 13, 0, 0, 0, 28, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 198, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 4, 98, 0, 16, 0, 3, 0, 0, 0, 86, 5, + 2, 0, 30, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, + 0, 0, 0, 182, 15, 16, 0, 3, 0, 0, 0, 80, 0, 0, 7, 66, 0, 16, 0, + 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, + 0, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 34, 0, + 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 18, 0, 0, 1, 32, + 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, + 1, 64, 0, 0, 5, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, + 0, 54, 0, 0, 5, 34, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 34, 0, 16, 0, 5, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 41, 0, 0, 10, + 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 78, + 0, 0, 11, 98, 0, 16, 0, 4, 0, 0, 0, 0, 208, 0, 0, 6, 1, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, + 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 35, 0, 0, 13, 50, 0, 16, + 0, 1, 0, 0, 0, 150, 5, 16, 128, 65, 0, 0, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 40, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, + 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 40, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 5, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 78, 0, 0, 8, 0, 208, 0, + 0, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 40, 0, 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 45, 0, 0, 8, + 50, 0, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 123, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 5, 0, + 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 194, 0, 16, 0, + 4, 0, 0, 0, 6, 0, 16, 0, 5, 0, 0, 0, 230, 113, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 45, 0, 0, 8, 50, 0, 16, 0, 6, 0, 0, 0, 86, 5, + 16, 0, 5, 0, 0, 0, 70, 123, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, + 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, 0, 166, 10, 16, 0, 5, 0, 0, 0, + 230, 113, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, + 0, 0, 0, 0, 0, 138, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 10, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 162, 0, 16, 0, + 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 242, 0, 16, 0, 4, 0, 0, 0, 22, 14, 16, 0, 4, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 11, 16, 0, 4, 0, 0, 0, + 22, 14, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 6, 0, 0, + 0, 22, 14, 16, 0, 6, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 70, 11, 16, 0, 6, 0, 0, 0, 22, 14, 16, 0, 6, 0, 0, + 0, 21, 0, 0, 1, 21, 0, 0, 1, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 31, + 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 11, 34, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, + 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 230, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, + 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 254, 7, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 85, 0, 0, 7, + 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 5, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, + 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 48, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 3, + 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 20, + 98, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 19, 0, 0, + 0, 19, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 11, 0, + 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 35, 0, 0, 12, 50, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 150, 5, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 0, 0, + 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 35, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 140, 0, + 0, 17, 98, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, + 0, 86, 6, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, + 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 18, 0, 0, 1, 42, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 2, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, + 50, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 128, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 22, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 146, 0, 16, 0, 1, 0, 0, + 0, 6, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 140, 0, 0, 17, 146, 0, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 6, 12, 16, 0, 1, 0, + 0, 0, 140, 0, 0, 17, 146, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 22, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 2, 64, 0, 0, + 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 166, 10, 16, + 0, 0, 0, 0, 0, 6, 12, 16, 0, 1, 0, 0, 0, 35, 0, 0, 12, 82, 0, + 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 6, 3, 16, 0, + 1, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, + 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 4, 0, 0, 0, 22, 11, 16, + 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 130, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 32, 0, 0, 10, + 114, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 60, 0, + 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 150, 5, 16, 0, 1, 0, 0, 0, 70, + 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 11, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 11, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, + 0, 70, 11, 16, 0, 2, 0, 0, 0, 70, 11, 16, 0, 3, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 1, 0, 0, 0, 70, 11, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 70, 11, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 11, + 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 6, 0, 0, + 0, 22, 11, 16, 0, 6, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 21, 0, 0, 1, 32, 0, 0, 10, 210, + 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, + 7, 82, 0, 16, 0, 0, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 6, 2, + 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 11, 16, 0, 6, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 11, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, + 70, 11, 16, 0, 1, 0, 0, 0, 70, 11, 16, 0, 2, 0, 0, 0, 21, 0, 0, + 1, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, + 16, 0, 1, 0, 0, 0, 70, 11, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, + 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, + 11, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 11, 16, + 0, 6, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 153, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 43, + 0, 0, 0, 30, 0, 0, 0, 6, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_64bpp_4xmsaa_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_64bpp_4xmsaa_scaled_cs.h new file mode 100644 index 0000000..7b2c668 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_fast_64bpp_4xmsaa_scaled_cs.h @@ -0,0 +1,639 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_resolve_edram_info; // Offset: 0 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 4 Size: 4 +// uint xe_resolve_dest_info; // Offset: 8 Size: 4 +// uint xe_resolve_dest_coordinate_info;// Offset: 12 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram texture uint2 buf T0 t0 1 +// xe_resolve_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 8 +dcl_thread_group 8, 8, 1 +and r0.xyzw, CB0[0][0].zxxz, l(7, 1023, 0x20000000, 8) +if_nz r0.z + ubfe r1.xy, l(2, 2, 0, 0), l(17, 20, 0, 0), CB0[0][0].yyyy +else + mov r1.xy, l(0,0,0,0) +endif +ubfe r2.xyz, l(3, 3, 11, 0), l(16, 19, 5, 0), CB0[0][0].yyyy +imul null, r0.z, r2.x, r2.z +and r1.z, CB0[0][0].z, l(0x01000000) +ushr r3.xyzw, CB0[0][0].ywww, l(4, 10, 20, 24) +ishl r4.x, vThreadID.x, l(2) +ishl r0.z, r0.z, l(3) +uge r0.z, r4.x, r0.z +if_nz r0.z + ret +endif +mov r5.x, CB0[0][0].y +mov r5.y, r3.x +bfi r2.zw, l(0, 0, 4, 1), l(0, 0, 3, 3), r5.xxxy, l(0, 0, 0, 0) +bfi r0.z, l(10), l(5), CB0[0][0].w, l(0) +bfi r3.xz, l(4, 0, 4, 0), l(3, 0, 3, 0), r3.zzwz, l(0, 0, 0, 0) +ubfe r5.xy, l(11, 3, 0, 0), l(13, 28, 0, 0), CB0[0][0].xwxx +umax r4.y, r1.y, vThreadID.y +imad r1.yw, r2.zzzw, r2.xxxy, r4.xxxy +uge r2.z, l(3), r5.y +if_nz r2.z + mov r6.y, r5.y +else + ieq r2.z, r5.y, l(5) + if_nz r2.z + mov r6.y, l(2) + else + mov r6.y, l(0) + endif +endif +ishl r1.yw, r1.yyyw, l(0, 1, 0, 1) +ushr r6.x, r6.y, l(1) +bfi r1.yw, l(0, 3, 0, 1), l(0, 0, 0, 0), r6.xxxy, r1.yyyw +imul null, r6.yz, r2.xxyx, l(0, 80, 16, 0) +ushr r6.x, r6.y, l(1) +udiv r2.zw, null, r1.yyyw, r6.xxxz +imad r0.y, r2.w, r0.y, r2.z +iadd r0.y, r0.y, r5.x +imad r1.yw, -r2.zzzw, r6.xxxz, r1.yyyw +imul null, r2.z, r6.z, r6.y +imad r1.y, r1.w, r6.x, r1.y +ishl r1.y, r1.y, l(1) +imad r0.y, r0.y, r2.z, r1.y +ishl r1.y, r2.z, l(11) +udiv null, r0.y, r0.y, r1.y +ushr r0.y, r0.y, l(1) +ld r5.zw, r0.yyyy, T0[0].zwxy +iadd r6.xyz, r0.yyyy, l(2, 4, 6, 0) +ld r5.xy, r6.xxxx, T0[0].xyzw +ld r7.xy, r6.yyyy, T0[0].xyzw +ld r7.zw, r6.zzzz, T0[0].zwxy +ieq r0.y, r4.x, l(0) +ine r1.y, r1.x, l(0) +and r0.y, r0.y, r1.y +if_nz r0.y + uge r0.y, r1.x, l(2) + if_nz r0.y + uge r0.y, r1.x, l(3) + if_nz r0.y + mov r7.xy, r7.zwzz + endif + mov r5.xy, r7.xyxx + endif + mov r5.xyzw, r5.xyxy +endif +if_nz r1.z + ubfe r0.y, l(4), l(24), CB0[0][0].x + ieq r1.xy, r0.yyyy, l(5, 7, 0, 0) + or r0.y, r1.y, r1.x + if_nz r0.y + bfi r5.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r5.yxwz, r5.xyzw + mov r7.zw, r7.wwwz + bfi r7.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r7.yxzw, r7.xywz + endif +endif +mov r4.z, vThreadID.y +imad r1.yz, r3.xxzx, r2.xxyx, r4.xxzx +ushr r1.x, r1.y, l(1) +udiv r1.yw, null, r1.xxxz, r2.xxxy +ishl r0.y, r1.y, l(1) +if_nz r0.w + ubfe r0.w, l(3), l(4), CB0[0][0].z + ishl r2.z, r3.y, l(5) + ishr r3.xy, r1.wwww, l(4, 3, 0, 0) + ishr r2.w, r0.w, l(2) + ushr r2.z, r2.z, l(4) + and r2.z, r2.z, l(2046) + imad r2.z, r2.w, r2.z, r3.x + ushr r3.x, r0.z, l(5) + ibfe r3.zw, l(0, 0, 27, 29), l(0, 0, 4, 2), r1.yyyy + imad r2.z, r2.z, r3.x, r3.z + ishl r3.x, r1.w, l(11) + and r3.x, r3.x, l(0x00003000) + bfi r3.x, l(3), l(9), r0.y, r3.x + ishr r3.x, r3.x, l(6) + iadd r2.w, r2.w, r3.y + bfi r3.y, l(1), l(1), r2.w, l(0) + iadd r3.y, r3.y, r3.w + bfi r3.y, l(2), l(1), r3.y, l(0) + bfi r2.w, l(1), l(0), r2.w, r3.y + bfi r3.yz, l(0, 19, 19, 0), l(0, 11, 14, 0), r2.zzzz, l(0, 0, 0, 0) + imad r3.xy, r3.xxxx, l(2, 16, 0, 0), r3.yzyy + bfi r3.xy, l(2, 2, 0, 0), l(9, 12, 0, 0), r0.wwww, r3.xyxx + bfi r0.w, l(1), l(4), r1.w, l(0) + ubfe r2.z, l(3), l(6), r3.x + and r3.z, r2.w, l(6) + bfi r2.w, l(1), l(8), r2.w, l(0) + imad r2.z, r2.z, l(32), r2.w + imad r2.z, r3.z, l(4), r2.z + bfi r3.xy, l(5, 5, 0, 0), l(0, 3, 0, 0), r0.wwww, r3.xyxx + bfi r0.w, l(9), l(3), r2.z, r3.y + bfi r0.w, l(6), l(0), r3.x, r0.w +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 4, 2), r1.yyyy + ishr r3.xy, r1.wwww, l(5, 2, 0, 0) + ushr r0.z, r0.z, l(5) + imad r0.z, r3.x, r0.z, r2.z + ishl r3.xz, r1.wwww, l(6, 0, 7, 0) + and r3.xz, r3.xxzx, l(896, 0, 2048, 0) + bfi r2.z, l(3), l(4), r0.y, r3.x + bfi r2.z, l(22), l(10), r0.z, r2.z + bfi r3.w, l(1), l(4), r1.w, l(0) + iadd r2.z, r2.z, r3.w + ishl r4.yz, r3.xxxx, l(0, 3, 2, 0) + bfi r4.yz, l(0, 3, 3, 0), l(0, 7, 6, 0), r0.yyyy, r4.yyzy + bfi r0.yz, l(0, 22, 22, 0), l(0, 13, 12, 0), r0.zzzz, r4.yyzy + imad r0.yz, r3.wwww, l(0, 8, 4, 0), r0.yyzy + bfi r0.y, l(12), l(0), r3.z, r0.y + and r0.z, r0.z, l(1792) + iadd r0.y, r0.y, r0.z + and r0.z, r3.y, l(2) + iadd r0.z, r2.w, r0.z + bfi r0.z, l(2), l(6), r0.z, l(0) + iadd r0.y, r0.y, r0.z + bfi r0.w, l(6), l(0), r2.z, r0.y +endif +imad r0.yz, -r1.yywy, r2.xxyx, r1.xxzx +imul null, r1.x, r2.y, r2.x +imad r0.y, r0.y, r2.y, r0.z +ishl r0.y, r0.y, l(4) +imad r0.y, r0.w, r1.x, r0.y +ushr r0.y, r0.y, l(4) +ieq r0.z, r0.x, l(4) +if_nz r0.z + mov r5.xyzw, r5.yxwz + mov r0.w, l(2) +else + mov r0.w, r0.x +endif +ieq r1.xyz, r0.wwww, l(1, 2, 3, 0) +or r1.xy, r1.yzyy, r1.xyxx +if_nz r1.x + ishl r3.xyzw, r5.zwxy, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r6.xyzw, r5.zwxy, l(8, 8, 8, 8) + and r6.xyzw, r6.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r5.xyzw, r3.zwxy, r6.zwxy +endif +if_nz r1.y + ushr r1.xyzw, r5.zwxy, l(16, 16, 16, 16) + bfi r5.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r5.xyzw, r1.zwxy +endif +store_uav_typed U0[0].xyzw, r0.yyyy, r5.zwxy +ult r0.w, l(1), r2.x +if_nz r0.w + ushr r0.w, r4.x, l(1) + udiv r1.x, null, r0.w, r2.x + imad r0.w, -r1.x, r2.x, r0.w + iadd r1.x, r0.w, l(1) + ieq r1.x, r2.x, r1.x + if_nz r1.x + ishl r1.x, r2.x, l(5) + ishl r0.w, r0.w, l(4) + iadd r0.w, -r0.w, r1.x + else + mov r0.w, l(16) + endif +else + mov r0.w, l(32) +endif +imul null, r0.w, r2.y, r0.w +ushr r0.w, r0.w, l(4) +iadd r0.y, r0.w, r0.y +if_nz r0.z + mov r7.xyzw, r7.yxwz + mov r0.x, l(2) +endif +ieq r0.xzw, r0.xxxx, l(1, 0, 2, 3) +or r0.xz, r0.zzwz, r0.xxzx +if_nz r0.x + ishl r1.xyzw, r7.xyzw, l(8, 8, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r2.xyzw, r7.xyzw, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r7.xyzw, r1.xyzw, r2.xyzw +endif +if_nz r0.z + ushr r1.xyzw, r7.xyzw, l(16, 16, 16, 16) + bfi r7.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r7.xyzw, r1.xyzw +endif +store_uav_typed U0[0].xyzw, r0.yyyy, r7.xyzw +ret +// Approximately 207 instruction slots used +#endif + +const BYTE resolve_fast_64bpp_4xmsaa_scaled_cs[] = { + 68, 88, 66, 67, 146, 245, 93, 84, 7, 50, 167, 252, 236, 19, 195, 72, 154, 161, 77, + 39, 1, 0, 0, 0, 60, 28, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 144, 2, + 0, 0, 160, 2, 0, 0, 176, 2, 0, 0, 160, 27, 0, 0, 82, 68, 69, 70, 84, + 2, 0, 0, 1, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 44, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 101, 100, 114, 97, 109, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 213, 0, 0, 0, 4, 0, 0, 0, 252, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 156, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 220, 1, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 247, 1, 0, 0, 8, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 12, 2, 0, 0, 12, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, + 114, 101, 115, 111, 108, 118, 101, 95, 101, 100, 114, 97, 109, 95, 105, 110, 102, 111, 0, + 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 178, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 99, 111, 111, 114, + 100, 105, 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 100, 101, 115, 116, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 99, 111, 111, 114, 100, 105, 110, 97, + 116, 101, 95, 105, 110, 102, 111, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 83, 72, 69, 88, 232, 24, 0, 0, 81, 0, 5, 0, 58, 6, 0, + 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 88, 8, 0, 7, 70, + 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, + 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 95, 0, 0, 2, 50, 0, + 2, 0, 104, 0, 0, 2, 8, 0, 0, 0, 155, 0, 0, 4, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, 0, + 38, 136, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 255, 3, 0, 0, 0, 0, 0, 32, 8, 0, 0, 0, 31, 0, + 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 17, 50, 0, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 17, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 86, 133, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 18, 0, 0, 1, 54, 0, 0, 8, 50, 0, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 1, 138, 0, 0, 17, 114, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 86, + 133, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, + 0, 208, 0, 0, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 9, 66, 0, 16, 0, 1, 0, + 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 1, 85, 0, 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, + 214, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 4, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 41, 0, + 0, 6, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 80, 0, 0, 7, 66, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, + 0, 0, 1, 54, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 26, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, + 0, 5, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 20, 194, 0, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, + 0, 13, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, + 64, 0, 0, 5, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 20, 82, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 166, 11, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 17, 50, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 13, 0, 0, 0, 28, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 6, 34, 0, 16, 0, 4, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 9, 162, 0, + 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 2, + 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 80, 0, 0, 7, 66, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, + 0, 31, 0, 4, 3, 42, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 34, 0, + 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 18, 0, 0, 1, 32, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, + 1, 64, 0, 0, 5, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 2, 0, 0, + 0, 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 41, 0, 0, 10, + 162, 0, 16, 0, 1, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, + 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 140, 0, 0, 17, 162, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 38, + 0, 0, 11, 0, 208, 0, 0, 98, 0, 16, 0, 6, 0, 0, 0, 6, 1, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 26, 0, + 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 78, 0, 0, 8, 194, + 0, 16, 0, 2, 0, 0, 0, 0, 208, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, + 6, 8, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 35, 0, 0, 10, + 162, 0, 16, 0, 1, 0, 0, 0, 166, 14, 16, 128, 65, 0, 0, 0, 2, 0, 0, + 0, 6, 8, 16, 0, 6, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 38, 0, + 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 6, + 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 35, + 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, + 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 11, 0, 0, 0, 78, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 45, 0, 0, 8, 194, 0, 16, 0, 5, 0, + 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 45, 0, 0, 8, 50, 0, 16, 0, 5, 0, 0, 0, 6, 0, + 16, 0, 6, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, + 0, 0, 8, 50, 0, 16, 0, 7, 0, 0, 0, 86, 5, 16, 0, 6, 0, 0, 0, + 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 194, 0, 16, + 0, 7, 0, 0, 0, 166, 10, 16, 0, 6, 0, 0, 0, 230, 116, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 39, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, + 0, 16, 0, 0, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 31, + 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, + 7, 0, 0, 0, 230, 10, 16, 0, 7, 0, 0, 0, 21, 0, 0, 1, 54, 0, 0, + 5, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 21, 0, + 0, 1, 54, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, 4, 16, 0, 5, + 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, + 138, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 1, 64, 0, 0, 24, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 86, + 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, + 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 22, 11, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, + 0, 0, 54, 0, 0, 5, 194, 0, 16, 0, 7, 0, 0, 0, 246, 11, 16, 0, 7, + 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 14, + 16, 0, 7, 0, 0, 0, 70, 11, 16, 0, 7, 0, 0, 0, 21, 0, 0, 1, 21, + 0, 0, 1, 54, 0, 0, 4, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 2, 0, + 35, 0, 0, 9, 98, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, + 0, 6, 1, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 4, 0, 0, 0, 85, 0, + 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 78, 0, 0, 8, 162, 0, 16, 0, 1, 0, 0, 0, + 0, 208, 0, 0, 6, 8, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, + 0, 41, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 0, + 0, 0, 0, 138, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, + 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 254, 7, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, + 0, 16, 0, 3, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 139, 0, 0, + 15, 194, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, + 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 41, 0, + 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 48, 0, 0, 140, 0, 0, + 11, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, + 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, + 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, + 0, 26, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 140, 0, + 0, 11, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 20, 98, 0, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 19, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 14, 0, 0, + 0, 0, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 50, + 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, + 0, 3, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 246, 15, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 138, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 1, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 32, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 66, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, + 1, 139, 0, 0, 15, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 86, 5, 16, 0, + 1, 0, 0, 0, 42, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 246, 15, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, + 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 82, 0, + 16, 0, 3, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 6, + 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, + 82, 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 128, 3, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 140, 0, + 0, 11, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 22, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 4, 0, 0, 0, 6, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, 4, 0, 0, 0, + 140, 0, 0, 17, 98, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 22, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 13, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, + 0, 0, 0, 86, 6, 16, 0, 4, 0, 0, 0, 35, 0, 0, 12, 98, 0, 16, 0, + 0, 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 86, 6, 16, 0, 0, 0, + 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, + 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, + 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 35, 0, 0, 10, 98, 0, 16, + 0, 0, 0, 0, 0, 86, 7, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 6, 1, + 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 38, 0, 0, 8, 0, + 208, 0, 0, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, 0, 9, + 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 22, 11, + 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 130, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 32, 0, 0, + 10, 114, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 60, + 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 150, 5, 16, 0, 1, 0, 0, 0, + 70, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 230, 4, 16, 0, 5, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 230, 4, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, 0, + 0, 0, 230, 4, 16, 0, 3, 0, 0, 0, 230, 4, 16, 0, 6, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 1, 0, 0, 0, 230, 4, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 230, 4, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, + 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 230, + 4, 16, 0, 5, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, + 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 78, + 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 10, 130, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, + 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, + 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 30, 0, 0, 8, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, + 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 18, + 0, 0, 1, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 54, 0, 0, 5, 130, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 21, 0, 0, 1, 38, 0, + 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 7, 0, 0, 0, 22, 11, 16, 0, + 7, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 21, 0, 0, 1, 32, 0, 0, 10, 210, 0, 16, 0, 0, 0, + 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, + 0, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 6, 2, 16, 0, 0, 0, 0, + 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, + 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, + 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 1, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, + 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 1, 0, + 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 207, 0, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 41, 0, + 0, 0, 9, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_128bpp_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_128bpp_cs.h new file mode 100644 index 0000000..15577ca --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_128bpp_cs.h @@ -0,0 +1,2024 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_resolve_edram_info; // Offset: 0 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 4 Size: 4 +// uint xe_resolve_dest_info; // Offset: 8 Size: 4 +// uint xe_resolve_dest_coordinate_info;// Offset: 12 Size: 4 +// uint xe_resolve_dest_base; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram texture byte r/o T0 t0 1 +// xe_resolve_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][2], immediateIndexed, space=0 +dcl_resource_raw T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 15 +dcl_thread_group 8, 8, 1 +and r0.xyzw, CB0[0][0].zxzz, l(7, 1023, 8, 0x01000000) +ushr r1.xyz, CB0[0][0].yywy, l(4, 5, 10, 0) +ushr r2.xyzw, CB0[0][0].wwww, l(20, 24, 24, 20) +ishl r3.xw, vThreadID.xxxx, l(1, 0, 0, 1) +bfi r1.y, l(11), l(3), r1.y, l(0) +uge r1.y, r3.w, r1.y +if_nz r1.y + ret +endif +ubfe r4.xyzw, l(2, 11, 4, 1), l(10, 13, 24, 28), CB0[0][0].xxxx +mov r1.w, CB0[0][0].y +bfi r1.xy, l(4, 1, 0, 0), l(3, 3, 0, 0), r1.wxww, l(0, 0, 0, 0) +ibfe r1.w, l(6), l(16), CB0[0][0].z +ishl r1.w, r1.w, l(23) +iadd r1.w, r1.w, l(0x3f800000) +bfi r5.x, l(10), l(5), CB0[0][0].w, l(0) +bfi r2.xyzw, l(4, 4, 4, 4), l(3, 3, 3, 3), r2.xyzw, l(0, 0, 0, 0) +ubfe r5.y, l(3), l(28), CB0[0][0].w +mov r3.yz, vThreadID.yyyy +iadd r1.xy, r1.xyxx, r3.wzww +uge r5.z, l(3), r5.y +if_nz r5.z + mov r6.y, r5.y +else + ieq r5.z, r5.y, l(5) + if_nz r5.z + mov r6.y, l(2) + else + mov r6.y, l(0) + endif +endif +uge r5.zw, r4.xxxx, l(0, 0, 2, 1) +and r5.zw, r5.zzzw, l(0, 0, 1, 1) +ishl r1.xy, r1.xyxx, r5.zwzz +ushr r6.x, r6.y, l(1) +and r6.xy, r6.xyxx, l(1, 1, 0, 0) +iadd r1.xy, r1.xyxx, r6.xyxx +ushr r6.x, l(80), r4.w +mov r6.y, l(16) +udiv r6.zw, null, r1.xxxy, r6.xxxy +imad r0.y, r6.w, r0.y, r6.z +iadd r0.y, r0.y, r4.y +imad r1.xy, -r6.zwzz, r6.xyxx, r1.xyxx +imad r1.x, r1.y, r6.x, r1.x +ishl r1.x, r1.x, r4.w +imad r0.y, r0.y, l(1280), r1.x +udiv null, r0.y, r0.y, l(0x00280000) +iadd r1.x, r4.w, r5.z +ishl r1.x, l(1), r1.x +if_nz r4.w + ieq r1.y, r1.x, l(2) + if_nz r1.y + ishl r1.y, r0.y, l(2) + ld_raw r6.xyzw, r1.y, T0[0].zwxy + mov r7.xy, r6.zwzz + else + ishl r1.y, r0.y, l(2) + ld_raw r7.xy, r1.y, T0[0].xyxx + iadd r1.y, r0.y, r1.x + ishl r1.y, r1.y, l(2) + ld_raw r6.xy, r1.y, T0[0].xyxx + endif + switch r4.z + case l(5) + ishl r7.zw, r7.xxxy, l(0, 0, 16, 16) + ishr r8.xyzw, r7.zxwy, l(16, 16, 16, 16) + itof r8.xyzw, r8.xyzw + mul r8.xyzw, r8.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r7.xyzw, r8.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r6.zw, r6.xxxy, l(0, 0, 16, 16) + ishr r8.xyzw, r6.zxwy, l(16, 16, 16, 16) + itof r8.xyzw, r8.xyzw + mul r8.xyzw, r8.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r6.xyzw, r8.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.xy, r7.xyxx, l(16, 16, 0, 0) + f16tof32 r7.xz, r7.xxyx + f16tof32 r7.yw, r4.xxxy + ushr r4.xy, r6.xyxx, l(16, 16, 0, 0) + f16tof32 r6.xz, r6.xxyx + f16tof32 r6.yw, r4.xxxy + break + default + mov r7.zw, l(0,0,0,0) + mov r6.zw, l(0,0,0,0) + break + endswitch +else + ieq r1.y, r1.x, l(1) + if_nz r1.y + ishl r1.y, r0.y, l(2) + ld_raw r6.xy, r1.y, T0[0].yxxx + mov r7.x, r6.y + else + ishl r1.y, r0.y, l(2) + ld_raw r7.x, r1.y, T0[0].xxxx + iadd r1.y, r0.y, r1.x + ishl r1.y, r1.y, l(2) + ld_raw r6.x, r1.y, T0[0].xxxx + endif + switch r4.z + case l(0) + case l(1) + ushr r7.yzw, r7.xxxx, l(0, 8, 16, 24) + and r8.xyzw, r7.xyzw, l(255, 255, 255, 255) + utof r8.xyzw, r8.xyzw + mul r7.xyzw, r8.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r6.yzw, r6.xxxx, l(0, 8, 16, 24) + and r8.xyzw, r6.xyzw, l(255, 255, 255, 255) + utof r8.xyzw, r8.xyzw + mul r6.xyzw, r8.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r7.yzw, r7.xxxx, l(0, 10, 20, 30) + and r8.xyzw, r7.xyzw, l(1023, 1023, 1023, 3) + utof r8.xyzw, r8.xyzw + mul r7.xyzw, r8.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r6.yzw, r6.xxxx, l(0, 10, 20, 30) + and r8.xyzw, r6.xyzw, l(1023, 1023, 1023, 3) + utof r8.xyzw, r8.xyzw + mul r6.xyzw, r8.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r7.yzw, r7.xxxx, l(0, 10, 20, 30) + and r8.xyz, r7.xyzx, l(1023, 1023, 1023, 0) + and r9.xyz, r7.xyzx, l(127, 127, 127, 0) + ubfe r10.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r7.xyzx + firstbit_hi r11.xyz, r9.xyzx + iadd r11.xyz, r11.xyzx, l(-24, -24, -24, 0) + movc r11.xyz, r9.xyzx, r11.xyzx, l(8,8,8,0) + iadd r12.xyz, -r11.xyzx, l(1, 1, 1, 0) + movc r12.xyz, r10.xyzx, r10.xyzx, r12.xyzx + bfi r11.xyz, l(7, 7, 7, 0), r11.xyzx, r7.xyzx, l(0, 0, 0, 0) + and r11.xyz, r11.xyzx, l(127, 127, 127, 0) + movc r9.xyz, r10.xyzx, r9.xyzx, r11.xyzx + ishl r10.xyz, r12.xyzx, l(23, 23, 23, 0) + iadd r10.xyz, r10.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r9.xyz, r9.xyzx, l(16, 16, 16, 0) + iadd r9.xyz, r10.xyzx, r9.xyzx + movc r7.xyz, r8.xyzx, r9.xyzx, l(0,0,0,0) + utof r1.y, r7.w + mul r7.w, r1.y, l(0.333333) + ushr r6.yzw, r6.xxxx, l(0, 10, 20, 30) + and r8.xyz, r6.xyzx, l(1023, 1023, 1023, 0) + and r9.xyz, r6.xyzx, l(127, 127, 127, 0) + ubfe r10.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r6.xyzx + firstbit_hi r11.xyz, r9.xyzx + iadd r11.xyz, r11.xyzx, l(-24, -24, -24, 0) + movc r11.xyz, r9.xyzx, r11.xyzx, l(8,8,8,0) + iadd r12.xyz, -r11.xyzx, l(1, 1, 1, 0) + movc r12.xyz, r10.xyzx, r10.xyzx, r12.xyzx + bfi r11.xyz, l(7, 7, 7, 0), r11.xyzx, r6.xyzx, l(0, 0, 0, 0) + and r11.xyz, r11.xyzx, l(127, 127, 127, 0) + movc r9.xyz, r10.xyzx, r9.xyzx, r11.xyzx + ishl r10.xyz, r12.xyzx, l(23, 23, 23, 0) + iadd r10.xyz, r10.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r9.xyz, r9.xyzx, l(16, 16, 16, 0) + iadd r9.xyz, r10.xyzx, r9.xyzx + movc r6.xyz, r8.xyzx, r9.xyzx, l(0,0,0,0) + utof r1.y, r6.w + mul r6.w, r1.y, l(0.333333) + break + case l(4) + ishl r7.y, r7.x, l(16) + ishr r4.xy, r7.yxyy, l(16, 16, 0, 0) + itof r4.xy, r4.xyxx + mul r4.xy, r4.xyxx, l(0.000977, 0.000977, 0.000000, 0.000000) + max r7.xy, r4.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + ishl r6.y, r6.x, l(16) + ishr r4.xy, r6.yxyy, l(16, 16, 0, 0) + itof r4.xy, r4.xyxx + mul r4.xy, r4.xyxx, l(0.000977, 0.000977, 0.000000, 0.000000) + max r6.xy, r4.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r7.zw, l(0,0,0,0) + mov r6.zw, l(0,0,0,0) + break + case l(6) + ushr r1.y, r7.x, l(16) + f16tof32 r7.x, r7.x + f16tof32 r7.y, r1.y + ushr r1.y, r6.x, l(16) + f16tof32 r6.x, r6.x + f16tof32 r6.y, r1.y + mov r7.zw, l(0,0,0,0) + mov r6.zw, l(0,0,0,0) + break + default + mov r7.yzw, l(0,0,0,0) + mov r6.yzw, l(0,0,0,0) + break + endswitch +endif +uge r1.y, r5.y, l(4) +if_nz r1.y + mul r1.y, r1.w, l(0.500000) + iadd r4.x, r0.y, l(80) + if_nz r4.w + ieq r4.y, r1.x, l(2) + if_nz r4.y + ishl r4.y, r4.x, l(2) + ld_raw r8.xyzw, r4.y, T0[0].zwxy + mov r9.xy, r8.zwzz + else + ishl r4.y, r4.x, l(2) + ld_raw r9.xy, r4.y, T0[0].xyxx + iadd r4.y, r1.x, r4.x + ishl r4.y, r4.y, l(2) + ld_raw r8.xy, r4.y, T0[0].xyxx + endif + switch r4.z + case l(5) + ishl r9.zw, r9.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r9.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r8.zw, r8.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r8.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r5.zw, r9.xxxy, l(0, 0, 16, 16) + f16tof32 r9.xz, r9.xxyx + f16tof32 r9.yw, r5.zzzw + ushr r5.zw, r8.xxxy, l(0, 0, 16, 16) + f16tof32 r8.xz, r8.xxyx + f16tof32 r8.yw, r5.zzzw + break + default + mov r9.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + endswitch + else + ieq r4.y, r1.x, l(1) + if_nz r4.y + ishl r4.y, r4.x, l(2) + ld_raw r8.xy, r4.y, T0[0].yxxx + mov r9.x, r8.y + else + ishl r4.y, r4.x, l(2) + ld_raw r9.x, r4.y, T0[0].xxxx + iadd r4.y, r1.x, r4.x + ishl r4.y, r4.y, l(2) + ld_raw r8.x, r4.y, T0[0].xxxx + endif + switch r4.z + case l(0) + case l(1) + ushr r9.yzw, r9.xxxx, l(0, 8, 16, 24) + and r10.xyzw, r9.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r8.yzw, r8.xxxx, l(0, 8, 16, 24) + and r10.xyzw, r8.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r9.yzw, r9.xxxx, l(0, 10, 20, 30) + and r10.xyzw, r9.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r8.yzw, r8.xxxx, l(0, 10, 20, 30) + and r10.xyzw, r8.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r9.yzw, r9.xxxx, l(0, 10, 20, 30) + and r10.xyz, r9.xyzx, l(1023, 1023, 1023, 0) + and r11.xyz, r9.xyzx, l(127, 127, 127, 0) + ubfe r12.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r9.xyzx + firstbit_hi r13.xyz, r11.xyzx + iadd r13.xyz, r13.xyzx, l(-24, -24, -24, 0) + movc r13.xyz, r11.xyzx, r13.xyzx, l(8,8,8,0) + iadd r14.xyz, -r13.xyzx, l(1, 1, 1, 0) + movc r14.xyz, r12.xyzx, r12.xyzx, r14.xyzx + bfi r13.xyz, l(7, 7, 7, 0), r13.xyzx, r9.xyzx, l(0, 0, 0, 0) + and r13.xyz, r13.xyzx, l(127, 127, 127, 0) + movc r11.xyz, r12.xyzx, r11.xyzx, r13.xyzx + ishl r12.xyz, r14.xyzx, l(23, 23, 23, 0) + iadd r12.xyz, r12.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r11.xyz, r11.xyzx, l(16, 16, 16, 0) + iadd r11.xyz, r12.xyzx, r11.xyzx + movc r9.xyz, r10.xyzx, r11.xyzx, l(0,0,0,0) + utof r4.y, r9.w + mul r9.w, r4.y, l(0.333333) + ushr r8.yzw, r8.xxxx, l(0, 10, 20, 30) + and r10.xyz, r8.xyzx, l(1023, 1023, 1023, 0) + and r11.xyz, r8.xyzx, l(127, 127, 127, 0) + ubfe r12.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r8.xyzx + firstbit_hi r13.xyz, r11.xyzx + iadd r13.xyz, r13.xyzx, l(-24, -24, -24, 0) + movc r13.xyz, r11.xyzx, r13.xyzx, l(8,8,8,0) + iadd r14.xyz, -r13.xyzx, l(1, 1, 1, 0) + movc r14.xyz, r12.xyzx, r12.xyzx, r14.xyzx + bfi r13.xyz, l(7, 7, 7, 0), r13.xyzx, r8.xyzx, l(0, 0, 0, 0) + and r13.xyz, r13.xyzx, l(127, 127, 127, 0) + movc r11.xyz, r12.xyzx, r11.xyzx, r13.xyzx + ishl r12.xyz, r14.xyzx, l(23, 23, 23, 0) + iadd r12.xyz, r12.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r11.xyz, r11.xyzx, l(16, 16, 16, 0) + iadd r11.xyz, r12.xyzx, r11.xyzx + movc r8.xyz, r10.xyzx, r11.xyzx, l(0,0,0,0) + utof r4.y, r8.w + mul r8.w, r4.y, l(0.333333) + break + case l(4) + ishl r9.y, r9.x, l(16) + ishr r5.zw, r9.yyyx, l(0, 0, 16, 16) + itof r5.zw, r5.zzzw + mul r5.zw, r5.zzzw, l(0.000000, 0.000000, 0.000977, 0.000977) + max r9.xy, r5.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + ishl r8.y, r8.x, l(16) + ishr r5.zw, r8.yyyx, l(0, 0, 16, 16) + itof r5.zw, r5.zzzw + mul r5.zw, r5.zzzw, l(0.000000, 0.000000, 0.000977, 0.000977) + max r8.xy, r5.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r9.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + case l(6) + ushr r4.y, r9.x, l(16) + f16tof32 r9.x, r9.x + f16tof32 r9.y, r4.y + ushr r4.y, r8.x, l(16) + f16tof32 r8.x, r8.x + f16tof32 r8.y, r4.y + mov r9.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + default + mov r9.yzw, l(0,0,0,0) + mov r8.yzw, l(0,0,0,0) + break + endswitch + endif + add r7.xyzw, r7.xyzw, r9.xyzw + add r6.xyzw, r6.xyzw, r8.xyzw + uge r4.y, r5.y, l(6) + if_nz r4.y + ishl r4.y, l(1), r4.w + mul r1.w, r1.w, l(0.250000) + iadd r0.y, r0.y, r4.y + if_nz r4.w + ieq r5.y, r1.x, l(2) + if_nz r5.y + ishl r5.y, r0.y, l(2) + ld_raw r8.xyzw, r5.y, T0[0].zwxy + mov r9.xy, r8.zwzz + else + ishl r5.y, r0.y, l(2) + ld_raw r9.xy, r5.y, T0[0].xyxx + iadd r5.y, r1.x, r0.y + ishl r5.y, r5.y, l(2) + ld_raw r8.xy, r5.y, T0[0].xyxx + endif + switch r4.z + case l(5) + ishl r9.zw, r9.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r9.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r8.zw, r8.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r8.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r5.yz, r9.xxyx, l(0, 16, 16, 0) + f16tof32 r9.xz, r9.xxyx + f16tof32 r9.yw, r5.yyyz + ushr r5.yz, r8.xxyx, l(0, 16, 16, 0) + f16tof32 r8.xz, r8.xxyx + f16tof32 r8.yw, r5.yyyz + break + default + mov r9.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + endswitch + else + ieq r5.y, r1.x, l(1) + if_nz r5.y + ishl r5.y, r0.y, l(2) + ld_raw r8.xy, r5.y, T0[0].yxxx + mov r9.x, r8.y + else + ishl r5.y, r0.y, l(2) + ld_raw r9.x, r5.y, T0[0].xxxx + iadd r0.y, r1.x, r0.y + ishl r0.y, r0.y, l(2) + ld_raw r8.x, r0.y, T0[0].xxxx + endif + switch r4.z + case l(0) + case l(1) + ushr r9.yzw, r9.xxxx, l(0, 8, 16, 24) + and r10.xyzw, r9.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r8.yzw, r8.xxxx, l(0, 8, 16, 24) + and r10.xyzw, r8.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r9.yzw, r9.xxxx, l(0, 10, 20, 30) + and r10.xyzw, r9.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r8.yzw, r8.xxxx, l(0, 10, 20, 30) + and r10.xyzw, r8.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r9.yzw, r9.xxxx, l(0, 10, 20, 30) + and r5.yzw, r9.xxyz, l(0, 1023, 1023, 1023) + and r10.xyz, r9.xyzx, l(127, 127, 127, 0) + ubfe r11.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r9.xyzx + firstbit_hi r12.xyz, r10.xyzx + iadd r12.xyz, r12.xyzx, l(-24, -24, -24, 0) + movc r12.xyz, r10.xyzx, r12.xyzx, l(8,8,8,0) + iadd r13.xyz, -r12.xyzx, l(1, 1, 1, 0) + movc r13.xyz, r11.xyzx, r11.xyzx, r13.xyzx + bfi r12.xyz, l(7, 7, 7, 0), r12.xyzx, r9.xyzx, l(0, 0, 0, 0) + and r12.xyz, r12.xyzx, l(127, 127, 127, 0) + movc r10.xyz, r11.xyzx, r10.xyzx, r12.xyzx + ishl r11.xyz, r13.xyzx, l(23, 23, 23, 0) + iadd r11.xyz, r11.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r10.xyz, r10.xyzx, l(16, 16, 16, 0) + iadd r10.xyz, r11.xyzx, r10.xyzx + movc r9.xyz, r5.yzwy, r10.xyzx, l(0,0,0,0) + utof r0.y, r9.w + mul r9.w, r0.y, l(0.333333) + ushr r8.yzw, r8.xxxx, l(0, 10, 20, 30) + and r5.yzw, r8.xxyz, l(0, 1023, 1023, 1023) + and r10.xyz, r8.xyzx, l(127, 127, 127, 0) + ubfe r11.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r8.xyzx + firstbit_hi r12.xyz, r10.xyzx + iadd r12.xyz, r12.xyzx, l(-24, -24, -24, 0) + movc r12.xyz, r10.xyzx, r12.xyzx, l(8,8,8,0) + iadd r13.xyz, -r12.xyzx, l(1, 1, 1, 0) + movc r13.xyz, r11.xyzx, r11.xyzx, r13.xyzx + bfi r12.xyz, l(7, 7, 7, 0), r12.xyzx, r8.xyzx, l(0, 0, 0, 0) + and r12.xyz, r12.xyzx, l(127, 127, 127, 0) + movc r10.xyz, r11.xyzx, r10.xyzx, r12.xyzx + ishl r11.xyz, r13.xyzx, l(23, 23, 23, 0) + iadd r11.xyz, r11.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r10.xyz, r10.xyzx, l(16, 16, 16, 0) + iadd r10.xyz, r11.xyzx, r10.xyzx + movc r8.xyz, r5.yzwy, r10.xyzx, l(0,0,0,0) + utof r0.y, r8.w + mul r8.w, r0.y, l(0.333333) + break + case l(4) + ishl r9.y, r9.x, l(16) + ishr r5.yz, r9.yyxy, l(0, 16, 16, 0) + itof r5.yz, r5.yyzy + mul r5.yz, r5.yyzy, l(0.000000, 0.000977, 0.000977, 0.000000) + max r9.xy, r5.yzyy, l(-1.000000, -1.000000, 0.000000, 0.000000) + ishl r8.y, r8.x, l(16) + ishr r5.yz, r8.yyxy, l(0, 16, 16, 0) + itof r5.yz, r5.yyzy + mul r5.yz, r5.yyzy, l(0.000000, 0.000977, 0.000977, 0.000000) + max r8.xy, r5.yzyy, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r9.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + case l(6) + ushr r0.y, r9.x, l(16) + f16tof32 r9.x, r9.x + f16tof32 r9.y, r0.y + ushr r0.y, r8.x, l(16) + f16tof32 r8.x, r8.x + f16tof32 r8.y, r0.y + mov r9.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + default + mov r9.yzw, l(0,0,0,0) + mov r8.yzw, l(0,0,0,0) + break + endswitch + endif + add r9.xyzw, r7.xyzw, r9.xyzw + add r8.xyzw, r6.xyzw, r8.xyzw + iadd r0.y, r4.y, r4.x + if_nz r4.w + ieq r4.x, r1.x, l(2) + if_nz r4.x + ishl r4.x, r0.y, l(2) + ld_raw r10.xyzw, r4.x, T0[0].zwxy + mov r11.xy, r10.zwzz + else + ishl r4.x, r0.y, l(2) + ld_raw r11.xy, r4.x, T0[0].xyxx + iadd r4.x, r1.x, r0.y + ishl r4.x, r4.x, l(2) + ld_raw r10.xy, r4.x, T0[0].xyxx + endif + switch r4.z + case l(5) + ishl r11.zw, r11.xxxy, l(0, 0, 16, 16) + ishr r12.xyzw, r11.zxwy, l(16, 16, 16, 16) + itof r12.xyzw, r12.xyzw + mul r12.xyzw, r12.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r11.xyzw, r12.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r10.zw, r10.xxxy, l(0, 0, 16, 16) + ishr r12.xyzw, r10.zxwy, l(16, 16, 16, 16) + itof r12.xyzw, r12.xyzw + mul r12.xyzw, r12.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r10.xyzw, r12.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.xy, r11.xyxx, l(16, 16, 0, 0) + f16tof32 r11.xz, r11.xxyx + f16tof32 r11.yw, r4.xxxy + ushr r4.xy, r10.xyxx, l(16, 16, 0, 0) + f16tof32 r10.xz, r10.xxyx + f16tof32 r10.yw, r4.xxxy + break + default + mov r11.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + break + endswitch + else + ieq r4.x, r1.x, l(1) + if_nz r4.x + ishl r4.x, r0.y, l(2) + ld_raw r10.xy, r4.x, T0[0].yxxx + mov r11.x, r10.y + else + ishl r4.x, r0.y, l(2) + ld_raw r11.x, r4.x, T0[0].xxxx + iadd r0.y, r1.x, r0.y + ishl r0.y, r0.y, l(2) + ld_raw r10.x, r0.y, T0[0].xxxx + endif + switch r4.z + case l(0) + case l(1) + ushr r11.yzw, r11.xxxx, l(0, 8, 16, 24) + and r4.xyzw, r11.xyzw, l(255, 255, 255, 255) + utof r4.xyzw, r4.xyzw + mul r11.xyzw, r4.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r10.yzw, r10.xxxx, l(0, 8, 16, 24) + and r4.xyzw, r10.xyzw, l(255, 255, 255, 255) + utof r4.xyzw, r4.xyzw + mul r10.xyzw, r4.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r11.yzw, r11.xxxx, l(0, 10, 20, 30) + and r4.xyzw, r11.xyzw, l(1023, 1023, 1023, 3) + utof r4.xyzw, r4.xyzw + mul r11.xyzw, r4.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r10.yzw, r10.xxxx, l(0, 10, 20, 30) + and r4.xyzw, r10.xyzw, l(1023, 1023, 1023, 3) + utof r4.xyzw, r4.xyzw + mul r10.xyzw, r4.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r11.yzw, r11.xxxx, l(0, 10, 20, 30) + and r4.xyz, r11.xyzx, l(1023, 1023, 1023, 0) + and r5.yzw, r11.xxyz, l(0, 127, 127, 127) + ubfe r12.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r11.xyzx + firstbit_hi r13.xyz, r5.yzwy + iadd r13.xyz, r13.xyzx, l(-24, -24, -24, 0) + movc r13.xyz, r5.yzwy, r13.xyzx, l(8,8,8,0) + iadd r14.xyz, -r13.xyzx, l(1, 1, 1, 0) + movc r14.xyz, r12.xyzx, r12.xyzx, r14.xyzx + bfi r13.xyz, l(7, 7, 7, 0), r13.xyzx, r11.xyzx, l(0, 0, 0, 0) + and r13.xyz, r13.xyzx, l(127, 127, 127, 0) + movc r5.yzw, r12.xxyz, r5.yyzw, r13.xxyz + ishl r12.xyz, r14.xyzx, l(23, 23, 23, 0) + iadd r12.xyz, r12.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r5.yzw, r5.yyzw, l(0, 16, 16, 16) + iadd r5.yzw, r12.xxyz, r5.yyzw + movc r11.xyz, r4.xyzx, r5.yzwy, l(0,0,0,0) + utof r0.y, r11.w + mul r11.w, r0.y, l(0.333333) + ushr r10.yzw, r10.xxxx, l(0, 10, 20, 30) + and r4.xyz, r10.xyzx, l(1023, 1023, 1023, 0) + and r5.yzw, r10.xxyz, l(0, 127, 127, 127) + ubfe r12.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r10.xyzx + firstbit_hi r13.xyz, r5.yzwy + iadd r13.xyz, r13.xyzx, l(-24, -24, -24, 0) + movc r13.xyz, r5.yzwy, r13.xyzx, l(8,8,8,0) + iadd r14.xyz, -r13.xyzx, l(1, 1, 1, 0) + movc r14.xyz, r12.xyzx, r12.xyzx, r14.xyzx + bfi r13.xyz, l(7, 7, 7, 0), r13.xyzx, r10.xyzx, l(0, 0, 0, 0) + and r13.xyz, r13.xyzx, l(127, 127, 127, 0) + movc r5.yzw, r12.xxyz, r5.yyzw, r13.xxyz + ishl r12.xyz, r14.xyzx, l(23, 23, 23, 0) + iadd r12.xyz, r12.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r5.yzw, r5.yyzw, l(0, 16, 16, 16) + iadd r5.yzw, r12.xxyz, r5.yyzw + movc r10.xyz, r4.xyzx, r5.yzwy, l(0,0,0,0) + utof r0.y, r10.w + mul r10.w, r0.y, l(0.333333) + break + case l(4) + ishl r11.y, r11.x, l(16) + ishr r4.xy, r11.yxyy, l(16, 16, 0, 0) + itof r4.xy, r4.xyxx + mul r4.xy, r4.xyxx, l(0.000977, 0.000977, 0.000000, 0.000000) + max r11.xy, r4.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + ishl r10.y, r10.x, l(16) + ishr r4.xy, r10.yxyy, l(16, 16, 0, 0) + itof r4.xy, r4.xyxx + mul r4.xy, r4.xyxx, l(0.000977, 0.000977, 0.000000, 0.000000) + max r10.xy, r4.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r11.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + break + case l(6) + ushr r0.y, r11.x, l(16) + f16tof32 r11.x, r11.x + f16tof32 r11.y, r0.y + ushr r0.y, r10.x, l(16) + f16tof32 r10.x, r10.x + f16tof32 r10.y, r0.y + mov r11.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + break + default + mov r11.yzw, l(0,0,0,0) + mov r10.yzw, l(0,0,0,0) + break + endswitch + endif + add r7.xyzw, r9.xyzw, r11.xyzw + add r6.xyzw, r8.xyzw, r10.xyzw + else + mov r1.w, r1.y + endif +endif +mul r4.xyzw, r1.wwww, r7.xyzw +mul r6.xyzw, r1.wwww, r6.xyzw +if_nz r0.w + mov r4.xz, r4.zzxz + mov r6.xz, r6.zzxz +endif +iadd r2.xyzw, r2.xyzw, r3.xyzw +if_nz r0.z + ubfe r0.y, l(3), l(4), CB0[0][0].z + ishl r0.z, r1.z, l(5) + ishr r1.xyzw, r2.zwzw, l(4, 5, 3, 3) + ishr r0.w, r0.y, l(2) + ushr r0.z, r0.z, l(4) + and r0.z, r0.z, l(2046) + imad r0.z, r0.w, r0.z, r1.x + ushr r1.x, r5.x, l(5) + imad r0.z, r0.z, r1.x, r1.y + ishl r1.x, r2.z, l(12) + and r1.x, r1.x, l(0x00006000) + bfi r1.x, l(3), l(10), r2.w, r1.x + ishr r1.x, r1.x, l(6) + iadd r0.w, r0.w, r1.z + bfi r1.y, l(1), l(1), r0.w, l(0) + iadd r1.y, r1.y, r1.w + bfi r1.y, l(2), l(1), r1.y, l(0) + bfi r0.w, l(1), l(0), r0.w, r1.y + bfi r1.yz, l(0, 18, 18, 0), l(0, 12, 15, 0), r0.zzzz, l(0, 0, 0, 0) + imad r1.xy, r1.xxxx, l(2, 16, 0, 0), r1.yzyy + bfi r0.yz, l(0, 2, 2, 0), l(0, 10, 13, 0), r0.yyyy, r1.xxyx + bfi r1.x, l(1), l(4), r2.z, l(0) + ubfe r1.y, l(3), l(6), r0.y + and r1.z, r0.w, l(6) + bfi r0.w, l(1), l(8), r0.w, l(0) + imad r0.w, r1.y, l(32), r0.w + imad r0.w, r1.z, l(4), r0.w + bfi r0.yz, l(0, 6, 6, 0), l(0, 0, 3, 0), r1.xxxx, r0.yyzy + bfi r0.z, l(9), l(3), r0.w, r0.z + bfi r0.y, l(6), l(0), r0.y, r0.z +else + ishr r1.xyzw, r2.xyzw, l(5, 5, 2, 3) + ushr r0.z, r5.x, l(5) + imad r0.z, r1.y, r0.z, r1.x + ishl r0.w, r2.z, l(7) + and r1.xy, r0.wwww, l(1792, 2048, 0, 0) + bfi r0.w, l(3), l(5), r2.w, r1.x + bfi r0.w, l(21), l(11), r0.z, r0.w + bfi r2.x, l(1), l(4), r2.z, l(0) + iadd r0.w, r0.w, r2.x + ishl r2.yz, r1.xxxx, l(0, 3, 2, 0) + bfi r2.yz, l(0, 3, 3, 0), l(0, 8, 7, 0), r2.wwww, r2.yyzy + bfi r2.yz, l(0, 21, 21, 0), l(0, 14, 13, 0), r0.zzzz, r2.yyzy + imad r2.xy, r2.xxxx, l(8, 4, 0, 0), r2.yzyy + bfi r0.z, l(12), l(0), r1.y, r2.x + and r1.x, r2.y, l(1792) + iadd r0.z, r0.z, r1.x + and r1.x, r1.z, l(2) + iadd r1.x, r1.w, r1.x + bfi r1.x, l(2), l(6), r1.x, l(0) + iadd r0.z, r0.z, r1.x + bfi r0.y, l(6), l(0), r0.w, r0.z +endif +iadd r0.y, r0.y, CB0[0][1].x +ushr r0.y, r0.y, l(4) +ieq r0.z, r0.x, l(5) +if_nz r0.z + mov r4.yw, r4.wwwy + mov r4.xyzw, r4.yzwx + mov r0.w, l(2) +else + mov r0.w, r0.x +endif +ieq r1.x, r0.w, l(4) +if_nz r1.x + mov r4.xyzw, r4.yxwz + mov r0.w, l(2) +endif +ieq r1.xyz, r0.wwww, l(1, 2, 3, 0) +or r1.xy, r1.yzyy, r1.xyxx +if_nz r1.x + ishl r2.xyzw, r4.xyzw, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r3.xyzw, r4.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r4.xyzw, r2.xyzw, r3.xyzw +endif +if_nz r1.y + ushr r1.xyzw, r4.xyzw, l(16, 16, 16, 16) + bfi r4.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r4.xyzw, r1.xyzw +endif +store_uav_typed U0[0].xyzw, r0.yyyy, r4.xyzw +iadd r0.y, r0.y, l(2) +if_nz r0.z + mov r6.yw, r6.wwwy + mov r6.xyzw, r6.yzwx + mov r0.x, l(2) +endif +ieq r0.z, r0.x, l(4) +if_nz r0.z + mov r6.xyzw, r6.yxwz + mov r0.x, l(2) +endif +ieq r0.xzw, r0.xxxx, l(1, 0, 2, 3) +or r0.xz, r0.zzwz, r0.xxzx +if_nz r0.x + ishl r1.xyzw, r6.xyzw, l(8, 8, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r2.xyzw, r6.xyzw, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r6.xyzw, r1.xyzw, r2.xyzw +endif +if_nz r0.z + ushr r1.xyzw, r6.xyzw, l(16, 16, 16, 16) + bfi r6.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r6.xyzw, r1.xyzw +endif +store_uav_typed U0[0].xyzw, r0.yyyy, r6.xyzw +ret +// Approximately 769 instruction slots used +#endif + +const BYTE resolve_full_128bpp_cs[] = { + 68, 88, 66, 67, 193, 104, 59, 219, 24, 74, 5, 1, 110, 111, 132, 110, 26, 59, 6, + 57, 1, 0, 0, 0, 56, 89, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 208, 2, + 0, 0, 224, 2, 0, 0, 240, 2, 0, 0, 156, 88, 0, 0, 82, 68, 69, 70, 148, + 2, 0, 0, 1, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 105, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 101, 100, 114, 97, 109, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 213, 0, 0, 0, 5, 0, 0, 0, 252, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 196, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 4, 2, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 31, 2, 0, 0, 8, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 52, 2, 0, 0, 12, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 84, 2, 0, + 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, + 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 101, 100, 114, 97, 109, 95, 105, 110, 102, + 111, 0, 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 218, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 99, 111, + 111, 114, 100, 105, 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 105, 110, 102, 111, 0, 120, 101, 95, + 114, 101, 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 99, 111, 111, 114, 100, 105, + 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 95, 98, 97, 115, 101, 0, 77, 105, 99, 114, 111, 115, 111, + 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, + 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, + 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 164, 85, 0, 0, + 81, 0, 5, 0, 105, 21, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 161, 0, 0, 6, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 95, 0, 0, + 2, 50, 0, 2, 0, 104, 0, 0, 2, 15, 0, 0, 0, 155, 0, 0, 4, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, 242, 0, 16, 0, 0, + 0, 0, 0, 38, 138, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 255, 3, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 1, 85, 0, 0, 12, 114, 0, 16, 0, 1, 0, 0, 0, 86, 135, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, + 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, 242, 0, 16, 0, + 2, 0, 0, 0, 246, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 20, 0, + 0, 0, 41, 0, 0, 9, 146, 0, 16, 0, 3, 0, 0, 0, 6, 0, 2, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, + 26, 0, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 17, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 11, 0, + 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 13, + 0, 0, 0, 24, 0, 0, 0, 28, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, + 0, 20, 50, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 15, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 139, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 128, 63, 140, 0, 0, 13, 18, 0, 16, 0, 5, 0, 0, 0, + 1, 64, 0, 0, 10, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 58, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, + 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 138, 0, 0, 11, 34, 0, 16, 0, 5, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 58, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 4, 98, 0, 16, + 0, 3, 0, 0, 0, 86, 5, 2, 0, 30, 0, 0, 7, 50, 0, 16, 0, 1, 0, + 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 182, 15, 16, 0, 3, 0, 0, 0, 80, + 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 26, 0, 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 5, 0, 0, + 0, 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 5, 0, + 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 26, + 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 34, 0, + 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 21, + 0, 0, 1, 80, 0, 0, 10, 194, 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 5, 0, 0, 0, 166, 14, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, + 70, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 6, 0, 0, 0, 70, + 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, + 0, 70, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 6, 0, 0, 0, 85, 0, + 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 80, 0, 0, 0, 58, + 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, + 1, 64, 0, 0, 16, 0, 0, 0, 78, 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, + 0, 0, 208, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 6, 0, + 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, + 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 4, 0, 0, 0, 35, 0, 0, 10, 50, 0, 16, 0, 1, 0, + 0, 0, 230, 10, 16, 128, 65, 0, 0, 0, 6, 0, 0, 0, 70, 0, 16, 0, 6, + 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 35, + 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 5, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 78, 0, 0, + 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 40, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, + 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 4, 0, + 0, 0, 32, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, + 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, + 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 230, 116, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 7, 0, 0, 0, + 230, 10, 16, 0, 6, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, + 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 70, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, + 0, 4, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, + 0, 10, 194, 0, 16, 0, 7, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 42, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 38, 7, 16, 0, 7, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 6, 0, 0, 0, + 6, 4, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 8, 0, + 0, 0, 38, 7, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, + 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 1, + 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, + 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, + 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, 10, 50, 0, + 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, + 82, 0, 16, 0, 7, 0, 0, 0, 6, 1, 16, 0, 7, 0, 0, 0, 131, 0, 0, + 5, 162, 0, 16, 0, 7, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 85, 0, + 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 131, 0, 0, 5, 82, 0, 16, 0, 6, 0, 0, 0, 6, 1, 16, 0, 6, 0, 0, + 0, 131, 0, 0, 5, 162, 0, 16, 0, 6, 0, 0, 0, 6, 4, 16, 0, 4, 0, + 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 194, 0, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 22, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 18, 0, 0, + 1, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 7, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, + 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, 1, 64, + 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 85, + 0, 0, 10, 226, 0, 16, 0, 7, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, + 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, + 8, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, + 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 6, + 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, + 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 8, + 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, + 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, + 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 7, 0, 0, 0, 6, 0, 16, 0, + 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, + 70, 14, 16, 0, 8, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, + 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, + 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 6, + 0, 0, 0, 6, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, + 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, + 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 2, 0, + 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, 1, + 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 7, 0, 0, 0, + 6, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, + 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 8, 0, + 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, + 9, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 135, 0, 0, + 5, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 30, 0, + 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, + 55, 0, 0, 12, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, + 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 12, + 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, + 9, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, + 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 140, 0, 0, 17, 114, + 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, + 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, + 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 9, 0, 0, + 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 70, 2, + 16, 0, 11, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, + 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, + 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, + 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, + 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 9, + 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, + 0, 9, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 9, 0, + 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 8, + 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 34, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 56, 0, 0, 7, 130, 0, + 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 171, + 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, + 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, + 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, + 0, 11, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 30, 0, 0, 10, 114, 0, + 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 232, + 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, + 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 70, 2, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 12, 0, 0, 0, 70, + 2, 16, 128, 65, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, + 0, 12, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, + 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, + 0, 10, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 11, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, + 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, + 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 55, 0, + 0, 12, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, + 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 34, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 6, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 6, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 171, 170, 170, 62, 2, + 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, + 0, 16, 0, 0, 0, 42, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 22, 5, + 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 5, 50, 0, 16, 0, 4, 0, 0, 0, + 70, 0, 16, 0, 4, 0, 0, 0, 56, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, + 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, + 128, 58, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 7, + 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, + 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, + 0, 6, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, + 0, 0, 42, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 22, 5, 16, 0, 6, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 43, 0, 0, 5, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 56, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 6, 0, 0, 0, + 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, 7, 34, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 16, + 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, + 7, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 18, + 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 131, 0, 0, 5, + 34, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, + 8, 194, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 6, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 226, 0, 16, + 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, 80, 0, 0, 7, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 34, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 63, 30, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 80, 0, 0, 0, 31, 0, 4, 3, 58, 0, + 16, 0, 4, 0, 0, 0, 32, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 10, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, + 26, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, + 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, + 0, 8, 242, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 230, + 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, + 9, 0, 0, 0, 230, 10, 16, 0, 8, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, + 7, 34, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 9, 0, 0, 0, 26, + 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, + 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 50, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, + 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, + 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, + 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 9, 0, 0, 0, 6, 4, 16, 0, 9, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 38, 7, 16, + 0, 9, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 9, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, + 8, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, + 16, 0, 10, 0, 0, 0, 38, 7, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, + 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 85, 0, + 0, 10, 194, 0, 16, 0, 5, 0, 0, 0, 6, 4, 16, 0, 9, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 131, 0, 0, 5, 82, 0, 16, 0, 9, 0, 0, 0, 6, 1, 16, 0, 9, 0, 0, + 0, 131, 0, 0, 5, 162, 0, 16, 0, 9, 0, 0, 0, 166, 14, 16, 0, 5, 0, + 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 5, 0, 0, 0, 6, 4, 16, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 8, 0, 0, 0, 6, 1, 16, + 0, 8, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 8, 0, 0, 0, 166, 14, + 16, 0, 5, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 194, + 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, 34, + 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, + 7, 34, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 8, 0, 0, 0, 26, + 0, 16, 0, 4, 0, 0, 0, 22, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, + 0, 18, 0, 0, 1, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 18, + 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, + 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 8, 0, 0, 0, + 26, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, 0, + 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, + 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, + 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, + 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, + 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, + 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 8, + 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, + 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, + 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, + 64, 0, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 9, 0, 0, 0, + 6, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, + 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 8, 32, + 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, + 0, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, + 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, + 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, + 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, + 9, 0, 0, 0, 6, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 114, 0, + 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, + 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, + 0, 15, 114, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, + 0, 135, 0, 0, 5, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, + 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, + 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, + 0, 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, + 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 13, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 55, 0, 0, 9, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, + 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 140, + 0, 0, 17, 114, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, + 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, + 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, + 0, 11, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, + 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 12, + 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, + 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, + 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, + 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, + 16, 0, 11, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 9, 0, 0, 0, 70, + 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, + 5, 34, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 56, 0, + 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, + 64, 0, 0, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 8, 0, 0, 0, + 6, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, + 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 10, 0, + 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, + 11, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 135, 0, 0, + 5, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 30, 0, + 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, + 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, + 55, 0, 0, 12, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, + 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 14, + 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, + 9, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, + 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 140, 0, 0, 17, 114, + 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, + 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, + 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, + 16, 0, 13, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, + 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, + 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, + 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, + 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 11, + 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, + 0, 11, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, + 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 10, + 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 34, 0, 16, + 0, 4, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 56, 0, 0, 7, 130, 0, + 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 171, + 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, + 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, + 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 194, 0, 16, 0, 5, 0, + 0, 0, 86, 1, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 194, 0, 16, 0, + 5, 0, 0, 0, 166, 14, 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 194, 0, 16, + 0, 5, 0, 0, 0, 166, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, + 0, 16, 0, 9, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 34, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 1, 64, + 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 194, 0, 16, 0, 5, 0, 0, 0, 86, + 1, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 194, 0, 16, 0, 5, 0, 0, + 0, 166, 14, 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 194, 0, 16, 0, 5, 0, + 0, 0, 166, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, + 8, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, + 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 1, + 64, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, + 10, 0, 16, 0, 9, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 9, 0, 0, + 0, 26, 0, 16, 0, 4, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 4, 0, + 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 131, + 0, 0, 5, 18, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, + 131, 0, 0, 5, 34, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, + 0, 54, 0, 0, 8, 194, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, + 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, + 8, 226, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, 0, 0, 0, + 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, + 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 80, 0, 0, 7, + 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 4, 0, 0, 0, 41, 0, + 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 4, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 62, 30, 0, 0, + 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 4, 0, 0, 0, 32, + 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 5, 0, 0, + 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 8, + 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 9, 0, 0, 0, 230, 10, 16, + 0, 8, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 50, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, + 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 5, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 5, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, + 8, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, + 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, + 0, 16, 0, 9, 0, 0, 0, 6, 4, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, + 10, 242, 0, 16, 0, 10, 0, 0, 0, 38, 7, 16, 0, 9, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, + 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, + 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, + 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 8, 0, 0, 0, 6, 4, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 38, + 7, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, + 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, + 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, 10, 98, 0, 16, 0, 5, + 0, 0, 0, 6, 1, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, + 0, 9, 0, 0, 0, 6, 1, 16, 0, 9, 0, 0, 0, 131, 0, 0, 5, 162, 0, + 16, 0, 9, 0, 0, 0, 86, 9, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 98, + 0, 16, 0, 5, 0, 0, 0, 6, 1, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, + 5, 82, 0, 16, 0, 8, 0, 0, 0, 6, 1, 16, 0, 8, 0, 0, 0, 131, 0, + 0, 5, 162, 0, 16, 0, 8, 0, 0, 0, 86, 9, 16, 0, 5, 0, 0, 0, 2, + 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 194, 0, 16, 0, 9, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, + 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, + 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 50, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, + 22, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 9, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 18, 0, 0, 1, 41, 0, + 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 9, 0, 0, 0, + 26, 0, 16, 0, 5, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 165, 0, 0, 8, 18, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, + 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, + 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 226, 0, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, + 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, + 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, + 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, + 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, + 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, + 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, + 85, 0, 0, 10, 226, 0, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 9, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 9, + 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, + 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 8, 0, 0, 0, + 6, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, + 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 8, 32, + 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 2, 0, 0, 1, 6, + 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, + 12, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 9, 0, 0, 0, 6, 0, 16, + 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, + 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, 6, + 9, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, + 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 135, 0, 0, 5, 114, 0, + 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 30, 0, 0, 10, 114, + 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, + 12, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 13, 0, 0, 0, + 70, 2, 16, 128, 65, 0, 0, 0, 12, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, + 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, + 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 9, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, + 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 12, + 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, + 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, + 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, + 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 10, 0, + 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 55, + 0, 0, 12, 114, 0, 16, 0, 9, 0, 0, 0, 150, 7, 16, 0, 5, 0, 0, 0, + 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 34, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 9, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 171, 170, 170, 62, + 85, 0, 0, 10, 226, 0, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, + 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, 6, 9, 16, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 8, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 12, 0, + 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 12, + 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, + 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, + 0, 12, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 128, + 65, 0, 0, 0, 12, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 13, 0, + 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, + 2, 16, 0, 13, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, + 0, 55, 0, 0, 9, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 11, 0, + 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 41, + 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, + 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, + 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, + 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 55, 0, 0, 12, 114, + 0, 16, 0, 8, 0, 0, 0, 150, 7, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 86, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, + 16, 0, 8, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 171, 170, 170, 62, 2, 0, 0, 1, + 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, + 0, 9, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 16, 0, + 0, 0, 42, 0, 0, 10, 98, 0, 16, 0, 5, 0, 0, 0, 86, 4, 16, 0, 9, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 43, 0, 0, 5, 98, 0, 16, 0, 5, 0, 0, 0, 86, 6, 16, + 0, 5, 0, 0, 0, 56, 0, 0, 10, 98, 0, 16, 0, 5, 0, 0, 0, 86, 6, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 1, 128, 58, 0, + 1, 128, 58, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 9, 0, 0, 0, + 150, 5, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, + 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, + 0, 0, 10, 98, 0, 16, 0, 5, 0, 0, 0, 86, 4, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 43, 0, 0, 5, 98, 0, 16, 0, 5, 0, 0, 0, 86, 6, 16, 0, 5, 0, + 0, 0, 56, 0, 0, 10, 98, 0, 16, 0, 5, 0, 0, 0, 86, 6, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 8, 0, 0, 0, 150, 5, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 9, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, + 0, 3, 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, + 131, 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, + 0, 131, 0, 0, 5, 34, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, + 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, + 8, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, + 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 226, 0, 16, 0, 9, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 1, 23, 0, 0, 1, 21, 0, 0, 1, 0, 0, 0, 7, 242, 0, 16, 0, 9, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 0, + 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 31, 0, + 4, 3, 58, 0, 16, 0, 4, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, 4, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, + 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 4, + 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 50, 0, 16, 0, 11, 0, 0, 0, 230, 10, 16, 0, 10, 0, 0, 0, 18, 0, 0, + 1, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 11, + 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, + 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, + 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, + 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, 1, 64, + 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 11, 0, 0, 0, 6, + 4, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, + 0, 38, 7, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 12, + 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, + 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, + 194, 0, 16, 0, 10, 0, 0, 0, 6, 4, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, + 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 38, 7, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 43, 0, 0, 5, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, + 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 11, 0, 0, 0, 6, 1, 16, + 0, 11, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 11, 0, 0, 0, 6, 4, + 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, + 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 10, 0, 0, + 0, 6, 1, 16, 0, 10, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 10, 0, + 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, + 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, 32, + 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, + 0, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 10, + 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 22, 112, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, + 0, 10, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 18, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, + 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, + 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, + 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, + 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 11, 0, 0, 0, + 6, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, + 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, + 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 11, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 129, 128, + 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, + 0, 16, 0, 10, 0, 0, 0, 6, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, + 0, 0, 5, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, + 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, + 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, + 11, 0, 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, + 0, 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, 6, 0, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, + 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, + 128, 58, 171, 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, + 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, + 226, 0, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, + 0, 10, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, 6, 9, 16, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, + 0, 11, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 13, 0, 0, 0, 150, 7, + 16, 0, 5, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, + 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, + 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 13, 0, 0, + 0, 150, 7, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 11, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, + 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, + 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, + 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, + 9, 226, 0, 16, 0, 5, 0, 0, 0, 6, 9, 16, 0, 12, 0, 0, 0, 86, 14, + 16, 0, 5, 0, 0, 0, 6, 9, 16, 0, 13, 0, 0, 0, 41, 0, 0, 10, 114, + 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, + 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, + 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, 86, 14, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 30, 0, 0, 7, 226, 0, 16, 0, 5, 0, 0, 0, 6, 9, 16, 0, 12, 0, + 0, 0, 86, 14, 16, 0, 5, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 11, + 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 150, 7, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 11, 0, + 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, + 10, 0, 0, 0, 6, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 114, 0, + 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, + 226, 0, 16, 0, 5, 0, 0, 0, 6, 9, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 138, 0, + 0, 15, 114, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, + 0, 135, 0, 0, 5, 114, 0, 16, 0, 13, 0, 0, 0, 150, 7, 16, 0, 5, 0, + 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, + 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 13, 0, 0, 0, 150, 7, 16, + 0, 5, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, + 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 13, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 55, 0, 0, 9, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, + 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 140, + 0, 0, 17, 114, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, + 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, + 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, + 0, 5, 0, 0, 0, 6, 9, 16, 0, 12, 0, 0, 0, 86, 14, 16, 0, 5, 0, + 0, 0, 6, 9, 16, 0, 13, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 12, + 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, + 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, + 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 226, + 0, 16, 0, 5, 0, 0, 0, 86, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 30, 0, 0, + 7, 226, 0, 16, 0, 5, 0, 0, 0, 6, 9, 16, 0, 12, 0, 0, 0, 86, 14, + 16, 0, 5, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 10, 0, 0, 0, 70, + 2, 16, 0, 4, 0, 0, 0, 150, 7, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, + 5, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 56, 0, + 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 171, 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, + 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, + 0, 11, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 50, 0, + 16, 0, 4, 0, 0, 0, 22, 5, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 5, + 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 56, 0, 0, + 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 0, 0, 0, 0, 0, 0, 0, 52, + 0, 0, 10, 50, 0, 16, 0, 11, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, + 0, 41, 0, 0, 7, 34, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 10, 0, + 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 50, 0, 16, 0, 4, + 0, 0, 0, 22, 5, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 5, 50, 0, 16, + 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 56, 0, 0, 10, 50, 0, + 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, + 50, 0, 16, 0, 10, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, + 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 11, + 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, + 11, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, + 0, 11, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 16, + 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, + 10, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, + 1, 54, 0, 0, 8, 226, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 226, + 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, + 1, 0, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, + 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 6, + 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 18, 0, 0, 1, 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 56, 0, 0, 7, 242, 0, + 16, 0, 4, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 7, + 0, 0, 0, 56, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 246, 15, 16, 0, + 1, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 4, 0, 0, 0, 166, 8, + 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 6, 0, 0, 0, 166, + 8, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 7, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 11, 34, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 1, 0, + 0, 0, 230, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 254, 7, 0, 0, + 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 85, 0, + 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, + 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 96, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 58, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 140, 0, + 0, 20, 98, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 18, + 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 150, 5, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, + 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, + 1, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, 34, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, + 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 140, 0, 0, 17, 98, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, + 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 140, 0, + 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 18, 0, 0, 1, 42, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, + 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, + 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, + 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, + 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 7, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 1, 64, 0, + 0, 11, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, + 0, 10, 98, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 17, 98, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 2, + 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 21, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 13, 0, + 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, 2, + 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 140, 0, + 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 21, 0, 0, 1, 30, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 32, 0, 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, + 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 162, 0, + 16, 0, 4, 0, 0, 0, 246, 7, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 242, + 0, 16, 0, 4, 0, 0, 0, 150, 3, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, + 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 18, 0, 0, + 1, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 21, 0, 0, 1, 32, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, 0, 4, 3, + 10, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 4, 0, 0, + 0, 22, 11, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 21, 0, 0, 1, 32, 0, 0, 10, 114, + 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, + 7, 50, 0, 16, 0, 1, 0, 0, 0, 150, 5, 16, 0, 1, 0, 0, 0, 70, 0, + 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, + 1, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, 0, + 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, + 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 42, + 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 6, 0, 0, 0, + 246, 7, 16, 0, 6, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 6, 0, 0, + 0, 150, 3, 16, 0, 6, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 21, 0, 0, 1, 32, 0, 0, 7, 66, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 242, 0, 16, 0, 6, 0, 0, 0, 22, 11, 16, 0, 6, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 21, + 0, 0, 1, 32, 0, 0, 10, 210, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 166, 11, + 16, 0, 0, 0, 0, 0, 6, 2, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, + 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 1, 0, + 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, + 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 6, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, + 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, + 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 62, 0, 0, 1, 83, 84, + 65, 84, 148, 0, 0, 0, 1, 3, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 66, 0, 0, 0, 172, 0, 0, 0, 114, 0, 0, 0, 55, 0, 0, 0, + 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 32, 0, 0, 0, 40, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_128bpp_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_128bpp_scaled_cs.h new file mode 100644 index 0000000..e9a007a --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_128bpp_scaled_cs.h @@ -0,0 +1,2115 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_resolve_edram_info; // Offset: 0 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 4 Size: 4 +// uint xe_resolve_dest_info; // Offset: 8 Size: 4 +// uint xe_resolve_dest_coordinate_info;// Offset: 12 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram texture byte r/o T0 t0 1 +// xe_resolve_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_raw T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 16 +dcl_thread_group 8, 8, 1 +and r0.xyzw, CB0[0][0].zxxz, l(7, 1023, 0x20000000, 8) +if_nz r0.z + ubfe r1.xy, l(2, 2, 0, 0), l(17, 20, 0, 0), CB0[0][0].yyyy +else + mov r1.xy, l(0,0,0,0) +endif +ubfe r2.xyz, l(3, 3, 11, 0), l(16, 19, 5, 0), CB0[0][0].yyyy +imul null, r0.z, r2.x, r2.z +and r1.z, CB0[0][0].z, l(0x01000000) +ushr r3.xyzw, CB0[0][0].ywww, l(4, 10, 20, 24) +ishl r4.x, vThreadID.x, l(1) +ishl r0.z, r0.z, l(3) +uge r0.z, r4.x, r0.z +if_nz r0.z + ret +endif +ubfe r5.xyzw, l(2, 11, 4, 1), l(10, 13, 24, 28), CB0[0][0].xxxx +mov r6.x, CB0[0][0].y +mov r6.y, r3.x +bfi r2.zw, l(0, 0, 4, 1), l(0, 0, 3, 3), r6.xxxy, l(0, 0, 0, 0) +ibfe r0.z, l(6), l(16), CB0[0][0].z +ishl r0.z, r0.z, l(23) +iadd r0.z, r0.z, l(0x3f800000) +bfi r1.w, l(10), l(5), CB0[0][0].w, l(0) +bfi r3.xz, l(4, 0, 4, 0), l(3, 0, 3, 0), r3.zzwz, l(0, 0, 0, 0) +ubfe r3.w, l(3), l(28), CB0[0][0].w +umax r6.x, r1.x, r4.x +umax r6.y, r1.y, vThreadID.y +imad r2.zw, r2.zzzw, r2.xxxy, r6.xxxy +uge r1.y, l(3), r3.w +if_nz r1.y + mov r6.y, r3.w +else + ieq r1.y, r3.w, l(5) + if_nz r1.y + mov r6.y, l(2) + else + mov r6.y, l(0) + endif +endif +uge r4.zw, r5.xxxx, l(0, 0, 2, 1) +and r4.zw, r4.zzzw, l(0, 0, 1, 1) +ishl r2.zw, r2.zzzw, r4.zzzw +ushr r6.x, r6.y, l(1) +and r6.xy, r6.xyxx, l(1, 1, 0, 0) +iadd r2.zw, r2.zzzw, r6.xxxy +imul null, r6.yz, r2.xxyx, l(0, 80, 16, 0) +ushr r6.x, r6.y, r5.w +udiv r7.xy, null, r2.zwzz, r6.xzxx +imad r0.y, r7.y, r0.y, r7.x +iadd r0.y, r0.y, r5.y +imad r2.zw, -r7.xxxy, r6.xxxz, r2.zzzw +imul null, r1.y, r6.z, r6.y +imad r2.z, r2.w, r6.x, r2.z +ishl r2.z, r2.z, r5.w +imad r0.y, r0.y, r1.y, r2.z +ishl r1.y, r1.y, l(11) +udiv null, r0.y, r0.y, r1.y +iadd r1.y, r4.z, r5.w +ishl r1.y, l(1), r1.y +if_nz r5.w + ieq r2.z, r1.y, l(2) + if_nz r2.z + ishl r2.z, r0.y, l(2) + ld_raw r6.xyzw, r2.z, T0[0].zwxy + mov r7.xy, r6.zwzz + else + ishl r2.z, r0.y, l(2) + ld_raw r7.xy, r2.z, T0[0].xyxx + iadd r2.z, r0.y, r1.y + ishl r2.z, r2.z, l(2) + ld_raw r6.xy, r2.z, T0[0].xyxx + endif + switch r5.z + case l(5) + ishl r7.zw, r7.xxxy, l(0, 0, 16, 16) + ishr r8.xyzw, r7.zxwy, l(16, 16, 16, 16) + itof r8.xyzw, r8.xyzw + mul r8.xyzw, r8.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r7.xyzw, r8.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r6.zw, r6.xxxy, l(0, 0, 16, 16) + ishr r8.xyzw, r6.zxwy, l(16, 16, 16, 16) + itof r8.xyzw, r8.xyzw + mul r8.xyzw, r8.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r6.xyzw, r8.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r2.zw, r7.xxxy, l(0, 0, 16, 16) + f16tof32 r7.xz, r7.xxyx + f16tof32 r7.yw, r2.zzzw + ushr r2.zw, r6.xxxy, l(0, 0, 16, 16) + f16tof32 r6.xz, r6.xxyx + f16tof32 r6.yw, r2.zzzw + break + default + mov r7.zw, l(0,0,0,0) + mov r6.zw, l(0,0,0,0) + break + endswitch +else + ieq r2.z, r1.y, l(1) + if_nz r2.z + ishl r2.z, r0.y, l(2) + ld_raw r6.xy, r2.z, T0[0].yxxx + mov r7.x, r6.y + else + ishl r2.z, r0.y, l(2) + ld_raw r7.x, r2.z, T0[0].xxxx + iadd r2.z, r0.y, r1.y + ishl r2.z, r2.z, l(2) + ld_raw r6.x, r2.z, T0[0].xxxx + endif + switch r5.z + case l(0) + case l(1) + ushr r7.yzw, r7.xxxx, l(0, 8, 16, 24) + and r8.xyzw, r7.xyzw, l(255, 255, 255, 255) + utof r8.xyzw, r8.xyzw + mul r7.xyzw, r8.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r6.yzw, r6.xxxx, l(0, 8, 16, 24) + and r8.xyzw, r6.xyzw, l(255, 255, 255, 255) + utof r8.xyzw, r8.xyzw + mul r6.xyzw, r8.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r7.yzw, r7.xxxx, l(0, 10, 20, 30) + and r8.xyzw, r7.xyzw, l(1023, 1023, 1023, 3) + utof r8.xyzw, r8.xyzw + mul r7.xyzw, r8.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r6.yzw, r6.xxxx, l(0, 10, 20, 30) + and r8.xyzw, r6.xyzw, l(1023, 1023, 1023, 3) + utof r8.xyzw, r8.xyzw + mul r6.xyzw, r8.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r7.yzw, r7.xxxx, l(0, 10, 20, 30) + and r8.xyz, r7.xyzx, l(1023, 1023, 1023, 0) + and r9.xyz, r7.xyzx, l(127, 127, 127, 0) + ubfe r10.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r7.xyzx + firstbit_hi r11.xyz, r9.xyzx + iadd r11.xyz, r11.xyzx, l(-24, -24, -24, 0) + movc r11.xyz, r9.xyzx, r11.xyzx, l(8,8,8,0) + iadd r12.xyz, -r11.xyzx, l(1, 1, 1, 0) + movc r12.xyz, r10.xyzx, r10.xyzx, r12.xyzx + bfi r11.xyz, l(7, 7, 7, 0), r11.xyzx, r7.xyzx, l(0, 0, 0, 0) + and r11.xyz, r11.xyzx, l(127, 127, 127, 0) + movc r9.xyz, r10.xyzx, r9.xyzx, r11.xyzx + ishl r10.xyz, r12.xyzx, l(23, 23, 23, 0) + iadd r10.xyz, r10.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r9.xyz, r9.xyzx, l(16, 16, 16, 0) + iadd r9.xyz, r10.xyzx, r9.xyzx + movc r7.xyz, r8.xyzx, r9.xyzx, l(0,0,0,0) + utof r2.z, r7.w + mul r7.w, r2.z, l(0.333333) + ushr r6.yzw, r6.xxxx, l(0, 10, 20, 30) + and r8.xyz, r6.xyzx, l(1023, 1023, 1023, 0) + and r9.xyz, r6.xyzx, l(127, 127, 127, 0) + ubfe r10.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r6.xyzx + firstbit_hi r11.xyz, r9.xyzx + iadd r11.xyz, r11.xyzx, l(-24, -24, -24, 0) + movc r11.xyz, r9.xyzx, r11.xyzx, l(8,8,8,0) + iadd r12.xyz, -r11.xyzx, l(1, 1, 1, 0) + movc r12.xyz, r10.xyzx, r10.xyzx, r12.xyzx + bfi r11.xyz, l(7, 7, 7, 0), r11.xyzx, r6.xyzx, l(0, 0, 0, 0) + and r11.xyz, r11.xyzx, l(127, 127, 127, 0) + movc r9.xyz, r10.xyzx, r9.xyzx, r11.xyzx + ishl r10.xyz, r12.xyzx, l(23, 23, 23, 0) + iadd r10.xyz, r10.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r9.xyz, r9.xyzx, l(16, 16, 16, 0) + iadd r9.xyz, r10.xyzx, r9.xyzx + movc r6.xyz, r8.xyzx, r9.xyzx, l(0,0,0,0) + utof r2.z, r6.w + mul r6.w, r2.z, l(0.333333) + break + case l(4) + ishl r7.y, r7.x, l(16) + ishr r2.zw, r7.yyyx, l(0, 0, 16, 16) + itof r2.zw, r2.zzzw + mul r2.zw, r2.zzzw, l(0.000000, 0.000000, 0.000977, 0.000977) + max r7.xy, r2.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + ishl r6.y, r6.x, l(16) + ishr r2.zw, r6.yyyx, l(0, 0, 16, 16) + itof r2.zw, r2.zzzw + mul r2.zw, r2.zzzw, l(0.000000, 0.000000, 0.000977, 0.000977) + max r6.xy, r2.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r7.zw, l(0,0,0,0) + mov r6.zw, l(0,0,0,0) + break + case l(6) + ushr r2.z, r7.x, l(16) + f16tof32 r7.x, r7.x + f16tof32 r7.y, r2.z + ushr r2.z, r6.x, l(16) + f16tof32 r6.x, r6.x + f16tof32 r6.y, r2.z + mov r7.zw, l(0,0,0,0) + mov r6.zw, l(0,0,0,0) + break + default + mov r7.yzw, l(0,0,0,0) + mov r6.yzw, l(0,0,0,0) + break + endswitch +endif +uge r2.z, r3.w, l(4) +if_nz r2.z + mul r2.z, r0.z, l(0.500000) + imad r2.w, l(80), r2.x, r0.y + if_nz r5.w + ieq r4.z, r1.y, l(2) + if_nz r4.z + ishl r4.z, r2.w, l(2) + ld_raw r8.xyzw, r4.z, T0[0].zwxy + mov r9.xy, r8.zwzz + else + ishl r4.z, r2.w, l(2) + ld_raw r9.xy, r4.z, T0[0].xyxx + iadd r4.z, r1.y, r2.w + ishl r4.z, r4.z, l(2) + ld_raw r8.xy, r4.z, T0[0].xyxx + endif + switch r5.z + case l(5) + ishl r9.zw, r9.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r9.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r8.zw, r8.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r8.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.zw, r9.xxxy, l(0, 0, 16, 16) + f16tof32 r9.xz, r9.xxyx + f16tof32 r9.yw, r4.zzzw + ushr r4.zw, r8.xxxy, l(0, 0, 16, 16) + f16tof32 r8.xz, r8.xxyx + f16tof32 r8.yw, r4.zzzw + break + default + mov r9.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + endswitch + else + ieq r4.z, r1.y, l(1) + if_nz r4.z + ishl r4.z, r2.w, l(2) + ld_raw r8.xy, r4.z, T0[0].yxxx + mov r9.x, r8.y + else + ishl r4.z, r2.w, l(2) + ld_raw r9.x, r4.z, T0[0].xxxx + iadd r4.z, r1.y, r2.w + ishl r4.z, r4.z, l(2) + ld_raw r8.x, r4.z, T0[0].xxxx + endif + switch r5.z + case l(0) + case l(1) + ushr r9.yzw, r9.xxxx, l(0, 8, 16, 24) + and r10.xyzw, r9.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r8.yzw, r8.xxxx, l(0, 8, 16, 24) + and r10.xyzw, r8.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r9.yzw, r9.xxxx, l(0, 10, 20, 30) + and r10.xyzw, r9.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r8.yzw, r8.xxxx, l(0, 10, 20, 30) + and r10.xyzw, r8.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r9.yzw, r9.xxxx, l(0, 10, 20, 30) + and r10.xyz, r9.xyzx, l(1023, 1023, 1023, 0) + and r11.xyz, r9.xyzx, l(127, 127, 127, 0) + ubfe r12.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r9.xyzx + firstbit_hi r13.xyz, r11.xyzx + iadd r13.xyz, r13.xyzx, l(-24, -24, -24, 0) + movc r13.xyz, r11.xyzx, r13.xyzx, l(8,8,8,0) + iadd r14.xyz, -r13.xyzx, l(1, 1, 1, 0) + movc r14.xyz, r12.xyzx, r12.xyzx, r14.xyzx + bfi r13.xyz, l(7, 7, 7, 0), r13.xyzx, r9.xyzx, l(0, 0, 0, 0) + and r13.xyz, r13.xyzx, l(127, 127, 127, 0) + movc r11.xyz, r12.xyzx, r11.xyzx, r13.xyzx + ishl r12.xyz, r14.xyzx, l(23, 23, 23, 0) + iadd r12.xyz, r12.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r11.xyz, r11.xyzx, l(16, 16, 16, 0) + iadd r11.xyz, r12.xyzx, r11.xyzx + movc r9.xyz, r10.xyzx, r11.xyzx, l(0,0,0,0) + utof r4.z, r9.w + mul r9.w, r4.z, l(0.333333) + ushr r8.yzw, r8.xxxx, l(0, 10, 20, 30) + and r10.xyz, r8.xyzx, l(1023, 1023, 1023, 0) + and r11.xyz, r8.xyzx, l(127, 127, 127, 0) + ubfe r12.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r8.xyzx + firstbit_hi r13.xyz, r11.xyzx + iadd r13.xyz, r13.xyzx, l(-24, -24, -24, 0) + movc r13.xyz, r11.xyzx, r13.xyzx, l(8,8,8,0) + iadd r14.xyz, -r13.xyzx, l(1, 1, 1, 0) + movc r14.xyz, r12.xyzx, r12.xyzx, r14.xyzx + bfi r13.xyz, l(7, 7, 7, 0), r13.xyzx, r8.xyzx, l(0, 0, 0, 0) + and r13.xyz, r13.xyzx, l(127, 127, 127, 0) + movc r11.xyz, r12.xyzx, r11.xyzx, r13.xyzx + ishl r12.xyz, r14.xyzx, l(23, 23, 23, 0) + iadd r12.xyz, r12.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r11.xyz, r11.xyzx, l(16, 16, 16, 0) + iadd r11.xyz, r12.xyzx, r11.xyzx + movc r8.xyz, r10.xyzx, r11.xyzx, l(0,0,0,0) + utof r4.z, r8.w + mul r8.w, r4.z, l(0.333333) + break + case l(4) + ishl r9.y, r9.x, l(16) + ishr r4.zw, r9.yyyx, l(0, 0, 16, 16) + itof r4.zw, r4.zzzw + mul r4.zw, r4.zzzw, l(0.000000, 0.000000, 0.000977, 0.000977) + max r9.xy, r4.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + ishl r8.y, r8.x, l(16) + ishr r4.zw, r8.yyyx, l(0, 0, 16, 16) + itof r4.zw, r4.zzzw + mul r4.zw, r4.zzzw, l(0.000000, 0.000000, 0.000977, 0.000977) + max r8.xy, r4.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r9.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + case l(6) + ushr r4.z, r9.x, l(16) + f16tof32 r9.x, r9.x + f16tof32 r9.y, r4.z + ushr r4.z, r8.x, l(16) + f16tof32 r8.x, r8.x + f16tof32 r8.y, r4.z + mov r9.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + default + mov r9.yzw, l(0,0,0,0) + mov r8.yzw, l(0,0,0,0) + break + endswitch + endif + add r7.xyzw, r7.xyzw, r9.xyzw + add r6.xyzw, r6.xyzw, r8.xyzw + uge r3.w, r3.w, l(6) + if_nz r3.w + ishl r3.w, l(1), r5.w + mul r0.z, r0.z, l(0.250000) + iadd r0.y, r0.y, r3.w + if_nz r5.w + ieq r4.z, r1.y, l(2) + if_nz r4.z + ishl r4.z, r0.y, l(2) + ld_raw r8.xyzw, r4.z, T0[0].zwxy + mov r9.xy, r8.zwzz + else + ishl r4.z, r0.y, l(2) + ld_raw r9.xy, r4.z, T0[0].xyxx + iadd r4.z, r1.y, r0.y + ishl r4.z, r4.z, l(2) + ld_raw r8.xy, r4.z, T0[0].xyxx + endif + switch r5.z + case l(5) + ishl r9.zw, r9.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r9.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r8.zw, r8.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r8.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.zw, r9.xxxy, l(0, 0, 16, 16) + f16tof32 r9.xz, r9.xxyx + f16tof32 r9.yw, r4.zzzw + ushr r4.zw, r8.xxxy, l(0, 0, 16, 16) + f16tof32 r8.xz, r8.xxyx + f16tof32 r8.yw, r4.zzzw + break + default + mov r9.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + endswitch + else + ieq r4.z, r1.y, l(1) + if_nz r4.z + ishl r4.z, r0.y, l(2) + ld_raw r8.xy, r4.z, T0[0].yxxx + mov r9.x, r8.y + else + ishl r4.z, r0.y, l(2) + ld_raw r9.x, r4.z, T0[0].xxxx + iadd r0.y, r1.y, r0.y + ishl r0.y, r0.y, l(2) + ld_raw r8.x, r0.y, T0[0].xxxx + endif + switch r5.z + case l(0) + case l(1) + ushr r9.yzw, r9.xxxx, l(0, 8, 16, 24) + and r10.xyzw, r9.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r8.yzw, r8.xxxx, l(0, 8, 16, 24) + and r10.xyzw, r8.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r9.yzw, r9.xxxx, l(0, 10, 20, 30) + and r10.xyzw, r9.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r8.yzw, r8.xxxx, l(0, 10, 20, 30) + and r10.xyzw, r8.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r9.yzw, r9.xxxx, l(0, 10, 20, 30) + and r10.xyz, r9.xyzx, l(1023, 1023, 1023, 0) + and r11.xyz, r9.xyzx, l(127, 127, 127, 0) + ubfe r12.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r9.xyzx + firstbit_hi r13.xyz, r11.xyzx + iadd r13.xyz, r13.xyzx, l(-24, -24, -24, 0) + movc r13.xyz, r11.xyzx, r13.xyzx, l(8,8,8,0) + iadd r14.xyz, -r13.xyzx, l(1, 1, 1, 0) + movc r14.xyz, r12.xyzx, r12.xyzx, r14.xyzx + bfi r13.xyz, l(7, 7, 7, 0), r13.xyzx, r9.xyzx, l(0, 0, 0, 0) + and r13.xyz, r13.xyzx, l(127, 127, 127, 0) + movc r11.xyz, r12.xyzx, r11.xyzx, r13.xyzx + ishl r12.xyz, r14.xyzx, l(23, 23, 23, 0) + iadd r12.xyz, r12.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r11.xyz, r11.xyzx, l(16, 16, 16, 0) + iadd r11.xyz, r12.xyzx, r11.xyzx + movc r9.xyz, r10.xyzx, r11.xyzx, l(0,0,0,0) + utof r0.y, r9.w + mul r9.w, r0.y, l(0.333333) + ushr r8.yzw, r8.xxxx, l(0, 10, 20, 30) + and r10.xyz, r8.xyzx, l(1023, 1023, 1023, 0) + and r11.xyz, r8.xyzx, l(127, 127, 127, 0) + ubfe r12.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r8.xyzx + firstbit_hi r13.xyz, r11.xyzx + iadd r13.xyz, r13.xyzx, l(-24, -24, -24, 0) + movc r13.xyz, r11.xyzx, r13.xyzx, l(8,8,8,0) + iadd r14.xyz, -r13.xyzx, l(1, 1, 1, 0) + movc r14.xyz, r12.xyzx, r12.xyzx, r14.xyzx + bfi r13.xyz, l(7, 7, 7, 0), r13.xyzx, r8.xyzx, l(0, 0, 0, 0) + and r13.xyz, r13.xyzx, l(127, 127, 127, 0) + movc r11.xyz, r12.xyzx, r11.xyzx, r13.xyzx + ishl r12.xyz, r14.xyzx, l(23, 23, 23, 0) + iadd r12.xyz, r12.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r11.xyz, r11.xyzx, l(16, 16, 16, 0) + iadd r11.xyz, r12.xyzx, r11.xyzx + movc r8.xyz, r10.xyzx, r11.xyzx, l(0,0,0,0) + utof r0.y, r8.w + mul r8.w, r0.y, l(0.333333) + break + case l(4) + ishl r9.y, r9.x, l(16) + ishr r4.zw, r9.yyyx, l(0, 0, 16, 16) + itof r4.zw, r4.zzzw + mul r4.zw, r4.zzzw, l(0.000000, 0.000000, 0.000977, 0.000977) + max r9.xy, r4.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + ishl r8.y, r8.x, l(16) + ishr r4.zw, r8.yyyx, l(0, 0, 16, 16) + itof r4.zw, r4.zzzw + mul r4.zw, r4.zzzw, l(0.000000, 0.000000, 0.000977, 0.000977) + max r8.xy, r4.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r9.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + case l(6) + ushr r0.y, r9.x, l(16) + f16tof32 r9.x, r9.x + f16tof32 r9.y, r0.y + ushr r0.y, r8.x, l(16) + f16tof32 r8.x, r8.x + f16tof32 r8.y, r0.y + mov r9.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + default + mov r9.yzw, l(0,0,0,0) + mov r8.yzw, l(0,0,0,0) + break + endswitch + endif + add r9.xyzw, r7.xyzw, r9.xyzw + add r8.xyzw, r6.xyzw, r8.xyzw + iadd r0.y, r2.w, r3.w + if_nz r5.w + ieq r2.w, r1.y, l(2) + if_nz r2.w + ishl r2.w, r0.y, l(2) + ld_raw r10.xyzw, r2.w, T0[0].zwxy + mov r11.xy, r10.zwzz + else + ishl r2.w, r0.y, l(2) + ld_raw r11.xy, r2.w, T0[0].xyxx + iadd r2.w, r1.y, r0.y + ishl r2.w, r2.w, l(2) + ld_raw r10.xy, r2.w, T0[0].xyxx + endif + switch r5.z + case l(5) + ishl r11.zw, r11.xxxy, l(0, 0, 16, 16) + ishr r12.xyzw, r11.zxwy, l(16, 16, 16, 16) + itof r12.xyzw, r12.xyzw + mul r12.xyzw, r12.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r11.xyzw, r12.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r10.zw, r10.xxxy, l(0, 0, 16, 16) + ishr r12.xyzw, r10.zxwy, l(16, 16, 16, 16) + itof r12.xyzw, r12.xyzw + mul r12.xyzw, r12.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r10.xyzw, r12.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.zw, r11.xxxy, l(0, 0, 16, 16) + f16tof32 r11.xz, r11.xxyx + f16tof32 r11.yw, r4.zzzw + ushr r4.zw, r10.xxxy, l(0, 0, 16, 16) + f16tof32 r10.xz, r10.xxyx + f16tof32 r10.yw, r4.zzzw + break + default + mov r11.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + break + endswitch + else + ieq r2.w, r1.y, l(1) + if_nz r2.w + ishl r2.w, r0.y, l(2) + ld_raw r10.xy, r2.w, T0[0].yxxx + mov r11.x, r10.y + else + ishl r2.w, r0.y, l(2) + ld_raw r11.x, r2.w, T0[0].xxxx + iadd r0.y, r1.y, r0.y + ishl r0.y, r0.y, l(2) + ld_raw r10.x, r0.y, T0[0].xxxx + endif + switch r5.z + case l(0) + case l(1) + ushr r11.yzw, r11.xxxx, l(0, 8, 16, 24) + and r5.xyzw, r11.xyzw, l(255, 255, 255, 255) + utof r5.xyzw, r5.xyzw + mul r11.xyzw, r5.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r10.yzw, r10.xxxx, l(0, 8, 16, 24) + and r5.xyzw, r10.xyzw, l(255, 255, 255, 255) + utof r5.xyzw, r5.xyzw + mul r10.xyzw, r5.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r11.yzw, r11.xxxx, l(0, 10, 20, 30) + and r5.xyzw, r11.xyzw, l(1023, 1023, 1023, 3) + utof r5.xyzw, r5.xyzw + mul r11.xyzw, r5.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r10.yzw, r10.xxxx, l(0, 10, 20, 30) + and r5.xyzw, r10.xyzw, l(1023, 1023, 1023, 3) + utof r5.xyzw, r5.xyzw + mul r10.xyzw, r5.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r11.yzw, r11.xxxx, l(0, 10, 20, 30) + and r5.xyz, r11.xyzx, l(1023, 1023, 1023, 0) + and r12.xyz, r11.xyzx, l(127, 127, 127, 0) + ubfe r13.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r11.xyzx + firstbit_hi r14.xyz, r12.xyzx + iadd r14.xyz, r14.xyzx, l(-24, -24, -24, 0) + movc r14.xyz, r12.xyzx, r14.xyzx, l(8,8,8,0) + iadd r15.xyz, -r14.xyzx, l(1, 1, 1, 0) + movc r15.xyz, r13.xyzx, r13.xyzx, r15.xyzx + bfi r14.xyz, l(7, 7, 7, 0), r14.xyzx, r11.xyzx, l(0, 0, 0, 0) + and r14.xyz, r14.xyzx, l(127, 127, 127, 0) + movc r12.xyz, r13.xyzx, r12.xyzx, r14.xyzx + ishl r13.xyz, r15.xyzx, l(23, 23, 23, 0) + iadd r13.xyz, r13.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r12.xyz, r12.xyzx, l(16, 16, 16, 0) + iadd r12.xyz, r13.xyzx, r12.xyzx + movc r11.xyz, r5.xyzx, r12.xyzx, l(0,0,0,0) + utof r0.y, r11.w + mul r11.w, r0.y, l(0.333333) + ushr r10.yzw, r10.xxxx, l(0, 10, 20, 30) + and r5.xyz, r10.xyzx, l(1023, 1023, 1023, 0) + and r12.xyz, r10.xyzx, l(127, 127, 127, 0) + ubfe r13.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r10.xyzx + firstbit_hi r14.xyz, r12.xyzx + iadd r14.xyz, r14.xyzx, l(-24, -24, -24, 0) + movc r14.xyz, r12.xyzx, r14.xyzx, l(8,8,8,0) + iadd r15.xyz, -r14.xyzx, l(1, 1, 1, 0) + movc r15.xyz, r13.xyzx, r13.xyzx, r15.xyzx + bfi r14.xyz, l(7, 7, 7, 0), r14.xyzx, r10.xyzx, l(0, 0, 0, 0) + and r14.xyz, r14.xyzx, l(127, 127, 127, 0) + movc r12.xyz, r13.xyzx, r12.xyzx, r14.xyzx + ishl r13.xyz, r15.xyzx, l(23, 23, 23, 0) + iadd r13.xyz, r13.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r12.xyz, r12.xyzx, l(16, 16, 16, 0) + iadd r12.xyz, r13.xyzx, r12.xyzx + movc r10.xyz, r5.xyzx, r12.xyzx, l(0,0,0,0) + utof r0.y, r10.w + mul r10.w, r0.y, l(0.333333) + break + case l(4) + ishl r11.y, r11.x, l(16) + ishr r4.zw, r11.yyyx, l(0, 0, 16, 16) + itof r4.zw, r4.zzzw + mul r4.zw, r4.zzzw, l(0.000000, 0.000000, 0.000977, 0.000977) + max r11.xy, r4.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + ishl r10.y, r10.x, l(16) + ishr r4.zw, r10.yyyx, l(0, 0, 16, 16) + itof r4.zw, r4.zzzw + mul r4.zw, r4.zzzw, l(0.000000, 0.000000, 0.000977, 0.000977) + max r10.xy, r4.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r11.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + break + case l(6) + ushr r0.y, r11.x, l(16) + f16tof32 r11.x, r11.x + f16tof32 r11.y, r0.y + ushr r0.y, r10.x, l(16) + f16tof32 r10.x, r10.x + f16tof32 r10.y, r0.y + mov r11.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + break + default + mov r11.yzw, l(0,0,0,0) + mov r10.yzw, l(0,0,0,0) + break + endswitch + endif + add r7.xyzw, r9.xyzw, r11.xyzw + add r6.xyzw, r8.xyzw, r10.xyzw + else + mov r0.z, r2.z + endif +endif +mul r5.xyzw, r0.zzzz, r7.xyzw +mul r6.xyzw, r0.zzzz, r6.xyzw +if_nz r1.z + mov r7.xy, r5.zxzz + mov r6.xz, r6.zzxz +else + mov r7.xy, r5.xzxx +endif +ult r0.y, r4.x, r1.x +if_nz r0.y + mov r7.zw, r5.yyyw + mov r6.xyzw, r7.xzyw +endif +mov r4.y, vThreadID.y +imad r0.yz, r3.xxzx, r2.xxyx, r4.xxyx +udiv r1.xy, null, r0.yzyy, r2.xyxx +if_nz r0.w + ubfe r0.w, l(3), l(4), CB0[0][0].z + ishl r1.z, r3.y, l(5) + ishr r3.xyzw, r1.yxyx, l(4, 5, 3, 3) + ishr r2.z, r0.w, l(2) + ushr r1.z, r1.z, l(4) + and r1.z, r1.z, l(2046) + imad r1.z, r2.z, r1.z, r3.x + ushr r2.w, r1.w, l(5) + imad r1.z, r1.z, r2.w, r3.y + ishl r2.w, r1.y, l(12) + and r2.w, r2.w, l(0x00006000) + bfi r2.w, l(3), l(10), r1.x, r2.w + ishr r2.w, r2.w, l(6) + iadd r2.z, r2.z, r3.z + bfi r3.x, l(1), l(1), r2.z, l(0) + iadd r3.x, r3.x, r3.w + bfi r3.x, l(2), l(1), r3.x, l(0) + bfi r2.z, l(1), l(0), r2.z, r3.x + bfi r3.xy, l(18, 18, 0, 0), l(12, 15, 0, 0), r1.zzzz, l(0, 0, 0, 0) + imad r3.xy, r2.wwww, l(2, 16, 0, 0), r3.xyxx + bfi r3.xy, l(2, 2, 0, 0), l(10, 13, 0, 0), r0.wwww, r3.xyxx + bfi r0.w, l(1), l(4), r1.y, l(0) + ubfe r1.z, l(3), l(6), r3.x + and r2.w, r2.z, l(6) + bfi r2.z, l(1), l(8), r2.z, l(0) + imad r1.z, r1.z, l(32), r2.z + imad r1.z, r2.w, l(4), r1.z + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r0.wwww, r3.xxxy + bfi r0.w, l(9), l(3), r1.z, r2.w + bfi r0.w, l(6), l(0), r2.z, r0.w +else + ishr r3.xyzw, r1.xyyx, l(5, 5, 2, 3) + ushr r1.z, r1.w, l(5) + imad r1.z, r3.y, r1.z, r3.x + ishl r1.w, r1.y, l(7) + and r2.zw, r1.wwww, l(0, 0, 1792, 2048) + bfi r1.w, l(3), l(5), r1.x, r2.z + bfi r1.w, l(21), l(11), r1.z, r1.w + bfi r3.x, l(1), l(4), r1.y, l(0) + iadd r1.w, r1.w, r3.x + ishl r4.yz, r2.zzzz, l(0, 3, 2, 0) + bfi r4.yz, l(0, 3, 3, 0), l(0, 8, 7, 0), r1.xxxx, r4.yyzy + bfi r4.yz, l(0, 21, 21, 0), l(0, 14, 13, 0), r1.zzzz, r4.yyzy + imad r3.xy, r3.xxxx, l(8, 4, 0, 0), r4.yzyy + bfi r1.z, l(12), l(0), r2.w, r3.x + and r2.z, r3.y, l(1792) + iadd r1.z, r1.z, r2.z + and r2.z, r3.z, l(2) + iadd r2.z, r3.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.z, r1.z, r2.z + bfi r0.w, l(6), l(0), r1.w, r1.z +endif +imad r0.yz, -r1.xxyx, r2.xxyx, r0.yyzy +imul null, r1.x, r2.y, r2.x +imad r0.y, r0.y, r2.y, r0.z +ishl r0.y, r0.y, l(4) +imad r0.y, r0.w, r1.x, r0.y +ushr r0.y, r0.y, l(4) +ieq r0.z, r0.x, l(5) +if_nz r0.z + mov r5.xz, r5.wwyw + mov r5.yw, r7.yyyx + mov r0.w, l(2) +else + mov r5.xz, r7.xxyx + mov r0.w, r0.x +endif +ieq r1.x, r0.w, l(4) +if_nz r1.x + mov r5.xyzw, r5.yxwz + mov r0.w, l(2) +endif +ieq r1.xyz, r0.wwww, l(1, 2, 3, 0) +or r1.xy, r1.yzyy, r1.xyxx +if_nz r1.x + ishl r3.xyzw, r5.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r7.xyzw, r5.xyzw, l(8, 8, 8, 8) + and r7.xyzw, r7.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r5.xyzw, r3.xyzw, r7.xyzw +endif +if_nz r1.y + ushr r1.xyzw, r5.xyzw, l(16, 16, 16, 16) + bfi r5.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r5.xyzw, r1.xyzw +endif +store_uav_typed U0[0].xyzw, r0.yyyy, r5.xyzw +ult r0.w, l(1), r2.x +if_nz r0.w + udiv r0.w, null, r4.x, r2.x + imad r0.w, -r0.w, r2.x, r4.x + iadd r1.x, r0.w, l(1) + ieq r1.x, r2.x, r1.x + if_nz r1.x + ishl r1.x, r2.x, l(5) + ishl r0.w, r0.w, l(4) + iadd r0.w, -r0.w, r1.x + else + mov r0.w, l(16) + endif +else + mov r0.w, l(32) +endif +imul null, r0.w, r2.y, r0.w +ushr r0.w, r0.w, l(4) +iadd r0.y, r0.w, r0.y +if_nz r0.z + mov r6.xyzw, r6.wzyx + mov r0.x, l(2) +endif +ieq r0.z, r0.x, l(4) +if_nz r0.z + mov r6.xyzw, r6.yxwz + mov r0.x, l(2) +endif +ieq r0.xzw, r0.xxxx, l(1, 0, 2, 3) +or r0.xz, r0.zzwz, r0.xxzx +if_nz r0.x + ishl r1.xyzw, r6.xyzw, l(8, 8, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r2.xyzw, r6.xyzw, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r6.xyzw, r1.xyzw, r2.xyzw +endif +if_nz r0.z + ushr r1.xyzw, r6.xyzw, l(16, 16, 16, 16) + bfi r6.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r6.xyzw, r1.xyzw +endif +store_uav_typed U0[0].xyzw, r0.yyyy, r6.xyzw +ret +// Approximately 811 instruction slots used +#endif + +const BYTE resolve_full_128bpp_scaled_cs[] = { + 68, 88, 66, 67, 189, 93, 75, 60, 155, 4, 205, 101, 66, 243, 48, 31, 242, 198, 33, + 246, 1, 0, 0, 0, 244, 92, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 144, 2, + 0, 0, 160, 2, 0, 0, 176, 2, 0, 0, 88, 92, 0, 0, 82, 68, 69, 70, 84, + 2, 0, 0, 1, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 44, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 101, 100, 114, 97, 109, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 213, 0, 0, 0, 4, 0, 0, 0, 252, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 156, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 220, 1, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 247, 1, 0, 0, 8, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 12, 2, 0, 0, 12, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, + 114, 101, 115, 111, 108, 118, 101, 95, 101, 100, 114, 97, 109, 95, 105, 110, 102, 111, 0, + 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 178, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 99, 111, 111, 114, + 100, 105, 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 100, 101, 115, 116, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 99, 111, 111, 114, 100, 105, 110, 97, + 116, 101, 95, 105, 110, 102, 111, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 83, 72, 69, 88, 160, 89, 0, 0, 81, 0, 5, 0, 104, 22, 0, + 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 161, 0, 0, 6, 70, + 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 156, 8, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 68, 68, 0, 0, 0, 0, 0, 0, 95, 0, 0, 2, 50, 0, 2, 0, 104, 0, + 0, 2, 16, 0, 0, 0, 155, 0, 0, 4, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, 0, 38, 136, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, + 0, 255, 3, 0, 0, 0, 0, 0, 32, 8, 0, 0, 0, 31, 0, 4, 3, 42, 0, + 16, 0, 0, 0, 0, 0, 138, 0, 0, 17, 50, 0, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 17, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 133, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, + 0, 1, 54, 0, 0, 8, 50, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 138, 0, 0, 17, 114, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 86, 133, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 1, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 1, 85, 0, 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, 214, 143, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, + 0, 10, 0, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 4, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, + 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 3, 0, 0, 0, 80, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, + 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, + 0, 0, 17, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, + 11, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, + 0, 13, 0, 0, 0, 24, 0, 0, 0, 28, 0, 0, 0, 6, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 0, 16, 0, 6, + 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 140, 0, 0, 20, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 6, 4, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 139, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, + 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 140, 0, 0, 13, 130, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, + 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 140, 0, 0, 20, 82, 0, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 166, 11, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 11, 130, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 58, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 7, + 18, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, + 0, 4, 0, 0, 0, 83, 0, 0, 6, 34, 0, 16, 0, 6, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 9, 194, 0, 16, 0, 2, + 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, + 6, 4, 16, 0, 6, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 31, 0, + 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 6, + 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 5, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 54, 0, + 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 18, + 0, 0, 1, 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 80, 0, 0, 10, 194, 0, 16, + 0, 4, 0, 0, 0, 6, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, + 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 41, 0, 0, + 7, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 166, 14, + 16, 0, 4, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 26, + 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, + 50, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, + 4, 16, 0, 6, 0, 0, 0, 38, 0, 0, 11, 0, 208, 0, 0, 98, 0, 16, 0, + 6, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 80, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, + 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 5, + 0, 0, 0, 78, 0, 0, 8, 50, 0, 16, 0, 7, 0, 0, 0, 0, 208, 0, 0, + 230, 10, 16, 0, 2, 0, 0, 0, 134, 0, 16, 0, 6, 0, 0, 0, 35, 0, 0, + 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 5, 0, 0, 0, 35, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, + 128, 65, 0, 0, 0, 7, 0, 0, 0, 6, 8, 16, 0, 6, 0, 0, 0, 166, 14, + 16, 0, 2, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, + 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, + 0, 10, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, + 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 78, 0, 0, 8, 0, + 208, 0, 0, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 41, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, + 32, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 2, 0, + 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, + 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 7, 0, 0, 0, 230, 10, + 16, 0, 6, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 165, 0, 0, 8, 50, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, + 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, + 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 70, 112, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 5, + 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, + 194, 0, 16, 0, 7, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, + 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 38, 7, 16, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 43, 0, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, + 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 6, 0, 0, 0, 6, 4, + 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, + 38, 7, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 8, 0, + 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, + 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, + 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, + 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, + 2, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, + 16, 0, 7, 0, 0, 0, 6, 1, 16, 0, 7, 0, 0, 0, 131, 0, 0, 5, 162, + 0, 16, 0, 7, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, + 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, 0, + 0, 5, 82, 0, 16, 0, 6, 0, 0, 0, 6, 1, 16, 0, 6, 0, 0, 0, 131, + 0, 0, 5, 162, 0, 16, 0, 6, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, + 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, + 23, 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, + 4, 3, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 165, 0, 0, 8, 50, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 22, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, + 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 18, 0, 0, 1, 41, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 7, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, + 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 165, 0, 0, 8, 18, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, + 0, 0, 3, 42, 0, 16, 0, 5, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, + 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, + 10, 226, 0, 16, 0, 7, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 86, 0, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 6, 0, 16, + 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, + 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 8, 0, 0, + 0, 70, 14, 16, 0, 8, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, + 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, + 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, + 0, 85, 0, 0, 10, 226, 0, 16, 0, 7, 0, 0, 0, 6, 0, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 8, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, + 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, + 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, + 0, 6, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, + 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, + 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 2, 0, 0, 1, + 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, + 0, 12, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 7, 0, 0, 0, 6, 0, + 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, + 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, + 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 9, 0, + 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 135, 0, 0, 5, 114, + 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 30, 0, 0, 10, + 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, + 0, 12, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 70, + 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 12, 0, 0, + 0, 70, 2, 16, 128, 65, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, + 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, + 10, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 9, 0, 0, 0, 70, + 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, + 11, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, + 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, + 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, + 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 9, + 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, + 55, 0, 0, 12, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, + 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, + 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 171, 170, 170, + 62, 85, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, + 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 11, + 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, + 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, + 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, + 128, 65, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 12, + 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, + 70, 2, 16, 0, 12, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 10, + 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, + 41, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, + 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, + 0, 9, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 70, + 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 55, 0, 0, 12, + 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, 2, 16, + 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 6, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 171, 170, 170, 62, 2, 0, 0, + 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, + 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 16, + 0, 0, 0, 42, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 86, 1, 16, 0, + 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 43, 0, 0, 5, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, + 16, 0, 2, 0, 0, 0, 56, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 7, 0, 0, + 0, 230, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, + 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, + 42, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 86, 1, 16, 0, 6, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 43, 0, 0, 5, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, + 0, 0, 0, 56, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, + 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 6, 0, 0, 0, 230, 10, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, + 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, + 2, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, + 0, 131, 0, 0, 5, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 7, 0, + 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, + 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, + 0, 6, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 131, 0, 0, 5, 34, 0, + 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 8, 194, + 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 226, 0, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, 80, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 31, 0, 4, 3, 42, 0, 16, 0, 2, 0, 0, 0, 56, 0, 0, 7, 66, 0, 16, + 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 63, 35, 0, 0, 9, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 80, + 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 31, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, 32, 0, 0, 7, 66, 0, 16, + 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 66, + 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, + 0, 4, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 50, 0, 16, 0, 9, 0, 0, 0, 230, 10, 16, 0, 8, 0, 0, 0, 18, + 0, 0, 1, 41, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, + 0, 9, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, + 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 8, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, + 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 5, 0, 0, 0, 6, 0, 0, 3, + 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 9, 0, 0, + 0, 6, 4, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 10, + 0, 0, 0, 38, 7, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, + 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, + 0, 10, 194, 0, 16, 0, 8, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 42, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 38, 7, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, + 7, 0, 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, + 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 9, 0, 0, 0, 6, + 1, 16, 0, 9, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 9, 0, 0, 0, + 166, 14, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, + 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 8, + 0, 0, 0, 6, 1, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, + 8, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, + 1, 54, 0, 0, 8, 194, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, + 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, + 1, 32, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 4, + 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, + 0, 8, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 22, 112, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, 26, + 0, 16, 0, 8, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 66, 0, 16, 0, + 4, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 165, 0, 0, 8, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 4, 0, + 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, + 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 18, 0, + 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, + 5, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, + 3, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 9, 0, + 0, 0, 6, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, + 10, 226, 0, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, + 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, + 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, + 62, 85, 0, 0, 10, 226, 0, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 8, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, + 8, 32, 128, 58, 171, 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, + 0, 3, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, + 0, 10, 226, 0, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 9, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, + 1, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, + 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 9, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 9, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 13, 0, 0, 0, + 70, 2, 16, 0, 11, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, + 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, + 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 13, + 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 11, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 128, 65, 0, + 0, 0, 13, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 14, 0, 0, 0, + 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, + 0, 14, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, + 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 41, 0, 0, + 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 0, 41, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, + 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, + 0, 9, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, + 9, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, + 0, 4, 0, 0, 0, 1, 64, 0, 0, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, + 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, + 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, + 138, 0, 0, 15, 114, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 8, + 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, + 11, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, + 0, 13, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, + 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 13, 0, 0, 0, 70, + 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 11, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 13, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, + 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, + 0, 140, 0, 0, 17, 114, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 13, + 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, + 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, + 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, + 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, + 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 23, 0, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, + 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, + 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, + 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 8, 0, 0, + 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, + 0, 0, 5, 66, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, + 56, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, + 0, 1, 64, 0, 0, 171, 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, + 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 10, + 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, + 194, 0, 16, 0, 4, 0, 0, 0, 86, 1, 16, 0, 9, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, + 0, 5, 194, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 56, + 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, 58, 0, 1, 128, + 58, 52, 0, 0, 10, 50, 0, 16, 0, 9, 0, 0, 0, 230, 10, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, + 8, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 194, 0, 16, + 0, 4, 0, 0, 0, 86, 1, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 194, + 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 56, 0, 0, 10, + 194, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, + 0, 10, 50, 0, 16, 0, 8, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, + 6, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, + 0, 9, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, + 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 131, 0, 0, 5, 34, + 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 85, 0, 0, 7, + 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, + 0, 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 8, 0, 0, 0, 10, 0, + 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 8, 0, 0, 0, 42, + 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 9, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, + 0, 0, 1, 54, 0, 0, 8, 226, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 226, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 21, + 0, 0, 1, 0, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, + 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, + 0, 0, 80, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, + 3, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 56, 0, 0, 7, 66, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 128, 62, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, + 0, 5, 0, 0, 0, 32, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 42, + 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, + 8, 242, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 230, 116, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 9, + 0, 0, 0, 230, 10, 16, 0, 8, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, + 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 9, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, + 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, + 0, 8, 50, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 70, + 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, + 42, 0, 16, 0, 5, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, + 0, 41, 0, 0, 10, 194, 0, 16, 0, 9, 0, 0, 0, 6, 4, 16, 0, 9, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 38, 7, 16, 0, + 9, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 8, + 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, + 0, 10, 0, 0, 0, 38, 7, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, + 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, + 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, + 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, + 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 9, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, + 0, 0, 5, 82, 0, 16, 0, 9, 0, 0, 0, 6, 1, 16, 0, 9, 0, 0, 0, + 131, 0, 0, 5, 162, 0, 16, 0, 9, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, + 0, 85, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 8, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 8, 0, 0, 0, 6, 1, 16, 0, + 8, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 8, 0, 0, 0, 166, 14, 16, + 0, 4, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 194, 0, + 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, 66, 0, + 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, + 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 8, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, 22, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, + 18, 0, 0, 1, 41, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 18, 0, + 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 8, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 5, 0, 0, 0, 6, 0, 0, + 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, + 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 9, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, + 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 8, 0, + 0, 0, 6, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, + 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, + 0, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 9, 0, 0, 0, 6, + 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, + 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, + 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, + 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, + 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, + 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 9, + 0, 0, 0, 6, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, + 0, 10, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 15, 114, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, + 135, 0, 0, 5, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, + 0, 30, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, + 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, + 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, + 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, + 16, 0, 14, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 13, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, + 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 140, 0, + 0, 17, 114, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, + 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, 0, + 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 11, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, + 0, 70, 2, 16, 0, 13, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 12, 0, + 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, + 0, 11, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, + 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, + 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 56, 0, 0, + 7, 130, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 8, 0, 0, 0, 6, + 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, + 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, + 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 11, + 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 135, 0, 0, 5, + 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 30, 0, 0, + 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, + 0, 0, 12, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, + 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 14, 0, + 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 13, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, + 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, + 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 140, 0, 0, 17, 114, 0, + 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, + 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, + 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, + 0, 13, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, + 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, + 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 11, 0, + 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, + 11, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, + 0, 55, 0, 0, 12, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 10, 0, + 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 34, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, + 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 171, 170, + 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 41, + 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, + 1, 64, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, + 0, 86, 1, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 194, 0, 16, 0, 4, + 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 56, 0, 0, 10, 194, 0, 16, 0, + 4, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, + 16, 0, 9, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, + 0, 16, 0, 0, 0, 42, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 86, 1, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 194, 0, 16, 0, 4, 0, 0, 0, + 166, 14, 16, 0, 4, 0, 0, 0, 56, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, + 0, 166, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 8, + 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, + 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, + 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 1, 64, + 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, 10, + 0, 16, 0, 9, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 9, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 131, 0, + 0, 5, 18, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 131, + 0, 0, 5, 34, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, + 226, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 8, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, 0, 0, 0, 7, + 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, + 0, 9, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, 32, 0, 0, + 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 2, 0, 0, 0, 41, + 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 10, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 11, 0, 0, 0, 230, 10, 16, 0, 10, + 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, + 8, 50, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 70, 112, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 10, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 5, 0, 0, 0, + 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, + 0, 11, 0, 0, 0, 6, 4, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, + 0, 16, 0, 12, 0, 0, 0, 38, 7, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, + 5, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 52, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 10, 0, 0, 0, 6, 4, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 38, 7, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 12, 0, 0, 0, 70, + 14, 16, 0, 12, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, + 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, + 1, 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, + 0, 6, 4, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 11, + 0, 0, 0, 6, 1, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, + 11, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 194, 0, 16, + 0, 4, 0, 0, 0, 6, 4, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, + 0, 16, 0, 10, 0, 0, 0, 6, 1, 16, 0, 10, 0, 0, 0, 131, 0, 0, 5, + 162, 0, 16, 0, 10, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 2, 0, 0, + 1, 10, 0, 0, 1, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, + 1, 18, 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, + 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, + 8, 50, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 22, 112, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, + 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, + 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 11, 0, 0, 0, 58, 0, + 16, 0, 2, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, + 0, 8, 18, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 6, + 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, + 42, 0, 16, 0, 5, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, + 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 226, 0, + 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 85, 0, 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, 6, 0, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, + 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 85, 0, + 0, 10, 226, 0, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, + 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, + 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, 6, 0, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, + 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, + 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, + 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, + 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, + 30, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, + 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 13, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, + 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, + 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 232, 255, + 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, + 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, + 14, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, + 16, 128, 65, 0, 0, 0, 14, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 15, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 14, 0, + 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, + 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, + 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, + 13, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, + 0, 41, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 12, 0, 0, 0, + 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 55, 0, 0, + 12, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 70, 2, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 11, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 11, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 171, 170, 170, 62, 85, 0, + 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, 6, 0, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, + 1, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 10, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 14, 0, 0, 0, + 70, 2, 16, 0, 12, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, + 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, + 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 14, + 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 11, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 128, 65, 0, + 0, 0, 14, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, + 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, + 0, 15, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 14, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, + 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 41, 0, 0, + 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 0, 41, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, + 13, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, + 0, 10, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 86, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 10, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 171, 170, 170, 62, 2, 0, 0, 1, 6, 0, + 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 11, + 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, + 42, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 86, 1, 16, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 43, 0, 0, 5, 194, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 4, + 0, 0, 0, 56, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, + 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 11, 0, 0, 0, 230, 10, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 10, 0, 0, 0, + 10, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 0, 0, + 10, 194, 0, 16, 0, 4, 0, 0, 0, 86, 1, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, + 0, 0, 5, 194, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, + 56, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, 58, 0, 1, + 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 10, 0, 0, 0, 230, 10, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, + 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 131, 0, + 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 131, + 0, 0, 5, 34, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, + 0, 1, 64, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 10, 0, + 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 10, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 226, 0, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 226, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, + 0, 0, 1, 21, 0, 0, 1, 0, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 0, 0, 0, + 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, + 56, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 7, 0, 0, 0, 56, 0, 0, 7, 242, 0, 16, 0, 6, 0, + 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 31, + 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, + 7, 0, 0, 0, 38, 10, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, + 0, 6, 0, 0, 0, 166, 8, 16, 0, 6, 0, 0, 0, 18, 0, 0, 1, 54, 0, + 0, 5, 50, 0, 16, 0, 7, 0, 0, 0, 134, 0, 16, 0, 5, 0, 0, 0, 21, + 0, 0, 1, 79, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 194, 0, 16, 0, 7, 0, 0, 0, 86, 13, + 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 6, 0, 0, 0, 134, + 13, 16, 0, 7, 0, 0, 0, 21, 0, 0, 1, 54, 0, 0, 4, 34, 0, 16, 0, + 4, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 9, 98, 0, 16, 0, 0, 0, 0, + 0, 6, 2, 16, 0, 3, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 6, 1, + 16, 0, 4, 0, 0, 0, 78, 0, 0, 8, 50, 0, 16, 0, 1, 0, 0, 0, 0, + 208, 0, 0, 150, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, + 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 11, 130, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, + 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 22, 1, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 85, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 254, 7, 0, 0, 35, + 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 85, 0, 0, + 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, + 3, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 7, 130, 0, + 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, + 96, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 3, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, + 20, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 18, 0, 0, 0, 18, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 15, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 35, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 246, 15, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 3, + 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, 66, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, + 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, + 11, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, + 0, 0, 17, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 246, 15, 16, 0, 0, 0, + 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 18, 0, 0, 1, 42, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 1, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, + 0, 2, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, + 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 246, + 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7, 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 1, 64, 0, 0, + 11, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 11, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, + 10, 98, 0, 16, 0, 4, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, + 0, 0, 17, 98, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 8, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, + 0, 0, 86, 6, 16, 0, 4, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 13, 0, 0, + 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 4, 0, + 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 150, 5, 16, 0, 4, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 11, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 21, + 0, 0, 1, 35, 0, 0, 10, 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 128, + 65, 0, 0, 0, 1, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 86, 6, 16, + 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 18, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 35, + 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 32, 0, 0, 7, 66, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 82, 0, 16, 0, 5, 0, 0, 0, 246, 13, 16, 0, 5, 0, 0, 0, 54, 0, 0, + 5, 162, 0, 16, 0, 5, 0, 0, 0, 86, 1, 16, 0, 7, 0, 0, 0, 54, 0, + 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 18, + 0, 0, 1, 54, 0, 0, 5, 82, 0, 16, 0, 5, 0, 0, 0, 6, 1, 16, 0, + 7, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 21, 0, 0, 1, 32, 0, 0, 7, 18, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, + 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, + 5, 0, 0, 0, 22, 11, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 21, 0, 0, 1, 32, 0, + 0, 10, 114, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 60, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 150, 5, 16, 0, 1, 0, 0, + 0, 70, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, + 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, + 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, + 0, 0, 17, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 5, 0, + 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, + 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, + 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 78, 0, 0, 8, 130, 0, 16, 0, 0, + 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 35, 0, 0, 10, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, + 128, 65, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, + 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, + 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, + 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, + 8, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 130, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, + 18, 0, 0, 1, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 32, 0, 0, 0, 21, 0, 0, 1, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, + 0, 16, 0, 6, 0, 0, 0, 182, 1, 16, 0, 6, 0, 0, 0, 54, 0, 0, 5, + 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 21, 0, 0, + 1, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 6, 0, 0, 0, 22, 11, 16, 0, + 6, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 21, 0, 0, 1, 32, 0, 0, 10, 210, 0, 16, 0, 0, 0, + 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, + 0, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 6, 2, 16, 0, 0, 0, 0, + 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, + 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, + 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 1, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 6, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 1, 0, + 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, + 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 43, 3, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 66, 0, 0, 0, 188, 0, 0, 0, 121, 0, + 0, 0, 59, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 32, 0, 0, + 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_16bpp_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_16bpp_cs.h new file mode 100644 index 0000000..7ade51f --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_16bpp_cs.h @@ -0,0 +1,3563 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_resolve_edram_info; // Offset: 0 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 4 Size: 4 +// uint xe_resolve_dest_info; // Offset: 8 Size: 4 +// uint xe_resolve_dest_coordinate_info;// Offset: 12 Size: 4 +// uint xe_resolve_dest_base; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram texture byte r/o T0 t0 1 +// xe_resolve_dest UAV uint2 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][2], immediateIndexed, space=0 +dcl_resource_raw T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 24 +dcl_thread_group 8, 8, 1 +and r0.xyzw, CB0[0][0].xzzz, l(1023, 7, 8, 0x01000000) +ushr r1.xyz, CB0[0][0].yywy, l(4, 5, 10, 0) +ushr r2.xyzw, CB0[0][0].wwww, l(20, 24, 24, 20) +ishl r3.xw, vThreadID.xxxx, l(2, 0, 0, 2) +bfi r1.y, l(11), l(3), r1.y, l(0) +uge r1.y, r3.w, r1.y +if_nz r1.y + ret +endif +ubfe r4.xyzw, l(2, 11, 4, 1), l(10, 13, 24, 28), CB0[0][0].xxxx +mov r1.w, CB0[0][0].y +bfi r1.xy, l(4, 1, 0, 0), l(3, 3, 0, 0), r1.wxww, l(0, 0, 0, 0) +ibfe r1.w, l(6), l(16), CB0[0][0].z +ishl r1.w, r1.w, l(23) +iadd r1.w, r1.w, l(0x3f800000) +bfi r5.x, l(10), l(5), CB0[0][0].w, l(0) +bfi r2.xyzw, l(4, 4, 4, 4), l(3, 3, 3, 3), r2.xyzw, l(0, 0, 0, 0) +ubfe r5.yz, l(0, 6, 3, 0), l(0, 7, 28, 0), CB0[0][0].zzwz +mov r3.yz, vThreadID.yyyy +iadd r1.xy, r1.xyxx, r3.wzww +uge r5.w, l(3), r5.z +if_nz r5.w + mov r6.y, r5.z +else + ieq r5.w, r5.z, l(5) + if_nz r5.w + mov r6.y, l(2) + else + mov r6.y, l(0) + endif +endif +uge r6.zw, r4.xxxx, l(0, 0, 2, 1) +and r6.zw, r6.zzzw, l(0, 0, 1, 1) +ishl r1.xy, r1.xyxx, r6.zwzz +ushr r6.x, r6.y, l(1) +and r6.xy, r6.xyxx, l(1, 1, 0, 0) +iadd r1.xy, r1.xyxx, r6.xyxx +ushr r6.x, l(80), r4.w +mov r6.y, l(16) +udiv r7.xy, null, r1.xyxx, r6.xyxx +imad r0.x, r7.y, r0.x, r7.x +iadd r0.x, r0.x, r4.y +imad r1.xy, -r7.xyxx, r6.xyxx, r1.xyxx +imad r1.x, r1.y, r6.x, r1.x +ishl r1.x, r1.x, r4.w +imad r0.x, r0.x, l(1280), r1.x +udiv null, r0.x, r0.x, l(0x00280000) +iadd r1.x, r4.w, r6.z +ishl r1.y, l(1), r1.x +if_nz r4.w + ieq r4.x, r1.y, l(2) + if_nz r4.x + ishl r4.x, r0.x, l(2) + ld_raw r6.xyzw, r4.x, T0[0].zwxy + iadd r4.x, r4.x, l(16) + ld_raw r7.xyzw, r4.x, T0[0].zwxy + mov r8.xy, r6.zwzz + mov r9.xy, r7.zwzz + else + ishl r4.x, r0.x, l(2) + ld_raw r8.xy, r4.x, T0[0].xyxx + iadd r4.x, r0.x, r1.y + ishl r4.x, r4.x, l(2) + ld_raw r6.xy, r4.x, T0[0].xyxx + ishl r4.xy, l(2, 3, 0, 0), r1.xxxx + iadd r4.xy, r0.xxxx, r4.xyxx + ishl r4.xy, r4.xyxx, l(2, 2, 0, 0) + ld_raw r9.xy, r4.x, T0[0].xyxx + ld_raw r7.xy, r4.y, T0[0].xyxx + endif + switch r4.z + case l(5) + ishl r8.zw, r8.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r8.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r6.zw, r6.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r6.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r6.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r9.zw, r9.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r9.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r7.zw, r7.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r7.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r7.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.xy, r8.xyxx, l(16, 16, 0, 0) + f16tof32 r8.xz, r8.xxyx + f16tof32 r8.yw, r4.xxxy + ushr r4.xy, r6.xyxx, l(16, 16, 0, 0) + f16tof32 r6.xz, r6.xxyx + f16tof32 r6.yw, r4.xxxy + ushr r4.xy, r9.xyxx, l(16, 16, 0, 0) + f16tof32 r9.xz, r9.xxyx + f16tof32 r9.yw, r4.xxxy + ushr r4.xy, r7.xyxx, l(16, 16, 0, 0) + f16tof32 r7.xz, r7.xxyx + f16tof32 r7.yw, r4.xxxy + break + default + mov r8.zw, l(0,0,0,0) + mov r6.zw, l(0,0,0,0) + mov r9.zw, l(0,0,0,0) + mov r7.zw, l(0,0,0,0) + break + endswitch +else + ieq r4.x, r1.y, l(1) + if_nz r4.x + ishl r4.x, r0.x, l(2) + ld_raw r7.xyzw, r4.x, T0[0].wxyz + else + ishl r4.x, r0.x, l(2) + ld_raw r7.y, r4.x, T0[0].xxxx + iadd r4.x, r0.x, r1.y + ishl r4.x, r4.x, l(2) + ld_raw r7.z, r4.x, T0[0].xxxx + ishl r4.xy, l(2, 3, 0, 0), r1.xxxx + iadd r4.xy, r0.xxxx, r4.xyxx + ishl r4.xy, r4.xyxx, l(2, 2, 0, 0) + ld_raw r7.w, r4.x, T0[0].xxxx + ld_raw r7.x, r4.y, T0[0].xxxx + endif + switch r4.z + case l(0) + case l(1) + ushr r10.yzw, r7.yyyy, l(0, 8, 16, 24) + mov r10.x, r7.y + and r10.xyzw, r10.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r10.yzw, r7.zzzz, l(0, 8, 16, 24) + mov r10.x, r7.z + and r10.xyzw, r10.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r6.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r10.yzw, r7.wwww, l(0, 8, 16, 24) + mov r10.x, r7.w + and r10.xyzw, r10.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r7.yzw, r7.xxxx, l(0, 8, 16, 24) + and r10.xyzw, r7.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r7.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r10.yzw, r7.yyyy, l(0, 10, 20, 30) + mov r10.x, r7.y + and r10.xyzw, r10.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r10.yzw, r7.zzzz, l(0, 10, 20, 30) + mov r10.x, r7.z + and r10.xyzw, r10.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r6.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r10.yzw, r7.wwww, l(0, 10, 20, 30) + mov r10.x, r7.w + and r10.xyzw, r10.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r7.yzw, r7.xxxx, l(0, 10, 20, 30) + and r10.xyzw, r7.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r7.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r10.xyzw, r7.yyyz, l(10, 20, 30, 30) + mov r11.x, r7.y + mov r11.yz, r10.xxyx + and r12.xyz, r11.xyzx, l(1023, 1023, 1023, 0) + and r13.xyz, r11.xyzx, l(127, 127, 127, 0) + ubfe r14.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r11.xyzx + firstbit_hi r15.xyz, r13.xyzx + iadd r15.xyz, r15.xyzx, l(-24, -24, -24, 0) + movc r15.xyz, r13.xyzx, r15.xyzx, l(8,8,8,0) + iadd r16.xyz, -r15.xyzx, l(1, 1, 1, 0) + movc r16.xyz, r14.xyzx, r14.xyzx, r16.xyzx + bfi r11.xyz, l(7, 7, 7, 0), r15.xyzx, r11.xyzx, l(0, 0, 0, 0) + and r11.xyz, r11.xyzx, l(127, 127, 127, 0) + movc r11.xyz, r14.xyzx, r13.xyzx, r11.xyzx + ishl r13.xyz, r16.xyzx, l(23, 23, 23, 0) + iadd r13.xyz, r13.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r11.xyz, r11.xyzx, l(16, 16, 16, 0) + iadd r11.xyz, r13.xyzx, r11.xyzx + movc r8.xyz, r12.xyzx, r11.xyzx, l(0,0,0,0) + utof r4.xy, r10.zwzz + ushr r10.xyzw, r7.zwwz, l(10, 10, 20, 20) + mov r11.x, r7.z + mov r11.yz, r10.xxwx + and r12.xyz, r11.xyzx, l(1023, 1023, 1023, 0) + and r13.xyz, r11.xyzx, l(127, 127, 127, 0) + ubfe r14.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r11.xyzx + firstbit_hi r15.xyz, r13.xyzx + iadd r15.xyz, r15.xyzx, l(-24, -24, -24, 0) + movc r15.xyz, r13.xyzx, r15.xyzx, l(8,8,8,0) + iadd r16.xyz, -r15.xyzx, l(1, 1, 1, 0) + movc r16.xyz, r14.xyzx, r14.xyzx, r16.xyzx + bfi r11.xyz, l(7, 7, 7, 0), r15.xyzx, r11.xyzx, l(0, 0, 0, 0) + and r11.xyz, r11.xyzx, l(127, 127, 127, 0) + movc r11.xyz, r14.xyzx, r13.xyzx, r11.xyzx + ishl r13.xyz, r16.xyzx, l(23, 23, 23, 0) + iadd r13.xyz, r13.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r11.xyz, r11.xyzx, l(16, 16, 16, 0) + iadd r11.xyz, r13.xyzx, r11.xyzx + movc r6.xyz, r12.xyzx, r11.xyzx, l(0,0,0,0) + mul r4.xy, r4.xyxx, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r10.x, r7.w + and r11.xyz, r10.xyzx, l(1023, 1023, 1023, 0) + and r12.xyz, r10.xyzx, l(127, 127, 127, 0) + ubfe r13.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r10.xyzx + firstbit_hi r14.xyz, r12.xyzx + iadd r14.xyz, r14.xyzx, l(-24, -24, -24, 0) + movc r14.xyz, r12.xyzx, r14.xyzx, l(8,8,8,0) + iadd r15.xyz, -r14.xyzx, l(1, 1, 1, 0) + movc r15.xyz, r13.xyzx, r13.xyzx, r15.xyzx + bfi r10.xyz, l(7, 7, 7, 0), r14.xyzx, r10.xyzx, l(0, 0, 0, 0) + and r10.xyz, r10.xyzx, l(127, 127, 127, 0) + movc r10.xyz, r13.xyzx, r12.xyzx, r10.xyzx + ishl r12.xyz, r15.xyzx, l(23, 23, 23, 0) + iadd r12.xyz, r12.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r10.xyz, r10.xyzx, l(16, 16, 16, 0) + iadd r10.xyz, r12.xyzx, r10.xyzx + movc r9.xyz, r11.xyzx, r10.xyzx, l(0,0,0,0) + ushr r10.xyzw, r7.wxxx, l(30, 10, 20, 30) + utof r11.xy, r10.xwxx + mov r10.x, r7.x + and r12.xyz, r10.xyzx, l(1023, 1023, 1023, 0) + and r13.xyz, r10.xyzx, l(127, 127, 127, 0) + ubfe r14.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r10.xyzx + firstbit_hi r15.xyz, r13.xyzx + iadd r15.xyz, r15.xyzx, l(-24, -24, -24, 0) + movc r15.xyz, r13.xyzx, r15.xyzx, l(8,8,8,0) + iadd r16.xyz, -r15.xyzx, l(1, 1, 1, 0) + movc r16.xyz, r14.xyzx, r14.xyzx, r16.xyzx + bfi r10.xyz, l(7, 7, 7, 0), r15.xyzx, r10.xyzx, l(0, 0, 0, 0) + and r10.xyz, r10.xyzx, l(127, 127, 127, 0) + movc r10.xyz, r14.xyzx, r13.xyzx, r10.xyzx + ishl r13.xyz, r16.xyzx, l(23, 23, 23, 0) + iadd r13.xyz, r13.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r10.xyz, r10.xyzx, l(16, 16, 16, 0) + iadd r10.xyz, r13.xyzx, r10.xyzx + movc r7.xyz, r12.xyzx, r10.xyzx, l(0,0,0,0) + mul r10.xy, r11.xyxx, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r8.w, r4.x + mov r6.w, r4.y + mov r9.w, r10.x + mov r7.w, r10.y + break + case l(4) + ishl r10.xyzw, r7.yzwx, l(16, 16, 16, 16) + mov r11.xz, r10.xxyx + mov r11.yw, r7.yyyz + ishr r11.xyzw, r11.xyzw, l(16, 16, 16, 16) + itof r11.xyzw, r11.xyzw + mul r11.xyzw, r11.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xy, r11.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r6.xy, r11.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r7.yz, r10.zzwz + ishr r10.xyzw, r7.ywzx, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xy, r10.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r7.xy, r10.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r8.zw, l(0,0,0,0) + mov r6.zw, l(0,0,0,0) + mov r9.zw, l(0,0,0,0) + mov r7.zw, l(0,0,0,0) + break + case l(6) + ushr r10.xyzw, r7.yzwx, l(16, 16, 16, 16) + f16tof32 r8.x, r7.y + f16tof32 r8.y, r10.x + f16tof32 r6.x, r7.z + f16tof32 r6.y, r10.y + f16tof32 r9.x, r7.w + f16tof32 r9.y, r10.z + f16tof32 r7.x, r7.x + f16tof32 r7.y, r10.w + mov r8.zw, l(0,0,0,0) + mov r6.zw, l(0,0,0,0) + mov r9.zw, l(0,0,0,0) + mov r7.zw, l(0,0,0,0) + break + default + mov r8.x, r7.y + mov r8.yzw, l(0,0,0,0) + mov r6.x, r7.z + mov r6.yzw, l(0,0,0,0) + mov r9.x, r7.w + mov r9.yzw, l(0,0,0,0) + mov r7.yzw, l(0,0,0,0) + break + endswitch +endif +uge r4.x, r5.z, l(4) +if_nz r4.x + mul r4.x, r1.w, l(0.500000) + iadd r4.y, r0.x, l(80) + if_nz r4.w + ieq r5.w, r1.y, l(2) + if_nz r5.w + ishl r5.w, r4.y, l(2) + ld_raw r10.xyzw, r5.w, T0[0].zwxy + iadd r5.w, r5.w, l(16) + ld_raw r11.xyzw, r5.w, T0[0].zwxy + mov r12.xy, r10.zwzz + mov r14.xy, r11.zwzz + else + ishl r5.w, r4.y, l(2) + ld_raw r12.xy, r5.w, T0[0].xyxx + iadd r5.w, r1.y, r4.y + ishl r5.w, r5.w, l(2) + ld_raw r10.xy, r5.w, T0[0].xyxx + ishl r13.xy, l(2, 3, 0, 0), r1.xxxx + iadd r13.xy, r4.yyyy, r13.xyxx + ishl r13.xy, r13.xyxx, l(2, 2, 0, 0) + ld_raw r14.xy, r13.x, T0[0].xyxx + ld_raw r11.xy, r13.y, T0[0].xyxx + endif + switch r4.z + case l(5) + ishl r12.zw, r12.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r12.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r12.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r10.zw, r10.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r10.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r10.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r14.zw, r14.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r14.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r11.zw, r11.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r11.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r11.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r13.xy, r12.xyxx, l(16, 16, 0, 0) + f16tof32 r12.xz, r12.xxyx + f16tof32 r12.yw, r13.xxxy + ushr r13.xy, r10.xyxx, l(16, 16, 0, 0) + f16tof32 r10.xz, r10.xxyx + f16tof32 r10.yw, r13.xxxy + ushr r13.xy, r14.xyxx, l(16, 16, 0, 0) + f16tof32 r14.xz, r14.xxyx + f16tof32 r14.yw, r13.xxxy + ushr r13.xy, r11.xyxx, l(16, 16, 0, 0) + f16tof32 r11.xz, r11.xxyx + f16tof32 r11.yw, r13.xxxy + break + default + mov r12.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + break + endswitch + else + ieq r5.w, r1.y, l(1) + if_nz r5.w + ishl r5.w, r4.y, l(2) + ld_raw r11.xyzw, r5.w, T0[0].wxyz + else + ishl r5.w, r4.y, l(2) + ld_raw r11.y, r5.w, T0[0].xxxx + iadd r5.w, r1.y, r4.y + ishl r5.w, r5.w, l(2) + ld_raw r11.z, r5.w, T0[0].xxxx + ishl r13.xy, l(2, 3, 0, 0), r1.xxxx + iadd r13.xy, r4.yyyy, r13.xyxx + ishl r13.xy, r13.xyxx, l(2, 2, 0, 0) + ld_raw r11.w, r13.x, T0[0].xxxx + ld_raw r11.x, r13.y, T0[0].xxxx + endif + switch r4.z + case l(0) + case l(1) + ushr r13.yzw, r11.yyyy, l(0, 8, 16, 24) + mov r13.x, r11.y + and r13.xyzw, r13.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r12.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r13.yzw, r11.zzzz, l(0, 8, 16, 24) + mov r13.x, r11.z + and r13.xyzw, r13.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r10.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r13.yzw, r11.wwww, l(0, 8, 16, 24) + mov r13.x, r11.w + and r13.xyzw, r13.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r14.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r11.yzw, r11.xxxx, l(0, 8, 16, 24) + and r13.xyzw, r11.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r11.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r13.yzw, r11.yyyy, l(0, 10, 20, 30) + mov r13.x, r11.y + and r13.xyzw, r13.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r12.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r13.yzw, r11.zzzz, l(0, 10, 20, 30) + mov r13.x, r11.z + and r13.xyzw, r13.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r10.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r13.yzw, r11.wwww, l(0, 10, 20, 30) + mov r13.x, r11.w + and r13.xyzw, r13.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r14.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r11.yzw, r11.xxxx, l(0, 10, 20, 30) + and r13.xyzw, r11.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r11.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r13.xyzw, r11.yyyz, l(10, 20, 30, 30) + mov r15.x, r11.y + mov r15.yz, r13.xxyx + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r12.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + utof r13.xy, r13.zwzz + ushr r15.xyzw, r11.zwwz, l(10, 10, 20, 20) + mov r16.x, r11.z + mov r16.yz, r15.xxwx + and r17.xyz, r16.xyzx, l(1023, 1023, 1023, 0) + and r18.xyz, r16.xyzx, l(127, 127, 127, 0) + ubfe r19.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r16.xyzx + firstbit_hi r20.xyz, r18.xyzx + iadd r20.xyz, r20.xyzx, l(-24, -24, -24, 0) + movc r20.xyz, r18.xyzx, r20.xyzx, l(8,8,8,0) + iadd r21.xyz, -r20.xyzx, l(1, 1, 1, 0) + movc r21.xyz, r19.xyzx, r19.xyzx, r21.xyzx + bfi r16.xyz, l(7, 7, 7, 0), r20.xyzx, r16.xyzx, l(0, 0, 0, 0) + and r16.xyz, r16.xyzx, l(127, 127, 127, 0) + movc r16.xyz, r19.xyzx, r18.xyzx, r16.xyzx + ishl r18.xyz, r21.xyzx, l(23, 23, 23, 0) + iadd r18.xyz, r18.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r16.xyz, r16.xyzx, l(16, 16, 16, 0) + iadd r16.xyz, r18.xyzx, r16.xyzx + movc r10.xyz, r17.xyzx, r16.xyzx, l(0,0,0,0) + mov r15.x, r11.w + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r14.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + ushr r15.xyzw, r11.wxxx, l(30, 10, 20, 30) + utof r13.zw, r15.xxxw + mov r15.x, r11.x + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r11.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + mul r13.xyzw, r13.xyzw, l(0.333333, 0.333333, 0.333333, 0.333333) + mov r12.w, r13.x + mov r10.w, r13.y + mov r14.w, r13.z + mov r11.w, r13.w + break + case l(4) + ishl r13.xyzw, r11.yzwx, l(16, 16, 16, 16) + mov r15.xz, r13.xxyx + mov r15.yw, r11.yyyz + ishr r15.xyzw, r15.xyzw, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r12.xy, r15.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r10.xy, r15.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r11.yz, r13.zzwz + ishr r13.xyzw, r11.ywzx, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xy, r13.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r11.xy, r13.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r12.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + break + case l(6) + ushr r13.xyzw, r11.yzwx, l(16, 16, 16, 16) + f16tof32 r12.x, r11.y + f16tof32 r12.y, r13.x + f16tof32 r10.x, r11.z + f16tof32 r10.y, r13.y + f16tof32 r14.x, r11.w + f16tof32 r14.y, r13.z + f16tof32 r11.x, r11.x + f16tof32 r11.y, r13.w + mov r12.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + break + default + mov r12.x, r11.y + mov r12.yzw, l(0,0,0,0) + mov r10.x, r11.z + mov r10.yzw, l(0,0,0,0) + mov r14.x, r11.w + mov r14.yzw, l(0,0,0,0) + mov r11.yzw, l(0,0,0,0) + break + endswitch + endif + add r8.xyzw, r8.xyzw, r12.xyzw + add r6.xyzw, r6.xyzw, r10.xyzw + add r9.xyzw, r9.xyzw, r14.xyzw + add r7.xyzw, r7.xyzw, r11.xyzw + uge r5.z, r5.z, l(6) + if_nz r5.z + ishl r5.z, l(1), r4.w + mul r1.w, r1.w, l(0.250000) + iadd r0.x, r0.x, r5.z + if_nz r4.w + ieq r5.w, r1.y, l(2) + if_nz r5.w + ishl r5.w, r0.x, l(2) + ld_raw r10.xyzw, r5.w, T0[0].zwxy + iadd r5.w, r5.w, l(16) + ld_raw r11.xyzw, r5.w, T0[0].zwxy + mov r12.xy, r10.zwzz + mov r14.xy, r11.zwzz + else + ishl r5.w, r0.x, l(2) + ld_raw r12.xy, r5.w, T0[0].xyxx + iadd r5.w, r1.y, r0.x + ishl r5.w, r5.w, l(2) + ld_raw r10.xy, r5.w, T0[0].xyxx + ishl r13.xy, l(2, 3, 0, 0), r1.xxxx + iadd r13.xy, r0.xxxx, r13.xyxx + ishl r13.xy, r13.xyxx, l(2, 2, 0, 0) + ld_raw r14.xy, r13.x, T0[0].xyxx + ld_raw r11.xy, r13.y, T0[0].xyxx + endif + switch r4.z + case l(5) + ishl r12.zw, r12.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r12.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r12.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r10.zw, r10.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r10.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r10.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r14.zw, r14.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r14.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r11.zw, r11.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r11.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r11.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r13.xy, r12.xyxx, l(16, 16, 0, 0) + f16tof32 r12.xz, r12.xxyx + f16tof32 r12.yw, r13.xxxy + ushr r13.xy, r10.xyxx, l(16, 16, 0, 0) + f16tof32 r10.xz, r10.xxyx + f16tof32 r10.yw, r13.xxxy + ushr r13.xy, r14.xyxx, l(16, 16, 0, 0) + f16tof32 r14.xz, r14.xxyx + f16tof32 r14.yw, r13.xxxy + ushr r13.xy, r11.xyxx, l(16, 16, 0, 0) + f16tof32 r11.xz, r11.xxyx + f16tof32 r11.yw, r13.xxxy + break + default + mov r12.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + break + endswitch + else + ieq r5.w, r1.y, l(1) + if_nz r5.w + ishl r5.w, r0.x, l(2) + ld_raw r11.xyzw, r5.w, T0[0].wxyz + else + ishl r5.w, r0.x, l(2) + ld_raw r11.y, r5.w, T0[0].xxxx + iadd r5.w, r1.y, r0.x + ishl r5.w, r5.w, l(2) + ld_raw r11.z, r5.w, T0[0].xxxx + ishl r13.xy, l(2, 3, 0, 0), r1.xxxx + iadd r13.xy, r0.xxxx, r13.xyxx + ishl r13.xy, r13.xyxx, l(2, 2, 0, 0) + ld_raw r11.w, r13.x, T0[0].xxxx + ld_raw r11.x, r13.y, T0[0].xxxx + endif + switch r4.z + case l(0) + case l(1) + ushr r13.yzw, r11.yyyy, l(0, 8, 16, 24) + mov r13.x, r11.y + and r13.xyzw, r13.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r12.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r13.yzw, r11.zzzz, l(0, 8, 16, 24) + mov r13.x, r11.z + and r13.xyzw, r13.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r10.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r13.yzw, r11.wwww, l(0, 8, 16, 24) + mov r13.x, r11.w + and r13.xyzw, r13.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r14.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r11.yzw, r11.xxxx, l(0, 8, 16, 24) + and r13.xyzw, r11.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r11.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r13.yzw, r11.yyyy, l(0, 10, 20, 30) + mov r13.x, r11.y + and r13.xyzw, r13.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r12.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r13.yzw, r11.zzzz, l(0, 10, 20, 30) + mov r13.x, r11.z + and r13.xyzw, r13.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r10.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r13.yzw, r11.wwww, l(0, 10, 20, 30) + mov r13.x, r11.w + and r13.xyzw, r13.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r14.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r11.yzw, r11.xxxx, l(0, 10, 20, 30) + and r13.xyzw, r11.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r11.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r13.xyzw, r11.yyyz, l(10, 20, 30, 30) + mov r15.x, r11.y + mov r15.yz, r13.xxyx + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r12.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + utof r13.xy, r13.zwzz + ushr r15.xyzw, r11.zwwz, l(10, 10, 20, 20) + mov r16.x, r11.z + mov r16.yz, r15.xxwx + and r17.xyz, r16.xyzx, l(1023, 1023, 1023, 0) + and r18.xyz, r16.xyzx, l(127, 127, 127, 0) + ubfe r19.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r16.xyzx + firstbit_hi r20.xyz, r18.xyzx + iadd r20.xyz, r20.xyzx, l(-24, -24, -24, 0) + movc r20.xyz, r18.xyzx, r20.xyzx, l(8,8,8,0) + iadd r21.xyz, -r20.xyzx, l(1, 1, 1, 0) + movc r21.xyz, r19.xyzx, r19.xyzx, r21.xyzx + bfi r16.xyz, l(7, 7, 7, 0), r20.xyzx, r16.xyzx, l(0, 0, 0, 0) + and r16.xyz, r16.xyzx, l(127, 127, 127, 0) + movc r16.xyz, r19.xyzx, r18.xyzx, r16.xyzx + ishl r18.xyz, r21.xyzx, l(23, 23, 23, 0) + iadd r18.xyz, r18.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r16.xyz, r16.xyzx, l(16, 16, 16, 0) + iadd r16.xyz, r18.xyzx, r16.xyzx + movc r10.xyz, r17.xyzx, r16.xyzx, l(0,0,0,0) + mov r15.x, r11.w + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r14.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + ushr r15.xyzw, r11.wxxx, l(30, 10, 20, 30) + utof r13.zw, r15.xxxw + mov r15.x, r11.x + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r11.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + mul r13.xyzw, r13.xyzw, l(0.333333, 0.333333, 0.333333, 0.333333) + mov r12.w, r13.x + mov r10.w, r13.y + mov r14.w, r13.z + mov r11.w, r13.w + break + case l(4) + ishl r13.xyzw, r11.yzwx, l(16, 16, 16, 16) + mov r15.xz, r13.xxyx + mov r15.yw, r11.yyyz + ishr r15.xyzw, r15.xyzw, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r12.xy, r15.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r10.xy, r15.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r11.yz, r13.zzwz + ishr r13.xyzw, r11.ywzx, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xy, r13.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r11.xy, r13.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r12.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + break + case l(6) + ushr r13.xyzw, r11.yzwx, l(16, 16, 16, 16) + f16tof32 r12.x, r11.y + f16tof32 r12.y, r13.x + f16tof32 r10.x, r11.z + f16tof32 r10.y, r13.y + f16tof32 r14.x, r11.w + f16tof32 r14.y, r13.z + f16tof32 r11.x, r11.x + f16tof32 r11.y, r13.w + mov r12.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + break + default + mov r12.x, r11.y + mov r12.yzw, l(0,0,0,0) + mov r10.x, r11.z + mov r10.yzw, l(0,0,0,0) + mov r14.x, r11.w + mov r14.yzw, l(0,0,0,0) + mov r11.yzw, l(0,0,0,0) + break + endswitch + endif + add r12.xyzw, r8.xyzw, r12.xyzw + add r10.xyzw, r6.xyzw, r10.xyzw + add r13.xyzw, r9.xyzw, r14.xyzw + add r11.xyzw, r7.xyzw, r11.xyzw + iadd r0.x, r4.y, r5.z + if_nz r4.w + ieq r4.y, r1.y, l(2) + if_nz r4.y + ishl r4.y, r0.x, l(2) + ld_raw r14.xyzw, r4.y, T0[0].zwxy + iadd r4.y, r4.y, l(16) + ld_raw r15.xyzw, r4.y, T0[0].zwxy + mov r16.xy, r14.zwzz + mov r17.xy, r15.zwzz + else + ishl r4.y, r0.x, l(2) + ld_raw r16.xy, r4.y, T0[0].xyxx + iadd r4.y, r1.y, r0.x + ishl r4.y, r4.y, l(2) + ld_raw r14.xy, r4.y, T0[0].xyxx + ishl r4.yw, l(0, 2, 0, 3), r1.xxxx + iadd r4.yw, r0.xxxx, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r17.xy, r4.y, T0[0].xyxx + ld_raw r15.xy, r4.w, T0[0].xyxx + endif + switch r4.z + case l(5) + ishl r16.zw, r16.xxxy, l(0, 0, 16, 16) + ishr r18.xyzw, r16.zxwy, l(16, 16, 16, 16) + itof r18.xyzw, r18.xyzw + mul r18.xyzw, r18.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r16.xyzw, r18.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r14.zw, r14.xxxy, l(0, 0, 16, 16) + ishr r18.xyzw, r14.zxwy, l(16, 16, 16, 16) + itof r18.xyzw, r18.xyzw + mul r18.xyzw, r18.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xyzw, r18.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r17.zw, r17.xxxy, l(0, 0, 16, 16) + ishr r18.xyzw, r17.zxwy, l(16, 16, 16, 16) + itof r18.xyzw, r18.xyzw + mul r18.xyzw, r18.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r17.xyzw, r18.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r15.zw, r15.xxxy, l(0, 0, 16, 16) + ishr r18.xyzw, r15.zxwy, l(16, 16, 16, 16) + itof r18.xyzw, r18.xyzw + mul r18.xyzw, r18.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r15.xyzw, r18.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.yw, r16.xxxy, l(0, 16, 0, 16) + f16tof32 r16.xz, r16.xxyx + f16tof32 r16.yw, r4.yyyw + ushr r4.yw, r14.xxxy, l(0, 16, 0, 16) + f16tof32 r14.xz, r14.xxyx + f16tof32 r14.yw, r4.yyyw + ushr r4.yw, r17.xxxy, l(0, 16, 0, 16) + f16tof32 r17.xz, r17.xxyx + f16tof32 r17.yw, r4.yyyw + ushr r4.yw, r15.xxxy, l(0, 16, 0, 16) + f16tof32 r15.xz, r15.xxyx + f16tof32 r15.yw, r4.yyyw + break + default + mov r16.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r17.zw, l(0,0,0,0) + mov r15.zw, l(0,0,0,0) + break + endswitch + else + ieq r4.y, r1.y, l(1) + if_nz r4.y + ishl r4.y, r0.x, l(2) + ld_raw r15.xyzw, r4.y, T0[0].wxyz + else + ishl r4.y, r0.x, l(2) + ld_raw r15.y, r4.y, T0[0].xxxx + iadd r1.y, r1.y, r0.x + ishl r1.y, r1.y, l(2) + ld_raw r15.z, r1.y, T0[0].xxxx + ishl r1.xy, l(2, 3, 0, 0), r1.xxxx + iadd r1.xy, r0.xxxx, r1.xyxx + ishl r1.xy, r1.xyxx, l(2, 2, 0, 0) + ld_raw r15.w, r1.x, T0[0].xxxx + ld_raw r15.x, r1.y, T0[0].xxxx + endif + switch r4.z + case l(0) + case l(1) + ushr r18.yzw, r15.yyyy, l(0, 8, 16, 24) + mov r18.x, r15.y + and r18.xyzw, r18.xyzw, l(255, 255, 255, 255) + utof r18.xyzw, r18.xyzw + mul r16.xyzw, r18.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r18.yzw, r15.zzzz, l(0, 8, 16, 24) + mov r18.x, r15.z + and r18.xyzw, r18.xyzw, l(255, 255, 255, 255) + utof r18.xyzw, r18.xyzw + mul r14.xyzw, r18.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r18.yzw, r15.wwww, l(0, 8, 16, 24) + mov r18.x, r15.w + and r18.xyzw, r18.xyzw, l(255, 255, 255, 255) + utof r18.xyzw, r18.xyzw + mul r17.xyzw, r18.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r15.yzw, r15.xxxx, l(0, 8, 16, 24) + and r18.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r18.xyzw, r18.xyzw + mul r15.xyzw, r18.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r18.yzw, r15.yyyy, l(0, 10, 20, 30) + mov r18.x, r15.y + and r18.xyzw, r18.xyzw, l(1023, 1023, 1023, 3) + utof r18.xyzw, r18.xyzw + mul r16.xyzw, r18.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r18.yzw, r15.zzzz, l(0, 10, 20, 30) + mov r18.x, r15.z + and r18.xyzw, r18.xyzw, l(1023, 1023, 1023, 3) + utof r18.xyzw, r18.xyzw + mul r14.xyzw, r18.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r18.yzw, r15.wwww, l(0, 10, 20, 30) + mov r18.x, r15.w + and r18.xyzw, r18.xyzw, l(1023, 1023, 1023, 3) + utof r18.xyzw, r18.xyzw + mul r17.xyzw, r18.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r15.yzw, r15.xxxx, l(0, 10, 20, 30) + and r18.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r18.xyzw, r18.xyzw + mul r15.xyzw, r18.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r18.xyzw, r15.yyyz, l(10, 20, 30, 30) + mov r19.x, r15.y + mov r19.yz, r18.xxyx + and r4.yzw, r19.xxyz, l(0, 1023, 1023, 1023) + and r20.xyz, r19.xyzx, l(127, 127, 127, 0) + ubfe r21.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r19.xyzx + firstbit_hi r22.xyz, r20.xyzx + iadd r22.xyz, r22.xyzx, l(-24, -24, -24, 0) + movc r22.xyz, r20.xyzx, r22.xyzx, l(8,8,8,0) + iadd r23.xyz, -r22.xyzx, l(1, 1, 1, 0) + movc r23.xyz, r21.xyzx, r21.xyzx, r23.xyzx + bfi r19.xyz, l(7, 7, 7, 0), r22.xyzx, r19.xyzx, l(0, 0, 0, 0) + and r19.xyz, r19.xyzx, l(127, 127, 127, 0) + movc r19.xyz, r21.xyzx, r20.xyzx, r19.xyzx + ishl r20.xyz, r23.xyzx, l(23, 23, 23, 0) + iadd r20.xyz, r20.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r19.xyz, r19.xyzx, l(16, 16, 16, 0) + iadd r19.xyz, r20.xyzx, r19.xyzx + movc r16.xyz, r4.yzwy, r19.xyzx, l(0,0,0,0) + utof r1.xy, r18.zwzz + ushr r18.xyzw, r15.zwwz, l(10, 10, 20, 20) + mov r19.x, r15.z + mov r19.yz, r18.xxwx + and r4.yzw, r19.xxyz, l(0, 1023, 1023, 1023) + and r20.xyz, r19.xyzx, l(127, 127, 127, 0) + ubfe r21.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r19.xyzx + firstbit_hi r22.xyz, r20.xyzx + iadd r22.xyz, r22.xyzx, l(-24, -24, -24, 0) + movc r22.xyz, r20.xyzx, r22.xyzx, l(8,8,8,0) + iadd r23.xyz, -r22.xyzx, l(1, 1, 1, 0) + movc r23.xyz, r21.xyzx, r21.xyzx, r23.xyzx + bfi r19.xyz, l(7, 7, 7, 0), r22.xyzx, r19.xyzx, l(0, 0, 0, 0) + and r19.xyz, r19.xyzx, l(127, 127, 127, 0) + movc r19.xyz, r21.xyzx, r20.xyzx, r19.xyzx + ishl r20.xyz, r23.xyzx, l(23, 23, 23, 0) + iadd r20.xyz, r20.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r19.xyz, r19.xyzx, l(16, 16, 16, 0) + iadd r19.xyz, r20.xyzx, r19.xyzx + movc r14.xyz, r4.yzwy, r19.xyzx, l(0,0,0,0) + mul r1.xy, r1.xyxx, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r18.x, r15.w + and r4.yzw, r18.xxyz, l(0, 1023, 1023, 1023) + and r19.xyz, r18.xyzx, l(127, 127, 127, 0) + ubfe r20.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r18.xyzx + firstbit_hi r21.xyz, r19.xyzx + iadd r21.xyz, r21.xyzx, l(-24, -24, -24, 0) + movc r21.xyz, r19.xyzx, r21.xyzx, l(8,8,8,0) + iadd r22.xyz, -r21.xyzx, l(1, 1, 1, 0) + movc r22.xyz, r20.xyzx, r20.xyzx, r22.xyzx + bfi r18.xyz, l(7, 7, 7, 0), r21.xyzx, r18.xyzx, l(0, 0, 0, 0) + and r18.xyz, r18.xyzx, l(127, 127, 127, 0) + movc r18.xyz, r20.xyzx, r19.xyzx, r18.xyzx + ishl r19.xyz, r22.xyzx, l(23, 23, 23, 0) + iadd r19.xyz, r19.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r18.xyz, r18.xyzx, l(16, 16, 16, 0) + iadd r18.xyz, r19.xyzx, r18.xyzx + movc r17.xyz, r4.yzwy, r18.xyzx, l(0,0,0,0) + ushr r18.xyzw, r15.wxxx, l(30, 10, 20, 30) + utof r4.yz, r18.xxwx + mov r18.x, r15.x + and r19.xyz, r18.xyzx, l(1023, 1023, 1023, 0) + and r20.xyz, r18.xyzx, l(127, 127, 127, 0) + ubfe r21.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r18.xyzx + firstbit_hi r22.xyz, r20.xyzx + iadd r22.xyz, r22.xyzx, l(-24, -24, -24, 0) + movc r22.xyz, r20.xyzx, r22.xyzx, l(8,8,8,0) + iadd r23.xyz, -r22.xyzx, l(1, 1, 1, 0) + movc r23.xyz, r21.xyzx, r21.xyzx, r23.xyzx + bfi r18.xyz, l(7, 7, 7, 0), r22.xyzx, r18.xyzx, l(0, 0, 0, 0) + and r18.xyz, r18.xyzx, l(127, 127, 127, 0) + movc r18.xyz, r21.xyzx, r20.xyzx, r18.xyzx + ishl r20.xyz, r23.xyzx, l(23, 23, 23, 0) + iadd r20.xyz, r20.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r18.xyz, r18.xyzx, l(16, 16, 16, 0) + iadd r18.xyz, r20.xyzx, r18.xyzx + movc r15.xyz, r19.xyzx, r18.xyzx, l(0,0,0,0) + mul r4.yz, r4.yyzy, l(0.000000, 0.333333, 0.333333, 0.000000) + mov r16.w, r1.x + mov r14.w, r1.y + mov r17.w, r4.y + mov r15.w, r4.z + break + case l(4) + ishl r18.xyzw, r15.yzwx, l(16, 16, 16, 16) + mov r19.xz, r18.xxyx + mov r19.yw, r15.yyyz + ishr r19.xyzw, r19.xyzw, l(16, 16, 16, 16) + itof r19.xyzw, r19.xyzw + mul r19.xyzw, r19.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r16.xy, r19.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r14.xy, r19.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r15.yz, r18.zzwz + ishr r18.xyzw, r15.ywzx, l(16, 16, 16, 16) + itof r18.xyzw, r18.xyzw + mul r18.xyzw, r18.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r17.xy, r18.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r15.xy, r18.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r16.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r17.zw, l(0,0,0,0) + mov r15.zw, l(0,0,0,0) + break + case l(6) + ushr r18.xyzw, r15.yzwx, l(16, 16, 16, 16) + f16tof32 r16.x, r15.y + f16tof32 r16.y, r18.x + f16tof32 r14.x, r15.z + f16tof32 r14.y, r18.y + f16tof32 r17.x, r15.w + f16tof32 r17.y, r18.z + f16tof32 r15.x, r15.x + f16tof32 r15.y, r18.w + mov r16.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r17.zw, l(0,0,0,0) + mov r15.zw, l(0,0,0,0) + break + default + mov r16.x, r15.y + mov r16.yzw, l(0,0,0,0) + mov r14.x, r15.z + mov r14.yzw, l(0,0,0,0) + mov r17.x, r15.w + mov r17.yzw, l(0,0,0,0) + mov r15.yzw, l(0,0,0,0) + break + endswitch + endif + add r8.xyzw, r12.xyzw, r16.xyzw + add r6.xyzw, r10.xyzw, r14.xyzw + add r9.xyzw, r13.xyzw, r17.xyzw + add r7.xyzw, r11.xyzw, r15.xyzw + else + mov r1.w, r4.x + endif +endif +mul r4.xyzw, r1.wwww, r8.xyzw +mul r6.xyzw, r1.wwww, r6.xyzw +mul r8.xyzw, r1.wwww, r9.xyzw +mul r7.xyzw, r1.wwww, r7.xyzw +if_nz r0.w + mov r4.xz, r4.zzxz + mov r6.xz, r6.zzxz + mov r8.xz, r8.zzxz + mov r7.xz, r7.zzxz +endif +switch r5.y + case l(3) + mov_sat r4.xyzw, r4.xyzw + mad r9.xyzw, r4.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r9.xyzw, r9.xyzw + imad r1.x, r9.y, l(32), r9.x + imad r1.x, r9.z, l(1024), r1.x + imad r1.x, r9.w, l(0x00008000), r1.x + mov_sat r6.xyzw, r6.xyzw + mad r9.xyzw, r6.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r9.xyzw, r9.xyzw + imad r1.y, r9.y, l(32), r9.x + imad r1.y, r9.z, l(1024), r1.y + ishl r1.w, r9.w, l(31) + imad r1.y, r1.y, l(0x00010000), r1.w + iadd r0.x, r1.y, r1.x + mov_sat r8.xyzw, r8.xyzw + mad r9.xyzw, r8.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r9.xyzw, r9.xyzw + imad r1.x, r9.y, l(32), r9.x + imad r1.x, r9.z, l(1024), r1.x + imad r1.x, r9.w, l(0x00008000), r1.x + mov_sat r7.xyzw, r7.xyzw + mad r9.xyzw, r7.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r9.xyzw, r9.xyzw + imad r1.y, r9.y, l(32), r9.x + imad r1.y, r9.z, l(1024), r1.y + ishl r1.w, r9.w, l(31) + imad r1.y, r1.y, l(0x00010000), r1.w + iadd r0.w, r1.y, r1.x + break + case l(4) + mov_sat r4.xyz, r4.xyzx + mad r1.xyw, r4.xyxz, l(31.000000, 63.000000, 0.000000, 31.000000), l(0.500000, 0.500000, 0.000000, 0.500000) + ftou r1.xyw, r1.xyxw + imad r1.x, r1.y, l(32), r1.x + imad r1.x, r1.w, l(2048), r1.x + mov_sat r6.xyz, r6.xyzx + mad r5.yzw, r6.xxyz, l(0.000000, 31.000000, 63.000000, 31.000000), l(0.000000, 0.500000, 0.500000, 0.500000) + ftou r5.yzw, r5.yyzw + imad r1.y, r5.z, l(32), r5.y + ishl r1.w, r5.w, l(27) + imad r1.y, r1.y, l(0x00010000), r1.w + iadd r0.x, r1.y, r1.x + mov_sat r8.xyz, r8.xyzx + mad r1.xyw, r8.xyxz, l(31.000000, 63.000000, 0.000000, 31.000000), l(0.500000, 0.500000, 0.000000, 0.500000) + ftou r1.xyw, r1.xyxw + imad r1.x, r1.y, l(32), r1.x + imad r1.x, r1.w, l(2048), r1.x + mov_sat r7.xyz, r7.xyzx + mad r5.yzw, r7.xxyz, l(0.000000, 31.000000, 63.000000, 31.000000), l(0.000000, 0.500000, 0.500000, 0.500000) + ftou r5.yzw, r5.yyzw + imad r1.y, r5.z, l(32), r5.y + ishl r1.w, r5.w, l(27) + imad r1.y, r1.y, l(0x00010000), r1.w + iadd r0.w, r1.y, r1.x + break + case l(5) + mov_sat r4.xyz, r4.xyzx + mad r1.xyw, r4.xyxz, l(31.000000, 31.000000, 0.000000, 63.000000), l(0.500000, 0.500000, 0.000000, 0.500000) + ftou r1.xyw, r1.xyxw + imad r1.x, r1.y, l(32), r1.x + imad r1.x, r1.w, l(1024), r1.x + mov_sat r6.xyz, r6.xyzx + mad r5.yzw, r6.xxyz, l(0.000000, 31.000000, 31.000000, 63.000000), l(0.000000, 0.500000, 0.500000, 0.500000) + ftou r5.yzw, r5.yyzw + imad r1.y, r5.z, l(32), r5.y + ishl r1.w, r5.w, l(26) + imad r1.y, r1.y, l(0x00010000), r1.w + iadd r0.x, r1.y, r1.x + mov_sat r8.xyz, r8.xyzx + mad r1.xyw, r8.xyxz, l(31.000000, 31.000000, 0.000000, 63.000000), l(0.500000, 0.500000, 0.000000, 0.500000) + ftou r1.xyw, r1.xyxw + imad r1.x, r1.y, l(32), r1.x + imad r1.x, r1.w, l(1024), r1.x + mov_sat r7.xyz, r7.xyzx + mad r5.yzw, r7.xxyz, l(0.000000, 31.000000, 31.000000, 63.000000), l(0.000000, 0.500000, 0.500000, 0.500000) + ftou r5.yzw, r5.yyzw + imad r1.y, r5.z, l(32), r5.y + ishl r1.w, r5.w, l(26) + imad r1.y, r1.y, l(0x00010000), r1.w + iadd r0.w, r1.y, r1.x + break + case l(10) + mov_sat r4.xy, r4.xyxx + mov_sat r4.zw, r6.xxxy + mad r9.xyzw, r4.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r9.xyzw, r9.xyzw + imad r1.x, r9.y, l(256), r9.x + imad r1.x, r9.z, l(0x00010000), r1.x + imad r0.x, r9.w, l(0x01000000), r1.x + mov_sat r8.xy, r8.xyxx + mov_sat r8.zw, r7.xxxy + mad r9.xyzw, r8.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r9.xyzw, r9.xyzw + imad r1.x, r9.y, l(256), r9.x + imad r1.x, r9.z, l(0x00010000), r1.x + imad r0.w, r9.w, l(0x01000000), r1.x + break + case l(15) + mov_sat r4.xyzw, r4.xyzw + mad r9.xyzw, r4.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r9.xyzw, r9.xyzw + imad r1.x, r9.y, l(16), r9.x + imad r1.x, r9.z, l(256), r1.x + imad r1.x, r9.w, l(4096), r1.x + mov_sat r6.xyzw, r6.xyzw + mad r9.xyzw, r6.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r9.xyzw, r9.xyzw + imad r1.y, r9.y, l(16), r9.x + imad r1.y, r9.z, l(256), r1.y + ishl r1.w, r9.w, l(28) + imad r1.y, r1.y, l(0x00010000), r1.w + iadd r0.x, r1.y, r1.x + mov_sat r8.xyzw, r8.xyzw + mad r9.xyzw, r8.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r9.xyzw, r9.xyzw + imad r1.x, r9.y, l(16), r9.x + imad r1.x, r9.z, l(256), r1.x + imad r1.x, r9.w, l(4096), r1.x + mov_sat r7.xyzw, r7.xyzw + mad r9.xyzw, r7.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r9.xyzw, r9.xyzw + imad r1.y, r9.y, l(16), r9.x + imad r1.y, r9.z, l(256), r1.y + ishl r1.w, r9.w, l(28) + imad r1.y, r1.y, l(0x00010000), r1.w + iadd r0.w, r1.y, r1.x + break + case l(24) + mov_sat r7.z, r4.x + mov_sat r7.y, r6.x + mov_sat r7.w, r8.x + mov_sat r7.x, r7.x + mad r9.xyzw, r7.zywx, l(65535.000000, 65535.000000, 65535.000000, 65535.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r9.xyzw, r9.xyzw + imad r0.xw, r9.yyyw, l(0x00010000, 0, 0, 0x00010000), r9.xxxz + break + default + f32tof16 r1.x, r4.x + f32tof16 r1.y, r6.x + imad r0.x, r1.y, l(0x00010000), r1.x + f32tof16 r1.x, r8.x + f32tof16 r1.y, r7.x + imad r0.w, r1.y, l(0x00010000), r1.x + break +endswitch +iadd r2.xyzw, r2.xyzw, r3.xyzw +if_nz r0.z + ubfe r0.z, l(3), l(4), CB0[0][0].z + ishl r1.x, r1.z, l(5) + ishr r3.xyzw, r2.zwzw, l(4, 5, 3, 3) + ishr r1.y, r0.z, l(2) + ushr r1.x, r1.x, l(4) + and r1.x, r1.x, l(2046) + imad r1.x, r1.y, r1.x, r3.x + ushr r1.z, r5.x, l(5) + imad r1.x, r1.x, r1.z, r3.y + ishl r1.z, r2.z, l(9) + and r1.z, r1.z, l(3072) + bfi r1.z, l(3), l(7), r2.w, r1.z + ishr r1.z, r1.z, l(6) + iadd r1.y, r1.y, r3.z + bfi r1.w, l(1), l(1), r1.y, l(0) + iadd r1.w, r1.w, r3.w + bfi r1.w, l(2), l(1), r1.w, l(0) + bfi r1.y, l(1), l(0), r1.y, r1.w + and r1.w, r1.z, l(48) + bfi r3.xy, l(21, 21, 0, 0), l(9, 12, 0, 0), r1.xxxx, l(0, 0, 0, 0) + imad r1.xw, r1.wwww, l(2, 0, 0, 16), r3.xxxy + bfi r1.xz, l(4, 0, 4, 0), l(0, 0, 3, 0), r1.zzzz, r1.xxwx + bfi r1.xz, l(2, 0, 2, 0), l(7, 0, 10, 0), r0.zzzz, r1.xxzx + ubfe r0.z, l(3), l(6), r1.x + and r1.w, r1.y, l(6) + bfi r1.y, l(1), l(8), r1.y, l(0) + imad r0.z, r0.z, l(32), r1.y + imad r0.z, r1.w, l(4), r0.z + bfi r1.xy, l(1, 1, 0, 0), l(4, 7, 0, 0), r2.zzzz, r1.xzxx + bfi r0.z, l(9), l(3), r0.z, r1.y + bfi r0.z, l(6), l(0), r1.x, r0.z +else + ishr r1.xyzw, r2.xyzw, l(5, 5, 2, 3) + ushr r2.x, r5.x, l(5) + imad r1.x, r1.y, r2.x, r1.x + ishl r2.xy, r2.zzzz, l(3, 7, 0, 0) + and r2.xy, r2.xyxx, l(112, 2048, 0, 0) + bfi r1.y, l(3), l(1), r2.w, r2.x + ishl r2.x, r2.x, l(1) + bfi r2.x, l(3), l(2), r2.w, r2.x + and r2.x, r2.x, l(224) + bfi r2.w, l(24), l(8), r1.x, r2.x + bfi r2.w, l(4), l(0), r1.y, r2.w + bfi r2.w, l(1), l(4), r2.z, r2.w + ishl r3.xy, r2.xxxx, l(3, 2, 0, 0) + bfi r3.xy, l(24, 24, 0, 0), l(11, 10, 0, 0), r1.xxxx, r3.xyxx + bfi r1.xy, l(4, 4, 0, 0), l(3, 2, 0, 0), r1.yyyy, r3.xyxx + bfi r1.xy, l(1, 1, 0, 0), l(7, 6, 0, 0), r2.zzzz, r1.xyxx + bfi r1.x, l(12), l(0), r2.y, r1.x + and r1.y, r1.y, l(1792) + iadd r1.x, r1.x, r1.y + and r1.y, r1.z, l(2) + iadd r1.y, r1.w, r1.y + bfi r1.y, l(2), l(6), r1.y, l(0) + iadd r1.x, r1.x, r1.y + bfi r0.z, l(6), l(0), r2.w, r1.x +endif +iadd r0.z, r0.z, CB0[0][1].x +ushr r0.z, r0.z, l(3) +ieq r0.y, r0.y, l(1) +if_nz r0.y + ishl r1.xy, r0.xwxx, l(8, 8, 0, 0) + ushr r1.zw, r0.xxxw, l(0, 0, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0x00ff00ff, 0x00ff00ff) + iadd r0.xw, r1.zzzw, r1.xxxy +endif +store_uav_typed U0[0].xyzw, r0.zzzz, r0.xwxx +ret +// Approximately 1328 instruction slots used +#endif + +const BYTE resolve_full_16bpp_cs[] = { + 68, 88, 66, 67, 197, 47, 56, 184, 10, 51, 243, 235, 193, 60, 210, 32, 141, 228, 24, + 157, 1, 0, 0, 0, 0, 162, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 208, 2, + 0, 0, 224, 2, 0, 0, 240, 2, 0, 0, 100, 161, 0, 0, 82, 68, 69, 70, 148, + 2, 0, 0, 1, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 105, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 101, 100, 114, 97, 109, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 213, 0, 0, 0, 5, 0, 0, 0, 252, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 196, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 4, 2, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 31, 2, 0, 0, 8, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 52, 2, 0, 0, 12, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 84, 2, 0, + 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, + 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 101, 100, 114, 97, 109, 95, 105, 110, 102, + 111, 0, 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 218, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 99, 111, + 111, 114, 100, 105, 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 105, 110, 102, 111, 0, 120, 101, 95, + 114, 101, 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 99, 111, 111, 114, 100, 105, + 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 95, 98, 97, 115, 101, 0, 77, 105, 99, 114, 111, 115, 111, + 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, + 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, + 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 108, 158, 0, 0, + 81, 0, 5, 0, 155, 39, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 161, 0, 0, 6, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 95, 0, 0, + 2, 50, 0, 2, 0, 104, 0, 0, 2, 24, 0, 0, 0, 155, 0, 0, 4, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, 242, 0, 16, 0, 0, + 0, 0, 0, 134, 138, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 255, 3, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 1, 85, 0, 0, 12, 114, 0, 16, 0, 1, 0, 0, 0, 86, 135, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, + 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, 242, 0, 16, 0, + 2, 0, 0, 0, 246, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 20, 0, + 0, 0, 41, 0, 0, 9, 146, 0, 16, 0, 3, 0, 0, 0, 6, 0, 2, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, + 26, 0, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 17, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 11, 0, + 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 13, + 0, 0, 0, 24, 0, 0, 0, 28, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, + 0, 20, 50, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 15, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 139, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 128, 63, 140, 0, 0, 13, 18, 0, 16, 0, 5, 0, 0, 0, + 1, 64, 0, 0, 10, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 58, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, + 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 138, 0, 0, 17, 98, 0, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, + 0, 166, 139, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 4, 98, 0, 16, 0, 3, 0, 0, 0, 86, 5, 2, 0, 30, 0, 0, 7, 50, + 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 182, 15, 16, 0, + 3, 0, 0, 0, 80, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 58, 0, + 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 42, + 0, 16, 0, 5, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, 0, + 5, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, + 0, 31, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 34, 0, + 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 18, 0, 0, 1, 54, + 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 1, 21, 0, 0, 1, 80, 0, 0, 10, 194, 0, 16, 0, 6, 0, 0, + 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 6, + 0, 0, 0, 166, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 50, 0, 16, + 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 6, 0, + 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, + 6, 0, 0, 0, 70, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, + 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 6, + 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 80, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 78, 0, 0, 8, 50, 0, + 16, 0, 7, 0, 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 70, + 0, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 7, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 35, 0, 0, 10, 50, + 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 128, 65, 0, 0, 0, 7, 0, 0, 0, + 70, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, + 9, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 5, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 78, 0, 0, 8, 0, 208, 0, 0, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 40, 0, 30, 0, 0, 7, + 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, + 0, 16, 0, 4, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 242, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, + 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, + 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, + 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 4, + 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 50, 0, 16, 0, 8, 0, 0, 0, 230, 10, 16, 0, 6, 0, 0, 0, 54, 0, 0, + 5, 50, 0, 16, 0, 9, 0, 0, 0, 230, 10, 16, 0, 7, 0, 0, 0, 18, 0, + 0, 1, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, + 8, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, + 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, + 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, + 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, + 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 4, 0, + 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, + 9, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 7, 0, 0, 0, 26, 0, + 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, + 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, + 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 8, 0, 0, + 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 10, + 0, 0, 0, 38, 7, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, + 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, + 0, 10, 194, 0, 16, 0, 6, 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 42, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 38, 7, 16, 0, 6, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 9, 0, 0, 0, + 6, 4, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 10, 0, + 0, 0, 38, 7, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, + 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, + 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, + 10, 194, 0, 16, 0, 7, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, + 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 38, 7, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, + 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 8, 0, 0, 0, 6, 1, + 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 8, 0, 0, 0, 6, + 4, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, + 70, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 6, 0, + 0, 0, 6, 1, 16, 0, 6, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 6, + 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, + 4, 0, 0, 0, 70, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, + 16, 0, 9, 0, 0, 0, 6, 1, 16, 0, 9, 0, 0, 0, 131, 0, 0, 5, 162, + 0, 16, 0, 9, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, + 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, + 0, 5, 82, 0, 16, 0, 7, 0, 0, 0, 6, 1, 16, 0, 7, 0, 0, 0, 131, + 0, 0, 5, 162, 0, 16, 0, 7, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, + 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 194, 0, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, + 194, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, + 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, + 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 7, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 18, 0, 0, 1, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 34, + 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, + 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, 7, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 41, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, + 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, + 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, + 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 7, 0, 0, + 0, 26, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, + 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, + 1, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, 86, 5, 16, + 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, + 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 26, + 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, + 0, 10, 0, 0, 0, 166, 10, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, + 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 85, 0, 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, 246, 15, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, + 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 7, 0, + 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, + 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, + 0, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, 86, + 5, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, + 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, + 0, 26, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 8, 32, + 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, + 0, 16, 0, 10, 0, 0, 0, 166, 10, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, + 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, 246, 15, 16, 0, + 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 58, 0, + 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 9, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, + 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, + 7, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 2, + 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, + 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, + 0, 86, 9, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 20, 0, + 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, + 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, + 11, 0, 0, 0, 6, 1, 16, 0, 10, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, + 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 15, 114, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, + 135, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, + 0, 30, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, + 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, + 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, + 16, 0, 16, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, + 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 114, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, + 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 11, 0, + 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 11, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, + 0, 70, 2, 16, 0, 11, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 13, 0, + 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, + 0, 11, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, + 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, + 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 10, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 10, 0, 0, 0, 230, 11, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, + 54, 0, 0, 5, 98, 0, 16, 0, 11, 0, 0, 0, 6, 3, 16, 0, 10, 0, 0, + 0, 1, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 14, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 11, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, + 0, 70, 2, 16, 0, 13, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 15, 0, + 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, + 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, + 15, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 128, 65, + 0, 0, 0, 15, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, + 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, + 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 41, 0, + 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, + 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 12, 114, 0, + 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 56, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 58, + 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, + 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 12, 0, + 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 135, 0, 0, 5, 114, + 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 30, 0, 0, 10, + 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, + 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, + 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, + 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 15, 0, 0, + 0, 70, 2, 16, 128, 65, 0, 0, 0, 14, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, + 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, + 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 10, 0, 0, 0, 70, + 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, + 10, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, + 0, 15, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, + 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, + 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, + 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 10, + 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, + 55, 0, 0, 12, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, + 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 10, + 0, 0, 0, 54, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, + 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 86, 0, 0, 5, 50, 0, 16, + 0, 11, 0, 0, 0, 198, 0, 16, 0, 10, 0, 0, 0, 54, 0, 0, 5, 18, 0, + 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, + 0, 0, 15, 114, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 10, 0, + 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 13, + 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, + 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, + 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, + 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 14, + 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, + 140, 0, 0, 17, 114, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, + 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, + 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 13, + 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, + 13, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, + 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, + 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, + 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, + 2, 16, 0, 10, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 7, 0, 0, 0, + 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, + 0, 10, 50, 0, 16, 0, 10, 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 130, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, + 0, 54, 0, 0, 5, 130, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 4, 0, + 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 10, + 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, + 10, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 150, 3, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 11, 0, 0, 0, 6, 1, 16, 0, + 10, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 11, 0, 0, 0, 86, 9, 16, + 0, 7, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, + 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, + 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, + 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 8, + 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, + 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, + 0, 6, 0, 0, 0, 230, 10, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 98, + 0, 16, 0, 7, 0, 0, 0, 166, 11, 16, 0, 10, 0, 0, 0, 42, 0, 0, 10, + 242, 0, 16, 0, 10, 0, 0, 0, 214, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, + 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, + 58, 52, 0, 0, 10, 50, 0, 16, 0, 9, 0, 0, 0, 70, 0, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, + 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 7, 0, 0, 0, 230, 10, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 8, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 10, 0, 0, 0, 150, 3, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, + 0, 0, 5, 18, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, + 131, 0, 0, 5, 34, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, + 0, 131, 0, 0, 5, 18, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 7, 0, + 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 10, + 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, + 7, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, + 0, 10, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, + 16, 0, 7, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 7, 0, 0, 0, 58, + 0, 16, 0, 10, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, + 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 8, + 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 6, 0, 0, 0, 42, 0, + 16, 0, 7, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, + 0, 54, 0, 0, 8, 226, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 226, + 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, + 1, 80, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 5, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, + 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 30, 0, 0, 7, 34, 0, 16, + 0, 4, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 80, 0, + 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 4, 0, 0, 0, 32, 0, 0, 7, 130, + 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 10, 0, 0, 0, 58, + 0, 16, 0, 5, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, + 0, 1, 64, 0, 0, 16, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 11, 0, + 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 12, 0, 0, 0, 230, 10, 16, 0, + 10, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 14, 0, 0, 0, 230, 10, 16, + 0, 11, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, + 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 50, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, + 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 4, 0, + 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, + 10, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 13, 0, 0, 0, + 86, 5, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, 41, 0, 0, + 10, 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, + 0, 0, 8, 50, 0, 16, 0, 14, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, + 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, + 0, 11, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 70, 112, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, + 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, + 194, 0, 16, 0, 12, 0, 0, 0, 6, 4, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, + 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 38, 7, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 43, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, + 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 10, 0, 0, 0, 6, 4, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, + 38, 7, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 13, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, + 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, + 0, 16, 0, 14, 0, 0, 0, 6, 4, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, + 10, 242, 0, 16, 0, 13, 0, 0, 0, 38, 7, 16, 0, 14, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, + 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, + 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, + 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 11, 0, 0, 0, 6, 4, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 38, + 7, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, + 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, + 11, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, + 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 13, + 0, 0, 0, 70, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, + 0, 12, 0, 0, 0, 6, 1, 16, 0, 12, 0, 0, 0, 131, 0, 0, 5, 162, 0, + 16, 0, 12, 0, 0, 0, 6, 4, 16, 0, 13, 0, 0, 0, 85, 0, 0, 10, 50, + 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, + 5, 82, 0, 16, 0, 10, 0, 0, 0, 6, 1, 16, 0, 10, 0, 0, 0, 131, 0, + 0, 5, 162, 0, 16, 0, 10, 0, 0, 0, 6, 4, 16, 0, 13, 0, 0, 0, 85, + 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 14, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 131, 0, 0, 5, 82, 0, 16, 0, 14, 0, 0, 0, 6, 1, 16, 0, 14, 0, + 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 14, 0, 0, 0, 6, 4, 16, 0, 13, + 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 11, 0, 0, 0, 6, 1, + 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 11, 0, 0, 0, 6, + 4, 16, 0, 13, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, + 194, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 18, + 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, + 0, 5, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, + 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, + 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 54, 121, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, + 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 5, + 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 4, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, + 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, + 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, + 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 13, + 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, + 41, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, + 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 13, + 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, + 18, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 6, 112, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, + 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, + 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, + 13, 0, 0, 0, 86, 5, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, + 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, + 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, + 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, + 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, 0, 166, 10, 16, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, + 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 42, 0, 16, 0, 11, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, + 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, + 0, 246, 15, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, + 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, + 10, 226, 0, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, + 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, + 16, 0, 13, 0, 0, 0, 86, 5, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, + 18, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, + 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, + 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, 0, 166, 10, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, + 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 42, 0, 16, + 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, + 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, + 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, + 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 13, + 0, 0, 0, 246, 15, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 13, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, + 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, + 0, 0, 10, 226, 0, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, + 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 13, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, + 128, 58, 171, 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, + 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 13, 0, 0, 0, 86, 9, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 54, + 0, 0, 5, 98, 0, 16, 0, 15, 0, 0, 0, 6, 1, 16, 0, 13, 0, 0, 0, + 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 15, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 17, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, + 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, + 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 11, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, + 0, 0, 19, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, + 0, 20, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, + 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 0, 41, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, + 0, 12, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 86, 0, 0, 5, 50, 0, 16, 0, 13, 0, 0, 0, 230, 10, 16, 0, + 13, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 230, 11, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 16, 0, 0, 0, 42, + 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 16, 0, 0, 0, + 6, 3, 16, 0, 15, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 18, + 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, + 0, 19, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 135, 0, 0, 5, + 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 30, 0, 0, + 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, + 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, + 0, 0, 12, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 21, 0, + 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 20, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, + 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, + 0, 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 140, 0, 0, 17, 114, 0, + 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, + 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, + 0, 16, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, + 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 16, 0, + 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, + 16, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, + 0, 55, 0, 0, 12, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 17, 0, + 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, + 15, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, + 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, + 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, + 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, + 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, + 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, 0, + 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, 0, + 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, 0, + 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, + 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 15, 0, 0, 0, 54, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 30, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 86, 0, + 0, 5, 194, 0, 16, 0, 13, 0, 0, 0, 6, 12, 16, 0, 15, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, + 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 15, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 17, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, + 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, + 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 11, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, + 0, 0, 19, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, + 0, 20, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, + 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 0, 41, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, + 0, 11, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, 171, 170, 170, + 62, 171, 170, 170, 62, 54, 0, 0, 5, 130, 0, 16, 0, 12, 0, 0, 0, 10, 0, + 16, 0, 13, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 10, 0, 0, 0, 26, + 0, 16, 0, 13, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 14, 0, 0, 0, + 42, 0, 16, 0, 13, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 11, 0, 0, + 0, 58, 0, 16, 0, 13, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, + 0, 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 150, + 3, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 15, 0, 0, + 0, 6, 1, 16, 0, 13, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 15, 0, + 0, 0, 86, 9, 16, 0, 11, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, + 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, + 50, 0, 16, 0, 12, 0, 0, 0, 70, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, + 0, 10, 50, 0, 16, 0, 10, 0, 0, 0, 230, 10, 16, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 98, 0, 16, 0, 11, 0, 0, 0, 166, 11, 16, 0, 13, 0, 0, + 0, 42, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 214, 2, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, + 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, + 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 14, 0, 0, 0, 70, + 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, + 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 11, 0, 0, + 0, 230, 10, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 150, 3, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, + 0, 11, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 12, 0, 0, 0, 10, 0, + 16, 0, 13, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 42, + 0, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 10, 0, 0, 0, + 26, 0, 16, 0, 13, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, + 0, 58, 0, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 14, 0, + 0, 0, 42, 0, 16, 0, 13, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 11, + 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, + 11, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 5, + 18, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, + 8, 226, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, + 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 58, 0, + 16, 0, 11, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 14, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 226, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, + 0, 1, 21, 0, 0, 1, 0, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 0, 0, 0, 7, + 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 0, 0, 0, 7, 242, + 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 80, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, + 0, 5, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 31, 0, 4, 3, 42, 0, + 16, 0, 5, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 56, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 128, 62, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 58, + 0, 16, 0, 4, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, + 3, 58, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 242, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, + 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 16, 0, + 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 5, + 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 50, 0, 16, 0, 12, 0, 0, 0, 230, 10, 16, 0, 10, 0, 0, 0, 54, 0, 0, + 5, 50, 0, 16, 0, 14, 0, 0, 0, 230, 10, 16, 0, 11, 0, 0, 0, 18, 0, + 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, + 12, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, + 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, + 0, 5, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, + 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, + 30, 0, 0, 7, 50, 0, 16, 0, 13, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 13, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 13, 0, + 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, + 14, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 11, 0, 0, 0, 26, 0, + 16, 0, 13, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, + 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, + 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 12, 0, 0, + 0, 6, 4, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 13, + 0, 0, 0, 38, 7, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, + 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, + 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, + 0, 10, 194, 0, 16, 0, 10, 0, 0, 0, 6, 4, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 42, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 38, 7, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 14, 0, 0, 0, + 6, 4, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 13, 0, + 0, 0, 38, 7, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, + 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 1, + 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, + 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, + 10, 194, 0, 16, 0, 11, 0, 0, 0, 6, 4, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, + 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 38, 7, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 43, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, + 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 12, 0, 0, 0, 6, 1, + 16, 0, 12, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 12, 0, 0, 0, 6, + 4, 16, 0, 13, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, + 70, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 10, 0, + 0, 0, 6, 1, 16, 0, 10, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 10, + 0, 0, 0, 6, 4, 16, 0, 13, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, + 13, 0, 0, 0, 70, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, + 16, 0, 14, 0, 0, 0, 6, 1, 16, 0, 14, 0, 0, 0, 131, 0, 0, 5, 162, + 0, 16, 0, 14, 0, 0, 0, 6, 4, 16, 0, 13, 0, 0, 0, 85, 0, 0, 10, + 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, + 0, 5, 82, 0, 16, 0, 11, 0, 0, 0, 6, 1, 16, 0, 11, 0, 0, 0, 131, + 0, 0, 5, 162, 0, 16, 0, 11, 0, 0, 0, 6, 4, 16, 0, 13, 0, 0, 0, + 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, + 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, + 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, 41, 0, + 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 11, 0, 0, 0, + 58, 0, 16, 0, 5, 0, 0, 0, 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 34, + 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, + 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, 11, 0, 0, 0, + 58, 0, 16, 0, 5, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 41, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, + 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 13, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, + 0, 13, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, + 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 11, 0, 0, + 0, 26, 0, 16, 0, 13, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, + 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, + 1, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, 0, 86, 5, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, + 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 26, + 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, + 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 12, + 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, + 0, 13, 0, 0, 0, 166, 10, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, + 0, 16, 0, 13, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, + 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, 0, 246, 15, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, + 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, + 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, + 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, + 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 11, 0, + 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 13, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, + 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, + 0, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, 0, 86, + 5, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, + 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, + 0, 26, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, + 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 12, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 8, 32, + 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, + 0, 16, 0, 13, 0, 0, 0, 166, 10, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 13, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 13, 0, + 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, + 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, 0, 246, 15, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 58, 0, + 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, + 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, + 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 14, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, + 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, + 11, 0, 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, + 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 2, + 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, + 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, + 0, 86, 9, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 20, 0, + 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, + 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, + 15, 0, 0, 0, 6, 1, 16, 0, 13, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, + 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, + 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, + 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, + 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, + 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, 0, + 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, 0, + 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, 0, + 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, + 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, + 50, 0, 16, 0, 13, 0, 0, 0, 230, 10, 16, 0, 13, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 15, 0, 0, 0, 230, 11, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 16, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, + 54, 0, 0, 5, 98, 0, 16, 0, 16, 0, 0, 0, 6, 3, 16, 0, 15, 0, 0, + 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 19, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 16, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 20, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 20, 0, + 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, + 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, + 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 128, 65, + 0, 0, 0, 20, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 21, 0, 0, + 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, + 16, 0, 21, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 41, 0, + 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 2, + 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, + 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 55, 0, 0, 12, 114, 0, + 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, + 0, 11, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 18, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, + 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 30, 0, 0, 10, 114, 0, + 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 232, + 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, + 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, + 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 20, 0, 0, 0, 70, + 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, + 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, + 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, + 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 20, + 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, + 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, + 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, + 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, + 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, + 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, + 0, 54, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 10, 0, + 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 86, 0, 0, 5, 194, 0, 16, 0, 13, + 0, 0, 0, 6, 12, 16, 0, 15, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, + 15, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, + 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, + 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, + 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, + 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, + 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, 0, + 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, 0, + 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, 0, + 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, + 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 171, 170, 170, 62, 171, 170, 170, 62, 171, 170, 170, 62, 171, 170, 170, 62, 54, 0, + 0, 5, 130, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 54, + 0, 0, 5, 130, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, + 54, 0, 0, 5, 130, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 13, 0, 0, + 0, 54, 0, 0, 5, 130, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 13, 0, + 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 150, 3, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 54, 0, 0, 5, 82, 0, 16, 0, 15, 0, 0, 0, 6, 1, 16, 0, 13, 0, + 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 15, 0, 0, 0, 86, 9, 16, 0, 11, + 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, + 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 12, 0, 0, + 0, 70, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 10, + 0, 0, 0, 230, 10, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, + 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, + 0, 11, 0, 0, 0, 166, 11, 16, 0, 13, 0, 0, 0, 42, 0, 0, 10, 242, 0, + 16, 0, 13, 0, 0, 0, 214, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, + 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, + 0, 0, 10, 50, 0, 16, 0, 14, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 0, 0, 10, 50, 0, 16, 0, 11, 0, 0, 0, 230, 10, 16, 0, 13, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 14, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 13, 0, 0, 0, 150, 3, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, + 5, 18, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 131, 0, + 0, 5, 34, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 131, + 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, + 131, 0, 0, 5, 34, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, + 0, 131, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 11, 0, + 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 13, + 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, + 11, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, + 0, 13, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, + 0, 26, 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, + 11, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 54, + 0, 0, 8, 226, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, 0, + 0, 0, 7, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, + 70, 14, 16, 0, 12, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 0, 0, + 0, 7, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, + 14, 16, 0, 14, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 11, 0, 0, 0, + 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 30, 0, 0, + 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 42, 0, + 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 4, 0, 0, 0, 32, + 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 4, 0, 0, + 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 14, + 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, + 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 165, 0, 0, 8, 242, 0, + 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 230, 116, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 16, 0, 0, 0, + 230, 10, 16, 0, 14, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 17, 0, 0, + 0, 230, 10, 16, 0, 15, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 34, 0, + 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 16, 0, 0, 0, 26, 0, 16, 0, + 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, + 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, + 50, 0, 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 162, 0, 16, 0, + 4, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, + 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 17, 0, 0, 0, 26, 0, 16, 0, + 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, + 8, 50, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 70, 112, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, + 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, + 41, 0, 0, 10, 194, 0, 16, 0, 16, 0, 0, 0, 6, 4, 16, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 38, 7, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, + 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, + 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, + 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 14, 0, + 0, 0, 6, 4, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, + 18, 0, 0, 0, 38, 7, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, + 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, + 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, + 0, 0, 10, 194, 0, 16, 0, 17, 0, 0, 0, 6, 4, 16, 0, 17, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 42, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 38, 7, 16, 0, 17, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, + 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, + 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, + 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, 0, 70, + 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, + 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 15, 0, 0, + 0, 6, 4, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 18, + 0, 0, 0, 38, 7, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, + 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, + 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, + 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, 10, 162, + 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, + 5, 82, 0, 16, 0, 16, 0, 0, 0, 6, 1, 16, 0, 16, 0, 0, 0, 131, 0, + 0, 5, 162, 0, 16, 0, 16, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 85, + 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 14, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 131, 0, 0, 5, 82, 0, 16, 0, 14, 0, 0, 0, 6, 1, 16, 0, 14, 0, + 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 14, 0, 0, 0, 86, 13, 16, 0, 4, + 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, + 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 17, 0, 0, 0, 6, 1, + 16, 0, 17, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 17, 0, 0, 0, 86, + 13, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, + 6, 4, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 15, 0, + 0, 0, 6, 1, 16, 0, 15, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 15, + 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, + 54, 0, 0, 8, 194, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 17, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, + 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 242, 0, 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, + 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, + 7, 34, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 15, 0, 0, 0, 26, + 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 66, 0, 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 50, + 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 1, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 15, 0, 0, 0, 10, + 0, 16, 0, 1, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 165, 0, 0, 8, 18, 0, 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, + 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, + 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 226, 0, 16, 0, 18, 0, 0, 0, 86, 5, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 26, 0, 16, 0, 15, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, + 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 86, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, 18, + 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 18, 0, 0, 0, 166, 10, 16, + 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, + 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 42, + 0, 16, 0, 15, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, + 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 18, 0, + 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 14, + 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, + 0, 18, 0, 0, 0, 246, 15, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, + 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, + 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 6, 0, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, + 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, + 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, + 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 85, 0, + 0, 10, 226, 0, 16, 0, 18, 0, 0, 0, 86, 5, 16, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, + 54, 0, 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 26, 0, 16, 0, 15, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, + 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, + 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, + 0, 18, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, + 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 18, 0, 0, 0, 166, + 10, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, + 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 18, 0, 0, + 0, 42, 0, 16, 0, 15, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 18, 0, + 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, + 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 14, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 8, 32, + 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, + 0, 16, 0, 18, 0, 0, 0, 246, 15, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, 0, 70, 14, 16, 0, 18, 0, + 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, + 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 6, 0, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, + 70, 14, 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, + 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, + 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, + 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, + 85, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 86, 9, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 30, 0, + 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 19, 0, 0, 0, 26, 0, 16, 0, 15, + 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 19, 0, 0, 0, 6, 1, 16, 0, + 18, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, 4, 0, 0, 0, 6, 9, 16, + 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 21, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, + 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, + 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, 232, 255, + 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, + 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, + 22, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 23, 0, 0, 0, 70, 2, + 16, 128, 65, 0, 0, 0, 22, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 23, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, + 0, 70, 2, 16, 0, 23, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, + 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, + 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 41, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 23, 0, + 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, + 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, + 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 55, 0, 0, + 12, 114, 0, 16, 0, 16, 0, 0, 0, 150, 7, 16, 0, 4, 0, 0, 0, 70, 2, + 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 50, 0, 16, 0, 1, 0, 0, 0, + 230, 10, 16, 0, 18, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, + 0, 230, 11, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 19, + 0, 0, 0, 42, 0, 16, 0, 15, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, + 19, 0, 0, 0, 6, 3, 16, 0, 18, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, + 0, 4, 0, 0, 0, 6, 9, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 15, 114, 0, 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 135, 0, 0, 5, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, + 0, 30, 0, 0, 10, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, 0, + 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, + 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, + 20, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, + 16, 0, 23, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 22, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 23, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, + 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 140, 0, + 0, 17, 114, 0, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, + 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, + 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, + 0, 70, 2, 16, 0, 19, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 20, 0, + 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, + 0, 19, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 150, 7, + 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 171, 170, 170, 62, 171, 170, 170, 62, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 1, + 0, 0, 10, 226, 0, 16, 0, 4, 0, 0, 0, 6, 9, 16, 0, 18, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 18, 0, + 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, + 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 18, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 21, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 21, 0, 0, 0, + 70, 2, 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, + 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 21, 0, + 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 11, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, + 0, 21, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 22, 0, 0, 0, 70, + 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, + 22, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, + 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, + 0, 9, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 41, 0, 0, 10, + 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, + 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, + 41, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 19, + 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, + 17, 0, 0, 0, 150, 7, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 54, 0, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, + 30, 0, 0, 0, 86, 0, 0, 5, 98, 0, 16, 0, 4, 0, 0, 0, 6, 3, 16, + 0, 18, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 10, 0, + 16, 0, 15, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, + 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 21, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 135, 0, 0, 5, 114, 0, + 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 30, 0, 0, 10, 114, + 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, + 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, + 12, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, + 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 23, 0, 0, 0, + 70, 2, 16, 128, 65, 0, 0, 0, 22, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, + 16, 0, 23, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, + 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, + 18, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 18, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, + 18, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, + 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, + 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, + 23, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, + 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, + 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 18, 0, + 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 55, + 0, 0, 12, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, 98, 0, 16, 0, 4, 0, + 0, 0, 86, 6, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 171, + 170, 170, 62, 171, 170, 170, 62, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, + 16, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, + 0, 14, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, + 16, 0, 17, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, + 0, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 2, 0, 0, 1, + 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 18, 0, 0, 0, 150, 3, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, 82, + 0, 16, 0, 19, 0, 0, 0, 6, 1, 16, 0, 18, 0, 0, 0, 54, 0, 0, 5, + 162, 0, 16, 0, 19, 0, 0, 0, 86, 9, 16, 0, 15, 0, 0, 0, 42, 0, 0, + 10, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, + 0, 0, 5, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, + 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, + 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 16, 0, 0, 0, 70, 0, 16, 0, 19, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, + 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 14, 0, 0, 0, 230, 10, 16, + 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 15, 0, 0, 0, 166, + 11, 16, 0, 18, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, + 214, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 18, 0, + 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 18, + 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, + 0, 17, 0, 0, 0, 70, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, + 0, 16, 0, 15, 0, 0, 0, 230, 10, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 14, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 17, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, + 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, + 0, 150, 3, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 16, + 0, 0, 0, 26, 0, 16, 0, 15, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, + 16, 0, 0, 0, 10, 0, 16, 0, 18, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, + 0, 14, 0, 0, 0, 42, 0, 16, 0, 15, 0, 0, 0, 131, 0, 0, 5, 34, 0, + 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, 18, 0, 0, 0, 131, 0, 0, 5, 18, + 0, 16, 0, 17, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 131, 0, 0, 5, + 34, 0, 16, 0, 17, 0, 0, 0, 42, 0, 16, 0, 18, 0, 0, 0, 131, 0, 0, + 5, 18, 0, 16, 0, 15, 0, 0, 0, 10, 0, 16, 0, 15, 0, 0, 0, 131, 0, + 0, 5, 34, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 54, + 0, 0, 8, 194, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 17, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, 0, + 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 16, 0, 0, 0, 26, 0, 16, 0, 15, + 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 15, 0, 0, 0, 54, 0, + 0, 8, 226, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, + 17, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, + 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, 0, 0, 0, 7, 242, 0, 16, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 16, 0, + 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 17, 0, 0, + 0, 0, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 130, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, + 21, 0, 0, 1, 56, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 246, 15, 16, + 0, 1, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 56, 0, 0, 7, 242, 0, + 16, 0, 6, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 6, + 0, 0, 0, 56, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 246, 15, 16, 0, + 1, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 56, 0, 0, 7, 242, 0, 16, + 0, 7, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 7, 0, + 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 82, + 0, 16, 0, 4, 0, 0, 0, 166, 8, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, + 82, 0, 16, 0, 6, 0, 0, 0, 166, 8, 16, 0, 6, 0, 0, 0, 54, 0, 0, + 5, 82, 0, 16, 0, 8, 0, 0, 0, 166, 8, 16, 0, 8, 0, 0, 0, 54, 0, + 0, 5, 82, 0, 16, 0, 7, 0, 0, 0, 166, 8, 16, 0, 7, 0, 0, 0, 21, + 0, 0, 1, 76, 0, 0, 3, 26, 0, 16, 0, 5, 0, 0, 0, 6, 0, 0, 3, + 1, 64, 0, 0, 3, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 9, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, + 0, 248, 65, 0, 0, 248, 65, 0, 0, 128, 63, 2, 64, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, + 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 18, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 32, + 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 0, 128, 0, 0, 10, + 0, 16, 0, 1, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 9, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, + 248, 65, 0, 0, 248, 65, 0, 0, 128, 63, 2, 64, 0, 0, 0, 0, 0, 63, 0, + 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 32, 0, + 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 1, 0, 58, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, + 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 8, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 9, 0, 0, 0, 70, + 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, + 0, 0, 248, 65, 0, 0, 128, 63, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, + 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 9, 0, + 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, + 10, 0, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 0, 128, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, + 0, 7, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, + 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, + 0, 248, 65, 0, 0, 128, 63, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 9, 0, 0, + 0, 70, 14, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, + 0, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 1, 0, 58, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 54, + 32, 0, 5, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, + 50, 0, 0, 15, 178, 0, 16, 0, 1, 0, 0, 0, 70, 8, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 0, 0, 0, 0, + 248, 65, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, + 0, 0, 63, 28, 0, 0, 5, 178, 0, 16, 0, 1, 0, 0, 0, 70, 12, 16, 0, + 1, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 54, 32, 0, 5, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, + 0, 50, 0, 0, 15, 226, 0, 16, 0, 5, 0, 0, 0, 6, 9, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, + 0, 248, 65, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0, 0, 63, 28, 0, 0, 5, 226, 0, 16, 0, 5, 0, 0, 0, 86, 14, 16, + 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 26, 0, 16, 0, 5, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 5, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 1, 0, 58, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 54, 32, 0, 5, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, + 0, 50, 0, 0, 15, 178, 0, 16, 0, 1, 0, 0, 0, 70, 8, 16, 0, 8, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 0, 0, 0, + 0, 248, 65, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, + 0, 0, 0, 63, 28, 0, 0, 5, 178, 0, 16, 0, 1, 0, 0, 0, 70, 12, 16, + 0, 1, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 10, 0, 16, 0, 1, 0, 0, + 0, 54, 32, 0, 5, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, + 0, 0, 50, 0, 0, 15, 226, 0, 16, 0, 5, 0, 0, 0, 6, 9, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, + 0, 0, 248, 65, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, + 63, 0, 0, 0, 63, 28, 0, 0, 5, 226, 0, 16, 0, 5, 0, 0, 0, 86, 14, + 16, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 26, 0, 16, 0, + 5, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 5, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 35, 0, 0, 9, 34, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 1, 0, 58, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, + 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, 54, 32, + 0, 5, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 50, + 0, 0, 15, 178, 0, 16, 0, 1, 0, 0, 0, 70, 8, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 0, 0, 0, 0, 124, + 66, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, + 0, 63, 28, 0, 0, 5, 178, 0, 16, 0, 1, 0, 0, 0, 70, 12, 16, 0, 1, + 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 54, + 32, 0, 5, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, + 50, 0, 0, 15, 226, 0, 16, 0, 5, 0, 0, 0, 6, 9, 16, 0, 6, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, + 124, 66, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, + 0, 0, 63, 28, 0, 0, 5, 226, 0, 16, 0, 5, 0, 0, 0, 86, 14, 16, 0, + 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, + 0, 5, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 26, 0, 16, 0, 5, 0, + 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 5, + 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 54, + 32, 0, 5, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, + 50, 0, 0, 15, 178, 0, 16, 0, 1, 0, 0, 0, 70, 8, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 0, 0, 0, 0, + 124, 66, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, + 0, 0, 63, 28, 0, 0, 5, 178, 0, 16, 0, 1, 0, 0, 0, 70, 12, 16, 0, + 1, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 54, 32, 0, 5, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, + 0, 50, 0, 0, 15, 226, 0, 16, 0, 5, 0, 0, 0, 6, 9, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, + 0, 124, 66, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0, 0, 63, 28, 0, 0, 5, 226, 0, 16, 0, 5, 0, 0, 0, 86, 14, 16, + 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 26, 0, 16, 0, 5, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 5, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 1, 0, 58, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 54, 32, 0, + 5, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 54, 32, + 0, 5, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 50, + 0, 0, 15, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, + 67, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, + 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, + 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 9, 0, 0, 0, 1, 64, 0, 0, 0, 1, 0, 0, 10, 0, 16, 0, 9, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 9, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 1, 0, 0, 0, 35, + 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 1, 10, 0, 16, 0, 1, 0, 0, 0, 54, 32, 0, + 5, 50, 0, 16, 0, 8, 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 54, 32, + 0, 5, 194, 0, 16, 0, 8, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 50, + 0, 0, 15, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, + 67, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, + 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, + 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 9, 0, 0, 0, 1, 64, 0, 0, 0, 1, 0, 0, 10, 0, 16, 0, 9, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 9, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 1, 0, 0, 0, 35, + 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 1, 10, 0, 16, 0, 1, 0, 0, 0, 2, 0, 0, + 1, 6, 0, 0, 3, 1, 64, 0, 0, 15, 0, 0, 0, 54, 32, 0, 5, 242, 0, + 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 50, 0, 0, 15, 242, + 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 2, 64, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, + 0, 5, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 35, + 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, + 1, 64, 0, 0, 16, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 35, 0, 0, + 9, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 1, 64, + 0, 0, 0, 1, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 18, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, + 0, 16, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, + 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 50, 0, 0, 15, 242, 0, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 2, 64, 0, 0, + 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, + 5, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 1, + 64, 0, 0, 16, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, + 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, + 0, 0, 1, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 28, + 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 8, + 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 112, + 65, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 2, 64, 0, 0, 0, 0, + 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, + 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, + 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, + 0, 16, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 18, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 0, + 1, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 0, 16, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 9, + 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 112, 65, + 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 2, 64, 0, 0, 0, 0, 0, + 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, + 16, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 0, 1, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, + 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 1, 0, 58, 0, 16, 0, 1, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 1, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, + 24, 0, 0, 0, 54, 32, 0, 5, 66, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, + 0, 4, 0, 0, 0, 54, 32, 0, 5, 34, 0, 16, 0, 7, 0, 0, 0, 10, 0, + 16, 0, 6, 0, 0, 0, 54, 32, 0, 5, 130, 0, 16, 0, 7, 0, 0, 0, 10, + 0, 16, 0, 8, 0, 0, 0, 54, 32, 0, 5, 18, 0, 16, 0, 7, 0, 0, 0, + 10, 0, 16, 0, 7, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 9, 0, 0, + 0, 102, 3, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 255, 127, 71, 0, 255, + 127, 71, 0, 255, 127, 71, 0, 255, 127, 71, 2, 64, 0, 0, 0, 0, 0, 63, 0, + 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 35, 0, 0, 12, 146, 0, 16, + 0, 0, 0, 0, 0, 86, 13, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 8, 16, 0, 9, + 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 130, 0, 0, 5, 18, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 130, 0, 0, 5, 34, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 18, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 1, 0, 10, 0, 16, 0, 1, 0, 0, 0, 130, 0, 0, 5, 18, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 130, 0, 0, 5, 34, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 35, 0, 0, 9, 130, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 1, 0, 10, 0, 16, 0, 1, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, + 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, + 0, 0, 138, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, + 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 230, 14, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 42, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 254, 7, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, + 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 9, + 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 12, 0, 0, 140, 0, 0, 11, 66, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 7, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 140, 0, + 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 48, 0, 0, 0, 140, 0, 0, 20, + 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 35, 0, 0, 12, 146, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, 82, 0, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 6, 3, 16, 0, 1, 0, + 0, 0, 140, 0, 0, 17, 82, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, + 0, 0, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 138, 0, 0, 9, 66, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, + 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 4, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, + 16, 0, 2, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 66, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, + 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 42, 0, 0, 10, 242, 0, 16, 0, + 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, + 0, 5, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 18, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 112, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, + 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, + 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 224, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 1, 64, + 0, 0, 8, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, + 50, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, + 0, 17, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, 24, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, + 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, + 0, 70, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, + 0, 140, 0, 0, 17, 50, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, + 2, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, + 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 21, + 0, 0, 1, 30, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 32, 0, 0, 7, 34, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, + 0, 1, 0, 0, 0, 198, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 194, + 0, 16, 0, 1, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 255, 0, 255, 0, 255, 0, 255, 0, 30, + 0, 0, 7, 146, 0, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, + 6, 4, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 198, 0, + 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 48, + 5, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 131, 0, 0, 0, + 61, 1, 0, 0, 172, 0, 0, 0, 61, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, + 0, 0, 0, 64, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_16bpp_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_16bpp_scaled_cs.h new file mode 100644 index 0000000..1227f86 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_16bpp_scaled_cs.h @@ -0,0 +1,3620 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_resolve_edram_info; // Offset: 0 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 4 Size: 4 +// uint xe_resolve_dest_info; // Offset: 8 Size: 4 +// uint xe_resolve_dest_coordinate_info;// Offset: 12 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram texture byte r/o T0 t0 1 +// xe_resolve_dest UAV uint2 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_raw T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 24 +dcl_thread_group 8, 8, 1 +and r0.xyzw, CB0[0][0].xxzz, l(1023, 0x20000000, 7, 8) +if_nz r0.y + ubfe r1.xy, l(2, 2, 0, 0), l(17, 20, 0, 0), CB0[0][0].yyyy +else + mov r1.xy, l(0,0,0,0) +endif +ubfe r2.xyz, l(3, 3, 11, 0), l(16, 19, 5, 0), CB0[0][0].yyyy +imul null, r0.y, r2.x, r2.z +and r1.z, CB0[0][0].z, l(0x01000000) +ushr r3.xyzw, CB0[0][0].ywww, l(4, 10, 20, 24) +ishl r4.x, vThreadID.x, l(2) +ishl r0.y, r0.y, l(3) +uge r0.y, r4.x, r0.y +if_nz r0.y + ret +endif +ubfe r5.xyzw, l(2, 11, 4, 1), l(10, 13, 24, 28), CB0[0][0].xxxx +mov r6.x, CB0[0][0].y +mov r6.y, r3.x +bfi r2.zw, l(0, 0, 4, 1), l(0, 0, 3, 3), r6.xxxy, l(0, 0, 0, 0) +ibfe r0.y, l(6), l(16), CB0[0][0].z +ishl r0.y, r0.y, l(23) +iadd r0.y, r0.y, l(0x3f800000) +bfi r1.w, l(10), l(5), CB0[0][0].w, l(0) +bfi r3.xz, l(4, 0, 4, 0), l(3, 0, 3, 0), r3.zzwz, l(0, 0, 0, 0) +ubfe r6.xy, l(6, 3, 0, 0), l(7, 28, 0, 0), CB0[0][0].zwzz +umax r4.y, r1.y, vThreadID.y +imad r2.zw, r2.zzzw, r2.xxxy, r4.xxxy +uge r1.y, l(3), r6.y +if_nz r1.y + mov r7.y, r6.y +else + ieq r1.y, r6.y, l(5) + if_nz r1.y + mov r7.y, l(2) + else + mov r7.y, l(0) + endif +endif +uge r4.yw, r5.xxxx, l(0, 2, 0, 1) +and r4.yw, r4.yyyw, l(0, 1, 0, 1) +ishl r2.zw, r2.zzzw, r4.yyyw +ushr r7.x, r7.y, l(1) +and r6.zw, r7.xxxy, l(0, 0, 1, 1) +iadd r2.zw, r2.zzzw, r6.zzzw +imul null, r7.yz, r2.xxyx, l(0, 80, 16, 0) +ushr r7.x, r7.y, r5.w +udiv r6.zw, null, r2.zzzw, r7.xxxz +imad r0.x, r6.w, r0.x, r6.z +iadd r0.x, r0.x, r5.y +imad r2.zw, -r6.zzzw, r7.xxxz, r2.zzzw +imul null, r1.y, r7.z, r7.y +imad r2.z, r2.w, r7.x, r2.z +ishl r2.z, r2.z, r5.w +imad r0.x, r0.x, r1.y, r2.z +ishl r1.y, r1.y, l(11) +udiv null, r0.x, r0.x, r1.y +iadd r1.y, r4.y, r5.w +ishl r2.z, l(1), r1.y +if_nz r5.w + ieq r2.w, r2.z, l(2) + if_nz r2.w + ishl r2.w, r0.x, l(2) + ld_raw r7.xyzw, r2.w, T0[0].zwxy + iadd r2.w, r2.w, l(16) + ld_raw r8.xyzw, r2.w, T0[0].zwxy + mov r9.xy, r7.zwzz + mov r10.xy, r8.zwzz + else + ishl r2.w, r0.x, l(2) + ld_raw r9.xy, r2.w, T0[0].xyxx + iadd r2.w, r0.x, r2.z + ishl r2.w, r2.w, l(2) + ld_raw r7.xy, r2.w, T0[0].xyxx + ishl r4.yw, l(0, 2, 0, 3), r1.yyyy + iadd r4.yw, r0.xxxx, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r10.xy, r4.y, T0[0].xyxx + ld_raw r8.xy, r4.w, T0[0].xyxx + endif + switch r5.z + case l(5) + ishl r9.zw, r9.xxxy, l(0, 0, 16, 16) + ishr r11.xyzw, r9.zxwy, l(16, 16, 16, 16) + itof r11.xyzw, r11.xyzw + mul r11.xyzw, r11.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xyzw, r11.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r7.zw, r7.xxxy, l(0, 0, 16, 16) + ishr r11.xyzw, r7.zxwy, l(16, 16, 16, 16) + itof r11.xyzw, r11.xyzw + mul r11.xyzw, r11.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r7.xyzw, r11.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r10.zw, r10.xxxy, l(0, 0, 16, 16) + ishr r11.xyzw, r10.zxwy, l(16, 16, 16, 16) + itof r11.xyzw, r11.xyzw + mul r11.xyzw, r11.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r10.xyzw, r11.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r8.zw, r8.xxxy, l(0, 0, 16, 16) + ishr r11.xyzw, r8.zxwy, l(16, 16, 16, 16) + itof r11.xyzw, r11.xyzw + mul r11.xyzw, r11.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xyzw, r11.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.yw, r9.xxxy, l(0, 16, 0, 16) + f16tof32 r9.xz, r9.xxyx + f16tof32 r9.yw, r4.yyyw + ushr r4.yw, r7.xxxy, l(0, 16, 0, 16) + f16tof32 r7.xz, r7.xxyx + f16tof32 r7.yw, r4.yyyw + ushr r4.yw, r10.xxxy, l(0, 16, 0, 16) + f16tof32 r10.xz, r10.xxyx + f16tof32 r10.yw, r4.yyyw + ushr r4.yw, r8.xxxy, l(0, 16, 0, 16) + f16tof32 r8.xz, r8.xxyx + f16tof32 r8.yw, r4.yyyw + break + default + mov r9.zw, l(0,0,0,0) + mov r7.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + endswitch +else + ieq r2.w, r2.z, l(1) + if_nz r2.w + ishl r2.w, r0.x, l(2) + ld_raw r8.xyzw, r2.w, T0[0].wxyz + else + ishl r2.w, r0.x, l(2) + ld_raw r8.y, r2.w, T0[0].xxxx + iadd r2.w, r0.x, r2.z + ishl r2.w, r2.w, l(2) + ld_raw r8.z, r2.w, T0[0].xxxx + ishl r4.yw, l(0, 2, 0, 3), r1.yyyy + iadd r4.yw, r0.xxxx, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r8.w, r4.y, T0[0].xxxx + ld_raw r8.x, r4.w, T0[0].xxxx + endif + switch r5.z + case l(0) + case l(1) + ushr r11.yzw, r8.yyyy, l(0, 8, 16, 24) + mov r11.x, r8.y + and r11.xyzw, r11.xyzw, l(255, 255, 255, 255) + utof r11.xyzw, r11.xyzw + mul r9.xyzw, r11.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r11.yzw, r8.zzzz, l(0, 8, 16, 24) + mov r11.x, r8.z + and r11.xyzw, r11.xyzw, l(255, 255, 255, 255) + utof r11.xyzw, r11.xyzw + mul r7.xyzw, r11.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r11.yzw, r8.wwww, l(0, 8, 16, 24) + mov r11.x, r8.w + and r11.xyzw, r11.xyzw, l(255, 255, 255, 255) + utof r11.xyzw, r11.xyzw + mul r10.xyzw, r11.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r8.yzw, r8.xxxx, l(0, 8, 16, 24) + and r11.xyzw, r8.xyzw, l(255, 255, 255, 255) + utof r11.xyzw, r11.xyzw + mul r8.xyzw, r11.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r11.yzw, r8.yyyy, l(0, 10, 20, 30) + mov r11.x, r8.y + and r11.xyzw, r11.xyzw, l(1023, 1023, 1023, 3) + utof r11.xyzw, r11.xyzw + mul r9.xyzw, r11.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r11.yzw, r8.zzzz, l(0, 10, 20, 30) + mov r11.x, r8.z + and r11.xyzw, r11.xyzw, l(1023, 1023, 1023, 3) + utof r11.xyzw, r11.xyzw + mul r7.xyzw, r11.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r11.yzw, r8.wwww, l(0, 10, 20, 30) + mov r11.x, r8.w + and r11.xyzw, r11.xyzw, l(1023, 1023, 1023, 3) + utof r11.xyzw, r11.xyzw + mul r10.xyzw, r11.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r8.yzw, r8.xxxx, l(0, 10, 20, 30) + and r11.xyzw, r8.xyzw, l(1023, 1023, 1023, 3) + utof r11.xyzw, r11.xyzw + mul r8.xyzw, r11.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r11.xyzw, r8.yyyz, l(10, 20, 30, 30) + mov r12.x, r8.y + mov r12.yz, r11.xxyx + and r13.xyz, r12.xyzx, l(1023, 1023, 1023, 0) + and r14.xyz, r12.xyzx, l(127, 127, 127, 0) + ubfe r15.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r12.xyzx + firstbit_hi r16.xyz, r14.xyzx + iadd r16.xyz, r16.xyzx, l(-24, -24, -24, 0) + movc r16.xyz, r14.xyzx, r16.xyzx, l(8,8,8,0) + iadd r17.xyz, -r16.xyzx, l(1, 1, 1, 0) + movc r17.xyz, r15.xyzx, r15.xyzx, r17.xyzx + bfi r12.xyz, l(7, 7, 7, 0), r16.xyzx, r12.xyzx, l(0, 0, 0, 0) + and r12.xyz, r12.xyzx, l(127, 127, 127, 0) + movc r12.xyz, r15.xyzx, r14.xyzx, r12.xyzx + ishl r14.xyz, r17.xyzx, l(23, 23, 23, 0) + iadd r14.xyz, r14.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r12.xyz, r12.xyzx, l(16, 16, 16, 0) + iadd r12.xyz, r14.xyzx, r12.xyzx + movc r9.xyz, r13.xyzx, r12.xyzx, l(0,0,0,0) + utof r4.yw, r11.zzzw + ushr r11.xyzw, r8.zwwz, l(10, 10, 20, 20) + mov r12.x, r8.z + mov r12.yz, r11.xxwx + and r13.xyz, r12.xyzx, l(1023, 1023, 1023, 0) + and r14.xyz, r12.xyzx, l(127, 127, 127, 0) + ubfe r15.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r12.xyzx + firstbit_hi r16.xyz, r14.xyzx + iadd r16.xyz, r16.xyzx, l(-24, -24, -24, 0) + movc r16.xyz, r14.xyzx, r16.xyzx, l(8,8,8,0) + iadd r17.xyz, -r16.xyzx, l(1, 1, 1, 0) + movc r17.xyz, r15.xyzx, r15.xyzx, r17.xyzx + bfi r12.xyz, l(7, 7, 7, 0), r16.xyzx, r12.xyzx, l(0, 0, 0, 0) + and r12.xyz, r12.xyzx, l(127, 127, 127, 0) + movc r12.xyz, r15.xyzx, r14.xyzx, r12.xyzx + ishl r14.xyz, r17.xyzx, l(23, 23, 23, 0) + iadd r14.xyz, r14.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r12.xyz, r12.xyzx, l(16, 16, 16, 0) + iadd r12.xyz, r14.xyzx, r12.xyzx + movc r7.xyz, r13.xyzx, r12.xyzx, l(0,0,0,0) + mul r4.yw, r4.yyyw, l(0.000000, 0.333333, 0.000000, 0.333333) + mov r11.x, r8.w + and r12.xyz, r11.xyzx, l(1023, 1023, 1023, 0) + and r13.xyz, r11.xyzx, l(127, 127, 127, 0) + ubfe r14.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r11.xyzx + firstbit_hi r15.xyz, r13.xyzx + iadd r15.xyz, r15.xyzx, l(-24, -24, -24, 0) + movc r15.xyz, r13.xyzx, r15.xyzx, l(8,8,8,0) + iadd r16.xyz, -r15.xyzx, l(1, 1, 1, 0) + movc r16.xyz, r14.xyzx, r14.xyzx, r16.xyzx + bfi r11.xyz, l(7, 7, 7, 0), r15.xyzx, r11.xyzx, l(0, 0, 0, 0) + and r11.xyz, r11.xyzx, l(127, 127, 127, 0) + movc r11.xyz, r14.xyzx, r13.xyzx, r11.xyzx + ishl r13.xyz, r16.xyzx, l(23, 23, 23, 0) + iadd r13.xyz, r13.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r11.xyz, r11.xyzx, l(16, 16, 16, 0) + iadd r11.xyz, r13.xyzx, r11.xyzx + movc r10.xyz, r12.xyzx, r11.xyzx, l(0,0,0,0) + ushr r11.xyzw, r8.wxxx, l(30, 10, 20, 30) + utof r5.xy, r11.xwxx + mov r11.x, r8.x + and r12.xyz, r11.xyzx, l(1023, 1023, 1023, 0) + and r13.xyz, r11.xyzx, l(127, 127, 127, 0) + ubfe r14.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r11.xyzx + firstbit_hi r15.xyz, r13.xyzx + iadd r15.xyz, r15.xyzx, l(-24, -24, -24, 0) + movc r15.xyz, r13.xyzx, r15.xyzx, l(8,8,8,0) + iadd r16.xyz, -r15.xyzx, l(1, 1, 1, 0) + movc r16.xyz, r14.xyzx, r14.xyzx, r16.xyzx + bfi r11.xyz, l(7, 7, 7, 0), r15.xyzx, r11.xyzx, l(0, 0, 0, 0) + and r11.xyz, r11.xyzx, l(127, 127, 127, 0) + movc r11.xyz, r14.xyzx, r13.xyzx, r11.xyzx + ishl r13.xyz, r16.xyzx, l(23, 23, 23, 0) + iadd r13.xyz, r13.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r11.xyz, r11.xyzx, l(16, 16, 16, 0) + iadd r11.xyz, r13.xyzx, r11.xyzx + movc r8.xyz, r12.xyzx, r11.xyzx, l(0,0,0,0) + mul r5.xy, r5.xyxx, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r9.w, r4.y + mov r7.w, r4.w + mov r10.w, r5.x + mov r8.w, r5.y + break + case l(4) + ishl r11.xyzw, r8.yzwx, l(16, 16, 16, 16) + mov r12.xz, r11.xxyx + mov r12.yw, r8.yyyz + ishr r12.xyzw, r12.xyzw, l(16, 16, 16, 16) + itof r12.xyzw, r12.xyzw + mul r12.xyzw, r12.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xy, r12.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r7.xy, r12.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r8.yz, r11.zzwz + ishr r11.xyzw, r8.ywzx, l(16, 16, 16, 16) + itof r11.xyzw, r11.xyzw + mul r11.xyzw, r11.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r10.xy, r11.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r8.xy, r11.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r9.zw, l(0,0,0,0) + mov r7.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + case l(6) + ushr r11.xyzw, r8.yzwx, l(16, 16, 16, 16) + f16tof32 r9.x, r8.y + f16tof32 r9.y, r11.x + f16tof32 r7.x, r8.z + f16tof32 r7.y, r11.y + f16tof32 r10.x, r8.w + f16tof32 r10.y, r11.z + f16tof32 r8.x, r8.x + f16tof32 r8.y, r11.w + mov r9.zw, l(0,0,0,0) + mov r7.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + default + mov r9.x, r8.y + mov r9.yzw, l(0,0,0,0) + mov r7.x, r8.z + mov r7.yzw, l(0,0,0,0) + mov r10.x, r8.w + mov r10.yzw, l(0,0,0,0) + mov r8.yzw, l(0,0,0,0) + break + endswitch +endif +uge r2.w, r6.y, l(4) +if_nz r2.w + mul r2.w, r0.y, l(0.500000) + imad r3.w, l(80), r2.x, r0.x + if_nz r5.w + ieq r4.y, r2.z, l(2) + if_nz r4.y + ishl r4.y, r3.w, l(2) + ld_raw r11.xyzw, r4.y, T0[0].zwxy + iadd r4.y, r4.y, l(16) + ld_raw r12.xyzw, r4.y, T0[0].zwxy + mov r13.xy, r11.zwzz + mov r14.xy, r12.zwzz + else + ishl r4.y, r3.w, l(2) + ld_raw r13.xy, r4.y, T0[0].xyxx + iadd r4.y, r2.z, r3.w + ishl r4.y, r4.y, l(2) + ld_raw r11.xy, r4.y, T0[0].xyxx + ishl r4.yw, l(0, 2, 0, 3), r1.yyyy + iadd r4.yw, r3.wwww, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r14.xy, r4.y, T0[0].xyxx + ld_raw r12.xy, r4.w, T0[0].xyxx + endif + switch r5.z + case l(5) + ishl r13.zw, r13.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r13.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r13.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r11.zw, r11.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r11.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r11.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r14.zw, r14.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r14.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r12.zw, r12.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r12.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r12.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.yw, r13.xxxy, l(0, 16, 0, 16) + f16tof32 r13.xz, r13.xxyx + f16tof32 r13.yw, r4.yyyw + ushr r4.yw, r11.xxxy, l(0, 16, 0, 16) + f16tof32 r11.xz, r11.xxyx + f16tof32 r11.yw, r4.yyyw + ushr r4.yw, r14.xxxy, l(0, 16, 0, 16) + f16tof32 r14.xz, r14.xxyx + f16tof32 r14.yw, r4.yyyw + ushr r4.yw, r12.xxxy, l(0, 16, 0, 16) + f16tof32 r12.xz, r12.xxyx + f16tof32 r12.yw, r4.yyyw + break + default + mov r13.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r12.zw, l(0,0,0,0) + break + endswitch + else + ieq r4.y, r2.z, l(1) + if_nz r4.y + ishl r4.y, r3.w, l(2) + ld_raw r12.xyzw, r4.y, T0[0].wxyz + else + ishl r4.y, r3.w, l(2) + ld_raw r12.y, r4.y, T0[0].xxxx + iadd r4.y, r2.z, r3.w + ishl r4.y, r4.y, l(2) + ld_raw r12.z, r4.y, T0[0].xxxx + ishl r4.yw, l(0, 2, 0, 3), r1.yyyy + iadd r4.yw, r3.wwww, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r12.w, r4.y, T0[0].xxxx + ld_raw r12.x, r4.w, T0[0].xxxx + endif + switch r5.z + case l(0) + case l(1) + ushr r15.yzw, r12.yyyy, l(0, 8, 16, 24) + mov r15.x, r12.y + and r15.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r13.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r15.yzw, r12.zzzz, l(0, 8, 16, 24) + mov r15.x, r12.z + and r15.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r11.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r15.yzw, r12.wwww, l(0, 8, 16, 24) + mov r15.x, r12.w + and r15.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r14.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r12.yzw, r12.xxxx, l(0, 8, 16, 24) + and r15.xyzw, r12.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r12.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r15.yzw, r12.yyyy, l(0, 10, 20, 30) + mov r15.x, r12.y + and r15.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r13.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r15.yzw, r12.zzzz, l(0, 10, 20, 30) + mov r15.x, r12.z + and r15.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r11.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r15.yzw, r12.wwww, l(0, 10, 20, 30) + mov r15.x, r12.w + and r15.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r14.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r12.yzw, r12.xxxx, l(0, 10, 20, 30) + and r15.xyzw, r12.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r12.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r15.xyzw, r12.yyyz, l(10, 20, 30, 30) + mov r16.x, r12.y + mov r16.yz, r15.xxyx + and r17.xyz, r16.xyzx, l(1023, 1023, 1023, 0) + and r18.xyz, r16.xyzx, l(127, 127, 127, 0) + ubfe r19.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r16.xyzx + firstbit_hi r20.xyz, r18.xyzx + iadd r20.xyz, r20.xyzx, l(-24, -24, -24, 0) + movc r20.xyz, r18.xyzx, r20.xyzx, l(8,8,8,0) + iadd r21.xyz, -r20.xyzx, l(1, 1, 1, 0) + movc r21.xyz, r19.xyzx, r19.xyzx, r21.xyzx + bfi r16.xyz, l(7, 7, 7, 0), r20.xyzx, r16.xyzx, l(0, 0, 0, 0) + and r16.xyz, r16.xyzx, l(127, 127, 127, 0) + movc r16.xyz, r19.xyzx, r18.xyzx, r16.xyzx + ishl r18.xyz, r21.xyzx, l(23, 23, 23, 0) + iadd r18.xyz, r18.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r16.xyz, r16.xyzx, l(16, 16, 16, 0) + iadd r16.xyz, r18.xyzx, r16.xyzx + movc r13.xyz, r17.xyzx, r16.xyzx, l(0,0,0,0) + utof r4.yw, r15.zzzw + ushr r15.xyzw, r12.zwwz, l(10, 10, 20, 20) + mov r16.x, r12.z + mov r16.yz, r15.xxwx + and r17.xyz, r16.xyzx, l(1023, 1023, 1023, 0) + and r18.xyz, r16.xyzx, l(127, 127, 127, 0) + ubfe r19.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r16.xyzx + firstbit_hi r20.xyz, r18.xyzx + iadd r20.xyz, r20.xyzx, l(-24, -24, -24, 0) + movc r20.xyz, r18.xyzx, r20.xyzx, l(8,8,8,0) + iadd r21.xyz, -r20.xyzx, l(1, 1, 1, 0) + movc r21.xyz, r19.xyzx, r19.xyzx, r21.xyzx + bfi r16.xyz, l(7, 7, 7, 0), r20.xyzx, r16.xyzx, l(0, 0, 0, 0) + and r16.xyz, r16.xyzx, l(127, 127, 127, 0) + movc r16.xyz, r19.xyzx, r18.xyzx, r16.xyzx + ishl r18.xyz, r21.xyzx, l(23, 23, 23, 0) + iadd r18.xyz, r18.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r16.xyz, r16.xyzx, l(16, 16, 16, 0) + iadd r16.xyz, r18.xyzx, r16.xyzx + movc r11.xyz, r17.xyzx, r16.xyzx, l(0,0,0,0) + mul r4.yw, r4.yyyw, l(0.000000, 0.333333, 0.000000, 0.333333) + mov r15.x, r12.w + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r14.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + ushr r15.xyzw, r12.wxxx, l(30, 10, 20, 30) + utof r5.xy, r15.xwxx + mov r15.x, r12.x + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r12.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + mul r5.xy, r5.xyxx, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r13.w, r4.y + mov r11.w, r4.w + mov r14.w, r5.x + mov r12.w, r5.y + break + case l(4) + ishl r15.xyzw, r12.yzwx, l(16, 16, 16, 16) + mov r16.xz, r15.xxyx + mov r16.yw, r12.yyyz + ishr r16.xyzw, r16.xyzw, l(16, 16, 16, 16) + itof r16.xyzw, r16.xyzw + mul r16.xyzw, r16.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r13.xy, r16.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r11.xy, r16.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r12.yz, r15.zzwz + ishr r15.xyzw, r12.ywzx, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xy, r15.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r12.xy, r15.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r13.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r12.zw, l(0,0,0,0) + break + case l(6) + ushr r15.xyzw, r12.yzwx, l(16, 16, 16, 16) + f16tof32 r13.x, r12.y + f16tof32 r13.y, r15.x + f16tof32 r11.x, r12.z + f16tof32 r11.y, r15.y + f16tof32 r14.x, r12.w + f16tof32 r14.y, r15.z + f16tof32 r12.x, r12.x + f16tof32 r12.y, r15.w + mov r13.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r12.zw, l(0,0,0,0) + break + default + mov r13.x, r12.y + mov r13.yzw, l(0,0,0,0) + mov r11.x, r12.z + mov r11.yzw, l(0,0,0,0) + mov r14.x, r12.w + mov r14.yzw, l(0,0,0,0) + mov r12.yzw, l(0,0,0,0) + break + endswitch + endif + add r9.xyzw, r9.xyzw, r13.xyzw + add r7.xyzw, r7.xyzw, r11.xyzw + add r10.xyzw, r10.xyzw, r14.xyzw + add r8.xyzw, r8.xyzw, r12.xyzw + uge r4.y, r6.y, l(6) + if_nz r4.y + ishl r4.y, l(1), r5.w + mul r0.y, r0.y, l(0.250000) + iadd r0.x, r0.x, r4.y + if_nz r5.w + ieq r4.w, r2.z, l(2) + if_nz r4.w + ishl r4.w, r0.x, l(2) + ld_raw r11.xyzw, r4.w, T0[0].zwxy + iadd r4.w, r4.w, l(16) + ld_raw r12.xyzw, r4.w, T0[0].zwxy + mov r13.xy, r11.zwzz + mov r14.xy, r12.zwzz + else + ishl r4.w, r0.x, l(2) + ld_raw r13.xy, r4.w, T0[0].xyxx + iadd r4.w, r2.z, r0.x + ishl r4.w, r4.w, l(2) + ld_raw r11.xy, r4.w, T0[0].xyxx + ishl r5.xy, l(2, 3, 0, 0), r1.yyyy + iadd r5.xy, r0.xxxx, r5.xyxx + ishl r5.xy, r5.xyxx, l(2, 2, 0, 0) + ld_raw r14.xy, r5.x, T0[0].xyxx + ld_raw r12.xy, r5.y, T0[0].xyxx + endif + switch r5.z + case l(5) + ishl r13.zw, r13.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r13.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r13.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r11.zw, r11.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r11.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r11.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r14.zw, r14.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r14.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r12.zw, r12.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r12.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r12.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r5.xy, r13.xyxx, l(16, 16, 0, 0) + f16tof32 r13.xz, r13.xxyx + f16tof32 r13.yw, r5.xxxy + ushr r5.xy, r11.xyxx, l(16, 16, 0, 0) + f16tof32 r11.xz, r11.xxyx + f16tof32 r11.yw, r5.xxxy + ushr r5.xy, r14.xyxx, l(16, 16, 0, 0) + f16tof32 r14.xz, r14.xxyx + f16tof32 r14.yw, r5.xxxy + ushr r5.xy, r12.xyxx, l(16, 16, 0, 0) + f16tof32 r12.xz, r12.xxyx + f16tof32 r12.yw, r5.xxxy + break + default + mov r13.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r12.zw, l(0,0,0,0) + break + endswitch + else + ieq r4.w, r2.z, l(1) + if_nz r4.w + ishl r4.w, r0.x, l(2) + ld_raw r12.xyzw, r4.w, T0[0].wxyz + else + ishl r4.w, r0.x, l(2) + ld_raw r12.y, r4.w, T0[0].xxxx + iadd r4.w, r2.z, r0.x + ishl r4.w, r4.w, l(2) + ld_raw r12.z, r4.w, T0[0].xxxx + ishl r5.xy, l(2, 3, 0, 0), r1.yyyy + iadd r5.xy, r0.xxxx, r5.xyxx + ishl r5.xy, r5.xyxx, l(2, 2, 0, 0) + ld_raw r12.w, r5.x, T0[0].xxxx + ld_raw r12.x, r5.y, T0[0].xxxx + endif + switch r5.z + case l(0) + case l(1) + ushr r15.yzw, r12.yyyy, l(0, 8, 16, 24) + mov r15.x, r12.y + and r15.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r13.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r15.yzw, r12.zzzz, l(0, 8, 16, 24) + mov r15.x, r12.z + and r15.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r11.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r15.yzw, r12.wwww, l(0, 8, 16, 24) + mov r15.x, r12.w + and r15.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r14.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r12.yzw, r12.xxxx, l(0, 8, 16, 24) + and r15.xyzw, r12.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r12.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r15.yzw, r12.yyyy, l(0, 10, 20, 30) + mov r15.x, r12.y + and r15.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r13.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r15.yzw, r12.zzzz, l(0, 10, 20, 30) + mov r15.x, r12.z + and r15.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r11.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r15.yzw, r12.wwww, l(0, 10, 20, 30) + mov r15.x, r12.w + and r15.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r14.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r12.yzw, r12.xxxx, l(0, 10, 20, 30) + and r15.xyzw, r12.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r12.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r15.xyzw, r12.yyyz, l(10, 20, 30, 30) + mov r16.x, r12.y + mov r16.yz, r15.xxyx + and r6.yzw, r16.xxyz, l(0, 1023, 1023, 1023) + and r17.xyz, r16.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r16.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r16.xyz, l(7, 7, 7, 0), r19.xyzx, r16.xyzx, l(0, 0, 0, 0) + and r16.xyz, r16.xyzx, l(127, 127, 127, 0) + movc r16.xyz, r18.xyzx, r17.xyzx, r16.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r16.xyz, r16.xyzx, l(16, 16, 16, 0) + iadd r16.xyz, r17.xyzx, r16.xyzx + movc r13.xyz, r6.yzwy, r16.xyzx, l(0,0,0,0) + utof r5.xy, r15.zwzz + ushr r15.xyzw, r12.zwwz, l(10, 10, 20, 20) + mov r16.x, r12.z + mov r16.yz, r15.xxwx + and r6.yzw, r16.xxyz, l(0, 1023, 1023, 1023) + and r17.xyz, r16.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r16.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r16.xyz, l(7, 7, 7, 0), r19.xyzx, r16.xyzx, l(0, 0, 0, 0) + and r16.xyz, r16.xyzx, l(127, 127, 127, 0) + movc r16.xyz, r18.xyzx, r17.xyzx, r16.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r16.xyz, r16.xyzx, l(16, 16, 16, 0) + iadd r16.xyz, r17.xyzx, r16.xyzx + movc r11.xyz, r6.yzwy, r16.xyzx, l(0,0,0,0) + mul r5.xy, r5.xyxx, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r15.x, r12.w + and r6.yzw, r15.xxyz, l(0, 1023, 1023, 1023) + and r16.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r17.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r18.xyz, r16.xyzx + iadd r18.xyz, r18.xyzx, l(-24, -24, -24, 0) + movc r18.xyz, r16.xyzx, r18.xyzx, l(8,8,8,0) + iadd r19.xyz, -r18.xyzx, l(1, 1, 1, 0) + movc r19.xyz, r17.xyzx, r17.xyzx, r19.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r18.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r17.xyzx, r16.xyzx, r15.xyzx + ishl r16.xyz, r19.xyzx, l(23, 23, 23, 0) + iadd r16.xyz, r16.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r16.xyzx, r15.xyzx + movc r14.xyz, r6.yzwy, r15.xyzx, l(0,0,0,0) + ushr r15.xyzw, r12.wxxx, l(30, 10, 20, 30) + utof r6.yz, r15.xxwx + mov r15.x, r12.x + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r12.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + mul r6.yz, r6.yyzy, l(0.000000, 0.333333, 0.333333, 0.000000) + mov r13.w, r5.x + mov r11.w, r5.y + mov r14.w, r6.y + mov r12.w, r6.z + break + case l(4) + ishl r15.xyzw, r12.yzwx, l(16, 16, 16, 16) + mov r16.xz, r15.xxyx + mov r16.yw, r12.yyyz + ishr r16.xyzw, r16.xyzw, l(16, 16, 16, 16) + itof r16.xyzw, r16.xyzw + mul r16.xyzw, r16.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r13.xy, r16.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r11.xy, r16.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r12.yz, r15.zzwz + ishr r15.xyzw, r12.ywzx, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xy, r15.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r12.xy, r15.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r13.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r12.zw, l(0,0,0,0) + break + case l(6) + ushr r15.xyzw, r12.yzwx, l(16, 16, 16, 16) + f16tof32 r13.x, r12.y + f16tof32 r13.y, r15.x + f16tof32 r11.x, r12.z + f16tof32 r11.y, r15.y + f16tof32 r14.x, r12.w + f16tof32 r14.y, r15.z + f16tof32 r12.x, r12.x + f16tof32 r12.y, r15.w + mov r13.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r12.zw, l(0,0,0,0) + break + default + mov r13.x, r12.y + mov r13.yzw, l(0,0,0,0) + mov r11.x, r12.z + mov r11.yzw, l(0,0,0,0) + mov r14.x, r12.w + mov r14.yzw, l(0,0,0,0) + mov r12.yzw, l(0,0,0,0) + break + endswitch + endif + add r13.xyzw, r9.xyzw, r13.xyzw + add r11.xyzw, r7.xyzw, r11.xyzw + add r14.xyzw, r10.xyzw, r14.xyzw + add r12.xyzw, r8.xyzw, r12.xyzw + iadd r0.x, r3.w, r4.y + if_nz r5.w + ieq r3.w, r2.z, l(2) + if_nz r3.w + ishl r3.w, r0.x, l(2) + ld_raw r15.xyzw, r3.w, T0[0].zwxy + iadd r3.w, r3.w, l(16) + ld_raw r16.xyzw, r3.w, T0[0].zwxy + mov r17.xy, r15.zwzz + mov r18.xy, r16.zwzz + else + ishl r3.w, r0.x, l(2) + ld_raw r17.xy, r3.w, T0[0].xyxx + iadd r3.w, r2.z, r0.x + ishl r3.w, r3.w, l(2) + ld_raw r15.xy, r3.w, T0[0].xyxx + ishl r4.yw, l(0, 2, 0, 3), r1.yyyy + iadd r4.yw, r0.xxxx, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r18.xy, r4.y, T0[0].xyxx + ld_raw r16.xy, r4.w, T0[0].xyxx + endif + switch r5.z + case l(5) + ishl r17.zw, r17.xxxy, l(0, 0, 16, 16) + ishr r19.xyzw, r17.zxwy, l(16, 16, 16, 16) + itof r19.xyzw, r19.xyzw + mul r19.xyzw, r19.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r17.xyzw, r19.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r15.zw, r15.xxxy, l(0, 0, 16, 16) + ishr r19.xyzw, r15.zxwy, l(16, 16, 16, 16) + itof r19.xyzw, r19.xyzw + mul r19.xyzw, r19.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r15.xyzw, r19.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r18.zw, r18.xxxy, l(0, 0, 16, 16) + ishr r19.xyzw, r18.zxwy, l(16, 16, 16, 16) + itof r19.xyzw, r19.xyzw + mul r19.xyzw, r19.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r18.xyzw, r19.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r16.zw, r16.xxxy, l(0, 0, 16, 16) + ishr r19.xyzw, r16.zxwy, l(16, 16, 16, 16) + itof r19.xyzw, r19.xyzw + mul r19.xyzw, r19.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r16.xyzw, r19.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.yw, r17.xxxy, l(0, 16, 0, 16) + f16tof32 r17.xz, r17.xxyx + f16tof32 r17.yw, r4.yyyw + ushr r4.yw, r15.xxxy, l(0, 16, 0, 16) + f16tof32 r15.xz, r15.xxyx + f16tof32 r15.yw, r4.yyyw + ushr r4.yw, r18.xxxy, l(0, 16, 0, 16) + f16tof32 r18.xz, r18.xxyx + f16tof32 r18.yw, r4.yyyw + ushr r4.yw, r16.xxxy, l(0, 16, 0, 16) + f16tof32 r16.xz, r16.xxyx + f16tof32 r16.yw, r4.yyyw + break + default + mov r17.zw, l(0,0,0,0) + mov r15.zw, l(0,0,0,0) + mov r18.zw, l(0,0,0,0) + mov r16.zw, l(0,0,0,0) + break + endswitch + else + ieq r3.w, r2.z, l(1) + if_nz r3.w + ishl r3.w, r0.x, l(2) + ld_raw r16.xyzw, r3.w, T0[0].wxyz + else + ishl r3.w, r0.x, l(2) + ld_raw r16.y, r3.w, T0[0].xxxx + iadd r2.z, r2.z, r0.x + ishl r2.z, r2.z, l(2) + ld_raw r16.z, r2.z, T0[0].xxxx + ishl r4.yw, l(0, 2, 0, 3), r1.yyyy + iadd r4.yw, r0.xxxx, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r16.w, r4.y, T0[0].xxxx + ld_raw r16.x, r4.w, T0[0].xxxx + endif + switch r5.z + case l(0) + case l(1) + ushr r5.yzw, r16.yyyy, l(0, 8, 16, 24) + mov r5.x, r16.y + and r5.xyzw, r5.xyzw, l(255, 255, 255, 255) + utof r5.xyzw, r5.xyzw + mul r17.xyzw, r5.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r5.yzw, r16.zzzz, l(0, 8, 16, 24) + mov r5.x, r16.z + and r5.xyzw, r5.xyzw, l(255, 255, 255, 255) + utof r5.xyzw, r5.xyzw + mul r15.xyzw, r5.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r5.yzw, r16.wwww, l(0, 8, 16, 24) + mov r5.x, r16.w + and r5.xyzw, r5.xyzw, l(255, 255, 255, 255) + utof r5.xyzw, r5.xyzw + mul r18.xyzw, r5.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r16.yzw, r16.xxxx, l(0, 8, 16, 24) + and r5.xyzw, r16.xyzw, l(255, 255, 255, 255) + utof r5.xyzw, r5.xyzw + mul r16.xyzw, r5.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r5.yzw, r16.yyyy, l(0, 10, 20, 30) + mov r5.x, r16.y + and r5.xyzw, r5.xyzw, l(1023, 1023, 1023, 3) + utof r5.xyzw, r5.xyzw + mul r17.xyzw, r5.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r5.yzw, r16.zzzz, l(0, 10, 20, 30) + mov r5.x, r16.z + and r5.xyzw, r5.xyzw, l(1023, 1023, 1023, 3) + utof r5.xyzw, r5.xyzw + mul r15.xyzw, r5.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r5.yzw, r16.wwww, l(0, 10, 20, 30) + mov r5.x, r16.w + and r5.xyzw, r5.xyzw, l(1023, 1023, 1023, 3) + utof r5.xyzw, r5.xyzw + mul r18.xyzw, r5.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r16.yzw, r16.xxxx, l(0, 10, 20, 30) + and r5.xyzw, r16.xyzw, l(1023, 1023, 1023, 3) + utof r5.xyzw, r5.xyzw + mul r16.xyzw, r5.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r5.xyzw, r16.yyyz, l(10, 20, 30, 30) + mov r19.x, r16.y + mov r19.yz, r5.xxyx + and r6.yzw, r19.xxyz, l(0, 1023, 1023, 1023) + and r20.xyz, r19.xyzx, l(127, 127, 127, 0) + ubfe r21.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r19.xyzx + firstbit_hi r22.xyz, r20.xyzx + iadd r22.xyz, r22.xyzx, l(-24, -24, -24, 0) + movc r22.xyz, r20.xyzx, r22.xyzx, l(8,8,8,0) + iadd r23.xyz, -r22.xyzx, l(1, 1, 1, 0) + movc r23.xyz, r21.xyzx, r21.xyzx, r23.xyzx + bfi r19.xyz, l(7, 7, 7, 0), r22.xyzx, r19.xyzx, l(0, 0, 0, 0) + and r19.xyz, r19.xyzx, l(127, 127, 127, 0) + movc r19.xyz, r21.xyzx, r20.xyzx, r19.xyzx + ishl r20.xyz, r23.xyzx, l(23, 23, 23, 0) + iadd r20.xyz, r20.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r19.xyz, r19.xyzx, l(16, 16, 16, 0) + iadd r19.xyz, r20.xyzx, r19.xyzx + movc r17.xyz, r6.yzwy, r19.xyzx, l(0,0,0,0) + utof r4.yw, r5.zzzw + ushr r5.xyzw, r16.zwwz, l(10, 10, 20, 20) + mov r19.x, r16.z + mov r19.yz, r5.xxwx + and r6.yzw, r19.xxyz, l(0, 1023, 1023, 1023) + and r20.xyz, r19.xyzx, l(127, 127, 127, 0) + ubfe r21.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r19.xyzx + firstbit_hi r22.xyz, r20.xyzx + iadd r22.xyz, r22.xyzx, l(-24, -24, -24, 0) + movc r22.xyz, r20.xyzx, r22.xyzx, l(8,8,8,0) + iadd r23.xyz, -r22.xyzx, l(1, 1, 1, 0) + movc r23.xyz, r21.xyzx, r21.xyzx, r23.xyzx + bfi r19.xyz, l(7, 7, 7, 0), r22.xyzx, r19.xyzx, l(0, 0, 0, 0) + and r19.xyz, r19.xyzx, l(127, 127, 127, 0) + movc r19.xyz, r21.xyzx, r20.xyzx, r19.xyzx + ishl r20.xyz, r23.xyzx, l(23, 23, 23, 0) + iadd r20.xyz, r20.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r19.xyz, r19.xyzx, l(16, 16, 16, 0) + iadd r19.xyz, r20.xyzx, r19.xyzx + movc r15.xyz, r6.yzwy, r19.xyzx, l(0,0,0,0) + mul r4.yw, r4.yyyw, l(0.000000, 0.333333, 0.000000, 0.333333) + mov r5.x, r16.w + and r6.yzw, r5.xxyz, l(0, 1023, 1023, 1023) + and r19.xyz, r5.xyzx, l(127, 127, 127, 0) + ubfe r20.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r5.xyzx + firstbit_hi r21.xyz, r19.xyzx + iadd r21.xyz, r21.xyzx, l(-24, -24, -24, 0) + movc r21.xyz, r19.xyzx, r21.xyzx, l(8,8,8,0) + iadd r22.xyz, -r21.xyzx, l(1, 1, 1, 0) + movc r22.xyz, r20.xyzx, r20.xyzx, r22.xyzx + bfi r5.xyz, l(7, 7, 7, 0), r21.xyzx, r5.xyzx, l(0, 0, 0, 0) + and r5.xyz, r5.xyzx, l(127, 127, 127, 0) + movc r5.xyz, r20.xyzx, r19.xyzx, r5.xyzx + ishl r19.xyz, r22.xyzx, l(23, 23, 23, 0) + iadd r19.xyz, r19.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r5.xyz, r5.xyzx, l(16, 16, 16, 0) + iadd r5.xyz, r19.xyzx, r5.xyzx + movc r18.xyz, r6.yzwy, r5.xyzx, l(0,0,0,0) + ushr r5.xyzw, r16.wxxx, l(30, 10, 20, 30) + utof r6.yz, r5.xxwx + mov r5.x, r16.x + and r19.xyz, r5.xyzx, l(1023, 1023, 1023, 0) + and r20.xyz, r5.xyzx, l(127, 127, 127, 0) + ubfe r21.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r5.xyzx + firstbit_hi r22.xyz, r20.xyzx + iadd r22.xyz, r22.xyzx, l(-24, -24, -24, 0) + movc r22.xyz, r20.xyzx, r22.xyzx, l(8,8,8,0) + iadd r23.xyz, -r22.xyzx, l(1, 1, 1, 0) + movc r23.xyz, r21.xyzx, r21.xyzx, r23.xyzx + bfi r5.xyz, l(7, 7, 7, 0), r22.xyzx, r5.xyzx, l(0, 0, 0, 0) + and r5.xyz, r5.xyzx, l(127, 127, 127, 0) + movc r5.xyz, r21.xyzx, r20.xyzx, r5.xyzx + ishl r20.xyz, r23.xyzx, l(23, 23, 23, 0) + iadd r20.xyz, r20.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r5.xyz, r5.xyzx, l(16, 16, 16, 0) + iadd r5.xyz, r20.xyzx, r5.xyzx + movc r16.xyz, r19.xyzx, r5.xyzx, l(0,0,0,0) + mul r5.xy, r6.yzyy, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r17.w, r4.y + mov r15.w, r4.w + mov r18.w, r5.x + mov r16.w, r5.y + break + case l(4) + ishl r5.xyzw, r16.yzwx, l(16, 16, 16, 16) + mov r19.xz, r5.xxyx + mov r19.yw, r16.yyyz + ishr r19.xyzw, r19.xyzw, l(16, 16, 16, 16) + itof r19.xyzw, r19.xyzw + mul r19.xyzw, r19.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r17.xy, r19.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r15.xy, r19.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r16.yz, r5.zzwz + ishr r5.xyzw, r16.ywzx, l(16, 16, 16, 16) + itof r5.xyzw, r5.xyzw + mul r5.xyzw, r5.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r18.xy, r5.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r16.xy, r5.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r17.zw, l(0,0,0,0) + mov r15.zw, l(0,0,0,0) + mov r18.zw, l(0,0,0,0) + mov r16.zw, l(0,0,0,0) + break + case l(6) + ushr r5.xyzw, r16.yzwx, l(16, 16, 16, 16) + f16tof32 r17.x, r16.y + f16tof32 r17.y, r5.x + f16tof32 r15.x, r16.z + f16tof32 r15.y, r5.y + f16tof32 r18.x, r16.w + f16tof32 r18.y, r5.z + f16tof32 r16.x, r16.x + f16tof32 r16.y, r5.w + mov r17.zw, l(0,0,0,0) + mov r15.zw, l(0,0,0,0) + mov r18.zw, l(0,0,0,0) + mov r16.zw, l(0,0,0,0) + break + default + mov r17.x, r16.y + mov r17.yzw, l(0,0,0,0) + mov r15.x, r16.z + mov r15.yzw, l(0,0,0,0) + mov r18.x, r16.w + mov r18.yzw, l(0,0,0,0) + mov r16.yzw, l(0,0,0,0) + break + endswitch + endif + add r9.xyzw, r13.xyzw, r17.xyzw + add r7.xyzw, r11.xyzw, r15.xyzw + add r10.xyzw, r14.xyzw, r18.xyzw + add r8.xyzw, r12.xyzw, r16.xyzw + else + mov r0.y, r2.w + endif +endif +mul r5.xyzw, r0.yyyy, r9.xyzw +mul r7.xyzw, r0.yyyy, r7.xyzw +mul r9.xyzw, r0.yyyy, r10.xyzw +mul r8.xyzw, r0.yyyy, r8.xyzw +if_nz r1.z + mov r5.xz, r5.zzxz + mov r7.xz, r7.zzxz + mov r9.xz, r9.zzxz + mov r8.xz, r8.zzxz +endif +switch r6.x + case l(3) + mov_sat r5.xyzw, r5.xyzw + mad r6.xyzw, r5.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r6.xyzw, r6.xyzw + imad r1.y, r6.y, l(32), r6.x + imad r1.y, r6.z, l(1024), r1.y + imad r1.y, r6.w, l(0x00008000), r1.y + mov_sat r7.xyzw, r7.xyzw + mad r6.xyzw, r7.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r6.xyzw, r6.xyzw + imad r1.z, r6.y, l(32), r6.x + imad r1.z, r6.z, l(1024), r1.z + ishl r2.z, r6.w, l(31) + imad r1.z, r1.z, l(0x00010000), r2.z + iadd r0.x, r1.z, r1.y + mov_sat r9.xyzw, r9.xyzw + mad r6.xyzw, r9.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r6.xyzw, r6.xyzw + imad r1.y, r6.y, l(32), r6.x + imad r1.y, r6.z, l(1024), r1.y + imad r1.y, r6.w, l(0x00008000), r1.y + mov_sat r8.xyzw, r8.xyzw + mad r6.xyzw, r8.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r6.xyzw, r6.xyzw + imad r1.z, r6.y, l(32), r6.x + imad r1.z, r6.z, l(1024), r1.z + ishl r2.z, r6.w, l(31) + imad r1.z, r1.z, l(0x00010000), r2.z + iadd r0.y, r1.z, r1.y + break + case l(4) + mov_sat r5.xyz, r5.xyzx + mad r6.xyz, r5.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) + ftou r6.xyz, r6.xyzx + imad r1.y, r6.y, l(32), r6.x + imad r1.y, r6.z, l(2048), r1.y + mov_sat r7.xyz, r7.xyzx + mad r6.xyz, r7.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) + ftou r6.xyz, r6.xyzx + imad r1.z, r6.y, l(32), r6.x + ishl r2.z, r6.z, l(27) + imad r1.z, r1.z, l(0x00010000), r2.z + iadd r0.x, r1.z, r1.y + mov_sat r9.xyz, r9.xyzx + mad r6.xyz, r9.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) + ftou r6.xyz, r6.xyzx + imad r1.y, r6.y, l(32), r6.x + imad r1.y, r6.z, l(2048), r1.y + mov_sat r8.xyz, r8.xyzx + mad r6.xyz, r8.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) + ftou r6.xyz, r6.xyzx + imad r1.z, r6.y, l(32), r6.x + ishl r2.z, r6.z, l(27) + imad r1.z, r1.z, l(0x00010000), r2.z + iadd r0.y, r1.z, r1.y + break + case l(5) + mov_sat r5.xyz, r5.xyzx + mad r6.xyz, r5.xyzx, l(31.000000, 31.000000, 63.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) + ftou r6.xyz, r6.xyzx + imad r1.y, r6.y, l(32), r6.x + imad r1.y, r6.z, l(1024), r1.y + mov_sat r7.xyz, r7.xyzx + mad r6.xyz, r7.xyzx, l(31.000000, 31.000000, 63.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) + ftou r6.xyz, r6.xyzx + imad r1.z, r6.y, l(32), r6.x + ishl r2.z, r6.z, l(26) + imad r1.z, r1.z, l(0x00010000), r2.z + iadd r0.x, r1.z, r1.y + mov_sat r9.xyz, r9.xyzx + mad r6.xyz, r9.xyzx, l(31.000000, 31.000000, 63.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) + ftou r6.xyz, r6.xyzx + imad r1.y, r6.y, l(32), r6.x + imad r1.y, r6.z, l(1024), r1.y + mov_sat r8.xyz, r8.xyzx + mad r6.xyz, r8.xyzx, l(31.000000, 31.000000, 63.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) + ftou r6.xyz, r6.xyzx + imad r1.z, r6.y, l(32), r6.x + ishl r2.z, r6.z, l(26) + imad r1.z, r1.z, l(0x00010000), r2.z + iadd r0.y, r1.z, r1.y + break + case l(10) + mov_sat r5.xy, r5.xyxx + mov_sat r5.zw, r7.xxxy + mad r6.xyzw, r5.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r6.xyzw, r6.xyzw + imad r1.y, r6.y, l(256), r6.x + imad r1.y, r6.z, l(0x00010000), r1.y + imad r0.x, r6.w, l(0x01000000), r1.y + mov_sat r9.xy, r9.xyxx + mov_sat r9.zw, r8.xxxy + mad r6.xyzw, r9.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r6.xyzw, r6.xyzw + imad r1.y, r6.y, l(256), r6.x + imad r1.y, r6.z, l(0x00010000), r1.y + imad r0.y, r6.w, l(0x01000000), r1.y + break + case l(15) + mov_sat r5.xyzw, r5.xyzw + mad r6.xyzw, r5.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r6.xyzw, r6.xyzw + imad r1.y, r6.y, l(16), r6.x + imad r1.y, r6.z, l(256), r1.y + imad r1.y, r6.w, l(4096), r1.y + mov_sat r7.xyzw, r7.xyzw + mad r6.xyzw, r7.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r6.xyzw, r6.xyzw + imad r1.z, r6.y, l(16), r6.x + imad r1.z, r6.z, l(256), r1.z + ishl r2.z, r6.w, l(28) + imad r1.z, r1.z, l(0x00010000), r2.z + iadd r0.x, r1.z, r1.y + mov_sat r9.xyzw, r9.xyzw + mad r6.xyzw, r9.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r6.xyzw, r6.xyzw + imad r1.y, r6.y, l(16), r6.x + imad r1.y, r6.z, l(256), r1.y + imad r1.y, r6.w, l(4096), r1.y + mov_sat r8.xyzw, r8.xyzw + mad r6.xyzw, r8.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r6.xyzw, r6.xyzw + imad r1.z, r6.y, l(16), r6.x + imad r1.z, r6.z, l(256), r1.z + ishl r2.z, r6.w, l(28) + imad r1.z, r1.z, l(0x00010000), r2.z + iadd r0.y, r1.z, r1.y + break + case l(24) + mov_sat r8.z, r5.x + mov_sat r8.y, r7.x + mov_sat r8.w, r9.x + mov_sat r8.x, r8.x + mad r6.xyzw, r8.zywx, l(65535.000000, 65535.000000, 65535.000000, 65535.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r6.xyzw, r6.xyzw + imad r0.xy, r6.ywyy, l(0x00010000, 0x00010000, 0, 0), r6.xzxx + break + default + f32tof16 r1.y, r5.x + f32tof16 r1.z, r7.x + imad r0.x, r1.z, l(0x00010000), r1.y + f32tof16 r1.y, r9.x + f32tof16 r1.z, r8.x + imad r0.y, r1.z, l(0x00010000), r1.y + break +endswitch +ieq r1.y, r4.x, l(0) +ine r1.z, r1.x, l(0) +and r1.y, r1.z, r1.y +if_nz r1.y + uge r1.y, r1.x, l(2) + if_nz r1.y + uge r1.x, r1.x, l(3) + if_nz r1.x + ushr r1.x, r0.y, l(16) + bfi r0.y, l(16), l(0), r1.x, r0.y + endif + bfi r0.x, l(16), l(16), r0.y, r0.x + endif + ushr r1.x, r0.x, l(16) + bfi r0.x, l(16), l(0), r1.x, r0.x +endif +mov r4.z, vThreadID.y +imad r1.yz, r3.xxzx, r2.xxyx, r4.xxzx +ushr r1.x, r1.y, l(3) +udiv r2.zw, null, r1.xxxz, r2.xxxy +if_nz r0.w + ubfe r0.w, l(3), l(4), CB0[0][0].z + ishl r3.x, r3.y, l(5) + ishr r3.yz, r2.wwww, l(0, 4, 3, 0) + ishr r3.w, r0.w, l(2) + ushr r3.x, r3.x, l(4) + and r3.x, r3.x, l(2046) + imad r3.x, r3.w, r3.x, r3.y + ushr r3.y, r1.w, l(5) + ibfe r4.xy, l(27, 29, 0, 0), l(2, 0, 0, 0), r2.zzzz + imad r3.x, r3.x, r3.y, r4.x + ishl r3.y, r2.w, l(9) + ishr r3.y, r3.y, l(6) + and r3.y, r3.y, l(48) + iadd r3.z, r3.w, r3.z + bfi r3.w, l(1), l(1), r3.z, l(0) + iadd r3.w, r3.w, r4.y + bfi r3.w, l(2), l(1), r3.w, l(0) + bfi r3.z, l(1), l(0), r3.z, r3.w + bfi r3.xw, l(21, 0, 0, 21), l(9, 0, 0, 12), r3.xxxx, l(0, 0, 0, 0) + imad r3.xy, r3.yyyy, l(2, 16, 0, 0), r3.xwxx + bfi r3.xy, l(2, 2, 0, 0), l(7, 10, 0, 0), r0.wwww, r3.xyxx + bfi r0.w, l(1), l(4), r2.w, l(0) + ubfe r3.w, l(3), l(6), r3.x + and r4.x, r3.z, l(6) + bfi r3.z, l(1), l(8), r3.z, l(0) + imad r3.z, r3.w, l(32), r3.z + imad r3.z, r4.x, l(4), r3.z + bfi r3.xy, l(5, 5, 0, 0), l(0, 3, 0, 0), r0.wwww, r3.xyxx + bfi r0.w, l(9), l(3), r3.z, r3.y + bfi r0.w, l(6), l(0), r3.x, r0.w +else + ibfe r3.xy, l(27, 29, 0, 0), l(2, 0, 0, 0), r2.zzzz + ishr r3.zw, r2.wwww, l(0, 0, 5, 2) + ushr r1.w, r1.w, l(5) + imad r1.w, r3.z, r1.w, r3.x + bfi r4.xyz, l(4, 4, 4, 0), l(4, 7, 6, 0), r2.wwww, l(0, 0, 0, 0) + bfi r4.xyz, l(24, 24, 24, 0), l(8, 11, 10, 0), r1.wwww, r4.xyzx + ishl r1.w, r2.w, l(7) + and r1.w, r1.w, l(2048) + bfi r1.w, l(12), l(0), r1.w, r4.y + and r3.x, r4.z, l(1792) + iadd r1.w, r1.w, r3.x + and r3.x, r3.w, l(2) + iadd r3.x, r3.y, r3.x + bfi r3.x, l(2), l(6), r3.x, l(0) + iadd r1.w, r1.w, r3.x + bfi r0.w, l(6), l(0), r4.x, r1.w +endif +imad r1.xz, -r2.zzwz, r2.xxyx, r1.xxzx +imul null, r1.w, r2.y, r2.x +imad r1.x, r1.x, r2.y, r1.z +ishl r1.x, r1.x, l(4) +bfi r1.x, l(3), l(1), r1.y, r1.x +imad r0.w, r0.w, r1.w, r1.x +ushr r0.w, r0.w, l(3) +ieq r0.z, r0.z, l(1) +if_nz r0.z + ishl r1.xy, r0.xyxx, l(8, 8, 0, 0) + ushr r1.zw, r0.xxxy, l(0, 0, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0x00ff00ff, 0x00ff00ff) + iadd r0.xy, r1.zwzz, r1.xyxx +endif +store_uav_typed U0[0].xyzw, r0.wwww, r0.xyxx +ret +// Approximately 1355 instruction slots used +#endif + +const BYTE resolve_full_16bpp_scaled_cs[] = { + 68, 88, 66, 67, 82, 213, 18, 189, 197, 246, 219, 147, 75, 2, 155, 28, 248, 198, 204, + 233, 1, 0, 0, 0, 80, 164, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 144, 2, + 0, 0, 160, 2, 0, 0, 176, 2, 0, 0, 180, 163, 0, 0, 82, 68, 69, 70, 84, + 2, 0, 0, 1, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 44, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 101, 100, 114, 97, 109, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 213, 0, 0, 0, 4, 0, 0, 0, 252, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 156, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 220, 1, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 247, 1, 0, 0, 8, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 12, 2, 0, 0, 12, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, + 114, 101, 115, 111, 108, 118, 101, 95, 101, 100, 114, 97, 109, 95, 105, 110, 102, 111, 0, + 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 178, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 99, 111, 111, 114, + 100, 105, 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 100, 101, 115, 116, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 99, 111, 111, 114, 100, 105, 110, 97, + 116, 101, 95, 105, 110, 102, 111, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 83, 72, 69, 88, 252, 160, 0, 0, 81, 0, 5, 0, 63, 40, 0, + 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 161, 0, 0, 6, 70, + 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 156, 8, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 68, 68, 0, 0, 0, 0, 0, 0, 95, 0, 0, 2, 50, 0, 2, 0, 104, 0, + 0, 2, 24, 0, 0, 0, 155, 0, 0, 4, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, 0, 6, 138, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, + 0, 0, 0, 0, 32, 7, 0, 0, 0, 8, 0, 0, 0, 31, 0, 4, 3, 26, 0, + 16, 0, 0, 0, 0, 0, 138, 0, 0, 17, 50, 0, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 17, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 133, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, + 0, 1, 54, 0, 0, 8, 50, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 138, 0, 0, 17, 114, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 86, 133, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 1, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 1, 85, 0, 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, 214, 143, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, + 0, 10, 0, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 4, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, + 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 3, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 31, 0, + 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, + 0, 0, 17, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, + 11, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, + 0, 13, 0, 0, 0, 24, 0, 0, 0, 28, 0, 0, 0, 6, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 0, 16, 0, 6, + 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 140, 0, 0, 20, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 6, 4, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 139, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, + 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 140, 0, 0, 13, 130, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, + 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 140, 0, 0, 20, 82, 0, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 166, 11, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 17, 50, 0, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 230, 138, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 83, 0, 0, 6, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 2, 0, 35, 0, 0, 9, 194, 0, 16, 0, 2, 0, 0, 0, 166, + 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, + 4, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 31, 0, 4, 3, 26, 0, + 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 7, 0, 0, 0, 26, + 0, 16, 0, 6, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, + 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, + 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 18, 0, 0, 1, 54, + 0, 0, 5, 34, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 1, 21, 0, 0, 1, 80, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 162, 0, 16, 0, 4, + 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 194, 0, 16, + 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 86, 13, 16, 0, 4, 0, + 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 7, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, + 6, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 194, 0, + 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 6, + 0, 0, 0, 38, 0, 0, 11, 0, 208, 0, 0, 98, 0, 16, 0, 7, 0, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 80, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 7, 0, + 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 78, + 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, 166, 14, 16, 0, + 2, 0, 0, 0, 6, 8, 16, 0, 7, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, + 35, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 128, 65, 0, 0, + 0, 6, 0, 0, 0, 6, 8, 16, 0, 7, 0, 0, 0, 166, 14, 16, 0, 2, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 35, 0, 0, 9, + 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, + 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, + 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, + 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 78, 0, 0, 8, 0, 208, 0, 0, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 4, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 7, 66, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, 32, 0, 0, 7, + 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 2, 0, 0, 0, 41, 0, + 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 7, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 8, + 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 9, 0, 0, 0, 230, 10, 16, + 0, 7, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 10, 0, 0, 0, 230, 10, + 16, 0, 8, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 2, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 165, 0, 0, 8, 50, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, + 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, + 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 70, 112, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 86, 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 162, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 41, 0, + 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 165, 0, 0, 8, 50, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, + 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, + 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, + 5, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, + 10, 194, 0, 16, 0, 9, 0, 0, 0, 6, 4, 16, 0, 9, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, + 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 38, 7, 16, 0, 9, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 43, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 7, 0, 0, 0, 6, + 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, + 0, 38, 7, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 11, + 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, + 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, + 194, 0, 16, 0, 10, 0, 0, 0, 6, 4, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, + 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 38, 7, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 43, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 8, 0, 0, 0, 6, 4, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, + 38, 7, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, + 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, + 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, + 4, 0, 0, 0, 6, 4, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, + 16, 0, 9, 0, 0, 0, 6, 1, 16, 0, 9, 0, 0, 0, 131, 0, 0, 5, 162, + 0, 16, 0, 9, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, + 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, + 0, 5, 82, 0, 16, 0, 7, 0, 0, 0, 6, 1, 16, 0, 7, 0, 0, 0, 131, + 0, 0, 5, 162, 0, 16, 0, 7, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, + 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 10, 0, 0, 0, 6, 1, 16, 0, 10, + 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 10, 0, 0, 0, 86, 13, 16, 0, + 4, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 8, 0, 0, 0, 6, + 1, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 8, 0, 0, 0, + 86, 13, 16, 0, 4, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, + 8, 194, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, + 18, 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, + 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, + 242, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 54, 121, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, + 66, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 6, 112, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 162, 0, 16, 0, + 4, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, + 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, + 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, + 8, 18, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 6, 112, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, + 0, 16, 0, 5, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, + 0, 11, 0, 0, 0, 86, 5, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, + 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 85, 0, 0, 10, 226, 0, 16, 0, 11, 0, 0, 0, 166, 10, 16, 0, 8, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, + 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, + 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 11, 0, + 0, 0, 246, 15, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, + 11, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, + 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, + 0, 10, 226, 0, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, + 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, + 0, 16, 0, 11, 0, 0, 0, 86, 5, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, + 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 11, 0, 0, 0, 166, 10, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, + 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, + 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, + 0, 70, 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, + 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, + 11, 0, 0, 0, 246, 15, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, + 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, + 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, + 85, 0, 0, 10, 226, 0, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, + 32, 128, 58, 171, 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, + 3, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 11, 0, 0, 0, 86, 9, 16, 0, 8, 0, 0, 0, 2, 64, + 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, + 54, 0, 0, 5, 98, 0, 16, 0, 12, 0, 0, 0, 6, 1, 16, 0, 11, 0, 0, + 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 12, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 16, 0, 0, + 0, 70, 2, 16, 0, 14, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 16, 0, + 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, + 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, + 16, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 128, 65, + 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, + 16, 0, 17, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 41, 0, + 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, + 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, + 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 55, 0, 0, 12, 114, 0, + 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 0, 0, 5, 162, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, + 0, 11, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 230, 11, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 20, + 0, 0, 0, 20, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, 0, + 42, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 12, 0, 0, + 0, 6, 3, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, 0, + 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, + 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 135, 0, 0, + 5, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 30, 0, + 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, + 55, 0, 0, 12, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, + 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, + 9, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, + 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 140, 0, 0, 17, 114, + 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, + 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, + 16, 0, 12, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, + 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, + 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, + 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, + 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 12, + 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, + 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, + 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 13, + 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, 162, 0, 16, + 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 171, 170, 170, 62, 0, 0, 0, 0, 171, 170, 170, 62, 54, 0, 0, 5, 18, + 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, + 138, 0, 0, 15, 114, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 11, + 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, + 13, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, + 0, 15, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, + 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 15, 0, 0, 0, 70, + 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 11, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, + 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, + 0, 140, 0, 0, 17, 114, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, + 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, + 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, + 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, + 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, + 0, 13, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 23, 0, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, + 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, + 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, + 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 10, 0, 0, + 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 54, 0, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 30, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, + 0, 86, 0, 0, 5, 50, 0, 16, 0, 5, 0, 0, 0, 198, 0, 16, 0, 11, 0, + 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, + 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 14, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 15, + 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, + 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, + 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, + 128, 65, 0, 0, 0, 15, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, + 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, + 70, 2, 16, 0, 16, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 14, + 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, + 41, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, + 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, + 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 12, + 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 70, + 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 9, 0, 0, + 0, 26, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 7, 0, + 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 10, + 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, + 8, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, + 3, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 11, 0, + 0, 0, 150, 3, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, + 12, 0, 0, 0, 6, 1, 16, 0, 11, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, + 0, 12, 0, 0, 0, 86, 9, 16, 0, 8, 0, 0, 0, 42, 0, 0, 10, 242, 0, + 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, + 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, + 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, + 0, 0, 10, 50, 0, 16, 0, 9, 0, 0, 0, 70, 0, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 0, 0, 10, 50, 0, 16, 0, 7, 0, 0, 0, 230, 10, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 8, 0, 0, 0, 166, 11, 16, 0, + 11, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 214, 2, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, + 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 10, 0, + 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, + 8, 0, 0, 0, 230, 10, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, + 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, + 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 150, 3, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, + 26, 0, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 9, 0, 0, + 0, 10, 0, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 7, 0, + 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 7, + 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, + 10, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, + 0, 10, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 18, 0, + 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 34, + 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, 8, + 194, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, + 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, + 54, 0, 0, 8, 226, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, + 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 8, 226, + 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, + 0, 58, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 1, 23, 0, 0, 1, 21, 0, 0, 1, 80, 0, 0, 7, 130, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, + 0, 4, 3, 58, 0, 16, 0, 2, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, + 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 63, 35, 0, 0, 9, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 80, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 31, + 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, 32, 0, 0, 7, 34, 0, 16, 0, + 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 31, 0, 4, 3, 26, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, + 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, + 4, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 16, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 12, 0, 0, 0, 26, + 0, 16, 0, 4, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 50, 0, 16, 0, 13, 0, 0, 0, 230, 10, 16, 0, 11, 0, 0, + 0, 54, 0, 0, 5, 50, 0, 16, 0, 14, 0, 0, 0, 230, 10, 16, 0, 12, 0, + 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 58, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, + 50, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 41, + 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, + 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 11, 0, 0, + 0, 26, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 86, 5, 16, 0, + 1, 0, 0, 0, 30, 0, 0, 7, 162, 0, 16, 0, 4, 0, 0, 0, 246, 15, 16, + 0, 3, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 162, 0, + 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, + 50, 0, 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 12, 0, + 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 5, 0, 0, 0, + 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, + 0, 13, 0, 0, 0, 6, 4, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, + 0, 16, 0, 15, 0, 0, 0, 38, 7, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, + 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 52, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 11, 0, 0, 0, 6, 4, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 38, 7, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, + 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, + 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, + 14, 0, 0, 0, 6, 4, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, + 16, 0, 15, 0, 0, 0, 38, 7, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, + 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, + 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 41, 0, 0, 10, 194, 0, 16, 0, 12, 0, 0, 0, 6, 4, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 38, 7, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, + 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, + 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, + 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, + 6, 4, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 13, 0, + 0, 0, 6, 1, 16, 0, 13, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 13, + 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, + 4, 0, 0, 0, 6, 4, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, + 16, 0, 11, 0, 0, 0, 6, 1, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 162, + 0, 16, 0, 11, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, + 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 14, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, + 0, 5, 82, 0, 16, 0, 14, 0, 0, 0, 6, 1, 16, 0, 14, 0, 0, 0, 131, + 0, 0, 5, 162, 0, 16, 0, 14, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, + 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 12, 0, 0, 0, 6, 1, 16, 0, 12, + 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 12, 0, 0, 0, 86, 13, 16, 0, + 4, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 194, 0, 16, + 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, + 32, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 4, 0, + 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, + 12, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 54, 121, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 34, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, + 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, + 12, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 86, + 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 162, 0, 16, 0, 4, 0, 0, 0, + 246, 15, 16, 0, 3, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 41, 0, 0, + 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 130, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, + 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, + 0, 12, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 5, + 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, + 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, + 0, 86, 5, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, + 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, + 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, + 10, 226, 0, 16, 0, 15, 0, 0, 0, 166, 10, 16, 0, 12, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 246, 15, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, + 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, + 58, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, + 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 14, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, + 16, 0, 12, 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, + 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, + 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 15, + 0, 0, 0, 86, 5, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 15, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, + 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, + 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 166, 10, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, + 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 12, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, + 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, + 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, + 246, 15, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, + 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, + 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, + 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 8, + 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, + 226, 0, 16, 0, 12, 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, + 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, + 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, + 0, 15, 0, 0, 0, 86, 9, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 10, 0, + 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, + 0, 16, 0, 16, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 54, 0, 0, 5, + 98, 0, 16, 0, 16, 0, 0, 0, 6, 1, 16, 0, 15, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, + 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, + 0, 138, 0, 0, 15, 114, 0, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, + 16, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, + 0, 18, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, + 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, + 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 20, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 11, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 20, + 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, + 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, + 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, + 20, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, + 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, + 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, + 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, + 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, + 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 70, 2, 16, 0, 16, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 13, 0, + 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 0, 0, 5, 162, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 15, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 230, 11, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 20, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 16, 0, 0, 0, 42, 0, 16, 0, + 12, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 16, 0, 0, 0, 6, 3, 16, + 0, 15, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, + 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 30, 0, 0, 10, 114, 0, + 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 232, + 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, + 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, + 0, 20, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 21, 0, 0, 0, 70, + 2, 16, 128, 65, 0, 0, 0, 20, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, + 0, 21, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, + 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, + 0, 19, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 21, + 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, + 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, + 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 55, 0, + 0, 12, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, + 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, + 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 171, 170, + 170, 62, 0, 0, 0, 0, 171, 170, 170, 62, 54, 0, 0, 5, 18, 0, 16, 0, 15, + 0, 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, + 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, + 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, + 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 135, + 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, + 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, + 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, 0, 0, + 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, + 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, + 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, + 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, + 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, + 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, + 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, + 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, + 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 15, 0, 0, 0, 54, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 30, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 86, 0, 0, + 5, 50, 0, 16, 0, 5, 0, 0, 0, 198, 0, 16, 0, 15, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 1, + 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, + 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, + 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 15, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, + 2, 16, 0, 17, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, + 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, + 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 11, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, + 0, 19, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, + 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, + 20, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, + 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, + 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, + 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, 10, + 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, + 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, + 41, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, + 12, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 56, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, + 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 11, 0, 0, 0, 58, 0, + 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 14, 0, 0, 0, 10, + 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 12, 0, 0, 0, + 26, 0, 16, 0, 5, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, + 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 150, 3, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 16, 0, 0, 0, + 6, 1, 16, 0, 15, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 16, 0, 0, + 0, 86, 9, 16, 0, 12, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 16, 0, + 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, + 16, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 16, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 1, + 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, + 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, + 10, 50, 0, 16, 0, 11, 0, 0, 0, 230, 10, 16, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 98, 0, 16, 0, 12, 0, 0, 0, 166, 11, 16, 0, 15, 0, 0, 0, + 42, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 214, 2, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 14, 0, 0, 0, 70, 0, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 12, 0, 0, 0, + 230, 10, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 13, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 150, 3, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, + 12, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 13, 0, 0, 0, 10, 0, 16, + 0, 15, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, + 16, 0, 12, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 11, 0, 0, 0, 26, + 0, 16, 0, 15, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, + 58, 0, 16, 0, 12, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 14, 0, 0, + 0, 42, 0, 16, 0, 15, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 12, 0, + 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 12, + 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 5, 18, + 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 54, 0, 0, 8, + 226, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, 0, + 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, + 0, 12, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 14, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 226, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, + 1, 21, 0, 0, 1, 0, 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 0, 0, 0, 7, 242, + 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 0, 0, 0, 7, 242, 0, + 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, + 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 56, 0, 0, 7, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 128, 62, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 58, 0, + 16, 0, 5, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, + 58, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, + 0, 8, 242, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 230, + 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, + 4, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, + 0, 165, 0, 0, 8, 242, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 4, 0, + 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, + 0, 16, 0, 13, 0, 0, 0, 230, 10, 16, 0, 11, 0, 0, 0, 54, 0, 0, 5, + 50, 0, 16, 0, 14, 0, 0, 0, 230, 10, 16, 0, 12, 0, 0, 0, 18, 0, 0, + 1, 41, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 13, + 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, + 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, + 10, 50, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 30, + 0, 0, 7, 50, 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, + 0, 70, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 14, + 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, + 0, 5, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, + 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 5, 0, 0, 0, 6, 0, 0, 3, 1, + 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 13, 0, 0, 0, + 6, 4, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 15, 0, + 0, 0, 38, 7, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, + 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 1, + 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, + 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, + 10, 194, 0, 16, 0, 11, 0, 0, 0, 6, 4, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, + 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 38, 7, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 43, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 14, 0, 0, 0, 6, + 4, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, + 0, 38, 7, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, + 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, + 194, 0, 16, 0, 12, 0, 0, 0, 6, 4, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, + 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 38, 7, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 43, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, + 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 13, 0, 0, 0, 6, 1, 16, + 0, 13, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 13, 0, 0, 0, 6, 4, + 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 70, + 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 11, 0, 0, + 0, 6, 1, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 11, 0, + 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 5, + 0, 0, 0, 70, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, + 0, 14, 0, 0, 0, 6, 1, 16, 0, 14, 0, 0, 0, 131, 0, 0, 5, 162, 0, + 16, 0, 14, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 50, + 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, + 5, 82, 0, 16, 0, 12, 0, 0, 0, 6, 1, 16, 0, 12, 0, 0, 0, 131, 0, + 0, 5, 162, 0, 16, 0, 12, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 2, + 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 194, 0, 16, 0, 13, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, + 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, 130, + 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 12, 0, 0, 0, 58, + 0, 16, 0, 4, 0, 0, 0, 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 34, 0, + 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, 12, 0, 0, 0, 58, + 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, + 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, + 5, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, 0, + 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 6, 112, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 12, 0, 0, 0, + 26, 0, 16, 0, 5, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 5, 0, 0, 0, 6, 0, + 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, + 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 86, 5, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, + 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 26, 0, + 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, + 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, + 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, + 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, + 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, + 15, 0, 0, 0, 166, 10, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, + 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, + 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, + 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 246, 15, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, + 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 12, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, + 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 12, 0, 0, + 0, 6, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, + 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 129, + 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, 1, + 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, + 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 86, 5, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, + 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, + 26, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, + 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, + 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, + 16, 0, 15, 0, 0, 0, 166, 10, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, + 18, 0, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, + 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, + 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 246, 15, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, + 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, + 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, + 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, + 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, + 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 12, + 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 15, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, + 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 2, 0, + 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, 1, + 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, + 86, 9, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 16, 0, + 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 16, + 0, 0, 0, 6, 1, 16, 0, 15, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, + 6, 0, 0, 0, 6, 9, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 114, 0, + 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, + 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 135, + 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, + 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, + 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, 0, 0, + 17, 114, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, + 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, + 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, + 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 70, 2, 16, 0, 16, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, + 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, + 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, + 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, + 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, + 16, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 13, 0, 0, 0, 150, 7, 16, + 0, 6, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 50, + 0, 16, 0, 5, 0, 0, 0, 230, 10, 16, 0, 15, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 15, 0, 0, 0, 230, 11, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 16, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 54, + 0, 0, 5, 98, 0, 16, 0, 16, 0, 0, 0, 6, 3, 16, 0, 15, 0, 0, 0, + 1, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 6, 9, 16, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 16, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 17, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, + 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, + 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 11, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, + 0, 0, 19, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, + 0, 20, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 41, 0, 0, + 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 0, 41, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, + 0, 11, 0, 0, 0, 150, 7, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 16, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 56, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 58, 0, + 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 6, + 9, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 17, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 135, 0, 0, 5, 114, 0, + 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 30, 0, 0, 10, 114, + 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, + 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, + 12, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, + 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 128, 65, 0, 0, 0, 18, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, + 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, + 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, + 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, + 19, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, + 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 15, 0, + 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, + 0, 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 150, 7, 16, 0, 6, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 15, 0, + 0, 0, 54, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 10, + 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 86, 0, 0, 5, 98, 0, 16, 0, + 6, 0, 0, 0, 6, 3, 16, 0, 15, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 15, 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 114, 0, + 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, + 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, + 0, 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, + 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, + 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, + 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, + 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, + 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, + 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, + 0, 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, + 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, + 0, 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, + 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, + 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, + 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, + 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, + 16, 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 12, 0, 0, 0, 70, + 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, + 10, 98, 0, 16, 0, 6, 0, 0, 0, 86, 6, 16, 0, 6, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, 0, 0, 0, 0, 54, + 0, 0, 5, 130, 0, 16, 0, 13, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, + 54, 0, 0, 5, 130, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, + 0, 54, 0, 0, 5, 130, 0, 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, 6, 0, + 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 6, + 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 150, 3, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 16, 0, 0, 0, 6, 1, 16, 0, 15, + 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 16, 0, 0, 0, 86, 9, 16, 0, + 12, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, + 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 16, 0, 0, 0, 70, + 14, 16, 0, 16, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, + 70, 14, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 13, 0, + 0, 0, 70, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, + 11, 0, 0, 0, 230, 10, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 98, 0, + 16, 0, 12, 0, 0, 0, 166, 11, 16, 0, 15, 0, 0, 0, 42, 0, 0, 10, 242, + 0, 16, 0, 15, 0, 0, 0, 214, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, + 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 52, 0, 0, 10, 50, 0, 16, 0, 14, 0, 0, 0, 70, 0, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, + 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 12, 0, 0, 0, 230, 10, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, + 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 15, 0, 0, 0, 150, 3, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, 0, + 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 131, + 0, 0, 5, 34, 0, 16, 0, 13, 0, 0, 0, 10, 0, 16, 0, 15, 0, 0, 0, + 131, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, + 0, 131, 0, 0, 5, 34, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 15, 0, + 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 12, + 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, + 15, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, + 0, 12, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 12, 0, 0, 0, 58, 0, + 16, 0, 15, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 13, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, + 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, + 0, 12, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, + 54, 0, 0, 8, 226, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 226, 0, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, + 0, 0, 0, 7, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, + 0, 70, 14, 16, 0, 13, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 0, + 0, 0, 7, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 14, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 12, 0, 0, + 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 30, 0, + 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 26, + 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, + 32, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 3, 0, + 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, + 15, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 165, 0, 0, 8, 242, + 0, 16, 0, 16, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 230, 116, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 17, 0, 0, + 0, 230, 10, 16, 0, 15, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 18, 0, + 0, 0, 230, 10, 16, 0, 16, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 17, 0, 0, 0, 58, 0, 16, + 0, 3, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, + 8, 50, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 70, 112, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 162, 0, 16, + 0, 4, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 4, 0, + 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 18, 0, 0, 0, 26, 0, 16, + 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, + 0, 8, 50, 0, 16, 0, 16, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 70, + 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, + 42, 0, 16, 0, 5, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, + 0, 41, 0, 0, 10, 194, 0, 16, 0, 17, 0, 0, 0, 6, 4, 16, 0, 17, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 38, 7, 16, 0, + 17, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, + 16, 0, 19, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 70, + 14, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, + 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 15, + 0, 0, 0, 6, 4, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, + 0, 19, 0, 0, 0, 38, 7, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, + 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, 64, 0, + 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, + 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, + 41, 0, 0, 10, 194, 0, 16, 0, 18, 0, 0, 0, 6, 4, 16, 0, 18, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 38, 7, 16, 0, 18, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, + 0, 19, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, + 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, + 70, 14, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 16, 0, + 0, 0, 6, 4, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, + 19, 0, 0, 0, 38, 7, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, + 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, + 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, + 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, 10, + 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 17, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, + 0, 5, 82, 0, 16, 0, 17, 0, 0, 0, 6, 1, 16, 0, 17, 0, 0, 0, 131, + 0, 0, 5, 162, 0, 16, 0, 17, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, + 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 15, 0, 0, 0, 6, 1, 16, 0, 15, + 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 15, 0, 0, 0, 86, 13, 16, 0, + 4, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, + 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 18, 0, 0, 0, 6, + 1, 16, 0, 18, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 18, 0, 0, 0, + 86, 13, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, + 0, 6, 4, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 16, + 0, 0, 0, 6, 1, 16, 0, 16, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, + 16, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, + 1, 54, 0, 0, 8, 194, 0, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, + 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 18, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, + 23, 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, + 4, 3, 58, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 3, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 165, 0, 0, 8, 242, 0, 16, 0, 16, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, + 0, 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, + 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 16, 0, 0, 0, + 58, 0, 16, 0, 3, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 165, 0, 0, 8, 66, 0, 16, 0, 16, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 162, 0, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, + 162, 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 13, 16, + 0, 4, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 16, 0, 0, 0, + 26, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 165, 0, 0, 8, 18, 0, 16, 0, 16, 0, 0, 0, 58, 0, 16, 0, 4, 0, + 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, + 0, 0, 3, 42, 0, 16, 0, 5, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, + 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, + 10, 226, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 16, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, 166, 10, + 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, + 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, + 42, 0, 16, 0, 16, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 15, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, + 16, 0, 5, 0, 0, 0, 246, 15, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, + 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 16, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, + 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, + 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 16, 0, 0, 0, 6, 0, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, + 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 16, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, + 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 85, + 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 16, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, + 0, 54, 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 16, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, + 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, + 166, 10, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, + 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 5, 0, + 0, 0, 42, 0, 16, 0, 16, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, + 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, + 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, + 226, 0, 16, 0, 5, 0, 0, 0, 246, 15, 16, 0, 16, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 16, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, + 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, + 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 16, 0, 0, 0, 6, 0, 16, + 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, + 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 16, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, + 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, + 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 86, 9, 16, 0, 16, 0, + 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 30, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 19, 0, 0, 0, 26, 0, 16, 0, + 16, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 19, 0, 0, 0, 6, 1, 16, + 0, 5, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 6, 9, + 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, + 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 21, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, + 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 30, 0, 0, 10, 114, 0, + 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, 232, + 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, + 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, + 0, 22, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 23, 0, 0, 0, 70, + 2, 16, 128, 65, 0, 0, 0, 22, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, + 0, 23, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, 0, + 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 19, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, + 0, 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 19, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 23, + 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, + 0, 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 55, 0, + 0, 12, 114, 0, 16, 0, 17, 0, 0, 0, 150, 7, 16, 0, 6, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 162, 0, 16, 0, 4, 0, 0, + 0, 166, 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, + 0, 0, 230, 11, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, + 19, 0, 0, 0, 42, 0, 16, 0, 16, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, + 0, 19, 0, 0, 0, 6, 3, 16, 0, 5, 0, 0, 0, 1, 0, 0, 10, 226, 0, + 16, 0, 6, 0, 0, 0, 6, 9, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, + 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, + 0, 15, 114, 0, 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 135, 0, 0, 5, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, + 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, + 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, + 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, + 0, 20, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, + 0, 16, 0, 23, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 22, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 55, 0, 0, 9, 114, 0, 16, 0, 23, 0, 0, 0, 70, 2, 16, 0, 21, 0, + 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 140, + 0, 0, 17, 114, 0, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, + 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, + 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, + 0, 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, + 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 20, + 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, + 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, + 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, + 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, + 16, 0, 19, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 15, 0, 0, 0, 150, + 7, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, + 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 171, 170, 170, 62, 0, 0, 0, 0, 171, 170, 170, 62, 54, + 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 16, 0, 0, 0, + 1, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 6, 9, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 20, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 5, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 21, 0, 0, 0, + 70, 2, 16, 0, 19, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 21, 0, 0, + 0, 70, 2, 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, + 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 21, + 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 11, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 128, 65, 0, + 0, 0, 21, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 22, 0, 0, 0, + 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, + 0, 22, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, + 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 41, 0, 0, + 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 0, 41, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, + 19, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, + 0, 18, 0, 0, 0, 150, 7, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 5, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 54, 0, 16, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 86, 0, 0, 5, 98, 0, 16, 0, 6, 0, 0, 0, 6, 3, + 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 10, + 0, 16, 0, 16, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 20, 0, + 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, + 21, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 135, 0, 0, 5, 114, + 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 30, 0, 0, 10, + 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, + 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, + 0, 12, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, + 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 23, 0, 0, + 0, 70, 2, 16, 128, 65, 0, 0, 0, 22, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, + 0, 16, 0, 23, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, + 21, 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 5, 0, 0, 0, 70, + 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, + 5, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, + 0, 23, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, + 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, + 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, + 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 5, + 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, + 55, 0, 0, 12, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, 50, 0, 16, 0, 5, + 0, 0, 0, 150, 5, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 171, 170, 170, 62, + 171, 170, 170, 62, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, + 0, 17, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, + 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, + 0, 16, 0, 18, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, + 130, 0, 16, 0, 16, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 2, 0, 0, + 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 150, 3, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, + 82, 0, 16, 0, 19, 0, 0, 0, 6, 1, 16, 0, 5, 0, 0, 0, 54, 0, 0, + 5, 162, 0, 16, 0, 19, 0, 0, 0, 86, 9, 16, 0, 16, 0, 0, 0, 42, 0, + 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 43, 0, 0, 5, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 17, 0, 0, 0, 70, 0, 16, 0, + 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, + 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 15, 0, 0, 0, 230, 10, + 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 16, 0, 0, 0, + 166, 11, 16, 0, 5, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 214, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, + 16, 0, 18, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, + 50, 0, 16, 0, 16, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 18, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 194, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, + 3, 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, + 0, 0, 150, 3, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, + 17, 0, 0, 0, 26, 0, 16, 0, 16, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, + 0, 17, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 131, 0, 0, 5, 18, 0, + 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 16, 0, 0, 0, 131, 0, 0, 5, 34, + 0, 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 131, 0, 0, 5, + 18, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 16, 0, 0, 0, 131, 0, 0, + 5, 34, 0, 16, 0, 18, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 131, 0, + 0, 5, 18, 0, 16, 0, 16, 0, 0, 0, 10, 0, 16, 0, 16, 0, 0, 0, 131, + 0, 0, 5, 34, 0, 16, 0, 16, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 18, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, + 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 17, 0, 0, 0, 26, 0, 16, 0, + 16, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 17, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 16, 0, 0, 0, 54, + 0, 0, 8, 226, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 18, 0, 0, 0, 58, 0, 16, 0, 16, 0, 0, 0, 54, 0, 0, 8, 226, 0, + 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 16, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, 0, 0, 0, 7, 242, 0, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 17, + 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 18, 0, + 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, + 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 21, 0, 0, + 1, 21, 0, 0, 1, 56, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, 86, 5, + 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 56, 0, 0, 7, 242, + 0, 16, 0, 7, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 56, 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 86, 5, 16, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 7, 242, 0, + 16, 0, 8, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 8, + 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, + 82, 0, 16, 0, 5, 0, 0, 0, 166, 8, 16, 0, 5, 0, 0, 0, 54, 0, 0, + 5, 82, 0, 16, 0, 7, 0, 0, 0, 166, 8, 16, 0, 7, 0, 0, 0, 54, 0, + 0, 5, 82, 0, 16, 0, 9, 0, 0, 0, 166, 8, 16, 0, 9, 0, 0, 0, 54, + 0, 0, 5, 82, 0, 16, 0, 8, 0, 0, 0, 166, 8, 16, 0, 8, 0, 0, 0, + 21, 0, 0, 1, 76, 0, 0, 3, 10, 0, 16, 0, 6, 0, 0, 0, 6, 0, 0, + 3, 1, 64, 0, 0, 3, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 5, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 6, + 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, + 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 128, 63, 2, 64, 0, 0, 0, 0, 0, + 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, + 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 32, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 4, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 128, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 7, 0, 0, + 0, 70, 14, 16, 0, 7, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, + 0, 248, 65, 0, 0, 248, 65, 0, 0, 128, 63, 2, 64, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, + 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 66, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 32, + 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 35, + 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 1, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, + 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 9, 0, 0, 0, 70, + 14, 16, 0, 9, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, + 65, 0, 0, 248, 65, 0, 0, 128, 63, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, + 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 6, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, + 0, 10, 0, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 128, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 8, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 6, 0, 0, 0, 70, + 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, + 0, 0, 248, 65, 0, 0, 128, 63, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, + 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, + 10, 0, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 35, 0, 0, 9, + 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 1, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, + 54, 32, 0, 5, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, + 0, 50, 0, 0, 15, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 5, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 248, 65, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0, 0, 0, 28, 0, 0, 5, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, + 0, 6, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, + 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 6, + 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 54, 32, 0, 5, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, + 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 248, 65, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, + 63, 0, 0, 0, 0, 28, 0, 0, 5, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, + 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, + 6, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 35, 0, 0, 9, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 1, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 54, 32, 0, 5, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, + 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 9, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 248, 65, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, + 63, 0, 0, 0, 0, 28, 0, 0, 5, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, + 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, + 6, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 54, 32, 0, 5, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, + 0, 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 248, + 65, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, + 0, 63, 0, 0, 0, 0, 28, 0, 0, 5, 114, 0, 16, 0, 6, 0, 0, 0, 70, + 2, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, + 0, 6, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, + 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 35, 0, 0, 9, 66, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 1, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, 54, + 32, 0, 5, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, + 50, 0, 0, 15, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, + 0, 0, 0, 28, 0, 0, 5, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, + 6, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 6, 0, + 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 6, + 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 54, 32, 0, 5, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, + 0, 50, 0, 0, 15, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 124, 66, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0, 0, 0, 28, 0, 0, 5, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, + 0, 6, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, + 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 6, + 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 1, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 54, 32, 0, 5, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, + 0, 50, 0, 0, 15, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 9, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 124, 66, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0, 0, 0, 28, 0, 0, 5, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, + 0, 6, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, + 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 6, + 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 54, 32, 0, 5, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, + 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 124, 66, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, + 63, 0, 0, 0, 0, 28, 0, 0, 5, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, + 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, + 6, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 35, 0, 0, 9, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 1, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 54, 32, + 0, 5, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 54, + 32, 0, 5, 194, 0, 16, 0, 5, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, + 50, 0, 0, 15, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, + 127, 67, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, + 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 1, 0, 0, 10, 0, 16, 0, 6, 0, + 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 6, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 1, 26, 0, 16, 0, 1, 0, 0, 0, 54, 32, + 0, 5, 50, 0, 16, 0, 9, 0, 0, 0, 70, 0, 16, 0, 9, 0, 0, 0, 54, + 32, 0, 5, 194, 0, 16, 0, 9, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, + 50, 0, 0, 15, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, + 127, 67, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, + 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 1, 0, 0, 10, 0, 16, 0, 6, 0, + 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 6, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 1, 26, 0, 16, 0, 1, 0, 0, 0, 2, 0, + 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 15, 0, 0, 0, 54, 32, 0, 5, 242, + 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 50, 0, 0, 15, + 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 2, 64, + 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, + 0, 0, 5, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, + 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, + 0, 1, 64, 0, 0, 16, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, + 64, 0, 0, 0, 1, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, + 34, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, + 0, 0, 16, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 54, 32, 0, 5, 242, 0, + 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 50, 0, 0, 15, 242, + 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 2, 64, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, + 0, 5, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 35, + 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, + 1, 64, 0, 0, 16, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 0, 1, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, + 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 28, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, + 0, 6, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 2, 64, 0, 0, 0, + 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, + 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 35, 0, 0, + 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 16, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 0, 1, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 16, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 8, + 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, + 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 112, + 65, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 2, 64, 0, 0, 0, 0, + 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, + 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, + 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, + 0, 16, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, + 1, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, + 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, + 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, + 0, 24, 0, 0, 0, 54, 32, 0, 5, 66, 0, 16, 0, 8, 0, 0, 0, 10, 0, + 16, 0, 5, 0, 0, 0, 54, 32, 0, 5, 34, 0, 16, 0, 8, 0, 0, 0, 10, + 0, 16, 0, 7, 0, 0, 0, 54, 32, 0, 5, 130, 0, 16, 0, 8, 0, 0, 0, + 10, 0, 16, 0, 9, 0, 0, 0, 54, 32, 0, 5, 18, 0, 16, 0, 8, 0, 0, + 0, 10, 0, 16, 0, 8, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 6, 0, + 0, 0, 102, 3, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 255, 127, 71, 0, + 255, 127, 71, 0, 255, 127, 71, 0, 255, 127, 71, 2, 64, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, + 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 35, 0, 0, 12, 50, 0, + 16, 0, 0, 0, 0, 0, 214, 5, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 0, 16, 0, + 6, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 130, 0, 0, 5, 34, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 130, 0, 0, 5, 66, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 35, 0, 0, 9, 18, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 1, 0, 26, 0, 16, 0, 1, 0, 0, 0, 130, 0, 0, 5, 34, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 130, 0, 0, 5, 66, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 1, 0, 26, 0, 16, 0, 1, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, + 1, 32, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 39, 0, 0, 7, 66, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, + 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, + 1, 0, 0, 0, 80, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 31, 0, 4, 3, 10, 0, + 16, 0, 1, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 140, 0, 0, 11, + 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 21, 0, 0, 1, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 16, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, + 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 16, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 16, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 54, 0, 0, + 4, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 9, 98, 0, + 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 6, 1, 16, 0, 2, + 0, 0, 0, 6, 2, 16, 0, 4, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 78, 0, 0, 8, 194, 0, 16, 0, 2, 0, 0, 0, 0, 208, 0, 0, 6, 8, + 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, + 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, + 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 42, 0, 0, 10, 98, 0, 16, 0, 3, 0, 0, 0, 246, 15, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 18, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, + 0, 3, 0, 0, 0, 1, 64, 0, 0, 254, 7, 0, 0, 35, 0, 0, 9, 18, 0, + 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, + 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, + 0, 139, 0, 0, 15, 50, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 27, 0, + 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, + 2, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, + 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 4, 0, + 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, + 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, + 0, 1, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, + 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, + 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 20, 146, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, + 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, + 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, + 0, 3, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 0, 16, 0, 3, + 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, + 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 138, 0, 0, 9, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, + 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, + 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 32, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 3, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 3, 0, + 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 26, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, + 0, 0, 15, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, + 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 2, 0, + 0, 0, 42, 0, 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 246, 15, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, + 2, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 130, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 20, 114, 0, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, + 114, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, 24, 0, 0, + 0, 24, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 11, 0, + 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, + 2, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, + 0, 3, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 7, + 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, + 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, + 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 4, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 35, 0, 0, + 10, 82, 0, 16, 0, 1, 0, 0, 0, 166, 11, 16, 128, 65, 0, 0, 0, 2, 0, + 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 38, + 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 32, 0, 0, 7, 66, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, + 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 0, 10, 194, 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 255, 0, 255, 0, 255, 0, + 255, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 1, + 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, + 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, + 0, 0, 75, 5, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 133, + 0, 0, 0, 70, 1, 0, 0, 178, 0, 0, 0, 62, 0, 0, 0, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 196, 0, 0, 0, 64, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_32bpp_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_32bpp_cs.h new file mode 100644 index 0000000..f6fba09 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_32bpp_cs.h @@ -0,0 +1,3559 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_resolve_edram_info; // Offset: 0 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 4 Size: 4 +// uint xe_resolve_dest_info; // Offset: 8 Size: 4 +// uint xe_resolve_dest_coordinate_info;// Offset: 12 Size: 4 +// uint xe_resolve_dest_base; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram texture byte r/o T0 t0 1 +// xe_resolve_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][2], immediateIndexed, space=0 +dcl_resource_raw T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 24 +dcl_thread_group 8, 8, 1 +and r0.xyzw, CB0[0][0].xzzz, l(1023, 7, 8, 0x01000000) +ushr r1.xyz, CB0[0][0].yywy, l(4, 5, 10, 0) +ushr r2.xyzw, CB0[0][0].wwww, l(20, 24, 24, 20) +ishl r3.xw, vThreadID.xxxx, l(2, 0, 0, 2) +bfi r1.y, l(11), l(3), r1.y, l(0) +uge r1.y, r3.w, r1.y +if_nz r1.y + ret +endif +ubfe r4.xyzw, l(2, 11, 4, 1), l(10, 13, 24, 28), CB0[0][0].xxxx +mov r1.w, CB0[0][0].y +bfi r1.xy, l(4, 1, 0, 0), l(3, 3, 0, 0), r1.wxww, l(0, 0, 0, 0) +ibfe r1.w, l(6), l(16), CB0[0][0].z +ishl r1.w, r1.w, l(23) +iadd r1.w, r1.w, l(0x3f800000) +bfi r5.x, l(10), l(5), CB0[0][0].w, l(0) +bfi r2.xyzw, l(4, 4, 4, 4), l(3, 3, 3, 3), r2.xyzw, l(0, 0, 0, 0) +ubfe r5.yz, l(0, 6, 3, 0), l(0, 7, 28, 0), CB0[0][0].zzwz +mov r3.yz, vThreadID.yyyy +iadd r1.xy, r1.xyxx, r3.wzww +uge r5.w, l(3), r5.z +if_nz r5.w + mov r6.y, r5.z +else + ieq r5.w, r5.z, l(5) + if_nz r5.w + mov r6.y, l(2) + else + mov r6.y, l(0) + endif +endif +uge r6.zw, r4.xxxx, l(0, 0, 2, 1) +and r6.zw, r6.zzzw, l(0, 0, 1, 1) +ishl r1.xy, r1.xyxx, r6.zwzz +ushr r6.x, r6.y, l(1) +and r6.xy, r6.xyxx, l(1, 1, 0, 0) +iadd r1.xy, r1.xyxx, r6.xyxx +ushr r6.x, l(80), r4.w +mov r6.y, l(16) +udiv r7.xy, null, r1.xyxx, r6.xyxx +imad r0.x, r7.y, r0.x, r7.x +iadd r0.x, r0.x, r4.y +imad r1.xy, -r7.xyxx, r6.xyxx, r1.xyxx +imad r1.x, r1.y, r6.x, r1.x +ishl r1.x, r1.x, r4.w +imad r0.x, r0.x, l(1280), r1.x +udiv null, r0.x, r0.x, l(0x00280000) +iadd r1.x, r4.w, r6.z +ishl r1.y, l(1), r1.x +if_nz r4.w + ieq r4.x, r1.y, l(2) + if_nz r4.x + ishl r4.x, r0.x, l(2) + ld_raw r6.xyzw, r4.x, T0[0].zwxy + iadd r4.x, r4.x, l(16) + ld_raw r7.xyzw, r4.x, T0[0].zwxy + mov r8.xy, r6.zwzz + mov r9.xy, r7.zwzz + else + ishl r4.x, r0.x, l(2) + ld_raw r8.xy, r4.x, T0[0].xyxx + iadd r4.x, r0.x, r1.y + ishl r4.x, r4.x, l(2) + ld_raw r6.xy, r4.x, T0[0].xyxx + ishl r4.xy, l(2, 3, 0, 0), r1.xxxx + iadd r4.xy, r0.xxxx, r4.xyxx + ishl r4.xy, r4.xyxx, l(2, 2, 0, 0) + ld_raw r9.xy, r4.x, T0[0].xyxx + ld_raw r7.xy, r4.y, T0[0].xyxx + endif + switch r4.z + case l(5) + ishl r8.zw, r8.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r8.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r6.zw, r6.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r6.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r6.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r9.zw, r9.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r9.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r7.zw, r7.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r7.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r7.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.xy, r8.xyxx, l(16, 16, 0, 0) + f16tof32 r8.xz, r8.xxyx + f16tof32 r8.yw, r4.xxxy + ushr r4.xy, r6.xyxx, l(16, 16, 0, 0) + f16tof32 r6.xz, r6.xxyx + f16tof32 r6.yw, r4.xxxy + ushr r4.xy, r9.xyxx, l(16, 16, 0, 0) + f16tof32 r9.xz, r9.xxyx + f16tof32 r9.yw, r4.xxxy + ushr r4.xy, r7.xyxx, l(16, 16, 0, 0) + f16tof32 r7.xz, r7.xxyx + f16tof32 r7.yw, r4.xxxy + break + default + mov r8.zw, l(0,0,0,0) + mov r6.zw, l(0,0,0,0) + mov r9.zw, l(0,0,0,0) + mov r7.zw, l(0,0,0,0) + break + endswitch +else + ieq r4.x, r1.y, l(1) + if_nz r4.x + ishl r4.x, r0.x, l(2) + ld_raw r7.xyzw, r4.x, T0[0].wxyz + else + ishl r4.x, r0.x, l(2) + ld_raw r7.y, r4.x, T0[0].xxxx + iadd r4.x, r0.x, r1.y + ishl r4.x, r4.x, l(2) + ld_raw r7.z, r4.x, T0[0].xxxx + ishl r4.xy, l(2, 3, 0, 0), r1.xxxx + iadd r4.xy, r0.xxxx, r4.xyxx + ishl r4.xy, r4.xyxx, l(2, 2, 0, 0) + ld_raw r7.w, r4.x, T0[0].xxxx + ld_raw r7.x, r4.y, T0[0].xxxx + endif + switch r4.z + case l(0) + case l(1) + ushr r10.yzw, r7.yyyy, l(0, 8, 16, 24) + mov r10.x, r7.y + and r10.xyzw, r10.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r10.yzw, r7.zzzz, l(0, 8, 16, 24) + mov r10.x, r7.z + and r10.xyzw, r10.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r6.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r10.yzw, r7.wwww, l(0, 8, 16, 24) + mov r10.x, r7.w + and r10.xyzw, r10.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r7.yzw, r7.xxxx, l(0, 8, 16, 24) + and r10.xyzw, r7.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r7.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r10.yzw, r7.yyyy, l(0, 10, 20, 30) + mov r10.x, r7.y + and r10.xyzw, r10.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r10.yzw, r7.zzzz, l(0, 10, 20, 30) + mov r10.x, r7.z + and r10.xyzw, r10.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r6.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r10.yzw, r7.wwww, l(0, 10, 20, 30) + mov r10.x, r7.w + and r10.xyzw, r10.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r7.yzw, r7.xxxx, l(0, 10, 20, 30) + and r10.xyzw, r7.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r7.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r10.xyzw, r7.yyyz, l(10, 20, 30, 30) + mov r11.x, r7.y + mov r11.yz, r10.xxyx + and r12.xyz, r11.xyzx, l(1023, 1023, 1023, 0) + and r13.xyz, r11.xyzx, l(127, 127, 127, 0) + ubfe r14.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r11.xyzx + firstbit_hi r15.xyz, r13.xyzx + iadd r15.xyz, r15.xyzx, l(-24, -24, -24, 0) + movc r15.xyz, r13.xyzx, r15.xyzx, l(8,8,8,0) + iadd r16.xyz, -r15.xyzx, l(1, 1, 1, 0) + movc r16.xyz, r14.xyzx, r14.xyzx, r16.xyzx + bfi r11.xyz, l(7, 7, 7, 0), r15.xyzx, r11.xyzx, l(0, 0, 0, 0) + and r11.xyz, r11.xyzx, l(127, 127, 127, 0) + movc r11.xyz, r14.xyzx, r13.xyzx, r11.xyzx + ishl r13.xyz, r16.xyzx, l(23, 23, 23, 0) + iadd r13.xyz, r13.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r11.xyz, r11.xyzx, l(16, 16, 16, 0) + iadd r11.xyz, r13.xyzx, r11.xyzx + movc r8.xyz, r12.xyzx, r11.xyzx, l(0,0,0,0) + utof r4.xy, r10.zwzz + ushr r10.xyzw, r7.zwwz, l(10, 10, 20, 20) + mov r11.x, r7.z + mov r11.yz, r10.xxwx + and r12.xyz, r11.xyzx, l(1023, 1023, 1023, 0) + and r13.xyz, r11.xyzx, l(127, 127, 127, 0) + ubfe r14.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r11.xyzx + firstbit_hi r15.xyz, r13.xyzx + iadd r15.xyz, r15.xyzx, l(-24, -24, -24, 0) + movc r15.xyz, r13.xyzx, r15.xyzx, l(8,8,8,0) + iadd r16.xyz, -r15.xyzx, l(1, 1, 1, 0) + movc r16.xyz, r14.xyzx, r14.xyzx, r16.xyzx + bfi r11.xyz, l(7, 7, 7, 0), r15.xyzx, r11.xyzx, l(0, 0, 0, 0) + and r11.xyz, r11.xyzx, l(127, 127, 127, 0) + movc r11.xyz, r14.xyzx, r13.xyzx, r11.xyzx + ishl r13.xyz, r16.xyzx, l(23, 23, 23, 0) + iadd r13.xyz, r13.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r11.xyz, r11.xyzx, l(16, 16, 16, 0) + iadd r11.xyz, r13.xyzx, r11.xyzx + movc r6.xyz, r12.xyzx, r11.xyzx, l(0,0,0,0) + mul r4.xy, r4.xyxx, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r10.x, r7.w + and r11.xyz, r10.xyzx, l(1023, 1023, 1023, 0) + and r12.xyz, r10.xyzx, l(127, 127, 127, 0) + ubfe r13.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r10.xyzx + firstbit_hi r14.xyz, r12.xyzx + iadd r14.xyz, r14.xyzx, l(-24, -24, -24, 0) + movc r14.xyz, r12.xyzx, r14.xyzx, l(8,8,8,0) + iadd r15.xyz, -r14.xyzx, l(1, 1, 1, 0) + movc r15.xyz, r13.xyzx, r13.xyzx, r15.xyzx + bfi r10.xyz, l(7, 7, 7, 0), r14.xyzx, r10.xyzx, l(0, 0, 0, 0) + and r10.xyz, r10.xyzx, l(127, 127, 127, 0) + movc r10.xyz, r13.xyzx, r12.xyzx, r10.xyzx + ishl r12.xyz, r15.xyzx, l(23, 23, 23, 0) + iadd r12.xyz, r12.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r10.xyz, r10.xyzx, l(16, 16, 16, 0) + iadd r10.xyz, r12.xyzx, r10.xyzx + movc r9.xyz, r11.xyzx, r10.xyzx, l(0,0,0,0) + ushr r10.xyzw, r7.wxxx, l(30, 10, 20, 30) + utof r11.xy, r10.xwxx + mov r10.x, r7.x + and r12.xyz, r10.xyzx, l(1023, 1023, 1023, 0) + and r13.xyz, r10.xyzx, l(127, 127, 127, 0) + ubfe r14.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r10.xyzx + firstbit_hi r15.xyz, r13.xyzx + iadd r15.xyz, r15.xyzx, l(-24, -24, -24, 0) + movc r15.xyz, r13.xyzx, r15.xyzx, l(8,8,8,0) + iadd r16.xyz, -r15.xyzx, l(1, 1, 1, 0) + movc r16.xyz, r14.xyzx, r14.xyzx, r16.xyzx + bfi r10.xyz, l(7, 7, 7, 0), r15.xyzx, r10.xyzx, l(0, 0, 0, 0) + and r10.xyz, r10.xyzx, l(127, 127, 127, 0) + movc r10.xyz, r14.xyzx, r13.xyzx, r10.xyzx + ishl r13.xyz, r16.xyzx, l(23, 23, 23, 0) + iadd r13.xyz, r13.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r10.xyz, r10.xyzx, l(16, 16, 16, 0) + iadd r10.xyz, r13.xyzx, r10.xyzx + movc r7.xyz, r12.xyzx, r10.xyzx, l(0,0,0,0) + mul r10.xy, r11.xyxx, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r8.w, r4.x + mov r6.w, r4.y + mov r9.w, r10.x + mov r7.w, r10.y + break + case l(4) + ishl r10.xyzw, r7.yzwx, l(16, 16, 16, 16) + mov r11.xz, r10.xxyx + mov r11.yw, r7.yyyz + ishr r11.xyzw, r11.xyzw, l(16, 16, 16, 16) + itof r11.xyzw, r11.xyzw + mul r11.xyzw, r11.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xy, r11.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r6.xy, r11.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r7.yz, r10.zzwz + ishr r10.xyzw, r7.ywzx, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xy, r10.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r7.xy, r10.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r8.zw, l(0,0,0,0) + mov r6.zw, l(0,0,0,0) + mov r9.zw, l(0,0,0,0) + mov r7.zw, l(0,0,0,0) + break + case l(6) + ushr r10.xyzw, r7.yzwx, l(16, 16, 16, 16) + f16tof32 r8.x, r7.y + f16tof32 r8.y, r10.x + f16tof32 r6.x, r7.z + f16tof32 r6.y, r10.y + f16tof32 r9.x, r7.w + f16tof32 r9.y, r10.z + f16tof32 r7.x, r7.x + f16tof32 r7.y, r10.w + mov r8.zw, l(0,0,0,0) + mov r6.zw, l(0,0,0,0) + mov r9.zw, l(0,0,0,0) + mov r7.zw, l(0,0,0,0) + break + default + mov r8.x, r7.y + mov r8.yzw, l(0,0,0,0) + mov r6.x, r7.z + mov r6.yzw, l(0,0,0,0) + mov r9.x, r7.w + mov r9.yzw, l(0,0,0,0) + mov r7.yzw, l(0,0,0,0) + break + endswitch +endif +uge r4.x, r5.z, l(4) +if_nz r4.x + mul r4.x, r1.w, l(0.500000) + iadd r4.y, r0.x, l(80) + if_nz r4.w + ieq r5.w, r1.y, l(2) + if_nz r5.w + ishl r5.w, r4.y, l(2) + ld_raw r10.xyzw, r5.w, T0[0].zwxy + iadd r5.w, r5.w, l(16) + ld_raw r11.xyzw, r5.w, T0[0].zwxy + mov r12.xy, r10.zwzz + mov r14.xy, r11.zwzz + else + ishl r5.w, r4.y, l(2) + ld_raw r12.xy, r5.w, T0[0].xyxx + iadd r5.w, r1.y, r4.y + ishl r5.w, r5.w, l(2) + ld_raw r10.xy, r5.w, T0[0].xyxx + ishl r13.xy, l(2, 3, 0, 0), r1.xxxx + iadd r13.xy, r4.yyyy, r13.xyxx + ishl r13.xy, r13.xyxx, l(2, 2, 0, 0) + ld_raw r14.xy, r13.x, T0[0].xyxx + ld_raw r11.xy, r13.y, T0[0].xyxx + endif + switch r4.z + case l(5) + ishl r12.zw, r12.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r12.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r12.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r10.zw, r10.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r10.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r10.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r14.zw, r14.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r14.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r11.zw, r11.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r11.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r11.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r13.xy, r12.xyxx, l(16, 16, 0, 0) + f16tof32 r12.xz, r12.xxyx + f16tof32 r12.yw, r13.xxxy + ushr r13.xy, r10.xyxx, l(16, 16, 0, 0) + f16tof32 r10.xz, r10.xxyx + f16tof32 r10.yw, r13.xxxy + ushr r13.xy, r14.xyxx, l(16, 16, 0, 0) + f16tof32 r14.xz, r14.xxyx + f16tof32 r14.yw, r13.xxxy + ushr r13.xy, r11.xyxx, l(16, 16, 0, 0) + f16tof32 r11.xz, r11.xxyx + f16tof32 r11.yw, r13.xxxy + break + default + mov r12.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + break + endswitch + else + ieq r5.w, r1.y, l(1) + if_nz r5.w + ishl r5.w, r4.y, l(2) + ld_raw r11.xyzw, r5.w, T0[0].wxyz + else + ishl r5.w, r4.y, l(2) + ld_raw r11.y, r5.w, T0[0].xxxx + iadd r5.w, r1.y, r4.y + ishl r5.w, r5.w, l(2) + ld_raw r11.z, r5.w, T0[0].xxxx + ishl r13.xy, l(2, 3, 0, 0), r1.xxxx + iadd r13.xy, r4.yyyy, r13.xyxx + ishl r13.xy, r13.xyxx, l(2, 2, 0, 0) + ld_raw r11.w, r13.x, T0[0].xxxx + ld_raw r11.x, r13.y, T0[0].xxxx + endif + switch r4.z + case l(0) + case l(1) + ushr r13.yzw, r11.yyyy, l(0, 8, 16, 24) + mov r13.x, r11.y + and r13.xyzw, r13.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r12.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r13.yzw, r11.zzzz, l(0, 8, 16, 24) + mov r13.x, r11.z + and r13.xyzw, r13.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r10.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r13.yzw, r11.wwww, l(0, 8, 16, 24) + mov r13.x, r11.w + and r13.xyzw, r13.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r14.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r11.yzw, r11.xxxx, l(0, 8, 16, 24) + and r13.xyzw, r11.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r11.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r13.yzw, r11.yyyy, l(0, 10, 20, 30) + mov r13.x, r11.y + and r13.xyzw, r13.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r12.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r13.yzw, r11.zzzz, l(0, 10, 20, 30) + mov r13.x, r11.z + and r13.xyzw, r13.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r10.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r13.yzw, r11.wwww, l(0, 10, 20, 30) + mov r13.x, r11.w + and r13.xyzw, r13.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r14.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r11.yzw, r11.xxxx, l(0, 10, 20, 30) + and r13.xyzw, r11.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r11.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r13.xyzw, r11.yyyz, l(10, 20, 30, 30) + mov r15.x, r11.y + mov r15.yz, r13.xxyx + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r12.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + utof r13.xy, r13.zwzz + ushr r15.xyzw, r11.zwwz, l(10, 10, 20, 20) + mov r16.x, r11.z + mov r16.yz, r15.xxwx + and r17.xyz, r16.xyzx, l(1023, 1023, 1023, 0) + and r18.xyz, r16.xyzx, l(127, 127, 127, 0) + ubfe r19.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r16.xyzx + firstbit_hi r20.xyz, r18.xyzx + iadd r20.xyz, r20.xyzx, l(-24, -24, -24, 0) + movc r20.xyz, r18.xyzx, r20.xyzx, l(8,8,8,0) + iadd r21.xyz, -r20.xyzx, l(1, 1, 1, 0) + movc r21.xyz, r19.xyzx, r19.xyzx, r21.xyzx + bfi r16.xyz, l(7, 7, 7, 0), r20.xyzx, r16.xyzx, l(0, 0, 0, 0) + and r16.xyz, r16.xyzx, l(127, 127, 127, 0) + movc r16.xyz, r19.xyzx, r18.xyzx, r16.xyzx + ishl r18.xyz, r21.xyzx, l(23, 23, 23, 0) + iadd r18.xyz, r18.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r16.xyz, r16.xyzx, l(16, 16, 16, 0) + iadd r16.xyz, r18.xyzx, r16.xyzx + movc r10.xyz, r17.xyzx, r16.xyzx, l(0,0,0,0) + mov r15.x, r11.w + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r14.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + ushr r15.xyzw, r11.wxxx, l(30, 10, 20, 30) + utof r13.zw, r15.xxxw + mov r15.x, r11.x + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r11.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + mul r13.xyzw, r13.xyzw, l(0.333333, 0.333333, 0.333333, 0.333333) + mov r12.w, r13.x + mov r10.w, r13.y + mov r14.w, r13.z + mov r11.w, r13.w + break + case l(4) + ishl r13.xyzw, r11.yzwx, l(16, 16, 16, 16) + mov r15.xz, r13.xxyx + mov r15.yw, r11.yyyz + ishr r15.xyzw, r15.xyzw, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r12.xy, r15.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r10.xy, r15.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r11.yz, r13.zzwz + ishr r13.xyzw, r11.ywzx, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xy, r13.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r11.xy, r13.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r12.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + break + case l(6) + ushr r13.xyzw, r11.yzwx, l(16, 16, 16, 16) + f16tof32 r12.x, r11.y + f16tof32 r12.y, r13.x + f16tof32 r10.x, r11.z + f16tof32 r10.y, r13.y + f16tof32 r14.x, r11.w + f16tof32 r14.y, r13.z + f16tof32 r11.x, r11.x + f16tof32 r11.y, r13.w + mov r12.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + break + default + mov r12.x, r11.y + mov r12.yzw, l(0,0,0,0) + mov r10.x, r11.z + mov r10.yzw, l(0,0,0,0) + mov r14.x, r11.w + mov r14.yzw, l(0,0,0,0) + mov r11.yzw, l(0,0,0,0) + break + endswitch + endif + add r8.xyzw, r8.xyzw, r12.xyzw + add r6.xyzw, r6.xyzw, r10.xyzw + add r9.xyzw, r9.xyzw, r14.xyzw + add r7.xyzw, r7.xyzw, r11.xyzw + uge r5.z, r5.z, l(6) + if_nz r5.z + ishl r5.z, l(1), r4.w + mul r1.w, r1.w, l(0.250000) + iadd r0.x, r0.x, r5.z + if_nz r4.w + ieq r5.w, r1.y, l(2) + if_nz r5.w + ishl r5.w, r0.x, l(2) + ld_raw r10.xyzw, r5.w, T0[0].zwxy + iadd r5.w, r5.w, l(16) + ld_raw r11.xyzw, r5.w, T0[0].zwxy + mov r12.xy, r10.zwzz + mov r14.xy, r11.zwzz + else + ishl r5.w, r0.x, l(2) + ld_raw r12.xy, r5.w, T0[0].xyxx + iadd r5.w, r1.y, r0.x + ishl r5.w, r5.w, l(2) + ld_raw r10.xy, r5.w, T0[0].xyxx + ishl r13.xy, l(2, 3, 0, 0), r1.xxxx + iadd r13.xy, r0.xxxx, r13.xyxx + ishl r13.xy, r13.xyxx, l(2, 2, 0, 0) + ld_raw r14.xy, r13.x, T0[0].xyxx + ld_raw r11.xy, r13.y, T0[0].xyxx + endif + switch r4.z + case l(5) + ishl r12.zw, r12.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r12.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r12.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r10.zw, r10.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r10.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r10.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r14.zw, r14.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r14.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r11.zw, r11.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r11.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r11.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r13.xy, r12.xyxx, l(16, 16, 0, 0) + f16tof32 r12.xz, r12.xxyx + f16tof32 r12.yw, r13.xxxy + ushr r13.xy, r10.xyxx, l(16, 16, 0, 0) + f16tof32 r10.xz, r10.xxyx + f16tof32 r10.yw, r13.xxxy + ushr r13.xy, r14.xyxx, l(16, 16, 0, 0) + f16tof32 r14.xz, r14.xxyx + f16tof32 r14.yw, r13.xxxy + ushr r13.xy, r11.xyxx, l(16, 16, 0, 0) + f16tof32 r11.xz, r11.xxyx + f16tof32 r11.yw, r13.xxxy + break + default + mov r12.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + break + endswitch + else + ieq r5.w, r1.y, l(1) + if_nz r5.w + ishl r5.w, r0.x, l(2) + ld_raw r11.xyzw, r5.w, T0[0].wxyz + else + ishl r5.w, r0.x, l(2) + ld_raw r11.y, r5.w, T0[0].xxxx + iadd r5.w, r1.y, r0.x + ishl r5.w, r5.w, l(2) + ld_raw r11.z, r5.w, T0[0].xxxx + ishl r13.xy, l(2, 3, 0, 0), r1.xxxx + iadd r13.xy, r0.xxxx, r13.xyxx + ishl r13.xy, r13.xyxx, l(2, 2, 0, 0) + ld_raw r11.w, r13.x, T0[0].xxxx + ld_raw r11.x, r13.y, T0[0].xxxx + endif + switch r4.z + case l(0) + case l(1) + ushr r13.yzw, r11.yyyy, l(0, 8, 16, 24) + mov r13.x, r11.y + and r13.xyzw, r13.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r12.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r13.yzw, r11.zzzz, l(0, 8, 16, 24) + mov r13.x, r11.z + and r13.xyzw, r13.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r10.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r13.yzw, r11.wwww, l(0, 8, 16, 24) + mov r13.x, r11.w + and r13.xyzw, r13.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r14.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r11.yzw, r11.xxxx, l(0, 8, 16, 24) + and r13.xyzw, r11.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r11.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r13.yzw, r11.yyyy, l(0, 10, 20, 30) + mov r13.x, r11.y + and r13.xyzw, r13.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r12.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r13.yzw, r11.zzzz, l(0, 10, 20, 30) + mov r13.x, r11.z + and r13.xyzw, r13.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r10.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r13.yzw, r11.wwww, l(0, 10, 20, 30) + mov r13.x, r11.w + and r13.xyzw, r13.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r14.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r11.yzw, r11.xxxx, l(0, 10, 20, 30) + and r13.xyzw, r11.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r11.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r13.xyzw, r11.yyyz, l(10, 20, 30, 30) + mov r15.x, r11.y + mov r15.yz, r13.xxyx + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r12.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + utof r13.xy, r13.zwzz + ushr r15.xyzw, r11.zwwz, l(10, 10, 20, 20) + mov r16.x, r11.z + mov r16.yz, r15.xxwx + and r17.xyz, r16.xyzx, l(1023, 1023, 1023, 0) + and r18.xyz, r16.xyzx, l(127, 127, 127, 0) + ubfe r19.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r16.xyzx + firstbit_hi r20.xyz, r18.xyzx + iadd r20.xyz, r20.xyzx, l(-24, -24, -24, 0) + movc r20.xyz, r18.xyzx, r20.xyzx, l(8,8,8,0) + iadd r21.xyz, -r20.xyzx, l(1, 1, 1, 0) + movc r21.xyz, r19.xyzx, r19.xyzx, r21.xyzx + bfi r16.xyz, l(7, 7, 7, 0), r20.xyzx, r16.xyzx, l(0, 0, 0, 0) + and r16.xyz, r16.xyzx, l(127, 127, 127, 0) + movc r16.xyz, r19.xyzx, r18.xyzx, r16.xyzx + ishl r18.xyz, r21.xyzx, l(23, 23, 23, 0) + iadd r18.xyz, r18.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r16.xyz, r16.xyzx, l(16, 16, 16, 0) + iadd r16.xyz, r18.xyzx, r16.xyzx + movc r10.xyz, r17.xyzx, r16.xyzx, l(0,0,0,0) + mov r15.x, r11.w + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r14.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + ushr r15.xyzw, r11.wxxx, l(30, 10, 20, 30) + utof r13.zw, r15.xxxw + mov r15.x, r11.x + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r11.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + mul r13.xyzw, r13.xyzw, l(0.333333, 0.333333, 0.333333, 0.333333) + mov r12.w, r13.x + mov r10.w, r13.y + mov r14.w, r13.z + mov r11.w, r13.w + break + case l(4) + ishl r13.xyzw, r11.yzwx, l(16, 16, 16, 16) + mov r15.xz, r13.xxyx + mov r15.yw, r11.yyyz + ishr r15.xyzw, r15.xyzw, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r12.xy, r15.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r10.xy, r15.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r11.yz, r13.zzwz + ishr r13.xyzw, r11.ywzx, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xy, r13.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r11.xy, r13.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r12.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + break + case l(6) + ushr r13.xyzw, r11.yzwx, l(16, 16, 16, 16) + f16tof32 r12.x, r11.y + f16tof32 r12.y, r13.x + f16tof32 r10.x, r11.z + f16tof32 r10.y, r13.y + f16tof32 r14.x, r11.w + f16tof32 r14.y, r13.z + f16tof32 r11.x, r11.x + f16tof32 r11.y, r13.w + mov r12.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + break + default + mov r12.x, r11.y + mov r12.yzw, l(0,0,0,0) + mov r10.x, r11.z + mov r10.yzw, l(0,0,0,0) + mov r14.x, r11.w + mov r14.yzw, l(0,0,0,0) + mov r11.yzw, l(0,0,0,0) + break + endswitch + endif + add r12.xyzw, r8.xyzw, r12.xyzw + add r10.xyzw, r6.xyzw, r10.xyzw + add r13.xyzw, r9.xyzw, r14.xyzw + add r11.xyzw, r7.xyzw, r11.xyzw + iadd r0.x, r4.y, r5.z + if_nz r4.w + ieq r4.y, r1.y, l(2) + if_nz r4.y + ishl r4.y, r0.x, l(2) + ld_raw r14.xyzw, r4.y, T0[0].zwxy + iadd r4.y, r4.y, l(16) + ld_raw r15.xyzw, r4.y, T0[0].zwxy + mov r16.xy, r14.zwzz + mov r17.xy, r15.zwzz + else + ishl r4.y, r0.x, l(2) + ld_raw r16.xy, r4.y, T0[0].xyxx + iadd r4.y, r1.y, r0.x + ishl r4.y, r4.y, l(2) + ld_raw r14.xy, r4.y, T0[0].xyxx + ishl r4.yw, l(0, 2, 0, 3), r1.xxxx + iadd r4.yw, r0.xxxx, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r17.xy, r4.y, T0[0].xyxx + ld_raw r15.xy, r4.w, T0[0].xyxx + endif + switch r4.z + case l(5) + ishl r16.zw, r16.xxxy, l(0, 0, 16, 16) + ishr r18.xyzw, r16.zxwy, l(16, 16, 16, 16) + itof r18.xyzw, r18.xyzw + mul r18.xyzw, r18.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r16.xyzw, r18.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r14.zw, r14.xxxy, l(0, 0, 16, 16) + ishr r18.xyzw, r14.zxwy, l(16, 16, 16, 16) + itof r18.xyzw, r18.xyzw + mul r18.xyzw, r18.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xyzw, r18.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r17.zw, r17.xxxy, l(0, 0, 16, 16) + ishr r18.xyzw, r17.zxwy, l(16, 16, 16, 16) + itof r18.xyzw, r18.xyzw + mul r18.xyzw, r18.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r17.xyzw, r18.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r15.zw, r15.xxxy, l(0, 0, 16, 16) + ishr r18.xyzw, r15.zxwy, l(16, 16, 16, 16) + itof r18.xyzw, r18.xyzw + mul r18.xyzw, r18.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r15.xyzw, r18.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.yw, r16.xxxy, l(0, 16, 0, 16) + f16tof32 r16.xz, r16.xxyx + f16tof32 r16.yw, r4.yyyw + ushr r4.yw, r14.xxxy, l(0, 16, 0, 16) + f16tof32 r14.xz, r14.xxyx + f16tof32 r14.yw, r4.yyyw + ushr r4.yw, r17.xxxy, l(0, 16, 0, 16) + f16tof32 r17.xz, r17.xxyx + f16tof32 r17.yw, r4.yyyw + ushr r4.yw, r15.xxxy, l(0, 16, 0, 16) + f16tof32 r15.xz, r15.xxyx + f16tof32 r15.yw, r4.yyyw + break + default + mov r16.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r17.zw, l(0,0,0,0) + mov r15.zw, l(0,0,0,0) + break + endswitch + else + ieq r4.y, r1.y, l(1) + if_nz r4.y + ishl r4.y, r0.x, l(2) + ld_raw r15.xyzw, r4.y, T0[0].wxyz + else + ishl r4.y, r0.x, l(2) + ld_raw r15.y, r4.y, T0[0].xxxx + iadd r1.y, r1.y, r0.x + ishl r1.y, r1.y, l(2) + ld_raw r15.z, r1.y, T0[0].xxxx + ishl r1.xy, l(2, 3, 0, 0), r1.xxxx + iadd r1.xy, r0.xxxx, r1.xyxx + ishl r1.xy, r1.xyxx, l(2, 2, 0, 0) + ld_raw r15.w, r1.x, T0[0].xxxx + ld_raw r15.x, r1.y, T0[0].xxxx + endif + switch r4.z + case l(0) + case l(1) + ushr r18.yzw, r15.yyyy, l(0, 8, 16, 24) + mov r18.x, r15.y + and r18.xyzw, r18.xyzw, l(255, 255, 255, 255) + utof r18.xyzw, r18.xyzw + mul r16.xyzw, r18.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r18.yzw, r15.zzzz, l(0, 8, 16, 24) + mov r18.x, r15.z + and r18.xyzw, r18.xyzw, l(255, 255, 255, 255) + utof r18.xyzw, r18.xyzw + mul r14.xyzw, r18.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r18.yzw, r15.wwww, l(0, 8, 16, 24) + mov r18.x, r15.w + and r18.xyzw, r18.xyzw, l(255, 255, 255, 255) + utof r18.xyzw, r18.xyzw + mul r17.xyzw, r18.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r15.yzw, r15.xxxx, l(0, 8, 16, 24) + and r18.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r18.xyzw, r18.xyzw + mul r15.xyzw, r18.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r18.yzw, r15.yyyy, l(0, 10, 20, 30) + mov r18.x, r15.y + and r18.xyzw, r18.xyzw, l(1023, 1023, 1023, 3) + utof r18.xyzw, r18.xyzw + mul r16.xyzw, r18.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r18.yzw, r15.zzzz, l(0, 10, 20, 30) + mov r18.x, r15.z + and r18.xyzw, r18.xyzw, l(1023, 1023, 1023, 3) + utof r18.xyzw, r18.xyzw + mul r14.xyzw, r18.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r18.yzw, r15.wwww, l(0, 10, 20, 30) + mov r18.x, r15.w + and r18.xyzw, r18.xyzw, l(1023, 1023, 1023, 3) + utof r18.xyzw, r18.xyzw + mul r17.xyzw, r18.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r15.yzw, r15.xxxx, l(0, 10, 20, 30) + and r18.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r18.xyzw, r18.xyzw + mul r15.xyzw, r18.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r18.xyzw, r15.yyyz, l(10, 20, 30, 30) + mov r19.x, r15.y + mov r19.yz, r18.xxyx + and r4.yzw, r19.xxyz, l(0, 1023, 1023, 1023) + and r20.xyz, r19.xyzx, l(127, 127, 127, 0) + ubfe r21.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r19.xyzx + firstbit_hi r22.xyz, r20.xyzx + iadd r22.xyz, r22.xyzx, l(-24, -24, -24, 0) + movc r22.xyz, r20.xyzx, r22.xyzx, l(8,8,8,0) + iadd r23.xyz, -r22.xyzx, l(1, 1, 1, 0) + movc r23.xyz, r21.xyzx, r21.xyzx, r23.xyzx + bfi r19.xyz, l(7, 7, 7, 0), r22.xyzx, r19.xyzx, l(0, 0, 0, 0) + and r19.xyz, r19.xyzx, l(127, 127, 127, 0) + movc r19.xyz, r21.xyzx, r20.xyzx, r19.xyzx + ishl r20.xyz, r23.xyzx, l(23, 23, 23, 0) + iadd r20.xyz, r20.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r19.xyz, r19.xyzx, l(16, 16, 16, 0) + iadd r19.xyz, r20.xyzx, r19.xyzx + movc r16.xyz, r4.yzwy, r19.xyzx, l(0,0,0,0) + utof r1.xy, r18.zwzz + ushr r18.xyzw, r15.zwwz, l(10, 10, 20, 20) + mov r19.x, r15.z + mov r19.yz, r18.xxwx + and r4.yzw, r19.xxyz, l(0, 1023, 1023, 1023) + and r20.xyz, r19.xyzx, l(127, 127, 127, 0) + ubfe r21.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r19.xyzx + firstbit_hi r22.xyz, r20.xyzx + iadd r22.xyz, r22.xyzx, l(-24, -24, -24, 0) + movc r22.xyz, r20.xyzx, r22.xyzx, l(8,8,8,0) + iadd r23.xyz, -r22.xyzx, l(1, 1, 1, 0) + movc r23.xyz, r21.xyzx, r21.xyzx, r23.xyzx + bfi r19.xyz, l(7, 7, 7, 0), r22.xyzx, r19.xyzx, l(0, 0, 0, 0) + and r19.xyz, r19.xyzx, l(127, 127, 127, 0) + movc r19.xyz, r21.xyzx, r20.xyzx, r19.xyzx + ishl r20.xyz, r23.xyzx, l(23, 23, 23, 0) + iadd r20.xyz, r20.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r19.xyz, r19.xyzx, l(16, 16, 16, 0) + iadd r19.xyz, r20.xyzx, r19.xyzx + movc r14.xyz, r4.yzwy, r19.xyzx, l(0,0,0,0) + mul r1.xy, r1.xyxx, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r18.x, r15.w + and r4.yzw, r18.xxyz, l(0, 1023, 1023, 1023) + and r19.xyz, r18.xyzx, l(127, 127, 127, 0) + ubfe r20.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r18.xyzx + firstbit_hi r21.xyz, r19.xyzx + iadd r21.xyz, r21.xyzx, l(-24, -24, -24, 0) + movc r21.xyz, r19.xyzx, r21.xyzx, l(8,8,8,0) + iadd r22.xyz, -r21.xyzx, l(1, 1, 1, 0) + movc r22.xyz, r20.xyzx, r20.xyzx, r22.xyzx + bfi r18.xyz, l(7, 7, 7, 0), r21.xyzx, r18.xyzx, l(0, 0, 0, 0) + and r18.xyz, r18.xyzx, l(127, 127, 127, 0) + movc r18.xyz, r20.xyzx, r19.xyzx, r18.xyzx + ishl r19.xyz, r22.xyzx, l(23, 23, 23, 0) + iadd r19.xyz, r19.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r18.xyz, r18.xyzx, l(16, 16, 16, 0) + iadd r18.xyz, r19.xyzx, r18.xyzx + movc r17.xyz, r4.yzwy, r18.xyzx, l(0,0,0,0) + ushr r18.xyzw, r15.wxxx, l(30, 10, 20, 30) + utof r4.yz, r18.xxwx + mov r18.x, r15.x + and r19.xyz, r18.xyzx, l(1023, 1023, 1023, 0) + and r20.xyz, r18.xyzx, l(127, 127, 127, 0) + ubfe r21.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r18.xyzx + firstbit_hi r22.xyz, r20.xyzx + iadd r22.xyz, r22.xyzx, l(-24, -24, -24, 0) + movc r22.xyz, r20.xyzx, r22.xyzx, l(8,8,8,0) + iadd r23.xyz, -r22.xyzx, l(1, 1, 1, 0) + movc r23.xyz, r21.xyzx, r21.xyzx, r23.xyzx + bfi r18.xyz, l(7, 7, 7, 0), r22.xyzx, r18.xyzx, l(0, 0, 0, 0) + and r18.xyz, r18.xyzx, l(127, 127, 127, 0) + movc r18.xyz, r21.xyzx, r20.xyzx, r18.xyzx + ishl r20.xyz, r23.xyzx, l(23, 23, 23, 0) + iadd r20.xyz, r20.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r18.xyz, r18.xyzx, l(16, 16, 16, 0) + iadd r18.xyz, r20.xyzx, r18.xyzx + movc r15.xyz, r19.xyzx, r18.xyzx, l(0,0,0,0) + mul r4.yz, r4.yyzy, l(0.000000, 0.333333, 0.333333, 0.000000) + mov r16.w, r1.x + mov r14.w, r1.y + mov r17.w, r4.y + mov r15.w, r4.z + break + case l(4) + ishl r18.xyzw, r15.yzwx, l(16, 16, 16, 16) + mov r19.xz, r18.xxyx + mov r19.yw, r15.yyyz + ishr r19.xyzw, r19.xyzw, l(16, 16, 16, 16) + itof r19.xyzw, r19.xyzw + mul r19.xyzw, r19.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r16.xy, r19.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r14.xy, r19.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r15.yz, r18.zzwz + ishr r18.xyzw, r15.ywzx, l(16, 16, 16, 16) + itof r18.xyzw, r18.xyzw + mul r18.xyzw, r18.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r17.xy, r18.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r15.xy, r18.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r16.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r17.zw, l(0,0,0,0) + mov r15.zw, l(0,0,0,0) + break + case l(6) + ushr r18.xyzw, r15.yzwx, l(16, 16, 16, 16) + f16tof32 r16.x, r15.y + f16tof32 r16.y, r18.x + f16tof32 r14.x, r15.z + f16tof32 r14.y, r18.y + f16tof32 r17.x, r15.w + f16tof32 r17.y, r18.z + f16tof32 r15.x, r15.x + f16tof32 r15.y, r18.w + mov r16.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r17.zw, l(0,0,0,0) + mov r15.zw, l(0,0,0,0) + break + default + mov r16.x, r15.y + mov r16.yzw, l(0,0,0,0) + mov r14.x, r15.z + mov r14.yzw, l(0,0,0,0) + mov r17.x, r15.w + mov r17.yzw, l(0,0,0,0) + mov r15.yzw, l(0,0,0,0) + break + endswitch + endif + add r8.xyzw, r12.xyzw, r16.xyzw + add r6.xyzw, r10.xyzw, r14.xyzw + add r9.xyzw, r13.xyzw, r17.xyzw + add r7.xyzw, r11.xyzw, r15.xyzw + else + mov r1.w, r4.x + endif +endif +mul r4.xyzw, r1.wwww, r8.xyzw +mul r6.xyzw, r1.wwww, r6.xyzw +mul r8.xyzw, r1.wwww, r9.xyzw +mul r7.xyzw, r1.wwww, r7.xyzw +if_nz r0.w + mov r4.xz, r4.zzxz + mov r6.xz, r6.zzxz + mov r8.xz, r8.zzxz + mov r9.xz, r7.zzxz +else + mov r9.xz, r7.xxzx +endif +switch r5.y + case l(6) + case l(14) + case l(50) + mov_sat r4.xyzw, r4.xyzw + mad r10.xyzw, r4.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r10.xyzw, r10.xyzw + imad r0.x, r10.y, l(256), r10.x + imad r0.x, r10.z, l(0x00010000), r0.x + imad r10.x, r10.w, l(0x01000000), r0.x + mov_sat r6.xyzw, r6.xyzw + mad r11.xyzw, r6.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r11.xyzw, r11.xyzw + imad r0.x, r11.y, l(256), r11.x + imad r0.x, r11.z, l(0x00010000), r0.x + imad r10.y, r11.w, l(0x01000000), r0.x + mov_sat r8.xyzw, r8.xyzw + mad r11.xyzw, r8.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r11.xyzw, r11.xyzw + imad r0.x, r11.y, l(256), r11.x + imad r0.x, r11.z, l(0x00010000), r0.x + imad r10.z, r11.w, l(0x01000000), r0.x + mov r9.yw, r7.yyyw + mov_sat r9.xyzw, r9.xyzw + mad r11.xyzw, r9.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r11.xyzw, r11.xyzw + imad r0.x, r11.y, l(256), r11.x + imad r0.x, r11.z, l(0x00010000), r0.x + imad r10.w, r11.w, l(0x01000000), r0.x + mov r9.xyzw, r10.wyxz + break + case l(7) + case l(54) + mov_sat r4.xyzw, r4.xyzw + mad r10.xyzw, r4.xyzw, l(1023.000000, 1023.000000, 1023.000000, 3.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r10.xyzw, r10.xyzw + imad r0.x, r10.y, l(1024), r10.x + imad r0.x, r10.z, l(0x00100000), r0.x + imad r10.x, r10.w, l(0x40000000), r0.x + mov_sat r6.xyzw, r6.xyzw + mad r11.xyzw, r6.xyzw, l(1023.000000, 1023.000000, 1023.000000, 3.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r11.xyzw, r11.xyzw + imad r0.x, r11.y, l(1024), r11.x + imad r0.x, r11.z, l(0x00100000), r0.x + imad r10.y, r11.w, l(0x40000000), r0.x + mov_sat r8.xyzw, r8.xyzw + mad r11.xyzw, r8.xyzw, l(1023.000000, 1023.000000, 1023.000000, 3.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r11.xyzw, r11.xyzw + imad r0.x, r11.y, l(1024), r11.x + imad r0.x, r11.z, l(0x00100000), r0.x + imad r10.z, r11.w, l(0x40000000), r0.x + mov_sat r7.xz, r9.xxzx + mov_sat r7.yw, r7.yyyw + mad r11.xyzw, r7.xyzw, l(1023.000000, 1023.000000, 1023.000000, 3.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r11.xyzw, r11.xyzw + imad r0.x, r11.y, l(1024), r11.x + imad r0.x, r11.z, l(0x00100000), r0.x + imad r10.w, r11.w, l(0x40000000), r0.x + mov r9.xyzw, r10.wyxz + break + case l(16) + case l(55) + mov_sat r4.xyz, r4.xyzx + mad r1.xyw, r4.xyxz, l(2047.000000, 2047.000000, 0.000000, 1023.000000), l(0.500000, 0.500000, 0.000000, 0.500000) + ftou r1.xyw, r1.xyxw + imad r0.x, r1.y, l(2048), r1.x + imad r10.x, r1.w, l(0x00400000), r0.x + mov_sat r6.xyz, r6.xyzx + mad r1.xyw, r6.xyxz, l(2047.000000, 2047.000000, 0.000000, 1023.000000), l(0.500000, 0.500000, 0.000000, 0.500000) + ftou r1.xyw, r1.xyxw + imad r0.x, r1.y, l(2048), r1.x + imad r10.y, r1.w, l(0x00400000), r0.x + mov_sat r8.xyz, r8.xyzx + mad r1.xyw, r8.xyxz, l(2047.000000, 2047.000000, 0.000000, 1023.000000), l(0.500000, 0.500000, 0.000000, 0.500000) + ftou r1.xyw, r1.xyxw + imad r0.x, r1.y, l(2048), r1.x + imad r10.z, r1.w, l(0x00400000), r0.x + mov_sat r7.xz, r9.xxzx + mov_sat r7.y, r7.y + mad r1.xyw, r7.xyxz, l(2047.000000, 2047.000000, 0.000000, 1023.000000), l(0.500000, 0.500000, 0.000000, 0.500000) + ftou r1.xyw, r1.xyxw + imad r0.x, r1.y, l(2048), r1.x + imad r10.w, r1.w, l(0x00400000), r0.x + mov r9.xyzw, r10.wyxz + break + case l(17) + case l(56) + mov_sat r4.xyz, r4.xyzx + mad r1.xyw, r4.xyxz, l(1023.000000, 2047.000000, 0.000000, 2047.000000), l(0.500000, 0.500000, 0.000000, 0.500000) + ftou r1.xyw, r1.xyxw + imad r0.x, r1.y, l(1024), r1.x + imad r10.x, r1.w, l(0x00200000), r0.x + mov_sat r6.xyz, r6.xyzx + mad r1.xyw, r6.xyxz, l(1023.000000, 2047.000000, 0.000000, 2047.000000), l(0.500000, 0.500000, 0.000000, 0.500000) + ftou r1.xyw, r1.xyxw + imad r0.x, r1.y, l(1024), r1.x + imad r10.y, r1.w, l(0x00200000), r0.x + mov_sat r8.xyz, r8.xyzx + mad r1.xyw, r8.xyxz, l(1023.000000, 2047.000000, 0.000000, 2047.000000), l(0.500000, 0.500000, 0.000000, 0.500000) + ftou r1.xyw, r1.xyxw + imad r0.x, r1.y, l(1024), r1.x + imad r10.z, r1.w, l(0x00200000), r0.x + mov_sat r7.xz, r9.xxzx + mov_sat r7.y, r7.y + mad r1.xyw, r7.xyxz, l(1023.000000, 2047.000000, 0.000000, 2047.000000), l(0.500000, 0.500000, 0.000000, 0.500000) + ftou r1.xyw, r1.xyxw + imad r0.x, r1.y, l(1024), r1.x + imad r10.w, r1.w, l(0x00200000), r0.x + mov r9.xyzw, r10.wyxz + break + case l(25) + mov_sat r4.xy, r4.xyxx + mad r0.xw, r4.xxxy, l(65535.000000, 0.000000, 0.000000, 65535.000000), l(0.500000, 0.000000, 0.000000, 0.500000) + ftou r0.xw, r0.xxxw + imad r9.z, r0.w, l(0x00010000), r0.x + mov_sat r6.xy, r6.xyxx + mad r0.xw, r6.xxxy, l(65535.000000, 0.000000, 0.000000, 65535.000000), l(0.500000, 0.000000, 0.000000, 0.500000) + ftou r0.xw, r0.xxxw + imad r9.y, r0.w, l(0x00010000), r0.x + mov_sat r8.xy, r8.xyxx + mad r0.xw, r8.xxxy, l(65535.000000, 0.000000, 0.000000, 65535.000000), l(0.500000, 0.000000, 0.000000, 0.500000) + ftou r0.xw, r0.xxxw + imad r9.w, r0.w, l(0x00010000), r0.x + mov_sat r7.x, r9.x + mov_sat r7.y, r7.y + mad r0.xw, r7.xxxy, l(65535.000000, 0.000000, 0.000000, 65535.000000), l(0.500000, 0.000000, 0.000000, 0.500000) + ftou r0.xw, r0.xxxw + imad r9.x, r0.w, l(0x00010000), r0.x + break + case l(31) + f32tof16 r0.xw, r4.xxxy + imad r9.z, r0.w, l(0x00010000), r0.x + f32tof16 r0.xw, r6.xxxy + imad r9.y, r0.w, l(0x00010000), r0.x + f32tof16 r0.xw, r8.xxxy + imad r9.w, r0.w, l(0x00010000), r0.x + f32tof16 r0.x, r9.x + f32tof16 r0.w, r7.y + imad r9.x, r0.w, l(0x00010000), r0.x + break + default + mov r9.z, r4.x + mov r9.y, r6.x + mov r9.w, r8.x + break +endswitch +iadd r2.xyzw, r2.xyzw, r3.xyzw +if_nz r0.z + ubfe r0.x, l(3), l(4), CB0[0][0].z + ishl r0.z, r1.z, l(5) + ishr r1.xyzw, r2.zwzw, l(4, 5, 3, 3) + ishr r0.w, r0.x, l(2) + ushr r0.z, r0.z, l(4) + and r0.z, r0.z, l(2046) + imad r0.z, r0.w, r0.z, r1.x + ushr r1.x, r5.x, l(5) + imad r0.z, r0.z, r1.x, r1.y + ishl r1.x, r2.z, l(10) + and r1.x, r1.x, l(6144) + bfi r1.x, l(3), l(8), r2.w, r1.x + ishr r1.x, r1.x, l(6) + iadd r0.w, r0.w, r1.z + bfi r1.y, l(1), l(1), r0.w, l(0) + iadd r1.y, r1.y, r1.w + bfi r1.y, l(2), l(1), r1.y, l(0) + bfi r0.w, l(1), l(0), r0.w, r1.y + bfi r1.yz, l(0, 20, 20, 0), l(0, 10, 13, 0), r0.zzzz, l(0, 0, 0, 0) + imad r1.xy, r1.xxxx, l(2, 16, 0, 0), r1.yzyy + bfi r0.xz, l(2, 0, 2, 0), l(8, 0, 11, 0), r0.xxxx, r1.xxyx + bfi r1.x, l(1), l(4), r2.z, l(0) + ubfe r1.y, l(3), l(6), r0.x + and r1.z, r0.w, l(6) + bfi r0.w, l(1), l(8), r0.w, l(0) + imad r0.w, r1.y, l(32), r0.w + imad r0.w, r1.z, l(4), r0.w + bfi r0.xz, l(5, 0, 5, 0), l(0, 0, 3, 0), r1.xxxx, r0.xxzx + bfi r0.z, l(9), l(3), r0.w, r0.z + bfi r0.x, l(6), l(0), r0.x, r0.z +else + ishr r1.xyzw, r2.xyzw, l(5, 5, 2, 3) + ushr r0.z, r5.x, l(5) + imad r0.z, r1.y, r0.z, r1.x + ishl r1.xy, r2.zzzz, l(5, 7, 0, 0) + and r1.xy, r1.xyxx, l(448, 2048, 0, 0) + bfi r0.w, l(3), l(3), r2.w, r1.x + bfi r0.w, l(23), l(9), r0.z, r0.w + bfi r2.x, l(1), l(4), r2.z, l(0) + iadd r0.w, r0.w, r2.x + ishl r2.yz, r1.xxxx, l(0, 3, 2, 0) + bfi r2.yz, l(0, 3, 3, 0), l(0, 6, 5, 0), r2.wwww, r2.yyzy + bfi r2.yz, l(0, 23, 23, 0), l(0, 12, 11, 0), r0.zzzz, r2.yyzy + imad r2.xy, r2.xxxx, l(8, 4, 0, 0), r2.yzyy + bfi r0.z, l(12), l(0), r1.y, r2.x + and r1.x, r2.y, l(1792) + iadd r0.z, r0.z, r1.x + and r1.x, r1.z, l(2) + iadd r1.x, r1.w, r1.x + bfi r1.x, l(2), l(6), r1.x, l(0) + iadd r0.z, r0.z, r1.x + bfi r0.x, l(6), l(0), r0.w, r0.z +endif +iadd r0.x, r0.x, CB0[0][1].x +ushr r0.x, r0.x, l(4) +ieq r0.yzw, r0.yyyy, l(0, 1, 2, 3) +or r0.yz, r0.zzwz, r0.yyzy +if_nz r0.y + ishl r1.xyzw, r9.zywx, l(8, 8, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r2.xyzw, r9.zywx, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r9.xyzw, r1.wyxz, r2.wyxz +endif +if_nz r0.z + ushr r1.xyzw, r9.zywx, l(16, 16, 16, 16) + bfi r9.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r9.xyzw, r1.wyxz +endif +store_uav_typed U0[0].xyzw, r0.xxxx, r9.zywx +ret +// Approximately 1331 instruction slots used +#endif + +const BYTE resolve_full_32bpp_cs[] = { + 68, 88, 66, 67, 78, 239, 227, 61, 252, 23, 41, 118, 58, 9, 111, 175, 37, 217, 27, + 212, 1, 0, 0, 0, 120, 161, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 208, 2, + 0, 0, 224, 2, 0, 0, 240, 2, 0, 0, 220, 160, 0, 0, 82, 68, 69, 70, 148, + 2, 0, 0, 1, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 105, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 101, 100, 114, 97, 109, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 213, 0, 0, 0, 5, 0, 0, 0, 252, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 196, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 4, 2, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 31, 2, 0, 0, 8, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 52, 2, 0, 0, 12, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 84, 2, 0, + 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, + 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 101, 100, 114, 97, 109, 95, 105, 110, 102, + 111, 0, 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 218, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 99, 111, + 111, 114, 100, 105, 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 105, 110, 102, 111, 0, 120, 101, 95, + 114, 101, 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 99, 111, 111, 114, 100, 105, + 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 95, 98, 97, 115, 101, 0, 77, 105, 99, 114, 111, 115, 111, + 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, + 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, + 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 228, 157, 0, 0, + 81, 0, 5, 0, 121, 39, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 161, 0, 0, 6, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 95, 0, 0, + 2, 50, 0, 2, 0, 104, 0, 0, 2, 24, 0, 0, 0, 155, 0, 0, 4, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, 242, 0, 16, 0, 0, + 0, 0, 0, 134, 138, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 255, 3, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 1, 85, 0, 0, 12, 114, 0, 16, 0, 1, 0, 0, 0, 86, 135, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, + 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, 242, 0, 16, 0, + 2, 0, 0, 0, 246, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 20, 0, + 0, 0, 41, 0, 0, 9, 146, 0, 16, 0, 3, 0, 0, 0, 6, 0, 2, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, + 26, 0, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 17, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 11, 0, + 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 13, + 0, 0, 0, 24, 0, 0, 0, 28, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, + 0, 20, 50, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 15, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 139, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 128, 63, 140, 0, 0, 13, 18, 0, 16, 0, 5, 0, 0, 0, + 1, 64, 0, 0, 10, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 58, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, + 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 138, 0, 0, 17, 98, 0, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, + 0, 166, 139, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 4, 98, 0, 16, 0, 3, 0, 0, 0, 86, 5, 2, 0, 30, 0, 0, 7, 50, + 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 182, 15, 16, 0, + 3, 0, 0, 0, 80, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 58, 0, + 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 42, + 0, 16, 0, 5, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, 0, + 5, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, + 0, 31, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 34, 0, + 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 18, 0, 0, 1, 54, + 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 1, 21, 0, 0, 1, 80, 0, 0, 10, 194, 0, 16, 0, 6, 0, 0, + 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 6, + 0, 0, 0, 166, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 50, 0, 16, + 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 6, 0, + 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, + 6, 0, 0, 0, 70, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, + 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 6, + 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 80, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 78, 0, 0, 8, 50, 0, + 16, 0, 7, 0, 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 70, + 0, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 7, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 35, 0, 0, 10, 50, + 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 128, 65, 0, 0, 0, 7, 0, 0, 0, + 70, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, + 9, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 5, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 78, 0, 0, 8, 0, 208, 0, 0, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 40, 0, 30, 0, 0, 7, + 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, + 0, 16, 0, 4, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 242, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, + 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, + 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, + 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 4, + 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 50, 0, 16, 0, 8, 0, 0, 0, 230, 10, 16, 0, 6, 0, 0, 0, 54, 0, 0, + 5, 50, 0, 16, 0, 9, 0, 0, 0, 230, 10, 16, 0, 7, 0, 0, 0, 18, 0, + 0, 1, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, + 8, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, + 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, + 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, + 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, + 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 4, 0, + 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, + 9, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 7, 0, 0, 0, 26, 0, + 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, + 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, + 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 8, 0, 0, + 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 10, + 0, 0, 0, 38, 7, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, + 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, + 0, 10, 194, 0, 16, 0, 6, 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 42, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 38, 7, 16, 0, 6, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 9, 0, 0, 0, + 6, 4, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 10, 0, + 0, 0, 38, 7, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, + 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, + 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, + 10, 194, 0, 16, 0, 7, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, + 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 38, 7, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, + 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 8, 0, 0, 0, 6, 1, + 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 8, 0, 0, 0, 6, + 4, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, + 70, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 6, 0, + 0, 0, 6, 1, 16, 0, 6, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 6, + 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, + 4, 0, 0, 0, 70, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, + 16, 0, 9, 0, 0, 0, 6, 1, 16, 0, 9, 0, 0, 0, 131, 0, 0, 5, 162, + 0, 16, 0, 9, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, + 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, + 0, 5, 82, 0, 16, 0, 7, 0, 0, 0, 6, 1, 16, 0, 7, 0, 0, 0, 131, + 0, 0, 5, 162, 0, 16, 0, 7, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, + 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 194, 0, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, + 194, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, + 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, + 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 7, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 18, 0, 0, 1, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 34, + 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, + 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, 7, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 41, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, + 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, + 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, + 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 7, 0, 0, + 0, 26, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, + 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, + 1, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, 86, 5, 16, + 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, + 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 26, + 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, + 0, 10, 0, 0, 0, 166, 10, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, + 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 85, 0, 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, 246, 15, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, + 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 7, 0, + 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, + 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, + 0, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, 86, + 5, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, + 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, + 0, 26, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 8, 32, + 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, + 0, 16, 0, 10, 0, 0, 0, 166, 10, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, + 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, 246, 15, 16, 0, + 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 58, 0, + 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 9, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, + 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, + 7, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 2, + 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, + 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, + 0, 86, 9, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 20, 0, + 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, + 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, + 11, 0, 0, 0, 6, 1, 16, 0, 10, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, + 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 15, 114, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, + 135, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, + 0, 30, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, + 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, + 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, + 16, 0, 16, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, + 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 114, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, + 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 11, 0, + 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 11, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, + 0, 70, 2, 16, 0, 11, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 13, 0, + 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, + 0, 11, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, + 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, + 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 10, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 10, 0, 0, 0, 230, 11, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, + 54, 0, 0, 5, 98, 0, 16, 0, 11, 0, 0, 0, 6, 3, 16, 0, 10, 0, 0, + 0, 1, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 14, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 11, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, + 0, 70, 2, 16, 0, 13, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 15, 0, + 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, + 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, + 15, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 128, 65, + 0, 0, 0, 15, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, + 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, + 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 41, 0, + 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, + 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 12, 114, 0, + 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 56, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 58, + 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, + 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 12, 0, + 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 135, 0, 0, 5, 114, + 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 30, 0, 0, 10, + 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, + 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, + 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, + 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 15, 0, 0, + 0, 70, 2, 16, 128, 65, 0, 0, 0, 14, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, + 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, + 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 10, 0, 0, 0, 70, + 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, + 10, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, + 0, 15, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, + 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, + 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, + 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 10, + 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, + 55, 0, 0, 12, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, + 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 10, + 0, 0, 0, 54, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, + 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 86, 0, 0, 5, 50, 0, 16, + 0, 11, 0, 0, 0, 198, 0, 16, 0, 10, 0, 0, 0, 54, 0, 0, 5, 18, 0, + 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, + 0, 0, 15, 114, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 10, 0, + 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 13, + 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, + 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, + 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, + 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 14, + 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, + 140, 0, 0, 17, 114, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, + 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, + 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 13, + 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, + 13, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, + 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, + 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, + 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, + 2, 16, 0, 10, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 7, 0, 0, 0, + 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, + 0, 10, 50, 0, 16, 0, 10, 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 130, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, + 0, 54, 0, 0, 5, 130, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 4, 0, + 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 10, + 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, + 10, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 150, 3, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 11, 0, 0, 0, 6, 1, 16, 0, + 10, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 11, 0, 0, 0, 86, 9, 16, + 0, 7, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, + 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, + 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, + 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 8, + 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, + 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, + 0, 6, 0, 0, 0, 230, 10, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 98, + 0, 16, 0, 7, 0, 0, 0, 166, 11, 16, 0, 10, 0, 0, 0, 42, 0, 0, 10, + 242, 0, 16, 0, 10, 0, 0, 0, 214, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, + 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, + 58, 52, 0, 0, 10, 50, 0, 16, 0, 9, 0, 0, 0, 70, 0, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, + 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 7, 0, 0, 0, 230, 10, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 8, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 10, 0, 0, 0, 150, 3, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, + 0, 0, 5, 18, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, + 131, 0, 0, 5, 34, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, + 0, 131, 0, 0, 5, 18, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 7, 0, + 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 10, + 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, + 7, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, + 0, 10, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, + 16, 0, 7, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 7, 0, 0, 0, 58, + 0, 16, 0, 10, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, + 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 8, + 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 6, 0, 0, 0, 42, 0, + 16, 0, 7, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, + 0, 54, 0, 0, 8, 226, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 226, + 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, + 1, 80, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 5, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, + 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 30, 0, 0, 7, 34, 0, 16, + 0, 4, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 80, 0, + 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 4, 0, 0, 0, 32, 0, 0, 7, 130, + 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 10, 0, 0, 0, 58, + 0, 16, 0, 5, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, + 0, 1, 64, 0, 0, 16, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 11, 0, + 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 12, 0, 0, 0, 230, 10, 16, 0, + 10, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 14, 0, 0, 0, 230, 10, 16, + 0, 11, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, + 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 50, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, + 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 4, 0, + 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, + 10, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 13, 0, 0, 0, + 86, 5, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, 41, 0, 0, + 10, 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, + 0, 0, 8, 50, 0, 16, 0, 14, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, + 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, + 0, 11, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 70, 112, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, + 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, + 194, 0, 16, 0, 12, 0, 0, 0, 6, 4, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, + 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 38, 7, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 43, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, + 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 10, 0, 0, 0, 6, 4, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, + 38, 7, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 13, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, + 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, + 0, 16, 0, 14, 0, 0, 0, 6, 4, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, + 10, 242, 0, 16, 0, 13, 0, 0, 0, 38, 7, 16, 0, 14, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, + 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, + 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, + 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 11, 0, 0, 0, 6, 4, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 38, + 7, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, + 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, + 11, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, + 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 13, + 0, 0, 0, 70, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, + 0, 12, 0, 0, 0, 6, 1, 16, 0, 12, 0, 0, 0, 131, 0, 0, 5, 162, 0, + 16, 0, 12, 0, 0, 0, 6, 4, 16, 0, 13, 0, 0, 0, 85, 0, 0, 10, 50, + 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, + 5, 82, 0, 16, 0, 10, 0, 0, 0, 6, 1, 16, 0, 10, 0, 0, 0, 131, 0, + 0, 5, 162, 0, 16, 0, 10, 0, 0, 0, 6, 4, 16, 0, 13, 0, 0, 0, 85, + 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 14, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 131, 0, 0, 5, 82, 0, 16, 0, 14, 0, 0, 0, 6, 1, 16, 0, 14, 0, + 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 14, 0, 0, 0, 6, 4, 16, 0, 13, + 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 11, 0, 0, 0, 6, 1, + 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 11, 0, 0, 0, 6, + 4, 16, 0, 13, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, + 194, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 18, + 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, + 0, 5, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, + 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, + 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 54, 121, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, + 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 5, + 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 4, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, + 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, + 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, + 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 13, + 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, + 41, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, + 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 13, + 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, + 18, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 6, 112, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, + 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, + 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, + 13, 0, 0, 0, 86, 5, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, + 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, + 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, + 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, + 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, 0, 166, 10, 16, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, + 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 42, 0, 16, 0, 11, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, + 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, + 0, 246, 15, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, + 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, + 10, 226, 0, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, + 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, + 16, 0, 13, 0, 0, 0, 86, 5, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, + 18, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, + 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, + 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, 0, 166, 10, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, + 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 42, 0, 16, + 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, + 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, + 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, + 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 13, + 0, 0, 0, 246, 15, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 13, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, + 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, + 0, 0, 10, 226, 0, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, + 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 13, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, + 128, 58, 171, 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, + 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 13, 0, 0, 0, 86, 9, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 54, + 0, 0, 5, 98, 0, 16, 0, 15, 0, 0, 0, 6, 1, 16, 0, 13, 0, 0, 0, + 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 15, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 17, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, + 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, + 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 11, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, + 0, 0, 19, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, + 0, 20, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, + 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 0, 41, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, + 0, 12, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 86, 0, 0, 5, 50, 0, 16, 0, 13, 0, 0, 0, 230, 10, 16, 0, + 13, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 230, 11, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 16, 0, 0, 0, 42, + 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 16, 0, 0, 0, + 6, 3, 16, 0, 15, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 18, + 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, + 0, 19, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 135, 0, 0, 5, + 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 30, 0, 0, + 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, + 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, + 0, 0, 12, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 21, 0, + 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 20, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, + 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, + 0, 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 140, 0, 0, 17, 114, 0, + 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, + 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, + 0, 16, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, + 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 16, 0, + 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, + 16, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, + 0, 55, 0, 0, 12, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 17, 0, + 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, + 15, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, + 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, + 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, + 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, + 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, + 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, 0, + 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, 0, + 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, 0, + 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, + 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 15, 0, 0, 0, 54, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 30, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 86, 0, + 0, 5, 194, 0, 16, 0, 13, 0, 0, 0, 6, 12, 16, 0, 15, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, + 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 15, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 17, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, + 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, + 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 11, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, + 0, 0, 19, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, + 0, 20, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, + 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 0, 41, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, + 0, 11, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, 171, 170, 170, + 62, 171, 170, 170, 62, 54, 0, 0, 5, 130, 0, 16, 0, 12, 0, 0, 0, 10, 0, + 16, 0, 13, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 10, 0, 0, 0, 26, + 0, 16, 0, 13, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 14, 0, 0, 0, + 42, 0, 16, 0, 13, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 11, 0, 0, + 0, 58, 0, 16, 0, 13, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, + 0, 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 150, + 3, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 15, 0, 0, + 0, 6, 1, 16, 0, 13, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 15, 0, + 0, 0, 86, 9, 16, 0, 11, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, + 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, + 50, 0, 16, 0, 12, 0, 0, 0, 70, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, + 0, 10, 50, 0, 16, 0, 10, 0, 0, 0, 230, 10, 16, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 98, 0, 16, 0, 11, 0, 0, 0, 166, 11, 16, 0, 13, 0, 0, + 0, 42, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 214, 2, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, + 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, + 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 14, 0, 0, 0, 70, + 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, + 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 11, 0, 0, + 0, 230, 10, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 150, 3, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, + 0, 11, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 12, 0, 0, 0, 10, 0, + 16, 0, 13, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 42, + 0, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 10, 0, 0, 0, + 26, 0, 16, 0, 13, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, + 0, 58, 0, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 14, 0, + 0, 0, 42, 0, 16, 0, 13, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 11, + 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, + 11, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 5, + 18, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, + 8, 226, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, + 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 58, 0, + 16, 0, 11, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 14, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 226, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, + 0, 1, 21, 0, 0, 1, 0, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 0, 0, 0, 7, + 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 0, 0, 0, 7, 242, + 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 80, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, + 0, 5, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 31, 0, 4, 3, 42, 0, + 16, 0, 5, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 56, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 128, 62, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 58, + 0, 16, 0, 4, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, + 3, 58, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 242, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, + 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 16, 0, + 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 5, + 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 50, 0, 16, 0, 12, 0, 0, 0, 230, 10, 16, 0, 10, 0, 0, 0, 54, 0, 0, + 5, 50, 0, 16, 0, 14, 0, 0, 0, 230, 10, 16, 0, 11, 0, 0, 0, 18, 0, + 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, + 12, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, + 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, + 0, 5, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, + 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, + 30, 0, 0, 7, 50, 0, 16, 0, 13, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 13, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 13, 0, + 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, + 14, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 11, 0, 0, 0, 26, 0, + 16, 0, 13, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, + 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, + 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 12, 0, 0, + 0, 6, 4, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 13, + 0, 0, 0, 38, 7, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, + 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, + 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, + 0, 10, 194, 0, 16, 0, 10, 0, 0, 0, 6, 4, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 42, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 38, 7, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 14, 0, 0, 0, + 6, 4, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 13, 0, + 0, 0, 38, 7, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, + 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 1, + 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, + 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, + 10, 194, 0, 16, 0, 11, 0, 0, 0, 6, 4, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, + 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 38, 7, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 43, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, + 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 12, 0, 0, 0, 6, 1, + 16, 0, 12, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 12, 0, 0, 0, 6, + 4, 16, 0, 13, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, + 70, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 10, 0, + 0, 0, 6, 1, 16, 0, 10, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 10, + 0, 0, 0, 6, 4, 16, 0, 13, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, + 13, 0, 0, 0, 70, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, + 16, 0, 14, 0, 0, 0, 6, 1, 16, 0, 14, 0, 0, 0, 131, 0, 0, 5, 162, + 0, 16, 0, 14, 0, 0, 0, 6, 4, 16, 0, 13, 0, 0, 0, 85, 0, 0, 10, + 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, + 0, 5, 82, 0, 16, 0, 11, 0, 0, 0, 6, 1, 16, 0, 11, 0, 0, 0, 131, + 0, 0, 5, 162, 0, 16, 0, 11, 0, 0, 0, 6, 4, 16, 0, 13, 0, 0, 0, + 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, + 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, + 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, 41, 0, + 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 11, 0, 0, 0, + 58, 0, 16, 0, 5, 0, 0, 0, 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 34, + 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, + 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, 11, 0, 0, 0, + 58, 0, 16, 0, 5, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 41, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, + 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 13, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, + 0, 13, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, + 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 11, 0, 0, + 0, 26, 0, 16, 0, 13, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, + 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, + 1, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, 0, 86, 5, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, + 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 26, + 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, + 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 12, + 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, + 0, 13, 0, 0, 0, 166, 10, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, + 0, 16, 0, 13, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, + 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, 0, 246, 15, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, + 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, + 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, + 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, + 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 11, 0, + 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 13, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, + 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, + 0, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, 0, 86, + 5, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, + 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, + 0, 26, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, + 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 12, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 8, 32, + 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, + 0, 16, 0, 13, 0, 0, 0, 166, 10, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 13, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 13, 0, + 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, + 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, 0, 246, 15, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 58, 0, + 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, + 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, + 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 14, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, + 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, + 11, 0, 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, + 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 2, + 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, + 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, + 0, 86, 9, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 20, 0, + 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, + 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, + 15, 0, 0, 0, 6, 1, 16, 0, 13, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, + 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, + 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, + 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, + 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, + 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, 0, + 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, 0, + 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, 0, + 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, + 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, + 50, 0, 16, 0, 13, 0, 0, 0, 230, 10, 16, 0, 13, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 15, 0, 0, 0, 230, 11, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 16, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, + 54, 0, 0, 5, 98, 0, 16, 0, 16, 0, 0, 0, 6, 3, 16, 0, 15, 0, 0, + 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 19, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 16, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 20, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 20, 0, + 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, + 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, + 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 128, 65, + 0, 0, 0, 20, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 21, 0, 0, + 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, + 16, 0, 21, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 41, 0, + 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 2, + 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, + 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 55, 0, 0, 12, 114, 0, + 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, + 0, 11, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 18, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, + 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 30, 0, 0, 10, 114, 0, + 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 232, + 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, + 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, + 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 20, 0, 0, 0, 70, + 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, + 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, + 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, + 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 20, + 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, + 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, + 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, + 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, + 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, + 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, + 0, 54, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 10, 0, + 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 86, 0, 0, 5, 194, 0, 16, 0, 13, + 0, 0, 0, 6, 12, 16, 0, 15, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, + 15, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, + 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, + 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, + 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, + 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, + 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, 0, + 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, 0, + 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, 0, + 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, + 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 171, 170, 170, 62, 171, 170, 170, 62, 171, 170, 170, 62, 171, 170, 170, 62, 54, 0, + 0, 5, 130, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 54, + 0, 0, 5, 130, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, + 54, 0, 0, 5, 130, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 13, 0, 0, + 0, 54, 0, 0, 5, 130, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 13, 0, + 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 150, 3, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 54, 0, 0, 5, 82, 0, 16, 0, 15, 0, 0, 0, 6, 1, 16, 0, 13, 0, + 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 15, 0, 0, 0, 86, 9, 16, 0, 11, + 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, + 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 12, 0, 0, + 0, 70, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 10, + 0, 0, 0, 230, 10, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, + 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, + 0, 11, 0, 0, 0, 166, 11, 16, 0, 13, 0, 0, 0, 42, 0, 0, 10, 242, 0, + 16, 0, 13, 0, 0, 0, 214, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, + 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, + 0, 0, 10, 50, 0, 16, 0, 14, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 0, 0, 10, 50, 0, 16, 0, 11, 0, 0, 0, 230, 10, 16, 0, 13, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 14, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 13, 0, 0, 0, 150, 3, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, + 5, 18, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 131, 0, + 0, 5, 34, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 131, + 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, + 131, 0, 0, 5, 34, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, + 0, 131, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 11, 0, + 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 13, + 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, + 11, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, + 0, 13, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, + 0, 26, 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, + 11, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 54, + 0, 0, 8, 226, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, 0, + 0, 0, 7, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, + 70, 14, 16, 0, 12, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 0, 0, + 0, 7, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, + 14, 16, 0, 14, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 11, 0, 0, 0, + 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 30, 0, 0, + 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 42, 0, + 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 4, 0, 0, 0, 32, + 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 4, 0, 0, + 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 14, + 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, + 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 165, 0, 0, 8, 242, 0, + 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 230, 116, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 16, 0, 0, 0, + 230, 10, 16, 0, 14, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 17, 0, 0, + 0, 230, 10, 16, 0, 15, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 34, 0, + 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 16, 0, 0, 0, 26, 0, 16, 0, + 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, + 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, + 50, 0, 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 162, 0, 16, 0, + 4, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, + 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 17, 0, 0, 0, 26, 0, 16, 0, + 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, + 8, 50, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 70, 112, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, + 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, + 41, 0, 0, 10, 194, 0, 16, 0, 16, 0, 0, 0, 6, 4, 16, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 38, 7, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, + 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, + 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, + 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 14, 0, + 0, 0, 6, 4, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, + 18, 0, 0, 0, 38, 7, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, + 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, + 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, + 0, 0, 10, 194, 0, 16, 0, 17, 0, 0, 0, 6, 4, 16, 0, 17, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 42, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 38, 7, 16, 0, 17, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, + 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, + 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, + 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, 0, 70, + 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, + 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 15, 0, 0, + 0, 6, 4, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 18, + 0, 0, 0, 38, 7, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, + 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, + 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, + 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, 10, 162, + 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, + 5, 82, 0, 16, 0, 16, 0, 0, 0, 6, 1, 16, 0, 16, 0, 0, 0, 131, 0, + 0, 5, 162, 0, 16, 0, 16, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 85, + 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 14, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 131, 0, 0, 5, 82, 0, 16, 0, 14, 0, 0, 0, 6, 1, 16, 0, 14, 0, + 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 14, 0, 0, 0, 86, 13, 16, 0, 4, + 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, + 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 17, 0, 0, 0, 6, 1, + 16, 0, 17, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 17, 0, 0, 0, 86, + 13, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, + 6, 4, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 15, 0, + 0, 0, 6, 1, 16, 0, 15, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 15, + 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, + 54, 0, 0, 8, 194, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 17, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, + 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 242, 0, 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, + 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, + 7, 34, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 15, 0, 0, 0, 26, + 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 66, 0, 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 50, + 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 1, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 15, 0, 0, 0, 10, + 0, 16, 0, 1, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 165, 0, 0, 8, 18, 0, 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, + 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, + 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 226, 0, 16, 0, 18, 0, 0, 0, 86, 5, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 26, 0, 16, 0, 15, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, + 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 86, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, 18, + 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 18, 0, 0, 0, 166, 10, 16, + 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, + 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 42, + 0, 16, 0, 15, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, + 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 18, 0, + 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 14, + 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, + 0, 18, 0, 0, 0, 246, 15, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, + 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, + 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 6, 0, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, + 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, + 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, + 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 85, 0, + 0, 10, 226, 0, 16, 0, 18, 0, 0, 0, 86, 5, 16, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, + 54, 0, 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 26, 0, 16, 0, 15, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, + 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, + 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, + 0, 18, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, + 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 18, 0, 0, 0, 166, + 10, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, + 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 18, 0, 0, + 0, 42, 0, 16, 0, 15, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 18, 0, + 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, + 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 14, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 8, 32, + 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, + 0, 16, 0, 18, 0, 0, 0, 246, 15, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, 0, 70, 14, 16, 0, 18, 0, + 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, + 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 6, 0, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, + 70, 14, 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, + 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, + 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, + 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, + 85, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 86, 9, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 30, 0, + 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 19, 0, 0, 0, 26, 0, 16, 0, 15, + 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 19, 0, 0, 0, 6, 1, 16, 0, + 18, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, 4, 0, 0, 0, 6, 9, 16, + 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 21, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, + 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, + 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, 232, 255, + 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, + 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, + 22, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 23, 0, 0, 0, 70, 2, + 16, 128, 65, 0, 0, 0, 22, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 23, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, + 0, 70, 2, 16, 0, 23, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, + 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, + 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 41, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 23, 0, + 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, + 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, + 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 55, 0, 0, + 12, 114, 0, 16, 0, 16, 0, 0, 0, 150, 7, 16, 0, 4, 0, 0, 0, 70, 2, + 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 50, 0, 16, 0, 1, 0, 0, 0, + 230, 10, 16, 0, 18, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, + 0, 230, 11, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 19, + 0, 0, 0, 42, 0, 16, 0, 15, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, + 19, 0, 0, 0, 6, 3, 16, 0, 18, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, + 0, 4, 0, 0, 0, 6, 9, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 15, 114, 0, 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 135, 0, 0, 5, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, + 0, 30, 0, 0, 10, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, 0, + 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, + 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, + 20, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, + 16, 0, 23, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 22, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 23, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, + 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 140, 0, + 0, 17, 114, 0, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, + 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, + 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, + 0, 70, 2, 16, 0, 19, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 20, 0, + 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, + 0, 19, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 150, 7, + 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 171, 170, 170, 62, 171, 170, 170, 62, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 1, + 0, 0, 10, 226, 0, 16, 0, 4, 0, 0, 0, 6, 9, 16, 0, 18, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 18, 0, + 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, + 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 18, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 21, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 21, 0, 0, 0, + 70, 2, 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, + 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 21, 0, + 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 11, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, + 0, 21, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 22, 0, 0, 0, 70, + 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, + 22, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, + 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, + 0, 9, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 41, 0, 0, 10, + 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, + 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, + 41, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 19, + 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, + 17, 0, 0, 0, 150, 7, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 54, 0, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, + 30, 0, 0, 0, 86, 0, 0, 5, 98, 0, 16, 0, 4, 0, 0, 0, 6, 3, 16, + 0, 18, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 10, 0, + 16, 0, 15, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, + 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 21, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 135, 0, 0, 5, 114, 0, + 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 30, 0, 0, 10, 114, + 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, + 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, + 12, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, + 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 23, 0, 0, 0, + 70, 2, 16, 128, 65, 0, 0, 0, 22, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, + 16, 0, 23, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, + 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, + 18, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 18, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, + 18, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, + 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, + 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, + 23, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, + 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, + 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 18, 0, + 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 55, + 0, 0, 12, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, 98, 0, 16, 0, 4, 0, + 0, 0, 86, 6, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 171, + 170, 170, 62, 171, 170, 170, 62, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, + 16, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, + 0, 14, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, + 16, 0, 17, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, + 0, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 2, 0, 0, 1, + 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 18, 0, 0, 0, 150, 3, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, 82, + 0, 16, 0, 19, 0, 0, 0, 6, 1, 16, 0, 18, 0, 0, 0, 54, 0, 0, 5, + 162, 0, 16, 0, 19, 0, 0, 0, 86, 9, 16, 0, 15, 0, 0, 0, 42, 0, 0, + 10, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, + 0, 0, 5, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, + 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, + 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 16, 0, 0, 0, 70, 0, 16, 0, 19, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, + 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 14, 0, 0, 0, 230, 10, 16, + 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 15, 0, 0, 0, 166, + 11, 16, 0, 18, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, + 214, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 18, 0, + 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 18, + 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, + 0, 17, 0, 0, 0, 70, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, + 0, 16, 0, 15, 0, 0, 0, 230, 10, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 14, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 17, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, + 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, + 0, 150, 3, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 16, + 0, 0, 0, 26, 0, 16, 0, 15, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, + 16, 0, 0, 0, 10, 0, 16, 0, 18, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, + 0, 14, 0, 0, 0, 42, 0, 16, 0, 15, 0, 0, 0, 131, 0, 0, 5, 34, 0, + 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, 18, 0, 0, 0, 131, 0, 0, 5, 18, + 0, 16, 0, 17, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 131, 0, 0, 5, + 34, 0, 16, 0, 17, 0, 0, 0, 42, 0, 16, 0, 18, 0, 0, 0, 131, 0, 0, + 5, 18, 0, 16, 0, 15, 0, 0, 0, 10, 0, 16, 0, 15, 0, 0, 0, 131, 0, + 0, 5, 34, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 54, + 0, 0, 8, 194, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 17, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, 0, + 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 16, 0, 0, 0, 26, 0, 16, 0, 15, + 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 15, 0, 0, 0, 54, 0, + 0, 8, 226, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, + 17, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, + 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, 0, 0, 0, 7, 242, 0, 16, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 16, 0, + 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 17, 0, 0, + 0, 0, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 130, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, + 21, 0, 0, 1, 56, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 246, 15, 16, + 0, 1, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 56, 0, 0, 7, 242, 0, + 16, 0, 6, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 6, + 0, 0, 0, 56, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 246, 15, 16, 0, + 1, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 56, 0, 0, 7, 242, 0, 16, + 0, 7, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 7, 0, + 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 82, + 0, 16, 0, 4, 0, 0, 0, 166, 8, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, + 82, 0, 16, 0, 6, 0, 0, 0, 166, 8, 16, 0, 6, 0, 0, 0, 54, 0, 0, + 5, 82, 0, 16, 0, 8, 0, 0, 0, 166, 8, 16, 0, 8, 0, 0, 0, 54, 0, + 0, 5, 82, 0, 16, 0, 9, 0, 0, 0, 166, 8, 16, 0, 7, 0, 0, 0, 18, + 0, 0, 1, 54, 0, 0, 5, 82, 0, 16, 0, 9, 0, 0, 0, 6, 2, 16, 0, + 7, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 26, 0, 16, 0, 5, 0, 0, + 0, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 3, 1, 64, + 0, 0, 14, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 50, 0, 0, 0, 54, + 32, 0, 5, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 50, 0, 0, 15, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, + 127, 67, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, + 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 10, 0, 0, 0, 1, 64, 0, 0, 0, 1, 0, 0, 10, 0, 16, 0, 10, 0, + 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 10, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 35, 0, 0, 9, 18, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 1, 10, 0, 16, 0, 0, 0, 0, 0, 54, 32, + 0, 5, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 50, + 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, + 67, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, + 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, + 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 11, 0, 0, 0, 1, 64, 0, 0, 0, 1, 0, 0, 10, 0, 16, 0, 11, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 11, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, 0, 0, 35, + 0, 0, 9, 34, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 1, 10, 0, 16, 0, 0, 0, 0, 0, 54, 32, 0, + 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 50, 0, + 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, + 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, + 63, 28, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 11, + 0, 0, 0, 1, 64, 0, 0, 0, 1, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, + 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 1, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 162, 0, 16, 0, 9, 0, 0, 0, 86, 13, 16, 0, 7, 0, 0, 0, 54, 32, 0, + 5, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 50, 0, + 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, + 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, + 63, 28, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 11, + 0, 0, 0, 1, 64, 0, 0, 0, 1, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, + 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, + 0, 9, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 1, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 242, 0, 16, 0, 9, 0, 0, 0, 118, 8, 16, 0, 10, 0, 0, 0, 2, 0, 0, + 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 6, 0, 0, 3, 1, 64, + 0, 0, 54, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 192, 127, 68, 0, 192, 127, + 68, 0, 192, 127, 68, 0, 0, 64, 64, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, + 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, + 0, 10, 0, 16, 0, 10, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 0, 0, 16, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 10, 0, 0, 0, + 58, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 10, 0, 16, + 0, 0, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 70, + 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 192, 127, 68, 0, 192, 127, 68, + 0, 192, 127, 68, 0, 0, 64, 64, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, + 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, + 10, 0, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 0, 16, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 10, 0, 0, 0, 58, + 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, + 0, 8, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 192, 127, 68, 0, 192, 127, 68, 0, + 192, 127, 68, 0, 0, 64, 64, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, + 0, 70, 14, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 10, + 0, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 0, 16, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 10, 0, 0, 0, 58, 0, + 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 10, 0, 16, 0, 0, + 0, 0, 0, 54, 32, 0, 5, 82, 0, 16, 0, 7, 0, 0, 0, 6, 2, 16, 0, + 9, 0, 0, 0, 54, 32, 0, 5, 162, 0, 16, 0, 7, 0, 0, 0, 86, 13, 16, + 0, 7, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, + 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 192, 127, 68, 0, 192, 127, 68, 0, + 192, 127, 68, 0, 0, 64, 64, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, + 0, 70, 14, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 10, + 0, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 0, 16, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, + 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 10, 0, 16, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 9, 0, 0, 0, 118, 8, 16, 0, + 10, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 16, 0, 0, + 0, 6, 0, 0, 3, 1, 64, 0, 0, 55, 0, 0, 0, 54, 32, 0, 5, 114, 0, + 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 50, 0, 0, 15, 178, + 0, 16, 0, 1, 0, 0, 0, 70, 8, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 0, 224, 255, 68, 0, 224, 255, 68, 0, 0, 0, 0, 0, 192, 127, 68, 2, 64, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 28, 0, + 0, 5, 178, 0, 16, 0, 1, 0, 0, 0, 70, 12, 16, 0, 1, 0, 0, 0, 35, + 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 8, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, + 9, 18, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 64, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 32, 0, 5, 114, + 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 50, 0, 0, 15, + 178, 0, 16, 0, 1, 0, 0, 0, 70, 8, 16, 0, 6, 0, 0, 0, 2, 64, 0, + 0, 0, 224, 255, 68, 0, 224, 255, 68, 0, 0, 0, 0, 0, 192, 127, 68, 2, 64, + 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 28, + 0, 0, 5, 178, 0, 16, 0, 1, 0, 0, 0, 70, 12, 16, 0, 1, 0, 0, 0, + 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 8, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 64, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 32, 0, 5, + 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 50, 0, 0, + 15, 178, 0, 16, 0, 1, 0, 0, 0, 70, 8, 16, 0, 8, 0, 0, 0, 2, 64, + 0, 0, 0, 224, 255, 68, 0, 224, 255, 68, 0, 0, 0, 0, 0, 192, 127, 68, 2, + 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, + 28, 0, 0, 5, 178, 0, 16, 0, 1, 0, 0, 0, 70, 12, 16, 0, 1, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 35, + 0, 0, 9, 66, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 64, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 32, 0, + 5, 82, 0, 16, 0, 7, 0, 0, 0, 6, 2, 16, 0, 9, 0, 0, 0, 54, 32, + 0, 5, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 50, + 0, 0, 15, 178, 0, 16, 0, 1, 0, 0, 0, 70, 8, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 0, 224, 255, 68, 0, 224, 255, 68, 0, 0, 0, 0, 0, 192, 127, + 68, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, + 0, 63, 28, 0, 0, 5, 178, 0, 16, 0, 1, 0, 0, 0, 70, 12, 16, 0, 1, + 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 10, 0, 16, 0, 1, 0, 0, + 0, 35, 0, 0, 9, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 64, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 242, 0, 16, 0, 9, 0, 0, 0, 118, 8, 16, 0, 10, 0, 0, 0, + 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 17, 0, 0, 0, 6, 0, 0, + 3, 1, 64, 0, 0, 56, 0, 0, 0, 54, 32, 0, 5, 114, 0, 16, 0, 4, 0, + 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 50, 0, 0, 15, 178, 0, 16, 0, 1, + 0, 0, 0, 70, 8, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 192, 127, 68, + 0, 224, 255, 68, 0, 0, 0, 0, 0, 224, 255, 68, 2, 64, 0, 0, 0, 0, 0, + 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 28, 0, 0, 5, 178, 0, + 16, 0, 1, 0, 0, 0, 70, 12, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 18, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 4, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 10, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 32, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 32, 0, 5, 114, 0, 16, 0, 6, + 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 50, 0, 0, 15, 178, 0, 16, 0, + 1, 0, 0, 0, 70, 8, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 192, 127, + 68, 0, 224, 255, 68, 0, 0, 0, 0, 0, 224, 255, 68, 2, 64, 0, 0, 0, 0, + 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 28, 0, 0, 5, 178, + 0, 16, 0, 1, 0, 0, 0, 70, 12, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 0, 4, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 34, 0, + 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 32, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 32, 0, 5, 114, 0, 16, 0, + 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 50, 0, 0, 15, 178, 0, 16, + 0, 1, 0, 0, 0, 70, 8, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 192, + 127, 68, 0, 224, 255, 68, 0, 0, 0, 0, 0, 224, 255, 68, 2, 64, 0, 0, 0, + 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 28, 0, 0, 5, + 178, 0, 16, 0, 1, 0, 0, 0, 70, 12, 16, 0, 1, 0, 0, 0, 35, 0, 0, + 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 4, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, + 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 32, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 32, 0, 5, 82, 0, 16, + 0, 7, 0, 0, 0, 6, 2, 16, 0, 9, 0, 0, 0, 54, 32, 0, 5, 34, 0, + 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 50, 0, 0, 15, 178, + 0, 16, 0, 1, 0, 0, 0, 70, 8, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, + 0, 192, 127, 68, 0, 224, 255, 68, 0, 0, 0, 0, 0, 224, 255, 68, 2, 64, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 28, 0, + 0, 5, 178, 0, 16, 0, 1, 0, 0, 0, 70, 12, 16, 0, 1, 0, 0, 0, 35, + 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 4, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, + 9, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 32, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, + 0, 16, 0, 9, 0, 0, 0, 118, 8, 16, 0, 10, 0, 0, 0, 2, 0, 0, 1, + 6, 0, 0, 3, 1, 64, 0, 0, 25, 0, 0, 0, 54, 32, 0, 5, 50, 0, 16, + 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 50, 0, 0, 15, 146, 0, + 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 255, 127, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 127, 71, 2, 64, 0, 0, + 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 28, 0, 0, + 5, 146, 0, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 32, 0, 5, + 50, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 6, 0, 0, 0, 50, 0, 0, + 15, 146, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 2, 64, + 0, 0, 0, 255, 127, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 127, 71, 2, + 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 28, 0, 0, 5, 146, 0, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, + 0, 35, 0, 0, 9, 34, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, + 32, 0, 5, 50, 0, 16, 0, 8, 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, + 50, 0, 0, 15, 146, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 0, 255, 127, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, + 127, 71, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 63, 28, 0, 0, 5, 146, 0, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, + 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 54, 32, 0, 5, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 9, + 0, 0, 0, 54, 32, 0, 5, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, + 7, 0, 0, 0, 50, 0, 0, 15, 146, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, + 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 255, 127, 71, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 255, 127, 71, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 63, 28, 0, 0, 5, 146, 0, 16, 0, 0, 0, 0, 0, + 6, 12, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 9, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 31, + 0, 0, 0, 130, 0, 0, 5, 146, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, + 4, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 130, 0, 0, 5, 146, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 6, + 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 130, 0, 0, 5, 146, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 8, 0, + 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 130, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, + 0, 130, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, + 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 9, 0, 0, + 0, 10, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 9, 0, + 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 9, + 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, + 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, + 0, 0, 138, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, + 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 230, 14, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 254, 7, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, + 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 10, + 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 24, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 8, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, + 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 20, 98, 0, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, + 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 1, + 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 17, 82, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, + 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 82, 0, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 42, 0, 0, + 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 85, + 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, + 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 166, + 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, + 0, 70, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 192, 1, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 64, + 0, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, + 0, 0, 10, 98, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 140, 0, 0, 17, 98, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, + 2, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 23, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 11, + 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, + 2, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 140, + 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 21, 0, 0, 1, 30, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 32, 0, 0, 10, 226, 0, 16, + 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 98, + 0, 16, 0, 0, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, + 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 10, 242, 0, 16, 0, 1, 0, 0, 0, 102, 3, 16, 0, 9, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 102, 3, 16, 0, 9, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 118, 8, + 16, 0, 1, 0, 0, 0, 118, 8, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 31, + 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, + 1, 0, 0, 0, 102, 3, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, + 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 118, 8, 16, + 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 102, 3, 16, 0, 9, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 51, 5, 0, 0, + 24, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 45, 1, 0, + 0, 173, 0, 0, 0, 62, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, + 64, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_32bpp_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_32bpp_scaled_cs.h new file mode 100644 index 0000000..14068cf --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_32bpp_scaled_cs.h @@ -0,0 +1,3644 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_resolve_edram_info; // Offset: 0 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 4 Size: 4 +// uint xe_resolve_dest_info; // Offset: 8 Size: 4 +// uint xe_resolve_dest_coordinate_info;// Offset: 12 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram texture byte r/o T0 t0 1 +// xe_resolve_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_raw T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 24 +dcl_thread_group 8, 8, 1 +and r0.xyzw, CB0[0][0].xxzz, l(1023, 0x20000000, 7, 8) +if_nz r0.y + ubfe r1.xy, l(2, 2, 0, 0), l(17, 20, 0, 0), CB0[0][0].yyyy +else + mov r1.xy, l(0,0,0,0) +endif +ubfe r2.xyz, l(3, 3, 11, 0), l(16, 19, 5, 0), CB0[0][0].yyyy +imul null, r0.y, r2.x, r2.z +and r1.z, CB0[0][0].z, l(0x01000000) +ushr r3.xyzw, CB0[0][0].ywww, l(4, 10, 20, 24) +ishl r4.x, vThreadID.x, l(2) +ishl r0.y, r0.y, l(3) +uge r0.y, r4.x, r0.y +if_nz r0.y + ret +endif +ubfe r5.xyzw, l(2, 11, 4, 1), l(10, 13, 24, 28), CB0[0][0].xxxx +mov r6.x, CB0[0][0].y +mov r6.y, r3.x +bfi r2.zw, l(0, 0, 4, 1), l(0, 0, 3, 3), r6.xxxy, l(0, 0, 0, 0) +ibfe r0.y, l(6), l(16), CB0[0][0].z +ishl r0.y, r0.y, l(23) +iadd r0.y, r0.y, l(0x3f800000) +bfi r1.w, l(10), l(5), CB0[0][0].w, l(0) +bfi r3.xz, l(4, 0, 4, 0), l(3, 0, 3, 0), r3.zzwz, l(0, 0, 0, 0) +ubfe r6.xy, l(6, 3, 0, 0), l(7, 28, 0, 0), CB0[0][0].zwzz +umax r4.y, r1.y, vThreadID.y +imad r2.zw, r2.zzzw, r2.xxxy, r4.xxxy +uge r1.y, l(3), r6.y +if_nz r1.y + mov r7.y, r6.y +else + ieq r1.y, r6.y, l(5) + if_nz r1.y + mov r7.y, l(2) + else + mov r7.y, l(0) + endif +endif +uge r4.yw, r5.xxxx, l(0, 2, 0, 1) +and r4.yw, r4.yyyw, l(0, 1, 0, 1) +ishl r2.zw, r2.zzzw, r4.yyyw +ushr r7.x, r7.y, l(1) +and r6.zw, r7.xxxy, l(0, 0, 1, 1) +iadd r2.zw, r2.zzzw, r6.zzzw +imul null, r7.yz, r2.xxyx, l(0, 80, 16, 0) +ushr r7.x, r7.y, r5.w +udiv r6.zw, null, r2.zzzw, r7.xxxz +imad r0.x, r6.w, r0.x, r6.z +iadd r0.x, r0.x, r5.y +imad r2.zw, -r6.zzzw, r7.xxxz, r2.zzzw +imul null, r1.y, r7.z, r7.y +imad r2.z, r2.w, r7.x, r2.z +ishl r2.z, r2.z, r5.w +imad r0.x, r0.x, r1.y, r2.z +ishl r1.y, r1.y, l(11) +udiv null, r0.x, r0.x, r1.y +iadd r1.y, r4.y, r5.w +ishl r2.z, l(1), r1.y +if_nz r5.w + ieq r2.w, r2.z, l(2) + if_nz r2.w + ishl r2.w, r0.x, l(2) + ld_raw r7.xyzw, r2.w, T0[0].zwxy + iadd r2.w, r2.w, l(16) + ld_raw r8.xyzw, r2.w, T0[0].zwxy + mov r9.xy, r7.zwzz + mov r10.xy, r8.zwzz + else + ishl r2.w, r0.x, l(2) + ld_raw r9.xy, r2.w, T0[0].xyxx + iadd r2.w, r0.x, r2.z + ishl r2.w, r2.w, l(2) + ld_raw r7.xy, r2.w, T0[0].xyxx + ishl r4.yw, l(0, 2, 0, 3), r1.yyyy + iadd r4.yw, r0.xxxx, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r10.xy, r4.y, T0[0].xyxx + ld_raw r8.xy, r4.w, T0[0].xyxx + endif + switch r5.z + case l(5) + ishl r9.zw, r9.xxxy, l(0, 0, 16, 16) + ishr r11.xyzw, r9.zxwy, l(16, 16, 16, 16) + itof r11.xyzw, r11.xyzw + mul r11.xyzw, r11.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xyzw, r11.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r7.zw, r7.xxxy, l(0, 0, 16, 16) + ishr r11.xyzw, r7.zxwy, l(16, 16, 16, 16) + itof r11.xyzw, r11.xyzw + mul r11.xyzw, r11.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r7.xyzw, r11.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r10.zw, r10.xxxy, l(0, 0, 16, 16) + ishr r11.xyzw, r10.zxwy, l(16, 16, 16, 16) + itof r11.xyzw, r11.xyzw + mul r11.xyzw, r11.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r10.xyzw, r11.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r8.zw, r8.xxxy, l(0, 0, 16, 16) + ishr r11.xyzw, r8.zxwy, l(16, 16, 16, 16) + itof r11.xyzw, r11.xyzw + mul r11.xyzw, r11.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xyzw, r11.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.yw, r9.xxxy, l(0, 16, 0, 16) + f16tof32 r9.xz, r9.xxyx + f16tof32 r9.yw, r4.yyyw + ushr r4.yw, r7.xxxy, l(0, 16, 0, 16) + f16tof32 r7.xz, r7.xxyx + f16tof32 r7.yw, r4.yyyw + ushr r4.yw, r10.xxxy, l(0, 16, 0, 16) + f16tof32 r10.xz, r10.xxyx + f16tof32 r10.yw, r4.yyyw + ushr r4.yw, r8.xxxy, l(0, 16, 0, 16) + f16tof32 r8.xz, r8.xxyx + f16tof32 r8.yw, r4.yyyw + break + default + mov r9.zw, l(0,0,0,0) + mov r7.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + endswitch +else + ieq r2.w, r2.z, l(1) + if_nz r2.w + ishl r2.w, r0.x, l(2) + ld_raw r8.xyzw, r2.w, T0[0].wxyz + else + ishl r2.w, r0.x, l(2) + ld_raw r8.y, r2.w, T0[0].xxxx + iadd r2.w, r0.x, r2.z + ishl r2.w, r2.w, l(2) + ld_raw r8.z, r2.w, T0[0].xxxx + ishl r4.yw, l(0, 2, 0, 3), r1.yyyy + iadd r4.yw, r0.xxxx, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r8.w, r4.y, T0[0].xxxx + ld_raw r8.x, r4.w, T0[0].xxxx + endif + switch r5.z + case l(0) + case l(1) + ushr r11.yzw, r8.yyyy, l(0, 8, 16, 24) + mov r11.x, r8.y + and r11.xyzw, r11.xyzw, l(255, 255, 255, 255) + utof r11.xyzw, r11.xyzw + mul r9.xyzw, r11.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r11.yzw, r8.zzzz, l(0, 8, 16, 24) + mov r11.x, r8.z + and r11.xyzw, r11.xyzw, l(255, 255, 255, 255) + utof r11.xyzw, r11.xyzw + mul r7.xyzw, r11.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r11.yzw, r8.wwww, l(0, 8, 16, 24) + mov r11.x, r8.w + and r11.xyzw, r11.xyzw, l(255, 255, 255, 255) + utof r11.xyzw, r11.xyzw + mul r10.xyzw, r11.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r8.yzw, r8.xxxx, l(0, 8, 16, 24) + and r11.xyzw, r8.xyzw, l(255, 255, 255, 255) + utof r11.xyzw, r11.xyzw + mul r8.xyzw, r11.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r11.yzw, r8.yyyy, l(0, 10, 20, 30) + mov r11.x, r8.y + and r11.xyzw, r11.xyzw, l(1023, 1023, 1023, 3) + utof r11.xyzw, r11.xyzw + mul r9.xyzw, r11.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r11.yzw, r8.zzzz, l(0, 10, 20, 30) + mov r11.x, r8.z + and r11.xyzw, r11.xyzw, l(1023, 1023, 1023, 3) + utof r11.xyzw, r11.xyzw + mul r7.xyzw, r11.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r11.yzw, r8.wwww, l(0, 10, 20, 30) + mov r11.x, r8.w + and r11.xyzw, r11.xyzw, l(1023, 1023, 1023, 3) + utof r11.xyzw, r11.xyzw + mul r10.xyzw, r11.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r8.yzw, r8.xxxx, l(0, 10, 20, 30) + and r11.xyzw, r8.xyzw, l(1023, 1023, 1023, 3) + utof r11.xyzw, r11.xyzw + mul r8.xyzw, r11.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r11.xyzw, r8.yyyz, l(10, 20, 30, 30) + mov r12.x, r8.y + mov r12.yz, r11.xxyx + and r13.xyz, r12.xyzx, l(1023, 1023, 1023, 0) + and r14.xyz, r12.xyzx, l(127, 127, 127, 0) + ubfe r15.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r12.xyzx + firstbit_hi r16.xyz, r14.xyzx + iadd r16.xyz, r16.xyzx, l(-24, -24, -24, 0) + movc r16.xyz, r14.xyzx, r16.xyzx, l(8,8,8,0) + iadd r17.xyz, -r16.xyzx, l(1, 1, 1, 0) + movc r17.xyz, r15.xyzx, r15.xyzx, r17.xyzx + bfi r12.xyz, l(7, 7, 7, 0), r16.xyzx, r12.xyzx, l(0, 0, 0, 0) + and r12.xyz, r12.xyzx, l(127, 127, 127, 0) + movc r12.xyz, r15.xyzx, r14.xyzx, r12.xyzx + ishl r14.xyz, r17.xyzx, l(23, 23, 23, 0) + iadd r14.xyz, r14.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r12.xyz, r12.xyzx, l(16, 16, 16, 0) + iadd r12.xyz, r14.xyzx, r12.xyzx + movc r9.xyz, r13.xyzx, r12.xyzx, l(0,0,0,0) + utof r4.yw, r11.zzzw + ushr r11.xyzw, r8.zwwz, l(10, 10, 20, 20) + mov r12.x, r8.z + mov r12.yz, r11.xxwx + and r13.xyz, r12.xyzx, l(1023, 1023, 1023, 0) + and r14.xyz, r12.xyzx, l(127, 127, 127, 0) + ubfe r15.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r12.xyzx + firstbit_hi r16.xyz, r14.xyzx + iadd r16.xyz, r16.xyzx, l(-24, -24, -24, 0) + movc r16.xyz, r14.xyzx, r16.xyzx, l(8,8,8,0) + iadd r17.xyz, -r16.xyzx, l(1, 1, 1, 0) + movc r17.xyz, r15.xyzx, r15.xyzx, r17.xyzx + bfi r12.xyz, l(7, 7, 7, 0), r16.xyzx, r12.xyzx, l(0, 0, 0, 0) + and r12.xyz, r12.xyzx, l(127, 127, 127, 0) + movc r12.xyz, r15.xyzx, r14.xyzx, r12.xyzx + ishl r14.xyz, r17.xyzx, l(23, 23, 23, 0) + iadd r14.xyz, r14.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r12.xyz, r12.xyzx, l(16, 16, 16, 0) + iadd r12.xyz, r14.xyzx, r12.xyzx + movc r7.xyz, r13.xyzx, r12.xyzx, l(0,0,0,0) + mul r4.yw, r4.yyyw, l(0.000000, 0.333333, 0.000000, 0.333333) + mov r11.x, r8.w + and r12.xyz, r11.xyzx, l(1023, 1023, 1023, 0) + and r13.xyz, r11.xyzx, l(127, 127, 127, 0) + ubfe r14.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r11.xyzx + firstbit_hi r15.xyz, r13.xyzx + iadd r15.xyz, r15.xyzx, l(-24, -24, -24, 0) + movc r15.xyz, r13.xyzx, r15.xyzx, l(8,8,8,0) + iadd r16.xyz, -r15.xyzx, l(1, 1, 1, 0) + movc r16.xyz, r14.xyzx, r14.xyzx, r16.xyzx + bfi r11.xyz, l(7, 7, 7, 0), r15.xyzx, r11.xyzx, l(0, 0, 0, 0) + and r11.xyz, r11.xyzx, l(127, 127, 127, 0) + movc r11.xyz, r14.xyzx, r13.xyzx, r11.xyzx + ishl r13.xyz, r16.xyzx, l(23, 23, 23, 0) + iadd r13.xyz, r13.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r11.xyz, r11.xyzx, l(16, 16, 16, 0) + iadd r11.xyz, r13.xyzx, r11.xyzx + movc r10.xyz, r12.xyzx, r11.xyzx, l(0,0,0,0) + ushr r11.xyzw, r8.wxxx, l(30, 10, 20, 30) + utof r5.xy, r11.xwxx + mov r11.x, r8.x + and r12.xyz, r11.xyzx, l(1023, 1023, 1023, 0) + and r13.xyz, r11.xyzx, l(127, 127, 127, 0) + ubfe r14.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r11.xyzx + firstbit_hi r15.xyz, r13.xyzx + iadd r15.xyz, r15.xyzx, l(-24, -24, -24, 0) + movc r15.xyz, r13.xyzx, r15.xyzx, l(8,8,8,0) + iadd r16.xyz, -r15.xyzx, l(1, 1, 1, 0) + movc r16.xyz, r14.xyzx, r14.xyzx, r16.xyzx + bfi r11.xyz, l(7, 7, 7, 0), r15.xyzx, r11.xyzx, l(0, 0, 0, 0) + and r11.xyz, r11.xyzx, l(127, 127, 127, 0) + movc r11.xyz, r14.xyzx, r13.xyzx, r11.xyzx + ishl r13.xyz, r16.xyzx, l(23, 23, 23, 0) + iadd r13.xyz, r13.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r11.xyz, r11.xyzx, l(16, 16, 16, 0) + iadd r11.xyz, r13.xyzx, r11.xyzx + movc r8.xyz, r12.xyzx, r11.xyzx, l(0,0,0,0) + mul r5.xy, r5.xyxx, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r9.w, r4.y + mov r7.w, r4.w + mov r10.w, r5.x + mov r8.w, r5.y + break + case l(4) + ishl r11.xyzw, r8.yzwx, l(16, 16, 16, 16) + mov r12.xz, r11.xxyx + mov r12.yw, r8.yyyz + ishr r12.xyzw, r12.xyzw, l(16, 16, 16, 16) + itof r12.xyzw, r12.xyzw + mul r12.xyzw, r12.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xy, r12.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r7.xy, r12.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r8.yz, r11.zzwz + ishr r11.xyzw, r8.ywzx, l(16, 16, 16, 16) + itof r11.xyzw, r11.xyzw + mul r11.xyzw, r11.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r10.xy, r11.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r8.xy, r11.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r9.zw, l(0,0,0,0) + mov r7.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + case l(6) + ushr r11.xyzw, r8.yzwx, l(16, 16, 16, 16) + f16tof32 r9.x, r8.y + f16tof32 r9.y, r11.x + f16tof32 r7.x, r8.z + f16tof32 r7.y, r11.y + f16tof32 r10.x, r8.w + f16tof32 r10.y, r11.z + f16tof32 r8.x, r8.x + f16tof32 r8.y, r11.w + mov r9.zw, l(0,0,0,0) + mov r7.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + default + mov r9.x, r8.y + mov r9.yzw, l(0,0,0,0) + mov r7.x, r8.z + mov r7.yzw, l(0,0,0,0) + mov r10.x, r8.w + mov r10.yzw, l(0,0,0,0) + mov r8.yzw, l(0,0,0,0) + break + endswitch +endif +uge r2.w, r6.y, l(4) +if_nz r2.w + mul r2.w, r0.y, l(0.500000) + imad r3.w, l(80), r2.x, r0.x + if_nz r5.w + ieq r4.y, r2.z, l(2) + if_nz r4.y + ishl r4.y, r3.w, l(2) + ld_raw r11.xyzw, r4.y, T0[0].zwxy + iadd r4.y, r4.y, l(16) + ld_raw r12.xyzw, r4.y, T0[0].zwxy + mov r13.xy, r11.zwzz + mov r14.xy, r12.zwzz + else + ishl r4.y, r3.w, l(2) + ld_raw r13.xy, r4.y, T0[0].xyxx + iadd r4.y, r2.z, r3.w + ishl r4.y, r4.y, l(2) + ld_raw r11.xy, r4.y, T0[0].xyxx + ishl r4.yw, l(0, 2, 0, 3), r1.yyyy + iadd r4.yw, r3.wwww, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r14.xy, r4.y, T0[0].xyxx + ld_raw r12.xy, r4.w, T0[0].xyxx + endif + switch r5.z + case l(5) + ishl r13.zw, r13.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r13.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r13.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r11.zw, r11.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r11.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r11.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r14.zw, r14.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r14.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r12.zw, r12.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r12.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r12.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.yw, r13.xxxy, l(0, 16, 0, 16) + f16tof32 r13.xz, r13.xxyx + f16tof32 r13.yw, r4.yyyw + ushr r4.yw, r11.xxxy, l(0, 16, 0, 16) + f16tof32 r11.xz, r11.xxyx + f16tof32 r11.yw, r4.yyyw + ushr r4.yw, r14.xxxy, l(0, 16, 0, 16) + f16tof32 r14.xz, r14.xxyx + f16tof32 r14.yw, r4.yyyw + ushr r4.yw, r12.xxxy, l(0, 16, 0, 16) + f16tof32 r12.xz, r12.xxyx + f16tof32 r12.yw, r4.yyyw + break + default + mov r13.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r12.zw, l(0,0,0,0) + break + endswitch + else + ieq r4.y, r2.z, l(1) + if_nz r4.y + ishl r4.y, r3.w, l(2) + ld_raw r12.xyzw, r4.y, T0[0].wxyz + else + ishl r4.y, r3.w, l(2) + ld_raw r12.y, r4.y, T0[0].xxxx + iadd r4.y, r2.z, r3.w + ishl r4.y, r4.y, l(2) + ld_raw r12.z, r4.y, T0[0].xxxx + ishl r4.yw, l(0, 2, 0, 3), r1.yyyy + iadd r4.yw, r3.wwww, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r12.w, r4.y, T0[0].xxxx + ld_raw r12.x, r4.w, T0[0].xxxx + endif + switch r5.z + case l(0) + case l(1) + ushr r15.yzw, r12.yyyy, l(0, 8, 16, 24) + mov r15.x, r12.y + and r15.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r13.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r15.yzw, r12.zzzz, l(0, 8, 16, 24) + mov r15.x, r12.z + and r15.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r11.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r15.yzw, r12.wwww, l(0, 8, 16, 24) + mov r15.x, r12.w + and r15.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r14.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r12.yzw, r12.xxxx, l(0, 8, 16, 24) + and r15.xyzw, r12.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r12.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r15.yzw, r12.yyyy, l(0, 10, 20, 30) + mov r15.x, r12.y + and r15.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r13.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r15.yzw, r12.zzzz, l(0, 10, 20, 30) + mov r15.x, r12.z + and r15.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r11.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r15.yzw, r12.wwww, l(0, 10, 20, 30) + mov r15.x, r12.w + and r15.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r14.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r12.yzw, r12.xxxx, l(0, 10, 20, 30) + and r15.xyzw, r12.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r12.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r15.xyzw, r12.yyyz, l(10, 20, 30, 30) + mov r16.x, r12.y + mov r16.yz, r15.xxyx + and r17.xyz, r16.xyzx, l(1023, 1023, 1023, 0) + and r18.xyz, r16.xyzx, l(127, 127, 127, 0) + ubfe r19.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r16.xyzx + firstbit_hi r20.xyz, r18.xyzx + iadd r20.xyz, r20.xyzx, l(-24, -24, -24, 0) + movc r20.xyz, r18.xyzx, r20.xyzx, l(8,8,8,0) + iadd r21.xyz, -r20.xyzx, l(1, 1, 1, 0) + movc r21.xyz, r19.xyzx, r19.xyzx, r21.xyzx + bfi r16.xyz, l(7, 7, 7, 0), r20.xyzx, r16.xyzx, l(0, 0, 0, 0) + and r16.xyz, r16.xyzx, l(127, 127, 127, 0) + movc r16.xyz, r19.xyzx, r18.xyzx, r16.xyzx + ishl r18.xyz, r21.xyzx, l(23, 23, 23, 0) + iadd r18.xyz, r18.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r16.xyz, r16.xyzx, l(16, 16, 16, 0) + iadd r16.xyz, r18.xyzx, r16.xyzx + movc r13.xyz, r17.xyzx, r16.xyzx, l(0,0,0,0) + utof r4.yw, r15.zzzw + ushr r15.xyzw, r12.zwwz, l(10, 10, 20, 20) + mov r16.x, r12.z + mov r16.yz, r15.xxwx + and r17.xyz, r16.xyzx, l(1023, 1023, 1023, 0) + and r18.xyz, r16.xyzx, l(127, 127, 127, 0) + ubfe r19.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r16.xyzx + firstbit_hi r20.xyz, r18.xyzx + iadd r20.xyz, r20.xyzx, l(-24, -24, -24, 0) + movc r20.xyz, r18.xyzx, r20.xyzx, l(8,8,8,0) + iadd r21.xyz, -r20.xyzx, l(1, 1, 1, 0) + movc r21.xyz, r19.xyzx, r19.xyzx, r21.xyzx + bfi r16.xyz, l(7, 7, 7, 0), r20.xyzx, r16.xyzx, l(0, 0, 0, 0) + and r16.xyz, r16.xyzx, l(127, 127, 127, 0) + movc r16.xyz, r19.xyzx, r18.xyzx, r16.xyzx + ishl r18.xyz, r21.xyzx, l(23, 23, 23, 0) + iadd r18.xyz, r18.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r16.xyz, r16.xyzx, l(16, 16, 16, 0) + iadd r16.xyz, r18.xyzx, r16.xyzx + movc r11.xyz, r17.xyzx, r16.xyzx, l(0,0,0,0) + mul r4.yw, r4.yyyw, l(0.000000, 0.333333, 0.000000, 0.333333) + mov r15.x, r12.w + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r14.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + ushr r15.xyzw, r12.wxxx, l(30, 10, 20, 30) + utof r5.xy, r15.xwxx + mov r15.x, r12.x + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r12.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + mul r5.xy, r5.xyxx, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r13.w, r4.y + mov r11.w, r4.w + mov r14.w, r5.x + mov r12.w, r5.y + break + case l(4) + ishl r15.xyzw, r12.yzwx, l(16, 16, 16, 16) + mov r16.xz, r15.xxyx + mov r16.yw, r12.yyyz + ishr r16.xyzw, r16.xyzw, l(16, 16, 16, 16) + itof r16.xyzw, r16.xyzw + mul r16.xyzw, r16.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r13.xy, r16.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r11.xy, r16.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r12.yz, r15.zzwz + ishr r15.xyzw, r12.ywzx, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xy, r15.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r12.xy, r15.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r13.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r12.zw, l(0,0,0,0) + break + case l(6) + ushr r15.xyzw, r12.yzwx, l(16, 16, 16, 16) + f16tof32 r13.x, r12.y + f16tof32 r13.y, r15.x + f16tof32 r11.x, r12.z + f16tof32 r11.y, r15.y + f16tof32 r14.x, r12.w + f16tof32 r14.y, r15.z + f16tof32 r12.x, r12.x + f16tof32 r12.y, r15.w + mov r13.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r12.zw, l(0,0,0,0) + break + default + mov r13.x, r12.y + mov r13.yzw, l(0,0,0,0) + mov r11.x, r12.z + mov r11.yzw, l(0,0,0,0) + mov r14.x, r12.w + mov r14.yzw, l(0,0,0,0) + mov r12.yzw, l(0,0,0,0) + break + endswitch + endif + add r9.xyzw, r9.xyzw, r13.xyzw + add r7.xyzw, r7.xyzw, r11.xyzw + add r10.xyzw, r10.xyzw, r14.xyzw + add r8.xyzw, r8.xyzw, r12.xyzw + uge r4.y, r6.y, l(6) + if_nz r4.y + ishl r4.y, l(1), r5.w + mul r0.y, r0.y, l(0.250000) + iadd r0.x, r0.x, r4.y + if_nz r5.w + ieq r4.w, r2.z, l(2) + if_nz r4.w + ishl r4.w, r0.x, l(2) + ld_raw r11.xyzw, r4.w, T0[0].zwxy + iadd r4.w, r4.w, l(16) + ld_raw r12.xyzw, r4.w, T0[0].zwxy + mov r13.xy, r11.zwzz + mov r14.xy, r12.zwzz + else + ishl r4.w, r0.x, l(2) + ld_raw r13.xy, r4.w, T0[0].xyxx + iadd r4.w, r2.z, r0.x + ishl r4.w, r4.w, l(2) + ld_raw r11.xy, r4.w, T0[0].xyxx + ishl r5.xy, l(2, 3, 0, 0), r1.yyyy + iadd r5.xy, r0.xxxx, r5.xyxx + ishl r5.xy, r5.xyxx, l(2, 2, 0, 0) + ld_raw r14.xy, r5.x, T0[0].xyxx + ld_raw r12.xy, r5.y, T0[0].xyxx + endif + switch r5.z + case l(5) + ishl r13.zw, r13.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r13.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r13.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r11.zw, r11.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r11.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r11.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r14.zw, r14.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r14.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r12.zw, r12.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r12.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r12.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r5.xy, r13.xyxx, l(16, 16, 0, 0) + f16tof32 r13.xz, r13.xxyx + f16tof32 r13.yw, r5.xxxy + ushr r5.xy, r11.xyxx, l(16, 16, 0, 0) + f16tof32 r11.xz, r11.xxyx + f16tof32 r11.yw, r5.xxxy + ushr r5.xy, r14.xyxx, l(16, 16, 0, 0) + f16tof32 r14.xz, r14.xxyx + f16tof32 r14.yw, r5.xxxy + ushr r5.xy, r12.xyxx, l(16, 16, 0, 0) + f16tof32 r12.xz, r12.xxyx + f16tof32 r12.yw, r5.xxxy + break + default + mov r13.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r12.zw, l(0,0,0,0) + break + endswitch + else + ieq r4.w, r2.z, l(1) + if_nz r4.w + ishl r4.w, r0.x, l(2) + ld_raw r12.xyzw, r4.w, T0[0].wxyz + else + ishl r4.w, r0.x, l(2) + ld_raw r12.y, r4.w, T0[0].xxxx + iadd r4.w, r2.z, r0.x + ishl r4.w, r4.w, l(2) + ld_raw r12.z, r4.w, T0[0].xxxx + ishl r5.xy, l(2, 3, 0, 0), r1.yyyy + iadd r5.xy, r0.xxxx, r5.xyxx + ishl r5.xy, r5.xyxx, l(2, 2, 0, 0) + ld_raw r12.w, r5.x, T0[0].xxxx + ld_raw r12.x, r5.y, T0[0].xxxx + endif + switch r5.z + case l(0) + case l(1) + ushr r15.yzw, r12.yyyy, l(0, 8, 16, 24) + mov r15.x, r12.y + and r15.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r13.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r15.yzw, r12.zzzz, l(0, 8, 16, 24) + mov r15.x, r12.z + and r15.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r11.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r15.yzw, r12.wwww, l(0, 8, 16, 24) + mov r15.x, r12.w + and r15.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r14.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r12.yzw, r12.xxxx, l(0, 8, 16, 24) + and r15.xyzw, r12.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r12.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r15.yzw, r12.yyyy, l(0, 10, 20, 30) + mov r15.x, r12.y + and r15.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r13.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r15.yzw, r12.zzzz, l(0, 10, 20, 30) + mov r15.x, r12.z + and r15.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r11.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r15.yzw, r12.wwww, l(0, 10, 20, 30) + mov r15.x, r12.w + and r15.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r14.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r12.yzw, r12.xxxx, l(0, 10, 20, 30) + and r15.xyzw, r12.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r12.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r15.xyzw, r12.yyyz, l(10, 20, 30, 30) + mov r16.x, r12.y + mov r16.yz, r15.xxyx + and r6.yzw, r16.xxyz, l(0, 1023, 1023, 1023) + and r17.xyz, r16.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r16.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r16.xyz, l(7, 7, 7, 0), r19.xyzx, r16.xyzx, l(0, 0, 0, 0) + and r16.xyz, r16.xyzx, l(127, 127, 127, 0) + movc r16.xyz, r18.xyzx, r17.xyzx, r16.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r16.xyz, r16.xyzx, l(16, 16, 16, 0) + iadd r16.xyz, r17.xyzx, r16.xyzx + movc r13.xyz, r6.yzwy, r16.xyzx, l(0,0,0,0) + utof r5.xy, r15.zwzz + ushr r15.xyzw, r12.zwwz, l(10, 10, 20, 20) + mov r16.x, r12.z + mov r16.yz, r15.xxwx + and r6.yzw, r16.xxyz, l(0, 1023, 1023, 1023) + and r17.xyz, r16.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r16.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r16.xyz, l(7, 7, 7, 0), r19.xyzx, r16.xyzx, l(0, 0, 0, 0) + and r16.xyz, r16.xyzx, l(127, 127, 127, 0) + movc r16.xyz, r18.xyzx, r17.xyzx, r16.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r16.xyz, r16.xyzx, l(16, 16, 16, 0) + iadd r16.xyz, r17.xyzx, r16.xyzx + movc r11.xyz, r6.yzwy, r16.xyzx, l(0,0,0,0) + mul r5.xy, r5.xyxx, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r15.x, r12.w + and r6.yzw, r15.xxyz, l(0, 1023, 1023, 1023) + and r16.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r17.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r18.xyz, r16.xyzx + iadd r18.xyz, r18.xyzx, l(-24, -24, -24, 0) + movc r18.xyz, r16.xyzx, r18.xyzx, l(8,8,8,0) + iadd r19.xyz, -r18.xyzx, l(1, 1, 1, 0) + movc r19.xyz, r17.xyzx, r17.xyzx, r19.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r18.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r17.xyzx, r16.xyzx, r15.xyzx + ishl r16.xyz, r19.xyzx, l(23, 23, 23, 0) + iadd r16.xyz, r16.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r16.xyzx, r15.xyzx + movc r14.xyz, r6.yzwy, r15.xyzx, l(0,0,0,0) + ushr r15.xyzw, r12.wxxx, l(30, 10, 20, 30) + utof r6.yz, r15.xxwx + mov r15.x, r12.x + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r12.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + mul r6.yz, r6.yyzy, l(0.000000, 0.333333, 0.333333, 0.000000) + mov r13.w, r5.x + mov r11.w, r5.y + mov r14.w, r6.y + mov r12.w, r6.z + break + case l(4) + ishl r15.xyzw, r12.yzwx, l(16, 16, 16, 16) + mov r16.xz, r15.xxyx + mov r16.yw, r12.yyyz + ishr r16.xyzw, r16.xyzw, l(16, 16, 16, 16) + itof r16.xyzw, r16.xyzw + mul r16.xyzw, r16.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r13.xy, r16.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r11.xy, r16.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r12.yz, r15.zzwz + ishr r15.xyzw, r12.ywzx, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xy, r15.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r12.xy, r15.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r13.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r12.zw, l(0,0,0,0) + break + case l(6) + ushr r15.xyzw, r12.yzwx, l(16, 16, 16, 16) + f16tof32 r13.x, r12.y + f16tof32 r13.y, r15.x + f16tof32 r11.x, r12.z + f16tof32 r11.y, r15.y + f16tof32 r14.x, r12.w + f16tof32 r14.y, r15.z + f16tof32 r12.x, r12.x + f16tof32 r12.y, r15.w + mov r13.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r12.zw, l(0,0,0,0) + break + default + mov r13.x, r12.y + mov r13.yzw, l(0,0,0,0) + mov r11.x, r12.z + mov r11.yzw, l(0,0,0,0) + mov r14.x, r12.w + mov r14.yzw, l(0,0,0,0) + mov r12.yzw, l(0,0,0,0) + break + endswitch + endif + add r13.xyzw, r9.xyzw, r13.xyzw + add r11.xyzw, r7.xyzw, r11.xyzw + add r14.xyzw, r10.xyzw, r14.xyzw + add r12.xyzw, r8.xyzw, r12.xyzw + iadd r0.x, r3.w, r4.y + if_nz r5.w + ieq r3.w, r2.z, l(2) + if_nz r3.w + ishl r3.w, r0.x, l(2) + ld_raw r15.xyzw, r3.w, T0[0].zwxy + iadd r3.w, r3.w, l(16) + ld_raw r16.xyzw, r3.w, T0[0].zwxy + mov r17.xy, r15.zwzz + mov r18.xy, r16.zwzz + else + ishl r3.w, r0.x, l(2) + ld_raw r17.xy, r3.w, T0[0].xyxx + iadd r3.w, r2.z, r0.x + ishl r3.w, r3.w, l(2) + ld_raw r15.xy, r3.w, T0[0].xyxx + ishl r4.yw, l(0, 2, 0, 3), r1.yyyy + iadd r4.yw, r0.xxxx, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r18.xy, r4.y, T0[0].xyxx + ld_raw r16.xy, r4.w, T0[0].xyxx + endif + switch r5.z + case l(5) + ishl r17.zw, r17.xxxy, l(0, 0, 16, 16) + ishr r19.xyzw, r17.zxwy, l(16, 16, 16, 16) + itof r19.xyzw, r19.xyzw + mul r19.xyzw, r19.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r17.xyzw, r19.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r15.zw, r15.xxxy, l(0, 0, 16, 16) + ishr r19.xyzw, r15.zxwy, l(16, 16, 16, 16) + itof r19.xyzw, r19.xyzw + mul r19.xyzw, r19.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r15.xyzw, r19.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r18.zw, r18.xxxy, l(0, 0, 16, 16) + ishr r19.xyzw, r18.zxwy, l(16, 16, 16, 16) + itof r19.xyzw, r19.xyzw + mul r19.xyzw, r19.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r18.xyzw, r19.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r16.zw, r16.xxxy, l(0, 0, 16, 16) + ishr r19.xyzw, r16.zxwy, l(16, 16, 16, 16) + itof r19.xyzw, r19.xyzw + mul r19.xyzw, r19.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r16.xyzw, r19.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.yw, r17.xxxy, l(0, 16, 0, 16) + f16tof32 r17.xz, r17.xxyx + f16tof32 r17.yw, r4.yyyw + ushr r4.yw, r15.xxxy, l(0, 16, 0, 16) + f16tof32 r15.xz, r15.xxyx + f16tof32 r15.yw, r4.yyyw + ushr r4.yw, r18.xxxy, l(0, 16, 0, 16) + f16tof32 r18.xz, r18.xxyx + f16tof32 r18.yw, r4.yyyw + ushr r4.yw, r16.xxxy, l(0, 16, 0, 16) + f16tof32 r16.xz, r16.xxyx + f16tof32 r16.yw, r4.yyyw + break + default + mov r17.zw, l(0,0,0,0) + mov r15.zw, l(0,0,0,0) + mov r18.zw, l(0,0,0,0) + mov r16.zw, l(0,0,0,0) + break + endswitch + else + ieq r3.w, r2.z, l(1) + if_nz r3.w + ishl r3.w, r0.x, l(2) + ld_raw r16.xyzw, r3.w, T0[0].wxyz + else + ishl r3.w, r0.x, l(2) + ld_raw r16.y, r3.w, T0[0].xxxx + iadd r2.z, r2.z, r0.x + ishl r2.z, r2.z, l(2) + ld_raw r16.z, r2.z, T0[0].xxxx + ishl r4.yw, l(0, 2, 0, 3), r1.yyyy + iadd r4.yw, r0.xxxx, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r16.w, r4.y, T0[0].xxxx + ld_raw r16.x, r4.w, T0[0].xxxx + endif + switch r5.z + case l(0) + case l(1) + ushr r5.yzw, r16.yyyy, l(0, 8, 16, 24) + mov r5.x, r16.y + and r5.xyzw, r5.xyzw, l(255, 255, 255, 255) + utof r5.xyzw, r5.xyzw + mul r17.xyzw, r5.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r5.yzw, r16.zzzz, l(0, 8, 16, 24) + mov r5.x, r16.z + and r5.xyzw, r5.xyzw, l(255, 255, 255, 255) + utof r5.xyzw, r5.xyzw + mul r15.xyzw, r5.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r5.yzw, r16.wwww, l(0, 8, 16, 24) + mov r5.x, r16.w + and r5.xyzw, r5.xyzw, l(255, 255, 255, 255) + utof r5.xyzw, r5.xyzw + mul r18.xyzw, r5.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r16.yzw, r16.xxxx, l(0, 8, 16, 24) + and r5.xyzw, r16.xyzw, l(255, 255, 255, 255) + utof r5.xyzw, r5.xyzw + mul r16.xyzw, r5.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r5.yzw, r16.yyyy, l(0, 10, 20, 30) + mov r5.x, r16.y + and r5.xyzw, r5.xyzw, l(1023, 1023, 1023, 3) + utof r5.xyzw, r5.xyzw + mul r17.xyzw, r5.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r5.yzw, r16.zzzz, l(0, 10, 20, 30) + mov r5.x, r16.z + and r5.xyzw, r5.xyzw, l(1023, 1023, 1023, 3) + utof r5.xyzw, r5.xyzw + mul r15.xyzw, r5.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r5.yzw, r16.wwww, l(0, 10, 20, 30) + mov r5.x, r16.w + and r5.xyzw, r5.xyzw, l(1023, 1023, 1023, 3) + utof r5.xyzw, r5.xyzw + mul r18.xyzw, r5.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r16.yzw, r16.xxxx, l(0, 10, 20, 30) + and r5.xyzw, r16.xyzw, l(1023, 1023, 1023, 3) + utof r5.xyzw, r5.xyzw + mul r16.xyzw, r5.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r5.xyzw, r16.yyyz, l(10, 20, 30, 30) + mov r19.x, r16.y + mov r19.yz, r5.xxyx + and r6.yzw, r19.xxyz, l(0, 1023, 1023, 1023) + and r20.xyz, r19.xyzx, l(127, 127, 127, 0) + ubfe r21.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r19.xyzx + firstbit_hi r22.xyz, r20.xyzx + iadd r22.xyz, r22.xyzx, l(-24, -24, -24, 0) + movc r22.xyz, r20.xyzx, r22.xyzx, l(8,8,8,0) + iadd r23.xyz, -r22.xyzx, l(1, 1, 1, 0) + movc r23.xyz, r21.xyzx, r21.xyzx, r23.xyzx + bfi r19.xyz, l(7, 7, 7, 0), r22.xyzx, r19.xyzx, l(0, 0, 0, 0) + and r19.xyz, r19.xyzx, l(127, 127, 127, 0) + movc r19.xyz, r21.xyzx, r20.xyzx, r19.xyzx + ishl r20.xyz, r23.xyzx, l(23, 23, 23, 0) + iadd r20.xyz, r20.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r19.xyz, r19.xyzx, l(16, 16, 16, 0) + iadd r19.xyz, r20.xyzx, r19.xyzx + movc r17.xyz, r6.yzwy, r19.xyzx, l(0,0,0,0) + utof r4.yw, r5.zzzw + ushr r5.xyzw, r16.zwwz, l(10, 10, 20, 20) + mov r19.x, r16.z + mov r19.yz, r5.xxwx + and r6.yzw, r19.xxyz, l(0, 1023, 1023, 1023) + and r20.xyz, r19.xyzx, l(127, 127, 127, 0) + ubfe r21.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r19.xyzx + firstbit_hi r22.xyz, r20.xyzx + iadd r22.xyz, r22.xyzx, l(-24, -24, -24, 0) + movc r22.xyz, r20.xyzx, r22.xyzx, l(8,8,8,0) + iadd r23.xyz, -r22.xyzx, l(1, 1, 1, 0) + movc r23.xyz, r21.xyzx, r21.xyzx, r23.xyzx + bfi r19.xyz, l(7, 7, 7, 0), r22.xyzx, r19.xyzx, l(0, 0, 0, 0) + and r19.xyz, r19.xyzx, l(127, 127, 127, 0) + movc r19.xyz, r21.xyzx, r20.xyzx, r19.xyzx + ishl r20.xyz, r23.xyzx, l(23, 23, 23, 0) + iadd r20.xyz, r20.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r19.xyz, r19.xyzx, l(16, 16, 16, 0) + iadd r19.xyz, r20.xyzx, r19.xyzx + movc r15.xyz, r6.yzwy, r19.xyzx, l(0,0,0,0) + mul r4.yw, r4.yyyw, l(0.000000, 0.333333, 0.000000, 0.333333) + mov r5.x, r16.w + and r6.yzw, r5.xxyz, l(0, 1023, 1023, 1023) + and r19.xyz, r5.xyzx, l(127, 127, 127, 0) + ubfe r20.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r5.xyzx + firstbit_hi r21.xyz, r19.xyzx + iadd r21.xyz, r21.xyzx, l(-24, -24, -24, 0) + movc r21.xyz, r19.xyzx, r21.xyzx, l(8,8,8,0) + iadd r22.xyz, -r21.xyzx, l(1, 1, 1, 0) + movc r22.xyz, r20.xyzx, r20.xyzx, r22.xyzx + bfi r5.xyz, l(7, 7, 7, 0), r21.xyzx, r5.xyzx, l(0, 0, 0, 0) + and r5.xyz, r5.xyzx, l(127, 127, 127, 0) + movc r5.xyz, r20.xyzx, r19.xyzx, r5.xyzx + ishl r19.xyz, r22.xyzx, l(23, 23, 23, 0) + iadd r19.xyz, r19.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r5.xyz, r5.xyzx, l(16, 16, 16, 0) + iadd r5.xyz, r19.xyzx, r5.xyzx + movc r18.xyz, r6.yzwy, r5.xyzx, l(0,0,0,0) + ushr r5.xyzw, r16.wxxx, l(30, 10, 20, 30) + utof r6.yz, r5.xxwx + mov r5.x, r16.x + and r19.xyz, r5.xyzx, l(1023, 1023, 1023, 0) + and r20.xyz, r5.xyzx, l(127, 127, 127, 0) + ubfe r21.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r5.xyzx + firstbit_hi r22.xyz, r20.xyzx + iadd r22.xyz, r22.xyzx, l(-24, -24, -24, 0) + movc r22.xyz, r20.xyzx, r22.xyzx, l(8,8,8,0) + iadd r23.xyz, -r22.xyzx, l(1, 1, 1, 0) + movc r23.xyz, r21.xyzx, r21.xyzx, r23.xyzx + bfi r5.xyz, l(7, 7, 7, 0), r22.xyzx, r5.xyzx, l(0, 0, 0, 0) + and r5.xyz, r5.xyzx, l(127, 127, 127, 0) + movc r5.xyz, r21.xyzx, r20.xyzx, r5.xyzx + ishl r20.xyz, r23.xyzx, l(23, 23, 23, 0) + iadd r20.xyz, r20.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r5.xyz, r5.xyzx, l(16, 16, 16, 0) + iadd r5.xyz, r20.xyzx, r5.xyzx + movc r16.xyz, r19.xyzx, r5.xyzx, l(0,0,0,0) + mul r5.xy, r6.yzyy, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r17.w, r4.y + mov r15.w, r4.w + mov r18.w, r5.x + mov r16.w, r5.y + break + case l(4) + ishl r5.xyzw, r16.yzwx, l(16, 16, 16, 16) + mov r19.xz, r5.xxyx + mov r19.yw, r16.yyyz + ishr r19.xyzw, r19.xyzw, l(16, 16, 16, 16) + itof r19.xyzw, r19.xyzw + mul r19.xyzw, r19.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r17.xy, r19.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r15.xy, r19.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r16.yz, r5.zzwz + ishr r5.xyzw, r16.ywzx, l(16, 16, 16, 16) + itof r5.xyzw, r5.xyzw + mul r5.xyzw, r5.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r18.xy, r5.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r16.xy, r5.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r17.zw, l(0,0,0,0) + mov r15.zw, l(0,0,0,0) + mov r18.zw, l(0,0,0,0) + mov r16.zw, l(0,0,0,0) + break + case l(6) + ushr r5.xyzw, r16.yzwx, l(16, 16, 16, 16) + f16tof32 r17.x, r16.y + f16tof32 r17.y, r5.x + f16tof32 r15.x, r16.z + f16tof32 r15.y, r5.y + f16tof32 r18.x, r16.w + f16tof32 r18.y, r5.z + f16tof32 r16.x, r16.x + f16tof32 r16.y, r5.w + mov r17.zw, l(0,0,0,0) + mov r15.zw, l(0,0,0,0) + mov r18.zw, l(0,0,0,0) + mov r16.zw, l(0,0,0,0) + break + default + mov r17.x, r16.y + mov r17.yzw, l(0,0,0,0) + mov r15.x, r16.z + mov r15.yzw, l(0,0,0,0) + mov r18.x, r16.w + mov r18.yzw, l(0,0,0,0) + mov r16.yzw, l(0,0,0,0) + break + endswitch + endif + add r9.xyzw, r13.xyzw, r17.xyzw + add r7.xyzw, r11.xyzw, r15.xyzw + add r10.xyzw, r14.xyzw, r18.xyzw + add r8.xyzw, r12.xyzw, r16.xyzw + else + mov r0.y, r2.w + endif +endif +mul r5.xyzw, r0.yyyy, r9.xyzw +mul r7.xyzw, r0.yyyy, r7.xyzw +mul r9.xyzw, r0.yyyy, r10.xyzw +mul r8.xyzw, r0.yyyy, r8.xyzw +if_nz r1.z + mov r5.xz, r5.zzxz + mov r7.xz, r7.zzxz + mov r9.xz, r9.zzxz + mov r10.xz, r8.zzxz +else + mov r10.xz, r8.xxzx +endif +switch r6.x + case l(6) + case l(14) + case l(50) + mov_sat r5.xyzw, r5.xyzw + mad r6.xyzw, r5.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r6.xyzw, r6.xyzw + imad r0.x, r6.y, l(256), r6.x + imad r0.x, r6.z, l(0x00010000), r0.x + imad r6.x, r6.w, l(0x01000000), r0.x + mov_sat r7.xyzw, r7.xyzw + mad r11.xyzw, r7.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r11.xyzw, r11.xyzw + imad r0.x, r11.y, l(256), r11.x + imad r0.x, r11.z, l(0x00010000), r0.x + imad r6.y, r11.w, l(0x01000000), r0.x + mov_sat r9.xyzw, r9.xyzw + mad r11.xyzw, r9.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r11.xyzw, r11.xyzw + imad r0.x, r11.y, l(256), r11.x + imad r0.x, r11.z, l(0x00010000), r0.x + imad r6.z, r11.w, l(0x01000000), r0.x + mov r10.yw, r8.yyyw + mov_sat r10.xyzw, r10.xyzw + mad r11.xyzw, r10.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r11.xyzw, r11.xyzw + imad r0.x, r11.y, l(256), r11.x + imad r0.x, r11.z, l(0x00010000), r0.x + imad r10.x, r11.w, l(0x01000000), r0.x + mov r10.yzw, r6.yyxz + break + case l(7) + case l(54) + mov_sat r5.xyzw, r5.xyzw + mad r6.xyzw, r5.xyzw, l(1023.000000, 1023.000000, 1023.000000, 3.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r6.xyzw, r6.xyzw + imad r0.x, r6.y, l(1024), r6.x + imad r0.x, r6.z, l(0x00100000), r0.x + imad r6.x, r6.w, l(0x40000000), r0.x + mov_sat r7.xyzw, r7.xyzw + mad r11.xyzw, r7.xyzw, l(1023.000000, 1023.000000, 1023.000000, 3.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r11.xyzw, r11.xyzw + imad r0.x, r11.y, l(1024), r11.x + imad r0.x, r11.z, l(0x00100000), r0.x + imad r6.y, r11.w, l(0x40000000), r0.x + mov_sat r9.xyzw, r9.xyzw + mad r11.xyzw, r9.xyzw, l(1023.000000, 1023.000000, 1023.000000, 3.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r11.xyzw, r11.xyzw + imad r0.x, r11.y, l(1024), r11.x + imad r0.x, r11.z, l(0x00100000), r0.x + imad r6.z, r11.w, l(0x40000000), r0.x + mov_sat r8.xz, r10.xxzx + mov_sat r8.yw, r8.yyyw + mad r11.xyzw, r8.xyzw, l(1023.000000, 1023.000000, 1023.000000, 3.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r11.xyzw, r11.xyzw + imad r0.x, r11.y, l(1024), r11.x + imad r0.x, r11.z, l(0x00100000), r0.x + imad r10.x, r11.w, l(0x40000000), r0.x + mov r10.yzw, r6.yyxz + break + case l(16) + case l(55) + mov_sat r5.xyz, r5.xyzx + mad r6.xyz, r5.xyzx, l(2047.000000, 2047.000000, 1023.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) + ftou r6.xyz, r6.xyzx + imad r0.x, r6.y, l(2048), r6.x + imad r6.x, r6.z, l(0x00400000), r0.x + mov_sat r7.xyz, r7.xyzx + mad r11.xyz, r7.xyzx, l(2047.000000, 2047.000000, 1023.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) + ftou r11.xyz, r11.xyzx + imad r0.x, r11.y, l(2048), r11.x + imad r6.y, r11.z, l(0x00400000), r0.x + mov_sat r9.xyz, r9.xyzx + mad r11.xyz, r9.xyzx, l(2047.000000, 2047.000000, 1023.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) + ftou r11.xyz, r11.xyzx + imad r0.x, r11.y, l(2048), r11.x + imad r6.z, r11.z, l(0x00400000), r0.x + mov_sat r8.xz, r10.xxzx + mov_sat r8.y, r8.y + mad r11.xyz, r8.xyzx, l(2047.000000, 2047.000000, 1023.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) + ftou r11.xyz, r11.xyzx + imad r0.x, r11.y, l(2048), r11.x + imad r10.x, r11.z, l(0x00400000), r0.x + mov r10.yzw, r6.yyxz + break + case l(17) + case l(56) + mov_sat r5.xyz, r5.xyzx + mad r6.xyz, r5.xyzx, l(1023.000000, 2047.000000, 2047.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) + ftou r6.xyz, r6.xyzx + imad r0.x, r6.y, l(1024), r6.x + imad r6.x, r6.z, l(0x00200000), r0.x + mov_sat r7.xyz, r7.xyzx + mad r11.xyz, r7.xyzx, l(1023.000000, 2047.000000, 2047.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) + ftou r11.xyz, r11.xyzx + imad r0.x, r11.y, l(1024), r11.x + imad r6.y, r11.z, l(0x00200000), r0.x + mov_sat r9.xyz, r9.xyzx + mad r11.xyz, r9.xyzx, l(1023.000000, 2047.000000, 2047.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) + ftou r11.xyz, r11.xyzx + imad r0.x, r11.y, l(1024), r11.x + imad r6.z, r11.z, l(0x00200000), r0.x + mov_sat r8.xz, r10.xxzx + mov_sat r8.y, r8.y + mad r11.xyz, r8.xyzx, l(1023.000000, 2047.000000, 2047.000000, 0.000000), l(0.500000, 0.500000, 0.500000, 0.000000) + ftou r11.xyz, r11.xyzx + imad r0.x, r11.y, l(1024), r11.x + imad r10.x, r11.z, l(0x00200000), r0.x + mov r10.yzw, r6.yyxz + break + case l(25) + mov_sat r5.xy, r5.xyxx + mad r0.xy, r5.xyxx, l(65535.000000, 65535.000000, 0.000000, 0.000000), l(0.500000, 0.500000, 0.000000, 0.000000) + ftou r0.xy, r0.xyxx + imad r10.z, r0.y, l(0x00010000), r0.x + mov_sat r7.xy, r7.xyxx + mad r0.xy, r7.xyxx, l(65535.000000, 65535.000000, 0.000000, 0.000000), l(0.500000, 0.500000, 0.000000, 0.000000) + ftou r0.xy, r0.xyxx + imad r10.y, r0.y, l(0x00010000), r0.x + mov_sat r9.xy, r9.xyxx + mad r0.xy, r9.xyxx, l(65535.000000, 65535.000000, 0.000000, 0.000000), l(0.500000, 0.500000, 0.000000, 0.000000) + ftou r0.xy, r0.xyxx + imad r10.w, r0.y, l(0x00010000), r0.x + mov_sat r8.x, r10.x + mov_sat r8.y, r8.y + mad r0.xy, r8.xyxx, l(65535.000000, 65535.000000, 0.000000, 0.000000), l(0.500000, 0.500000, 0.000000, 0.000000) + ftou r0.xy, r0.xyxx + imad r10.x, r0.y, l(0x00010000), r0.x + break + case l(31) + f32tof16 r0.xy, r5.xyxx + imad r10.z, r0.y, l(0x00010000), r0.x + f32tof16 r0.xy, r7.xyxx + imad r10.y, r0.y, l(0x00010000), r0.x + f32tof16 r0.xy, r9.xyxx + imad r10.w, r0.y, l(0x00010000), r0.x + f32tof16 r0.x, r10.x + f32tof16 r0.y, r8.y + imad r10.x, r0.y, l(0x00010000), r0.x + break + default + mov r10.z, r5.x + mov r10.y, r7.x + mov r10.w, r9.x + break +endswitch +ieq r0.x, r4.x, l(0) +ine r0.y, r1.x, l(0) +and r0.x, r0.y, r0.x +if_nz r0.x + uge r0.x, r1.x, l(2) + if_nz r0.x + uge r0.x, r1.x, l(3) + if_nz r0.x + mov r10.w, r10.x + endif + mov r10.yw, r10.wwww + endif + mov r10.yzw, r10.yyyw +endif +mov r4.z, vThreadID.y +imad r1.yz, r3.xxzx, r2.xxyx, r4.xxzx +ushr r1.x, r1.y, l(2) +udiv r0.xy, null, r1.xzxx, r2.xyxx +ishl r1.y, r0.x, l(2) +if_nz r0.w + ubfe r0.w, l(3), l(4), CB0[0][0].z + ishl r2.z, r3.y, l(5) + ishr r3.xy, r0.yyyy, l(4, 3, 0, 0) + ishr r2.w, r0.w, l(2) + ushr r2.z, r2.z, l(4) + and r2.z, r2.z, l(2046) + imad r2.z, r2.w, r2.z, r3.x + ushr r3.x, r1.w, l(5) + ibfe r3.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), r0.xxxx + imad r2.z, r2.z, r3.x, r3.z + ishl r3.x, r0.y, l(10) + and r3.x, r3.x, l(6144) + bfi r3.x, l(3), l(8), r1.y, r3.x + ishr r3.x, r3.x, l(6) + iadd r2.w, r2.w, r3.y + bfi r3.y, l(1), l(1), r2.w, l(0) + iadd r3.y, r3.y, r3.w + bfi r3.y, l(2), l(1), r3.y, l(0) + bfi r2.w, l(1), l(0), r2.w, r3.y + bfi r3.yz, l(0, 20, 20, 0), l(0, 10, 13, 0), r2.zzzz, l(0, 0, 0, 0) + imad r3.xy, r3.xxxx, l(2, 16, 0, 0), r3.yzyy + bfi r3.xy, l(2, 2, 0, 0), l(8, 11, 0, 0), r0.wwww, r3.xyxx + bfi r0.w, l(1), l(4), r0.y, l(0) + ubfe r2.z, l(3), l(6), r3.x + and r3.z, r2.w, l(6) + bfi r2.w, l(1), l(8), r2.w, l(0) + imad r2.z, r2.z, l(32), r2.w + imad r2.z, r3.z, l(4), r2.z + bfi r3.xy, l(5, 5, 0, 0), l(0, 3, 0, 0), r0.wwww, r3.xyxx + bfi r0.w, l(9), l(3), r2.z, r3.y + bfi r0.w, l(6), l(0), r3.x, r0.w +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), r0.xxxx + ishr r3.xy, r0.yyyy, l(5, 2, 0, 0) + ushr r1.w, r1.w, l(5) + imad r1.w, r3.x, r1.w, r2.z + ishl r3.xz, r0.yyyy, l(5, 0, 7, 0) + and r3.xz, r3.xxzx, l(448, 0, 2048, 0) + bfi r2.z, l(3), l(3), r1.y, r3.x + bfi r2.z, l(23), l(9), r1.w, r2.z + bfi r3.w, l(1), l(4), r0.y, l(0) + iadd r2.z, r2.z, r3.w + ishl r4.xy, r3.xxxx, l(3, 2, 0, 0) + bfi r4.xy, l(3, 3, 0, 0), l(6, 5, 0, 0), r1.yyyy, r4.xyxx + bfi r1.yw, l(0, 23, 0, 23), l(0, 12, 0, 11), r1.wwww, r4.xxxy + imad r1.yw, r3.wwww, l(0, 8, 0, 4), r1.yyyw + bfi r1.y, l(12), l(0), r3.z, r1.y + and r1.w, r1.w, l(1792) + iadd r1.y, r1.y, r1.w + and r1.w, r3.y, l(2) + iadd r1.w, r2.w, r1.w + bfi r1.w, l(2), l(6), r1.w, l(0) + iadd r1.y, r1.y, r1.w + bfi r0.w, l(6), l(0), r2.z, r1.y +endif +imad r0.xy, -r0.xyxx, r2.xyxx, r1.xzxx +imul null, r1.x, r2.y, r2.x +imad r0.x, r0.x, r2.y, r0.y +ishl r0.x, r0.x, l(4) +imad r0.x, r0.w, r1.x, r0.x +ushr r0.x, r0.x, l(4) +ieq r0.yzw, r0.zzzz, l(0, 1, 2, 3) +or r0.yz, r0.zzwz, r0.yyzy +if_nz r0.y + ishl r1.xyzw, r10.zywx, l(8, 8, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r2.xyzw, r10.zywx, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r10.xyzw, r1.wyxz, r2.wyxz +endif +if_nz r0.z + ushr r1.xyzw, r10.zywx, l(16, 16, 16, 16) + bfi r10.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r10.xyzw, r1.wyxz +endif +store_uav_typed U0[0].xyzw, r0.xxxx, r10.zywx +ret +// Approximately 1367 instruction slots used +#endif + +const BYTE resolve_full_32bpp_scaled_cs[] = { + 68, 88, 66, 67, 136, 129, 86, 240, 253, 192, 179, 46, 56, 77, 127, 51, 104, 158, 97, + 246, 1, 0, 0, 0, 36, 165, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 144, 2, + 0, 0, 160, 2, 0, 0, 176, 2, 0, 0, 136, 164, 0, 0, 82, 68, 69, 70, 84, + 2, 0, 0, 1, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 44, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 101, 100, 114, 97, 109, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 213, 0, 0, 0, 4, 0, 0, 0, 252, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 156, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 220, 1, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 247, 1, 0, 0, 8, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 12, 2, 0, 0, 12, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, + 114, 101, 115, 111, 108, 118, 101, 95, 101, 100, 114, 97, 109, 95, 105, 110, 102, 111, 0, + 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 178, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 99, 111, 111, 114, + 100, 105, 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 100, 101, 115, 116, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 99, 111, 111, 114, 100, 105, 110, 97, + 116, 101, 95, 105, 110, 102, 111, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 83, 72, 69, 88, 208, 161, 0, 0, 81, 0, 5, 0, 116, 40, 0, + 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 161, 0, 0, 6, 70, + 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 156, 8, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 68, 68, 0, 0, 0, 0, 0, 0, 95, 0, 0, 2, 50, 0, 2, 0, 104, 0, + 0, 2, 24, 0, 0, 0, 155, 0, 0, 4, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, 0, 6, 138, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, + 0, 0, 0, 0, 32, 7, 0, 0, 0, 8, 0, 0, 0, 31, 0, 4, 3, 26, 0, + 16, 0, 0, 0, 0, 0, 138, 0, 0, 17, 50, 0, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 17, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 133, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, + 0, 1, 54, 0, 0, 8, 50, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 138, 0, 0, 17, 114, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 86, 133, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 1, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 1, 85, 0, 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, 214, 143, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, + 0, 10, 0, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 4, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, + 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 3, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 31, 0, + 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, + 0, 0, 17, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, + 11, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, + 0, 13, 0, 0, 0, 24, 0, 0, 0, 28, 0, 0, 0, 6, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 0, 16, 0, 6, + 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 140, 0, 0, 20, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 6, 4, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 139, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, + 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 140, 0, 0, 13, 130, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, + 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 140, 0, 0, 20, 82, 0, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 166, 11, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 17, 50, 0, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 230, 138, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 83, 0, 0, 6, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 2, 0, 35, 0, 0, 9, 194, 0, 16, 0, 2, 0, 0, 0, 166, + 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, + 4, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 31, 0, 4, 3, 26, 0, + 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 7, 0, 0, 0, 26, + 0, 16, 0, 6, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, + 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, + 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 18, 0, 0, 1, 54, + 0, 0, 5, 34, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 1, 21, 0, 0, 1, 80, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 162, 0, 16, 0, 4, + 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 194, 0, 16, + 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 86, 13, 16, 0, 4, 0, + 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 7, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, + 6, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 194, 0, + 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 6, + 0, 0, 0, 38, 0, 0, 11, 0, 208, 0, 0, 98, 0, 16, 0, 7, 0, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 80, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 7, 0, + 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 78, + 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, 166, 14, 16, 0, + 2, 0, 0, 0, 6, 8, 16, 0, 7, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, + 35, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 128, 65, 0, 0, + 0, 6, 0, 0, 0, 6, 8, 16, 0, 7, 0, 0, 0, 166, 14, 16, 0, 2, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 35, 0, 0, 9, + 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, + 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, + 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, + 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 78, 0, 0, 8, 0, 208, 0, 0, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 4, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 7, 66, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, 32, 0, 0, 7, + 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 2, 0, 0, 0, 41, 0, + 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 7, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 8, + 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 9, 0, 0, 0, 230, 10, 16, + 0, 7, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 10, 0, 0, 0, 230, 10, + 16, 0, 8, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 2, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 165, 0, 0, 8, 50, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, + 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, + 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 70, 112, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 86, 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 162, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 41, 0, + 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 165, 0, 0, 8, 50, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, + 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, + 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, + 5, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, + 10, 194, 0, 16, 0, 9, 0, 0, 0, 6, 4, 16, 0, 9, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, + 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 38, 7, 16, 0, 9, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 43, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 7, 0, 0, 0, 6, + 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, + 0, 38, 7, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 11, + 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, + 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, + 194, 0, 16, 0, 10, 0, 0, 0, 6, 4, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, + 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 38, 7, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 43, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 8, 0, 0, 0, 6, 4, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, + 38, 7, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, + 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, + 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, + 4, 0, 0, 0, 6, 4, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, + 16, 0, 9, 0, 0, 0, 6, 1, 16, 0, 9, 0, 0, 0, 131, 0, 0, 5, 162, + 0, 16, 0, 9, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, + 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, + 0, 5, 82, 0, 16, 0, 7, 0, 0, 0, 6, 1, 16, 0, 7, 0, 0, 0, 131, + 0, 0, 5, 162, 0, 16, 0, 7, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, + 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 10, 0, 0, 0, 6, 1, 16, 0, 10, + 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 10, 0, 0, 0, 86, 13, 16, 0, + 4, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 8, 0, 0, 0, 6, + 1, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 8, 0, 0, 0, + 86, 13, 16, 0, 4, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, + 8, 194, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, + 18, 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, + 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, + 242, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 54, 121, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, + 66, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 6, 112, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 162, 0, 16, 0, + 4, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, + 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, + 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, + 8, 18, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 6, 112, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, + 0, 16, 0, 5, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, + 0, 11, 0, 0, 0, 86, 5, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, + 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 85, 0, 0, 10, 226, 0, 16, 0, 11, 0, 0, 0, 166, 10, 16, 0, 8, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, + 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, + 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 11, 0, + 0, 0, 246, 15, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, + 11, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, + 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, + 0, 10, 226, 0, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, + 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, + 0, 16, 0, 11, 0, 0, 0, 86, 5, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, + 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 11, 0, 0, 0, 166, 10, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, + 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, + 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, + 0, 70, 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, + 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, + 11, 0, 0, 0, 246, 15, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, + 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, + 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, + 85, 0, 0, 10, 226, 0, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, + 32, 128, 58, 171, 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, + 3, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 11, 0, 0, 0, 86, 9, 16, 0, 8, 0, 0, 0, 2, 64, + 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, + 54, 0, 0, 5, 98, 0, 16, 0, 12, 0, 0, 0, 6, 1, 16, 0, 11, 0, 0, + 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 12, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 16, 0, 0, + 0, 70, 2, 16, 0, 14, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 16, 0, + 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, + 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, + 16, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 128, 65, + 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, + 16, 0, 17, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 41, 0, + 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, + 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, + 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 55, 0, 0, 12, 114, 0, + 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 0, 0, 5, 162, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, + 0, 11, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 230, 11, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 20, + 0, 0, 0, 20, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, 0, + 42, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 12, 0, 0, + 0, 6, 3, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, 0, + 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, + 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 135, 0, 0, + 5, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 30, 0, + 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, + 55, 0, 0, 12, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, + 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, + 9, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, + 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 140, 0, 0, 17, 114, + 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, + 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, + 16, 0, 12, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, + 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, + 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, + 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, + 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 12, + 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, + 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, + 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 13, + 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, 162, 0, 16, + 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 171, 170, 170, 62, 0, 0, 0, 0, 171, 170, 170, 62, 54, 0, 0, 5, 18, + 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, + 138, 0, 0, 15, 114, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 11, + 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, + 13, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, + 0, 15, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, + 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 15, 0, 0, 0, 70, + 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 11, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, + 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, + 0, 140, 0, 0, 17, 114, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, + 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, + 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, + 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, + 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, + 0, 13, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 23, 0, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, + 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, + 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, + 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 10, 0, 0, + 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 54, 0, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 30, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, + 0, 86, 0, 0, 5, 50, 0, 16, 0, 5, 0, 0, 0, 198, 0, 16, 0, 11, 0, + 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, + 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 14, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 15, + 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, + 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, + 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, + 128, 65, 0, 0, 0, 15, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, + 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, + 70, 2, 16, 0, 16, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 14, + 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, + 41, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, + 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, + 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 12, + 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 70, + 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 9, 0, 0, + 0, 26, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 7, 0, + 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 10, + 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, + 8, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, + 3, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 11, 0, + 0, 0, 150, 3, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, + 12, 0, 0, 0, 6, 1, 16, 0, 11, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, + 0, 12, 0, 0, 0, 86, 9, 16, 0, 8, 0, 0, 0, 42, 0, 0, 10, 242, 0, + 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, + 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, + 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, + 0, 0, 10, 50, 0, 16, 0, 9, 0, 0, 0, 70, 0, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 0, 0, 10, 50, 0, 16, 0, 7, 0, 0, 0, 230, 10, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 8, 0, 0, 0, 166, 11, 16, 0, + 11, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 214, 2, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, + 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 10, 0, + 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, + 8, 0, 0, 0, 230, 10, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, + 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, + 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 150, 3, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, + 26, 0, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 9, 0, 0, + 0, 10, 0, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 7, 0, + 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 7, + 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, + 10, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, + 0, 10, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 18, 0, + 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 34, + 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, 8, + 194, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, + 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, + 54, 0, 0, 8, 226, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, + 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 8, 226, + 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, + 0, 58, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 1, 23, 0, 0, 1, 21, 0, 0, 1, 80, 0, 0, 7, 130, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, + 0, 4, 3, 58, 0, 16, 0, 2, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, + 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 63, 35, 0, 0, 9, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 80, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 31, + 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, 32, 0, 0, 7, 34, 0, 16, 0, + 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 31, 0, 4, 3, 26, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, + 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, + 4, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 16, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 12, 0, 0, 0, 26, + 0, 16, 0, 4, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 50, 0, 16, 0, 13, 0, 0, 0, 230, 10, 16, 0, 11, 0, 0, + 0, 54, 0, 0, 5, 50, 0, 16, 0, 14, 0, 0, 0, 230, 10, 16, 0, 12, 0, + 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 58, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, + 50, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 41, + 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, + 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 11, 0, 0, + 0, 26, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 86, 5, 16, 0, + 1, 0, 0, 0, 30, 0, 0, 7, 162, 0, 16, 0, 4, 0, 0, 0, 246, 15, 16, + 0, 3, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 162, 0, + 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, + 50, 0, 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 12, 0, + 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 5, 0, 0, 0, + 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, + 0, 13, 0, 0, 0, 6, 4, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, + 0, 16, 0, 15, 0, 0, 0, 38, 7, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, + 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 52, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 11, 0, 0, 0, 6, 4, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 38, 7, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, + 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, + 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, + 14, 0, 0, 0, 6, 4, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, + 16, 0, 15, 0, 0, 0, 38, 7, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, + 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, + 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 41, 0, 0, 10, 194, 0, 16, 0, 12, 0, 0, 0, 6, 4, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 38, 7, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, + 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, + 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, + 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, + 6, 4, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 13, 0, + 0, 0, 6, 1, 16, 0, 13, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 13, + 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, + 4, 0, 0, 0, 6, 4, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, + 16, 0, 11, 0, 0, 0, 6, 1, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 162, + 0, 16, 0, 11, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, + 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 14, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, + 0, 5, 82, 0, 16, 0, 14, 0, 0, 0, 6, 1, 16, 0, 14, 0, 0, 0, 131, + 0, 0, 5, 162, 0, 16, 0, 14, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, + 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 12, 0, 0, 0, 6, 1, 16, 0, 12, + 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 12, 0, 0, 0, 86, 13, 16, 0, + 4, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 194, 0, 16, + 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, + 32, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 4, 0, + 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, + 12, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 54, 121, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 34, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, + 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, + 12, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 86, + 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 162, 0, 16, 0, 4, 0, 0, 0, + 246, 15, 16, 0, 3, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 41, 0, 0, + 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 130, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, + 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, + 0, 12, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 5, + 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, + 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, + 0, 86, 5, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, + 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, + 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, + 10, 226, 0, 16, 0, 15, 0, 0, 0, 166, 10, 16, 0, 12, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 246, 15, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, + 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, + 58, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, + 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 14, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, + 16, 0, 12, 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, + 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, + 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 15, + 0, 0, 0, 86, 5, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 15, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, + 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, + 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 166, 10, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, + 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 12, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, + 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, + 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, + 246, 15, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, + 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, + 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, + 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 8, + 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, + 226, 0, 16, 0, 12, 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, + 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, + 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, + 0, 15, 0, 0, 0, 86, 9, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 10, 0, + 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, + 0, 16, 0, 16, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 54, 0, 0, 5, + 98, 0, 16, 0, 16, 0, 0, 0, 6, 1, 16, 0, 15, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, + 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, + 0, 138, 0, 0, 15, 114, 0, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, + 16, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, + 0, 18, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, + 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, + 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 20, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 11, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 20, + 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, + 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, + 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, + 20, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, + 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, + 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, + 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, + 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, + 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 70, 2, 16, 0, 16, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 13, 0, + 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 0, 0, 5, 162, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 15, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 230, 11, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 20, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 16, 0, 0, 0, 42, 0, 16, 0, + 12, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 16, 0, 0, 0, 6, 3, 16, + 0, 15, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, + 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 30, 0, 0, 10, 114, 0, + 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 232, + 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, + 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, + 0, 20, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 21, 0, 0, 0, 70, + 2, 16, 128, 65, 0, 0, 0, 20, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, + 0, 21, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, + 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, + 0, 19, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 21, + 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, + 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, + 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 55, 0, + 0, 12, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, + 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, + 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 171, 170, + 170, 62, 0, 0, 0, 0, 171, 170, 170, 62, 54, 0, 0, 5, 18, 0, 16, 0, 15, + 0, 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, + 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, + 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, + 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 135, + 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, + 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, + 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, 0, 0, + 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, + 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, + 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, + 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, + 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, + 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, + 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, + 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, + 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 15, 0, 0, 0, 54, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 30, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 86, 0, 0, + 5, 50, 0, 16, 0, 5, 0, 0, 0, 198, 0, 16, 0, 15, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 1, + 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, + 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, + 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 15, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, + 2, 16, 0, 17, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, + 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, + 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 11, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, + 0, 19, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, + 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, + 20, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, + 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, + 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, + 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, 10, + 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, + 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, + 41, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, + 12, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 56, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, + 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 11, 0, 0, 0, 58, 0, + 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 14, 0, 0, 0, 10, + 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 12, 0, 0, 0, + 26, 0, 16, 0, 5, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, + 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 150, 3, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 16, 0, 0, 0, + 6, 1, 16, 0, 15, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 16, 0, 0, + 0, 86, 9, 16, 0, 12, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 16, 0, + 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, + 16, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 16, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 1, + 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, + 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, + 10, 50, 0, 16, 0, 11, 0, 0, 0, 230, 10, 16, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 98, 0, 16, 0, 12, 0, 0, 0, 166, 11, 16, 0, 15, 0, 0, 0, + 42, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 214, 2, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 14, 0, 0, 0, 70, 0, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 12, 0, 0, 0, + 230, 10, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 13, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 150, 3, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, + 12, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 13, 0, 0, 0, 10, 0, 16, + 0, 15, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, + 16, 0, 12, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 11, 0, 0, 0, 26, + 0, 16, 0, 15, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, + 58, 0, 16, 0, 12, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 14, 0, 0, + 0, 42, 0, 16, 0, 15, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 12, 0, + 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 12, + 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 5, 18, + 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 54, 0, 0, 8, + 226, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, 0, + 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, + 0, 12, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 14, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 226, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, + 1, 21, 0, 0, 1, 0, 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 0, 0, 0, 7, 242, + 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 0, 0, 0, 7, 242, 0, + 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, + 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 56, 0, 0, 7, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 128, 62, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 58, 0, + 16, 0, 5, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, + 58, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, + 0, 8, 242, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 230, + 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, + 4, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, + 0, 165, 0, 0, 8, 242, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 4, 0, + 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, + 0, 16, 0, 13, 0, 0, 0, 230, 10, 16, 0, 11, 0, 0, 0, 54, 0, 0, 5, + 50, 0, 16, 0, 14, 0, 0, 0, 230, 10, 16, 0, 12, 0, 0, 0, 18, 0, 0, + 1, 41, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 13, + 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, + 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, + 10, 50, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 30, + 0, 0, 7, 50, 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, + 0, 70, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 14, + 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, + 0, 5, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, + 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 5, 0, 0, 0, 6, 0, 0, 3, 1, + 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 13, 0, 0, 0, + 6, 4, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 15, 0, + 0, 0, 38, 7, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, + 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 1, + 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, + 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, + 10, 194, 0, 16, 0, 11, 0, 0, 0, 6, 4, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, + 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 38, 7, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 43, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 14, 0, 0, 0, 6, + 4, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, + 0, 38, 7, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, + 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, + 194, 0, 16, 0, 12, 0, 0, 0, 6, 4, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, + 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 38, 7, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 43, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, + 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 13, 0, 0, 0, 6, 1, 16, + 0, 13, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 13, 0, 0, 0, 6, 4, + 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 70, + 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 11, 0, 0, + 0, 6, 1, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 11, 0, + 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 5, + 0, 0, 0, 70, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, + 0, 14, 0, 0, 0, 6, 1, 16, 0, 14, 0, 0, 0, 131, 0, 0, 5, 162, 0, + 16, 0, 14, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 50, + 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, + 5, 82, 0, 16, 0, 12, 0, 0, 0, 6, 1, 16, 0, 12, 0, 0, 0, 131, 0, + 0, 5, 162, 0, 16, 0, 12, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 2, + 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 194, 0, 16, 0, 13, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, + 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, 130, + 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 12, 0, 0, 0, 58, + 0, 16, 0, 4, 0, 0, 0, 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 34, 0, + 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, 12, 0, 0, 0, 58, + 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, + 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, + 5, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, 0, + 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 6, 112, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 12, 0, 0, 0, + 26, 0, 16, 0, 5, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 5, 0, 0, 0, 6, 0, + 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, + 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 86, 5, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, + 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 26, 0, + 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, + 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, + 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, + 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, + 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, + 15, 0, 0, 0, 166, 10, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, + 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, + 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, + 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 246, 15, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, + 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 12, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, + 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 12, 0, 0, + 0, 6, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, + 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 129, + 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, 1, + 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, + 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 86, 5, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, + 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, + 26, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, + 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, + 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, + 16, 0, 15, 0, 0, 0, 166, 10, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, + 18, 0, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, + 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, + 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 246, 15, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, + 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, + 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, + 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, + 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, + 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 12, + 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 15, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, + 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 2, 0, + 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, 1, + 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, + 86, 9, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 16, 0, + 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 16, + 0, 0, 0, 6, 1, 16, 0, 15, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, + 6, 0, 0, 0, 6, 9, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 114, 0, + 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, + 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 135, + 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, + 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, + 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, 0, 0, + 17, 114, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, + 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, + 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, + 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 70, 2, 16, 0, 16, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, + 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, + 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, + 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, + 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, + 16, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 13, 0, 0, 0, 150, 7, 16, + 0, 6, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 50, + 0, 16, 0, 5, 0, 0, 0, 230, 10, 16, 0, 15, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 15, 0, 0, 0, 230, 11, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 16, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 54, + 0, 0, 5, 98, 0, 16, 0, 16, 0, 0, 0, 6, 3, 16, 0, 15, 0, 0, 0, + 1, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 6, 9, 16, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 16, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 17, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, + 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, + 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 11, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, + 0, 0, 19, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, + 0, 20, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 41, 0, 0, + 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 0, 41, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, + 0, 11, 0, 0, 0, 150, 7, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 16, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 56, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 58, 0, + 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 6, + 9, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 17, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 135, 0, 0, 5, 114, 0, + 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 30, 0, 0, 10, 114, + 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, + 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, + 12, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, + 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 128, 65, 0, 0, 0, 18, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, + 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, + 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, + 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, + 19, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, + 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 15, 0, + 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, + 0, 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 150, 7, 16, 0, 6, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 15, 0, + 0, 0, 54, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 10, + 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 86, 0, 0, 5, 98, 0, 16, 0, + 6, 0, 0, 0, 6, 3, 16, 0, 15, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 15, 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 114, 0, + 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, + 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, + 0, 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, + 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, + 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, + 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, + 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, + 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, + 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, + 0, 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, + 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, + 0, 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, + 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, + 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, + 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, + 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, + 16, 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 12, 0, 0, 0, 70, + 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, + 10, 98, 0, 16, 0, 6, 0, 0, 0, 86, 6, 16, 0, 6, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, 0, 0, 0, 0, 54, + 0, 0, 5, 130, 0, 16, 0, 13, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, + 54, 0, 0, 5, 130, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, + 0, 54, 0, 0, 5, 130, 0, 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, 6, 0, + 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 6, + 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 150, 3, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 16, 0, 0, 0, 6, 1, 16, 0, 15, + 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 16, 0, 0, 0, 86, 9, 16, 0, + 12, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, + 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 16, 0, 0, 0, 70, + 14, 16, 0, 16, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, + 70, 14, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 13, 0, + 0, 0, 70, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, + 11, 0, 0, 0, 230, 10, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 98, 0, + 16, 0, 12, 0, 0, 0, 166, 11, 16, 0, 15, 0, 0, 0, 42, 0, 0, 10, 242, + 0, 16, 0, 15, 0, 0, 0, 214, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, + 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 52, 0, 0, 10, 50, 0, 16, 0, 14, 0, 0, 0, 70, 0, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, + 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 12, 0, 0, 0, 230, 10, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, + 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 15, 0, 0, 0, 150, 3, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, 0, + 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 131, + 0, 0, 5, 34, 0, 16, 0, 13, 0, 0, 0, 10, 0, 16, 0, 15, 0, 0, 0, + 131, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, + 0, 131, 0, 0, 5, 34, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 15, 0, + 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 12, + 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, + 15, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, + 0, 12, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 12, 0, 0, 0, 58, 0, + 16, 0, 15, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 13, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, + 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, + 0, 12, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, + 54, 0, 0, 8, 226, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 226, 0, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, + 0, 0, 0, 7, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, + 0, 70, 14, 16, 0, 13, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 0, + 0, 0, 7, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 14, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 12, 0, 0, + 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 30, 0, + 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 26, + 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, + 32, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 3, 0, + 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, + 15, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 165, 0, 0, 8, 242, + 0, 16, 0, 16, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 230, 116, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 17, 0, 0, + 0, 230, 10, 16, 0, 15, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 18, 0, + 0, 0, 230, 10, 16, 0, 16, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 17, 0, 0, 0, 58, 0, 16, + 0, 3, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, + 8, 50, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 70, 112, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 162, 0, 16, + 0, 4, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 4, 0, + 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 18, 0, 0, 0, 26, 0, 16, + 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, + 0, 8, 50, 0, 16, 0, 16, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 70, + 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, + 42, 0, 16, 0, 5, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, + 0, 41, 0, 0, 10, 194, 0, 16, 0, 17, 0, 0, 0, 6, 4, 16, 0, 17, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 38, 7, 16, 0, + 17, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, + 16, 0, 19, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 70, + 14, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, + 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 15, + 0, 0, 0, 6, 4, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, + 0, 19, 0, 0, 0, 38, 7, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, + 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, 64, 0, + 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, + 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, + 41, 0, 0, 10, 194, 0, 16, 0, 18, 0, 0, 0, 6, 4, 16, 0, 18, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 38, 7, 16, 0, 18, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, + 0, 19, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, + 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, + 70, 14, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 16, 0, + 0, 0, 6, 4, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, + 19, 0, 0, 0, 38, 7, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, + 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, + 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, + 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, 10, + 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 17, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, + 0, 5, 82, 0, 16, 0, 17, 0, 0, 0, 6, 1, 16, 0, 17, 0, 0, 0, 131, + 0, 0, 5, 162, 0, 16, 0, 17, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, + 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 15, 0, 0, 0, 6, 1, 16, 0, 15, + 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 15, 0, 0, 0, 86, 13, 16, 0, + 4, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, + 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 18, 0, 0, 0, 6, + 1, 16, 0, 18, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 18, 0, 0, 0, + 86, 13, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, + 0, 6, 4, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 16, + 0, 0, 0, 6, 1, 16, 0, 16, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, + 16, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, + 1, 54, 0, 0, 8, 194, 0, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, + 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 18, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, + 23, 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, + 4, 3, 58, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 3, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 165, 0, 0, 8, 242, 0, 16, 0, 16, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, + 0, 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, + 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 16, 0, 0, 0, + 58, 0, 16, 0, 3, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 165, 0, 0, 8, 66, 0, 16, 0, 16, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 162, 0, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, + 162, 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 13, 16, + 0, 4, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 16, 0, 0, 0, + 26, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 165, 0, 0, 8, 18, 0, 16, 0, 16, 0, 0, 0, 58, 0, 16, 0, 4, 0, + 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, + 0, 0, 3, 42, 0, 16, 0, 5, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, + 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, + 10, 226, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 16, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, 166, 10, + 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, + 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, + 42, 0, 16, 0, 16, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 15, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, + 16, 0, 5, 0, 0, 0, 246, 15, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, + 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 16, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, + 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, + 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 16, 0, 0, 0, 6, 0, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, + 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 16, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, + 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 85, + 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 16, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, + 0, 54, 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 16, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, + 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, + 166, 10, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, + 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 5, 0, + 0, 0, 42, 0, 16, 0, 16, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, + 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, + 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, + 226, 0, 16, 0, 5, 0, 0, 0, 246, 15, 16, 0, 16, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 16, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, + 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, + 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 16, 0, 0, 0, 6, 0, 16, + 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, + 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 16, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, + 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, + 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 86, 9, 16, 0, 16, 0, + 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 30, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 19, 0, 0, 0, 26, 0, 16, 0, + 16, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 19, 0, 0, 0, 6, 1, 16, + 0, 5, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 6, 9, + 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, + 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 21, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, + 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 30, 0, 0, 10, 114, 0, + 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, 232, + 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, + 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, + 0, 22, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 23, 0, 0, 0, 70, + 2, 16, 128, 65, 0, 0, 0, 22, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, + 0, 23, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, 0, + 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 19, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, + 0, 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 19, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 23, + 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, + 0, 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 55, 0, + 0, 12, 114, 0, 16, 0, 17, 0, 0, 0, 150, 7, 16, 0, 6, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 162, 0, 16, 0, 4, 0, 0, + 0, 166, 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, + 0, 0, 230, 11, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, + 19, 0, 0, 0, 42, 0, 16, 0, 16, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, + 0, 19, 0, 0, 0, 6, 3, 16, 0, 5, 0, 0, 0, 1, 0, 0, 10, 226, 0, + 16, 0, 6, 0, 0, 0, 6, 9, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, + 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, + 0, 15, 114, 0, 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 135, 0, 0, 5, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, + 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, + 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, + 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, + 0, 20, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, + 0, 16, 0, 23, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 22, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 55, 0, 0, 9, 114, 0, 16, 0, 23, 0, 0, 0, 70, 2, 16, 0, 21, 0, + 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 140, + 0, 0, 17, 114, 0, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, + 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, + 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, + 0, 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, + 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 20, + 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, + 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, + 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, + 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, + 16, 0, 19, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 15, 0, 0, 0, 150, + 7, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, + 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 171, 170, 170, 62, 0, 0, 0, 0, 171, 170, 170, 62, 54, + 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 16, 0, 0, 0, + 1, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 6, 9, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 20, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 5, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 21, 0, 0, 0, + 70, 2, 16, 0, 19, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 21, 0, 0, + 0, 70, 2, 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, + 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 21, + 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 11, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 128, 65, 0, + 0, 0, 21, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 22, 0, 0, 0, + 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, + 0, 22, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, + 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 41, 0, 0, + 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 0, 41, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, + 19, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, + 0, 18, 0, 0, 0, 150, 7, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 5, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 54, 0, 16, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 86, 0, 0, 5, 98, 0, 16, 0, 6, 0, 0, 0, 6, 3, + 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 10, + 0, 16, 0, 16, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 20, 0, + 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, + 21, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 135, 0, 0, 5, 114, + 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 30, 0, 0, 10, + 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, + 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, + 0, 12, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, + 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 23, 0, 0, + 0, 70, 2, 16, 128, 65, 0, 0, 0, 22, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, + 0, 16, 0, 23, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, + 21, 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 5, 0, 0, 0, 70, + 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, + 5, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, + 0, 23, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, + 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, + 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, + 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 5, + 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, + 55, 0, 0, 12, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, 50, 0, 16, 0, 5, + 0, 0, 0, 150, 5, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 171, 170, 170, 62, + 171, 170, 170, 62, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, + 0, 17, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, + 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, + 0, 16, 0, 18, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, + 130, 0, 16, 0, 16, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 2, 0, 0, + 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 150, 3, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, + 82, 0, 16, 0, 19, 0, 0, 0, 6, 1, 16, 0, 5, 0, 0, 0, 54, 0, 0, + 5, 162, 0, 16, 0, 19, 0, 0, 0, 86, 9, 16, 0, 16, 0, 0, 0, 42, 0, + 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 43, 0, 0, 5, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 17, 0, 0, 0, 70, 0, 16, 0, + 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, + 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 15, 0, 0, 0, 230, 10, + 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 16, 0, 0, 0, + 166, 11, 16, 0, 5, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 214, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, + 16, 0, 18, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, + 50, 0, 16, 0, 16, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 18, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 194, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, + 3, 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, + 0, 0, 150, 3, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, + 17, 0, 0, 0, 26, 0, 16, 0, 16, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, + 0, 17, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 131, 0, 0, 5, 18, 0, + 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 16, 0, 0, 0, 131, 0, 0, 5, 34, + 0, 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 131, 0, 0, 5, + 18, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 16, 0, 0, 0, 131, 0, 0, + 5, 34, 0, 16, 0, 18, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 131, 0, + 0, 5, 18, 0, 16, 0, 16, 0, 0, 0, 10, 0, 16, 0, 16, 0, 0, 0, 131, + 0, 0, 5, 34, 0, 16, 0, 16, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 18, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, + 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 17, 0, 0, 0, 26, 0, 16, 0, + 16, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 17, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 16, 0, 0, 0, 54, + 0, 0, 8, 226, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 18, 0, 0, 0, 58, 0, 16, 0, 16, 0, 0, 0, 54, 0, 0, 8, 226, 0, + 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 16, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, 0, 0, 0, 7, 242, 0, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 17, + 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 18, 0, + 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, + 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 21, 0, 0, + 1, 21, 0, 0, 1, 56, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, 86, 5, + 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 56, 0, 0, 7, 242, + 0, 16, 0, 7, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 56, 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 86, 5, 16, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 7, 242, 0, + 16, 0, 8, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 8, + 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, + 82, 0, 16, 0, 5, 0, 0, 0, 166, 8, 16, 0, 5, 0, 0, 0, 54, 0, 0, + 5, 82, 0, 16, 0, 7, 0, 0, 0, 166, 8, 16, 0, 7, 0, 0, 0, 54, 0, + 0, 5, 82, 0, 16, 0, 9, 0, 0, 0, 166, 8, 16, 0, 9, 0, 0, 0, 54, + 0, 0, 5, 82, 0, 16, 0, 10, 0, 0, 0, 166, 8, 16, 0, 8, 0, 0, 0, + 18, 0, 0, 1, 54, 0, 0, 5, 82, 0, 16, 0, 10, 0, 0, 0, 6, 2, 16, + 0, 8, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 10, 0, 16, 0, 6, 0, + 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 3, 1, + 64, 0, 0, 14, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 50, 0, 0, 0, + 54, 32, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 50, 0, 0, 15, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 5, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, + 0, 127, 67, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 1, 0, 0, 10, 0, 16, 0, 6, + 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 6, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 1, 10, 0, 16, 0, 0, 0, 0, 0, 54, + 32, 0, 5, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 50, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, + 127, 67, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, + 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 1, 0, 0, 10, 0, 16, 0, 11, 0, + 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 11, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 35, 0, 0, 9, 34, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 1, 10, 0, 16, 0, 0, 0, 0, 0, 54, 32, + 0, 5, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 50, + 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, + 67, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, + 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, + 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 11, 0, 0, 0, 1, 64, 0, 0, 0, 1, 0, 0, 10, 0, 16, 0, 11, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 11, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, 0, 0, 35, + 0, 0, 9, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 1, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 162, 0, 16, 0, 10, 0, 0, 0, 86, 13, 16, 0, 8, 0, 0, 0, 54, 32, + 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 50, + 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, + 67, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, + 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, + 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 11, 0, 0, 0, 1, 64, 0, 0, 0, 1, 0, 0, 10, 0, 16, 0, 11, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 11, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, 0, 0, 35, + 0, 0, 9, 18, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 1, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 226, 0, 16, 0, 10, 0, 0, 0, 86, 8, 16, 0, 6, 0, 0, 0, 2, 0, + 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 6, 0, 0, 3, 1, + 64, 0, 0, 54, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 6, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 192, 127, 68, 0, 192, + 127, 68, 0, 192, 127, 68, 0, 0, 64, 64, 2, 64, 0, 0, 0, 0, 0, 63, 0, + 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, + 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 4, + 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 16, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 6, 0, 0, + 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 10, 0, + 16, 0, 0, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 7, 0, 0, 0, 70, + 14, 16, 0, 7, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, + 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 192, 127, 68, 0, 192, 127, + 68, 0, 192, 127, 68, 0, 0, 64, 64, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, + 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 11, + 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, + 0, 10, 0, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 0, 16, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 6, 0, 0, 0, + 58, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 10, 0, 16, + 0, 0, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 70, + 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 192, 127, 68, 0, 192, 127, 68, + 0, 192, 127, 68, 0, 0, 64, 64, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, + 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, + 10, 0, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 0, 16, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 6, 0, 0, 0, 58, + 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 32, 0, 5, 82, 0, 16, 0, 8, 0, 0, 0, 6, 2, 16, + 0, 10, 0, 0, 0, 54, 32, 0, 5, 162, 0, 16, 0, 8, 0, 0, 0, 86, 13, + 16, 0, 8, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 70, + 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 192, 127, 68, 0, 192, 127, 68, + 0, 192, 127, 68, 0, 0, 64, 64, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, + 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, + 10, 0, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 0, 16, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 10, 0, 0, 0, 58, + 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 226, 0, 16, 0, 10, 0, 0, 0, 86, 8, 16, + 0, 6, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 16, 0, + 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 55, 0, 0, 0, 54, 32, 0, 5, 114, + 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 50, 0, 0, 15, + 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 224, 255, 68, 0, 224, 255, 68, 0, 192, 127, 68, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 28, + 0, 0, 5, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, + 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, + 0, 1, 64, 0, 0, 0, 8, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 35, 0, + 0, 9, 18, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 64, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 32, 0, 5, + 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 50, 0, 0, + 15, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 0, 224, 255, 68, 0, 224, 255, 68, 0, 192, 127, 68, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, + 28, 0, 0, 5, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 11, 0, + 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 35, + 0, 0, 9, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 64, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 32, 0, + 5, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 50, 0, + 0, 15, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, + 64, 0, 0, 0, 224, 255, 68, 0, 224, 255, 68, 0, 192, 127, 68, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, + 0, 28, 0, 0, 5, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, + 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 11, + 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, + 35, 0, 0, 9, 66, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 64, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 32, + 0, 5, 82, 0, 16, 0, 8, 0, 0, 0, 6, 2, 16, 0, 10, 0, 0, 0, 54, + 32, 0, 5, 34, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, + 50, 0, 0, 15, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 0, 224, 255, 68, 0, 224, 255, 68, 0, 192, 127, 68, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, + 0, 0, 0, 28, 0, 0, 5, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, + 11, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 10, 0, 16, 0, 11, 0, + 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 11, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 64, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 226, 0, 16, 0, 10, 0, 0, 0, 86, 8, 16, 0, 6, 0, 0, + 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 17, 0, 0, 0, 6, 0, + 0, 3, 1, 64, 0, 0, 56, 0, 0, 0, 54, 32, 0, 5, 114, 0, 16, 0, 5, + 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, + 6, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 192, 127, + 68, 0, 224, 255, 68, 0, 224, 255, 68, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 28, 0, 0, 5, 114, + 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, + 0, 0, 4, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 18, 0, + 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 32, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 32, 0, 5, 114, 0, 16, 0, + 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 50, 0, 0, 15, 114, 0, 16, + 0, 11, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 192, + 127, 68, 0, 224, 255, 68, 0, 224, 255, 68, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 28, 0, 0, 5, + 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 35, 0, 0, + 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 1, 64, + 0, 0, 0, 4, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 32, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 32, 0, 5, 114, 0, 16, + 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 50, 0, 0, 15, 114, 0, + 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, + 192, 127, 68, 0, 224, 255, 68, 0, 224, 255, 68, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 28, 0, 0, + 5, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 35, 0, + 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 1, + 64, 0, 0, 0, 4, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, + 66, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 32, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 32, 0, 5, 82, 0, + 16, 0, 8, 0, 0, 0, 6, 2, 16, 0, 10, 0, 0, 0, 54, 32, 0, 5, 34, + 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 50, 0, 0, 15, + 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, + 0, 0, 192, 127, 68, 0, 224, 255, 68, 0, 224, 255, 68, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 28, + 0, 0, 5, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, + 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, + 0, 1, 64, 0, 0, 0, 4, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 35, 0, + 0, 9, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 32, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 226, 0, 16, 0, 10, 0, 0, 0, 86, 8, 16, 0, 6, 0, 0, 0, 2, 0, 0, + 1, 6, 0, 0, 3, 1, 64, 0, 0, 25, 0, 0, 0, 54, 32, 0, 5, 50, 0, + 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 50, 0, 0, 15, 50, + 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 0, 255, 127, 71, 0, 255, 127, 71, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, + 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 35, + 0, 0, 9, 66, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 32, 0, + 5, 50, 0, 16, 0, 7, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 50, 0, + 0, 15, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 0, 255, 127, 71, 0, 255, 127, 71, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, + 0, 28, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, + 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 54, 32, 0, 5, 50, 0, 16, 0, 9, 0, 0, 0, 70, 0, 16, 0, 9, 0, 0, + 0, 50, 0, 0, 15, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 9, 0, + 0, 0, 2, 64, 0, 0, 0, 255, 127, 71, 0, 255, 127, 71, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 28, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 10, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 54, 32, 0, 5, 18, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, + 10, 0, 0, 0, 54, 32, 0, 5, 34, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, + 0, 8, 0, 0, 0, 50, 0, 0, 15, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 255, 127, 71, 0, 255, 127, 71, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 10, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, + 31, 0, 0, 0, 130, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 5, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 10, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 130, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 7, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 130, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 9, + 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 130, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 10, 0, + 0, 0, 130, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, + 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 10, 0, + 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 10, + 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, + 10, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, + 1, 32, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 39, 0, 0, 7, 34, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, + 0, 0, 80, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, + 0, 0, 0, 0, 80, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 31, 0, 4, 3, 10, 0, + 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 10, 0, 0, 0, 10, + 0, 16, 0, 10, 0, 0, 0, 21, 0, 0, 1, 54, 0, 0, 5, 162, 0, 16, 0, + 10, 0, 0, 0, 246, 15, 16, 0, 10, 0, 0, 0, 21, 0, 0, 1, 54, 0, 0, + 5, 226, 0, 16, 0, 10, 0, 0, 0, 86, 13, 16, 0, 10, 0, 0, 0, 21, 0, + 0, 1, 54, 0, 0, 4, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 2, 0, 35, + 0, 0, 9, 98, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 78, 0, 0, 8, 50, 0, 16, 0, 0, 0, 0, 0, 0, + 208, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, + 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, + 0, 0, 138, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, + 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 254, 7, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 139, 0, 0, 15, + 194, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 35, + 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, + 7, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 10, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 24, 0, 0, 140, 0, 0, 11, + 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 8, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, + 0, 140, 0, 0, 11, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, + 26, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 20, 98, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, + 0, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 50, 0, + 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 2, + 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, + 3, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 138, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, + 1, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, + 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 32, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 66, 0, + 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 3, + 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, + 139, 0, 0, 15, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 130, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 82, 0, 16, + 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 82, + 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 192, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 140, 0, 0, + 11, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, + 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 23, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, + 0, 3, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 6, 0, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 140, + 0, 0, 17, 162, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 23, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 12, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 246, 15, 16, 0, 1, 0, + 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 35, 0, 0, 12, 162, 0, 16, 0, 1, + 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, + 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 35, 0, 0, 10, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 2, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 38, 0, 0, 8, 0, 208, + 0, 0, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, 0, 9, 18, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 32, 0, 0, 10, 226, 0, 16, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, + 3, 0, 0, 0, 60, 0, 0, 7, 98, 0, 16, 0, 0, 0, 0, 0, 166, 11, 16, + 0, 0, 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, + 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 102, + 3, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, + 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 2, + 0, 0, 0, 102, 3, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, + 0, 16, 0, 10, 0, 0, 0, 118, 8, 16, 0, 1, 0, 0, 0, 118, 8, 16, 0, + 2, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 102, 3, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 118, 8, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, + 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 102, 3, 16, 0, 10, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, + 84, 148, 0, 0, 0, 87, 5, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 134, 0, 0, 0, 57, 1, 0, 0, 179, 0, 0, 0, 63, 0, 0, 0, 34, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 208, 0, 0, 0, 64, 0, 0, 0, 84, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_64bpp_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_64bpp_cs.h new file mode 100644 index 0000000..9c31934 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_64bpp_cs.h @@ -0,0 +1,3351 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_resolve_edram_info; // Offset: 0 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 4 Size: 4 +// uint xe_resolve_dest_info; // Offset: 8 Size: 4 +// uint xe_resolve_dest_coordinate_info;// Offset: 12 Size: 4 +// uint xe_resolve_dest_base; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram texture byte r/o T0 t0 1 +// xe_resolve_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][2], immediateIndexed, space=0 +dcl_resource_raw T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 24 +dcl_thread_group 8, 8, 1 +and r0.xyzw, CB0[0][0].zxzz, l(7, 1023, 8, 0x01000000) +ushr r1.xyz, CB0[0][0].yywy, l(4, 5, 10, 0) +ushr r2.xyzw, CB0[0][0].wwww, l(20, 24, 24, 20) +ishl r3.xw, vThreadID.xxxx, l(2, 0, 0, 2) +bfi r1.y, l(11), l(3), r1.y, l(0) +uge r1.y, r3.w, r1.y +if_nz r1.y + ret +endif +ubfe r4.xyzw, l(2, 11, 4, 1), l(10, 13, 24, 28), CB0[0][0].xxxx +mov r1.w, CB0[0][0].y +bfi r1.xy, l(4, 1, 0, 0), l(3, 3, 0, 0), r1.wxww, l(0, 0, 0, 0) +ibfe r1.w, l(6), l(16), CB0[0][0].z +ishl r1.w, r1.w, l(23) +iadd r1.w, r1.w, l(0x3f800000) +bfi r5.x, l(10), l(5), CB0[0][0].w, l(0) +bfi r2.xyzw, l(4, 4, 4, 4), l(3, 3, 3, 3), r2.xyzw, l(0, 0, 0, 0) +ubfe r5.yz, l(0, 6, 3, 0), l(0, 7, 28, 0), CB0[0][0].zzwz +mov r3.yz, vThreadID.yyyy +iadd r1.xy, r1.xyxx, r3.wzww +uge r5.w, l(3), r5.z +if_nz r5.w + mov r6.y, r5.z +else + ieq r5.w, r5.z, l(5) + if_nz r5.w + mov r6.y, l(2) + else + mov r6.y, l(0) + endif +endif +uge r6.zw, r4.xxxx, l(0, 0, 2, 1) +and r6.zw, r6.zzzw, l(0, 0, 1, 1) +ishl r1.xy, r1.xyxx, r6.zwzz +ushr r6.x, r6.y, l(1) +and r6.xy, r6.xyxx, l(1, 1, 0, 0) +iadd r1.xy, r1.xyxx, r6.xyxx +ushr r6.x, l(80), r4.w +mov r6.y, l(16) +udiv r7.xy, null, r1.xyxx, r6.xyxx +imad r0.y, r7.y, r0.y, r7.x +iadd r0.y, r0.y, r4.y +imad r1.xy, -r7.xyxx, r6.xyxx, r1.xyxx +imad r1.x, r1.y, r6.x, r1.x +ishl r1.x, r1.x, r4.w +imad r0.y, r0.y, l(1280), r1.x +udiv null, r0.y, r0.y, l(0x00280000) +iadd r1.x, r4.w, r6.z +ishl r1.y, l(1), r1.x +if_nz r4.w + ieq r4.x, r1.y, l(2) + if_nz r4.x + ishl r4.x, r0.y, l(2) + ld_raw r6.xyzw, r4.x, T0[0].zwxy + iadd r4.x, r4.x, l(16) + ld_raw r7.xyzw, r4.x, T0[0].zwxy + mov r8.xy, r6.zwzz + mov r9.xy, r7.zwzz + else + ishl r4.x, r0.y, l(2) + ld_raw r8.xy, r4.x, T0[0].xyxx + iadd r4.x, r0.y, r1.y + ishl r4.x, r4.x, l(2) + ld_raw r6.xy, r4.x, T0[0].xyxx + ishl r4.xy, l(2, 3, 0, 0), r1.xxxx + iadd r4.xy, r0.yyyy, r4.xyxx + ishl r4.xy, r4.xyxx, l(2, 2, 0, 0) + ld_raw r9.xy, r4.x, T0[0].xyxx + ld_raw r7.xy, r4.y, T0[0].xyxx + endif + switch r4.z + case l(5) + ishl r8.zw, r8.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r8.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r6.zw, r6.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r6.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r6.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r9.zw, r9.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r9.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r7.zw, r7.xxxy, l(0, 0, 16, 16) + ishr r10.xyzw, r7.zxwy, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r7.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.xy, r8.xyxx, l(16, 16, 0, 0) + f16tof32 r8.xz, r8.xxyx + f16tof32 r8.yw, r4.xxxy + ushr r4.xy, r6.xyxx, l(16, 16, 0, 0) + f16tof32 r6.xz, r6.xxyx + f16tof32 r6.yw, r4.xxxy + ushr r4.xy, r9.xyxx, l(16, 16, 0, 0) + f16tof32 r9.xz, r9.xxyx + f16tof32 r9.yw, r4.xxxy + ushr r4.xy, r7.xyxx, l(16, 16, 0, 0) + f16tof32 r7.xz, r7.xxyx + f16tof32 r7.yw, r4.xxxy + break + default + mov r8.zw, l(0,0,0,0) + mov r6.zw, l(0,0,0,0) + mov r9.zw, l(0,0,0,0) + mov r7.zw, l(0,0,0,0) + break + endswitch +else + ieq r4.x, r1.y, l(1) + if_nz r4.x + ishl r4.x, r0.y, l(2) + ld_raw r7.xyzw, r4.x, T0[0].wxyz + else + ishl r4.x, r0.y, l(2) + ld_raw r7.y, r4.x, T0[0].xxxx + iadd r4.x, r0.y, r1.y + ishl r4.x, r4.x, l(2) + ld_raw r7.z, r4.x, T0[0].xxxx + ishl r4.xy, l(2, 3, 0, 0), r1.xxxx + iadd r4.xy, r0.yyyy, r4.xyxx + ishl r4.xy, r4.xyxx, l(2, 2, 0, 0) + ld_raw r7.w, r4.x, T0[0].xxxx + ld_raw r7.x, r4.y, T0[0].xxxx + endif + switch r4.z + case l(0) + case l(1) + ushr r10.yzw, r7.yyyy, l(0, 8, 16, 24) + mov r10.x, r7.y + and r10.xyzw, r10.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r10.yzw, r7.zzzz, l(0, 8, 16, 24) + mov r10.x, r7.z + and r10.xyzw, r10.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r6.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r10.yzw, r7.wwww, l(0, 8, 16, 24) + mov r10.x, r7.w + and r10.xyzw, r10.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r7.yzw, r7.xxxx, l(0, 8, 16, 24) + and r10.xyzw, r7.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r7.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r10.yzw, r7.yyyy, l(0, 10, 20, 30) + mov r10.x, r7.y + and r10.xyzw, r10.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r10.yzw, r7.zzzz, l(0, 10, 20, 30) + mov r10.x, r7.z + and r10.xyzw, r10.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r6.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r10.yzw, r7.wwww, l(0, 10, 20, 30) + mov r10.x, r7.w + and r10.xyzw, r10.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r7.yzw, r7.xxxx, l(0, 10, 20, 30) + and r10.xyzw, r7.xyzw, l(1023, 1023, 1023, 3) + utof r10.xyzw, r10.xyzw + mul r7.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r10.xyzw, r7.yyyz, l(10, 20, 30, 30) + mov r11.x, r7.y + mov r11.yz, r10.xxyx + and r12.xyz, r11.xyzx, l(1023, 1023, 1023, 0) + and r13.xyz, r11.xyzx, l(127, 127, 127, 0) + ubfe r14.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r11.xyzx + firstbit_hi r15.xyz, r13.xyzx + iadd r15.xyz, r15.xyzx, l(-24, -24, -24, 0) + movc r15.xyz, r13.xyzx, r15.xyzx, l(8,8,8,0) + iadd r16.xyz, -r15.xyzx, l(1, 1, 1, 0) + movc r16.xyz, r14.xyzx, r14.xyzx, r16.xyzx + bfi r11.xyz, l(7, 7, 7, 0), r15.xyzx, r11.xyzx, l(0, 0, 0, 0) + and r11.xyz, r11.xyzx, l(127, 127, 127, 0) + movc r11.xyz, r14.xyzx, r13.xyzx, r11.xyzx + ishl r13.xyz, r16.xyzx, l(23, 23, 23, 0) + iadd r13.xyz, r13.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r11.xyz, r11.xyzx, l(16, 16, 16, 0) + iadd r11.xyz, r13.xyzx, r11.xyzx + movc r8.xyz, r12.xyzx, r11.xyzx, l(0,0,0,0) + utof r4.xy, r10.zwzz + ushr r10.xyzw, r7.zwwz, l(10, 10, 20, 20) + mov r11.x, r7.z + mov r11.yz, r10.xxwx + and r12.xyz, r11.xyzx, l(1023, 1023, 1023, 0) + and r13.xyz, r11.xyzx, l(127, 127, 127, 0) + ubfe r14.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r11.xyzx + firstbit_hi r15.xyz, r13.xyzx + iadd r15.xyz, r15.xyzx, l(-24, -24, -24, 0) + movc r15.xyz, r13.xyzx, r15.xyzx, l(8,8,8,0) + iadd r16.xyz, -r15.xyzx, l(1, 1, 1, 0) + movc r16.xyz, r14.xyzx, r14.xyzx, r16.xyzx + bfi r11.xyz, l(7, 7, 7, 0), r15.xyzx, r11.xyzx, l(0, 0, 0, 0) + and r11.xyz, r11.xyzx, l(127, 127, 127, 0) + movc r11.xyz, r14.xyzx, r13.xyzx, r11.xyzx + ishl r13.xyz, r16.xyzx, l(23, 23, 23, 0) + iadd r13.xyz, r13.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r11.xyz, r11.xyzx, l(16, 16, 16, 0) + iadd r11.xyz, r13.xyzx, r11.xyzx + movc r6.xyz, r12.xyzx, r11.xyzx, l(0,0,0,0) + mul r4.xy, r4.xyxx, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r10.x, r7.w + and r11.xyz, r10.xyzx, l(1023, 1023, 1023, 0) + and r12.xyz, r10.xyzx, l(127, 127, 127, 0) + ubfe r13.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r10.xyzx + firstbit_hi r14.xyz, r12.xyzx + iadd r14.xyz, r14.xyzx, l(-24, -24, -24, 0) + movc r14.xyz, r12.xyzx, r14.xyzx, l(8,8,8,0) + iadd r15.xyz, -r14.xyzx, l(1, 1, 1, 0) + movc r15.xyz, r13.xyzx, r13.xyzx, r15.xyzx + bfi r10.xyz, l(7, 7, 7, 0), r14.xyzx, r10.xyzx, l(0, 0, 0, 0) + and r10.xyz, r10.xyzx, l(127, 127, 127, 0) + movc r10.xyz, r13.xyzx, r12.xyzx, r10.xyzx + ishl r12.xyz, r15.xyzx, l(23, 23, 23, 0) + iadd r12.xyz, r12.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r10.xyz, r10.xyzx, l(16, 16, 16, 0) + iadd r10.xyz, r12.xyzx, r10.xyzx + movc r9.xyz, r11.xyzx, r10.xyzx, l(0,0,0,0) + ushr r10.xyzw, r7.wxxx, l(30, 10, 20, 30) + utof r11.xy, r10.xwxx + mov r10.x, r7.x + and r12.xyz, r10.xyzx, l(1023, 1023, 1023, 0) + and r13.xyz, r10.xyzx, l(127, 127, 127, 0) + ubfe r14.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r10.xyzx + firstbit_hi r15.xyz, r13.xyzx + iadd r15.xyz, r15.xyzx, l(-24, -24, -24, 0) + movc r15.xyz, r13.xyzx, r15.xyzx, l(8,8,8,0) + iadd r16.xyz, -r15.xyzx, l(1, 1, 1, 0) + movc r16.xyz, r14.xyzx, r14.xyzx, r16.xyzx + bfi r10.xyz, l(7, 7, 7, 0), r15.xyzx, r10.xyzx, l(0, 0, 0, 0) + and r10.xyz, r10.xyzx, l(127, 127, 127, 0) + movc r10.xyz, r14.xyzx, r13.xyzx, r10.xyzx + ishl r13.xyz, r16.xyzx, l(23, 23, 23, 0) + iadd r13.xyz, r13.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r10.xyz, r10.xyzx, l(16, 16, 16, 0) + iadd r10.xyz, r13.xyzx, r10.xyzx + movc r7.xyz, r12.xyzx, r10.xyzx, l(0,0,0,0) + mul r10.xy, r11.xyxx, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r8.w, r4.x + mov r6.w, r4.y + mov r9.w, r10.x + mov r7.w, r10.y + break + case l(4) + ishl r10.xyzw, r7.yzwx, l(16, 16, 16, 16) + mov r11.xz, r10.xxyx + mov r11.yw, r7.yyyz + ishr r11.xyzw, r11.xyzw, l(16, 16, 16, 16) + itof r11.xyzw, r11.xyzw + mul r11.xyzw, r11.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xy, r11.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r6.xy, r11.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r7.yz, r10.zzwz + ishr r10.xyzw, r7.ywzx, l(16, 16, 16, 16) + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xy, r10.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r7.xy, r10.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r8.zw, l(0,0,0,0) + mov r6.zw, l(0,0,0,0) + mov r9.zw, l(0,0,0,0) + mov r7.zw, l(0,0,0,0) + break + case l(6) + ushr r10.xyzw, r7.yzwx, l(16, 16, 16, 16) + f16tof32 r8.x, r7.y + f16tof32 r8.y, r10.x + f16tof32 r6.x, r7.z + f16tof32 r6.y, r10.y + f16tof32 r9.x, r7.w + f16tof32 r9.y, r10.z + f16tof32 r7.x, r7.x + f16tof32 r7.y, r10.w + mov r8.zw, l(0,0,0,0) + mov r6.zw, l(0,0,0,0) + mov r9.zw, l(0,0,0,0) + mov r7.zw, l(0,0,0,0) + break + default + mov r8.x, r7.y + mov r8.yzw, l(0,0,0,0) + mov r6.x, r7.z + mov r6.yzw, l(0,0,0,0) + mov r9.x, r7.w + mov r9.yzw, l(0,0,0,0) + mov r7.yzw, l(0,0,0,0) + break + endswitch +endif +uge r4.x, r5.z, l(4) +if_nz r4.x + mul r4.x, r1.w, l(0.500000) + iadd r4.y, r0.y, l(80) + if_nz r4.w + ieq r5.w, r1.y, l(2) + if_nz r5.w + ishl r5.w, r4.y, l(2) + ld_raw r10.xyzw, r5.w, T0[0].zwxy + iadd r5.w, r5.w, l(16) + ld_raw r11.xyzw, r5.w, T0[0].zwxy + mov r12.xy, r10.zwzz + mov r14.xy, r11.zwzz + else + ishl r5.w, r4.y, l(2) + ld_raw r12.xy, r5.w, T0[0].xyxx + iadd r5.w, r1.y, r4.y + ishl r5.w, r5.w, l(2) + ld_raw r10.xy, r5.w, T0[0].xyxx + ishl r13.xy, l(2, 3, 0, 0), r1.xxxx + iadd r13.xy, r4.yyyy, r13.xyxx + ishl r13.xy, r13.xyxx, l(2, 2, 0, 0) + ld_raw r14.xy, r13.x, T0[0].xyxx + ld_raw r11.xy, r13.y, T0[0].xyxx + endif + switch r4.z + case l(5) + ishl r12.zw, r12.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r12.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r12.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r10.zw, r10.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r10.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r10.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r14.zw, r14.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r14.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r11.zw, r11.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r11.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r11.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r13.xy, r12.xyxx, l(16, 16, 0, 0) + f16tof32 r12.xz, r12.xxyx + f16tof32 r12.yw, r13.xxxy + ushr r13.xy, r10.xyxx, l(16, 16, 0, 0) + f16tof32 r10.xz, r10.xxyx + f16tof32 r10.yw, r13.xxxy + ushr r13.xy, r14.xyxx, l(16, 16, 0, 0) + f16tof32 r14.xz, r14.xxyx + f16tof32 r14.yw, r13.xxxy + ushr r13.xy, r11.xyxx, l(16, 16, 0, 0) + f16tof32 r11.xz, r11.xxyx + f16tof32 r11.yw, r13.xxxy + break + default + mov r12.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + break + endswitch + else + ieq r5.w, r1.y, l(1) + if_nz r5.w + ishl r5.w, r4.y, l(2) + ld_raw r11.xyzw, r5.w, T0[0].wxyz + else + ishl r5.w, r4.y, l(2) + ld_raw r11.y, r5.w, T0[0].xxxx + iadd r5.w, r1.y, r4.y + ishl r5.w, r5.w, l(2) + ld_raw r11.z, r5.w, T0[0].xxxx + ishl r13.xy, l(2, 3, 0, 0), r1.xxxx + iadd r13.xy, r4.yyyy, r13.xyxx + ishl r13.xy, r13.xyxx, l(2, 2, 0, 0) + ld_raw r11.w, r13.x, T0[0].xxxx + ld_raw r11.x, r13.y, T0[0].xxxx + endif + switch r4.z + case l(0) + case l(1) + ushr r13.yzw, r11.yyyy, l(0, 8, 16, 24) + mov r13.x, r11.y + and r13.xyzw, r13.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r12.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r13.yzw, r11.zzzz, l(0, 8, 16, 24) + mov r13.x, r11.z + and r13.xyzw, r13.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r10.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r13.yzw, r11.wwww, l(0, 8, 16, 24) + mov r13.x, r11.w + and r13.xyzw, r13.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r14.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r11.yzw, r11.xxxx, l(0, 8, 16, 24) + and r13.xyzw, r11.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r11.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r13.yzw, r11.yyyy, l(0, 10, 20, 30) + mov r13.x, r11.y + and r13.xyzw, r13.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r12.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r13.yzw, r11.zzzz, l(0, 10, 20, 30) + mov r13.x, r11.z + and r13.xyzw, r13.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r10.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r13.yzw, r11.wwww, l(0, 10, 20, 30) + mov r13.x, r11.w + and r13.xyzw, r13.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r14.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r11.yzw, r11.xxxx, l(0, 10, 20, 30) + and r13.xyzw, r11.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r11.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r13.xyzw, r11.yyyz, l(10, 20, 30, 30) + mov r15.x, r11.y + mov r15.yz, r13.xxyx + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r12.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + utof r13.xy, r13.zwzz + ushr r15.xyzw, r11.zwwz, l(10, 10, 20, 20) + mov r16.x, r11.z + mov r16.yz, r15.xxwx + and r17.xyz, r16.xyzx, l(1023, 1023, 1023, 0) + and r18.xyz, r16.xyzx, l(127, 127, 127, 0) + ubfe r19.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r16.xyzx + firstbit_hi r20.xyz, r18.xyzx + iadd r20.xyz, r20.xyzx, l(-24, -24, -24, 0) + movc r20.xyz, r18.xyzx, r20.xyzx, l(8,8,8,0) + iadd r21.xyz, -r20.xyzx, l(1, 1, 1, 0) + movc r21.xyz, r19.xyzx, r19.xyzx, r21.xyzx + bfi r16.xyz, l(7, 7, 7, 0), r20.xyzx, r16.xyzx, l(0, 0, 0, 0) + and r16.xyz, r16.xyzx, l(127, 127, 127, 0) + movc r16.xyz, r19.xyzx, r18.xyzx, r16.xyzx + ishl r18.xyz, r21.xyzx, l(23, 23, 23, 0) + iadd r18.xyz, r18.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r16.xyz, r16.xyzx, l(16, 16, 16, 0) + iadd r16.xyz, r18.xyzx, r16.xyzx + movc r10.xyz, r17.xyzx, r16.xyzx, l(0,0,0,0) + mov r15.x, r11.w + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r14.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + ushr r15.xyzw, r11.wxxx, l(30, 10, 20, 30) + utof r13.zw, r15.xxxw + mov r15.x, r11.x + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r11.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + mul r13.xyzw, r13.xyzw, l(0.333333, 0.333333, 0.333333, 0.333333) + mov r12.w, r13.x + mov r10.w, r13.y + mov r14.w, r13.z + mov r11.w, r13.w + break + case l(4) + ishl r13.xyzw, r11.yzwx, l(16, 16, 16, 16) + mov r15.xz, r13.xxyx + mov r15.yw, r11.yyyz + ishr r15.xyzw, r15.xyzw, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r12.xy, r15.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r10.xy, r15.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r11.yz, r13.zzwz + ishr r13.xyzw, r11.ywzx, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xy, r13.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r11.xy, r13.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r12.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + break + case l(6) + ushr r13.xyzw, r11.yzwx, l(16, 16, 16, 16) + f16tof32 r12.x, r11.y + f16tof32 r12.y, r13.x + f16tof32 r10.x, r11.z + f16tof32 r10.y, r13.y + f16tof32 r14.x, r11.w + f16tof32 r14.y, r13.z + f16tof32 r11.x, r11.x + f16tof32 r11.y, r13.w + mov r12.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + break + default + mov r12.x, r11.y + mov r12.yzw, l(0,0,0,0) + mov r10.x, r11.z + mov r10.yzw, l(0,0,0,0) + mov r14.x, r11.w + mov r14.yzw, l(0,0,0,0) + mov r11.yzw, l(0,0,0,0) + break + endswitch + endif + add r8.xyzw, r8.xyzw, r12.xyzw + add r6.xyzw, r6.xyzw, r10.xyzw + add r9.xyzw, r9.xyzw, r14.xyzw + add r7.xyzw, r7.xyzw, r11.xyzw + uge r5.z, r5.z, l(6) + if_nz r5.z + ishl r5.z, l(1), r4.w + mul r1.w, r1.w, l(0.250000) + iadd r0.y, r0.y, r5.z + if_nz r4.w + ieq r5.w, r1.y, l(2) + if_nz r5.w + ishl r5.w, r0.y, l(2) + ld_raw r10.xyzw, r5.w, T0[0].zwxy + iadd r5.w, r5.w, l(16) + ld_raw r11.xyzw, r5.w, T0[0].zwxy + mov r12.xy, r10.zwzz + mov r14.xy, r11.zwzz + else + ishl r5.w, r0.y, l(2) + ld_raw r12.xy, r5.w, T0[0].xyxx + iadd r5.w, r1.y, r0.y + ishl r5.w, r5.w, l(2) + ld_raw r10.xy, r5.w, T0[0].xyxx + ishl r13.xy, l(2, 3, 0, 0), r1.xxxx + iadd r13.xy, r0.yyyy, r13.xyxx + ishl r13.xy, r13.xyxx, l(2, 2, 0, 0) + ld_raw r14.xy, r13.x, T0[0].xyxx + ld_raw r11.xy, r13.y, T0[0].xyxx + endif + switch r4.z + case l(5) + ishl r12.zw, r12.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r12.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r12.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r10.zw, r10.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r10.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r10.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r14.zw, r14.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r14.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r11.zw, r11.xxxy, l(0, 0, 16, 16) + ishr r13.xyzw, r11.zxwy, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r11.xyzw, r13.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r13.xy, r12.xyxx, l(16, 16, 0, 0) + f16tof32 r12.xz, r12.xxyx + f16tof32 r12.yw, r13.xxxy + ushr r13.xy, r10.xyxx, l(16, 16, 0, 0) + f16tof32 r10.xz, r10.xxyx + f16tof32 r10.yw, r13.xxxy + ushr r13.xy, r14.xyxx, l(16, 16, 0, 0) + f16tof32 r14.xz, r14.xxyx + f16tof32 r14.yw, r13.xxxy + ushr r13.xy, r11.xyxx, l(16, 16, 0, 0) + f16tof32 r11.xz, r11.xxyx + f16tof32 r11.yw, r13.xxxy + break + default + mov r12.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + break + endswitch + else + ieq r5.w, r1.y, l(1) + if_nz r5.w + ishl r5.w, r0.y, l(2) + ld_raw r11.xyzw, r5.w, T0[0].wxyz + else + ishl r5.w, r0.y, l(2) + ld_raw r11.y, r5.w, T0[0].xxxx + iadd r5.w, r1.y, r0.y + ishl r5.w, r5.w, l(2) + ld_raw r11.z, r5.w, T0[0].xxxx + ishl r13.xy, l(2, 3, 0, 0), r1.xxxx + iadd r13.xy, r0.yyyy, r13.xyxx + ishl r13.xy, r13.xyxx, l(2, 2, 0, 0) + ld_raw r11.w, r13.x, T0[0].xxxx + ld_raw r11.x, r13.y, T0[0].xxxx + endif + switch r4.z + case l(0) + case l(1) + ushr r13.yzw, r11.yyyy, l(0, 8, 16, 24) + mov r13.x, r11.y + and r13.xyzw, r13.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r12.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r13.yzw, r11.zzzz, l(0, 8, 16, 24) + mov r13.x, r11.z + and r13.xyzw, r13.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r10.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r13.yzw, r11.wwww, l(0, 8, 16, 24) + mov r13.x, r11.w + and r13.xyzw, r13.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r14.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r11.yzw, r11.xxxx, l(0, 8, 16, 24) + and r13.xyzw, r11.xyzw, l(255, 255, 255, 255) + utof r13.xyzw, r13.xyzw + mul r11.xyzw, r13.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r13.yzw, r11.yyyy, l(0, 10, 20, 30) + mov r13.x, r11.y + and r13.xyzw, r13.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r12.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r13.yzw, r11.zzzz, l(0, 10, 20, 30) + mov r13.x, r11.z + and r13.xyzw, r13.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r10.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r13.yzw, r11.wwww, l(0, 10, 20, 30) + mov r13.x, r11.w + and r13.xyzw, r13.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r14.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r11.yzw, r11.xxxx, l(0, 10, 20, 30) + and r13.xyzw, r11.xyzw, l(1023, 1023, 1023, 3) + utof r13.xyzw, r13.xyzw + mul r11.xyzw, r13.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r13.xyzw, r11.yyyz, l(10, 20, 30, 30) + mov r15.x, r11.y + mov r15.yz, r13.xxyx + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r12.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + utof r13.xy, r13.zwzz + ushr r15.xyzw, r11.zwwz, l(10, 10, 20, 20) + mov r16.x, r11.z + mov r16.yz, r15.xxwx + and r17.xyz, r16.xyzx, l(1023, 1023, 1023, 0) + and r18.xyz, r16.xyzx, l(127, 127, 127, 0) + ubfe r19.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r16.xyzx + firstbit_hi r20.xyz, r18.xyzx + iadd r20.xyz, r20.xyzx, l(-24, -24, -24, 0) + movc r20.xyz, r18.xyzx, r20.xyzx, l(8,8,8,0) + iadd r21.xyz, -r20.xyzx, l(1, 1, 1, 0) + movc r21.xyz, r19.xyzx, r19.xyzx, r21.xyzx + bfi r16.xyz, l(7, 7, 7, 0), r20.xyzx, r16.xyzx, l(0, 0, 0, 0) + and r16.xyz, r16.xyzx, l(127, 127, 127, 0) + movc r16.xyz, r19.xyzx, r18.xyzx, r16.xyzx + ishl r18.xyz, r21.xyzx, l(23, 23, 23, 0) + iadd r18.xyz, r18.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r16.xyz, r16.xyzx, l(16, 16, 16, 0) + iadd r16.xyz, r18.xyzx, r16.xyzx + movc r10.xyz, r17.xyzx, r16.xyzx, l(0,0,0,0) + mov r15.x, r11.w + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r14.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + ushr r15.xyzw, r11.wxxx, l(30, 10, 20, 30) + utof r13.zw, r15.xxxw + mov r15.x, r11.x + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r11.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + mul r13.xyzw, r13.xyzw, l(0.333333, 0.333333, 0.333333, 0.333333) + mov r12.w, r13.x + mov r10.w, r13.y + mov r14.w, r13.z + mov r11.w, r13.w + break + case l(4) + ishl r13.xyzw, r11.yzwx, l(16, 16, 16, 16) + mov r15.xz, r13.xxyx + mov r15.yw, r11.yyyz + ishr r15.xyzw, r15.xyzw, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r12.xy, r15.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r10.xy, r15.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r11.yz, r13.zzwz + ishr r13.xyzw, r11.ywzx, l(16, 16, 16, 16) + itof r13.xyzw, r13.xyzw + mul r13.xyzw, r13.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xy, r13.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r11.xy, r13.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r12.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + break + case l(6) + ushr r13.xyzw, r11.yzwx, l(16, 16, 16, 16) + f16tof32 r12.x, r11.y + f16tof32 r12.y, r13.x + f16tof32 r10.x, r11.z + f16tof32 r10.y, r13.y + f16tof32 r14.x, r11.w + f16tof32 r14.y, r13.z + f16tof32 r11.x, r11.x + f16tof32 r11.y, r13.w + mov r12.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + break + default + mov r12.x, r11.y + mov r12.yzw, l(0,0,0,0) + mov r10.x, r11.z + mov r10.yzw, l(0,0,0,0) + mov r14.x, r11.w + mov r14.yzw, l(0,0,0,0) + mov r11.yzw, l(0,0,0,0) + break + endswitch + endif + add r12.xyzw, r8.xyzw, r12.xyzw + add r10.xyzw, r6.xyzw, r10.xyzw + add r13.xyzw, r9.xyzw, r14.xyzw + add r11.xyzw, r7.xyzw, r11.xyzw + iadd r0.y, r4.y, r5.z + if_nz r4.w + ieq r4.y, r1.y, l(2) + if_nz r4.y + ishl r4.y, r0.y, l(2) + ld_raw r14.xyzw, r4.y, T0[0].zwxy + iadd r4.y, r4.y, l(16) + ld_raw r15.xyzw, r4.y, T0[0].zwxy + mov r16.xy, r14.zwzz + mov r17.xy, r15.zwzz + else + ishl r4.y, r0.y, l(2) + ld_raw r16.xy, r4.y, T0[0].xyxx + iadd r4.y, r1.y, r0.y + ishl r4.y, r4.y, l(2) + ld_raw r14.xy, r4.y, T0[0].xyxx + ishl r4.yw, l(0, 2, 0, 3), r1.xxxx + iadd r4.yw, r0.yyyy, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r17.xy, r4.y, T0[0].xyxx + ld_raw r15.xy, r4.w, T0[0].xyxx + endif + switch r4.z + case l(5) + ishl r16.zw, r16.xxxy, l(0, 0, 16, 16) + ishr r18.xyzw, r16.zxwy, l(16, 16, 16, 16) + itof r18.xyzw, r18.xyzw + mul r18.xyzw, r18.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r16.xyzw, r18.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r14.zw, r14.xxxy, l(0, 0, 16, 16) + ishr r18.xyzw, r14.zxwy, l(16, 16, 16, 16) + itof r18.xyzw, r18.xyzw + mul r18.xyzw, r18.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xyzw, r18.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r17.zw, r17.xxxy, l(0, 0, 16, 16) + ishr r18.xyzw, r17.zxwy, l(16, 16, 16, 16) + itof r18.xyzw, r18.xyzw + mul r18.xyzw, r18.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r17.xyzw, r18.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r15.zw, r15.xxxy, l(0, 0, 16, 16) + ishr r18.xyzw, r15.zxwy, l(16, 16, 16, 16) + itof r18.xyzw, r18.xyzw + mul r18.xyzw, r18.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r15.xyzw, r18.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.yw, r16.xxxy, l(0, 16, 0, 16) + f16tof32 r16.xz, r16.xxyx + f16tof32 r16.yw, r4.yyyw + ushr r4.yw, r14.xxxy, l(0, 16, 0, 16) + f16tof32 r14.xz, r14.xxyx + f16tof32 r14.yw, r4.yyyw + ushr r4.yw, r17.xxxy, l(0, 16, 0, 16) + f16tof32 r17.xz, r17.xxyx + f16tof32 r17.yw, r4.yyyw + ushr r4.yw, r15.xxxy, l(0, 16, 0, 16) + f16tof32 r15.xz, r15.xxyx + f16tof32 r15.yw, r4.yyyw + break + default + mov r16.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r17.zw, l(0,0,0,0) + mov r15.zw, l(0,0,0,0) + break + endswitch + else + ieq r4.y, r1.y, l(1) + if_nz r4.y + ishl r4.y, r0.y, l(2) + ld_raw r15.xyzw, r4.y, T0[0].wxyz + else + ishl r4.y, r0.y, l(2) + ld_raw r15.y, r4.y, T0[0].xxxx + iadd r1.y, r1.y, r0.y + ishl r1.y, r1.y, l(2) + ld_raw r15.z, r1.y, T0[0].xxxx + ishl r1.xy, l(2, 3, 0, 0), r1.xxxx + iadd r1.xy, r0.yyyy, r1.xyxx + ishl r1.xy, r1.xyxx, l(2, 2, 0, 0) + ld_raw r15.w, r1.x, T0[0].xxxx + ld_raw r15.x, r1.y, T0[0].xxxx + endif + switch r4.z + case l(0) + case l(1) + ushr r18.yzw, r15.yyyy, l(0, 8, 16, 24) + mov r18.x, r15.y + and r18.xyzw, r18.xyzw, l(255, 255, 255, 255) + utof r18.xyzw, r18.xyzw + mul r16.xyzw, r18.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r18.yzw, r15.zzzz, l(0, 8, 16, 24) + mov r18.x, r15.z + and r18.xyzw, r18.xyzw, l(255, 255, 255, 255) + utof r18.xyzw, r18.xyzw + mul r14.xyzw, r18.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r18.yzw, r15.wwww, l(0, 8, 16, 24) + mov r18.x, r15.w + and r18.xyzw, r18.xyzw, l(255, 255, 255, 255) + utof r18.xyzw, r18.xyzw + mul r17.xyzw, r18.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r15.yzw, r15.xxxx, l(0, 8, 16, 24) + and r18.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r18.xyzw, r18.xyzw + mul r15.xyzw, r18.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r18.yzw, r15.yyyy, l(0, 10, 20, 30) + mov r18.x, r15.y + and r18.xyzw, r18.xyzw, l(1023, 1023, 1023, 3) + utof r18.xyzw, r18.xyzw + mul r16.xyzw, r18.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r18.yzw, r15.zzzz, l(0, 10, 20, 30) + mov r18.x, r15.z + and r18.xyzw, r18.xyzw, l(1023, 1023, 1023, 3) + utof r18.xyzw, r18.xyzw + mul r14.xyzw, r18.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r18.yzw, r15.wwww, l(0, 10, 20, 30) + mov r18.x, r15.w + and r18.xyzw, r18.xyzw, l(1023, 1023, 1023, 3) + utof r18.xyzw, r18.xyzw + mul r17.xyzw, r18.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r15.yzw, r15.xxxx, l(0, 10, 20, 30) + and r18.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r18.xyzw, r18.xyzw + mul r15.xyzw, r18.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r18.xyzw, r15.yyyz, l(10, 20, 30, 30) + mov r19.x, r15.y + mov r19.yz, r18.xxyx + and r4.yzw, r19.xxyz, l(0, 1023, 1023, 1023) + and r20.xyz, r19.xyzx, l(127, 127, 127, 0) + ubfe r21.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r19.xyzx + firstbit_hi r22.xyz, r20.xyzx + iadd r22.xyz, r22.xyzx, l(-24, -24, -24, 0) + movc r22.xyz, r20.xyzx, r22.xyzx, l(8,8,8,0) + iadd r23.xyz, -r22.xyzx, l(1, 1, 1, 0) + movc r23.xyz, r21.xyzx, r21.xyzx, r23.xyzx + bfi r19.xyz, l(7, 7, 7, 0), r22.xyzx, r19.xyzx, l(0, 0, 0, 0) + and r19.xyz, r19.xyzx, l(127, 127, 127, 0) + movc r19.xyz, r21.xyzx, r20.xyzx, r19.xyzx + ishl r20.xyz, r23.xyzx, l(23, 23, 23, 0) + iadd r20.xyz, r20.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r19.xyz, r19.xyzx, l(16, 16, 16, 0) + iadd r19.xyz, r20.xyzx, r19.xyzx + movc r16.xyz, r4.yzwy, r19.xyzx, l(0,0,0,0) + utof r1.xy, r18.zwzz + ushr r18.xyzw, r15.zwwz, l(10, 10, 20, 20) + mov r19.x, r15.z + mov r19.yz, r18.xxwx + and r4.yzw, r19.xxyz, l(0, 1023, 1023, 1023) + and r20.xyz, r19.xyzx, l(127, 127, 127, 0) + ubfe r21.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r19.xyzx + firstbit_hi r22.xyz, r20.xyzx + iadd r22.xyz, r22.xyzx, l(-24, -24, -24, 0) + movc r22.xyz, r20.xyzx, r22.xyzx, l(8,8,8,0) + iadd r23.xyz, -r22.xyzx, l(1, 1, 1, 0) + movc r23.xyz, r21.xyzx, r21.xyzx, r23.xyzx + bfi r19.xyz, l(7, 7, 7, 0), r22.xyzx, r19.xyzx, l(0, 0, 0, 0) + and r19.xyz, r19.xyzx, l(127, 127, 127, 0) + movc r19.xyz, r21.xyzx, r20.xyzx, r19.xyzx + ishl r20.xyz, r23.xyzx, l(23, 23, 23, 0) + iadd r20.xyz, r20.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r19.xyz, r19.xyzx, l(16, 16, 16, 0) + iadd r19.xyz, r20.xyzx, r19.xyzx + movc r14.xyz, r4.yzwy, r19.xyzx, l(0,0,0,0) + mul r1.xy, r1.xyxx, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r18.x, r15.w + and r4.yzw, r18.xxyz, l(0, 1023, 1023, 1023) + and r19.xyz, r18.xyzx, l(127, 127, 127, 0) + ubfe r20.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r18.xyzx + firstbit_hi r21.xyz, r19.xyzx + iadd r21.xyz, r21.xyzx, l(-24, -24, -24, 0) + movc r21.xyz, r19.xyzx, r21.xyzx, l(8,8,8,0) + iadd r22.xyz, -r21.xyzx, l(1, 1, 1, 0) + movc r22.xyz, r20.xyzx, r20.xyzx, r22.xyzx + bfi r18.xyz, l(7, 7, 7, 0), r21.xyzx, r18.xyzx, l(0, 0, 0, 0) + and r18.xyz, r18.xyzx, l(127, 127, 127, 0) + movc r18.xyz, r20.xyzx, r19.xyzx, r18.xyzx + ishl r19.xyz, r22.xyzx, l(23, 23, 23, 0) + iadd r19.xyz, r19.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r18.xyz, r18.xyzx, l(16, 16, 16, 0) + iadd r18.xyz, r19.xyzx, r18.xyzx + movc r17.xyz, r4.yzwy, r18.xyzx, l(0,0,0,0) + ushr r18.xyzw, r15.wxxx, l(30, 10, 20, 30) + utof r4.yz, r18.xxwx + mov r18.x, r15.x + and r19.xyz, r18.xyzx, l(1023, 1023, 1023, 0) + and r20.xyz, r18.xyzx, l(127, 127, 127, 0) + ubfe r21.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r18.xyzx + firstbit_hi r22.xyz, r20.xyzx + iadd r22.xyz, r22.xyzx, l(-24, -24, -24, 0) + movc r22.xyz, r20.xyzx, r22.xyzx, l(8,8,8,0) + iadd r23.xyz, -r22.xyzx, l(1, 1, 1, 0) + movc r23.xyz, r21.xyzx, r21.xyzx, r23.xyzx + bfi r18.xyz, l(7, 7, 7, 0), r22.xyzx, r18.xyzx, l(0, 0, 0, 0) + and r18.xyz, r18.xyzx, l(127, 127, 127, 0) + movc r18.xyz, r21.xyzx, r20.xyzx, r18.xyzx + ishl r20.xyz, r23.xyzx, l(23, 23, 23, 0) + iadd r20.xyz, r20.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r18.xyz, r18.xyzx, l(16, 16, 16, 0) + iadd r18.xyz, r20.xyzx, r18.xyzx + movc r15.xyz, r19.xyzx, r18.xyzx, l(0,0,0,0) + mul r4.yz, r4.yyzy, l(0.000000, 0.333333, 0.333333, 0.000000) + mov r16.w, r1.x + mov r14.w, r1.y + mov r17.w, r4.y + mov r15.w, r4.z + break + case l(4) + ishl r18.xyzw, r15.yzwx, l(16, 16, 16, 16) + mov r19.xz, r18.xxyx + mov r19.yw, r15.yyyz + ishr r19.xyzw, r19.xyzw, l(16, 16, 16, 16) + itof r19.xyzw, r19.xyzw + mul r19.xyzw, r19.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r16.xy, r19.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r14.xy, r19.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r15.yz, r18.zzwz + ishr r18.xyzw, r15.ywzx, l(16, 16, 16, 16) + itof r18.xyzw, r18.xyzw + mul r18.xyzw, r18.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r17.xy, r18.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r15.xy, r18.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r16.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r17.zw, l(0,0,0,0) + mov r15.zw, l(0,0,0,0) + break + case l(6) + ushr r18.xyzw, r15.yzwx, l(16, 16, 16, 16) + f16tof32 r16.x, r15.y + f16tof32 r16.y, r18.x + f16tof32 r14.x, r15.z + f16tof32 r14.y, r18.y + f16tof32 r17.x, r15.w + f16tof32 r17.y, r18.z + f16tof32 r15.x, r15.x + f16tof32 r15.y, r18.w + mov r16.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r17.zw, l(0,0,0,0) + mov r15.zw, l(0,0,0,0) + break + default + mov r16.x, r15.y + mov r16.yzw, l(0,0,0,0) + mov r14.x, r15.z + mov r14.yzw, l(0,0,0,0) + mov r17.x, r15.w + mov r17.yzw, l(0,0,0,0) + mov r15.yzw, l(0,0,0,0) + break + endswitch + endif + add r8.xyzw, r12.xyzw, r16.xyzw + add r6.xyzw, r10.xyzw, r14.xyzw + add r9.xyzw, r13.xyzw, r17.xyzw + add r7.xyzw, r11.xyzw, r15.xyzw + else + mov r1.w, r4.x + endif +endif +mul r4.xyzw, r1.wwww, r8.xyzw +mul r6.xyzw, r1.wwww, r6.xzwy +mul r8.xyzw, r1.wwww, r9.xyzw +mul r7.xyzw, r1.wwww, r7.xzwy +if_nz r0.w + mov r4.xz, r4.zzxz + mov r9.xz, r6.yyxy + mov r8.xz, r8.zzxz + mov r10.xz, r7.yyxy +else + mov r9.xz, r6.xxyx + mov r10.xz, r7.xxyx +endif +switch r5.y + case l(26) + mov_sat r4.xyzw, r4.xyzw + mad r11.xyzw, r4.xyzw, l(65535.000000, 65535.000000, 65535.000000, 65535.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r11.xyzw, r11.xyzw + imad r6.xy, r11.ywyy, l(0x00010000, 0x00010000, 0, 0), r11.xzxx + mov r9.yw, r6.wwwz + mov_sat r9.xyzw, r9.xyzw + mad r11.xyzw, r9.xyzw, l(65535.000000, 65535.000000, 65535.000000, 65535.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r11.xyzw, r11.xyzw + imad r6.zw, r11.yyyw, l(0, 0, 0x00010000, 0x00010000), r11.xxxz + mov_sat r8.xyzw, r8.xyzw + mad r11.xyzw, r8.xyzw, l(65535.000000, 65535.000000, 65535.000000, 65535.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r11.xyzw, r11.xyzw + imad r7.xy, r11.ywyy, l(0x00010000, 0x00010000, 0, 0), r11.xzxx + mov r10.yw, r7.wwwz + mov_sat r10.xyzw, r10.xyzw + mad r11.xyzw, r10.xyzw, l(65535.000000, 65535.000000, 65535.000000, 65535.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r11.xyzw, r11.xyzw + imad r7.zw, r11.yyyw, l(0, 0, 0x00010000, 0x00010000), r11.xxxz + break + case l(32) + f32tof16 r0.yw, r4.xxxz + f32tof16 r1.xy, r4.ywyy + imad r6.xy, r1.xyxx, l(0x00010000, 0x00010000, 0, 0), r0.ywyy + f32tof16 r0.yw, r9.xxxz + f32tof16 r1.xy, r6.wzww + imad r6.zw, r1.xxxy, l(0, 0, 0x00010000, 0x00010000), r0.yyyw + f32tof16 r0.yw, r8.xxxz + f32tof16 r1.xy, r8.ywyy + imad r7.xy, r1.xyxx, l(0x00010000, 0x00010000, 0, 0), r0.ywyy + f32tof16 r0.yw, r10.xxxz + f32tof16 r1.xy, r7.wzww + imad r7.zw, r1.xxxy, l(0, 0, 0x00010000, 0x00010000), r0.yyyw + break + default + mov r6.xy, r4.xyxx + mov r6.z, r9.x + mov r7.xy, r8.xyxx + mov r7.z, r10.x + break +endswitch +iadd r2.xyzw, r2.xyzw, r3.xyzw +if_nz r0.z + ubfe r0.y, l(3), l(4), CB0[0][0].z + ishl r0.z, r1.z, l(5) + ishr r1.xyzw, r2.zwzw, l(4, 5, 3, 3) + ishr r0.w, r0.y, l(2) + ushr r0.z, r0.z, l(4) + and r0.z, r0.z, l(2046) + imad r0.z, r0.w, r0.z, r1.x + ushr r1.x, r5.x, l(5) + imad r0.z, r0.z, r1.x, r1.y + ishl r1.x, r2.z, l(11) + and r1.x, r1.x, l(0x00003000) + bfi r1.x, l(3), l(9), r2.w, r1.x + ishr r1.x, r1.x, l(6) + iadd r0.w, r0.w, r1.z + bfi r1.y, l(1), l(1), r0.w, l(0) + iadd r1.y, r1.y, r1.w + bfi r1.y, l(2), l(1), r1.y, l(0) + bfi r0.w, l(1), l(0), r0.w, r1.y + bfi r1.yz, l(0, 19, 19, 0), l(0, 11, 14, 0), r0.zzzz, l(0, 0, 0, 0) + imad r1.xy, r1.xxxx, l(2, 16, 0, 0), r1.yzyy + bfi r0.yz, l(0, 2, 2, 0), l(0, 9, 12, 0), r0.yyyy, r1.xxyx + bfi r1.x, l(1), l(4), r2.z, l(0) + ubfe r1.y, l(3), l(6), r0.y + and r1.z, r0.w, l(6) + bfi r0.w, l(1), l(8), r0.w, l(0) + imad r0.w, r1.y, l(32), r0.w + imad r0.w, r1.z, l(4), r0.w + bfi r0.yz, l(0, 6, 6, 0), l(0, 0, 3, 0), r1.xxxx, r0.yyzy + bfi r0.z, l(9), l(3), r0.w, r0.z + bfi r0.y, l(6), l(0), r0.y, r0.z +else + ishr r1.xyzw, r2.xyzw, l(5, 5, 2, 3) + ushr r0.z, r5.x, l(5) + imad r0.z, r1.y, r0.z, r1.x + ishl r1.xy, r2.zzzz, l(6, 7, 0, 0) + and r1.xy, r1.xyxx, l(896, 2048, 0, 0) + bfi r0.w, l(3), l(4), r2.w, r1.x + bfi r0.w, l(22), l(10), r0.z, r0.w + bfi r2.x, l(1), l(4), r2.z, l(0) + iadd r0.w, r0.w, r2.x + ishl r2.yz, r1.xxxx, l(0, 3, 2, 0) + bfi r2.yz, l(0, 3, 3, 0), l(0, 7, 6, 0), r2.wwww, r2.yyzy + bfi r2.yz, l(0, 22, 22, 0), l(0, 13, 12, 0), r0.zzzz, r2.yyzy + imad r2.xy, r2.xxxx, l(8, 4, 0, 0), r2.yzyy + bfi r0.z, l(12), l(0), r1.y, r2.x + and r1.x, r2.y, l(1792) + iadd r0.z, r0.z, r1.x + and r1.x, r1.z, l(2) + iadd r1.x, r1.w, r1.x + bfi r1.x, l(2), l(6), r1.x, l(0) + iadd r0.z, r0.z, r1.x + bfi r0.y, l(6), l(0), r0.w, r0.z +endif +iadd r0.y, r0.y, CB0[0][1].x +ushr r0.y, r0.y, l(4) +ieq r0.z, r0.x, l(4) +if_nz r0.z + mov r6.xyzw, r6.yxwz + mov r0.w, l(2) +else + mov r0.w, r0.x +endif +ieq r1.xyz, r0.wwww, l(1, 2, 3, 0) +or r1.xy, r1.yzyy, r1.xyxx +if_nz r1.x + ishl r2.xyzw, r6.xyzw, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r3.xyzw, r6.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r6.xyzw, r2.xyzw, r3.xyzw +endif +if_nz r1.y + ushr r1.xyzw, r6.xyzw, l(16, 16, 16, 16) + bfi r6.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r6.xyzw, r1.xyzw +endif +store_uav_typed U0[0].xyzw, r0.yyyy, r6.xyzw +iadd r0.y, r0.y, l(2) +if_nz r0.z + mov r7.xyzw, r7.yxwz + mov r0.x, l(2) +endif +ieq r0.xzw, r0.xxxx, l(1, 0, 2, 3) +or r0.xz, r0.zzwz, r0.xxzx +if_nz r0.x + ishl r1.xyzw, r7.xyzw, l(8, 8, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r2.xyzw, r7.xyzw, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r7.xyzw, r1.xyzw, r2.xyzw +endif +if_nz r0.z + ushr r1.xyzw, r7.xyzw, l(16, 16, 16, 16) + bfi r7.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r7.xyzw, r1.xyzw +endif +store_uav_typed U0[0].xyzw, r0.yyyy, r7.xyzw +ret +// Approximately 1254 instruction slots used +#endif + +const BYTE resolve_full_64bpp_cs[] = { + 68, 88, 66, 67, 40, 2, 139, 150, 213, 204, 110, 62, 172, 117, 242, 185, 199, 19, 62, + 252, 1, 0, 0, 0, 192, 151, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 208, 2, + 0, 0, 224, 2, 0, 0, 240, 2, 0, 0, 36, 151, 0, 0, 82, 68, 69, 70, 148, + 2, 0, 0, 1, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 105, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 101, 100, 114, 97, 109, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 213, 0, 0, 0, 5, 0, 0, 0, 252, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 196, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 4, 2, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 31, 2, 0, 0, 8, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 52, 2, 0, 0, 12, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 84, 2, 0, + 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, + 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 101, 100, 114, 97, 109, 95, 105, 110, 102, + 111, 0, 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 218, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 99, 111, + 111, 114, 100, 105, 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 105, 110, 102, 111, 0, 120, 101, 95, + 114, 101, 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 99, 111, 111, 114, 100, 105, + 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 95, 98, 97, 115, 101, 0, 77, 105, 99, 114, 111, 115, 111, + 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, + 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, + 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 44, 148, 0, 0, + 81, 0, 5, 0, 11, 37, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 161, 0, 0, 6, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 95, 0, 0, + 2, 50, 0, 2, 0, 104, 0, 0, 2, 24, 0, 0, 0, 155, 0, 0, 4, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, 242, 0, 16, 0, 0, + 0, 0, 0, 38, 138, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 255, 3, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 1, 85, 0, 0, 12, 114, 0, 16, 0, 1, 0, 0, 0, 86, 135, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, + 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, 242, 0, 16, 0, + 2, 0, 0, 0, 246, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 20, 0, + 0, 0, 41, 0, 0, 9, 146, 0, 16, 0, 3, 0, 0, 0, 6, 0, 2, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, + 26, 0, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 17, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 11, 0, + 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 13, + 0, 0, 0, 24, 0, 0, 0, 28, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, + 0, 20, 50, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 15, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 139, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 128, 63, 140, 0, 0, 13, 18, 0, 16, 0, 5, 0, 0, 0, + 1, 64, 0, 0, 10, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 58, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, + 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 138, 0, 0, 17, 98, 0, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, + 0, 166, 139, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 4, 98, 0, 16, 0, 3, 0, 0, 0, 86, 5, 2, 0, 30, 0, 0, 7, 50, + 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 182, 15, 16, 0, + 3, 0, 0, 0, 80, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 58, 0, + 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 42, + 0, 16, 0, 5, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, 0, + 5, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, + 0, 31, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 34, 0, + 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 18, 0, 0, 1, 54, + 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 1, 21, 0, 0, 1, 80, 0, 0, 10, 194, 0, 16, 0, 6, 0, 0, + 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 6, + 0, 0, 0, 166, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 50, 0, 16, + 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 6, 0, + 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, + 6, 0, 0, 0, 70, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, + 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 6, + 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 80, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 78, 0, 0, 8, 50, 0, + 16, 0, 7, 0, 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 70, + 0, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 35, 0, 0, 10, 50, + 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 128, 65, 0, 0, 0, 7, 0, 0, 0, + 70, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, + 9, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 5, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 78, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 40, 0, 30, 0, 0, 7, + 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, + 0, 16, 0, 4, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 242, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, + 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, + 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, + 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 4, + 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 50, 0, 16, 0, 8, 0, 0, 0, 230, 10, 16, 0, 6, 0, 0, 0, 54, 0, 0, + 5, 50, 0, 16, 0, 9, 0, 0, 0, 230, 10, 16, 0, 7, 0, 0, 0, 18, 0, + 0, 1, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, + 8, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, + 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, + 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, + 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, + 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 4, 0, + 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, + 9, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 7, 0, 0, 0, 26, 0, + 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, + 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, + 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 8, 0, 0, + 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 10, + 0, 0, 0, 38, 7, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, + 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, + 0, 10, 194, 0, 16, 0, 6, 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 42, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 38, 7, 16, 0, 6, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 9, 0, 0, 0, + 6, 4, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 10, 0, + 0, 0, 38, 7, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, + 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, + 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, + 10, 194, 0, 16, 0, 7, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, + 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 38, 7, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, + 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 8, 0, 0, 0, 6, 1, + 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 8, 0, 0, 0, 6, + 4, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, + 70, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 6, 0, + 0, 0, 6, 1, 16, 0, 6, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 6, + 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, + 4, 0, 0, 0, 70, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, + 16, 0, 9, 0, 0, 0, 6, 1, 16, 0, 9, 0, 0, 0, 131, 0, 0, 5, 162, + 0, 16, 0, 9, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, + 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, + 0, 5, 82, 0, 16, 0, 7, 0, 0, 0, 6, 1, 16, 0, 7, 0, 0, 0, 131, + 0, 0, 5, 162, 0, 16, 0, 7, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, + 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 194, 0, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, + 194, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, + 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, + 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 7, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 18, 0, 0, 1, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 34, + 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, + 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, 7, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 41, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, + 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, + 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, + 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 7, 0, 0, + 0, 26, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, + 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, + 1, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, 86, 5, 16, + 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, + 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 26, + 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, + 0, 10, 0, 0, 0, 166, 10, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, + 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 85, 0, 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, 246, 15, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, + 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 7, 0, + 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, + 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, + 0, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, 86, + 5, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, + 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, + 0, 26, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 8, 32, + 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, + 0, 16, 0, 10, 0, 0, 0, 166, 10, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, + 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, 246, 15, 16, 0, + 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 58, 0, + 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 9, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, + 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, + 7, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 2, + 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, + 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, + 0, 86, 9, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 20, 0, + 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, + 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, + 11, 0, 0, 0, 6, 1, 16, 0, 10, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, + 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 15, 114, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, + 135, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, + 0, 30, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, + 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, + 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, + 16, 0, 16, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, + 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 114, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, + 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 11, 0, + 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 11, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, + 0, 70, 2, 16, 0, 11, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 13, 0, + 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, + 0, 11, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, + 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, + 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 10, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 10, 0, 0, 0, 230, 11, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, + 54, 0, 0, 5, 98, 0, 16, 0, 11, 0, 0, 0, 6, 3, 16, 0, 10, 0, 0, + 0, 1, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 14, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 11, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, + 0, 70, 2, 16, 0, 13, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 15, 0, + 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, + 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, + 15, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 128, 65, + 0, 0, 0, 15, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, + 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, + 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 41, 0, + 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, + 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 12, 114, 0, + 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 56, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 58, + 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, + 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 12, 0, + 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 135, 0, 0, 5, 114, + 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 30, 0, 0, 10, + 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, + 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, + 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, + 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 15, 0, 0, + 0, 70, 2, 16, 128, 65, 0, 0, 0, 14, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, + 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, + 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 10, 0, 0, 0, 70, + 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, + 10, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, + 0, 15, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, + 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, + 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, + 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 10, + 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, + 55, 0, 0, 12, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, + 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 10, + 0, 0, 0, 54, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, + 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 86, 0, 0, 5, 50, 0, 16, + 0, 11, 0, 0, 0, 198, 0, 16, 0, 10, 0, 0, 0, 54, 0, 0, 5, 18, 0, + 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, + 0, 0, 15, 114, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 10, 0, + 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 13, + 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, + 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, + 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, + 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 14, + 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, + 140, 0, 0, 17, 114, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, + 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, + 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 13, + 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, + 13, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, + 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, + 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, + 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, + 2, 16, 0, 10, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 7, 0, 0, 0, + 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, + 0, 10, 50, 0, 16, 0, 10, 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 130, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, + 0, 54, 0, 0, 5, 130, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 4, 0, + 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 10, + 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, + 10, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 150, 3, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 11, 0, 0, 0, 6, 1, 16, 0, + 10, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 11, 0, 0, 0, 86, 9, 16, + 0, 7, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, + 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, + 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, + 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 8, + 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, + 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, + 0, 6, 0, 0, 0, 230, 10, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 98, + 0, 16, 0, 7, 0, 0, 0, 166, 11, 16, 0, 10, 0, 0, 0, 42, 0, 0, 10, + 242, 0, 16, 0, 10, 0, 0, 0, 214, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, + 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, + 58, 52, 0, 0, 10, 50, 0, 16, 0, 9, 0, 0, 0, 70, 0, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, + 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 7, 0, 0, 0, 230, 10, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 8, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 10, 0, 0, 0, 150, 3, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, + 0, 0, 5, 18, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, + 131, 0, 0, 5, 34, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, + 0, 131, 0, 0, 5, 18, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 7, 0, + 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 10, + 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, + 7, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, + 0, 10, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, + 16, 0, 7, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 7, 0, 0, 0, 58, + 0, 16, 0, 10, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, + 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 8, + 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 6, 0, 0, 0, 42, 0, + 16, 0, 7, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, + 0, 54, 0, 0, 8, 226, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 226, + 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, + 1, 80, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 5, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 4, + 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 30, 0, 0, 7, 34, 0, 16, + 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 80, 0, + 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 4, 0, 0, 0, 32, 0, 0, 7, 130, + 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 10, 0, 0, 0, 58, + 0, 16, 0, 5, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, + 0, 1, 64, 0, 0, 16, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 11, 0, + 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 12, 0, 0, 0, 230, 10, 16, 0, + 10, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 14, 0, 0, 0, 230, 10, 16, + 0, 11, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, + 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 50, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, + 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 4, 0, + 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, + 10, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 13, 0, 0, 0, + 86, 5, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, 41, 0, 0, + 10, 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, + 0, 0, 8, 50, 0, 16, 0, 14, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, + 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, + 0, 11, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 70, 112, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, + 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, + 194, 0, 16, 0, 12, 0, 0, 0, 6, 4, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, + 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 38, 7, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 43, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, + 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 10, 0, 0, 0, 6, 4, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, + 38, 7, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 13, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, + 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, + 0, 16, 0, 14, 0, 0, 0, 6, 4, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, + 10, 242, 0, 16, 0, 13, 0, 0, 0, 38, 7, 16, 0, 14, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, + 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, + 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, + 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 11, 0, 0, 0, 6, 4, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 38, + 7, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, + 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, + 11, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, + 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 13, + 0, 0, 0, 70, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, + 0, 12, 0, 0, 0, 6, 1, 16, 0, 12, 0, 0, 0, 131, 0, 0, 5, 162, 0, + 16, 0, 12, 0, 0, 0, 6, 4, 16, 0, 13, 0, 0, 0, 85, 0, 0, 10, 50, + 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, + 5, 82, 0, 16, 0, 10, 0, 0, 0, 6, 1, 16, 0, 10, 0, 0, 0, 131, 0, + 0, 5, 162, 0, 16, 0, 10, 0, 0, 0, 6, 4, 16, 0, 13, 0, 0, 0, 85, + 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 14, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 131, 0, 0, 5, 82, 0, 16, 0, 14, 0, 0, 0, 6, 1, 16, 0, 14, 0, + 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 14, 0, 0, 0, 6, 4, 16, 0, 13, + 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 11, 0, 0, 0, 6, 1, + 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 11, 0, 0, 0, 6, + 4, 16, 0, 13, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, + 194, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 18, + 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, + 0, 5, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, + 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, + 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 54, 121, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, + 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 5, + 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 4, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, + 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, + 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, + 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 13, + 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, + 41, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, + 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 13, + 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, + 18, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 6, 112, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, + 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, + 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, + 13, 0, 0, 0, 86, 5, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, + 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, + 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, + 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, + 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, 0, 166, 10, 16, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, + 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 42, 0, 16, 0, 11, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, + 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, + 0, 246, 15, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, + 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, + 10, 226, 0, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, + 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, + 16, 0, 13, 0, 0, 0, 86, 5, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, + 18, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, + 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, + 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, 0, 166, 10, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, + 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 42, 0, 16, + 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, + 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, + 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, + 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 13, + 0, 0, 0, 246, 15, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 13, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, + 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, + 0, 0, 10, 226, 0, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, + 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 13, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, + 128, 58, 171, 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, + 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 13, 0, 0, 0, 86, 9, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 54, + 0, 0, 5, 98, 0, 16, 0, 15, 0, 0, 0, 6, 1, 16, 0, 13, 0, 0, 0, + 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 15, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 17, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, + 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, + 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 11, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, + 0, 0, 19, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, + 0, 20, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, + 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 0, 41, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, + 0, 12, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 86, 0, 0, 5, 50, 0, 16, 0, 13, 0, 0, 0, 230, 10, 16, 0, + 13, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 230, 11, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 16, 0, 0, 0, 42, + 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 16, 0, 0, 0, + 6, 3, 16, 0, 15, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 18, + 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, + 0, 19, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 135, 0, 0, 5, + 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 30, 0, 0, + 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, + 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, + 0, 0, 12, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 21, 0, + 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 20, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, + 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, + 0, 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 140, 0, 0, 17, 114, 0, + 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, + 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, + 0, 16, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, + 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 16, 0, + 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, + 16, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, + 0, 55, 0, 0, 12, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 17, 0, + 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, + 15, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, + 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, + 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, + 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, + 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, + 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, 0, + 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, 0, + 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, 0, + 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, + 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 15, 0, 0, 0, 54, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 30, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 86, 0, + 0, 5, 194, 0, 16, 0, 13, 0, 0, 0, 6, 12, 16, 0, 15, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, + 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 15, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 17, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, + 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, + 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 11, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, + 0, 0, 19, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, + 0, 20, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, + 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 0, 41, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, + 0, 11, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, 171, 170, 170, + 62, 171, 170, 170, 62, 54, 0, 0, 5, 130, 0, 16, 0, 12, 0, 0, 0, 10, 0, + 16, 0, 13, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 10, 0, 0, 0, 26, + 0, 16, 0, 13, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 14, 0, 0, 0, + 42, 0, 16, 0, 13, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 11, 0, 0, + 0, 58, 0, 16, 0, 13, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, + 0, 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 150, + 3, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 15, 0, 0, + 0, 6, 1, 16, 0, 13, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 15, 0, + 0, 0, 86, 9, 16, 0, 11, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, + 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, + 50, 0, 16, 0, 12, 0, 0, 0, 70, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, + 0, 10, 50, 0, 16, 0, 10, 0, 0, 0, 230, 10, 16, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 98, 0, 16, 0, 11, 0, 0, 0, 166, 11, 16, 0, 13, 0, 0, + 0, 42, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 214, 2, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, + 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, + 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 14, 0, 0, 0, 70, + 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, + 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 11, 0, 0, + 0, 230, 10, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 150, 3, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, + 0, 11, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 12, 0, 0, 0, 10, 0, + 16, 0, 13, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 42, + 0, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 10, 0, 0, 0, + 26, 0, 16, 0, 13, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, + 0, 58, 0, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 14, 0, + 0, 0, 42, 0, 16, 0, 13, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 11, + 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, + 11, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 5, + 18, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, + 8, 226, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, + 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 58, 0, + 16, 0, 11, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 14, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 226, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, + 0, 1, 21, 0, 0, 1, 0, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 0, 0, 0, 7, + 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 0, 0, 0, 7, 242, + 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 80, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, + 0, 5, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 31, 0, 4, 3, 42, 0, + 16, 0, 5, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 56, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 128, 62, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 58, + 0, 16, 0, 4, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, + 3, 58, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 242, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, + 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 16, 0, + 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 5, + 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 50, 0, 16, 0, 12, 0, 0, 0, 230, 10, 16, 0, 10, 0, 0, 0, 54, 0, 0, + 5, 50, 0, 16, 0, 14, 0, 0, 0, 230, 10, 16, 0, 11, 0, 0, 0, 18, 0, + 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, + 12, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, + 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, + 0, 5, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, + 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, + 30, 0, 0, 7, 50, 0, 16, 0, 13, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 13, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 13, 0, + 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, + 14, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 11, 0, 0, 0, 26, 0, + 16, 0, 13, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, + 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, + 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 12, 0, 0, + 0, 6, 4, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 13, + 0, 0, 0, 38, 7, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, + 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, + 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, + 0, 10, 194, 0, 16, 0, 10, 0, 0, 0, 6, 4, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 42, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 38, 7, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 14, 0, 0, 0, + 6, 4, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 13, 0, + 0, 0, 38, 7, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, + 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 1, + 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, + 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, + 10, 194, 0, 16, 0, 11, 0, 0, 0, 6, 4, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, + 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 38, 7, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 43, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, + 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 12, 0, 0, 0, 6, 1, + 16, 0, 12, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 12, 0, 0, 0, 6, + 4, 16, 0, 13, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, + 70, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 10, 0, + 0, 0, 6, 1, 16, 0, 10, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 10, + 0, 0, 0, 6, 4, 16, 0, 13, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, + 13, 0, 0, 0, 70, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, + 16, 0, 14, 0, 0, 0, 6, 1, 16, 0, 14, 0, 0, 0, 131, 0, 0, 5, 162, + 0, 16, 0, 14, 0, 0, 0, 6, 4, 16, 0, 13, 0, 0, 0, 85, 0, 0, 10, + 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, + 0, 5, 82, 0, 16, 0, 11, 0, 0, 0, 6, 1, 16, 0, 11, 0, 0, 0, 131, + 0, 0, 5, 162, 0, 16, 0, 11, 0, 0, 0, 6, 4, 16, 0, 13, 0, 0, 0, + 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, + 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, + 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, 41, 0, + 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 11, 0, 0, 0, + 58, 0, 16, 0, 5, 0, 0, 0, 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 34, + 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, + 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, 11, 0, 0, 0, + 58, 0, 16, 0, 5, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 41, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, + 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 13, 0, 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, + 0, 13, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, + 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 11, 0, 0, + 0, 26, 0, 16, 0, 13, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, + 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, + 1, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, 0, 86, 5, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, + 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 26, + 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, + 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 12, + 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, + 0, 13, 0, 0, 0, 166, 10, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, + 0, 16, 0, 13, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, + 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, 0, 246, 15, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, + 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, + 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, + 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, + 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 11, 0, + 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 13, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, + 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, + 0, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, 0, 86, + 5, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, + 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, + 0, 26, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, + 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 12, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 8, 32, + 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, + 0, 16, 0, 13, 0, 0, 0, 166, 10, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 13, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 13, 0, + 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, + 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, 0, 246, 15, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 58, 0, + 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, + 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 13, 0, 0, + 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 14, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, + 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, + 11, 0, 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, + 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 2, + 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, + 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, + 0, 86, 9, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 20, 0, + 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, + 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, + 15, 0, 0, 0, 6, 1, 16, 0, 13, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, + 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, + 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, + 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, + 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, + 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, 0, + 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, 0, + 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, 0, + 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, + 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, + 50, 0, 16, 0, 13, 0, 0, 0, 230, 10, 16, 0, 13, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 15, 0, 0, 0, 230, 11, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 16, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, + 54, 0, 0, 5, 98, 0, 16, 0, 16, 0, 0, 0, 6, 3, 16, 0, 15, 0, 0, + 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 19, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 16, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 20, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 20, 0, + 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, + 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, + 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 128, 65, + 0, 0, 0, 20, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 21, 0, 0, + 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, + 16, 0, 21, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 41, 0, + 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 2, + 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, + 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 55, 0, 0, 12, 114, 0, + 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, + 0, 11, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 18, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, + 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 30, 0, 0, 10, 114, 0, + 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 232, + 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, + 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, + 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 20, 0, 0, 0, 70, + 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, + 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, + 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, + 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 20, + 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, + 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, + 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, + 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, + 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, + 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, + 0, 54, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 10, 0, + 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 86, 0, 0, 5, 194, 0, 16, 0, 13, + 0, 0, 0, 6, 12, 16, 0, 15, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, + 15, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, + 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, + 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, + 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, + 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, + 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, 0, + 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, 0, + 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, 0, + 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, + 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 171, 170, 170, 62, 171, 170, 170, 62, 171, 170, 170, 62, 171, 170, 170, 62, 54, 0, + 0, 5, 130, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 54, + 0, 0, 5, 130, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, + 54, 0, 0, 5, 130, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 13, 0, 0, + 0, 54, 0, 0, 5, 130, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 13, 0, + 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 150, 3, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 54, 0, 0, 5, 82, 0, 16, 0, 15, 0, 0, 0, 6, 1, 16, 0, 13, 0, + 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 15, 0, 0, 0, 86, 9, 16, 0, 11, + 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, + 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 12, 0, 0, + 0, 70, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 10, + 0, 0, 0, 230, 10, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, + 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, + 0, 11, 0, 0, 0, 166, 11, 16, 0, 13, 0, 0, 0, 42, 0, 0, 10, 242, 0, + 16, 0, 13, 0, 0, 0, 214, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, + 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, + 0, 0, 10, 50, 0, 16, 0, 14, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 0, 0, 10, 50, 0, 16, 0, 11, 0, 0, 0, 230, 10, 16, 0, 13, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 14, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 13, 0, 0, 0, 150, 3, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, + 5, 18, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 131, 0, + 0, 5, 34, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 131, + 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, + 131, 0, 0, 5, 34, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, + 0, 131, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 11, 0, + 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 13, + 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, + 11, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, + 0, 13, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, + 0, 26, 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, + 11, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 54, + 0, 0, 8, 226, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, 0, + 0, 0, 7, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, + 70, 14, 16, 0, 12, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 0, 0, + 0, 7, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, + 14, 16, 0, 14, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 11, 0, 0, 0, + 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 30, 0, 0, + 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 42, 0, + 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 4, 0, 0, 0, 32, + 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 4, 0, 0, + 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 14, + 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, + 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 165, 0, 0, 8, 242, 0, + 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 230, 116, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 16, 0, 0, 0, + 230, 10, 16, 0, 14, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 17, 0, 0, + 0, 230, 10, 16, 0, 15, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 34, 0, + 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 16, 0, 0, 0, 26, 0, 16, 0, + 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, + 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, + 50, 0, 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 162, 0, 16, 0, + 4, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, + 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 17, 0, 0, 0, 26, 0, 16, 0, + 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, + 8, 50, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 70, 112, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, + 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, + 41, 0, 0, 10, 194, 0, 16, 0, 16, 0, 0, 0, 6, 4, 16, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 38, 7, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, + 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, + 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, + 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 14, 0, + 0, 0, 6, 4, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, + 18, 0, 0, 0, 38, 7, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, + 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, + 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, + 0, 0, 10, 194, 0, 16, 0, 17, 0, 0, 0, 6, 4, 16, 0, 17, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 42, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 38, 7, 16, 0, 17, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, + 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, + 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, + 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, 0, 70, + 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, + 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 15, 0, 0, + 0, 6, 4, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 18, + 0, 0, 0, 38, 7, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, + 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, + 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, + 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, 10, 162, + 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, + 5, 82, 0, 16, 0, 16, 0, 0, 0, 6, 1, 16, 0, 16, 0, 0, 0, 131, 0, + 0, 5, 162, 0, 16, 0, 16, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 85, + 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 14, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 131, 0, 0, 5, 82, 0, 16, 0, 14, 0, 0, 0, 6, 1, 16, 0, 14, 0, + 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 14, 0, 0, 0, 86, 13, 16, 0, 4, + 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, + 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 17, 0, 0, 0, 6, 1, + 16, 0, 17, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 17, 0, 0, 0, 86, + 13, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, + 6, 4, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 15, 0, + 0, 0, 6, 1, 16, 0, 15, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 15, + 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, + 54, 0, 0, 8, 194, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 17, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, + 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 242, 0, 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, + 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, + 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 15, 0, 0, 0, 26, + 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 66, 0, 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 50, + 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 1, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 15, 0, 0, 0, 10, + 0, 16, 0, 1, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 165, 0, 0, 8, 18, 0, 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, + 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, + 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 226, 0, 16, 0, 18, 0, 0, 0, 86, 5, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 26, 0, 16, 0, 15, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, + 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 86, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, 18, + 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 18, 0, 0, 0, 166, 10, 16, + 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, + 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 42, + 0, 16, 0, 15, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, + 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 18, 0, + 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 14, + 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, + 0, 18, 0, 0, 0, 246, 15, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, + 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, + 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 6, 0, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, + 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, + 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, + 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 85, 0, + 0, 10, 226, 0, 16, 0, 18, 0, 0, 0, 86, 5, 16, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, + 54, 0, 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 26, 0, 16, 0, 15, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, + 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, + 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, + 0, 18, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, + 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 18, 0, 0, 0, 166, + 10, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, + 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 18, 0, 0, + 0, 42, 0, 16, 0, 15, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 18, 0, + 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, + 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 14, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 8, 32, + 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, + 0, 16, 0, 18, 0, 0, 0, 246, 15, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, 0, 70, 14, 16, 0, 18, 0, + 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, + 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 6, 0, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 18, 0, 0, 0, + 70, 14, 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, + 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, + 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, + 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, + 85, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 86, 9, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 30, 0, + 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 19, 0, 0, 0, 26, 0, 16, 0, 15, + 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 19, 0, 0, 0, 6, 1, 16, 0, + 18, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, 4, 0, 0, 0, 6, 9, 16, + 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 21, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, + 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, + 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, 232, 255, + 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, + 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, + 22, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 23, 0, 0, 0, 70, 2, + 16, 128, 65, 0, 0, 0, 22, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 23, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, + 0, 70, 2, 16, 0, 23, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, + 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, + 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 41, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 23, 0, + 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, + 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, + 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 55, 0, 0, + 12, 114, 0, 16, 0, 16, 0, 0, 0, 150, 7, 16, 0, 4, 0, 0, 0, 70, 2, + 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 50, 0, 16, 0, 1, 0, 0, 0, + 230, 10, 16, 0, 18, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, + 0, 230, 11, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 19, + 0, 0, 0, 42, 0, 16, 0, 15, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, + 19, 0, 0, 0, 6, 3, 16, 0, 18, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, + 0, 4, 0, 0, 0, 6, 9, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 114, + 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 15, 114, 0, 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 135, 0, 0, 5, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, + 0, 30, 0, 0, 10, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, 0, + 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, + 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, + 20, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, + 16, 0, 23, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 22, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 23, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, + 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 140, 0, + 0, 17, 114, 0, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, + 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, + 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, + 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, + 0, 70, 2, 16, 0, 19, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 20, 0, + 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, + 0, 19, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 150, 7, + 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, + 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 171, 170, 170, 62, 171, 170, 170, 62, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 1, + 0, 0, 10, 226, 0, 16, 0, 4, 0, 0, 0, 6, 9, 16, 0, 18, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 18, 0, + 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, + 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 18, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 21, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 21, 0, 0, 0, + 70, 2, 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, + 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 21, 0, + 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 11, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, + 0, 21, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 22, 0, 0, 0, 70, + 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, + 22, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, + 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, + 0, 9, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 41, 0, 0, 10, + 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, + 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, + 41, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 19, + 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, + 17, 0, 0, 0, 150, 7, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 54, 0, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, + 30, 0, 0, 0, 86, 0, 0, 5, 98, 0, 16, 0, 4, 0, 0, 0, 6, 3, 16, + 0, 18, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 10, 0, + 16, 0, 15, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, + 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 21, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 135, 0, 0, 5, 114, 0, + 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 30, 0, 0, 10, 114, + 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, + 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, + 12, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, + 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 23, 0, 0, 0, + 70, 2, 16, 128, 65, 0, 0, 0, 22, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, + 16, 0, 23, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, + 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, + 18, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 18, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, + 18, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, + 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, + 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, + 23, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, + 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, + 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 18, 0, + 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 55, + 0, 0, 12, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, 98, 0, 16, 0, 4, 0, + 0, 0, 86, 6, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 171, + 170, 170, 62, 171, 170, 170, 62, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, + 16, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, + 0, 14, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, + 16, 0, 17, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, + 0, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 2, 0, 0, 1, + 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 18, 0, 0, 0, 150, 3, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, 82, + 0, 16, 0, 19, 0, 0, 0, 6, 1, 16, 0, 18, 0, 0, 0, 54, 0, 0, 5, + 162, 0, 16, 0, 19, 0, 0, 0, 86, 9, 16, 0, 15, 0, 0, 0, 42, 0, 0, + 10, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, + 0, 0, 5, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, + 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, + 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 16, 0, 0, 0, 70, 0, 16, 0, 19, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, + 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 14, 0, 0, 0, 230, 10, 16, + 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 15, 0, 0, 0, 166, + 11, 16, 0, 18, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, + 214, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 18, 0, + 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 18, + 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, + 0, 17, 0, 0, 0, 70, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, + 0, 16, 0, 15, 0, 0, 0, 230, 10, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 14, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 17, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, + 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, + 0, 150, 3, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 16, + 0, 0, 0, 26, 0, 16, 0, 15, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, + 16, 0, 0, 0, 10, 0, 16, 0, 18, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, + 0, 14, 0, 0, 0, 42, 0, 16, 0, 15, 0, 0, 0, 131, 0, 0, 5, 34, 0, + 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, 18, 0, 0, 0, 131, 0, 0, 5, 18, + 0, 16, 0, 17, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 131, 0, 0, 5, + 34, 0, 16, 0, 17, 0, 0, 0, 42, 0, 16, 0, 18, 0, 0, 0, 131, 0, 0, + 5, 18, 0, 16, 0, 15, 0, 0, 0, 10, 0, 16, 0, 15, 0, 0, 0, 131, 0, + 0, 5, 34, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 54, + 0, 0, 8, 194, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 17, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, 0, + 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 16, 0, 0, 0, 26, 0, 16, 0, 15, + 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 15, 0, 0, 0, 54, 0, + 0, 8, 226, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, + 17, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, + 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, 0, 0, 0, 7, 242, 0, 16, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 16, 0, + 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 17, 0, 0, + 0, 0, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 130, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, + 21, 0, 0, 1, 56, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 246, 15, 16, + 0, 1, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 56, 0, 0, 7, 242, 0, + 16, 0, 6, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 134, 7, 16, 0, 6, + 0, 0, 0, 56, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 246, 15, 16, 0, + 1, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 56, 0, 0, 7, 242, 0, 16, + 0, 7, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 134, 7, 16, 0, 7, 0, + 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 82, + 0, 16, 0, 4, 0, 0, 0, 166, 8, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, + 82, 0, 16, 0, 9, 0, 0, 0, 86, 4, 16, 0, 6, 0, 0, 0, 54, 0, 0, + 5, 82, 0, 16, 0, 8, 0, 0, 0, 166, 8, 16, 0, 8, 0, 0, 0, 54, 0, + 0, 5, 82, 0, 16, 0, 10, 0, 0, 0, 86, 4, 16, 0, 7, 0, 0, 0, 18, + 0, 0, 1, 54, 0, 0, 5, 82, 0, 16, 0, 9, 0, 0, 0, 6, 1, 16, 0, + 6, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 10, 0, 0, 0, 6, 1, 16, + 0, 7, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 26, 0, 16, 0, 5, 0, + 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 26, 0, 0, 0, 54, 32, 0, 5, 242, + 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 50, 0, 0, 15, + 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 0, 255, 127, 71, 0, 255, 127, 71, 0, 255, 127, 71, 0, 255, 127, 71, 2, 64, + 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, + 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 35, 0, 0, 12, 50, 0, 16, 0, 6, 0, 0, 0, 214, 5, 16, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 134, 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 9, + 0, 0, 0, 246, 11, 16, 0, 6, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, + 0, 11, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 255, + 127, 71, 0, 255, 127, 71, 0, 255, 127, 71, 0, 255, 127, 71, 2, 64, 0, 0, 0, + 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, + 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 35, 0, 0, + 12, 194, 0, 16, 0, 6, 0, 0, 0, 86, 13, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 6, + 8, 16, 0, 11, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, + 70, 14, 16, 0, 8, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, + 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 255, 127, 71, 0, 255, + 127, 71, 0, 255, 127, 71, 0, 255, 127, 71, 2, 64, 0, 0, 0, 0, 0, 63, 0, + 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, + 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, + 0, 7, 0, 0, 0, 214, 5, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 0, 16, 0, 11, + 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 10, 0, 0, 0, 246, 11, 16, 0, + 7, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 255, 127, 71, 0, 255, 127, 71, 0, + 255, 127, 71, 0, 255, 127, 71, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, + 0, 70, 14, 16, 0, 11, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, 0, 7, 0, + 0, 0, 86, 13, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 6, 8, 16, 0, 11, 0, 0, 0, + 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 32, 0, 0, 0, 130, 0, 0, + 5, 162, 0, 16, 0, 0, 0, 0, 0, 6, 8, 16, 0, 4, 0, 0, 0, 130, 0, + 0, 5, 50, 0, 16, 0, 1, 0, 0, 0, 214, 5, 16, 0, 4, 0, 0, 0, 35, + 0, 0, 12, 50, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 214, 5, 16, 0, 0, 0, 0, 0, 130, 0, 0, 5, 162, 0, 16, 0, 0, 0, + 0, 0, 6, 8, 16, 0, 9, 0, 0, 0, 130, 0, 0, 5, 50, 0, 16, 0, 1, + 0, 0, 0, 182, 15, 16, 0, 6, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, 0, + 6, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 86, 13, 16, 0, 0, 0, + 0, 0, 130, 0, 0, 5, 162, 0, 16, 0, 0, 0, 0, 0, 6, 8, 16, 0, 8, + 0, 0, 0, 130, 0, 0, 5, 50, 0, 16, 0, 1, 0, 0, 0, 214, 5, 16, 0, + 8, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 7, 0, 0, 0, 70, 0, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 214, 5, 16, 0, 0, 0, 0, 0, 130, 0, 0, 5, 162, + 0, 16, 0, 0, 0, 0, 0, 6, 8, 16, 0, 10, 0, 0, 0, 130, 0, 0, 5, + 50, 0, 16, 0, 1, 0, 0, 0, 182, 15, 16, 0, 7, 0, 0, 0, 35, 0, 0, + 12, 194, 0, 16, 0, 7, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 86, + 13, 16, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 5, + 50, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, + 5, 66, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 54, 0, + 0, 5, 50, 0, 16, 0, 7, 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 54, + 0, 0, 5, 66, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, + 2, 0, 0, 1, 23, 0, 0, 1, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 31, 0, + 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 11, 34, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 5, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 230, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, + 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 254, 7, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, + 5, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 48, 0, + 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, + 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 20, 98, + 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, + 19, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 11, 0, 0, + 0, 14, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, + 0, 0, 12, 50, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 150, 5, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 35, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 35, + 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, + 17, 98, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, + 86, 6, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, 34, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 18, 0, 0, 1, 42, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 2, + 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 50, + 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 128, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, + 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 22, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 2, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, + 0, 140, 0, 0, 17, 98, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 13, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, + 0, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, + 0, 2, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, + 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 6, 0, 0, 0, 22, 11, 16, 0, + 6, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 32, 0, 0, 10, 114, + 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, + 7, 50, 0, 16, 0, 1, 0, 0, 0, 150, 5, 16, 0, 1, 0, 0, 0, 70, 0, + 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, + 1, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, 0, + 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, + 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, + 14, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 42, + 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 7, 0, 0, 0, + 22, 11, 16, 0, 7, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 21, 0, 0, 1, 32, 0, 0, 10, 210, 0, + 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, + 82, 0, 16, 0, 0, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 6, 2, 16, + 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, + 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, + 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, + 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, + 0, 1, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, + 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, + 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 230, 4, 0, + 0, 24, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 116, 0, 0, 0, 10, 1, + 0, 0, 178, 0, 0, 0, 59, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188, 0, 0, + 0, 64, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_64bpp_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_64bpp_scaled_cs.h new file mode 100644 index 0000000..a79db47 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_64bpp_scaled_cs.h @@ -0,0 +1,3478 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_resolve_edram_info; // Offset: 0 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 4 Size: 4 +// uint xe_resolve_dest_info; // Offset: 8 Size: 4 +// uint xe_resolve_dest_coordinate_info;// Offset: 12 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram texture byte r/o T0 t0 1 +// xe_resolve_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_raw T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 24 +dcl_thread_group 8, 8, 1 +and r0.xyzw, CB0[0][0].zxxz, l(7, 1023, 0x20000000, 8) +if_nz r0.z + ubfe r1.xy, l(2, 2, 0, 0), l(17, 20, 0, 0), CB0[0][0].yyyy +else + mov r1.xy, l(0,0,0,0) +endif +ubfe r2.xyz, l(3, 3, 11, 0), l(16, 19, 5, 0), CB0[0][0].yyyy +imul null, r0.z, r2.x, r2.z +and r1.z, CB0[0][0].z, l(0x01000000) +ushr r3.xyzw, CB0[0][0].ywww, l(4, 10, 20, 24) +ishl r4.x, vThreadID.x, l(2) +ishl r0.z, r0.z, l(3) +uge r0.z, r4.x, r0.z +if_nz r0.z + ret +endif +ubfe r5.xyzw, l(2, 11, 4, 1), l(10, 13, 24, 28), CB0[0][0].xxxx +mov r6.x, CB0[0][0].y +mov r6.y, r3.x +bfi r2.zw, l(0, 0, 4, 1), l(0, 0, 3, 3), r6.xxxy, l(0, 0, 0, 0) +ibfe r0.z, l(6), l(16), CB0[0][0].z +ishl r0.z, r0.z, l(23) +iadd r0.z, r0.z, l(0x3f800000) +bfi r1.w, l(10), l(5), CB0[0][0].w, l(0) +bfi r3.xz, l(4, 0, 4, 0), l(3, 0, 3, 0), r3.zzwz, l(0, 0, 0, 0) +ubfe r6.xy, l(6, 3, 0, 0), l(7, 28, 0, 0), CB0[0][0].zwzz +umax r4.y, r1.y, vThreadID.y +imad r2.zw, r2.zzzw, r2.xxxy, r4.xxxy +uge r1.y, l(3), r6.y +if_nz r1.y + mov r7.y, r6.y +else + ieq r1.y, r6.y, l(5) + if_nz r1.y + mov r7.y, l(2) + else + mov r7.y, l(0) + endif +endif +uge r4.yw, r5.xxxx, l(0, 2, 0, 1) +and r4.yw, r4.yyyw, l(0, 1, 0, 1) +ishl r2.zw, r2.zzzw, r4.yyyw +ushr r7.x, r7.y, l(1) +and r6.zw, r7.xxxy, l(0, 0, 1, 1) +iadd r2.zw, r2.zzzw, r6.zzzw +imul null, r7.yz, r2.xxyx, l(0, 80, 16, 0) +ushr r7.x, r7.y, r5.w +udiv r6.zw, null, r2.zzzw, r7.xxxz +imad r0.y, r6.w, r0.y, r6.z +iadd r0.y, r0.y, r5.y +imad r2.zw, -r6.zzzw, r7.xxxz, r2.zzzw +imul null, r1.y, r7.z, r7.y +imad r2.z, r2.w, r7.x, r2.z +ishl r2.z, r2.z, r5.w +imad r0.y, r0.y, r1.y, r2.z +ishl r1.y, r1.y, l(11) +udiv null, r0.y, r0.y, r1.y +iadd r1.y, r4.y, r5.w +ishl r2.z, l(1), r1.y +if_nz r5.w + ieq r2.w, r2.z, l(2) + if_nz r2.w + ishl r2.w, r0.y, l(2) + ld_raw r7.xyzw, r2.w, T0[0].zwxy + iadd r2.w, r2.w, l(16) + ld_raw r8.xyzw, r2.w, T0[0].zwxy + mov r9.xy, r7.zwzz + mov r10.xy, r8.zwzz + else + ishl r2.w, r0.y, l(2) + ld_raw r9.xy, r2.w, T0[0].xyxx + iadd r2.w, r0.y, r2.z + ishl r2.w, r2.w, l(2) + ld_raw r7.xy, r2.w, T0[0].xyxx + ishl r4.yw, l(0, 2, 0, 3), r1.yyyy + iadd r4.yw, r0.yyyy, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r10.xy, r4.y, T0[0].xyxx + ld_raw r8.xy, r4.w, T0[0].xyxx + endif + switch r5.z + case l(5) + ishl r9.zw, r9.xxxy, l(0, 0, 16, 16) + ishr r11.xyzw, r9.zxwy, l(16, 16, 16, 16) + itof r11.xyzw, r11.xyzw + mul r11.xyzw, r11.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xyzw, r11.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r7.zw, r7.xxxy, l(0, 0, 16, 16) + ishr r11.xyzw, r7.zxwy, l(16, 16, 16, 16) + itof r11.xyzw, r11.xyzw + mul r11.xyzw, r11.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r7.xyzw, r11.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r10.zw, r10.xxxy, l(0, 0, 16, 16) + ishr r11.xyzw, r10.zxwy, l(16, 16, 16, 16) + itof r11.xyzw, r11.xyzw + mul r11.xyzw, r11.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r10.xyzw, r11.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r8.zw, r8.xxxy, l(0, 0, 16, 16) + ishr r11.xyzw, r8.zxwy, l(16, 16, 16, 16) + itof r11.xyzw, r11.xyzw + mul r11.xyzw, r11.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xyzw, r11.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.yw, r9.xxxy, l(0, 16, 0, 16) + f16tof32 r9.xz, r9.xxyx + f16tof32 r9.yw, r4.yyyw + ushr r4.yw, r7.xxxy, l(0, 16, 0, 16) + f16tof32 r7.xz, r7.xxyx + f16tof32 r7.yw, r4.yyyw + ushr r4.yw, r10.xxxy, l(0, 16, 0, 16) + f16tof32 r10.xz, r10.xxyx + f16tof32 r10.yw, r4.yyyw + ushr r4.yw, r8.xxxy, l(0, 16, 0, 16) + f16tof32 r8.xz, r8.xxyx + f16tof32 r8.yw, r4.yyyw + break + default + mov r9.zw, l(0,0,0,0) + mov r7.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + endswitch +else + ieq r2.w, r2.z, l(1) + if_nz r2.w + ishl r2.w, r0.y, l(2) + ld_raw r8.xyzw, r2.w, T0[0].wxyz + else + ishl r2.w, r0.y, l(2) + ld_raw r8.y, r2.w, T0[0].xxxx + iadd r2.w, r0.y, r2.z + ishl r2.w, r2.w, l(2) + ld_raw r8.z, r2.w, T0[0].xxxx + ishl r4.yw, l(0, 2, 0, 3), r1.yyyy + iadd r4.yw, r0.yyyy, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r8.w, r4.y, T0[0].xxxx + ld_raw r8.x, r4.w, T0[0].xxxx + endif + switch r5.z + case l(0) + case l(1) + ushr r11.yzw, r8.yyyy, l(0, 8, 16, 24) + mov r11.x, r8.y + and r11.xyzw, r11.xyzw, l(255, 255, 255, 255) + utof r11.xyzw, r11.xyzw + mul r9.xyzw, r11.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r11.yzw, r8.zzzz, l(0, 8, 16, 24) + mov r11.x, r8.z + and r11.xyzw, r11.xyzw, l(255, 255, 255, 255) + utof r11.xyzw, r11.xyzw + mul r7.xyzw, r11.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r11.yzw, r8.wwww, l(0, 8, 16, 24) + mov r11.x, r8.w + and r11.xyzw, r11.xyzw, l(255, 255, 255, 255) + utof r11.xyzw, r11.xyzw + mul r10.xyzw, r11.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r8.yzw, r8.xxxx, l(0, 8, 16, 24) + and r11.xyzw, r8.xyzw, l(255, 255, 255, 255) + utof r11.xyzw, r11.xyzw + mul r8.xyzw, r11.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r11.yzw, r8.yyyy, l(0, 10, 20, 30) + mov r11.x, r8.y + and r11.xyzw, r11.xyzw, l(1023, 1023, 1023, 3) + utof r11.xyzw, r11.xyzw + mul r9.xyzw, r11.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r11.yzw, r8.zzzz, l(0, 10, 20, 30) + mov r11.x, r8.z + and r11.xyzw, r11.xyzw, l(1023, 1023, 1023, 3) + utof r11.xyzw, r11.xyzw + mul r7.xyzw, r11.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r11.yzw, r8.wwww, l(0, 10, 20, 30) + mov r11.x, r8.w + and r11.xyzw, r11.xyzw, l(1023, 1023, 1023, 3) + utof r11.xyzw, r11.xyzw + mul r10.xyzw, r11.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r8.yzw, r8.xxxx, l(0, 10, 20, 30) + and r11.xyzw, r8.xyzw, l(1023, 1023, 1023, 3) + utof r11.xyzw, r11.xyzw + mul r8.xyzw, r11.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r11.xyzw, r8.yyyz, l(10, 20, 30, 30) + mov r12.x, r8.y + mov r12.yz, r11.xxyx + and r13.xyz, r12.xyzx, l(1023, 1023, 1023, 0) + and r14.xyz, r12.xyzx, l(127, 127, 127, 0) + ubfe r15.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r12.xyzx + firstbit_hi r16.xyz, r14.xyzx + iadd r16.xyz, r16.xyzx, l(-24, -24, -24, 0) + movc r16.xyz, r14.xyzx, r16.xyzx, l(8,8,8,0) + iadd r17.xyz, -r16.xyzx, l(1, 1, 1, 0) + movc r17.xyz, r15.xyzx, r15.xyzx, r17.xyzx + bfi r12.xyz, l(7, 7, 7, 0), r16.xyzx, r12.xyzx, l(0, 0, 0, 0) + and r12.xyz, r12.xyzx, l(127, 127, 127, 0) + movc r12.xyz, r15.xyzx, r14.xyzx, r12.xyzx + ishl r14.xyz, r17.xyzx, l(23, 23, 23, 0) + iadd r14.xyz, r14.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r12.xyz, r12.xyzx, l(16, 16, 16, 0) + iadd r12.xyz, r14.xyzx, r12.xyzx + movc r9.xyz, r13.xyzx, r12.xyzx, l(0,0,0,0) + utof r4.yw, r11.zzzw + ushr r11.xyzw, r8.zwwz, l(10, 10, 20, 20) + mov r12.x, r8.z + mov r12.yz, r11.xxwx + and r13.xyz, r12.xyzx, l(1023, 1023, 1023, 0) + and r14.xyz, r12.xyzx, l(127, 127, 127, 0) + ubfe r15.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r12.xyzx + firstbit_hi r16.xyz, r14.xyzx + iadd r16.xyz, r16.xyzx, l(-24, -24, -24, 0) + movc r16.xyz, r14.xyzx, r16.xyzx, l(8,8,8,0) + iadd r17.xyz, -r16.xyzx, l(1, 1, 1, 0) + movc r17.xyz, r15.xyzx, r15.xyzx, r17.xyzx + bfi r12.xyz, l(7, 7, 7, 0), r16.xyzx, r12.xyzx, l(0, 0, 0, 0) + and r12.xyz, r12.xyzx, l(127, 127, 127, 0) + movc r12.xyz, r15.xyzx, r14.xyzx, r12.xyzx + ishl r14.xyz, r17.xyzx, l(23, 23, 23, 0) + iadd r14.xyz, r14.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r12.xyz, r12.xyzx, l(16, 16, 16, 0) + iadd r12.xyz, r14.xyzx, r12.xyzx + movc r7.xyz, r13.xyzx, r12.xyzx, l(0,0,0,0) + mul r4.yw, r4.yyyw, l(0.000000, 0.333333, 0.000000, 0.333333) + mov r11.x, r8.w + and r12.xyz, r11.xyzx, l(1023, 1023, 1023, 0) + and r13.xyz, r11.xyzx, l(127, 127, 127, 0) + ubfe r14.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r11.xyzx + firstbit_hi r15.xyz, r13.xyzx + iadd r15.xyz, r15.xyzx, l(-24, -24, -24, 0) + movc r15.xyz, r13.xyzx, r15.xyzx, l(8,8,8,0) + iadd r16.xyz, -r15.xyzx, l(1, 1, 1, 0) + movc r16.xyz, r14.xyzx, r14.xyzx, r16.xyzx + bfi r11.xyz, l(7, 7, 7, 0), r15.xyzx, r11.xyzx, l(0, 0, 0, 0) + and r11.xyz, r11.xyzx, l(127, 127, 127, 0) + movc r11.xyz, r14.xyzx, r13.xyzx, r11.xyzx + ishl r13.xyz, r16.xyzx, l(23, 23, 23, 0) + iadd r13.xyz, r13.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r11.xyz, r11.xyzx, l(16, 16, 16, 0) + iadd r11.xyz, r13.xyzx, r11.xyzx + movc r10.xyz, r12.xyzx, r11.xyzx, l(0,0,0,0) + ushr r11.xyzw, r8.wxxx, l(30, 10, 20, 30) + utof r5.xy, r11.xwxx + mov r11.x, r8.x + and r12.xyz, r11.xyzx, l(1023, 1023, 1023, 0) + and r13.xyz, r11.xyzx, l(127, 127, 127, 0) + ubfe r14.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r11.xyzx + firstbit_hi r15.xyz, r13.xyzx + iadd r15.xyz, r15.xyzx, l(-24, -24, -24, 0) + movc r15.xyz, r13.xyzx, r15.xyzx, l(8,8,8,0) + iadd r16.xyz, -r15.xyzx, l(1, 1, 1, 0) + movc r16.xyz, r14.xyzx, r14.xyzx, r16.xyzx + bfi r11.xyz, l(7, 7, 7, 0), r15.xyzx, r11.xyzx, l(0, 0, 0, 0) + and r11.xyz, r11.xyzx, l(127, 127, 127, 0) + movc r11.xyz, r14.xyzx, r13.xyzx, r11.xyzx + ishl r13.xyz, r16.xyzx, l(23, 23, 23, 0) + iadd r13.xyz, r13.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r11.xyz, r11.xyzx, l(16, 16, 16, 0) + iadd r11.xyz, r13.xyzx, r11.xyzx + movc r8.xyz, r12.xyzx, r11.xyzx, l(0,0,0,0) + mul r5.xy, r5.xyxx, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r9.w, r4.y + mov r7.w, r4.w + mov r10.w, r5.x + mov r8.w, r5.y + break + case l(4) + ishl r11.xyzw, r8.yzwx, l(16, 16, 16, 16) + mov r12.xz, r11.xxyx + mov r12.yw, r8.yyyz + ishr r12.xyzw, r12.xyzw, l(16, 16, 16, 16) + itof r12.xyzw, r12.xyzw + mul r12.xyzw, r12.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xy, r12.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r7.xy, r12.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r8.yz, r11.zzwz + ishr r11.xyzw, r8.ywzx, l(16, 16, 16, 16) + itof r11.xyzw, r11.xyzw + mul r11.xyzw, r11.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r10.xy, r11.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r8.xy, r11.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r9.zw, l(0,0,0,0) + mov r7.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + case l(6) + ushr r11.xyzw, r8.yzwx, l(16, 16, 16, 16) + f16tof32 r9.x, r8.y + f16tof32 r9.y, r11.x + f16tof32 r7.x, r8.z + f16tof32 r7.y, r11.y + f16tof32 r10.x, r8.w + f16tof32 r10.y, r11.z + f16tof32 r8.x, r8.x + f16tof32 r8.y, r11.w + mov r9.zw, l(0,0,0,0) + mov r7.zw, l(0,0,0,0) + mov r10.zw, l(0,0,0,0) + mov r8.zw, l(0,0,0,0) + break + default + mov r9.x, r8.y + mov r9.yzw, l(0,0,0,0) + mov r7.x, r8.z + mov r7.yzw, l(0,0,0,0) + mov r10.x, r8.w + mov r10.yzw, l(0,0,0,0) + mov r8.yzw, l(0,0,0,0) + break + endswitch +endif +uge r2.w, r6.y, l(4) +if_nz r2.w + mul r2.w, r0.z, l(0.500000) + imad r3.w, l(80), r2.x, r0.y + if_nz r5.w + ieq r4.y, r2.z, l(2) + if_nz r4.y + ishl r4.y, r3.w, l(2) + ld_raw r11.xyzw, r4.y, T0[0].zwxy + iadd r4.y, r4.y, l(16) + ld_raw r12.xyzw, r4.y, T0[0].zwxy + mov r13.xy, r11.zwzz + mov r14.xy, r12.zwzz + else + ishl r4.y, r3.w, l(2) + ld_raw r13.xy, r4.y, T0[0].xyxx + iadd r4.y, r2.z, r3.w + ishl r4.y, r4.y, l(2) + ld_raw r11.xy, r4.y, T0[0].xyxx + ishl r4.yw, l(0, 2, 0, 3), r1.yyyy + iadd r4.yw, r3.wwww, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r14.xy, r4.y, T0[0].xyxx + ld_raw r12.xy, r4.w, T0[0].xyxx + endif + switch r5.z + case l(5) + ishl r13.zw, r13.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r13.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r13.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r11.zw, r11.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r11.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r11.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r14.zw, r14.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r14.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r12.zw, r12.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r12.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r12.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.yw, r13.xxxy, l(0, 16, 0, 16) + f16tof32 r13.xz, r13.xxyx + f16tof32 r13.yw, r4.yyyw + ushr r4.yw, r11.xxxy, l(0, 16, 0, 16) + f16tof32 r11.xz, r11.xxyx + f16tof32 r11.yw, r4.yyyw + ushr r4.yw, r14.xxxy, l(0, 16, 0, 16) + f16tof32 r14.xz, r14.xxyx + f16tof32 r14.yw, r4.yyyw + ushr r4.yw, r12.xxxy, l(0, 16, 0, 16) + f16tof32 r12.xz, r12.xxyx + f16tof32 r12.yw, r4.yyyw + break + default + mov r13.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r12.zw, l(0,0,0,0) + break + endswitch + else + ieq r4.y, r2.z, l(1) + if_nz r4.y + ishl r4.y, r3.w, l(2) + ld_raw r12.xyzw, r4.y, T0[0].wxyz + else + ishl r4.y, r3.w, l(2) + ld_raw r12.y, r4.y, T0[0].xxxx + iadd r4.y, r2.z, r3.w + ishl r4.y, r4.y, l(2) + ld_raw r12.z, r4.y, T0[0].xxxx + ishl r4.yw, l(0, 2, 0, 3), r1.yyyy + iadd r4.yw, r3.wwww, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r12.w, r4.y, T0[0].xxxx + ld_raw r12.x, r4.w, T0[0].xxxx + endif + switch r5.z + case l(0) + case l(1) + ushr r15.yzw, r12.yyyy, l(0, 8, 16, 24) + mov r15.x, r12.y + and r15.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r13.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r15.yzw, r12.zzzz, l(0, 8, 16, 24) + mov r15.x, r12.z + and r15.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r11.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r15.yzw, r12.wwww, l(0, 8, 16, 24) + mov r15.x, r12.w + and r15.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r14.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r12.yzw, r12.xxxx, l(0, 8, 16, 24) + and r15.xyzw, r12.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r12.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r15.yzw, r12.yyyy, l(0, 10, 20, 30) + mov r15.x, r12.y + and r15.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r13.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r15.yzw, r12.zzzz, l(0, 10, 20, 30) + mov r15.x, r12.z + and r15.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r11.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r15.yzw, r12.wwww, l(0, 10, 20, 30) + mov r15.x, r12.w + and r15.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r14.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r12.yzw, r12.xxxx, l(0, 10, 20, 30) + and r15.xyzw, r12.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r12.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r15.xyzw, r12.yyyz, l(10, 20, 30, 30) + mov r16.x, r12.y + mov r16.yz, r15.xxyx + and r17.xyz, r16.xyzx, l(1023, 1023, 1023, 0) + and r18.xyz, r16.xyzx, l(127, 127, 127, 0) + ubfe r19.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r16.xyzx + firstbit_hi r20.xyz, r18.xyzx + iadd r20.xyz, r20.xyzx, l(-24, -24, -24, 0) + movc r20.xyz, r18.xyzx, r20.xyzx, l(8,8,8,0) + iadd r21.xyz, -r20.xyzx, l(1, 1, 1, 0) + movc r21.xyz, r19.xyzx, r19.xyzx, r21.xyzx + bfi r16.xyz, l(7, 7, 7, 0), r20.xyzx, r16.xyzx, l(0, 0, 0, 0) + and r16.xyz, r16.xyzx, l(127, 127, 127, 0) + movc r16.xyz, r19.xyzx, r18.xyzx, r16.xyzx + ishl r18.xyz, r21.xyzx, l(23, 23, 23, 0) + iadd r18.xyz, r18.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r16.xyz, r16.xyzx, l(16, 16, 16, 0) + iadd r16.xyz, r18.xyzx, r16.xyzx + movc r13.xyz, r17.xyzx, r16.xyzx, l(0,0,0,0) + utof r4.yw, r15.zzzw + ushr r15.xyzw, r12.zwwz, l(10, 10, 20, 20) + mov r16.x, r12.z + mov r16.yz, r15.xxwx + and r17.xyz, r16.xyzx, l(1023, 1023, 1023, 0) + and r18.xyz, r16.xyzx, l(127, 127, 127, 0) + ubfe r19.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r16.xyzx + firstbit_hi r20.xyz, r18.xyzx + iadd r20.xyz, r20.xyzx, l(-24, -24, -24, 0) + movc r20.xyz, r18.xyzx, r20.xyzx, l(8,8,8,0) + iadd r21.xyz, -r20.xyzx, l(1, 1, 1, 0) + movc r21.xyz, r19.xyzx, r19.xyzx, r21.xyzx + bfi r16.xyz, l(7, 7, 7, 0), r20.xyzx, r16.xyzx, l(0, 0, 0, 0) + and r16.xyz, r16.xyzx, l(127, 127, 127, 0) + movc r16.xyz, r19.xyzx, r18.xyzx, r16.xyzx + ishl r18.xyz, r21.xyzx, l(23, 23, 23, 0) + iadd r18.xyz, r18.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r16.xyz, r16.xyzx, l(16, 16, 16, 0) + iadd r16.xyz, r18.xyzx, r16.xyzx + movc r11.xyz, r17.xyzx, r16.xyzx, l(0,0,0,0) + mul r4.yw, r4.yyyw, l(0.000000, 0.333333, 0.000000, 0.333333) + mov r15.x, r12.w + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r14.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + ushr r15.xyzw, r12.wxxx, l(30, 10, 20, 30) + utof r5.xy, r15.xwxx + mov r15.x, r12.x + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r12.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + mul r5.xy, r5.xyxx, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r13.w, r4.y + mov r11.w, r4.w + mov r14.w, r5.x + mov r12.w, r5.y + break + case l(4) + ishl r15.xyzw, r12.yzwx, l(16, 16, 16, 16) + mov r16.xz, r15.xxyx + mov r16.yw, r12.yyyz + ishr r16.xyzw, r16.xyzw, l(16, 16, 16, 16) + itof r16.xyzw, r16.xyzw + mul r16.xyzw, r16.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r13.xy, r16.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r11.xy, r16.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r12.yz, r15.zzwz + ishr r15.xyzw, r12.ywzx, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xy, r15.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r12.xy, r15.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r13.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r12.zw, l(0,0,0,0) + break + case l(6) + ushr r15.xyzw, r12.yzwx, l(16, 16, 16, 16) + f16tof32 r13.x, r12.y + f16tof32 r13.y, r15.x + f16tof32 r11.x, r12.z + f16tof32 r11.y, r15.y + f16tof32 r14.x, r12.w + f16tof32 r14.y, r15.z + f16tof32 r12.x, r12.x + f16tof32 r12.y, r15.w + mov r13.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r12.zw, l(0,0,0,0) + break + default + mov r13.x, r12.y + mov r13.yzw, l(0,0,0,0) + mov r11.x, r12.z + mov r11.yzw, l(0,0,0,0) + mov r14.x, r12.w + mov r14.yzw, l(0,0,0,0) + mov r12.yzw, l(0,0,0,0) + break + endswitch + endif + add r9.xyzw, r9.xyzw, r13.xyzw + add r7.xyzw, r7.xyzw, r11.xyzw + add r10.xyzw, r10.xyzw, r14.xyzw + add r8.xyzw, r8.xyzw, r12.xyzw + uge r4.y, r6.y, l(6) + if_nz r4.y + ishl r4.y, l(1), r5.w + mul r0.z, r0.z, l(0.250000) + iadd r0.y, r0.y, r4.y + if_nz r5.w + ieq r4.w, r2.z, l(2) + if_nz r4.w + ishl r4.w, r0.y, l(2) + ld_raw r11.xyzw, r4.w, T0[0].zwxy + iadd r4.w, r4.w, l(16) + ld_raw r12.xyzw, r4.w, T0[0].zwxy + mov r13.xy, r11.zwzz + mov r14.xy, r12.zwzz + else + ishl r4.w, r0.y, l(2) + ld_raw r13.xy, r4.w, T0[0].xyxx + iadd r4.w, r2.z, r0.y + ishl r4.w, r4.w, l(2) + ld_raw r11.xy, r4.w, T0[0].xyxx + ishl r5.xy, l(2, 3, 0, 0), r1.yyyy + iadd r5.xy, r0.yyyy, r5.xyxx + ishl r5.xy, r5.xyxx, l(2, 2, 0, 0) + ld_raw r14.xy, r5.x, T0[0].xyxx + ld_raw r12.xy, r5.y, T0[0].xyxx + endif + switch r5.z + case l(5) + ishl r13.zw, r13.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r13.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r13.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r11.zw, r11.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r11.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r11.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r14.zw, r14.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r14.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r12.zw, r12.xxxy, l(0, 0, 16, 16) + ishr r15.xyzw, r12.zxwy, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r12.xyzw, r15.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r5.xy, r13.xyxx, l(16, 16, 0, 0) + f16tof32 r13.xz, r13.xxyx + f16tof32 r13.yw, r5.xxxy + ushr r5.xy, r11.xyxx, l(16, 16, 0, 0) + f16tof32 r11.xz, r11.xxyx + f16tof32 r11.yw, r5.xxxy + ushr r5.xy, r14.xyxx, l(16, 16, 0, 0) + f16tof32 r14.xz, r14.xxyx + f16tof32 r14.yw, r5.xxxy + ushr r5.xy, r12.xyxx, l(16, 16, 0, 0) + f16tof32 r12.xz, r12.xxyx + f16tof32 r12.yw, r5.xxxy + break + default + mov r13.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r12.zw, l(0,0,0,0) + break + endswitch + else + ieq r4.w, r2.z, l(1) + if_nz r4.w + ishl r4.w, r0.y, l(2) + ld_raw r12.xyzw, r4.w, T0[0].wxyz + else + ishl r4.w, r0.y, l(2) + ld_raw r12.y, r4.w, T0[0].xxxx + iadd r4.w, r2.z, r0.y + ishl r4.w, r4.w, l(2) + ld_raw r12.z, r4.w, T0[0].xxxx + ishl r5.xy, l(2, 3, 0, 0), r1.yyyy + iadd r5.xy, r0.yyyy, r5.xyxx + ishl r5.xy, r5.xyxx, l(2, 2, 0, 0) + ld_raw r12.w, r5.x, T0[0].xxxx + ld_raw r12.x, r5.y, T0[0].xxxx + endif + switch r5.z + case l(0) + case l(1) + ushr r15.yzw, r12.yyyy, l(0, 8, 16, 24) + mov r15.x, r12.y + and r15.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r13.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r15.yzw, r12.zzzz, l(0, 8, 16, 24) + mov r15.x, r12.z + and r15.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r11.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r15.yzw, r12.wwww, l(0, 8, 16, 24) + mov r15.x, r12.w + and r15.xyzw, r15.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r14.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r12.yzw, r12.xxxx, l(0, 8, 16, 24) + and r15.xyzw, r12.xyzw, l(255, 255, 255, 255) + utof r15.xyzw, r15.xyzw + mul r12.xyzw, r15.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r15.yzw, r12.yyyy, l(0, 10, 20, 30) + mov r15.x, r12.y + and r15.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r13.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r15.yzw, r12.zzzz, l(0, 10, 20, 30) + mov r15.x, r12.z + and r15.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r11.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r15.yzw, r12.wwww, l(0, 10, 20, 30) + mov r15.x, r12.w + and r15.xyzw, r15.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r14.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r12.yzw, r12.xxxx, l(0, 10, 20, 30) + and r15.xyzw, r12.xyzw, l(1023, 1023, 1023, 3) + utof r15.xyzw, r15.xyzw + mul r12.xyzw, r15.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r15.xyzw, r12.yyyz, l(10, 20, 30, 30) + mov r16.x, r12.y + mov r16.yz, r15.xxyx + and r6.yzw, r16.xxyz, l(0, 1023, 1023, 1023) + and r17.xyz, r16.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r16.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r16.xyz, l(7, 7, 7, 0), r19.xyzx, r16.xyzx, l(0, 0, 0, 0) + and r16.xyz, r16.xyzx, l(127, 127, 127, 0) + movc r16.xyz, r18.xyzx, r17.xyzx, r16.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r16.xyz, r16.xyzx, l(16, 16, 16, 0) + iadd r16.xyz, r17.xyzx, r16.xyzx + movc r13.xyz, r6.yzwy, r16.xyzx, l(0,0,0,0) + utof r5.xy, r15.zwzz + ushr r15.xyzw, r12.zwwz, l(10, 10, 20, 20) + mov r16.x, r12.z + mov r16.yz, r15.xxwx + and r6.yzw, r16.xxyz, l(0, 1023, 1023, 1023) + and r17.xyz, r16.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r16.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r16.xyz, l(7, 7, 7, 0), r19.xyzx, r16.xyzx, l(0, 0, 0, 0) + and r16.xyz, r16.xyzx, l(127, 127, 127, 0) + movc r16.xyz, r18.xyzx, r17.xyzx, r16.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r16.xyz, r16.xyzx, l(16, 16, 16, 0) + iadd r16.xyz, r17.xyzx, r16.xyzx + movc r11.xyz, r6.yzwy, r16.xyzx, l(0,0,0,0) + mul r5.xy, r5.xyxx, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r15.x, r12.w + and r6.yzw, r15.xxyz, l(0, 1023, 1023, 1023) + and r16.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r17.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r18.xyz, r16.xyzx + iadd r18.xyz, r18.xyzx, l(-24, -24, -24, 0) + movc r18.xyz, r16.xyzx, r18.xyzx, l(8,8,8,0) + iadd r19.xyz, -r18.xyzx, l(1, 1, 1, 0) + movc r19.xyz, r17.xyzx, r17.xyzx, r19.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r18.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r17.xyzx, r16.xyzx, r15.xyzx + ishl r16.xyz, r19.xyzx, l(23, 23, 23, 0) + iadd r16.xyz, r16.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r16.xyzx, r15.xyzx + movc r14.xyz, r6.yzwy, r15.xyzx, l(0,0,0,0) + ushr r15.xyzw, r12.wxxx, l(30, 10, 20, 30) + utof r6.yz, r15.xxwx + mov r15.x, r12.x + and r16.xyz, r15.xyzx, l(1023, 1023, 1023, 0) + and r17.xyz, r15.xyzx, l(127, 127, 127, 0) + ubfe r18.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r15.xyzx + firstbit_hi r19.xyz, r17.xyzx + iadd r19.xyz, r19.xyzx, l(-24, -24, -24, 0) + movc r19.xyz, r17.xyzx, r19.xyzx, l(8,8,8,0) + iadd r20.xyz, -r19.xyzx, l(1, 1, 1, 0) + movc r20.xyz, r18.xyzx, r18.xyzx, r20.xyzx + bfi r15.xyz, l(7, 7, 7, 0), r19.xyzx, r15.xyzx, l(0, 0, 0, 0) + and r15.xyz, r15.xyzx, l(127, 127, 127, 0) + movc r15.xyz, r18.xyzx, r17.xyzx, r15.xyzx + ishl r17.xyz, r20.xyzx, l(23, 23, 23, 0) + iadd r17.xyz, r17.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r15.xyz, r15.xyzx, l(16, 16, 16, 0) + iadd r15.xyz, r17.xyzx, r15.xyzx + movc r12.xyz, r16.xyzx, r15.xyzx, l(0,0,0,0) + mul r6.yz, r6.yyzy, l(0.000000, 0.333333, 0.333333, 0.000000) + mov r13.w, r5.x + mov r11.w, r5.y + mov r14.w, r6.y + mov r12.w, r6.z + break + case l(4) + ishl r15.xyzw, r12.yzwx, l(16, 16, 16, 16) + mov r16.xz, r15.xxyx + mov r16.yw, r12.yyyz + ishr r16.xyzw, r16.xyzw, l(16, 16, 16, 16) + itof r16.xyzw, r16.xyzw + mul r16.xyzw, r16.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r13.xy, r16.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r11.xy, r16.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r12.yz, r15.zzwz + ishr r15.xyzw, r12.ywzx, l(16, 16, 16, 16) + itof r15.xyzw, r15.xyzw + mul r15.xyzw, r15.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r14.xy, r15.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r12.xy, r15.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r13.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r12.zw, l(0,0,0,0) + break + case l(6) + ushr r15.xyzw, r12.yzwx, l(16, 16, 16, 16) + f16tof32 r13.x, r12.y + f16tof32 r13.y, r15.x + f16tof32 r11.x, r12.z + f16tof32 r11.y, r15.y + f16tof32 r14.x, r12.w + f16tof32 r14.y, r15.z + f16tof32 r12.x, r12.x + f16tof32 r12.y, r15.w + mov r13.zw, l(0,0,0,0) + mov r11.zw, l(0,0,0,0) + mov r14.zw, l(0,0,0,0) + mov r12.zw, l(0,0,0,0) + break + default + mov r13.x, r12.y + mov r13.yzw, l(0,0,0,0) + mov r11.x, r12.z + mov r11.yzw, l(0,0,0,0) + mov r14.x, r12.w + mov r14.yzw, l(0,0,0,0) + mov r12.yzw, l(0,0,0,0) + break + endswitch + endif + add r13.xyzw, r9.xyzw, r13.xyzw + add r11.xyzw, r7.xyzw, r11.xyzw + add r14.xyzw, r10.xyzw, r14.xyzw + add r12.xyzw, r8.xyzw, r12.xyzw + iadd r0.y, r3.w, r4.y + if_nz r5.w + ieq r3.w, r2.z, l(2) + if_nz r3.w + ishl r3.w, r0.y, l(2) + ld_raw r15.xyzw, r3.w, T0[0].zwxy + iadd r3.w, r3.w, l(16) + ld_raw r16.xyzw, r3.w, T0[0].zwxy + mov r17.xy, r15.zwzz + mov r18.xy, r16.zwzz + else + ishl r3.w, r0.y, l(2) + ld_raw r17.xy, r3.w, T0[0].xyxx + iadd r3.w, r2.z, r0.y + ishl r3.w, r3.w, l(2) + ld_raw r15.xy, r3.w, T0[0].xyxx + ishl r4.yw, l(0, 2, 0, 3), r1.yyyy + iadd r4.yw, r0.yyyy, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r18.xy, r4.y, T0[0].xyxx + ld_raw r16.xy, r4.w, T0[0].xyxx + endif + switch r5.z + case l(5) + ishl r17.zw, r17.xxxy, l(0, 0, 16, 16) + ishr r19.xyzw, r17.zxwy, l(16, 16, 16, 16) + itof r19.xyzw, r19.xyzw + mul r19.xyzw, r19.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r17.xyzw, r19.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r15.zw, r15.xxxy, l(0, 0, 16, 16) + ishr r19.xyzw, r15.zxwy, l(16, 16, 16, 16) + itof r19.xyzw, r19.xyzw + mul r19.xyzw, r19.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r15.xyzw, r19.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r18.zw, r18.xxxy, l(0, 0, 16, 16) + ishr r19.xyzw, r18.zxwy, l(16, 16, 16, 16) + itof r19.xyzw, r19.xyzw + mul r19.xyzw, r19.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r18.xyzw, r19.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ishl r16.zw, r16.xxxy, l(0, 0, 16, 16) + ishr r19.xyzw, r16.zxwy, l(16, 16, 16, 16) + itof r19.xyzw, r19.xyzw + mul r19.xyzw, r19.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r16.xyzw, r19.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + ushr r4.yw, r17.xxxy, l(0, 16, 0, 16) + f16tof32 r17.xz, r17.xxyx + f16tof32 r17.yw, r4.yyyw + ushr r4.yw, r15.xxxy, l(0, 16, 0, 16) + f16tof32 r15.xz, r15.xxyx + f16tof32 r15.yw, r4.yyyw + ushr r4.yw, r18.xxxy, l(0, 16, 0, 16) + f16tof32 r18.xz, r18.xxyx + f16tof32 r18.yw, r4.yyyw + ushr r4.yw, r16.xxxy, l(0, 16, 0, 16) + f16tof32 r16.xz, r16.xxyx + f16tof32 r16.yw, r4.yyyw + break + default + mov r17.zw, l(0,0,0,0) + mov r15.zw, l(0,0,0,0) + mov r18.zw, l(0,0,0,0) + mov r16.zw, l(0,0,0,0) + break + endswitch + else + ieq r3.w, r2.z, l(1) + if_nz r3.w + ishl r3.w, r0.y, l(2) + ld_raw r16.xyzw, r3.w, T0[0].wxyz + else + ishl r3.w, r0.y, l(2) + ld_raw r16.y, r3.w, T0[0].xxxx + iadd r2.z, r2.z, r0.y + ishl r2.z, r2.z, l(2) + ld_raw r16.z, r2.z, T0[0].xxxx + ishl r4.yw, l(0, 2, 0, 3), r1.yyyy + iadd r4.yw, r0.yyyy, r4.yyyw + ishl r4.yw, r4.yyyw, l(0, 2, 0, 2) + ld_raw r16.w, r4.y, T0[0].xxxx + ld_raw r16.x, r4.w, T0[0].xxxx + endif + switch r5.z + case l(0) + case l(1) + ushr r5.yzw, r16.yyyy, l(0, 8, 16, 24) + mov r5.x, r16.y + and r5.xyzw, r5.xyzw, l(255, 255, 255, 255) + utof r5.xyzw, r5.xyzw + mul r17.xyzw, r5.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r5.yzw, r16.zzzz, l(0, 8, 16, 24) + mov r5.x, r16.z + and r5.xyzw, r5.xyzw, l(255, 255, 255, 255) + utof r5.xyzw, r5.xyzw + mul r15.xyzw, r5.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r5.yzw, r16.wwww, l(0, 8, 16, 24) + mov r5.x, r16.w + and r5.xyzw, r5.xyzw, l(255, 255, 255, 255) + utof r5.xyzw, r5.xyzw + mul r18.xyzw, r5.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r16.yzw, r16.xxxx, l(0, 8, 16, 24) + and r5.xyzw, r16.xyzw, l(255, 255, 255, 255) + utof r5.xyzw, r5.xyzw + mul r16.xyzw, r5.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + ushr r5.yzw, r16.yyyy, l(0, 10, 20, 30) + mov r5.x, r16.y + and r5.xyzw, r5.xyzw, l(1023, 1023, 1023, 3) + utof r5.xyzw, r5.xyzw + mul r17.xyzw, r5.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r5.yzw, r16.zzzz, l(0, 10, 20, 30) + mov r5.x, r16.z + and r5.xyzw, r5.xyzw, l(1023, 1023, 1023, 3) + utof r5.xyzw, r5.xyzw + mul r15.xyzw, r5.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r5.yzw, r16.wwww, l(0, 10, 20, 30) + mov r5.x, r16.w + and r5.xyzw, r5.xyzw, l(1023, 1023, 1023, 3) + utof r5.xyzw, r5.xyzw + mul r18.xyzw, r5.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + ushr r16.yzw, r16.xxxx, l(0, 10, 20, 30) + and r5.xyzw, r16.xyzw, l(1023, 1023, 1023, 3) + utof r5.xyzw, r5.xyzw + mul r16.xyzw, r5.xyzw, l(0.000978, 0.000978, 0.000978, 0.333333) + break + case l(3) + case l(12) + ushr r5.xyzw, r16.yyyz, l(10, 20, 30, 30) + mov r19.x, r16.y + mov r19.yz, r5.xxyx + and r6.yzw, r19.xxyz, l(0, 1023, 1023, 1023) + and r20.xyz, r19.xyzx, l(127, 127, 127, 0) + ubfe r21.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r19.xyzx + firstbit_hi r22.xyz, r20.xyzx + iadd r22.xyz, r22.xyzx, l(-24, -24, -24, 0) + movc r22.xyz, r20.xyzx, r22.xyzx, l(8,8,8,0) + iadd r23.xyz, -r22.xyzx, l(1, 1, 1, 0) + movc r23.xyz, r21.xyzx, r21.xyzx, r23.xyzx + bfi r19.xyz, l(7, 7, 7, 0), r22.xyzx, r19.xyzx, l(0, 0, 0, 0) + and r19.xyz, r19.xyzx, l(127, 127, 127, 0) + movc r19.xyz, r21.xyzx, r20.xyzx, r19.xyzx + ishl r20.xyz, r23.xyzx, l(23, 23, 23, 0) + iadd r20.xyz, r20.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r19.xyz, r19.xyzx, l(16, 16, 16, 0) + iadd r19.xyz, r20.xyzx, r19.xyzx + movc r17.xyz, r6.yzwy, r19.xyzx, l(0,0,0,0) + utof r4.yw, r5.zzzw + ushr r5.xyzw, r16.zwwz, l(10, 10, 20, 20) + mov r19.x, r16.z + mov r19.yz, r5.xxwx + and r6.yzw, r19.xxyz, l(0, 1023, 1023, 1023) + and r20.xyz, r19.xyzx, l(127, 127, 127, 0) + ubfe r21.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r19.xyzx + firstbit_hi r22.xyz, r20.xyzx + iadd r22.xyz, r22.xyzx, l(-24, -24, -24, 0) + movc r22.xyz, r20.xyzx, r22.xyzx, l(8,8,8,0) + iadd r23.xyz, -r22.xyzx, l(1, 1, 1, 0) + movc r23.xyz, r21.xyzx, r21.xyzx, r23.xyzx + bfi r19.xyz, l(7, 7, 7, 0), r22.xyzx, r19.xyzx, l(0, 0, 0, 0) + and r19.xyz, r19.xyzx, l(127, 127, 127, 0) + movc r19.xyz, r21.xyzx, r20.xyzx, r19.xyzx + ishl r20.xyz, r23.xyzx, l(23, 23, 23, 0) + iadd r20.xyz, r20.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r19.xyz, r19.xyzx, l(16, 16, 16, 0) + iadd r19.xyz, r20.xyzx, r19.xyzx + movc r15.xyz, r6.yzwy, r19.xyzx, l(0,0,0,0) + mul r4.yw, r4.yyyw, l(0.000000, 0.333333, 0.000000, 0.333333) + mov r5.x, r16.w + and r6.yzw, r5.xxyz, l(0, 1023, 1023, 1023) + and r19.xyz, r5.xyzx, l(127, 127, 127, 0) + ubfe r20.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r5.xyzx + firstbit_hi r21.xyz, r19.xyzx + iadd r21.xyz, r21.xyzx, l(-24, -24, -24, 0) + movc r21.xyz, r19.xyzx, r21.xyzx, l(8,8,8,0) + iadd r22.xyz, -r21.xyzx, l(1, 1, 1, 0) + movc r22.xyz, r20.xyzx, r20.xyzx, r22.xyzx + bfi r5.xyz, l(7, 7, 7, 0), r21.xyzx, r5.xyzx, l(0, 0, 0, 0) + and r5.xyz, r5.xyzx, l(127, 127, 127, 0) + movc r5.xyz, r20.xyzx, r19.xyzx, r5.xyzx + ishl r19.xyz, r22.xyzx, l(23, 23, 23, 0) + iadd r19.xyz, r19.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r5.xyz, r5.xyzx, l(16, 16, 16, 0) + iadd r5.xyz, r19.xyzx, r5.xyzx + movc r18.xyz, r6.yzwy, r5.xyzx, l(0,0,0,0) + ushr r5.xyzw, r16.wxxx, l(30, 10, 20, 30) + utof r6.yz, r5.xxwx + mov r5.x, r16.x + and r19.xyz, r5.xyzx, l(1023, 1023, 1023, 0) + and r20.xyz, r5.xyzx, l(127, 127, 127, 0) + ubfe r21.xyz, l(3, 3, 3, 0), l(7, 7, 7, 0), r5.xyzx + firstbit_hi r22.xyz, r20.xyzx + iadd r22.xyz, r22.xyzx, l(-24, -24, -24, 0) + movc r22.xyz, r20.xyzx, r22.xyzx, l(8,8,8,0) + iadd r23.xyz, -r22.xyzx, l(1, 1, 1, 0) + movc r23.xyz, r21.xyzx, r21.xyzx, r23.xyzx + bfi r5.xyz, l(7, 7, 7, 0), r22.xyzx, r5.xyzx, l(0, 0, 0, 0) + and r5.xyz, r5.xyzx, l(127, 127, 127, 0) + movc r5.xyz, r21.xyzx, r20.xyzx, r5.xyzx + ishl r20.xyz, r23.xyzx, l(23, 23, 23, 0) + iadd r20.xyz, r20.xyzx, l(0x3e000000, 0x3e000000, 0x3e000000, 0) + ishl r5.xyz, r5.xyzx, l(16, 16, 16, 0) + iadd r5.xyz, r20.xyzx, r5.xyzx + movc r16.xyz, r19.xyzx, r5.xyzx, l(0,0,0,0) + mul r5.xy, r6.yzyy, l(0.333333, 0.333333, 0.000000, 0.000000) + mov r17.w, r4.y + mov r15.w, r4.w + mov r18.w, r5.x + mov r16.w, r5.y + break + case l(4) + ishl r5.xyzw, r16.yzwx, l(16, 16, 16, 16) + mov r19.xz, r5.xxyx + mov r19.yw, r16.yyyz + ishr r19.xyzw, r19.xyzw, l(16, 16, 16, 16) + itof r19.xyzw, r19.xyzw + mul r19.xyzw, r19.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r17.xy, r19.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r15.xy, r19.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r16.yz, r5.zzwz + ishr r5.xyzw, r16.ywzx, l(16, 16, 16, 16) + itof r5.xyzw, r5.xyzw + mul r5.xyzw, r5.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r18.xy, r5.xyxx, l(-1.000000, -1.000000, 0.000000, 0.000000) + max r16.xy, r5.zwzz, l(-1.000000, -1.000000, 0.000000, 0.000000) + mov r17.zw, l(0,0,0,0) + mov r15.zw, l(0,0,0,0) + mov r18.zw, l(0,0,0,0) + mov r16.zw, l(0,0,0,0) + break + case l(6) + ushr r5.xyzw, r16.yzwx, l(16, 16, 16, 16) + f16tof32 r17.x, r16.y + f16tof32 r17.y, r5.x + f16tof32 r15.x, r16.z + f16tof32 r15.y, r5.y + f16tof32 r18.x, r16.w + f16tof32 r18.y, r5.z + f16tof32 r16.x, r16.x + f16tof32 r16.y, r5.w + mov r17.zw, l(0,0,0,0) + mov r15.zw, l(0,0,0,0) + mov r18.zw, l(0,0,0,0) + mov r16.zw, l(0,0,0,0) + break + default + mov r17.x, r16.y + mov r17.yzw, l(0,0,0,0) + mov r15.x, r16.z + mov r15.yzw, l(0,0,0,0) + mov r18.x, r16.w + mov r18.yzw, l(0,0,0,0) + mov r16.yzw, l(0,0,0,0) + break + endswitch + endif + add r9.xyzw, r13.xyzw, r17.xyzw + add r7.xyzw, r11.xyzw, r15.xyzw + add r10.xyzw, r14.xyzw, r18.xyzw + add r8.xyzw, r12.xyzw, r16.xyzw + else + mov r0.z, r2.w + endif +endif +mul r5.xyzw, r0.zzzz, r9.xyzw +mul r7.xyzw, r0.zzzz, r7.wyxz +mul r9.xyzw, r0.zzzz, r10.xyzw +mul r8.xyzw, r0.zzzz, r8.xzwy +if_nz r1.z + mov r5.xz, r5.zzxz + mov r10.xz, r7.wwzw + mov r9.xz, r9.zzxz + mov r11.xz, r8.yyxy +else + mov r10.xz, r7.zzwz + mov r11.xz, r8.xxyx +endif +switch r6.x + case l(26) + mov_sat r5.xyzw, r5.xyzw + mad r6.xyzw, r5.xyzw, l(65535.000000, 65535.000000, 65535.000000, 65535.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r6.xyzw, r6.xyzw + imad r7.zw, r6.yyyw, l(0, 0, 0x00010000, 0x00010000), r6.xxxz + mov r10.yw, r7.yyyx + mov_sat r10.xyzw, r10.xyzw + mad r6.xyzw, r10.xyzw, l(65535.000000, 65535.000000, 65535.000000, 65535.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r6.xyzw, r6.xyzw + imad r7.xy, r6.ywyy, l(0x00010000, 0x00010000, 0, 0), r6.xzxx + mov_sat r9.xyzw, r9.xyzw + mad r6.xyzw, r9.xyzw, l(65535.000000, 65535.000000, 65535.000000, 65535.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r6.xyzw, r6.xyzw + imad r8.xy, r6.ywyy, l(0x00010000, 0x00010000, 0, 0), r6.xzxx + mov r11.yw, r8.wwwz + mov_sat r11.xyzw, r11.xyzw + mad r6.xyzw, r11.xyzw, l(65535.000000, 65535.000000, 65535.000000, 65535.000000), l(0.500000, 0.500000, 0.500000, 0.500000) + ftou r6.xyzw, r6.xyzw + imad r8.zw, r6.yyyw, l(0, 0, 0x00010000, 0x00010000), r6.xxxz + break + case l(32) + f32tof16 r0.yz, r5.xxzx + f32tof16 r1.yz, r5.yywy + imad r7.zw, r1.yyyz, l(0, 0, 0x00010000, 0x00010000), r0.yyyz + f32tof16 r0.yz, r10.xxzx + f32tof16 r1.yz, r7.yyxy + imad r7.xy, r1.yzyy, l(0x00010000, 0x00010000, 0, 0), r0.yzyy + f32tof16 r0.yz, r9.xxzx + f32tof16 r1.yz, r9.yywy + imad r8.xy, r1.yzyy, l(0x00010000, 0x00010000, 0, 0), r0.yzyy + f32tof16 r0.yz, r11.xxzx + f32tof16 r1.yz, r8.wwzw + imad r8.zw, r1.yyyz, l(0, 0, 0x00010000, 0x00010000), r0.yyyz + break + default + mov r7.zw, r5.xxxy + mov r7.x, r10.x + mov r8.xy, r9.xyxx + mov r8.z, r11.x + break +endswitch +ieq r0.y, r4.x, l(0) +ine r0.z, r1.x, l(0) +and r0.y, r0.z, r0.y +if_nz r0.y + uge r0.y, r1.x, l(2) + if_nz r0.y + uge r0.y, r1.x, l(3) + if_nz r0.y + mov r8.xy, r8.zwzz + endif + mov r7.xy, r8.xyxx + endif + mov r7.xyzw, r7.xyxy +endif +mov r4.z, vThreadID.y +imad r1.yz, r3.xxzx, r2.xxyx, r4.xxzx +ushr r1.x, r1.y, l(1) +udiv r0.yz, null, r1.xxzx, r2.xxyx +ishl r1.y, r0.y, l(1) +if_nz r0.w + ubfe r0.w, l(3), l(4), CB0[0][0].z + ishl r2.z, r3.y, l(5) + ishr r3.xy, r0.zzzz, l(4, 3, 0, 0) + ishr r2.w, r0.w, l(2) + ushr r2.z, r2.z, l(4) + and r2.z, r2.z, l(2046) + imad r2.z, r2.w, r2.z, r3.x + ushr r3.x, r1.w, l(5) + ibfe r3.zw, l(0, 0, 27, 29), l(0, 0, 4, 2), r0.yyyy + imad r2.z, r2.z, r3.x, r3.z + ishl r3.x, r0.z, l(11) + and r3.x, r3.x, l(0x00003000) + bfi r3.x, l(3), l(9), r1.y, r3.x + ishr r3.x, r3.x, l(6) + iadd r2.w, r2.w, r3.y + bfi r3.y, l(1), l(1), r2.w, l(0) + iadd r3.y, r3.y, r3.w + bfi r3.y, l(2), l(1), r3.y, l(0) + bfi r2.w, l(1), l(0), r2.w, r3.y + bfi r3.yz, l(0, 19, 19, 0), l(0, 11, 14, 0), r2.zzzz, l(0, 0, 0, 0) + imad r3.xy, r3.xxxx, l(2, 16, 0, 0), r3.yzyy + bfi r3.xy, l(2, 2, 0, 0), l(9, 12, 0, 0), r0.wwww, r3.xyxx + bfi r0.w, l(1), l(4), r0.z, l(0) + ubfe r2.z, l(3), l(6), r3.x + and r3.z, r2.w, l(6) + bfi r2.w, l(1), l(8), r2.w, l(0) + imad r2.z, r2.z, l(32), r2.w + imad r2.z, r3.z, l(4), r2.z + bfi r3.xy, l(5, 5, 0, 0), l(0, 3, 0, 0), r0.wwww, r3.xyxx + bfi r0.w, l(9), l(3), r2.z, r3.y + bfi r0.w, l(6), l(0), r3.x, r0.w +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 4, 2), r0.yyyy + ishr r3.xy, r0.zzzz, l(5, 2, 0, 0) + ushr r1.w, r1.w, l(5) + imad r1.w, r3.x, r1.w, r2.z + ishl r3.xz, r0.zzzz, l(6, 0, 7, 0) + and r3.xz, r3.xxzx, l(896, 0, 2048, 0) + bfi r2.z, l(3), l(4), r1.y, r3.x + bfi r2.z, l(22), l(10), r1.w, r2.z + bfi r3.w, l(1), l(4), r0.z, l(0) + iadd r2.z, r2.z, r3.w + ishl r4.yz, r3.xxxx, l(0, 3, 2, 0) + bfi r4.yz, l(0, 3, 3, 0), l(0, 7, 6, 0), r1.yyyy, r4.yyzy + bfi r1.yw, l(0, 22, 0, 22), l(0, 13, 0, 12), r1.wwww, r4.yyyz + imad r1.yw, r3.wwww, l(0, 8, 0, 4), r1.yyyw + bfi r1.y, l(12), l(0), r3.z, r1.y + and r1.w, r1.w, l(1792) + iadd r1.y, r1.y, r1.w + and r1.w, r3.y, l(2) + iadd r1.w, r2.w, r1.w + bfi r1.w, l(2), l(6), r1.w, l(0) + iadd r1.y, r1.y, r1.w + bfi r0.w, l(6), l(0), r2.z, r1.y +endif +imad r0.yz, -r0.yyzy, r2.xxyx, r1.xxzx +imul null, r1.x, r2.y, r2.x +imad r0.y, r0.y, r2.y, r0.z +ishl r0.y, r0.y, l(4) +imad r0.y, r0.w, r1.x, r0.y +ushr r0.y, r0.y, l(4) +ieq r0.z, r0.x, l(4) +if_nz r0.z + mov r7.xyzw, r7.yxwz + mov r0.w, l(2) +else + mov r0.w, r0.x +endif +ieq r1.xyz, r0.wwww, l(1, 2, 3, 0) +or r1.xy, r1.yzyy, r1.xyxx +if_nz r1.x + ishl r3.xyzw, r7.zwxy, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r7.zwxy, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r7.xyzw, r3.zwxy, r5.zwxy +endif +if_nz r1.y + ushr r1.xyzw, r7.zwxy, l(16, 16, 16, 16) + bfi r7.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r7.xyzw, r1.zwxy +endif +store_uav_typed U0[0].xyzw, r0.yyyy, r7.zwxy +ult r0.w, l(1), r2.x +if_nz r0.w + ushr r0.w, r4.x, l(1) + udiv r1.x, null, r0.w, r2.x + imad r0.w, -r1.x, r2.x, r0.w + iadd r1.x, r0.w, l(1) + ieq r1.x, r2.x, r1.x + if_nz r1.x + ishl r1.x, r2.x, l(5) + ishl r0.w, r0.w, l(4) + iadd r0.w, -r0.w, r1.x + else + mov r0.w, l(16) + endif +else + mov r0.w, l(32) +endif +imul null, r0.w, r2.y, r0.w +ushr r0.w, r0.w, l(4) +iadd r0.y, r0.w, r0.y +if_nz r0.z + mov r8.zw, r8.wwwz + mov r8.xyzw, r8.yxzw + mov r0.x, l(2) +endif +ieq r0.xzw, r0.xxxx, l(1, 0, 2, 3) +or r0.xz, r0.zzwz, r0.xxzx +if_nz r0.x + ishl r1.xyzw, r8.xyzw, l(8, 8, 8, 8) + and r1.xyzw, r1.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r2.xyzw, r8.xyzw, l(8, 8, 8, 8) + and r2.xyzw, r2.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r8.xyzw, r1.xyzw, r2.xyzw +endif +if_nz r0.z + ushr r1.xyzw, r8.xyzw, l(16, 16, 16, 16) + bfi r8.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r8.xyzw, r1.xyzw +endif +store_uav_typed U0[0].xyzw, r0.yyyy, r8.xyzw +ret +// Approximately 1310 instruction slots used +#endif + +const BYTE resolve_full_64bpp_scaled_cs[] = { + 68, 88, 66, 67, 122, 14, 52, 240, 164, 51, 71, 124, 149, 25, 146, 49, 217, 112, 217, + 13, 1, 0, 0, 0, 28, 157, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 144, 2, + 0, 0, 160, 2, 0, 0, 176, 2, 0, 0, 128, 156, 0, 0, 82, 68, 69, 70, 84, + 2, 0, 0, 1, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 44, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 101, 100, 114, 97, 109, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 213, 0, 0, 0, 4, 0, 0, 0, 252, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 156, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 220, 1, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 247, 1, 0, 0, 8, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 12, 2, 0, 0, 12, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, + 114, 101, 115, 111, 108, 118, 101, 95, 101, 100, 114, 97, 109, 95, 105, 110, 102, 111, 0, + 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 178, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 99, 111, 111, 114, + 100, 105, 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 100, 101, 115, 116, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 99, 111, 111, 114, 100, 105, 110, 97, + 116, 101, 95, 105, 110, 102, 111, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 83, 72, 69, 88, 200, 153, 0, 0, 81, 0, 5, 0, 114, 38, 0, + 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 161, 0, 0, 6, 70, + 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 156, 8, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 68, 68, 0, 0, 0, 0, 0, 0, 95, 0, 0, 2, 50, 0, 2, 0, 104, 0, + 0, 2, 24, 0, 0, 0, 155, 0, 0, 4, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, 0, 38, 136, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, + 0, 255, 3, 0, 0, 0, 0, 0, 32, 8, 0, 0, 0, 31, 0, 4, 3, 42, 0, + 16, 0, 0, 0, 0, 0, 138, 0, 0, 17, 50, 0, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 17, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 133, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, + 0, 1, 54, 0, 0, 8, 50, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 138, 0, 0, 17, 114, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 86, 133, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 1, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 1, 85, 0, 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, 214, 143, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, + 0, 10, 0, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 4, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, + 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 3, 0, 0, 0, 80, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, + 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, + 0, 0, 17, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, + 11, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, + 0, 13, 0, 0, 0, 24, 0, 0, 0, 28, 0, 0, 0, 6, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 0, 16, 0, 6, + 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 140, 0, 0, 20, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 6, 4, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 139, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, + 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 140, 0, 0, 13, 130, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, + 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 140, 0, 0, 20, 82, 0, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 166, 11, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 17, 50, 0, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 230, 138, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 83, 0, 0, 6, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 2, 0, 35, 0, 0, 9, 194, 0, 16, 0, 2, 0, 0, 0, 166, + 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, + 4, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 31, 0, 4, 3, 26, 0, + 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 7, 0, 0, 0, 26, + 0, 16, 0, 6, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, + 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, + 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 18, 0, 0, 1, 54, + 0, 0, 5, 34, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 1, 21, 0, 0, 1, 80, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 162, 0, 16, 0, 4, + 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 194, 0, 16, + 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 86, 13, 16, 0, 4, 0, + 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 7, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, + 6, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 194, 0, + 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 6, + 0, 0, 0, 38, 0, 0, 11, 0, 208, 0, 0, 98, 0, 16, 0, 7, 0, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 80, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 7, 0, + 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 78, + 0, 0, 8, 194, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, 166, 14, 16, 0, + 2, 0, 0, 0, 6, 8, 16, 0, 7, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, + 35, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 128, 65, 0, 0, + 0, 6, 0, 0, 0, 6, 8, 16, 0, 7, 0, 0, 0, 166, 14, 16, 0, 2, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 35, 0, 0, 9, + 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, + 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, + 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, + 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 78, 0, 0, 8, 0, 208, 0, 0, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 4, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 7, 66, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, 32, 0, 0, 7, + 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 2, 0, 0, 0, 41, 0, + 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 7, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 8, + 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 9, 0, 0, 0, 230, 10, 16, + 0, 7, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 10, 0, 0, 0, 230, 10, + 16, 0, 8, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 165, 0, 0, 8, 50, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, + 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, + 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, + 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 70, 112, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 86, 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 162, 0, 16, 0, 4, 0, 0, + 0, 86, 5, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 41, 0, + 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 165, 0, 0, 8, 50, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, + 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, + 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, + 5, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, + 10, 194, 0, 16, 0, 9, 0, 0, 0, 6, 4, 16, 0, 9, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, + 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 38, 7, 16, 0, 9, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 43, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 7, 0, 0, 0, 6, + 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, + 0, 38, 7, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 11, + 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, + 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, + 194, 0, 16, 0, 10, 0, 0, 0, 6, 4, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, + 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 38, 7, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 43, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 8, 0, 0, 0, 6, 4, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, + 38, 7, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, + 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, + 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, + 4, 0, 0, 0, 6, 4, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, + 16, 0, 9, 0, 0, 0, 6, 1, 16, 0, 9, 0, 0, 0, 131, 0, 0, 5, 162, + 0, 16, 0, 9, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, + 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, + 0, 5, 82, 0, 16, 0, 7, 0, 0, 0, 6, 1, 16, 0, 7, 0, 0, 0, 131, + 0, 0, 5, 162, 0, 16, 0, 7, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, + 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 10, 0, 0, 0, 6, 1, 16, 0, 10, + 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 10, 0, 0, 0, 86, 13, 16, 0, + 4, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 8, 0, 0, 0, 6, + 1, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 8, 0, 0, 0, + 86, 13, 16, 0, 4, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, + 8, 194, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, + 18, 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, + 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, + 242, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 54, 121, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, + 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, + 66, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 6, 112, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 162, 0, 16, 0, + 4, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, + 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, + 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, + 8, 18, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 6, 112, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, + 0, 16, 0, 5, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, + 0, 11, 0, 0, 0, 86, 5, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, + 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 85, 0, 0, 10, 226, 0, 16, 0, 11, 0, 0, 0, 166, 10, 16, 0, 8, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, + 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, + 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 11, 0, + 0, 0, 246, 15, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, + 11, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, + 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, + 0, 10, 226, 0, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, + 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, + 0, 16, 0, 11, 0, 0, 0, 86, 5, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, + 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 11, 0, 0, 0, 166, 10, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, + 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, + 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, + 0, 70, 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, + 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, + 11, 0, 0, 0, 246, 15, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, + 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, + 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, + 85, 0, 0, 10, 226, 0, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, + 32, 128, 58, 171, 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, + 3, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 11, 0, 0, 0, 86, 9, 16, 0, 8, 0, 0, 0, 2, 64, + 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, + 54, 0, 0, 5, 98, 0, 16, 0, 12, 0, 0, 0, 6, 1, 16, 0, 11, 0, 0, + 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 12, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 16, 0, 0, + 0, 70, 2, 16, 0, 14, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 16, 0, + 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, + 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, + 16, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 128, 65, + 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, + 16, 0, 17, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 41, 0, + 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, + 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, + 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 55, 0, 0, 12, 114, 0, + 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 0, 0, 5, 162, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, + 0, 11, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 230, 11, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 20, + 0, 0, 0, 20, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, 0, + 42, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 12, 0, 0, + 0, 6, 3, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, 0, + 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, + 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 135, 0, 0, + 5, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 30, 0, + 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, + 55, 0, 0, 12, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, + 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, + 9, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, + 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 140, 0, 0, 17, 114, + 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, + 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, + 16, 0, 12, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, + 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, + 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, + 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, + 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 12, + 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, + 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, + 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 13, + 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, 162, 0, 16, + 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 171, 170, 170, 62, 0, 0, 0, 0, 171, 170, 170, 62, 54, 0, 0, 5, 18, + 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, + 138, 0, 0, 15, 114, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 11, + 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, + 13, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, + 0, 15, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, + 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 15, 0, 0, 0, 70, + 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 11, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, + 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, + 0, 140, 0, 0, 17, 114, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, + 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, + 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, + 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, + 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, + 0, 13, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 23, 0, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, + 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, + 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, + 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 10, 0, 0, + 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 54, 0, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 30, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, + 0, 86, 0, 0, 5, 50, 0, 16, 0, 5, 0, 0, 0, 198, 0, 16, 0, 11, 0, + 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, + 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 14, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 15, + 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, + 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, + 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, + 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, + 128, 65, 0, 0, 0, 15, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, + 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, + 70, 2, 16, 0, 16, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 14, + 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, + 41, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, + 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, + 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 12, + 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 70, + 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 9, 0, 0, + 0, 26, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 7, 0, + 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 10, + 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, + 8, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, + 3, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 11, 0, + 0, 0, 150, 3, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, + 12, 0, 0, 0, 6, 1, 16, 0, 11, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, + 0, 12, 0, 0, 0, 86, 9, 16, 0, 8, 0, 0, 0, 42, 0, 0, 10, 242, 0, + 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, + 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, + 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, + 0, 0, 10, 50, 0, 16, 0, 9, 0, 0, 0, 70, 0, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 0, 0, 10, 50, 0, 16, 0, 7, 0, 0, 0, 230, 10, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 8, 0, 0, 0, 166, 11, 16, 0, + 11, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 214, 2, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, + 14, 16, 0, 11, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 10, 0, + 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, + 8, 0, 0, 0, 230, 10, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, + 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, + 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 150, 3, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, + 26, 0, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 9, 0, 0, + 0, 10, 0, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 7, 0, + 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 7, + 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, + 10, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, + 0, 10, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 18, 0, + 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 34, + 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, 8, + 194, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, + 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, + 54, 0, 0, 8, 226, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, + 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 8, 226, + 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, + 0, 58, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 1, 23, 0, 0, 1, 21, 0, 0, 1, 80, 0, 0, 7, 130, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, + 0, 4, 3, 58, 0, 16, 0, 2, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, + 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 63, 35, 0, 0, 9, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 80, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 31, + 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, 32, 0, 0, 7, 34, 0, 16, 0, + 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 31, 0, 4, 3, 26, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, + 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, + 4, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 16, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 12, 0, 0, 0, 26, + 0, 16, 0, 4, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 50, 0, 16, 0, 13, 0, 0, 0, 230, 10, 16, 0, 11, 0, 0, + 0, 54, 0, 0, 5, 50, 0, 16, 0, 14, 0, 0, 0, 230, 10, 16, 0, 12, 0, + 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 58, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, + 50, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 41, + 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, + 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 11, 0, 0, + 0, 26, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 86, 5, 16, 0, + 1, 0, 0, 0, 30, 0, 0, 7, 162, 0, 16, 0, 4, 0, 0, 0, 246, 15, 16, + 0, 3, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 162, 0, + 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, + 50, 0, 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 12, 0, + 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 5, 0, 0, 0, + 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, + 0, 13, 0, 0, 0, 6, 4, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, + 0, 16, 0, 15, 0, 0, 0, 38, 7, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, + 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 52, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 11, 0, 0, 0, 6, 4, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 38, 7, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, + 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, + 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, + 14, 0, 0, 0, 6, 4, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, + 16, 0, 15, 0, 0, 0, 38, 7, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, + 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, + 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 41, 0, 0, 10, 194, 0, 16, 0, 12, 0, 0, 0, 6, 4, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 38, 7, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, + 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, + 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, + 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, + 6, 4, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 13, 0, + 0, 0, 6, 1, 16, 0, 13, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 13, + 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, + 4, 0, 0, 0, 6, 4, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, + 16, 0, 11, 0, 0, 0, 6, 1, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 162, + 0, 16, 0, 11, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, + 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 14, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, + 0, 5, 82, 0, 16, 0, 14, 0, 0, 0, 6, 1, 16, 0, 14, 0, 0, 0, 131, + 0, 0, 5, 162, 0, 16, 0, 14, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, + 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 12, 0, 0, 0, 6, 1, 16, 0, 12, + 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 12, 0, 0, 0, 86, 13, 16, 0, + 4, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 194, 0, 16, + 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, + 32, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 4, 0, + 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, + 12, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 54, 121, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 34, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, + 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, + 12, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 86, + 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 162, 0, 16, 0, 4, 0, 0, 0, + 246, 15, 16, 0, 3, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 41, 0, 0, + 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 130, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, + 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, + 0, 12, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 5, + 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, + 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, + 0, 86, 5, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, + 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, + 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, + 10, 226, 0, 16, 0, 15, 0, 0, 0, 166, 10, 16, 0, 12, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 246, 15, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, + 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, + 58, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, + 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 14, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, + 16, 0, 12, 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, + 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, + 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 15, + 0, 0, 0, 86, 5, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 15, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, + 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, + 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 166, 10, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, + 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 12, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, + 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, + 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, + 246, 15, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, + 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, + 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, + 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 8, + 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, + 226, 0, 16, 0, 12, 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, + 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, + 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, + 0, 15, 0, 0, 0, 86, 9, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 10, 0, + 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, + 0, 16, 0, 16, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 54, 0, 0, 5, + 98, 0, 16, 0, 16, 0, 0, 0, 6, 1, 16, 0, 15, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, + 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, + 0, 138, 0, 0, 15, 114, 0, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, + 16, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, + 0, 18, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, + 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, + 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 20, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 11, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 20, + 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, + 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, + 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, + 20, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, + 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, + 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, + 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, + 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, + 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, + 0, 70, 2, 16, 0, 16, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 13, 0, + 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 0, 0, 5, 162, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 15, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 230, 11, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 20, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 16, 0, 0, 0, 42, 0, 16, 0, + 12, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 16, 0, 0, 0, 6, 3, 16, + 0, 15, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, + 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 30, 0, 0, 10, 114, 0, + 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 232, + 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, + 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, + 0, 20, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 21, 0, 0, 0, 70, + 2, 16, 128, 65, 0, 0, 0, 20, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, + 0, 21, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, + 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, + 0, 19, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 21, + 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, + 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, + 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, + 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 55, 0, + 0, 12, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, + 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, + 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 171, 170, + 170, 62, 0, 0, 0, 0, 171, 170, 170, 62, 54, 0, 0, 5, 18, 0, 16, 0, 15, + 0, 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, + 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, + 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, + 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 135, + 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, + 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, + 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, 0, 0, + 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, + 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, + 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, + 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, + 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, + 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, + 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, + 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, + 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 15, 0, 0, 0, 54, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 30, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 86, 0, 0, + 5, 50, 0, 16, 0, 5, 0, 0, 0, 198, 0, 16, 0, 15, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 1, + 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, + 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, + 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 15, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, + 2, 16, 0, 17, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, + 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, + 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 11, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, + 0, 19, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, + 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, + 20, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, + 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, + 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, + 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, 10, + 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, + 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, + 41, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, + 12, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 56, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, + 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 11, 0, 0, 0, 58, 0, + 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 14, 0, 0, 0, 10, + 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 12, 0, 0, 0, + 26, 0, 16, 0, 5, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, + 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 150, 3, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 16, 0, 0, 0, + 6, 1, 16, 0, 15, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 16, 0, 0, + 0, 86, 9, 16, 0, 12, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 16, 0, + 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, + 16, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 16, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 1, + 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, + 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, + 10, 50, 0, 16, 0, 11, 0, 0, 0, 230, 10, 16, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 98, 0, 16, 0, 12, 0, 0, 0, 166, 11, 16, 0, 15, 0, 0, 0, + 42, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 214, 2, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 14, 0, 0, 0, 70, 0, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 12, 0, 0, 0, + 230, 10, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 13, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 150, 3, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, + 12, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 13, 0, 0, 0, 10, 0, 16, + 0, 15, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, + 16, 0, 12, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 11, 0, 0, 0, 26, + 0, 16, 0, 15, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, + 58, 0, 16, 0, 12, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 14, 0, 0, + 0, 42, 0, 16, 0, 15, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 12, 0, + 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 12, + 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 194, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 5, 18, + 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 54, 0, 0, 8, + 226, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, 0, + 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, + 0, 12, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 14, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 226, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, + 1, 21, 0, 0, 1, 0, 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 0, 0, 0, 7, 242, + 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 0, 0, 0, 7, 242, 0, + 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, + 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 56, 0, 0, 7, 66, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 128, 62, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 58, 0, + 16, 0, 5, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, + 58, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, + 0, 8, 242, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 230, + 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, + 4, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, + 0, 165, 0, 0, 8, 242, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 4, 0, + 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, + 0, 16, 0, 13, 0, 0, 0, 230, 10, 16, 0, 11, 0, 0, 0, 54, 0, 0, 5, + 50, 0, 16, 0, 14, 0, 0, 0, 230, 10, 16, 0, 12, 0, 0, 0, 18, 0, 0, + 1, 41, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 13, + 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, + 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, + 10, 50, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 30, + 0, 0, 7, 50, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, + 0, 70, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 14, + 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, + 0, 5, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, + 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 5, 0, 0, 0, 6, 0, 0, 3, 1, + 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 13, 0, 0, 0, + 6, 4, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 15, 0, + 0, 0, 38, 7, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, + 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 1, + 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, + 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, + 10, 194, 0, 16, 0, 11, 0, 0, 0, 6, 4, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, + 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 38, 7, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 43, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 14, 0, 0, 0, 6, + 4, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, + 0, 38, 7, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, + 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, + 194, 0, 16, 0, 12, 0, 0, 0, 6, 4, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, + 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 38, 7, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 43, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, + 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 13, 0, 0, 0, 6, 1, 16, + 0, 13, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 13, 0, 0, 0, 6, 4, + 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 70, + 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 11, 0, 0, + 0, 6, 1, 16, 0, 11, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 11, 0, + 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 5, + 0, 0, 0, 70, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, + 0, 14, 0, 0, 0, 6, 1, 16, 0, 14, 0, 0, 0, 131, 0, 0, 5, 162, 0, + 16, 0, 14, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 50, + 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, + 5, 82, 0, 16, 0, 12, 0, 0, 0, 6, 1, 16, 0, 12, 0, 0, 0, 131, 0, + 0, 5, 162, 0, 16, 0, 12, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 2, + 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 8, 194, 0, 16, 0, 13, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, + 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, 130, + 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 12, 0, 0, 0, 58, + 0, 16, 0, 4, 0, 0, 0, 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 34, 0, + 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, 12, 0, 0, 0, 58, + 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, + 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, + 5, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, 0, + 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 6, 112, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 12, 0, 0, 0, + 26, 0, 16, 0, 5, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 21, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 5, 0, 0, 0, 6, 0, + 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, + 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 86, 5, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, + 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 26, 0, + 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, + 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, + 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 13, 0, + 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, + 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, + 15, 0, 0, 0, 166, 10, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, + 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, + 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, + 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 246, 15, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, + 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 12, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, + 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 12, 0, 0, + 0, 6, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, + 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 129, + 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, 1, + 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, + 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 86, 5, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, + 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, + 26, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, + 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, + 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, + 16, 0, 15, 0, 0, 0, 166, 10, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, + 18, 0, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, + 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, + 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 15, 0, 0, 0, 246, 15, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, + 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, + 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, + 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, + 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, + 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 12, + 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 15, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, + 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 2, 0, + 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, 1, + 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, + 86, 9, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 16, 0, + 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 16, + 0, 0, 0, 6, 1, 16, 0, 15, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, + 6, 0, 0, 0, 6, 9, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 114, 0, + 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, + 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 135, + 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, + 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, + 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, 0, 0, + 17, 114, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, + 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, + 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, + 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 70, 2, 16, 0, 16, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, + 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, + 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, + 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, + 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, + 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, + 16, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 13, 0, 0, 0, 150, 7, 16, + 0, 6, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 50, + 0, 16, 0, 5, 0, 0, 0, 230, 10, 16, 0, 15, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 15, 0, 0, 0, 230, 11, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 16, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 54, + 0, 0, 5, 98, 0, 16, 0, 16, 0, 0, 0, 6, 3, 16, 0, 15, 0, 0, 0, + 1, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 6, 9, 16, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 16, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 17, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, + 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, + 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 11, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, + 0, 0, 19, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, + 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, + 0, 20, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, + 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 41, 0, 0, + 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 0, 41, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, + 0, 11, 0, 0, 0, 150, 7, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 16, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 56, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 58, 0, + 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 6, + 9, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 17, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 135, 0, 0, 5, 114, 0, + 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 30, 0, 0, 10, 114, + 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, + 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, + 12, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, + 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 128, 65, 0, 0, 0, 18, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, + 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, + 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, + 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, + 19, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, + 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, + 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 15, 0, + 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, + 0, 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 150, 7, 16, 0, 6, 0, 0, 0, + 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 15, 0, + 0, 0, 54, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 10, + 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 86, 0, 0, 5, 98, 0, 16, 0, + 6, 0, 0, 0, 6, 3, 16, 0, 15, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 15, 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 114, 0, + 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, + 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, + 0, 15, 114, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, + 0, 135, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, + 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, + 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, + 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, + 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, + 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 19, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, + 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 140, + 0, 0, 17, 114, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, + 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, + 0, 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, + 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 17, + 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, + 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, + 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, + 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, + 16, 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 12, 0, 0, 0, 70, + 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, + 10, 98, 0, 16, 0, 6, 0, 0, 0, 86, 6, 16, 0, 6, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 171, 170, 170, 62, 171, 170, 170, 62, 0, 0, 0, 0, 54, + 0, 0, 5, 130, 0, 16, 0, 13, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, + 54, 0, 0, 5, 130, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, + 0, 54, 0, 0, 5, 130, 0, 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, 6, 0, + 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 6, + 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 150, 3, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 16, 0, 0, 0, 6, 1, 16, 0, 15, + 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 16, 0, 0, 0, 86, 9, 16, 0, + 12, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, + 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 16, 0, 0, 0, 70, + 14, 16, 0, 16, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, + 70, 14, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 13, 0, + 0, 0, 70, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, + 11, 0, 0, 0, 230, 10, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 98, 0, + 16, 0, 12, 0, 0, 0, 166, 11, 16, 0, 15, 0, 0, 0, 42, 0, 0, 10, 242, + 0, 16, 0, 15, 0, 0, 0, 214, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, + 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 52, 0, 0, 10, 50, 0, 16, 0, 14, 0, 0, 0, 70, 0, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, + 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 12, 0, 0, 0, 230, 10, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, + 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 15, 0, 0, 0, 150, 3, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, 0, + 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 131, + 0, 0, 5, 34, 0, 16, 0, 13, 0, 0, 0, 10, 0, 16, 0, 15, 0, 0, 0, + 131, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, + 0, 131, 0, 0, 5, 34, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 15, 0, + 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 12, + 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, + 15, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, + 0, 12, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, 0, 12, 0, 0, 0, 58, 0, + 16, 0, 15, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 13, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, + 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, + 0, 12, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, + 54, 0, 0, 8, 226, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 226, 0, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, + 0, 0, 0, 7, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, + 0, 70, 14, 16, 0, 13, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 0, + 0, 0, 7, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 14, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 12, 0, 0, + 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 30, 0, + 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 26, + 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, + 32, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 3, 0, + 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, + 15, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 165, 0, 0, 8, 242, + 0, 16, 0, 16, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 230, 116, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 17, 0, 0, + 0, 230, 10, 16, 0, 15, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 18, 0, + 0, 0, 230, 10, 16, 0, 16, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, + 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 17, 0, 0, 0, 58, 0, 16, + 0, 3, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, + 8, 50, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 70, 112, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 162, 0, 16, + 0, 4, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 4, 0, + 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 165, 0, 0, 8, 50, 0, 16, 0, 18, 0, 0, 0, 26, 0, 16, + 0, 4, 0, 0, 0, 70, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, + 0, 8, 50, 0, 16, 0, 16, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 70, + 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, + 42, 0, 16, 0, 5, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, + 0, 41, 0, 0, 10, 194, 0, 16, 0, 17, 0, 0, 0, 6, 4, 16, 0, 17, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 38, 7, 16, 0, + 17, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, + 16, 0, 19, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 70, + 14, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, + 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 15, + 0, 0, 0, 6, 4, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, + 0, 19, 0, 0, 0, 38, 7, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, + 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, 64, 0, + 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, + 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, + 41, 0, 0, 10, 194, 0, 16, 0, 18, 0, 0, 0, 6, 4, 16, 0, 18, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 38, 7, 16, 0, 18, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, + 0, 19, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, + 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, + 70, 14, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 41, 0, 0, 10, 194, 0, 16, 0, 16, 0, + 0, 0, 6, 4, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, + 19, 0, 0, 0, 38, 7, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, + 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, + 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, + 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 85, 0, 0, 10, + 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 17, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, + 0, 5, 82, 0, 16, 0, 17, 0, 0, 0, 6, 1, 16, 0, 17, 0, 0, 0, 131, + 0, 0, 5, 162, 0, 16, 0, 17, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, + 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 15, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 15, 0, 0, 0, 6, 1, 16, 0, 15, + 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 15, 0, 0, 0, 86, 13, 16, 0, + 4, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, + 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 18, 0, 0, 0, 6, + 1, 16, 0, 18, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, 18, 0, 0, 0, + 86, 13, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, + 0, 6, 4, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 82, 0, 16, 0, 16, + 0, 0, 0, 6, 1, 16, 0, 16, 0, 0, 0, 131, 0, 0, 5, 162, 0, 16, 0, + 16, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, + 1, 54, 0, 0, 8, 194, 0, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, + 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 18, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, + 23, 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, + 4, 3, 58, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 3, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 165, 0, 0, 8, 242, 0, 16, 0, 16, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, + 0, 54, 121, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, + 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 16, 0, 0, 0, + 58, 0, 16, 0, 3, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 165, 0, 0, 8, 66, 0, 16, 0, 16, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 162, 0, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, + 162, 0, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 86, 13, 16, + 0, 4, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 16, 0, 0, 0, + 26, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 165, 0, 0, 8, 18, 0, 16, 0, 16, 0, 0, 0, 58, 0, 16, 0, 4, 0, + 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 76, + 0, 0, 3, 42, 0, 16, 0, 5, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, + 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, + 10, 226, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 16, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, 166, 10, + 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, + 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, + 42, 0, 16, 0, 16, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 15, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 10, 226, 0, + 16, 0, 5, 0, 0, 0, 246, 15, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 5, + 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 16, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, + 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, + 128, 59, 85, 0, 0, 10, 226, 0, 16, 0, 16, 0, 0, 0, 6, 0, 16, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, + 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 16, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, + 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 85, + 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 16, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, + 0, 54, 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 16, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, + 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, + 166, 10, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, + 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 5, 0, + 0, 0, 42, 0, 16, 0, 16, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, + 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, + 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 85, 0, 0, 10, + 226, 0, 16, 0, 5, 0, 0, 0, 246, 15, 16, 0, 16, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 16, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 3, 0, 0, + 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, + 171, 170, 170, 62, 85, 0, 0, 10, 226, 0, 16, 0, 16, 0, 0, 0, 6, 0, 16, + 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 20, 0, + 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 16, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, + 32, 128, 58, 8, 32, 128, 58, 171, 170, 170, 62, 2, 0, 0, 1, 6, 0, 0, 3, + 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 86, 9, 16, 0, 16, 0, + 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 30, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 19, 0, 0, 0, 26, 0, 16, 0, + 16, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 19, 0, 0, 0, 6, 1, 16, + 0, 5, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 6, 9, + 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, + 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 21, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, + 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 30, 0, 0, 10, 114, 0, + 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, 232, + 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, + 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, + 0, 22, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 23, 0, 0, 0, 70, + 2, 16, 128, 65, 0, 0, 0, 22, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, + 0, 23, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, 0, + 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 19, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, + 0, 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 19, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 23, + 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, + 0, 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 55, 0, + 0, 12, 114, 0, 16, 0, 17, 0, 0, 0, 150, 7, 16, 0, 6, 0, 0, 0, 70, + 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 162, 0, 16, 0, 4, 0, 0, + 0, 166, 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, + 0, 0, 230, 11, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, + 19, 0, 0, 0, 42, 0, 16, 0, 16, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, + 0, 19, 0, 0, 0, 6, 3, 16, 0, 5, 0, 0, 0, 1, 0, 0, 10, 226, 0, + 16, 0, 6, 0, 0, 0, 6, 9, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, + 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, + 0, 15, 114, 0, 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 135, 0, 0, 5, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, + 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, + 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, + 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, + 0, 20, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, + 0, 16, 0, 23, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 22, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 55, 0, 0, 9, 114, 0, 16, 0, 23, 0, 0, 0, 70, 2, 16, 0, 21, 0, + 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 140, + 0, 0, 17, 114, 0, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, + 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, + 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, + 0, 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, + 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 20, + 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, + 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, + 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, + 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, + 16, 0, 19, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 15, 0, 0, 0, 150, + 7, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, + 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 171, 170, 170, 62, 0, 0, 0, 0, 171, 170, 170, 62, 54, + 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 16, 0, 0, 0, + 1, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 6, 9, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 20, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 5, 0, 0, 0, 135, 0, 0, 5, 114, 0, 16, 0, 21, 0, 0, 0, + 70, 2, 16, 0, 19, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 21, 0, 0, + 0, 70, 2, 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, + 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 21, + 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 11, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 128, 65, 0, + 0, 0, 21, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 22, 0, 0, 0, + 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, + 0, 22, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 9, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, + 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 41, 0, 0, + 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 0, 41, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, + 19, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, + 0, 18, 0, 0, 0, 150, 7, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 5, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 54, 0, 16, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, + 0, 30, 0, 0, 0, 86, 0, 0, 5, 98, 0, 16, 0, 6, 0, 0, 0, 6, 3, + 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 10, + 0, 16, 0, 16, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, + 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 20, 0, + 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, + 21, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 135, 0, 0, 5, 114, + 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 30, 0, 0, 10, + 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, + 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 55, 0, + 0, 12, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, + 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 114, 0, 16, 0, 23, 0, 0, + 0, 70, 2, 16, 128, 65, 0, 0, 0, 22, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, + 0, 16, 0, 23, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, + 21, 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 140, 0, 0, 17, 114, 0, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 5, 0, 0, 0, 70, + 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, + 5, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, + 0, 23, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, + 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, + 0, 0, 0, 62, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, + 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 5, + 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, + 55, 0, 0, 12, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, + 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 10, 50, 0, 16, 0, 5, + 0, 0, 0, 150, 5, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 171, 170, 170, 62, + 171, 170, 170, 62, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, + 0, 17, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, + 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, + 0, 16, 0, 18, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, + 130, 0, 16, 0, 16, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 2, 0, 0, + 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 150, 3, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, + 82, 0, 16, 0, 19, 0, 0, 0, 6, 1, 16, 0, 5, 0, 0, 0, 54, 0, 0, + 5, 162, 0, 16, 0, 19, 0, 0, 0, 86, 9, 16, 0, 16, 0, 0, 0, 42, 0, + 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 43, 0, 0, 5, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 19, 0, 0, 0, 70, 14, 16, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 52, 0, 0, 10, 50, 0, 16, 0, 17, 0, 0, 0, 70, 0, 16, 0, + 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, + 0, 0, 0, 0, 0, 52, 0, 0, 10, 50, 0, 16, 0, 15, 0, 0, 0, 230, 10, + 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 16, 0, 0, 0, + 166, 11, 16, 0, 5, 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 214, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 50, 0, + 16, 0, 18, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 10, + 50, 0, 16, 0, 16, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 18, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 8, 194, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, + 3, 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, + 0, 0, 150, 3, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 131, 0, 0, 5, 18, 0, 16, 0, + 17, 0, 0, 0, 26, 0, 16, 0, 16, 0, 0, 0, 131, 0, 0, 5, 34, 0, 16, + 0, 17, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 131, 0, 0, 5, 18, 0, + 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 16, 0, 0, 0, 131, 0, 0, 5, 34, + 0, 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 131, 0, 0, 5, + 18, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 16, 0, 0, 0, 131, 0, 0, + 5, 34, 0, 16, 0, 18, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 131, 0, + 0, 5, 18, 0, 16, 0, 16, 0, 0, 0, 10, 0, 16, 0, 16, 0, 0, 0, 131, + 0, 0, 5, 34, 0, 16, 0, 16, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 18, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 8, 194, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, + 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 17, 0, 0, 0, 26, 0, 16, 0, + 16, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 17, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 16, 0, 0, 0, 54, + 0, 0, 8, 226, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 18, 0, 0, 0, 58, 0, 16, 0, 16, 0, 0, 0, 54, 0, 0, 8, 226, 0, + 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 16, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, 0, 0, 0, 7, 242, 0, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 17, + 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 18, 0, + 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, + 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 21, 0, 0, + 1, 21, 0, 0, 1, 56, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, 166, 10, + 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 56, 0, 0, 7, 242, + 0, 16, 0, 7, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 118, 8, 16, 0, + 7, 0, 0, 0, 56, 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 166, 10, 16, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 7, 242, 0, + 16, 0, 8, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 134, 7, 16, 0, 8, + 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, + 82, 0, 16, 0, 5, 0, 0, 0, 166, 8, 16, 0, 5, 0, 0, 0, 54, 0, 0, + 5, 82, 0, 16, 0, 10, 0, 0, 0, 246, 14, 16, 0, 7, 0, 0, 0, 54, 0, + 0, 5, 82, 0, 16, 0, 9, 0, 0, 0, 166, 8, 16, 0, 9, 0, 0, 0, 54, + 0, 0, 5, 82, 0, 16, 0, 11, 0, 0, 0, 86, 4, 16, 0, 8, 0, 0, 0, + 18, 0, 0, 1, 54, 0, 0, 5, 82, 0, 16, 0, 10, 0, 0, 0, 166, 11, 16, + 0, 7, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 11, 0, 0, 0, 6, 1, + 16, 0, 8, 0, 0, 0, 21, 0, 0, 1, 76, 0, 0, 3, 10, 0, 16, 0, 6, + 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 26, 0, 0, 0, 54, 32, 0, 5, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 50, 0, 0, + 15, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 0, 255, 127, 71, 0, 255, 127, 71, 0, 255, 127, 71, 0, 255, 127, 71, 2, + 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, + 28, 0, 0, 5, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, + 0, 35, 0, 0, 12, 194, 0, 16, 0, 7, 0, 0, 0, 86, 13, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 6, 8, 16, 0, 6, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, + 10, 0, 0, 0, 86, 1, 16, 0, 7, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 50, 0, 0, 15, 242, 0, + 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, + 255, 127, 71, 0, 255, 127, 71, 0, 255, 127, 71, 0, 255, 127, 71, 2, 64, 0, 0, + 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, + 5, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 35, 0, + 0, 12, 50, 0, 16, 0, 7, 0, 0, 0, 214, 5, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 134, 0, 16, 0, 6, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 9, 0, 0, + 0, 70, 14, 16, 0, 9, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 255, 127, 71, 0, + 255, 127, 71, 0, 255, 127, 71, 0, 255, 127, 71, 2, 64, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, + 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 35, 0, 0, 12, 50, 0, + 16, 0, 8, 0, 0, 0, 214, 5, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 0, 16, 0, + 6, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 11, 0, 0, 0, 246, 11, 16, + 0, 8, 0, 0, 0, 54, 32, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, + 16, 0, 11, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 6, 0, 0, 0, 70, + 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 255, 127, 71, 0, 255, 127, 71, + 0, 255, 127, 71, 0, 255, 127, 71, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, + 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, 0, 8, + 0, 0, 0, 86, 13, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 6, 8, 16, 0, 6, 0, 0, + 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 32, 0, 0, 0, 130, 0, + 0, 5, 98, 0, 16, 0, 0, 0, 0, 0, 6, 2, 16, 0, 5, 0, 0, 0, 130, + 0, 0, 5, 98, 0, 16, 0, 1, 0, 0, 0, 86, 7, 16, 0, 5, 0, 0, 0, + 35, 0, 0, 12, 194, 0, 16, 0, 7, 0, 0, 0, 86, 9, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 86, 9, 16, 0, 0, 0, 0, 0, 130, 0, 0, 5, 98, 0, 16, 0, 0, + 0, 0, 0, 6, 2, 16, 0, 10, 0, 0, 0, 130, 0, 0, 5, 98, 0, 16, 0, + 1, 0, 0, 0, 86, 4, 16, 0, 7, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, + 0, 7, 0, 0, 0, 150, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, 0, + 0, 0, 0, 130, 0, 0, 5, 98, 0, 16, 0, 0, 0, 0, 0, 6, 2, 16, 0, + 9, 0, 0, 0, 130, 0, 0, 5, 98, 0, 16, 0, 1, 0, 0, 0, 86, 7, 16, + 0, 9, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 8, 0, 0, 0, 150, 5, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, 0, 0, 0, 0, 130, 0, 0, 5, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 2, 16, 0, 11, 0, 0, 0, 130, 0, 0, + 5, 98, 0, 16, 0, 1, 0, 0, 0, 246, 14, 16, 0, 8, 0, 0, 0, 35, 0, + 0, 12, 194, 0, 16, 0, 8, 0, 0, 0, 86, 9, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 86, 9, 16, 0, 0, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 54, 0, 0, + 5, 194, 0, 16, 0, 7, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 54, + 0, 0, 5, 50, 0, 16, 0, 8, 0, 0, 0, 70, 0, 16, 0, 9, 0, 0, 0, + 54, 0, 0, 5, 66, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, + 0, 2, 0, 0, 1, 23, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 39, + 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 31, 0, + 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, + 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, + 0, 16, 0, 8, 0, 0, 0, 230, 10, 16, 0, 8, 0, 0, 0, 21, 0, 0, 1, + 54, 0, 0, 5, 50, 0, 16, 0, 7, 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, + 0, 21, 0, 0, 1, 54, 0, 0, 5, 242, 0, 16, 0, 7, 0, 0, 0, 70, 4, + 16, 0, 7, 0, 0, 0, 21, 0, 0, 1, 54, 0, 0, 4, 66, 0, 16, 0, 4, + 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 9, 98, 0, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 3, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 6, 2, 16, + 0, 4, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 78, 0, 0, 8, 98, + 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, + 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 11, 130, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 5, 0, 0, 0, 42, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, + 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, + 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 254, 7, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 85, 0, 0, 7, 18, + 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 5, 0, 0, 0, 139, 0, 0, 15, 194, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 86, + 5, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, + 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, 7, 18, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 0, 48, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 3, + 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, + 0, 3, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 140, 0, + 0, 20, 98, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 19, + 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 150, 5, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, 66, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, + 10, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, + 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, 0, 16, 0, 2, 0, + 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 17, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 140, 0, + 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 15, 194, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 42, 0, 0, 10, 50, 0, 16, 0, + 3, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 41, 0, 0, 10, 82, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 128, 3, 0, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 98, 0, + 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, + 98, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 86, + 6, 16, 0, 4, 0, 0, 0, 140, 0, 0, 17, 162, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 12, 0, + 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 86, 9, 16, 0, 4, 0, 0, 0, 35, + 0, 0, 12, 162, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 86, 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 0, 7, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 130, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, + 35, 0, 0, 10, 98, 0, 16, 0, 0, 0, 0, 0, 86, 6, 16, 128, 65, 0, 0, + 0, 0, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 1, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 18, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, + 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 32, 0, 0, 7, 66, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, + 0, 7, 0, 0, 0, 22, 11, 16, 0, 7, 0, 0, 0, 54, 0, 0, 5, 130, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 18, 0, 0, 1, 54, + 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 21, 0, 0, 1, 32, 0, 0, 10, 114, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 150, + 5, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, + 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 230, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, + 0, 5, 0, 0, 0, 230, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 7, 0, 0, 0, 230, 4, 16, 0, 3, 0, 0, 0, 230, 4, + 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 1, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 230, 4, 16, 0, + 7, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 70, 14, 16, 0, 7, 0, 0, 0, 230, 4, 16, 0, 1, 0, 0, 0, 21, 0, 0, + 1, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, + 16, 0, 0, 0, 0, 0, 230, 4, 16, 0, 7, 0, 0, 0, 79, 0, 0, 7, 130, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, + 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 78, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 0, + 208, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 35, 0, 0, 10, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, + 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 8, 130, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 130, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, + 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, + 0, 21, 0, 0, 1, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, + 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 31, 0, + 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 194, 0, 16, 0, 8, + 0, 0, 0, 246, 11, 16, 0, 8, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, + 8, 0, 0, 0, 22, 14, 16, 0, 8, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 21, 0, 0, 1, 32, 0, + 0, 10, 210, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, + 60, 0, 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, + 0, 6, 2, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, + 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 8, + 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, + 0, 0, 17, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 8, 0, + 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, + 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 8, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, + 0, 30, 5, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 118, 0, + 0, 0, 29, 1, 0, 0, 188, 0, 0, 0, 62, 0, 0, 0, 40, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 195, 0, 0, 0, 64, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_8bpp_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_8bpp_cs.h new file mode 100644 index 0000000..55efc4e --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_8bpp_cs.h @@ -0,0 +1,1761 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_resolve_edram_info; // Offset: 0 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 4 Size: 4 +// uint xe_resolve_dest_info; // Offset: 8 Size: 4 +// uint xe_resolve_dest_coordinate_info;// Offset: 12 Size: 4 +// uint xe_resolve_dest_base; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram texture byte r/o T0 t0 1 +// xe_resolve_dest UAV uint2 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][2], immediateIndexed, space=0 +dcl_resource_raw T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 17 +dcl_thread_group 8, 8, 1 +ubfe r0.x, l(11), l(5), CB0[0][0].y +and r0.yzw, CB0[0][0].xxzz, l(0, 1023, 8, 0x01000000) +ushr r1.xyzw, CB0[0][0].ywww, l(4, 10, 20, 24) +uge r0.x, vThreadID.x, r0.x +if_nz r0.x + ret +endif +ubfe r2.xyzw, l(2, 11, 4, 1), l(10, 13, 24, 28), CB0[0][0].xxxx +mov r3.x, CB0[0][0].y +mov r3.y, r1.x +bfi r3.xy, l(4, 1, 0, 0), l(3, 3, 0, 0), r3.xyxx, l(0, 0, 0, 0) +ibfe r0.x, l(6), l(16), CB0[0][0].z +ishl r0.x, r0.x, l(23) +iadd r0.x, r0.x, l(0x3f800000) +bfi r1.x, l(10), l(5), CB0[0][0].w, l(0) +bfi r4.xyzw, l(4, 4, 4, 4), l(3, 3, 3, 3), r1.zwwz, l(0, 0, 0, 0) +ubfe r1.z, l(3), l(28), CB0[0][0].w +ishl r5.xw, vThreadID.xxxx, l(3, 0, 0, 3) +mov r5.yz, vThreadID.yyyy +iadd r3.xy, r3.xyxx, r5.wzww +uge r1.w, l(3), r1.z +if_nz r1.w + mov r6.y, r1.z +else + ieq r1.w, r1.z, l(5) + if_nz r1.w + mov r6.y, l(2) + else + mov r6.y, l(0) + endif +endif +uge r3.zw, r2.xxxx, l(0, 0, 2, 1) +and r3.zw, r3.zzzw, l(0, 0, 1, 1) +ishl r3.xy, r3.xyxx, r3.zwzz +ushr r6.x, r6.y, l(1) +and r6.xy, r6.xyxx, l(1, 1, 0, 0) +iadd r3.xy, r3.xyxx, r6.xyxx +ushr r6.x, l(80), r2.w +mov r6.y, l(16) +udiv r6.zw, null, r3.xxxy, r6.xxxy +imad r0.y, r6.w, r0.y, r6.z +iadd r0.y, r0.y, r2.y +imad r2.xy, -r6.zwzz, r6.xyxx, r3.xyxx +imad r1.w, r2.y, r6.x, r2.x +ishl r1.w, r1.w, r2.w +imad r0.y, r0.y, l(1280), r1.w +udiv null, r0.y, r0.y, l(0x00280000) +iadd r1.w, r2.w, r3.z +ishl r2.x, l(1), r1.w +if_nz r0.w + iadd r0.y, r2.w, r0.y +endif +ieq r2.y, r2.x, l(1) +if_nz r2.y + ishl r3.x, r0.y, l(2) + ld_raw r6.xyzw, r3.x, T0[0].xyzw + iadd r3.x, r3.x, l(16) + ld_raw r3.xyzw, r3.x, T0[0].xyzw +else + ishl r7.x, r0.y, l(2) + ld_raw r6.x, r7.x, T0[0].xxxx + iadd r7.x, r2.x, r0.y + ishl r7.x, r7.x, l(2) + ld_raw r6.y, r7.x, T0[0].xxxx + ishl r7.xyzw, l(2, 3, 4, 5), r1.wwww + iadd r7.xyzw, r0.yyyy, r7.xyzw + ishl r7.xyzw, r7.xyzw, l(2, 2, 2, 2) + ld_raw r6.z, r7.x, T0[0].xxxx + ld_raw r6.w, r7.y, T0[0].xxxx + ld_raw r3.x, r7.z, T0[0].xxxx + ld_raw r3.y, r7.w, T0[0].xxxx + ishl r7.xy, l(6, 7, 0, 0), r1.wwww + iadd r7.xy, r0.yyyy, r7.xyxx + ishl r7.xy, r7.xyxx, l(2, 2, 0, 0) + ld_raw r3.z, r7.x, T0[0].xxxx + ld_raw r3.w, r7.y, T0[0].xxxx +endif +if_nz r2.w + switch r2.z + case l(5) + ibfe r7.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r6.xyzw + itof r7.xyzw, r7.xyzw + mul r7.xyzw, r7.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r6.xyzw, r7.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ibfe r7.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r3.xyzw + itof r7.xyzw, r7.xyzw + mul r7.xyzw, r7.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r3.xyzw, r7.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + f16tof32 r6.xyzw, r6.xyzw + f16tof32 r3.xyzw, r3.xyzw + break + default + break + endswitch +else + switch r2.z + case l(0) + case l(1) + movc r7.x, r0.w, l(16), l(0) + ushr r8.xyzw, r6.xyzw, r7.xxxx + and r8.xyzw, r8.xyzw, l(255, 255, 255, 255) + utof r8.xyzw, r8.xyzw + mul r6.xyzw, r8.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r7.xyzw, r3.xyzw, r7.xxxx + and r7.xyzw, r7.xyzw, l(255, 255, 255, 255) + utof r7.xyzw, r7.xyzw + mul r3.xyzw, r7.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + movc r7.x, r0.w, l(20), l(0) + ushr r8.xyzw, r6.xyzw, r7.xxxx + and r8.xyzw, r8.xyzw, l(1023, 1023, 1023, 1023) + utof r8.xyzw, r8.xyzw + mul r6.xyzw, r8.xyzw, l(0.000978, 0.000978, 0.000978, 0.000978) + ushr r7.xyzw, r3.xyzw, r7.xxxx + and r7.xyzw, r7.xyzw, l(1023, 1023, 1023, 1023) + utof r7.xyzw, r7.xyzw + mul r3.xyzw, r7.xyzw, l(0.000978, 0.000978, 0.000978, 0.000978) + break + case l(3) + case l(12) + movc r7.x, r0.w, l(20), l(0) + ushr r8.xyzw, r6.xyzw, r7.xxxx + and r9.xyzw, r8.xyzw, l(1023, 1023, 1023, 1023) + and r10.xyzw, r8.xyzw, l(127, 127, 127, 127) + ubfe r11.xyzw, l(3, 3, 3, 3), l(7, 7, 7, 7), r8.xyzw + firstbit_hi r12.xyzw, r10.xyzw + iadd r12.xyzw, r12.xyzw, l(-24, -24, -24, -24) + movc r12.xyzw, r10.xyzw, r12.xyzw, l(8,8,8,8) + iadd r13.xyzw, -r12.xyzw, l(1, 1, 1, 1) + movc r13.xyzw, r11.xyzw, r11.xyzw, r13.xyzw + bfi r8.xyzw, l(7, 7, 7, 7), r12.xyzw, r8.xyzw, l(0, 0, 0, 0) + and r8.xyzw, r8.xyzw, l(127, 127, 127, 127) + movc r8.xyzw, r11.xyzw, r10.xyzw, r8.xyzw + ishl r10.xyzw, r13.xyzw, l(23, 23, 23, 23) + iadd r10.xyzw, r10.xyzw, l(0x3e000000, 0x3e000000, 0x3e000000, 0x3e000000) + ishl r8.xyzw, r8.xyzw, l(16, 16, 16, 16) + iadd r8.xyzw, r10.xyzw, r8.xyzw + movc r6.xyzw, r9.xyzw, r8.xyzw, l(0,0,0,0) + ushr r7.xyzw, r3.xyzw, r7.xxxx + and r8.xyzw, r7.xyzw, l(1023, 1023, 1023, 1023) + and r9.xyzw, r7.xyzw, l(127, 127, 127, 127) + ubfe r10.xyzw, l(3, 3, 3, 3), l(7, 7, 7, 7), r7.xyzw + firstbit_hi r11.xyzw, r9.xyzw + iadd r11.xyzw, r11.xyzw, l(-24, -24, -24, -24) + movc r11.xyzw, r9.xyzw, r11.xyzw, l(8,8,8,8) + iadd r12.xyzw, -r11.xyzw, l(1, 1, 1, 1) + movc r12.xyzw, r10.xyzw, r10.xyzw, r12.xyzw + bfi r7.xyzw, l(7, 7, 7, 7), r11.xyzw, r7.xyzw, l(0, 0, 0, 0) + and r7.xyzw, r7.xyzw, l(127, 127, 127, 127) + movc r7.xyzw, r10.xyzw, r9.xyzw, r7.xyzw + ishl r9.xyzw, r12.xyzw, l(23, 23, 23, 23) + iadd r9.xyzw, r9.xyzw, l(0x3e000000, 0x3e000000, 0x3e000000, 0x3e000000) + ishl r7.xyzw, r7.xyzw, l(16, 16, 16, 16) + iadd r7.xyzw, r9.xyzw, r7.xyzw + movc r3.xyzw, r8.xyzw, r7.xyzw, l(0,0,0,0) + break + case l(4) + ibfe r7.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r6.xyzw + itof r7.xyzw, r7.xyzw + mul r7.xyzw, r7.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r6.xyzw, r7.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ibfe r7.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r3.xyzw + itof r7.xyzw, r7.xyzw + mul r7.xyzw, r7.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r3.xyzw, r7.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(6) + f16tof32 r6.xyzw, r6.xyzw + f16tof32 r3.xyzw, r3.xyzw + break + default + break + endswitch +endif +uge r7.x, r1.z, l(4) +if_nz r7.x + mul r7.x, r0.x, l(0.500000) + iadd r7.y, r0.y, l(80) + if_nz r2.y + ishl r7.z, r7.y, l(2) + ld_raw r8.xyzw, r7.z, T0[0].xyzw + iadd r7.z, r7.z, l(16) + ld_raw r9.xyzw, r7.z, T0[0].xyzw + else + ishl r7.z, r7.y, l(2) + ld_raw r8.x, r7.z, T0[0].xxxx + iadd r7.z, r2.x, r7.y + ishl r7.z, r7.z, l(2) + ld_raw r8.y, r7.z, T0[0].xxxx + ishl r10.xyzw, l(2, 3, 4, 5), r1.wwww + iadd r10.xyzw, r7.yyyy, r10.xyzw + ishl r10.xyzw, r10.xyzw, l(2, 2, 2, 2) + ld_raw r8.z, r10.x, T0[0].xxxx + ld_raw r8.w, r10.y, T0[0].xxxx + ld_raw r9.x, r10.z, T0[0].xxxx + ld_raw r9.y, r10.w, T0[0].xxxx + ishl r7.zw, l(0, 0, 6, 7), r1.wwww + iadd r7.zw, r7.zzzw, r7.yyyy + ishl r7.zw, r7.zzzw, l(0, 0, 2, 2) + ld_raw r9.z, r7.z, T0[0].xxxx + ld_raw r9.w, r7.w, T0[0].xxxx + endif + if_nz r2.w + switch r2.z + case l(5) + ibfe r10.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r8.xyzw + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ibfe r10.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r9.xyzw + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + f16tof32 r8.xyzw, r8.xyzw + f16tof32 r9.xyzw, r9.xyzw + break + default + break + endswitch + else + switch r2.z + case l(0) + case l(1) + movc r7.z, r0.w, l(16), l(0) + ushr r10.xyzw, r8.xyzw, r7.zzzz + and r10.xyzw, r10.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r10.xyzw, r9.xyzw, r7.zzzz + and r10.xyzw, r10.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + movc r7.z, r0.w, l(20), l(0) + ushr r10.xyzw, r8.xyzw, r7.zzzz + and r10.xyzw, r10.xyzw, l(1023, 1023, 1023, 1023) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.000978) + ushr r10.xyzw, r9.xyzw, r7.zzzz + and r10.xyzw, r10.xyzw, l(1023, 1023, 1023, 1023) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.000978) + break + case l(3) + case l(12) + movc r7.z, r0.w, l(20), l(0) + ushr r10.xyzw, r8.xyzw, r7.zzzz + and r11.xyzw, r10.xyzw, l(1023, 1023, 1023, 1023) + and r12.xyzw, r10.xyzw, l(127, 127, 127, 127) + ubfe r13.xyzw, l(3, 3, 3, 3), l(7, 7, 7, 7), r10.xyzw + firstbit_hi r14.xyzw, r12.xyzw + iadd r14.xyzw, r14.xyzw, l(-24, -24, -24, -24) + movc r14.xyzw, r12.xyzw, r14.xyzw, l(8,8,8,8) + iadd r15.xyzw, -r14.xyzw, l(1, 1, 1, 1) + movc r15.xyzw, r13.xyzw, r13.xyzw, r15.xyzw + bfi r10.xyzw, l(7, 7, 7, 7), r14.xyzw, r10.xyzw, l(0, 0, 0, 0) + and r10.xyzw, r10.xyzw, l(127, 127, 127, 127) + movc r10.xyzw, r13.xyzw, r12.xyzw, r10.xyzw + ishl r12.xyzw, r15.xyzw, l(23, 23, 23, 23) + iadd r12.xyzw, r12.xyzw, l(0x3e000000, 0x3e000000, 0x3e000000, 0x3e000000) + ishl r10.xyzw, r10.xyzw, l(16, 16, 16, 16) + iadd r10.xyzw, r12.xyzw, r10.xyzw + movc r8.xyzw, r11.xyzw, r10.xyzw, l(0,0,0,0) + ushr r10.xyzw, r9.xyzw, r7.zzzz + and r11.xyzw, r10.xyzw, l(1023, 1023, 1023, 1023) + and r12.xyzw, r10.xyzw, l(127, 127, 127, 127) + ubfe r13.xyzw, l(3, 3, 3, 3), l(7, 7, 7, 7), r10.xyzw + firstbit_hi r14.xyzw, r12.xyzw + iadd r14.xyzw, r14.xyzw, l(-24, -24, -24, -24) + movc r14.xyzw, r12.xyzw, r14.xyzw, l(8,8,8,8) + iadd r15.xyzw, -r14.xyzw, l(1, 1, 1, 1) + movc r15.xyzw, r13.xyzw, r13.xyzw, r15.xyzw + bfi r10.xyzw, l(7, 7, 7, 7), r14.xyzw, r10.xyzw, l(0, 0, 0, 0) + and r10.xyzw, r10.xyzw, l(127, 127, 127, 127) + movc r10.xyzw, r13.xyzw, r12.xyzw, r10.xyzw + ishl r12.xyzw, r15.xyzw, l(23, 23, 23, 23) + iadd r12.xyzw, r12.xyzw, l(0x3e000000, 0x3e000000, 0x3e000000, 0x3e000000) + ishl r10.xyzw, r10.xyzw, l(16, 16, 16, 16) + iadd r10.xyzw, r12.xyzw, r10.xyzw + movc r9.xyzw, r11.xyzw, r10.xyzw, l(0,0,0,0) + break + case l(4) + ibfe r10.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r8.xyzw + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ibfe r10.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r9.xyzw + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(6) + f16tof32 r8.xyzw, r8.xyzw + f16tof32 r9.xyzw, r9.xyzw + break + default + break + endswitch + endif + add r6.xyzw, r6.xyzw, r8.xyzw + add r3.xyzw, r3.xyzw, r9.xyzw + uge r1.z, r1.z, l(6) + if_nz r1.z + ishl r1.z, l(1), r2.w + mul r0.x, r0.x, l(0.250000) + iadd r0.y, r0.y, r1.z + if_nz r2.y + ishl r7.z, r0.y, l(2) + ld_raw r8.xyzw, r7.z, T0[0].xyzw + iadd r7.z, r7.z, l(16) + ld_raw r9.xyzw, r7.z, T0[0].xyzw + else + ishl r7.z, r0.y, l(2) + ld_raw r8.x, r7.z, T0[0].xxxx + iadd r7.z, r2.x, r0.y + ishl r7.z, r7.z, l(2) + ld_raw r8.y, r7.z, T0[0].xxxx + ishl r10.xyzw, l(2, 3, 4, 5), r1.wwww + iadd r10.xyzw, r0.yyyy, r10.xyzw + ishl r10.xyzw, r10.xyzw, l(2, 2, 2, 2) + ld_raw r8.z, r10.x, T0[0].xxxx + ld_raw r8.w, r10.y, T0[0].xxxx + ld_raw r9.x, r10.z, T0[0].xxxx + ld_raw r9.y, r10.w, T0[0].xxxx + ishl r7.zw, l(0, 0, 6, 7), r1.wwww + iadd r7.zw, r0.yyyy, r7.zzzw + ishl r7.zw, r7.zzzw, l(0, 0, 2, 2) + ld_raw r9.z, r7.z, T0[0].xxxx + ld_raw r9.w, r7.w, T0[0].xxxx + endif + if_nz r2.w + switch r2.z + case l(5) + ibfe r10.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r8.xyzw + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ibfe r10.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r9.xyzw + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + f16tof32 r8.xyzw, r8.xyzw + f16tof32 r9.xyzw, r9.xyzw + break + default + break + endswitch + else + switch r2.z + case l(0) + case l(1) + movc r0.y, r0.w, l(16), l(0) + ushr r10.xyzw, r8.xyzw, r0.yyyy + and r10.xyzw, r10.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r10.xyzw, r9.xyzw, r0.yyyy + and r10.xyzw, r10.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + movc r0.y, r0.w, l(20), l(0) + ushr r10.xyzw, r8.xyzw, r0.yyyy + and r10.xyzw, r10.xyzw, l(1023, 1023, 1023, 1023) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.000978) + ushr r10.xyzw, r9.xyzw, r0.yyyy + and r10.xyzw, r10.xyzw, l(1023, 1023, 1023, 1023) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.000978) + break + case l(3) + case l(12) + movc r0.y, r0.w, l(20), l(0) + ushr r10.xyzw, r8.xyzw, r0.yyyy + and r11.xyzw, r10.xyzw, l(1023, 1023, 1023, 1023) + and r12.xyzw, r10.xyzw, l(127, 127, 127, 127) + ubfe r13.xyzw, l(3, 3, 3, 3), l(7, 7, 7, 7), r10.xyzw + firstbit_hi r14.xyzw, r12.xyzw + iadd r14.xyzw, r14.xyzw, l(-24, -24, -24, -24) + movc r14.xyzw, r12.xyzw, r14.xyzw, l(8,8,8,8) + iadd r15.xyzw, -r14.xyzw, l(1, 1, 1, 1) + movc r15.xyzw, r13.xyzw, r13.xyzw, r15.xyzw + bfi r10.xyzw, l(7, 7, 7, 7), r14.xyzw, r10.xyzw, l(0, 0, 0, 0) + and r10.xyzw, r10.xyzw, l(127, 127, 127, 127) + movc r10.xyzw, r13.xyzw, r12.xyzw, r10.xyzw + ishl r12.xyzw, r15.xyzw, l(23, 23, 23, 23) + iadd r12.xyzw, r12.xyzw, l(0x3e000000, 0x3e000000, 0x3e000000, 0x3e000000) + ishl r10.xyzw, r10.xyzw, l(16, 16, 16, 16) + iadd r10.xyzw, r12.xyzw, r10.xyzw + movc r8.xyzw, r11.xyzw, r10.xyzw, l(0,0,0,0) + ushr r10.xyzw, r9.xyzw, r0.yyyy + and r11.xyzw, r10.xyzw, l(1023, 1023, 1023, 1023) + and r12.xyzw, r10.xyzw, l(127, 127, 127, 127) + ubfe r13.xyzw, l(3, 3, 3, 3), l(7, 7, 7, 7), r10.xyzw + firstbit_hi r14.xyzw, r12.xyzw + iadd r14.xyzw, r14.xyzw, l(-24, -24, -24, -24) + movc r14.xyzw, r12.xyzw, r14.xyzw, l(8,8,8,8) + iadd r15.xyzw, -r14.xyzw, l(1, 1, 1, 1) + movc r15.xyzw, r13.xyzw, r13.xyzw, r15.xyzw + bfi r10.xyzw, l(7, 7, 7, 7), r14.xyzw, r10.xyzw, l(0, 0, 0, 0) + and r10.xyzw, r10.xyzw, l(127, 127, 127, 127) + movc r10.xyzw, r13.xyzw, r12.xyzw, r10.xyzw + ishl r12.xyzw, r15.xyzw, l(23, 23, 23, 23) + iadd r12.xyzw, r12.xyzw, l(0x3e000000, 0x3e000000, 0x3e000000, 0x3e000000) + ishl r10.xyzw, r10.xyzw, l(16, 16, 16, 16) + iadd r10.xyzw, r12.xyzw, r10.xyzw + movc r9.xyzw, r11.xyzw, r10.xyzw, l(0,0,0,0) + break + case l(4) + ibfe r10.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r8.xyzw + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ibfe r10.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r9.xyzw + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(6) + f16tof32 r8.xyzw, r8.xyzw + f16tof32 r9.xyzw, r9.xyzw + break + default + break + endswitch + endif + add r8.xyzw, r6.xyzw, r8.xyzw + add r9.xyzw, r3.xyzw, r9.xyzw + iadd r0.y, r1.z, r7.y + if_nz r2.y + ishl r1.z, r0.y, l(2) + ld_raw r10.xyzw, r1.z, T0[0].xyzw + iadd r1.z, r1.z, l(16) + ld_raw r11.xyzw, r1.z, T0[0].xyzw + else + ishl r1.z, r0.y, l(2) + ld_raw r10.x, r1.z, T0[0].xxxx + iadd r1.z, r2.x, r0.y + ishl r1.z, r1.z, l(2) + ld_raw r10.y, r1.z, T0[0].xxxx + ishl r12.xyzw, l(2, 3, 4, 5), r1.wwww + iadd r12.xyzw, r0.yyyy, r12.xyzw + ishl r12.xyzw, r12.xyzw, l(2, 2, 2, 2) + ld_raw r10.z, r12.x, T0[0].xxxx + ld_raw r10.w, r12.y, T0[0].xxxx + ld_raw r11.x, r12.z, T0[0].xxxx + ld_raw r11.y, r12.w, T0[0].xxxx + ishl r1.zw, l(0, 0, 6, 7), r1.wwww + iadd r1.zw, r0.yyyy, r1.zzzw + ishl r1.zw, r1.zzzw, l(0, 0, 2, 2) + ld_raw r11.z, r1.z, T0[0].xxxx + ld_raw r11.w, r1.w, T0[0].xxxx + endif + if_nz r2.w + switch r2.z + case l(5) + ibfe r12.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r10.xyzw + itof r12.xyzw, r12.xyzw + mul r12.xyzw, r12.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r10.xyzw, r12.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ibfe r12.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r11.xyzw + itof r12.xyzw, r12.xyzw + mul r12.xyzw, r12.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r11.xyzw, r12.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + f16tof32 r10.xyzw, r10.xyzw + f16tof32 r11.xyzw, r11.xyzw + break + default + break + endswitch + else + switch r2.z + case l(0) + case l(1) + movc r0.y, r0.w, l(16), l(0) + ushr r2.xyzw, r10.xyzw, r0.yyyy + and r2.xyzw, r2.xyzw, l(255, 255, 255, 255) + utof r2.xyzw, r2.xyzw + mul r10.xyzw, r2.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r2.xyzw, r11.xyzw, r0.yyyy + and r2.xyzw, r2.xyzw, l(255, 255, 255, 255) + utof r2.xyzw, r2.xyzw + mul r11.xyzw, r2.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + movc r0.y, r0.w, l(20), l(0) + ushr r2.xyzw, r10.xyzw, r0.yyyy + and r2.xyzw, r2.xyzw, l(1023, 1023, 1023, 1023) + utof r2.xyzw, r2.xyzw + mul r10.xyzw, r2.xyzw, l(0.000978, 0.000978, 0.000978, 0.000978) + ushr r2.xyzw, r11.xyzw, r0.yyyy + and r2.xyzw, r2.xyzw, l(1023, 1023, 1023, 1023) + utof r2.xyzw, r2.xyzw + mul r11.xyzw, r2.xyzw, l(0.000978, 0.000978, 0.000978, 0.000978) + break + case l(3) + case l(12) + movc r0.y, r0.w, l(20), l(0) + ushr r2.xyzw, r10.xyzw, r0.yyyy + and r12.xyzw, r2.xyzw, l(1023, 1023, 1023, 1023) + and r13.xyzw, r2.xyzw, l(127, 127, 127, 127) + ubfe r14.xyzw, l(3, 3, 3, 3), l(7, 7, 7, 7), r2.xyzw + firstbit_hi r15.xyzw, r13.xyzw + iadd r15.xyzw, r15.xyzw, l(-24, -24, -24, -24) + movc r15.xyzw, r13.xyzw, r15.xyzw, l(8,8,8,8) + iadd r16.xyzw, -r15.xyzw, l(1, 1, 1, 1) + movc r16.xyzw, r14.xyzw, r14.xyzw, r16.xyzw + bfi r2.xyzw, l(7, 7, 7, 7), r15.xyzw, r2.xyzw, l(0, 0, 0, 0) + and r2.xyzw, r2.xyzw, l(127, 127, 127, 127) + movc r2.xyzw, r14.xyzw, r13.xyzw, r2.xyzw + ishl r13.xyzw, r16.xyzw, l(23, 23, 23, 23) + iadd r13.xyzw, r13.xyzw, l(0x3e000000, 0x3e000000, 0x3e000000, 0x3e000000) + ishl r2.xyzw, r2.xyzw, l(16, 16, 16, 16) + iadd r2.xyzw, r13.xyzw, r2.xyzw + movc r10.xyzw, r12.xyzw, r2.xyzw, l(0,0,0,0) + ushr r2.xyzw, r11.xyzw, r0.yyyy + and r12.xyzw, r2.xyzw, l(1023, 1023, 1023, 1023) + and r13.xyzw, r2.xyzw, l(127, 127, 127, 127) + ubfe r14.xyzw, l(3, 3, 3, 3), l(7, 7, 7, 7), r2.xyzw + firstbit_hi r15.xyzw, r13.xyzw + iadd r15.xyzw, r15.xyzw, l(-24, -24, -24, -24) + movc r15.xyzw, r13.xyzw, r15.xyzw, l(8,8,8,8) + iadd r16.xyzw, -r15.xyzw, l(1, 1, 1, 1) + movc r16.xyzw, r14.xyzw, r14.xyzw, r16.xyzw + bfi r2.xyzw, l(7, 7, 7, 7), r15.xyzw, r2.xyzw, l(0, 0, 0, 0) + and r2.xyzw, r2.xyzw, l(127, 127, 127, 127) + movc r2.xyzw, r14.xyzw, r13.xyzw, r2.xyzw + ishl r13.xyzw, r16.xyzw, l(23, 23, 23, 23) + iadd r13.xyzw, r13.xyzw, l(0x3e000000, 0x3e000000, 0x3e000000, 0x3e000000) + ishl r2.xyzw, r2.xyzw, l(16, 16, 16, 16) + iadd r2.xyzw, r13.xyzw, r2.xyzw + movc r11.xyzw, r12.xyzw, r2.xyzw, l(0,0,0,0) + break + case l(4) + ibfe r2.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r10.xyzw + itof r2.xyzw, r2.xyzw + mul r2.xyzw, r2.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r10.xyzw, r2.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ibfe r2.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r11.xyzw + itof r2.xyzw, r2.xyzw + mul r2.xyzw, r2.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r11.xyzw, r2.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(6) + f16tof32 r10.xyzw, r10.xyzw + f16tof32 r11.xyzw, r11.xyzw + break + default + break + endswitch + endif + add r6.xyzw, r8.xyzw, r10.xyzw + add r3.xyzw, r9.xyzw, r11.xyzw + else + mov r0.x, r7.x + endif +endif +mul_sat r2.xyzw, r0.xxxx, r6.xyzw +mul_sat r3.xyzw, r0.xxxx, r3.xyzw +iadd r4.xyzw, r4.xyzw, r5.xyzw +if_nz r0.z + ubfe r0.x, l(3), l(4), CB0[0][0].z + ishl r0.y, r1.y, l(5) + ishr r5.xyzw, r4.zwzw, l(4, 5, 3, 3) + ishr r0.z, r0.x, l(2) + ushr r0.y, r0.y, l(4) + and r0.y, r0.y, l(2046) + imad r0.y, r0.z, r0.y, r5.x + ushr r0.w, r1.x, l(5) + imad r0.y, r0.y, r0.w, r5.y + ishl r0.w, r4.z, l(8) + ishr r0.w, r0.w, l(6) + iadd r0.z, r0.z, r5.z + bfi r1.y, l(1), l(1), r0.z, l(0) + iadd r1.y, r1.y, r5.w + bfi r1.y, l(2), l(1), r1.y, l(0) + bfi r0.z, l(1), l(0), r0.z, r1.y + and r1.yz, r0.wwww, l(0, 16, 8, 0) + bfi r0.yw, l(0, 22, 0, 22), l(0, 8, 0, 11), r0.yyyy, l(0, 0, 0, 0) + imad r0.yw, r1.yyyy, l(0, 2, 0, 16), r0.yyyw + bfi r0.yw, l(0, 5, 0, 5), l(0, 0, 0, 3), r1.zzzz, r0.yyyw + bfi r0.xy, l(2, 2, 0, 0), l(6, 9, 0, 0), r0.xxxx, r0.ywyy + ubfe r0.w, l(3), l(6), r0.x + and r1.y, r0.z, l(6) + bfi r0.z, l(1), l(8), r0.z, l(0) + imad r0.z, r0.w, l(32), r0.z + imad r0.z, r1.y, l(4), r0.z + bfi r0.xy, l(1, 1, 0, 0), l(4, 7, 0, 0), r4.zzzz, r0.xyxx + bfi r0.y, l(9), l(3), r0.z, r0.y + bfi r0.x, l(6), l(0), r0.x, r0.y +else + ishr r5.xyzw, r4.xyzw, l(5, 5, 2, 3) + ushr r0.y, r1.x, l(5) + imad r0.y, r5.y, r0.y, r5.x + ishl r0.zw, r4.zzzz, l(0, 0, 2, 7) + ishl r1.x, r0.z, l(1) + and r1.x, r1.x, l(96) + bfi r1.y, l(25), l(7), r0.y, r1.x + and r0.zw, r0.zzzw, l(0, 0, 8, 2048) + iadd r1.y, r1.y, r0.z + bfi r1.y, l(1), l(4), r4.z, r1.y + ishl r1.xz, r1.xxxx, l(3, 0, 2, 0) + bfi r1.xz, l(25, 0, 25, 0), l(10, 0, 9, 0), r0.yyyy, r1.xxzx + imad r0.yz, r0.zzzz, l(0, 8, 4, 0), r1.xxzx + bfi r0.yz, l(0, 1, 1, 0), l(0, 7, 6, 0), r4.zzzz, r0.yyzy + bfi r0.y, l(12), l(0), r0.w, r0.y + and r0.z, r0.z, l(1792) + iadd r0.y, r0.y, r0.z + and r0.z, r5.z, l(2) + iadd r0.z, r5.w, r0.z + bfi r0.z, l(2), l(6), r0.z, l(0) + iadd r0.y, r0.y, r0.z + bfi r0.x, l(6), l(0), r1.y, r0.y +endif +iadd r0.x, r0.x, CB0[0][1].x +ushr r0.x, r0.x, l(3) +mad r1.xyzw, r2.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000), l(0.500000, 0.500000, 0.500000, 0.500000) +ftou r1.xyzw, r1.xyzw +imad r0.y, r1.y, l(256), r1.x +imad r0.y, r1.z, l(0x00010000), r0.y +imad r1.xzw, r1.wwww, l(0x01000000, 0, 0x01000000, 0x01000000), r0.yyyy +mad r2.xyzw, r3.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000), l(0.500000, 0.500000, 0.500000, 0.500000) +ftou r2.xyzw, r2.xyzw +imad r0.y, r2.y, l(256), r2.x +imad r0.y, r2.z, l(0x00010000), r0.y +imad r1.y, r2.w, l(0x01000000), r0.y +store_uav_typed U0[0].xyzw, r0.xxxx, r1.xyzw +ret +// Approximately 644 instruction slots used +#endif + +const BYTE resolve_full_8bpp_cs[] = { + 68, 88, 66, 67, 193, 146, 105, 71, 141, 57, 58, 139, 145, 238, 96, 196, 146, 227, 48, + 15, 1, 0, 0, 0, 4, 79, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 208, 2, + 0, 0, 224, 2, 0, 0, 240, 2, 0, 0, 104, 78, 0, 0, 82, 68, 69, 70, 148, + 2, 0, 0, 1, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 105, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 101, 100, 114, 97, 109, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 213, 0, 0, 0, 5, 0, 0, 0, 252, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 196, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 4, 2, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 31, 2, 0, 0, 8, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 52, 2, 0, 0, 12, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 84, 2, 0, + 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 224, 1, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, + 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 101, 100, 114, 97, 109, 95, 105, 110, 102, + 111, 0, 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 218, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 99, 111, + 111, 114, 100, 105, 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 105, 110, 102, 111, 0, 120, 101, 95, + 114, 101, 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 99, 111, 111, 114, 100, 105, + 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 95, 98, 97, 115, 101, 0, 77, 105, 99, 114, 111, 115, 111, + 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, + 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, + 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 112, 75, 0, 0, + 81, 0, 5, 0, 220, 18, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 161, 0, 0, 6, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 95, 0, 0, + 2, 50, 0, 2, 0, 104, 0, 0, 2, 17, 0, 0, 0, 155, 0, 0, 4, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 138, 0, 0, 11, 18, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, + 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 12, 226, 0, 16, 0, 0, 0, 0, 0, 6, 138, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 1, 85, 0, 0, 12, 242, 0, 16, 0, 1, 0, 0, 0, + 214, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 4, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 80, 0, + 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 2, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 24, 0, 0, 0, 28, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, + 18, 0, 16, 0, 3, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, 0, 11, 18, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, + 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 23, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 140, 0, 0, 13, + 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 64, 0, + 0, 5, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 230, 11, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 11, 66, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 28, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 41, 0, 0, 9, 146, 0, 16, 0, 5, 0, 0, 0, 6, 0, 2, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 54, + 0, 0, 4, 98, 0, 16, 0, 5, 0, 0, 0, 86, 5, 2, 0, 30, 0, 0, 7, + 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 182, 15, 16, + 0, 5, 0, 0, 0, 80, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, + 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, + 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, + 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 18, 0, 0, 1, + 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 21, 0, 0, 1, 21, 0, 0, 1, 80, 0, 0, 10, 194, 0, 16, 0, 3, 0, + 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, + 3, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 50, 0, + 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 3, + 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, + 0, 6, 0, 0, 0, 70, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, + 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, + 6, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, + 0, 80, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 34, 0, + 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 78, 0, 0, 8, 194, + 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, + 6, 4, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 10, + 50, 0, 16, 0, 2, 0, 0, 0, 230, 10, 16, 128, 65, 0, 0, 0, 6, 0, 0, + 0, 70, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 35, 0, + 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, + 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 2, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 5, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 78, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 40, 0, 30, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, + 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, + 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 21, 0, + 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, + 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, + 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 165, 0, 0, + 8, 242, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 70, 126, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 18, + 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, + 0, 7, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, + 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, + 8, 34, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 6, 112, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, + 5, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 7, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 7, 0, + 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, + 0, 7, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, + 0, 8, 130, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 6, + 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, + 3, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 3, 0, 0, 0, 58, 0, + 16, 0, 7, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, + 0, 0, 10, 50, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, + 0, 30, 0, 0, 7, 50, 0, 16, 0, 7, 0, 0, 0, 86, 5, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 7, + 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, + 0, 3, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 6, 112, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 3, 0, 0, 0, 26, + 0, 16, 0, 7, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 2, 0, 0, 0, 76, 0, 0, + 3, 42, 0, 16, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, + 0, 0, 139, 0, 0, 15, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, + 16, 0, 7, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, + 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, + 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 139, 0, 0, 15, 242, 0, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 43, 0, 0, 5, 242, 0, + 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, + 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, + 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 131, 0, 0, 5, + 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 131, 0, 0, + 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 0, + 0, 1, 10, 0, 0, 1, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, 76, + 0, 0, 3, 42, 0, 16, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, + 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, + 9, 18, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 16, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 242, + 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, + 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 8, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 7, 242, 0, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 86, 0, 0, 5, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, + 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 55, 0, 0, 9, 18, 0, + 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 20, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, + 8, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, + 8, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, + 128, 58, 8, 32, 128, 58, 85, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, + 58, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, + 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 55, 0, 0, 9, 18, 0, 16, 0, 7, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, 14, 16, + 0, 8, 0, 0, 0, 135, 0, 0, 5, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, + 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, + 232, 255, 255, 255, 232, 255, 255, 255, 55, 0, 0, 12, 242, 0, 16, 0, 12, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 30, + 0, 0, 11, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, + 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, 14, 16, + 0, 12, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 55, 0, 0, + 9, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 41, 0, 0, 10, 242, + 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, + 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 41, + 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 6, + 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 85, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, + 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 9, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 138, 0, 0, 15, 242, + 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 135, 0, + 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 30, + 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, + 255, 55, 0, 0, 12, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 9, 0, + 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, 11, 242, 0, 16, 0, + 12, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 55, 0, + 0, 9, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 140, 0, 0, 17, + 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, + 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, + 14, 16, 0, 7, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, + 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, + 0, 23, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 9, 0, + 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, + 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 41, 0, 0, 10, 242, 0, 16, 0, + 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 30, 0, 0, 7, 242, 0, + 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 7, + 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, + 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 139, 0, 0, 15, 242, 0, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 43, 0, 0, 5, 242, 0, + 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, + 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 139, + 0, 0, 15, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, + 6, 0, 0, 0, 131, 0, 0, 5, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 131, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 2, 0, 0, 1, 23, + 0, 0, 1, 21, 0, 0, 1, 80, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 7, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 7, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 30, + 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 80, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, + 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 7, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 8, + 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, + 0, 7, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 165, 0, 0, 8, 242, 0, + 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 66, 0, 16, 0, + 7, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 165, 0, 0, 8, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 7, 0, + 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, + 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, + 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, + 0, 7, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 34, 0, + 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 6, 112, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, + 0, 246, 15, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 10, 0, + 0, 0, 86, 5, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 165, 0, 0, 8, 66, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 10, 0, + 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, + 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 9, 0, 0, + 0, 42, 0, 16, 0, 10, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 10, + 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, + 194, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 7, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 30, 0, + 0, 7, 194, 0, 16, 0, 7, 0, 0, 0, 166, 14, 16, 0, 7, 0, 0, 0, 86, + 5, 16, 0, 7, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 7, 0, 0, 0, + 166, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, 9, 0, + 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, + 7, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, + 1, 31, 0, 4, 3, 58, 0, 16, 0, 2, 0, 0, 0, 76, 0, 0, 3, 42, 0, + 16, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, 139, + 0, 0, 15, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 8, 0, + 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 128, 191, 139, 0, 0, 15, 242, 0, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, + 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 131, 0, 0, 5, 242, 0, 16, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 242, 0, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 0, 0, 1, 10, + 0, 0, 1, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, 76, 0, 0, 3, + 42, 0, 16, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, + 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 66, 0, + 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 166, 10, 16, 0, 7, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, + 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, + 128, 59, 129, 128, 128, 59, 85, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 9, 0, 0, 0, 166, 10, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, + 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 7, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 8, 0, 0, 0, 166, 10, 16, 0, 7, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 8, + 32, 128, 58, 85, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 9, 0, 0, 0, 166, 10, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 86, 0, 0, 5, 242, + 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 2, 0, + 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, 1, + 64, 0, 0, 12, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 7, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 8, 0, 0, 0, 166, 10, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 138, + 0, 0, 15, 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 135, 0, 0, 5, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, + 14, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, + 255, 232, 255, 255, 255, 55, 0, 0, 12, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, + 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, 11, + 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 14, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, + 140, 0, 0, 17, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, 14, 16, 0, 14, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 55, 0, 0, 9, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, + 12, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, + 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 10, 242, 0, + 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 41, 0, 0, 10, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 30, 0, + 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 8, 0, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 166, + 10, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 12, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 135, 0, 0, 5, 242, + 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 30, 0, 0, 10, + 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 2, 64, 0, + 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 55, 0, + 0, 12, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, + 14, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, 11, 242, 0, 16, 0, 15, 0, 0, + 0, 70, 14, 16, 128, 65, 0, 0, 0, 14, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 242, + 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, + 0, 15, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, + 0, 0, 23, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, + 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, + 0, 0, 0, 62, 0, 0, 0, 62, 41, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 55, 0, 0, 12, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, + 64, 0, 0, 4, 0, 0, 0, 139, 0, 0, 15, 242, 0, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, + 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 139, 0, 0, 15, + 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 43, + 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, + 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, + 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, + 0, 131, 0, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, + 0, 0, 131, 0, 0, 5, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, + 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 2, 0, 0, 1, 23, 0, 0, 1, + 21, 0, 0, 1, 0, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 0, 0, 0, 7, 242, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 9, + 0, 0, 0, 80, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, + 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 56, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 128, 62, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, + 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, + 242, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 70, 126, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 7, 0, + 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 165, + 0, 0, 8, 242, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, + 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, + 7, 66, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 8, 0, 0, 0, 42, + 0, 16, 0, 7, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, + 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 34, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, + 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, + 0, 0, 5, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 242, + 0, 16, 0, 10, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, 8, 0, 0, 0, 10, + 0, 16, 0, 10, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 165, 0, 0, 8, 130, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, + 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 18, 0, + 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 6, 112, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 9, 0, 0, 0, + 58, 0, 16, 0, 10, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 41, 0, 0, 10, 194, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 246, 15, 16, 0, 1, + 0, 0, 0, 30, 0, 0, 7, 194, 0, 16, 0, 7, 0, 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 166, 14, 16, 0, 7, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, + 0, 7, 0, 0, 0, 166, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, + 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 9, 0, 0, + 0, 58, 0, 16, 0, 7, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 2, 0, 0, 0, 76, + 0, 0, 3, 42, 0, 16, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, + 5, 0, 0, 0, 139, 0, 0, 15, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 8, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, + 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 8, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 139, 0, 0, 15, 242, 0, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 43, 0, 0, 5, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, + 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 131, 0, + 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 131, + 0, 0, 5, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, + 2, 0, 0, 1, 10, 0, 0, 1, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, + 1, 76, 0, 0, 3, 42, 0, 16, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, + 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 55, + 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 16, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 85, 0, 0, + 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 86, 5, + 16, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, + 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 7, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, + 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, + 128, 59, 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, + 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 55, 0, 0, 9, + 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 20, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 86, 5, 16, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, + 8, 32, 128, 58, 8, 32, 128, 58, 85, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 9, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 8, + 32, 128, 58, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, + 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 20, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 135, 0, 0, 5, 242, 0, 16, 0, 14, 0, 0, 0, + 70, 14, 16, 0, 12, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, + 0, 70, 14, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, + 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 55, 0, 0, 12, 242, 0, 16, 0, 14, + 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 30, 0, 0, 11, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 128, 65, 0, + 0, 0, 14, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 15, 0, 0, 0, + 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, + 0, 15, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, + 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 55, + 0, 0, 9, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, + 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 41, 0, 0, + 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 30, + 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 62, 41, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 12, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 9, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 138, 0, 0, + 15, 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 135, 0, 0, 5, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, + 0, 30, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 14, 0, + 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 232, + 255, 255, 255, 55, 0, 0, 12, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, + 12, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, 11, 242, 0, + 16, 0, 15, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 14, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 55, 0, 0, 9, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 12, 0, + 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, + 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 41, 0, 0, 10, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 30, 0, 0, 7, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, + 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, + 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 139, 0, 0, 15, 242, 0, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 43, 0, 0, 5, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, + 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 139, 0, 0, 15, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 9, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, + 0, 0, 6, 0, 0, 0, 131, 0, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 242, 0, 16, 0, 9, 0, 0, 0, + 70, 14, 16, 0, 9, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 2, 0, 0, + 1, 23, 0, 0, 1, 21, 0, 0, 1, 0, 0, 0, 7, 242, 0, 16, 0, 8, 0, + 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 0, + 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 31, 0, + 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 165, 0, 0, 8, 242, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 16, + 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, + 1, 41, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 10, + 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, + 10, 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, + 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 30, + 0, 0, 7, 242, 0, 16, 0, 12, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 12, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, + 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, 10, + 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, + 0, 12, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, + 0, 8, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 6, + 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, + 11, 0, 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 246, + 15, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 194, 0, 16, 0, 1, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 41, 0, 0, + 10, 194, 0, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 66, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, 0, 16, + 0, 11, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 6, 112, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 2, + 0, 0, 0, 76, 0, 0, 3, 42, 0, 16, 0, 2, 0, 0, 0, 6, 0, 0, 3, + 1, 64, 0, 0, 5, 0, 0, 0, 139, 0, 0, 15, 242, 0, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, + 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 1, + 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, + 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 139, 0, 0, + 15, 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 43, 0, 0, 5, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, + 0, 0, 131, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 131, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 2, 0, 0, 1, 23, 0, 0, + 1, 18, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 2, 0, 0, 0, 6, 0, + 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, + 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 85, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 129, + 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 7, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 86, 5, 16, + 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, + 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, + 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, + 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, + 55, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 20, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 85, 0, + 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 86, + 5, 16, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, + 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 85, 0, 0, 7, 242, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 86, 5, 16, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, + 32, 128, 58, 8, 32, 128, 58, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, + 3, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 55, 0, 0, + 9, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 20, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 242, + 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 14, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 135, 0, 0, 5, 242, 0, 16, 0, + 15, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, + 0, 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 232, 255, + 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 55, 0, 0, 12, 242, + 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 30, 0, 0, 11, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, + 16, 128, 65, 0, 0, 0, 15, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, + 16, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, + 0, 70, 14, 16, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 14, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 16, 0, + 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, + 62, 0, 0, 0, 62, 41, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 55, 0, 0, + 12, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 138, 0, 0, 15, 242, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 135, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, + 0, 13, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, + 255, 255, 255, 232, 255, 255, 255, 55, 0, 0, 12, 242, 0, 16, 0, 15, 0, 0, 0, + 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 30, 0, + 0, 11, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, + 0, 14, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 16, 0, + 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 55, 0, 0, 9, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, + 0, 13, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 10, + 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 41, 0, + 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 139, 0, 0, + 15, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 43, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 139, 0, 0, 15, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, + 11, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, + 0, 3, 1, 64, 0, 0, 6, 0, 0, 0, 131, 0, 0, 5, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 131, 0, 0, 5, 242, 0, 16, 0, + 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, + 1, 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, 0, 0, 0, 7, 242, 0, + 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, + 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 21, 0, + 0, 1, 21, 0, 0, 1, 56, 32, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 6, + 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 56, 32, 0, 7, + 242, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 42, + 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 230, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 254, 7, 0, 0, 35, 0, 0, 9, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, + 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 41, + 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, + 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, + 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 5, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 5, + 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 10, + 98, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 140, 0, + 0, 20, 162, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 22, + 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 35, 0, 0, 12, 162, 0, 16, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 86, 13, 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 162, 0, 16, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, + 0, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 86, 13, 16, 0, + 0, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + 0, 16, 0, 0, 0, 0, 0, 214, 5, 16, 0, 0, 0, 0, 0, 138, 0, 0, 9, + 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 34, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 166, 10, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 42, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 5, + 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, + 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, + 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 166, 10, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 7, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 96, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 25, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, + 0, 0, 0, 166, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 8, 0, 0, 0, 0, 8, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, + 0, 6, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 82, 0, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 6, 2, 16, 0, 1, 0, + 0, 0, 35, 0, 0, 12, 98, 0, 16, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 4, 0, 0, 0, 86, 6, 16, 0, + 0, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, + 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, + 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, + 0, 0, 127, 67, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, + 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, + 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 1, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 35, 0, 0, 12, 210, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 1, 86, 5, 16, 0, 0, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 2, 64, 0, 0, 0, + 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 35, 0, 0, + 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 0, 1, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 1, 0, 26, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 1, 26, 0, 16, 0, 0, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 132, 2, 0, + 0, 17, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 0, 143, 0, + 0, 0, 88, 0, 0, 0, 50, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, + 0, 44, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_8bpp_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_8bpp_scaled_cs.h new file mode 100644 index 0000000..08e86b8 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/resolve_full_8bpp_scaled_cs.h @@ -0,0 +1,1832 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_resolve_edram_info; // Offset: 0 Size: 4 +// uint xe_resolve_coordinate_info; // Offset: 4 Size: 4 +// uint xe_resolve_dest_info; // Offset: 8 Size: 4 +// uint xe_resolve_dest_coordinate_info;// Offset: 12 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_resolve_edram texture byte r/o T0 t0 1 +// xe_resolve_dest UAV uint2 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_raw T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xy +dcl_temps 17 +dcl_thread_group 8, 8, 1 +and r0.xyzw, CB0[0][0].xxzz, l(1023, 0x20000000, 8, 0x01000000) +if_nz r0.y + ubfe r1.xy, l(2, 2, 0, 0), l(17, 20, 0, 0), CB0[0][0].yyyy +else + mov r1.xy, l(0,0,0,0) +endif +ubfe r2.xyz, l(3, 3, 11, 0), l(16, 19, 5, 0), CB0[0][0].yyyy +imul null, r0.y, r2.x, r2.z +ushr r3.xyzw, CB0[0][0].ywww, l(4, 10, 20, 24) +uge r0.y, vThreadID.x, r0.y +if_nz r0.y + ret +endif +ubfe r4.xyzw, l(2, 11, 4, 1), l(10, 13, 24, 28), CB0[0][0].xxxx +mov r5.x, CB0[0][0].y +mov r5.y, r3.x +bfi r1.zw, l(0, 0, 4, 1), l(0, 0, 3, 3), r5.xxxy, l(0, 0, 0, 0) +ibfe r0.y, l(6), l(16), CB0[0][0].z +ishl r0.y, r0.y, l(23) +iadd r0.y, r0.y, l(0x3f800000) +bfi r2.z, l(10), l(5), CB0[0][0].w, l(0) +bfi r3.xz, l(4, 0, 4, 0), l(3, 0, 3, 0), r3.zzwz, l(0, 0, 0, 0) +ubfe r2.w, l(3), l(28), CB0[0][0].w +ishl r5.x, vThreadID.x, l(3) +umax r5.y, r1.y, vThreadID.y +imad r1.yz, r1.zzwz, r2.xxyx, r5.xxyx +uge r1.w, l(3), r2.w +if_nz r1.w + mov r6.y, r2.w +else + ieq r1.w, r2.w, l(5) + if_nz r1.w + mov r6.y, l(2) + else + mov r6.y, l(0) + endif +endif +uge r5.yw, r4.xxxx, l(0, 2, 0, 1) +and r5.yw, r5.yyyw, l(0, 1, 0, 1) +ishl r1.yz, r1.yyzy, r5.yywy +ushr r6.x, r6.y, l(1) +and r6.xy, r6.xyxx, l(1, 1, 0, 0) +iadd r1.yz, r1.yyzy, r6.xxyx +imul null, r6.yz, r2.xxyx, l(0, 80, 16, 0) +ushr r6.x, r6.y, r4.w +udiv r7.xy, null, r1.yzyy, r6.xzxx +imad r0.x, r7.y, r0.x, r7.x +iadd r0.x, r0.x, r4.y +imad r1.yz, -r7.xxyx, r6.xxzx, r1.yyzy +imul null, r1.w, r6.z, r6.y +imad r1.y, r1.z, r6.x, r1.y +ishl r1.y, r1.y, r4.w +imad r0.x, r0.x, r1.w, r1.y +ishl r1.y, r1.w, l(11) +udiv null, r0.x, r0.x, r1.y +iadd r1.y, r4.w, r5.y +ishl r1.z, l(1), r1.y +if_nz r0.w + iadd r0.x, r4.w, r0.x +endif +ieq r1.w, r1.z, l(1) +if_nz r1.w + ishl r3.w, r0.x, l(2) + ld_raw r6.xyzw, r3.w, T0[0].xyzw + iadd r3.w, r3.w, l(16) + ld_raw r7.xyzw, r3.w, T0[0].xyzw +else + ishl r3.w, r0.x, l(2) + ld_raw r6.x, r3.w, T0[0].xxxx + iadd r3.w, r1.z, r0.x + ishl r3.w, r3.w, l(2) + ld_raw r6.y, r3.w, T0[0].xxxx + ishl r8.xyzw, l(2, 3, 4, 5), r1.yyyy + iadd r8.xyzw, r0.xxxx, r8.xyzw + ishl r8.xyzw, r8.xyzw, l(2, 2, 2, 2) + ld_raw r6.z, r8.x, T0[0].xxxx + ld_raw r6.w, r8.y, T0[0].xxxx + ld_raw r7.x, r8.z, T0[0].xxxx + ld_raw r7.y, r8.w, T0[0].xxxx + ishl r4.xy, l(6, 7, 0, 0), r1.yyyy + iadd r4.xy, r0.xxxx, r4.xyxx + ishl r4.xy, r4.xyxx, l(2, 2, 0, 0) + ld_raw r7.z, r4.x, T0[0].xxxx + ld_raw r7.w, r4.y, T0[0].xxxx +endif +if_nz r4.w + switch r4.z + case l(5) + ibfe r8.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r6.xyzw + itof r8.xyzw, r8.xyzw + mul r8.xyzw, r8.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r6.xyzw, r8.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ibfe r8.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r7.xyzw + itof r8.xyzw, r8.xyzw + mul r8.xyzw, r8.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r7.xyzw, r8.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + f16tof32 r6.xyzw, r6.xyzw + f16tof32 r7.xyzw, r7.xyzw + break + default + break + endswitch +else + switch r4.z + case l(0) + case l(1) + movc r3.w, r0.w, l(16), l(0) + ushr r8.xyzw, r6.xyzw, r3.wwww + and r8.xyzw, r8.xyzw, l(255, 255, 255, 255) + utof r8.xyzw, r8.xyzw + mul r6.xyzw, r8.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r8.xyzw, r7.xyzw, r3.wwww + and r8.xyzw, r8.xyzw, l(255, 255, 255, 255) + utof r8.xyzw, r8.xyzw + mul r7.xyzw, r8.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + movc r3.w, r0.w, l(20), l(0) + ushr r8.xyzw, r6.xyzw, r3.wwww + and r8.xyzw, r8.xyzw, l(1023, 1023, 1023, 1023) + utof r8.xyzw, r8.xyzw + mul r6.xyzw, r8.xyzw, l(0.000978, 0.000978, 0.000978, 0.000978) + ushr r8.xyzw, r7.xyzw, r3.wwww + and r8.xyzw, r8.xyzw, l(1023, 1023, 1023, 1023) + utof r8.xyzw, r8.xyzw + mul r7.xyzw, r8.xyzw, l(0.000978, 0.000978, 0.000978, 0.000978) + break + case l(3) + case l(12) + movc r3.w, r0.w, l(20), l(0) + ushr r8.xyzw, r6.xyzw, r3.wwww + and r9.xyzw, r8.xyzw, l(1023, 1023, 1023, 1023) + and r10.xyzw, r8.xyzw, l(127, 127, 127, 127) + ubfe r11.xyzw, l(3, 3, 3, 3), l(7, 7, 7, 7), r8.xyzw + firstbit_hi r12.xyzw, r10.xyzw + iadd r12.xyzw, r12.xyzw, l(-24, -24, -24, -24) + movc r12.xyzw, r10.xyzw, r12.xyzw, l(8,8,8,8) + iadd r13.xyzw, -r12.xyzw, l(1, 1, 1, 1) + movc r13.xyzw, r11.xyzw, r11.xyzw, r13.xyzw + bfi r8.xyzw, l(7, 7, 7, 7), r12.xyzw, r8.xyzw, l(0, 0, 0, 0) + and r8.xyzw, r8.xyzw, l(127, 127, 127, 127) + movc r8.xyzw, r11.xyzw, r10.xyzw, r8.xyzw + ishl r10.xyzw, r13.xyzw, l(23, 23, 23, 23) + iadd r10.xyzw, r10.xyzw, l(0x3e000000, 0x3e000000, 0x3e000000, 0x3e000000) + ishl r8.xyzw, r8.xyzw, l(16, 16, 16, 16) + iadd r8.xyzw, r10.xyzw, r8.xyzw + movc r6.xyzw, r9.xyzw, r8.xyzw, l(0,0,0,0) + ushr r8.xyzw, r7.xyzw, r3.wwww + and r9.xyzw, r8.xyzw, l(1023, 1023, 1023, 1023) + and r10.xyzw, r8.xyzw, l(127, 127, 127, 127) + ubfe r11.xyzw, l(3, 3, 3, 3), l(7, 7, 7, 7), r8.xyzw + firstbit_hi r12.xyzw, r10.xyzw + iadd r12.xyzw, r12.xyzw, l(-24, -24, -24, -24) + movc r12.xyzw, r10.xyzw, r12.xyzw, l(8,8,8,8) + iadd r13.xyzw, -r12.xyzw, l(1, 1, 1, 1) + movc r13.xyzw, r11.xyzw, r11.xyzw, r13.xyzw + bfi r8.xyzw, l(7, 7, 7, 7), r12.xyzw, r8.xyzw, l(0, 0, 0, 0) + and r8.xyzw, r8.xyzw, l(127, 127, 127, 127) + movc r8.xyzw, r11.xyzw, r10.xyzw, r8.xyzw + ishl r10.xyzw, r13.xyzw, l(23, 23, 23, 23) + iadd r10.xyzw, r10.xyzw, l(0x3e000000, 0x3e000000, 0x3e000000, 0x3e000000) + ishl r8.xyzw, r8.xyzw, l(16, 16, 16, 16) + iadd r8.xyzw, r10.xyzw, r8.xyzw + movc r7.xyzw, r9.xyzw, r8.xyzw, l(0,0,0,0) + break + case l(4) + ibfe r8.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r6.xyzw + itof r8.xyzw, r8.xyzw + mul r8.xyzw, r8.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r6.xyzw, r8.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ibfe r8.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r7.xyzw + itof r8.xyzw, r8.xyzw + mul r8.xyzw, r8.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r7.xyzw, r8.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(6) + f16tof32 r6.xyzw, r6.xyzw + f16tof32 r7.xyzw, r7.xyzw + break + default + break + endswitch +endif +uge r3.w, r2.w, l(4) +if_nz r3.w + mul r3.w, r0.y, l(0.500000) + imad r4.x, l(80), r2.x, r0.x + if_nz r1.w + ishl r4.y, r4.x, l(2) + ld_raw r8.xyzw, r4.y, T0[0].xyzw + iadd r4.y, r4.y, l(16) + ld_raw r9.xyzw, r4.y, T0[0].xyzw + else + ishl r4.y, r4.x, l(2) + ld_raw r8.x, r4.y, T0[0].xxxx + iadd r4.y, r1.z, r4.x + ishl r4.y, r4.y, l(2) + ld_raw r8.y, r4.y, T0[0].xxxx + ishl r10.xyzw, l(2, 3, 4, 5), r1.yyyy + iadd r10.xyzw, r4.xxxx, r10.xyzw + ishl r10.xyzw, r10.xyzw, l(2, 2, 2, 2) + ld_raw r8.z, r10.x, T0[0].xxxx + ld_raw r8.w, r10.y, T0[0].xxxx + ld_raw r9.x, r10.z, T0[0].xxxx + ld_raw r9.y, r10.w, T0[0].xxxx + ishl r5.yw, l(0, 6, 0, 7), r1.yyyy + iadd r5.yw, r4.xxxx, r5.yyyw + ishl r5.yw, r5.yyyw, l(0, 2, 0, 2) + ld_raw r9.z, r5.y, T0[0].xxxx + ld_raw r9.w, r5.w, T0[0].xxxx + endif + if_nz r4.w + switch r4.z + case l(5) + ibfe r10.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r8.xyzw + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ibfe r10.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r9.xyzw + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + f16tof32 r8.xyzw, r8.xyzw + f16tof32 r9.xyzw, r9.xyzw + break + default + break + endswitch + else + switch r4.z + case l(0) + case l(1) + movc r4.y, r0.w, l(16), l(0) + ushr r10.xyzw, r8.xyzw, r4.yyyy + and r10.xyzw, r10.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r10.xyzw, r9.xyzw, r4.yyyy + and r10.xyzw, r10.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + movc r4.y, r0.w, l(20), l(0) + ushr r10.xyzw, r8.xyzw, r4.yyyy + and r10.xyzw, r10.xyzw, l(1023, 1023, 1023, 1023) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.000978) + ushr r10.xyzw, r9.xyzw, r4.yyyy + and r10.xyzw, r10.xyzw, l(1023, 1023, 1023, 1023) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.000978) + break + case l(3) + case l(12) + movc r4.y, r0.w, l(20), l(0) + ushr r10.xyzw, r8.xyzw, r4.yyyy + and r11.xyzw, r10.xyzw, l(1023, 1023, 1023, 1023) + and r12.xyzw, r10.xyzw, l(127, 127, 127, 127) + ubfe r13.xyzw, l(3, 3, 3, 3), l(7, 7, 7, 7), r10.xyzw + firstbit_hi r14.xyzw, r12.xyzw + iadd r14.xyzw, r14.xyzw, l(-24, -24, -24, -24) + movc r14.xyzw, r12.xyzw, r14.xyzw, l(8,8,8,8) + iadd r15.xyzw, -r14.xyzw, l(1, 1, 1, 1) + movc r15.xyzw, r13.xyzw, r13.xyzw, r15.xyzw + bfi r10.xyzw, l(7, 7, 7, 7), r14.xyzw, r10.xyzw, l(0, 0, 0, 0) + and r10.xyzw, r10.xyzw, l(127, 127, 127, 127) + movc r10.xyzw, r13.xyzw, r12.xyzw, r10.xyzw + ishl r12.xyzw, r15.xyzw, l(23, 23, 23, 23) + iadd r12.xyzw, r12.xyzw, l(0x3e000000, 0x3e000000, 0x3e000000, 0x3e000000) + ishl r10.xyzw, r10.xyzw, l(16, 16, 16, 16) + iadd r10.xyzw, r12.xyzw, r10.xyzw + movc r8.xyzw, r11.xyzw, r10.xyzw, l(0,0,0,0) + ushr r10.xyzw, r9.xyzw, r4.yyyy + and r11.xyzw, r10.xyzw, l(1023, 1023, 1023, 1023) + and r12.xyzw, r10.xyzw, l(127, 127, 127, 127) + ubfe r13.xyzw, l(3, 3, 3, 3), l(7, 7, 7, 7), r10.xyzw + firstbit_hi r14.xyzw, r12.xyzw + iadd r14.xyzw, r14.xyzw, l(-24, -24, -24, -24) + movc r14.xyzw, r12.xyzw, r14.xyzw, l(8,8,8,8) + iadd r15.xyzw, -r14.xyzw, l(1, 1, 1, 1) + movc r15.xyzw, r13.xyzw, r13.xyzw, r15.xyzw + bfi r10.xyzw, l(7, 7, 7, 7), r14.xyzw, r10.xyzw, l(0, 0, 0, 0) + and r10.xyzw, r10.xyzw, l(127, 127, 127, 127) + movc r10.xyzw, r13.xyzw, r12.xyzw, r10.xyzw + ishl r12.xyzw, r15.xyzw, l(23, 23, 23, 23) + iadd r12.xyzw, r12.xyzw, l(0x3e000000, 0x3e000000, 0x3e000000, 0x3e000000) + ishl r10.xyzw, r10.xyzw, l(16, 16, 16, 16) + iadd r10.xyzw, r12.xyzw, r10.xyzw + movc r9.xyzw, r11.xyzw, r10.xyzw, l(0,0,0,0) + break + case l(4) + ibfe r10.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r8.xyzw + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ibfe r10.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r9.xyzw + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(6) + f16tof32 r8.xyzw, r8.xyzw + f16tof32 r9.xyzw, r9.xyzw + break + default + break + endswitch + endif + add r6.xyzw, r6.xyzw, r8.xyzw + add r7.xyzw, r7.xyzw, r9.xyzw + uge r2.w, r2.w, l(6) + if_nz r2.w + ishl r2.w, l(1), r4.w + mul r0.y, r0.y, l(0.250000) + iadd r0.x, r0.x, r2.w + if_nz r1.w + ishl r4.y, r0.x, l(2) + ld_raw r8.xyzw, r4.y, T0[0].xyzw + iadd r4.y, r4.y, l(16) + ld_raw r9.xyzw, r4.y, T0[0].xyzw + else + ishl r4.y, r0.x, l(2) + ld_raw r8.x, r4.y, T0[0].xxxx + iadd r4.y, r1.z, r0.x + ishl r4.y, r4.y, l(2) + ld_raw r8.y, r4.y, T0[0].xxxx + ishl r10.xyzw, l(2, 3, 4, 5), r1.yyyy + iadd r10.xyzw, r0.xxxx, r10.xyzw + ishl r10.xyzw, r10.xyzw, l(2, 2, 2, 2) + ld_raw r8.z, r10.x, T0[0].xxxx + ld_raw r8.w, r10.y, T0[0].xxxx + ld_raw r9.x, r10.z, T0[0].xxxx + ld_raw r9.y, r10.w, T0[0].xxxx + ishl r5.yw, l(0, 6, 0, 7), r1.yyyy + iadd r5.yw, r0.xxxx, r5.yyyw + ishl r5.yw, r5.yyyw, l(0, 2, 0, 2) + ld_raw r9.z, r5.y, T0[0].xxxx + ld_raw r9.w, r5.w, T0[0].xxxx + endif + if_nz r4.w + switch r4.z + case l(5) + ibfe r10.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r8.xyzw + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ibfe r10.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r9.xyzw + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + f16tof32 r8.xyzw, r8.xyzw + f16tof32 r9.xyzw, r9.xyzw + break + default + break + endswitch + else + switch r4.z + case l(0) + case l(1) + movc r0.x, r0.w, l(16), l(0) + ushr r10.xyzw, r8.xyzw, r0.xxxx + and r10.xyzw, r10.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r10.xyzw, r9.xyzw, r0.xxxx + and r10.xyzw, r10.xyzw, l(255, 255, 255, 255) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + movc r0.x, r0.w, l(20), l(0) + ushr r10.xyzw, r8.xyzw, r0.xxxx + and r10.xyzw, r10.xyzw, l(1023, 1023, 1023, 1023) + utof r10.xyzw, r10.xyzw + mul r8.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.000978) + ushr r10.xyzw, r9.xyzw, r0.xxxx + and r10.xyzw, r10.xyzw, l(1023, 1023, 1023, 1023) + utof r10.xyzw, r10.xyzw + mul r9.xyzw, r10.xyzw, l(0.000978, 0.000978, 0.000978, 0.000978) + break + case l(3) + case l(12) + movc r0.x, r0.w, l(20), l(0) + ushr r10.xyzw, r8.xyzw, r0.xxxx + and r11.xyzw, r10.xyzw, l(1023, 1023, 1023, 1023) + and r12.xyzw, r10.xyzw, l(127, 127, 127, 127) + ubfe r13.xyzw, l(3, 3, 3, 3), l(7, 7, 7, 7), r10.xyzw + firstbit_hi r14.xyzw, r12.xyzw + iadd r14.xyzw, r14.xyzw, l(-24, -24, -24, -24) + movc r14.xyzw, r12.xyzw, r14.xyzw, l(8,8,8,8) + iadd r15.xyzw, -r14.xyzw, l(1, 1, 1, 1) + movc r15.xyzw, r13.xyzw, r13.xyzw, r15.xyzw + bfi r10.xyzw, l(7, 7, 7, 7), r14.xyzw, r10.xyzw, l(0, 0, 0, 0) + and r10.xyzw, r10.xyzw, l(127, 127, 127, 127) + movc r10.xyzw, r13.xyzw, r12.xyzw, r10.xyzw + ishl r12.xyzw, r15.xyzw, l(23, 23, 23, 23) + iadd r12.xyzw, r12.xyzw, l(0x3e000000, 0x3e000000, 0x3e000000, 0x3e000000) + ishl r10.xyzw, r10.xyzw, l(16, 16, 16, 16) + iadd r10.xyzw, r12.xyzw, r10.xyzw + movc r8.xyzw, r11.xyzw, r10.xyzw, l(0,0,0,0) + ushr r10.xyzw, r9.xyzw, r0.xxxx + and r11.xyzw, r10.xyzw, l(1023, 1023, 1023, 1023) + and r12.xyzw, r10.xyzw, l(127, 127, 127, 127) + ubfe r13.xyzw, l(3, 3, 3, 3), l(7, 7, 7, 7), r10.xyzw + firstbit_hi r14.xyzw, r12.xyzw + iadd r14.xyzw, r14.xyzw, l(-24, -24, -24, -24) + movc r14.xyzw, r12.xyzw, r14.xyzw, l(8,8,8,8) + iadd r15.xyzw, -r14.xyzw, l(1, 1, 1, 1) + movc r15.xyzw, r13.xyzw, r13.xyzw, r15.xyzw + bfi r10.xyzw, l(7, 7, 7, 7), r14.xyzw, r10.xyzw, l(0, 0, 0, 0) + and r10.xyzw, r10.xyzw, l(127, 127, 127, 127) + movc r10.xyzw, r13.xyzw, r12.xyzw, r10.xyzw + ishl r12.xyzw, r15.xyzw, l(23, 23, 23, 23) + iadd r12.xyzw, r12.xyzw, l(0x3e000000, 0x3e000000, 0x3e000000, 0x3e000000) + ishl r10.xyzw, r10.xyzw, l(16, 16, 16, 16) + iadd r10.xyzw, r12.xyzw, r10.xyzw + movc r9.xyzw, r11.xyzw, r10.xyzw, l(0,0,0,0) + break + case l(4) + ibfe r10.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r8.xyzw + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r8.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ibfe r10.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r9.xyzw + itof r10.xyzw, r10.xyzw + mul r10.xyzw, r10.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r9.xyzw, r10.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(6) + f16tof32 r8.xyzw, r8.xyzw + f16tof32 r9.xyzw, r9.xyzw + break + default + break + endswitch + endif + add r8.xyzw, r6.xyzw, r8.xyzw + add r9.xyzw, r7.xyzw, r9.xyzw + iadd r0.x, r2.w, r4.x + if_nz r1.w + ishl r1.w, r0.x, l(2) + ld_raw r10.xyzw, r1.w, T0[0].xyzw + iadd r1.w, r1.w, l(16) + ld_raw r11.xyzw, r1.w, T0[0].xyzw + else + ishl r1.w, r0.x, l(2) + ld_raw r10.x, r1.w, T0[0].xxxx + iadd r1.z, r1.z, r0.x + ishl r1.z, r1.z, l(2) + ld_raw r10.y, r1.z, T0[0].xxxx + ishl r12.xyzw, l(2, 3, 4, 5), r1.yyyy + iadd r12.xyzw, r0.xxxx, r12.xyzw + ishl r12.xyzw, r12.xyzw, l(2, 2, 2, 2) + ld_raw r10.z, r12.x, T0[0].xxxx + ld_raw r10.w, r12.y, T0[0].xxxx + ld_raw r11.x, r12.z, T0[0].xxxx + ld_raw r11.y, r12.w, T0[0].xxxx + ishl r1.yz, l(0, 6, 7, 0), r1.yyyy + iadd r1.yz, r0.xxxx, r1.yyzy + ishl r1.yz, r1.yyzy, l(0, 2, 2, 0) + ld_raw r11.z, r1.y, T0[0].xxxx + ld_raw r11.w, r1.z, T0[0].xxxx + endif + if_nz r4.w + switch r4.z + case l(5) + ibfe r12.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r10.xyzw + itof r12.xyzw, r12.xyzw + mul r12.xyzw, r12.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r10.xyzw, r12.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ibfe r12.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r11.xyzw + itof r12.xyzw, r12.xyzw + mul r12.xyzw, r12.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r11.xyzw, r12.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(7) + f16tof32 r10.xyzw, r10.xyzw + f16tof32 r11.xyzw, r11.xyzw + break + default + break + endswitch + else + switch r4.z + case l(0) + case l(1) + movc r0.x, r0.w, l(16), l(0) + ushr r4.xyzw, r10.xyzw, r0.xxxx + and r4.xyzw, r4.xyzw, l(255, 255, 255, 255) + utof r4.xyzw, r4.xyzw + mul r10.xyzw, r4.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + ushr r4.xyzw, r11.xyzw, r0.xxxx + and r4.xyzw, r4.xyzw, l(255, 255, 255, 255) + utof r4.xyzw, r4.xyzw + mul r11.xyzw, r4.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) + break + case l(2) + case l(10) + movc r0.x, r0.w, l(20), l(0) + ushr r4.xyzw, r10.xyzw, r0.xxxx + and r4.xyzw, r4.xyzw, l(1023, 1023, 1023, 1023) + utof r4.xyzw, r4.xyzw + mul r10.xyzw, r4.xyzw, l(0.000978, 0.000978, 0.000978, 0.000978) + ushr r4.xyzw, r11.xyzw, r0.xxxx + and r4.xyzw, r4.xyzw, l(1023, 1023, 1023, 1023) + utof r4.xyzw, r4.xyzw + mul r11.xyzw, r4.xyzw, l(0.000978, 0.000978, 0.000978, 0.000978) + break + case l(3) + case l(12) + movc r0.x, r0.w, l(20), l(0) + ushr r4.xyzw, r10.xyzw, r0.xxxx + and r12.xyzw, r4.xyzw, l(1023, 1023, 1023, 1023) + and r13.xyzw, r4.xyzw, l(127, 127, 127, 127) + ubfe r14.xyzw, l(3, 3, 3, 3), l(7, 7, 7, 7), r4.xyzw + firstbit_hi r15.xyzw, r13.xyzw + iadd r15.xyzw, r15.xyzw, l(-24, -24, -24, -24) + movc r15.xyzw, r13.xyzw, r15.xyzw, l(8,8,8,8) + iadd r16.xyzw, -r15.xyzw, l(1, 1, 1, 1) + movc r16.xyzw, r14.xyzw, r14.xyzw, r16.xyzw + bfi r4.xyzw, l(7, 7, 7, 7), r15.xyzw, r4.xyzw, l(0, 0, 0, 0) + and r4.xyzw, r4.xyzw, l(127, 127, 127, 127) + movc r4.xyzw, r14.xyzw, r13.xyzw, r4.xyzw + ishl r13.xyzw, r16.xyzw, l(23, 23, 23, 23) + iadd r13.xyzw, r13.xyzw, l(0x3e000000, 0x3e000000, 0x3e000000, 0x3e000000) + ishl r4.xyzw, r4.xyzw, l(16, 16, 16, 16) + iadd r4.xyzw, r13.xyzw, r4.xyzw + movc r10.xyzw, r12.xyzw, r4.xyzw, l(0,0,0,0) + ushr r4.xyzw, r11.xyzw, r0.xxxx + and r12.xyzw, r4.xyzw, l(1023, 1023, 1023, 1023) + and r13.xyzw, r4.xyzw, l(127, 127, 127, 127) + ubfe r14.xyzw, l(3, 3, 3, 3), l(7, 7, 7, 7), r4.xyzw + firstbit_hi r15.xyzw, r13.xyzw + iadd r15.xyzw, r15.xyzw, l(-24, -24, -24, -24) + movc r15.xyzw, r13.xyzw, r15.xyzw, l(8,8,8,8) + iadd r16.xyzw, -r15.xyzw, l(1, 1, 1, 1) + movc r16.xyzw, r14.xyzw, r14.xyzw, r16.xyzw + bfi r4.xyzw, l(7, 7, 7, 7), r15.xyzw, r4.xyzw, l(0, 0, 0, 0) + and r4.xyzw, r4.xyzw, l(127, 127, 127, 127) + movc r4.xyzw, r14.xyzw, r13.xyzw, r4.xyzw + ishl r13.xyzw, r16.xyzw, l(23, 23, 23, 23) + iadd r13.xyzw, r13.xyzw, l(0x3e000000, 0x3e000000, 0x3e000000, 0x3e000000) + ishl r4.xyzw, r4.xyzw, l(16, 16, 16, 16) + iadd r4.xyzw, r13.xyzw, r4.xyzw + movc r11.xyzw, r12.xyzw, r4.xyzw, l(0,0,0,0) + break + case l(4) + ibfe r4.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r10.xyzw + itof r4.xyzw, r4.xyzw + mul r4.xyzw, r4.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r10.xyzw, r4.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + ibfe r4.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r11.xyzw + itof r4.xyzw, r4.xyzw + mul r4.xyzw, r4.xyzw, l(0.000977, 0.000977, 0.000977, 0.000977) + max r11.xyzw, r4.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) + break + case l(6) + f16tof32 r10.xyzw, r10.xyzw + f16tof32 r11.xyzw, r11.xyzw + break + default + break + endswitch + endif + add r6.xyzw, r8.xyzw, r10.xyzw + add r7.xyzw, r9.xyzw, r11.xyzw + else + mov r0.y, r3.w + endif +endif +mul r4.xyzw, r0.yyyy, r6.zxyw +mul_sat r6.xyzw, r0.yyyy, r7.xyzw +ieq r0.x, r5.x, l(0) +ine r0.y, r1.x, l(0) +and r0.x, r0.y, r0.x +if_nz r0.x + uge r0.x, r1.x, l(2) + if_nz r0.x + uge r0.x, r1.x, l(3) + if_nz r0.x + mov r4.x, r4.w + endif + mov r4.xz, r4.xxxx + endif + mov r4.xyz, r4.xzzx +endif +mov r5.z, vThreadID.y +imad r1.yz, r3.xxzx, r2.xxyx, r5.xxzx +ushr r1.x, r1.y, l(3) +udiv r0.xy, null, r1.xzxx, r2.xyxx +if_nz r0.z + ubfe r0.z, l(3), l(4), CB0[0][0].z + ishl r0.w, r3.y, l(5) + ishr r1.yw, r0.yyyy, l(0, 4, 0, 3) + ishr r2.w, r0.z, l(2) + ushr r0.w, r0.w, l(4) + and r0.w, r0.w, l(2046) + imad r0.w, r2.w, r0.w, r1.y + ushr r1.y, r2.z, l(5) + ibfe r3.xy, l(27, 29, 0, 0), l(2, 0, 0, 0), r0.xxxx + imad r0.w, r0.w, r1.y, r3.x + ishl r1.y, r0.y, l(8) + ishr r1.y, r1.y, l(6) + iadd r1.w, r1.w, r2.w + bfi r2.w, l(1), l(1), r1.w, l(0) + iadd r2.w, r2.w, r3.y + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r1.w, l(1), l(0), r1.w, r2.w + and r3.xy, r1.yyyy, l(16, 8, 0, 0) + bfi r3.zw, l(0, 0, 22, 22), l(0, 0, 8, 11), r0.wwww, l(0, 0, 0, 0) + imad r3.xz, r3.xxxx, l(2, 0, 16, 0), r3.zzwz + bfi r3.xy, l(5, 5, 0, 0), l(0, 3, 0, 0), r3.yyyy, r3.xzxx + bfi r0.zw, l(0, 0, 2, 2), l(0, 0, 6, 9), r0.zzzz, r3.xxxy + ubfe r1.y, l(3), l(6), r0.z + and r2.w, r1.w, l(6) + bfi r1.w, l(1), l(8), r1.w, l(0) + imad r1.y, r1.y, l(32), r1.w + imad r1.y, r2.w, l(4), r1.y + bfi r0.zw, l(0, 0, 1, 1), l(0, 0, 4, 7), r0.yyyy, r0.zzzw + bfi r0.w, l(9), l(3), r1.y, r0.w + bfi r0.z, l(6), l(0), r0.z, r0.w +else + ibfe r1.yw, l(0, 27, 0, 29), l(0, 2, 0, 0), r0.xxxx + ishr r3.xy, r0.yyyy, l(5, 2, 0, 0) + ushr r0.w, r2.z, l(5) + imad r0.w, r3.x, r0.w, r1.y + ishl r2.zw, r0.yyyy, l(0, 0, 2, 7) + ishl r1.y, r2.z, l(1) + and r1.y, r1.y, l(96) + bfi r3.x, l(25), l(7), r0.w, r1.y + and r2.zw, r2.zzzw, l(0, 0, 8, 2048) + iadd r3.x, r3.x, r2.z + ishl r3.zw, r1.yyyy, l(0, 0, 3, 2) + bfi r3.zw, l(0, 0, 25, 25), l(0, 0, 10, 9), r0.wwww, r3.zzzw + imad r3.zw, r2.zzzz, l(0, 0, 8, 4), r3.zzzw + bfi r3.xzw, l(1, 0, 1, 1), l(4, 0, 7, 6), r0.yyyy, r3.xxzw + bfi r0.w, l(12), l(0), r2.w, r3.z + and r1.y, r3.w, l(1792) + iadd r0.w, r0.w, r1.y + and r1.y, r3.y, l(2) + iadd r1.y, r1.w, r1.y + bfi r1.y, l(2), l(6), r1.y, l(0) + iadd r0.w, r0.w, r1.y + bfi r0.z, l(6), l(0), r3.x, r0.w +endif +imad r0.xy, -r0.xyxx, r2.xyxx, r1.xzxx +imul null, r0.w, r2.y, r2.x +imad r0.x, r0.x, r2.y, r0.y +ishl r0.x, r0.x, l(3) +imad r0.x, r0.z, r0.w, r0.x +ushr r0.x, r0.x, l(3) +mov_sat r4.xyzw, r4.xyzw +mad r1.xyzw, r4.yzxw, l(255.000000, 255.000000, 255.000000, 255.000000), l(0.500000, 0.500000, 0.500000, 0.500000) +ftou r1.xyzw, r1.xyzw +imad r0.y, r1.y, l(256), r1.x +imad r0.y, r1.z, l(0x00010000), r0.y +imad r1.xzw, r1.wwww, l(0x01000000, 0, 0x01000000, 0x01000000), r0.yyyy +mad r2.xyzw, r6.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000), l(0.500000, 0.500000, 0.500000, 0.500000) +ftou r2.xyzw, r2.xyzw +imad r0.y, r2.y, l(256), r2.x +imad r0.y, r2.z, l(0x00010000), r0.y +imad r1.y, r2.w, l(0x01000000), r0.y +store_uav_typed U0[0].xyzw, r0.xxxx, r1.xyzw +ret +// Approximately 675 instruction slots used +#endif + +const BYTE resolve_full_8bpp_scaled_cs[] = { + 68, 88, 66, 67, 117, 79, 26, 104, 183, 192, 179, 141, 92, 115, 99, 93, 202, 53, 94, + 29, 1, 0, 0, 0, 8, 82, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 144, 2, + 0, 0, 160, 2, 0, 0, 176, 2, 0, 0, 108, 81, 0, 0, 82, 68, 69, 70, 84, + 2, 0, 0, 1, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 44, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 101, 100, 114, 97, 109, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, + 101, 95, 100, 101, 115, 116, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, + 120, 101, 0, 213, 0, 0, 0, 4, 0, 0, 0, 252, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 156, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 220, 1, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 247, 1, 0, 0, 8, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 12, 2, 0, 0, 12, + 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 184, 1, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, + 114, 101, 115, 111, 108, 118, 101, 95, 101, 100, 114, 97, 109, 95, 105, 110, 102, 111, 0, + 100, 119, 111, 114, 100, 0, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 178, 1, 0, 0, 120, 101, 95, 114, 101, 115, 111, 108, 118, 101, 95, 99, 111, 111, 114, + 100, 105, 110, 97, 116, 101, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, 115, 111, + 108, 118, 101, 95, 100, 101, 115, 116, 95, 105, 110, 102, 111, 0, 120, 101, 95, 114, 101, + 115, 111, 108, 118, 101, 95, 100, 101, 115, 116, 95, 99, 111, 111, 114, 100, 105, 110, 97, + 116, 101, 95, 105, 110, 102, 111, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 83, 72, 69, 88, 180, 78, 0, 0, 81, 0, 5, 0, 173, 19, 0, + 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 161, 0, 0, 6, 70, + 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 156, 8, 0, 7, 70, 238, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 68, 68, 0, 0, 0, 0, 0, 0, 95, 0, 0, 2, 50, 0, 2, 0, 104, 0, + 0, 2, 17, 0, 0, 0, 155, 0, 0, 4, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, 0, 6, 138, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, + 0, 0, 0, 0, 32, 8, 0, 0, 0, 0, 0, 0, 1, 31, 0, 4, 3, 26, 0, + 16, 0, 0, 0, 0, 0, 138, 0, 0, 17, 50, 0, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 17, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 133, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, + 0, 1, 54, 0, 0, 8, 50, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 138, 0, 0, 17, 114, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 86, 133, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 85, 0, 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, 214, 143, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, + 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 80, 0, 0, 6, + 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 2, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, + 0, 1, 138, 0, 0, 17, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, + 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 10, 0, 0, 0, 13, 0, 0, 0, 24, 0, 0, 0, 28, 0, 0, 0, 6, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 0, + 16, 0, 5, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 140, 0, 0, 20, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 6, + 4, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 23, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 140, 0, 0, 13, 66, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 20, 82, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 166, 11, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 11, 130, 0, 16, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 28, 0, + 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, + 0, 0, 6, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, + 3, 0, 0, 0, 83, 0, 0, 6, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 9, 98, 0, 16, 0, 1, 0, + 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 6, + 1, 16, 0, 5, 0, 0, 0, 80, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, + 3, 58, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 130, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 5, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, + 5, 34, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 18, 0, + 0, 1, 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 80, 0, 0, 10, 162, 0, 16, 0, + 5, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 162, 0, + 16, 0, 5, 0, 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, + 98, 0, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 1, 0, 0, 0, 86, 7, 16, + 0, 5, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 26, 0, + 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 50, + 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 98, 0, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 1, 0, 0, 0, 6, 1, + 16, 0, 6, 0, 0, 0, 38, 0, 0, 11, 0, 208, 0, 0, 98, 0, 16, 0, 6, + 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 80, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, + 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 4, 0, + 0, 0, 78, 0, 0, 8, 50, 0, 16, 0, 7, 0, 0, 0, 0, 208, 0, 0, 150, + 5, 16, 0, 1, 0, 0, 0, 134, 0, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, + 0, 0, 0, 35, 0, 0, 10, 98, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 128, + 65, 0, 0, 0, 7, 0, 0, 0, 6, 2, 16, 0, 6, 0, 0, 0, 86, 6, 16, + 0, 1, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 35, + 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, + 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 4, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 78, 0, 0, 8, 0, 208, + 0, 0, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, + 0, 3, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 16, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 7, 0, 0, 0, + 58, 0, 16, 0, 3, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 18, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 18, + 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, + 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 6, 0, 0, 0, + 58, 0, 16, 0, 3, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 86, 5, 16, 0, 1, + 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, + 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 6, 112, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 6, 0, 0, + 0, 26, 0, 16, 0, 8, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 8, + 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, + 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 6, 112, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, + 4, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, + 0, 41, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, + 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, + 8, 130, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 6, 112, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, + 0, 16, 0, 4, 0, 0, 0, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, + 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, 139, 0, 0, 15, 242, 0, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 43, 0, 0, 5, + 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, + 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, + 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 139, 0, 0, 15, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, + 0, 8, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, + 0, 0, 7, 0, 0, 0, 131, 0, 0, 5, 242, 0, 16, 0, 6, 0, 0, 0, 70, + 14, 16, 0, 6, 0, 0, 0, 131, 0, 0, 5, 242, 0, 16, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 7, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 2, 0, 0, + 1, 23, 0, 0, 1, 18, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, + 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, + 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, + 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, + 85, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, + 0, 246, 15, 16, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, + 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, + 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, + 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 7, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 129, 128, + 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, 1, 6, + 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, + 10, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 6, + 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 86, 0, 0, 5, 242, 0, + 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, + 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 85, 0, 0, + 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 246, 15, + 16, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 8, 0, 0, + 0, 70, 14, 16, 0, 8, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, + 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 2, 0, 0, 1, 6, 0, 0, 3, + 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, + 0, 55, 0, 0, 9, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 85, + 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, + 246, 15, 16, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, + 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 135, 0, 0, 5, + 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 30, 0, 0, + 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, + 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 55, + 0, 0, 12, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, 11, 242, 0, 16, 0, 13, 0, + 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 12, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, + 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 11, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 140, 0, 0, 17, 242, 0, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 8, 0, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 8, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, + 62, 0, 0, 0, 62, 0, 0, 0, 62, 41, 0, 0, 10, 242, 0, 16, 0, 8, 0, + 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, + 0, 55, 0, 0, 12, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 9, 0, + 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, + 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 8, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 8, 0, 0, 0, 135, 0, 0, 5, 242, 0, 16, 0, 12, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 12, 0, + 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, + 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 55, 0, 0, 12, 242, 0, 16, 0, + 12, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 30, 0, 0, 11, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 128, 65, + 0, 0, 0, 12, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 13, 0, 0, + 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, + 16, 0, 13, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 55, 0, 0, 9, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 41, 0, + 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, + 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, + 30, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, + 0, 62, 41, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 55, 0, 0, 12, 242, 0, + 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, + 0, 139, 0, 0, 15, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, + 0, 8, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, + 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 139, 0, 0, 15, 242, 0, 16, 0, 8, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, + 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, + 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, + 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, 0, 131, 0, 0, 5, 242, + 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 131, 0, 0, 5, + 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 0, 0, + 1, 10, 0, 0, 1, 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, 80, 0, + 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 3, 0, 0, 0, + 56, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 63, 35, 0, 0, 9, 18, 0, 16, 0, 4, 0, + 0, 0, 1, 64, 0, 0, 80, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, + 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 8, 0, + 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, + 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 165, 0, 0, 8, 242, 0, 16, + 0, 9, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 70, 126, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 34, 0, 16, 0, 4, + 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 165, 0, 0, 8, 18, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, + 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, + 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, + 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, + 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 34, 0, 16, + 0, 8, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, + 86, 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, + 0, 6, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 41, 0, + 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, + 165, 0, 0, 8, 66, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, + 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, 0, + 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 6, 112, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 9, 0, 0, 0, + 42, 0, 16, 0, 10, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 165, 0, 0, 8, 34, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 10, 0, + 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 162, + 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, + 7, 162, 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 86, 13, + 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 5, 0, 0, 0, 86, + 13, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, 9, 0, 0, + 0, 26, 0, 16, 0, 5, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 5, + 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 31, 0, 4, 3, 58, 0, 16, 0, 4, 0, 0, 0, 76, 0, 0, 3, 42, 0, 16, + 0, 4, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, 0, 0, 0, 139, 0, + 0, 15, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, + 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, + 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 139, 0, 0, 15, 242, 0, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 9, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, + 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, + 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 131, 0, 0, 5, 242, 0, 16, 0, + 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 242, 0, 16, + 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 0, 0, 1, 10, 0, + 0, 1, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, 76, 0, 0, 3, 42, + 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, + 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 85, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, + 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, + 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, 0, 0, 6, 0, 0, + 3, 1, 64, 0, 0, 10, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 8, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 86, + 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, + 128, 58, 85, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 9, + 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 86, 0, 0, 5, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 2, 0, 0, + 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 3, 1, 64, + 0, 0, 12, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 4, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 8, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 138, 0, + 0, 15, 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 135, 0, 0, 5, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 12, 0, + 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 14, + 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, + 232, 255, 255, 255, 55, 0, 0, 12, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, + 0, 12, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, 11, 242, + 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 14, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 55, 0, 0, 9, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 13, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 140, + 0, 0, 17, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, + 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 12, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 12, + 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, + 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, + 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 41, 0, 0, 10, 242, + 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, + 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 86, 5, + 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 7, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 135, 0, 0, 5, 242, 0, + 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 30, 0, 0, 10, 242, + 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, + 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 55, 0, 0, + 12, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, + 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, 11, 242, 0, 16, 0, 15, 0, 0, 0, + 70, 14, 16, 128, 65, 0, 0, 0, 14, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 242, 0, + 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 7, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, + 0, 127, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, + 0, 23, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, + 0, 0, 62, 0, 0, 0, 62, 41, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 55, + 0, 0, 12, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, + 0, 0, 4, 0, 0, 0, 139, 0, 0, 15, 242, 0, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 8, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, + 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 139, 0, 0, 15, 242, + 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 43, 0, + 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, + 58, 52, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 6, 0, 0, 0, + 131, 0, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, + 0, 131, 0, 0, 5, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, + 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 2, 0, 0, 1, 23, 0, 0, 1, 21, + 0, 0, 1, 0, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 0, 0, 0, 7, 242, 0, 16, + 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, + 0, 0, 80, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, + 2, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 56, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 128, 62, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, + 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 242, + 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 70, 126, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, + 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 165, 0, + 0, 8, 242, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 70, + 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, + 34, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 8, 0, 0, 0, 26, 0, + 16, 0, 4, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, + 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, + 0, 8, 34, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 6, + 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, + 0, 5, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 242, 0, + 16, 0, 10, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, 8, 0, 0, 0, 10, 0, + 16, 0, 10, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, + 0, 0, 8, 130, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, + 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, + 0, 9, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 6, 112, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 9, 0, 0, 0, 58, + 0, 16, 0, 10, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 10, 162, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 86, 5, 16, 0, 1, 0, + 0, 0, 30, 0, 0, 7, 162, 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 0, + 0, 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, + 5, 0, 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, + 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 6, 112, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 9, 0, 0, 0, + 58, 0, 16, 0, 5, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 4, 0, 0, 0, 76, 0, + 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 5, + 0, 0, 0, 139, 0, 0, 15, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 8, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 8, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 139, 0, 0, 15, 242, 0, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 43, 0, 0, 5, 242, + 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, + 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, + 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, 0, 131, 0, 0, + 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 131, 0, + 0, 5, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, + 0, 0, 1, 10, 0, 0, 1, 2, 0, 0, 1, 23, 0, 0, 1, 18, 0, 0, 1, + 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, + 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, + 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 16, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 6, 0, 16, + 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, + 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, + 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 7, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 2, 0, + 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 55, 0, 0, 9, 18, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 20, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, + 32, 128, 58, 8, 32, 128, 58, 85, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 86, + 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, + 128, 58, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, 0, 0, 0, 6, + 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 55, 0, 0, 9, 18, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 135, 0, 0, 5, 242, 0, 16, 0, 14, 0, 0, 0, 70, + 14, 16, 0, 12, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, + 70, 14, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, + 255, 232, 255, 255, 255, 232, 255, 255, 255, 55, 0, 0, 12, 242, 0, 16, 0, 14, 0, + 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 30, 0, 0, 11, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, + 0, 14, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 15, 0, 0, 0, 70, + 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, 14, + 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 55, 0, + 0, 9, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, + 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 41, 0, 0, 10, + 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 30, 0, + 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, + 41, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, + 8, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 9, + 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 138, 0, 0, 15, + 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 135, + 0, 0, 5, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, + 30, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, + 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, + 255, 255, 55, 0, 0, 12, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, 11, 242, 0, 16, + 0, 15, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 14, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 55, + 0, 0, 9, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, + 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, + 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 12, + 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, + 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 41, 0, 0, 10, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 30, 0, 0, 7, 242, + 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, + 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 6, + 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 139, 0, 0, 15, 242, 0, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 43, 0, 0, 5, 242, + 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, + 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, + 139, 0, 0, 15, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 9, + 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, + 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, + 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, + 0, 6, 0, 0, 0, 131, 0, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 8, 0, 0, 0, 131, 0, 0, 5, 242, 0, 16, 0, 9, 0, 0, 0, 70, + 14, 16, 0, 9, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 2, 0, 0, 1, + 23, 0, 0, 1, 21, 0, 0, 1, 0, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 0, 0, + 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, + 14, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, + 3, 58, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, + 0, 0, 8, 242, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 16, 0, + 0, 0, 165, 0, 0, 8, 242, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, + 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 18, 0, 16, 0, 10, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, + 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, + 0, 4, 0, 0, 0, 5, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 30, 0, + 0, 7, 242, 0, 16, 0, 12, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 12, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, + 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 2, 0, 0, 0, 2, 0, 0, 0, 165, 0, 0, 8, 66, 0, 16, 0, 10, 0, + 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, + 12, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, + 8, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 6, 112, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 34, 0, 16, 0, 11, + 0, 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 86, 5, + 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 98, 0, 16, 0, 1, 0, 0, 0, 6, + 0, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, + 98, 0, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 165, 0, + 0, 8, 66, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 6, + 112, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 8, 130, 0, 16, 0, + 11, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 6, 112, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 4, 0, + 0, 0, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, 3, 1, + 64, 0, 0, 5, 0, 0, 0, 139, 0, 0, 15, 242, 0, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 12, + 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, + 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 139, 0, 0, 15, + 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 43, + 0, 0, 5, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, + 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, + 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 7, 0, 0, + 0, 131, 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 131, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, + 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, 2, 0, 0, 1, 23, 0, 0, 1, + 18, 0, 0, 1, 76, 0, 0, 3, 42, 0, 16, 0, 4, 0, 0, 0, 6, 0, 0, + 3, 1, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 1, 0, + 0, 0, 55, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 6, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, + 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 129, 128, + 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 129, 128, 128, 59, 85, 0, 0, 7, 242, + 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 129, 128, 128, 59, 129, 128, 128, + 59, 129, 128, 128, 59, 129, 128, 128, 59, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, + 0, 0, 2, 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 10, 0, 0, 0, 55, + 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 20, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 85, 0, 0, + 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 6, 0, + 16, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, + 32, 128, 58, 8, 32, 128, 58, 8, 32, 128, 58, 85, 0, 0, 7, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 32, 128, 58, 8, 32, 128, 58, 8, 32, + 128, 58, 8, 32, 128, 58, 2, 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 3, + 0, 0, 0, 6, 0, 0, 3, 1, 64, 0, 0, 12, 0, 0, 0, 55, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 20, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 242, 0, + 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 6, 0, 16, 0, 0, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, + 0, 0, 0, 127, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 14, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 135, 0, 0, 5, 242, 0, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, + 15, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, + 255, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, 255, 255, 55, 0, 0, 12, 242, 0, + 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 30, 0, 0, 11, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, + 128, 65, 0, 0, 0, 15, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 16, + 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, + 70, 14, 16, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, + 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 14, + 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, + 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, + 0, 0, 0, 62, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 55, 0, 0, 12, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, + 138, 0, 0, 15, 242, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, 14, 16, 0, 4, + 0, 0, 0, 135, 0, 0, 5, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 15, 0, 0, 0, 70, 14, 16, + 0, 15, 0, 0, 0, 2, 64, 0, 0, 232, 255, 255, 255, 232, 255, 255, 255, 232, 255, + 255, 255, 232, 255, 255, 255, 55, 0, 0, 12, 242, 0, 16, 0, 15, 0, 0, 0, 70, + 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, + 11, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 15, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, + 14, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, + 0, 140, 0, 0, 17, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 70, 14, 16, 0, 15, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 127, 0, + 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 55, 0, 0, 9, 242, + 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 13, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 23, 0, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 10, 242, + 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 41, 0, 0, + 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 30, + 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 11, 0, 0, + 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 1, 6, 0, 0, 3, 1, 64, 0, 0, 4, 0, 0, 0, 139, 0, 0, 15, + 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 43, + 0, 0, 5, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 0, 1, + 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, + 0, 0, 128, 191, 139, 0, 0, 15, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 11, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 1, 128, 58, 0, 1, + 128, 58, 0, 1, 128, 58, 0, 1, 128, 58, 52, 0, 0, 10, 242, 0, 16, 0, 11, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 2, 0, 0, 1, 6, 0, 0, + 3, 1, 64, 0, 0, 6, 0, 0, 0, 131, 0, 0, 5, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 131, 0, 0, 5, 242, 0, 16, 0, 11, + 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 0, 0, 1, 10, 0, 0, 1, + 2, 0, 0, 1, 23, 0, 0, 1, 21, 0, 0, 1, 0, 0, 0, 7, 242, 0, 16, + 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, + 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, + 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 21, 0, 0, + 1, 21, 0, 0, 1, 56, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 86, 5, + 16, 0, 0, 0, 0, 0, 38, 13, 16, 0, 6, 0, 0, 0, 56, 32, 0, 7, 242, + 0, 16, 0, 6, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 5, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 39, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, + 0, 0, 0, 0, 0, 80, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, + 0, 16, 0, 0, 0, 0, 0, 80, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 54, 0, 0, 5, 82, + 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, + 54, 0, 0, 5, 114, 0, 16, 0, 4, 0, 0, 0, 134, 2, 16, 0, 4, 0, 0, + 0, 21, 0, 0, 1, 54, 0, 0, 4, 66, 0, 16, 0, 5, 0, 0, 0, 26, 0, + 2, 0, 35, 0, 0, 9, 98, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 3, + 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 5, 0, 0, 0, + 85, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 78, 0, 0, 8, 50, 0, 16, 0, 0, 0, + 0, 0, 0, 208, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 2, + 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 11, + 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 10, 162, 0, 16, 0, + 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, + 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 254, 7, + 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 5, 0, 0, 0, 139, 0, 0, 15, 50, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, + 42, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, + 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, + 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, + 86, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 20, 194, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 22, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, + 11, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 82, 0, + 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 166, 11, 16, 0, + 3, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, + 5, 16, 0, 3, 0, 0, 0, 134, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, + 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 6, + 4, 16, 0, 3, 0, 0, 0, 138, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 35, + 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 17, 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, + 166, 14, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 18, 0, 0, 1, 139, 0, 0, 15, 162, 0, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, + 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, + 35, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, + 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 0, 0, + 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 96, 0, 0, 0, 140, + 0, 0, 11, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, + 1, 64, 0, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 0, 8, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, + 10, 194, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 140, + 0, 0, 17, 194, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 25, 0, 0, 0, 25, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 246, 15, 16, 0, 0, 0, + 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, 0, 3, + 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, + 0, 140, 0, 0, 17, 210, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 6, 14, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, + 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, + 0, 0, 1, 35, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 128, + 65, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 134, 0, 16, + 0, 1, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 35, + 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, 32, 0, 5, 242, 0, + 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 50, 0, 0, 15, 242, + 0, 16, 0, 1, 0, 0, 0, 150, 12, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 2, 64, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, + 0, 5, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 35, + 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 1, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, + 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 1, 0, 26, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 12, 210, + 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 86, 5, 16, + 0, 0, 0, 0, 0, 50, 0, 0, 15, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, + 0, 127, 67, 0, 0, 127, 67, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0, 0, 63, 0, 0, 0, 63, 28, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 1, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 1, 26, 0, 16, 0, 0, + 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 148, 0, 0, 0, 163, 2, 0, 0, 17, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 0, 153, 0, 0, 0, 94, 0, 0, 0, 51, + 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 44, 0, 0, 0, 34, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/tessellation_adaptive_vs.h b/src/graphics/shaders/bytecode/d3d12_5_1/tessellation_adaptive_vs.h new file mode 100644 index 0000000..b9c5e1c --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/tessellation_adaptive_vs.h @@ -0,0 +1,275 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer xe_system_cbuffer +// { +// +// uint xe_flags; // Offset: 0 Size: 4 [unused] +// float2 xe_tessellation_factor_range;// Offset: 4 Size: 8 +// uint xe_line_loop_closing_index; // Offset: 12 Size: 4 [unused] +// uint xe_vertex_index_endian; // Offset: 16 Size: 4 +// uint xe_vertex_index_offset; // Offset: 20 Size: 4 [unused] +// uint2 xe_vertex_index_min_max; // Offset: 24 Size: 8 [unused] +// float4 xe_user_clip_planes[6]; // Offset: 32 Size: 96 [unused] +// float3 xe_ndc_scale; // Offset: 128 Size: 12 [unused] +// float xe_point_vertex_diameter_min;// Offset: 140 Size: 4 [unused] +// float3 xe_ndc_offset; // Offset: 144 Size: 12 [unused] +// float xe_point_vertex_diameter_max;// Offset: 156 Size: 4 [unused] +// float2 xe_point_constant_diameter; // Offset: 160 Size: 8 [unused] +// float2 xe_point_screen_diameter_to_ndc_radius;// Offset: 168 Size: 8 [unused] +// uint4 xe_texture_swizzled_signs[2];// Offset: 176 Size: 32 [unused] +// uint xe_textures_resolved; // Offset: 208 Size: 4 [unused] +// uint2 xe_sample_count_log2; // Offset: 212 Size: 8 [unused] +// float xe_alpha_test_reference; // Offset: 220 Size: 4 [unused] +// uint xe_alpha_to_mask; // Offset: 224 Size: 4 [unused] +// uint xe_edram_32bpp_tile_pitch_dwords_scaled;// Offset: 228 Size: 4 [unused] +// uint xe_edram_depth_base_dwords_scaled;// Offset: 232 Size: 4 [unused] +// float4 xe_color_exp_bias; // Offset: 240 Size: 16 [unused] +// float2 xe_edram_poly_offset_front; // Offset: 256 Size: 8 [unused] +// float2 xe_edram_poly_offset_back; // Offset: 264 Size: 8 [unused] +// uint4 xe_edram_stencil[2]; // Offset: 272 Size: 32 [unused] +// uint4 xe_edram_rt_base_dwords_scaled;// Offset: 304 Size: 16 [unused] +// uint4 xe_edram_rt_format_flags; // Offset: 320 Size: 16 [unused] +// float4 xe_edram_rt_clamp[4]; // Offset: 336 Size: 64 [unused] +// uint4 xe_edram_rt_keep_mask[2]; // Offset: 400 Size: 32 [unused] +// uint4 xe_edram_rt_blend_factors_ops;// Offset: 432 Size: 16 [unused] +// float4 xe_edram_blend_constant; // Offset: 448 Size: 16 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_system_cbuffer cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_VertexID 0 x 0 VERTID uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XETESSFACTOR 0 x 0 NONE float x +// +vs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][2], immediateIndexed, space=0 +dcl_input_sgv v0.x, vertex_id +dcl_output o0.x +dcl_temps 1 +ieq r0.xyz, CB0[0][1].xxxx, l(1, 2, 3, 0) +or r0.xy, r0.yzyy, r0.xyxx +if_nz r0.x + ishl r0.x, v0.x, l(8) + ushr r0.z, v0.x, l(8) + and r0.xz, r0.xxzx, l(0xff00ff00, 0, 0x00ff00ff, 0) + iadd r0.x, r0.z, r0.x +else + mov r0.x, v0.x +endif +if_nz r0.y + ushr r0.y, r0.x, l(16) + bfi r0.x, l(16), l(16), r0.x, r0.y +endif +add r0.x, r0.x, l(1.000000) +max r0.x, r0.x, CB0[0][0].y +min o0.x, r0.x, CB0[0][0].z +ret +// Approximately 18 instruction slots used +#endif + +const BYTE tessellation_adaptive_vs[] = { + 68, 88, 66, 67, 124, 10, 20, 236, 52, 205, 17, 163, 29, 96, 4, 68, 69, 43, 2, + 171, 1, 0, 0, 0, 116, 13, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 104, 10, + 0, 0, 156, 10, 0, 0, 212, 10, 0, 0, 216, 12, 0, 0, 82, 68, 69, 70, 44, + 10, 0, 0, 1, 0, 0, 0, 120, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 254, 255, 0, 5, 0, 0, 2, 10, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 115, 121, 115, 116, 101, 109, 95, 99, + 98, 117, 102, 102, 101, 114, 0, 171, 171, 100, 0, 0, 0, 30, 0, 0, 0, 144, 0, + 0, 0, 208, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 5, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 5, 0, + 0, 4, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 152, 5, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 188, + 5, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 215, 5, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 80, 5, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 238, 5, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 5, 6, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 72, 6, 0, 0, 32, 0, 0, 0, 96, 0, 0, 0, + 0, 0, 0, 0, 100, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 136, 6, 0, 0, 128, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 6, 0, 0, 140, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 8, 7, 0, 0, 144, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 22, 7, 0, 0, + 156, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 51, 7, + 0, 0, 160, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, 5, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 78, 7, 0, 0, 168, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, 5, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 117, 7, 0, 0, 176, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 152, + 7, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 188, 7, 0, 0, 208, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 209, 7, 0, 0, 212, 0, 0, 0, 8, 0, 0, 0, 0, + 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 230, 7, 0, 0, 220, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 254, 7, 0, 0, 224, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 8, 0, 0, 228, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 55, 8, 0, 0, 232, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 89, 8, 0, + 0, 240, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 144, + 8, 0, 0, 0, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 171, 8, 0, 0, 8, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, 5, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 197, 8, 0, 0, 16, 1, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, + 216, 8, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 252, 8, 0, 0, 48, 1, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 64, 9, 0, 0, 64, 1, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 89, 9, 0, 0, 80, 1, 0, 0, 64, 0, + 0, 0, 0, 0, 0, 0, 108, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 144, 9, 0, 0, 144, 1, 0, 0, + 32, 0, 0, 0, 0, 0, 0, 0, 168, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 204, 9, 0, 0, 176, 1, + 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 234, 9, 0, 0, + 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 102, 108, 97, 103, 115, 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 73, 5, 0, 0, 120, 101, 95, 116, 101, 115, 115, + 101, 108, 108, 97, 116, 105, 111, 110, 95, 102, 97, 99, 116, 111, 114, 95, 114, 97, 110, + 103, 101, 0, 102, 108, 111, 97, 116, 50, 0, 1, 0, 3, 0, 1, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 145, 5, 0, 0, 120, 101, 95, 108, 105, 110, 101, 95, 108, 111, 111, + 112, 95, 99, 108, 111, 115, 105, 110, 103, 95, 105, 110, 100, 101, 120, 0, 120, 101, 95, + 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, 120, 95, 101, 110, 100, 105, 97, 110, + 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, 120, 95, 111, 102, + 102, 115, 101, 116, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, + 120, 95, 109, 105, 110, 95, 109, 97, 120, 0, 117, 105, 110, 116, 50, 0, 171, 1, 0, + 19, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 6, 0, 0, 120, 101, 95, 117, + 115, 101, 114, 95, 99, 108, 105, 112, 95, 112, 108, 97, 110, 101, 115, 0, 102, 108, 111, + 97, 116, 52, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 6, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, + 6, 0, 0, 120, 101, 95, 110, 100, 99, 95, 115, 99, 97, 108, 101, 0, 102, 108, 111, + 97, 116, 51, 0, 1, 0, 3, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 149, 6, + 0, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, 101, 120, 95, 100, + 105, 97, 109, 101, 116, 101, 114, 95, 109, 105, 110, 0, 102, 108, 111, 97, 116, 0, 171, + 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 6, 0, 0, 120, 101, + 95, 110, 100, 99, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 112, 111, 105, 110, + 116, 95, 118, 101, 114, 116, 101, 120, 95, 100, 105, 97, 109, 101, 116, 101, 114, 95, 109, + 97, 120, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 99, 111, 110, 115, 116, 97, 110, + 116, 95, 100, 105, 97, 109, 101, 116, 101, 114, 0, 120, 101, 95, 112, 111, 105, 110, 116, + 95, 115, 99, 114, 101, 101, 110, 95, 100, 105, 97, 109, 101, 116, 101, 114, 95, 116, 111, + 95, 110, 100, 99, 95, 114, 97, 100, 105, 117, 115, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 115, 119, 105, 122, 122, 108, 101, 100, 95, 115, 105, 103, 110, 115, 0, + 117, 105, 110, 116, 52, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 115, 95, + 114, 101, 115, 111, 108, 118, 101, 100, 0, 120, 101, 95, 115, 97, 109, 112, 108, 101, 95, + 99, 111, 117, 110, 116, 95, 108, 111, 103, 50, 0, 120, 101, 95, 97, 108, 112, 104, 97, + 95, 116, 101, 115, 116, 95, 114, 101, 102, 101, 114, 101, 110, 99, 101, 0, 120, 101, 95, + 97, 108, 112, 104, 97, 95, 116, 111, 95, 109, 97, 115, 107, 0, 120, 101, 95, 101, 100, + 114, 97, 109, 95, 51, 50, 98, 112, 112, 95, 116, 105, 108, 101, 95, 112, 105, 116, 99, + 104, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, 0, 120, 101, 95, + 101, 100, 114, 97, 109, 95, 100, 101, 112, 116, 104, 95, 98, 97, 115, 101, 95, 100, 119, + 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, 0, 120, 101, 95, 99, 111, 108, 111, + 114, 95, 101, 120, 112, 95, 98, 105, 97, 115, 0, 171, 1, 0, 3, 0, 1, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, + 112, 111, 108, 121, 95, 111, 102, 102, 115, 101, 116, 95, 102, 114, 111, 110, 116, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, 102, 115, 101, 116, + 95, 98, 97, 99, 107, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 115, 116, 101, 110, + 99, 105, 108, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 98, 97, 115, + 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, 0, 171, 1, 0, + 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, + 100, 114, 97, 109, 95, 114, 116, 95, 102, 111, 114, 109, 97, 116, 95, 102, 108, 97, 103, + 115, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 99, 108, 97, 109, 112, + 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 6, 0, 0, + 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 107, 101, 101, 112, 95, 109, 97, + 115, 107, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, + 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 98, 108, 101, 110, + 100, 95, 102, 97, 99, 116, 111, 114, 115, 95, 111, 112, 115, 0, 120, 101, 95, 101, 100, + 114, 97, 109, 95, 98, 108, 101, 110, 100, 95, 99, 111, 110, 115, 116, 97, 110, 116, 0, + 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, + 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, + 49, 0, 171, 171, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, + 0, 32, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 83, 86, 95, 86, 101, 114, 116, 101, 120, 73, 68, 0, 79, + 83, 71, 78, 48, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 14, 0, + 0, 88, 69, 84, 69, 83, 83, 70, 65, 67, 84, 79, 82, 0, 171, 171, 171, 83, 72, + 69, 88, 252, 1, 0, 0, 81, 0, 1, 0, 127, 0, 0, 0, 106, 8, 0, 1, 89, + 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 4, 18, 16, 16, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 101, 0, 0, 3, 18, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, 32, 0, 0, 12, 114, 0, 16, 0, 0, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, + 7, 50, 0, 16, 0, 0, 0, 0, 0, 150, 5, 16, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 41, + 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 8, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, + 0, 10, 16, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 0, 0, 0, 0, 6, 2, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, + 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, + 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, + 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 0, 0, 0, 7, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, + 63, 52, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, + 0, 0, 9, 18, 32, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 148, 0, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 2, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/tessellation_indexed_vs.h b/src/graphics/shaders/bytecode/d3d12_5_1/tessellation_indexed_vs.h new file mode 100644 index 0000000..a291351 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/tessellation_indexed_vs.h @@ -0,0 +1,279 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer xe_system_cbuffer +// { +// +// uint xe_flags; // Offset: 0 Size: 4 [unused] +// float2 xe_tessellation_factor_range;// Offset: 4 Size: 8 [unused] +// uint xe_line_loop_closing_index; // Offset: 12 Size: 4 [unused] +// uint xe_vertex_index_endian; // Offset: 16 Size: 4 +// uint xe_vertex_index_offset; // Offset: 20 Size: 4 +// uint2 xe_vertex_index_min_max; // Offset: 24 Size: 8 +// float4 xe_user_clip_planes[6]; // Offset: 32 Size: 96 [unused] +// float3 xe_ndc_scale; // Offset: 128 Size: 12 [unused] +// float xe_point_vertex_diameter_min;// Offset: 140 Size: 4 [unused] +// float3 xe_ndc_offset; // Offset: 144 Size: 12 [unused] +// float xe_point_vertex_diameter_max;// Offset: 156 Size: 4 [unused] +// float2 xe_point_constant_diameter; // Offset: 160 Size: 8 [unused] +// float2 xe_point_screen_diameter_to_ndc_radius;// Offset: 168 Size: 8 [unused] +// uint4 xe_texture_swizzled_signs[2];// Offset: 176 Size: 32 [unused] +// uint xe_textures_resolved; // Offset: 208 Size: 4 [unused] +// uint2 xe_sample_count_log2; // Offset: 212 Size: 8 [unused] +// float xe_alpha_test_reference; // Offset: 220 Size: 4 [unused] +// uint xe_alpha_to_mask; // Offset: 224 Size: 4 [unused] +// uint xe_edram_32bpp_tile_pitch_dwords_scaled;// Offset: 228 Size: 4 [unused] +// uint xe_edram_depth_base_dwords_scaled;// Offset: 232 Size: 4 [unused] +// float4 xe_color_exp_bias; // Offset: 240 Size: 16 [unused] +// float2 xe_edram_poly_offset_front; // Offset: 256 Size: 8 [unused] +// float2 xe_edram_poly_offset_back; // Offset: 264 Size: 8 [unused] +// uint4 xe_edram_stencil[2]; // Offset: 272 Size: 32 [unused] +// uint4 xe_edram_rt_base_dwords_scaled;// Offset: 304 Size: 16 [unused] +// uint4 xe_edram_rt_format_flags; // Offset: 320 Size: 16 [unused] +// float4 xe_edram_rt_clamp[4]; // Offset: 336 Size: 64 [unused] +// uint4 xe_edram_rt_keep_mask[2]; // Offset: 400 Size: 32 [unused] +// uint4 xe_edram_rt_blend_factors_ops;// Offset: 432 Size: 16 [unused] +// float4 xe_edram_blend_constant; // Offset: 448 Size: 16 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_system_cbuffer cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_VertexID 0 x 0 VERTID uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE float x +// +vs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][2], immediateIndexed, space=0 +dcl_input_sgv v0.x, vertex_id +dcl_output o0.x +dcl_temps 1 +ieq r0.xyz, CB0[0][1].xxxx, l(1, 2, 3, 0) +or r0.xy, r0.yzyy, r0.xyxx +if_nz r0.x + ishl r0.x, v0.x, l(8) + ushr r0.z, v0.x, l(8) + and r0.xz, r0.xxzx, l(0xff00ff00, 0, 0x00ff00ff, 0) + iadd r0.x, r0.z, r0.x +else + mov r0.x, v0.x +endif +if_nz r0.y + ushr r0.y, r0.x, l(16) + bfi r0.x, l(16), l(16), r0.x, r0.y +endif +iadd r0.x, r0.x, CB0[0][1].y +and r0.x, r0.x, l(0x00ffffff) +umax r0.x, r0.x, CB0[0][1].z +umin r0.x, r0.x, CB0[0][1].w +utof o0.x, r0.x +ret +// Approximately 20 instruction slots used +#endif + +const BYTE tessellation_indexed_vs[] = { + 68, 88, 66, 67, 72, 50, 55, 79, 78, 232, 44, 71, 22, 110, 232, 129, 83, 139, 178, + 150, 1, 0, 0, 0, 168, 13, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 104, 10, + 0, 0, 156, 10, 0, 0, 208, 10, 0, 0, 12, 13, 0, 0, 82, 68, 69, 70, 44, + 10, 0, 0, 1, 0, 0, 0, 120, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 254, 255, 0, 5, 0, 0, 2, 10, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 115, 121, 115, 116, 101, 109, 95, 99, + 98, 117, 102, 102, 101, 114, 0, 171, 171, 100, 0, 0, 0, 30, 0, 0, 0, 144, 0, + 0, 0, 208, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 5, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 5, 0, + 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, 5, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 188, + 5, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 215, 5, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 80, 5, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 238, 5, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 5, 6, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 2, 0, + 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 72, 6, 0, 0, 32, 0, 0, 0, 96, 0, 0, 0, + 0, 0, 0, 0, 100, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 136, 6, 0, 0, 128, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 6, 0, 0, 140, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 8, 7, 0, 0, 144, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 156, 6, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 22, 7, 0, 0, + 156, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 51, 7, + 0, 0, 160, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, 5, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 78, 7, 0, 0, 168, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, 5, 0, + 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 117, 7, 0, 0, 176, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 152, + 7, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 188, 7, 0, 0, 208, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 209, 7, 0, 0, 212, 0, 0, 0, 8, 0, 0, 0, 0, + 0, 0, 0, 36, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 230, 7, 0, 0, 220, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 228, 6, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 254, 7, 0, 0, 224, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 8, 0, 0, 228, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 55, 8, 0, 0, 232, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 80, 5, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 89, 8, 0, + 0, 240, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 144, + 8, 0, 0, 0, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, 5, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 171, 8, 0, 0, 8, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 152, 5, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 197, 8, 0, 0, 16, 1, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, + 216, 8, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 252, 8, 0, 0, 48, 1, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 64, 9, 0, 0, 64, 1, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 89, 9, 0, 0, 80, 1, 0, 0, 64, 0, + 0, 0, 0, 0, 0, 0, 108, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 144, 9, 0, 0, 144, 1, 0, 0, + 32, 0, 0, 0, 0, 0, 0, 0, 168, 9, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 204, 9, 0, 0, 176, 1, + 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 234, 9, 0, 0, + 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 8, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 102, 108, 97, 103, 115, 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 73, 5, 0, 0, 120, 101, 95, 116, 101, 115, 115, + 101, 108, 108, 97, 116, 105, 111, 110, 95, 102, 97, 99, 116, 111, 114, 95, 114, 97, 110, + 103, 101, 0, 102, 108, 111, 97, 116, 50, 0, 1, 0, 3, 0, 1, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 145, 5, 0, 0, 120, 101, 95, 108, 105, 110, 101, 95, 108, 111, 111, + 112, 95, 99, 108, 111, 115, 105, 110, 103, 95, 105, 110, 100, 101, 120, 0, 120, 101, 95, + 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, 120, 95, 101, 110, 100, 105, 97, 110, + 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, 120, 95, 111, 102, + 102, 115, 101, 116, 0, 120, 101, 95, 118, 101, 114, 116, 101, 120, 95, 105, 110, 100, 101, + 120, 95, 109, 105, 110, 95, 109, 97, 120, 0, 117, 105, 110, 116, 50, 0, 171, 1, 0, + 19, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 6, 0, 0, 120, 101, 95, 117, + 115, 101, 114, 95, 99, 108, 105, 112, 95, 112, 108, 97, 110, 101, 115, 0, 102, 108, 111, + 97, 116, 52, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 6, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, + 6, 0, 0, 120, 101, 95, 110, 100, 99, 95, 115, 99, 97, 108, 101, 0, 102, 108, 111, + 97, 116, 51, 0, 1, 0, 3, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 149, 6, + 0, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 118, 101, 114, 116, 101, 120, 95, 100, + 105, 97, 109, 101, 116, 101, 114, 95, 109, 105, 110, 0, 102, 108, 111, 97, 116, 0, 171, + 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 6, 0, 0, 120, 101, + 95, 110, 100, 99, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 112, 111, 105, 110, + 116, 95, 118, 101, 114, 116, 101, 120, 95, 100, 105, 97, 109, 101, 116, 101, 114, 95, 109, + 97, 120, 0, 120, 101, 95, 112, 111, 105, 110, 116, 95, 99, 111, 110, 115, 116, 97, 110, + 116, 95, 100, 105, 97, 109, 101, 116, 101, 114, 0, 120, 101, 95, 112, 111, 105, 110, 116, + 95, 115, 99, 114, 101, 101, 110, 95, 100, 105, 97, 109, 101, 116, 101, 114, 95, 116, 111, + 95, 110, 100, 99, 95, 114, 97, 100, 105, 117, 115, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 115, 119, 105, 122, 122, 108, 101, 100, 95, 115, 105, 103, 110, 115, 0, + 117, 105, 110, 116, 52, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 115, 95, + 114, 101, 115, 111, 108, 118, 101, 100, 0, 120, 101, 95, 115, 97, 109, 112, 108, 101, 95, + 99, 111, 117, 110, 116, 95, 108, 111, 103, 50, 0, 120, 101, 95, 97, 108, 112, 104, 97, + 95, 116, 101, 115, 116, 95, 114, 101, 102, 101, 114, 101, 110, 99, 101, 0, 120, 101, 95, + 97, 108, 112, 104, 97, 95, 116, 111, 95, 109, 97, 115, 107, 0, 120, 101, 95, 101, 100, + 114, 97, 109, 95, 51, 50, 98, 112, 112, 95, 116, 105, 108, 101, 95, 112, 105, 116, 99, + 104, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, 0, 120, 101, 95, + 101, 100, 114, 97, 109, 95, 100, 101, 112, 116, 104, 95, 98, 97, 115, 101, 95, 100, 119, + 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, 0, 120, 101, 95, 99, 111, 108, 111, + 114, 95, 101, 120, 112, 95, 98, 105, 97, 115, 0, 171, 1, 0, 3, 0, 1, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 92, 6, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, + 112, 111, 108, 121, 95, 111, 102, 102, 115, 101, 116, 95, 102, 114, 111, 110, 116, 0, 120, + 101, 95, 101, 100, 114, 97, 109, 95, 112, 111, 108, 121, 95, 111, 102, 102, 115, 101, 116, + 95, 98, 97, 99, 107, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 115, 116, 101, 110, + 99, 105, 108, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 143, 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 98, 97, 115, + 101, 95, 100, 119, 111, 114, 100, 115, 95, 115, 99, 97, 108, 101, 100, 0, 171, 1, 0, + 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 7, 0, 0, 120, 101, 95, 101, + 100, 114, 97, 109, 95, 114, 116, 95, 102, 111, 114, 109, 97, 116, 95, 102, 108, 97, 103, + 115, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 99, 108, 97, 109, 112, + 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 6, 0, 0, + 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 107, 101, 101, 112, 95, 109, 97, + 115, 107, 0, 171, 171, 1, 0, 19, 0, 1, 0, 4, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, + 7, 0, 0, 120, 101, 95, 101, 100, 114, 97, 109, 95, 114, 116, 95, 98, 108, 101, 110, + 100, 95, 102, 97, 99, 116, 111, 114, 115, 95, 111, 112, 115, 0, 120, 101, 95, 101, 100, + 114, 97, 109, 95, 98, 108, 101, 110, 100, 95, 99, 111, 110, 115, 116, 97, 110, 116, 0, + 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, + 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, + 49, 0, 171, 171, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, + 0, 32, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 83, 86, 95, 86, 101, 114, 116, 101, 120, 73, 68, 0, 79, + 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 14, 0, + 0, 88, 69, 86, 69, 82, 84, 69, 88, 73, 68, 0, 171, 83, 72, 69, 88, 52, 2, + 0, 0, 81, 0, 1, 0, 141, 0, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, + 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 96, 0, 0, 4, 18, 16, 16, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 101, 0, 0, 3, 18, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, + 0, 0, 32, 0, 0, 12, 114, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, + 0, 0, 0, 0, 0, 150, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, + 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 8, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 82, 0, + 16, 0, 0, 0, 0, 0, 6, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 255, 0, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, + 0, 0, 10, 16, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, + 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 140, 0, 0, + 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 64, + 0, 0, 16, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 0, 83, 0, 0, 9, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 84, 0, 0, 9, 18, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 86, 0, 0, 5, 18, 32, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, + 148, 0, 0, 0, 20, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_128bpb_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_128bpb_cs.h new file mode 100644 index 0000000..d855200 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_128bpb_cs.h @@ -0,0 +1,423 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(1) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(4) +imad r1.y, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.y, CB0[0][2].x, r0.w +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r2.xw, l(27, 0, 0, 29), l(4, 0, 0, 2), vThreadID.xxxx + imad r0.y, r0.y, r1.w, r2.x + ishl r1.z, vThreadID.y, l(12) + and r1.z, r1.z, l(0x00006000) + bfi r1.z, l(3), l(10), r1.x, r1.z + ishr r1.z, r1.z, l(6) + iadd r1.w, r2.y, r2.z + bfi r2.x, l(1), l(1), r1.w, l(0) + iadd r2.x, r2.x, r2.w + bfi r2.x, l(2), l(1), r2.x, l(0) + bfi r1.w, l(1), l(0), r1.w, r2.x + bfi r2.xy, l(18, 18, 0, 0), l(12, 15, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(10, 13, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(6) + bfi r1.w, l(1), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(6, 6, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.zw, l(0, 0, 27, 29), l(0, 0, 4, 2), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r2.z, CB0[0][0].z, l(5) + imad r1.z, r2.x, r2.z, r1.z + ishl r2.x, vThreadID.y, l(7) + and r2.xz, r2.xxxx, l(1792, 0, 2048, 0) + bfi r2.w, l(3), l(5), r1.x, r2.x + bfi r2.w, l(21), l(11), r1.z, r2.w + bfi r3.x, l(1), l(4), vThreadID.y, l(0) + iadd r2.w, r2.w, r3.x + ishl r3.yz, r2.xxxx, l(0, 3, 2, 0) + bfi r3.yz, l(0, 3, 3, 0), l(0, 8, 7, 0), r1.xxxx, r3.yyzy + bfi r1.xz, l(21, 0, 21, 0), l(14, 0, 13, 0), r1.zzzz, r3.yyzy + imad r1.xz, r3.xxxx, l(8, 0, 4, 0), r1.xxzx + bfi r1.x, l(12), l(0), r2.z, r1.x + and r1.z, r1.z, l(1792) + iadd r1.x, r1.x, r1.z + and r1.z, r2.y, l(2) + iadd r1.z, r1.w, r1.z + bfi r1.z, l(2), l(6), r1.z, l(0) + iadd r1.x, r1.x, r1.z + bfi r0.y, l(6), l(0), r2.w, r1.x + endif +else + imad r1.x, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.x, CB0[0][0].z, r0.w +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.y, r0.y, l(4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r1.xzw, r0.zzzz, l(1, 0, 2, 3) +or r0.zw, r1.zzzw, r1.xxxz +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +store_uav_typed U0[0].xyzw, r1.yyyy, r2.xyzw +iadd r1.x, r1.y, l(1) +if_nz r0.x + mov r0.x, l(32) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r0.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r0.xyzw +endif +store_uav_typed U0[0].xyzw, r1.xxxx, r2.xyzw +ret +// Approximately 109 instruction slots used +#endif + +const BYTE texture_load_128bpb_cs[] = { + 68, 88, 66, 67, 175, 240, 215, 228, 28, 212, 172, 11, 139, 214, 181, 91, 179, 145, 93, + 198, 1, 0, 0, 0, 48, 19, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 148, 18, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 88, 14, 0, + 0, 81, 0, 5, 0, 150, 3, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 114, 0, 16, 0, 2, 0, + 0, 0, 150, 5, 2, 0, 2, 64, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 1, 0, 0, 0, + 246, 139, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 14, + 146, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 96, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 140, 0, 0, 20, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 18, 0, + 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 12, + 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, + 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 13, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 138, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, + 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 32, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, + 0, 0, 1, 139, 0, 0, 14, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, + 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 6, + 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 7, 0, 0, + 0, 1, 0, 0, 10, 82, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 3, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, + 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, + 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 3, 0, 0, 0, + 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 3, 0, 0, + 0, 140, 0, 0, 17, 82, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 21, 0, + 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 14, + 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, + 1, 0, 0, 0, 86, 6, 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 82, 0, 16, + 0, 1, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 6, 2, 16, 0, 1, + 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, + 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 35, 0, + 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 2, 0, 58, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, + 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, + 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 210, 0, 16, 0, 1, 0, 0, 0, + 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 0, 0, + 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 6, 8, 16, 0, 1, 0, 0, 0, 31, + 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, + 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 30, 0, + 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, + 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, + 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, + 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 109, 0, 0, 0, 5, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, + 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_128bpb_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_128bpb_scaled_cs.h new file mode 100644 index 0000000..355fb34 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_128bpb_scaled_cs.h @@ -0,0 +1,453 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(1) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.z, r1.x, l(4) +imad r1.w, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.z, r1.w, CB0[0][2].x, r1.z +iadd r1.z, r1.z, CB0[0][1].w +ushr r1.z, r1.z, l(4) +udiv r2.xy, null, r1.xyxx, r0.zwzz +if_nz r0.x + ishr r3.xyzw, r2.yxyx, l(4, 5, 3, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r2.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r1.w, r0.x, r2.z, r3.x + imad r1.w, r1.w, r2.w, r3.y + ishl r2.z, r2.y, l(12) + and r2.z, r2.z, l(0x00006000) + bfi r2.z, l(3), l(10), r2.x, r2.z + ishr r2.z, r2.z, l(6) + iadd r0.x, r0.x, r3.z + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.w + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r3.xy, l(18, 18, 0, 0), l(12, 15, 0, 0), r1.wwww, l(0, 0, 0, 0) + imad r2.zw, r2.zzzz, l(0, 0, 2, 16), r3.xxxy + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 10, 13), vThreadID.zzzz, r2.zzzw + bfi r1.w, l(1), l(4), r2.y, l(0) + ubfe r3.x, l(3), l(6), r2.z + and r3.y, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.x, l(32), r0.x + imad r0.x, r3.y, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r1.wwww, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ishr r3.xyzw, r2.xyyx, l(5, 5, 2, 3) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.w, r3.y, r1.w, r3.x + ishl r2.z, r2.y, l(7) + and r2.zw, r2.zzzz, l(0, 0, 1792, 2048) + bfi r3.x, l(3), l(5), r2.x, r2.z + bfi r3.x, l(21), l(11), r1.w, r3.x + bfi r3.y, l(1), l(4), r2.y, l(0) + iadd r3.x, r3.x, r3.y + ishl r4.xy, r2.zzzz, l(3, 2, 0, 0) + bfi r4.xy, l(3, 3, 0, 0), l(8, 7, 0, 0), r2.xxxx, r4.xyxx + bfi r4.xy, l(21, 21, 0, 0), l(14, 13, 0, 0), r1.wwww, r4.xyxx + imad r4.xy, r3.yyyy, l(8, 4, 0, 0), r4.xyxx + bfi r1.w, l(12), l(0), r2.w, r4.x + and r2.z, r4.y, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.z, l(2) + iadd r2.z, r3.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.x, r1.w +endif +imad r1.yw, -r2.xxxy, r0.zzzw, r1.xxxy +imul null, r2.x, r0.w, r0.z +imad r1.y, r1.y, r0.w, r1.w +ishl r1.y, r1.y, l(4) +imad r0.x, r0.x, r2.x, r1.y +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r2.xyzw, r0.xxxx, T0[0].xyzw +ieq r3.xyz, r0.yyyy, l(1, 2, 3, 0) +or r1.yw, r3.yyyz, r3.xxxy +if_nz r1.y + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r1.w + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +store_uav_typed U0[0].xyzw, r1.zzzz, r2.xyzw +iadd r0.y, r1.z, l(1) +ult r2.x, l(1), r0.z +if_nz r2.x + udiv r2.x, null, r1.x, r0.z + imad r1.x, -r2.x, r0.z, r1.x + iadd r2.x, r1.x, l(1) + ieq r2.x, r0.z, r2.x + if_nz r2.x + ishl r0.z, r0.z, l(5) + ishl r1.x, r1.x, l(4) + iadd r0.z, r0.z, -r1.x + else + mov r0.z, l(16) + endif +else + mov r0.z, l(32) +endif +imul null, r0.z, r0.w, r0.z +ushr r0.z, r0.z, l(4) +iadd r0.x, r0.z, r0.x +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r1.y + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r1.w + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +store_uav_typed U0[0].xyzw, r0.yyyy, r2.xyzw +ret +// Approximately 121 instruction slots used +#endif + +const BYTE texture_load_128bpb_scaled_cs[] = { + 68, 88, 66, 67, 198, 95, 37, 247, 141, 77, 51, 231, 157, 250, 65, 9, 22, 247, 190, + 228, 1, 0, 0, 0, 140, 20, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 240, 19, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 180, 15, 0, + 0, 81, 0, 5, 0, 237, 3, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 66, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 78, 0, 0, + 8, 50, 0, 16, 0, 2, 0, 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 1, 0, + 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 22, 1, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 42, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 2, + 0, 0, 0, 246, 139, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, + 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 35, + 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, + 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 12, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 96, 0, 0, 140, 0, 0, 11, + 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 10, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, + 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 194, 0, + 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 6, 4, 16, 0, + 3, 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 166, + 10, 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, + 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, + 34, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, + 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, + 1, 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, + 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 42, 0, 0, 10, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 1, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 85, 0, + 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, + 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, + 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, + 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, + 0, 0, 8, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, + 3, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 140, 0, + 0, 11, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, + 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 50, 0, + 16, 0, 4, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, + 50, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 70, + 0, 16, 0, 4, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 14, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 35, + 0, 0, 12, 50, 0, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 4, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, + 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, + 0, 0, 7, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, + 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, + 35, 0, 0, 10, 162, 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 128, 65, 0, 0, + 0, 2, 0, 0, 0, 166, 14, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 1, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 18, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, + 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 30, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, + 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, + 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 60, 0, 0, 7, 162, 0, 16, 0, 1, 0, 0, 0, 86, 9, 16, + 0, 3, 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 31, 0, 4, 3, 26, 0, + 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, + 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 164, + 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, + 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 79, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, + 2, 0, 0, 0, 78, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 0, 208, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, + 0, 10, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 2, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, + 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, + 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 8, 66, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, + 1, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 54, 0, + 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 21, + 0, 0, 1, 38, 0, 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, + 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, + 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, + 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, + 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, + 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, + 0, 121, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_16bpb_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_16bpb_cs.h new file mode 100644 index 0000000..641f5e0 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_16bpb_cs.h @@ -0,0 +1,381 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(4) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(1) +imad r1.y, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.y, CB0[0][2].x, r0.w +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r1.z, l(27), l(1), vThreadID.x + imad r0.y, r0.y, r1.w, r1.z + ishl r1.z, vThreadID.y, l(9) + ishr r1.z, r1.z, l(6) + and r1.z, r1.z, l(48) + iadd r1.w, r2.y, r2.z + and r2.x, r1.w, l(1) + ishr r2.y, r1.x, l(3) + bfi r1.w, l(1), l(1), r1.w, l(0) + iadd r1.w, r1.w, r2.y + bfi r1.w, l(2), l(1), r1.w, l(0) + iadd r1.w, r1.w, r2.x + bfi r2.xy, l(21, 21, 0, 0), l(9, 12, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(7, 10, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(4) + bfi r1.w, l(2), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(5, 5, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.z, l(27), l(1), vThreadID.x + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.z, r2.x, r1.w, r1.z + bfi r2.xzw, l(4, 0, 4, 4), l(4, 0, 7, 6), vThreadID.yyyy, l(0, 0, 0, 0) + bfi r2.xzw, l(24, 0, 24, 24), l(8, 0, 11, 10), r1.zzzz, r2.xxzw + ishl r1.z, vThreadID.y, l(7) + and r1.z, r1.z, l(2048) + bfi r1.z, l(12), l(0), r1.z, r2.z + and r1.w, r2.w, l(1792) + iadd r1.z, r1.z, r1.w + and r1.w, r2.y, l(2) + ishr r1.x, r1.x, l(3) + iadd r1.x, r1.x, r1.w + bfi r1.x, l(2), l(6), r1.x, l(0) + iadd r1.x, r1.z, r1.x + bfi r0.y, l(6), l(0), r2.x, r1.x + endif +else + imad r1.x, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.x, CB0[0][0].z, r0.w +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.y, r0.y, l(4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r0.z, r0.z, l(1) +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +store_uav_typed U0[0].xyzw, r1.yyyy, r2.xyzw +iadd r0.w, r1.y, l(1) +if_nz r0.x + mov r0.x, l(64) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +store_uav_typed U0[0].xyzw, r0.wwww, r2.xyzw +ret +// Approximately 96 instruction slots used +#endif + +const BYTE texture_load_16bpb_cs[] = { + 68, 88, 66, 67, 70, 63, 226, 191, 20, 148, 36, 58, 207, 1, 178, 229, 94, 61, 2, + 47, 1, 0, 0, 0, 0, 17, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 100, 16, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 40, 12, 0, + 0, 81, 0, 5, 0, 10, 3, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 114, 0, 16, 0, 2, 0, + 0, 0, 150, 5, 2, 0, 2, 64, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 1, 0, 0, 0, + 246, 139, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 8, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 10, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 2, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, + 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 2, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, + 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 50, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 34, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, + 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 8, 66, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 10, 0, 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, + 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 19, 210, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 86, 5, 2, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 140, 0, 0, 17, 210, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 24, 0, + 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 166, 10, 16, 0, + 1, 0, 0, 0, 6, 14, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, + 7, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 35, 0, 0, 9, 18, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 30, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 30, + 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, + 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, + 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 7, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, + 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 164, + 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, + 84, 148, 0, 0, 0, 96, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_16bpb_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_16bpb_scaled_cs.h new file mode 100644 index 0000000..6a5ab7c --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_16bpb_scaled_cs.h @@ -0,0 +1,419 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(4) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(1) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(3) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r1.w, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), r1.xxxx + imad r1.w, r1.w, r3.y, r3.x + ishl r2.z, r1.z, l(9) + ishr r2.z, r2.z, l(6) + and r2.z, r2.z, l(48) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r3.xy, l(21, 21, 0, 0), l(9, 12, 0, 0), r1.wwww, l(0, 0, 0, 0) + imad r2.zw, r2.zzzz, l(0, 0, 2, 16), r3.xxxy + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 7, 10), vThreadID.zzzz, r2.zzzw + bfi r1.w, l(1), l(4), r1.z, l(0) + ubfe r3.x, l(3), l(6), r2.z + and r3.y, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.x, l(32), r0.x + imad r0.x, r3.y, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r1.wwww, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 2, 0), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.w, r3.x, r1.w, r2.z + bfi r3.xzw, l(4, 0, 4, 4), l(4, 0, 7, 6), r1.zzzz, l(0, 0, 0, 0) + bfi r3.xzw, l(24, 0, 24, 24), l(8, 0, 11, 10), r1.wwww, r3.xxzw + ishl r1.w, r1.z, l(7) + and r1.w, r1.w, l(2048) + bfi r1.w, l(12), l(0), r1.w, r3.z + and r2.z, r3.w, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.x, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].xyzw +ieq r0.y, r0.y, l(1) +if_nz r0.y + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +store_uav_typed U0[0].xyzw, r1.yyyy, r3.xyzw +iadd r1.x, r1.y, l(1) +ult r1.z, l(1), r0.z +if_nz r1.z + udiv r1.z, null, r2.x, r0.z + imad r1.z, -r1.z, r0.z, r2.x + iadd r1.w, r1.z, l(1) + ieq r1.w, r0.z, r1.w + if_nz r1.w + ishl r0.z, r0.z, l(6) + ishl r1.z, r1.z, l(4) + iadd r0.z, r0.z, -r1.z + else + mov r0.z, l(16) + endif +else + mov r0.z, l(64) +endif +imul null, r0.z, r0.w, r0.z +ushr r0.z, r0.z, l(4) +iadd r0.x, r0.z, r0.x +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.y + ishl r0.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r0.xyzw, r0.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r0.xyzw, r3.xyzw +endif +store_uav_typed U0[0].xyzw, r1.xxxx, r2.xyzw +ret +// Approximately 109 instruction slots used +#endif + +const BYTE texture_load_16bpb_scaled_cs[] = { + 68, 88, 66, 67, 87, 248, 66, 207, 6, 166, 159, 88, 60, 235, 2, 29, 150, 103, 104, + 112, 1, 0, 0, 0, 236, 18, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 80, 18, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 20, 14, 0, + 0, 81, 0, 5, 0, 133, 3, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 10, 194, 0, 16, 0, 2, 0, + 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, + 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, 143, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, 0, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, + 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 12, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 6, + 4, 16, 0, 3, 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 10, 0, + 0, 0, 166, 10, 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 138, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, + 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 32, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, + 0, 0, 15, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, + 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 20, 210, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 166, 10, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 140, 0, 0, 17, 210, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 246, + 15, 16, 0, 1, 0, 0, 0, 6, 14, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 7, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, + 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, + 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, + 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 6, + 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, + 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, + 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 79, 0, 0, 7, 66, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 78, 0, 0, + 8, 66, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 10, 66, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, + 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 30, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 18, 0, 0, + 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, + 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 21, 0, 0, 1, 38, 0, 0, 8, + 0, 208, 0, 0, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, + 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, + 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, + 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, + 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, + 0, 0, 0, 109, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 42, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_32bpb_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_32bpb_cs.h new file mode 100644 index 0000000..0652770 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_32bpb_cs.h @@ -0,0 +1,412 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(2) +imad r1.x, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.x, r1.x, CB0[0][2].x, r0.w +iadd r1.x, r1.x, CB0[0][1].w +ushr r1.x, r1.x, l(4) +if_nz r0.x + if_nz r0.y + ishr r1.yzw, vThreadID.yyzy, l(0, 4, 2, 3) + ushr r2.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r0.y, r1.z, r2.x, r1.y + ibfe r2.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), vThreadID.xxxx + imad r0.y, r0.y, r2.y, r2.x + ishl r1.y, vThreadID.y, l(10) + ishr r1.y, r1.y, l(6) + and r1.y, r1.y, l(96) + iadd r1.z, r1.z, r1.w + bfi r1.w, l(1), l(1), r1.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r1.w, l(2), l(1), r1.w, l(0) + bfi r1.z, l(1), l(0), r1.z, r1.w + bfi r2.xy, l(20, 20, 0, 0), l(10, 13, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r1.yw, r1.yyyy, l(0, 2, 0, 16), r2.xxxy + bfi r1.yw, l(0, 2, 0, 2), l(0, 8, 0, 11), vThreadID.zzzz, r1.yyyw + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r2.x, l(3), l(6), r1.y + and r2.y, r1.z, l(6) + bfi r1.z, l(1), l(8), r1.z, l(0) + imad r1.z, r2.x, l(32), r1.z + imad r1.z, r2.y, l(4), r1.z + bfi r1.yw, l(0, 6, 0, 6), l(0, 0, 0, 3), r0.yyyy, r1.yyyw + bfi r0.y, l(9), l(3), r1.z, r1.w + bfi r0.y, l(6), l(0), r1.y, r0.y + else + ibfe r1.yz, l(0, 27, 29, 0), l(0, 2, 0, 0), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.y, r2.x, r1.w, r1.y + ishl r2.xz, vThreadID.yyyy, l(5, 0, 7, 0) + and r2.xz, r2.xxzx, l(448, 0, 2048, 0) + bfi r1.w, l(23), l(9), r1.y, r2.x + bfi r2.w, l(1), l(4), vThreadID.y, l(0) + iadd r1.w, r1.w, r2.w + ishl r3.xy, r2.xxxx, l(3, 2, 0, 0) + bfi r3.xy, l(23, 23, 0, 0), l(12, 11, 0, 0), r1.yyyy, r3.xyxx + imad r2.xw, r2.wwww, l(8, 0, 0, 4), r3.xxxy + bfi r1.y, l(12), l(0), r2.z, r2.x + and r2.x, r2.w, l(1792) + iadd r1.y, r1.y, r2.x + and r2.x, r2.y, l(2) + iadd r1.z, r1.z, r2.x + bfi r1.z, l(2), l(6), r1.z, l(0) + iadd r1.y, r1.y, r1.z + bfi r0.y, l(6), l(0), r1.w, r1.y + endif +else + imad r1.y, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.y, CB0[0][0].z, r0.w +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.y, r0.y, l(4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r1.yzw, r0.zzzz, l(0, 1, 2, 3) +or r0.zw, r1.zzzw, r1.yyyz +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +store_uav_typed U0[0].xyzw, r1.xxxx, r2.xyzw +iadd r1.y, r1.x, l(1) +if_nz r0.x + mov r0.x, l(32) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r0.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r0.xyzw +endif +store_uav_typed U0[0].xyzw, r1.yyyy, r2.xyzw +ret +// Approximately 106 instruction slots used +#endif + +const BYTE texture_load_32bpb_cs[] = { + 68, 88, 66, 67, 113, 119, 123, 36, 36, 108, 214, 72, 203, 201, 246, 222, 77, 233, 194, + 73, 1, 0, 0, 0, 160, 18, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 4, 18, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 200, 13, 0, + 0, 81, 0, 5, 0, 114, 3, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 226, 0, 16, 0, 1, 0, + 0, 0, 86, 6, 2, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, + 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, + 182, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 139, 0, 0, 14, + 82, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, + 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 96, 0, 0, 0, 30, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 20, 50, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, + 0, 0, 12, 162, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 6, 4, 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 162, 0, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 166, 10, 2, 0, 86, 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 10, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, + 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, + 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 32, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 162, 0, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, + 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, + 14, 98, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 27, 0, + 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 2, 0, 42, 0, 0, 9, + 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, + 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, 82, 0, 16, 0, 2, 0, + 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 2, 0, 0, 0, + 6, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, + 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, + 0, 35, 0, 0, 12, 146, 0, 16, 0, 2, 0, 0, 0, 246, 15, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, + 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 21, 0, + 0, 1, 18, 0, 0, 1, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, + 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, + 226, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 0, + 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 86, + 9, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, + 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 32, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 85, + 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, + 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, + 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, + 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, + 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, + 0, 0, 0, 106, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 34, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_32bpb_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_32bpb_scaled_cs.h new file mode 100644 index 0000000..da5c027 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_32bpb_scaled_cs.h @@ -0,0 +1,469 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(2) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(2) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +ishl r1.w, r1.x, l(2) +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r2.z, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(3, 0, 1, 0), r1.xxxx + imad r2.z, r2.z, r3.y, r3.x + ishl r3.x, r1.z, l(10) + and r3.x, r3.x, l(6144) + bfi r3.x, l(3), l(8), r1.w, r3.x + ishr r3.x, r3.x, l(6) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r2.zw, l(0, 0, 20, 20), l(0, 0, 10, 13), r2.zzzz, l(0, 0, 0, 0) + imad r2.zw, r3.xxxx, l(0, 0, 2, 16), r2.zzzw + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 8, 11), vThreadID.zzzz, r2.zzzw + bfi r3.x, l(1), l(4), r1.z, l(0) + ubfe r3.y, l(3), l(6), r2.z + and r3.z, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.y, l(32), r0.x + imad r0.x, r3.z, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r3.xxxx, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r3.z, CB0[0][0].z, l(5) + imad r2.z, r3.x, r3.z, r2.z + ishl r3.xz, r1.zzzz, l(5, 0, 7, 0) + and r3.xz, r3.xxzx, l(448, 0, 2048, 0) + bfi r3.w, l(3), l(3), r1.w, r3.x + bfi r3.w, l(23), l(9), r2.z, r3.w + bfi r4.x, l(1), l(4), r1.z, l(0) + iadd r3.w, r3.w, r4.x + ishl r4.yz, r3.xxxx, l(0, 3, 2, 0) + bfi r4.yz, l(0, 3, 3, 0), l(0, 6, 5, 0), r1.wwww, r4.yyzy + bfi r4.yz, l(0, 23, 23, 0), l(0, 12, 11, 0), r2.zzzz, r4.yyzy + imad r4.xy, r4.xxxx, l(8, 4, 0, 0), r4.yzyy + bfi r1.w, l(12), l(0), r3.z, r4.x + and r2.z, r4.y, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.w, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].xyzw +ieq r1.xzw, r0.yyyy, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +if_nz r1.z + ushr r4.xyzw, r3.xyzw, l(16, 16, 16, 16) + bfi r3.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r3.xyzw, r4.xyzw +endif +store_uav_typed U0[0].xyzw, r1.yyyy, r3.xyzw +iadd r0.y, r1.y, l(1) +ult r1.w, l(1), r0.z +if_nz r1.w + udiv r1.w, null, r2.x, r0.z + imad r1.w, -r1.w, r0.z, r2.x + iadd r2.x, r1.w, l(1) + ieq r2.x, r0.z, r2.x + if_nz r2.x + ishl r0.z, r0.z, l(5) + ishl r1.w, r1.w, l(4) + iadd r0.z, r0.z, -r1.w + else + mov r0.z, l(16) + endif +else + mov r0.z, l(32) +endif +imul null, r0.z, r0.w, r0.z +ushr r0.z, r0.z, l(4) +iadd r0.x, r0.z, r0.x +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r1.x + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r1.z + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +store_uav_typed U0[0].xyzw, r0.yyyy, r2.xyzw +ret +// Approximately 126 instruction slots used +#endif + +const BYTE texture_load_32bpb_scaled_cs[] = { + 68, 88, 66, 67, 10, 79, 63, 19, 86, 175, 185, 132, 173, 236, 60, 182, 28, 146, 110, + 38, 1, 0, 0, 0, 88, 21, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 188, 20, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 128, 16, 0, + 0, 81, 0, 5, 0, 32, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, + 0, 42, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 85, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, + 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 10, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 24, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 194, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, + 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, + 0, 2, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 166, 14, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 166, 10, + 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 9, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 15, 194, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 9, 66, 0, 16, 0, 3, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, + 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, + 82, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 23, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, + 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 4, 0, + 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 12, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, + 0, 2, 0, 0, 0, 86, 6, 16, 0, 4, 0, 0, 0, 35, 0, 0, 12, 50, 0, + 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, + 4, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, + 166, 11, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, + 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 10, 210, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, + 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 79, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 78, + 0, 0, 8, 130, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 10, 130, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, + 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, + 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 30, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 18, + 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 21, 0, 0, 1, 38, 0, + 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, + 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, + 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, + 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 126, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, + 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_64bpb_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_64bpb_cs.h new file mode 100644 index 0000000..adf2cd0 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_64bpb_cs.h @@ -0,0 +1,424 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(2) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(3) +imad r1.y, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.y, CB0[0][2].x, r0.w +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r2.xw, l(27, 0, 0, 29), l(3, 0, 0, 1), vThreadID.xxxx + imad r0.y, r0.y, r1.w, r2.x + ishl r1.z, vThreadID.y, l(11) + and r1.z, r1.z, l(0x00003000) + bfi r1.z, l(3), l(9), r1.x, r1.z + ishr r1.z, r1.z, l(6) + iadd r1.w, r2.y, r2.z + bfi r2.x, l(1), l(1), r1.w, l(0) + iadd r2.x, r2.x, r2.w + bfi r2.x, l(2), l(1), r2.x, l(0) + bfi r1.w, l(1), l(0), r1.w, r2.x + bfi r2.xy, l(19, 19, 0, 0), l(11, 14, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(9, 12, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(6) + bfi r1.w, l(1), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(6, 6, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r2.z, CB0[0][0].z, l(5) + imad r1.z, r2.x, r2.z, r1.z + ishl r2.xz, vThreadID.yyyy, l(6, 0, 7, 0) + and r2.xz, r2.xxzx, l(896, 0, 2048, 0) + bfi r2.w, l(3), l(4), r1.x, r2.x + bfi r2.w, l(22), l(10), r1.z, r2.w + bfi r3.x, l(1), l(4), vThreadID.y, l(0) + iadd r2.w, r2.w, r3.x + ishl r3.yz, r2.xxxx, l(0, 3, 2, 0) + bfi r3.yz, l(0, 3, 3, 0), l(0, 7, 6, 0), r1.xxxx, r3.yyzy + bfi r1.xz, l(22, 0, 22, 0), l(13, 0, 12, 0), r1.zzzz, r3.yyzy + imad r1.xz, r3.xxxx, l(8, 0, 4, 0), r1.xxzx + bfi r1.x, l(12), l(0), r2.z, r1.x + and r1.z, r1.z, l(1792) + iadd r1.x, r1.x, r1.z + and r1.z, r2.y, l(2) + iadd r1.z, r1.w, r1.z + bfi r1.z, l(2), l(6), r1.z, l(0) + iadd r1.x, r1.x, r1.z + bfi r0.y, l(6), l(0), r2.w, r1.x + endif +else + imad r1.x, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.x, CB0[0][0].z, r0.w +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.y, r0.y, l(4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r1.xzw, r0.zzzz, l(1, 0, 2, 3) +or r0.zw, r1.zzzw, r1.xxxz +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +store_uav_typed U0[0].xyzw, r1.yyyy, r2.xyzw +iadd r1.x, r1.y, l(1) +if_nz r0.x + mov r0.x, l(32) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r0.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r0.xyzw +endif +store_uav_typed U0[0].xyzw, r1.xxxx, r2.xyzw +ret +// Approximately 109 instruction slots used +#endif + +const BYTE texture_load_64bpb_cs[] = { + 68, 88, 66, 67, 158, 115, 29, 104, 199, 37, 248, 193, 226, 242, 109, 124, 148, 237, 57, + 79, 1, 0, 0, 0, 60, 19, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 160, 18, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 100, 14, 0, + 0, 81, 0, 5, 0, 153, 3, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 114, 0, 16, 0, 2, 0, + 0, 0, 150, 5, 2, 0, 2, 64, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 1, 0, 0, 0, + 246, 139, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 14, + 146, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 48, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 140, 0, 0, 20, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 19, 0, + 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 11, + 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, + 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 138, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, + 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 32, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, + 0, 0, 1, 139, 0, 0, 14, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, + 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, + 82, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 82, 0, + 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 128, + 3, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 22, + 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 18, 0, 16, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, + 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, + 41, 0, 0, 10, 98, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, + 0, 1, 0, 0, 0, 86, 6, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, 82, 0, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 22, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 86, 6, 16, + 0, 3, 0, 0, 0, 35, 0, 0, 12, 82, 0, 16, 0, 1, 0, 0, 0, 6, 0, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, + 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, + 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 35, 0, 0, 9, 18, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 30, + 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, + 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 86, + 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 32, 0, 0, 10, 210, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, + 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, + 0, 0, 0, 6, 8, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, + 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, + 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 18, 0, 0, 1, 54, 0, + 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, + 0, 0, 1, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, + 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 0, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 21, 0, 0, + 1, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, + 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, + 84, 65, 84, 148, 0, 0, 0, 109, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, + 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_64bpb_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_64bpb_scaled_cs.h new file mode 100644 index 0000000..d6f8e60 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_64bpb_scaled_cs.h @@ -0,0 +1,469 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(2) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(3) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(1) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +ishl r1.w, r1.x, l(1) +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r2.z, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(4, 0, 2, 0), r1.xxxx + imad r2.z, r2.z, r3.y, r3.x + ishl r3.x, r1.z, l(11) + and r3.x, r3.x, l(0x00003000) + bfi r3.x, l(3), l(9), r1.w, r3.x + ishr r3.x, r3.x, l(6) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r2.zw, l(0, 0, 19, 19), l(0, 0, 11, 14), r2.zzzz, l(0, 0, 0, 0) + imad r2.zw, r3.xxxx, l(0, 0, 2, 16), r2.zzzw + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 9, 12), vThreadID.zzzz, r2.zzzw + bfi r3.x, l(1), l(4), r1.z, l(0) + ubfe r3.y, l(3), l(6), r2.z + and r3.z, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.y, l(32), r0.x + imad r0.x, r3.z, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r3.xxxx, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 4, 2), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r3.z, CB0[0][0].z, l(5) + imad r2.z, r3.x, r3.z, r2.z + ishl r3.xz, r1.zzzz, l(6, 0, 7, 0) + and r3.xz, r3.xxzx, l(896, 0, 2048, 0) + bfi r3.w, l(3), l(4), r1.w, r3.x + bfi r3.w, l(22), l(10), r2.z, r3.w + bfi r4.x, l(1), l(4), r1.z, l(0) + iadd r3.w, r3.w, r4.x + ishl r4.yz, r3.xxxx, l(0, 3, 2, 0) + bfi r4.yz, l(0, 3, 3, 0), l(0, 7, 6, 0), r1.wwww, r4.yyzy + bfi r4.yz, l(0, 22, 22, 0), l(0, 13, 12, 0), r2.zzzz, r4.yyzy + imad r4.xy, r4.xxxx, l(8, 4, 0, 0), r4.yzyy + bfi r1.w, l(12), l(0), r3.z, r4.x + and r2.z, r4.y, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.w, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].xyzw +ieq r1.xzw, r0.yyyy, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +if_nz r1.z + ushr r4.xyzw, r3.xyzw, l(16, 16, 16, 16) + bfi r3.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r3.xyzw, r4.xyzw +endif +store_uav_typed U0[0].xyzw, r1.yyyy, r3.xyzw +iadd r0.y, r1.y, l(1) +ult r1.w, l(1), r0.z +if_nz r1.w + udiv r1.w, null, r2.x, r0.z + imad r1.w, -r1.w, r0.z, r2.x + iadd r2.x, r1.w, l(1) + ieq r2.x, r0.z, r2.x + if_nz r2.x + ishl r0.z, r0.z, l(5) + ishl r1.w, r1.w, l(4) + iadd r0.z, r0.z, -r1.w + else + mov r0.z, l(16) + endif +else + mov r0.z, l(32) +endif +imul null, r0.z, r0.w, r0.z +ushr r0.z, r0.z, l(4) +iadd r0.x, r0.z, r0.x +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r1.x + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r1.z + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +store_uav_typed U0[0].xyzw, r0.yyyy, r2.xyzw +ret +// Approximately 126 instruction slots used +#endif + +const BYTE texture_load_64bpb_scaled_cs[] = { + 68, 88, 66, 67, 18, 96, 28, 50, 154, 40, 131, 225, 117, 189, 194, 8, 25, 110, 236, + 225, 1, 0, 0, 0, 88, 21, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 188, 20, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 128, 16, 0, + 0, 81, 0, 5, 0, 32, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, + 0, 42, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 85, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, + 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 11, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 48, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 9, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 194, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 14, + 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, + 0, 2, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 166, 14, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 166, 10, + 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 9, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 15, 194, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 9, 66, 0, 16, 0, 3, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, + 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, + 82, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 128, 3, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 22, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 4, 0, + 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 13, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, + 0, 2, 0, 0, 0, 86, 6, 16, 0, 4, 0, 0, 0, 35, 0, 0, 12, 50, 0, + 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, + 4, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, + 166, 11, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, + 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 10, 210, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, + 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 79, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 78, + 0, 0, 8, 130, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 10, 130, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, + 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, + 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 30, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 18, + 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 21, 0, 0, 1, 38, 0, + 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, + 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, + 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, + 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 21, 0, 0, 1, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 126, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, + 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_8bpb_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_8bpb_cs.h new file mode 100644 index 0000000..ae75376 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_8bpb_cs.h @@ -0,0 +1,350 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint2 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 3 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(4) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +imad r0.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r0.z, r0.z, CB0[0][2].x, r1.x +iadd r0.z, r0.z, CB0[0][1].w +if_nz r0.x + if_nz r0.y + ishr r1.yzw, vThreadID.yyzy, l(0, 4, 2, 3) + ushr r0.yw, CB0[0][0].wwwz, l(0, 4, 0, 5) + imad r0.y, r1.z, r0.y, r1.y + ibfe r1.y, l(27), l(1), vThreadID.x + imad r0.y, r0.y, r0.w, r1.y + ishl r0.w, vThreadID.y, l(8) + ishr r0.w, r0.w, l(6) + iadd r1.y, r1.z, r1.w + and r1.z, r1.y, l(1) + ishr r1.w, r1.x, l(3) + bfi r1.y, l(1), l(1), r1.y, l(0) + iadd r1.y, r1.y, r1.w + bfi r1.y, l(2), l(1), r1.y, l(0) + iadd r1.y, r1.y, r1.z + and r1.zw, r0.wwww, l(0, 0, 16, 8) + bfi r0.yw, l(0, 22, 0, 22), l(0, 8, 0, 11), r0.yyyy, l(0, 0, 0, 0) + imad r0.yw, r1.zzzz, l(0, 2, 0, 16), r0.yyyw + bfi r0.yw, l(0, 5, 0, 5), l(0, 0, 0, 3), r1.wwww, r0.yyyw + bfi r0.yw, l(0, 2, 0, 2), l(0, 6, 0, 9), vThreadID.zzzz, r0.yyyw + ubfe r1.z, l(3), l(6), r0.y + and r1.w, r1.y, l(4) + bfi r1.y, l(2), l(8), r1.y, l(0) + imad r1.y, r1.z, l(32), r1.y + imad r1.y, r1.w, l(4), r1.y + bfi r0.yw, l(0, 1, 0, 1), l(0, 4, 0, 7), vThreadID.yyyy, r0.yyyw + bfi r0.w, l(9), l(3), r1.y, r0.w + bfi r0.y, l(6), l(0), r0.y, r0.w + else + ibfe r0.w, l(27), l(1), vThreadID.x + ishr r1.yz, vThreadID.yyyy, l(0, 5, 2, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r0.w, r1.y, r1.w, r0.w + ishl r1.yw, vThreadID.yyyy, l(0, 2, 0, 7) + ishl r2.x, r1.y, l(1) + and r2.x, r2.x, l(96) + bfi r2.y, l(25), l(7), r0.w, r2.x + and r1.yw, r1.yyyw, l(0, 8, 0, 2048) + iadd r2.y, r2.y, r1.y + ishl r2.xz, r2.xxxx, l(3, 0, 2, 0) + bfi r2.xz, l(25, 0, 25, 0), l(10, 0, 9, 0), r0.wwww, r2.xxzx + imad r2.xz, r1.yyyy, l(8, 0, 4, 0), r2.xxzx + bfi r2.xyz, l(1, 1, 1, 0), l(7, 4, 6, 0), vThreadID.yyyy, r2.xyzx + bfi r0.w, l(12), l(0), r1.w, r2.x + and r1.y, r2.z, l(1792) + iadd r0.w, r0.w, r1.y + and r1.y, r1.z, l(2) + ishr r1.z, r1.x, l(3) + iadd r1.y, r1.z, r1.y + bfi r1.y, l(2), l(6), r1.y, l(0) + iadd r0.w, r0.w, r1.y + bfi r0.y, l(6), l(0), r2.y, r0.w + endif +else + imad r0.w, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r0.w, CB0[0][0].z, r1.x +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.yz, r0.yyzy, l(0, 3, 4, 0) +ld r1.xy, r0.yyyy, T0[0].xyzw +if_nz r0.x + mov r0.x, l(64) +else + mov r0.x, l(8) +endif +ushr r0.x, r0.x, l(3) +iadd r0.x, r0.x, r0.y +ld r1.zw, r0.xxxx, T0[0].zwxy +store_uav_typed U0[0].xyzw, r0.zzzz, r1.xyzw +ret +// Approximately 82 instruction slots used +#endif + +const BYTE texture_load_8bpb_cs[] = { + 68, 88, 66, 67, 40, 44, 23, 106, 122, 80, 54, 51, 116, 33, 60, 249, 151, 94, 150, + 231, 1, 0, 0, 0, 192, 15, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 36, 15, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 232, 10, 0, + 0, 81, 0, 5, 0, 186, 2, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 3, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 35, 0, 0, + 9, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 66, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, + 0, 30, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 31, + 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 0, 9, 226, 0, 16, 0, 1, 0, 0, 0, 86, 6, 2, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, 0, + 0, 0, 85, 0, 0, 12, 162, 0, 16, 0, 0, 0, 0, 0, 246, 139, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 139, 0, 0, 8, 34, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 10, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 41, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 2, 0, 1, + 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, + 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, + 10, 194, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 140, + 0, 0, 20, 162, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 22, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 8, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 86, 5, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 35, 0, 0, 12, 162, 0, 16, 0, 0, 0, 0, 0, 166, 10, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 86, 13, 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 162, 0, + 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 86, 13, 16, + 0, 0, 0, 0, 0, 140, 0, 0, 16, 162, 0, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 166, 10, 2, 0, 86, 13, 16, 0, 0, 0, 0, 0, 138, 0, 0, 9, 66, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 8, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 140, 0, 0, 16, 162, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 86, 5, 2, + 0, 86, 13, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 11, + 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 18, 0, 0, 1, 139, 0, 0, 8, 130, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 27, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 2, 0, + 42, 0, 0, 9, 98, 0, 16, 0, 1, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, + 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 9, 162, 0, + 16, 0, 1, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, + 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 96, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, + 10, 162, 0, 16, 0, 1, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 30, + 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 82, 0, 16, 0, 2, 0, 0, + 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 82, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 6, 2, 16, 0, 2, 0, + 0, 0, 35, 0, 0, 12, 82, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 6, 2, 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 114, 0, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 0, 0, 86, 5, 2, 0, 70, 2, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, + 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 3, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 18, 0, 0, 1, 35, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 2, + 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, + 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 98, 0, 16, 0, 0, + 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 50, 0, 16, + 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, + 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 8, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, + 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 194, 0, 16, 0, 1, 0, 0, + 0, 6, 0, 16, 0, 0, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, + 10, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 148, 0, 0, 0, 82, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 14, 0, 0, 0, 5, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_8bpb_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_8bpb_scaled_cs.h new file mode 100644 index 0000000..e766664 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_8bpb_scaled_cs.h @@ -0,0 +1,392 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint2 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(4) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yz, l(0, 3, 3, 0), l(0, 4, 7, 0), CB0[0][0].xxxx +imad r0.w, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r0.w, r0.w, CB0[0][2].x, r1.x +iadd r0.w, r0.w, CB0[0][1].w +ushr r1.x, r1.x, l(3) +mov r1.y, vThreadID.y +udiv r1.zw, null, r1.xxxy, r0.yyyz +if_nz r0.x + ishr r2.xy, r1.wwww, l(4, 3, 0, 0) + ishr r0.x, vThreadID.z, l(2) + ushr r2.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r2.x, r0.x, r2.z, r2.x + ibfe r3.xy, l(27, 29, 0, 0), l(2, 0, 0, 0), r1.zzzz + imad r2.x, r2.x, r2.w, r3.x + ishl r2.z, r1.w, l(8) + ishr r2.z, r2.z, l(6) + iadd r0.x, r0.x, r2.y + bfi r2.y, l(1), l(1), r0.x, l(0) + iadd r2.y, r2.y, r3.y + bfi r2.xyw, l(22, 2, 0, 22), l(8, 1, 0, 11), r2.xyxx, l(0, 0, 0, 0) + bfi r0.x, l(1), l(0), r0.x, r2.y + and r2.yz, r2.zzzz, l(0, 16, 8, 0) + imad r2.xy, r2.yyyy, l(2, 16, 0, 0), r2.xwxx + bfi r2.xy, l(5, 5, 0, 0), l(0, 3, 0, 0), r2.zzzz, r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(6, 9, 0, 0), vThreadID.zzzz, r2.xyxx + ubfe r2.z, l(3), l(6), r2.x + and r2.w, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r2.z, l(32), r0.x + imad r0.x, r2.w, l(4), r0.x + bfi r2.xy, l(1, 1, 0, 0), l(4, 7, 0, 0), r1.wwww, r2.xyxx + bfi r0.x, l(9), l(3), r0.x, r2.y + bfi r0.x, l(6), l(0), r2.x, r0.x +else + ibfe r2.xy, l(27, 29, 0, 0), l(2, 0, 0, 0), r1.zzzz + ishr r2.zw, r1.wwww, l(0, 0, 5, 2) + ushr r3.x, CB0[0][0].z, l(5) + imad r2.x, r2.z, r3.x, r2.x + ishl r3.xy, r1.wwww, l(2, 7, 0, 0) + ishl r2.z, r3.x, l(1) + and r2.z, r2.z, l(96) + bfi r3.z, l(25), l(7), r2.x, r2.z + and r3.xy, r3.xyxx, l(8, 2048, 0, 0) + iadd r3.z, r3.z, r3.x + bfi r3.z, l(1), l(4), r1.w, r3.z + ishl r4.xy, r2.zzzz, l(3, 2, 0, 0) + bfi r2.xz, l(25, 0, 25, 0), l(10, 0, 9, 0), r2.xxxx, r4.xxyx + imad r2.xz, r3.xxxx, l(8, 0, 4, 0), r2.xxzx + bfi r2.xz, l(1, 0, 1, 0), l(7, 0, 6, 0), r1.wwww, r2.xxzx + bfi r2.x, l(12), l(0), r3.y, r2.x + and r2.z, r2.z, l(1792) + iadd r2.x, r2.x, r2.z + and r2.z, r2.w, l(2) + iadd r2.y, r2.y, r2.z + bfi r2.y, l(2), l(6), r2.y, l(0) + iadd r2.x, r2.x, r2.y + bfi r0.x, l(6), l(0), r3.z, r2.x +endif +imad r1.yz, -r1.zzwz, r0.yyzy, r1.xxyx +imul null, r1.w, r0.z, r0.y +imad r1.y, r1.y, r0.z, r1.z +ishl r1.y, r1.y, l(3) +imad r0.x, r0.x, r1.w, r1.y +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.xw, r0.xxxw, l(3, 0, 0, 4) +ld r2.xy, r0.xxxx, T0[0].xyzw +ult r1.y, l(1), r0.y +if_nz r1.y + udiv r1.y, null, r1.x, r0.y + imad r1.x, -r1.y, r0.y, r1.x + iadd r1.y, r1.x, l(1) + ieq r1.y, r0.y, r1.y + if_nz r1.y + ishl r0.y, r0.y, l(6) + ishl r1.x, r1.x, l(3) + iadd r0.y, r0.y, -r1.x + else + mov r0.y, l(8) + endif +else + mov r0.y, l(64) +endif +imul null, r0.y, r0.z, r0.y +ushr r0.y, r0.y, l(3) +iadd r0.x, r0.y, r0.x +ld r2.zw, r0.xxxx, T0[0].zwxy +store_uav_typed U0[0].xyzw, r0.wwww, r2.xyzw +ret +// Approximately 96 instruction slots used +#endif + +const BYTE texture_load_8bpb_scaled_cs[] = { + 68, 88, 66, 67, 197, 166, 177, 165, 113, 197, 117, 164, 80, 31, 113, 208, 208, 117, 226, + 197, 1, 0, 0, 0, 216, 17, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 60, 17, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 0, 13, 0, + 0, 81, 0, 5, 0, 64, 3, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 98, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, + 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 130, 0, + 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 30, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, + 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 2, 0, 78, 0, 0, 8, 194, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 86, 9, 16, 0, 0, 0, 0, 0, 31, 0, + 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 10, 50, 0, 16, 0, 2, + 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 6, 18, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, + 0, 12, 194, 0, 16, 0, 2, 0, 0, 0, 246, 139, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 139, 0, 0, 15, 50, 0, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 166, 10, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, + 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, + 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, + 34, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 20, 178, 0, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 22, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 22, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 11, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, + 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, + 0, 0, 1, 0, 0, 10, 98, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 198, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 17, 50, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 50, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, 0, 0, 0, 138, 0, 0, 9, 66, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, + 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, + 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 4, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, + 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, + 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, + 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 15, 50, 0, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 42, 0, 0, 10, 194, + 0, 16, 0, 2, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 85, 0, 0, + 9, 18, 0, 16, 0, 3, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 18, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, + 0, 3, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, + 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 96, 0, 0, 0, 140, 0, 0, 11, 66, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 1, 64, 0, 0, 7, + 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 1, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, + 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, + 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 41, 0, + 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 17, 82, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 25, 0, 0, + 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, + 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 2, + 0, 0, 0, 6, 1, 16, 0, 4, 0, 0, 0, 35, 0, 0, 12, 82, 0, 16, 0, + 2, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 6, 2, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 17, 82, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, + 0, 1, 0, 0, 0, 6, 2, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 11, 34, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 21, 0, 0, 1, 35, 0, 0, 10, 98, 0, 16, 0, 1, 0, 0, 0, 166, 11, 16, + 128, 65, 0, 0, 0, 1, 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 6, 1, + 16, 0, 1, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 30, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 85, 0, 0, 10, 146, 0, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 45, 0, 0, 8, 50, 0, 16, 0, 2, 0, 0, 0, 6, 0, + 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, + 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, + 0, 78, 0, 0, 8, 34, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 10, 18, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, + 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, + 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, + 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, + 0, 18, 0, 0, 1, 54, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 8, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 54, 0, 0, 5, 34, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 21, 0, 0, 1, + 38, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, + 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 194, 0, 16, + 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 230, 116, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 96, 0, 0, 0, 5, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 0, 17, 0, + 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_bgrg8_rgb8_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_bgrg8_rgb8_cs.h new file mode 100644 index 0000000..3aa512a --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_bgrg8_rgb8_cs.h @@ -0,0 +1,516 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(3) +imad r1.y, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r0.w, r1.y, CB0[0][2].x, r0.w +iadd r0.w, r0.w, CB0[0][1].w +if_nz r0.x + if_nz r0.y + ishr r1.yzw, vThreadID.yyzy, l(0, 4, 2, 3) + ushr r2.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r0.y, r1.z, r2.x, r1.y + ibfe r2.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), vThreadID.xxxx + imad r0.y, r0.y, r2.y, r2.x + ishl r1.y, vThreadID.y, l(10) + ishr r1.y, r1.y, l(6) + and r1.y, r1.y, l(96) + iadd r1.z, r1.z, r1.w + bfi r1.w, l(1), l(1), r1.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r1.w, l(2), l(1), r1.w, l(0) + bfi r1.z, l(1), l(0), r1.z, r1.w + bfi r2.xy, l(20, 20, 0, 0), l(10, 13, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r1.yw, r1.yyyy, l(0, 2, 0, 16), r2.xxxy + bfi r1.yw, l(0, 2, 0, 2), l(0, 8, 0, 11), vThreadID.zzzz, r1.yyyw + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r2.x, l(3), l(6), r1.y + and r2.y, r1.z, l(6) + bfi r1.z, l(1), l(8), r1.z, l(0) + imad r1.z, r2.x, l(32), r1.z + imad r1.z, r2.y, l(4), r1.z + bfi r1.yw, l(0, 6, 0, 6), l(0, 0, 0, 3), r0.yyyy, r1.yyyw + bfi r0.y, l(9), l(3), r1.z, r1.w + bfi r0.y, l(6), l(0), r1.y, r0.y + else + ibfe r1.yz, l(0, 27, 29, 0), l(0, 2, 0, 0), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.y, r2.x, r1.w, r1.y + ishl r2.xz, vThreadID.yyyy, l(5, 0, 7, 0) + and r2.xz, r2.xxzx, l(448, 0, 2048, 0) + bfi r1.w, l(23), l(9), r1.y, r2.x + bfi r2.w, l(1), l(4), vThreadID.y, l(0) + iadd r1.w, r1.w, r2.w + ishl r3.xy, r2.xxxx, l(3, 2, 0, 0) + bfi r3.xy, l(23, 23, 0, 0), l(12, 11, 0, 0), r1.yyyy, r3.xyxx + imad r2.xw, r2.wwww, l(8, 0, 0, 4), r3.xxxy + bfi r1.y, l(12), l(0), r2.z, r2.x + and r2.x, r2.w, l(1792) + iadd r1.y, r1.y, r2.x + and r2.x, r2.y, l(2) + iadd r1.z, r1.z, r2.x + bfi r1.z, l(2), l(6), r1.z, l(0) + iadd r1.y, r1.y, r1.z + bfi r0.y, l(6), l(0), r1.w, r1.y + endif +else + ishl r1.x, r1.x, l(2) + imad r1.y, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.y, CB0[0][0].z, r1.x +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.yw, r0.yyyw, l(0, 4, 0, 4) +ld r1.xyzw, r0.yyyy, T0[0].xyzw +ieq r2.xyz, r0.zzzz, l(1, 2, 3, 0) +or r2.xy, r2.yzyy, r2.xyxx +if_nz r2.x + ishl r3.xyzw, r1.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r1.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r1.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r2.y + ushr r3.xyzw, r1.xyzw, l(16, 16, 16, 16) + bfi r1.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r1.xyzw, r3.xyzw +endif +ushr r2.zw, r1.xxxy, l(0, 0, 16, 16) +bfi r3.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r1.xxyy, l(0, 0, 0, 0) +imul null, r3.xyzw, r3.xyzw, l(257, 257, 257, 257) +bfi r3.xyzw, l(8, 8, 8, 8), l(0, 0, 0, 0), r2.zzww, r3.xyzw +and r4.xz, r1.xxyx, l(0x0000ff00, 0, 0x0000ff00, 0) +and r4.yw, r2.zzzw, l(0, 0x0000ff00, 0, 0x0000ff00) +iadd r3.xyzw, r3.xyzw, r4.xyzw +ushr r1.xy, r1.zwzz, l(16, 16, 0, 0) +bfi r4.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r1.zzww, l(0, 0, 0, 0) +imul null, r4.xyzw, r4.xyzw, l(257, 257, 257, 257) +bfi r4.xyzw, l(8, 8, 8, 8), l(0, 0, 0, 0), r1.xxyy, r4.xyzw +and r5.xyzw, r1.zxwy, l(0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00) +iadd r1.xyzw, r4.xyzw, r5.xyzw +store_uav_typed U0[0].xyzw, r0.wwww, r3.xyzw +iadd r3.xyz, r0.wwww, l(1, 2, 3, 0) +store_uav_typed U0[0].xyzw, r3.xxxx, r1.xyzw +if_nz r0.x + mov r0.x, l(32) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r1.xyzw, r0.xxxx, T0[0].xyzw +if_nz r2.x + ishl r4.xyzw, r1.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r1.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r1.xyzw, r4.xyzw, r5.xyzw +endif +if_nz r2.y + ushr r2.xyzw, r1.xyzw, l(16, 16, 16, 16) + bfi r1.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r1.xyzw, r2.xyzw +endif +ushr r0.xy, r1.xyxx, l(16, 16, 0, 0) +bfi r2.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r1.xxyy, l(0, 0, 0, 0) +imul null, r2.xyzw, r2.xyzw, l(257, 257, 257, 257) +bfi r2.xyzw, l(8, 8, 8, 8), l(0, 0, 0, 0), r0.xxyy, r2.xyzw +and r4.xz, r1.xxyx, l(0x0000ff00, 0, 0x0000ff00, 0) +and r4.yw, r0.xxxy, l(0, 0x0000ff00, 0, 0x0000ff00) +iadd r2.xyzw, r2.xyzw, r4.xyzw +ushr r0.xy, r1.zwzz, l(16, 16, 0, 0) +bfi r4.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r1.zzww, l(0, 0, 0, 0) +imul null, r4.xyzw, r4.xyzw, l(257, 257, 257, 257) +bfi r4.xyzw, l(8, 8, 8, 8), l(0, 0, 0, 0), r0.xxyy, r4.xyzw +and r1.xz, r1.zzwz, l(0x0000ff00, 0, 0x0000ff00, 0) +and r1.yw, r0.xxxy, l(0, 0x0000ff00, 0, 0x0000ff00) +iadd r1.xyzw, r1.xyzw, r4.xyzw +store_uav_typed U0[0].xyzw, r3.yyyy, r2.xyzw +store_uav_typed U0[0].xyzw, r3.zzzz, r1.xyzw +ret +// Approximately 135 instruction slots used +#endif + +const BYTE texture_load_bgrg8_rgb8_cs[] = { + 68, 88, 66, 67, 168, 82, 117, 230, 99, 127, 248, 61, 253, 160, 3, 158, 3, 127, 67, + 237, 1, 0, 0, 0, 32, 24, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 132, 23, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 72, 19, 0, + 0, 81, 0, 5, 0, 210, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 130, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, + 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 0, 9, 226, 0, 16, 0, 1, 0, 0, 0, 86, 6, 2, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 85, 0, + 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 182, 143, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 139, 0, 0, 14, 82, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 41, 0, 0, 6, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, + 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 96, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, + 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 162, 0, 16, 0, 1, 0, + 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 16, 162, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 166, 10, 2, 0, 86, + 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, 18, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, + 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 8, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, + 0, 0, 17, 162, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, + 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 14, 98, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, 86, + 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, + 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 41, 0, 0, 9, 82, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, + 0, 1, 64, 0, 0, 9, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 130, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 41, 0, + 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 17, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, + 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 12, 0, + 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, + 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 146, 0, 16, 0, + 2, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 6, 4, 16, 0, 3, 0, + 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 41, 0, 0, + 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, + 0, 0, 0, 0, 0, 86, 13, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, + 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 2, 0, 0, + 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 2, + 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, + 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, + 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, + 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 21, 0, 0, 1, 85, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 6, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 11, 0, 208, 0, 0, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 15, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 4, 0, + 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 0, 0, + 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 162, 0, 16, 0, + 4, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 30, 0, 0, 7, 242, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, + 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 166, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 11, 0, 208, 0, 0, 242, 0, + 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, + 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 140, 0, 0, 17, + 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 5, 16, 0, 1, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 38, 7, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 255, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 1, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 164, + 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, + 0, 3, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 8, 242, + 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, + 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, + 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 7, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 1, + 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, + 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, + 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 31, + 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 10, 50, 0, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 6, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 11, + 0, 208, 0, 0, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, + 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 5, 16, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 1, 0, 0, 10, 82, 0, + 16, 0, 4, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, + 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 30, 0, + 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, + 230, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 166, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 11, 0, 208, + 0, 0, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, + 140, 0, 0, 17, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 5, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, + 1, 0, 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, + 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 162, 0, + 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 30, 0, 0, 7, + 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 164, + 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, + 84, 148, 0, 0, 0, 135, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_bgrg8_rgbg8_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_bgrg8_rgbg8_cs.h new file mode 100644 index 0000000..065b635 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_bgrg8_rgbg8_cs.h @@ -0,0 +1,441 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(2) +imad r1.x, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.x, r1.x, CB0[0][2].x, r0.w +iadd r1.x, r1.x, CB0[0][1].w +ushr r1.x, r1.x, l(4) +if_nz r0.x + if_nz r0.y + ishr r1.yzw, vThreadID.yyzy, l(0, 4, 2, 3) + ushr r2.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r0.y, r1.z, r2.x, r1.y + ibfe r2.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), vThreadID.xxxx + imad r0.y, r0.y, r2.y, r2.x + ishl r1.y, vThreadID.y, l(10) + ishr r1.y, r1.y, l(6) + and r1.y, r1.y, l(96) + iadd r1.z, r1.z, r1.w + bfi r1.w, l(1), l(1), r1.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r1.w, l(2), l(1), r1.w, l(0) + bfi r1.z, l(1), l(0), r1.z, r1.w + bfi r2.xy, l(20, 20, 0, 0), l(10, 13, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r1.yw, r1.yyyy, l(0, 2, 0, 16), r2.xxxy + bfi r1.yw, l(0, 2, 0, 2), l(0, 8, 0, 11), vThreadID.zzzz, r1.yyyw + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r2.x, l(3), l(6), r1.y + and r2.y, r1.z, l(6) + bfi r1.z, l(1), l(8), r1.z, l(0) + imad r1.z, r2.x, l(32), r1.z + imad r1.z, r2.y, l(4), r1.z + bfi r1.yw, l(0, 6, 0, 6), l(0, 0, 0, 3), r0.yyyy, r1.yyyw + bfi r0.y, l(9), l(3), r1.z, r1.w + bfi r0.y, l(6), l(0), r1.y, r0.y + else + ibfe r1.yz, l(0, 27, 29, 0), l(0, 2, 0, 0), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.y, r2.x, r1.w, r1.y + ishl r2.xz, vThreadID.yyyy, l(5, 0, 7, 0) + and r2.xz, r2.xxzx, l(448, 0, 2048, 0) + bfi r1.w, l(23), l(9), r1.y, r2.x + bfi r2.w, l(1), l(4), vThreadID.y, l(0) + iadd r1.w, r1.w, r2.w + ishl r3.xy, r2.xxxx, l(3, 2, 0, 0) + bfi r3.xy, l(23, 23, 0, 0), l(12, 11, 0, 0), r1.yyyy, r3.xyxx + imad r2.xw, r2.wwww, l(8, 0, 0, 4), r3.xxxy + bfi r1.y, l(12), l(0), r2.z, r2.x + and r2.x, r2.w, l(1792) + iadd r1.y, r1.y, r2.x + and r2.x, r2.y, l(2) + iadd r1.z, r1.z, r2.x + bfi r1.z, l(2), l(6), r1.z, l(0) + iadd r1.y, r1.y, r1.z + bfi r0.y, l(6), l(0), r1.w, r1.y + endif +else + imad r1.y, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.y, CB0[0][0].z, r0.w +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.y, r0.y, l(4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r1.yzw, r0.zzzz, l(0, 1, 2, 3) +or r0.zw, r1.zzzw, r1.yyyz +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +and r3.xyzw, r2.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) +bfi r3.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +ubfe r2.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r2.xyzw +iadd r2.xyzw, r3.xyzw, r2.xyzw +store_uav_typed U0[0].xyzw, r1.xxxx, r2.xyzw +iadd r1.y, r1.x, l(1) +if_nz r0.x + mov r0.x, l(32) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r0.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r0.xyzw +endif +and r0.xyzw, r2.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) +bfi r0.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r2.xyzw, r0.xyzw +ubfe r2.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r2.xyzw +iadd r0.xyzw, r0.xyzw, r2.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r0.xyzw +ret +// Approximately 114 instruction slots used +#endif + +const BYTE texture_load_bgrg8_rgbg8_cs[] = { + 68, 88, 66, 67, 78, 24, 96, 17, 12, 86, 141, 27, 188, 137, 190, 246, 116, 36, 171, + 126, 1, 0, 0, 0, 40, 20, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 140, 19, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 80, 15, 0, + 0, 81, 0, 5, 0, 212, 3, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 226, 0, 16, 0, 1, 0, + 0, 0, 86, 6, 2, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, + 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, + 182, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 139, 0, 0, 14, + 82, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, + 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 96, 0, 0, 0, 30, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 20, 50, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, + 0, 0, 12, 162, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 6, 4, 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 162, 0, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 166, 10, 2, 0, 86, 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 10, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, + 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, + 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 32, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 162, 0, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, + 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, + 14, 98, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 27, 0, + 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 2, 0, 42, 0, 0, 9, + 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, + 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, 82, 0, 16, 0, 2, 0, + 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 2, 0, 0, 0, + 6, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, + 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, + 0, 35, 0, 0, 12, 146, 0, 16, 0, 2, 0, 0, 0, 246, 15, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, + 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 21, 0, + 0, 1, 18, 0, 0, 1, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, + 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, + 226, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 0, + 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 86, + 9, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 140, 0, 0, 17, 242, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 164, + 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, + 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 18, 0, 0, 1, + 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, + 0, 21, 0, 0, 1, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, + 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, + 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, + 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, + 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, + 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 21, + 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 140, 0, 0, 17, 242, 0, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 138, 0, 0, + 15, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 30, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 0, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 114, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, + 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_ctx1_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_ctx1_cs.h new file mode 100644 index 0000000..4652401 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_ctx1_cs.h @@ -0,0 +1,1373 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 8 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(2) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r1.yz, r1.xxyx, l(0, 2, 2, 0) +ishl r0.w, r1.y, l(1) +imad r1.y, vThreadID.z, CB0[0][2].y, r1.z +imad r0.w, r1.y, CB0[0][2].x, r0.w +iadd r0.w, r0.w, CB0[0][1].w +ushr r1.y, CB0[0][2].x, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r2.xw, l(27, 0, 0, 29), l(3, 0, 0, 1), vThreadID.xxxx + imad r0.y, r0.y, r1.w, r2.x + ishl r1.z, vThreadID.y, l(11) + and r1.z, r1.z, l(0x00003000) + bfi r1.z, l(3), l(9), r1.x, r1.z + ishr r1.z, r1.z, l(6) + iadd r1.w, r2.y, r2.z + bfi r2.x, l(1), l(1), r1.w, l(0) + iadd r2.x, r2.x, r2.w + bfi r2.x, l(2), l(1), r2.x, l(0) + bfi r1.w, l(1), l(0), r1.w, r2.x + bfi r2.xy, l(19, 19, 0, 0), l(11, 14, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(9, 12, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(6) + bfi r1.w, l(1), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(6, 6, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r2.z, CB0[0][0].z, l(5) + imad r1.z, r2.x, r2.z, r1.z + ishl r2.xz, vThreadID.yyyy, l(6, 0, 7, 0) + and r2.xz, r2.xxzx, l(896, 0, 2048, 0) + bfi r2.w, l(3), l(4), r1.x, r2.x + bfi r2.w, l(22), l(10), r1.z, r2.w + bfi r3.x, l(1), l(4), vThreadID.y, l(0) + iadd r2.w, r2.w, r3.x + ishl r3.yz, r2.xxxx, l(0, 3, 2, 0) + bfi r3.yz, l(0, 3, 3, 0), l(0, 7, 6, 0), r1.xxxx, r3.yyzy + bfi r3.yz, l(0, 22, 22, 0), l(0, 13, 12, 0), r1.zzzz, r3.yyzy + imad r3.xy, r3.xxxx, l(8, 4, 0, 0), r3.yzyy + bfi r1.z, l(12), l(0), r2.z, r3.x + and r2.x, r3.y, l(1792) + iadd r1.z, r1.z, r2.x + and r2.x, r2.y, l(2) + iadd r1.w, r1.w, r2.x + bfi r1.w, l(2), l(6), r1.w, l(0) + iadd r1.z, r1.z, r1.w + bfi r0.y, l(6), l(0), r2.w, r1.z + endif +else + ishl r1.x, r1.x, l(3) + imad r1.z, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.z, CB0[0][0].z, r1.x +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.yw, r0.yyyw, l(0, 4, 0, 4) +ld r2.xyzw, r0.yyyy, T0[0].xzyw +ieq r1.xzw, r0.zzzz, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r3.xyzw, r2.xzyw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xzyw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xzyw, r4.xzyw +endif +if_nz r1.z + ushr r3.xyzw, r2.xzyw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xzyw +endif +ubfe r3.xy, l(8, 8, 0, 0), l(8, 8, 0, 0), r2.xyxx +bfi r3.zw, l(0, 0, 8, 8), l(0, 0, 16, 16), r2.xxxy, l(0, 0, 0, 0) +iadd r3.xy, r3.zwzz, r3.xyxx +ushr r3.zw, r2.xxxy, l(0, 0, 24, 24) +and r2.xy, r2.xyxx, l(0x00ff0000, 0x00ff0000, 0, 0) +iadd r2.xy, r2.xyxx, r3.zwzz +ishl r3.zw, r2.zzzw, l(0, 0, 1, 1) +and r3.zw, r3.zzzw, l(0, 0, 0xaaaaaaaa, 0xaaaaaaaa) +ushr r2.zw, r2.zzzw, l(0, 0, 1, 1) +and r2.zw, r2.zzzw, l(0, 0, 0x55555555, 0x55555555) +iadd r2.zw, r2.zzzw, r3.zzzw +ushr r3.zw, r2.zzzw, l(0, 0, 1, 1) +and r3.zw, r3.zzzw, l(0, 0, 0x55555555, 0x55555555) +xor r2.zw, r2.zzzw, r3.zzzw +not r4.xy, r2.wzww +ushr r5.yzw, r4.yyyy, l(0, 4, 2, 6) +mov r5.x, r4.y +and r5.xyzw, r5.xyzw, l(3, 3, 3, 3) +ushr r6.yzw, r2.zzzz, l(0, 4, 2, 6) +mov r6.x, r2.z +and r6.xyzw, r6.xyzw, l(3, 3, 3, 3) +imul null, r6.xyzw, r2.xxxx, r6.xyzw +imad r5.xyzw, r5.xyzw, r3.xxxx, r6.xyzw +and r6.xyzw, r5.xyzw, l(2047, 2047, 2047, 2047) +udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) +ushr r5.xyzw, r5.xyzw, l(16, 16, 16, 16) +udiv r5.xyzw, null, r5.xyzw, l(3, 3, 3, 3) +ishl r5.xyzw, r5.xyzw, l(8, 8, 24, 24) +or r3.zw, r5.xxxy, r6.xxxy +ishl r5.xy, r6.zwzz, l(16, 16, 0, 0) +or r3.zw, r3.zzzw, r5.xxxy +or r5.xy, r5.zwzz, r3.zwzz +ushr r4.yzw, r4.xxxx, l(0, 4, 2, 6) +and r4.xyzw, r4.xyzw, l(3, 3, 3, 3) +ushr r6.yzw, r2.wwww, l(0, 4, 2, 6) +mov r6.x, r2.w +and r6.xyzw, r6.xyzw, l(3, 3, 3, 3) +imul null, r6.xyzw, r2.yyyy, r6.xyzw +imad r4.xyzw, r4.xyzw, r3.yyyy, r6.xyzw +and r6.xyzw, r4.xyzw, l(2047, 2047, 2047, 2047) +udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) +ushr r4.xyzw, r4.xyzw, l(16, 16, 16, 16) +udiv r4.xyzw, null, r4.xyzw, l(3, 3, 3, 3) +ishl r4.xyzw, r4.xyzw, l(8, 8, 24, 24) +or r3.zw, r4.xxxy, r6.xxxy +ishl r4.xy, r6.zwzz, l(16, 16, 0, 0) +or r3.zw, r3.zzzw, r4.xxxy +or r5.zw, r4.zzzw, r3.zzzw +store_uav_typed U0[0].xyzw, r0.wwww, r5.xyzw +imad r0.z, vThreadID.y, l(4), l(1) +ult r0.z, r0.z, CB0[0][2].y +if_nz r0.z + iadd r1.w, r1.y, r0.w + ushr r4.xy, r2.wzww, l(8, 8, 0, 0) + not r5.xy, r4.xyxx + ushr r6.yzw, r5.yyyy, l(0, 4, 2, 6) + mov r6.x, r5.y + and r6.xyzw, r6.xyzw, l(3, 3, 3, 3) + ushr r7.yzw, r4.yyyy, l(0, 4, 2, 6) + mov r7.x, r4.y + and r7.xyzw, r7.xyzw, l(3, 3, 3, 3) + imul null, r7.xyzw, r2.xxxx, r7.xyzw + imad r6.xyzw, r6.xyzw, r3.xxxx, r7.xyzw + and r7.xyzw, r6.xyzw, l(2047, 2047, 2047, 2047) + udiv r7.xyzw, null, r7.xyzw, l(3, 3, 3, 3) + ushr r6.xyzw, r6.xyzw, l(16, 16, 16, 16) + udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) + ishl r6.xyzw, r6.xyzw, l(8, 8, 24, 24) + or r3.zw, r6.xxxy, r7.xxxy + ishl r6.xy, r7.zwzz, l(16, 16, 0, 0) + or r3.zw, r3.zzzw, r6.xxxy + or r6.xy, r6.zwzz, r3.zwzz + ushr r5.yzw, r5.xxxx, l(0, 4, 2, 6) + and r5.xyzw, r5.xyzw, l(3, 3, 3, 3) + ushr r4.yzw, r4.xxxx, l(0, 4, 2, 6) + and r4.xyzw, r4.xyzw, l(3, 3, 3, 3) + imul null, r4.xyzw, r2.yyyy, r4.xyzw + imad r4.xyzw, r5.xyzw, r3.yyyy, r4.xyzw + and r5.xyzw, r4.xyzw, l(2047, 2047, 2047, 2047) + udiv r5.xyzw, null, r5.xyzw, l(3, 3, 3, 3) + ushr r4.xyzw, r4.xyzw, l(16, 16, 16, 16) + udiv r4.xyzw, null, r4.xyzw, l(3, 3, 3, 3) + ishl r4.xyzw, r4.xyzw, l(8, 8, 24, 24) + or r3.zw, r4.xxxy, r5.xxxy + ishl r4.xy, r5.zwzz, l(16, 16, 0, 0) + or r3.zw, r3.zzzw, r4.xxxy + or r6.zw, r4.zzzw, r3.zzzw + store_uav_typed U0[0].xyzw, r1.wwww, r6.xyzw + imad r1.w, vThreadID.y, l(4), l(2) + ult r1.w, r1.w, CB0[0][2].y + if_nz r1.w + ishl r1.w, r1.y, l(1) + iadd r1.w, r0.w, r1.w + ushr r4.xy, r2.wzww, l(16, 16, 0, 0) + not r5.xy, r4.xyxx + ushr r6.yzw, r5.yyyy, l(0, 4, 2, 6) + mov r6.x, r5.y + and r6.xyzw, r6.xyzw, l(3, 3, 3, 3) + ushr r7.yzw, r4.yyyy, l(0, 4, 2, 6) + mov r7.x, r4.y + and r7.xyzw, r7.xyzw, l(3, 3, 3, 3) + imul null, r7.xyzw, r2.xxxx, r7.xyzw + imad r6.xyzw, r6.xyzw, r3.xxxx, r7.xyzw + and r7.xyzw, r6.xyzw, l(2047, 2047, 2047, 2047) + udiv r7.xyzw, null, r7.xyzw, l(3, 3, 3, 3) + ushr r6.xyzw, r6.xyzw, l(16, 16, 16, 16) + udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) + ishl r6.xyzw, r6.xyzw, l(8, 8, 24, 24) + or r3.zw, r6.xxxy, r7.xxxy + ishl r6.xy, r7.zwzz, l(16, 16, 0, 0) + or r3.zw, r3.zzzw, r6.xxxy + or r6.xy, r6.zwzz, r3.zwzz + ushr r5.yzw, r5.xxxx, l(0, 4, 2, 6) + and r5.xyzw, r5.xyzw, l(3, 3, 3, 3) + ushr r4.yzw, r4.xxxx, l(0, 4, 2, 6) + and r4.xyzw, r4.xyzw, l(3, 3, 3, 3) + imul null, r4.xyzw, r2.yyyy, r4.xyzw + imad r4.xyzw, r5.xyzw, r3.yyyy, r4.xyzw + and r5.xyzw, r4.xyzw, l(2047, 2047, 2047, 2047) + udiv r5.xyzw, null, r5.xyzw, l(3, 3, 3, 3) + ushr r4.xyzw, r4.xyzw, l(16, 16, 16, 16) + udiv r4.xyzw, null, r4.xyzw, l(3, 3, 3, 3) + ishl r4.xyzw, r4.xyzw, l(8, 8, 24, 24) + or r3.zw, r4.xxxy, r5.xxxy + ishl r4.xy, r5.zwzz, l(16, 16, 0, 0) + or r3.zw, r3.zzzw, r4.xxxy + or r6.zw, r4.zzzw, r3.zzzw + store_uav_typed U0[0].xyzw, r1.wwww, r6.xyzw + imad r1.w, vThreadID.y, l(4), l(3) + ult r1.w, r1.w, CB0[0][2].y + if_nz r1.w + imad r1.w, l(3), r1.y, r0.w + ushr r4.xy, r2.wzww, l(24, 24, 0, 0) + not r5.xy, r4.xyxx + ushr r6.yzw, r5.yyyy, l(0, 4, 2, 6) + mov r6.x, r5.y + and r6.xyzw, r6.xyzw, l(3, 3, 3, 3) + ushr r7.yzw, r4.yyyy, l(0, 4, 2, 6) + mov r7.x, r4.y + and r7.xyzw, r7.xyzw, l(3, 3, 3, 3) + imul null, r7.xyzw, r2.xxxx, r7.xyzw + imad r6.xyzw, r6.xyzw, r3.xxxx, r7.xyzw + and r7.xyzw, r6.xyzw, l(2047, 2047, 2047, 2047) + udiv r7.xyzw, null, r7.xyzw, l(3, 3, 3, 3) + ushr r6.xyzw, r6.xyzw, l(16, 16, 16, 16) + udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) + ishl r6.xyzw, r6.xyzw, l(8, 8, 24, 24) + or r2.xz, r6.xxyx, r7.xxyx + ishl r3.xz, r7.zzwz, l(16, 0, 16, 0) + or r2.xz, r2.xxzx, r3.xxzx + or r6.xy, r6.zwzz, r2.xzxx + ushr r5.yzw, r5.xxxx, l(0, 4, 2, 6) + and r5.xyzw, r5.xyzw, l(3, 3, 3, 3) + ushr r4.yzw, r4.xxxx, l(0, 4, 2, 6) + and r4.xyzw, r4.xyzw, l(3, 3, 3, 3) + imul null, r2.xyzw, r2.yyyy, r4.xyzw + imad r2.xyzw, r5.xyzw, r3.yyyy, r2.xyzw + and r3.xyzw, r2.xyzw, l(2047, 2047, 2047, 2047) + udiv r3.xyzw, null, r3.xyzw, l(3, 3, 3, 3) + ushr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) + udiv r2.xyzw, null, r2.xyzw, l(3, 3, 3, 3) + ishl r2.xyzw, r2.xyzw, l(8, 8, 24, 24) + or r2.xy, r2.xyxx, r3.xyxx + ishl r3.xy, r3.zwzz, l(16, 16, 0, 0) + or r2.xy, r2.xyxx, r3.xyxx + or r6.zw, r2.zzzw, r2.xxxy + store_uav_typed U0[0].xyzw, r1.wwww, r6.xyzw + endif + endif +endif +iadd r0.w, r0.w, l(1) +movc r0.x, r0.x, l(2), l(1) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xzyw +if_nz r1.x + ishl r3.xyzw, r2.xzyw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xzyw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xzyw, r4.xzyw +endif +if_nz r1.z + ushr r3.xyzw, r2.xzyw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xzyw +endif +ubfe r0.xy, l(8, 8, 0, 0), l(8, 8, 0, 0), r2.xyxx +bfi r1.xz, l(8, 0, 8, 0), l(16, 0, 16, 0), r2.xxyx, l(0, 0, 0, 0) +iadd r0.xy, r0.xyxx, r1.xzxx +ushr r1.xz, r2.xxyx, l(24, 0, 24, 0) +and r2.xy, r2.xyxx, l(0x00ff0000, 0x00ff0000, 0, 0) +iadd r1.xz, r1.xxzx, r2.xxyx +ishl r2.xy, r2.zwzz, l(1, 1, 0, 0) +ushr r2.zw, r2.zzzw, l(0, 0, 1, 1) +and r2.xyzw, r2.xyzw, l(0xaaaaaaaa, 0xaaaaaaaa, 0x55555555, 0x55555555) +iadd r2.xy, r2.zwzz, r2.xyxx +ushr r2.zw, r2.xxxy, l(0, 0, 1, 1) +and r2.zw, r2.zzzw, l(0, 0, 0x55555555, 0x55555555) +xor r2.xy, r2.zwzz, r2.xyxx +not r3.xy, r2.yxyy +ushr r4.yzw, r3.yyyy, l(0, 4, 2, 6) +mov r4.x, r3.y +and r4.xyzw, r4.xyzw, l(3, 3, 3, 3) +ushr r5.yzw, r2.xxxx, l(0, 4, 2, 6) +mov r5.x, r2.x +and r5.xyzw, r5.xyzw, l(3, 3, 3, 3) +imul null, r5.xyzw, r1.xxxx, r5.xyzw +imad r4.xyzw, r4.xyzw, r0.xxxx, r5.xyzw +and r5.xyzw, r4.xyzw, l(2047, 2047, 2047, 2047) +udiv r5.xyzw, null, r5.xyzw, l(3, 3, 3, 3) +ushr r4.xyzw, r4.xyzw, l(16, 16, 16, 16) +udiv r4.xyzw, null, r4.xyzw, l(3, 3, 3, 3) +ishl r4.xyzw, r4.xyzw, l(8, 8, 24, 24) +or r2.zw, r4.xxxy, r5.xxxy +ishl r4.xy, r5.zwzz, l(16, 16, 0, 0) +or r2.zw, r2.zzzw, r4.xxxy +or r4.xy, r4.zwzz, r2.zwzz +ushr r3.yzw, r3.xxxx, l(0, 4, 2, 6) +and r3.xyzw, r3.xyzw, l(3, 3, 3, 3) +ushr r5.yzw, r2.yyyy, l(0, 4, 2, 6) +mov r5.x, r2.y +and r5.xyzw, r5.xyzw, l(3, 3, 3, 3) +imul null, r5.xyzw, r1.zzzz, r5.xyzw +imad r3.xyzw, r3.xyzw, r0.yyyy, r5.xyzw +and r5.xyzw, r3.xyzw, l(2047, 2047, 2047, 2047) +udiv r5.xyzw, null, r5.xyzw, l(3, 3, 3, 3) +ushr r3.xyzw, r3.xyzw, l(16, 16, 16, 16) +udiv r3.xyzw, null, r3.xyzw, l(3, 3, 3, 3) +ishl r3.xyzw, r3.xyzw, l(8, 8, 24, 24) +or r2.zw, r3.xxxy, r5.xxxy +ishl r3.xy, r5.zwzz, l(16, 16, 0, 0) +or r2.zw, r2.zzzw, r3.xxxy +or r4.zw, r3.zzzw, r2.zzzw +store_uav_typed U0[0].xyzw, r0.wwww, r4.xyzw +if_nz r0.z + iadd r0.z, r1.y, r0.w + ushr r3.xy, r2.yxyy, l(8, 8, 0, 0) + not r4.xy, r3.xyxx + ushr r5.yzw, r4.yyyy, l(0, 4, 2, 6) + mov r5.x, r4.y + and r5.xyzw, r5.xyzw, l(3, 3, 3, 3) + ushr r6.yzw, r3.yyyy, l(0, 4, 2, 6) + mov r6.x, r3.y + and r6.xyzw, r6.xyzw, l(3, 3, 3, 3) + imul null, r6.xyzw, r1.xxxx, r6.xyzw + imad r5.xyzw, r5.xyzw, r0.xxxx, r6.xyzw + and r6.xyzw, r5.xyzw, l(2047, 2047, 2047, 2047) + udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) + ushr r5.xyzw, r5.xyzw, l(16, 16, 16, 16) + udiv r5.xyzw, null, r5.xyzw, l(3, 3, 3, 3) + ishl r5.xyzw, r5.xyzw, l(8, 8, 24, 24) + or r2.zw, r5.xxxy, r6.xxxy + ishl r5.xy, r6.zwzz, l(16, 16, 0, 0) + or r2.zw, r2.zzzw, r5.xxxy + or r5.xy, r5.zwzz, r2.zwzz + ushr r4.yzw, r4.xxxx, l(0, 4, 2, 6) + and r4.xyzw, r4.xyzw, l(3, 3, 3, 3) + ushr r3.yzw, r3.xxxx, l(0, 4, 2, 6) + and r3.xyzw, r3.xyzw, l(3, 3, 3, 3) + imul null, r3.xyzw, r1.zzzz, r3.xyzw + imad r3.xyzw, r4.xyzw, r0.yyyy, r3.xyzw + and r4.xyzw, r3.xyzw, l(2047, 2047, 2047, 2047) + udiv r4.xyzw, null, r4.xyzw, l(3, 3, 3, 3) + ushr r3.xyzw, r3.xyzw, l(16, 16, 16, 16) + udiv r3.xyzw, null, r3.xyzw, l(3, 3, 3, 3) + ishl r3.xyzw, r3.xyzw, l(8, 8, 24, 24) + or r2.zw, r3.xxxy, r4.xxxy + ishl r3.xy, r4.zwzz, l(16, 16, 0, 0) + or r2.zw, r2.zzzw, r3.xxxy + or r5.zw, r3.zzzw, r2.zzzw + store_uav_typed U0[0].xyzw, r0.zzzz, r5.xyzw + imad r0.z, vThreadID.y, l(4), l(2) + ult r0.z, r0.z, CB0[0][2].y + if_nz r0.z + ishl r0.z, r1.y, l(1) + iadd r0.z, r0.z, r0.w + ushr r3.xy, r2.yxyy, l(16, 16, 0, 0) + not r4.xy, r3.xyxx + ushr r5.yzw, r4.yyyy, l(0, 4, 2, 6) + mov r5.x, r4.y + and r5.xyzw, r5.xyzw, l(3, 3, 3, 3) + ushr r6.yzw, r3.yyyy, l(0, 4, 2, 6) + mov r6.x, r3.y + and r6.xyzw, r6.xyzw, l(3, 3, 3, 3) + imul null, r6.xyzw, r1.xxxx, r6.xyzw + imad r5.xyzw, r5.xyzw, r0.xxxx, r6.xyzw + and r6.xyzw, r5.xyzw, l(2047, 2047, 2047, 2047) + udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) + ushr r5.xyzw, r5.xyzw, l(16, 16, 16, 16) + udiv r5.xyzw, null, r5.xyzw, l(3, 3, 3, 3) + ishl r5.xyzw, r5.xyzw, l(8, 8, 24, 24) + or r2.zw, r5.xxxy, r6.xxxy + ishl r5.xy, r6.zwzz, l(16, 16, 0, 0) + or r2.zw, r2.zzzw, r5.xxxy + or r5.xy, r5.zwzz, r2.zwzz + ushr r4.yzw, r4.xxxx, l(0, 4, 2, 6) + and r4.xyzw, r4.xyzw, l(3, 3, 3, 3) + ushr r3.yzw, r3.xxxx, l(0, 4, 2, 6) + and r3.xyzw, r3.xyzw, l(3, 3, 3, 3) + imul null, r3.xyzw, r1.zzzz, r3.xyzw + imad r3.xyzw, r4.xyzw, r0.yyyy, r3.xyzw + and r4.xyzw, r3.xyzw, l(2047, 2047, 2047, 2047) + udiv r4.xyzw, null, r4.xyzw, l(3, 3, 3, 3) + ushr r3.xyzw, r3.xyzw, l(16, 16, 16, 16) + udiv r3.xyzw, null, r3.xyzw, l(3, 3, 3, 3) + ishl r3.xyzw, r3.xyzw, l(8, 8, 24, 24) + or r2.zw, r3.xxxy, r4.xxxy + ishl r3.xy, r4.zwzz, l(16, 16, 0, 0) + or r2.zw, r2.zzzw, r3.xxxy + or r5.zw, r3.zzzw, r2.zzzw + store_uav_typed U0[0].xyzw, r0.zzzz, r5.xyzw + imad r0.z, vThreadID.y, l(4), l(3) + ult r0.z, r0.z, CB0[0][2].y + if_nz r0.z + imad r0.z, l(3), r1.y, r0.w + ushr r2.xy, r2.yxyy, l(24, 24, 0, 0) + not r3.xy, r2.xyxx + ushr r4.yzw, r3.yyyy, l(0, 4, 2, 6) + mov r4.x, r3.y + and r4.xyzw, r4.xyzw, l(3, 3, 3, 3) + ushr r5.yzw, r2.yyyy, l(0, 4, 2, 6) + mov r5.x, r2.y + and r5.xyzw, r5.xyzw, l(3, 3, 3, 3) + imul null, r5.xyzw, r1.xxxx, r5.xyzw + imad r4.xyzw, r4.xyzw, r0.xxxx, r5.xyzw + and r5.xyzw, r4.xyzw, l(2047, 2047, 2047, 2047) + udiv r5.xyzw, null, r5.xyzw, l(3, 3, 3, 3) + ushr r4.xyzw, r4.xyzw, l(16, 16, 16, 16) + udiv r4.xyzw, null, r4.xyzw, l(3, 3, 3, 3) + ishl r4.xyzw, r4.xyzw, l(8, 8, 24, 24) + or r0.xw, r4.xxxy, r5.xxxy + ishl r1.xy, r5.zwzz, l(16, 16, 0, 0) + or r0.xw, r0.xxxw, r1.xxxy + or r4.xy, r4.zwzz, r0.xwxx + ushr r3.yzw, r3.xxxx, l(0, 4, 2, 6) + and r3.xyzw, r3.xyzw, l(3, 3, 3, 3) + ushr r2.yzw, r2.xxxx, l(0, 4, 2, 6) + and r2.xyzw, r2.xyzw, l(3, 3, 3, 3) + imul null, r1.xyzw, r1.zzzz, r2.xyzw + imad r1.xyzw, r3.xyzw, r0.yyyy, r1.xyzw + and r2.xyzw, r1.xyzw, l(2047, 2047, 2047, 2047) + udiv r2.xyzw, null, r2.xyzw, l(3, 3, 3, 3) + ushr r1.xyzw, r1.xyzw, l(16, 16, 16, 16) + udiv r1.xyzw, null, r1.xyzw, l(3, 3, 3, 3) + ishl r1.xyzw, r1.xyzw, l(8, 8, 24, 24) + or r0.xy, r1.xyxx, r2.xyxx + ishl r1.xy, r2.zwzz, l(16, 16, 0, 0) + or r0.xy, r0.xyxx, r1.xyxx + or r4.zw, r1.zzzw, r0.xxxy + store_uav_typed U0[0].xyzw, r0.zzzz, r4.xyzw + endif + endif +endif +ret +// Approximately 441 instruction slots used +#endif + +const BYTE texture_load_ctx1_cs[] = { + 68, 88, 66, 67, 115, 231, 89, 89, 49, 188, 154, 206, 254, 240, 60, 244, 153, 221, 99, + 181, 1, 0, 0, 0, 16, 65, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 116, 64, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 56, 60, 0, + 0, 81, 0, 5, 0, 14, 15, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 8, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 35, 0, 0, 10, 34, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, + 11, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 30, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 85, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, + 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 150, 5, 2, + 0, 2, 64, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 1, 0, 0, 0, 246, 139, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 14, 146, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 2, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 48, + 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, + 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 19, 0, 0, 0, 19, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 14, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 35, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 50, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 138, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, + 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, + 0, 14, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, 2, 0, 42, 0, 0, + 9, 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 9, 66, + 0, 16, 0, 2, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, 82, 0, 16, 0, 2, + 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 2, 0, 0, + 0, 6, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 128, 3, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 64, + 0, 0, 10, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 10, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 98, + 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, + 17, 98, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, + 86, 6, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 0, 0, 0, 0, + 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 3, 0, 0, 0, + 35, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 150, 5, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, + 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, + 1, 18, 0, 0, 1, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 35, 0, 0, 9, 66, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 21, + 0, 0, 1, 30, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 85, 0, 0, 10, 162, 0, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 134, 125, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 10, 210, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 134, 13, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 134, 13, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, + 0, 0, 134, 13, 16, 0, 3, 0, 0, 0, 134, 13, 16, 0, 4, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 3, 0, 0, 0, 134, 13, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 134, 13, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 138, 0, 0, 15, 50, 0, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 20, 194, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 3, 0, + 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 3, + 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, + 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, + 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 230, 10, 16, 0, + 3, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 166, + 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 170, 170, 170, 170, 170, 170, 170, 170, 85, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, + 0, 166, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, + 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 85, 85, 85, 85, 85, 85, 85, 30, 0, 0, 7, 194, 0, 16, + 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 3, 0, + 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, + 85, 85, 85, 85, 85, 85, 87, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 166, + 14, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 59, 0, 0, 5, + 50, 0, 16, 0, 4, 0, 0, 0, 182, 15, 16, 0, 2, 0, 0, 0, 85, 0, 0, + 10, 226, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 166, 10, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 6, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, + 6, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, + 0, 35, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, + 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 7, 0, + 0, 78, 0, 0, 11, 242, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 5, 0, + 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 60, 0, + 0, 7, 194, 0, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 6, + 4, 16, 0, 6, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, + 230, 10, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 3, 0, + 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 60, + 0, 0, 7, 50, 0, 16, 0, 5, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, + 230, 10, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, + 0, 6, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 5, 18, + 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, + 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 6, 0, 0, 0, 86, 5, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, + 7, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, + 6, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, + 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 78, 0, 0, 11, 242, 0, 16, 0, 4, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 24, 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 3, 0, 0, + 0, 6, 4, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 41, 0, + 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 60, 0, 0, 7, 194, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, + 0, 6, 4, 16, 0, 4, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 5, 0, + 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 164, + 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 35, 0, 0, 8, 66, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 79, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 182, + 15, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 5, 50, 0, 16, 0, 5, 0, 0, + 0, 70, 0, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 6, 0, + 0, 0, 86, 5, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, + 6, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, + 0, 16, 0, 7, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 7, 0, 0, 0, 6, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 35, 0, 0, 9, 242, 0, + 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, + 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 78, 0, 0, 11, 242, 0, + 16, 0, 7, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 85, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, 70, + 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 3, + 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, + 41, 0, 0, 10, 50, 0, 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, 7, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 3, + 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, + 6, 0, 0, 0, 230, 10, 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, + 0, 85, 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 5, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 4, 0, 0, 0, 6, 0, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, + 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, + 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, + 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, + 7, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 5, 0, 0, 0, 0, 208, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, + 4, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, + 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, + 60, 0, 0, 7, 194, 0, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, + 0, 6, 4, 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 4, 0, + 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, + 3, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, + 0, 60, 0, 0, 7, 194, 0, 16, 0, 6, 0, 0, 0, 166, 14, 16, 0, 4, 0, + 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 35, 0, 0, 8, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 79, 0, + 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, + 58, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, + 182, 15, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 5, 50, 0, 16, 0, 5, 0, + 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 6, + 0, 0, 0, 86, 5, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 6, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, + 226, 0, 16, 0, 7, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 7, 0, 0, 0, 6, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 35, 0, 0, 9, 242, + 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 7, + 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 78, 0, 0, 11, 242, + 0, 16, 0, 7, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, + 3, 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, + 0, 41, 0, 0, 10, 50, 0, 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, + 3, 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, + 0, 6, 0, 0, 0, 230, 10, 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, 3, 0, + 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 4, 0, 0, 0, 6, + 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, + 0, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, + 255, 7, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 5, 0, 0, 0, 0, 208, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, + 0, 4, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, + 0, 60, 0, 0, 7, 194, 0, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, 4, 0, + 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 4, + 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, + 0, 3, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, 4, 0, + 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 6, 0, 0, 0, 166, 14, 16, 0, 4, + 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 35, 0, 0, 8, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, + 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 79, + 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, + 3, 58, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, + 182, 15, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, 24, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 5, 50, 0, 16, 0, 5, 0, + 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 6, + 0, 0, 0, 86, 5, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 6, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, + 226, 0, 16, 0, 7, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 7, 0, 0, 0, 6, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 35, 0, 0, 9, 242, + 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 7, + 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 78, 0, 0, 11, 242, + 0, 16, 0, 7, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, + 2, 0, 0, 0, 6, 1, 16, 0, 6, 0, 0, 0, 6, 1, 16, 0, 7, 0, 0, + 0, 41, 0, 0, 10, 82, 0, 16, 0, 3, 0, 0, 0, 166, 11, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, + 2, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, + 0, 6, 0, 0, 0, 230, 10, 16, 0, 6, 0, 0, 0, 134, 0, 16, 0, 2, 0, + 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 4, 0, 0, 0, 6, + 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, + 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, + 255, 7, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 3, 0, 0, 0, 0, 208, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, + 0, 2, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, + 0, 60, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, + 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, + 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, + 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 3, 0, + 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 6, 0, 0, 0, 166, 14, 16, 0, 2, + 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 30, 0, + 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, + 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 134, 125, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 134, 13, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 134, 13, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, + 0, 0, 134, 13, 16, 0, 3, 0, 0, 0, 134, 13, 16, 0, 4, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 3, 0, 0, 0, 134, 13, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 134, 13, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 138, 0, 0, 15, 50, 0, + 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 20, 82, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, + 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 82, 0, 16, 0, 1, + 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, + 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, + 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, + 2, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 230, 10, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 170, 170, 170, 170, 170, 170, + 170, 170, 85, 85, 85, 85, 85, 85, 85, 85, 30, 0, 0, 7, 50, 0, 16, 0, 2, + 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, + 85, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, + 85, 85, 85, 85, 87, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 230, 10, 16, + 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 59, 0, 0, 5, 50, 0, + 16, 0, 3, 0, 0, 0, 22, 5, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 226, + 0, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 85, 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, + 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 5, 0, + 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 35, + 0, 0, 9, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 78, + 0, 0, 11, 242, 0, 16, 0, 5, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 4, 0, 0, 0, + 0, 208, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, + 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, + 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 6, 4, 16, + 0, 5, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, + 166, 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 60, 0, 0, + 7, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 230, 10, + 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 3, 0, 0, 0, 6, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 5, + 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 5, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, + 0, 208, 0, 0, 242, 0, 16, 0, 5, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, + 0, 255, 7, 0, 0, 255, 7, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 5, 0, + 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 78, 0, + 0, 11, 242, 0, 16, 0, 3, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 24, 0, + 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 6, + 4, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, + 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, + 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, + 4, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 4, 0, 0, 0, + 166, 14, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 164, 0, 0, + 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, + 0, 3, 0, 0, 0, 22, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 5, 50, + 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, + 226, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 85, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 86, 5, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, + 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 6, + 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, + 35, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, + 78, 0, 0, 11, 242, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 5, 0, 0, + 0, 0, 208, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, + 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, + 7, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 6, 4, + 16, 0, 6, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 230, + 10, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, + 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 60, 0, + 0, 7, 50, 0, 16, 0, 5, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 230, + 10, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 4, 0, 0, 0, + 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 2, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, + 3, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, + 0, 208, 0, 0, 242, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, + 0, 255, 7, 0, 0, 255, 7, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 4, 0, + 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 78, 0, + 0, 11, 242, 0, 16, 0, 3, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 24, 0, + 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 6, + 4, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, + 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, + 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, + 4, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 5, 0, 0, 0, + 166, 14, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 164, 0, 0, + 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 35, 0, 0, 8, 66, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 79, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 50, 0, + 16, 0, 3, 0, 0, 0, 22, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 5, + 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 85, 0, 0, + 10, 226, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 86, 5, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 6, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, + 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, + 6, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, + 0, 35, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, + 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 7, 0, + 0, 78, 0, 0, 11, 242, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 5, 0, + 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 60, 0, + 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 6, + 4, 16, 0, 6, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, + 230, 10, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 2, 0, + 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 60, + 0, 0, 7, 50, 0, 16, 0, 5, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, + 230, 10, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, + 0, 3, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 242, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, + 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 4, + 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 78, + 0, 0, 11, 242, 0, 16, 0, 3, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 24, + 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, + 6, 4, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 41, 0, 0, + 10, 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, + 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, + 6, 4, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 5, 0, 0, + 0, 166, 14, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 164, 0, + 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 35, 0, 0, 8, 66, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 79, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, + 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 50, 0, + 16, 0, 2, 0, 0, 0, 22, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 24, + 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 5, + 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, + 10, 226, 0, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 6, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, + 0, 2, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, + 5, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 35, 0, 0, 9, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 7, 0, + 0, 78, 0, 0, 11, 242, 0, 16, 0, 5, 0, 0, 0, 0, 208, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 4, 0, + 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 60, 0, + 0, 7, 146, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 6, + 4, 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, + 230, 10, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 146, 0, 16, 0, 0, 0, + 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 60, + 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, + 198, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 3, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, + 0, 2, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 242, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 1, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 1, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 1, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, + 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 2, + 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 78, + 0, 0, 11, 242, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 24, + 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, + 10, 50, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, + 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 1, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 4, 0, 0, + 0, 166, 14, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, 164, 0, + 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, + 21, 0, 0, 1, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 185, 1, 0, + 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 121, 0, + 0, 0, 231, 0, 0, 0, 4, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_depth_float_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_depth_float_cs.h new file mode 100644 index 0000000..9e052e3 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_depth_float_cs.h @@ -0,0 +1,511 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 7 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(2) +imad r1.x, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.x, r1.x, CB0[0][2].x, r0.w +iadd r1.x, r1.x, CB0[0][1].w +ushr r1.x, r1.x, l(4) +if_nz r0.x + if_nz r0.y + ishr r1.yzw, vThreadID.yyzy, l(0, 4, 2, 3) + ushr r2.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r0.y, r1.z, r2.x, r1.y + ibfe r2.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), vThreadID.xxxx + imad r0.y, r0.y, r2.y, r2.x + ishl r1.y, vThreadID.y, l(10) + ishr r1.y, r1.y, l(6) + and r1.y, r1.y, l(96) + iadd r1.z, r1.z, r1.w + bfi r1.w, l(1), l(1), r1.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r1.w, l(2), l(1), r1.w, l(0) + bfi r1.z, l(1), l(0), r1.z, r1.w + bfi r2.xy, l(20, 20, 0, 0), l(10, 13, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r1.yw, r1.yyyy, l(0, 2, 0, 16), r2.xxxy + bfi r1.yw, l(0, 2, 0, 2), l(0, 8, 0, 11), vThreadID.zzzz, r1.yyyw + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r2.x, l(3), l(6), r1.y + and r2.y, r1.z, l(6) + bfi r1.z, l(1), l(8), r1.z, l(0) + imad r1.z, r2.x, l(32), r1.z + imad r1.z, r2.y, l(4), r1.z + bfi r1.yw, l(0, 6, 0, 6), l(0, 0, 0, 3), r0.yyyy, r1.yyyw + bfi r0.y, l(9), l(3), r1.z, r1.w + bfi r0.y, l(6), l(0), r1.y, r0.y + else + ibfe r1.yz, l(0, 27, 29, 0), l(0, 2, 0, 0), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.y, r2.x, r1.w, r1.y + ishl r2.xz, vThreadID.yyyy, l(5, 0, 7, 0) + and r2.xz, r2.xxzx, l(448, 0, 2048, 0) + bfi r1.w, l(23), l(9), r1.y, r2.x + bfi r2.w, l(1), l(4), vThreadID.y, l(0) + iadd r1.w, r1.w, r2.w + ishl r3.xy, r2.xxxx, l(3, 2, 0, 0) + bfi r3.xy, l(23, 23, 0, 0), l(12, 11, 0, 0), r1.yyyy, r3.xyxx + imad r2.xw, r2.wwww, l(8, 0, 0, 4), r3.xxxy + bfi r1.y, l(12), l(0), r2.z, r2.x + and r2.x, r2.w, l(1792) + iadd r1.y, r1.y, r2.x + and r2.x, r2.y, l(2) + iadd r1.z, r1.z, r2.x + bfi r1.z, l(2), l(6), r1.z, l(0) + iadd r1.y, r1.y, r1.z + bfi r0.y, l(6), l(0), r1.w, r1.y + endif +else + imad r1.y, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.y, CB0[0][0].z, r0.w +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.y, r0.y, l(4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r1.yzw, r0.zzzz, l(0, 1, 2, 3) +or r0.zw, r1.zzzw, r1.yyyz +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +ushr r3.xyzw, r2.xyzw, l(8, 8, 8, 8) +ubfe r2.xyzw, l(20, 20, 20, 20), l(8, 8, 8, 8), r2.xyzw +ushr r4.xyzw, r3.xyzw, l(20, 20, 20, 20) +firstbit_hi r5.xyzw, r2.xyzw +iadd r5.xyzw, r5.xyzw, l(-11, -11, -11, -11) +movc r5.xyzw, r2.xyzw, r5.xyzw, l(21,21,21,21) +iadd r6.xyzw, -r5.xyzw, l(1, 1, 1, 1) +movc r6.xyzw, r4.xyzw, r4.xyzw, r6.xyzw +ishl r5.xyzw, r2.xyzw, r5.xyzw +and r5.xyzw, r5.xyzw, l(0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff) +movc r2.xyzw, r4.xyzw, r2.xyzw, r5.xyzw +ishl r4.xyzw, r6.xyzw, l(23, 23, 23, 23) +iadd r4.xyzw, r4.xyzw, l(0x38000000, 0x38000000, 0x38000000, 0x38000000) +ishl r2.xyzw, r2.xyzw, l(3, 3, 3, 3) +iadd r2.xyzw, r4.xyzw, r2.xyzw +movc r2.xyzw, r3.xyzw, r2.xyzw, l(0,0,0,0) +store_uav_typed U0[0].xyzw, r1.xxxx, r2.xyzw +iadd r1.y, r1.x, l(1) +if_nz r0.x + mov r0.x, l(32) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r0.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r0.xyzw +endif +ushr r0.xyzw, r2.xyzw, l(8, 8, 8, 8) +ubfe r2.xyzw, l(20, 20, 20, 20), l(8, 8, 8, 8), r2.xyzw +ushr r3.xyzw, r0.xyzw, l(20, 20, 20, 20) +firstbit_hi r4.xyzw, r2.xyzw +iadd r4.xyzw, r4.xyzw, l(-11, -11, -11, -11) +movc r4.xyzw, r2.xyzw, r4.xyzw, l(21,21,21,21) +iadd r5.xyzw, -r4.xyzw, l(1, 1, 1, 1) +movc r5.xyzw, r3.xyzw, r3.xyzw, r5.xyzw +ishl r4.xyzw, r2.xyzw, r4.xyzw +and r4.xyzw, r4.xyzw, l(0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff) +movc r2.xyzw, r3.xyzw, r2.xyzw, r4.xyzw +ishl r3.xyzw, r5.xyzw, l(23, 23, 23, 23) +iadd r3.xyzw, r3.xyzw, l(0x38000000, 0x38000000, 0x38000000, 0x38000000) +ishl r2.xyzw, r2.xyzw, l(3, 3, 3, 3) +iadd r2.xyzw, r3.xyzw, r2.xyzw +movc r0.xyzw, r0.xyzw, r2.xyzw, l(0,0,0,0) +store_uav_typed U0[0].xyzw, r1.yyyy, r0.xyzw +ret +// Approximately 138 instruction slots used +#endif + +const BYTE texture_load_depth_float_cs[] = { + 68, 88, 66, 67, 133, 56, 104, 213, 125, 198, 32, 154, 110, 109, 132, 190, 134, 163, 190, + 244, 1, 0, 0, 0, 136, 23, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 236, 22, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 176, 18, 0, + 0, 81, 0, 5, 0, 172, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 7, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 226, 0, 16, 0, 1, 0, + 0, 0, 86, 6, 2, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, + 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, + 182, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 139, 0, 0, 14, + 82, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, + 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 96, 0, 0, 0, 30, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 20, 50, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, + 0, 0, 12, 162, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 6, 4, 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 162, 0, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 166, 10, 2, 0, 86, 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 10, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, + 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, + 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 32, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 162, 0, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, + 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, + 14, 98, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 27, 0, + 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 2, 0, 42, 0, 0, 9, + 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, + 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, 82, 0, 16, 0, 2, 0, + 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 2, 0, 0, 0, + 6, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, + 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, + 0, 35, 0, 0, 12, 146, 0, 16, 0, 2, 0, 0, 0, 246, 15, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, + 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 21, 0, + 0, 1, 18, 0, 0, 1, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, + 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, + 226, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 0, + 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 86, + 9, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 138, 0, 0, 15, 242, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 20, 0, 0, 0, 20, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 85, 0, + 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 135, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 30, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, + 0, 0, 2, 64, 0, 0, 245, 255, 255, 255, 245, 255, 255, 255, 245, 255, 255, 255, 245, + 255, 255, 255, 55, 0, 0, 12, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, + 0, 21, 0, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 30, 0, 0, 11, 242, 0, + 16, 0, 6, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 55, 0, 0, 9, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 41, 0, + 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 255, 15, 0, 255, 255, 15, + 0, 255, 255, 15, 0, 255, 255, 15, 0, 55, 0, 0, 9, 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, + 0, 23, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 56, 0, + 0, 0, 56, 0, 0, 0, 56, 0, 0, 0, 56, 41, 0, 0, 10, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 242, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 8, 242, 224, + 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, + 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 45, + 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, + 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, + 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, + 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, + 85, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 85, 0, + 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 138, 0, 0, 15, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, + 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, + 0, 20, 0, 0, 0, 135, 0, 0, 5, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 245, 255, 255, 255, 245, 255, 255, 255, + 245, 255, 255, 255, 245, 255, 255, 255, 55, 0, 0, 12, 242, 0, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 30, + 0, 0, 11, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 41, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 255, + 15, 0, 255, 255, 15, 0, 255, 255, 15, 0, 255, 255, 15, 0, 55, 0, 0, 9, 242, + 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 23, 0, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 0, 56, 41, 0, 0, + 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 30, + 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, + 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, + 1, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, + 84, 148, 0, 0, 0, 138, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_depth_float_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_depth_float_scaled_cs.h new file mode 100644 index 0000000..0594dc4 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_depth_float_scaled_cs.h @@ -0,0 +1,567 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 8 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(2) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(2) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +ishl r1.w, r1.x, l(2) +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r2.z, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(3, 0, 1, 0), r1.xxxx + imad r2.z, r2.z, r3.y, r3.x + ishl r3.x, r1.z, l(10) + and r3.x, r3.x, l(6144) + bfi r3.x, l(3), l(8), r1.w, r3.x + ishr r3.x, r3.x, l(6) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r2.zw, l(0, 0, 20, 20), l(0, 0, 10, 13), r2.zzzz, l(0, 0, 0, 0) + imad r2.zw, r3.xxxx, l(0, 0, 2, 16), r2.zzzw + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 8, 11), vThreadID.zzzz, r2.zzzw + bfi r3.x, l(1), l(4), r1.z, l(0) + ubfe r3.y, l(3), l(6), r2.z + and r3.z, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.y, l(32), r0.x + imad r0.x, r3.z, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r3.xxxx, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r3.z, CB0[0][0].z, l(5) + imad r2.z, r3.x, r3.z, r2.z + ishl r3.xz, r1.zzzz, l(5, 0, 7, 0) + and r3.xz, r3.xxzx, l(448, 0, 2048, 0) + bfi r3.w, l(3), l(3), r1.w, r3.x + bfi r3.w, l(23), l(9), r2.z, r3.w + bfi r4.x, l(1), l(4), r1.z, l(0) + iadd r3.w, r3.w, r4.x + ishl r4.yz, r3.xxxx, l(0, 3, 2, 0) + bfi r4.yz, l(0, 3, 3, 0), l(0, 6, 5, 0), r1.wwww, r4.yyzy + bfi r4.yz, l(0, 23, 23, 0), l(0, 12, 11, 0), r2.zzzz, r4.yyzy + imad r4.xy, r4.xxxx, l(8, 4, 0, 0), r4.yzyy + bfi r1.w, l(12), l(0), r3.z, r4.x + and r2.z, r4.y, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.w, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].xyzw +ieq r1.xzw, r0.yyyy, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +if_nz r1.z + ushr r4.xyzw, r3.xyzw, l(16, 16, 16, 16) + bfi r3.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r3.xyzw, r4.xyzw +endif +ushr r4.xyzw, r3.xyzw, l(8, 8, 8, 8) +ubfe r3.xyzw, l(20, 20, 20, 20), l(8, 8, 8, 8), r3.xyzw +ushr r5.xyzw, r4.xyzw, l(20, 20, 20, 20) +firstbit_hi r6.xyzw, r3.xyzw +iadd r6.xyzw, r6.xyzw, l(-11, -11, -11, -11) +movc r6.xyzw, r3.xyzw, r6.xyzw, l(21,21,21,21) +iadd r7.xyzw, -r6.xyzw, l(1, 1, 1, 1) +movc r7.xyzw, r5.xyzw, r5.xyzw, r7.xyzw +ishl r6.xyzw, r3.xyzw, r6.xyzw +and r6.xyzw, r6.xyzw, l(0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff) +movc r3.xyzw, r5.xyzw, r3.xyzw, r6.xyzw +ishl r5.xyzw, r7.xyzw, l(23, 23, 23, 23) +iadd r5.xyzw, r5.xyzw, l(0x38000000, 0x38000000, 0x38000000, 0x38000000) +ishl r3.xyzw, r3.xyzw, l(3, 3, 3, 3) +iadd r3.xyzw, r5.xyzw, r3.xyzw +movc r3.xyzw, r4.xyzw, r3.xyzw, l(0,0,0,0) +store_uav_typed U0[0].xyzw, r1.yyyy, r3.xyzw +iadd r0.y, r1.y, l(1) +ult r1.w, l(1), r0.z +if_nz r1.w + udiv r1.w, null, r2.x, r0.z + imad r1.w, -r1.w, r0.z, r2.x + iadd r2.x, r1.w, l(1) + ieq r2.x, r0.z, r2.x + if_nz r2.x + ishl r0.z, r0.z, l(5) + ishl r1.w, r1.w, l(4) + iadd r0.z, r0.z, -r1.w + else + mov r0.z, l(16) + endif +else + mov r0.z, l(32) +endif +imul null, r0.z, r0.w, r0.z +ushr r0.z, r0.z, l(4) +iadd r0.x, r0.z, r0.x +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r1.x + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r1.z + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +ushr r3.xyzw, r2.xyzw, l(8, 8, 8, 8) +ubfe r2.xyzw, l(20, 20, 20, 20), l(8, 8, 8, 8), r2.xyzw +ushr r4.xyzw, r3.xyzw, l(20, 20, 20, 20) +firstbit_hi r5.xyzw, r2.xyzw +iadd r5.xyzw, r5.xyzw, l(-11, -11, -11, -11) +movc r5.xyzw, r2.xyzw, r5.xyzw, l(21,21,21,21) +iadd r6.xyzw, -r5.xyzw, l(1, 1, 1, 1) +movc r6.xyzw, r4.xyzw, r4.xyzw, r6.xyzw +ishl r5.xyzw, r2.xyzw, r5.xyzw +and r5.xyzw, r5.xyzw, l(0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff) +movc r2.xyzw, r4.xyzw, r2.xyzw, r5.xyzw +ishl r4.xyzw, r6.xyzw, l(23, 23, 23, 23) +iadd r4.xyzw, r4.xyzw, l(0x38000000, 0x38000000, 0x38000000, 0x38000000) +ishl r2.xyzw, r2.xyzw, l(3, 3, 3, 3) +iadd r2.xyzw, r4.xyzw, r2.xyzw +movc r2.xyzw, r3.xyzw, r2.xyzw, l(0,0,0,0) +store_uav_typed U0[0].xyzw, r0.yyyy, r2.xyzw +ret +// Approximately 158 instruction slots used +#endif + +const BYTE texture_load_depth_float_scaled_cs[] = { + 68, 88, 66, 67, 200, 79, 199, 219, 76, 83, 35, 242, 135, 157, 88, 82, 83, 73, 244, + 45, 1, 0, 0, 0, 64, 26, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 164, 25, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 104, 21, 0, + 0, 81, 0, 5, 0, 90, 5, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 8, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, + 0, 42, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 85, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, + 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 10, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 24, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 194, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, + 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, + 0, 2, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 166, 14, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 166, 10, + 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 9, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 15, 194, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 9, 66, 0, 16, 0, 3, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, + 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, + 82, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 23, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, + 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 4, 0, + 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 12, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, + 0, 2, 0, 0, 0, 86, 6, 16, 0, 4, 0, 0, 0, 35, 0, 0, 12, 50, 0, + 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, + 4, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, + 166, 11, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, + 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 10, 210, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 10, 242, 0, + 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 138, 0, 0, 15, + 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, + 0, 20, 0, 0, 0, 20, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, + 0, 135, 0, 0, 5, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, + 0, 0, 0, 2, 64, 0, 0, 245, 255, 255, 255, 245, 255, 255, 255, 245, 255, 255, 255, + 245, 255, 255, 255, 55, 0, 0, 12, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 21, 0, + 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 30, 0, 0, 11, 242, + 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 6, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 55, 0, 0, 9, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 5, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 41, + 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 255, 15, 0, 255, 255, + 15, 0, 255, 255, 15, 0, 255, 255, 15, 0, 55, 0, 0, 9, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 56, + 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 0, 56, 41, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 8, 242, + 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 79, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, + 78, 0, 0, 8, 130, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 10, 130, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, + 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, + 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 30, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, + 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 21, 0, 0, 1, 38, + 0, 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, + 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, + 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, + 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 10, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 135, 0, + 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 30, + 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 245, 255, 255, 255, 245, 255, 255, 255, 245, 255, 255, 255, 245, 255, 255, + 255, 55, 0, 0, 12, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, + 0, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 30, 0, 0, 11, 242, 0, 16, 0, + 6, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 55, 0, + 0, 9, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 41, 0, 0, 7, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 255, 15, 0, 255, 255, 15, 0, 255, + 255, 15, 0, 255, 255, 15, 0, 55, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, + 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 56, 0, 0, 0, + 56, 0, 0, 0, 56, 0, 0, 0, 56, 41, 0, 0, 10, 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 55, 0, 0, 12, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 158, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 60, + 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_depth_unorm_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_depth_unorm_cs.h new file mode 100644 index 0000000..a7a89df --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_depth_unorm_cs.h @@ -0,0 +1,440 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(2) +imad r1.x, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.x, r1.x, CB0[0][2].x, r0.w +iadd r1.x, r1.x, CB0[0][1].w +ushr r1.x, r1.x, l(4) +if_nz r0.x + if_nz r0.y + ishr r1.yzw, vThreadID.yyzy, l(0, 4, 2, 3) + ushr r2.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r0.y, r1.z, r2.x, r1.y + ibfe r2.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), vThreadID.xxxx + imad r0.y, r0.y, r2.y, r2.x + ishl r1.y, vThreadID.y, l(10) + ishr r1.y, r1.y, l(6) + and r1.y, r1.y, l(96) + iadd r1.z, r1.z, r1.w + bfi r1.w, l(1), l(1), r1.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r1.w, l(2), l(1), r1.w, l(0) + bfi r1.z, l(1), l(0), r1.z, r1.w + bfi r2.xy, l(20, 20, 0, 0), l(10, 13, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r1.yw, r1.yyyy, l(0, 2, 0, 16), r2.xxxy + bfi r1.yw, l(0, 2, 0, 2), l(0, 8, 0, 11), vThreadID.zzzz, r1.yyyw + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r2.x, l(3), l(6), r1.y + and r2.y, r1.z, l(6) + bfi r1.z, l(1), l(8), r1.z, l(0) + imad r1.z, r2.x, l(32), r1.z + imad r1.z, r2.y, l(4), r1.z + bfi r1.yw, l(0, 6, 0, 6), l(0, 0, 0, 3), r0.yyyy, r1.yyyw + bfi r0.y, l(9), l(3), r1.z, r1.w + bfi r0.y, l(6), l(0), r1.y, r0.y + else + ibfe r1.yz, l(0, 27, 29, 0), l(0, 2, 0, 0), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.y, r2.x, r1.w, r1.y + ishl r2.xz, vThreadID.yyyy, l(5, 0, 7, 0) + and r2.xz, r2.xxzx, l(448, 0, 2048, 0) + bfi r1.w, l(23), l(9), r1.y, r2.x + bfi r2.w, l(1), l(4), vThreadID.y, l(0) + iadd r1.w, r1.w, r2.w + ishl r3.xy, r2.xxxx, l(3, 2, 0, 0) + bfi r3.xy, l(23, 23, 0, 0), l(12, 11, 0, 0), r1.yyyy, r3.xyxx + imad r2.xw, r2.wwww, l(8, 0, 0, 4), r3.xxxy + bfi r1.y, l(12), l(0), r2.z, r2.x + and r2.x, r2.w, l(1792) + iadd r1.y, r1.y, r2.x + and r2.x, r2.y, l(2) + iadd r1.z, r1.z, r2.x + bfi r1.z, l(2), l(6), r1.z, l(0) + iadd r1.y, r1.y, r1.z + bfi r0.y, l(6), l(0), r1.w, r1.y + endif +else + imad r1.y, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.y, CB0[0][0].z, r0.w +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.y, r0.y, l(4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r1.yzw, r0.zzzz, l(0, 1, 2, 3) +or r0.zw, r1.zzzw, r1.yyyz +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +ushr r2.xyzw, r2.xyzw, l(8, 8, 8, 8) +ushr r3.xyzw, r2.xyzw, l(23, 23, 23, 23) +iadd r2.xyzw, r2.xyzw, r3.xyzw +utof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000000, 0.000000, 0.000000, 0.000000) +store_uav_typed U0[0].xyzw, r1.xxxx, r2.xyzw +iadd r1.y, r1.x, l(1) +if_nz r0.x + mov r0.x, l(32) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r0.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r0.xyzw +endif +ushr r0.xyzw, r2.xyzw, l(8, 8, 8, 8) +ushr r2.xyzw, r0.xyzw, l(23, 23, 23, 23) +iadd r0.xyzw, r0.xyzw, r2.xyzw +utof r0.xyzw, r0.xyzw +mul r0.xyzw, r0.xyzw, l(0.000000, 0.000000, 0.000000, 0.000000) +store_uav_typed U0[0].xyzw, r1.yyyy, r0.xyzw +ret +// Approximately 116 instruction slots used +#endif + +const BYTE texture_load_depth_unorm_cs[] = { + 68, 88, 66, 67, 33, 0, 105, 181, 119, 225, 102, 78, 236, 232, 57, 130, 171, 22, 211, + 240, 1, 0, 0, 0, 240, 19, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 84, 19, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 24, 15, 0, + 0, 81, 0, 5, 0, 198, 3, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 226, 0, 16, 0, 1, 0, + 0, 0, 86, 6, 2, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, + 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, + 182, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 139, 0, 0, 14, + 82, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, + 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 96, 0, 0, 0, 30, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 20, 50, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, + 0, 0, 12, 162, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 6, 4, 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 162, 0, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 166, 10, 2, 0, 86, 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 10, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, + 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, + 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 32, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 162, 0, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, + 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, + 14, 98, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 27, 0, + 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 2, 0, 42, 0, 0, 9, + 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, + 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, 82, 0, 16, 0, 2, 0, + 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 2, 0, 0, 0, + 6, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, + 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, + 0, 35, 0, 0, 12, 146, 0, 16, 0, 2, 0, 0, 0, 246, 15, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, + 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 21, 0, + 0, 1, 18, 0, 0, 1, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, + 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, + 226, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 0, + 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 86, + 9, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 10, 242, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 51, 0, 0, 128, + 51, 0, 0, 128, 51, 0, 0, 128, 51, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 32, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 7, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, + 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 10, 242, 0, + 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 30, 0, + 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 51, 0, 0, + 128, 51, 0, 0, 128, 51, 0, 0, 128, 51, 164, 0, 0, 8, 242, 224, 33, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 116, 0, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 36, 0, + 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_depth_unorm_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_depth_unorm_scaled_cs.h new file mode 100644 index 0000000..e3cb363 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_depth_unorm_scaled_cs.h @@ -0,0 +1,497 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(2) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(2) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +ishl r1.w, r1.x, l(2) +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r2.z, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(3, 0, 1, 0), r1.xxxx + imad r2.z, r2.z, r3.y, r3.x + ishl r3.x, r1.z, l(10) + and r3.x, r3.x, l(6144) + bfi r3.x, l(3), l(8), r1.w, r3.x + ishr r3.x, r3.x, l(6) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r2.zw, l(0, 0, 20, 20), l(0, 0, 10, 13), r2.zzzz, l(0, 0, 0, 0) + imad r2.zw, r3.xxxx, l(0, 0, 2, 16), r2.zzzw + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 8, 11), vThreadID.zzzz, r2.zzzw + bfi r3.x, l(1), l(4), r1.z, l(0) + ubfe r3.y, l(3), l(6), r2.z + and r3.z, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.y, l(32), r0.x + imad r0.x, r3.z, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r3.xxxx, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r3.z, CB0[0][0].z, l(5) + imad r2.z, r3.x, r3.z, r2.z + ishl r3.xz, r1.zzzz, l(5, 0, 7, 0) + and r3.xz, r3.xxzx, l(448, 0, 2048, 0) + bfi r3.w, l(3), l(3), r1.w, r3.x + bfi r3.w, l(23), l(9), r2.z, r3.w + bfi r4.x, l(1), l(4), r1.z, l(0) + iadd r3.w, r3.w, r4.x + ishl r4.yz, r3.xxxx, l(0, 3, 2, 0) + bfi r4.yz, l(0, 3, 3, 0), l(0, 6, 5, 0), r1.wwww, r4.yyzy + bfi r4.yz, l(0, 23, 23, 0), l(0, 12, 11, 0), r2.zzzz, r4.yyzy + imad r4.xy, r4.xxxx, l(8, 4, 0, 0), r4.yzyy + bfi r1.w, l(12), l(0), r3.z, r4.x + and r2.z, r4.y, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.w, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].xyzw +ieq r1.xzw, r0.yyyy, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +if_nz r1.z + ushr r4.xyzw, r3.xyzw, l(16, 16, 16, 16) + bfi r3.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r3.xyzw, r4.xyzw +endif +ushr r3.xyzw, r3.xyzw, l(8, 8, 8, 8) +ushr r4.xyzw, r3.xyzw, l(23, 23, 23, 23) +iadd r3.xyzw, r3.xyzw, r4.xyzw +utof r3.xyzw, r3.xyzw +mul r3.xyzw, r3.xyzw, l(0.000000, 0.000000, 0.000000, 0.000000) +store_uav_typed U0[0].xyzw, r1.yyyy, r3.xyzw +iadd r0.y, r1.y, l(1) +ult r1.w, l(1), r0.z +if_nz r1.w + udiv r1.w, null, r2.x, r0.z + imad r1.w, -r1.w, r0.z, r2.x + iadd r2.x, r1.w, l(1) + ieq r2.x, r0.z, r2.x + if_nz r2.x + ishl r0.z, r0.z, l(5) + ishl r1.w, r1.w, l(4) + iadd r0.z, r0.z, -r1.w + else + mov r0.z, l(16) + endif +else + mov r0.z, l(32) +endif +imul null, r0.z, r0.w, r0.z +ushr r0.z, r0.z, l(4) +iadd r0.x, r0.z, r0.x +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r1.x + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r1.z + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +ushr r2.xyzw, r2.xyzw, l(8, 8, 8, 8) +ushr r3.xyzw, r2.xyzw, l(23, 23, 23, 23) +iadd r2.xyzw, r2.xyzw, r3.xyzw +utof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000000, 0.000000, 0.000000, 0.000000) +store_uav_typed U0[0].xyzw, r0.yyyy, r2.xyzw +ret +// Approximately 136 instruction slots used +#endif + +const BYTE texture_load_depth_unorm_scaled_cs[] = { + 68, 88, 66, 67, 64, 175, 131, 6, 249, 15, 222, 85, 196, 33, 9, 194, 117, 187, 235, + 99, 1, 0, 0, 0, 168, 22, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 12, 22, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 208, 17, 0, + 0, 81, 0, 5, 0, 116, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, + 0, 42, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 85, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, + 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 10, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 24, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 194, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, + 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, + 0, 2, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 166, 14, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 166, 10, + 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 9, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 15, 194, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 9, 66, 0, 16, 0, 3, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, + 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, + 82, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 23, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, + 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 4, 0, + 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 12, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, + 0, 2, 0, 0, 0, 86, 6, 16, 0, 4, 0, 0, 0, 35, 0, 0, 12, 50, 0, + 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, + 4, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, + 166, 11, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, + 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 10, 210, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 10, 242, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 30, 0, + 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 51, 0, 0, + 128, 51, 0, 0, 128, 51, 0, 0, 128, 51, 164, 0, 0, 8, 242, 224, 33, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 79, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 78, 0, 0, 8, + 130, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 10, 130, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 32, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 2, + 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 30, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 18, 0, 0, 1, + 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, + 0, 21, 0, 0, 1, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 21, 0, 0, 1, 38, 0, 0, 8, 0, + 208, 0, 0, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, + 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, + 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, + 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, + 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 21, 0, 0, 1, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, + 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 128, 51, 0, 0, 128, 51, 0, 0, 128, 51, 0, + 0, 128, 51, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 148, 0, 0, 0, 136, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 48, 0, 0, 0, 30, 0, 0, 0, 5, + 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxn_rg8_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxn_rg8_cs.h new file mode 100644 index 0000000..6ed4322 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxn_rg8_cs.h @@ -0,0 +1,2194 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 19 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(1) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r1.yz, r1.xxyx, l(0, 2, 2, 0) +ishl r0.w, r1.y, l(1) +imad r1.y, vThreadID.z, CB0[0][2].y, r1.z +imad r0.w, r1.y, CB0[0][2].x, r0.w +iadd r0.w, r0.w, CB0[0][1].w +ushr r1.y, CB0[0][2].x, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r2.xw, l(27, 0, 0, 29), l(4, 0, 0, 2), vThreadID.xxxx + imad r0.y, r0.y, r1.w, r2.x + ishl r1.z, vThreadID.y, l(12) + and r1.z, r1.z, l(0x00006000) + bfi r1.z, l(3), l(10), r1.x, r1.z + ishr r1.z, r1.z, l(6) + iadd r1.w, r2.y, r2.z + bfi r2.x, l(1), l(1), r1.w, l(0) + iadd r2.x, r2.x, r2.w + bfi r2.x, l(2), l(1), r2.x, l(0) + bfi r1.w, l(1), l(0), r1.w, r2.x + bfi r2.xy, l(18, 18, 0, 0), l(12, 15, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(10, 13, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(6) + bfi r1.w, l(1), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(6, 6, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.zw, l(0, 0, 27, 29), l(0, 0, 4, 2), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r2.z, CB0[0][0].z, l(5) + imad r1.z, r2.x, r2.z, r1.z + ishl r2.x, vThreadID.y, l(7) + and r2.xz, r2.xxxx, l(1792, 0, 2048, 0) + bfi r2.w, l(3), l(5), r1.x, r2.x + bfi r2.w, l(21), l(11), r1.z, r2.w + bfi r3.x, l(1), l(4), vThreadID.y, l(0) + iadd r2.w, r2.w, r3.x + ishl r3.yz, r2.xxxx, l(0, 3, 2, 0) + bfi r3.yz, l(0, 3, 3, 0), l(0, 8, 7, 0), r1.xxxx, r3.yyzy + bfi r3.yz, l(0, 21, 21, 0), l(0, 14, 13, 0), r1.zzzz, r3.yyzy + imad r3.xy, r3.xxxx, l(8, 4, 0, 0), r3.yzyy + bfi r1.z, l(12), l(0), r2.z, r3.x + and r2.x, r3.y, l(1792) + iadd r1.z, r1.z, r2.x + and r2.x, r2.y, l(2) + iadd r1.w, r1.w, r2.x + bfi r1.w, l(2), l(6), r1.w, l(0) + iadd r1.z, r1.z, r1.w + bfi r0.y, l(6), l(0), r2.w, r1.z + endif +else + ishl r1.x, r1.x, l(4) + imad r1.z, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.z, CB0[0][0].z, r1.x +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.yw, r0.yyyw, l(0, 4, 0, 4) +ld r2.xyzw, r0.yyyy, T0[0].ywxz +ieq r1.xzw, r0.zzzz, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r3.xyzw, r2.zxwy, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.zxwy, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.ywxz, r4.ywxz +endif +if_nz r1.z + ushr r3.xyzw, r2.zxwy, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.ywxz + mov r3.xy, r2.zwzz +else + mov r3.xy, r2.zwzz +endif +movc r0.x, r0.x, l(2), l(1) +iadd r0.x, r0.x, r0.y +ld r4.xyzw, r0.xxxx, T0[0].ywxz +if_nz r1.x + ishl r5.xyzw, r4.zxwy, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r6.xyzw, r4.zxwy, l(8, 8, 8, 8) + and r6.xyzw, r6.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r4.xyzw, r5.ywxz, r6.ywxz +endif +if_nz r1.z + ushr r5.xyzw, r4.zxwy, l(16, 16, 16, 16) + bfi r4.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r4.xyzw, r5.ywxz + mov r2.zw, r4.xxxy +else + mov r2.zw, r4.xxxy +endif +ushr r3.zw, r3.xxxy, l(0, 0, 8, 8) +and r5.xyzw, r3.xzyw, l(255, 255, 255, 255) +ushr r4.xy, r4.zwzz, l(8, 8, 0, 0) +and r6.xyzw, r4.zxwy, l(255, 255, 255, 255) +mov r4.xy, r3.xyxx +ushr r3.xyzw, r4.xyzw, l(16, 16, 16, 16) +bfi r4.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r2.xyzw, l(0, 0, 0, 0) +iadd r3.xyzw, r3.xyzw, r4.xyzw +uge r0.xy, r5.ywyy, r5.xzxx +ushr r4.xyzw, r3.xxyy, l(1, 2, 1, 2) +and r1.xz, r3.xxyx, r4.xxzx +and r1.xz, r1.xxzx, l(0x00492492, 0, 0x00492492, 0) +ishl r7.xy, r1.xzxx, l(1, 1, 0, 0) +ushr r7.zw, r1.xxxz, l(0, 0, 1, 1) +iadd r1.xz, r1.xxzx, r7.xxyx +iadd r1.xz, r1.xxzx, r7.zzwz +and r7.xyzw, r3.xyzw, l(0x00249249, 0x00249249, 0x00249249, 0x00249249) +iadd r8.xyzw, r7.xyzw, l(0x00db6db6, 0x00db6db6, 0x00db6db6, 0x00db6db6) +and r8.xy, r1.xzxx, r8.xyxx +or r9.xy, r3.xyxx, r4.xzxx +and r10.xyzw, r4.xyzw, l(0x00249249, 0x00249249, 0x00249249, 0x00249249) +or r4.xy, r4.ywyy, r9.xyxx +and r4.xy, r4.xyxx, l(0x00249249, 0x00249249, 0, 0) +xor r4.xy, r4.xyxx, l(0x00249249, 0x00249249, 0, 0) +not r9.xyzw, r10.xyzw +and r10.xyzw, r7.xxyy, r9.xxzz +and r9.xyzw, r9.yyww, r10.xyzw +or r3.xy, r3.xyxx, r4.xyxx +iadd r3.xy, r3.xyxx, l(0xffdb6db7, 0xffdb6db7, 0, 0) +or r3.xy, r9.xwxx, r3.xyxx +ishl r4.xyzw, r9.xyzw, l(2, 1, 2, 1) +or r7.xy, r3.xyxx, r4.xzxx +not r1.xz, r1.xxzx +and r1.xz, r1.xxzx, r7.xxyx +or r1.xz, r8.xxyx, r1.xxzx +iadd r4.xy, r4.ywyy, r4.xzxx +or r3.xy, r3.xyxx, r4.xyxx +movc r4.xy, r0.xyxx, r1.xzxx, r3.xyxx +uge r1.xz, r6.yywy, r6.xxzx +ushr r9.xyzw, r3.zzww, l(1, 2, 1, 2) +and r3.xy, r3.zwzz, r9.xzxx +and r3.xy, r3.xyxx, l(0x00492492, 0x00492492, 0, 0) +ishl r7.xy, r3.xyxx, l(1, 1, 0, 0) +ushr r8.xy, r3.xyxx, l(1, 1, 0, 0) +iadd r3.xy, r3.xyxx, r7.xyxx +iadd r3.xy, r3.xyxx, r8.xyxx +and r7.xy, r3.xyxx, r8.zwzz +or r8.xy, r3.zwzz, r9.xzxx +and r10.xyzw, r9.xyzw, l(0x00249249, 0x00249249, 0x00249249, 0x00249249) +or r8.xy, r9.ywyy, r8.xyxx +and r8.xy, r8.xyxx, l(0x00249249, 0x00249249, 0, 0) +xor r8.xy, r8.xyxx, l(0x00249249, 0x00249249, 0, 0) +not r9.xyzw, r10.xyzw +and r10.xyzw, r7.zzww, r9.xxzz +and r9.xyzw, r9.yyww, r10.xyzw +or r3.zw, r3.zzzw, r8.xxxy +iadd r3.zw, r3.zzzw, l(0, 0, 0xffdb6db7, 0xffdb6db7) +or r3.zw, r9.yyyw, r3.zzzw +ishl r8.xyzw, r9.xyzw, l(2, 1, 2, 1) +or r7.zw, r3.zzzw, r8.xxxz +not r3.xy, r3.xyxx +and r3.xy, r3.xyxx, r7.zwzz +or r3.xy, r7.xyxx, r3.xyxx +iadd r7.xy, r8.ywyy, r8.xzxx +or r3.zw, r3.zzzw, r7.xxxy +movc r4.zw, r1.xxxz, r3.xxxy, r3.zzzw +ushr r3.xy, r4.xyxx, l(1, 1, 0, 0) +and r3.xy, r4.xyxx, r3.xyxx +and r3.xy, r3.xyxx, l(1170, 1170, 0, 0) +ishl r3.zw, r3.xxxy, l(0, 0, 1, 1) +ushr r7.xy, r3.xyxx, l(1, 1, 0, 0) +iadd r3.xy, r3.xyxx, r3.zwzz +iadd r3.xy, r3.xyxx, r7.xyxx +not r7.xyzw, r3.xxxy +and r8.xyzw, r4.xxxy, r7.zzzw +iadd r9.xyzw, -r8.zzzw, l(2925, 2925, 2925, 2925) +and r7.xyzw, r7.xyzw, r9.xyzw +and r3.zw, r7.zzzw, l(0, 0, 7, 7) +and r9.xy, r8.zwzz, l(7, 7, 0, 0) +imul null, r9.xy, r5.ywyy, r9.xyxx +imad r3.zw, r5.xxxz, r3.zzzw, r9.xxxy +udiv r3.zw, null, r3.zzzw, l(0, 0, 5, 5) +ubfe r9.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r7.xyzw +ubfe r10.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r8.xyzw +imul null, r10.xyzw, r5.yyyw, r10.xyzw +imad r9.xyzw, r5.xxxz, r9.xyzw, r10.xyzw +udiv r9.xyzw, null, r9.xyzw, l(5, 5, 5, 5) +imad r10.xy, r9.xwxx, l(0x00010000, 0x00010000, 0, 0), r3.zwzz +imad r10.z, r9.z, l(0x00010000), r9.y +and r3.xy, r3.xyxx, r4.xyxx +ishl r9.xyzw, r3.xxyy, l(13, 7, 13, 7) +and r9.xyzw, r9.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000) +bfi r11.xy, l(1, 1, 0, 0), l(0, 0, 0, 0), r3.xyxx, r9.xzxx +ubfe r3.xy, l(1, 1, 0, 0), l(6, 6, 0, 0), r3.xyxx +iadd r11.zw, r9.yyyw, r3.xxxy +imad r3.xy, r11.xzxx, l(255, 255, 0, 0), r10.xzxx +not r9.xyzw, r4.xxxy +and r3.zw, r9.zzzw, l(0, 0, 7, 7) +and r12.xyzw, r4.xyzw, l(7, 7, 7, 7) +imul null, r7.xy, r5.ywyy, r12.xyxx +imad r3.zw, r5.xxxz, r3.zzzw, r7.xxxy +udiv r3.zw, null, r3.zzzw, l(0, 0, 7, 7) +ubfe r13.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r9.xyzw +ubfe r14.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r4.xxxy +imul null, r14.xyzw, r5.yyyw, r14.xyzw +imad r13.xyzw, r5.xxxz, r13.xyzw, r14.xyzw +udiv r13.xyzw, null, r13.xyzw, l(7, 7, 7, 7) +imad r14.xy, r13.xwxx, l(0x00010000, 0x00010000, 0, 0), r3.zwzz +imad r14.z, r13.z, l(0x00010000), r13.y +ubfe r3.zw, l(0, 0, 3, 3), l(0, 0, 6, 9), r7.wwww +ubfe r7.xy, l(3, 3, 0, 0), l(6, 9, 0, 0), r8.wwww +imul null, r7.xy, r5.wwww, r7.xyxx +imad r3.zw, r5.zzzz, r3.zzzw, r7.xxxy +udiv r3.zw, null, r3.zzzw, l(0, 0, 5, 5) +imad r10.w, r3.w, l(0x00010000), r3.z +imad r3.zw, r11.yyyw, l(0, 0, 255, 255), r10.yyyw +ubfe r7.xy, l(3, 3, 0, 0), l(6, 9, 0, 0), r9.wwww +ubfe r8.xyzw, l(3, 3, 3, 3), l(6, 9, 6, 9), r4.yyww +imul null, r7.zw, r5.wwww, r8.xxxy +imad r7.xy, r5.zzzz, r7.xyxx, r7.zwzz +udiv r7.xy, null, r7.xyxx, l(7, 7, 0, 0) +imad r14.w, r7.y, l(0x00010000), r7.x +movc r3.xyzw, r0.xxyy, r3.xyzw, r14.xzyw +ishl r3.zw, r3.zzzw, l(0, 0, 8, 8) +or r3.xy, r3.zwzz, r3.xyxx +ushr r7.xy, r4.zwzz, l(1, 1, 0, 0) +and r7.xy, r4.zwzz, r7.xyxx +and r7.xy, r7.xyxx, l(1170, 1170, 0, 0) +ishl r7.zw, r7.xxxy, l(0, 0, 1, 1) +ushr r8.xy, r7.xyxx, l(1, 1, 0, 0) +iadd r7.xy, r7.xyxx, r7.zwzz +iadd r7.xy, r7.xyxx, r8.xyxx +not r9.xyzw, r7.xxxy +and r10.xyzw, r4.zzzw, r9.zzzw +iadd r11.xyzw, -r10.zzzw, l(2925, 2925, 2925, 2925) +and r9.xyzw, r9.xyzw, r11.xyzw +and r7.zw, r9.zzzw, l(0, 0, 7, 7) +and r8.xy, r10.zwzz, l(7, 7, 0, 0) +imul null, r8.xyzw, r6.ywww, r8.xyzw +imad r7.zw, r6.xxxz, r7.zzzw, r8.xxxy +udiv r7.zw, null, r7.zzzw, l(0, 0, 5, 5) +ubfe r11.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r9.xyzw +ubfe r13.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r10.xyzw +imul null, r13.xyzw, r6.yyyw, r13.xyzw +imad r11.xyzw, r6.xxxz, r11.xyzw, r13.xyzw +udiv r11.xyzw, null, r11.xyzw, l(5, 5, 5, 5) +imad r13.xy, r11.xwxx, l(0x00010000, 0x00010000, 0, 0), r7.zwzz +imad r13.z, r11.z, l(0x00010000), r11.y +and r7.xy, r4.zwzz, r7.xyxx +ishl r11.xyzw, r7.xxyy, l(13, 7, 13, 7) +and r11.xyzw, r11.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000) +bfi r14.xy, l(1, 1, 0, 0), l(0, 0, 0, 0), r7.xyxx, r11.xzxx +ubfe r7.xy, l(1, 1, 0, 0), l(6, 6, 0, 0), r7.xyxx +iadd r14.zw, r11.yyyw, r7.xxxy +imad r7.xy, r14.xzxx, l(255, 255, 0, 0), r13.xzxx +not r11.xyzw, r4.zzzw +and r7.zw, r11.zzzw, l(0, 0, 7, 7) +imul null, r8.xy, r6.ywyy, r12.zwzz +imad r7.zw, r6.xxxz, r7.zzzw, r8.xxxy +udiv r7.zw, null, r7.zzzw, l(0, 0, 7, 7) +ubfe r12.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r11.xyzw +ubfe r15.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r4.zzzw +imul null, r15.xyzw, r6.yyyw, r15.xyzw +imad r12.xyzw, r6.xxxz, r12.xyzw, r15.xyzw +udiv r12.xyzw, null, r12.xyzw, l(7, 7, 7, 7) +imad r15.xy, r12.xwxx, l(0x00010000, 0x00010000, 0, 0), r7.zwzz +imad r15.z, r12.z, l(0x00010000), r12.y +ubfe r7.zw, l(0, 0, 3, 3), l(0, 0, 6, 9), r9.wwww +ubfe r8.xy, l(3, 3, 0, 0), l(6, 9, 0, 0), r10.wwww +imul null, r8.xy, r6.wwww, r8.xyxx +imad r7.zw, r6.zzzz, r7.zzzw, r8.xxxy +udiv r7.zw, null, r7.zzzw, l(0, 0, 5, 5) +imad r13.w, r7.w, l(0x00010000), r7.z +imad r7.zw, r14.yyyw, l(0, 0, 255, 255), r13.yyyw +ubfe r8.xy, l(3, 3, 0, 0), l(6, 9, 0, 0), r11.wwww +imad r8.xy, r6.zzzz, r8.xyxx, r8.zwzz +udiv r8.xy, null, r8.xyxx, l(7, 7, 0, 0) +imad r15.w, r8.y, l(0x00010000), r8.x +movc r7.xyzw, r1.xxzz, r7.xyzw, r15.xzyw +ishl r7.zw, r7.zzzw, l(0, 0, 8, 8) +or r3.zw, r7.zzzw, r7.xxxy +store_uav_typed U0[0].xyzw, r0.wwww, r3.xyzw +imad r0.z, vThreadID.y, l(4), l(1) +ult r1.w, r0.z, CB0[0][2].y +if_nz r1.w + iadd r0.w, r1.y, r0.w + ushr r3.xyzw, r4.xyzw, l(12, 12, 12, 12) + ushr r7.xyzw, r3.xyzw, l(1, 1, 1, 1) + and r7.xyzw, r3.xyzw, r7.xyzw + and r7.xyzw, r7.xyzw, l(1170, 1170, 1170, 1170) + ishl r8.xyzw, r7.xyzw, l(1, 1, 1, 1) + ushr r9.xyzw, r7.xyzw, l(1, 1, 1, 1) + iadd r7.xyzw, r7.xyzw, r8.xyzw + iadd r7.xyzw, r7.xyzw, r9.xyzw + not r8.xyzw, r7.xyzw + and r9.xyzw, r3.xyzw, r8.xyzw + iadd r10.xyzw, -r9.xyzw, l(2925, 2925, 2925, 2925) + and r8.xyzw, r8.xyzw, r10.xyzw + and r10.xyzw, r8.xyzw, l(7, 7, 7, 7) + and r11.xyzw, r9.xyzw, l(7, 7, 7, 7) + imul null, r11.xy, r5.ywyy, r11.xyxx + imad r10.xy, r5.xzxx, r10.xyxx, r11.xyxx + udiv r10.xy, null, r10.xyxx, l(5, 5, 0, 0) + ubfe r12.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r8.xxxy + ubfe r13.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r9.xxxy + imul null, r13.xyzw, r5.yyyw, r13.xyzw + imad r12.xyzw, r5.xxxz, r12.xyzw, r13.xyzw + udiv r12.xyzw, null, r12.xyzw, l(5, 5, 5, 5) + imad r13.xy, r12.xwxx, l(0x00010000, 0x00010000, 0, 0), r10.xyxx + imad r13.z, r12.z, l(0x00010000), r12.y + and r7.xyzw, r3.xyzw, r7.xyzw + ishl r12.xyzw, r7.xxyy, l(13, 7, 13, 7) + and r12.xyzw, r12.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000) + bfi r14.xy, l(1, 1, 0, 0), l(0, 0, 0, 0), r7.xyxx, r12.xzxx + ubfe r15.xyzw, l(1, 1, 1, 1), l(6, 6, 6, 6), r7.xyzw + iadd r14.zw, r12.yyyw, r15.xxxy + imad r7.xy, r14.xzxx, l(255, 255, 0, 0), r13.xzxx + not r3.xyzw, r3.xyzw + and r12.xyzw, r3.xyzw, l(7, 7, 7, 7) + ubfe r16.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r4.xxxx + imul null, r16.xyzw, r5.yyyy, r16.xyzw + imad r1.w, r5.x, r12.x, r16.x + udiv r1.w, null, r1.w, l(7) + ubfe r17.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r3.xxxy + imad r16.xyz, r5.xxxx, r17.xyzx, r16.yzwy + udiv r16.xyz, null, r16.xyzx, l(7, 7, 7, 0) + imad r10.x, r16.x, l(0x00010000), r1.w + imad r10.y, r16.z, l(0x00010000), r16.y + movc r7.xy, r0.xxxx, r7.xyxx, r10.xyxx + ubfe r16.xyzw, l(3, 3, 3, 3), l(6, 9, 3, 6), r8.yyzz + ubfe r18.xyzw, l(3, 3, 3, 3), l(6, 9, 3, 6), r9.yyzz + imul null, r8.xy, r5.wwww, r18.xyxx + imad r8.xy, r5.zzzz, r16.xyxx, r8.xyxx + udiv r8.xy, null, r8.xyxx, l(5, 5, 0, 0) + imad r13.w, r8.y, l(0x00010000), r8.x + imad r8.xy, r14.ywyy, l(255, 255, 0, 0), r13.ywyy + ubfe r13.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r4.yyyy + imul null, r13.xyzw, r5.wwww, r13.xyzw + imad r1.w, r5.z, r12.y, r13.x + udiv r1.w, null, r1.w, l(7) + imad r3.x, r5.z, r17.w, r13.y + udiv r3.x, null, r3.x, l(7) + imad r4.x, r3.x, l(0x00010000), r1.w + ubfe r14.xyzw, l(3, 3, 3, 3), l(6, 9, 3, 6), r3.yyzz + imad r3.xy, r5.zzzz, r14.xyxx, r13.zwzz + udiv r3.xy, null, r3.xyxx, l(7, 7, 0, 0) + imad r4.y, r3.y, l(0x00010000), r3.x + movc r3.xy, r0.yyyy, r8.xyxx, r4.xyxx + ishl r3.xy, r3.xyxx, l(8, 8, 0, 0) + or r13.xy, r3.xyxx, r7.xyxx + imul null, r3.xy, r6.ywyy, r11.zwzz + imad r3.xy, r6.xzxx, r10.zwzz, r3.xyxx + udiv r3.xy, null, r3.xyxx, l(5, 5, 0, 0) + imul null, r4.xy, r6.yyyy, r18.zwzz + imad r4.xy, r6.xxxx, r16.zwzz, r4.xyxx + udiv r4.xy, null, r4.xyxx, l(5, 5, 0, 0) + imad r10.z, r4.x, l(0x00010000), r3.x + ubfe r8.xyzw, l(3, 3, 3, 3), l(9, 3, 6, 9), r8.zwww + ubfe r9.xyzw, l(3, 3, 3, 3), l(9, 3, 6, 9), r9.zwww + imul null, r9.xyzw, r6.ywww, r9.xyzw + imad r8.xyzw, r6.xzzz, r8.xyzw, r9.xyzw + udiv r8.xyzw, null, r8.xyzw, l(5, 5, 5, 5) + imad r10.w, r8.x, l(0x00010000), r4.y + ishl r9.xyzw, r7.zzww, l(13, 7, 13, 7) + and r9.xyzw, r9.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000) + bfi r7.xy, l(1, 1, 0, 0), l(0, 0, 0, 0), r7.zwzz, r9.xzxx + iadd r7.zw, r9.yyyw, r15.zzzw + imad r4.xy, r7.xzxx, l(255, 255, 0, 0), r10.zwzz + ubfe r9.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r4.zzzz + imul null, r9.xyzw, r6.yyyy, r9.xyzw + imad r1.w, r6.x, r12.z, r9.x + udiv r1.w, null, r1.w, l(7) + imad r7.xz, r6.xxxx, r14.zzwz, r9.yyzy + udiv r7.xz, null, r7.xxzx, l(7, 0, 7, 0) + imad r10.z, r7.x, l(0x00010000), r1.w + ubfe r11.xyzw, l(3, 3, 3, 3), l(9, 3, 6, 9), r3.zwww + imad r1.w, r6.x, r11.x, r9.w + udiv r1.w, null, r1.w, l(7) + imad r10.w, r1.w, l(0x00010000), r7.z + movc r3.xz, r1.xxxx, r4.xxyx, r10.zzwz + imad r9.z, r8.y, l(0x00010000), r3.y + imad r9.w, r8.w, l(0x00010000), r8.z + imad r3.yw, r7.yyyw, l(0, 255, 0, 255), r9.zzzw + ubfe r4.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r4.wwww + imul null, r4.xyzw, r4.xyzw, r6.wwww + imad r1.w, r6.z, r12.w, r4.x + udiv r1.w, null, r1.w, l(7) + imad r4.xyz, r6.zzzz, r11.yzwy, r4.yzwy + udiv r4.xyz, null, r4.xyzx, l(7, 7, 7, 0) + imad r7.z, r4.x, l(0x00010000), r1.w + imad r7.w, r4.z, l(0x00010000), r4.y + movc r3.yw, r1.zzzz, r3.yyyw, r7.zzzw + ishl r3.yw, r3.yyyw, l(0, 8, 0, 8) + or r13.zw, r3.yyyw, r3.xxxz + store_uav_typed U0[0].xyzw, r0.wwww, r13.xyzw + iadd r0.z, r0.z, l(1) + ult r1.w, r0.z, CB0[0][2].y + if_nz r1.w + iadd r0.w, r1.y, r0.w + ushr r2.xyzw, r2.xyzw, l(8, 8, 8, 8) + ushr r3.xyzw, r2.xxyy, l(1, 2, 1, 2) + and r4.xy, r2.xyxx, r3.xzxx + and r4.xy, r4.xyxx, l(0x00492492, 0x00492492, 0, 0) + ishl r4.zw, r4.xxxy, l(0, 0, 1, 1) + ushr r7.xy, r4.xyxx, l(1, 1, 0, 0) + iadd r4.xy, r4.xyxx, r4.zwzz + iadd r4.xy, r4.xyxx, r7.xyxx + and r7.xyzw, r2.xyzw, l(0x00249249, 0x00249249, 0x00249249, 0x00249249) + iadd r8.xyzw, r7.xyzw, l(0x00db6db6, 0x00db6db6, 0x00db6db6, 0x00db6db6) + and r4.zw, r4.xxxy, r8.xxxy + or r8.xy, r2.xyxx, r3.xzxx + and r9.xyzw, r3.xyzw, l(0x00249249, 0x00249249, 0x00249249, 0x00249249) + or r3.xy, r3.ywyy, r8.xyxx + and r3.xy, r3.xyxx, l(0x00249249, 0x00249249, 0, 0) + xor r3.xy, r3.xyxx, l(0x00249249, 0x00249249, 0, 0) + not r9.xyzw, r9.xyzw + and r10.xyzw, r7.xxyy, r9.xxzz + and r9.xyzw, r9.yyww, r10.xyzw + or r2.xy, r2.xyxx, r3.xyxx + iadd r2.xy, r2.xyxx, l(0xffdb6db7, 0xffdb6db7, 0, 0) + or r2.xy, r9.xwxx, r2.xyxx + ishl r3.xyzw, r9.xyzw, l(2, 1, 2, 1) + or r7.xy, r2.xyxx, r3.xzxx + not r4.xy, r4.xyxx + and r4.xy, r4.xyxx, r7.xyxx + or r4.xy, r4.zwzz, r4.xyxx + iadd r3.xy, r3.ywyy, r3.xzxx + or r2.xy, r2.xyxx, r3.xyxx + movc r3.xy, r0.xyxx, r4.xyxx, r2.xyxx + ushr r4.xyzw, r2.zzww, l(1, 2, 1, 2) + and r2.xy, r2.zwzz, r4.xzxx + and r2.xy, r2.xyxx, l(0x00492492, 0x00492492, 0, 0) + ishl r7.xy, r2.xyxx, l(1, 1, 0, 0) + ushr r8.xy, r2.xyxx, l(1, 1, 0, 0) + iadd r2.xy, r2.xyxx, r7.xyxx + iadd r2.xy, r2.xyxx, r8.xyxx + and r7.xy, r2.xyxx, r8.zwzz + or r8.xy, r2.zwzz, r4.xzxx + and r9.xyzw, r4.xyzw, l(0x00249249, 0x00249249, 0x00249249, 0x00249249) + or r4.xy, r4.ywyy, r8.xyxx + and r4.xy, r4.xyxx, l(0x00249249, 0x00249249, 0, 0) + xor r4.xy, r4.xyxx, l(0x00249249, 0x00249249, 0, 0) + not r8.xyzw, r9.xyzw + and r9.xyzw, r7.zzww, r8.xxzz + and r8.xyzw, r8.yyww, r9.xyzw + or r2.zw, r2.zzzw, r4.xxxy + iadd r2.zw, r2.zzzw, l(0, 0, 0xffdb6db7, 0xffdb6db7) + or r2.zw, r8.yyyw, r2.zzzw + ishl r4.xyzw, r8.xyzw, l(2, 1, 2, 1) + or r7.zw, r2.zzzw, r4.xxxz + not r2.xy, r2.xyxx + and r2.xy, r2.xyxx, r7.zwzz + or r2.xy, r7.xyxx, r2.xyxx + iadd r4.xy, r4.ywyy, r4.xzxx + or r2.zw, r2.zzzw, r4.xxxy + movc r3.zw, r1.xxxz, r2.xxxy, r2.zzzw + ushr r2.xy, r3.xyxx, l(1, 1, 0, 0) + and r2.xy, r3.xyxx, r2.xyxx + and r2.xy, r2.xyxx, l(1170, 1170, 0, 0) + ishl r2.zw, r2.xxxy, l(0, 0, 1, 1) + ushr r4.xy, r2.xyxx, l(1, 1, 0, 0) + iadd r2.xy, r2.xyxx, r2.zwzz + iadd r2.xy, r2.xyxx, r4.xyxx + not r4.xyzw, r2.xxxy + and r7.xyzw, r3.xxxy, r4.zzzw + iadd r8.xyzw, -r7.zzzw, l(2925, 2925, 2925, 2925) + and r4.xyzw, r4.xyzw, r8.xyzw + and r2.zw, r4.zzzw, l(0, 0, 7, 7) + and r8.xy, r7.zwzz, l(7, 7, 0, 0) + imul null, r8.xy, r5.ywyy, r8.xyxx + imad r2.zw, r5.xxxz, r2.zzzw, r8.xxxy + udiv r2.zw, null, r2.zzzw, l(0, 0, 5, 5) + ubfe r8.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r4.xyzw + ubfe r9.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r7.xyzw + imul null, r9.xyzw, r5.yyyw, r9.xyzw + imad r8.xyzw, r5.xxxz, r8.xyzw, r9.xyzw + udiv r8.xyzw, null, r8.xyzw, l(5, 5, 5, 5) + imad r9.xy, r8.xwxx, l(0x00010000, 0x00010000, 0, 0), r2.zwzz + imad r9.z, r8.z, l(0x00010000), r8.y + and r2.xy, r2.xyxx, r3.xyxx + ishl r8.xyzw, r2.xxyy, l(13, 7, 13, 7) + and r8.xyzw, r8.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000) + bfi r10.xy, l(1, 1, 0, 0), l(0, 0, 0, 0), r2.xyxx, r8.xzxx + ubfe r2.xy, l(1, 1, 0, 0), l(6, 6, 0, 0), r2.xyxx + iadd r10.zw, r8.yyyw, r2.xxxy + imad r2.xy, r10.xzxx, l(255, 255, 0, 0), r9.xzxx + not r8.xyzw, r3.xxxy + and r2.zw, r8.zzzw, l(0, 0, 7, 7) + and r11.xyzw, r3.xyzw, l(7, 7, 7, 7) + imul null, r4.xy, r5.ywyy, r11.xyxx + imad r2.zw, r5.xxxz, r2.zzzw, r4.xxxy + udiv r2.zw, null, r2.zzzw, l(0, 0, 7, 7) + ubfe r12.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r8.xyzw + ubfe r13.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r3.xxxy + imul null, r13.xyzw, r5.yyyw, r13.xyzw + imad r12.xyzw, r5.xxxz, r12.xyzw, r13.xyzw + udiv r12.xyzw, null, r12.xyzw, l(7, 7, 7, 7) + imad r13.xy, r12.xwxx, l(0x00010000, 0x00010000, 0, 0), r2.zwzz + imad r13.z, r12.z, l(0x00010000), r12.y + ubfe r2.zw, l(0, 0, 3, 3), l(0, 0, 6, 9), r4.wwww + ubfe r4.xy, l(3, 3, 0, 0), l(6, 9, 0, 0), r7.wwww + imul null, r4.xy, r4.xyxx, r5.wwww + imad r2.zw, r5.zzzz, r2.zzzw, r4.xxxy + udiv r2.zw, null, r2.zzzw, l(0, 0, 5, 5) + imad r9.w, r2.w, l(0x00010000), r2.z + imad r2.zw, r10.yyyw, l(0, 0, 255, 255), r9.yyyw + ubfe r4.xy, l(3, 3, 0, 0), l(6, 9, 0, 0), r8.wwww + ubfe r7.xyzw, l(3, 3, 3, 3), l(6, 9, 6, 9), r3.yyww + imul null, r4.zw, r5.wwww, r7.xxxy + imad r4.xy, r5.zzzz, r4.xyxx, r4.zwzz + udiv r4.xy, null, r4.xyxx, l(7, 7, 0, 0) + imad r13.w, r4.y, l(0x00010000), r4.x + movc r2.xyzw, r0.xxyy, r2.xyzw, r13.xzyw + ishl r2.zw, r2.zzzw, l(0, 0, 8, 8) + or r2.xy, r2.zwzz, r2.xyxx + ushr r4.xy, r3.zwzz, l(1, 1, 0, 0) + and r4.xy, r3.zwzz, r4.xyxx + and r4.xy, r4.xyxx, l(1170, 1170, 0, 0) + ishl r4.zw, r4.xxxy, l(0, 0, 1, 1) + ushr r7.xy, r4.xyxx, l(1, 1, 0, 0) + iadd r4.xy, r4.xyxx, r4.zwzz + iadd r4.xy, r4.xyxx, r7.xyxx + not r8.xyzw, r4.xxxy + and r9.xyzw, r3.zzzw, r8.zzzw + iadd r10.xyzw, -r9.zzzw, l(2925, 2925, 2925, 2925) + and r8.xyzw, r8.xyzw, r10.xyzw + and r4.zw, r8.zzzw, l(0, 0, 7, 7) + and r7.xy, r9.zwzz, l(7, 7, 0, 0) + imul null, r7.xyzw, r6.ywww, r7.xyzw + imad r4.zw, r6.xxxz, r4.zzzw, r7.xxxy + udiv r4.zw, null, r4.zzzw, l(0, 0, 5, 5) + ubfe r10.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r8.xyzw + ubfe r12.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r9.xyzw + imul null, r12.xyzw, r6.yyyw, r12.xyzw + imad r10.xyzw, r6.xxxz, r10.xyzw, r12.xyzw + udiv r10.xyzw, null, r10.xyzw, l(5, 5, 5, 5) + imad r12.xy, r10.xwxx, l(0x00010000, 0x00010000, 0, 0), r4.zwzz + imad r12.z, r10.z, l(0x00010000), r10.y + and r4.xy, r3.zwzz, r4.xyxx + ishl r10.xyzw, r4.xxyy, l(13, 7, 13, 7) + and r10.xyzw, r10.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000) + bfi r13.xy, l(1, 1, 0, 0), l(0, 0, 0, 0), r4.xyxx, r10.xzxx + ubfe r4.xy, l(1, 1, 0, 0), l(6, 6, 0, 0), r4.xyxx + iadd r13.zw, r10.yyyw, r4.xxxy + imad r4.xy, r13.xzxx, l(255, 255, 0, 0), r12.xzxx + not r10.xyzw, r3.zzzw + and r4.zw, r10.zzzw, l(0, 0, 7, 7) + imul null, r7.xy, r6.ywyy, r11.zwzz + imad r4.zw, r6.xxxz, r4.zzzw, r7.xxxy + udiv r4.zw, null, r4.zzzw, l(0, 0, 7, 7) + ubfe r11.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r10.xyzw + ubfe r14.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r3.zzzw + imul null, r14.xyzw, r6.yyyw, r14.xyzw + imad r11.xyzw, r6.xxxz, r11.xyzw, r14.xyzw + udiv r11.xyzw, null, r11.xyzw, l(7, 7, 7, 7) + imad r14.xy, r11.xwxx, l(0x00010000, 0x00010000, 0, 0), r4.zwzz + imad r14.z, r11.z, l(0x00010000), r11.y + ubfe r4.zw, l(0, 0, 3, 3), l(0, 0, 6, 9), r8.wwww + ubfe r7.xy, l(3, 3, 0, 0), l(6, 9, 0, 0), r9.wwww + imul null, r7.xy, r6.wwww, r7.xyxx + imad r4.zw, r6.zzzz, r4.zzzw, r7.xxxy + udiv r4.zw, null, r4.zzzw, l(0, 0, 5, 5) + imad r12.w, r4.w, l(0x00010000), r4.z + imad r4.zw, r13.yyyw, l(0, 0, 255, 255), r12.yyyw + ubfe r7.xy, l(3, 3, 0, 0), l(6, 9, 0, 0), r10.wwww + imad r7.xy, r6.zzzz, r7.xyxx, r7.zwzz + udiv r7.xy, null, r7.xyxx, l(7, 7, 0, 0) + imad r14.w, r7.y, l(0x00010000), r7.x + movc r4.xyzw, r1.xxzz, r4.xyzw, r14.xzyw + ishl r4.zw, r4.zzzw, l(0, 0, 8, 8) + or r2.zw, r4.zzzw, r4.xxxy + store_uav_typed U0[0].xyzw, r0.wwww, r2.xyzw + or r0.z, r0.z, l(3) + ult r0.z, r0.z, CB0[0][2].y + if_nz r0.z + iadd r0.z, r1.y, r0.w + ushr r2.xyzw, r3.xyzw, l(12, 12, 12, 12) + ushr r4.xyzw, r2.xyzw, l(1, 1, 1, 1) + and r4.xyzw, r2.xyzw, r4.xyzw + and r4.xyzw, r4.xyzw, l(1170, 1170, 1170, 1170) + ishl r7.xyzw, r4.xyzw, l(1, 1, 1, 1) + ushr r8.xyzw, r4.xyzw, l(1, 1, 1, 1) + iadd r4.xyzw, r4.xyzw, r7.xyzw + iadd r4.xyzw, r4.xyzw, r8.xyzw + not r7.xyzw, r4.xyzw + and r8.xyzw, r2.xyzw, r7.xyzw + iadd r9.xyzw, -r8.xyzw, l(2925, 2925, 2925, 2925) + and r7.xyzw, r7.xyzw, r9.xyzw + and r9.xyzw, r7.xyzw, l(7, 7, 7, 7) + and r10.xyzw, r8.xyzw, l(7, 7, 7, 7) + imul null, r1.yw, r5.yyyw, r10.xxxy + imad r1.yw, r5.xxxz, r9.xxxy, r1.yyyw + udiv r1.yw, null, r1.yyyw, l(0, 5, 0, 5) + ubfe r11.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r7.xxxy + ubfe r12.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r8.xxxy + imul null, r12.xyzw, r5.yyyw, r12.xyzw + imad r11.xyzw, r5.xxxz, r11.xyzw, r12.xyzw + udiv r11.xyzw, null, r11.xyzw, l(5, 5, 5, 5) + imad r12.xy, r11.xwxx, l(0x00010000, 0x00010000, 0, 0), r1.ywyy + imad r12.z, r11.z, l(0x00010000), r11.y + and r4.xyzw, r2.xyzw, r4.xyzw + ishl r11.xyzw, r4.xxyy, l(13, 7, 13, 7) + and r11.xyzw, r11.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000) + bfi r13.xy, l(1, 1, 0, 0), l(0, 0, 0, 0), r4.xyxx, r11.xzxx + ubfe r14.xyzw, l(1, 1, 1, 1), l(6, 6, 6, 6), r4.xyzw + iadd r13.zw, r11.yyyw, r14.xxxy + imad r1.yw, r13.xxxz, l(0, 255, 0, 255), r12.xxxz + not r2.xyzw, r2.xyzw + and r11.xyzw, r2.xyzw, l(7, 7, 7, 7) + ubfe r15.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r3.xxxx + imul null, r15.xyzw, r5.yyyy, r15.xyzw + imad r0.w, r5.x, r11.x, r15.x + udiv r0.w, null, r0.w, l(7) + ubfe r16.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r2.xxxy + imad r15.xyz, r5.xxxx, r16.xyzx, r15.yzwy + udiv r15.xyz, null, r15.xyzx, l(7, 7, 7, 0) + imad r4.x, r15.x, l(0x00010000), r0.w + imad r4.y, r15.z, l(0x00010000), r15.y + movc r0.xw, r0.xxxx, r1.yyyw, r4.xxxy + ubfe r15.xyzw, l(3, 3, 3, 3), l(6, 9, 3, 6), r7.yyzz + ubfe r17.xyzw, l(3, 3, 3, 3), l(6, 9, 3, 6), r8.yyzz + imul null, r1.yw, r5.wwww, r17.xxxy + imad r1.yw, r5.zzzz, r15.xxxy, r1.yyyw + udiv r1.yw, null, r1.yyyw, l(0, 5, 0, 5) + imad r12.w, r1.w, l(0x00010000), r1.y + imad r1.yw, r13.yyyw, l(0, 255, 0, 255), r12.yyyw + ubfe r12.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r3.yyyy + imul null, r12.xyzw, r5.wwww, r12.xyzw + imad r2.x, r5.z, r11.y, r12.x + udiv r2.x, null, r2.x, l(7) + imad r3.x, r5.z, r16.w, r12.y + udiv r3.x, null, r3.x, l(7) + imad r3.x, r3.x, l(0x00010000), r2.x + ubfe r13.xyzw, l(3, 3, 3, 3), l(6, 9, 3, 6), r2.yyzz + imad r2.xy, r5.zzzz, r13.xyxx, r12.zwzz + udiv r2.xy, null, r2.xyxx, l(7, 7, 0, 0) + imad r3.y, r2.y, l(0x00010000), r2.x + movc r1.yw, r0.yyyy, r1.yyyw, r3.xxxy + ishl r1.yw, r1.yyyw, l(0, 8, 0, 8) + or r5.xy, r0.xwxx, r1.ywyy + imul null, r0.xy, r6.ywyy, r10.zwzz + imad r0.xy, r6.xzxx, r9.zwzz, r0.xyxx + udiv r0.xy, null, r0.xyxx, l(5, 5, 0, 0) + imul null, r1.yw, r6.yyyy, r17.zzzw + imad r1.yw, r6.xxxx, r15.zzzw, r1.yyyw + udiv r1.yw, null, r1.yyyw, l(0, 5, 0, 5) + imad r9.z, r1.y, l(0x00010000), r0.x + ubfe r7.xyzw, l(3, 3, 3, 3), l(9, 3, 6, 9), r7.zwww + ubfe r8.xyzw, l(3, 3, 3, 3), l(9, 3, 6, 9), r8.zwww + imul null, r8.xyzw, r6.ywww, r8.xyzw + imad r7.xyzw, r6.xzzz, r7.xyzw, r8.xyzw + udiv r7.xyzw, null, r7.xyzw, l(5, 5, 5, 5) + imad r9.w, r7.x, l(0x00010000), r1.w + ishl r8.xyzw, r4.zzww, l(13, 7, 13, 7) + and r8.xyzw, r8.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000) + bfi r4.xy, l(1, 1, 0, 0), l(0, 0, 0, 0), r4.zwzz, r8.xzxx + iadd r4.zw, r8.yyyw, r14.zzzw + imad r0.xw, r4.xxxz, l(255, 0, 0, 255), r9.zzzw + ubfe r8.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r3.zzzz + imul null, r8.xyzw, r6.yyyy, r8.xyzw + imad r1.y, r6.x, r11.z, r8.x + udiv r1.y, null, r1.y, l(7) + imad r2.xy, r6.xxxx, r13.zwzz, r8.yzyy + udiv r2.xy, null, r2.xyxx, l(7, 7, 0, 0) + imad r9.z, r2.x, l(0x00010000), r1.y + ubfe r10.xyzw, l(3, 3, 3, 3), l(9, 3, 6, 9), r2.zwww + imad r1.y, r6.x, r10.x, r8.w + udiv r1.y, null, r1.y, l(7) + imad r9.w, r1.y, l(0x00010000), r2.y + movc r0.xw, r1.xxxx, r0.xxxw, r9.zzzw + imad r2.z, r7.y, l(0x00010000), r0.y + imad r2.w, r7.w, l(0x00010000), r7.z + imad r1.xy, r4.ywyy, l(255, 255, 0, 0), r2.zwzz + ubfe r2.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r3.wwww + imul null, r2.xyzw, r2.xyzw, r6.wwww + imad r0.y, r6.z, r11.w, r2.x + udiv r0.y, null, r0.y, l(7) + imad r2.xyz, r6.zzzz, r10.yzwy, r2.yzwy + udiv r2.xyz, null, r2.xyzx, l(7, 7, 7, 0) + imad r3.z, r2.x, l(0x00010000), r0.y + imad r3.w, r2.z, l(0x00010000), r2.y + movc r1.xy, r1.zzzz, r1.xyxx, r3.zwzz + ishl r1.xy, r1.xyxx, l(8, 8, 0, 0) + or r5.zw, r0.xxxw, r1.xxxy + store_uav_typed U0[0].xyzw, r0.zzzz, r5.xyzw + endif + endif +endif +ret +// Approximately 697 instruction slots used +#endif + +const BYTE texture_load_dxn_rg8_cs[] = { + 68, 88, 66, 67, 137, 87, 255, 185, 52, 190, 36, 210, 133, 55, 111, 212, 122, 171, 135, + 87, 1, 0, 0, 0, 244, 106, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 88, 106, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 28, 102, 0, + 0, 81, 0, 5, 0, 135, 25, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 19, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 35, 0, 0, 10, 34, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, + 11, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 30, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 85, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, + 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 150, 5, 2, + 0, 2, 64, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 1, 0, 0, 0, 246, 139, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 14, 146, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 2, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 96, + 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, + 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 18, 0, 0, 0, 18, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 15, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 35, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 50, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 138, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, + 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, + 0, 14, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 2, 0, 42, 0, 0, + 9, 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 9, 66, + 0, 16, 0, 2, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, + 82, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 140, 0, + 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 5, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 21, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 18, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 6, + 0, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, + 98, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, + 0, 21, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 14, 0, + 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 86, + 6, 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, + 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, 3, 0, 0, 0, 140, 0, + 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, + 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, + 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 41, 0, 0, 7, 18, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 2, 0, 58, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 2, 0, + 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 0, 0, 0, + 0, 86, 13, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 214, 120, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 32, 0, 0, 10, 210, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, + 11, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, + 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 38, 7, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, + 0, 4, 0, 0, 0, 38, 7, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 2, 0, 0, 0, 214, 8, 16, 0, 3, 0, 0, 0, 214, 8, + 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 38, 7, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 214, 8, 16, 0, 3, 0, 0, 0, 54, 0, 0, + 5, 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 18, 0, + 0, 1, 54, 0, 0, 5, 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 2, + 0, 0, 0, 21, 0, 0, 1, 55, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, + 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 214, 120, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 38, 7, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 38, 7, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 4, 0, + 0, 0, 214, 8, 16, 0, 5, 0, 0, 0, 214, 8, 16, 0, 6, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 38, 7, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 214, 8, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 194, 0, 16, 0, 2, 0, + 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 194, + 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, + 85, 0, 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 134, 13, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, + 255, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 38, + 7, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 4, 0, 0, + 0, 70, 0, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 80, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 214, 5, + 16, 0, 5, 0, 0, 0, 134, 0, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 4, 0, 0, 0, 6, 5, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, + 7, 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 6, 2, + 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, + 2, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 146, 36, 73, 0, 0, 0, 0, 0, + 146, 36, 73, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 7, 0, 0, + 0, 134, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 7, + 0, 0, 0, 6, 8, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 82, 0, 16, + 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 7, 0, + 0, 0, 30, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, + 0, 0, 0, 166, 11, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 7, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 73, 146, 36, + 0, 73, 146, 36, 0, 73, 146, 36, 0, 73, 146, 36, 0, 30, 0, 0, 10, 242, 0, + 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 182, + 109, 219, 0, 182, 109, 219, 0, 182, 109, 219, 0, 182, 109, 219, 0, 1, 0, 0, 7, + 50, 0, 16, 0, 8, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, + 0, 8, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 9, 0, 0, 0, 70, 0, + 16, 0, 3, 0, 0, 0, 134, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 73, 146, 36, 0, 73, 146, 36, 0, 73, 146, 36, 0, 73, 146, 36, 0, 60, 0, 0, + 7, 50, 0, 16, 0, 4, 0, 0, 0, 214, 5, 16, 0, 4, 0, 0, 0, 70, 0, + 16, 0, 9, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, + 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 73, 146, 36, 0, 73, 146, 36, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, + 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 73, 146, 36, 0, 73, 146, + 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 5, 242, 0, 16, 0, 9, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, + 10, 0, 0, 0, 6, 5, 16, 0, 7, 0, 0, 0, 6, 10, 16, 0, 9, 0, 0, + 0, 1, 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 86, 15, 16, 0, 9, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 3, + 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, + 30, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 183, 109, 219, 255, 183, 109, 219, 255, 0, 0, 0, 0, 0, 0, + 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 198, 0, 16, 0, 9, + 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, + 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 50, 0, + 16, 0, 7, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 134, 0, 16, 0, 4, + 0, 0, 0, 59, 0, 0, 5, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, + 1, 0, 0, 0, 1, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, + 0, 1, 0, 0, 0, 6, 1, 16, 0, 7, 0, 0, 0, 60, 0, 0, 7, 82, 0, + 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 8, 0, 0, 0, 6, 2, 16, 0, 1, + 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 214, 5, 16, 0, + 4, 0, 0, 0, 134, 0, 16, 0, 4, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, + 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 4, 0, + 0, 0, 55, 0, 0, 9, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 0, + 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, + 80, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 86, 7, 16, 0, 6, 0, 0, + 0, 6, 2, 16, 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 9, 0, + 0, 0, 166, 15, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, + 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 7, 50, 0, 16, 0, + 3, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 134, 0, 16, 0, 9, 0, 0, + 0, 1, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 146, 36, 73, 0, 146, 36, 73, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 7, 0, 0, 0, 70, 0, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 8, 0, 0, 0, 70, 0, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, + 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, + 7, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, + 16, 0, 8, 0, 0, 0, 1, 0, 0, 7, 50, 0, 16, 0, 7, 0, 0, 0, 70, + 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 8, 0, 0, 0, 60, 0, 0, 7, + 50, 0, 16, 0, 8, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 134, 0, 16, + 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 73, 146, 36, 0, 73, 146, 36, 0, 73, + 146, 36, 0, 73, 146, 36, 0, 60, 0, 0, 7, 50, 0, 16, 0, 8, 0, 0, 0, + 214, 5, 16, 0, 9, 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, + 10, 50, 0, 16, 0, 8, 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 2, 64, + 0, 0, 73, 146, 36, 0, 73, 146, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, + 0, 0, 10, 50, 0, 16, 0, 8, 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 73, 146, 36, 0, 73, 146, 36, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 59, 0, 0, 5, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 166, 15, 16, 0, 7, + 0, 0, 0, 6, 10, 16, 0, 9, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, + 9, 0, 0, 0, 86, 15, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 60, 0, 0, 7, 194, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 3, 0, + 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 30, 0, 0, 10, 194, 0, 16, 0, 3, + 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 183, 109, 219, 255, 183, 109, 219, 255, 60, 0, 0, 7, 194, 0, 16, + 0, 3, 0, 0, 0, 86, 13, 16, 0, 9, 0, 0, 0, 166, 14, 16, 0, 3, 0, + 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 9, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 7, 0, 0, 0, 166, 14, 16, + 0, 3, 0, 0, 0, 6, 8, 16, 0, 8, 0, 0, 0, 59, 0, 0, 5, 50, 0, + 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 50, + 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, + 7, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, + 0, 7, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 50, 0, + 16, 0, 7, 0, 0, 0, 214, 5, 16, 0, 8, 0, 0, 0, 134, 0, 16, 0, 8, + 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, + 3, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 55, 0, 0, 9, 194, 0, 16, + 0, 4, 0, 0, 0, 6, 8, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 3, 0, + 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 3, + 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 50, 0, 16, + 0, 3, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 3, 0, + 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 146, 4, 0, 0, 146, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 6, 4, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 7, 0, 0, 0, 70, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, + 0, 70, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 30, 0, + 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, + 0, 16, 0, 7, 0, 0, 0, 59, 0, 0, 5, 242, 0, 16, 0, 7, 0, 0, 0, + 6, 4, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, + 0, 6, 4, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 7, 0, 0, 0, 30, 0, + 0, 11, 242, 0, 16, 0, 9, 0, 0, 0, 166, 14, 16, 128, 65, 0, 0, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, + 109, 11, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, + 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 1, 0, 0, 10, 194, 0, + 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, + 50, 0, 16, 0, 9, 0, 0, 0, 230, 10, 16, 0, 8, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, + 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 9, 0, 0, 0, 214, 5, 16, 0, 5, + 0, 0, 0, 70, 0, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 194, 0, 16, 0, + 3, 0, 0, 0, 6, 8, 16, 0, 5, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, + 0, 6, 4, 16, 0, 9, 0, 0, 0, 78, 0, 0, 11, 194, 0, 16, 0, 3, 0, + 0, 0, 0, 208, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 138, 0, 0, 15, + 242, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, + 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 138, + 0, 0, 15, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, 0, 8, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 10, 0, 0, 0, 86, + 13, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 35, 0, 0, 9, + 242, 0, 16, 0, 9, 0, 0, 0, 6, 8, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 78, 0, 0, 11, 242, 0, + 16, 0, 9, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 35, 0, 0, 12, 50, 0, 16, 0, 10, 0, 0, 0, 198, 0, 16, 0, 9, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 10, + 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, + 26, 0, 16, 0, 9, 0, 0, 0, 1, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, + 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 41, 0, + 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 6, 5, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 13, 0, 0, 0, 7, 0, 0, 0, 13, 0, 0, 0, 7, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 140, 0, 0, 17, 50, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 3, 0, 0, 0, 134, 0, 16, 0, 9, 0, 0, 0, 138, 0, 0, 15, 50, 0, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, + 7, 194, 0, 16, 0, 11, 0, 0, 0, 86, 13, 16, 0, 9, 0, 0, 0, 6, 4, + 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 134, + 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 134, 0, 16, 0, 10, 0, 0, 0, 59, 0, 0, + 5, 242, 0, 16, 0, 9, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 1, 0, + 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 9, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 7, 0, 0, 0, 214, + 5, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 12, 0, 0, 0, 35, 0, 0, 9, + 194, 0, 16, 0, 3, 0, 0, 0, 6, 8, 16, 0, 5, 0, 0, 0, 166, 14, 16, + 0, 3, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 78, 0, 0, 11, 194, 0, + 16, 0, 3, 0, 0, 0, 0, 208, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 138, 0, 0, 15, 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, 0, 9, + 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 6, 4, + 16, 0, 4, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 14, + 0, 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, + 35, 0, 0, 9, 242, 0, 16, 0, 13, 0, 0, 0, 6, 8, 16, 0, 5, 0, 0, + 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 78, 0, + 0, 11, 242, 0, 16, 0, 13, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 14, 0, 0, 0, 198, 0, 16, + 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 35, 0, 0, 9, 66, + 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 13, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 1, 0, 26, 0, 16, 0, 13, 0, 0, 0, 138, 0, 0, 15, 194, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 9, 0, 0, 0, 246, 15, 16, 0, 7, 0, 0, 0, 138, 0, 0, 15, + 50, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 8, 0, 0, 0, 38, + 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 7, 0, 0, 0, 246, 15, 16, 0, + 5, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 35, 0, 0, 9, 194, 0, 16, + 0, 3, 0, 0, 0, 166, 10, 16, 0, 5, 0, 0, 0, 166, 14, 16, 0, 3, 0, + 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 78, 0, 0, 11, 194, 0, 16, 0, 3, + 0, 0, 0, 0, 208, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, + 9, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 1, 0, 42, 0, 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 194, + 0, 16, 0, 3, 0, 0, 0, 86, 13, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 13, 16, + 0, 10, 0, 0, 0, 138, 0, 0, 15, 50, 0, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 246, 15, 16, 0, 9, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 6, 0, 0, 0, 9, + 0, 0, 0, 86, 15, 16, 0, 4, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 194, 0, 16, 0, 7, 0, 0, 0, 246, 15, 16, 0, 5, 0, 0, 0, 6, 4, 16, + 0, 8, 0, 0, 0, 35, 0, 0, 9, 50, 0, 16, 0, 7, 0, 0, 0, 166, 10, + 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 230, 10, 16, 0, 7, + 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, 0, 7, 0, 0, 0, 0, 208, 0, 0, + 70, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 14, 0, + 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, + 0, 16, 0, 7, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 3, 0, 0, 0, + 6, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 134, 13, 16, + 0, 14, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 166, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, + 230, 10, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 85, 0, 0, + 10, 50, 0, 16, 0, 7, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 7, 50, 0, 16, 0, 7, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, + 70, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 7, 0, 0, + 0, 70, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 146, 4, 0, 0, 146, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 7, + 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, + 0, 8, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, + 0, 16, 0, 7, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 230, 10, 16, 0, + 7, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 7, 0, 0, 0, 70, 0, 16, + 0, 7, 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 59, 0, 0, 5, 242, 0, + 16, 0, 9, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 1, 0, 0, 7, 242, + 0, 16, 0, 10, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, + 9, 0, 0, 0, 30, 0, 0, 11, 242, 0, 16, 0, 11, 0, 0, 0, 166, 14, 16, + 128, 65, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 109, 11, 0, 0, 109, 11, + 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 9, + 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 1, 0, 0, 10, 194, 0, 16, 0, 7, 0, 0, 0, 166, 14, 16, 0, 9, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 8, 0, 0, 0, 230, 10, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 8, 0, 0, + 0, 214, 15, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 35, 0, + 0, 9, 194, 0, 16, 0, 7, 0, 0, 0, 6, 8, 16, 0, 6, 0, 0, 0, 166, + 14, 16, 0, 7, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 78, 0, 0, 11, + 194, 0, 16, 0, 7, 0, 0, 0, 0, 208, 0, 0, 166, 14, 16, 0, 7, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, + 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 9, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, + 0, 13, 0, 0, 0, 86, 13, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 13, 0, + 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 11, 0, 0, 0, 6, 8, 16, 0, 6, + 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, + 78, 0, 0, 11, 242, 0, 16, 0, 11, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, + 0, 0, 5, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 13, 0, 0, 0, 198, + 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 230, 10, 16, 0, 7, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 13, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 1, 0, 26, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 7, 50, + 0, 16, 0, 7, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, + 7, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 6, 5, 16, + 0, 7, 0, 0, 0, 2, 64, 0, 0, 13, 0, 0, 0, 7, 0, 0, 0, 13, 0, + 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, + 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 140, 0, 0, 17, 50, 0, 16, 0, 14, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 134, 0, 16, 0, 11, 0, 0, 0, + 138, 0, 0, 15, 50, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 6, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 7, + 0, 0, 0, 30, 0, 0, 7, 194, 0, 16, 0, 14, 0, 0, 0, 86, 13, 16, 0, + 11, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, + 0, 7, 0, 0, 0, 134, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 0, 16, 0, 13, + 0, 0, 0, 59, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 166, 14, 16, 0, + 4, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 7, 0, 0, 0, 166, 14, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 8, + 0, 0, 0, 214, 5, 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, 12, 0, 0, 0, + 35, 0, 0, 9, 194, 0, 16, 0, 7, 0, 0, 0, 6, 8, 16, 0, 6, 0, 0, + 0, 166, 14, 16, 0, 7, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 78, 0, + 0, 11, 194, 0, 16, 0, 7, 0, 0, 0, 0, 208, 0, 0, 166, 14, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 11, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 15, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, + 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, + 0, 16, 0, 15, 0, 0, 0, 86, 13, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, + 15, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 12, 0, 0, 0, 6, 8, 16, + 0, 6, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 15, 0, + 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 12, 0, 0, 0, 0, 208, 0, 0, 70, + 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 15, 0, 0, + 0, 198, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 10, 16, 0, 7, 0, 0, 0, 35, + 0, 0, 9, 66, 0, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 1, 0, 26, 0, 16, 0, 12, 0, 0, 0, 138, 0, 0, + 15, 194, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 246, 15, 16, 0, 9, 0, 0, 0, + 138, 0, 0, 15, 50, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 6, 0, + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 10, + 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 8, 0, 0, 0, + 246, 15, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 35, 0, 0, + 9, 194, 0, 16, 0, 7, 0, 0, 0, 166, 10, 16, 0, 6, 0, 0, 0, 166, 14, + 16, 0, 7, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 78, 0, 0, 11, 194, + 0, 16, 0, 7, 0, 0, 0, 0, 208, 0, 0, 166, 14, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, + 0, 35, 0, 0, 9, 130, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 7, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 42, 0, 16, 0, 7, 0, 0, 0, 35, + 0, 0, 12, 194, 0, 16, 0, 7, 0, 0, 0, 86, 13, 16, 0, 14, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 86, 13, 16, 0, 13, 0, 0, 0, 138, 0, 0, 15, 50, 0, 16, 0, 8, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 246, 15, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 50, 0, 16, + 0, 8, 0, 0, 0, 166, 10, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 8, 0, + 0, 0, 230, 10, 16, 0, 8, 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, 0, 8, + 0, 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 130, 0, 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 8, 0, 0, 0, 55, 0, 0, 9, 242, + 0, 16, 0, 7, 0, 0, 0, 6, 10, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 134, 13, 16, 0, 15, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, + 0, 7, 0, 0, 0, 166, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 60, 0, 0, 7, 194, + 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 7, 0, 0, 0, 6, 4, 16, 0, + 7, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 35, 0, + 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 79, 0, 0, 9, 130, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, + 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, + 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 85, 0, 0, 10, 242, 0, + 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, + 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, + 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 146, 4, 0, 0, 146, 4, 0, 0, 146, + 4, 0, 0, 146, 4, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, + 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 9, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 59, 0, 0, 5, 242, 0, 16, 0, 8, + 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, + 0, 30, 0, 0, 11, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 128, 65, 0, + 0, 0, 9, 0, 0, 0, 2, 64, 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, 109, + 11, 0, 0, 109, 11, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, + 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 11, 0, 0, 0, 214, 5, + 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 50, + 0, 16, 0, 10, 0, 0, 0, 134, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, + 10, 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, + 0, 10, 0, 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, + 0, 0, 15, 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 6, 4, 16, 0, 8, 0, + 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 6, 4, 16, + 0, 9, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 13, 0, + 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 35, + 0, 0, 9, 242, 0, 16, 0, 12, 0, 0, 0, 6, 8, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 78, 0, 0, + 11, 242, 0, 16, 0, 12, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 13, 0, 0, 0, 198, 0, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 70, 0, 16, 0, 10, 0, 0, 0, 35, 0, 0, 9, 66, 0, + 16, 0, 13, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 1, 0, 26, 0, 16, 0, 12, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, + 7, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 6, 5, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 13, 0, 0, 0, 7, 0, 0, 0, 13, 0, 0, 0, 7, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 140, 0, 0, 17, 50, 0, 16, 0, 14, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 7, 0, 0, 0, 134, 0, 16, 0, 12, 0, 0, 0, 138, 0, 0, + 15, 242, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, + 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 30, 0, 0, 7, 194, 0, 16, 0, 14, 0, 0, 0, 86, 13, 16, 0, 12, 0, 0, + 0, 6, 4, 16, 0, 15, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 7, 0, + 0, 0, 134, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 0, 16, 0, 13, 0, 0, 0, + 59, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 12, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 21, 0, 0, 0, 6, 0, + 16, 0, 4, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 16, + 0, 0, 0, 86, 5, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, + 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, + 0, 10, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 16, 0, 0, 0, 78, 0, + 0, 8, 130, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, + 17, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, + 0, 0, 3, 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 35, 0, 0, 9, 114, + 0, 16, 0, 16, 0, 0, 0, 6, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 150, 7, 16, 0, 16, 0, 0, 0, 78, 0, 0, 11, 114, 0, 16, + 0, 16, 0, 0, 0, 0, 208, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 35, + 0, 0, 9, 18, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 16, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 1, 0, 58, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, + 9, 34, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 16, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 1, 0, 26, 0, 16, 0, 16, 0, 0, 0, 55, 0, 0, 9, 50, + 0, 16, 0, 7, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 7, 0, 0, 0, 70, 0, 16, 0, 10, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, + 0, 16, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, + 0, 0, 0, 6, 0, 0, 0, 86, 10, 16, 0, 8, 0, 0, 0, 138, 0, 0, 15, + 242, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 9, 0, + 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 86, 10, 16, 0, 9, 0, 0, 0, 38, + 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 8, 0, 0, 0, 246, 15, 16, 0, + 5, 0, 0, 0, 70, 0, 16, 0, 18, 0, 0, 0, 35, 0, 0, 9, 50, 0, 16, + 0, 8, 0, 0, 0, 166, 10, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 16, 0, + 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, 0, 8, + 0, 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, + 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 130, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 8, 0, 0, 0, 35, 0, 0, 12, 50, + 0, 16, 0, 8, 0, 0, 0, 214, 5, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 5, 16, + 0, 13, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 21, 0, 0, 0, + 86, 5, 16, 0, 4, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, + 0, 13, 0, 0, 0, 246, 15, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 13, 0, + 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 5, + 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, + 78, 0, 0, 8, 130, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 35, 0, 0, 9, 18, 0, + 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 17, + 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 78, 0, 0, 8, 18, 0, 16, 0, + 3, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 7, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 86, 10, + 16, 0, 3, 0, 0, 0, 35, 0, 0, 9, 50, 0, 16, 0, 3, 0, 0, 0, 166, + 10, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 14, 0, 0, 0, 230, 10, 16, 0, + 13, 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, 0, 3, 0, 0, 0, 0, 208, 0, + 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 4, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, + 10, 0, 16, 0, 3, 0, 0, 0, 55, 0, 0, 9, 50, 0, 16, 0, 3, 0, 0, + 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 70, 0, + 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 13, 0, 0, + 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 38, 0, + 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 3, 0, 0, 0, 214, 5, 16, 0, 6, + 0, 0, 0, 230, 10, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 50, 0, 16, 0, + 3, 0, 0, 0, 134, 0, 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, 10, 0, 0, + 0, 70, 0, 16, 0, 3, 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, 0, 3, 0, + 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 5, + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, + 0, 208, 0, 0, 50, 0, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 6, 0, 0, + 0, 230, 10, 16, 0, 18, 0, 0, 0, 35, 0, 0, 9, 50, 0, 16, 0, 4, 0, + 0, 0, 6, 0, 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, 16, 0, 0, 0, 70, + 0, 16, 0, 4, 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, 0, 4, 0, 0, 0, + 0, 208, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, + 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 1, 0, 10, 0, 16, 0, 3, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 6, 0, + 0, 0, 9, 0, 0, 0, 230, 15, 16, 0, 8, 0, 0, 0, 138, 0, 0, 15, 242, + 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 3, 0, 0, + 0, 6, 0, 0, 0, 9, 0, 0, 0, 230, 15, 16, 0, 9, 0, 0, 0, 38, 0, + 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 9, 0, 0, 0, 214, 15, 16, 0, 6, + 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, + 8, 0, 0, 0, 134, 10, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, + 0, 70, 14, 16, 0, 9, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 8, 0, + 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 5, + 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, + 130, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 1, 0, 26, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, + 16, 0, 9, 0, 0, 0, 166, 15, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 13, + 0, 0, 0, 7, 0, 0, 0, 13, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 140, 0, + 0, 17, 50, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 10, 16, 0, 7, 0, 0, + 0, 134, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 194, 0, 16, 0, 7, 0, + 0, 0, 86, 13, 16, 0, 9, 0, 0, 0, 166, 14, 16, 0, 15, 0, 0, 0, 35, + 0, 0, 12, 50, 0, 16, 0, 4, 0, 0, 0, 134, 0, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 230, 10, 16, 0, 10, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 9, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, + 21, 0, 0, 0, 166, 10, 16, 0, 4, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, + 0, 242, 0, 16, 0, 9, 0, 0, 0, 86, 5, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, + 9, 0, 0, 0, 78, 0, 0, 8, 130, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 35, 0, + 0, 9, 82, 0, 16, 0, 7, 0, 0, 0, 6, 0, 16, 0, 6, 0, 0, 0, 166, + 11, 16, 0, 14, 0, 0, 0, 86, 6, 16, 0, 9, 0, 0, 0, 78, 0, 0, 11, + 82, 0, 16, 0, 7, 0, 0, 0, 0, 208, 0, 0, 6, 2, 16, 0, 7, 0, 0, + 0, 2, 64, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 7, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 138, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 9, 0, + 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 230, 15, 16, 0, 3, + 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 6, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, + 0, 78, 0, 0, 8, 130, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 35, 0, 0, 9, 130, + 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 1, 0, 42, 0, 16, 0, 7, 0, 0, 0, 55, 0, 0, 9, 82, 0, 16, + 0, 3, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 4, 0, + 0, 0, 166, 11, 16, 0, 10, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 9, + 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, + 26, 0, 16, 0, 3, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 9, 0, 0, + 0, 58, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 42, 0, + 16, 0, 8, 0, 0, 0, 35, 0, 0, 12, 162, 0, 16, 0, 3, 0, 0, 0, 86, + 13, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, + 0, 0, 0, 0, 255, 0, 0, 0, 166, 14, 16, 0, 9, 0, 0, 0, 138, 0, 0, + 15, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 15, + 0, 0, 0, 18, 0, 0, 0, 21, 0, 0, 0, 246, 15, 16, 0, 4, 0, 0, 0, + 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 130, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 12, + 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 78, 0, 0, 8, 130, 0, 16, 0, + 1, 0, 0, 0, 0, 208, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 7, 0, 0, 0, 35, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 166, 10, + 16, 0, 6, 0, 0, 0, 150, 7, 16, 0, 11, 0, 0, 0, 150, 7, 16, 0, 4, + 0, 0, 0, 78, 0, 0, 11, 114, 0, 16, 0, 4, 0, 0, 0, 0, 208, 0, 0, + 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 7, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 7, 0, + 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 7, 0, 0, 0, + 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 26, 0, 16, + 0, 4, 0, 0, 0, 55, 0, 0, 9, 162, 0, 16, 0, 3, 0, 0, 0, 166, 10, + 16, 0, 1, 0, 0, 0, 86, 13, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 7, + 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 3, 0, 0, 0, 86, 13, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 8, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 13, 0, 0, 0, 86, 13, + 16, 0, 3, 0, 0, 0, 6, 8, 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, + 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 13, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 79, 0, + 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, + 58, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, + 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 6, 5, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 2, + 0, 0, 0, 134, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, + 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 146, 36, 73, + 0, 146, 36, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 194, 0, + 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 50, 0, 16, 0, 7, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 230, + 10, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, + 70, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 73, 146, 36, 0, 73, 146, 36, 0, 73, 146, 36, 0, 73, 146, 36, 0, 30, + 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 182, 109, 219, 0, 182, 109, 219, 0, 182, 109, 219, 0, 182, 109, 219, + 0, 1, 0, 0, 7, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 4, 0, + 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 8, + 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 134, 0, 16, 0, 3, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 73, 146, 36, 0, 73, 146, 36, 0, 73, 146, 36, 0, 73, 146, + 36, 0, 60, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 214, 5, 16, 0, 3, + 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, + 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 73, 146, 36, + 0, 73, 146, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 10, 50, 0, + 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 73, + 146, 36, 0, 73, 146, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 5, + 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 1, 0, 0, + 7, 242, 0, 16, 0, 10, 0, 0, 0, 6, 5, 16, 0, 7, 0, 0, 0, 6, 10, + 16, 0, 9, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 86, + 15, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 60, 0, 0, 7, + 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, + 0, 3, 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 183, 109, 219, 255, 183, 109, 219, 255, 0, + 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, + 198, 0, 16, 0, 9, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, + 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, + 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 60, + 0, 0, 7, 50, 0, 16, 0, 7, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, + 134, 0, 16, 0, 3, 0, 0, 0, 59, 0, 0, 5, 50, 0, 16, 0, 4, 0, 0, + 0, 70, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 50, 0, 16, 0, 4, 0, + 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 60, + 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, + 70, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, + 0, 214, 5, 16, 0, 3, 0, 0, 0, 134, 0, 16, 0, 3, 0, 0, 0, 60, 0, + 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, + 0, 16, 0, 3, 0, 0, 0, 55, 0, 0, 9, 50, 0, 16, 0, 3, 0, 0, 0, + 70, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, + 0, 2, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 166, 15, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, + 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, + 230, 10, 16, 0, 2, 0, 0, 0, 134, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, + 10, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 146, 36, 73, 0, 146, 36, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, + 0, 0, 10, 50, 0, 16, 0, 7, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 85, 0, 0, 10, 50, 0, 16, 0, 8, 0, 0, 0, 70, 0, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, + 2, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, + 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 8, 0, + 0, 0, 1, 0, 0, 7, 50, 0, 16, 0, 7, 0, 0, 0, 70, 0, 16, 0, 2, + 0, 0, 0, 230, 10, 16, 0, 8, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, + 8, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 134, 0, 16, 0, 4, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 73, 146, 36, 0, 73, 146, 36, 0, 73, 146, 36, 0, 73, + 146, 36, 0, 60, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 214, 5, 16, 0, + 4, 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, + 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 73, 146, + 36, 0, 73, 146, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 10, 50, + 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 73, 146, 36, 0, 73, 146, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, + 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 1, 0, + 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 166, 15, 16, 0, 7, 0, 0, 0, 6, + 10, 16, 0, 8, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, + 86, 15, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 60, 0, 0, + 7, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, 4, + 16, 0, 4, 0, 0, 0, 30, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 183, 109, 219, 255, 183, 109, 219, 255, 60, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, + 0, 86, 13, 16, 0, 8, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 41, 0, + 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, + 60, 0, 0, 7, 194, 0, 16, 0, 7, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, + 0, 6, 8, 16, 0, 4, 0, 0, 0, 59, 0, 0, 5, 50, 0, 16, 0, 2, 0, + 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 50, 0, 16, 0, 2, + 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 230, 10, 16, 0, 7, 0, 0, 0, + 60, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, + 0, 70, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, + 0, 0, 214, 5, 16, 0, 4, 0, 0, 0, 134, 0, 16, 0, 4, 0, 0, 0, 60, + 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, + 6, 4, 16, 0, 4, 0, 0, 0, 55, 0, 0, 9, 194, 0, 16, 0, 3, 0, 0, + 0, 6, 8, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 166, 14, + 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 70, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, + 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 1, 0, + 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 146, 4, 0, 0, 146, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, + 0, 2, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 50, 0, + 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 4, + 0, 0, 0, 59, 0, 0, 5, 242, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, + 2, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 6, 4, 16, + 0, 3, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 30, 0, 0, 11, 242, 0, + 16, 0, 8, 0, 0, 0, 166, 14, 16, 128, 65, 0, 0, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, + 1, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, + 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, + 8, 0, 0, 0, 230, 10, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, + 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, + 0, 0, 50, 0, 16, 0, 8, 0, 0, 0, 214, 5, 16, 0, 5, 0, 0, 0, 70, + 0, 16, 0, 8, 0, 0, 0, 35, 0, 0, 9, 194, 0, 16, 0, 2, 0, 0, 0, + 6, 8, 16, 0, 5, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, + 0, 8, 0, 0, 0, 78, 0, 0, 11, 194, 0, 16, 0, 2, 0, 0, 0, 0, 208, + 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, + 0, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 138, 0, 0, 15, 242, + 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, + 0, 9, 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 38, 0, + 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 9, 0, 0, 0, 86, 13, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, + 8, 0, 0, 0, 6, 8, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, + 0, 70, 14, 16, 0, 9, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 8, 0, + 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 5, + 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 12, + 50, 0, 16, 0, 9, 0, 0, 0, 198, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 10, + 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 9, 0, 0, 0, 42, + 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 26, 0, 16, 0, + 8, 0, 0, 0, 1, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, + 0, 2, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, + 16, 0, 8, 0, 0, 0, 6, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 13, + 0, 0, 0, 7, 0, 0, 0, 13, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 140, 0, + 0, 17, 50, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, + 0, 134, 0, 16, 0, 8, 0, 0, 0, 138, 0, 0, 15, 50, 0, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 194, 0, 16, + 0, 10, 0, 0, 0, 86, 13, 16, 0, 8, 0, 0, 0, 6, 4, 16, 0, 2, 0, + 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 134, 0, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 134, 0, 16, 0, 9, 0, 0, 0, 59, 0, 0, 5, 242, 0, 16, + 0, 8, 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 1, 0, 0, 10, 194, 0, + 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 38, 0, + 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 4, 0, 0, 0, 214, 5, 16, 0, 5, + 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 194, 0, 16, 0, + 2, 0, 0, 0, 6, 8, 16, 0, 5, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, + 0, 6, 4, 16, 0, 4, 0, 0, 0, 78, 0, 0, 11, 194, 0, 16, 0, 2, 0, + 0, 0, 0, 208, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 138, 0, 0, 15, + 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, + 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 138, + 0, 0, 15, 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 6, 4, 16, 0, 3, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 13, 0, 0, 0, 86, + 13, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 35, 0, 0, 9, + 242, 0, 16, 0, 12, 0, 0, 0, 6, 8, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 12, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 78, 0, 0, 11, 242, 0, + 16, 0, 12, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 35, 0, 0, 12, 50, 0, 16, 0, 13, 0, 0, 0, 198, 0, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 13, + 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, + 26, 0, 16, 0, 12, 0, 0, 0, 138, 0, 0, 15, 194, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 9, + 0, 0, 0, 246, 15, 16, 0, 4, 0, 0, 0, 138, 0, 0, 15, 50, 0, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 7, 0, 0, 0, 38, 0, 0, 8, 0, + 208, 0, 0, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, + 246, 15, 16, 0, 5, 0, 0, 0, 35, 0, 0, 9, 194, 0, 16, 0, 2, 0, 0, + 0, 166, 10, 16, 0, 5, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, 4, + 16, 0, 4, 0, 0, 0, 78, 0, 0, 11, 194, 0, 16, 0, 2, 0, 0, 0, 0, + 208, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, + 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 1, 0, 42, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, 0, 2, + 0, 0, 0, 86, 13, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 13, 16, 0, 9, 0, 0, + 0, 138, 0, 0, 15, 50, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 6, + 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, + 8, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 86, + 15, 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 194, 0, 16, 0, + 4, 0, 0, 0, 246, 15, 16, 0, 5, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, + 0, 35, 0, 0, 9, 50, 0, 16, 0, 4, 0, 0, 0, 166, 10, 16, 0, 5, 0, + 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 78, + 0, 0, 11, 50, 0, 16, 0, 4, 0, 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 13, 0, 0, 0, 26, 0, + 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 4, + 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 6, 5, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 134, 13, 16, 0, 13, 0, 0, + 0, 41, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 230, 10, 16, 0, + 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, + 0, 4, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 50, + 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, + 4, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 146, 4, 0, 0, 146, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, + 4, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 7, 0, 0, + 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 4, + 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, + 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, + 0, 70, 0, 16, 0, 7, 0, 0, 0, 59, 0, 0, 5, 242, 0, 16, 0, 8, 0, + 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 9, + 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 8, 0, 0, 0, + 30, 0, 0, 11, 242, 0, 16, 0, 10, 0, 0, 0, 166, 14, 16, 128, 65, 0, 0, + 0, 9, 0, 0, 0, 2, 64, 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, 109, 11, + 0, 0, 109, 11, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 1, 0, 0, 10, + 194, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 1, 0, + 0, 10, 50, 0, 16, 0, 7, 0, 0, 0, 230, 10, 16, 0, 9, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 7, 0, 0, 0, 214, 15, 16, + 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 35, 0, 0, 9, 194, 0, + 16, 0, 4, 0, 0, 0, 6, 8, 16, 0, 6, 0, 0, 0, 166, 14, 16, 0, 4, + 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 78, 0, 0, 11, 194, 0, 16, 0, + 4, 0, 0, 0, 0, 208, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 138, 0, + 0, 15, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, + 0, 138, 0, 0, 15, 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 9, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 12, 0, 0, + 0, 86, 13, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 35, 0, + 0, 9, 242, 0, 16, 0, 10, 0, 0, 0, 6, 8, 16, 0, 6, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 78, 0, 0, 11, + 242, 0, 16, 0, 10, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, + 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 12, 0, 0, 0, 198, 0, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 12, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 1, 0, 26, 0, 16, 0, 10, 0, 0, 0, 1, 0, 0, 7, 50, 0, 16, 0, 4, + 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 6, 5, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 13, 0, 0, 0, 7, 0, 0, 0, 13, 0, 0, 0, 7, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 140, 0, 0, 17, 50, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, + 0, 16, 0, 4, 0, 0, 0, 134, 0, 16, 0, 10, 0, 0, 0, 138, 0, 0, 15, + 50, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 30, + 0, 0, 7, 194, 0, 16, 0, 13, 0, 0, 0, 86, 13, 16, 0, 10, 0, 0, 0, + 6, 4, 16, 0, 4, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 4, 0, 0, + 0, 134, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 0, 16, 0, 12, 0, 0, 0, 59, + 0, 0, 5, 242, 0, 16, 0, 10, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, + 1, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 7, 0, 0, 0, 214, + 5, 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, + 194, 0, 16, 0, 4, 0, 0, 0, 6, 8, 16, 0, 6, 0, 0, 0, 166, 14, 16, + 0, 4, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 78, 0, 0, 11, 194, 0, + 16, 0, 4, 0, 0, 0, 0, 208, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 138, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 166, 14, + 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 14, + 0, 0, 0, 86, 13, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, + 35, 0, 0, 9, 242, 0, 16, 0, 11, 0, 0, 0, 6, 8, 16, 0, 6, 0, 0, + 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 78, 0, + 0, 11, 242, 0, 16, 0, 11, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 14, 0, 0, 0, 198, 0, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 35, 0, 0, 9, 66, + 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 1, 0, 26, 0, 16, 0, 11, 0, 0, 0, 138, 0, 0, 15, 194, 0, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 9, 0, 0, 0, 246, 15, 16, 0, 8, 0, 0, 0, 138, 0, 0, 15, + 50, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 9, 0, 0, 0, 38, + 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 7, 0, 0, 0, 246, 15, 16, 0, + 6, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 35, 0, 0, 9, 194, 0, 16, + 0, 4, 0, 0, 0, 166, 10, 16, 0, 6, 0, 0, 0, 166, 14, 16, 0, 4, 0, + 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 78, 0, 0, 11, 194, 0, 16, 0, 4, + 0, 0, 0, 0, 208, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, + 9, 130, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 1, 0, 42, 0, 16, 0, 4, 0, 0, 0, 35, 0, 0, 12, 194, + 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 86, 13, 16, + 0, 12, 0, 0, 0, 138, 0, 0, 15, 50, 0, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 246, 15, 16, 0, 10, 0, 0, 0, 35, 0, 0, 9, 50, 0, 16, 0, 7, 0, 0, + 0, 166, 10, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 230, 10, + 16, 0, 7, 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, 0, 7, 0, 0, 0, 0, + 208, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, + 0, 14, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 1, 0, 10, 0, 16, 0, 7, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 4, + 0, 0, 0, 6, 10, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 134, 13, 16, 0, 14, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, + 0, 166, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 2, + 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, + 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 66, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, + 0, 0, 0, 79, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, + 0, 12, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 146, 4, 0, 0, 146, 4, 0, 0, 146, 4, 0, 0, 146, 4, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 8, 0, + 0, 0, 59, 0, 0, 5, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 4, + 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 30, 0, 0, 11, 242, 0, 16, + 0, 9, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 8, 0, 0, 0, 2, 64, + 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, 1, + 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, + 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, + 0, 162, 0, 16, 0, 1, 0, 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 6, 4, + 16, 0, 10, 0, 0, 0, 35, 0, 0, 9, 162, 0, 16, 0, 1, 0, 0, 0, 6, + 8, 16, 0, 5, 0, 0, 0, 6, 4, 16, 0, 9, 0, 0, 0, 86, 13, 16, 0, + 1, 0, 0, 0, 78, 0, 0, 11, 162, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, + 0, 86, 13, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, + 0, 3, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, + 9, 0, 0, 0, 3, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 242, 0, 16, 0, 12, 0, 0, 0, 86, 13, 16, 0, 5, 0, + 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 11, + 0, 0, 0, 6, 8, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 70, 14, 16, 0, 12, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 11, 0, 0, + 0, 0, 208, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 5, 0, + 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 12, 50, + 0, 16, 0, 12, 0, 0, 0, 198, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 5, 16, + 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 12, 0, 0, 0, 42, 0, + 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 26, 0, 16, 0, 11, + 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 11, 0, 0, 0, 6, 5, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 13, 0, + 0, 0, 7, 0, 0, 0, 13, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 140, 0, 0, + 17, 50, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, + 134, 0, 16, 0, 11, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 14, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 194, 0, 16, 0, + 13, 0, 0, 0, 86, 13, 16, 0, 11, 0, 0, 0, 6, 4, 16, 0, 14, 0, 0, + 0, 35, 0, 0, 12, 162, 0, 16, 0, 1, 0, 0, 0, 6, 8, 16, 0, 13, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, + 0, 0, 0, 6, 8, 16, 0, 12, 0, 0, 0, 59, 0, 0, 5, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 11, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, + 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 15, 0, 0, + 0, 18, 0, 0, 0, 21, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 38, 0, + 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 15, 0, 0, 0, 86, 5, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, + 0, 10, 0, 16, 0, 15, 0, 0, 0, 78, 0, 0, 8, 130, 0, 16, 0, 0, 0, + 0, 0, 0, 208, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, + 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 6, 4, + 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 6, + 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 150, 7, 16, 0, + 15, 0, 0, 0, 78, 0, 0, 11, 114, 0, 16, 0, 15, 0, 0, 0, 0, 208, 0, + 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 4, + 0, 0, 0, 10, 0, 16, 0, 15, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 4, 0, 0, + 0, 42, 0, 16, 0, 15, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 26, 0, + 16, 0, 15, 0, 0, 0, 55, 0, 0, 9, 146, 0, 16, 0, 0, 0, 0, 0, 6, + 0, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, + 4, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 86, + 10, 16, 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 17, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 6, 0, + 0, 0, 86, 10, 16, 0, 8, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 162, + 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 5, 0, 0, 0, 6, 4, 16, 0, + 17, 0, 0, 0, 35, 0, 0, 9, 162, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, + 0, 5, 0, 0, 0, 6, 4, 16, 0, 15, 0, 0, 0, 86, 13, 16, 0, 1, 0, + 0, 0, 78, 0, 0, 11, 162, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 86, + 13, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 12, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 35, 0, 0, 12, 162, 0, 16, 0, 1, 0, 0, 0, 86, + 13, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, + 0, 0, 0, 0, 255, 0, 0, 0, 86, 13, 16, 0, 12, 0, 0, 0, 138, 0, 0, + 15, 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 15, + 0, 0, 0, 18, 0, 0, 0, 21, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, + 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 12, 0, 0, 0, 246, 15, 16, + 0, 5, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 35, 0, 0, 9, 18, 0, + 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 11, + 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 78, 0, 0, 8, 18, 0, 16, 0, + 2, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 7, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, + 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 16, 0, 0, 0, 26, 0, 16, 0, 12, + 0, 0, 0, 78, 0, 0, 8, 18, 0, 16, 0, 3, 0, 0, 0, 0, 208, 0, 0, + 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 35, 0, 0, + 9, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 2, 0, 0, 0, 138, 0, 0, 15, 242, + 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 9, 0, 0, + 0, 3, 0, 0, 0, 6, 0, 0, 0, 86, 10, 16, 0, 2, 0, 0, 0, 35, 0, + 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 5, 0, 0, 0, 70, + 0, 16, 0, 13, 0, 0, 0, 230, 10, 16, 0, 12, 0, 0, 0, 78, 0, 0, 11, + 50, 0, 16, 0, 2, 0, 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 55, 0, 0, 9, 162, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, + 0, 86, 13, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 41, 0, + 0, 10, 162, 0, 16, 0, 1, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, + 60, 0, 0, 7, 50, 0, 16, 0, 5, 0, 0, 0, 198, 0, 16, 0, 0, 0, 0, + 0, 214, 5, 16, 0, 1, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, + 16, 0, 0, 0, 0, 0, 214, 5, 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, 10, + 0, 0, 0, 35, 0, 0, 9, 50, 0, 16, 0, 0, 0, 0, 0, 134, 0, 16, 0, + 6, 0, 0, 0, 230, 10, 16, 0, 9, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, + 0, 78, 0, 0, 11, 50, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 162, 0, 16, 0, + 1, 0, 0, 0, 86, 5, 16, 0, 6, 0, 0, 0, 166, 14, 16, 0, 17, 0, 0, + 0, 35, 0, 0, 9, 162, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 6, 0, + 0, 0, 166, 14, 16, 0, 15, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 78, + 0, 0, 11, 162, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 86, 13, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, + 0, 5, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 9, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 9, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 230, 15, + 16, 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, + 0, 230, 15, 16, 0, 8, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, + 16, 0, 8, 0, 0, 0, 214, 15, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, + 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 7, 0, 0, 0, 134, 10, 16, 0, + 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, + 0, 78, 0, 0, 11, 242, 0, 16, 0, 7, 0, 0, 0, 0, 208, 0, 0, 70, 14, + 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 9, 0, 0, 0, + 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 166, 15, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 13, 0, 0, 0, 7, 0, 0, 0, 13, + 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, + 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 140, 0, 0, 17, 50, 0, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 134, 0, 16, 0, 8, 0, 0, + 0, 30, 0, 0, 7, 194, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 8, 0, + 0, 0, 166, 14, 16, 0, 14, 0, 0, 0, 35, 0, 0, 12, 146, 0, 16, 0, 0, + 0, 0, 0, 6, 8, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 166, 14, 16, 0, 9, 0, 0, + 0, 138, 0, 0, 15, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 12, + 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 21, 0, 0, 0, 166, 10, 16, 0, + 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 8, 0, 0, + 0, 86, 5, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 42, + 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 78, 0, 0, 8, + 34, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 7, 0, 0, 0, 35, 0, 0, 9, 50, 0, 16, 0, 2, 0, + 0, 0, 6, 0, 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, 13, 0, 0, 0, 150, + 5, 16, 0, 8, 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, 0, 2, 0, 0, 0, + 0, 208, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, + 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, + 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 1, 0, 26, 0, 16, 0, 1, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 6, 0, + 0, 0, 9, 0, 0, 0, 230, 15, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, + 10, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 78, 0, 0, 8, 34, 0, 16, + 0, 1, 0, 0, 0, 0, 208, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 7, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 9, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 55, 0, 0, 9, 146, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, + 0, 1, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 9, 0, + 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 7, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 35, 0, 0, 9, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 1, 0, 42, 0, 16, 0, 7, 0, 0, 0, 35, 0, + 0, 12, 50, 0, 16, 0, 1, 0, 0, 0, 214, 5, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 230, 10, 16, 0, 2, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 21, + 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 246, 15, 16, + 0, 6, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 78, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 35, 0, 0, + 9, 114, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 6, 0, 0, 0, 150, 7, + 16, 0, 10, 0, 0, 0, 150, 7, 16, 0, 2, 0, 0, 0, 78, 0, 0, 11, 114, + 0, 16, 0, 2, 0, 0, 0, 0, 208, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + 0, 35, 0, 0, 9, 66, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 26, 0, 16, 0, 0, 0, 0, 0, 35, + 0, 0, 9, 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 1, 0, 26, 0, 16, 0, 2, 0, 0, 0, 55, 0, 0, + 9, 50, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 70, 0, + 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 50, + 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, + 7, 194, 0, 16, 0, 5, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 6, 4, + 16, 0, 1, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 62, 0, 0, 1, 83, 84, 65, + 84, 148, 0, 0, 0, 185, 2, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 27, 1, 0, 0, 7, 1, 0, 0, 6, 0, 0, 0, 10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt1_rgba8_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt1_rgba8_cs.h new file mode 100644 index 0000000..1b9cc8d --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt1_rgba8_cs.h @@ -0,0 +1,2841 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 17 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(2) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r1.yz, r1.xxyx, l(0, 2, 2, 0) +ishl r0.w, r1.y, l(2) +imad r1.y, vThreadID.z, CB0[0][2].y, r1.z +imad r0.w, r1.y, CB0[0][2].x, r0.w +iadd r0.w, r0.w, CB0[0][1].w +ushr r1.y, CB0[0][2].x, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r2.xw, l(27, 0, 0, 29), l(3, 0, 0, 1), vThreadID.xxxx + imad r0.y, r0.y, r1.w, r2.x + ishl r1.z, vThreadID.y, l(11) + and r1.z, r1.z, l(0x00003000) + bfi r1.z, l(3), l(9), r1.x, r1.z + ishr r1.z, r1.z, l(6) + iadd r1.w, r2.y, r2.z + bfi r2.x, l(1), l(1), r1.w, l(0) + iadd r2.x, r2.x, r2.w + bfi r2.x, l(2), l(1), r2.x, l(0) + bfi r1.w, l(1), l(0), r1.w, r2.x + bfi r2.xy, l(19, 19, 0, 0), l(11, 14, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(9, 12, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(6) + bfi r1.w, l(1), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(6, 6, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r2.z, CB0[0][0].z, l(5) + imad r1.z, r2.x, r2.z, r1.z + ishl r2.xz, vThreadID.yyyy, l(6, 0, 7, 0) + and r2.xz, r2.xxzx, l(896, 0, 2048, 0) + bfi r2.w, l(3), l(4), r1.x, r2.x + bfi r2.w, l(22), l(10), r1.z, r2.w + bfi r3.x, l(1), l(4), vThreadID.y, l(0) + iadd r2.w, r2.w, r3.x + ishl r3.yz, r2.xxxx, l(0, 3, 2, 0) + bfi r3.yz, l(0, 3, 3, 0), l(0, 7, 6, 0), r1.xxxx, r3.yyzy + bfi r3.yz, l(0, 22, 22, 0), l(0, 13, 12, 0), r1.zzzz, r3.yyzy + imad r3.xy, r3.xxxx, l(8, 4, 0, 0), r3.yzyy + bfi r1.z, l(12), l(0), r2.z, r3.x + and r2.x, r3.y, l(1792) + iadd r1.z, r1.z, r2.x + and r2.x, r2.y, l(2) + iadd r1.w, r1.w, r2.x + bfi r1.w, l(2), l(6), r1.w, l(0) + iadd r1.z, r1.z, r1.w + bfi r0.y, l(6), l(0), r2.w, r1.z + endif +else + ishl r1.x, r1.x, l(3) + imad r1.z, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.z, CB0[0][0].z, r1.x +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.yw, r0.yyyw, l(0, 4, 0, 4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r1.xzw, r0.zzzz, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r1.z + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw + mov r3.xy, r2.ywyy +else + mov r3.xy, r2.ywyy +endif +movc r0.x, r0.x, l(2), l(1) +iadd r0.x, r0.x, r0.y +ld r4.xyzw, r0.xxxx, T0[0].xyzw +if_nz r1.x + ishl r5.xyzw, r4.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r6.xyzw, r4.xyzw, l(8, 8, 8, 8) + and r6.xyzw, r6.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r4.xyzw, r5.xyzw, r6.xyzw +endif +if_nz r1.z + ushr r5.xyzw, r4.xyzw, l(16, 16, 16, 16) + bfi r4.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r4.xyzw, r5.xyzw + mov r3.zw, r4.yyyw +else + mov r3.zw, r4.yyyw +endif +ishl r5.xyz, r2.xxxx, l(3, 7, 12, 0) +ushr r6.xyz, r2.xxxx, l(13, 4, 9, 0) +mov r5.w, r6.x +and r0.xy, r5.xwxx, l(248, 248, 0, 0) +mov r6.xw, r5.zzzy +and r1.xz, r6.wwzw, l(0x0003f000, 0, 0x0003f000, 0) +iadd r0.xy, r0.xyxx, r1.xzxx +and r1.xz, r6.xxyx, l(0x0f800000, 0, 0x0f800000, 0) +iadd r0.xy, r0.xyxx, r1.xzxx +ushr r1.xz, r0.xxyx, l(5, 0, 5, 0) +and r1.xz, r1.xxzx, l(0x00700007, 0, 0x00700007, 0) +iadd r0.xy, r0.xyxx, r1.xzxx +ushr r1.xz, r0.xxyx, l(6, 0, 6, 0) +and r1.xz, r1.xxzx, l(3072, 0, 3072, 0) +iadd r0.xy, r0.xyxx, r1.xzxx +ishl r5.xyz, r2.zzzz, l(3, 7, 12, 0) +ushr r2.xyz, r2.zzzz, l(13, 4, 9, 0) +mov r5.w, r2.x +and r1.xz, r5.xxwx, l(248, 0, 248, 0) +mov r2.xw, r5.zzzy +and r2.zw, r2.wwwz, l(0, 0, 0x0003f000, 0x0003f000) +iadd r1.xz, r1.xxzx, r2.zzwz +and r2.xy, r2.xyxx, l(0x0f800000, 0x0f800000, 0, 0) +iadd r1.xz, r1.xxzx, r2.xxyx +ushr r2.xy, r1.xzxx, l(5, 5, 0, 0) +and r2.xy, r2.xyxx, l(0x00700007, 0x00700007, 0, 0) +iadd r1.xz, r1.xxzx, r2.xxyx +ushr r2.xy, r1.xzxx, l(6, 6, 0, 0) +and r2.xy, r2.xyxx, l(3072, 3072, 0, 0) +iadd r2.xy, r1.zxzz, r2.yxyy +ishl r5.xyz, r4.xxxx, l(3, 7, 12, 0) +ushr r6.xyz, r4.xxxx, l(13, 4, 9, 0) +mov r5.w, r6.x +and r1.xz, r5.xxwx, l(248, 0, 248, 0) +mov r6.xw, r5.zzzy +and r4.xy, r6.wzww, l(0x0003f000, 0x0003f000, 0, 0) +iadd r1.xz, r1.xxzx, r4.xxyx +and r4.xy, r6.xyxx, l(0x0f800000, 0x0f800000, 0, 0) +iadd r1.xz, r1.xxzx, r4.xxyx +ushr r4.xy, r1.xzxx, l(5, 5, 0, 0) +and r4.xy, r4.xyxx, l(0x00700007, 0x00700007, 0, 0) +iadd r1.xz, r1.xxzx, r4.xxyx +ushr r4.xy, r1.xzxx, l(6, 6, 0, 0) +and r4.xy, r4.xyxx, l(3072, 3072, 0, 0) +iadd r1.xz, r1.xxzx, r4.xxyx +ishl r5.xyz, r4.zzzz, l(3, 7, 12, 0) +ushr r4.xyz, r4.zzzz, l(13, 4, 9, 0) +mov r5.w, r4.x +and r5.xw, r5.xxxw, l(248, 0, 0, 248) +mov r4.xw, r5.zzzy +and r4.zw, r4.wwwz, l(0, 0, 0x0003f000, 0x0003f000) +iadd r4.zw, r4.zzzw, r5.xxxw +and r4.xy, r4.xyxx, l(0x0f800000, 0x0f800000, 0, 0) +iadd r4.xy, r4.xyxx, r4.zwzz +ushr r4.zw, r4.xxxy, l(0, 0, 5, 5) +and r4.zw, r4.zzzw, l(0, 0, 0x00700007, 0x00700007) +iadd r4.xy, r4.zwzz, r4.xyxx +ushr r4.zw, r4.xxxy, l(0, 0, 6, 6) +and r4.zw, r4.zzzw, l(0, 0, 3072, 3072) +iadd r4.xy, r4.zwzz, r4.xyxx +mov r5.x, r0.y +mov r5.y, r2.x +mov r5.z, r1.z +mov r5.w, r4.y +mov r2.x, r0.x +mov r2.z, r1.x +mov r2.w, r4.x +uge r6.xyzw, r5.xyzw, r2.xyzw +not r7.xyzw, r3.xyzw +ishl r8.xyzw, r7.xyzw, l(1, 1, 1, 1) +and r8.xyzw, r8.xyzw, l(0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa) +xor r7.xyzw, r7.xyzw, r8.xyzw +ishl r8.xyzw, r3.xyzw, l(1, 1, 1, 1) +and r8.xyzw, r8.xyzw, l(0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa) +ushr r3.xyzw, r3.xyzw, l(1, 1, 1, 1) +and r3.xyzw, r3.xyzw, l(0x55555555, 0x55555555, 0x55555555, 0x55555555) +iadd r3.xyzw, r3.xyzw, r8.xyzw +ushr r8.xyzw, r3.xyzw, l(1, 1, 1, 1) +and r8.xyzw, r8.xyzw, l(0x55555555, 0x55555555, 0x55555555, 0x55555555) +xor r3.xyzw, r3.xyzw, r8.xyzw +movc r3.xyzw, r6.xyzw, r7.xyzw, r3.xyzw +ushr r7.xyzw, r3.xxxx, l(2, 4, 6, 1) +mov r8.x, r3.x +mov r8.yzw, r7.xxyz +and r9.xyzw, r8.xyzw, l(1, 1, 1, 1) +ubfe r10.xyzw, l(1, 1, 1, 1), l(1, 3, 5, 7), r8.xxxx +imul null, r10.xyzw, r0.yyyy, r10.xyzw +imad r9.xyzw, r9.xyzw, r2.xxxx, r10.xyzw +and r10.x, r7.w, r8.x +and r11.x, r10.x, l(0x55555555) +ushr r10.yzw, r11.xxxx, l(0, 2, 4, 6) +and r12.xyzw, r10.xyzw, l(1, 1, 1, 1) +or r7.x, r7.w, r8.x +ubfe r12.xyzw, l(9, 9, 9, 9), r12.xyzw, r9.xyzw +ishl r12.xyzw, r12.xyzw, l(16, 16, 16, 16) +mov r11.yzw, r10.yyzw +bfi r10.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r11.xyzw, l(10, 10, 10, 10) +ubfe r10.xyzw, l(9, 9, 9, 9), r10.xyzw, r9.xyzw +ishl r10.xyzw, r10.xyzw, l(8, 8, 8, 8) +iadd r10.xyzw, r10.xyzw, r12.xyzw +bfi r11.xyzw, l(2, 2, 2, 2), l(0, 0, 0, 0), r11.xyzw, l(20, 20, 20, 20) +ushr r9.xyzw, r9.xyzw, r11.xyzw +iadd r9.xyzw, r9.xyzw, r10.xyzw +ushr r7.yzw, r7.xxxx, l(0, 2, 4, 6) +and r7.xyzw, r7.xyzw, l(1, 1, 1, 1) +imad r7.xyzw, r7.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000), r9.xyzw +not r9.xyzw, r3.wxyz +ushr r10.yzw, r9.yyyy, l(0, 2, 4, 6) +mov r10.x, r9.y +and r10.xyzw, r10.xyzw, l(3, 3, 3, 3) +and r11.xyzw, r8.xyzw, l(3, 3, 3, 3) +imul null, r11.xyzw, r0.yyyy, r11.xyzw +imad r10.xyzw, r10.xyzw, r2.xxxx, r11.xyzw +and r11.xyzw, r10.xyzw, l(1023, 1023, 1023, 1023) +udiv r11.xyzw, null, r11.xyzw, l(3, 3, 3, 3) +ishl r11.xyzw, r11.xyzw, l(16, 16, 16, 16) +ubfe r12.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r10.xyzw +udiv r12.xyzw, null, r12.xyzw, l(3, 3, 3, 3) +bfi r11.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r12.xyzw, r11.xyzw +ushr r10.xyzw, r10.xyzw, l(20, 20, 20, 20) +udiv r10.xyzw, null, r10.xyzw, l(3, 3, 3, 3) +or r10.xyzw, r10.xyzw, r11.xyzw +or r10.xyzw, r10.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) +movc r7.xyzw, r6.xxxx, r7.xyzw, r10.xyzw +store_uav_typed U0[0].xyzw, r0.wwww, r7.xyzw +iadd r5.xzw, r0.wwww, l(1, 0, 2, 3) +ushr r7.xyzw, r3.yyyy, l(2, 4, 6, 1) +mov r10.x, r3.y +mov r10.yzw, r7.xxyz +and r11.xyzw, r10.xyzw, l(1, 1, 1, 1) +ubfe r12.xyzw, l(1, 1, 1, 1), l(1, 3, 5, 7), r3.yyyy +imul null, r12.xyzw, r5.yyyy, r12.xyzw +imad r11.xyzw, r11.xyzw, r2.yyyy, r12.xyzw +and r12.x, r3.y, r7.w +and r13.x, r12.x, l(0x55555555) +ushr r12.yzw, r13.xxxx, l(0, 2, 4, 6) +and r14.xyzw, r12.xyzw, l(1, 1, 1, 1) +or r7.x, r3.y, r7.w +ubfe r14.xyzw, l(9, 9, 9, 9), r14.xyzw, r11.xyzw +ishl r14.xyzw, r14.xyzw, l(16, 16, 16, 16) +mov r13.yzw, r12.yyzw +bfi r12.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r13.xyzw, l(10, 10, 10, 10) +ubfe r12.xyzw, l(9, 9, 9, 9), r12.xyzw, r11.xyzw +ishl r12.xyzw, r12.xyzw, l(8, 8, 8, 8) +iadd r12.xyzw, r12.xyzw, r14.xyzw +bfi r13.xyzw, l(2, 2, 2, 2), l(0, 0, 0, 0), r13.xyzw, l(20, 20, 20, 20) +ushr r11.xyzw, r11.xyzw, r13.xyzw +iadd r11.xyzw, r11.xyzw, r12.xyzw +ushr r7.yzw, r7.xxxx, l(0, 2, 4, 6) +and r7.xyzw, r7.xyzw, l(1, 1, 1, 1) +imad r7.xyzw, r7.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000), r11.xyzw +ushr r11.yzw, r9.zzzz, l(0, 2, 4, 6) +mov r11.x, r9.z +and r11.xyzw, r11.xyzw, l(3, 3, 3, 3) +and r10.xyzw, r10.xyzw, l(3, 3, 3, 3) +imul null, r10.xyzw, r5.yyyy, r10.xyzw +imad r10.xyzw, r11.xyzw, r2.yyyy, r10.xyzw +and r11.xyzw, r10.xyzw, l(1023, 1023, 1023, 1023) +udiv r11.xyzw, null, r11.xyzw, l(3, 3, 3, 3) +ishl r11.xyzw, r11.xyzw, l(16, 16, 16, 16) +ubfe r12.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r10.xyzw +udiv r12.xyzw, null, r12.xyzw, l(3, 3, 3, 3) +bfi r11.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r12.xyzw, r11.xyzw +ushr r10.xyzw, r10.xyzw, l(20, 20, 20, 20) +udiv r10.xyzw, null, r10.xyzw, l(3, 3, 3, 3) +or r10.xyzw, r10.xyzw, r11.xyzw +or r10.xyzw, r10.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) +movc r7.xyzw, r6.yyyy, r7.xyzw, r10.xyzw +store_uav_typed U0[0].xyzw, r5.xxxx, r7.xyzw +ushr r7.xyzw, r3.zzzz, l(2, 4, 6, 1) +mov r10.x, r3.z +mov r10.yzw, r7.xxyz +and r11.xyzw, r10.xyzw, l(1, 1, 1, 1) +ubfe r12.xyzw, l(1, 1, 1, 1), l(1, 3, 5, 7), r3.zzzz +imul null, r12.xyzw, r1.zzzz, r12.xyzw +imad r11.xyzw, r11.xyzw, r1.xxxx, r12.xyzw +and r12.x, r3.z, r7.w +and r13.x, r12.x, l(0x55555555) +ushr r12.yzw, r13.xxxx, l(0, 2, 4, 6) +and r14.xyzw, r12.xyzw, l(1, 1, 1, 1) +or r7.x, r3.z, r7.w +ubfe r14.xyzw, l(9, 9, 9, 9), r14.xyzw, r11.xyzw +ishl r14.xyzw, r14.xyzw, l(16, 16, 16, 16) +mov r13.yzw, r12.yyzw +bfi r12.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r13.xyzw, l(10, 10, 10, 10) +ubfe r12.xyzw, l(9, 9, 9, 9), r12.xyzw, r11.xyzw +ishl r12.xyzw, r12.xyzw, l(8, 8, 8, 8) +iadd r12.xyzw, r12.xyzw, r14.xyzw +bfi r13.xyzw, l(2, 2, 2, 2), l(0, 0, 0, 0), r13.xyzw, l(20, 20, 20, 20) +ushr r11.xyzw, r11.xyzw, r13.xyzw +iadd r11.xyzw, r11.xyzw, r12.xyzw +ushr r7.yzw, r7.xxxx, l(0, 2, 4, 6) +and r7.xyzw, r7.xyzw, l(1, 1, 1, 1) +imad r7.xyzw, r7.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000), r11.xyzw +ushr r11.yzw, r9.wwww, l(0, 2, 4, 6) +mov r11.x, r9.w +and r11.xyzw, r11.xyzw, l(3, 3, 3, 3) +and r10.xyzw, r10.xyzw, l(3, 3, 3, 3) +imul null, r10.xyzw, r1.zzzz, r10.xyzw +imad r10.xyzw, r11.xyzw, r1.xxxx, r10.xyzw +and r11.xyzw, r10.xyzw, l(1023, 1023, 1023, 1023) +udiv r11.xyzw, null, r11.xyzw, l(3, 3, 3, 3) +ishl r11.xyzw, r11.xyzw, l(16, 16, 16, 16) +ubfe r12.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r10.xyzw +udiv r12.xyzw, null, r12.xyzw, l(3, 3, 3, 3) +bfi r11.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r12.xyzw, r11.xyzw +ushr r10.xyzw, r10.xyzw, l(20, 20, 20, 20) +udiv r10.xyzw, null, r10.xyzw, l(3, 3, 3, 3) +or r10.xyzw, r10.xyzw, r11.xyzw +or r10.xyzw, r10.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) +movc r7.xyzw, r6.zzzz, r7.xyzw, r10.xyzw +store_uav_typed U0[0].xyzw, r5.zzzz, r7.xyzw +ushr r7.xyzw, r3.wwww, l(2, 4, 6, 1) +mov r10.x, r3.w +mov r10.yzw, r7.xxyz +and r11.xyzw, r10.xyzw, l(1, 1, 1, 1) +ubfe r12.xyzw, l(1, 1, 1, 1), l(1, 3, 5, 7), r3.wwww +imul null, r12.xyzw, r4.yyyy, r12.xyzw +imad r11.xyzw, r11.xyzw, r4.xxxx, r12.xyzw +and r12.x, r3.w, r7.w +and r13.x, r12.x, l(0x55555555) +ushr r12.yzw, r13.xxxx, l(0, 2, 4, 6) +and r14.xyzw, r12.xyzw, l(1, 1, 1, 1) +or r7.x, r3.w, r7.w +ubfe r14.xyzw, l(9, 9, 9, 9), r14.xyzw, r11.xyzw +ishl r14.xyzw, r14.xyzw, l(16, 16, 16, 16) +mov r13.yzw, r12.yyzw +bfi r12.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r13.xyzw, l(10, 10, 10, 10) +ubfe r12.xyzw, l(9, 9, 9, 9), r12.xyzw, r11.xyzw +ishl r12.xyzw, r12.xyzw, l(8, 8, 8, 8) +iadd r12.xyzw, r12.xyzw, r14.xyzw +bfi r13.xyzw, l(2, 2, 2, 2), l(0, 0, 0, 0), r13.xyzw, l(20, 20, 20, 20) +ushr r11.xyzw, r11.xyzw, r13.xyzw +iadd r11.xyzw, r11.xyzw, r12.xyzw +ushr r7.yzw, r7.xxxx, l(0, 2, 4, 6) +and r7.xyzw, r7.xyzw, l(1, 1, 1, 1) +imad r7.xyzw, r7.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000), r11.xyzw +ushr r9.yzw, r9.xxxx, l(0, 2, 4, 6) +and r9.xyzw, r9.xyzw, l(3, 3, 3, 3) +and r10.xyzw, r10.xyzw, l(3, 3, 3, 3) +imul null, r10.xyzw, r4.yyyy, r10.xyzw +imad r9.xyzw, r9.xyzw, r4.xxxx, r10.xyzw +and r10.xyzw, r9.xyzw, l(1023, 1023, 1023, 1023) +udiv r10.xyzw, null, r10.xyzw, l(3, 3, 3, 3) +ishl r10.xyzw, r10.xyzw, l(16, 16, 16, 16) +ubfe r11.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r9.xyzw +udiv r11.xyzw, null, r11.xyzw, l(3, 3, 3, 3) +bfi r10.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r11.xyzw, r10.xyzw +ushr r9.xyzw, r9.xyzw, l(20, 20, 20, 20) +udiv r9.xyzw, null, r9.xyzw, l(3, 3, 3, 3) +or r9.xyzw, r9.xyzw, r10.xyzw +or r9.xyzw, r9.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) +movc r7.xyzw, r6.wwww, r7.xyzw, r9.xyzw +store_uav_typed U0[0].xyzw, r5.wwww, r7.xyzw +imad r0.x, vThreadID.y, l(4), l(1) +ult r0.x, r0.x, CB0[0][2].y +if_nz r0.x + iadd r0.w, r1.y, r0.w + ushr r7.xyzw, r3.xyzw, l(8, 8, 8, 8) + ushr r9.xyzw, r7.xxxx, l(2, 4, 6, 1) + mov r10.x, r7.x + mov r10.yzw, r9.xxyz + and r11.xyzw, r10.xyzw, l(1, 1, 1, 1) + ubfe r12.xyzw, l(1, 1, 1, 1), l(9, 11, 13, 15), r8.xxxx + imul null, r12.xyzw, r0.yyyy, r12.xyzw + imad r11.xyzw, r11.xyzw, r2.xxxx, r12.xyzw + and r12.x, r9.w, r10.x + and r13.x, r12.x, l(0x00555555) + ushr r12.yzw, r13.xxxx, l(0, 2, 4, 6) + and r14.xyzw, r12.xyzw, l(1, 1, 1, 1) + or r9.x, r9.w, r10.x + ubfe r14.xyzw, l(9, 9, 9, 9), r14.xyzw, r11.xyzw + ishl r14.xyzw, r14.xyzw, l(16, 16, 16, 16) + mov r13.yzw, r12.yyzw + bfi r12.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r13.xyzw, l(10, 10, 10, 10) + ubfe r12.xyzw, l(9, 9, 9, 9), r12.xyzw, r11.xyzw + ishl r12.xyzw, r12.xyzw, l(8, 8, 8, 8) + iadd r12.xyzw, r12.xyzw, r14.xyzw + bfi r13.xyzw, l(2, 2, 2, 2), l(0, 0, 0, 0), r13.xyzw, l(20, 20, 20, 20) + ushr r11.xyzw, r11.xyzw, r13.xyzw + iadd r11.xyzw, r11.xyzw, r12.xyzw + ushr r9.yzw, r9.xxxx, l(0, 2, 4, 6) + and r9.xyzw, r9.xyzw, l(1, 1, 1, 1) + imad r9.xyzw, r9.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000), r11.xyzw + not r11.xyzw, r7.wxyz + ushr r12.yzw, r11.yyyy, l(0, 2, 4, 6) + mov r12.x, r11.y + and r12.xyzw, r12.xyzw, l(3, 3, 3, 3) + and r13.xyzw, r10.xyzw, l(3, 3, 3, 3) + imul null, r13.xyzw, r0.yyyy, r13.xyzw + imad r12.xyzw, r12.xyzw, r2.xxxx, r13.xyzw + and r13.xyzw, r12.xyzw, l(1023, 1023, 1023, 1023) + udiv r13.xyzw, null, r13.xyzw, l(3, 3, 3, 3) + ishl r13.xyzw, r13.xyzw, l(16, 16, 16, 16) + ubfe r14.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r12.xyzw + udiv r14.xyzw, null, r14.xyzw, l(3, 3, 3, 3) + bfi r13.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r14.xyzw, r13.xyzw + ushr r12.xyzw, r12.xyzw, l(20, 20, 20, 20) + udiv r12.xyzw, null, r12.xyzw, l(3, 3, 3, 3) + or r12.xyzw, r12.xyzw, r13.xyzw + or r12.xyzw, r12.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) + movc r9.xyzw, r6.xxxx, r9.xyzw, r12.xyzw + store_uav_typed U0[0].xyzw, r0.wwww, r9.xyzw + iadd r5.xzw, r0.wwww, l(1, 0, 2, 3) + ushr r9.xyzw, r7.yyyy, l(2, 4, 6, 1) + mov r12.x, r7.y + mov r12.yzw, r9.xxyz + and r13.xyzw, r12.xyzw, l(1, 1, 1, 1) + ubfe r14.xyzw, l(1, 1, 1, 1), l(9, 11, 13, 15), r3.yyyy + imul null, r14.xyzw, r5.yyyy, r14.xyzw + imad r13.xyzw, r13.xyzw, r2.yyyy, r14.xyzw + and r14.x, r7.y, r9.w + and r15.x, r14.x, l(0x00555555) + ushr r14.yzw, r15.xxxx, l(0, 2, 4, 6) + and r16.xyzw, r14.xyzw, l(1, 1, 1, 1) + or r9.x, r7.y, r9.w + ubfe r16.xyzw, l(9, 9, 9, 9), r16.xyzw, r13.xyzw + ishl r16.xyzw, r16.xyzw, l(16, 16, 16, 16) + mov r15.yzw, r14.yyzw + bfi r14.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r15.xyzw, l(10, 10, 10, 10) + ubfe r14.xyzw, l(9, 9, 9, 9), r14.xyzw, r13.xyzw + ishl r14.xyzw, r14.xyzw, l(8, 8, 8, 8) + iadd r14.xyzw, r14.xyzw, r16.xyzw + bfi r15.xyzw, l(2, 2, 2, 2), l(0, 0, 0, 0), r15.xyzw, l(20, 20, 20, 20) + ushr r13.xyzw, r13.xyzw, r15.xyzw + iadd r13.xyzw, r13.xyzw, r14.xyzw + ushr r9.yzw, r9.xxxx, l(0, 2, 4, 6) + and r9.xyzw, r9.xyzw, l(1, 1, 1, 1) + imad r9.xyzw, r9.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000), r13.xyzw + ushr r13.yzw, r11.zzzz, l(0, 2, 4, 6) + mov r13.x, r11.z + and r13.xyzw, r13.xyzw, l(3, 3, 3, 3) + and r12.xyzw, r12.xyzw, l(3, 3, 3, 3) + imul null, r12.xyzw, r5.yyyy, r12.xyzw + imad r12.xyzw, r13.xyzw, r2.yyyy, r12.xyzw + and r13.xyzw, r12.xyzw, l(1023, 1023, 1023, 1023) + udiv r13.xyzw, null, r13.xyzw, l(3, 3, 3, 3) + ishl r13.xyzw, r13.xyzw, l(16, 16, 16, 16) + ubfe r14.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r12.xyzw + udiv r14.xyzw, null, r14.xyzw, l(3, 3, 3, 3) + bfi r13.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r14.xyzw, r13.xyzw + ushr r12.xyzw, r12.xyzw, l(20, 20, 20, 20) + udiv r12.xyzw, null, r12.xyzw, l(3, 3, 3, 3) + or r12.xyzw, r12.xyzw, r13.xyzw + or r12.xyzw, r12.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) + movc r9.xyzw, r6.yyyy, r9.xyzw, r12.xyzw + store_uav_typed U0[0].xyzw, r5.xxxx, r9.xyzw + ushr r9.xyzw, r7.zzzz, l(2, 4, 6, 1) + mov r12.x, r7.z + mov r12.yzw, r9.xxyz + and r13.xyzw, r12.xyzw, l(1, 1, 1, 1) + ubfe r14.xyzw, l(1, 1, 1, 1), l(9, 11, 13, 15), r3.zzzz + imul null, r14.xyzw, r1.zzzz, r14.xyzw + imad r13.xyzw, r13.xyzw, r1.xxxx, r14.xyzw + and r14.x, r7.z, r9.w + and r15.x, r14.x, l(0x00555555) + ushr r14.yzw, r15.xxxx, l(0, 2, 4, 6) + and r16.xyzw, r14.xyzw, l(1, 1, 1, 1) + or r9.x, r7.z, r9.w + ubfe r16.xyzw, l(9, 9, 9, 9), r16.xyzw, r13.xyzw + ishl r16.xyzw, r16.xyzw, l(16, 16, 16, 16) + mov r15.yzw, r14.yyzw + bfi r14.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r15.xyzw, l(10, 10, 10, 10) + ubfe r14.xyzw, l(9, 9, 9, 9), r14.xyzw, r13.xyzw + ishl r14.xyzw, r14.xyzw, l(8, 8, 8, 8) + iadd r14.xyzw, r14.xyzw, r16.xyzw + bfi r15.xyzw, l(2, 2, 2, 2), l(0, 0, 0, 0), r15.xyzw, l(20, 20, 20, 20) + ushr r13.xyzw, r13.xyzw, r15.xyzw + iadd r13.xyzw, r13.xyzw, r14.xyzw + ushr r9.yzw, r9.xxxx, l(0, 2, 4, 6) + and r9.xyzw, r9.xyzw, l(1, 1, 1, 1) + imad r9.xyzw, r9.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000), r13.xyzw + ushr r13.yzw, r11.wwww, l(0, 2, 4, 6) + mov r13.x, r11.w + and r13.xyzw, r13.xyzw, l(3, 3, 3, 3) + and r12.xyzw, r12.xyzw, l(3, 3, 3, 3) + imul null, r12.xyzw, r1.zzzz, r12.xyzw + imad r12.xyzw, r13.xyzw, r1.xxxx, r12.xyzw + and r13.xyzw, r12.xyzw, l(1023, 1023, 1023, 1023) + udiv r13.xyzw, null, r13.xyzw, l(3, 3, 3, 3) + ishl r13.xyzw, r13.xyzw, l(16, 16, 16, 16) + ubfe r14.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r12.xyzw + udiv r14.xyzw, null, r14.xyzw, l(3, 3, 3, 3) + bfi r13.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r14.xyzw, r13.xyzw + ushr r12.xyzw, r12.xyzw, l(20, 20, 20, 20) + udiv r12.xyzw, null, r12.xyzw, l(3, 3, 3, 3) + or r12.xyzw, r12.xyzw, r13.xyzw + or r12.xyzw, r12.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) + movc r9.xyzw, r6.zzzz, r9.xyzw, r12.xyzw + store_uav_typed U0[0].xyzw, r5.zzzz, r9.xyzw + ushr r9.xyzw, r7.wwww, l(2, 4, 6, 1) + mov r12.x, r7.w + mov r12.yzw, r9.xxyz + and r13.xyzw, r12.xyzw, l(1, 1, 1, 1) + ubfe r14.xyzw, l(1, 1, 1, 1), l(9, 11, 13, 15), r3.wwww + imul null, r14.xyzw, r4.yyyy, r14.xyzw + imad r13.xyzw, r13.xyzw, r4.xxxx, r14.xyzw + and r14.x, r7.w, r9.w + and r15.x, r14.x, l(0x00555555) + ushr r14.yzw, r15.xxxx, l(0, 2, 4, 6) + and r16.xyzw, r14.xyzw, l(1, 1, 1, 1) + or r9.x, r7.w, r9.w + ubfe r16.xyzw, l(9, 9, 9, 9), r16.xyzw, r13.xyzw + ishl r16.xyzw, r16.xyzw, l(16, 16, 16, 16) + mov r15.yzw, r14.yyzw + bfi r14.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r15.xyzw, l(10, 10, 10, 10) + ubfe r14.xyzw, l(9, 9, 9, 9), r14.xyzw, r13.xyzw + ishl r14.xyzw, r14.xyzw, l(8, 8, 8, 8) + iadd r14.xyzw, r14.xyzw, r16.xyzw + bfi r15.xyzw, l(2, 2, 2, 2), l(0, 0, 0, 0), r15.xyzw, l(20, 20, 20, 20) + ushr r13.xyzw, r13.xyzw, r15.xyzw + iadd r13.xyzw, r13.xyzw, r14.xyzw + ushr r9.yzw, r9.xxxx, l(0, 2, 4, 6) + and r9.xyzw, r9.xyzw, l(1, 1, 1, 1) + imad r9.xyzw, r9.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000), r13.xyzw + ushr r11.yzw, r11.xxxx, l(0, 2, 4, 6) + and r11.xyzw, r11.xyzw, l(3, 3, 3, 3) + and r12.xyzw, r12.xyzw, l(3, 3, 3, 3) + imul null, r12.xyzw, r4.yyyy, r12.xyzw + imad r11.xyzw, r11.xyzw, r4.xxxx, r12.xyzw + and r12.xyzw, r11.xyzw, l(1023, 1023, 1023, 1023) + udiv r12.xyzw, null, r12.xyzw, l(3, 3, 3, 3) + ishl r12.xyzw, r12.xyzw, l(16, 16, 16, 16) + ubfe r13.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r11.xyzw + udiv r13.xyzw, null, r13.xyzw, l(3, 3, 3, 3) + bfi r12.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r13.xyzw, r12.xyzw + ushr r11.xyzw, r11.xyzw, l(20, 20, 20, 20) + udiv r11.xyzw, null, r11.xyzw, l(3, 3, 3, 3) + or r11.xyzw, r11.xyzw, r12.xyzw + or r11.xyzw, r11.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) + movc r9.xyzw, r6.wwww, r9.xyzw, r11.xyzw + store_uav_typed U0[0].xyzw, r5.wwww, r9.xyzw + imad r0.x, vThreadID.y, l(4), l(2) + ult r0.x, r0.x, CB0[0][2].y + not r0.z, r0.x + if_nz r0.x + iadd r0.w, r1.y, r0.w + ushr r3.xyzw, r7.xyzw, l(8, 8, 8, 8) + else + mov r3.x, r10.x + mov r3.yzw, r7.yyzw + endif + if_z r0.z + ushr r7.xyzw, r3.xxxx, l(2, 4, 6, 1) + mov r9.x, r3.x + mov r9.yzw, r7.xxyz + and r10.xyzw, r9.xyzw, l(1, 1, 1, 1) + ubfe r11.xyzw, l(1, 1, 1, 1), l(1, 3, 5, 7), r3.xxxx + imul null, r11.xyzw, r0.yyyy, r11.xyzw + imad r10.xyzw, r10.xyzw, r2.xxxx, r11.xyzw + and r11.x, r3.x, r7.w + and r12.x, r11.x, l(0x00555555) + ushr r11.yzw, r12.xxxx, l(0, 2, 4, 6) + and r13.xyzw, r11.xyzw, l(1, 1, 1, 1) + or r7.x, r3.x, r7.w + ubfe r13.xyzw, l(9, 9, 9, 9), r13.xyzw, r10.xyzw + ishl r13.xyzw, r13.xyzw, l(16, 16, 16, 16) + mov r12.yzw, r11.yyzw + bfi r11.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r12.xyzw, l(10, 10, 10, 10) + ubfe r11.xyzw, l(9, 9, 9, 9), r11.xyzw, r10.xyzw + ishl r11.xyzw, r11.xyzw, l(8, 8, 8, 8) + iadd r11.xyzw, r11.xyzw, r13.xyzw + bfi r12.xyzw, l(2, 2, 2, 2), l(0, 0, 0, 0), r12.xyzw, l(20, 20, 20, 20) + ushr r10.xyzw, r10.xyzw, r12.xyzw + iadd r10.xyzw, r10.xyzw, r11.xyzw + ushr r7.yzw, r7.xxxx, l(0, 2, 4, 6) + and r7.xyzw, r7.xyzw, l(1, 1, 1, 1) + imad r7.xyzw, r7.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000), r10.xyzw + not r10.x, r3.x + ushr r10.yzw, r10.xxxx, l(0, 2, 4, 6) + and r10.xyzw, r10.xyzw, l(3, 3, 3, 3) + and r9.xyzw, r9.xyzw, l(3, 3, 3, 3) + imul null, r9.xyzw, r0.yyyy, r9.xyzw + imad r9.xyzw, r10.xyzw, r2.xxxx, r9.xyzw + and r10.xyzw, r9.xyzw, l(1023, 1023, 1023, 1023) + udiv r10.xyzw, null, r10.xyzw, l(3, 3, 3, 3) + ishl r10.xyzw, r10.xyzw, l(16, 16, 16, 16) + ubfe r11.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r9.xyzw + udiv r11.xyzw, null, r11.xyzw, l(3, 3, 3, 3) + bfi r10.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r11.xyzw, r10.xyzw + ushr r9.xyzw, r9.xyzw, l(20, 20, 20, 20) + udiv r9.xyzw, null, r9.xyzw, l(3, 3, 3, 3) + or r9.xyzw, r9.xyzw, r10.xyzw + or r9.xyzw, r9.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) + movc r7.xyzw, r6.xxxx, r7.xyzw, r9.xyzw + store_uav_typed U0[0].xyzw, r0.wwww, r7.xyzw + iadd r5.xzw, r0.wwww, l(1, 0, 2, 3) + ushr r7.xyzw, r3.yyyy, l(2, 4, 6, 1) + mov r9.x, r3.y + mov r9.yzw, r7.xxyz + and r10.xyzw, r9.xyzw, l(1, 1, 1, 1) + ubfe r11.xyzw, l(1, 1, 1, 1), l(1, 3, 5, 7), r3.yyyy + imul null, r11.xyzw, r5.yyyy, r11.xyzw + imad r10.xyzw, r10.xyzw, r2.yyyy, r11.xyzw + and r11.x, r3.y, r7.w + and r12.x, r11.x, l(0x00555555) + ushr r11.yzw, r12.xxxx, l(0, 2, 4, 6) + and r13.xyzw, r11.xyzw, l(1, 1, 1, 1) + or r7.x, r3.y, r7.w + ubfe r13.xyzw, l(9, 9, 9, 9), r13.xyzw, r10.xyzw + ishl r13.xyzw, r13.xyzw, l(16, 16, 16, 16) + mov r12.yzw, r11.yyzw + bfi r11.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r12.xyzw, l(10, 10, 10, 10) + ubfe r11.xyzw, l(9, 9, 9, 9), r11.xyzw, r10.xyzw + ishl r11.xyzw, r11.xyzw, l(8, 8, 8, 8) + iadd r11.xyzw, r11.xyzw, r13.xyzw + bfi r12.xyzw, l(2, 2, 2, 2), l(0, 0, 0, 0), r12.xyzw, l(20, 20, 20, 20) + ushr r10.xyzw, r10.xyzw, r12.xyzw + iadd r10.xyzw, r10.xyzw, r11.xyzw + ushr r7.yzw, r7.xxxx, l(0, 2, 4, 6) + and r7.xyzw, r7.xyzw, l(1, 1, 1, 1) + imad r7.xyzw, r7.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000), r10.xyzw + not r10.x, r3.y + ushr r10.yzw, r10.xxxx, l(0, 2, 4, 6) + and r10.xyzw, r10.xyzw, l(3, 3, 3, 3) + and r9.xyzw, r9.xyzw, l(3, 3, 3, 3) + imul null, r9.xyzw, r5.yyyy, r9.xyzw + imad r9.xyzw, r10.xyzw, r2.yyyy, r9.xyzw + and r10.xyzw, r9.xyzw, l(1023, 1023, 1023, 1023) + udiv r10.xyzw, null, r10.xyzw, l(3, 3, 3, 3) + ishl r10.xyzw, r10.xyzw, l(16, 16, 16, 16) + ubfe r11.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r9.xyzw + udiv r11.xyzw, null, r11.xyzw, l(3, 3, 3, 3) + bfi r10.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r11.xyzw, r10.xyzw + ushr r9.xyzw, r9.xyzw, l(20, 20, 20, 20) + udiv r9.xyzw, null, r9.xyzw, l(3, 3, 3, 3) + or r9.xyzw, r9.xyzw, r10.xyzw + or r9.xyzw, r9.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) + movc r7.xyzw, r6.yyyy, r7.xyzw, r9.xyzw + store_uav_typed U0[0].xyzw, r5.xxxx, r7.xyzw + ushr r7.xyzw, r3.zzzz, l(2, 4, 6, 1) + mov r9.x, r3.z + mov r9.yzw, r7.xxyz + and r10.xyzw, r9.xyzw, l(1, 1, 1, 1) + ubfe r11.xyzw, l(1, 1, 1, 1), l(1, 3, 5, 7), r3.zzzz + imul null, r11.xyzw, r1.zzzz, r11.xyzw + imad r10.xyzw, r10.xyzw, r1.xxxx, r11.xyzw + and r11.x, r3.z, r7.w + and r12.x, r11.x, l(0x00555555) + ushr r11.yzw, r12.xxxx, l(0, 2, 4, 6) + and r13.xyzw, r11.xyzw, l(1, 1, 1, 1) + or r7.x, r3.z, r7.w + ubfe r13.xyzw, l(9, 9, 9, 9), r13.xyzw, r10.xyzw + ishl r13.xyzw, r13.xyzw, l(16, 16, 16, 16) + mov r12.yzw, r11.yyzw + bfi r11.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r12.xyzw, l(10, 10, 10, 10) + ubfe r11.xyzw, l(9, 9, 9, 9), r11.xyzw, r10.xyzw + ishl r11.xyzw, r11.xyzw, l(8, 8, 8, 8) + iadd r11.xyzw, r11.xyzw, r13.xyzw + bfi r12.xyzw, l(2, 2, 2, 2), l(0, 0, 0, 0), r12.xyzw, l(20, 20, 20, 20) + ushr r10.xyzw, r10.xyzw, r12.xyzw + iadd r10.xyzw, r10.xyzw, r11.xyzw + ushr r7.yzw, r7.xxxx, l(0, 2, 4, 6) + and r7.xyzw, r7.xyzw, l(1, 1, 1, 1) + imad r7.xyzw, r7.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000), r10.xyzw + not r10.x, r3.z + ushr r10.yzw, r10.xxxx, l(0, 2, 4, 6) + and r10.xyzw, r10.xyzw, l(3, 3, 3, 3) + and r9.xyzw, r9.xyzw, l(3, 3, 3, 3) + imul null, r9.xyzw, r1.zzzz, r9.xyzw + imad r9.xyzw, r10.xyzw, r1.xxxx, r9.xyzw + and r10.xyzw, r9.xyzw, l(1023, 1023, 1023, 1023) + udiv r10.xyzw, null, r10.xyzw, l(3, 3, 3, 3) + ishl r10.xyzw, r10.xyzw, l(16, 16, 16, 16) + ubfe r11.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r9.xyzw + udiv r11.xyzw, null, r11.xyzw, l(3, 3, 3, 3) + bfi r10.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r11.xyzw, r10.xyzw + ushr r9.xyzw, r9.xyzw, l(20, 20, 20, 20) + udiv r9.xyzw, null, r9.xyzw, l(3, 3, 3, 3) + or r9.xyzw, r9.xyzw, r10.xyzw + or r9.xyzw, r9.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) + movc r7.xyzw, r6.zzzz, r7.xyzw, r9.xyzw + store_uav_typed U0[0].xyzw, r5.zzzz, r7.xyzw + ushr r7.xyzw, r3.wwww, l(2, 4, 6, 1) + mov r9.x, r3.w + mov r9.yzw, r7.xxyz + and r10.xyzw, r9.xyzw, l(1, 1, 1, 1) + ubfe r11.xyzw, l(1, 1, 1, 1), l(1, 3, 5, 7), r3.wwww + imul null, r11.xyzw, r4.yyyy, r11.xyzw + imad r10.xyzw, r10.xyzw, r4.xxxx, r11.xyzw + and r11.x, r3.w, r7.w + and r12.x, r11.x, l(0x00555555) + ushr r11.yzw, r12.xxxx, l(0, 2, 4, 6) + and r13.xyzw, r11.xyzw, l(1, 1, 1, 1) + or r7.x, r3.w, r7.w + ubfe r13.xyzw, l(9, 9, 9, 9), r13.xyzw, r10.xyzw + ishl r13.xyzw, r13.xyzw, l(16, 16, 16, 16) + mov r12.yzw, r11.yyzw + bfi r11.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r12.xyzw, l(10, 10, 10, 10) + ubfe r11.xyzw, l(9, 9, 9, 9), r11.xyzw, r10.xyzw + ishl r11.xyzw, r11.xyzw, l(8, 8, 8, 8) + iadd r11.xyzw, r11.xyzw, r13.xyzw + bfi r12.xyzw, l(2, 2, 2, 2), l(0, 0, 0, 0), r12.xyzw, l(20, 20, 20, 20) + ushr r10.xyzw, r10.xyzw, r12.xyzw + iadd r10.xyzw, r10.xyzw, r11.xyzw + ushr r7.yzw, r7.xxxx, l(0, 2, 4, 6) + and r7.xyzw, r7.xyzw, l(1, 1, 1, 1) + imad r7.xyzw, r7.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000), r10.xyzw + not r10.x, r3.w + ushr r10.yzw, r10.xxxx, l(0, 2, 4, 6) + and r10.xyzw, r10.xyzw, l(3, 3, 3, 3) + and r9.xyzw, r9.xyzw, l(3, 3, 3, 3) + imul null, r9.xyzw, r4.yyyy, r9.xyzw + imad r9.xyzw, r10.xyzw, r4.xxxx, r9.xyzw + and r10.xyzw, r9.xyzw, l(1023, 1023, 1023, 1023) + udiv r10.xyzw, null, r10.xyzw, l(3, 3, 3, 3) + ishl r10.xyzw, r10.xyzw, l(16, 16, 16, 16) + ubfe r11.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r9.xyzw + udiv r11.xyzw, null, r11.xyzw, l(3, 3, 3, 3) + bfi r10.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r11.xyzw, r10.xyzw + ushr r9.xyzw, r9.xyzw, l(20, 20, 20, 20) + udiv r9.xyzw, null, r9.xyzw, l(3, 3, 3, 3) + or r9.xyzw, r9.xyzw, r10.xyzw + or r9.xyzw, r9.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) + movc r7.xyzw, r6.wwww, r7.xyzw, r9.xyzw + store_uav_typed U0[0].xyzw, r5.wwww, r7.xyzw + endif +else + mov r3.x, r8.x + mov r0.z, l(-1) +endif +if_z r0.z + imad r0.x, vThreadID.y, l(4), l(3) + ult r0.x, r0.x, CB0[0][2].y + if_nz r0.x + iadd r0.x, r1.y, r0.w + ushr r7.xyzw, r3.wxyz, l(8, 8, 8, 8) + ushr r8.xyzw, r7.yyyy, l(2, 4, 6, 1) + mov r9.x, r7.y + mov r9.yzw, r8.xxyz + and r10.xyzw, r9.xyzw, l(1, 1, 1, 1) + ubfe r11.xyzw, l(1, 1, 1, 1), l(9, 11, 13, 15), r3.xxxx + imul null, r11.xyzw, r0.yyyy, r11.xyzw + imad r10.xyzw, r10.xyzw, r2.xxxx, r11.xyzw + and r11.x, r8.w, r9.x + and r12.x, r11.x, l(0x00555555) + ushr r11.yzw, r12.xxxx, l(0, 2, 4, 6) + and r13.xyzw, r11.xyzw, l(1, 1, 1, 1) + or r8.x, r8.w, r9.x + ubfe r13.xyzw, l(9, 9, 9, 9), r13.xyzw, r10.xyzw + ishl r13.xyzw, r13.xyzw, l(16, 16, 16, 16) + mov r12.yzw, r11.yyzw + bfi r11.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r12.xyzw, l(10, 10, 10, 10) + ubfe r11.xyzw, l(9, 9, 9, 9), r11.xyzw, r10.xyzw + ishl r11.xyzw, r11.xyzw, l(8, 8, 8, 8) + iadd r11.xyzw, r11.xyzw, r13.xyzw + bfi r12.xyzw, l(2, 2, 2, 2), l(0, 0, 0, 0), r12.xyzw, l(20, 20, 20, 20) + ushr r10.xyzw, r10.xyzw, r12.xyzw + iadd r10.xyzw, r10.xyzw, r11.xyzw + ushr r8.yzw, r8.xxxx, l(0, 2, 4, 6) + and r8.xyzw, r8.xyzw, l(1, 1, 1, 1) + imad r8.xyzw, r8.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000), r10.xyzw + not r10.xyzw, r7.xyzw + ushr r11.yzw, r10.yyyy, l(0, 2, 4, 6) + mov r11.x, r10.y + and r11.xyzw, r11.xyzw, l(3, 3, 3, 3) + and r9.xyzw, r9.xyzw, l(3, 3, 3, 3) + imul null, r9.xyzw, r0.yyyy, r9.xyzw + imad r9.xyzw, r11.xyzw, r2.xxxx, r9.xyzw + and r11.xyzw, r9.xyzw, l(1023, 1023, 1023, 1023) + udiv r11.xyzw, null, r11.xyzw, l(3, 3, 3, 3) + ishl r11.xyzw, r11.xyzw, l(16, 16, 16, 16) + ubfe r12.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r9.xyzw + udiv r12.xyzw, null, r12.xyzw, l(3, 3, 3, 3) + bfi r11.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r12.xyzw, r11.xyzw + ushr r9.xyzw, r9.xyzw, l(20, 20, 20, 20) + udiv r9.xyzw, null, r9.xyzw, l(3, 3, 3, 3) + or r9.xyzw, r9.xyzw, r11.xyzw + or r9.xyzw, r9.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) + movc r8.xyzw, r6.xxxx, r8.xyzw, r9.xyzw + store_uav_typed U0[0].xyzw, r0.xxxx, r8.xyzw + iadd r0.yzw, r0.xxxx, l(0, 1, 2, 3) + ushr r8.xyzw, r7.zzzz, l(2, 4, 6, 1) + mov r9.x, r7.z + mov r9.yzw, r8.xxyz + and r11.xyzw, r9.xyzw, l(1, 1, 1, 1) + ubfe r12.xyzw, l(1, 1, 1, 1), l(9, 11, 13, 15), r3.yyyy + imul null, r12.xyzw, r5.yyyy, r12.xyzw + imad r11.xyzw, r11.xyzw, r2.yyyy, r12.xyzw + and r12.x, r7.z, r8.w + and r13.x, r12.x, l(0x00555555) + ushr r12.yzw, r13.xxxx, l(0, 2, 4, 6) + and r14.xyzw, r12.xyzw, l(1, 1, 1, 1) + or r8.x, r7.z, r8.w + ubfe r14.xyzw, l(9, 9, 9, 9), r14.xyzw, r11.xyzw + ishl r14.xyzw, r14.xyzw, l(16, 16, 16, 16) + mov r13.yzw, r12.yyzw + bfi r12.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r13.xyzw, l(10, 10, 10, 10) + ubfe r12.xyzw, l(9, 9, 9, 9), r12.xyzw, r11.xyzw + ishl r12.xyzw, r12.xyzw, l(8, 8, 8, 8) + iadd r12.xyzw, r12.xyzw, r14.xyzw + bfi r13.xyzw, l(2, 2, 2, 2), l(0, 0, 0, 0), r13.xyzw, l(20, 20, 20, 20) + ushr r11.xyzw, r11.xyzw, r13.xyzw + iadd r11.xyzw, r11.xyzw, r12.xyzw + ushr r8.yzw, r8.xxxx, l(0, 2, 4, 6) + and r8.xyzw, r8.xyzw, l(1, 1, 1, 1) + imad r8.xyzw, r8.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000), r11.xyzw + ushr r11.yzw, r10.zzzz, l(0, 2, 4, 6) + mov r11.x, r10.z + and r11.xyzw, r11.xyzw, l(3, 3, 3, 3) + and r9.xyzw, r9.xyzw, l(3, 3, 3, 3) + imul null, r5.xyzw, r5.yyyy, r9.xyzw + imad r2.xyzw, r11.xyzw, r2.yyyy, r5.xyzw + and r5.xyzw, r2.xyzw, l(1023, 1023, 1023, 1023) + udiv r5.xyzw, null, r5.xyzw, l(3, 3, 3, 3) + ishl r5.xyzw, r5.xyzw, l(16, 16, 16, 16) + ubfe r9.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r2.xyzw + udiv r9.xyzw, null, r9.xyzw, l(3, 3, 3, 3) + bfi r5.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r9.xyzw, r5.xyzw + ushr r2.xyzw, r2.xyzw, l(20, 20, 20, 20) + udiv r2.xyzw, null, r2.xyzw, l(3, 3, 3, 3) + or r2.xyzw, r2.xyzw, r5.xyzw + or r2.xyzw, r2.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) + movc r2.xyzw, r6.yyyy, r8.xyzw, r2.xyzw + store_uav_typed U0[0].xyzw, r0.yyyy, r2.xyzw + ushr r2.xyzw, r7.wwww, l(2, 4, 6, 1) + mov r5.x, r7.w + mov r5.yzw, r2.xxyz + and r8.xyzw, r5.xyzw, l(1, 1, 1, 1) + ubfe r9.xyzw, l(1, 1, 1, 1), l(9, 11, 13, 15), r3.zzzz + imul null, r9.xyzw, r1.zzzz, r9.xyzw + imad r8.xyzw, r8.xyzw, r1.xxxx, r9.xyzw + and r9.x, r7.w, r2.w + and r11.x, r9.x, l(0x00555555) + ushr r9.yzw, r11.xxxx, l(0, 2, 4, 6) + and r12.xyzw, r9.xyzw, l(1, 1, 1, 1) + or r2.x, r2.w, r7.w + ubfe r12.xyzw, l(9, 9, 9, 9), r12.xyzw, r8.xyzw + ishl r12.xyzw, r12.xyzw, l(16, 16, 16, 16) + mov r11.yzw, r9.yyzw + bfi r9.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r11.xyzw, l(10, 10, 10, 10) + ubfe r9.xyzw, l(9, 9, 9, 9), r9.xyzw, r8.xyzw + ishl r9.xyzw, r9.xyzw, l(8, 8, 8, 8) + iadd r9.xyzw, r9.xyzw, r12.xyzw + bfi r11.xyzw, l(2, 2, 2, 2), l(0, 0, 0, 0), r11.xyzw, l(20, 20, 20, 20) + ushr r8.xyzw, r8.xyzw, r11.xyzw + iadd r8.xyzw, r8.xyzw, r9.xyzw + ushr r2.yzw, r2.xxxx, l(0, 2, 4, 6) + and r2.xyzw, r2.xyzw, l(1, 1, 1, 1) + imad r2.xyzw, r2.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000), r8.xyzw + ushr r8.yzw, r10.wwww, l(0, 2, 4, 6) + mov r8.x, r10.w + and r8.xyzw, r8.xyzw, l(3, 3, 3, 3) + and r5.xyzw, r5.xyzw, l(3, 3, 3, 3) + imul null, r5.xyzw, r1.zzzz, r5.xyzw + imad r1.xyzw, r8.xyzw, r1.xxxx, r5.xyzw + and r5.xyzw, r1.xyzw, l(1023, 1023, 1023, 1023) + udiv r5.xyzw, null, r5.xyzw, l(3, 3, 3, 3) + ishl r5.xyzw, r5.xyzw, l(16, 16, 16, 16) + ubfe r8.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r1.xyzw + udiv r8.xyzw, null, r8.xyzw, l(3, 3, 3, 3) + bfi r5.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r8.xyzw, r5.xyzw + ushr r1.xyzw, r1.xyzw, l(20, 20, 20, 20) + udiv r1.xyzw, null, r1.xyzw, l(3, 3, 3, 3) + or r1.xyzw, r1.xyzw, r5.xyzw + or r1.xyzw, r1.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) + movc r1.xyzw, r6.zzzz, r2.xyzw, r1.xyzw + store_uav_typed U0[0].xyzw, r0.zzzz, r1.xyzw + ushr r1.xyzw, r7.xxxx, l(2, 4, 6, 1) + mov r7.yzw, r1.xxyz + and r2.xyzw, r7.xyzw, l(1, 1, 1, 1) + ubfe r3.xyzw, l(1, 1, 1, 1), l(9, 11, 13, 15), r3.wwww + imul null, r3.xyzw, r4.yyyy, r3.xyzw + imad r2.xyzw, r2.xyzw, r4.xxxx, r3.xyzw + and r3.x, r7.x, r1.w + and r5.x, r3.x, l(0x00555555) + ushr r3.yzw, r5.xxxx, l(0, 2, 4, 6) + and r8.xyzw, r3.xyzw, l(1, 1, 1, 1) + or r1.x, r1.w, r7.x + ubfe r8.xyzw, l(9, 9, 9, 9), r8.xyzw, r2.xyzw + ishl r8.xyzw, r8.xyzw, l(16, 16, 16, 16) + mov r5.yzw, r3.yyzw + bfi r3.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r5.xyzw, l(10, 10, 10, 10) + ubfe r3.xyzw, l(9, 9, 9, 9), r3.xyzw, r2.xyzw + ishl r3.xyzw, r3.xyzw, l(8, 8, 8, 8) + iadd r3.xyzw, r3.xyzw, r8.xyzw + bfi r5.xyzw, l(2, 2, 2, 2), l(0, 0, 0, 0), r5.xyzw, l(20, 20, 20, 20) + ushr r2.xyzw, r2.xyzw, r5.xyzw + iadd r2.xyzw, r2.xyzw, r3.xyzw + ushr r1.yzw, r1.xxxx, l(0, 2, 4, 6) + and r1.xyzw, r1.xyzw, l(1, 1, 1, 1) + imad r1.xyzw, r1.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000), r2.xyzw + ushr r10.yzw, r10.xxxx, l(0, 2, 4, 6) + and r2.xyzw, r10.xyzw, l(3, 3, 3, 3) + and r3.xyzw, r7.xyzw, l(3, 3, 3, 3) + imul null, r3.xyzw, r4.yyyy, r3.xyzw + imad r2.xyzw, r2.xyzw, r4.xxxx, r3.xyzw + and r3.xyzw, r2.xyzw, l(1023, 1023, 1023, 1023) + udiv r3.xyzw, null, r3.xyzw, l(3, 3, 3, 3) + ishl r3.xyzw, r3.xyzw, l(16, 16, 16, 16) + ubfe r4.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r2.xyzw + udiv r4.xyzw, null, r4.xyzw, l(3, 3, 3, 3) + bfi r3.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r4.xyzw, r3.xyzw + ushr r2.xyzw, r2.xyzw, l(20, 20, 20, 20) + udiv r2.xyzw, null, r2.xyzw, l(3, 3, 3, 3) + or r2.xyzw, r2.xyzw, r3.xyzw + or r2.xyzw, r2.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) + movc r1.xyzw, r6.wwww, r1.xyzw, r2.xyzw + store_uav_typed U0[0].xyzw, r0.wwww, r1.xyzw + endif +endif +ret +// Approximately 910 instruction slots used +#endif + +const BYTE texture_load_dxt1_rgba8_cs[] = { + 68, 88, 66, 67, 161, 24, 231, 196, 142, 81, 55, 239, 217, 116, 43, 253, 142, 236, 150, + 205, 1, 0, 0, 0, 52, 139, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 152, 138, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 92, 134, 0, + 0, 81, 0, 5, 0, 151, 33, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 17, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 35, 0, 0, 10, 34, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, + 11, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 30, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 85, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, + 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 150, 5, 2, + 0, 2, 64, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 1, 0, 0, 0, 246, 139, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 14, 146, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 2, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 48, + 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, + 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 19, 0, 0, 0, 19, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 14, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 35, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 50, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 138, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, + 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, + 0, 14, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, 2, 0, 42, 0, 0, + 9, 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 9, 66, + 0, 16, 0, 2, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, 82, 0, 16, 0, 2, + 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 2, 0, 0, + 0, 6, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 128, 3, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 64, + 0, 0, 10, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 10, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 98, + 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, + 17, 98, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, + 86, 6, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 0, 0, 0, 0, + 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 3, 0, 0, 0, + 35, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 150, 5, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, + 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, + 1, 18, 0, 0, 1, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 35, 0, 0, 9, 66, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 21, + 0, 0, 1, 30, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 85, 0, 0, 10, 162, 0, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 10, 210, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 3, 0, + 0, 0, 214, 5, 16, 0, 2, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 50, + 0, 16, 0, 3, 0, 0, 0, 214, 5, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, + 55, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, + 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 4, 0, 0, 0, + 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, + 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, + 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, + 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, + 0, 0, 54, 0, 0, 5, 194, 0, 16, 0, 3, 0, 0, 0, 86, 13, 16, 0, 4, + 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 194, 0, 16, 0, 3, 0, 0, 0, + 86, 13, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 41, 0, 0, 10, 114, 0, 16, + 0, 5, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 7, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 114, + 0, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 13, 0, 0, 0, 4, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 130, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 0, + 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 198, 0, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 146, 0, 16, 0, 6, 0, 0, 0, 166, 6, 16, 0, 5, 0, 0, + 0, 1, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 246, 14, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 0, 240, 3, 0, 0, 0, 0, 0, 0, 240, 3, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, + 0, 1, 0, 0, 0, 6, 1, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 128, 15, 0, 0, 0, 0, 0, 0, 128, 15, 0, 0, 0, 0, 30, 0, 0, 7, 50, + 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 134, 0, 16, 0, + 1, 0, 0, 0, 85, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, + 2, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 7, 0, 112, 0, 0, 0, 0, 0, + 7, 0, 112, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 0, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 85, 0, + 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, + 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, + 5, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 7, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 114, 0, + 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 13, + 0, 0, 0, 4, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 130, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, + 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 3, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 146, 0, 16, 0, 2, 0, 0, 0, 166, 6, 16, 0, 5, 0, 0, 0, + 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 246, 11, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 3, 0, 0, 240, + 3, 0, 30, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, + 0, 0, 0, 166, 11, 16, 0, 2, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, + 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 15, 0, 0, 128, 15, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 82, 0, + 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 2, + 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 134, 0, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 7, 0, 112, 0, 7, 0, 112, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 85, 0, 0, + 10, 50, 0, 16, 0, 2, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 38, 10, 16, 0, 1, 0, + 0, 0, 22, 5, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 5, + 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 7, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 114, 0, 16, + 0, 6, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 13, 0, + 0, 0, 4, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, + 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 0, 0, 10, + 82, 0, 16, 0, 1, 0, 0, 0, 6, 3, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 248, 0, 0, 0, 0, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 146, 0, 16, 0, 6, 0, 0, 0, 166, 6, 16, 0, 5, 0, 0, 0, 1, + 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 182, 15, 16, 0, 6, 0, 0, 0, + 2, 64, 0, 0, 0, 240, 3, 0, 0, 240, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, + 0, 0, 6, 1, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 4, + 0, 0, 0, 70, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 15, + 0, 0, 128, 15, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 82, 0, 16, + 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 4, 0, + 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 134, 0, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 7, 0, 112, 0, 7, 0, 112, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 6, + 2, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, + 50, 0, 16, 0, 4, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 6, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, + 0, 6, 1, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 5, 0, + 0, 0, 166, 10, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 7, + 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 114, 0, 16, 0, + 4, 0, 0, 0, 166, 10, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 13, 0, 0, + 0, 4, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, + 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 146, + 0, 16, 0, 5, 0, 0, 0, 6, 12, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 0, 0, 0, 54, 0, 0, + 5, 146, 0, 16, 0, 4, 0, 0, 0, 166, 6, 16, 0, 5, 0, 0, 0, 1, 0, + 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 246, 11, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 3, 0, 0, 240, 3, 0, + 30, 0, 0, 7, 194, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, + 0, 6, 12, 16, 0, 5, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 4, 0, + 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 15, 0, + 0, 128, 15, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, + 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, + 0, 85, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 112, + 0, 7, 0, 112, 0, 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, + 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 194, + 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, + 10, 194, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 30, + 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, + 70, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 5, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 5, + 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, + 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, + 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 80, 0, 0, 7, + 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 59, 0, 0, 5, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, + 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 87, 0, 0, 7, 242, 0, 16, 0, 7, + 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 85, 0, + 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 87, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 7, 0, + 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, + 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, + 8, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 226, 0, 16, + 0, 8, 0, 0, 0, 6, 9, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 138, 0, 0, 15, + 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 3, 0, + 0, 0, 5, 0, 0, 0, 7, 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, 0, 38, + 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 10, 0, 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, + 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 10, + 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, + 1, 0, 0, 7, 18, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, + 0, 1, 64, 0, 0, 85, 85, 85, 85, 85, 0, 0, 10, 226, 0, 16, 0, 10, 0, + 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 12, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 18, 0, + 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 8, + 0, 0, 0, 138, 0, 0, 12, 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 70, 14, 16, + 0, 12, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 41, 0, 0, 10, 242, 0, + 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, + 226, 0, 16, 0, 11, 0, 0, 0, 86, 14, 16, 0, 10, 0, 0, 0, 140, 0, 0, + 20, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 138, 0, 0, 12, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 9, 0, + 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, 7, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, + 0, 0, 0, 20, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, + 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 7, 0, 0, 0, 6, + 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, + 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 7, + 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 255, + 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 70, 14, 16, 0, 9, 0, 0, + 0, 59, 0, 0, 5, 242, 0, 16, 0, 9, 0, 0, 0, 54, 9, 16, 0, 3, 0, + 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, 86, 5, 16, 0, 9, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, + 6, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, + 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, + 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, + 16, 0, 11, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 11, + 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 11, 0, 0, 0, 0, 208, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 78, 0, 0, 11, 242, + 0, 16, 0, 12, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 140, 0, 0, 17, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, + 12, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 78, 0, 0, 11, 242, + 0, 16, 0, 10, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 60, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 60, 0, 0, 10, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 255, + 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 55, 0, 0, 9, 242, 0, 16, + 0, 7, 0, 0, 0, 6, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 30, 0, 0, 10, 210, 0, 16, 0, 5, 0, 0, 0, 246, 15, 16, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 86, + 5, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, + 6, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, + 0, 26, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 226, 0, 16, 0, 10, 0, + 0, 0, 6, 9, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 5, + 0, 0, 0, 7, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, + 0, 208, 0, 0, 242, 0, 16, 0, 12, 0, 0, 0, 86, 5, 16, 0, 5, 0, 0, + 0, 70, 14, 16, 0, 12, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 12, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 12, 0, 0, 0, + 26, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, + 7, 18, 0, 16, 0, 13, 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 1, 64, + 0, 0, 85, 85, 85, 85, 85, 0, 0, 10, 226, 0, 16, 0, 12, 0, 0, 0, 6, + 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, + 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 7, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, + 138, 0, 0, 12, 242, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, + 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 70, 14, 16, 0, 14, 0, + 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 14, + 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, 226, 0, 16, + 0, 13, 0, 0, 0, 86, 14, 16, 0, 12, 0, 0, 0, 140, 0, 0, 20, 242, 0, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 138, 0, + 0, 12, 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, + 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, + 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 12, + 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, + 140, 0, 0, 20, 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, + 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 20, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 11, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 30, 0, 0, 7, 242, 0, + 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 7, 0, 0, 0, 6, 0, 16, 0, + 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, + 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, + 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 255, 70, 14, 16, 0, 11, 0, 0, 0, 85, 0, + 0, 10, 226, 0, 16, 0, 11, 0, 0, 0, 166, 10, 16, 0, 9, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, + 54, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 10, 0, + 0, 0, 86, 5, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 35, + 0, 0, 9, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 86, 5, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, + 0, 0, 11, 242, 0, 16, 0, 11, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, + 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 12, + 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 10, + 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, + 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 11, 0, 0, 0, 60, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, + 0, 0, 0, 255, 0, 0, 0, 255, 55, 0, 0, 9, 242, 0, 16, 0, 7, 0, 0, + 0, 86, 5, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 85, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 166, 10, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, + 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 3, + 0, 0, 0, 54, 0, 0, 5, 226, 0, 16, 0, 10, 0, 0, 0, 6, 9, 16, 0, + 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 7, 0, 0, + 0, 166, 10, 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, + 16, 0, 12, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, + 0, 1, 0, 0, 7, 18, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 13, + 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 85, 85, 85, 85, + 85, 0, 0, 10, 226, 0, 16, 0, 12, 0, 0, 0, 6, 0, 16, 0, 13, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, + 0, 3, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 138, 0, 0, 12, 242, 0, + 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, + 0, 0, 0, 9, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, + 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, 226, 0, 16, 0, 13, 0, 0, 0, 86, + 14, 16, 0, 12, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 138, 0, 0, 12, 242, 0, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, + 0, 9, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, + 0, 12, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 140, 0, 0, 20, 242, 0, + 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, + 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 85, 0, + 0, 7, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, + 14, 16, 0, 13, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 11, 0, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 85, 0, 0, + 10, 226, 0, 16, 0, 7, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 35, 0, 0, 12, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 70, 14, 16, 0, 11, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, + 11, 0, 0, 0, 246, 15, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 5, 18, 0, + 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, + 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 10, 0, 0, 0, 166, 10, 16, 0, + 1, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 1, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, 0, 11, 242, 0, 16, + 0, 11, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 138, 0, 0, 15, 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 10, 0, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 10, + 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 12, 0, 0, 0, 0, 208, 0, + 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 20, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 10, 0, 0, 0, 0, 208, 0, + 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 60, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 55, 0, 0, 9, 242, 0, 16, 0, 7, 0, 0, 0, 166, 10, 16, 0, 6, + 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, + 0, 5, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 85, 0, 0, 10, 242, 0, + 16, 0, 7, 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 2, + 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, + 18, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, + 5, 226, 0, 16, 0, 10, 0, 0, 0, 6, 9, 16, 0, 7, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 138, 0, 0, 15, 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 7, 0, 0, 0, 246, 15, 16, 0, 3, + 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 12, 0, 0, 0, + 86, 5, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 35, 0, 0, + 9, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 6, 0, + 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 1, 0, 0, 7, 18, + 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, + 7, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 13, 0, 0, 0, 10, 0, 16, + 0, 12, 0, 0, 0, 1, 64, 0, 0, 85, 85, 85, 85, 85, 0, 0, 10, 226, 0, + 16, 0, 12, 0, 0, 0, 6, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 60, 0, + 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 58, + 0, 16, 0, 7, 0, 0, 0, 138, 0, 0, 12, 242, 0, 16, 0, 14, 0, 0, 0, + 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, + 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 41, 0, + 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 54, 0, 0, 5, 226, 0, 16, 0, 13, 0, 0, 0, 86, 14, 16, 0, 12, 0, 0, + 0, 140, 0, 0, 20, 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 138, 0, 0, 12, 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, + 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 70, + 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 41, 0, 0, 10, + 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 30, 0, + 0, 7, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, + 14, 16, 0, 14, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 13, 0, 0, 0, + 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, + 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, + 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 7, + 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 12, 242, + 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 70, 14, 16, + 0, 11, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 9, 0, 0, 0, 6, 0, + 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, + 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, + 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 242, 0, 16, 0, 10, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 9, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 10, 0, 0, 0, 0, 208, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 138, 0, 0, 15, 242, 0, + 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, + 10, 0, 0, 0, 10, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 78, 0, 0, + 11, 242, 0, 16, 0, 11, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, + 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 78, 0, 0, + 11, 242, 0, 16, 0, 9, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 9, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 60, 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 60, 0, 0, 10, 242, 0, 16, + 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 55, 0, 0, 9, 242, + 0, 16, 0, 7, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 7, 0, 0, 0, 35, 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 79, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 31, 0, + 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 85, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, + 1, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, + 0, 7, 0, 0, 0, 54, 0, 0, 5, 226, 0, 16, 0, 10, 0, 0, 0, 6, 9, + 16, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 11, 0, 0, 0, 13, 0, 0, 0, 15, + 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 242, 0, 16, 0, 12, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, + 0, 12, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, + 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, + 9, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, + 0, 13, 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 85, 85, + 85, 0, 85, 0, 0, 10, 226, 0, 16, 0, 12, 0, 0, 0, 6, 0, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, + 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 58, + 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 138, 0, 0, 12, + 242, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, + 0, 9, 0, 0, 0, 9, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, + 16, 0, 11, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, + 14, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, 226, 0, 16, 0, 13, 0, 0, + 0, 86, 14, 16, 0, 12, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 138, 0, 0, 12, 242, 0, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, + 0, 0, 0, 9, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 12, 0, 0, 0, 70, + 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 140, 0, 0, 20, + 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, + 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 85, 0, 0, 7, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, + 0, 70, 14, 16, 0, 13, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 85, + 0, 0, 10, 226, 0, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 9, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, + 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, + 255, 0, 0, 0, 255, 70, 14, 16, 0, 11, 0, 0, 0, 59, 0, 0, 5, 242, 0, + 16, 0, 11, 0, 0, 0, 54, 9, 16, 0, 7, 0, 0, 0, 85, 0, 0, 10, 226, + 0, 16, 0, 12, 0, 0, 0, 86, 5, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 13, 0, 0, 0, 86, + 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 35, 0, 0, 9, + 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 6, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, 0, 11, + 242, 0, 16, 0, 13, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 12, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 14, 0, 0, 0, + 0, 208, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, + 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, + 0, 13, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, + 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, + 0, 0, 0, 20, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 12, 0, 0, 0, + 0, 208, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 242, 0, + 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 60, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, + 255, 0, 0, 0, 255, 55, 0, 0, 9, 242, 0, 16, 0, 9, 0, 0, 0, 6, 0, + 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 246, 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 30, 0, 0, + 10, 210, 0, 16, 0, 5, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 86, 5, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, + 0, 54, 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 7, 0, + 0, 0, 54, 0, 0, 5, 226, 0, 16, 0, 12, 0, 0, 0, 6, 9, 16, 0, 9, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 14, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 9, 0, 0, 0, 11, 0, 0, 0, 13, 0, 0, 0, 15, 0, 0, 0, + 86, 5, 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, + 0, 14, 0, 0, 0, 86, 5, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 14, 0, + 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, + 1, 0, 0, 7, 18, 0, 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, + 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 15, 0, + 0, 0, 10, 0, 16, 0, 14, 0, 0, 0, 1, 64, 0, 0, 85, 85, 85, 0, 85, + 0, 0, 10, 226, 0, 16, 0, 14, 0, 0, 0, 6, 0, 16, 0, 15, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, 14, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, + 7, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 138, 0, 0, 12, 242, 0, 16, + 0, 16, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, + 0, 0, 9, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 54, 0, 0, 5, 226, 0, 16, 0, 15, 0, 0, 0, 86, 14, + 16, 0, 14, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 14, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 138, 0, 0, 12, 242, 0, 16, 0, 14, + 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 14, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, + 14, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, + 0, 15, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, + 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 85, 0, 0, + 7, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, + 16, 0, 15, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 13, 0, 0, 0, 70, + 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 85, 0, 0, 10, + 226, 0, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 35, 0, 0, 12, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 70, 14, 16, 0, 13, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 13, + 0, 0, 0, 166, 10, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 13, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, + 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 12, 0, 0, 0, 86, 5, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, + 12, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, + 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, + 13, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, + 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 138, 0, 0, 15, 242, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 10, 0, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 14, 0, 0, 0, 0, 208, 0, 0, + 70, 14, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 13, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, + 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 12, 0, 0, 0, 0, 208, 0, 0, + 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 242, 0, 16, 0, 12, 0, + 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 60, + 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, + 255, 55, 0, 0, 9, 242, 0, 16, 0, 9, 0, 0, 0, 86, 5, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 164, + 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, + 5, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, + 0, 9, 0, 0, 0, 166, 10, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 18, + 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 5, + 226, 0, 16, 0, 12, 0, 0, 0, 6, 9, 16, 0, 9, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 138, + 0, 0, 15, 242, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, + 0, 11, 0, 0, 0, 13, 0, 0, 0, 15, 0, 0, 0, 166, 10, 16, 0, 3, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 14, 0, 0, 0, 166, + 10, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 35, 0, 0, 9, + 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 6, 0, 16, + 0, 1, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 1, 0, 0, 7, 18, 0, + 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 9, + 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 15, 0, 0, 0, 10, 0, 16, 0, + 14, 0, 0, 0, 1, 64, 0, 0, 85, 85, 85, 0, 85, 0, 0, 10, 226, 0, 16, + 0, 14, 0, 0, 0, 6, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, + 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 58, 0, + 16, 0, 9, 0, 0, 0, 138, 0, 0, 12, 242, 0, 16, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, + 70, 14, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 41, 0, 0, + 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 54, + 0, 0, 5, 226, 0, 16, 0, 15, 0, 0, 0, 86, 14, 16, 0, 14, 0, 0, 0, + 140, 0, 0, 20, 242, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, + 10, 0, 0, 0, 138, 0, 0, 12, 242, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, + 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 70, 14, + 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 41, 0, 0, 10, 242, + 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, + 16, 0, 16, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 15, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 13, + 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, + 30, 0, 0, 7, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 70, 14, 16, 0, 14, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 9, 0, + 0, 0, 6, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 12, 242, 0, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 70, 14, 16, 0, + 13, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 13, 0, 0, 0, 246, 15, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, + 0, 0, 6, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 58, + 0, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, + 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 12, 0, + 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 242, 0, 16, 0, 12, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 70, 14, 16, + 0, 12, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, + 16, 0, 13, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 13, 0, 0, 0, 0, 208, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, + 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 138, 0, 0, 15, 242, 0, + 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, + 10, 0, 0, 0, 10, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 78, 0, 0, + 11, 242, 0, 16, 0, 14, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 14, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 78, 0, 0, + 11, 242, 0, 16, 0, 12, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 60, 0, 0, 7, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, + 12, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 60, 0, 0, 10, 242, 0, 16, + 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 55, 0, 0, 9, 242, + 0, 16, 0, 9, 0, 0, 0, 166, 10, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 246, + 15, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, + 6, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, + 0, 58, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 5, 226, 0, 16, 0, 12, 0, + 0, 0, 6, 9, 16, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, + 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, + 0, 14, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 11, 0, 0, 0, 13, + 0, 0, 0, 15, 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, + 0, 208, 0, 0, 242, 0, 16, 0, 14, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 14, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 13, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 14, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 14, 0, 0, 0, + 58, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 0, 0, + 7, 18, 0, 16, 0, 15, 0, 0, 0, 10, 0, 16, 0, 14, 0, 0, 0, 1, 64, + 0, 0, 85, 85, 85, 0, 85, 0, 0, 10, 226, 0, 16, 0, 14, 0, 0, 0, 6, + 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, + 0, 70, 14, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 9, + 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, + 138, 0, 0, 12, 242, 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, + 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 70, 14, 16, 0, 16, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 16, + 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, 226, 0, 16, + 0, 15, 0, 0, 0, 86, 14, 16, 0, 14, 0, 0, 0, 140, 0, 0, 20, 242, 0, + 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 2, 64, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 138, 0, + 0, 12, 242, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, + 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, + 70, 14, 16, 0, 13, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, + 0, 70, 14, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 14, + 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, + 140, 0, 0, 20, 242, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, + 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 15, + 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 20, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, + 0, 13, 0, 0, 0, 70, 14, 16, 0, 15, 0, 0, 0, 30, 0, 0, 7, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 14, + 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, + 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, + 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 9, 0, 0, 0, + 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 255, 70, 14, 16, 0, 13, 0, 0, 0, 85, 0, + 0, 10, 226, 0, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 12, 0, 0, + 0, 86, 5, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 35, 0, + 0, 9, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 6, + 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, + 0, 11, 242, 0, 16, 0, 12, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 13, 0, 0, 0, 2, + 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 11, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 13, 0, + 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, + 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, + 14, 16, 0, 12, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, + 0, 20, 0, 0, 0, 20, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 11, 0, + 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, + 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 12, 0, 0, 0, 60, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, + 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 255, 55, 0, 0, 9, 242, 0, 16, 0, 9, 0, 0, 0, + 246, 15, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, + 0, 11, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 246, 15, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 35, + 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 79, 0, 0, 9, 18, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 59, 0, 0, 5, 66, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 18, 0, 0, 1, + 54, 0, 0, 5, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, + 0, 54, 0, 0, 5, 226, 0, 16, 0, 3, 0, 0, 0, 86, 14, 16, 0, 7, 0, + 0, 0, 21, 0, 0, 1, 31, 0, 0, 3, 42, 0, 16, 0, 0, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, + 0, 54, 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 54, 0, 0, 5, 226, 0, 16, 0, 9, 0, 0, 0, 6, 9, 16, 0, 7, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 9, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 7, 0, 0, 0, + 6, 0, 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, + 0, 11, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 1, 0, 0, 7, 18, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 58, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 12, 0, + 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 85, 85, 85, 0, 85, + 0, 0, 10, 226, 0, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 138, 0, 0, 12, 242, 0, 16, + 0, 13, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, + 0, 0, 9, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 54, 0, 0, 5, 226, 0, 16, 0, 12, 0, 0, 0, 86, 14, + 16, 0, 11, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 138, 0, 0, 12, 242, 0, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 85, 0, 0, + 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 12, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 85, 0, 0, 10, + 226, 0, 16, 0, 7, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 35, 0, 0, 12, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 70, 14, 16, 0, 10, 0, 0, 0, 59, 0, 0, 5, 18, 0, 16, 0, 10, + 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, + 10, 0, 0, 0, 6, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, + 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 9, 0, 0, 0, 86, 5, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, + 10, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, + 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 138, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 10, 0, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, 14, 16, 0, 9, + 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 11, 0, 0, 0, 0, 208, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, + 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, + 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 9, 0, 0, 0, 0, 208, 0, 0, + 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 242, 0, 16, 0, 9, 0, + 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 60, + 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, + 255, 55, 0, 0, 9, 242, 0, 16, 0, 7, 0, 0, 0, 6, 0, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 164, + 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 30, 0, 0, 10, 210, 0, 16, + 0, 5, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 7, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 54, 0, + 0, 5, 226, 0, 16, 0, 9, 0, 0, 0, 6, 9, 16, 0, 7, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 138, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 7, 0, 0, 0, 86, 5, 16, 0, + 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 11, 0, 0, + 0, 86, 5, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 35, 0, + 0, 9, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 86, + 5, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 1, 0, 0, 7, + 18, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, + 0, 7, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 12, 0, 0, 0, 10, 0, + 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 85, 85, 85, 0, 85, 0, 0, 10, 226, + 0, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 60, + 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 7, 0, 0, 0, 138, 0, 0, 12, 242, 0, 16, 0, 13, 0, 0, + 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, + 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 54, 0, 0, 5, 226, 0, 16, 0, 12, 0, 0, 0, 86, 14, 16, 0, 11, 0, + 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 10, 0, 0, 0, 138, 0, 0, 12, 242, 0, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 41, 0, 0, + 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 30, + 0, 0, 7, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 70, 14, 16, 0, 13, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, + 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 12, 0, + 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, + 7, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 12, + 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 70, 14, + 16, 0, 10, 0, 0, 0, 59, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 26, + 0, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, + 6, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, + 0, 0, 242, 0, 16, 0, 9, 0, 0, 0, 86, 5, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 9, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 10, 0, 0, 0, + 0, 208, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, + 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 138, 0, 0, 15, + 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 78, + 0, 0, 11, 242, 0, 16, 0, 11, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 78, + 0, 0, 11, 242, 0, 16, 0, 9, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, + 9, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 60, 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 60, 0, 0, 10, 242, + 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 55, 0, 0, + 9, 242, 0, 16, 0, 7, 0, 0, 0, 86, 5, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 164, 0, 0, 8, 242, + 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 7, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, + 0, 166, 10, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, + 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 9, + 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 226, 0, 16, 0, + 9, 0, 0, 0, 6, 9, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 138, 0, 0, 15, 242, + 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 3, 0, 0, + 0, 5, 0, 0, 0, 7, 0, 0, 0, 166, 10, 16, 0, 3, 0, 0, 0, 38, 0, + 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 11, 0, 0, 0, 166, 10, 16, 0, 1, + 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, + 0, 70, 14, 16, 0, 11, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 11, 0, + 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 1, + 0, 0, 7, 18, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, + 1, 64, 0, 0, 85, 85, 85, 0, 85, 0, 0, 10, 226, 0, 16, 0, 11, 0, 0, + 0, 6, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, + 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, + 0, 7, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 7, 0, + 0, 0, 138, 0, 0, 12, 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 9, + 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, 226, + 0, 16, 0, 12, 0, 0, 0, 86, 14, 16, 0, 11, 0, 0, 0, 140, 0, 0, 20, + 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, + 138, 0, 0, 12, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, + 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 11, + 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 13, 0, + 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 2, + 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 30, 0, 0, 7, + 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 11, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 7, 0, 0, 0, 6, 0, + 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, + 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 70, 14, 16, 0, 10, 0, 0, 0, + 59, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, + 0, 85, 0, 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, 6, 0, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, + 9, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, + 0, 35, 0, 0, 9, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, + 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 78, 0, 0, 11, 242, 0, 16, 0, 10, 0, 0, 0, 0, 208, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, + 10, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, + 0, 11, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 140, + 0, 0, 17, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 9, + 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, + 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, + 0, 9, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, + 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 60, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, + 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 55, 0, 0, 9, 242, 0, 16, 0, 7, + 0, 0, 0, 166, 10, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 9, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 166, 10, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 7, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 246, 15, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, + 1, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, + 0, 3, 0, 0, 0, 54, 0, 0, 5, 226, 0, 16, 0, 9, 0, 0, 0, 6, 9, + 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 7, + 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 242, 0, 16, 0, 11, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 11, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 11, + 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, + 0, 12, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 85, 85, + 85, 0, 85, 0, 0, 10, 226, 0, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, + 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 58, + 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 138, 0, 0, 12, + 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, + 0, 9, 0, 0, 0, 9, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, + 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, 226, 0, 16, 0, 12, 0, 0, + 0, 86, 14, 16, 0, 11, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 138, 0, 0, 12, 242, 0, + 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, + 0, 0, 0, 9, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, + 0, 11, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 11, 0, 0, 0, 70, + 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 140, 0, 0, 20, + 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 85, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 12, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 85, + 0, 0, 10, 226, 0, 16, 0, 7, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, + 255, 0, 0, 0, 255, 70, 14, 16, 0, 10, 0, 0, 0, 59, 0, 0, 5, 18, 0, + 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, + 0, 16, 0, 10, 0, 0, 0, 6, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 9, 0, 0, 0, 86, 5, + 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 242, + 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 6, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, 0, 11, 242, + 0, 16, 0, 10, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 11, 0, 0, 0, 0, + 208, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, + 0, 10, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, + 0, 9, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 9, 0, 0, 0, 0, + 208, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 242, 0, 16, + 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 60, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, + 0, 0, 0, 255, 55, 0, 0, 9, 242, 0, 16, 0, 7, 0, 0, 0, 246, 15, 16, + 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, + 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 21, 0, 0, 1, + 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, + 0, 8, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 255, 255, 255, 255, 21, 0, 0, 1, 31, 0, 0, 3, 42, 0, 16, 0, 0, + 0, 0, 0, 35, 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 2, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 79, 0, 0, + 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, + 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 7, 0, 0, 0, 54, 9, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 86, 5, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, + 0, 54, 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 7, 0, + 0, 0, 54, 0, 0, 5, 226, 0, 16, 0, 9, 0, 0, 0, 6, 9, 16, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 9, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 9, 0, 0, 0, 11, 0, 0, 0, 13, 0, 0, 0, 15, 0, 0, 0, + 6, 0, 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, + 0, 11, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 1, 0, 0, 7, 18, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, + 0, 10, 0, 16, 0, 9, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 12, 0, + 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 85, 85, 85, 0, 85, + 0, 0, 10, 226, 0, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, + 8, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 138, 0, 0, 12, 242, 0, 16, + 0, 13, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, + 0, 0, 9, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 54, 0, 0, 5, 226, 0, 16, 0, 12, 0, 0, 0, 86, 14, + 16, 0, 11, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 11, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 138, 0, 0, 12, 242, 0, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 85, 0, 0, + 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 12, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 85, 0, 0, 10, + 226, 0, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 35, 0, 0, 12, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 70, 14, 16, 0, 10, 0, 0, 0, 59, 0, 0, 5, 242, 0, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, + 11, 0, 0, 0, 86, 5, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 5, 18, 0, + 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, + 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 9, 0, 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, + 0, 9, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, + 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, 0, 11, 242, 0, 16, + 0, 11, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 138, 0, 0, 15, 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 10, 0, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 10, + 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 9, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 12, 0, 0, 0, 0, 208, 0, + 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 11, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, + 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 20, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 9, 0, 0, 0, 0, 208, 0, + 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 242, 0, 16, 0, 9, + 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 60, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 55, 0, 0, 9, 242, 0, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 6, + 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, + 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 30, 0, 0, 10, 226, 0, + 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 8, 0, 0, 0, 166, 10, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 54, + 0, 0, 5, 226, 0, 16, 0, 9, 0, 0, 0, 6, 9, 16, 0, 8, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 9, 0, 0, 0, 11, 0, 0, 0, 13, 0, 0, 0, 15, 0, 0, 0, 86, 5, 16, + 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 12, 0, + 0, 0, 86, 5, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 35, + 0, 0, 9, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 86, 5, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 1, 0, 0, + 7, 18, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 58, 0, + 16, 0, 8, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 13, 0, 0, 0, 10, + 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 85, 85, 85, 0, 85, 0, 0, 10, + 226, 0, 16, 0, 12, 0, 0, 0, 6, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 60, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, + 0, 58, 0, 16, 0, 8, 0, 0, 0, 138, 0, 0, 12, 242, 0, 16, 0, 14, 0, + 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, + 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 54, 0, 0, 5, 226, 0, 16, 0, 13, 0, 0, 0, 86, 14, 16, 0, 12, + 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 10, 0, 0, 0, 138, 0, 0, 12, 242, 0, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, + 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 41, 0, + 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 30, 0, 0, 7, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, + 0, 70, 14, 16, 0, 14, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 13, 0, + 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, + 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 85, 0, 0, 7, 242, 0, + 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 13, + 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, + 11, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, + 0, 8, 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, + 12, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 70, + 14, 16, 0, 11, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 11, 0, 0, 0, + 166, 10, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, 0, + 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, + 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, + 208, 0, 0, 242, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 11, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 5, 0, 0, + 0, 0, 208, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, + 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 138, 0, 0, + 15, 242, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 78, 0, 0, 11, 242, 0, 16, 0, 9, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, + 0, 9, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 85, 0, + 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 78, 0, 0, 11, 242, 0, 16, 0, 2, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 60, 0, 0, 10, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 55, 0, + 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 6, 0, 0, 0, 70, + 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 164, 0, 0, 8, + 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, + 0, 0, 246, 15, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, + 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, + 5, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 5, 226, 0, 16, + 0, 5, 0, 0, 0, 6, 9, 16, 0, 2, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 138, 0, 0, 15, + 242, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 11, 0, + 0, 0, 13, 0, 0, 0, 15, 0, 0, 0, 166, 10, 16, 0, 3, 0, 0, 0, 38, + 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 9, 0, 0, 0, 166, 10, 16, 0, + 1, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 1, 0, + 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 9, + 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 1, 0, 0, 7, 18, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, + 0, 1, 64, 0, 0, 85, 85, 85, 0, 85, 0, 0, 10, 226, 0, 16, 0, 9, 0, + 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 12, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 18, 0, + 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 7, + 0, 0, 0, 138, 0, 0, 12, 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 70, 14, 16, + 0, 12, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 41, 0, 0, 10, 242, 0, + 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, + 226, 0, 16, 0, 11, 0, 0, 0, 86, 14, 16, 0, 9, 0, 0, 0, 140, 0, 0, + 20, 242, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 138, 0, 0, 12, 242, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 9, 0, + 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, + 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, 7, 242, 0, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, + 0, 0, 0, 20, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, + 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 2, 0, 0, 0, 6, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 255, + 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 70, 14, 16, 0, 8, 0, 0, + 0, 85, 0, 0, 10, 226, 0, 16, 0, 8, 0, 0, 0, 246, 15, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, + 10, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, + 0, 5, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 5, 0, + 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 8, + 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 5, 0, 0, 0, 0, 208, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 78, 0, 0, 11, 242, 0, + 16, 0, 8, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 140, 0, 0, 17, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, + 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, + 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, + 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 78, 0, 0, 11, 242, 0, + 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 60, 0, 0, 7, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 60, 0, 0, 10, 242, 0, 16, 0, 1, 0, + 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 55, 0, 0, 9, 242, 0, 16, 0, + 1, 0, 0, 0, 166, 10, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 1, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, + 7, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, + 0, 1, 0, 0, 0, 54, 0, 0, 5, 226, 0, 16, 0, 7, 0, 0, 0, 6, 9, + 16, 0, 1, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 11, 0, 0, 0, 13, 0, 0, 0, 15, + 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 242, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, + 7, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, + 0, 5, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 85, 85, + 85, 0, 85, 0, 0, 10, 226, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, + 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 138, 0, 0, 12, + 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, + 0, 9, 0, 0, 0, 9, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 54, 0, 0, 5, 226, 0, 16, 0, 5, 0, 0, + 0, 86, 14, 16, 0, 3, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 138, 0, 0, 12, 242, 0, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, + 0, 0, 0, 9, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 140, 0, 0, 20, + 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 85, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 85, + 0, 0, 10, 226, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, + 255, 0, 0, 0, 255, 70, 14, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 226, 0, + 16, 0, 10, 0, 0, 0, 6, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 35, 0, 0, 9, 242, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, 0, 11, 242, 0, + 16, 0, 3, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 10, + 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 4, 0, 0, 0, 0, 208, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, + 0, 20, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 2, 0, 0, 0, 0, 208, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 60, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 55, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, + 6, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, + 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 21, + 0, 0, 1, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 142, 3, 0, 0, + 17, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, + 0, 141, 1, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, + 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt3_rgba8_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt3_rgba8_cs.h new file mode 100644 index 0000000..e4be64d --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt3_rgba8_cs.h @@ -0,0 +1,1125 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 9 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(1) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r1.yz, r1.xxyx, l(0, 2, 2, 0) +ishl r0.w, r1.y, l(2) +imad r1.y, vThreadID.z, CB0[0][2].y, r1.z +imad r0.w, r1.y, CB0[0][2].x, r0.w +iadd r0.w, r0.w, CB0[0][1].w +ushr r1.y, CB0[0][2].x, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r2.xw, l(27, 0, 0, 29), l(4, 0, 0, 2), vThreadID.xxxx + imad r0.y, r0.y, r1.w, r2.x + ishl r1.z, vThreadID.y, l(12) + and r1.z, r1.z, l(0x00006000) + bfi r1.z, l(3), l(10), r1.x, r1.z + ishr r1.z, r1.z, l(6) + iadd r1.w, r2.y, r2.z + bfi r2.x, l(1), l(1), r1.w, l(0) + iadd r2.x, r2.x, r2.w + bfi r2.x, l(2), l(1), r2.x, l(0) + bfi r1.w, l(1), l(0), r1.w, r2.x + bfi r2.xy, l(18, 18, 0, 0), l(12, 15, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(10, 13, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(6) + bfi r1.w, l(1), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(6, 6, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.zw, l(0, 0, 27, 29), l(0, 0, 4, 2), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r2.z, CB0[0][0].z, l(5) + imad r1.z, r2.x, r2.z, r1.z + ishl r2.x, vThreadID.y, l(7) + and r2.xz, r2.xxxx, l(1792, 0, 2048, 0) + bfi r2.w, l(3), l(5), r1.x, r2.x + bfi r2.w, l(21), l(11), r1.z, r2.w + bfi r3.x, l(1), l(4), vThreadID.y, l(0) + iadd r2.w, r2.w, r3.x + ishl r3.yz, r2.xxxx, l(0, 3, 2, 0) + bfi r3.yz, l(0, 3, 3, 0), l(0, 8, 7, 0), r1.xxxx, r3.yyzy + bfi r3.yz, l(0, 21, 21, 0), l(0, 14, 13, 0), r1.zzzz, r3.yyzy + imad r3.xy, r3.xxxx, l(8, 4, 0, 0), r3.yzyy + bfi r1.z, l(12), l(0), r2.z, r3.x + and r2.x, r3.y, l(1792) + iadd r1.z, r1.z, r2.x + and r2.x, r2.y, l(2) + iadd r1.w, r1.w, r2.x + bfi r1.w, l(2), l(6), r1.w, l(0) + iadd r1.z, r1.z, r1.w + bfi r0.y, l(6), l(0), r2.w, r1.z + endif +else + ishl r1.x, r1.x, l(4) + imad r1.z, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.z, CB0[0][0].z, r1.x +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.yw, r0.yyyw, l(0, 4, 0, 4) +ld r2.xyzw, r0.yyyy, T0[0].yxzw +ieq r1.xzw, r0.zzzz, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r3.xyzw, r2.yxzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.yxzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.yxzw, r4.yxzw +endif +if_nz r1.z + ushr r3.xyzw, r2.yxzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.yxzw + mov r3.x, r2.y +else + mov r3.x, r2.y +endif +ishl r4.xyz, r2.zzzz, l(3, 7, 12, 0) +ushr r5.xyz, r2.zzzz, l(13, 4, 9, 0) +mov r4.w, r5.x +and r4.xw, r4.xxxw, l(248, 0, 0, 248) +mov r5.xw, r4.zzzy +and r5.zw, r5.wwwz, l(0, 0, 0x0003f000, 0x0003f000) +iadd r4.xy, r4.xwxx, r5.zwzz +and r4.zw, r5.xxxy, l(0, 0, 0x0f800000, 0x0f800000) +iadd r4.xy, r4.zwzz, r4.xyxx +ushr r4.zw, r4.xxxy, l(0, 0, 5, 5) +and r4.zw, r4.zzzw, l(0, 0, 0x00700007, 0x00700007) +iadd r4.xy, r4.zwzz, r4.xyxx +ushr r4.zw, r4.xxxy, l(0, 0, 6, 6) +and r4.zw, r4.zzzw, l(0, 0, 3072, 3072) +iadd r4.xy, r4.zwzz, r4.xyxx +ishl r0.z, r2.w, l(1) +and r0.z, r0.z, l(0xaaaaaaaa) +ushr r1.w, r2.w, l(1) +and r1.w, r1.w, l(0x55555555) +iadd r0.z, r0.z, r1.w +ushr r1.w, r0.z, l(1) +and r1.w, r1.w, l(0x55555555) +xor r5.x, r0.z, r1.w +not r6.x, r5.x +ushr r6.yzw, r6.xxxx, l(0, 2, 4, 6) +and r6.xyzw, r6.xyzw, l(3, 3, 3, 3) +ushr r5.yzw, r5.xxxx, l(0, 2, 4, 6) +and r7.xyzw, r5.xyzw, l(3, 3, 3, 3) +imul null, r7.xyzw, r4.yyyy, r7.xyzw +imad r6.xyzw, r6.xyzw, r4.xxxx, r7.xyzw +and r7.xyzw, r6.xyzw, l(1023, 1023, 1023, 1023) +udiv r7.xyzw, null, r7.xyzw, l(3, 3, 3, 3) +ishl r7.xyzw, r7.xyzw, l(16, 16, 16, 16) +ubfe r8.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r6.xyzw +udiv r8.xyzw, null, r8.xyzw, l(3, 3, 3, 3) +bfi r7.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r8.xyzw, r7.xyzw +ushr r6.xyzw, r6.xyzw, l(20, 20, 20, 20) +udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) +or r6.xyzw, r6.xyzw, r7.xyzw +ushr r3.yzw, r3.xxxx, l(0, 4, 8, 12) +and r7.xyzw, r3.xyzw, l(15, 15, 15, 15) +imad r6.xyzw, r7.xyzw, l(0x11000000, 0x11000000, 0x11000000, 0x11000000), r6.xyzw +store_uav_typed U0[0].xyzw, r0.wwww, r6.xyzw +imad r0.z, vThreadID.y, l(4), l(1) +ult r0.z, r0.z, CB0[0][2].y +if_nz r0.z + iadd r1.w, r1.y, r0.w + ushr r6.x, r5.x, l(8) + not r7.x, r6.x + ushr r7.yzw, r7.xxxx, l(0, 2, 4, 6) + and r7.xyzw, r7.xyzw, l(3, 3, 3, 3) + ushr r6.yzw, r6.xxxx, l(0, 2, 4, 6) + and r6.xyzw, r6.xyzw, l(3, 3, 3, 3) + imul null, r6.xyzw, r4.yyyy, r6.xyzw + imad r6.xyzw, r7.xyzw, r4.xxxx, r6.xyzw + and r7.xyzw, r6.xyzw, l(1023, 1023, 1023, 1023) + udiv r7.xyzw, null, r7.xyzw, l(3, 3, 3, 3) + ishl r7.xyzw, r7.xyzw, l(16, 16, 16, 16) + ubfe r8.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r6.xyzw + udiv r8.xyzw, null, r8.xyzw, l(3, 3, 3, 3) + bfi r7.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r8.xyzw, r7.xyzw + ushr r6.xyzw, r6.xyzw, l(20, 20, 20, 20) + udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) + or r6.xyzw, r6.xyzw, r7.xyzw + ubfe r3.xyzw, l(4, 4, 4, 4), l(16, 20, 24, 28), r3.xxxx + imad r3.xyzw, r3.xyzw, l(0x11000000, 0x11000000, 0x11000000, 0x11000000), r6.xyzw + store_uav_typed U0[0].xyzw, r1.wwww, r3.xyzw + imad r1.w, vThreadID.y, l(4), l(2) + ult r1.w, r1.w, CB0[0][2].y + if_nz r1.w + ishl r1.w, r1.y, l(1) + iadd r1.w, r0.w, r1.w + ushr r3.x, r5.x, l(16) + not r6.x, r3.x + ushr r6.yzw, r6.xxxx, l(0, 2, 4, 6) + and r6.xyzw, r6.xyzw, l(3, 3, 3, 3) + ushr r3.yzw, r3.xxxx, l(0, 2, 4, 6) + and r3.xyzw, r3.xyzw, l(3, 3, 3, 3) + imul null, r3.xyzw, r4.yyyy, r3.xyzw + imad r3.xyzw, r6.xyzw, r4.xxxx, r3.xyzw + and r6.xyzw, r3.xyzw, l(1023, 1023, 1023, 1023) + udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) + ishl r6.xyzw, r6.xyzw, l(16, 16, 16, 16) + ubfe r7.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r3.xyzw + udiv r7.xyzw, null, r7.xyzw, l(3, 3, 3, 3) + bfi r6.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r7.xyzw, r6.xyzw + ushr r3.xyzw, r3.xyzw, l(20, 20, 20, 20) + udiv r3.xyzw, null, r3.xyzw, l(3, 3, 3, 3) + or r3.xyzw, r3.xyzw, r6.xyzw + ushr r2.yzw, r2.xxxx, l(0, 4, 8, 12) + and r6.xyzw, r2.xyzw, l(15, 15, 15, 15) + imad r3.xyzw, r6.xyzw, l(0x11000000, 0x11000000, 0x11000000, 0x11000000), r3.xyzw + store_uav_typed U0[0].xyzw, r1.wwww, r3.xyzw + imad r1.w, vThreadID.y, l(4), l(3) + ult r1.w, r1.w, CB0[0][2].y + if_nz r1.w + imad r1.w, l(3), r1.y, r0.w + ushr r3.x, r5.x, l(24) + not r5.x, r3.x + ushr r5.yzw, r5.xxxx, l(0, 2, 4, 6) + and r5.xyzw, r5.xyzw, l(3, 3, 3, 3) + ushr r3.yzw, r3.xxxx, l(0, 2, 4, 6) + and r3.xyzw, r3.xyzw, l(3, 3, 3, 3) + imul null, r3.xyzw, r4.yyyy, r3.xyzw + imad r3.xyzw, r5.xyzw, r4.xxxx, r3.xyzw + and r4.xyzw, r3.xyzw, l(1023, 1023, 1023, 1023) + udiv r4.xyzw, null, r4.xyzw, l(3, 3, 3, 3) + ishl r4.xyzw, r4.xyzw, l(16, 16, 16, 16) + ubfe r5.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r3.xyzw + udiv r5.xyzw, null, r5.xyzw, l(3, 3, 3, 3) + bfi r4.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r5.xyzw, r4.xyzw + ushr r3.xyzw, r3.xyzw, l(20, 20, 20, 20) + udiv r3.xyzw, null, r3.xyzw, l(3, 3, 3, 3) + or r3.xyzw, r3.xyzw, r4.xyzw + ubfe r2.xyzw, l(4, 4, 4, 4), l(16, 20, 24, 28), r2.xxxx + imad r2.xyzw, r2.xyzw, l(0x11000000, 0x11000000, 0x11000000, 0x11000000), r3.xyzw + store_uav_typed U0[0].xyzw, r1.wwww, r2.xyzw + endif + endif +endif +iadd r0.w, r0.w, l(1) +movc r0.x, r0.x, l(2), l(1) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].yxzw +if_nz r1.x + ishl r3.xyzw, r2.yxzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.yxzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.yxzw, r4.yxzw +endif +if_nz r1.z + ushr r3.xyzw, r2.yxzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.yxzw + mov r3.x, r2.y +else + mov r3.x, r2.y +endif +ishl r4.xyz, r2.zzzz, l(3, 7, 12, 0) +ushr r5.xyz, r2.zzzz, l(13, 4, 9, 0) +mov r4.w, r5.x +and r0.xy, r4.xwxx, l(248, 248, 0, 0) +mov r5.xw, r4.zzzy +and r1.xz, r5.wwzw, l(0x0003f000, 0, 0x0003f000, 0) +iadd r0.xy, r0.xyxx, r1.xzxx +and r1.xz, r5.xxyx, l(0x0f800000, 0, 0x0f800000, 0) +iadd r0.xy, r0.xyxx, r1.xzxx +ushr r1.xz, r0.xxyx, l(5, 0, 5, 0) +and r1.xz, r1.xxzx, l(0x00700007, 0, 0x00700007, 0) +iadd r0.xy, r0.xyxx, r1.xzxx +ushr r1.xz, r0.xxyx, l(6, 0, 6, 0) +and r1.xz, r1.xxzx, l(3072, 0, 3072, 0) +iadd r0.xy, r0.xyxx, r1.xzxx +ishl r1.x, r2.w, l(1) +ushr r1.z, r2.w, l(1) +and r1.xz, r1.xxzx, l(0xaaaaaaaa, 0, 0x55555555, 0) +iadd r1.x, r1.z, r1.x +ushr r1.z, r1.x, l(1) +and r1.z, r1.z, l(0x55555555) +xor r4.x, r1.z, r1.x +not r5.x, r4.x +ushr r5.yzw, r5.xxxx, l(0, 2, 4, 6) +and r5.xyzw, r5.xyzw, l(3, 3, 3, 3) +ushr r4.yzw, r4.xxxx, l(0, 2, 4, 6) +and r6.xyzw, r4.xyzw, l(3, 3, 3, 3) +imul null, r6.xyzw, r0.yyyy, r6.xyzw +imad r5.xyzw, r5.xyzw, r0.xxxx, r6.xyzw +and r6.xyzw, r5.xyzw, l(1023, 1023, 1023, 1023) +udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) +ishl r6.xyzw, r6.xyzw, l(16, 16, 16, 16) +ubfe r7.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r5.xyzw +udiv r7.xyzw, null, r7.xyzw, l(3, 3, 3, 3) +bfi r6.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r7.xyzw, r6.xyzw +ushr r5.xyzw, r5.xyzw, l(20, 20, 20, 20) +udiv r5.xyzw, null, r5.xyzw, l(3, 3, 3, 3) +or r5.xyzw, r5.xyzw, r6.xyzw +ushr r3.yzw, r3.xxxx, l(0, 4, 8, 12) +and r6.xyzw, r3.xyzw, l(15, 15, 15, 15) +imad r5.xyzw, r6.xyzw, l(0x11000000, 0x11000000, 0x11000000, 0x11000000), r5.xyzw +store_uav_typed U0[0].xyzw, r0.wwww, r5.xyzw +if_nz r0.z + iadd r0.z, r1.y, r0.w + ushr r5.x, r4.x, l(8) + not r6.x, r5.x + ushr r6.yzw, r6.xxxx, l(0, 2, 4, 6) + and r6.xyzw, r6.xyzw, l(3, 3, 3, 3) + ushr r5.yzw, r5.xxxx, l(0, 2, 4, 6) + and r5.xyzw, r5.xyzw, l(3, 3, 3, 3) + imul null, r5.xyzw, r0.yyyy, r5.xyzw + imad r5.xyzw, r6.xyzw, r0.xxxx, r5.xyzw + and r6.xyzw, r5.xyzw, l(1023, 1023, 1023, 1023) + udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) + ishl r6.xyzw, r6.xyzw, l(16, 16, 16, 16) + ubfe r7.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r5.xyzw + udiv r7.xyzw, null, r7.xyzw, l(3, 3, 3, 3) + bfi r6.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r7.xyzw, r6.xyzw + ushr r5.xyzw, r5.xyzw, l(20, 20, 20, 20) + udiv r5.xyzw, null, r5.xyzw, l(3, 3, 3, 3) + or r5.xyzw, r5.xyzw, r6.xyzw + ubfe r3.xyzw, l(4, 4, 4, 4), l(16, 20, 24, 28), r3.xxxx + imad r3.xyzw, r3.xyzw, l(0x11000000, 0x11000000, 0x11000000, 0x11000000), r5.xyzw + store_uav_typed U0[0].xyzw, r0.zzzz, r3.xyzw + imad r0.z, vThreadID.y, l(4), l(2) + ult r0.z, r0.z, CB0[0][2].y + if_nz r0.z + ishl r0.z, r1.y, l(1) + iadd r0.z, r0.z, r0.w + ushr r3.x, r4.x, l(16) + not r5.x, r3.x + ushr r5.yzw, r5.xxxx, l(0, 2, 4, 6) + and r5.xyzw, r5.xyzw, l(3, 3, 3, 3) + ushr r3.yzw, r3.xxxx, l(0, 2, 4, 6) + and r3.xyzw, r3.xyzw, l(3, 3, 3, 3) + imul null, r3.xyzw, r0.yyyy, r3.xyzw + imad r3.xyzw, r5.xyzw, r0.xxxx, r3.xyzw + and r5.xyzw, r3.xyzw, l(1023, 1023, 1023, 1023) + udiv r5.xyzw, null, r5.xyzw, l(3, 3, 3, 3) + ishl r5.xyzw, r5.xyzw, l(16, 16, 16, 16) + ubfe r6.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r3.xyzw + udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) + bfi r5.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r6.xyzw, r5.xyzw + ushr r3.xyzw, r3.xyzw, l(20, 20, 20, 20) + udiv r3.xyzw, null, r3.xyzw, l(3, 3, 3, 3) + or r3.xyzw, r3.xyzw, r5.xyzw + ushr r2.yzw, r2.xxxx, l(0, 4, 8, 12) + and r5.xyzw, r2.xyzw, l(15, 15, 15, 15) + imad r3.xyzw, r5.xyzw, l(0x11000000, 0x11000000, 0x11000000, 0x11000000), r3.xyzw + store_uav_typed U0[0].xyzw, r0.zzzz, r3.xyzw + imad r0.z, vThreadID.y, l(4), l(3) + ult r0.z, r0.z, CB0[0][2].y + if_nz r0.z + imad r0.z, l(3), r1.y, r0.w + ushr r1.x, r4.x, l(24) + not r3.x, r1.x + ushr r3.yzw, r3.xxxx, l(0, 2, 4, 6) + and r3.xyzw, r3.xyzw, l(3, 3, 3, 3) + ushr r1.yzw, r1.xxxx, l(0, 2, 4, 6) + and r1.xyzw, r1.xyzw, l(3, 3, 3, 3) + imul null, r1.xyzw, r0.yyyy, r1.xyzw + imad r1.xyzw, r3.xyzw, r0.xxxx, r1.xyzw + and r3.xyzw, r1.xyzw, l(1023, 1023, 1023, 1023) + udiv r3.xyzw, null, r3.xyzw, l(3, 3, 3, 3) + ishl r3.xyzw, r3.xyzw, l(16, 16, 16, 16) + ubfe r4.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r1.xyzw + udiv r4.xyzw, null, r4.xyzw, l(3, 3, 3, 3) + bfi r3.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r4.xyzw, r3.xyzw + ushr r1.xyzw, r1.xyzw, l(20, 20, 20, 20) + udiv r1.xyzw, null, r1.xyzw, l(3, 3, 3, 3) + or r1.xyzw, r1.xyzw, r3.xyzw + ubfe r2.xyzw, l(4, 4, 4, 4), l(16, 20, 24, 28), r2.xxxx + imad r1.xyzw, r2.xyzw, l(0x11000000, 0x11000000, 0x11000000, 0x11000000), r1.xyzw + store_uav_typed U0[0].xyzw, r0.zzzz, r1.xyzw + endif + endif +endif +ret +// Approximately 347 instruction slots used +#endif + +const BYTE texture_load_dxt3_rgba8_cs[] = { + 68, 88, 66, 67, 57, 182, 117, 152, 4, 237, 12, 67, 185, 113, 138, 208, 218, 118, 230, + 188, 1, 0, 0, 0, 156, 53, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 0, 53, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 196, 48, 0, + 0, 81, 0, 5, 0, 49, 12, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 9, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 35, 0, 0, 10, 34, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, + 11, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 30, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 85, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, + 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 150, 5, 2, + 0, 2, 64, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 1, 0, 0, 0, 246, 139, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 14, 146, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 2, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 96, + 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, + 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 18, 0, 0, 0, 18, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 15, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 35, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 50, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 138, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, + 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, + 0, 14, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 2, 0, 42, 0, 0, + 9, 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 9, 66, + 0, 16, 0, 2, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, + 82, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 140, 0, + 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 5, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 21, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 18, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 6, + 0, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, + 98, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, + 0, 21, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 14, 0, + 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 86, + 6, 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, + 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, 3, 0, 0, 0, 140, 0, + 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, + 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, + 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 41, 0, 0, 7, 18, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 2, 0, 58, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 2, 0, + 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 0, 0, 0, + 0, 86, 13, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 22, 126, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 32, 0, 0, 10, 210, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, + 11, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, + 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 22, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, + 0, 4, 0, 0, 0, 22, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 2, 0, 0, 0, 22, 14, 16, 0, 3, 0, 0, 0, 22, 14, + 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 22, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 22, 14, 16, 0, 3, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 18, 0, + 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, + 0, 0, 0, 21, 0, 0, 1, 41, 0, 0, 10, 114, 0, 16, 0, 4, 0, 0, 0, + 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 7, 0, 0, + 0, 12, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 114, 0, 16, 0, 5, 0, + 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 13, 0, 0, 0, 4, + 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, + 4, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 0, 0, 10, 146, 0, 16, + 0, 4, 0, 0, 0, 6, 12, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 248, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 0, 0, 0, 54, 0, 0, 5, 146, + 0, 16, 0, 5, 0, 0, 0, 166, 6, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, + 194, 0, 16, 0, 5, 0, 0, 0, 246, 11, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 3, 0, 0, 240, 3, 0, 30, 0, + 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 198, 0, 16, 0, 4, 0, 0, 0, 230, + 10, 16, 0, 5, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, + 6, 4, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 128, 15, 0, 0, 128, 15, 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, + 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 85, + 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, + 0, 1, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 112, 0, 7, + 0, 112, 0, 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, + 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 194, 0, 16, + 0, 4, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 194, + 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 30, 0, 0, + 7, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 70, 0, + 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, + 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 170, 170, 170, 170, 85, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 85, 85, 85, 85, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 85, 85, 85, 85, 87, 0, 0, 7, 18, 0, 16, + 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 59, 0, 0, 5, 18, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 5, + 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, + 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, + 6, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 242, 0, 16, 0, 7, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 7, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 7, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 7, 0, 0, 0, 0, 208, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, + 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 138, 0, 0, 15, 242, 0, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, + 10, 0, 0, 0, 10, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 78, 0, 0, + 11, 242, 0, 16, 0, 8, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 8, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, + 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 78, 0, 0, + 11, 242, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 60, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, + 0, 3, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 35, 0, 0, + 12, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 70, + 14, 16, 0, 6, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, + 0, 35, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 2, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 79, 0, 0, 9, 66, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, + 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, + 8, 0, 0, 0, 59, 0, 0, 5, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, + 0, 6, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 7, 0, 0, 0, 6, 0, + 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, + 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 6, 0, + 0, 0, 6, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, + 0, 0, 242, 0, 16, 0, 6, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 7, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 7, 0, 0, 0, + 0, 208, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, + 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 138, 0, 0, 15, + 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 78, + 0, 0, 11, 242, 0, 16, 0, 8, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 78, + 0, 0, 11, 242, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 60, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, + 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 20, 0, 0, + 0, 24, 0, 0, 0, 28, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 35, 0, + 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, + 70, 14, 16, 0, 6, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 35, 0, 0, 8, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 79, 0, 0, 9, + 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, + 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 59, 0, 0, 5, 18, + 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, + 226, 0, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 85, 0, 0, 10, 226, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 3, 0, 0, + 0, 86, 5, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 35, 0, + 0, 9, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 6, + 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, + 0, 11, 242, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 6, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 7, 0, + 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, + 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, + 14, 16, 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, + 0, 20, 0, 0, 0, 20, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 3, 0, + 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 2, 0, 0, 0, 6, 0, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, + 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 15, 0, 0, 0, 15, 0, 0, + 0, 15, 0, 0, 0, 15, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 17, 0, + 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 70, 14, 16, 0, 3, 0, 0, 0, + 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, + 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 35, 0, 0, 8, 130, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 79, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 1, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 35, 0, + 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, + 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, + 0, 24, 0, 0, 0, 59, 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, 6, + 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 3, + 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, + 208, 0, 0, 242, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 4, 0, 0, + 0, 0, 208, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, + 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 138, 0, 0, + 15, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 78, 0, 0, 11, 242, 0, 16, 0, 5, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 85, 0, + 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 78, 0, 0, 11, 242, 0, 16, 0, 3, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 138, 0, 0, 15, + 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 20, 0, + 0, 0, 24, 0, 0, 0, 28, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 35, + 0, 0, 12, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, + 17, 70, 14, 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 30, 0, 0, 7, + 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 55, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, + 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 22, 126, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 22, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 22, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, + 22, 14, 16, 0, 3, 0, 0, 0, 22, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, + 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, 0, + 16, 0, 3, 0, 0, 0, 22, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, + 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 22, + 14, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 3, 0, 0, 0, + 26, 0, 16, 0, 2, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, + 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 41, 0, + 0, 10, 114, 0, 16, 0, 4, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 13, 0, 0, 0, 4, 0, 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 5, + 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 198, 0, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 5, 146, 0, 16, 0, 5, 0, 0, 0, 166, 6, + 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 246, + 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 240, 3, 0, 0, 0, 0, 0, + 0, 240, 3, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 0, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 128, 15, 0, 0, 0, 0, 0, 0, 128, 15, 0, 0, 0, 0, + 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, + 0, 134, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 82, 0, 16, 0, 1, 0, + 0, 0, 6, 1, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, + 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 7, 0, 112, + 0, 0, 0, 0, 0, 7, 0, 112, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, + 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 134, 0, 16, 0, 1, + 0, 0, 0, 85, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, + 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, + 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 170, 170, 170, 170, 0, 0, 0, 0, 85, 85, 85, 85, 0, 0, 0, 0, 30, 0, + 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 85, 85, 85, 85, 87, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 59, 0, 0, 5, + 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 85, 0, 0, + 10, 226, 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 85, 0, 0, 10, 226, 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 6, 0, + 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 35, + 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, + 0, 0, 11, 242, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 7, + 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 5, + 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, + 7, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 3, 0, 0, 0, 6, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 8, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 15, 0, 0, 0, 15, 0, + 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 17, + 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 70, 14, 16, 0, 5, 0, 0, + 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, + 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 42, + 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 8, 0, 0, 0, 59, 0, 0, 5, 18, 0, 16, 0, 6, 0, 0, 0, 10, + 0, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, + 6, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, + 5, 0, 0, 0, 6, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, + 0, 208, 0, 0, 242, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 5, 0, + 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 6, 0, + 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, + 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 138, 0, + 0, 15, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, + 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 78, 0, 0, 11, 242, 0, 16, 0, 7, 0, 0, 0, 0, 208, 0, 0, 70, 14, + 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 6, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, + 0, 78, 0, 0, 11, 242, 0, 16, 0, 5, 0, 0, 0, 0, 208, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 138, 0, 0, + 15, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, + 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 20, + 0, 0, 0, 24, 0, 0, 0, 28, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, + 35, 0, 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, + 0, 17, 70, 14, 16, 0, 5, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 35, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 2, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 79, 0, + 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, + 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 59, 0, 0, + 5, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 85, 0, + 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, + 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 3, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 35, 0, 0, 9, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 78, 0, 0, 11, 242, 0, 16, 0, 5, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 6, 0, 0, + 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, + 6, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, + 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, + 3, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, + 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 2, 0, 0, 0, + 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 8, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 15, 0, 0, 0, 15, + 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 70, 14, 16, 0, 3, 0, + 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, + 10, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 35, 0, 0, 8, + 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 79, 0, 0, 9, 66, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, + 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, + 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, + 64, 0, 0, 24, 0, 0, 0, 59, 0, 0, 5, 18, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 3, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, + 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 242, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 1, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 1, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 3, + 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, + 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 138, + 0, 0, 15, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, + 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, 14, 16, 0, 1, 0, + 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 4, 0, 0, 0, 0, 208, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 85, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 70, + 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 242, 0, 16, 0, 1, 0, 0, + 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 138, 0, + 0, 15, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 20, 0, 0, 0, 24, 0, 0, 0, 28, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, + 0, 35, 0, 0, 12, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, + 0, 0, 17, 70, 14, 16, 0, 1, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 14, 16, + 0, 1, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 62, 0, + 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 91, 1, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 155, 0, 0, 0, + 6, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt3a_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt3a_cs.h new file mode 100644 index 0000000..0cb69db --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt3a_cs.h @@ -0,0 +1,608 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 7 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(2) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r1.yz, r1.xxyx, l(0, 2, 2, 0) +imad r0.w, vThreadID.z, CB0[0][2].y, r1.z +imad r0.w, r0.w, CB0[0][2].x, r1.y +iadd r0.w, r0.w, CB0[0][1].w +ushr r1.y, CB0[0][2].x, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r2.xw, l(27, 0, 0, 29), l(3, 0, 0, 1), vThreadID.xxxx + imad r0.y, r0.y, r1.w, r2.x + ishl r1.z, vThreadID.y, l(11) + and r1.z, r1.z, l(0x00003000) + bfi r1.z, l(3), l(9), r1.x, r1.z + ishr r1.z, r1.z, l(6) + iadd r1.w, r2.y, r2.z + bfi r2.x, l(1), l(1), r1.w, l(0) + iadd r2.x, r2.x, r2.w + bfi r2.x, l(2), l(1), r2.x, l(0) + bfi r1.w, l(1), l(0), r1.w, r2.x + bfi r2.xy, l(19, 19, 0, 0), l(11, 14, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(9, 12, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(6) + bfi r1.w, l(1), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(6, 6, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r2.z, CB0[0][0].z, l(5) + imad r1.z, r2.x, r2.z, r1.z + ishl r2.xz, vThreadID.yyyy, l(6, 0, 7, 0) + and r2.xz, r2.xxzx, l(896, 0, 2048, 0) + bfi r2.w, l(3), l(4), r1.x, r2.x + bfi r2.w, l(22), l(10), r1.z, r2.w + bfi r3.x, l(1), l(4), vThreadID.y, l(0) + iadd r2.w, r2.w, r3.x + ishl r3.yz, r2.xxxx, l(0, 3, 2, 0) + bfi r3.yz, l(0, 3, 3, 0), l(0, 7, 6, 0), r1.xxxx, r3.yyzy + bfi r3.yz, l(0, 22, 22, 0), l(0, 13, 12, 0), r1.zzzz, r3.yyzy + imad r3.xy, r3.xxxx, l(8, 4, 0, 0), r3.yzyy + bfi r1.z, l(12), l(0), r2.z, r3.x + and r2.x, r3.y, l(1792) + iadd r1.z, r1.z, r2.x + and r2.x, r2.y, l(2) + iadd r1.w, r1.w, r2.x + bfi r1.w, l(2), l(6), r1.w, l(0) + iadd r1.z, r1.z, r1.w + bfi r0.y, l(6), l(0), r2.w, r1.z + endif +else + ishl r1.x, r1.x, l(3) + imad r1.z, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.z, CB0[0][0].z, r1.x +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.yw, r0.yyyw, l(0, 4, 0, 4) +ld r2.xyzw, r0.yyyy, T0[0].ywxz +ieq r1.xzw, r0.zzzz, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r3.xyzw, r2.zxwy, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.zxwy, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.ywxz, r4.ywxz +endif +if_nz r1.z + ushr r3.xyzw, r2.zxwy, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.ywxz + mov r3.xy, r2.zwzz +else + mov r3.xy, r2.zwzz +endif +movc r0.x, r0.x, l(2), l(1) +iadd r0.x, r0.x, r0.y +ld r4.xyzw, r0.xxxx, T0[0].xyzw +if_nz r1.x + ishl r5.xyzw, r4.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r6.xyzw, r4.xyzw, l(8, 8, 8, 8) + and r6.xyzw, r6.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r4.xyzw, r5.xyzw, r6.xyzw +endif +if_nz r1.z + ushr r5.xyzw, r4.xyzw, l(16, 16, 16, 16) + bfi r5.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r4.xyzw, r5.xyzw + mov r3.zw, r5.xxxz + mov r2.zw, r5.yyyw +else + mov r3.zw, r4.xxxz + mov r2.zw, r4.yyyw +endif +bfi r4.xyzw, l(8, 8, 8, 8), l(4, 4, 4, 4), r3.xyzw, l(0, 0, 0, 0) +bfi r4.xyzw, l(4, 4, 4, 4), l(0, 0, 0, 0), r3.xyzw, r4.xyzw +ishl r5.xyzw, r3.xyzw, l(8, 8, 8, 8) +and r5.xyzw, r5.xyzw, l(0x000ff000, 0x000ff000, 0x000ff000, 0x000ff000) +iadd r4.xyzw, r4.xyzw, r5.xyzw +ishl r5.xyzw, r3.xyzw, l(12, 12, 12, 12) +and r5.xyzw, r5.xyzw, l(0x0ff00000, 0x0ff00000, 0x0ff00000, 0x0ff00000) +iadd r4.xyzw, r4.xyzw, r5.xyzw +ishl r5.xyzw, r3.xyzw, l(16, 16, 16, 16) +bfi r4.xyzw, l(28, 28, 28, 28), l(0, 0, 0, 0), r4.xyzw, r5.xyzw +store_uav_typed U0[0].xyzw, r0.wwww, r4.xyzw +imad r0.x, vThreadID.y, l(4), l(1) +ult r0.y, r0.x, CB0[0][2].y +if_nz r0.y + iadd r0.y, r1.y, r0.w + ushr r4.xyzw, r3.xyzw, l(16, 16, 16, 16) + bfi r5.xyzw, l(8, 8, 8, 8), l(4, 4, 4, 4), r4.xyzw, l(0, 0, 0, 0) + bfi r5.xyzw, l(4, 4, 4, 4), l(0, 0, 0, 0), r4.xyzw, r5.xyzw + ishl r6.xyzw, r4.xyzw, l(8, 8, 8, 8) + and r6.xyzw, r6.xyzw, l(0x000ff000, 0x000ff000, 0x000ff000, 0x000ff000) + iadd r5.xyzw, r5.xyzw, r6.xyzw + ishl r4.xyzw, r4.xyzw, l(12, 12, 12, 12) + bfi r4.xyzw, l(20, 20, 20, 20), l(0, 0, 0, 0), r5.xyzw, r4.xyzw + bfi r3.xyzw, l(28, 28, 28, 28), l(0, 0, 0, 0), r4.xyzw, r3.xyzw + store_uav_typed U0[0].xyzw, r0.yyyy, r3.xyzw + iadd r0.x, r0.x, l(1) + ult r0.z, r0.x, CB0[0][2].y + if_nz r0.z + iadd r0.y, r1.y, r0.y + bfi r3.xyzw, l(8, 8, 8, 8), l(4, 4, 4, 4), r2.xyzw, l(0, 0, 0, 0) + bfi r3.xyzw, l(4, 4, 4, 4), l(0, 0, 0, 0), r2.xyzw, r3.xyzw + ishl r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x000ff000, 0x000ff000, 0x000ff000, 0x000ff000) + iadd r3.xyzw, r3.xyzw, r4.xyzw + ishl r4.xyzw, r2.xyzw, l(12, 12, 12, 12) + and r4.xyzw, r4.xyzw, l(0x0ff00000, 0x0ff00000, 0x0ff00000, 0x0ff00000) + iadd r3.xyzw, r3.xyzw, r4.xyzw + ishl r4.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r3.xyzw, l(28, 28, 28, 28), l(0, 0, 0, 0), r3.xyzw, r4.xyzw + store_uav_typed U0[0].xyzw, r0.yyyy, r3.xyzw + or r0.x, r0.x, l(3) + ult r0.x, r0.x, CB0[0][2].y + if_nz r0.x + iadd r0.x, r1.y, r0.y + ushr r1.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r3.xyzw, l(8, 8, 8, 8), l(4, 4, 4, 4), r1.xyzw, l(0, 0, 0, 0) + bfi r3.xyzw, l(4, 4, 4, 4), l(0, 0, 0, 0), r1.xyzw, r3.xyzw + ishl r4.xyzw, r1.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x000ff000, 0x000ff000, 0x000ff000, 0x000ff000) + iadd r3.xyzw, r3.xyzw, r4.xyzw + ishl r1.xyzw, r1.xyzw, l(12, 12, 12, 12) + bfi r1.xyzw, l(20, 20, 20, 20), l(0, 0, 0, 0), r3.xyzw, r1.xyzw + bfi r1.xyzw, l(28, 28, 28, 28), l(0, 0, 0, 0), r1.xyzw, r2.xyzw + store_uav_typed U0[0].xyzw, r0.xxxx, r1.xyzw + endif + endif +endif +ret +// Approximately 167 instruction slots used +#endif + +const BYTE texture_load_dxt3a_cs[] = { + 68, 88, 66, 67, 245, 18, 72, 94, 1, 28, 156, 223, 91, 178, 163, 174, 221, 77, 218, + 156, 1, 0, 0, 0, 148, 28, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 248, 27, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 188, 23, 0, + 0, 81, 0, 5, 0, 239, 5, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 7, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 35, 0, 0, 10, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 130, 0, + 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 9, 34, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, + 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 114, + 0, 16, 0, 2, 0, 0, 0, 150, 5, 2, 0, 2, 64, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, 194, 0, 16, + 0, 1, 0, 0, 0, 246, 139, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, + 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 139, 0, 0, 14, 146, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 27, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 2, 0, + 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, + 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 11, + 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 48, 0, 0, 140, 0, 0, 11, 66, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 9, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 19, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 11, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 2, + 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, + 0, 140, 0, 0, 16, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, + 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 2, 0, + 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, + 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, 66, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, + 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, + 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 140, 0, 0, 17, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 14, 194, 0, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, + 0, 0, 0, 6, 0, 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, + 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 85, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 9, 82, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, + 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 10, 82, 0, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 128, 3, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 22, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 18, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, + 0, 3, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 3, 0, 0, 0, 6, 0, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 3, 0, 0, 0, 140, + 0, 0, 17, 98, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 22, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 13, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, + 0, 0, 86, 6, 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 3, + 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, 3, 0, 0, + 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, + 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 41, 0, 0, 7, + 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, + 0, 0, 0, 0, 86, 13, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, + 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 214, 120, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 210, 0, 16, 0, 1, 0, 0, 0, + 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, 1, 0, + 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 31, + 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, + 3, 0, 0, 0, 38, 7, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 38, 7, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 214, 8, 16, 0, 3, 0, 0, + 0, 214, 8, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, + 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 38, + 7, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 214, 8, 16, 0, 3, 0, 0, 0, + 54, 0, 0, 5, 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, + 0, 18, 0, 0, 1, 54, 0, 0, 5, 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, + 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 55, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, + 0, 8, 242, 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, + 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, + 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 6, 0, + 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 140, 0, 0, 17, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 194, 0, 16, + 0, 3, 0, 0, 0, 6, 8, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 194, 0, + 16, 0, 2, 0, 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 18, 0, 0, 1, 54, + 0, 0, 5, 194, 0, 16, 0, 3, 0, 0, 0, 6, 8, 16, 0, 4, 0, 0, 0, + 54, 0, 0, 5, 194, 0, 16, 0, 2, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, + 0, 21, 0, 0, 1, 140, 0, 0, 20, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 0, 240, 15, 0, 0, 240, 15, 0, 0, 240, 15, + 0, 0, 240, 15, 0, 30, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 242, + 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 240, 15, 0, 0, 240, 15, 0, 0, 240, 15, 0, 0, 240, 15, 30, + 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, + 28, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, + 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 35, 0, 0, 8, + 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 79, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, + 0, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, + 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 240, 15, 0, 0, + 240, 15, 0, 0, 240, 15, 0, 0, 240, 15, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, + 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 140, 0, 0, 17, 242, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, + 28, 0, 0, 0, 28, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 79, 0, 0, 9, 66, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 242, 0, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 240, 15, 0, 0, 240, 15, + 0, 0, 240, 15, 0, 0, 240, 15, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 240, 15, 0, 0, 240, 15, 0, 0, 240, 15, 0, + 0, 240, 15, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, + 28, 0, 0, 0, 28, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 4, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 60, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 79, 0, 0, 9, 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 1, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, + 0, 0, 4, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, + 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 240, 15, 0, 0, + 240, 15, 0, 0, 240, 15, 0, 0, 240, 15, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, + 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 242, + 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, + 28, 0, 0, 0, 28, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, + 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 62, 0, 0, 1, 83, 84, 65, + 84, 148, 0, 0, 0, 167, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 33, 0, 0, 0, 6, 0, 0, 0, 10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt3aas1111_argb4_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt3aas1111_argb4_cs.h new file mode 100644 index 0000000..25bd032 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt3aas1111_argb4_cs.h @@ -0,0 +1,1285 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 11 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(2) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r1.yz, r1.xxyx, l(0, 2, 2, 0) +ishl r0.w, r1.y, l(1) +imad r1.y, vThreadID.z, CB0[0][2].y, r1.z +imad r0.w, r1.y, CB0[0][2].x, r0.w +iadd r0.w, r0.w, CB0[0][1].w +ushr r1.y, CB0[0][2].x, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r2.xw, l(27, 0, 0, 29), l(3, 0, 0, 1), vThreadID.xxxx + imad r0.y, r0.y, r1.w, r2.x + ishl r1.z, vThreadID.y, l(11) + and r1.z, r1.z, l(0x00003000) + bfi r1.z, l(3), l(9), r1.x, r1.z + ishr r1.z, r1.z, l(6) + iadd r1.w, r2.y, r2.z + bfi r2.x, l(1), l(1), r1.w, l(0) + iadd r2.x, r2.x, r2.w + bfi r2.x, l(2), l(1), r2.x, l(0) + bfi r1.w, l(1), l(0), r1.w, r2.x + bfi r2.xy, l(19, 19, 0, 0), l(11, 14, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(9, 12, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(6) + bfi r1.w, l(1), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(6, 6, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r2.z, CB0[0][0].z, l(5) + imad r1.z, r2.x, r2.z, r1.z + ishl r2.xz, vThreadID.yyyy, l(6, 0, 7, 0) + and r2.xz, r2.xxzx, l(896, 0, 2048, 0) + bfi r2.w, l(3), l(4), r1.x, r2.x + bfi r2.w, l(22), l(10), r1.z, r2.w + bfi r3.x, l(1), l(4), vThreadID.y, l(0) + iadd r2.w, r2.w, r3.x + ishl r3.yz, r2.xxxx, l(0, 3, 2, 0) + bfi r3.yz, l(0, 3, 3, 0), l(0, 7, 6, 0), r1.xxxx, r3.yyzy + bfi r3.yz, l(0, 22, 22, 0), l(0, 13, 12, 0), r1.zzzz, r3.yyzy + imad r3.xy, r3.xxxx, l(8, 4, 0, 0), r3.yzyy + bfi r1.z, l(12), l(0), r2.z, r3.x + and r2.x, r3.y, l(1792) + iadd r1.z, r1.z, r2.x + and r2.x, r2.y, l(2) + iadd r1.w, r1.w, r2.x + bfi r1.w, l(2), l(6), r1.w, l(0) + iadd r1.z, r1.z, r1.w + bfi r0.y, l(6), l(0), r2.w, r1.z + endif +else + ishl r1.x, r1.x, l(3) + imad r1.z, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.z, CB0[0][0].z, r1.x +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.yw, r0.yyyw, l(0, 4, 0, 4) +ld r2.xyzw, r0.yyyy, T0[0].ywxz +ieq r1.xzw, r0.zzzz, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r3.xyzw, r2.zxwy, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.zxwy, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.ywxz, r4.ywxz +endif +if_nz r1.z + ushr r3.xyzw, r2.zxwy, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.ywxz + mov r3.xy, r2.zwzz +else + mov r3.xy, r2.zwzz +endif +movc r0.x, r0.x, l(2), l(1) +iadd r0.x, r0.x, r0.y +ld r4.xyzw, r0.xxxx, T0[0].xzyw +if_nz r1.x + ishl r5.xyzw, r4.xzyw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r6.xyzw, r4.xzyw, l(8, 8, 8, 8) + and r6.xyzw, r6.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r4.xyzw, r5.xzyw, r6.xzyw +endif +if_nz r1.z + ushr r5.xyzw, r4.xzyw, l(16, 16, 16, 16) + bfi r4.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r4.xyzw, r5.xzyw + mov r5.zw, r4.xxxy +else + mov r5.zw, r4.xxxy +endif +ushr r6.xyzw, r3.xxyy, l(3, 11, 3, 11) +bfi r6.xyzw, l(1, 1, 1, 1), l(4, 4, 4, 4), r6.xyzw, l(0, 0, 0, 0) +ushr r7.xyzw, r3.xxyy, l(7, 15, 7, 15) +bfi r7.xyzw, l(1, 1, 1, 1), l(20, 20, 20, 20), r7.xyzw, l(0, 0, 0, 0) +iadd r6.xyzw, r6.xyzw, r7.xyzw +ushr r7.xyzw, r3.xxyy, l(2, 10, 2, 10) +bfi r6.xyzw, l(1, 1, 1, 1), l(8, 8, 8, 8), r7.xyzw, r6.xyzw +ushr r7.xyzw, r3.xxyy, l(6, 14, 6, 14) +bfi r7.xyzw, l(1, 1, 1, 1), l(24, 24, 24, 24), r7.xyzw, l(0, 0, 0, 0) +iadd r6.xyzw, r6.xyzw, r7.xyzw +ushr r7.xyzw, r3.xxyy, l(1, 9, 1, 9) +bfi r6.xyzw, l(1, 1, 1, 1), l(12, 12, 12, 12), r7.xyzw, r6.xyzw +ushr r7.xyzw, r3.xxyy, l(5, 13, 5, 13) +bfi r8.xyzw, l(1, 1, 1, 1), l(28, 28, 28, 28), r7.xyzw, l(0, 0, 0, 0) +iadd r8.xyzw, r6.xyzw, r8.xyzw +ushr r3.zw, r3.xxxy, l(0, 0, 8, 8) +bfi r8.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r3.xzyw, r8.xyzw +ushr r9.xyzw, r3.xxyy, l(4, 12, 4, 12) +bfi r8.xyzw, l(1, 1, 1, 1), l(16, 16, 16, 16), r9.xyzw, r8.xyzw +bfi r7.xyzw, l(1, 1, 1, 1), l(29, 29, 29, 29), r7.xyzw, l(0, 0, 0, 0) +imad r6.xyzw, r6.xyzw, l(2, 2, 2, 2), r7.xyzw +bfi r6.xyzw, l(1, 1, 1, 1), l(1, 1, 1, 1), r3.xzyw, r6.xyzw +bfi r6.xyzw, l(1, 1, 1, 1), l(17, 17, 17, 17), r9.xyzw, r6.xyzw +iadd r6.xyzw, r6.xyzw, r8.xyzw +ishl r7.xyzw, r6.xyzw, l(2, 2, 2, 2) +iadd r6.xyzw, r6.xyzw, r7.xyzw +store_uav_typed U0[0].xyzw, r0.wwww, r6.xyzw +iadd r0.x, r0.w, l(1) +ushr r6.xyzw, r5.zzww, l(3, 11, 3, 11) +bfi r6.xyzw, l(1, 1, 1, 1), l(4, 4, 4, 4), r6.xyzw, l(0, 0, 0, 0) +ushr r7.xyzw, r5.zzww, l(7, 15, 7, 15) +bfi r7.xyzw, l(1, 1, 1, 1), l(20, 20, 20, 20), r7.xyzw, l(0, 0, 0, 0) +iadd r6.xyzw, r6.xyzw, r7.xyzw +ushr r7.xyzw, r5.zzww, l(2, 10, 2, 10) +bfi r6.xyzw, l(1, 1, 1, 1), l(8, 8, 8, 8), r7.xyzw, r6.xyzw +ushr r7.xyzw, r5.zzww, l(6, 14, 6, 14) +bfi r7.xyzw, l(1, 1, 1, 1), l(24, 24, 24, 24), r7.xyzw, l(0, 0, 0, 0) +iadd r6.xyzw, r6.xyzw, r7.xyzw +ushr r7.xyzw, r5.zzww, l(1, 9, 1, 9) +bfi r6.xyzw, l(1, 1, 1, 1), l(12, 12, 12, 12), r7.xyzw, r6.xyzw +ushr r7.xyzw, r5.zzww, l(5, 13, 5, 13) +bfi r8.xyzw, l(1, 1, 1, 1), l(28, 28, 28, 28), r7.xyzw, l(0, 0, 0, 0) +iadd r8.xyzw, r6.xyzw, r8.xyzw +ushr r5.xy, r5.zwzz, l(8, 8, 0, 0) +bfi r8.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r5.zxwy, r8.xyzw +ushr r9.xyzw, r5.zzww, l(4, 12, 4, 12) +bfi r8.xyzw, l(1, 1, 1, 1), l(16, 16, 16, 16), r9.xyzw, r8.xyzw +bfi r7.xyzw, l(1, 1, 1, 1), l(29, 29, 29, 29), r7.xyzw, l(0, 0, 0, 0) +imad r6.xyzw, r6.xyzw, l(2, 2, 2, 2), r7.xyzw +bfi r6.xyzw, l(1, 1, 1, 1), l(1, 1, 1, 1), r5.zxwy, r6.xyzw +bfi r6.xyzw, l(1, 1, 1, 1), l(17, 17, 17, 17), r9.xyzw, r6.xyzw +iadd r6.xyzw, r6.xyzw, r8.xyzw +ishl r7.xyzw, r6.xyzw, l(2, 2, 2, 2) +iadd r6.xyzw, r6.xyzw, r7.xyzw +store_uav_typed U0[0].xyzw, r0.xxxx, r6.xyzw +imad r0.x, vThreadID.y, l(4), l(1) +ult r0.y, r0.x, CB0[0][2].y +if_nz r0.y + iadd r0.y, r1.y, r0.w + mov r5.xy, r3.xyxx + ushr r3.xyzw, r5.xyzw, l(16, 16, 16, 16) + ushr r5.xyzw, r3.xxyy, l(3, 11, 3, 11) + bfi r5.xyzw, l(1, 1, 1, 1), l(4, 4, 4, 4), r5.xyzw, l(0, 0, 0, 0) + ushr r6.xyzw, r3.xxyy, l(7, 15, 7, 15) + bfi r6.xyzw, l(1, 12, 1, 12), l(20, 20, 20, 20), r6.xyzw, l(0, 0, 0, 0) + iadd r5.xyzw, r5.xyzw, r6.xyzw + ushr r6.xyzw, r3.xxyy, l(2, 10, 2, 10) + bfi r5.xyzw, l(1, 1, 1, 1), l(8, 8, 8, 8), r6.xyzw, r5.xyzw + ushr r6.xyzw, r3.xxyy, l(6, 14, 6, 14) + bfi r6.xyzw, l(1, 1, 1, 1), l(24, 24, 24, 24), r6.xyzw, l(0, 0, 0, 0) + iadd r5.xyzw, r5.xyzw, r6.xyzw + ushr r6.xyzw, r3.xxyy, l(1, 9, 1, 9) + bfi r5.xyzw, l(1, 1, 1, 1), l(12, 12, 12, 12), r6.xyzw, r5.xyzw + ushr r6.xyzw, r3.xxyy, l(5, 13, 5, 13) + bfi r7.xyzw, l(1, 1, 1, 1), l(28, 28, 28, 28), r6.xyzw, l(0, 0, 0, 0) + iadd r7.xyzw, r5.xyzw, r7.xyzw + ushr r8.xyzw, r3.xzyw, l(8, 8, 8, 8) + mov r9.xz, r3.xxyx + mov r9.yw, r8.xxxz + bfi r7.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r9.xyzw, r7.xyzw + ushr r10.xyzw, r3.xxyy, l(4, 12, 4, 12) + bfi r7.xyzw, l(1, 1, 1, 1), l(16, 16, 16, 16), r10.xyzw, r7.xyzw + bfi r6.xyzw, l(1, 1, 1, 1), l(29, 29, 29, 29), r6.xyzw, l(0, 0, 0, 0) + imad r5.xyzw, r5.xyzw, l(2, 2, 2, 2), r6.xyzw + bfi r5.xyzw, l(1, 1, 1, 1), l(1, 1, 1, 1), r9.xyzw, r5.xyzw + bfi r5.xyzw, l(1, 1, 1, 1), l(17, 17, 17, 17), r10.xyzw, r5.xyzw + iadd r5.xyzw, r5.xyzw, r7.xyzw + ishl r6.xyzw, r5.xyzw, l(2, 2, 2, 2) + iadd r5.xyzw, r5.xyzw, r6.xyzw + store_uav_typed U0[0].xyzw, r0.yyyy, r5.xyzw + iadd r0.z, r0.y, l(1) + ushr r5.xyzw, r3.zzww, l(3, 11, 3, 11) + bfi r5.xyzw, l(1, 1, 1, 1), l(4, 4, 4, 4), r5.xyzw, l(0, 0, 0, 0) + ushr r6.xyzw, r3.zzww, l(7, 15, 7, 15) + bfi r6.xyzw, l(1, 12, 1, 12), l(20, 20, 20, 20), r6.xyzw, l(0, 0, 0, 0) + iadd r5.xyzw, r5.xyzw, r6.xyzw + ushr r6.xyzw, r3.zzww, l(2, 10, 2, 10) + bfi r5.xyzw, l(1, 1, 1, 1), l(8, 8, 8, 8), r6.xyzw, r5.xyzw + ushr r6.xyzw, r3.zzww, l(6, 14, 6, 14) + bfi r6.xyzw, l(1, 1, 1, 1), l(24, 24, 24, 24), r6.xyzw, l(0, 0, 0, 0) + iadd r5.xyzw, r5.xyzw, r6.xyzw + ushr r6.xyzw, r3.zzww, l(1, 9, 1, 9) + bfi r5.xyzw, l(1, 1, 1, 1), l(12, 12, 12, 12), r6.xyzw, r5.xyzw + ushr r6.xyzw, r3.zzww, l(5, 13, 5, 13) + bfi r7.xyzw, l(1, 1, 1, 1), l(28, 28, 28, 28), r6.xyzw, l(0, 0, 0, 0) + iadd r7.xyzw, r5.xyzw, r7.xyzw + mov r8.xz, r3.zzwz + bfi r7.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r8.xyzw, r7.xyzw + ushr r3.xyzw, r3.zzww, l(4, 12, 4, 12) + bfi r7.xyzw, l(1, 1, 1, 1), l(16, 16, 16, 16), r3.xyzw, r7.xyzw + bfi r6.xyzw, l(1, 1, 1, 1), l(29, 29, 29, 29), r6.xyzw, l(0, 0, 0, 0) + imad r5.xyzw, r5.xyzw, l(2, 2, 2, 2), r6.xyzw + bfi r5.xyzw, l(1, 1, 1, 1), l(1, 1, 1, 1), r8.xyzw, r5.xyzw + bfi r3.xyzw, l(1, 1, 1, 1), l(17, 17, 17, 17), r3.xyzw, r5.xyzw + iadd r3.xyzw, r3.xyzw, r7.xyzw + ishl r5.xyzw, r3.xyzw, l(2, 2, 2, 2) + iadd r3.xyzw, r3.xyzw, r5.xyzw + store_uav_typed U0[0].xyzw, r0.zzzz, r3.xyzw + iadd r0.x, r0.x, l(1) + ult r0.z, r0.x, CB0[0][2].y + if_nz r0.z + iadd r0.y, r1.y, r0.y + ushr r3.xyzw, r2.xxyy, l(3, 11, 3, 11) + bfi r3.xyzw, l(1, 1, 1, 1), l(4, 4, 4, 4), r3.xyzw, l(0, 0, 0, 0) + ushr r5.xyzw, r2.xxyy, l(7, 15, 7, 15) + bfi r5.xyzw, l(1, 1, 1, 1), l(20, 20, 20, 20), r5.xyzw, l(0, 0, 0, 0) + iadd r3.xyzw, r3.xyzw, r5.xyzw + ushr r5.xyzw, r2.xxyy, l(2, 10, 2, 10) + bfi r3.xyzw, l(1, 1, 1, 1), l(8, 8, 8, 8), r5.xyzw, r3.xyzw + ushr r5.xyzw, r2.xxyy, l(6, 14, 6, 14) + bfi r5.xyzw, l(1, 1, 1, 1), l(24, 24, 24, 24), r5.xyzw, l(0, 0, 0, 0) + iadd r3.xyzw, r3.xyzw, r5.xyzw + ushr r5.xyzw, r2.xxyy, l(1, 9, 1, 9) + bfi r3.xyzw, l(1, 1, 1, 1), l(12, 12, 12, 12), r5.xyzw, r3.xyzw + ushr r5.xyzw, r2.xxyy, l(5, 13, 5, 13) + bfi r6.xyzw, l(1, 1, 1, 1), l(28, 28, 28, 28), r5.xyzw, l(0, 0, 0, 0) + iadd r6.xyzw, r3.xyzw, r6.xyzw + ushr r2.zw, r2.xxxy, l(0, 0, 8, 8) + bfi r6.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r2.xzyw, r6.xyzw + ushr r7.xyzw, r2.xxyy, l(4, 12, 4, 12) + bfi r6.xyzw, l(1, 1, 1, 1), l(16, 16, 16, 16), r7.xyzw, r6.xyzw + bfi r5.xyzw, l(1, 1, 1, 1), l(29, 29, 29, 29), r5.xyzw, l(0, 0, 0, 0) + imad r3.xyzw, r3.xyzw, l(2, 2, 2, 2), r5.xyzw + bfi r3.xyzw, l(1, 1, 1, 1), l(1, 1, 1, 1), r2.xzyw, r3.xyzw + bfi r3.xyzw, l(1, 1, 1, 1), l(17, 17, 17, 17), r7.xyzw, r3.xyzw + iadd r3.xyzw, r3.xyzw, r6.xyzw + ishl r5.xyzw, r3.xyzw, l(2, 2, 2, 2) + iadd r3.xyzw, r3.xyzw, r5.xyzw + store_uav_typed U0[0].xyzw, r0.yyyy, r3.xyzw + iadd r0.z, r0.y, l(1) + ushr r3.xyzw, r4.zzww, l(3, 11, 3, 11) + bfi r3.xyzw, l(1, 1, 1, 1), l(4, 4, 4, 4), r3.xyzw, l(0, 0, 0, 0) + ushr r5.xyzw, r4.zzww, l(7, 15, 7, 15) + bfi r5.xyzw, l(1, 1, 1, 1), l(20, 20, 20, 20), r5.xyzw, l(0, 0, 0, 0) + iadd r3.xyzw, r3.xyzw, r5.xyzw + ushr r5.xyzw, r4.zzww, l(2, 10, 2, 10) + bfi r3.xyzw, l(1, 1, 1, 1), l(8, 8, 8, 8), r5.xyzw, r3.xyzw + ushr r5.xyzw, r4.zzww, l(6, 14, 6, 14) + bfi r5.xyzw, l(1, 1, 1, 1), l(24, 24, 24, 24), r5.xyzw, l(0, 0, 0, 0) + iadd r3.xyzw, r3.xyzw, r5.xyzw + ushr r5.xyzw, r4.zzww, l(1, 9, 1, 9) + bfi r3.xyzw, l(1, 1, 1, 1), l(12, 12, 12, 12), r5.xyzw, r3.xyzw + ushr r5.xyzw, r4.zzww, l(5, 13, 5, 13) + bfi r6.xyzw, l(1, 1, 1, 1), l(28, 28, 28, 28), r5.xyzw, l(0, 0, 0, 0) + iadd r6.xyzw, r3.xyzw, r6.xyzw + ushr r4.xy, r4.zwzz, l(8, 8, 0, 0) + bfi r6.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r4.zxwy, r6.xyzw + ushr r7.xyzw, r4.zzww, l(4, 12, 4, 12) + bfi r6.xyzw, l(1, 1, 1, 1), l(16, 16, 16, 16), r7.xyzw, r6.xyzw + bfi r5.xyzw, l(1, 1, 1, 1), l(29, 29, 29, 29), r5.xyzw, l(0, 0, 0, 0) + imad r3.xyzw, r3.xyzw, l(2, 2, 2, 2), r5.xyzw + bfi r3.xyzw, l(1, 1, 1, 1), l(1, 1, 1, 1), r4.zxwy, r3.xyzw + bfi r3.xyzw, l(1, 1, 1, 1), l(17, 17, 17, 17), r7.xyzw, r3.xyzw + iadd r3.xyzw, r3.xyzw, r6.xyzw + ishl r5.xyzw, r3.xyzw, l(2, 2, 2, 2) + iadd r3.xyzw, r3.xyzw, r5.xyzw + store_uav_typed U0[0].xyzw, r0.zzzz, r3.xyzw + or r0.x, r0.x, l(3) + ult r0.x, r0.x, CB0[0][2].y + if_nz r0.x + iadd r0.x, r1.y, r0.y + mov r4.xy, r2.xyxx + ushr r1.xyzw, r4.xyzw, l(16, 16, 16, 16) + ushr r2.xyzw, r1.xxyy, l(3, 11, 3, 11) + bfi r2.xyzw, l(1, 1, 1, 1), l(4, 4, 4, 4), r2.xyzw, l(0, 0, 0, 0) + ushr r3.xyzw, r1.xxyy, l(7, 15, 7, 15) + bfi r3.xyzw, l(1, 12, 1, 12), l(20, 20, 20, 20), r3.xyzw, l(0, 0, 0, 0) + iadd r2.xyzw, r2.xyzw, r3.xyzw + ushr r3.xyzw, r1.xxyy, l(2, 10, 2, 10) + bfi r2.xyzw, l(1, 1, 1, 1), l(8, 8, 8, 8), r3.xyzw, r2.xyzw + ushr r3.xyzw, r1.xxyy, l(6, 14, 6, 14) + bfi r3.xyzw, l(1, 1, 1, 1), l(24, 24, 24, 24), r3.xyzw, l(0, 0, 0, 0) + iadd r2.xyzw, r2.xyzw, r3.xyzw + ushr r3.xyzw, r1.xxyy, l(1, 9, 1, 9) + bfi r2.xyzw, l(1, 1, 1, 1), l(12, 12, 12, 12), r3.xyzw, r2.xyzw + ushr r3.xyzw, r1.xxyy, l(5, 13, 5, 13) + bfi r4.xyzw, l(1, 1, 1, 1), l(28, 28, 28, 28), r3.xyzw, l(0, 0, 0, 0) + iadd r4.xyzw, r2.xyzw, r4.xyzw + ushr r5.xyzw, r1.xzyw, l(8, 8, 8, 8) + mov r6.xz, r1.xxyx + mov r6.yw, r5.xxxz + bfi r4.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r6.xyzw, r4.xyzw + ushr r7.xyzw, r1.xxyy, l(4, 12, 4, 12) + bfi r4.xyzw, l(1, 1, 1, 1), l(16, 16, 16, 16), r7.xyzw, r4.xyzw + bfi r3.xyzw, l(1, 1, 1, 1), l(29, 29, 29, 29), r3.xyzw, l(0, 0, 0, 0) + imad r2.xyzw, r2.xyzw, l(2, 2, 2, 2), r3.xyzw + bfi r2.xyzw, l(1, 1, 1, 1), l(1, 1, 1, 1), r6.xyzw, r2.xyzw + bfi r2.xyzw, l(1, 1, 1, 1), l(17, 17, 17, 17), r7.xyzw, r2.xyzw + iadd r2.xyzw, r2.xyzw, r4.xyzw + ishl r3.xyzw, r2.xyzw, l(2, 2, 2, 2) + iadd r2.xyzw, r2.xyzw, r3.xyzw + store_uav_typed U0[0].xyzw, r0.xxxx, r2.xyzw + iadd r0.y, r0.x, l(1) + ushr r2.xyzw, r1.zzww, l(3, 11, 3, 11) + bfi r2.xyzw, l(1, 1, 1, 1), l(4, 4, 4, 4), r2.xyzw, l(0, 0, 0, 0) + ushr r3.xyzw, r1.zzww, l(7, 15, 7, 15) + bfi r3.xyzw, l(1, 12, 1, 12), l(20, 20, 20, 20), r3.xyzw, l(0, 0, 0, 0) + iadd r2.xyzw, r2.xyzw, r3.xyzw + ushr r3.xyzw, r1.zzww, l(2, 10, 2, 10) + bfi r2.xyzw, l(1, 1, 1, 1), l(8, 8, 8, 8), r3.xyzw, r2.xyzw + ushr r3.xyzw, r1.zzww, l(6, 14, 6, 14) + bfi r3.xyzw, l(1, 1, 1, 1), l(24, 24, 24, 24), r3.xyzw, l(0, 0, 0, 0) + iadd r2.xyzw, r2.xyzw, r3.xyzw + ushr r3.xyzw, r1.zzww, l(1, 9, 1, 9) + bfi r2.xyzw, l(1, 1, 1, 1), l(12, 12, 12, 12), r3.xyzw, r2.xyzw + ushr r3.xyzw, r1.zzww, l(5, 13, 5, 13) + bfi r4.xyzw, l(1, 1, 1, 1), l(28, 28, 28, 28), r3.xyzw, l(0, 0, 0, 0) + iadd r4.xyzw, r2.xyzw, r4.xyzw + mov r5.xz, r1.zzwz + bfi r4.xyzw, l(1, 1, 1, 1), l(0, 0, 0, 0), r5.xyzw, r4.xyzw + ushr r1.xyzw, r1.zzww, l(4, 12, 4, 12) + bfi r4.xyzw, l(1, 1, 1, 1), l(16, 16, 16, 16), r1.xyzw, r4.xyzw + bfi r3.xyzw, l(1, 1, 1, 1), l(29, 29, 29, 29), r3.xyzw, l(0, 0, 0, 0) + imad r2.xyzw, r2.xyzw, l(2, 2, 2, 2), r3.xyzw + bfi r2.xyzw, l(1, 1, 1, 1), l(1, 1, 1, 1), r5.xyzw, r2.xyzw + bfi r1.xyzw, l(1, 1, 1, 1), l(17, 17, 17, 17), r1.xyzw, r2.xyzw + iadd r1.xyzw, r1.xyzw, r4.xyzw + ishl r2.xyzw, r1.xyzw, l(2, 2, 2, 2) + iadd r1.xyzw, r1.xyzw, r2.xyzw + store_uav_typed U0[0].xyzw, r0.yyyy, r1.xyzw + endif + endif +endif +ret +// Approximately 352 instruction slots used +#endif + +const BYTE texture_load_dxt3aas1111_argb4_cs[] = { + 68, 88, 66, 67, 106, 21, 164, 106, 53, 203, 48, 103, 85, 234, 172, 94, 171, 31, 152, + 224, 1, 0, 0, 0, 24, 65, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 124, 64, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 64, 60, 0, + 0, 81, 0, 5, 0, 16, 15, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 11, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 35, 0, 0, 10, 34, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, + 11, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 30, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 85, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, + 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 150, 5, 2, + 0, 2, 64, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 1, 0, 0, 0, 246, 139, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 14, 146, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 2, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 48, + 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, + 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 19, 0, 0, 0, 19, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 14, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 35, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 50, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 138, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, + 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, + 0, 14, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, 2, 0, 42, 0, 0, + 9, 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 9, 66, + 0, 16, 0, 2, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, 82, 0, 16, 0, 2, + 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 2, 0, 0, + 0, 6, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 128, 3, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 64, + 0, 0, 10, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 10, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 98, + 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, + 17, 98, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, + 86, 6, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 0, 0, 0, 0, + 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 3, 0, 0, 0, + 35, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 150, 5, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, + 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, + 1, 18, 0, 0, 1, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 35, 0, 0, 9, 66, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 21, + 0, 0, 1, 30, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 85, 0, 0, 10, 162, 0, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 214, 120, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 10, 210, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 38, 7, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 38, 7, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, + 0, 0, 214, 8, 16, 0, 3, 0, 0, 0, 214, 8, 16, 0, 4, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 3, 0, 0, 0, 38, 7, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 214, 8, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 3, 0, + 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 50, + 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, + 55, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, + 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 4, 0, 0, 0, + 6, 0, 16, 0, 0, 0, 0, 0, 134, 125, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 134, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, + 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 134, 13, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, + 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 134, 13, 16, 0, 5, + 0, 0, 0, 134, 13, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, + 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 134, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 134, 13, 16, 0, 5, 0, + 0, 0, 54, 0, 0, 5, 194, 0, 16, 0, 5, 0, 0, 0, 6, 4, 16, 0, 4, + 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 194, 0, 16, 0, 5, 0, 0, 0, + 6, 4, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 10, 242, 0, 16, + 0, 6, 0, 0, 0, 6, 5, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 140, 0, 0, 20, 242, + 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 4, 0, 0, 0, 4, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 6, 5, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 15, 0, 0, + 0, 140, 0, 0, 20, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 20, + 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 7, 0, 0, 0, 6, 5, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 2, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 10, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, + 0, 6, 5, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 14, 0, + 0, 0, 6, 0, 0, 0, 14, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, + 0, 24, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, + 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 6, 5, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 9, 0, 0, 0, 1, 0, + 0, 0, 9, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, + 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 85, 0, + 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 6, 5, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, + 140, 0, 0, 20, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 28, 0, + 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 70, 14, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 85, 0, 0, 10, 194, 0, + 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 140, 0, 0, 17, + 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 13, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 8, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, + 6, 5, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 12, 0, 0, + 0, 4, 0, 0, 0, 12, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 8, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, + 0, 140, 0, 0, 20, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 29, + 0, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, + 0, 0, 0, 2, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 140, 0, 0, 17, + 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 134, 13, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 6, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 6, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, + 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 30, + 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 8, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 166, 15, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, + 0, 11, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 7, 0, + 0, 0, 166, 15, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 15, + 0, 0, 0, 7, 0, 0, 0, 15, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, + 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, + 0, 7, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 166, 15, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 10, 0, 0, 0, 2, + 0, 0, 0, 10, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 6, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 166, 15, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 6, 0, 0, 0, 14, 0, 0, 0, 6, 0, 0, 0, 14, 0, 0, + 0, 140, 0, 0, 20, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 24, + 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 7, 0, 0, 0, 166, 15, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 9, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 12, + 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, + 0, 166, 15, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 13, 0, + 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, + 0, 28, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, + 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, + 8, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 230, 10, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 38, 7, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 85, 0, + 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 166, 15, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, + 140, 0, 0, 17, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 9, + 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, + 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 29, 0, + 0, 0, 29, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, + 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 7, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 38, 7, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 17, 0, 0, 0, + 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, + 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 35, 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 2, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 79, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, + 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 6, 5, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 11, + 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, + 6, 5, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 15, 0, 0, + 0, 7, 0, 0, 0, 15, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 20, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 6, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 6, 5, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, + 0, 10, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 6, 0, 0, 0, 6, 5, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 6, 0, 0, 0, 14, 0, 0, 0, 6, 0, 0, 0, 14, 0, 0, 0, 140, + 0, 0, 20, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, + 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 70, 14, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, + 0, 6, 0, 0, 0, 6, 5, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 9, 0, 0, 0, 140, 0, 0, 17, 242, + 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 12, 0, 0, + 0, 12, 0, 0, 0, 12, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 6, + 5, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, + 5, 0, 0, 0, 13, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 7, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 7, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 7, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 134, 13, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 9, 0, 0, 0, 6, 1, 16, + 0, 3, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 9, 0, 0, 0, 6, 8, + 16, 0, 8, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 85, 0, + 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 6, 5, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, + 140, 0, 0, 17, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 10, + 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 29, 0, + 0, 0, 29, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 17, 0, 0, 0, + 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, + 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 166, 15, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 140, 0, 0, 20, + 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, + 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 166, 15, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 7, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 15, 0, + 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 2, 64, 0, 0, + 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 6, 0, 0, 0, 166, 15, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 10, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 6, 0, + 0, 0, 166, 15, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 14, + 0, 0, 0, 6, 0, 0, 0, 14, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, + 0, 0, 24, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 166, 15, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 9, 0, 0, 0, 1, + 0, 0, 0, 9, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, + 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 166, 15, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 13, 0, 0, + 0, 140, 0, 0, 20, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 28, + 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 54, 0, 0, 5, 82, + 0, 16, 0, 8, 0, 0, 0, 166, 11, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, + 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 7, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 166, 15, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 12, 0, 0, + 0, 4, 0, 0, 0, 12, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, + 0, 140, 0, 0, 20, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 29, + 0, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, + 0, 0, 0, 2, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 140, 0, 0, 17, + 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 30, + 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 7, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 79, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 6, 5, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, + 0, 11, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, + 0, 0, 6, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 15, + 0, 0, 0, 7, 0, 0, 0, 15, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 6, 5, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 10, 0, 0, 0, 2, + 0, 0, 0, 10, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 6, 5, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 6, 0, 0, 0, 14, 0, 0, 0, 6, 0, 0, 0, 14, 0, 0, + 0, 140, 0, 0, 20, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 24, + 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 5, 0, 0, 0, 6, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 9, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 12, + 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 6, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 13, 0, + 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 6, + 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, + 0, 28, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, + 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 134, 13, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 85, 0, + 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 6, 5, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, + 140, 0, 0, 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 7, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 29, 0, + 0, 0, 29, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 134, 13, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 17, 0, 0, 0, + 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, 0, + 16, 0, 3, 0, 0, 0, 166, 15, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 140, 0, 0, 20, + 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, + 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 166, 15, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 7, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 15, 0, + 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 166, 15, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 10, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, + 0, 0, 166, 15, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 14, + 0, 0, 0, 6, 0, 0, 0, 14, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, + 0, 0, 24, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 166, 15, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 9, 0, 0, 0, 1, + 0, 0, 0, 9, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 166, 15, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 13, 0, 0, + 0, 140, 0, 0, 20, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 28, + 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 85, 0, 0, 10, 50, + 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 7, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, + 0, 166, 15, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 12, 0, + 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 6, + 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, + 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 29, 0, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 2, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 38, 7, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, + 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 5, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, + 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, + 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 3, 0, 0, 0, 79, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, + 0, 2, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, + 6, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 11, 0, 0, + 0, 3, 0, 0, 0, 11, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, + 16, 0, 3, 0, 0, 0, 6, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 7, + 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 15, 0, 0, 0, 140, 0, 0, 20, + 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 12, 0, 0, + 0, 1, 0, 0, 0, 12, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, + 0, 0, 6, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 10, + 0, 0, 0, 2, 0, 0, 0, 10, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 6, 5, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 14, 0, 0, 0, 6, 0, 0, + 0, 14, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 6, 5, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 9, 0, 0, + 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 12, + 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 6, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 5, 0, + 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, 140, 0, 0, 20, 242, + 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 28, 0, 0, 0, 28, 0, 0, + 0, 28, 0, 0, 0, 28, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 134, 13, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 6, + 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, + 6, 0, 0, 0, 6, 8, 16, 0, 5, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 6, 5, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, 4, 0, + 0, 0, 12, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 140, 0, + 0, 20, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 29, 0, 0, 0, + 29, 0, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 70, + 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, + 0, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 164, 0, 0, + 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 166, 15, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 11, 0, + 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 166, + 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 15, 0, 0, 0, + 7, 0, 0, 0, 15, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 166, 15, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, + 10, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 3, 0, 0, 0, 166, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 6, 0, 0, 0, 14, 0, 0, 0, 6, 0, 0, 0, 14, 0, 0, 0, 140, 0, + 0, 20, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, + 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, + 3, 0, 0, 0, 166, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 9, 0, 0, 0, 1, 0, 0, 0, 9, 0, 0, 0, 140, 0, 0, 17, 242, 0, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, + 12, 0, 0, 0, 12, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 166, 15, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, 5, + 0, 0, 0, 13, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 54, 0, 0, 5, 82, 0, 16, 0, 5, 0, 0, 0, 166, 11, 16, 0, 1, 0, + 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 242, 0, + 16, 0, 1, 0, 0, 0, 166, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 4, + 0, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, 140, 0, 0, 17, + 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 29, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, + 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 17, 242, 0, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, + 17, 0, 0, 0, 17, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, + 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, + 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, + 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 62, 0, 0, 1, 83, 84, 65, + 84, 148, 0, 0, 0, 96, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 89, 0, 0, 0, 6, 0, 0, 0, 10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 13, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, + 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt3aas1111_bgra4_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt3aas1111_bgra4_cs.h new file mode 100644 index 0000000..d141d3c --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt3aas1111_bgra4_cs.h @@ -0,0 +1,1203 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 10 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(2) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r1.yz, r1.xxyx, l(0, 2, 2, 0) +ishl r0.w, r1.y, l(1) +imad r1.y, vThreadID.z, CB0[0][2].y, r1.z +imad r0.w, r1.y, CB0[0][2].x, r0.w +iadd r0.w, r0.w, CB0[0][1].w +ushr r1.y, CB0[0][2].x, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r2.xw, l(27, 0, 0, 29), l(3, 0, 0, 1), vThreadID.xxxx + imad r0.y, r0.y, r1.w, r2.x + ishl r1.z, vThreadID.y, l(11) + and r1.z, r1.z, l(0x00003000) + bfi r1.z, l(3), l(9), r1.x, r1.z + ishr r1.z, r1.z, l(6) + iadd r1.w, r2.y, r2.z + bfi r2.x, l(1), l(1), r1.w, l(0) + iadd r2.x, r2.x, r2.w + bfi r2.x, l(2), l(1), r2.x, l(0) + bfi r1.w, l(1), l(0), r1.w, r2.x + bfi r2.xy, l(19, 19, 0, 0), l(11, 14, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(9, 12, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(6) + bfi r1.w, l(1), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(6, 6, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r2.z, CB0[0][0].z, l(5) + imad r1.z, r2.x, r2.z, r1.z + ishl r2.xz, vThreadID.yyyy, l(6, 0, 7, 0) + and r2.xz, r2.xxzx, l(896, 0, 2048, 0) + bfi r2.w, l(3), l(4), r1.x, r2.x + bfi r2.w, l(22), l(10), r1.z, r2.w + bfi r3.x, l(1), l(4), vThreadID.y, l(0) + iadd r2.w, r2.w, r3.x + ishl r3.yz, r2.xxxx, l(0, 3, 2, 0) + bfi r3.yz, l(0, 3, 3, 0), l(0, 7, 6, 0), r1.xxxx, r3.yyzy + bfi r3.yz, l(0, 22, 22, 0), l(0, 13, 12, 0), r1.zzzz, r3.yyzy + imad r3.xy, r3.xxxx, l(8, 4, 0, 0), r3.yzyy + bfi r1.z, l(12), l(0), r2.z, r3.x + and r2.x, r3.y, l(1792) + iadd r1.z, r1.z, r2.x + and r2.x, r2.y, l(2) + iadd r1.w, r1.w, r2.x + bfi r1.w, l(2), l(6), r1.w, l(0) + iadd r1.z, r1.z, r1.w + bfi r0.y, l(6), l(0), r2.w, r1.z + endif +else + ishl r1.x, r1.x, l(3) + imad r1.z, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.z, CB0[0][0].z, r1.x +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.yw, r0.yyyw, l(0, 4, 0, 4) +ld r2.xyzw, r0.yyyy, T0[0].ywxz +ieq r1.xzw, r0.zzzz, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r3.xyzw, r2.zxwy, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.zxwy, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.ywxz, r4.ywxz +endif +if_nz r1.z + ushr r3.xyzw, r2.zxwy, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.ywxz + mov r3.xy, r2.zwzz +else + mov r3.xy, r2.zwzz +endif +movc r0.x, r0.x, l(2), l(1) +iadd r0.x, r0.x, r0.y +ld r4.xyzw, r0.xxxx, T0[0].xzyw +if_nz r1.x + ishl r5.xyzw, r4.xzyw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r6.xyzw, r4.xzyw, l(8, 8, 8, 8) + and r6.xyzw, r6.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r4.xyzw, r5.xzyw, r6.xzyw +endif +if_nz r1.z + ushr r5.xyzw, r4.xzyw, l(16, 16, 16, 16) + bfi r4.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r4.xyzw, r5.xzyw + mov r5.zw, r4.xxxy +else + mov r5.zw, r4.xxxy +endif +ushr r6.xyzw, r3.xxyy, l(3, 11, 3, 11) +bfi r6.xyzw, l(1, 1, 1, 1), l(8, 8, 8, 8), r6.xyzw, l(0, 0, 0, 0) +ushr r7.xyzw, r3.xxyy, l(7, 15, 7, 15) +bfi r7.xyzw, l(1, 1, 1, 1), l(24, 24, 24, 24), r7.xyzw, l(0, 0, 0, 0) +iadd r6.xyzw, r6.xyzw, r7.xyzw +ushr r7.xyzw, r3.xxyy, l(2, 10, 2, 10) +bfi r7.xyzw, l(1, 1, 1, 1), l(4, 4, 4, 4), r7.xyzw, l(0, 0, 0, 0) +iadd r6.xyzw, r6.xyzw, r7.xyzw +ushr r7.xyzw, r3.xxyy, l(6, 14, 6, 14) +bfi r6.xyzw, l(1, 1, 1, 1), l(20, 20, 20, 20), r7.xyzw, r6.xyzw +ubfe r7.xyzw, l(1, 1, 1, 1), l(1, 9, 1, 9), r3.xxyy +iadd r6.xyzw, r6.xyzw, r7.xyzw +ushr r7.xyzw, r3.xxyy, l(5, 13, 5, 13) +bfi r6.xyzw, l(1, 1, 1, 1), l(16, 16, 16, 16), r7.xyzw, r6.xyzw +ushr r3.zw, r3.xxxy, l(0, 0, 8, 8) +bfi r6.xyzw, l(1, 1, 1, 1), l(12, 12, 12, 12), r3.xzyw, r6.xyzw +ushr r7.xyzw, r3.xxyy, l(4, 12, 4, 12) +bfi r8.xyzw, l(1, 1, 1, 1), l(28, 28, 28, 28), r7.xyzw, l(0, 0, 0, 0) +iadd r8.xyzw, r6.xyzw, r8.xyzw +bfi r7.xyzw, l(1, 1, 1, 1), l(29, 29, 29, 29), r7.xyzw, l(0, 0, 0, 0) +imad r6.xyzw, r6.xyzw, l(2, 2, 2, 2), r7.xyzw +iadd r6.xyzw, r6.xyzw, r8.xyzw +ishl r7.xyzw, r6.xyzw, l(2, 2, 2, 2) +iadd r6.xyzw, r6.xyzw, r7.xyzw +store_uav_typed U0[0].xyzw, r0.wwww, r6.xyzw +iadd r0.x, r0.w, l(1) +ushr r6.xyzw, r5.zzww, l(3, 11, 3, 11) +bfi r6.xyzw, l(1, 1, 1, 1), l(8, 8, 8, 8), r6.xyzw, l(0, 0, 0, 0) +ushr r7.xyzw, r5.zzww, l(7, 15, 7, 15) +bfi r7.xyzw, l(1, 1, 1, 1), l(24, 24, 24, 24), r7.xyzw, l(0, 0, 0, 0) +iadd r6.xyzw, r6.xyzw, r7.xyzw +ushr r7.xyzw, r5.zzww, l(2, 10, 2, 10) +bfi r7.xyzw, l(1, 1, 1, 1), l(4, 4, 4, 4), r7.xyzw, l(0, 0, 0, 0) +iadd r6.xyzw, r6.xyzw, r7.xyzw +ushr r7.xyzw, r5.zzww, l(6, 14, 6, 14) +bfi r6.xyzw, l(1, 1, 1, 1), l(20, 20, 20, 20), r7.xyzw, r6.xyzw +ubfe r7.xyzw, l(1, 1, 1, 1), l(1, 9, 1, 9), r5.zzww +iadd r6.xyzw, r6.xyzw, r7.xyzw +ushr r7.xyzw, r5.zzww, l(5, 13, 5, 13) +bfi r6.xyzw, l(1, 1, 1, 1), l(16, 16, 16, 16), r7.xyzw, r6.xyzw +ushr r5.xy, r5.zwzz, l(8, 8, 0, 0) +bfi r6.xyzw, l(1, 1, 1, 1), l(12, 12, 12, 12), r5.zxwy, r6.xyzw +ushr r7.xyzw, r5.zzww, l(4, 12, 4, 12) +bfi r8.xyzw, l(1, 1, 1, 1), l(28, 28, 28, 28), r7.xyzw, l(0, 0, 0, 0) +iadd r8.xyzw, r6.xyzw, r8.xyzw +bfi r7.xyzw, l(1, 1, 1, 1), l(29, 29, 29, 29), r7.xyzw, l(0, 0, 0, 0) +imad r6.xyzw, r6.xyzw, l(2, 2, 2, 2), r7.xyzw +iadd r6.xyzw, r6.xyzw, r8.xyzw +ishl r7.xyzw, r6.xyzw, l(2, 2, 2, 2) +iadd r6.xyzw, r6.xyzw, r7.xyzw +store_uav_typed U0[0].xyzw, r0.xxxx, r6.xyzw +imad r0.x, vThreadID.y, l(4), l(1) +ult r0.y, r0.x, CB0[0][2].y +if_nz r0.y + iadd r0.y, r1.y, r0.w + mov r5.xy, r3.xyxx + ushr r6.xyzw, r5.xyzw, l(16, 16, 16, 16) + ushr r7.xyzw, r6.xxyy, l(3, 11, 3, 11) + bfi r7.xyzw, l(1, 1, 1, 1), l(8, 8, 8, 8), r7.xyzw, l(0, 0, 0, 0) + ushr r8.xyzw, r6.xxyy, l(7, 15, 7, 15) + bfi r8.xyzw, l(1, 8, 1, 8), l(24, 24, 24, 24), r8.xyzw, l(0, 0, 0, 0) + iadd r7.xyzw, r7.xyzw, r8.xyzw + ushr r8.xyzw, r6.xxyy, l(2, 10, 2, 10) + bfi r8.xyzw, l(1, 1, 1, 1), l(4, 4, 4, 4), r8.xyzw, l(0, 0, 0, 0) + iadd r7.xyzw, r7.xyzw, r8.xyzw + ushr r8.xyzw, r6.xxyy, l(6, 14, 6, 14) + bfi r7.xyzw, l(1, 1, 1, 1), l(20, 20, 20, 20), r8.xyzw, r7.xyzw + ubfe r3.xyzw, l(1, 1, 1, 1), l(17, 25, 17, 25), r3.xxyy + iadd r3.xyzw, r7.xyzw, r3.xyzw + ushr r7.xyzw, r6.xxyy, l(5, 13, 5, 13) + bfi r3.xyzw, l(1, 1, 1, 1), l(16, 16, 16, 16), r7.xyzw, r3.xyzw + ushr r7.xyzw, r6.xzyw, l(8, 8, 8, 8) + mov r8.xz, r6.xxyx + mov r8.yw, r7.xxxz + bfi r3.xyzw, l(1, 1, 1, 1), l(12, 12, 12, 12), r8.xyzw, r3.xyzw + ushr r8.xyzw, r6.xxyy, l(4, 12, 4, 12) + bfi r9.xyzw, l(1, 1, 1, 1), l(28, 28, 28, 28), r8.xyzw, l(0, 0, 0, 0) + iadd r9.xyzw, r3.xyzw, r9.xyzw + bfi r8.xyzw, l(1, 1, 1, 1), l(29, 29, 29, 29), r8.xyzw, l(0, 0, 0, 0) + imad r3.xyzw, r3.xyzw, l(2, 2, 2, 2), r8.xyzw + iadd r3.xyzw, r3.xyzw, r9.xyzw + ishl r8.xyzw, r3.xyzw, l(2, 2, 2, 2) + iadd r3.xyzw, r3.xyzw, r8.xyzw + store_uav_typed U0[0].xyzw, r0.yyyy, r3.xyzw + iadd r0.z, r0.y, l(1) + ushr r3.xyzw, r6.zzww, l(3, 11, 3, 11) + bfi r3.xyzw, l(1, 1, 1, 1), l(8, 8, 8, 8), r3.xyzw, l(0, 0, 0, 0) + ushr r8.xyzw, r6.zzww, l(7, 15, 7, 15) + bfi r8.xyzw, l(1, 8, 1, 8), l(24, 24, 24, 24), r8.xyzw, l(0, 0, 0, 0) + iadd r3.xyzw, r3.xyzw, r8.xyzw + ushr r8.xyzw, r6.zzww, l(2, 10, 2, 10) + bfi r8.xyzw, l(1, 1, 1, 1), l(4, 4, 4, 4), r8.xyzw, l(0, 0, 0, 0) + iadd r3.xyzw, r3.xyzw, r8.xyzw + ushr r8.xyzw, r6.zzww, l(6, 14, 6, 14) + bfi r3.xyzw, l(1, 1, 1, 1), l(20, 20, 20, 20), r8.xyzw, r3.xyzw + ubfe r5.xyzw, l(1, 1, 1, 1), l(17, 25, 17, 25), r5.zzww + iadd r3.xyzw, r3.xyzw, r5.xyzw + ushr r5.xyzw, r6.zzww, l(5, 13, 5, 13) + bfi r3.xyzw, l(1, 1, 1, 1), l(16, 16, 16, 16), r5.xyzw, r3.xyzw + mov r7.xz, r6.zzwz + bfi r3.xyzw, l(1, 1, 1, 1), l(12, 12, 12, 12), r7.xyzw, r3.xyzw + ushr r5.xyzw, r6.zzww, l(4, 12, 4, 12) + bfi r6.xyzw, l(1, 1, 1, 1), l(28, 28, 28, 28), r5.xyzw, l(0, 0, 0, 0) + iadd r6.xyzw, r3.xyzw, r6.xyzw + bfi r5.xyzw, l(1, 1, 1, 1), l(29, 29, 29, 29), r5.xyzw, l(0, 0, 0, 0) + imad r3.xyzw, r3.xyzw, l(2, 2, 2, 2), r5.xyzw + iadd r3.xyzw, r3.xyzw, r6.xyzw + ishl r5.xyzw, r3.xyzw, l(2, 2, 2, 2) + iadd r3.xyzw, r3.xyzw, r5.xyzw + store_uav_typed U0[0].xyzw, r0.zzzz, r3.xyzw + iadd r0.x, r0.x, l(1) + ult r0.z, r0.x, CB0[0][2].y + if_nz r0.z + iadd r0.y, r1.y, r0.y + ushr r3.xyzw, r2.xxyy, l(3, 11, 3, 11) + bfi r3.xyzw, l(1, 1, 1, 1), l(8, 8, 8, 8), r3.xyzw, l(0, 0, 0, 0) + ushr r5.xyzw, r2.xxyy, l(7, 15, 7, 15) + bfi r5.xyzw, l(1, 1, 1, 1), l(24, 24, 24, 24), r5.xyzw, l(0, 0, 0, 0) + iadd r3.xyzw, r3.xyzw, r5.xyzw + ushr r5.xyzw, r2.xxyy, l(2, 10, 2, 10) + bfi r5.xyzw, l(1, 1, 1, 1), l(4, 4, 4, 4), r5.xyzw, l(0, 0, 0, 0) + iadd r3.xyzw, r3.xyzw, r5.xyzw + ushr r5.xyzw, r2.xxyy, l(6, 14, 6, 14) + bfi r3.xyzw, l(1, 1, 1, 1), l(20, 20, 20, 20), r5.xyzw, r3.xyzw + ubfe r5.xyzw, l(1, 1, 1, 1), l(1, 9, 1, 9), r2.xxyy + iadd r3.xyzw, r3.xyzw, r5.xyzw + ushr r5.xyzw, r2.xxyy, l(5, 13, 5, 13) + bfi r3.xyzw, l(1, 1, 1, 1), l(16, 16, 16, 16), r5.xyzw, r3.xyzw + ushr r2.zw, r2.xxxy, l(0, 0, 8, 8) + bfi r3.xyzw, l(1, 1, 1, 1), l(12, 12, 12, 12), r2.xzyw, r3.xyzw + ushr r5.xyzw, r2.xxyy, l(4, 12, 4, 12) + bfi r6.xyzw, l(1, 1, 1, 1), l(28, 28, 28, 28), r5.xyzw, l(0, 0, 0, 0) + iadd r6.xyzw, r3.xyzw, r6.xyzw + bfi r5.xyzw, l(1, 1, 1, 1), l(29, 29, 29, 29), r5.xyzw, l(0, 0, 0, 0) + imad r3.xyzw, r3.xyzw, l(2, 2, 2, 2), r5.xyzw + iadd r3.xyzw, r3.xyzw, r6.xyzw + ishl r5.xyzw, r3.xyzw, l(2, 2, 2, 2) + iadd r3.xyzw, r3.xyzw, r5.xyzw + store_uav_typed U0[0].xyzw, r0.yyyy, r3.xyzw + iadd r0.z, r0.y, l(1) + ushr r3.xyzw, r4.zzww, l(3, 11, 3, 11) + bfi r3.xyzw, l(1, 1, 1, 1), l(8, 8, 8, 8), r3.xyzw, l(0, 0, 0, 0) + ushr r5.xyzw, r4.zzww, l(7, 15, 7, 15) + bfi r5.xyzw, l(1, 1, 1, 1), l(24, 24, 24, 24), r5.xyzw, l(0, 0, 0, 0) + iadd r3.xyzw, r3.xyzw, r5.xyzw + ushr r5.xyzw, r4.zzww, l(2, 10, 2, 10) + bfi r5.xyzw, l(1, 1, 1, 1), l(4, 4, 4, 4), r5.xyzw, l(0, 0, 0, 0) + iadd r3.xyzw, r3.xyzw, r5.xyzw + ushr r5.xyzw, r4.zzww, l(6, 14, 6, 14) + bfi r3.xyzw, l(1, 1, 1, 1), l(20, 20, 20, 20), r5.xyzw, r3.xyzw + ubfe r5.xyzw, l(1, 1, 1, 1), l(1, 9, 1, 9), r4.zzww + iadd r3.xyzw, r3.xyzw, r5.xyzw + ushr r5.xyzw, r4.zzww, l(5, 13, 5, 13) + bfi r3.xyzw, l(1, 1, 1, 1), l(16, 16, 16, 16), r5.xyzw, r3.xyzw + ushr r4.xy, r4.zwzz, l(8, 8, 0, 0) + bfi r3.xyzw, l(1, 1, 1, 1), l(12, 12, 12, 12), r4.zxwy, r3.xyzw + ushr r5.xyzw, r4.zzww, l(4, 12, 4, 12) + bfi r6.xyzw, l(1, 1, 1, 1), l(28, 28, 28, 28), r5.xyzw, l(0, 0, 0, 0) + iadd r6.xyzw, r3.xyzw, r6.xyzw + bfi r5.xyzw, l(1, 1, 1, 1), l(29, 29, 29, 29), r5.xyzw, l(0, 0, 0, 0) + imad r3.xyzw, r3.xyzw, l(2, 2, 2, 2), r5.xyzw + iadd r3.xyzw, r3.xyzw, r6.xyzw + ishl r5.xyzw, r3.xyzw, l(2, 2, 2, 2) + iadd r3.xyzw, r3.xyzw, r5.xyzw + store_uav_typed U0[0].xyzw, r0.zzzz, r3.xyzw + or r0.x, r0.x, l(3) + ult r0.x, r0.x, CB0[0][2].y + if_nz r0.x + iadd r0.x, r1.y, r0.y + mov r4.xy, r2.xyxx + ushr r1.xyzw, r4.xyzw, l(16, 16, 16, 16) + ushr r3.xyzw, r1.xxyy, l(3, 11, 3, 11) + bfi r3.xyzw, l(1, 1, 1, 1), l(8, 8, 8, 8), r3.xyzw, l(0, 0, 0, 0) + ushr r5.xyzw, r1.xxyy, l(7, 15, 7, 15) + bfi r5.xyzw, l(1, 8, 1, 8), l(24, 24, 24, 24), r5.xyzw, l(0, 0, 0, 0) + iadd r3.xyzw, r3.xyzw, r5.xyzw + ushr r5.xyzw, r1.xxyy, l(2, 10, 2, 10) + bfi r5.xyzw, l(1, 1, 1, 1), l(4, 4, 4, 4), r5.xyzw, l(0, 0, 0, 0) + iadd r3.xyzw, r3.xyzw, r5.xyzw + ushr r5.xyzw, r1.xxyy, l(6, 14, 6, 14) + bfi r3.xyzw, l(1, 1, 1, 1), l(20, 20, 20, 20), r5.xyzw, r3.xyzw + ubfe r2.xyzw, l(1, 1, 1, 1), l(17, 25, 17, 25), r2.xxyy + iadd r2.xyzw, r3.xyzw, r2.xyzw + ushr r3.xyzw, r1.xxyy, l(5, 13, 5, 13) + bfi r2.xyzw, l(1, 1, 1, 1), l(16, 16, 16, 16), r3.xyzw, r2.xyzw + ushr r3.xyzw, r1.xzyw, l(8, 8, 8, 8) + mov r5.xz, r1.xxyx + mov r5.yw, r3.xxxz + bfi r2.xyzw, l(1, 1, 1, 1), l(12, 12, 12, 12), r5.xyzw, r2.xyzw + ushr r5.xyzw, r1.xxyy, l(4, 12, 4, 12) + bfi r6.xyzw, l(1, 1, 1, 1), l(28, 28, 28, 28), r5.xyzw, l(0, 0, 0, 0) + iadd r6.xyzw, r2.xyzw, r6.xyzw + bfi r5.xyzw, l(1, 1, 1, 1), l(29, 29, 29, 29), r5.xyzw, l(0, 0, 0, 0) + imad r2.xyzw, r2.xyzw, l(2, 2, 2, 2), r5.xyzw + iadd r2.xyzw, r2.xyzw, r6.xyzw + ishl r5.xyzw, r2.xyzw, l(2, 2, 2, 2) + iadd r2.xyzw, r2.xyzw, r5.xyzw + store_uav_typed U0[0].xyzw, r0.xxxx, r2.xyzw + iadd r0.y, r0.x, l(1) + ushr r2.xyzw, r1.zzww, l(3, 11, 3, 11) + bfi r2.xyzw, l(1, 1, 1, 1), l(8, 8, 8, 8), r2.xyzw, l(0, 0, 0, 0) + ushr r5.xyzw, r1.zzww, l(7, 15, 7, 15) + bfi r5.xyzw, l(1, 8, 1, 8), l(24, 24, 24, 24), r5.xyzw, l(0, 0, 0, 0) + iadd r2.xyzw, r2.xyzw, r5.xyzw + ushr r5.xyzw, r1.zzww, l(2, 10, 2, 10) + bfi r5.xyzw, l(1, 1, 1, 1), l(4, 4, 4, 4), r5.xyzw, l(0, 0, 0, 0) + iadd r2.xyzw, r2.xyzw, r5.xyzw + ushr r5.xyzw, r1.zzww, l(6, 14, 6, 14) + bfi r2.xyzw, l(1, 1, 1, 1), l(20, 20, 20, 20), r5.xyzw, r2.xyzw + ubfe r4.xyzw, l(1, 1, 1, 1), l(17, 25, 17, 25), r4.zzww + iadd r2.xyzw, r2.xyzw, r4.xyzw + ushr r4.xyzw, r1.zzww, l(5, 13, 5, 13) + bfi r2.xyzw, l(1, 1, 1, 1), l(16, 16, 16, 16), r4.xyzw, r2.xyzw + mov r3.xz, r1.zzwz + bfi r2.xyzw, l(1, 1, 1, 1), l(12, 12, 12, 12), r3.xyzw, r2.xyzw + ushr r1.xyzw, r1.zzww, l(4, 12, 4, 12) + bfi r3.xyzw, l(1, 1, 1, 1), l(28, 28, 28, 28), r1.xyzw, l(0, 0, 0, 0) + iadd r3.xyzw, r2.xyzw, r3.xyzw + bfi r1.xyzw, l(1, 1, 1, 1), l(29, 29, 29, 29), r1.xyzw, l(0, 0, 0, 0) + imad r1.xyzw, r2.xyzw, l(2, 2, 2, 2), r1.xyzw + iadd r1.xyzw, r1.xyzw, r3.xyzw + ishl r2.xyzw, r1.xyzw, l(2, 2, 2, 2) + iadd r1.xyzw, r1.xyzw, r2.xyzw + store_uav_typed U0[0].xyzw, r0.yyyy, r1.xyzw + endif + endif +endif +ret +// Approximately 336 instruction slots used +#endif + +const BYTE texture_load_dxt3aas1111_bgra4_cs[] = { + 68, 88, 66, 67, 14, 66, 192, 176, 67, 14, 85, 193, 165, 146, 201, 199, 79, 92, 136, + 38, 1, 0, 0, 0, 56, 60, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 156, 59, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 96, 55, 0, + 0, 81, 0, 5, 0, 216, 13, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 10, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 35, 0, 0, 10, 34, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, + 11, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 30, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 85, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, + 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 150, 5, 2, + 0, 2, 64, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 1, 0, 0, 0, 246, 139, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 14, 146, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 2, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 48, + 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, + 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 19, 0, 0, 0, 19, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 14, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 35, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 50, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 138, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, + 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, + 0, 14, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, 2, 0, 42, 0, 0, + 9, 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 9, 66, + 0, 16, 0, 2, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, 82, 0, 16, 0, 2, + 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 2, 0, 0, + 0, 6, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 128, 3, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 64, + 0, 0, 10, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 10, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 98, + 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, + 17, 98, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, + 86, 6, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 0, 0, 0, 0, + 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 3, 0, 0, 0, + 35, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 150, 5, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, + 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, + 1, 18, 0, 0, 1, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 35, 0, 0, 9, 66, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 21, + 0, 0, 1, 30, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 85, 0, 0, 10, 162, 0, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 214, 120, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 10, 210, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 38, 7, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 38, 7, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, + 0, 0, 214, 8, 16, 0, 3, 0, 0, 0, 214, 8, 16, 0, 4, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 3, 0, 0, 0, 38, 7, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 214, 8, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 3, 0, + 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 50, + 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, + 55, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, + 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 4, 0, 0, 0, + 6, 0, 16, 0, 0, 0, 0, 0, 134, 125, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 134, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, + 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 134, 13, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, + 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 134, 13, 16, 0, 5, + 0, 0, 0, 134, 13, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, + 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 134, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 134, 13, 16, 0, 5, 0, + 0, 0, 54, 0, 0, 5, 194, 0, 16, 0, 5, 0, 0, 0, 6, 4, 16, 0, 4, + 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 194, 0, 16, 0, 5, 0, 0, 0, + 6, 4, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 10, 242, 0, 16, + 0, 6, 0, 0, 0, 6, 5, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 140, 0, 0, 20, 242, + 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 6, 5, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 15, 0, 0, + 0, 140, 0, 0, 20, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 24, + 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 7, 0, 0, 0, 6, 5, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 2, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 10, 0, 0, 0, 140, 0, 0, + 20, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 7, + 0, 0, 0, 6, 5, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, + 14, 0, 0, 0, 6, 0, 0, 0, 14, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, + 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, + 0, 0, 0, 20, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 9, 0, 0, 0, 6, + 5, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 7, 0, 0, 0, 6, 5, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, 140, + 0, 0, 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 3, + 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, + 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, + 0, 0, 0, 12, 0, 0, 0, 134, 13, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 6, 5, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, 4, 0, + 0, 0, 12, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, + 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 8, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, + 140, 0, 0, 20, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 29, 0, + 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 70, 14, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 242, + 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, + 8, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, + 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 164, 0, 0, 8, + 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 166, 15, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, + 0, 140, 0, 0, 20, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 166, 15, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 15, 0, 0, 0, 7, + 0, 0, 0, 15, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 166, 15, 16, 0, 5, 0, + 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 10, + 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 7, 0, 0, 0, 166, 15, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 6, 0, 0, 0, 14, 0, 0, 0, 6, 0, 0, 0, 14, 0, 0, 0, 140, + 0, 0, 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, + 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 70, 14, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 7, + 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, + 0, 9, 0, 0, 0, 166, 15, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 242, 0, + 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 166, 15, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, + 0, 13, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 85, 0, 0, + 10, 50, 0, 16, 0, 5, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, + 0, 0, 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, + 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 38, 7, 16, 0, 5, 0, + 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 7, + 0, 0, 0, 166, 15, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, + 12, 0, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, + 0, 0, 0, 28, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, + 16, 0, 8, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 29, 0, 0, + 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 6, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 7, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, + 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 35, 0, 0, 8, + 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 79, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 5, 0, + 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 6, + 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, + 0, 7, 0, 0, 0, 6, 5, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 140, 0, 0, 20, 242, + 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 6, 5, 16, 0, 6, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 15, 0, 0, + 0, 140, 0, 0, 20, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 24, + 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 70, 14, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, + 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 8, 0, 0, 0, 6, 5, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, + 2, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 10, 0, 0, 0, 140, 0, 0, + 20, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 8, + 0, 0, 0, 6, 5, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, + 14, 0, 0, 0, 6, 0, 0, 0, 14, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, + 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, + 0, 0, 0, 20, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 17, 0, 0, 0, 25, 0, 0, 0, 17, 0, 0, 0, 25, 0, 0, 0, 6, + 5, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 7, 0, 0, 0, 6, 5, 16, 0, 6, 0, 0, 0, 2, 64, + 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, 140, + 0, 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 7, + 0, 0, 0, 134, 13, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, + 0, 8, 0, 0, 0, 6, 1, 16, 0, 6, 0, 0, 0, 54, 0, 0, 5, 162, 0, + 16, 0, 8, 0, 0, 0, 6, 8, 16, 0, 7, 0, 0, 0, 140, 0, 0, 17, 242, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 12, 0, 0, + 0, 12, 0, 0, 0, 12, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 6, + 5, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, + 4, 0, 0, 0, 12, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 9, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, + 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 9, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 9, 0, + 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 29, 0, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 70, 14, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 2, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 164, 0, + 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 166, 15, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 11, + 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, + 166, 15, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 15, 0, 0, + 0, 7, 0, 0, 0, 15, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 8, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, + 24, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 8, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 166, 15, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, + 0, 10, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 166, 15, 16, 0, 6, 0, 0, 0, + 2, 64, 0, 0, 6, 0, 0, 0, 14, 0, 0, 0, 6, 0, 0, 0, 14, 0, 0, + 0, 140, 0, 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 20, + 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 70, 14, 16, 0, + 8, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 17, 0, 0, 0, 25, 0, 0, 0, 17, + 0, 0, 0, 25, 0, 0, 0, 166, 15, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 166, 15, + 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, 5, + 0, 0, 0, 13, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 54, + 0, 0, 5, 82, 0, 16, 0, 7, 0, 0, 0, 166, 11, 16, 0, 6, 0, 0, 0, + 140, 0, 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 12, 0, + 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 70, 14, 16, 0, 7, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, + 5, 0, 0, 0, 166, 15, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, + 0, 12, 0, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, 140, 0, 0, 20, 242, 0, + 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, + 28, 0, 0, 0, 28, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 6, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 29, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, + 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 70, 14, 16, 0, 5, 0, + 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, + 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, + 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 242, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 166, 10, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, + 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 79, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 6, + 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, + 3, 0, 0, 0, 11, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, + 0, 5, 0, 0, 0, 6, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 7, 0, + 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 15, 0, 0, 0, 140, 0, 0, 20, 242, + 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, 24, 0, 0, + 0, 24, 0, 0, 0, 24, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 6, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 10, 0, + 0, 0, 2, 0, 0, 0, 10, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 6, 5, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 14, 0, 0, 0, 6, 0, + 0, 0, 14, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 138, 0, + 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 9, 0, 0, 0, 1, 0, 0, 0, 9, 0, 0, 0, 6, 5, 16, 0, 2, 0, 0, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, + 0, 0, 0, 6, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, + 13, 0, 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, + 0, 134, 13, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 85, 0, + 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 6, 5, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, + 140, 0, 0, 20, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 28, 0, + 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 140, 0, 0, 20, 242, 0, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, + 29, 0, 0, 0, 29, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, + 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 41, 0, + 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, + 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 166, 15, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 140, 0, 0, 20, 242, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 166, 15, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 15, 0, 0, + 0, 140, 0, 0, 20, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 24, + 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 5, 0, 0, 0, 166, 15, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 2, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 10, 0, 0, 0, 140, 0, 0, + 20, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, + 0, 0, 0, 166, 15, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, + 14, 0, 0, 0, 6, 0, 0, 0, 14, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, + 0, 0, 0, 20, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 9, 0, 0, 0, 166, + 15, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 5, 0, 0, 0, 166, 15, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, 140, + 0, 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 5, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 4, + 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, + 0, 0, 0, 12, 0, 0, 0, 38, 7, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 166, 15, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, 4, 0, + 0, 0, 12, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, + 140, 0, 0, 20, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 29, 0, + 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 164, 0, 0, 8, + 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 79, + 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, + 85, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 6, 5, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, + 11, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 6, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 15, 0, + 0, 0, 7, 0, 0, 0, 15, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, + 0, 24, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 6, 5, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 10, 0, 0, 0, 2, 0, + 0, 0, 10, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 6, 5, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 6, 0, 0, 0, 14, 0, 0, 0, 6, 0, 0, 0, 14, 0, + 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 138, 0, 0, 15, 242, 0, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 17, 0, 0, 0, 25, 0, 0, 0, + 17, 0, 0, 0, 25, 0, 0, 0, 6, 5, 16, 0, 2, 0, 0, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 6, + 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, + 5, 0, 0, 0, 13, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 134, 13, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 5, 0, 0, 0, 6, 1, 16, 0, 1, + 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 5, 0, 0, 0, 6, 8, 16, 0, + 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 6, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 4, 0, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, 140, 0, + 0, 20, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 28, 0, 0, 0, + 28, 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 29, 0, + 0, 0, 29, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 41, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 30, 0, + 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, + 0, 0, 0, 166, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 11, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 5, 0, 0, 0, 166, 15, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 15, 0, 0, 0, 140, + 0, 0, 20, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 8, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, + 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 70, 14, 16, 0, 5, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, + 0, 5, 0, 0, 0, 166, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 10, 0, 0, 0, 140, 0, 0, 20, 242, + 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 4, 0, 0, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 166, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 14, 0, + 0, 0, 6, 0, 0, 0, 14, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, + 0, 20, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 17, 0, 0, 0, 25, 0, 0, 0, 17, 0, 0, 0, 25, 0, 0, 0, 166, 15, 16, + 0, 4, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 4, 0, 0, 0, 166, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 5, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 13, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 3, 0, 0, + 0, 166, 11, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, + 12, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 166, 15, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 12, + 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 70, 14, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 140, 0, 0, + 20, 242, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 29, 0, 0, 0, 29, + 0, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 35, 0, 0, 12, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, + 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, + 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 62, + 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 80, 1, 0, 0, 10, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 81, 0, 0, + 0, 6, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt5_rgba8_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt5_rgba8_cs.h new file mode 100644 index 0000000..f55d51c --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt5_rgba8_cs.h @@ -0,0 +1,2486 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 8 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(1) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r1.yz, r1.xxyx, l(0, 2, 2, 0) +ishl r0.w, r1.y, l(2) +imad r1.y, vThreadID.z, CB0[0][2].y, r1.z +imad r0.w, r1.y, CB0[0][2].x, r0.w +iadd r0.w, r0.w, CB0[0][1].w +ushr r1.y, CB0[0][2].x, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r2.xw, l(27, 0, 0, 29), l(4, 0, 0, 2), vThreadID.xxxx + imad r0.y, r0.y, r1.w, r2.x + ishl r1.z, vThreadID.y, l(12) + and r1.z, r1.z, l(0x00006000) + bfi r1.z, l(3), l(10), r1.x, r1.z + ishr r1.z, r1.z, l(6) + iadd r1.w, r2.y, r2.z + bfi r2.x, l(1), l(1), r1.w, l(0) + iadd r2.x, r2.x, r2.w + bfi r2.x, l(2), l(1), r2.x, l(0) + bfi r1.w, l(1), l(0), r1.w, r2.x + bfi r2.xy, l(18, 18, 0, 0), l(12, 15, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(10, 13, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(6) + bfi r1.w, l(1), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(6, 6, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.zw, l(0, 0, 27, 29), l(0, 0, 4, 2), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r2.z, CB0[0][0].z, l(5) + imad r1.z, r2.x, r2.z, r1.z + ishl r2.x, vThreadID.y, l(7) + and r2.xz, r2.xxxx, l(1792, 0, 2048, 0) + bfi r2.w, l(3), l(5), r1.x, r2.x + bfi r2.w, l(21), l(11), r1.z, r2.w + bfi r3.x, l(1), l(4), vThreadID.y, l(0) + iadd r2.w, r2.w, r3.x + ishl r3.yz, r2.xxxx, l(0, 3, 2, 0) + bfi r3.yz, l(0, 3, 3, 0), l(0, 8, 7, 0), r1.xxxx, r3.yyzy + bfi r3.yz, l(0, 21, 21, 0), l(0, 14, 13, 0), r1.zzzz, r3.yyzy + imad r3.xy, r3.xxxx, l(8, 4, 0, 0), r3.yzyy + bfi r1.z, l(12), l(0), r2.z, r3.x + and r2.x, r3.y, l(1792) + iadd r1.z, r1.z, r2.x + and r2.x, r2.y, l(2) + iadd r1.w, r1.w, r2.x + bfi r1.w, l(2), l(6), r1.w, l(0) + iadd r1.z, r1.z, r1.w + bfi r0.y, l(6), l(0), r2.w, r1.z + endif +else + ishl r1.x, r1.x, l(4) + imad r1.z, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.z, CB0[0][0].z, r1.x +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.yw, r0.yyyw, l(0, 4, 0, 4) +ld r2.xyzw, r0.yyyy, T0[0].yxzw +ieq r1.xzw, r0.zzzz, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r3.xyzw, r2.yxzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.yxzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.yxzw, r4.yxzw +endif +if_nz r1.z + ushr r3.xyzw, r2.yxzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.yxzw + mov r3.xy, r2.ywyy +else + mov r3.xy, r2.ywyy +endif +ishl r4.xyz, r2.zzzz, l(3, 7, 12, 0) +ushr r5.xyz, r2.zzzz, l(13, 4, 9, 0) +mov r4.w, r5.x +and r2.yz, r4.xxwx, l(0, 248, 248, 0) +mov r5.xw, r4.zzzy +and r4.xy, r5.wzww, l(0x0003f000, 0x0003f000, 0, 0) +iadd r2.yz, r2.yyzy, r4.xxyx +and r4.xy, r5.xyxx, l(0x0f800000, 0x0f800000, 0, 0) +iadd r2.yz, r2.yyzy, r4.xxyx +ushr r4.xy, r2.yzyy, l(5, 5, 0, 0) +and r4.xy, r4.xyxx, l(0x00700007, 0x00700007, 0, 0) +iadd r2.yz, r2.yyzy, r4.xxyx +ushr r4.xy, r2.yzyy, l(6, 6, 0, 0) +and r4.xy, r4.xyxx, l(3072, 3072, 0, 0) +iadd r2.yz, r2.yyzy, r4.xxyx +ishl r0.z, r3.y, l(1) +and r0.z, r0.z, l(0xaaaaaaaa) +ushr r4.xyz, r3.yxxy, l(1, 8, 16, 0) +and r1.w, r4.x, l(0x55555555) +iadd r0.z, r0.z, r1.w +ushr r1.w, r0.z, l(1) +and r1.w, r1.w, l(0x55555555) +xor r5.x, r0.z, r1.w +mov r3.z, r4.y +and r3.xy, r3.xzxx, l(255, 255, 0, 0) +bfi r0.z, l(8), l(16), r2.x, l(0) +iadd r0.z, r0.z, r4.z +uge r1.w, r3.y, r3.x +ushr r3.zw, r0.zzzz, l(0, 0, 1, 2) +and r2.w, r0.z, r3.z +and r2.w, r2.w, l(0x00492492) +ishl r4.x, r2.w, l(1) +ushr r4.y, r2.w, l(1) +iadd r2.w, r2.w, r4.x +iadd r2.w, r2.w, r4.y +and r4.x, r0.z, l(0x00249249) +iadd r4.y, r4.x, l(0x00db6db6) +and r4.y, r2.w, r4.y +or r4.z, r0.z, r3.z +and r6.xy, r3.zwzz, l(0x00249249, 0x00249249, 0, 0) +or r3.z, r3.w, r4.z +and r3.z, r3.z, l(0x00249249) +xor r3.z, r3.z, l(0x00249249) +not r4.zw, r6.xxxy +and r3.w, r4.z, r4.x +and r3.w, r4.w, r3.w +or r0.z, r0.z, r3.z +iadd r0.z, r0.z, l(0xffdb6db7) +or r0.z, r3.w, r0.z +ishl r3.zw, r3.wwww, l(0, 0, 2, 1) +or r4.x, r0.z, r3.z +not r2.w, r2.w +and r2.w, r2.w, r4.x +or r2.w, r4.y, r2.w +iadd r3.z, r3.w, r3.z +or r0.z, r0.z, r3.z +movc r0.z, r1.w, r2.w, r0.z +not r4.x, r5.x +ushr r4.yzw, r4.xxxx, l(0, 2, 4, 6) +and r4.xyzw, r4.xyzw, l(3, 3, 3, 3) +ushr r5.yzw, r5.xxxx, l(0, 2, 4, 6) +and r6.xyzw, r5.xyzw, l(3, 3, 3, 3) +imul null, r6.xyzw, r2.zzzz, r6.xyzw +imad r4.xyzw, r4.xyzw, r2.yyyy, r6.xyzw +and r6.xyzw, r4.xyzw, l(1023, 1023, 1023, 1023) +udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) +ishl r6.xyzw, r6.xyzw, l(16, 16, 16, 16) +ubfe r7.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r4.xyzw +udiv r7.xyzw, null, r7.xyzw, l(3, 3, 3, 3) +bfi r6.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r7.xyzw, r6.xyzw +ushr r4.xyzw, r4.xyzw, l(20, 20, 20, 20) +udiv r4.xyzw, null, r4.xyzw, l(3, 3, 3, 3) +or r4.xyzw, r4.xyzw, r6.xyzw +ushr r2.w, r0.z, l(1) +and r2.w, r0.z, r2.w +and r2.w, r2.w, l(1170) +ishl r3.z, r2.w, l(1) +ushr r3.w, r2.w, l(1) +iadd r2.w, r2.w, r3.z +iadd r2.w, r2.w, r3.w +not r3.z, r2.w +and r3.w, r0.z, r3.z +iadd r5.y, -r3.w, l(2925) +and r3.z, r3.z, r5.y +and r5.yz, r3.zzwz, l(0, 7, 7, 0) +imul null, r5.z, r3.y, r5.z +imad r5.y, r3.x, r5.y, r5.z +udiv r5.y, null, r5.y, l(5) +ubfe r6.xyz, l(3, 3, 3, 0), l(3, 6, 9, 0), r3.zzzz +ubfe r7.xyz, l(3, 3, 3, 0), l(3, 6, 9, 0), r3.wwww +imul null, r7.xyz, r3.yyyy, r7.xyzx +imad r6.xyz, r3.xxxx, r6.xyzx, r7.xyzx +udiv r6.xyz, null, r6.xyzx, l(5, 5, 5, 0) +ishl r6.xyz, r6.xyzx, l(8, 16, 24, 0) +or r3.z, r5.y, r6.x +or r3.z, r6.y, r3.z +or r3.z, r6.z, r3.z +and r2.w, r0.z, r2.w +ishl r5.yzw, r2.wwww, l(0, 5, 10, 15) +and r5.yzw, r5.yyzw, l(0, 256, 0x00010000, 0x01000000) +bfi r2.w, l(1), l(0), r2.w, r5.y +iadd r2.w, r5.z, r2.w +iadd r2.w, r5.w, r2.w +imad r2.w, r2.w, l(255), r3.z +not r3.z, r0.z +and r3.w, r3.z, l(7) +and r5.y, r0.z, l(7) +imul null, r5.y, r3.y, r5.y +imad r3.w, r3.x, r3.w, r5.y +udiv r3.w, null, r3.w, l(7) +ubfe r5.yzw, l(0, 3, 3, 3), l(0, 3, 6, 9), r3.zzzz +ubfe r6.xyz, l(3, 3, 3, 0), l(3, 6, 9, 0), r0.zzzz +imul null, r6.xyz, r3.yyyy, r6.xyzx +imad r5.yzw, r3.xxxx, r5.yyzw, r6.xxyz +udiv r5.yzw, null, r5.yyzw, l(0, 7, 7, 7) +ishl r5.yzw, r5.yyzw, l(0, 8, 16, 24) +or r3.z, r3.w, r5.y +or r3.z, r5.z, r3.z +or r3.z, r5.w, r3.z +movc r6.w, r1.w, r2.w, r3.z +ishl r6.xyz, r6.wwww, l(24, 16, 8, 0) +and r6.xyzw, r6.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) +or r4.xyzw, r4.xyzw, r6.xyzw +store_uav_typed U0[0].xyzw, r0.wwww, r4.xyzw +imad r2.w, vThreadID.y, l(4), l(1) +ult r2.w, r2.w, CB0[0][2].y +if_nz r2.w + iadd r3.z, r1.y, r0.w + ushr r4.x, r5.x, l(8) + not r6.x, r4.x + ushr r6.yzw, r6.xxxx, l(0, 2, 4, 6) + and r6.xyzw, r6.xyzw, l(3, 3, 3, 3) + ushr r4.yzw, r4.xxxx, l(0, 2, 4, 6) + and r4.xyzw, r4.xyzw, l(3, 3, 3, 3) + imul null, r4.xyzw, r2.zzzz, r4.xyzw + imad r4.xyzw, r6.xyzw, r2.yyyy, r4.xyzw + and r6.xyzw, r4.xyzw, l(1023, 1023, 1023, 1023) + udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) + ishl r6.xyzw, r6.xyzw, l(16, 16, 16, 16) + ubfe r7.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r4.xyzw + udiv r7.xyzw, null, r7.xyzw, l(3, 3, 3, 3) + bfi r6.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r7.xyzw, r6.xyzw + ushr r4.xyzw, r4.xyzw, l(20, 20, 20, 20) + udiv r4.xyzw, null, r4.xyzw, l(3, 3, 3, 3) + or r4.xyzw, r4.xyzw, r6.xyzw + ushr r3.w, r0.z, l(12) + ushr r5.y, r3.w, l(1) + and r5.y, r3.w, r5.y + and r5.y, r5.y, l(1170) + ishl r5.z, r5.y, l(1) + ushr r5.w, r5.y, l(1) + iadd r5.y, r5.y, r5.z + iadd r5.y, r5.y, r5.w + not r5.z, r5.y + and r5.yw, r3.wwww, r5.yyyz + iadd r6.x, -r5.w, l(2925) + and r5.z, r5.z, r6.x + and r6.xy, r5.zwzz, l(7, 7, 0, 0) + imul null, r6.y, r3.y, r6.y + imad r6.x, r3.x, r6.x, r6.y + ubfe r6.yzw, l(0, 3, 3, 3), l(0, 3, 6, 9), r5.zzzz + ubfe r7.xyz, l(3, 3, 3, 0), l(3, 6, 9, 0), r5.wwww + imul null, r7.xyz, r3.yyyy, r7.xyzx + imad r6.yzw, r3.xxxx, r6.yyzw, r7.xxyz + udiv r6.xyzw, null, r6.xyzw, l(5, 5, 5, 5) + ishl r6.yzw, r6.yyzw, l(0, 8, 16, 24) + or r5.z, r6.y, r6.x + or r5.z, r6.z, r5.z + or r5.z, r6.w, r5.z + ishl r6.xyz, r5.yyyy, l(5, 10, 15, 0) + and r6.xyz, r6.xyzx, l(256, 0x00010000, 0x01000000, 0) + bfi r5.y, l(1), l(0), r5.y, r6.x + iadd r5.y, r6.y, r5.y + iadd r5.y, r6.z, r5.y + imad r5.y, r5.y, l(255), r5.z + not r3.w, r3.w + and r5.z, r3.w, l(7) + ubfe r6.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r0.zzzz + imul null, r6.xyzw, r3.yyyy, r6.xyzw + imad r0.z, r3.x, r5.z, r6.x + udiv r0.z, null, r0.z, l(7) + ubfe r7.xyz, l(3, 3, 3, 0), l(3, 6, 9, 0), r3.wwww + imad r6.xyz, r3.xxxx, r7.xyzx, r6.yzwy + udiv r6.xyz, null, r6.xyzx, l(7, 7, 7, 0) + ishl r6.xyz, r6.xyzx, l(8, 16, 24, 0) + or r0.z, r0.z, r6.x + or r0.z, r6.y, r0.z + or r0.z, r6.z, r0.z + movc r6.w, r1.w, r5.y, r0.z + ishl r6.xyz, r6.wwww, l(24, 16, 8, 0) + and r6.xyzw, r6.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) + or r4.xyzw, r4.xyzw, r6.xyzw + store_uav_typed U0[0].xyzw, r3.zzzz, r4.xyzw + imad r0.z, vThreadID.y, l(4), l(2) + ult r0.z, r0.z, CB0[0][2].y + if_nz r0.z + ushr r0.z, r2.x, l(8) + ushr r3.zw, r0.zzzz, l(0, 0, 1, 2) + and r2.x, r0.z, r3.z + and r2.x, r2.x, l(0x00492492) + ishl r4.x, r2.x, l(1) + ushr r4.y, r2.x, l(1) + iadd r2.x, r2.x, r4.x + iadd r2.x, r2.x, r4.y + and r4.x, r0.z, l(0x00249249) + iadd r4.y, r4.x, l(0x00db6db6) + and r4.y, r2.x, r4.y + or r4.z, r0.z, r3.z + and r5.yz, r3.zzwz, l(0, 0x00249249, 0x00249249, 0) + or r3.z, r3.w, r4.z + and r3.z, r3.z, l(0x00249249) + xor r3.z, r3.z, l(0x00249249) + not r4.zw, r5.yyyz + and r3.w, r4.z, r4.x + and r3.w, r4.w, r3.w + or r0.z, r0.z, r3.z + iadd r0.z, r0.z, l(0xffdb6db7) + or r0.z, r3.w, r0.z + ishl r3.zw, r3.wwww, l(0, 0, 2, 1) + or r4.x, r0.z, r3.z + not r2.x, r2.x + and r2.x, r2.x, r4.x + or r2.x, r4.y, r2.x + iadd r3.z, r3.w, r3.z + or r0.z, r0.z, r3.z + movc r0.z, r1.w, r2.x, r0.z + ishl r2.x, r1.y, l(1) + iadd r2.x, r0.w, r2.x + ushr r4.x, r5.x, l(16) + not r6.x, r4.x + ushr r6.yzw, r6.xxxx, l(0, 2, 4, 6) + and r6.xyzw, r6.xyzw, l(3, 3, 3, 3) + ushr r4.yzw, r4.xxxx, l(0, 2, 4, 6) + and r4.xyzw, r4.xyzw, l(3, 3, 3, 3) + imul null, r4.xyzw, r2.zzzz, r4.xyzw + imad r4.xyzw, r6.xyzw, r2.yyyy, r4.xyzw + and r6.xyzw, r4.xyzw, l(1023, 1023, 1023, 1023) + udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) + ishl r6.xyzw, r6.xyzw, l(16, 16, 16, 16) + ubfe r7.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r4.xyzw + udiv r7.xyzw, null, r7.xyzw, l(3, 3, 3, 3) + bfi r6.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r7.xyzw, r6.xyzw + ushr r4.xyzw, r4.xyzw, l(20, 20, 20, 20) + udiv r4.xyzw, null, r4.xyzw, l(3, 3, 3, 3) + or r4.xyzw, r4.xyzw, r6.xyzw + ushr r3.z, r0.z, l(1) + and r3.z, r0.z, r3.z + and r3.z, r3.z, l(1170) + ishl r3.w, r3.z, l(1) + ushr r5.y, r3.z, l(1) + iadd r3.z, r3.z, r3.w + iadd r3.z, r3.z, r5.y + not r3.w, r3.z + and r5.y, r0.z, r3.w + iadd r5.z, -r5.y, l(2925) + and r3.w, r3.w, r5.z + and r5.z, r3.w, l(7) + and r5.w, r5.y, l(7) + imul null, r5.w, r3.y, r5.w + imad r5.z, r3.x, r5.z, r5.w + udiv r5.z, null, r5.z, l(5) + ubfe r6.xyz, l(3, 3, 3, 0), l(3, 6, 9, 0), r3.wwww + ubfe r7.xyz, l(3, 3, 3, 0), l(3, 6, 9, 0), r5.yyyy + imul null, r7.xyz, r3.yyyy, r7.xyzx + imad r6.xyz, r3.xxxx, r6.xyzx, r7.xyzx + udiv r6.xyz, null, r6.xyzx, l(5, 5, 5, 0) + ishl r6.xyz, r6.xyzx, l(8, 16, 24, 0) + or r3.w, r5.z, r6.x + or r3.w, r6.y, r3.w + or r3.w, r6.z, r3.w + and r3.z, r0.z, r3.z + ishl r5.yzw, r3.zzzz, l(0, 5, 10, 15) + and r5.yzw, r5.yyzw, l(0, 256, 0x00010000, 0x01000000) + bfi r3.z, l(1), l(0), r3.z, r5.y + iadd r3.z, r5.z, r3.z + iadd r3.z, r5.w, r3.z + imad r3.z, r3.z, l(255), r3.w + not r3.w, r0.z + and r5.y, r3.w, l(7) + and r5.z, r0.z, l(7) + imul null, r5.z, r3.y, r5.z + imad r5.y, r3.x, r5.y, r5.z + udiv r5.y, null, r5.y, l(7) + ubfe r6.xyz, l(3, 3, 3, 0), l(3, 6, 9, 0), r3.wwww + ubfe r7.xyz, l(3, 3, 3, 0), l(3, 6, 9, 0), r0.zzzz + imul null, r7.xyz, r3.yyyy, r7.xyzx + imad r6.xyz, r3.xxxx, r6.xyzx, r7.xyzx + udiv r6.xyz, null, r6.xyzx, l(7, 7, 7, 0) + ishl r6.xyz, r6.xyzx, l(8, 16, 24, 0) + or r3.w, r5.y, r6.x + or r3.w, r6.y, r3.w + or r3.w, r6.z, r3.w + movc r6.w, r1.w, r3.z, r3.w + ishl r6.xyz, r6.wwww, l(24, 16, 8, 0) + and r6.xyzw, r6.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) + or r4.xyzw, r4.xyzw, r6.xyzw + store_uav_typed U0[0].xyzw, r2.xxxx, r4.xyzw + imad r2.x, vThreadID.y, l(4), l(3) + ult r2.x, r2.x, CB0[0][2].y + if_nz r2.x + imad r2.x, l(3), r1.y, r0.w + ushr r4.x, r5.x, l(24) + not r5.x, r4.x + ushr r5.yzw, r5.xxxx, l(0, 2, 4, 6) + and r5.xyzw, r5.xyzw, l(3, 3, 3, 3) + ushr r4.yzw, r4.xxxx, l(0, 2, 4, 6) + and r4.xyzw, r4.xyzw, l(3, 3, 3, 3) + imul null, r4.xyzw, r2.zzzz, r4.xyzw + imad r4.xyzw, r5.xyzw, r2.yyyy, r4.xyzw + and r5.xyzw, r4.xyzw, l(1023, 1023, 1023, 1023) + udiv r5.xyzw, null, r5.xyzw, l(3, 3, 3, 3) + ishl r5.xyzw, r5.xyzw, l(16, 16, 16, 16) + ubfe r6.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r4.xyzw + udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) + bfi r5.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r6.xyzw, r5.xyzw + ushr r4.xyzw, r4.xyzw, l(20, 20, 20, 20) + udiv r4.xyzw, null, r4.xyzw, l(3, 3, 3, 3) + or r4.xyzw, r4.xyzw, r5.xyzw + ushr r2.y, r0.z, l(12) + ushr r2.z, r2.y, l(1) + and r2.z, r2.y, r2.z + and r2.z, r2.z, l(1170) + ishl r3.z, r2.z, l(1) + ushr r3.w, r2.z, l(1) + iadd r2.z, r2.z, r3.z + iadd r2.z, r2.z, r3.w + not r3.z, r2.z + and r3.w, r2.y, r3.z + iadd r5.x, -r3.w, l(2925) + and r3.z, r3.z, r5.x + and r5.xy, r3.zwzz, l(7, 7, 0, 0) + imul null, r5.y, r3.y, r5.y + imad r5.x, r3.x, r5.x, r5.y + ubfe r5.yzw, l(0, 3, 3, 3), l(0, 3, 6, 9), r3.zzzz + ubfe r6.xyz, l(3, 3, 3, 0), l(3, 6, 9, 0), r3.wwww + imul null, r6.xyz, r3.yyyy, r6.xyzx + imad r5.yzw, r3.xxxx, r5.yyzw, r6.xxyz + udiv r5.xyzw, null, r5.xyzw, l(5, 5, 5, 5) + ishl r5.yzw, r5.yyzw, l(0, 8, 16, 24) + or r3.z, r5.y, r5.x + or r3.z, r5.z, r3.z + or r3.z, r5.w, r3.z + and r2.z, r2.z, r2.y + ishl r5.xyz, r2.zzzz, l(5, 10, 15, 0) + and r5.xyz, r5.xyzx, l(256, 0x00010000, 0x01000000, 0) + bfi r2.z, l(1), l(0), r2.z, r5.x + iadd r2.z, r5.y, r2.z + iadd r2.z, r5.z, r2.z + imad r2.z, r2.z, l(255), r3.z + not r2.y, r2.y + and r3.z, r2.y, l(7) + ubfe r5.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r0.zzzz + imul null, r5.xyzw, r3.yyyy, r5.xyzw + imad r0.z, r3.x, r3.z, r5.x + udiv r0.z, null, r0.z, l(7) + ubfe r3.yzw, l(0, 3, 3, 3), l(0, 3, 6, 9), r2.yyyy + imad r3.xyz, r3.xxxx, r3.yzwy, r5.yzwy + udiv r3.xyz, null, r3.xyzx, l(7, 7, 7, 0) + ishl r3.xyz, r3.xyzx, l(8, 16, 24, 0) + or r0.z, r0.z, r3.x + or r0.z, r3.y, r0.z + or r0.z, r3.z, r0.z + movc r3.w, r1.w, r2.z, r0.z + ishl r3.xyz, r3.wwww, l(24, 16, 8, 0) + and r3.xyzw, r3.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) + or r3.xyzw, r3.xyzw, r4.xyzw + store_uav_typed U0[0].xyzw, r2.xxxx, r3.xyzw + endif + endif +endif +iadd r0.z, r0.w, l(1) +movc r0.x, r0.x, l(2), l(1) +iadd r0.x, r0.x, r0.y +ld r3.xyzw, r0.xxxx, T0[0].yxzw +if_nz r1.x + ishl r4.xyzw, r3.yxzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.yxzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.yxzw, r5.yxzw +endif +if_nz r1.z + ushr r4.xyzw, r3.yxzw, l(16, 16, 16, 16) + bfi r3.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r3.xyzw, r4.yxzw + mov r2.xy, r3.ywyy +else + mov r2.xy, r3.ywyy +endif +ishl r4.xyz, r3.zzzz, l(3, 7, 12, 0) +ushr r5.xyz, r3.zzzz, l(13, 4, 9, 0) +mov r4.w, r5.x +and r0.xy, r4.xwxx, l(248, 248, 0, 0) +mov r5.xw, r4.zzzy +and r1.xz, r5.wwzw, l(0x0003f000, 0, 0x0003f000, 0) +iadd r0.xy, r0.xyxx, r1.xzxx +and r1.xz, r5.xxyx, l(0x0f800000, 0, 0x0f800000, 0) +iadd r0.xy, r0.xyxx, r1.xzxx +ushr r1.xz, r0.xxyx, l(5, 0, 5, 0) +and r1.xz, r1.xxzx, l(0x00700007, 0, 0x00700007, 0) +iadd r0.xy, r0.xyxx, r1.xzxx +ushr r1.xz, r0.xxyx, l(6, 0, 6, 0) +and r1.xz, r1.xxzx, l(3072, 0, 3072, 0) +iadd r0.xy, r0.xyxx, r1.xzxx +ishl r0.w, r2.y, l(1) +and r0.w, r0.w, l(0xaaaaaaaa) +ushr r1.xzw, r2.yyxx, l(1, 0, 8, 16) +and r1.x, r1.x, l(0x55555555) +iadd r0.w, r0.w, r1.x +ushr r1.x, r0.w, l(1) +and r1.x, r1.x, l(0x55555555) +xor r4.x, r0.w, r1.x +mov r2.z, r1.z +and r1.xz, r2.xxzx, l(255, 0, 255, 0) +bfi r0.w, l(8), l(16), r3.x, l(0) +iadd r0.w, r0.w, r1.w +uge r1.w, r1.z, r1.x +ushr r2.xy, r0.wwww, l(1, 2, 0, 0) +and r2.z, r0.w, r2.x +and r2.z, r2.z, l(0x00492492) +ishl r3.y, r2.z, l(1) +ushr r3.z, r2.z, l(1) +iadd r2.z, r2.z, r3.y +iadd r2.z, r2.z, r3.z +and r3.y, r0.w, l(0x00249249) +iadd r3.z, r3.y, l(0x00db6db6) +and r3.z, r2.z, r3.z +or r3.w, r0.w, r2.x +and r5.xy, r2.xyxx, l(0x00249249, 0x00249249, 0, 0) +or r2.x, r2.y, r3.w +and r2.x, r2.x, l(0x00249249) +xor r2.x, r2.x, l(0x00249249) +not r5.xy, r5.xyxx +and r2.y, r3.y, r5.x +and r2.y, r5.y, r2.y +or r0.w, r0.w, r2.x +iadd r0.w, r0.w, l(0xffdb6db7) +or r0.w, r2.y, r0.w +ishl r2.xy, r2.yyyy, l(2, 1, 0, 0) +or r3.y, r0.w, r2.x +not r2.z, r2.z +and r2.z, r2.z, r3.y +or r2.z, r3.z, r2.z +iadd r2.x, r2.y, r2.x +or r0.w, r0.w, r2.x +movc r0.w, r1.w, r2.z, r0.w +not r5.x, r4.x +ushr r5.yzw, r5.xxxx, l(0, 2, 4, 6) +and r5.xyzw, r5.xyzw, l(3, 3, 3, 3) +ushr r4.yzw, r4.xxxx, l(0, 2, 4, 6) +and r6.xyzw, r4.xyzw, l(3, 3, 3, 3) +imul null, r6.xyzw, r0.yyyy, r6.xyzw +imad r5.xyzw, r5.xyzw, r0.xxxx, r6.xyzw +and r6.xyzw, r5.xyzw, l(1023, 1023, 1023, 1023) +udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) +ishl r6.xyzw, r6.xyzw, l(16, 16, 16, 16) +ubfe r7.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r5.xyzw +udiv r7.xyzw, null, r7.xyzw, l(3, 3, 3, 3) +bfi r6.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r7.xyzw, r6.xyzw +ushr r5.xyzw, r5.xyzw, l(20, 20, 20, 20) +udiv r5.xyzw, null, r5.xyzw, l(3, 3, 3, 3) +or r5.xyzw, r5.xyzw, r6.xyzw +ushr r2.x, r0.w, l(1) +and r2.x, r0.w, r2.x +and r2.x, r2.x, l(1170) +ishl r2.y, r2.x, l(1) +ushr r2.z, r2.x, l(1) +iadd r2.x, r2.x, r2.y +iadd r2.x, r2.x, r2.z +not r2.y, r2.x +and r2.xz, r0.wwww, r2.xxyx +iadd r3.y, -r2.z, l(2925) +and r2.y, r2.y, r3.y +and r3.yz, r2.yyzy, l(0, 7, 7, 0) +imul null, r3.z, r1.z, r3.z +imad r3.y, r1.x, r3.y, r3.z +udiv r3.y, null, r3.y, l(5) +ubfe r4.yzw, l(0, 3, 3, 3), l(0, 3, 6, 9), r2.yyyy +ubfe r6.xyz, l(3, 3, 3, 0), l(3, 6, 9, 0), r2.zzzz +imul null, r6.xyz, r1.zzzz, r6.xyzx +imad r4.yzw, r1.xxxx, r4.yyzw, r6.xxyz +udiv r4.yzw, null, r4.yyzw, l(0, 5, 5, 5) +ishl r4.yzw, r4.yyzw, l(0, 8, 16, 24) +or r2.y, r3.y, r4.y +or r2.y, r4.z, r2.y +or r2.y, r4.w, r2.y +ishl r3.yzw, r2.xxxx, l(0, 5, 10, 15) +and r3.yzw, r3.yyzw, l(0, 256, 0x00010000, 0x01000000) +bfi r2.x, l(1), l(0), r2.x, r3.y +iadd r2.x, r3.z, r2.x +iadd r2.x, r3.w, r2.x +imad r2.x, r2.x, l(255), r2.y +not r2.y, r0.w +and r2.z, r2.y, l(7) +and r3.y, r0.w, l(7) +imul null, r3.y, r1.z, r3.y +imad r2.z, r1.x, r2.z, r3.y +udiv r2.z, null, r2.z, l(7) +ubfe r3.yzw, l(0, 3, 3, 3), l(0, 3, 6, 9), r2.yyyy +ubfe r4.yzw, l(0, 3, 3, 3), l(0, 3, 6, 9), r0.wwww +imul null, r4.yzw, r1.zzzz, r4.yyzw +imad r3.yzw, r1.xxxx, r3.yyzw, r4.yyzw +udiv r3.yzw, null, r3.yyzw, l(0, 7, 7, 7) +ishl r3.yzw, r3.yyzw, l(0, 8, 16, 24) +or r2.y, r2.z, r3.y +or r2.y, r3.z, r2.y +or r2.y, r3.w, r2.y +movc r6.w, r1.w, r2.x, r2.y +ishl r6.xyz, r6.wwww, l(24, 16, 8, 0) +and r6.xyzw, r6.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) +or r5.xyzw, r5.xyzw, r6.xyzw +store_uav_typed U0[0].xyzw, r0.zzzz, r5.xyzw +if_nz r2.w + iadd r2.x, r1.y, r0.z + ushr r5.x, r4.x, l(8) + not r6.x, r5.x + ushr r6.yzw, r6.xxxx, l(0, 2, 4, 6) + and r6.xyzw, r6.xyzw, l(3, 3, 3, 3) + ushr r5.yzw, r5.xxxx, l(0, 2, 4, 6) + and r5.xyzw, r5.xyzw, l(3, 3, 3, 3) + imul null, r5.xyzw, r0.yyyy, r5.xyzw + imad r5.xyzw, r6.xyzw, r0.xxxx, r5.xyzw + and r6.xyzw, r5.xyzw, l(1023, 1023, 1023, 1023) + udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) + ishl r6.xyzw, r6.xyzw, l(16, 16, 16, 16) + ubfe r7.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r5.xyzw + udiv r7.xyzw, null, r7.xyzw, l(3, 3, 3, 3) + bfi r6.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r7.xyzw, r6.xyzw + ushr r5.xyzw, r5.xyzw, l(20, 20, 20, 20) + udiv r5.xyzw, null, r5.xyzw, l(3, 3, 3, 3) + or r5.xyzw, r5.xyzw, r6.xyzw + ushr r2.y, r0.w, l(12) + ushr r2.z, r2.y, l(1) + and r2.z, r2.y, r2.z + and r2.z, r2.z, l(1170) + ishl r2.w, r2.z, l(1) + ushr r3.y, r2.z, l(1) + iadd r2.z, r2.z, r2.w + iadd r2.z, r2.z, r3.y + not r2.w, r2.z + and r3.y, r2.w, r2.y + iadd r3.z, -r3.y, l(2925) + and r2.w, r2.w, r3.z + and r3.z, r2.w, l(7) + and r3.w, r3.y, l(7) + imul null, r3.w, r1.z, r3.w + imad r3.z, r1.x, r3.z, r3.w + udiv r3.z, null, r3.z, l(5) + ubfe r4.yzw, l(0, 3, 3, 3), l(0, 3, 6, 9), r2.wwww + ubfe r6.xyz, l(3, 3, 3, 0), l(3, 6, 9, 0), r3.yyyy + imul null, r6.xyz, r1.zzzz, r6.xyzx + imad r4.yzw, r1.xxxx, r4.yyzw, r6.xxyz + udiv r4.yzw, null, r4.yyzw, l(0, 5, 5, 5) + ishl r4.yzw, r4.yyzw, l(0, 8, 16, 24) + or r2.w, r3.z, r4.y + or r2.w, r4.z, r2.w + or r2.w, r4.w, r2.w + and r2.z, r2.z, r2.y + ishl r3.yzw, r2.zzzz, l(0, 5, 10, 15) + and r3.yzw, r3.yyzw, l(0, 256, 0x00010000, 0x01000000) + bfi r2.z, l(1), l(0), r2.z, r3.y + iadd r2.z, r3.z, r2.z + iadd r2.z, r3.w, r2.z + imad r2.z, r2.z, l(255), r2.w + not r2.y, r2.y + and r2.w, r2.y, l(7) + ubfe r6.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r0.wwww + imul null, r6.xyzw, r1.zzzz, r6.xyzw + imad r0.w, r1.x, r2.w, r6.x + udiv r0.w, null, r0.w, l(7) + ubfe r3.yzw, l(0, 3, 3, 3), l(0, 3, 6, 9), r2.yyyy + imad r3.yzw, r1.xxxx, r3.yyzw, r6.yyzw + udiv r3.yzw, null, r3.yyzw, l(0, 7, 7, 7) + ishl r3.yzw, r3.yyzw, l(0, 8, 16, 24) + or r0.w, r0.w, r3.y + or r0.w, r3.z, r0.w + or r0.w, r3.w, r0.w + movc r6.w, r1.w, r2.z, r0.w + ishl r6.xyz, r6.wwww, l(24, 16, 8, 0) + and r6.xyzw, r6.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) + or r5.xyzw, r5.xyzw, r6.xyzw + store_uav_typed U0[0].xyzw, r2.xxxx, r5.xyzw + imad r0.w, vThreadID.y, l(4), l(2) + ult r0.w, r0.w, CB0[0][2].y + if_nz r0.w + ushr r0.w, r3.x, l(8) + ushr r2.xy, r0.wwww, l(1, 2, 0, 0) + and r2.z, r0.w, r2.x + and r2.z, r2.z, l(0x00492492) + ishl r2.w, r2.z, l(1) + ushr r3.x, r2.z, l(1) + iadd r2.z, r2.z, r2.w + iadd r2.z, r2.z, r3.x + and r2.w, r0.w, l(0x00249249) + iadd r3.x, r2.w, l(0x00db6db6) + and r3.x, r2.z, r3.x + or r3.y, r0.w, r2.x + and r3.zw, r2.xxxy, l(0, 0, 0x00249249, 0x00249249) + or r2.x, r2.y, r3.y + and r2.x, r2.x, l(0x00249249) + xor r2.x, r2.x, l(0x00249249) + not r3.yz, r3.zzwz + and r2.y, r2.w, r3.y + and r2.y, r3.z, r2.y + or r0.w, r0.w, r2.x + iadd r0.w, r0.w, l(0xffdb6db7) + or r0.w, r2.y, r0.w + ishl r2.xy, r2.yyyy, l(2, 1, 0, 0) + or r2.w, r0.w, r2.x + not r2.z, r2.z + and r2.z, r2.z, r2.w + or r2.z, r3.x, r2.z + iadd r2.x, r2.y, r2.x + or r0.w, r0.w, r2.x + movc r0.w, r1.w, r2.z, r0.w + ishl r2.x, r1.y, l(1) + iadd r2.x, r0.z, r2.x + ushr r3.x, r4.x, l(16) + not r5.x, r3.x + ushr r5.yzw, r5.xxxx, l(0, 2, 4, 6) + and r5.xyzw, r5.xyzw, l(3, 3, 3, 3) + ushr r3.yzw, r3.xxxx, l(0, 2, 4, 6) + and r3.xyzw, r3.xyzw, l(3, 3, 3, 3) + imul null, r3.xyzw, r0.yyyy, r3.xyzw + imad r3.xyzw, r5.xyzw, r0.xxxx, r3.xyzw + and r5.xyzw, r3.xyzw, l(1023, 1023, 1023, 1023) + udiv r5.xyzw, null, r5.xyzw, l(3, 3, 3, 3) + ishl r5.xyzw, r5.xyzw, l(16, 16, 16, 16) + ubfe r6.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r3.xyzw + udiv r6.xyzw, null, r6.xyzw, l(3, 3, 3, 3) + bfi r5.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r6.xyzw, r5.xyzw + ushr r3.xyzw, r3.xyzw, l(20, 20, 20, 20) + udiv r3.xyzw, null, r3.xyzw, l(3, 3, 3, 3) + or r3.xyzw, r3.xyzw, r5.xyzw + ushr r2.y, r0.w, l(1) + and r2.y, r0.w, r2.y + and r2.y, r2.y, l(1170) + ishl r2.z, r2.y, l(1) + ushr r2.w, r2.y, l(1) + iadd r2.y, r2.y, r2.z + iadd r2.y, r2.y, r2.w + not r2.z, r2.y + and r2.yw, r0.wwww, r2.yyyz + iadd r4.y, -r2.w, l(2925) + and r2.z, r2.z, r4.y + and r4.yz, r2.zzwz, l(0, 7, 7, 0) + imul null, r4.z, r1.z, r4.z + imad r4.y, r1.x, r4.y, r4.z + udiv r4.y, null, r4.y, l(5) + ubfe r5.xyz, l(3, 3, 3, 0), l(3, 6, 9, 0), r2.zzzz + ubfe r6.xyz, l(3, 3, 3, 0), l(3, 6, 9, 0), r2.wwww + imul null, r6.xyz, r1.zzzz, r6.xyzx + imad r5.xyz, r1.xxxx, r5.xyzx, r6.xyzx + udiv r5.xyz, null, r5.xyzx, l(5, 5, 5, 0) + ishl r5.xyz, r5.xyzx, l(8, 16, 24, 0) + or r2.z, r4.y, r5.x + or r2.z, r5.y, r2.z + or r2.z, r5.z, r2.z + ishl r4.yzw, r2.yyyy, l(0, 5, 10, 15) + and r4.yzw, r4.yyzw, l(0, 256, 0x00010000, 0x01000000) + bfi r2.y, l(1), l(0), r2.y, r4.y + iadd r2.y, r4.z, r2.y + iadd r2.y, r4.w, r2.y + imad r2.y, r2.y, l(255), r2.z + not r2.z, r0.w + and r2.w, r2.z, l(7) + and r4.y, r0.w, l(7) + imul null, r4.y, r1.z, r4.y + imad r2.w, r1.x, r2.w, r4.y + udiv r2.w, null, r2.w, l(7) + ubfe r4.yzw, l(0, 3, 3, 3), l(0, 3, 6, 9), r2.zzzz + ubfe r5.xyz, l(3, 3, 3, 0), l(3, 6, 9, 0), r0.wwww + imul null, r5.xyz, r1.zzzz, r5.xyzx + imad r4.yzw, r1.xxxx, r4.yyzw, r5.xxyz + udiv r4.yzw, null, r4.yyzw, l(0, 7, 7, 7) + ishl r4.yzw, r4.yyzw, l(0, 8, 16, 24) + or r2.z, r2.w, r4.y + or r2.z, r4.z, r2.z + or r2.z, r4.w, r2.z + movc r5.w, r1.w, r2.y, r2.z + ishl r5.xyz, r5.wwww, l(24, 16, 8, 0) + and r5.xyzw, r5.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) + or r3.xyzw, r3.xyzw, r5.xyzw + store_uav_typed U0[0].xyzw, r2.xxxx, r3.xyzw + imad r2.x, vThreadID.y, l(4), l(3) + ult r2.x, r2.x, CB0[0][2].y + if_nz r2.x + imad r0.z, l(3), r1.y, r0.z + ushr r2.x, r4.x, l(24) + not r3.x, r2.x + ushr r3.yzw, r3.xxxx, l(0, 2, 4, 6) + and r3.xyzw, r3.xyzw, l(3, 3, 3, 3) + ushr r2.yzw, r2.xxxx, l(0, 2, 4, 6) + and r2.xyzw, r2.xyzw, l(3, 3, 3, 3) + imul null, r2.xyzw, r0.yyyy, r2.xyzw + imad r2.xyzw, r3.xyzw, r0.xxxx, r2.xyzw + and r3.xyzw, r2.xyzw, l(1023, 1023, 1023, 1023) + udiv r3.xyzw, null, r3.xyzw, l(3, 3, 3, 3) + ishl r3.xyzw, r3.xyzw, l(16, 16, 16, 16) + ubfe r4.xyzw, l(10, 10, 10, 10), l(10, 10, 10, 10), r2.xyzw + udiv r4.xyzw, null, r4.xyzw, l(3, 3, 3, 3) + bfi r3.xyzw, l(8, 8, 8, 8), l(8, 8, 8, 8), r4.xyzw, r3.xyzw + ushr r2.xyzw, r2.xyzw, l(20, 20, 20, 20) + udiv r2.xyzw, null, r2.xyzw, l(3, 3, 3, 3) + or r2.xyzw, r2.xyzw, r3.xyzw + ushr r0.x, r0.w, l(12) + ushr r0.y, r0.x, l(1) + and r0.y, r0.x, r0.y + and r0.y, r0.y, l(1170) + ishl r1.y, r0.y, l(1) + ushr r3.x, r0.y, l(1) + iadd r0.y, r0.y, r1.y + iadd r0.y, r0.y, r3.x + not r1.y, r0.y + and r3.x, r0.x, r1.y + iadd r3.y, -r3.x, l(2925) + and r1.y, r1.y, r3.y + and r3.y, r1.y, l(7) + and r3.z, r3.x, l(7) + imul null, r3.z, r1.z, r3.z + imad r3.y, r1.x, r3.y, r3.z + ubfe r4.xyz, l(3, 3, 3, 0), l(3, 6, 9, 0), r1.yyyy + ubfe r3.xzw, l(3, 0, 3, 3), l(3, 0, 6, 9), r3.xxxx + imul null, r3.xzw, r1.zzzz, r3.xxzw + imad r3.xzw, r1.xxxx, r4.xxyz, r3.xxzw + udiv r3.xyzw, null, r3.xyzw, l(5, 5, 5, 5) + ishl r3.xzw, r3.xxzw, l(8, 0, 16, 24) + or r1.y, r3.x, r3.y + or r1.y, r3.z, r1.y + or r1.y, r3.w, r1.y + and r0.y, r0.y, r0.x + ishl r3.xyz, r0.yyyy, l(5, 10, 15, 0) + and r3.xyz, r3.xyzx, l(256, 0x00010000, 0x01000000, 0) + bfi r0.y, l(1), l(0), r0.y, r3.x + iadd r0.y, r3.y, r0.y + iadd r0.y, r3.z, r0.y + imad r0.y, r0.y, l(255), r1.y + not r0.x, r0.x + and r1.y, r0.x, l(7) + ubfe r3.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r0.wwww + imul null, r3.xyzw, r1.zzzz, r3.xyzw + imad r0.w, r1.x, r1.y, r3.x + udiv r0.w, null, r0.w, l(7) + ubfe r4.xyz, l(3, 3, 3, 0), l(3, 6, 9, 0), r0.xxxx + imad r1.xyz, r1.xxxx, r4.xyzx, r3.yzwy + udiv r1.xyz, null, r1.xyzx, l(7, 7, 7, 0) + ishl r1.xyz, r1.xyzx, l(8, 16, 24, 0) + or r0.x, r0.w, r1.x + or r0.x, r1.y, r0.x + or r0.x, r1.z, r0.x + movc r1.w, r1.w, r0.y, r0.x + ishl r1.xyz, r1.wwww, l(24, 16, 8, 0) + and r1.xyzw, r1.xyzw, l(0xff000000, 0xff000000, 0xff000000, 0xff000000) + or r1.xyzw, r1.xyzw, r2.xyzw + store_uav_typed U0[0].xyzw, r0.zzzz, r1.xyzw + endif + endif +endif +ret +// Approximately 849 instruction slots used +#endif + +const BYTE texture_load_dxt5_rgba8_cs[] = { + 68, 88, 66, 67, 48, 101, 47, 119, 216, 187, 72, 27, 170, 250, 52, 18, 141, 202, 188, + 199, 1, 0, 0, 0, 104, 117, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 204, 116, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 144, 112, 0, + 0, 81, 0, 5, 0, 36, 28, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 8, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 35, 0, 0, 10, 34, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, + 11, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 30, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 85, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, + 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 150, 5, 2, + 0, 2, 64, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 1, 0, 0, 0, 246, 139, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 14, 146, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 2, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 96, + 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, + 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 18, 0, 0, 0, 18, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 15, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 35, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 50, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 138, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, + 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, + 0, 14, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 2, 0, 42, 0, 0, + 9, 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 9, 66, + 0, 16, 0, 2, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, + 82, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 140, 0, + 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 5, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 21, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 18, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 6, + 0, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, + 98, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, + 0, 21, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 14, 0, + 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 86, + 6, 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, + 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, 3, 0, 0, 0, 140, 0, + 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, + 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, + 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 41, 0, 0, 7, 18, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 2, 0, 58, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 2, 0, + 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, 0, 0, 0, + 0, 86, 13, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 22, 126, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 32, 0, 0, 10, 210, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, + 11, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, + 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 22, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, + 0, 4, 0, 0, 0, 22, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 2, 0, 0, 0, 22, 14, 16, 0, 3, 0, 0, 0, 22, 14, + 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 22, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 22, 14, 16, 0, 3, 0, 0, 0, 54, 0, 0, + 5, 50, 0, 16, 0, 3, 0, 0, 0, 214, 5, 16, 0, 2, 0, 0, 0, 18, 0, + 0, 1, 54, 0, 0, 5, 50, 0, 16, 0, 3, 0, 0, 0, 214, 5, 16, 0, 2, + 0, 0, 0, 21, 0, 0, 1, 41, 0, 0, 10, 114, 0, 16, 0, 4, 0, 0, 0, + 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 7, 0, 0, + 0, 12, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 114, 0, 16, 0, 5, 0, + 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 13, 0, 0, 0, 4, + 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, + 4, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 0, 0, 10, 98, 0, 16, + 0, 2, 0, 0, 0, 6, 3, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 146, + 0, 16, 0, 5, 0, 0, 0, 166, 6, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, + 50, 0, 16, 0, 4, 0, 0, 0, 182, 15, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 240, 3, 0, 0, 240, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 6, + 1, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, + 70, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 15, 0, 0, 128, + 15, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 98, 0, 16, 0, 2, 0, + 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 4, 0, 0, 0, 85, + 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 7, 0, 112, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, + 2, 0, 0, 0, 6, 1, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, + 0, 4, 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 6, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 50, + 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 0, 12, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 98, 0, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 6, 1, + 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, + 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 170, 170, 170, 170, 85, 0, 0, 10, 114, 0, 16, 0, 4, 0, 0, 0, 22, 4, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 16, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 85, 85, 85, 85, 30, 0, 0, + 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 85, 85, 85, 85, 87, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 66, + 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, + 50, 0, 16, 0, 3, 0, 0, 0, 134, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, + 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 1, + 64, 0, 0, 16, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 80, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, + 0, 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 2, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 130, + 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 146, 36, 73, 0, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, + 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, + 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 73, 146, 36, 0, 30, 0, 0, 7, 34, 0, 16, 0, + 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 182, 109, 219, + 0, 1, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 4, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 1, 0, 0, 10, 50, 0, 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 73, 146, 36, 0, 73, 146, 36, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, + 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, + 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 73, 146, 36, + 0, 87, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 73, 146, 36, 0, 59, 0, 0, 5, 194, 0, 16, 0, 4, + 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, + 3, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, + 0, 1, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 183, 109, 219, 255, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 41, + 0, 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, + 0, 60, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 59, 0, 0, 5, 130, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, + 0, 60, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, + 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 59, 0, 0, 5, 18, 0, 16, 0, 4, 0, 0, 0, + 10, 0, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, + 0, 5, 0, 0, 0, 6, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 242, 0, 16, 0, 6, 0, 0, 0, 166, 10, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 6, + 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, + 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 138, + 0, 0, 15, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, + 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 7, 0, 0, 0, 0, 208, 0, 0, 70, + 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 6, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, + 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 4, 0, 0, 0, 0, 208, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 85, 0, + 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, + 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 146, 4, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, + 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, + 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 130, + 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 59, 0, 0, 5, 66, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, + 0, 2, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 8, 34, + 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 109, 11, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 0, + 0, 10, 98, 0, 16, 0, 5, 0, 0, 0, 166, 11, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 38, 0, 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, + 0, 3, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, + 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 5, + 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 78, 0, 0, 8, 34, 0, 16, 0, + 5, 0, 0, 0, 0, 208, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, + 0, 5, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 6, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 166, 10, 16, 0, 3, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 7, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 114, 0, 16, 0, 7, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, + 0, 7, 0, 0, 0, 35, 0, 0, 9, 114, 0, 16, 0, 6, 0, 0, 0, 6, 0, + 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 7, + 0, 0, 0, 78, 0, 0, 11, 114, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, + 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 6, 0, + 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 16, + 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, + 3, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, + 0, 60, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 6, 0, + 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 3, + 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 1, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 226, 0, 16, 0, 5, 0, + 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 5, + 0, 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, + 5, 0, 0, 0, 86, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 140, 0, 0, 11, 130, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 35, + 0, 0, 9, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 255, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 59, 0, 0, + 5, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, + 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 3, 0, + 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 3, + 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, + 26, 0, 16, 0, 5, 0, 0, 0, 78, 0, 0, 8, 130, 0, 16, 0, 3, 0, 0, + 0, 0, 208, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 7, 0, + 0, 0, 138, 0, 0, 15, 226, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 166, 10, 16, + 0, 3, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 6, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 166, 10, 16, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 114, 0, 16, + 0, 6, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 6, 0, + 0, 0, 35, 0, 0, 9, 226, 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 3, + 0, 0, 0, 86, 14, 16, 0, 5, 0, 0, 0, 6, 9, 16, 0, 6, 0, 0, 0, + 78, 0, 0, 11, 226, 0, 16, 0, 5, 0, 0, 0, 0, 208, 0, 0, 86, 14, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 41, 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, 86, + 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, + 16, 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, + 0, 58, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 60, 0, + 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, + 0, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 55, 0, 0, + 9, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 114, + 0, 16, 0, 6, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, + 24, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 60, + 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 35, 0, 0, 8, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 2, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 79, 0, 0, 9, + 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, + 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, + 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, + 0, 8, 0, 0, 0, 59, 0, 0, 5, 18, 0, 16, 0, 6, 0, 0, 0, 10, 0, + 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 6, + 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 4, + 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, + 208, 0, 0, 242, 0, 16, 0, 4, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 6, 0, 0, + 0, 0, 208, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, + 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 138, 0, 0, + 15, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 78, 0, 0, 11, 242, 0, 16, 0, 7, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, + 0, 7, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 85, 0, + 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 78, 0, 0, 11, 242, 0, 16, 0, 4, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 85, 0, 0, 7, + 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 12, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 34, + 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, + 5, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, + 0, 5, 0, 0, 0, 1, 64, 0, 0, 146, 4, 0, 0, 41, 0, 0, 7, 66, 0, + 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, + 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 5, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 5, 0, + 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 5, + 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 59, 0, 0, 5, 66, 0, 16, 0, + 5, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 0, 0, 7, 162, 0, 16, + 0, 5, 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, 86, 9, 16, 0, 5, 0, + 0, 0, 30, 0, 0, 8, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 128, 65, + 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0, 109, 11, 0, 0, 1, 0, 0, 7, + 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, + 0, 6, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 6, 0, 0, 0, 230, 10, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, + 6, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 138, + 0, 0, 15, 226, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 166, 10, 16, 0, 5, 0, + 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, + 0, 5, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 114, 0, 16, 0, 7, 0, + 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 35, + 0, 0, 9, 226, 0, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, + 86, 14, 16, 0, 6, 0, 0, 0, 6, 9, 16, 0, 7, 0, 0, 0, 78, 0, 0, + 11, 242, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 41, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 86, 14, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, + 0, 24, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 26, 0, + 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 60, 0, 0, 7, 66, + 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, + 5, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, + 0, 6, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 6, 0, 0, 0, 86, 5, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 5, + 0, 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, + 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, + 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 140, 0, + 0, 11, 34, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, + 6, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, + 0, 6, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 34, 0, + 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 5, + 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, + 5, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, + 0, 59, 0, 0, 5, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 18, 0, + 0, 0, 21, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, + 208, 0, 0, 242, 0, 16, 0, 6, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 10, 0, + 16, 0, 6, 0, 0, 0, 78, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 0, + 208, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, + 138, 0, 0, 15, 114, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 3, + 0, 0, 0, 35, 0, 0, 9, 114, 0, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, + 3, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 150, 7, 16, 0, 6, 0, 0, + 0, 78, 0, 0, 11, 114, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, 70, 2, + 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, + 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 16, 0, 0, + 0, 24, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 60, + 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 55, 0, + 0, 9, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, + 114, 0, 16, 0, 6, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, 0, 2, 64, 0, + 0, 24, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, + 60, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, + 0, 0, 0, 35, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 2, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 79, 0, 0, + 9, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 42, + 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 85, 0, 0, + 10, 194, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, + 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, + 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 146, 36, 73, 0, 41, 0, + 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, + 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, + 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, + 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 73, 146, 36, 0, 30, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 182, 109, 219, 0, 1, 0, 0, 7, 34, + 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, + 4, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 10, 98, 0, + 16, 0, 5, 0, 0, 0, 166, 11, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 73, 146, 36, 0, 73, 146, 36, 0, 0, 0, 0, 0, 60, 0, 0, 7, + 66, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, + 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 73, 146, 36, 0, 87, 0, 0, 7, 66, + 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 73, 146, 36, 0, 59, 0, 0, 5, 194, 0, 16, 0, 4, 0, 0, 0, 86, 9, 16, + 0, 5, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 130, + 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 66, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 183, + 109, 219, 255, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, + 0, 3, 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 18, + 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 3, 0, 0, 0, 59, 0, 0, 5, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 60, 0, 0, 7, 18, + 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, + 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 66, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, + 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 41, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 85, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, + 0, 1, 64, 0, 0, 16, 0, 0, 0, 59, 0, 0, 5, 18, 0, 16, 0, 6, 0, + 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, 0, 6, + 0, 0, 0, 6, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 10, 226, + 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 38, + 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 4, 0, 0, 0, 166, 10, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 86, 5, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, 0, 11, 242, 0, 16, + 0, 6, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 138, 0, 0, 15, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 10, 0, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, 0, 10, + 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 7, 0, 0, 0, 0, 208, 0, + 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 6, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 20, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 4, 0, 0, 0, 0, 208, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, + 85, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, + 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 146, 4, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, + 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, + 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 26, 0, + 16, 0, 5, 0, 0, 0, 59, 0, 0, 5, 130, 0, 16, 0, 3, 0, 0, 0, 42, + 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, + 8, 66, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 5, 0, + 0, 0, 1, 64, 0, 0, 109, 11, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 3, + 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, + 1, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 5, 0, + 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 38, + 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, + 3, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 5, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 5, 0, + 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 78, 0, 0, 8, 66, 0, 16, 0, 5, + 0, 0, 0, 0, 208, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, + 5, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 3, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 86, 5, 16, 0, 5, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 114, + 0, 16, 0, 7, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, + 7, 0, 0, 0, 35, 0, 0, 9, 114, 0, 16, 0, 6, 0, 0, 0, 6, 0, 16, + 0, 3, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 7, 0, + 0, 0, 78, 0, 0, 11, 114, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, 70, + 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, + 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 16, 0, + 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 3, + 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, + 60, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, + 0, 58, 0, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, + 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, + 0, 166, 10, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 5, 0, + 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, 5, + 0, 0, 0, 86, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 140, 0, 0, 11, 66, 0, 16, + 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, + 42, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, + 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 255, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 59, 0, 0, 5, + 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, + 7, 34, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 7, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 38, 0, 0, 8, + 0, 208, 0, 0, 66, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 16, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 5, 0, + 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, + 0, 16, 0, 5, 0, 0, 0, 78, 0, 0, 8, 34, 0, 16, 0, 5, 0, 0, 0, + 0, 208, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, + 0, 138, 0, 0, 15, 114, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, + 3, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 166, + 10, 16, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 114, 0, 16, 0, + 7, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, + 0, 35, 0, 0, 9, 114, 0, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 3, 0, + 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 78, + 0, 0, 11, 114, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, 70, 2, 16, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, + 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, + 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, + 26, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 60, 0, 0, + 7, 130, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 42, + 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 55, 0, 0, 9, + 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, + 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 6, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 24, + 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 60, 0, + 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 6, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 35, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 2, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 79, 0, 0, 9, 18, + 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, + 0, 2, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, + 5, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 59, 0, 0, 5, 18, 0, 16, + 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 226, 0, + 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, + 0, 10, 226, 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 4, 0, 0, 0, 166, + 10, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 35, 0, 0, 9, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 86, 5, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, 0, 11, + 242, 0, 16, 0, 5, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 6, 0, 0, 0, + 0, 208, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, + 0, 0, 0, 20, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 4, 0, 0, 0, + 0, 208, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 242, 0, + 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, + 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, + 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, + 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 146, 4, 0, + 0, 41, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 3, + 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 59, + 0, 0, 5, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 1, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 8, 18, 0, 16, 0, 5, 0, + 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 109, + 11, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, + 3, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, + 0, 5, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, + 208, 0, 0, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, + 26, 0, 16, 0, 5, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 5, 0, 0, + 0, 10, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 26, 0, + 16, 0, 5, 0, 0, 0, 138, 0, 0, 15, 226, 0, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, + 0, 166, 10, 16, 0, 3, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, + 0, 114, 0, 16, 0, 6, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, + 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 226, 0, 16, 0, 5, 0, 0, 0, 6, + 0, 16, 0, 3, 0, 0, 0, 86, 14, 16, 0, 5, 0, 0, 0, 6, 9, 16, 0, + 6, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 5, 0, 0, 0, 0, 208, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, + 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 226, 0, 16, 0, 5, + 0, 0, 0, 86, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, + 0, 3, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 5, 0, + 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 5, + 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, + 3, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, + 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 5, + 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, + 10, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, + 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 1, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 140, 0, 0, 11, 66, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, + 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 5, 0, + 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 255, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 59, 0, + 0, 5, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, + 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 21, + 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 242, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 5, + 0, 0, 0, 78, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 138, 0, 0, + 15, 226, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, + 35, 0, 0, 9, 114, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, + 0, 150, 7, 16, 0, 3, 0, 0, 0, 150, 7, 16, 0, 5, 0, 0, 0, 78, 0, + 0, 11, 114, 0, 16, 0, 3, 0, 0, 0, 0, 208, 0, 0, 70, 2, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, + 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, + 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 130, + 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, + 0, 3, 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 24, 0, + 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 60, 0, 0, + 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 4, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 30, 0, 0, 7, 66, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 55, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 3, 0, + 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 22, 126, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 22, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 22, 14, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 22, 14, 16, + 0, 4, 0, 0, 0, 22, 14, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 31, 0, + 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 22, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 22, 14, 16, 0, + 4, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 2, 0, 0, 0, 214, 5, 16, + 0, 3, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 50, 0, 16, 0, 2, 0, + 0, 0, 214, 5, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 41, 0, 0, 10, 114, + 0, 16, 0, 4, 0, 0, 0, 166, 10, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 7, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, + 10, 114, 0, 16, 0, 5, 0, 0, 0, 166, 10, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 13, 0, 0, 0, 4, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 130, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, + 1, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 198, 0, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 5, 146, 0, 16, 0, 5, 0, 0, 0, 166, 6, 16, 0, 4, + 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 246, 14, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 0, 240, 3, 0, 0, 0, 0, 0, 0, 240, 3, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 10, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 128, 15, 0, 0, 0, 0, 0, 0, 128, 15, 0, 0, 0, 0, 30, 0, 0, + 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 134, 0, + 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, + 1, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, + 0, 6, 2, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 7, 0, 112, 0, 0, 0, + 0, 0, 7, 0, 112, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, + 85, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 0, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 170, 170, 170, 170, 85, 0, 0, 10, 210, 0, 16, + 0, 1, 0, 0, 0, 86, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 85, 85, 85, 85, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 7, 18, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 85, 85, 85, 85, 87, 0, 0, 7, 18, 0, 16, + 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, + 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 8, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 10, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 80, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 2, + 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, + 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 146, 36, 73, 0, 41, 0, 0, 7, 34, 0, 16, 0, + 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 85, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, + 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 73, 146, 36, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 182, 109, 219, 0, 1, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 60, 0, + 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, + 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 73, 146, 36, 0, 73, 146, 36, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, + 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 73, 146, 36, 0, 87, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, + 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 73, 146, 36, 0, 59, 0, + 0, 5, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 1, + 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 5, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 60, 0, + 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 183, 109, 219, 255, 60, 0, 0, + 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 86, + 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 59, 0, + 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, + 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 55, 0, 0, + 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 59, 0, 0, 5, 18, + 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, + 226, 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 85, 0, 0, 10, 226, 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 6, 0, 0, + 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 35, 0, + 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 6, + 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, + 0, 11, 242, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 6, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 7, 0, + 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, + 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, + 14, 16, 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, + 0, 20, 0, 0, 0, 20, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 5, 0, + 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 18, + 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 146, 4, 0, 0, 41, 0, 0, 7, 34, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, + 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, + 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 59, 0, 0, 5, 34, 0, 16, 0, + 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 82, 0, 16, + 0, 2, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 2, 0, + 0, 0, 30, 0, 0, 8, 34, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 128, 65, + 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 109, 11, 0, 0, 1, 0, 0, 7, + 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, + 0, 3, 0, 0, 0, 1, 0, 0, 10, 98, 0, 16, 0, 3, 0, 0, 0, 86, 6, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, + 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, + 0, 35, 0, 0, 9, 34, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 78, + 0, 0, 8, 34, 0, 16, 0, 3, 0, 0, 0, 0, 208, 0, 0, 26, 0, 16, 0, + 3, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 138, 0, 0, 15, 226, 0, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 6, + 0, 0, 0, 9, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 138, 0, 0, 15, + 114, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 38, + 0, 0, 8, 0, 208, 0, 0, 114, 0, 16, 0, 6, 0, 0, 0, 166, 10, 16, 0, + 1, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 226, 0, 16, + 0, 4, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 86, 14, 16, 0, 4, 0, + 0, 0, 6, 9, 16, 0, 6, 0, 0, 0, 78, 0, 0, 11, 226, 0, 16, 0, 4, + 0, 0, 0, 0, 208, 0, 0, 86, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 41, 0, 0, + 10, 226, 0, 16, 0, 4, 0, 0, 0, 86, 14, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 60, + 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, + 26, 0, 16, 0, 4, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, + 0, 42, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 60, 0, + 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 26, + 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 226, 0, 16, 0, 3, 0, 0, 0, + 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 5, 0, 0, + 0, 10, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, 3, 0, + 0, 0, 86, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 140, 0, 0, 11, 18, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 30, 0, + 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, + 9, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 255, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 59, 0, 0, 5, 34, + 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, + 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 7, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 38, 0, 0, 8, 0, + 208, 0, 0, 34, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 3, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, + 16, 0, 3, 0, 0, 0, 78, 0, 0, 8, 66, 0, 16, 0, 2, 0, 0, 0, 0, + 208, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, + 138, 0, 0, 15, 226, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 86, 5, 16, 0, 2, + 0, 0, 0, 138, 0, 0, 15, 226, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 246, 15, + 16, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 226, 0, 16, 0, 4, + 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 86, 14, 16, 0, 4, 0, 0, 0, + 35, 0, 0, 9, 226, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, + 0, 86, 14, 16, 0, 3, 0, 0, 0, 86, 14, 16, 0, 4, 0, 0, 0, 78, 0, + 0, 11, 226, 0, 16, 0, 3, 0, 0, 0, 0, 208, 0, 0, 86, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 41, 0, 0, 10, 226, 0, 16, 0, 3, 0, 0, 0, 86, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, + 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, + 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, + 0, 2, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 130, + 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, + 0, 6, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 24, 0, + 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 60, 0, 0, + 7, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 31, 0, 4, 3, 58, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, + 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, + 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 59, 0, 0, 5, 18, 0, 16, 0, + 6, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 226, 0, 16, + 0, 6, 0, 0, 0, 6, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, + 10, 226, 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 5, 0, 0, 0, 86, 5, + 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 35, 0, 0, 9, 242, + 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 6, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, 0, 11, 242, + 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, + 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 7, 0, 0, 0, 0, + 208, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, + 0, 6, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, + 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 5, 0, 0, 0, 0, + 208, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 242, 0, 16, + 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 6, 0, + 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, + 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 146, 4, 0, 0, + 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 59, 0, + 0, 5, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, + 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 8, 66, 0, 16, 0, 3, 0, 0, + 0, 26, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 109, 11, + 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, + 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, + 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, + 0, 1, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 130, + 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 78, 0, 0, 8, 66, 0, 16, 0, 3, 0, 0, 0, 0, 208, 0, 0, 42, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 138, 0, 0, 15, + 226, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 138, + 0, 0, 15, 114, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 3, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 114, 0, 16, 0, 6, 0, 0, 0, 166, + 10, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, + 226, 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 86, 14, 16, + 0, 4, 0, 0, 0, 6, 9, 16, 0, 6, 0, 0, 0, 78, 0, 0, 11, 226, 0, + 16, 0, 4, 0, 0, 0, 0, 208, 0, 0, 86, 14, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 41, 0, 0, 10, 226, 0, 16, 0, 4, 0, 0, 0, 86, 14, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, + 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, + 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, + 2, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, + 0, 60, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, + 41, 0, 0, 10, 226, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 15, 0, + 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, 3, 0, 0, 0, 86, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 1, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 59, 0, 0, 5, 34, 0, 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 138, 0, + 0, 15, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, + 15, 0, 0, 0, 18, 0, 0, 0, 21, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, + 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 6, 0, 0, 0, 166, 10, + 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 130, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 78, 0, 0, 8, 130, 0, 16, + 0, 0, 0, 0, 0, 0, 208, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 7, 0, 0, 0, 138, 0, 0, 15, 226, 0, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, + 0, 86, 5, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 226, 0, 16, 0, 3, 0, + 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 86, 14, 16, 0, 3, 0, 0, 0, 86, + 14, 16, 0, 6, 0, 0, 0, 78, 0, 0, 11, 226, 0, 16, 0, 3, 0, 0, 0, + 0, 208, 0, 0, 86, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 41, 0, 0, 10, 226, 0, + 16, 0, 3, 0, 0, 0, 86, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, + 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 3, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 130, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, 246, 15, 16, 0, 6, + 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 60, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 164, 0, 0, 8, + 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 35, 0, 0, 8, 130, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 79, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 130, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 8, + 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 246, 15, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 146, 36, 73, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 18, 0, + 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, + 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 73, 146, 36, 0, 30, 0, 0, 7, 18, 0, 16, 0, + 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 182, 109, 219, + 0, 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 3, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 1, 0, 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 146, 36, 0, 73, 146, + 36, 0, 60, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, + 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 73, 146, 36, + 0, 87, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 73, 146, 36, 0, 59, 0, 0, 5, 98, 0, 16, 0, 3, + 0, 0, 0, 166, 11, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, + 0, 1, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, + 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 0, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 183, 109, 219, 255, 60, 0, 0, 7, 130, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, + 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 59, 0, 0, 5, 66, 0, 16, 0, 2, + 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, + 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, + 0, 60, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 60, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, + 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 59, 0, 0, 5, + 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 85, 0, 0, + 10, 226, 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 85, 0, 0, 10, 226, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 3, 0, + 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 35, + 0, 0, 9, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, + 0, 0, 11, 242, 0, 16, 0, 5, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 6, 0, 0, 0, + 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 6, + 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 3, + 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, + 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, + 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 2, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 146, 4, 0, 0, 41, 0, 0, 7, 66, + 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, + 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, + 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 59, 0, 0, 5, 66, 0, 16, + 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 162, 0, + 16, 0, 2, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 86, 9, 16, 0, 2, + 0, 0, 0, 30, 0, 0, 8, 34, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 128, + 65, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 109, 11, 0, 0, 1, 0, 0, + 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, + 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 98, 0, 16, 0, 4, 0, 0, 0, 166, + 11, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 66, 0, 16, + 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 4, 0, + 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, + 78, 0, 0, 8, 34, 0, 16, 0, 4, 0, 0, 0, 0, 208, 0, 0, 26, 0, 16, + 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 138, 0, 0, 15, 114, 0, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 138, 0, 0, + 15, 114, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, + 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, + 38, 0, 0, 8, 0, 208, 0, 0, 114, 0, 16, 0, 6, 0, 0, 0, 166, 10, 16, + 0, 1, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 114, 0, + 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 5, + 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 78, 0, 0, 11, 114, 0, 16, 0, + 5, 0, 0, 0, 0, 208, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 41, 0, + 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, + 60, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, + 0, 10, 0, 16, 0, 5, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 60, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 226, 0, 16, 0, 4, 0, 0, + 0, 86, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 5, 0, + 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, 4, + 0, 0, 0, 86, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 140, 0, 0, 11, 34, 0, 16, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 30, + 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, + 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, + 0, 58, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 255, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 59, 0, 0, 5, + 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, + 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 7, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 38, 0, 0, 8, + 0, 208, 0, 0, 34, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 4, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 4, 0, 0, 0, 78, 0, 0, 8, 130, 0, 16, 0, 2, 0, 0, 0, + 0, 208, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, + 0, 138, 0, 0, 15, 226, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 166, 10, 16, 0, + 2, 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 114, 0, 16, 0, + 5, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, + 0, 35, 0, 0, 9, 226, 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 1, 0, + 0, 0, 86, 14, 16, 0, 4, 0, 0, 0, 6, 9, 16, 0, 5, 0, 0, 0, 78, + 0, 0, 11, 226, 0, 16, 0, 4, 0, 0, 0, 0, 208, 0, 0, 86, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 7, 0, 0, 0, 41, 0, 0, 10, 226, 0, 16, 0, 4, 0, 0, 0, 86, 14, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, + 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 60, 0, 0, + 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 55, 0, 0, 9, + 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 114, 0, + 16, 0, 5, 0, 0, 0, 246, 15, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 24, + 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 60, 0, + 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 35, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 2, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 79, 0, 0, 9, 18, + 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, + 0, 2, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, + 4, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 59, 0, 0, 5, 18, 0, 16, + 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 226, 0, + 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 85, 0, + 0, 10, 226, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 2, 0, 0, 0, 86, + 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 6, 0, 16, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 78, 0, 0, 11, + 242, 0, 16, 0, 3, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 4, 0, 0, 0, + 0, 208, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 140, 0, 0, 17, 242, 0, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, + 0, 0, 0, 20, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 2, 0, 0, 0, + 0, 208, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 242, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 146, 4, 0, + 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 3, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 59, + 0, 0, 5, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 8, 34, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 109, + 11, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, + 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, + 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, + 0, 3, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, + 0, 0, 0, 138, 0, 0, 15, 114, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 86, 5, + 16, 0, 1, 0, 0, 0, 138, 0, 0, 15, 210, 0, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 210, 0, + 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 6, 14, 16, 0, 3, + 0, 0, 0, 35, 0, 0, 9, 210, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, + 1, 0, 0, 0, 6, 9, 16, 0, 4, 0, 0, 0, 6, 14, 16, 0, 3, 0, 0, + 0, 78, 0, 0, 11, 242, 0, 16, 0, 3, 0, 0, 0, 0, 208, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 210, 0, 16, 0, 3, 0, 0, 0, + 6, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 60, + 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 0, + 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 3, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 10, 0, 0, + 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 3, 0, + 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 30, 0, + 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 255, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 59, 0, 0, 5, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 21, 0, 0, 0, + 246, 15, 16, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, + 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, + 78, 0, 0, 8, 130, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, 58, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 138, 0, 0, 15, 114, 0, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 114, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 2, + 16, 0, 4, 0, 0, 0, 150, 7, 16, 0, 3, 0, 0, 0, 78, 0, 0, 11, 114, + 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + 0, 41, 0, 0, 10, 114, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 0, + 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 1, 0, + 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, 16, + 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 60, 0, 0, 7, 242, 0, + 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 166, 10, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 21, 0, 0, + 1, 21, 0, 0, 1, 21, 0, 0, 1, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, + 0, 0, 81, 3, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 9, 1, 0, 0, 179, 1, 0, 0, 6, 0, 0, 0, 13, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 11, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt5a_r8_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt5a_r8_cs.h new file mode 100644 index 0000000..4b5bd06 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_dxt5a_r8_cs.h @@ -0,0 +1,2329 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 19 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(2) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r1.yz, r1.xxyx, l(0, 2, 2, 0) +imad r0.w, vThreadID.z, CB0[0][2].y, r1.z +imad r0.w, r0.w, CB0[0][2].x, r1.y +iadd r0.w, r0.w, CB0[0][1].w +ushr r1.y, CB0[0][2].x, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r2.xw, l(27, 0, 0, 29), l(3, 0, 0, 1), vThreadID.xxxx + imad r0.y, r0.y, r1.w, r2.x + ishl r1.z, vThreadID.y, l(11) + and r1.z, r1.z, l(0x00003000) + bfi r1.z, l(3), l(9), r1.x, r1.z + ishr r1.z, r1.z, l(6) + iadd r1.w, r2.y, r2.z + bfi r2.x, l(1), l(1), r1.w, l(0) + iadd r2.x, r2.x, r2.w + bfi r2.x, l(2), l(1), r2.x, l(0) + bfi r1.w, l(1), l(0), r1.w, r2.x + bfi r2.xy, l(19, 19, 0, 0), l(11, 14, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(9, 12, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(6) + bfi r1.w, l(1), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(6, 6, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r2.z, CB0[0][0].z, l(5) + imad r1.z, r2.x, r2.z, r1.z + ishl r2.xz, vThreadID.yyyy, l(6, 0, 7, 0) + and r2.xz, r2.xxzx, l(896, 0, 2048, 0) + bfi r2.w, l(3), l(4), r1.x, r2.x + bfi r2.w, l(22), l(10), r1.z, r2.w + bfi r3.x, l(1), l(4), vThreadID.y, l(0) + iadd r2.w, r2.w, r3.x + ishl r3.yz, r2.xxxx, l(0, 3, 2, 0) + bfi r3.yz, l(0, 3, 3, 0), l(0, 7, 6, 0), r1.xxxx, r3.yyzy + bfi r3.yz, l(0, 22, 22, 0), l(0, 13, 12, 0), r1.zzzz, r3.yyzy + imad r3.xy, r3.xxxx, l(8, 4, 0, 0), r3.yzyy + bfi r1.z, l(12), l(0), r2.z, r3.x + and r2.x, r3.y, l(1792) + iadd r1.z, r1.z, r2.x + and r2.x, r2.y, l(2) + iadd r1.w, r1.w, r2.x + bfi r1.w, l(2), l(6), r1.w, l(0) + iadd r1.z, r1.z, r1.w + bfi r0.y, l(6), l(0), r2.w, r1.z + endif +else + ishl r1.x, r1.x, l(3) + imad r1.z, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.z, CB0[0][0].z, r1.x +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.yw, r0.yyyw, l(0, 4, 0, 4) +ld r2.xyzw, r0.yyyy, T0[0].ywxz +ieq r1.xzw, r0.zzzz, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r3.xyzw, r2.zxwy, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.zxwy, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.ywxz, r4.ywxz +endif +if_nz r1.z + ushr r3.xyzw, r2.zxwy, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.ywxz + mov r3.xy, r2.zwzz +else + mov r3.xy, r2.zwzz +endif +movc r0.x, r0.x, l(2), l(1) +iadd r0.x, r0.x, r0.y +ld r4.xyzw, r0.xxxx, T0[0].ywxz +if_nz r1.x + ishl r5.xyzw, r4.zxwy, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r6.xyzw, r4.zxwy, l(8, 8, 8, 8) + and r6.xyzw, r6.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r4.xyzw, r5.ywxz, r6.ywxz +endif +if_nz r1.z + ushr r5.xyzw, r4.zxwy, l(16, 16, 16, 16) + bfi r4.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r4.xyzw, r5.ywxz + mov r2.zw, r4.xxxy +else + mov r2.zw, r4.xxxy +endif +ushr r3.zw, r3.xxxy, l(0, 0, 8, 8) +and r5.xyzw, r3.xzyw, l(255, 255, 255, 255) +ushr r4.xy, r4.zwzz, l(8, 8, 0, 0) +and r6.xyzw, r4.zxwy, l(255, 255, 255, 255) +mov r4.xy, r3.xyxx +ushr r3.xyzw, r4.xyzw, l(16, 16, 16, 16) +bfi r4.xyzw, l(8, 8, 8, 8), l(16, 16, 16, 16), r2.xyzw, l(0, 0, 0, 0) +iadd r3.xyzw, r3.xyzw, r4.xyzw +uge r0.xy, r5.ywyy, r5.xzxx +ushr r4.xyzw, r3.xxyy, l(1, 2, 1, 2) +and r1.xz, r3.xxyx, r4.xxzx +and r1.xz, r1.xxzx, l(0x00492492, 0, 0x00492492, 0) +ishl r7.xy, r1.xzxx, l(1, 1, 0, 0) +ushr r7.zw, r1.xxxz, l(0, 0, 1, 1) +iadd r1.xz, r1.xxzx, r7.xxyx +iadd r1.xz, r1.xxzx, r7.zzwz +and r7.xyzw, r3.xyzw, l(0x00249249, 0x00249249, 0x00249249, 0x00249249) +iadd r8.xyzw, r7.xyzw, l(0x00db6db6, 0x00db6db6, 0x00db6db6, 0x00db6db6) +and r8.xy, r1.xzxx, r8.xyxx +or r9.xy, r3.xyxx, r4.xzxx +and r10.xyzw, r4.xyzw, l(0x00249249, 0x00249249, 0x00249249, 0x00249249) +or r4.xy, r4.ywyy, r9.xyxx +and r4.xy, r4.xyxx, l(0x00249249, 0x00249249, 0, 0) +xor r4.xy, r4.xyxx, l(0x00249249, 0x00249249, 0, 0) +not r9.xyzw, r10.xyzw +and r10.xyzw, r7.xxyy, r9.xxzz +and r9.xyzw, r9.yyww, r10.xyzw +or r3.xy, r3.xyxx, r4.xyxx +iadd r3.xy, r3.xyxx, l(0xffdb6db7, 0xffdb6db7, 0, 0) +or r3.xy, r9.xwxx, r3.xyxx +ishl r4.xyzw, r9.xyzw, l(2, 1, 2, 1) +or r7.xy, r3.xyxx, r4.xzxx +not r1.xz, r1.xxzx +and r1.xz, r1.xxzx, r7.xxyx +or r1.xz, r8.xxyx, r1.xxzx +iadd r4.xy, r4.ywyy, r4.xzxx +or r3.xy, r3.xyxx, r4.xyxx +movc r4.xy, r0.xyxx, r1.xzxx, r3.xyxx +uge r1.xz, r6.yywy, r6.xxzx +ushr r9.xyzw, r3.zzww, l(1, 2, 1, 2) +and r3.xy, r3.zwzz, r9.xzxx +and r3.xy, r3.xyxx, l(0x00492492, 0x00492492, 0, 0) +ishl r7.xy, r3.xyxx, l(1, 1, 0, 0) +ushr r8.xy, r3.xyxx, l(1, 1, 0, 0) +iadd r3.xy, r3.xyxx, r7.xyxx +iadd r3.xy, r3.xyxx, r8.xyxx +and r7.xy, r3.xyxx, r8.zwzz +or r8.xy, r3.zwzz, r9.xzxx +and r10.xyzw, r9.xyzw, l(0x00249249, 0x00249249, 0x00249249, 0x00249249) +or r8.xy, r9.ywyy, r8.xyxx +and r8.xy, r8.xyxx, l(0x00249249, 0x00249249, 0, 0) +xor r8.xy, r8.xyxx, l(0x00249249, 0x00249249, 0, 0) +not r9.xyzw, r10.xyzw +and r10.xyzw, r7.zzww, r9.xxzz +and r9.xyzw, r9.yyww, r10.xyzw +or r3.zw, r3.zzzw, r8.xxxy +iadd r3.zw, r3.zzzw, l(0, 0, 0xffdb6db7, 0xffdb6db7) +or r3.zw, r9.yyyw, r3.zzzw +ishl r8.xyzw, r9.xyzw, l(2, 1, 2, 1) +or r7.zw, r3.zzzw, r8.xxxz +not r3.xy, r3.xyxx +and r3.xy, r3.xyxx, r7.zwzz +or r3.xy, r7.xyxx, r3.xyxx +iadd r7.xy, r8.ywyy, r8.xzxx +or r3.zw, r3.zzzw, r7.xxxy +movc r4.zw, r1.xxxz, r3.xxxy, r3.zzzw +ushr r3.xyzw, r4.xyzw, l(1, 1, 1, 1) +and r3.xyzw, r4.xyzw, r3.xyzw +and r3.xyzw, r3.xyzw, l(1170, 1170, 1170, 1170) +ishl r7.xyzw, r3.xyzw, l(1, 1, 1, 1) +ushr r8.xyzw, r3.xyzw, l(1, 1, 1, 1) +iadd r3.xyzw, r3.xyzw, r7.xyzw +iadd r3.xyzw, r3.xyzw, r8.xyzw +not r7.xyzw, r3.xxxy +and r8.xyzw, r4.xxxy, r7.zzzw +iadd r9.xyzw, -r8.zzzw, l(2925, 2925, 2925, 2925) +and r7.xyzw, r7.xyzw, r9.xyzw +and r9.xy, r7.zwzz, l(7, 7, 0, 0) +and r9.zw, r8.zzzw, l(0, 0, 7, 7) +imul null, r9.zw, r5.yyyw, r9.zzzw +imad r9.xy, r5.xzxx, r9.xyxx, r9.zwzz +udiv r9.xy, null, r9.xyxx, l(5, 5, 0, 0) +ubfe r10.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r7.xyzw +ubfe r11.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r8.xyzw +imul null, r11.xyzw, r5.yyyw, r11.xyzw +imad r10.xyzw, r5.xxxz, r10.xyzw, r11.xyzw +udiv r10.xyzw, null, r10.xyzw, l(5, 5, 5, 5) +ishl r10.xyzw, r10.xyzw, l(8, 16, 24, 8) +or r7.xy, r9.xyxx, r10.xwxx +or r0.z, r10.y, r7.x +or r0.z, r10.z, r0.z +and r9.xyzw, r3.xyzw, r4.xyzw +ishl r10.xyzw, r9.xxxy, l(5, 10, 15, 5) +and r10.xyzw, r10.xyzw, l(256, 0x00010000, 0x01000000, 256) +bfi r3.xy, l(1, 1, 0, 0), l(0, 0, 0, 0), r9.xyxx, r10.xwxx +iadd r1.w, r10.y, r3.x +iadd r1.w, r10.z, r1.w +imad r0.z, r1.w, l(255), r0.z +not r10.xyzw, r4.xxxy +and r7.xz, r10.zzwz, l(7, 0, 7, 0) +and r11.xyzw, r4.xyzw, l(7, 7, 7, 7) +imul null, r8.xy, r5.ywyy, r11.xyxx +imad r7.xz, r5.xxzx, r7.xxzx, r8.xxyx +udiv r7.xz, null, r7.xxzx, l(7, 0, 7, 0) +ubfe r12.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r10.xyzw +ubfe r13.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r4.xxxy +imul null, r13.xyzw, r5.yyyw, r13.xyzw +imad r12.xyzw, r5.xxxz, r12.xyzw, r13.xyzw +udiv r12.xyzw, null, r12.xyzw, l(7, 7, 7, 7) +ishl r12.xyzw, r12.xyzw, l(8, 16, 24, 8) +or r7.xz, r7.xxzx, r12.xxwx +or r1.w, r12.y, r7.x +or r1.w, r12.z, r1.w +movc r12.x, r0.x, r0.z, r1.w +ubfe r7.xw, l(3, 0, 0, 3), l(6, 0, 0, 9), r7.wwww +ubfe r8.xy, l(3, 3, 0, 0), l(6, 9, 0, 0), r8.wwww +imul null, r8.xy, r5.wwww, r8.xyxx +imad r7.xw, r5.zzzz, r7.xxxw, r8.xxxy +udiv r7.xw, null, r7.xxxw, l(5, 0, 0, 5) +ishl r7.xw, r7.xxxw, l(16, 0, 0, 24) +or r0.z, r7.x, r7.y +or r0.z, r7.w, r0.z +ishl r8.xyzw, r9.yyww, l(10, 15, 10, 15) +and r8.xyzw, r8.xyzw, l(0x00010000, 0x01000000, 0x00010000, 0x01000000) +iadd r1.w, r3.y, r8.x +iadd r1.w, r8.y, r1.w +imad r0.z, r1.w, l(255), r0.z +ubfe r3.xy, l(3, 3, 0, 0), l(6, 9, 0, 0), r10.wwww +ubfe r10.xyzw, l(3, 3, 3, 3), l(6, 9, 6, 9), r4.yyww +imul null, r7.xy, r5.wwww, r10.xyxx +imad r3.xy, r5.zzzz, r3.xyxx, r7.xyxx +udiv r3.xy, null, r3.xyxx, l(7, 7, 0, 0) +ishl r3.xy, r3.xyxx, l(16, 24, 0, 0) +or r1.w, r3.x, r7.z +or r1.w, r3.y, r1.w +movc r12.y, r0.y, r0.z, r1.w +not r3.xyzw, r3.zzzw +and r7.xyzw, r3.zzzw, r4.zzzw +iadd r13.xyzw, -r7.zzzw, l(2925, 2925, 2925, 2925) +and r3.xyzw, r3.xyzw, r13.xyzw +and r8.xy, r3.zwzz, l(7, 7, 0, 0) +and r9.xy, r7.zwzz, l(7, 7, 0, 0) +imul null, r9.xy, r6.ywyy, r9.xyxx +imad r8.xy, r6.xzxx, r8.xyxx, r9.xyxx +udiv r8.xy, null, r8.xyxx, l(5, 5, 0, 0) +ubfe r13.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r3.xyzw +ubfe r14.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r7.xyzw +imul null, r14.xyzw, r6.yyyw, r14.xyzw +imad r13.xyzw, r6.xxxz, r13.xyzw, r14.xyzw +udiv r13.xyzw, null, r13.xyzw, l(5, 5, 5, 5) +ishl r13.xyzw, r13.xyzw, l(8, 16, 24, 8) +or r3.xy, r8.xyxx, r13.xwxx +or r0.z, r13.y, r3.x +or r0.z, r13.z, r0.z +ishl r13.xyzw, r9.zzzw, l(5, 10, 15, 5) +and r13.xyzw, r13.xyzw, l(256, 0x00010000, 0x01000000, 256) +bfi r3.xz, l(1, 0, 1, 0), l(0, 0, 0, 0), r9.zzwz, r13.xxwx +iadd r1.w, r13.y, r3.x +iadd r1.w, r13.z, r1.w +imad r0.z, r1.w, l(255), r0.z +not r9.xyzw, r4.zzzw +and r7.xy, r9.zwzz, l(7, 7, 0, 0) +imul null, r8.xy, r6.ywyy, r11.zwzz +imad r7.xy, r6.xzxx, r7.xyxx, r8.xyxx +udiv r7.xy, null, r7.xyxx, l(7, 7, 0, 0) +ubfe r11.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r9.xyzw +ubfe r13.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r4.zzzw +imul null, r13.xyzw, r6.yyyw, r13.xyzw +imad r11.xyzw, r6.xxxz, r11.xyzw, r13.xyzw +udiv r11.xyzw, null, r11.xyzw, l(7, 7, 7, 7) +ishl r11.xyzw, r11.xyzw, l(8, 16, 24, 8) +or r7.xy, r7.xyxx, r11.xwxx +or r1.w, r11.y, r7.x +or r1.w, r11.z, r1.w +movc r12.z, r1.x, r0.z, r1.w +ubfe r3.xw, l(3, 0, 0, 3), l(6, 0, 0, 9), r3.wwww +ubfe r7.xz, l(3, 0, 3, 0), l(6, 0, 9, 0), r7.wwww +imul null, r7.xz, r6.wwww, r7.xxzx +imad r3.xw, r6.zzzz, r3.xxxw, r7.xxxz +udiv r3.xw, null, r3.xxxw, l(5, 0, 0, 5) +ishl r3.xw, r3.xxxw, l(16, 0, 0, 24) +or r0.z, r3.x, r3.y +or r0.z, r3.w, r0.z +iadd r1.w, r8.z, r3.z +iadd r1.w, r8.w, r1.w +imad r0.z, r1.w, l(255), r0.z +ubfe r3.xy, l(3, 3, 0, 0), l(6, 9, 0, 0), r9.wwww +imul null, r3.zw, r6.wwww, r10.zzzw +imad r3.xy, r6.zzzz, r3.xyxx, r3.zwzz +udiv r3.xy, null, r3.xyxx, l(7, 7, 0, 0) +ishl r3.xy, r3.xyxx, l(16, 24, 0, 0) +or r1.w, r3.x, r7.y +or r1.w, r3.y, r1.w +movc r12.w, r1.z, r0.z, r1.w +store_uav_typed U0[0].xyzw, r0.wwww, r12.xyzw +imad r0.z, vThreadID.y, l(4), l(1) +ult r1.w, r0.z, CB0[0][2].y +if_nz r1.w + iadd r0.w, r1.y, r0.w + ushr r3.xyzw, r4.xyzw, l(12, 12, 12, 12) + ushr r7.xyzw, r3.xyzw, l(1, 1, 1, 1) + and r7.xyzw, r3.xyzw, r7.xyzw + and r7.xyzw, r7.xyzw, l(1170, 1170, 1170, 1170) + ishl r8.xyzw, r7.xyzw, l(1, 1, 1, 1) + ushr r9.xyzw, r7.xyzw, l(1, 1, 1, 1) + iadd r7.xyzw, r7.xyzw, r8.xyzw + iadd r7.xyzw, r7.xyzw, r9.xyzw + not r8.xyzw, r7.xyzw + and r9.xyzw, r3.xyzw, r8.xyzw + iadd r10.xyzw, -r9.xyzw, l(2925, 2925, 2925, 2925) + and r8.xyzw, r8.xyzw, r10.xyzw + and r10.xyzw, r8.xyzw, l(7, 7, 7, 7) + and r11.xyzw, r9.xyzw, l(7, 7, 7, 7) + imul null, r11.xy, r5.ywyy, r11.xyxx + imad r10.xy, r5.xzxx, r10.xyxx, r11.xyxx + udiv r10.xy, null, r10.xyxx, l(5, 5, 0, 0) + ubfe r12.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r8.xxxy + ubfe r13.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r9.xxxy + imul null, r13.xyzw, r5.yyyw, r13.xyzw + imad r12.xyzw, r5.xxxz, r12.xyzw, r13.xyzw + udiv r12.xyzw, null, r12.xyzw, l(5, 5, 5, 5) + ishl r12.xyzw, r12.xyzw, l(8, 16, 24, 8) + or r10.xy, r10.xyxx, r12.xwxx + or r1.w, r12.y, r10.x + or r1.w, r12.z, r1.w + and r7.xyzw, r3.xyzw, r7.xyzw + ishl r12.xyzw, r7.xxxy, l(5, 10, 15, 5) + and r12.xyzw, r12.xyzw, l(256, 0x00010000, 0x01000000, 256) + bfi r11.xy, l(1, 1, 0, 0), l(0, 0, 0, 0), r7.xyxx, r12.xwxx + iadd r7.x, r12.y, r11.x + iadd r7.x, r12.z, r7.x + imad r1.w, r7.x, l(255), r1.w + not r3.xyzw, r3.xyzw + and r12.xyzw, r3.xyzw, l(7, 7, 7, 7) + ubfe r13.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r4.xxxx + imul null, r13.xyzw, r5.yyyy, r13.xyzw + imad r4.x, r5.x, r12.x, r13.x + udiv r4.x, null, r4.x, l(7) + ubfe r14.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r3.xxxy + imad r13.xyz, r5.xxxx, r14.xyzx, r13.yzwy + udiv r13.xyz, null, r13.xyzx, l(7, 7, 7, 0) + ishl r13.xyz, r13.xyzx, l(8, 16, 24, 0) + or r3.x, r4.x, r13.x + or r3.x, r13.y, r3.x + or r3.x, r13.z, r3.x + movc r13.x, r0.x, r1.w, r3.x + ubfe r15.xyzw, l(3, 3, 3, 3), l(6, 9, 3, 6), r8.yyzz + ubfe r16.xyzw, l(3, 3, 3, 3), l(6, 9, 3, 6), r9.yyzz + imul null, r8.xy, r5.wwww, r16.xyxx + imad r8.xy, r5.zzzz, r15.xyxx, r8.xyxx + udiv r8.xy, null, r8.xyxx, l(5, 5, 0, 0) + ishl r8.xy, r8.xyxx, l(16, 24, 0, 0) + or r1.w, r8.x, r10.y + or r1.w, r8.y, r1.w + ishl r17.xyzw, r7.yyzz, l(10, 15, 5, 10) + and r17.xyzw, r17.xyzw, l(0x00010000, 0x01000000, 256, 0x00010000) + iadd r3.x, r11.y, r17.x + iadd r3.x, r17.y, r3.x + imad r1.w, r3.x, l(255), r1.w + ubfe r18.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r4.yyyy + imul null, r18.xyzw, r5.wwww, r18.xyzw + imad r3.x, r5.z, r12.y, r18.x + udiv r3.x, null, r3.x, l(7) + imad r4.x, r5.z, r14.w, r18.y + udiv r4.x, null, r4.x, l(7) + ishl r4.x, r4.x, l(8) + or r3.x, r3.x, r4.x + ubfe r14.xyzw, l(3, 3, 3, 3), l(6, 9, 3, 6), r3.yyzz + imad r4.xy, r5.zzzz, r14.xyxx, r18.zwzz + udiv r4.xy, null, r4.xyxx, l(7, 7, 0, 0) + ishl r4.xy, r4.xyxx, l(16, 24, 0, 0) + or r3.x, r3.x, r4.x + or r3.x, r4.y, r3.x + movc r13.y, r0.y, r1.w, r3.x + imul null, r3.xy, r6.ywyy, r11.zwzz + imad r3.xy, r6.xzxx, r10.zwzz, r3.xyxx + udiv r3.xy, null, r3.xyxx, l(5, 5, 0, 0) + imul null, r4.xy, r6.yyyy, r16.zwzz + imad r4.xy, r6.xxxx, r15.zwzz, r4.xyxx + udiv r4.xy, null, r4.xyxx, l(5, 5, 0, 0) + ishl r4.xy, r4.xyxx, l(8, 16, 0, 0) + or r1.w, r3.x, r4.x + or r1.w, r4.y, r1.w + ubfe r8.xyzw, l(3, 3, 3, 3), l(9, 3, 6, 9), r8.zwww + ubfe r9.xyzw, l(3, 3, 3, 3), l(9, 3, 6, 9), r9.zwww + imul null, r9.xyzw, r6.ywww, r9.xyzw + imad r8.xyzw, r6.xzzz, r8.xyzw, r9.xyzw + udiv r8.xyzw, null, r8.xyzw, l(5, 5, 5, 5) + ishl r8.xyzw, r8.xyzw, l(24, 8, 16, 24) + or r1.w, r1.w, r8.x + bfi r3.x, l(1), l(0), r7.z, r17.z + iadd r3.x, r17.w, r3.x + ishl r9.xyzw, r7.zwww, l(15, 5, 10, 15) + and r9.xyzw, r9.xyzw, l(0x01000000, 256, 0x00010000, 0x01000000) + iadd r3.x, r3.x, r9.x + imad r1.w, r3.x, l(255), r1.w + ubfe r10.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r4.zzzz + imul null, r10.xyzw, r6.yyyy, r10.xyzw + imad r3.x, r6.x, r12.z, r10.x + udiv r3.x, null, r3.x, l(7) + imad r4.xy, r6.xxxx, r14.zwzz, r10.yzyy + udiv r4.xy, null, r4.xyxx, l(7, 7, 0, 0) + ishl r4.xy, r4.xyxx, l(8, 16, 0, 0) + or r3.x, r3.x, r4.x + or r3.x, r4.y, r3.x + ubfe r11.xyzw, l(3, 3, 3, 3), l(9, 3, 6, 9), r3.zwww + imad r3.z, r6.x, r11.x, r10.w + udiv r3.z, null, r3.z, l(7) + ishl r3.z, r3.z, l(24) + or r3.x, r3.z, r3.x + movc r13.z, r1.x, r1.w, r3.x + or r1.w, r3.y, r8.y + or r1.w, r8.z, r1.w + or r1.w, r8.w, r1.w + bfi r3.x, l(1), l(0), r7.w, r9.y + iadd r3.x, r9.z, r3.x + iadd r3.x, r9.w, r3.x + imad r1.w, r3.x, l(255), r1.w + ubfe r3.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r4.wwww + imul null, r3.xyzw, r3.xyzw, r6.wwww + imad r3.x, r6.z, r12.w, r3.x + imad r3.yzw, r6.zzzz, r11.yyzw, r3.yyzw + udiv r3.xyzw, null, r3.xyzw, l(7, 7, 7, 7) + ishl r3.yzw, r3.yyzw, l(0, 8, 16, 24) + or r3.x, r3.y, r3.x + or r3.x, r3.z, r3.x + or r3.x, r3.w, r3.x + movc r13.w, r1.z, r1.w, r3.x + store_uav_typed U0[0].xyzw, r0.wwww, r13.xyzw + iadd r0.z, r0.z, l(1) + ult r1.w, r0.z, CB0[0][2].y + if_nz r1.w + iadd r0.w, r1.y, r0.w + ushr r2.xyzw, r2.xyzw, l(8, 8, 8, 8) + ushr r3.xyzw, r2.xxyy, l(1, 2, 1, 2) + and r4.xy, r2.xyxx, r3.xzxx + and r4.xy, r4.xyxx, l(0x00492492, 0x00492492, 0, 0) + ishl r4.zw, r4.xxxy, l(0, 0, 1, 1) + ushr r7.xy, r4.xyxx, l(1, 1, 0, 0) + iadd r4.xy, r4.xyxx, r4.zwzz + iadd r4.xy, r4.xyxx, r7.xyxx + and r7.xyzw, r2.xyzw, l(0x00249249, 0x00249249, 0x00249249, 0x00249249) + iadd r8.xyzw, r7.xyzw, l(0x00db6db6, 0x00db6db6, 0x00db6db6, 0x00db6db6) + and r4.zw, r4.xxxy, r8.xxxy + or r8.xy, r2.xyxx, r3.xzxx + and r9.xyzw, r3.xyzw, l(0x00249249, 0x00249249, 0x00249249, 0x00249249) + or r3.xy, r3.ywyy, r8.xyxx + and r3.xy, r3.xyxx, l(0x00249249, 0x00249249, 0, 0) + xor r3.xy, r3.xyxx, l(0x00249249, 0x00249249, 0, 0) + not r9.xyzw, r9.xyzw + and r10.xyzw, r7.xxyy, r9.xxzz + and r9.xyzw, r9.yyww, r10.xyzw + or r2.xy, r2.xyxx, r3.xyxx + iadd r2.xy, r2.xyxx, l(0xffdb6db7, 0xffdb6db7, 0, 0) + or r2.xy, r9.xwxx, r2.xyxx + ishl r3.xyzw, r9.xyzw, l(2, 1, 2, 1) + or r7.xy, r2.xyxx, r3.xzxx + not r4.xy, r4.xyxx + and r4.xy, r4.xyxx, r7.xyxx + or r4.xy, r4.zwzz, r4.xyxx + iadd r3.xy, r3.ywyy, r3.xzxx + or r2.xy, r2.xyxx, r3.xyxx + movc r3.xy, r0.xyxx, r4.xyxx, r2.xyxx + ushr r4.xyzw, r2.zzww, l(1, 2, 1, 2) + and r2.xy, r2.zwzz, r4.xzxx + and r2.xy, r2.xyxx, l(0x00492492, 0x00492492, 0, 0) + ishl r7.xy, r2.xyxx, l(1, 1, 0, 0) + ushr r8.xy, r2.xyxx, l(1, 1, 0, 0) + iadd r2.xy, r2.xyxx, r7.xyxx + iadd r2.xy, r2.xyxx, r8.xyxx + and r7.xy, r2.xyxx, r8.zwzz + or r8.xy, r2.zwzz, r4.xzxx + and r9.xyzw, r4.xyzw, l(0x00249249, 0x00249249, 0x00249249, 0x00249249) + or r4.xy, r4.ywyy, r8.xyxx + and r4.xy, r4.xyxx, l(0x00249249, 0x00249249, 0, 0) + xor r4.xy, r4.xyxx, l(0x00249249, 0x00249249, 0, 0) + not r8.xyzw, r9.xyzw + and r9.xyzw, r7.zzww, r8.xxzz + and r8.xyzw, r8.yyww, r9.xyzw + or r2.zw, r2.zzzw, r4.xxxy + iadd r2.zw, r2.zzzw, l(0, 0, 0xffdb6db7, 0xffdb6db7) + or r2.zw, r8.yyyw, r2.zzzw + ishl r4.xyzw, r8.xyzw, l(2, 1, 2, 1) + or r7.zw, r2.zzzw, r4.xxxz + not r2.xy, r2.xyxx + and r2.xy, r2.xyxx, r7.zwzz + or r2.xy, r7.xyxx, r2.xyxx + iadd r4.xy, r4.ywyy, r4.xzxx + or r2.zw, r2.zzzw, r4.xxxy + movc r3.zw, r1.xxxz, r2.xxxy, r2.zzzw + ushr r2.xyzw, r3.xyzw, l(1, 1, 1, 1) + and r2.xyzw, r3.xyzw, r2.xyzw + and r2.xyzw, r2.xyzw, l(1170, 1170, 1170, 1170) + ishl r4.xyzw, r2.xyzw, l(1, 1, 1, 1) + ushr r7.xyzw, r2.xyzw, l(1, 1, 1, 1) + iadd r2.xyzw, r2.xyzw, r4.xyzw + iadd r2.xyzw, r2.xyzw, r7.xyzw + not r4.xyzw, r2.xxxy + and r7.xyzw, r3.xxxy, r4.zzzw + iadd r8.xyzw, -r7.zzzw, l(2925, 2925, 2925, 2925) + and r4.xyzw, r4.xyzw, r8.xyzw + and r8.xy, r4.zwzz, l(7, 7, 0, 0) + and r8.zw, r7.zzzw, l(0, 0, 7, 7) + imul null, r8.zw, r5.yyyw, r8.zzzw + imad r8.xy, r5.xzxx, r8.xyxx, r8.zwzz + udiv r8.xy, null, r8.xyxx, l(5, 5, 0, 0) + ubfe r9.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r4.xyzw + ubfe r10.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r7.xyzw + imul null, r10.xyzw, r5.yyyw, r10.xyzw + imad r9.xyzw, r5.xxxz, r9.xyzw, r10.xyzw + udiv r9.xyzw, null, r9.xyzw, l(5, 5, 5, 5) + ishl r9.xyzw, r9.xyzw, l(8, 16, 24, 8) + or r4.xy, r8.xyxx, r9.xwxx + or r1.w, r9.y, r4.x + or r1.w, r9.z, r1.w + and r8.xyzw, r2.xyzw, r3.xyzw + ishl r9.xyzw, r8.xxxy, l(5, 10, 15, 5) + and r9.xyzw, r9.xyzw, l(256, 0x00010000, 0x01000000, 256) + bfi r2.xy, l(1, 1, 0, 0), l(0, 0, 0, 0), r8.xyxx, r9.xwxx + iadd r2.x, r9.y, r2.x + iadd r2.x, r9.z, r2.x + imad r1.w, r2.x, l(255), r1.w + not r9.xyzw, r3.xxxy + and r4.xz, r9.zzwz, l(7, 0, 7, 0) + and r10.xyzw, r3.xyzw, l(7, 7, 7, 7) + imul null, r7.xy, r5.ywyy, r10.xyxx + imad r4.xz, r5.xxzx, r4.xxzx, r7.xxyx + udiv r4.xz, null, r4.xxzx, l(7, 0, 7, 0) + ubfe r11.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r9.xyzw + ubfe r12.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r3.xxxy + imul null, r12.xyzw, r5.yyyw, r12.xyzw + imad r11.xyzw, r5.xxxz, r11.xyzw, r12.xyzw + udiv r11.xyzw, null, r11.xyzw, l(7, 7, 7, 7) + ishl r11.xyzw, r11.xyzw, l(8, 16, 24, 8) + or r4.xz, r4.xxzx, r11.xxwx + or r2.x, r11.y, r4.x + or r2.x, r11.z, r2.x + movc r11.x, r0.x, r1.w, r2.x + ubfe r4.xw, l(3, 0, 0, 3), l(6, 0, 0, 9), r4.wwww + ubfe r7.xy, l(3, 3, 0, 0), l(6, 9, 0, 0), r7.wwww + imul null, r7.xy, r5.wwww, r7.xyxx + imad r4.xw, r5.zzzz, r4.xxxw, r7.xxxy + udiv r4.xw, null, r4.xxxw, l(5, 0, 0, 5) + ishl r4.xw, r4.xxxw, l(16, 0, 0, 24) + or r1.w, r4.x, r4.y + or r1.w, r4.w, r1.w + ishl r7.xyzw, r8.yyww, l(10, 15, 10, 15) + and r7.xyzw, r7.xyzw, l(0x00010000, 0x01000000, 0x00010000, 0x01000000) + iadd r2.x, r2.y, r7.x + iadd r2.x, r7.y, r2.x + imad r1.w, r2.x, l(255), r1.w + ubfe r2.xy, l(3, 3, 0, 0), l(6, 9, 0, 0), r9.wwww + ubfe r9.xyzw, l(3, 3, 3, 3), l(6, 9, 6, 9), r3.yyww + imul null, r4.xy, r5.wwww, r9.xyxx + imad r2.xy, r5.zzzz, r2.xyxx, r4.xyxx + udiv r2.xy, null, r2.xyxx, l(7, 7, 0, 0) + ishl r2.xy, r2.xyxx, l(16, 24, 0, 0) + or r2.x, r2.x, r4.z + or r2.x, r2.y, r2.x + movc r11.y, r0.y, r1.w, r2.x + not r2.xyzw, r2.zzzw + and r4.xyzw, r2.zzzw, r3.zzzw + iadd r12.xyzw, -r4.zzzw, l(2925, 2925, 2925, 2925) + and r2.xyzw, r2.xyzw, r12.xyzw + and r7.xy, r2.zwzz, l(7, 7, 0, 0) + and r8.xy, r4.zwzz, l(7, 7, 0, 0) + imul null, r8.xy, r6.ywyy, r8.xyxx + imad r7.xy, r6.xzxx, r7.xyxx, r8.xyxx + udiv r7.xy, null, r7.xyxx, l(5, 5, 0, 0) + ubfe r12.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r2.xyzw + ubfe r13.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r4.xyzw + imul null, r13.xyzw, r6.yyyw, r13.xyzw + imad r12.xyzw, r6.xxxz, r12.xyzw, r13.xyzw + udiv r12.xyzw, null, r12.xyzw, l(5, 5, 5, 5) + ishl r12.xyzw, r12.xyzw, l(8, 16, 24, 8) + or r2.xy, r7.xyxx, r12.xwxx + or r1.w, r12.y, r2.x + or r1.w, r12.z, r1.w + ishl r12.xyzw, r8.zzzw, l(5, 10, 15, 5) + and r12.xyzw, r12.xyzw, l(256, 0x00010000, 0x01000000, 256) + bfi r2.xz, l(1, 0, 1, 0), l(0, 0, 0, 0), r8.zzwz, r12.xxwx + iadd r2.x, r12.y, r2.x + iadd r2.x, r12.z, r2.x + imad r1.w, r2.x, l(255), r1.w + not r8.xyzw, r3.zzzw + and r4.xy, r8.zwzz, l(7, 7, 0, 0) + imul null, r7.xy, r6.ywyy, r10.zwzz + imad r4.xy, r6.xzxx, r4.xyxx, r7.xyxx + udiv r4.xy, null, r4.xyxx, l(7, 7, 0, 0) + ubfe r10.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r8.xyzw + ubfe r12.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r3.zzzw + imul null, r12.xyzw, r6.yyyw, r12.xyzw + imad r10.xyzw, r6.xxxz, r10.xyzw, r12.xyzw + udiv r10.xyzw, null, r10.xyzw, l(7, 7, 7, 7) + ishl r10.xyzw, r10.xyzw, l(8, 16, 24, 8) + or r4.xy, r4.xyxx, r10.xwxx + or r2.x, r10.y, r4.x + or r2.x, r10.z, r2.x + movc r11.z, r1.x, r1.w, r2.x + ubfe r2.xw, l(3, 0, 0, 3), l(6, 0, 0, 9), r2.wwww + ubfe r4.xz, l(3, 0, 3, 0), l(6, 0, 9, 0), r4.wwww + imul null, r4.xz, r4.xxzx, r6.wwww + imad r2.xw, r6.zzzz, r2.xxxw, r4.xxxz + udiv r2.xw, null, r2.xxxw, l(5, 0, 0, 5) + ishl r2.xw, r2.xxxw, l(16, 0, 0, 24) + or r1.w, r2.x, r2.y + or r1.w, r2.w, r1.w + iadd r2.x, r7.z, r2.z + iadd r2.x, r7.w, r2.x + imad r1.w, r2.x, l(255), r1.w + ubfe r2.xy, l(3, 3, 0, 0), l(6, 9, 0, 0), r8.wwww + imul null, r2.zw, r6.wwww, r9.zzzw + imad r2.xy, r6.zzzz, r2.xyxx, r2.zwzz + udiv r2.xy, null, r2.xyxx, l(7, 7, 0, 0) + ishl r2.xy, r2.xyxx, l(16, 24, 0, 0) + or r2.x, r2.x, r4.y + or r2.x, r2.y, r2.x + movc r11.w, r1.z, r1.w, r2.x + store_uav_typed U0[0].xyzw, r0.wwww, r11.xyzw + or r0.z, r0.z, l(3) + ult r0.z, r0.z, CB0[0][2].y + if_nz r0.z + iadd r0.z, r1.y, r0.w + ushr r2.xyzw, r3.xyzw, l(12, 12, 12, 12) + ushr r4.xyzw, r2.xyzw, l(1, 1, 1, 1) + and r4.xyzw, r2.xyzw, r4.xyzw + and r4.xyzw, r4.xyzw, l(1170, 1170, 1170, 1170) + ishl r7.xyzw, r4.xyzw, l(1, 1, 1, 1) + ushr r8.xyzw, r4.xyzw, l(1, 1, 1, 1) + iadd r4.xyzw, r4.xyzw, r7.xyzw + iadd r4.xyzw, r4.xyzw, r8.xyzw + not r7.xyzw, r4.xyzw + and r8.xyzw, r2.xyzw, r7.xyzw + iadd r9.xyzw, -r8.xyzw, l(2925, 2925, 2925, 2925) + and r7.xyzw, r7.xyzw, r9.xyzw + and r9.xyzw, r7.xyzw, l(7, 7, 7, 7) + and r10.xyzw, r8.xyzw, l(7, 7, 7, 7) + imul null, r1.yw, r5.yyyw, r10.xxxy + imad r1.yw, r5.xxxz, r9.xxxy, r1.yyyw + udiv r1.yw, null, r1.yyyw, l(0, 5, 0, 5) + ubfe r11.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r7.xxxy + ubfe r12.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r8.xxxy + imul null, r12.xyzw, r5.yyyw, r12.xyzw + imad r11.xyzw, r5.xxxz, r11.xyzw, r12.xyzw + udiv r11.xyzw, null, r11.xyzw, l(5, 5, 5, 5) + ishl r11.xyzw, r11.xyzw, l(8, 16, 24, 8) + or r1.yw, r1.yyyw, r11.xxxw + or r0.w, r11.y, r1.y + or r0.w, r11.z, r0.w + and r4.xyzw, r2.xyzw, r4.xyzw + ishl r11.xyzw, r4.xxxy, l(5, 10, 15, 5) + and r11.xyzw, r11.xyzw, l(256, 0x00010000, 0x01000000, 256) + bfi r9.xy, l(1, 1, 0, 0), l(0, 0, 0, 0), r4.xyxx, r11.xwxx + iadd r1.y, r11.y, r9.x + iadd r1.y, r11.z, r1.y + imad r0.w, r1.y, l(255), r0.w + not r2.xyzw, r2.xyzw + and r11.xyzw, r2.xyzw, l(7, 7, 7, 7) + ubfe r12.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r3.xxxx + imul null, r12.xyzw, r5.yyyy, r12.xyzw + imad r1.y, r5.x, r11.x, r12.x + udiv r1.y, null, r1.y, l(7) + ubfe r13.xyzw, l(3, 3, 3, 3), l(3, 6, 9, 3), r2.xxxy + imad r12.xyz, r5.xxxx, r13.xyzx, r12.yzwy + udiv r12.xyz, null, r12.xyzx, l(7, 7, 7, 0) + ishl r12.xyz, r12.xyzx, l(8, 16, 24, 0) + or r1.y, r1.y, r12.x + or r1.y, r12.y, r1.y + or r1.y, r12.z, r1.y + movc r12.x, r0.x, r0.w, r1.y + ubfe r14.xyzw, l(3, 3, 3, 3), l(6, 9, 3, 6), r7.yyzz + ubfe r15.xyzw, l(3, 3, 3, 3), l(6, 9, 3, 6), r8.yyzz + imul null, r0.xw, r5.wwww, r15.xxxy + imad r0.xw, r5.zzzz, r14.xxxy, r0.xxxw + udiv r0.xw, null, r0.xxxw, l(5, 0, 0, 5) + ishl r0.xw, r0.xxxw, l(16, 0, 0, 24) + or r0.x, r0.x, r1.w + or r0.x, r0.w, r0.x + ishl r16.xyzw, r4.yyzz, l(10, 15, 5, 10) + and r16.xyzw, r16.xyzw, l(0x00010000, 0x01000000, 256, 0x00010000) + iadd r0.w, r9.y, r16.x + iadd r0.w, r16.y, r0.w + imad r0.x, r0.w, l(255), r0.x + ubfe r17.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r3.yyyy + imul null, r17.xyzw, r5.wwww, r17.xyzw + imad r0.w, r5.z, r11.y, r17.x + udiv r0.w, null, r0.w, l(7) + imad r1.y, r5.z, r13.w, r17.y + udiv r1.y, null, r1.y, l(7) + ishl r1.y, r1.y, l(8) + or r0.w, r0.w, r1.y + ubfe r13.xyzw, l(3, 3, 3, 3), l(6, 9, 3, 6), r2.yyzz + imad r1.yw, r5.zzzz, r13.xxxy, r17.zzzw + udiv r1.yw, null, r1.yyyw, l(0, 7, 0, 7) + ishl r1.yw, r1.yyyw, l(0, 16, 0, 24) + or r0.w, r0.w, r1.y + or r0.w, r1.w, r0.w + movc r12.y, r0.y, r0.x, r0.w + imul null, r0.xy, r6.ywyy, r10.zwzz + imad r0.xy, r6.xzxx, r9.zwzz, r0.xyxx + udiv r0.xy, null, r0.xyxx, l(5, 5, 0, 0) + imul null, r1.yw, r6.yyyy, r15.zzzw + imad r1.yw, r6.xxxx, r14.zzzw, r1.yyyw + udiv r1.yw, null, r1.yyyw, l(0, 5, 0, 5) + ishl r1.yw, r1.yyyw, l(0, 8, 0, 16) + or r0.x, r0.x, r1.y + or r0.x, r1.w, r0.x + ubfe r5.xyzw, l(3, 3, 3, 3), l(9, 3, 6, 9), r7.zwww + ubfe r7.xyzw, l(3, 3, 3, 3), l(9, 3, 6, 9), r8.zwww + imul null, r7.xyzw, r6.ywww, r7.xyzw + imad r5.xyzw, r6.xzzz, r5.xyzw, r7.xyzw + udiv r5.xyzw, null, r5.xyzw, l(5, 5, 5, 5) + ishl r5.xyzw, r5.xyzw, l(24, 8, 16, 24) + or r0.x, r0.x, r5.x + bfi r0.w, l(1), l(0), r4.z, r16.z + iadd r0.w, r16.w, r0.w + ishl r7.xyzw, r4.zwww, l(15, 5, 10, 15) + and r7.xyzw, r7.xyzw, l(0x01000000, 256, 0x00010000, 0x01000000) + iadd r0.w, r0.w, r7.x + imad r0.x, r0.w, l(255), r0.x + ubfe r8.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r3.zzzz + imul null, r8.xyzw, r6.yyyy, r8.xyzw + imad r0.w, r6.x, r11.z, r8.x + udiv r0.w, null, r0.w, l(7) + imad r1.yw, r6.xxxx, r13.zzzw, r8.yyyz + udiv r1.yw, null, r1.yyyw, l(0, 7, 0, 7) + ishl r1.yw, r1.yyyw, l(0, 8, 0, 16) + or r0.w, r0.w, r1.y + or r0.w, r1.w, r0.w + ubfe r2.xyzw, l(3, 3, 3, 3), l(9, 3, 6, 9), r2.zwww + imad r1.y, r6.x, r2.x, r8.w + udiv r1.y, null, r1.y, l(7) + ishl r1.y, r1.y, l(24) + or r0.w, r0.w, r1.y + movc r12.z, r1.x, r0.x, r0.w + or r0.x, r0.y, r5.y + or r0.x, r5.z, r0.x + or r0.x, r5.w, r0.x + bfi r0.y, l(1), l(0), r4.w, r7.y + iadd r0.y, r7.z, r0.y + iadd r0.y, r7.w, r0.y + imad r0.x, r0.y, l(255), r0.x + ubfe r3.xyzw, l(3, 3, 3, 3), l(12, 15, 18, 21), r3.wwww + imul null, r3.xyzw, r3.xyzw, r6.wwww + imad r0.y, r6.z, r11.w, r3.x + udiv r0.y, null, r0.y, l(7) + imad r1.xyw, r6.zzzz, r2.yzyw, r3.yzyw + udiv r1.xyw, null, r1.xyxw, l(7, 7, 0, 7) + ishl r1.xyw, r1.xyxw, l(8, 16, 0, 24) + or r0.y, r0.y, r1.x + or r0.y, r1.y, r0.y + or r0.y, r1.w, r0.y + movc r12.w, r1.z, r0.x, r0.y + store_uav_typed U0[0].xyzw, r0.zzzz, r12.xyzw + endif + endif +endif +ret +// Approximately 765 instruction slots used +#endif + +const BYTE texture_load_dxt5a_r8_cs[] = { + 68, 88, 66, 67, 198, 160, 226, 253, 226, 47, 241, 236, 103, 60, 221, 49, 250, 252, 202, + 62, 1, 0, 0, 0, 252, 111, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 96, 111, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 36, 107, 0, + 0, 81, 0, 5, 0, 201, 26, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 19, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 35, 0, 0, 10, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 130, 0, + 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 9, 34, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, + 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 114, + 0, 16, 0, 2, 0, 0, 0, 150, 5, 2, 0, 2, 64, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, 194, 0, 16, + 0, 1, 0, 0, 0, 246, 139, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, + 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 139, 0, 0, 14, 146, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 27, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 2, 0, + 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, + 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 11, + 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 48, 0, 0, 140, 0, 0, 11, 66, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 9, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 19, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 11, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 2, + 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, + 0, 140, 0, 0, 16, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, + 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 2, 0, + 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, + 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, 66, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, + 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, + 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 140, 0, 0, 17, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 14, 194, 0, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, + 0, 0, 0, 6, 0, 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, + 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 85, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 9, 82, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, + 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 10, 82, 0, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 128, 3, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 22, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 18, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, + 0, 3, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 3, 0, 0, 0, 6, 0, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 3, 0, 0, 0, 140, + 0, 0, 17, 98, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 22, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 13, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, + 0, 0, 86, 6, 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 3, + 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, 3, 0, 0, + 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, + 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 41, 0, 0, 7, + 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, 0, + 0, 0, 0, 0, 86, 13, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, + 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 214, 120, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 210, 0, 16, 0, 1, 0, 0, 0, + 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, 1, 0, + 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 31, + 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, + 3, 0, 0, 0, 38, 7, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 38, 7, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 214, 8, 16, 0, 3, 0, 0, + 0, 214, 8, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, + 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 38, + 7, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 214, 8, 16, 0, 3, 0, 0, 0, + 54, 0, 0, 5, 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, + 0, 18, 0, 0, 1, 54, 0, 0, 5, 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, + 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 55, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, + 0, 8, 242, 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 214, + 120, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, + 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 38, 7, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, + 0, 38, 7, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 4, 0, 0, 0, 214, 8, 16, 0, 5, 0, 0, 0, 214, 8, 16, 0, 6, 0, + 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 38, 7, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 140, 0, 0, 17, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 214, 8, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 194, 0, 16, + 0, 2, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 18, 0, 0, 1, 54, 0, + 0, 5, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 21, + 0, 0, 1, 85, 0, 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 134, 13, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, + 0, 0, 0, 255, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, + 230, 10, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, + 0, 0, 38, 7, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, + 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, + 4, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 20, 242, + 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 80, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, + 0, 214, 5, 16, 0, 5, 0, 0, 0, 134, 0, 16, 0, 5, 0, 0, 0, 85, 0, + 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 6, 5, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, + 1, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, + 0, 6, 2, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 1, 0, + 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 146, 36, 73, 0, 0, + 0, 0, 0, 146, 36, 73, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, + 7, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 194, 0, + 16, 0, 7, 0, 0, 0, 6, 8, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, + 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 6, 1, 16, + 0, 7, 0, 0, 0, 30, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, + 16, 0, 1, 0, 0, 0, 166, 11, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 73, 146, 36, 0, 73, 146, 36, 0, 73, 146, 36, 0, 73, 146, 36, 0, 30, 0, 0, + 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 182, 109, 219, 0, 182, 109, 219, 0, 182, 109, 219, 0, 182, 109, 219, 0, 1, + 0, 0, 7, 50, 0, 16, 0, 8, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, + 70, 0, 16, 0, 8, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 9, 0, 0, + 0, 70, 0, 16, 0, 3, 0, 0, 0, 134, 0, 16, 0, 4, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 73, 146, 36, 0, 73, 146, 36, 0, 73, 146, 36, 0, 73, 146, 36, 0, + 60, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 214, 5, 16, 0, 4, 0, 0, + 0, 70, 0, 16, 0, 9, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 4, 0, + 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 73, 146, 36, 0, 73, + 146, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 10, 50, 0, 16, 0, + 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 73, 146, 36, + 0, 73, 146, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 5, 242, 0, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 1, 0, 0, 7, 242, + 0, 16, 0, 10, 0, 0, 0, 6, 5, 16, 0, 7, 0, 0, 0, 6, 10, 16, 0, + 9, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 86, 15, 16, + 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 60, 0, 0, 7, 50, 0, + 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 4, + 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 183, 109, 219, 255, 183, 109, 219, 255, 0, 0, 0, + 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 198, 0, + 16, 0, 9, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, + 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, + 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, + 7, 50, 0, 16, 0, 7, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 134, 0, + 16, 0, 4, 0, 0, 0, 59, 0, 0, 5, 82, 0, 16, 0, 1, 0, 0, 0, 6, + 2, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 7, 0, 0, 0, 60, 0, 0, + 7, 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 8, 0, 0, 0, 6, 2, + 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 214, + 5, 16, 0, 4, 0, 0, 0, 134, 0, 16, 0, 4, 0, 0, 0, 60, 0, 0, 7, + 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 55, 0, 0, 9, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 3, + 0, 0, 0, 80, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 86, 7, 16, 0, + 6, 0, 0, 0, 6, 2, 16, 0, 6, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, + 0, 9, 0, 0, 0, 166, 15, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 7, 50, + 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 134, 0, 16, 0, + 9, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 146, 36, 73, 0, 146, 36, 73, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 7, 0, 0, 0, 70, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 8, 0, 0, + 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 3, + 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, + 30, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, + 0, 70, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 7, 50, 0, 16, 0, 7, 0, + 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 8, 0, 0, 0, 60, + 0, 0, 7, 50, 0, 16, 0, 8, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, + 134, 0, 16, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 73, 146, 36, 0, 73, 146, + 36, 0, 73, 146, 36, 0, 73, 146, 36, 0, 60, 0, 0, 7, 50, 0, 16, 0, 8, + 0, 0, 0, 214, 5, 16, 0, 9, 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, + 1, 0, 0, 10, 50, 0, 16, 0, 8, 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, + 0, 2, 64, 0, 0, 73, 146, 36, 0, 73, 146, 36, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 87, 0, 0, 10, 50, 0, 16, 0, 8, 0, 0, 0, 70, 0, 16, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 73, 146, 36, 0, 73, 146, 36, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 59, 0, 0, 5, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 166, 15, + 16, 0, 7, 0, 0, 0, 6, 10, 16, 0, 9, 0, 0, 0, 1, 0, 0, 7, 242, + 0, 16, 0, 9, 0, 0, 0, 86, 15, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, + 0, 3, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 30, 0, 0, 10, 194, 0, + 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 183, 109, 219, 255, 183, 109, 219, 255, 60, 0, 0, 7, + 194, 0, 16, 0, 3, 0, 0, 0, 86, 13, 16, 0, 9, 0, 0, 0, 166, 14, 16, + 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, + 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 7, 0, 0, 0, + 166, 14, 16, 0, 3, 0, 0, 0, 6, 8, 16, 0, 8, 0, 0, 0, 59, 0, 0, + 5, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 1, 0, + 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 230, + 10, 16, 0, 7, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, + 70, 0, 16, 0, 7, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, + 7, 50, 0, 16, 0, 7, 0, 0, 0, 214, 5, 16, 0, 8, 0, 0, 0, 134, 0, + 16, 0, 8, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 3, 0, 0, 0, 166, + 14, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 55, 0, 0, 9, + 194, 0, 16, 0, 4, 0, 0, 0, 6, 8, 16, 0, 1, 0, 0, 0, 6, 4, 16, + 0, 3, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 85, 0, 0, 10, 242, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 146, 4, 0, 0, 146, 4, 0, 0, 146, + 4, 0, 0, 146, 4, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 8, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 59, 0, 0, 5, 242, 0, 16, 0, 7, + 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, + 8, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 7, 0, 0, + 0, 30, 0, 0, 11, 242, 0, 16, 0, 9, 0, 0, 0, 166, 14, 16, 128, 65, 0, + 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, 109, + 11, 0, 0, 109, 11, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 1, 0, 0, + 10, 50, 0, 16, 0, 9, 0, 0, 0, 230, 10, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 10, 194, 0, 16, 0, 9, 0, 0, 0, 166, 14, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 38, 0, 0, 8, 0, 208, 0, 0, 194, 0, 16, 0, 9, 0, 0, 0, 86, 13, + 16, 0, 5, 0, 0, 0, 166, 14, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 50, + 0, 16, 0, 9, 0, 0, 0, 134, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, + 9, 0, 0, 0, 230, 10, 16, 0, 9, 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, + 0, 9, 0, 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 9, 0, 0, 0, 2, 64, + 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, + 0, 0, 15, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, 0, 7, 0, + 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 8, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 11, 0, + 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 35, + 0, 0, 9, 242, 0, 16, 0, 10, 0, 0, 0, 6, 8, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 78, 0, 0, + 11, 242, 0, 16, 0, 10, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, + 0, 8, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 7, 0, 0, 0, 70, 0, + 16, 0, 9, 0, 0, 0, 198, 0, 16, 0, 10, 0, 0, 0, 60, 0, 0, 7, 66, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, + 7, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 10, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 242, 0, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, + 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 6, 4, 16, 0, + 9, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 15, 0, 0, + 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 9, 0, 0, 0, 198, 0, 16, 0, 10, 0, 0, 0, 30, + 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, + 10, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 255, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 59, 0, 0, 5, + 242, 0, 16, 0, 10, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 1, 0, 0, + 10, 82, 0, 16, 0, 7, 0, 0, 0, 166, 11, 16, 0, 10, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 8, 0, 0, 0, 214, 5, + 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 82, + 0, 16, 0, 7, 0, 0, 0, 6, 2, 16, 0, 5, 0, 0, 0, 6, 2, 16, 0, + 7, 0, 0, 0, 6, 1, 16, 0, 8, 0, 0, 0, 78, 0, 0, 11, 82, 0, 16, + 0, 7, 0, 0, 0, 0, 208, 0, 0, 6, 2, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 138, + 0, 0, 15, 242, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 6, 4, 16, + 0, 4, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 13, 0, + 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 35, + 0, 0, 9, 242, 0, 16, 0, 12, 0, 0, 0, 6, 8, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 78, 0, 0, + 11, 242, 0, 16, 0, 12, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 12, 0, + 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, + 0, 8, 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, 7, 0, 0, 0, 6, 2, + 16, 0, 7, 0, 0, 0, 6, 3, 16, 0, 12, 0, 0, 0, 60, 0, 0, 7, 130, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, + 7, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, + 0, 12, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 55, 0, 0, 9, 18, 0, + 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 138, 0, 0, 15, 146, 0, 16, 0, + 7, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 246, 15, 16, 0, 7, 0, 0, 0, 138, 0, 0, 15, 50, + 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 8, 0, 0, 0, 38, 0, + 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 8, 0, 0, 0, 246, 15, 16, 0, 5, + 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 35, 0, 0, 9, 146, 0, 16, 0, + 7, 0, 0, 0, 166, 10, 16, 0, 5, 0, 0, 0, 6, 12, 16, 0, 7, 0, 0, + 0, 6, 4, 16, 0, 8, 0, 0, 0, 78, 0, 0, 11, 146, 0, 16, 0, 7, 0, + 0, 0, 0, 208, 0, 0, 6, 12, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, + 146, 0, 16, 0, 7, 0, 0, 0, 6, 12, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 60, 0, + 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 26, + 0, 16, 0, 7, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 10, 242, 0, 16, 0, 8, 0, 0, 0, 86, 15, 16, 0, 9, 0, 0, 0, 2, 64, + 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, + 1, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 255, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 138, 0, + 0, 15, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 10, 0, 0, + 0, 138, 0, 0, 15, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 6, + 0, 0, 0, 9, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 86, 15, 16, 0, + 4, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 7, 0, 0, + 0, 246, 15, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 10, 0, 0, 0, 35, 0, + 0, 9, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 5, 0, 0, 0, 70, + 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 78, 0, 0, 11, + 50, 0, 16, 0, 3, 0, 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, + 0, 3, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 60, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 59, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 3, 0, + 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 166, 14, 16, 0, 3, + 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 30, 0, 0, 11, 242, 0, 16, 0, + 13, 0, 0, 0, 166, 14, 16, 128, 65, 0, 0, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 109, 11, 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, 1, 0, + 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 13, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 8, 0, 0, 0, + 230, 10, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 9, 0, + 0, 0, 230, 10, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 50, 0, 16, 0, 9, 0, 0, 0, 214, 5, 16, 0, 6, 0, 0, 0, 70, 0, 16, + 0, 9, 0, 0, 0, 35, 0, 0, 9, 50, 0, 16, 0, 8, 0, 0, 0, 134, 0, + 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 70, 0, 16, 0, 9, + 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, 0, 8, 0, 0, 0, 0, 208, 0, 0, + 70, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 13, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, + 0, 14, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, + 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 38, 0, 0, 8, + 0, 208, 0, 0, 242, 0, 16, 0, 14, 0, 0, 0, 86, 13, 16, 0, 6, 0, 0, + 0, 70, 14, 16, 0, 14, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 13, 0, + 0, 0, 6, 8, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 70, + 14, 16, 0, 14, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 13, 0, 0, 0, + 0, 208, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, + 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 242, 0, + 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 60, 0, 0, 7, + 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 198, 0, 16, + 0, 13, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 13, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 66, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 13, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 166, 14, 16, + 0, 9, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 15, 0, + 0, 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 70, + 14, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 1, 0, 1, 0, 0, 140, 0, 0, 17, 82, 0, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 166, 11, 16, 0, 9, 0, 0, 0, 6, 3, 16, 0, 13, 0, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, + 0, 10, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 35, + 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 255, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 59, 0, 0, + 5, 242, 0, 16, 0, 9, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 1, 0, + 0, 10, 50, 0, 16, 0, 7, 0, 0, 0, 230, 10, 16, 0, 9, 0, 0, 0, 2, + 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 8, 0, 0, 0, 214, 5, 16, + 0, 6, 0, 0, 0, 230, 10, 16, 0, 11, 0, 0, 0, 35, 0, 0, 9, 50, 0, + 16, 0, 7, 0, 0, 0, 134, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 7, + 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, 0, + 7, 0, 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, + 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, + 0, 138, 0, 0, 15, 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, + 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 166, 14, 16, 0, + 4, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 13, 0, 0, + 0, 86, 13, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 35, 0, + 0, 9, 242, 0, 16, 0, 11, 0, 0, 0, 6, 8, 16, 0, 6, 0, 0, 0, 70, + 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 78, 0, 0, 11, + 242, 0, 16, 0, 11, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, + 8, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 7, 0, 0, 0, 70, 0, 16, + 0, 7, 0, 0, 0, 198, 0, 16, 0, 11, 0, 0, 0, 60, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 7, + 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 11, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, + 0, 12, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 138, 0, 0, 15, 146, 0, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, 138, 0, 0, 15, 82, 0, + 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 7, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 82, 0, 16, 0, 7, 0, 0, 0, 246, 15, 16, 0, 6, 0, + 0, 0, 6, 2, 16, 0, 7, 0, 0, 0, 35, 0, 0, 9, 146, 0, 16, 0, 3, + 0, 0, 0, 166, 10, 16, 0, 6, 0, 0, 0, 6, 12, 16, 0, 3, 0, 0, 0, + 6, 8, 16, 0, 7, 0, 0, 0, 78, 0, 0, 11, 146, 0, 16, 0, 3, 0, 0, + 0, 0, 208, 0, 0, 6, 12, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 146, + 0, 16, 0, 3, 0, 0, 0, 6, 12, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, + 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 26, 0, + 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, + 0, 3, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 255, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 15, 50, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 9, 0, 0, 0, 38, 0, 0, 8, + 0, 208, 0, 0, 194, 0, 16, 0, 3, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, + 0, 166, 14, 16, 0, 10, 0, 0, 0, 35, 0, 0, 9, 50, 0, 16, 0, 3, 0, + 0, 0, 166, 10, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 230, + 10, 16, 0, 3, 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, 0, 3, 0, 0, 0, + 0, 208, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, + 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, + 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, + 0, 7, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, + 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 55, 0, 0, 9, 130, + 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 12, 0, 0, 0, 35, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 79, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 31, 0, + 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 146, + 4, 0, 0, 146, 4, 0, 0, 146, 4, 0, 0, 146, 4, 0, 0, 41, 0, 0, 10, + 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 85, 0, + 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 30, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, + 0, 70, 14, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 59, + 0, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 1, 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 8, 0, 0, 0, 30, 0, 0, 11, 242, 0, 16, 0, 10, 0, + 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 9, 0, 0, 0, 2, 64, 0, 0, 109, + 11, 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, 1, 0, 0, 7, + 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, + 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, + 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, + 0, 7, 0, 0, 0, 7, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, + 16, 0, 11, 0, 0, 0, 214, 5, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 11, + 0, 0, 0, 35, 0, 0, 9, 50, 0, 16, 0, 10, 0, 0, 0, 134, 0, 16, 0, + 5, 0, 0, 0, 70, 0, 16, 0, 10, 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, + 0, 78, 0, 0, 11, 50, 0, 16, 0, 10, 0, 0, 0, 0, 208, 0, 0, 70, 0, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, + 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 13, + 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, + 0, 3, 0, 0, 0, 6, 4, 16, 0, 9, 0, 0, 0, 38, 0, 0, 8, 0, 208, + 0, 0, 242, 0, 16, 0, 13, 0, 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 13, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 12, 0, 0, 0, + 6, 8, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, + 0, 13, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 12, 0, 0, 0, 0, 208, + 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, + 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 16, 0, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 60, 0, 0, 7, 50, 0, + 16, 0, 10, 0, 0, 0, 70, 0, 16, 0, 10, 0, 0, 0, 198, 0, 16, 0, 12, + 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 12, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, + 12, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, + 0, 10, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, + 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 140, 0, 0, 17, + 50, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 198, + 0, 16, 0, 12, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, + 26, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 30, 0, 0, + 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 10, 0, + 16, 0, 7, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 59, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 13, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 21, 0, + 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, + 0, 16, 0, 13, 0, 0, 0, 86, 5, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, + 0, 5, 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 13, 0, + 0, 0, 78, 0, 0, 8, 18, 0, 16, 0, 4, 0, 0, 0, 0, 208, 0, 0, 10, + 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 138, 0, 0, 15, + 242, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, + 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 35, + 0, 0, 9, 114, 0, 16, 0, 13, 0, 0, 0, 6, 0, 16, 0, 5, 0, 0, 0, + 70, 2, 16, 0, 14, 0, 0, 0, 150, 7, 16, 0, 13, 0, 0, 0, 78, 0, 0, + 11, 114, 0, 16, 0, 13, 0, 0, 0, 0, 208, 0, 0, 70, 2, 16, 0, 13, 0, + 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, + 13, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, + 0, 0, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 60, 0, 0, 7, 18, + 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, + 0, 13, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 55, 0, 0, 9, 18, 0, + 16, 0, 13, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, + 15, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, + 0, 0, 6, 0, 0, 0, 86, 10, 16, 0, 8, 0, 0, 0, 138, 0, 0, 15, 242, + 0, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 9, 0, 0, + 0, 3, 0, 0, 0, 6, 0, 0, 0, 86, 10, 16, 0, 9, 0, 0, 0, 38, 0, + 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 8, 0, 0, 0, 246, 15, 16, 0, 5, + 0, 0, 0, 70, 0, 16, 0, 16, 0, 0, 0, 35, 0, 0, 9, 50, 0, 16, 0, + 8, 0, 0, 0, 166, 10, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 15, 0, 0, + 0, 70, 0, 16, 0, 8, 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, 0, 8, 0, + 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 5, + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, + 50, 0, 16, 0, 8, 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 26, + 0, 16, 0, 10, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, + 10, 242, 0, 16, 0, 17, 0, 0, 0, 86, 10, 16, 0, 7, 0, 0, 0, 2, 64, + 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, 0, 70, 14, 16, 0, 17, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, + 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 11, 0, + 0, 0, 10, 0, 16, 0, 17, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, + 0, 0, 0, 26, 0, 16, 0, 17, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, + 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 255, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 138, 0, + 0, 15, 242, 0, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, + 15, 0, 0, 0, 18, 0, 0, 0, 21, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, + 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 18, 0, 0, 0, 246, 15, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 35, 0, 0, 9, 18, + 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, + 12, 0, 0, 0, 10, 0, 16, 0, 18, 0, 0, 0, 78, 0, 0, 8, 18, 0, 16, + 0, 3, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 7, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 42, + 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, + 18, 0, 0, 0, 78, 0, 0, 8, 18, 0, 16, 0, 4, 0, 0, 0, 0, 208, 0, + 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, + 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, + 64, 0, 0, 8, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 138, 0, 0, + 15, 242, 0, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 9, + 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 86, 10, 16, 0, 3, 0, 0, 0, + 35, 0, 0, 9, 50, 0, 16, 0, 4, 0, 0, 0, 166, 10, 16, 0, 5, 0, 0, + 0, 70, 0, 16, 0, 14, 0, 0, 0, 230, 10, 16, 0, 18, 0, 0, 0, 78, 0, + 0, 11, 50, 0, 16, 0, 4, 0, 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 60, 0, 0, 7, + 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, + 0, 3, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 13, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, + 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 3, 0, 0, 0, + 214, 5, 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, 11, 0, 0, 0, 35, 0, 0, + 9, 50, 0, 16, 0, 3, 0, 0, 0, 134, 0, 16, 0, 6, 0, 0, 0, 230, 10, + 16, 0, 10, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 78, 0, 0, 11, 50, + 0, 16, 0, 3, 0, 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 4, 0, 0, 0, 86, 5, + 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, 16, 0, 0, 0, 35, 0, 0, 9, 50, + 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, + 15, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, + 0, 4, 0, 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, + 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 138, 0, 0, 15, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 9, 0, + 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 230, 15, 16, 0, 8, + 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 9, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 230, 15, + 16, 0, 9, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 9, + 0, 0, 0, 214, 15, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, + 35, 0, 0, 9, 242, 0, 16, 0, 8, 0, 0, 0, 134, 10, 16, 0, 6, 0, 0, + 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 78, 0, + 0, 11, 242, 0, 16, 0, 8, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 5, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 16, 0, + 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 140, 0, 0, 11, + 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 17, 0, + 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 17, + 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, + 9, 0, 0, 0, 230, 15, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 15, 0, 0, + 0, 5, 0, 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 30, 0, 0, 7, + 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, + 0, 9, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 12, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 21, 0, 0, 0, 166, 10, + 16, 0, 4, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 10, + 0, 0, 0, 86, 5, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, + 35, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, + 0, 42, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 78, 0, + 0, 8, 18, 0, 16, 0, 3, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 35, 0, 0, 9, 50, 0, 16, 0, + 4, 0, 0, 0, 6, 0, 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, 14, 0, 0, + 0, 150, 5, 16, 0, 10, 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, 0, 4, 0, + 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, + 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, + 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 10, + 0, 16, 0, 4, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, + 26, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 138, 0, 0, + 15, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 3, + 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 230, 15, 16, 0, 3, 0, 0, 0, + 35, 0, 0, 9, 66, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, + 0, 10, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 78, 0, + 0, 8, 66, 0, 16, 0, 3, 0, 0, 0, 0, 208, 0, 0, 42, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, + 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, + 0, 60, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 13, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 60, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 9, + 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, + 9, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, + 0, 3, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 138, 0, 0, 15, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 12, 0, + 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 21, 0, 0, 0, 246, 15, 16, 0, 4, + 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, 0, 35, 0, 0, + 9, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 58, 0, + 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 35, 0, 0, 9, 226, + 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 6, 0, 0, 0, 86, 14, 16, 0, + 11, 0, 0, 0, 86, 14, 16, 0, 3, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, + 0, 3, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 41, + 0, 0, 10, 226, 0, 16, 0, 3, 0, 0, 0, 86, 14, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, + 0, 60, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 3, + 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, + 60, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, + 0, 10, 0, 16, 0, 3, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 13, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, + 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 79, 0, 0, 9, 130, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, + 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 6, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 7, 50, + 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 134, 0, 16, 0, + 3, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 146, 36, 73, 0, 146, 36, 73, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, + 4, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 7, 0, 0, + 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 4, + 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, + 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, + 0, 70, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 73, 146, 36, 0, 73, + 146, 36, 0, 73, 146, 36, 0, 73, 146, 36, 0, 30, 0, 0, 10, 242, 0, 16, 0, + 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 182, 109, 219, + 0, 182, 109, 219, 0, 182, 109, 219, 0, 182, 109, 219, 0, 1, 0, 0, 7, 194, 0, + 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 8, + 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 8, 0, 0, 0, 70, 0, 16, 0, + 2, 0, 0, 0, 134, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 9, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 73, 146, + 36, 0, 73, 146, 36, 0, 73, 146, 36, 0, 73, 146, 36, 0, 60, 0, 0, 7, 50, + 0, 16, 0, 3, 0, 0, 0, 214, 5, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, + 8, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 73, 146, 36, 0, 73, 146, 36, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 87, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 73, 146, 36, 0, 73, 146, 36, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 5, 242, 0, 16, 0, 9, 0, 0, + 0, 70, 14, 16, 0, 9, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 10, 0, + 0, 0, 6, 5, 16, 0, 7, 0, 0, 0, 6, 10, 16, 0, 9, 0, 0, 0, 1, + 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 86, 15, 16, 0, 9, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, + 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 30, 0, + 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 183, 109, 219, 255, 183, 109, 219, 255, 0, 0, 0, 0, 0, 0, 0, 0, + 60, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 198, 0, 16, 0, 9, 0, 0, + 0, 70, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 1, + 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, + 7, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 134, 0, 16, 0, 3, 0, 0, + 0, 59, 0, 0, 5, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, + 0, 0, 1, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, + 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, + 4, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, + 0, 30, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 214, 5, 16, 0, 3, 0, + 0, 0, 134, 0, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 2, + 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, + 55, 0, 0, 9, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 85, 0, + 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 166, 15, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, + 1, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, + 0, 134, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 2, 0, + 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 146, 36, 73, 0, 146, + 36, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, + 7, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 50, 0, + 16, 0, 8, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, + 0, 7, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 7, 50, + 0, 16, 0, 7, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 230, 10, 16, 0, + 8, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 8, 0, 0, 0, 230, 10, 16, + 0, 2, 0, 0, 0, 134, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 73, + 146, 36, 0, 73, 146, 36, 0, 73, 146, 36, 0, 73, 146, 36, 0, 60, 0, 0, 7, + 50, 0, 16, 0, 4, 0, 0, 0, 214, 5, 16, 0, 4, 0, 0, 0, 70, 0, 16, + 0, 8, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 73, 146, 36, 0, 73, 146, 36, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, + 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 73, 146, 36, 0, 73, 146, 36, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 5, 242, 0, 16, 0, 8, 0, + 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 9, + 0, 0, 0, 166, 15, 16, 0, 7, 0, 0, 0, 6, 10, 16, 0, 8, 0, 0, 0, + 1, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 86, 15, 16, 0, 8, 0, 0, + 0, 70, 14, 16, 0, 9, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 2, 0, + 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 30, + 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 109, 219, 255, 183, 109, 219, + 255, 60, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 86, 13, 16, 0, 8, 0, + 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, + 0, 7, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, 8, 16, 0, 4, 0, + 0, 0, 59, 0, 0, 5, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, + 0, 0, 0, 1, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, + 2, 0, 0, 0, 230, 10, 16, 0, 7, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, + 0, 2, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 70, 0, 16, 0, 2, 0, + 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 214, 5, 16, 0, 4, + 0, 0, 0, 134, 0, 16, 0, 4, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, + 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, + 0, 55, 0, 0, 9, 194, 0, 16, 0, 3, 0, 0, 0, 6, 8, 16, 0, 1, 0, + 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 146, 4, 0, 0, + 146, 4, 0, 0, 146, 4, 0, 0, 146, 4, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 59, 0, 0, 5, + 242, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 1, 0, 0, + 7, 242, 0, 16, 0, 7, 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 166, 14, + 16, 0, 4, 0, 0, 0, 30, 0, 0, 11, 242, 0, 16, 0, 8, 0, 0, 0, 166, + 14, 16, 128, 65, 0, 0, 0, 7, 0, 0, 0, 2, 64, 0, 0, 109, 11, 0, 0, + 109, 11, 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, 1, 0, 0, 7, 242, 0, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 8, 0, 0, 0, 230, 10, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 8, 0, 0, 0, 166, 14, 16, + 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 194, 0, 16, 0, 8, + 0, 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 166, 14, 16, 0, 8, 0, 0, 0, + 35, 0, 0, 9, 50, 0, 16, 0, 8, 0, 0, 0, 134, 0, 16, 0, 5, 0, 0, + 0, 70, 0, 16, 0, 8, 0, 0, 0, 230, 10, 16, 0, 8, 0, 0, 0, 78, 0, + 0, 11, 50, 0, 16, 0, 8, 0, 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, + 0, 16, 0, 10, 0, 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, + 10, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 9, 0, 0, 0, 6, 8, 16, + 0, 5, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, + 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 9, 0, 0, 0, 0, 208, 0, 0, 70, + 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 5, 0, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, + 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 16, 0, + 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 4, + 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 198, 0, 16, 0, 9, 0, 0, 0, + 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, + 0, 10, 0, 16, 0, 4, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, + 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, + 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 10, 0, + 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, + 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 140, 0, 0, 17, 50, 0, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 198, 0, 16, 0, + 9, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, + 0, 9, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, + 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 59, 0, 0, 5, 242, 0, 16, 0, 9, 0, 0, 0, 6, 4, 16, 0, 3, 0, + 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 4, 0, 0, 0, 166, 11, 16, 0, 9, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 7, + 0, 0, 0, 214, 5, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 10, 0, 0, 0, + 35, 0, 0, 9, 82, 0, 16, 0, 4, 0, 0, 0, 6, 2, 16, 0, 5, 0, 0, + 0, 6, 2, 16, 0, 4, 0, 0, 0, 6, 1, 16, 0, 7, 0, 0, 0, 78, 0, + 0, 11, 82, 0, 16, 0, 4, 0, 0, 0, 0, 208, 0, 0, 6, 2, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 9, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, + 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, + 0, 16, 0, 12, 0, 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, + 12, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 11, 0, 0, 0, 6, 8, 16, + 0, 5, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 12, 0, + 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 11, 0, 0, 0, 0, 208, 0, 0, 70, + 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, + 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 16, 0, + 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, 4, + 0, 0, 0, 6, 2, 16, 0, 4, 0, 0, 0, 6, 3, 16, 0, 11, 0, 0, 0, + 60, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, + 0, 10, 0, 16, 0, 4, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 55, + 0, 0, 9, 18, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 138, 0, 0, + 15, 146, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 246, 15, 16, 0, 4, 0, 0, 0, + 138, 0, 0, 15, 50, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 6, 0, + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 7, + 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 7, 0, 0, 0, + 246, 15, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 35, 0, 0, + 9, 146, 0, 16, 0, 4, 0, 0, 0, 166, 10, 16, 0, 5, 0, 0, 0, 6, 12, + 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 78, 0, 0, 11, 146, + 0, 16, 0, 4, 0, 0, 0, 0, 208, 0, 0, 6, 12, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, + 0, 41, 0, 0, 10, 146, 0, 16, 0, 4, 0, 0, 0, 6, 12, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, + 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 86, 15, 16, 0, 8, + 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 10, 0, 0, 0, + 15, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, + 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, + 1, 0, 0, 0, 0, 1, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, + 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 138, 0, 0, 15, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, + 16, 0, 9, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 9, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, + 0, 86, 15, 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, + 16, 0, 4, 0, 0, 0, 246, 15, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 9, + 0, 0, 0, 35, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, + 5, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, + 0, 78, 0, 0, 11, 50, 0, 16, 0, 2, 0, 0, 0, 0, 208, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, + 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 24, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 60, + 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 11, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 59, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 166, + 14, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, + 166, 14, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, + 11, 242, 0, 16, 0, 12, 0, 0, 0, 166, 14, 16, 128, 65, 0, 0, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, 109, + 11, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, + 0, 7, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 50, + 0, 16, 0, 8, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 50, 0, 16, 0, 8, 0, 0, 0, 214, 5, 16, 0, 6, 0, + 0, 0, 70, 0, 16, 0, 8, 0, 0, 0, 35, 0, 0, 9, 50, 0, 16, 0, 7, + 0, 0, 0, 134, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, + 70, 0, 16, 0, 8, 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, 0, 7, 0, 0, + 0, 0, 208, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 5, 0, + 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 242, + 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, + 0, 9, 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 138, 0, + 0, 15, 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 13, 0, 0, 0, 86, 13, + 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 35, 0, 0, 9, 242, + 0, 16, 0, 12, 0, 0, 0, 6, 8, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, + 12, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, + 0, 12, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, + 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 41, + 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 8, 0, 0, + 0, 60, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 7, 0, + 0, 0, 198, 0, 16, 0, 12, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 12, 0, + 0, 0, 166, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 10, + 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 140, 0, 0, 17, 82, 0, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 166, 11, 16, 0, 8, 0, 0, 0, 6, 3, 16, + 0, 12, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, + 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 59, 0, 0, 5, 242, 0, 16, 0, 8, 0, 0, 0, 166, 14, 16, 0, 3, + 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, + 8, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 7, 0, + 0, 0, 214, 5, 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, 10, 0, 0, 0, 35, + 0, 0, 9, 50, 0, 16, 0, 4, 0, 0, 0, 134, 0, 16, 0, 6, 0, 0, 0, + 70, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 78, 0, 0, + 11, 50, 0, 16, 0, 4, 0, 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 8, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 12, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, + 0, 166, 14, 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, + 16, 0, 12, 0, 0, 0, 86, 13, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 10, 0, 0, 0, 6, 8, 16, 0, + 6, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, + 0, 78, 0, 0, 11, 242, 0, 16, 0, 10, 0, 0, 0, 0, 208, 0, 0, 70, 14, + 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, + 0, 0, 0, 7, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, + 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 16, 0, 0, + 0, 24, 0, 0, 0, 8, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 4, 0, + 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 198, 0, 16, 0, 10, 0, 0, 0, 60, + 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, + 0, 42, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 55, 0, + 0, 9, 66, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 138, 0, 0, 15, + 146, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 138, + 0, 0, 15, 82, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 4, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 82, 0, 16, 0, 4, 0, 0, 0, 6, + 2, 16, 0, 4, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, + 146, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 6, 0, 0, 0, 6, 12, 16, + 0, 2, 0, 0, 0, 6, 8, 16, 0, 4, 0, 0, 0, 78, 0, 0, 11, 146, 0, + 16, 0, 2, 0, 0, 0, 0, 208, 0, 0, 6, 12, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, + 41, 0, 0, 10, 146, 0, 16, 0, 2, 0, 0, 0, 6, 12, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, + 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 7, 0, + 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 255, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 138, 0, + 0, 15, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 8, 0, 0, + 0, 38, 0, 0, 8, 0, 208, 0, 0, 194, 0, 16, 0, 2, 0, 0, 0, 246, 15, + 16, 0, 6, 0, 0, 0, 166, 14, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 50, + 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, + 2, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 78, 0, 0, 11, 50, 0, 16, + 0, 2, 0, 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, + 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 60, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 55, 0, 0, 9, 130, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 164, 0, + 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 79, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 31, + 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 146, 4, 0, 0, 146, 4, 0, 0, 146, 4, 0, 0, 146, 4, 0, 0, 41, 0, 0, + 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, + 59, 0, 0, 5, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 1, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 30, 0, 0, 11, 242, 0, 16, 0, 9, + 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 8, 0, 0, 0, 2, 64, 0, 0, + 109, 11, 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, 109, 11, 0, 0, 1, 0, 0, + 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, + 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, + 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, + 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 162, + 0, 16, 0, 1, 0, 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 6, 4, 16, 0, + 10, 0, 0, 0, 35, 0, 0, 9, 162, 0, 16, 0, 1, 0, 0, 0, 6, 8, 16, + 0, 5, 0, 0, 0, 6, 4, 16, 0, 9, 0, 0, 0, 86, 13, 16, 0, 1, 0, + 0, 0, 78, 0, 0, 11, 162, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 86, + 13, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 5, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, + 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, + 12, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, + 0, 0, 3, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 38, 0, 0, 8, 0, + 208, 0, 0, 242, 0, 16, 0, 12, 0, 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 12, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 11, 0, 0, + 0, 6, 8, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, + 16, 0, 12, 0, 0, 0, 78, 0, 0, 11, 242, 0, 16, 0, 11, 0, 0, 0, 0, + 208, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, + 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 60, 0, 0, 7, 162, + 0, 16, 0, 1, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 6, 12, 16, 0, + 11, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 11, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 60, 0, 0, 7, 130, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 11, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 5, 0, + 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, + 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 140, 0, 0, + 17, 50, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, + 198, 0, 16, 0, 11, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 58, 0, 16, + 0, 0, 0, 0, 0, 59, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 7, 0, 0, 0, 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 21, + 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, + 242, 0, 16, 0, 12, 0, 0, 0, 86, 5, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 12, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 12, + 0, 0, 0, 78, 0, 0, 8, 34, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 138, 0, 0, + 15, 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 6, + 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, + 35, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 6, 0, 16, 0, 5, 0, 0, + 0, 70, 2, 16, 0, 13, 0, 0, 0, 150, 7, 16, 0, 12, 0, 0, 0, 78, 0, + 0, 11, 114, 0, 16, 0, 12, 0, 0, 0, 0, 208, 0, 0, 70, 2, 16, 0, 12, + 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 41, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, + 0, 12, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 24, 0, + 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 60, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 55, 0, 0, 9, 18, + 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, + 0, 14, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 3, + 0, 0, 0, 6, 0, 0, 0, 86, 10, 16, 0, 7, 0, 0, 0, 138, 0, 0, 15, + 242, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 9, 0, + 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 86, 10, 16, 0, 8, 0, 0, 0, 38, + 0, 0, 8, 0, 208, 0, 0, 146, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, + 5, 0, 0, 0, 6, 4, 16, 0, 15, 0, 0, 0, 35, 0, 0, 9, 146, 0, 16, + 0, 0, 0, 0, 0, 166, 10, 16, 0, 5, 0, 0, 0, 6, 4, 16, 0, 14, 0, + 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 78, 0, 0, 11, 146, 0, 16, 0, 0, + 0, 0, 0, 0, 208, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 41, 0, 0, + 10, 146, 0, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 60, + 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 1, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, + 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, 86, 10, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, + 1, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, + 0, 0, 0, 10, 0, 16, 0, 16, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 16, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 138, + 0, 0, 15, 242, 0, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, + 0, 15, 0, 0, 0, 18, 0, 0, 0, 21, 0, 0, 0, 86, 5, 16, 0, 3, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 17, 0, 0, 0, 246, + 15, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 17, 0, 0, 0, 35, 0, 0, 9, + 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, + 0, 11, 0, 0, 0, 10, 0, 16, 0, 17, 0, 0, 0, 78, 0, 0, 8, 130, 0, + 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 7, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, + 0, 17, 0, 0, 0, 78, 0, 0, 8, 34, 0, 16, 0, 1, 0, 0, 0, 0, 208, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, + 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 8, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 138, 0, + 0, 15, 242, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, + 9, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 86, 10, 16, 0, 2, 0, 0, + 0, 35, 0, 0, 9, 162, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 5, 0, + 0, 0, 6, 4, 16, 0, 13, 0, 0, 0, 166, 14, 16, 0, 17, 0, 0, 0, 78, + 0, 0, 11, 162, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 86, 13, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, + 0, 7, 0, 0, 0, 41, 0, 0, 10, 162, 0, 16, 0, 1, 0, 0, 0, 86, 13, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 60, 0, 0, + 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 12, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 0, 0, 0, + 0, 214, 5, 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, 10, 0, 0, 0, 35, 0, + 0, 9, 50, 0, 16, 0, 0, 0, 0, 0, 134, 0, 16, 0, 6, 0, 0, 0, 230, + 10, 16, 0, 9, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 78, 0, 0, 11, + 50, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, 70, 0, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 162, 0, 16, 0, 1, 0, 0, 0, 86, + 5, 16, 0, 6, 0, 0, 0, 166, 14, 16, 0, 15, 0, 0, 0, 35, 0, 0, 9, + 162, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 6, 0, 0, 0, 166, 14, 16, + 0, 14, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 78, 0, 0, 11, 162, 0, + 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, + 41, 0, 0, 10, 162, 0, 16, 0, 1, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 138, 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 9, + 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 230, 15, 16, 0, + 7, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 230, + 15, 16, 0, 8, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, + 7, 0, 0, 0, 214, 15, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, + 0, 35, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 134, 10, 16, 0, 6, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 78, + 0, 0, 11, 242, 0, 16, 0, 5, 0, 0, 0, 0, 208, 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, + 0, 5, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 16, + 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 16, + 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 16, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 7, 0, 0, 0, 230, 15, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 15, 0, + 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 30, 0, 0, + 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 7, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 21, 0, 0, 0, 166, + 10, 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, + 8, 0, 0, 0, 86, 5, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, + 0, 35, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, + 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 78, + 0, 0, 8, 130, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 35, 0, 0, 9, 162, 0, 16, + 0, 1, 0, 0, 0, 6, 0, 16, 0, 6, 0, 0, 0, 166, 14, 16, 0, 13, 0, + 0, 0, 86, 9, 16, 0, 8, 0, 0, 0, 78, 0, 0, 11, 162, 0, 16, 0, 1, + 0, 0, 0, 0, 208, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 41, 0, 0, + 10, 162, 0, 16, 0, 1, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 60, + 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 138, 0, + 0, 15, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, + 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 230, 15, 16, 0, 2, 0, 0, + 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 6, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 78, + 0, 0, 8, 34, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 24, 0, + 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, + 12, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 60, + 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 140, 0, + 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, + 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 138, 0, 0, 15, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 12, + 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 21, 0, 0, 0, 246, 15, 16, 0, + 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 58, + 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 78, 0, 0, 8, + 34, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 7, 0, 0, 0, 35, 0, 0, 9, 178, 0, 16, 0, 1, 0, + 0, 0, 166, 10, 16, 0, 6, 0, 0, 0, 150, 13, 16, 0, 2, 0, 0, 0, 150, + 13, 16, 0, 3, 0, 0, 0, 78, 0, 0, 11, 178, 0, 16, 0, 1, 0, 0, 0, + 0, 208, 0, 0, 70, 12, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, + 0, 7, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 41, 0, 0, 10, 178, 0, + 16, 0, 1, 0, 0, 0, 70, 12, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, + 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 34, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, + 10, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 21, 0, 0, 1, + 21, 0, 0, 1, 21, 0, 0, 1, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, + 0, 253, 2, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 24, 1, 0, 0, 78, 1, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_gbgr8_grgb8_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_gbgr8_grgb8_cs.h new file mode 100644 index 0000000..d0429d3 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_gbgr8_grgb8_cs.h @@ -0,0 +1,451 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(2) +imad r1.x, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.x, r1.x, CB0[0][2].x, r0.w +iadd r1.x, r1.x, CB0[0][1].w +ushr r1.x, r1.x, l(4) +if_nz r0.x + if_nz r0.y + ishr r1.yzw, vThreadID.yyzy, l(0, 4, 2, 3) + ushr r2.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r0.y, r1.z, r2.x, r1.y + ibfe r2.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), vThreadID.xxxx + imad r0.y, r0.y, r2.y, r2.x + ishl r1.y, vThreadID.y, l(10) + ishr r1.y, r1.y, l(6) + and r1.y, r1.y, l(96) + iadd r1.z, r1.z, r1.w + bfi r1.w, l(1), l(1), r1.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r1.w, l(2), l(1), r1.w, l(0) + bfi r1.z, l(1), l(0), r1.z, r1.w + bfi r2.xy, l(20, 20, 0, 0), l(10, 13, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r1.yw, r1.yyyy, l(0, 2, 0, 16), r2.xxxy + bfi r1.yw, l(0, 2, 0, 2), l(0, 8, 0, 11), vThreadID.zzzz, r1.yyyw + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r2.x, l(3), l(6), r1.y + and r2.y, r1.z, l(6) + bfi r1.z, l(1), l(8), r1.z, l(0) + imad r1.z, r2.x, l(32), r1.z + imad r1.z, r2.y, l(4), r1.z + bfi r1.yw, l(0, 6, 0, 6), l(0, 0, 0, 3), r0.yyyy, r1.yyyw + bfi r0.y, l(9), l(3), r1.z, r1.w + bfi r0.y, l(6), l(0), r1.y, r0.y + else + ibfe r1.yz, l(0, 27, 29, 0), l(0, 2, 0, 0), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.y, r2.x, r1.w, r1.y + ishl r2.xz, vThreadID.yyyy, l(5, 0, 7, 0) + and r2.xz, r2.xxzx, l(448, 0, 2048, 0) + bfi r1.w, l(23), l(9), r1.y, r2.x + bfi r2.w, l(1), l(4), vThreadID.y, l(0) + iadd r1.w, r1.w, r2.w + ishl r3.xy, r2.xxxx, l(3, 2, 0, 0) + bfi r3.xy, l(23, 23, 0, 0), l(12, 11, 0, 0), r1.yyyy, r3.xyxx + imad r2.xw, r2.wwww, l(8, 0, 0, 4), r3.xxxy + bfi r1.y, l(12), l(0), r2.z, r2.x + and r2.x, r2.w, l(1792) + iadd r1.y, r1.y, r2.x + and r2.x, r2.y, l(2) + iadd r1.z, r1.z, r2.x + bfi r1.z, l(2), l(6), r1.z, l(0) + iadd r1.y, r1.y, r1.z + bfi r0.y, l(6), l(0), r1.w, r1.y + endif +else + imad r1.y, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.y, CB0[0][0].z, r0.w +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.y, r0.y, l(4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r1.yzw, r0.zzzz, l(0, 1, 2, 3) +or r0.zw, r1.zzzw, r1.yyyz +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +and r3.xyzw, r2.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) +ishl r4.xyzw, r2.xyzw, l(16, 16, 16, 16) +bfi r3.xyzw, l(24, 24, 24, 24), l(0, 0, 0, 0), r3.xyzw, r4.xyzw +ushr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +and r2.xyzw, r2.xyzw, l(0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00) +iadd r2.xyzw, r2.xyzw, r3.xyzw +store_uav_typed U0[0].xyzw, r1.xxxx, r2.xyzw +iadd r1.y, r1.x, l(1) +if_nz r0.x + mov r0.x, l(32) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r0.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r0.xyzw +endif +and r0.xyzw, r2.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) +ishl r3.xyzw, r2.xyzw, l(16, 16, 16, 16) +bfi r0.xyzw, l(24, 24, 24, 24), l(0, 0, 0, 0), r0.xyzw, r3.xyzw +ushr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +and r2.xyzw, r2.xyzw, l(0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00) +iadd r0.xyzw, r0.xyzw, r2.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r0.xyzw +ret +// Approximately 118 instruction slots used +#endif + +const BYTE texture_load_gbgr8_grgb8_cs[] = { + 68, 88, 66, 67, 72, 147, 197, 205, 180, 143, 31, 127, 137, 134, 140, 56, 133, 149, 172, + 224, 1, 0, 0, 0, 160, 20, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 4, 20, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 200, 15, 0, + 0, 81, 0, 5, 0, 242, 3, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 226, 0, 16, 0, 1, 0, + 0, 0, 86, 6, 2, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, + 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, + 182, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 139, 0, 0, 14, + 82, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, + 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 96, 0, 0, 0, 30, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 20, 50, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, + 0, 0, 12, 162, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 6, 4, 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 162, 0, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 166, 10, 2, 0, 86, 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 10, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, + 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, + 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 32, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 162, 0, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, + 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, + 14, 98, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 27, 0, + 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 2, 0, 42, 0, 0, 9, + 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, + 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, 82, 0, 16, 0, 2, 0, + 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 2, 0, 0, 0, + 6, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, + 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, + 0, 35, 0, 0, 12, 146, 0, 16, 0, 2, 0, 0, 0, 246, 15, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, + 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 21, 0, + 0, 1, 18, 0, 0, 1, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, + 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, + 226, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 0, + 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 86, + 9, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 41, 0, 0, 10, 242, + 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, 24, 0, + 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 18, + 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 16, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, + 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, + 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, + 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, + 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, + 24, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, + 0, 0, 0, 255, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 164, 0, 0, 8, + 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, + 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 38, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_gbgr8_rgb8_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_gbgr8_rgb8_cs.h new file mode 100644 index 0000000..10cb220 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_gbgr8_rgb8_cs.h @@ -0,0 +1,514 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(3) +imad r1.y, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r0.w, r1.y, CB0[0][2].x, r0.w +iadd r0.w, r0.w, CB0[0][1].w +if_nz r0.x + if_nz r0.y + ishr r1.yzw, vThreadID.yyzy, l(0, 4, 2, 3) + ushr r2.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r0.y, r1.z, r2.x, r1.y + ibfe r2.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), vThreadID.xxxx + imad r0.y, r0.y, r2.y, r2.x + ishl r1.y, vThreadID.y, l(10) + ishr r1.y, r1.y, l(6) + and r1.y, r1.y, l(96) + iadd r1.z, r1.z, r1.w + bfi r1.w, l(1), l(1), r1.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r1.w, l(2), l(1), r1.w, l(0) + bfi r1.z, l(1), l(0), r1.z, r1.w + bfi r2.xy, l(20, 20, 0, 0), l(10, 13, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r1.yw, r1.yyyy, l(0, 2, 0, 16), r2.xxxy + bfi r1.yw, l(0, 2, 0, 2), l(0, 8, 0, 11), vThreadID.zzzz, r1.yyyw + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r2.x, l(3), l(6), r1.y + and r2.y, r1.z, l(6) + bfi r1.z, l(1), l(8), r1.z, l(0) + imad r1.z, r2.x, l(32), r1.z + imad r1.z, r2.y, l(4), r1.z + bfi r1.yw, l(0, 6, 0, 6), l(0, 0, 0, 3), r0.yyyy, r1.yyyw + bfi r0.y, l(9), l(3), r1.z, r1.w + bfi r0.y, l(6), l(0), r1.y, r0.y + else + ibfe r1.yz, l(0, 27, 29, 0), l(0, 2, 0, 0), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.y, r2.x, r1.w, r1.y + ishl r2.xz, vThreadID.yyyy, l(5, 0, 7, 0) + and r2.xz, r2.xxzx, l(448, 0, 2048, 0) + bfi r1.w, l(23), l(9), r1.y, r2.x + bfi r2.w, l(1), l(4), vThreadID.y, l(0) + iadd r1.w, r1.w, r2.w + ishl r3.xy, r2.xxxx, l(3, 2, 0, 0) + bfi r3.xy, l(23, 23, 0, 0), l(12, 11, 0, 0), r1.yyyy, r3.xyxx + imad r2.xw, r2.wwww, l(8, 0, 0, 4), r3.xxxy + bfi r1.y, l(12), l(0), r2.z, r2.x + and r2.x, r2.w, l(1792) + iadd r1.y, r1.y, r2.x + and r2.x, r2.y, l(2) + iadd r1.z, r1.z, r2.x + bfi r1.z, l(2), l(6), r1.z, l(0) + iadd r1.y, r1.y, r1.z + bfi r0.y, l(6), l(0), r1.w, r1.y + endif +else + ishl r1.x, r1.x, l(2) + imad r1.y, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.y, CB0[0][0].z, r1.x +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.yw, r0.yyyw, l(0, 4, 0, 4) +ld r1.xyzw, r0.yyyy, T0[0].xyzw +ieq r2.xyz, r0.zzzz, l(1, 2, 3, 0) +or r2.xy, r2.yzyy, r2.xyxx +if_nz r2.x + ishl r3.xyzw, r1.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r1.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r1.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r2.y + ushr r3.xyzw, r1.xyzw, l(16, 16, 16, 16) + bfi r1.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r1.xyzw, r3.xyzw +endif +ushr r3.xyzw, r1.xyxy, l(24, 24, 8, 8) +ishl r4.xyzw, r1.xxyy, l(8, 8, 8, 8) +and r4.xyzw, r4.xyzw, l(0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000) +imad r4.xyzw, r4.xyzw, l(257, 257, 257, 257), r3.xxyy +bfi r5.xz, l(8, 0, 8, 0), l(8, 0, 8, 0), r1.xxyx, l(0, 0, 0, 0) +and r5.yw, r3.zzzw, l(0, 0x0000ff00, 0, 0x0000ff00) +iadd r3.xyzw, r4.xyzw, r5.xyzw +ushr r4.xyzw, r1.zwzw, l(24, 24, 8, 8) +ishl r5.xyzw, r1.zzww, l(8, 8, 8, 8) +and r5.xyzw, r5.xyzw, l(0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000) +imad r5.xyzw, r5.xyzw, l(257, 257, 257, 257), r4.xxyy +bfi r1.xz, l(8, 0, 8, 0), l(8, 0, 8, 0), r1.zzwz, l(0, 0, 0, 0) +and r1.yw, r4.zzzw, l(0, 0x0000ff00, 0, 0x0000ff00) +iadd r1.xyzw, r1.xyzw, r5.xyzw +store_uav_typed U0[0].xyzw, r0.wwww, r3.xyzw +iadd r3.xyz, r0.wwww, l(1, 2, 3, 0) +store_uav_typed U0[0].xyzw, r3.xxxx, r1.xyzw +if_nz r0.x + mov r0.x, l(32) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r1.xyzw, r0.xxxx, T0[0].xyzw +if_nz r2.x + ishl r4.xyzw, r1.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r1.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r1.xyzw, r4.xyzw, r5.xyzw +endif +if_nz r2.y + ushr r2.xyzw, r1.xyzw, l(16, 16, 16, 16) + bfi r1.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r1.xyzw, r2.xyzw +endif +ushr r2.xyzw, r1.xyxy, l(24, 24, 8, 8) +ishl r4.xyzw, r1.xxyy, l(8, 8, 8, 8) +and r4.xyzw, r4.xyzw, l(0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000) +imad r4.xyzw, r4.xyzw, l(257, 257, 257, 257), r2.xxyy +bfi r5.xz, l(8, 0, 8, 0), l(8, 0, 8, 0), r1.xxyx, l(0, 0, 0, 0) +and r5.yw, r2.zzzw, l(0, 0x0000ff00, 0, 0x0000ff00) +iadd r2.xyzw, r4.xyzw, r5.xyzw +ushr r4.xyzw, r1.zwzw, l(24, 24, 8, 8) +ishl r5.xyzw, r1.zzww, l(8, 8, 8, 8) +and r5.xyzw, r5.xyzw, l(0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000) +imad r5.xyzw, r5.xyzw, l(257, 257, 257, 257), r4.xxyy +bfi r1.xz, l(8, 0, 8, 0), l(8, 0, 8, 0), r1.zzwz, l(0, 0, 0, 0) +and r1.yw, r4.zzzw, l(0, 0x0000ff00, 0, 0x0000ff00) +iadd r1.xyzw, r1.xyzw, r5.xyzw +store_uav_typed U0[0].xyzw, r3.yyyy, r2.xyzw +store_uav_typed U0[0].xyzw, r3.zzzz, r1.xyzw +ret +// Approximately 136 instruction slots used +#endif + +const BYTE texture_load_gbgr8_rgb8_cs[] = { + 68, 88, 66, 67, 242, 6, 205, 24, 105, 182, 92, 28, 245, 242, 71, 67, 196, 35, 223, + 251, 1, 0, 0, 0, 232, 23, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 76, 23, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 16, 19, 0, + 0, 81, 0, 5, 0, 196, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 130, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, + 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 0, 9, 226, 0, 16, 0, 1, 0, 0, 0, 86, 6, 2, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 85, 0, + 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 182, 143, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 139, 0, 0, 14, 82, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 41, 0, 0, 6, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, + 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 96, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, + 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 162, 0, 16, 0, 1, 0, + 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 16, 162, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 166, 10, 2, 0, 86, + 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, 18, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, + 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 8, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, + 0, 0, 17, 162, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, + 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 14, 98, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, 86, + 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, + 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 41, 0, 0, 9, 82, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, + 0, 1, 64, 0, 0, 9, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 130, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 41, 0, + 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 17, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, + 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 12, 0, + 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, + 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 146, 0, 16, 0, + 2, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 6, 4, 16, 0, 3, 0, + 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 41, 0, 0, + 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, + 0, 0, 0, 0, 0, 86, 13, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, + 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 2, 0, 0, + 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 2, + 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, + 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, + 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, + 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 21, 0, 0, 1, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 4, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 6, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 35, 0, 0, 12, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 6, 5, 16, 0, 3, 0, + 0, 0, 140, 0, 0, 20, 82, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 6, 1, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 162, 0, 16, 0, 5, 0, 0, 0, 166, + 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, + 0, 0, 0, 0, 0, 255, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 85, 0, + 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 230, 14, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 166, 15, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 35, 0, 0, 12, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, + 0, 0, 1, 1, 0, 0, 6, 5, 16, 0, 4, 0, 0, 0, 140, 0, 0, 20, 82, + 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 8, 0, 0, 0, 0, 0, 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 10, 162, 0, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 3, 0, 0, 0, 246, 15, 16, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, + 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 18, 0, 0, 1, 54, 0, + 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, + 0, 0, 1, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, + 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, + 0, 5, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 2, + 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 21, 0, 0, + 1, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 4, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 6, 5, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 255, 0, 0, 0, 255, 0, 35, 0, 0, 12, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, 0, 6, 5, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 20, 82, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 162, 0, 16, 0, 5, 0, 0, 0, 166, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, + 0, 255, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, + 16, 0, 4, 0, 0, 0, 230, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 24, + 0, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 41, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 166, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, + 35, 0, 0, 12, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, + 0, 0, 6, 5, 16, 0, 4, 0, 0, 0, 140, 0, 0, 20, 82, 0, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 162, + 0, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, + 65, 84, 148, 0, 0, 0, 136, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r10g11b11_rgba16_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r10g11b11_rgba16_cs.h new file mode 100644 index 0000000..9ab45ab --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r10g11b11_rgba16_cs.h @@ -0,0 +1,555 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(3) +imad r1.y, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r0.w, r1.y, CB0[0][2].x, r0.w +iadd r0.w, r0.w, CB0[0][1].w +if_nz r0.x + if_nz r0.y + ishr r1.yzw, vThreadID.yyzy, l(0, 4, 2, 3) + ushr r2.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r0.y, r1.z, r2.x, r1.y + ibfe r2.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), vThreadID.xxxx + imad r0.y, r0.y, r2.y, r2.x + ishl r1.y, vThreadID.y, l(10) + ishr r1.y, r1.y, l(6) + and r1.y, r1.y, l(96) + iadd r1.z, r1.z, r1.w + bfi r1.w, l(1), l(1), r1.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r1.w, l(2), l(1), r1.w, l(0) + bfi r1.z, l(1), l(0), r1.z, r1.w + bfi r2.xy, l(20, 20, 0, 0), l(10, 13, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r1.yw, r1.yyyy, l(0, 2, 0, 16), r2.xxxy + bfi r1.yw, l(0, 2, 0, 2), l(0, 8, 0, 11), vThreadID.zzzz, r1.yyyw + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r2.x, l(3), l(6), r1.y + and r2.y, r1.z, l(6) + bfi r1.z, l(1), l(8), r1.z, l(0) + imad r1.z, r2.x, l(32), r1.z + imad r1.z, r2.y, l(4), r1.z + bfi r1.yw, l(0, 6, 0, 6), l(0, 0, 0, 3), r0.yyyy, r1.yyyw + bfi r0.y, l(9), l(3), r1.z, r1.w + bfi r0.y, l(6), l(0), r1.y, r0.y + else + ibfe r1.yz, l(0, 27, 29, 0), l(0, 2, 0, 0), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.y, r2.x, r1.w, r1.y + ishl r2.xz, vThreadID.yyyy, l(5, 0, 7, 0) + and r2.xz, r2.xxzx, l(448, 0, 2048, 0) + bfi r1.w, l(23), l(9), r1.y, r2.x + bfi r2.w, l(1), l(4), vThreadID.y, l(0) + iadd r1.w, r1.w, r2.w + ishl r3.xy, r2.xxxx, l(3, 2, 0, 0) + bfi r3.xy, l(23, 23, 0, 0), l(12, 11, 0, 0), r1.yyyy, r3.xyxx + imad r2.xw, r2.wwww, l(8, 0, 0, 4), r3.xxxy + bfi r1.y, l(12), l(0), r2.z, r2.x + and r2.x, r2.w, l(1792) + iadd r1.y, r1.y, r2.x + and r2.x, r2.y, l(2) + iadd r1.z, r1.z, r2.x + bfi r1.z, l(2), l(6), r1.z, l(0) + iadd r1.y, r1.y, r1.z + bfi r0.y, l(6), l(0), r1.w, r1.y + endif +else + ishl r1.x, r1.x, l(2) + imad r1.y, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.y, CB0[0][0].z, r1.x +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.yw, r0.yyyw, l(0, 4, 0, 4) +ld r1.xyzw, r0.yyyy, T0[0].zwxy +ieq r2.xyz, r0.zzzz, l(1, 2, 3, 0) +or r2.xy, r2.yzyy, r2.xyxx +if_nz r2.x + ishl r3.xyzw, r1.zwxy, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r1.zwxy, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r1.xyzw, r3.zwxy, r4.zwxy +endif +if_nz r2.y + ushr r3.xyzw, r1.zwxy, l(16, 16, 16, 16) + bfi r1.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r1.xyzw, r3.zwxy + mov r3.xy, r1.zwzz +else + mov r3.xy, r1.zwzz +endif +ushr r3.zw, r3.xxxy, l(0, 0, 21, 21) +bfi r4.xyzw, l(10, 27, 10, 27), l(6, 5, 6, 5), r3.xzyw, l(0, 0, 0, 0) +ubfe r5.xyzw, l(6, 5, 6, 5), l(4, 27, 4, 27), r3.xxyy +iadd r4.xyzw, r4.xyzw, r5.xyzw +ishl r2.zw, r3.xxxy, l(0, 0, 11, 11) +and r3.xy, r3.xyxx, l(0x001f0000, 0x001f0000, 0, 0) +bfi r2.zw, l(0, 0, 21, 21), l(0, 0, 0, 0), r3.xxxy, r2.zzzw +iadd r3.xz, r2.zzwz, r4.xxzx +iadd r3.yw, r4.yyyw, l(0, 0xffff0000, 0, 0xffff0000) +ushr r1.zw, r1.xxxy, l(0, 0, 21, 21) +bfi r4.xyzw, l(10, 27, 10, 27), l(6, 5, 6, 5), r1.xzyw, l(0, 0, 0, 0) +ubfe r5.xyzw, l(6, 5, 6, 5), l(4, 27, 4, 27), r1.xxyy +iadd r4.xyzw, r4.xyzw, r5.xyzw +ishl r1.zw, r1.xxxy, l(0, 0, 11, 11) +and r1.xy, r1.xyxx, l(0x001f0000, 0x001f0000, 0, 0) +bfi r1.xy, l(21, 21, 0, 0), l(0, 0, 0, 0), r1.xyxx, r1.zwzz +iadd r1.xz, r1.xxyx, r4.xxzx +iadd r1.yw, r4.yyyw, l(0, 0xffff0000, 0, 0xffff0000) +store_uav_typed U0[0].xyzw, r0.wwww, r3.xyzw +iadd r3.xyz, r0.wwww, l(1, 2, 3, 0) +store_uav_typed U0[0].xyzw, r3.xxxx, r1.xyzw +if_nz r0.x + mov r0.x, l(32) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r1.xyzw, r0.xxxx, T0[0].zwxy +if_nz r2.x + ishl r4.xyzw, r1.zwxy, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r1.zwxy, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r1.xyzw, r4.zwxy, r5.zwxy +endif +if_nz r2.y + ushr r2.xyzw, r1.zwxy, l(16, 16, 16, 16) + bfi r1.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r1.xyzw, r2.zwxy + mov r2.xy, r1.zwzz +else + mov r2.xy, r1.zwzz +endif +ushr r2.zw, r2.xxxy, l(0, 0, 21, 21) +bfi r4.xyzw, l(10, 27, 10, 27), l(6, 5, 6, 5), r2.xzyw, l(0, 0, 0, 0) +ubfe r5.xyzw, l(6, 5, 6, 5), l(4, 27, 4, 27), r2.xxyy +iadd r4.xyzw, r4.xyzw, r5.xyzw +ishl r0.xy, r2.xyxx, l(11, 11, 0, 0) +and r2.xy, r2.xyxx, l(0x001f0000, 0x001f0000, 0, 0) +bfi r0.xy, l(21, 21, 0, 0), l(0, 0, 0, 0), r2.xyxx, r0.xyxx +iadd r2.xz, r0.xxyx, r4.xxzx +iadd r2.yw, r4.yyyw, l(0, 0xffff0000, 0, 0xffff0000) +ushr r1.zw, r1.xxxy, l(0, 0, 21, 21) +bfi r4.xyzw, l(10, 27, 10, 27), l(6, 5, 6, 5), r1.xzyw, l(0, 0, 0, 0) +ubfe r5.xyzw, l(6, 5, 6, 5), l(4, 27, 4, 27), r1.xxyy +iadd r4.xyzw, r4.xyzw, r5.xyzw +ishl r0.xy, r1.xyxx, l(11, 11, 0, 0) +and r1.xy, r1.xyxx, l(0x001f0000, 0x001f0000, 0, 0) +bfi r0.xy, l(21, 21, 0, 0), l(0, 0, 0, 0), r1.xyxx, r0.xyxx +iadd r1.xz, r0.xxyx, r4.xxzx +iadd r1.yw, r4.yyyw, l(0, 0xffff0000, 0, 0xffff0000) +store_uav_typed U0[0].xyzw, r3.yyyy, r2.xyzw +store_uav_typed U0[0].xyzw, r3.zzzz, r1.xyzw +ret +// Approximately 150 instruction slots used +#endif + +const BYTE texture_load_r10g11b11_rgba16_cs[] = { + 68, 88, 66, 67, 224, 89, 222, 129, 166, 183, 93, 231, 201, 98, 207, 138, 82, 135, 157, + 47, 1, 0, 0, 0, 240, 25, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 84, 25, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 24, 21, 0, + 0, 81, 0, 5, 0, 70, 5, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 130, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, + 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 0, 9, 226, 0, 16, 0, 1, 0, 0, 0, 86, 6, 2, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 85, 0, + 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 182, 143, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 139, 0, 0, 14, 82, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 41, 0, 0, 6, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, + 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 96, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, + 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 162, 0, 16, 0, 1, 0, + 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 16, 162, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 166, 10, 2, 0, 86, + 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, 18, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, + 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 8, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, + 0, 0, 17, 162, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, + 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 14, 98, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, 86, + 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, + 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 41, 0, 0, 9, 82, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, + 0, 1, 64, 0, 0, 9, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 130, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 41, 0, + 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 17, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, + 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 12, 0, + 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, + 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 146, 0, 16, 0, + 2, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 6, 4, 16, 0, 3, 0, + 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 41, 0, 0, + 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, + 0, 0, 0, 0, 0, 86, 13, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, + 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 230, 116, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 2, 0, 0, + 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 2, + 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, + 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 230, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, + 10, 242, 0, 16, 0, 4, 0, 0, 0, 230, 4, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 1, 0, 0, 0, 230, 4, 16, 0, 3, 0, + 0, 0, 230, 4, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, + 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 230, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 230, 4, 16, 0, 3, 0, 0, + 0, 54, 0, 0, 5, 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 1, 0, + 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 50, 0, 16, 0, 3, 0, 0, 0, 230, + 10, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 10, 194, 0, 16, 0, + 3, 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 140, 0, 0, 20, 242, 0, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 27, 0, 0, 0, 10, + 0, 0, 0, 27, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, + 6, 0, 0, 0, 5, 0, 0, 0, 134, 13, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, + 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 5, + 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, + 27, 0, 0, 0, 4, 0, 0, 0, 27, 0, 0, 0, 6, 5, 16, 0, 3, 0, 0, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 2, + 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, + 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 31, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 21, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 166, 14, + 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 82, 0, 16, 0, 3, 0, 0, 0, 166, + 11, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 4, 0, 0, 0, 30, 0, 0, 10, + 162, 0, 16, 0, 3, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 85, 0, + 0, 10, 194, 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, + 140, 0, 0, 20, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, + 0, 27, 0, 0, 0, 10, 0, 0, 0, 27, 0, 0, 0, 2, 64, 0, 0, 6, 0, + 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 134, 13, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 6, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 4, 0, 0, 0, 27, 0, 0, 0, 4, 0, 0, 0, 27, 0, 0, 0, 6, + 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 41, 0, 0, + 10, 194, 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 1, + 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 140, 0, 0, 17, 50, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 21, 0, + 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 1, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 82, 0, 16, + 0, 1, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 4, 0, + 0, 0, 30, 0, 0, 10, 162, 0, 16, 0, 1, 0, 0, 0, 86, 13, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, + 0, 0, 255, 255, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 30, 0, + 0, 10, 114, 0, 16, 0, 3, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, + 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 32, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, + 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, + 242, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 230, 116, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, + 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 230, 4, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 230, + 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 1, + 0, 0, 0, 230, 4, 16, 0, 4, 0, 0, 0, 230, 4, 16, 0, 5, 0, 0, 0, + 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 2, 0, 0, 0, 230, 4, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, + 0, 0, 17, 242, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 1, 0, + 0, 0, 230, 4, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 2, + 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, + 50, 0, 16, 0, 2, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 21, 0, 0, + 1, 85, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 21, + 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 10, 0, 0, 0, 27, 0, 0, 0, 10, 0, 0, 0, 27, 0, 0, 0, 2, 64, 0, + 0, 6, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 134, 13, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 4, 0, 0, 0, 27, 0, 0, 0, 4, 0, 0, 0, 27, 0, + 0, 0, 6, 5, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 41, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, + 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 82, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 0, 0, 0, 0, 6, 2, 16, + 0, 4, 0, 0, 0, 30, 0, 0, 10, 162, 0, 16, 0, 2, 0, 0, 0, 86, 13, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, + 0, 0, 0, 0, 0, 255, 255, 85, 0, 0, 10, 194, 0, 16, 0, 1, 0, 0, 0, + 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 21, 0, 0, 0, 21, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 27, 0, 0, 0, 10, 0, 0, 0, 27, + 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, + 5, 0, 0, 0, 134, 13, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 242, 0, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 6, + 0, 0, 0, 5, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 27, 0, 0, 0, + 4, 0, 0, 0, 27, 0, 0, 0, 6, 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 70, + 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, + 0, 70, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 31, 0, 0, 0, + 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 0, + 0, 0, 0, 6, 2, 16, 0, 4, 0, 0, 0, 30, 0, 0, 10, 162, 0, 16, 0, + 1, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 164, 0, 0, 8, 242, 224, + 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 166, 10, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, + 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 150, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 29, + 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r10g11b11_rgba16_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r10g11b11_rgba16_scaled_cs.h new file mode 100644 index 0000000..d999648 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r10g11b11_rgba16_scaled_cs.h @@ -0,0 +1,611 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 7 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(3) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(2) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +ishl r1.w, r1.x, l(2) +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r2.z, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(3, 0, 1, 0), r1.xxxx + imad r2.z, r2.z, r3.y, r3.x + ishl r3.x, r1.z, l(10) + and r3.x, r3.x, l(6144) + bfi r3.x, l(3), l(8), r1.w, r3.x + ishr r3.x, r3.x, l(6) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r2.zw, l(0, 0, 20, 20), l(0, 0, 10, 13), r2.zzzz, l(0, 0, 0, 0) + imad r2.zw, r3.xxxx, l(0, 0, 2, 16), r2.zzzw + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 8, 11), vThreadID.zzzz, r2.zzzw + bfi r3.x, l(1), l(4), r1.z, l(0) + ubfe r3.y, l(3), l(6), r2.z + and r3.z, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.y, l(32), r0.x + imad r0.x, r3.z, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r3.xxxx, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r3.z, CB0[0][0].z, l(5) + imad r2.z, r3.x, r3.z, r2.z + ishl r3.xz, r1.zzzz, l(5, 0, 7, 0) + and r3.xz, r3.xxzx, l(448, 0, 2048, 0) + bfi r3.w, l(3), l(3), r1.w, r3.x + bfi r3.w, l(23), l(9), r2.z, r3.w + bfi r4.x, l(1), l(4), r1.z, l(0) + iadd r3.w, r3.w, r4.x + ishl r4.yz, r3.xxxx, l(0, 3, 2, 0) + bfi r4.yz, l(0, 3, 3, 0), l(0, 6, 5, 0), r1.wwww, r4.yyzy + bfi r4.yz, l(0, 23, 23, 0), l(0, 12, 11, 0), r2.zzzz, r4.yyzy + imad r4.xy, r4.xxxx, l(8, 4, 0, 0), r4.yzyy + bfi r1.w, l(12), l(0), r3.z, r4.x + and r2.z, r4.y, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.w, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].zwxy +ieq r1.xzw, r0.yyyy, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r4.xyzw, r3.zwxy, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.zwxy, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.zwxy, r5.zwxy +endif +if_nz r1.z + ushr r4.xyzw, r3.zwxy, l(16, 16, 16, 16) + bfi r3.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r3.xyzw, r4.zwxy + mov r4.xy, r3.zwzz +else + mov r4.xy, r3.zwzz +endif +ushr r4.zw, r4.xxxy, l(0, 0, 21, 21) +bfi r5.xyzw, l(10, 27, 10, 27), l(6, 5, 6, 5), r4.xzyw, l(0, 0, 0, 0) +ubfe r6.xyzw, l(6, 5, 6, 5), l(4, 27, 4, 27), r4.xxyy +iadd r5.xyzw, r5.xyzw, r6.xyzw +ishl r2.yz, r4.xxyx, l(0, 11, 11, 0) +and r4.xy, r4.xyxx, l(0x001f0000, 0x001f0000, 0, 0) +bfi r2.yz, l(0, 21, 21, 0), l(0, 0, 0, 0), r4.xxyx, r2.yyzy +iadd r4.xz, r2.yyzy, r5.xxzx +iadd r4.yw, r5.yyyw, l(0, 0xffff0000, 0, 0xffff0000) +ushr r3.zw, r3.xxxy, l(0, 0, 21, 21) +bfi r5.xyzw, l(10, 27, 10, 27), l(6, 5, 6, 5), r3.xzyw, l(0, 0, 0, 0) +ubfe r6.xyzw, l(6, 5, 6, 5), l(4, 27, 4, 27), r3.xxyy +iadd r5.xyzw, r5.xyzw, r6.xyzw +ishl r2.yz, r3.xxyx, l(0, 11, 11, 0) +and r3.xy, r3.xyxx, l(0x001f0000, 0x001f0000, 0, 0) +bfi r2.yz, l(0, 21, 21, 0), l(0, 0, 0, 0), r3.xxyx, r2.yyzy +iadd r3.xz, r2.yyzy, r5.xxzx +iadd r3.yw, r5.yyyw, l(0, 0xffff0000, 0, 0xffff0000) +store_uav_typed U0[0].xyzw, r1.yyyy, r4.xyzw +iadd r2.yzw, r1.yyyy, l(0, 1, 2, 3) +store_uav_typed U0[0].xyzw, r2.yyyy, r3.xyzw +ult r0.y, l(1), r0.z +if_nz r0.y + udiv r0.y, null, r2.x, r0.z + imad r0.y, -r0.y, r0.z, r2.x + iadd r1.w, r0.y, l(1) + ieq r1.w, r0.z, r1.w + if_nz r1.w + ishl r0.z, r0.z, l(5) + ishl r0.y, r0.y, l(4) + iadd r0.y, -r0.y, r0.z + else + mov r0.y, l(16) + endif +else + mov r0.y, l(32) +endif +imul null, r0.y, r0.w, r0.y +ushr r0.y, r0.y, l(4) +iadd r0.x, r0.y, r0.x +ld r0.xyzw, r0.xxxx, T0[0].zwxy +if_nz r1.x + ishl r3.xyzw, r0.zwxy, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r0.zwxy, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r0.xyzw, r3.zwxy, r4.zwxy +endif +if_nz r1.z + ushr r3.xyzw, r0.zwxy, l(16, 16, 16, 16) + bfi r0.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r0.xyzw, r3.zwxy + mov r3.xy, r0.zwzz +else + mov r3.xy, r0.zwzz +endif +ushr r3.zw, r3.xxxy, l(0, 0, 21, 21) +bfi r4.xyzw, l(10, 27, 10, 27), l(6, 5, 6, 5), r3.xzyw, l(0, 0, 0, 0) +ubfe r5.xyzw, l(6, 5, 6, 5), l(4, 27, 4, 27), r3.xxyy +iadd r4.xyzw, r4.xyzw, r5.xyzw +ishl r1.xz, r3.xxyx, l(11, 0, 11, 0) +and r2.xy, r3.xyxx, l(0x001f0000, 0x001f0000, 0, 0) +bfi r1.xz, l(21, 0, 21, 0), l(0, 0, 0, 0), r2.xxyx, r1.xxzx +iadd r3.xz, r1.xxzx, r4.xxzx +iadd r3.yw, r4.yyyw, l(0, 0xffff0000, 0, 0xffff0000) +ushr r0.zw, r0.xxxy, l(0, 0, 21, 21) +bfi r4.xyzw, l(10, 27, 10, 27), l(6, 5, 6, 5), r0.xzyw, l(0, 0, 0, 0) +ubfe r5.xyzw, l(6, 5, 6, 5), l(4, 27, 4, 27), r0.xxyy +iadd r4.xyzw, r4.xyzw, r5.xyzw +ishl r0.zw, r0.xxxy, l(0, 0, 11, 11) +and r0.xy, r0.xyxx, l(0x001f0000, 0x001f0000, 0, 0) +bfi r0.xy, l(21, 21, 0, 0), l(0, 0, 0, 0), r0.xyxx, r0.zwzz +iadd r0.xz, r0.xxyx, r4.xxzx +iadd r0.yw, r4.yyyw, l(0, 0xffff0000, 0, 0xffff0000) +store_uav_typed U0[0].xyzw, r2.zzzz, r3.xyzw +store_uav_typed U0[0].xyzw, r2.wwww, r0.xyzw +ret +// Approximately 170 instruction slots used +#endif + +const BYTE texture_load_r10g11b11_rgba16_scaled_cs[] = { + 68, 88, 66, 67, 178, 254, 250, 55, 88, 175, 35, 103, 187, 50, 111, 251, 29, 187, 118, + 234, 1, 0, 0, 0, 156, 28, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 0, 28, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 196, 23, 0, + 0, 81, 0, 5, 0, 241, 5, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 7, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, + 0, 42, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 85, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, + 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 10, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 24, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 194, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, + 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, + 0, 2, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 166, 14, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 166, 10, + 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 9, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 15, 194, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 9, 66, 0, 16, 0, 3, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, + 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, + 82, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 23, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, + 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 4, 0, + 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 12, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, + 0, 2, 0, 0, 0, 86, 6, 16, 0, 4, 0, 0, 0, 35, 0, 0, 12, 50, 0, + 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, + 4, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, + 166, 11, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, + 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 10, 210, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 230, 4, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 230, 4, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, + 0, 0, 230, 4, 16, 0, 4, 0, 0, 0, 230, 4, 16, 0, 5, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 230, 4, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 230, 4, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 4, 0, + 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 50, + 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, + 85, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 21, 0, + 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 10, + 0, 0, 0, 27, 0, 0, 0, 10, 0, 0, 0, 27, 0, 0, 0, 2, 64, 0, 0, + 6, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 134, 13, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 4, 0, 0, 0, 27, 0, 0, 0, 4, 0, 0, 0, 27, 0, 0, + 0, 6, 5, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 41, + 0, 0, 10, 98, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 1, + 16, 0, 4, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 82, + 0, 16, 0, 4, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, + 5, 0, 0, 0, 30, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, + 0, 0, 0, 0, 255, 255, 85, 0, 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 6, + 4, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 21, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 10, 0, 0, 0, 27, 0, 0, 0, 10, 0, 0, 0, 27, 0, + 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, + 0, 0, 0, 134, 13, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, + 0, 6, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 6, 0, + 0, 0, 5, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 27, 0, 0, 0, 4, + 0, 0, 0, 27, 0, 0, 0, 6, 5, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 6, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 2, 0, 0, 0, 6, 1, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 11, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, + 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 31, 0, 0, 0, 31, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, + 0, 30, 0, 0, 7, 82, 0, 16, 0, 3, 0, 0, 0, 86, 6, 16, 0, 2, 0, + 0, 0, 6, 2, 16, 0, 5, 0, 0, 0, 30, 0, 0, 10, 162, 0, 16, 0, 3, + 0, 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 164, 0, 0, 8, 242, 224, 33, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 14, + 16, 0, 4, 0, 0, 0, 30, 0, 0, 10, 226, 0, 16, 0, 2, 0, 0, 0, 86, + 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 2, 0, 0, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 79, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, + 0, 0, 0, 0, 78, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, + 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, + 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 31, + 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, + 0, 41, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 8, 34, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 54, 0, + 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 21, + 0, 0, 1, 38, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, + 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, + 242, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 230, 116, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, + 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 230, 4, 16, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 230, + 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 0, + 0, 0, 0, 230, 4, 16, 0, 3, 0, 0, 0, 230, 4, 16, 0, 4, 0, 0, 0, + 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, + 10, 242, 0, 16, 0, 3, 0, 0, 0, 230, 4, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, + 0, 0, 17, 242, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 230, 4, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 3, + 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, + 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 21, 0, 0, + 1, 85, 0, 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 21, + 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 10, 0, 0, 0, 27, 0, 0, 0, 10, 0, 0, 0, 27, 0, 0, 0, 2, 64, 0, + 0, 6, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 134, 13, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 4, 0, 0, 0, 27, 0, 0, 0, 4, 0, 0, 0, 27, 0, + 0, 0, 6, 5, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 41, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 140, 0, 0, 17, 82, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 21, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + 1, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, + 82, 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 6, 2, 16, + 0, 4, 0, 0, 0, 30, 0, 0, 10, 162, 0, 16, 0, 3, 0, 0, 0, 86, 13, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, + 0, 0, 0, 0, 0, 255, 255, 85, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, + 6, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 21, 0, 0, 0, 21, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 27, 0, 0, 0, 10, 0, 0, 0, 27, + 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, + 5, 0, 0, 0, 134, 13, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 242, 0, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 6, + 0, 0, 0, 5, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 27, 0, 0, 0, + 4, 0, 0, 0, 27, 0, 0, 0, 6, 5, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, + 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 6, + 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 31, 0, 0, 0, + 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 0, + 0, 0, 0, 6, 2, 16, 0, 4, 0, 0, 0, 30, 0, 0, 10, 162, 0, 16, 0, + 0, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 164, 0, 0, 8, 242, 224, + 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, + 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 170, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 34, + 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r10g11b11_rgba16_snorm_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r10g11b11_rgba16_snorm_cs.h new file mode 100644 index 0000000..b450e5e --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r10g11b11_rgba16_snorm_cs.h @@ -0,0 +1,877 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(3) +imad r1.y, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r0.w, r1.y, CB0[0][2].x, r0.w +iadd r0.w, r0.w, CB0[0][1].w +if_nz r0.x + if_nz r0.y + ishr r1.yzw, vThreadID.yyzy, l(0, 4, 2, 3) + ushr r2.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r0.y, r1.z, r2.x, r1.y + ibfe r2.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), vThreadID.xxxx + imad r0.y, r0.y, r2.y, r2.x + ishl r1.y, vThreadID.y, l(10) + ishr r1.y, r1.y, l(6) + and r1.y, r1.y, l(96) + iadd r1.z, r1.z, r1.w + bfi r1.w, l(1), l(1), r1.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r1.w, l(2), l(1), r1.w, l(0) + bfi r1.z, l(1), l(0), r1.z, r1.w + bfi r2.xy, l(20, 20, 0, 0), l(10, 13, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r1.yw, r1.yyyy, l(0, 2, 0, 16), r2.xxxy + bfi r1.yw, l(0, 2, 0, 2), l(0, 8, 0, 11), vThreadID.zzzz, r1.yyyw + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r2.x, l(3), l(6), r1.y + and r2.y, r1.z, l(6) + bfi r1.z, l(1), l(8), r1.z, l(0) + imad r1.z, r2.x, l(32), r1.z + imad r1.z, r2.y, l(4), r1.z + bfi r1.yw, l(0, 6, 0, 6), l(0, 0, 0, 3), r0.yyyy, r1.yyyw + bfi r0.y, l(9), l(3), r1.z, r1.w + bfi r0.y, l(6), l(0), r1.y, r0.y + else + ibfe r1.yz, l(0, 27, 29, 0), l(0, 2, 0, 0), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.y, r2.x, r1.w, r1.y + ishl r2.xz, vThreadID.yyyy, l(5, 0, 7, 0) + and r2.xz, r2.xxzx, l(448, 0, 2048, 0) + bfi r1.w, l(23), l(9), r1.y, r2.x + bfi r2.w, l(1), l(4), vThreadID.y, l(0) + iadd r1.w, r1.w, r2.w + ishl r3.xy, r2.xxxx, l(3, 2, 0, 0) + bfi r3.xy, l(23, 23, 0, 0), l(12, 11, 0, 0), r1.yyyy, r3.xyxx + imad r2.xw, r2.wwww, l(8, 0, 0, 4), r3.xxxy + bfi r1.y, l(12), l(0), r2.z, r2.x + and r2.x, r2.w, l(1792) + iadd r1.y, r1.y, r2.x + and r2.x, r2.y, l(2) + iadd r1.z, r1.z, r2.x + bfi r1.z, l(2), l(6), r1.z, l(0) + iadd r1.y, r1.y, r1.z + bfi r0.y, l(6), l(0), r1.w, r1.y + endif +else + ishl r1.x, r1.x, l(2) + imad r1.y, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.y, CB0[0][0].z, r1.x +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.yw, r0.yyyw, l(0, 4, 0, 4) +ld r1.xyzw, r0.yyyy, T0[0].xyzw +ieq r2.xyz, r0.zzzz, l(1, 2, 3, 0) +or r2.xy, r2.yzyy, r2.xyxx +if_nz r2.x + ishl r3.xyzw, r1.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r1.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r1.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r2.y + ushr r3.xyzw, r1.xyzw, l(16, 16, 16, 16) + bfi r1.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r1.xyzw, r3.xyzw +endif +and r2.zw, r1.xxxy, l(0, 0, 1023, 1023) +ubfe r3.xyzw, l(1, 1, 11, 11), l(9, 9, 10, 10), r1.xyxy +ieq r4.xy, r2.zwzz, l(512, 512, 0, 0) +movc r2.zw, r4.xxxy, l(0,0,513,513), r2.zzzw +movc r4.xyzw, r3.xyxy, l(1023,1023,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r2.zw, r2.zzzw, r4.xxxy +iadd r2.zw, r3.xxxy, r2.zzzw +ishl r4.xy, r2.zwzz, l(6, 6, 0, 0) +ushr r2.zw, r2.zzzw, l(0, 0, 3, 3) +or r2.zw, r2.zzzw, r4.xxxy +xor r2.zw, r4.zzzw, r2.zzzw +iadd r2.zw, r3.xxxy, r2.zzzw +ubfe r3.xy, l(1, 1, 0, 0), l(20, 20, 0, 0), r1.xyxx +ieq r4.xy, r3.zwzz, l(1024, 1024, 0, 0) +movc r3.zw, r4.xxxy, l(0,0,1025,1025), r3.zzzw +movc r4.xyzw, r3.xyxy, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r3.zw, r3.zzzw, r4.xxxy +iadd r3.zw, r3.xxxy, r3.zzzw +ishl r4.xy, r3.zwzz, l(5, 5, 0, 0) +ushr r3.zw, r3.zzzw, l(0, 0, 5, 5) +or r3.zw, r3.zzzw, r4.xxxy +xor r3.zw, r4.zzzw, r3.zzzw +iadd r3.xy, r3.xyxx, r3.zwzz +ishl r3.xy, r3.xyxx, l(16, 16, 0, 0) +or r3.xz, r2.zzwz, r3.xxyx +ushr r1.xy, r1.xyxx, l(21, 21, 0, 0) +ushr r2.zw, r1.xxxy, l(0, 0, 10, 10) +ieq r4.xy, r1.xyxx, l(1024, 1024, 0, 0) +movc r1.xy, r4.xyxx, l(1025,1025,0,0), r1.xyxx +movc r4.xyzw, r2.zwzw, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r1.xy, r1.xyxx, r4.xyxx +iadd r1.xy, r2.zwzz, r1.xyxx +ishl r4.xy, r1.xyxx, l(5, 5, 0, 0) +ushr r1.xy, r1.xyxx, l(5, 5, 0, 0) +or r1.xy, r1.xyxx, r4.xyxx +xor r1.xy, r4.zwzz, r1.xyxx +iadd r1.xy, r2.zwzz, r1.xyxx +or r3.yw, r1.xxxy, l(0, 0x7fff0000, 0, 0x7fff0000) +and r1.xy, r1.zwzz, l(1023, 1023, 0, 0) +ubfe r4.xyzw, l(1, 1, 11, 11), l(9, 9, 10, 10), r1.zwzw +ieq r2.zw, r1.xxxy, l(0, 0, 512, 512) +movc r1.xy, r2.zwzz, l(513,513,0,0), r1.xyxx +movc r5.xyzw, r4.xyxy, l(1023,1023,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r1.xy, r1.xyxx, r5.xyxx +iadd r1.xy, r4.xyxx, r1.xyxx +ishl r2.zw, r1.xxxy, l(0, 0, 6, 6) +ushr r1.xy, r1.xyxx, l(3, 3, 0, 0) +or r1.xy, r1.xyxx, r2.zwzz +xor r1.xy, r5.zwzz, r1.xyxx +iadd r1.xy, r4.xyxx, r1.xyxx +ubfe r2.zw, l(0, 0, 1, 1), l(0, 0, 20, 20), r1.zzzw +ieq r4.xy, r4.zwzz, l(1024, 1024, 0, 0) +movc r4.xy, r4.xyxx, l(1025,1025,0,0), r4.zwzz +movc r5.xyzw, r2.zwzw, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r4.xy, r4.xyxx, r5.xyxx +iadd r4.xy, r2.zwzz, r4.xyxx +ishl r4.zw, r4.xxxy, l(0, 0, 5, 5) +ushr r4.xy, r4.xyxx, l(5, 5, 0, 0) +or r4.xy, r4.xyxx, r4.zwzz +xor r4.xy, r5.zwzz, r4.xyxx +iadd r2.zw, r2.zzzw, r4.xxxy +ishl r2.zw, r2.zzzw, l(0, 0, 16, 16) +or r4.xz, r1.xxyx, r2.zzwz +ushr r1.xy, r1.zwzz, l(21, 21, 0, 0) +ushr r1.zw, r1.xxxy, l(0, 0, 10, 10) +ieq r2.zw, r1.xxxy, l(0, 0, 1024, 1024) +movc r1.xy, r2.zwzz, l(1025,1025,0,0), r1.xyxx +movc r5.xyzw, r1.zwzw, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r1.xy, r1.xyxx, r5.xyxx +iadd r1.xy, r1.zwzz, r1.xyxx +ishl r2.zw, r1.xxxy, l(0, 0, 5, 5) +ushr r1.xy, r1.xyxx, l(5, 5, 0, 0) +or r1.xy, r1.xyxx, r2.zwzz +xor r1.xy, r5.zwzz, r1.xyxx +iadd r1.xy, r1.zwzz, r1.xyxx +or r4.yw, r1.xxxy, l(0, 0x7fff0000, 0, 0x7fff0000) +store_uav_typed U0[0].xyzw, r0.wwww, r3.xyzw +iadd r1.xyz, r0.wwww, l(1, 2, 3, 0) +store_uav_typed U0[0].xyzw, r1.xxxx, r4.xyzw +if_nz r0.x + mov r0.x, l(32) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r3.xyzw, r0.xxxx, T0[0].xyzw +if_nz r2.x + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +if_nz r2.y + ushr r2.xyzw, r3.xyzw, l(16, 16, 16, 16) + bfi r3.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r3.xyzw, r2.xyzw +endif +and r0.xy, r3.xyxx, l(1023, 1023, 0, 0) +ubfe r2.xyzw, l(1, 1, 11, 11), l(9, 9, 10, 10), r3.xyxy +ieq r1.xw, r0.xxxy, l(512, 0, 0, 512) +movc r0.xy, r1.xwxx, l(513,513,0,0), r0.xyxx +movc r4.xyzw, r2.xyxy, l(1023,1023,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r0.xy, r0.xyxx, r4.xyxx +iadd r0.xy, r2.xyxx, r0.xyxx +ishl r1.xw, r0.xxxy, l(6, 0, 0, 6) +ushr r0.xy, r0.xyxx, l(3, 3, 0, 0) +or r0.xy, r0.xyxx, r1.xwxx +xor r0.xy, r4.zwzz, r0.xyxx +iadd r0.xy, r2.xyxx, r0.xyxx +ubfe r1.xw, l(1, 0, 0, 1), l(20, 0, 0, 20), r3.xxxy +ieq r2.xy, r2.zwzz, l(1024, 1024, 0, 0) +movc r2.xy, r2.xyxx, l(1025,1025,0,0), r2.zwzz +movc r4.xyzw, r1.xwxw, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r2.xy, r2.xyxx, r4.xyxx +iadd r2.xy, r1.xwxx, r2.xyxx +ishl r2.zw, r2.xxxy, l(0, 0, 5, 5) +ushr r2.xy, r2.xyxx, l(5, 5, 0, 0) +or r2.xy, r2.xyxx, r2.zwzz +xor r2.xy, r4.zwzz, r2.xyxx +iadd r1.xw, r1.xxxw, r2.xxxy +ishl r1.xw, r1.xxxw, l(16, 0, 0, 16) +or r2.xz, r0.xxyx, r1.xxwx +ushr r0.xy, r3.xyxx, l(21, 21, 0, 0) +ushr r1.xw, r0.xxxy, l(10, 0, 0, 10) +ieq r3.xy, r0.xyxx, l(1024, 1024, 0, 0) +movc r0.xy, r3.xyxx, l(1025,1025,0,0), r0.xyxx +movc r4.xyzw, r1.xwxw, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r0.xy, r0.xyxx, r4.xyxx +iadd r0.xy, r1.xwxx, r0.xyxx +ishl r3.xy, r0.xyxx, l(5, 5, 0, 0) +ushr r0.xy, r0.xyxx, l(5, 5, 0, 0) +or r0.xy, r0.xyxx, r3.xyxx +xor r0.xy, r4.zwzz, r0.xyxx +iadd r0.xy, r1.xwxx, r0.xyxx +or r2.yw, r0.xxxy, l(0, 0x7fff0000, 0, 0x7fff0000) +and r0.xy, r3.zwzz, l(1023, 1023, 0, 0) +ubfe r4.xyzw, l(1, 1, 11, 11), l(9, 9, 10, 10), r3.zwzw +ieq r1.xw, r0.xxxy, l(512, 0, 0, 512) +movc r0.xy, r1.xwxx, l(513,513,0,0), r0.xyxx +movc r5.xyzw, r4.xyxy, l(1023,1023,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r0.xy, r0.xyxx, r5.xyxx +iadd r0.xy, r4.xyxx, r0.xyxx +ishl r1.xw, r0.xxxy, l(6, 0, 0, 6) +ushr r0.xy, r0.xyxx, l(3, 3, 0, 0) +or r0.xy, r0.xyxx, r1.xwxx +xor r0.xy, r5.zwzz, r0.xyxx +iadd r0.xy, r4.xyxx, r0.xyxx +ubfe r1.xw, l(1, 0, 0, 1), l(20, 0, 0, 20), r3.zzzw +ieq r3.xy, r4.zwzz, l(1024, 1024, 0, 0) +movc r3.xy, r3.xyxx, l(1025,1025,0,0), r4.zwzz +movc r4.xyzw, r1.xwxw, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r3.xy, r3.xyxx, r4.xyxx +iadd r3.xy, r1.xwxx, r3.xyxx +ishl r4.xy, r3.xyxx, l(5, 5, 0, 0) +ushr r3.xy, r3.xyxx, l(5, 5, 0, 0) +or r3.xy, r3.xyxx, r4.xyxx +xor r3.xy, r4.zwzz, r3.xyxx +iadd r1.xw, r1.xxxw, r3.xxxy +ishl r1.xw, r1.xxxw, l(16, 0, 0, 16) +or r4.xz, r0.xxyx, r1.xxwx +ushr r0.xy, r3.zwzz, l(21, 21, 0, 0) +ushr r1.xw, r0.xxxy, l(10, 0, 0, 10) +ieq r3.xy, r0.xyxx, l(1024, 1024, 0, 0) +movc r0.xy, r3.xyxx, l(1025,1025,0,0), r0.xyxx +movc r3.xyzw, r1.xwxw, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r0.xy, r0.xyxx, r3.xyxx +iadd r0.xy, r1.xwxx, r0.xyxx +ishl r3.xy, r0.xyxx, l(5, 5, 0, 0) +ushr r0.xy, r0.xyxx, l(5, 5, 0, 0) +or r0.xy, r0.xyxx, r3.xyxx +xor r0.xy, r3.zwzz, r0.xyxx +iadd r0.xy, r1.xwxx, r0.xyxx +or r4.yw, r0.xxxy, l(0, 0x7fff0000, 0, 0x7fff0000) +store_uav_typed U0[0].xyzw, r1.yyyy, r2.xyzw +store_uav_typed U0[0].xyzw, r1.zzzz, r4.xyzw +ret +// Approximately 260 instruction slots used +#endif + +const BYTE texture_load_r10g11b11_rgba16_snorm_cs[] = { + 68, 88, 66, 67, 108, 157, 131, 183, 213, 174, 42, 36, 189, 18, 116, 193, 200, 168, 42, + 83, 1, 0, 0, 0, 168, 41, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 12, 41, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 208, 36, 0, + 0, 81, 0, 5, 0, 52, 9, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 130, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, + 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 0, 9, 226, 0, 16, 0, 1, 0, 0, 0, 86, 6, 2, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 85, 0, + 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 182, 143, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 139, 0, 0, 14, 82, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 41, 0, 0, 6, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, + 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 96, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, + 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 162, 0, 16, 0, 1, 0, + 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 16, 162, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 166, 10, 2, 0, 86, + 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, 18, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, + 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 8, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, + 0, 0, 17, 162, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, + 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 14, 98, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, 86, + 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, + 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 41, 0, 0, 9, 82, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, + 0, 1, 64, 0, 0, 9, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 130, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 41, 0, + 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 17, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, + 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 12, 0, + 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, + 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 146, 0, 16, 0, + 2, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 6, 4, 16, 0, 3, 0, + 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 41, 0, 0, + 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, + 0, 0, 0, 0, 0, 86, 13, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, + 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 2, 0, 0, + 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 2, + 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, + 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, + 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, + 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 21, 0, 0, 1, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 70, 4, 16, 0, 1, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, 4, + 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 194, 0, 16, + 0, 2, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 166, 14, 16, 0, 2, + 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 4, 0, 0, 0, 70, 4, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 255, 0, + 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 166, + 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, + 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 166, 14, 16, + 0, 2, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, + 166, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 2, 0, + 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 87, + 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, + 166, 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, + 0, 6, 4, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 138, 0, + 0, 15, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, + 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, + 0, 32, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 55, 0, 0, 12, 194, 0, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0, + 0, 1, 4, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 55, 0, 0, 15, 242, 0, + 16, 0, 4, 0, 0, 0, 70, 4, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, + 7, 0, 0, 255, 7, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, + 7, 194, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 6, 4, + 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 194, 0, 16, 0, 3, 0, 0, 0, 6, + 4, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, + 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 60, 0, 0, 7, 194, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, + 0, 6, 4, 16, 0, 4, 0, 0, 0, 87, 0, 0, 7, 194, 0, 16, 0, 3, 0, + 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 30, + 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, + 230, 10, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, + 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, 3, + 0, 0, 0, 166, 11, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, + 85, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, + 10, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, 1, 0, 0, 0, 70, + 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 55, 0, 0, + 15, 242, 0, 16, 0, 4, 0, 0, 0, 230, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 87, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, + 0, 70, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 1, 0, + 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 41, + 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 85, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, + 1, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, + 0, 1, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 1, 0, + 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 2, + 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 60, 0, 0, 10, 162, 0, 16, 0, + 3, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 255, 127, 1, 0, 0, 10, 50, 0, + 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, + 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 11, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 230, 14, 16, 0, 1, 0, 0, 0, 32, + 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 55, 0, 0, 12, 50, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, + 5, 0, 0, 0, 70, 4, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 50, + 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, + 5, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 194, 0, + 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 85, 0, 0, 10, + 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, + 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 230, + 10, 16, 0, 2, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, + 230, 10, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, + 7, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 70, 0, + 16, 0, 1, 0, 0, 0, 138, 0, 0, 15, 194, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, + 0, 166, 14, 16, 0, 1, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, 4, 0, + 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, + 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 4, 0, + 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 10, 16, 0, 4, 0, + 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, 230, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 255, 0, 0, + 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, + 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 50, + 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, + 4, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, + 0, 0, 5, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, + 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, + 0, 70, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 87, 0, + 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 70, + 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, + 166, 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 41, 0, 0, + 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 4, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, + 166, 11, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, + 0, 230, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 1, + 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 32, 0, 0, 10, 194, 0, 16, + 0, 2, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 55, 0, 0, 12, 50, + 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 1, 4, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 1, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, 230, 14, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, + 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, + 0, 70, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 30, 0, + 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 70, + 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, + 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 0, 0, 0, 5, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 1, 0, + 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, + 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, + 0, 87, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 5, 0, + 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 1, + 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, + 60, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, + 255, 127, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 10, + 114, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 164, 0, + 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 32, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, + 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 50, 0, 16, + 0, 0, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 242, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 11, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, 4, 16, 0, 3, 0, 0, 0, 32, 0, + 0, 10, 146, 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 55, 0, 0, 12, 50, 0, 16, 0, 0, 0, 0, 0, 198, 0, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 4, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, + 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 4, + 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 2, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 146, 0, 16, + 0, 1, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 85, 0, 0, 10, 50, + 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, + 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 198, 0, + 16, 0, 1, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 230, + 10, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, + 0, 0, 0, 0, 0, 138, 0, 0, 15, 146, 0, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, + 6, 4, 16, 0, 3, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, + 0, 230, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, 2, + 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 4, 0, 0, + 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, + 0, 55, 0, 0, 15, 242, 0, 16, 0, 4, 0, 0, 0, 198, 12, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 255, 0, 0, 255, + 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, + 0, 2, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 50, 0, + 16, 0, 2, 0, 0, 0, 198, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 2, + 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, + 0, 5, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, + 70, 0, 16, 0, 2, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 87, 0, 0, + 7, 50, 0, 16, 0, 2, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 146, 0, 16, 0, 1, 0, 0, 0, 6, + 12, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, + 146, 0, 16, 0, 1, 0, 0, 0, 6, 12, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 60, 0, + 0, 7, 82, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 0, 0, 0, 0, 6, + 3, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 146, 0, 16, 0, 1, 0, + 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, + 3, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 50, 0, + 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, + 4, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 4, 0, 0, 0, 198, 12, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 255, + 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, + 7, 50, 0, 16, 0, 0, 0, 0, 0, 198, 0, 16, 0, 1, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, + 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, + 87, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, + 0, 70, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, + 0, 0, 198, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 60, + 0, 0, 10, 162, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 255, + 127, 1, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 9, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 230, 14, + 16, 0, 3, 0, 0, 0, 32, 0, 0, 10, 146, 0, 16, 0, 1, 0, 0, 0, 6, + 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, 0, 0, 0, + 0, 198, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 2, 0, 0, 1, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 55, + 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, 70, 4, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 255, 0, 0, 255, 255, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, + 0, 41, 0, 0, 10, 146, 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, 198, 0, 16, 0, 1, 0, 0, 0, 87, 0, 0, 7, 50, + 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 15, 146, 0, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 20, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 32, 0, 0, + 10, 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 230, 10, 16, 0, 4, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 4, 0, + 0, 0, 198, 12, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, + 7, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, + 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 4, 0, + 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 198, 0, 16, 0, 1, + 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, + 4, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 50, 0, + 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 5, + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, + 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, + 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 146, + 0, 16, 0, 1, 0, 0, 0, 6, 12, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, + 3, 0, 0, 0, 41, 0, 0, 10, 146, 0, 16, 0, 1, 0, 0, 0, 6, 12, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, 4, 0, 0, 0, 6, + 1, 16, 0, 0, 0, 0, 0, 6, 3, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 50, 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 0, 10, 146, 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, + 32, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, + 0, 3, 0, 0, 0, 198, 12, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 7, + 0, 0, 255, 7, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 3, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 198, 0, + 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, + 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, + 10, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, + 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 3, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, + 0, 230, 10, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 198, 0, 16, 0, 1, 0, 0, 0, 70, + 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, + 6, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 255, + 127, 0, 0, 0, 0, 0, 0, 255, 127, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 166, 10, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 148, 0, 0, 0, 4, 1, 0, 0, 6, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 89, 0, 0, 0, 5, + 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r10g11b11_rgba16_snorm_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r10g11b11_rgba16_snorm_scaled_cs.h new file mode 100644 index 0000000..5b6e565 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r10g11b11_rgba16_snorm_scaled_cs.h @@ -0,0 +1,933 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 7 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(3) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(2) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +ishl r1.w, r1.x, l(2) +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r2.z, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(3, 0, 1, 0), r1.xxxx + imad r2.z, r2.z, r3.y, r3.x + ishl r3.x, r1.z, l(10) + and r3.x, r3.x, l(6144) + bfi r3.x, l(3), l(8), r1.w, r3.x + ishr r3.x, r3.x, l(6) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r2.zw, l(0, 0, 20, 20), l(0, 0, 10, 13), r2.zzzz, l(0, 0, 0, 0) + imad r2.zw, r3.xxxx, l(0, 0, 2, 16), r2.zzzw + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 8, 11), vThreadID.zzzz, r2.zzzw + bfi r3.x, l(1), l(4), r1.z, l(0) + ubfe r3.y, l(3), l(6), r2.z + and r3.z, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.y, l(32), r0.x + imad r0.x, r3.z, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r3.xxxx, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r3.z, CB0[0][0].z, l(5) + imad r2.z, r3.x, r3.z, r2.z + ishl r3.xz, r1.zzzz, l(5, 0, 7, 0) + and r3.xz, r3.xxzx, l(448, 0, 2048, 0) + bfi r3.w, l(3), l(3), r1.w, r3.x + bfi r3.w, l(23), l(9), r2.z, r3.w + bfi r4.x, l(1), l(4), r1.z, l(0) + iadd r3.w, r3.w, r4.x + ishl r4.yz, r3.xxxx, l(0, 3, 2, 0) + bfi r4.yz, l(0, 3, 3, 0), l(0, 6, 5, 0), r1.wwww, r4.yyzy + bfi r4.yz, l(0, 23, 23, 0), l(0, 12, 11, 0), r2.zzzz, r4.yyzy + imad r4.xy, r4.xxxx, l(8, 4, 0, 0), r4.yzyy + bfi r1.w, l(12), l(0), r3.z, r4.x + and r2.z, r4.y, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.w, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].xyzw +ieq r1.xzw, r0.yyyy, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +if_nz r1.z + ushr r4.xyzw, r3.xyzw, l(16, 16, 16, 16) + bfi r3.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r3.xyzw, r4.xyzw +endif +and r2.yz, r3.xxyx, l(0, 1023, 1023, 0) +ubfe r4.xyzw, l(1, 1, 11, 11), l(9, 9, 10, 10), r3.xyxy +ieq r5.xy, r2.yzyy, l(512, 512, 0, 0) +movc r2.yz, r5.xxyx, l(0,513,513,0), r2.yyzy +movc r5.xyzw, r4.xyxy, l(1023,1023,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r2.yz, r2.yyzy, r5.xxyx +iadd r2.yz, r4.xxyx, r2.yyzy +ishl r5.xy, r2.yzyy, l(6, 6, 0, 0) +ushr r2.yz, r2.yyzy, l(0, 3, 3, 0) +or r2.yz, r2.yyzy, r5.xxyx +xor r2.yz, r5.zzwz, r2.yyzy +iadd r2.yz, r4.xxyx, r2.yyzy +ubfe r4.xy, l(1, 1, 0, 0), l(20, 20, 0, 0), r3.xyxx +ieq r5.xy, r4.zwzz, l(1024, 1024, 0, 0) +movc r4.zw, r5.xxxy, l(0,0,1025,1025), r4.zzzw +movc r5.xyzw, r4.xyxy, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r4.zw, r4.zzzw, r5.xxxy +iadd r4.zw, r4.xxxy, r4.zzzw +ishl r5.xy, r4.zwzz, l(5, 5, 0, 0) +ushr r4.zw, r4.zzzw, l(0, 0, 5, 5) +or r4.zw, r4.zzzw, r5.xxxy +xor r4.zw, r5.zzzw, r4.zzzw +iadd r4.xy, r4.xyxx, r4.zwzz +ishl r4.xy, r4.xyxx, l(16, 16, 0, 0) +or r4.xz, r2.yyzy, r4.xxyx +ushr r2.yz, r3.xxyx, l(0, 21, 21, 0) +ushr r3.xy, r2.yzyy, l(10, 10, 0, 0) +ieq r5.xy, r2.yzyy, l(1024, 1024, 0, 0) +movc r2.yz, r5.xxyx, l(0,1025,1025,0), r2.yyzy +movc r5.xyzw, r3.xyxy, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r2.yz, r2.yyzy, r5.xxyx +iadd r2.yz, r3.xxyx, r2.yyzy +ishl r5.xy, r2.yzyy, l(5, 5, 0, 0) +ushr r2.yz, r2.yyzy, l(0, 5, 5, 0) +or r2.yz, r2.yyzy, r5.xxyx +xor r2.yz, r5.zzwz, r2.yyzy +iadd r2.yz, r3.xxyx, r2.yyzy +or r4.yw, r2.yyyz, l(0, 0x7fff0000, 0, 0x7fff0000) +and r2.yz, r3.zzwz, l(0, 1023, 1023, 0) +ubfe r5.xyzw, l(1, 1, 11, 11), l(9, 9, 10, 10), r3.zwzw +ieq r3.xy, r2.yzyy, l(512, 512, 0, 0) +movc r2.yz, r3.xxyx, l(0,513,513,0), r2.yyzy +movc r6.xyzw, r5.xyxy, l(1023,1023,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r2.yz, r2.yyzy, r6.xxyx +iadd r2.yz, r5.xxyx, r2.yyzy +ishl r3.xy, r2.yzyy, l(6, 6, 0, 0) +ushr r2.yz, r2.yyzy, l(0, 3, 3, 0) +or r2.yz, r2.yyzy, r3.xxyx +xor r2.yz, r6.zzwz, r2.yyzy +iadd r2.yz, r5.xxyx, r2.yyzy +ubfe r3.xy, l(1, 1, 0, 0), l(20, 20, 0, 0), r3.zwzz +ieq r5.xy, r5.zwzz, l(1024, 1024, 0, 0) +movc r5.xy, r5.xyxx, l(1025,1025,0,0), r5.zwzz +movc r6.xyzw, r3.xyxy, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r5.xy, r5.xyxx, r6.xyxx +iadd r5.xy, r3.xyxx, r5.xyxx +ishl r5.zw, r5.xxxy, l(0, 0, 5, 5) +ushr r5.xy, r5.xyxx, l(5, 5, 0, 0) +or r5.xy, r5.xyxx, r5.zwzz +xor r5.xy, r6.zwzz, r5.xyxx +iadd r3.xy, r3.xyxx, r5.xyxx +ishl r3.xy, r3.xyxx, l(16, 16, 0, 0) +or r5.xz, r2.yyzy, r3.xxyx +ushr r2.yz, r3.zzwz, l(0, 21, 21, 0) +ushr r3.xy, r2.yzyy, l(10, 10, 0, 0) +ieq r3.zw, r2.yyyz, l(0, 0, 1024, 1024) +movc r2.yz, r3.zzwz, l(0,1025,1025,0), r2.yyzy +movc r6.xyzw, r3.xyxy, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r2.yz, r2.yyzy, r6.xxyx +iadd r2.yz, r3.xxyx, r2.yyzy +ishl r3.zw, r2.yyyz, l(0, 0, 5, 5) +ushr r2.yz, r2.yyzy, l(0, 5, 5, 0) +or r2.yz, r2.yyzy, r3.zzwz +xor r2.yz, r6.zzwz, r2.yyzy +iadd r2.yz, r3.xxyx, r2.yyzy +or r5.yw, r2.yyyz, l(0, 0x7fff0000, 0, 0x7fff0000) +store_uav_typed U0[0].xyzw, r1.yyyy, r4.xyzw +iadd r2.yzw, r1.yyyy, l(0, 1, 2, 3) +store_uav_typed U0[0].xyzw, r2.yyyy, r5.xyzw +ult r0.y, l(1), r0.z +if_nz r0.y + udiv r0.y, null, r2.x, r0.z + imad r0.y, -r0.y, r0.z, r2.x + iadd r1.w, r0.y, l(1) + ieq r1.w, r0.z, r1.w + if_nz r1.w + ishl r0.z, r0.z, l(5) + ishl r0.y, r0.y, l(4) + iadd r0.y, -r0.y, r0.z + else + mov r0.y, l(16) + endif +else + mov r0.y, l(32) +endif +imul null, r0.y, r0.w, r0.y +ushr r0.y, r0.y, l(4) +iadd r0.x, r0.y, r0.x +ld r0.xyzw, r0.xxxx, T0[0].xyzw +if_nz r1.x + ishl r3.xyzw, r0.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r0.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r0.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r1.z + ushr r3.xyzw, r0.xyzw, l(16, 16, 16, 16) + bfi r0.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r0.xyzw, r3.xyzw +endif +and r1.xz, r0.xxyx, l(1023, 0, 1023, 0) +ubfe r3.xyzw, l(1, 1, 11, 11), l(9, 9, 10, 10), r0.xyxy +ieq r2.xy, r1.xzxx, l(512, 512, 0, 0) +movc r1.xz, r2.xxyx, l(513,0,513,0), r1.xxzx +movc r4.xyzw, r3.xyxy, l(1023,1023,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r1.xz, r1.xxzx, r4.xxyx +iadd r1.xz, r3.xxyx, r1.xxzx +ishl r2.xy, r1.xzxx, l(6, 6, 0, 0) +ushr r1.xz, r1.xxzx, l(3, 0, 3, 0) +or r1.xz, r1.xxzx, r2.xxyx +xor r1.xz, r4.zzwz, r1.xxzx +iadd r1.xz, r3.xxyx, r1.xxzx +ubfe r2.xy, l(1, 1, 0, 0), l(20, 20, 0, 0), r0.xyxx +ieq r3.xy, r3.zwzz, l(1024, 1024, 0, 0) +movc r3.xy, r3.xyxx, l(1025,1025,0,0), r3.zwzz +movc r4.xyzw, r2.xyxy, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r3.xy, r3.xyxx, r4.xyxx +iadd r3.xy, r2.xyxx, r3.xyxx +ishl r3.zw, r3.xxxy, l(0, 0, 5, 5) +ushr r3.xy, r3.xyxx, l(5, 5, 0, 0) +or r3.xy, r3.xyxx, r3.zwzz +xor r3.xy, r4.zwzz, r3.xyxx +iadd r2.xy, r2.xyxx, r3.xyxx +ishl r2.xy, r2.xyxx, l(16, 16, 0, 0) +or r3.xz, r1.xxzx, r2.xxyx +ushr r0.xy, r0.xyxx, l(21, 21, 0, 0) +ushr r1.xz, r0.xxyx, l(10, 0, 10, 0) +ieq r2.xy, r0.xyxx, l(1024, 1024, 0, 0) +movc r0.xy, r2.xyxx, l(1025,1025,0,0), r0.xyxx +movc r4.xyzw, r1.xzxz, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r0.xy, r0.xyxx, r4.xyxx +iadd r0.xy, r1.xzxx, r0.xyxx +ishl r2.xy, r0.xyxx, l(5, 5, 0, 0) +ushr r0.xy, r0.xyxx, l(5, 5, 0, 0) +or r0.xy, r0.xyxx, r2.xyxx +xor r0.xy, r4.zwzz, r0.xyxx +iadd r0.xy, r1.xzxx, r0.xyxx +or r3.yw, r0.xxxy, l(0, 0x7fff0000, 0, 0x7fff0000) +and r0.xy, r0.zwzz, l(1023, 1023, 0, 0) +ubfe r4.xyzw, l(1, 1, 11, 11), l(9, 9, 10, 10), r0.zwzw +ieq r1.xz, r0.xxyx, l(512, 0, 512, 0) +movc r0.xy, r1.xzxx, l(513,513,0,0), r0.xyxx +movc r5.xyzw, r4.xyxy, l(1023,1023,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r0.xy, r0.xyxx, r5.xyxx +iadd r0.xy, r4.xyxx, r0.xyxx +ishl r1.xz, r0.xxyx, l(6, 0, 6, 0) +ushr r0.xy, r0.xyxx, l(3, 3, 0, 0) +or r0.xy, r0.xyxx, r1.xzxx +xor r0.xy, r5.zwzz, r0.xyxx +iadd r0.xy, r4.xyxx, r0.xyxx +ubfe r1.xz, l(1, 0, 1, 0), l(20, 0, 20, 0), r0.zzwz +ieq r2.xy, r4.zwzz, l(1024, 1024, 0, 0) +movc r2.xy, r2.xyxx, l(1025,1025,0,0), r4.zwzz +movc r4.xyzw, r1.xzxz, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r2.xy, r2.xyxx, r4.xyxx +iadd r2.xy, r1.xzxx, r2.xyxx +ishl r4.xy, r2.xyxx, l(5, 5, 0, 0) +ushr r2.xy, r2.xyxx, l(5, 5, 0, 0) +or r2.xy, r2.xyxx, r4.xyxx +xor r2.xy, r4.zwzz, r2.xyxx +iadd r1.xz, r1.xxzx, r2.xxyx +ishl r1.xz, r1.xxzx, l(16, 0, 16, 0) +or r4.xz, r0.xxyx, r1.xxzx +ushr r0.xy, r0.zwzz, l(21, 21, 0, 0) +ushr r0.zw, r0.xxxy, l(0, 0, 10, 10) +ieq r1.xz, r0.xxyx, l(1024, 0, 1024, 0) +movc r0.xy, r1.xzxx, l(1025,1025,0,0), r0.xyxx +movc r5.xyzw, r0.zwzw, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r0.xy, r0.xyxx, r5.xyxx +iadd r0.xy, r0.zwzz, r0.xyxx +ishl r1.xz, r0.xxyx, l(5, 0, 5, 0) +ushr r0.xy, r0.xyxx, l(5, 5, 0, 0) +or r0.xy, r0.xyxx, r1.xzxx +xor r0.xy, r5.zwzz, r0.xyxx +iadd r0.xy, r0.zwzz, r0.xyxx +or r4.yw, r0.xxxy, l(0, 0x7fff0000, 0, 0x7fff0000) +store_uav_typed U0[0].xyzw, r2.zzzz, r3.xyzw +store_uav_typed U0[0].xyzw, r2.wwww, r4.xyzw +ret +// Approximately 280 instruction slots used +#endif + +const BYTE texture_load_r10g11b11_rgba16_snorm_scaled_cs[] = { + 68, 88, 66, 67, 76, 51, 249, 151, 223, 214, 131, 148, 15, 160, 41, 161, 40, 195, 114, + 229, 1, 0, 0, 0, 84, 44, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 184, 43, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 124, 39, 0, + 0, 81, 0, 5, 0, 223, 9, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 7, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, + 0, 42, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 85, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, + 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 10, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 24, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 194, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, + 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, + 0, 2, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 166, 14, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 166, 10, + 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 9, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 15, 194, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 9, 66, 0, 16, 0, 3, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, + 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, + 82, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 23, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, + 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 4, 0, + 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 12, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, + 0, 2, 0, 0, 0, 86, 6, 16, 0, 4, 0, 0, 0, 35, 0, 0, 12, 50, 0, + 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, + 4, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, + 166, 11, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, + 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 10, 210, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 98, 0, + 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, + 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 11, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, 4, 16, 0, 3, 0, 0, 0, 32, + 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 55, 0, 0, 12, 98, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 5, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 0, + 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, + 5, 0, 0, 0, 70, 4, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, + 0, 255, 3, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 98, + 0, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, + 5, 0, 0, 0, 30, 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, + 0, 4, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 50, 0, + 16, 0, 5, 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 6, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, + 98, 0, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 60, 0, + 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 6, + 1, 16, 0, 5, 0, 0, 0, 87, 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, + 166, 11, 16, 0, 5, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 30, 0, 0, + 7, 98, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 4, 0, 0, 0, 86, 6, + 16, 0, 2, 0, 0, 0, 138, 0, 0, 15, 50, 0, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 3, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, 5, 0, + 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 194, 0, 16, 0, + 4, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, 166, 14, 16, 0, 4, 0, + 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, 70, 4, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 255, 0, 0, + 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 87, 0, 0, 7, 194, 0, 16, 0, 4, 0, 0, 0, 166, 14, + 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 194, + 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, + 4, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 230, 10, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 166, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 5, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 4, 0, 0, + 0, 166, 14, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 87, 0, + 0, 7, 194, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 5, 0, 0, 0, 166, + 14, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, + 70, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 41, 0, 0, + 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 4, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, + 6, 1, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 98, 0, 16, 0, 2, 0, 0, + 0, 6, 1, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 21, 0, + 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 3, + 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, + 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, + 0, 5, 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 4, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 98, + 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 86, 6, 16, + 0, 2, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, 70, 4, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, + 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, + 0, 86, 6, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 5, 0, 0, 0, 30, 0, + 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 86, + 6, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, + 150, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 98, 0, 16, 0, 2, 0, + 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 5, + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 98, 0, 16, 0, + 2, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 5, 0, 0, + 0, 87, 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 5, 0, + 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 98, 0, 16, 0, 2, + 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, + 60, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 9, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, + 255, 127, 1, 0, 0, 10, 98, 0, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 230, + 14, 16, 0, 3, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, + 150, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 98, 0, 16, 0, 2, 0, + 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, + 2, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, + 55, 0, 0, 15, 242, 0, 16, 0, 6, 0, 0, 0, 70, 4, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 255, 0, 0, 255, 255, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 87, 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, + 2, 0, 0, 0, 6, 1, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 98, 0, 16, + 0, 2, 0, 0, 0, 6, 1, 16, 0, 5, 0, 0, 0, 86, 6, 16, 0, 2, 0, + 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 150, 5, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 10, 98, 0, 16, 0, 2, 0, 0, 0, 86, 6, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 86, + 6, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 87, 0, 0, 7, + 98, 0, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 6, 0, 0, 0, 86, 6, 16, + 0, 2, 0, 0, 0, 30, 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 6, 1, + 16, 0, 5, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 138, 0, 0, 15, 50, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 32, 0, + 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 12, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 6, + 0, 0, 0, 70, 4, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, + 255, 7, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, + 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 6, + 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, + 3, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, + 0, 5, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 85, 0, 0, 10, 50, + 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, + 7, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 230, 10, + 16, 0, 5, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 5, 0, 0, 0, 230, + 10, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, + 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, + 0, 5, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, 5, 0, 0, 0, + 86, 6, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 85, 0, 0, + 10, 98, 0, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 85, + 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 0, 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 86, 9, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 4, 0, 0, 55, 0, 0, 12, 98, 0, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, 4, 0, 0, 1, 4, 0, + 0, 0, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 55, 0, 0, 15, 242, 0, + 16, 0, 6, 0, 0, 0, 70, 4, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, + 7, 0, 0, 255, 7, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, + 7, 98, 0, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 6, 1, + 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 6, + 1, 16, 0, 3, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, + 194, 0, 16, 0, 3, 0, 0, 0, 86, 9, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 85, 0, + 0, 10, 98, 0, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 60, 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, + 0, 166, 11, 16, 0, 3, 0, 0, 0, 87, 0, 0, 7, 98, 0, 16, 0, 2, 0, + 0, 0, 166, 11, 16, 0, 6, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 30, + 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, + 86, 6, 16, 0, 2, 0, 0, 0, 60, 0, 0, 10, 162, 0, 16, 0, 5, 0, 0, + 0, 86, 9, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 255, 127, 0, 0, 0, 0, 0, 0, 255, 127, 164, 0, 0, 8, 242, 224, 33, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 30, 0, 0, 10, 226, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, + 0, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 79, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, + 0, 0, 78, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 10, + 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, + 3, 58, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, + 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 54, 0, 0, 5, + 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 21, 0, 0, + 1, 38, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, + 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 82, 0, 16, + 0, 1, 0, 0, 0, 6, 1, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 242, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 11, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 70, 4, 16, 0, 0, 0, 0, 0, 32, 0, + 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 12, 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, + 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 4, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, + 255, 3, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 82, 0, + 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 4, + 0, 0, 0, 30, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, + 3, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, + 0, 2, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 6, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, + 7, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 6, 1, + 16, 0, 2, 0, 0, 0, 87, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, + 11, 16, 0, 4, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, + 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 6, 2, 16, + 0, 1, 0, 0, 0, 138, 0, 0, 15, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, + 0, 230, 10, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, 3, + 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 4, 0, 0, + 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, + 0, 55, 0, 0, 15, 242, 0, 16, 0, 4, 0, 0, 0, 70, 4, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 255, 0, 0, 255, + 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, + 0, 3, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 50, 0, + 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 3, + 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, + 0, 5, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, + 70, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 87, 0, 0, + 7, 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 70, 0, + 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 70, + 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, + 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, + 0, 7, 82, 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 6, + 1, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 82, 0, 16, 0, 1, 0, + 0, 0, 6, 1, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 0, + 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, + 2, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 50, 0, + 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, + 4, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 4, 0, 0, 0, 134, 8, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 255, + 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, + 7, 50, 0, 16, 0, 0, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 70, + 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, + 87, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, + 0, 70, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, + 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 60, + 0, 0, 10, 162, 0, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 255, + 127, 1, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 9, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 230, 14, + 16, 0, 0, 0, 0, 0, 32, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, + 1, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, 0, 0, 0, + 0, 134, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 2, 0, 0, 1, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 55, + 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, 70, 4, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 255, 0, 0, 255, 255, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, + 0, 41, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 87, 0, 0, 7, 50, + 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 15, 82, 0, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, + 20, 0, 0, 0, 0, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 32, 0, 0, + 10, 50, 0, 16, 0, 2, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 230, 10, 16, 0, 4, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 4, 0, + 0, 0, 134, 8, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, + 7, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, + 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 4, 0, + 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 134, 0, 16, 0, 1, + 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, + 4, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 50, 0, + 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, + 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 230, 10, + 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, + 2, 0, 0, 0, 41, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, 4, 0, 0, 0, 6, + 1, 16, 0, 0, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 50, 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, + 32, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, 0, 0, 0, 0, 134, 0, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, + 0, 5, 0, 0, 0, 230, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 255, 7, + 0, 0, 255, 7, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 5, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 230, 10, + 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, + 10, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, + 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, + 134, 0, 16, 0, 1, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, + 0, 230, 10, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 70, + 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, + 6, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 255, + 127, 0, 0, 0, 0, 0, 0, 255, 127, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 246, 15, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 148, 0, 0, 0, 24, 1, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 98, 0, 0, 0, 94, 0, 0, 0, 5, + 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r11g11b10_rgba16_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r11g11b10_rgba16_cs.h new file mode 100644 index 0000000..7331560 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r11g11b10_rgba16_cs.h @@ -0,0 +1,563 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 7 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(3) +imad r1.y, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r0.w, r1.y, CB0[0][2].x, r0.w +iadd r0.w, r0.w, CB0[0][1].w +if_nz r0.x + if_nz r0.y + ishr r1.yzw, vThreadID.yyzy, l(0, 4, 2, 3) + ushr r2.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r0.y, r1.z, r2.x, r1.y + ibfe r2.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), vThreadID.xxxx + imad r0.y, r0.y, r2.y, r2.x + ishl r1.y, vThreadID.y, l(10) + ishr r1.y, r1.y, l(6) + and r1.y, r1.y, l(96) + iadd r1.z, r1.z, r1.w + bfi r1.w, l(1), l(1), r1.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r1.w, l(2), l(1), r1.w, l(0) + bfi r1.z, l(1), l(0), r1.z, r1.w + bfi r2.xy, l(20, 20, 0, 0), l(10, 13, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r1.yw, r1.yyyy, l(0, 2, 0, 16), r2.xxxy + bfi r1.yw, l(0, 2, 0, 2), l(0, 8, 0, 11), vThreadID.zzzz, r1.yyyw + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r2.x, l(3), l(6), r1.y + and r2.y, r1.z, l(6) + bfi r1.z, l(1), l(8), r1.z, l(0) + imad r1.z, r2.x, l(32), r1.z + imad r1.z, r2.y, l(4), r1.z + bfi r1.yw, l(0, 6, 0, 6), l(0, 0, 0, 3), r0.yyyy, r1.yyyw + bfi r0.y, l(9), l(3), r1.z, r1.w + bfi r0.y, l(6), l(0), r1.y, r0.y + else + ibfe r1.yz, l(0, 27, 29, 0), l(0, 2, 0, 0), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.y, r2.x, r1.w, r1.y + ishl r2.xz, vThreadID.yyyy, l(5, 0, 7, 0) + and r2.xz, r2.xxzx, l(448, 0, 2048, 0) + bfi r1.w, l(23), l(9), r1.y, r2.x + bfi r2.w, l(1), l(4), vThreadID.y, l(0) + iadd r1.w, r1.w, r2.w + ishl r3.xy, r2.xxxx, l(3, 2, 0, 0) + bfi r3.xy, l(23, 23, 0, 0), l(12, 11, 0, 0), r1.yyyy, r3.xyxx + imad r2.xw, r2.wwww, l(8, 0, 0, 4), r3.xxxy + bfi r1.y, l(12), l(0), r2.z, r2.x + and r2.x, r2.w, l(1792) + iadd r1.y, r1.y, r2.x + and r2.x, r2.y, l(2) + iadd r1.z, r1.z, r2.x + bfi r1.z, l(2), l(6), r1.z, l(0) + iadd r1.y, r1.y, r1.z + bfi r0.y, l(6), l(0), r1.w, r1.y + endif +else + ishl r1.x, r1.x, l(2) + imad r1.y, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.y, CB0[0][0].z, r1.x +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.yw, r0.yyyw, l(0, 4, 0, 4) +ld r1.xyzw, r0.yyyy, T0[0].zwxy +ieq r2.xyz, r0.zzzz, l(1, 2, 3, 0) +or r2.xy, r2.yzyy, r2.xyxx +if_nz r2.x + ishl r3.xyzw, r1.zwxy, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r1.zwxy, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r1.xyzw, r3.zwxy, r4.zwxy +endif +if_nz r2.y + ushr r3.xyzw, r1.zwxy, l(16, 16, 16, 16) + bfi r1.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r1.xyzw, r3.zwxy + mov r3.xy, r1.zwzz +else + mov r3.xy, r1.zwzz +endif +ushr r4.xyzw, r3.xyxy, l(22, 22, 1, 1) +mov r3.zw, r4.xxxy +bfi r5.xyzw, l(11, 26, 11, 26), l(5, 6, 5, 6), r3.xzyw, l(0, 0, 0, 0) +ubfe r6.xyzw, l(5, 6, 5, 6), l(6, 26, 6, 26), r3.xxyy +iadd r5.xyzw, r5.xyzw, r6.xyzw +ishl r2.zw, r3.xxxy, l(0, 0, 10, 10) +and r3.xy, r4.zwzz, l(0x001f0000, 0x001f0000, 0, 0) +bfi r2.zw, l(0, 0, 21, 21), l(0, 0, 0, 0), r3.xxxy, r2.zzzw +iadd r3.xz, r2.zzwz, r5.xxzx +iadd r3.yw, r5.yyyw, l(0, 0xffff0000, 0, 0xffff0000) +ushr r4.xyzw, r1.xyxy, l(22, 22, 1, 1) +mov r1.zw, r4.xxxy +bfi r5.xyzw, l(11, 26, 11, 26), l(5, 6, 5, 6), r1.xzyw, l(0, 0, 0, 0) +ubfe r6.xyzw, l(5, 6, 5, 6), l(6, 26, 6, 26), r1.xxyy +iadd r5.xyzw, r5.xyzw, r6.xyzw +ishl r1.xy, r1.xyxx, l(10, 10, 0, 0) +and r1.zw, r4.zzzw, l(0, 0, 0x001f0000, 0x001f0000) +bfi r1.xy, l(21, 21, 0, 0), l(0, 0, 0, 0), r1.zwzz, r1.xyxx +iadd r1.xz, r1.xxyx, r5.xxzx +iadd r1.yw, r5.yyyw, l(0, 0xffff0000, 0, 0xffff0000) +store_uav_typed U0[0].xyzw, r0.wwww, r3.xyzw +iadd r3.xyz, r0.wwww, l(1, 2, 3, 0) +store_uav_typed U0[0].xyzw, r3.xxxx, r1.xyzw +if_nz r0.x + mov r0.x, l(32) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r1.xyzw, r0.xxxx, T0[0].zwxy +if_nz r2.x + ishl r4.xyzw, r1.zwxy, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r1.zwxy, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r1.xyzw, r4.zwxy, r5.zwxy +endif +if_nz r2.y + ushr r2.xyzw, r1.zwxy, l(16, 16, 16, 16) + bfi r1.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r1.xyzw, r2.zwxy + mov r2.xy, r1.zwzz +else + mov r2.xy, r1.zwzz +endif +ushr r4.xyzw, r2.xyxy, l(22, 22, 1, 1) +mov r2.zw, r4.xxxy +bfi r5.xyzw, l(11, 26, 11, 26), l(5, 6, 5, 6), r2.xzyw, l(0, 0, 0, 0) +ubfe r6.xyzw, l(5, 6, 5, 6), l(6, 26, 6, 26), r2.xxyy +iadd r5.xyzw, r5.xyzw, r6.xyzw +ishl r0.xy, r2.xyxx, l(10, 10, 0, 0) +and r2.xy, r4.zwzz, l(0x001f0000, 0x001f0000, 0, 0) +bfi r0.xy, l(21, 21, 0, 0), l(0, 0, 0, 0), r2.xyxx, r0.xyxx +iadd r2.xz, r0.xxyx, r5.xxzx +iadd r2.yw, r5.yyyw, l(0, 0xffff0000, 0, 0xffff0000) +ushr r4.xyzw, r1.xyxy, l(22, 22, 1, 1) +mov r1.zw, r4.xxxy +bfi r5.xyzw, l(11, 26, 11, 26), l(5, 6, 5, 6), r1.xzyw, l(0, 0, 0, 0) +ubfe r6.xyzw, l(5, 6, 5, 6), l(6, 26, 6, 26), r1.xxyy +iadd r5.xyzw, r5.xyzw, r6.xyzw +ishl r0.xy, r1.xyxx, l(10, 10, 0, 0) +and r1.xy, r4.zwzz, l(0x001f0000, 0x001f0000, 0, 0) +bfi r0.xy, l(21, 21, 0, 0), l(0, 0, 0, 0), r1.xyxx, r0.xyxx +iadd r1.xz, r0.xxyx, r5.xxzx +iadd r1.yw, r5.yyyw, l(0, 0xffff0000, 0, 0xffff0000) +store_uav_typed U0[0].xyzw, r3.yyyy, r2.xyzw +store_uav_typed U0[0].xyzw, r3.zzzz, r1.xyzw +ret +// Approximately 154 instruction slots used +#endif + +const BYTE texture_load_r11g11b10_rgba16_cs[] = { + 68, 88, 66, 67, 144, 201, 238, 193, 169, 92, 86, 99, 243, 177, 241, 143, 47, 129, 10, + 154, 1, 0, 0, 0, 64, 26, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 164, 25, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 104, 21, 0, + 0, 81, 0, 5, 0, 90, 5, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 7, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 130, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, + 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 0, 9, 226, 0, 16, 0, 1, 0, 0, 0, 86, 6, 2, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 85, 0, + 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 182, 143, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 139, 0, 0, 14, 82, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 41, 0, 0, 6, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, + 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 96, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, + 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 162, 0, 16, 0, 1, 0, + 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 16, 162, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 166, 10, 2, 0, 86, + 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, 18, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, + 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 8, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, + 0, 0, 17, 162, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, + 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 14, 98, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, 86, + 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, + 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 41, 0, 0, 9, 82, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, + 0, 1, 64, 0, 0, 9, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 130, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 41, 0, + 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 17, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, + 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 12, 0, + 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, + 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 146, 0, 16, 0, + 2, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 6, 4, 16, 0, 3, 0, + 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 41, 0, 0, + 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, + 0, 0, 0, 0, 0, 86, 13, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, + 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 230, 116, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 2, 0, 0, + 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 2, + 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, + 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 230, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, + 10, 242, 0, 16, 0, 4, 0, 0, 0, 230, 4, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 1, 0, 0, 0, 230, 4, 16, 0, 3, 0, + 0, 0, 230, 4, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, + 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 230, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 230, 4, 16, 0, 3, 0, 0, + 0, 54, 0, 0, 5, 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 1, 0, + 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 50, 0, 16, 0, 3, 0, 0, 0, 230, + 10, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 4, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 22, 0, 0, + 0, 22, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 194, 0, + 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 140, 0, 0, 20, 242, + 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 26, 0, 0, 0, + 11, 0, 0, 0, 26, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 6, 0, 0, + 0, 5, 0, 0, 0, 6, 0, 0, 0, 134, 13, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, + 0, 0, 15, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, + 6, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, + 0, 26, 0, 0, 0, 6, 0, 0, 0, 26, 0, 0, 0, 6, 5, 16, 0, 3, 0, + 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, + 2, 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 10, 50, 0, + 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 31, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, + 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 21, 0, 0, 0, 21, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 166, + 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 82, 0, 16, 0, 3, 0, 0, 0, + 166, 11, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 5, 0, 0, 0, 30, 0, 0, + 10, 162, 0, 16, 0, 3, 0, 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 85, + 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 4, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 54, 0, 0, 5, 194, 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 4, 0, + 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 11, + 0, 0, 0, 26, 0, 0, 0, 11, 0, 0, 0, 26, 0, 0, 0, 2, 64, 0, 0, + 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 134, 13, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, + 2, 64, 0, 0, 6, 0, 0, 0, 26, 0, 0, 0, 6, 0, 0, 0, 26, 0, 0, + 0, 6, 5, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, 0, + 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 41, + 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 10, 194, 0, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, + 0, 31, 0, 140, 0, 0, 17, 50, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 10, + 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, + 5, 0, 0, 0, 30, 0, 0, 10, 162, 0, 16, 0, 1, 0, 0, 0, 86, 13, 16, + 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, + 0, 0, 0, 0, 255, 255, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 30, 0, 0, 10, 114, 0, 16, 0, 3, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, + 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 32, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 85, + 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, + 0, 8, 242, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 230, + 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, + 2, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 230, 4, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, + 0, 230, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, + 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 1, 0, 0, 0, 230, 4, 16, 0, 4, 0, 0, 0, 230, 4, 16, 0, 5, 0, + 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 230, 4, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 140, 0, 0, 17, 242, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, + 1, 0, 0, 0, 230, 4, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, + 0, 2, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 54, 0, + 0, 5, 50, 0, 16, 0, 2, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 21, + 0, 0, 1, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 4, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 54, 0, 0, 5, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, + 16, 0, 4, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 11, 0, 0, 0, 26, 0, 0, 0, 11, 0, 0, 0, 26, 0, 0, 0, + 2, 64, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, + 0, 134, 13, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 6, + 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 26, 0, 0, 0, 6, 0, 0, + 0, 26, 0, 0, 0, 6, 5, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 242, 0, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 6, + 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 230, 10, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 82, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 0, 0, 0, 0, + 6, 2, 16, 0, 5, 0, 0, 0, 30, 0, 0, 10, 162, 0, 16, 0, 2, 0, 0, + 0, 86, 13, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 22, 0, 0, 0, + 22, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 194, 0, 16, + 0, 1, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 140, 0, 0, 20, 242, 0, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 26, 0, 0, 0, 11, + 0, 0, 0, 26, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, + 5, 0, 0, 0, 6, 0, 0, 0, 134, 13, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, + 0, 15, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 6, + 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, + 26, 0, 0, 0, 6, 0, 0, 0, 26, 0, 0, 0, 6, 5, 16, 0, 1, 0, 0, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, + 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, + 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, + 0, 1, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 31, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 50, + 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 6, + 1, 16, 0, 0, 0, 0, 0, 6, 2, 16, 0, 5, 0, 0, 0, 30, 0, 0, 10, + 162, 0, 16, 0, 1, 0, 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 164, 0, + 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 154, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 51, + 0, 0, 0, 29, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r11g11b10_rgba16_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r11g11b10_rgba16_scaled_cs.h new file mode 100644 index 0000000..50949b4 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r11g11b10_rgba16_scaled_cs.h @@ -0,0 +1,619 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 8 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(3) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(2) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +ishl r1.w, r1.x, l(2) +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r2.z, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(3, 0, 1, 0), r1.xxxx + imad r2.z, r2.z, r3.y, r3.x + ishl r3.x, r1.z, l(10) + and r3.x, r3.x, l(6144) + bfi r3.x, l(3), l(8), r1.w, r3.x + ishr r3.x, r3.x, l(6) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r2.zw, l(0, 0, 20, 20), l(0, 0, 10, 13), r2.zzzz, l(0, 0, 0, 0) + imad r2.zw, r3.xxxx, l(0, 0, 2, 16), r2.zzzw + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 8, 11), vThreadID.zzzz, r2.zzzw + bfi r3.x, l(1), l(4), r1.z, l(0) + ubfe r3.y, l(3), l(6), r2.z + and r3.z, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.y, l(32), r0.x + imad r0.x, r3.z, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r3.xxxx, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r3.z, CB0[0][0].z, l(5) + imad r2.z, r3.x, r3.z, r2.z + ishl r3.xz, r1.zzzz, l(5, 0, 7, 0) + and r3.xz, r3.xxzx, l(448, 0, 2048, 0) + bfi r3.w, l(3), l(3), r1.w, r3.x + bfi r3.w, l(23), l(9), r2.z, r3.w + bfi r4.x, l(1), l(4), r1.z, l(0) + iadd r3.w, r3.w, r4.x + ishl r4.yz, r3.xxxx, l(0, 3, 2, 0) + bfi r4.yz, l(0, 3, 3, 0), l(0, 6, 5, 0), r1.wwww, r4.yyzy + bfi r4.yz, l(0, 23, 23, 0), l(0, 12, 11, 0), r2.zzzz, r4.yyzy + imad r4.xy, r4.xxxx, l(8, 4, 0, 0), r4.yzyy + bfi r1.w, l(12), l(0), r3.z, r4.x + and r2.z, r4.y, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.w, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].zwxy +ieq r1.xzw, r0.yyyy, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r4.xyzw, r3.zwxy, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.zwxy, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.zwxy, r5.zwxy +endif +if_nz r1.z + ushr r4.xyzw, r3.zwxy, l(16, 16, 16, 16) + bfi r3.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r3.xyzw, r4.zwxy + mov r4.xy, r3.zwzz +else + mov r4.xy, r3.zwzz +endif +ushr r5.xyzw, r4.xyxy, l(22, 22, 1, 1) +mov r4.zw, r5.xxxy +bfi r6.xyzw, l(11, 26, 11, 26), l(5, 6, 5, 6), r4.xzyw, l(0, 0, 0, 0) +ubfe r7.xyzw, l(5, 6, 5, 6), l(6, 26, 6, 26), r4.xxyy +iadd r6.xyzw, r6.xyzw, r7.xyzw +ishl r2.yz, r4.xxyx, l(0, 10, 10, 0) +and r4.xy, r5.zwzz, l(0x001f0000, 0x001f0000, 0, 0) +bfi r2.yz, l(0, 21, 21, 0), l(0, 0, 0, 0), r4.xxyx, r2.yyzy +iadd r4.xz, r2.yyzy, r6.xxzx +iadd r4.yw, r6.yyyw, l(0, 0xffff0000, 0, 0xffff0000) +ushr r5.xyzw, r3.xyxy, l(22, 22, 1, 1) +mov r3.zw, r5.xxxy +bfi r6.xyzw, l(11, 26, 11, 26), l(5, 6, 5, 6), r3.xzyw, l(0, 0, 0, 0) +ubfe r7.xyzw, l(5, 6, 5, 6), l(6, 26, 6, 26), r3.xxyy +iadd r6.xyzw, r6.xyzw, r7.xyzw +ishl r2.yz, r3.xxyx, l(0, 10, 10, 0) +and r3.xy, r5.zwzz, l(0x001f0000, 0x001f0000, 0, 0) +bfi r2.yz, l(0, 21, 21, 0), l(0, 0, 0, 0), r3.xxyx, r2.yyzy +iadd r3.xz, r2.yyzy, r6.xxzx +iadd r3.yw, r6.yyyw, l(0, 0xffff0000, 0, 0xffff0000) +store_uav_typed U0[0].xyzw, r1.yyyy, r4.xyzw +iadd r2.yzw, r1.yyyy, l(0, 1, 2, 3) +store_uav_typed U0[0].xyzw, r2.yyyy, r3.xyzw +ult r0.y, l(1), r0.z +if_nz r0.y + udiv r0.y, null, r2.x, r0.z + imad r0.y, -r0.y, r0.z, r2.x + iadd r1.w, r0.y, l(1) + ieq r1.w, r0.z, r1.w + if_nz r1.w + ishl r0.z, r0.z, l(5) + ishl r0.y, r0.y, l(4) + iadd r0.y, -r0.y, r0.z + else + mov r0.y, l(16) + endif +else + mov r0.y, l(32) +endif +imul null, r0.y, r0.w, r0.y +ushr r0.y, r0.y, l(4) +iadd r0.x, r0.y, r0.x +ld r0.xyzw, r0.xxxx, T0[0].zwxy +if_nz r1.x + ishl r3.xyzw, r0.zwxy, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r0.zwxy, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r0.xyzw, r3.zwxy, r4.zwxy +endif +if_nz r1.z + ushr r3.xyzw, r0.zwxy, l(16, 16, 16, 16) + bfi r0.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r0.xyzw, r3.zwxy + mov r3.xy, r0.zwzz +else + mov r3.xy, r0.zwzz +endif +ushr r4.xyzw, r3.xyxy, l(22, 22, 1, 1) +mov r3.zw, r4.xxxy +bfi r5.xyzw, l(11, 26, 11, 26), l(5, 6, 5, 6), r3.xzyw, l(0, 0, 0, 0) +ubfe r6.xyzw, l(5, 6, 5, 6), l(6, 26, 6, 26), r3.xxyy +iadd r5.xyzw, r5.xyzw, r6.xyzw +ishl r1.xz, r3.xxyx, l(10, 0, 10, 0) +and r2.xy, r4.zwzz, l(0x001f0000, 0x001f0000, 0, 0) +bfi r1.xz, l(21, 0, 21, 0), l(0, 0, 0, 0), r2.xxyx, r1.xxzx +iadd r3.xz, r1.xxzx, r5.xxzx +iadd r3.yw, r5.yyyw, l(0, 0xffff0000, 0, 0xffff0000) +ushr r4.xyzw, r0.xyxy, l(22, 22, 1, 1) +mov r0.zw, r4.xxxy +bfi r5.xyzw, l(11, 26, 11, 26), l(5, 6, 5, 6), r0.xzyw, l(0, 0, 0, 0) +ubfe r6.xyzw, l(5, 6, 5, 6), l(6, 26, 6, 26), r0.xxyy +iadd r5.xyzw, r5.xyzw, r6.xyzw +ishl r0.xy, r0.xyxx, l(10, 10, 0, 0) +and r0.zw, r4.zzzw, l(0, 0, 0x001f0000, 0x001f0000) +bfi r0.xy, l(21, 21, 0, 0), l(0, 0, 0, 0), r0.zwzz, r0.xyxx +iadd r0.xz, r0.xxyx, r5.xxzx +iadd r0.yw, r5.yyyw, l(0, 0xffff0000, 0, 0xffff0000) +store_uav_typed U0[0].xyzw, r2.zzzz, r3.xyzw +store_uav_typed U0[0].xyzw, r2.wwww, r0.xyzw +ret +// Approximately 174 instruction slots used +#endif + +const BYTE texture_load_r11g11b10_rgba16_scaled_cs[] = { + 68, 88, 66, 67, 26, 129, 228, 234, 255, 135, 242, 250, 208, 92, 34, 237, 184, 132, 56, + 16, 1, 0, 0, 0, 236, 28, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 80, 28, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 20, 24, 0, + 0, 81, 0, 5, 0, 5, 6, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 8, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, + 0, 42, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 85, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, + 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 10, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 24, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 194, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, + 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, + 0, 2, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 166, 14, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 166, 10, + 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 9, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 15, 194, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 9, 66, 0, 16, 0, 3, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, + 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, + 82, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 23, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, + 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 4, 0, + 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 12, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, + 0, 2, 0, 0, 0, 86, 6, 16, 0, 4, 0, 0, 0, 35, 0, 0, 12, 50, 0, + 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, + 4, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, + 166, 11, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, + 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 10, 210, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 230, 4, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 230, 4, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, + 0, 0, 230, 4, 16, 0, 4, 0, 0, 0, 230, 4, 16, 0, 5, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 230, 4, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 230, 4, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 4, 0, + 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 50, + 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, + 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 4, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 54, 0, 0, 5, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 5, + 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, + 11, 0, 0, 0, 26, 0, 0, 0, 11, 0, 0, 0, 26, 0, 0, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 134, 13, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 7, 0, 0, 0, + 2, 64, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, + 0, 2, 64, 0, 0, 6, 0, 0, 0, 26, 0, 0, 0, 6, 0, 0, 0, 26, 0, + 0, 0, 6, 5, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 6, + 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, + 41, 0, 0, 10, 98, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + 1, 16, 0, 4, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, + 82, 0, 16, 0, 4, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 6, 2, 16, + 0, 6, 0, 0, 0, 30, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, + 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, + 0, 0, 0, 0, 0, 255, 255, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 4, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 22, 0, 0, 0, 22, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 194, 0, 16, 0, 3, 0, + 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 6, + 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 26, 0, 0, 0, 11, 0, 0, 0, + 26, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, + 0, 6, 0, 0, 0, 134, 13, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 242, + 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, + 5, 0, 0, 0, 6, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 26, 0, 0, + 0, 6, 0, 0, 0, 26, 0, 0, 0, 6, 5, 16, 0, 3, 0, 0, 0, 30, 0, + 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, + 14, 16, 0, 7, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 2, 0, 0, 0, + 6, 1, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 3, 0, + 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 31, 0, 0, + 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 21, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 86, 6, 16, 0, 2, + 0, 0, 0, 30, 0, 0, 7, 82, 0, 16, 0, 3, 0, 0, 0, 86, 6, 16, 0, + 2, 0, 0, 0, 6, 2, 16, 0, 6, 0, 0, 0, 30, 0, 0, 10, 162, 0, 16, + 0, 3, 0, 0, 0, 86, 13, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 164, 0, 0, 8, 242, + 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 30, 0, 0, 10, 226, 0, 16, 0, 2, 0, 0, + 0, 86, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 79, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, + 16, 0, 0, 0, 0, 0, 78, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 0, + 208, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 35, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 8, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 34, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, + 54, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, + 0, 21, 0, 0, 1, 38, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, + 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 45, 0, + 0, 8, 242, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 230, + 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, + 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 230, 4, 16, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, + 0, 230, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 0, 0, 0, 0, 230, 4, 16, 0, 3, 0, 0, 0, 230, 4, 16, 0, 4, 0, + 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 230, 4, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 140, 0, 0, 17, 242, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 230, 4, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, + 0, 3, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 54, 0, + 0, 5, 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 21, + 0, 0, 1, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 4, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 54, 0, 0, 5, 194, 0, 16, 0, 3, 0, 0, 0, 6, 4, + 16, 0, 4, 0, 0, 0, 140, 0, 0, 20, 242, 0, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 11, 0, 0, 0, 26, 0, 0, 0, 11, 0, 0, 0, 26, 0, 0, 0, + 2, 64, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, + 0, 134, 13, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 6, + 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, + 6, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 26, 0, 0, 0, 6, 0, 0, + 0, 26, 0, 0, 0, 6, 5, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 242, 0, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 6, + 0, 0, 0, 41, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 230, 10, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 82, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 30, + 0, 0, 7, 82, 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 5, 0, 0, 0, 30, 0, 0, 10, 162, 0, 16, 0, 3, 0, 0, + 0, 86, 13, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 22, 0, 0, 0, + 22, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 194, 0, 16, + 0, 0, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 140, 0, 0, 20, 242, 0, + 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 26, 0, 0, 0, 11, + 0, 0, 0, 26, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, + 5, 0, 0, 0, 6, 0, 0, 0, 134, 13, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, + 0, 15, 242, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 6, + 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, + 26, 0, 0, 0, 6, 0, 0, 0, 26, 0, 0, 0, 6, 5, 16, 0, 0, 0, 0, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, + 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, + 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, + 0, 0, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 31, 0, 140, 0, 0, 17, 50, + 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 6, + 1, 16, 0, 0, 0, 0, 0, 6, 2, 16, 0, 5, 0, 0, 0, 30, 0, 0, 10, + 162, 0, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 164, 0, + 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 174, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 62, + 0, 0, 0, 34, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r11g11b10_rgba16_snorm_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r11g11b10_rgba16_snorm_cs.h new file mode 100644 index 0000000..74f436a --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r11g11b10_rgba16_snorm_cs.h @@ -0,0 +1,877 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(3) +imad r1.y, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r0.w, r1.y, CB0[0][2].x, r0.w +iadd r0.w, r0.w, CB0[0][1].w +if_nz r0.x + if_nz r0.y + ishr r1.yzw, vThreadID.yyzy, l(0, 4, 2, 3) + ushr r2.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r0.y, r1.z, r2.x, r1.y + ibfe r2.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), vThreadID.xxxx + imad r0.y, r0.y, r2.y, r2.x + ishl r1.y, vThreadID.y, l(10) + ishr r1.y, r1.y, l(6) + and r1.y, r1.y, l(96) + iadd r1.z, r1.z, r1.w + bfi r1.w, l(1), l(1), r1.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r1.w, l(2), l(1), r1.w, l(0) + bfi r1.z, l(1), l(0), r1.z, r1.w + bfi r2.xy, l(20, 20, 0, 0), l(10, 13, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r1.yw, r1.yyyy, l(0, 2, 0, 16), r2.xxxy + bfi r1.yw, l(0, 2, 0, 2), l(0, 8, 0, 11), vThreadID.zzzz, r1.yyyw + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r2.x, l(3), l(6), r1.y + and r2.y, r1.z, l(6) + bfi r1.z, l(1), l(8), r1.z, l(0) + imad r1.z, r2.x, l(32), r1.z + imad r1.z, r2.y, l(4), r1.z + bfi r1.yw, l(0, 6, 0, 6), l(0, 0, 0, 3), r0.yyyy, r1.yyyw + bfi r0.y, l(9), l(3), r1.z, r1.w + bfi r0.y, l(6), l(0), r1.y, r0.y + else + ibfe r1.yz, l(0, 27, 29, 0), l(0, 2, 0, 0), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.y, r2.x, r1.w, r1.y + ishl r2.xz, vThreadID.yyyy, l(5, 0, 7, 0) + and r2.xz, r2.xxzx, l(448, 0, 2048, 0) + bfi r1.w, l(23), l(9), r1.y, r2.x + bfi r2.w, l(1), l(4), vThreadID.y, l(0) + iadd r1.w, r1.w, r2.w + ishl r3.xy, r2.xxxx, l(3, 2, 0, 0) + bfi r3.xy, l(23, 23, 0, 0), l(12, 11, 0, 0), r1.yyyy, r3.xyxx + imad r2.xw, r2.wwww, l(8, 0, 0, 4), r3.xxxy + bfi r1.y, l(12), l(0), r2.z, r2.x + and r2.x, r2.w, l(1792) + iadd r1.y, r1.y, r2.x + and r2.x, r2.y, l(2) + iadd r1.z, r1.z, r2.x + bfi r1.z, l(2), l(6), r1.z, l(0) + iadd r1.y, r1.y, r1.z + bfi r0.y, l(6), l(0), r1.w, r1.y + endif +else + ishl r1.x, r1.x, l(2) + imad r1.y, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.y, CB0[0][0].z, r1.x +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.yw, r0.yyyw, l(0, 4, 0, 4) +ld r1.xyzw, r0.yyyy, T0[0].xyzw +ieq r2.xyz, r0.zzzz, l(1, 2, 3, 0) +or r2.xy, r2.yzyy, r2.xyxx +if_nz r2.x + ishl r3.xyzw, r1.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r1.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r1.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r2.y + ushr r3.xyzw, r1.xyzw, l(16, 16, 16, 16) + bfi r1.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r1.xyzw, r3.xyzw +endif +and r2.zw, r1.xxxy, l(0, 0, 2047, 2047) +ubfe r3.xyzw, l(1, 1, 11, 11), l(10, 10, 11, 11), r1.xyxy +ieq r4.xy, r2.zwzz, l(1024, 1024, 0, 0) +movc r2.zw, r4.xxxy, l(0,0,1025,1025), r2.zzzw +movc r4.xyzw, r3.xyxy, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r2.zw, r2.zzzw, r4.xxxy +iadd r2.zw, r3.xxxy, r2.zzzw +ishl r4.xy, r2.zwzz, l(5, 5, 0, 0) +ushr r2.zw, r2.zzzw, l(0, 0, 5, 5) +or r2.zw, r2.zzzw, r4.xxxy +xor r2.zw, r4.zzzw, r2.zzzw +iadd r2.zw, r3.xxxy, r2.zzzw +ubfe r3.xy, l(1, 1, 0, 0), l(21, 21, 0, 0), r1.xyxx +ieq r4.xy, r3.zwzz, l(1024, 1024, 0, 0) +movc r3.zw, r4.xxxy, l(0,0,1025,1025), r3.zzzw +movc r4.xyzw, r3.xyxy, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r3.zw, r3.zzzw, r4.xxxy +iadd r3.zw, r3.xxxy, r3.zzzw +ishl r4.xy, r3.zwzz, l(5, 5, 0, 0) +ushr r3.zw, r3.zzzw, l(0, 0, 5, 5) +or r3.zw, r3.zzzw, r4.xxxy +xor r3.zw, r4.zzzw, r3.zzzw +iadd r3.xy, r3.xyxx, r3.zwzz +ishl r3.xy, r3.xyxx, l(16, 16, 0, 0) +or r3.xz, r2.zzwz, r3.xxyx +ushr r1.xy, r1.xyxx, l(22, 22, 0, 0) +ushr r2.zw, r1.xxxy, l(0, 0, 9, 9) +ieq r4.xy, r1.xyxx, l(512, 512, 0, 0) +movc r1.xy, r4.xyxx, l(513,513,0,0), r1.xyxx +movc r4.xyzw, r2.zwzw, l(1023,1023,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r1.xy, r1.xyxx, r4.xyxx +iadd r1.xy, r2.zwzz, r1.xyxx +ishl r4.xy, r1.xyxx, l(6, 6, 0, 0) +ushr r1.xy, r1.xyxx, l(3, 3, 0, 0) +or r1.xy, r1.xyxx, r4.xyxx +xor r1.xy, r4.zwzz, r1.xyxx +iadd r1.xy, r2.zwzz, r1.xyxx +or r3.yw, r1.xxxy, l(0, 0x7fff0000, 0, 0x7fff0000) +and r1.xy, r1.zwzz, l(2047, 2047, 0, 0) +ubfe r4.xyzw, l(1, 1, 11, 11), l(10, 10, 11, 11), r1.zwzw +ieq r2.zw, r1.xxxy, l(0, 0, 1024, 1024) +movc r1.xy, r2.zwzz, l(1025,1025,0,0), r1.xyxx +movc r5.xyzw, r4.xyxy, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r1.xy, r1.xyxx, r5.xyxx +iadd r1.xy, r4.xyxx, r1.xyxx +ishl r2.zw, r1.xxxy, l(0, 0, 5, 5) +ushr r1.xy, r1.xyxx, l(5, 5, 0, 0) +or r1.xy, r1.xyxx, r2.zwzz +xor r1.xy, r5.zwzz, r1.xyxx +iadd r1.xy, r4.xyxx, r1.xyxx +ubfe r2.zw, l(0, 0, 1, 1), l(0, 0, 21, 21), r1.zzzw +ieq r4.xy, r4.zwzz, l(1024, 1024, 0, 0) +movc r4.xy, r4.xyxx, l(1025,1025,0,0), r4.zwzz +movc r5.xyzw, r2.zwzw, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r4.xy, r4.xyxx, r5.xyxx +iadd r4.xy, r2.zwzz, r4.xyxx +ishl r4.zw, r4.xxxy, l(0, 0, 5, 5) +ushr r4.xy, r4.xyxx, l(5, 5, 0, 0) +or r4.xy, r4.xyxx, r4.zwzz +xor r4.xy, r5.zwzz, r4.xyxx +iadd r2.zw, r2.zzzw, r4.xxxy +ishl r2.zw, r2.zzzw, l(0, 0, 16, 16) +or r4.xz, r1.xxyx, r2.zzwz +ushr r1.xy, r1.zwzz, l(22, 22, 0, 0) +ushr r1.zw, r1.xxxy, l(0, 0, 9, 9) +ieq r2.zw, r1.xxxy, l(0, 0, 512, 512) +movc r1.xy, r2.zwzz, l(513,513,0,0), r1.xyxx +movc r5.xyzw, r1.zwzw, l(1023,1023,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r1.xy, r1.xyxx, r5.xyxx +iadd r1.xy, r1.zwzz, r1.xyxx +ishl r2.zw, r1.xxxy, l(0, 0, 6, 6) +ushr r1.xy, r1.xyxx, l(3, 3, 0, 0) +or r1.xy, r1.xyxx, r2.zwzz +xor r1.xy, r5.zwzz, r1.xyxx +iadd r1.xy, r1.zwzz, r1.xyxx +or r4.yw, r1.xxxy, l(0, 0x7fff0000, 0, 0x7fff0000) +store_uav_typed U0[0].xyzw, r0.wwww, r3.xyzw +iadd r1.xyz, r0.wwww, l(1, 2, 3, 0) +store_uav_typed U0[0].xyzw, r1.xxxx, r4.xyzw +if_nz r0.x + mov r0.x, l(32) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r3.xyzw, r0.xxxx, T0[0].xyzw +if_nz r2.x + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +if_nz r2.y + ushr r2.xyzw, r3.xyzw, l(16, 16, 16, 16) + bfi r3.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r3.xyzw, r2.xyzw +endif +and r0.xy, r3.xyxx, l(2047, 2047, 0, 0) +ubfe r2.xyzw, l(1, 1, 11, 11), l(10, 10, 11, 11), r3.xyxy +ieq r1.xw, r0.xxxy, l(1024, 0, 0, 1024) +movc r0.xy, r1.xwxx, l(1025,1025,0,0), r0.xyxx +movc r4.xyzw, r2.xyxy, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r0.xy, r0.xyxx, r4.xyxx +iadd r0.xy, r2.xyxx, r0.xyxx +ishl r1.xw, r0.xxxy, l(5, 0, 0, 5) +ushr r0.xy, r0.xyxx, l(5, 5, 0, 0) +or r0.xy, r0.xyxx, r1.xwxx +xor r0.xy, r4.zwzz, r0.xyxx +iadd r0.xy, r2.xyxx, r0.xyxx +ubfe r1.xw, l(1, 0, 0, 1), l(21, 0, 0, 21), r3.xxxy +ieq r2.xy, r2.zwzz, l(1024, 1024, 0, 0) +movc r2.xy, r2.xyxx, l(1025,1025,0,0), r2.zwzz +movc r4.xyzw, r1.xwxw, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r2.xy, r2.xyxx, r4.xyxx +iadd r2.xy, r1.xwxx, r2.xyxx +ishl r2.zw, r2.xxxy, l(0, 0, 5, 5) +ushr r2.xy, r2.xyxx, l(5, 5, 0, 0) +or r2.xy, r2.xyxx, r2.zwzz +xor r2.xy, r4.zwzz, r2.xyxx +iadd r1.xw, r1.xxxw, r2.xxxy +ishl r1.xw, r1.xxxw, l(16, 0, 0, 16) +or r2.xz, r0.xxyx, r1.xxwx +ushr r0.xy, r3.xyxx, l(22, 22, 0, 0) +ushr r1.xw, r0.xxxy, l(9, 0, 0, 9) +ieq r3.xy, r0.xyxx, l(512, 512, 0, 0) +movc r0.xy, r3.xyxx, l(513,513,0,0), r0.xyxx +movc r4.xyzw, r1.xwxw, l(1023,1023,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r0.xy, r0.xyxx, r4.xyxx +iadd r0.xy, r1.xwxx, r0.xyxx +ishl r3.xy, r0.xyxx, l(6, 6, 0, 0) +ushr r0.xy, r0.xyxx, l(3, 3, 0, 0) +or r0.xy, r0.xyxx, r3.xyxx +xor r0.xy, r4.zwzz, r0.xyxx +iadd r0.xy, r1.xwxx, r0.xyxx +or r2.yw, r0.xxxy, l(0, 0x7fff0000, 0, 0x7fff0000) +and r0.xy, r3.zwzz, l(2047, 2047, 0, 0) +ubfe r4.xyzw, l(1, 1, 11, 11), l(10, 10, 11, 11), r3.zwzw +ieq r1.xw, r0.xxxy, l(1024, 0, 0, 1024) +movc r0.xy, r1.xwxx, l(1025,1025,0,0), r0.xyxx +movc r5.xyzw, r4.xyxy, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r0.xy, r0.xyxx, r5.xyxx +iadd r0.xy, r4.xyxx, r0.xyxx +ishl r1.xw, r0.xxxy, l(5, 0, 0, 5) +ushr r0.xy, r0.xyxx, l(5, 5, 0, 0) +or r0.xy, r0.xyxx, r1.xwxx +xor r0.xy, r5.zwzz, r0.xyxx +iadd r0.xy, r4.xyxx, r0.xyxx +ubfe r1.xw, l(1, 0, 0, 1), l(21, 0, 0, 21), r3.zzzw +ieq r3.xy, r4.zwzz, l(1024, 1024, 0, 0) +movc r3.xy, r3.xyxx, l(1025,1025,0,0), r4.zwzz +movc r4.xyzw, r1.xwxw, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r3.xy, r3.xyxx, r4.xyxx +iadd r3.xy, r1.xwxx, r3.xyxx +ishl r4.xy, r3.xyxx, l(5, 5, 0, 0) +ushr r3.xy, r3.xyxx, l(5, 5, 0, 0) +or r3.xy, r3.xyxx, r4.xyxx +xor r3.xy, r4.zwzz, r3.xyxx +iadd r1.xw, r1.xxxw, r3.xxxy +ishl r1.xw, r1.xxxw, l(16, 0, 0, 16) +or r4.xz, r0.xxyx, r1.xxwx +ushr r0.xy, r3.zwzz, l(22, 22, 0, 0) +ushr r1.xw, r0.xxxy, l(9, 0, 0, 9) +ieq r3.xy, r0.xyxx, l(512, 512, 0, 0) +movc r0.xy, r3.xyxx, l(513,513,0,0), r0.xyxx +movc r3.xyzw, r1.xwxw, l(1023,1023,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r0.xy, r0.xyxx, r3.xyxx +iadd r0.xy, r1.xwxx, r0.xyxx +ishl r3.xy, r0.xyxx, l(6, 6, 0, 0) +ushr r0.xy, r0.xyxx, l(3, 3, 0, 0) +or r0.xy, r0.xyxx, r3.xyxx +xor r0.xy, r3.zwzz, r0.xyxx +iadd r0.xy, r1.xwxx, r0.xyxx +or r4.yw, r0.xxxy, l(0, 0x7fff0000, 0, 0x7fff0000) +store_uav_typed U0[0].xyzw, r1.yyyy, r2.xyzw +store_uav_typed U0[0].xyzw, r1.zzzz, r4.xyzw +ret +// Approximately 260 instruction slots used +#endif + +const BYTE texture_load_r11g11b10_rgba16_snorm_cs[] = { + 68, 88, 66, 67, 121, 27, 9, 213, 114, 157, 198, 17, 219, 63, 149, 81, 186, 58, 75, + 154, 1, 0, 0, 0, 168, 41, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 12, 41, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 208, 36, 0, + 0, 81, 0, 5, 0, 52, 9, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 130, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, + 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 0, 9, 226, 0, 16, 0, 1, 0, 0, 0, 86, 6, 2, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 85, 0, + 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 182, 143, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, 139, 0, 0, 14, 82, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 41, 0, 0, 6, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, + 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 96, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, + 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 162, 0, 16, 0, 1, 0, + 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 16, 162, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 166, 10, 2, 0, 86, + 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, 18, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, + 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 8, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, + 0, 0, 17, 162, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, + 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 14, 98, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, 86, + 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, + 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 41, 0, 0, 9, 82, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, + 0, 1, 64, 0, 0, 9, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 130, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 41, 0, + 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 17, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 23, 0, 0, + 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 12, 0, + 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, + 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 146, 0, 16, 0, + 2, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 6, 4, 16, 0, 3, 0, + 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 41, 0, 0, + 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 162, 0, 16, + 0, 0, 0, 0, 0, 86, 13, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, + 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 2, 0, 0, + 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 2, + 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, + 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, + 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, + 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 21, 0, 0, 1, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, + 7, 0, 0, 255, 7, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, + 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 11, 0, + 0, 0, 70, 4, 16, 0, 1, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, 4, + 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 194, 0, 16, + 0, 2, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, 166, 14, 16, 0, 2, + 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 4, 0, 0, 0, 70, 4, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 255, 0, + 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 166, + 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, + 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 166, 14, 16, + 0, 2, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, + 166, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 0, 0, 0, 5, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 2, 0, + 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 87, + 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, + 166, 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, + 0, 6, 4, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 138, 0, + 0, 15, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, + 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, + 0, 32, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 55, 0, 0, 12, 194, 0, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0, + 0, 1, 4, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 55, 0, 0, 15, 242, 0, + 16, 0, 4, 0, 0, 0, 70, 4, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, + 7, 0, 0, 255, 7, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, + 7, 194, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 6, 4, + 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 194, 0, 16, 0, 3, 0, 0, 0, 6, + 4, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, + 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 60, 0, 0, 7, 194, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, + 0, 6, 4, 16, 0, 4, 0, 0, 0, 87, 0, 0, 7, 194, 0, 16, 0, 3, 0, + 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 30, + 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, + 230, 10, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, + 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, 3, + 0, 0, 0, 166, 11, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, + 85, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 9, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, 1, 0, 0, 0, 70, + 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 55, 0, 0, + 15, 242, 0, 16, 0, 4, 0, 0, 0, 230, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 87, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, + 0, 70, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 1, 0, + 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 41, + 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 85, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, + 1, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, + 0, 1, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 1, 0, + 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 2, + 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 60, 0, 0, 10, 162, 0, 16, 0, + 3, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 255, 127, 1, 0, 0, 10, 50, 0, + 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, + 7, 0, 0, 255, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, + 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 11, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 230, 14, 16, 0, 1, 0, 0, 0, 32, + 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, + 0, 55, 0, 0, 12, 50, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, + 5, 0, 0, 0, 70, 4, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, + 0, 255, 7, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 50, + 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, + 5, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 194, 0, + 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 85, 0, 0, 10, + 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, + 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 230, + 10, 16, 0, 2, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, + 230, 10, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, + 7, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 70, 0, + 16, 0, 1, 0, 0, 0, 138, 0, 0, 15, 194, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 21, 0, 0, + 0, 166, 14, 16, 0, 1, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, 4, 0, + 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, + 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 4, 0, + 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 10, 16, 0, 4, 0, + 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, 230, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 255, 0, 0, + 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, + 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 50, + 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, + 4, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, + 0, 0, 5, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, + 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, + 0, 70, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 87, 0, + 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 70, + 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, + 166, 14, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 41, 0, 0, + 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 4, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, + 166, 11, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, + 0, 230, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 22, 0, 0, 0, 22, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 1, + 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 32, 0, 0, 10, 194, 0, 16, + 0, 2, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 55, 0, 0, 12, 50, + 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 1, 2, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 1, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, 230, 14, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, + 0, 70, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 30, 0, + 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 70, + 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, + 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 6, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 1, 0, + 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, + 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, + 0, 87, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 5, 0, + 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 1, + 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, + 60, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, + 255, 127, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 10, + 114, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 164, 0, + 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 32, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, + 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 50, 0, 16, + 0, 0, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 7, + 0, 0, 255, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 242, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 11, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 11, 0, 0, 0, 11, 0, 0, 0, 70, 4, 16, 0, 3, 0, 0, 0, 32, 0, + 0, 10, 146, 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 55, 0, 0, 12, 50, 0, 16, 0, 0, 0, 0, 0, 198, 0, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 4, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, + 255, 7, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, + 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 4, + 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 2, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 146, 0, 16, + 0, 1, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 85, 0, 0, 10, 50, + 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, + 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 198, 0, + 16, 0, 1, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 230, + 10, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, + 0, 0, 0, 0, 0, 138, 0, 0, 15, 146, 0, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, + 6, 4, 16, 0, 3, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, + 0, 230, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, 2, + 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 4, 0, 0, + 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, + 0, 55, 0, 0, 15, 242, 0, 16, 0, 4, 0, 0, 0, 198, 12, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 255, 0, 0, 255, + 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, + 0, 2, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 50, 0, + 16, 0, 2, 0, 0, 0, 198, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 2, + 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, + 0, 5, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, + 70, 0, 16, 0, 2, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 87, 0, 0, + 7, 50, 0, 16, 0, 2, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 146, 0, 16, 0, 1, 0, 0, 0, 6, + 12, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, + 146, 0, 16, 0, 1, 0, 0, 0, 6, 12, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 60, 0, + 0, 7, 82, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 0, 0, 0, 0, 6, + 3, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 22, 0, 0, 0, 22, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 146, 0, 16, 0, 1, 0, + 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, + 3, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 50, 0, + 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, + 2, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 4, 0, 0, 0, 198, 12, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 255, + 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, + 7, 50, 0, 16, 0, 0, 0, 0, 0, 198, 0, 16, 0, 1, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, + 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, + 87, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, + 0, 70, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, + 0, 0, 198, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 60, + 0, 0, 10, 162, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 255, + 127, 1, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 230, 14, + 16, 0, 3, 0, 0, 0, 32, 0, 0, 10, 146, 0, 16, 0, 1, 0, 0, 0, 6, + 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, 0, 0, 0, + 0, 198, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 4, 0, 0, 1, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 55, + 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, 70, 4, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 255, 0, 0, 255, 255, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, + 0, 41, 0, 0, 10, 146, 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, 198, 0, 16, 0, 1, 0, 0, 0, 87, 0, 0, 7, 50, + 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 15, 146, 0, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 21, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 32, 0, 0, + 10, 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 230, 10, 16, 0, 4, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 4, 0, + 0, 0, 198, 12, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, + 7, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, + 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 4, 0, + 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 198, 0, 16, 0, 1, + 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, + 4, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 50, 0, + 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 5, + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, + 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, + 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 146, + 0, 16, 0, 1, 0, 0, 0, 6, 12, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, + 3, 0, 0, 0, 41, 0, 0, 10, 146, 0, 16, 0, 1, 0, 0, 0, 6, 12, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, 4, 0, 0, 0, 6, + 1, 16, 0, 0, 0, 0, 0, 6, 3, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 50, 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 22, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 0, 10, 146, 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 32, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, + 0, 3, 0, 0, 0, 198, 12, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 3, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 198, 0, + 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, + 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 6, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, + 10, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, + 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 3, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, + 0, 230, 10, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 198, 0, 16, 0, 1, 0, 0, 0, 70, + 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, + 6, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 255, + 127, 0, 0, 0, 0, 0, 0, 255, 127, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 166, 10, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 148, 0, 0, 0, 4, 1, 0, 0, 6, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 89, 0, 0, 0, 5, + 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r11g11b10_rgba16_snorm_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r11g11b10_rgba16_snorm_scaled_cs.h new file mode 100644 index 0000000..899ed65 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r11g11b10_rgba16_snorm_scaled_cs.h @@ -0,0 +1,933 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 7 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(3) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(2) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +ishl r1.w, r1.x, l(2) +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r2.z, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(3, 0, 1, 0), r1.xxxx + imad r2.z, r2.z, r3.y, r3.x + ishl r3.x, r1.z, l(10) + and r3.x, r3.x, l(6144) + bfi r3.x, l(3), l(8), r1.w, r3.x + ishr r3.x, r3.x, l(6) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r2.zw, l(0, 0, 20, 20), l(0, 0, 10, 13), r2.zzzz, l(0, 0, 0, 0) + imad r2.zw, r3.xxxx, l(0, 0, 2, 16), r2.zzzw + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 8, 11), vThreadID.zzzz, r2.zzzw + bfi r3.x, l(1), l(4), r1.z, l(0) + ubfe r3.y, l(3), l(6), r2.z + and r3.z, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.y, l(32), r0.x + imad r0.x, r3.z, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r3.xxxx, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r3.z, CB0[0][0].z, l(5) + imad r2.z, r3.x, r3.z, r2.z + ishl r3.xz, r1.zzzz, l(5, 0, 7, 0) + and r3.xz, r3.xxzx, l(448, 0, 2048, 0) + bfi r3.w, l(3), l(3), r1.w, r3.x + bfi r3.w, l(23), l(9), r2.z, r3.w + bfi r4.x, l(1), l(4), r1.z, l(0) + iadd r3.w, r3.w, r4.x + ishl r4.yz, r3.xxxx, l(0, 3, 2, 0) + bfi r4.yz, l(0, 3, 3, 0), l(0, 6, 5, 0), r1.wwww, r4.yyzy + bfi r4.yz, l(0, 23, 23, 0), l(0, 12, 11, 0), r2.zzzz, r4.yyzy + imad r4.xy, r4.xxxx, l(8, 4, 0, 0), r4.yzyy + bfi r1.w, l(12), l(0), r3.z, r4.x + and r2.z, r4.y, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.w, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].xyzw +ieq r1.xzw, r0.yyyy, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +if_nz r1.z + ushr r4.xyzw, r3.xyzw, l(16, 16, 16, 16) + bfi r3.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r3.xyzw, r4.xyzw +endif +and r2.yz, r3.xxyx, l(0, 2047, 2047, 0) +ubfe r4.xyzw, l(1, 1, 11, 11), l(10, 10, 11, 11), r3.xyxy +ieq r5.xy, r2.yzyy, l(1024, 1024, 0, 0) +movc r2.yz, r5.xxyx, l(0,1025,1025,0), r2.yyzy +movc r5.xyzw, r4.xyxy, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r2.yz, r2.yyzy, r5.xxyx +iadd r2.yz, r4.xxyx, r2.yyzy +ishl r5.xy, r2.yzyy, l(5, 5, 0, 0) +ushr r2.yz, r2.yyzy, l(0, 5, 5, 0) +or r2.yz, r2.yyzy, r5.xxyx +xor r2.yz, r5.zzwz, r2.yyzy +iadd r2.yz, r4.xxyx, r2.yyzy +ubfe r4.xy, l(1, 1, 0, 0), l(21, 21, 0, 0), r3.xyxx +ieq r5.xy, r4.zwzz, l(1024, 1024, 0, 0) +movc r4.zw, r5.xxxy, l(0,0,1025,1025), r4.zzzw +movc r5.xyzw, r4.xyxy, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r4.zw, r4.zzzw, r5.xxxy +iadd r4.zw, r4.xxxy, r4.zzzw +ishl r5.xy, r4.zwzz, l(5, 5, 0, 0) +ushr r4.zw, r4.zzzw, l(0, 0, 5, 5) +or r4.zw, r4.zzzw, r5.xxxy +xor r4.zw, r5.zzzw, r4.zzzw +iadd r4.xy, r4.xyxx, r4.zwzz +ishl r4.xy, r4.xyxx, l(16, 16, 0, 0) +or r4.xz, r2.yyzy, r4.xxyx +ushr r2.yz, r3.xxyx, l(0, 22, 22, 0) +ushr r3.xy, r2.yzyy, l(9, 9, 0, 0) +ieq r5.xy, r2.yzyy, l(512, 512, 0, 0) +movc r2.yz, r5.xxyx, l(0,513,513,0), r2.yyzy +movc r5.xyzw, r3.xyxy, l(1023,1023,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r2.yz, r2.yyzy, r5.xxyx +iadd r2.yz, r3.xxyx, r2.yyzy +ishl r5.xy, r2.yzyy, l(6, 6, 0, 0) +ushr r2.yz, r2.yyzy, l(0, 3, 3, 0) +or r2.yz, r2.yyzy, r5.xxyx +xor r2.yz, r5.zzwz, r2.yyzy +iadd r2.yz, r3.xxyx, r2.yyzy +or r4.yw, r2.yyyz, l(0, 0x7fff0000, 0, 0x7fff0000) +and r2.yz, r3.zzwz, l(0, 2047, 2047, 0) +ubfe r5.xyzw, l(1, 1, 11, 11), l(10, 10, 11, 11), r3.zwzw +ieq r3.xy, r2.yzyy, l(1024, 1024, 0, 0) +movc r2.yz, r3.xxyx, l(0,1025,1025,0), r2.yyzy +movc r6.xyzw, r5.xyxy, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r2.yz, r2.yyzy, r6.xxyx +iadd r2.yz, r5.xxyx, r2.yyzy +ishl r3.xy, r2.yzyy, l(5, 5, 0, 0) +ushr r2.yz, r2.yyzy, l(0, 5, 5, 0) +or r2.yz, r2.yyzy, r3.xxyx +xor r2.yz, r6.zzwz, r2.yyzy +iadd r2.yz, r5.xxyx, r2.yyzy +ubfe r3.xy, l(1, 1, 0, 0), l(21, 21, 0, 0), r3.zwzz +ieq r5.xy, r5.zwzz, l(1024, 1024, 0, 0) +movc r5.xy, r5.xyxx, l(1025,1025,0,0), r5.zwzz +movc r6.xyzw, r3.xyxy, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r5.xy, r5.xyxx, r6.xyxx +iadd r5.xy, r3.xyxx, r5.xyxx +ishl r5.zw, r5.xxxy, l(0, 0, 5, 5) +ushr r5.xy, r5.xyxx, l(5, 5, 0, 0) +or r5.xy, r5.xyxx, r5.zwzz +xor r5.xy, r6.zwzz, r5.xyxx +iadd r3.xy, r3.xyxx, r5.xyxx +ishl r3.xy, r3.xyxx, l(16, 16, 0, 0) +or r5.xz, r2.yyzy, r3.xxyx +ushr r2.yz, r3.zzwz, l(0, 22, 22, 0) +ushr r3.xy, r2.yzyy, l(9, 9, 0, 0) +ieq r3.zw, r2.yyyz, l(0, 0, 512, 512) +movc r2.yz, r3.zzwz, l(0,513,513,0), r2.yyzy +movc r6.xyzw, r3.xyxy, l(1023,1023,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r2.yz, r2.yyzy, r6.xxyx +iadd r2.yz, r3.xxyx, r2.yyzy +ishl r3.zw, r2.yyyz, l(0, 0, 6, 6) +ushr r2.yz, r2.yyzy, l(0, 3, 3, 0) +or r2.yz, r2.yyzy, r3.zzwz +xor r2.yz, r6.zzwz, r2.yyzy +iadd r2.yz, r3.xxyx, r2.yyzy +or r5.yw, r2.yyyz, l(0, 0x7fff0000, 0, 0x7fff0000) +store_uav_typed U0[0].xyzw, r1.yyyy, r4.xyzw +iadd r2.yzw, r1.yyyy, l(0, 1, 2, 3) +store_uav_typed U0[0].xyzw, r2.yyyy, r5.xyzw +ult r0.y, l(1), r0.z +if_nz r0.y + udiv r0.y, null, r2.x, r0.z + imad r0.y, -r0.y, r0.z, r2.x + iadd r1.w, r0.y, l(1) + ieq r1.w, r0.z, r1.w + if_nz r1.w + ishl r0.z, r0.z, l(5) + ishl r0.y, r0.y, l(4) + iadd r0.y, -r0.y, r0.z + else + mov r0.y, l(16) + endif +else + mov r0.y, l(32) +endif +imul null, r0.y, r0.w, r0.y +ushr r0.y, r0.y, l(4) +iadd r0.x, r0.y, r0.x +ld r0.xyzw, r0.xxxx, T0[0].xyzw +if_nz r1.x + ishl r3.xyzw, r0.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r0.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r0.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r1.z + ushr r3.xyzw, r0.xyzw, l(16, 16, 16, 16) + bfi r0.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r0.xyzw, r3.xyzw +endif +and r1.xz, r0.xxyx, l(2047, 0, 2047, 0) +ubfe r3.xyzw, l(1, 1, 11, 11), l(10, 10, 11, 11), r0.xyxy +ieq r2.xy, r1.xzxx, l(1024, 1024, 0, 0) +movc r1.xz, r2.xxyx, l(1025,0,1025,0), r1.xxzx +movc r4.xyzw, r3.xyxy, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r1.xz, r1.xxzx, r4.xxyx +iadd r1.xz, r3.xxyx, r1.xxzx +ishl r2.xy, r1.xzxx, l(5, 5, 0, 0) +ushr r1.xz, r1.xxzx, l(5, 0, 5, 0) +or r1.xz, r1.xxzx, r2.xxyx +xor r1.xz, r4.zzwz, r1.xxzx +iadd r1.xz, r3.xxyx, r1.xxzx +ubfe r2.xy, l(1, 1, 0, 0), l(21, 21, 0, 0), r0.xyxx +ieq r3.xy, r3.zwzz, l(1024, 1024, 0, 0) +movc r3.xy, r3.xyxx, l(1025,1025,0,0), r3.zwzz +movc r4.xyzw, r2.xyxy, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r3.xy, r3.xyxx, r4.xyxx +iadd r3.xy, r2.xyxx, r3.xyxx +ishl r3.zw, r3.xxxy, l(0, 0, 5, 5) +ushr r3.xy, r3.xyxx, l(5, 5, 0, 0) +or r3.xy, r3.xyxx, r3.zwzz +xor r3.xy, r4.zwzz, r3.xyxx +iadd r2.xy, r2.xyxx, r3.xyxx +ishl r2.xy, r2.xyxx, l(16, 16, 0, 0) +or r3.xz, r1.xxzx, r2.xxyx +ushr r0.xy, r0.xyxx, l(22, 22, 0, 0) +ushr r1.xz, r0.xxyx, l(9, 0, 9, 0) +ieq r2.xy, r0.xyxx, l(512, 512, 0, 0) +movc r0.xy, r2.xyxx, l(513,513,0,0), r0.xyxx +movc r4.xyzw, r1.xzxz, l(1023,1023,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r0.xy, r0.xyxx, r4.xyxx +iadd r0.xy, r1.xzxx, r0.xyxx +ishl r2.xy, r0.xyxx, l(6, 6, 0, 0) +ushr r0.xy, r0.xyxx, l(3, 3, 0, 0) +or r0.xy, r0.xyxx, r2.xyxx +xor r0.xy, r4.zwzz, r0.xyxx +iadd r0.xy, r1.xzxx, r0.xyxx +or r3.yw, r0.xxxy, l(0, 0x7fff0000, 0, 0x7fff0000) +and r0.xy, r0.zwzz, l(2047, 2047, 0, 0) +ubfe r4.xyzw, l(1, 1, 11, 11), l(10, 10, 11, 11), r0.zwzw +ieq r1.xz, r0.xxyx, l(1024, 0, 1024, 0) +movc r0.xy, r1.xzxx, l(1025,1025,0,0), r0.xyxx +movc r5.xyzw, r4.xyxy, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r0.xy, r0.xyxx, r5.xyxx +iadd r0.xy, r4.xyxx, r0.xyxx +ishl r1.xz, r0.xxyx, l(5, 0, 5, 0) +ushr r0.xy, r0.xyxx, l(5, 5, 0, 0) +or r0.xy, r0.xyxx, r1.xzxx +xor r0.xy, r5.zwzz, r0.xyxx +iadd r0.xy, r4.xyxx, r0.xyxx +ubfe r1.xz, l(1, 0, 1, 0), l(21, 0, 21, 0), r0.zzwz +ieq r2.xy, r4.zwzz, l(1024, 1024, 0, 0) +movc r2.xy, r2.xyxx, l(1025,1025,0,0), r4.zwzz +movc r4.xyzw, r1.xzxz, l(2047,2047,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r2.xy, r2.xyxx, r4.xyxx +iadd r2.xy, r1.xzxx, r2.xyxx +ishl r4.xy, r2.xyxx, l(5, 5, 0, 0) +ushr r2.xy, r2.xyxx, l(5, 5, 0, 0) +or r2.xy, r2.xyxx, r4.xyxx +xor r2.xy, r4.zwzz, r2.xyxx +iadd r1.xz, r1.xxzx, r2.xxyx +ishl r1.xz, r1.xxzx, l(16, 0, 16, 0) +or r4.xz, r0.xxyx, r1.xxzx +ushr r0.xy, r0.zwzz, l(22, 22, 0, 0) +ushr r0.zw, r0.xxxy, l(0, 0, 9, 9) +ieq r1.xz, r0.xxyx, l(512, 0, 512, 0) +movc r0.xy, r1.xzxx, l(513,513,0,0), r0.xyxx +movc r5.xyzw, r0.zwzw, l(1023,1023,0x0000ffff,0x0000ffff), l(0,0,0,0) +xor r0.xy, r0.xyxx, r5.xyxx +iadd r0.xy, r0.zwzz, r0.xyxx +ishl r1.xz, r0.xxyx, l(6, 0, 6, 0) +ushr r0.xy, r0.xyxx, l(3, 3, 0, 0) +or r0.xy, r0.xyxx, r1.xzxx +xor r0.xy, r5.zwzz, r0.xyxx +iadd r0.xy, r0.zwzz, r0.xyxx +or r4.yw, r0.xxxy, l(0, 0x7fff0000, 0, 0x7fff0000) +store_uav_typed U0[0].xyzw, r2.zzzz, r3.xyzw +store_uav_typed U0[0].xyzw, r2.wwww, r4.xyzw +ret +// Approximately 280 instruction slots used +#endif + +const BYTE texture_load_r11g11b10_rgba16_snorm_scaled_cs[] = { + 68, 88, 66, 67, 42, 104, 90, 160, 187, 155, 83, 235, 160, 99, 161, 175, 154, 132, 58, + 61, 1, 0, 0, 0, 84, 44, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 184, 43, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 124, 39, 0, + 0, 81, 0, 5, 0, 223, 9, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 7, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, + 0, 42, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 85, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, + 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 10, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 24, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 194, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, + 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, + 0, 2, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 166, 14, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 166, 10, + 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 9, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 15, 194, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 9, 66, 0, 16, 0, 3, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, + 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, + 82, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 23, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, + 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 4, 0, + 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 12, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, + 0, 2, 0, 0, 0, 86, 6, 16, 0, 4, 0, 0, 0, 35, 0, 0, 12, 50, 0, + 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, + 4, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, + 166, 11, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, + 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 10, 210, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 98, 0, + 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, + 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 11, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 70, 4, 16, 0, 3, 0, 0, 0, 32, + 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 55, 0, 0, 12, 98, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 5, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, 0, + 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, + 5, 0, 0, 0, 70, 4, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, + 0, 255, 7, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 98, + 0, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, + 5, 0, 0, 0, 30, 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, + 0, 4, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 50, 0, + 16, 0, 5, 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, + 98, 0, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 60, 0, + 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 6, + 1, 16, 0, 5, 0, 0, 0, 87, 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, + 166, 11, 16, 0, 5, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 30, 0, 0, + 7, 98, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 4, 0, 0, 0, 86, 6, + 16, 0, 2, 0, 0, 0, 138, 0, 0, 15, 50, 0, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 3, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, 5, 0, + 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 194, 0, 16, 0, + 4, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, 166, 14, 16, 0, 4, 0, + 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, 70, 4, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 255, 0, 0, + 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 87, 0, 0, 7, 194, 0, 16, 0, 4, 0, 0, 0, 166, 14, + 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 194, + 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, + 4, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 230, 10, 16, + 0, 4, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 166, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 5, 0, 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 4, 0, 0, + 0, 166, 14, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 87, 0, + 0, 7, 194, 0, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 5, 0, 0, 0, 166, + 14, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, + 70, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 41, 0, 0, + 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 4, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, + 6, 1, 16, 0, 4, 0, 0, 0, 85, 0, 0, 10, 98, 0, 16, 0, 2, 0, 0, + 0, 6, 1, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 22, 0, + 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 3, + 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, + 0, 5, 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 2, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 98, + 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 86, 6, 16, + 0, 2, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, 70, 4, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, + 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, + 0, 86, 6, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 5, 0, 0, 0, 30, 0, + 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 86, + 6, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, + 150, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 98, 0, 16, 0, 2, 0, + 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 98, 0, 16, 0, + 2, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 5, 0, 0, + 0, 87, 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 5, 0, + 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 98, 0, 16, 0, 2, + 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, + 60, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 9, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, + 255, 127, 1, 0, 0, 10, 98, 0, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 2, 64, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 230, + 14, 16, 0, 3, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, + 150, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 98, 0, 16, 0, 2, 0, + 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, + 4, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, + 55, 0, 0, 15, 242, 0, 16, 0, 6, 0, 0, 0, 70, 4, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 255, 0, 0, 255, 255, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 87, 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, + 2, 0, 0, 0, 6, 1, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 98, 0, 16, + 0, 2, 0, 0, 0, 6, 1, 16, 0, 5, 0, 0, 0, 86, 6, 16, 0, 2, 0, + 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 150, 5, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 10, 98, 0, 16, 0, 2, 0, 0, 0, 86, 6, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 86, + 6, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 87, 0, 0, 7, + 98, 0, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 6, 0, 0, 0, 86, 6, 16, + 0, 2, 0, 0, 0, 30, 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 6, 1, + 16, 0, 5, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 138, 0, 0, 15, 50, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 32, 0, + 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 2, + 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 12, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 6, + 0, 0, 0, 70, 4, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, + 255, 7, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, + 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 6, + 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, + 3, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, + 0, 5, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 85, 0, 0, 10, 50, + 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, + 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, + 7, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 230, 10, + 16, 0, 5, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 5, 0, 0, 0, 230, + 10, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, + 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, + 0, 5, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, 5, 0, 0, 0, + 86, 6, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 85, 0, 0, + 10, 98, 0, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 85, + 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 0, 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 86, 9, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 55, 0, 0, 12, 98, 0, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 1, 2, 0, + 0, 0, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 55, 0, 0, 15, 242, 0, + 16, 0, 6, 0, 0, 0, 70, 4, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, + 3, 0, 0, 255, 3, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, + 7, 98, 0, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 6, 1, + 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 6, + 1, 16, 0, 3, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, + 194, 0, 16, 0, 3, 0, 0, 0, 86, 9, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 85, 0, + 0, 10, 98, 0, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 60, 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, + 0, 166, 11, 16, 0, 3, 0, 0, 0, 87, 0, 0, 7, 98, 0, 16, 0, 2, 0, + 0, 0, 166, 11, 16, 0, 6, 0, 0, 0, 86, 6, 16, 0, 2, 0, 0, 0, 30, + 0, 0, 7, 98, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, + 86, 6, 16, 0, 2, 0, 0, 0, 60, 0, 0, 10, 162, 0, 16, 0, 5, 0, 0, + 0, 86, 9, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 255, 127, 0, 0, 0, 0, 0, 0, 255, 127, 164, 0, 0, 8, 242, 224, 33, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 30, 0, 0, 10, 226, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, + 0, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, + 79, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, + 0, 0, 78, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 10, + 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, + 3, 58, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, + 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 54, 0, 0, 5, + 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 21, 0, 0, + 1, 38, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, + 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 82, 0, 16, + 0, 1, 0, 0, 0, 6, 1, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 255, 7, + 0, 0, 0, 0, 0, 0, 255, 7, 0, 0, 0, 0, 0, 0, 138, 0, 0, 15, 242, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 11, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 11, 0, 0, 0, 11, 0, 0, 0, 70, 4, 16, 0, 0, 0, 0, 0, 32, 0, + 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 12, 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, + 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 4, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, + 255, 7, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 82, 0, + 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 4, + 0, 0, 0, 30, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, + 3, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, + 0, 2, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 5, 0, + 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, + 7, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 6, 1, + 16, 0, 2, 0, 0, 0, 87, 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, + 11, 16, 0, 4, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, + 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 6, 2, 16, + 0, 1, 0, 0, 0, 138, 0, 0, 15, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, + 0, 230, 10, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, 3, + 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 4, 0, 0, + 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, + 0, 55, 0, 0, 15, 242, 0, 16, 0, 4, 0, 0, 0, 70, 4, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 255, 0, 0, 255, + 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, + 0, 3, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 50, 0, + 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 3, + 0, 0, 0, 41, 0, 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, + 0, 5, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, + 70, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 3, 0, 0, 0, 87, 0, 0, + 7, 50, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 70, 0, + 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 70, + 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 10, + 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, + 0, 7, 82, 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 6, + 1, 16, 0, 2, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 22, 0, 0, 0, 22, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 82, 0, 16, 0, 1, 0, + 0, 0, 6, 1, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, + 2, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 50, 0, + 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, + 2, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 4, 0, 0, 0, 134, 8, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 255, 3, 0, 0, 255, 255, + 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, + 7, 50, 0, 16, 0, 0, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 70, + 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, + 87, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, + 0, 70, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, + 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 60, + 0, 0, 10, 162, 0, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 255, + 127, 1, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 138, 0, 0, 15, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 230, 14, + 16, 0, 0, 0, 0, 0, 32, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, + 1, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, 0, 0, 0, + 0, 134, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 4, 0, 0, 1, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 55, + 0, 0, 15, 242, 0, 16, 0, 5, 0, 0, 0, 70, 4, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 255, 7, 0, 0, 255, 7, 0, 0, 255, 255, 0, 0, 255, 255, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, + 0, 41, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 85, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 87, 0, 0, 7, 50, + 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 138, 0, 0, 15, 82, 0, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 0, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 32, 0, 0, + 10, 50, 0, 16, 0, 2, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 230, 10, 16, 0, 4, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, 0, 4, 0, + 0, 0, 134, 8, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 7, 0, 0, 255, + 7, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, + 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 4, 0, + 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 134, 0, 16, 0, 1, + 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, + 4, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 10, 50, 0, + 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, + 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, + 0, 4, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 230, 10, + 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, + 2, 0, 0, 0, 41, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 82, 0, 16, 0, 4, 0, 0, 0, 6, + 1, 16, 0, 0, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 50, 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 22, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, + 32, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, 0, 0, 0, 0, 134, 0, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 55, 0, 0, 15, 242, 0, 16, + 0, 5, 0, 0, 0, 230, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 255, 3, + 0, 0, 255, 3, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 7, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 5, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 230, 10, + 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 1, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, + 10, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, + 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, + 134, 0, 16, 0, 1, 0, 0, 0, 87, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, + 0, 230, 10, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 70, + 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, + 6, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 255, + 127, 0, 0, 0, 0, 0, 0, 255, 127, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 246, 15, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 148, 0, 0, 0, 24, 1, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 98, 0, 0, 0, 94, 0, 0, 0, 5, + 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r16_snorm_float_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r16_snorm_float_cs.h new file mode 100644 index 0000000..ed2c9e8 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r16_snorm_float_cs.h @@ -0,0 +1,443 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(4) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(1) +imad r1.y, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.y, CB0[0][2].x, r0.w +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r1.z, l(27), l(1), vThreadID.x + imad r0.y, r0.y, r1.w, r1.z + ishl r1.z, vThreadID.y, l(9) + ishr r1.z, r1.z, l(6) + and r1.z, r1.z, l(48) + iadd r1.w, r2.y, r2.z + and r2.x, r1.w, l(1) + ishr r2.y, r1.x, l(3) + bfi r1.w, l(1), l(1), r1.w, l(0) + iadd r1.w, r1.w, r2.y + bfi r1.w, l(2), l(1), r1.w, l(0) + iadd r1.w, r1.w, r2.x + bfi r2.xy, l(21, 21, 0, 0), l(9, 12, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(7, 10, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(4) + bfi r1.w, l(2), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(5, 5, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.z, l(27), l(1), vThreadID.x + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.z, r2.x, r1.w, r1.z + bfi r2.xzw, l(4, 0, 4, 4), l(4, 0, 7, 6), vThreadID.yyyy, l(0, 0, 0, 0) + bfi r2.xzw, l(24, 0, 24, 24), l(8, 0, 11, 10), r1.zzzz, r2.xxzw + ishl r1.z, vThreadID.y, l(7) + and r1.z, r1.z, l(2048) + bfi r1.z, l(12), l(0), r1.z, r2.z + and r1.w, r2.w, l(1792) + iadd r1.z, r1.z, r1.w + and r1.w, r2.y, l(2) + ishr r1.x, r1.x, l(3) + iadd r1.x, r1.x, r1.w + bfi r1.x, l(2), l(6), r1.x, l(0) + iadd r1.x, r1.z, r1.x + bfi r0.y, l(6), l(0), r2.x, r1.x + endif +else + imad r1.x, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.x, CB0[0][0].z, r0.w +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.y, r0.y, l(4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r0.z, r0.z, l(1) +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +ibfe r3.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r2.xyzw +itof r3.xyzw, r3.xyzw +mul r3.xyzw, r3.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r3.xyzw, r3.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +ishr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +itof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r2.xyzw, r2.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +f32tof16 r3.xyzw, r3.xyzw +f32tof16 r2.xyzw, r2.xyzw +imad r2.xyzw, r2.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r3.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r2.xyzw +iadd r0.w, r1.y, l(1) +if_nz r0.x + mov r0.x, l(64) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +ibfe r3.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r2.xyzw +itof r3.xyzw, r3.xyzw +mul r3.xyzw, r3.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r3.xyzw, r3.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +ishr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +itof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r2.xyzw, r2.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +f32tof16 r3.xyzw, r3.xyzw +f32tof16 r2.xyzw, r2.xyzw +imad r2.xyzw, r2.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r3.xyzw +store_uav_typed U0[0].xyzw, r0.wwww, r2.xyzw +ret +// Approximately 118 instruction slots used +#endif + +const BYTE texture_load_r16_snorm_float_cs[] = { + 68, 88, 66, 67, 143, 151, 37, 156, 111, 236, 179, 56, 228, 140, 226, 249, 38, 142, 80, + 129, 1, 0, 0, 0, 8, 20, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 108, 19, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 48, 15, 0, + 0, 81, 0, 5, 0, 204, 3, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 114, 0, 16, 0, 2, 0, + 0, 0, 150, 5, 2, 0, 2, 64, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 1, 0, 0, 0, + 246, 139, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 8, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 10, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 2, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, + 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 2, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, + 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 50, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 34, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, + 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 8, 66, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 10, 0, 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, + 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 19, 210, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 86, 5, 2, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 140, 0, 0, 17, 210, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 24, 0, + 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 166, 10, 16, 0, + 1, 0, 0, 0, 6, 14, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, + 7, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 35, 0, 0, 9, 18, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 30, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 21, 0, 0, 1, 139, 0, 0, 15, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 56, 0, + 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 52, 0, 0, 10, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 42, 0, 0, 10, 242, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 52, + 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 130, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 130, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 70, 14, 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, 224, + 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, + 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 45, + 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, + 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, + 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, + 0, 0, 0, 21, 0, 0, 1, 139, 0, 0, 15, 242, 0, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, + 56, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 52, 0, 0, 10, 242, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 42, 0, 0, 10, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, + 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 56, + 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, + 56, 52, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 128, 191, 130, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 130, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 70, 14, 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, + 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, + 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, + 0, 0, 0, 38, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r16_snorm_float_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r16_snorm_float_scaled_cs.h new file mode 100644 index 0000000..ed6ab77 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r16_snorm_float_scaled_cs.h @@ -0,0 +1,482 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(4) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(1) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(3) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r1.w, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), r1.xxxx + imad r1.w, r1.w, r3.y, r3.x + ishl r2.z, r1.z, l(9) + ishr r2.z, r2.z, l(6) + and r2.z, r2.z, l(48) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r3.xy, l(21, 21, 0, 0), l(9, 12, 0, 0), r1.wwww, l(0, 0, 0, 0) + imad r2.zw, r2.zzzz, l(0, 0, 2, 16), r3.xxxy + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 7, 10), vThreadID.zzzz, r2.zzzw + bfi r1.w, l(1), l(4), r1.z, l(0) + ubfe r3.x, l(3), l(6), r2.z + and r3.y, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.x, l(32), r0.x + imad r0.x, r3.y, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r1.wwww, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 2, 0), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.w, r3.x, r1.w, r2.z + bfi r3.xzw, l(4, 0, 4, 4), l(4, 0, 7, 6), r1.zzzz, l(0, 0, 0, 0) + bfi r3.xzw, l(24, 0, 24, 24), l(8, 0, 11, 10), r1.wwww, r3.xxzw + ishl r1.w, r1.z, l(7) + and r1.w, r1.w, l(2048) + bfi r1.w, l(12), l(0), r1.w, r3.z + and r2.z, r3.w, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.x, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].xyzw +ieq r0.y, r0.y, l(1) +if_nz r0.y + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +ibfe r4.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r3.xyzw +itof r4.xyzw, r4.xyzw +mul r4.xyzw, r4.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r4.xyzw, r4.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +ishr r3.xyzw, r3.xyzw, l(16, 16, 16, 16) +itof r3.xyzw, r3.xyzw +mul r3.xyzw, r3.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r3.xyzw, r3.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +f32tof16 r4.xyzw, r4.xyzw +f32tof16 r3.xyzw, r3.xyzw +imad r3.xyzw, r3.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r4.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r3.xyzw +iadd r1.x, r1.y, l(1) +ult r1.z, l(1), r0.z +if_nz r1.z + udiv r1.z, null, r2.x, r0.z + imad r1.z, -r1.z, r0.z, r2.x + iadd r1.w, r1.z, l(1) + ieq r1.w, r0.z, r1.w + if_nz r1.w + ishl r0.z, r0.z, l(6) + ishl r1.z, r1.z, l(4) + iadd r0.z, r0.z, -r1.z + else + mov r0.z, l(16) + endif +else + mov r0.z, l(64) +endif +imul null, r0.z, r0.w, r0.z +ushr r0.z, r0.z, l(4) +iadd r0.x, r0.z, r0.x +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.y + ishl r0.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r0.xyzw, r0.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r0.xyzw, r3.xyzw +endif +ibfe r0.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r2.xyzw +itof r0.xyzw, r0.xyzw +mul r0.xyzw, r0.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r0.xyzw, r0.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +ishr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +itof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r2.xyzw, r2.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +f32tof16 r0.xyzw, r0.xyzw +f32tof16 r2.xyzw, r2.xyzw +imad r0.xyzw, r2.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r0.xyzw +store_uav_typed U0[0].xyzw, r1.xxxx, r0.xyzw +ret +// Approximately 131 instruction slots used +#endif + +const BYTE texture_load_r16_snorm_float_scaled_cs[] = { + 68, 88, 66, 67, 110, 82, 64, 169, 215, 177, 103, 92, 47, 114, 203, 69, 237, 23, 57, + 97, 1, 0, 0, 0, 244, 21, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 88, 21, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 28, 17, 0, + 0, 81, 0, 5, 0, 71, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 10, 194, 0, 16, 0, 2, 0, + 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, + 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, 143, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, 0, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, + 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 12, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 6, + 4, 16, 0, 3, 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 10, 0, + 0, 0, 166, 10, 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 138, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, + 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 32, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, + 0, 0, 15, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, + 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 20, 210, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 166, 10, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 140, 0, 0, 17, 210, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 246, + 15, 16, 0, 1, 0, 0, 0, 6, 14, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 7, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, + 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, + 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, + 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 6, + 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, + 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, + 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 139, 0, 0, 15, 242, 0, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 43, 0, 0, 5, 242, + 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, + 0, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 52, 0, + 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, + 42, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, + 56, 0, 1, 0, 56, 52, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, + 0, 128, 191, 0, 0, 128, 191, 130, 0, 0, 5, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 4, 0, 0, 0, 130, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, + 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, + 0, 1, 0, 0, 0, 78, 0, 0, 8, 66, 0, 16, 0, 1, 0, 0, 0, 0, 208, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, + 0, 0, 10, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 128, 65, 0, 0, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, + 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 8, 66, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 65, 0, 0, + 0, 1, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 54, + 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, + 21, 0, 0, 1, 38, 0, 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, + 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, + 8, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 21, 0, 0, 1, 139, 0, 0, 15, 242, 0, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 56, 0, + 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 52, 0, 0, 10, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 42, 0, 0, 10, 242, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 52, + 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 130, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 130, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 70, 14, 16, 0, 0, 0, 0, 0, 164, 0, 0, 8, 242, 224, + 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, + 131, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, + 0, 46, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r16_unorm_float_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r16_unorm_float_cs.h new file mode 100644 index 0000000..c50f2c8 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r16_unorm_float_cs.h @@ -0,0 +1,429 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(4) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(1) +imad r1.y, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.y, CB0[0][2].x, r0.w +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r1.z, l(27), l(1), vThreadID.x + imad r0.y, r0.y, r1.w, r1.z + ishl r1.z, vThreadID.y, l(9) + ishr r1.z, r1.z, l(6) + and r1.z, r1.z, l(48) + iadd r1.w, r2.y, r2.z + and r2.x, r1.w, l(1) + ishr r2.y, r1.x, l(3) + bfi r1.w, l(1), l(1), r1.w, l(0) + iadd r1.w, r1.w, r2.y + bfi r1.w, l(2), l(1), r1.w, l(0) + iadd r1.w, r1.w, r2.x + bfi r2.xy, l(21, 21, 0, 0), l(9, 12, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(7, 10, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(4) + bfi r1.w, l(2), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(5, 5, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.z, l(27), l(1), vThreadID.x + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.z, r2.x, r1.w, r1.z + bfi r2.xzw, l(4, 0, 4, 4), l(4, 0, 7, 6), vThreadID.yyyy, l(0, 0, 0, 0) + bfi r2.xzw, l(24, 0, 24, 24), l(8, 0, 11, 10), r1.zzzz, r2.xxzw + ishl r1.z, vThreadID.y, l(7) + and r1.z, r1.z, l(2048) + bfi r1.z, l(12), l(0), r1.z, r2.z + and r1.w, r2.w, l(1792) + iadd r1.z, r1.z, r1.w + and r1.w, r2.y, l(2) + ishr r1.x, r1.x, l(3) + iadd r1.x, r1.x, r1.w + bfi r1.x, l(2), l(6), r1.x, l(0) + iadd r1.x, r1.z, r1.x + bfi r0.y, l(6), l(0), r2.x, r1.x + endif +else + imad r1.x, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.x, CB0[0][0].z, r0.w +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.y, r0.y, l(4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r0.z, r0.z, l(1) +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +and r3.xyzw, r2.xyzw, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff) +utof r3.xyzw, r3.xyzw +mul r3.xyzw, r3.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +ushr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +utof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +f32tof16 r3.xyzw, r3.xyzw +f32tof16 r2.xyzw, r2.xyzw +imad r2.xyzw, r2.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r3.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r2.xyzw +iadd r0.w, r1.y, l(1) +if_nz r0.x + mov r0.x, l(64) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +and r3.xyzw, r2.xyzw, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff) +utof r3.xyzw, r3.xyzw +mul r3.xyzw, r3.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +ushr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +utof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +f32tof16 r3.xyzw, r3.xyzw +f32tof16 r2.xyzw, r2.xyzw +imad r2.xyzw, r2.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r3.xyzw +store_uav_typed U0[0].xyzw, r0.wwww, r2.xyzw +ret +// Approximately 114 instruction slots used +#endif + +const BYTE texture_load_r16_unorm_float_cs[] = { + 68, 88, 66, 67, 182, 22, 12, 160, 129, 36, 182, 51, 1, 81, 38, 127, 220, 191, 206, + 163, 1, 0, 0, 0, 64, 19, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 164, 18, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 104, 14, 0, + 0, 81, 0, 5, 0, 154, 3, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 114, 0, 16, 0, 2, 0, + 0, 0, 150, 5, 2, 0, 2, 64, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 1, 0, 0, 0, + 246, 139, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 8, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 10, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 2, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, + 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 2, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, + 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 50, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 34, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, + 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 8, 66, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 10, 0, 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, + 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 19, 210, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 86, 5, 2, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 140, 0, 0, 17, 210, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 24, 0, + 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 166, 10, 16, 0, + 1, 0, 0, 0, 6, 14, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, + 7, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 35, 0, 0, 9, 18, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 30, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, + 255, 0, 0, 255, 255, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 128, 0, 128, 55, 128, 0, + 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 85, 0, 0, 10, 242, 0, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 128, + 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 130, 0, 0, 5, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 130, 0, 0, + 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 35, 0, + 0, 12, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 64, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, + 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, + 0, 1, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, + 255, 255, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 128, 0, 128, 55, 128, 0, 128, 55, 128, + 0, 128, 55, 128, 0, 128, 55, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 128, 0, 128, 55, + 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 130, 0, 0, 5, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 130, 0, 0, 5, 242, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 35, 0, 0, 12, 242, + 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 62, + 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 36, 0, 0, 0, 24, 0, 0, + 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r16_unorm_float_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r16_unorm_float_scaled_cs.h new file mode 100644 index 0000000..40bac4e --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r16_unorm_float_scaled_cs.h @@ -0,0 +1,468 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(4) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(1) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(3) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r1.w, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), r1.xxxx + imad r1.w, r1.w, r3.y, r3.x + ishl r2.z, r1.z, l(9) + ishr r2.z, r2.z, l(6) + and r2.z, r2.z, l(48) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r3.xy, l(21, 21, 0, 0), l(9, 12, 0, 0), r1.wwww, l(0, 0, 0, 0) + imad r2.zw, r2.zzzz, l(0, 0, 2, 16), r3.xxxy + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 7, 10), vThreadID.zzzz, r2.zzzw + bfi r1.w, l(1), l(4), r1.z, l(0) + ubfe r3.x, l(3), l(6), r2.z + and r3.y, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.x, l(32), r0.x + imad r0.x, r3.y, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r1.wwww, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 2, 0), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.w, r3.x, r1.w, r2.z + bfi r3.xzw, l(4, 0, 4, 4), l(4, 0, 7, 6), r1.zzzz, l(0, 0, 0, 0) + bfi r3.xzw, l(24, 0, 24, 24), l(8, 0, 11, 10), r1.wwww, r3.xxzw + ishl r1.w, r1.z, l(7) + and r1.w, r1.w, l(2048) + bfi r1.w, l(12), l(0), r1.w, r3.z + and r2.z, r3.w, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.x, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].xyzw +ieq r0.y, r0.y, l(1) +if_nz r0.y + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +and r4.xyzw, r3.xyzw, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff) +utof r4.xyzw, r4.xyzw +mul r4.xyzw, r4.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +ushr r3.xyzw, r3.xyzw, l(16, 16, 16, 16) +utof r3.xyzw, r3.xyzw +mul r3.xyzw, r3.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +f32tof16 r4.xyzw, r4.xyzw +f32tof16 r3.xyzw, r3.xyzw +imad r3.xyzw, r3.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r4.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r3.xyzw +iadd r1.x, r1.y, l(1) +ult r1.z, l(1), r0.z +if_nz r1.z + udiv r1.z, null, r2.x, r0.z + imad r1.z, -r1.z, r0.z, r2.x + iadd r1.w, r1.z, l(1) + ieq r1.w, r0.z, r1.w + if_nz r1.w + ishl r0.z, r0.z, l(6) + ishl r1.z, r1.z, l(4) + iadd r0.z, r0.z, -r1.z + else + mov r0.z, l(16) + endif +else + mov r0.z, l(64) +endif +imul null, r0.z, r0.w, r0.z +ushr r0.z, r0.z, l(4) +iadd r0.x, r0.z, r0.x +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.y + ishl r0.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r0.xyzw, r0.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r0.xyzw, r3.xyzw +endif +and r0.xyzw, r2.xyzw, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff) +utof r0.xyzw, r0.xyzw +mul r0.xyzw, r0.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +ushr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +utof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +f32tof16 r0.xyzw, r0.xyzw +f32tof16 r2.xyzw, r2.xyzw +imad r0.xyzw, r2.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r0.xyzw +store_uav_typed U0[0].xyzw, r1.xxxx, r0.xyzw +ret +// Approximately 127 instruction slots used +#endif + +const BYTE texture_load_r16_unorm_float_scaled_cs[] = { + 68, 88, 66, 67, 243, 38, 231, 36, 32, 72, 14, 107, 22, 4, 60, 55, 118, 237, 100, + 234, 1, 0, 0, 0, 44, 21, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 144, 20, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 84, 16, 0, + 0, 81, 0, 5, 0, 21, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 10, 194, 0, 16, 0, 2, 0, + 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, + 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, 143, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, 0, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, + 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 12, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 6, + 4, 16, 0, 3, 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 10, 0, + 0, 0, 166, 10, 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 138, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, + 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 32, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, + 0, 0, 15, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, + 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 20, 210, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 166, 10, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 140, 0, 0, 17, 210, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 246, + 15, 16, 0, 1, 0, 0, 0, 6, 14, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 7, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, + 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, + 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, + 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 6, + 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, + 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, + 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 255, 0, + 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 86, 0, 0, 5, 242, 0, + 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 56, 0, 0, 10, 242, + 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, + 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 85, 0, 0, + 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 86, + 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, + 128, 55, 130, 0, 0, 5, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, + 0, 0, 0, 130, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 70, 14, 16, 0, 4, 0, 0, 0, 164, 0, 0, 8, 242, + 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 79, 0, + 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, + 78, 0, 0, 8, 66, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, + 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 10, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, + 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 30, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, + 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 21, 0, 0, 1, 38, + 0, 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, + 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, + 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 1, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, + 1, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, + 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, + 55, 128, 0, 128, 55, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 128, 0, 128, 55, 128, 0, + 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 130, 0, 0, 5, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 130, 0, 0, 5, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 70, 14, 16, 0, 0, + 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 148, 0, 0, 0, 127, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 44, 0, 0, 0, 27, 0, 0, 0, 5, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r4g4b4a4_a4r4g4b4_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r4g4b4a4_a4r4g4b4_cs.h new file mode 100644 index 0000000..9aeccaa --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r4g4b4a4_a4r4g4b4_cs.h @@ -0,0 +1,410 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(4) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(1) +imad r1.y, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.y, CB0[0][2].x, r0.w +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r1.z, l(27), l(1), vThreadID.x + imad r0.y, r0.y, r1.w, r1.z + ishl r1.z, vThreadID.y, l(9) + ishr r1.z, r1.z, l(6) + and r1.z, r1.z, l(48) + iadd r1.w, r2.y, r2.z + and r2.x, r1.w, l(1) + ishr r2.y, r1.x, l(3) + bfi r1.w, l(1), l(1), r1.w, l(0) + iadd r1.w, r1.w, r2.y + bfi r1.w, l(2), l(1), r1.w, l(0) + iadd r1.w, r1.w, r2.x + bfi r2.xy, l(21, 21, 0, 0), l(9, 12, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(7, 10, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(4) + bfi r1.w, l(2), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(5, 5, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.z, l(27), l(1), vThreadID.x + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.z, r2.x, r1.w, r1.z + bfi r2.xzw, l(4, 0, 4, 4), l(4, 0, 7, 6), vThreadID.yyyy, l(0, 0, 0, 0) + bfi r2.xzw, l(24, 0, 24, 24), l(8, 0, 11, 10), r1.zzzz, r2.xxzw + ishl r1.z, vThreadID.y, l(7) + and r1.z, r1.z, l(2048) + bfi r1.z, l(12), l(0), r1.z, r2.z + and r1.w, r2.w, l(1792) + iadd r1.z, r1.z, r1.w + and r1.w, r2.y, l(2) + ishr r1.x, r1.x, l(3) + iadd r1.x, r1.x, r1.w + bfi r1.x, l(2), l(6), r1.x, l(0) + iadd r1.x, r1.z, r1.x + bfi r0.y, l(6), l(0), r2.x, r1.x + endif +else + imad r1.x, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.x, CB0[0][0].z, r0.w +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.y, r0.y, l(4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r0.z, r0.z, l(1) +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +ishl r3.xyzw, r2.xyzw, l(4, 4, 4, 4) +and r3.xyzw, r3.xyzw, l(0xfff0fff0, 0xfff0fff0, 0xfff0fff0, 0xfff0fff0) +ushr r2.xyzw, r2.xyzw, l(12, 12, 12, 12) +and r2.xyzw, r2.xyzw, l(0x000f000f, 0x000f000f, 0x000f000f, 0x000f000f) +iadd r2.xyzw, r2.xyzw, r3.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r2.xyzw +iadd r0.w, r1.y, l(1) +if_nz r0.x + mov r0.x, l(64) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +ishl r3.xyzw, r2.xyzw, l(4, 4, 4, 4) +and r3.xyzw, r3.xyzw, l(0xfff0fff0, 0xfff0fff0, 0xfff0fff0, 0xfff0fff0) +ushr r2.xyzw, r2.xyzw, l(12, 12, 12, 12) +and r2.xyzw, r2.xyzw, l(0x000f000f, 0x000f000f, 0x000f000f, 0x000f000f) +iadd r2.xyzw, r2.xyzw, r3.xyzw +store_uav_typed U0[0].xyzw, r0.wwww, r2.xyzw +ret +// Approximately 106 instruction slots used +#endif + +const BYTE texture_load_r4g4b4a4_a4r4g4b4_cs[] = { + 68, 88, 66, 67, 118, 228, 49, 77, 79, 69, 118, 45, 202, 74, 186, 234, 187, 224, 119, + 75, 1, 0, 0, 0, 120, 18, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 220, 17, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 160, 13, 0, + 0, 81, 0, 5, 0, 104, 3, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 114, 0, 16, 0, 2, 0, + 0, 0, 150, 5, 2, 0, 2, 64, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 1, 0, 0, 0, + 246, 139, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 8, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 10, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 2, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, + 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 2, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, + 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 50, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 34, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, + 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 8, 66, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 10, 0, 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, + 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 19, 210, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 86, 5, 2, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 140, 0, 0, 17, 210, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 24, 0, + 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 166, 10, 16, 0, + 1, 0, 0, 0, 6, 14, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, + 7, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 35, 0, 0, 9, 18, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 30, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 21, 0, 0, 1, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, + 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 240, 255, 240, 255, 240, 255, 240, + 255, 240, 255, 240, 255, 240, 255, 240, 255, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 12, + 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 15, 0, 15, + 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 30, 0, 0, 7, 242, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, + 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, + 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 16, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, + 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, + 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, + 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 41, 0, 0, + 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 240, 255, 240, 255, 240, 255, 240, 255, 240, 255, 240, 255, 240, 255, 240, + 255, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, + 0, 15, 0, 15, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, + 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, + 0, 106, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 38, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r4g4b4a4_a4r4g4b4_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r4g4b4a4_a4r4g4b4_scaled_cs.h new file mode 100644 index 0000000..c01fddd --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r4g4b4a4_a4r4g4b4_scaled_cs.h @@ -0,0 +1,449 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(4) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(1) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(3) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r1.w, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), r1.xxxx + imad r1.w, r1.w, r3.y, r3.x + ishl r2.z, r1.z, l(9) + ishr r2.z, r2.z, l(6) + and r2.z, r2.z, l(48) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r3.xy, l(21, 21, 0, 0), l(9, 12, 0, 0), r1.wwww, l(0, 0, 0, 0) + imad r2.zw, r2.zzzz, l(0, 0, 2, 16), r3.xxxy + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 7, 10), vThreadID.zzzz, r2.zzzw + bfi r1.w, l(1), l(4), r1.z, l(0) + ubfe r3.x, l(3), l(6), r2.z + and r3.y, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.x, l(32), r0.x + imad r0.x, r3.y, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r1.wwww, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 2, 0), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.w, r3.x, r1.w, r2.z + bfi r3.xzw, l(4, 0, 4, 4), l(4, 0, 7, 6), r1.zzzz, l(0, 0, 0, 0) + bfi r3.xzw, l(24, 0, 24, 24), l(8, 0, 11, 10), r1.wwww, r3.xxzw + ishl r1.w, r1.z, l(7) + and r1.w, r1.w, l(2048) + bfi r1.w, l(12), l(0), r1.w, r3.z + and r2.z, r3.w, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.x, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].xyzw +ieq r0.y, r0.y, l(1) +if_nz r0.y + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +ishl r4.xyzw, r3.xyzw, l(4, 4, 4, 4) +and r4.xyzw, r4.xyzw, l(0xfff0fff0, 0xfff0fff0, 0xfff0fff0, 0xfff0fff0) +ushr r3.xyzw, r3.xyzw, l(12, 12, 12, 12) +and r3.xyzw, r3.xyzw, l(0x000f000f, 0x000f000f, 0x000f000f, 0x000f000f) +iadd r3.xyzw, r3.xyzw, r4.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r3.xyzw +iadd r1.x, r1.y, l(1) +ult r1.z, l(1), r0.z +if_nz r1.z + udiv r1.z, null, r2.x, r0.z + imad r1.z, -r1.z, r0.z, r2.x + iadd r1.w, r1.z, l(1) + ieq r1.w, r0.z, r1.w + if_nz r1.w + ishl r0.z, r0.z, l(6) + ishl r1.z, r1.z, l(4) + iadd r0.z, r0.z, -r1.z + else + mov r0.z, l(16) + endif +else + mov r0.z, l(64) +endif +imul null, r0.z, r0.w, r0.z +ushr r0.z, r0.z, l(4) +iadd r0.x, r0.z, r0.x +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.y + ishl r0.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r0.xyzw, r0.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r0.xyzw, r3.xyzw +endif +ishl r0.xyzw, r2.xyzw, l(4, 4, 4, 4) +and r0.xyzw, r0.xyzw, l(0xfff0fff0, 0xfff0fff0, 0xfff0fff0, 0xfff0fff0) +ushr r2.xyzw, r2.xyzw, l(12, 12, 12, 12) +and r2.xyzw, r2.xyzw, l(0x000f000f, 0x000f000f, 0x000f000f, 0x000f000f) +iadd r0.xyzw, r0.xyzw, r2.xyzw +store_uav_typed U0[0].xyzw, r1.xxxx, r0.xyzw +ret +// Approximately 119 instruction slots used +#endif + +const BYTE texture_load_r4g4b4a4_a4r4g4b4_scaled_cs[] = { + 68, 88, 66, 67, 17, 76, 236, 143, 192, 227, 93, 112, 151, 155, 84, 93, 222, 209, 136, + 217, 1, 0, 0, 0, 100, 20, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 200, 19, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 140, 15, 0, + 0, 81, 0, 5, 0, 227, 3, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 10, 194, 0, 16, 0, 2, 0, + 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, + 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, 143, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, 0, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, + 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 12, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 6, + 4, 16, 0, 3, 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 10, 0, + 0, 0, 166, 10, 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 138, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, + 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 32, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, + 0, 0, 15, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, + 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 20, 210, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 166, 10, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 140, 0, 0, 17, 210, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 246, + 15, 16, 0, 1, 0, 0, 0, 6, 14, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 7, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, + 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, + 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, + 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 6, + 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, + 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, + 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 41, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, + 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 240, + 255, 240, 255, 240, 255, 240, 255, 240, 255, 240, 255, 240, 255, 240, 255, 85, 0, 0, 10, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, + 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 78, 0, 0, 8, 66, + 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 10, 66, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 32, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, + 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 30, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 18, 0, 0, 1, 54, + 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, + 21, 0, 0, 1, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 64, 0, 0, 0, 21, 0, 0, 1, 38, 0, 0, 8, 0, 208, + 0, 0, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, + 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 6, + 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, + 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 41, 0, 0, 10, 242, + 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 240, 255, 240, 255, 240, 255, 240, 255, 240, 255, 240, 255, 240, 255, 240, 255, 85, + 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, + 0, 15, 0, 30, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 14, + 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 119, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 46, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r4g4b4a4_b4g4r4a4_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r4g4b4a4_b4g4r4a4_cs.h new file mode 100644 index 0000000..44738eb --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r4g4b4a4_b4g4r4a4_cs.h @@ -0,0 +1,421 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(4) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(1) +imad r1.y, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.y, CB0[0][2].x, r0.w +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r1.z, l(27), l(1), vThreadID.x + imad r0.y, r0.y, r1.w, r1.z + ishl r1.z, vThreadID.y, l(9) + ishr r1.z, r1.z, l(6) + and r1.z, r1.z, l(48) + iadd r1.w, r2.y, r2.z + and r2.x, r1.w, l(1) + ishr r2.y, r1.x, l(3) + bfi r1.w, l(1), l(1), r1.w, l(0) + iadd r1.w, r1.w, r2.y + bfi r1.w, l(2), l(1), r1.w, l(0) + iadd r1.w, r1.w, r2.x + bfi r2.xy, l(21, 21, 0, 0), l(9, 12, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(7, 10, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(4) + bfi r1.w, l(2), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(5, 5, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.z, l(27), l(1), vThreadID.x + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.z, r2.x, r1.w, r1.z + bfi r2.xzw, l(4, 0, 4, 4), l(4, 0, 7, 6), vThreadID.yyyy, l(0, 0, 0, 0) + bfi r2.xzw, l(24, 0, 24, 24), l(8, 0, 11, 10), r1.zzzz, r2.xxzw + ishl r1.z, vThreadID.y, l(7) + and r1.z, r1.z, l(2048) + bfi r1.z, l(12), l(0), r1.z, r2.z + and r1.w, r2.w, l(1792) + iadd r1.z, r1.z, r1.w + and r1.w, r2.y, l(2) + ishr r1.x, r1.x, l(3) + iadd r1.x, r1.x, r1.w + bfi r1.x, l(2), l(6), r1.x, l(0) + iadd r1.x, r1.z, r1.x + bfi r0.y, l(6), l(0), r2.x, r1.x + endif +else + imad r1.x, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.x, CB0[0][0].z, r0.w +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.y, r0.y, l(4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r0.z, r0.z, l(1) +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +and r3.xyzw, r2.xyzw, l(0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0) +ishl r4.xyzw, r2.xyzw, l(8, 8, 8, 8) +and r4.xyzw, r4.xyzw, l(0x0f000f00, 0x0f000f00, 0x0f000f00, 0x0f000f00) +iadd r3.xyzw, r3.xyzw, r4.xyzw +ushr r2.xyzw, r2.xyzw, l(8, 8, 8, 8) +and r2.xyzw, r2.xyzw, l(0x000f000f, 0x000f000f, 0x000f000f, 0x000f000f) +iadd r2.xyzw, r2.xyzw, r3.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r2.xyzw +iadd r0.w, r1.y, l(1) +if_nz r0.x + mov r0.x, l(64) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +and r3.xyzw, r2.xyzw, l(0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0) +ishl r4.xyzw, r2.xyzw, l(8, 8, 8, 8) +and r4.xyzw, r4.xyzw, l(0x0f000f00, 0x0f000f00, 0x0f000f00, 0x0f000f00) +iadd r3.xyzw, r3.xyzw, r4.xyzw +ushr r2.xyzw, r2.xyzw, l(8, 8, 8, 8) +and r2.xyzw, r2.xyzw, l(0x000f000f, 0x000f000f, 0x000f000f, 0x000f000f) +iadd r2.xyzw, r2.xyzw, r3.xyzw +store_uav_typed U0[0].xyzw, r0.wwww, r2.xyzw +ret +// Approximately 110 instruction slots used +#endif + +const BYTE texture_load_r4g4b4a4_b4g4r4a4_cs[] = { + 68, 88, 66, 67, 213, 238, 135, 67, 96, 108, 43, 224, 244, 162, 22, 180, 208, 186, 151, + 221, 1, 0, 0, 0, 0, 19, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 100, 18, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 40, 14, 0, + 0, 81, 0, 5, 0, 138, 3, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 114, 0, 16, 0, 2, 0, + 0, 0, 150, 5, 2, 0, 2, 64, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 1, 0, 0, 0, + 246, 139, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 8, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 10, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 2, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, + 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 2, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, + 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 50, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 34, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, + 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 8, 66, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 10, 0, 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, + 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 19, 210, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 86, 5, 2, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 140, 0, 0, 17, 210, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 24, 0, + 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 166, 10, 16, 0, + 1, 0, 0, 0, 6, 14, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, + 7, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 35, 0, 0, 9, 18, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 30, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 15, 0, 15, 0, + 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 30, 0, 0, 7, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, + 0, 15, 0, 15, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, + 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, + 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, + 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, + 1, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, + 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, + 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, + 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 41, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 15, + 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 30, 0, 0, 7, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 15, 0, 15, 0, 15, 0, 15, 0, + 15, 0, 15, 0, 15, 0, 15, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 164, 0, + 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, + 148, 0, 0, 0, 110, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 40, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r4g4b4a4_b4g4r4a4_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r4g4b4a4_b4g4r4a4_scaled_cs.h new file mode 100644 index 0000000..dd012bc --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r4g4b4a4_b4g4r4a4_scaled_cs.h @@ -0,0 +1,460 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(4) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(1) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(3) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r1.w, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), r1.xxxx + imad r1.w, r1.w, r3.y, r3.x + ishl r2.z, r1.z, l(9) + ishr r2.z, r2.z, l(6) + and r2.z, r2.z, l(48) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r3.xy, l(21, 21, 0, 0), l(9, 12, 0, 0), r1.wwww, l(0, 0, 0, 0) + imad r2.zw, r2.zzzz, l(0, 0, 2, 16), r3.xxxy + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 7, 10), vThreadID.zzzz, r2.zzzw + bfi r1.w, l(1), l(4), r1.z, l(0) + ubfe r3.x, l(3), l(6), r2.z + and r3.y, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.x, l(32), r0.x + imad r0.x, r3.y, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r1.wwww, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 2, 0), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.w, r3.x, r1.w, r2.z + bfi r3.xzw, l(4, 0, 4, 4), l(4, 0, 7, 6), r1.zzzz, l(0, 0, 0, 0) + bfi r3.xzw, l(24, 0, 24, 24), l(8, 0, 11, 10), r1.wwww, r3.xxzw + ishl r1.w, r1.z, l(7) + and r1.w, r1.w, l(2048) + bfi r1.w, l(12), l(0), r1.w, r3.z + and r2.z, r3.w, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.x, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].xyzw +ieq r0.y, r0.y, l(1) +if_nz r0.y + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +and r4.xyzw, r3.xyzw, l(0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0) +ishl r5.xyzw, r3.xyzw, l(8, 8, 8, 8) +and r5.xyzw, r5.xyzw, l(0x0f000f00, 0x0f000f00, 0x0f000f00, 0x0f000f00) +iadd r4.xyzw, r4.xyzw, r5.xyzw +ushr r3.xyzw, r3.xyzw, l(8, 8, 8, 8) +and r3.xyzw, r3.xyzw, l(0x000f000f, 0x000f000f, 0x000f000f, 0x000f000f) +iadd r3.xyzw, r3.xyzw, r4.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r3.xyzw +iadd r1.x, r1.y, l(1) +ult r1.z, l(1), r0.z +if_nz r1.z + udiv r1.z, null, r2.x, r0.z + imad r1.z, -r1.z, r0.z, r2.x + iadd r1.w, r1.z, l(1) + ieq r1.w, r0.z, r1.w + if_nz r1.w + ishl r0.z, r0.z, l(6) + ishl r1.z, r1.z, l(4) + iadd r0.z, r0.z, -r1.z + else + mov r0.z, l(16) + endif +else + mov r0.z, l(64) +endif +imul null, r0.z, r0.w, r0.z +ushr r0.z, r0.z, l(4) +iadd r0.x, r0.z, r0.x +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.y + ishl r0.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r0.xyzw, r0.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r0.xyzw, r3.xyzw +endif +and r0.xyzw, r2.xyzw, l(0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0, 0xf0f0f0f0) +ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) +and r3.xyzw, r3.xyzw, l(0x0f000f00, 0x0f000f00, 0x0f000f00, 0x0f000f00) +iadd r0.xyzw, r0.xyzw, r3.xyzw +ushr r2.xyzw, r2.xyzw, l(8, 8, 8, 8) +and r2.xyzw, r2.xyzw, l(0x000f000f, 0x000f000f, 0x000f000f, 0x000f000f) +iadd r0.xyzw, r0.xyzw, r2.xyzw +store_uav_typed U0[0].xyzw, r1.xxxx, r0.xyzw +ret +// Approximately 123 instruction slots used +#endif + +const BYTE texture_load_r4g4b4a4_b4g4r4a4_scaled_cs[] = { + 68, 88, 66, 67, 20, 84, 165, 228, 30, 88, 37, 157, 197, 152, 210, 234, 235, 7, 114, + 150, 1, 0, 0, 0, 236, 20, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 80, 20, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 20, 16, 0, + 0, 81, 0, 5, 0, 5, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 10, 194, 0, 16, 0, 2, 0, + 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, + 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, 143, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, 0, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, + 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 12, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 6, + 4, 16, 0, 3, 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 10, 0, + 0, 0, 166, 10, 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 138, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, + 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 32, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, + 0, 0, 15, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, + 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 20, 210, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 166, 10, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 140, 0, 0, 17, 210, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 246, + 15, 16, 0, 1, 0, 0, 0, 6, 14, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 7, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, + 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, + 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, + 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 6, + 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, + 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, + 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 41, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 30, 0, + 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 15, 0, 15, 0, 15, + 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, + 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, + 16, 0, 1, 0, 0, 0, 78, 0, 0, 8, 66, 0, 16, 0, 1, 0, 0, 0, 0, + 208, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 35, 0, 0, 10, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 128, 65, 0, 0, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 8, 66, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 65, 0, + 0, 0, 1, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, + 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, + 0, 21, 0, 0, 1, 38, 0, 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 85, + 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 45, 0, + 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, + 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, + 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 15, 0, 15, + 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 30, 0, 0, 7, 242, 0, 16, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, + 15, 0, 15, 0, 15, 0, 30, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 164, 0, 0, 8, + 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, + 0, 0, 123, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 48, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r5g5b5a1_b5g5r5a1_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r5g5b5a1_b5g5r5a1_cs.h new file mode 100644 index 0000000..909de85 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r5g5b5a1_b5g5r5a1_cs.h @@ -0,0 +1,421 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(4) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(1) +imad r1.y, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.y, CB0[0][2].x, r0.w +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r1.z, l(27), l(1), vThreadID.x + imad r0.y, r0.y, r1.w, r1.z + ishl r1.z, vThreadID.y, l(9) + ishr r1.z, r1.z, l(6) + and r1.z, r1.z, l(48) + iadd r1.w, r2.y, r2.z + and r2.x, r1.w, l(1) + ishr r2.y, r1.x, l(3) + bfi r1.w, l(1), l(1), r1.w, l(0) + iadd r1.w, r1.w, r2.y + bfi r1.w, l(2), l(1), r1.w, l(0) + iadd r1.w, r1.w, r2.x + bfi r2.xy, l(21, 21, 0, 0), l(9, 12, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(7, 10, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(4) + bfi r1.w, l(2), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(5, 5, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.z, l(27), l(1), vThreadID.x + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.z, r2.x, r1.w, r1.z + bfi r2.xzw, l(4, 0, 4, 4), l(4, 0, 7, 6), vThreadID.yyyy, l(0, 0, 0, 0) + bfi r2.xzw, l(24, 0, 24, 24), l(8, 0, 11, 10), r1.zzzz, r2.xxzw + ishl r1.z, vThreadID.y, l(7) + and r1.z, r1.z, l(2048) + bfi r1.z, l(12), l(0), r1.z, r2.z + and r1.w, r2.w, l(1792) + iadd r1.z, r1.z, r1.w + and r1.w, r2.y, l(2) + ishr r1.x, r1.x, l(3) + iadd r1.x, r1.x, r1.w + bfi r1.x, l(2), l(6), r1.x, l(0) + iadd r1.x, r1.z, r1.x + bfi r0.y, l(6), l(0), r2.x, r1.x + endif +else + imad r1.x, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.x, CB0[0][0].z, r0.w +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.y, r0.y, l(4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r0.z, r0.z, l(1) +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +and r3.xyzw, r2.xyzw, l(0x83e083e0, 0x83e083e0, 0x83e083e0, 0x83e083e0) +ishl r4.xyzw, r2.xyzw, l(10, 10, 10, 10) +and r4.xyzw, r4.xyzw, l(0x7c007c00, 0x7c007c00, 0x7c007c00, 0x7c007c00) +iadd r3.xyzw, r3.xyzw, r4.xyzw +ushr r2.xyzw, r2.xyzw, l(10, 10, 10, 10) +and r2.xyzw, r2.xyzw, l(0x001f001f, 0x001f001f, 0x001f001f, 0x001f001f) +iadd r2.xyzw, r2.xyzw, r3.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r2.xyzw +iadd r0.w, r1.y, l(1) +if_nz r0.x + mov r0.x, l(64) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +and r3.xyzw, r2.xyzw, l(0x83e083e0, 0x83e083e0, 0x83e083e0, 0x83e083e0) +ishl r4.xyzw, r2.xyzw, l(10, 10, 10, 10) +and r4.xyzw, r4.xyzw, l(0x7c007c00, 0x7c007c00, 0x7c007c00, 0x7c007c00) +iadd r3.xyzw, r3.xyzw, r4.xyzw +ushr r2.xyzw, r2.xyzw, l(10, 10, 10, 10) +and r2.xyzw, r2.xyzw, l(0x001f001f, 0x001f001f, 0x001f001f, 0x001f001f) +iadd r2.xyzw, r2.xyzw, r3.xyzw +store_uav_typed U0[0].xyzw, r0.wwww, r2.xyzw +ret +// Approximately 110 instruction slots used +#endif + +const BYTE texture_load_r5g5b5a1_b5g5r5a1_cs[] = { + 68, 88, 66, 67, 90, 178, 91, 211, 80, 195, 171, 57, 69, 56, 82, 164, 142, 245, 95, + 251, 1, 0, 0, 0, 0, 19, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 100, 18, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 40, 14, 0, + 0, 81, 0, 5, 0, 138, 3, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 114, 0, 16, 0, 2, 0, + 0, 0, 150, 5, 2, 0, 2, 64, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 1, 0, 0, 0, + 246, 139, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 8, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 10, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 2, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, + 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 2, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, + 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 50, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 34, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, + 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 8, 66, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 10, 0, 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, + 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 19, 210, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 86, 5, 2, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 140, 0, 0, 17, 210, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 24, 0, + 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 166, 10, 16, 0, + 1, 0, 0, 0, 6, 14, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, + 7, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 35, 0, 0, 9, 18, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 30, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 224, 131, 224, 131, 224, 131, 224, 131, 224, + 131, 224, 131, 224, 131, 224, 131, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 124, 0, 124, 0, + 124, 0, 124, 0, 124, 0, 124, 0, 124, 0, 124, 30, 0, 0, 7, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 31, 0, 31, 0, 31, 0, 31, 0, 31, 0, 31, + 0, 31, 0, 31, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, + 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, + 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, + 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, + 1, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, + 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, + 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, + 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 224, 131, 224, 131, 224, 131, + 224, 131, 224, 131, 224, 131, 224, 131, 224, 131, 41, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, + 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 124, + 0, 124, 0, 124, 0, 124, 0, 124, 0, 124, 0, 124, 0, 124, 30, 0, 0, 7, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 10, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 31, 0, 31, 0, 31, 0, 31, 0, + 31, 0, 31, 0, 31, 0, 31, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 164, 0, + 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, + 148, 0, 0, 0, 110, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 40, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r5g5b5a1_b5g5r5a1_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r5g5b5a1_b5g5r5a1_scaled_cs.h new file mode 100644 index 0000000..76374f4 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r5g5b5a1_b5g5r5a1_scaled_cs.h @@ -0,0 +1,460 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(4) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(1) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(3) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r1.w, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), r1.xxxx + imad r1.w, r1.w, r3.y, r3.x + ishl r2.z, r1.z, l(9) + ishr r2.z, r2.z, l(6) + and r2.z, r2.z, l(48) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r3.xy, l(21, 21, 0, 0), l(9, 12, 0, 0), r1.wwww, l(0, 0, 0, 0) + imad r2.zw, r2.zzzz, l(0, 0, 2, 16), r3.xxxy + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 7, 10), vThreadID.zzzz, r2.zzzw + bfi r1.w, l(1), l(4), r1.z, l(0) + ubfe r3.x, l(3), l(6), r2.z + and r3.y, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.x, l(32), r0.x + imad r0.x, r3.y, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r1.wwww, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 2, 0), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.w, r3.x, r1.w, r2.z + bfi r3.xzw, l(4, 0, 4, 4), l(4, 0, 7, 6), r1.zzzz, l(0, 0, 0, 0) + bfi r3.xzw, l(24, 0, 24, 24), l(8, 0, 11, 10), r1.wwww, r3.xxzw + ishl r1.w, r1.z, l(7) + and r1.w, r1.w, l(2048) + bfi r1.w, l(12), l(0), r1.w, r3.z + and r2.z, r3.w, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.x, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].xyzw +ieq r0.y, r0.y, l(1) +if_nz r0.y + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +and r4.xyzw, r3.xyzw, l(0x83e083e0, 0x83e083e0, 0x83e083e0, 0x83e083e0) +ishl r5.xyzw, r3.xyzw, l(10, 10, 10, 10) +and r5.xyzw, r5.xyzw, l(0x7c007c00, 0x7c007c00, 0x7c007c00, 0x7c007c00) +iadd r4.xyzw, r4.xyzw, r5.xyzw +ushr r3.xyzw, r3.xyzw, l(10, 10, 10, 10) +and r3.xyzw, r3.xyzw, l(0x001f001f, 0x001f001f, 0x001f001f, 0x001f001f) +iadd r3.xyzw, r3.xyzw, r4.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r3.xyzw +iadd r1.x, r1.y, l(1) +ult r1.z, l(1), r0.z +if_nz r1.z + udiv r1.z, null, r2.x, r0.z + imad r1.z, -r1.z, r0.z, r2.x + iadd r1.w, r1.z, l(1) + ieq r1.w, r0.z, r1.w + if_nz r1.w + ishl r0.z, r0.z, l(6) + ishl r1.z, r1.z, l(4) + iadd r0.z, r0.z, -r1.z + else + mov r0.z, l(16) + endif +else + mov r0.z, l(64) +endif +imul null, r0.z, r0.w, r0.z +ushr r0.z, r0.z, l(4) +iadd r0.x, r0.z, r0.x +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.y + ishl r0.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r0.xyzw, r0.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r0.xyzw, r3.xyzw +endif +and r0.xyzw, r2.xyzw, l(0x83e083e0, 0x83e083e0, 0x83e083e0, 0x83e083e0) +ishl r3.xyzw, r2.xyzw, l(10, 10, 10, 10) +and r3.xyzw, r3.xyzw, l(0x7c007c00, 0x7c007c00, 0x7c007c00, 0x7c007c00) +iadd r0.xyzw, r0.xyzw, r3.xyzw +ushr r2.xyzw, r2.xyzw, l(10, 10, 10, 10) +and r2.xyzw, r2.xyzw, l(0x001f001f, 0x001f001f, 0x001f001f, 0x001f001f) +iadd r0.xyzw, r0.xyzw, r2.xyzw +store_uav_typed U0[0].xyzw, r1.xxxx, r0.xyzw +ret +// Approximately 123 instruction slots used +#endif + +const BYTE texture_load_r5g5b5a1_b5g5r5a1_scaled_cs[] = { + 68, 88, 66, 67, 233, 4, 84, 54, 105, 50, 30, 76, 219, 249, 131, 70, 131, 15, 195, + 34, 1, 0, 0, 0, 236, 20, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 80, 20, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 20, 16, 0, + 0, 81, 0, 5, 0, 5, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 10, 194, 0, 16, 0, 2, 0, + 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, + 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, 143, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, 0, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, + 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 12, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 6, + 4, 16, 0, 3, 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 10, 0, + 0, 0, 166, 10, 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 138, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, + 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 32, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, + 0, 0, 15, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, + 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 20, 210, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 166, 10, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 140, 0, 0, 17, 210, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 246, + 15, 16, 0, 1, 0, 0, 0, 6, 14, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 7, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, + 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, + 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, + 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 6, + 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, + 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, + 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 224, 131, 224, + 131, 224, 131, 224, 131, 224, 131, 224, 131, 224, 131, 224, 131, 41, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 10, + 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 124, 0, 124, 0, 124, 0, 124, 0, 124, 0, 124, 0, 124, 0, 124, 30, 0, + 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 10, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 31, 0, 31, 0, 31, + 0, 31, 0, 31, 0, 31, 0, 31, 0, 31, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, + 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, + 16, 0, 1, 0, 0, 0, 78, 0, 0, 8, 66, 0, 16, 0, 1, 0, 0, 0, 0, + 208, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 35, 0, 0, 10, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 128, 65, 0, 0, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 8, 66, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 65, 0, + 0, 0, 1, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, + 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, + 0, 21, 0, 0, 1, 38, 0, 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 85, + 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 45, 0, + 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, + 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, + 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 224, 131, 224, 131, 224, 131, 224, 131, + 224, 131, 224, 131, 224, 131, 224, 131, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, + 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 124, 0, 124, + 0, 124, 0, 124, 0, 124, 0, 124, 0, 124, 0, 124, 30, 0, 0, 7, 242, 0, 16, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, + 10, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 31, 0, 31, 0, 31, 0, 31, 0, 31, 0, + 31, 0, 31, 0, 31, 0, 30, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 164, 0, 0, 8, + 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, + 0, 0, 123, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 48, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r5g5b6_b5g6r5_swizzle_rbga_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r5g5b6_b5g6r5_swizzle_rbga_cs.h new file mode 100644 index 0000000..078f27e --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r5g5b6_b5g6r5_swizzle_rbga_cs.h @@ -0,0 +1,410 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(4) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(1) +imad r1.y, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.y, CB0[0][2].x, r0.w +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r1.z, l(27), l(1), vThreadID.x + imad r0.y, r0.y, r1.w, r1.z + ishl r1.z, vThreadID.y, l(9) + ishr r1.z, r1.z, l(6) + and r1.z, r1.z, l(48) + iadd r1.w, r2.y, r2.z + and r2.x, r1.w, l(1) + ishr r2.y, r1.x, l(3) + bfi r1.w, l(1), l(1), r1.w, l(0) + iadd r1.w, r1.w, r2.y + bfi r1.w, l(2), l(1), r1.w, l(0) + iadd r1.w, r1.w, r2.x + bfi r2.xy, l(21, 21, 0, 0), l(9, 12, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(7, 10, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(4) + bfi r1.w, l(2), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(5, 5, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.z, l(27), l(1), vThreadID.x + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.z, r2.x, r1.w, r1.z + bfi r2.xzw, l(4, 0, 4, 4), l(4, 0, 7, 6), vThreadID.yyyy, l(0, 0, 0, 0) + bfi r2.xzw, l(24, 0, 24, 24), l(8, 0, 11, 10), r1.zzzz, r2.xxzw + ishl r1.z, vThreadID.y, l(7) + and r1.z, r1.z, l(2048) + bfi r1.z, l(12), l(0), r1.z, r2.z + and r1.w, r2.w, l(1792) + iadd r1.z, r1.z, r1.w + and r1.w, r2.y, l(2) + ishr r1.x, r1.x, l(3) + iadd r1.x, r1.x, r1.w + bfi r1.x, l(2), l(6), r1.x, l(0) + iadd r1.x, r1.z, r1.x + bfi r0.y, l(6), l(0), r2.x, r1.x + endif +else + imad r1.x, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.x, CB0[0][0].z, r0.w +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.y, r0.y, l(4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r0.z, r0.z, l(1) +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +ishl r3.xyzw, r2.xyzw, l(11, 11, 11, 11) +and r3.xyzw, r3.xyzw, l(0xf800f800, 0xf800f800, 0xf800f800, 0xf800f800) +ushr r2.xyzw, r2.xyzw, l(5, 5, 5, 5) +and r2.xyzw, r2.xyzw, l(0x07ff07ff, 0x07ff07ff, 0x07ff07ff, 0x07ff07ff) +iadd r2.xyzw, r2.xyzw, r3.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r2.xyzw +iadd r0.w, r1.y, l(1) +if_nz r0.x + mov r0.x, l(64) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +ishl r3.xyzw, r2.xyzw, l(11, 11, 11, 11) +and r3.xyzw, r3.xyzw, l(0xf800f800, 0xf800f800, 0xf800f800, 0xf800f800) +ushr r2.xyzw, r2.xyzw, l(5, 5, 5, 5) +and r2.xyzw, r2.xyzw, l(0x07ff07ff, 0x07ff07ff, 0x07ff07ff, 0x07ff07ff) +iadd r2.xyzw, r2.xyzw, r3.xyzw +store_uav_typed U0[0].xyzw, r0.wwww, r2.xyzw +ret +// Approximately 106 instruction slots used +#endif + +const BYTE texture_load_r5g5b6_b5g6r5_swizzle_rbga_cs[] = { + 68, 88, 66, 67, 202, 164, 170, 174, 93, 200, 186, 29, 32, 41, 245, 108, 163, 179, 215, + 250, 1, 0, 0, 0, 120, 18, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 220, 17, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 160, 13, 0, + 0, 81, 0, 5, 0, 104, 3, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 114, 0, 16, 0, 2, 0, + 0, 0, 150, 5, 2, 0, 2, 64, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 1, 0, 0, 0, + 246, 139, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 8, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 10, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 2, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, + 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 2, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, + 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 50, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 34, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, + 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 8, 66, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 10, 0, 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, + 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 19, 210, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 86, 5, 2, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 140, 0, 0, 17, 210, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 24, 0, + 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 166, 10, 16, 0, + 1, 0, 0, 0, 6, 14, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, + 7, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 35, 0, 0, 9, 18, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 30, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 21, 0, 0, 1, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11, + 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 248, 0, 248, 0, 248, 0, + 248, 0, 248, 0, 248, 0, 248, 0, 248, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 7, 255, + 7, 255, 7, 255, 7, 255, 7, 255, 7, 255, 7, 255, 7, 30, 0, 0, 7, 242, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, + 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 54, + 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, + 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 16, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, + 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, + 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, + 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 41, 0, 0, + 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, + 248, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 255, 7, 255, 7, 255, 7, 255, 7, 255, 7, 255, + 7, 255, 7, 255, 7, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, + 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, + 0, 106, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 38, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r5g5b6_b5g6r5_swizzle_rbga_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r5g5b6_b5g6r5_swizzle_rbga_scaled_cs.h new file mode 100644 index 0000000..686288e --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r5g5b6_b5g6r5_swizzle_rbga_scaled_cs.h @@ -0,0 +1,449 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(4) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(1) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(3) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r1.w, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), r1.xxxx + imad r1.w, r1.w, r3.y, r3.x + ishl r2.z, r1.z, l(9) + ishr r2.z, r2.z, l(6) + and r2.z, r2.z, l(48) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r3.xy, l(21, 21, 0, 0), l(9, 12, 0, 0), r1.wwww, l(0, 0, 0, 0) + imad r2.zw, r2.zzzz, l(0, 0, 2, 16), r3.xxxy + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 7, 10), vThreadID.zzzz, r2.zzzw + bfi r1.w, l(1), l(4), r1.z, l(0) + ubfe r3.x, l(3), l(6), r2.z + and r3.y, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.x, l(32), r0.x + imad r0.x, r3.y, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r1.wwww, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 2, 0), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.w, r3.x, r1.w, r2.z + bfi r3.xzw, l(4, 0, 4, 4), l(4, 0, 7, 6), r1.zzzz, l(0, 0, 0, 0) + bfi r3.xzw, l(24, 0, 24, 24), l(8, 0, 11, 10), r1.wwww, r3.xxzw + ishl r1.w, r1.z, l(7) + and r1.w, r1.w, l(2048) + bfi r1.w, l(12), l(0), r1.w, r3.z + and r2.z, r3.w, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.x, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].xyzw +ieq r0.y, r0.y, l(1) +if_nz r0.y + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +ishl r4.xyzw, r3.xyzw, l(11, 11, 11, 11) +and r4.xyzw, r4.xyzw, l(0xf800f800, 0xf800f800, 0xf800f800, 0xf800f800) +ushr r3.xyzw, r3.xyzw, l(5, 5, 5, 5) +and r3.xyzw, r3.xyzw, l(0x07ff07ff, 0x07ff07ff, 0x07ff07ff, 0x07ff07ff) +iadd r3.xyzw, r3.xyzw, r4.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r3.xyzw +iadd r1.x, r1.y, l(1) +ult r1.z, l(1), r0.z +if_nz r1.z + udiv r1.z, null, r2.x, r0.z + imad r1.z, -r1.z, r0.z, r2.x + iadd r1.w, r1.z, l(1) + ieq r1.w, r0.z, r1.w + if_nz r1.w + ishl r0.z, r0.z, l(6) + ishl r1.z, r1.z, l(4) + iadd r0.z, r0.z, -r1.z + else + mov r0.z, l(16) + endif +else + mov r0.z, l(64) +endif +imul null, r0.z, r0.w, r0.z +ushr r0.z, r0.z, l(4) +iadd r0.x, r0.z, r0.x +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.y + ishl r0.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r0.xyzw, r0.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r0.xyzw, r3.xyzw +endif +ishl r0.xyzw, r2.xyzw, l(11, 11, 11, 11) +and r0.xyzw, r0.xyzw, l(0xf800f800, 0xf800f800, 0xf800f800, 0xf800f800) +ushr r2.xyzw, r2.xyzw, l(5, 5, 5, 5) +and r2.xyzw, r2.xyzw, l(0x07ff07ff, 0x07ff07ff, 0x07ff07ff, 0x07ff07ff) +iadd r0.xyzw, r0.xyzw, r2.xyzw +store_uav_typed U0[0].xyzw, r1.xxxx, r0.xyzw +ret +// Approximately 119 instruction slots used +#endif + +const BYTE texture_load_r5g5b6_b5g6r5_swizzle_rbga_scaled_cs[] = { + 68, 88, 66, 67, 133, 237, 121, 51, 84, 78, 25, 47, 124, 230, 127, 77, 30, 88, 101, + 126, 1, 0, 0, 0, 100, 20, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 200, 19, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 140, 15, 0, + 0, 81, 0, 5, 0, 227, 3, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 10, 194, 0, 16, 0, 2, 0, + 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, + 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, 143, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, 0, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, + 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 12, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 6, + 4, 16, 0, 3, 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 10, 0, + 0, 0, 166, 10, 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 138, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, + 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 32, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, + 0, 0, 15, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, + 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 20, 210, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 166, 10, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 140, 0, 0, 17, 210, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 246, + 15, 16, 0, 1, 0, 0, 0, 6, 14, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 7, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, + 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, + 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, + 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 6, + 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, + 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, + 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 41, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, + 0, 11, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 85, 0, 0, 10, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 255, 7, 255, 7, 255, 7, 255, 7, 255, 7, 255, 7, 255, 7, 255, 7, + 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 78, 0, 0, 8, 66, + 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 10, 66, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 32, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, + 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 30, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 18, 0, 0, 1, 54, + 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, + 21, 0, 0, 1, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 64, 0, 0, 0, 21, 0, 0, 1, 38, 0, 0, 8, 0, 208, + 0, 0, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, + 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 6, + 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, + 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 41, 0, 0, 10, 242, + 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 11, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, + 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 85, + 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, + 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 255, 7, 255, 7, 255, 7, 255, 7, 255, 7, 255, 7, 255, + 7, 255, 7, 30, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 14, + 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 119, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 46, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r5g6b5_b5g6r5_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r5g6b5_b5g6r5_cs.h new file mode 100644 index 0000000..dcee9d6 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r5g6b5_b5g6r5_cs.h @@ -0,0 +1,421 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(4) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(1) +imad r1.y, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.y, CB0[0][2].x, r0.w +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r1.z, l(27), l(1), vThreadID.x + imad r0.y, r0.y, r1.w, r1.z + ishl r1.z, vThreadID.y, l(9) + ishr r1.z, r1.z, l(6) + and r1.z, r1.z, l(48) + iadd r1.w, r2.y, r2.z + and r2.x, r1.w, l(1) + ishr r2.y, r1.x, l(3) + bfi r1.w, l(1), l(1), r1.w, l(0) + iadd r1.w, r1.w, r2.y + bfi r1.w, l(2), l(1), r1.w, l(0) + iadd r1.w, r1.w, r2.x + bfi r2.xy, l(21, 21, 0, 0), l(9, 12, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(7, 10, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(4) + bfi r1.w, l(2), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(5, 5, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.z, l(27), l(1), vThreadID.x + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.z, r2.x, r1.w, r1.z + bfi r2.xzw, l(4, 0, 4, 4), l(4, 0, 7, 6), vThreadID.yyyy, l(0, 0, 0, 0) + bfi r2.xzw, l(24, 0, 24, 24), l(8, 0, 11, 10), r1.zzzz, r2.xxzw + ishl r1.z, vThreadID.y, l(7) + and r1.z, r1.z, l(2048) + bfi r1.z, l(12), l(0), r1.z, r2.z + and r1.w, r2.w, l(1792) + iadd r1.z, r1.z, r1.w + and r1.w, r2.y, l(2) + ishr r1.x, r1.x, l(3) + iadd r1.x, r1.x, r1.w + bfi r1.x, l(2), l(6), r1.x, l(0) + iadd r1.x, r1.z, r1.x + bfi r0.y, l(6), l(0), r2.x, r1.x + endif +else + imad r1.x, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.x, CB0[0][0].z, r0.w +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.y, r0.y, l(4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r0.z, r0.z, l(1) +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +and r3.xyzw, r2.xyzw, l(0x07e007e0, 0x07e007e0, 0x07e007e0, 0x07e007e0) +ishl r4.xyzw, r2.xyzw, l(11, 11, 11, 11) +and r4.xyzw, r4.xyzw, l(0xf800f800, 0xf800f800, 0xf800f800, 0xf800f800) +iadd r3.xyzw, r3.xyzw, r4.xyzw +ushr r2.xyzw, r2.xyzw, l(11, 11, 11, 11) +and r2.xyzw, r2.xyzw, l(0x001f001f, 0x001f001f, 0x001f001f, 0x001f001f) +iadd r2.xyzw, r2.xyzw, r3.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r2.xyzw +iadd r0.w, r1.y, l(1) +if_nz r0.x + mov r0.x, l(64) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +and r3.xyzw, r2.xyzw, l(0x07e007e0, 0x07e007e0, 0x07e007e0, 0x07e007e0) +ishl r4.xyzw, r2.xyzw, l(11, 11, 11, 11) +and r4.xyzw, r4.xyzw, l(0xf800f800, 0xf800f800, 0xf800f800, 0xf800f800) +iadd r3.xyzw, r3.xyzw, r4.xyzw +ushr r2.xyzw, r2.xyzw, l(11, 11, 11, 11) +and r2.xyzw, r2.xyzw, l(0x001f001f, 0x001f001f, 0x001f001f, 0x001f001f) +iadd r2.xyzw, r2.xyzw, r3.xyzw +store_uav_typed U0[0].xyzw, r0.wwww, r2.xyzw +ret +// Approximately 110 instruction slots used +#endif + +const BYTE texture_load_r5g6b5_b5g6r5_cs[] = { + 68, 88, 66, 67, 193, 120, 96, 202, 31, 141, 55, 92, 145, 4, 113, 224, 20, 3, 206, + 2, 1, 0, 0, 0, 0, 19, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 100, 18, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 40, 14, 0, + 0, 81, 0, 5, 0, 138, 3, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 114, 0, 16, 0, 2, 0, + 0, 0, 150, 5, 2, 0, 2, 64, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 1, 0, 0, 0, + 246, 139, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 8, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 10, 0, 2, 0, 35, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 2, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, + 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, + 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 2, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, + 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 50, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 34, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, 9, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, + 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 8, 66, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 10, 0, 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, + 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, + 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 19, 210, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 86, 5, 2, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 140, 0, 0, 17, 210, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 24, 0, + 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 166, 10, 16, 0, + 1, 0, 0, 0, 6, 14, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, + 7, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 140, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 35, 0, 0, 9, 18, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 30, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, + 86, 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, + 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 224, 7, 224, 7, 224, 7, 224, 7, 224, + 7, 224, 7, 224, 7, 224, 7, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 11, 0, 0, + 0, 11, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 248, 0, 248, 0, + 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 30, 0, 0, 7, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 31, 0, 31, 0, 31, 0, 31, 0, 31, 0, 31, + 0, 31, 0, 31, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, + 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, + 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, + 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, + 1, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, + 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, + 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, + 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 224, 7, 224, 7, 224, 7, + 224, 7, 224, 7, 224, 7, 224, 7, 224, 7, 41, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, + 11, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, + 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 248, + 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 30, 0, 0, 7, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11, 0, + 0, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 31, 0, 31, 0, 31, 0, 31, 0, + 31, 0, 31, 0, 31, 0, 31, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 164, 0, + 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, + 148, 0, 0, 0, 110, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 40, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r5g6b5_b5g6r5_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r5g6b5_b5g6r5_scaled_cs.h new file mode 100644 index 0000000..ef0da41 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_r5g6b5_b5g6r5_scaled_cs.h @@ -0,0 +1,460 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(4) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(1) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(3) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r1.w, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), r1.xxxx + imad r1.w, r1.w, r3.y, r3.x + ishl r2.z, r1.z, l(9) + ishr r2.z, r2.z, l(6) + and r2.z, r2.z, l(48) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r3.xy, l(21, 21, 0, 0), l(9, 12, 0, 0), r1.wwww, l(0, 0, 0, 0) + imad r2.zw, r2.zzzz, l(0, 0, 2, 16), r3.xxxy + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 7, 10), vThreadID.zzzz, r2.zzzw + bfi r1.w, l(1), l(4), r1.z, l(0) + ubfe r3.x, l(3), l(6), r2.z + and r3.y, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.x, l(32), r0.x + imad r0.x, r3.y, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r1.wwww, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 2, 0), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.w, r3.x, r1.w, r2.z + bfi r3.xzw, l(4, 0, 4, 4), l(4, 0, 7, 6), r1.zzzz, l(0, 0, 0, 0) + bfi r3.xzw, l(24, 0, 24, 24), l(8, 0, 11, 10), r1.wwww, r3.xxzw + ishl r1.w, r1.z, l(7) + and r1.w, r1.w, l(2048) + bfi r1.w, l(12), l(0), r1.w, r3.z + and r2.z, r3.w, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.x, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].xyzw +ieq r0.y, r0.y, l(1) +if_nz r0.y + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +and r4.xyzw, r3.xyzw, l(0x07e007e0, 0x07e007e0, 0x07e007e0, 0x07e007e0) +ishl r5.xyzw, r3.xyzw, l(11, 11, 11, 11) +and r5.xyzw, r5.xyzw, l(0xf800f800, 0xf800f800, 0xf800f800, 0xf800f800) +iadd r4.xyzw, r4.xyzw, r5.xyzw +ushr r3.xyzw, r3.xyzw, l(11, 11, 11, 11) +and r3.xyzw, r3.xyzw, l(0x001f001f, 0x001f001f, 0x001f001f, 0x001f001f) +iadd r3.xyzw, r3.xyzw, r4.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r3.xyzw +iadd r1.x, r1.y, l(1) +ult r1.z, l(1), r0.z +if_nz r1.z + udiv r1.z, null, r2.x, r0.z + imad r1.z, -r1.z, r0.z, r2.x + iadd r1.w, r1.z, l(1) + ieq r1.w, r0.z, r1.w + if_nz r1.w + ishl r0.z, r0.z, l(6) + ishl r1.z, r1.z, l(4) + iadd r0.z, r0.z, -r1.z + else + mov r0.z, l(16) + endif +else + mov r0.z, l(64) +endif +imul null, r0.z, r0.w, r0.z +ushr r0.z, r0.z, l(4) +iadd r0.x, r0.z, r0.x +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.y + ishl r0.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r0.xyzw, r0.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r0.xyzw, r3.xyzw +endif +and r0.xyzw, r2.xyzw, l(0x07e007e0, 0x07e007e0, 0x07e007e0, 0x07e007e0) +ishl r3.xyzw, r2.xyzw, l(11, 11, 11, 11) +and r3.xyzw, r3.xyzw, l(0xf800f800, 0xf800f800, 0xf800f800, 0xf800f800) +iadd r0.xyzw, r0.xyzw, r3.xyzw +ushr r2.xyzw, r2.xyzw, l(11, 11, 11, 11) +and r2.xyzw, r2.xyzw, l(0x001f001f, 0x001f001f, 0x001f001f, 0x001f001f) +iadd r0.xyzw, r0.xyzw, r2.xyzw +store_uav_typed U0[0].xyzw, r1.xxxx, r0.xyzw +ret +// Approximately 123 instruction slots used +#endif + +const BYTE texture_load_r5g6b5_b5g6r5_scaled_cs[] = { + 68, 88, 66, 67, 156, 154, 161, 151, 238, 179, 29, 247, 212, 197, 8, 117, 107, 6, 95, + 177, 1, 0, 0, 0, 236, 20, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 80, 20, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 20, 16, 0, + 0, 81, 0, 5, 0, 5, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 10, 194, 0, 16, 0, 2, 0, + 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, + 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, 143, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, + 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, 0, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, + 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 50, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 12, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 6, + 4, 16, 0, 3, 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 10, 0, + 0, 0, 166, 10, 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 138, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, + 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 32, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, + 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, + 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, + 0, 0, 15, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, + 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 20, 210, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 166, 10, 16, 0, 1, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 140, 0, 0, 17, 210, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 246, + 15, 16, 0, 1, 0, 0, 0, 6, 14, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 7, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, + 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, + 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, + 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, 0, 16, 0, 1, 0, 0, 0, 6, 2, + 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 6, + 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, + 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, + 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 224, 7, 224, + 7, 224, 7, 224, 7, 224, 7, 224, 7, 224, 7, 224, 7, 41, 0, 0, 10, 242, 0, + 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 11, + 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, + 0, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 30, 0, + 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 5, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 11, 0, 0, + 0, 11, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 31, 0, 31, 0, 31, + 0, 31, 0, 31, 0, 31, 0, 31, 0, 31, 0, 30, 0, 0, 7, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, + 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, + 16, 0, 1, 0, 0, 0, 78, 0, 0, 8, 66, 0, 16, 0, 1, 0, 0, 0, 0, + 208, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 35, 0, 0, 10, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 128, 65, 0, 0, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 8, 66, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 65, 0, + 0, 0, 1, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, + 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, + 0, 21, 0, 0, 1, 38, 0, 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 85, + 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 45, 0, + 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, + 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, + 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 224, 7, 224, 7, 224, 7, 224, 7, + 224, 7, 224, 7, 224, 7, 224, 7, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 11, 0, + 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 248, 0, 248, + 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 0, 248, 30, 0, 0, 7, 242, 0, 16, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, + 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 31, 0, 31, 0, 31, 0, 31, 0, 31, 0, + 31, 0, 31, 0, 31, 0, 30, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 164, 0, 0, 8, + 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, + 0, 0, 123, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 48, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rg16_snorm_float_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rg16_snorm_float_cs.h new file mode 100644 index 0000000..5e08a23 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rg16_snorm_float_cs.h @@ -0,0 +1,475 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(2) +imad r1.x, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.x, r1.x, CB0[0][2].x, r0.w +iadd r1.x, r1.x, CB0[0][1].w +ushr r1.x, r1.x, l(4) +if_nz r0.x + if_nz r0.y + ishr r1.yzw, vThreadID.yyzy, l(0, 4, 2, 3) + ushr r2.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r0.y, r1.z, r2.x, r1.y + ibfe r2.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), vThreadID.xxxx + imad r0.y, r0.y, r2.y, r2.x + ishl r1.y, vThreadID.y, l(10) + ishr r1.y, r1.y, l(6) + and r1.y, r1.y, l(96) + iadd r1.z, r1.z, r1.w + bfi r1.w, l(1), l(1), r1.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r1.w, l(2), l(1), r1.w, l(0) + bfi r1.z, l(1), l(0), r1.z, r1.w + bfi r2.xy, l(20, 20, 0, 0), l(10, 13, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r1.yw, r1.yyyy, l(0, 2, 0, 16), r2.xxxy + bfi r1.yw, l(0, 2, 0, 2), l(0, 8, 0, 11), vThreadID.zzzz, r1.yyyw + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r2.x, l(3), l(6), r1.y + and r2.y, r1.z, l(6) + bfi r1.z, l(1), l(8), r1.z, l(0) + imad r1.z, r2.x, l(32), r1.z + imad r1.z, r2.y, l(4), r1.z + bfi r1.yw, l(0, 6, 0, 6), l(0, 0, 0, 3), r0.yyyy, r1.yyyw + bfi r0.y, l(9), l(3), r1.z, r1.w + bfi r0.y, l(6), l(0), r1.y, r0.y + else + ibfe r1.yz, l(0, 27, 29, 0), l(0, 2, 0, 0), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.y, r2.x, r1.w, r1.y + ishl r2.xz, vThreadID.yyyy, l(5, 0, 7, 0) + and r2.xz, r2.xxzx, l(448, 0, 2048, 0) + bfi r1.w, l(23), l(9), r1.y, r2.x + bfi r2.w, l(1), l(4), vThreadID.y, l(0) + iadd r1.w, r1.w, r2.w + ishl r3.xy, r2.xxxx, l(3, 2, 0, 0) + bfi r3.xy, l(23, 23, 0, 0), l(12, 11, 0, 0), r1.yyyy, r3.xyxx + imad r2.xw, r2.wwww, l(8, 0, 0, 4), r3.xxxy + bfi r1.y, l(12), l(0), r2.z, r2.x + and r2.x, r2.w, l(1792) + iadd r1.y, r1.y, r2.x + and r2.x, r2.y, l(2) + iadd r1.z, r1.z, r2.x + bfi r1.z, l(2), l(6), r1.z, l(0) + iadd r1.y, r1.y, r1.z + bfi r0.y, l(6), l(0), r1.w, r1.y + endif +else + imad r1.y, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.y, CB0[0][0].z, r0.w +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.y, r0.y, l(4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r1.yzw, r0.zzzz, l(0, 1, 2, 3) +or r0.zw, r1.zzzw, r1.yyyz +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +ibfe r3.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r2.xyzw +itof r3.xyzw, r3.xyzw +mul r3.xyzw, r3.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r3.xyzw, r3.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +ishr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +itof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r2.xyzw, r2.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +f32tof16 r3.xyzw, r3.xyzw +f32tof16 r2.xyzw, r2.xyzw +imad r2.xyzw, r2.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r3.xyzw +store_uav_typed U0[0].xyzw, r1.xxxx, r2.xyzw +iadd r1.y, r1.x, l(1) +if_nz r0.x + mov r0.x, l(32) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r0.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r0.xyzw +endif +ibfe r0.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r2.xyzw +itof r0.xyzw, r0.xyzw +mul r0.xyzw, r0.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r0.xyzw, r0.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +ishr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +itof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r2.xyzw, r2.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +f32tof16 r0.xyzw, r0.xyzw +f32tof16 r2.xyzw, r2.xyzw +imad r0.xyzw, r2.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r0.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r0.xyzw +ret +// Approximately 128 instruction slots used +#endif + +const BYTE texture_load_rg16_snorm_float_cs[] = { + 68, 88, 66, 67, 208, 189, 187, 210, 71, 234, 226, 104, 73, 80, 129, 101, 149, 18, 0, + 106, 1, 0, 0, 0, 168, 21, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 12, 21, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 208, 16, 0, + 0, 81, 0, 5, 0, 52, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 226, 0, 16, 0, 1, 0, + 0, 0, 86, 6, 2, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, + 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, + 182, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 139, 0, 0, 14, + 82, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, + 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 96, 0, 0, 0, 30, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 20, 50, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, + 0, 0, 12, 162, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 6, 4, 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 162, 0, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 166, 10, 2, 0, 86, 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 10, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, + 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, + 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 32, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 162, 0, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, + 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, + 14, 98, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 27, 0, + 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 2, 0, 42, 0, 0, 9, + 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, + 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, 82, 0, 16, 0, 2, 0, + 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 2, 0, 0, 0, + 6, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, + 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, + 0, 35, 0, 0, 12, 146, 0, 16, 0, 2, 0, 0, 0, 246, 15, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, + 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 21, 0, + 0, 1, 18, 0, 0, 1, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, + 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, + 226, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 0, + 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 86, + 9, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 139, 0, 0, 15, 242, 0, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 43, 0, 0, 5, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 52, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 42, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, + 0, 56, 0, 1, 0, 56, 52, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, + 0, 0, 128, 191, 0, 0, 128, 191, 130, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 130, 0, 0, 5, 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, + 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 18, 0, + 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, + 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, + 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 6, + 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, + 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, + 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, + 0, 21, 0, 0, 1, 139, 0, 0, 15, 242, 0, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 56, 0, + 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 52, 0, 0, 10, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 42, 0, 0, 10, 242, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 52, + 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 130, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 130, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 70, 14, 16, 0, 0, 0, 0, 0, 164, 0, 0, 8, 242, 224, + 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, + 128, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, + 0, 38, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rg16_snorm_float_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rg16_snorm_float_scaled_cs.h new file mode 100644 index 0000000..eb89be2 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rg16_snorm_float_scaled_cs.h @@ -0,0 +1,532 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(2) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(2) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +ishl r1.w, r1.x, l(2) +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r2.z, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(3, 0, 1, 0), r1.xxxx + imad r2.z, r2.z, r3.y, r3.x + ishl r3.x, r1.z, l(10) + and r3.x, r3.x, l(6144) + bfi r3.x, l(3), l(8), r1.w, r3.x + ishr r3.x, r3.x, l(6) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r2.zw, l(0, 0, 20, 20), l(0, 0, 10, 13), r2.zzzz, l(0, 0, 0, 0) + imad r2.zw, r3.xxxx, l(0, 0, 2, 16), r2.zzzw + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 8, 11), vThreadID.zzzz, r2.zzzw + bfi r3.x, l(1), l(4), r1.z, l(0) + ubfe r3.y, l(3), l(6), r2.z + and r3.z, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.y, l(32), r0.x + imad r0.x, r3.z, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r3.xxxx, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r3.z, CB0[0][0].z, l(5) + imad r2.z, r3.x, r3.z, r2.z + ishl r3.xz, r1.zzzz, l(5, 0, 7, 0) + and r3.xz, r3.xxzx, l(448, 0, 2048, 0) + bfi r3.w, l(3), l(3), r1.w, r3.x + bfi r3.w, l(23), l(9), r2.z, r3.w + bfi r4.x, l(1), l(4), r1.z, l(0) + iadd r3.w, r3.w, r4.x + ishl r4.yz, r3.xxxx, l(0, 3, 2, 0) + bfi r4.yz, l(0, 3, 3, 0), l(0, 6, 5, 0), r1.wwww, r4.yyzy + bfi r4.yz, l(0, 23, 23, 0), l(0, 12, 11, 0), r2.zzzz, r4.yyzy + imad r4.xy, r4.xxxx, l(8, 4, 0, 0), r4.yzyy + bfi r1.w, l(12), l(0), r3.z, r4.x + and r2.z, r4.y, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.w, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].xyzw +ieq r1.xzw, r0.yyyy, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +if_nz r1.z + ushr r4.xyzw, r3.xyzw, l(16, 16, 16, 16) + bfi r3.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r3.xyzw, r4.xyzw +endif +ibfe r4.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r3.xyzw +itof r4.xyzw, r4.xyzw +mul r4.xyzw, r4.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r4.xyzw, r4.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +ishr r3.xyzw, r3.xyzw, l(16, 16, 16, 16) +itof r3.xyzw, r3.xyzw +mul r3.xyzw, r3.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r3.xyzw, r3.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +f32tof16 r4.xyzw, r4.xyzw +f32tof16 r3.xyzw, r3.xyzw +imad r3.xyzw, r3.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r4.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r3.xyzw +iadd r0.y, r1.y, l(1) +ult r1.w, l(1), r0.z +if_nz r1.w + udiv r1.w, null, r2.x, r0.z + imad r1.w, -r1.w, r0.z, r2.x + iadd r2.x, r1.w, l(1) + ieq r2.x, r0.z, r2.x + if_nz r2.x + ishl r0.z, r0.z, l(5) + ishl r1.w, r1.w, l(4) + iadd r0.z, r0.z, -r1.w + else + mov r0.z, l(16) + endif +else + mov r0.z, l(32) +endif +imul null, r0.z, r0.w, r0.z +ushr r0.z, r0.z, l(4) +iadd r0.x, r0.z, r0.x +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r1.x + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r1.z + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +ibfe r3.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r2.xyzw +itof r3.xyzw, r3.xyzw +mul r3.xyzw, r3.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r3.xyzw, r3.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +ishr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +itof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r2.xyzw, r2.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +f32tof16 r3.xyzw, r3.xyzw +f32tof16 r2.xyzw, r2.xyzw +imad r2.xyzw, r2.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r3.xyzw +store_uav_typed U0[0].xyzw, r0.yyyy, r2.xyzw +ret +// Approximately 148 instruction slots used +#endif + +const BYTE texture_load_rg16_snorm_float_scaled_cs[] = { + 68, 88, 66, 67, 199, 123, 60, 247, 47, 192, 251, 139, 8, 216, 93, 14, 37, 83, 68, + 54, 1, 0, 0, 0, 96, 24, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 196, 23, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 136, 19, 0, + 0, 81, 0, 5, 0, 226, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, + 0, 42, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 85, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, + 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 10, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 24, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 194, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, + 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, + 0, 2, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 166, 14, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 166, 10, + 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 9, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 15, 194, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 9, 66, 0, 16, 0, 3, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, + 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, + 82, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 23, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, + 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 4, 0, + 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 12, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, + 0, 2, 0, 0, 0, 86, 6, 16, 0, 4, 0, 0, 0, 35, 0, 0, 12, 50, 0, + 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, + 4, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, + 166, 11, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, + 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 10, 210, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 139, 0, 0, 15, 242, 0, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 43, 0, 0, + 5, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, + 52, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 42, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 56, 0, 1, 0, 56, 0, + 1, 0, 56, 0, 1, 0, 56, 52, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 130, 0, 0, 5, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 130, 0, 0, 5, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, + 5, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, + 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 58, + 0, 16, 0, 1, 0, 0, 0, 78, 0, 0, 8, 130, 0, 16, 0, 1, 0, 0, 0, + 0, 208, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 35, 0, 0, 10, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 128, 65, 0, + 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, + 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 5, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 8, 66, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 128, 65, + 0, 0, 0, 1, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, + 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, + 0, 0, 21, 0, 0, 1, 38, 0, 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, 0, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 45, + 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, + 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, + 0, 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, + 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, + 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 139, 0, + 0, 15, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 43, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, + 0, 1, 0, 56, 52, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 42, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 56, 0, + 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 52, 0, 0, 10, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 130, 0, 0, 5, 242, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 130, 0, 0, 5, 242, + 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 35, 0, 0, 12, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 148, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 50, 0, 0, 0, 26, 0, + 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rg16_unorm_float_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rg16_unorm_float_cs.h new file mode 100644 index 0000000..a15b228 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rg16_unorm_float_cs.h @@ -0,0 +1,461 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(2) +imad r1.x, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.x, r1.x, CB0[0][2].x, r0.w +iadd r1.x, r1.x, CB0[0][1].w +ushr r1.x, r1.x, l(4) +if_nz r0.x + if_nz r0.y + ishr r1.yzw, vThreadID.yyzy, l(0, 4, 2, 3) + ushr r2.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r0.y, r1.z, r2.x, r1.y + ibfe r2.xz, l(27, 0, 29, 0), l(2, 0, 0, 0), vThreadID.xxxx + imad r0.y, r0.y, r2.y, r2.x + ishl r1.y, vThreadID.y, l(10) + ishr r1.y, r1.y, l(6) + and r1.y, r1.y, l(96) + iadd r1.z, r1.z, r1.w + bfi r1.w, l(1), l(1), r1.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r1.w, l(2), l(1), r1.w, l(0) + bfi r1.z, l(1), l(0), r1.z, r1.w + bfi r2.xy, l(20, 20, 0, 0), l(10, 13, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r1.yw, r1.yyyy, l(0, 2, 0, 16), r2.xxxy + bfi r1.yw, l(0, 2, 0, 2), l(0, 8, 0, 11), vThreadID.zzzz, r1.yyyw + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r2.x, l(3), l(6), r1.y + and r2.y, r1.z, l(6) + bfi r1.z, l(1), l(8), r1.z, l(0) + imad r1.z, r2.x, l(32), r1.z + imad r1.z, r2.y, l(4), r1.z + bfi r1.yw, l(0, 6, 0, 6), l(0, 0, 0, 3), r0.yyyy, r1.yyyw + bfi r0.y, l(9), l(3), r1.z, r1.w + bfi r0.y, l(6), l(0), r1.y, r0.y + else + ibfe r1.yz, l(0, 27, 29, 0), l(0, 2, 0, 0), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r1.w, CB0[0][0].z, l(5) + imad r1.y, r2.x, r1.w, r1.y + ishl r2.xz, vThreadID.yyyy, l(5, 0, 7, 0) + and r2.xz, r2.xxzx, l(448, 0, 2048, 0) + bfi r1.w, l(23), l(9), r1.y, r2.x + bfi r2.w, l(1), l(4), vThreadID.y, l(0) + iadd r1.w, r1.w, r2.w + ishl r3.xy, r2.xxxx, l(3, 2, 0, 0) + bfi r3.xy, l(23, 23, 0, 0), l(12, 11, 0, 0), r1.yyyy, r3.xyxx + imad r2.xw, r2.wwww, l(8, 0, 0, 4), r3.xxxy + bfi r1.y, l(12), l(0), r2.z, r2.x + and r2.x, r2.w, l(1792) + iadd r1.y, r1.y, r2.x + and r2.x, r2.y, l(2) + iadd r1.z, r1.z, r2.x + bfi r1.z, l(2), l(6), r1.z, l(0) + iadd r1.y, r1.y, r1.z + bfi r0.y, l(6), l(0), r1.w, r1.y + endif +else + imad r1.y, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.y, CB0[0][0].z, r0.w +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.y, r0.y, l(4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r1.yzw, r0.zzzz, l(0, 1, 2, 3) +or r0.zw, r1.zzzw, r1.yyyz +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +and r3.xyzw, r2.xyzw, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff) +utof r3.xyzw, r3.xyzw +mul r3.xyzw, r3.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +ushr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +utof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +f32tof16 r3.xyzw, r3.xyzw +f32tof16 r2.xyzw, r2.xyzw +imad r2.xyzw, r2.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r3.xyzw +store_uav_typed U0[0].xyzw, r1.xxxx, r2.xyzw +iadd r1.y, r1.x, l(1) +if_nz r0.x + mov r0.x, l(32) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r0.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r0.xyzw +endif +and r0.xyzw, r2.xyzw, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff) +utof r0.xyzw, r0.xyzw +mul r0.xyzw, r0.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +ushr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +utof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +f32tof16 r0.xyzw, r0.xyzw +f32tof16 r2.xyzw, r2.xyzw +imad r0.xyzw, r2.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r0.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r0.xyzw +ret +// Approximately 124 instruction slots used +#endif + +const BYTE texture_load_rg16_unorm_float_cs[] = { + 68, 88, 66, 67, 155, 208, 16, 82, 232, 204, 136, 183, 92, 98, 245, 45, 149, 64, 155, + 174, 1, 0, 0, 0, 224, 20, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 68, 20, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 8, 16, 0, + 0, 81, 0, 5, 0, 2, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 18, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 226, 0, 16, 0, 1, 0, + 0, 0, 86, 6, 2, 0, 2, 64, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, + 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, + 182, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 139, 0, 0, 14, + 82, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, + 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 34, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, + 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 96, 0, 0, 0, 30, 0, 0, + 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 20, 50, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 10, 0, 0, 0, 13, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, + 0, 0, 12, 162, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 6, 4, 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, 162, 0, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 166, 10, 2, 0, 86, 13, 16, 0, 1, 0, 0, 0, 140, 0, 0, + 10, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, + 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, + 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 32, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 162, 0, 16, 0, 1, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 86, 13, 16, 0, 1, 0, 0, 0, + 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, + 14, 98, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 27, 0, + 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 2, 0, 42, 0, 0, 9, + 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 9, 130, 0, + 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, 82, 0, 16, 0, 2, 0, + 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 2, 0, 0, 0, + 6, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 26, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, + 6, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 50, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 12, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, + 0, 35, 0, 0, 12, 146, 0, 16, 0, 2, 0, 0, 0, 246, 15, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, + 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, + 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, + 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 21, 0, + 0, 1, 18, 0, 0, 1, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, + 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, + 226, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 0, + 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 86, + 9, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 255, + 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 86, 0, 0, 5, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 85, 0, + 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 128, + 0, 128, 55, 130, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 130, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 70, 14, 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, + 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, + 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, + 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, + 0, 1, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, + 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 42, + 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, + 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, + 1, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, + 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, + 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, + 55, 128, 0, 128, 55, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 128, 0, 128, 55, 128, 0, + 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 130, 0, 0, 5, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 130, 0, 0, 5, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 70, 14, 16, 0, 0, + 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 5, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 148, 0, 0, 0, 124, 0, 0, 0, 5, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 36, 0, 0, 0, 26, 0, 0, 0, 5, + 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rg16_unorm_float_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rg16_unorm_float_scaled_cs.h new file mode 100644 index 0000000..02c6bcc --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rg16_unorm_float_scaled_cs.h @@ -0,0 +1,517 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(3) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(2) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(2) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +ishl r1.w, r1.x, l(2) +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r2.z, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(3, 0, 1, 0), r1.xxxx + imad r2.z, r2.z, r3.y, r3.x + ishl r3.x, r1.z, l(10) + and r3.x, r3.x, l(6144) + bfi r3.x, l(3), l(8), r1.w, r3.x + ishr r3.x, r3.x, l(6) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r2.zw, l(0, 0, 20, 20), l(0, 0, 10, 13), r2.zzzz, l(0, 0, 0, 0) + imad r2.zw, r3.xxxx, l(0, 0, 2, 16), r2.zzzw + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 8, 11), vThreadID.zzzz, r2.zzzw + bfi r3.x, l(1), l(4), r1.z, l(0) + ubfe r3.y, l(3), l(6), r2.z + and r3.z, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.y, l(32), r0.x + imad r0.x, r3.z, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r3.xxxx, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r3.z, CB0[0][0].z, l(5) + imad r2.z, r3.x, r3.z, r2.z + ishl r3.xz, r1.zzzz, l(5, 0, 7, 0) + and r3.xz, r3.xxzx, l(448, 0, 2048, 0) + bfi r3.w, l(3), l(3), r1.w, r3.x + bfi r3.w, l(23), l(9), r2.z, r3.w + bfi r4.x, l(1), l(4), r1.z, l(0) + iadd r3.w, r3.w, r4.x + ishl r4.yz, r3.xxxx, l(0, 3, 2, 0) + bfi r4.yz, l(0, 3, 3, 0), l(0, 6, 5, 0), r1.wwww, r4.yyzy + bfi r4.yz, l(0, 23, 23, 0), l(0, 12, 11, 0), r2.zzzz, r4.yyzy + imad r4.xy, r4.xxxx, l(8, 4, 0, 0), r4.yzyy + bfi r1.w, l(12), l(0), r3.z, r4.x + and r2.z, r4.y, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.w, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].xyzw +ieq r1.xzw, r0.yyyy, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +if_nz r1.z + ushr r4.xyzw, r3.xyzw, l(16, 16, 16, 16) + bfi r3.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r3.xyzw, r4.xyzw +endif +and r4.xyzw, r3.xyzw, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff) +utof r4.xyzw, r4.xyzw +mul r4.xyzw, r4.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +ushr r3.xyzw, r3.xyzw, l(16, 16, 16, 16) +utof r3.xyzw, r3.xyzw +mul r3.xyzw, r3.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +f32tof16 r4.xyzw, r4.xyzw +f32tof16 r3.xyzw, r3.xyzw +imad r3.xyzw, r3.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r4.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r3.xyzw +iadd r0.y, r1.y, l(1) +ult r1.w, l(1), r0.z +if_nz r1.w + udiv r1.w, null, r2.x, r0.z + imad r1.w, -r1.w, r0.z, r2.x + iadd r2.x, r1.w, l(1) + ieq r2.x, r0.z, r2.x + if_nz r2.x + ishl r0.z, r0.z, l(5) + ishl r1.w, r1.w, l(4) + iadd r0.z, r0.z, -r1.w + else + mov r0.z, l(16) + endif +else + mov r0.z, l(32) +endif +imul null, r0.z, r0.w, r0.z +ushr r0.z, r0.z, l(4) +iadd r0.x, r0.z, r0.x +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r1.x + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r1.z + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +and r3.xyzw, r2.xyzw, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff) +utof r3.xyzw, r3.xyzw +mul r3.xyzw, r3.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +ushr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +utof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +f32tof16 r3.xyzw, r3.xyzw +f32tof16 r2.xyzw, r2.xyzw +imad r2.xyzw, r2.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r3.xyzw +store_uav_typed U0[0].xyzw, r0.yyyy, r2.xyzw +ret +// Approximately 144 instruction slots used +#endif + +const BYTE texture_load_rg16_unorm_float_scaled_cs[] = { + 68, 88, 66, 67, 181, 180, 34, 243, 64, 149, 232, 191, 86, 100, 160, 179, 165, 159, 90, + 222, 1, 0, 0, 0, 152, 23, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 252, 22, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 192, 18, 0, + 0, 81, 0, 5, 0, 176, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 2, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, + 0, 42, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 85, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, + 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 10, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 24, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 194, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 20, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, + 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, + 0, 2, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 166, 14, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 166, 10, + 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 9, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 15, 194, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 9, 66, 0, 16, 0, 3, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, + 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, + 82, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 192, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 23, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, + 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 4, 0, + 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 12, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, + 0, 2, 0, 0, 0, 86, 6, 16, 0, 4, 0, 0, 0, 35, 0, 0, 12, 50, 0, + 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, + 4, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, + 166, 11, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, + 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 10, 210, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, + 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, + 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 86, 0, 0, 5, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 85, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 86, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, + 128, 0, 128, 55, 130, 0, 0, 5, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 130, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 70, 14, 16, 0, 4, 0, 0, 0, 164, 0, 0, + 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 79, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, + 0, 0, 78, 0, 0, 8, 130, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 10, + 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, + 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, + 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, + 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 54, 0, 0, 5, + 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 21, 0, 0, + 1, 38, 0, 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, + 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 255, + 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 86, 0, 0, 5, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 85, 0, + 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 128, + 0, 128, 55, 130, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 130, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 70, 14, 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, + 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, + 0, 0, 144, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, + 0, 0, 0, 48, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rgba16_snorm_float_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rgba16_snorm_float_cs.h new file mode 100644 index 0000000..5b47b0f --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rgba16_snorm_float_cs.h @@ -0,0 +1,486 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(2) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(3) +imad r1.y, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.y, CB0[0][2].x, r0.w +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r2.xw, l(27, 0, 0, 29), l(3, 0, 0, 1), vThreadID.xxxx + imad r0.y, r0.y, r1.w, r2.x + ishl r1.z, vThreadID.y, l(11) + and r1.z, r1.z, l(0x00003000) + bfi r1.z, l(3), l(9), r1.x, r1.z + ishr r1.z, r1.z, l(6) + iadd r1.w, r2.y, r2.z + bfi r2.x, l(1), l(1), r1.w, l(0) + iadd r2.x, r2.x, r2.w + bfi r2.x, l(2), l(1), r2.x, l(0) + bfi r1.w, l(1), l(0), r1.w, r2.x + bfi r2.xy, l(19, 19, 0, 0), l(11, 14, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(9, 12, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(6) + bfi r1.w, l(1), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(6, 6, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r2.z, CB0[0][0].z, l(5) + imad r1.z, r2.x, r2.z, r1.z + ishl r2.xz, vThreadID.yyyy, l(6, 0, 7, 0) + and r2.xz, r2.xxzx, l(896, 0, 2048, 0) + bfi r2.w, l(3), l(4), r1.x, r2.x + bfi r2.w, l(22), l(10), r1.z, r2.w + bfi r3.x, l(1), l(4), vThreadID.y, l(0) + iadd r2.w, r2.w, r3.x + ishl r3.yz, r2.xxxx, l(0, 3, 2, 0) + bfi r3.yz, l(0, 3, 3, 0), l(0, 7, 6, 0), r1.xxxx, r3.yyzy + bfi r1.xz, l(22, 0, 22, 0), l(13, 0, 12, 0), r1.zzzz, r3.yyzy + imad r1.xz, r3.xxxx, l(8, 0, 4, 0), r1.xxzx + bfi r1.x, l(12), l(0), r2.z, r1.x + and r1.z, r1.z, l(1792) + iadd r1.x, r1.x, r1.z + and r1.z, r2.y, l(2) + iadd r1.z, r1.w, r1.z + bfi r1.z, l(2), l(6), r1.z, l(0) + iadd r1.x, r1.x, r1.z + bfi r0.y, l(6), l(0), r2.w, r1.x + endif +else + imad r1.x, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.x, CB0[0][0].z, r0.w +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.y, r0.y, l(4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r1.xzw, r0.zzzz, l(1, 0, 2, 3) +or r0.zw, r1.zzzw, r1.xxxz +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +ibfe r3.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r2.xyzw +itof r3.xyzw, r3.xyzw +mul r3.xyzw, r3.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r3.xyzw, r3.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +ishr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +itof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r2.xyzw, r2.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +f32tof16 r3.xyzw, r3.xyzw +f32tof16 r2.xyzw, r2.xyzw +imad r2.xyzw, r2.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r3.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r2.xyzw +iadd r1.x, r1.y, l(1) +if_nz r0.x + mov r0.x, l(32) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r0.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r0.xyzw +endif +ibfe r0.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r2.xyzw +itof r0.xyzw, r0.xyzw +mul r0.xyzw, r0.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r0.xyzw, r0.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +ishr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +itof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r2.xyzw, r2.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +f32tof16 r0.xyzw, r0.xyzw +f32tof16 r2.xyzw, r2.xyzw +imad r0.xyzw, r2.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r0.xyzw +store_uav_typed U0[0].xyzw, r1.xxxx, r0.xyzw +ret +// Approximately 131 instruction slots used +#endif + +const BYTE texture_load_rgba16_snorm_float_cs[] = { + 68, 88, 66, 67, 233, 25, 194, 67, 75, 41, 78, 235, 71, 151, 135, 202, 40, 242, 177, + 34, 1, 0, 0, 0, 68, 22, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 168, 21, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 108, 17, 0, + 0, 81, 0, 5, 0, 91, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 114, 0, 16, 0, 2, 0, + 0, 0, 150, 5, 2, 0, 2, 64, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 1, 0, 0, 0, + 246, 139, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 14, + 146, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 48, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 140, 0, 0, 20, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 19, 0, + 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 11, + 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, + 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 138, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, + 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 32, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, + 0, 0, 1, 139, 0, 0, 14, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, + 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, + 82, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 82, 0, + 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 128, + 3, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 22, + 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 18, 0, 16, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, + 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, + 41, 0, 0, 10, 98, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, + 0, 1, 0, 0, 0, 86, 6, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, 82, 0, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 22, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 86, 6, 16, + 0, 3, 0, 0, 0, 35, 0, 0, 12, 82, 0, 16, 0, 1, 0, 0, 0, 6, 0, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, + 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, + 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 35, 0, 0, 9, 18, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 30, + 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, + 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 86, + 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 32, 0, 0, 10, 210, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, + 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, + 0, 0, 0, 6, 8, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, + 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 139, 0, 0, + 15, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 43, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 0, + 1, 0, 56, 52, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 42, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 56, 0, 1, + 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 52, 0, 0, 10, 242, 0, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, + 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 130, 0, 0, 5, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 130, 0, 0, 5, 242, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 35, 0, 0, 12, 242, + 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 30, + 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, + 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, + 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 7, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, + 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, + 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 0, 0, 0, 0, 21, 0, 0, 1, 139, 0, 0, 15, 242, 0, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, + 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, + 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, + 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 52, 0, 0, 10, + 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 42, 0, + 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 43, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 0, + 1, 0, 56, 52, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 130, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, + 16, 0, 0, 0, 0, 0, 130, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 70, 14, 16, 0, 0, 0, 0, 0, 164, 0, + 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, + 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, + 148, 0, 0, 0, 131, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 8, 0, 0, 0, 38, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rgba16_snorm_float_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rgba16_snorm_float_scaled_cs.h new file mode 100644 index 0000000..353c481 --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rgba16_snorm_float_scaled_cs.h @@ -0,0 +1,532 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(2) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(3) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(1) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +ishl r1.w, r1.x, l(1) +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r2.z, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(4, 0, 2, 0), r1.xxxx + imad r2.z, r2.z, r3.y, r3.x + ishl r3.x, r1.z, l(11) + and r3.x, r3.x, l(0x00003000) + bfi r3.x, l(3), l(9), r1.w, r3.x + ishr r3.x, r3.x, l(6) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r2.zw, l(0, 0, 19, 19), l(0, 0, 11, 14), r2.zzzz, l(0, 0, 0, 0) + imad r2.zw, r3.xxxx, l(0, 0, 2, 16), r2.zzzw + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 9, 12), vThreadID.zzzz, r2.zzzw + bfi r3.x, l(1), l(4), r1.z, l(0) + ubfe r3.y, l(3), l(6), r2.z + and r3.z, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.y, l(32), r0.x + imad r0.x, r3.z, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r3.xxxx, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 4, 2), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r3.z, CB0[0][0].z, l(5) + imad r2.z, r3.x, r3.z, r2.z + ishl r3.xz, r1.zzzz, l(6, 0, 7, 0) + and r3.xz, r3.xxzx, l(896, 0, 2048, 0) + bfi r3.w, l(3), l(4), r1.w, r3.x + bfi r3.w, l(22), l(10), r2.z, r3.w + bfi r4.x, l(1), l(4), r1.z, l(0) + iadd r3.w, r3.w, r4.x + ishl r4.yz, r3.xxxx, l(0, 3, 2, 0) + bfi r4.yz, l(0, 3, 3, 0), l(0, 7, 6, 0), r1.wwww, r4.yyzy + bfi r4.yz, l(0, 22, 22, 0), l(0, 13, 12, 0), r2.zzzz, r4.yyzy + imad r4.xy, r4.xxxx, l(8, 4, 0, 0), r4.yzyy + bfi r1.w, l(12), l(0), r3.z, r4.x + and r2.z, r4.y, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.w, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].xyzw +ieq r1.xzw, r0.yyyy, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +if_nz r1.z + ushr r4.xyzw, r3.xyzw, l(16, 16, 16, 16) + bfi r3.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r3.xyzw, r4.xyzw +endif +ibfe r4.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r3.xyzw +itof r4.xyzw, r4.xyzw +mul r4.xyzw, r4.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r4.xyzw, r4.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +ishr r3.xyzw, r3.xyzw, l(16, 16, 16, 16) +itof r3.xyzw, r3.xyzw +mul r3.xyzw, r3.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r3.xyzw, r3.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +f32tof16 r4.xyzw, r4.xyzw +f32tof16 r3.xyzw, r3.xyzw +imad r3.xyzw, r3.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r4.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r3.xyzw +iadd r0.y, r1.y, l(1) +ult r1.w, l(1), r0.z +if_nz r1.w + udiv r1.w, null, r2.x, r0.z + imad r1.w, -r1.w, r0.z, r2.x + iadd r2.x, r1.w, l(1) + ieq r2.x, r0.z, r2.x + if_nz r2.x + ishl r0.z, r0.z, l(5) + ishl r1.w, r1.w, l(4) + iadd r0.z, r0.z, -r1.w + else + mov r0.z, l(16) + endif +else + mov r0.z, l(32) +endif +imul null, r0.z, r0.w, r0.z +ushr r0.z, r0.z, l(4) +iadd r0.x, r0.z, r0.x +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r1.x + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r1.z + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +ibfe r3.xyzw, l(16, 16, 16, 16), l(0, 0, 0, 0), r2.xyzw +itof r3.xyzw, r3.xyzw +mul r3.xyzw, r3.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r3.xyzw, r3.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +ishr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +itof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000031, 0.000031, 0.000031, 0.000031) +max r2.xyzw, r2.xyzw, l(-1.000000, -1.000000, -1.000000, -1.000000) +f32tof16 r3.xyzw, r3.xyzw +f32tof16 r2.xyzw, r2.xyzw +imad r2.xyzw, r2.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r3.xyzw +store_uav_typed U0[0].xyzw, r0.yyyy, r2.xyzw +ret +// Approximately 148 instruction slots used +#endif + +const BYTE texture_load_rgba16_snorm_float_scaled_cs[] = { + 68, 88, 66, 67, 12, 48, 22, 60, 104, 58, 37, 248, 63, 0, 17, 246, 123, 219, 159, + 100, 1, 0, 0, 0, 96, 24, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 196, 23, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 136, 19, 0, + 0, 81, 0, 5, 0, 226, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, + 0, 42, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 85, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, + 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 11, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 48, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 9, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 194, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 14, + 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, + 0, 2, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 166, 14, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 166, 10, + 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 9, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 15, 194, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 9, 66, 0, 16, 0, 3, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, + 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, + 82, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 128, 3, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 22, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 4, 0, + 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 13, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, + 0, 2, 0, 0, 0, 86, 6, 16, 0, 4, 0, 0, 0, 35, 0, 0, 12, 50, 0, + 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, + 4, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, + 166, 11, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, + 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 10, 210, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 139, 0, 0, 15, 242, 0, + 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 43, 0, 0, + 5, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 56, 0, + 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, + 52, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 42, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 56, 0, 1, 0, 56, 0, + 1, 0, 56, 0, 1, 0, 56, 52, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 130, 0, 0, 5, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 130, 0, 0, 5, 242, 0, 16, 0, 3, + 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, + 5, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, + 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 58, + 0, 16, 0, 1, 0, 0, 0, 78, 0, 0, 8, 130, 0, 16, 0, 1, 0, 0, 0, + 0, 208, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 35, 0, 0, 10, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 128, 65, 0, + 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, + 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 5, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 8, 66, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 128, 65, + 0, 0, 0, 1, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, + 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, + 0, 0, 21, 0, 0, 1, 38, 0, 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, 0, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 45, + 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, + 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, + 0, 1, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, + 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, + 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, + 85, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 139, 0, + 0, 15, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 43, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, + 0, 1, 0, 56, 52, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, + 128, 191, 0, 0, 128, 191, 42, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 43, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 56, 0, + 1, 0, 56, 0, 1, 0, 56, 0, 1, 0, 56, 52, 0, 0, 10, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 191, 0, 0, 128, 191, 0, 0, 128, 191, 0, 0, 128, 191, 130, 0, 0, 5, 242, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 130, 0, 0, 5, 242, + 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 35, 0, 0, 12, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 148, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 50, 0, 0, 0, 26, 0, + 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rgba16_unorm_float_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rgba16_unorm_float_cs.h new file mode 100644 index 0000000..8b3ffdb --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rgba16_unorm_float_cs.h @@ -0,0 +1,472 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 5 +dcl_thread_group 4, 32, 1 +and r0.xy, CB0[0][0].xxxx, l(1, 2, 0, 0) +ishl r1.x, vThreadID.x, l(2) +mov r1.y, vThreadID.y +uge r0.zw, r1.xxxy, CB0[0][1].xxxy +or r0.z, r0.w, r0.z +if_nz r0.z + ret +endif +ubfe r0.z, l(2), l(2), CB0[0][0].x +ishl r0.w, r1.x, l(3) +imad r1.y, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.y, CB0[0][2].x, r0.w +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +if_nz r0.x + if_nz r0.y + ishr r2.xyz, vThreadID.yzyy, l(4, 2, 3, 0) + ushr r1.zw, CB0[0][0].wwwz, l(0, 0, 4, 5) + imad r0.y, r2.y, r1.z, r2.x + ibfe r2.xw, l(27, 0, 0, 29), l(3, 0, 0, 1), vThreadID.xxxx + imad r0.y, r0.y, r1.w, r2.x + ishl r1.z, vThreadID.y, l(11) + and r1.z, r1.z, l(0x00003000) + bfi r1.z, l(3), l(9), r1.x, r1.z + ishr r1.z, r1.z, l(6) + iadd r1.w, r2.y, r2.z + bfi r2.x, l(1), l(1), r1.w, l(0) + iadd r2.x, r2.x, r2.w + bfi r2.x, l(2), l(1), r2.x, l(0) + bfi r1.w, l(1), l(0), r1.w, r2.x + bfi r2.xy, l(19, 19, 0, 0), l(11, 14, 0, 0), r0.yyyy, l(0, 0, 0, 0) + imad r2.xy, r1.zzzz, l(2, 16, 0, 0), r2.xyxx + bfi r2.xy, l(2, 2, 0, 0), l(9, 12, 0, 0), vThreadID.zzzz, r2.xyxx + bfi r0.y, l(1), l(4), vThreadID.y, l(0) + ubfe r1.z, l(3), l(6), r2.x + and r2.z, r1.w, l(6) + bfi r1.w, l(1), l(8), r1.w, l(0) + imad r1.z, r1.z, l(32), r1.w + imad r1.z, r2.z, l(4), r1.z + bfi r2.xy, l(6, 6, 0, 0), l(0, 3, 0, 0), r0.yyyy, r2.xyxx + bfi r0.y, l(9), l(3), r1.z, r2.y + bfi r0.y, l(6), l(0), r2.x, r0.y + else + ibfe r1.zw, l(0, 0, 27, 29), l(0, 0, 3, 1), vThreadID.xxxx + ishr r2.xy, vThreadID.yyyy, l(5, 2, 0, 0) + ushr r2.z, CB0[0][0].z, l(5) + imad r1.z, r2.x, r2.z, r1.z + ishl r2.xz, vThreadID.yyyy, l(6, 0, 7, 0) + and r2.xz, r2.xxzx, l(896, 0, 2048, 0) + bfi r2.w, l(3), l(4), r1.x, r2.x + bfi r2.w, l(22), l(10), r1.z, r2.w + bfi r3.x, l(1), l(4), vThreadID.y, l(0) + iadd r2.w, r2.w, r3.x + ishl r3.yz, r2.xxxx, l(0, 3, 2, 0) + bfi r3.yz, l(0, 3, 3, 0), l(0, 7, 6, 0), r1.xxxx, r3.yyzy + bfi r1.xz, l(22, 0, 22, 0), l(13, 0, 12, 0), r1.zzzz, r3.yyzy + imad r1.xz, r3.xxxx, l(8, 0, 4, 0), r1.xxzx + bfi r1.x, l(12), l(0), r2.z, r1.x + and r1.z, r1.z, l(1792) + iadd r1.x, r1.x, r1.z + and r1.z, r2.y, l(2) + iadd r1.z, r1.w, r1.z + bfi r1.z, l(2), l(6), r1.z, l(0) + iadd r1.x, r1.x, r1.z + bfi r0.y, l(6), l(0), r2.w, r1.x + endif +else + imad r1.x, vThreadID.z, CB0[0][0].w, vThreadID.y + imad r0.y, r1.x, CB0[0][0].z, r0.w +endif +iadd r0.y, r0.y, CB0[0][0].y +ushr r0.y, r0.y, l(4) +ld r2.xyzw, r0.yyyy, T0[0].xyzw +ieq r1.xzw, r0.zzzz, l(1, 0, 2, 3) +or r0.zw, r1.zzzw, r1.xxxz +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +and r3.xyzw, r2.xyzw, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff) +utof r3.xyzw, r3.xyzw +mul r3.xyzw, r3.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +ushr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +utof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +f32tof16 r3.xyzw, r3.xyzw +f32tof16 r2.xyzw, r2.xyzw +imad r2.xyzw, r2.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r3.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r2.xyzw +iadd r1.x, r1.y, l(1) +if_nz r0.x + mov r0.x, l(32) +else + mov r0.x, l(16) +endif +ushr r0.x, r0.x, l(4) +iadd r0.x, r0.x, r0.y +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r0.z + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r0.w + ushr r0.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r0.xyzw +endif +and r0.xyzw, r2.xyzw, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff) +utof r0.xyzw, r0.xyzw +mul r0.xyzw, r0.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +ushr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +utof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +f32tof16 r0.xyzw, r0.xyzw +f32tof16 r2.xyzw, r2.xyzw +imad r0.xyzw, r2.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r0.xyzw +store_uav_typed U0[0].xyzw, r1.xxxx, r0.xyzw +ret +// Approximately 127 instruction slots used +#endif + +const BYTE texture_load_rgba16_unorm_float_cs[] = { + 68, 88, 66, 67, 20, 93, 102, 191, 218, 223, 58, 86, 49, 146, 72, 40, 107, 13, 130, + 203, 1, 0, 0, 0, 124, 21, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 224, 20, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 164, 16, 0, + 0, 81, 0, 5, 0, 41, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 5, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12, + 50, 0, 16, 0, 0, 0, 0, 0, 6, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, 194, 0, 16, 0, 0, 0, 0, + 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 132, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 138, 0, 0, + 11, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, + 9, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, + 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, + 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 9, 114, 0, 16, 0, 2, 0, + 0, 0, 150, 5, 2, 0, 2, 64, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 12, 194, 0, 16, 0, 1, 0, 0, 0, + 246, 139, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 14, + 146, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 2, 0, 35, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 6, 66, 0, 16, + 0, 1, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 48, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 10, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, + 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 130, + 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, + 0, 140, 0, 0, 20, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 19, 0, + 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 11, + 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 35, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 16, + 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 10, 2, 0, 70, 0, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 2, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 138, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, + 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, + 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 32, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 17, 50, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, + 0, 0, 1, 139, 0, 0, 14, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, + 2, 0, 42, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, + 82, 0, 16, 0, 2, 0, 0, 0, 86, 5, 2, 0, 2, 64, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 82, 0, + 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 128, + 3, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, + 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, + 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 22, + 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 10, 18, 0, 16, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, + 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, + 41, 0, 0, 10, 98, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, + 0, 1, 0, 0, 0, 86, 6, 16, 0, 3, 0, 0, 0, 140, 0, 0, 17, 82, 0, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 22, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 86, 6, 16, + 0, 3, 0, 0, 0, 35, 0, 0, 12, 82, 0, 16, 0, 1, 0, 0, 0, 6, 0, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 6, 2, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, + 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, + 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, + 140, 0, 0, 11, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, + 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, + 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 35, 0, 0, 9, 18, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 2, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 26, 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 30, + 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, + 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 86, + 5, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 32, 0, 0, 10, 210, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, + 0, 0, 60, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, + 0, 0, 0, 6, 8, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, + 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, + 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, + 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, + 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 86, + 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 56, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 2, 64, 0, 0, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, + 128, 55, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, + 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 128, 0, 128, 55, 128, 0, 128, 55, 128, + 0, 128, 55, 128, 0, 128, 55, 130, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 130, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, + 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, + 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 18, 0, 0, + 1, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, + 0, 0, 21, 0, 0, 1, 85, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, + 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, + 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 10, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 85, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 1, 0, + 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, + 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, + 16, 0, 0, 0, 0, 0, 85, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, 17, 242, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, + 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, + 0, 0, 255, 255, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 128, 0, 128, 55, 128, 0, 128, + 55, 128, 0, 128, 55, 128, 0, 128, 55, 85, 0, 0, 10, 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 86, 0, 0, 5, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, + 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 128, 0, + 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 130, 0, 0, 5, 242, + 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 130, 0, 0, 5, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 35, 0, 0, + 12, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 70, + 14, 16, 0, 0, 0, 0, 0, 164, 0, 0, 8, 242, 224, 33, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, + 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 127, 0, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 36, 0, 0, 0, 26, + 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rgba16_unorm_float_scaled_cs.h b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rgba16_unorm_float_scaled_cs.h new file mode 100644 index 0000000..715e8db --- /dev/null +++ b/src/graphics/shaders/bytecode/d3d12_5_1/texture_load_rgba16_unorm_float_scaled_cs.h @@ -0,0 +1,517 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// uint xe_texture_load_is_tiled_3d_endian_scale;// Offset: 0 Size: 4 +// uint xe_texture_load_guest_offset; // Offset: 4 Size: 4 +// uint xe_texture_load_guest_pitch_aligned;// Offset: 8 Size: 4 +// uint xe_texture_load_guest_z_stride_block_rows_aligned;// Offset: 12 Size: 4 +// uint3 xe_texture_load_size_blocks; // Offset: 16 Size: 12 +// uint xe_texture_load_host_offset; // Offset: 28 Size: 4 +// uint xe_texture_load_host_pitch; // Offset: 32 Size: 4 +// uint xe_texture_load_height_texels;// Offset: 36 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_texture_load_source texture uint4 buf T0 t0 1 +// xe_texture_load_dest UAV uint4 buf U0 u0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Input +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +cs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][3], immediateIndexed, space=0 +dcl_resource_buffer (uint,uint,uint,uint) T0[0:0], space=0 +dcl_uav_typed_buffer (uint,uint,uint,uint) U0[0:0], space=0 +dcl_input vThreadID.xyz +dcl_temps 6 +dcl_thread_group 4, 32, 1 +and r0.x, CB0[0][0].x, l(2) +ishl r1.x, vThreadID.x, l(2) +mov r1.y, vThreadID.y +uge r0.yz, r1.xxyx, CB0[0][1].xxyx +or r0.y, r0.z, r0.y +if_nz r0.y + ret +endif +ubfe r0.yzw, l(0, 2, 3, 3), l(0, 2, 4, 7), CB0[0][0].xxxx +ishl r1.y, r1.x, l(3) +imad r1.z, vThreadID.z, CB0[0][1].y, vThreadID.y +imad r1.y, r1.z, CB0[0][2].x, r1.y +iadd r1.y, r1.y, CB0[0][1].w +ushr r1.y, r1.y, l(4) +ushr r2.x, r1.x, l(1) +mov r2.y, vThreadID.y +udiv r1.xz, null, r2.xxyx, r0.zzwz +ishl r1.w, r1.x, l(1) +if_nz r0.x + ishr r2.zw, r1.zzzz, l(0, 0, 4, 3) + ishr r0.x, vThreadID.z, l(2) + ushr r3.xy, CB0[0][0].wzww, l(4, 5, 0, 0) + imad r2.z, r0.x, r3.x, r2.z + ibfe r3.xz, l(27, 0, 29, 0), l(4, 0, 2, 0), r1.xxxx + imad r2.z, r2.z, r3.y, r3.x + ishl r3.x, r1.z, l(11) + and r3.x, r3.x, l(0x00003000) + bfi r3.x, l(3), l(9), r1.w, r3.x + ishr r3.x, r3.x, l(6) + iadd r0.x, r0.x, r2.w + bfi r2.w, l(1), l(1), r0.x, l(0) + iadd r2.w, r2.w, r3.z + bfi r2.w, l(2), l(1), r2.w, l(0) + bfi r0.x, l(1), l(0), r0.x, r2.w + bfi r2.zw, l(0, 0, 19, 19), l(0, 0, 11, 14), r2.zzzz, l(0, 0, 0, 0) + imad r2.zw, r3.xxxx, l(0, 0, 2, 16), r2.zzzw + bfi r2.zw, l(0, 0, 2, 2), l(0, 0, 9, 12), vThreadID.zzzz, r2.zzzw + bfi r3.x, l(1), l(4), r1.z, l(0) + ubfe r3.y, l(3), l(6), r2.z + and r3.z, r0.x, l(6) + bfi r0.x, l(1), l(8), r0.x, l(0) + imad r0.x, r3.y, l(32), r0.x + imad r0.x, r3.z, l(4), r0.x + bfi r2.zw, l(0, 0, 5, 5), l(0, 0, 0, 3), r3.xxxx, r2.zzzw + bfi r0.x, l(9), l(3), r0.x, r2.w + bfi r0.x, l(6), l(0), r2.z, r0.x +else + ibfe r2.zw, l(0, 0, 27, 29), l(0, 0, 4, 2), r1.xxxx + ishr r3.xy, r1.zzzz, l(5, 2, 0, 0) + ushr r3.z, CB0[0][0].z, l(5) + imad r2.z, r3.x, r3.z, r2.z + ishl r3.xz, r1.zzzz, l(6, 0, 7, 0) + and r3.xz, r3.xxzx, l(896, 0, 2048, 0) + bfi r3.w, l(3), l(4), r1.w, r3.x + bfi r3.w, l(22), l(10), r2.z, r3.w + bfi r4.x, l(1), l(4), r1.z, l(0) + iadd r3.w, r3.w, r4.x + ishl r4.yz, r3.xxxx, l(0, 3, 2, 0) + bfi r4.yz, l(0, 3, 3, 0), l(0, 7, 6, 0), r1.wwww, r4.yyzy + bfi r4.yz, l(0, 22, 22, 0), l(0, 13, 12, 0), r2.zzzz, r4.yyzy + imad r4.xy, r4.xxxx, l(8, 4, 0, 0), r4.yzyy + bfi r1.w, l(12), l(0), r3.z, r4.x + and r2.z, r4.y, l(1792) + iadd r1.w, r1.w, r2.z + and r2.z, r3.y, l(2) + iadd r2.z, r2.w, r2.z + bfi r2.z, l(2), l(6), r2.z, l(0) + iadd r1.w, r1.w, r2.z + bfi r0.x, l(6), l(0), r3.w, r1.w +endif +imad r1.xz, -r1.xxzx, r0.zzwz, r2.xxyx +imul null, r1.w, r0.w, r0.z +imad r1.x, r1.x, r0.w, r1.z +ishl r1.x, r1.x, l(4) +imad r0.x, r0.x, r1.w, r1.x +iadd r0.x, r0.x, CB0[0][0].y +ushr r0.x, r0.x, l(4) +ld r3.xyzw, r0.xxxx, T0[0].xyzw +ieq r1.xzw, r0.yyyy, l(1, 0, 2, 3) +or r1.xz, r1.zzwz, r1.xxzx +if_nz r1.x + ishl r4.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r5.xyzw, r3.xyzw, l(8, 8, 8, 8) + and r5.xyzw, r5.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r3.xyzw, r4.xyzw, r5.xyzw +endif +if_nz r1.z + ushr r4.xyzw, r3.xyzw, l(16, 16, 16, 16) + bfi r3.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r3.xyzw, r4.xyzw +endif +and r4.xyzw, r3.xyzw, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff) +utof r4.xyzw, r4.xyzw +mul r4.xyzw, r4.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +ushr r3.xyzw, r3.xyzw, l(16, 16, 16, 16) +utof r3.xyzw, r3.xyzw +mul r3.xyzw, r3.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +f32tof16 r4.xyzw, r4.xyzw +f32tof16 r3.xyzw, r3.xyzw +imad r3.xyzw, r3.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r4.xyzw +store_uav_typed U0[0].xyzw, r1.yyyy, r3.xyzw +iadd r0.y, r1.y, l(1) +ult r1.w, l(1), r0.z +if_nz r1.w + udiv r1.w, null, r2.x, r0.z + imad r1.w, -r1.w, r0.z, r2.x + iadd r2.x, r1.w, l(1) + ieq r2.x, r0.z, r2.x + if_nz r2.x + ishl r0.z, r0.z, l(5) + ishl r1.w, r1.w, l(4) + iadd r0.z, r0.z, -r1.w + else + mov r0.z, l(16) + endif +else + mov r0.z, l(32) +endif +imul null, r0.z, r0.w, r0.z +ushr r0.z, r0.z, l(4) +iadd r0.x, r0.z, r0.x +ld r2.xyzw, r0.xxxx, T0[0].xyzw +if_nz r1.x + ishl r3.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r3.xyzw, r3.xyzw, l(0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00) + ushr r4.xyzw, r2.xyzw, l(8, 8, 8, 8) + and r4.xyzw, r4.xyzw, l(0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff) + iadd r2.xyzw, r3.xyzw, r4.xyzw +endif +if_nz r1.z + ushr r3.xyzw, r2.xyzw, l(16, 16, 16, 16) + bfi r2.xyzw, l(16, 16, 16, 16), l(16, 16, 16, 16), r2.xyzw, r3.xyzw +endif +and r3.xyzw, r2.xyzw, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff) +utof r3.xyzw, r3.xyzw +mul r3.xyzw, r3.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +ushr r2.xyzw, r2.xyzw, l(16, 16, 16, 16) +utof r2.xyzw, r2.xyzw +mul r2.xyzw, r2.xyzw, l(0.000015, 0.000015, 0.000015, 0.000015) +f32tof16 r3.xyzw, r3.xyzw +f32tof16 r2.xyzw, r2.xyzw +imad r2.xyzw, r2.xyzw, l(0x00010000, 0x00010000, 0x00010000, 0x00010000), r3.xyzw +store_uav_typed U0[0].xyzw, r0.yyyy, r2.xyzw +ret +// Approximately 144 instruction slots used +#endif + +const BYTE texture_load_rgba16_unorm_float_scaled_cs[] = { + 68, 88, 66, 67, 203, 228, 67, 105, 255, 236, 183, 61, 208, 88, 69, 150, 87, 12, 128, + 51, 1, 0, 0, 0, 152, 23, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 20, 4, + 0, 0, 36, 4, 0, 0, 52, 4, 0, 0, 252, 22, 0, 0, 82, 68, 69, 70, 216, + 3, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 83, 67, 0, 5, 0, 0, 173, 3, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 116, 101, 120, 116, + 117, 114, 101, 95, 108, 111, 97, 100, 95, 115, 111, 117, 114, 99, 101, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 100, 101, 115, 116, 0, 112, + 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 224, 0, 0, 0, + 8, 0, 0, 0, 8, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 156, 2, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, + 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 185, 2, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, + 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 221, 2, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 15, 3, 0, 0, 16, 0, 0, 0, 12, 0, + 0, 0, 2, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 88, 3, 0, 0, 28, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 116, 3, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 143, 3, 0, 0, + 36, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 105, 115, 95, 116, 105, + 108, 101, 100, 95, 51, 100, 95, 101, 110, 100, 105, 97, 110, 95, 115, 99, 97, 108, 101, + 0, 100, 119, 111, 114, 100, 0, 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 113, 2, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, + 97, 100, 95, 103, 117, 101, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, + 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, + 112, 105, 116, 99, 104, 95, 97, 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 103, 117, 101, 115, 116, 95, 122, 95, + 115, 116, 114, 105, 100, 101, 95, 98, 108, 111, 99, 107, 95, 114, 111, 119, 115, 95, 97, + 108, 105, 103, 110, 101, 100, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, + 111, 97, 100, 95, 115, 105, 122, 101, 95, 98, 108, 111, 99, 107, 115, 0, 117, 105, 110, + 116, 51, 0, 171, 171, 171, 1, 0, 19, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 3, 0, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, + 95, 104, 111, 115, 116, 95, 111, 102, 102, 115, 101, 116, 0, 120, 101, 95, 116, 101, 120, + 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, 111, 115, 116, 95, 112, 105, 116, 99, + 104, 0, 120, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 108, 111, 97, 100, 95, 104, + 101, 105, 103, 104, 116, 95, 116, 101, 120, 101, 108, 115, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, + 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, + 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 192, 18, 0, + 0, 81, 0, 5, 0, 176, 4, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 88, 8, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, 156, 8, 0, 7, 70, 238, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 2, 114, 0, 2, 0, 104, 0, 0, 2, 6, 0, 0, 0, 155, + 0, 0, 4, 4, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 6, 18, 0, + 16, 0, 1, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 54, + 0, 0, 4, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 2, 0, 80, 0, 0, 9, + 98, 0, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 1, 0, 0, 0, 6, 129, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 21, 0, 0, 1, 138, 0, 0, 17, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, + 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, + 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 3, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 2, 0, 26, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, + 0, 2, 0, 35, 0, 0, 11, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, + 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 54, 0, 0, 4, 34, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 2, 0, 78, 0, 0, 8, 82, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, + 6, 1, 16, 0, 2, 0, 0, 0, 166, 11, 16, 0, 0, 0, 0, 0, 41, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, + 0, 42, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 2, 0, 1, 64, + 0, 0, 2, 0, 0, 0, 85, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 182, + 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 139, 0, 0, 15, 82, + 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, + 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 11, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 48, 0, 0, 140, 0, 0, 11, 18, + 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 9, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, + 0, 42, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, + 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 20, 194, 0, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 19, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 14, + 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, + 0, 2, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 166, 14, 16, 0, 2, + 0, 0, 0, 140, 0, 0, 16, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 166, 10, + 2, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 3, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 9, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, + 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, + 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 6, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 140, 0, 0, 17, 194, 0, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 140, 0, + 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, + 64, 0, 0, 3, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 139, 0, 0, 15, 194, + 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 0, 0, 0, 29, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, + 64, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 9, 66, 0, 16, 0, 3, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 35, 0, + 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, + 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 10, + 82, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 10, 82, 0, 16, 0, 3, 0, 0, 0, 6, 2, 16, 0, 3, 0, 0, 0, 2, + 64, 0, 0, 128, 3, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 3, 0, 0, 0, 1, + 64, 0, 0, 22, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, + 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 10, 98, 0, 16, 0, 4, 0, 0, + 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 86, 6, 16, 0, 4, 0, + 0, 0, 140, 0, 0, 17, 98, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 13, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 166, 10, 16, + 0, 2, 0, 0, 0, 86, 6, 16, 0, 4, 0, 0, 0, 35, 0, 0, 12, 50, 0, + 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 8, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, + 4, 0, 0, 0, 140, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, + 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 7, 0, 0, + 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, + 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 2, 0, 0, 0, 140, 0, 0, 11, 66, 0, 16, 0, 2, 0, 0, + 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 35, 0, 0, 10, 82, + 0, 16, 0, 1, 0, 0, 0, 6, 2, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, + 166, 11, 16, 0, 0, 0, 0, 0, 6, 1, 16, 0, 2, 0, 0, 0, 38, 0, 0, + 8, 0, 208, 0, 0, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, + 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, + 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 35, 0, + 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 45, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 10, 210, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, + 0, 0, 7, 82, 0, 16, 0, 1, 0, 0, 0, 166, 11, 16, 0, 1, 0, 0, 0, + 6, 2, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, + 0, 41, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, + 4, 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 21, + 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, + 0, 17, 242, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, + 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, + 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, + 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 86, 0, 0, 5, + 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 56, 0, 0, + 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 85, + 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 86, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, + 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, + 128, 0, 128, 55, 130, 0, 0, 5, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 130, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 3, 0, 0, 0, 70, + 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 70, 14, 16, 0, 4, 0, 0, 0, 164, 0, 0, + 8, 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 1, 0, + 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, + 79, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, + 0, 0, 78, 0, 0, 8, 130, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 10, + 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 10, + 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, + 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, + 3, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, + 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, + 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 16, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 54, 0, 0, 5, + 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 21, 0, 0, + 1, 38, 0, 0, 8, 0, 208, 0, 0, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, + 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 45, 0, 0, 8, 242, 0, + 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, + 41, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, + 0, 0, 0, 2, 64, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 85, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, + 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 30, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, + 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, + 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 10, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, + 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 140, 0, 0, + 17, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 242, 0, 16, + 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 255, + 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 86, 0, 0, 5, 242, + 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 56, 0, 0, 10, + 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, + 0, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 85, 0, + 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, + 64, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, + 86, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, + 0, 56, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, 128, 0, 128, 55, 128, 0, 128, 55, 128, 0, 128, 55, 128, + 0, 128, 55, 130, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 130, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 35, 0, 0, 12, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 70, 14, 16, 0, 3, 0, 0, 0, 164, 0, 0, 8, + 242, 224, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, + 0, 0, 144, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, + 0, 0, 0, 48, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}; diff --git a/src/graphics/shaders/placeholder.ps.glsl b/src/graphics/shaders/placeholder.ps.glsl new file mode 100644 index 0000000..17649cf --- /dev/null +++ b/src/graphics/shaders/placeholder.ps.glsl @@ -0,0 +1,18 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#version 460 + +// Minimal placeholder pixel shader for async pipeline hot-swap. +// Discarding avoids transient black flashes while real shaders are compiling. +layout(location = 0) out vec4 oC0; + +void main() { + discard; +} diff --git a/src/graphics/shaders/resolve_downscale.cs.glsl b/src/graphics/shaders/resolve_downscale.cs.glsl new file mode 100644 index 0000000..a3c8c12 --- /dev/null +++ b/src/graphics/shaders/resolve_downscale.cs.glsl @@ -0,0 +1,160 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#version 460 + +// Compute shader to downscale scaled resolve buffer data back to 1x resolution. +// Operates on 32x32 tiled data format used by Xbox 360. +// Each thread handles one output pixel (one 32x32 tile = 1024 threads). +// +// By default, picks the top-left pixel of each scale_x * scale_y block. +// When xe_downscale_half_pixel_offset is set, samples from (scale/2, scale/2) +// within each block to compensate for the half-pixel offset becoming a +// full-pixel offset at higher resolutions. + +layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in; + +layout(push_constant) uniform ResolveDownscaleConstants { + uint xe_downscale_scale_x; // 1 to kMaxDrawResolutionScaleAlongAxis + uint xe_downscale_scale_y; // 1 to kMaxDrawResolutionScaleAlongAxis + uint xe_downscale_pixel_size_log2; // 0=8bit, 1=16bit, 2=32bit, 3=64bit + uint xe_downscale_tile_count; // Number of 32x32 tiles to process + uint xe_downscale_source_offset_bytes; // Byte offset into source buffer + // When non-zero, apply half-pixel offset correction by sampling from + // (scale/2, scale/2) within each scaled block instead of (0, 0). + // This compensates for the D3D9-style half-pixel offset used by Xbox 360 + // games, which at Nx resolution scaling shifts rendered content by + // (N/2, N/2) host pixels. + uint xe_downscale_half_pixel_offset; +}; + +// Source buffer (scaled resolve data) +layout(std430, set = 0, binding = 0) readonly buffer SourceBuffer { + uint data[]; +} xe_resolve_source; + +// Destination buffer (1x resolution) +layout(std430, set = 0, binding = 1) writeonly buffer DestBuffer { + uint data[]; +} xe_resolve_dest; + +// Groupshared memory for coalescing sub-32-bit writes +shared uint gs_tile_data[32 * 32]; + +void main() { + uint tile_index = gl_WorkGroupID.x; + + // Early out if beyond tile count + if (tile_index >= xe_downscale_tile_count) { + return; + } + + uint row = gl_LocalInvocationID.y; + uint column = gl_LocalInvocationID.x; + uint pixel_index = row * 32u + column; // 0-1023 + + uint pixel_size = 1u << xe_downscale_pixel_size_log2; + uint tile_size_1x = 32u * 32u * pixel_size; + uint scale_xy = xe_downscale_scale_x * xe_downscale_scale_y; + uint tile_size_scaled = tile_size_1x * scale_xy; + + // Compute offset within each scaled block to sample from. + // Without half-pixel correction: sample from (0, 0) = linear offset 0. + // With half-pixel correction: sample from (scale/2, scale/2) to compensate + // for the D3D9-style half-pixel offset shifting content by (N/2, N/2) pixels + // at Nx resolution. + uint block_sample_offset = 0u; + if (xe_downscale_half_pixel_offset != 0u && scale_xy > 1u) { + uint offset_x = xe_downscale_scale_x >> 1u; + uint offset_y = xe_downscale_scale_y >> 1u; + block_sample_offset = offset_x + offset_y * xe_downscale_scale_x; + } + + // Source offset: base of the scaled block plus offset within block + // Add source_offset_bytes to handle buffer-relative addressing + // This must be done before division to preserve sub-dword byte position + uint src_byte_offset = xe_downscale_source_offset_bytes + + tile_index * tile_size_scaled + + pixel_index * pixel_size * scale_xy + + block_sample_offset * pixel_size; + uint src_offset = src_byte_offset >> 2u; + + // Destination offset in 1x buffer + uint dst_byte_offset = tile_index * tile_size_1x + + pixel_index * pixel_size; + uint dst_offset = dst_byte_offset >> 2u; + + // Copy pixel based on size + switch (xe_downscale_pixel_size_log2) { + case 0u: { // 8-bit - use groupshared to coalesce 4 bytes into 32-bit writes + // Load the byte value + uint src_word = xe_resolve_source.data[src_offset]; + uint byte_val = (src_word >> ((src_byte_offset & 3u) * 8u)) & 0xFFu; + + // Each group of 4 threads packs into one uint + uint pack_index = pixel_index >> 2u; // Which uint (0-255) + uint byte_pos = pixel_index & 3u; // Which byte in uint (0-3) + + // Pack byte into shared memory + uint contribution = byte_val << (byte_pos * 8u); + if (byte_pos == 0u) { + gs_tile_data[pack_index] = contribution; + } + barrier(); + if (byte_pos != 0u) { + atomicOr(gs_tile_data[pack_index], contribution); + } + barrier(); + + // First thread of each 4 writes the packed uint + if (byte_pos == 0u) { + xe_resolve_dest.data[tile_index * (32u * 32u / 4u) + pack_index] = + gs_tile_data[pack_index]; + } + break; + } + case 1u: { // 16-bit - use groupshared to coalesce 2 shorts into 32-bit writes + // Load the short value + uint src_word = xe_resolve_source.data[src_offset]; + uint short_val = (src_word >> ((src_byte_offset & 2u) * 8u)) & 0xFFFFu; + + // Each group of 2 threads packs into one uint + uint pack_index = pixel_index >> 1u; // Which uint (0-511) + uint short_pos = pixel_index & 1u; // Which short in uint (0-1) + + // Pack short into shared memory + uint contribution = short_val << (short_pos * 16u); + if (short_pos == 0u) { + gs_tile_data[pack_index] = contribution; + } + barrier(); + if (short_pos != 0u) { + atomicOr(gs_tile_data[pack_index], contribution); + } + barrier(); + + // First thread of each 2 writes the packed uint + if (short_pos == 0u) { + xe_resolve_dest.data[tile_index * (32u * 32u * 2u / 4u) + pack_index] = + gs_tile_data[pack_index]; + } + break; + } + case 2u: { // 32-bit - direct copy + xe_resolve_dest.data[dst_offset] = xe_resolve_source.data[src_offset]; + break; + } + case 3u: { // 64-bit - direct copy (2 uints) + xe_resolve_dest.data[dst_offset] = xe_resolve_source.data[src_offset]; + xe_resolve_dest.data[dst_offset + 1u] = + xe_resolve_source.data[src_offset + 1u]; + break; + } + } +} diff --git a/src/graphics/shaders/resolve_downscale.cs.hlsl b/src/graphics/shaders/resolve_downscale.cs.hlsl new file mode 100644 index 0000000..91c2f95 --- /dev/null +++ b/src/graphics/shaders/resolve_downscale.cs.hlsl @@ -0,0 +1,147 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +// Compute shader to downscale scaled resolve buffer data back to 1x resolution. +// Operates on 32x32 tiled data format used by Xbox 360. +// Each thread handles one output pixel (one 32x32 tile = 1024 threads). +// +// By default, picks the top-left pixel of each scale_x * scale_y block. +// When xe_downscale_half_pixel_offset is set, samples from (scale/2, scale/2) +// within each block to compensate for the half-pixel offset becoming a +// full-pixel offset at higher resolutions. + +cbuffer XeResolveDownscaleConstants : register(b0) { + uint xe_downscale_scale_x; // 1 to kMaxDrawResolutionScaleAlongAxis + uint xe_downscale_scale_y; // 1 to kMaxDrawResolutionScaleAlongAxis + uint xe_downscale_pixel_size_log2; // 0=8bit, 1=16bit, 2=32bit, 3=64bit + uint xe_downscale_tile_count; // Number of 32x32 tiles to process + // When non-zero, apply half-pixel offset correction by sampling from + // (scale/2, scale/2) within each scaled block instead of (0, 0). + // This compensates for the D3D9-style half-pixel offset used by Xbox 360 + // games, which at Nx resolution scaling shifts rendered content by + // (N/2, N/2) host pixels. + uint xe_downscale_half_pixel_offset; +}; + +ByteAddressBuffer xe_resolve_source : register(t0); +RWByteAddressBuffer xe_resolve_dest : register(u0); + +// Groupshared memory for coalescing sub-32-bit writes +// Max tile size at 1x is 32*32*8 bytes = 8KB for 64-bit pixels +// We only need this for 8-bit and 16-bit where we coalesce to 32-bit stores +groupshared uint gs_tile_data[32 * 32]; + +// Thread group processes one 32x32 tile worth of output +[numthreads(32, 32, 1)] +void main(uint3 xe_group_id : SV_GroupID, + uint3 xe_thread_id_in_group : SV_GroupThreadID, + uint xe_group_thread_index : SV_GroupIndex) { + uint tile_index = xe_group_id.x; + + // Early out if beyond tile count + [branch] if (tile_index >= xe_downscale_tile_count) { + return; + } + + uint row = xe_thread_id_in_group.y; + uint column = xe_thread_id_in_group.x; + uint pixel_index = row * 32 + column; // 0-1023 + + uint pixel_size = 1u << xe_downscale_pixel_size_log2; + uint tile_size_1x = 32 * 32 * pixel_size; + uint scale_xy = xe_downscale_scale_x * xe_downscale_scale_y; + uint tile_size_scaled = tile_size_1x * scale_xy; + + // Compute offset within each scaled block to sample from. + // Without half-pixel correction: sample from (0, 0) = linear offset 0. + // With half-pixel correction: sample from (scale/2, scale/2) to compensate + // for the D3D9-style half-pixel offset shifting content by (N/2, N/2) pixels + // at Nx resolution. + uint block_sample_offset = 0u; + [branch] if (xe_downscale_half_pixel_offset != 0u && scale_xy > 1u) { + uint offset_x = xe_downscale_scale_x >> 1u; + uint offset_y = xe_downscale_scale_y >> 1u; + block_sample_offset = offset_x + offset_y * xe_downscale_scale_x; + } + + // Source offset: base of the scaled block plus offset within block + uint src_offset = tile_index * tile_size_scaled + + pixel_index * pixel_size * scale_xy + + block_sample_offset * pixel_size; + + // Destination offset in 1x buffer + uint dst_offset = tile_index * tile_size_1x + + pixel_index * pixel_size; + + // Copy pixel based on size + [branch] switch (xe_downscale_pixel_size_log2) { + case 0: { // 8-bit - use groupshared to coalesce 4 bytes into 32-bit writes + // Load the byte value + uint byte_val = (xe_resolve_source.Load(src_offset & ~3u) >> + ((src_offset & 3u) * 8u)) & 0xFFu; + + // Each group of 4 threads packs into one uint + uint pack_index = pixel_index >> 2; // Which uint (0-255) + uint byte_pos = pixel_index & 3u; // Which byte in uint (0-3) + + // Pack byte into shared memory uint using atomics within group + uint contribution = byte_val << (byte_pos * 8u); + if (byte_pos == 0u) { + gs_tile_data[pack_index] = contribution; + } + GroupMemoryBarrierWithGroupSync(); + if (byte_pos != 0u) { + InterlockedOr(gs_tile_data[pack_index], contribution); + } + GroupMemoryBarrierWithGroupSync(); + + // First thread of each 4 writes the packed uint + if (byte_pos == 0u) { + xe_resolve_dest.Store(tile_index * (32 * 32) + pack_index * 4, + gs_tile_data[pack_index]); + } + break; + } + case 1: { // 16-bit - use groupshared to coalesce 2 shorts into 32-bit writes + // Load the short value + uint short_val = (xe_resolve_source.Load(src_offset & ~3u) >> + ((src_offset & 2u) * 8u)) & 0xFFFFu; + + // Each group of 2 threads packs into one uint + uint pack_index = pixel_index >> 1; // Which uint (0-511) + uint short_pos = pixel_index & 1u; // Which short in uint (0-1) + + // Pack short into shared memory + uint contribution = short_val << (short_pos * 16u); + if (short_pos == 0u) { + gs_tile_data[pack_index] = contribution; + } + GroupMemoryBarrierWithGroupSync(); + if (short_pos != 0u) { + InterlockedOr(gs_tile_data[pack_index], contribution); + } + GroupMemoryBarrierWithGroupSync(); + + // First thread of each 2 writes the packed uint + if (short_pos == 0u) { + xe_resolve_dest.Store(tile_index * (32 * 32 * 2) + pack_index * 4, + gs_tile_data[pack_index]); + } + break; + } + case 2: { // 32-bit - direct copy + xe_resolve_dest.Store(dst_offset, xe_resolve_source.Load(src_offset)); + break; + } + case 3: { // 64-bit - direct copy + xe_resolve_dest.Store2(dst_offset, xe_resolve_source.Load2(src_offset)); + break; + } + } +} diff --git a/src/graphics/shaders/vulkan_spirv/apply_gamma_pwl_cs.h b/src/graphics/shaders/vulkan_spirv/apply_gamma_pwl_cs.h new file mode 100644 index 0000000..231c9e6 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/apply_gamma_pwl_cs.h @@ -0,0 +1,232 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 24005 +; Schema: 0 + OpCapability Shader + OpCapability SampledBuffer + OpCapability StorageImageExtendedFormats + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 16 8 1 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_struct_993 Block + OpMemberDecorate %_struct_993 0 Offset 0 + OpDecorate %5759 Binding 0 + OpDecorate %5759 DescriptorSet 1 + OpDecorate %5945 Binding 0 + OpDecorate %5945 DescriptorSet 0 + OpDecorate %3258 NonReadable + OpDecorate %3258 Binding 0 + OpDecorate %3258 DescriptorSet 2 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %float = OpTypeFloat 32 + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 + %uint_0 = OpConstant %uint 0 + %uint_7 = OpConstant %uint 7 + %uint_1 = OpConstant %uint 1 +%float_0_125 = OpConstant %float 0.125 +%float_1_52737048en05 = OpConstant %float 1.52737048e-05 + %v3uint = OpTypeVector %uint 3 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_struct_993 = OpTypeStruct %v2uint +%_ptr_PushConstant__struct_993 = OpTypePointer PushConstant %_struct_993 + %3305 = OpVariable %_ptr_PushConstant__struct_993 PushConstant + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_v2uint = OpTypePointer PushConstant %v2uint + %bool = OpTypeBool + %v2bool = OpTypeVector %bool 2 + %150 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_150 = OpTypePointer UniformConstant %150 + %5759 = OpVariable %_ptr_UniformConstant_150 UniformConstant + %v2int = OpTypeVector %int 2 + %v4float = OpTypeVector %float 4 + %v3float = OpTypeVector %float 3 + %float_1023 = OpConstant %float 1023 + %float_0_5 = OpConstant %float 0.5 + %152 = OpTypeImage %uint Buffer 0 0 0 1 Unknown +%_ptr_UniformConstant_152 = OpTypePointer UniformConstant %152 + %5945 = OpVariable %_ptr_UniformConstant_152 UniformConstant + %uint_3 = OpConstant %uint 3 + %v4uint = OpTypeVector %uint 4 + %uint_2 = OpConstant %uint 2 + %166 = OpTypeImage %float 2D 0 0 0 2 Rgb10A2 +%_ptr_UniformConstant_166 = OpTypePointer UniformConstant %166 + %3258 = OpVariable %_ptr_UniformConstant_166 UniformConstant + %uint_16 = OpConstant %uint 16 + %uint_8 = OpConstant %uint 8 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_16 %uint_8 %uint_1 + %939 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %21573 None + OpSwitch %uint_0 %12914 + %12914 = OpLabel + %13761 = OpLoad %v3uint %gl_GlobalInvocationID + %21717 = OpVectorShuffle %v2uint %13761 %13761 0 1 + %7760 = OpAccessChain %_ptr_PushConstant_v2uint %3305 %int_0 + %13378 = OpLoad %v2uint %7760 + %23437 = OpUGreaterThanEqual %v2bool %21717 %13378 + %23076 = OpAny %bool %23437 + OpSelectionMerge %18302 DontFlatten + OpBranchConditional %23076 %21992 %18302 + %21992 = OpLabel + OpBranch %21573 + %18302 = OpLabel + %24004 = OpLoad %150 %5759 + %10533 = OpBitcast %v2int %21717 + %6680 = OpImageFetch %v4float %24004 %10533 Lod %int_0 + %16242 = OpVectorShuffle %v3float %6680 %6680 0 1 2 + %13907 = OpVectorTimesScalar %v3float %16242 %float_1023 + %16889 = OpFAdd %v3float %13907 %939 + %11099 = OpConvertFToU %v3uint %16889 + %19954 = OpLoad %152 %5945 + %23099 = OpCompositeExtract %uint %11099 0 + %17722 = OpShiftRightLogical %uint %23099 %uint_3 + %15968 = OpIMul %uint %17722 %uint_3 + %18268 = OpBitcast %int %15968 + %14598 = OpImageFetch %v4uint %19954 %18268 + %6376 = OpCompositeExtract %uint %14598 0 + %17705 = OpConvertUToF %float %6376 + %12314 = OpBitwiseAnd %uint %23099 %uint_7 + %14345 = OpCompositeExtract %uint %14598 1 + %16230 = OpIMul %uint %12314 %14345 + %17759 = OpConvertUToF %float %16230 + %22854 = OpFMul %float %17759 %float_0_125 + %11948 = OpFAdd %float %17705 %22854 + %6845 = OpFMul %float %11948 %float_1_52737048en05 + %6923 = OpExtInst %float %1 FClamp %6845 %float_0 %float_1 + %14371 = OpLoad %152 %5945 + %12884 = OpCompositeExtract %uint %11099 1 + %17798 = OpShiftRightLogical %uint %12884 %uint_3 + %15827 = OpIMul %uint %17798 %uint_3 + %18887 = OpIAdd %uint %15827 %uint_1 + %14460 = OpBitcast %int %18887 + %17829 = OpImageFetch %v4uint %14371 %14460 + %6377 = OpCompositeExtract %uint %17829 0 + %17706 = OpConvertUToF %float %6377 + %12315 = OpBitwiseAnd %uint %12884 %uint_7 + %14346 = OpCompositeExtract %uint %17829 1 + %16231 = OpIMul %uint %12315 %14346 + %17760 = OpConvertUToF %float %16231 + %22855 = OpFMul %float %17760 %float_0_125 + %11949 = OpFAdd %float %17706 %22855 + %6846 = OpFMul %float %11949 %float_1_52737048en05 + %6924 = OpExtInst %float %1 FClamp %6846 %float_0 %float_1 + %14372 = OpLoad %152 %5945 + %12885 = OpCompositeExtract %uint %11099 2 + %17799 = OpShiftRightLogical %uint %12885 %uint_3 + %15828 = OpIMul %uint %17799 %uint_3 + %18888 = OpIAdd %uint %15828 %uint_2 + %14461 = OpBitcast %int %18888 + %17830 = OpImageFetch %v4uint %14372 %14461 + %6378 = OpCompositeExtract %uint %17830 0 + %17707 = OpConvertUToF %float %6378 + %12316 = OpBitwiseAnd %uint %12885 %uint_7 + %14347 = OpCompositeExtract %uint %17830 1 + %16232 = OpIMul %uint %12316 %14347 + %17761 = OpConvertUToF %float %16232 + %22856 = OpFMul %float %17761 %float_0_125 + %11950 = OpFAdd %float %17707 %22856 + %7206 = OpFMul %float %11950 %float_1_52737048en05 + %22327 = OpExtInst %float %1 FClamp %7206 %float_0 %float_1 + %6470 = OpCompositeConstruct %v4float %6923 %6924 %22327 %float_1 + %12275 = OpLoad %166 %3258 + OpImageWrite %12275 %10533 %6470 + OpBranch %21573 + %21573 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t apply_gamma_pwl_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00005DC5, 0x00000000, 0x00020011, 0x00000001, 0x00020011, + 0x0000002E, 0x00020011, 0x00000031, 0x0006000B, 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, + 0x00000000, 0x0003000E, 0x00000000, 0x00000001, 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, + 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, 0x00000011, 0x00000010, 0x00000008, 0x00000001, + 0x00040047, 0x00000F48, 0x0000000B, 0x0000001C, 0x00030047, 0x000003E1, 0x00000002, 0x00050048, + 0x000003E1, 0x00000000, 0x00000023, 0x00000000, 0x00040047, 0x0000167F, 0x00000021, 0x00000000, + 0x00040047, 0x0000167F, 0x00000022, 0x00000001, 0x00040047, 0x00001739, 0x00000021, 0x00000000, + 0x00040047, 0x00001739, 0x00000022, 0x00000000, 0x00030047, 0x00000CBA, 0x00000019, 0x00040047, + 0x00000CBA, 0x00000021, 0x00000000, 0x00040047, 0x00000CBA, 0x00000022, 0x00000002, 0x00040047, + 0x00000B0F, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, + 0x00030016, 0x0000000D, 0x00000020, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, + 0x00000011, 0x0000000B, 0x00000002, 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, 0x0004002B, + 0x0000000D, 0x0000008A, 0x3F800000, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, + 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, + 0x0000000D, 0x000001E0, 0x3E000000, 0x0004002B, 0x0000000D, 0x000009AA, 0x37802008, 0x00040017, + 0x00000014, 0x0000000B, 0x00000003, 0x00040020, 0x00000291, 0x00000001, 0x00000014, 0x0004003B, + 0x00000291, 0x00000F48, 0x00000001, 0x0003001E, 0x000003E1, 0x00000011, 0x00040020, 0x0000065E, + 0x00000009, 0x000003E1, 0x0004003B, 0x0000065E, 0x00000CE9, 0x00000009, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x0000028E, + 0x00000009, 0x00000011, 0x00020014, 0x00000009, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x00090019, 0x00000096, 0x0000000D, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00040020, 0x00000313, 0x00000000, 0x00000096, 0x0004003B, 0x00000313, 0x0000167F, + 0x00000000, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x0000001D, 0x0000000D, + 0x00000004, 0x00040017, 0x00000018, 0x0000000D, 0x00000003, 0x0004002B, 0x0000000D, 0x00000409, + 0x447FC000, 0x0004002B, 0x0000000D, 0x000000FC, 0x3F000000, 0x00090019, 0x00000098, 0x0000000B, + 0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00040020, 0x00000315, + 0x00000000, 0x00000098, 0x0004003B, 0x00000315, 0x00001739, 0x00000000, 0x0004002B, 0x0000000B, + 0x00000A13, 0x00000003, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x0004002B, 0x0000000B, + 0x00000A10, 0x00000002, 0x00090019, 0x000000A6, 0x0000000D, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000002, 0x0000000B, 0x00040020, 0x00000323, 0x00000000, 0x000000A6, 0x0004003B, + 0x00000323, 0x00000CBA, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, + 0x0000000B, 0x00000A22, 0x00000008, 0x0006002C, 0x00000014, 0x00000B0F, 0x00000A3A, 0x00000A22, + 0x00000A0D, 0x0006002C, 0x00000018, 0x000003AB, 0x000000FC, 0x000000FC, 0x000000FC, 0x00050036, + 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00005445, + 0x00000000, 0x000300FB, 0x00000A0A, 0x00003272, 0x000200F8, 0x00003272, 0x0004003D, 0x00000014, + 0x000035C1, 0x00000F48, 0x0007004F, 0x00000011, 0x000054D5, 0x000035C1, 0x000035C1, 0x00000000, + 0x00000001, 0x00050041, 0x0000028E, 0x00001E50, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x00000011, + 0x00003442, 0x00001E50, 0x000500AE, 0x0000000F, 0x00005B8D, 0x000054D5, 0x00003442, 0x0004009A, + 0x00000009, 0x00005A24, 0x00005B8D, 0x000300F7, 0x0000477E, 0x00000002, 0x000400FA, 0x00005A24, + 0x000055E8, 0x0000477E, 0x000200F8, 0x000055E8, 0x000200F9, 0x00005445, 0x000200F8, 0x0000477E, + 0x0004003D, 0x00000096, 0x00005DC4, 0x0000167F, 0x0004007C, 0x00000012, 0x00002925, 0x000054D5, + 0x0007005F, 0x0000001D, 0x00001A18, 0x00005DC4, 0x00002925, 0x00000002, 0x00000A0B, 0x0008004F, + 0x00000018, 0x00003F72, 0x00001A18, 0x00001A18, 0x00000000, 0x00000001, 0x00000002, 0x0005008E, + 0x00000018, 0x00003653, 0x00003F72, 0x00000409, 0x00050081, 0x00000018, 0x000041F9, 0x00003653, + 0x000003AB, 0x0004006D, 0x00000014, 0x00002B5B, 0x000041F9, 0x0004003D, 0x00000098, 0x00004DF2, + 0x00001739, 0x00050051, 0x0000000B, 0x00005A3B, 0x00002B5B, 0x00000000, 0x000500C2, 0x0000000B, + 0x0000453A, 0x00005A3B, 0x00000A13, 0x00050084, 0x0000000B, 0x00003E60, 0x0000453A, 0x00000A13, + 0x0004007C, 0x0000000C, 0x0000475C, 0x00003E60, 0x0005005F, 0x00000017, 0x00003906, 0x00004DF2, + 0x0000475C, 0x00050051, 0x0000000B, 0x000018E8, 0x00003906, 0x00000000, 0x00040070, 0x0000000D, + 0x00004529, 0x000018E8, 0x000500C7, 0x0000000B, 0x0000301A, 0x00005A3B, 0x00000A1F, 0x00050051, + 0x0000000B, 0x00003809, 0x00003906, 0x00000001, 0x00050084, 0x0000000B, 0x00003F66, 0x0000301A, + 0x00003809, 0x00040070, 0x0000000D, 0x0000455F, 0x00003F66, 0x00050085, 0x0000000D, 0x00005946, + 0x0000455F, 0x000001E0, 0x00050081, 0x0000000D, 0x00002EAC, 0x00004529, 0x00005946, 0x00050085, + 0x0000000D, 0x00001ABD, 0x00002EAC, 0x000009AA, 0x0008000C, 0x0000000D, 0x00001B0B, 0x00000001, + 0x0000002B, 0x00001ABD, 0x00000A0C, 0x0000008A, 0x0004003D, 0x00000098, 0x00003823, 0x00001739, + 0x00050051, 0x0000000B, 0x00003254, 0x00002B5B, 0x00000001, 0x000500C2, 0x0000000B, 0x00004586, + 0x00003254, 0x00000A13, 0x00050084, 0x0000000B, 0x00003DD3, 0x00004586, 0x00000A13, 0x00050080, + 0x0000000B, 0x000049C7, 0x00003DD3, 0x00000A0D, 0x0004007C, 0x0000000C, 0x0000387C, 0x000049C7, + 0x0005005F, 0x00000017, 0x000045A5, 0x00003823, 0x0000387C, 0x00050051, 0x0000000B, 0x000018E9, + 0x000045A5, 0x00000000, 0x00040070, 0x0000000D, 0x0000452A, 0x000018E9, 0x000500C7, 0x0000000B, + 0x0000301B, 0x00003254, 0x00000A1F, 0x00050051, 0x0000000B, 0x0000380A, 0x000045A5, 0x00000001, + 0x00050084, 0x0000000B, 0x00003F67, 0x0000301B, 0x0000380A, 0x00040070, 0x0000000D, 0x00004560, + 0x00003F67, 0x00050085, 0x0000000D, 0x00005947, 0x00004560, 0x000001E0, 0x00050081, 0x0000000D, + 0x00002EAD, 0x0000452A, 0x00005947, 0x00050085, 0x0000000D, 0x00001ABE, 0x00002EAD, 0x000009AA, + 0x0008000C, 0x0000000D, 0x00001B0C, 0x00000001, 0x0000002B, 0x00001ABE, 0x00000A0C, 0x0000008A, + 0x0004003D, 0x00000098, 0x00003824, 0x00001739, 0x00050051, 0x0000000B, 0x00003255, 0x00002B5B, + 0x00000002, 0x000500C2, 0x0000000B, 0x00004587, 0x00003255, 0x00000A13, 0x00050084, 0x0000000B, + 0x00003DD4, 0x00004587, 0x00000A13, 0x00050080, 0x0000000B, 0x000049C8, 0x00003DD4, 0x00000A10, + 0x0004007C, 0x0000000C, 0x0000387D, 0x000049C8, 0x0005005F, 0x00000017, 0x000045A6, 0x00003824, + 0x0000387D, 0x00050051, 0x0000000B, 0x000018EA, 0x000045A6, 0x00000000, 0x00040070, 0x0000000D, + 0x0000452B, 0x000018EA, 0x000500C7, 0x0000000B, 0x0000301C, 0x00003255, 0x00000A1F, 0x00050051, + 0x0000000B, 0x0000380B, 0x000045A6, 0x00000001, 0x00050084, 0x0000000B, 0x00003F68, 0x0000301C, + 0x0000380B, 0x00040070, 0x0000000D, 0x00004561, 0x00003F68, 0x00050085, 0x0000000D, 0x00005948, + 0x00004561, 0x000001E0, 0x00050081, 0x0000000D, 0x00002EAE, 0x0000452B, 0x00005948, 0x00050085, + 0x0000000D, 0x00001C26, 0x00002EAE, 0x000009AA, 0x0008000C, 0x0000000D, 0x00005737, 0x00000001, + 0x0000002B, 0x00001C26, 0x00000A0C, 0x0000008A, 0x00070050, 0x0000001D, 0x00001946, 0x00001B0B, + 0x00001B0C, 0x00005737, 0x0000008A, 0x0004003D, 0x000000A6, 0x00002FF3, 0x00000CBA, 0x00040063, + 0x00002FF3, 0x00002925, 0x00001946, 0x000200F9, 0x00005445, 0x000200F8, 0x00005445, 0x000100FD, + 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/apply_gamma_pwl_fxaa_luma_cs.h b/src/graphics/shaders/vulkan_spirv/apply_gamma_pwl_fxaa_luma_cs.h new file mode 100644 index 0000000..88fa0d7 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/apply_gamma_pwl_fxaa_luma_cs.h @@ -0,0 +1,247 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 24255 +; Schema: 0 + OpCapability Shader + OpCapability SampledBuffer + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 16 8 1 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_struct_993 Block + OpMemberDecorate %_struct_993 0 Offset 0 + OpDecorate %5759 Binding 0 + OpDecorate %5759 DescriptorSet 1 + OpDecorate %5945 Binding 0 + OpDecorate %5945 DescriptorSet 0 + OpDecorate %3258 NonReadable + OpDecorate %3258 Binding 0 + OpDecorate %3258 DescriptorSet 2 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %float = OpTypeFloat 32 + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 + %uint_0 = OpConstant %uint 0 + %uint_7 = OpConstant %uint 7 + %uint_1 = OpConstant %uint 1 +%float_0_125 = OpConstant %float 0.125 +%float_1_52737048en05 = OpConstant %float 1.52737048e-05 + %v3uint = OpTypeVector %uint 3 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_struct_993 = OpTypeStruct %v2uint +%_ptr_PushConstant__struct_993 = OpTypePointer PushConstant %_struct_993 + %3305 = OpVariable %_ptr_PushConstant__struct_993 PushConstant + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_v2uint = OpTypePointer PushConstant %v2uint + %bool = OpTypeBool + %v2bool = OpTypeVector %bool 2 + %150 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_150 = OpTypePointer UniformConstant %150 + %5759 = OpVariable %_ptr_UniformConstant_150 UniformConstant + %v2int = OpTypeVector %int 2 + %v4float = OpTypeVector %float 4 + %v3float = OpTypeVector %float 3 + %float_1023 = OpConstant %float 1023 + %float_0_5 = OpConstant %float 0.5 + %152 = OpTypeImage %uint Buffer 0 0 0 1 Unknown +%_ptr_UniformConstant_152 = OpTypePointer UniformConstant %152 + %5945 = OpVariable %_ptr_UniformConstant_152 UniformConstant + %uint_3 = OpConstant %uint 3 + %v4uint = OpTypeVector %uint 4 + %uint_2 = OpConstant %uint 2 +%float_0_298999995 = OpConstant %float 0.298999995 +%float_0_587000012 = OpConstant %float 0.587000012 +%float_0_114 = OpConstant %float 0.114 + %1268 = OpConstantComposite %v3float %float_0_298999995 %float_0_587000012 %float_0_114 + %166 = OpTypeImage %float 2D 0 0 0 2 Rgba16f +%_ptr_UniformConstant_166 = OpTypePointer UniformConstant %166 + %3258 = OpVariable %_ptr_UniformConstant_166 UniformConstant + %uint_16 = OpConstant %uint 16 + %uint_8 = OpConstant %uint 8 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_16 %uint_8 %uint_1 + %939 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5 + %10264 = OpUndef %v4float + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %21573 None + OpSwitch %uint_0 %12914 + %12914 = OpLabel + %13761 = OpLoad %v3uint %gl_GlobalInvocationID + %21717 = OpVectorShuffle %v2uint %13761 %13761 0 1 + %7760 = OpAccessChain %_ptr_PushConstant_v2uint %3305 %int_0 + %13378 = OpLoad %v2uint %7760 + %23437 = OpUGreaterThanEqual %v2bool %21717 %13378 + %23076 = OpAny %bool %23437 + OpSelectionMerge %18302 DontFlatten + OpBranchConditional %23076 %21992 %18302 + %21992 = OpLabel + OpBranch %21573 + %18302 = OpLabel + %24004 = OpLoad %150 %5759 + %10533 = OpBitcast %v2int %21717 + %6680 = OpImageFetch %v4float %24004 %10533 Lod %int_0 + %16242 = OpVectorShuffle %v3float %6680 %6680 0 1 2 + %13907 = OpVectorTimesScalar %v3float %16242 %float_1023 + %16889 = OpFAdd %v3float %13907 %939 + %11099 = OpConvertFToU %v3uint %16889 + %19954 = OpLoad %152 %5945 + %23099 = OpCompositeExtract %uint %11099 0 + %17722 = OpShiftRightLogical %uint %23099 %uint_3 + %15968 = OpIMul %uint %17722 %uint_3 + %18268 = OpBitcast %int %15968 + %14598 = OpImageFetch %v4uint %19954 %18268 + %6376 = OpCompositeExtract %uint %14598 0 + %17705 = OpConvertUToF %float %6376 + %12314 = OpBitwiseAnd %uint %23099 %uint_7 + %14345 = OpCompositeExtract %uint %14598 1 + %16230 = OpIMul %uint %12314 %14345 + %17759 = OpConvertUToF %float %16230 + %22854 = OpFMul %float %17759 %float_0_125 + %11948 = OpFAdd %float %17705 %22854 + %7244 = OpFMul %float %11948 %float_1_52737048en05 + %21981 = OpExtInst %float %1 FClamp %7244 %float_0 %float_1 + %8813 = OpCompositeInsert %v4float %21981 %10264 0 + %13846 = OpLoad %152 %5945 + %17466 = OpCompositeExtract %uint %11099 1 + %17798 = OpShiftRightLogical %uint %17466 %uint_3 + %15827 = OpIMul %uint %17798 %uint_3 + %18887 = OpIAdd %uint %15827 %uint_1 + %14460 = OpBitcast %int %18887 + %17829 = OpImageFetch %v4uint %13846 %14460 + %6377 = OpCompositeExtract %uint %17829 0 + %17706 = OpConvertUToF %float %6377 + %12315 = OpBitwiseAnd %uint %17466 %uint_7 + %14346 = OpCompositeExtract %uint %17829 1 + %16231 = OpIMul %uint %12315 %14346 + %17760 = OpConvertUToF %float %16231 + %22855 = OpFMul %float %17760 %float_0_125 + %11949 = OpFAdd %float %17706 %22855 + %7245 = OpFMul %float %11949 %float_1_52737048en05 + %21982 = OpExtInst %float %1 FClamp %7245 %float_0 %float_1 + %8814 = OpCompositeInsert %v4float %21982 %8813 1 + %13847 = OpLoad %152 %5945 + %17467 = OpCompositeExtract %uint %11099 2 + %17799 = OpShiftRightLogical %uint %17467 %uint_3 + %15828 = OpIMul %uint %17799 %uint_3 + %18888 = OpIAdd %uint %15828 %uint_2 + %14461 = OpBitcast %int %18888 + %17830 = OpImageFetch %v4uint %13847 %14461 + %6378 = OpCompositeExtract %uint %17830 0 + %17707 = OpConvertUToF %float %6378 + %12316 = OpBitwiseAnd %uint %17467 %uint_7 + %14347 = OpCompositeExtract %uint %17830 1 + %16232 = OpIMul %uint %12316 %14347 + %17761 = OpConvertUToF %float %16232 + %22856 = OpFMul %float %17761 %float_0_125 + %11950 = OpFAdd %float %17707 %22856 + %7246 = OpFMul %float %11950 %float_1_52737048en05 + %22323 = OpExtInst %float %1 FClamp %7246 %float_0 %float_1 + %6972 = OpCompositeInsert %v4float %22323 %8814 2 + %24254 = OpVectorShuffle %v3float %6972 %6972 0 1 2 + %9657 = OpDot %float %24254 %1268 + %18930 = OpCompositeConstruct %v4float %21981 %21982 %22323 %9657 + %12273 = OpLoad %166 %3258 + OpImageWrite %12273 %10533 %18930 + OpBranch %21573 + %21573 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t apply_gamma_pwl_fxaa_luma_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00005EBF, 0x00000000, 0x00020011, 0x00000001, 0x00020011, + 0x0000002E, 0x0006000B, 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, + 0x00000000, 0x00000001, 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, + 0x00060010, 0x0000161F, 0x00000011, 0x00000010, 0x00000008, 0x00000001, 0x00040047, 0x00000F48, + 0x0000000B, 0x0000001C, 0x00030047, 0x000003E1, 0x00000002, 0x00050048, 0x000003E1, 0x00000000, + 0x00000023, 0x00000000, 0x00040047, 0x0000167F, 0x00000021, 0x00000000, 0x00040047, 0x0000167F, + 0x00000022, 0x00000001, 0x00040047, 0x00001739, 0x00000021, 0x00000000, 0x00040047, 0x00001739, + 0x00000022, 0x00000000, 0x00030047, 0x00000CBA, 0x00000019, 0x00040047, 0x00000CBA, 0x00000021, + 0x00000000, 0x00040047, 0x00000CBA, 0x00000022, 0x00000002, 0x00040047, 0x00000B0F, 0x0000000B, + 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00030016, 0x0000000D, + 0x00000020, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, + 0x00000002, 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, 0x0004002B, 0x0000000D, 0x0000008A, + 0x3F800000, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A1F, + 0x00000007, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000D, 0x000001E0, + 0x3E000000, 0x0004002B, 0x0000000D, 0x000009AA, 0x37802008, 0x00040017, 0x00000014, 0x0000000B, + 0x00000003, 0x00040020, 0x00000291, 0x00000001, 0x00000014, 0x0004003B, 0x00000291, 0x00000F48, + 0x00000001, 0x0003001E, 0x000003E1, 0x00000011, 0x00040020, 0x0000065E, 0x00000009, 0x000003E1, + 0x0004003B, 0x0000065E, 0x00000CE9, 0x00000009, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x0000028E, 0x00000009, 0x00000011, + 0x00020014, 0x00000009, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x00090019, 0x00000096, + 0x0000000D, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00040020, + 0x00000313, 0x00000000, 0x00000096, 0x0004003B, 0x00000313, 0x0000167F, 0x00000000, 0x00040017, + 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x00040017, + 0x00000018, 0x0000000D, 0x00000003, 0x0004002B, 0x0000000D, 0x00000409, 0x447FC000, 0x0004002B, + 0x0000000D, 0x000000FC, 0x3F000000, 0x00090019, 0x00000098, 0x0000000B, 0x00000005, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00040020, 0x00000315, 0x00000000, 0x00000098, + 0x0004003B, 0x00000315, 0x00001739, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000D, 0x00000351, 0x3E991687, 0x0004002B, 0x0000000D, 0x00000458, 0x3F1645A2, + 0x0004002B, 0x0000000D, 0x000001DC, 0x3DE978D5, 0x0006002C, 0x00000018, 0x000004F4, 0x00000351, + 0x00000458, 0x000001DC, 0x00090019, 0x000000A6, 0x0000000D, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000002, 0x00000002, 0x00040020, 0x00000323, 0x00000000, 0x000000A6, 0x0004003B, + 0x00000323, 0x00000CBA, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, + 0x0000000B, 0x00000A22, 0x00000008, 0x0006002C, 0x00000014, 0x00000B0F, 0x00000A3A, 0x00000A22, + 0x00000A0D, 0x0006002C, 0x00000018, 0x000003AB, 0x000000FC, 0x000000FC, 0x000000FC, 0x00030001, + 0x0000001D, 0x00002818, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, + 0x00003B06, 0x000300F7, 0x00005445, 0x00000000, 0x000300FB, 0x00000A0A, 0x00003272, 0x000200F8, + 0x00003272, 0x0004003D, 0x00000014, 0x000035C1, 0x00000F48, 0x0007004F, 0x00000011, 0x000054D5, + 0x000035C1, 0x000035C1, 0x00000000, 0x00000001, 0x00050041, 0x0000028E, 0x00001E50, 0x00000CE9, + 0x00000A0B, 0x0004003D, 0x00000011, 0x00003442, 0x00001E50, 0x000500AE, 0x0000000F, 0x00005B8D, + 0x000054D5, 0x00003442, 0x0004009A, 0x00000009, 0x00005A24, 0x00005B8D, 0x000300F7, 0x0000477E, + 0x00000002, 0x000400FA, 0x00005A24, 0x000055E8, 0x0000477E, 0x000200F8, 0x000055E8, 0x000200F9, + 0x00005445, 0x000200F8, 0x0000477E, 0x0004003D, 0x00000096, 0x00005DC4, 0x0000167F, 0x0004007C, + 0x00000012, 0x00002925, 0x000054D5, 0x0007005F, 0x0000001D, 0x00001A18, 0x00005DC4, 0x00002925, + 0x00000002, 0x00000A0B, 0x0008004F, 0x00000018, 0x00003F72, 0x00001A18, 0x00001A18, 0x00000000, + 0x00000001, 0x00000002, 0x0005008E, 0x00000018, 0x00003653, 0x00003F72, 0x00000409, 0x00050081, + 0x00000018, 0x000041F9, 0x00003653, 0x000003AB, 0x0004006D, 0x00000014, 0x00002B5B, 0x000041F9, + 0x0004003D, 0x00000098, 0x00004DF2, 0x00001739, 0x00050051, 0x0000000B, 0x00005A3B, 0x00002B5B, + 0x00000000, 0x000500C2, 0x0000000B, 0x0000453A, 0x00005A3B, 0x00000A13, 0x00050084, 0x0000000B, + 0x00003E60, 0x0000453A, 0x00000A13, 0x0004007C, 0x0000000C, 0x0000475C, 0x00003E60, 0x0005005F, + 0x00000017, 0x00003906, 0x00004DF2, 0x0000475C, 0x00050051, 0x0000000B, 0x000018E8, 0x00003906, + 0x00000000, 0x00040070, 0x0000000D, 0x00004529, 0x000018E8, 0x000500C7, 0x0000000B, 0x0000301A, + 0x00005A3B, 0x00000A1F, 0x00050051, 0x0000000B, 0x00003809, 0x00003906, 0x00000001, 0x00050084, + 0x0000000B, 0x00003F66, 0x0000301A, 0x00003809, 0x00040070, 0x0000000D, 0x0000455F, 0x00003F66, + 0x00050085, 0x0000000D, 0x00005946, 0x0000455F, 0x000001E0, 0x00050081, 0x0000000D, 0x00002EAC, + 0x00004529, 0x00005946, 0x00050085, 0x0000000D, 0x00001C4C, 0x00002EAC, 0x000009AA, 0x0008000C, + 0x0000000D, 0x000055DD, 0x00000001, 0x0000002B, 0x00001C4C, 0x00000A0C, 0x0000008A, 0x00060052, + 0x0000001D, 0x0000226D, 0x000055DD, 0x00002818, 0x00000000, 0x0004003D, 0x00000098, 0x00003616, + 0x00001739, 0x00050051, 0x0000000B, 0x0000443A, 0x00002B5B, 0x00000001, 0x000500C2, 0x0000000B, + 0x00004586, 0x0000443A, 0x00000A13, 0x00050084, 0x0000000B, 0x00003DD3, 0x00004586, 0x00000A13, + 0x00050080, 0x0000000B, 0x000049C7, 0x00003DD3, 0x00000A0D, 0x0004007C, 0x0000000C, 0x0000387C, + 0x000049C7, 0x0005005F, 0x00000017, 0x000045A5, 0x00003616, 0x0000387C, 0x00050051, 0x0000000B, + 0x000018E9, 0x000045A5, 0x00000000, 0x00040070, 0x0000000D, 0x0000452A, 0x000018E9, 0x000500C7, + 0x0000000B, 0x0000301B, 0x0000443A, 0x00000A1F, 0x00050051, 0x0000000B, 0x0000380A, 0x000045A5, + 0x00000001, 0x00050084, 0x0000000B, 0x00003F67, 0x0000301B, 0x0000380A, 0x00040070, 0x0000000D, + 0x00004560, 0x00003F67, 0x00050085, 0x0000000D, 0x00005947, 0x00004560, 0x000001E0, 0x00050081, + 0x0000000D, 0x00002EAD, 0x0000452A, 0x00005947, 0x00050085, 0x0000000D, 0x00001C4D, 0x00002EAD, + 0x000009AA, 0x0008000C, 0x0000000D, 0x000055DE, 0x00000001, 0x0000002B, 0x00001C4D, 0x00000A0C, + 0x0000008A, 0x00060052, 0x0000001D, 0x0000226E, 0x000055DE, 0x0000226D, 0x00000001, 0x0004003D, + 0x00000098, 0x00003617, 0x00001739, 0x00050051, 0x0000000B, 0x0000443B, 0x00002B5B, 0x00000002, + 0x000500C2, 0x0000000B, 0x00004587, 0x0000443B, 0x00000A13, 0x00050084, 0x0000000B, 0x00003DD4, + 0x00004587, 0x00000A13, 0x00050080, 0x0000000B, 0x000049C8, 0x00003DD4, 0x00000A10, 0x0004007C, + 0x0000000C, 0x0000387D, 0x000049C8, 0x0005005F, 0x00000017, 0x000045A6, 0x00003617, 0x0000387D, + 0x00050051, 0x0000000B, 0x000018EA, 0x000045A6, 0x00000000, 0x00040070, 0x0000000D, 0x0000452B, + 0x000018EA, 0x000500C7, 0x0000000B, 0x0000301C, 0x0000443B, 0x00000A1F, 0x00050051, 0x0000000B, + 0x0000380B, 0x000045A6, 0x00000001, 0x00050084, 0x0000000B, 0x00003F68, 0x0000301C, 0x0000380B, + 0x00040070, 0x0000000D, 0x00004561, 0x00003F68, 0x00050085, 0x0000000D, 0x00005948, 0x00004561, + 0x000001E0, 0x00050081, 0x0000000D, 0x00002EAE, 0x0000452B, 0x00005948, 0x00050085, 0x0000000D, + 0x00001C4E, 0x00002EAE, 0x000009AA, 0x0008000C, 0x0000000D, 0x00005733, 0x00000001, 0x0000002B, + 0x00001C4E, 0x00000A0C, 0x0000008A, 0x00060052, 0x0000001D, 0x00001B3C, 0x00005733, 0x0000226E, + 0x00000002, 0x0008004F, 0x00000018, 0x00005EBE, 0x00001B3C, 0x00001B3C, 0x00000000, 0x00000001, + 0x00000002, 0x00050094, 0x0000000D, 0x000025B9, 0x00005EBE, 0x000004F4, 0x00070050, 0x0000001D, + 0x000049F2, 0x000055DD, 0x000055DE, 0x00005733, 0x000025B9, 0x0004003D, 0x000000A6, 0x00002FF1, + 0x00000CBA, 0x00040063, 0x00002FF1, 0x00002925, 0x000049F2, 0x000200F9, 0x00005445, 0x000200F8, + 0x00005445, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/apply_gamma_pwl_fxaa_luma_ps.h b/src/graphics/shaders/vulkan_spirv/apply_gamma_pwl_fxaa_luma_ps.h new file mode 100644 index 0000000..2e627bb --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/apply_gamma_pwl_fxaa_luma_ps.h @@ -0,0 +1,204 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 24950 +; Schema: 0 + OpCapability Shader + OpCapability SampledBuffer + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %5663 "main" %gl_FragCoord %3258 + OpExecutionMode %5663 OriginUpperLeft + OpDecorate %gl_FragCoord BuiltIn FragCoord + OpDecorate %5759 Binding 0 + OpDecorate %5759 DescriptorSet 1 + OpDecorate %5945 Binding 0 + OpDecorate %5945 DescriptorSet 0 + OpDecorate %3258 Location 0 + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %float = OpTypeFloat 32 + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 + %uint_7 = OpConstant %uint 7 + %uint_1 = OpConstant %uint 1 +%float_0_125 = OpConstant %float 0.125 +%float_1_52737048en05 = OpConstant %float 1.52737048e-05 + %v4float = OpTypeVector %float 4 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%gl_FragCoord = OpVariable %_ptr_Input_v4float Input + %v2float = OpTypeVector %float 2 + %v3uint = OpTypeVector %uint 3 + %150 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_150 = OpTypePointer UniformConstant %150 + %5759 = OpVariable %_ptr_UniformConstant_150 UniformConstant + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %int_0 = OpConstant %int 0 + %v3float = OpTypeVector %float 3 + %float_1023 = OpConstant %float 1023 + %float_0_5 = OpConstant %float 0.5 + %152 = OpTypeImage %uint Buffer 0 0 0 1 Unknown +%_ptr_UniformConstant_152 = OpTypePointer UniformConstant %152 + %5945 = OpVariable %_ptr_UniformConstant_152 UniformConstant + %uint_3 = OpConstant %uint 3 + %v4uint = OpTypeVector %uint 4 + %uint_2 = OpConstant %uint 2 +%float_0_298999995 = OpConstant %float 0.298999995 +%float_0_587000012 = OpConstant %float 0.587000012 +%float_0_114 = OpConstant %float 0.114 + %1268 = OpConstantComposite %v3float %float_0_298999995 %float_0_587000012 %float_0_114 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %3258 = OpVariable %_ptr_Output_v4float Output + %939 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5 + %10264 = OpUndef %v4float + %5663 = OpFunction %void None %1282 + %24949 = OpLabel + %18552 = OpLoad %v4float %gl_FragCoord + %14105 = OpVectorShuffle %v2float %18552 %18552 0 1 + %8667 = OpConvertFToU %v2uint %14105 + %21665 = OpLoad %150 %5759 + %11127 = OpBitcast %v2int %8667 + %6680 = OpImageFetch %v4float %21665 %11127 Lod %int_0 + %16242 = OpVectorShuffle %v3float %6680 %6680 0 1 2 + %13907 = OpVectorTimesScalar %v3float %16242 %float_1023 + %16889 = OpFAdd %v3float %13907 %939 + %11099 = OpConvertFToU %v3uint %16889 + %19954 = OpLoad %152 %5945 + %23099 = OpCompositeExtract %uint %11099 0 + %17722 = OpShiftRightLogical %uint %23099 %uint_3 + %15968 = OpIMul %uint %17722 %uint_3 + %18268 = OpBitcast %int %15968 + %14598 = OpImageFetch %v4uint %19954 %18268 + %6376 = OpCompositeExtract %uint %14598 0 + %17705 = OpConvertUToF %float %6376 + %12314 = OpBitwiseAnd %uint %23099 %uint_7 + %14345 = OpCompositeExtract %uint %14598 1 + %16230 = OpIMul %uint %12314 %14345 + %17759 = OpConvertUToF %float %16230 + %22854 = OpFMul %float %17759 %float_0_125 + %11948 = OpFAdd %float %17705 %22854 + %7244 = OpFMul %float %11948 %float_1_52737048en05 + %21981 = OpExtInst %float %1 FClamp %7244 %float_0 %float_1 + %8813 = OpCompositeInsert %v4float %21981 %10264 0 + %13846 = OpLoad %152 %5945 + %17466 = OpCompositeExtract %uint %11099 1 + %17798 = OpShiftRightLogical %uint %17466 %uint_3 + %15827 = OpIMul %uint %17798 %uint_3 + %18887 = OpIAdd %uint %15827 %uint_1 + %14460 = OpBitcast %int %18887 + %17829 = OpImageFetch %v4uint %13846 %14460 + %6377 = OpCompositeExtract %uint %17829 0 + %17706 = OpConvertUToF %float %6377 + %12315 = OpBitwiseAnd %uint %17466 %uint_7 + %14346 = OpCompositeExtract %uint %17829 1 + %16231 = OpIMul %uint %12315 %14346 + %17760 = OpConvertUToF %float %16231 + %22855 = OpFMul %float %17760 %float_0_125 + %11949 = OpFAdd %float %17706 %22855 + %7245 = OpFMul %float %11949 %float_1_52737048en05 + %21982 = OpExtInst %float %1 FClamp %7245 %float_0 %float_1 + %8814 = OpCompositeInsert %v4float %21982 %8813 1 + %13847 = OpLoad %152 %5945 + %17467 = OpCompositeExtract %uint %11099 2 + %17799 = OpShiftRightLogical %uint %17467 %uint_3 + %15828 = OpIMul %uint %17799 %uint_3 + %18888 = OpIAdd %uint %15828 %uint_2 + %14461 = OpBitcast %int %18888 + %17830 = OpImageFetch %v4uint %13847 %14461 + %6378 = OpCompositeExtract %uint %17830 0 + %17707 = OpConvertUToF %float %6378 + %12316 = OpBitwiseAnd %uint %17467 %uint_7 + %14347 = OpCompositeExtract %uint %17830 1 + %16232 = OpIMul %uint %12316 %14347 + %17761 = OpConvertUToF %float %16232 + %22856 = OpFMul %float %17761 %float_0_125 + %11950 = OpFAdd %float %17707 %22856 + %7246 = OpFMul %float %11950 %float_1_52737048en05 + %22323 = OpExtInst %float %1 FClamp %7246 %float_0 %float_1 + %6972 = OpCompositeInsert %v4float %22323 %8814 2 + %24254 = OpVectorShuffle %v3float %6972 %6972 0 1 2 + %9676 = OpDot %float %24254 %1268 + %21683 = OpCompositeConstruct %v4float %21981 %21982 %22323 %9676 + OpStore %3258 %21683 + OpReturn + OpFunctionEnd +#endif + +const uint32_t apply_gamma_pwl_fxaa_luma_ps[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006176, 0x00000000, 0x00020011, 0x00000001, 0x00020011, + 0x0000002E, 0x0006000B, 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, + 0x00000000, 0x00000001, 0x0007000F, 0x00000004, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000C93, + 0x00000CBA, 0x00030010, 0x0000161F, 0x00000007, 0x00040047, 0x00000C93, 0x0000000B, 0x0000000F, + 0x00040047, 0x0000167F, 0x00000021, 0x00000000, 0x00040047, 0x0000167F, 0x00000022, 0x00000001, + 0x00040047, 0x00001739, 0x00000021, 0x00000000, 0x00040047, 0x00001739, 0x00000022, 0x00000000, + 0x00040047, 0x00000CBA, 0x0000001E, 0x00000000, 0x00020013, 0x00000008, 0x00030021, 0x00000502, + 0x00000008, 0x00030016, 0x0000000D, 0x00000020, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, + 0x0004002B, 0x0000000D, 0x0000008A, 0x3F800000, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000D, 0x000001E0, 0x3E000000, + 0x0004002B, 0x0000000D, 0x000009AA, 0x37802008, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, + 0x00040020, 0x0000029A, 0x00000001, 0x0000001D, 0x0004003B, 0x0000029A, 0x00000C93, 0x00000001, + 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x00090019, 0x00000096, 0x0000000D, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00040020, 0x00000313, 0x00000000, 0x00000096, 0x0004003B, 0x00000313, 0x0000167F, + 0x00000000, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, + 0x00000002, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040017, 0x00000018, 0x0000000D, + 0x00000003, 0x0004002B, 0x0000000D, 0x00000409, 0x447FC000, 0x0004002B, 0x0000000D, 0x000000FC, + 0x3F000000, 0x00090019, 0x00000098, 0x0000000B, 0x00000005, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00040020, 0x00000315, 0x00000000, 0x00000098, 0x0004003B, 0x00000315, + 0x00001739, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000D, + 0x00000351, 0x3E991687, 0x0004002B, 0x0000000D, 0x00000458, 0x3F1645A2, 0x0004002B, 0x0000000D, + 0x000001DC, 0x3DE978D5, 0x0006002C, 0x00000018, 0x000004F4, 0x00000351, 0x00000458, 0x000001DC, + 0x00040020, 0x0000029B, 0x00000003, 0x0000001D, 0x0004003B, 0x0000029B, 0x00000CBA, 0x00000003, + 0x0006002C, 0x00000018, 0x000003AB, 0x000000FC, 0x000000FC, 0x000000FC, 0x00030001, 0x0000001D, + 0x00002818, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00006175, + 0x0004003D, 0x0000001D, 0x00004878, 0x00000C93, 0x0007004F, 0x00000013, 0x00003719, 0x00004878, + 0x00004878, 0x00000000, 0x00000001, 0x0004006D, 0x00000011, 0x000021DB, 0x00003719, 0x0004003D, + 0x00000096, 0x000054A1, 0x0000167F, 0x0004007C, 0x00000012, 0x00002B77, 0x000021DB, 0x0007005F, + 0x0000001D, 0x00001A18, 0x000054A1, 0x00002B77, 0x00000002, 0x00000A0B, 0x0008004F, 0x00000018, + 0x00003F72, 0x00001A18, 0x00001A18, 0x00000000, 0x00000001, 0x00000002, 0x0005008E, 0x00000018, + 0x00003653, 0x00003F72, 0x00000409, 0x00050081, 0x00000018, 0x000041F9, 0x00003653, 0x000003AB, + 0x0004006D, 0x00000014, 0x00002B5B, 0x000041F9, 0x0004003D, 0x00000098, 0x00004DF2, 0x00001739, + 0x00050051, 0x0000000B, 0x00005A3B, 0x00002B5B, 0x00000000, 0x000500C2, 0x0000000B, 0x0000453A, + 0x00005A3B, 0x00000A13, 0x00050084, 0x0000000B, 0x00003E60, 0x0000453A, 0x00000A13, 0x0004007C, + 0x0000000C, 0x0000475C, 0x00003E60, 0x0005005F, 0x00000017, 0x00003906, 0x00004DF2, 0x0000475C, + 0x00050051, 0x0000000B, 0x000018E8, 0x00003906, 0x00000000, 0x00040070, 0x0000000D, 0x00004529, + 0x000018E8, 0x000500C7, 0x0000000B, 0x0000301A, 0x00005A3B, 0x00000A1F, 0x00050051, 0x0000000B, + 0x00003809, 0x00003906, 0x00000001, 0x00050084, 0x0000000B, 0x00003F66, 0x0000301A, 0x00003809, + 0x00040070, 0x0000000D, 0x0000455F, 0x00003F66, 0x00050085, 0x0000000D, 0x00005946, 0x0000455F, + 0x000001E0, 0x00050081, 0x0000000D, 0x00002EAC, 0x00004529, 0x00005946, 0x00050085, 0x0000000D, + 0x00001C4C, 0x00002EAC, 0x000009AA, 0x0008000C, 0x0000000D, 0x000055DD, 0x00000001, 0x0000002B, + 0x00001C4C, 0x00000A0C, 0x0000008A, 0x00060052, 0x0000001D, 0x0000226D, 0x000055DD, 0x00002818, + 0x00000000, 0x0004003D, 0x00000098, 0x00003616, 0x00001739, 0x00050051, 0x0000000B, 0x0000443A, + 0x00002B5B, 0x00000001, 0x000500C2, 0x0000000B, 0x00004586, 0x0000443A, 0x00000A13, 0x00050084, + 0x0000000B, 0x00003DD3, 0x00004586, 0x00000A13, 0x00050080, 0x0000000B, 0x000049C7, 0x00003DD3, + 0x00000A0D, 0x0004007C, 0x0000000C, 0x0000387C, 0x000049C7, 0x0005005F, 0x00000017, 0x000045A5, + 0x00003616, 0x0000387C, 0x00050051, 0x0000000B, 0x000018E9, 0x000045A5, 0x00000000, 0x00040070, + 0x0000000D, 0x0000452A, 0x000018E9, 0x000500C7, 0x0000000B, 0x0000301B, 0x0000443A, 0x00000A1F, + 0x00050051, 0x0000000B, 0x0000380A, 0x000045A5, 0x00000001, 0x00050084, 0x0000000B, 0x00003F67, + 0x0000301B, 0x0000380A, 0x00040070, 0x0000000D, 0x00004560, 0x00003F67, 0x00050085, 0x0000000D, + 0x00005947, 0x00004560, 0x000001E0, 0x00050081, 0x0000000D, 0x00002EAD, 0x0000452A, 0x00005947, + 0x00050085, 0x0000000D, 0x00001C4D, 0x00002EAD, 0x000009AA, 0x0008000C, 0x0000000D, 0x000055DE, + 0x00000001, 0x0000002B, 0x00001C4D, 0x00000A0C, 0x0000008A, 0x00060052, 0x0000001D, 0x0000226E, + 0x000055DE, 0x0000226D, 0x00000001, 0x0004003D, 0x00000098, 0x00003617, 0x00001739, 0x00050051, + 0x0000000B, 0x0000443B, 0x00002B5B, 0x00000002, 0x000500C2, 0x0000000B, 0x00004587, 0x0000443B, + 0x00000A13, 0x00050084, 0x0000000B, 0x00003DD4, 0x00004587, 0x00000A13, 0x00050080, 0x0000000B, + 0x000049C8, 0x00003DD4, 0x00000A10, 0x0004007C, 0x0000000C, 0x0000387D, 0x000049C8, 0x0005005F, + 0x00000017, 0x000045A6, 0x00003617, 0x0000387D, 0x00050051, 0x0000000B, 0x000018EA, 0x000045A6, + 0x00000000, 0x00040070, 0x0000000D, 0x0000452B, 0x000018EA, 0x000500C7, 0x0000000B, 0x0000301C, + 0x0000443B, 0x00000A1F, 0x00050051, 0x0000000B, 0x0000380B, 0x000045A6, 0x00000001, 0x00050084, + 0x0000000B, 0x00003F68, 0x0000301C, 0x0000380B, 0x00040070, 0x0000000D, 0x00004561, 0x00003F68, + 0x00050085, 0x0000000D, 0x00005948, 0x00004561, 0x000001E0, 0x00050081, 0x0000000D, 0x00002EAE, + 0x0000452B, 0x00005948, 0x00050085, 0x0000000D, 0x00001C4E, 0x00002EAE, 0x000009AA, 0x0008000C, + 0x0000000D, 0x00005733, 0x00000001, 0x0000002B, 0x00001C4E, 0x00000A0C, 0x0000008A, 0x00060052, + 0x0000001D, 0x00001B3C, 0x00005733, 0x0000226E, 0x00000002, 0x0008004F, 0x00000018, 0x00005EBE, + 0x00001B3C, 0x00001B3C, 0x00000000, 0x00000001, 0x00000002, 0x00050094, 0x0000000D, 0x000025CC, + 0x00005EBE, 0x000004F4, 0x00070050, 0x0000001D, 0x000054B3, 0x000055DD, 0x000055DE, 0x00005733, + 0x000025CC, 0x0003003E, 0x00000CBA, 0x000054B3, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/apply_gamma_pwl_ps.h b/src/graphics/shaders/vulkan_spirv/apply_gamma_pwl_ps.h new file mode 100644 index 0000000..f334871 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/apply_gamma_pwl_ps.h @@ -0,0 +1,188 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 24950 +; Schema: 0 + OpCapability Shader + OpCapability SampledBuffer + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %5663 "main" %gl_FragCoord %3258 + OpExecutionMode %5663 OriginUpperLeft + OpDecorate %gl_FragCoord BuiltIn FragCoord + OpDecorate %5759 Binding 0 + OpDecorate %5759 DescriptorSet 1 + OpDecorate %5945 Binding 0 + OpDecorate %5945 DescriptorSet 0 + OpDecorate %3258 Location 0 + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %float = OpTypeFloat 32 + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 + %uint_7 = OpConstant %uint 7 + %uint_1 = OpConstant %uint 1 +%float_0_125 = OpConstant %float 0.125 +%float_1_52737048en05 = OpConstant %float 1.52737048e-05 + %v4float = OpTypeVector %float 4 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%gl_FragCoord = OpVariable %_ptr_Input_v4float Input + %v2float = OpTypeVector %float 2 + %v3uint = OpTypeVector %uint 3 + %150 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_150 = OpTypePointer UniformConstant %150 + %5759 = OpVariable %_ptr_UniformConstant_150 UniformConstant + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %int_0 = OpConstant %int 0 + %v3float = OpTypeVector %float 3 + %float_1023 = OpConstant %float 1023 + %float_0_5 = OpConstant %float 0.5 + %152 = OpTypeImage %uint Buffer 0 0 0 1 Unknown +%_ptr_UniformConstant_152 = OpTypePointer UniformConstant %152 + %5945 = OpVariable %_ptr_UniformConstant_152 UniformConstant + %uint_3 = OpConstant %uint 3 + %v4uint = OpTypeVector %uint 4 + %uint_2 = OpConstant %uint 2 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %3258 = OpVariable %_ptr_Output_v4float Output + %939 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5 + %5663 = OpFunction %void None %1282 + %24949 = OpLabel + %18552 = OpLoad %v4float %gl_FragCoord + %14105 = OpVectorShuffle %v2float %18552 %18552 0 1 + %8667 = OpConvertFToU %v2uint %14105 + %21665 = OpLoad %150 %5759 + %11127 = OpBitcast %v2int %8667 + %6680 = OpImageFetch %v4float %21665 %11127 Lod %int_0 + %16242 = OpVectorShuffle %v3float %6680 %6680 0 1 2 + %13907 = OpVectorTimesScalar %v3float %16242 %float_1023 + %16889 = OpFAdd %v3float %13907 %939 + %11099 = OpConvertFToU %v3uint %16889 + %19954 = OpLoad %152 %5945 + %23099 = OpCompositeExtract %uint %11099 0 + %17722 = OpShiftRightLogical %uint %23099 %uint_3 + %15968 = OpIMul %uint %17722 %uint_3 + %18268 = OpBitcast %int %15968 + %14598 = OpImageFetch %v4uint %19954 %18268 + %6376 = OpCompositeExtract %uint %14598 0 + %17705 = OpConvertUToF %float %6376 + %12314 = OpBitwiseAnd %uint %23099 %uint_7 + %14345 = OpCompositeExtract %uint %14598 1 + %16230 = OpIMul %uint %12314 %14345 + %17759 = OpConvertUToF %float %16230 + %22854 = OpFMul %float %17759 %float_0_125 + %11948 = OpFAdd %float %17705 %22854 + %6845 = OpFMul %float %11948 %float_1_52737048en05 + %6923 = OpExtInst %float %1 FClamp %6845 %float_0 %float_1 + %14371 = OpLoad %152 %5945 + %12884 = OpCompositeExtract %uint %11099 1 + %17798 = OpShiftRightLogical %uint %12884 %uint_3 + %15827 = OpIMul %uint %17798 %uint_3 + %18887 = OpIAdd %uint %15827 %uint_1 + %14460 = OpBitcast %int %18887 + %17829 = OpImageFetch %v4uint %14371 %14460 + %6377 = OpCompositeExtract %uint %17829 0 + %17706 = OpConvertUToF %float %6377 + %12315 = OpBitwiseAnd %uint %12884 %uint_7 + %14346 = OpCompositeExtract %uint %17829 1 + %16231 = OpIMul %uint %12315 %14346 + %17760 = OpConvertUToF %float %16231 + %22855 = OpFMul %float %17760 %float_0_125 + %11949 = OpFAdd %float %17706 %22855 + %6846 = OpFMul %float %11949 %float_1_52737048en05 + %6924 = OpExtInst %float %1 FClamp %6846 %float_0 %float_1 + %14372 = OpLoad %152 %5945 + %12885 = OpCompositeExtract %uint %11099 2 + %17799 = OpShiftRightLogical %uint %12885 %uint_3 + %15828 = OpIMul %uint %17799 %uint_3 + %18888 = OpIAdd %uint %15828 %uint_2 + %14461 = OpBitcast %int %18888 + %17830 = OpImageFetch %v4uint %14372 %14461 + %6378 = OpCompositeExtract %uint %17830 0 + %17707 = OpConvertUToF %float %6378 + %12316 = OpBitwiseAnd %uint %12885 %uint_7 + %14347 = OpCompositeExtract %uint %17830 1 + %16232 = OpIMul %uint %12316 %14347 + %17761 = OpConvertUToF %float %16232 + %22856 = OpFMul %float %17761 %float_0_125 + %11950 = OpFAdd %float %17707 %22856 + %7206 = OpFMul %float %11950 %float_1_52737048en05 + %22346 = OpExtInst %float %1 FClamp %7206 %float_0 %float_1 + %9223 = OpCompositeConstruct %v4float %6923 %6924 %22346 %float_1 + OpStore %3258 %9223 + OpReturn + OpFunctionEnd +#endif + +const uint32_t apply_gamma_pwl_ps[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006176, 0x00000000, 0x00020011, 0x00000001, 0x00020011, + 0x0000002E, 0x0006000B, 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, + 0x00000000, 0x00000001, 0x0007000F, 0x00000004, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000C93, + 0x00000CBA, 0x00030010, 0x0000161F, 0x00000007, 0x00040047, 0x00000C93, 0x0000000B, 0x0000000F, + 0x00040047, 0x0000167F, 0x00000021, 0x00000000, 0x00040047, 0x0000167F, 0x00000022, 0x00000001, + 0x00040047, 0x00001739, 0x00000021, 0x00000000, 0x00040047, 0x00001739, 0x00000022, 0x00000000, + 0x00040047, 0x00000CBA, 0x0000001E, 0x00000000, 0x00020013, 0x00000008, 0x00030021, 0x00000502, + 0x00000008, 0x00030016, 0x0000000D, 0x00000020, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, + 0x0004002B, 0x0000000D, 0x0000008A, 0x3F800000, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000D, 0x000001E0, 0x3E000000, + 0x0004002B, 0x0000000D, 0x000009AA, 0x37802008, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, + 0x00040020, 0x0000029A, 0x00000001, 0x0000001D, 0x0004003B, 0x0000029A, 0x00000C93, 0x00000001, + 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x00090019, 0x00000096, 0x0000000D, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00040020, 0x00000313, 0x00000000, 0x00000096, 0x0004003B, 0x00000313, 0x0000167F, + 0x00000000, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, + 0x00000002, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040017, 0x00000018, 0x0000000D, + 0x00000003, 0x0004002B, 0x0000000D, 0x00000409, 0x447FC000, 0x0004002B, 0x0000000D, 0x000000FC, + 0x3F000000, 0x00090019, 0x00000098, 0x0000000B, 0x00000005, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00040020, 0x00000315, 0x00000000, 0x00000098, 0x0004003B, 0x00000315, + 0x00001739, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x00040020, 0x0000029B, + 0x00000003, 0x0000001D, 0x0004003B, 0x0000029B, 0x00000CBA, 0x00000003, 0x0006002C, 0x00000018, + 0x000003AB, 0x000000FC, 0x000000FC, 0x000000FC, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, + 0x00000502, 0x000200F8, 0x00006175, 0x0004003D, 0x0000001D, 0x00004878, 0x00000C93, 0x0007004F, + 0x00000013, 0x00003719, 0x00004878, 0x00004878, 0x00000000, 0x00000001, 0x0004006D, 0x00000011, + 0x000021DB, 0x00003719, 0x0004003D, 0x00000096, 0x000054A1, 0x0000167F, 0x0004007C, 0x00000012, + 0x00002B77, 0x000021DB, 0x0007005F, 0x0000001D, 0x00001A18, 0x000054A1, 0x00002B77, 0x00000002, + 0x00000A0B, 0x0008004F, 0x00000018, 0x00003F72, 0x00001A18, 0x00001A18, 0x00000000, 0x00000001, + 0x00000002, 0x0005008E, 0x00000018, 0x00003653, 0x00003F72, 0x00000409, 0x00050081, 0x00000018, + 0x000041F9, 0x00003653, 0x000003AB, 0x0004006D, 0x00000014, 0x00002B5B, 0x000041F9, 0x0004003D, + 0x00000098, 0x00004DF2, 0x00001739, 0x00050051, 0x0000000B, 0x00005A3B, 0x00002B5B, 0x00000000, + 0x000500C2, 0x0000000B, 0x0000453A, 0x00005A3B, 0x00000A13, 0x00050084, 0x0000000B, 0x00003E60, + 0x0000453A, 0x00000A13, 0x0004007C, 0x0000000C, 0x0000475C, 0x00003E60, 0x0005005F, 0x00000017, + 0x00003906, 0x00004DF2, 0x0000475C, 0x00050051, 0x0000000B, 0x000018E8, 0x00003906, 0x00000000, + 0x00040070, 0x0000000D, 0x00004529, 0x000018E8, 0x000500C7, 0x0000000B, 0x0000301A, 0x00005A3B, + 0x00000A1F, 0x00050051, 0x0000000B, 0x00003809, 0x00003906, 0x00000001, 0x00050084, 0x0000000B, + 0x00003F66, 0x0000301A, 0x00003809, 0x00040070, 0x0000000D, 0x0000455F, 0x00003F66, 0x00050085, + 0x0000000D, 0x00005946, 0x0000455F, 0x000001E0, 0x00050081, 0x0000000D, 0x00002EAC, 0x00004529, + 0x00005946, 0x00050085, 0x0000000D, 0x00001ABD, 0x00002EAC, 0x000009AA, 0x0008000C, 0x0000000D, + 0x00001B0B, 0x00000001, 0x0000002B, 0x00001ABD, 0x00000A0C, 0x0000008A, 0x0004003D, 0x00000098, + 0x00003823, 0x00001739, 0x00050051, 0x0000000B, 0x00003254, 0x00002B5B, 0x00000001, 0x000500C2, + 0x0000000B, 0x00004586, 0x00003254, 0x00000A13, 0x00050084, 0x0000000B, 0x00003DD3, 0x00004586, + 0x00000A13, 0x00050080, 0x0000000B, 0x000049C7, 0x00003DD3, 0x00000A0D, 0x0004007C, 0x0000000C, + 0x0000387C, 0x000049C7, 0x0005005F, 0x00000017, 0x000045A5, 0x00003823, 0x0000387C, 0x00050051, + 0x0000000B, 0x000018E9, 0x000045A5, 0x00000000, 0x00040070, 0x0000000D, 0x0000452A, 0x000018E9, + 0x000500C7, 0x0000000B, 0x0000301B, 0x00003254, 0x00000A1F, 0x00050051, 0x0000000B, 0x0000380A, + 0x000045A5, 0x00000001, 0x00050084, 0x0000000B, 0x00003F67, 0x0000301B, 0x0000380A, 0x00040070, + 0x0000000D, 0x00004560, 0x00003F67, 0x00050085, 0x0000000D, 0x00005947, 0x00004560, 0x000001E0, + 0x00050081, 0x0000000D, 0x00002EAD, 0x0000452A, 0x00005947, 0x00050085, 0x0000000D, 0x00001ABE, + 0x00002EAD, 0x000009AA, 0x0008000C, 0x0000000D, 0x00001B0C, 0x00000001, 0x0000002B, 0x00001ABE, + 0x00000A0C, 0x0000008A, 0x0004003D, 0x00000098, 0x00003824, 0x00001739, 0x00050051, 0x0000000B, + 0x00003255, 0x00002B5B, 0x00000002, 0x000500C2, 0x0000000B, 0x00004587, 0x00003255, 0x00000A13, + 0x00050084, 0x0000000B, 0x00003DD4, 0x00004587, 0x00000A13, 0x00050080, 0x0000000B, 0x000049C8, + 0x00003DD4, 0x00000A10, 0x0004007C, 0x0000000C, 0x0000387D, 0x000049C8, 0x0005005F, 0x00000017, + 0x000045A6, 0x00003824, 0x0000387D, 0x00050051, 0x0000000B, 0x000018EA, 0x000045A6, 0x00000000, + 0x00040070, 0x0000000D, 0x0000452B, 0x000018EA, 0x000500C7, 0x0000000B, 0x0000301C, 0x00003255, + 0x00000A1F, 0x00050051, 0x0000000B, 0x0000380B, 0x000045A6, 0x00000001, 0x00050084, 0x0000000B, + 0x00003F68, 0x0000301C, 0x0000380B, 0x00040070, 0x0000000D, 0x00004561, 0x00003F68, 0x00050085, + 0x0000000D, 0x00005948, 0x00004561, 0x000001E0, 0x00050081, 0x0000000D, 0x00002EAE, 0x0000452B, + 0x00005948, 0x00050085, 0x0000000D, 0x00001C26, 0x00002EAE, 0x000009AA, 0x0008000C, 0x0000000D, + 0x0000574A, 0x00000001, 0x0000002B, 0x00001C26, 0x00000A0C, 0x0000008A, 0x00070050, 0x0000001D, + 0x00002407, 0x00001B0B, 0x00001B0C, 0x0000574A, 0x0000008A, 0x0003003E, 0x00000CBA, 0x00002407, + 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/apply_gamma_table_cs.h b/src/graphics/shaders/vulkan_spirv/apply_gamma_table_cs.h new file mode 100644 index 0000000..31759cd --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/apply_gamma_table_cs.h @@ -0,0 +1,164 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 24689 +; Schema: 0 + OpCapability Shader + OpCapability SampledBuffer + OpCapability StorageImageExtendedFormats + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 16 8 1 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_struct_993 Block + OpMemberDecorate %_struct_993 0 Offset 0 + OpDecorate %5759 Binding 0 + OpDecorate %5759 DescriptorSet 1 + OpDecorate %5945 Binding 0 + OpDecorate %5945 DescriptorSet 0 + OpDecorate %3258 NonReadable + OpDecorate %3258 Binding 0 + OpDecorate %3258 DescriptorSet 2 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_struct_993 = OpTypeStruct %v2uint +%_ptr_PushConstant__struct_993 = OpTypePointer PushConstant %_struct_993 + %3305 = OpVariable %_ptr_PushConstant__struct_993 PushConstant + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_v2uint = OpTypePointer PushConstant %v2uint + %bool = OpTypeBool + %v2bool = OpTypeVector %bool 2 + %float = OpTypeFloat 32 + %150 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_150 = OpTypePointer UniformConstant %150 + %5759 = OpVariable %_ptr_UniformConstant_150 UniformConstant + %v2int = OpTypeVector %int 2 + %v4float = OpTypeVector %float 4 + %v3float = OpTypeVector %float 3 + %float_255 = OpConstant %float 255 + %float_0_5 = OpConstant %float 0.5 + %154 = OpTypeImage %float Buffer 0 0 0 1 Unknown +%_ptr_UniformConstant_154 = OpTypePointer UniformConstant %154 + %5945 = OpVariable %_ptr_UniformConstant_154 UniformConstant + %uint_0 = OpConstant %uint 0 + %uint_1 = OpConstant %uint 1 + %float_1 = OpConstant %float 1 + %166 = OpTypeImage %float 2D 0 0 0 2 Rgb10A2 +%_ptr_UniformConstant_166 = OpTypePointer UniformConstant %166 + %3258 = OpVariable %_ptr_UniformConstant_166 UniformConstant + %uint_16 = OpConstant %uint 16 + %uint_8 = OpConstant %uint 8 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_16 %uint_8 %uint_1 + %939 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %21573 None + OpSwitch %uint_0 %12914 + %12914 = OpLabel + %13761 = OpLoad %v3uint %gl_GlobalInvocationID + %21717 = OpVectorShuffle %v2uint %13761 %13761 0 1 + %7760 = OpAccessChain %_ptr_PushConstant_v2uint %3305 %int_0 + %13378 = OpLoad %v2uint %7760 + %23437 = OpUGreaterThanEqual %v2bool %21717 %13378 + %23076 = OpAny %bool %23437 + OpSelectionMerge %18302 DontFlatten + OpBranchConditional %23076 %21992 %18302 + %21992 = OpLabel + OpBranch %21573 + %18302 = OpLabel + %24004 = OpLoad %150 %5759 + %10533 = OpBitcast %v2int %21717 + %6680 = OpImageFetch %v4float %24004 %10533 Lod %int_0 + %16242 = OpVectorShuffle %v3float %6680 %6680 0 1 2 + %13907 = OpVectorTimesScalar %v3float %16242 %float_255 + %16889 = OpFAdd %v3float %13907 %939 + %11099 = OpConvertFToU %v3uint %16889 + %18624 = OpLoad %154 %5945 + %15435 = OpCompositeExtract %uint %11099 0 + %24686 = OpBitcast %int %15435 + %8011 = OpImageFetch %v4float %18624 %24686 + %12957 = OpCompositeExtract %float %8011 2 + %18146 = OpLoad %154 %5945 + %12224 = OpCompositeExtract %uint %11099 1 + %24687 = OpBitcast %int %12224 + %8012 = OpImageFetch %v4float %18146 %24687 + %12958 = OpCompositeExtract %float %8012 1 + %18147 = OpLoad %154 %5945 + %12225 = OpCompositeExtract %uint %11099 2 + %24688 = OpBitcast %int %12225 + %8372 = OpImageFetch %v4float %18147 %24688 + %9290 = OpCompositeExtract %float %8372 0 + %18032 = OpCompositeConstruct %v4float %12957 %12958 %9290 %float_1 + %19279 = OpLoad %166 %3258 + OpImageWrite %19279 %10533 %18032 + OpBranch %21573 + %21573 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t apply_gamma_table_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006071, 0x00000000, 0x00020011, 0x00000001, 0x00020011, + 0x0000002E, 0x00020011, 0x00000031, 0x0006000B, 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, + 0x00000000, 0x0003000E, 0x00000000, 0x00000001, 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, + 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, 0x00000011, 0x00000010, 0x00000008, 0x00000001, + 0x00040047, 0x00000F48, 0x0000000B, 0x0000001C, 0x00030047, 0x000003E1, 0x00000002, 0x00050048, + 0x000003E1, 0x00000000, 0x00000023, 0x00000000, 0x00040047, 0x0000167F, 0x00000021, 0x00000000, + 0x00040047, 0x0000167F, 0x00000022, 0x00000001, 0x00040047, 0x00001739, 0x00000021, 0x00000000, + 0x00040047, 0x00001739, 0x00000022, 0x00000000, 0x00030047, 0x00000CBA, 0x00000019, 0x00040047, + 0x00000CBA, 0x00000021, 0x00000000, 0x00040047, 0x00000CBA, 0x00000022, 0x00000002, 0x00040047, + 0x00000B0F, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, + 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, + 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x00040020, 0x00000291, 0x00000001, 0x00000014, + 0x0004003B, 0x00000291, 0x00000F48, 0x00000001, 0x0003001E, 0x000003E1, 0x00000011, 0x00040020, + 0x0000065E, 0x00000009, 0x000003E1, 0x0004003B, 0x0000065E, 0x00000CE9, 0x00000009, 0x00040015, + 0x0000000C, 0x00000020, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, + 0x0000028E, 0x00000009, 0x00000011, 0x00020014, 0x00000009, 0x00040017, 0x0000000F, 0x00000009, + 0x00000002, 0x00030016, 0x0000000D, 0x00000020, 0x00090019, 0x00000096, 0x0000000D, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00040020, 0x00000313, 0x00000000, + 0x00000096, 0x0004003B, 0x00000313, 0x0000167F, 0x00000000, 0x00040017, 0x00000012, 0x0000000C, + 0x00000002, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x00040017, 0x00000018, 0x0000000D, + 0x00000003, 0x0004002B, 0x0000000D, 0x00000540, 0x437F0000, 0x0004002B, 0x0000000D, 0x000000FC, + 0x3F000000, 0x00090019, 0x0000009A, 0x0000000D, 0x00000005, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00040020, 0x00000317, 0x00000000, 0x0000009A, 0x0004003B, 0x00000317, + 0x00001739, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, + 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000D, 0x0000008A, 0x3F800000, 0x00090019, 0x000000A6, + 0x0000000D, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x0000000B, 0x00040020, + 0x00000323, 0x00000000, 0x000000A6, 0x0004003B, 0x00000323, 0x00000CBA, 0x00000000, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0006002C, + 0x00000014, 0x00000B0F, 0x00000A3A, 0x00000A22, 0x00000A0D, 0x0006002C, 0x00000018, 0x000003AB, + 0x000000FC, 0x000000FC, 0x000000FC, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, + 0x000200F8, 0x00003B06, 0x000300F7, 0x00005445, 0x00000000, 0x000300FB, 0x00000A0A, 0x00003272, + 0x000200F8, 0x00003272, 0x0004003D, 0x00000014, 0x000035C1, 0x00000F48, 0x0007004F, 0x00000011, + 0x000054D5, 0x000035C1, 0x000035C1, 0x00000000, 0x00000001, 0x00050041, 0x0000028E, 0x00001E50, + 0x00000CE9, 0x00000A0B, 0x0004003D, 0x00000011, 0x00003442, 0x00001E50, 0x000500AE, 0x0000000F, + 0x00005B8D, 0x000054D5, 0x00003442, 0x0004009A, 0x00000009, 0x00005A24, 0x00005B8D, 0x000300F7, + 0x0000477E, 0x00000002, 0x000400FA, 0x00005A24, 0x000055E8, 0x0000477E, 0x000200F8, 0x000055E8, + 0x000200F9, 0x00005445, 0x000200F8, 0x0000477E, 0x0004003D, 0x00000096, 0x00005DC4, 0x0000167F, + 0x0004007C, 0x00000012, 0x00002925, 0x000054D5, 0x0007005F, 0x0000001D, 0x00001A18, 0x00005DC4, + 0x00002925, 0x00000002, 0x00000A0B, 0x0008004F, 0x00000018, 0x00003F72, 0x00001A18, 0x00001A18, + 0x00000000, 0x00000001, 0x00000002, 0x0005008E, 0x00000018, 0x00003653, 0x00003F72, 0x00000540, + 0x00050081, 0x00000018, 0x000041F9, 0x00003653, 0x000003AB, 0x0004006D, 0x00000014, 0x00002B5B, + 0x000041F9, 0x0004003D, 0x0000009A, 0x000048C0, 0x00001739, 0x00050051, 0x0000000B, 0x00003C4B, + 0x00002B5B, 0x00000000, 0x0004007C, 0x0000000C, 0x0000606E, 0x00003C4B, 0x0005005F, 0x0000001D, + 0x00001F4B, 0x000048C0, 0x0000606E, 0x00050051, 0x0000000D, 0x0000329D, 0x00001F4B, 0x00000002, + 0x0004003D, 0x0000009A, 0x000046E2, 0x00001739, 0x00050051, 0x0000000B, 0x00002FC0, 0x00002B5B, + 0x00000001, 0x0004007C, 0x0000000C, 0x0000606F, 0x00002FC0, 0x0005005F, 0x0000001D, 0x00001F4C, + 0x000046E2, 0x0000606F, 0x00050051, 0x0000000D, 0x0000329E, 0x00001F4C, 0x00000001, 0x0004003D, + 0x0000009A, 0x000046E3, 0x00001739, 0x00050051, 0x0000000B, 0x00002FC1, 0x00002B5B, 0x00000002, + 0x0004007C, 0x0000000C, 0x00006070, 0x00002FC1, 0x0005005F, 0x0000001D, 0x000020B4, 0x000046E3, + 0x00006070, 0x00050051, 0x0000000D, 0x0000244A, 0x000020B4, 0x00000000, 0x00070050, 0x0000001D, + 0x00004670, 0x0000329D, 0x0000329E, 0x0000244A, 0x0000008A, 0x0004003D, 0x000000A6, 0x00004B4F, + 0x00000CBA, 0x00040063, 0x00004B4F, 0x00002925, 0x00004670, 0x000200F9, 0x00005445, 0x000200F8, + 0x00005445, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/apply_gamma_table_fxaa_luma_cs.h b/src/graphics/shaders/vulkan_spirv/apply_gamma_table_fxaa_luma_cs.h new file mode 100644 index 0000000..25a7220 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/apply_gamma_table_fxaa_luma_cs.h @@ -0,0 +1,178 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 24802 +; Schema: 0 + OpCapability Shader + OpCapability SampledBuffer + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 16 8 1 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_struct_993 Block + OpMemberDecorate %_struct_993 0 Offset 0 + OpDecorate %5759 Binding 0 + OpDecorate %5759 DescriptorSet 1 + OpDecorate %5945 Binding 0 + OpDecorate %5945 DescriptorSet 0 + OpDecorate %3258 NonReadable + OpDecorate %3258 Binding 0 + OpDecorate %3258 DescriptorSet 2 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_struct_993 = OpTypeStruct %v2uint +%_ptr_PushConstant__struct_993 = OpTypePointer PushConstant %_struct_993 + %3305 = OpVariable %_ptr_PushConstant__struct_993 PushConstant + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_v2uint = OpTypePointer PushConstant %v2uint + %bool = OpTypeBool + %v2bool = OpTypeVector %bool 2 + %float = OpTypeFloat 32 + %150 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_150 = OpTypePointer UniformConstant %150 + %5759 = OpVariable %_ptr_UniformConstant_150 UniformConstant + %v2int = OpTypeVector %int 2 + %v4float = OpTypeVector %float 4 + %v3float = OpTypeVector %float 3 + %float_255 = OpConstant %float 255 + %float_0_5 = OpConstant %float 0.5 + %154 = OpTypeImage %float Buffer 0 0 0 1 Unknown +%_ptr_UniformConstant_154 = OpTypePointer UniformConstant %154 + %5945 = OpVariable %_ptr_UniformConstant_154 UniformConstant + %uint_0 = OpConstant %uint 0 + %uint_1 = OpConstant %uint 1 +%float_0_298999995 = OpConstant %float 0.298999995 +%float_0_587000012 = OpConstant %float 0.587000012 +%float_0_114 = OpConstant %float 0.114 + %1268 = OpConstantComposite %v3float %float_0_298999995 %float_0_587000012 %float_0_114 + %166 = OpTypeImage %float 2D 0 0 0 2 Rgba16f +%_ptr_UniformConstant_166 = OpTypePointer UniformConstant %166 + %3258 = OpVariable %_ptr_UniformConstant_166 UniformConstant + %uint_16 = OpConstant %uint 16 + %uint_8 = OpConstant %uint 8 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_16 %uint_8 %uint_1 + %939 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5 + %10264 = OpUndef %v4float + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %21573 None + OpSwitch %uint_0 %12914 + %12914 = OpLabel + %13761 = OpLoad %v3uint %gl_GlobalInvocationID + %21717 = OpVectorShuffle %v2uint %13761 %13761 0 1 + %7760 = OpAccessChain %_ptr_PushConstant_v2uint %3305 %int_0 + %13378 = OpLoad %v2uint %7760 + %23437 = OpUGreaterThanEqual %v2bool %21717 %13378 + %23076 = OpAny %bool %23437 + OpSelectionMerge %18302 DontFlatten + OpBranchConditional %23076 %21992 %18302 + %21992 = OpLabel + OpBranch %21573 + %18302 = OpLabel + %24004 = OpLoad %150 %5759 + %10533 = OpBitcast %v2int %21717 + %6680 = OpImageFetch %v4float %24004 %10533 Lod %int_0 + %16242 = OpVectorShuffle %v3float %6680 %6680 0 1 2 + %13907 = OpVectorTimesScalar %v3float %16242 %float_255 + %16889 = OpFAdd %v3float %13907 %939 + %11099 = OpConvertFToU %v3uint %16889 + %18624 = OpLoad %154 %5945 + %15435 = OpCompositeExtract %uint %11099 0 + %24686 = OpBitcast %int %15435 + %8410 = OpImageFetch %v4float %18624 %24686 + %8944 = OpCompositeExtract %float %8410 2 + %20375 = OpCompositeInsert %v4float %8944 %10264 0 + %19520 = OpLoad %154 %5945 + %9802 = OpCompositeExtract %uint %11099 1 + %24687 = OpBitcast %int %9802 + %8411 = OpImageFetch %v4float %19520 %24687 + %8945 = OpCompositeExtract %float %8411 1 + %20376 = OpCompositeInsert %v4float %8945 %20375 1 + %19521 = OpLoad %154 %5945 + %9803 = OpCompositeExtract %uint %11099 2 + %24688 = OpBitcast %int %9803 + %8412 = OpImageFetch %v4float %19521 %24688 + %9286 = OpCompositeExtract %float %8412 0 + %18534 = OpCompositeInsert %v4float %9286 %20376 2 + %24801 = OpVectorShuffle %v3float %18534 %18534 0 1 2 + %9657 = OpDot %float %24801 %1268 + %18930 = OpCompositeConstruct %v4float %8944 %8945 %9286 %9657 + %12273 = OpLoad %166 %3258 + OpImageWrite %12273 %10533 %18930 + OpBranch %21573 + %21573 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t apply_gamma_table_fxaa_luma_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000060E2, 0x00000000, 0x00020011, 0x00000001, 0x00020011, + 0x0000002E, 0x0006000B, 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, + 0x00000000, 0x00000001, 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, + 0x00060010, 0x0000161F, 0x00000011, 0x00000010, 0x00000008, 0x00000001, 0x00040047, 0x00000F48, + 0x0000000B, 0x0000001C, 0x00030047, 0x000003E1, 0x00000002, 0x00050048, 0x000003E1, 0x00000000, + 0x00000023, 0x00000000, 0x00040047, 0x0000167F, 0x00000021, 0x00000000, 0x00040047, 0x0000167F, + 0x00000022, 0x00000001, 0x00040047, 0x00001739, 0x00000021, 0x00000000, 0x00040047, 0x00001739, + 0x00000022, 0x00000000, 0x00030047, 0x00000CBA, 0x00000019, 0x00040047, 0x00000CBA, 0x00000021, + 0x00000000, 0x00040047, 0x00000CBA, 0x00000022, 0x00000002, 0x00040047, 0x00000B0F, 0x0000000B, + 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000B, + 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, + 0x0000000B, 0x00000003, 0x00040020, 0x00000291, 0x00000001, 0x00000014, 0x0004003B, 0x00000291, + 0x00000F48, 0x00000001, 0x0003001E, 0x000003E1, 0x00000011, 0x00040020, 0x0000065E, 0x00000009, + 0x000003E1, 0x0004003B, 0x0000065E, 0x00000CE9, 0x00000009, 0x00040015, 0x0000000C, 0x00000020, + 0x00000001, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x0000028E, 0x00000009, + 0x00000011, 0x00020014, 0x00000009, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x00030016, + 0x0000000D, 0x00000020, 0x00090019, 0x00000096, 0x0000000D, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00040020, 0x00000313, 0x00000000, 0x00000096, 0x0004003B, + 0x00000313, 0x0000167F, 0x00000000, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, + 0x0000001D, 0x0000000D, 0x00000004, 0x00040017, 0x00000018, 0x0000000D, 0x00000003, 0x0004002B, + 0x0000000D, 0x00000540, 0x437F0000, 0x0004002B, 0x0000000D, 0x000000FC, 0x3F000000, 0x00090019, + 0x0000009A, 0x0000000D, 0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x00040020, 0x00000317, 0x00000000, 0x0000009A, 0x0004003B, 0x00000317, 0x00001739, 0x00000000, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0004002B, 0x0000000D, 0x00000351, 0x3E991687, 0x0004002B, 0x0000000D, 0x00000458, 0x3F1645A2, + 0x0004002B, 0x0000000D, 0x000001DC, 0x3DE978D5, 0x0006002C, 0x00000018, 0x000004F4, 0x00000351, + 0x00000458, 0x000001DC, 0x00090019, 0x000000A6, 0x0000000D, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000002, 0x00000002, 0x00040020, 0x00000323, 0x00000000, 0x000000A6, 0x0004003B, + 0x00000323, 0x00000CBA, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, + 0x0000000B, 0x00000A22, 0x00000008, 0x0006002C, 0x00000014, 0x00000B0F, 0x00000A3A, 0x00000A22, + 0x00000A0D, 0x0006002C, 0x00000018, 0x000003AB, 0x000000FC, 0x000000FC, 0x000000FC, 0x00030001, + 0x0000001D, 0x00002818, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, + 0x00003B06, 0x000300F7, 0x00005445, 0x00000000, 0x000300FB, 0x00000A0A, 0x00003272, 0x000200F8, + 0x00003272, 0x0004003D, 0x00000014, 0x000035C1, 0x00000F48, 0x0007004F, 0x00000011, 0x000054D5, + 0x000035C1, 0x000035C1, 0x00000000, 0x00000001, 0x00050041, 0x0000028E, 0x00001E50, 0x00000CE9, + 0x00000A0B, 0x0004003D, 0x00000011, 0x00003442, 0x00001E50, 0x000500AE, 0x0000000F, 0x00005B8D, + 0x000054D5, 0x00003442, 0x0004009A, 0x00000009, 0x00005A24, 0x00005B8D, 0x000300F7, 0x0000477E, + 0x00000002, 0x000400FA, 0x00005A24, 0x000055E8, 0x0000477E, 0x000200F8, 0x000055E8, 0x000200F9, + 0x00005445, 0x000200F8, 0x0000477E, 0x0004003D, 0x00000096, 0x00005DC4, 0x0000167F, 0x0004007C, + 0x00000012, 0x00002925, 0x000054D5, 0x0007005F, 0x0000001D, 0x00001A18, 0x00005DC4, 0x00002925, + 0x00000002, 0x00000A0B, 0x0008004F, 0x00000018, 0x00003F72, 0x00001A18, 0x00001A18, 0x00000000, + 0x00000001, 0x00000002, 0x0005008E, 0x00000018, 0x00003653, 0x00003F72, 0x00000540, 0x00050081, + 0x00000018, 0x000041F9, 0x00003653, 0x000003AB, 0x0004006D, 0x00000014, 0x00002B5B, 0x000041F9, + 0x0004003D, 0x0000009A, 0x000048C0, 0x00001739, 0x00050051, 0x0000000B, 0x00003C4B, 0x00002B5B, + 0x00000000, 0x0004007C, 0x0000000C, 0x0000606E, 0x00003C4B, 0x0005005F, 0x0000001D, 0x000020DA, + 0x000048C0, 0x0000606E, 0x00050051, 0x0000000D, 0x000022F0, 0x000020DA, 0x00000002, 0x00060052, + 0x0000001D, 0x00004F97, 0x000022F0, 0x00002818, 0x00000000, 0x0004003D, 0x0000009A, 0x00004C40, + 0x00001739, 0x00050051, 0x0000000B, 0x0000264A, 0x00002B5B, 0x00000001, 0x0004007C, 0x0000000C, + 0x0000606F, 0x0000264A, 0x0005005F, 0x0000001D, 0x000020DB, 0x00004C40, 0x0000606F, 0x00050051, + 0x0000000D, 0x000022F1, 0x000020DB, 0x00000001, 0x00060052, 0x0000001D, 0x00004F98, 0x000022F1, + 0x00004F97, 0x00000001, 0x0004003D, 0x0000009A, 0x00004C41, 0x00001739, 0x00050051, 0x0000000B, + 0x0000264B, 0x00002B5B, 0x00000002, 0x0004007C, 0x0000000C, 0x00006070, 0x0000264B, 0x0005005F, + 0x0000001D, 0x000020DC, 0x00004C41, 0x00006070, 0x00050051, 0x0000000D, 0x00002446, 0x000020DC, + 0x00000000, 0x00060052, 0x0000001D, 0x00004866, 0x00002446, 0x00004F98, 0x00000002, 0x0008004F, + 0x00000018, 0x000060E1, 0x00004866, 0x00004866, 0x00000000, 0x00000001, 0x00000002, 0x00050094, + 0x0000000D, 0x000025B9, 0x000060E1, 0x000004F4, 0x00070050, 0x0000001D, 0x000049F2, 0x000022F0, + 0x000022F1, 0x00002446, 0x000025B9, 0x0004003D, 0x000000A6, 0x00002FF1, 0x00000CBA, 0x00040063, + 0x00002FF1, 0x00002925, 0x000049F2, 0x000200F9, 0x00005445, 0x000200F8, 0x00005445, 0x000100FD, + 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/apply_gamma_table_fxaa_luma_ps.h b/src/graphics/shaders/vulkan_spirv/apply_gamma_table_fxaa_luma_ps.h new file mode 100644 index 0000000..6c5701f --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/apply_gamma_table_fxaa_luma_ps.h @@ -0,0 +1,133 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 24950 +; Schema: 0 + OpCapability Shader + OpCapability SampledBuffer + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %5663 "main" %gl_FragCoord %3258 + OpExecutionMode %5663 OriginUpperLeft + OpDecorate %gl_FragCoord BuiltIn FragCoord + OpDecorate %5759 Binding 0 + OpDecorate %5759 DescriptorSet 1 + OpDecorate %5945 Binding 0 + OpDecorate %5945 DescriptorSet 0 + OpDecorate %3258 Location 0 + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%gl_FragCoord = OpVariable %_ptr_Input_v4float Input + %v2float = OpTypeVector %float 2 + %v3uint = OpTypeVector %uint 3 + %150 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_150 = OpTypePointer UniformConstant %150 + %5759 = OpVariable %_ptr_UniformConstant_150 UniformConstant + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %int_0 = OpConstant %int 0 + %v3float = OpTypeVector %float 3 + %float_255 = OpConstant %float 255 + %float_0_5 = OpConstant %float 0.5 + %154 = OpTypeImage %float Buffer 0 0 0 1 Unknown +%_ptr_UniformConstant_154 = OpTypePointer UniformConstant %154 + %5945 = OpVariable %_ptr_UniformConstant_154 UniformConstant +%float_0_298999995 = OpConstant %float 0.298999995 +%float_0_587000012 = OpConstant %float 0.587000012 +%float_0_114 = OpConstant %float 0.114 + %1268 = OpConstantComposite %v3float %float_0_298999995 %float_0_587000012 %float_0_114 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %3258 = OpVariable %_ptr_Output_v4float Output + %939 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5 + %10264 = OpUndef %v4float + %5663 = OpFunction %void None %1282 + %24949 = OpLabel + %18552 = OpLoad %v4float %gl_FragCoord + %14105 = OpVectorShuffle %v2float %18552 %18552 0 1 + %8667 = OpConvertFToU %v2uint %14105 + %21665 = OpLoad %150 %5759 + %11127 = OpBitcast %v2int %8667 + %6680 = OpImageFetch %v4float %21665 %11127 Lod %int_0 + %16242 = OpVectorShuffle %v3float %6680 %6680 0 1 2 + %13907 = OpVectorTimesScalar %v3float %16242 %float_255 + %16889 = OpFAdd %v3float %13907 %939 + %11099 = OpConvertFToU %v3uint %16889 + %18624 = OpLoad %154 %5945 + %15435 = OpCompositeExtract %uint %11099 0 + %24686 = OpBitcast %int %15435 + %8410 = OpImageFetch %v4float %18624 %24686 + %8944 = OpCompositeExtract %float %8410 2 + %20375 = OpCompositeInsert %v4float %8944 %10264 0 + %19520 = OpLoad %154 %5945 + %9802 = OpCompositeExtract %uint %11099 1 + %24687 = OpBitcast %int %9802 + %8411 = OpImageFetch %v4float %19520 %24687 + %8945 = OpCompositeExtract %float %8411 1 + %20376 = OpCompositeInsert %v4float %8945 %20375 1 + %19521 = OpLoad %154 %5945 + %9803 = OpCompositeExtract %uint %11099 2 + %24688 = OpBitcast %int %9803 + %8412 = OpImageFetch %v4float %19521 %24688 + %9286 = OpCompositeExtract %float %8412 0 + %18534 = OpCompositeInsert %v4float %9286 %20376 2 + %24801 = OpVectorShuffle %v3float %18534 %18534 0 1 2 + %9676 = OpDot %float %24801 %1268 + %21683 = OpCompositeConstruct %v4float %8944 %8945 %9286 %9676 + OpStore %3258 %21683 + OpReturn + OpFunctionEnd +#endif + +const uint32_t apply_gamma_table_fxaa_luma_ps[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006176, 0x00000000, 0x00020011, 0x00000001, 0x00020011, + 0x0000002E, 0x0006000B, 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, + 0x00000000, 0x00000001, 0x0007000F, 0x00000004, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000C93, + 0x00000CBA, 0x00030010, 0x0000161F, 0x00000007, 0x00040047, 0x00000C93, 0x0000000B, 0x0000000F, + 0x00040047, 0x0000167F, 0x00000021, 0x00000000, 0x00040047, 0x0000167F, 0x00000022, 0x00000001, + 0x00040047, 0x00001739, 0x00000021, 0x00000000, 0x00040047, 0x00001739, 0x00000022, 0x00000000, + 0x00040047, 0x00000CBA, 0x0000001E, 0x00000000, 0x00020013, 0x00000008, 0x00030021, 0x00000502, + 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, + 0x00000002, 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, + 0x00040020, 0x0000029A, 0x00000001, 0x0000001D, 0x0004003B, 0x0000029A, 0x00000C93, 0x00000001, + 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x00090019, 0x00000096, 0x0000000D, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00040020, 0x00000313, 0x00000000, 0x00000096, 0x0004003B, 0x00000313, 0x0000167F, + 0x00000000, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, + 0x00000002, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040017, 0x00000018, 0x0000000D, + 0x00000003, 0x0004002B, 0x0000000D, 0x00000540, 0x437F0000, 0x0004002B, 0x0000000D, 0x000000FC, + 0x3F000000, 0x00090019, 0x0000009A, 0x0000000D, 0x00000005, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00040020, 0x00000317, 0x00000000, 0x0000009A, 0x0004003B, 0x00000317, + 0x00001739, 0x00000000, 0x0004002B, 0x0000000D, 0x00000351, 0x3E991687, 0x0004002B, 0x0000000D, + 0x00000458, 0x3F1645A2, 0x0004002B, 0x0000000D, 0x000001DC, 0x3DE978D5, 0x0006002C, 0x00000018, + 0x000004F4, 0x00000351, 0x00000458, 0x000001DC, 0x00040020, 0x0000029B, 0x00000003, 0x0000001D, + 0x0004003B, 0x0000029B, 0x00000CBA, 0x00000003, 0x0006002C, 0x00000018, 0x000003AB, 0x000000FC, + 0x000000FC, 0x000000FC, 0x00030001, 0x0000001D, 0x00002818, 0x00050036, 0x00000008, 0x0000161F, + 0x00000000, 0x00000502, 0x000200F8, 0x00006175, 0x0004003D, 0x0000001D, 0x00004878, 0x00000C93, + 0x0007004F, 0x00000013, 0x00003719, 0x00004878, 0x00004878, 0x00000000, 0x00000001, 0x0004006D, + 0x00000011, 0x000021DB, 0x00003719, 0x0004003D, 0x00000096, 0x000054A1, 0x0000167F, 0x0004007C, + 0x00000012, 0x00002B77, 0x000021DB, 0x0007005F, 0x0000001D, 0x00001A18, 0x000054A1, 0x00002B77, + 0x00000002, 0x00000A0B, 0x0008004F, 0x00000018, 0x00003F72, 0x00001A18, 0x00001A18, 0x00000000, + 0x00000001, 0x00000002, 0x0005008E, 0x00000018, 0x00003653, 0x00003F72, 0x00000540, 0x00050081, + 0x00000018, 0x000041F9, 0x00003653, 0x000003AB, 0x0004006D, 0x00000014, 0x00002B5B, 0x000041F9, + 0x0004003D, 0x0000009A, 0x000048C0, 0x00001739, 0x00050051, 0x0000000B, 0x00003C4B, 0x00002B5B, + 0x00000000, 0x0004007C, 0x0000000C, 0x0000606E, 0x00003C4B, 0x0005005F, 0x0000001D, 0x000020DA, + 0x000048C0, 0x0000606E, 0x00050051, 0x0000000D, 0x000022F0, 0x000020DA, 0x00000002, 0x00060052, + 0x0000001D, 0x00004F97, 0x000022F0, 0x00002818, 0x00000000, 0x0004003D, 0x0000009A, 0x00004C40, + 0x00001739, 0x00050051, 0x0000000B, 0x0000264A, 0x00002B5B, 0x00000001, 0x0004007C, 0x0000000C, + 0x0000606F, 0x0000264A, 0x0005005F, 0x0000001D, 0x000020DB, 0x00004C40, 0x0000606F, 0x00050051, + 0x0000000D, 0x000022F1, 0x000020DB, 0x00000001, 0x00060052, 0x0000001D, 0x00004F98, 0x000022F1, + 0x00004F97, 0x00000001, 0x0004003D, 0x0000009A, 0x00004C41, 0x00001739, 0x00050051, 0x0000000B, + 0x0000264B, 0x00002B5B, 0x00000002, 0x0004007C, 0x0000000C, 0x00006070, 0x0000264B, 0x0005005F, + 0x0000001D, 0x000020DC, 0x00004C41, 0x00006070, 0x00050051, 0x0000000D, 0x00002446, 0x000020DC, + 0x00000000, 0x00060052, 0x0000001D, 0x00004866, 0x00002446, 0x00004F98, 0x00000002, 0x0008004F, + 0x00000018, 0x000060E1, 0x00004866, 0x00004866, 0x00000000, 0x00000001, 0x00000002, 0x00050094, + 0x0000000D, 0x000025CC, 0x000060E1, 0x000004F4, 0x00070050, 0x0000001D, 0x000054B3, 0x000022F0, + 0x000022F1, 0x00002446, 0x000025CC, 0x0003003E, 0x00000CBA, 0x000054B3, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/apply_gamma_table_ps.h b/src/graphics/shaders/vulkan_spirv/apply_gamma_table_ps.h new file mode 100644 index 0000000..ffb0b68 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/apply_gamma_table_ps.h @@ -0,0 +1,118 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 24950 +; Schema: 0 + OpCapability Shader + OpCapability SampledBuffer + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %5663 "main" %gl_FragCoord %3258 + OpExecutionMode %5663 OriginUpperLeft + OpDecorate %gl_FragCoord BuiltIn FragCoord + OpDecorate %5759 Binding 0 + OpDecorate %5759 DescriptorSet 1 + OpDecorate %5945 Binding 0 + OpDecorate %5945 DescriptorSet 0 + OpDecorate %3258 Location 0 + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%gl_FragCoord = OpVariable %_ptr_Input_v4float Input + %v2float = OpTypeVector %float 2 + %v3uint = OpTypeVector %uint 3 + %150 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_150 = OpTypePointer UniformConstant %150 + %5759 = OpVariable %_ptr_UniformConstant_150 UniformConstant + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %int_0 = OpConstant %int 0 + %v3float = OpTypeVector %float 3 + %float_255 = OpConstant %float 255 + %float_0_5 = OpConstant %float 0.5 + %154 = OpTypeImage %float Buffer 0 0 0 1 Unknown +%_ptr_UniformConstant_154 = OpTypePointer UniformConstant %154 + %5945 = OpVariable %_ptr_UniformConstant_154 UniformConstant + %float_1 = OpConstant %float 1 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %3258 = OpVariable %_ptr_Output_v4float Output + %939 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5 + %5663 = OpFunction %void None %1282 + %24949 = OpLabel + %18552 = OpLoad %v4float %gl_FragCoord + %14105 = OpVectorShuffle %v2float %18552 %18552 0 1 + %8667 = OpConvertFToU %v2uint %14105 + %21665 = OpLoad %150 %5759 + %11127 = OpBitcast %v2int %8667 + %6680 = OpImageFetch %v4float %21665 %11127 Lod %int_0 + %16242 = OpVectorShuffle %v3float %6680 %6680 0 1 2 + %13907 = OpVectorTimesScalar %v3float %16242 %float_255 + %16889 = OpFAdd %v3float %13907 %939 + %11099 = OpConvertFToU %v3uint %16889 + %18624 = OpLoad %154 %5945 + %15435 = OpCompositeExtract %uint %11099 0 + %24686 = OpBitcast %int %15435 + %8011 = OpImageFetch %v4float %18624 %24686 + %12957 = OpCompositeExtract %float %8011 2 + %18146 = OpLoad %154 %5945 + %12224 = OpCompositeExtract %uint %11099 1 + %24687 = OpBitcast %int %12224 + %8012 = OpImageFetch %v4float %18146 %24687 + %12958 = OpCompositeExtract %float %8012 1 + %18147 = OpLoad %154 %5945 + %12225 = OpCompositeExtract %uint %11099 2 + %24688 = OpBitcast %int %12225 + %8372 = OpImageFetch %v4float %18147 %24688 + %9309 = OpCompositeExtract %float %8372 0 + %20785 = OpCompositeConstruct %v4float %12957 %12958 %9309 %float_1 + OpStore %3258 %20785 + OpReturn + OpFunctionEnd +#endif + +const uint32_t apply_gamma_table_ps[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006176, 0x00000000, 0x00020011, 0x00000001, 0x00020011, + 0x0000002E, 0x0006000B, 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, + 0x00000000, 0x00000001, 0x0007000F, 0x00000004, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000C93, + 0x00000CBA, 0x00030010, 0x0000161F, 0x00000007, 0x00040047, 0x00000C93, 0x0000000B, 0x0000000F, + 0x00040047, 0x0000167F, 0x00000021, 0x00000000, 0x00040047, 0x0000167F, 0x00000022, 0x00000001, + 0x00040047, 0x00001739, 0x00000021, 0x00000000, 0x00040047, 0x00001739, 0x00000022, 0x00000000, + 0x00040047, 0x00000CBA, 0x0000001E, 0x00000000, 0x00020013, 0x00000008, 0x00030021, 0x00000502, + 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, + 0x00000002, 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, + 0x00040020, 0x0000029A, 0x00000001, 0x0000001D, 0x0004003B, 0x0000029A, 0x00000C93, 0x00000001, + 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x00090019, 0x00000096, 0x0000000D, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00040020, 0x00000313, 0x00000000, 0x00000096, 0x0004003B, 0x00000313, 0x0000167F, + 0x00000000, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, + 0x00000002, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040017, 0x00000018, 0x0000000D, + 0x00000003, 0x0004002B, 0x0000000D, 0x00000540, 0x437F0000, 0x0004002B, 0x0000000D, 0x000000FC, + 0x3F000000, 0x00090019, 0x0000009A, 0x0000000D, 0x00000005, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00040020, 0x00000317, 0x00000000, 0x0000009A, 0x0004003B, 0x00000317, + 0x00001739, 0x00000000, 0x0004002B, 0x0000000D, 0x0000008A, 0x3F800000, 0x00040020, 0x0000029B, + 0x00000003, 0x0000001D, 0x0004003B, 0x0000029B, 0x00000CBA, 0x00000003, 0x0006002C, 0x00000018, + 0x000003AB, 0x000000FC, 0x000000FC, 0x000000FC, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, + 0x00000502, 0x000200F8, 0x00006175, 0x0004003D, 0x0000001D, 0x00004878, 0x00000C93, 0x0007004F, + 0x00000013, 0x00003719, 0x00004878, 0x00004878, 0x00000000, 0x00000001, 0x0004006D, 0x00000011, + 0x000021DB, 0x00003719, 0x0004003D, 0x00000096, 0x000054A1, 0x0000167F, 0x0004007C, 0x00000012, + 0x00002B77, 0x000021DB, 0x0007005F, 0x0000001D, 0x00001A18, 0x000054A1, 0x00002B77, 0x00000002, + 0x00000A0B, 0x0008004F, 0x00000018, 0x00003F72, 0x00001A18, 0x00001A18, 0x00000000, 0x00000001, + 0x00000002, 0x0005008E, 0x00000018, 0x00003653, 0x00003F72, 0x00000540, 0x00050081, 0x00000018, + 0x000041F9, 0x00003653, 0x000003AB, 0x0004006D, 0x00000014, 0x00002B5B, 0x000041F9, 0x0004003D, + 0x0000009A, 0x000048C0, 0x00001739, 0x00050051, 0x0000000B, 0x00003C4B, 0x00002B5B, 0x00000000, + 0x0004007C, 0x0000000C, 0x0000606E, 0x00003C4B, 0x0005005F, 0x0000001D, 0x00001F4B, 0x000048C0, + 0x0000606E, 0x00050051, 0x0000000D, 0x0000329D, 0x00001F4B, 0x00000002, 0x0004003D, 0x0000009A, + 0x000046E2, 0x00001739, 0x00050051, 0x0000000B, 0x00002FC0, 0x00002B5B, 0x00000001, 0x0004007C, + 0x0000000C, 0x0000606F, 0x00002FC0, 0x0005005F, 0x0000001D, 0x00001F4C, 0x000046E2, 0x0000606F, + 0x00050051, 0x0000000D, 0x0000329E, 0x00001F4C, 0x00000001, 0x0004003D, 0x0000009A, 0x000046E3, + 0x00001739, 0x00050051, 0x0000000B, 0x00002FC1, 0x00002B5B, 0x00000002, 0x0004007C, 0x0000000C, + 0x00006070, 0x00002FC1, 0x0005005F, 0x0000001D, 0x000020B4, 0x000046E3, 0x00006070, 0x00050051, + 0x0000000D, 0x0000245D, 0x000020B4, 0x00000000, 0x00070050, 0x0000001D, 0x00005131, 0x0000329D, + 0x0000329E, 0x0000245D, 0x0000008A, 0x0003003E, 0x00000CBA, 0x00005131, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/fullscreen_cw_vs.h b/src/graphics/shaders/vulkan_spirv/fullscreen_cw_vs.h new file mode 100644 index 0000000..77a9668 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/fullscreen_cw_vs.h @@ -0,0 +1,93 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 22213 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %5663 "main" %4930 %gl_VertexIndex + OpDecorate %_struct_374 Block + OpMemberDecorate %_struct_374 0 BuiltIn Position + OpMemberDecorate %_struct_374 1 BuiltIn PointSize + OpMemberDecorate %_struct_374 2 BuiltIn ClipDistance + OpMemberDecorate %_struct_374 3 BuiltIn CullDistance + OpDecorate %gl_VertexIndex BuiltIn VertexIndex + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %uint_1 = OpConstant %uint 1 +%_arr_float_uint_1 = OpTypeArray %float %uint_1 +%_struct_374 = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 +%_ptr_Output__struct_374 = OpTypePointer Output %_struct_374 + %4930 = OpVariable %_ptr_Output__struct_374 Output + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 +%_ptr_Input_int = OpTypePointer Input %int +%gl_VertexIndex = OpVariable %_ptr_Input_int Input + %uint_0 = OpConstant %uint 0 + %1819 = OpConstantComposite %v2uint %uint_0 %uint_1 + %v2float = OpTypeVector %float 2 + %float_4 = OpConstant %float 4 + %2183 = OpConstantComposite %v2float %float_4 %float_4 + %float_n1 = OpConstant %float -1 + %73 = OpConstantComposite %v2float %float_n1 %float_n1 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %5663 = OpFunction %void None %1282 + %6733 = OpLabel + %10216 = OpLoad %int %gl_VertexIndex + %15313 = OpBitcast %uint %10216 + %15408 = OpCompositeConstruct %v2uint %15313 %15313 + %14991 = OpShiftRightLogical %v2uint %15408 %1819 + %18859 = OpBitwiseAnd %v2uint %14991 %1828 + %16455 = OpConvertUToF %v2float %18859 + %8403 = OpFMul %v2float %16455 %2183 + %22212 = OpFAdd %v2float %8403 %73 + %10599 = OpCompositeExtract %float %22212 0 + %13956 = OpCompositeExtract %float %22212 1 + %18260 = OpCompositeConstruct %v4float %10599 %13956 %float_0 %float_1 + %12055 = OpAccessChain %_ptr_Output_v4float %4930 %int_0 + OpStore %12055 %18260 + OpReturn + OpFunctionEnd +#endif + +const uint32_t fullscreen_cw_vs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000056C5, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0007000F, 0x00000000, 0x0000161F, 0x6E69616D, 0x00000000, 0x00001342, 0x00001029, 0x00030047, + 0x00000176, 0x00000002, 0x00050048, 0x00000176, 0x00000000, 0x0000000B, 0x00000000, 0x00050048, + 0x00000176, 0x00000001, 0x0000000B, 0x00000001, 0x00050048, 0x00000176, 0x00000002, 0x0000000B, + 0x00000003, 0x00050048, 0x00000176, 0x00000003, 0x0000000B, 0x00000004, 0x00040047, 0x00001029, + 0x0000000B, 0x0000002A, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00040015, + 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00030016, + 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x0004002B, 0x0000000B, + 0x00000A0D, 0x00000001, 0x0004001C, 0x0000025C, 0x0000000D, 0x00000A0D, 0x0006001E, 0x00000176, + 0x0000001D, 0x0000000D, 0x0000025C, 0x0000025C, 0x00040020, 0x000003F3, 0x00000003, 0x00000176, + 0x0004003B, 0x000003F3, 0x00001342, 0x00000003, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000289, 0x00000001, 0x0000000C, + 0x0004003B, 0x00000289, 0x00001029, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, + 0x0005002C, 0x00000011, 0x0000071B, 0x00000A0A, 0x00000A0D, 0x00040017, 0x00000013, 0x0000000D, + 0x00000002, 0x0004002B, 0x0000000D, 0x00000B69, 0x40800000, 0x0005002C, 0x00000013, 0x00000887, + 0x00000B69, 0x00000B69, 0x0004002B, 0x0000000D, 0x00000341, 0xBF800000, 0x0005002C, 0x00000013, + 0x00000049, 0x00000341, 0x00000341, 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, 0x0004002B, + 0x0000000D, 0x0000008A, 0x3F800000, 0x00040020, 0x0000029A, 0x00000003, 0x0000001D, 0x0005002C, + 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, + 0x00000502, 0x000200F8, 0x00001A4D, 0x0004003D, 0x0000000C, 0x000027E8, 0x00001029, 0x0004007C, + 0x0000000B, 0x00003BD1, 0x000027E8, 0x00050050, 0x00000011, 0x00003C30, 0x00003BD1, 0x00003BD1, + 0x000500C2, 0x00000011, 0x00003A8F, 0x00003C30, 0x0000071B, 0x000500C7, 0x00000011, 0x000049AB, + 0x00003A8F, 0x00000724, 0x00040070, 0x00000013, 0x00004047, 0x000049AB, 0x00050085, 0x00000013, + 0x000020D3, 0x00004047, 0x00000887, 0x00050081, 0x00000013, 0x000056C4, 0x000020D3, 0x00000049, + 0x00050051, 0x0000000D, 0x00002967, 0x000056C4, 0x00000000, 0x00050051, 0x0000000D, 0x00003684, + 0x000056C4, 0x00000001, 0x00070050, 0x0000001D, 0x00004754, 0x00002967, 0x00003684, 0x00000A0C, + 0x0000008A, 0x00050041, 0x0000029A, 0x00002F17, 0x00001342, 0x00000A0B, 0x0003003E, 0x00002F17, + 0x00004754, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/host_depth_store_1xmsaa_cs.h b/src/graphics/shaders/vulkan_spirv/host_depth_store_1xmsaa_cs.h new file mode 100644 index 0000000..eac1b79 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/host_depth_store_1xmsaa_cs.h @@ -0,0 +1,291 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 24936 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_struct_990 Block + OpMemberDecorate %_struct_990 0 Offset 0 + OpMemberDecorate %_struct_990 1 Offset 4 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonReadable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4790 NonReadable + OpDecorate %4790 Binding 0 + OpDecorate %4790 DescriptorSet 0 + OpDecorate %3709 Binding 0 + OpDecorate %3709 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %bool = OpTypeBool + %uint_2 = OpConstant %uint 2 + %uint_1 = OpConstant %uint 1 + %uint_0 = OpConstant %uint 0 + %uint_80 = OpConstant %uint 80 + %uint_16 = OpConstant %uint 16 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %int = OpTypeInt 32 1 + %uint_10 = OpConstant %uint 10 + %1927 = OpConstantComposite %v2uint %uint_0 %uint_10 + %uint_1023 = OpConstant %uint 1023 + %uint_3 = OpConstant %uint 3 + %uint_20 = OpConstant %uint 20 + %uint_13 = OpConstant %uint 13 + %2053 = OpConstantComposite %v2uint %uint_10 %uint_13 + %uint_7 = OpConstant %uint 7 +%_struct_990 = OpTypeStruct %uint %uint +%_ptr_PushConstant__struct_990 = OpTypePointer PushConstant %_struct_990 + %3305 = OpVariable %_ptr_PushConstant__struct_990 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %int_1 = OpConstant %int 1 + %v3uint = OpTypeVector %uint 3 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_ptr_Input_uint = OpTypePointer Input %uint + %v2int = OpTypeVector %int 2 + %1834 = OpConstantComposite %v2uint %uint_3 %uint_0 + %v4uint = OpTypeVector %uint 4 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4790 = OpVariable %_ptr_Uniform__struct_1972 Uniform + %float = OpTypeFloat 32 + %150 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_150 = OpTypePointer UniformConstant %150 + %3709 = OpVariable %_ptr_UniformConstant_150 UniformConstant + %v4float = OpTypeVector %float 4 + %1824 = OpConstantComposite %v2int %int_1 %int_0 + %int_2 = OpConstant %int 2 + %1833 = OpConstantComposite %v2int %int_2 %int_0 + %int_3 = OpConstant %int 3 + %1842 = OpConstantComposite %v2int %int_3 %int_0 +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint + %int_4 = OpConstant %int 4 + %1851 = OpConstantComposite %v2int %int_4 %int_0 + %int_5 = OpConstant %int 5 + %1860 = OpConstantComposite %v2int %int_5 %int_0 + %int_6 = OpConstant %int 6 + %1869 = OpConstantComposite %v2int %int_6 %int_0 + %int_7 = OpConstant %int 7 + %1878 = OpConstantComposite %v2int %int_7 %int_0 + %uint_8 = OpConstant %uint 8 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %2213 = OpConstantComposite %v2uint %uint_1023 %uint_1023 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %20439 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %22340 = OpLoad %uint %20439 + %10293 = OpCompositeConstruct %v2uint %22340 %22340 + %24330 = OpShiftRightLogical %v2uint %10293 %2053 + %6551 = OpBitwiseAnd %v2uint %24330 %1954 + %21183 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0 + %23612 = OpLoad %uint %21183 + %21170 = OpShiftRightLogical %uint %15627 %uint_20 + %15922 = OpBitwiseAnd %uint %21170 %uint_1023 + %8846 = OpIAdd %uint %15922 %uint_1 + %11841 = OpCompositeExtract %uint %6551 0 + %17907 = OpIMul %uint %8846 %11841 + %7287 = OpUGreaterThanEqual %bool %23612 %17907 + OpSelectionMerge %16345 DontFlatten + OpBranchConditional %7287 %21992 %16345 + %21992 = OpLabel + OpBranch %19578 + %16345 = OpLabel + %10771 = OpCompositeConstruct %v2uint %15627 %15627 + %13581 = OpShiftRightLogical %v2uint %10771 %1927 + %23379 = OpBitwiseAnd %v2uint %13581 %2213 + %13680 = OpShiftLeftLogical %v2uint %23379 %1870 + %24677 = OpIMul %v2uint %13680 %6551 + %7005 = OpLoad %v3uint %gl_GlobalInvocationID + %22399 = OpVectorShuffle %v2uint %7005 %7005 0 1 + %21597 = OpShiftLeftLogical %v2uint %22399 %1834 + %9038 = OpIAdd %v2uint %24677 %21597 + %24559 = OpBitcast %v2int %9038 + %8121 = OpBitcast %v2uint %24559 + %24935 = OpBitwiseAnd %uint %22340 %uint_1023 + %11893 = OpIMul %v2uint %2719 %6551 + %16817 = OpUDiv %v2uint %8121 %11893 + %9129 = OpCompositeExtract %uint %16817 1 + %11046 = OpIMul %uint %9129 %24935 + %24741 = OpCompositeExtract %uint %16817 0 + %20806 = OpIAdd %uint %11046 %24741 + %13527 = OpIMul %v2uint %16817 %11893 + %20715 = OpISub %v2uint %8121 %13527 + %7303 = OpCompositeExtract %uint %11893 0 + %22882 = OpCompositeExtract %uint %11893 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %20806 %13170 + %16084 = OpCompositeExtract %uint %20715 1 + %15890 = OpIMul %uint %16084 %7303 + %24665 = OpCompositeExtract %uint %20715 0 + %22714 = OpIAdd %uint %15890 %24665 + %15776 = OpIAdd %uint %15520 %22714 + %16002 = OpShiftRightLogical %uint %15776 %uint_2 + %7456 = OpLoad %150 %3709 + %16549 = OpImageFetch %v4float %7456 %24559 Lod %int_0 + %24082 = OpCompositeExtract %float %16549 0 + %9464 = OpLoad %150 %3709 + %13324 = OpIAdd %v2int %24559 %1824 + %16413 = OpImageFetch %v4float %9464 %13324 Lod %int_0 + %10619 = OpCompositeExtract %float %16413 0 + %9465 = OpLoad %150 %3709 + %13325 = OpIAdd %v2int %24559 %1833 + %16414 = OpImageFetch %v4float %9465 %13325 Lod %int_0 + %10620 = OpCompositeExtract %float %16414 0 + %9466 = OpLoad %150 %3709 + %13326 = OpIAdd %v2int %24559 %1842 + %16774 = OpImageFetch %v4float %9466 %13326 Lod %int_0 + %7256 = OpCompositeExtract %float %16774 0 + %6487 = OpCompositeConstruct %v4float %24082 %10619 %10620 %7256 + %20366 = OpBitcast %v4uint %6487 + %12860 = OpAccessChain %_ptr_Uniform_v4uint %4790 %int_0 %16002 + OpStore %12860 %20366 + %13403 = OpIAdd %uint %16002 %uint_1 + %24531 = OpLoad %150 %3709 + %15716 = OpIAdd %v2int %24559 %1851 + %16415 = OpImageFetch %v4float %24531 %15716 Lod %int_0 + %10621 = OpCompositeExtract %float %16415 0 + %9467 = OpLoad %150 %3709 + %13327 = OpIAdd %v2int %24559 %1860 + %16416 = OpImageFetch %v4float %9467 %13327 Lod %int_0 + %10622 = OpCompositeExtract %float %16416 0 + %9468 = OpLoad %150 %3709 + %13328 = OpIAdd %v2int %24559 %1869 + %16417 = OpImageFetch %v4float %9468 %13328 Lod %int_0 + %10623 = OpCompositeExtract %float %16417 0 + %9469 = OpLoad %150 %3709 + %13329 = OpIAdd %v2int %24559 %1878 + %16775 = OpImageFetch %v4float %9469 %13329 Lod %int_0 + %7257 = OpCompositeExtract %float %16775 0 + %6488 = OpCompositeConstruct %v4float %10621 %10622 %10623 %7257 + %20367 = OpBitcast %v4uint %6488 + %15159 = OpAccessChain %_ptr_Uniform_v4uint %4790 %int_0 %13403 + OpStore %15159 %20367 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t host_depth_store_1xmsaa_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006168, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00030047, 0x000003DE, 0x00000002, 0x00050048, + 0x000003DE, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x000003DE, 0x00000001, 0x00000023, + 0x00000004, 0x00040047, 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, + 0x00000010, 0x00030047, 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000019, + 0x00050048, 0x000007B4, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x000012B6, 0x00000019, + 0x00040047, 0x000012B6, 0x00000021, 0x00000000, 0x00040047, 0x000012B6, 0x00000022, 0x00000000, + 0x00040047, 0x00000E7D, 0x00000021, 0x00000000, 0x00040047, 0x00000E7D, 0x00000022, 0x00000001, + 0x00040047, 0x00000AC7, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, + 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, + 0x00000002, 0x00020014, 0x00000009, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, + 0x0000000B, 0x00000AFA, 0x00000050, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0005002C, + 0x00000011, 0x00000A9F, 0x00000AFA, 0x00000A3A, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, + 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0005002C, 0x00000011, 0x00000787, 0x00000A0A, + 0x00000A28, 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, 0x0004002B, 0x0000000B, 0x00000A13, + 0x00000003, 0x0004002B, 0x0000000B, 0x00000A46, 0x00000014, 0x0004002B, 0x0000000B, 0x00000A31, + 0x0000000D, 0x0005002C, 0x00000011, 0x00000805, 0x00000A28, 0x00000A31, 0x0004002B, 0x0000000B, + 0x00000A1F, 0x00000007, 0x0004001E, 0x000003DE, 0x0000000B, 0x0000000B, 0x00040020, 0x0000065B, + 0x00000009, 0x000003DE, 0x0004003B, 0x0000065B, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0004002B, 0x0000000C, + 0x00000A0E, 0x00000001, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x00040020, 0x00000291, + 0x00000001, 0x00000014, 0x0004003B, 0x00000291, 0x00000F48, 0x00000001, 0x00040020, 0x00000289, + 0x00000001, 0x0000000B, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x0005002C, 0x00000011, + 0x0000072A, 0x00000A13, 0x00000A0A, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x0003001D, + 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, + 0x000007B4, 0x0004003B, 0x00000A32, 0x000012B6, 0x00000002, 0x00030016, 0x0000000D, 0x00000020, + 0x00090019, 0x00000096, 0x0000000D, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00040020, 0x00000313, 0x00000000, 0x00000096, 0x0004003B, 0x00000313, 0x00000E7D, + 0x00000000, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x0005002C, 0x00000012, 0x00000720, + 0x00000A0E, 0x00000A0B, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0005002C, 0x00000012, + 0x00000729, 0x00000A11, 0x00000A0B, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0005002C, + 0x00000012, 0x00000732, 0x00000A14, 0x00000A0B, 0x00040020, 0x00000294, 0x00000002, 0x00000017, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0005002C, 0x00000012, 0x0000073B, 0x00000A17, + 0x00000A0B, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0005002C, 0x00000012, 0x00000744, + 0x00000A1A, 0x00000A0B, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0005002C, 0x00000012, + 0x0000074D, 0x00000A1D, 0x00000A0B, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0005002C, + 0x00000012, 0x00000756, 0x00000A20, 0x00000A0B, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, + 0x0006002C, 0x00000014, 0x00000AC7, 0x00000A22, 0x00000A22, 0x00000A0D, 0x0005002C, 0x00000011, + 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0005002C, 0x00000011, 0x000008A5, 0x00000A44, 0x00000A44, + 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, 0x00050036, 0x00000008, 0x0000161F, + 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, + 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000056E5, 0x00000CE9, + 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003D0B, 0x000056E5, 0x00050041, 0x00000288, 0x00004FD7, + 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005744, 0x00004FD7, 0x00050050, 0x00000011, + 0x00002835, 0x00005744, 0x00005744, 0x000500C2, 0x00000011, 0x00005F0A, 0x00002835, 0x00000805, + 0x000500C7, 0x00000011, 0x00001997, 0x00005F0A, 0x000007A2, 0x00050041, 0x00000289, 0x000052BF, + 0x00000F48, 0x00000A0A, 0x0004003D, 0x0000000B, 0x00005C3C, 0x000052BF, 0x000500C2, 0x0000000B, + 0x000052B2, 0x00003D0B, 0x00000A46, 0x000500C7, 0x0000000B, 0x00003E32, 0x000052B2, 0x00000A44, + 0x00050080, 0x0000000B, 0x0000228E, 0x00003E32, 0x00000A0D, 0x00050051, 0x0000000B, 0x00002E41, + 0x00001997, 0x00000000, 0x00050084, 0x0000000B, 0x000045F3, 0x0000228E, 0x00002E41, 0x000500AE, + 0x00000009, 0x00001C77, 0x00005C3C, 0x000045F3, 0x000300F7, 0x00003FD9, 0x00000002, 0x000400FA, + 0x00001C77, 0x000055E8, 0x00003FD9, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, + 0x00003FD9, 0x00050050, 0x00000011, 0x00002A13, 0x00003D0B, 0x00003D0B, 0x000500C2, 0x00000011, + 0x0000350D, 0x00002A13, 0x00000787, 0x000500C7, 0x00000011, 0x00005B53, 0x0000350D, 0x000008A5, + 0x000500C4, 0x00000011, 0x00003570, 0x00005B53, 0x0000074E, 0x00050084, 0x00000011, 0x00006065, + 0x00003570, 0x00001997, 0x0004003D, 0x00000014, 0x00001B5D, 0x00000F48, 0x0007004F, 0x00000011, + 0x0000577F, 0x00001B5D, 0x00001B5D, 0x00000000, 0x00000001, 0x000500C4, 0x00000011, 0x0000545D, + 0x0000577F, 0x0000072A, 0x00050080, 0x00000011, 0x0000234E, 0x00006065, 0x0000545D, 0x0004007C, + 0x00000012, 0x00005FEF, 0x0000234E, 0x0004007C, 0x00000011, 0x00001FB9, 0x00005FEF, 0x000500C7, + 0x0000000B, 0x00006167, 0x00005744, 0x00000A44, 0x00050084, 0x00000011, 0x00002E75, 0x00000A9F, + 0x00001997, 0x00050086, 0x00000011, 0x000041B1, 0x00001FB9, 0x00002E75, 0x00050051, 0x0000000B, + 0x000023A9, 0x000041B1, 0x00000001, 0x00050084, 0x0000000B, 0x00002B26, 0x000023A9, 0x00006167, + 0x00050051, 0x0000000B, 0x000060A5, 0x000041B1, 0x00000000, 0x00050080, 0x0000000B, 0x00005146, + 0x00002B26, 0x000060A5, 0x00050084, 0x00000011, 0x000034D7, 0x000041B1, 0x00002E75, 0x00050082, + 0x00000011, 0x000050EB, 0x00001FB9, 0x000034D7, 0x00050051, 0x0000000B, 0x00001C87, 0x00002E75, + 0x00000000, 0x00050051, 0x0000000B, 0x00005962, 0x00002E75, 0x00000001, 0x00050084, 0x0000000B, + 0x00003372, 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, 0x00003CA0, 0x00005146, 0x00003372, + 0x00050051, 0x0000000B, 0x00003ED4, 0x000050EB, 0x00000001, 0x00050084, 0x0000000B, 0x00003E12, + 0x00003ED4, 0x00001C87, 0x00050051, 0x0000000B, 0x00006059, 0x000050EB, 0x00000000, 0x00050080, + 0x0000000B, 0x000058BA, 0x00003E12, 0x00006059, 0x00050080, 0x0000000B, 0x00003DA0, 0x00003CA0, + 0x000058BA, 0x000500C2, 0x0000000B, 0x00003E82, 0x00003DA0, 0x00000A10, 0x0004003D, 0x00000096, + 0x00001D20, 0x00000E7D, 0x0007005F, 0x0000001D, 0x000040A5, 0x00001D20, 0x00005FEF, 0x00000002, + 0x00000A0B, 0x00050051, 0x0000000D, 0x00005E12, 0x000040A5, 0x00000000, 0x0004003D, 0x00000096, + 0x000024F8, 0x00000E7D, 0x00050080, 0x00000012, 0x0000340C, 0x00005FEF, 0x00000720, 0x0007005F, + 0x0000001D, 0x0000401D, 0x000024F8, 0x0000340C, 0x00000002, 0x00000A0B, 0x00050051, 0x0000000D, + 0x0000297B, 0x0000401D, 0x00000000, 0x0004003D, 0x00000096, 0x000024F9, 0x00000E7D, 0x00050080, + 0x00000012, 0x0000340D, 0x00005FEF, 0x00000729, 0x0007005F, 0x0000001D, 0x0000401E, 0x000024F9, + 0x0000340D, 0x00000002, 0x00000A0B, 0x00050051, 0x0000000D, 0x0000297C, 0x0000401E, 0x00000000, + 0x0004003D, 0x00000096, 0x000024FA, 0x00000E7D, 0x00050080, 0x00000012, 0x0000340E, 0x00005FEF, + 0x00000732, 0x0007005F, 0x0000001D, 0x00004186, 0x000024FA, 0x0000340E, 0x00000002, 0x00000A0B, + 0x00050051, 0x0000000D, 0x00001C58, 0x00004186, 0x00000000, 0x00070050, 0x0000001D, 0x00001957, + 0x00005E12, 0x0000297B, 0x0000297C, 0x00001C58, 0x0004007C, 0x00000017, 0x00004F8E, 0x00001957, + 0x00060041, 0x00000294, 0x0000323C, 0x000012B6, 0x00000A0B, 0x00003E82, 0x0003003E, 0x0000323C, + 0x00004F8E, 0x00050080, 0x0000000B, 0x0000345B, 0x00003E82, 0x00000A0D, 0x0004003D, 0x00000096, + 0x00005FD3, 0x00000E7D, 0x00050080, 0x00000012, 0x00003D64, 0x00005FEF, 0x0000073B, 0x0007005F, + 0x0000001D, 0x0000401F, 0x00005FD3, 0x00003D64, 0x00000002, 0x00000A0B, 0x00050051, 0x0000000D, + 0x0000297D, 0x0000401F, 0x00000000, 0x0004003D, 0x00000096, 0x000024FB, 0x00000E7D, 0x00050080, + 0x00000012, 0x0000340F, 0x00005FEF, 0x00000744, 0x0007005F, 0x0000001D, 0x00004020, 0x000024FB, + 0x0000340F, 0x00000002, 0x00000A0B, 0x00050051, 0x0000000D, 0x0000297E, 0x00004020, 0x00000000, + 0x0004003D, 0x00000096, 0x000024FC, 0x00000E7D, 0x00050080, 0x00000012, 0x00003410, 0x00005FEF, + 0x0000074D, 0x0007005F, 0x0000001D, 0x00004021, 0x000024FC, 0x00003410, 0x00000002, 0x00000A0B, + 0x00050051, 0x0000000D, 0x0000297F, 0x00004021, 0x00000000, 0x0004003D, 0x00000096, 0x000024FD, + 0x00000E7D, 0x00050080, 0x00000012, 0x00003411, 0x00005FEF, 0x00000756, 0x0007005F, 0x0000001D, + 0x00004187, 0x000024FD, 0x00003411, 0x00000002, 0x00000A0B, 0x00050051, 0x0000000D, 0x00001C59, + 0x00004187, 0x00000000, 0x00070050, 0x0000001D, 0x00001958, 0x0000297D, 0x0000297E, 0x0000297F, + 0x00001C59, 0x0004007C, 0x00000017, 0x00004F8F, 0x00001958, 0x00060041, 0x00000294, 0x00003B37, + 0x000012B6, 0x00000A0B, 0x0000345B, 0x0003003E, 0x00003B37, 0x00004F8F, 0x000200F9, 0x00004C7A, + 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/host_depth_store_2xmsaa_cs.h b/src/graphics/shaders/vulkan_spirv/host_depth_store_2xmsaa_cs.h new file mode 100644 index 0000000..45df148 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/host_depth_store_2xmsaa_cs.h @@ -0,0 +1,330 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 24898 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_struct_990 Block + OpMemberDecorate %_struct_990 0 Offset 0 + OpMemberDecorate %_struct_990 1 Offset 4 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonReadable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4790 NonReadable + OpDecorate %4790 Binding 0 + OpDecorate %4790 DescriptorSet 0 + OpDecorate %3709 Binding 0 + OpDecorate %3709 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %bool = OpTypeBool + %uint_2 = OpConstant %uint 2 + %uint_1 = OpConstant %uint 1 + %uint_0 = OpConstant %uint 0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %uint_80 = OpConstant %uint 80 + %uint_16 = OpConstant %uint 16 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %int = OpTypeInt 32 1 + %uint_10 = OpConstant %uint 10 + %1927 = OpConstantComposite %v2uint %uint_0 %uint_10 + %uint_1023 = OpConstant %uint 1023 + %uint_3 = OpConstant %uint 3 + %uint_20 = OpConstant %uint 20 + %uint_13 = OpConstant %uint 13 + %2053 = OpConstantComposite %v2uint %uint_10 %uint_13 + %uint_7 = OpConstant %uint 7 +%_struct_990 = OpTypeStruct %uint %uint +%_ptr_PushConstant__struct_990 = OpTypePointer PushConstant %_struct_990 + %3305 = OpVariable %_ptr_PushConstant__struct_990 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %int_1 = OpConstant %int 1 + %v3uint = OpTypeVector %uint 3 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_ptr_Input_uint = OpTypePointer Input %uint + %v2int = OpTypeVector %int 2 + %int_3 = OpConstant %int 3 + %v4uint = OpTypeVector %uint 4 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4790 = OpVariable %_ptr_Uniform__struct_1972 Uniform + %float = OpTypeFloat 32 + %182 = OpTypeImage %float 2D 0 0 1 1 Unknown +%_ptr_UniformConstant_182 = OpTypePointer UniformConstant %182 + %3709 = OpVariable %_ptr_UniformConstant_182 UniformConstant + %v4float = OpTypeVector %float 4 + %1824 = OpConstantComposite %v2int %int_1 %int_0 + %int_2 = OpConstant %int 2 + %1833 = OpConstantComposite %v2int %int_2 %int_0 + %1842 = OpConstantComposite %v2int %int_3 %int_0 +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint + %int_4 = OpConstant %int 4 + %1851 = OpConstantComposite %v2int %int_4 %int_0 + %int_5 = OpConstant %int 5 + %1860 = OpConstantComposite %v2int %int_5 %int_0 + %int_6 = OpConstant %int 6 + %1869 = OpConstantComposite %v2int %int_6 %int_0 + %int_7 = OpConstant %int 7 + %1878 = OpConstantComposite %v2int %int_7 %int_0 + %uint_8 = OpConstant %uint 8 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %2213 = OpConstantComposite %v2uint %uint_1023 %uint_1023 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %1819 = OpConstantComposite %v2uint %uint_0 %uint_1 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %20439 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %22340 = OpLoad %uint %20439 + %10293 = OpCompositeConstruct %v2uint %22340 %22340 + %24330 = OpShiftRightLogical %v2uint %10293 %2053 + %6551 = OpBitwiseAnd %v2uint %24330 %1954 + %21183 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0 + %23612 = OpLoad %uint %21183 + %21170 = OpShiftRightLogical %uint %15627 %uint_20 + %15922 = OpBitwiseAnd %uint %21170 %uint_1023 + %8846 = OpIAdd %uint %15922 %uint_1 + %11841 = OpCompositeExtract %uint %6551 0 + %17907 = OpIMul %uint %8846 %11841 + %7287 = OpUGreaterThanEqual %bool %23612 %17907 + OpSelectionMerge %16345 DontFlatten + OpBranchConditional %7287 %21992 %16345 + %21992 = OpLabel + OpBranch %19578 + %16345 = OpLabel + %10771 = OpCompositeConstruct %v2uint %15627 %15627 + %13581 = OpShiftRightLogical %v2uint %10771 %1927 + %23379 = OpBitwiseAnd %v2uint %13581 %2213 + %16245 = OpShiftLeftLogical %v2uint %23379 %1870 + %20127 = OpIMul %v2uint %16245 %6551 + %19539 = OpShiftLeftLogical %uint %23612 %uint_3 + %17126 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_1 + %22160 = OpLoad %uint %17126 + %22686 = OpShiftRightLogical %uint %22160 %uint_1 + %6471 = OpCompositeConstruct %v2uint %19539 %22686 + %9483 = OpIAdd %v2uint %20127 %6471 + %13160 = OpBitcast %v2int %9483 + %11709 = OpBitwiseAnd %uint %22160 %uint_1 + %11164 = OpBitcast %v2uint %13160 + %24897 = OpBitwiseAnd %uint %22340 %uint_1023 + %13947 = OpShiftLeftLogical %v2uint %11164 %1819 + %10422 = OpCompositeConstruct %v2uint %11709 %11709 + %9093 = OpShiftRightLogical %v2uint %10422 %1816 + %16072 = OpBitwiseAnd %v2uint %9093 %1828 + %19132 = OpIAdd %v2uint %13947 %16072 + %11447 = OpIMul %v2uint %2719 %6551 + %7983 = OpUDiv %v2uint %19132 %11447 + %9129 = OpCompositeExtract %uint %7983 1 + %11046 = OpIMul %uint %9129 %24897 + %24741 = OpCompositeExtract %uint %7983 0 + %20806 = OpIAdd %uint %11046 %24741 + %13527 = OpIMul %v2uint %7983 %11447 + %20715 = OpISub %v2uint %19132 %13527 + %7303 = OpCompositeExtract %uint %11447 0 + %22882 = OpCompositeExtract %uint %11447 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %20806 %13170 + %16084 = OpCompositeExtract %uint %20715 1 + %15890 = OpIMul %uint %16084 %7303 + %24665 = OpCompositeExtract %uint %20715 0 + %22714 = OpIAdd %uint %15890 %24665 + %18303 = OpIAdd %uint %15520 %22714 + %14040 = OpShiftRightLogical %uint %18303 %uint_2 + %13780 = OpShiftRightLogical %uint %22340 %uint_16 + %12661 = OpBitwiseAnd %uint %13780 %uint_1 + %11491 = OpINotEqual %bool %12661 %uint_0 + OpSelectionMerge %8129 None + OpBranchConditional %11491 %22983 %14914 + %14914 = OpLabel + %24444 = OpINotEqual %bool %11709 %uint_0 + %20803 = OpSelect %int %24444 %int_3 %int_0 + OpBranch %8129 + %22983 = OpLabel + %7795 = OpINotEqual %bool %11709 %uint_0 + %20804 = OpSelect %int %7795 %int_0 %int_1 + OpBranch %8129 + %8129 = OpLabel + %21086 = OpPhi %int %20804 %22983 %20803 %14914 + %12853 = OpLoad %182 %3709 + %22167 = OpImageFetch %v4float %12853 %13160 Sample %21086 + %24082 = OpCompositeExtract %float %22167 0 + %9464 = OpLoad %182 %3709 + %13324 = OpIAdd %v2int %13160 %1824 + %16413 = OpImageFetch %v4float %9464 %13324 Sample %21086 + %10619 = OpCompositeExtract %float %16413 0 + %9465 = OpLoad %182 %3709 + %13325 = OpIAdd %v2int %13160 %1833 + %16414 = OpImageFetch %v4float %9465 %13325 Sample %21086 + %10620 = OpCompositeExtract %float %16414 0 + %9466 = OpLoad %182 %3709 + %13326 = OpIAdd %v2int %13160 %1842 + %16774 = OpImageFetch %v4float %9466 %13326 Sample %21086 + %7256 = OpCompositeExtract %float %16774 0 + %6487 = OpCompositeConstruct %v4float %24082 %10619 %10620 %7256 + %20366 = OpBitcast %v4uint %6487 + %12860 = OpAccessChain %_ptr_Uniform_v4uint %4790 %int_0 %14040 + OpStore %12860 %20366 + %13403 = OpIAdd %uint %14040 %uint_1 + %24531 = OpLoad %182 %3709 + %15716 = OpIAdd %v2int %13160 %1851 + %16415 = OpImageFetch %v4float %24531 %15716 Sample %21086 + %10621 = OpCompositeExtract %float %16415 0 + %9467 = OpLoad %182 %3709 + %13327 = OpIAdd %v2int %13160 %1860 + %16416 = OpImageFetch %v4float %9467 %13327 Sample %21086 + %10622 = OpCompositeExtract %float %16416 0 + %9468 = OpLoad %182 %3709 + %13328 = OpIAdd %v2int %13160 %1869 + %16417 = OpImageFetch %v4float %9468 %13328 Sample %21086 + %10623 = OpCompositeExtract %float %16417 0 + %9469 = OpLoad %182 %3709 + %13329 = OpIAdd %v2int %13160 %1878 + %16775 = OpImageFetch %v4float %9469 %13329 Sample %21086 + %7257 = OpCompositeExtract %float %16775 0 + %6488 = OpCompositeConstruct %v4float %10621 %10622 %10623 %7257 + %20367 = OpBitcast %v4uint %6488 + %15159 = OpAccessChain %_ptr_Uniform_v4uint %4790 %int_0 %13403 + OpStore %15159 %20367 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t host_depth_store_2xmsaa_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006142, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00030047, 0x000003DE, 0x00000002, 0x00050048, + 0x000003DE, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x000003DE, 0x00000001, 0x00000023, + 0x00000004, 0x00040047, 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, + 0x00000010, 0x00030047, 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000019, + 0x00050048, 0x000007B4, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x000012B6, 0x00000019, + 0x00040047, 0x000012B6, 0x00000021, 0x00000000, 0x00040047, 0x000012B6, 0x00000022, 0x00000000, + 0x00040047, 0x00000E7D, 0x00000021, 0x00000000, 0x00040047, 0x00000E7D, 0x00000022, 0x00000001, + 0x00040047, 0x00000AC7, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, + 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, + 0x00000002, 0x00020014, 0x00000009, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0005002C, + 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, 0x0005002C, 0x00000011, 0x00000718, 0x00000A0D, + 0x00000A0A, 0x0004002B, 0x0000000B, 0x00000AFA, 0x00000050, 0x0004002B, 0x0000000B, 0x00000A3A, + 0x00000010, 0x0005002C, 0x00000011, 0x00000A9F, 0x00000AFA, 0x00000A3A, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0005002C, 0x00000011, + 0x00000787, 0x00000A0A, 0x00000A28, 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, 0x0004002B, + 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A46, 0x00000014, 0x0004002B, + 0x0000000B, 0x00000A31, 0x0000000D, 0x0005002C, 0x00000011, 0x00000805, 0x00000A28, 0x00000A31, + 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004001E, 0x000003DE, 0x0000000B, 0x0000000B, + 0x00040020, 0x0000065B, 0x00000009, 0x000003DE, 0x0004003B, 0x0000065B, 0x00000CE9, 0x00000009, + 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x00040020, 0x00000291, 0x00000001, 0x00000014, 0x0004003B, 0x00000291, 0x00000F48, 0x00000001, + 0x00040020, 0x00000289, 0x00000001, 0x0000000B, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A32, 0x000012B6, 0x00000002, 0x00030016, 0x0000000D, + 0x00000020, 0x00090019, 0x000000B6, 0x0000000D, 0x00000001, 0x00000000, 0x00000000, 0x00000001, + 0x00000001, 0x00000000, 0x00040020, 0x00000333, 0x00000000, 0x000000B6, 0x0004003B, 0x00000333, + 0x00000E7D, 0x00000000, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x0005002C, 0x00000012, + 0x00000720, 0x00000A0E, 0x00000A0B, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0005002C, + 0x00000012, 0x00000729, 0x00000A11, 0x00000A0B, 0x0005002C, 0x00000012, 0x00000732, 0x00000A14, + 0x00000A0B, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0004002B, 0x0000000C, 0x00000A17, + 0x00000004, 0x0005002C, 0x00000012, 0x0000073B, 0x00000A17, 0x00000A0B, 0x0004002B, 0x0000000C, + 0x00000A1A, 0x00000005, 0x0005002C, 0x00000012, 0x00000744, 0x00000A1A, 0x00000A0B, 0x0004002B, + 0x0000000C, 0x00000A1D, 0x00000006, 0x0005002C, 0x00000012, 0x0000074D, 0x00000A1D, 0x00000A0B, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0005002C, 0x00000012, 0x00000756, 0x00000A20, + 0x00000A0B, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0006002C, 0x00000014, 0x00000AC7, + 0x00000A22, 0x00000A22, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, + 0x0005002C, 0x00000011, 0x000008A5, 0x00000A44, 0x00000A44, 0x0005002C, 0x00000011, 0x0000074E, + 0x00000A13, 0x00000A13, 0x0005002C, 0x00000011, 0x0000071B, 0x00000A0A, 0x00000A0D, 0x00050036, + 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, + 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, + 0x000056E5, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003D0B, 0x000056E5, 0x00050041, + 0x00000288, 0x00004FD7, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005744, 0x00004FD7, + 0x00050050, 0x00000011, 0x00002835, 0x00005744, 0x00005744, 0x000500C2, 0x00000011, 0x00005F0A, + 0x00002835, 0x00000805, 0x000500C7, 0x00000011, 0x00001997, 0x00005F0A, 0x000007A2, 0x00050041, + 0x00000289, 0x000052BF, 0x00000F48, 0x00000A0A, 0x0004003D, 0x0000000B, 0x00005C3C, 0x000052BF, + 0x000500C2, 0x0000000B, 0x000052B2, 0x00003D0B, 0x00000A46, 0x000500C7, 0x0000000B, 0x00003E32, + 0x000052B2, 0x00000A44, 0x00050080, 0x0000000B, 0x0000228E, 0x00003E32, 0x00000A0D, 0x00050051, + 0x0000000B, 0x00002E41, 0x00001997, 0x00000000, 0x00050084, 0x0000000B, 0x000045F3, 0x0000228E, + 0x00002E41, 0x000500AE, 0x00000009, 0x00001C77, 0x00005C3C, 0x000045F3, 0x000300F7, 0x00003FD9, + 0x00000002, 0x000400FA, 0x00001C77, 0x000055E8, 0x00003FD9, 0x000200F8, 0x000055E8, 0x000200F9, + 0x00004C7A, 0x000200F8, 0x00003FD9, 0x00050050, 0x00000011, 0x00002A13, 0x00003D0B, 0x00003D0B, + 0x000500C2, 0x00000011, 0x0000350D, 0x00002A13, 0x00000787, 0x000500C7, 0x00000011, 0x00005B53, + 0x0000350D, 0x000008A5, 0x000500C4, 0x00000011, 0x00003F75, 0x00005B53, 0x0000074E, 0x00050084, + 0x00000011, 0x00004E9F, 0x00003F75, 0x00001997, 0x000500C4, 0x0000000B, 0x00004C53, 0x00005C3C, + 0x00000A13, 0x00050041, 0x00000289, 0x000042E6, 0x00000F48, 0x00000A0D, 0x0004003D, 0x0000000B, + 0x00005690, 0x000042E6, 0x000500C2, 0x0000000B, 0x0000589E, 0x00005690, 0x00000A0D, 0x00050050, + 0x00000011, 0x00001947, 0x00004C53, 0x0000589E, 0x00050080, 0x00000011, 0x0000250B, 0x00004E9F, + 0x00001947, 0x0004007C, 0x00000012, 0x00003368, 0x0000250B, 0x000500C7, 0x0000000B, 0x00002DBD, + 0x00005690, 0x00000A0D, 0x0004007C, 0x00000011, 0x00002B9C, 0x00003368, 0x000500C7, 0x0000000B, + 0x00006141, 0x00005744, 0x00000A44, 0x000500C4, 0x00000011, 0x0000367B, 0x00002B9C, 0x0000071B, + 0x00050050, 0x00000011, 0x000028B6, 0x00002DBD, 0x00002DBD, 0x000500C2, 0x00000011, 0x00002385, + 0x000028B6, 0x00000718, 0x000500C7, 0x00000011, 0x00003EC8, 0x00002385, 0x00000724, 0x00050080, + 0x00000011, 0x00004ABC, 0x0000367B, 0x00003EC8, 0x00050084, 0x00000011, 0x00002CB7, 0x00000A9F, + 0x00001997, 0x00050086, 0x00000011, 0x00001F2F, 0x00004ABC, 0x00002CB7, 0x00050051, 0x0000000B, + 0x000023A9, 0x00001F2F, 0x00000001, 0x00050084, 0x0000000B, 0x00002B26, 0x000023A9, 0x00006141, + 0x00050051, 0x0000000B, 0x000060A5, 0x00001F2F, 0x00000000, 0x00050080, 0x0000000B, 0x00005146, + 0x00002B26, 0x000060A5, 0x00050084, 0x00000011, 0x000034D7, 0x00001F2F, 0x00002CB7, 0x00050082, + 0x00000011, 0x000050EB, 0x00004ABC, 0x000034D7, 0x00050051, 0x0000000B, 0x00001C87, 0x00002CB7, + 0x00000000, 0x00050051, 0x0000000B, 0x00005962, 0x00002CB7, 0x00000001, 0x00050084, 0x0000000B, + 0x00003372, 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, 0x00003CA0, 0x00005146, 0x00003372, + 0x00050051, 0x0000000B, 0x00003ED4, 0x000050EB, 0x00000001, 0x00050084, 0x0000000B, 0x00003E12, + 0x00003ED4, 0x00001C87, 0x00050051, 0x0000000B, 0x00006059, 0x000050EB, 0x00000000, 0x00050080, + 0x0000000B, 0x000058BA, 0x00003E12, 0x00006059, 0x00050080, 0x0000000B, 0x0000477F, 0x00003CA0, + 0x000058BA, 0x000500C2, 0x0000000B, 0x000036D8, 0x0000477F, 0x00000A10, 0x000500C2, 0x0000000B, + 0x000035D4, 0x00005744, 0x00000A3A, 0x000500C7, 0x0000000B, 0x00003175, 0x000035D4, 0x00000A0D, + 0x000500AB, 0x00000009, 0x00002CE3, 0x00003175, 0x00000A0A, 0x000300F7, 0x00001FC1, 0x00000000, + 0x000400FA, 0x00002CE3, 0x000059C7, 0x00003A42, 0x000200F8, 0x00003A42, 0x000500AB, 0x00000009, + 0x00005F7C, 0x00002DBD, 0x00000A0A, 0x000600A9, 0x0000000C, 0x00005143, 0x00005F7C, 0x00000A14, + 0x00000A0B, 0x000200F9, 0x00001FC1, 0x000200F8, 0x000059C7, 0x000500AB, 0x00000009, 0x00001E73, + 0x00002DBD, 0x00000A0A, 0x000600A9, 0x0000000C, 0x00005144, 0x00001E73, 0x00000A0B, 0x00000A0E, + 0x000200F9, 0x00001FC1, 0x000200F8, 0x00001FC1, 0x000700F5, 0x0000000C, 0x0000525E, 0x00005144, + 0x000059C7, 0x00005143, 0x00003A42, 0x0004003D, 0x000000B6, 0x00003235, 0x00000E7D, 0x0007005F, + 0x0000001D, 0x00005697, 0x00003235, 0x00003368, 0x00000040, 0x0000525E, 0x00050051, 0x0000000D, + 0x00005E12, 0x00005697, 0x00000000, 0x0004003D, 0x000000B6, 0x000024F8, 0x00000E7D, 0x00050080, + 0x00000012, 0x0000340C, 0x00003368, 0x00000720, 0x0007005F, 0x0000001D, 0x0000401D, 0x000024F8, + 0x0000340C, 0x00000040, 0x0000525E, 0x00050051, 0x0000000D, 0x0000297B, 0x0000401D, 0x00000000, + 0x0004003D, 0x000000B6, 0x000024F9, 0x00000E7D, 0x00050080, 0x00000012, 0x0000340D, 0x00003368, + 0x00000729, 0x0007005F, 0x0000001D, 0x0000401E, 0x000024F9, 0x0000340D, 0x00000040, 0x0000525E, + 0x00050051, 0x0000000D, 0x0000297C, 0x0000401E, 0x00000000, 0x0004003D, 0x000000B6, 0x000024FA, + 0x00000E7D, 0x00050080, 0x00000012, 0x0000340E, 0x00003368, 0x00000732, 0x0007005F, 0x0000001D, + 0x00004186, 0x000024FA, 0x0000340E, 0x00000040, 0x0000525E, 0x00050051, 0x0000000D, 0x00001C58, + 0x00004186, 0x00000000, 0x00070050, 0x0000001D, 0x00001957, 0x00005E12, 0x0000297B, 0x0000297C, + 0x00001C58, 0x0004007C, 0x00000017, 0x00004F8E, 0x00001957, 0x00060041, 0x00000294, 0x0000323C, + 0x000012B6, 0x00000A0B, 0x000036D8, 0x0003003E, 0x0000323C, 0x00004F8E, 0x00050080, 0x0000000B, + 0x0000345B, 0x000036D8, 0x00000A0D, 0x0004003D, 0x000000B6, 0x00005FD3, 0x00000E7D, 0x00050080, + 0x00000012, 0x00003D64, 0x00003368, 0x0000073B, 0x0007005F, 0x0000001D, 0x0000401F, 0x00005FD3, + 0x00003D64, 0x00000040, 0x0000525E, 0x00050051, 0x0000000D, 0x0000297D, 0x0000401F, 0x00000000, + 0x0004003D, 0x000000B6, 0x000024FB, 0x00000E7D, 0x00050080, 0x00000012, 0x0000340F, 0x00003368, + 0x00000744, 0x0007005F, 0x0000001D, 0x00004020, 0x000024FB, 0x0000340F, 0x00000040, 0x0000525E, + 0x00050051, 0x0000000D, 0x0000297E, 0x00004020, 0x00000000, 0x0004003D, 0x000000B6, 0x000024FC, + 0x00000E7D, 0x00050080, 0x00000012, 0x00003410, 0x00003368, 0x0000074D, 0x0007005F, 0x0000001D, + 0x00004021, 0x000024FC, 0x00003410, 0x00000040, 0x0000525E, 0x00050051, 0x0000000D, 0x0000297F, + 0x00004021, 0x00000000, 0x0004003D, 0x000000B6, 0x000024FD, 0x00000E7D, 0x00050080, 0x00000012, + 0x00003411, 0x00003368, 0x00000756, 0x0007005F, 0x0000001D, 0x00004187, 0x000024FD, 0x00003411, + 0x00000040, 0x0000525E, 0x00050051, 0x0000000D, 0x00001C59, 0x00004187, 0x00000000, 0x00070050, + 0x0000001D, 0x00001958, 0x0000297D, 0x0000297E, 0x0000297F, 0x00001C59, 0x0004007C, 0x00000017, + 0x00004F8F, 0x00001958, 0x00060041, 0x00000294, 0x00003B37, 0x000012B6, 0x00000A0B, 0x0000345B, + 0x0003003E, 0x00003B37, 0x00004F8F, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, + 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/host_depth_store_4xmsaa_cs.h b/src/graphics/shaders/vulkan_spirv/host_depth_store_4xmsaa_cs.h new file mode 100644 index 0000000..dde518e --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/host_depth_store_4xmsaa_cs.h @@ -0,0 +1,291 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 24742 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_struct_990 Block + OpMemberDecorate %_struct_990 0 Offset 0 + OpMemberDecorate %_struct_990 1 Offset 4 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonReadable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4790 NonReadable + OpDecorate %4790 Binding 0 + OpDecorate %4790 DescriptorSet 0 + OpDecorate %3709 Binding 0 + OpDecorate %3709 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %bool = OpTypeBool + %uint_2 = OpConstant %uint 2 + %uint_1 = OpConstant %uint 1 + %uint_0 = OpConstant %uint 0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %uint_80 = OpConstant %uint 80 + %uint_16 = OpConstant %uint 16 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %int = OpTypeInt 32 1 + %uint_10 = OpConstant %uint 10 + %1927 = OpConstantComposite %v2uint %uint_0 %uint_10 + %uint_1023 = OpConstant %uint 1023 + %uint_3 = OpConstant %uint 3 + %uint_20 = OpConstant %uint 20 + %uint_13 = OpConstant %uint 13 + %2053 = OpConstantComposite %v2uint %uint_10 %uint_13 + %uint_7 = OpConstant %uint 7 +%_struct_990 = OpTypeStruct %uint %uint +%_ptr_PushConstant__struct_990 = OpTypePointer PushConstant %_struct_990 + %3305 = OpVariable %_ptr_PushConstant__struct_990 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %int_1 = OpConstant %int 1 + %v3uint = OpTypeVector %uint 3 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_ptr_Input_uint = OpTypePointer Input %uint + %v2int = OpTypeVector %int 2 + %v4uint = OpTypeVector %uint 4 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4790 = OpVariable %_ptr_Uniform__struct_1972 Uniform + %float = OpTypeFloat 32 + %182 = OpTypeImage %float 2D 0 0 1 1 Unknown +%_ptr_UniformConstant_182 = OpTypePointer UniformConstant %182 + %3709 = OpVariable %_ptr_UniformConstant_182 UniformConstant + %v4float = OpTypeVector %float 4 + %1824 = OpConstantComposite %v2int %int_1 %int_0 +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint + %int_2 = OpConstant %int 2 + %1833 = OpConstantComposite %v2int %int_2 %int_0 + %int_3 = OpConstant %int 3 + %1842 = OpConstantComposite %v2int %int_3 %int_0 + %uint_8 = OpConstant %uint 8 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %2213 = OpConstantComposite %v2uint %uint_1023 %uint_1023 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %20439 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %22340 = OpLoad %uint %20439 + %10293 = OpCompositeConstruct %v2uint %22340 %22340 + %24330 = OpShiftRightLogical %v2uint %10293 %2053 + %6551 = OpBitwiseAnd %v2uint %24330 %1954 + %21183 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0 + %23517 = OpLoad %uint %21183 + %23384 = OpShiftRightLogical %uint %23517 %uint_1 + %7355 = OpShiftRightLogical %uint %15627 %uint_20 + %16946 = OpBitwiseAnd %uint %7355 %uint_1023 + %8846 = OpIAdd %uint %16946 %uint_1 + %11841 = OpCompositeExtract %uint %6551 0 + %17907 = OpIMul %uint %8846 %11841 + %7287 = OpUGreaterThanEqual %bool %23384 %17907 + OpSelectionMerge %16345 DontFlatten + OpBranchConditional %7287 %21992 %16345 + %21992 = OpLabel + OpBranch %19578 + %16345 = OpLabel + %10771 = OpCompositeConstruct %v2uint %15627 %15627 + %13581 = OpShiftRightLogical %v2uint %10771 %1927 + %23379 = OpBitwiseAnd %v2uint %13581 %2213 + %16245 = OpShiftLeftLogical %v2uint %23379 %1870 + %20127 = OpIMul %v2uint %16245 %6551 + %19539 = OpShiftLeftLogical %uint %23517 %uint_2 + %17126 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_1 + %22160 = OpLoad %uint %17126 + %22686 = OpShiftRightLogical %uint %22160 %uint_1 + %6471 = OpCompositeConstruct %v2uint %19539 %22686 + %8058 = OpIAdd %v2uint %20127 %6471 + %8432 = OpBitcast %v2int %8058 + %7291 = OpBitcast %v2uint %8432 + %22610 = OpShiftLeftLogical %v2uint %7291 %1828 + %8742 = OpLoad %v3uint %gl_GlobalInvocationID + %16994 = OpVectorShuffle %v2uint %8742 %8742 0 1 + %24648 = OpBitwiseAnd %v2uint %16994 %1828 + %14895 = OpBitwiseOr %v2uint %22610 %24648 + %10861 = OpBitwiseAnd %uint %22340 %uint_1023 + %22341 = OpIMul %v2uint %2719 %6551 + %16817 = OpUDiv %v2uint %14895 %22341 + %9129 = OpCompositeExtract %uint %16817 1 + %11046 = OpIMul %uint %9129 %10861 + %24741 = OpCompositeExtract %uint %16817 0 + %20806 = OpIAdd %uint %11046 %24741 + %13527 = OpIMul %v2uint %16817 %22341 + %20715 = OpISub %v2uint %14895 %13527 + %7303 = OpCompositeExtract %uint %22341 0 + %22882 = OpCompositeExtract %uint %22341 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %20806 %13170 + %16084 = OpCompositeExtract %uint %20715 1 + %15890 = OpIMul %uint %16084 %7303 + %24665 = OpCompositeExtract %uint %20715 0 + %22714 = OpIAdd %uint %15890 %24665 + %18398 = OpIAdd %uint %15520 %22714 + %13118 = OpShiftRightLogical %uint %18398 %uint_2 + %10583 = OpBitwiseAnd %uint %22160 %uint_1 + %16337 = OpShiftLeftLogical %uint %10583 %uint_1 + %21075 = OpBitcast %int %16337 + %8163 = OpIAdd %int %21075 %int_1 + %22164 = OpLoad %182 %3709 + %8519 = OpImageFetch %v4float %22164 %8432 Sample %21075 + %23455 = OpCompositeExtract %float %8519 0 + %14907 = OpLoad %182 %3709 + %18741 = OpImageFetch %v4float %14907 %8432 Sample %8163 + %24082 = OpCompositeExtract %float %18741 0 + %9464 = OpLoad %182 %3709 + %13324 = OpIAdd %v2int %8432 %1824 + %16413 = OpImageFetch %v4float %9464 %13324 Sample %21075 + %9992 = OpCompositeExtract %float %16413 0 + %14908 = OpLoad %182 %3709 + %19102 = OpImageFetch %v4float %14908 %13324 Sample %8163 + %20719 = OpCompositeExtract %float %19102 0 + %6487 = OpCompositeConstruct %v4float %23455 %24082 %9992 %20719 + %20366 = OpBitcast %v4uint %6487 + %12860 = OpAccessChain %_ptr_Uniform_v4uint %4790 %int_0 %13118 + OpStore %12860 %20366 + %13403 = OpIAdd %uint %13118 %uint_1 + %24531 = OpLoad %182 %3709 + %15716 = OpIAdd %v2int %8432 %1833 + %16414 = OpImageFetch %v4float %24531 %15716 Sample %21075 + %9993 = OpCompositeExtract %float %16414 0 + %14909 = OpLoad %182 %3709 + %18742 = OpImageFetch %v4float %14909 %15716 Sample %8163 + %24083 = OpCompositeExtract %float %18742 0 + %9465 = OpLoad %182 %3709 + %13325 = OpIAdd %v2int %8432 %1842 + %16415 = OpImageFetch %v4float %9465 %13325 Sample %21075 + %9994 = OpCompositeExtract %float %16415 0 + %14910 = OpLoad %182 %3709 + %19103 = OpImageFetch %v4float %14910 %13325 Sample %8163 + %20720 = OpCompositeExtract %float %19103 0 + %6488 = OpCompositeConstruct %v4float %9993 %24083 %9994 %20720 + %20367 = OpBitcast %v4uint %6488 + %15159 = OpAccessChain %_ptr_Uniform_v4uint %4790 %int_0 %13403 + OpStore %15159 %20367 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t host_depth_store_4xmsaa_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000060A6, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00030047, 0x000003DE, 0x00000002, 0x00050048, + 0x000003DE, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x000003DE, 0x00000001, 0x00000023, + 0x00000004, 0x00040047, 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, + 0x00000010, 0x00030047, 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000019, + 0x00050048, 0x000007B4, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x000012B6, 0x00000019, + 0x00040047, 0x000012B6, 0x00000021, 0x00000000, 0x00040047, 0x000012B6, 0x00000022, 0x00000000, + 0x00040047, 0x00000E7D, 0x00000021, 0x00000000, 0x00040047, 0x00000E7D, 0x00000022, 0x00000001, + 0x00040047, 0x00000AC7, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, + 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, + 0x00000002, 0x00020014, 0x00000009, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0005002C, + 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, 0x0004002B, 0x0000000B, 0x00000AFA, 0x00000050, + 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0005002C, 0x00000011, 0x00000A9F, 0x00000AFA, + 0x00000A3A, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A28, + 0x0000000A, 0x0005002C, 0x00000011, 0x00000787, 0x00000A0A, 0x00000A28, 0x0004002B, 0x0000000B, + 0x00000A44, 0x000003FF, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, + 0x00000A46, 0x00000014, 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, 0x0005002C, 0x00000011, + 0x00000805, 0x00000A28, 0x00000A31, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004001E, + 0x000003DE, 0x0000000B, 0x0000000B, 0x00040020, 0x0000065B, 0x00000009, 0x000003DE, 0x0004003B, + 0x0000065B, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, + 0x00000288, 0x00000009, 0x0000000B, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x00040017, + 0x00000014, 0x0000000B, 0x00000003, 0x00040020, 0x00000291, 0x00000001, 0x00000014, 0x0004003B, + 0x00000291, 0x00000F48, 0x00000001, 0x00040020, 0x00000289, 0x00000001, 0x0000000B, 0x00040017, + 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x0003001D, + 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, + 0x000007B4, 0x0004003B, 0x00000A32, 0x000012B6, 0x00000002, 0x00030016, 0x0000000D, 0x00000020, + 0x00090019, 0x000000B6, 0x0000000D, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x00000000, 0x00040020, 0x00000333, 0x00000000, 0x000000B6, 0x0004003B, 0x00000333, 0x00000E7D, + 0x00000000, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x0005002C, 0x00000012, 0x00000720, + 0x00000A0E, 0x00000A0B, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0004002B, 0x0000000C, + 0x00000A11, 0x00000002, 0x0005002C, 0x00000012, 0x00000729, 0x00000A11, 0x00000A0B, 0x0004002B, + 0x0000000C, 0x00000A14, 0x00000003, 0x0005002C, 0x00000012, 0x00000732, 0x00000A14, 0x00000A0B, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0006002C, 0x00000014, 0x00000AC7, 0x00000A22, + 0x00000A22, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0005002C, + 0x00000011, 0x000008A5, 0x00000A44, 0x00000A44, 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, + 0x00000A13, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, + 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, + 0x00050041, 0x00000288, 0x000056E5, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003D0B, + 0x000056E5, 0x00050041, 0x00000288, 0x00004FD7, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, + 0x00005744, 0x00004FD7, 0x00050050, 0x00000011, 0x00002835, 0x00005744, 0x00005744, 0x000500C2, + 0x00000011, 0x00005F0A, 0x00002835, 0x00000805, 0x000500C7, 0x00000011, 0x00001997, 0x00005F0A, + 0x000007A2, 0x00050041, 0x00000289, 0x000052BF, 0x00000F48, 0x00000A0A, 0x0004003D, 0x0000000B, + 0x00005BDD, 0x000052BF, 0x000500C2, 0x0000000B, 0x00005B58, 0x00005BDD, 0x00000A0D, 0x000500C2, + 0x0000000B, 0x00001CBB, 0x00003D0B, 0x00000A46, 0x000500C7, 0x0000000B, 0x00004232, 0x00001CBB, + 0x00000A44, 0x00050080, 0x0000000B, 0x0000228E, 0x00004232, 0x00000A0D, 0x00050051, 0x0000000B, + 0x00002E41, 0x00001997, 0x00000000, 0x00050084, 0x0000000B, 0x000045F3, 0x0000228E, 0x00002E41, + 0x000500AE, 0x00000009, 0x00001C77, 0x00005B58, 0x000045F3, 0x000300F7, 0x00003FD9, 0x00000002, + 0x000400FA, 0x00001C77, 0x000055E8, 0x00003FD9, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, + 0x000200F8, 0x00003FD9, 0x00050050, 0x00000011, 0x00002A13, 0x00003D0B, 0x00003D0B, 0x000500C2, + 0x00000011, 0x0000350D, 0x00002A13, 0x00000787, 0x000500C7, 0x00000011, 0x00005B53, 0x0000350D, + 0x000008A5, 0x000500C4, 0x00000011, 0x00003F75, 0x00005B53, 0x0000074E, 0x00050084, 0x00000011, + 0x00004E9F, 0x00003F75, 0x00001997, 0x000500C4, 0x0000000B, 0x00004C53, 0x00005BDD, 0x00000A10, + 0x00050041, 0x00000289, 0x000042E6, 0x00000F48, 0x00000A0D, 0x0004003D, 0x0000000B, 0x00005690, + 0x000042E6, 0x000500C2, 0x0000000B, 0x0000589E, 0x00005690, 0x00000A0D, 0x00050050, 0x00000011, + 0x00001947, 0x00004C53, 0x0000589E, 0x00050080, 0x00000011, 0x00001F7A, 0x00004E9F, 0x00001947, + 0x0004007C, 0x00000012, 0x000020F0, 0x00001F7A, 0x0004007C, 0x00000011, 0x00001C7B, 0x000020F0, + 0x000500C4, 0x00000011, 0x00005852, 0x00001C7B, 0x00000724, 0x0004003D, 0x00000014, 0x00002226, + 0x00000F48, 0x0007004F, 0x00000011, 0x00004262, 0x00002226, 0x00002226, 0x00000000, 0x00000001, + 0x000500C7, 0x00000011, 0x00006048, 0x00004262, 0x00000724, 0x000500C5, 0x00000011, 0x00003A2F, + 0x00005852, 0x00006048, 0x000500C7, 0x0000000B, 0x00002A6D, 0x00005744, 0x00000A44, 0x00050084, + 0x00000011, 0x00005745, 0x00000A9F, 0x00001997, 0x00050086, 0x00000011, 0x000041B1, 0x00003A2F, + 0x00005745, 0x00050051, 0x0000000B, 0x000023A9, 0x000041B1, 0x00000001, 0x00050084, 0x0000000B, + 0x00002B26, 0x000023A9, 0x00002A6D, 0x00050051, 0x0000000B, 0x000060A5, 0x000041B1, 0x00000000, + 0x00050080, 0x0000000B, 0x00005146, 0x00002B26, 0x000060A5, 0x00050084, 0x00000011, 0x000034D7, + 0x000041B1, 0x00005745, 0x00050082, 0x00000011, 0x000050EB, 0x00003A2F, 0x000034D7, 0x00050051, + 0x0000000B, 0x00001C87, 0x00005745, 0x00000000, 0x00050051, 0x0000000B, 0x00005962, 0x00005745, + 0x00000001, 0x00050084, 0x0000000B, 0x00003372, 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, + 0x00003CA0, 0x00005146, 0x00003372, 0x00050051, 0x0000000B, 0x00003ED4, 0x000050EB, 0x00000001, + 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, 0x00001C87, 0x00050051, 0x0000000B, 0x00006059, + 0x000050EB, 0x00000000, 0x00050080, 0x0000000B, 0x000058BA, 0x00003E12, 0x00006059, 0x00050080, + 0x0000000B, 0x000047DE, 0x00003CA0, 0x000058BA, 0x000500C2, 0x0000000B, 0x0000333E, 0x000047DE, + 0x00000A10, 0x000500C7, 0x0000000B, 0x00002957, 0x00005690, 0x00000A0D, 0x000500C4, 0x0000000B, + 0x00003FD1, 0x00002957, 0x00000A0D, 0x0004007C, 0x0000000C, 0x00005253, 0x00003FD1, 0x00050080, + 0x0000000C, 0x00001FE3, 0x00005253, 0x00000A0E, 0x0004003D, 0x000000B6, 0x00005694, 0x00000E7D, + 0x0007005F, 0x0000001D, 0x00002147, 0x00005694, 0x000020F0, 0x00000040, 0x00005253, 0x00050051, + 0x0000000D, 0x00005B9F, 0x00002147, 0x00000000, 0x0004003D, 0x000000B6, 0x00003A3B, 0x00000E7D, + 0x0007005F, 0x0000001D, 0x00004935, 0x00003A3B, 0x000020F0, 0x00000040, 0x00001FE3, 0x00050051, + 0x0000000D, 0x00005E12, 0x00004935, 0x00000000, 0x0004003D, 0x000000B6, 0x000024F8, 0x00000E7D, + 0x00050080, 0x00000012, 0x0000340C, 0x000020F0, 0x00000720, 0x0007005F, 0x0000001D, 0x0000401D, + 0x000024F8, 0x0000340C, 0x00000040, 0x00005253, 0x00050051, 0x0000000D, 0x00002708, 0x0000401D, + 0x00000000, 0x0004003D, 0x000000B6, 0x00003A3C, 0x00000E7D, 0x0007005F, 0x0000001D, 0x00004A9E, + 0x00003A3C, 0x0000340C, 0x00000040, 0x00001FE3, 0x00050051, 0x0000000D, 0x000050EF, 0x00004A9E, + 0x00000000, 0x00070050, 0x0000001D, 0x00001957, 0x00005B9F, 0x00005E12, 0x00002708, 0x000050EF, + 0x0004007C, 0x00000017, 0x00004F8E, 0x00001957, 0x00060041, 0x00000294, 0x0000323C, 0x000012B6, + 0x00000A0B, 0x0000333E, 0x0003003E, 0x0000323C, 0x00004F8E, 0x00050080, 0x0000000B, 0x0000345B, + 0x0000333E, 0x00000A0D, 0x0004003D, 0x000000B6, 0x00005FD3, 0x00000E7D, 0x00050080, 0x00000012, + 0x00003D64, 0x000020F0, 0x00000729, 0x0007005F, 0x0000001D, 0x0000401E, 0x00005FD3, 0x00003D64, + 0x00000040, 0x00005253, 0x00050051, 0x0000000D, 0x00002709, 0x0000401E, 0x00000000, 0x0004003D, + 0x000000B6, 0x00003A3D, 0x00000E7D, 0x0007005F, 0x0000001D, 0x00004936, 0x00003A3D, 0x00003D64, + 0x00000040, 0x00001FE3, 0x00050051, 0x0000000D, 0x00005E13, 0x00004936, 0x00000000, 0x0004003D, + 0x000000B6, 0x000024F9, 0x00000E7D, 0x00050080, 0x00000012, 0x0000340D, 0x000020F0, 0x00000732, + 0x0007005F, 0x0000001D, 0x0000401F, 0x000024F9, 0x0000340D, 0x00000040, 0x00005253, 0x00050051, + 0x0000000D, 0x0000270A, 0x0000401F, 0x00000000, 0x0004003D, 0x000000B6, 0x00003A3E, 0x00000E7D, + 0x0007005F, 0x0000001D, 0x00004A9F, 0x00003A3E, 0x0000340D, 0x00000040, 0x00001FE3, 0x00050051, + 0x0000000D, 0x000050F0, 0x00004A9F, 0x00000000, 0x00070050, 0x0000001D, 0x00001958, 0x00002709, + 0x00005E13, 0x0000270A, 0x000050F0, 0x0004007C, 0x00000017, 0x00004F8F, 0x00001958, 0x00060041, + 0x00000294, 0x00003B37, 0x000012B6, 0x00000A0B, 0x0000345B, 0x0003003E, 0x00003B37, 0x00004F8F, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/passthrough_position_xy_vs.h b/src/graphics/shaders/vulkan_spirv/passthrough_position_xy_vs.h new file mode 100644 index 0000000..d1ea12d --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/passthrough_position_xy_vs.h @@ -0,0 +1,69 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 24988 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %5663 "main" %4930 %5474 + OpDecorate %_struct_2935 Block + OpMemberDecorate %_struct_2935 0 BuiltIn Position + OpMemberDecorate %_struct_2935 1 BuiltIn PointSize + OpMemberDecorate %_struct_2935 2 BuiltIn ClipDistance + OpMemberDecorate %_struct_2935 3 BuiltIn CullDistance + OpDecorate %5474 Location 0 + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %uint = OpTypeInt 32 0 + %uint_1 = OpConstant %uint 1 +%_arr_float_uint_1 = OpTypeArray %float %uint_1 +%_struct_2935 = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 +%_ptr_Output__struct_2935 = OpTypePointer Output %_struct_2935 + %4930 = OpVariable %_ptr_Output__struct_2935 Output + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 + %v2float = OpTypeVector %float 2 +%_ptr_Input_v2float = OpTypePointer Input %v2float + %5474 = OpVariable %_ptr_Input_v2float Input + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %5663 = OpFunction %void None %1282 + %24987 = OpLabel + %17674 = OpLoad %v2float %5474 + %21995 = OpCompositeExtract %float %17674 0 + %23384 = OpCompositeExtract %float %17674 1 + %18260 = OpCompositeConstruct %v4float %21995 %23384 %float_0 %float_1 + %12055 = OpAccessChain %_ptr_Output_v4float %4930 %int_0 + OpStore %12055 %18260 + OpReturn + OpFunctionEnd +#endif + +const uint32_t passthrough_position_xy_vs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x0000619C, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0007000F, 0x00000000, 0x0000161F, 0x6E69616D, 0x00000000, 0x00001342, 0x00001562, 0x00030047, + 0x00000B77, 0x00000002, 0x00050048, 0x00000B77, 0x00000000, 0x0000000B, 0x00000000, 0x00050048, + 0x00000B77, 0x00000001, 0x0000000B, 0x00000001, 0x00050048, 0x00000B77, 0x00000002, 0x0000000B, + 0x00000003, 0x00050048, 0x00000B77, 0x00000003, 0x0000000B, 0x00000004, 0x00040047, 0x00001562, + 0x0000001E, 0x00000000, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00030016, + 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x00040015, 0x0000000B, + 0x00000020, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004001C, 0x0000022A, + 0x0000000D, 0x00000A0D, 0x0006001E, 0x00000B77, 0x0000001D, 0x0000000D, 0x0000022A, 0x0000022A, + 0x00040020, 0x00000231, 0x00000003, 0x00000B77, 0x0004003B, 0x00000231, 0x00001342, 0x00000003, + 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, + 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x00040020, 0x00000290, 0x00000001, 0x00000013, + 0x0004003B, 0x00000290, 0x00001562, 0x00000001, 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, + 0x0004002B, 0x0000000D, 0x0000008A, 0x3F800000, 0x00040020, 0x0000029A, 0x00000003, 0x0000001D, + 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x0000619B, 0x0004003D, + 0x00000013, 0x0000450A, 0x00001562, 0x00050051, 0x0000000D, 0x000055EB, 0x0000450A, 0x00000000, + 0x00050051, 0x0000000D, 0x00005B58, 0x0000450A, 0x00000001, 0x00070050, 0x0000001D, 0x00004754, + 0x000055EB, 0x00005B58, 0x00000A0C, 0x0000008A, 0x00050041, 0x0000029A, 0x00002F17, 0x00001342, + 0x00000A0B, 0x0003003E, 0x00002F17, 0x00004754, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_clear_32bpp_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_clear_32bpp_cs.h new file mode 100644 index 0000000..ebf8f57 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_clear_32bpp_cs.h @@ -0,0 +1,249 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25175 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_struct_1014 Block + OpMemberDecorate %_struct_1014 0 Offset 0 + OpMemberDecorate %_struct_1014 1 Offset 8 + OpMemberDecorate %_struct_1014 2 Offset 12 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonReadable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %3271 NonReadable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %bool = OpTypeBool + %uint_2 = OpConstant %uint 2 + %uint_1 = OpConstant %uint 1 + %1837 = OpConstantComposite %v2uint %uint_2 %uint_1 + %v2bool = OpTypeVector %bool 2 + %uint_0 = OpConstant %uint 0 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %uint_80 = OpConstant %uint 80 + %uint_16 = OpConstant %uint 16 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %int = OpTypeInt 32 1 +%_struct_1014 = OpTypeStruct %v2uint %uint %uint +%_ptr_PushConstant__struct_1014 = OpTypePointer PushConstant %_struct_1014 + %3305 = OpVariable %_ptr_PushConstant__struct_1014 PushConstant + %int_1 = OpConstant %int 1 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %int_2 = OpConstant %int 2 + %int_0 = OpConstant %int 0 + %uint_1023 = OpConstant %uint 1023 + %uint_10 = OpConstant %uint 10 + %uint_3 = OpConstant %uint 3 + %uint_4096 = OpConstant %uint 4096 + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_15 = OpConstant %uint 15 + %uint_4 = OpConstant %uint 4 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 + %uint_5 = OpConstant %uint 5 +%_ptr_PushConstant_v2uint = OpTypePointer PushConstant %v2uint + %v3uint = OpTypeVector %uint 3 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_ptr_Input_uint = OpTypePointer Input %uint + %1834 = OpConstantComposite %v2uint %uint_3 %uint_0 + %v4uint = OpTypeVector %uint 4 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %3271 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint + %uint_8 = OpConstant %uint 8 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %uint_40 = OpConstant %uint 40 + %int_40 = OpConstant %int 40 + %int_n40 = OpConstant %int -40 + %uint_1280 = OpConstant %uint 1280 +%uint_2621440 = OpConstant %uint 2621440 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %20073 = OpShiftRightLogical %uint %15627 %uint_10 + %7177 = OpBitwiseAnd %uint %20073 %uint_3 + %23023 = OpBitwiseAnd %uint %15627 %uint_4096 + %20495 = OpINotEqual %bool %23023 %uint_0 + %8141 = OpShiftRightLogical %uint %15627 %uint_13 + %24990 = OpBitwiseAnd %uint %8141 %uint_2047 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9576 = OpShiftRightLogical %v2uint %8871 %1855 + %23379 = OpBitwiseAnd %v2uint %9576 %1954 + %16207 = OpShiftLeftLogical %v2uint %23379 %1870 + %23019 = OpIMul %v2uint %16207 %1828 + %12819 = OpShiftRightLogical %uint %20824 %uint_5 + %16204 = OpBitwiseAnd %uint %12819 %uint_2047 + %19017 = OpAccessChain %_ptr_PushConstant_v2uint %3305 %int_0 + %23788 = OpLoad %v2uint %19017 + %13183 = OpCompositeConstruct %v2uint %7177 %7177 + %21741 = OpUGreaterThanEqual %v2bool %13183 %1837 + %22612 = OpSelect %v2uint %21741 %1828 %1807 + %23890 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0 + %19209 = OpLoad %uint %23890 + %20350 = OpCompositeExtract %uint %22612 0 + %15478 = OpShiftLeftLogical %uint %16204 %20350 + %15379 = OpUGreaterThanEqual %bool %19209 %15478 + OpSelectionMerge %17447 DontFlatten + OpBranchConditional %15379 %21992 %17447 + %21992 = OpLabel + OpBranch %19578 + %17447 = OpLabel + %14637 = OpLoad %v3uint %gl_GlobalInvocationID + %20690 = OpVectorShuffle %v2uint %14637 %14637 0 1 + %9909 = OpShiftLeftLogical %v2uint %20690 %1834 + %23542 = OpShiftLeftLogical %v2uint %23019 %22612 + %7525 = OpIAdd %v2uint %9909 %23542 + %25079 = OpUDiv %v2uint %7525 %2719 + %12360 = OpCompositeExtract %uint %25079 1 + %11046 = OpIMul %uint %12360 %20561 + %24665 = OpCompositeExtract %uint %25079 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %24990 %21536 + %6459 = OpIMul %v2uint %25079 %2719 + %14279 = OpISub %v2uint %7525 %6459 + OpSelectionMerge %19725 None + OpBranchConditional %20495 %10558 %19725 + %10558 = OpLabel + %11791 = OpCompositeExtract %uint %14279 0 + %24981 = OpBitcast %int %11791 + %7841 = OpUGreaterThanEqual %bool %11791 %uint_40 + %22568 = OpSelect %int %7841 %int_n40 %int_40 + %11768 = OpIAdd %int %24981 %22568 + %8071 = OpBitcast %uint %11768 + %21574 = OpCompositeInsert %v2uint %8071 %14279 0 + OpBranch %19725 + %19725 = OpLabel + %8537 = OpPhi %v2uint %14279 %17447 %21574 %10558 + %6671 = OpIMul %uint %8742 %uint_1280 + %13892 = OpCompositeExtract %uint %8537 1 + %15890 = OpIMul %uint %13892 %uint_80 + %24666 = OpCompositeExtract %uint %8537 0 + %21631 = OpIAdd %uint %15890 %24666 + %9093 = OpIAdd %uint %6671 %21631 + %8443 = OpUMod %uint %9093 %uint_2621440 + %16234 = OpShiftRightLogical %uint %8443 %uint_2 + %14952 = OpVectorShuffle %v4uint %23788 %23788 0 0 0 0 + %7737 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %16234 + OpStore %7737 %14952 + %11457 = OpIAdd %uint %16234 %uint_1 + %25174 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %11457 + OpStore %25174 %14952 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_clear_32bpp_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006257, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00030047, 0x000003F6, 0x00000002, 0x00050048, + 0x000003F6, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x000003F6, 0x00000001, 0x00000023, + 0x00000008, 0x00050048, 0x000003F6, 0x00000002, 0x00000023, 0x0000000C, 0x00040047, 0x00000F48, + 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, 0x000007B4, + 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000019, 0x00050048, 0x000007B4, 0x00000000, + 0x00000023, 0x00000000, 0x00030047, 0x00000CC7, 0x00000019, 0x00040047, 0x00000CC7, 0x00000021, + 0x00000000, 0x00040047, 0x00000CC7, 0x00000022, 0x00000000, 0x00040047, 0x00000AC7, 0x0000000B, + 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000B, + 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00020014, 0x00000009, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0005002C, 0x00000011, 0x0000072D, 0x00000A10, 0x00000A0D, 0x00040017, 0x0000000F, 0x00000009, + 0x00000002, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0005002C, 0x00000011, 0x0000070F, + 0x00000A0A, 0x00000A0A, 0x0005002C, 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, 0x0004002B, + 0x0000000B, 0x00000AFA, 0x00000050, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0005002C, + 0x00000011, 0x00000A9F, 0x00000AFA, 0x00000A3A, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, + 0x0005001E, 0x000003F6, 0x00000011, 0x0000000B, 0x0000000B, 0x00040020, 0x00000673, 0x00000009, + 0x000003F6, 0x0004003B, 0x00000673, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0E, + 0x00000001, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0004002B, 0x0000000C, 0x00000A11, + 0x00000002, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A44, + 0x000003FF, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000A13, + 0x00000003, 0x0004002B, 0x0000000B, 0x00000AFE, 0x00001000, 0x0004002B, 0x0000000B, 0x00000A31, + 0x0000000D, 0x0004002B, 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A37, + 0x0000000F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0005002C, 0x00000011, 0x0000073F, + 0x00000A0A, 0x00000A16, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x00040020, 0x0000028E, + 0x00000009, 0x00000011, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x00040020, 0x00000291, + 0x00000001, 0x00000014, 0x0004003B, 0x00000291, 0x00000F48, 0x00000001, 0x00040020, 0x00000289, + 0x00000001, 0x0000000B, 0x0005002C, 0x00000011, 0x0000072A, 0x00000A13, 0x00000A0A, 0x00040017, + 0x00000017, 0x0000000B, 0x00000004, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, + 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A32, 0x00000CC7, + 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0004002B, 0x0000000B, 0x00000A22, + 0x00000008, 0x0006002C, 0x00000014, 0x00000AC7, 0x00000A22, 0x00000A22, 0x00000A0D, 0x0005002C, + 0x00000011, 0x000007A2, 0x00000A37, 0x00000A0D, 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, + 0x00000A13, 0x0004002B, 0x0000000B, 0x00000A82, 0x00000028, 0x0004002B, 0x0000000C, 0x00000A83, + 0x00000028, 0x0004002B, 0x0000000C, 0x00000993, 0xFFFFFFD8, 0x0004002B, 0x0000000B, 0x00000184, + 0x00000500, 0x0004002B, 0x0000000B, 0x0000086E, 0x00280000, 0x00050036, 0x00000008, 0x0000161F, + 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, + 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000056E5, 0x00000CE9, + 0x00000A0E, 0x0004003D, 0x0000000B, 0x00003D0B, 0x000056E5, 0x00050041, 0x00000288, 0x000058AC, + 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005158, 0x000058AC, 0x000500C7, 0x0000000B, + 0x00005051, 0x00003D0B, 0x00000A44, 0x000500C2, 0x0000000B, 0x00004E69, 0x00003D0B, 0x00000A28, + 0x000500C7, 0x0000000B, 0x00001C09, 0x00004E69, 0x00000A13, 0x000500C7, 0x0000000B, 0x000059EF, + 0x00003D0B, 0x00000AFE, 0x000500AB, 0x00000009, 0x0000500F, 0x000059EF, 0x00000A0A, 0x000500C2, + 0x0000000B, 0x00001FCD, 0x00003D0B, 0x00000A31, 0x000500C7, 0x0000000B, 0x0000619E, 0x00001FCD, + 0x00000A81, 0x00050050, 0x00000011, 0x000022A7, 0x00005158, 0x00005158, 0x000500C2, 0x00000011, + 0x00002568, 0x000022A7, 0x0000073F, 0x000500C7, 0x00000011, 0x00005B53, 0x00002568, 0x000007A2, + 0x000500C4, 0x00000011, 0x00003F4F, 0x00005B53, 0x0000074E, 0x00050084, 0x00000011, 0x000059EB, + 0x00003F4F, 0x00000724, 0x000500C2, 0x0000000B, 0x00003213, 0x00005158, 0x00000A19, 0x000500C7, + 0x0000000B, 0x00003F4C, 0x00003213, 0x00000A81, 0x00050041, 0x0000028E, 0x00004A49, 0x00000CE9, + 0x00000A0B, 0x0004003D, 0x00000011, 0x00005CEC, 0x00004A49, 0x00050050, 0x00000011, 0x0000337F, + 0x00001C09, 0x00001C09, 0x000500AE, 0x0000000F, 0x000054ED, 0x0000337F, 0x0000072D, 0x000600A9, + 0x00000011, 0x00005854, 0x000054ED, 0x00000724, 0x0000070F, 0x00050041, 0x00000289, 0x00005D52, + 0x00000F48, 0x00000A0A, 0x0004003D, 0x0000000B, 0x00004B09, 0x00005D52, 0x00050051, 0x0000000B, + 0x00004F7E, 0x00005854, 0x00000000, 0x000500C4, 0x0000000B, 0x00003C76, 0x00003F4C, 0x00004F7E, + 0x000500AE, 0x00000009, 0x00003C13, 0x00004B09, 0x00003C76, 0x000300F7, 0x00004427, 0x00000002, + 0x000400FA, 0x00003C13, 0x000055E8, 0x00004427, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, + 0x000200F8, 0x00004427, 0x0004003D, 0x00000014, 0x0000392D, 0x00000F48, 0x0007004F, 0x00000011, + 0x000050D2, 0x0000392D, 0x0000392D, 0x00000000, 0x00000001, 0x000500C4, 0x00000011, 0x000026B5, + 0x000050D2, 0x0000072A, 0x000500C4, 0x00000011, 0x00005BF6, 0x000059EB, 0x00005854, 0x00050080, + 0x00000011, 0x00001D65, 0x000026B5, 0x00005BF6, 0x00050086, 0x00000011, 0x000061F7, 0x00001D65, + 0x00000A9F, 0x00050051, 0x0000000B, 0x00003048, 0x000061F7, 0x00000001, 0x00050084, 0x0000000B, + 0x00002B26, 0x00003048, 0x00005051, 0x00050051, 0x0000000B, 0x00006059, 0x000061F7, 0x00000000, + 0x00050080, 0x0000000B, 0x00005420, 0x00002B26, 0x00006059, 0x00050080, 0x0000000B, 0x00002226, + 0x0000619E, 0x00005420, 0x00050084, 0x00000011, 0x0000193B, 0x000061F7, 0x00000A9F, 0x00050082, + 0x00000011, 0x000037C7, 0x00001D65, 0x0000193B, 0x000300F7, 0x00004D0D, 0x00000000, 0x000400FA, + 0x0000500F, 0x0000293E, 0x00004D0D, 0x000200F8, 0x0000293E, 0x00050051, 0x0000000B, 0x00002E0F, + 0x000037C7, 0x00000000, 0x0004007C, 0x0000000C, 0x00006195, 0x00002E0F, 0x000500AE, 0x00000009, + 0x00001EA1, 0x00002E0F, 0x00000A82, 0x000600A9, 0x0000000C, 0x00005828, 0x00001EA1, 0x00000993, + 0x00000A83, 0x00050080, 0x0000000C, 0x00002DF8, 0x00006195, 0x00005828, 0x0004007C, 0x0000000B, + 0x00001F87, 0x00002DF8, 0x00060052, 0x00000011, 0x00005446, 0x00001F87, 0x000037C7, 0x00000000, + 0x000200F9, 0x00004D0D, 0x000200F8, 0x00004D0D, 0x000700F5, 0x00000011, 0x00002159, 0x000037C7, + 0x00004427, 0x00005446, 0x0000293E, 0x00050084, 0x0000000B, 0x00001A0F, 0x00002226, 0x00000184, + 0x00050051, 0x0000000B, 0x00003644, 0x00002159, 0x00000001, 0x00050084, 0x0000000B, 0x00003E12, + 0x00003644, 0x00000AFA, 0x00050051, 0x0000000B, 0x0000605A, 0x00002159, 0x00000000, 0x00050080, + 0x0000000B, 0x0000547F, 0x00003E12, 0x0000605A, 0x00050080, 0x0000000B, 0x00002385, 0x00001A0F, + 0x0000547F, 0x00050089, 0x0000000B, 0x000020FB, 0x00002385, 0x0000086E, 0x000500C2, 0x0000000B, + 0x00003F6A, 0x000020FB, 0x00000A10, 0x0009004F, 0x00000017, 0x00003A68, 0x00005CEC, 0x00005CEC, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00060041, 0x00000294, 0x00001E39, 0x00000CC7, + 0x00000A0B, 0x00003F6A, 0x0003003E, 0x00001E39, 0x00003A68, 0x00050080, 0x0000000B, 0x00002CC1, + 0x00003F6A, 0x00000A0D, 0x00060041, 0x00000294, 0x00006256, 0x00000CC7, 0x00000A0B, 0x00002CC1, + 0x0003003E, 0x00006256, 0x00003A68, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, + 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_clear_32bpp_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_clear_32bpp_scaled_cs.h new file mode 100644 index 0000000..48a8d8e --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_clear_32bpp_scaled_cs.h @@ -0,0 +1,280 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25175 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_struct_1014 Block + OpMemberDecorate %_struct_1014 0 Offset 0 + OpMemberDecorate %_struct_1014 1 Offset 8 + OpMemberDecorate %_struct_1014 2 Offset 12 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonReadable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %3271 NonReadable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %bool = OpTypeBool + %uint_2 = OpConstant %uint 2 + %uint_1 = OpConstant %uint 1 + %1837 = OpConstantComposite %v2uint %uint_2 %uint_1 + %v2bool = OpTypeVector %bool 2 + %uint_0 = OpConstant %uint 0 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %uint_80 = OpConstant %uint 80 + %uint_16 = OpConstant %uint 16 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %int = OpTypeInt 32 1 + %uint_2048 = OpConstant %uint 2048 +%_struct_1014 = OpTypeStruct %v2uint %uint %uint +%_ptr_PushConstant__struct_1014 = OpTypePointer PushConstant %_struct_1014 + %3305 = OpVariable %_ptr_PushConstant__struct_1014 PushConstant + %int_1 = OpConstant %int 1 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %int_2 = OpConstant %int 2 + %int_0 = OpConstant %int 0 + %uint_1023 = OpConstant %uint 1023 + %uint_10 = OpConstant %uint 10 + %uint_3 = OpConstant %uint 3 + %uint_4096 = OpConstant %uint 4096 + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_15 = OpConstant %uint 15 + %uint_19 = OpConstant %uint 19 + %2179 = OpConstantComposite %v2uint %uint_16 %uint_19 + %uint_7 = OpConstant %uint 7 + %uint_4 = OpConstant %uint 4 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 + %uint_5 = OpConstant %uint 5 +%_ptr_PushConstant_v2uint = OpTypePointer PushConstant %v2uint + %v3uint = OpTypeVector %uint 3 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_ptr_Input_uint = OpTypePointer Input %uint + %1834 = OpConstantComposite %v2uint %uint_3 %uint_0 + %v4uint = OpTypeVector %uint 4 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %3271 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint + %uint_8 = OpConstant %uint 8 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %1955 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %20073 = OpShiftRightLogical %uint %15627 %uint_10 + %7177 = OpBitwiseAnd %uint %20073 %uint_3 + %23023 = OpBitwiseAnd %uint %15627 %uint_4096 + %20495 = OpINotEqual %bool %23023 %uint_0 + %8141 = OpShiftRightLogical %uint %15627 %uint_13 + %24990 = OpBitwiseAnd %uint %8141 %uint_2047 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9538 = OpShiftRightLogical %v2uint %8871 %2179 + %24998 = OpBitwiseAnd %v2uint %9538 %1954 + %21040 = OpShiftRightLogical %v2uint %8871 %1855 + %6955 = OpBitwiseAnd %v2uint %21040 %1955 + %16207 = OpShiftLeftLogical %v2uint %6955 %1870 + %23019 = OpIMul %v2uint %16207 %24998 + %13123 = OpShiftRightLogical %uint %20824 %uint_5 + %14785 = OpBitwiseAnd %uint %13123 %uint_2047 + %8858 = OpCompositeExtract %uint %24998 0 + %22993 = OpIMul %uint %14785 %8858 + %20321 = OpAccessChain %_ptr_PushConstant_v2uint %3305 %int_0 + %18180 = OpLoad %v2uint %20321 + %13183 = OpCompositeConstruct %v2uint %7177 %7177 + %21741 = OpUGreaterThanEqual %v2bool %13183 %1837 + %22612 = OpSelect %v2uint %21741 %1828 %1807 + %23890 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0 + %19209 = OpLoad %uint %23890 + %20350 = OpCompositeExtract %uint %22612 0 + %15478 = OpShiftLeftLogical %uint %22993 %20350 + %15379 = OpUGreaterThanEqual %bool %19209 %15478 + OpSelectionMerge %17447 DontFlatten + OpBranchConditional %15379 %21992 %17447 + %21992 = OpLabel + OpBranch %19578 + %17447 = OpLabel + %14637 = OpLoad %v3uint %gl_GlobalInvocationID + %20690 = OpVectorShuffle %v2uint %14637 %14637 0 1 + %9909 = OpShiftLeftLogical %v2uint %20690 %1834 + %23504 = OpShiftLeftLogical %v2uint %23019 %22612 + %8878 = OpIAdd %v2uint %9909 %23504 + %12256 = OpIMul %v2uint %2719 %24998 + %7983 = OpUDiv %v2uint %8878 %12256 + %9129 = OpCompositeExtract %uint %7983 1 + %11046 = OpIMul %uint %9129 %20561 + %24665 = OpCompositeExtract %uint %7983 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %24990 %21536 + %6459 = OpIMul %v2uint %7983 %12256 + %14279 = OpISub %v2uint %8878 %6459 + OpSelectionMerge %18756 None + OpBranchConditional %20495 %11888 %18756 + %11888 = OpLabel + %16985 = OpCompositeExtract %uint %12256 0 + %13307 = OpShiftRightLogical %uint %16985 %uint_1 + %22207 = OpCompositeExtract %uint %14279 0 + %15197 = OpBitcast %int %22207 + %15736 = OpUGreaterThanEqual %bool %22207 %13307 + OpSelectionMerge %22850 None + OpBranchConditional %15736 %23061 %24565 + %24565 = OpLabel + %20693 = OpBitcast %int %13307 + OpBranch %22850 + %23061 = OpLabel + %18885 = OpBitcast %int %13307 + %17199 = OpSNegate %int %18885 + OpBranch %22850 + %22850 = OpLabel + %10046 = OpPhi %int %17199 %23061 %20693 %24565 + %11983 = OpIAdd %int %15197 %10046 + %17709 = OpBitcast %uint %11983 + %21574 = OpCompositeInsert %v2uint %17709 %14279 0 + OpBranch %18756 + %18756 = OpLabel + %17360 = OpPhi %v2uint %14279 %17447 %21574 %22850 + %24023 = OpCompositeExtract %uint %12256 0 + %22303 = OpCompositeExtract %uint %12256 1 + %13170 = OpIMul %uint %24023 %22303 + %15520 = OpIMul %uint %8742 %13170 + %16084 = OpCompositeExtract %uint %17360 1 + %15890 = OpIMul %uint %16084 %24023 + %24666 = OpCompositeExtract %uint %17360 0 + %21537 = OpIAdd %uint %15890 %24666 + %8875 = OpIAdd %uint %15520 %21537 + %23312 = OpIMul %uint %13170 %uint_2048 + %20061 = OpUMod %uint %8875 %23312 + %19460 = OpShiftRightLogical %uint %20061 %uint_2 + %14952 = OpVectorShuffle %v4uint %18180 %18180 0 0 0 0 + %7737 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %19460 + OpStore %7737 %14952 + %11457 = OpIAdd %uint %19460 %uint_1 + %25174 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %11457 + OpStore %25174 %14952 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_clear_32bpp_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006257, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00030047, 0x000003F6, 0x00000002, 0x00050048, + 0x000003F6, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x000003F6, 0x00000001, 0x00000023, + 0x00000008, 0x00050048, 0x000003F6, 0x00000002, 0x00000023, 0x0000000C, 0x00040047, 0x00000F48, + 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, 0x000007B4, + 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000019, 0x00050048, 0x000007B4, 0x00000000, + 0x00000023, 0x00000000, 0x00030047, 0x00000CC7, 0x00000019, 0x00040047, 0x00000CC7, 0x00000021, + 0x00000000, 0x00040047, 0x00000CC7, 0x00000022, 0x00000000, 0x00040047, 0x00000AC7, 0x0000000B, + 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000B, + 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00020014, 0x00000009, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0005002C, 0x00000011, 0x0000072D, 0x00000A10, 0x00000A0D, 0x00040017, 0x0000000F, 0x00000009, + 0x00000002, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0005002C, 0x00000011, 0x0000070F, + 0x00000A0A, 0x00000A0A, 0x0005002C, 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, 0x0004002B, + 0x0000000B, 0x00000AFA, 0x00000050, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0005002C, + 0x00000011, 0x00000A9F, 0x00000AFA, 0x00000A3A, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, + 0x0004002B, 0x0000000B, 0x00000A84, 0x00000800, 0x0005001E, 0x000003F6, 0x00000011, 0x0000000B, + 0x0000000B, 0x00040020, 0x00000673, 0x00000009, 0x000003F6, 0x0004003B, 0x00000673, 0x00000CE9, + 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x00040020, 0x00000288, 0x00000009, + 0x0000000B, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x00000A0B, + 0x00000000, 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, 0x0004002B, 0x0000000B, 0x00000A28, + 0x0000000A, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000AFE, + 0x00001000, 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, 0x0004002B, 0x0000000B, 0x00000A81, + 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, 0x0004002B, 0x0000000B, 0x00000A43, + 0x00000013, 0x0005002C, 0x00000011, 0x00000883, 0x00000A3A, 0x00000A43, 0x0004002B, 0x0000000B, + 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0005002C, 0x00000011, + 0x0000073F, 0x00000A0A, 0x00000A16, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x00040020, + 0x0000028E, 0x00000009, 0x00000011, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x00040020, + 0x00000291, 0x00000001, 0x00000014, 0x0004003B, 0x00000291, 0x00000F48, 0x00000001, 0x00040020, + 0x00000289, 0x00000001, 0x0000000B, 0x0005002C, 0x00000011, 0x0000072A, 0x00000A13, 0x00000A0A, + 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, + 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A32, + 0x00000CC7, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0004002B, 0x0000000B, + 0x00000A22, 0x00000008, 0x0006002C, 0x00000014, 0x00000AC7, 0x00000A22, 0x00000A22, 0x00000A0D, + 0x0005002C, 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0005002C, 0x00000011, 0x000007A3, + 0x00000A37, 0x00000A0D, 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, 0x00050036, + 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, + 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, + 0x000056E5, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00003D0B, 0x000056E5, 0x00050041, + 0x00000288, 0x000058AC, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005158, 0x000058AC, + 0x000500C7, 0x0000000B, 0x00005051, 0x00003D0B, 0x00000A44, 0x000500C2, 0x0000000B, 0x00004E69, + 0x00003D0B, 0x00000A28, 0x000500C7, 0x0000000B, 0x00001C09, 0x00004E69, 0x00000A13, 0x000500C7, + 0x0000000B, 0x000059EF, 0x00003D0B, 0x00000AFE, 0x000500AB, 0x00000009, 0x0000500F, 0x000059EF, + 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001FCD, 0x00003D0B, 0x00000A31, 0x000500C7, 0x0000000B, + 0x0000619E, 0x00001FCD, 0x00000A81, 0x00050050, 0x00000011, 0x000022A7, 0x00005158, 0x00005158, + 0x000500C2, 0x00000011, 0x00002542, 0x000022A7, 0x00000883, 0x000500C7, 0x00000011, 0x000061A6, + 0x00002542, 0x000007A2, 0x000500C2, 0x00000011, 0x00005230, 0x000022A7, 0x0000073F, 0x000500C7, + 0x00000011, 0x00001B2B, 0x00005230, 0x000007A3, 0x000500C4, 0x00000011, 0x00003F4F, 0x00001B2B, + 0x0000074E, 0x00050084, 0x00000011, 0x000059EB, 0x00003F4F, 0x000061A6, 0x000500C2, 0x0000000B, + 0x00003343, 0x00005158, 0x00000A19, 0x000500C7, 0x0000000B, 0x000039C1, 0x00003343, 0x00000A81, + 0x00050051, 0x0000000B, 0x0000229A, 0x000061A6, 0x00000000, 0x00050084, 0x0000000B, 0x000059D1, + 0x000039C1, 0x0000229A, 0x00050041, 0x0000028E, 0x00004F61, 0x00000CE9, 0x00000A0B, 0x0004003D, + 0x00000011, 0x00004704, 0x00004F61, 0x00050050, 0x00000011, 0x0000337F, 0x00001C09, 0x00001C09, + 0x000500AE, 0x0000000F, 0x000054ED, 0x0000337F, 0x0000072D, 0x000600A9, 0x00000011, 0x00005854, + 0x000054ED, 0x00000724, 0x0000070F, 0x00050041, 0x00000289, 0x00005D52, 0x00000F48, 0x00000A0A, + 0x0004003D, 0x0000000B, 0x00004B09, 0x00005D52, 0x00050051, 0x0000000B, 0x00004F7E, 0x00005854, + 0x00000000, 0x000500C4, 0x0000000B, 0x00003C76, 0x000059D1, 0x00004F7E, 0x000500AE, 0x00000009, + 0x00003C13, 0x00004B09, 0x00003C76, 0x000300F7, 0x00004427, 0x00000002, 0x000400FA, 0x00003C13, + 0x000055E8, 0x00004427, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004427, + 0x0004003D, 0x00000014, 0x0000392D, 0x00000F48, 0x0007004F, 0x00000011, 0x000050D2, 0x0000392D, + 0x0000392D, 0x00000000, 0x00000001, 0x000500C4, 0x00000011, 0x000026B5, 0x000050D2, 0x0000072A, + 0x000500C4, 0x00000011, 0x00005BD0, 0x000059EB, 0x00005854, 0x00050080, 0x00000011, 0x000022AE, + 0x000026B5, 0x00005BD0, 0x00050084, 0x00000011, 0x00002FE0, 0x00000A9F, 0x000061A6, 0x00050086, + 0x00000011, 0x00001F2F, 0x000022AE, 0x00002FE0, 0x00050051, 0x0000000B, 0x000023A9, 0x00001F2F, + 0x00000001, 0x00050084, 0x0000000B, 0x00002B26, 0x000023A9, 0x00005051, 0x00050051, 0x0000000B, + 0x00006059, 0x00001F2F, 0x00000000, 0x00050080, 0x0000000B, 0x00005420, 0x00002B26, 0x00006059, + 0x00050080, 0x0000000B, 0x00002226, 0x0000619E, 0x00005420, 0x00050084, 0x00000011, 0x0000193B, + 0x00001F2F, 0x00002FE0, 0x00050082, 0x00000011, 0x000037C7, 0x000022AE, 0x0000193B, 0x000300F7, + 0x00004944, 0x00000000, 0x000400FA, 0x0000500F, 0x00002E70, 0x00004944, 0x000200F8, 0x00002E70, + 0x00050051, 0x0000000B, 0x00004259, 0x00002FE0, 0x00000000, 0x000500C2, 0x0000000B, 0x000033FB, + 0x00004259, 0x00000A0D, 0x00050051, 0x0000000B, 0x000056BF, 0x000037C7, 0x00000000, 0x0004007C, + 0x0000000C, 0x00003B5D, 0x000056BF, 0x000500AE, 0x00000009, 0x00003D78, 0x000056BF, 0x000033FB, + 0x000300F7, 0x00005942, 0x00000000, 0x000400FA, 0x00003D78, 0x00005A15, 0x00005FF5, 0x000200F8, + 0x00005FF5, 0x0004007C, 0x0000000C, 0x000050D5, 0x000033FB, 0x000200F9, 0x00005942, 0x000200F8, + 0x00005A15, 0x0004007C, 0x0000000C, 0x000049C5, 0x000033FB, 0x0004007E, 0x0000000C, 0x0000432F, + 0x000049C5, 0x000200F9, 0x00005942, 0x000200F8, 0x00005942, 0x000700F5, 0x0000000C, 0x0000273E, + 0x0000432F, 0x00005A15, 0x000050D5, 0x00005FF5, 0x00050080, 0x0000000C, 0x00002ECF, 0x00003B5D, + 0x0000273E, 0x0004007C, 0x0000000B, 0x0000452D, 0x00002ECF, 0x00060052, 0x00000011, 0x00005446, + 0x0000452D, 0x000037C7, 0x00000000, 0x000200F9, 0x00004944, 0x000200F8, 0x00004944, 0x000700F5, + 0x00000011, 0x000043D0, 0x000037C7, 0x00004427, 0x00005446, 0x00005942, 0x00050051, 0x0000000B, + 0x00005DD7, 0x00002FE0, 0x00000000, 0x00050051, 0x0000000B, 0x0000571F, 0x00002FE0, 0x00000001, + 0x00050084, 0x0000000B, 0x00003372, 0x00005DD7, 0x0000571F, 0x00050084, 0x0000000B, 0x00003CA0, + 0x00002226, 0x00003372, 0x00050051, 0x0000000B, 0x00003ED4, 0x000043D0, 0x00000001, 0x00050084, + 0x0000000B, 0x00003E12, 0x00003ED4, 0x00005DD7, 0x00050051, 0x0000000B, 0x0000605A, 0x000043D0, + 0x00000000, 0x00050080, 0x0000000B, 0x00005421, 0x00003E12, 0x0000605A, 0x00050080, 0x0000000B, + 0x000022AB, 0x00003CA0, 0x00005421, 0x00050084, 0x0000000B, 0x00005B10, 0x00003372, 0x00000A84, + 0x00050089, 0x0000000B, 0x00004E5D, 0x000022AB, 0x00005B10, 0x000500C2, 0x0000000B, 0x00004C04, + 0x00004E5D, 0x00000A10, 0x0009004F, 0x00000017, 0x00003A68, 0x00004704, 0x00004704, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00060041, 0x00000294, 0x00001E39, 0x00000CC7, 0x00000A0B, + 0x00004C04, 0x0003003E, 0x00001E39, 0x00003A68, 0x00050080, 0x0000000B, 0x00002CC1, 0x00004C04, + 0x00000A0D, 0x00060041, 0x00000294, 0x00006256, 0x00000CC7, 0x00000A0B, 0x00002CC1, 0x0003003E, + 0x00006256, 0x00003A68, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_clear_64bpp_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_clear_64bpp_cs.h new file mode 100644 index 0000000..2f25784 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_clear_64bpp_cs.h @@ -0,0 +1,231 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25175 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_struct_1014 Block + OpMemberDecorate %_struct_1014 0 Offset 0 + OpMemberDecorate %_struct_1014 1 Offset 8 + OpMemberDecorate %_struct_1014 2 Offset 12 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonReadable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %3271 NonReadable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %bool = OpTypeBool + %uint_2 = OpConstant %uint 2 + %uint_1 = OpConstant %uint 1 + %1837 = OpConstantComposite %v2uint %uint_2 %uint_1 + %v2bool = OpTypeVector %bool 2 + %uint_0 = OpConstant %uint 0 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %uint_16 = OpConstant %uint 16 + %int = OpTypeInt 32 1 +%_struct_1014 = OpTypeStruct %v2uint %uint %uint +%_ptr_PushConstant__struct_1014 = OpTypePointer PushConstant %_struct_1014 + %3305 = OpVariable %_ptr_PushConstant__struct_1014 PushConstant + %int_1 = OpConstant %int 1 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %int_2 = OpConstant %int 2 + %int_0 = OpConstant %int 0 + %uint_1023 = OpConstant %uint 1023 + %uint_10 = OpConstant %uint 10 + %uint_3 = OpConstant %uint 3 + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_15 = OpConstant %uint 15 + %uint_4 = OpConstant %uint 4 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 + %uint_5 = OpConstant %uint 5 +%_ptr_PushConstant_v2uint = OpTypePointer PushConstant %v2uint + %v3uint = OpTypeVector %uint 3 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_ptr_Input_uint = OpTypePointer Input %uint + %1834 = OpConstantComposite %v2uint %uint_3 %uint_0 + %v4uint = OpTypeVector %uint 4 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %3271 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint + %uint_8 = OpConstant %uint 8 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %uint_40 = OpConstant %uint 40 + %2359 = OpConstantComposite %v2uint %uint_40 %uint_16 + %uint_1280 = OpConstant %uint 1280 +%uint_2621440 = OpConstant %uint 2621440 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %19978 = OpShiftRightLogical %uint %15627 %uint_10 + %8574 = OpBitwiseAnd %uint %19978 %uint_3 + %18836 = OpShiftRightLogical %uint %15627 %uint_13 + %9130 = OpBitwiseAnd %uint %18836 %uint_2047 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9576 = OpShiftRightLogical %v2uint %8871 %1855 + %23379 = OpBitwiseAnd %v2uint %9576 %1954 + %16207 = OpShiftLeftLogical %v2uint %23379 %1870 + %23019 = OpIMul %v2uint %16207 %1828 + %12819 = OpShiftRightLogical %uint %20824 %uint_5 + %16204 = OpBitwiseAnd %uint %12819 %uint_2047 + %19017 = OpAccessChain %_ptr_PushConstant_v2uint %3305 %int_0 + %23788 = OpLoad %v2uint %19017 + %13183 = OpCompositeConstruct %v2uint %8574 %8574 + %21741 = OpUGreaterThanEqual %v2bool %13183 %1837 + %22612 = OpSelect %v2uint %21741 %1828 %1807 + %23890 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0 + %19209 = OpLoad %uint %23890 + %20350 = OpCompositeExtract %uint %22612 0 + %15478 = OpShiftLeftLogical %uint %16204 %20350 + %15379 = OpUGreaterThanEqual %bool %19209 %15478 + OpSelectionMerge %17447 DontFlatten + OpBranchConditional %15379 %21992 %17447 + %21992 = OpLabel + OpBranch %19578 + %17447 = OpLabel + %14637 = OpLoad %v3uint %gl_GlobalInvocationID + %20690 = OpVectorShuffle %v2uint %14637 %14637 0 1 + %9909 = OpShiftLeftLogical %v2uint %20690 %1834 + %23542 = OpShiftLeftLogical %v2uint %23019 %22612 + %7525 = OpIAdd %v2uint %9909 %23542 + %25079 = OpUDiv %v2uint %7525 %2359 + %12360 = OpCompositeExtract %uint %25079 1 + %11046 = OpIMul %uint %12360 %20561 + %24665 = OpCompositeExtract %uint %25079 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %9130 %21536 + %23345 = OpIMul %v2uint %25079 %2359 + %11892 = OpISub %v2uint %7525 %23345 + %9022 = OpIMul %uint %8742 %uint_1280 + %14471 = OpCompositeExtract %uint %11892 1 + %15890 = OpIMul %uint %14471 %uint_40 + %6886 = OpCompositeExtract %uint %11892 0 + %9696 = OpIAdd %uint %15890 %6886 + %18116 = OpShiftLeftLogical %uint %9696 %uint_1 + %18581 = OpIAdd %uint %9022 %18116 + %18086 = OpUMod %uint %18581 %uint_2621440 + %16234 = OpShiftRightLogical %uint %18086 %uint_2 + %14952 = OpVectorShuffle %v4uint %23788 %23788 0 1 0 1 + %7737 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %16234 + OpStore %7737 %14952 + %11457 = OpIAdd %uint %16234 %uint_1 + %22875 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %11457 + OpStore %22875 %14952 + %11458 = OpIAdd %uint %16234 %uint_2 + %22876 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %11458 + OpStore %22876 %14952 + %11459 = OpIAdd %uint %16234 %uint_3 + %25174 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %11459 + OpStore %25174 %14952 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_clear_64bpp_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006257, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00030047, 0x000003F6, 0x00000002, 0x00050048, + 0x000003F6, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x000003F6, 0x00000001, 0x00000023, + 0x00000008, 0x00050048, 0x000003F6, 0x00000002, 0x00000023, 0x0000000C, 0x00040047, 0x00000F48, + 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, 0x000007B4, + 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000019, 0x00050048, 0x000007B4, 0x00000000, + 0x00000023, 0x00000000, 0x00030047, 0x00000CC7, 0x00000019, 0x00040047, 0x00000CC7, 0x00000021, + 0x00000000, 0x00040047, 0x00000CC7, 0x00000022, 0x00000000, 0x00040047, 0x00000AC7, 0x0000000B, + 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000B, + 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00020014, 0x00000009, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0005002C, 0x00000011, 0x0000072D, 0x00000A10, 0x00000A0D, 0x00040017, 0x0000000F, 0x00000009, + 0x00000002, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0005002C, 0x00000011, 0x0000070F, + 0x00000A0A, 0x00000A0A, 0x0005002C, 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x0005001E, + 0x000003F6, 0x00000011, 0x0000000B, 0x0000000B, 0x00040020, 0x00000673, 0x00000009, 0x000003F6, + 0x0004003B, 0x00000673, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, + 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, 0x0004002B, 0x0000000B, 0x00000A81, 0x000007FF, + 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0005002C, 0x00000011, 0x0000073F, 0x00000A0A, 0x00000A16, 0x0004002B, 0x0000000B, 0x00000A19, + 0x00000005, 0x00040020, 0x0000028E, 0x00000009, 0x00000011, 0x00040017, 0x00000014, 0x0000000B, + 0x00000003, 0x00040020, 0x00000291, 0x00000001, 0x00000014, 0x0004003B, 0x00000291, 0x00000F48, + 0x00000001, 0x00040020, 0x00000289, 0x00000001, 0x0000000B, 0x0005002C, 0x00000011, 0x0000072A, + 0x00000A13, 0x00000A0A, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x0003001D, 0x000007DC, + 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, + 0x0004003B, 0x00000A32, 0x00000CC7, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0006002C, 0x00000014, 0x00000AC7, 0x00000A22, + 0x00000A22, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A37, 0x00000A0D, 0x0005002C, + 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, 0x0004002B, 0x0000000B, 0x00000A82, 0x00000028, + 0x0005002C, 0x00000011, 0x00000937, 0x00000A82, 0x00000A3A, 0x0004002B, 0x0000000B, 0x00000184, + 0x00000500, 0x0004002B, 0x0000000B, 0x0000086E, 0x00280000, 0x00050036, 0x00000008, 0x0000161F, + 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, + 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000056E5, 0x00000CE9, + 0x00000A0E, 0x0004003D, 0x0000000B, 0x00003D0B, 0x000056E5, 0x00050041, 0x00000288, 0x000058AC, + 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005158, 0x000058AC, 0x000500C7, 0x0000000B, + 0x00005051, 0x00003D0B, 0x00000A44, 0x000500C2, 0x0000000B, 0x00004E0A, 0x00003D0B, 0x00000A28, + 0x000500C7, 0x0000000B, 0x0000217E, 0x00004E0A, 0x00000A13, 0x000500C2, 0x0000000B, 0x00004994, + 0x00003D0B, 0x00000A31, 0x000500C7, 0x0000000B, 0x000023AA, 0x00004994, 0x00000A81, 0x00050050, + 0x00000011, 0x000022A7, 0x00005158, 0x00005158, 0x000500C2, 0x00000011, 0x00002568, 0x000022A7, + 0x0000073F, 0x000500C7, 0x00000011, 0x00005B53, 0x00002568, 0x000007A2, 0x000500C4, 0x00000011, + 0x00003F4F, 0x00005B53, 0x0000074E, 0x00050084, 0x00000011, 0x000059EB, 0x00003F4F, 0x00000724, + 0x000500C2, 0x0000000B, 0x00003213, 0x00005158, 0x00000A19, 0x000500C7, 0x0000000B, 0x00003F4C, + 0x00003213, 0x00000A81, 0x00050041, 0x0000028E, 0x00004A49, 0x00000CE9, 0x00000A0B, 0x0004003D, + 0x00000011, 0x00005CEC, 0x00004A49, 0x00050050, 0x00000011, 0x0000337F, 0x0000217E, 0x0000217E, + 0x000500AE, 0x0000000F, 0x000054ED, 0x0000337F, 0x0000072D, 0x000600A9, 0x00000011, 0x00005854, + 0x000054ED, 0x00000724, 0x0000070F, 0x00050041, 0x00000289, 0x00005D52, 0x00000F48, 0x00000A0A, + 0x0004003D, 0x0000000B, 0x00004B09, 0x00005D52, 0x00050051, 0x0000000B, 0x00004F7E, 0x00005854, + 0x00000000, 0x000500C4, 0x0000000B, 0x00003C76, 0x00003F4C, 0x00004F7E, 0x000500AE, 0x00000009, + 0x00003C13, 0x00004B09, 0x00003C76, 0x000300F7, 0x00004427, 0x00000002, 0x000400FA, 0x00003C13, + 0x000055E8, 0x00004427, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004427, + 0x0004003D, 0x00000014, 0x0000392D, 0x00000F48, 0x0007004F, 0x00000011, 0x000050D2, 0x0000392D, + 0x0000392D, 0x00000000, 0x00000001, 0x000500C4, 0x00000011, 0x000026B5, 0x000050D2, 0x0000072A, + 0x000500C4, 0x00000011, 0x00005BF6, 0x000059EB, 0x00005854, 0x00050080, 0x00000011, 0x00001D65, + 0x000026B5, 0x00005BF6, 0x00050086, 0x00000011, 0x000061F7, 0x00001D65, 0x00000937, 0x00050051, + 0x0000000B, 0x00003048, 0x000061F7, 0x00000001, 0x00050084, 0x0000000B, 0x00002B26, 0x00003048, + 0x00005051, 0x00050051, 0x0000000B, 0x00006059, 0x000061F7, 0x00000000, 0x00050080, 0x0000000B, + 0x00005420, 0x00002B26, 0x00006059, 0x00050080, 0x0000000B, 0x00002226, 0x000023AA, 0x00005420, + 0x00050084, 0x00000011, 0x00005B31, 0x000061F7, 0x00000937, 0x00050082, 0x00000011, 0x00002E74, + 0x00001D65, 0x00005B31, 0x00050084, 0x0000000B, 0x0000233E, 0x00002226, 0x00000184, 0x00050051, + 0x0000000B, 0x00003887, 0x00002E74, 0x00000001, 0x00050084, 0x0000000B, 0x00003E12, 0x00003887, + 0x00000A82, 0x00050051, 0x0000000B, 0x00001AE6, 0x00002E74, 0x00000000, 0x00050080, 0x0000000B, + 0x000025E0, 0x00003E12, 0x00001AE6, 0x000500C4, 0x0000000B, 0x000046C4, 0x000025E0, 0x00000A0D, + 0x00050080, 0x0000000B, 0x00004895, 0x0000233E, 0x000046C4, 0x00050089, 0x0000000B, 0x000046A6, + 0x00004895, 0x0000086E, 0x000500C2, 0x0000000B, 0x00003F6A, 0x000046A6, 0x00000A10, 0x0009004F, + 0x00000017, 0x00003A68, 0x00005CEC, 0x00005CEC, 0x00000000, 0x00000001, 0x00000000, 0x00000001, + 0x00060041, 0x00000294, 0x00001E39, 0x00000CC7, 0x00000A0B, 0x00003F6A, 0x0003003E, 0x00001E39, + 0x00003A68, 0x00050080, 0x0000000B, 0x00002CC1, 0x00003F6A, 0x00000A0D, 0x00060041, 0x00000294, + 0x0000595B, 0x00000CC7, 0x00000A0B, 0x00002CC1, 0x0003003E, 0x0000595B, 0x00003A68, 0x00050080, + 0x0000000B, 0x00002CC2, 0x00003F6A, 0x00000A10, 0x00060041, 0x00000294, 0x0000595C, 0x00000CC7, + 0x00000A0B, 0x00002CC2, 0x0003003E, 0x0000595C, 0x00003A68, 0x00050080, 0x0000000B, 0x00002CC3, + 0x00003F6A, 0x00000A13, 0x00060041, 0x00000294, 0x00006256, 0x00000CC7, 0x00000A0B, 0x00002CC3, + 0x0003003E, 0x00006256, 0x00003A68, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, + 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_clear_64bpp_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_clear_64bpp_scaled_cs.h new file mode 100644 index 0000000..1dda62c --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_clear_64bpp_scaled_cs.h @@ -0,0 +1,255 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25175 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_struct_1014 Block + OpMemberDecorate %_struct_1014 0 Offset 0 + OpMemberDecorate %_struct_1014 1 Offset 8 + OpMemberDecorate %_struct_1014 2 Offset 12 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonReadable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %3271 NonReadable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %bool = OpTypeBool + %uint_2 = OpConstant %uint 2 + %uint_1 = OpConstant %uint 1 + %1837 = OpConstantComposite %v2uint %uint_2 %uint_1 + %v2bool = OpTypeVector %bool 2 + %uint_0 = OpConstant %uint 0 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %uint_80 = OpConstant %uint 80 + %uint_16 = OpConstant %uint 16 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %int = OpTypeInt 32 1 + %uint_2048 = OpConstant %uint 2048 +%_struct_1014 = OpTypeStruct %v2uint %uint %uint +%_ptr_PushConstant__struct_1014 = OpTypePointer PushConstant %_struct_1014 + %3305 = OpVariable %_ptr_PushConstant__struct_1014 PushConstant + %int_1 = OpConstant %int 1 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %int_2 = OpConstant %int 2 + %int_0 = OpConstant %int 0 + %uint_1023 = OpConstant %uint 1023 + %uint_10 = OpConstant %uint 10 + %uint_3 = OpConstant %uint 3 + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_15 = OpConstant %uint 15 + %uint_19 = OpConstant %uint 19 + %2179 = OpConstantComposite %v2uint %uint_16 %uint_19 + %uint_7 = OpConstant %uint 7 + %uint_4 = OpConstant %uint 4 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 + %uint_5 = OpConstant %uint 5 +%_ptr_PushConstant_v2uint = OpTypePointer PushConstant %v2uint + %v3uint = OpTypeVector %uint 3 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_ptr_Input_uint = OpTypePointer Input %uint + %1834 = OpConstantComposite %v2uint %uint_3 %uint_0 + %v4uint = OpTypeVector %uint 4 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %3271 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint + %uint_8 = OpConstant %uint 8 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %1955 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %19978 = OpShiftRightLogical %uint %15627 %uint_10 + %8574 = OpBitwiseAnd %uint %19978 %uint_3 + %18836 = OpShiftRightLogical %uint %15627 %uint_13 + %9130 = OpBitwiseAnd %uint %18836 %uint_2047 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9538 = OpShiftRightLogical %v2uint %8871 %2179 + %24998 = OpBitwiseAnd %v2uint %9538 %1954 + %21040 = OpShiftRightLogical %v2uint %8871 %1855 + %6955 = OpBitwiseAnd %v2uint %21040 %1955 + %16207 = OpShiftLeftLogical %v2uint %6955 %1870 + %23019 = OpIMul %v2uint %16207 %24998 + %13123 = OpShiftRightLogical %uint %20824 %uint_5 + %14785 = OpBitwiseAnd %uint %13123 %uint_2047 + %8858 = OpCompositeExtract %uint %24998 0 + %22993 = OpIMul %uint %14785 %8858 + %20321 = OpAccessChain %_ptr_PushConstant_v2uint %3305 %int_0 + %18180 = OpLoad %v2uint %20321 + %13183 = OpCompositeConstruct %v2uint %8574 %8574 + %21741 = OpUGreaterThanEqual %v2bool %13183 %1837 + %22612 = OpSelect %v2uint %21741 %1828 %1807 + %23890 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0 + %19209 = OpLoad %uint %23890 + %20350 = OpCompositeExtract %uint %22612 0 + %15478 = OpShiftLeftLogical %uint %22993 %20350 + %15379 = OpUGreaterThanEqual %bool %19209 %15478 + OpSelectionMerge %17447 DontFlatten + OpBranchConditional %15379 %21992 %17447 + %21992 = OpLabel + OpBranch %19578 + %17447 = OpLabel + %14637 = OpLoad %v3uint %gl_GlobalInvocationID + %20690 = OpVectorShuffle %v2uint %14637 %14637 0 1 + %9909 = OpShiftLeftLogical %v2uint %20690 %1834 + %23504 = OpShiftLeftLogical %v2uint %23019 %22612 + %10018 = OpIAdd %v2uint %9909 %23504 + %21954 = OpIMul %v2uint %2719 %24998 + %14725 = OpShiftRightLogical %v2uint %21954 %1816 + %19799 = OpUDiv %v2uint %10018 %14725 + %20390 = OpCompositeExtract %uint %19799 1 + %11046 = OpIMul %uint %20390 %20561 + %24665 = OpCompositeExtract %uint %19799 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %9130 %21536 + %22376 = OpIMul %v2uint %19799 %14725 + %20715 = OpISub %v2uint %10018 %22376 + %7303 = OpCompositeExtract %uint %21954 0 + %22882 = OpCompositeExtract %uint %21954 1 + %13170 = OpIMul %uint %7303 %22882 + %14551 = OpIMul %uint %8742 %13170 + %6805 = OpCompositeExtract %uint %20715 1 + %23526 = OpCompositeExtract %uint %14725 0 + %22886 = OpIMul %uint %6805 %23526 + %6886 = OpCompositeExtract %uint %20715 0 + %9696 = OpIAdd %uint %22886 %6886 + %18021 = OpShiftLeftLogical %uint %9696 %uint_1 + %18363 = OpIAdd %uint %14551 %18021 + %13884 = OpIMul %uint %13170 %uint_2048 + %20061 = OpUMod %uint %18363 %13884 + %19460 = OpShiftRightLogical %uint %20061 %uint_2 + %14952 = OpVectorShuffle %v4uint %18180 %18180 0 1 0 1 + %7737 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %19460 + OpStore %7737 %14952 + %11457 = OpIAdd %uint %19460 %uint_1 + %22875 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %11457 + OpStore %22875 %14952 + %11458 = OpIAdd %uint %19460 %uint_2 + %22876 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %11458 + OpStore %22876 %14952 + %11459 = OpIAdd %uint %19460 %uint_3 + %25174 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %11459 + OpStore %25174 %14952 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_clear_64bpp_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006257, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00030047, 0x000003F6, 0x00000002, 0x00050048, + 0x000003F6, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x000003F6, 0x00000001, 0x00000023, + 0x00000008, 0x00050048, 0x000003F6, 0x00000002, 0x00000023, 0x0000000C, 0x00040047, 0x00000F48, + 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, 0x000007B4, + 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000019, 0x00050048, 0x000007B4, 0x00000000, + 0x00000023, 0x00000000, 0x00030047, 0x00000CC7, 0x00000019, 0x00040047, 0x00000CC7, 0x00000021, + 0x00000000, 0x00040047, 0x00000CC7, 0x00000022, 0x00000000, 0x00040047, 0x00000AC7, 0x0000000B, + 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000B, + 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00020014, 0x00000009, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0005002C, 0x00000011, 0x0000072D, 0x00000A10, 0x00000A0D, 0x00040017, 0x0000000F, 0x00000009, + 0x00000002, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0005002C, 0x00000011, 0x0000070F, + 0x00000A0A, 0x00000A0A, 0x0005002C, 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, 0x0005002C, + 0x00000011, 0x00000718, 0x00000A0D, 0x00000A0A, 0x0004002B, 0x0000000B, 0x00000AFA, 0x00000050, + 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0005002C, 0x00000011, 0x00000A9F, 0x00000AFA, + 0x00000A3A, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A84, + 0x00000800, 0x0005001E, 0x000003F6, 0x00000011, 0x0000000B, 0x0000000B, 0x00040020, 0x00000673, + 0x00000009, 0x000003F6, 0x0004003B, 0x00000673, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0E, 0x00000001, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0004002B, 0x0000000C, + 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x0004002B, 0x0000000B, + 0x00000A44, 0x000003FF, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, + 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, 0x0004002B, 0x0000000B, + 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, 0x0004002B, 0x0000000B, + 0x00000A43, 0x00000013, 0x0005002C, 0x00000011, 0x00000883, 0x00000A3A, 0x00000A43, 0x0004002B, + 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0005002C, + 0x00000011, 0x0000073F, 0x00000A0A, 0x00000A16, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x00040020, 0x0000028E, 0x00000009, 0x00000011, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x00040020, 0x00000291, 0x00000001, 0x00000014, 0x0004003B, 0x00000291, 0x00000F48, 0x00000001, + 0x00040020, 0x00000289, 0x00000001, 0x0000000B, 0x0005002C, 0x00000011, 0x0000072A, 0x00000A13, + 0x00000A0A, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x0003001D, 0x000007DC, 0x00000017, + 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, 0x0004003B, + 0x00000A32, 0x00000CC7, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0004002B, + 0x0000000B, 0x00000A22, 0x00000008, 0x0006002C, 0x00000014, 0x00000AC7, 0x00000A22, 0x00000A22, + 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0005002C, 0x00000011, + 0x000007A3, 0x00000A37, 0x00000A0D, 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, + 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, + 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, + 0x00000288, 0x000056E5, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00003D0B, 0x000056E5, + 0x00050041, 0x00000288, 0x000058AC, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005158, + 0x000058AC, 0x000500C7, 0x0000000B, 0x00005051, 0x00003D0B, 0x00000A44, 0x000500C2, 0x0000000B, + 0x00004E0A, 0x00003D0B, 0x00000A28, 0x000500C7, 0x0000000B, 0x0000217E, 0x00004E0A, 0x00000A13, + 0x000500C2, 0x0000000B, 0x00004994, 0x00003D0B, 0x00000A31, 0x000500C7, 0x0000000B, 0x000023AA, + 0x00004994, 0x00000A81, 0x00050050, 0x00000011, 0x000022A7, 0x00005158, 0x00005158, 0x000500C2, + 0x00000011, 0x00002542, 0x000022A7, 0x00000883, 0x000500C7, 0x00000011, 0x000061A6, 0x00002542, + 0x000007A2, 0x000500C2, 0x00000011, 0x00005230, 0x000022A7, 0x0000073F, 0x000500C7, 0x00000011, + 0x00001B2B, 0x00005230, 0x000007A3, 0x000500C4, 0x00000011, 0x00003F4F, 0x00001B2B, 0x0000074E, + 0x00050084, 0x00000011, 0x000059EB, 0x00003F4F, 0x000061A6, 0x000500C2, 0x0000000B, 0x00003343, + 0x00005158, 0x00000A19, 0x000500C7, 0x0000000B, 0x000039C1, 0x00003343, 0x00000A81, 0x00050051, + 0x0000000B, 0x0000229A, 0x000061A6, 0x00000000, 0x00050084, 0x0000000B, 0x000059D1, 0x000039C1, + 0x0000229A, 0x00050041, 0x0000028E, 0x00004F61, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x00000011, + 0x00004704, 0x00004F61, 0x00050050, 0x00000011, 0x0000337F, 0x0000217E, 0x0000217E, 0x000500AE, + 0x0000000F, 0x000054ED, 0x0000337F, 0x0000072D, 0x000600A9, 0x00000011, 0x00005854, 0x000054ED, + 0x00000724, 0x0000070F, 0x00050041, 0x00000289, 0x00005D52, 0x00000F48, 0x00000A0A, 0x0004003D, + 0x0000000B, 0x00004B09, 0x00005D52, 0x00050051, 0x0000000B, 0x00004F7E, 0x00005854, 0x00000000, + 0x000500C4, 0x0000000B, 0x00003C76, 0x000059D1, 0x00004F7E, 0x000500AE, 0x00000009, 0x00003C13, + 0x00004B09, 0x00003C76, 0x000300F7, 0x00004427, 0x00000002, 0x000400FA, 0x00003C13, 0x000055E8, + 0x00004427, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004427, 0x0004003D, + 0x00000014, 0x0000392D, 0x00000F48, 0x0007004F, 0x00000011, 0x000050D2, 0x0000392D, 0x0000392D, + 0x00000000, 0x00000001, 0x000500C4, 0x00000011, 0x000026B5, 0x000050D2, 0x0000072A, 0x000500C4, + 0x00000011, 0x00005BD0, 0x000059EB, 0x00005854, 0x00050080, 0x00000011, 0x00002722, 0x000026B5, + 0x00005BD0, 0x00050084, 0x00000011, 0x000055C2, 0x00000A9F, 0x000061A6, 0x000500C2, 0x00000011, + 0x00003985, 0x000055C2, 0x00000718, 0x00050086, 0x00000011, 0x00004D57, 0x00002722, 0x00003985, + 0x00050051, 0x0000000B, 0x00004FA6, 0x00004D57, 0x00000001, 0x00050084, 0x0000000B, 0x00002B26, + 0x00004FA6, 0x00005051, 0x00050051, 0x0000000B, 0x00006059, 0x00004D57, 0x00000000, 0x00050080, + 0x0000000B, 0x00005420, 0x00002B26, 0x00006059, 0x00050080, 0x0000000B, 0x00002226, 0x000023AA, + 0x00005420, 0x00050084, 0x00000011, 0x00005768, 0x00004D57, 0x00003985, 0x00050082, 0x00000011, + 0x000050EB, 0x00002722, 0x00005768, 0x00050051, 0x0000000B, 0x00001C87, 0x000055C2, 0x00000000, + 0x00050051, 0x0000000B, 0x00005962, 0x000055C2, 0x00000001, 0x00050084, 0x0000000B, 0x00003372, + 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, 0x000038D7, 0x00002226, 0x00003372, 0x00050051, + 0x0000000B, 0x00001A95, 0x000050EB, 0x00000001, 0x00050051, 0x0000000B, 0x00005BE6, 0x00003985, + 0x00000000, 0x00050084, 0x0000000B, 0x00005966, 0x00001A95, 0x00005BE6, 0x00050051, 0x0000000B, + 0x00001AE6, 0x000050EB, 0x00000000, 0x00050080, 0x0000000B, 0x000025E0, 0x00005966, 0x00001AE6, + 0x000500C4, 0x0000000B, 0x00004665, 0x000025E0, 0x00000A0D, 0x00050080, 0x0000000B, 0x000047BB, + 0x000038D7, 0x00004665, 0x00050084, 0x0000000B, 0x0000363C, 0x00003372, 0x00000A84, 0x00050089, + 0x0000000B, 0x00004E5D, 0x000047BB, 0x0000363C, 0x000500C2, 0x0000000B, 0x00004C04, 0x00004E5D, + 0x00000A10, 0x0009004F, 0x00000017, 0x00003A68, 0x00004704, 0x00004704, 0x00000000, 0x00000001, + 0x00000000, 0x00000001, 0x00060041, 0x00000294, 0x00001E39, 0x00000CC7, 0x00000A0B, 0x00004C04, + 0x0003003E, 0x00001E39, 0x00003A68, 0x00050080, 0x0000000B, 0x00002CC1, 0x00004C04, 0x00000A0D, + 0x00060041, 0x00000294, 0x0000595B, 0x00000CC7, 0x00000A0B, 0x00002CC1, 0x0003003E, 0x0000595B, + 0x00003A68, 0x00050080, 0x0000000B, 0x00002CC2, 0x00004C04, 0x00000A10, 0x00060041, 0x00000294, + 0x0000595C, 0x00000CC7, 0x00000A0B, 0x00002CC2, 0x0003003E, 0x0000595C, 0x00003A68, 0x00050080, + 0x0000000B, 0x00002CC3, 0x00004C04, 0x00000A13, 0x00060041, 0x00000294, 0x00006256, 0x00000CC7, + 0x00000A0B, 0x00002CC3, 0x0003003E, 0x00006256, 0x00003A68, 0x000200F9, 0x00004C7A, 0x000200F8, + 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_downscale_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_downscale_cs.h new file mode 100644 index 0000000..fd9d6a7 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_downscale_cs.h @@ -0,0 +1,376 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25190 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_WorkGroupID %gl_LocalInvocationID + OpExecutionMode %5663 LocalSize 32 32 1 + OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId + OpDecorate %_struct_1056 Block + OpMemberDecorate %_struct_1056 0 Offset 0 + OpMemberDecorate %_struct_1056 1 Offset 4 + OpMemberDecorate %_struct_1056 2 Offset 8 + OpMemberDecorate %_struct_1056 3 Offset 12 + OpMemberDecorate %_struct_1056 4 Offset 16 + OpMemberDecorate %_struct_1056 5 Offset 20 + OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId + OpDecorate %_runtimearr_uint ArrayStride 4 + OpDecorate %_struct_1948 BufferBlock + OpMemberDecorate %_struct_1948 0 NonWritable + OpMemberDecorate %_struct_1948 0 Offset 0 + OpDecorate %3152 NonWritable + OpDecorate %3152 Binding 0 + OpDecorate %3152 DescriptorSet 0 + OpDecorate %_runtimearr_uint_0 ArrayStride 4 + OpDecorate %_struct_1949 BufferBlock + OpMemberDecorate %_struct_1949 0 NonReadable + OpMemberDecorate %_struct_1949 0 Offset 0 + OpDecorate %5522 NonReadable + OpDecorate %5522 Binding 1 + OpDecorate %5522 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input + %uint_0 = OpConstant %uint 0 +%_ptr_Input_uint = OpTypePointer Input %uint +%_struct_1056 = OpTypeStruct %uint %uint %uint %uint %uint %uint +%_ptr_PushConstant__struct_1056 = OpTypePointer PushConstant %_struct_1056 + %4930 = OpVariable %_ptr_PushConstant__struct_1056 PushConstant + %int = OpTypeInt 32 1 + %int_3 = OpConstant %int 3 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %bool = OpTypeBool +%gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input + %uint_1 = OpConstant %uint 1 + %uint_32 = OpConstant %uint 32 + %int_2 = OpConstant %int 2 + %uint_1024 = OpConstant %uint 1024 + %int_0 = OpConstant %int 0 + %int_1 = OpConstant %int 1 + %int_5 = OpConstant %int 5 + %int_4 = OpConstant %int 4 + %uint_2 = OpConstant %uint 2 +%_runtimearr_uint = OpTypeRuntimeArray %uint +%_struct_1948 = OpTypeStruct %_runtimearr_uint +%_ptr_Uniform__struct_1948 = OpTypePointer Uniform %_struct_1948 + %3152 = OpVariable %_ptr_Uniform__struct_1948 Uniform +%_ptr_Uniform_uint = OpTypePointer Uniform %uint + %uint_3 = OpConstant %uint 3 + %uint_8 = OpConstant %uint 8 + %uint_255 = OpConstant %uint 255 +%_arr_uint_uint_1024 = OpTypeArray %uint %uint_1024 +%_ptr_Workgroup__arr_uint_uint_1024 = OpTypePointer Workgroup %_arr_uint_uint_1024 + %4017 = OpVariable %_ptr_Workgroup__arr_uint_uint_1024 Workgroup +%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint + %uint_264 = OpConstant %uint 264 +%_runtimearr_uint_0 = OpTypeRuntimeArray %uint +%_struct_1949 = OpTypeStruct %_runtimearr_uint_0 +%_ptr_Uniform__struct_1949 = OpTypePointer Uniform %_struct_1949 + %5522 = OpVariable %_ptr_Uniform__struct_1949 Uniform + %uint_256 = OpConstant %uint 256 + %uint_65535 = OpConstant %uint 65535 + %uint_16 = OpConstant %uint 16 + %uint_512 = OpConstant %uint 512 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_32 %uint_32 %uint_1 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %14903 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_Input_uint %gl_WorkGroupID %uint_0 + %15627 = OpLoad %uint %22245 + %22225 = OpAccessChain %_ptr_PushConstant_uint %4930 %int_3 + %7085 = OpLoad %uint %22225 + %7405 = OpUGreaterThanEqual %bool %15627 %7085 + OpSelectionMerge %16413 None + OpBranchConditional %7405 %21992 %16413 + %21992 = OpLabel + OpBranch %14903 + %16413 = OpLabel + %20632 = OpAccessChain %_ptr_Input_uint %gl_LocalInvocationID %uint_1 + %15628 = OpLoad %uint %20632 + %21427 = OpAccessChain %_ptr_Input_uint %gl_LocalInvocationID %uint_0 + %12090 = OpLoad %uint %21427 + %6234 = OpIMul %uint %15628 %uint_32 + %8353 = OpIAdd %uint %6234 %12090 + %16525 = OpAccessChain %_ptr_PushConstant_uint %4930 %int_2 + %13159 = OpLoad %uint %16525 + %15178 = OpShiftLeftLogical %uint %uint_1 %13159 + %21815 = OpIMul %uint %uint_1024 %15178 + %13000 = OpAccessChain %_ptr_PushConstant_uint %4930 %int_0 + %18628 = OpLoad %uint %13000 + %21428 = OpAccessChain %_ptr_PushConstant_uint %4930 %int_1 + %12166 = OpLoad %uint %21428 + %24613 = OpIMul %uint %18628 %12166 + %13723 = OpIMul %uint %21815 %24613 + %8597 = OpAccessChain %_ptr_PushConstant_uint %4930 %int_5 + %21470 = OpLoad %uint %8597 + %24311 = OpINotEqual %bool %21470 %uint_0 + %23629 = OpUGreaterThan %bool %24613 %uint_1 + %11037 = OpLogicalAnd %bool %24311 %23629 + OpSelectionMerge %23266 None + OpBranchConditional %11037 %11410 %23266 + %11410 = OpLabel + %20167 = OpShiftRightLogical %uint %18628 %uint_1 + %24779 = OpShiftRightLogical %uint %12166 %uint_1 + %16010 = OpIMul %uint %24779 %18628 + %19240 = OpIAdd %uint %20167 %16010 + OpBranch %23266 + %23266 = OpLabel + %19748 = OpPhi %uint %uint_0 %16413 %19240 %11410 + %25074 = OpAccessChain %_ptr_PushConstant_uint %4930 %int_4 + %25189 = OpLoad %uint %25074 + %7507 = OpIMul %uint %15627 %13723 + %17182 = OpIAdd %uint %25189 %7507 + %19692 = OpIMul %uint %8353 %15178 + %16238 = OpIMul %uint %19692 %24613 + %6869 = OpIAdd %uint %17182 %16238 + %21638 = OpIMul %uint %19748 %15178 + %18521 = OpIAdd %uint %6869 %21638 + %7572 = OpShiftRightLogical %uint %18521 %uint_2 + %6935 = OpIMul %uint %15627 %21815 + %9665 = OpIAdd %uint %6935 %19692 + %9085 = OpShiftRightLogical %uint %9665 %uint_2 + OpSelectionMerge %18023 None + OpSwitch %13159 %18023 0 %11881 1 %16414 2 %16415 3 %8158 + %11881 = OpLabel + %24791 = OpAccessChain %_ptr_Uniform_uint %3152 %int_0 %7572 + %12865 = OpLoad %uint %24791 + %12121 = OpBitwiseAnd %uint %18521 %uint_3 + %13987 = OpIMul %uint %12121 %uint_8 + %14461 = OpShiftRightLogical %uint %12865 %13987 + %15580 = OpBitwiseAnd %uint %14461 %uint_255 + %19824 = OpShiftRightLogical %uint %8353 %uint_2 + %19243 = OpBitwiseAnd %uint %8353 %uint_3 + %14114 = OpIMul %uint %19243 %uint_8 + %23170 = OpShiftLeftLogical %uint %15580 %14114 + %15629 = OpIEqual %bool %19243 %uint_0 + OpSelectionMerge %20883 None + OpBranchConditional %15629 %12148 %20883 + %12148 = OpLabel + %21533 = OpAccessChain %_ptr_Workgroup_uint %4017 %19824 + OpStore %21533 %23170 + OpBranch %20883 + %20883 = OpLabel + OpControlBarrier %uint_2 %uint_2 %uint_264 + %15932 = OpINotEqual %bool %19243 %uint_0 + OpSelectionMerge %9094 None + OpBranchConditional %15932 %15549 %9094 + %15549 = OpLabel + %9637 = OpAccessChain %_ptr_Workgroup_uint %4017 %19824 + %6303 = OpAtomicOr %uint %9637 %uint_1 %uint_0 %23170 + OpBranch %9094 + %9094 = OpLabel + OpControlBarrier %uint_2 %uint_2 %uint_264 + OpSelectionMerge %18021 None + OpBranchConditional %15629 %20882 %18021 + %20882 = OpLabel + %10747 = OpIMul %uint %15627 %uint_256 + %14186 = OpIAdd %uint %10747 %19824 + %14036 = OpAccessChain %_ptr_Workgroup_uint %4017 %19824 + %15421 = OpLoad %uint %14036 + %23477 = OpAccessChain %_ptr_Uniform_uint %5522 %int_0 %14186 + OpStore %23477 %15421 + OpBranch %18021 + %18021 = OpLabel + OpBranch %18023 + %16414 = OpLabel + %23178 = OpAccessChain %_ptr_Uniform_uint %3152 %int_0 %7572 + %12866 = OpLoad %uint %23178 + %12122 = OpBitwiseAnd %uint %18521 %uint_2 + %13988 = OpIMul %uint %12122 %uint_8 + %14462 = OpShiftRightLogical %uint %12866 %13988 + %15581 = OpBitwiseAnd %uint %14462 %uint_65535 + %19825 = OpShiftRightLogical %uint %8353 %uint_1 + %19244 = OpBitwiseAnd %uint %8353 %uint_1 + %14115 = OpIMul %uint %19244 %uint_16 + %23171 = OpShiftLeftLogical %uint %15581 %14115 + %15630 = OpIEqual %bool %19244 %uint_0 + OpSelectionMerge %20884 None + OpBranchConditional %15630 %12149 %20884 + %12149 = OpLabel + %21534 = OpAccessChain %_ptr_Workgroup_uint %4017 %19825 + OpStore %21534 %23171 + OpBranch %20884 + %20884 = OpLabel + OpControlBarrier %uint_2 %uint_2 %uint_264 + %15933 = OpINotEqual %bool %19244 %uint_0 + OpSelectionMerge %9095 None + OpBranchConditional %15933 %15550 %9095 + %15550 = OpLabel + %9638 = OpAccessChain %_ptr_Workgroup_uint %4017 %19825 + %6304 = OpAtomicOr %uint %9638 %uint_1 %uint_0 %23171 + OpBranch %9095 + %9095 = OpLabel + OpControlBarrier %uint_2 %uint_2 %uint_264 + OpSelectionMerge %18022 None + OpBranchConditional %15630 %20885 %18022 + %20885 = OpLabel + %10748 = OpIMul %uint %15627 %uint_512 + %14187 = OpIAdd %uint %10748 %19825 + %14037 = OpAccessChain %_ptr_Workgroup_uint %4017 %19825 + %15422 = OpLoad %uint %14037 + %23478 = OpAccessChain %_ptr_Uniform_uint %5522 %int_0 %14187 + OpStore %23478 %15422 + OpBranch %18022 + %18022 = OpLabel + OpBranch %18023 + %16415 = OpLabel + %20633 = OpAccessChain %_ptr_Uniform_uint %3152 %int_0 %7572 + %15646 = OpLoad %uint %20633 + %23479 = OpAccessChain %_ptr_Uniform_uint %5522 %int_0 %9085 + OpStore %23479 %15646 + OpBranch %18023 + %8158 = OpLabel + %20634 = OpAccessChain %_ptr_Uniform_uint %3152 %int_0 %7572 + %15647 = OpLoad %uint %20634 + %21178 = OpAccessChain %_ptr_Uniform_uint %5522 %int_0 %9085 + OpStore %21178 %15647 + %19686 = OpIAdd %uint %9085 %uint_1 + %13384 = OpIAdd %uint %7572 %uint_1 + %10810 = OpAccessChain %_ptr_Uniform_uint %3152 %int_0 %13384 + %15423 = OpLoad %uint %10810 + %23480 = OpAccessChain %_ptr_Uniform_uint %5522 %int_0 %19686 + OpStore %23480 %15423 + OpBranch %18023 + %18023 = OpLabel + OpBranch %14903 + %14903 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_downscale_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006266, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0007000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000BEF, 0x00000DA3, 0x00060010, + 0x0000161F, 0x00000011, 0x00000020, 0x00000020, 0x00000001, 0x00040047, 0x00000BEF, 0x0000000B, + 0x0000001A, 0x00030047, 0x00000420, 0x00000002, 0x00050048, 0x00000420, 0x00000000, 0x00000023, + 0x00000000, 0x00050048, 0x00000420, 0x00000001, 0x00000023, 0x00000004, 0x00050048, 0x00000420, + 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000420, 0x00000003, 0x00000023, 0x0000000C, + 0x00050048, 0x00000420, 0x00000004, 0x00000023, 0x00000010, 0x00050048, 0x00000420, 0x00000005, + 0x00000023, 0x00000014, 0x00040047, 0x00000DA3, 0x0000000B, 0x0000001B, 0x00040047, 0x000007D0, + 0x00000006, 0x00000004, 0x00030047, 0x0000079C, 0x00000003, 0x00040048, 0x0000079C, 0x00000000, + 0x00000018, 0x00050048, 0x0000079C, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000C50, + 0x00000018, 0x00040047, 0x00000C50, 0x00000021, 0x00000000, 0x00040047, 0x00000C50, 0x00000022, + 0x00000000, 0x00040047, 0x000007D1, 0x00000006, 0x00000004, 0x00030047, 0x0000079D, 0x00000003, + 0x00040048, 0x0000079D, 0x00000000, 0x00000019, 0x00050048, 0x0000079D, 0x00000000, 0x00000023, + 0x00000000, 0x00030047, 0x00001592, 0x00000019, 0x00040047, 0x00001592, 0x00000021, 0x00000001, + 0x00040047, 0x00001592, 0x00000022, 0x00000000, 0x00040047, 0x000000FC, 0x0000000B, 0x00000019, + 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, + 0x00000000, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x00040020, 0x00000291, 0x00000001, + 0x00000014, 0x0004003B, 0x00000291, 0x00000BEF, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A0A, + 0x00000000, 0x00040020, 0x00000288, 0x00000001, 0x0000000B, 0x0008001E, 0x00000420, 0x0000000B, + 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x0000069D, 0x00000009, + 0x00000420, 0x0004003B, 0x0000069D, 0x00001342, 0x00000009, 0x00040015, 0x0000000C, 0x00000020, + 0x00000001, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x00040020, 0x00000289, 0x00000009, + 0x0000000B, 0x00020014, 0x00000009, 0x0004003B, 0x00000291, 0x00000DA3, 0x00000001, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0004002B, + 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A47, 0x00000400, 0x0004002B, + 0x0000000C, 0x00000A0B, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, + 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, + 0x0000000B, 0x00000A10, 0x00000002, 0x0003001D, 0x000007D0, 0x0000000B, 0x0003001E, 0x0000079C, + 0x000007D0, 0x00040020, 0x00000A19, 0x00000002, 0x0000079C, 0x0004003B, 0x00000A19, 0x00000C50, + 0x00000002, 0x00040020, 0x0000028A, 0x00000002, 0x0000000B, 0x0004002B, 0x0000000B, 0x00000A13, + 0x00000003, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x00000144, + 0x000000FF, 0x0004001C, 0x00000293, 0x0000000B, 0x00000A47, 0x00040020, 0x00000510, 0x00000004, + 0x00000293, 0x0004003B, 0x00000510, 0x00000FB1, 0x00000004, 0x00040020, 0x0000028B, 0x00000004, + 0x0000000B, 0x0004002B, 0x0000000B, 0x0000015F, 0x00000108, 0x0003001D, 0x000007D1, 0x0000000B, + 0x0003001E, 0x0000079D, 0x000007D1, 0x00040020, 0x00000A1B, 0x00000002, 0x0000079D, 0x0004003B, + 0x00000A1B, 0x00001592, 0x00000002, 0x0004002B, 0x0000000B, 0x00000147, 0x00000100, 0x0004002B, + 0x0000000B, 0x000001C1, 0x0000FFFF, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, + 0x0000000B, 0x00000447, 0x00000200, 0x0006002C, 0x00000014, 0x000000FC, 0x00000A6A, 0x00000A6A, + 0x00000A0D, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, + 0x000300F7, 0x00003A37, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, + 0x00050041, 0x00000288, 0x000056E5, 0x00000BEF, 0x00000A0A, 0x0004003D, 0x0000000B, 0x00003D0B, + 0x000056E5, 0x00050041, 0x00000289, 0x000056D1, 0x00001342, 0x00000A14, 0x0004003D, 0x0000000B, + 0x00001BAD, 0x000056D1, 0x000500AE, 0x00000009, 0x00001CED, 0x00003D0B, 0x00001BAD, 0x000300F7, + 0x0000401D, 0x00000000, 0x000400FA, 0x00001CED, 0x000055E8, 0x0000401D, 0x000200F8, 0x000055E8, + 0x000200F9, 0x00003A37, 0x000200F8, 0x0000401D, 0x00050041, 0x00000288, 0x00005098, 0x00000DA3, + 0x00000A0D, 0x0004003D, 0x0000000B, 0x00003D0C, 0x00005098, 0x00050041, 0x00000288, 0x000053B3, + 0x00000DA3, 0x00000A0A, 0x0004003D, 0x0000000B, 0x00002F3A, 0x000053B3, 0x00050084, 0x0000000B, + 0x0000185A, 0x00003D0C, 0x00000A6A, 0x00050080, 0x0000000B, 0x000020A1, 0x0000185A, 0x00002F3A, + 0x00050041, 0x00000289, 0x0000408D, 0x00001342, 0x00000A11, 0x0004003D, 0x0000000B, 0x00003367, + 0x0000408D, 0x000500C4, 0x0000000B, 0x00003B4A, 0x00000A0D, 0x00003367, 0x00050084, 0x0000000B, + 0x00005537, 0x00000A47, 0x00003B4A, 0x00050041, 0x00000289, 0x000032C8, 0x00001342, 0x00000A0B, + 0x0004003D, 0x0000000B, 0x000048C4, 0x000032C8, 0x00050041, 0x00000289, 0x000053B4, 0x00001342, + 0x00000A0E, 0x0004003D, 0x0000000B, 0x00002F86, 0x000053B4, 0x00050084, 0x0000000B, 0x00006025, + 0x000048C4, 0x00002F86, 0x00050084, 0x0000000B, 0x0000359B, 0x00005537, 0x00006025, 0x00050041, + 0x00000289, 0x00002195, 0x00001342, 0x00000A1A, 0x0004003D, 0x0000000B, 0x000053DE, 0x00002195, + 0x000500AB, 0x00000009, 0x00005EF7, 0x000053DE, 0x00000A0A, 0x000500AC, 0x00000009, 0x00005C4D, + 0x00006025, 0x00000A0D, 0x000500A7, 0x00000009, 0x00002B1D, 0x00005EF7, 0x00005C4D, 0x000300F7, + 0x00005AE2, 0x00000000, 0x000400FA, 0x00002B1D, 0x00002C92, 0x00005AE2, 0x000200F8, 0x00002C92, + 0x000500C2, 0x0000000B, 0x00004EC7, 0x000048C4, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000060CB, + 0x00002F86, 0x00000A0D, 0x00050084, 0x0000000B, 0x00003E8A, 0x000060CB, 0x000048C4, 0x00050080, + 0x0000000B, 0x00004B28, 0x00004EC7, 0x00003E8A, 0x000200F9, 0x00005AE2, 0x000200F8, 0x00005AE2, + 0x000700F5, 0x0000000B, 0x00004D24, 0x00000A0A, 0x0000401D, 0x00004B28, 0x00002C92, 0x00050041, + 0x00000289, 0x000061F2, 0x00001342, 0x00000A17, 0x0004003D, 0x0000000B, 0x00006265, 0x000061F2, + 0x00050084, 0x0000000B, 0x00001D53, 0x00003D0B, 0x0000359B, 0x00050080, 0x0000000B, 0x0000431E, + 0x00006265, 0x00001D53, 0x00050084, 0x0000000B, 0x00004CEC, 0x000020A1, 0x00003B4A, 0x00050084, + 0x0000000B, 0x00003F6E, 0x00004CEC, 0x00006025, 0x00050080, 0x0000000B, 0x00001AD5, 0x0000431E, + 0x00003F6E, 0x00050084, 0x0000000B, 0x00005486, 0x00004D24, 0x00003B4A, 0x00050080, 0x0000000B, + 0x00004859, 0x00001AD5, 0x00005486, 0x000500C2, 0x0000000B, 0x00001D94, 0x00004859, 0x00000A10, + 0x00050084, 0x0000000B, 0x00001B17, 0x00003D0B, 0x00005537, 0x00050080, 0x0000000B, 0x000025C1, + 0x00001B17, 0x00004CEC, 0x000500C2, 0x0000000B, 0x0000237D, 0x000025C1, 0x00000A10, 0x000300F7, + 0x00004667, 0x00000000, 0x000B00FB, 0x00003367, 0x00004667, 0x00000000, 0x00002E69, 0x00000001, + 0x0000401E, 0x00000002, 0x0000401F, 0x00000003, 0x00001FDE, 0x000200F8, 0x00002E69, 0x00060041, + 0x0000028A, 0x000060D7, 0x00000C50, 0x00000A0B, 0x00001D94, 0x0004003D, 0x0000000B, 0x00003241, + 0x000060D7, 0x000500C7, 0x0000000B, 0x00002F59, 0x00004859, 0x00000A13, 0x00050084, 0x0000000B, + 0x000036A3, 0x00002F59, 0x00000A22, 0x000500C2, 0x0000000B, 0x0000387D, 0x00003241, 0x000036A3, + 0x000500C7, 0x0000000B, 0x00003CDC, 0x0000387D, 0x00000144, 0x000500C2, 0x0000000B, 0x00004D70, + 0x000020A1, 0x00000A10, 0x000500C7, 0x0000000B, 0x00004B2B, 0x000020A1, 0x00000A13, 0x00050084, + 0x0000000B, 0x00003722, 0x00004B2B, 0x00000A22, 0x000500C4, 0x0000000B, 0x00005A82, 0x00003CDC, + 0x00003722, 0x000500AA, 0x00000009, 0x00003D0D, 0x00004B2B, 0x00000A0A, 0x000300F7, 0x00005193, + 0x00000000, 0x000400FA, 0x00003D0D, 0x00002F74, 0x00005193, 0x000200F8, 0x00002F74, 0x00050041, + 0x0000028B, 0x0000541D, 0x00000FB1, 0x00004D70, 0x0003003E, 0x0000541D, 0x00005A82, 0x000200F9, + 0x00005193, 0x000200F8, 0x00005193, 0x000400E0, 0x00000A10, 0x00000A10, 0x0000015F, 0x000500AB, + 0x00000009, 0x00003E3C, 0x00004B2B, 0x00000A0A, 0x000300F7, 0x00002386, 0x00000000, 0x000400FA, + 0x00003E3C, 0x00003CBD, 0x00002386, 0x000200F8, 0x00003CBD, 0x00050041, 0x0000028B, 0x000025A5, + 0x00000FB1, 0x00004D70, 0x000700F1, 0x0000000B, 0x0000189F, 0x000025A5, 0x00000A0D, 0x00000A0A, + 0x00005A82, 0x000200F9, 0x00002386, 0x000200F8, 0x00002386, 0x000400E0, 0x00000A10, 0x00000A10, + 0x0000015F, 0x000300F7, 0x00004665, 0x00000000, 0x000400FA, 0x00003D0D, 0x00005192, 0x00004665, + 0x000200F8, 0x00005192, 0x00050084, 0x0000000B, 0x000029FB, 0x00003D0B, 0x00000147, 0x00050080, + 0x0000000B, 0x0000376A, 0x000029FB, 0x00004D70, 0x00050041, 0x0000028B, 0x000036D4, 0x00000FB1, + 0x00004D70, 0x0004003D, 0x0000000B, 0x00003C3D, 0x000036D4, 0x00060041, 0x0000028A, 0x00005BB5, + 0x00001592, 0x00000A0B, 0x0000376A, 0x0003003E, 0x00005BB5, 0x00003C3D, 0x000200F9, 0x00004665, + 0x000200F8, 0x00004665, 0x000200F9, 0x00004667, 0x000200F8, 0x0000401E, 0x00060041, 0x0000028A, + 0x00005A8A, 0x00000C50, 0x00000A0B, 0x00001D94, 0x0004003D, 0x0000000B, 0x00003242, 0x00005A8A, + 0x000500C7, 0x0000000B, 0x00002F5A, 0x00004859, 0x00000A10, 0x00050084, 0x0000000B, 0x000036A4, + 0x00002F5A, 0x00000A22, 0x000500C2, 0x0000000B, 0x0000387E, 0x00003242, 0x000036A4, 0x000500C7, + 0x0000000B, 0x00003CDD, 0x0000387E, 0x000001C1, 0x000500C2, 0x0000000B, 0x00004D71, 0x000020A1, + 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004B2C, 0x000020A1, 0x00000A0D, 0x00050084, 0x0000000B, + 0x00003723, 0x00004B2C, 0x00000A3A, 0x000500C4, 0x0000000B, 0x00005A83, 0x00003CDD, 0x00003723, + 0x000500AA, 0x00000009, 0x00003D0E, 0x00004B2C, 0x00000A0A, 0x000300F7, 0x00005194, 0x00000000, + 0x000400FA, 0x00003D0E, 0x00002F75, 0x00005194, 0x000200F8, 0x00002F75, 0x00050041, 0x0000028B, + 0x0000541E, 0x00000FB1, 0x00004D71, 0x0003003E, 0x0000541E, 0x00005A83, 0x000200F9, 0x00005194, + 0x000200F8, 0x00005194, 0x000400E0, 0x00000A10, 0x00000A10, 0x0000015F, 0x000500AB, 0x00000009, + 0x00003E3D, 0x00004B2C, 0x00000A0A, 0x000300F7, 0x00002387, 0x00000000, 0x000400FA, 0x00003E3D, + 0x00003CBE, 0x00002387, 0x000200F8, 0x00003CBE, 0x00050041, 0x0000028B, 0x000025A6, 0x00000FB1, + 0x00004D71, 0x000700F1, 0x0000000B, 0x000018A0, 0x000025A6, 0x00000A0D, 0x00000A0A, 0x00005A83, + 0x000200F9, 0x00002387, 0x000200F8, 0x00002387, 0x000400E0, 0x00000A10, 0x00000A10, 0x0000015F, + 0x000300F7, 0x00004666, 0x00000000, 0x000400FA, 0x00003D0E, 0x00005195, 0x00004666, 0x000200F8, + 0x00005195, 0x00050084, 0x0000000B, 0x000029FC, 0x00003D0B, 0x00000447, 0x00050080, 0x0000000B, + 0x0000376B, 0x000029FC, 0x00004D71, 0x00050041, 0x0000028B, 0x000036D5, 0x00000FB1, 0x00004D71, + 0x0004003D, 0x0000000B, 0x00003C3E, 0x000036D5, 0x00060041, 0x0000028A, 0x00005BB6, 0x00001592, + 0x00000A0B, 0x0000376B, 0x0003003E, 0x00005BB6, 0x00003C3E, 0x000200F9, 0x00004666, 0x000200F8, + 0x00004666, 0x000200F9, 0x00004667, 0x000200F8, 0x0000401F, 0x00060041, 0x0000028A, 0x00005099, + 0x00000C50, 0x00000A0B, 0x00001D94, 0x0004003D, 0x0000000B, 0x00003D1E, 0x00005099, 0x00060041, + 0x0000028A, 0x00005BB7, 0x00001592, 0x00000A0B, 0x0000237D, 0x0003003E, 0x00005BB7, 0x00003D1E, + 0x000200F9, 0x00004667, 0x000200F8, 0x00001FDE, 0x00060041, 0x0000028A, 0x0000509A, 0x00000C50, + 0x00000A0B, 0x00001D94, 0x0004003D, 0x0000000B, 0x00003D1F, 0x0000509A, 0x00060041, 0x0000028A, + 0x000052BA, 0x00001592, 0x00000A0B, 0x0000237D, 0x0003003E, 0x000052BA, 0x00003D1F, 0x00050080, + 0x0000000B, 0x00004CE6, 0x0000237D, 0x00000A0D, 0x00050080, 0x0000000B, 0x00003448, 0x00001D94, + 0x00000A0D, 0x00060041, 0x0000028A, 0x00002A3A, 0x00000C50, 0x00000A0B, 0x00003448, 0x0004003D, + 0x0000000B, 0x00003C3F, 0x00002A3A, 0x00060041, 0x0000028A, 0x00005BB8, 0x00001592, 0x00000A0B, + 0x00004CE6, 0x0003003E, 0x00005BB8, 0x00003C3F, 0x000200F9, 0x00004667, 0x000200F8, 0x00004667, + 0x000200F9, 0x00003A37, 0x000200F8, 0x00003A37, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_fast_32bpp_1x2xmsaa_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_fast_32bpp_1x2xmsaa_cs.h new file mode 100644 index 0000000..a5a7b89 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_fast_32bpp_1x2xmsaa_cs.h @@ -0,0 +1,737 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25204 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_struct_1036 Block + OpMemberDecorate %_struct_1036 0 Offset 0 + OpMemberDecorate %_struct_1036 1 Offset 4 + OpMemberDecorate %_struct_1036 2 Offset 8 + OpMemberDecorate %_struct_1036 3 Offset 12 + OpMemberDecorate %_struct_1036 4 Offset 16 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %3271 NonWritable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5522 NonReadable + OpDecorate %5522 Binding 0 + OpDecorate %5522 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %bool = OpTypeBool + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %1837 = OpConstantComposite %v2uint %uint_2 %uint_1 + %v2bool = OpTypeVector %bool 2 + %uint_0 = OpConstant %uint 0 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %uint_80 = OpConstant %uint 80 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_struct_1036 = OpTypeStruct %uint %uint %uint %uint %uint +%_ptr_PushConstant__struct_1036 = OpTypePointer PushConstant %_struct_1036 + %3305 = OpVariable %_ptr_PushConstant__struct_1036 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %uint_1023 = OpConstant %uint 1023 + %uint_10 = OpConstant %uint 10 + %uint_4096 = OpConstant %uint 4096 + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_24 = OpConstant %uint 24 + %uint_15 = OpConstant %uint 15 + %uint_28 = OpConstant %uint 28 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 +%uint_16777216 = OpConstant %uint 16777216 + %uint_20 = OpConstant %uint 20 + %2275 = OpConstantComposite %v2uint %uint_20 %uint_24 + %v3uint = OpTypeVector %uint 3 + %uint_255 = OpConstant %uint 255 +%uint_3222273024 = OpConstant %uint 3222273024 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_ptr_Input_uint = OpTypePointer Input %uint + %1834 = OpConstantComposite %v2uint %uint_3 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %3271 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5522 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %1611 = OpConstantComposite %v4uint %uint_255 %uint_255 %uint_255 %uint_255 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %2352 = OpConstantComposite %v4uint %uint_3222273024 %uint_3222273024 %uint_3222273024 %uint_3222273024 + %929 = OpConstantComposite %v4uint %uint_1023 %uint_1023 %uint_1023 %uint_1023 + %965 = OpConstantComposite %v4uint %uint_20 %uint_20 %uint_20 %uint_20 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %uint_40 = OpConstant %uint 40 + %int_40 = OpConstant %int 40 + %int_n40 = OpConstant %int -40 + %uint_1280 = OpConstant %uint 1280 +%uint_2621440 = OpConstant %uint 2621440 + %false = OpConstantFalse %bool + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %20073 = OpShiftRightLogical %uint %15627 %uint_10 + %7177 = OpBitwiseAnd %uint %20073 %uint_3 + %23023 = OpBitwiseAnd %uint %15627 %uint_4096 + %20495 = OpINotEqual %bool %23023 %uint_0 + %10307 = OpShiftRightLogical %uint %15627 %uint_13 + %24434 = OpBitwiseAnd %uint %10307 %uint_2047 + %18836 = OpShiftRightLogical %uint %15627 %uint_24 + %9130 = OpBitwiseAnd %uint %18836 %uint_15 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9576 = OpShiftRightLogical %v2uint %8871 %1855 + %23379 = OpBitwiseAnd %v2uint %9576 %1954 + %16207 = OpShiftLeftLogical %v2uint %23379 %1870 + %23019 = OpIMul %v2uint %16207 %1828 + %12819 = OpShiftRightLogical %uint %20824 %uint_5 + %16204 = OpBitwiseAnd %uint %12819 %uint_2047 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %24236 = OpLoad %uint %18732 + %22701 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %20919 = OpLoad %uint %22701 + %19164 = OpBitwiseAnd %uint %24236 %uint_7 + %21999 = OpBitwiseAnd %uint %24236 %uint_8 + %20496 = OpINotEqual %bool %21999 %uint_0 + %10402 = OpShiftRightLogical %uint %24236 %uint_4 + %23037 = OpBitwiseAnd %uint %10402 %uint_7 + %23118 = OpBitwiseAnd %uint %24236 %uint_16777216 + %19573 = OpINotEqual %bool %23118 %uint_0 + %8003 = OpBitwiseAnd %uint %20919 %uint_1023 + %15783 = OpShiftLeftLogical %uint %8003 %uint_5 + %22591 = OpShiftRightLogical %uint %20919 %uint_10 + %19390 = OpBitwiseAnd %uint %22591 %uint_1023 + %25203 = OpShiftLeftLogical %uint %19390 %uint_5 + %10422 = OpCompositeConstruct %v2uint %20919 %20919 + %10385 = OpShiftRightLogical %v2uint %10422 %2275 + %23380 = OpBitwiseAnd %v2uint %10385 %2122 + %16208 = OpShiftLeftLogical %v2uint %23380 %1870 + %23020 = OpIMul %v2uint %16208 %1828 + %12820 = OpShiftRightLogical %uint %20919 %uint_28 + %16205 = OpBitwiseAnd %uint %12820 %uint_7 + %18733 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_4 + %24237 = OpLoad %uint %18733 + %22225 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0 + %7085 = OpLoad %uint %22225 + %7405 = OpUGreaterThanEqual %bool %7085 %16204 + OpSelectionMerge %17447 DontFlatten + OpBranchConditional %7405 %21992 %17447 + %21992 = OpLabel + OpBranch %19578 + %17447 = OpLabel + %14637 = OpLoad %v3uint %gl_GlobalInvocationID + %18505 = OpVectorShuffle %v2uint %14637 %14637 0 1 + %9840 = OpShiftLeftLogical %v2uint %18505 %1834 + %24498 = OpCompositeExtract %uint %9840 0 + %7150 = OpCompositeExtract %uint %9840 1 + %24446 = OpExtInst %uint %1 UMax %7150 %uint_0 + %20975 = OpCompositeConstruct %v2uint %24498 %24446 + %21036 = OpIAdd %v2uint %20975 %23019 + %16075 = OpULessThanEqual %bool %16205 %uint_3 + OpSelectionMerge %23776 None + OpBranchConditional %16075 %10990 %15087 + %15087 = OpLabel + %13566 = OpIEqual %bool %16205 %uint_5 + %8438 = OpSelect %uint %13566 %uint_2 %uint_0 + OpBranch %23776 + %10990 = OpLabel + OpBranch %23776 + %23776 = OpLabel + %19300 = OpPhi %uint %16205 %10990 %8438 %15087 + %16830 = OpCompositeConstruct %v2uint %7177 %7177 + %11801 = OpUGreaterThanEqual %v2bool %16830 %1837 + %19381 = OpSelect %v2uint %11801 %1828 %1807 + %10986 = OpShiftLeftLogical %v2uint %21036 %19381 + %24669 = OpCompositeConstruct %v2uint %19300 %19300 + %9093 = OpShiftRightLogical %v2uint %24669 %1816 + %16110 = OpBitwiseAnd %v2uint %9093 %1828 + %17779 = OpIAdd %v2uint %10986 %16110 + %24270 = OpUDiv %v2uint %17779 %2719 + %12360 = OpCompositeExtract %uint %24270 1 + %11046 = OpIMul %uint %12360 %20561 + %24665 = OpCompositeExtract %uint %24270 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %24434 %21536 + %6459 = OpIMul %v2uint %24270 %2719 + %14279 = OpISub %v2uint %17779 %6459 + OpSelectionMerge %19725 None + OpBranchConditional %20495 %10558 %19725 + %10558 = OpLabel + %11791 = OpCompositeExtract %uint %14279 0 + %24981 = OpBitcast %int %11791 + %7841 = OpUGreaterThanEqual %bool %11791 %uint_40 + %22568 = OpSelect %int %7841 %int_n40 %int_40 + %11768 = OpIAdd %int %24981 %22568 + %8071 = OpBitcast %uint %11768 + %21574 = OpCompositeInsert %v2uint %8071 %14279 0 + OpBranch %19725 + %19725 = OpLabel + %8537 = OpPhi %v2uint %14279 %23776 %21574 %10558 + %6671 = OpIMul %uint %8742 %uint_1280 + %13892 = OpCompositeExtract %uint %8537 1 + %15890 = OpIMul %uint %13892 %uint_80 + %24666 = OpCompositeExtract %uint %8537 0 + %21631 = OpIAdd %uint %15890 %24666 + %9094 = OpIAdd %uint %6671 %21631 + %8177 = OpUMod %uint %9094 %uint_2621440 + %18580 = OpShiftRightLogical %uint %8177 %uint_2 + %17174 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %18580 + %12609 = OpLoad %v4uint %17174 + %11687 = OpIAdd %uint %18580 %uint_1 + %7197 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %11687 + %18360 = OpLoad %v4uint %7197 + %15472 = OpIEqual %bool %24498 %uint_0 + %15603 = OpSelect %bool %15472 %false %15472 + OpSelectionMerge %21910 DontFlatten + OpBranchConditional %15603 %9760 %21910 + %9760 = OpLabel + %20482 = OpCompositeExtract %uint %12609 1 + %14335 = OpCompositeInsert %v4uint %20482 %12609 0 + OpBranch %21910 + %21910 = OpLabel + %10924 = OpPhi %v4uint %12609 %19725 %14335 %9760 + OpSelectionMerge %21263 DontFlatten + OpBranchConditional %19573 %22395 %21263 + %22395 = OpLabel + OpSelectionMerge %14836 None + OpSwitch %9130 %14836 0 %21920 1 %21920 2 %10391 3 %10391 10 %10391 12 %10391 + %10391 = OpLabel + %15273 = OpBitwiseAnd %v4uint %10924 %2352 + %23564 = OpBitwiseAnd %v4uint %10924 %929 + %24837 = OpShiftLeftLogical %v4uint %23564 %965 + %18005 = OpBitwiseOr %v4uint %15273 %24837 + %23170 = OpShiftRightLogical %v4uint %10924 %965 + %6442 = OpBitwiseAnd %v4uint %23170 %929 + %15589 = OpBitwiseOr %v4uint %18005 %6442 + %19519 = OpBitwiseAnd %v4uint %18360 %2352 + %17946 = OpBitwiseAnd %v4uint %18360 %929 + %24838 = OpShiftLeftLogical %v4uint %17946 %965 + %18006 = OpBitwiseOr %v4uint %19519 %24838 + %23171 = OpShiftRightLogical %v4uint %18360 %965 + %7392 = OpBitwiseAnd %v4uint %23171 %929 + %7870 = OpBitwiseOr %v4uint %18006 %7392 + OpBranch %14836 + %21920 = OpLabel + %20117 = OpBitwiseAnd %v4uint %10924 %1838 + %23565 = OpBitwiseAnd %v4uint %10924 %1611 + %24839 = OpShiftLeftLogical %v4uint %23565 %749 + %18007 = OpBitwiseOr %v4uint %20117 %24839 + %23172 = OpShiftRightLogical %v4uint %10924 %749 + %6443 = OpBitwiseAnd %v4uint %23172 %1611 + %15590 = OpBitwiseOr %v4uint %18007 %6443 + %19520 = OpBitwiseAnd %v4uint %18360 %1838 + %17947 = OpBitwiseAnd %v4uint %18360 %1611 + %24840 = OpShiftLeftLogical %v4uint %17947 %749 + %18008 = OpBitwiseOr %v4uint %19520 %24840 + %23173 = OpShiftRightLogical %v4uint %18360 %749 + %7393 = OpBitwiseAnd %v4uint %23173 %1611 + %7871 = OpBitwiseOr %v4uint %18008 %7393 + OpBranch %14836 + %14836 = OpLabel + %11251 = OpPhi %v4uint %18360 %22395 %7871 %21920 %7870 %10391 + %13709 = OpPhi %v4uint %10924 %22395 %15590 %21920 %15589 %10391 + OpBranch %21263 + %21263 = OpLabel + %8952 = OpPhi %v4uint %18360 %21910 %11251 %14836 + %22009 = OpPhi %v4uint %10924 %21910 %13709 %14836 + %7319 = OpIAdd %v2uint %9840 %23020 + OpSelectionMerge %21237 DontFlatten + OpBranchConditional %20496 %10574 %21373 + %21373 = OpLabel + %10608 = OpBitcast %v2int %7319 + %17090 = OpCompositeExtract %int %10608 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %10608 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %15783 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17303 = OpIAdd %int %10934 %17741 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15435 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18356 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18356 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12151 + %19165 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19165 %int_2 + %16708 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21587 %int_6 + %15436 = OpIAdd %int %16708 %21580 + %11782 = OpBitwiseAnd %int %16727 %int_63 + %14671 = OpIAdd %int %15436 %11782 + %22127 = OpBitcast %uint %14671 + OpBranch %21237 + %10574 = OpLabel + %19866 = OpCompositeExtract %uint %7319 0 + %11267 = OpCompositeExtract %uint %7319 1 + %8414 = OpCompositeConstruct %v3uint %19866 %11267 %23037 + %20125 = OpBitcast %v3int %8414 + %10438 = OpCompositeExtract %int %20125 1 + %9470 = OpShiftRightArithmetic %int %10438 %int_4 + %10056 = OpCompositeExtract %int %20125 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %25203 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %15783 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %20125 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12601 = OpBitwiseAnd %int %10438 %int_6 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %10438 %int_3 + %13731 = OpIAdd %int %8725 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19166 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19166 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18357 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18357 %uint_8 + %16729 = OpIAdd %int %10332 %21582 + %19167 = OpBitwiseAnd %int %10438 %int_1 + %21583 = OpShiftLeftLogical %int %19167 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16730 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22128 = OpBitcast %uint %24314 + OpBranch %21237 + %21237 = OpLabel + %11376 = OpPhi %uint %22128 %10574 %22127 %21373 + %20616 = OpIAdd %uint %11376 %24237 + %18675 = OpShiftRightLogical %uint %20616 %uint_4 + %12010 = OpIEqual %bool %19164 %uint_1 + %22390 = OpIEqual %bool %19164 %uint_2 + %22150 = OpLogicalOr %bool %12010 %22390 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %22009 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %22009 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %22009 %21237 %16376 %10583 + %19638 = OpIEqual %bool %19164 %uint_3 + %15139 = OpLogicalOr %bool %22390 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %24825 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %18675 + OpStore %24825 %19767 + %21685 = OpIAdd %uint %18675 %uint_2 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %8952 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %8952 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10925 = OpPhi %v4uint %8952 %11416 %16377 %10584 + OpSelectionMerge %11417 None + OpBranchConditional %15139 %11065 %11417 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10925 %749 + %15336 = OpShiftRightLogical %v4uint %10925 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %10925 %14874 %10729 %11065 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %21685 + OpStore %8053 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_fast_32bpp_1x2xmsaa_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006274, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00030047, 0x0000040C, 0x00000002, 0x00050048, + 0x0000040C, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x0000040C, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x0000040C, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x0000040C, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x0000040C, 0x00000004, 0x00000023, 0x00000010, + 0x00040047, 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, + 0x00030047, 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, + 0x000007B4, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000CC7, 0x00000018, 0x00040047, + 0x00000CC7, 0x00000021, 0x00000000, 0x00040047, 0x00000CC7, 0x00000022, 0x00000000, 0x00040047, + 0x000007DD, 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, + 0x00000000, 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, + 0x00001592, 0x00000019, 0x00040047, 0x00001592, 0x00000021, 0x00000000, 0x00040047, 0x00001592, + 0x00000022, 0x00000001, 0x00040047, 0x00000AC7, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, + 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, + 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00020014, + 0x00000009, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, + 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A0D, + 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x000008A6, + 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, + 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A3A, + 0x00000010, 0x0005002C, 0x00000011, 0x0000072D, 0x00000A10, 0x00000A0D, 0x00040017, 0x0000000F, + 0x00000009, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0005002C, 0x00000011, + 0x0000070F, 0x00000A0A, 0x00000A0A, 0x0005002C, 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, + 0x0005002C, 0x00000011, 0x00000718, 0x00000A0D, 0x00000A0A, 0x0004002B, 0x0000000B, 0x00000AFA, + 0x00000050, 0x0005002C, 0x00000011, 0x00000A9F, 0x00000AFA, 0x00000A3A, 0x0004002B, 0x0000000C, + 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, + 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, + 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, + 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, + 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, + 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, + 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, + 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, + 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, + 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0007001E, 0x0000040C, + 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000688, 0x00000009, + 0x0000040C, 0x0004003B, 0x00000688, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, + 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0004002B, 0x0000000B, 0x00000A44, + 0x000003FF, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000AFE, + 0x00001000, 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, 0x0004002B, 0x0000000B, 0x00000A81, + 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A52, 0x00000018, 0x0004002B, 0x0000000B, 0x00000A37, + 0x0000000F, 0x0004002B, 0x0000000B, 0x00000A5E, 0x0000001C, 0x0005002C, 0x00000011, 0x0000073F, + 0x00000A0A, 0x00000A16, 0x0004002B, 0x0000000B, 0x00000926, 0x01000000, 0x0004002B, 0x0000000B, + 0x00000A46, 0x00000014, 0x0005002C, 0x00000011, 0x000008E3, 0x00000A46, 0x00000A52, 0x00040017, + 0x00000014, 0x0000000B, 0x00000003, 0x0004002B, 0x0000000B, 0x00000144, 0x000000FF, 0x0004002B, + 0x0000000B, 0x00000B54, 0xC00FFC00, 0x00040020, 0x00000291, 0x00000001, 0x00000014, 0x0004003B, + 0x00000291, 0x00000F48, 0x00000001, 0x00040020, 0x00000289, 0x00000001, 0x0000000B, 0x0005002C, + 0x00000011, 0x0000072A, 0x00000A13, 0x00000A0A, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, + 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A32, + 0x00000CC7, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, + 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A33, 0x00000002, 0x000007B5, + 0x0004003B, 0x00000A33, 0x00001592, 0x00000002, 0x0006002C, 0x00000014, 0x00000AC7, 0x00000A22, + 0x00000A22, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A37, 0x00000A0D, 0x0005002C, + 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, 0x0005002C, 0x00000011, 0x0000084A, 0x00000A37, + 0x00000A37, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, + 0x0007002C, 0x00000017, 0x0000064B, 0x00000144, 0x00000144, 0x00000144, 0x00000144, 0x0007002C, + 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0007002C, 0x00000017, + 0x00000930, 0x00000B54, 0x00000B54, 0x00000B54, 0x00000B54, 0x0007002C, 0x00000017, 0x000003A1, + 0x00000A44, 0x00000A44, 0x00000A44, 0x00000A44, 0x0007002C, 0x00000017, 0x000003C5, 0x00000A46, + 0x00000A46, 0x00000A46, 0x00000A46, 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0007002C, + 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, + 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0004002B, 0x0000000B, 0x00000A82, + 0x00000028, 0x0004002B, 0x0000000C, 0x00000A83, 0x00000028, 0x0004002B, 0x0000000C, 0x00000993, + 0xFFFFFFD8, 0x0004002B, 0x0000000B, 0x00000184, 0x00000500, 0x0004002B, 0x0000000B, 0x0000086E, + 0x00280000, 0x0003002A, 0x00000009, 0x00000787, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, + 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, + 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000056E5, 0x00000CE9, 0x00000A0B, + 0x0004003D, 0x0000000B, 0x00003D0B, 0x000056E5, 0x00050041, 0x00000288, 0x000058AC, 0x00000CE9, + 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005158, 0x000058AC, 0x000500C7, 0x0000000B, 0x00005051, + 0x00003D0B, 0x00000A44, 0x000500C2, 0x0000000B, 0x00004E69, 0x00003D0B, 0x00000A28, 0x000500C7, + 0x0000000B, 0x00001C09, 0x00004E69, 0x00000A13, 0x000500C7, 0x0000000B, 0x000059EF, 0x00003D0B, + 0x00000AFE, 0x000500AB, 0x00000009, 0x0000500F, 0x000059EF, 0x00000A0A, 0x000500C2, 0x0000000B, + 0x00002843, 0x00003D0B, 0x00000A31, 0x000500C7, 0x0000000B, 0x00005F72, 0x00002843, 0x00000A81, + 0x000500C2, 0x0000000B, 0x00004994, 0x00003D0B, 0x00000A52, 0x000500C7, 0x0000000B, 0x000023AA, + 0x00004994, 0x00000A37, 0x00050050, 0x00000011, 0x000022A7, 0x00005158, 0x00005158, 0x000500C2, + 0x00000011, 0x00002568, 0x000022A7, 0x0000073F, 0x000500C7, 0x00000011, 0x00005B53, 0x00002568, + 0x000007A2, 0x000500C4, 0x00000011, 0x00003F4F, 0x00005B53, 0x0000074E, 0x00050084, 0x00000011, + 0x000059EB, 0x00003F4F, 0x00000724, 0x000500C2, 0x0000000B, 0x00003213, 0x00005158, 0x00000A19, + 0x000500C7, 0x0000000B, 0x00003F4C, 0x00003213, 0x00000A81, 0x00050041, 0x00000288, 0x0000492C, + 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, + 0x000058AD, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x000051B7, 0x000058AD, 0x000500C7, + 0x0000000B, 0x00004ADC, 0x00005EAC, 0x00000A1F, 0x000500C7, 0x0000000B, 0x000055EF, 0x00005EAC, + 0x00000A22, 0x000500AB, 0x00000009, 0x00005010, 0x000055EF, 0x00000A0A, 0x000500C2, 0x0000000B, + 0x000028A2, 0x00005EAC, 0x00000A16, 0x000500C7, 0x0000000B, 0x000059FD, 0x000028A2, 0x00000A1F, + 0x000500C7, 0x0000000B, 0x00005A4E, 0x00005EAC, 0x00000926, 0x000500AB, 0x00000009, 0x00004C75, + 0x00005A4E, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00001F43, 0x000051B7, 0x00000A44, 0x000500C4, + 0x0000000B, 0x00003DA7, 0x00001F43, 0x00000A19, 0x000500C2, 0x0000000B, 0x0000583F, 0x000051B7, + 0x00000A28, 0x000500C7, 0x0000000B, 0x00004BBE, 0x0000583F, 0x00000A44, 0x000500C4, 0x0000000B, + 0x00006273, 0x00004BBE, 0x00000A19, 0x00050050, 0x00000011, 0x000028B6, 0x000051B7, 0x000051B7, + 0x000500C2, 0x00000011, 0x00002891, 0x000028B6, 0x000008E3, 0x000500C7, 0x00000011, 0x00005B54, + 0x00002891, 0x0000084A, 0x000500C4, 0x00000011, 0x00003F50, 0x00005B54, 0x0000074E, 0x00050084, + 0x00000011, 0x000059EC, 0x00003F50, 0x00000724, 0x000500C2, 0x0000000B, 0x00003214, 0x000051B7, + 0x00000A5E, 0x000500C7, 0x0000000B, 0x00003F4D, 0x00003214, 0x00000A1F, 0x00050041, 0x00000288, + 0x0000492D, 0x00000CE9, 0x00000A17, 0x0004003D, 0x0000000B, 0x00005EAD, 0x0000492D, 0x00050041, + 0x00000289, 0x000056D1, 0x00000F48, 0x00000A0A, 0x0004003D, 0x0000000B, 0x00001BAD, 0x000056D1, + 0x000500AE, 0x00000009, 0x00001CED, 0x00001BAD, 0x00003F4C, 0x000300F7, 0x00004427, 0x00000002, + 0x000400FA, 0x00001CED, 0x000055E8, 0x00004427, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, + 0x000200F8, 0x00004427, 0x0004003D, 0x00000014, 0x0000392D, 0x00000F48, 0x0007004F, 0x00000011, + 0x00004849, 0x0000392D, 0x0000392D, 0x00000000, 0x00000001, 0x000500C4, 0x00000011, 0x00002670, + 0x00004849, 0x0000072A, 0x00050051, 0x0000000B, 0x00005FB2, 0x00002670, 0x00000000, 0x00050051, + 0x0000000B, 0x00001BEE, 0x00002670, 0x00000001, 0x0007000C, 0x0000000B, 0x00005F7E, 0x00000001, + 0x00000029, 0x00001BEE, 0x00000A0A, 0x00050050, 0x00000011, 0x000051EF, 0x00005FB2, 0x00005F7E, + 0x00050080, 0x00000011, 0x0000522C, 0x000051EF, 0x000059EB, 0x000500B2, 0x00000009, 0x00003ECB, + 0x00003F4D, 0x00000A13, 0x000300F7, 0x00005CE0, 0x00000000, 0x000400FA, 0x00003ECB, 0x00002AEE, + 0x00003AEF, 0x000200F8, 0x00003AEF, 0x000500AA, 0x00000009, 0x000034FE, 0x00003F4D, 0x00000A19, + 0x000600A9, 0x0000000B, 0x000020F6, 0x000034FE, 0x00000A10, 0x00000A0A, 0x000200F9, 0x00005CE0, + 0x000200F8, 0x00002AEE, 0x000200F9, 0x00005CE0, 0x000200F8, 0x00005CE0, 0x000700F5, 0x0000000B, + 0x00004B64, 0x00003F4D, 0x00002AEE, 0x000020F6, 0x00003AEF, 0x00050050, 0x00000011, 0x000041BE, + 0x00001C09, 0x00001C09, 0x000500AE, 0x0000000F, 0x00002E19, 0x000041BE, 0x0000072D, 0x000600A9, + 0x00000011, 0x00004BB5, 0x00002E19, 0x00000724, 0x0000070F, 0x000500C4, 0x00000011, 0x00002AEA, + 0x0000522C, 0x00004BB5, 0x00050050, 0x00000011, 0x0000605D, 0x00004B64, 0x00004B64, 0x000500C2, + 0x00000011, 0x00002385, 0x0000605D, 0x00000718, 0x000500C7, 0x00000011, 0x00003EEE, 0x00002385, + 0x00000724, 0x00050080, 0x00000011, 0x00004573, 0x00002AEA, 0x00003EEE, 0x00050086, 0x00000011, + 0x00005ECE, 0x00004573, 0x00000A9F, 0x00050051, 0x0000000B, 0x00003048, 0x00005ECE, 0x00000001, + 0x00050084, 0x0000000B, 0x00002B26, 0x00003048, 0x00005051, 0x00050051, 0x0000000B, 0x00006059, + 0x00005ECE, 0x00000000, 0x00050080, 0x0000000B, 0x00005420, 0x00002B26, 0x00006059, 0x00050080, + 0x0000000B, 0x00002226, 0x00005F72, 0x00005420, 0x00050084, 0x00000011, 0x0000193B, 0x00005ECE, + 0x00000A9F, 0x00050082, 0x00000011, 0x000037C7, 0x00004573, 0x0000193B, 0x000300F7, 0x00004D0D, + 0x00000000, 0x000400FA, 0x0000500F, 0x0000293E, 0x00004D0D, 0x000200F8, 0x0000293E, 0x00050051, + 0x0000000B, 0x00002E0F, 0x000037C7, 0x00000000, 0x0004007C, 0x0000000C, 0x00006195, 0x00002E0F, + 0x000500AE, 0x00000009, 0x00001EA1, 0x00002E0F, 0x00000A82, 0x000600A9, 0x0000000C, 0x00005828, + 0x00001EA1, 0x00000993, 0x00000A83, 0x00050080, 0x0000000C, 0x00002DF8, 0x00006195, 0x00005828, + 0x0004007C, 0x0000000B, 0x00001F87, 0x00002DF8, 0x00060052, 0x00000011, 0x00005446, 0x00001F87, + 0x000037C7, 0x00000000, 0x000200F9, 0x00004D0D, 0x000200F8, 0x00004D0D, 0x000700F5, 0x00000011, + 0x00002159, 0x000037C7, 0x00005CE0, 0x00005446, 0x0000293E, 0x00050084, 0x0000000B, 0x00001A0F, + 0x00002226, 0x00000184, 0x00050051, 0x0000000B, 0x00003644, 0x00002159, 0x00000001, 0x00050084, + 0x0000000B, 0x00003E12, 0x00003644, 0x00000AFA, 0x00050051, 0x0000000B, 0x0000605A, 0x00002159, + 0x00000000, 0x00050080, 0x0000000B, 0x0000547F, 0x00003E12, 0x0000605A, 0x00050080, 0x0000000B, + 0x00002386, 0x00001A0F, 0x0000547F, 0x00050089, 0x0000000B, 0x00001FF1, 0x00002386, 0x0000086E, + 0x000500C2, 0x0000000B, 0x00004894, 0x00001FF1, 0x00000A10, 0x00060041, 0x00000294, 0x00004316, + 0x00000CC7, 0x00000A0B, 0x00004894, 0x0004003D, 0x00000017, 0x00003141, 0x00004316, 0x00050080, + 0x0000000B, 0x00002DA7, 0x00004894, 0x00000A0D, 0x00060041, 0x00000294, 0x00001C1D, 0x00000CC7, + 0x00000A0B, 0x00002DA7, 0x0004003D, 0x00000017, 0x000047B8, 0x00001C1D, 0x000500AA, 0x00000009, + 0x00003C70, 0x00005FB2, 0x00000A0A, 0x000600A9, 0x00000009, 0x00003CF3, 0x00003C70, 0x00000787, + 0x00003C70, 0x000300F7, 0x00005596, 0x00000002, 0x000400FA, 0x00003CF3, 0x00002620, 0x00005596, + 0x000200F8, 0x00002620, 0x00050051, 0x0000000B, 0x00005002, 0x00003141, 0x00000001, 0x00060052, + 0x00000017, 0x000037FF, 0x00005002, 0x00003141, 0x00000000, 0x000200F9, 0x00005596, 0x000200F8, + 0x00005596, 0x000700F5, 0x00000017, 0x00002AAC, 0x00003141, 0x00004D0D, 0x000037FF, 0x00002620, + 0x000300F7, 0x0000530F, 0x00000002, 0x000400FA, 0x00004C75, 0x0000577B, 0x0000530F, 0x000200F8, + 0x0000577B, 0x000300F7, 0x000039F4, 0x00000000, 0x000F00FB, 0x000023AA, 0x000039F4, 0x00000000, + 0x000055A0, 0x00000001, 0x000055A0, 0x00000002, 0x00002897, 0x00000003, 0x00002897, 0x0000000A, + 0x00002897, 0x0000000C, 0x00002897, 0x000200F8, 0x00002897, 0x000500C7, 0x00000017, 0x00003BA9, + 0x00002AAC, 0x00000930, 0x000500C7, 0x00000017, 0x00005C0C, 0x00002AAC, 0x000003A1, 0x000500C4, + 0x00000017, 0x00006105, 0x00005C0C, 0x000003C5, 0x000500C5, 0x00000017, 0x00004655, 0x00003BA9, + 0x00006105, 0x000500C2, 0x00000017, 0x00005A82, 0x00002AAC, 0x000003C5, 0x000500C7, 0x00000017, + 0x0000192A, 0x00005A82, 0x000003A1, 0x000500C5, 0x00000017, 0x00003CE5, 0x00004655, 0x0000192A, + 0x000500C7, 0x00000017, 0x00004C3F, 0x000047B8, 0x00000930, 0x000500C7, 0x00000017, 0x0000461A, + 0x000047B8, 0x000003A1, 0x000500C4, 0x00000017, 0x00006106, 0x0000461A, 0x000003C5, 0x000500C5, + 0x00000017, 0x00004656, 0x00004C3F, 0x00006106, 0x000500C2, 0x00000017, 0x00005A83, 0x000047B8, + 0x000003C5, 0x000500C7, 0x00000017, 0x00001CE0, 0x00005A83, 0x000003A1, 0x000500C5, 0x00000017, + 0x00001EBE, 0x00004656, 0x00001CE0, 0x000200F9, 0x000039F4, 0x000200F8, 0x000055A0, 0x000500C7, + 0x00000017, 0x00004E95, 0x00002AAC, 0x0000072E, 0x000500C7, 0x00000017, 0x00005C0D, 0x00002AAC, + 0x0000064B, 0x000500C4, 0x00000017, 0x00006107, 0x00005C0D, 0x000002ED, 0x000500C5, 0x00000017, + 0x00004657, 0x00004E95, 0x00006107, 0x000500C2, 0x00000017, 0x00005A84, 0x00002AAC, 0x000002ED, + 0x000500C7, 0x00000017, 0x0000192B, 0x00005A84, 0x0000064B, 0x000500C5, 0x00000017, 0x00003CE6, + 0x00004657, 0x0000192B, 0x000500C7, 0x00000017, 0x00004C40, 0x000047B8, 0x0000072E, 0x000500C7, + 0x00000017, 0x0000461B, 0x000047B8, 0x0000064B, 0x000500C4, 0x00000017, 0x00006108, 0x0000461B, + 0x000002ED, 0x000500C5, 0x00000017, 0x00004658, 0x00004C40, 0x00006108, 0x000500C2, 0x00000017, + 0x00005A85, 0x000047B8, 0x000002ED, 0x000500C7, 0x00000017, 0x00001CE1, 0x00005A85, 0x0000064B, + 0x000500C5, 0x00000017, 0x00001EBF, 0x00004658, 0x00001CE1, 0x000200F9, 0x000039F4, 0x000200F8, + 0x000039F4, 0x000900F5, 0x00000017, 0x00002BF3, 0x000047B8, 0x0000577B, 0x00001EBF, 0x000055A0, + 0x00001EBE, 0x00002897, 0x000900F5, 0x00000017, 0x0000358D, 0x00002AAC, 0x0000577B, 0x00003CE6, + 0x000055A0, 0x00003CE5, 0x00002897, 0x000200F9, 0x0000530F, 0x000200F8, 0x0000530F, 0x000700F5, + 0x00000017, 0x000022F8, 0x000047B8, 0x00005596, 0x00002BF3, 0x000039F4, 0x000700F5, 0x00000017, + 0x000055F9, 0x00002AAC, 0x00005596, 0x0000358D, 0x000039F4, 0x00050080, 0x00000011, 0x00001C97, + 0x00002670, 0x000059EC, 0x000300F7, 0x000052F5, 0x00000002, 0x000400FA, 0x00005010, 0x0000294E, + 0x0000537D, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000012, 0x00002970, 0x00001C97, 0x00050051, + 0x0000000C, 0x000042C2, 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, + 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, + 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00003DA7, 0x00000A19, + 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, + 0x000018AA, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, + 0x00004A8E, 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002AB6, 0x000042C2, 0x00000A20, + 0x000500C7, 0x0000000C, 0x00003138, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454D, + 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454D, 0x000500C4, + 0x0000000C, 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, + 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, + 0x00003C4B, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, + 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4B, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B4, + 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544A, 0x000047B4, 0x00000A17, 0x00050080, + 0x0000000C, 0x00004157, 0x00004D30, 0x0000544A, 0x000500C7, 0x0000000C, 0x00005022, 0x00004157, + 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, + 0x00050080, 0x0000000C, 0x00004158, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADD, + 0x00004157, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544B, 0x00004ADD, 0x00000A11, 0x00050080, + 0x0000000C, 0x00004144, 0x00004158, 0x0000544B, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, + 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, + 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, + 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544C, + 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004144, 0x0000544C, 0x000500C7, + 0x0000000C, 0x00002E06, 0x00004157, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4C, + 0x00002E06, 0x0004007C, 0x0000000B, 0x0000566F, 0x0000394F, 0x000200F9, 0x000052F5, 0x000200F8, + 0x0000294E, 0x00050051, 0x0000000B, 0x00004D9A, 0x00001C97, 0x00000000, 0x00050051, 0x0000000B, + 0x00002C03, 0x00001C97, 0x00000001, 0x00060050, 0x00000014, 0x000020DE, 0x00004D9A, 0x00002C03, + 0x000059FD, 0x0004007C, 0x00000016, 0x00004E9D, 0x000020DE, 0x00050051, 0x0000000C, 0x000028C6, + 0x00004E9D, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FE, 0x000028C6, 0x00000A17, 0x00050051, + 0x0000000C, 0x00002748, 0x00004E9D, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, + 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00006273, 0x00000A16, 0x0004007C, 0x0000000C, + 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005321, 0x0000405D, 0x000018AB, 0x00050080, + 0x0000000C, 0x00003B27, 0x000024FE, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00003DA7, + 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, + 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, 0x00004E9D, 0x00000000, 0x000500C3, + 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, + 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A22, 0x000500C7, 0x0000000C, + 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, + 0x000028C6, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, + 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454E, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, + 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, + 0x00002215, 0x000028C6, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405D, + 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, + 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, + 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000034BD, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544D, 0x00004ADE, 0x00000A0E, 0x00050080, 0x0000000C, + 0x00003C4D, 0x00005A0C, 0x0000544D, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, + 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, + 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, + 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544E, 0x000047B5, 0x00000A22, 0x00050080, 0x0000000C, + 0x00004159, 0x0000285C, 0x0000544E, 0x000500C7, 0x0000000C, 0x00004ADF, 0x000028C6, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544F, 0x00004ADF, 0x00000A17, 0x00050080, 0x0000000C, 0x0000415A, + 0x00004159, 0x0000544F, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4D, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x0000415A, + 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, + 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4D, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, + 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, + 0x0000000C, 0x00005AB2, 0x0000415A, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, + 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005559, 0x0000415A, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, + 0x0004007C, 0x0000000B, 0x00005670, 0x00005EFA, 0x000200F9, 0x000052F5, 0x000200F8, 0x000052F5, + 0x000700F5, 0x0000000B, 0x00002C70, 0x00005670, 0x0000294E, 0x0000566F, 0x0000537D, 0x00050080, + 0x0000000B, 0x00005088, 0x00002C70, 0x00005EAD, 0x000500C2, 0x0000000B, 0x000048F3, 0x00005088, + 0x00000A16, 0x000500AA, 0x00000009, 0x00002EEA, 0x00004ADC, 0x00000A0D, 0x000500AA, 0x00000009, + 0x00005776, 0x00004ADC, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x00002EEA, 0x00005776, + 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, + 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x000055F9, 0x000009CE, 0x000500C4, 0x00000017, + 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x000055F9, 0x0000072E, + 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, + 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, + 0x00005879, 0x000055F9, 0x000052F5, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, + 0x00004ADC, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005776, 0x00004CB6, 0x000300F7, + 0x00002C98, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x00002C98, 0x000200F8, 0x00002B38, + 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, + 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, + 0x00002C98, 0x000200F8, 0x00002C98, 0x000700F5, 0x00000017, 0x00004D37, 0x00005879, 0x00003463, + 0x000029E8, 0x00002B38, 0x00060041, 0x00000294, 0x000060F9, 0x00001592, 0x00000A0B, 0x000048F3, + 0x0003003E, 0x000060F9, 0x00004D37, 0x00050080, 0x0000000B, 0x000054B5, 0x000048F3, 0x00000A10, + 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, + 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000022F8, 0x000009CE, 0x000500C4, 0x00000017, + 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000022F8, 0x0000072E, + 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, + 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, + 0x00002AAD, 0x000022F8, 0x00002C98, 0x00003FF9, 0x00002958, 0x000300F7, 0x00002C99, 0x00000000, + 0x000400FA, 0x00003B23, 0x00002B39, 0x00002C99, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, + 0x00005E18, 0x00002AAD, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAD, 0x000002ED, + 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002C99, 0x000200F8, + 0x00002C99, 0x000700F5, 0x00000017, 0x00004D39, 0x00002AAD, 0x00003A1A, 0x000029E9, 0x00002B39, + 0x00060041, 0x00000294, 0x00001F75, 0x00001592, 0x00000A0B, 0x000054B5, 0x0003003E, 0x00001F75, + 0x00004D39, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_fast_32bpp_1x2xmsaa_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_fast_32bpp_1x2xmsaa_scaled_cs.h new file mode 100644 index 0000000..21e73ab --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_fast_32bpp_1x2xmsaa_scaled_cs.h @@ -0,0 +1,895 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25204 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_struct_1017 Block + OpMemberDecorate %_struct_1017 0 Offset 0 + OpMemberDecorate %_struct_1017 1 Offset 4 + OpMemberDecorate %_struct_1017 2 Offset 8 + OpMemberDecorate %_struct_1017 3 Offset 12 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %3271 NonWritable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5522 NonReadable + OpDecorate %5522 Binding 0 + OpDecorate %5522 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %bool = OpTypeBool + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %v3uint = OpTypeVector %uint 3 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %1837 = OpConstantComposite %v2uint %uint_2 %uint_1 + %v2bool = OpTypeVector %bool 2 + %uint_0 = OpConstant %uint 0 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %uint_80 = OpConstant %uint 80 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %uint_2048 = OpConstant %uint 2048 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1017 = OpTypeStruct %uint %uint %uint %uint +%_ptr_PushConstant__struct_1017 = OpTypePointer PushConstant %_struct_1017 + %3305 = OpVariable %_ptr_PushConstant__struct_1017 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %uint_1023 = OpConstant %uint 1023 + %uint_10 = OpConstant %uint 10 + %uint_4096 = OpConstant %uint 4096 + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_24 = OpConstant %uint 24 + %uint_15 = OpConstant %uint 15 + %uint_28 = OpConstant %uint 28 + %uint_19 = OpConstant %uint 19 + %2179 = OpConstantComposite %v2uint %uint_16 %uint_19 +%uint_536870912 = OpConstant %uint 536870912 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 +%uint_16777216 = OpConstant %uint 16777216 + %uint_20 = OpConstant %uint 20 + %2275 = OpConstantComposite %v2uint %uint_20 %uint_24 + %uint_255 = OpConstant %uint 255 +%uint_3222273024 = OpConstant %uint 3222273024 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_ptr_Input_uint = OpTypePointer Input %uint + %1834 = OpConstantComposite %v2uint %uint_3 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %3271 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5522 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %1955 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %1611 = OpConstantComposite %v4uint %uint_255 %uint_255 %uint_255 %uint_255 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %2352 = OpConstantComposite %v4uint %uint_3222273024 %uint_3222273024 %uint_3222273024 %uint_3222273024 + %929 = OpConstantComposite %v4uint %uint_1023 %uint_1023 %uint_1023 %uint_1023 + %965 = OpConstantComposite %v4uint %uint_20 %uint_20 %uint_20 %uint_20 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %20073 = OpShiftRightLogical %uint %15627 %uint_10 + %7177 = OpBitwiseAnd %uint %20073 %uint_3 + %23023 = OpBitwiseAnd %uint %15627 %uint_4096 + %20495 = OpINotEqual %bool %23023 %uint_0 + %10307 = OpShiftRightLogical %uint %15627 %uint_13 + %24434 = OpBitwiseAnd %uint %10307 %uint_2047 + %18836 = OpShiftRightLogical %uint %15627 %uint_24 + %9130 = OpBitwiseAnd %uint %18836 %uint_15 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9633 = OpShiftRightLogical %v2uint %8871 %2179 + %23601 = OpBitwiseAnd %v2uint %9633 %1954 + %24030 = OpBitwiseAnd %uint %15627 %uint_536870912 + %12295 = OpINotEqual %bool %24030 %uint_0 + OpSelectionMerge %14676 None + OpBranchConditional %12295 %16739 %21992 + %21992 = OpLabel + OpBranch %14676 + %16739 = OpLabel + %15278 = OpShiftRightLogical %v2uint %23601 %1828 + OpBranch %14676 + %14676 = OpLabel + %19124 = OpPhi %v2uint %15278 %16739 %1807 %21992 + %7038 = OpShiftRightLogical %v2uint %8871 %1855 + %11769 = OpBitwiseAnd %v2uint %7038 %1955 + %16207 = OpShiftLeftLogical %v2uint %11769 %1870 + %23019 = OpIMul %v2uint %16207 %23601 + %13123 = OpShiftRightLogical %uint %20824 %uint_5 + %14785 = OpBitwiseAnd %uint %13123 %uint_2047 + %8858 = OpCompositeExtract %uint %23601 0 + %22993 = OpIMul %uint %14785 %8858 + %20036 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %18628 = OpLoad %uint %20036 + %22701 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %20919 = OpLoad %uint %22701 + %19164 = OpBitwiseAnd %uint %18628 %uint_7 + %21999 = OpBitwiseAnd %uint %18628 %uint_8 + %20496 = OpINotEqual %bool %21999 %uint_0 + %10402 = OpShiftRightLogical %uint %18628 %uint_4 + %23037 = OpBitwiseAnd %uint %10402 %uint_7 + %23118 = OpBitwiseAnd %uint %18628 %uint_16777216 + %19573 = OpINotEqual %bool %23118 %uint_0 + %8003 = OpBitwiseAnd %uint %20919 %uint_1023 + %15783 = OpShiftLeftLogical %uint %8003 %uint_5 + %22591 = OpShiftRightLogical %uint %20919 %uint_10 + %19390 = OpBitwiseAnd %uint %22591 %uint_1023 + %25203 = OpShiftLeftLogical %uint %19390 %uint_5 + %10422 = OpCompositeConstruct %v2uint %20919 %20919 + %10385 = OpShiftRightLogical %v2uint %10422 %2275 + %23379 = OpBitwiseAnd %v2uint %10385 %2122 + %16208 = OpShiftLeftLogical %v2uint %23379 %1870 + %23020 = OpIMul %v2uint %16208 %23601 + %12819 = OpShiftRightLogical %uint %20919 %uint_28 + %16204 = OpBitwiseAnd %uint %12819 %uint_7 + %20803 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0 + %8913 = OpLoad %uint %20803 + %7405 = OpUGreaterThanEqual %bool %8913 %22993 + OpSelectionMerge %17447 DontFlatten + OpBranchConditional %7405 %21993 %17447 + %21993 = OpLabel + OpBranch %19578 + %17447 = OpLabel + %14637 = OpLoad %v3uint %gl_GlobalInvocationID + %18505 = OpVectorShuffle %v2uint %14637 %14637 0 1 + %9840 = OpShiftLeftLogical %v2uint %18505 %1834 + %6697 = OpCompositeExtract %uint %9840 0 + %18425 = OpCompositeExtract %uint %9840 1 + %14186 = OpCompositeExtract %uint %19124 1 + %24446 = OpExtInst %uint %1 UMax %18425 %14186 + %20975 = OpCompositeConstruct %v2uint %6697 %24446 + %21036 = OpIAdd %v2uint %20975 %23019 + %16075 = OpULessThanEqual %bool %16204 %uint_3 + OpSelectionMerge %23776 None + OpBranchConditional %16075 %10990 %15087 + %15087 = OpLabel + %13566 = OpIEqual %bool %16204 %uint_5 + %8438 = OpSelect %uint %13566 %uint_2 %uint_0 + OpBranch %23776 + %10990 = OpLabel + OpBranch %23776 + %23776 = OpLabel + %19300 = OpPhi %uint %16204 %10990 %8438 %15087 + %16830 = OpCompositeConstruct %v2uint %7177 %7177 + %11801 = OpUGreaterThanEqual %v2bool %16830 %1837 + %19381 = OpSelect %v2uint %11801 %1828 %1807 + %10986 = OpShiftLeftLogical %v2uint %21036 %19381 + %24669 = OpCompositeConstruct %v2uint %19300 %19300 + %9093 = OpShiftRightLogical %v2uint %24669 %1816 + %16072 = OpBitwiseAnd %v2uint %9093 %1828 + %19132 = OpIAdd %v2uint %10986 %16072 + %11447 = OpIMul %v2uint %2719 %23601 + %7983 = OpUDiv %v2uint %19132 %11447 + %9129 = OpCompositeExtract %uint %7983 1 + %11046 = OpIMul %uint %9129 %20561 + %24665 = OpCompositeExtract %uint %7983 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %24434 %21536 + %6459 = OpIMul %v2uint %7983 %11447 + %14279 = OpISub %v2uint %19132 %6459 + OpSelectionMerge %18756 None + OpBranchConditional %20495 %11888 %18756 + %11888 = OpLabel + %16985 = OpCompositeExtract %uint %11447 0 + %13307 = OpShiftRightLogical %uint %16985 %uint_1 + %22207 = OpCompositeExtract %uint %14279 0 + %15197 = OpBitcast %int %22207 + %15736 = OpUGreaterThanEqual %bool %22207 %13307 + OpSelectionMerge %22850 None + OpBranchConditional %15736 %23061 %24565 + %24565 = OpLabel + %20693 = OpBitcast %int %13307 + OpBranch %22850 + %23061 = OpLabel + %18885 = OpBitcast %int %13307 + %17199 = OpSNegate %int %18885 + OpBranch %22850 + %22850 = OpLabel + %10046 = OpPhi %int %17199 %23061 %20693 %24565 + %11983 = OpIAdd %int %15197 %10046 + %17709 = OpBitcast %uint %11983 + %21574 = OpCompositeInsert %v2uint %17709 %14279 0 + OpBranch %18756 + %18756 = OpLabel + %17360 = OpPhi %v2uint %14279 %23776 %21574 %22850 + %24023 = OpCompositeExtract %uint %11447 0 + %22303 = OpCompositeExtract %uint %11447 1 + %13170 = OpIMul %uint %24023 %22303 + %15520 = OpIMul %uint %8742 %13170 + %16084 = OpCompositeExtract %uint %17360 1 + %15890 = OpIMul %uint %16084 %24023 + %24666 = OpCompositeExtract %uint %17360 0 + %21537 = OpIAdd %uint %15890 %24666 + %8875 = OpIAdd %uint %15520 %21537 + %23312 = OpIMul %uint %13170 %uint_2048 + %19795 = OpUMod %uint %8875 %23312 + %21806 = OpShiftRightLogical %uint %19795 %uint_2 + %17174 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %21806 + %12609 = OpLoad %v4uint %17174 + %11687 = OpIAdd %uint %21806 %uint_1 + %7197 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %11687 + %19842 = OpLoad %v4uint %7197 + %21106 = OpIEqual %bool %6697 %uint_0 + OpSelectionMerge %13276 None + OpBranchConditional %21106 %11451 %13276 + %11451 = OpLabel + %24156 = OpCompositeExtract %uint %19124 0 + %22470 = OpINotEqual %bool %24156 %uint_0 + OpBranch %13276 + %13276 = OpLabel + %10924 = OpPhi %bool %21106 %18756 %22470 %11451 + OpSelectionMerge %21910 DontFlatten + OpBranchConditional %10924 %11508 %21910 + %11508 = OpLabel + %23599 = OpCompositeExtract %uint %19124 0 + %17346 = OpUGreaterThanEqual %bool %23599 %uint_2 + OpSelectionMerge %18758 None + OpBranchConditional %17346 %15877 %18758 + %15877 = OpLabel + %24532 = OpUGreaterThanEqual %bool %23599 %uint_3 + OpSelectionMerge %18757 None + OpBranchConditional %24532 %9760 %18757 + %9760 = OpLabel + %20482 = OpCompositeExtract %uint %12609 3 + %14335 = OpCompositeInsert %v4uint %20482 %12609 2 + OpBranch %18757 + %18757 = OpLabel + %17379 = OpPhi %v4uint %12609 %15877 %14335 %9760 + %7002 = OpCompositeExtract %uint %17379 2 + %15144 = OpCompositeInsert %v4uint %7002 %17379 1 + OpBranch %18758 + %18758 = OpLabel + %17380 = OpPhi %v4uint %12609 %11508 %15144 %18757 + %7003 = OpCompositeExtract %uint %17380 1 + %15145 = OpCompositeInsert %v4uint %7003 %17380 0 + OpBranch %21910 + %21910 = OpLabel + %10925 = OpPhi %v4uint %12609 %13276 %15145 %18758 + OpSelectionMerge %21263 DontFlatten + OpBranchConditional %19573 %22395 %21263 + %22395 = OpLabel + OpSelectionMerge %14836 None + OpSwitch %9130 %14836 0 %21920 1 %21920 2 %10391 3 %10391 10 %10391 12 %10391 + %10391 = OpLabel + %15273 = OpBitwiseAnd %v4uint %10925 %2352 + %23564 = OpBitwiseAnd %v4uint %10925 %929 + %24837 = OpShiftLeftLogical %v4uint %23564 %965 + %18005 = OpBitwiseOr %v4uint %15273 %24837 + %23170 = OpShiftRightLogical %v4uint %10925 %965 + %6442 = OpBitwiseAnd %v4uint %23170 %929 + %15589 = OpBitwiseOr %v4uint %18005 %6442 + %19519 = OpBitwiseAnd %v4uint %19842 %2352 + %17946 = OpBitwiseAnd %v4uint %19842 %929 + %24838 = OpShiftLeftLogical %v4uint %17946 %965 + %18006 = OpBitwiseOr %v4uint %19519 %24838 + %23171 = OpShiftRightLogical %v4uint %19842 %965 + %7392 = OpBitwiseAnd %v4uint %23171 %929 + %7870 = OpBitwiseOr %v4uint %18006 %7392 + OpBranch %14836 + %21920 = OpLabel + %20117 = OpBitwiseAnd %v4uint %10925 %1838 + %23565 = OpBitwiseAnd %v4uint %10925 %1611 + %24839 = OpShiftLeftLogical %v4uint %23565 %749 + %18007 = OpBitwiseOr %v4uint %20117 %24839 + %23172 = OpShiftRightLogical %v4uint %10925 %749 + %6443 = OpBitwiseAnd %v4uint %23172 %1611 + %15590 = OpBitwiseOr %v4uint %18007 %6443 + %19520 = OpBitwiseAnd %v4uint %19842 %1838 + %17947 = OpBitwiseAnd %v4uint %19842 %1611 + %24840 = OpShiftLeftLogical %v4uint %17947 %749 + %18008 = OpBitwiseOr %v4uint %19520 %24840 + %23173 = OpShiftRightLogical %v4uint %19842 %749 + %7393 = OpBitwiseAnd %v4uint %23173 %1611 + %7871 = OpBitwiseOr %v4uint %18008 %7393 + OpBranch %14836 + %14836 = OpLabel + %11251 = OpPhi %v4uint %19842 %22395 %7871 %21920 %7870 %10391 + %13709 = OpPhi %v4uint %10925 %22395 %15590 %21920 %15589 %10391 + OpBranch %21263 + %21263 = OpLabel + %8952 = OpPhi %v4uint %19842 %21910 %11251 %14836 + %18855 = OpPhi %v4uint %10925 %21910 %13709 %14836 + %13755 = OpIAdd %v2uint %9840 %23020 + %13244 = OpCompositeExtract %uint %13755 0 + %9555 = OpCompositeExtract %uint %13755 1 + %11053 = OpShiftRightLogical %uint %13244 %uint_2 + %7832 = OpCompositeConstruct %v2uint %11053 %9555 + %24920 = OpUDiv %v2uint %7832 %23601 + %13932 = OpCompositeExtract %uint %24920 0 + %19770 = OpShiftLeftLogical %uint %13932 %uint_2 + %24251 = OpCompositeExtract %uint %24920 1 + %21452 = OpCompositeConstruct %v3uint %19770 %24251 %23037 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %20496 %22206 %10904 + %10904 = OpLabel + %7339 = OpVectorShuffle %v2uint %21452 %21452 0 1 + %22991 = OpBitcast %v2int %7339 + %6403 = OpCompositeExtract %int %22991 0 + %9469 = OpShiftRightArithmetic %int %6403 %int_5 + %10055 = OpCompositeExtract %int %22991 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %15783 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17303 = OpIAdd %int %10934 %17741 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15435 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18356 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18356 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12151 + %19165 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19165 %int_2 + %16708 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21587 %int_6 + %15436 = OpIAdd %int %16708 %21580 + %11782 = OpBitwiseAnd %int %16727 %int_63 + %14671 = OpIAdd %int %15436 %11782 + %22127 = OpBitcast %uint %14671 + OpBranch %21313 + %22206 = OpLabel + %6573 = OpBitcast %v3int %21452 + %17090 = OpCompositeExtract %int %6573 1 + %9470 = OpShiftRightArithmetic %int %17090 %int_4 + %10056 = OpCompositeExtract %int %6573 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %25203 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %15783 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %6573 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12601 = OpBitwiseAnd %int %17090 %int_6 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19166 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19166 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18357 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18357 %uint_8 + %16729 = OpIAdd %int %10332 %21582 + %19167 = OpBitwiseAnd %int %17090 %int_1 + %21583 = OpShiftLeftLogical %int %19167 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16730 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22128 = OpBitcast %uint %24314 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22128 %22206 %22127 %10904 + %16296 = OpIMul %v2uint %24920 %23601 + %16261 = OpISub %v2uint %7832 %16296 + %17551 = OpCompositeExtract %uint %23601 1 + %23632 = OpIMul %uint %8858 %17551 + %15521 = OpIMul %uint %9468 %23632 + %16085 = OpCompositeExtract %uint %16261 0 + %15891 = OpIMul %uint %16085 %17551 + %6886 = OpCompositeExtract %uint %16261 1 + %11045 = OpIAdd %uint %15891 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_2 + %23219 = OpBitwiseAnd %uint %13244 %uint_3 + %9559 = OpIAdd %uint %24733 %23219 + %17811 = OpShiftLeftLogical %uint %9559 %uint_2 + %8264 = OpIAdd %uint %15521 %17811 + %8213 = OpShiftRightLogical %uint %8264 %uint_4 + %12010 = OpIEqual %bool %19164 %uint_1 + %22390 = OpIEqual %bool %19164 %uint_2 + %22150 = OpLogicalOr %bool %12010 %22390 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %18855 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %18855 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %18855 %21313 %16376 %10583 + %19638 = OpIEqual %bool %19164 %uint_3 + %15139 = OpLogicalOr %bool %22390 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %6590 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %8213 + OpStore %6590 %19767 + %23542 = OpUGreaterThan %bool %8858 %uint_1 + OpSelectionMerge %19116 DontFlatten + OpBranchConditional %23542 %14554 %21994 + %21994 = OpLabel + OpBranch %19116 + %14554 = OpLabel + %13898 = OpShiftRightLogical %uint %6697 %uint_2 + %7937 = OpUDiv %uint %13898 %8858 + %16891 = OpIMul %uint %7937 %8858 + %12657 = OpISub %uint %13898 %16891 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %8858 + OpSelectionMerge %9304 None + OpBranchConditional %13375 %7387 %21995 + %21995 = OpLabel + OpBranch %9304 + %7387 = OpLabel + %15254 = OpIMul %uint %uint_32 %8858 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18759 = OpISub %uint %15254 %21519 + OpBranch %9304 + %9304 = OpLabel + %10540 = OpPhi %uint %18759 %7387 %uint_16 %21995 + OpBranch %19116 + %19116 = OpLabel + %10684 = OpPhi %uint %10540 %9304 %uint_32 %21994 + %18731 = OpIMul %uint %10684 %17551 + %19951 = OpShiftRightLogical %uint %18731 %uint_4 + %23410 = OpIAdd %uint %8213 %19951 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %8952 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %8952 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10926 = OpPhi %v4uint %8952 %19116 %16377 %10584 + OpSelectionMerge %11417 None + OpBranchConditional %15139 %11065 %11417 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10926 %749 + %15336 = OpShiftRightLogical %v4uint %10926 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %10926 %14874 %10729 %11065 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %23410 + OpStore %8053 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_fast_32bpp_1x2xmsaa_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006274, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00030047, 0x000003F9, 0x00000002, 0x00050048, + 0x000003F9, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x000003F9, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x000003F9, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x000003F9, + 0x00000003, 0x00000023, 0x0000000C, 0x00040047, 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, + 0x000007DC, 0x00000006, 0x00000010, 0x00030047, 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, + 0x00000000, 0x00000018, 0x00050048, 0x000007B4, 0x00000000, 0x00000023, 0x00000000, 0x00030047, + 0x00000CC7, 0x00000018, 0x00040047, 0x00000CC7, 0x00000021, 0x00000000, 0x00040047, 0x00000CC7, + 0x00000022, 0x00000000, 0x00040047, 0x000007DD, 0x00000006, 0x00000010, 0x00030047, 0x000007B5, + 0x00000003, 0x00040048, 0x000007B5, 0x00000000, 0x00000019, 0x00050048, 0x000007B5, 0x00000000, + 0x00000023, 0x00000000, 0x00030047, 0x00001592, 0x00000019, 0x00040047, 0x00001592, 0x00000021, + 0x00000000, 0x00040047, 0x00001592, 0x00000022, 0x00000001, 0x00040047, 0x00000AC7, 0x0000000B, + 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000B, + 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00020014, 0x00000009, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, + 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, + 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, + 0x0005002C, 0x00000011, 0x0000072D, 0x00000A10, 0x00000A0D, 0x00040017, 0x0000000F, 0x00000009, + 0x00000002, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0005002C, 0x00000011, 0x0000070F, + 0x00000A0A, 0x00000A0A, 0x0005002C, 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, 0x0005002C, + 0x00000011, 0x00000718, 0x00000A0D, 0x00000A0A, 0x0004002B, 0x0000000B, 0x00000AFA, 0x00000050, + 0x0005002C, 0x00000011, 0x00000A9F, 0x00000AFA, 0x00000A3A, 0x0004002B, 0x0000000B, 0x00000A84, + 0x00000800, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, + 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A20, + 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, + 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, + 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, + 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, + 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, + 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, + 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, + 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, + 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0006001E, 0x000003F9, 0x0000000B, + 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000676, 0x00000009, 0x000003F9, 0x0004003B, + 0x00000676, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, + 0x00000288, 0x00000009, 0x0000000B, 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, 0x0004002B, + 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000AFE, 0x00001000, 0x0004002B, + 0x0000000B, 0x00000A31, 0x0000000D, 0x0004002B, 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, + 0x0000000B, 0x00000A52, 0x00000018, 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, 0x0004002B, + 0x0000000B, 0x00000A5E, 0x0000001C, 0x0004002B, 0x0000000B, 0x00000A43, 0x00000013, 0x0005002C, + 0x00000011, 0x00000883, 0x00000A3A, 0x00000A43, 0x0004002B, 0x0000000B, 0x00000510, 0x20000000, + 0x0005002C, 0x00000011, 0x0000073F, 0x00000A0A, 0x00000A16, 0x0004002B, 0x0000000B, 0x00000926, + 0x01000000, 0x0004002B, 0x0000000B, 0x00000A46, 0x00000014, 0x0005002C, 0x00000011, 0x000008E3, + 0x00000A46, 0x00000A52, 0x0004002B, 0x0000000B, 0x00000144, 0x000000FF, 0x0004002B, 0x0000000B, + 0x00000B54, 0xC00FFC00, 0x00040020, 0x00000291, 0x00000001, 0x00000014, 0x0004003B, 0x00000291, + 0x00000F48, 0x00000001, 0x00040020, 0x00000289, 0x00000001, 0x0000000B, 0x0005002C, 0x00000011, + 0x0000072A, 0x00000A13, 0x00000A0A, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, + 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A32, 0x00000CC7, + 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, + 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A33, 0x00000002, 0x000007B5, 0x0004003B, + 0x00000A33, 0x00001592, 0x00000002, 0x0006002C, 0x00000014, 0x00000AC7, 0x00000A22, 0x00000A22, + 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0005002C, 0x00000011, + 0x000007A3, 0x00000A37, 0x00000A0D, 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, + 0x0005002C, 0x00000011, 0x0000084A, 0x00000A37, 0x00000A37, 0x0007002C, 0x00000017, 0x0000072E, + 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x0000064B, 0x00000144, + 0x00000144, 0x00000144, 0x00000144, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x0007002C, 0x00000017, 0x00000930, 0x00000B54, 0x00000B54, 0x00000B54, + 0x00000B54, 0x0007002C, 0x00000017, 0x000003A1, 0x00000A44, 0x00000A44, 0x00000A44, 0x00000A44, + 0x0007002C, 0x00000017, 0x000003C5, 0x00000A46, 0x00000A46, 0x00000A46, 0x00000A46, 0x0004002B, + 0x0000000B, 0x00000A25, 0x00000009, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, + 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, + 0x00000A22, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, + 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, + 0x00050041, 0x00000288, 0x000056E5, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003D0B, + 0x000056E5, 0x00050041, 0x00000288, 0x000058AC, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, + 0x00005158, 0x000058AC, 0x000500C7, 0x0000000B, 0x00005051, 0x00003D0B, 0x00000A44, 0x000500C2, + 0x0000000B, 0x00004E69, 0x00003D0B, 0x00000A28, 0x000500C7, 0x0000000B, 0x00001C09, 0x00004E69, + 0x00000A13, 0x000500C7, 0x0000000B, 0x000059EF, 0x00003D0B, 0x00000AFE, 0x000500AB, 0x00000009, + 0x0000500F, 0x000059EF, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00002843, 0x00003D0B, 0x00000A31, + 0x000500C7, 0x0000000B, 0x00005F72, 0x00002843, 0x00000A81, 0x000500C2, 0x0000000B, 0x00004994, + 0x00003D0B, 0x00000A52, 0x000500C7, 0x0000000B, 0x000023AA, 0x00004994, 0x00000A37, 0x00050050, + 0x00000011, 0x000022A7, 0x00005158, 0x00005158, 0x000500C2, 0x00000011, 0x000025A1, 0x000022A7, + 0x00000883, 0x000500C7, 0x00000011, 0x00005C31, 0x000025A1, 0x000007A2, 0x000500C7, 0x0000000B, + 0x00005DDE, 0x00003D0B, 0x00000510, 0x000500AB, 0x00000009, 0x00003007, 0x00005DDE, 0x00000A0A, + 0x000300F7, 0x00003954, 0x00000000, 0x000400FA, 0x00003007, 0x00004163, 0x000055E8, 0x000200F8, + 0x000055E8, 0x000200F9, 0x00003954, 0x000200F8, 0x00004163, 0x000500C2, 0x00000011, 0x00003BAE, + 0x00005C31, 0x00000724, 0x000200F9, 0x00003954, 0x000200F8, 0x00003954, 0x000700F5, 0x00000011, + 0x00004AB4, 0x00003BAE, 0x00004163, 0x0000070F, 0x000055E8, 0x000500C2, 0x00000011, 0x00001B7E, + 0x000022A7, 0x0000073F, 0x000500C7, 0x00000011, 0x00002DF9, 0x00001B7E, 0x000007A3, 0x000500C4, + 0x00000011, 0x00003F4F, 0x00002DF9, 0x0000074E, 0x00050084, 0x00000011, 0x000059EB, 0x00003F4F, + 0x00005C31, 0x000500C2, 0x0000000B, 0x00003343, 0x00005158, 0x00000A19, 0x000500C7, 0x0000000B, + 0x000039C1, 0x00003343, 0x00000A81, 0x00050051, 0x0000000B, 0x0000229A, 0x00005C31, 0x00000000, + 0x00050084, 0x0000000B, 0x000059D1, 0x000039C1, 0x0000229A, 0x00050041, 0x00000288, 0x00004E44, + 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x000048C4, 0x00004E44, 0x00050041, 0x00000288, + 0x000058AD, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x000051B7, 0x000058AD, 0x000500C7, + 0x0000000B, 0x00004ADC, 0x000048C4, 0x00000A1F, 0x000500C7, 0x0000000B, 0x000055EF, 0x000048C4, + 0x00000A22, 0x000500AB, 0x00000009, 0x00005010, 0x000055EF, 0x00000A0A, 0x000500C2, 0x0000000B, + 0x000028A2, 0x000048C4, 0x00000A16, 0x000500C7, 0x0000000B, 0x000059FD, 0x000028A2, 0x00000A1F, + 0x000500C7, 0x0000000B, 0x00005A4E, 0x000048C4, 0x00000926, 0x000500AB, 0x00000009, 0x00004C75, + 0x00005A4E, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00001F43, 0x000051B7, 0x00000A44, 0x000500C4, + 0x0000000B, 0x00003DA7, 0x00001F43, 0x00000A19, 0x000500C2, 0x0000000B, 0x0000583F, 0x000051B7, + 0x00000A28, 0x000500C7, 0x0000000B, 0x00004BBE, 0x0000583F, 0x00000A44, 0x000500C4, 0x0000000B, + 0x00006273, 0x00004BBE, 0x00000A19, 0x00050050, 0x00000011, 0x000028B6, 0x000051B7, 0x000051B7, + 0x000500C2, 0x00000011, 0x00002891, 0x000028B6, 0x000008E3, 0x000500C7, 0x00000011, 0x00005B53, + 0x00002891, 0x0000084A, 0x000500C4, 0x00000011, 0x00003F50, 0x00005B53, 0x0000074E, 0x00050084, + 0x00000011, 0x000059EC, 0x00003F50, 0x00005C31, 0x000500C2, 0x0000000B, 0x00003213, 0x000051B7, + 0x00000A5E, 0x000500C7, 0x0000000B, 0x00003F4C, 0x00003213, 0x00000A1F, 0x00050041, 0x00000289, + 0x00005143, 0x00000F48, 0x00000A0A, 0x0004003D, 0x0000000B, 0x000022D1, 0x00005143, 0x000500AE, + 0x00000009, 0x00001CED, 0x000022D1, 0x000059D1, 0x000300F7, 0x00004427, 0x00000002, 0x000400FA, + 0x00001CED, 0x000055E9, 0x00004427, 0x000200F8, 0x000055E9, 0x000200F9, 0x00004C7A, 0x000200F8, + 0x00004427, 0x0004003D, 0x00000014, 0x0000392D, 0x00000F48, 0x0007004F, 0x00000011, 0x00004849, + 0x0000392D, 0x0000392D, 0x00000000, 0x00000001, 0x000500C4, 0x00000011, 0x00002670, 0x00004849, + 0x0000072A, 0x00050051, 0x0000000B, 0x00001A29, 0x00002670, 0x00000000, 0x00050051, 0x0000000B, + 0x000047F9, 0x00002670, 0x00000001, 0x00050051, 0x0000000B, 0x0000376A, 0x00004AB4, 0x00000001, + 0x0007000C, 0x0000000B, 0x00005F7E, 0x00000001, 0x00000029, 0x000047F9, 0x0000376A, 0x00050050, + 0x00000011, 0x000051EF, 0x00001A29, 0x00005F7E, 0x00050080, 0x00000011, 0x0000522C, 0x000051EF, + 0x000059EB, 0x000500B2, 0x00000009, 0x00003ECB, 0x00003F4C, 0x00000A13, 0x000300F7, 0x00005CE0, + 0x00000000, 0x000400FA, 0x00003ECB, 0x00002AEE, 0x00003AEF, 0x000200F8, 0x00003AEF, 0x000500AA, + 0x00000009, 0x000034FE, 0x00003F4C, 0x00000A19, 0x000600A9, 0x0000000B, 0x000020F6, 0x000034FE, + 0x00000A10, 0x00000A0A, 0x000200F9, 0x00005CE0, 0x000200F8, 0x00002AEE, 0x000200F9, 0x00005CE0, + 0x000200F8, 0x00005CE0, 0x000700F5, 0x0000000B, 0x00004B64, 0x00003F4C, 0x00002AEE, 0x000020F6, + 0x00003AEF, 0x00050050, 0x00000011, 0x000041BE, 0x00001C09, 0x00001C09, 0x000500AE, 0x0000000F, + 0x00002E19, 0x000041BE, 0x0000072D, 0x000600A9, 0x00000011, 0x00004BB5, 0x00002E19, 0x00000724, + 0x0000070F, 0x000500C4, 0x00000011, 0x00002AEA, 0x0000522C, 0x00004BB5, 0x00050050, 0x00000011, + 0x0000605D, 0x00004B64, 0x00004B64, 0x000500C2, 0x00000011, 0x00002385, 0x0000605D, 0x00000718, + 0x000500C7, 0x00000011, 0x00003EC8, 0x00002385, 0x00000724, 0x00050080, 0x00000011, 0x00004ABC, + 0x00002AEA, 0x00003EC8, 0x00050084, 0x00000011, 0x00002CB7, 0x00000A9F, 0x00005C31, 0x00050086, + 0x00000011, 0x00001F2F, 0x00004ABC, 0x00002CB7, 0x00050051, 0x0000000B, 0x000023A9, 0x00001F2F, + 0x00000001, 0x00050084, 0x0000000B, 0x00002B26, 0x000023A9, 0x00005051, 0x00050051, 0x0000000B, + 0x00006059, 0x00001F2F, 0x00000000, 0x00050080, 0x0000000B, 0x00005420, 0x00002B26, 0x00006059, + 0x00050080, 0x0000000B, 0x00002226, 0x00005F72, 0x00005420, 0x00050084, 0x00000011, 0x0000193B, + 0x00001F2F, 0x00002CB7, 0x00050082, 0x00000011, 0x000037C7, 0x00004ABC, 0x0000193B, 0x000300F7, + 0x00004944, 0x00000000, 0x000400FA, 0x0000500F, 0x00002E70, 0x00004944, 0x000200F8, 0x00002E70, + 0x00050051, 0x0000000B, 0x00004259, 0x00002CB7, 0x00000000, 0x000500C2, 0x0000000B, 0x000033FB, + 0x00004259, 0x00000A0D, 0x00050051, 0x0000000B, 0x000056BF, 0x000037C7, 0x00000000, 0x0004007C, + 0x0000000C, 0x00003B5D, 0x000056BF, 0x000500AE, 0x00000009, 0x00003D78, 0x000056BF, 0x000033FB, + 0x000300F7, 0x00005942, 0x00000000, 0x000400FA, 0x00003D78, 0x00005A15, 0x00005FF5, 0x000200F8, + 0x00005FF5, 0x0004007C, 0x0000000C, 0x000050D5, 0x000033FB, 0x000200F9, 0x00005942, 0x000200F8, + 0x00005A15, 0x0004007C, 0x0000000C, 0x000049C5, 0x000033FB, 0x0004007E, 0x0000000C, 0x0000432F, + 0x000049C5, 0x000200F9, 0x00005942, 0x000200F8, 0x00005942, 0x000700F5, 0x0000000C, 0x0000273E, + 0x0000432F, 0x00005A15, 0x000050D5, 0x00005FF5, 0x00050080, 0x0000000C, 0x00002ECF, 0x00003B5D, + 0x0000273E, 0x0004007C, 0x0000000B, 0x0000452D, 0x00002ECF, 0x00060052, 0x00000011, 0x00005446, + 0x0000452D, 0x000037C7, 0x00000000, 0x000200F9, 0x00004944, 0x000200F8, 0x00004944, 0x000700F5, + 0x00000011, 0x000043D0, 0x000037C7, 0x00005CE0, 0x00005446, 0x00005942, 0x00050051, 0x0000000B, + 0x00005DD7, 0x00002CB7, 0x00000000, 0x00050051, 0x0000000B, 0x0000571F, 0x00002CB7, 0x00000001, + 0x00050084, 0x0000000B, 0x00003372, 0x00005DD7, 0x0000571F, 0x00050084, 0x0000000B, 0x00003CA0, + 0x00002226, 0x00003372, 0x00050051, 0x0000000B, 0x00003ED4, 0x000043D0, 0x00000001, 0x00050084, + 0x0000000B, 0x00003E12, 0x00003ED4, 0x00005DD7, 0x00050051, 0x0000000B, 0x0000605A, 0x000043D0, + 0x00000000, 0x00050080, 0x0000000B, 0x00005421, 0x00003E12, 0x0000605A, 0x00050080, 0x0000000B, + 0x000022AB, 0x00003CA0, 0x00005421, 0x00050084, 0x0000000B, 0x00005B10, 0x00003372, 0x00000A84, + 0x00050089, 0x0000000B, 0x00004D53, 0x000022AB, 0x00005B10, 0x000500C2, 0x0000000B, 0x0000552E, + 0x00004D53, 0x00000A10, 0x00060041, 0x00000294, 0x00004316, 0x00000CC7, 0x00000A0B, 0x0000552E, + 0x0004003D, 0x00000017, 0x00003141, 0x00004316, 0x00050080, 0x0000000B, 0x00002DA7, 0x0000552E, + 0x00000A0D, 0x00060041, 0x00000294, 0x00001C1D, 0x00000CC7, 0x00000A0B, 0x00002DA7, 0x0004003D, + 0x00000017, 0x00004D82, 0x00001C1D, 0x000500AA, 0x00000009, 0x00005272, 0x00001A29, 0x00000A0A, + 0x000300F7, 0x000033DC, 0x00000000, 0x000400FA, 0x00005272, 0x00002CBB, 0x000033DC, 0x000200F8, + 0x00002CBB, 0x00050051, 0x0000000B, 0x00005E5C, 0x00004AB4, 0x00000000, 0x000500AB, 0x00000009, + 0x000057C6, 0x00005E5C, 0x00000A0A, 0x000200F9, 0x000033DC, 0x000200F8, 0x000033DC, 0x000700F5, + 0x00000009, 0x00002AAC, 0x00005272, 0x00004944, 0x000057C6, 0x00002CBB, 0x000300F7, 0x00005596, + 0x00000002, 0x000400FA, 0x00002AAC, 0x00002CF4, 0x00005596, 0x000200F8, 0x00002CF4, 0x00050051, + 0x0000000B, 0x00005C2F, 0x00004AB4, 0x00000000, 0x000500AE, 0x00000009, 0x000043C2, 0x00005C2F, + 0x00000A10, 0x000300F7, 0x00004946, 0x00000000, 0x000400FA, 0x000043C2, 0x00003E05, 0x00004946, + 0x000200F8, 0x00003E05, 0x000500AE, 0x00000009, 0x00005FD4, 0x00005C2F, 0x00000A13, 0x000300F7, + 0x00004945, 0x00000000, 0x000400FA, 0x00005FD4, 0x00002620, 0x00004945, 0x000200F8, 0x00002620, + 0x00050051, 0x0000000B, 0x00005002, 0x00003141, 0x00000003, 0x00060052, 0x00000017, 0x000037FF, + 0x00005002, 0x00003141, 0x00000002, 0x000200F9, 0x00004945, 0x000200F8, 0x00004945, 0x000700F5, + 0x00000017, 0x000043E3, 0x00003141, 0x00003E05, 0x000037FF, 0x00002620, 0x00050051, 0x0000000B, + 0x00001B5A, 0x000043E3, 0x00000002, 0x00060052, 0x00000017, 0x00003B28, 0x00001B5A, 0x000043E3, + 0x00000001, 0x000200F9, 0x00004946, 0x000200F8, 0x00004946, 0x000700F5, 0x00000017, 0x000043E4, + 0x00003141, 0x00002CF4, 0x00003B28, 0x00004945, 0x00050051, 0x0000000B, 0x00001B5B, 0x000043E4, + 0x00000001, 0x00060052, 0x00000017, 0x00003B29, 0x00001B5B, 0x000043E4, 0x00000000, 0x000200F9, + 0x00005596, 0x000200F8, 0x00005596, 0x000700F5, 0x00000017, 0x00002AAD, 0x00003141, 0x000033DC, + 0x00003B29, 0x00004946, 0x000300F7, 0x0000530F, 0x00000002, 0x000400FA, 0x00004C75, 0x0000577B, + 0x0000530F, 0x000200F8, 0x0000577B, 0x000300F7, 0x000039F4, 0x00000000, 0x000F00FB, 0x000023AA, + 0x000039F4, 0x00000000, 0x000055A0, 0x00000001, 0x000055A0, 0x00000002, 0x00002897, 0x00000003, + 0x00002897, 0x0000000A, 0x00002897, 0x0000000C, 0x00002897, 0x000200F8, 0x00002897, 0x000500C7, + 0x00000017, 0x00003BA9, 0x00002AAD, 0x00000930, 0x000500C7, 0x00000017, 0x00005C0C, 0x00002AAD, + 0x000003A1, 0x000500C4, 0x00000017, 0x00006105, 0x00005C0C, 0x000003C5, 0x000500C5, 0x00000017, + 0x00004655, 0x00003BA9, 0x00006105, 0x000500C2, 0x00000017, 0x00005A82, 0x00002AAD, 0x000003C5, + 0x000500C7, 0x00000017, 0x0000192A, 0x00005A82, 0x000003A1, 0x000500C5, 0x00000017, 0x00003CE5, + 0x00004655, 0x0000192A, 0x000500C7, 0x00000017, 0x00004C3F, 0x00004D82, 0x00000930, 0x000500C7, + 0x00000017, 0x0000461A, 0x00004D82, 0x000003A1, 0x000500C4, 0x00000017, 0x00006106, 0x0000461A, + 0x000003C5, 0x000500C5, 0x00000017, 0x00004656, 0x00004C3F, 0x00006106, 0x000500C2, 0x00000017, + 0x00005A83, 0x00004D82, 0x000003C5, 0x000500C7, 0x00000017, 0x00001CE0, 0x00005A83, 0x000003A1, + 0x000500C5, 0x00000017, 0x00001EBE, 0x00004656, 0x00001CE0, 0x000200F9, 0x000039F4, 0x000200F8, + 0x000055A0, 0x000500C7, 0x00000017, 0x00004E95, 0x00002AAD, 0x0000072E, 0x000500C7, 0x00000017, + 0x00005C0D, 0x00002AAD, 0x0000064B, 0x000500C4, 0x00000017, 0x00006107, 0x00005C0D, 0x000002ED, + 0x000500C5, 0x00000017, 0x00004657, 0x00004E95, 0x00006107, 0x000500C2, 0x00000017, 0x00005A84, + 0x00002AAD, 0x000002ED, 0x000500C7, 0x00000017, 0x0000192B, 0x00005A84, 0x0000064B, 0x000500C5, + 0x00000017, 0x00003CE6, 0x00004657, 0x0000192B, 0x000500C7, 0x00000017, 0x00004C40, 0x00004D82, + 0x0000072E, 0x000500C7, 0x00000017, 0x0000461B, 0x00004D82, 0x0000064B, 0x000500C4, 0x00000017, + 0x00006108, 0x0000461B, 0x000002ED, 0x000500C5, 0x00000017, 0x00004658, 0x00004C40, 0x00006108, + 0x000500C2, 0x00000017, 0x00005A85, 0x00004D82, 0x000002ED, 0x000500C7, 0x00000017, 0x00001CE1, + 0x00005A85, 0x0000064B, 0x000500C5, 0x00000017, 0x00001EBF, 0x00004658, 0x00001CE1, 0x000200F9, + 0x000039F4, 0x000200F8, 0x000039F4, 0x000900F5, 0x00000017, 0x00002BF3, 0x00004D82, 0x0000577B, + 0x00001EBF, 0x000055A0, 0x00001EBE, 0x00002897, 0x000900F5, 0x00000017, 0x0000358D, 0x00002AAD, + 0x0000577B, 0x00003CE6, 0x000055A0, 0x00003CE5, 0x00002897, 0x000200F9, 0x0000530F, 0x000200F8, + 0x0000530F, 0x000700F5, 0x00000017, 0x000022F8, 0x00004D82, 0x00005596, 0x00002BF3, 0x000039F4, + 0x000700F5, 0x00000017, 0x000049A7, 0x00002AAD, 0x00005596, 0x0000358D, 0x000039F4, 0x00050080, + 0x00000011, 0x000035BB, 0x00002670, 0x000059EC, 0x00050051, 0x0000000B, 0x000033BC, 0x000035BB, + 0x00000000, 0x00050051, 0x0000000B, 0x00002553, 0x000035BB, 0x00000001, 0x000500C2, 0x0000000B, + 0x00002B2D, 0x000033BC, 0x00000A10, 0x00050050, 0x00000011, 0x00001E98, 0x00002B2D, 0x00002553, + 0x00050086, 0x00000011, 0x00006158, 0x00001E98, 0x00005C31, 0x00050051, 0x0000000B, 0x0000366C, + 0x00006158, 0x00000000, 0x000500C4, 0x0000000B, 0x00004D3A, 0x0000366C, 0x00000A10, 0x00050051, + 0x0000000B, 0x00005EBB, 0x00006158, 0x00000001, 0x00060050, 0x00000014, 0x000053CC, 0x00004D3A, + 0x00005EBB, 0x000059FD, 0x000300F7, 0x00005341, 0x00000002, 0x000400FA, 0x00005010, 0x000056BE, + 0x00002A98, 0x000200F8, 0x00002A98, 0x0007004F, 0x00000011, 0x00001CAB, 0x000053CC, 0x000053CC, + 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000059CF, 0x00001CAB, 0x00050051, 0x0000000C, + 0x00001903, 0x000059CF, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x00001903, 0x00000A1A, + 0x00050051, 0x0000000C, 0x00002747, 0x000059CF, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, + 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00003DA7, 0x00000A19, 0x0004007C, + 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AA, + 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, + 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002AB6, 0x00001903, 0x00000A20, 0x000500C7, + 0x0000000C, 0x00003138, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, + 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454D, 0x000500C4, 0x0000000C, + 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, + 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, + 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, + 0x0000000C, 0x00004D30, 0x00003C4B, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544A, 0x000047B4, 0x00000A17, 0x00050080, 0x0000000C, + 0x00004157, 0x00004D30, 0x0000544A, 0x000500C7, 0x0000000C, 0x00005022, 0x00004157, 0x0000040B, + 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, + 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, + 0x0000000C, 0x00004158, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADD, 0x00004157, + 0x00000388, 0x000500C4, 0x0000000C, 0x0000544B, 0x00004ADD, 0x00000A11, 0x00050080, 0x0000000C, + 0x00004144, 0x00004158, 0x0000544B, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, + 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, + 0x00001903, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, + 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544C, 0x00005453, + 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004144, 0x0000544C, 0x000500C7, 0x0000000C, + 0x00002E06, 0x00004157, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4C, 0x00002E06, + 0x0004007C, 0x0000000B, 0x0000566F, 0x0000394F, 0x000200F9, 0x00005341, 0x000200F8, 0x000056BE, + 0x0004007C, 0x00000016, 0x000019AD, 0x000053CC, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, + 0x00000001, 0x000500C3, 0x0000000C, 0x000024FE, 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, + 0x00002748, 0x000019AD, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A11, + 0x000500C2, 0x0000000B, 0x00005B4E, 0x00006273, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AB, + 0x00005B4E, 0x00050084, 0x0000000C, 0x00005321, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, + 0x00003B27, 0x000024FE, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00003DA7, 0x00000A19, + 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, + 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, + 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, + 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002CF6, + 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, + 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x000042C2, + 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, + 0x0000434B, 0x00004D38, 0x0000454E, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A22, + 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, + 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405D, 0x000500C7, + 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, + 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000034BD, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000544D, 0x00004ADE, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4D, + 0x00005A0C, 0x0000544D, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, + 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, + 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, + 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000544E, 0x000047B5, 0x00000A22, 0x00050080, 0x0000000C, 0x00004159, + 0x0000285C, 0x0000544E, 0x000500C7, 0x0000000C, 0x00004ADF, 0x000042C2, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x0000544F, 0x00004ADF, 0x00000A17, 0x00050080, 0x0000000C, 0x0000415A, 0x00004159, + 0x0000544F, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4D, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x0000415A, 0x00000A1D, + 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, + 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00005AB1, 0x00003C4D, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, + 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, + 0x00005AB2, 0x0000415A, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, + 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, + 0x0000415A, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, 0x0004007C, + 0x0000000B, 0x00005670, 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, + 0x0000000B, 0x000024FC, 0x00005670, 0x000056BE, 0x0000566F, 0x00002A98, 0x00050084, 0x00000011, + 0x00003FA8, 0x00006158, 0x00005C31, 0x00050082, 0x00000011, 0x00003F85, 0x00001E98, 0x00003FA8, + 0x00050051, 0x0000000B, 0x0000448F, 0x00005C31, 0x00000001, 0x00050084, 0x0000000B, 0x00005C50, + 0x0000229A, 0x0000448F, 0x00050084, 0x0000000B, 0x00003CA1, 0x000024FC, 0x00005C50, 0x00050051, + 0x0000000B, 0x00003ED5, 0x00003F85, 0x00000000, 0x00050084, 0x0000000B, 0x00003E13, 0x00003ED5, + 0x0000448F, 0x00050051, 0x0000000B, 0x00001AE6, 0x00003F85, 0x00000001, 0x00050080, 0x0000000B, + 0x00002B25, 0x00003E13, 0x00001AE6, 0x000500C4, 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A10, + 0x000500C7, 0x0000000B, 0x00005AB3, 0x000033BC, 0x00000A13, 0x00050080, 0x0000000B, 0x00002557, + 0x0000609D, 0x00005AB3, 0x000500C4, 0x0000000B, 0x00004593, 0x00002557, 0x00000A10, 0x00050080, + 0x0000000B, 0x00002048, 0x00003CA1, 0x00004593, 0x000500C2, 0x0000000B, 0x00002015, 0x00002048, + 0x00000A16, 0x000500AA, 0x00000009, 0x00002EEA, 0x00004ADC, 0x00000A0D, 0x000500AA, 0x00000009, + 0x00005776, 0x00004ADC, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x00002EEA, 0x00005776, + 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, + 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x000049A7, 0x000009CE, 0x000500C4, 0x00000017, + 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x000049A7, 0x0000072E, + 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, + 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, + 0x00005879, 0x000049A7, 0x00005341, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, + 0x00004ADC, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005776, 0x00004CB6, 0x000300F7, + 0x00002C98, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x00002C98, 0x000200F8, 0x00002B38, + 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, + 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, + 0x00002C98, 0x000200F8, 0x00002C98, 0x000700F5, 0x00000017, 0x00004D37, 0x00005879, 0x00003463, + 0x000029E8, 0x00002B38, 0x00060041, 0x00000294, 0x000019BE, 0x00001592, 0x00000A0B, 0x00002015, + 0x0003003E, 0x000019BE, 0x00004D37, 0x000500AC, 0x00000009, 0x00005BF6, 0x0000229A, 0x00000A0D, + 0x000300F7, 0x00004AAC, 0x00000002, 0x000400FA, 0x00005BF6, 0x000038DA, 0x000055EA, 0x000200F8, + 0x000055EA, 0x000200F9, 0x00004AAC, 0x000200F8, 0x000038DA, 0x000500C2, 0x0000000B, 0x0000364A, + 0x00001A29, 0x00000A10, 0x00050086, 0x0000000B, 0x00001F01, 0x0000364A, 0x0000229A, 0x00050084, + 0x0000000B, 0x000041FB, 0x00001F01, 0x0000229A, 0x00050082, 0x0000000B, 0x00003171, 0x0000364A, + 0x000041FB, 0x00050080, 0x0000000B, 0x00002527, 0x00003171, 0x00000A0D, 0x000500AA, 0x00000009, + 0x0000343F, 0x00002527, 0x0000229A, 0x000300F7, 0x00002458, 0x00000000, 0x000400FA, 0x0000343F, + 0x00001CDB, 0x000055EB, 0x000200F8, 0x000055EB, 0x000200F9, 0x00002458, 0x000200F8, 0x00001CDB, + 0x00050084, 0x0000000B, 0x00003B96, 0x00000A6A, 0x0000229A, 0x000500C4, 0x0000000B, 0x0000540F, + 0x00003171, 0x00000A16, 0x00050082, 0x0000000B, 0x00004947, 0x00003B96, 0x0000540F, 0x000200F9, + 0x00002458, 0x000200F8, 0x00002458, 0x000700F5, 0x0000000B, 0x0000292C, 0x00004947, 0x00001CDB, + 0x00000A3A, 0x000055EB, 0x000200F9, 0x00004AAC, 0x000200F8, 0x00004AAC, 0x000700F5, 0x0000000B, + 0x000029BC, 0x0000292C, 0x00002458, 0x00000A6A, 0x000055EA, 0x00050084, 0x0000000B, 0x0000492B, + 0x000029BC, 0x0000448F, 0x000500C2, 0x0000000B, 0x00004DEF, 0x0000492B, 0x00000A16, 0x00050080, + 0x0000000B, 0x00005B72, 0x00002015, 0x00004DEF, 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, + 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, + 0x000022F8, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, + 0x00000017, 0x000050AD, 0x000022F8, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, + 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, + 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAE, 0x000022F8, 0x00004AAC, 0x00003FF9, + 0x00002958, 0x000300F7, 0x00002C99, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, 0x00002C99, + 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAE, 0x000002ED, 0x000500C2, + 0x00000017, 0x00003BE8, 0x00002AAE, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, + 0x00003BE8, 0x000200F9, 0x00002C99, 0x000200F8, 0x00002C99, 0x000700F5, 0x00000017, 0x00004D39, + 0x00002AAE, 0x00003A1A, 0x000029E9, 0x00002B39, 0x00060041, 0x00000294, 0x00001F75, 0x00001592, + 0x00000A0B, 0x00005B72, 0x0003003E, 0x00001F75, 0x00004D39, 0x000200F9, 0x00004C7A, 0x000200F8, + 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_fast_32bpp_4xmsaa_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_fast_32bpp_4xmsaa_cs.h new file mode 100644 index 0000000..386965f --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_fast_32bpp_4xmsaa_cs.h @@ -0,0 +1,810 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25204 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_struct_1036 Block + OpMemberDecorate %_struct_1036 0 Offset 0 + OpMemberDecorate %_struct_1036 1 Offset 4 + OpMemberDecorate %_struct_1036 2 Offset 8 + OpMemberDecorate %_struct_1036 3 Offset 12 + OpMemberDecorate %_struct_1036 4 Offset 16 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %3271 NonWritable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5522 NonReadable + OpDecorate %5522 Binding 0 + OpDecorate %5522 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %bool = OpTypeBool + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_0 = OpConstant %uint 0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %uint_80 = OpConstant %uint 80 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_struct_1036 = OpTypeStruct %uint %uint %uint %uint %uint +%_ptr_PushConstant__struct_1036 = OpTypePointer PushConstant %_struct_1036 + %3305 = OpVariable %_ptr_PushConstant__struct_1036 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %uint_1023 = OpConstant %uint 1023 + %uint_10 = OpConstant %uint 10 + %uint_4096 = OpConstant %uint 4096 + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_24 = OpConstant %uint 24 + %uint_15 = OpConstant %uint 15 + %uint_28 = OpConstant %uint 28 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 +%uint_16777216 = OpConstant %uint 16777216 + %uint_20 = OpConstant %uint 20 + %2275 = OpConstantComposite %v2uint %uint_20 %uint_24 + %v3uint = OpTypeVector %uint 3 + %uint_255 = OpConstant %uint 255 +%uint_3222273024 = OpConstant %uint 3222273024 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_ptr_Input_uint = OpTypePointer Input %uint + %1834 = OpConstantComposite %v2uint %uint_3 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %3271 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5522 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %1611 = OpConstantComposite %v4uint %uint_255 %uint_255 %uint_255 %uint_255 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %2352 = OpConstantComposite %v4uint %uint_3222273024 %uint_3222273024 %uint_3222273024 %uint_3222273024 + %929 = OpConstantComposite %v4uint %uint_1023 %uint_1023 %uint_1023 %uint_1023 + %965 = OpConstantComposite %v4uint %uint_20 %uint_20 %uint_20 %uint_20 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %uint_40 = OpConstant %uint 40 + %int_40 = OpConstant %int 40 + %int_n40 = OpConstant %int -40 + %uint_1280 = OpConstant %uint 1280 +%uint_2621440 = OpConstant %uint 2621440 + %false = OpConstantFalse %bool + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %20919 = OpLoad %uint %22700 + %19164 = OpBitwiseAnd %uint %15627 %uint_1023 + %21999 = OpBitwiseAnd %uint %15627 %uint_4096 + %20495 = OpINotEqual %bool %21999 %uint_0 + %10307 = OpShiftRightLogical %uint %15627 %uint_13 + %24434 = OpBitwiseAnd %uint %10307 %uint_2047 + %18836 = OpShiftRightLogical %uint %15627 %uint_24 + %9130 = OpBitwiseAnd %uint %18836 %uint_15 + %8871 = OpCompositeConstruct %v2uint %20919 %20919 + %9576 = OpShiftRightLogical %v2uint %8871 %1855 + %23379 = OpBitwiseAnd %v2uint %9576 %1954 + %16207 = OpShiftLeftLogical %v2uint %23379 %1870 + %23019 = OpIMul %v2uint %16207 %1828 + %12819 = OpShiftRightLogical %uint %20919 %uint_5 + %16204 = OpBitwiseAnd %uint %12819 %uint_2047 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %24236 = OpLoad %uint %18732 + %22701 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %20920 = OpLoad %uint %22701 + %19165 = OpBitwiseAnd %uint %24236 %uint_7 + %22000 = OpBitwiseAnd %uint %24236 %uint_8 + %20496 = OpINotEqual %bool %22000 %uint_0 + %10402 = OpShiftRightLogical %uint %24236 %uint_4 + %23037 = OpBitwiseAnd %uint %10402 %uint_7 + %23118 = OpBitwiseAnd %uint %24236 %uint_16777216 + %19573 = OpINotEqual %bool %23118 %uint_0 + %8003 = OpBitwiseAnd %uint %20920 %uint_1023 + %15783 = OpShiftLeftLogical %uint %8003 %uint_5 + %22591 = OpShiftRightLogical %uint %20920 %uint_10 + %19390 = OpBitwiseAnd %uint %22591 %uint_1023 + %25203 = OpShiftLeftLogical %uint %19390 %uint_5 + %10422 = OpCompositeConstruct %v2uint %20920 %20920 + %10385 = OpShiftRightLogical %v2uint %10422 %2275 + %23380 = OpBitwiseAnd %v2uint %10385 %2122 + %16208 = OpShiftLeftLogical %v2uint %23380 %1870 + %23020 = OpIMul %v2uint %16208 %1828 + %12820 = OpShiftRightLogical %uint %20920 %uint_28 + %16205 = OpBitwiseAnd %uint %12820 %uint_7 + %18733 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_4 + %24237 = OpLoad %uint %18733 + %22225 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0 + %7085 = OpLoad %uint %22225 + %7405 = OpUGreaterThanEqual %bool %7085 %16204 + OpSelectionMerge %17447 DontFlatten + OpBranchConditional %7405 %21992 %17447 + %21992 = OpLabel + OpBranch %19578 + %17447 = OpLabel + %14637 = OpLoad %v3uint %gl_GlobalInvocationID + %18505 = OpVectorShuffle %v2uint %14637 %14637 0 1 + %9840 = OpShiftLeftLogical %v2uint %18505 %1834 + %24498 = OpCompositeExtract %uint %9840 0 + %7150 = OpCompositeExtract %uint %9840 1 + %24446 = OpExtInst %uint %1 UMax %7150 %uint_0 + %20975 = OpCompositeConstruct %v2uint %24498 %24446 + %21036 = OpIAdd %v2uint %20975 %23019 + %16075 = OpULessThanEqual %bool %16205 %uint_3 + OpSelectionMerge %6909 None + OpBranchConditional %16075 %10990 %15087 + %15087 = OpLabel + %13566 = OpIEqual %bool %16205 %uint_5 + %8438 = OpSelect %uint %13566 %uint_2 %uint_0 + OpBranch %6909 + %10990 = OpLabel + OpBranch %6909 + %6909 = OpLabel + %16517 = OpPhi %uint %16205 %10990 %8438 %15087 + %11201 = OpShiftLeftLogical %v2uint %21036 %1828 + %21693 = OpCompositeConstruct %v2uint %16517 %16517 + %9093 = OpShiftRightLogical %v2uint %21693 %1816 + %16110 = OpBitwiseAnd %v2uint %9093 %1828 + %17779 = OpIAdd %v2uint %11201 %16110 + %24270 = OpUDiv %v2uint %17779 %2719 + %12360 = OpCompositeExtract %uint %24270 1 + %11046 = OpIMul %uint %12360 %19164 + %24665 = OpCompositeExtract %uint %24270 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %24434 %21536 + %6459 = OpIMul %v2uint %24270 %2719 + %14279 = OpISub %v2uint %17779 %6459 + OpSelectionMerge %19725 None + OpBranchConditional %20495 %10558 %19725 + %10558 = OpLabel + %11791 = OpCompositeExtract %uint %14279 0 + %24981 = OpBitcast %int %11791 + %7841 = OpUGreaterThanEqual %bool %11791 %uint_40 + %22568 = OpSelect %int %7841 %int_n40 %int_40 + %11768 = OpIAdd %int %24981 %22568 + %8071 = OpBitcast %uint %11768 + %21574 = OpCompositeInsert %v2uint %8071 %14279 0 + OpBranch %19725 + %19725 = OpLabel + %8537 = OpPhi %v2uint %14279 %6909 %21574 %10558 + %6671 = OpIMul %uint %8742 %uint_1280 + %13892 = OpCompositeExtract %uint %8537 1 + %15890 = OpIMul %uint %13892 %uint_80 + %24666 = OpCompositeExtract %uint %8537 0 + %21631 = OpIAdd %uint %15890 %24666 + %9094 = OpIAdd %uint %6671 %21631 + %10191 = OpUMod %uint %9094 %uint_2621440 + %22847 = OpShiftRightLogical %uint %10191 %uint_2 + %8736 = OpINotEqual %bool %16205 %uint_2 + OpSelectionMerge %13276 None + OpBranchConditional %8736 %16434 %13276 + %16434 = OpLabel + %10585 = OpINotEqual %bool %16205 %uint_3 + OpBranch %13276 + %13276 = OpLabel + %10924 = OpPhi %bool %8736 %19725 %10585 %16434 + OpSelectionMerge %20259 DontFlatten + OpBranchConditional %10924 %9761 %12129 + %12129 = OpLabel + %18514 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %22847 + %13239 = OpLoad %v4uint %18514 + %20300 = OpCompositeExtract %uint %13239 1 + %15080 = OpCompositeExtract %uint %13239 3 + %19011 = OpIAdd %uint %22847 %uint_1 + %8722 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %19011 + %13014 = OpLoad %v4uint %8722 + %19388 = OpCompositeExtract %uint %13014 1 + %24581 = OpCompositeExtract %uint %13014 3 + %7418 = OpCompositeConstruct %v4uint %20300 %15080 %19388 %24581 + %6646 = OpIAdd %uint %22847 %uint_2 + %23758 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %6646 + %13015 = OpLoad %v4uint %23758 + %20301 = OpCompositeExtract %uint %13015 1 + %15081 = OpCompositeExtract %uint %13015 3 + %19012 = OpIAdd %uint %22847 %uint_3 + %8723 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %19012 + %13016 = OpLoad %v4uint %8723 + %19389 = OpCompositeExtract %uint %13016 1 + %7809 = OpCompositeExtract %uint %13016 3 + %9033 = OpCompositeConstruct %v4uint %20301 %15081 %19389 %7809 + OpBranch %20259 + %9761 = OpLabel + %20936 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %22847 + %13240 = OpLoad %v4uint %20936 + %20302 = OpCompositeExtract %uint %13240 0 + %15082 = OpCompositeExtract %uint %13240 2 + %19013 = OpIAdd %uint %22847 %uint_1 + %8724 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %19013 + %13017 = OpLoad %v4uint %8724 + %19391 = OpCompositeExtract %uint %13017 0 + %24582 = OpCompositeExtract %uint %13017 2 + %7419 = OpCompositeConstruct %v4uint %20302 %15082 %19391 %24582 + %6647 = OpIAdd %uint %22847 %uint_2 + %23759 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %6647 + %13018 = OpLoad %v4uint %23759 + %20303 = OpCompositeExtract %uint %13018 0 + %15083 = OpCompositeExtract %uint %13018 2 + %19014 = OpIAdd %uint %22847 %uint_3 + %8725 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %19014 + %13019 = OpLoad %v4uint %8725 + %19392 = OpCompositeExtract %uint %13019 0 + %7810 = OpCompositeExtract %uint %13019 2 + %9034 = OpCompositeConstruct %v4uint %20303 %15083 %19392 %7810 + OpBranch %20259 + %20259 = OpLabel + %9750 = OpPhi %v4uint %9034 %9761 %9033 %12129 + %13261 = OpPhi %v4uint %7419 %9761 %7418 %12129 + %19928 = OpIEqual %bool %24498 %uint_0 + %22246 = OpSelect %bool %19928 %false %19928 + OpSelectionMerge %21910 DontFlatten + OpBranchConditional %22246 %9760 %21910 + %9760 = OpLabel + %20482 = OpCompositeExtract %uint %13261 1 + %14335 = OpCompositeInsert %v4uint %20482 %13261 0 + OpBranch %21910 + %21910 = OpLabel + %10925 = OpPhi %v4uint %13261 %20259 %14335 %9760 + OpSelectionMerge %21263 DontFlatten + OpBranchConditional %19573 %22395 %21263 + %22395 = OpLabel + OpSelectionMerge %14836 None + OpSwitch %9130 %14836 0 %21920 1 %21920 2 %10391 3 %10391 10 %10391 12 %10391 + %10391 = OpLabel + %15273 = OpBitwiseAnd %v4uint %10925 %2352 + %23564 = OpBitwiseAnd %v4uint %10925 %929 + %24837 = OpShiftLeftLogical %v4uint %23564 %965 + %18005 = OpBitwiseOr %v4uint %15273 %24837 + %23170 = OpShiftRightLogical %v4uint %10925 %965 + %6442 = OpBitwiseAnd %v4uint %23170 %929 + %15589 = OpBitwiseOr %v4uint %18005 %6442 + %19519 = OpBitwiseAnd %v4uint %9750 %2352 + %17946 = OpBitwiseAnd %v4uint %9750 %929 + %24838 = OpShiftLeftLogical %v4uint %17946 %965 + %18006 = OpBitwiseOr %v4uint %19519 %24838 + %23171 = OpShiftRightLogical %v4uint %9750 %965 + %7392 = OpBitwiseAnd %v4uint %23171 %929 + %7870 = OpBitwiseOr %v4uint %18006 %7392 + OpBranch %14836 + %21920 = OpLabel + %20117 = OpBitwiseAnd %v4uint %10925 %1838 + %23565 = OpBitwiseAnd %v4uint %10925 %1611 + %24839 = OpShiftLeftLogical %v4uint %23565 %749 + %18007 = OpBitwiseOr %v4uint %20117 %24839 + %23172 = OpShiftRightLogical %v4uint %10925 %749 + %6443 = OpBitwiseAnd %v4uint %23172 %1611 + %15590 = OpBitwiseOr %v4uint %18007 %6443 + %19520 = OpBitwiseAnd %v4uint %9750 %1838 + %17947 = OpBitwiseAnd %v4uint %9750 %1611 + %24840 = OpShiftLeftLogical %v4uint %17947 %749 + %18008 = OpBitwiseOr %v4uint %19520 %24840 + %23173 = OpShiftRightLogical %v4uint %9750 %749 + %7393 = OpBitwiseAnd %v4uint %23173 %1611 + %7871 = OpBitwiseOr %v4uint %18008 %7393 + OpBranch %14836 + %14836 = OpLabel + %11251 = OpPhi %v4uint %9750 %22395 %7871 %21920 %7870 %10391 + %13709 = OpPhi %v4uint %10925 %22395 %15590 %21920 %15589 %10391 + OpBranch %21263 + %21263 = OpLabel + %8952 = OpPhi %v4uint %9750 %21910 %11251 %14836 + %22009 = OpPhi %v4uint %10925 %21910 %13709 %14836 + %7319 = OpIAdd %v2uint %9840 %23020 + OpSelectionMerge %21237 DontFlatten + OpBranchConditional %20496 %10574 %21373 + %21373 = OpLabel + %10608 = OpBitcast %v2int %7319 + %17090 = OpCompositeExtract %int %10608 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %10608 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %15783 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17303 = OpIAdd %int %10934 %17741 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15435 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18356 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18356 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12151 + %19166 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19166 %int_2 + %16708 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21587 %int_6 + %15436 = OpIAdd %int %16708 %21580 + %11782 = OpBitwiseAnd %int %16727 %int_63 + %14671 = OpIAdd %int %15436 %11782 + %22127 = OpBitcast %uint %14671 + OpBranch %21237 + %10574 = OpLabel + %19866 = OpCompositeExtract %uint %7319 0 + %11267 = OpCompositeExtract %uint %7319 1 + %8414 = OpCompositeConstruct %v3uint %19866 %11267 %23037 + %20125 = OpBitcast %v3int %8414 + %10438 = OpCompositeExtract %int %20125 1 + %9470 = OpShiftRightArithmetic %int %10438 %int_4 + %10056 = OpCompositeExtract %int %20125 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %25203 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %15783 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %20125 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12601 = OpBitwiseAnd %int %10438 %int_6 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8726 = OpShiftRightArithmetic %int %10438 %int_3 + %13731 = OpIAdd %int %8726 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19167 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19167 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18357 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18357 %uint_8 + %16729 = OpIAdd %int %10332 %21582 + %19168 = OpBitwiseAnd %int %10438 %int_1 + %21583 = OpShiftLeftLogical %int %19168 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16730 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22128 = OpBitcast %uint %24314 + OpBranch %21237 + %21237 = OpLabel + %11376 = OpPhi %uint %22128 %10574 %22127 %21373 + %20616 = OpIAdd %uint %11376 %24237 + %18675 = OpShiftRightLogical %uint %20616 %uint_4 + %12010 = OpIEqual %bool %19165 %uint_1 + %22390 = OpIEqual %bool %19165 %uint_2 + %22150 = OpLogicalOr %bool %12010 %22390 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %22009 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %22009 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %22009 %21237 %16376 %10583 + %19638 = OpIEqual %bool %19165 %uint_3 + %15139 = OpLogicalOr %bool %22390 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %24825 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %18675 + OpStore %24825 %19767 + %21685 = OpIAdd %uint %18675 %uint_2 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %8952 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %8952 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10926 = OpPhi %v4uint %8952 %11416 %16377 %10584 + OpSelectionMerge %11417 None + OpBranchConditional %15139 %11065 %11417 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10926 %749 + %15336 = OpShiftRightLogical %v4uint %10926 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %10926 %14874 %10729 %11065 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %21685 + OpStore %8053 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_fast_32bpp_4xmsaa_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006274, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00030047, 0x0000040C, 0x00000002, 0x00050048, + 0x0000040C, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x0000040C, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x0000040C, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x0000040C, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x0000040C, 0x00000004, 0x00000023, 0x00000010, + 0x00040047, 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, + 0x00030047, 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, + 0x000007B4, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000CC7, 0x00000018, 0x00040047, + 0x00000CC7, 0x00000021, 0x00000000, 0x00040047, 0x00000CC7, 0x00000022, 0x00000000, 0x00040047, + 0x000007DD, 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, + 0x00000000, 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, + 0x00001592, 0x00000019, 0x00040047, 0x00001592, 0x00000021, 0x00000000, 0x00040047, 0x00001592, + 0x00000022, 0x00000001, 0x00040047, 0x00000AC7, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, + 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, + 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00020014, + 0x00000009, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, + 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A0D, + 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x000008A6, + 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, + 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A3A, + 0x00000010, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0005002C, 0x00000011, 0x00000724, + 0x00000A0D, 0x00000A0D, 0x0005002C, 0x00000011, 0x00000718, 0x00000A0D, 0x00000A0A, 0x0004002B, + 0x0000000B, 0x00000AFA, 0x00000050, 0x0005002C, 0x00000011, 0x00000A9F, 0x00000AFA, 0x00000A3A, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, + 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, + 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, + 0x0007001E, 0x0000040C, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, + 0x00000688, 0x00000009, 0x0000040C, 0x0004003B, 0x00000688, 0x00000CE9, 0x00000009, 0x0004002B, + 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0004002B, + 0x0000000B, 0x00000A44, 0x000003FF, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, + 0x0000000B, 0x00000AFE, 0x00001000, 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, 0x0004002B, + 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A52, 0x00000018, 0x0004002B, + 0x0000000B, 0x00000A37, 0x0000000F, 0x0004002B, 0x0000000B, 0x00000A5E, 0x0000001C, 0x0005002C, + 0x00000011, 0x0000073F, 0x00000A0A, 0x00000A16, 0x0004002B, 0x0000000B, 0x00000926, 0x01000000, + 0x0004002B, 0x0000000B, 0x00000A46, 0x00000014, 0x0005002C, 0x00000011, 0x000008E3, 0x00000A46, + 0x00000A52, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x0004002B, 0x0000000B, 0x00000144, + 0x000000FF, 0x0004002B, 0x0000000B, 0x00000B54, 0xC00FFC00, 0x00040020, 0x00000291, 0x00000001, + 0x00000014, 0x0004003B, 0x00000291, 0x00000F48, 0x00000001, 0x00040020, 0x00000289, 0x00000001, + 0x0000000B, 0x0005002C, 0x00000011, 0x0000072A, 0x00000A13, 0x00000A0A, 0x0003001D, 0x000007DC, + 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, + 0x0004003B, 0x00000A32, 0x00000CC7, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, + 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A33, + 0x00000002, 0x000007B5, 0x0004003B, 0x00000A33, 0x00001592, 0x00000002, 0x0006002C, 0x00000014, + 0x00000AC7, 0x00000A22, 0x00000A22, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A37, + 0x00000A0D, 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, 0x0005002C, 0x00000011, + 0x0000084A, 0x00000A37, 0x00000A37, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, + 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x0000064B, 0x00000144, 0x00000144, 0x00000144, + 0x00000144, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, + 0x0007002C, 0x00000017, 0x00000930, 0x00000B54, 0x00000B54, 0x00000B54, 0x00000B54, 0x0007002C, + 0x00000017, 0x000003A1, 0x00000A44, 0x00000A44, 0x00000A44, 0x00000A44, 0x0007002C, 0x00000017, + 0x000003C5, 0x00000A46, 0x00000A46, 0x00000A46, 0x00000A46, 0x0004002B, 0x0000000B, 0x00000A25, + 0x00000009, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, + 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0004002B, + 0x0000000B, 0x00000A82, 0x00000028, 0x0004002B, 0x0000000C, 0x00000A83, 0x00000028, 0x0004002B, + 0x0000000C, 0x00000993, 0xFFFFFFD8, 0x0004002B, 0x0000000B, 0x00000184, 0x00000500, 0x0004002B, + 0x0000000B, 0x0000086E, 0x00280000, 0x0003002A, 0x00000009, 0x00000787, 0x00050036, 0x00000008, + 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, + 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000056E5, + 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003D0B, 0x000056E5, 0x00050041, 0x00000288, + 0x000058AC, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x000051B7, 0x000058AC, 0x000500C7, + 0x0000000B, 0x00004ADC, 0x00003D0B, 0x00000A44, 0x000500C7, 0x0000000B, 0x000055EF, 0x00003D0B, + 0x00000AFE, 0x000500AB, 0x00000009, 0x0000500F, 0x000055EF, 0x00000A0A, 0x000500C2, 0x0000000B, + 0x00002843, 0x00003D0B, 0x00000A31, 0x000500C7, 0x0000000B, 0x00005F72, 0x00002843, 0x00000A81, + 0x000500C2, 0x0000000B, 0x00004994, 0x00003D0B, 0x00000A52, 0x000500C7, 0x0000000B, 0x000023AA, + 0x00004994, 0x00000A37, 0x00050050, 0x00000011, 0x000022A7, 0x000051B7, 0x000051B7, 0x000500C2, + 0x00000011, 0x00002568, 0x000022A7, 0x0000073F, 0x000500C7, 0x00000011, 0x00005B53, 0x00002568, + 0x000007A2, 0x000500C4, 0x00000011, 0x00003F4F, 0x00005B53, 0x0000074E, 0x00050084, 0x00000011, + 0x000059EB, 0x00003F4F, 0x00000724, 0x000500C2, 0x0000000B, 0x00003213, 0x000051B7, 0x00000A19, + 0x000500C7, 0x0000000B, 0x00003F4C, 0x00003213, 0x00000A81, 0x00050041, 0x00000288, 0x0000492C, + 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, + 0x000058AD, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x000051B8, 0x000058AD, 0x000500C7, + 0x0000000B, 0x00004ADD, 0x00005EAC, 0x00000A1F, 0x000500C7, 0x0000000B, 0x000055F0, 0x00005EAC, + 0x00000A22, 0x000500AB, 0x00000009, 0x00005010, 0x000055F0, 0x00000A0A, 0x000500C2, 0x0000000B, + 0x000028A2, 0x00005EAC, 0x00000A16, 0x000500C7, 0x0000000B, 0x000059FD, 0x000028A2, 0x00000A1F, + 0x000500C7, 0x0000000B, 0x00005A4E, 0x00005EAC, 0x00000926, 0x000500AB, 0x00000009, 0x00004C75, + 0x00005A4E, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00001F43, 0x000051B8, 0x00000A44, 0x000500C4, + 0x0000000B, 0x00003DA7, 0x00001F43, 0x00000A19, 0x000500C2, 0x0000000B, 0x0000583F, 0x000051B8, + 0x00000A28, 0x000500C7, 0x0000000B, 0x00004BBE, 0x0000583F, 0x00000A44, 0x000500C4, 0x0000000B, + 0x00006273, 0x00004BBE, 0x00000A19, 0x00050050, 0x00000011, 0x000028B6, 0x000051B8, 0x000051B8, + 0x000500C2, 0x00000011, 0x00002891, 0x000028B6, 0x000008E3, 0x000500C7, 0x00000011, 0x00005B54, + 0x00002891, 0x0000084A, 0x000500C4, 0x00000011, 0x00003F50, 0x00005B54, 0x0000074E, 0x00050084, + 0x00000011, 0x000059EC, 0x00003F50, 0x00000724, 0x000500C2, 0x0000000B, 0x00003214, 0x000051B8, + 0x00000A5E, 0x000500C7, 0x0000000B, 0x00003F4D, 0x00003214, 0x00000A1F, 0x00050041, 0x00000288, + 0x0000492D, 0x00000CE9, 0x00000A17, 0x0004003D, 0x0000000B, 0x00005EAD, 0x0000492D, 0x00050041, + 0x00000289, 0x000056D1, 0x00000F48, 0x00000A0A, 0x0004003D, 0x0000000B, 0x00001BAD, 0x000056D1, + 0x000500AE, 0x00000009, 0x00001CED, 0x00001BAD, 0x00003F4C, 0x000300F7, 0x00004427, 0x00000002, + 0x000400FA, 0x00001CED, 0x000055E8, 0x00004427, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, + 0x000200F8, 0x00004427, 0x0004003D, 0x00000014, 0x0000392D, 0x00000F48, 0x0007004F, 0x00000011, + 0x00004849, 0x0000392D, 0x0000392D, 0x00000000, 0x00000001, 0x000500C4, 0x00000011, 0x00002670, + 0x00004849, 0x0000072A, 0x00050051, 0x0000000B, 0x00005FB2, 0x00002670, 0x00000000, 0x00050051, + 0x0000000B, 0x00001BEE, 0x00002670, 0x00000001, 0x0007000C, 0x0000000B, 0x00005F7E, 0x00000001, + 0x00000029, 0x00001BEE, 0x00000A0A, 0x00050050, 0x00000011, 0x000051EF, 0x00005FB2, 0x00005F7E, + 0x00050080, 0x00000011, 0x0000522C, 0x000051EF, 0x000059EB, 0x000500B2, 0x00000009, 0x00003ECB, + 0x00003F4D, 0x00000A13, 0x000300F7, 0x00001AFD, 0x00000000, 0x000400FA, 0x00003ECB, 0x00002AEE, + 0x00003AEF, 0x000200F8, 0x00003AEF, 0x000500AA, 0x00000009, 0x000034FE, 0x00003F4D, 0x00000A19, + 0x000600A9, 0x0000000B, 0x000020F6, 0x000034FE, 0x00000A10, 0x00000A0A, 0x000200F9, 0x00001AFD, + 0x000200F8, 0x00002AEE, 0x000200F9, 0x00001AFD, 0x000200F8, 0x00001AFD, 0x000700F5, 0x0000000B, + 0x00004085, 0x00003F4D, 0x00002AEE, 0x000020F6, 0x00003AEF, 0x000500C4, 0x00000011, 0x00002BC1, + 0x0000522C, 0x00000724, 0x00050050, 0x00000011, 0x000054BD, 0x00004085, 0x00004085, 0x000500C2, + 0x00000011, 0x00002385, 0x000054BD, 0x00000718, 0x000500C7, 0x00000011, 0x00003EEE, 0x00002385, + 0x00000724, 0x00050080, 0x00000011, 0x00004573, 0x00002BC1, 0x00003EEE, 0x00050086, 0x00000011, + 0x00005ECE, 0x00004573, 0x00000A9F, 0x00050051, 0x0000000B, 0x00003048, 0x00005ECE, 0x00000001, + 0x00050084, 0x0000000B, 0x00002B26, 0x00003048, 0x00004ADC, 0x00050051, 0x0000000B, 0x00006059, + 0x00005ECE, 0x00000000, 0x00050080, 0x0000000B, 0x00005420, 0x00002B26, 0x00006059, 0x00050080, + 0x0000000B, 0x00002226, 0x00005F72, 0x00005420, 0x00050084, 0x00000011, 0x0000193B, 0x00005ECE, + 0x00000A9F, 0x00050082, 0x00000011, 0x000037C7, 0x00004573, 0x0000193B, 0x000300F7, 0x00004D0D, + 0x00000000, 0x000400FA, 0x0000500F, 0x0000293E, 0x00004D0D, 0x000200F8, 0x0000293E, 0x00050051, + 0x0000000B, 0x00002E0F, 0x000037C7, 0x00000000, 0x0004007C, 0x0000000C, 0x00006195, 0x00002E0F, + 0x000500AE, 0x00000009, 0x00001EA1, 0x00002E0F, 0x00000A82, 0x000600A9, 0x0000000C, 0x00005828, + 0x00001EA1, 0x00000993, 0x00000A83, 0x00050080, 0x0000000C, 0x00002DF8, 0x00006195, 0x00005828, + 0x0004007C, 0x0000000B, 0x00001F87, 0x00002DF8, 0x00060052, 0x00000011, 0x00005446, 0x00001F87, + 0x000037C7, 0x00000000, 0x000200F9, 0x00004D0D, 0x000200F8, 0x00004D0D, 0x000700F5, 0x00000011, + 0x00002159, 0x000037C7, 0x00001AFD, 0x00005446, 0x0000293E, 0x00050084, 0x0000000B, 0x00001A0F, + 0x00002226, 0x00000184, 0x00050051, 0x0000000B, 0x00003644, 0x00002159, 0x00000001, 0x00050084, + 0x0000000B, 0x00003E12, 0x00003644, 0x00000AFA, 0x00050051, 0x0000000B, 0x0000605A, 0x00002159, + 0x00000000, 0x00050080, 0x0000000B, 0x0000547F, 0x00003E12, 0x0000605A, 0x00050080, 0x0000000B, + 0x00002386, 0x00001A0F, 0x0000547F, 0x00050089, 0x0000000B, 0x000027CF, 0x00002386, 0x0000086E, + 0x000500C2, 0x0000000B, 0x0000593F, 0x000027CF, 0x00000A10, 0x000500AB, 0x00000009, 0x00002220, + 0x00003F4D, 0x00000A10, 0x000300F7, 0x000033DC, 0x00000000, 0x000400FA, 0x00002220, 0x00004032, + 0x000033DC, 0x000200F8, 0x00004032, 0x000500AB, 0x00000009, 0x00002959, 0x00003F4D, 0x00000A13, + 0x000200F9, 0x000033DC, 0x000200F8, 0x000033DC, 0x000700F5, 0x00000009, 0x00002AAC, 0x00002220, + 0x00004D0D, 0x00002959, 0x00004032, 0x000300F7, 0x00004F23, 0x00000002, 0x000400FA, 0x00002AAC, + 0x00002621, 0x00002F61, 0x000200F8, 0x00002F61, 0x00060041, 0x00000294, 0x00004852, 0x00000CC7, + 0x00000A0B, 0x0000593F, 0x0004003D, 0x00000017, 0x000033B7, 0x00004852, 0x00050051, 0x0000000B, + 0x00004F4C, 0x000033B7, 0x00000001, 0x00050051, 0x0000000B, 0x00003AE8, 0x000033B7, 0x00000003, + 0x00050080, 0x0000000B, 0x00004A43, 0x0000593F, 0x00000A0D, 0x00060041, 0x00000294, 0x00002212, + 0x00000CC7, 0x00000A0B, 0x00004A43, 0x0004003D, 0x00000017, 0x000032D6, 0x00002212, 0x00050051, + 0x0000000B, 0x00004BBC, 0x000032D6, 0x00000001, 0x00050051, 0x0000000B, 0x00006005, 0x000032D6, + 0x00000003, 0x00070050, 0x00000017, 0x00001CFA, 0x00004F4C, 0x00003AE8, 0x00004BBC, 0x00006005, + 0x00050080, 0x0000000B, 0x000019F6, 0x0000593F, 0x00000A10, 0x00060041, 0x00000294, 0x00005CCE, + 0x00000CC7, 0x00000A0B, 0x000019F6, 0x0004003D, 0x00000017, 0x000032D7, 0x00005CCE, 0x00050051, + 0x0000000B, 0x00004F4D, 0x000032D7, 0x00000001, 0x00050051, 0x0000000B, 0x00003AE9, 0x000032D7, + 0x00000003, 0x00050080, 0x0000000B, 0x00004A44, 0x0000593F, 0x00000A13, 0x00060041, 0x00000294, + 0x00002213, 0x00000CC7, 0x00000A0B, 0x00004A44, 0x0004003D, 0x00000017, 0x000032D8, 0x00002213, + 0x00050051, 0x0000000B, 0x00004BBD, 0x000032D8, 0x00000001, 0x00050051, 0x0000000B, 0x00001E81, + 0x000032D8, 0x00000003, 0x00070050, 0x00000017, 0x00002349, 0x00004F4D, 0x00003AE9, 0x00004BBD, + 0x00001E81, 0x000200F9, 0x00004F23, 0x000200F8, 0x00002621, 0x00060041, 0x00000294, 0x000051C8, + 0x00000CC7, 0x00000A0B, 0x0000593F, 0x0004003D, 0x00000017, 0x000033B8, 0x000051C8, 0x00050051, + 0x0000000B, 0x00004F4E, 0x000033B8, 0x00000000, 0x00050051, 0x0000000B, 0x00003AEA, 0x000033B8, + 0x00000002, 0x00050080, 0x0000000B, 0x00004A45, 0x0000593F, 0x00000A0D, 0x00060041, 0x00000294, + 0x00002214, 0x00000CC7, 0x00000A0B, 0x00004A45, 0x0004003D, 0x00000017, 0x000032D9, 0x00002214, + 0x00050051, 0x0000000B, 0x00004BBF, 0x000032D9, 0x00000000, 0x00050051, 0x0000000B, 0x00006006, + 0x000032D9, 0x00000002, 0x00070050, 0x00000017, 0x00001CFB, 0x00004F4E, 0x00003AEA, 0x00004BBF, + 0x00006006, 0x00050080, 0x0000000B, 0x000019F7, 0x0000593F, 0x00000A10, 0x00060041, 0x00000294, + 0x00005CCF, 0x00000CC7, 0x00000A0B, 0x000019F7, 0x0004003D, 0x00000017, 0x000032DA, 0x00005CCF, + 0x00050051, 0x0000000B, 0x00004F4F, 0x000032DA, 0x00000000, 0x00050051, 0x0000000B, 0x00003AEB, + 0x000032DA, 0x00000002, 0x00050080, 0x0000000B, 0x00004A46, 0x0000593F, 0x00000A13, 0x00060041, + 0x00000294, 0x00002215, 0x00000CC7, 0x00000A0B, 0x00004A46, 0x0004003D, 0x00000017, 0x000032DB, + 0x00002215, 0x00050051, 0x0000000B, 0x00004BC0, 0x000032DB, 0x00000000, 0x00050051, 0x0000000B, + 0x00001E82, 0x000032DB, 0x00000002, 0x00070050, 0x00000017, 0x0000234A, 0x00004F4F, 0x00003AEB, + 0x00004BC0, 0x00001E82, 0x000200F9, 0x00004F23, 0x000200F8, 0x00004F23, 0x000700F5, 0x00000017, + 0x00002616, 0x0000234A, 0x00002621, 0x00002349, 0x00002F61, 0x000700F5, 0x00000017, 0x000033CD, + 0x00001CFB, 0x00002621, 0x00001CFA, 0x00002F61, 0x000500AA, 0x00000009, 0x00004DD8, 0x00005FB2, + 0x00000A0A, 0x000600A9, 0x00000009, 0x000056E6, 0x00004DD8, 0x00000787, 0x00004DD8, 0x000300F7, + 0x00005596, 0x00000002, 0x000400FA, 0x000056E6, 0x00002620, 0x00005596, 0x000200F8, 0x00002620, + 0x00050051, 0x0000000B, 0x00005002, 0x000033CD, 0x00000001, 0x00060052, 0x00000017, 0x000037FF, + 0x00005002, 0x000033CD, 0x00000000, 0x000200F9, 0x00005596, 0x000200F8, 0x00005596, 0x000700F5, + 0x00000017, 0x00002AAD, 0x000033CD, 0x00004F23, 0x000037FF, 0x00002620, 0x000300F7, 0x0000530F, + 0x00000002, 0x000400FA, 0x00004C75, 0x0000577B, 0x0000530F, 0x000200F8, 0x0000577B, 0x000300F7, + 0x000039F4, 0x00000000, 0x000F00FB, 0x000023AA, 0x000039F4, 0x00000000, 0x000055A0, 0x00000001, + 0x000055A0, 0x00000002, 0x00002897, 0x00000003, 0x00002897, 0x0000000A, 0x00002897, 0x0000000C, + 0x00002897, 0x000200F8, 0x00002897, 0x000500C7, 0x00000017, 0x00003BA9, 0x00002AAD, 0x00000930, + 0x000500C7, 0x00000017, 0x00005C0C, 0x00002AAD, 0x000003A1, 0x000500C4, 0x00000017, 0x00006105, + 0x00005C0C, 0x000003C5, 0x000500C5, 0x00000017, 0x00004655, 0x00003BA9, 0x00006105, 0x000500C2, + 0x00000017, 0x00005A82, 0x00002AAD, 0x000003C5, 0x000500C7, 0x00000017, 0x0000192A, 0x00005A82, + 0x000003A1, 0x000500C5, 0x00000017, 0x00003CE5, 0x00004655, 0x0000192A, 0x000500C7, 0x00000017, + 0x00004C3F, 0x00002616, 0x00000930, 0x000500C7, 0x00000017, 0x0000461A, 0x00002616, 0x000003A1, + 0x000500C4, 0x00000017, 0x00006106, 0x0000461A, 0x000003C5, 0x000500C5, 0x00000017, 0x00004656, + 0x00004C3F, 0x00006106, 0x000500C2, 0x00000017, 0x00005A83, 0x00002616, 0x000003C5, 0x000500C7, + 0x00000017, 0x00001CE0, 0x00005A83, 0x000003A1, 0x000500C5, 0x00000017, 0x00001EBE, 0x00004656, + 0x00001CE0, 0x000200F9, 0x000039F4, 0x000200F8, 0x000055A0, 0x000500C7, 0x00000017, 0x00004E95, + 0x00002AAD, 0x0000072E, 0x000500C7, 0x00000017, 0x00005C0D, 0x00002AAD, 0x0000064B, 0x000500C4, + 0x00000017, 0x00006107, 0x00005C0D, 0x000002ED, 0x000500C5, 0x00000017, 0x00004657, 0x00004E95, + 0x00006107, 0x000500C2, 0x00000017, 0x00005A84, 0x00002AAD, 0x000002ED, 0x000500C7, 0x00000017, + 0x0000192B, 0x00005A84, 0x0000064B, 0x000500C5, 0x00000017, 0x00003CE6, 0x00004657, 0x0000192B, + 0x000500C7, 0x00000017, 0x00004C40, 0x00002616, 0x0000072E, 0x000500C7, 0x00000017, 0x0000461B, + 0x00002616, 0x0000064B, 0x000500C4, 0x00000017, 0x00006108, 0x0000461B, 0x000002ED, 0x000500C5, + 0x00000017, 0x00004658, 0x00004C40, 0x00006108, 0x000500C2, 0x00000017, 0x00005A85, 0x00002616, + 0x000002ED, 0x000500C7, 0x00000017, 0x00001CE1, 0x00005A85, 0x0000064B, 0x000500C5, 0x00000017, + 0x00001EBF, 0x00004658, 0x00001CE1, 0x000200F9, 0x000039F4, 0x000200F8, 0x000039F4, 0x000900F5, + 0x00000017, 0x00002BF3, 0x00002616, 0x0000577B, 0x00001EBF, 0x000055A0, 0x00001EBE, 0x00002897, + 0x000900F5, 0x00000017, 0x0000358D, 0x00002AAD, 0x0000577B, 0x00003CE6, 0x000055A0, 0x00003CE5, + 0x00002897, 0x000200F9, 0x0000530F, 0x000200F8, 0x0000530F, 0x000700F5, 0x00000017, 0x000022F8, + 0x00002616, 0x00005596, 0x00002BF3, 0x000039F4, 0x000700F5, 0x00000017, 0x000055F9, 0x00002AAD, + 0x00005596, 0x0000358D, 0x000039F4, 0x00050080, 0x00000011, 0x00001C97, 0x00002670, 0x000059EC, + 0x000300F7, 0x000052F5, 0x00000002, 0x000400FA, 0x00005010, 0x0000294E, 0x0000537D, 0x000200F8, + 0x0000537D, 0x0004007C, 0x00000012, 0x00002970, 0x00001C97, 0x00050051, 0x0000000C, 0x000042C2, + 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, + 0x0000000C, 0x00002747, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, + 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, + 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AA, 0x00050080, + 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, + 0x00000A25, 0x000500C7, 0x0000000C, 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003138, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454D, 0x000500C4, 0x0000000C, 0x000018E7, + 0x00004397, 0x00000A10, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, + 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00004A8E, + 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, + 0x00004D30, 0x00003C4B, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544A, 0x000047B4, 0x00000A17, 0x00050080, 0x0000000C, 0x00004157, + 0x00004D30, 0x0000544A, 0x000500C7, 0x0000000C, 0x00005022, 0x00004157, 0x0000040B, 0x000500C4, + 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, + 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, + 0x00004158, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADE, 0x00004157, 0x00000388, + 0x000500C4, 0x0000000C, 0x0000544B, 0x00004ADE, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, + 0x00004158, 0x0000544B, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, + 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, + 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544C, 0x00005453, 0x00000A1D, + 0x00050080, 0x0000000C, 0x00003C4C, 0x00004144, 0x0000544C, 0x000500C7, 0x0000000C, 0x00002E06, + 0x00004157, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4C, 0x00002E06, 0x0004007C, + 0x0000000B, 0x0000566F, 0x0000394F, 0x000200F9, 0x000052F5, 0x000200F8, 0x0000294E, 0x00050051, + 0x0000000B, 0x00004D9A, 0x00001C97, 0x00000000, 0x00050051, 0x0000000B, 0x00002C03, 0x00001C97, + 0x00000001, 0x00060050, 0x00000014, 0x000020DE, 0x00004D9A, 0x00002C03, 0x000059FD, 0x0004007C, + 0x00000016, 0x00004E9D, 0x000020DE, 0x00050051, 0x0000000C, 0x000028C6, 0x00004E9D, 0x00000001, + 0x000500C3, 0x0000000C, 0x000024FE, 0x000028C6, 0x00000A17, 0x00050051, 0x0000000C, 0x00002748, + 0x00004E9D, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A11, 0x000500C2, + 0x0000000B, 0x00005B4E, 0x00006273, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, + 0x00050084, 0x0000000C, 0x00005321, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003B27, + 0x000024FE, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00003DA7, 0x00000A19, 0x0004007C, + 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, + 0x00050051, 0x0000000C, 0x00006242, 0x00004E9D, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, + 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, + 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, + 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, + 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x000028C6, 0x00000A1D, + 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, + 0x00004D38, 0x0000454E, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A22, 0x000500C3, + 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002216, 0x000028C6, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002216, 0x0000405D, 0x000500C7, 0x0000000C, + 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, + 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADF, 0x000034BD, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544D, 0x00004ADF, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4D, 0x00005A0C, + 0x0000544D, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, + 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, + 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544E, 0x000047B5, 0x00000A22, 0x00050080, 0x0000000C, 0x00004159, 0x0000285C, + 0x0000544E, 0x000500C7, 0x0000000C, 0x00004AE0, 0x000028C6, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544F, 0x00004AE0, 0x00000A17, 0x00050080, 0x0000000C, 0x0000415A, 0x00004159, 0x0000544F, + 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4D, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, + 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x0000415A, 0x00000A1D, 0x000500C7, + 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, + 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005AB1, 0x00003C4D, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, + 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, + 0x0000415A, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, + 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x0000415A, + 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, + 0x00005670, 0x00005EFA, 0x000200F9, 0x000052F5, 0x000200F8, 0x000052F5, 0x000700F5, 0x0000000B, + 0x00002C70, 0x00005670, 0x0000294E, 0x0000566F, 0x0000537D, 0x00050080, 0x0000000B, 0x00005088, + 0x00002C70, 0x00005EAD, 0x000500C2, 0x0000000B, 0x000048F3, 0x00005088, 0x00000A16, 0x000500AA, + 0x00000009, 0x00002EEA, 0x00004ADD, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005776, 0x00004ADD, + 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x00002EEA, 0x00005776, 0x000300F7, 0x00003463, + 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, + 0x00000017, 0x0000475F, 0x000055F9, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x000055F9, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, + 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x000055F9, + 0x000052F5, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x00004ADD, 0x00000A13, + 0x000500A6, 0x00000009, 0x00003B23, 0x00005776, 0x00004CB6, 0x000300F7, 0x00002C98, 0x00000000, + 0x000400FA, 0x00003B23, 0x00002B38, 0x00002C98, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, + 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, + 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x00002C98, 0x000200F8, + 0x00002C98, 0x000700F5, 0x00000017, 0x00004D37, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, + 0x00060041, 0x00000294, 0x000060F9, 0x00001592, 0x00000A0B, 0x000048F3, 0x0003003E, 0x000060F9, + 0x00004D37, 0x00050080, 0x0000000B, 0x000054B5, 0x000048F3, 0x00000A10, 0x000300F7, 0x00003A1A, + 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, + 0x00000017, 0x00004760, 0x000022F8, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000022F8, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, + 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAE, 0x000022F8, + 0x00002C98, 0x00003FF9, 0x00002958, 0x000300F7, 0x00002C99, 0x00000000, 0x000400FA, 0x00003B23, + 0x00002B39, 0x00002C99, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAE, + 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAE, 0x000002ED, 0x000500C5, 0x00000017, + 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002C99, 0x000200F8, 0x00002C99, 0x000700F5, + 0x00000017, 0x00004D39, 0x00002AAE, 0x00003A1A, 0x000029E9, 0x00002B39, 0x00060041, 0x00000294, + 0x00001F75, 0x00001592, 0x00000A0B, 0x000054B5, 0x0003003E, 0x00001F75, 0x00004D39, 0x000200F9, + 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_fast_32bpp_4xmsaa_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_fast_32bpp_4xmsaa_scaled_cs.h new file mode 100644 index 0000000..c9a0031 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_fast_32bpp_4xmsaa_scaled_cs.h @@ -0,0 +1,969 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25204 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_struct_1017 Block + OpMemberDecorate %_struct_1017 0 Offset 0 + OpMemberDecorate %_struct_1017 1 Offset 4 + OpMemberDecorate %_struct_1017 2 Offset 8 + OpMemberDecorate %_struct_1017 3 Offset 12 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %3271 NonWritable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5522 NonReadable + OpDecorate %5522 Binding 0 + OpDecorate %5522 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %bool = OpTypeBool + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %v3uint = OpTypeVector %uint 3 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_0 = OpConstant %uint 0 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %uint_80 = OpConstant %uint 80 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %uint_2048 = OpConstant %uint 2048 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1017 = OpTypeStruct %uint %uint %uint %uint +%_ptr_PushConstant__struct_1017 = OpTypePointer PushConstant %_struct_1017 + %3305 = OpVariable %_ptr_PushConstant__struct_1017 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %uint_1023 = OpConstant %uint 1023 + %uint_10 = OpConstant %uint 10 + %uint_4096 = OpConstant %uint 4096 + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_24 = OpConstant %uint 24 + %uint_15 = OpConstant %uint 15 + %uint_28 = OpConstant %uint 28 + %uint_19 = OpConstant %uint 19 + %2179 = OpConstantComposite %v2uint %uint_16 %uint_19 +%uint_536870912 = OpConstant %uint 536870912 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 +%uint_16777216 = OpConstant %uint 16777216 + %uint_20 = OpConstant %uint 20 + %2275 = OpConstantComposite %v2uint %uint_20 %uint_24 + %uint_255 = OpConstant %uint 255 +%uint_3222273024 = OpConstant %uint 3222273024 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_ptr_Input_uint = OpTypePointer Input %uint + %1834 = OpConstantComposite %v2uint %uint_3 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %3271 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5522 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %1955 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %1611 = OpConstantComposite %v4uint %uint_255 %uint_255 %uint_255 %uint_255 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %2352 = OpConstantComposite %v4uint %uint_3222273024 %uint_3222273024 %uint_3222273024 %uint_3222273024 + %929 = OpConstantComposite %v4uint %uint_1023 %uint_1023 %uint_1023 %uint_1023 + %965 = OpConstantComposite %v4uint %uint_20 %uint_20 %uint_20 %uint_20 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %20919 = OpLoad %uint %22700 + %19164 = OpBitwiseAnd %uint %15627 %uint_1023 + %21999 = OpBitwiseAnd %uint %15627 %uint_4096 + %20495 = OpINotEqual %bool %21999 %uint_0 + %10307 = OpShiftRightLogical %uint %15627 %uint_13 + %24434 = OpBitwiseAnd %uint %10307 %uint_2047 + %18836 = OpShiftRightLogical %uint %15627 %uint_24 + %9130 = OpBitwiseAnd %uint %18836 %uint_15 + %8871 = OpCompositeConstruct %v2uint %20919 %20919 + %9633 = OpShiftRightLogical %v2uint %8871 %2179 + %23601 = OpBitwiseAnd %v2uint %9633 %1954 + %24030 = OpBitwiseAnd %uint %15627 %uint_536870912 + %12295 = OpINotEqual %bool %24030 %uint_0 + OpSelectionMerge %14676 None + OpBranchConditional %12295 %16739 %21992 + %21992 = OpLabel + OpBranch %14676 + %16739 = OpLabel + %15278 = OpShiftRightLogical %v2uint %23601 %1828 + OpBranch %14676 + %14676 = OpLabel + %19124 = OpPhi %v2uint %15278 %16739 %1807 %21992 + %7038 = OpShiftRightLogical %v2uint %8871 %1855 + %11769 = OpBitwiseAnd %v2uint %7038 %1955 + %16207 = OpShiftLeftLogical %v2uint %11769 %1870 + %23019 = OpIMul %v2uint %16207 %23601 + %13123 = OpShiftRightLogical %uint %20919 %uint_5 + %14785 = OpBitwiseAnd %uint %13123 %uint_2047 + %8858 = OpCompositeExtract %uint %23601 0 + %22993 = OpIMul %uint %14785 %8858 + %20036 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %18628 = OpLoad %uint %20036 + %22701 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %20920 = OpLoad %uint %22701 + %19165 = OpBitwiseAnd %uint %18628 %uint_7 + %22000 = OpBitwiseAnd %uint %18628 %uint_8 + %20496 = OpINotEqual %bool %22000 %uint_0 + %10402 = OpShiftRightLogical %uint %18628 %uint_4 + %23037 = OpBitwiseAnd %uint %10402 %uint_7 + %23118 = OpBitwiseAnd %uint %18628 %uint_16777216 + %19573 = OpINotEqual %bool %23118 %uint_0 + %8003 = OpBitwiseAnd %uint %20920 %uint_1023 + %15783 = OpShiftLeftLogical %uint %8003 %uint_5 + %22591 = OpShiftRightLogical %uint %20920 %uint_10 + %19390 = OpBitwiseAnd %uint %22591 %uint_1023 + %25203 = OpShiftLeftLogical %uint %19390 %uint_5 + %10422 = OpCompositeConstruct %v2uint %20920 %20920 + %10385 = OpShiftRightLogical %v2uint %10422 %2275 + %23379 = OpBitwiseAnd %v2uint %10385 %2122 + %16208 = OpShiftLeftLogical %v2uint %23379 %1870 + %23020 = OpIMul %v2uint %16208 %23601 + %12819 = OpShiftRightLogical %uint %20920 %uint_28 + %16204 = OpBitwiseAnd %uint %12819 %uint_7 + %20803 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0 + %8913 = OpLoad %uint %20803 + %7405 = OpUGreaterThanEqual %bool %8913 %22993 + OpSelectionMerge %17447 DontFlatten + OpBranchConditional %7405 %21993 %17447 + %21993 = OpLabel + OpBranch %19578 + %17447 = OpLabel + %14637 = OpLoad %v3uint %gl_GlobalInvocationID + %18505 = OpVectorShuffle %v2uint %14637 %14637 0 1 + %9840 = OpShiftLeftLogical %v2uint %18505 %1834 + %6697 = OpCompositeExtract %uint %9840 0 + %18425 = OpCompositeExtract %uint %9840 1 + %14186 = OpCompositeExtract %uint %19124 1 + %24446 = OpExtInst %uint %1 UMax %18425 %14186 + %20975 = OpCompositeConstruct %v2uint %6697 %24446 + %21036 = OpIAdd %v2uint %20975 %23019 + %16075 = OpULessThanEqual %bool %16204 %uint_3 + OpSelectionMerge %6909 None + OpBranchConditional %16075 %10990 %15087 + %15087 = OpLabel + %13566 = OpIEqual %bool %16204 %uint_5 + %8438 = OpSelect %uint %13566 %uint_2 %uint_0 + OpBranch %6909 + %10990 = OpLabel + OpBranch %6909 + %6909 = OpLabel + %16517 = OpPhi %uint %16204 %10990 %8438 %15087 + %11201 = OpShiftLeftLogical %v2uint %21036 %1828 + %21693 = OpCompositeConstruct %v2uint %16517 %16517 + %9093 = OpShiftRightLogical %v2uint %21693 %1816 + %16072 = OpBitwiseAnd %v2uint %9093 %1828 + %19132 = OpIAdd %v2uint %11201 %16072 + %11447 = OpIMul %v2uint %2719 %23601 + %7983 = OpUDiv %v2uint %19132 %11447 + %9129 = OpCompositeExtract %uint %7983 1 + %11046 = OpIMul %uint %9129 %19164 + %24665 = OpCompositeExtract %uint %7983 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %24434 %21536 + %6459 = OpIMul %v2uint %7983 %11447 + %14279 = OpISub %v2uint %19132 %6459 + OpSelectionMerge %18756 None + OpBranchConditional %20495 %11888 %18756 + %11888 = OpLabel + %16985 = OpCompositeExtract %uint %11447 0 + %13307 = OpShiftRightLogical %uint %16985 %uint_1 + %22207 = OpCompositeExtract %uint %14279 0 + %15197 = OpBitcast %int %22207 + %15736 = OpUGreaterThanEqual %bool %22207 %13307 + OpSelectionMerge %22850 None + OpBranchConditional %15736 %23061 %24565 + %24565 = OpLabel + %20693 = OpBitcast %int %13307 + OpBranch %22850 + %23061 = OpLabel + %18885 = OpBitcast %int %13307 + %17199 = OpSNegate %int %18885 + OpBranch %22850 + %22850 = OpLabel + %10046 = OpPhi %int %17199 %23061 %20693 %24565 + %11983 = OpIAdd %int %15197 %10046 + %17709 = OpBitcast %uint %11983 + %21574 = OpCompositeInsert %v2uint %17709 %14279 0 + OpBranch %18756 + %18756 = OpLabel + %17360 = OpPhi %v2uint %14279 %6909 %21574 %22850 + %24023 = OpCompositeExtract %uint %11447 0 + %22303 = OpCompositeExtract %uint %11447 1 + %13170 = OpIMul %uint %24023 %22303 + %15520 = OpIMul %uint %8742 %13170 + %16084 = OpCompositeExtract %uint %17360 1 + %15890 = OpIMul %uint %16084 %24023 + %24666 = OpCompositeExtract %uint %17360 0 + %21537 = OpIAdd %uint %15890 %24666 + %8875 = OpIAdd %uint %15520 %21537 + %23312 = OpIMul %uint %13170 %uint_2048 + %21809 = OpUMod %uint %8875 %23312 + %7002 = OpShiftRightLogical %uint %21809 %uint_2 + %8736 = OpINotEqual %bool %16204 %uint_2 + OpSelectionMerge %13276 None + OpBranchConditional %8736 %16434 %13276 + %16434 = OpLabel + %10585 = OpINotEqual %bool %16204 %uint_3 + OpBranch %13276 + %13276 = OpLabel + %10924 = OpPhi %bool %8736 %18756 %10585 %16434 + OpSelectionMerge %20259 DontFlatten + OpBranchConditional %10924 %9761 %12129 + %12129 = OpLabel + %18514 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %7002 + %13239 = OpLoad %v4uint %18514 + %20300 = OpCompositeExtract %uint %13239 1 + %15080 = OpCompositeExtract %uint %13239 3 + %19011 = OpIAdd %uint %7002 %uint_1 + %8722 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %19011 + %13014 = OpLoad %v4uint %8722 + %19388 = OpCompositeExtract %uint %13014 1 + %24581 = OpCompositeExtract %uint %13014 3 + %7418 = OpCompositeConstruct %v4uint %20300 %15080 %19388 %24581 + %6646 = OpIAdd %uint %7002 %uint_2 + %23758 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %6646 + %13015 = OpLoad %v4uint %23758 + %20301 = OpCompositeExtract %uint %13015 1 + %15081 = OpCompositeExtract %uint %13015 3 + %19012 = OpIAdd %uint %7002 %uint_3 + %8723 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %19012 + %13016 = OpLoad %v4uint %8723 + %19389 = OpCompositeExtract %uint %13016 1 + %7809 = OpCompositeExtract %uint %13016 3 + %9033 = OpCompositeConstruct %v4uint %20301 %15081 %19389 %7809 + OpBranch %20259 + %9761 = OpLabel + %20936 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %7002 + %13240 = OpLoad %v4uint %20936 + %20302 = OpCompositeExtract %uint %13240 0 + %15082 = OpCompositeExtract %uint %13240 2 + %19013 = OpIAdd %uint %7002 %uint_1 + %8724 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %19013 + %13017 = OpLoad %v4uint %8724 + %19391 = OpCompositeExtract %uint %13017 0 + %24582 = OpCompositeExtract %uint %13017 2 + %7419 = OpCompositeConstruct %v4uint %20302 %15082 %19391 %24582 + %6647 = OpIAdd %uint %7002 %uint_2 + %23759 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %6647 + %13018 = OpLoad %v4uint %23759 + %20303 = OpCompositeExtract %uint %13018 0 + %15083 = OpCompositeExtract %uint %13018 2 + %19014 = OpIAdd %uint %7002 %uint_3 + %8725 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %19014 + %13019 = OpLoad %v4uint %8725 + %19392 = OpCompositeExtract %uint %13019 0 + %7810 = OpCompositeExtract %uint %13019 2 + %9034 = OpCompositeConstruct %v4uint %20303 %15083 %19392 %7810 + OpBranch %20259 + %20259 = OpLabel + %9750 = OpPhi %v4uint %9034 %9761 %9033 %12129 + %14743 = OpPhi %v4uint %7419 %9761 %7418 %12129 + %6491 = OpIEqual %bool %6697 %uint_0 + OpSelectionMerge %13277 None + OpBranchConditional %6491 %11451 %13277 + %11451 = OpLabel + %24156 = OpCompositeExtract %uint %19124 0 + %22470 = OpINotEqual %bool %24156 %uint_0 + OpBranch %13277 + %13277 = OpLabel + %10925 = OpPhi %bool %6491 %20259 %22470 %11451 + OpSelectionMerge %21910 DontFlatten + OpBranchConditional %10925 %11508 %21910 + %11508 = OpLabel + %23599 = OpCompositeExtract %uint %19124 0 + %17346 = OpUGreaterThanEqual %bool %23599 %uint_2 + OpSelectionMerge %18758 None + OpBranchConditional %17346 %15877 %18758 + %15877 = OpLabel + %24532 = OpUGreaterThanEqual %bool %23599 %uint_3 + OpSelectionMerge %18757 None + OpBranchConditional %24532 %9760 %18757 + %9760 = OpLabel + %20482 = OpCompositeExtract %uint %14743 3 + %14335 = OpCompositeInsert %v4uint %20482 %14743 2 + OpBranch %18757 + %18757 = OpLabel + %17379 = OpPhi %v4uint %14743 %15877 %14335 %9760 + %7003 = OpCompositeExtract %uint %17379 2 + %15144 = OpCompositeInsert %v4uint %7003 %17379 1 + OpBranch %18758 + %18758 = OpLabel + %17380 = OpPhi %v4uint %14743 %11508 %15144 %18757 + %7004 = OpCompositeExtract %uint %17380 1 + %15145 = OpCompositeInsert %v4uint %7004 %17380 0 + OpBranch %21910 + %21910 = OpLabel + %10926 = OpPhi %v4uint %14743 %13277 %15145 %18758 + OpSelectionMerge %21263 DontFlatten + OpBranchConditional %19573 %22395 %21263 + %22395 = OpLabel + OpSelectionMerge %14836 None + OpSwitch %9130 %14836 0 %21920 1 %21920 2 %10391 3 %10391 10 %10391 12 %10391 + %10391 = OpLabel + %15273 = OpBitwiseAnd %v4uint %10926 %2352 + %23564 = OpBitwiseAnd %v4uint %10926 %929 + %24837 = OpShiftLeftLogical %v4uint %23564 %965 + %18005 = OpBitwiseOr %v4uint %15273 %24837 + %23170 = OpShiftRightLogical %v4uint %10926 %965 + %6442 = OpBitwiseAnd %v4uint %23170 %929 + %15589 = OpBitwiseOr %v4uint %18005 %6442 + %19519 = OpBitwiseAnd %v4uint %9750 %2352 + %17946 = OpBitwiseAnd %v4uint %9750 %929 + %24838 = OpShiftLeftLogical %v4uint %17946 %965 + %18006 = OpBitwiseOr %v4uint %19519 %24838 + %23171 = OpShiftRightLogical %v4uint %9750 %965 + %7392 = OpBitwiseAnd %v4uint %23171 %929 + %7870 = OpBitwiseOr %v4uint %18006 %7392 + OpBranch %14836 + %21920 = OpLabel + %20117 = OpBitwiseAnd %v4uint %10926 %1838 + %23565 = OpBitwiseAnd %v4uint %10926 %1611 + %24839 = OpShiftLeftLogical %v4uint %23565 %749 + %18007 = OpBitwiseOr %v4uint %20117 %24839 + %23172 = OpShiftRightLogical %v4uint %10926 %749 + %6443 = OpBitwiseAnd %v4uint %23172 %1611 + %15590 = OpBitwiseOr %v4uint %18007 %6443 + %19520 = OpBitwiseAnd %v4uint %9750 %1838 + %17947 = OpBitwiseAnd %v4uint %9750 %1611 + %24840 = OpShiftLeftLogical %v4uint %17947 %749 + %18008 = OpBitwiseOr %v4uint %19520 %24840 + %23173 = OpShiftRightLogical %v4uint %9750 %749 + %7393 = OpBitwiseAnd %v4uint %23173 %1611 + %7871 = OpBitwiseOr %v4uint %18008 %7393 + OpBranch %14836 + %14836 = OpLabel + %11251 = OpPhi %v4uint %9750 %22395 %7871 %21920 %7870 %10391 + %13709 = OpPhi %v4uint %10926 %22395 %15590 %21920 %15589 %10391 + OpBranch %21263 + %21263 = OpLabel + %8952 = OpPhi %v4uint %9750 %21910 %11251 %14836 + %18855 = OpPhi %v4uint %10926 %21910 %13709 %14836 + %13755 = OpIAdd %v2uint %9840 %23020 + %13244 = OpCompositeExtract %uint %13755 0 + %9555 = OpCompositeExtract %uint %13755 1 + %11053 = OpShiftRightLogical %uint %13244 %uint_2 + %7832 = OpCompositeConstruct %v2uint %11053 %9555 + %24920 = OpUDiv %v2uint %7832 %23601 + %13932 = OpCompositeExtract %uint %24920 0 + %19770 = OpShiftLeftLogical %uint %13932 %uint_2 + %24251 = OpCompositeExtract %uint %24920 1 + %21452 = OpCompositeConstruct %v3uint %19770 %24251 %23037 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %20496 %22206 %10904 + %10904 = OpLabel + %7339 = OpVectorShuffle %v2uint %21452 %21452 0 1 + %22991 = OpBitcast %v2int %7339 + %6403 = OpCompositeExtract %int %22991 0 + %9469 = OpShiftRightArithmetic %int %6403 %int_5 + %10055 = OpCompositeExtract %int %22991 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %15783 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17303 = OpIAdd %int %10934 %17741 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15435 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18356 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18356 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12151 + %19166 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19166 %int_2 + %16708 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21587 %int_6 + %15436 = OpIAdd %int %16708 %21580 + %11782 = OpBitwiseAnd %int %16727 %int_63 + %14671 = OpIAdd %int %15436 %11782 + %22127 = OpBitcast %uint %14671 + OpBranch %21313 + %22206 = OpLabel + %6573 = OpBitcast %v3int %21452 + %17090 = OpCompositeExtract %int %6573 1 + %9470 = OpShiftRightArithmetic %int %17090 %int_4 + %10056 = OpCompositeExtract %int %6573 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %25203 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %15783 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %6573 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12601 = OpBitwiseAnd %int %17090 %int_6 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8726 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8726 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19167 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19167 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18357 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18357 %uint_8 + %16729 = OpIAdd %int %10332 %21582 + %19168 = OpBitwiseAnd %int %17090 %int_1 + %21583 = OpShiftLeftLogical %int %19168 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16730 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22128 = OpBitcast %uint %24314 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22128 %22206 %22127 %10904 + %16296 = OpIMul %v2uint %24920 %23601 + %16261 = OpISub %v2uint %7832 %16296 + %17551 = OpCompositeExtract %uint %23601 1 + %23632 = OpIMul %uint %8858 %17551 + %15521 = OpIMul %uint %9468 %23632 + %16085 = OpCompositeExtract %uint %16261 0 + %15891 = OpIMul %uint %16085 %17551 + %6886 = OpCompositeExtract %uint %16261 1 + %11045 = OpIAdd %uint %15891 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_2 + %23219 = OpBitwiseAnd %uint %13244 %uint_3 + %9559 = OpIAdd %uint %24733 %23219 + %17811 = OpShiftLeftLogical %uint %9559 %uint_2 + %8264 = OpIAdd %uint %15521 %17811 + %8213 = OpShiftRightLogical %uint %8264 %uint_4 + %12010 = OpIEqual %bool %19165 %uint_1 + %22390 = OpIEqual %bool %19165 %uint_2 + %22150 = OpLogicalOr %bool %12010 %22390 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %18855 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %18855 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %18855 %21313 %16376 %10583 + %19638 = OpIEqual %bool %19165 %uint_3 + %15139 = OpLogicalOr %bool %22390 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %6590 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %8213 + OpStore %6590 %19767 + %23542 = OpUGreaterThan %bool %8858 %uint_1 + OpSelectionMerge %19116 DontFlatten + OpBranchConditional %23542 %14554 %21994 + %21994 = OpLabel + OpBranch %19116 + %14554 = OpLabel + %13898 = OpShiftRightLogical %uint %6697 %uint_2 + %7937 = OpUDiv %uint %13898 %8858 + %16891 = OpIMul %uint %7937 %8858 + %12657 = OpISub %uint %13898 %16891 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %8858 + OpSelectionMerge %9304 None + OpBranchConditional %13375 %7387 %21995 + %21995 = OpLabel + OpBranch %9304 + %7387 = OpLabel + %15254 = OpIMul %uint %uint_32 %8858 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18759 = OpISub %uint %15254 %21519 + OpBranch %9304 + %9304 = OpLabel + %10540 = OpPhi %uint %18759 %7387 %uint_16 %21995 + OpBranch %19116 + %19116 = OpLabel + %10684 = OpPhi %uint %10540 %9304 %uint_32 %21994 + %18731 = OpIMul %uint %10684 %17551 + %19951 = OpShiftRightLogical %uint %18731 %uint_4 + %23410 = OpIAdd %uint %8213 %19951 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %8952 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %8952 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10927 = OpPhi %v4uint %8952 %19116 %16377 %10584 + OpSelectionMerge %11417 None + OpBranchConditional %15139 %11065 %11417 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10927 %749 + %15336 = OpShiftRightLogical %v4uint %10927 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %10927 %14874 %10729 %11065 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %23410 + OpStore %8053 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_fast_32bpp_4xmsaa_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006274, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00030047, 0x000003F9, 0x00000002, 0x00050048, + 0x000003F9, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x000003F9, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x000003F9, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x000003F9, + 0x00000003, 0x00000023, 0x0000000C, 0x00040047, 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, + 0x000007DC, 0x00000006, 0x00000010, 0x00030047, 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, + 0x00000000, 0x00000018, 0x00050048, 0x000007B4, 0x00000000, 0x00000023, 0x00000000, 0x00030047, + 0x00000CC7, 0x00000018, 0x00040047, 0x00000CC7, 0x00000021, 0x00000000, 0x00040047, 0x00000CC7, + 0x00000022, 0x00000000, 0x00040047, 0x000007DD, 0x00000006, 0x00000010, 0x00030047, 0x000007B5, + 0x00000003, 0x00040048, 0x000007B5, 0x00000000, 0x00000019, 0x00050048, 0x000007B5, 0x00000000, + 0x00000023, 0x00000000, 0x00030047, 0x00001592, 0x00000019, 0x00040047, 0x00001592, 0x00000021, + 0x00000000, 0x00040047, 0x00001592, 0x00000022, 0x00000001, 0x00040047, 0x00000AC7, 0x0000000B, + 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000B, + 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00020014, 0x00000009, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, + 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, + 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0005002C, 0x00000011, 0x0000070F, 0x00000A0A, + 0x00000A0A, 0x0005002C, 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, 0x0005002C, 0x00000011, + 0x00000718, 0x00000A0D, 0x00000A0A, 0x0004002B, 0x0000000B, 0x00000AFA, 0x00000050, 0x0005002C, + 0x00000011, 0x00000A9F, 0x00000AFA, 0x00000A3A, 0x0004002B, 0x0000000B, 0x00000A84, 0x00000800, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, + 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, + 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, + 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0006001E, 0x000003F9, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000676, 0x00000009, 0x000003F9, 0x0004003B, 0x00000676, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, + 0x00000009, 0x0000000B, 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, 0x0004002B, 0x0000000B, + 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000AFE, 0x00001000, 0x0004002B, 0x0000000B, + 0x00000A31, 0x0000000D, 0x0004002B, 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, + 0x00000A52, 0x00000018, 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, 0x0004002B, 0x0000000B, + 0x00000A5E, 0x0000001C, 0x0004002B, 0x0000000B, 0x00000A43, 0x00000013, 0x0005002C, 0x00000011, + 0x00000883, 0x00000A3A, 0x00000A43, 0x0004002B, 0x0000000B, 0x00000510, 0x20000000, 0x0005002C, + 0x00000011, 0x0000073F, 0x00000A0A, 0x00000A16, 0x0004002B, 0x0000000B, 0x00000926, 0x01000000, + 0x0004002B, 0x0000000B, 0x00000A46, 0x00000014, 0x0005002C, 0x00000011, 0x000008E3, 0x00000A46, + 0x00000A52, 0x0004002B, 0x0000000B, 0x00000144, 0x000000FF, 0x0004002B, 0x0000000B, 0x00000B54, + 0xC00FFC00, 0x00040020, 0x00000291, 0x00000001, 0x00000014, 0x0004003B, 0x00000291, 0x00000F48, + 0x00000001, 0x00040020, 0x00000289, 0x00000001, 0x0000000B, 0x0005002C, 0x00000011, 0x0000072A, + 0x00000A13, 0x00000A0A, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A32, 0x00000CC7, 0x00000002, + 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, + 0x000007B5, 0x000007DD, 0x00040020, 0x00000A33, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A33, + 0x00001592, 0x00000002, 0x0006002C, 0x00000014, 0x00000AC7, 0x00000A22, 0x00000A22, 0x00000A0D, + 0x0005002C, 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0005002C, 0x00000011, 0x000007A3, + 0x00000A37, 0x00000A0D, 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, 0x0005002C, + 0x00000011, 0x0000084A, 0x00000A37, 0x00000A37, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, + 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x0000064B, 0x00000144, 0x00000144, + 0x00000144, 0x00000144, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, + 0x00000A3A, 0x0007002C, 0x00000017, 0x00000930, 0x00000B54, 0x00000B54, 0x00000B54, 0x00000B54, + 0x0007002C, 0x00000017, 0x000003A1, 0x00000A44, 0x00000A44, 0x00000A44, 0x00000A44, 0x0007002C, + 0x00000017, 0x000003C5, 0x00000A46, 0x00000A46, 0x00000A46, 0x00000A46, 0x0004002B, 0x0000000B, + 0x00000A25, 0x00000009, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, + 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, + 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, + 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, + 0x00000288, 0x000056E5, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003D0B, 0x000056E5, + 0x00050041, 0x00000288, 0x000058AC, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x000051B7, + 0x000058AC, 0x000500C7, 0x0000000B, 0x00004ADC, 0x00003D0B, 0x00000A44, 0x000500C7, 0x0000000B, + 0x000055EF, 0x00003D0B, 0x00000AFE, 0x000500AB, 0x00000009, 0x0000500F, 0x000055EF, 0x00000A0A, + 0x000500C2, 0x0000000B, 0x00002843, 0x00003D0B, 0x00000A31, 0x000500C7, 0x0000000B, 0x00005F72, + 0x00002843, 0x00000A81, 0x000500C2, 0x0000000B, 0x00004994, 0x00003D0B, 0x00000A52, 0x000500C7, + 0x0000000B, 0x000023AA, 0x00004994, 0x00000A37, 0x00050050, 0x00000011, 0x000022A7, 0x000051B7, + 0x000051B7, 0x000500C2, 0x00000011, 0x000025A1, 0x000022A7, 0x00000883, 0x000500C7, 0x00000011, + 0x00005C31, 0x000025A1, 0x000007A2, 0x000500C7, 0x0000000B, 0x00005DDE, 0x00003D0B, 0x00000510, + 0x000500AB, 0x00000009, 0x00003007, 0x00005DDE, 0x00000A0A, 0x000300F7, 0x00003954, 0x00000000, + 0x000400FA, 0x00003007, 0x00004163, 0x000055E8, 0x000200F8, 0x000055E8, 0x000200F9, 0x00003954, + 0x000200F8, 0x00004163, 0x000500C2, 0x00000011, 0x00003BAE, 0x00005C31, 0x00000724, 0x000200F9, + 0x00003954, 0x000200F8, 0x00003954, 0x000700F5, 0x00000011, 0x00004AB4, 0x00003BAE, 0x00004163, + 0x0000070F, 0x000055E8, 0x000500C2, 0x00000011, 0x00001B7E, 0x000022A7, 0x0000073F, 0x000500C7, + 0x00000011, 0x00002DF9, 0x00001B7E, 0x000007A3, 0x000500C4, 0x00000011, 0x00003F4F, 0x00002DF9, + 0x0000074E, 0x00050084, 0x00000011, 0x000059EB, 0x00003F4F, 0x00005C31, 0x000500C2, 0x0000000B, + 0x00003343, 0x000051B7, 0x00000A19, 0x000500C7, 0x0000000B, 0x000039C1, 0x00003343, 0x00000A81, + 0x00050051, 0x0000000B, 0x0000229A, 0x00005C31, 0x00000000, 0x00050084, 0x0000000B, 0x000059D1, + 0x000039C1, 0x0000229A, 0x00050041, 0x00000288, 0x00004E44, 0x00000CE9, 0x00000A11, 0x0004003D, + 0x0000000B, 0x000048C4, 0x00004E44, 0x00050041, 0x00000288, 0x000058AD, 0x00000CE9, 0x00000A14, + 0x0004003D, 0x0000000B, 0x000051B8, 0x000058AD, 0x000500C7, 0x0000000B, 0x00004ADD, 0x000048C4, + 0x00000A1F, 0x000500C7, 0x0000000B, 0x000055F0, 0x000048C4, 0x00000A22, 0x000500AB, 0x00000009, + 0x00005010, 0x000055F0, 0x00000A0A, 0x000500C2, 0x0000000B, 0x000028A2, 0x000048C4, 0x00000A16, + 0x000500C7, 0x0000000B, 0x000059FD, 0x000028A2, 0x00000A1F, 0x000500C7, 0x0000000B, 0x00005A4E, + 0x000048C4, 0x00000926, 0x000500AB, 0x00000009, 0x00004C75, 0x00005A4E, 0x00000A0A, 0x000500C7, + 0x0000000B, 0x00001F43, 0x000051B8, 0x00000A44, 0x000500C4, 0x0000000B, 0x00003DA7, 0x00001F43, + 0x00000A19, 0x000500C2, 0x0000000B, 0x0000583F, 0x000051B8, 0x00000A28, 0x000500C7, 0x0000000B, + 0x00004BBE, 0x0000583F, 0x00000A44, 0x000500C4, 0x0000000B, 0x00006273, 0x00004BBE, 0x00000A19, + 0x00050050, 0x00000011, 0x000028B6, 0x000051B8, 0x000051B8, 0x000500C2, 0x00000011, 0x00002891, + 0x000028B6, 0x000008E3, 0x000500C7, 0x00000011, 0x00005B53, 0x00002891, 0x0000084A, 0x000500C4, + 0x00000011, 0x00003F50, 0x00005B53, 0x0000074E, 0x00050084, 0x00000011, 0x000059EC, 0x00003F50, + 0x00005C31, 0x000500C2, 0x0000000B, 0x00003213, 0x000051B8, 0x00000A5E, 0x000500C7, 0x0000000B, + 0x00003F4C, 0x00003213, 0x00000A1F, 0x00050041, 0x00000289, 0x00005143, 0x00000F48, 0x00000A0A, + 0x0004003D, 0x0000000B, 0x000022D1, 0x00005143, 0x000500AE, 0x00000009, 0x00001CED, 0x000022D1, + 0x000059D1, 0x000300F7, 0x00004427, 0x00000002, 0x000400FA, 0x00001CED, 0x000055E9, 0x00004427, + 0x000200F8, 0x000055E9, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004427, 0x0004003D, 0x00000014, + 0x0000392D, 0x00000F48, 0x0007004F, 0x00000011, 0x00004849, 0x0000392D, 0x0000392D, 0x00000000, + 0x00000001, 0x000500C4, 0x00000011, 0x00002670, 0x00004849, 0x0000072A, 0x00050051, 0x0000000B, + 0x00001A29, 0x00002670, 0x00000000, 0x00050051, 0x0000000B, 0x000047F9, 0x00002670, 0x00000001, + 0x00050051, 0x0000000B, 0x0000376A, 0x00004AB4, 0x00000001, 0x0007000C, 0x0000000B, 0x00005F7E, + 0x00000001, 0x00000029, 0x000047F9, 0x0000376A, 0x00050050, 0x00000011, 0x000051EF, 0x00001A29, + 0x00005F7E, 0x00050080, 0x00000011, 0x0000522C, 0x000051EF, 0x000059EB, 0x000500B2, 0x00000009, + 0x00003ECB, 0x00003F4C, 0x00000A13, 0x000300F7, 0x00001AFD, 0x00000000, 0x000400FA, 0x00003ECB, + 0x00002AEE, 0x00003AEF, 0x000200F8, 0x00003AEF, 0x000500AA, 0x00000009, 0x000034FE, 0x00003F4C, + 0x00000A19, 0x000600A9, 0x0000000B, 0x000020F6, 0x000034FE, 0x00000A10, 0x00000A0A, 0x000200F9, + 0x00001AFD, 0x000200F8, 0x00002AEE, 0x000200F9, 0x00001AFD, 0x000200F8, 0x00001AFD, 0x000700F5, + 0x0000000B, 0x00004085, 0x00003F4C, 0x00002AEE, 0x000020F6, 0x00003AEF, 0x000500C4, 0x00000011, + 0x00002BC1, 0x0000522C, 0x00000724, 0x00050050, 0x00000011, 0x000054BD, 0x00004085, 0x00004085, + 0x000500C2, 0x00000011, 0x00002385, 0x000054BD, 0x00000718, 0x000500C7, 0x00000011, 0x00003EC8, + 0x00002385, 0x00000724, 0x00050080, 0x00000011, 0x00004ABC, 0x00002BC1, 0x00003EC8, 0x00050084, + 0x00000011, 0x00002CB7, 0x00000A9F, 0x00005C31, 0x00050086, 0x00000011, 0x00001F2F, 0x00004ABC, + 0x00002CB7, 0x00050051, 0x0000000B, 0x000023A9, 0x00001F2F, 0x00000001, 0x00050084, 0x0000000B, + 0x00002B26, 0x000023A9, 0x00004ADC, 0x00050051, 0x0000000B, 0x00006059, 0x00001F2F, 0x00000000, + 0x00050080, 0x0000000B, 0x00005420, 0x00002B26, 0x00006059, 0x00050080, 0x0000000B, 0x00002226, + 0x00005F72, 0x00005420, 0x00050084, 0x00000011, 0x0000193B, 0x00001F2F, 0x00002CB7, 0x00050082, + 0x00000011, 0x000037C7, 0x00004ABC, 0x0000193B, 0x000300F7, 0x00004944, 0x00000000, 0x000400FA, + 0x0000500F, 0x00002E70, 0x00004944, 0x000200F8, 0x00002E70, 0x00050051, 0x0000000B, 0x00004259, + 0x00002CB7, 0x00000000, 0x000500C2, 0x0000000B, 0x000033FB, 0x00004259, 0x00000A0D, 0x00050051, + 0x0000000B, 0x000056BF, 0x000037C7, 0x00000000, 0x0004007C, 0x0000000C, 0x00003B5D, 0x000056BF, + 0x000500AE, 0x00000009, 0x00003D78, 0x000056BF, 0x000033FB, 0x000300F7, 0x00005942, 0x00000000, + 0x000400FA, 0x00003D78, 0x00005A15, 0x00005FF5, 0x000200F8, 0x00005FF5, 0x0004007C, 0x0000000C, + 0x000050D5, 0x000033FB, 0x000200F9, 0x00005942, 0x000200F8, 0x00005A15, 0x0004007C, 0x0000000C, + 0x000049C5, 0x000033FB, 0x0004007E, 0x0000000C, 0x0000432F, 0x000049C5, 0x000200F9, 0x00005942, + 0x000200F8, 0x00005942, 0x000700F5, 0x0000000C, 0x0000273E, 0x0000432F, 0x00005A15, 0x000050D5, + 0x00005FF5, 0x00050080, 0x0000000C, 0x00002ECF, 0x00003B5D, 0x0000273E, 0x0004007C, 0x0000000B, + 0x0000452D, 0x00002ECF, 0x00060052, 0x00000011, 0x00005446, 0x0000452D, 0x000037C7, 0x00000000, + 0x000200F9, 0x00004944, 0x000200F8, 0x00004944, 0x000700F5, 0x00000011, 0x000043D0, 0x000037C7, + 0x00001AFD, 0x00005446, 0x00005942, 0x00050051, 0x0000000B, 0x00005DD7, 0x00002CB7, 0x00000000, + 0x00050051, 0x0000000B, 0x0000571F, 0x00002CB7, 0x00000001, 0x00050084, 0x0000000B, 0x00003372, + 0x00005DD7, 0x0000571F, 0x00050084, 0x0000000B, 0x00003CA0, 0x00002226, 0x00003372, 0x00050051, + 0x0000000B, 0x00003ED4, 0x000043D0, 0x00000001, 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, + 0x00005DD7, 0x00050051, 0x0000000B, 0x0000605A, 0x000043D0, 0x00000000, 0x00050080, 0x0000000B, + 0x00005421, 0x00003E12, 0x0000605A, 0x00050080, 0x0000000B, 0x000022AB, 0x00003CA0, 0x00005421, + 0x00050084, 0x0000000B, 0x00005B10, 0x00003372, 0x00000A84, 0x00050089, 0x0000000B, 0x00005531, + 0x000022AB, 0x00005B10, 0x000500C2, 0x0000000B, 0x00001B5A, 0x00005531, 0x00000A10, 0x000500AB, + 0x00000009, 0x00002220, 0x00003F4C, 0x00000A10, 0x000300F7, 0x000033DC, 0x00000000, 0x000400FA, + 0x00002220, 0x00004032, 0x000033DC, 0x000200F8, 0x00004032, 0x000500AB, 0x00000009, 0x00002959, + 0x00003F4C, 0x00000A13, 0x000200F9, 0x000033DC, 0x000200F8, 0x000033DC, 0x000700F5, 0x00000009, + 0x00002AAC, 0x00002220, 0x00004944, 0x00002959, 0x00004032, 0x000300F7, 0x00004F23, 0x00000002, + 0x000400FA, 0x00002AAC, 0x00002621, 0x00002F61, 0x000200F8, 0x00002F61, 0x00060041, 0x00000294, + 0x00004852, 0x00000CC7, 0x00000A0B, 0x00001B5A, 0x0004003D, 0x00000017, 0x000033B7, 0x00004852, + 0x00050051, 0x0000000B, 0x00004F4C, 0x000033B7, 0x00000001, 0x00050051, 0x0000000B, 0x00003AE8, + 0x000033B7, 0x00000003, 0x00050080, 0x0000000B, 0x00004A43, 0x00001B5A, 0x00000A0D, 0x00060041, + 0x00000294, 0x00002212, 0x00000CC7, 0x00000A0B, 0x00004A43, 0x0004003D, 0x00000017, 0x000032D6, + 0x00002212, 0x00050051, 0x0000000B, 0x00004BBC, 0x000032D6, 0x00000001, 0x00050051, 0x0000000B, + 0x00006005, 0x000032D6, 0x00000003, 0x00070050, 0x00000017, 0x00001CFA, 0x00004F4C, 0x00003AE8, + 0x00004BBC, 0x00006005, 0x00050080, 0x0000000B, 0x000019F6, 0x00001B5A, 0x00000A10, 0x00060041, + 0x00000294, 0x00005CCE, 0x00000CC7, 0x00000A0B, 0x000019F6, 0x0004003D, 0x00000017, 0x000032D7, + 0x00005CCE, 0x00050051, 0x0000000B, 0x00004F4D, 0x000032D7, 0x00000001, 0x00050051, 0x0000000B, + 0x00003AE9, 0x000032D7, 0x00000003, 0x00050080, 0x0000000B, 0x00004A44, 0x00001B5A, 0x00000A13, + 0x00060041, 0x00000294, 0x00002213, 0x00000CC7, 0x00000A0B, 0x00004A44, 0x0004003D, 0x00000017, + 0x000032D8, 0x00002213, 0x00050051, 0x0000000B, 0x00004BBD, 0x000032D8, 0x00000001, 0x00050051, + 0x0000000B, 0x00001E81, 0x000032D8, 0x00000003, 0x00070050, 0x00000017, 0x00002349, 0x00004F4D, + 0x00003AE9, 0x00004BBD, 0x00001E81, 0x000200F9, 0x00004F23, 0x000200F8, 0x00002621, 0x00060041, + 0x00000294, 0x000051C8, 0x00000CC7, 0x00000A0B, 0x00001B5A, 0x0004003D, 0x00000017, 0x000033B8, + 0x000051C8, 0x00050051, 0x0000000B, 0x00004F4E, 0x000033B8, 0x00000000, 0x00050051, 0x0000000B, + 0x00003AEA, 0x000033B8, 0x00000002, 0x00050080, 0x0000000B, 0x00004A45, 0x00001B5A, 0x00000A0D, + 0x00060041, 0x00000294, 0x00002214, 0x00000CC7, 0x00000A0B, 0x00004A45, 0x0004003D, 0x00000017, + 0x000032D9, 0x00002214, 0x00050051, 0x0000000B, 0x00004BBF, 0x000032D9, 0x00000000, 0x00050051, + 0x0000000B, 0x00006006, 0x000032D9, 0x00000002, 0x00070050, 0x00000017, 0x00001CFB, 0x00004F4E, + 0x00003AEA, 0x00004BBF, 0x00006006, 0x00050080, 0x0000000B, 0x000019F7, 0x00001B5A, 0x00000A10, + 0x00060041, 0x00000294, 0x00005CCF, 0x00000CC7, 0x00000A0B, 0x000019F7, 0x0004003D, 0x00000017, + 0x000032DA, 0x00005CCF, 0x00050051, 0x0000000B, 0x00004F4F, 0x000032DA, 0x00000000, 0x00050051, + 0x0000000B, 0x00003AEB, 0x000032DA, 0x00000002, 0x00050080, 0x0000000B, 0x00004A46, 0x00001B5A, + 0x00000A13, 0x00060041, 0x00000294, 0x00002215, 0x00000CC7, 0x00000A0B, 0x00004A46, 0x0004003D, + 0x00000017, 0x000032DB, 0x00002215, 0x00050051, 0x0000000B, 0x00004BC0, 0x000032DB, 0x00000000, + 0x00050051, 0x0000000B, 0x00001E82, 0x000032DB, 0x00000002, 0x00070050, 0x00000017, 0x0000234A, + 0x00004F4F, 0x00003AEB, 0x00004BC0, 0x00001E82, 0x000200F9, 0x00004F23, 0x000200F8, 0x00004F23, + 0x000700F5, 0x00000017, 0x00002616, 0x0000234A, 0x00002621, 0x00002349, 0x00002F61, 0x000700F5, + 0x00000017, 0x00003997, 0x00001CFB, 0x00002621, 0x00001CFA, 0x00002F61, 0x000500AA, 0x00000009, + 0x0000195B, 0x00001A29, 0x00000A0A, 0x000300F7, 0x000033DD, 0x00000000, 0x000400FA, 0x0000195B, + 0x00002CBB, 0x000033DD, 0x000200F8, 0x00002CBB, 0x00050051, 0x0000000B, 0x00005E5C, 0x00004AB4, + 0x00000000, 0x000500AB, 0x00000009, 0x000057C6, 0x00005E5C, 0x00000A0A, 0x000200F9, 0x000033DD, + 0x000200F8, 0x000033DD, 0x000700F5, 0x00000009, 0x00002AAD, 0x0000195B, 0x00004F23, 0x000057C6, + 0x00002CBB, 0x000300F7, 0x00005596, 0x00000002, 0x000400FA, 0x00002AAD, 0x00002CF4, 0x00005596, + 0x000200F8, 0x00002CF4, 0x00050051, 0x0000000B, 0x00005C2F, 0x00004AB4, 0x00000000, 0x000500AE, + 0x00000009, 0x000043C2, 0x00005C2F, 0x00000A10, 0x000300F7, 0x00004946, 0x00000000, 0x000400FA, + 0x000043C2, 0x00003E05, 0x00004946, 0x000200F8, 0x00003E05, 0x000500AE, 0x00000009, 0x00005FD4, + 0x00005C2F, 0x00000A13, 0x000300F7, 0x00004945, 0x00000000, 0x000400FA, 0x00005FD4, 0x00002620, + 0x00004945, 0x000200F8, 0x00002620, 0x00050051, 0x0000000B, 0x00005002, 0x00003997, 0x00000003, + 0x00060052, 0x00000017, 0x000037FF, 0x00005002, 0x00003997, 0x00000002, 0x000200F9, 0x00004945, + 0x000200F8, 0x00004945, 0x000700F5, 0x00000017, 0x000043E3, 0x00003997, 0x00003E05, 0x000037FF, + 0x00002620, 0x00050051, 0x0000000B, 0x00001B5B, 0x000043E3, 0x00000002, 0x00060052, 0x00000017, + 0x00003B28, 0x00001B5B, 0x000043E3, 0x00000001, 0x000200F9, 0x00004946, 0x000200F8, 0x00004946, + 0x000700F5, 0x00000017, 0x000043E4, 0x00003997, 0x00002CF4, 0x00003B28, 0x00004945, 0x00050051, + 0x0000000B, 0x00001B5C, 0x000043E4, 0x00000001, 0x00060052, 0x00000017, 0x00003B29, 0x00001B5C, + 0x000043E4, 0x00000000, 0x000200F9, 0x00005596, 0x000200F8, 0x00005596, 0x000700F5, 0x00000017, + 0x00002AAE, 0x00003997, 0x000033DD, 0x00003B29, 0x00004946, 0x000300F7, 0x0000530F, 0x00000002, + 0x000400FA, 0x00004C75, 0x0000577B, 0x0000530F, 0x000200F8, 0x0000577B, 0x000300F7, 0x000039F4, + 0x00000000, 0x000F00FB, 0x000023AA, 0x000039F4, 0x00000000, 0x000055A0, 0x00000001, 0x000055A0, + 0x00000002, 0x00002897, 0x00000003, 0x00002897, 0x0000000A, 0x00002897, 0x0000000C, 0x00002897, + 0x000200F8, 0x00002897, 0x000500C7, 0x00000017, 0x00003BA9, 0x00002AAE, 0x00000930, 0x000500C7, + 0x00000017, 0x00005C0C, 0x00002AAE, 0x000003A1, 0x000500C4, 0x00000017, 0x00006105, 0x00005C0C, + 0x000003C5, 0x000500C5, 0x00000017, 0x00004655, 0x00003BA9, 0x00006105, 0x000500C2, 0x00000017, + 0x00005A82, 0x00002AAE, 0x000003C5, 0x000500C7, 0x00000017, 0x0000192A, 0x00005A82, 0x000003A1, + 0x000500C5, 0x00000017, 0x00003CE5, 0x00004655, 0x0000192A, 0x000500C7, 0x00000017, 0x00004C3F, + 0x00002616, 0x00000930, 0x000500C7, 0x00000017, 0x0000461A, 0x00002616, 0x000003A1, 0x000500C4, + 0x00000017, 0x00006106, 0x0000461A, 0x000003C5, 0x000500C5, 0x00000017, 0x00004656, 0x00004C3F, + 0x00006106, 0x000500C2, 0x00000017, 0x00005A83, 0x00002616, 0x000003C5, 0x000500C7, 0x00000017, + 0x00001CE0, 0x00005A83, 0x000003A1, 0x000500C5, 0x00000017, 0x00001EBE, 0x00004656, 0x00001CE0, + 0x000200F9, 0x000039F4, 0x000200F8, 0x000055A0, 0x000500C7, 0x00000017, 0x00004E95, 0x00002AAE, + 0x0000072E, 0x000500C7, 0x00000017, 0x00005C0D, 0x00002AAE, 0x0000064B, 0x000500C4, 0x00000017, + 0x00006107, 0x00005C0D, 0x000002ED, 0x000500C5, 0x00000017, 0x00004657, 0x00004E95, 0x00006107, + 0x000500C2, 0x00000017, 0x00005A84, 0x00002AAE, 0x000002ED, 0x000500C7, 0x00000017, 0x0000192B, + 0x00005A84, 0x0000064B, 0x000500C5, 0x00000017, 0x00003CE6, 0x00004657, 0x0000192B, 0x000500C7, + 0x00000017, 0x00004C40, 0x00002616, 0x0000072E, 0x000500C7, 0x00000017, 0x0000461B, 0x00002616, + 0x0000064B, 0x000500C4, 0x00000017, 0x00006108, 0x0000461B, 0x000002ED, 0x000500C5, 0x00000017, + 0x00004658, 0x00004C40, 0x00006108, 0x000500C2, 0x00000017, 0x00005A85, 0x00002616, 0x000002ED, + 0x000500C7, 0x00000017, 0x00001CE1, 0x00005A85, 0x0000064B, 0x000500C5, 0x00000017, 0x00001EBF, + 0x00004658, 0x00001CE1, 0x000200F9, 0x000039F4, 0x000200F8, 0x000039F4, 0x000900F5, 0x00000017, + 0x00002BF3, 0x00002616, 0x0000577B, 0x00001EBF, 0x000055A0, 0x00001EBE, 0x00002897, 0x000900F5, + 0x00000017, 0x0000358D, 0x00002AAE, 0x0000577B, 0x00003CE6, 0x000055A0, 0x00003CE5, 0x00002897, + 0x000200F9, 0x0000530F, 0x000200F8, 0x0000530F, 0x000700F5, 0x00000017, 0x000022F8, 0x00002616, + 0x00005596, 0x00002BF3, 0x000039F4, 0x000700F5, 0x00000017, 0x000049A7, 0x00002AAE, 0x00005596, + 0x0000358D, 0x000039F4, 0x00050080, 0x00000011, 0x000035BB, 0x00002670, 0x000059EC, 0x00050051, + 0x0000000B, 0x000033BC, 0x000035BB, 0x00000000, 0x00050051, 0x0000000B, 0x00002553, 0x000035BB, + 0x00000001, 0x000500C2, 0x0000000B, 0x00002B2D, 0x000033BC, 0x00000A10, 0x00050050, 0x00000011, + 0x00001E98, 0x00002B2D, 0x00002553, 0x00050086, 0x00000011, 0x00006158, 0x00001E98, 0x00005C31, + 0x00050051, 0x0000000B, 0x0000366C, 0x00006158, 0x00000000, 0x000500C4, 0x0000000B, 0x00004D3A, + 0x0000366C, 0x00000A10, 0x00050051, 0x0000000B, 0x00005EBB, 0x00006158, 0x00000001, 0x00060050, + 0x00000014, 0x000053CC, 0x00004D3A, 0x00005EBB, 0x000059FD, 0x000300F7, 0x00005341, 0x00000002, + 0x000400FA, 0x00005010, 0x000056BE, 0x00002A98, 0x000200F8, 0x00002A98, 0x0007004F, 0x00000011, + 0x00001CAB, 0x000053CC, 0x000053CC, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000059CF, + 0x00001CAB, 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, 0x00000000, 0x000500C3, 0x0000000C, + 0x000024FD, 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000059CF, 0x00000001, + 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, + 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, + 0x00005347, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, + 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002AB6, + 0x00001903, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x00002747, 0x00000A35, 0x000500C4, + 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, + 0x0000454D, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, 0x0000000C, + 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4B, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, + 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4B, 0x00003397, 0x000500C7, + 0x0000000C, 0x000047B4, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544A, 0x000047B4, + 0x00000A17, 0x00050080, 0x0000000C, 0x00004157, 0x00004D30, 0x0000544A, 0x000500C7, 0x0000000C, + 0x00005022, 0x00004157, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, + 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x00004158, 0x00002416, 0x00002F77, 0x000500C7, + 0x0000000C, 0x00004ADE, 0x00004157, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544B, 0x00004ADE, + 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x00004158, 0x0000544B, 0x000500C7, 0x0000000C, + 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, + 0x000500C3, 0x0000000C, 0x00001EEC, 0x00001903, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, + 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544C, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004144, + 0x0000544C, 0x000500C7, 0x0000000C, 0x00002E06, 0x00004157, 0x00000AC8, 0x00050080, 0x0000000C, + 0x0000394F, 0x00003C4C, 0x00002E06, 0x0004007C, 0x0000000B, 0x0000566F, 0x0000394F, 0x000200F9, + 0x00005341, 0x000200F8, 0x000056BE, 0x0004007C, 0x00000016, 0x000019AD, 0x000053CC, 0x00050051, + 0x0000000C, 0x000042C2, 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FE, 0x000042C2, + 0x00000A17, 0x00050051, 0x0000000C, 0x00002748, 0x000019AD, 0x00000002, 0x000500C3, 0x0000000C, + 0x0000405D, 0x00002748, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00006273, 0x00000A16, + 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005321, 0x0000405D, + 0x000018AB, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FE, 0x00005321, 0x000500C2, 0x0000000B, + 0x00002348, 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, + 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, 0x000019AD, + 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, + 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A22, + 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, + 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, + 0x0000000C, 0x00003139, 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, + 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454E, 0x000500C4, 0x0000000C, + 0x00001B88, 0x0000434B, 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, + 0x000500C3, 0x0000000C, 0x00002216, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, + 0x00002216, 0x0000405D, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, + 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, + 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, + 0x00004ADF, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544D, 0x00004ADF, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4D, 0x00005A0C, 0x0000544D, 0x000500C7, 0x0000000C, 0x0000335E, + 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, + 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, + 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, + 0x000047B5, 0x00002748, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544E, 0x000047B5, 0x00000A22, + 0x00050080, 0x0000000C, 0x00004159, 0x0000285C, 0x0000544E, 0x000500C7, 0x0000000C, 0x00004AE0, + 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544F, 0x00004AE0, 0x00000A17, 0x00050080, + 0x0000000C, 0x0000415A, 0x00004159, 0x0000544F, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4D, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, + 0x00003332, 0x0000415A, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, + 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, + 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4D, 0x00000A05, 0x00050080, + 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, + 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x0000415A, 0x0000040B, 0x00050080, 0x0000000C, + 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005559, 0x0000415A, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, + 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, 0x00005670, 0x00005EFA, 0x000200F9, 0x00005341, + 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, 0x000024FC, 0x00005670, 0x000056BE, 0x0000566F, + 0x00002A98, 0x00050084, 0x00000011, 0x00003FA8, 0x00006158, 0x00005C31, 0x00050082, 0x00000011, + 0x00003F85, 0x00001E98, 0x00003FA8, 0x00050051, 0x0000000B, 0x0000448F, 0x00005C31, 0x00000001, + 0x00050084, 0x0000000B, 0x00005C50, 0x0000229A, 0x0000448F, 0x00050084, 0x0000000B, 0x00003CA1, + 0x000024FC, 0x00005C50, 0x00050051, 0x0000000B, 0x00003ED5, 0x00003F85, 0x00000000, 0x00050084, + 0x0000000B, 0x00003E13, 0x00003ED5, 0x0000448F, 0x00050051, 0x0000000B, 0x00001AE6, 0x00003F85, + 0x00000001, 0x00050080, 0x0000000B, 0x00002B25, 0x00003E13, 0x00001AE6, 0x000500C4, 0x0000000B, + 0x0000609D, 0x00002B25, 0x00000A10, 0x000500C7, 0x0000000B, 0x00005AB3, 0x000033BC, 0x00000A13, + 0x00050080, 0x0000000B, 0x00002557, 0x0000609D, 0x00005AB3, 0x000500C4, 0x0000000B, 0x00004593, + 0x00002557, 0x00000A10, 0x00050080, 0x0000000B, 0x00002048, 0x00003CA1, 0x00004593, 0x000500C2, + 0x0000000B, 0x00002015, 0x00002048, 0x00000A16, 0x000500AA, 0x00000009, 0x00002EEA, 0x00004ADD, + 0x00000A0D, 0x000500AA, 0x00000009, 0x00005776, 0x00004ADD, 0x00000A10, 0x000500A6, 0x00000009, + 0x00005686, 0x00002EEA, 0x00005776, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, + 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x000049A7, + 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, + 0x000050AC, 0x000049A7, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, + 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, + 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x000049A7, 0x00005341, 0x00003FF8, 0x00002957, + 0x000500AA, 0x00000009, 0x00004CB6, 0x00004ADD, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, + 0x00005776, 0x00004CB6, 0x000300F7, 0x00002C98, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, + 0x00002C98, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, + 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, + 0x00005E17, 0x00003BE7, 0x000200F9, 0x00002C98, 0x000200F8, 0x00002C98, 0x000700F5, 0x00000017, + 0x00004D37, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x00060041, 0x00000294, 0x000019BE, + 0x00001592, 0x00000A0B, 0x00002015, 0x0003003E, 0x000019BE, 0x00004D37, 0x000500AC, 0x00000009, + 0x00005BF6, 0x0000229A, 0x00000A0D, 0x000300F7, 0x00004AAC, 0x00000002, 0x000400FA, 0x00005BF6, + 0x000038DA, 0x000055EA, 0x000200F8, 0x000055EA, 0x000200F9, 0x00004AAC, 0x000200F8, 0x000038DA, + 0x000500C2, 0x0000000B, 0x0000364A, 0x00001A29, 0x00000A10, 0x00050086, 0x0000000B, 0x00001F01, + 0x0000364A, 0x0000229A, 0x00050084, 0x0000000B, 0x000041FB, 0x00001F01, 0x0000229A, 0x00050082, + 0x0000000B, 0x00003171, 0x0000364A, 0x000041FB, 0x00050080, 0x0000000B, 0x00002527, 0x00003171, + 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, 0x0000229A, 0x000300F7, 0x00002458, + 0x00000000, 0x000400FA, 0x0000343F, 0x00001CDB, 0x000055EB, 0x000200F8, 0x000055EB, 0x000200F9, + 0x00002458, 0x000200F8, 0x00001CDB, 0x00050084, 0x0000000B, 0x00003B96, 0x00000A6A, 0x0000229A, + 0x000500C4, 0x0000000B, 0x0000540F, 0x00003171, 0x00000A16, 0x00050082, 0x0000000B, 0x00004947, + 0x00003B96, 0x0000540F, 0x000200F9, 0x00002458, 0x000200F8, 0x00002458, 0x000700F5, 0x0000000B, + 0x0000292C, 0x00004947, 0x00001CDB, 0x00000A3A, 0x000055EB, 0x000200F9, 0x00004AAC, 0x000200F8, + 0x00004AAC, 0x000700F5, 0x0000000B, 0x000029BC, 0x0000292C, 0x00002458, 0x00000A6A, 0x000055EA, + 0x00050084, 0x0000000B, 0x0000492B, 0x000029BC, 0x0000448F, 0x000500C2, 0x0000000B, 0x00004DEF, + 0x0000492B, 0x00000A16, 0x00050080, 0x0000000B, 0x00005B72, 0x00002015, 0x00004DEF, 0x000300F7, + 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, + 0x000500C7, 0x00000017, 0x00004760, 0x000022F8, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, + 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000022F8, 0x0000072E, 0x000500C2, + 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, + 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAF, + 0x000022F8, 0x00004AAC, 0x00003FF9, 0x00002958, 0x000300F7, 0x00002C99, 0x00000000, 0x000400FA, + 0x00003B23, 0x00002B39, 0x00002C99, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, + 0x00002AAF, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAF, 0x000002ED, 0x000500C5, + 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002C99, 0x000200F8, 0x00002C99, + 0x000700F5, 0x00000017, 0x00004D39, 0x00002AAF, 0x00003A1A, 0x000029E9, 0x00002B39, 0x00060041, + 0x00000294, 0x00001F75, 0x00001592, 0x00000A0B, 0x00005B72, 0x0003003E, 0x00001F75, 0x00004D39, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_fast_64bpp_1x2xmsaa_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_fast_64bpp_1x2xmsaa_cs.h new file mode 100644 index 0000000..e8bda8c --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_fast_64bpp_1x2xmsaa_cs.h @@ -0,0 +1,708 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25271 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_struct_1036 Block + OpMemberDecorate %_struct_1036 0 Offset 0 + OpMemberDecorate %_struct_1036 1 Offset 4 + OpMemberDecorate %_struct_1036 2 Offset 8 + OpMemberDecorate %_struct_1036 3 Offset 12 + OpMemberDecorate %_struct_1036 4 Offset 16 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %3271 NonWritable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5522 NonReadable + OpDecorate %5522 Binding 0 + OpDecorate %5522 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %bool = OpTypeBool + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_4 = OpConstant %uint 4 + %1837 = OpConstantComposite %v2uint %uint_2 %uint_1 + %v2bool = OpTypeVector %bool 2 + %uint_0 = OpConstant %uint 0 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_struct_1036 = OpTypeStruct %uint %uint %uint %uint %uint +%_ptr_PushConstant__struct_1036 = OpTypePointer PushConstant %_struct_1036 + %3305 = OpVariable %_ptr_PushConstant__struct_1036 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %uint_1023 = OpConstant %uint 1023 + %uint_10 = OpConstant %uint 10 + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_24 = OpConstant %uint 24 + %uint_15 = OpConstant %uint 15 + %uint_28 = OpConstant %uint 28 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 +%uint_16777216 = OpConstant %uint 16777216 + %uint_20 = OpConstant %uint 20 + %2275 = OpConstantComposite %v2uint %uint_20 %uint_24 + %v3uint = OpTypeVector %uint 3 +%uint_4294901760 = OpConstant %uint 4294901760 + %uint_65535 = OpConstant %uint 65535 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %1825 = OpConstantComposite %v2uint %uint_2 %uint_0 + %false = OpConstantFalse %bool +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %3271 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5522 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %uint_9 = OpConstant %uint 9 + %1877 = OpConstantComposite %v4uint %uint_4294901760 %uint_4294901760 %uint_4294901760 %uint_4294901760 + %850 = OpConstantComposite %v4uint %uint_65535 %uint_65535 %uint_65535 %uint_65535 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %uint_40 = OpConstant %uint 40 + %2359 = OpConstantComposite %v2uint %uint_40 %uint_16 + %uint_1280 = OpConstant %uint 1280 +%uint_2621440 = OpConstant %uint 2621440 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %19978 = OpShiftRightLogical %uint %15627 %uint_10 + %8574 = OpBitwiseAnd %uint %19978 %uint_3 + %21002 = OpShiftRightLogical %uint %15627 %uint_13 + %8575 = OpBitwiseAnd %uint %21002 %uint_2047 + %18836 = OpShiftRightLogical %uint %15627 %uint_24 + %9130 = OpBitwiseAnd %uint %18836 %uint_15 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9576 = OpShiftRightLogical %v2uint %8871 %1855 + %23379 = OpBitwiseAnd %v2uint %9576 %1954 + %16207 = OpShiftLeftLogical %v2uint %23379 %1870 + %23019 = OpIMul %v2uint %16207 %1828 + %12819 = OpShiftRightLogical %uint %20824 %uint_5 + %16204 = OpBitwiseAnd %uint %12819 %uint_2047 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %24236 = OpLoad %uint %18732 + %22701 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %20919 = OpLoad %uint %22701 + %19164 = OpBitwiseAnd %uint %24236 %uint_7 + %21999 = OpBitwiseAnd %uint %24236 %uint_8 + %20495 = OpINotEqual %bool %21999 %uint_0 + %10402 = OpShiftRightLogical %uint %24236 %uint_4 + %23037 = OpBitwiseAnd %uint %10402 %uint_7 + %23118 = OpBitwiseAnd %uint %24236 %uint_16777216 + %19573 = OpINotEqual %bool %23118 %uint_0 + %8003 = OpBitwiseAnd %uint %20919 %uint_1023 + %15783 = OpShiftLeftLogical %uint %8003 %uint_5 + %22591 = OpShiftRightLogical %uint %20919 %uint_10 + %19390 = OpBitwiseAnd %uint %22591 %uint_1023 + %25203 = OpShiftLeftLogical %uint %19390 %uint_5 + %10422 = OpCompositeConstruct %v2uint %20919 %20919 + %10385 = OpShiftRightLogical %v2uint %10422 %2275 + %23380 = OpBitwiseAnd %v2uint %10385 %2122 + %16208 = OpShiftLeftLogical %v2uint %23380 %1870 + %23020 = OpIMul %v2uint %16208 %1828 + %12820 = OpShiftRightLogical %uint %20919 %uint_28 + %16205 = OpBitwiseAnd %uint %12820 %uint_7 + %18656 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_4 + %25270 = OpLoad %uint %18656 + %14159 = OpLoad %v3uint %gl_GlobalInvocationID + %12672 = OpVectorShuffle %v2uint %14159 %14159 0 1 + %12025 = OpShiftLeftLogical %v2uint %12672 %1825 + %7640 = OpCompositeExtract %uint %12025 0 + %11658 = OpShiftLeftLogical %uint %16204 %uint_3 + %15379 = OpUGreaterThanEqual %bool %7640 %11658 + OpSelectionMerge %12755 DontFlatten + OpBranchConditional %15379 %21992 %12755 + %21992 = OpLabel + OpBranch %19578 + %12755 = OpLabel + %7340 = OpCompositeExtract %uint %12025 1 + %7992 = OpExtInst %uint %1 UMax %7340 %uint_0 + %20975 = OpCompositeConstruct %v2uint %7640 %7992 + %21036 = OpIAdd %v2uint %20975 %23019 + %16075 = OpULessThanEqual %bool %16205 %uint_3 + OpSelectionMerge %23776 None + OpBranchConditional %16075 %10990 %15087 + %15087 = OpLabel + %13566 = OpIEqual %bool %16205 %uint_5 + %8438 = OpSelect %uint %13566 %uint_2 %uint_0 + OpBranch %23776 + %10990 = OpLabel + OpBranch %23776 + %23776 = OpLabel + %19300 = OpPhi %uint %16205 %10990 %8438 %15087 + %16830 = OpCompositeConstruct %v2uint %8574 %8574 + %11801 = OpUGreaterThanEqual %v2bool %16830 %1837 + %19381 = OpSelect %v2uint %11801 %1828 %1807 + %10986 = OpShiftLeftLogical %v2uint %21036 %19381 + %24669 = OpCompositeConstruct %v2uint %19300 %19300 + %9093 = OpShiftRightLogical %v2uint %24669 %1816 + %16110 = OpBitwiseAnd %v2uint %9093 %1828 + %17779 = OpIAdd %v2uint %10986 %16110 + %24270 = OpUDiv %v2uint %17779 %2359 + %12360 = OpCompositeExtract %uint %24270 1 + %11046 = OpIMul %uint %12360 %20561 + %24665 = OpCompositeExtract %uint %24270 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %8575 %21536 + %23345 = OpIMul %v2uint %24270 %2359 + %11892 = OpISub %v2uint %17779 %23345 + %9022 = OpIMul %uint %8742 %uint_1280 + %14471 = OpCompositeExtract %uint %11892 1 + %15890 = OpIMul %uint %14471 %uint_40 + %6886 = OpCompositeExtract %uint %11892 0 + %9696 = OpIAdd %uint %15890 %6886 + %18116 = OpShiftLeftLogical %uint %9696 %uint_1 + %18581 = OpIAdd %uint %9022 %18116 + %17820 = OpUMod %uint %18581 %uint_2621440 + %18580 = OpShiftRightLogical %uint %17820 %uint_2 + %17174 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %18580 + %12609 = OpLoad %v4uint %17174 + %11687 = OpIAdd %uint %18580 %uint_1 + %7197 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %11687 + %18360 = OpLoad %v4uint %7197 + %15472 = OpIEqual %bool %7640 %uint_0 + %15603 = OpSelect %bool %15472 %false %15472 + OpSelectionMerge %21910 DontFlatten + OpBranchConditional %15603 %9760 %21910 + %9760 = OpLabel + %17290 = OpCompositeExtract %uint %12609 2 + %21174 = OpCompositeInsert %v4uint %17290 %12609 0 + %23044 = OpCompositeExtract %uint %12609 3 + %9296 = OpCompositeInsert %v4uint %23044 %21174 1 + OpBranch %21910 + %21910 = OpLabel + %10924 = OpPhi %v4uint %12609 %23776 %9296 %9760 + OpSelectionMerge %21263 DontFlatten + OpBranchConditional %19573 %15068 %21263 + %15068 = OpLabel + %13701 = OpIEqual %bool %9130 %uint_5 + %17015 = OpLogicalNot %bool %13701 + OpSelectionMerge %15698 None + OpBranchConditional %17015 %16607 %15698 + %16607 = OpLabel + %18778 = OpIEqual %bool %9130 %uint_7 + OpBranch %15698 + %15698 = OpLabel + %10925 = OpPhi %bool %13701 %15068 %18778 %16607 + OpSelectionMerge %14836 DontFlatten + OpBranchConditional %10925 %8360 %14836 + %8360 = OpLabel + %19441 = OpBitwiseAnd %v4uint %10924 %1877 + %20970 = OpVectorShuffle %v4uint %10924 %10924 1 0 3 2 + %7405 = OpBitwiseAnd %v4uint %20970 %850 + %13888 = OpBitwiseOr %v4uint %19441 %7405 + %21265 = OpBitwiseAnd %v4uint %18360 %1877 + %15352 = OpVectorShuffle %v4uint %18360 %18360 1 0 3 2 + %8355 = OpBitwiseAnd %v4uint %15352 %850 + %8449 = OpBitwiseOr %v4uint %21265 %8355 + OpBranch %14836 + %14836 = OpLabel + %11251 = OpPhi %v4uint %18360 %15698 %8449 %8360 + %13709 = OpPhi %v4uint %10924 %15698 %13888 %8360 + OpBranch %21263 + %21263 = OpLabel + %8952 = OpPhi %v4uint %18360 %21910 %11251 %14836 + %22009 = OpPhi %v4uint %10924 %21910 %13709 %14836 + %7319 = OpIAdd %v2uint %12025 %23020 + OpSelectionMerge %21237 DontFlatten + OpBranchConditional %20495 %10574 %21373 + %21373 = OpLabel + %10608 = OpBitcast %v2int %7319 + %17090 = OpCompositeExtract %int %10608 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %10608 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %15783 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_10 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17303 = OpIAdd %int %10934 %17741 + %6375 = OpShiftLeftLogical %int %17303 %uint_3 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15435 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18356 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18356 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12151 + %19165 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19165 %int_2 + %16708 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21587 %int_6 + %15436 = OpIAdd %int %16708 %21580 + %11782 = OpBitwiseAnd %int %16727 %int_63 + %14671 = OpIAdd %int %15436 %11782 + %22127 = OpBitcast %uint %14671 + OpBranch %21237 + %10574 = OpLabel + %19866 = OpCompositeExtract %uint %7319 0 + %11267 = OpCompositeExtract %uint %7319 1 + %8414 = OpCompositeConstruct %v3uint %19866 %11267 %23037 + %20125 = OpBitcast %v3int %8414 + %10438 = OpCompositeExtract %int %20125 1 + %9470 = OpShiftRightArithmetic %int %10438 %int_4 + %10056 = OpCompositeExtract %int %20125 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %25203 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %15783 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %20125 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_9 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12601 = OpBitwiseAnd %int %10438 %int_6 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7048 = OpShiftLeftLogical %int %17227 %uint_9 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %10438 %int_3 + %13731 = OpIAdd %int %8725 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19166 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19166 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23346 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23346 %23274 + %18357 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18357 %uint_9 + %16729 = OpIAdd %int %10332 %21582 + %19167 = OpBitwiseAnd %int %10438 %int_1 + %21583 = OpShiftLeftLogical %int %19167 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23347 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10908 = OpIAdd %int %23347 %23217 + %23348 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10909 = OpIAdd %int %23348 %23218 + %23349 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16730 %int_63 + %24314 = OpIAdd %int %23349 %21849 + %22128 = OpBitcast %uint %24314 + OpBranch %21237 + %21237 = OpLabel + %11376 = OpPhi %uint %22128 %10574 %22127 %21373 + %20616 = OpIAdd %uint %11376 %25270 + %20138 = OpShiftRightLogical %uint %20616 %uint_4 + %19356 = OpIEqual %bool %19164 %uint_4 + OpSelectionMerge %14780 None + OpBranchConditional %19356 %13279 %14780 + %13279 = OpLabel + %7958 = OpVectorShuffle %v4uint %22009 %22009 1 0 3 2 + OpBranch %14780 + %14780 = OpLabel + %22898 = OpPhi %v4uint %22009 %21237 %7958 %13279 + %6605 = OpSelect %uint %19356 %uint_2 %19164 + %13412 = OpIEqual %bool %6605 %uint_1 + %18370 = OpIEqual %bool %6605 %uint_2 + %22150 = OpLogicalOr %bool %13412 %18370 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %22898 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %22898 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %22898 %14780 %16376 %10583 + %19638 = OpIEqual %bool %6605 %uint_3 + %15139 = OpLogicalOr %bool %18370 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %24825 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %20138 + OpStore %24825 %19767 + %21685 = OpIAdd %uint %20138 %uint_2 + OpSelectionMerge %16262 None + OpBranchConditional %19356 %13280 %16262 + %13280 = OpLabel + %7959 = OpVectorShuffle %v4uint %8952 %8952 1 0 3 2 + OpBranch %16262 + %16262 = OpLabel + %10926 = OpPhi %v4uint %8952 %11416 %7959 %13280 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %10926 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %10926 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10927 = OpPhi %v4uint %10926 %16262 %16377 %10584 + OpSelectionMerge %11417 None + OpBranchConditional %15139 %11065 %11417 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10927 %749 + %15336 = OpShiftRightLogical %v4uint %10927 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %10927 %14874 %10729 %11065 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %21685 + OpStore %8053 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_fast_64bpp_1x2xmsaa_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000062B7, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00030047, 0x0000040C, 0x00000002, 0x00050048, + 0x0000040C, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x0000040C, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x0000040C, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x0000040C, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x0000040C, 0x00000004, 0x00000023, 0x00000010, + 0x00040047, 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, + 0x00030047, 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, + 0x000007B4, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000CC7, 0x00000018, 0x00040047, + 0x00000CC7, 0x00000021, 0x00000000, 0x00040047, 0x00000CC7, 0x00000022, 0x00000000, 0x00040047, + 0x000007DD, 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, + 0x00000000, 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, + 0x00001592, 0x00000019, 0x00040047, 0x00001592, 0x00000021, 0x00000000, 0x00040047, 0x00001592, + 0x00000022, 0x00000001, 0x00040047, 0x00000AC7, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, + 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, + 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00020014, + 0x00000009, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, + 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A0D, + 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x000008A6, + 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, + 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A3A, + 0x00000010, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0005002C, 0x00000011, 0x0000072D, + 0x00000A10, 0x00000A0D, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0004002B, 0x0000000B, + 0x00000A0A, 0x00000000, 0x0005002C, 0x00000011, 0x0000070F, 0x00000A0A, 0x00000A0A, 0x0005002C, + 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, 0x0005002C, 0x00000011, 0x00000718, 0x00000A0D, + 0x00000A0A, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, + 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A20, + 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, + 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, + 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, + 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, + 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, + 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, + 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000C, 0x0000078B, + 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0007001E, 0x0000040C, 0x0000000B, + 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000688, 0x00000009, 0x0000040C, + 0x0004003B, 0x00000688, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, + 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, + 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, + 0x0004002B, 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A52, 0x00000018, + 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, 0x0004002B, 0x0000000B, 0x00000A5E, 0x0000001C, + 0x0005002C, 0x00000011, 0x0000073F, 0x00000A0A, 0x00000A16, 0x0004002B, 0x0000000B, 0x00000926, + 0x01000000, 0x0004002B, 0x0000000B, 0x00000A46, 0x00000014, 0x0005002C, 0x00000011, 0x000008E3, + 0x00000A46, 0x00000A52, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x0004002B, 0x0000000B, + 0x0000068D, 0xFFFF0000, 0x0004002B, 0x0000000B, 0x000001C1, 0x0000FFFF, 0x00040020, 0x00000291, + 0x00000001, 0x00000014, 0x0004003B, 0x00000291, 0x00000F48, 0x00000001, 0x0005002C, 0x00000011, + 0x00000721, 0x00000A10, 0x00000A0A, 0x0003002A, 0x00000009, 0x00000787, 0x0003001D, 0x000007DC, + 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, + 0x0004003B, 0x00000A32, 0x00000CC7, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, + 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A33, + 0x00000002, 0x000007B5, 0x0004003B, 0x00000A33, 0x00001592, 0x00000002, 0x0006002C, 0x00000014, + 0x00000AC7, 0x00000A22, 0x00000A22, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A37, + 0x00000A0D, 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, 0x0005002C, 0x00000011, + 0x0000084A, 0x00000A37, 0x00000A37, 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0007002C, + 0x00000017, 0x00000755, 0x0000068D, 0x0000068D, 0x0000068D, 0x0000068D, 0x0007002C, 0x00000017, + 0x00000352, 0x000001C1, 0x000001C1, 0x000001C1, 0x000001C1, 0x0007002C, 0x00000017, 0x000009CE, + 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, + 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, + 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, + 0x00000A3A, 0x0004002B, 0x0000000B, 0x00000A82, 0x00000028, 0x0005002C, 0x00000011, 0x00000937, + 0x00000A82, 0x00000A3A, 0x0004002B, 0x0000000B, 0x00000184, 0x00000500, 0x0004002B, 0x0000000B, + 0x0000086E, 0x00280000, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, + 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, + 0x00002E68, 0x00050041, 0x00000288, 0x000056E5, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, + 0x00003D0B, 0x000056E5, 0x00050041, 0x00000288, 0x000058AC, 0x00000CE9, 0x00000A0E, 0x0004003D, + 0x0000000B, 0x00005158, 0x000058AC, 0x000500C7, 0x0000000B, 0x00005051, 0x00003D0B, 0x00000A44, + 0x000500C2, 0x0000000B, 0x00004E0A, 0x00003D0B, 0x00000A28, 0x000500C7, 0x0000000B, 0x0000217E, + 0x00004E0A, 0x00000A13, 0x000500C2, 0x0000000B, 0x0000520A, 0x00003D0B, 0x00000A31, 0x000500C7, + 0x0000000B, 0x0000217F, 0x0000520A, 0x00000A81, 0x000500C2, 0x0000000B, 0x00004994, 0x00003D0B, + 0x00000A52, 0x000500C7, 0x0000000B, 0x000023AA, 0x00004994, 0x00000A37, 0x00050050, 0x00000011, + 0x000022A7, 0x00005158, 0x00005158, 0x000500C2, 0x00000011, 0x00002568, 0x000022A7, 0x0000073F, + 0x000500C7, 0x00000011, 0x00005B53, 0x00002568, 0x000007A2, 0x000500C4, 0x00000011, 0x00003F4F, + 0x00005B53, 0x0000074E, 0x00050084, 0x00000011, 0x000059EB, 0x00003F4F, 0x00000724, 0x000500C2, + 0x0000000B, 0x00003213, 0x00005158, 0x00000A19, 0x000500C7, 0x0000000B, 0x00003F4C, 0x00003213, + 0x00000A81, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, + 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x000058AD, 0x00000CE9, 0x00000A14, 0x0004003D, + 0x0000000B, 0x000051B7, 0x000058AD, 0x000500C7, 0x0000000B, 0x00004ADC, 0x00005EAC, 0x00000A1F, + 0x000500C7, 0x0000000B, 0x000055EF, 0x00005EAC, 0x00000A22, 0x000500AB, 0x00000009, 0x0000500F, + 0x000055EF, 0x00000A0A, 0x000500C2, 0x0000000B, 0x000028A2, 0x00005EAC, 0x00000A16, 0x000500C7, + 0x0000000B, 0x000059FD, 0x000028A2, 0x00000A1F, 0x000500C7, 0x0000000B, 0x00005A4E, 0x00005EAC, + 0x00000926, 0x000500AB, 0x00000009, 0x00004C75, 0x00005A4E, 0x00000A0A, 0x000500C7, 0x0000000B, + 0x00001F43, 0x000051B7, 0x00000A44, 0x000500C4, 0x0000000B, 0x00003DA7, 0x00001F43, 0x00000A19, + 0x000500C2, 0x0000000B, 0x0000583F, 0x000051B7, 0x00000A28, 0x000500C7, 0x0000000B, 0x00004BBE, + 0x0000583F, 0x00000A44, 0x000500C4, 0x0000000B, 0x00006273, 0x00004BBE, 0x00000A19, 0x00050050, + 0x00000011, 0x000028B6, 0x000051B7, 0x000051B7, 0x000500C2, 0x00000011, 0x00002891, 0x000028B6, + 0x000008E3, 0x000500C7, 0x00000011, 0x00005B54, 0x00002891, 0x0000084A, 0x000500C4, 0x00000011, + 0x00003F50, 0x00005B54, 0x0000074E, 0x00050084, 0x00000011, 0x000059EC, 0x00003F50, 0x00000724, + 0x000500C2, 0x0000000B, 0x00003214, 0x000051B7, 0x00000A5E, 0x000500C7, 0x0000000B, 0x00003F4D, + 0x00003214, 0x00000A1F, 0x00050041, 0x00000288, 0x000048E0, 0x00000CE9, 0x00000A17, 0x0004003D, + 0x0000000B, 0x000062B6, 0x000048E0, 0x0004003D, 0x00000014, 0x0000374F, 0x00000F48, 0x0007004F, + 0x00000011, 0x00003180, 0x0000374F, 0x0000374F, 0x00000000, 0x00000001, 0x000500C4, 0x00000011, + 0x00002EF9, 0x00003180, 0x00000721, 0x00050051, 0x0000000B, 0x00001DD8, 0x00002EF9, 0x00000000, + 0x000500C4, 0x0000000B, 0x00002D8A, 0x00003F4C, 0x00000A13, 0x000500AE, 0x00000009, 0x00003C13, + 0x00001DD8, 0x00002D8A, 0x000300F7, 0x000031D3, 0x00000002, 0x000400FA, 0x00003C13, 0x000055E8, + 0x000031D3, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000031D3, 0x00050051, + 0x0000000B, 0x00001CAC, 0x00002EF9, 0x00000001, 0x0007000C, 0x0000000B, 0x00001F38, 0x00000001, + 0x00000029, 0x00001CAC, 0x00000A0A, 0x00050050, 0x00000011, 0x000051EF, 0x00001DD8, 0x00001F38, + 0x00050080, 0x00000011, 0x0000522C, 0x000051EF, 0x000059EB, 0x000500B2, 0x00000009, 0x00003ECB, + 0x00003F4D, 0x00000A13, 0x000300F7, 0x00005CE0, 0x00000000, 0x000400FA, 0x00003ECB, 0x00002AEE, + 0x00003AEF, 0x000200F8, 0x00003AEF, 0x000500AA, 0x00000009, 0x000034FE, 0x00003F4D, 0x00000A19, + 0x000600A9, 0x0000000B, 0x000020F6, 0x000034FE, 0x00000A10, 0x00000A0A, 0x000200F9, 0x00005CE0, + 0x000200F8, 0x00002AEE, 0x000200F9, 0x00005CE0, 0x000200F8, 0x00005CE0, 0x000700F5, 0x0000000B, + 0x00004B64, 0x00003F4D, 0x00002AEE, 0x000020F6, 0x00003AEF, 0x00050050, 0x00000011, 0x000041BE, + 0x0000217E, 0x0000217E, 0x000500AE, 0x0000000F, 0x00002E19, 0x000041BE, 0x0000072D, 0x000600A9, + 0x00000011, 0x00004BB5, 0x00002E19, 0x00000724, 0x0000070F, 0x000500C4, 0x00000011, 0x00002AEA, + 0x0000522C, 0x00004BB5, 0x00050050, 0x00000011, 0x0000605D, 0x00004B64, 0x00004B64, 0x000500C2, + 0x00000011, 0x00002385, 0x0000605D, 0x00000718, 0x000500C7, 0x00000011, 0x00003EEE, 0x00002385, + 0x00000724, 0x00050080, 0x00000011, 0x00004573, 0x00002AEA, 0x00003EEE, 0x00050086, 0x00000011, + 0x00005ECE, 0x00004573, 0x00000937, 0x00050051, 0x0000000B, 0x00003048, 0x00005ECE, 0x00000001, + 0x00050084, 0x0000000B, 0x00002B26, 0x00003048, 0x00005051, 0x00050051, 0x0000000B, 0x00006059, + 0x00005ECE, 0x00000000, 0x00050080, 0x0000000B, 0x00005420, 0x00002B26, 0x00006059, 0x00050080, + 0x0000000B, 0x00002226, 0x0000217F, 0x00005420, 0x00050084, 0x00000011, 0x00005B31, 0x00005ECE, + 0x00000937, 0x00050082, 0x00000011, 0x00002E74, 0x00004573, 0x00005B31, 0x00050084, 0x0000000B, + 0x0000233E, 0x00002226, 0x00000184, 0x00050051, 0x0000000B, 0x00003887, 0x00002E74, 0x00000001, + 0x00050084, 0x0000000B, 0x00003E12, 0x00003887, 0x00000A82, 0x00050051, 0x0000000B, 0x00001AE6, + 0x00002E74, 0x00000000, 0x00050080, 0x0000000B, 0x000025E0, 0x00003E12, 0x00001AE6, 0x000500C4, + 0x0000000B, 0x000046C4, 0x000025E0, 0x00000A0D, 0x00050080, 0x0000000B, 0x00004895, 0x0000233E, + 0x000046C4, 0x00050089, 0x0000000B, 0x0000459C, 0x00004895, 0x0000086E, 0x000500C2, 0x0000000B, + 0x00004894, 0x0000459C, 0x00000A10, 0x00060041, 0x00000294, 0x00004316, 0x00000CC7, 0x00000A0B, + 0x00004894, 0x0004003D, 0x00000017, 0x00003141, 0x00004316, 0x00050080, 0x0000000B, 0x00002DA7, + 0x00004894, 0x00000A0D, 0x00060041, 0x00000294, 0x00001C1D, 0x00000CC7, 0x00000A0B, 0x00002DA7, + 0x0004003D, 0x00000017, 0x000047B8, 0x00001C1D, 0x000500AA, 0x00000009, 0x00003C70, 0x00001DD8, + 0x00000A0A, 0x000600A9, 0x00000009, 0x00003CF3, 0x00003C70, 0x00000787, 0x00003C70, 0x000300F7, + 0x00005596, 0x00000002, 0x000400FA, 0x00003CF3, 0x00002620, 0x00005596, 0x000200F8, 0x00002620, + 0x00050051, 0x0000000B, 0x0000438A, 0x00003141, 0x00000002, 0x00060052, 0x00000017, 0x000052B6, + 0x0000438A, 0x00003141, 0x00000000, 0x00050051, 0x0000000B, 0x00005A04, 0x00003141, 0x00000003, + 0x00060052, 0x00000017, 0x00002450, 0x00005A04, 0x000052B6, 0x00000001, 0x000200F9, 0x00005596, + 0x000200F8, 0x00005596, 0x000700F5, 0x00000017, 0x00002AAC, 0x00003141, 0x00005CE0, 0x00002450, + 0x00002620, 0x000300F7, 0x0000530F, 0x00000002, 0x000400FA, 0x00004C75, 0x00003ADC, 0x0000530F, + 0x000200F8, 0x00003ADC, 0x000500AA, 0x00000009, 0x00003585, 0x000023AA, 0x00000A19, 0x000400A8, + 0x00000009, 0x00004277, 0x00003585, 0x000300F7, 0x00003D52, 0x00000000, 0x000400FA, 0x00004277, + 0x000040DF, 0x00003D52, 0x000200F8, 0x000040DF, 0x000500AA, 0x00000009, 0x0000495A, 0x000023AA, + 0x00000A1F, 0x000200F9, 0x00003D52, 0x000200F8, 0x00003D52, 0x000700F5, 0x00000009, 0x00002AAD, + 0x00003585, 0x00003ADC, 0x0000495A, 0x000040DF, 0x000300F7, 0x000039F4, 0x00000002, 0x000400FA, + 0x00002AAD, 0x000020A8, 0x000039F4, 0x000200F8, 0x000020A8, 0x000500C7, 0x00000017, 0x00004BF1, + 0x00002AAC, 0x00000755, 0x0009004F, 0x00000017, 0x000051EA, 0x00002AAC, 0x00002AAC, 0x00000001, + 0x00000000, 0x00000003, 0x00000002, 0x000500C7, 0x00000017, 0x00001CED, 0x000051EA, 0x00000352, + 0x000500C5, 0x00000017, 0x00003640, 0x00004BF1, 0x00001CED, 0x000500C7, 0x00000017, 0x00005311, + 0x000047B8, 0x00000755, 0x0009004F, 0x00000017, 0x00003BF8, 0x000047B8, 0x000047B8, 0x00000001, + 0x00000000, 0x00000003, 0x00000002, 0x000500C7, 0x00000017, 0x000020A3, 0x00003BF8, 0x00000352, + 0x000500C5, 0x00000017, 0x00002101, 0x00005311, 0x000020A3, 0x000200F9, 0x000039F4, 0x000200F8, + 0x000039F4, 0x000700F5, 0x00000017, 0x00002BF3, 0x000047B8, 0x00003D52, 0x00002101, 0x000020A8, + 0x000700F5, 0x00000017, 0x0000358D, 0x00002AAC, 0x00003D52, 0x00003640, 0x000020A8, 0x000200F9, + 0x0000530F, 0x000200F8, 0x0000530F, 0x000700F5, 0x00000017, 0x000022F8, 0x000047B8, 0x00005596, + 0x00002BF3, 0x000039F4, 0x000700F5, 0x00000017, 0x000055F9, 0x00002AAC, 0x00005596, 0x0000358D, + 0x000039F4, 0x00050080, 0x00000011, 0x00001C97, 0x00002EF9, 0x000059EC, 0x000300F7, 0x000052F5, + 0x00000002, 0x000400FA, 0x0000500F, 0x0000294E, 0x0000537D, 0x000200F8, 0x0000537D, 0x0004007C, + 0x00000012, 0x00002970, 0x00001C97, 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000000, + 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, + 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, + 0x0000000B, 0x00005B4D, 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, + 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003F5E, + 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A28, 0x000500C7, + 0x0000000C, 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x00002747, + 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, + 0x00004397, 0x00002AB6, 0x0000454D, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A13, + 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, + 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00004A8E, 0x00002F76, 0x000500C7, + 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4B, + 0x00003397, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544A, 0x000047B4, 0x00000A17, 0x00050080, 0x0000000C, 0x00004157, 0x00004D30, 0x0000544A, + 0x000500C7, 0x0000000C, 0x00005022, 0x00004157, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, + 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, + 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x00004158, 0x00002416, + 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADD, 0x00004157, 0x00000388, 0x000500C4, 0x0000000C, + 0x0000544B, 0x00004ADD, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x00004158, 0x0000544B, + 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, + 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, + 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544C, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, + 0x00003C4C, 0x00004144, 0x0000544C, 0x000500C7, 0x0000000C, 0x00002E06, 0x00004157, 0x00000AC8, + 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4C, 0x00002E06, 0x0004007C, 0x0000000B, 0x0000566F, + 0x0000394F, 0x000200F9, 0x000052F5, 0x000200F8, 0x0000294E, 0x00050051, 0x0000000B, 0x00004D9A, + 0x00001C97, 0x00000000, 0x00050051, 0x0000000B, 0x00002C03, 0x00001C97, 0x00000001, 0x00060050, + 0x00000014, 0x000020DE, 0x00004D9A, 0x00002C03, 0x000059FD, 0x0004007C, 0x00000016, 0x00004E9D, + 0x000020DE, 0x00050051, 0x0000000C, 0x000028C6, 0x00004E9D, 0x00000001, 0x000500C3, 0x0000000C, + 0x000024FE, 0x000028C6, 0x00000A17, 0x00050051, 0x0000000C, 0x00002748, 0x00004E9D, 0x00000002, + 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4E, + 0x00006273, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, + 0x00005321, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FE, 0x00005321, + 0x000500C2, 0x0000000B, 0x00002348, 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, + 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, + 0x00006242, 0x00004E9D, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, + 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, + 0x000049FC, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, + 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, + 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x000028C6, 0x00000A1D, 0x000500C4, 0x0000000C, + 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454E, + 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A25, 0x000500C3, 0x0000000C, 0x00005DE3, + 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000028C6, 0x00000A14, 0x00050080, + 0x0000000C, 0x000035A3, 0x00002215, 0x0000405D, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, + 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, + 0x000500C7, 0x0000000C, 0x00004ADE, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544D, + 0x00004ADE, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4D, 0x00005A0C, 0x0000544D, 0x000500C7, + 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, + 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B32, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, + 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B32, 0x00005AEA, + 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544E, + 0x000047B5, 0x00000A25, 0x00050080, 0x0000000C, 0x00004159, 0x0000285C, 0x0000544E, 0x000500C7, + 0x0000000C, 0x00004ADF, 0x000028C6, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544F, 0x00004ADF, + 0x00000A17, 0x00050080, 0x0000000C, 0x0000415A, 0x00004159, 0x0000544F, 0x000500C7, 0x0000000C, + 0x00004FD6, 0x00003C4D, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, + 0x000500C3, 0x0000000C, 0x00003332, 0x0000415A, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, + 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, + 0x0000000C, 0x00005B33, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4D, + 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B33, 0x00005AB1, 0x000500C4, 0x0000000C, + 0x00005B34, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x0000415A, 0x0000040B, + 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B34, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B35, + 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x0000415A, 0x00000AC8, 0x00050080, + 0x0000000C, 0x00005EFA, 0x00005B35, 0x00005559, 0x0004007C, 0x0000000B, 0x00005670, 0x00005EFA, + 0x000200F9, 0x000052F5, 0x000200F8, 0x000052F5, 0x000700F5, 0x0000000B, 0x00002C70, 0x00005670, + 0x0000294E, 0x0000566F, 0x0000537D, 0x00050080, 0x0000000B, 0x00005088, 0x00002C70, 0x000062B6, + 0x000500C2, 0x0000000B, 0x00004EAA, 0x00005088, 0x00000A16, 0x000500AA, 0x00000009, 0x00004B9C, + 0x00004ADC, 0x00000A16, 0x000300F7, 0x000039BC, 0x00000000, 0x000400FA, 0x00004B9C, 0x000033DF, + 0x000039BC, 0x000200F8, 0x000033DF, 0x0009004F, 0x00000017, 0x00001F16, 0x000055F9, 0x000055F9, + 0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x000200F9, 0x000039BC, 0x000200F8, 0x000039BC, + 0x000700F5, 0x00000017, 0x00005972, 0x000055F9, 0x000052F5, 0x00001F16, 0x000033DF, 0x000600A9, + 0x0000000B, 0x000019CD, 0x00004B9C, 0x00000A10, 0x00004ADC, 0x000500AA, 0x00000009, 0x00003464, + 0x000019CD, 0x00000A0D, 0x000500AA, 0x00000009, 0x000047C2, 0x000019CD, 0x00000A10, 0x000500A6, + 0x00000009, 0x00005686, 0x00003464, 0x000047C2, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, + 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, + 0x00005972, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, + 0x00000017, 0x000050AC, 0x00005972, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, + 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, + 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00005972, 0x000039BC, 0x00003FF8, + 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000019CD, 0x00000A13, 0x000500A6, 0x00000009, + 0x00003B23, 0x000047C2, 0x00004CB6, 0x000300F7, 0x00002C98, 0x00000000, 0x000400FA, 0x00003B23, + 0x00002B38, 0x00002C98, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, + 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, + 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x00002C98, 0x000200F8, 0x00002C98, 0x000700F5, + 0x00000017, 0x00004D37, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x00060041, 0x00000294, + 0x000060F9, 0x00001592, 0x00000A0B, 0x00004EAA, 0x0003003E, 0x000060F9, 0x00004D37, 0x00050080, + 0x0000000B, 0x000054B5, 0x00004EAA, 0x00000A10, 0x000300F7, 0x00003F86, 0x00000000, 0x000400FA, + 0x00004B9C, 0x000033E0, 0x00003F86, 0x000200F8, 0x000033E0, 0x0009004F, 0x00000017, 0x00001F17, + 0x000022F8, 0x000022F8, 0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x000200F9, 0x00003F86, + 0x000200F8, 0x00003F86, 0x000700F5, 0x00000017, 0x00002AAE, 0x000022F8, 0x00002C98, 0x00001F17, + 0x000033E0, 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, + 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x00002AAE, 0x000009CE, 0x000500C4, + 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x00002AAE, + 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, + 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, + 0x00000017, 0x00002AAF, 0x00002AAE, 0x00003F86, 0x00003FF9, 0x00002958, 0x000300F7, 0x00002C99, + 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, 0x00002C99, 0x000200F8, 0x00002B39, 0x000500C4, + 0x00000017, 0x00005E18, 0x00002AAF, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAF, + 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002C99, + 0x000200F8, 0x00002C99, 0x000700F5, 0x00000017, 0x00004D39, 0x00002AAF, 0x00003A1A, 0x000029E9, + 0x00002B39, 0x00060041, 0x00000294, 0x00001F75, 0x00001592, 0x00000A0B, 0x000054B5, 0x0003003E, + 0x00001F75, 0x00004D39, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_fast_64bpp_1x2xmsaa_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_fast_64bpp_1x2xmsaa_scaled_cs.h new file mode 100644 index 0000000..602b9ef --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_fast_64bpp_1x2xmsaa_scaled_cs.h @@ -0,0 +1,867 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25204 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_struct_1017 Block + OpMemberDecorate %_struct_1017 0 Offset 0 + OpMemberDecorate %_struct_1017 1 Offset 4 + OpMemberDecorate %_struct_1017 2 Offset 8 + OpMemberDecorate %_struct_1017 3 Offset 12 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %3271 NonWritable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5522 NonReadable + OpDecorate %5522 Binding 0 + OpDecorate %5522 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %bool = OpTypeBool + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %v3uint = OpTypeVector %uint 3 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_4 = OpConstant %uint 4 + %1837 = OpConstantComposite %v2uint %uint_2 %uint_1 + %v2bool = OpTypeVector %bool 2 + %uint_0 = OpConstant %uint 0 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %uint_80 = OpConstant %uint 80 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %uint_2048 = OpConstant %uint 2048 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1017 = OpTypeStruct %uint %uint %uint %uint +%_ptr_PushConstant__struct_1017 = OpTypePointer PushConstant %_struct_1017 + %3305 = OpVariable %_ptr_PushConstant__struct_1017 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %uint_1023 = OpConstant %uint 1023 + %uint_10 = OpConstant %uint 10 + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_24 = OpConstant %uint 24 + %uint_15 = OpConstant %uint 15 + %uint_28 = OpConstant %uint 28 + %uint_19 = OpConstant %uint 19 + %2179 = OpConstantComposite %v2uint %uint_16 %uint_19 +%uint_536870912 = OpConstant %uint 536870912 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 +%uint_16777216 = OpConstant %uint 16777216 + %uint_20 = OpConstant %uint 20 + %2275 = OpConstantComposite %v2uint %uint_20 %uint_24 +%uint_4294901760 = OpConstant %uint 4294901760 + %uint_65535 = OpConstant %uint 65535 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %1825 = OpConstantComposite %v2uint %uint_2 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %3271 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5522 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %1955 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %uint_9 = OpConstant %uint 9 + %1877 = OpConstantComposite %v4uint %uint_4294901760 %uint_4294901760 %uint_4294901760 %uint_4294901760 + %850 = OpConstantComposite %v4uint %uint_65535 %uint_65535 %uint_65535 %uint_65535 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %19978 = OpShiftRightLogical %uint %15627 %uint_10 + %8574 = OpBitwiseAnd %uint %19978 %uint_3 + %21002 = OpShiftRightLogical %uint %15627 %uint_13 + %8575 = OpBitwiseAnd %uint %21002 %uint_2047 + %18836 = OpShiftRightLogical %uint %15627 %uint_24 + %9130 = OpBitwiseAnd %uint %18836 %uint_15 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9633 = OpShiftRightLogical %v2uint %8871 %2179 + %23601 = OpBitwiseAnd %v2uint %9633 %1954 + %24030 = OpBitwiseAnd %uint %15627 %uint_536870912 + %12295 = OpINotEqual %bool %24030 %uint_0 + OpSelectionMerge %14676 None + OpBranchConditional %12295 %16739 %21992 + %21992 = OpLabel + OpBranch %14676 + %16739 = OpLabel + %15278 = OpShiftRightLogical %v2uint %23601 %1828 + OpBranch %14676 + %14676 = OpLabel + %19124 = OpPhi %v2uint %15278 %16739 %1807 %21992 + %7038 = OpShiftRightLogical %v2uint %8871 %1855 + %11769 = OpBitwiseAnd %v2uint %7038 %1955 + %16207 = OpShiftLeftLogical %v2uint %11769 %1870 + %23019 = OpIMul %v2uint %16207 %23601 + %13123 = OpShiftRightLogical %uint %20824 %uint_5 + %14785 = OpBitwiseAnd %uint %13123 %uint_2047 + %8858 = OpCompositeExtract %uint %23601 0 + %22993 = OpIMul %uint %14785 %8858 + %20036 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %18628 = OpLoad %uint %20036 + %22701 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %20919 = OpLoad %uint %22701 + %19164 = OpBitwiseAnd %uint %18628 %uint_7 + %21999 = OpBitwiseAnd %uint %18628 %uint_8 + %20495 = OpINotEqual %bool %21999 %uint_0 + %10402 = OpShiftRightLogical %uint %18628 %uint_4 + %23037 = OpBitwiseAnd %uint %10402 %uint_7 + %23118 = OpBitwiseAnd %uint %18628 %uint_16777216 + %19573 = OpINotEqual %bool %23118 %uint_0 + %8003 = OpBitwiseAnd %uint %20919 %uint_1023 + %15783 = OpShiftLeftLogical %uint %8003 %uint_5 + %22591 = OpShiftRightLogical %uint %20919 %uint_10 + %19390 = OpBitwiseAnd %uint %22591 %uint_1023 + %25203 = OpShiftLeftLogical %uint %19390 %uint_5 + %10422 = OpCompositeConstruct %v2uint %20919 %20919 + %10385 = OpShiftRightLogical %v2uint %10422 %2275 + %23379 = OpBitwiseAnd %v2uint %10385 %2122 + %16208 = OpShiftLeftLogical %v2uint %23379 %1870 + %23020 = OpIMul %v2uint %16208 %23601 + %12743 = OpShiftRightLogical %uint %20919 %uint_28 + %17238 = OpBitwiseAnd %uint %12743 %uint_7 + %12737 = OpLoad %v3uint %gl_GlobalInvocationID + %14500 = OpVectorShuffle %v2uint %12737 %12737 0 1 + %12025 = OpShiftLeftLogical %v2uint %14500 %1825 + %7640 = OpCompositeExtract %uint %12025 0 + %11658 = OpShiftLeftLogical %uint %22993 %uint_3 + %15379 = OpUGreaterThanEqual %bool %7640 %11658 + OpSelectionMerge %14025 DontFlatten + OpBranchConditional %15379 %21993 %14025 + %21993 = OpLabel + OpBranch %19578 + %14025 = OpLabel + %18615 = OpCompositeExtract %uint %12025 1 + %16803 = OpCompositeExtract %uint %19124 1 + %24446 = OpExtInst %uint %1 UMax %18615 %16803 + %20975 = OpCompositeConstruct %v2uint %7640 %24446 + %21036 = OpIAdd %v2uint %20975 %23019 + %16075 = OpULessThanEqual %bool %17238 %uint_3 + OpSelectionMerge %23776 None + OpBranchConditional %16075 %10990 %15087 + %15087 = OpLabel + %13566 = OpIEqual %bool %17238 %uint_5 + %8438 = OpSelect %uint %13566 %uint_2 %uint_0 + OpBranch %23776 + %10990 = OpLabel + OpBranch %23776 + %23776 = OpLabel + %19300 = OpPhi %uint %17238 %10990 %8438 %15087 + %16830 = OpCompositeConstruct %v2uint %8574 %8574 + %11801 = OpUGreaterThanEqual %v2bool %16830 %1837 + %19381 = OpSelect %v2uint %11801 %1828 %1807 + %10986 = OpShiftLeftLogical %v2uint %21036 %19381 + %24669 = OpCompositeConstruct %v2uint %19300 %19300 + %9093 = OpShiftRightLogical %v2uint %24669 %1816 + %16072 = OpBitwiseAnd %v2uint %9093 %1828 + %20272 = OpIAdd %v2uint %10986 %16072 + %21145 = OpIMul %v2uint %2719 %23601 + %14725 = OpShiftRightLogical %v2uint %21145 %1816 + %19799 = OpUDiv %v2uint %20272 %14725 + %20390 = OpCompositeExtract %uint %19799 1 + %11046 = OpIMul %uint %20390 %20561 + %24665 = OpCompositeExtract %uint %19799 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %8575 %21536 + %22376 = OpIMul %v2uint %19799 %14725 + %20715 = OpISub %v2uint %20272 %22376 + %7303 = OpCompositeExtract %uint %21145 0 + %22882 = OpCompositeExtract %uint %21145 1 + %13170 = OpIMul %uint %7303 %22882 + %14551 = OpIMul %uint %8742 %13170 + %6805 = OpCompositeExtract %uint %20715 1 + %23526 = OpCompositeExtract %uint %14725 0 + %22886 = OpIMul %uint %6805 %23526 + %6886 = OpCompositeExtract %uint %20715 0 + %9696 = OpIAdd %uint %22886 %6886 + %18021 = OpShiftLeftLogical %uint %9696 %uint_1 + %18363 = OpIAdd %uint %14551 %18021 + %13884 = OpIMul %uint %13170 %uint_2048 + %19795 = OpUMod %uint %18363 %13884 + %21806 = OpShiftRightLogical %uint %19795 %uint_2 + %17174 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %21806 + %12609 = OpLoad %v4uint %17174 + %11687 = OpIAdd %uint %21806 %uint_1 + %7197 = OpAccessChain %_ptr_Uniform_v4uint %3271 %int_0 %11687 + %19842 = OpLoad %v4uint %7197 + %21106 = OpIEqual %bool %7640 %uint_0 + OpSelectionMerge %13276 None + OpBranchConditional %21106 %11451 %13276 + %11451 = OpLabel + %24156 = OpCompositeExtract %uint %19124 0 + %22470 = OpINotEqual %bool %24156 %uint_0 + OpBranch %13276 + %13276 = OpLabel + %10924 = OpPhi %bool %21106 %23776 %22470 %11451 + OpSelectionMerge %21873 DontFlatten + OpBranchConditional %10924 %11508 %21873 + %11508 = OpLabel + %23599 = OpCompositeExtract %uint %19124 0 + %17346 = OpUGreaterThanEqual %bool %23599 %uint_2 + OpSelectionMerge %21872 None + OpBranchConditional %17346 %15877 %21872 + %15877 = OpLabel + %24532 = OpUGreaterThanEqual %bool %23599 %uint_3 + OpSelectionMerge %18756 None + OpBranchConditional %24532 %9760 %18756 + %9760 = OpLabel + %17290 = OpCompositeExtract %uint %19842 2 + %21174 = OpCompositeInsert %v4uint %17290 %19842 0 + %23044 = OpCompositeExtract %uint %19842 3 + %9296 = OpCompositeInsert %v4uint %23044 %21174 1 + OpBranch %18756 + %18756 = OpLabel + %17379 = OpPhi %v4uint %19842 %15877 %9296 %9760 + %22881 = OpCompositeExtract %uint %17379 0 + %21983 = OpCompositeInsert %v4uint %22881 %12609 2 + %23045 = OpCompositeExtract %uint %17379 1 + %9297 = OpCompositeInsert %v4uint %23045 %21983 3 + OpBranch %21872 + %21872 = OpLabel + %8059 = OpPhi %v4uint %19842 %11508 %17379 %18756 + %7934 = OpPhi %v4uint %12609 %11508 %9297 %18756 + %23690 = OpCompositeExtract %uint %7934 2 + %21984 = OpCompositeInsert %v4uint %23690 %7934 0 + %23046 = OpCompositeExtract %uint %7934 3 + %9298 = OpCompositeInsert %v4uint %23046 %21984 1 + OpBranch %21873 + %21873 = OpLabel + %11213 = OpPhi %v4uint %19842 %13276 %8059 %21872 + %14093 = OpPhi %v4uint %12609 %13276 %9298 %21872 + OpSelectionMerge %21263 DontFlatten + OpBranchConditional %19573 %15068 %21263 + %15068 = OpLabel + %13701 = OpIEqual %bool %9130 %uint_5 + %17015 = OpLogicalNot %bool %13701 + OpSelectionMerge %15698 None + OpBranchConditional %17015 %16607 %15698 + %16607 = OpLabel + %18778 = OpIEqual %bool %9130 %uint_7 + OpBranch %15698 + %15698 = OpLabel + %10925 = OpPhi %bool %13701 %15068 %18778 %16607 + OpSelectionMerge %14836 DontFlatten + OpBranchConditional %10925 %8360 %14836 + %8360 = OpLabel + %19441 = OpBitwiseAnd %v4uint %14093 %1877 + %20970 = OpVectorShuffle %v4uint %14093 %14093 1 0 3 2 + %7405 = OpBitwiseAnd %v4uint %20970 %850 + %13888 = OpBitwiseOr %v4uint %19441 %7405 + %21265 = OpBitwiseAnd %v4uint %11213 %1877 + %15352 = OpVectorShuffle %v4uint %11213 %11213 1 0 3 2 + %8355 = OpBitwiseAnd %v4uint %15352 %850 + %8449 = OpBitwiseOr %v4uint %21265 %8355 + OpBranch %14836 + %14836 = OpLabel + %11251 = OpPhi %v4uint %11213 %15698 %8449 %8360 + %13709 = OpPhi %v4uint %14093 %15698 %13888 %8360 + OpBranch %21263 + %21263 = OpLabel + %8952 = OpPhi %v4uint %11213 %21873 %11251 %14836 + %18855 = OpPhi %v4uint %14093 %21873 %13709 %14836 + %13755 = OpIAdd %v2uint %12025 %23020 + %13244 = OpCompositeExtract %uint %13755 0 + %9555 = OpCompositeExtract %uint %13755 1 + %11053 = OpShiftRightLogical %uint %13244 %uint_1 + %7832 = OpCompositeConstruct %v2uint %11053 %9555 + %24920 = OpUDiv %v2uint %7832 %23601 + %13932 = OpCompositeExtract %uint %24920 0 + %19770 = OpShiftLeftLogical %uint %13932 %uint_1 + %24251 = OpCompositeExtract %uint %24920 1 + %21452 = OpCompositeConstruct %v3uint %19770 %24251 %23037 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %20495 %22206 %10904 + %10904 = OpLabel + %7339 = OpVectorShuffle %v2uint %21452 %21452 0 1 + %22991 = OpBitcast %v2int %7339 + %6403 = OpCompositeExtract %int %22991 0 + %9469 = OpShiftRightArithmetic %int %6403 %int_5 + %10055 = OpCompositeExtract %int %22991 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %15783 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_10 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17303 = OpIAdd %int %10934 %17741 + %6375 = OpShiftLeftLogical %int %17303 %uint_3 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15435 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18356 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18356 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12151 + %19165 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19165 %int_2 + %16708 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21587 %int_6 + %15436 = OpIAdd %int %16708 %21580 + %11782 = OpBitwiseAnd %int %16727 %int_63 + %14671 = OpIAdd %int %15436 %11782 + %22127 = OpBitcast %uint %14671 + OpBranch %21313 + %22206 = OpLabel + %6573 = OpBitcast %v3int %21452 + %17090 = OpCompositeExtract %int %6573 1 + %9470 = OpShiftRightArithmetic %int %17090 %int_4 + %10056 = OpCompositeExtract %int %6573 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %25203 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %15783 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %6573 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_9 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12601 = OpBitwiseAnd %int %17090 %int_6 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7048 = OpShiftLeftLogical %int %17227 %uint_9 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19166 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19166 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18357 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18357 %uint_9 + %16729 = OpIAdd %int %10332 %21582 + %19167 = OpBitwiseAnd %int %17090 %int_1 + %21583 = OpShiftLeftLogical %int %19167 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16730 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22128 = OpBitcast %uint %24314 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22128 %22206 %22127 %10904 + %16296 = OpIMul %v2uint %24920 %23601 + %16261 = OpISub %v2uint %7832 %16296 + %17551 = OpCompositeExtract %uint %23601 1 + %23632 = OpIMul %uint %8858 %17551 + %15520 = OpIMul %uint %9468 %23632 + %16084 = OpCompositeExtract %uint %16261 0 + %15890 = OpIMul %uint %16084 %17551 + %6887 = OpCompositeExtract %uint %16261 1 + %11045 = OpIAdd %uint %15890 %6887 + %24733 = OpShiftLeftLogical %uint %11045 %uint_1 + %23219 = OpBitwiseAnd %uint %13244 %uint_1 + %9559 = OpIAdd %uint %24733 %23219 + %17811 = OpShiftLeftLogical %uint %9559 %uint_3 + %8264 = OpIAdd %uint %15520 %17811 + %9676 = OpShiftRightLogical %uint %8264 %uint_4 + %19356 = OpIEqual %bool %19164 %uint_4 + OpSelectionMerge %14780 None + OpBranchConditional %19356 %13279 %14780 + %13279 = OpLabel + %7958 = OpVectorShuffle %v4uint %18855 %18855 1 0 3 2 + OpBranch %14780 + %14780 = OpLabel + %22898 = OpPhi %v4uint %18855 %21313 %7958 %13279 + %6605 = OpSelect %uint %19356 %uint_2 %19164 + %13412 = OpIEqual %bool %6605 %uint_1 + %18370 = OpIEqual %bool %6605 %uint_2 + %22150 = OpLogicalOr %bool %13412 %18370 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %22898 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %22898 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %22898 %14780 %16376 %10583 + %19638 = OpIEqual %bool %6605 %uint_3 + %15139 = OpLogicalOr %bool %18370 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %6590 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %9676 + OpStore %6590 %19767 + %23542 = OpUGreaterThan %bool %8858 %uint_1 + OpSelectionMerge %19116 DontFlatten + OpBranchConditional %23542 %14554 %21994 + %21994 = OpLabel + OpBranch %19116 + %14554 = OpLabel + %13898 = OpShiftRightLogical %uint %7640 %uint_1 + %7937 = OpUDiv %uint %13898 %8858 + %16891 = OpIMul %uint %7937 %8858 + %12657 = OpISub %uint %13898 %16891 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %8858 + OpSelectionMerge %9304 None + OpBranchConditional %13375 %7387 %21995 + %21995 = OpLabel + OpBranch %9304 + %7387 = OpLabel + %15254 = OpIMul %uint %uint_32 %8858 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18757 = OpISub %uint %15254 %21519 + OpBranch %9304 + %9304 = OpLabel + %10540 = OpPhi %uint %18757 %7387 %uint_16 %21995 + OpBranch %19116 + %19116 = OpLabel + %10684 = OpPhi %uint %10540 %9304 %uint_32 %21994 + %18731 = OpIMul %uint %10684 %17551 + %19951 = OpShiftRightLogical %uint %18731 %uint_4 + %23410 = OpIAdd %uint %9676 %19951 + OpSelectionMerge %16262 None + OpBranchConditional %19356 %13280 %16262 + %13280 = OpLabel + %7959 = OpVectorShuffle %v4uint %8952 %8952 1 0 3 2 + OpBranch %16262 + %16262 = OpLabel + %10926 = OpPhi %v4uint %8952 %19116 %7959 %13280 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %10926 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %10926 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10927 = OpPhi %v4uint %10926 %16262 %16377 %10584 + OpSelectionMerge %11417 None + OpBranchConditional %15139 %11065 %11417 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10927 %749 + %15336 = OpShiftRightLogical %v4uint %10927 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %10927 %14874 %10729 %11065 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %23410 + OpStore %8053 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_fast_64bpp_1x2xmsaa_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006274, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00030047, 0x000003F9, 0x00000002, 0x00050048, + 0x000003F9, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x000003F9, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x000003F9, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x000003F9, + 0x00000003, 0x00000023, 0x0000000C, 0x00040047, 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, + 0x000007DC, 0x00000006, 0x00000010, 0x00030047, 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, + 0x00000000, 0x00000018, 0x00050048, 0x000007B4, 0x00000000, 0x00000023, 0x00000000, 0x00030047, + 0x00000CC7, 0x00000018, 0x00040047, 0x00000CC7, 0x00000021, 0x00000000, 0x00040047, 0x00000CC7, + 0x00000022, 0x00000000, 0x00040047, 0x000007DD, 0x00000006, 0x00000010, 0x00030047, 0x000007B5, + 0x00000003, 0x00040048, 0x000007B5, 0x00000000, 0x00000019, 0x00050048, 0x000007B5, 0x00000000, + 0x00000023, 0x00000000, 0x00030047, 0x00001592, 0x00000019, 0x00040047, 0x00001592, 0x00000021, + 0x00000000, 0x00040047, 0x00001592, 0x00000022, 0x00000001, 0x00040047, 0x00000AC7, 0x0000000B, + 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000B, + 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00020014, 0x00000009, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, + 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, + 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, + 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0005002C, 0x00000011, 0x0000072D, 0x00000A10, + 0x00000A0D, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A0A, + 0x00000000, 0x0005002C, 0x00000011, 0x0000070F, 0x00000A0A, 0x00000A0A, 0x0005002C, 0x00000011, + 0x00000724, 0x00000A0D, 0x00000A0D, 0x0005002C, 0x00000011, 0x00000718, 0x00000A0D, 0x00000A0A, + 0x0004002B, 0x0000000B, 0x00000AFA, 0x00000050, 0x0005002C, 0x00000011, 0x00000A9F, 0x00000AFA, + 0x00000A3A, 0x0004002B, 0x0000000B, 0x00000A84, 0x00000800, 0x0004002B, 0x0000000C, 0x00000A1A, + 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, + 0x00000007, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, + 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, + 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, + 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, + 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, + 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, + 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, + 0x0000003F, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, + 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0006001E, 0x000003F9, 0x0000000B, + 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000676, 0x00000009, 0x000003F9, 0x0004003B, + 0x00000676, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, + 0x00000288, 0x00000009, 0x0000000B, 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, 0x0004002B, + 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, 0x0004002B, + 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A52, 0x00000018, 0x0004002B, + 0x0000000B, 0x00000A37, 0x0000000F, 0x0004002B, 0x0000000B, 0x00000A5E, 0x0000001C, 0x0004002B, + 0x0000000B, 0x00000A43, 0x00000013, 0x0005002C, 0x00000011, 0x00000883, 0x00000A3A, 0x00000A43, + 0x0004002B, 0x0000000B, 0x00000510, 0x20000000, 0x0005002C, 0x00000011, 0x0000073F, 0x00000A0A, + 0x00000A16, 0x0004002B, 0x0000000B, 0x00000926, 0x01000000, 0x0004002B, 0x0000000B, 0x00000A46, + 0x00000014, 0x0005002C, 0x00000011, 0x000008E3, 0x00000A46, 0x00000A52, 0x0004002B, 0x0000000B, + 0x0000068D, 0xFFFF0000, 0x0004002B, 0x0000000B, 0x000001C1, 0x0000FFFF, 0x00040020, 0x00000291, + 0x00000001, 0x00000014, 0x0004003B, 0x00000291, 0x00000F48, 0x00000001, 0x0005002C, 0x00000011, + 0x00000721, 0x00000A10, 0x00000A0A, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, + 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A32, 0x00000CC7, + 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, + 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A33, 0x00000002, 0x000007B5, 0x0004003B, + 0x00000A33, 0x00001592, 0x00000002, 0x0006002C, 0x00000014, 0x00000AC7, 0x00000A22, 0x00000A22, + 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0005002C, 0x00000011, + 0x000007A3, 0x00000A37, 0x00000A0D, 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, + 0x0005002C, 0x00000011, 0x0000084A, 0x00000A37, 0x00000A37, 0x0004002B, 0x0000000B, 0x00000A25, + 0x00000009, 0x0007002C, 0x00000017, 0x00000755, 0x0000068D, 0x0000068D, 0x0000068D, 0x0000068D, + 0x0007002C, 0x00000017, 0x00000352, 0x000001C1, 0x000001C1, 0x000001C1, 0x000001C1, 0x0007002C, + 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, + 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, + 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, + 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, + 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000056E5, 0x00000CE9, 0x00000A0B, 0x0004003D, + 0x0000000B, 0x00003D0B, 0x000056E5, 0x00050041, 0x00000288, 0x000058AC, 0x00000CE9, 0x00000A0E, + 0x0004003D, 0x0000000B, 0x00005158, 0x000058AC, 0x000500C7, 0x0000000B, 0x00005051, 0x00003D0B, + 0x00000A44, 0x000500C2, 0x0000000B, 0x00004E0A, 0x00003D0B, 0x00000A28, 0x000500C7, 0x0000000B, + 0x0000217E, 0x00004E0A, 0x00000A13, 0x000500C2, 0x0000000B, 0x0000520A, 0x00003D0B, 0x00000A31, + 0x000500C7, 0x0000000B, 0x0000217F, 0x0000520A, 0x00000A81, 0x000500C2, 0x0000000B, 0x00004994, + 0x00003D0B, 0x00000A52, 0x000500C7, 0x0000000B, 0x000023AA, 0x00004994, 0x00000A37, 0x00050050, + 0x00000011, 0x000022A7, 0x00005158, 0x00005158, 0x000500C2, 0x00000011, 0x000025A1, 0x000022A7, + 0x00000883, 0x000500C7, 0x00000011, 0x00005C31, 0x000025A1, 0x000007A2, 0x000500C7, 0x0000000B, + 0x00005DDE, 0x00003D0B, 0x00000510, 0x000500AB, 0x00000009, 0x00003007, 0x00005DDE, 0x00000A0A, + 0x000300F7, 0x00003954, 0x00000000, 0x000400FA, 0x00003007, 0x00004163, 0x000055E8, 0x000200F8, + 0x000055E8, 0x000200F9, 0x00003954, 0x000200F8, 0x00004163, 0x000500C2, 0x00000011, 0x00003BAE, + 0x00005C31, 0x00000724, 0x000200F9, 0x00003954, 0x000200F8, 0x00003954, 0x000700F5, 0x00000011, + 0x00004AB4, 0x00003BAE, 0x00004163, 0x0000070F, 0x000055E8, 0x000500C2, 0x00000011, 0x00001B7E, + 0x000022A7, 0x0000073F, 0x000500C7, 0x00000011, 0x00002DF9, 0x00001B7E, 0x000007A3, 0x000500C4, + 0x00000011, 0x00003F4F, 0x00002DF9, 0x0000074E, 0x00050084, 0x00000011, 0x000059EB, 0x00003F4F, + 0x00005C31, 0x000500C2, 0x0000000B, 0x00003343, 0x00005158, 0x00000A19, 0x000500C7, 0x0000000B, + 0x000039C1, 0x00003343, 0x00000A81, 0x00050051, 0x0000000B, 0x0000229A, 0x00005C31, 0x00000000, + 0x00050084, 0x0000000B, 0x000059D1, 0x000039C1, 0x0000229A, 0x00050041, 0x00000288, 0x00004E44, + 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x000048C4, 0x00004E44, 0x00050041, 0x00000288, + 0x000058AD, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x000051B7, 0x000058AD, 0x000500C7, + 0x0000000B, 0x00004ADC, 0x000048C4, 0x00000A1F, 0x000500C7, 0x0000000B, 0x000055EF, 0x000048C4, + 0x00000A22, 0x000500AB, 0x00000009, 0x0000500F, 0x000055EF, 0x00000A0A, 0x000500C2, 0x0000000B, + 0x000028A2, 0x000048C4, 0x00000A16, 0x000500C7, 0x0000000B, 0x000059FD, 0x000028A2, 0x00000A1F, + 0x000500C7, 0x0000000B, 0x00005A4E, 0x000048C4, 0x00000926, 0x000500AB, 0x00000009, 0x00004C75, + 0x00005A4E, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00001F43, 0x000051B7, 0x00000A44, 0x000500C4, + 0x0000000B, 0x00003DA7, 0x00001F43, 0x00000A19, 0x000500C2, 0x0000000B, 0x0000583F, 0x000051B7, + 0x00000A28, 0x000500C7, 0x0000000B, 0x00004BBE, 0x0000583F, 0x00000A44, 0x000500C4, 0x0000000B, + 0x00006273, 0x00004BBE, 0x00000A19, 0x00050050, 0x00000011, 0x000028B6, 0x000051B7, 0x000051B7, + 0x000500C2, 0x00000011, 0x00002891, 0x000028B6, 0x000008E3, 0x000500C7, 0x00000011, 0x00005B53, + 0x00002891, 0x0000084A, 0x000500C4, 0x00000011, 0x00003F50, 0x00005B53, 0x0000074E, 0x00050084, + 0x00000011, 0x000059EC, 0x00003F50, 0x00005C31, 0x000500C2, 0x0000000B, 0x000031C7, 0x000051B7, + 0x00000A5E, 0x000500C7, 0x0000000B, 0x00004356, 0x000031C7, 0x00000A1F, 0x0004003D, 0x00000014, + 0x000031C1, 0x00000F48, 0x0007004F, 0x00000011, 0x000038A4, 0x000031C1, 0x000031C1, 0x00000000, + 0x00000001, 0x000500C4, 0x00000011, 0x00002EF9, 0x000038A4, 0x00000721, 0x00050051, 0x0000000B, + 0x00001DD8, 0x00002EF9, 0x00000000, 0x000500C4, 0x0000000B, 0x00002D8A, 0x000059D1, 0x00000A13, + 0x000500AE, 0x00000009, 0x00003C13, 0x00001DD8, 0x00002D8A, 0x000300F7, 0x000036C9, 0x00000002, + 0x000400FA, 0x00003C13, 0x000055E9, 0x000036C9, 0x000200F8, 0x000055E9, 0x000200F9, 0x00004C7A, + 0x000200F8, 0x000036C9, 0x00050051, 0x0000000B, 0x000048B7, 0x00002EF9, 0x00000001, 0x00050051, + 0x0000000B, 0x000041A3, 0x00004AB4, 0x00000001, 0x0007000C, 0x0000000B, 0x00005F7E, 0x00000001, + 0x00000029, 0x000048B7, 0x000041A3, 0x00050050, 0x00000011, 0x000051EF, 0x00001DD8, 0x00005F7E, + 0x00050080, 0x00000011, 0x0000522C, 0x000051EF, 0x000059EB, 0x000500B2, 0x00000009, 0x00003ECB, + 0x00004356, 0x00000A13, 0x000300F7, 0x00005CE0, 0x00000000, 0x000400FA, 0x00003ECB, 0x00002AEE, + 0x00003AEF, 0x000200F8, 0x00003AEF, 0x000500AA, 0x00000009, 0x000034FE, 0x00004356, 0x00000A19, + 0x000600A9, 0x0000000B, 0x000020F6, 0x000034FE, 0x00000A10, 0x00000A0A, 0x000200F9, 0x00005CE0, + 0x000200F8, 0x00002AEE, 0x000200F9, 0x00005CE0, 0x000200F8, 0x00005CE0, 0x000700F5, 0x0000000B, + 0x00004B64, 0x00004356, 0x00002AEE, 0x000020F6, 0x00003AEF, 0x00050050, 0x00000011, 0x000041BE, + 0x0000217E, 0x0000217E, 0x000500AE, 0x0000000F, 0x00002E19, 0x000041BE, 0x0000072D, 0x000600A9, + 0x00000011, 0x00004BB5, 0x00002E19, 0x00000724, 0x0000070F, 0x000500C4, 0x00000011, 0x00002AEA, + 0x0000522C, 0x00004BB5, 0x00050050, 0x00000011, 0x0000605D, 0x00004B64, 0x00004B64, 0x000500C2, + 0x00000011, 0x00002385, 0x0000605D, 0x00000718, 0x000500C7, 0x00000011, 0x00003EC8, 0x00002385, + 0x00000724, 0x00050080, 0x00000011, 0x00004F30, 0x00002AEA, 0x00003EC8, 0x00050084, 0x00000011, + 0x00005299, 0x00000A9F, 0x00005C31, 0x000500C2, 0x00000011, 0x00003985, 0x00005299, 0x00000718, + 0x00050086, 0x00000011, 0x00004D57, 0x00004F30, 0x00003985, 0x00050051, 0x0000000B, 0x00004FA6, + 0x00004D57, 0x00000001, 0x00050084, 0x0000000B, 0x00002B26, 0x00004FA6, 0x00005051, 0x00050051, + 0x0000000B, 0x00006059, 0x00004D57, 0x00000000, 0x00050080, 0x0000000B, 0x00005420, 0x00002B26, + 0x00006059, 0x00050080, 0x0000000B, 0x00002226, 0x0000217F, 0x00005420, 0x00050084, 0x00000011, + 0x00005768, 0x00004D57, 0x00003985, 0x00050082, 0x00000011, 0x000050EB, 0x00004F30, 0x00005768, + 0x00050051, 0x0000000B, 0x00001C87, 0x00005299, 0x00000000, 0x00050051, 0x0000000B, 0x00005962, + 0x00005299, 0x00000001, 0x00050084, 0x0000000B, 0x00003372, 0x00001C87, 0x00005962, 0x00050084, + 0x0000000B, 0x000038D7, 0x00002226, 0x00003372, 0x00050051, 0x0000000B, 0x00001A95, 0x000050EB, + 0x00000001, 0x00050051, 0x0000000B, 0x00005BE6, 0x00003985, 0x00000000, 0x00050084, 0x0000000B, + 0x00005966, 0x00001A95, 0x00005BE6, 0x00050051, 0x0000000B, 0x00001AE6, 0x000050EB, 0x00000000, + 0x00050080, 0x0000000B, 0x000025E0, 0x00005966, 0x00001AE6, 0x000500C4, 0x0000000B, 0x00004665, + 0x000025E0, 0x00000A0D, 0x00050080, 0x0000000B, 0x000047BB, 0x000038D7, 0x00004665, 0x00050084, + 0x0000000B, 0x0000363C, 0x00003372, 0x00000A84, 0x00050089, 0x0000000B, 0x00004D53, 0x000047BB, + 0x0000363C, 0x000500C2, 0x0000000B, 0x0000552E, 0x00004D53, 0x00000A10, 0x00060041, 0x00000294, + 0x00004316, 0x00000CC7, 0x00000A0B, 0x0000552E, 0x0004003D, 0x00000017, 0x00003141, 0x00004316, + 0x00050080, 0x0000000B, 0x00002DA7, 0x0000552E, 0x00000A0D, 0x00060041, 0x00000294, 0x00001C1D, + 0x00000CC7, 0x00000A0B, 0x00002DA7, 0x0004003D, 0x00000017, 0x00004D82, 0x00001C1D, 0x000500AA, + 0x00000009, 0x00005272, 0x00001DD8, 0x00000A0A, 0x000300F7, 0x000033DC, 0x00000000, 0x000400FA, + 0x00005272, 0x00002CBB, 0x000033DC, 0x000200F8, 0x00002CBB, 0x00050051, 0x0000000B, 0x00005E5C, + 0x00004AB4, 0x00000000, 0x000500AB, 0x00000009, 0x000057C6, 0x00005E5C, 0x00000A0A, 0x000200F9, + 0x000033DC, 0x000200F8, 0x000033DC, 0x000700F5, 0x00000009, 0x00002AAC, 0x00005272, 0x00005CE0, + 0x000057C6, 0x00002CBB, 0x000300F7, 0x00005571, 0x00000002, 0x000400FA, 0x00002AAC, 0x00002CF4, + 0x00005571, 0x000200F8, 0x00002CF4, 0x00050051, 0x0000000B, 0x00005C2F, 0x00004AB4, 0x00000000, + 0x000500AE, 0x00000009, 0x000043C2, 0x00005C2F, 0x00000A10, 0x000300F7, 0x00005570, 0x00000000, + 0x000400FA, 0x000043C2, 0x00003E05, 0x00005570, 0x000200F8, 0x00003E05, 0x000500AE, 0x00000009, + 0x00005FD4, 0x00005C2F, 0x00000A13, 0x000300F7, 0x00004944, 0x00000000, 0x000400FA, 0x00005FD4, + 0x00002620, 0x00004944, 0x000200F8, 0x00002620, 0x00050051, 0x0000000B, 0x0000438A, 0x00004D82, + 0x00000002, 0x00060052, 0x00000017, 0x000052B6, 0x0000438A, 0x00004D82, 0x00000000, 0x00050051, + 0x0000000B, 0x00005A04, 0x00004D82, 0x00000003, 0x00060052, 0x00000017, 0x00002450, 0x00005A04, + 0x000052B6, 0x00000001, 0x000200F9, 0x00004944, 0x000200F8, 0x00004944, 0x000700F5, 0x00000017, + 0x000043E3, 0x00004D82, 0x00003E05, 0x00002450, 0x00002620, 0x00050051, 0x0000000B, 0x00005961, + 0x000043E3, 0x00000000, 0x00060052, 0x00000017, 0x000055DF, 0x00005961, 0x00003141, 0x00000002, + 0x00050051, 0x0000000B, 0x00005A05, 0x000043E3, 0x00000001, 0x00060052, 0x00000017, 0x00002451, + 0x00005A05, 0x000055DF, 0x00000003, 0x000200F9, 0x00005570, 0x000200F8, 0x00005570, 0x000700F5, + 0x00000017, 0x00001F7B, 0x00004D82, 0x00002CF4, 0x000043E3, 0x00004944, 0x000700F5, 0x00000017, + 0x00001EFE, 0x00003141, 0x00002CF4, 0x00002451, 0x00004944, 0x00050051, 0x0000000B, 0x00005C8A, + 0x00001EFE, 0x00000002, 0x00060052, 0x00000017, 0x000055E0, 0x00005C8A, 0x00001EFE, 0x00000000, + 0x00050051, 0x0000000B, 0x00005A06, 0x00001EFE, 0x00000003, 0x00060052, 0x00000017, 0x00002452, + 0x00005A06, 0x000055E0, 0x00000001, 0x000200F9, 0x00005571, 0x000200F8, 0x00005571, 0x000700F5, + 0x00000017, 0x00002BCD, 0x00004D82, 0x000033DC, 0x00001F7B, 0x00005570, 0x000700F5, 0x00000017, + 0x0000370D, 0x00003141, 0x000033DC, 0x00002452, 0x00005570, 0x000300F7, 0x0000530F, 0x00000002, + 0x000400FA, 0x00004C75, 0x00003ADC, 0x0000530F, 0x000200F8, 0x00003ADC, 0x000500AA, 0x00000009, + 0x00003585, 0x000023AA, 0x00000A19, 0x000400A8, 0x00000009, 0x00004277, 0x00003585, 0x000300F7, + 0x00003D52, 0x00000000, 0x000400FA, 0x00004277, 0x000040DF, 0x00003D52, 0x000200F8, 0x000040DF, + 0x000500AA, 0x00000009, 0x0000495A, 0x000023AA, 0x00000A1F, 0x000200F9, 0x00003D52, 0x000200F8, + 0x00003D52, 0x000700F5, 0x00000009, 0x00002AAD, 0x00003585, 0x00003ADC, 0x0000495A, 0x000040DF, + 0x000300F7, 0x000039F4, 0x00000002, 0x000400FA, 0x00002AAD, 0x000020A8, 0x000039F4, 0x000200F8, + 0x000020A8, 0x000500C7, 0x00000017, 0x00004BF1, 0x0000370D, 0x00000755, 0x0009004F, 0x00000017, + 0x000051EA, 0x0000370D, 0x0000370D, 0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x000500C7, + 0x00000017, 0x00001CED, 0x000051EA, 0x00000352, 0x000500C5, 0x00000017, 0x00003640, 0x00004BF1, + 0x00001CED, 0x000500C7, 0x00000017, 0x00005311, 0x00002BCD, 0x00000755, 0x0009004F, 0x00000017, + 0x00003BF8, 0x00002BCD, 0x00002BCD, 0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x000500C7, + 0x00000017, 0x000020A3, 0x00003BF8, 0x00000352, 0x000500C5, 0x00000017, 0x00002101, 0x00005311, + 0x000020A3, 0x000200F9, 0x000039F4, 0x000200F8, 0x000039F4, 0x000700F5, 0x00000017, 0x00002BF3, + 0x00002BCD, 0x00003D52, 0x00002101, 0x000020A8, 0x000700F5, 0x00000017, 0x0000358D, 0x0000370D, + 0x00003D52, 0x00003640, 0x000020A8, 0x000200F9, 0x0000530F, 0x000200F8, 0x0000530F, 0x000700F5, + 0x00000017, 0x000022F8, 0x00002BCD, 0x00005571, 0x00002BF3, 0x000039F4, 0x000700F5, 0x00000017, + 0x000049A7, 0x0000370D, 0x00005571, 0x0000358D, 0x000039F4, 0x00050080, 0x00000011, 0x000035BB, + 0x00002EF9, 0x000059EC, 0x00050051, 0x0000000B, 0x000033BC, 0x000035BB, 0x00000000, 0x00050051, + 0x0000000B, 0x00002553, 0x000035BB, 0x00000001, 0x000500C2, 0x0000000B, 0x00002B2D, 0x000033BC, + 0x00000A0D, 0x00050050, 0x00000011, 0x00001E98, 0x00002B2D, 0x00002553, 0x00050086, 0x00000011, + 0x00006158, 0x00001E98, 0x00005C31, 0x00050051, 0x0000000B, 0x0000366C, 0x00006158, 0x00000000, + 0x000500C4, 0x0000000B, 0x00004D3A, 0x0000366C, 0x00000A0D, 0x00050051, 0x0000000B, 0x00005EBB, + 0x00006158, 0x00000001, 0x00060050, 0x00000014, 0x000053CC, 0x00004D3A, 0x00005EBB, 0x000059FD, + 0x000300F7, 0x00005341, 0x00000002, 0x000400FA, 0x0000500F, 0x000056BE, 0x00002A98, 0x000200F8, + 0x00002A98, 0x0007004F, 0x00000011, 0x00001CAB, 0x000053CC, 0x000053CC, 0x00000000, 0x00000001, + 0x0004007C, 0x00000012, 0x000059CF, 0x00001CAB, 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, + 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, + 0x00002747, 0x000059CF, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, + 0x000500C2, 0x0000000B, 0x00005B4D, 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AA, + 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, + 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A28, + 0x000500C7, 0x0000000C, 0x00002AB6, 0x00001903, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, + 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, + 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454D, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, + 0x00000A13, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, + 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00004A8E, 0x00002F76, + 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, + 0x00003C4B, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x0000544A, 0x000047B4, 0x00000A17, 0x00050080, 0x0000000C, 0x00004157, 0x00004D30, + 0x0000544A, 0x000500C7, 0x0000000C, 0x00005022, 0x00004157, 0x0000040B, 0x000500C4, 0x0000000C, + 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, + 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x00004158, + 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADD, 0x00004157, 0x00000388, 0x000500C4, + 0x0000000C, 0x0000544B, 0x00004ADD, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x00004158, + 0x0000544B, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, + 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x00001903, 0x00000A14, + 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, + 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544C, 0x00005453, 0x00000A1D, 0x00050080, + 0x0000000C, 0x00003C4C, 0x00004144, 0x0000544C, 0x000500C7, 0x0000000C, 0x00002E06, 0x00004157, + 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4C, 0x00002E06, 0x0004007C, 0x0000000B, + 0x0000566F, 0x0000394F, 0x000200F9, 0x00005341, 0x000200F8, 0x000056BE, 0x0004007C, 0x00000016, + 0x000019AD, 0x000053CC, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000001, 0x000500C3, + 0x0000000C, 0x000024FE, 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002748, 0x000019AD, + 0x00000002, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A11, 0x000500C2, 0x0000000B, + 0x00005B4E, 0x00006273, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, + 0x0000000C, 0x00005321, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FE, + 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, + 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, + 0x0000000C, 0x00006242, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, + 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, + 0x0000225D, 0x000049FC, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, + 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, + 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x000042C2, 0x00000A1D, 0x000500C4, + 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, + 0x0000454E, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A25, 0x000500C3, 0x0000000C, + 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, + 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405D, 0x000500C7, 0x0000000C, 0x00005A0C, + 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, + 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544D, 0x00004ADE, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4D, 0x00005A0C, 0x0000544D, + 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, + 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, + 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, + 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544E, 0x000047B5, 0x00000A25, 0x00050080, 0x0000000C, 0x00004159, 0x0000285C, 0x0000544E, + 0x000500C7, 0x0000000C, 0x00004ADF, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544F, + 0x00004ADF, 0x00000A17, 0x00050080, 0x0000000C, 0x0000415A, 0x00004159, 0x0000544F, 0x000500C7, + 0x0000000C, 0x00004FD6, 0x00003C4D, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, + 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x0000415A, 0x00000A1D, 0x000500C7, 0x0000000C, + 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, + 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, + 0x00003C4D, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, + 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x0000415A, + 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, + 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x0000415A, 0x00000AC8, + 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, 0x00005670, + 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, 0x000024FC, + 0x00005670, 0x000056BE, 0x0000566F, 0x00002A98, 0x00050084, 0x00000011, 0x00003FA8, 0x00006158, + 0x00005C31, 0x00050082, 0x00000011, 0x00003F85, 0x00001E98, 0x00003FA8, 0x00050051, 0x0000000B, + 0x0000448F, 0x00005C31, 0x00000001, 0x00050084, 0x0000000B, 0x00005C50, 0x0000229A, 0x0000448F, + 0x00050084, 0x0000000B, 0x00003CA0, 0x000024FC, 0x00005C50, 0x00050051, 0x0000000B, 0x00003ED4, + 0x00003F85, 0x00000000, 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, 0x0000448F, 0x00050051, + 0x0000000B, 0x00001AE7, 0x00003F85, 0x00000001, 0x00050080, 0x0000000B, 0x00002B25, 0x00003E12, + 0x00001AE7, 0x000500C4, 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A0D, 0x000500C7, 0x0000000B, + 0x00005AB3, 0x000033BC, 0x00000A0D, 0x00050080, 0x0000000B, 0x00002557, 0x0000609D, 0x00005AB3, + 0x000500C4, 0x0000000B, 0x00004593, 0x00002557, 0x00000A13, 0x00050080, 0x0000000B, 0x00002048, + 0x00003CA0, 0x00004593, 0x000500C2, 0x0000000B, 0x000025CC, 0x00002048, 0x00000A16, 0x000500AA, + 0x00000009, 0x00004B9C, 0x00004ADC, 0x00000A16, 0x000300F7, 0x000039BC, 0x00000000, 0x000400FA, + 0x00004B9C, 0x000033DF, 0x000039BC, 0x000200F8, 0x000033DF, 0x0009004F, 0x00000017, 0x00001F16, + 0x000049A7, 0x000049A7, 0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x000200F9, 0x000039BC, + 0x000200F8, 0x000039BC, 0x000700F5, 0x00000017, 0x00005972, 0x000049A7, 0x00005341, 0x00001F16, + 0x000033DF, 0x000600A9, 0x0000000B, 0x000019CD, 0x00004B9C, 0x00000A10, 0x00004ADC, 0x000500AA, + 0x00000009, 0x00003464, 0x000019CD, 0x00000A0D, 0x000500AA, 0x00000009, 0x000047C2, 0x000019CD, + 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x00003464, 0x000047C2, 0x000300F7, 0x00003463, + 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, + 0x00000017, 0x0000475F, 0x00005972, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00005972, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, + 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00005972, + 0x000039BC, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000019CD, 0x00000A13, + 0x000500A6, 0x00000009, 0x00003B23, 0x000047C2, 0x00004CB6, 0x000300F7, 0x00002C98, 0x00000000, + 0x000400FA, 0x00003B23, 0x00002B38, 0x00002C98, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, + 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, + 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x00002C98, 0x000200F8, + 0x00002C98, 0x000700F5, 0x00000017, 0x00004D37, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, + 0x00060041, 0x00000294, 0x000019BE, 0x00001592, 0x00000A0B, 0x000025CC, 0x0003003E, 0x000019BE, + 0x00004D37, 0x000500AC, 0x00000009, 0x00005BF6, 0x0000229A, 0x00000A0D, 0x000300F7, 0x00004AAC, + 0x00000002, 0x000400FA, 0x00005BF6, 0x000038DA, 0x000055EA, 0x000200F8, 0x000055EA, 0x000200F9, + 0x00004AAC, 0x000200F8, 0x000038DA, 0x000500C2, 0x0000000B, 0x0000364A, 0x00001DD8, 0x00000A0D, + 0x00050086, 0x0000000B, 0x00001F01, 0x0000364A, 0x0000229A, 0x00050084, 0x0000000B, 0x000041FB, + 0x00001F01, 0x0000229A, 0x00050082, 0x0000000B, 0x00003171, 0x0000364A, 0x000041FB, 0x00050080, + 0x0000000B, 0x00002527, 0x00003171, 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, + 0x0000229A, 0x000300F7, 0x00002458, 0x00000000, 0x000400FA, 0x0000343F, 0x00001CDB, 0x000055EB, + 0x000200F8, 0x000055EB, 0x000200F9, 0x00002458, 0x000200F8, 0x00001CDB, 0x00050084, 0x0000000B, + 0x00003B96, 0x00000A6A, 0x0000229A, 0x000500C4, 0x0000000B, 0x0000540F, 0x00003171, 0x00000A16, + 0x00050082, 0x0000000B, 0x00004945, 0x00003B96, 0x0000540F, 0x000200F9, 0x00002458, 0x000200F8, + 0x00002458, 0x000700F5, 0x0000000B, 0x0000292C, 0x00004945, 0x00001CDB, 0x00000A3A, 0x000055EB, + 0x000200F9, 0x00004AAC, 0x000200F8, 0x00004AAC, 0x000700F5, 0x0000000B, 0x000029BC, 0x0000292C, + 0x00002458, 0x00000A6A, 0x000055EA, 0x00050084, 0x0000000B, 0x0000492B, 0x000029BC, 0x0000448F, + 0x000500C2, 0x0000000B, 0x00004DEF, 0x0000492B, 0x00000A16, 0x00050080, 0x0000000B, 0x00005B72, + 0x000025CC, 0x00004DEF, 0x000300F7, 0x00003F86, 0x00000000, 0x000400FA, 0x00004B9C, 0x000033E0, + 0x00003F86, 0x000200F8, 0x000033E0, 0x0009004F, 0x00000017, 0x00001F17, 0x000022F8, 0x000022F8, + 0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x000200F9, 0x00003F86, 0x000200F8, 0x00003F86, + 0x000700F5, 0x00000017, 0x00002AAE, 0x000022F8, 0x00004AAC, 0x00001F17, 0x000033E0, 0x000300F7, + 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, + 0x000500C7, 0x00000017, 0x00004760, 0x00002AAE, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, + 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x00002AAE, 0x0000072E, 0x000500C2, + 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, + 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAF, + 0x00002AAE, 0x00003F86, 0x00003FF9, 0x00002958, 0x000300F7, 0x00002C99, 0x00000000, 0x000400FA, + 0x00003B23, 0x00002B39, 0x00002C99, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, + 0x00002AAF, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAF, 0x000002ED, 0x000500C5, + 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002C99, 0x000200F8, 0x00002C99, + 0x000700F5, 0x00000017, 0x00004D39, 0x00002AAF, 0x00003A1A, 0x000029E9, 0x00002B39, 0x00060041, + 0x00000294, 0x00001F75, 0x00001592, 0x00000A0B, 0x00005B72, 0x0003003E, 0x00001F75, 0x00004D39, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_fast_64bpp_4xmsaa_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_fast_64bpp_4xmsaa_cs.h new file mode 100644 index 0000000..569107e --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_fast_64bpp_4xmsaa_cs.h @@ -0,0 +1,722 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25271 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_struct_1036 Block + OpMemberDecorate %_struct_1036 0 Offset 0 + OpMemberDecorate %_struct_1036 1 Offset 4 + OpMemberDecorate %_struct_1036 2 Offset 8 + OpMemberDecorate %_struct_1036 3 Offset 12 + OpMemberDecorate %_struct_1036 4 Offset 16 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v2uint ArrayStride 8 + OpDecorate %_struct_1960 BufferBlock + OpMemberDecorate %_struct_1960 0 NonWritable + OpMemberDecorate %_struct_1960 0 Offset 0 + OpDecorate %3271 NonWritable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonReadable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %5522 NonReadable + OpDecorate %5522 Binding 0 + OpDecorate %5522 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %bool = OpTypeBool + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_4 = OpConstant %uint 4 + %uint_0 = OpConstant %uint 0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_6 = OpConstant %uint 6 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_struct_1036 = OpTypeStruct %uint %uint %uint %uint %uint +%_ptr_PushConstant__struct_1036 = OpTypePointer PushConstant %_struct_1036 + %3305 = OpVariable %_ptr_PushConstant__struct_1036 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %uint_1023 = OpConstant %uint 1023 + %uint_10 = OpConstant %uint 10 + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_24 = OpConstant %uint 24 + %uint_15 = OpConstant %uint 15 + %uint_28 = OpConstant %uint 28 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 +%uint_16777216 = OpConstant %uint 16777216 + %uint_20 = OpConstant %uint 20 + %2275 = OpConstantComposite %v2uint %uint_20 %uint_24 + %v3uint = OpTypeVector %uint 3 +%uint_4294901760 = OpConstant %uint 4294901760 + %uint_65535 = OpConstant %uint 65535 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %1825 = OpConstantComposite %v2uint %uint_2 %uint_0 + %false = OpConstantFalse %bool +%_runtimearr_v2uint = OpTypeRuntimeArray %v2uint +%_struct_1960 = OpTypeStruct %_runtimearr_v2uint +%_ptr_Uniform__struct_1960 = OpTypePointer Uniform %_struct_1960 + %3271 = OpVariable %_ptr_Uniform__struct_1960 Uniform +%_ptr_Uniform_v2uint = OpTypePointer Uniform %v2uint +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %5522 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %uint_9 = OpConstant %uint 9 + %1877 = OpConstantComposite %v4uint %uint_4294901760 %uint_4294901760 %uint_4294901760 %uint_4294901760 + %850 = OpConstantComposite %v4uint %uint_65535 %uint_65535 %uint_65535 %uint_65535 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %uint_40 = OpConstant %uint 40 + %2359 = OpConstantComposite %v2uint %uint_40 %uint_16 + %uint_1280 = OpConstant %uint 1280 +%uint_2621440 = OpConstant %uint 2621440 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %19978 = OpShiftRightLogical %uint %15627 %uint_13 + %8574 = OpBitwiseAnd %uint %19978 %uint_2047 + %18836 = OpShiftRightLogical %uint %15627 %uint_24 + %9130 = OpBitwiseAnd %uint %18836 %uint_15 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9576 = OpShiftRightLogical %v2uint %8871 %1855 + %23379 = OpBitwiseAnd %v2uint %9576 %1954 + %16207 = OpShiftLeftLogical %v2uint %23379 %1870 + %23019 = OpIMul %v2uint %16207 %1828 + %12819 = OpShiftRightLogical %uint %20824 %uint_5 + %16204 = OpBitwiseAnd %uint %12819 %uint_2047 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %24236 = OpLoad %uint %18732 + %22701 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %20919 = OpLoad %uint %22701 + %19164 = OpBitwiseAnd %uint %24236 %uint_7 + %21999 = OpBitwiseAnd %uint %24236 %uint_8 + %20495 = OpINotEqual %bool %21999 %uint_0 + %10402 = OpShiftRightLogical %uint %24236 %uint_4 + %23037 = OpBitwiseAnd %uint %10402 %uint_7 + %23118 = OpBitwiseAnd %uint %24236 %uint_16777216 + %19573 = OpINotEqual %bool %23118 %uint_0 + %8003 = OpBitwiseAnd %uint %20919 %uint_1023 + %15783 = OpShiftLeftLogical %uint %8003 %uint_5 + %22591 = OpShiftRightLogical %uint %20919 %uint_10 + %19390 = OpBitwiseAnd %uint %22591 %uint_1023 + %25203 = OpShiftLeftLogical %uint %19390 %uint_5 + %10422 = OpCompositeConstruct %v2uint %20919 %20919 + %10385 = OpShiftRightLogical %v2uint %10422 %2275 + %23380 = OpBitwiseAnd %v2uint %10385 %2122 + %16208 = OpShiftLeftLogical %v2uint %23380 %1870 + %23020 = OpIMul %v2uint %16208 %1828 + %12820 = OpShiftRightLogical %uint %20919 %uint_28 + %16205 = OpBitwiseAnd %uint %12820 %uint_7 + %18656 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_4 + %25270 = OpLoad %uint %18656 + %14159 = OpLoad %v3uint %gl_GlobalInvocationID + %12672 = OpVectorShuffle %v2uint %14159 %14159 0 1 + %12025 = OpShiftLeftLogical %v2uint %12672 %1825 + %7640 = OpCompositeExtract %uint %12025 0 + %11658 = OpShiftLeftLogical %uint %16204 %uint_3 + %15379 = OpUGreaterThanEqual %bool %7640 %11658 + OpSelectionMerge %12755 DontFlatten + OpBranchConditional %15379 %21992 %12755 + %21992 = OpLabel + OpBranch %19578 + %12755 = OpLabel + %7340 = OpCompositeExtract %uint %12025 1 + %7992 = OpExtInst %uint %1 UMax %7340 %uint_0 + %20975 = OpCompositeConstruct %v2uint %7640 %7992 + %21036 = OpIAdd %v2uint %20975 %23019 + %16075 = OpULessThanEqual %bool %16205 %uint_3 + OpSelectionMerge %6909 None + OpBranchConditional %16075 %10990 %15087 + %15087 = OpLabel + %13566 = OpIEqual %bool %16205 %uint_5 + %8438 = OpSelect %uint %13566 %uint_2 %uint_0 + OpBranch %6909 + %10990 = OpLabel + OpBranch %6909 + %6909 = OpLabel + %16517 = OpPhi %uint %16205 %10990 %8438 %15087 + %11201 = OpShiftLeftLogical %v2uint %21036 %1828 + %21693 = OpCompositeConstruct %v2uint %16517 %16517 + %9093 = OpShiftRightLogical %v2uint %21693 %1816 + %16110 = OpBitwiseAnd %v2uint %9093 %1828 + %17779 = OpIAdd %v2uint %11201 %16110 + %24270 = OpUDiv %v2uint %17779 %2359 + %12360 = OpCompositeExtract %uint %24270 1 + %11046 = OpIMul %uint %12360 %20561 + %24665 = OpCompositeExtract %uint %24270 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %8574 %21536 + %23345 = OpIMul %v2uint %24270 %2359 + %11892 = OpISub %v2uint %17779 %23345 + %9022 = OpIMul %uint %8742 %uint_1280 + %14471 = OpCompositeExtract %uint %11892 1 + %15890 = OpIMul %uint %14471 %uint_40 + %6886 = OpCompositeExtract %uint %11892 0 + %9696 = OpIAdd %uint %15890 %6886 + %18116 = OpShiftLeftLogical %uint %9696 %uint_1 + %18581 = OpIAdd %uint %9022 %18116 + %17820 = OpUMod %uint %18581 %uint_2621440 + %18580 = OpShiftRightLogical %uint %17820 %uint_1 + %16281 = OpAccessChain %_ptr_Uniform_v2uint %3271 %int_0 %18580 + %21044 = OpLoad %v2uint %16281 + %20300 = OpCompositeExtract %uint %21044 0 + %15080 = OpCompositeExtract %uint %21044 1 + %19011 = OpIAdd %uint %18580 %uint_2 + %8722 = OpAccessChain %_ptr_Uniform_v2uint %3271 %int_0 %19011 + %13014 = OpLoad %v2uint %8722 + %19388 = OpCompositeExtract %uint %13014 0 + %24581 = OpCompositeExtract %uint %13014 1 + %7418 = OpCompositeConstruct %v4uint %20300 %15080 %19388 %24581 + %6646 = OpIAdd %uint %18580 %uint_4 + %23758 = OpAccessChain %_ptr_Uniform_v2uint %3271 %int_0 %6646 + %13015 = OpLoad %v2uint %23758 + %20301 = OpCompositeExtract %uint %13015 0 + %15081 = OpCompositeExtract %uint %13015 1 + %19012 = OpIAdd %uint %18580 %uint_6 + %8723 = OpAccessChain %_ptr_Uniform_v2uint %3271 %int_0 %19012 + %13016 = OpLoad %v2uint %8723 + %19389 = OpCompositeExtract %uint %13016 0 + %6308 = OpCompositeExtract %uint %13016 1 + %21199 = OpCompositeConstruct %v4uint %20301 %15081 %19389 %6308 + %23045 = OpIEqual %bool %7640 %uint_0 + %21241 = OpSelect %bool %23045 %false %23045 + OpSelectionMerge %21910 DontFlatten + OpBranchConditional %21241 %9587 %21910 + %9587 = OpLabel + %12289 = OpCompositeInsert %v4uint %19388 %7418 0 + %14086 = OpCompositeInsert %v4uint %24581 %12289 1 + OpBranch %21910 + %21910 = OpLabel + %10924 = OpPhi %v4uint %7418 %6909 %14086 %9587 + OpSelectionMerge %21263 DontFlatten + OpBranchConditional %19573 %15068 %21263 + %15068 = OpLabel + %13701 = OpIEqual %bool %9130 %uint_5 + %17015 = OpLogicalNot %bool %13701 + OpSelectionMerge %15698 None + OpBranchConditional %17015 %16607 %15698 + %16607 = OpLabel + %18778 = OpIEqual %bool %9130 %uint_7 + OpBranch %15698 + %15698 = OpLabel + %10925 = OpPhi %bool %13701 %15068 %18778 %16607 + OpSelectionMerge %14836 DontFlatten + OpBranchConditional %10925 %8360 %14836 + %8360 = OpLabel + %19441 = OpBitwiseAnd %v4uint %10924 %1877 + %20970 = OpVectorShuffle %v4uint %10924 %10924 1 0 3 2 + %7405 = OpBitwiseAnd %v4uint %20970 %850 + %13888 = OpBitwiseOr %v4uint %19441 %7405 + %21265 = OpBitwiseAnd %v4uint %21199 %1877 + %15352 = OpVectorShuffle %v4uint %21199 %21199 1 0 3 2 + %8355 = OpBitwiseAnd %v4uint %15352 %850 + %8449 = OpBitwiseOr %v4uint %21265 %8355 + OpBranch %14836 + %14836 = OpLabel + %11251 = OpPhi %v4uint %21199 %15698 %8449 %8360 + %13709 = OpPhi %v4uint %10924 %15698 %13888 %8360 + OpBranch %21263 + %21263 = OpLabel + %8952 = OpPhi %v4uint %21199 %21910 %11251 %14836 + %22009 = OpPhi %v4uint %10924 %21910 %13709 %14836 + %7319 = OpIAdd %v2uint %12025 %23020 + OpSelectionMerge %21237 DontFlatten + OpBranchConditional %20495 %10574 %21373 + %21373 = OpLabel + %10608 = OpBitcast %v2int %7319 + %17090 = OpCompositeExtract %int %10608 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %10608 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %15783 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_10 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17303 = OpIAdd %int %10934 %17741 + %6375 = OpShiftLeftLogical %int %17303 %uint_3 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15435 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18356 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18356 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12151 + %19165 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19165 %int_2 + %16708 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21587 %int_6 + %15436 = OpIAdd %int %16708 %21580 + %11782 = OpBitwiseAnd %int %16727 %int_63 + %14671 = OpIAdd %int %15436 %11782 + %22127 = OpBitcast %uint %14671 + OpBranch %21237 + %10574 = OpLabel + %19866 = OpCompositeExtract %uint %7319 0 + %11267 = OpCompositeExtract %uint %7319 1 + %8414 = OpCompositeConstruct %v3uint %19866 %11267 %23037 + %20125 = OpBitcast %v3int %8414 + %10438 = OpCompositeExtract %int %20125 1 + %9470 = OpShiftRightArithmetic %int %10438 %int_4 + %10056 = OpCompositeExtract %int %20125 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %25203 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %15783 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %20125 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_9 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12601 = OpBitwiseAnd %int %10438 %int_6 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7048 = OpShiftLeftLogical %int %17227 %uint_9 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %10438 %int_3 + %13731 = OpIAdd %int %8725 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19166 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19166 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23346 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23346 %23274 + %18357 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18357 %uint_9 + %16729 = OpIAdd %int %10332 %21582 + %19167 = OpBitwiseAnd %int %10438 %int_1 + %21583 = OpShiftLeftLogical %int %19167 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23347 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10908 = OpIAdd %int %23347 %23217 + %23348 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10909 = OpIAdd %int %23348 %23218 + %23349 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16730 %int_63 + %24314 = OpIAdd %int %23349 %21849 + %22128 = OpBitcast %uint %24314 + OpBranch %21237 + %21237 = OpLabel + %11376 = OpPhi %uint %22128 %10574 %22127 %21373 + %20616 = OpIAdd %uint %11376 %25270 + %20138 = OpShiftRightLogical %uint %20616 %uint_4 + %19356 = OpIEqual %bool %19164 %uint_4 + OpSelectionMerge %14780 None + OpBranchConditional %19356 %13279 %14780 + %13279 = OpLabel + %7958 = OpVectorShuffle %v4uint %22009 %22009 1 0 3 2 + OpBranch %14780 + %14780 = OpLabel + %22898 = OpPhi %v4uint %22009 %21237 %7958 %13279 + %6605 = OpSelect %uint %19356 %uint_2 %19164 + %13412 = OpIEqual %bool %6605 %uint_1 + %18370 = OpIEqual %bool %6605 %uint_2 + %22150 = OpLogicalOr %bool %13412 %18370 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %22898 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %22898 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %22898 %14780 %16376 %10583 + %19638 = OpIEqual %bool %6605 %uint_3 + %15139 = OpLogicalOr %bool %18370 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %24825 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %20138 + OpStore %24825 %19767 + %21685 = OpIAdd %uint %20138 %uint_2 + OpSelectionMerge %16262 None + OpBranchConditional %19356 %13280 %16262 + %13280 = OpLabel + %7959 = OpVectorShuffle %v4uint %8952 %8952 1 0 3 2 + OpBranch %16262 + %16262 = OpLabel + %10926 = OpPhi %v4uint %8952 %11416 %7959 %13280 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %10926 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %10926 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10927 = OpPhi %v4uint %10926 %16262 %16377 %10584 + OpSelectionMerge %11417 None + OpBranchConditional %15139 %11065 %11417 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10927 %749 + %15336 = OpShiftRightLogical %v4uint %10927 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %10927 %14874 %10729 %11065 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %21685 + OpStore %8053 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_fast_64bpp_4xmsaa_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000062B7, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00030047, 0x0000040C, 0x00000002, 0x00050048, + 0x0000040C, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x0000040C, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x0000040C, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x0000040C, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x0000040C, 0x00000004, 0x00000023, 0x00000010, + 0x00040047, 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007D6, 0x00000006, 0x00000008, + 0x00030047, 0x000007A8, 0x00000003, 0x00040048, 0x000007A8, 0x00000000, 0x00000018, 0x00050048, + 0x000007A8, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000CC7, 0x00000018, 0x00040047, + 0x00000CC7, 0x00000021, 0x00000000, 0x00040047, 0x00000CC7, 0x00000022, 0x00000000, 0x00040047, + 0x000007DC, 0x00000006, 0x00000010, 0x00030047, 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, + 0x00000000, 0x00000019, 0x00050048, 0x000007B4, 0x00000000, 0x00000023, 0x00000000, 0x00030047, + 0x00001592, 0x00000019, 0x00040047, 0x00001592, 0x00000021, 0x00000000, 0x00040047, 0x00001592, + 0x00000022, 0x00000001, 0x00040047, 0x00000AC7, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, + 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, + 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00020014, + 0x00000009, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, + 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A0D, + 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x000008A6, + 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, + 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A3A, + 0x00000010, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000B, 0x00000A0A, + 0x00000000, 0x0005002C, 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, 0x0005002C, 0x00000011, + 0x00000718, 0x00000A0D, 0x00000A0A, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, + 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, + 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, + 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, + 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, + 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, + 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, + 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, + 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, + 0x0000000B, 0x00000A1C, 0x00000006, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, + 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0007001E, 0x0000040C, 0x0000000B, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000688, 0x00000009, 0x0000040C, 0x0004003B, 0x00000688, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, + 0x00000009, 0x0000000B, 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, 0x0004002B, 0x0000000B, + 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, 0x0004002B, 0x0000000B, + 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A52, 0x00000018, 0x0004002B, 0x0000000B, + 0x00000A37, 0x0000000F, 0x0004002B, 0x0000000B, 0x00000A5E, 0x0000001C, 0x0005002C, 0x00000011, + 0x0000073F, 0x00000A0A, 0x00000A16, 0x0004002B, 0x0000000B, 0x00000926, 0x01000000, 0x0004002B, + 0x0000000B, 0x00000A46, 0x00000014, 0x0005002C, 0x00000011, 0x000008E3, 0x00000A46, 0x00000A52, + 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x0004002B, 0x0000000B, 0x0000068D, 0xFFFF0000, + 0x0004002B, 0x0000000B, 0x000001C1, 0x0000FFFF, 0x00040020, 0x00000291, 0x00000001, 0x00000014, + 0x0004003B, 0x00000291, 0x00000F48, 0x00000001, 0x0005002C, 0x00000011, 0x00000721, 0x00000A10, + 0x00000A0A, 0x0003002A, 0x00000009, 0x00000787, 0x0003001D, 0x000007D6, 0x00000011, 0x0003001E, + 0x000007A8, 0x000007D6, 0x00040020, 0x00000A25, 0x00000002, 0x000007A8, 0x0004003B, 0x00000A25, + 0x00000CC7, 0x00000002, 0x00040020, 0x0000028E, 0x00000002, 0x00000011, 0x0003001D, 0x000007DC, + 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, + 0x0004003B, 0x00000A32, 0x00001592, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, + 0x0006002C, 0x00000014, 0x00000AC7, 0x00000A22, 0x00000A22, 0x00000A0D, 0x0005002C, 0x00000011, + 0x000007A2, 0x00000A37, 0x00000A0D, 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, + 0x0005002C, 0x00000011, 0x0000084A, 0x00000A37, 0x00000A37, 0x0004002B, 0x0000000B, 0x00000A26, + 0x00000009, 0x0007002C, 0x00000017, 0x00000755, 0x0000068D, 0x0000068D, 0x0000068D, 0x0000068D, + 0x0007002C, 0x00000017, 0x00000352, 0x000001C1, 0x000001C1, 0x000001C1, 0x000001C1, 0x0007002C, + 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, + 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, + 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0004002B, 0x0000000B, 0x00000A82, 0x00000028, 0x0005002C, + 0x00000011, 0x00000937, 0x00000A82, 0x00000A3A, 0x0004002B, 0x0000000B, 0x00000184, 0x00000500, + 0x0004002B, 0x0000000B, 0x0000086E, 0x00280000, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, + 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, + 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000056E5, 0x00000CE9, 0x00000A0B, + 0x0004003D, 0x0000000B, 0x00003D0B, 0x000056E5, 0x00050041, 0x00000288, 0x000058AC, 0x00000CE9, + 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005158, 0x000058AC, 0x000500C7, 0x0000000B, 0x00005051, + 0x00003D0B, 0x00000A44, 0x000500C2, 0x0000000B, 0x00004E0A, 0x00003D0B, 0x00000A31, 0x000500C7, + 0x0000000B, 0x0000217E, 0x00004E0A, 0x00000A81, 0x000500C2, 0x0000000B, 0x00004994, 0x00003D0B, + 0x00000A52, 0x000500C7, 0x0000000B, 0x000023AA, 0x00004994, 0x00000A37, 0x00050050, 0x00000011, + 0x000022A7, 0x00005158, 0x00005158, 0x000500C2, 0x00000011, 0x00002568, 0x000022A7, 0x0000073F, + 0x000500C7, 0x00000011, 0x00005B53, 0x00002568, 0x000007A2, 0x000500C4, 0x00000011, 0x00003F4F, + 0x00005B53, 0x0000074E, 0x00050084, 0x00000011, 0x000059EB, 0x00003F4F, 0x00000724, 0x000500C2, + 0x0000000B, 0x00003213, 0x00005158, 0x00000A19, 0x000500C7, 0x0000000B, 0x00003F4C, 0x00003213, + 0x00000A81, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, + 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x000058AD, 0x00000CE9, 0x00000A14, 0x0004003D, + 0x0000000B, 0x000051B7, 0x000058AD, 0x000500C7, 0x0000000B, 0x00004ADC, 0x00005EAC, 0x00000A1F, + 0x000500C7, 0x0000000B, 0x000055EF, 0x00005EAC, 0x00000A22, 0x000500AB, 0x00000009, 0x0000500F, + 0x000055EF, 0x00000A0A, 0x000500C2, 0x0000000B, 0x000028A2, 0x00005EAC, 0x00000A16, 0x000500C7, + 0x0000000B, 0x000059FD, 0x000028A2, 0x00000A1F, 0x000500C7, 0x0000000B, 0x00005A4E, 0x00005EAC, + 0x00000926, 0x000500AB, 0x00000009, 0x00004C75, 0x00005A4E, 0x00000A0A, 0x000500C7, 0x0000000B, + 0x00001F43, 0x000051B7, 0x00000A44, 0x000500C4, 0x0000000B, 0x00003DA7, 0x00001F43, 0x00000A19, + 0x000500C2, 0x0000000B, 0x0000583F, 0x000051B7, 0x00000A28, 0x000500C7, 0x0000000B, 0x00004BBE, + 0x0000583F, 0x00000A44, 0x000500C4, 0x0000000B, 0x00006273, 0x00004BBE, 0x00000A19, 0x00050050, + 0x00000011, 0x000028B6, 0x000051B7, 0x000051B7, 0x000500C2, 0x00000011, 0x00002891, 0x000028B6, + 0x000008E3, 0x000500C7, 0x00000011, 0x00005B54, 0x00002891, 0x0000084A, 0x000500C4, 0x00000011, + 0x00003F50, 0x00005B54, 0x0000074E, 0x00050084, 0x00000011, 0x000059EC, 0x00003F50, 0x00000724, + 0x000500C2, 0x0000000B, 0x00003214, 0x000051B7, 0x00000A5E, 0x000500C7, 0x0000000B, 0x00003F4D, + 0x00003214, 0x00000A1F, 0x00050041, 0x00000288, 0x000048E0, 0x00000CE9, 0x00000A17, 0x0004003D, + 0x0000000B, 0x000062B6, 0x000048E0, 0x0004003D, 0x00000014, 0x0000374F, 0x00000F48, 0x0007004F, + 0x00000011, 0x00003180, 0x0000374F, 0x0000374F, 0x00000000, 0x00000001, 0x000500C4, 0x00000011, + 0x00002EF9, 0x00003180, 0x00000721, 0x00050051, 0x0000000B, 0x00001DD8, 0x00002EF9, 0x00000000, + 0x000500C4, 0x0000000B, 0x00002D8A, 0x00003F4C, 0x00000A13, 0x000500AE, 0x00000009, 0x00003C13, + 0x00001DD8, 0x00002D8A, 0x000300F7, 0x000031D3, 0x00000002, 0x000400FA, 0x00003C13, 0x000055E8, + 0x000031D3, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000031D3, 0x00050051, + 0x0000000B, 0x00001CAC, 0x00002EF9, 0x00000001, 0x0007000C, 0x0000000B, 0x00001F38, 0x00000001, + 0x00000029, 0x00001CAC, 0x00000A0A, 0x00050050, 0x00000011, 0x000051EF, 0x00001DD8, 0x00001F38, + 0x00050080, 0x00000011, 0x0000522C, 0x000051EF, 0x000059EB, 0x000500B2, 0x00000009, 0x00003ECB, + 0x00003F4D, 0x00000A13, 0x000300F7, 0x00001AFD, 0x00000000, 0x000400FA, 0x00003ECB, 0x00002AEE, + 0x00003AEF, 0x000200F8, 0x00003AEF, 0x000500AA, 0x00000009, 0x000034FE, 0x00003F4D, 0x00000A19, + 0x000600A9, 0x0000000B, 0x000020F6, 0x000034FE, 0x00000A10, 0x00000A0A, 0x000200F9, 0x00001AFD, + 0x000200F8, 0x00002AEE, 0x000200F9, 0x00001AFD, 0x000200F8, 0x00001AFD, 0x000700F5, 0x0000000B, + 0x00004085, 0x00003F4D, 0x00002AEE, 0x000020F6, 0x00003AEF, 0x000500C4, 0x00000011, 0x00002BC1, + 0x0000522C, 0x00000724, 0x00050050, 0x00000011, 0x000054BD, 0x00004085, 0x00004085, 0x000500C2, + 0x00000011, 0x00002385, 0x000054BD, 0x00000718, 0x000500C7, 0x00000011, 0x00003EEE, 0x00002385, + 0x00000724, 0x00050080, 0x00000011, 0x00004573, 0x00002BC1, 0x00003EEE, 0x00050086, 0x00000011, + 0x00005ECE, 0x00004573, 0x00000937, 0x00050051, 0x0000000B, 0x00003048, 0x00005ECE, 0x00000001, + 0x00050084, 0x0000000B, 0x00002B26, 0x00003048, 0x00005051, 0x00050051, 0x0000000B, 0x00006059, + 0x00005ECE, 0x00000000, 0x00050080, 0x0000000B, 0x00005420, 0x00002B26, 0x00006059, 0x00050080, + 0x0000000B, 0x00002226, 0x0000217E, 0x00005420, 0x00050084, 0x00000011, 0x00005B31, 0x00005ECE, + 0x00000937, 0x00050082, 0x00000011, 0x00002E74, 0x00004573, 0x00005B31, 0x00050084, 0x0000000B, + 0x0000233E, 0x00002226, 0x00000184, 0x00050051, 0x0000000B, 0x00003887, 0x00002E74, 0x00000001, + 0x00050084, 0x0000000B, 0x00003E12, 0x00003887, 0x00000A82, 0x00050051, 0x0000000B, 0x00001AE6, + 0x00002E74, 0x00000000, 0x00050080, 0x0000000B, 0x000025E0, 0x00003E12, 0x00001AE6, 0x000500C4, + 0x0000000B, 0x000046C4, 0x000025E0, 0x00000A0D, 0x00050080, 0x0000000B, 0x00004895, 0x0000233E, + 0x000046C4, 0x00050089, 0x0000000B, 0x0000459C, 0x00004895, 0x0000086E, 0x000500C2, 0x0000000B, + 0x00004894, 0x0000459C, 0x00000A0D, 0x00060041, 0x0000028E, 0x00003F99, 0x00000CC7, 0x00000A0B, + 0x00004894, 0x0004003D, 0x00000011, 0x00005234, 0x00003F99, 0x00050051, 0x0000000B, 0x00004F4C, + 0x00005234, 0x00000000, 0x00050051, 0x0000000B, 0x00003AE8, 0x00005234, 0x00000001, 0x00050080, + 0x0000000B, 0x00004A43, 0x00004894, 0x00000A10, 0x00060041, 0x0000028E, 0x00002212, 0x00000CC7, + 0x00000A0B, 0x00004A43, 0x0004003D, 0x00000011, 0x000032D6, 0x00002212, 0x00050051, 0x0000000B, + 0x00004BBC, 0x000032D6, 0x00000000, 0x00050051, 0x0000000B, 0x00006005, 0x000032D6, 0x00000001, + 0x00070050, 0x00000017, 0x00001CFA, 0x00004F4C, 0x00003AE8, 0x00004BBC, 0x00006005, 0x00050080, + 0x0000000B, 0x000019F6, 0x00004894, 0x00000A16, 0x00060041, 0x0000028E, 0x00005CCE, 0x00000CC7, + 0x00000A0B, 0x000019F6, 0x0004003D, 0x00000011, 0x000032D7, 0x00005CCE, 0x00050051, 0x0000000B, + 0x00004F4D, 0x000032D7, 0x00000000, 0x00050051, 0x0000000B, 0x00003AE9, 0x000032D7, 0x00000001, + 0x00050080, 0x0000000B, 0x00004A44, 0x00004894, 0x00000A1C, 0x00060041, 0x0000028E, 0x00002213, + 0x00000CC7, 0x00000A0B, 0x00004A44, 0x0004003D, 0x00000011, 0x000032D8, 0x00002213, 0x00050051, + 0x0000000B, 0x00004BBD, 0x000032D8, 0x00000000, 0x00050051, 0x0000000B, 0x000018A4, 0x000032D8, + 0x00000001, 0x00070050, 0x00000017, 0x000052CF, 0x00004F4D, 0x00003AE9, 0x00004BBD, 0x000018A4, + 0x000500AA, 0x00000009, 0x00005A05, 0x00001DD8, 0x00000A0A, 0x000600A9, 0x00000009, 0x000052F9, + 0x00005A05, 0x00000787, 0x00005A05, 0x000300F7, 0x00005596, 0x00000002, 0x000400FA, 0x000052F9, + 0x00002573, 0x00005596, 0x000200F8, 0x00002573, 0x00060052, 0x00000017, 0x00003001, 0x00004BBC, + 0x00001CFA, 0x00000000, 0x00060052, 0x00000017, 0x00003706, 0x00006005, 0x00003001, 0x00000001, + 0x000200F9, 0x00005596, 0x000200F8, 0x00005596, 0x000700F5, 0x00000017, 0x00002AAC, 0x00001CFA, + 0x00001AFD, 0x00003706, 0x00002573, 0x000300F7, 0x0000530F, 0x00000002, 0x000400FA, 0x00004C75, + 0x00003ADC, 0x0000530F, 0x000200F8, 0x00003ADC, 0x000500AA, 0x00000009, 0x00003585, 0x000023AA, + 0x00000A19, 0x000400A8, 0x00000009, 0x00004277, 0x00003585, 0x000300F7, 0x00003D52, 0x00000000, + 0x000400FA, 0x00004277, 0x000040DF, 0x00003D52, 0x000200F8, 0x000040DF, 0x000500AA, 0x00000009, + 0x0000495A, 0x000023AA, 0x00000A1F, 0x000200F9, 0x00003D52, 0x000200F8, 0x00003D52, 0x000700F5, + 0x00000009, 0x00002AAD, 0x00003585, 0x00003ADC, 0x0000495A, 0x000040DF, 0x000300F7, 0x000039F4, + 0x00000002, 0x000400FA, 0x00002AAD, 0x000020A8, 0x000039F4, 0x000200F8, 0x000020A8, 0x000500C7, + 0x00000017, 0x00004BF1, 0x00002AAC, 0x00000755, 0x0009004F, 0x00000017, 0x000051EA, 0x00002AAC, + 0x00002AAC, 0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x000500C7, 0x00000017, 0x00001CED, + 0x000051EA, 0x00000352, 0x000500C5, 0x00000017, 0x00003640, 0x00004BF1, 0x00001CED, 0x000500C7, + 0x00000017, 0x00005311, 0x000052CF, 0x00000755, 0x0009004F, 0x00000017, 0x00003BF8, 0x000052CF, + 0x000052CF, 0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x000500C7, 0x00000017, 0x000020A3, + 0x00003BF8, 0x00000352, 0x000500C5, 0x00000017, 0x00002101, 0x00005311, 0x000020A3, 0x000200F9, + 0x000039F4, 0x000200F8, 0x000039F4, 0x000700F5, 0x00000017, 0x00002BF3, 0x000052CF, 0x00003D52, + 0x00002101, 0x000020A8, 0x000700F5, 0x00000017, 0x0000358D, 0x00002AAC, 0x00003D52, 0x00003640, + 0x000020A8, 0x000200F9, 0x0000530F, 0x000200F8, 0x0000530F, 0x000700F5, 0x00000017, 0x000022F8, + 0x000052CF, 0x00005596, 0x00002BF3, 0x000039F4, 0x000700F5, 0x00000017, 0x000055F9, 0x00002AAC, + 0x00005596, 0x0000358D, 0x000039F4, 0x00050080, 0x00000011, 0x00001C97, 0x00002EF9, 0x000059EC, + 0x000300F7, 0x000052F5, 0x00000002, 0x000400FA, 0x0000500F, 0x0000294E, 0x0000537D, 0x000200F8, + 0x0000537D, 0x0004007C, 0x00000012, 0x00002970, 0x00001C97, 0x00050051, 0x0000000C, 0x000042C2, + 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, + 0x0000000C, 0x00002747, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, + 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, + 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AA, 0x00050080, + 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, + 0x00000A28, 0x000500C7, 0x0000000C, 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003138, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454D, 0x000500C4, 0x0000000C, 0x000018E7, + 0x00004397, 0x00000A13, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, + 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00004A8E, + 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, + 0x00004D30, 0x00003C4B, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544A, 0x000047B4, 0x00000A17, 0x00050080, 0x0000000C, 0x00004157, + 0x00004D30, 0x0000544A, 0x000500C7, 0x0000000C, 0x00005022, 0x00004157, 0x0000040B, 0x000500C4, + 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, + 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, + 0x00004158, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADD, 0x00004157, 0x00000388, + 0x000500C4, 0x0000000C, 0x0000544B, 0x00004ADD, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, + 0x00004158, 0x0000544B, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, + 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, + 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544C, 0x00005453, 0x00000A1D, + 0x00050080, 0x0000000C, 0x00003C4C, 0x00004144, 0x0000544C, 0x000500C7, 0x0000000C, 0x00002E06, + 0x00004157, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4C, 0x00002E06, 0x0004007C, + 0x0000000B, 0x0000566F, 0x0000394F, 0x000200F9, 0x000052F5, 0x000200F8, 0x0000294E, 0x00050051, + 0x0000000B, 0x00004D9A, 0x00001C97, 0x00000000, 0x00050051, 0x0000000B, 0x00002C03, 0x00001C97, + 0x00000001, 0x00060050, 0x00000014, 0x000020DE, 0x00004D9A, 0x00002C03, 0x000059FD, 0x0004007C, + 0x00000016, 0x00004E9D, 0x000020DE, 0x00050051, 0x0000000C, 0x000028C6, 0x00004E9D, 0x00000001, + 0x000500C3, 0x0000000C, 0x000024FE, 0x000028C6, 0x00000A17, 0x00050051, 0x0000000C, 0x00002748, + 0x00004E9D, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A11, 0x000500C2, + 0x0000000B, 0x00005B4E, 0x00006273, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, + 0x00050084, 0x0000000C, 0x00005321, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003B27, + 0x000024FE, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00003DA7, 0x00000A19, 0x0004007C, + 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, + 0x00050051, 0x0000000C, 0x00006242, 0x00004E9D, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, + 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, + 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A26, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, + 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, + 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x000028C6, 0x00000A1D, + 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, + 0x00004D38, 0x0000454E, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A26, 0x000500C3, + 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000028C6, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405D, 0x000500C7, 0x0000000C, + 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, + 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000034BD, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544D, 0x00004ADE, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4D, 0x00005A0C, + 0x0000544D, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, + 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B32, 0x00004F70, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, + 0x00005B32, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544E, 0x000047B5, 0x00000A26, 0x00050080, 0x0000000C, 0x00004159, 0x0000285C, + 0x0000544E, 0x000500C7, 0x0000000C, 0x00004ADF, 0x000028C6, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544F, 0x00004ADF, 0x00000A17, 0x00050080, 0x0000000C, 0x0000415A, 0x00004159, 0x0000544F, + 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4D, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, + 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x0000415A, 0x00000A1D, 0x000500C7, + 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, + 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B33, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005AB1, 0x00003C4D, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B33, 0x00005AB1, + 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, + 0x0000415A, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B34, 0x00005AB2, 0x000500C4, + 0x0000000C, 0x00005B35, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x0000415A, + 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B35, 0x00005559, 0x0004007C, 0x0000000B, + 0x00005670, 0x00005EFA, 0x000200F9, 0x000052F5, 0x000200F8, 0x000052F5, 0x000700F5, 0x0000000B, + 0x00002C70, 0x00005670, 0x0000294E, 0x0000566F, 0x0000537D, 0x00050080, 0x0000000B, 0x00005088, + 0x00002C70, 0x000062B6, 0x000500C2, 0x0000000B, 0x00004EAA, 0x00005088, 0x00000A16, 0x000500AA, + 0x00000009, 0x00004B9C, 0x00004ADC, 0x00000A16, 0x000300F7, 0x000039BC, 0x00000000, 0x000400FA, + 0x00004B9C, 0x000033DF, 0x000039BC, 0x000200F8, 0x000033DF, 0x0009004F, 0x00000017, 0x00001F16, + 0x000055F9, 0x000055F9, 0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x000200F9, 0x000039BC, + 0x000200F8, 0x000039BC, 0x000700F5, 0x00000017, 0x00005972, 0x000055F9, 0x000052F5, 0x00001F16, + 0x000033DF, 0x000600A9, 0x0000000B, 0x000019CD, 0x00004B9C, 0x00000A10, 0x00004ADC, 0x000500AA, + 0x00000009, 0x00003464, 0x000019CD, 0x00000A0D, 0x000500AA, 0x00000009, 0x000047C2, 0x000019CD, + 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x00003464, 0x000047C2, 0x000300F7, 0x00003463, + 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, + 0x00000017, 0x0000475F, 0x00005972, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00005972, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, + 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00005972, + 0x000039BC, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000019CD, 0x00000A13, + 0x000500A6, 0x00000009, 0x00003B23, 0x000047C2, 0x00004CB6, 0x000300F7, 0x00002C98, 0x00000000, + 0x000400FA, 0x00003B23, 0x00002B38, 0x00002C98, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, + 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, + 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x00002C98, 0x000200F8, + 0x00002C98, 0x000700F5, 0x00000017, 0x00004D37, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, + 0x00060041, 0x00000294, 0x000060F9, 0x00001592, 0x00000A0B, 0x00004EAA, 0x0003003E, 0x000060F9, + 0x00004D37, 0x00050080, 0x0000000B, 0x000054B5, 0x00004EAA, 0x00000A10, 0x000300F7, 0x00003F86, + 0x00000000, 0x000400FA, 0x00004B9C, 0x000033E0, 0x00003F86, 0x000200F8, 0x000033E0, 0x0009004F, + 0x00000017, 0x00001F17, 0x000022F8, 0x000022F8, 0x00000001, 0x00000000, 0x00000003, 0x00000002, + 0x000200F9, 0x00003F86, 0x000200F8, 0x00003F86, 0x000700F5, 0x00000017, 0x00002AAE, 0x000022F8, + 0x00002C98, 0x00001F17, 0x000033E0, 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, + 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x00002AAE, + 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, + 0x000050AD, 0x00002AAE, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, + 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, + 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAF, 0x00002AAE, 0x00003F86, 0x00003FF9, 0x00002958, + 0x000300F7, 0x00002C99, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, 0x00002C99, 0x000200F8, + 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAF, 0x000002ED, 0x000500C2, 0x00000017, + 0x00003BE8, 0x00002AAF, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, + 0x000200F9, 0x00002C99, 0x000200F8, 0x00002C99, 0x000700F5, 0x00000017, 0x00004D39, 0x00002AAF, + 0x00003A1A, 0x000029E9, 0x00002B39, 0x00060041, 0x00000294, 0x00001F75, 0x00001592, 0x00000A0B, + 0x000054B5, 0x0003003E, 0x00001F75, 0x00004D39, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, + 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_fast_64bpp_4xmsaa_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_fast_64bpp_4xmsaa_scaled_cs.h new file mode 100644 index 0000000..5e8ce15 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_fast_64bpp_4xmsaa_scaled_cs.h @@ -0,0 +1,882 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25204 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_struct_1017 Block + OpMemberDecorate %_struct_1017 0 Offset 0 + OpMemberDecorate %_struct_1017 1 Offset 4 + OpMemberDecorate %_struct_1017 2 Offset 8 + OpMemberDecorate %_struct_1017 3 Offset 12 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v2uint ArrayStride 8 + OpDecorate %_struct_1960 BufferBlock + OpMemberDecorate %_struct_1960 0 NonWritable + OpMemberDecorate %_struct_1960 0 Offset 0 + OpDecorate %3271 NonWritable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonReadable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %5522 NonReadable + OpDecorate %5522 Binding 0 + OpDecorate %5522 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %bool = OpTypeBool + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %v3uint = OpTypeVector %uint 3 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_4 = OpConstant %uint 4 + %uint_0 = OpConstant %uint 0 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %uint_80 = OpConstant %uint 80 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %uint_2048 = OpConstant %uint 2048 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_6 = OpConstant %uint 6 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1017 = OpTypeStruct %uint %uint %uint %uint +%_ptr_PushConstant__struct_1017 = OpTypePointer PushConstant %_struct_1017 + %3305 = OpVariable %_ptr_PushConstant__struct_1017 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %uint_1023 = OpConstant %uint 1023 + %uint_10 = OpConstant %uint 10 + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_24 = OpConstant %uint 24 + %uint_15 = OpConstant %uint 15 + %uint_28 = OpConstant %uint 28 + %uint_19 = OpConstant %uint 19 + %2179 = OpConstantComposite %v2uint %uint_16 %uint_19 +%uint_536870912 = OpConstant %uint 536870912 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 +%uint_16777216 = OpConstant %uint 16777216 + %uint_20 = OpConstant %uint 20 + %2275 = OpConstantComposite %v2uint %uint_20 %uint_24 +%uint_4294901760 = OpConstant %uint 4294901760 + %uint_65535 = OpConstant %uint 65535 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %1825 = OpConstantComposite %v2uint %uint_2 %uint_0 +%_runtimearr_v2uint = OpTypeRuntimeArray %v2uint +%_struct_1960 = OpTypeStruct %_runtimearr_v2uint +%_ptr_Uniform__struct_1960 = OpTypePointer Uniform %_struct_1960 + %3271 = OpVariable %_ptr_Uniform__struct_1960 Uniform +%_ptr_Uniform_v2uint = OpTypePointer Uniform %v2uint +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %5522 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %1955 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %uint_9 = OpConstant %uint 9 + %1877 = OpConstantComposite %v4uint %uint_4294901760 %uint_4294901760 %uint_4294901760 %uint_4294901760 + %850 = OpConstantComposite %v4uint %uint_65535 %uint_65535 %uint_65535 %uint_65535 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %19978 = OpShiftRightLogical %uint %15627 %uint_13 + %8574 = OpBitwiseAnd %uint %19978 %uint_2047 + %18836 = OpShiftRightLogical %uint %15627 %uint_24 + %9130 = OpBitwiseAnd %uint %18836 %uint_15 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9633 = OpShiftRightLogical %v2uint %8871 %2179 + %23601 = OpBitwiseAnd %v2uint %9633 %1954 + %24030 = OpBitwiseAnd %uint %15627 %uint_536870912 + %12295 = OpINotEqual %bool %24030 %uint_0 + OpSelectionMerge %14676 None + OpBranchConditional %12295 %16739 %21992 + %21992 = OpLabel + OpBranch %14676 + %16739 = OpLabel + %15278 = OpShiftRightLogical %v2uint %23601 %1828 + OpBranch %14676 + %14676 = OpLabel + %19124 = OpPhi %v2uint %15278 %16739 %1807 %21992 + %7038 = OpShiftRightLogical %v2uint %8871 %1855 + %11769 = OpBitwiseAnd %v2uint %7038 %1955 + %16207 = OpShiftLeftLogical %v2uint %11769 %1870 + %23019 = OpIMul %v2uint %16207 %23601 + %13123 = OpShiftRightLogical %uint %20824 %uint_5 + %14785 = OpBitwiseAnd %uint %13123 %uint_2047 + %8858 = OpCompositeExtract %uint %23601 0 + %22993 = OpIMul %uint %14785 %8858 + %20036 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %18628 = OpLoad %uint %20036 + %22701 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %20919 = OpLoad %uint %22701 + %19164 = OpBitwiseAnd %uint %18628 %uint_7 + %21999 = OpBitwiseAnd %uint %18628 %uint_8 + %20495 = OpINotEqual %bool %21999 %uint_0 + %10402 = OpShiftRightLogical %uint %18628 %uint_4 + %23037 = OpBitwiseAnd %uint %10402 %uint_7 + %23118 = OpBitwiseAnd %uint %18628 %uint_16777216 + %19573 = OpINotEqual %bool %23118 %uint_0 + %8003 = OpBitwiseAnd %uint %20919 %uint_1023 + %15783 = OpShiftLeftLogical %uint %8003 %uint_5 + %22591 = OpShiftRightLogical %uint %20919 %uint_10 + %19390 = OpBitwiseAnd %uint %22591 %uint_1023 + %25203 = OpShiftLeftLogical %uint %19390 %uint_5 + %10422 = OpCompositeConstruct %v2uint %20919 %20919 + %10385 = OpShiftRightLogical %v2uint %10422 %2275 + %23379 = OpBitwiseAnd %v2uint %10385 %2122 + %16208 = OpShiftLeftLogical %v2uint %23379 %1870 + %23020 = OpIMul %v2uint %16208 %23601 + %12743 = OpShiftRightLogical %uint %20919 %uint_28 + %17238 = OpBitwiseAnd %uint %12743 %uint_7 + %12737 = OpLoad %v3uint %gl_GlobalInvocationID + %14500 = OpVectorShuffle %v2uint %12737 %12737 0 1 + %12025 = OpShiftLeftLogical %v2uint %14500 %1825 + %7640 = OpCompositeExtract %uint %12025 0 + %11658 = OpShiftLeftLogical %uint %22993 %uint_3 + %15379 = OpUGreaterThanEqual %bool %7640 %11658 + OpSelectionMerge %14025 DontFlatten + OpBranchConditional %15379 %21993 %14025 + %21993 = OpLabel + OpBranch %19578 + %14025 = OpLabel + %18615 = OpCompositeExtract %uint %12025 1 + %16803 = OpCompositeExtract %uint %19124 1 + %24446 = OpExtInst %uint %1 UMax %18615 %16803 + %20975 = OpCompositeConstruct %v2uint %7640 %24446 + %21036 = OpIAdd %v2uint %20975 %23019 + %16075 = OpULessThanEqual %bool %17238 %uint_3 + OpSelectionMerge %6909 None + OpBranchConditional %16075 %10990 %15087 + %15087 = OpLabel + %13566 = OpIEqual %bool %17238 %uint_5 + %8438 = OpSelect %uint %13566 %uint_2 %uint_0 + OpBranch %6909 + %10990 = OpLabel + OpBranch %6909 + %6909 = OpLabel + %16517 = OpPhi %uint %17238 %10990 %8438 %15087 + %11201 = OpShiftLeftLogical %v2uint %21036 %1828 + %21693 = OpCompositeConstruct %v2uint %16517 %16517 + %9093 = OpShiftRightLogical %v2uint %21693 %1816 + %16072 = OpBitwiseAnd %v2uint %9093 %1828 + %20272 = OpIAdd %v2uint %11201 %16072 + %21145 = OpIMul %v2uint %2719 %23601 + %14725 = OpShiftRightLogical %v2uint %21145 %1816 + %19799 = OpUDiv %v2uint %20272 %14725 + %20390 = OpCompositeExtract %uint %19799 1 + %11046 = OpIMul %uint %20390 %20561 + %24665 = OpCompositeExtract %uint %19799 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %8574 %21536 + %22376 = OpIMul %v2uint %19799 %14725 + %20715 = OpISub %v2uint %20272 %22376 + %7303 = OpCompositeExtract %uint %21145 0 + %22882 = OpCompositeExtract %uint %21145 1 + %13170 = OpIMul %uint %7303 %22882 + %14551 = OpIMul %uint %8742 %13170 + %6805 = OpCompositeExtract %uint %20715 1 + %23526 = OpCompositeExtract %uint %14725 0 + %22886 = OpIMul %uint %6805 %23526 + %6886 = OpCompositeExtract %uint %20715 0 + %9696 = OpIAdd %uint %22886 %6886 + %18021 = OpShiftLeftLogical %uint %9696 %uint_1 + %18363 = OpIAdd %uint %14551 %18021 + %13884 = OpIMul %uint %13170 %uint_2048 + %19795 = OpUMod %uint %18363 %13884 + %21806 = OpShiftRightLogical %uint %19795 %uint_1 + %16281 = OpAccessChain %_ptr_Uniform_v2uint %3271 %int_0 %21806 + %21044 = OpLoad %v2uint %16281 + %20300 = OpCompositeExtract %uint %21044 0 + %15080 = OpCompositeExtract %uint %21044 1 + %19011 = OpIAdd %uint %21806 %uint_2 + %8722 = OpAccessChain %_ptr_Uniform_v2uint %3271 %int_0 %19011 + %13014 = OpLoad %v2uint %8722 + %19388 = OpCompositeExtract %uint %13014 0 + %24581 = OpCompositeExtract %uint %13014 1 + %7418 = OpCompositeConstruct %v4uint %20300 %15080 %19388 %24581 + %6646 = OpIAdd %uint %21806 %uint_4 + %23758 = OpAccessChain %_ptr_Uniform_v2uint %3271 %int_0 %6646 + %13015 = OpLoad %v2uint %23758 + %20301 = OpCompositeExtract %uint %13015 0 + %15081 = OpCompositeExtract %uint %13015 1 + %19012 = OpIAdd %uint %21806 %uint_6 + %8723 = OpAccessChain %_ptr_Uniform_v2uint %3271 %int_0 %19012 + %13016 = OpLoad %v2uint %8723 + %19389 = OpCompositeExtract %uint %13016 0 + %6308 = OpCompositeExtract %uint %13016 1 + %22681 = OpCompositeConstruct %v4uint %20301 %15081 %19389 %6308 + %9608 = OpIEqual %bool %7640 %uint_0 + OpSelectionMerge %13276 None + OpBranchConditional %9608 %11451 %13276 + %11451 = OpLabel + %24156 = OpCompositeExtract %uint %19124 0 + %22470 = OpINotEqual %bool %24156 %uint_0 + OpBranch %13276 + %13276 = OpLabel + %10924 = OpPhi %bool %9608 %6909 %22470 %11451 + OpSelectionMerge %21873 DontFlatten + OpBranchConditional %10924 %11508 %21873 + %11508 = OpLabel + %23599 = OpCompositeExtract %uint %19124 0 + %17346 = OpUGreaterThanEqual %bool %23599 %uint_2 + OpSelectionMerge %21872 None + OpBranchConditional %17346 %15877 %21872 + %15877 = OpLabel + %24532 = OpUGreaterThanEqual %bool %23599 %uint_3 + OpSelectionMerge %18756 None + OpBranchConditional %24532 %9587 %18756 + %9587 = OpLabel + %12289 = OpCompositeInsert %v4uint %19389 %22681 0 + %14086 = OpCompositeInsert %v4uint %6308 %12289 1 + OpBranch %18756 + %18756 = OpLabel + %17379 = OpPhi %v4uint %22681 %15877 %14086 %9587 + %22881 = OpCompositeExtract %uint %17379 0 + %21983 = OpCompositeInsert %v4uint %22881 %7418 2 + %23044 = OpCompositeExtract %uint %17379 1 + %9296 = OpCompositeInsert %v4uint %23044 %21983 3 + OpBranch %21872 + %21872 = OpLabel + %8059 = OpPhi %v4uint %22681 %11508 %17379 %18756 + %7934 = OpPhi %v4uint %7418 %11508 %9296 %18756 + %23690 = OpCompositeExtract %uint %7934 2 + %21984 = OpCompositeInsert %v4uint %23690 %7934 0 + %23045 = OpCompositeExtract %uint %7934 3 + %9297 = OpCompositeInsert %v4uint %23045 %21984 1 + OpBranch %21873 + %21873 = OpLabel + %11213 = OpPhi %v4uint %22681 %13276 %8059 %21872 + %14093 = OpPhi %v4uint %7418 %13276 %9297 %21872 + OpSelectionMerge %21263 DontFlatten + OpBranchConditional %19573 %15068 %21263 + %15068 = OpLabel + %13701 = OpIEqual %bool %9130 %uint_5 + %17015 = OpLogicalNot %bool %13701 + OpSelectionMerge %15698 None + OpBranchConditional %17015 %16607 %15698 + %16607 = OpLabel + %18778 = OpIEqual %bool %9130 %uint_7 + OpBranch %15698 + %15698 = OpLabel + %10925 = OpPhi %bool %13701 %15068 %18778 %16607 + OpSelectionMerge %14836 DontFlatten + OpBranchConditional %10925 %8360 %14836 + %8360 = OpLabel + %19441 = OpBitwiseAnd %v4uint %14093 %1877 + %20970 = OpVectorShuffle %v4uint %14093 %14093 1 0 3 2 + %7405 = OpBitwiseAnd %v4uint %20970 %850 + %13888 = OpBitwiseOr %v4uint %19441 %7405 + %21265 = OpBitwiseAnd %v4uint %11213 %1877 + %15352 = OpVectorShuffle %v4uint %11213 %11213 1 0 3 2 + %8355 = OpBitwiseAnd %v4uint %15352 %850 + %8449 = OpBitwiseOr %v4uint %21265 %8355 + OpBranch %14836 + %14836 = OpLabel + %11251 = OpPhi %v4uint %11213 %15698 %8449 %8360 + %13709 = OpPhi %v4uint %14093 %15698 %13888 %8360 + OpBranch %21263 + %21263 = OpLabel + %8952 = OpPhi %v4uint %11213 %21873 %11251 %14836 + %18855 = OpPhi %v4uint %14093 %21873 %13709 %14836 + %13755 = OpIAdd %v2uint %12025 %23020 + %13244 = OpCompositeExtract %uint %13755 0 + %9555 = OpCompositeExtract %uint %13755 1 + %11053 = OpShiftRightLogical %uint %13244 %uint_1 + %7832 = OpCompositeConstruct %v2uint %11053 %9555 + %24920 = OpUDiv %v2uint %7832 %23601 + %13932 = OpCompositeExtract %uint %24920 0 + %19770 = OpShiftLeftLogical %uint %13932 %uint_1 + %24251 = OpCompositeExtract %uint %24920 1 + %21452 = OpCompositeConstruct %v3uint %19770 %24251 %23037 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %20495 %22206 %10904 + %10904 = OpLabel + %7339 = OpVectorShuffle %v2uint %21452 %21452 0 1 + %22991 = OpBitcast %v2int %7339 + %6403 = OpCompositeExtract %int %22991 0 + %9469 = OpShiftRightArithmetic %int %6403 %int_5 + %10055 = OpCompositeExtract %int %22991 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %15783 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_10 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17303 = OpIAdd %int %10934 %17741 + %6375 = OpShiftLeftLogical %int %17303 %uint_3 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15435 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18356 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18356 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12151 + %19165 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19165 %int_2 + %16708 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21587 %int_6 + %15436 = OpIAdd %int %16708 %21580 + %11782 = OpBitwiseAnd %int %16727 %int_63 + %14671 = OpIAdd %int %15436 %11782 + %22127 = OpBitcast %uint %14671 + OpBranch %21313 + %22206 = OpLabel + %6573 = OpBitcast %v3int %21452 + %17090 = OpCompositeExtract %int %6573 1 + %9470 = OpShiftRightArithmetic %int %17090 %int_4 + %10056 = OpCompositeExtract %int %6573 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %25203 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %15783 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %6573 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_9 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12601 = OpBitwiseAnd %int %17090 %int_6 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7048 = OpShiftLeftLogical %int %17227 %uint_9 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19166 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19166 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18357 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18357 %uint_9 + %16729 = OpIAdd %int %10332 %21582 + %19167 = OpBitwiseAnd %int %17090 %int_1 + %21583 = OpShiftLeftLogical %int %19167 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16730 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22128 = OpBitcast %uint %24314 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22128 %22206 %22127 %10904 + %16296 = OpIMul %v2uint %24920 %23601 + %16261 = OpISub %v2uint %7832 %16296 + %17551 = OpCompositeExtract %uint %23601 1 + %23632 = OpIMul %uint %8858 %17551 + %15520 = OpIMul %uint %9468 %23632 + %16084 = OpCompositeExtract %uint %16261 0 + %15890 = OpIMul %uint %16084 %17551 + %6887 = OpCompositeExtract %uint %16261 1 + %11045 = OpIAdd %uint %15890 %6887 + %24733 = OpShiftLeftLogical %uint %11045 %uint_1 + %23219 = OpBitwiseAnd %uint %13244 %uint_1 + %9559 = OpIAdd %uint %24733 %23219 + %17811 = OpShiftLeftLogical %uint %9559 %uint_3 + %8264 = OpIAdd %uint %15520 %17811 + %9676 = OpShiftRightLogical %uint %8264 %uint_4 + %19356 = OpIEqual %bool %19164 %uint_4 + OpSelectionMerge %14780 None + OpBranchConditional %19356 %13279 %14780 + %13279 = OpLabel + %7958 = OpVectorShuffle %v4uint %18855 %18855 1 0 3 2 + OpBranch %14780 + %14780 = OpLabel + %22898 = OpPhi %v4uint %18855 %21313 %7958 %13279 + %6605 = OpSelect %uint %19356 %uint_2 %19164 + %13412 = OpIEqual %bool %6605 %uint_1 + %18370 = OpIEqual %bool %6605 %uint_2 + %22150 = OpLogicalOr %bool %13412 %18370 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %22898 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %22898 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %22898 %14780 %16376 %10583 + %19638 = OpIEqual %bool %6605 %uint_3 + %15139 = OpLogicalOr %bool %18370 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %6590 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %9676 + OpStore %6590 %19767 + %23542 = OpUGreaterThan %bool %8858 %uint_1 + OpSelectionMerge %19116 DontFlatten + OpBranchConditional %23542 %14554 %21994 + %21994 = OpLabel + OpBranch %19116 + %14554 = OpLabel + %13898 = OpShiftRightLogical %uint %7640 %uint_1 + %7937 = OpUDiv %uint %13898 %8858 + %16891 = OpIMul %uint %7937 %8858 + %12657 = OpISub %uint %13898 %16891 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %8858 + OpSelectionMerge %9304 None + OpBranchConditional %13375 %7387 %21995 + %21995 = OpLabel + OpBranch %9304 + %7387 = OpLabel + %15254 = OpIMul %uint %uint_32 %8858 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18757 = OpISub %uint %15254 %21519 + OpBranch %9304 + %9304 = OpLabel + %10540 = OpPhi %uint %18757 %7387 %uint_16 %21995 + OpBranch %19116 + %19116 = OpLabel + %10684 = OpPhi %uint %10540 %9304 %uint_32 %21994 + %18731 = OpIMul %uint %10684 %17551 + %19951 = OpShiftRightLogical %uint %18731 %uint_4 + %23410 = OpIAdd %uint %9676 %19951 + OpSelectionMerge %16262 None + OpBranchConditional %19356 %13280 %16262 + %13280 = OpLabel + %7959 = OpVectorShuffle %v4uint %8952 %8952 1 0 3 2 + OpBranch %16262 + %16262 = OpLabel + %10926 = OpPhi %v4uint %8952 %19116 %7959 %13280 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %10926 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %10926 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10927 = OpPhi %v4uint %10926 %16262 %16377 %10584 + OpSelectionMerge %11417 None + OpBranchConditional %15139 %11065 %11417 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10927 %749 + %15336 = OpShiftRightLogical %v4uint %10927 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %10927 %14874 %10729 %11065 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %23410 + OpStore %8053 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_fast_64bpp_4xmsaa_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006274, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00030047, 0x000003F9, 0x00000002, 0x00050048, + 0x000003F9, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x000003F9, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x000003F9, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x000003F9, + 0x00000003, 0x00000023, 0x0000000C, 0x00040047, 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, + 0x000007D6, 0x00000006, 0x00000008, 0x00030047, 0x000007A8, 0x00000003, 0x00040048, 0x000007A8, + 0x00000000, 0x00000018, 0x00050048, 0x000007A8, 0x00000000, 0x00000023, 0x00000000, 0x00030047, + 0x00000CC7, 0x00000018, 0x00040047, 0x00000CC7, 0x00000021, 0x00000000, 0x00040047, 0x00000CC7, + 0x00000022, 0x00000000, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, 0x000007B4, + 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000019, 0x00050048, 0x000007B4, 0x00000000, + 0x00000023, 0x00000000, 0x00030047, 0x00001592, 0x00000019, 0x00040047, 0x00001592, 0x00000021, + 0x00000000, 0x00040047, 0x00001592, 0x00000022, 0x00000001, 0x00040047, 0x00000AC7, 0x0000000B, + 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000B, + 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00020014, 0x00000009, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, + 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, + 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, + 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, + 0x0005002C, 0x00000011, 0x0000070F, 0x00000A0A, 0x00000A0A, 0x0005002C, 0x00000011, 0x00000724, + 0x00000A0D, 0x00000A0D, 0x0005002C, 0x00000011, 0x00000718, 0x00000A0D, 0x00000A0A, 0x0004002B, + 0x0000000B, 0x00000AFA, 0x00000050, 0x0005002C, 0x00000011, 0x00000A9F, 0x00000AFA, 0x00000A3A, + 0x0004002B, 0x0000000B, 0x00000A84, 0x00000800, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, + 0x0006001E, 0x000003F9, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000676, + 0x00000009, 0x000003F9, 0x0004003B, 0x00000676, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0004002B, 0x0000000B, + 0x00000A44, 0x000003FF, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, + 0x00000A31, 0x0000000D, 0x0004002B, 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, + 0x00000A52, 0x00000018, 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, 0x0004002B, 0x0000000B, + 0x00000A5E, 0x0000001C, 0x0004002B, 0x0000000B, 0x00000A43, 0x00000013, 0x0005002C, 0x00000011, + 0x00000883, 0x00000A3A, 0x00000A43, 0x0004002B, 0x0000000B, 0x00000510, 0x20000000, 0x0005002C, + 0x00000011, 0x0000073F, 0x00000A0A, 0x00000A16, 0x0004002B, 0x0000000B, 0x00000926, 0x01000000, + 0x0004002B, 0x0000000B, 0x00000A46, 0x00000014, 0x0005002C, 0x00000011, 0x000008E3, 0x00000A46, + 0x00000A52, 0x0004002B, 0x0000000B, 0x0000068D, 0xFFFF0000, 0x0004002B, 0x0000000B, 0x000001C1, + 0x0000FFFF, 0x00040020, 0x00000291, 0x00000001, 0x00000014, 0x0004003B, 0x00000291, 0x00000F48, + 0x00000001, 0x0005002C, 0x00000011, 0x00000721, 0x00000A10, 0x00000A0A, 0x0003001D, 0x000007D6, + 0x00000011, 0x0003001E, 0x000007A8, 0x000007D6, 0x00040020, 0x00000A25, 0x00000002, 0x000007A8, + 0x0004003B, 0x00000A25, 0x00000CC7, 0x00000002, 0x00040020, 0x0000028E, 0x00000002, 0x00000011, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A32, 0x00001592, 0x00000002, 0x00040020, 0x00000294, + 0x00000002, 0x00000017, 0x0006002C, 0x00000014, 0x00000AC7, 0x00000A22, 0x00000A22, 0x00000A0D, + 0x0005002C, 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0005002C, 0x00000011, 0x000007A3, + 0x00000A37, 0x00000A0D, 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, 0x0005002C, + 0x00000011, 0x0000084A, 0x00000A37, 0x00000A37, 0x0004002B, 0x0000000B, 0x00000A26, 0x00000009, + 0x0007002C, 0x00000017, 0x00000755, 0x0000068D, 0x0000068D, 0x0000068D, 0x0000068D, 0x0007002C, + 0x00000017, 0x00000352, 0x000001C1, 0x000001C1, 0x000001C1, 0x000001C1, 0x0007002C, 0x00000017, + 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, + 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, + 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, + 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, + 0x00002E68, 0x00050041, 0x00000288, 0x000056E5, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, + 0x00003D0B, 0x000056E5, 0x00050041, 0x00000288, 0x000058AC, 0x00000CE9, 0x00000A0E, 0x0004003D, + 0x0000000B, 0x00005158, 0x000058AC, 0x000500C7, 0x0000000B, 0x00005051, 0x00003D0B, 0x00000A44, + 0x000500C2, 0x0000000B, 0x00004E0A, 0x00003D0B, 0x00000A31, 0x000500C7, 0x0000000B, 0x0000217E, + 0x00004E0A, 0x00000A81, 0x000500C2, 0x0000000B, 0x00004994, 0x00003D0B, 0x00000A52, 0x000500C7, + 0x0000000B, 0x000023AA, 0x00004994, 0x00000A37, 0x00050050, 0x00000011, 0x000022A7, 0x00005158, + 0x00005158, 0x000500C2, 0x00000011, 0x000025A1, 0x000022A7, 0x00000883, 0x000500C7, 0x00000011, + 0x00005C31, 0x000025A1, 0x000007A2, 0x000500C7, 0x0000000B, 0x00005DDE, 0x00003D0B, 0x00000510, + 0x000500AB, 0x00000009, 0x00003007, 0x00005DDE, 0x00000A0A, 0x000300F7, 0x00003954, 0x00000000, + 0x000400FA, 0x00003007, 0x00004163, 0x000055E8, 0x000200F8, 0x000055E8, 0x000200F9, 0x00003954, + 0x000200F8, 0x00004163, 0x000500C2, 0x00000011, 0x00003BAE, 0x00005C31, 0x00000724, 0x000200F9, + 0x00003954, 0x000200F8, 0x00003954, 0x000700F5, 0x00000011, 0x00004AB4, 0x00003BAE, 0x00004163, + 0x0000070F, 0x000055E8, 0x000500C2, 0x00000011, 0x00001B7E, 0x000022A7, 0x0000073F, 0x000500C7, + 0x00000011, 0x00002DF9, 0x00001B7E, 0x000007A3, 0x000500C4, 0x00000011, 0x00003F4F, 0x00002DF9, + 0x0000074E, 0x00050084, 0x00000011, 0x000059EB, 0x00003F4F, 0x00005C31, 0x000500C2, 0x0000000B, + 0x00003343, 0x00005158, 0x00000A19, 0x000500C7, 0x0000000B, 0x000039C1, 0x00003343, 0x00000A81, + 0x00050051, 0x0000000B, 0x0000229A, 0x00005C31, 0x00000000, 0x00050084, 0x0000000B, 0x000059D1, + 0x000039C1, 0x0000229A, 0x00050041, 0x00000288, 0x00004E44, 0x00000CE9, 0x00000A11, 0x0004003D, + 0x0000000B, 0x000048C4, 0x00004E44, 0x00050041, 0x00000288, 0x000058AD, 0x00000CE9, 0x00000A14, + 0x0004003D, 0x0000000B, 0x000051B7, 0x000058AD, 0x000500C7, 0x0000000B, 0x00004ADC, 0x000048C4, + 0x00000A1F, 0x000500C7, 0x0000000B, 0x000055EF, 0x000048C4, 0x00000A22, 0x000500AB, 0x00000009, + 0x0000500F, 0x000055EF, 0x00000A0A, 0x000500C2, 0x0000000B, 0x000028A2, 0x000048C4, 0x00000A16, + 0x000500C7, 0x0000000B, 0x000059FD, 0x000028A2, 0x00000A1F, 0x000500C7, 0x0000000B, 0x00005A4E, + 0x000048C4, 0x00000926, 0x000500AB, 0x00000009, 0x00004C75, 0x00005A4E, 0x00000A0A, 0x000500C7, + 0x0000000B, 0x00001F43, 0x000051B7, 0x00000A44, 0x000500C4, 0x0000000B, 0x00003DA7, 0x00001F43, + 0x00000A19, 0x000500C2, 0x0000000B, 0x0000583F, 0x000051B7, 0x00000A28, 0x000500C7, 0x0000000B, + 0x00004BBE, 0x0000583F, 0x00000A44, 0x000500C4, 0x0000000B, 0x00006273, 0x00004BBE, 0x00000A19, + 0x00050050, 0x00000011, 0x000028B6, 0x000051B7, 0x000051B7, 0x000500C2, 0x00000011, 0x00002891, + 0x000028B6, 0x000008E3, 0x000500C7, 0x00000011, 0x00005B53, 0x00002891, 0x0000084A, 0x000500C4, + 0x00000011, 0x00003F50, 0x00005B53, 0x0000074E, 0x00050084, 0x00000011, 0x000059EC, 0x00003F50, + 0x00005C31, 0x000500C2, 0x0000000B, 0x000031C7, 0x000051B7, 0x00000A5E, 0x000500C7, 0x0000000B, + 0x00004356, 0x000031C7, 0x00000A1F, 0x0004003D, 0x00000014, 0x000031C1, 0x00000F48, 0x0007004F, + 0x00000011, 0x000038A4, 0x000031C1, 0x000031C1, 0x00000000, 0x00000001, 0x000500C4, 0x00000011, + 0x00002EF9, 0x000038A4, 0x00000721, 0x00050051, 0x0000000B, 0x00001DD8, 0x00002EF9, 0x00000000, + 0x000500C4, 0x0000000B, 0x00002D8A, 0x000059D1, 0x00000A13, 0x000500AE, 0x00000009, 0x00003C13, + 0x00001DD8, 0x00002D8A, 0x000300F7, 0x000036C9, 0x00000002, 0x000400FA, 0x00003C13, 0x000055E9, + 0x000036C9, 0x000200F8, 0x000055E9, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000036C9, 0x00050051, + 0x0000000B, 0x000048B7, 0x00002EF9, 0x00000001, 0x00050051, 0x0000000B, 0x000041A3, 0x00004AB4, + 0x00000001, 0x0007000C, 0x0000000B, 0x00005F7E, 0x00000001, 0x00000029, 0x000048B7, 0x000041A3, + 0x00050050, 0x00000011, 0x000051EF, 0x00001DD8, 0x00005F7E, 0x00050080, 0x00000011, 0x0000522C, + 0x000051EF, 0x000059EB, 0x000500B2, 0x00000009, 0x00003ECB, 0x00004356, 0x00000A13, 0x000300F7, + 0x00001AFD, 0x00000000, 0x000400FA, 0x00003ECB, 0x00002AEE, 0x00003AEF, 0x000200F8, 0x00003AEF, + 0x000500AA, 0x00000009, 0x000034FE, 0x00004356, 0x00000A19, 0x000600A9, 0x0000000B, 0x000020F6, + 0x000034FE, 0x00000A10, 0x00000A0A, 0x000200F9, 0x00001AFD, 0x000200F8, 0x00002AEE, 0x000200F9, + 0x00001AFD, 0x000200F8, 0x00001AFD, 0x000700F5, 0x0000000B, 0x00004085, 0x00004356, 0x00002AEE, + 0x000020F6, 0x00003AEF, 0x000500C4, 0x00000011, 0x00002BC1, 0x0000522C, 0x00000724, 0x00050050, + 0x00000011, 0x000054BD, 0x00004085, 0x00004085, 0x000500C2, 0x00000011, 0x00002385, 0x000054BD, + 0x00000718, 0x000500C7, 0x00000011, 0x00003EC8, 0x00002385, 0x00000724, 0x00050080, 0x00000011, + 0x00004F30, 0x00002BC1, 0x00003EC8, 0x00050084, 0x00000011, 0x00005299, 0x00000A9F, 0x00005C31, + 0x000500C2, 0x00000011, 0x00003985, 0x00005299, 0x00000718, 0x00050086, 0x00000011, 0x00004D57, + 0x00004F30, 0x00003985, 0x00050051, 0x0000000B, 0x00004FA6, 0x00004D57, 0x00000001, 0x00050084, + 0x0000000B, 0x00002B26, 0x00004FA6, 0x00005051, 0x00050051, 0x0000000B, 0x00006059, 0x00004D57, + 0x00000000, 0x00050080, 0x0000000B, 0x00005420, 0x00002B26, 0x00006059, 0x00050080, 0x0000000B, + 0x00002226, 0x0000217E, 0x00005420, 0x00050084, 0x00000011, 0x00005768, 0x00004D57, 0x00003985, + 0x00050082, 0x00000011, 0x000050EB, 0x00004F30, 0x00005768, 0x00050051, 0x0000000B, 0x00001C87, + 0x00005299, 0x00000000, 0x00050051, 0x0000000B, 0x00005962, 0x00005299, 0x00000001, 0x00050084, + 0x0000000B, 0x00003372, 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, 0x000038D7, 0x00002226, + 0x00003372, 0x00050051, 0x0000000B, 0x00001A95, 0x000050EB, 0x00000001, 0x00050051, 0x0000000B, + 0x00005BE6, 0x00003985, 0x00000000, 0x00050084, 0x0000000B, 0x00005966, 0x00001A95, 0x00005BE6, + 0x00050051, 0x0000000B, 0x00001AE6, 0x000050EB, 0x00000000, 0x00050080, 0x0000000B, 0x000025E0, + 0x00005966, 0x00001AE6, 0x000500C4, 0x0000000B, 0x00004665, 0x000025E0, 0x00000A0D, 0x00050080, + 0x0000000B, 0x000047BB, 0x000038D7, 0x00004665, 0x00050084, 0x0000000B, 0x0000363C, 0x00003372, + 0x00000A84, 0x00050089, 0x0000000B, 0x00004D53, 0x000047BB, 0x0000363C, 0x000500C2, 0x0000000B, + 0x0000552E, 0x00004D53, 0x00000A0D, 0x00060041, 0x0000028E, 0x00003F99, 0x00000CC7, 0x00000A0B, + 0x0000552E, 0x0004003D, 0x00000011, 0x00005234, 0x00003F99, 0x00050051, 0x0000000B, 0x00004F4C, + 0x00005234, 0x00000000, 0x00050051, 0x0000000B, 0x00003AE8, 0x00005234, 0x00000001, 0x00050080, + 0x0000000B, 0x00004A43, 0x0000552E, 0x00000A10, 0x00060041, 0x0000028E, 0x00002212, 0x00000CC7, + 0x00000A0B, 0x00004A43, 0x0004003D, 0x00000011, 0x000032D6, 0x00002212, 0x00050051, 0x0000000B, + 0x00004BBC, 0x000032D6, 0x00000000, 0x00050051, 0x0000000B, 0x00006005, 0x000032D6, 0x00000001, + 0x00070050, 0x00000017, 0x00001CFA, 0x00004F4C, 0x00003AE8, 0x00004BBC, 0x00006005, 0x00050080, + 0x0000000B, 0x000019F6, 0x0000552E, 0x00000A16, 0x00060041, 0x0000028E, 0x00005CCE, 0x00000CC7, + 0x00000A0B, 0x000019F6, 0x0004003D, 0x00000011, 0x000032D7, 0x00005CCE, 0x00050051, 0x0000000B, + 0x00004F4D, 0x000032D7, 0x00000000, 0x00050051, 0x0000000B, 0x00003AE9, 0x000032D7, 0x00000001, + 0x00050080, 0x0000000B, 0x00004A44, 0x0000552E, 0x00000A1C, 0x00060041, 0x0000028E, 0x00002213, + 0x00000CC7, 0x00000A0B, 0x00004A44, 0x0004003D, 0x00000011, 0x000032D8, 0x00002213, 0x00050051, + 0x0000000B, 0x00004BBD, 0x000032D8, 0x00000000, 0x00050051, 0x0000000B, 0x000018A4, 0x000032D8, + 0x00000001, 0x00070050, 0x00000017, 0x00005899, 0x00004F4D, 0x00003AE9, 0x00004BBD, 0x000018A4, + 0x000500AA, 0x00000009, 0x00002588, 0x00001DD8, 0x00000A0A, 0x000300F7, 0x000033DC, 0x00000000, + 0x000400FA, 0x00002588, 0x00002CBB, 0x000033DC, 0x000200F8, 0x00002CBB, 0x00050051, 0x0000000B, + 0x00005E5C, 0x00004AB4, 0x00000000, 0x000500AB, 0x00000009, 0x000057C6, 0x00005E5C, 0x00000A0A, + 0x000200F9, 0x000033DC, 0x000200F8, 0x000033DC, 0x000700F5, 0x00000009, 0x00002AAC, 0x00002588, + 0x00001AFD, 0x000057C6, 0x00002CBB, 0x000300F7, 0x00005571, 0x00000002, 0x000400FA, 0x00002AAC, + 0x00002CF4, 0x00005571, 0x000200F8, 0x00002CF4, 0x00050051, 0x0000000B, 0x00005C2F, 0x00004AB4, + 0x00000000, 0x000500AE, 0x00000009, 0x000043C2, 0x00005C2F, 0x00000A10, 0x000300F7, 0x00005570, + 0x00000000, 0x000400FA, 0x000043C2, 0x00003E05, 0x00005570, 0x000200F8, 0x00003E05, 0x000500AE, + 0x00000009, 0x00005FD4, 0x00005C2F, 0x00000A13, 0x000300F7, 0x00004944, 0x00000000, 0x000400FA, + 0x00005FD4, 0x00002573, 0x00004944, 0x000200F8, 0x00002573, 0x00060052, 0x00000017, 0x00003001, + 0x00004BBD, 0x00005899, 0x00000000, 0x00060052, 0x00000017, 0x00003706, 0x000018A4, 0x00003001, + 0x00000001, 0x000200F9, 0x00004944, 0x000200F8, 0x00004944, 0x000700F5, 0x00000017, 0x000043E3, + 0x00005899, 0x00003E05, 0x00003706, 0x00002573, 0x00050051, 0x0000000B, 0x00005961, 0x000043E3, + 0x00000000, 0x00060052, 0x00000017, 0x000055DF, 0x00005961, 0x00001CFA, 0x00000002, 0x00050051, + 0x0000000B, 0x00005A04, 0x000043E3, 0x00000001, 0x00060052, 0x00000017, 0x00002450, 0x00005A04, + 0x000055DF, 0x00000003, 0x000200F9, 0x00005570, 0x000200F8, 0x00005570, 0x000700F5, 0x00000017, + 0x00001F7B, 0x00005899, 0x00002CF4, 0x000043E3, 0x00004944, 0x000700F5, 0x00000017, 0x00001EFE, + 0x00001CFA, 0x00002CF4, 0x00002450, 0x00004944, 0x00050051, 0x0000000B, 0x00005C8A, 0x00001EFE, + 0x00000002, 0x00060052, 0x00000017, 0x000055E0, 0x00005C8A, 0x00001EFE, 0x00000000, 0x00050051, + 0x0000000B, 0x00005A05, 0x00001EFE, 0x00000003, 0x00060052, 0x00000017, 0x00002451, 0x00005A05, + 0x000055E0, 0x00000001, 0x000200F9, 0x00005571, 0x000200F8, 0x00005571, 0x000700F5, 0x00000017, + 0x00002BCD, 0x00005899, 0x000033DC, 0x00001F7B, 0x00005570, 0x000700F5, 0x00000017, 0x0000370D, + 0x00001CFA, 0x000033DC, 0x00002451, 0x00005570, 0x000300F7, 0x0000530F, 0x00000002, 0x000400FA, + 0x00004C75, 0x00003ADC, 0x0000530F, 0x000200F8, 0x00003ADC, 0x000500AA, 0x00000009, 0x00003585, + 0x000023AA, 0x00000A19, 0x000400A8, 0x00000009, 0x00004277, 0x00003585, 0x000300F7, 0x00003D52, + 0x00000000, 0x000400FA, 0x00004277, 0x000040DF, 0x00003D52, 0x000200F8, 0x000040DF, 0x000500AA, + 0x00000009, 0x0000495A, 0x000023AA, 0x00000A1F, 0x000200F9, 0x00003D52, 0x000200F8, 0x00003D52, + 0x000700F5, 0x00000009, 0x00002AAD, 0x00003585, 0x00003ADC, 0x0000495A, 0x000040DF, 0x000300F7, + 0x000039F4, 0x00000002, 0x000400FA, 0x00002AAD, 0x000020A8, 0x000039F4, 0x000200F8, 0x000020A8, + 0x000500C7, 0x00000017, 0x00004BF1, 0x0000370D, 0x00000755, 0x0009004F, 0x00000017, 0x000051EA, + 0x0000370D, 0x0000370D, 0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x000500C7, 0x00000017, + 0x00001CED, 0x000051EA, 0x00000352, 0x000500C5, 0x00000017, 0x00003640, 0x00004BF1, 0x00001CED, + 0x000500C7, 0x00000017, 0x00005311, 0x00002BCD, 0x00000755, 0x0009004F, 0x00000017, 0x00003BF8, + 0x00002BCD, 0x00002BCD, 0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x000500C7, 0x00000017, + 0x000020A3, 0x00003BF8, 0x00000352, 0x000500C5, 0x00000017, 0x00002101, 0x00005311, 0x000020A3, + 0x000200F9, 0x000039F4, 0x000200F8, 0x000039F4, 0x000700F5, 0x00000017, 0x00002BF3, 0x00002BCD, + 0x00003D52, 0x00002101, 0x000020A8, 0x000700F5, 0x00000017, 0x0000358D, 0x0000370D, 0x00003D52, + 0x00003640, 0x000020A8, 0x000200F9, 0x0000530F, 0x000200F8, 0x0000530F, 0x000700F5, 0x00000017, + 0x000022F8, 0x00002BCD, 0x00005571, 0x00002BF3, 0x000039F4, 0x000700F5, 0x00000017, 0x000049A7, + 0x0000370D, 0x00005571, 0x0000358D, 0x000039F4, 0x00050080, 0x00000011, 0x000035BB, 0x00002EF9, + 0x000059EC, 0x00050051, 0x0000000B, 0x000033BC, 0x000035BB, 0x00000000, 0x00050051, 0x0000000B, + 0x00002553, 0x000035BB, 0x00000001, 0x000500C2, 0x0000000B, 0x00002B2D, 0x000033BC, 0x00000A0D, + 0x00050050, 0x00000011, 0x00001E98, 0x00002B2D, 0x00002553, 0x00050086, 0x00000011, 0x00006158, + 0x00001E98, 0x00005C31, 0x00050051, 0x0000000B, 0x0000366C, 0x00006158, 0x00000000, 0x000500C4, + 0x0000000B, 0x00004D3A, 0x0000366C, 0x00000A0D, 0x00050051, 0x0000000B, 0x00005EBB, 0x00006158, + 0x00000001, 0x00060050, 0x00000014, 0x000053CC, 0x00004D3A, 0x00005EBB, 0x000059FD, 0x000300F7, + 0x00005341, 0x00000002, 0x000400FA, 0x0000500F, 0x000056BE, 0x00002A98, 0x000200F8, 0x00002A98, + 0x0007004F, 0x00000011, 0x00001CAB, 0x000053CC, 0x000053CC, 0x00000000, 0x00000001, 0x0004007C, + 0x00000012, 0x000059CF, 0x00001CAB, 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, 0x00000000, + 0x000500C3, 0x0000000C, 0x000024FD, 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, + 0x000059CF, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, + 0x0000000B, 0x00005B4D, 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, + 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003F5E, + 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A28, 0x000500C7, + 0x0000000C, 0x00002AB6, 0x00001903, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x00002747, + 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, + 0x00004397, 0x00002AB6, 0x0000454D, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A13, + 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, + 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00004A8E, 0x00002F76, 0x000500C7, + 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4B, + 0x00003397, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544A, 0x000047B4, 0x00000A17, 0x00050080, 0x0000000C, 0x00004157, 0x00004D30, 0x0000544A, + 0x000500C7, 0x0000000C, 0x00005022, 0x00004157, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, + 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, + 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x00004158, 0x00002416, + 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADD, 0x00004157, 0x00000388, 0x000500C4, 0x0000000C, + 0x0000544B, 0x00004ADD, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x00004158, 0x0000544B, + 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, + 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x00001903, 0x00000A14, 0x00050080, + 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544C, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, + 0x00003C4C, 0x00004144, 0x0000544C, 0x000500C7, 0x0000000C, 0x00002E06, 0x00004157, 0x00000AC8, + 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4C, 0x00002E06, 0x0004007C, 0x0000000B, 0x0000566F, + 0x0000394F, 0x000200F9, 0x00005341, 0x000200F8, 0x000056BE, 0x0004007C, 0x00000016, 0x000019AD, + 0x000053CC, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, + 0x000024FE, 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002748, 0x000019AD, 0x00000002, + 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4E, + 0x00006273, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, + 0x00005321, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FE, 0x00005321, + 0x000500C2, 0x0000000B, 0x00002348, 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, + 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, + 0x00006242, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, + 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, + 0x000049FC, 0x00000A26, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, + 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, + 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, + 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454E, + 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A26, 0x000500C3, 0x0000000C, 0x00005DE3, + 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, 0x00050080, + 0x0000000C, 0x000035A3, 0x00002215, 0x0000405D, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, + 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, + 0x000500C7, 0x0000000C, 0x00004ADE, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544D, + 0x00004ADE, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4D, 0x00005A0C, 0x0000544D, 0x000500C7, + 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, + 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, + 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, + 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544E, + 0x000047B5, 0x00000A26, 0x00050080, 0x0000000C, 0x00004159, 0x0000285C, 0x0000544E, 0x000500C7, + 0x0000000C, 0x00004ADF, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544F, 0x00004ADF, + 0x00000A17, 0x00050080, 0x0000000C, 0x0000415A, 0x00004159, 0x0000544F, 0x000500C7, 0x0000000C, + 0x00004FD6, 0x00003C4D, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, + 0x000500C3, 0x0000000C, 0x00003332, 0x0000415A, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, + 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, + 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4D, + 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, + 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x0000415A, 0x0000040B, + 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, + 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x0000415A, 0x00000AC8, 0x00050080, + 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, 0x00005670, 0x00005EFA, + 0x000200F9, 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, 0x000024FC, 0x00005670, + 0x000056BE, 0x0000566F, 0x00002A98, 0x00050084, 0x00000011, 0x00003FA8, 0x00006158, 0x00005C31, + 0x00050082, 0x00000011, 0x00003F85, 0x00001E98, 0x00003FA8, 0x00050051, 0x0000000B, 0x0000448F, + 0x00005C31, 0x00000001, 0x00050084, 0x0000000B, 0x00005C50, 0x0000229A, 0x0000448F, 0x00050084, + 0x0000000B, 0x00003CA0, 0x000024FC, 0x00005C50, 0x00050051, 0x0000000B, 0x00003ED4, 0x00003F85, + 0x00000000, 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, 0x0000448F, 0x00050051, 0x0000000B, + 0x00001AE7, 0x00003F85, 0x00000001, 0x00050080, 0x0000000B, 0x00002B25, 0x00003E12, 0x00001AE7, + 0x000500C4, 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00005AB3, + 0x000033BC, 0x00000A0D, 0x00050080, 0x0000000B, 0x00002557, 0x0000609D, 0x00005AB3, 0x000500C4, + 0x0000000B, 0x00004593, 0x00002557, 0x00000A13, 0x00050080, 0x0000000B, 0x00002048, 0x00003CA0, + 0x00004593, 0x000500C2, 0x0000000B, 0x000025CC, 0x00002048, 0x00000A16, 0x000500AA, 0x00000009, + 0x00004B9C, 0x00004ADC, 0x00000A16, 0x000300F7, 0x000039BC, 0x00000000, 0x000400FA, 0x00004B9C, + 0x000033DF, 0x000039BC, 0x000200F8, 0x000033DF, 0x0009004F, 0x00000017, 0x00001F16, 0x000049A7, + 0x000049A7, 0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x000200F9, 0x000039BC, 0x000200F8, + 0x000039BC, 0x000700F5, 0x00000017, 0x00005972, 0x000049A7, 0x00005341, 0x00001F16, 0x000033DF, + 0x000600A9, 0x0000000B, 0x000019CD, 0x00004B9C, 0x00000A10, 0x00004ADC, 0x000500AA, 0x00000009, + 0x00003464, 0x000019CD, 0x00000A0D, 0x000500AA, 0x00000009, 0x000047C2, 0x000019CD, 0x00000A10, + 0x000500A6, 0x00000009, 0x00005686, 0x00003464, 0x000047C2, 0x000300F7, 0x00003463, 0x00000000, + 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, + 0x0000475F, 0x00005972, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AC, 0x00005972, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, + 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, + 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00005972, 0x000039BC, + 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000019CD, 0x00000A13, 0x000500A6, + 0x00000009, 0x00003B23, 0x000047C2, 0x00004CB6, 0x000300F7, 0x00002C98, 0x00000000, 0x000400FA, + 0x00003B23, 0x00002B38, 0x00002C98, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, + 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, + 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x00002C98, 0x000200F8, 0x00002C98, + 0x000700F5, 0x00000017, 0x00004D37, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x00060041, + 0x00000294, 0x000019BE, 0x00001592, 0x00000A0B, 0x000025CC, 0x0003003E, 0x000019BE, 0x00004D37, + 0x000500AC, 0x00000009, 0x00005BF6, 0x0000229A, 0x00000A0D, 0x000300F7, 0x00004AAC, 0x00000002, + 0x000400FA, 0x00005BF6, 0x000038DA, 0x000055EA, 0x000200F8, 0x000055EA, 0x000200F9, 0x00004AAC, + 0x000200F8, 0x000038DA, 0x000500C2, 0x0000000B, 0x0000364A, 0x00001DD8, 0x00000A0D, 0x00050086, + 0x0000000B, 0x00001F01, 0x0000364A, 0x0000229A, 0x00050084, 0x0000000B, 0x000041FB, 0x00001F01, + 0x0000229A, 0x00050082, 0x0000000B, 0x00003171, 0x0000364A, 0x000041FB, 0x00050080, 0x0000000B, + 0x00002527, 0x00003171, 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, 0x0000229A, + 0x000300F7, 0x00002458, 0x00000000, 0x000400FA, 0x0000343F, 0x00001CDB, 0x000055EB, 0x000200F8, + 0x000055EB, 0x000200F9, 0x00002458, 0x000200F8, 0x00001CDB, 0x00050084, 0x0000000B, 0x00003B96, + 0x00000A6A, 0x0000229A, 0x000500C4, 0x0000000B, 0x0000540F, 0x00003171, 0x00000A16, 0x00050082, + 0x0000000B, 0x00004945, 0x00003B96, 0x0000540F, 0x000200F9, 0x00002458, 0x000200F8, 0x00002458, + 0x000700F5, 0x0000000B, 0x0000292C, 0x00004945, 0x00001CDB, 0x00000A3A, 0x000055EB, 0x000200F9, + 0x00004AAC, 0x000200F8, 0x00004AAC, 0x000700F5, 0x0000000B, 0x000029BC, 0x0000292C, 0x00002458, + 0x00000A6A, 0x000055EA, 0x00050084, 0x0000000B, 0x0000492B, 0x000029BC, 0x0000448F, 0x000500C2, + 0x0000000B, 0x00004DEF, 0x0000492B, 0x00000A16, 0x00050080, 0x0000000B, 0x00005B72, 0x000025CC, + 0x00004DEF, 0x000300F7, 0x00003F86, 0x00000000, 0x000400FA, 0x00004B9C, 0x000033E0, 0x00003F86, + 0x000200F8, 0x000033E0, 0x0009004F, 0x00000017, 0x00001F17, 0x000022F8, 0x000022F8, 0x00000001, + 0x00000000, 0x00000003, 0x00000002, 0x000200F9, 0x00003F86, 0x000200F8, 0x00003F86, 0x000700F5, + 0x00000017, 0x00002AAE, 0x000022F8, 0x00004AAC, 0x00001F17, 0x000033E0, 0x000300F7, 0x00003A1A, + 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, + 0x00000017, 0x00004760, 0x00002AAE, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x00002AAE, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, + 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAF, 0x00002AAE, + 0x00003F86, 0x00003FF9, 0x00002958, 0x000300F7, 0x00002C99, 0x00000000, 0x000400FA, 0x00003B23, + 0x00002B39, 0x00002C99, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAF, + 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAF, 0x000002ED, 0x000500C5, 0x00000017, + 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002C99, 0x000200F8, 0x00002C99, 0x000700F5, + 0x00000017, 0x00004D39, 0x00002AAF, 0x00003A1A, 0x000029E9, 0x00002B39, 0x00060041, 0x00000294, + 0x00001F75, 0x00001592, 0x00000A0B, 0x00005B72, 0x0003003E, 0x00001F75, 0x00004D39, 0x000200F9, + 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_full_128bpp_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_full_128bpp_cs.h new file mode 100644 index 0000000..23418f4 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_full_128bpp_cs.h @@ -0,0 +1,2488 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25271 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_runtimearr_uint ArrayStride 4 + OpDecorate %_struct_1948 BufferBlock + OpMemberDecorate %_struct_1948 0 NonWritable + OpMemberDecorate %_struct_1948 0 Offset 0 + OpDecorate %3271 NonWritable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %_struct_1036 Block + OpMemberDecorate %_struct_1036 0 Offset 0 + OpMemberDecorate %_struct_1036 1 Offset 4 + OpMemberDecorate %_struct_1036 2 Offset 8 + OpMemberDecorate %_struct_1036 3 Offset 12 + OpMemberDecorate %_struct_1036 4 Offset 16 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonReadable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %5522 NonReadable + OpDecorate %5522 Binding 0 + OpDecorate %5522 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %v4uint = OpTypeVector %uint 4 + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 + %v4float = OpTypeVector %float 4 + %bool = OpTypeBool + %v3int = OpTypeVector %int 3 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_4 = OpConstant %uint 4 + %uint_5 = OpConstant %uint 5 + %uint_0 = OpConstant %uint 0 + %uint_24 = OpConstant %uint 24 + %653 = OpConstantComposite %v4uint %uint_0 %uint_8 %uint_16 %uint_24 + %uint_255 = OpConstant %uint 255 +%float_0_00392156886 = OpConstant %float 0.00392156886 + %uint_10 = OpConstant %uint 10 + %uint_20 = OpConstant %uint 20 + %uint_30 = OpConstant %uint 30 + %845 = OpConstantComposite %v4uint %uint_0 %uint_10 %uint_20 %uint_30 + %uint_1023 = OpConstant %uint 1023 + %635 = OpConstantComposite %v4uint %uint_1023 %uint_1023 %uint_1023 %uint_3 +%float_0_000977517106 = OpConstant %float 0.000977517106 +%float_0_333333343 = OpConstant %float 0.333333343 + %2798 = OpConstantComposite %v4float %float_0_000977517106 %float_0_000977517106 %float_0_000977517106 %float_0_333333343 + %2996 = OpConstantComposite %v3uint %uint_0 %uint_10 %uint_20 + %uint_127 = OpConstant %uint 127 + %uint_7 = OpConstant %uint 7 + %v3bool = OpTypeVector %bool 3 + %uint_124 = OpConstant %uint 124 + %uint_23 = OpConstant %uint 23 + %v3float = OpTypeVector %float 3 + %float_n1 = OpConstant %float -1 + %int_16 = OpConstant %int 16 + %int_0 = OpConstant %int 0 + %1959 = OpConstantComposite %v2int %int_16 %int_0 +%float_0_000976592302 = OpConstant %float 0.000976592302 + %v4int = OpTypeVector %int 4 + %290 = OpConstantComposite %v4int %int_16 %int_0 %int_16 %int_0 + %1837 = OpConstantComposite %v2uint %uint_2 %uint_1 + %v2bool = OpTypeVector %bool 2 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %uint_80 = OpConstant %uint 80 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %int_5 = OpConstant %int 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_6 = OpConstant %uint 6 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_runtimearr_uint = OpTypeRuntimeArray %uint +%_struct_1948 = OpTypeStruct %_runtimearr_uint +%_ptr_Uniform__struct_1948 = OpTypePointer Uniform %_struct_1948 + %3271 = OpVariable %_ptr_Uniform__struct_1948 Uniform +%_ptr_Uniform_uint = OpTypePointer Uniform %uint +%_struct_1036 = OpTypeStruct %uint %uint %uint %uint %uint +%_ptr_PushConstant__struct_1036 = OpTypePointer PushConstant %_struct_1036 + %3305 = OpVariable %_ptr_PushConstant__struct_1036 PushConstant +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_15 = OpConstant %uint 15 + %uint_28 = OpConstant %uint 28 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 + %int_10 = OpConstant %int 10 + %int_26 = OpConstant %int 26 + %int_23 = OpConstant %int 23 +%uint_16777216 = OpConstant %uint 16777216 + %2275 = OpConstantComposite %v2uint %uint_20 %uint_24 + %float_0 = OpConstant %float 0 + %float_0_5 = OpConstant %float 0.5 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %5522 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %1284 = OpConstantComposite %v4float %float_n1 %float_n1 %float_n1 %float_n1 + %770 = OpConstantComposite %v4int %int_16 %int_16 %int_16 %int_16 + %1611 = OpConstantComposite %v4uint %uint_255 %uint_255 %uint_255 %uint_255 + %261 = OpConstantComposite %v3uint %uint_1023 %uint_1023 %uint_1023 + %1126 = OpConstantComposite %v3uint %uint_127 %uint_127 %uint_127 + %2828 = OpConstantComposite %v3uint %uint_7 %uint_7 %uint_7 + %2578 = OpConstantComposite %v3uint %uint_0 %uint_0 %uint_0 + %1018 = OpConstantComposite %v3uint %uint_124 %uint_124 %uint_124 + %393 = OpConstantComposite %v3uint %uint_23 %uint_23 %uint_23 + %141 = OpConstantComposite %v3uint %uint_16 %uint_16 %uint_16 + %73 = OpConstantComposite %v2float %float_n1 %float_n1 + %2151 = OpConstantComposite %v2int %int_16 %int_16 + %uint_11 = OpConstant %uint 11 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 +%int_1065353216 = OpConstant %int 1065353216 + %uint_1280 = OpConstant %uint 1280 +%uint_2621440 = OpConstant %uint 2621440 +%uint_4294967290 = OpConstant %uint 4294967290 + %2360 = OpConstantComposite %v3uint %uint_4294967290 %uint_4294967290 %uint_4294967290 + %uint_81 = OpConstant %uint 81 + %uint_82 = OpConstant %uint 82 + %uint_83 = OpConstant %uint 83 + %float_0_25 = OpConstant %float 0.25 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %19978 = OpShiftRightLogical %uint %15627 %uint_10 + %8574 = OpBitwiseAnd %uint %19978 %uint_3 + %21002 = OpShiftRightLogical %uint %15627 %uint_13 + %8575 = OpBitwiseAnd %uint %21002 %uint_2047 + %21003 = OpShiftRightLogical %uint %15627 %uint_24 + %8576 = OpBitwiseAnd %uint %21003 %uint_15 + %18836 = OpShiftRightLogical %uint %15627 %uint_28 + %9130 = OpBitwiseAnd %uint %18836 %uint_1 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9576 = OpShiftRightLogical %v2uint %8871 %1855 + %23379 = OpBitwiseAnd %v2uint %9576 %1954 + %16207 = OpShiftLeftLogical %v2uint %23379 %1870 + %23019 = OpIMul %v2uint %16207 %1828 + %12819 = OpShiftRightLogical %uint %20824 %uint_5 + %16204 = OpBitwiseAnd %uint %12819 %uint_2047 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %24236 = OpLoad %uint %18732 + %22701 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %20919 = OpLoad %uint %22701 + %19164 = OpBitwiseAnd %uint %24236 %uint_7 + %21999 = OpBitwiseAnd %uint %24236 %uint_8 + %20495 = OpINotEqual %bool %21999 %uint_0 + %8977 = OpShiftRightLogical %uint %24236 %uint_4 + %17416 = OpBitwiseAnd %uint %8977 %uint_7 + %22920 = OpBitcast %int %24236 + %13711 = OpShiftLeftLogical %int %22920 %int_10 + %20636 = OpShiftRightArithmetic %int %13711 %int_26 + %18178 = OpShiftLeftLogical %int %20636 %int_23 + %7462 = OpIAdd %int %18178 %int_1065353216 + %11052 = OpBitcast %float %7462 + %22649 = OpBitwiseAnd %uint %24236 %uint_16777216 + %7513 = OpINotEqual %bool %22649 %uint_0 + %8003 = OpBitwiseAnd %uint %20919 %uint_1023 + %15783 = OpShiftLeftLogical %uint %8003 %uint_5 + %22591 = OpShiftRightLogical %uint %20919 %uint_10 + %19390 = OpBitwiseAnd %uint %22591 %uint_1023 + %25203 = OpShiftLeftLogical %uint %19390 %uint_5 + %10422 = OpCompositeConstruct %v2uint %20919 %20919 + %10385 = OpShiftRightLogical %v2uint %10422 %2275 + %23380 = OpBitwiseAnd %v2uint %10385 %2122 + %16208 = OpShiftLeftLogical %v2uint %23380 %1870 + %23020 = OpIMul %v2uint %16208 %1828 + %12820 = OpShiftRightLogical %uint %20919 %uint_28 + %16205 = OpBitwiseAnd %uint %12820 %uint_7 + %18656 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_4 + %25270 = OpLoad %uint %18656 + %14159 = OpLoad %v3uint %gl_GlobalInvocationID + %12672 = OpVectorShuffle %v2uint %14159 %14159 0 1 + %12025 = OpShiftLeftLogical %v2uint %12672 %1816 + %7640 = OpCompositeExtract %uint %12025 0 + %11658 = OpShiftLeftLogical %uint %16204 %uint_3 + %15379 = OpUGreaterThanEqual %bool %7640 %11658 + OpSelectionMerge %20570 DontFlatten + OpBranchConditional %15379 %21992 %20570 + %21992 = OpLabel + OpBranch %19578 + %20570 = OpLabel + %15264 = OpExtInst %uint %1 UMax %7640 %uint_0 + %9142 = OpCompositeExtract %uint %12025 1 + %16709 = OpExtInst %uint %1 UMax %9142 %uint_0 + %20975 = OpCompositeConstruct %v2uint %15264 %16709 + %21036 = OpIAdd %v2uint %20975 %23019 + %16075 = OpULessThanEqual %bool %16205 %uint_3 + OpSelectionMerge %23776 None + OpBranchConditional %16075 %10990 %15087 + %15087 = OpLabel + %13566 = OpIEqual %bool %16205 %uint_5 + %8438 = OpSelect %uint %13566 %uint_2 %uint_0 + OpBranch %23776 + %10990 = OpLabel + OpBranch %23776 + %23776 = OpLabel + %19300 = OpPhi %uint %16205 %10990 %8438 %15087 + %16830 = OpCompositeConstruct %v2uint %8574 %8574 + %11801 = OpUGreaterThanEqual %v2bool %16830 %1837 + %19381 = OpSelect %v2uint %11801 %1828 %1807 + %10986 = OpShiftLeftLogical %v2uint %21036 %19381 + %24669 = OpCompositeConstruct %v2uint %19300 %19300 + %9093 = OpShiftRightLogical %v2uint %24669 %1816 + %15084 = OpBitwiseAnd %v2uint %9093 %1828 + %10197 = OpIAdd %v2uint %10986 %15084 + %8548 = OpCompositeConstruct %v2uint %9130 %uint_0 + %9802 = OpShiftRightLogical %v2uint %2719 %8548 + %10146 = OpUDiv %v2uint %10197 %9802 + %20390 = OpCompositeExtract %uint %10146 1 + %11046 = OpIMul %uint %20390 %20561 + %24665 = OpCompositeExtract %uint %10146 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %8575 %21536 + %23345 = OpIMul %v2uint %10146 %9802 + %11892 = OpISub %v2uint %10197 %23345 + %8053 = OpIMul %uint %8742 %uint_1280 + %24263 = OpCompositeExtract %uint %11892 1 + %23526 = OpCompositeExtract %uint %9802 0 + %22886 = OpIMul %uint %24263 %23526 + %6886 = OpCompositeExtract %uint %11892 0 + %9696 = OpIAdd %uint %22886 %6886 + %18116 = OpShiftLeftLogical %uint %9696 %9130 + %18201 = OpIAdd %uint %8053 %18116 + %23256 = OpUMod %uint %18201 %uint_2621440 + %13153 = OpUGreaterThanEqual %bool %8574 %uint_2 + %24735 = OpSelect %uint %13153 %uint_1 %uint_0 + %20074 = OpIAdd %uint %9130 %24735 + %6555 = OpShiftLeftLogical %uint %uint_1 %20074 + %23279 = OpINotEqual %bool %9130 %uint_0 + OpSelectionMerge %21263 DontFlatten + OpBranchConditional %23279 %15205 %16569 + %16569 = OpLabel + %19162 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20297 DontFlatten + OpBranchConditional %19162 %9761 %12129 + %12129 = OpLabel + %19407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %23256 + %23875 = OpLoad %uint %19407 + %11687 = OpIAdd %uint %23256 %6555 + %24558 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11687 + %16379 = OpLoad %uint %24558 + %20780 = OpCompositeConstruct %v2uint %23875 %16379 + OpBranch %20297 + %9761 = OpLabel + %21829 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %23256 + %23876 = OpLoad %uint %21829 + %11688 = OpIAdd %uint %23256 %uint_1 + %24559 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11688 + %16380 = OpLoad %uint %24559 + %20781 = OpCompositeConstruct %v2uint %23876 %16380 + OpBranch %20297 + %20297 = OpLabel + %10943 = OpPhi %v2uint %20781 %9761 %20780 %12129 + OpSelectionMerge %16224 None + OpSwitch %8576 %19451 0 %14585 1 %14585 2 %7355 10 %7355 3 %7354 12 %7354 4 %8190 6 %8243 + %8243 = OpLabel + %24406 = OpCompositeExtract %uint %10943 0 + %24679 = OpExtInst %v2float %1 UnpackHalf2x16 %24406 + %10082 = OpCompositeExtract %float %24679 0 + %17478 = OpCompositeExtract %float %24679 1 + %14604 = OpCompositeConstruct %v4float %10082 %17478 %float_0 %float_0 + %17274 = OpCompositeExtract %uint %10943 1 + %18027 = OpExtInst %v2float %1 UnpackHalf2x16 %17274 + %10083 = OpCompositeExtract %float %18027 0 + %20670 = OpCompositeExtract %float %18027 1 + %9033 = OpCompositeConstruct %v4float %10083 %20670 %float_0 %float_0 + OpBranch %16224 + %8190 = OpLabel + %12427 = OpCompositeExtract %uint %10943 0 + %22685 = OpBitcast %int %12427 + %18202 = OpCompositeConstruct %v2int %22685 %22685 + %18349 = OpShiftLeftLogical %v2int %18202 %1959 + %13335 = OpShiftRightArithmetic %v2int %18349 %2151 + %10903 = OpConvertSToF %v2float %13335 + %18247 = OpVectorTimesScalar %v2float %10903 %float_0_000976592302 + %24070 = OpExtInst %v2float %1 FMax %73 %18247 + %24330 = OpCompositeExtract %float %24070 0 + %15572 = OpCompositeExtract %float %24070 1 + %16670 = OpCompositeConstruct %v4float %24330 %15572 %float_0 %float_0 + %19522 = OpCompositeExtract %uint %10943 1 + %16033 = OpBitcast %int %19522 + %18203 = OpCompositeConstruct %v2int %16033 %16033 + %18350 = OpShiftLeftLogical %v2int %18203 %1959 + %13336 = OpShiftRightArithmetic %v2int %18350 %2151 + %10904 = OpConvertSToF %v2float %13336 + %18248 = OpVectorTimesScalar %v2float %10904 %float_0_000976592302 + %24071 = OpExtInst %v2float %1 FMax %73 %18248 + %24331 = OpCompositeExtract %float %24071 0 + %18764 = OpCompositeExtract %float %24071 1 + %9034 = OpCompositeConstruct %v4float %24331 %18764 %float_0 %float_0 + OpBranch %16224 + %7354 = OpLabel + %22205 = OpCompositeExtract %uint %10943 0 + %20234 = OpCompositeConstruct %v3uint %22205 %22205 %22205 + %11021 = OpShiftRightLogical %v3uint %20234 %2996 + %24038 = OpBitwiseAnd %v3uint %11021 %261 + %18588 = OpBitwiseAnd %v3uint %24038 %1126 + %23440 = OpShiftRightLogical %v3uint %24038 %2828 + %16585 = OpIEqual %v3bool %23440 %2578 + %11339 = OpExtInst %v3int %1 FindUMsb %18588 + %10773 = OpBitcast %v3uint %11339 + %6266 = OpISub %v3uint %2828 %10773 + %8720 = OpIAdd %v3uint %10773 %2360 + %10351 = OpSelect %v3uint %16585 %8720 %23440 + %23252 = OpShiftLeftLogical %v3uint %18588 %6266 + %18842 = OpBitwiseAnd %v3uint %23252 %1126 + %10909 = OpSelect %v3uint %16585 %18842 %18588 + %24569 = OpIAdd %v3uint %10351 %1018 + %20351 = OpShiftLeftLogical %v3uint %24569 %393 + %16294 = OpShiftLeftLogical %v3uint %10909 %141 + %22396 = OpBitwiseOr %v3uint %20351 %16294 + %13824 = OpIEqual %v3bool %24038 %2578 + %16962 = OpSelect %v3uint %13824 %2578 %22396 + %10703 = OpBitcast %v3float %16962 + %19364 = OpShiftRightLogical %uint %22205 %uint_30 + %18446 = OpConvertUToF %float %19364 + %15903 = OpFMul %float %18446 %float_0_333333343 + %21442 = OpCompositeExtract %float %10703 0 + %10837 = OpCompositeExtract %float %10703 1 + %7833 = OpCompositeExtract %float %10703 2 + %15834 = OpCompositeConstruct %v4float %21442 %10837 %7833 %15903 + %10229 = OpCompositeExtract %uint %10943 1 + %13582 = OpCompositeConstruct %v3uint %10229 %10229 %10229 + %11022 = OpShiftRightLogical %v3uint %13582 %2996 + %24039 = OpBitwiseAnd %v3uint %11022 %261 + %18589 = OpBitwiseAnd %v3uint %24039 %1126 + %23441 = OpShiftRightLogical %v3uint %24039 %2828 + %16586 = OpIEqual %v3bool %23441 %2578 + %11340 = OpExtInst %v3int %1 FindUMsb %18589 + %10774 = OpBitcast %v3uint %11340 + %6267 = OpISub %v3uint %2828 %10774 + %8721 = OpIAdd %v3uint %10774 %2360 + %10352 = OpSelect %v3uint %16586 %8721 %23441 + %23253 = OpShiftLeftLogical %v3uint %18589 %6267 + %18843 = OpBitwiseAnd %v3uint %23253 %1126 + %10910 = OpSelect %v3uint %16586 %18843 %18589 + %24570 = OpIAdd %v3uint %10352 %1018 + %20352 = OpShiftLeftLogical %v3uint %24570 %393 + %16295 = OpShiftLeftLogical %v3uint %10910 %141 + %22397 = OpBitwiseOr %v3uint %20352 %16295 + %13825 = OpIEqual %v3bool %24039 %2578 + %16963 = OpSelect %v3uint %13825 %2578 %22397 + %10704 = OpBitcast %v3float %16963 + %19365 = OpShiftRightLogical %uint %10229 %uint_30 + %18447 = OpConvertUToF %float %19365 + %15904 = OpFMul %float %18447 %float_0_333333343 + %21443 = OpCompositeExtract %float %10704 0 + %10838 = OpCompositeExtract %float %10704 1 + %11025 = OpCompositeExtract %float %10704 2 + %9035 = OpCompositeConstruct %v4float %21443 %10838 %11025 %15904 + OpBranch %16224 + %7355 = OpLabel + %22206 = OpCompositeExtract %uint %10943 0 + %20235 = OpCompositeConstruct %v4uint %22206 %22206 %22206 %22206 + %9368 = OpShiftRightLogical %v4uint %20235 %845 + %18859 = OpBitwiseAnd %v4uint %9368 %635 + %15543 = OpConvertUToF %v4float %18859 + %16688 = OpFMul %v4float %15543 %2798 + %23762 = OpCompositeExtract %uint %10943 1 + %20813 = OpCompositeConstruct %v4uint %23762 %23762 %23762 %23762 + %9369 = OpShiftRightLogical %v4uint %20813 %845 + %18860 = OpBitwiseAnd %v4uint %9369 %635 + %18735 = OpConvertUToF %v4float %18860 + %9887 = OpFMul %v4float %18735 %2798 + OpBranch %16224 + %14585 = OpLabel + %22207 = OpCompositeExtract %uint %10943 0 + %20236 = OpCompositeConstruct %v4uint %22207 %22207 %22207 %22207 + %9370 = OpShiftRightLogical %v4uint %20236 %653 + %19030 = OpBitwiseAnd %v4uint %9370 %1611 + %13986 = OpConvertUToF %v4float %19030 + %19235 = OpVectorTimesScalar %v4float %13986 %float_0_00392156886 + %8607 = OpCompositeExtract %uint %10943 1 + %24843 = OpCompositeConstruct %v4uint %8607 %8607 %8607 %8607 + %9371 = OpShiftRightLogical %v4uint %24843 %653 + %19031 = OpBitwiseAnd %v4uint %9371 %1611 + %17178 = OpConvertUToF %v4float %19031 + %12434 = OpVectorTimesScalar %v4float %17178 %float_0_00392156886 + OpBranch %16224 + %19451 = OpLabel + %12428 = OpCompositeExtract %uint %10943 0 + %20462 = OpBitcast %float %12428 + %17206 = OpCompositeConstruct %v2float %20462 %float_0 + %11664 = OpVectorShuffle %v4float %17206 %17206 0 1 1 1 + %22193 = OpCompositeExtract %uint %10943 1 + %16232 = OpBitcast %float %22193 + %20398 = OpCompositeConstruct %v2float %16232 %float_0 + %23098 = OpVectorShuffle %v4float %20398 %20398 0 1 1 1 + OpBranch %16224 + %16224 = OpLabel + %11251 = OpPhi %v4float %23098 %19451 %12434 %14585 %9887 %7355 %9035 %7354 %9034 %8190 %9033 %8243 + %13709 = OpPhi %v4float %11664 %19451 %19235 %14585 %16688 %7355 %15834 %7354 %16670 %8190 %14604 %8243 + OpBranch %21263 + %15205 = OpLabel + %21584 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20298 DontFlatten + OpBranchConditional %21584 %9762 %12130 + %12130 = OpLabel + %19408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %23256 + %23877 = OpLoad %uint %19408 + %11689 = OpIAdd %uint %23256 %uint_1 + %6399 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11689 + %23650 = OpLoad %uint %6399 + %11690 = OpIAdd %uint %23256 %6555 + %6400 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11690 + %23651 = OpLoad %uint %6400 + %11691 = OpIAdd %uint %11690 %uint_1 + %24560 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11691 + %16381 = OpLoad %uint %24560 + %20782 = OpCompositeConstruct %v4uint %23877 %23650 %23651 %16381 + OpBranch %20298 + %9762 = OpLabel + %21830 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %23256 + %23878 = OpLoad %uint %21830 + %11692 = OpIAdd %uint %23256 %uint_1 + %6401 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11692 + %23652 = OpLoad %uint %6401 + %11693 = OpIAdd %uint %23256 %uint_2 + %6402 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11693 + %23653 = OpLoad %uint %6402 + %11694 = OpIAdd %uint %23256 %uint_3 + %24561 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11694 + %16382 = OpLoad %uint %24561 + %20783 = OpCompositeConstruct %v4uint %23878 %23652 %23653 %16382 + OpBranch %20298 + %20298 = OpLabel + %10944 = OpPhi %v4uint %20783 %9762 %20782 %12130 + OpSelectionMerge %20259 None + OpSwitch %8576 %20310 5 %8536 7 %8244 + %8244 = OpLabel + %24407 = OpCompositeExtract %uint %10944 0 + %24680 = OpExtInst %v2float %1 UnpackHalf2x16 %24407 + %10101 = OpCompositeExtract %float %24680 0 + %16056 = OpCompositeExtract %float %24680 1 + %17025 = OpCompositeExtract %uint %10944 1 + %15605 = OpExtInst %v2float %1 UnpackHalf2x16 %17025 + %10084 = OpCompositeExtract %float %15605 0 + %17479 = OpCompositeExtract %float %15605 1 + %14605 = OpCompositeConstruct %v4float %10101 %16056 %10084 %17479 + %17275 = OpCompositeExtract %uint %10944 2 + %18028 = OpExtInst %v2float %1 UnpackHalf2x16 %17275 + %10102 = OpCompositeExtract %float %18028 0 + %16057 = OpCompositeExtract %float %18028 1 + %17026 = OpCompositeExtract %uint %10944 3 + %15606 = OpExtInst %v2float %1 UnpackHalf2x16 %17026 + %10085 = OpCompositeExtract %float %15606 0 + %20671 = OpCompositeExtract %float %15606 1 + %9036 = OpCompositeConstruct %v4float %10102 %16057 %10085 %20671 + OpBranch %20259 + %8536 = OpLabel + %9723 = OpVectorShuffle %v2uint %10944 %10944 0 1 + %23356 = OpBitcast %v2int %9723 + %24782 = OpVectorShuffle %v4int %23356 %23356 0 0 1 1 + %18598 = OpShiftLeftLogical %v4int %24782 %290 + %15757 = OpShiftRightArithmetic %v4int %18598 %770 + %10905 = OpConvertSToF %v4float %15757 + %18209 = OpVectorTimesScalar %v4float %10905 %float_0_000976592302 + %25233 = OpExtInst %v4float %1 FMax %1284 %18209 + %14187 = OpVectorShuffle %v2uint %10944 %10944 2 3 + %9407 = OpBitcast %v2int %14187 + %24783 = OpVectorShuffle %v4int %9407 %9407 0 0 1 1 + %18599 = OpShiftLeftLogical %v4int %24783 %290 + %15758 = OpShiftRightArithmetic %v4int %18599 %770 + %10906 = OpConvertSToF %v4float %15758 + %21439 = OpVectorTimesScalar %v4float %10906 %float_0_000976592302 + %17250 = OpExtInst %v4float %1 FMax %1284 %21439 + OpBranch %20259 + %20310 = OpLabel + %9763 = OpVectorShuffle %v2uint %10944 %10944 0 1 + %20825 = OpBitcast %v2float %9763 + %7035 = OpCompositeExtract %float %20825 0 + %13418 = OpCompositeExtract %float %20825 1 + %17016 = OpCompositeConstruct %v4float %7035 %13418 %float_0 %float_0 + %16856 = OpVectorShuffle %v2uint %10944 %10944 2 3 + %14173 = OpBitcast %v2float %16856 + %7036 = OpCompositeExtract %float %14173 0 + %16648 = OpCompositeExtract %float %14173 1 + %9037 = OpCompositeConstruct %v4float %7036 %16648 %float_0 %float_0 + OpBranch %20259 + %20259 = OpLabel + %11252 = OpPhi %v4float %9037 %20310 %17250 %8536 %9036 %8244 + %13710 = OpPhi %v4float %17016 %20310 %25233 %8536 %14605 %8244 + OpBranch %21263 + %21263 = OpLabel + %9826 = OpPhi %v4float %11252 %20259 %11251 %16224 + %14051 = OpPhi %v4float %13710 %20259 %13709 %16224 + %11861 = OpUGreaterThanEqual %bool %16205 %uint_4 + OpSelectionMerge %21267 DontFlatten + OpBranchConditional %11861 %20709 %21267 + %20709 = OpLabel + %25083 = OpFMul %float %11052 %float_0_5 + %24184 = OpIAdd %uint %23256 %uint_80 + OpSelectionMerge %21264 DontFlatten + OpBranchConditional %23279 %15206 %16570 + %16570 = OpLabel + %19163 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20299 DontFlatten + OpBranchConditional %19163 %9764 %12131 + %12131 = OpLabel + %19409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24184 + %23879 = OpLoad %uint %19409 + %11695 = OpIAdd %uint %24184 %6555 + %24562 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11695 + %16383 = OpLoad %uint %24562 + %20784 = OpCompositeConstruct %v2uint %23879 %16383 + OpBranch %20299 + %9764 = OpLabel + %21831 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24184 + %23880 = OpLoad %uint %21831 + %11696 = OpIAdd %uint %23256 %uint_81 + %24563 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11696 + %16384 = OpLoad %uint %24563 + %20785 = OpCompositeConstruct %v2uint %23880 %16384 + OpBranch %20299 + %20299 = OpLabel + %10945 = OpPhi %v2uint %20785 %9764 %20784 %12131 + OpSelectionMerge %16225 None + OpSwitch %8576 %19452 0 %14586 1 %14586 2 %7357 10 %7357 3 %7356 12 %7356 4 %8191 6 %8245 + %8245 = OpLabel + %24408 = OpCompositeExtract %uint %10945 0 + %24681 = OpExtInst %v2float %1 UnpackHalf2x16 %24408 + %10086 = OpCompositeExtract %float %24681 0 + %17480 = OpCompositeExtract %float %24681 1 + %14606 = OpCompositeConstruct %v4float %10086 %17480 %float_0 %float_0 + %17276 = OpCompositeExtract %uint %10945 1 + %18029 = OpExtInst %v2float %1 UnpackHalf2x16 %17276 + %10087 = OpCompositeExtract %float %18029 0 + %20672 = OpCompositeExtract %float %18029 1 + %9038 = OpCompositeConstruct %v4float %10087 %20672 %float_0 %float_0 + OpBranch %16225 + %8191 = OpLabel + %12429 = OpCompositeExtract %uint %10945 0 + %22686 = OpBitcast %int %12429 + %18204 = OpCompositeConstruct %v2int %22686 %22686 + %18351 = OpShiftLeftLogical %v2int %18204 %1959 + %13337 = OpShiftRightArithmetic %v2int %18351 %2151 + %10907 = OpConvertSToF %v2float %13337 + %18249 = OpVectorTimesScalar %v2float %10907 %float_0_000976592302 + %24072 = OpExtInst %v2float %1 FMax %73 %18249 + %24332 = OpCompositeExtract %float %24072 0 + %15573 = OpCompositeExtract %float %24072 1 + %16671 = OpCompositeConstruct %v4float %24332 %15573 %float_0 %float_0 + %19523 = OpCompositeExtract %uint %10945 1 + %16034 = OpBitcast %int %19523 + %18205 = OpCompositeConstruct %v2int %16034 %16034 + %18352 = OpShiftLeftLogical %v2int %18205 %1959 + %13338 = OpShiftRightArithmetic %v2int %18352 %2151 + %10908 = OpConvertSToF %v2float %13338 + %18250 = OpVectorTimesScalar %v2float %10908 %float_0_000976592302 + %24073 = OpExtInst %v2float %1 FMax %73 %18250 + %24333 = OpCompositeExtract %float %24073 0 + %18765 = OpCompositeExtract %float %24073 1 + %9039 = OpCompositeConstruct %v4float %24333 %18765 %float_0 %float_0 + OpBranch %16225 + %7356 = OpLabel + %22208 = OpCompositeExtract %uint %10945 0 + %20237 = OpCompositeConstruct %v3uint %22208 %22208 %22208 + %11023 = OpShiftRightLogical %v3uint %20237 %2996 + %24040 = OpBitwiseAnd %v3uint %11023 %261 + %18590 = OpBitwiseAnd %v3uint %24040 %1126 + %23442 = OpShiftRightLogical %v3uint %24040 %2828 + %16587 = OpIEqual %v3bool %23442 %2578 + %11341 = OpExtInst %v3int %1 FindUMsb %18590 + %10775 = OpBitcast %v3uint %11341 + %6268 = OpISub %v3uint %2828 %10775 + %8722 = OpIAdd %v3uint %10775 %2360 + %10353 = OpSelect %v3uint %16587 %8722 %23442 + %23254 = OpShiftLeftLogical %v3uint %18590 %6268 + %18844 = OpBitwiseAnd %v3uint %23254 %1126 + %10911 = OpSelect %v3uint %16587 %18844 %18590 + %24571 = OpIAdd %v3uint %10353 %1018 + %20353 = OpShiftLeftLogical %v3uint %24571 %393 + %16296 = OpShiftLeftLogical %v3uint %10911 %141 + %22398 = OpBitwiseOr %v3uint %20353 %16296 + %13826 = OpIEqual %v3bool %24040 %2578 + %16964 = OpSelect %v3uint %13826 %2578 %22398 + %10705 = OpBitcast %v3float %16964 + %19366 = OpShiftRightLogical %uint %22208 %uint_30 + %18448 = OpConvertUToF %float %19366 + %15905 = OpFMul %float %18448 %float_0_333333343 + %21444 = OpCompositeExtract %float %10705 0 + %10839 = OpCompositeExtract %float %10705 1 + %7834 = OpCompositeExtract %float %10705 2 + %15835 = OpCompositeConstruct %v4float %21444 %10839 %7834 %15905 + %10230 = OpCompositeExtract %uint %10945 1 + %13583 = OpCompositeConstruct %v3uint %10230 %10230 %10230 + %11024 = OpShiftRightLogical %v3uint %13583 %2996 + %24041 = OpBitwiseAnd %v3uint %11024 %261 + %18591 = OpBitwiseAnd %v3uint %24041 %1126 + %23443 = OpShiftRightLogical %v3uint %24041 %2828 + %16588 = OpIEqual %v3bool %23443 %2578 + %11342 = OpExtInst %v3int %1 FindUMsb %18591 + %10776 = OpBitcast %v3uint %11342 + %6269 = OpISub %v3uint %2828 %10776 + %8723 = OpIAdd %v3uint %10776 %2360 + %10354 = OpSelect %v3uint %16588 %8723 %23443 + %23255 = OpShiftLeftLogical %v3uint %18591 %6269 + %18845 = OpBitwiseAnd %v3uint %23255 %1126 + %10912 = OpSelect %v3uint %16588 %18845 %18591 + %24572 = OpIAdd %v3uint %10354 %1018 + %20354 = OpShiftLeftLogical %v3uint %24572 %393 + %16297 = OpShiftLeftLogical %v3uint %10912 %141 + %22399 = OpBitwiseOr %v3uint %20354 %16297 + %13827 = OpIEqual %v3bool %24041 %2578 + %16965 = OpSelect %v3uint %13827 %2578 %22399 + %10706 = OpBitcast %v3float %16965 + %19367 = OpShiftRightLogical %uint %10230 %uint_30 + %18449 = OpConvertUToF %float %19367 + %15906 = OpFMul %float %18449 %float_0_333333343 + %21445 = OpCompositeExtract %float %10706 0 + %10840 = OpCompositeExtract %float %10706 1 + %11026 = OpCompositeExtract %float %10706 2 + %9040 = OpCompositeConstruct %v4float %21445 %10840 %11026 %15906 + OpBranch %16225 + %7357 = OpLabel + %22209 = OpCompositeExtract %uint %10945 0 + %20238 = OpCompositeConstruct %v4uint %22209 %22209 %22209 %22209 + %9372 = OpShiftRightLogical %v4uint %20238 %845 + %18861 = OpBitwiseAnd %v4uint %9372 %635 + %15544 = OpConvertUToF %v4float %18861 + %16689 = OpFMul %v4float %15544 %2798 + %23763 = OpCompositeExtract %uint %10945 1 + %20814 = OpCompositeConstruct %v4uint %23763 %23763 %23763 %23763 + %9373 = OpShiftRightLogical %v4uint %20814 %845 + %18862 = OpBitwiseAnd %v4uint %9373 %635 + %18736 = OpConvertUToF %v4float %18862 + %9888 = OpFMul %v4float %18736 %2798 + OpBranch %16225 + %14586 = OpLabel + %22210 = OpCompositeExtract %uint %10945 0 + %20239 = OpCompositeConstruct %v4uint %22210 %22210 %22210 %22210 + %9374 = OpShiftRightLogical %v4uint %20239 %653 + %19032 = OpBitwiseAnd %v4uint %9374 %1611 + %13987 = OpConvertUToF %v4float %19032 + %19236 = OpVectorTimesScalar %v4float %13987 %float_0_00392156886 + %8608 = OpCompositeExtract %uint %10945 1 + %24844 = OpCompositeConstruct %v4uint %8608 %8608 %8608 %8608 + %9375 = OpShiftRightLogical %v4uint %24844 %653 + %19033 = OpBitwiseAnd %v4uint %9375 %1611 + %17179 = OpConvertUToF %v4float %19033 + %12435 = OpVectorTimesScalar %v4float %17179 %float_0_00392156886 + OpBranch %16225 + %19452 = OpLabel + %12430 = OpCompositeExtract %uint %10945 0 + %20463 = OpBitcast %float %12430 + %17207 = OpCompositeConstruct %v2float %20463 %float_0 + %11665 = OpVectorShuffle %v4float %17207 %17207 0 1 1 1 + %22194 = OpCompositeExtract %uint %10945 1 + %16233 = OpBitcast %float %22194 + %20399 = OpCompositeConstruct %v2float %16233 %float_0 + %23099 = OpVectorShuffle %v4float %20399 %20399 0 1 1 1 + OpBranch %16225 + %16225 = OpLabel + %11253 = OpPhi %v4float %23099 %19452 %12435 %14586 %9888 %7357 %9040 %7356 %9039 %8191 %9038 %8245 + %13712 = OpPhi %v4float %11665 %19452 %19236 %14586 %16689 %7357 %15835 %7356 %16671 %8191 %14606 %8245 + OpBranch %21264 + %15206 = OpLabel + %21585 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20300 DontFlatten + OpBranchConditional %21585 %9765 %12132 + %12132 = OpLabel + %19410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24184 + %23881 = OpLoad %uint %19410 + %11697 = OpIAdd %uint %23256 %uint_81 + %6403 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11697 + %23654 = OpLoad %uint %6403 + %11698 = OpIAdd %uint %24184 %6555 + %6404 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11698 + %23655 = OpLoad %uint %6404 + %11699 = OpIAdd %uint %11698 %uint_1 + %24564 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11699 + %16385 = OpLoad %uint %24564 + %20786 = OpCompositeConstruct %v4uint %23881 %23654 %23655 %16385 + OpBranch %20300 + %9765 = OpLabel + %21832 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24184 + %23882 = OpLoad %uint %21832 + %11700 = OpIAdd %uint %23256 %uint_81 + %6405 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11700 + %23656 = OpLoad %uint %6405 + %11701 = OpIAdd %uint %23256 %uint_82 + %6406 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11701 + %23657 = OpLoad %uint %6406 + %11702 = OpIAdd %uint %23256 %uint_83 + %24565 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11702 + %16386 = OpLoad %uint %24565 + %20787 = OpCompositeConstruct %v4uint %23882 %23656 %23657 %16386 + OpBranch %20300 + %20300 = OpLabel + %10946 = OpPhi %v4uint %20787 %9765 %20786 %12132 + OpSelectionMerge %20260 None + OpSwitch %8576 %20311 5 %8537 7 %8246 + %8246 = OpLabel + %24409 = OpCompositeExtract %uint %10946 0 + %24682 = OpExtInst %v2float %1 UnpackHalf2x16 %24409 + %10103 = OpCompositeExtract %float %24682 0 + %16058 = OpCompositeExtract %float %24682 1 + %17027 = OpCompositeExtract %uint %10946 1 + %15607 = OpExtInst %v2float %1 UnpackHalf2x16 %17027 + %10088 = OpCompositeExtract %float %15607 0 + %17481 = OpCompositeExtract %float %15607 1 + %14607 = OpCompositeConstruct %v4float %10103 %16058 %10088 %17481 + %17277 = OpCompositeExtract %uint %10946 2 + %18030 = OpExtInst %v2float %1 UnpackHalf2x16 %17277 + %10104 = OpCompositeExtract %float %18030 0 + %16059 = OpCompositeExtract %float %18030 1 + %17028 = OpCompositeExtract %uint %10946 3 + %15608 = OpExtInst %v2float %1 UnpackHalf2x16 %17028 + %10089 = OpCompositeExtract %float %15608 0 + %20673 = OpCompositeExtract %float %15608 1 + %9041 = OpCompositeConstruct %v4float %10104 %16059 %10089 %20673 + OpBranch %20260 + %8537 = OpLabel + %9724 = OpVectorShuffle %v2uint %10946 %10946 0 1 + %23357 = OpBitcast %v2int %9724 + %24784 = OpVectorShuffle %v4int %23357 %23357 0 0 1 1 + %18600 = OpShiftLeftLogical %v4int %24784 %290 + %15759 = OpShiftRightArithmetic %v4int %18600 %770 + %10913 = OpConvertSToF %v4float %15759 + %18210 = OpVectorTimesScalar %v4float %10913 %float_0_000976592302 + %25234 = OpExtInst %v4float %1 FMax %1284 %18210 + %14188 = OpVectorShuffle %v2uint %10946 %10946 2 3 + %9408 = OpBitcast %v2int %14188 + %24785 = OpVectorShuffle %v4int %9408 %9408 0 0 1 1 + %18601 = OpShiftLeftLogical %v4int %24785 %290 + %15760 = OpShiftRightArithmetic %v4int %18601 %770 + %10914 = OpConvertSToF %v4float %15760 + %21440 = OpVectorTimesScalar %v4float %10914 %float_0_000976592302 + %17251 = OpExtInst %v4float %1 FMax %1284 %21440 + OpBranch %20260 + %20311 = OpLabel + %9766 = OpVectorShuffle %v2uint %10946 %10946 0 1 + %20826 = OpBitcast %v2float %9766 + %7037 = OpCompositeExtract %float %20826 0 + %13419 = OpCompositeExtract %float %20826 1 + %17017 = OpCompositeConstruct %v4float %7037 %13419 %float_0 %float_0 + %16857 = OpVectorShuffle %v2uint %10946 %10946 2 3 + %14174 = OpBitcast %v2float %16857 + %7038 = OpCompositeExtract %float %14174 0 + %16649 = OpCompositeExtract %float %14174 1 + %9042 = OpCompositeConstruct %v4float %7038 %16649 %float_0 %float_0 + OpBranch %20260 + %20260 = OpLabel + %11254 = OpPhi %v4float %9042 %20311 %17251 %8537 %9041 %8246 + %13713 = OpPhi %v4float %17017 %20311 %25234 %8537 %14607 %8246 + OpBranch %21264 + %21264 = OpLabel + %8971 = OpPhi %v4float %11254 %20260 %11253 %16225 + %19594 = OpPhi %v4float %13713 %20260 %13712 %16225 + %18096 = OpFAdd %v4float %14051 %19594 + %17754 = OpFAdd %v4float %9826 %8971 + %14461 = OpUGreaterThanEqual %bool %16205 %uint_6 + OpSelectionMerge %24264 DontFlatten + OpBranchConditional %14461 %9905 %24264 + %9905 = OpLabel + %14258 = OpShiftLeftLogical %uint %uint_1 %9130 + %12090 = OpFMul %float %11052 %float_0_25 + %20988 = OpIAdd %uint %23256 %14258 + OpSelectionMerge %21265 DontFlatten + OpBranchConditional %23279 %15207 %16571 + %16571 = OpLabel + %19165 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20301 DontFlatten + OpBranchConditional %19165 %9767 %12133 + %12133 = OpLabel + %19411 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23883 = OpLoad %uint %19411 + %11703 = OpIAdd %uint %20988 %6555 + %24566 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11703 + %16387 = OpLoad %uint %24566 + %20788 = OpCompositeConstruct %v2uint %23883 %16387 + OpBranch %20301 + %9767 = OpLabel + %21833 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23884 = OpLoad %uint %21833 + %11704 = OpIAdd %uint %20988 %uint_1 + %24567 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11704 + %16388 = OpLoad %uint %24567 + %20789 = OpCompositeConstruct %v2uint %23884 %16388 + OpBranch %20301 + %20301 = OpLabel + %10947 = OpPhi %v2uint %20789 %9767 %20788 %12133 + OpSelectionMerge %16226 None + OpSwitch %8576 %19453 0 %14587 1 %14587 2 %7359 10 %7359 3 %7358 12 %7358 4 %8192 6 %8247 + %8247 = OpLabel + %24410 = OpCompositeExtract %uint %10947 0 + %24683 = OpExtInst %v2float %1 UnpackHalf2x16 %24410 + %10090 = OpCompositeExtract %float %24683 0 + %17482 = OpCompositeExtract %float %24683 1 + %14608 = OpCompositeConstruct %v4float %10090 %17482 %float_0 %float_0 + %17278 = OpCompositeExtract %uint %10947 1 + %18031 = OpExtInst %v2float %1 UnpackHalf2x16 %17278 + %10091 = OpCompositeExtract %float %18031 0 + %20674 = OpCompositeExtract %float %18031 1 + %9043 = OpCompositeConstruct %v4float %10091 %20674 %float_0 %float_0 + OpBranch %16226 + %8192 = OpLabel + %12431 = OpCompositeExtract %uint %10947 0 + %22687 = OpBitcast %int %12431 + %18206 = OpCompositeConstruct %v2int %22687 %22687 + %18353 = OpShiftLeftLogical %v2int %18206 %1959 + %13339 = OpShiftRightArithmetic %v2int %18353 %2151 + %10915 = OpConvertSToF %v2float %13339 + %18251 = OpVectorTimesScalar %v2float %10915 %float_0_000976592302 + %24074 = OpExtInst %v2float %1 FMax %73 %18251 + %24334 = OpCompositeExtract %float %24074 0 + %15574 = OpCompositeExtract %float %24074 1 + %16672 = OpCompositeConstruct %v4float %24334 %15574 %float_0 %float_0 + %19524 = OpCompositeExtract %uint %10947 1 + %16035 = OpBitcast %int %19524 + %18207 = OpCompositeConstruct %v2int %16035 %16035 + %18354 = OpShiftLeftLogical %v2int %18207 %1959 + %13340 = OpShiftRightArithmetic %v2int %18354 %2151 + %10916 = OpConvertSToF %v2float %13340 + %18252 = OpVectorTimesScalar %v2float %10916 %float_0_000976592302 + %24075 = OpExtInst %v2float %1 FMax %73 %18252 + %24335 = OpCompositeExtract %float %24075 0 + %18766 = OpCompositeExtract %float %24075 1 + %9044 = OpCompositeConstruct %v4float %24335 %18766 %float_0 %float_0 + OpBranch %16226 + %7358 = OpLabel + %22211 = OpCompositeExtract %uint %10947 0 + %20240 = OpCompositeConstruct %v3uint %22211 %22211 %22211 + %11027 = OpShiftRightLogical %v3uint %20240 %2996 + %24042 = OpBitwiseAnd %v3uint %11027 %261 + %18592 = OpBitwiseAnd %v3uint %24042 %1126 + %23444 = OpShiftRightLogical %v3uint %24042 %2828 + %16589 = OpIEqual %v3bool %23444 %2578 + %11343 = OpExtInst %v3int %1 FindUMsb %18592 + %10777 = OpBitcast %v3uint %11343 + %6270 = OpISub %v3uint %2828 %10777 + %8724 = OpIAdd %v3uint %10777 %2360 + %10355 = OpSelect %v3uint %16589 %8724 %23444 + %23257 = OpShiftLeftLogical %v3uint %18592 %6270 + %18846 = OpBitwiseAnd %v3uint %23257 %1126 + %10917 = OpSelect %v3uint %16589 %18846 %18592 + %24573 = OpIAdd %v3uint %10355 %1018 + %20355 = OpShiftLeftLogical %v3uint %24573 %393 + %16298 = OpShiftLeftLogical %v3uint %10917 %141 + %22400 = OpBitwiseOr %v3uint %20355 %16298 + %13828 = OpIEqual %v3bool %24042 %2578 + %16966 = OpSelect %v3uint %13828 %2578 %22400 + %10707 = OpBitcast %v3float %16966 + %19368 = OpShiftRightLogical %uint %22211 %uint_30 + %18450 = OpConvertUToF %float %19368 + %15907 = OpFMul %float %18450 %float_0_333333343 + %21446 = OpCompositeExtract %float %10707 0 + %10841 = OpCompositeExtract %float %10707 1 + %7835 = OpCompositeExtract %float %10707 2 + %15836 = OpCompositeConstruct %v4float %21446 %10841 %7835 %15907 + %10231 = OpCompositeExtract %uint %10947 1 + %13584 = OpCompositeConstruct %v3uint %10231 %10231 %10231 + %11028 = OpShiftRightLogical %v3uint %13584 %2996 + %24043 = OpBitwiseAnd %v3uint %11028 %261 + %18593 = OpBitwiseAnd %v3uint %24043 %1126 + %23445 = OpShiftRightLogical %v3uint %24043 %2828 + %16590 = OpIEqual %v3bool %23445 %2578 + %11344 = OpExtInst %v3int %1 FindUMsb %18593 + %10778 = OpBitcast %v3uint %11344 + %6271 = OpISub %v3uint %2828 %10778 + %8725 = OpIAdd %v3uint %10778 %2360 + %10356 = OpSelect %v3uint %16590 %8725 %23445 + %23258 = OpShiftLeftLogical %v3uint %18593 %6271 + %18847 = OpBitwiseAnd %v3uint %23258 %1126 + %10918 = OpSelect %v3uint %16590 %18847 %18593 + %24574 = OpIAdd %v3uint %10356 %1018 + %20356 = OpShiftLeftLogical %v3uint %24574 %393 + %16299 = OpShiftLeftLogical %v3uint %10918 %141 + %22401 = OpBitwiseOr %v3uint %20356 %16299 + %13829 = OpIEqual %v3bool %24043 %2578 + %16967 = OpSelect %v3uint %13829 %2578 %22401 + %10708 = OpBitcast %v3float %16967 + %19369 = OpShiftRightLogical %uint %10231 %uint_30 + %18451 = OpConvertUToF %float %19369 + %15908 = OpFMul %float %18451 %float_0_333333343 + %21447 = OpCompositeExtract %float %10708 0 + %10842 = OpCompositeExtract %float %10708 1 + %11029 = OpCompositeExtract %float %10708 2 + %9045 = OpCompositeConstruct %v4float %21447 %10842 %11029 %15908 + OpBranch %16226 + %7359 = OpLabel + %22212 = OpCompositeExtract %uint %10947 0 + %20241 = OpCompositeConstruct %v4uint %22212 %22212 %22212 %22212 + %9376 = OpShiftRightLogical %v4uint %20241 %845 + %18863 = OpBitwiseAnd %v4uint %9376 %635 + %15545 = OpConvertUToF %v4float %18863 + %16690 = OpFMul %v4float %15545 %2798 + %23764 = OpCompositeExtract %uint %10947 1 + %20815 = OpCompositeConstruct %v4uint %23764 %23764 %23764 %23764 + %9377 = OpShiftRightLogical %v4uint %20815 %845 + %18864 = OpBitwiseAnd %v4uint %9377 %635 + %18737 = OpConvertUToF %v4float %18864 + %9889 = OpFMul %v4float %18737 %2798 + OpBranch %16226 + %14587 = OpLabel + %22213 = OpCompositeExtract %uint %10947 0 + %20242 = OpCompositeConstruct %v4uint %22213 %22213 %22213 %22213 + %9378 = OpShiftRightLogical %v4uint %20242 %653 + %19034 = OpBitwiseAnd %v4uint %9378 %1611 + %13988 = OpConvertUToF %v4float %19034 + %19237 = OpVectorTimesScalar %v4float %13988 %float_0_00392156886 + %8609 = OpCompositeExtract %uint %10947 1 + %24845 = OpCompositeConstruct %v4uint %8609 %8609 %8609 %8609 + %9379 = OpShiftRightLogical %v4uint %24845 %653 + %19035 = OpBitwiseAnd %v4uint %9379 %1611 + %17180 = OpConvertUToF %v4float %19035 + %12436 = OpVectorTimesScalar %v4float %17180 %float_0_00392156886 + OpBranch %16226 + %19453 = OpLabel + %12432 = OpCompositeExtract %uint %10947 0 + %20464 = OpBitcast %float %12432 + %17208 = OpCompositeConstruct %v2float %20464 %float_0 + %11666 = OpVectorShuffle %v4float %17208 %17208 0 1 1 1 + %22195 = OpCompositeExtract %uint %10947 1 + %16234 = OpBitcast %float %22195 + %20400 = OpCompositeConstruct %v2float %16234 %float_0 + %23100 = OpVectorShuffle %v4float %20400 %20400 0 1 1 1 + OpBranch %16226 + %16226 = OpLabel + %11255 = OpPhi %v4float %23100 %19453 %12436 %14587 %9889 %7359 %9045 %7358 %9044 %8192 %9043 %8247 + %13714 = OpPhi %v4float %11666 %19453 %19237 %14587 %16690 %7359 %15836 %7358 %16672 %8192 %14608 %8247 + OpBranch %21265 + %15207 = OpLabel + %21586 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20302 DontFlatten + OpBranchConditional %21586 %9768 %12134 + %12134 = OpLabel + %19412 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23885 = OpLoad %uint %19412 + %11705 = OpIAdd %uint %20988 %uint_1 + %6407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11705 + %23658 = OpLoad %uint %6407 + %11706 = OpIAdd %uint %20988 %6555 + %6408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11706 + %23659 = OpLoad %uint %6408 + %11707 = OpIAdd %uint %11706 %uint_1 + %24568 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11707 + %16389 = OpLoad %uint %24568 + %20790 = OpCompositeConstruct %v4uint %23885 %23658 %23659 %16389 + OpBranch %20302 + %9768 = OpLabel + %21834 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23886 = OpLoad %uint %21834 + %11708 = OpIAdd %uint %20988 %uint_1 + %6409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11708 + %23660 = OpLoad %uint %6409 + %11709 = OpIAdd %uint %20988 %uint_2 + %6410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11709 + %23661 = OpLoad %uint %6410 + %11710 = OpIAdd %uint %20988 %uint_3 + %24575 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11710 + %16390 = OpLoad %uint %24575 + %20791 = OpCompositeConstruct %v4uint %23886 %23660 %23661 %16390 + OpBranch %20302 + %20302 = OpLabel + %10948 = OpPhi %v4uint %20791 %9768 %20790 %12134 + OpSelectionMerge %20261 None + OpSwitch %8576 %20312 5 %8538 7 %8248 + %8248 = OpLabel + %24411 = OpCompositeExtract %uint %10948 0 + %24684 = OpExtInst %v2float %1 UnpackHalf2x16 %24411 + %10105 = OpCompositeExtract %float %24684 0 + %16060 = OpCompositeExtract %float %24684 1 + %17029 = OpCompositeExtract %uint %10948 1 + %15609 = OpExtInst %v2float %1 UnpackHalf2x16 %17029 + %10092 = OpCompositeExtract %float %15609 0 + %17483 = OpCompositeExtract %float %15609 1 + %14609 = OpCompositeConstruct %v4float %10105 %16060 %10092 %17483 + %17279 = OpCompositeExtract %uint %10948 2 + %18032 = OpExtInst %v2float %1 UnpackHalf2x16 %17279 + %10106 = OpCompositeExtract %float %18032 0 + %16061 = OpCompositeExtract %float %18032 1 + %17030 = OpCompositeExtract %uint %10948 3 + %15610 = OpExtInst %v2float %1 UnpackHalf2x16 %17030 + %10093 = OpCompositeExtract %float %15610 0 + %20675 = OpCompositeExtract %float %15610 1 + %9046 = OpCompositeConstruct %v4float %10106 %16061 %10093 %20675 + OpBranch %20261 + %8538 = OpLabel + %9725 = OpVectorShuffle %v2uint %10948 %10948 0 1 + %23358 = OpBitcast %v2int %9725 + %24786 = OpVectorShuffle %v4int %23358 %23358 0 0 1 1 + %18602 = OpShiftLeftLogical %v4int %24786 %290 + %15761 = OpShiftRightArithmetic %v4int %18602 %770 + %10919 = OpConvertSToF %v4float %15761 + %18211 = OpVectorTimesScalar %v4float %10919 %float_0_000976592302 + %25235 = OpExtInst %v4float %1 FMax %1284 %18211 + %14189 = OpVectorShuffle %v2uint %10948 %10948 2 3 + %9409 = OpBitcast %v2int %14189 + %24787 = OpVectorShuffle %v4int %9409 %9409 0 0 1 1 + %18603 = OpShiftLeftLogical %v4int %24787 %290 + %15762 = OpShiftRightArithmetic %v4int %18603 %770 + %10920 = OpConvertSToF %v4float %15762 + %21441 = OpVectorTimesScalar %v4float %10920 %float_0_000976592302 + %17252 = OpExtInst %v4float %1 FMax %1284 %21441 + OpBranch %20261 + %20312 = OpLabel + %9769 = OpVectorShuffle %v2uint %10948 %10948 0 1 + %20827 = OpBitcast %v2float %9769 + %7039 = OpCompositeExtract %float %20827 0 + %13420 = OpCompositeExtract %float %20827 1 + %17018 = OpCompositeConstruct %v4float %7039 %13420 %float_0 %float_0 + %16858 = OpVectorShuffle %v2uint %10948 %10948 2 3 + %14175 = OpBitcast %v2float %16858 + %7040 = OpCompositeExtract %float %14175 0 + %16650 = OpCompositeExtract %float %14175 1 + %9047 = OpCompositeConstruct %v4float %7040 %16650 %float_0 %float_0 + OpBranch %20261 + %20261 = OpLabel + %11256 = OpPhi %v4float %9047 %20312 %17252 %8538 %9046 %8248 + %13715 = OpPhi %v4float %17018 %20312 %25235 %8538 %14609 %8248 + OpBranch %21265 + %21265 = OpLabel + %8972 = OpPhi %v4float %11256 %20261 %11255 %16226 + %19595 = OpPhi %v4float %13715 %20261 %13714 %16226 + %17222 = OpFAdd %v4float %18096 %19595 + %6641 = OpFAdd %v4float %17754 %8972 + %16376 = OpIAdd %uint %24184 %14258 + OpSelectionMerge %21266 DontFlatten + OpBranchConditional %23279 %15208 %16572 + %16572 = OpLabel + %19166 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20303 DontFlatten + OpBranchConditional %19166 %9770 %12135 + %12135 = OpLabel + %19413 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23887 = OpLoad %uint %19413 + %11711 = OpIAdd %uint %16376 %6555 + %24576 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11711 + %16391 = OpLoad %uint %24576 + %20792 = OpCompositeConstruct %v2uint %23887 %16391 + OpBranch %20303 + %9770 = OpLabel + %21835 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23888 = OpLoad %uint %21835 + %11712 = OpIAdd %uint %16376 %uint_1 + %24577 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11712 + %16392 = OpLoad %uint %24577 + %20793 = OpCompositeConstruct %v2uint %23888 %16392 + OpBranch %20303 + %20303 = OpLabel + %10949 = OpPhi %v2uint %20793 %9770 %20792 %12135 + OpSelectionMerge %16227 None + OpSwitch %8576 %19454 0 %14588 1 %14588 2 %7361 10 %7361 3 %7360 12 %7360 4 %8193 6 %8249 + %8249 = OpLabel + %24412 = OpCompositeExtract %uint %10949 0 + %24685 = OpExtInst %v2float %1 UnpackHalf2x16 %24412 + %10094 = OpCompositeExtract %float %24685 0 + %17484 = OpCompositeExtract %float %24685 1 + %14610 = OpCompositeConstruct %v4float %10094 %17484 %float_0 %float_0 + %17280 = OpCompositeExtract %uint %10949 1 + %18033 = OpExtInst %v2float %1 UnpackHalf2x16 %17280 + %10095 = OpCompositeExtract %float %18033 0 + %20676 = OpCompositeExtract %float %18033 1 + %9048 = OpCompositeConstruct %v4float %10095 %20676 %float_0 %float_0 + OpBranch %16227 + %8193 = OpLabel + %12433 = OpCompositeExtract %uint %10949 0 + %22688 = OpBitcast %int %12433 + %18208 = OpCompositeConstruct %v2int %22688 %22688 + %18355 = OpShiftLeftLogical %v2int %18208 %1959 + %13341 = OpShiftRightArithmetic %v2int %18355 %2151 + %10921 = OpConvertSToF %v2float %13341 + %18253 = OpVectorTimesScalar %v2float %10921 %float_0_000976592302 + %24076 = OpExtInst %v2float %1 FMax %73 %18253 + %24336 = OpCompositeExtract %float %24076 0 + %15575 = OpCompositeExtract %float %24076 1 + %16673 = OpCompositeConstruct %v4float %24336 %15575 %float_0 %float_0 + %19525 = OpCompositeExtract %uint %10949 1 + %16036 = OpBitcast %int %19525 + %18212 = OpCompositeConstruct %v2int %16036 %16036 + %18356 = OpShiftLeftLogical %v2int %18212 %1959 + %13342 = OpShiftRightArithmetic %v2int %18356 %2151 + %10922 = OpConvertSToF %v2float %13342 + %18254 = OpVectorTimesScalar %v2float %10922 %float_0_000976592302 + %24077 = OpExtInst %v2float %1 FMax %73 %18254 + %24337 = OpCompositeExtract %float %24077 0 + %18767 = OpCompositeExtract %float %24077 1 + %9049 = OpCompositeConstruct %v4float %24337 %18767 %float_0 %float_0 + OpBranch %16227 + %7360 = OpLabel + %22214 = OpCompositeExtract %uint %10949 0 + %20243 = OpCompositeConstruct %v3uint %22214 %22214 %22214 + %11030 = OpShiftRightLogical %v3uint %20243 %2996 + %24044 = OpBitwiseAnd %v3uint %11030 %261 + %18594 = OpBitwiseAnd %v3uint %24044 %1126 + %23446 = OpShiftRightLogical %v3uint %24044 %2828 + %16591 = OpIEqual %v3bool %23446 %2578 + %11345 = OpExtInst %v3int %1 FindUMsb %18594 + %10779 = OpBitcast %v3uint %11345 + %6272 = OpISub %v3uint %2828 %10779 + %8726 = OpIAdd %v3uint %10779 %2360 + %10357 = OpSelect %v3uint %16591 %8726 %23446 + %23259 = OpShiftLeftLogical %v3uint %18594 %6272 + %18848 = OpBitwiseAnd %v3uint %23259 %1126 + %10923 = OpSelect %v3uint %16591 %18848 %18594 + %24578 = OpIAdd %v3uint %10357 %1018 + %20357 = OpShiftLeftLogical %v3uint %24578 %393 + %16300 = OpShiftLeftLogical %v3uint %10923 %141 + %22402 = OpBitwiseOr %v3uint %20357 %16300 + %13830 = OpIEqual %v3bool %24044 %2578 + %16968 = OpSelect %v3uint %13830 %2578 %22402 + %10709 = OpBitcast %v3float %16968 + %19370 = OpShiftRightLogical %uint %22214 %uint_30 + %18452 = OpConvertUToF %float %19370 + %15909 = OpFMul %float %18452 %float_0_333333343 + %21448 = OpCompositeExtract %float %10709 0 + %10843 = OpCompositeExtract %float %10709 1 + %7836 = OpCompositeExtract %float %10709 2 + %15837 = OpCompositeConstruct %v4float %21448 %10843 %7836 %15909 + %10232 = OpCompositeExtract %uint %10949 1 + %13585 = OpCompositeConstruct %v3uint %10232 %10232 %10232 + %11031 = OpShiftRightLogical %v3uint %13585 %2996 + %24045 = OpBitwiseAnd %v3uint %11031 %261 + %18595 = OpBitwiseAnd %v3uint %24045 %1126 + %23447 = OpShiftRightLogical %v3uint %24045 %2828 + %16592 = OpIEqual %v3bool %23447 %2578 + %11346 = OpExtInst %v3int %1 FindUMsb %18595 + %10780 = OpBitcast %v3uint %11346 + %6273 = OpISub %v3uint %2828 %10780 + %8727 = OpIAdd %v3uint %10780 %2360 + %10358 = OpSelect %v3uint %16592 %8727 %23447 + %23260 = OpShiftLeftLogical %v3uint %18595 %6273 + %18849 = OpBitwiseAnd %v3uint %23260 %1126 + %10924 = OpSelect %v3uint %16592 %18849 %18595 + %24579 = OpIAdd %v3uint %10358 %1018 + %20358 = OpShiftLeftLogical %v3uint %24579 %393 + %16301 = OpShiftLeftLogical %v3uint %10924 %141 + %22403 = OpBitwiseOr %v3uint %20358 %16301 + %13831 = OpIEqual %v3bool %24045 %2578 + %16969 = OpSelect %v3uint %13831 %2578 %22403 + %10710 = OpBitcast %v3float %16969 + %19371 = OpShiftRightLogical %uint %10232 %uint_30 + %18453 = OpConvertUToF %float %19371 + %15910 = OpFMul %float %18453 %float_0_333333343 + %21449 = OpCompositeExtract %float %10710 0 + %10844 = OpCompositeExtract %float %10710 1 + %11032 = OpCompositeExtract %float %10710 2 + %9050 = OpCompositeConstruct %v4float %21449 %10844 %11032 %15910 + OpBranch %16227 + %7361 = OpLabel + %22215 = OpCompositeExtract %uint %10949 0 + %20244 = OpCompositeConstruct %v4uint %22215 %22215 %22215 %22215 + %9380 = OpShiftRightLogical %v4uint %20244 %845 + %18865 = OpBitwiseAnd %v4uint %9380 %635 + %15546 = OpConvertUToF %v4float %18865 + %16691 = OpFMul %v4float %15546 %2798 + %23765 = OpCompositeExtract %uint %10949 1 + %20816 = OpCompositeConstruct %v4uint %23765 %23765 %23765 %23765 + %9381 = OpShiftRightLogical %v4uint %20816 %845 + %18866 = OpBitwiseAnd %v4uint %9381 %635 + %18738 = OpConvertUToF %v4float %18866 + %9890 = OpFMul %v4float %18738 %2798 + OpBranch %16227 + %14588 = OpLabel + %22216 = OpCompositeExtract %uint %10949 0 + %20245 = OpCompositeConstruct %v4uint %22216 %22216 %22216 %22216 + %9382 = OpShiftRightLogical %v4uint %20245 %653 + %19036 = OpBitwiseAnd %v4uint %9382 %1611 + %13989 = OpConvertUToF %v4float %19036 + %19238 = OpVectorTimesScalar %v4float %13989 %float_0_00392156886 + %8610 = OpCompositeExtract %uint %10949 1 + %24846 = OpCompositeConstruct %v4uint %8610 %8610 %8610 %8610 + %9383 = OpShiftRightLogical %v4uint %24846 %653 + %19037 = OpBitwiseAnd %v4uint %9383 %1611 + %17181 = OpConvertUToF %v4float %19037 + %12437 = OpVectorTimesScalar %v4float %17181 %float_0_00392156886 + OpBranch %16227 + %19454 = OpLabel + %12438 = OpCompositeExtract %uint %10949 0 + %20465 = OpBitcast %float %12438 + %17209 = OpCompositeConstruct %v2float %20465 %float_0 + %11667 = OpVectorShuffle %v4float %17209 %17209 0 1 1 1 + %22196 = OpCompositeExtract %uint %10949 1 + %16235 = OpBitcast %float %22196 + %20401 = OpCompositeConstruct %v2float %16235 %float_0 + %23101 = OpVectorShuffle %v4float %20401 %20401 0 1 1 1 + OpBranch %16227 + %16227 = OpLabel + %11257 = OpPhi %v4float %23101 %19454 %12437 %14588 %9890 %7361 %9050 %7360 %9049 %8193 %9048 %8249 + %13716 = OpPhi %v4float %11667 %19454 %19238 %14588 %16691 %7361 %15837 %7360 %16673 %8193 %14610 %8249 + OpBranch %21266 + %15208 = OpLabel + %21587 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20304 DontFlatten + OpBranchConditional %21587 %9771 %12136 + %12136 = OpLabel + %19414 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23889 = OpLoad %uint %19414 + %11713 = OpIAdd %uint %16376 %uint_1 + %6411 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11713 + %23662 = OpLoad %uint %6411 + %11714 = OpIAdd %uint %16376 %6555 + %6412 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11714 + %23663 = OpLoad %uint %6412 + %11715 = OpIAdd %uint %11714 %uint_1 + %24580 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11715 + %16393 = OpLoad %uint %24580 + %20794 = OpCompositeConstruct %v4uint %23889 %23662 %23663 %16393 + OpBranch %20304 + %9771 = OpLabel + %21836 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23890 = OpLoad %uint %21836 + %11716 = OpIAdd %uint %16376 %uint_1 + %6413 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11716 + %23664 = OpLoad %uint %6413 + %11717 = OpIAdd %uint %16376 %uint_2 + %6414 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11717 + %23665 = OpLoad %uint %6414 + %11718 = OpIAdd %uint %16376 %uint_3 + %24581 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11718 + %16394 = OpLoad %uint %24581 + %20795 = OpCompositeConstruct %v4uint %23890 %23664 %23665 %16394 + OpBranch %20304 + %20304 = OpLabel + %10950 = OpPhi %v4uint %20795 %9771 %20794 %12136 + OpSelectionMerge %20262 None + OpSwitch %8576 %20313 5 %8539 7 %8250 + %8250 = OpLabel + %24413 = OpCompositeExtract %uint %10950 0 + %24686 = OpExtInst %v2float %1 UnpackHalf2x16 %24413 + %10107 = OpCompositeExtract %float %24686 0 + %16062 = OpCompositeExtract %float %24686 1 + %17031 = OpCompositeExtract %uint %10950 1 + %15611 = OpExtInst %v2float %1 UnpackHalf2x16 %17031 + %10096 = OpCompositeExtract %float %15611 0 + %17485 = OpCompositeExtract %float %15611 1 + %14611 = OpCompositeConstruct %v4float %10107 %16062 %10096 %17485 + %17281 = OpCompositeExtract %uint %10950 2 + %18034 = OpExtInst %v2float %1 UnpackHalf2x16 %17281 + %10108 = OpCompositeExtract %float %18034 0 + %16063 = OpCompositeExtract %float %18034 1 + %17032 = OpCompositeExtract %uint %10950 3 + %15612 = OpExtInst %v2float %1 UnpackHalf2x16 %17032 + %10097 = OpCompositeExtract %float %15612 0 + %20677 = OpCompositeExtract %float %15612 1 + %9051 = OpCompositeConstruct %v4float %10108 %16063 %10097 %20677 + OpBranch %20262 + %8539 = OpLabel + %9726 = OpVectorShuffle %v2uint %10950 %10950 0 1 + %23359 = OpBitcast %v2int %9726 + %24788 = OpVectorShuffle %v4int %23359 %23359 0 0 1 1 + %18604 = OpShiftLeftLogical %v4int %24788 %290 + %15763 = OpShiftRightArithmetic %v4int %18604 %770 + %10925 = OpConvertSToF %v4float %15763 + %18213 = OpVectorTimesScalar %v4float %10925 %float_0_000976592302 + %25236 = OpExtInst %v4float %1 FMax %1284 %18213 + %14190 = OpVectorShuffle %v2uint %10950 %10950 2 3 + %9410 = OpBitcast %v2int %14190 + %24789 = OpVectorShuffle %v4int %9410 %9410 0 0 1 1 + %18605 = OpShiftLeftLogical %v4int %24789 %290 + %15764 = OpShiftRightArithmetic %v4int %18605 %770 + %10926 = OpConvertSToF %v4float %15764 + %21450 = OpVectorTimesScalar %v4float %10926 %float_0_000976592302 + %17253 = OpExtInst %v4float %1 FMax %1284 %21450 + OpBranch %20262 + %20313 = OpLabel + %9772 = OpVectorShuffle %v2uint %10950 %10950 0 1 + %20828 = OpBitcast %v2float %9772 + %7041 = OpCompositeExtract %float %20828 0 + %13421 = OpCompositeExtract %float %20828 1 + %17019 = OpCompositeConstruct %v4float %7041 %13421 %float_0 %float_0 + %16859 = OpVectorShuffle %v2uint %10950 %10950 2 3 + %14176 = OpBitcast %v2float %16859 + %7042 = OpCompositeExtract %float %14176 0 + %16651 = OpCompositeExtract %float %14176 1 + %9052 = OpCompositeConstruct %v4float %7042 %16651 %float_0 %float_0 + OpBranch %20262 + %20262 = OpLabel + %11258 = OpPhi %v4float %9052 %20313 %17253 %8539 %9051 %8250 + %13717 = OpPhi %v4float %17019 %20313 %25236 %8539 %14611 %8250 + OpBranch %21266 + %21266 = OpLabel + %8973 = OpPhi %v4float %11258 %20262 %11257 %16227 + %19596 = OpPhi %v4float %13717 %20262 %13716 %16227 + %19521 = OpFAdd %v4float %17222 %19596 + %23869 = OpFAdd %v4float %6641 %8973 + OpBranch %24264 + %24264 = OpLabel + %11175 = OpPhi %v4float %17754 %21264 %23869 %21266 + %14420 = OpPhi %v4float %18096 %21264 %19521 %21266 + %14518 = OpPhi %float %25083 %21264 %12090 %21266 + OpBranch %21267 + %21267 = OpLabel + %11176 = OpPhi %v4float %9826 %21263 %11175 %24264 + %12387 = OpPhi %v4float %14051 %21263 %14420 %24264 + %11944 = OpPhi %float %11052 %21263 %14518 %24264 + %25151 = OpVectorTimesScalar %v4float %12387 %11944 + %9562 = OpVectorTimesScalar %v4float %11176 %11944 + OpSelectionMerge %16228 DontFlatten + OpBranchConditional %7513 %10049 %16228 + %10049 = OpLabel + %18316 = OpVectorShuffle %v4float %25151 %25151 2 1 0 3 + %20341 = OpVectorShuffle %v4float %9562 %9562 2 1 0 3 + OpBranch %16228 + %16228 = OpLabel + %8952 = OpPhi %v4float %9562 %21267 %20341 %10049 + %22009 = OpPhi %v4float %25151 %21267 %18316 %10049 + %7319 = OpIAdd %v2uint %12025 %23020 + OpSelectionMerge %21237 DontFlatten + OpBranchConditional %20495 %10574 %21373 + %21373 = OpLabel + %10608 = OpBitcast %v2int %7319 + %17090 = OpCompositeExtract %int %10608 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %10608 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %15783 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_11 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17303 = OpIAdd %int %10934 %17741 + %6375 = OpShiftLeftLogical %int %17303 %uint_4 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15435 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18357 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21588 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21588 %int_6 + %15436 = OpIAdd %int %16708 %21580 + %11782 = OpBitwiseAnd %int %16727 %int_63 + %14671 = OpIAdd %int %15436 %11782 + %22127 = OpBitcast %uint %14671 + OpBranch %21237 + %10574 = OpLabel + %19866 = OpCompositeExtract %uint %7319 0 + %11267 = OpCompositeExtract %uint %7319 1 + %8414 = OpCompositeConstruct %v3uint %19866 %11267 %17416 + %20125 = OpBitcast %v3int %8414 + %10438 = OpCompositeExtract %int %20125 1 + %9470 = OpShiftRightArithmetic %int %10438 %int_4 + %10056 = OpCompositeExtract %int %20125 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %25203 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %15783 %uint_5 + %12439 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12439 + %25154 = OpCompositeExtract %int %20125 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_10 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12601 = OpBitwiseAnd %int %10438 %int_6 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7048 = OpShiftLeftLogical %int %17227 %uint_10 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8728 = OpShiftRightArithmetic %int %10438 %int_3 + %13731 = OpIAdd %int %8728 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19168 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19168 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23346 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23346 %23274 + %18358 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18358 %uint_10 + %16729 = OpIAdd %int %10332 %21582 + %19169 = OpBitwiseAnd %int %10438 %int_1 + %21583 = OpShiftLeftLogical %int %19169 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23347 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10927 = OpIAdd %int %23347 %23217 + %23348 = OpShiftLeftLogical %int %10927 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10928 = OpIAdd %int %23348 %23218 + %23349 = OpShiftLeftLogical %int %10928 %int_3 + %21849 = OpBitwiseAnd %int %16730 %int_63 + %24314 = OpIAdd %int %23349 %21849 + %22128 = OpBitcast %uint %24314 + OpBranch %21237 + %21237 = OpLabel + %11376 = OpPhi %uint %22128 %10574 %22127 %21373 + %19742 = OpIAdd %uint %11376 %25270 + %7562 = OpShiftRightLogical %uint %19742 %uint_4 + %9007 = OpBitcast %v4uint %22009 + %8174 = OpIEqual %bool %19164 %uint_5 + OpSelectionMerge %14780 None + OpBranchConditional %8174 %13279 %14780 + %13279 = OpLabel + %7958 = OpVectorShuffle %v4uint %9007 %9007 3 2 1 0 + OpBranch %14780 + %14780 = OpLabel + %22898 = OpPhi %v4uint %9007 %21237 %7958 %13279 + %8068 = OpSelect %uint %8174 %uint_2 %19164 + %20758 = OpIEqual %bool %8068 %uint_4 + OpSelectionMerge %14781 None + OpBranchConditional %20758 %13280 %14781 + %13280 = OpLabel + %7959 = OpVectorShuffle %v4uint %22898 %22898 1 0 3 2 + OpBranch %14781 + %14781 = OpLabel + %22899 = OpPhi %v4uint %22898 %14780 %7959 %13280 + %6605 = OpSelect %uint %20758 %uint_2 %8068 + %13412 = OpIEqual %bool %6605 %uint_1 + %18370 = OpIEqual %bool %6605 %uint_2 + %22150 = OpLogicalOr %bool %13412 %18370 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %22899 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %22899 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16377 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22650 = OpPhi %v4uint %22899 %14781 %16377 %10583 + %19638 = OpIEqual %bool %6605 %uint_3 + %15139 = OpLogicalOr %bool %18370 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22650 %749 + %15335 = OpShiftRightLogical %v4uint %22650 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22650 %13411 %10728 %11064 + %24825 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %7562 + OpStore %24825 %19767 + %23836 = OpIAdd %uint %7562 %uint_2 + %18261 = OpBitcast %v4uint %8952 + OpSelectionMerge %16262 None + OpBranchConditional %8174 %13281 %16262 + %13281 = OpLabel + %7960 = OpVectorShuffle %v4uint %18261 %18261 3 2 1 0 + OpBranch %16262 + %16262 = OpLabel + %10929 = OpPhi %v4uint %18261 %11416 %7960 %13281 + OpSelectionMerge %16263 None + OpBranchConditional %20758 %13282 %16263 + %13282 = OpLabel + %7961 = OpVectorShuffle %v4uint %10929 %10929 1 0 3 2 + OpBranch %16263 + %16263 = OpLabel + %10930 = OpPhi %v4uint %10929 %16262 %7961 %13282 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %10930 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %10930 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16378 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10931 = OpPhi %v4uint %10930 %16263 %16378 %10584 + OpSelectionMerge %11417 None + OpBranchConditional %15139 %11065 %11417 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10931 %749 + %15336 = OpShiftRightLogical %v4uint %10931 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %10931 %14874 %10729 %11065 + %8054 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %23836 + OpStore %8054 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_full_128bpp_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000062B7, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00040047, 0x000007D0, 0x00000006, 0x00000004, + 0x00030047, 0x0000079C, 0x00000003, 0x00040048, 0x0000079C, 0x00000000, 0x00000018, 0x00050048, + 0x0000079C, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000CC7, 0x00000018, 0x00040047, + 0x00000CC7, 0x00000021, 0x00000000, 0x00040047, 0x00000CC7, 0x00000022, 0x00000000, 0x00030047, + 0x0000040C, 0x00000002, 0x00050048, 0x0000040C, 0x00000000, 0x00000023, 0x00000000, 0x00050048, + 0x0000040C, 0x00000001, 0x00000023, 0x00000004, 0x00050048, 0x0000040C, 0x00000002, 0x00000023, + 0x00000008, 0x00050048, 0x0000040C, 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x0000040C, + 0x00000004, 0x00000023, 0x00000010, 0x00040047, 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, + 0x000007DC, 0x00000006, 0x00000010, 0x00030047, 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, + 0x00000000, 0x00000019, 0x00050048, 0x000007B4, 0x00000000, 0x00000023, 0x00000000, 0x00030047, + 0x00001592, 0x00000019, 0x00040047, 0x00001592, 0x00000021, 0x00000000, 0x00040047, 0x00001592, + 0x00000022, 0x00000001, 0x00040047, 0x00000AC7, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, + 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, + 0x00000012, 0x0000000C, 0x00000002, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, + 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x00040017, + 0x00000017, 0x0000000B, 0x00000004, 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x00000013, + 0x0000000D, 0x00000002, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x00020014, 0x00000009, + 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, + 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A52, 0x00000018, + 0x0007002C, 0x00000017, 0x0000028D, 0x00000A0A, 0x00000A22, 0x00000A3A, 0x00000A52, 0x0004002B, + 0x0000000B, 0x00000144, 0x000000FF, 0x0004002B, 0x0000000D, 0x0000017A, 0x3B808081, 0x0004002B, + 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000A46, 0x00000014, 0x0004002B, + 0x0000000B, 0x00000A64, 0x0000001E, 0x0007002C, 0x00000017, 0x0000034D, 0x00000A0A, 0x00000A28, + 0x00000A46, 0x00000A64, 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, 0x0007002C, 0x00000017, + 0x0000027B, 0x00000A44, 0x00000A44, 0x00000A44, 0x00000A13, 0x0004002B, 0x0000000D, 0x000006FE, + 0x3A802008, 0x0004002B, 0x0000000D, 0x00000149, 0x3EAAAAAB, 0x0007002C, 0x0000001D, 0x00000AEE, + 0x000006FE, 0x000006FE, 0x000006FE, 0x00000149, 0x0006002C, 0x00000014, 0x00000BB4, 0x00000A0A, + 0x00000A28, 0x00000A46, 0x0004002B, 0x0000000B, 0x00000B87, 0x0000007F, 0x0004002B, 0x0000000B, + 0x00000A1F, 0x00000007, 0x00040017, 0x00000010, 0x00000009, 0x00000003, 0x0004002B, 0x0000000B, + 0x00000B7E, 0x0000007C, 0x0004002B, 0x0000000B, 0x00000A4F, 0x00000017, 0x00040017, 0x00000018, + 0x0000000D, 0x00000003, 0x0004002B, 0x0000000D, 0x00000341, 0xBF800000, 0x0004002B, 0x0000000C, + 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x0005002C, 0x00000012, + 0x000007A7, 0x00000A3B, 0x00000A0B, 0x0004002B, 0x0000000D, 0x000007FE, 0x3A800100, 0x00040017, + 0x0000001A, 0x0000000C, 0x00000004, 0x0007002C, 0x0000001A, 0x00000122, 0x00000A3B, 0x00000A0B, + 0x00000A3B, 0x00000A0B, 0x0005002C, 0x00000011, 0x0000072D, 0x00000A10, 0x00000A0D, 0x00040017, + 0x0000000F, 0x00000009, 0x00000002, 0x0005002C, 0x00000011, 0x0000070F, 0x00000A0A, 0x00000A0A, + 0x0005002C, 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, 0x0005002C, 0x00000011, 0x00000718, + 0x00000A0D, 0x00000A0A, 0x0004002B, 0x0000000B, 0x00000AFA, 0x00000050, 0x0005002C, 0x00000011, + 0x00000A9F, 0x00000AFA, 0x00000A3A, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, + 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, + 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, + 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, + 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, + 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, + 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, + 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, 0x0004002B, + 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0003001D, + 0x000007D0, 0x0000000B, 0x0003001E, 0x0000079C, 0x000007D0, 0x00040020, 0x00000A1B, 0x00000002, + 0x0000079C, 0x0004003B, 0x00000A1B, 0x00000CC7, 0x00000002, 0x00040020, 0x00000288, 0x00000002, + 0x0000000B, 0x0007001E, 0x0000040C, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, + 0x00040020, 0x00000688, 0x00000009, 0x0000040C, 0x0004003B, 0x00000688, 0x00000CE9, 0x00000009, + 0x00040020, 0x00000289, 0x00000009, 0x0000000B, 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, + 0x0004002B, 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, + 0x0004002B, 0x0000000B, 0x00000A5E, 0x0000001C, 0x0005002C, 0x00000011, 0x0000073F, 0x00000A0A, + 0x00000A16, 0x0004002B, 0x0000000C, 0x00000A29, 0x0000000A, 0x0004002B, 0x0000000C, 0x00000A59, + 0x0000001A, 0x0004002B, 0x0000000C, 0x00000A50, 0x00000017, 0x0004002B, 0x0000000B, 0x00000926, + 0x01000000, 0x0005002C, 0x00000011, 0x000008E3, 0x00000A46, 0x00000A52, 0x0004002B, 0x0000000D, + 0x00000A0C, 0x00000000, 0x0004002B, 0x0000000D, 0x000000FC, 0x3F000000, 0x00040020, 0x00000291, + 0x00000001, 0x00000014, 0x0004003B, 0x00000291, 0x00000F48, 0x00000001, 0x0003001D, 0x000007DC, + 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, + 0x0004003B, 0x00000A32, 0x00001592, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, + 0x0006002C, 0x00000014, 0x00000AC7, 0x00000A22, 0x00000A22, 0x00000A0D, 0x0005002C, 0x00000011, + 0x000007A2, 0x00000A37, 0x00000A0D, 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, + 0x0005002C, 0x00000011, 0x0000084A, 0x00000A37, 0x00000A37, 0x0007002C, 0x0000001D, 0x00000504, + 0x00000341, 0x00000341, 0x00000341, 0x00000341, 0x0007002C, 0x0000001A, 0x00000302, 0x00000A3B, + 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x0007002C, 0x00000017, 0x0000064B, 0x00000144, 0x00000144, + 0x00000144, 0x00000144, 0x0006002C, 0x00000014, 0x00000105, 0x00000A44, 0x00000A44, 0x00000A44, + 0x0006002C, 0x00000014, 0x00000466, 0x00000B87, 0x00000B87, 0x00000B87, 0x0006002C, 0x00000014, + 0x00000B0C, 0x00000A1F, 0x00000A1F, 0x00000A1F, 0x0006002C, 0x00000014, 0x00000A12, 0x00000A0A, + 0x00000A0A, 0x00000A0A, 0x0006002C, 0x00000014, 0x000003FA, 0x00000B7E, 0x00000B7E, 0x00000B7E, + 0x0006002C, 0x00000014, 0x00000189, 0x00000A4F, 0x00000A4F, 0x00000A4F, 0x0006002C, 0x00000014, + 0x0000008D, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000013, 0x00000049, 0x00000341, + 0x00000341, 0x0005002C, 0x00000012, 0x00000867, 0x00000A3B, 0x00000A3B, 0x0004002B, 0x0000000B, + 0x00000A2B, 0x0000000B, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, + 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, + 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, + 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0004002B, 0x0000000C, + 0x00000089, 0x3F800000, 0x0004002B, 0x0000000B, 0x00000184, 0x00000500, 0x0004002B, 0x0000000B, + 0x0000086E, 0x00280000, 0x0004002B, 0x0000000B, 0x000009F8, 0xFFFFFFFA, 0x0006002C, 0x00000014, + 0x00000938, 0x000009F8, 0x000009F8, 0x000009F8, 0x0004002B, 0x0000000B, 0x00000AFD, 0x00000051, + 0x0004002B, 0x0000000B, 0x00000B00, 0x00000052, 0x0004002B, 0x0000000B, 0x00000B03, 0x00000053, + 0x0004002B, 0x0000000D, 0x0000016E, 0x3E800000, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, + 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, + 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000289, 0x000056E5, 0x00000CE9, 0x00000A0B, + 0x0004003D, 0x0000000B, 0x00003D0B, 0x000056E5, 0x00050041, 0x00000289, 0x000058AC, 0x00000CE9, + 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005158, 0x000058AC, 0x000500C7, 0x0000000B, 0x00005051, + 0x00003D0B, 0x00000A44, 0x000500C2, 0x0000000B, 0x00004E0A, 0x00003D0B, 0x00000A28, 0x000500C7, + 0x0000000B, 0x0000217E, 0x00004E0A, 0x00000A13, 0x000500C2, 0x0000000B, 0x0000520A, 0x00003D0B, + 0x00000A31, 0x000500C7, 0x0000000B, 0x0000217F, 0x0000520A, 0x00000A81, 0x000500C2, 0x0000000B, + 0x0000520B, 0x00003D0B, 0x00000A52, 0x000500C7, 0x0000000B, 0x00002180, 0x0000520B, 0x00000A37, + 0x000500C2, 0x0000000B, 0x00004994, 0x00003D0B, 0x00000A5E, 0x000500C7, 0x0000000B, 0x000023AA, + 0x00004994, 0x00000A0D, 0x00050050, 0x00000011, 0x000022A7, 0x00005158, 0x00005158, 0x000500C2, + 0x00000011, 0x00002568, 0x000022A7, 0x0000073F, 0x000500C7, 0x00000011, 0x00005B53, 0x00002568, + 0x000007A2, 0x000500C4, 0x00000011, 0x00003F4F, 0x00005B53, 0x0000074E, 0x00050084, 0x00000011, + 0x000059EB, 0x00003F4F, 0x00000724, 0x000500C2, 0x0000000B, 0x00003213, 0x00005158, 0x00000A19, + 0x000500C7, 0x0000000B, 0x00003F4C, 0x00003213, 0x00000A81, 0x00050041, 0x00000289, 0x0000492C, + 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000289, + 0x000058AD, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x000051B7, 0x000058AD, 0x000500C7, + 0x0000000B, 0x00004ADC, 0x00005EAC, 0x00000A1F, 0x000500C7, 0x0000000B, 0x000055EF, 0x00005EAC, + 0x00000A22, 0x000500AB, 0x00000009, 0x0000500F, 0x000055EF, 0x00000A0A, 0x000500C2, 0x0000000B, + 0x00002311, 0x00005EAC, 0x00000A16, 0x000500C7, 0x0000000B, 0x00004408, 0x00002311, 0x00000A1F, + 0x0004007C, 0x0000000C, 0x00005988, 0x00005EAC, 0x000500C4, 0x0000000C, 0x0000358F, 0x00005988, + 0x00000A29, 0x000500C3, 0x0000000C, 0x0000509C, 0x0000358F, 0x00000A59, 0x000500C4, 0x0000000C, + 0x00004702, 0x0000509C, 0x00000A50, 0x00050080, 0x0000000C, 0x00001D26, 0x00004702, 0x00000089, + 0x0004007C, 0x0000000D, 0x00002B2C, 0x00001D26, 0x000500C7, 0x0000000B, 0x00005879, 0x00005EAC, + 0x00000926, 0x000500AB, 0x00000009, 0x00001D59, 0x00005879, 0x00000A0A, 0x000500C7, 0x0000000B, + 0x00001F43, 0x000051B7, 0x00000A44, 0x000500C4, 0x0000000B, 0x00003DA7, 0x00001F43, 0x00000A19, + 0x000500C2, 0x0000000B, 0x0000583F, 0x000051B7, 0x00000A28, 0x000500C7, 0x0000000B, 0x00004BBE, + 0x0000583F, 0x00000A44, 0x000500C4, 0x0000000B, 0x00006273, 0x00004BBE, 0x00000A19, 0x00050050, + 0x00000011, 0x000028B6, 0x000051B7, 0x000051B7, 0x000500C2, 0x00000011, 0x00002891, 0x000028B6, + 0x000008E3, 0x000500C7, 0x00000011, 0x00005B54, 0x00002891, 0x0000084A, 0x000500C4, 0x00000011, + 0x00003F50, 0x00005B54, 0x0000074E, 0x00050084, 0x00000011, 0x000059EC, 0x00003F50, 0x00000724, + 0x000500C2, 0x0000000B, 0x00003214, 0x000051B7, 0x00000A5E, 0x000500C7, 0x0000000B, 0x00003F4D, + 0x00003214, 0x00000A1F, 0x00050041, 0x00000289, 0x000048E0, 0x00000CE9, 0x00000A17, 0x0004003D, + 0x0000000B, 0x000062B6, 0x000048E0, 0x0004003D, 0x00000014, 0x0000374F, 0x00000F48, 0x0007004F, + 0x00000011, 0x00003180, 0x0000374F, 0x0000374F, 0x00000000, 0x00000001, 0x000500C4, 0x00000011, + 0x00002EF9, 0x00003180, 0x00000718, 0x00050051, 0x0000000B, 0x00001DD8, 0x00002EF9, 0x00000000, + 0x000500C4, 0x0000000B, 0x00002D8A, 0x00003F4C, 0x00000A13, 0x000500AE, 0x00000009, 0x00003C13, + 0x00001DD8, 0x00002D8A, 0x000300F7, 0x0000505A, 0x00000002, 0x000400FA, 0x00003C13, 0x000055E8, + 0x0000505A, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x0000505A, 0x0007000C, + 0x0000000B, 0x00003BA0, 0x00000001, 0x00000029, 0x00001DD8, 0x00000A0A, 0x00050051, 0x0000000B, + 0x000023B6, 0x00002EF9, 0x00000001, 0x0007000C, 0x0000000B, 0x00004145, 0x00000001, 0x00000029, + 0x000023B6, 0x00000A0A, 0x00050050, 0x00000011, 0x000051EF, 0x00003BA0, 0x00004145, 0x00050080, + 0x00000011, 0x0000522C, 0x000051EF, 0x000059EB, 0x000500B2, 0x00000009, 0x00003ECB, 0x00003F4D, + 0x00000A13, 0x000300F7, 0x00005CE0, 0x00000000, 0x000400FA, 0x00003ECB, 0x00002AEE, 0x00003AEF, + 0x000200F8, 0x00003AEF, 0x000500AA, 0x00000009, 0x000034FE, 0x00003F4D, 0x00000A19, 0x000600A9, + 0x0000000B, 0x000020F6, 0x000034FE, 0x00000A10, 0x00000A0A, 0x000200F9, 0x00005CE0, 0x000200F8, + 0x00002AEE, 0x000200F9, 0x00005CE0, 0x000200F8, 0x00005CE0, 0x000700F5, 0x0000000B, 0x00004B64, + 0x00003F4D, 0x00002AEE, 0x000020F6, 0x00003AEF, 0x00050050, 0x00000011, 0x000041BE, 0x0000217E, + 0x0000217E, 0x000500AE, 0x0000000F, 0x00002E19, 0x000041BE, 0x0000072D, 0x000600A9, 0x00000011, + 0x00004BB5, 0x00002E19, 0x00000724, 0x0000070F, 0x000500C4, 0x00000011, 0x00002AEA, 0x0000522C, + 0x00004BB5, 0x00050050, 0x00000011, 0x0000605D, 0x00004B64, 0x00004B64, 0x000500C2, 0x00000011, + 0x00002385, 0x0000605D, 0x00000718, 0x000500C7, 0x00000011, 0x00003AEC, 0x00002385, 0x00000724, + 0x00050080, 0x00000011, 0x000027D5, 0x00002AEA, 0x00003AEC, 0x00050050, 0x00000011, 0x00002164, + 0x000023AA, 0x00000A0A, 0x000500C2, 0x00000011, 0x0000264A, 0x00000A9F, 0x00002164, 0x00050086, + 0x00000011, 0x000027A2, 0x000027D5, 0x0000264A, 0x00050051, 0x0000000B, 0x00004FA6, 0x000027A2, + 0x00000001, 0x00050084, 0x0000000B, 0x00002B26, 0x00004FA6, 0x00005051, 0x00050051, 0x0000000B, + 0x00006059, 0x000027A2, 0x00000000, 0x00050080, 0x0000000B, 0x00005420, 0x00002B26, 0x00006059, + 0x00050080, 0x0000000B, 0x00002226, 0x0000217F, 0x00005420, 0x00050084, 0x00000011, 0x00005B31, + 0x000027A2, 0x0000264A, 0x00050082, 0x00000011, 0x00002E74, 0x000027D5, 0x00005B31, 0x00050084, + 0x0000000B, 0x00001F75, 0x00002226, 0x00000184, 0x00050051, 0x0000000B, 0x00005EC7, 0x00002E74, + 0x00000001, 0x00050051, 0x0000000B, 0x00005BE6, 0x0000264A, 0x00000000, 0x00050084, 0x0000000B, + 0x00005966, 0x00005EC7, 0x00005BE6, 0x00050051, 0x0000000B, 0x00001AE6, 0x00002E74, 0x00000000, + 0x00050080, 0x0000000B, 0x000025E0, 0x00005966, 0x00001AE6, 0x000500C4, 0x0000000B, 0x000046C4, + 0x000025E0, 0x000023AA, 0x00050080, 0x0000000B, 0x00004719, 0x00001F75, 0x000046C4, 0x00050089, + 0x0000000B, 0x00005AD8, 0x00004719, 0x0000086E, 0x000500AE, 0x00000009, 0x00003361, 0x0000217E, + 0x00000A10, 0x000600A9, 0x0000000B, 0x0000609F, 0x00003361, 0x00000A0D, 0x00000A0A, 0x00050080, + 0x0000000B, 0x00004E6A, 0x000023AA, 0x0000609F, 0x000500C4, 0x0000000B, 0x0000199B, 0x00000A0D, + 0x00004E6A, 0x000500AB, 0x00000009, 0x00005AEF, 0x000023AA, 0x00000A0A, 0x000300F7, 0x0000530F, + 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B65, 0x000040B9, 0x000200F8, 0x000040B9, 0x000500AA, + 0x00000009, 0x00004ADA, 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F49, 0x00000002, 0x000400FA, + 0x00004ADA, 0x00002621, 0x00002F61, 0x000200F8, 0x00002F61, 0x00060041, 0x00000288, 0x00004BCF, + 0x00000CC7, 0x00000A0B, 0x00005AD8, 0x0004003D, 0x0000000B, 0x00005D43, 0x00004BCF, 0x00050080, + 0x0000000B, 0x00002DA7, 0x00005AD8, 0x0000199B, 0x00060041, 0x00000288, 0x00005FEE, 0x00000CC7, + 0x00000A0B, 0x00002DA7, 0x0004003D, 0x0000000B, 0x00003FFB, 0x00005FEE, 0x00050050, 0x00000011, + 0x0000512C, 0x00005D43, 0x00003FFB, 0x000200F9, 0x00004F49, 0x000200F8, 0x00002621, 0x00060041, + 0x00000288, 0x00005545, 0x00000CC7, 0x00000A0B, 0x00005AD8, 0x0004003D, 0x0000000B, 0x00005D44, + 0x00005545, 0x00050080, 0x0000000B, 0x00002DA8, 0x00005AD8, 0x00000A0D, 0x00060041, 0x00000288, + 0x00005FEF, 0x00000CC7, 0x00000A0B, 0x00002DA8, 0x0004003D, 0x0000000B, 0x00003FFC, 0x00005FEF, + 0x00050050, 0x00000011, 0x0000512D, 0x00005D44, 0x00003FFC, 0x000200F9, 0x00004F49, 0x000200F8, + 0x00004F49, 0x000700F5, 0x00000011, 0x00002ABF, 0x0000512D, 0x00002621, 0x0000512C, 0x00002F61, + 0x000300F7, 0x00003F60, 0x00000000, 0x001300FB, 0x00002180, 0x00004BFB, 0x00000000, 0x000038F9, + 0x00000001, 0x000038F9, 0x00000002, 0x00001CBB, 0x0000000A, 0x00001CBB, 0x00000003, 0x00001CBA, + 0x0000000C, 0x00001CBA, 0x00000004, 0x00001FFE, 0x00000006, 0x00002033, 0x000200F8, 0x00002033, + 0x00050051, 0x0000000B, 0x00005F56, 0x00002ABF, 0x00000000, 0x0006000C, 0x00000013, 0x00006067, + 0x00000001, 0x0000003E, 0x00005F56, 0x00050051, 0x0000000D, 0x00002762, 0x00006067, 0x00000000, + 0x00050051, 0x0000000D, 0x00004446, 0x00006067, 0x00000001, 0x00070050, 0x0000001D, 0x0000390C, + 0x00002762, 0x00004446, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x0000437A, 0x00002ABF, + 0x00000001, 0x0006000C, 0x00000013, 0x0000466B, 0x00000001, 0x0000003E, 0x0000437A, 0x00050051, + 0x0000000D, 0x00002763, 0x0000466B, 0x00000000, 0x00050051, 0x0000000D, 0x000050BE, 0x0000466B, + 0x00000001, 0x00070050, 0x0000001D, 0x00002349, 0x00002763, 0x000050BE, 0x00000A0C, 0x00000A0C, + 0x000200F9, 0x00003F60, 0x000200F8, 0x00001FFE, 0x00050051, 0x0000000B, 0x0000308B, 0x00002ABF, + 0x00000000, 0x0004007C, 0x0000000C, 0x0000589D, 0x0000308B, 0x00050050, 0x00000012, 0x0000471A, + 0x0000589D, 0x0000589D, 0x000500C4, 0x00000012, 0x000047AD, 0x0000471A, 0x000007A7, 0x000500C3, + 0x00000012, 0x00003417, 0x000047AD, 0x00000867, 0x0004006F, 0x00000013, 0x00002A97, 0x00003417, + 0x0005008E, 0x00000013, 0x00004747, 0x00002A97, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E06, + 0x00000001, 0x00000028, 0x00000049, 0x00004747, 0x00050051, 0x0000000D, 0x00005F0A, 0x00005E06, + 0x00000000, 0x00050051, 0x0000000D, 0x00003CD4, 0x00005E06, 0x00000001, 0x00070050, 0x0000001D, + 0x0000411E, 0x00005F0A, 0x00003CD4, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C42, + 0x00002ABF, 0x00000001, 0x0004007C, 0x0000000C, 0x00003EA1, 0x00004C42, 0x00050050, 0x00000012, + 0x0000471B, 0x00003EA1, 0x00003EA1, 0x000500C4, 0x00000012, 0x000047AE, 0x0000471B, 0x000007A7, + 0x000500C3, 0x00000012, 0x00003418, 0x000047AE, 0x00000867, 0x0004006F, 0x00000013, 0x00002A98, + 0x00003418, 0x0005008E, 0x00000013, 0x00004748, 0x00002A98, 0x000007FE, 0x0007000C, 0x00000013, + 0x00005E07, 0x00000001, 0x00000028, 0x00000049, 0x00004748, 0x00050051, 0x0000000D, 0x00005F0B, + 0x00005E07, 0x00000000, 0x00050051, 0x0000000D, 0x0000494C, 0x00005E07, 0x00000001, 0x00070050, + 0x0000001D, 0x0000234A, 0x00005F0B, 0x0000494C, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F60, + 0x000200F8, 0x00001CBA, 0x00050051, 0x0000000B, 0x000056BD, 0x00002ABF, 0x00000000, 0x00060050, + 0x00000014, 0x00004F0A, 0x000056BD, 0x000056BD, 0x000056BD, 0x000500C2, 0x00000014, 0x00002B0D, + 0x00004F0A, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DE6, 0x00002B0D, 0x00000105, 0x000500C7, + 0x00000014, 0x0000489C, 0x00005DE6, 0x00000466, 0x000500C2, 0x00000014, 0x00005B90, 0x00005DE6, + 0x00000B0C, 0x000500AA, 0x00000010, 0x000040C9, 0x00005B90, 0x00000A12, 0x0006000C, 0x00000016, + 0x00002C4B, 0x00000001, 0x0000004B, 0x0000489C, 0x0004007C, 0x00000014, 0x00002A15, 0x00002C4B, + 0x00050082, 0x00000014, 0x0000187A, 0x00000B0C, 0x00002A15, 0x00050080, 0x00000014, 0x00002210, + 0x00002A15, 0x00000938, 0x000600A9, 0x00000014, 0x0000286F, 0x000040C9, 0x00002210, 0x00005B90, + 0x000500C4, 0x00000014, 0x00005AD4, 0x0000489C, 0x0000187A, 0x000500C7, 0x00000014, 0x0000499A, + 0x00005AD4, 0x00000466, 0x000600A9, 0x00000014, 0x00002A9D, 0x000040C9, 0x0000499A, 0x0000489C, + 0x00050080, 0x00000014, 0x00005FF9, 0x0000286F, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F7F, + 0x00005FF9, 0x00000189, 0x000500C4, 0x00000014, 0x00003FA6, 0x00002A9D, 0x0000008D, 0x000500C5, + 0x00000014, 0x0000577C, 0x00004F7F, 0x00003FA6, 0x000500AA, 0x00000010, 0x00003600, 0x00005DE6, + 0x00000A12, 0x000600A9, 0x00000014, 0x00004242, 0x00003600, 0x00000A12, 0x0000577C, 0x0004007C, + 0x00000018, 0x000029CF, 0x00004242, 0x000500C2, 0x0000000B, 0x00004BA4, 0x000056BD, 0x00000A64, + 0x00040070, 0x0000000D, 0x0000480E, 0x00004BA4, 0x00050085, 0x0000000D, 0x00003E1F, 0x0000480E, + 0x00000149, 0x00050051, 0x0000000D, 0x000053C2, 0x000029CF, 0x00000000, 0x00050051, 0x0000000D, + 0x00002A55, 0x000029CF, 0x00000001, 0x00050051, 0x0000000D, 0x00001E99, 0x000029CF, 0x00000002, + 0x00070050, 0x0000001D, 0x00003DDA, 0x000053C2, 0x00002A55, 0x00001E99, 0x00003E1F, 0x00050051, + 0x0000000B, 0x000027F5, 0x00002ABF, 0x00000001, 0x00060050, 0x00000014, 0x0000350E, 0x000027F5, + 0x000027F5, 0x000027F5, 0x000500C2, 0x00000014, 0x00002B0E, 0x0000350E, 0x00000BB4, 0x000500C7, + 0x00000014, 0x00005DE7, 0x00002B0E, 0x00000105, 0x000500C7, 0x00000014, 0x0000489D, 0x00005DE7, + 0x00000466, 0x000500C2, 0x00000014, 0x00005B91, 0x00005DE7, 0x00000B0C, 0x000500AA, 0x00000010, + 0x000040CA, 0x00005B91, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4C, 0x00000001, 0x0000004B, + 0x0000489D, 0x0004007C, 0x00000014, 0x00002A16, 0x00002C4C, 0x00050082, 0x00000014, 0x0000187B, + 0x00000B0C, 0x00002A16, 0x00050080, 0x00000014, 0x00002211, 0x00002A16, 0x00000938, 0x000600A9, + 0x00000014, 0x00002870, 0x000040CA, 0x00002211, 0x00005B91, 0x000500C4, 0x00000014, 0x00005AD5, + 0x0000489D, 0x0000187B, 0x000500C7, 0x00000014, 0x0000499B, 0x00005AD5, 0x00000466, 0x000600A9, + 0x00000014, 0x00002A9E, 0x000040CA, 0x0000499B, 0x0000489D, 0x00050080, 0x00000014, 0x00005FFA, + 0x00002870, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F80, 0x00005FFA, 0x00000189, 0x000500C4, + 0x00000014, 0x00003FA7, 0x00002A9E, 0x0000008D, 0x000500C5, 0x00000014, 0x0000577D, 0x00004F80, + 0x00003FA7, 0x000500AA, 0x00000010, 0x00003601, 0x00005DE7, 0x00000A12, 0x000600A9, 0x00000014, + 0x00004243, 0x00003601, 0x00000A12, 0x0000577D, 0x0004007C, 0x00000018, 0x000029D0, 0x00004243, + 0x000500C2, 0x0000000B, 0x00004BA5, 0x000027F5, 0x00000A64, 0x00040070, 0x0000000D, 0x0000480F, + 0x00004BA5, 0x00050085, 0x0000000D, 0x00003E20, 0x0000480F, 0x00000149, 0x00050051, 0x0000000D, + 0x000053C3, 0x000029D0, 0x00000000, 0x00050051, 0x0000000D, 0x00002A56, 0x000029D0, 0x00000001, + 0x00050051, 0x0000000D, 0x00002B11, 0x000029D0, 0x00000002, 0x00070050, 0x0000001D, 0x0000234B, + 0x000053C3, 0x00002A56, 0x00002B11, 0x00003E20, 0x000200F9, 0x00003F60, 0x000200F8, 0x00001CBB, + 0x00050051, 0x0000000B, 0x000056BE, 0x00002ABF, 0x00000000, 0x00070050, 0x00000017, 0x00004F0B, + 0x000056BE, 0x000056BE, 0x000056BE, 0x000056BE, 0x000500C2, 0x00000017, 0x00002498, 0x00004F0B, + 0x0000034D, 0x000500C7, 0x00000017, 0x000049AB, 0x00002498, 0x0000027B, 0x00040070, 0x0000001D, + 0x00003CB7, 0x000049AB, 0x00050085, 0x0000001D, 0x00004130, 0x00003CB7, 0x00000AEE, 0x00050051, + 0x0000000B, 0x00005CD2, 0x00002ABF, 0x00000001, 0x00070050, 0x00000017, 0x0000514D, 0x00005CD2, + 0x00005CD2, 0x00005CD2, 0x00005CD2, 0x000500C2, 0x00000017, 0x00002499, 0x0000514D, 0x0000034D, + 0x000500C7, 0x00000017, 0x000049AC, 0x00002499, 0x0000027B, 0x00040070, 0x0000001D, 0x0000492F, + 0x000049AC, 0x00050085, 0x0000001D, 0x0000269F, 0x0000492F, 0x00000AEE, 0x000200F9, 0x00003F60, + 0x000200F8, 0x000038F9, 0x00050051, 0x0000000B, 0x000056BF, 0x00002ABF, 0x00000000, 0x00070050, + 0x00000017, 0x00004F0C, 0x000056BF, 0x000056BF, 0x000056BF, 0x000056BF, 0x000500C2, 0x00000017, + 0x0000249A, 0x00004F0C, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A56, 0x0000249A, 0x0000064B, + 0x00040070, 0x0000001D, 0x000036A2, 0x00004A56, 0x0005008E, 0x0000001D, 0x00004B23, 0x000036A2, + 0x0000017A, 0x00050051, 0x0000000B, 0x0000219F, 0x00002ABF, 0x00000001, 0x00070050, 0x00000017, + 0x0000610B, 0x0000219F, 0x0000219F, 0x0000219F, 0x0000219F, 0x000500C2, 0x00000017, 0x0000249B, + 0x0000610B, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A57, 0x0000249B, 0x0000064B, 0x00040070, + 0x0000001D, 0x0000431A, 0x00004A57, 0x0005008E, 0x0000001D, 0x00003092, 0x0000431A, 0x0000017A, + 0x000200F9, 0x00003F60, 0x000200F8, 0x00004BFB, 0x00050051, 0x0000000B, 0x0000308C, 0x00002ABF, + 0x00000000, 0x0004007C, 0x0000000D, 0x00004FEE, 0x0000308C, 0x00050050, 0x00000013, 0x00004336, + 0x00004FEE, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D90, 0x00004336, 0x00004336, 0x00000000, + 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B1, 0x00002ABF, 0x00000001, + 0x0004007C, 0x0000000D, 0x00003F68, 0x000056B1, 0x00050050, 0x00000013, 0x00004FAE, 0x00003F68, + 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3A, 0x00004FAE, 0x00004FAE, 0x00000000, 0x00000001, + 0x00000001, 0x00000001, 0x000200F9, 0x00003F60, 0x000200F8, 0x00003F60, 0x000F00F5, 0x0000001D, + 0x00002BF3, 0x00005A3A, 0x00004BFB, 0x00003092, 0x000038F9, 0x0000269F, 0x00001CBB, 0x0000234B, + 0x00001CBA, 0x0000234A, 0x00001FFE, 0x00002349, 0x00002033, 0x000F00F5, 0x0000001D, 0x0000358D, + 0x00002D90, 0x00004BFB, 0x00004B23, 0x000038F9, 0x00004130, 0x00001CBB, 0x00003DDA, 0x00001CBA, + 0x0000411E, 0x00001FFE, 0x0000390C, 0x00002033, 0x000200F9, 0x0000530F, 0x000200F8, 0x00003B65, + 0x000500AA, 0x00000009, 0x00005450, 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F4A, 0x00000002, + 0x000400FA, 0x00005450, 0x00002622, 0x00002F62, 0x000200F8, 0x00002F62, 0x00060041, 0x00000288, + 0x00004BD0, 0x00000CC7, 0x00000A0B, 0x00005AD8, 0x0004003D, 0x0000000B, 0x00005D45, 0x00004BD0, + 0x00050080, 0x0000000B, 0x00002DA9, 0x00005AD8, 0x00000A0D, 0x00060041, 0x00000288, 0x000018FF, + 0x00000CC7, 0x00000A0B, 0x00002DA9, 0x0004003D, 0x0000000B, 0x00005C62, 0x000018FF, 0x00050080, + 0x0000000B, 0x00002DAA, 0x00005AD8, 0x0000199B, 0x00060041, 0x00000288, 0x00001900, 0x00000CC7, + 0x00000A0B, 0x00002DAA, 0x0004003D, 0x0000000B, 0x00005C63, 0x00001900, 0x00050080, 0x0000000B, + 0x00002DAB, 0x00002DAA, 0x00000A0D, 0x00060041, 0x00000288, 0x00005FF0, 0x00000CC7, 0x00000A0B, + 0x00002DAB, 0x0004003D, 0x0000000B, 0x00003FFD, 0x00005FF0, 0x00070050, 0x00000017, 0x0000512E, + 0x00005D45, 0x00005C62, 0x00005C63, 0x00003FFD, 0x000200F9, 0x00004F4A, 0x000200F8, 0x00002622, + 0x00060041, 0x00000288, 0x00005546, 0x00000CC7, 0x00000A0B, 0x00005AD8, 0x0004003D, 0x0000000B, + 0x00005D46, 0x00005546, 0x00050080, 0x0000000B, 0x00002DAC, 0x00005AD8, 0x00000A0D, 0x00060041, + 0x00000288, 0x00001901, 0x00000CC7, 0x00000A0B, 0x00002DAC, 0x0004003D, 0x0000000B, 0x00005C64, + 0x00001901, 0x00050080, 0x0000000B, 0x00002DAD, 0x00005AD8, 0x00000A10, 0x00060041, 0x00000288, + 0x00001902, 0x00000CC7, 0x00000A0B, 0x00002DAD, 0x0004003D, 0x0000000B, 0x00005C65, 0x00001902, + 0x00050080, 0x0000000B, 0x00002DAE, 0x00005AD8, 0x00000A13, 0x00060041, 0x00000288, 0x00005FF1, + 0x00000CC7, 0x00000A0B, 0x00002DAE, 0x0004003D, 0x0000000B, 0x00003FFE, 0x00005FF1, 0x00070050, + 0x00000017, 0x0000512F, 0x00005D46, 0x00005C64, 0x00005C65, 0x00003FFE, 0x000200F9, 0x00004F4A, + 0x000200F8, 0x00004F4A, 0x000700F5, 0x00000017, 0x00002AC0, 0x0000512F, 0x00002622, 0x0000512E, + 0x00002F62, 0x000300F7, 0x00004F23, 0x00000000, 0x000700FB, 0x00002180, 0x00004F56, 0x00000005, + 0x00002158, 0x00000007, 0x00002034, 0x000200F8, 0x00002034, 0x00050051, 0x0000000B, 0x00005F57, + 0x00002AC0, 0x00000000, 0x0006000C, 0x00000013, 0x00006068, 0x00000001, 0x0000003E, 0x00005F57, + 0x00050051, 0x0000000D, 0x00002775, 0x00006068, 0x00000000, 0x00050051, 0x0000000D, 0x00003EB8, + 0x00006068, 0x00000001, 0x00050051, 0x0000000B, 0x00004281, 0x00002AC0, 0x00000001, 0x0006000C, + 0x00000013, 0x00003CF5, 0x00000001, 0x0000003E, 0x00004281, 0x00050051, 0x0000000D, 0x00002764, + 0x00003CF5, 0x00000000, 0x00050051, 0x0000000D, 0x00004447, 0x00003CF5, 0x00000001, 0x00070050, + 0x0000001D, 0x0000390D, 0x00002775, 0x00003EB8, 0x00002764, 0x00004447, 0x00050051, 0x0000000B, + 0x0000437B, 0x00002AC0, 0x00000002, 0x0006000C, 0x00000013, 0x0000466C, 0x00000001, 0x0000003E, + 0x0000437B, 0x00050051, 0x0000000D, 0x00002776, 0x0000466C, 0x00000000, 0x00050051, 0x0000000D, + 0x00003EB9, 0x0000466C, 0x00000001, 0x00050051, 0x0000000B, 0x00004282, 0x00002AC0, 0x00000003, + 0x0006000C, 0x00000013, 0x00003CF6, 0x00000001, 0x0000003E, 0x00004282, 0x00050051, 0x0000000D, + 0x00002765, 0x00003CF6, 0x00000000, 0x00050051, 0x0000000D, 0x000050BF, 0x00003CF6, 0x00000001, + 0x00070050, 0x0000001D, 0x0000234C, 0x00002776, 0x00003EB9, 0x00002765, 0x000050BF, 0x000200F9, + 0x00004F23, 0x000200F8, 0x00002158, 0x0007004F, 0x00000011, 0x000025FB, 0x00002AC0, 0x00002AC0, + 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x00005B3C, 0x000025FB, 0x0009004F, 0x0000001A, + 0x000060CE, 0x00005B3C, 0x00005B3C, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, + 0x0000001A, 0x000048A6, 0x000060CE, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D8D, 0x000048A6, + 0x00000302, 0x0004006F, 0x0000001D, 0x00002A99, 0x00003D8D, 0x0005008E, 0x0000001D, 0x00004721, + 0x00002A99, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006291, 0x00000001, 0x00000028, 0x00000504, + 0x00004721, 0x0007004F, 0x00000011, 0x0000376B, 0x00002AC0, 0x00002AC0, 0x00000002, 0x00000003, + 0x0004007C, 0x00000012, 0x000024BF, 0x0000376B, 0x0009004F, 0x0000001A, 0x000060CF, 0x000024BF, + 0x000024BF, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048A7, + 0x000060CF, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D8E, 0x000048A7, 0x00000302, 0x0004006F, + 0x0000001D, 0x00002A9A, 0x00003D8E, 0x0005008E, 0x0000001D, 0x000053BF, 0x00002A9A, 0x000007FE, + 0x0007000C, 0x0000001D, 0x00004362, 0x00000001, 0x00000028, 0x00000504, 0x000053BF, 0x000200F9, + 0x00004F23, 0x000200F8, 0x00004F56, 0x0007004F, 0x00000011, 0x00002623, 0x00002AC0, 0x00002AC0, + 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x00005159, 0x00002623, 0x00050051, 0x0000000D, + 0x00001B7B, 0x00005159, 0x00000000, 0x00050051, 0x0000000D, 0x0000346A, 0x00005159, 0x00000001, + 0x00070050, 0x0000001D, 0x00004278, 0x00001B7B, 0x0000346A, 0x00000A0C, 0x00000A0C, 0x0007004F, + 0x00000011, 0x000041D8, 0x00002AC0, 0x00002AC0, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, + 0x0000375D, 0x000041D8, 0x00050051, 0x0000000D, 0x00001B7C, 0x0000375D, 0x00000000, 0x00050051, + 0x0000000D, 0x00004108, 0x0000375D, 0x00000001, 0x00070050, 0x0000001D, 0x0000234D, 0x00001B7C, + 0x00004108, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F23, 0x000200F8, 0x00004F23, 0x000900F5, + 0x0000001D, 0x00002BF4, 0x0000234D, 0x00004F56, 0x00004362, 0x00002158, 0x0000234C, 0x00002034, + 0x000900F5, 0x0000001D, 0x0000358E, 0x00004278, 0x00004F56, 0x00006291, 0x00002158, 0x0000390D, + 0x00002034, 0x000200F9, 0x0000530F, 0x000200F8, 0x0000530F, 0x000700F5, 0x0000001D, 0x00002662, + 0x00002BF4, 0x00004F23, 0x00002BF3, 0x00003F60, 0x000700F5, 0x0000001D, 0x000036E3, 0x0000358E, + 0x00004F23, 0x0000358D, 0x00003F60, 0x000500AE, 0x00000009, 0x00002E55, 0x00003F4D, 0x00000A16, + 0x000300F7, 0x00005313, 0x00000002, 0x000400FA, 0x00002E55, 0x000050E5, 0x00005313, 0x000200F8, + 0x000050E5, 0x00050085, 0x0000000D, 0x000061FB, 0x00002B2C, 0x000000FC, 0x00050080, 0x0000000B, + 0x00005E78, 0x00005AD8, 0x00000AFA, 0x000300F7, 0x00005310, 0x00000002, 0x000400FA, 0x00005AEF, + 0x00003B66, 0x000040BA, 0x000200F8, 0x000040BA, 0x000500AA, 0x00000009, 0x00004ADB, 0x0000199B, + 0x00000A0D, 0x000300F7, 0x00004F4B, 0x00000002, 0x000400FA, 0x00004ADB, 0x00002624, 0x00002F63, + 0x000200F8, 0x00002F63, 0x00060041, 0x00000288, 0x00004BD1, 0x00000CC7, 0x00000A0B, 0x00005E78, + 0x0004003D, 0x0000000B, 0x00005D47, 0x00004BD1, 0x00050080, 0x0000000B, 0x00002DAF, 0x00005E78, + 0x0000199B, 0x00060041, 0x00000288, 0x00005FF2, 0x00000CC7, 0x00000A0B, 0x00002DAF, 0x0004003D, + 0x0000000B, 0x00003FFF, 0x00005FF2, 0x00050050, 0x00000011, 0x00005130, 0x00005D47, 0x00003FFF, + 0x000200F9, 0x00004F4B, 0x000200F8, 0x00002624, 0x00060041, 0x00000288, 0x00005547, 0x00000CC7, + 0x00000A0B, 0x00005E78, 0x0004003D, 0x0000000B, 0x00005D48, 0x00005547, 0x00050080, 0x0000000B, + 0x00002DB0, 0x00005AD8, 0x00000AFD, 0x00060041, 0x00000288, 0x00005FF3, 0x00000CC7, 0x00000A0B, + 0x00002DB0, 0x0004003D, 0x0000000B, 0x00004000, 0x00005FF3, 0x00050050, 0x00000011, 0x00005131, + 0x00005D48, 0x00004000, 0x000200F9, 0x00004F4B, 0x000200F8, 0x00004F4B, 0x000700F5, 0x00000011, + 0x00002AC1, 0x00005131, 0x00002624, 0x00005130, 0x00002F63, 0x000300F7, 0x00003F61, 0x00000000, + 0x001300FB, 0x00002180, 0x00004BFC, 0x00000000, 0x000038FA, 0x00000001, 0x000038FA, 0x00000002, + 0x00001CBD, 0x0000000A, 0x00001CBD, 0x00000003, 0x00001CBC, 0x0000000C, 0x00001CBC, 0x00000004, + 0x00001FFF, 0x00000006, 0x00002035, 0x000200F8, 0x00002035, 0x00050051, 0x0000000B, 0x00005F58, + 0x00002AC1, 0x00000000, 0x0006000C, 0x00000013, 0x00006069, 0x00000001, 0x0000003E, 0x00005F58, + 0x00050051, 0x0000000D, 0x00002766, 0x00006069, 0x00000000, 0x00050051, 0x0000000D, 0x00004448, + 0x00006069, 0x00000001, 0x00070050, 0x0000001D, 0x0000390E, 0x00002766, 0x00004448, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x0000437C, 0x00002AC1, 0x00000001, 0x0006000C, 0x00000013, + 0x0000466D, 0x00000001, 0x0000003E, 0x0000437C, 0x00050051, 0x0000000D, 0x00002767, 0x0000466D, + 0x00000000, 0x00050051, 0x0000000D, 0x000050C0, 0x0000466D, 0x00000001, 0x00070050, 0x0000001D, + 0x0000234E, 0x00002767, 0x000050C0, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F61, 0x000200F8, + 0x00001FFF, 0x00050051, 0x0000000B, 0x0000308D, 0x00002AC1, 0x00000000, 0x0004007C, 0x0000000C, + 0x0000589E, 0x0000308D, 0x00050050, 0x00000012, 0x0000471C, 0x0000589E, 0x0000589E, 0x000500C4, + 0x00000012, 0x000047AF, 0x0000471C, 0x000007A7, 0x000500C3, 0x00000012, 0x00003419, 0x000047AF, + 0x00000867, 0x0004006F, 0x00000013, 0x00002A9B, 0x00003419, 0x0005008E, 0x00000013, 0x00004749, + 0x00002A9B, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E08, 0x00000001, 0x00000028, 0x00000049, + 0x00004749, 0x00050051, 0x0000000D, 0x00005F0C, 0x00005E08, 0x00000000, 0x00050051, 0x0000000D, + 0x00003CD5, 0x00005E08, 0x00000001, 0x00070050, 0x0000001D, 0x0000411F, 0x00005F0C, 0x00003CD5, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C43, 0x00002AC1, 0x00000001, 0x0004007C, + 0x0000000C, 0x00003EA2, 0x00004C43, 0x00050050, 0x00000012, 0x0000471D, 0x00003EA2, 0x00003EA2, + 0x000500C4, 0x00000012, 0x000047B0, 0x0000471D, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341A, + 0x000047B0, 0x00000867, 0x0004006F, 0x00000013, 0x00002A9C, 0x0000341A, 0x0005008E, 0x00000013, + 0x0000474A, 0x00002A9C, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E09, 0x00000001, 0x00000028, + 0x00000049, 0x0000474A, 0x00050051, 0x0000000D, 0x00005F0D, 0x00005E09, 0x00000000, 0x00050051, + 0x0000000D, 0x0000494D, 0x00005E09, 0x00000001, 0x00070050, 0x0000001D, 0x0000234F, 0x00005F0D, + 0x0000494D, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F61, 0x000200F8, 0x00001CBC, 0x00050051, + 0x0000000B, 0x000056C0, 0x00002AC1, 0x00000000, 0x00060050, 0x00000014, 0x00004F0D, 0x000056C0, + 0x000056C0, 0x000056C0, 0x000500C2, 0x00000014, 0x00002B0F, 0x00004F0D, 0x00000BB4, 0x000500C7, + 0x00000014, 0x00005DE8, 0x00002B0F, 0x00000105, 0x000500C7, 0x00000014, 0x0000489E, 0x00005DE8, + 0x00000466, 0x000500C2, 0x00000014, 0x00005B92, 0x00005DE8, 0x00000B0C, 0x000500AA, 0x00000010, + 0x000040CB, 0x00005B92, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4D, 0x00000001, 0x0000004B, + 0x0000489E, 0x0004007C, 0x00000014, 0x00002A17, 0x00002C4D, 0x00050082, 0x00000014, 0x0000187C, + 0x00000B0C, 0x00002A17, 0x00050080, 0x00000014, 0x00002212, 0x00002A17, 0x00000938, 0x000600A9, + 0x00000014, 0x00002871, 0x000040CB, 0x00002212, 0x00005B92, 0x000500C4, 0x00000014, 0x00005AD6, + 0x0000489E, 0x0000187C, 0x000500C7, 0x00000014, 0x0000499C, 0x00005AD6, 0x00000466, 0x000600A9, + 0x00000014, 0x00002A9F, 0x000040CB, 0x0000499C, 0x0000489E, 0x00050080, 0x00000014, 0x00005FFB, + 0x00002871, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F81, 0x00005FFB, 0x00000189, 0x000500C4, + 0x00000014, 0x00003FA8, 0x00002A9F, 0x0000008D, 0x000500C5, 0x00000014, 0x0000577E, 0x00004F81, + 0x00003FA8, 0x000500AA, 0x00000010, 0x00003602, 0x00005DE8, 0x00000A12, 0x000600A9, 0x00000014, + 0x00004244, 0x00003602, 0x00000A12, 0x0000577E, 0x0004007C, 0x00000018, 0x000029D1, 0x00004244, + 0x000500C2, 0x0000000B, 0x00004BA6, 0x000056C0, 0x00000A64, 0x00040070, 0x0000000D, 0x00004810, + 0x00004BA6, 0x00050085, 0x0000000D, 0x00003E21, 0x00004810, 0x00000149, 0x00050051, 0x0000000D, + 0x000053C4, 0x000029D1, 0x00000000, 0x00050051, 0x0000000D, 0x00002A57, 0x000029D1, 0x00000001, + 0x00050051, 0x0000000D, 0x00001E9A, 0x000029D1, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDB, + 0x000053C4, 0x00002A57, 0x00001E9A, 0x00003E21, 0x00050051, 0x0000000B, 0x000027F6, 0x00002AC1, + 0x00000001, 0x00060050, 0x00000014, 0x0000350F, 0x000027F6, 0x000027F6, 0x000027F6, 0x000500C2, + 0x00000014, 0x00002B10, 0x0000350F, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DE9, 0x00002B10, + 0x00000105, 0x000500C7, 0x00000014, 0x0000489F, 0x00005DE9, 0x00000466, 0x000500C2, 0x00000014, + 0x00005B93, 0x00005DE9, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CC, 0x00005B93, 0x00000A12, + 0x0006000C, 0x00000016, 0x00002C4E, 0x00000001, 0x0000004B, 0x0000489F, 0x0004007C, 0x00000014, + 0x00002A18, 0x00002C4E, 0x00050082, 0x00000014, 0x0000187D, 0x00000B0C, 0x00002A18, 0x00050080, + 0x00000014, 0x00002213, 0x00002A18, 0x00000938, 0x000600A9, 0x00000014, 0x00002872, 0x000040CC, + 0x00002213, 0x00005B93, 0x000500C4, 0x00000014, 0x00005AD7, 0x0000489F, 0x0000187D, 0x000500C7, + 0x00000014, 0x0000499D, 0x00005AD7, 0x00000466, 0x000600A9, 0x00000014, 0x00002AA0, 0x000040CC, + 0x0000499D, 0x0000489F, 0x00050080, 0x00000014, 0x00005FFC, 0x00002872, 0x000003FA, 0x000500C4, + 0x00000014, 0x00004F82, 0x00005FFC, 0x00000189, 0x000500C4, 0x00000014, 0x00003FA9, 0x00002AA0, + 0x0000008D, 0x000500C5, 0x00000014, 0x0000577F, 0x00004F82, 0x00003FA9, 0x000500AA, 0x00000010, + 0x00003603, 0x00005DE9, 0x00000A12, 0x000600A9, 0x00000014, 0x00004245, 0x00003603, 0x00000A12, + 0x0000577F, 0x0004007C, 0x00000018, 0x000029D2, 0x00004245, 0x000500C2, 0x0000000B, 0x00004BA7, + 0x000027F6, 0x00000A64, 0x00040070, 0x0000000D, 0x00004811, 0x00004BA7, 0x00050085, 0x0000000D, + 0x00003E22, 0x00004811, 0x00000149, 0x00050051, 0x0000000D, 0x000053C5, 0x000029D2, 0x00000000, + 0x00050051, 0x0000000D, 0x00002A58, 0x000029D2, 0x00000001, 0x00050051, 0x0000000D, 0x00002B12, + 0x000029D2, 0x00000002, 0x00070050, 0x0000001D, 0x00002350, 0x000053C5, 0x00002A58, 0x00002B12, + 0x00003E22, 0x000200F9, 0x00003F61, 0x000200F8, 0x00001CBD, 0x00050051, 0x0000000B, 0x000056C1, + 0x00002AC1, 0x00000000, 0x00070050, 0x00000017, 0x00004F0E, 0x000056C1, 0x000056C1, 0x000056C1, + 0x000056C1, 0x000500C2, 0x00000017, 0x0000249C, 0x00004F0E, 0x0000034D, 0x000500C7, 0x00000017, + 0x000049AD, 0x0000249C, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CB8, 0x000049AD, 0x00050085, + 0x0000001D, 0x00004131, 0x00003CB8, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD3, 0x00002AC1, + 0x00000001, 0x00070050, 0x00000017, 0x0000514E, 0x00005CD3, 0x00005CD3, 0x00005CD3, 0x00005CD3, + 0x000500C2, 0x00000017, 0x0000249D, 0x0000514E, 0x0000034D, 0x000500C7, 0x00000017, 0x000049AE, + 0x0000249D, 0x0000027B, 0x00040070, 0x0000001D, 0x00004930, 0x000049AE, 0x00050085, 0x0000001D, + 0x000026A0, 0x00004930, 0x00000AEE, 0x000200F9, 0x00003F61, 0x000200F8, 0x000038FA, 0x00050051, + 0x0000000B, 0x000056C2, 0x00002AC1, 0x00000000, 0x00070050, 0x00000017, 0x00004F0F, 0x000056C2, + 0x000056C2, 0x000056C2, 0x000056C2, 0x000500C2, 0x00000017, 0x0000249E, 0x00004F0F, 0x0000028D, + 0x000500C7, 0x00000017, 0x00004A58, 0x0000249E, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A3, + 0x00004A58, 0x0005008E, 0x0000001D, 0x00004B24, 0x000036A3, 0x0000017A, 0x00050051, 0x0000000B, + 0x000021A0, 0x00002AC1, 0x00000001, 0x00070050, 0x00000017, 0x0000610C, 0x000021A0, 0x000021A0, + 0x000021A0, 0x000021A0, 0x000500C2, 0x00000017, 0x0000249F, 0x0000610C, 0x0000028D, 0x000500C7, + 0x00000017, 0x00004A59, 0x0000249F, 0x0000064B, 0x00040070, 0x0000001D, 0x0000431B, 0x00004A59, + 0x0005008E, 0x0000001D, 0x00003093, 0x0000431B, 0x0000017A, 0x000200F9, 0x00003F61, 0x000200F8, + 0x00004BFC, 0x00050051, 0x0000000B, 0x0000308E, 0x00002AC1, 0x00000000, 0x0004007C, 0x0000000D, + 0x00004FEF, 0x0000308E, 0x00050050, 0x00000013, 0x00004337, 0x00004FEF, 0x00000A0C, 0x0009004F, + 0x0000001D, 0x00002D91, 0x00004337, 0x00004337, 0x00000000, 0x00000001, 0x00000001, 0x00000001, + 0x00050051, 0x0000000B, 0x000056B2, 0x00002AC1, 0x00000001, 0x0004007C, 0x0000000D, 0x00003F69, + 0x000056B2, 0x00050050, 0x00000013, 0x00004FAF, 0x00003F69, 0x00000A0C, 0x0009004F, 0x0000001D, + 0x00005A3B, 0x00004FAF, 0x00004FAF, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000200F9, + 0x00003F61, 0x000200F8, 0x00003F61, 0x000F00F5, 0x0000001D, 0x00002BF5, 0x00005A3B, 0x00004BFC, + 0x00003093, 0x000038FA, 0x000026A0, 0x00001CBD, 0x00002350, 0x00001CBC, 0x0000234F, 0x00001FFF, + 0x0000234E, 0x00002035, 0x000F00F5, 0x0000001D, 0x00003590, 0x00002D91, 0x00004BFC, 0x00004B24, + 0x000038FA, 0x00004131, 0x00001CBD, 0x00003DDB, 0x00001CBC, 0x0000411F, 0x00001FFF, 0x0000390E, + 0x00002035, 0x000200F9, 0x00005310, 0x000200F8, 0x00003B66, 0x000500AA, 0x00000009, 0x00005451, + 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F4C, 0x00000002, 0x000400FA, 0x00005451, 0x00002625, + 0x00002F64, 0x000200F8, 0x00002F64, 0x00060041, 0x00000288, 0x00004BD2, 0x00000CC7, 0x00000A0B, + 0x00005E78, 0x0004003D, 0x0000000B, 0x00005D49, 0x00004BD2, 0x00050080, 0x0000000B, 0x00002DB1, + 0x00005AD8, 0x00000AFD, 0x00060041, 0x00000288, 0x00001903, 0x00000CC7, 0x00000A0B, 0x00002DB1, + 0x0004003D, 0x0000000B, 0x00005C66, 0x00001903, 0x00050080, 0x0000000B, 0x00002DB2, 0x00005E78, + 0x0000199B, 0x00060041, 0x00000288, 0x00001904, 0x00000CC7, 0x00000A0B, 0x00002DB2, 0x0004003D, + 0x0000000B, 0x00005C67, 0x00001904, 0x00050080, 0x0000000B, 0x00002DB3, 0x00002DB2, 0x00000A0D, + 0x00060041, 0x00000288, 0x00005FF4, 0x00000CC7, 0x00000A0B, 0x00002DB3, 0x0004003D, 0x0000000B, + 0x00004001, 0x00005FF4, 0x00070050, 0x00000017, 0x00005132, 0x00005D49, 0x00005C66, 0x00005C67, + 0x00004001, 0x000200F9, 0x00004F4C, 0x000200F8, 0x00002625, 0x00060041, 0x00000288, 0x00005548, + 0x00000CC7, 0x00000A0B, 0x00005E78, 0x0004003D, 0x0000000B, 0x00005D4A, 0x00005548, 0x00050080, + 0x0000000B, 0x00002DB4, 0x00005AD8, 0x00000AFD, 0x00060041, 0x00000288, 0x00001905, 0x00000CC7, + 0x00000A0B, 0x00002DB4, 0x0004003D, 0x0000000B, 0x00005C68, 0x00001905, 0x00050080, 0x0000000B, + 0x00002DB5, 0x00005AD8, 0x00000B00, 0x00060041, 0x00000288, 0x00001906, 0x00000CC7, 0x00000A0B, + 0x00002DB5, 0x0004003D, 0x0000000B, 0x00005C69, 0x00001906, 0x00050080, 0x0000000B, 0x00002DB6, + 0x00005AD8, 0x00000B03, 0x00060041, 0x00000288, 0x00005FF5, 0x00000CC7, 0x00000A0B, 0x00002DB6, + 0x0004003D, 0x0000000B, 0x00004002, 0x00005FF5, 0x00070050, 0x00000017, 0x00005133, 0x00005D4A, + 0x00005C68, 0x00005C69, 0x00004002, 0x000200F9, 0x00004F4C, 0x000200F8, 0x00004F4C, 0x000700F5, + 0x00000017, 0x00002AC2, 0x00005133, 0x00002625, 0x00005132, 0x00002F64, 0x000300F7, 0x00004F24, + 0x00000000, 0x000700FB, 0x00002180, 0x00004F57, 0x00000005, 0x00002159, 0x00000007, 0x00002036, + 0x000200F8, 0x00002036, 0x00050051, 0x0000000B, 0x00005F59, 0x00002AC2, 0x00000000, 0x0006000C, + 0x00000013, 0x0000606A, 0x00000001, 0x0000003E, 0x00005F59, 0x00050051, 0x0000000D, 0x00002777, + 0x0000606A, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBA, 0x0000606A, 0x00000001, 0x00050051, + 0x0000000B, 0x00004283, 0x00002AC2, 0x00000001, 0x0006000C, 0x00000013, 0x00003CF7, 0x00000001, + 0x0000003E, 0x00004283, 0x00050051, 0x0000000D, 0x00002768, 0x00003CF7, 0x00000000, 0x00050051, + 0x0000000D, 0x00004449, 0x00003CF7, 0x00000001, 0x00070050, 0x0000001D, 0x0000390F, 0x00002777, + 0x00003EBA, 0x00002768, 0x00004449, 0x00050051, 0x0000000B, 0x0000437D, 0x00002AC2, 0x00000002, + 0x0006000C, 0x00000013, 0x0000466E, 0x00000001, 0x0000003E, 0x0000437D, 0x00050051, 0x0000000D, + 0x00002778, 0x0000466E, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBB, 0x0000466E, 0x00000001, + 0x00050051, 0x0000000B, 0x00004284, 0x00002AC2, 0x00000003, 0x0006000C, 0x00000013, 0x00003CF8, + 0x00000001, 0x0000003E, 0x00004284, 0x00050051, 0x0000000D, 0x00002769, 0x00003CF8, 0x00000000, + 0x00050051, 0x0000000D, 0x000050C1, 0x00003CF8, 0x00000001, 0x00070050, 0x0000001D, 0x00002351, + 0x00002778, 0x00003EBB, 0x00002769, 0x000050C1, 0x000200F9, 0x00004F24, 0x000200F8, 0x00002159, + 0x0007004F, 0x00000011, 0x000025FC, 0x00002AC2, 0x00002AC2, 0x00000000, 0x00000001, 0x0004007C, + 0x00000012, 0x00005B3D, 0x000025FC, 0x0009004F, 0x0000001A, 0x000060D0, 0x00005B3D, 0x00005B3D, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048A8, 0x000060D0, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D8F, 0x000048A8, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002AA1, 0x00003D8F, 0x0005008E, 0x0000001D, 0x00004722, 0x00002AA1, 0x000007FE, 0x0007000C, + 0x0000001D, 0x00006292, 0x00000001, 0x00000028, 0x00000504, 0x00004722, 0x0007004F, 0x00000011, + 0x0000376C, 0x00002AC2, 0x00002AC2, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C0, + 0x0000376C, 0x0009004F, 0x0000001A, 0x000060D1, 0x000024C0, 0x000024C0, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048A9, 0x000060D1, 0x00000122, 0x000500C3, + 0x0000001A, 0x00003D90, 0x000048A9, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA2, 0x00003D90, + 0x0005008E, 0x0000001D, 0x000053C0, 0x00002AA2, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004363, + 0x00000001, 0x00000028, 0x00000504, 0x000053C0, 0x000200F9, 0x00004F24, 0x000200F8, 0x00004F57, + 0x0007004F, 0x00000011, 0x00002626, 0x00002AC2, 0x00002AC2, 0x00000000, 0x00000001, 0x0004007C, + 0x00000013, 0x0000515A, 0x00002626, 0x00050051, 0x0000000D, 0x00001B7D, 0x0000515A, 0x00000000, + 0x00050051, 0x0000000D, 0x0000346B, 0x0000515A, 0x00000001, 0x00070050, 0x0000001D, 0x00004279, + 0x00001B7D, 0x0000346B, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041D9, 0x00002AC2, + 0x00002AC2, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x0000375E, 0x000041D9, 0x00050051, + 0x0000000D, 0x00001B7E, 0x0000375E, 0x00000000, 0x00050051, 0x0000000D, 0x00004109, 0x0000375E, + 0x00000001, 0x00070050, 0x0000001D, 0x00002352, 0x00001B7E, 0x00004109, 0x00000A0C, 0x00000A0C, + 0x000200F9, 0x00004F24, 0x000200F8, 0x00004F24, 0x000900F5, 0x0000001D, 0x00002BF6, 0x00002352, + 0x00004F57, 0x00004363, 0x00002159, 0x00002351, 0x00002036, 0x000900F5, 0x0000001D, 0x00003591, + 0x00004279, 0x00004F57, 0x00006292, 0x00002159, 0x0000390F, 0x00002036, 0x000200F9, 0x00005310, + 0x000200F8, 0x00005310, 0x000700F5, 0x0000001D, 0x0000230B, 0x00002BF6, 0x00004F24, 0x00002BF5, + 0x00003F61, 0x000700F5, 0x0000001D, 0x00004C8A, 0x00003591, 0x00004F24, 0x00003590, 0x00003F61, + 0x00050081, 0x0000001D, 0x000046B0, 0x000036E3, 0x00004C8A, 0x00050081, 0x0000001D, 0x0000455A, + 0x00002662, 0x0000230B, 0x000500AE, 0x00000009, 0x0000387D, 0x00003F4D, 0x00000A1C, 0x000300F7, + 0x00005EC8, 0x00000002, 0x000400FA, 0x0000387D, 0x000026B1, 0x00005EC8, 0x000200F8, 0x000026B1, + 0x000500C4, 0x0000000B, 0x000037B2, 0x00000A0D, 0x000023AA, 0x00050085, 0x0000000D, 0x00002F3A, + 0x00002B2C, 0x0000016E, 0x00050080, 0x0000000B, 0x000051FC, 0x00005AD8, 0x000037B2, 0x000300F7, + 0x00005311, 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B67, 0x000040BB, 0x000200F8, 0x000040BB, + 0x000500AA, 0x00000009, 0x00004ADD, 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F4D, 0x00000002, + 0x000400FA, 0x00004ADD, 0x00002627, 0x00002F65, 0x000200F8, 0x00002F65, 0x00060041, 0x00000288, + 0x00004BD3, 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, 0x00005D4B, 0x00004BD3, + 0x00050080, 0x0000000B, 0x00002DB7, 0x000051FC, 0x0000199B, 0x00060041, 0x00000288, 0x00005FF6, + 0x00000CC7, 0x00000A0B, 0x00002DB7, 0x0004003D, 0x0000000B, 0x00004003, 0x00005FF6, 0x00050050, + 0x00000011, 0x00005134, 0x00005D4B, 0x00004003, 0x000200F9, 0x00004F4D, 0x000200F8, 0x00002627, + 0x00060041, 0x00000288, 0x00005549, 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, + 0x00005D4C, 0x00005549, 0x00050080, 0x0000000B, 0x00002DB8, 0x000051FC, 0x00000A0D, 0x00060041, + 0x00000288, 0x00005FF7, 0x00000CC7, 0x00000A0B, 0x00002DB8, 0x0004003D, 0x0000000B, 0x00004004, + 0x00005FF7, 0x00050050, 0x00000011, 0x00005135, 0x00005D4C, 0x00004004, 0x000200F9, 0x00004F4D, + 0x000200F8, 0x00004F4D, 0x000700F5, 0x00000011, 0x00002AC3, 0x00005135, 0x00002627, 0x00005134, + 0x00002F65, 0x000300F7, 0x00003F62, 0x00000000, 0x001300FB, 0x00002180, 0x00004BFD, 0x00000000, + 0x000038FB, 0x00000001, 0x000038FB, 0x00000002, 0x00001CBF, 0x0000000A, 0x00001CBF, 0x00000003, + 0x00001CBE, 0x0000000C, 0x00001CBE, 0x00000004, 0x00002000, 0x00000006, 0x00002037, 0x000200F8, + 0x00002037, 0x00050051, 0x0000000B, 0x00005F5A, 0x00002AC3, 0x00000000, 0x0006000C, 0x00000013, + 0x0000606B, 0x00000001, 0x0000003E, 0x00005F5A, 0x00050051, 0x0000000D, 0x0000276A, 0x0000606B, + 0x00000000, 0x00050051, 0x0000000D, 0x0000444A, 0x0000606B, 0x00000001, 0x00070050, 0x0000001D, + 0x00003910, 0x0000276A, 0x0000444A, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x0000437E, + 0x00002AC3, 0x00000001, 0x0006000C, 0x00000013, 0x0000466F, 0x00000001, 0x0000003E, 0x0000437E, + 0x00050051, 0x0000000D, 0x0000276B, 0x0000466F, 0x00000000, 0x00050051, 0x0000000D, 0x000050C2, + 0x0000466F, 0x00000001, 0x00070050, 0x0000001D, 0x00002353, 0x0000276B, 0x000050C2, 0x00000A0C, + 0x00000A0C, 0x000200F9, 0x00003F62, 0x000200F8, 0x00002000, 0x00050051, 0x0000000B, 0x0000308F, + 0x00002AC3, 0x00000000, 0x0004007C, 0x0000000C, 0x0000589F, 0x0000308F, 0x00050050, 0x00000012, + 0x0000471E, 0x0000589F, 0x0000589F, 0x000500C4, 0x00000012, 0x000047B1, 0x0000471E, 0x000007A7, + 0x000500C3, 0x00000012, 0x0000341B, 0x000047B1, 0x00000867, 0x0004006F, 0x00000013, 0x00002AA3, + 0x0000341B, 0x0005008E, 0x00000013, 0x0000474B, 0x00002AA3, 0x000007FE, 0x0007000C, 0x00000013, + 0x00005E0A, 0x00000001, 0x00000028, 0x00000049, 0x0000474B, 0x00050051, 0x0000000D, 0x00005F0E, + 0x00005E0A, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD6, 0x00005E0A, 0x00000001, 0x00070050, + 0x0000001D, 0x00004120, 0x00005F0E, 0x00003CD6, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x00004C44, 0x00002AC3, 0x00000001, 0x0004007C, 0x0000000C, 0x00003EA3, 0x00004C44, 0x00050050, + 0x00000012, 0x0000471F, 0x00003EA3, 0x00003EA3, 0x000500C4, 0x00000012, 0x000047B2, 0x0000471F, + 0x000007A7, 0x000500C3, 0x00000012, 0x0000341C, 0x000047B2, 0x00000867, 0x0004006F, 0x00000013, + 0x00002AA4, 0x0000341C, 0x0005008E, 0x00000013, 0x0000474C, 0x00002AA4, 0x000007FE, 0x0007000C, + 0x00000013, 0x00005E0B, 0x00000001, 0x00000028, 0x00000049, 0x0000474C, 0x00050051, 0x0000000D, + 0x00005F0F, 0x00005E0B, 0x00000000, 0x00050051, 0x0000000D, 0x0000494E, 0x00005E0B, 0x00000001, + 0x00070050, 0x0000001D, 0x00002354, 0x00005F0F, 0x0000494E, 0x00000A0C, 0x00000A0C, 0x000200F9, + 0x00003F62, 0x000200F8, 0x00001CBE, 0x00050051, 0x0000000B, 0x000056C3, 0x00002AC3, 0x00000000, + 0x00060050, 0x00000014, 0x00004F10, 0x000056C3, 0x000056C3, 0x000056C3, 0x000500C2, 0x00000014, + 0x00002B13, 0x00004F10, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEA, 0x00002B13, 0x00000105, + 0x000500C7, 0x00000014, 0x000048A0, 0x00005DEA, 0x00000466, 0x000500C2, 0x00000014, 0x00005B94, + 0x00005DEA, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CD, 0x00005B94, 0x00000A12, 0x0006000C, + 0x00000016, 0x00002C4F, 0x00000001, 0x0000004B, 0x000048A0, 0x0004007C, 0x00000014, 0x00002A19, + 0x00002C4F, 0x00050082, 0x00000014, 0x0000187E, 0x00000B0C, 0x00002A19, 0x00050080, 0x00000014, + 0x00002214, 0x00002A19, 0x00000938, 0x000600A9, 0x00000014, 0x00002873, 0x000040CD, 0x00002214, + 0x00005B94, 0x000500C4, 0x00000014, 0x00005AD9, 0x000048A0, 0x0000187E, 0x000500C7, 0x00000014, + 0x0000499E, 0x00005AD9, 0x00000466, 0x000600A9, 0x00000014, 0x00002AA5, 0x000040CD, 0x0000499E, + 0x000048A0, 0x00050080, 0x00000014, 0x00005FFD, 0x00002873, 0x000003FA, 0x000500C4, 0x00000014, + 0x00004F83, 0x00005FFD, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAA, 0x00002AA5, 0x0000008D, + 0x000500C5, 0x00000014, 0x00005780, 0x00004F83, 0x00003FAA, 0x000500AA, 0x00000010, 0x00003604, + 0x00005DEA, 0x00000A12, 0x000600A9, 0x00000014, 0x00004246, 0x00003604, 0x00000A12, 0x00005780, + 0x0004007C, 0x00000018, 0x000029D3, 0x00004246, 0x000500C2, 0x0000000B, 0x00004BA8, 0x000056C3, + 0x00000A64, 0x00040070, 0x0000000D, 0x00004812, 0x00004BA8, 0x00050085, 0x0000000D, 0x00003E23, + 0x00004812, 0x00000149, 0x00050051, 0x0000000D, 0x000053C6, 0x000029D3, 0x00000000, 0x00050051, + 0x0000000D, 0x00002A59, 0x000029D3, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9B, 0x000029D3, + 0x00000002, 0x00070050, 0x0000001D, 0x00003DDC, 0x000053C6, 0x00002A59, 0x00001E9B, 0x00003E23, + 0x00050051, 0x0000000B, 0x000027F7, 0x00002AC3, 0x00000001, 0x00060050, 0x00000014, 0x00003510, + 0x000027F7, 0x000027F7, 0x000027F7, 0x000500C2, 0x00000014, 0x00002B14, 0x00003510, 0x00000BB4, + 0x000500C7, 0x00000014, 0x00005DEB, 0x00002B14, 0x00000105, 0x000500C7, 0x00000014, 0x000048A1, + 0x00005DEB, 0x00000466, 0x000500C2, 0x00000014, 0x00005B95, 0x00005DEB, 0x00000B0C, 0x000500AA, + 0x00000010, 0x000040CE, 0x00005B95, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C50, 0x00000001, + 0x0000004B, 0x000048A1, 0x0004007C, 0x00000014, 0x00002A1A, 0x00002C50, 0x00050082, 0x00000014, + 0x0000187F, 0x00000B0C, 0x00002A1A, 0x00050080, 0x00000014, 0x00002215, 0x00002A1A, 0x00000938, + 0x000600A9, 0x00000014, 0x00002874, 0x000040CE, 0x00002215, 0x00005B95, 0x000500C4, 0x00000014, + 0x00005ADA, 0x000048A1, 0x0000187F, 0x000500C7, 0x00000014, 0x0000499F, 0x00005ADA, 0x00000466, + 0x000600A9, 0x00000014, 0x00002AA6, 0x000040CE, 0x0000499F, 0x000048A1, 0x00050080, 0x00000014, + 0x00005FFE, 0x00002874, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F84, 0x00005FFE, 0x00000189, + 0x000500C4, 0x00000014, 0x00003FAB, 0x00002AA6, 0x0000008D, 0x000500C5, 0x00000014, 0x00005781, + 0x00004F84, 0x00003FAB, 0x000500AA, 0x00000010, 0x00003605, 0x00005DEB, 0x00000A12, 0x000600A9, + 0x00000014, 0x00004247, 0x00003605, 0x00000A12, 0x00005781, 0x0004007C, 0x00000018, 0x000029D4, + 0x00004247, 0x000500C2, 0x0000000B, 0x00004BA9, 0x000027F7, 0x00000A64, 0x00040070, 0x0000000D, + 0x00004813, 0x00004BA9, 0x00050085, 0x0000000D, 0x00003E24, 0x00004813, 0x00000149, 0x00050051, + 0x0000000D, 0x000053C7, 0x000029D4, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5A, 0x000029D4, + 0x00000001, 0x00050051, 0x0000000D, 0x00002B15, 0x000029D4, 0x00000002, 0x00070050, 0x0000001D, + 0x00002355, 0x000053C7, 0x00002A5A, 0x00002B15, 0x00003E24, 0x000200F9, 0x00003F62, 0x000200F8, + 0x00001CBF, 0x00050051, 0x0000000B, 0x000056C4, 0x00002AC3, 0x00000000, 0x00070050, 0x00000017, + 0x00004F11, 0x000056C4, 0x000056C4, 0x000056C4, 0x000056C4, 0x000500C2, 0x00000017, 0x000024A0, + 0x00004F11, 0x0000034D, 0x000500C7, 0x00000017, 0x000049AF, 0x000024A0, 0x0000027B, 0x00040070, + 0x0000001D, 0x00003CB9, 0x000049AF, 0x00050085, 0x0000001D, 0x00004132, 0x00003CB9, 0x00000AEE, + 0x00050051, 0x0000000B, 0x00005CD4, 0x00002AC3, 0x00000001, 0x00070050, 0x00000017, 0x0000514F, + 0x00005CD4, 0x00005CD4, 0x00005CD4, 0x00005CD4, 0x000500C2, 0x00000017, 0x000024A1, 0x0000514F, + 0x0000034D, 0x000500C7, 0x00000017, 0x000049B0, 0x000024A1, 0x0000027B, 0x00040070, 0x0000001D, + 0x00004931, 0x000049B0, 0x00050085, 0x0000001D, 0x000026A1, 0x00004931, 0x00000AEE, 0x000200F9, + 0x00003F62, 0x000200F8, 0x000038FB, 0x00050051, 0x0000000B, 0x000056C5, 0x00002AC3, 0x00000000, + 0x00070050, 0x00000017, 0x00004F12, 0x000056C5, 0x000056C5, 0x000056C5, 0x000056C5, 0x000500C2, + 0x00000017, 0x000024A2, 0x00004F12, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5A, 0x000024A2, + 0x0000064B, 0x00040070, 0x0000001D, 0x000036A4, 0x00004A5A, 0x0005008E, 0x0000001D, 0x00004B25, + 0x000036A4, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A1, 0x00002AC3, 0x00000001, 0x00070050, + 0x00000017, 0x0000610D, 0x000021A1, 0x000021A1, 0x000021A1, 0x000021A1, 0x000500C2, 0x00000017, + 0x000024A3, 0x0000610D, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5B, 0x000024A3, 0x0000064B, + 0x00040070, 0x0000001D, 0x0000431C, 0x00004A5B, 0x0005008E, 0x0000001D, 0x00003094, 0x0000431C, + 0x0000017A, 0x000200F9, 0x00003F62, 0x000200F8, 0x00004BFD, 0x00050051, 0x0000000B, 0x00003090, + 0x00002AC3, 0x00000000, 0x0004007C, 0x0000000D, 0x00004FF0, 0x00003090, 0x00050050, 0x00000013, + 0x00004338, 0x00004FF0, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D92, 0x00004338, 0x00004338, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B3, 0x00002AC3, + 0x00000001, 0x0004007C, 0x0000000D, 0x00003F6A, 0x000056B3, 0x00050050, 0x00000013, 0x00004FB0, + 0x00003F6A, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3C, 0x00004FB0, 0x00004FB0, 0x00000000, + 0x00000001, 0x00000001, 0x00000001, 0x000200F9, 0x00003F62, 0x000200F8, 0x00003F62, 0x000F00F5, + 0x0000001D, 0x00002BF7, 0x00005A3C, 0x00004BFD, 0x00003094, 0x000038FB, 0x000026A1, 0x00001CBF, + 0x00002355, 0x00001CBE, 0x00002354, 0x00002000, 0x00002353, 0x00002037, 0x000F00F5, 0x0000001D, + 0x00003592, 0x00002D92, 0x00004BFD, 0x00004B25, 0x000038FB, 0x00004132, 0x00001CBF, 0x00003DDC, + 0x00001CBE, 0x00004120, 0x00002000, 0x00003910, 0x00002037, 0x000200F9, 0x00005311, 0x000200F8, + 0x00003B67, 0x000500AA, 0x00000009, 0x00005452, 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F4E, + 0x00000002, 0x000400FA, 0x00005452, 0x00002628, 0x00002F66, 0x000200F8, 0x00002F66, 0x00060041, + 0x00000288, 0x00004BD4, 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, 0x00005D4D, + 0x00004BD4, 0x00050080, 0x0000000B, 0x00002DB9, 0x000051FC, 0x00000A0D, 0x00060041, 0x00000288, + 0x00001907, 0x00000CC7, 0x00000A0B, 0x00002DB9, 0x0004003D, 0x0000000B, 0x00005C6A, 0x00001907, + 0x00050080, 0x0000000B, 0x00002DBA, 0x000051FC, 0x0000199B, 0x00060041, 0x00000288, 0x00001908, + 0x00000CC7, 0x00000A0B, 0x00002DBA, 0x0004003D, 0x0000000B, 0x00005C6B, 0x00001908, 0x00050080, + 0x0000000B, 0x00002DBB, 0x00002DBA, 0x00000A0D, 0x00060041, 0x00000288, 0x00005FF8, 0x00000CC7, + 0x00000A0B, 0x00002DBB, 0x0004003D, 0x0000000B, 0x00004005, 0x00005FF8, 0x00070050, 0x00000017, + 0x00005136, 0x00005D4D, 0x00005C6A, 0x00005C6B, 0x00004005, 0x000200F9, 0x00004F4E, 0x000200F8, + 0x00002628, 0x00060041, 0x00000288, 0x0000554A, 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, + 0x0000000B, 0x00005D4E, 0x0000554A, 0x00050080, 0x0000000B, 0x00002DBC, 0x000051FC, 0x00000A0D, + 0x00060041, 0x00000288, 0x00001909, 0x00000CC7, 0x00000A0B, 0x00002DBC, 0x0004003D, 0x0000000B, + 0x00005C6C, 0x00001909, 0x00050080, 0x0000000B, 0x00002DBD, 0x000051FC, 0x00000A10, 0x00060041, + 0x00000288, 0x0000190A, 0x00000CC7, 0x00000A0B, 0x00002DBD, 0x0004003D, 0x0000000B, 0x00005C6D, + 0x0000190A, 0x00050080, 0x0000000B, 0x00002DBE, 0x000051FC, 0x00000A13, 0x00060041, 0x00000288, + 0x00005FFF, 0x00000CC7, 0x00000A0B, 0x00002DBE, 0x0004003D, 0x0000000B, 0x00004006, 0x00005FFF, + 0x00070050, 0x00000017, 0x00005137, 0x00005D4E, 0x00005C6C, 0x00005C6D, 0x00004006, 0x000200F9, + 0x00004F4E, 0x000200F8, 0x00004F4E, 0x000700F5, 0x00000017, 0x00002AC4, 0x00005137, 0x00002628, + 0x00005136, 0x00002F66, 0x000300F7, 0x00004F25, 0x00000000, 0x000700FB, 0x00002180, 0x00004F58, + 0x00000005, 0x0000215A, 0x00000007, 0x00002038, 0x000200F8, 0x00002038, 0x00050051, 0x0000000B, + 0x00005F5B, 0x00002AC4, 0x00000000, 0x0006000C, 0x00000013, 0x0000606C, 0x00000001, 0x0000003E, + 0x00005F5B, 0x00050051, 0x0000000D, 0x00002779, 0x0000606C, 0x00000000, 0x00050051, 0x0000000D, + 0x00003EBC, 0x0000606C, 0x00000001, 0x00050051, 0x0000000B, 0x00004285, 0x00002AC4, 0x00000001, + 0x0006000C, 0x00000013, 0x00003CF9, 0x00000001, 0x0000003E, 0x00004285, 0x00050051, 0x0000000D, + 0x0000276C, 0x00003CF9, 0x00000000, 0x00050051, 0x0000000D, 0x0000444B, 0x00003CF9, 0x00000001, + 0x00070050, 0x0000001D, 0x00003911, 0x00002779, 0x00003EBC, 0x0000276C, 0x0000444B, 0x00050051, + 0x0000000B, 0x0000437F, 0x00002AC4, 0x00000002, 0x0006000C, 0x00000013, 0x00004670, 0x00000001, + 0x0000003E, 0x0000437F, 0x00050051, 0x0000000D, 0x0000277A, 0x00004670, 0x00000000, 0x00050051, + 0x0000000D, 0x00003EBD, 0x00004670, 0x00000001, 0x00050051, 0x0000000B, 0x00004286, 0x00002AC4, + 0x00000003, 0x0006000C, 0x00000013, 0x00003CFA, 0x00000001, 0x0000003E, 0x00004286, 0x00050051, + 0x0000000D, 0x0000276D, 0x00003CFA, 0x00000000, 0x00050051, 0x0000000D, 0x000050C3, 0x00003CFA, + 0x00000001, 0x00070050, 0x0000001D, 0x00002356, 0x0000277A, 0x00003EBD, 0x0000276D, 0x000050C3, + 0x000200F9, 0x00004F25, 0x000200F8, 0x0000215A, 0x0007004F, 0x00000011, 0x000025FD, 0x00002AC4, + 0x00002AC4, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x00005B3E, 0x000025FD, 0x0009004F, + 0x0000001A, 0x000060D2, 0x00005B3E, 0x00005B3E, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C4, 0x0000001A, 0x000048AA, 0x000060D2, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D91, + 0x000048AA, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA7, 0x00003D91, 0x0005008E, 0x0000001D, + 0x00004723, 0x00002AA7, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006293, 0x00000001, 0x00000028, + 0x00000504, 0x00004723, 0x0007004F, 0x00000011, 0x0000376D, 0x00002AC4, 0x00002AC4, 0x00000002, + 0x00000003, 0x0004007C, 0x00000012, 0x000024C1, 0x0000376D, 0x0009004F, 0x0000001A, 0x000060D3, + 0x000024C1, 0x000024C1, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, + 0x000048AB, 0x000060D3, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D92, 0x000048AB, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002AA8, 0x00003D92, 0x0005008E, 0x0000001D, 0x000053C1, 0x00002AA8, + 0x000007FE, 0x0007000C, 0x0000001D, 0x00004364, 0x00000001, 0x00000028, 0x00000504, 0x000053C1, + 0x000200F9, 0x00004F25, 0x000200F8, 0x00004F58, 0x0007004F, 0x00000011, 0x00002629, 0x00002AC4, + 0x00002AC4, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x0000515B, 0x00002629, 0x00050051, + 0x0000000D, 0x00001B7F, 0x0000515B, 0x00000000, 0x00050051, 0x0000000D, 0x0000346C, 0x0000515B, + 0x00000001, 0x00070050, 0x0000001D, 0x0000427A, 0x00001B7F, 0x0000346C, 0x00000A0C, 0x00000A0C, + 0x0007004F, 0x00000011, 0x000041DA, 0x00002AC4, 0x00002AC4, 0x00000002, 0x00000003, 0x0004007C, + 0x00000013, 0x0000375F, 0x000041DA, 0x00050051, 0x0000000D, 0x00001B80, 0x0000375F, 0x00000000, + 0x00050051, 0x0000000D, 0x0000410A, 0x0000375F, 0x00000001, 0x00070050, 0x0000001D, 0x00002357, + 0x00001B80, 0x0000410A, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F25, 0x000200F8, 0x00004F25, + 0x000900F5, 0x0000001D, 0x00002BF8, 0x00002357, 0x00004F58, 0x00004364, 0x0000215A, 0x00002356, + 0x00002038, 0x000900F5, 0x0000001D, 0x00003593, 0x0000427A, 0x00004F58, 0x00006293, 0x0000215A, + 0x00003911, 0x00002038, 0x000200F9, 0x00005311, 0x000200F8, 0x00005311, 0x000700F5, 0x0000001D, + 0x0000230C, 0x00002BF8, 0x00004F25, 0x00002BF7, 0x00003F62, 0x000700F5, 0x0000001D, 0x00004C8B, + 0x00003593, 0x00004F25, 0x00003592, 0x00003F62, 0x00050081, 0x0000001D, 0x00004346, 0x000046B0, + 0x00004C8B, 0x00050081, 0x0000001D, 0x000019F1, 0x0000455A, 0x0000230C, 0x00050080, 0x0000000B, + 0x00003FF8, 0x00005E78, 0x000037B2, 0x000300F7, 0x00005312, 0x00000002, 0x000400FA, 0x00005AEF, + 0x00003B68, 0x000040BC, 0x000200F8, 0x000040BC, 0x000500AA, 0x00000009, 0x00004ADE, 0x0000199B, + 0x00000A0D, 0x000300F7, 0x00004F4F, 0x00000002, 0x000400FA, 0x00004ADE, 0x0000262A, 0x00002F67, + 0x000200F8, 0x00002F67, 0x00060041, 0x00000288, 0x00004BD5, 0x00000CC7, 0x00000A0B, 0x00003FF8, + 0x0004003D, 0x0000000B, 0x00005D4F, 0x00004BD5, 0x00050080, 0x0000000B, 0x00002DBF, 0x00003FF8, + 0x0000199B, 0x00060041, 0x00000288, 0x00006000, 0x00000CC7, 0x00000A0B, 0x00002DBF, 0x0004003D, + 0x0000000B, 0x00004007, 0x00006000, 0x00050050, 0x00000011, 0x00005138, 0x00005D4F, 0x00004007, + 0x000200F9, 0x00004F4F, 0x000200F8, 0x0000262A, 0x00060041, 0x00000288, 0x0000554B, 0x00000CC7, + 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D50, 0x0000554B, 0x00050080, 0x0000000B, + 0x00002DC0, 0x00003FF8, 0x00000A0D, 0x00060041, 0x00000288, 0x00006001, 0x00000CC7, 0x00000A0B, + 0x00002DC0, 0x0004003D, 0x0000000B, 0x00004008, 0x00006001, 0x00050050, 0x00000011, 0x00005139, + 0x00005D50, 0x00004008, 0x000200F9, 0x00004F4F, 0x000200F8, 0x00004F4F, 0x000700F5, 0x00000011, + 0x00002AC5, 0x00005139, 0x0000262A, 0x00005138, 0x00002F67, 0x000300F7, 0x00003F63, 0x00000000, + 0x001300FB, 0x00002180, 0x00004BFE, 0x00000000, 0x000038FC, 0x00000001, 0x000038FC, 0x00000002, + 0x00001CC1, 0x0000000A, 0x00001CC1, 0x00000003, 0x00001CC0, 0x0000000C, 0x00001CC0, 0x00000004, + 0x00002001, 0x00000006, 0x00002039, 0x000200F8, 0x00002039, 0x00050051, 0x0000000B, 0x00005F5C, + 0x00002AC5, 0x00000000, 0x0006000C, 0x00000013, 0x0000606D, 0x00000001, 0x0000003E, 0x00005F5C, + 0x00050051, 0x0000000D, 0x0000276E, 0x0000606D, 0x00000000, 0x00050051, 0x0000000D, 0x0000444C, + 0x0000606D, 0x00000001, 0x00070050, 0x0000001D, 0x00003912, 0x0000276E, 0x0000444C, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x00004380, 0x00002AC5, 0x00000001, 0x0006000C, 0x00000013, + 0x00004671, 0x00000001, 0x0000003E, 0x00004380, 0x00050051, 0x0000000D, 0x0000276F, 0x00004671, + 0x00000000, 0x00050051, 0x0000000D, 0x000050C4, 0x00004671, 0x00000001, 0x00070050, 0x0000001D, + 0x00002358, 0x0000276F, 0x000050C4, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F63, 0x000200F8, + 0x00002001, 0x00050051, 0x0000000B, 0x00003091, 0x00002AC5, 0x00000000, 0x0004007C, 0x0000000C, + 0x000058A0, 0x00003091, 0x00050050, 0x00000012, 0x00004720, 0x000058A0, 0x000058A0, 0x000500C4, + 0x00000012, 0x000047B3, 0x00004720, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341D, 0x000047B3, + 0x00000867, 0x0004006F, 0x00000013, 0x00002AA9, 0x0000341D, 0x0005008E, 0x00000013, 0x0000474D, + 0x00002AA9, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0C, 0x00000001, 0x00000028, 0x00000049, + 0x0000474D, 0x00050051, 0x0000000D, 0x00005F10, 0x00005E0C, 0x00000000, 0x00050051, 0x0000000D, + 0x00003CD7, 0x00005E0C, 0x00000001, 0x00070050, 0x0000001D, 0x00004121, 0x00005F10, 0x00003CD7, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C45, 0x00002AC5, 0x00000001, 0x0004007C, + 0x0000000C, 0x00003EA4, 0x00004C45, 0x00050050, 0x00000012, 0x00004724, 0x00003EA4, 0x00003EA4, + 0x000500C4, 0x00000012, 0x000047B4, 0x00004724, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341E, + 0x000047B4, 0x00000867, 0x0004006F, 0x00000013, 0x00002AAA, 0x0000341E, 0x0005008E, 0x00000013, + 0x0000474E, 0x00002AAA, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0D, 0x00000001, 0x00000028, + 0x00000049, 0x0000474E, 0x00050051, 0x0000000D, 0x00005F11, 0x00005E0D, 0x00000000, 0x00050051, + 0x0000000D, 0x0000494F, 0x00005E0D, 0x00000001, 0x00070050, 0x0000001D, 0x00002359, 0x00005F11, + 0x0000494F, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F63, 0x000200F8, 0x00001CC0, 0x00050051, + 0x0000000B, 0x000056C6, 0x00002AC5, 0x00000000, 0x00060050, 0x00000014, 0x00004F13, 0x000056C6, + 0x000056C6, 0x000056C6, 0x000500C2, 0x00000014, 0x00002B16, 0x00004F13, 0x00000BB4, 0x000500C7, + 0x00000014, 0x00005DEC, 0x00002B16, 0x00000105, 0x000500C7, 0x00000014, 0x000048A2, 0x00005DEC, + 0x00000466, 0x000500C2, 0x00000014, 0x00005B96, 0x00005DEC, 0x00000B0C, 0x000500AA, 0x00000010, + 0x000040CF, 0x00005B96, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C51, 0x00000001, 0x0000004B, + 0x000048A2, 0x0004007C, 0x00000014, 0x00002A1B, 0x00002C51, 0x00050082, 0x00000014, 0x00001880, + 0x00000B0C, 0x00002A1B, 0x00050080, 0x00000014, 0x00002216, 0x00002A1B, 0x00000938, 0x000600A9, + 0x00000014, 0x00002875, 0x000040CF, 0x00002216, 0x00005B96, 0x000500C4, 0x00000014, 0x00005ADB, + 0x000048A2, 0x00001880, 0x000500C7, 0x00000014, 0x000049A0, 0x00005ADB, 0x00000466, 0x000600A9, + 0x00000014, 0x00002AAB, 0x000040CF, 0x000049A0, 0x000048A2, 0x00050080, 0x00000014, 0x00006002, + 0x00002875, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F85, 0x00006002, 0x00000189, 0x000500C4, + 0x00000014, 0x00003FAC, 0x00002AAB, 0x0000008D, 0x000500C5, 0x00000014, 0x00005782, 0x00004F85, + 0x00003FAC, 0x000500AA, 0x00000010, 0x00003606, 0x00005DEC, 0x00000A12, 0x000600A9, 0x00000014, + 0x00004248, 0x00003606, 0x00000A12, 0x00005782, 0x0004007C, 0x00000018, 0x000029D5, 0x00004248, + 0x000500C2, 0x0000000B, 0x00004BAA, 0x000056C6, 0x00000A64, 0x00040070, 0x0000000D, 0x00004814, + 0x00004BAA, 0x00050085, 0x0000000D, 0x00003E25, 0x00004814, 0x00000149, 0x00050051, 0x0000000D, + 0x000053C8, 0x000029D5, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5B, 0x000029D5, 0x00000001, + 0x00050051, 0x0000000D, 0x00001E9C, 0x000029D5, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDD, + 0x000053C8, 0x00002A5B, 0x00001E9C, 0x00003E25, 0x00050051, 0x0000000B, 0x000027F8, 0x00002AC5, + 0x00000001, 0x00060050, 0x00000014, 0x00003511, 0x000027F8, 0x000027F8, 0x000027F8, 0x000500C2, + 0x00000014, 0x00002B17, 0x00003511, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DED, 0x00002B17, + 0x00000105, 0x000500C7, 0x00000014, 0x000048A3, 0x00005DED, 0x00000466, 0x000500C2, 0x00000014, + 0x00005B97, 0x00005DED, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D0, 0x00005B97, 0x00000A12, + 0x0006000C, 0x00000016, 0x00002C52, 0x00000001, 0x0000004B, 0x000048A3, 0x0004007C, 0x00000014, + 0x00002A1C, 0x00002C52, 0x00050082, 0x00000014, 0x00001881, 0x00000B0C, 0x00002A1C, 0x00050080, + 0x00000014, 0x00002217, 0x00002A1C, 0x00000938, 0x000600A9, 0x00000014, 0x00002876, 0x000040D0, + 0x00002217, 0x00005B97, 0x000500C4, 0x00000014, 0x00005ADC, 0x000048A3, 0x00001881, 0x000500C7, + 0x00000014, 0x000049A1, 0x00005ADC, 0x00000466, 0x000600A9, 0x00000014, 0x00002AAC, 0x000040D0, + 0x000049A1, 0x000048A3, 0x00050080, 0x00000014, 0x00006003, 0x00002876, 0x000003FA, 0x000500C4, + 0x00000014, 0x00004F86, 0x00006003, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAD, 0x00002AAC, + 0x0000008D, 0x000500C5, 0x00000014, 0x00005783, 0x00004F86, 0x00003FAD, 0x000500AA, 0x00000010, + 0x00003607, 0x00005DED, 0x00000A12, 0x000600A9, 0x00000014, 0x00004249, 0x00003607, 0x00000A12, + 0x00005783, 0x0004007C, 0x00000018, 0x000029D6, 0x00004249, 0x000500C2, 0x0000000B, 0x00004BAB, + 0x000027F8, 0x00000A64, 0x00040070, 0x0000000D, 0x00004815, 0x00004BAB, 0x00050085, 0x0000000D, + 0x00003E26, 0x00004815, 0x00000149, 0x00050051, 0x0000000D, 0x000053C9, 0x000029D6, 0x00000000, + 0x00050051, 0x0000000D, 0x00002A5C, 0x000029D6, 0x00000001, 0x00050051, 0x0000000D, 0x00002B18, + 0x000029D6, 0x00000002, 0x00070050, 0x0000001D, 0x0000235A, 0x000053C9, 0x00002A5C, 0x00002B18, + 0x00003E26, 0x000200F9, 0x00003F63, 0x000200F8, 0x00001CC1, 0x00050051, 0x0000000B, 0x000056C7, + 0x00002AC5, 0x00000000, 0x00070050, 0x00000017, 0x00004F14, 0x000056C7, 0x000056C7, 0x000056C7, + 0x000056C7, 0x000500C2, 0x00000017, 0x000024A4, 0x00004F14, 0x0000034D, 0x000500C7, 0x00000017, + 0x000049B1, 0x000024A4, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBA, 0x000049B1, 0x00050085, + 0x0000001D, 0x00004133, 0x00003CBA, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD5, 0x00002AC5, + 0x00000001, 0x00070050, 0x00000017, 0x00005150, 0x00005CD5, 0x00005CD5, 0x00005CD5, 0x00005CD5, + 0x000500C2, 0x00000017, 0x000024A5, 0x00005150, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B2, + 0x000024A5, 0x0000027B, 0x00040070, 0x0000001D, 0x00004932, 0x000049B2, 0x00050085, 0x0000001D, + 0x000026A2, 0x00004932, 0x00000AEE, 0x000200F9, 0x00003F63, 0x000200F8, 0x000038FC, 0x00050051, + 0x0000000B, 0x000056C8, 0x00002AC5, 0x00000000, 0x00070050, 0x00000017, 0x00004F15, 0x000056C8, + 0x000056C8, 0x000056C8, 0x000056C8, 0x000500C2, 0x00000017, 0x000024A6, 0x00004F15, 0x0000028D, + 0x000500C7, 0x00000017, 0x00004A5C, 0x000024A6, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A5, + 0x00004A5C, 0x0005008E, 0x0000001D, 0x00004B26, 0x000036A5, 0x0000017A, 0x00050051, 0x0000000B, + 0x000021A2, 0x00002AC5, 0x00000001, 0x00070050, 0x00000017, 0x0000610E, 0x000021A2, 0x000021A2, + 0x000021A2, 0x000021A2, 0x000500C2, 0x00000017, 0x000024A7, 0x0000610E, 0x0000028D, 0x000500C7, + 0x00000017, 0x00004A5D, 0x000024A7, 0x0000064B, 0x00040070, 0x0000001D, 0x0000431D, 0x00004A5D, + 0x0005008E, 0x0000001D, 0x00003095, 0x0000431D, 0x0000017A, 0x000200F9, 0x00003F63, 0x000200F8, + 0x00004BFE, 0x00050051, 0x0000000B, 0x00003096, 0x00002AC5, 0x00000000, 0x0004007C, 0x0000000D, + 0x00004FF1, 0x00003096, 0x00050050, 0x00000013, 0x00004339, 0x00004FF1, 0x00000A0C, 0x0009004F, + 0x0000001D, 0x00002D93, 0x00004339, 0x00004339, 0x00000000, 0x00000001, 0x00000001, 0x00000001, + 0x00050051, 0x0000000B, 0x000056B4, 0x00002AC5, 0x00000001, 0x0004007C, 0x0000000D, 0x00003F6B, + 0x000056B4, 0x00050050, 0x00000013, 0x00004FB1, 0x00003F6B, 0x00000A0C, 0x0009004F, 0x0000001D, + 0x00005A3D, 0x00004FB1, 0x00004FB1, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000200F9, + 0x00003F63, 0x000200F8, 0x00003F63, 0x000F00F5, 0x0000001D, 0x00002BF9, 0x00005A3D, 0x00004BFE, + 0x00003095, 0x000038FC, 0x000026A2, 0x00001CC1, 0x0000235A, 0x00001CC0, 0x00002359, 0x00002001, + 0x00002358, 0x00002039, 0x000F00F5, 0x0000001D, 0x00003594, 0x00002D93, 0x00004BFE, 0x00004B26, + 0x000038FC, 0x00004133, 0x00001CC1, 0x00003DDD, 0x00001CC0, 0x00004121, 0x00002001, 0x00003912, + 0x00002039, 0x000200F9, 0x00005312, 0x000200F8, 0x00003B68, 0x000500AA, 0x00000009, 0x00005453, + 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F50, 0x00000002, 0x000400FA, 0x00005453, 0x0000262B, + 0x00002F68, 0x000200F8, 0x00002F68, 0x00060041, 0x00000288, 0x00004BD6, 0x00000CC7, 0x00000A0B, + 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D51, 0x00004BD6, 0x00050080, 0x0000000B, 0x00002DC1, + 0x00003FF8, 0x00000A0D, 0x00060041, 0x00000288, 0x0000190B, 0x00000CC7, 0x00000A0B, 0x00002DC1, + 0x0004003D, 0x0000000B, 0x00005C6E, 0x0000190B, 0x00050080, 0x0000000B, 0x00002DC2, 0x00003FF8, + 0x0000199B, 0x00060041, 0x00000288, 0x0000190C, 0x00000CC7, 0x00000A0B, 0x00002DC2, 0x0004003D, + 0x0000000B, 0x00005C6F, 0x0000190C, 0x00050080, 0x0000000B, 0x00002DC3, 0x00002DC2, 0x00000A0D, + 0x00060041, 0x00000288, 0x00006004, 0x00000CC7, 0x00000A0B, 0x00002DC3, 0x0004003D, 0x0000000B, + 0x00004009, 0x00006004, 0x00070050, 0x00000017, 0x0000513A, 0x00005D51, 0x00005C6E, 0x00005C6F, + 0x00004009, 0x000200F9, 0x00004F50, 0x000200F8, 0x0000262B, 0x00060041, 0x00000288, 0x0000554C, + 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D52, 0x0000554C, 0x00050080, + 0x0000000B, 0x00002DC4, 0x00003FF8, 0x00000A0D, 0x00060041, 0x00000288, 0x0000190D, 0x00000CC7, + 0x00000A0B, 0x00002DC4, 0x0004003D, 0x0000000B, 0x00005C70, 0x0000190D, 0x00050080, 0x0000000B, + 0x00002DC5, 0x00003FF8, 0x00000A10, 0x00060041, 0x00000288, 0x0000190E, 0x00000CC7, 0x00000A0B, + 0x00002DC5, 0x0004003D, 0x0000000B, 0x00005C71, 0x0000190E, 0x00050080, 0x0000000B, 0x00002DC6, + 0x00003FF8, 0x00000A13, 0x00060041, 0x00000288, 0x00006005, 0x00000CC7, 0x00000A0B, 0x00002DC6, + 0x0004003D, 0x0000000B, 0x0000400A, 0x00006005, 0x00070050, 0x00000017, 0x0000513B, 0x00005D52, + 0x00005C70, 0x00005C71, 0x0000400A, 0x000200F9, 0x00004F50, 0x000200F8, 0x00004F50, 0x000700F5, + 0x00000017, 0x00002AC6, 0x0000513B, 0x0000262B, 0x0000513A, 0x00002F68, 0x000300F7, 0x00004F26, + 0x00000000, 0x000700FB, 0x00002180, 0x00004F59, 0x00000005, 0x0000215B, 0x00000007, 0x0000203A, + 0x000200F8, 0x0000203A, 0x00050051, 0x0000000B, 0x00005F5D, 0x00002AC6, 0x00000000, 0x0006000C, + 0x00000013, 0x0000606E, 0x00000001, 0x0000003E, 0x00005F5D, 0x00050051, 0x0000000D, 0x0000277B, + 0x0000606E, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBE, 0x0000606E, 0x00000001, 0x00050051, + 0x0000000B, 0x00004287, 0x00002AC6, 0x00000001, 0x0006000C, 0x00000013, 0x00003CFB, 0x00000001, + 0x0000003E, 0x00004287, 0x00050051, 0x0000000D, 0x00002770, 0x00003CFB, 0x00000000, 0x00050051, + 0x0000000D, 0x0000444D, 0x00003CFB, 0x00000001, 0x00070050, 0x0000001D, 0x00003913, 0x0000277B, + 0x00003EBE, 0x00002770, 0x0000444D, 0x00050051, 0x0000000B, 0x00004381, 0x00002AC6, 0x00000002, + 0x0006000C, 0x00000013, 0x00004672, 0x00000001, 0x0000003E, 0x00004381, 0x00050051, 0x0000000D, + 0x0000277C, 0x00004672, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBF, 0x00004672, 0x00000001, + 0x00050051, 0x0000000B, 0x00004288, 0x00002AC6, 0x00000003, 0x0006000C, 0x00000013, 0x00003CFC, + 0x00000001, 0x0000003E, 0x00004288, 0x00050051, 0x0000000D, 0x00002771, 0x00003CFC, 0x00000000, + 0x00050051, 0x0000000D, 0x000050C5, 0x00003CFC, 0x00000001, 0x00070050, 0x0000001D, 0x0000235B, + 0x0000277C, 0x00003EBF, 0x00002771, 0x000050C5, 0x000200F9, 0x00004F26, 0x000200F8, 0x0000215B, + 0x0007004F, 0x00000011, 0x000025FE, 0x00002AC6, 0x00002AC6, 0x00000000, 0x00000001, 0x0004007C, + 0x00000012, 0x00005B3F, 0x000025FE, 0x0009004F, 0x0000001A, 0x000060D4, 0x00005B3F, 0x00005B3F, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048AC, 0x000060D4, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D93, 0x000048AC, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002AAD, 0x00003D93, 0x0005008E, 0x0000001D, 0x00004725, 0x00002AAD, 0x000007FE, 0x0007000C, + 0x0000001D, 0x00006294, 0x00000001, 0x00000028, 0x00000504, 0x00004725, 0x0007004F, 0x00000011, + 0x0000376E, 0x00002AC6, 0x00002AC6, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C2, + 0x0000376E, 0x0009004F, 0x0000001A, 0x000060D5, 0x000024C2, 0x000024C2, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048AD, 0x000060D5, 0x00000122, 0x000500C3, + 0x0000001A, 0x00003D94, 0x000048AD, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AAE, 0x00003D94, + 0x0005008E, 0x0000001D, 0x000053CA, 0x00002AAE, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004365, + 0x00000001, 0x00000028, 0x00000504, 0x000053CA, 0x000200F9, 0x00004F26, 0x000200F8, 0x00004F59, + 0x0007004F, 0x00000011, 0x0000262C, 0x00002AC6, 0x00002AC6, 0x00000000, 0x00000001, 0x0004007C, + 0x00000013, 0x0000515C, 0x0000262C, 0x00050051, 0x0000000D, 0x00001B81, 0x0000515C, 0x00000000, + 0x00050051, 0x0000000D, 0x0000346D, 0x0000515C, 0x00000001, 0x00070050, 0x0000001D, 0x0000427B, + 0x00001B81, 0x0000346D, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DB, 0x00002AC6, + 0x00002AC6, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x00003760, 0x000041DB, 0x00050051, + 0x0000000D, 0x00001B82, 0x00003760, 0x00000000, 0x00050051, 0x0000000D, 0x0000410B, 0x00003760, + 0x00000001, 0x00070050, 0x0000001D, 0x0000235C, 0x00001B82, 0x0000410B, 0x00000A0C, 0x00000A0C, + 0x000200F9, 0x00004F26, 0x000200F8, 0x00004F26, 0x000900F5, 0x0000001D, 0x00002BFA, 0x0000235C, + 0x00004F59, 0x00004365, 0x0000215B, 0x0000235B, 0x0000203A, 0x000900F5, 0x0000001D, 0x00003595, + 0x0000427B, 0x00004F59, 0x00006294, 0x0000215B, 0x00003913, 0x0000203A, 0x000200F9, 0x00005312, + 0x000200F8, 0x00005312, 0x000700F5, 0x0000001D, 0x0000230D, 0x00002BFA, 0x00004F26, 0x00002BF9, + 0x00003F63, 0x000700F5, 0x0000001D, 0x00004C8C, 0x00003595, 0x00004F26, 0x00003594, 0x00003F63, + 0x00050081, 0x0000001D, 0x00004C41, 0x00004346, 0x00004C8C, 0x00050081, 0x0000001D, 0x00005D3D, + 0x000019F1, 0x0000230D, 0x000200F9, 0x00005EC8, 0x000200F8, 0x00005EC8, 0x000700F5, 0x0000001D, + 0x00002BA7, 0x0000455A, 0x00005310, 0x00005D3D, 0x00005312, 0x000700F5, 0x0000001D, 0x00003854, + 0x000046B0, 0x00005310, 0x00004C41, 0x00005312, 0x000700F5, 0x0000000D, 0x000038B6, 0x000061FB, + 0x00005310, 0x00002F3A, 0x00005312, 0x000200F9, 0x00005313, 0x000200F8, 0x00005313, 0x000700F5, + 0x0000001D, 0x00002BA8, 0x00002662, 0x0000530F, 0x00002BA7, 0x00005EC8, 0x000700F5, 0x0000001D, + 0x00003063, 0x000036E3, 0x0000530F, 0x00003854, 0x00005EC8, 0x000700F5, 0x0000000D, 0x00002EA8, + 0x00002B2C, 0x0000530F, 0x000038B6, 0x00005EC8, 0x0005008E, 0x0000001D, 0x0000623F, 0x00003063, + 0x00002EA8, 0x0005008E, 0x0000001D, 0x0000255A, 0x00002BA8, 0x00002EA8, 0x000300F7, 0x00003F64, + 0x00000002, 0x000400FA, 0x00001D59, 0x00002741, 0x00003F64, 0x000200F8, 0x00002741, 0x0009004F, + 0x0000001D, 0x0000478C, 0x0000623F, 0x0000623F, 0x00000002, 0x00000001, 0x00000000, 0x00000003, + 0x0009004F, 0x0000001D, 0x00004F75, 0x0000255A, 0x0000255A, 0x00000002, 0x00000001, 0x00000000, + 0x00000003, 0x000200F9, 0x00003F64, 0x000200F8, 0x00003F64, 0x000700F5, 0x0000001D, 0x000022F8, + 0x0000255A, 0x00005313, 0x00004F75, 0x00002741, 0x000700F5, 0x0000001D, 0x000055F9, 0x0000623F, + 0x00005313, 0x0000478C, 0x00002741, 0x00050080, 0x00000011, 0x00001C97, 0x00002EF9, 0x000059EC, + 0x000300F7, 0x000052F5, 0x00000002, 0x000400FA, 0x0000500F, 0x0000294E, 0x0000537D, 0x000200F8, + 0x0000537D, 0x0004007C, 0x00000012, 0x00002970, 0x00001C97, 0x00050051, 0x0000000C, 0x000042C2, + 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, + 0x0000000C, 0x00002747, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, + 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, + 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AA, 0x00050080, + 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, + 0x00000A2B, 0x000500C7, 0x0000000C, 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003138, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454D, 0x000500C4, 0x0000000C, 0x000018E7, + 0x00004397, 0x00000A16, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, + 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00004A8E, + 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, + 0x00004D30, 0x00003C4B, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002747, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544A, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004157, + 0x00004D30, 0x0000544A, 0x000500C7, 0x0000000C, 0x00005022, 0x00004157, 0x0000040B, 0x000500C4, + 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, + 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, + 0x00004158, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004157, 0x00000388, + 0x000500C4, 0x0000000C, 0x0000544B, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, + 0x00004158, 0x0000544B, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, + 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, + 0x00005454, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544C, 0x00005454, 0x00000A1D, + 0x00050080, 0x0000000C, 0x00003C4C, 0x00004144, 0x0000544C, 0x000500C7, 0x0000000C, 0x00002E06, + 0x00004157, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4C, 0x00002E06, 0x0004007C, + 0x0000000B, 0x0000566F, 0x0000394F, 0x000200F9, 0x000052F5, 0x000200F8, 0x0000294E, 0x00050051, + 0x0000000B, 0x00004D9A, 0x00001C97, 0x00000000, 0x00050051, 0x0000000B, 0x00002C03, 0x00001C97, + 0x00000001, 0x00060050, 0x00000014, 0x000020DE, 0x00004D9A, 0x00002C03, 0x00004408, 0x0004007C, + 0x00000016, 0x00004E9D, 0x000020DE, 0x00050051, 0x0000000C, 0x000028C6, 0x00004E9D, 0x00000001, + 0x000500C3, 0x0000000C, 0x000024FE, 0x000028C6, 0x00000A17, 0x00050051, 0x0000000C, 0x00002748, + 0x00004E9D, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A11, 0x000500C2, + 0x0000000B, 0x00005B4E, 0x00006273, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, + 0x00050084, 0x0000000C, 0x00005321, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003B27, + 0x000024FE, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00003DA7, 0x00000A19, 0x0004007C, + 0x0000000C, 0x00003097, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x00003097, + 0x00050051, 0x0000000C, 0x00006242, 0x00004E9D, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, + 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, + 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A28, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, + 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, + 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x000028C6, 0x00000A1D, + 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, + 0x00004D38, 0x0000454E, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A28, 0x000500C3, + 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002218, 0x000028C6, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002218, 0x0000405D, 0x000500C7, 0x0000000C, + 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, + 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004AE0, 0x000034BD, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544D, 0x00004AE0, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4D, 0x00005A0C, + 0x0000544D, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, + 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B32, 0x00004F70, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, + 0x00005B32, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B6, 0x00002748, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544E, 0x000047B6, 0x00000A28, 0x00050080, 0x0000000C, 0x00004159, 0x0000285C, + 0x0000544E, 0x000500C7, 0x0000000C, 0x00004AE1, 0x000028C6, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544F, 0x00004AE1, 0x00000A17, 0x00050080, 0x0000000C, 0x0000415A, 0x00004159, 0x0000544F, + 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4D, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, + 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x0000415A, 0x00000A1D, 0x000500C7, + 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, + 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B33, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005AB1, 0x00003C4D, 0x00000A05, 0x00050080, 0x0000000C, 0x00002AAF, 0x00005B33, 0x00005AB1, + 0x000500C4, 0x0000000C, 0x00005B34, 0x00002AAF, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, + 0x0000415A, 0x0000040B, 0x00050080, 0x0000000C, 0x00002AB0, 0x00005B34, 0x00005AB2, 0x000500C4, + 0x0000000C, 0x00005B35, 0x00002AB0, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x0000415A, + 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B35, 0x00005559, 0x0004007C, 0x0000000B, + 0x00005670, 0x00005EFA, 0x000200F9, 0x000052F5, 0x000200F8, 0x000052F5, 0x000700F5, 0x0000000B, + 0x00002C70, 0x00005670, 0x0000294E, 0x0000566F, 0x0000537D, 0x00050080, 0x0000000B, 0x00004D1E, + 0x00002C70, 0x000062B6, 0x000500C2, 0x0000000B, 0x00001D8A, 0x00004D1E, 0x00000A16, 0x0004007C, + 0x00000017, 0x0000232F, 0x000055F9, 0x000500AA, 0x00000009, 0x00001FEE, 0x00004ADC, 0x00000A19, + 0x000300F7, 0x000039BC, 0x00000000, 0x000400FA, 0x00001FEE, 0x000033DF, 0x000039BC, 0x000200F8, + 0x000033DF, 0x0009004F, 0x00000017, 0x00001F16, 0x0000232F, 0x0000232F, 0x00000003, 0x00000002, + 0x00000001, 0x00000000, 0x000200F9, 0x000039BC, 0x000200F8, 0x000039BC, 0x000700F5, 0x00000017, + 0x00005972, 0x0000232F, 0x000052F5, 0x00001F16, 0x000033DF, 0x000600A9, 0x0000000B, 0x00001F84, + 0x00001FEE, 0x00000A10, 0x00004ADC, 0x000500AA, 0x00000009, 0x00005116, 0x00001F84, 0x00000A16, + 0x000300F7, 0x000039BD, 0x00000000, 0x000400FA, 0x00005116, 0x000033E0, 0x000039BD, 0x000200F8, + 0x000033E0, 0x0009004F, 0x00000017, 0x00001F17, 0x00005972, 0x00005972, 0x00000001, 0x00000000, + 0x00000003, 0x00000002, 0x000200F9, 0x000039BD, 0x000200F8, 0x000039BD, 0x000700F5, 0x00000017, + 0x00005973, 0x00005972, 0x000039BC, 0x00001F17, 0x000033E0, 0x000600A9, 0x0000000B, 0x000019CD, + 0x00005116, 0x00000A10, 0x00001F84, 0x000500AA, 0x00000009, 0x00003464, 0x000019CD, 0x00000A0D, + 0x000500AA, 0x00000009, 0x000047C2, 0x000019CD, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, + 0x00003464, 0x000047C2, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, + 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00005973, 0x000009CE, + 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, + 0x00005973, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, + 0x00000017, 0x00003FF9, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, + 0x000700F5, 0x00000017, 0x0000587A, 0x00005973, 0x000039BD, 0x00003FF9, 0x00002957, 0x000500AA, + 0x00000009, 0x00004CB6, 0x000019CD, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x000047C2, + 0x00004CB6, 0x000300F7, 0x00002C98, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x00002C98, + 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x0000587A, 0x000002ED, 0x000500C2, + 0x00000017, 0x00003BE7, 0x0000587A, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, + 0x00003BE7, 0x000200F9, 0x00002C98, 0x000200F8, 0x00002C98, 0x000700F5, 0x00000017, 0x00004D37, + 0x0000587A, 0x00003463, 0x000029E8, 0x00002B38, 0x00060041, 0x00000294, 0x000060F9, 0x00001592, + 0x00000A0B, 0x00001D8A, 0x0003003E, 0x000060F9, 0x00004D37, 0x00050080, 0x0000000B, 0x00005D1C, + 0x00001D8A, 0x00000A10, 0x0004007C, 0x00000017, 0x00004755, 0x000022F8, 0x000300F7, 0x00003F86, + 0x00000000, 0x000400FA, 0x00001FEE, 0x000033E1, 0x00003F86, 0x000200F8, 0x000033E1, 0x0009004F, + 0x00000017, 0x00001F18, 0x00004755, 0x00004755, 0x00000003, 0x00000002, 0x00000001, 0x00000000, + 0x000200F9, 0x00003F86, 0x000200F8, 0x00003F86, 0x000700F5, 0x00000017, 0x00002AB1, 0x00004755, + 0x00002C98, 0x00001F18, 0x000033E1, 0x000300F7, 0x00003F87, 0x00000000, 0x000400FA, 0x00005116, + 0x000033E2, 0x00003F87, 0x000200F8, 0x000033E2, 0x0009004F, 0x00000017, 0x00001F19, 0x00002AB1, + 0x00002AB1, 0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x000200F9, 0x00003F87, 0x000200F8, + 0x00003F87, 0x000700F5, 0x00000017, 0x00002AB2, 0x00002AB1, 0x00003F86, 0x00001F19, 0x000033E2, + 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, + 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x00002AB2, 0x000009CE, 0x000500C4, 0x00000017, + 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x00002AB2, 0x0000072E, + 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FFA, + 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, + 0x00002AB3, 0x00002AB2, 0x00003F87, 0x00003FFA, 0x00002958, 0x000300F7, 0x00002C99, 0x00000000, + 0x000400FA, 0x00003B23, 0x00002B39, 0x00002C99, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, + 0x00005E18, 0x00002AB3, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AB3, 0x000002ED, + 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002C99, 0x000200F8, + 0x00002C99, 0x000700F5, 0x00000017, 0x00004D39, 0x00002AB3, 0x00003A1A, 0x000029E9, 0x00002B39, + 0x00060041, 0x00000294, 0x00001F76, 0x00001592, 0x00000A0B, 0x00005D1C, 0x0003003E, 0x00001F76, + 0x00004D39, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_full_128bpp_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_full_128bpp_scaled_cs.h new file mode 100644 index 0000000..7298c45 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_full_128bpp_scaled_cs.h @@ -0,0 +1,2590 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25237 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_runtimearr_uint ArrayStride 4 + OpDecorate %_struct_1948 BufferBlock + OpMemberDecorate %_struct_1948 0 NonWritable + OpMemberDecorate %_struct_1948 0 Offset 0 + OpDecorate %3271 NonWritable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %_struct_1017 Block + OpMemberDecorate %_struct_1017 0 Offset 0 + OpMemberDecorate %_struct_1017 1 Offset 4 + OpMemberDecorate %_struct_1017 2 Offset 8 + OpMemberDecorate %_struct_1017 3 Offset 12 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonReadable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %5522 NonReadable + OpDecorate %5522 Binding 0 + OpDecorate %5522 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %v4uint = OpTypeVector %uint 4 + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 + %v4float = OpTypeVector %float 4 + %bool = OpTypeBool + %v3int = OpTypeVector %int 3 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_4 = OpConstant %uint 4 + %uint_5 = OpConstant %uint 5 + %uint_0 = OpConstant %uint 0 + %uint_24 = OpConstant %uint 24 + %653 = OpConstantComposite %v4uint %uint_0 %uint_8 %uint_16 %uint_24 + %uint_255 = OpConstant %uint 255 +%float_0_00392156886 = OpConstant %float 0.00392156886 + %uint_10 = OpConstant %uint 10 + %uint_20 = OpConstant %uint 20 + %uint_30 = OpConstant %uint 30 + %845 = OpConstantComposite %v4uint %uint_0 %uint_10 %uint_20 %uint_30 + %uint_1023 = OpConstant %uint 1023 + %635 = OpConstantComposite %v4uint %uint_1023 %uint_1023 %uint_1023 %uint_3 +%float_0_000977517106 = OpConstant %float 0.000977517106 +%float_0_333333343 = OpConstant %float 0.333333343 + %2798 = OpConstantComposite %v4float %float_0_000977517106 %float_0_000977517106 %float_0_000977517106 %float_0_333333343 + %2996 = OpConstantComposite %v3uint %uint_0 %uint_10 %uint_20 + %uint_127 = OpConstant %uint 127 + %uint_7 = OpConstant %uint 7 + %v3bool = OpTypeVector %bool 3 + %uint_124 = OpConstant %uint 124 + %uint_23 = OpConstant %uint 23 + %v3float = OpTypeVector %float 3 + %float_n1 = OpConstant %float -1 + %int_16 = OpConstant %int 16 + %int_0 = OpConstant %int 0 + %1959 = OpConstantComposite %v2int %int_16 %int_0 +%float_0_000976592302 = OpConstant %float 0.000976592302 + %v4int = OpTypeVector %int 4 + %290 = OpConstantComposite %v4int %int_16 %int_0 %int_16 %int_0 + %1837 = OpConstantComposite %v2uint %uint_2 %uint_1 + %v2bool = OpTypeVector %bool 2 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %uint_80 = OpConstant %uint 80 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %uint_2048 = OpConstant %uint 2048 + %int_5 = OpConstant %int 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_6 = OpConstant %uint 6 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_runtimearr_uint = OpTypeRuntimeArray %uint +%_struct_1948 = OpTypeStruct %_runtimearr_uint +%_ptr_Uniform__struct_1948 = OpTypePointer Uniform %_struct_1948 + %3271 = OpVariable %_ptr_Uniform__struct_1948 Uniform +%_ptr_Uniform_uint = OpTypePointer Uniform %uint +%_struct_1017 = OpTypeStruct %uint %uint %uint %uint +%_ptr_PushConstant__struct_1017 = OpTypePointer PushConstant %_struct_1017 + %3305 = OpVariable %_ptr_PushConstant__struct_1017 PushConstant +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_15 = OpConstant %uint 15 + %uint_28 = OpConstant %uint 28 + %uint_19 = OpConstant %uint 19 + %2179 = OpConstantComposite %v2uint %uint_16 %uint_19 +%uint_536870912 = OpConstant %uint 536870912 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 + %int_10 = OpConstant %int 10 + %int_26 = OpConstant %int 26 + %int_23 = OpConstant %int 23 +%uint_16777216 = OpConstant %uint 16777216 + %2275 = OpConstantComposite %v2uint %uint_20 %uint_24 + %float_0 = OpConstant %float 0 + %float_0_5 = OpConstant %float 0.5 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %5522 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %1955 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %1284 = OpConstantComposite %v4float %float_n1 %float_n1 %float_n1 %float_n1 + %770 = OpConstantComposite %v4int %int_16 %int_16 %int_16 %int_16 + %1611 = OpConstantComposite %v4uint %uint_255 %uint_255 %uint_255 %uint_255 + %261 = OpConstantComposite %v3uint %uint_1023 %uint_1023 %uint_1023 + %1126 = OpConstantComposite %v3uint %uint_127 %uint_127 %uint_127 + %2828 = OpConstantComposite %v3uint %uint_7 %uint_7 %uint_7 + %2578 = OpConstantComposite %v3uint %uint_0 %uint_0 %uint_0 + %1018 = OpConstantComposite %v3uint %uint_124 %uint_124 %uint_124 + %393 = OpConstantComposite %v3uint %uint_23 %uint_23 %uint_23 + %141 = OpConstantComposite %v3uint %uint_16 %uint_16 %uint_16 + %73 = OpConstantComposite %v2float %float_n1 %float_n1 + %2151 = OpConstantComposite %v2int %int_16 %int_16 + %uint_11 = OpConstant %uint 11 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 +%int_1065353216 = OpConstant %int 1065353216 +%uint_4294967290 = OpConstant %uint 4294967290 + %2360 = OpConstantComposite %v3uint %uint_4294967290 %uint_4294967290 %uint_4294967290 + %float_0_25 = OpConstant %float 0.25 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %19978 = OpShiftRightLogical %uint %15627 %uint_10 + %8574 = OpBitwiseAnd %uint %19978 %uint_3 + %21002 = OpShiftRightLogical %uint %15627 %uint_13 + %8575 = OpBitwiseAnd %uint %21002 %uint_2047 + %21003 = OpShiftRightLogical %uint %15627 %uint_24 + %8576 = OpBitwiseAnd %uint %21003 %uint_15 + %18836 = OpShiftRightLogical %uint %15627 %uint_28 + %9130 = OpBitwiseAnd %uint %18836 %uint_1 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9633 = OpShiftRightLogical %v2uint %8871 %2179 + %23601 = OpBitwiseAnd %v2uint %9633 %1954 + %24030 = OpBitwiseAnd %uint %15627 %uint_536870912 + %12295 = OpINotEqual %bool %24030 %uint_0 + OpSelectionMerge %14676 None + OpBranchConditional %12295 %16739 %21992 + %21992 = OpLabel + OpBranch %14676 + %16739 = OpLabel + %15278 = OpShiftRightLogical %v2uint %23601 %1828 + OpBranch %14676 + %14676 = OpLabel + %19124 = OpPhi %v2uint %15278 %16739 %1807 %21992 + %7038 = OpShiftRightLogical %v2uint %8871 %1855 + %11769 = OpBitwiseAnd %v2uint %7038 %1955 + %16207 = OpShiftLeftLogical %v2uint %11769 %1870 + %23019 = OpIMul %v2uint %16207 %23601 + %13123 = OpShiftRightLogical %uint %20824 %uint_5 + %14785 = OpBitwiseAnd %uint %13123 %uint_2047 + %8858 = OpCompositeExtract %uint %23601 0 + %22993 = OpIMul %uint %14785 %8858 + %20036 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %18628 = OpLoad %uint %20036 + %22701 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %20919 = OpLoad %uint %22701 + %19164 = OpBitwiseAnd %uint %18628 %uint_7 + %21999 = OpBitwiseAnd %uint %18628 %uint_8 + %20495 = OpINotEqual %bool %21999 %uint_0 + %8977 = OpShiftRightLogical %uint %18628 %uint_4 + %17416 = OpBitwiseAnd %uint %8977 %uint_7 + %22920 = OpBitcast %int %18628 + %13711 = OpShiftLeftLogical %int %22920 %int_10 + %20636 = OpShiftRightArithmetic %int %13711 %int_26 + %18178 = OpShiftLeftLogical %int %20636 %int_23 + %7462 = OpIAdd %int %18178 %int_1065353216 + %11052 = OpBitcast %float %7462 + %22649 = OpBitwiseAnd %uint %18628 %uint_16777216 + %7513 = OpINotEqual %bool %22649 %uint_0 + %8003 = OpBitwiseAnd %uint %20919 %uint_1023 + %15783 = OpShiftLeftLogical %uint %8003 %uint_5 + %22591 = OpShiftRightLogical %uint %20919 %uint_10 + %19390 = OpBitwiseAnd %uint %22591 %uint_1023 + %25203 = OpShiftLeftLogical %uint %19390 %uint_5 + %10422 = OpCompositeConstruct %v2uint %20919 %20919 + %10385 = OpShiftRightLogical %v2uint %10422 %2275 + %23379 = OpBitwiseAnd %v2uint %10385 %2122 + %16208 = OpShiftLeftLogical %v2uint %23379 %1870 + %23020 = OpIMul %v2uint %16208 %23601 + %12743 = OpShiftRightLogical %uint %20919 %uint_28 + %17238 = OpBitwiseAnd %uint %12743 %uint_7 + %12737 = OpLoad %v3uint %gl_GlobalInvocationID + %14500 = OpVectorShuffle %v2uint %12737 %12737 0 1 + %12025 = OpShiftLeftLogical %v2uint %14500 %1816 + %7640 = OpCompositeExtract %uint %12025 0 + %11658 = OpShiftLeftLogical %uint %22993 %uint_3 + %15379 = OpUGreaterThanEqual %bool %7640 %11658 + OpSelectionMerge %12755 DontFlatten + OpBranchConditional %15379 %21993 %12755 + %21993 = OpLabel + OpBranch %19578 + %12755 = OpLabel + %7359 = OpCompositeExtract %uint %19124 0 + %6926 = OpExtInst %uint %1 UMax %7640 %7359 + %17800 = OpCompositeExtract %uint %12025 1 + %6449 = OpCompositeExtract %uint %19124 1 + %24446 = OpExtInst %uint %1 UMax %17800 %6449 + %20975 = OpCompositeConstruct %v2uint %6926 %24446 + %21036 = OpIAdd %v2uint %20975 %23019 + %16075 = OpULessThanEqual %bool %17238 %uint_3 + OpSelectionMerge %23776 None + OpBranchConditional %16075 %10990 %15087 + %15087 = OpLabel + %13566 = OpIEqual %bool %17238 %uint_5 + %8438 = OpSelect %uint %13566 %uint_2 %uint_0 + OpBranch %23776 + %10990 = OpLabel + OpBranch %23776 + %23776 = OpLabel + %19300 = OpPhi %uint %17238 %10990 %8438 %15087 + %16830 = OpCompositeConstruct %v2uint %8574 %8574 + %11801 = OpUGreaterThanEqual %v2bool %16830 %1837 + %19381 = OpSelect %v2uint %11801 %1828 %1807 + %10986 = OpShiftLeftLogical %v2uint %21036 %19381 + %24669 = OpCompositeConstruct %v2uint %19300 %19300 + %9093 = OpShiftRightLogical %v2uint %24669 %1816 + %16072 = OpBitwiseAnd %v2uint %9093 %1828 + %18106 = OpIAdd %v2uint %10986 %16072 + %22936 = OpIMul %v2uint %2719 %23601 + %11332 = OpCompositeConstruct %v2uint %9130 %uint_0 + %6571 = OpShiftRightLogical %v2uint %22936 %11332 + %10146 = OpUDiv %v2uint %18106 %6571 + %20390 = OpCompositeExtract %uint %10146 1 + %11046 = OpIMul %uint %20390 %20561 + %24665 = OpCompositeExtract %uint %10146 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %8575 %21536 + %22376 = OpIMul %v2uint %10146 %6571 + %20715 = OpISub %v2uint %18106 %22376 + %7303 = OpCompositeExtract %uint %22936 0 + %22882 = OpCompositeExtract %uint %22936 1 + %13170 = OpIMul %uint %7303 %22882 + %14551 = OpIMul %uint %8742 %13170 + %6805 = OpCompositeExtract %uint %20715 1 + %23526 = OpCompositeExtract %uint %6571 0 + %22886 = OpIMul %uint %6805 %23526 + %6886 = OpCompositeExtract %uint %20715 0 + %9696 = OpIAdd %uint %22886 %6886 + %18021 = OpShiftLeftLogical %uint %9696 %9130 + %18363 = OpIAdd %uint %14551 %18021 + %13504 = OpIMul %uint %13170 %uint_2048 + %25231 = OpUMod %uint %18363 %13504 + %16379 = OpUGreaterThanEqual %bool %8574 %uint_2 + %24735 = OpSelect %uint %16379 %uint_1 %uint_0 + %20074 = OpIAdd %uint %9130 %24735 + %6555 = OpShiftLeftLogical %uint %uint_1 %20074 + %23279 = OpINotEqual %bool %9130 %uint_0 + OpSelectionMerge %21263 DontFlatten + OpBranchConditional %23279 %15205 %16569 + %16569 = OpLabel + %19162 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20297 DontFlatten + OpBranchConditional %19162 %9761 %12129 + %12129 = OpLabel + %19407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %25231 + %23875 = OpLoad %uint %19407 + %11687 = OpIAdd %uint %25231 %6555 + %24558 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11687 + %16380 = OpLoad %uint %24558 + %20780 = OpCompositeConstruct %v2uint %23875 %16380 + OpBranch %20297 + %9761 = OpLabel + %21829 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %25231 + %23876 = OpLoad %uint %21829 + %11688 = OpIAdd %uint %25231 %uint_1 + %24559 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11688 + %16381 = OpLoad %uint %24559 + %20781 = OpCompositeConstruct %v2uint %23876 %16381 + OpBranch %20297 + %20297 = OpLabel + %10943 = OpPhi %v2uint %20781 %9761 %20780 %12129 + OpSelectionMerge %16224 None + OpSwitch %8576 %19451 0 %14585 1 %14585 2 %7355 10 %7355 3 %7354 12 %7354 4 %8190 6 %8243 + %8243 = OpLabel + %24406 = OpCompositeExtract %uint %10943 0 + %24679 = OpExtInst %v2float %1 UnpackHalf2x16 %24406 + %10082 = OpCompositeExtract %float %24679 0 + %17478 = OpCompositeExtract %float %24679 1 + %14604 = OpCompositeConstruct %v4float %10082 %17478 %float_0 %float_0 + %17274 = OpCompositeExtract %uint %10943 1 + %18027 = OpExtInst %v2float %1 UnpackHalf2x16 %17274 + %10083 = OpCompositeExtract %float %18027 0 + %20670 = OpCompositeExtract %float %18027 1 + %9033 = OpCompositeConstruct %v4float %10083 %20670 %float_0 %float_0 + OpBranch %16224 + %8190 = OpLabel + %12427 = OpCompositeExtract %uint %10943 0 + %22685 = OpBitcast %int %12427 + %18202 = OpCompositeConstruct %v2int %22685 %22685 + %18349 = OpShiftLeftLogical %v2int %18202 %1959 + %13335 = OpShiftRightArithmetic %v2int %18349 %2151 + %10903 = OpConvertSToF %v2float %13335 + %18247 = OpVectorTimesScalar %v2float %10903 %float_0_000976592302 + %24070 = OpExtInst %v2float %1 FMax %73 %18247 + %24330 = OpCompositeExtract %float %24070 0 + %15572 = OpCompositeExtract %float %24070 1 + %16670 = OpCompositeConstruct %v4float %24330 %15572 %float_0 %float_0 + %19522 = OpCompositeExtract %uint %10943 1 + %16033 = OpBitcast %int %19522 + %18203 = OpCompositeConstruct %v2int %16033 %16033 + %18350 = OpShiftLeftLogical %v2int %18203 %1959 + %13336 = OpShiftRightArithmetic %v2int %18350 %2151 + %10904 = OpConvertSToF %v2float %13336 + %18248 = OpVectorTimesScalar %v2float %10904 %float_0_000976592302 + %24071 = OpExtInst %v2float %1 FMax %73 %18248 + %24331 = OpCompositeExtract %float %24071 0 + %18764 = OpCompositeExtract %float %24071 1 + %9034 = OpCompositeConstruct %v4float %24331 %18764 %float_0 %float_0 + OpBranch %16224 + %7354 = OpLabel + %22205 = OpCompositeExtract %uint %10943 0 + %20234 = OpCompositeConstruct %v3uint %22205 %22205 %22205 + %11021 = OpShiftRightLogical %v3uint %20234 %2996 + %24038 = OpBitwiseAnd %v3uint %11021 %261 + %18588 = OpBitwiseAnd %v3uint %24038 %1126 + %23440 = OpShiftRightLogical %v3uint %24038 %2828 + %16585 = OpIEqual %v3bool %23440 %2578 + %11339 = OpExtInst %v3int %1 FindUMsb %18588 + %10773 = OpBitcast %v3uint %11339 + %6266 = OpISub %v3uint %2828 %10773 + %8720 = OpIAdd %v3uint %10773 %2360 + %10351 = OpSelect %v3uint %16585 %8720 %23440 + %23252 = OpShiftLeftLogical %v3uint %18588 %6266 + %18842 = OpBitwiseAnd %v3uint %23252 %1126 + %10909 = OpSelect %v3uint %16585 %18842 %18588 + %24569 = OpIAdd %v3uint %10351 %1018 + %20351 = OpShiftLeftLogical %v3uint %24569 %393 + %16294 = OpShiftLeftLogical %v3uint %10909 %141 + %22396 = OpBitwiseOr %v3uint %20351 %16294 + %13824 = OpIEqual %v3bool %24038 %2578 + %16962 = OpSelect %v3uint %13824 %2578 %22396 + %10703 = OpBitcast %v3float %16962 + %19364 = OpShiftRightLogical %uint %22205 %uint_30 + %18446 = OpConvertUToF %float %19364 + %15903 = OpFMul %float %18446 %float_0_333333343 + %21442 = OpCompositeExtract %float %10703 0 + %10837 = OpCompositeExtract %float %10703 1 + %7833 = OpCompositeExtract %float %10703 2 + %15834 = OpCompositeConstruct %v4float %21442 %10837 %7833 %15903 + %10229 = OpCompositeExtract %uint %10943 1 + %13582 = OpCompositeConstruct %v3uint %10229 %10229 %10229 + %11022 = OpShiftRightLogical %v3uint %13582 %2996 + %24039 = OpBitwiseAnd %v3uint %11022 %261 + %18589 = OpBitwiseAnd %v3uint %24039 %1126 + %23441 = OpShiftRightLogical %v3uint %24039 %2828 + %16586 = OpIEqual %v3bool %23441 %2578 + %11340 = OpExtInst %v3int %1 FindUMsb %18589 + %10774 = OpBitcast %v3uint %11340 + %6267 = OpISub %v3uint %2828 %10774 + %8721 = OpIAdd %v3uint %10774 %2360 + %10352 = OpSelect %v3uint %16586 %8721 %23441 + %23253 = OpShiftLeftLogical %v3uint %18589 %6267 + %18843 = OpBitwiseAnd %v3uint %23253 %1126 + %10910 = OpSelect %v3uint %16586 %18843 %18589 + %24570 = OpIAdd %v3uint %10352 %1018 + %20352 = OpShiftLeftLogical %v3uint %24570 %393 + %16295 = OpShiftLeftLogical %v3uint %10910 %141 + %22397 = OpBitwiseOr %v3uint %20352 %16295 + %13825 = OpIEqual %v3bool %24039 %2578 + %16963 = OpSelect %v3uint %13825 %2578 %22397 + %10704 = OpBitcast %v3float %16963 + %19365 = OpShiftRightLogical %uint %10229 %uint_30 + %18447 = OpConvertUToF %float %19365 + %15904 = OpFMul %float %18447 %float_0_333333343 + %21443 = OpCompositeExtract %float %10704 0 + %10838 = OpCompositeExtract %float %10704 1 + %11025 = OpCompositeExtract %float %10704 2 + %9035 = OpCompositeConstruct %v4float %21443 %10838 %11025 %15904 + OpBranch %16224 + %7355 = OpLabel + %22206 = OpCompositeExtract %uint %10943 0 + %20235 = OpCompositeConstruct %v4uint %22206 %22206 %22206 %22206 + %9368 = OpShiftRightLogical %v4uint %20235 %845 + %18859 = OpBitwiseAnd %v4uint %9368 %635 + %15543 = OpConvertUToF %v4float %18859 + %16688 = OpFMul %v4float %15543 %2798 + %23762 = OpCompositeExtract %uint %10943 1 + %20813 = OpCompositeConstruct %v4uint %23762 %23762 %23762 %23762 + %9369 = OpShiftRightLogical %v4uint %20813 %845 + %18860 = OpBitwiseAnd %v4uint %9369 %635 + %18735 = OpConvertUToF %v4float %18860 + %9887 = OpFMul %v4float %18735 %2798 + OpBranch %16224 + %14585 = OpLabel + %22207 = OpCompositeExtract %uint %10943 0 + %20236 = OpCompositeConstruct %v4uint %22207 %22207 %22207 %22207 + %9370 = OpShiftRightLogical %v4uint %20236 %653 + %19030 = OpBitwiseAnd %v4uint %9370 %1611 + %13986 = OpConvertUToF %v4float %19030 + %19235 = OpVectorTimesScalar %v4float %13986 %float_0_00392156886 + %8607 = OpCompositeExtract %uint %10943 1 + %24843 = OpCompositeConstruct %v4uint %8607 %8607 %8607 %8607 + %9371 = OpShiftRightLogical %v4uint %24843 %653 + %19031 = OpBitwiseAnd %v4uint %9371 %1611 + %17178 = OpConvertUToF %v4float %19031 + %12434 = OpVectorTimesScalar %v4float %17178 %float_0_00392156886 + OpBranch %16224 + %19451 = OpLabel + %12428 = OpCompositeExtract %uint %10943 0 + %20462 = OpBitcast %float %12428 + %17206 = OpCompositeConstruct %v2float %20462 %float_0 + %11664 = OpVectorShuffle %v4float %17206 %17206 0 1 1 1 + %22193 = OpCompositeExtract %uint %10943 1 + %16232 = OpBitcast %float %22193 + %20398 = OpCompositeConstruct %v2float %16232 %float_0 + %23098 = OpVectorShuffle %v4float %20398 %20398 0 1 1 1 + OpBranch %16224 + %16224 = OpLabel + %11251 = OpPhi %v4float %23098 %19451 %12434 %14585 %9887 %7355 %9035 %7354 %9034 %8190 %9033 %8243 + %13709 = OpPhi %v4float %11664 %19451 %19235 %14585 %16688 %7355 %15834 %7354 %16670 %8190 %14604 %8243 + OpBranch %21263 + %15205 = OpLabel + %21584 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20298 DontFlatten + OpBranchConditional %21584 %9762 %12130 + %12130 = OpLabel + %19408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %25231 + %23877 = OpLoad %uint %19408 + %11689 = OpIAdd %uint %25231 %uint_1 + %6399 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11689 + %23650 = OpLoad %uint %6399 + %11690 = OpIAdd %uint %25231 %6555 + %6400 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11690 + %23651 = OpLoad %uint %6400 + %11691 = OpIAdd %uint %11690 %uint_1 + %24560 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11691 + %16382 = OpLoad %uint %24560 + %20782 = OpCompositeConstruct %v4uint %23877 %23650 %23651 %16382 + OpBranch %20298 + %9762 = OpLabel + %21830 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %25231 + %23878 = OpLoad %uint %21830 + %11692 = OpIAdd %uint %25231 %uint_1 + %6401 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11692 + %23652 = OpLoad %uint %6401 + %11693 = OpIAdd %uint %25231 %uint_2 + %6402 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11693 + %23653 = OpLoad %uint %6402 + %11694 = OpIAdd %uint %25231 %uint_3 + %24561 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11694 + %16383 = OpLoad %uint %24561 + %20783 = OpCompositeConstruct %v4uint %23878 %23652 %23653 %16383 + OpBranch %20298 + %20298 = OpLabel + %10944 = OpPhi %v4uint %20783 %9762 %20782 %12130 + OpSelectionMerge %20259 None + OpSwitch %8576 %20310 5 %8536 7 %8244 + %8244 = OpLabel + %24407 = OpCompositeExtract %uint %10944 0 + %24680 = OpExtInst %v2float %1 UnpackHalf2x16 %24407 + %10101 = OpCompositeExtract %float %24680 0 + %16056 = OpCompositeExtract %float %24680 1 + %17025 = OpCompositeExtract %uint %10944 1 + %15605 = OpExtInst %v2float %1 UnpackHalf2x16 %17025 + %10084 = OpCompositeExtract %float %15605 0 + %17479 = OpCompositeExtract %float %15605 1 + %14605 = OpCompositeConstruct %v4float %10101 %16056 %10084 %17479 + %17275 = OpCompositeExtract %uint %10944 2 + %18028 = OpExtInst %v2float %1 UnpackHalf2x16 %17275 + %10102 = OpCompositeExtract %float %18028 0 + %16057 = OpCompositeExtract %float %18028 1 + %17026 = OpCompositeExtract %uint %10944 3 + %15606 = OpExtInst %v2float %1 UnpackHalf2x16 %17026 + %10085 = OpCompositeExtract %float %15606 0 + %20671 = OpCompositeExtract %float %15606 1 + %9036 = OpCompositeConstruct %v4float %10102 %16057 %10085 %20671 + OpBranch %20259 + %8536 = OpLabel + %9723 = OpVectorShuffle %v2uint %10944 %10944 0 1 + %23356 = OpBitcast %v2int %9723 + %24782 = OpVectorShuffle %v4int %23356 %23356 0 0 1 1 + %18598 = OpShiftLeftLogical %v4int %24782 %290 + %15757 = OpShiftRightArithmetic %v4int %18598 %770 + %10905 = OpConvertSToF %v4float %15757 + %18209 = OpVectorTimesScalar %v4float %10905 %float_0_000976592302 + %25233 = OpExtInst %v4float %1 FMax %1284 %18209 + %14187 = OpVectorShuffle %v2uint %10944 %10944 2 3 + %9407 = OpBitcast %v2int %14187 + %24783 = OpVectorShuffle %v4int %9407 %9407 0 0 1 1 + %18599 = OpShiftLeftLogical %v4int %24783 %290 + %15758 = OpShiftRightArithmetic %v4int %18599 %770 + %10906 = OpConvertSToF %v4float %15758 + %21439 = OpVectorTimesScalar %v4float %10906 %float_0_000976592302 + %17250 = OpExtInst %v4float %1 FMax %1284 %21439 + OpBranch %20259 + %20310 = OpLabel + %9763 = OpVectorShuffle %v2uint %10944 %10944 0 1 + %20825 = OpBitcast %v2float %9763 + %7035 = OpCompositeExtract %float %20825 0 + %13418 = OpCompositeExtract %float %20825 1 + %17016 = OpCompositeConstruct %v4float %7035 %13418 %float_0 %float_0 + %16856 = OpVectorShuffle %v2uint %10944 %10944 2 3 + %14173 = OpBitcast %v2float %16856 + %7036 = OpCompositeExtract %float %14173 0 + %16648 = OpCompositeExtract %float %14173 1 + %9037 = OpCompositeConstruct %v4float %7036 %16648 %float_0 %float_0 + OpBranch %20259 + %20259 = OpLabel + %11252 = OpPhi %v4float %9037 %20310 %17250 %8536 %9036 %8244 + %13710 = OpPhi %v4float %17016 %20310 %25233 %8536 %14605 %8244 + OpBranch %21263 + %21263 = OpLabel + %9826 = OpPhi %v4float %11252 %20259 %11251 %16224 + %14051 = OpPhi %v4float %13710 %20259 %13709 %16224 + %11861 = OpUGreaterThanEqual %bool %17238 %uint_4 + OpSelectionMerge %21267 DontFlatten + OpBranchConditional %11861 %20977 %21267 + %20977 = OpLabel + %11079 = OpIMul %uint %uint_80 %8858 + %23069 = OpFMul %float %11052 %float_0_5 + %8114 = OpIAdd %uint %25231 %11079 + OpSelectionMerge %21264 DontFlatten + OpBranchConditional %23279 %15206 %16570 + %16570 = OpLabel + %19163 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20299 DontFlatten + OpBranchConditional %19163 %9764 %12131 + %12131 = OpLabel + %19409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8114 + %23879 = OpLoad %uint %19409 + %11695 = OpIAdd %uint %8114 %6555 + %24562 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11695 + %16384 = OpLoad %uint %24562 + %20784 = OpCompositeConstruct %v2uint %23879 %16384 + OpBranch %20299 + %9764 = OpLabel + %21831 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8114 + %23880 = OpLoad %uint %21831 + %11696 = OpIAdd %uint %8114 %uint_1 + %24563 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11696 + %16385 = OpLoad %uint %24563 + %20785 = OpCompositeConstruct %v2uint %23880 %16385 + OpBranch %20299 + %20299 = OpLabel + %10945 = OpPhi %v2uint %20785 %9764 %20784 %12131 + OpSelectionMerge %16225 None + OpSwitch %8576 %19452 0 %14586 1 %14586 2 %7357 10 %7357 3 %7356 12 %7356 4 %8191 6 %8245 + %8245 = OpLabel + %24408 = OpCompositeExtract %uint %10945 0 + %24681 = OpExtInst %v2float %1 UnpackHalf2x16 %24408 + %10086 = OpCompositeExtract %float %24681 0 + %17480 = OpCompositeExtract %float %24681 1 + %14606 = OpCompositeConstruct %v4float %10086 %17480 %float_0 %float_0 + %17276 = OpCompositeExtract %uint %10945 1 + %18029 = OpExtInst %v2float %1 UnpackHalf2x16 %17276 + %10087 = OpCompositeExtract %float %18029 0 + %20672 = OpCompositeExtract %float %18029 1 + %9038 = OpCompositeConstruct %v4float %10087 %20672 %float_0 %float_0 + OpBranch %16225 + %8191 = OpLabel + %12429 = OpCompositeExtract %uint %10945 0 + %22686 = OpBitcast %int %12429 + %18204 = OpCompositeConstruct %v2int %22686 %22686 + %18351 = OpShiftLeftLogical %v2int %18204 %1959 + %13337 = OpShiftRightArithmetic %v2int %18351 %2151 + %10907 = OpConvertSToF %v2float %13337 + %18249 = OpVectorTimesScalar %v2float %10907 %float_0_000976592302 + %24072 = OpExtInst %v2float %1 FMax %73 %18249 + %24332 = OpCompositeExtract %float %24072 0 + %15573 = OpCompositeExtract %float %24072 1 + %16671 = OpCompositeConstruct %v4float %24332 %15573 %float_0 %float_0 + %19523 = OpCompositeExtract %uint %10945 1 + %16034 = OpBitcast %int %19523 + %18205 = OpCompositeConstruct %v2int %16034 %16034 + %18352 = OpShiftLeftLogical %v2int %18205 %1959 + %13338 = OpShiftRightArithmetic %v2int %18352 %2151 + %10908 = OpConvertSToF %v2float %13338 + %18250 = OpVectorTimesScalar %v2float %10908 %float_0_000976592302 + %24073 = OpExtInst %v2float %1 FMax %73 %18250 + %24333 = OpCompositeExtract %float %24073 0 + %18765 = OpCompositeExtract %float %24073 1 + %9039 = OpCompositeConstruct %v4float %24333 %18765 %float_0 %float_0 + OpBranch %16225 + %7356 = OpLabel + %22208 = OpCompositeExtract %uint %10945 0 + %20237 = OpCompositeConstruct %v3uint %22208 %22208 %22208 + %11023 = OpShiftRightLogical %v3uint %20237 %2996 + %24040 = OpBitwiseAnd %v3uint %11023 %261 + %18590 = OpBitwiseAnd %v3uint %24040 %1126 + %23442 = OpShiftRightLogical %v3uint %24040 %2828 + %16587 = OpIEqual %v3bool %23442 %2578 + %11341 = OpExtInst %v3int %1 FindUMsb %18590 + %10775 = OpBitcast %v3uint %11341 + %6268 = OpISub %v3uint %2828 %10775 + %8722 = OpIAdd %v3uint %10775 %2360 + %10353 = OpSelect %v3uint %16587 %8722 %23442 + %23254 = OpShiftLeftLogical %v3uint %18590 %6268 + %18844 = OpBitwiseAnd %v3uint %23254 %1126 + %10911 = OpSelect %v3uint %16587 %18844 %18590 + %24571 = OpIAdd %v3uint %10353 %1018 + %20353 = OpShiftLeftLogical %v3uint %24571 %393 + %16296 = OpShiftLeftLogical %v3uint %10911 %141 + %22398 = OpBitwiseOr %v3uint %20353 %16296 + %13826 = OpIEqual %v3bool %24040 %2578 + %16964 = OpSelect %v3uint %13826 %2578 %22398 + %10705 = OpBitcast %v3float %16964 + %19366 = OpShiftRightLogical %uint %22208 %uint_30 + %18448 = OpConvertUToF %float %19366 + %15905 = OpFMul %float %18448 %float_0_333333343 + %21444 = OpCompositeExtract %float %10705 0 + %10839 = OpCompositeExtract %float %10705 1 + %7834 = OpCompositeExtract %float %10705 2 + %15835 = OpCompositeConstruct %v4float %21444 %10839 %7834 %15905 + %10230 = OpCompositeExtract %uint %10945 1 + %13583 = OpCompositeConstruct %v3uint %10230 %10230 %10230 + %11024 = OpShiftRightLogical %v3uint %13583 %2996 + %24041 = OpBitwiseAnd %v3uint %11024 %261 + %18591 = OpBitwiseAnd %v3uint %24041 %1126 + %23443 = OpShiftRightLogical %v3uint %24041 %2828 + %16588 = OpIEqual %v3bool %23443 %2578 + %11342 = OpExtInst %v3int %1 FindUMsb %18591 + %10776 = OpBitcast %v3uint %11342 + %6269 = OpISub %v3uint %2828 %10776 + %8723 = OpIAdd %v3uint %10776 %2360 + %10354 = OpSelect %v3uint %16588 %8723 %23443 + %23255 = OpShiftLeftLogical %v3uint %18591 %6269 + %18845 = OpBitwiseAnd %v3uint %23255 %1126 + %10912 = OpSelect %v3uint %16588 %18845 %18591 + %24572 = OpIAdd %v3uint %10354 %1018 + %20354 = OpShiftLeftLogical %v3uint %24572 %393 + %16297 = OpShiftLeftLogical %v3uint %10912 %141 + %22399 = OpBitwiseOr %v3uint %20354 %16297 + %13827 = OpIEqual %v3bool %24041 %2578 + %16965 = OpSelect %v3uint %13827 %2578 %22399 + %10706 = OpBitcast %v3float %16965 + %19367 = OpShiftRightLogical %uint %10230 %uint_30 + %18449 = OpConvertUToF %float %19367 + %15906 = OpFMul %float %18449 %float_0_333333343 + %21445 = OpCompositeExtract %float %10706 0 + %10840 = OpCompositeExtract %float %10706 1 + %11026 = OpCompositeExtract %float %10706 2 + %9040 = OpCompositeConstruct %v4float %21445 %10840 %11026 %15906 + OpBranch %16225 + %7357 = OpLabel + %22209 = OpCompositeExtract %uint %10945 0 + %20238 = OpCompositeConstruct %v4uint %22209 %22209 %22209 %22209 + %9372 = OpShiftRightLogical %v4uint %20238 %845 + %18861 = OpBitwiseAnd %v4uint %9372 %635 + %15544 = OpConvertUToF %v4float %18861 + %16689 = OpFMul %v4float %15544 %2798 + %23763 = OpCompositeExtract %uint %10945 1 + %20814 = OpCompositeConstruct %v4uint %23763 %23763 %23763 %23763 + %9373 = OpShiftRightLogical %v4uint %20814 %845 + %18862 = OpBitwiseAnd %v4uint %9373 %635 + %18736 = OpConvertUToF %v4float %18862 + %9888 = OpFMul %v4float %18736 %2798 + OpBranch %16225 + %14586 = OpLabel + %22210 = OpCompositeExtract %uint %10945 0 + %20239 = OpCompositeConstruct %v4uint %22210 %22210 %22210 %22210 + %9374 = OpShiftRightLogical %v4uint %20239 %653 + %19032 = OpBitwiseAnd %v4uint %9374 %1611 + %13987 = OpConvertUToF %v4float %19032 + %19236 = OpVectorTimesScalar %v4float %13987 %float_0_00392156886 + %8608 = OpCompositeExtract %uint %10945 1 + %24844 = OpCompositeConstruct %v4uint %8608 %8608 %8608 %8608 + %9375 = OpShiftRightLogical %v4uint %24844 %653 + %19033 = OpBitwiseAnd %v4uint %9375 %1611 + %17179 = OpConvertUToF %v4float %19033 + %12435 = OpVectorTimesScalar %v4float %17179 %float_0_00392156886 + OpBranch %16225 + %19452 = OpLabel + %12430 = OpCompositeExtract %uint %10945 0 + %20463 = OpBitcast %float %12430 + %17207 = OpCompositeConstruct %v2float %20463 %float_0 + %11665 = OpVectorShuffle %v4float %17207 %17207 0 1 1 1 + %22194 = OpCompositeExtract %uint %10945 1 + %16233 = OpBitcast %float %22194 + %20399 = OpCompositeConstruct %v2float %16233 %float_0 + %23099 = OpVectorShuffle %v4float %20399 %20399 0 1 1 1 + OpBranch %16225 + %16225 = OpLabel + %11253 = OpPhi %v4float %23099 %19452 %12435 %14586 %9888 %7357 %9040 %7356 %9039 %8191 %9038 %8245 + %13712 = OpPhi %v4float %11665 %19452 %19236 %14586 %16689 %7357 %15835 %7356 %16671 %8191 %14606 %8245 + OpBranch %21264 + %15206 = OpLabel + %21585 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20300 DontFlatten + OpBranchConditional %21585 %9765 %12132 + %12132 = OpLabel + %19410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8114 + %23881 = OpLoad %uint %19410 + %11697 = OpIAdd %uint %8114 %uint_1 + %6403 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11697 + %23654 = OpLoad %uint %6403 + %11698 = OpIAdd %uint %8114 %6555 + %6404 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11698 + %23655 = OpLoad %uint %6404 + %11699 = OpIAdd %uint %11698 %uint_1 + %24564 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11699 + %16386 = OpLoad %uint %24564 + %20786 = OpCompositeConstruct %v4uint %23881 %23654 %23655 %16386 + OpBranch %20300 + %9765 = OpLabel + %21832 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8114 + %23882 = OpLoad %uint %21832 + %11700 = OpIAdd %uint %8114 %uint_1 + %6405 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11700 + %23656 = OpLoad %uint %6405 + %11701 = OpIAdd %uint %8114 %uint_2 + %6406 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11701 + %23657 = OpLoad %uint %6406 + %11702 = OpIAdd %uint %8114 %uint_3 + %24565 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11702 + %16387 = OpLoad %uint %24565 + %20787 = OpCompositeConstruct %v4uint %23882 %23656 %23657 %16387 + OpBranch %20300 + %20300 = OpLabel + %10946 = OpPhi %v4uint %20787 %9765 %20786 %12132 + OpSelectionMerge %20260 None + OpSwitch %8576 %20311 5 %8537 7 %8246 + %8246 = OpLabel + %24409 = OpCompositeExtract %uint %10946 0 + %24682 = OpExtInst %v2float %1 UnpackHalf2x16 %24409 + %10103 = OpCompositeExtract %float %24682 0 + %16058 = OpCompositeExtract %float %24682 1 + %17027 = OpCompositeExtract %uint %10946 1 + %15607 = OpExtInst %v2float %1 UnpackHalf2x16 %17027 + %10088 = OpCompositeExtract %float %15607 0 + %17481 = OpCompositeExtract %float %15607 1 + %14607 = OpCompositeConstruct %v4float %10103 %16058 %10088 %17481 + %17277 = OpCompositeExtract %uint %10946 2 + %18030 = OpExtInst %v2float %1 UnpackHalf2x16 %17277 + %10104 = OpCompositeExtract %float %18030 0 + %16059 = OpCompositeExtract %float %18030 1 + %17028 = OpCompositeExtract %uint %10946 3 + %15608 = OpExtInst %v2float %1 UnpackHalf2x16 %17028 + %10089 = OpCompositeExtract %float %15608 0 + %20673 = OpCompositeExtract %float %15608 1 + %9041 = OpCompositeConstruct %v4float %10104 %16059 %10089 %20673 + OpBranch %20260 + %8537 = OpLabel + %9724 = OpVectorShuffle %v2uint %10946 %10946 0 1 + %23357 = OpBitcast %v2int %9724 + %24784 = OpVectorShuffle %v4int %23357 %23357 0 0 1 1 + %18600 = OpShiftLeftLogical %v4int %24784 %290 + %15759 = OpShiftRightArithmetic %v4int %18600 %770 + %10913 = OpConvertSToF %v4float %15759 + %18210 = OpVectorTimesScalar %v4float %10913 %float_0_000976592302 + %25234 = OpExtInst %v4float %1 FMax %1284 %18210 + %14188 = OpVectorShuffle %v2uint %10946 %10946 2 3 + %9408 = OpBitcast %v2int %14188 + %24785 = OpVectorShuffle %v4int %9408 %9408 0 0 1 1 + %18601 = OpShiftLeftLogical %v4int %24785 %290 + %15760 = OpShiftRightArithmetic %v4int %18601 %770 + %10914 = OpConvertSToF %v4float %15760 + %21440 = OpVectorTimesScalar %v4float %10914 %float_0_000976592302 + %17251 = OpExtInst %v4float %1 FMax %1284 %21440 + OpBranch %20260 + %20311 = OpLabel + %9766 = OpVectorShuffle %v2uint %10946 %10946 0 1 + %20826 = OpBitcast %v2float %9766 + %7037 = OpCompositeExtract %float %20826 0 + %13419 = OpCompositeExtract %float %20826 1 + %17017 = OpCompositeConstruct %v4float %7037 %13419 %float_0 %float_0 + %16857 = OpVectorShuffle %v2uint %10946 %10946 2 3 + %14174 = OpBitcast %v2float %16857 + %7039 = OpCompositeExtract %float %14174 0 + %16649 = OpCompositeExtract %float %14174 1 + %9042 = OpCompositeConstruct %v4float %7039 %16649 %float_0 %float_0 + OpBranch %20260 + %20260 = OpLabel + %11254 = OpPhi %v4float %9042 %20311 %17251 %8537 %9041 %8246 + %13713 = OpPhi %v4float %17017 %20311 %25234 %8537 %14607 %8246 + OpBranch %21264 + %21264 = OpLabel + %8971 = OpPhi %v4float %11254 %20260 %11253 %16225 + %19594 = OpPhi %v4float %13713 %20260 %13712 %16225 + %18096 = OpFAdd %v4float %14051 %19594 + %17754 = OpFAdd %v4float %9826 %8971 + %14461 = OpUGreaterThanEqual %bool %17238 %uint_6 + OpSelectionMerge %24264 DontFlatten + OpBranchConditional %14461 %9905 %24264 + %9905 = OpLabel + %14258 = OpShiftLeftLogical %uint %uint_1 %9130 + %12090 = OpFMul %float %11052 %float_0_25 + %20988 = OpIAdd %uint %25231 %14258 + OpSelectionMerge %21265 DontFlatten + OpBranchConditional %23279 %15207 %16571 + %16571 = OpLabel + %19165 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20301 DontFlatten + OpBranchConditional %19165 %9767 %12133 + %12133 = OpLabel + %19411 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23883 = OpLoad %uint %19411 + %11703 = OpIAdd %uint %20988 %6555 + %24566 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11703 + %16388 = OpLoad %uint %24566 + %20788 = OpCompositeConstruct %v2uint %23883 %16388 + OpBranch %20301 + %9767 = OpLabel + %21833 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23884 = OpLoad %uint %21833 + %11704 = OpIAdd %uint %20988 %uint_1 + %24567 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11704 + %16389 = OpLoad %uint %24567 + %20789 = OpCompositeConstruct %v2uint %23884 %16389 + OpBranch %20301 + %20301 = OpLabel + %10947 = OpPhi %v2uint %20789 %9767 %20788 %12133 + OpSelectionMerge %16226 None + OpSwitch %8576 %19453 0 %14587 1 %14587 2 %7360 10 %7360 3 %7358 12 %7358 4 %8192 6 %8247 + %8247 = OpLabel + %24410 = OpCompositeExtract %uint %10947 0 + %24683 = OpExtInst %v2float %1 UnpackHalf2x16 %24410 + %10090 = OpCompositeExtract %float %24683 0 + %17482 = OpCompositeExtract %float %24683 1 + %14608 = OpCompositeConstruct %v4float %10090 %17482 %float_0 %float_0 + %17278 = OpCompositeExtract %uint %10947 1 + %18031 = OpExtInst %v2float %1 UnpackHalf2x16 %17278 + %10091 = OpCompositeExtract %float %18031 0 + %20674 = OpCompositeExtract %float %18031 1 + %9043 = OpCompositeConstruct %v4float %10091 %20674 %float_0 %float_0 + OpBranch %16226 + %8192 = OpLabel + %12431 = OpCompositeExtract %uint %10947 0 + %22687 = OpBitcast %int %12431 + %18206 = OpCompositeConstruct %v2int %22687 %22687 + %18353 = OpShiftLeftLogical %v2int %18206 %1959 + %13339 = OpShiftRightArithmetic %v2int %18353 %2151 + %10915 = OpConvertSToF %v2float %13339 + %18251 = OpVectorTimesScalar %v2float %10915 %float_0_000976592302 + %24074 = OpExtInst %v2float %1 FMax %73 %18251 + %24334 = OpCompositeExtract %float %24074 0 + %15574 = OpCompositeExtract %float %24074 1 + %16672 = OpCompositeConstruct %v4float %24334 %15574 %float_0 %float_0 + %19524 = OpCompositeExtract %uint %10947 1 + %16035 = OpBitcast %int %19524 + %18207 = OpCompositeConstruct %v2int %16035 %16035 + %18354 = OpShiftLeftLogical %v2int %18207 %1959 + %13340 = OpShiftRightArithmetic %v2int %18354 %2151 + %10916 = OpConvertSToF %v2float %13340 + %18252 = OpVectorTimesScalar %v2float %10916 %float_0_000976592302 + %24075 = OpExtInst %v2float %1 FMax %73 %18252 + %24335 = OpCompositeExtract %float %24075 0 + %18766 = OpCompositeExtract %float %24075 1 + %9044 = OpCompositeConstruct %v4float %24335 %18766 %float_0 %float_0 + OpBranch %16226 + %7358 = OpLabel + %22211 = OpCompositeExtract %uint %10947 0 + %20240 = OpCompositeConstruct %v3uint %22211 %22211 %22211 + %11027 = OpShiftRightLogical %v3uint %20240 %2996 + %24042 = OpBitwiseAnd %v3uint %11027 %261 + %18592 = OpBitwiseAnd %v3uint %24042 %1126 + %23444 = OpShiftRightLogical %v3uint %24042 %2828 + %16589 = OpIEqual %v3bool %23444 %2578 + %11343 = OpExtInst %v3int %1 FindUMsb %18592 + %10777 = OpBitcast %v3uint %11343 + %6270 = OpISub %v3uint %2828 %10777 + %8724 = OpIAdd %v3uint %10777 %2360 + %10355 = OpSelect %v3uint %16589 %8724 %23444 + %23256 = OpShiftLeftLogical %v3uint %18592 %6270 + %18846 = OpBitwiseAnd %v3uint %23256 %1126 + %10917 = OpSelect %v3uint %16589 %18846 %18592 + %24573 = OpIAdd %v3uint %10355 %1018 + %20355 = OpShiftLeftLogical %v3uint %24573 %393 + %16298 = OpShiftLeftLogical %v3uint %10917 %141 + %22400 = OpBitwiseOr %v3uint %20355 %16298 + %13828 = OpIEqual %v3bool %24042 %2578 + %16966 = OpSelect %v3uint %13828 %2578 %22400 + %10707 = OpBitcast %v3float %16966 + %19368 = OpShiftRightLogical %uint %22211 %uint_30 + %18450 = OpConvertUToF %float %19368 + %15907 = OpFMul %float %18450 %float_0_333333343 + %21446 = OpCompositeExtract %float %10707 0 + %10841 = OpCompositeExtract %float %10707 1 + %7835 = OpCompositeExtract %float %10707 2 + %15836 = OpCompositeConstruct %v4float %21446 %10841 %7835 %15907 + %10231 = OpCompositeExtract %uint %10947 1 + %13584 = OpCompositeConstruct %v3uint %10231 %10231 %10231 + %11028 = OpShiftRightLogical %v3uint %13584 %2996 + %24043 = OpBitwiseAnd %v3uint %11028 %261 + %18593 = OpBitwiseAnd %v3uint %24043 %1126 + %23445 = OpShiftRightLogical %v3uint %24043 %2828 + %16590 = OpIEqual %v3bool %23445 %2578 + %11344 = OpExtInst %v3int %1 FindUMsb %18593 + %10778 = OpBitcast %v3uint %11344 + %6271 = OpISub %v3uint %2828 %10778 + %8725 = OpIAdd %v3uint %10778 %2360 + %10356 = OpSelect %v3uint %16590 %8725 %23445 + %23257 = OpShiftLeftLogical %v3uint %18593 %6271 + %18847 = OpBitwiseAnd %v3uint %23257 %1126 + %10918 = OpSelect %v3uint %16590 %18847 %18593 + %24574 = OpIAdd %v3uint %10356 %1018 + %20356 = OpShiftLeftLogical %v3uint %24574 %393 + %16299 = OpShiftLeftLogical %v3uint %10918 %141 + %22401 = OpBitwiseOr %v3uint %20356 %16299 + %13829 = OpIEqual %v3bool %24043 %2578 + %16967 = OpSelect %v3uint %13829 %2578 %22401 + %10708 = OpBitcast %v3float %16967 + %19369 = OpShiftRightLogical %uint %10231 %uint_30 + %18451 = OpConvertUToF %float %19369 + %15908 = OpFMul %float %18451 %float_0_333333343 + %21447 = OpCompositeExtract %float %10708 0 + %10842 = OpCompositeExtract %float %10708 1 + %11029 = OpCompositeExtract %float %10708 2 + %9045 = OpCompositeConstruct %v4float %21447 %10842 %11029 %15908 + OpBranch %16226 + %7360 = OpLabel + %22212 = OpCompositeExtract %uint %10947 0 + %20241 = OpCompositeConstruct %v4uint %22212 %22212 %22212 %22212 + %9376 = OpShiftRightLogical %v4uint %20241 %845 + %18863 = OpBitwiseAnd %v4uint %9376 %635 + %15545 = OpConvertUToF %v4float %18863 + %16690 = OpFMul %v4float %15545 %2798 + %23764 = OpCompositeExtract %uint %10947 1 + %20815 = OpCompositeConstruct %v4uint %23764 %23764 %23764 %23764 + %9377 = OpShiftRightLogical %v4uint %20815 %845 + %18864 = OpBitwiseAnd %v4uint %9377 %635 + %18737 = OpConvertUToF %v4float %18864 + %9889 = OpFMul %v4float %18737 %2798 + OpBranch %16226 + %14587 = OpLabel + %22213 = OpCompositeExtract %uint %10947 0 + %20242 = OpCompositeConstruct %v4uint %22213 %22213 %22213 %22213 + %9378 = OpShiftRightLogical %v4uint %20242 %653 + %19034 = OpBitwiseAnd %v4uint %9378 %1611 + %13988 = OpConvertUToF %v4float %19034 + %19237 = OpVectorTimesScalar %v4float %13988 %float_0_00392156886 + %8609 = OpCompositeExtract %uint %10947 1 + %24845 = OpCompositeConstruct %v4uint %8609 %8609 %8609 %8609 + %9379 = OpShiftRightLogical %v4uint %24845 %653 + %19035 = OpBitwiseAnd %v4uint %9379 %1611 + %17180 = OpConvertUToF %v4float %19035 + %12436 = OpVectorTimesScalar %v4float %17180 %float_0_00392156886 + OpBranch %16226 + %19453 = OpLabel + %12432 = OpCompositeExtract %uint %10947 0 + %20464 = OpBitcast %float %12432 + %17208 = OpCompositeConstruct %v2float %20464 %float_0 + %11666 = OpVectorShuffle %v4float %17208 %17208 0 1 1 1 + %22195 = OpCompositeExtract %uint %10947 1 + %16234 = OpBitcast %float %22195 + %20400 = OpCompositeConstruct %v2float %16234 %float_0 + %23100 = OpVectorShuffle %v4float %20400 %20400 0 1 1 1 + OpBranch %16226 + %16226 = OpLabel + %11255 = OpPhi %v4float %23100 %19453 %12436 %14587 %9889 %7360 %9045 %7358 %9044 %8192 %9043 %8247 + %13714 = OpPhi %v4float %11666 %19453 %19237 %14587 %16690 %7360 %15836 %7358 %16672 %8192 %14608 %8247 + OpBranch %21265 + %15207 = OpLabel + %21586 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20302 DontFlatten + OpBranchConditional %21586 %9768 %12134 + %12134 = OpLabel + %19412 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23885 = OpLoad %uint %19412 + %11705 = OpIAdd %uint %20988 %uint_1 + %6407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11705 + %23658 = OpLoad %uint %6407 + %11706 = OpIAdd %uint %20988 %6555 + %6408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11706 + %23659 = OpLoad %uint %6408 + %11707 = OpIAdd %uint %11706 %uint_1 + %24568 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11707 + %16390 = OpLoad %uint %24568 + %20790 = OpCompositeConstruct %v4uint %23885 %23658 %23659 %16390 + OpBranch %20302 + %9768 = OpLabel + %21834 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23886 = OpLoad %uint %21834 + %11708 = OpIAdd %uint %20988 %uint_1 + %6409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11708 + %23660 = OpLoad %uint %6409 + %11709 = OpIAdd %uint %20988 %uint_2 + %6410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11709 + %23661 = OpLoad %uint %6410 + %11710 = OpIAdd %uint %20988 %uint_3 + %24575 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11710 + %16391 = OpLoad %uint %24575 + %20791 = OpCompositeConstruct %v4uint %23886 %23660 %23661 %16391 + OpBranch %20302 + %20302 = OpLabel + %10948 = OpPhi %v4uint %20791 %9768 %20790 %12134 + OpSelectionMerge %20261 None + OpSwitch %8576 %20312 5 %8538 7 %8248 + %8248 = OpLabel + %24411 = OpCompositeExtract %uint %10948 0 + %24684 = OpExtInst %v2float %1 UnpackHalf2x16 %24411 + %10105 = OpCompositeExtract %float %24684 0 + %16060 = OpCompositeExtract %float %24684 1 + %17029 = OpCompositeExtract %uint %10948 1 + %15609 = OpExtInst %v2float %1 UnpackHalf2x16 %17029 + %10092 = OpCompositeExtract %float %15609 0 + %17483 = OpCompositeExtract %float %15609 1 + %14609 = OpCompositeConstruct %v4float %10105 %16060 %10092 %17483 + %17279 = OpCompositeExtract %uint %10948 2 + %18032 = OpExtInst %v2float %1 UnpackHalf2x16 %17279 + %10106 = OpCompositeExtract %float %18032 0 + %16061 = OpCompositeExtract %float %18032 1 + %17030 = OpCompositeExtract %uint %10948 3 + %15610 = OpExtInst %v2float %1 UnpackHalf2x16 %17030 + %10093 = OpCompositeExtract %float %15610 0 + %20675 = OpCompositeExtract %float %15610 1 + %9046 = OpCompositeConstruct %v4float %10106 %16061 %10093 %20675 + OpBranch %20261 + %8538 = OpLabel + %9725 = OpVectorShuffle %v2uint %10948 %10948 0 1 + %23358 = OpBitcast %v2int %9725 + %24786 = OpVectorShuffle %v4int %23358 %23358 0 0 1 1 + %18602 = OpShiftLeftLogical %v4int %24786 %290 + %15761 = OpShiftRightArithmetic %v4int %18602 %770 + %10919 = OpConvertSToF %v4float %15761 + %18211 = OpVectorTimesScalar %v4float %10919 %float_0_000976592302 + %25235 = OpExtInst %v4float %1 FMax %1284 %18211 + %14189 = OpVectorShuffle %v2uint %10948 %10948 2 3 + %9409 = OpBitcast %v2int %14189 + %24787 = OpVectorShuffle %v4int %9409 %9409 0 0 1 1 + %18603 = OpShiftLeftLogical %v4int %24787 %290 + %15762 = OpShiftRightArithmetic %v4int %18603 %770 + %10920 = OpConvertSToF %v4float %15762 + %21441 = OpVectorTimesScalar %v4float %10920 %float_0_000976592302 + %17252 = OpExtInst %v4float %1 FMax %1284 %21441 + OpBranch %20261 + %20312 = OpLabel + %9769 = OpVectorShuffle %v2uint %10948 %10948 0 1 + %20827 = OpBitcast %v2float %9769 + %7040 = OpCompositeExtract %float %20827 0 + %13420 = OpCompositeExtract %float %20827 1 + %17018 = OpCompositeConstruct %v4float %7040 %13420 %float_0 %float_0 + %16858 = OpVectorShuffle %v2uint %10948 %10948 2 3 + %14175 = OpBitcast %v2float %16858 + %7041 = OpCompositeExtract %float %14175 0 + %16650 = OpCompositeExtract %float %14175 1 + %9047 = OpCompositeConstruct %v4float %7041 %16650 %float_0 %float_0 + OpBranch %20261 + %20261 = OpLabel + %11256 = OpPhi %v4float %9047 %20312 %17252 %8538 %9046 %8248 + %13715 = OpPhi %v4float %17018 %20312 %25235 %8538 %14609 %8248 + OpBranch %21265 + %21265 = OpLabel + %8972 = OpPhi %v4float %11256 %20261 %11255 %16226 + %19595 = OpPhi %v4float %13715 %20261 %13714 %16226 + %17222 = OpFAdd %v4float %18096 %19595 + %6641 = OpFAdd %v4float %17754 %8972 + %16376 = OpIAdd %uint %8114 %14258 + OpSelectionMerge %21266 DontFlatten + OpBranchConditional %23279 %15208 %16572 + %16572 = OpLabel + %19166 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20303 DontFlatten + OpBranchConditional %19166 %9770 %12135 + %12135 = OpLabel + %19413 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23887 = OpLoad %uint %19413 + %11711 = OpIAdd %uint %16376 %6555 + %24576 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11711 + %16392 = OpLoad %uint %24576 + %20792 = OpCompositeConstruct %v2uint %23887 %16392 + OpBranch %20303 + %9770 = OpLabel + %21835 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23888 = OpLoad %uint %21835 + %11712 = OpIAdd %uint %16376 %uint_1 + %24577 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11712 + %16393 = OpLoad %uint %24577 + %20793 = OpCompositeConstruct %v2uint %23888 %16393 + OpBranch %20303 + %20303 = OpLabel + %10949 = OpPhi %v2uint %20793 %9770 %20792 %12135 + OpSelectionMerge %16227 None + OpSwitch %8576 %19454 0 %14588 1 %14588 2 %7362 10 %7362 3 %7361 12 %7361 4 %8193 6 %8249 + %8249 = OpLabel + %24412 = OpCompositeExtract %uint %10949 0 + %24685 = OpExtInst %v2float %1 UnpackHalf2x16 %24412 + %10094 = OpCompositeExtract %float %24685 0 + %17484 = OpCompositeExtract %float %24685 1 + %14610 = OpCompositeConstruct %v4float %10094 %17484 %float_0 %float_0 + %17280 = OpCompositeExtract %uint %10949 1 + %18033 = OpExtInst %v2float %1 UnpackHalf2x16 %17280 + %10095 = OpCompositeExtract %float %18033 0 + %20676 = OpCompositeExtract %float %18033 1 + %9048 = OpCompositeConstruct %v4float %10095 %20676 %float_0 %float_0 + OpBranch %16227 + %8193 = OpLabel + %12433 = OpCompositeExtract %uint %10949 0 + %22688 = OpBitcast %int %12433 + %18208 = OpCompositeConstruct %v2int %22688 %22688 + %18355 = OpShiftLeftLogical %v2int %18208 %1959 + %13341 = OpShiftRightArithmetic %v2int %18355 %2151 + %10921 = OpConvertSToF %v2float %13341 + %18253 = OpVectorTimesScalar %v2float %10921 %float_0_000976592302 + %24076 = OpExtInst %v2float %1 FMax %73 %18253 + %24336 = OpCompositeExtract %float %24076 0 + %15575 = OpCompositeExtract %float %24076 1 + %16673 = OpCompositeConstruct %v4float %24336 %15575 %float_0 %float_0 + %19525 = OpCompositeExtract %uint %10949 1 + %16036 = OpBitcast %int %19525 + %18212 = OpCompositeConstruct %v2int %16036 %16036 + %18356 = OpShiftLeftLogical %v2int %18212 %1959 + %13342 = OpShiftRightArithmetic %v2int %18356 %2151 + %10922 = OpConvertSToF %v2float %13342 + %18254 = OpVectorTimesScalar %v2float %10922 %float_0_000976592302 + %24077 = OpExtInst %v2float %1 FMax %73 %18254 + %24337 = OpCompositeExtract %float %24077 0 + %18767 = OpCompositeExtract %float %24077 1 + %9049 = OpCompositeConstruct %v4float %24337 %18767 %float_0 %float_0 + OpBranch %16227 + %7361 = OpLabel + %22214 = OpCompositeExtract %uint %10949 0 + %20243 = OpCompositeConstruct %v3uint %22214 %22214 %22214 + %11030 = OpShiftRightLogical %v3uint %20243 %2996 + %24044 = OpBitwiseAnd %v3uint %11030 %261 + %18594 = OpBitwiseAnd %v3uint %24044 %1126 + %23446 = OpShiftRightLogical %v3uint %24044 %2828 + %16591 = OpIEqual %v3bool %23446 %2578 + %11345 = OpExtInst %v3int %1 FindUMsb %18594 + %10779 = OpBitcast %v3uint %11345 + %6272 = OpISub %v3uint %2828 %10779 + %8726 = OpIAdd %v3uint %10779 %2360 + %10357 = OpSelect %v3uint %16591 %8726 %23446 + %23258 = OpShiftLeftLogical %v3uint %18594 %6272 + %18848 = OpBitwiseAnd %v3uint %23258 %1126 + %10923 = OpSelect %v3uint %16591 %18848 %18594 + %24578 = OpIAdd %v3uint %10357 %1018 + %20357 = OpShiftLeftLogical %v3uint %24578 %393 + %16300 = OpShiftLeftLogical %v3uint %10923 %141 + %22402 = OpBitwiseOr %v3uint %20357 %16300 + %13830 = OpIEqual %v3bool %24044 %2578 + %16968 = OpSelect %v3uint %13830 %2578 %22402 + %10709 = OpBitcast %v3float %16968 + %19370 = OpShiftRightLogical %uint %22214 %uint_30 + %18452 = OpConvertUToF %float %19370 + %15909 = OpFMul %float %18452 %float_0_333333343 + %21448 = OpCompositeExtract %float %10709 0 + %10843 = OpCompositeExtract %float %10709 1 + %7836 = OpCompositeExtract %float %10709 2 + %15837 = OpCompositeConstruct %v4float %21448 %10843 %7836 %15909 + %10232 = OpCompositeExtract %uint %10949 1 + %13585 = OpCompositeConstruct %v3uint %10232 %10232 %10232 + %11031 = OpShiftRightLogical %v3uint %13585 %2996 + %24045 = OpBitwiseAnd %v3uint %11031 %261 + %18595 = OpBitwiseAnd %v3uint %24045 %1126 + %23447 = OpShiftRightLogical %v3uint %24045 %2828 + %16592 = OpIEqual %v3bool %23447 %2578 + %11346 = OpExtInst %v3int %1 FindUMsb %18595 + %10780 = OpBitcast %v3uint %11346 + %6273 = OpISub %v3uint %2828 %10780 + %8727 = OpIAdd %v3uint %10780 %2360 + %10358 = OpSelect %v3uint %16592 %8727 %23447 + %23259 = OpShiftLeftLogical %v3uint %18595 %6273 + %18849 = OpBitwiseAnd %v3uint %23259 %1126 + %10924 = OpSelect %v3uint %16592 %18849 %18595 + %24579 = OpIAdd %v3uint %10358 %1018 + %20358 = OpShiftLeftLogical %v3uint %24579 %393 + %16301 = OpShiftLeftLogical %v3uint %10924 %141 + %22403 = OpBitwiseOr %v3uint %20358 %16301 + %13831 = OpIEqual %v3bool %24045 %2578 + %16969 = OpSelect %v3uint %13831 %2578 %22403 + %10710 = OpBitcast %v3float %16969 + %19371 = OpShiftRightLogical %uint %10232 %uint_30 + %18453 = OpConvertUToF %float %19371 + %15910 = OpFMul %float %18453 %float_0_333333343 + %21449 = OpCompositeExtract %float %10710 0 + %10844 = OpCompositeExtract %float %10710 1 + %11032 = OpCompositeExtract %float %10710 2 + %9050 = OpCompositeConstruct %v4float %21449 %10844 %11032 %15910 + OpBranch %16227 + %7362 = OpLabel + %22215 = OpCompositeExtract %uint %10949 0 + %20244 = OpCompositeConstruct %v4uint %22215 %22215 %22215 %22215 + %9380 = OpShiftRightLogical %v4uint %20244 %845 + %18865 = OpBitwiseAnd %v4uint %9380 %635 + %15546 = OpConvertUToF %v4float %18865 + %16691 = OpFMul %v4float %15546 %2798 + %23765 = OpCompositeExtract %uint %10949 1 + %20816 = OpCompositeConstruct %v4uint %23765 %23765 %23765 %23765 + %9381 = OpShiftRightLogical %v4uint %20816 %845 + %18866 = OpBitwiseAnd %v4uint %9381 %635 + %18738 = OpConvertUToF %v4float %18866 + %9890 = OpFMul %v4float %18738 %2798 + OpBranch %16227 + %14588 = OpLabel + %22216 = OpCompositeExtract %uint %10949 0 + %20245 = OpCompositeConstruct %v4uint %22216 %22216 %22216 %22216 + %9382 = OpShiftRightLogical %v4uint %20245 %653 + %19036 = OpBitwiseAnd %v4uint %9382 %1611 + %13989 = OpConvertUToF %v4float %19036 + %19238 = OpVectorTimesScalar %v4float %13989 %float_0_00392156886 + %8610 = OpCompositeExtract %uint %10949 1 + %24846 = OpCompositeConstruct %v4uint %8610 %8610 %8610 %8610 + %9383 = OpShiftRightLogical %v4uint %24846 %653 + %19037 = OpBitwiseAnd %v4uint %9383 %1611 + %17181 = OpConvertUToF %v4float %19037 + %12437 = OpVectorTimesScalar %v4float %17181 %float_0_00392156886 + OpBranch %16227 + %19454 = OpLabel + %12438 = OpCompositeExtract %uint %10949 0 + %20465 = OpBitcast %float %12438 + %17209 = OpCompositeConstruct %v2float %20465 %float_0 + %11667 = OpVectorShuffle %v4float %17209 %17209 0 1 1 1 + %22196 = OpCompositeExtract %uint %10949 1 + %16235 = OpBitcast %float %22196 + %20401 = OpCompositeConstruct %v2float %16235 %float_0 + %23101 = OpVectorShuffle %v4float %20401 %20401 0 1 1 1 + OpBranch %16227 + %16227 = OpLabel + %11257 = OpPhi %v4float %23101 %19454 %12437 %14588 %9890 %7362 %9050 %7361 %9049 %8193 %9048 %8249 + %13716 = OpPhi %v4float %11667 %19454 %19238 %14588 %16691 %7362 %15837 %7361 %16673 %8193 %14610 %8249 + OpBranch %21266 + %15208 = OpLabel + %21587 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20304 DontFlatten + OpBranchConditional %21587 %9771 %12136 + %12136 = OpLabel + %19414 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23889 = OpLoad %uint %19414 + %11713 = OpIAdd %uint %16376 %uint_1 + %6411 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11713 + %23662 = OpLoad %uint %6411 + %11714 = OpIAdd %uint %16376 %6555 + %6412 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11714 + %23663 = OpLoad %uint %6412 + %11715 = OpIAdd %uint %11714 %uint_1 + %24580 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11715 + %16394 = OpLoad %uint %24580 + %20794 = OpCompositeConstruct %v4uint %23889 %23662 %23663 %16394 + OpBranch %20304 + %9771 = OpLabel + %21836 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23890 = OpLoad %uint %21836 + %11716 = OpIAdd %uint %16376 %uint_1 + %6413 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11716 + %23664 = OpLoad %uint %6413 + %11717 = OpIAdd %uint %16376 %uint_2 + %6414 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11717 + %23665 = OpLoad %uint %6414 + %11718 = OpIAdd %uint %16376 %uint_3 + %24581 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11718 + %16395 = OpLoad %uint %24581 + %20795 = OpCompositeConstruct %v4uint %23890 %23664 %23665 %16395 + OpBranch %20304 + %20304 = OpLabel + %10950 = OpPhi %v4uint %20795 %9771 %20794 %12136 + OpSelectionMerge %20262 None + OpSwitch %8576 %20313 5 %8539 7 %8250 + %8250 = OpLabel + %24413 = OpCompositeExtract %uint %10950 0 + %24686 = OpExtInst %v2float %1 UnpackHalf2x16 %24413 + %10107 = OpCompositeExtract %float %24686 0 + %16062 = OpCompositeExtract %float %24686 1 + %17031 = OpCompositeExtract %uint %10950 1 + %15611 = OpExtInst %v2float %1 UnpackHalf2x16 %17031 + %10096 = OpCompositeExtract %float %15611 0 + %17485 = OpCompositeExtract %float %15611 1 + %14611 = OpCompositeConstruct %v4float %10107 %16062 %10096 %17485 + %17281 = OpCompositeExtract %uint %10950 2 + %18034 = OpExtInst %v2float %1 UnpackHalf2x16 %17281 + %10108 = OpCompositeExtract %float %18034 0 + %16063 = OpCompositeExtract %float %18034 1 + %17032 = OpCompositeExtract %uint %10950 3 + %15612 = OpExtInst %v2float %1 UnpackHalf2x16 %17032 + %10097 = OpCompositeExtract %float %15612 0 + %20677 = OpCompositeExtract %float %15612 1 + %9051 = OpCompositeConstruct %v4float %10108 %16063 %10097 %20677 + OpBranch %20262 + %8539 = OpLabel + %9726 = OpVectorShuffle %v2uint %10950 %10950 0 1 + %23359 = OpBitcast %v2int %9726 + %24788 = OpVectorShuffle %v4int %23359 %23359 0 0 1 1 + %18604 = OpShiftLeftLogical %v4int %24788 %290 + %15763 = OpShiftRightArithmetic %v4int %18604 %770 + %10925 = OpConvertSToF %v4float %15763 + %18213 = OpVectorTimesScalar %v4float %10925 %float_0_000976592302 + %25236 = OpExtInst %v4float %1 FMax %1284 %18213 + %14190 = OpVectorShuffle %v2uint %10950 %10950 2 3 + %9410 = OpBitcast %v2int %14190 + %24789 = OpVectorShuffle %v4int %9410 %9410 0 0 1 1 + %18605 = OpShiftLeftLogical %v4int %24789 %290 + %15764 = OpShiftRightArithmetic %v4int %18605 %770 + %10926 = OpConvertSToF %v4float %15764 + %21450 = OpVectorTimesScalar %v4float %10926 %float_0_000976592302 + %17253 = OpExtInst %v4float %1 FMax %1284 %21450 + OpBranch %20262 + %20313 = OpLabel + %9772 = OpVectorShuffle %v2uint %10950 %10950 0 1 + %20828 = OpBitcast %v2float %9772 + %7042 = OpCompositeExtract %float %20828 0 + %13421 = OpCompositeExtract %float %20828 1 + %17019 = OpCompositeConstruct %v4float %7042 %13421 %float_0 %float_0 + %16859 = OpVectorShuffle %v2uint %10950 %10950 2 3 + %14176 = OpBitcast %v2float %16859 + %7043 = OpCompositeExtract %float %14176 0 + %16651 = OpCompositeExtract %float %14176 1 + %9052 = OpCompositeConstruct %v4float %7043 %16651 %float_0 %float_0 + OpBranch %20262 + %20262 = OpLabel + %11258 = OpPhi %v4float %9052 %20313 %17253 %8539 %9051 %8250 + %13717 = OpPhi %v4float %17019 %20313 %25236 %8539 %14611 %8250 + OpBranch %21266 + %21266 = OpLabel + %8973 = OpPhi %v4float %11258 %20262 %11257 %16227 + %19596 = OpPhi %v4float %13717 %20262 %13716 %16227 + %19521 = OpFAdd %v4float %17222 %19596 + %23869 = OpFAdd %v4float %6641 %8973 + OpBranch %24264 + %24264 = OpLabel + %11175 = OpPhi %v4float %17754 %21264 %23869 %21266 + %14420 = OpPhi %v4float %18096 %21264 %19521 %21266 + %14518 = OpPhi %float %23069 %21264 %12090 %21266 + OpBranch %21267 + %21267 = OpLabel + %11176 = OpPhi %v4float %9826 %21263 %11175 %24264 + %12387 = OpPhi %v4float %14051 %21263 %14420 %24264 + %11944 = OpPhi %float %11052 %21263 %14518 %24264 + %25151 = OpVectorTimesScalar %v4float %12387 %11944 + %9562 = OpVectorTimesScalar %v4float %11176 %11944 + OpSelectionMerge %16228 DontFlatten + OpBranchConditional %7513 %10049 %16228 + %10049 = OpLabel + %18316 = OpVectorShuffle %v4float %25151 %25151 2 1 0 3 + %20341 = OpVectorShuffle %v4float %9562 %9562 2 1 0 3 + OpBranch %16228 + %16228 = OpLabel + %9864 = OpPhi %v4float %9562 %21267 %20341 %10049 + %13705 = OpPhi %v4float %25151 %21267 %18316 %10049 + %14546 = OpULessThan %bool %7640 %7359 + OpSelectionMerge %24688 DontFlatten + OpBranchConditional %14546 %21994 %24688 + %21994 = OpLabel + OpBranch %24688 + %24688 = OpLabel + %10236 = OpPhi %v4float %9864 %16228 %13705 %21994 + %10234 = OpIAdd %v2uint %12025 %23020 + %9053 = OpUDiv %v2uint %10234 %23601 + %21164 = OpCompositeExtract %uint %9053 0 + %18218 = OpCompositeExtract %uint %9053 1 + %9417 = OpCompositeConstruct %v3uint %21164 %18218 %17416 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %20495 %22217 %10927 + %10927 = OpLabel + %7339 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %7339 + %6415 = OpCompositeExtract %int %22991 0 + %9469 = OpShiftRightArithmetic %int %6415 %int_5 + %10055 = OpCompositeExtract %int %22991 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %15783 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_11 + %10934 = OpBitwiseAnd %int %6415 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17303 = OpIAdd %int %10934 %17741 + %6375 = OpShiftLeftLogical %int %17303 %uint_4 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15435 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18357 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6415 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21588 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21588 %int_6 + %15436 = OpIAdd %int %16708 %21580 + %11782 = OpBitwiseAnd %int %16727 %int_63 + %14671 = OpIAdd %int %15436 %11782 + %22127 = OpBitcast %uint %14671 + OpBranch %21313 + %22217 = OpLabel + %6573 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %6573 1 + %9470 = OpShiftRightArithmetic %int %17090 %int_4 + %10056 = OpCompositeExtract %int %6573 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %25203 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %15783 %uint_5 + %12439 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12439 + %25154 = OpCompositeExtract %int %6573 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_10 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12601 = OpBitwiseAnd %int %17090 %int_6 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7048 = OpShiftLeftLogical %int %17227 %uint_10 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8728 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8728 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19168 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19168 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18358 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18358 %uint_10 + %16729 = OpIAdd %int %10332 %21582 + %19169 = OpBitwiseAnd %int %17090 %int_1 + %21583 = OpShiftLeftLogical %int %19169 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10928 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10928 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10929 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10929 %int_3 + %21849 = OpBitwiseAnd %int %16730 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22128 = OpBitcast %uint %24314 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22128 %22217 %22127 %10927 + %16302 = OpIMul %v2uint %9053 %23601 + %16261 = OpISub %v2uint %10234 %16302 + %17551 = OpCompositeExtract %uint %23601 1 + %23632 = OpIMul %uint %8858 %17551 + %15520 = OpIMul %uint %9468 %23632 + %16084 = OpCompositeExtract %uint %16261 0 + %15890 = OpIMul %uint %16084 %17551 + %6887 = OpCompositeExtract %uint %16261 1 + %9697 = OpIAdd %uint %15890 %6887 + %19199 = OpShiftLeftLogical %uint %9697 %uint_4 + %7390 = OpIAdd %uint %15520 %19199 + %16171 = OpShiftRightLogical %uint %7390 %uint_4 + %9007 = OpBitcast %v4uint %13705 + %8174 = OpIEqual %bool %19164 %uint_5 + OpSelectionMerge %14780 None + OpBranchConditional %8174 %13279 %14780 + %13279 = OpLabel + %7958 = OpVectorShuffle %v4uint %9007 %9007 3 2 1 0 + OpBranch %14780 + %14780 = OpLabel + %22898 = OpPhi %v4uint %9007 %21313 %7958 %13279 + %8068 = OpSelect %uint %8174 %uint_2 %19164 + %20758 = OpIEqual %bool %8068 %uint_4 + OpSelectionMerge %14781 None + OpBranchConditional %20758 %13280 %14781 + %13280 = OpLabel + %7959 = OpVectorShuffle %v4uint %22898 %22898 1 0 3 2 + OpBranch %14781 + %14781 = OpLabel + %22899 = OpPhi %v4uint %22898 %14780 %7959 %13280 + %6605 = OpSelect %uint %20758 %uint_2 %8068 + %13412 = OpIEqual %bool %6605 %uint_1 + %18370 = OpIEqual %bool %6605 %uint_2 + %22150 = OpLogicalOr %bool %13412 %18370 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %22899 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %22899 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16377 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22650 = OpPhi %v4uint %22899 %14781 %16377 %10583 + %19638 = OpIEqual %bool %6605 %uint_3 + %15139 = OpLogicalOr %bool %18370 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22650 %749 + %15335 = OpShiftRightLogical %v4uint %22650 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22650 %13411 %10728 %11064 + %6590 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %16171 + OpStore %6590 %19767 + %23542 = OpUGreaterThan %bool %8858 %uint_1 + OpSelectionMerge %19116 DontFlatten + OpBranchConditional %23542 %24896 %21995 + %21995 = OpLabel + OpBranch %19116 + %24896 = OpLabel + %9940 = OpUDiv %uint %7640 %8858 + %9086 = OpIMul %uint %9940 %8858 + %12657 = OpISub %uint %7640 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %8858 + OpSelectionMerge %9304 None + OpBranchConditional %13375 %7387 %21996 + %21996 = OpLabel + OpBranch %9304 + %7387 = OpLabel + %15254 = OpIMul %uint %uint_32 %8858 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %15254 %21519 + OpBranch %9304 + %9304 = OpLabel + %10540 = OpPhi %uint %18756 %7387 %uint_16 %21996 + OpBranch %19116 + %19116 = OpLabel + %10684 = OpPhi %uint %10540 %9304 %uint_32 %21995 + %18731 = OpIMul %uint %10684 %17551 + %17614 = OpShiftRightLogical %uint %18731 %uint_4 + %6490 = OpIAdd %uint %16171 %17614 + %21707 = OpBitcast %v4uint %10236 + OpSelectionMerge %16262 None + OpBranchConditional %8174 %13281 %16262 + %13281 = OpLabel + %7960 = OpVectorShuffle %v4uint %21707 %21707 3 2 1 0 + OpBranch %16262 + %16262 = OpLabel + %10930 = OpPhi %v4uint %21707 %19116 %7960 %13281 + OpSelectionMerge %16263 None + OpBranchConditional %20758 %13282 %16263 + %13282 = OpLabel + %7961 = OpVectorShuffle %v4uint %10930 %10930 1 0 3 2 + OpBranch %16263 + %16263 = OpLabel + %10931 = OpPhi %v4uint %10930 %16262 %7961 %13282 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %10931 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %10931 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16378 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10932 = OpPhi %v4uint %10931 %16263 %16378 %10584 + OpSelectionMerge %11417 None + OpBranchConditional %15139 %11065 %11417 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10932 %749 + %15336 = OpShiftRightLogical %v4uint %10932 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %10932 %14874 %10729 %11065 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %6490 + OpStore %8053 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_full_128bpp_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006295, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00040047, 0x000007D0, 0x00000006, 0x00000004, + 0x00030047, 0x0000079C, 0x00000003, 0x00040048, 0x0000079C, 0x00000000, 0x00000018, 0x00050048, + 0x0000079C, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000CC7, 0x00000018, 0x00040047, + 0x00000CC7, 0x00000021, 0x00000000, 0x00040047, 0x00000CC7, 0x00000022, 0x00000000, 0x00030047, + 0x000003F9, 0x00000002, 0x00050048, 0x000003F9, 0x00000000, 0x00000023, 0x00000000, 0x00050048, + 0x000003F9, 0x00000001, 0x00000023, 0x00000004, 0x00050048, 0x000003F9, 0x00000002, 0x00000023, + 0x00000008, 0x00050048, 0x000003F9, 0x00000003, 0x00000023, 0x0000000C, 0x00040047, 0x00000F48, + 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, 0x000007B4, + 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000019, 0x00050048, 0x000007B4, 0x00000000, + 0x00000023, 0x00000000, 0x00030047, 0x00001592, 0x00000019, 0x00040047, 0x00001592, 0x00000021, + 0x00000000, 0x00040047, 0x00001592, 0x00000022, 0x00000001, 0x00040047, 0x00000AC7, 0x0000000B, + 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040015, 0x0000000B, + 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, + 0x0000000B, 0x00000003, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00030016, 0x0000000D, + 0x00000020, 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x00040017, 0x0000001D, 0x0000000D, + 0x00000004, 0x00020014, 0x00000009, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, + 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, + 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, + 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, + 0x0000000B, 0x00000A52, 0x00000018, 0x0007002C, 0x00000017, 0x0000028D, 0x00000A0A, 0x00000A22, + 0x00000A3A, 0x00000A52, 0x0004002B, 0x0000000B, 0x00000144, 0x000000FF, 0x0004002B, 0x0000000D, + 0x0000017A, 0x3B808081, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, + 0x00000A46, 0x00000014, 0x0004002B, 0x0000000B, 0x00000A64, 0x0000001E, 0x0007002C, 0x00000017, + 0x0000034D, 0x00000A0A, 0x00000A28, 0x00000A46, 0x00000A64, 0x0004002B, 0x0000000B, 0x00000A44, + 0x000003FF, 0x0007002C, 0x00000017, 0x0000027B, 0x00000A44, 0x00000A44, 0x00000A44, 0x00000A13, + 0x0004002B, 0x0000000D, 0x000006FE, 0x3A802008, 0x0004002B, 0x0000000D, 0x00000149, 0x3EAAAAAB, + 0x0007002C, 0x0000001D, 0x00000AEE, 0x000006FE, 0x000006FE, 0x000006FE, 0x00000149, 0x0006002C, + 0x00000014, 0x00000BB4, 0x00000A0A, 0x00000A28, 0x00000A46, 0x0004002B, 0x0000000B, 0x00000B87, + 0x0000007F, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x00040017, 0x00000010, 0x00000009, + 0x00000003, 0x0004002B, 0x0000000B, 0x00000B7E, 0x0000007C, 0x0004002B, 0x0000000B, 0x00000A4F, + 0x00000017, 0x00040017, 0x00000018, 0x0000000D, 0x00000003, 0x0004002B, 0x0000000D, 0x00000341, + 0xBF800000, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000A0B, + 0x00000000, 0x0005002C, 0x00000012, 0x000007A7, 0x00000A3B, 0x00000A0B, 0x0004002B, 0x0000000D, + 0x000007FE, 0x3A800100, 0x00040017, 0x0000001A, 0x0000000C, 0x00000004, 0x0007002C, 0x0000001A, + 0x00000122, 0x00000A3B, 0x00000A0B, 0x00000A3B, 0x00000A0B, 0x0005002C, 0x00000011, 0x0000072D, + 0x00000A10, 0x00000A0D, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0005002C, 0x00000011, + 0x0000070F, 0x00000A0A, 0x00000A0A, 0x0005002C, 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, + 0x0005002C, 0x00000011, 0x00000718, 0x00000A0D, 0x00000A0A, 0x0004002B, 0x0000000B, 0x00000AFA, + 0x00000050, 0x0005002C, 0x00000011, 0x00000A9F, 0x00000AFA, 0x00000A3A, 0x0004002B, 0x0000000B, + 0x00000A84, 0x00000800, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000C, + 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, + 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, + 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, + 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, + 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, + 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, + 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, 0x0004002B, 0x0000000C, + 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, + 0x00000A6A, 0x00000020, 0x0003001D, 0x000007D0, 0x0000000B, 0x0003001E, 0x0000079C, 0x000007D0, + 0x00040020, 0x00000A1B, 0x00000002, 0x0000079C, 0x0004003B, 0x00000A1B, 0x00000CC7, 0x00000002, + 0x00040020, 0x00000288, 0x00000002, 0x0000000B, 0x0006001E, 0x000003F9, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000676, 0x00000009, 0x000003F9, 0x0004003B, 0x00000676, + 0x00000CE9, 0x00000009, 0x00040020, 0x00000289, 0x00000009, 0x0000000B, 0x0004002B, 0x0000000B, + 0x00000A31, 0x0000000D, 0x0004002B, 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, + 0x00000A37, 0x0000000F, 0x0004002B, 0x0000000B, 0x00000A5E, 0x0000001C, 0x0004002B, 0x0000000B, + 0x00000A43, 0x00000013, 0x0005002C, 0x00000011, 0x00000883, 0x00000A3A, 0x00000A43, 0x0004002B, + 0x0000000B, 0x00000510, 0x20000000, 0x0005002C, 0x00000011, 0x0000073F, 0x00000A0A, 0x00000A16, + 0x0004002B, 0x0000000C, 0x00000A29, 0x0000000A, 0x0004002B, 0x0000000C, 0x00000A59, 0x0000001A, + 0x0004002B, 0x0000000C, 0x00000A50, 0x00000017, 0x0004002B, 0x0000000B, 0x00000926, 0x01000000, + 0x0005002C, 0x00000011, 0x000008E3, 0x00000A46, 0x00000A52, 0x0004002B, 0x0000000D, 0x00000A0C, + 0x00000000, 0x0004002B, 0x0000000D, 0x000000FC, 0x3F000000, 0x00040020, 0x00000291, 0x00000001, + 0x00000014, 0x0004003B, 0x00000291, 0x00000F48, 0x00000001, 0x0003001D, 0x000007DC, 0x00000017, + 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, 0x0004003B, + 0x00000A32, 0x00001592, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0006002C, + 0x00000014, 0x00000AC7, 0x00000A22, 0x00000A22, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, + 0x00000A1F, 0x00000A1F, 0x0005002C, 0x00000011, 0x000007A3, 0x00000A37, 0x00000A0D, 0x0005002C, + 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, 0x0005002C, 0x00000011, 0x0000084A, 0x00000A37, + 0x00000A37, 0x0007002C, 0x0000001D, 0x00000504, 0x00000341, 0x00000341, 0x00000341, 0x00000341, + 0x0007002C, 0x0000001A, 0x00000302, 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x0007002C, + 0x00000017, 0x0000064B, 0x00000144, 0x00000144, 0x00000144, 0x00000144, 0x0006002C, 0x00000014, + 0x00000105, 0x00000A44, 0x00000A44, 0x00000A44, 0x0006002C, 0x00000014, 0x00000466, 0x00000B87, + 0x00000B87, 0x00000B87, 0x0006002C, 0x00000014, 0x00000B0C, 0x00000A1F, 0x00000A1F, 0x00000A1F, + 0x0006002C, 0x00000014, 0x00000A12, 0x00000A0A, 0x00000A0A, 0x00000A0A, 0x0006002C, 0x00000014, + 0x000003FA, 0x00000B7E, 0x00000B7E, 0x00000B7E, 0x0006002C, 0x00000014, 0x00000189, 0x00000A4F, + 0x00000A4F, 0x00000A4F, 0x0006002C, 0x00000014, 0x0000008D, 0x00000A3A, 0x00000A3A, 0x00000A3A, + 0x0005002C, 0x00000013, 0x00000049, 0x00000341, 0x00000341, 0x0005002C, 0x00000012, 0x00000867, + 0x00000A3B, 0x00000A3B, 0x0004002B, 0x0000000B, 0x00000A2B, 0x0000000B, 0x0007002C, 0x00000017, + 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, + 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, + 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x0004002B, 0x0000000C, 0x00000089, 0x3F800000, 0x0004002B, 0x0000000B, + 0x000009F8, 0xFFFFFFFA, 0x0006002C, 0x00000014, 0x00000938, 0x000009F8, 0x000009F8, 0x000009F8, + 0x0004002B, 0x0000000D, 0x0000016E, 0x3E800000, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, + 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, + 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000289, 0x000056E5, 0x00000CE9, 0x00000A0B, + 0x0004003D, 0x0000000B, 0x00003D0B, 0x000056E5, 0x00050041, 0x00000289, 0x000058AC, 0x00000CE9, + 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005158, 0x000058AC, 0x000500C7, 0x0000000B, 0x00005051, + 0x00003D0B, 0x00000A44, 0x000500C2, 0x0000000B, 0x00004E0A, 0x00003D0B, 0x00000A28, 0x000500C7, + 0x0000000B, 0x0000217E, 0x00004E0A, 0x00000A13, 0x000500C2, 0x0000000B, 0x0000520A, 0x00003D0B, + 0x00000A31, 0x000500C7, 0x0000000B, 0x0000217F, 0x0000520A, 0x00000A81, 0x000500C2, 0x0000000B, + 0x0000520B, 0x00003D0B, 0x00000A52, 0x000500C7, 0x0000000B, 0x00002180, 0x0000520B, 0x00000A37, + 0x000500C2, 0x0000000B, 0x00004994, 0x00003D0B, 0x00000A5E, 0x000500C7, 0x0000000B, 0x000023AA, + 0x00004994, 0x00000A0D, 0x00050050, 0x00000011, 0x000022A7, 0x00005158, 0x00005158, 0x000500C2, + 0x00000011, 0x000025A1, 0x000022A7, 0x00000883, 0x000500C7, 0x00000011, 0x00005C31, 0x000025A1, + 0x000007A2, 0x000500C7, 0x0000000B, 0x00005DDE, 0x00003D0B, 0x00000510, 0x000500AB, 0x00000009, + 0x00003007, 0x00005DDE, 0x00000A0A, 0x000300F7, 0x00003954, 0x00000000, 0x000400FA, 0x00003007, + 0x00004163, 0x000055E8, 0x000200F8, 0x000055E8, 0x000200F9, 0x00003954, 0x000200F8, 0x00004163, + 0x000500C2, 0x00000011, 0x00003BAE, 0x00005C31, 0x00000724, 0x000200F9, 0x00003954, 0x000200F8, + 0x00003954, 0x000700F5, 0x00000011, 0x00004AB4, 0x00003BAE, 0x00004163, 0x0000070F, 0x000055E8, + 0x000500C2, 0x00000011, 0x00001B7E, 0x000022A7, 0x0000073F, 0x000500C7, 0x00000011, 0x00002DF9, + 0x00001B7E, 0x000007A3, 0x000500C4, 0x00000011, 0x00003F4F, 0x00002DF9, 0x0000074E, 0x00050084, + 0x00000011, 0x000059EB, 0x00003F4F, 0x00005C31, 0x000500C2, 0x0000000B, 0x00003343, 0x00005158, + 0x00000A19, 0x000500C7, 0x0000000B, 0x000039C1, 0x00003343, 0x00000A81, 0x00050051, 0x0000000B, + 0x0000229A, 0x00005C31, 0x00000000, 0x00050084, 0x0000000B, 0x000059D1, 0x000039C1, 0x0000229A, + 0x00050041, 0x00000289, 0x00004E44, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x000048C4, + 0x00004E44, 0x00050041, 0x00000289, 0x000058AD, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, + 0x000051B7, 0x000058AD, 0x000500C7, 0x0000000B, 0x00004ADC, 0x000048C4, 0x00000A1F, 0x000500C7, + 0x0000000B, 0x000055EF, 0x000048C4, 0x00000A22, 0x000500AB, 0x00000009, 0x0000500F, 0x000055EF, + 0x00000A0A, 0x000500C2, 0x0000000B, 0x00002311, 0x000048C4, 0x00000A16, 0x000500C7, 0x0000000B, + 0x00004408, 0x00002311, 0x00000A1F, 0x0004007C, 0x0000000C, 0x00005988, 0x000048C4, 0x000500C4, + 0x0000000C, 0x0000358F, 0x00005988, 0x00000A29, 0x000500C3, 0x0000000C, 0x0000509C, 0x0000358F, + 0x00000A59, 0x000500C4, 0x0000000C, 0x00004702, 0x0000509C, 0x00000A50, 0x00050080, 0x0000000C, + 0x00001D26, 0x00004702, 0x00000089, 0x0004007C, 0x0000000D, 0x00002B2C, 0x00001D26, 0x000500C7, + 0x0000000B, 0x00005879, 0x000048C4, 0x00000926, 0x000500AB, 0x00000009, 0x00001D59, 0x00005879, + 0x00000A0A, 0x000500C7, 0x0000000B, 0x00001F43, 0x000051B7, 0x00000A44, 0x000500C4, 0x0000000B, + 0x00003DA7, 0x00001F43, 0x00000A19, 0x000500C2, 0x0000000B, 0x0000583F, 0x000051B7, 0x00000A28, + 0x000500C7, 0x0000000B, 0x00004BBE, 0x0000583F, 0x00000A44, 0x000500C4, 0x0000000B, 0x00006273, + 0x00004BBE, 0x00000A19, 0x00050050, 0x00000011, 0x000028B6, 0x000051B7, 0x000051B7, 0x000500C2, + 0x00000011, 0x00002891, 0x000028B6, 0x000008E3, 0x000500C7, 0x00000011, 0x00005B53, 0x00002891, + 0x0000084A, 0x000500C4, 0x00000011, 0x00003F50, 0x00005B53, 0x0000074E, 0x00050084, 0x00000011, + 0x000059EC, 0x00003F50, 0x00005C31, 0x000500C2, 0x0000000B, 0x000031C7, 0x000051B7, 0x00000A5E, + 0x000500C7, 0x0000000B, 0x00004356, 0x000031C7, 0x00000A1F, 0x0004003D, 0x00000014, 0x000031C1, + 0x00000F48, 0x0007004F, 0x00000011, 0x000038A4, 0x000031C1, 0x000031C1, 0x00000000, 0x00000001, + 0x000500C4, 0x00000011, 0x00002EF9, 0x000038A4, 0x00000718, 0x00050051, 0x0000000B, 0x00001DD8, + 0x00002EF9, 0x00000000, 0x000500C4, 0x0000000B, 0x00002D8A, 0x000059D1, 0x00000A13, 0x000500AE, + 0x00000009, 0x00003C13, 0x00001DD8, 0x00002D8A, 0x000300F7, 0x000031D3, 0x00000002, 0x000400FA, + 0x00003C13, 0x000055E9, 0x000031D3, 0x000200F8, 0x000055E9, 0x000200F9, 0x00004C7A, 0x000200F8, + 0x000031D3, 0x00050051, 0x0000000B, 0x00001CBF, 0x00004AB4, 0x00000000, 0x0007000C, 0x0000000B, + 0x00001B0E, 0x00000001, 0x00000029, 0x00001DD8, 0x00001CBF, 0x00050051, 0x0000000B, 0x00004588, + 0x00002EF9, 0x00000001, 0x00050051, 0x0000000B, 0x00001931, 0x00004AB4, 0x00000001, 0x0007000C, + 0x0000000B, 0x00005F7E, 0x00000001, 0x00000029, 0x00004588, 0x00001931, 0x00050050, 0x00000011, + 0x000051EF, 0x00001B0E, 0x00005F7E, 0x00050080, 0x00000011, 0x0000522C, 0x000051EF, 0x000059EB, + 0x000500B2, 0x00000009, 0x00003ECB, 0x00004356, 0x00000A13, 0x000300F7, 0x00005CE0, 0x00000000, + 0x000400FA, 0x00003ECB, 0x00002AEE, 0x00003AEF, 0x000200F8, 0x00003AEF, 0x000500AA, 0x00000009, + 0x000034FE, 0x00004356, 0x00000A19, 0x000600A9, 0x0000000B, 0x000020F6, 0x000034FE, 0x00000A10, + 0x00000A0A, 0x000200F9, 0x00005CE0, 0x000200F8, 0x00002AEE, 0x000200F9, 0x00005CE0, 0x000200F8, + 0x00005CE0, 0x000700F5, 0x0000000B, 0x00004B64, 0x00004356, 0x00002AEE, 0x000020F6, 0x00003AEF, + 0x00050050, 0x00000011, 0x000041BE, 0x0000217E, 0x0000217E, 0x000500AE, 0x0000000F, 0x00002E19, + 0x000041BE, 0x0000072D, 0x000600A9, 0x00000011, 0x00004BB5, 0x00002E19, 0x00000724, 0x0000070F, + 0x000500C4, 0x00000011, 0x00002AEA, 0x0000522C, 0x00004BB5, 0x00050050, 0x00000011, 0x0000605D, + 0x00004B64, 0x00004B64, 0x000500C2, 0x00000011, 0x00002385, 0x0000605D, 0x00000718, 0x000500C7, + 0x00000011, 0x00003EC8, 0x00002385, 0x00000724, 0x00050080, 0x00000011, 0x000046BA, 0x00002AEA, + 0x00003EC8, 0x00050084, 0x00000011, 0x00005998, 0x00000A9F, 0x00005C31, 0x00050050, 0x00000011, + 0x00002C44, 0x000023AA, 0x00000A0A, 0x000500C2, 0x00000011, 0x000019AB, 0x00005998, 0x00002C44, + 0x00050086, 0x00000011, 0x000027A2, 0x000046BA, 0x000019AB, 0x00050051, 0x0000000B, 0x00004FA6, + 0x000027A2, 0x00000001, 0x00050084, 0x0000000B, 0x00002B26, 0x00004FA6, 0x00005051, 0x00050051, + 0x0000000B, 0x00006059, 0x000027A2, 0x00000000, 0x00050080, 0x0000000B, 0x00005420, 0x00002B26, + 0x00006059, 0x00050080, 0x0000000B, 0x00002226, 0x0000217F, 0x00005420, 0x00050084, 0x00000011, + 0x00005768, 0x000027A2, 0x000019AB, 0x00050082, 0x00000011, 0x000050EB, 0x000046BA, 0x00005768, + 0x00050051, 0x0000000B, 0x00001C87, 0x00005998, 0x00000000, 0x00050051, 0x0000000B, 0x00005962, + 0x00005998, 0x00000001, 0x00050084, 0x0000000B, 0x00003372, 0x00001C87, 0x00005962, 0x00050084, + 0x0000000B, 0x000038D7, 0x00002226, 0x00003372, 0x00050051, 0x0000000B, 0x00001A95, 0x000050EB, + 0x00000001, 0x00050051, 0x0000000B, 0x00005BE6, 0x000019AB, 0x00000000, 0x00050084, 0x0000000B, + 0x00005966, 0x00001A95, 0x00005BE6, 0x00050051, 0x0000000B, 0x00001AE6, 0x000050EB, 0x00000000, + 0x00050080, 0x0000000B, 0x000025E0, 0x00005966, 0x00001AE6, 0x000500C4, 0x0000000B, 0x00004665, + 0x000025E0, 0x000023AA, 0x00050080, 0x0000000B, 0x000047BB, 0x000038D7, 0x00004665, 0x00050084, + 0x0000000B, 0x000034C0, 0x00003372, 0x00000A84, 0x00050089, 0x0000000B, 0x0000628F, 0x000047BB, + 0x000034C0, 0x000500AE, 0x00000009, 0x00003FFB, 0x0000217E, 0x00000A10, 0x000600A9, 0x0000000B, + 0x0000609F, 0x00003FFB, 0x00000A0D, 0x00000A0A, 0x00050080, 0x0000000B, 0x00004E6A, 0x000023AA, + 0x0000609F, 0x000500C4, 0x0000000B, 0x0000199B, 0x00000A0D, 0x00004E6A, 0x000500AB, 0x00000009, + 0x00005AEF, 0x000023AA, 0x00000A0A, 0x000300F7, 0x0000530F, 0x00000002, 0x000400FA, 0x00005AEF, + 0x00003B65, 0x000040B9, 0x000200F8, 0x000040B9, 0x000500AA, 0x00000009, 0x00004ADA, 0x0000199B, + 0x00000A0D, 0x000300F7, 0x00004F49, 0x00000002, 0x000400FA, 0x00004ADA, 0x00002621, 0x00002F61, + 0x000200F8, 0x00002F61, 0x00060041, 0x00000288, 0x00004BCF, 0x00000CC7, 0x00000A0B, 0x0000628F, + 0x0004003D, 0x0000000B, 0x00005D43, 0x00004BCF, 0x00050080, 0x0000000B, 0x00002DA7, 0x0000628F, + 0x0000199B, 0x00060041, 0x00000288, 0x00005FEE, 0x00000CC7, 0x00000A0B, 0x00002DA7, 0x0004003D, + 0x0000000B, 0x00003FFC, 0x00005FEE, 0x00050050, 0x00000011, 0x0000512C, 0x00005D43, 0x00003FFC, + 0x000200F9, 0x00004F49, 0x000200F8, 0x00002621, 0x00060041, 0x00000288, 0x00005545, 0x00000CC7, + 0x00000A0B, 0x0000628F, 0x0004003D, 0x0000000B, 0x00005D44, 0x00005545, 0x00050080, 0x0000000B, + 0x00002DA8, 0x0000628F, 0x00000A0D, 0x00060041, 0x00000288, 0x00005FEF, 0x00000CC7, 0x00000A0B, + 0x00002DA8, 0x0004003D, 0x0000000B, 0x00003FFD, 0x00005FEF, 0x00050050, 0x00000011, 0x0000512D, + 0x00005D44, 0x00003FFD, 0x000200F9, 0x00004F49, 0x000200F8, 0x00004F49, 0x000700F5, 0x00000011, + 0x00002ABF, 0x0000512D, 0x00002621, 0x0000512C, 0x00002F61, 0x000300F7, 0x00003F60, 0x00000000, + 0x001300FB, 0x00002180, 0x00004BFB, 0x00000000, 0x000038F9, 0x00000001, 0x000038F9, 0x00000002, + 0x00001CBB, 0x0000000A, 0x00001CBB, 0x00000003, 0x00001CBA, 0x0000000C, 0x00001CBA, 0x00000004, + 0x00001FFE, 0x00000006, 0x00002033, 0x000200F8, 0x00002033, 0x00050051, 0x0000000B, 0x00005F56, + 0x00002ABF, 0x00000000, 0x0006000C, 0x00000013, 0x00006067, 0x00000001, 0x0000003E, 0x00005F56, + 0x00050051, 0x0000000D, 0x00002762, 0x00006067, 0x00000000, 0x00050051, 0x0000000D, 0x00004446, + 0x00006067, 0x00000001, 0x00070050, 0x0000001D, 0x0000390C, 0x00002762, 0x00004446, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x0000437A, 0x00002ABF, 0x00000001, 0x0006000C, 0x00000013, + 0x0000466B, 0x00000001, 0x0000003E, 0x0000437A, 0x00050051, 0x0000000D, 0x00002763, 0x0000466B, + 0x00000000, 0x00050051, 0x0000000D, 0x000050BE, 0x0000466B, 0x00000001, 0x00070050, 0x0000001D, + 0x00002349, 0x00002763, 0x000050BE, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F60, 0x000200F8, + 0x00001FFE, 0x00050051, 0x0000000B, 0x0000308B, 0x00002ABF, 0x00000000, 0x0004007C, 0x0000000C, + 0x0000589D, 0x0000308B, 0x00050050, 0x00000012, 0x0000471A, 0x0000589D, 0x0000589D, 0x000500C4, + 0x00000012, 0x000047AD, 0x0000471A, 0x000007A7, 0x000500C3, 0x00000012, 0x00003417, 0x000047AD, + 0x00000867, 0x0004006F, 0x00000013, 0x00002A97, 0x00003417, 0x0005008E, 0x00000013, 0x00004747, + 0x00002A97, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E06, 0x00000001, 0x00000028, 0x00000049, + 0x00004747, 0x00050051, 0x0000000D, 0x00005F0A, 0x00005E06, 0x00000000, 0x00050051, 0x0000000D, + 0x00003CD4, 0x00005E06, 0x00000001, 0x00070050, 0x0000001D, 0x0000411E, 0x00005F0A, 0x00003CD4, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C42, 0x00002ABF, 0x00000001, 0x0004007C, + 0x0000000C, 0x00003EA1, 0x00004C42, 0x00050050, 0x00000012, 0x0000471B, 0x00003EA1, 0x00003EA1, + 0x000500C4, 0x00000012, 0x000047AE, 0x0000471B, 0x000007A7, 0x000500C3, 0x00000012, 0x00003418, + 0x000047AE, 0x00000867, 0x0004006F, 0x00000013, 0x00002A98, 0x00003418, 0x0005008E, 0x00000013, + 0x00004748, 0x00002A98, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E07, 0x00000001, 0x00000028, + 0x00000049, 0x00004748, 0x00050051, 0x0000000D, 0x00005F0B, 0x00005E07, 0x00000000, 0x00050051, + 0x0000000D, 0x0000494C, 0x00005E07, 0x00000001, 0x00070050, 0x0000001D, 0x0000234A, 0x00005F0B, + 0x0000494C, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F60, 0x000200F8, 0x00001CBA, 0x00050051, + 0x0000000B, 0x000056BD, 0x00002ABF, 0x00000000, 0x00060050, 0x00000014, 0x00004F0A, 0x000056BD, + 0x000056BD, 0x000056BD, 0x000500C2, 0x00000014, 0x00002B0D, 0x00004F0A, 0x00000BB4, 0x000500C7, + 0x00000014, 0x00005DE6, 0x00002B0D, 0x00000105, 0x000500C7, 0x00000014, 0x0000489C, 0x00005DE6, + 0x00000466, 0x000500C2, 0x00000014, 0x00005B90, 0x00005DE6, 0x00000B0C, 0x000500AA, 0x00000010, + 0x000040C9, 0x00005B90, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4B, 0x00000001, 0x0000004B, + 0x0000489C, 0x0004007C, 0x00000014, 0x00002A15, 0x00002C4B, 0x00050082, 0x00000014, 0x0000187A, + 0x00000B0C, 0x00002A15, 0x00050080, 0x00000014, 0x00002210, 0x00002A15, 0x00000938, 0x000600A9, + 0x00000014, 0x0000286F, 0x000040C9, 0x00002210, 0x00005B90, 0x000500C4, 0x00000014, 0x00005AD4, + 0x0000489C, 0x0000187A, 0x000500C7, 0x00000014, 0x0000499A, 0x00005AD4, 0x00000466, 0x000600A9, + 0x00000014, 0x00002A9D, 0x000040C9, 0x0000499A, 0x0000489C, 0x00050080, 0x00000014, 0x00005FF9, + 0x0000286F, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F7F, 0x00005FF9, 0x00000189, 0x000500C4, + 0x00000014, 0x00003FA6, 0x00002A9D, 0x0000008D, 0x000500C5, 0x00000014, 0x0000577C, 0x00004F7F, + 0x00003FA6, 0x000500AA, 0x00000010, 0x00003600, 0x00005DE6, 0x00000A12, 0x000600A9, 0x00000014, + 0x00004242, 0x00003600, 0x00000A12, 0x0000577C, 0x0004007C, 0x00000018, 0x000029CF, 0x00004242, + 0x000500C2, 0x0000000B, 0x00004BA4, 0x000056BD, 0x00000A64, 0x00040070, 0x0000000D, 0x0000480E, + 0x00004BA4, 0x00050085, 0x0000000D, 0x00003E1F, 0x0000480E, 0x00000149, 0x00050051, 0x0000000D, + 0x000053C2, 0x000029CF, 0x00000000, 0x00050051, 0x0000000D, 0x00002A55, 0x000029CF, 0x00000001, + 0x00050051, 0x0000000D, 0x00001E99, 0x000029CF, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDA, + 0x000053C2, 0x00002A55, 0x00001E99, 0x00003E1F, 0x00050051, 0x0000000B, 0x000027F5, 0x00002ABF, + 0x00000001, 0x00060050, 0x00000014, 0x0000350E, 0x000027F5, 0x000027F5, 0x000027F5, 0x000500C2, + 0x00000014, 0x00002B0E, 0x0000350E, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DE7, 0x00002B0E, + 0x00000105, 0x000500C7, 0x00000014, 0x0000489D, 0x00005DE7, 0x00000466, 0x000500C2, 0x00000014, + 0x00005B91, 0x00005DE7, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CA, 0x00005B91, 0x00000A12, + 0x0006000C, 0x00000016, 0x00002C4C, 0x00000001, 0x0000004B, 0x0000489D, 0x0004007C, 0x00000014, + 0x00002A16, 0x00002C4C, 0x00050082, 0x00000014, 0x0000187B, 0x00000B0C, 0x00002A16, 0x00050080, + 0x00000014, 0x00002211, 0x00002A16, 0x00000938, 0x000600A9, 0x00000014, 0x00002870, 0x000040CA, + 0x00002211, 0x00005B91, 0x000500C4, 0x00000014, 0x00005AD5, 0x0000489D, 0x0000187B, 0x000500C7, + 0x00000014, 0x0000499B, 0x00005AD5, 0x00000466, 0x000600A9, 0x00000014, 0x00002A9E, 0x000040CA, + 0x0000499B, 0x0000489D, 0x00050080, 0x00000014, 0x00005FFA, 0x00002870, 0x000003FA, 0x000500C4, + 0x00000014, 0x00004F80, 0x00005FFA, 0x00000189, 0x000500C4, 0x00000014, 0x00003FA7, 0x00002A9E, + 0x0000008D, 0x000500C5, 0x00000014, 0x0000577D, 0x00004F80, 0x00003FA7, 0x000500AA, 0x00000010, + 0x00003601, 0x00005DE7, 0x00000A12, 0x000600A9, 0x00000014, 0x00004243, 0x00003601, 0x00000A12, + 0x0000577D, 0x0004007C, 0x00000018, 0x000029D0, 0x00004243, 0x000500C2, 0x0000000B, 0x00004BA5, + 0x000027F5, 0x00000A64, 0x00040070, 0x0000000D, 0x0000480F, 0x00004BA5, 0x00050085, 0x0000000D, + 0x00003E20, 0x0000480F, 0x00000149, 0x00050051, 0x0000000D, 0x000053C3, 0x000029D0, 0x00000000, + 0x00050051, 0x0000000D, 0x00002A56, 0x000029D0, 0x00000001, 0x00050051, 0x0000000D, 0x00002B11, + 0x000029D0, 0x00000002, 0x00070050, 0x0000001D, 0x0000234B, 0x000053C3, 0x00002A56, 0x00002B11, + 0x00003E20, 0x000200F9, 0x00003F60, 0x000200F8, 0x00001CBB, 0x00050051, 0x0000000B, 0x000056BE, + 0x00002ABF, 0x00000000, 0x00070050, 0x00000017, 0x00004F0B, 0x000056BE, 0x000056BE, 0x000056BE, + 0x000056BE, 0x000500C2, 0x00000017, 0x00002498, 0x00004F0B, 0x0000034D, 0x000500C7, 0x00000017, + 0x000049AB, 0x00002498, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CB7, 0x000049AB, 0x00050085, + 0x0000001D, 0x00004130, 0x00003CB7, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD2, 0x00002ABF, + 0x00000001, 0x00070050, 0x00000017, 0x0000514D, 0x00005CD2, 0x00005CD2, 0x00005CD2, 0x00005CD2, + 0x000500C2, 0x00000017, 0x00002499, 0x0000514D, 0x0000034D, 0x000500C7, 0x00000017, 0x000049AC, + 0x00002499, 0x0000027B, 0x00040070, 0x0000001D, 0x0000492F, 0x000049AC, 0x00050085, 0x0000001D, + 0x0000269F, 0x0000492F, 0x00000AEE, 0x000200F9, 0x00003F60, 0x000200F8, 0x000038F9, 0x00050051, + 0x0000000B, 0x000056BF, 0x00002ABF, 0x00000000, 0x00070050, 0x00000017, 0x00004F0C, 0x000056BF, + 0x000056BF, 0x000056BF, 0x000056BF, 0x000500C2, 0x00000017, 0x0000249A, 0x00004F0C, 0x0000028D, + 0x000500C7, 0x00000017, 0x00004A56, 0x0000249A, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A2, + 0x00004A56, 0x0005008E, 0x0000001D, 0x00004B23, 0x000036A2, 0x0000017A, 0x00050051, 0x0000000B, + 0x0000219F, 0x00002ABF, 0x00000001, 0x00070050, 0x00000017, 0x0000610B, 0x0000219F, 0x0000219F, + 0x0000219F, 0x0000219F, 0x000500C2, 0x00000017, 0x0000249B, 0x0000610B, 0x0000028D, 0x000500C7, + 0x00000017, 0x00004A57, 0x0000249B, 0x0000064B, 0x00040070, 0x0000001D, 0x0000431A, 0x00004A57, + 0x0005008E, 0x0000001D, 0x00003092, 0x0000431A, 0x0000017A, 0x000200F9, 0x00003F60, 0x000200F8, + 0x00004BFB, 0x00050051, 0x0000000B, 0x0000308C, 0x00002ABF, 0x00000000, 0x0004007C, 0x0000000D, + 0x00004FEE, 0x0000308C, 0x00050050, 0x00000013, 0x00004336, 0x00004FEE, 0x00000A0C, 0x0009004F, + 0x0000001D, 0x00002D90, 0x00004336, 0x00004336, 0x00000000, 0x00000001, 0x00000001, 0x00000001, + 0x00050051, 0x0000000B, 0x000056B1, 0x00002ABF, 0x00000001, 0x0004007C, 0x0000000D, 0x00003F68, + 0x000056B1, 0x00050050, 0x00000013, 0x00004FAE, 0x00003F68, 0x00000A0C, 0x0009004F, 0x0000001D, + 0x00005A3A, 0x00004FAE, 0x00004FAE, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000200F9, + 0x00003F60, 0x000200F8, 0x00003F60, 0x000F00F5, 0x0000001D, 0x00002BF3, 0x00005A3A, 0x00004BFB, + 0x00003092, 0x000038F9, 0x0000269F, 0x00001CBB, 0x0000234B, 0x00001CBA, 0x0000234A, 0x00001FFE, + 0x00002349, 0x00002033, 0x000F00F5, 0x0000001D, 0x0000358D, 0x00002D90, 0x00004BFB, 0x00004B23, + 0x000038F9, 0x00004130, 0x00001CBB, 0x00003DDA, 0x00001CBA, 0x0000411E, 0x00001FFE, 0x0000390C, + 0x00002033, 0x000200F9, 0x0000530F, 0x000200F8, 0x00003B65, 0x000500AA, 0x00000009, 0x00005450, + 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F4A, 0x00000002, 0x000400FA, 0x00005450, 0x00002622, + 0x00002F62, 0x000200F8, 0x00002F62, 0x00060041, 0x00000288, 0x00004BD0, 0x00000CC7, 0x00000A0B, + 0x0000628F, 0x0004003D, 0x0000000B, 0x00005D45, 0x00004BD0, 0x00050080, 0x0000000B, 0x00002DA9, + 0x0000628F, 0x00000A0D, 0x00060041, 0x00000288, 0x000018FF, 0x00000CC7, 0x00000A0B, 0x00002DA9, + 0x0004003D, 0x0000000B, 0x00005C62, 0x000018FF, 0x00050080, 0x0000000B, 0x00002DAA, 0x0000628F, + 0x0000199B, 0x00060041, 0x00000288, 0x00001900, 0x00000CC7, 0x00000A0B, 0x00002DAA, 0x0004003D, + 0x0000000B, 0x00005C63, 0x00001900, 0x00050080, 0x0000000B, 0x00002DAB, 0x00002DAA, 0x00000A0D, + 0x00060041, 0x00000288, 0x00005FF0, 0x00000CC7, 0x00000A0B, 0x00002DAB, 0x0004003D, 0x0000000B, + 0x00003FFE, 0x00005FF0, 0x00070050, 0x00000017, 0x0000512E, 0x00005D45, 0x00005C62, 0x00005C63, + 0x00003FFE, 0x000200F9, 0x00004F4A, 0x000200F8, 0x00002622, 0x00060041, 0x00000288, 0x00005546, + 0x00000CC7, 0x00000A0B, 0x0000628F, 0x0004003D, 0x0000000B, 0x00005D46, 0x00005546, 0x00050080, + 0x0000000B, 0x00002DAC, 0x0000628F, 0x00000A0D, 0x00060041, 0x00000288, 0x00001901, 0x00000CC7, + 0x00000A0B, 0x00002DAC, 0x0004003D, 0x0000000B, 0x00005C64, 0x00001901, 0x00050080, 0x0000000B, + 0x00002DAD, 0x0000628F, 0x00000A10, 0x00060041, 0x00000288, 0x00001902, 0x00000CC7, 0x00000A0B, + 0x00002DAD, 0x0004003D, 0x0000000B, 0x00005C65, 0x00001902, 0x00050080, 0x0000000B, 0x00002DAE, + 0x0000628F, 0x00000A13, 0x00060041, 0x00000288, 0x00005FF1, 0x00000CC7, 0x00000A0B, 0x00002DAE, + 0x0004003D, 0x0000000B, 0x00003FFF, 0x00005FF1, 0x00070050, 0x00000017, 0x0000512F, 0x00005D46, + 0x00005C64, 0x00005C65, 0x00003FFF, 0x000200F9, 0x00004F4A, 0x000200F8, 0x00004F4A, 0x000700F5, + 0x00000017, 0x00002AC0, 0x0000512F, 0x00002622, 0x0000512E, 0x00002F62, 0x000300F7, 0x00004F23, + 0x00000000, 0x000700FB, 0x00002180, 0x00004F56, 0x00000005, 0x00002158, 0x00000007, 0x00002034, + 0x000200F8, 0x00002034, 0x00050051, 0x0000000B, 0x00005F57, 0x00002AC0, 0x00000000, 0x0006000C, + 0x00000013, 0x00006068, 0x00000001, 0x0000003E, 0x00005F57, 0x00050051, 0x0000000D, 0x00002775, + 0x00006068, 0x00000000, 0x00050051, 0x0000000D, 0x00003EB8, 0x00006068, 0x00000001, 0x00050051, + 0x0000000B, 0x00004281, 0x00002AC0, 0x00000001, 0x0006000C, 0x00000013, 0x00003CF5, 0x00000001, + 0x0000003E, 0x00004281, 0x00050051, 0x0000000D, 0x00002764, 0x00003CF5, 0x00000000, 0x00050051, + 0x0000000D, 0x00004447, 0x00003CF5, 0x00000001, 0x00070050, 0x0000001D, 0x0000390D, 0x00002775, + 0x00003EB8, 0x00002764, 0x00004447, 0x00050051, 0x0000000B, 0x0000437B, 0x00002AC0, 0x00000002, + 0x0006000C, 0x00000013, 0x0000466C, 0x00000001, 0x0000003E, 0x0000437B, 0x00050051, 0x0000000D, + 0x00002776, 0x0000466C, 0x00000000, 0x00050051, 0x0000000D, 0x00003EB9, 0x0000466C, 0x00000001, + 0x00050051, 0x0000000B, 0x00004282, 0x00002AC0, 0x00000003, 0x0006000C, 0x00000013, 0x00003CF6, + 0x00000001, 0x0000003E, 0x00004282, 0x00050051, 0x0000000D, 0x00002765, 0x00003CF6, 0x00000000, + 0x00050051, 0x0000000D, 0x000050BF, 0x00003CF6, 0x00000001, 0x00070050, 0x0000001D, 0x0000234C, + 0x00002776, 0x00003EB9, 0x00002765, 0x000050BF, 0x000200F9, 0x00004F23, 0x000200F8, 0x00002158, + 0x0007004F, 0x00000011, 0x000025FB, 0x00002AC0, 0x00002AC0, 0x00000000, 0x00000001, 0x0004007C, + 0x00000012, 0x00005B3C, 0x000025FB, 0x0009004F, 0x0000001A, 0x000060CE, 0x00005B3C, 0x00005B3C, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048A6, 0x000060CE, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D8D, 0x000048A6, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002A99, 0x00003D8D, 0x0005008E, 0x0000001D, 0x00004721, 0x00002A99, 0x000007FE, 0x0007000C, + 0x0000001D, 0x00006291, 0x00000001, 0x00000028, 0x00000504, 0x00004721, 0x0007004F, 0x00000011, + 0x0000376B, 0x00002AC0, 0x00002AC0, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024BF, + 0x0000376B, 0x0009004F, 0x0000001A, 0x000060CF, 0x000024BF, 0x000024BF, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048A7, 0x000060CF, 0x00000122, 0x000500C3, + 0x0000001A, 0x00003D8E, 0x000048A7, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A9A, 0x00003D8E, + 0x0005008E, 0x0000001D, 0x000053BF, 0x00002A9A, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004362, + 0x00000001, 0x00000028, 0x00000504, 0x000053BF, 0x000200F9, 0x00004F23, 0x000200F8, 0x00004F56, + 0x0007004F, 0x00000011, 0x00002623, 0x00002AC0, 0x00002AC0, 0x00000000, 0x00000001, 0x0004007C, + 0x00000013, 0x00005159, 0x00002623, 0x00050051, 0x0000000D, 0x00001B7B, 0x00005159, 0x00000000, + 0x00050051, 0x0000000D, 0x0000346A, 0x00005159, 0x00000001, 0x00070050, 0x0000001D, 0x00004278, + 0x00001B7B, 0x0000346A, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041D8, 0x00002AC0, + 0x00002AC0, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x0000375D, 0x000041D8, 0x00050051, + 0x0000000D, 0x00001B7C, 0x0000375D, 0x00000000, 0x00050051, 0x0000000D, 0x00004108, 0x0000375D, + 0x00000001, 0x00070050, 0x0000001D, 0x0000234D, 0x00001B7C, 0x00004108, 0x00000A0C, 0x00000A0C, + 0x000200F9, 0x00004F23, 0x000200F8, 0x00004F23, 0x000900F5, 0x0000001D, 0x00002BF4, 0x0000234D, + 0x00004F56, 0x00004362, 0x00002158, 0x0000234C, 0x00002034, 0x000900F5, 0x0000001D, 0x0000358E, + 0x00004278, 0x00004F56, 0x00006291, 0x00002158, 0x0000390D, 0x00002034, 0x000200F9, 0x0000530F, + 0x000200F8, 0x0000530F, 0x000700F5, 0x0000001D, 0x00002662, 0x00002BF4, 0x00004F23, 0x00002BF3, + 0x00003F60, 0x000700F5, 0x0000001D, 0x000036E3, 0x0000358E, 0x00004F23, 0x0000358D, 0x00003F60, + 0x000500AE, 0x00000009, 0x00002E55, 0x00004356, 0x00000A16, 0x000300F7, 0x00005313, 0x00000002, + 0x000400FA, 0x00002E55, 0x000051F1, 0x00005313, 0x000200F8, 0x000051F1, 0x00050084, 0x0000000B, + 0x00002B47, 0x00000AFA, 0x0000229A, 0x00050085, 0x0000000D, 0x00005A1D, 0x00002B2C, 0x000000FC, + 0x00050080, 0x0000000B, 0x00001FB2, 0x0000628F, 0x00002B47, 0x000300F7, 0x00005310, 0x00000002, + 0x000400FA, 0x00005AEF, 0x00003B66, 0x000040BA, 0x000200F8, 0x000040BA, 0x000500AA, 0x00000009, + 0x00004ADB, 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F4B, 0x00000002, 0x000400FA, 0x00004ADB, + 0x00002624, 0x00002F63, 0x000200F8, 0x00002F63, 0x00060041, 0x00000288, 0x00004BD1, 0x00000CC7, + 0x00000A0B, 0x00001FB2, 0x0004003D, 0x0000000B, 0x00005D47, 0x00004BD1, 0x00050080, 0x0000000B, + 0x00002DAF, 0x00001FB2, 0x0000199B, 0x00060041, 0x00000288, 0x00005FF2, 0x00000CC7, 0x00000A0B, + 0x00002DAF, 0x0004003D, 0x0000000B, 0x00004000, 0x00005FF2, 0x00050050, 0x00000011, 0x00005130, + 0x00005D47, 0x00004000, 0x000200F9, 0x00004F4B, 0x000200F8, 0x00002624, 0x00060041, 0x00000288, + 0x00005547, 0x00000CC7, 0x00000A0B, 0x00001FB2, 0x0004003D, 0x0000000B, 0x00005D48, 0x00005547, + 0x00050080, 0x0000000B, 0x00002DB0, 0x00001FB2, 0x00000A0D, 0x00060041, 0x00000288, 0x00005FF3, + 0x00000CC7, 0x00000A0B, 0x00002DB0, 0x0004003D, 0x0000000B, 0x00004001, 0x00005FF3, 0x00050050, + 0x00000011, 0x00005131, 0x00005D48, 0x00004001, 0x000200F9, 0x00004F4B, 0x000200F8, 0x00004F4B, + 0x000700F5, 0x00000011, 0x00002AC1, 0x00005131, 0x00002624, 0x00005130, 0x00002F63, 0x000300F7, + 0x00003F61, 0x00000000, 0x001300FB, 0x00002180, 0x00004BFC, 0x00000000, 0x000038FA, 0x00000001, + 0x000038FA, 0x00000002, 0x00001CBD, 0x0000000A, 0x00001CBD, 0x00000003, 0x00001CBC, 0x0000000C, + 0x00001CBC, 0x00000004, 0x00001FFF, 0x00000006, 0x00002035, 0x000200F8, 0x00002035, 0x00050051, + 0x0000000B, 0x00005F58, 0x00002AC1, 0x00000000, 0x0006000C, 0x00000013, 0x00006069, 0x00000001, + 0x0000003E, 0x00005F58, 0x00050051, 0x0000000D, 0x00002766, 0x00006069, 0x00000000, 0x00050051, + 0x0000000D, 0x00004448, 0x00006069, 0x00000001, 0x00070050, 0x0000001D, 0x0000390E, 0x00002766, + 0x00004448, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x0000437C, 0x00002AC1, 0x00000001, + 0x0006000C, 0x00000013, 0x0000466D, 0x00000001, 0x0000003E, 0x0000437C, 0x00050051, 0x0000000D, + 0x00002767, 0x0000466D, 0x00000000, 0x00050051, 0x0000000D, 0x000050C0, 0x0000466D, 0x00000001, + 0x00070050, 0x0000001D, 0x0000234E, 0x00002767, 0x000050C0, 0x00000A0C, 0x00000A0C, 0x000200F9, + 0x00003F61, 0x000200F8, 0x00001FFF, 0x00050051, 0x0000000B, 0x0000308D, 0x00002AC1, 0x00000000, + 0x0004007C, 0x0000000C, 0x0000589E, 0x0000308D, 0x00050050, 0x00000012, 0x0000471C, 0x0000589E, + 0x0000589E, 0x000500C4, 0x00000012, 0x000047AF, 0x0000471C, 0x000007A7, 0x000500C3, 0x00000012, + 0x00003419, 0x000047AF, 0x00000867, 0x0004006F, 0x00000013, 0x00002A9B, 0x00003419, 0x0005008E, + 0x00000013, 0x00004749, 0x00002A9B, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E08, 0x00000001, + 0x00000028, 0x00000049, 0x00004749, 0x00050051, 0x0000000D, 0x00005F0C, 0x00005E08, 0x00000000, + 0x00050051, 0x0000000D, 0x00003CD5, 0x00005E08, 0x00000001, 0x00070050, 0x0000001D, 0x0000411F, + 0x00005F0C, 0x00003CD5, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C43, 0x00002AC1, + 0x00000001, 0x0004007C, 0x0000000C, 0x00003EA2, 0x00004C43, 0x00050050, 0x00000012, 0x0000471D, + 0x00003EA2, 0x00003EA2, 0x000500C4, 0x00000012, 0x000047B0, 0x0000471D, 0x000007A7, 0x000500C3, + 0x00000012, 0x0000341A, 0x000047B0, 0x00000867, 0x0004006F, 0x00000013, 0x00002A9C, 0x0000341A, + 0x0005008E, 0x00000013, 0x0000474A, 0x00002A9C, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E09, + 0x00000001, 0x00000028, 0x00000049, 0x0000474A, 0x00050051, 0x0000000D, 0x00005F0D, 0x00005E09, + 0x00000000, 0x00050051, 0x0000000D, 0x0000494D, 0x00005E09, 0x00000001, 0x00070050, 0x0000001D, + 0x0000234F, 0x00005F0D, 0x0000494D, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F61, 0x000200F8, + 0x00001CBC, 0x00050051, 0x0000000B, 0x000056C0, 0x00002AC1, 0x00000000, 0x00060050, 0x00000014, + 0x00004F0D, 0x000056C0, 0x000056C0, 0x000056C0, 0x000500C2, 0x00000014, 0x00002B0F, 0x00004F0D, + 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DE8, 0x00002B0F, 0x00000105, 0x000500C7, 0x00000014, + 0x0000489E, 0x00005DE8, 0x00000466, 0x000500C2, 0x00000014, 0x00005B92, 0x00005DE8, 0x00000B0C, + 0x000500AA, 0x00000010, 0x000040CB, 0x00005B92, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4D, + 0x00000001, 0x0000004B, 0x0000489E, 0x0004007C, 0x00000014, 0x00002A17, 0x00002C4D, 0x00050082, + 0x00000014, 0x0000187C, 0x00000B0C, 0x00002A17, 0x00050080, 0x00000014, 0x00002212, 0x00002A17, + 0x00000938, 0x000600A9, 0x00000014, 0x00002871, 0x000040CB, 0x00002212, 0x00005B92, 0x000500C4, + 0x00000014, 0x00005AD6, 0x0000489E, 0x0000187C, 0x000500C7, 0x00000014, 0x0000499C, 0x00005AD6, + 0x00000466, 0x000600A9, 0x00000014, 0x00002A9F, 0x000040CB, 0x0000499C, 0x0000489E, 0x00050080, + 0x00000014, 0x00005FFB, 0x00002871, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F81, 0x00005FFB, + 0x00000189, 0x000500C4, 0x00000014, 0x00003FA8, 0x00002A9F, 0x0000008D, 0x000500C5, 0x00000014, + 0x0000577E, 0x00004F81, 0x00003FA8, 0x000500AA, 0x00000010, 0x00003602, 0x00005DE8, 0x00000A12, + 0x000600A9, 0x00000014, 0x00004244, 0x00003602, 0x00000A12, 0x0000577E, 0x0004007C, 0x00000018, + 0x000029D1, 0x00004244, 0x000500C2, 0x0000000B, 0x00004BA6, 0x000056C0, 0x00000A64, 0x00040070, + 0x0000000D, 0x00004810, 0x00004BA6, 0x00050085, 0x0000000D, 0x00003E21, 0x00004810, 0x00000149, + 0x00050051, 0x0000000D, 0x000053C4, 0x000029D1, 0x00000000, 0x00050051, 0x0000000D, 0x00002A57, + 0x000029D1, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9A, 0x000029D1, 0x00000002, 0x00070050, + 0x0000001D, 0x00003DDB, 0x000053C4, 0x00002A57, 0x00001E9A, 0x00003E21, 0x00050051, 0x0000000B, + 0x000027F6, 0x00002AC1, 0x00000001, 0x00060050, 0x00000014, 0x0000350F, 0x000027F6, 0x000027F6, + 0x000027F6, 0x000500C2, 0x00000014, 0x00002B10, 0x0000350F, 0x00000BB4, 0x000500C7, 0x00000014, + 0x00005DE9, 0x00002B10, 0x00000105, 0x000500C7, 0x00000014, 0x0000489F, 0x00005DE9, 0x00000466, + 0x000500C2, 0x00000014, 0x00005B93, 0x00005DE9, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CC, + 0x00005B93, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4E, 0x00000001, 0x0000004B, 0x0000489F, + 0x0004007C, 0x00000014, 0x00002A18, 0x00002C4E, 0x00050082, 0x00000014, 0x0000187D, 0x00000B0C, + 0x00002A18, 0x00050080, 0x00000014, 0x00002213, 0x00002A18, 0x00000938, 0x000600A9, 0x00000014, + 0x00002872, 0x000040CC, 0x00002213, 0x00005B93, 0x000500C4, 0x00000014, 0x00005AD7, 0x0000489F, + 0x0000187D, 0x000500C7, 0x00000014, 0x0000499D, 0x00005AD7, 0x00000466, 0x000600A9, 0x00000014, + 0x00002AA0, 0x000040CC, 0x0000499D, 0x0000489F, 0x00050080, 0x00000014, 0x00005FFC, 0x00002872, + 0x000003FA, 0x000500C4, 0x00000014, 0x00004F82, 0x00005FFC, 0x00000189, 0x000500C4, 0x00000014, + 0x00003FA9, 0x00002AA0, 0x0000008D, 0x000500C5, 0x00000014, 0x0000577F, 0x00004F82, 0x00003FA9, + 0x000500AA, 0x00000010, 0x00003603, 0x00005DE9, 0x00000A12, 0x000600A9, 0x00000014, 0x00004245, + 0x00003603, 0x00000A12, 0x0000577F, 0x0004007C, 0x00000018, 0x000029D2, 0x00004245, 0x000500C2, + 0x0000000B, 0x00004BA7, 0x000027F6, 0x00000A64, 0x00040070, 0x0000000D, 0x00004811, 0x00004BA7, + 0x00050085, 0x0000000D, 0x00003E22, 0x00004811, 0x00000149, 0x00050051, 0x0000000D, 0x000053C5, + 0x000029D2, 0x00000000, 0x00050051, 0x0000000D, 0x00002A58, 0x000029D2, 0x00000001, 0x00050051, + 0x0000000D, 0x00002B12, 0x000029D2, 0x00000002, 0x00070050, 0x0000001D, 0x00002350, 0x000053C5, + 0x00002A58, 0x00002B12, 0x00003E22, 0x000200F9, 0x00003F61, 0x000200F8, 0x00001CBD, 0x00050051, + 0x0000000B, 0x000056C1, 0x00002AC1, 0x00000000, 0x00070050, 0x00000017, 0x00004F0E, 0x000056C1, + 0x000056C1, 0x000056C1, 0x000056C1, 0x000500C2, 0x00000017, 0x0000249C, 0x00004F0E, 0x0000034D, + 0x000500C7, 0x00000017, 0x000049AD, 0x0000249C, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CB8, + 0x000049AD, 0x00050085, 0x0000001D, 0x00004131, 0x00003CB8, 0x00000AEE, 0x00050051, 0x0000000B, + 0x00005CD3, 0x00002AC1, 0x00000001, 0x00070050, 0x00000017, 0x0000514E, 0x00005CD3, 0x00005CD3, + 0x00005CD3, 0x00005CD3, 0x000500C2, 0x00000017, 0x0000249D, 0x0000514E, 0x0000034D, 0x000500C7, + 0x00000017, 0x000049AE, 0x0000249D, 0x0000027B, 0x00040070, 0x0000001D, 0x00004930, 0x000049AE, + 0x00050085, 0x0000001D, 0x000026A0, 0x00004930, 0x00000AEE, 0x000200F9, 0x00003F61, 0x000200F8, + 0x000038FA, 0x00050051, 0x0000000B, 0x000056C2, 0x00002AC1, 0x00000000, 0x00070050, 0x00000017, + 0x00004F0F, 0x000056C2, 0x000056C2, 0x000056C2, 0x000056C2, 0x000500C2, 0x00000017, 0x0000249E, + 0x00004F0F, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A58, 0x0000249E, 0x0000064B, 0x00040070, + 0x0000001D, 0x000036A3, 0x00004A58, 0x0005008E, 0x0000001D, 0x00004B24, 0x000036A3, 0x0000017A, + 0x00050051, 0x0000000B, 0x000021A0, 0x00002AC1, 0x00000001, 0x00070050, 0x00000017, 0x0000610C, + 0x000021A0, 0x000021A0, 0x000021A0, 0x000021A0, 0x000500C2, 0x00000017, 0x0000249F, 0x0000610C, + 0x0000028D, 0x000500C7, 0x00000017, 0x00004A59, 0x0000249F, 0x0000064B, 0x00040070, 0x0000001D, + 0x0000431B, 0x00004A59, 0x0005008E, 0x0000001D, 0x00003093, 0x0000431B, 0x0000017A, 0x000200F9, + 0x00003F61, 0x000200F8, 0x00004BFC, 0x00050051, 0x0000000B, 0x0000308E, 0x00002AC1, 0x00000000, + 0x0004007C, 0x0000000D, 0x00004FEF, 0x0000308E, 0x00050050, 0x00000013, 0x00004337, 0x00004FEF, + 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D91, 0x00004337, 0x00004337, 0x00000000, 0x00000001, + 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B2, 0x00002AC1, 0x00000001, 0x0004007C, + 0x0000000D, 0x00003F69, 0x000056B2, 0x00050050, 0x00000013, 0x00004FAF, 0x00003F69, 0x00000A0C, + 0x0009004F, 0x0000001D, 0x00005A3B, 0x00004FAF, 0x00004FAF, 0x00000000, 0x00000001, 0x00000001, + 0x00000001, 0x000200F9, 0x00003F61, 0x000200F8, 0x00003F61, 0x000F00F5, 0x0000001D, 0x00002BF5, + 0x00005A3B, 0x00004BFC, 0x00003093, 0x000038FA, 0x000026A0, 0x00001CBD, 0x00002350, 0x00001CBC, + 0x0000234F, 0x00001FFF, 0x0000234E, 0x00002035, 0x000F00F5, 0x0000001D, 0x00003590, 0x00002D91, + 0x00004BFC, 0x00004B24, 0x000038FA, 0x00004131, 0x00001CBD, 0x00003DDB, 0x00001CBC, 0x0000411F, + 0x00001FFF, 0x0000390E, 0x00002035, 0x000200F9, 0x00005310, 0x000200F8, 0x00003B66, 0x000500AA, + 0x00000009, 0x00005451, 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F4C, 0x00000002, 0x000400FA, + 0x00005451, 0x00002625, 0x00002F64, 0x000200F8, 0x00002F64, 0x00060041, 0x00000288, 0x00004BD2, + 0x00000CC7, 0x00000A0B, 0x00001FB2, 0x0004003D, 0x0000000B, 0x00005D49, 0x00004BD2, 0x00050080, + 0x0000000B, 0x00002DB1, 0x00001FB2, 0x00000A0D, 0x00060041, 0x00000288, 0x00001903, 0x00000CC7, + 0x00000A0B, 0x00002DB1, 0x0004003D, 0x0000000B, 0x00005C66, 0x00001903, 0x00050080, 0x0000000B, + 0x00002DB2, 0x00001FB2, 0x0000199B, 0x00060041, 0x00000288, 0x00001904, 0x00000CC7, 0x00000A0B, + 0x00002DB2, 0x0004003D, 0x0000000B, 0x00005C67, 0x00001904, 0x00050080, 0x0000000B, 0x00002DB3, + 0x00002DB2, 0x00000A0D, 0x00060041, 0x00000288, 0x00005FF4, 0x00000CC7, 0x00000A0B, 0x00002DB3, + 0x0004003D, 0x0000000B, 0x00004002, 0x00005FF4, 0x00070050, 0x00000017, 0x00005132, 0x00005D49, + 0x00005C66, 0x00005C67, 0x00004002, 0x000200F9, 0x00004F4C, 0x000200F8, 0x00002625, 0x00060041, + 0x00000288, 0x00005548, 0x00000CC7, 0x00000A0B, 0x00001FB2, 0x0004003D, 0x0000000B, 0x00005D4A, + 0x00005548, 0x00050080, 0x0000000B, 0x00002DB4, 0x00001FB2, 0x00000A0D, 0x00060041, 0x00000288, + 0x00001905, 0x00000CC7, 0x00000A0B, 0x00002DB4, 0x0004003D, 0x0000000B, 0x00005C68, 0x00001905, + 0x00050080, 0x0000000B, 0x00002DB5, 0x00001FB2, 0x00000A10, 0x00060041, 0x00000288, 0x00001906, + 0x00000CC7, 0x00000A0B, 0x00002DB5, 0x0004003D, 0x0000000B, 0x00005C69, 0x00001906, 0x00050080, + 0x0000000B, 0x00002DB6, 0x00001FB2, 0x00000A13, 0x00060041, 0x00000288, 0x00005FF5, 0x00000CC7, + 0x00000A0B, 0x00002DB6, 0x0004003D, 0x0000000B, 0x00004003, 0x00005FF5, 0x00070050, 0x00000017, + 0x00005133, 0x00005D4A, 0x00005C68, 0x00005C69, 0x00004003, 0x000200F9, 0x00004F4C, 0x000200F8, + 0x00004F4C, 0x000700F5, 0x00000017, 0x00002AC2, 0x00005133, 0x00002625, 0x00005132, 0x00002F64, + 0x000300F7, 0x00004F24, 0x00000000, 0x000700FB, 0x00002180, 0x00004F57, 0x00000005, 0x00002159, + 0x00000007, 0x00002036, 0x000200F8, 0x00002036, 0x00050051, 0x0000000B, 0x00005F59, 0x00002AC2, + 0x00000000, 0x0006000C, 0x00000013, 0x0000606A, 0x00000001, 0x0000003E, 0x00005F59, 0x00050051, + 0x0000000D, 0x00002777, 0x0000606A, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBA, 0x0000606A, + 0x00000001, 0x00050051, 0x0000000B, 0x00004283, 0x00002AC2, 0x00000001, 0x0006000C, 0x00000013, + 0x00003CF7, 0x00000001, 0x0000003E, 0x00004283, 0x00050051, 0x0000000D, 0x00002768, 0x00003CF7, + 0x00000000, 0x00050051, 0x0000000D, 0x00004449, 0x00003CF7, 0x00000001, 0x00070050, 0x0000001D, + 0x0000390F, 0x00002777, 0x00003EBA, 0x00002768, 0x00004449, 0x00050051, 0x0000000B, 0x0000437D, + 0x00002AC2, 0x00000002, 0x0006000C, 0x00000013, 0x0000466E, 0x00000001, 0x0000003E, 0x0000437D, + 0x00050051, 0x0000000D, 0x00002778, 0x0000466E, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBB, + 0x0000466E, 0x00000001, 0x00050051, 0x0000000B, 0x00004284, 0x00002AC2, 0x00000003, 0x0006000C, + 0x00000013, 0x00003CF8, 0x00000001, 0x0000003E, 0x00004284, 0x00050051, 0x0000000D, 0x00002769, + 0x00003CF8, 0x00000000, 0x00050051, 0x0000000D, 0x000050C1, 0x00003CF8, 0x00000001, 0x00070050, + 0x0000001D, 0x00002351, 0x00002778, 0x00003EBB, 0x00002769, 0x000050C1, 0x000200F9, 0x00004F24, + 0x000200F8, 0x00002159, 0x0007004F, 0x00000011, 0x000025FC, 0x00002AC2, 0x00002AC2, 0x00000000, + 0x00000001, 0x0004007C, 0x00000012, 0x00005B3D, 0x000025FC, 0x0009004F, 0x0000001A, 0x000060D0, + 0x00005B3D, 0x00005B3D, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, + 0x000048A8, 0x000060D0, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D8F, 0x000048A8, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002AA1, 0x00003D8F, 0x0005008E, 0x0000001D, 0x00004722, 0x00002AA1, + 0x000007FE, 0x0007000C, 0x0000001D, 0x00006292, 0x00000001, 0x00000028, 0x00000504, 0x00004722, + 0x0007004F, 0x00000011, 0x0000376C, 0x00002AC2, 0x00002AC2, 0x00000002, 0x00000003, 0x0004007C, + 0x00000012, 0x000024C0, 0x0000376C, 0x0009004F, 0x0000001A, 0x000060D1, 0x000024C0, 0x000024C0, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048A9, 0x000060D1, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D90, 0x000048A9, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002AA2, 0x00003D90, 0x0005008E, 0x0000001D, 0x000053C0, 0x00002AA2, 0x000007FE, 0x0007000C, + 0x0000001D, 0x00004363, 0x00000001, 0x00000028, 0x00000504, 0x000053C0, 0x000200F9, 0x00004F24, + 0x000200F8, 0x00004F57, 0x0007004F, 0x00000011, 0x00002626, 0x00002AC2, 0x00002AC2, 0x00000000, + 0x00000001, 0x0004007C, 0x00000013, 0x0000515A, 0x00002626, 0x00050051, 0x0000000D, 0x00001B7D, + 0x0000515A, 0x00000000, 0x00050051, 0x0000000D, 0x0000346B, 0x0000515A, 0x00000001, 0x00070050, + 0x0000001D, 0x00004279, 0x00001B7D, 0x0000346B, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, + 0x000041D9, 0x00002AC2, 0x00002AC2, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x0000375E, + 0x000041D9, 0x00050051, 0x0000000D, 0x00001B7F, 0x0000375E, 0x00000000, 0x00050051, 0x0000000D, + 0x00004109, 0x0000375E, 0x00000001, 0x00070050, 0x0000001D, 0x00002352, 0x00001B7F, 0x00004109, + 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F24, 0x000200F8, 0x00004F24, 0x000900F5, 0x0000001D, + 0x00002BF6, 0x00002352, 0x00004F57, 0x00004363, 0x00002159, 0x00002351, 0x00002036, 0x000900F5, + 0x0000001D, 0x00003591, 0x00004279, 0x00004F57, 0x00006292, 0x00002159, 0x0000390F, 0x00002036, + 0x000200F9, 0x00005310, 0x000200F8, 0x00005310, 0x000700F5, 0x0000001D, 0x0000230B, 0x00002BF6, + 0x00004F24, 0x00002BF5, 0x00003F61, 0x000700F5, 0x0000001D, 0x00004C8A, 0x00003591, 0x00004F24, + 0x00003590, 0x00003F61, 0x00050081, 0x0000001D, 0x000046B0, 0x000036E3, 0x00004C8A, 0x00050081, + 0x0000001D, 0x0000455A, 0x00002662, 0x0000230B, 0x000500AE, 0x00000009, 0x0000387D, 0x00004356, + 0x00000A1C, 0x000300F7, 0x00005EC8, 0x00000002, 0x000400FA, 0x0000387D, 0x000026B1, 0x00005EC8, + 0x000200F8, 0x000026B1, 0x000500C4, 0x0000000B, 0x000037B2, 0x00000A0D, 0x000023AA, 0x00050085, + 0x0000000D, 0x00002F3A, 0x00002B2C, 0x0000016E, 0x00050080, 0x0000000B, 0x000051FC, 0x0000628F, + 0x000037B2, 0x000300F7, 0x00005311, 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B67, 0x000040BB, + 0x000200F8, 0x000040BB, 0x000500AA, 0x00000009, 0x00004ADD, 0x0000199B, 0x00000A0D, 0x000300F7, + 0x00004F4D, 0x00000002, 0x000400FA, 0x00004ADD, 0x00002627, 0x00002F65, 0x000200F8, 0x00002F65, + 0x00060041, 0x00000288, 0x00004BD3, 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, + 0x00005D4B, 0x00004BD3, 0x00050080, 0x0000000B, 0x00002DB7, 0x000051FC, 0x0000199B, 0x00060041, + 0x00000288, 0x00005FF6, 0x00000CC7, 0x00000A0B, 0x00002DB7, 0x0004003D, 0x0000000B, 0x00004004, + 0x00005FF6, 0x00050050, 0x00000011, 0x00005134, 0x00005D4B, 0x00004004, 0x000200F9, 0x00004F4D, + 0x000200F8, 0x00002627, 0x00060041, 0x00000288, 0x00005549, 0x00000CC7, 0x00000A0B, 0x000051FC, + 0x0004003D, 0x0000000B, 0x00005D4C, 0x00005549, 0x00050080, 0x0000000B, 0x00002DB8, 0x000051FC, + 0x00000A0D, 0x00060041, 0x00000288, 0x00005FF7, 0x00000CC7, 0x00000A0B, 0x00002DB8, 0x0004003D, + 0x0000000B, 0x00004005, 0x00005FF7, 0x00050050, 0x00000011, 0x00005135, 0x00005D4C, 0x00004005, + 0x000200F9, 0x00004F4D, 0x000200F8, 0x00004F4D, 0x000700F5, 0x00000011, 0x00002AC3, 0x00005135, + 0x00002627, 0x00005134, 0x00002F65, 0x000300F7, 0x00003F62, 0x00000000, 0x001300FB, 0x00002180, + 0x00004BFD, 0x00000000, 0x000038FB, 0x00000001, 0x000038FB, 0x00000002, 0x00001CC0, 0x0000000A, + 0x00001CC0, 0x00000003, 0x00001CBE, 0x0000000C, 0x00001CBE, 0x00000004, 0x00002000, 0x00000006, + 0x00002037, 0x000200F8, 0x00002037, 0x00050051, 0x0000000B, 0x00005F5A, 0x00002AC3, 0x00000000, + 0x0006000C, 0x00000013, 0x0000606B, 0x00000001, 0x0000003E, 0x00005F5A, 0x00050051, 0x0000000D, + 0x0000276A, 0x0000606B, 0x00000000, 0x00050051, 0x0000000D, 0x0000444A, 0x0000606B, 0x00000001, + 0x00070050, 0x0000001D, 0x00003910, 0x0000276A, 0x0000444A, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x0000437E, 0x00002AC3, 0x00000001, 0x0006000C, 0x00000013, 0x0000466F, 0x00000001, + 0x0000003E, 0x0000437E, 0x00050051, 0x0000000D, 0x0000276B, 0x0000466F, 0x00000000, 0x00050051, + 0x0000000D, 0x000050C2, 0x0000466F, 0x00000001, 0x00070050, 0x0000001D, 0x00002353, 0x0000276B, + 0x000050C2, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F62, 0x000200F8, 0x00002000, 0x00050051, + 0x0000000B, 0x0000308F, 0x00002AC3, 0x00000000, 0x0004007C, 0x0000000C, 0x0000589F, 0x0000308F, + 0x00050050, 0x00000012, 0x0000471E, 0x0000589F, 0x0000589F, 0x000500C4, 0x00000012, 0x000047B1, + 0x0000471E, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341B, 0x000047B1, 0x00000867, 0x0004006F, + 0x00000013, 0x00002AA3, 0x0000341B, 0x0005008E, 0x00000013, 0x0000474B, 0x00002AA3, 0x000007FE, + 0x0007000C, 0x00000013, 0x00005E0A, 0x00000001, 0x00000028, 0x00000049, 0x0000474B, 0x00050051, + 0x0000000D, 0x00005F0E, 0x00005E0A, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD6, 0x00005E0A, + 0x00000001, 0x00070050, 0x0000001D, 0x00004120, 0x00005F0E, 0x00003CD6, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x00004C44, 0x00002AC3, 0x00000001, 0x0004007C, 0x0000000C, 0x00003EA3, + 0x00004C44, 0x00050050, 0x00000012, 0x0000471F, 0x00003EA3, 0x00003EA3, 0x000500C4, 0x00000012, + 0x000047B2, 0x0000471F, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341C, 0x000047B2, 0x00000867, + 0x0004006F, 0x00000013, 0x00002AA4, 0x0000341C, 0x0005008E, 0x00000013, 0x0000474C, 0x00002AA4, + 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0B, 0x00000001, 0x00000028, 0x00000049, 0x0000474C, + 0x00050051, 0x0000000D, 0x00005F0F, 0x00005E0B, 0x00000000, 0x00050051, 0x0000000D, 0x0000494E, + 0x00005E0B, 0x00000001, 0x00070050, 0x0000001D, 0x00002354, 0x00005F0F, 0x0000494E, 0x00000A0C, + 0x00000A0C, 0x000200F9, 0x00003F62, 0x000200F8, 0x00001CBE, 0x00050051, 0x0000000B, 0x000056C3, + 0x00002AC3, 0x00000000, 0x00060050, 0x00000014, 0x00004F10, 0x000056C3, 0x000056C3, 0x000056C3, + 0x000500C2, 0x00000014, 0x00002B13, 0x00004F10, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEA, + 0x00002B13, 0x00000105, 0x000500C7, 0x00000014, 0x000048A0, 0x00005DEA, 0x00000466, 0x000500C2, + 0x00000014, 0x00005B94, 0x00005DEA, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CD, 0x00005B94, + 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4F, 0x00000001, 0x0000004B, 0x000048A0, 0x0004007C, + 0x00000014, 0x00002A19, 0x00002C4F, 0x00050082, 0x00000014, 0x0000187E, 0x00000B0C, 0x00002A19, + 0x00050080, 0x00000014, 0x00002214, 0x00002A19, 0x00000938, 0x000600A9, 0x00000014, 0x00002873, + 0x000040CD, 0x00002214, 0x00005B94, 0x000500C4, 0x00000014, 0x00005AD8, 0x000048A0, 0x0000187E, + 0x000500C7, 0x00000014, 0x0000499E, 0x00005AD8, 0x00000466, 0x000600A9, 0x00000014, 0x00002AA5, + 0x000040CD, 0x0000499E, 0x000048A0, 0x00050080, 0x00000014, 0x00005FFD, 0x00002873, 0x000003FA, + 0x000500C4, 0x00000014, 0x00004F83, 0x00005FFD, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAA, + 0x00002AA5, 0x0000008D, 0x000500C5, 0x00000014, 0x00005780, 0x00004F83, 0x00003FAA, 0x000500AA, + 0x00000010, 0x00003604, 0x00005DEA, 0x00000A12, 0x000600A9, 0x00000014, 0x00004246, 0x00003604, + 0x00000A12, 0x00005780, 0x0004007C, 0x00000018, 0x000029D3, 0x00004246, 0x000500C2, 0x0000000B, + 0x00004BA8, 0x000056C3, 0x00000A64, 0x00040070, 0x0000000D, 0x00004812, 0x00004BA8, 0x00050085, + 0x0000000D, 0x00003E23, 0x00004812, 0x00000149, 0x00050051, 0x0000000D, 0x000053C6, 0x000029D3, + 0x00000000, 0x00050051, 0x0000000D, 0x00002A59, 0x000029D3, 0x00000001, 0x00050051, 0x0000000D, + 0x00001E9B, 0x000029D3, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDC, 0x000053C6, 0x00002A59, + 0x00001E9B, 0x00003E23, 0x00050051, 0x0000000B, 0x000027F7, 0x00002AC3, 0x00000001, 0x00060050, + 0x00000014, 0x00003510, 0x000027F7, 0x000027F7, 0x000027F7, 0x000500C2, 0x00000014, 0x00002B14, + 0x00003510, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEB, 0x00002B14, 0x00000105, 0x000500C7, + 0x00000014, 0x000048A1, 0x00005DEB, 0x00000466, 0x000500C2, 0x00000014, 0x00005B95, 0x00005DEB, + 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CE, 0x00005B95, 0x00000A12, 0x0006000C, 0x00000016, + 0x00002C50, 0x00000001, 0x0000004B, 0x000048A1, 0x0004007C, 0x00000014, 0x00002A1A, 0x00002C50, + 0x00050082, 0x00000014, 0x0000187F, 0x00000B0C, 0x00002A1A, 0x00050080, 0x00000014, 0x00002215, + 0x00002A1A, 0x00000938, 0x000600A9, 0x00000014, 0x00002874, 0x000040CE, 0x00002215, 0x00005B95, + 0x000500C4, 0x00000014, 0x00005AD9, 0x000048A1, 0x0000187F, 0x000500C7, 0x00000014, 0x0000499F, + 0x00005AD9, 0x00000466, 0x000600A9, 0x00000014, 0x00002AA6, 0x000040CE, 0x0000499F, 0x000048A1, + 0x00050080, 0x00000014, 0x00005FFE, 0x00002874, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F84, + 0x00005FFE, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAB, 0x00002AA6, 0x0000008D, 0x000500C5, + 0x00000014, 0x00005781, 0x00004F84, 0x00003FAB, 0x000500AA, 0x00000010, 0x00003605, 0x00005DEB, + 0x00000A12, 0x000600A9, 0x00000014, 0x00004247, 0x00003605, 0x00000A12, 0x00005781, 0x0004007C, + 0x00000018, 0x000029D4, 0x00004247, 0x000500C2, 0x0000000B, 0x00004BA9, 0x000027F7, 0x00000A64, + 0x00040070, 0x0000000D, 0x00004813, 0x00004BA9, 0x00050085, 0x0000000D, 0x00003E24, 0x00004813, + 0x00000149, 0x00050051, 0x0000000D, 0x000053C7, 0x000029D4, 0x00000000, 0x00050051, 0x0000000D, + 0x00002A5A, 0x000029D4, 0x00000001, 0x00050051, 0x0000000D, 0x00002B15, 0x000029D4, 0x00000002, + 0x00070050, 0x0000001D, 0x00002355, 0x000053C7, 0x00002A5A, 0x00002B15, 0x00003E24, 0x000200F9, + 0x00003F62, 0x000200F8, 0x00001CC0, 0x00050051, 0x0000000B, 0x000056C4, 0x00002AC3, 0x00000000, + 0x00070050, 0x00000017, 0x00004F11, 0x000056C4, 0x000056C4, 0x000056C4, 0x000056C4, 0x000500C2, + 0x00000017, 0x000024A0, 0x00004F11, 0x0000034D, 0x000500C7, 0x00000017, 0x000049AF, 0x000024A0, + 0x0000027B, 0x00040070, 0x0000001D, 0x00003CB9, 0x000049AF, 0x00050085, 0x0000001D, 0x00004132, + 0x00003CB9, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD4, 0x00002AC3, 0x00000001, 0x00070050, + 0x00000017, 0x0000514F, 0x00005CD4, 0x00005CD4, 0x00005CD4, 0x00005CD4, 0x000500C2, 0x00000017, + 0x000024A1, 0x0000514F, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B0, 0x000024A1, 0x0000027B, + 0x00040070, 0x0000001D, 0x00004931, 0x000049B0, 0x00050085, 0x0000001D, 0x000026A1, 0x00004931, + 0x00000AEE, 0x000200F9, 0x00003F62, 0x000200F8, 0x000038FB, 0x00050051, 0x0000000B, 0x000056C5, + 0x00002AC3, 0x00000000, 0x00070050, 0x00000017, 0x00004F12, 0x000056C5, 0x000056C5, 0x000056C5, + 0x000056C5, 0x000500C2, 0x00000017, 0x000024A2, 0x00004F12, 0x0000028D, 0x000500C7, 0x00000017, + 0x00004A5A, 0x000024A2, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A4, 0x00004A5A, 0x0005008E, + 0x0000001D, 0x00004B25, 0x000036A4, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A1, 0x00002AC3, + 0x00000001, 0x00070050, 0x00000017, 0x0000610D, 0x000021A1, 0x000021A1, 0x000021A1, 0x000021A1, + 0x000500C2, 0x00000017, 0x000024A3, 0x0000610D, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5B, + 0x000024A3, 0x0000064B, 0x00040070, 0x0000001D, 0x0000431C, 0x00004A5B, 0x0005008E, 0x0000001D, + 0x00003094, 0x0000431C, 0x0000017A, 0x000200F9, 0x00003F62, 0x000200F8, 0x00004BFD, 0x00050051, + 0x0000000B, 0x00003090, 0x00002AC3, 0x00000000, 0x0004007C, 0x0000000D, 0x00004FF0, 0x00003090, + 0x00050050, 0x00000013, 0x00004338, 0x00004FF0, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D92, + 0x00004338, 0x00004338, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, + 0x000056B3, 0x00002AC3, 0x00000001, 0x0004007C, 0x0000000D, 0x00003F6A, 0x000056B3, 0x00050050, + 0x00000013, 0x00004FB0, 0x00003F6A, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3C, 0x00004FB0, + 0x00004FB0, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000200F9, 0x00003F62, 0x000200F8, + 0x00003F62, 0x000F00F5, 0x0000001D, 0x00002BF7, 0x00005A3C, 0x00004BFD, 0x00003094, 0x000038FB, + 0x000026A1, 0x00001CC0, 0x00002355, 0x00001CBE, 0x00002354, 0x00002000, 0x00002353, 0x00002037, + 0x000F00F5, 0x0000001D, 0x00003592, 0x00002D92, 0x00004BFD, 0x00004B25, 0x000038FB, 0x00004132, + 0x00001CC0, 0x00003DDC, 0x00001CBE, 0x00004120, 0x00002000, 0x00003910, 0x00002037, 0x000200F9, + 0x00005311, 0x000200F8, 0x00003B67, 0x000500AA, 0x00000009, 0x00005452, 0x0000199B, 0x00000A10, + 0x000300F7, 0x00004F4E, 0x00000002, 0x000400FA, 0x00005452, 0x00002628, 0x00002F66, 0x000200F8, + 0x00002F66, 0x00060041, 0x00000288, 0x00004BD4, 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, + 0x0000000B, 0x00005D4D, 0x00004BD4, 0x00050080, 0x0000000B, 0x00002DB9, 0x000051FC, 0x00000A0D, + 0x00060041, 0x00000288, 0x00001907, 0x00000CC7, 0x00000A0B, 0x00002DB9, 0x0004003D, 0x0000000B, + 0x00005C6A, 0x00001907, 0x00050080, 0x0000000B, 0x00002DBA, 0x000051FC, 0x0000199B, 0x00060041, + 0x00000288, 0x00001908, 0x00000CC7, 0x00000A0B, 0x00002DBA, 0x0004003D, 0x0000000B, 0x00005C6B, + 0x00001908, 0x00050080, 0x0000000B, 0x00002DBB, 0x00002DBA, 0x00000A0D, 0x00060041, 0x00000288, + 0x00005FF8, 0x00000CC7, 0x00000A0B, 0x00002DBB, 0x0004003D, 0x0000000B, 0x00004006, 0x00005FF8, + 0x00070050, 0x00000017, 0x00005136, 0x00005D4D, 0x00005C6A, 0x00005C6B, 0x00004006, 0x000200F9, + 0x00004F4E, 0x000200F8, 0x00002628, 0x00060041, 0x00000288, 0x0000554A, 0x00000CC7, 0x00000A0B, + 0x000051FC, 0x0004003D, 0x0000000B, 0x00005D4E, 0x0000554A, 0x00050080, 0x0000000B, 0x00002DBC, + 0x000051FC, 0x00000A0D, 0x00060041, 0x00000288, 0x00001909, 0x00000CC7, 0x00000A0B, 0x00002DBC, + 0x0004003D, 0x0000000B, 0x00005C6C, 0x00001909, 0x00050080, 0x0000000B, 0x00002DBD, 0x000051FC, + 0x00000A10, 0x00060041, 0x00000288, 0x0000190A, 0x00000CC7, 0x00000A0B, 0x00002DBD, 0x0004003D, + 0x0000000B, 0x00005C6D, 0x0000190A, 0x00050080, 0x0000000B, 0x00002DBE, 0x000051FC, 0x00000A13, + 0x00060041, 0x00000288, 0x00005FFF, 0x00000CC7, 0x00000A0B, 0x00002DBE, 0x0004003D, 0x0000000B, + 0x00004007, 0x00005FFF, 0x00070050, 0x00000017, 0x00005137, 0x00005D4E, 0x00005C6C, 0x00005C6D, + 0x00004007, 0x000200F9, 0x00004F4E, 0x000200F8, 0x00004F4E, 0x000700F5, 0x00000017, 0x00002AC4, + 0x00005137, 0x00002628, 0x00005136, 0x00002F66, 0x000300F7, 0x00004F25, 0x00000000, 0x000700FB, + 0x00002180, 0x00004F58, 0x00000005, 0x0000215A, 0x00000007, 0x00002038, 0x000200F8, 0x00002038, + 0x00050051, 0x0000000B, 0x00005F5B, 0x00002AC4, 0x00000000, 0x0006000C, 0x00000013, 0x0000606C, + 0x00000001, 0x0000003E, 0x00005F5B, 0x00050051, 0x0000000D, 0x00002779, 0x0000606C, 0x00000000, + 0x00050051, 0x0000000D, 0x00003EBC, 0x0000606C, 0x00000001, 0x00050051, 0x0000000B, 0x00004285, + 0x00002AC4, 0x00000001, 0x0006000C, 0x00000013, 0x00003CF9, 0x00000001, 0x0000003E, 0x00004285, + 0x00050051, 0x0000000D, 0x0000276C, 0x00003CF9, 0x00000000, 0x00050051, 0x0000000D, 0x0000444B, + 0x00003CF9, 0x00000001, 0x00070050, 0x0000001D, 0x00003911, 0x00002779, 0x00003EBC, 0x0000276C, + 0x0000444B, 0x00050051, 0x0000000B, 0x0000437F, 0x00002AC4, 0x00000002, 0x0006000C, 0x00000013, + 0x00004670, 0x00000001, 0x0000003E, 0x0000437F, 0x00050051, 0x0000000D, 0x0000277A, 0x00004670, + 0x00000000, 0x00050051, 0x0000000D, 0x00003EBD, 0x00004670, 0x00000001, 0x00050051, 0x0000000B, + 0x00004286, 0x00002AC4, 0x00000003, 0x0006000C, 0x00000013, 0x00003CFA, 0x00000001, 0x0000003E, + 0x00004286, 0x00050051, 0x0000000D, 0x0000276D, 0x00003CFA, 0x00000000, 0x00050051, 0x0000000D, + 0x000050C3, 0x00003CFA, 0x00000001, 0x00070050, 0x0000001D, 0x00002356, 0x0000277A, 0x00003EBD, + 0x0000276D, 0x000050C3, 0x000200F9, 0x00004F25, 0x000200F8, 0x0000215A, 0x0007004F, 0x00000011, + 0x000025FD, 0x00002AC4, 0x00002AC4, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x00005B3E, + 0x000025FD, 0x0009004F, 0x0000001A, 0x000060D2, 0x00005B3E, 0x00005B3E, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048AA, 0x000060D2, 0x00000122, 0x000500C3, + 0x0000001A, 0x00003D91, 0x000048AA, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA7, 0x00003D91, + 0x0005008E, 0x0000001D, 0x00004723, 0x00002AA7, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006293, + 0x00000001, 0x00000028, 0x00000504, 0x00004723, 0x0007004F, 0x00000011, 0x0000376D, 0x00002AC4, + 0x00002AC4, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C1, 0x0000376D, 0x0009004F, + 0x0000001A, 0x000060D3, 0x000024C1, 0x000024C1, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C4, 0x0000001A, 0x000048AB, 0x000060D3, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D92, + 0x000048AB, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA8, 0x00003D92, 0x0005008E, 0x0000001D, + 0x000053C1, 0x00002AA8, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004364, 0x00000001, 0x00000028, + 0x00000504, 0x000053C1, 0x000200F9, 0x00004F25, 0x000200F8, 0x00004F58, 0x0007004F, 0x00000011, + 0x00002629, 0x00002AC4, 0x00002AC4, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x0000515B, + 0x00002629, 0x00050051, 0x0000000D, 0x00001B80, 0x0000515B, 0x00000000, 0x00050051, 0x0000000D, + 0x0000346C, 0x0000515B, 0x00000001, 0x00070050, 0x0000001D, 0x0000427A, 0x00001B80, 0x0000346C, + 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DA, 0x00002AC4, 0x00002AC4, 0x00000002, + 0x00000003, 0x0004007C, 0x00000013, 0x0000375F, 0x000041DA, 0x00050051, 0x0000000D, 0x00001B81, + 0x0000375F, 0x00000000, 0x00050051, 0x0000000D, 0x0000410A, 0x0000375F, 0x00000001, 0x00070050, + 0x0000001D, 0x00002357, 0x00001B81, 0x0000410A, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F25, + 0x000200F8, 0x00004F25, 0x000900F5, 0x0000001D, 0x00002BF8, 0x00002357, 0x00004F58, 0x00004364, + 0x0000215A, 0x00002356, 0x00002038, 0x000900F5, 0x0000001D, 0x00003593, 0x0000427A, 0x00004F58, + 0x00006293, 0x0000215A, 0x00003911, 0x00002038, 0x000200F9, 0x00005311, 0x000200F8, 0x00005311, + 0x000700F5, 0x0000001D, 0x0000230C, 0x00002BF8, 0x00004F25, 0x00002BF7, 0x00003F62, 0x000700F5, + 0x0000001D, 0x00004C8B, 0x00003593, 0x00004F25, 0x00003592, 0x00003F62, 0x00050081, 0x0000001D, + 0x00004346, 0x000046B0, 0x00004C8B, 0x00050081, 0x0000001D, 0x000019F1, 0x0000455A, 0x0000230C, + 0x00050080, 0x0000000B, 0x00003FF8, 0x00001FB2, 0x000037B2, 0x000300F7, 0x00005312, 0x00000002, + 0x000400FA, 0x00005AEF, 0x00003B68, 0x000040BC, 0x000200F8, 0x000040BC, 0x000500AA, 0x00000009, + 0x00004ADE, 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F4F, 0x00000002, 0x000400FA, 0x00004ADE, + 0x0000262A, 0x00002F67, 0x000200F8, 0x00002F67, 0x00060041, 0x00000288, 0x00004BD5, 0x00000CC7, + 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D4F, 0x00004BD5, 0x00050080, 0x0000000B, + 0x00002DBF, 0x00003FF8, 0x0000199B, 0x00060041, 0x00000288, 0x00006000, 0x00000CC7, 0x00000A0B, + 0x00002DBF, 0x0004003D, 0x0000000B, 0x00004008, 0x00006000, 0x00050050, 0x00000011, 0x00005138, + 0x00005D4F, 0x00004008, 0x000200F9, 0x00004F4F, 0x000200F8, 0x0000262A, 0x00060041, 0x00000288, + 0x0000554B, 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D50, 0x0000554B, + 0x00050080, 0x0000000B, 0x00002DC0, 0x00003FF8, 0x00000A0D, 0x00060041, 0x00000288, 0x00006001, + 0x00000CC7, 0x00000A0B, 0x00002DC0, 0x0004003D, 0x0000000B, 0x00004009, 0x00006001, 0x00050050, + 0x00000011, 0x00005139, 0x00005D50, 0x00004009, 0x000200F9, 0x00004F4F, 0x000200F8, 0x00004F4F, + 0x000700F5, 0x00000011, 0x00002AC5, 0x00005139, 0x0000262A, 0x00005138, 0x00002F67, 0x000300F7, + 0x00003F63, 0x00000000, 0x001300FB, 0x00002180, 0x00004BFE, 0x00000000, 0x000038FC, 0x00000001, + 0x000038FC, 0x00000002, 0x00001CC2, 0x0000000A, 0x00001CC2, 0x00000003, 0x00001CC1, 0x0000000C, + 0x00001CC1, 0x00000004, 0x00002001, 0x00000006, 0x00002039, 0x000200F8, 0x00002039, 0x00050051, + 0x0000000B, 0x00005F5C, 0x00002AC5, 0x00000000, 0x0006000C, 0x00000013, 0x0000606D, 0x00000001, + 0x0000003E, 0x00005F5C, 0x00050051, 0x0000000D, 0x0000276E, 0x0000606D, 0x00000000, 0x00050051, + 0x0000000D, 0x0000444C, 0x0000606D, 0x00000001, 0x00070050, 0x0000001D, 0x00003912, 0x0000276E, + 0x0000444C, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004380, 0x00002AC5, 0x00000001, + 0x0006000C, 0x00000013, 0x00004671, 0x00000001, 0x0000003E, 0x00004380, 0x00050051, 0x0000000D, + 0x0000276F, 0x00004671, 0x00000000, 0x00050051, 0x0000000D, 0x000050C4, 0x00004671, 0x00000001, + 0x00070050, 0x0000001D, 0x00002358, 0x0000276F, 0x000050C4, 0x00000A0C, 0x00000A0C, 0x000200F9, + 0x00003F63, 0x000200F8, 0x00002001, 0x00050051, 0x0000000B, 0x00003091, 0x00002AC5, 0x00000000, + 0x0004007C, 0x0000000C, 0x000058A0, 0x00003091, 0x00050050, 0x00000012, 0x00004720, 0x000058A0, + 0x000058A0, 0x000500C4, 0x00000012, 0x000047B3, 0x00004720, 0x000007A7, 0x000500C3, 0x00000012, + 0x0000341D, 0x000047B3, 0x00000867, 0x0004006F, 0x00000013, 0x00002AA9, 0x0000341D, 0x0005008E, + 0x00000013, 0x0000474D, 0x00002AA9, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0C, 0x00000001, + 0x00000028, 0x00000049, 0x0000474D, 0x00050051, 0x0000000D, 0x00005F10, 0x00005E0C, 0x00000000, + 0x00050051, 0x0000000D, 0x00003CD7, 0x00005E0C, 0x00000001, 0x00070050, 0x0000001D, 0x00004121, + 0x00005F10, 0x00003CD7, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C45, 0x00002AC5, + 0x00000001, 0x0004007C, 0x0000000C, 0x00003EA4, 0x00004C45, 0x00050050, 0x00000012, 0x00004724, + 0x00003EA4, 0x00003EA4, 0x000500C4, 0x00000012, 0x000047B4, 0x00004724, 0x000007A7, 0x000500C3, + 0x00000012, 0x0000341E, 0x000047B4, 0x00000867, 0x0004006F, 0x00000013, 0x00002AAA, 0x0000341E, + 0x0005008E, 0x00000013, 0x0000474E, 0x00002AAA, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0D, + 0x00000001, 0x00000028, 0x00000049, 0x0000474E, 0x00050051, 0x0000000D, 0x00005F11, 0x00005E0D, + 0x00000000, 0x00050051, 0x0000000D, 0x0000494F, 0x00005E0D, 0x00000001, 0x00070050, 0x0000001D, + 0x00002359, 0x00005F11, 0x0000494F, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F63, 0x000200F8, + 0x00001CC1, 0x00050051, 0x0000000B, 0x000056C6, 0x00002AC5, 0x00000000, 0x00060050, 0x00000014, + 0x00004F13, 0x000056C6, 0x000056C6, 0x000056C6, 0x000500C2, 0x00000014, 0x00002B16, 0x00004F13, + 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEC, 0x00002B16, 0x00000105, 0x000500C7, 0x00000014, + 0x000048A2, 0x00005DEC, 0x00000466, 0x000500C2, 0x00000014, 0x00005B96, 0x00005DEC, 0x00000B0C, + 0x000500AA, 0x00000010, 0x000040CF, 0x00005B96, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C51, + 0x00000001, 0x0000004B, 0x000048A2, 0x0004007C, 0x00000014, 0x00002A1B, 0x00002C51, 0x00050082, + 0x00000014, 0x00001880, 0x00000B0C, 0x00002A1B, 0x00050080, 0x00000014, 0x00002216, 0x00002A1B, + 0x00000938, 0x000600A9, 0x00000014, 0x00002875, 0x000040CF, 0x00002216, 0x00005B96, 0x000500C4, + 0x00000014, 0x00005ADA, 0x000048A2, 0x00001880, 0x000500C7, 0x00000014, 0x000049A0, 0x00005ADA, + 0x00000466, 0x000600A9, 0x00000014, 0x00002AAB, 0x000040CF, 0x000049A0, 0x000048A2, 0x00050080, + 0x00000014, 0x00006002, 0x00002875, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F85, 0x00006002, + 0x00000189, 0x000500C4, 0x00000014, 0x00003FAC, 0x00002AAB, 0x0000008D, 0x000500C5, 0x00000014, + 0x00005782, 0x00004F85, 0x00003FAC, 0x000500AA, 0x00000010, 0x00003606, 0x00005DEC, 0x00000A12, + 0x000600A9, 0x00000014, 0x00004248, 0x00003606, 0x00000A12, 0x00005782, 0x0004007C, 0x00000018, + 0x000029D5, 0x00004248, 0x000500C2, 0x0000000B, 0x00004BAA, 0x000056C6, 0x00000A64, 0x00040070, + 0x0000000D, 0x00004814, 0x00004BAA, 0x00050085, 0x0000000D, 0x00003E25, 0x00004814, 0x00000149, + 0x00050051, 0x0000000D, 0x000053C8, 0x000029D5, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5B, + 0x000029D5, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9C, 0x000029D5, 0x00000002, 0x00070050, + 0x0000001D, 0x00003DDD, 0x000053C8, 0x00002A5B, 0x00001E9C, 0x00003E25, 0x00050051, 0x0000000B, + 0x000027F8, 0x00002AC5, 0x00000001, 0x00060050, 0x00000014, 0x00003511, 0x000027F8, 0x000027F8, + 0x000027F8, 0x000500C2, 0x00000014, 0x00002B17, 0x00003511, 0x00000BB4, 0x000500C7, 0x00000014, + 0x00005DED, 0x00002B17, 0x00000105, 0x000500C7, 0x00000014, 0x000048A3, 0x00005DED, 0x00000466, + 0x000500C2, 0x00000014, 0x00005B97, 0x00005DED, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D0, + 0x00005B97, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C52, 0x00000001, 0x0000004B, 0x000048A3, + 0x0004007C, 0x00000014, 0x00002A1C, 0x00002C52, 0x00050082, 0x00000014, 0x00001881, 0x00000B0C, + 0x00002A1C, 0x00050080, 0x00000014, 0x00002217, 0x00002A1C, 0x00000938, 0x000600A9, 0x00000014, + 0x00002876, 0x000040D0, 0x00002217, 0x00005B97, 0x000500C4, 0x00000014, 0x00005ADB, 0x000048A3, + 0x00001881, 0x000500C7, 0x00000014, 0x000049A1, 0x00005ADB, 0x00000466, 0x000600A9, 0x00000014, + 0x00002AAC, 0x000040D0, 0x000049A1, 0x000048A3, 0x00050080, 0x00000014, 0x00006003, 0x00002876, + 0x000003FA, 0x000500C4, 0x00000014, 0x00004F86, 0x00006003, 0x00000189, 0x000500C4, 0x00000014, + 0x00003FAD, 0x00002AAC, 0x0000008D, 0x000500C5, 0x00000014, 0x00005783, 0x00004F86, 0x00003FAD, + 0x000500AA, 0x00000010, 0x00003607, 0x00005DED, 0x00000A12, 0x000600A9, 0x00000014, 0x00004249, + 0x00003607, 0x00000A12, 0x00005783, 0x0004007C, 0x00000018, 0x000029D6, 0x00004249, 0x000500C2, + 0x0000000B, 0x00004BAB, 0x000027F8, 0x00000A64, 0x00040070, 0x0000000D, 0x00004815, 0x00004BAB, + 0x00050085, 0x0000000D, 0x00003E26, 0x00004815, 0x00000149, 0x00050051, 0x0000000D, 0x000053C9, + 0x000029D6, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5C, 0x000029D6, 0x00000001, 0x00050051, + 0x0000000D, 0x00002B18, 0x000029D6, 0x00000002, 0x00070050, 0x0000001D, 0x0000235A, 0x000053C9, + 0x00002A5C, 0x00002B18, 0x00003E26, 0x000200F9, 0x00003F63, 0x000200F8, 0x00001CC2, 0x00050051, + 0x0000000B, 0x000056C7, 0x00002AC5, 0x00000000, 0x00070050, 0x00000017, 0x00004F14, 0x000056C7, + 0x000056C7, 0x000056C7, 0x000056C7, 0x000500C2, 0x00000017, 0x000024A4, 0x00004F14, 0x0000034D, + 0x000500C7, 0x00000017, 0x000049B1, 0x000024A4, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBA, + 0x000049B1, 0x00050085, 0x0000001D, 0x00004133, 0x00003CBA, 0x00000AEE, 0x00050051, 0x0000000B, + 0x00005CD5, 0x00002AC5, 0x00000001, 0x00070050, 0x00000017, 0x00005150, 0x00005CD5, 0x00005CD5, + 0x00005CD5, 0x00005CD5, 0x000500C2, 0x00000017, 0x000024A5, 0x00005150, 0x0000034D, 0x000500C7, + 0x00000017, 0x000049B2, 0x000024A5, 0x0000027B, 0x00040070, 0x0000001D, 0x00004932, 0x000049B2, + 0x00050085, 0x0000001D, 0x000026A2, 0x00004932, 0x00000AEE, 0x000200F9, 0x00003F63, 0x000200F8, + 0x000038FC, 0x00050051, 0x0000000B, 0x000056C8, 0x00002AC5, 0x00000000, 0x00070050, 0x00000017, + 0x00004F15, 0x000056C8, 0x000056C8, 0x000056C8, 0x000056C8, 0x000500C2, 0x00000017, 0x000024A6, + 0x00004F15, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5C, 0x000024A6, 0x0000064B, 0x00040070, + 0x0000001D, 0x000036A5, 0x00004A5C, 0x0005008E, 0x0000001D, 0x00004B26, 0x000036A5, 0x0000017A, + 0x00050051, 0x0000000B, 0x000021A2, 0x00002AC5, 0x00000001, 0x00070050, 0x00000017, 0x0000610E, + 0x000021A2, 0x000021A2, 0x000021A2, 0x000021A2, 0x000500C2, 0x00000017, 0x000024A7, 0x0000610E, + 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5D, 0x000024A7, 0x0000064B, 0x00040070, 0x0000001D, + 0x0000431D, 0x00004A5D, 0x0005008E, 0x0000001D, 0x00003095, 0x0000431D, 0x0000017A, 0x000200F9, + 0x00003F63, 0x000200F8, 0x00004BFE, 0x00050051, 0x0000000B, 0x00003096, 0x00002AC5, 0x00000000, + 0x0004007C, 0x0000000D, 0x00004FF1, 0x00003096, 0x00050050, 0x00000013, 0x00004339, 0x00004FF1, + 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D93, 0x00004339, 0x00004339, 0x00000000, 0x00000001, + 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B4, 0x00002AC5, 0x00000001, 0x0004007C, + 0x0000000D, 0x00003F6B, 0x000056B4, 0x00050050, 0x00000013, 0x00004FB1, 0x00003F6B, 0x00000A0C, + 0x0009004F, 0x0000001D, 0x00005A3D, 0x00004FB1, 0x00004FB1, 0x00000000, 0x00000001, 0x00000001, + 0x00000001, 0x000200F9, 0x00003F63, 0x000200F8, 0x00003F63, 0x000F00F5, 0x0000001D, 0x00002BF9, + 0x00005A3D, 0x00004BFE, 0x00003095, 0x000038FC, 0x000026A2, 0x00001CC2, 0x0000235A, 0x00001CC1, + 0x00002359, 0x00002001, 0x00002358, 0x00002039, 0x000F00F5, 0x0000001D, 0x00003594, 0x00002D93, + 0x00004BFE, 0x00004B26, 0x000038FC, 0x00004133, 0x00001CC2, 0x00003DDD, 0x00001CC1, 0x00004121, + 0x00002001, 0x00003912, 0x00002039, 0x000200F9, 0x00005312, 0x000200F8, 0x00003B68, 0x000500AA, + 0x00000009, 0x00005453, 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F50, 0x00000002, 0x000400FA, + 0x00005453, 0x0000262B, 0x00002F68, 0x000200F8, 0x00002F68, 0x00060041, 0x00000288, 0x00004BD6, + 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D51, 0x00004BD6, 0x00050080, + 0x0000000B, 0x00002DC1, 0x00003FF8, 0x00000A0D, 0x00060041, 0x00000288, 0x0000190B, 0x00000CC7, + 0x00000A0B, 0x00002DC1, 0x0004003D, 0x0000000B, 0x00005C6E, 0x0000190B, 0x00050080, 0x0000000B, + 0x00002DC2, 0x00003FF8, 0x0000199B, 0x00060041, 0x00000288, 0x0000190C, 0x00000CC7, 0x00000A0B, + 0x00002DC2, 0x0004003D, 0x0000000B, 0x00005C6F, 0x0000190C, 0x00050080, 0x0000000B, 0x00002DC3, + 0x00002DC2, 0x00000A0D, 0x00060041, 0x00000288, 0x00006004, 0x00000CC7, 0x00000A0B, 0x00002DC3, + 0x0004003D, 0x0000000B, 0x0000400A, 0x00006004, 0x00070050, 0x00000017, 0x0000513A, 0x00005D51, + 0x00005C6E, 0x00005C6F, 0x0000400A, 0x000200F9, 0x00004F50, 0x000200F8, 0x0000262B, 0x00060041, + 0x00000288, 0x0000554C, 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D52, + 0x0000554C, 0x00050080, 0x0000000B, 0x00002DC4, 0x00003FF8, 0x00000A0D, 0x00060041, 0x00000288, + 0x0000190D, 0x00000CC7, 0x00000A0B, 0x00002DC4, 0x0004003D, 0x0000000B, 0x00005C70, 0x0000190D, + 0x00050080, 0x0000000B, 0x00002DC5, 0x00003FF8, 0x00000A10, 0x00060041, 0x00000288, 0x0000190E, + 0x00000CC7, 0x00000A0B, 0x00002DC5, 0x0004003D, 0x0000000B, 0x00005C71, 0x0000190E, 0x00050080, + 0x0000000B, 0x00002DC6, 0x00003FF8, 0x00000A13, 0x00060041, 0x00000288, 0x00006005, 0x00000CC7, + 0x00000A0B, 0x00002DC6, 0x0004003D, 0x0000000B, 0x0000400B, 0x00006005, 0x00070050, 0x00000017, + 0x0000513B, 0x00005D52, 0x00005C70, 0x00005C71, 0x0000400B, 0x000200F9, 0x00004F50, 0x000200F8, + 0x00004F50, 0x000700F5, 0x00000017, 0x00002AC6, 0x0000513B, 0x0000262B, 0x0000513A, 0x00002F68, + 0x000300F7, 0x00004F26, 0x00000000, 0x000700FB, 0x00002180, 0x00004F59, 0x00000005, 0x0000215B, + 0x00000007, 0x0000203A, 0x000200F8, 0x0000203A, 0x00050051, 0x0000000B, 0x00005F5D, 0x00002AC6, + 0x00000000, 0x0006000C, 0x00000013, 0x0000606E, 0x00000001, 0x0000003E, 0x00005F5D, 0x00050051, + 0x0000000D, 0x0000277B, 0x0000606E, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBE, 0x0000606E, + 0x00000001, 0x00050051, 0x0000000B, 0x00004287, 0x00002AC6, 0x00000001, 0x0006000C, 0x00000013, + 0x00003CFB, 0x00000001, 0x0000003E, 0x00004287, 0x00050051, 0x0000000D, 0x00002770, 0x00003CFB, + 0x00000000, 0x00050051, 0x0000000D, 0x0000444D, 0x00003CFB, 0x00000001, 0x00070050, 0x0000001D, + 0x00003913, 0x0000277B, 0x00003EBE, 0x00002770, 0x0000444D, 0x00050051, 0x0000000B, 0x00004381, + 0x00002AC6, 0x00000002, 0x0006000C, 0x00000013, 0x00004672, 0x00000001, 0x0000003E, 0x00004381, + 0x00050051, 0x0000000D, 0x0000277C, 0x00004672, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBF, + 0x00004672, 0x00000001, 0x00050051, 0x0000000B, 0x00004288, 0x00002AC6, 0x00000003, 0x0006000C, + 0x00000013, 0x00003CFC, 0x00000001, 0x0000003E, 0x00004288, 0x00050051, 0x0000000D, 0x00002771, + 0x00003CFC, 0x00000000, 0x00050051, 0x0000000D, 0x000050C5, 0x00003CFC, 0x00000001, 0x00070050, + 0x0000001D, 0x0000235B, 0x0000277C, 0x00003EBF, 0x00002771, 0x000050C5, 0x000200F9, 0x00004F26, + 0x000200F8, 0x0000215B, 0x0007004F, 0x00000011, 0x000025FE, 0x00002AC6, 0x00002AC6, 0x00000000, + 0x00000001, 0x0004007C, 0x00000012, 0x00005B3F, 0x000025FE, 0x0009004F, 0x0000001A, 0x000060D4, + 0x00005B3F, 0x00005B3F, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, + 0x000048AC, 0x000060D4, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D93, 0x000048AC, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002AAD, 0x00003D93, 0x0005008E, 0x0000001D, 0x00004725, 0x00002AAD, + 0x000007FE, 0x0007000C, 0x0000001D, 0x00006294, 0x00000001, 0x00000028, 0x00000504, 0x00004725, + 0x0007004F, 0x00000011, 0x0000376E, 0x00002AC6, 0x00002AC6, 0x00000002, 0x00000003, 0x0004007C, + 0x00000012, 0x000024C2, 0x0000376E, 0x0009004F, 0x0000001A, 0x000060D5, 0x000024C2, 0x000024C2, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048AD, 0x000060D5, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D94, 0x000048AD, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002AAE, 0x00003D94, 0x0005008E, 0x0000001D, 0x000053CA, 0x00002AAE, 0x000007FE, 0x0007000C, + 0x0000001D, 0x00004365, 0x00000001, 0x00000028, 0x00000504, 0x000053CA, 0x000200F9, 0x00004F26, + 0x000200F8, 0x00004F59, 0x0007004F, 0x00000011, 0x0000262C, 0x00002AC6, 0x00002AC6, 0x00000000, + 0x00000001, 0x0004007C, 0x00000013, 0x0000515C, 0x0000262C, 0x00050051, 0x0000000D, 0x00001B82, + 0x0000515C, 0x00000000, 0x00050051, 0x0000000D, 0x0000346D, 0x0000515C, 0x00000001, 0x00070050, + 0x0000001D, 0x0000427B, 0x00001B82, 0x0000346D, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, + 0x000041DB, 0x00002AC6, 0x00002AC6, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x00003760, + 0x000041DB, 0x00050051, 0x0000000D, 0x00001B83, 0x00003760, 0x00000000, 0x00050051, 0x0000000D, + 0x0000410B, 0x00003760, 0x00000001, 0x00070050, 0x0000001D, 0x0000235C, 0x00001B83, 0x0000410B, + 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F26, 0x000200F8, 0x00004F26, 0x000900F5, 0x0000001D, + 0x00002BFA, 0x0000235C, 0x00004F59, 0x00004365, 0x0000215B, 0x0000235B, 0x0000203A, 0x000900F5, + 0x0000001D, 0x00003595, 0x0000427B, 0x00004F59, 0x00006294, 0x0000215B, 0x00003913, 0x0000203A, + 0x000200F9, 0x00005312, 0x000200F8, 0x00005312, 0x000700F5, 0x0000001D, 0x0000230D, 0x00002BFA, + 0x00004F26, 0x00002BF9, 0x00003F63, 0x000700F5, 0x0000001D, 0x00004C8C, 0x00003595, 0x00004F26, + 0x00003594, 0x00003F63, 0x00050081, 0x0000001D, 0x00004C41, 0x00004346, 0x00004C8C, 0x00050081, + 0x0000001D, 0x00005D3D, 0x000019F1, 0x0000230D, 0x000200F9, 0x00005EC8, 0x000200F8, 0x00005EC8, + 0x000700F5, 0x0000001D, 0x00002BA7, 0x0000455A, 0x00005310, 0x00005D3D, 0x00005312, 0x000700F5, + 0x0000001D, 0x00003854, 0x000046B0, 0x00005310, 0x00004C41, 0x00005312, 0x000700F5, 0x0000000D, + 0x000038B6, 0x00005A1D, 0x00005310, 0x00002F3A, 0x00005312, 0x000200F9, 0x00005313, 0x000200F8, + 0x00005313, 0x000700F5, 0x0000001D, 0x00002BA8, 0x00002662, 0x0000530F, 0x00002BA7, 0x00005EC8, + 0x000700F5, 0x0000001D, 0x00003063, 0x000036E3, 0x0000530F, 0x00003854, 0x00005EC8, 0x000700F5, + 0x0000000D, 0x00002EA8, 0x00002B2C, 0x0000530F, 0x000038B6, 0x00005EC8, 0x0005008E, 0x0000001D, + 0x0000623F, 0x00003063, 0x00002EA8, 0x0005008E, 0x0000001D, 0x0000255A, 0x00002BA8, 0x00002EA8, + 0x000300F7, 0x00003F64, 0x00000002, 0x000400FA, 0x00001D59, 0x00002741, 0x00003F64, 0x000200F8, + 0x00002741, 0x0009004F, 0x0000001D, 0x0000478C, 0x0000623F, 0x0000623F, 0x00000002, 0x00000001, + 0x00000000, 0x00000003, 0x0009004F, 0x0000001D, 0x00004F75, 0x0000255A, 0x0000255A, 0x00000002, + 0x00000001, 0x00000000, 0x00000003, 0x000200F9, 0x00003F64, 0x000200F8, 0x00003F64, 0x000700F5, + 0x0000001D, 0x00002688, 0x0000255A, 0x00005313, 0x00004F75, 0x00002741, 0x000700F5, 0x0000001D, + 0x00003589, 0x0000623F, 0x00005313, 0x0000478C, 0x00002741, 0x000500B0, 0x00000009, 0x000038D2, + 0x00001DD8, 0x00001CBF, 0x000300F7, 0x00006070, 0x00000002, 0x000400FA, 0x000038D2, 0x000055EA, + 0x00006070, 0x000200F8, 0x000055EA, 0x000200F9, 0x00006070, 0x000200F8, 0x00006070, 0x000700F5, + 0x0000001D, 0x000027FC, 0x00002688, 0x00003F64, 0x00003589, 0x000055EA, 0x00050080, 0x00000011, + 0x000027FA, 0x00002EF9, 0x000059EC, 0x00050086, 0x00000011, 0x0000235D, 0x000027FA, 0x00005C31, + 0x00050051, 0x0000000B, 0x000052AC, 0x0000235D, 0x00000000, 0x00050051, 0x0000000B, 0x0000472A, + 0x0000235D, 0x00000001, 0x00060050, 0x00000014, 0x000024C9, 0x000052AC, 0x0000472A, 0x00004408, + 0x000300F7, 0x00005341, 0x00000002, 0x000400FA, 0x0000500F, 0x000056C9, 0x00002AAF, 0x000200F8, + 0x00002AAF, 0x0007004F, 0x00000011, 0x00001CAB, 0x000024C9, 0x000024C9, 0x00000000, 0x00000001, + 0x0004007C, 0x00000012, 0x000059CF, 0x00001CAB, 0x00050051, 0x0000000C, 0x0000190F, 0x000059CF, + 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x0000190F, 0x00000A1A, 0x00050051, 0x0000000C, + 0x00002747, 0x000059CF, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, + 0x000500C2, 0x0000000B, 0x00005B4D, 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AA, + 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, + 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A2B, + 0x000500C7, 0x0000000C, 0x00002AB6, 0x0000190F, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, + 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, + 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454D, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, + 0x00000A16, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, + 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00004A8E, 0x00002F76, + 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, + 0x00003C4B, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002747, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x0000544A, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004157, 0x00004D30, + 0x0000544A, 0x000500C7, 0x0000000C, 0x00005022, 0x00004157, 0x0000040B, 0x000500C4, 0x0000000C, + 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, + 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x00004158, + 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004157, 0x00000388, 0x000500C4, + 0x0000000C, 0x0000544B, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x00004158, + 0x0000544B, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, + 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x0000190F, 0x00000A14, + 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005454, + 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544C, 0x00005454, 0x00000A1D, 0x00050080, + 0x0000000C, 0x00003C4C, 0x00004144, 0x0000544C, 0x000500C7, 0x0000000C, 0x00002E06, 0x00004157, + 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4C, 0x00002E06, 0x0004007C, 0x0000000B, + 0x0000566F, 0x0000394F, 0x000200F9, 0x00005341, 0x000200F8, 0x000056C9, 0x0004007C, 0x00000016, + 0x000019AD, 0x000024C9, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000001, 0x000500C3, + 0x0000000C, 0x000024FE, 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002748, 0x000019AD, + 0x00000002, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A11, 0x000500C2, 0x0000000B, + 0x00005B4E, 0x00006273, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, + 0x0000000C, 0x00005321, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FE, + 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, + 0x00003097, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x00003097, 0x00050051, + 0x0000000C, 0x00006242, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, + 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, + 0x0000225D, 0x000049FC, 0x00000A28, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, + 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, + 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x000042C2, 0x00000A1D, 0x000500C4, + 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, + 0x0000454E, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A28, 0x000500C3, 0x0000000C, + 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002218, 0x000042C2, 0x00000A14, + 0x00050080, 0x0000000C, 0x000035A3, 0x00002218, 0x0000405D, 0x000500C7, 0x0000000C, 0x00005A0C, + 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, + 0x0000496A, 0x000500C7, 0x0000000C, 0x00004AE0, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544D, 0x00004AE0, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4D, 0x00005A0C, 0x0000544D, + 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, + 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, + 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, + 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B6, 0x00002748, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544E, 0x000047B6, 0x00000A28, 0x00050080, 0x0000000C, 0x00004159, 0x0000285C, 0x0000544E, + 0x000500C7, 0x0000000C, 0x00004AE1, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544F, + 0x00004AE1, 0x00000A17, 0x00050080, 0x0000000C, 0x0000415A, 0x00004159, 0x0000544F, 0x000500C7, + 0x0000000C, 0x00004FD6, 0x00003C4D, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, + 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x0000415A, 0x00000A1D, 0x000500C7, 0x0000000C, + 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, + 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, + 0x00003C4D, 0x00000A05, 0x00050080, 0x0000000C, 0x00002AB0, 0x00005B32, 0x00005AB1, 0x000500C4, + 0x0000000C, 0x00005B33, 0x00002AB0, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x0000415A, + 0x0000040B, 0x00050080, 0x0000000C, 0x00002AB1, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, + 0x00005B34, 0x00002AB1, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x0000415A, 0x00000AC8, + 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, 0x00005670, + 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, 0x000024FC, + 0x00005670, 0x000056C9, 0x0000566F, 0x00002AAF, 0x00050084, 0x00000011, 0x00003FAE, 0x0000235D, + 0x00005C31, 0x00050082, 0x00000011, 0x00003F85, 0x000027FA, 0x00003FAE, 0x00050051, 0x0000000B, + 0x0000448F, 0x00005C31, 0x00000001, 0x00050084, 0x0000000B, 0x00005C50, 0x0000229A, 0x0000448F, + 0x00050084, 0x0000000B, 0x00003CA0, 0x000024FC, 0x00005C50, 0x00050051, 0x0000000B, 0x00003ED4, + 0x00003F85, 0x00000000, 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, 0x0000448F, 0x00050051, + 0x0000000B, 0x00001AE7, 0x00003F85, 0x00000001, 0x00050080, 0x0000000B, 0x000025E1, 0x00003E12, + 0x00001AE7, 0x000500C4, 0x0000000B, 0x00004AFF, 0x000025E1, 0x00000A16, 0x00050080, 0x0000000B, + 0x00001CDE, 0x00003CA0, 0x00004AFF, 0x000500C2, 0x0000000B, 0x00003F2B, 0x00001CDE, 0x00000A16, + 0x0004007C, 0x00000017, 0x0000232F, 0x00003589, 0x000500AA, 0x00000009, 0x00001FEE, 0x00004ADC, + 0x00000A19, 0x000300F7, 0x000039BC, 0x00000000, 0x000400FA, 0x00001FEE, 0x000033DF, 0x000039BC, + 0x000200F8, 0x000033DF, 0x0009004F, 0x00000017, 0x00001F16, 0x0000232F, 0x0000232F, 0x00000003, + 0x00000002, 0x00000001, 0x00000000, 0x000200F9, 0x000039BC, 0x000200F8, 0x000039BC, 0x000700F5, + 0x00000017, 0x00005972, 0x0000232F, 0x00005341, 0x00001F16, 0x000033DF, 0x000600A9, 0x0000000B, + 0x00001F84, 0x00001FEE, 0x00000A10, 0x00004ADC, 0x000500AA, 0x00000009, 0x00005116, 0x00001F84, + 0x00000A16, 0x000300F7, 0x000039BD, 0x00000000, 0x000400FA, 0x00005116, 0x000033E0, 0x000039BD, + 0x000200F8, 0x000033E0, 0x0009004F, 0x00000017, 0x00001F17, 0x00005972, 0x00005972, 0x00000001, + 0x00000000, 0x00000003, 0x00000002, 0x000200F9, 0x000039BD, 0x000200F8, 0x000039BD, 0x000700F5, + 0x00000017, 0x00005973, 0x00005972, 0x000039BC, 0x00001F17, 0x000033E0, 0x000600A9, 0x0000000B, + 0x000019CD, 0x00005116, 0x00000A10, 0x00001F84, 0x000500AA, 0x00000009, 0x00003464, 0x000019CD, + 0x00000A0D, 0x000500AA, 0x00000009, 0x000047C2, 0x000019CD, 0x00000A10, 0x000500A6, 0x00000009, + 0x00005686, 0x00003464, 0x000047C2, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, + 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00005973, + 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, + 0x000050AC, 0x00005973, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, + 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, + 0x00003463, 0x000700F5, 0x00000017, 0x0000587A, 0x00005973, 0x000039BD, 0x00003FF9, 0x00002957, + 0x000500AA, 0x00000009, 0x00004CB6, 0x000019CD, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, + 0x000047C2, 0x00004CB6, 0x000300F7, 0x00002C98, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, + 0x00002C98, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x0000587A, 0x000002ED, + 0x000500C2, 0x00000017, 0x00003BE7, 0x0000587A, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, + 0x00005E17, 0x00003BE7, 0x000200F9, 0x00002C98, 0x000200F8, 0x00002C98, 0x000700F5, 0x00000017, + 0x00004D37, 0x0000587A, 0x00003463, 0x000029E8, 0x00002B38, 0x00060041, 0x00000294, 0x000019BE, + 0x00001592, 0x00000A0B, 0x00003F2B, 0x0003003E, 0x000019BE, 0x00004D37, 0x000500AC, 0x00000009, + 0x00005BF6, 0x0000229A, 0x00000A0D, 0x000300F7, 0x00004AAC, 0x00000002, 0x000400FA, 0x00005BF6, + 0x00006140, 0x000055EB, 0x000200F8, 0x000055EB, 0x000200F9, 0x00004AAC, 0x000200F8, 0x00006140, + 0x00050086, 0x0000000B, 0x000026D4, 0x00001DD8, 0x0000229A, 0x00050084, 0x0000000B, 0x0000237E, + 0x000026D4, 0x0000229A, 0x00050082, 0x0000000B, 0x00003171, 0x00001DD8, 0x0000237E, 0x00050080, + 0x0000000B, 0x00002527, 0x00003171, 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, + 0x0000229A, 0x000300F7, 0x00002458, 0x00000000, 0x000400FA, 0x0000343F, 0x00001CDB, 0x000055EC, + 0x000200F8, 0x000055EC, 0x000200F9, 0x00002458, 0x000200F8, 0x00001CDB, 0x00050084, 0x0000000B, + 0x00003B96, 0x00000A6A, 0x0000229A, 0x000500C4, 0x0000000B, 0x0000540F, 0x00003171, 0x00000A16, + 0x00050082, 0x0000000B, 0x00004944, 0x00003B96, 0x0000540F, 0x000200F9, 0x00002458, 0x000200F8, + 0x00002458, 0x000700F5, 0x0000000B, 0x0000292C, 0x00004944, 0x00001CDB, 0x00000A3A, 0x000055EC, + 0x000200F9, 0x00004AAC, 0x000200F8, 0x00004AAC, 0x000700F5, 0x0000000B, 0x000029BC, 0x0000292C, + 0x00002458, 0x00000A6A, 0x000055EB, 0x00050084, 0x0000000B, 0x0000492B, 0x000029BC, 0x0000448F, + 0x000500C2, 0x0000000B, 0x000044CE, 0x0000492B, 0x00000A16, 0x00050080, 0x0000000B, 0x0000195A, + 0x00003F2B, 0x000044CE, 0x0004007C, 0x00000017, 0x000054CB, 0x000027FC, 0x000300F7, 0x00003F86, + 0x00000000, 0x000400FA, 0x00001FEE, 0x000033E1, 0x00003F86, 0x000200F8, 0x000033E1, 0x0009004F, + 0x00000017, 0x00001F18, 0x000054CB, 0x000054CB, 0x00000003, 0x00000002, 0x00000001, 0x00000000, + 0x000200F9, 0x00003F86, 0x000200F8, 0x00003F86, 0x000700F5, 0x00000017, 0x00002AB2, 0x000054CB, + 0x00004AAC, 0x00001F18, 0x000033E1, 0x000300F7, 0x00003F87, 0x00000000, 0x000400FA, 0x00005116, + 0x000033E2, 0x00003F87, 0x000200F8, 0x000033E2, 0x0009004F, 0x00000017, 0x00001F19, 0x00002AB2, + 0x00002AB2, 0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x000200F9, 0x00003F87, 0x000200F8, + 0x00003F87, 0x000700F5, 0x00000017, 0x00002AB3, 0x00002AB2, 0x00003F86, 0x00001F19, 0x000033E2, + 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, + 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x00002AB3, 0x000009CE, 0x000500C4, 0x00000017, + 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x00002AB3, 0x0000072E, + 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FFA, + 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, + 0x00002AB4, 0x00002AB3, 0x00003F87, 0x00003FFA, 0x00002958, 0x000300F7, 0x00002C99, 0x00000000, + 0x000400FA, 0x00003B23, 0x00002B39, 0x00002C99, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, + 0x00005E18, 0x00002AB4, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AB4, 0x000002ED, + 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002C99, 0x000200F8, + 0x00002C99, 0x000700F5, 0x00000017, 0x00004D39, 0x00002AB4, 0x00003A1A, 0x000029E9, 0x00002B39, + 0x00060041, 0x00000294, 0x00001F75, 0x00001592, 0x00000A0B, 0x0000195A, 0x0003003E, 0x00001F75, + 0x00004D39, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_full_16bpp_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_full_16bpp_cs.h new file mode 100644 index 0000000..ff98046 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_full_16bpp_cs.h @@ -0,0 +1,4420 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25271 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_runtimearr_uint ArrayStride 4 + OpDecorate %_struct_1948 BufferBlock + OpMemberDecorate %_struct_1948 0 NonWritable + OpMemberDecorate %_struct_1948 0 Offset 0 + OpDecorate %3271 NonWritable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %_struct_1036 Block + OpMemberDecorate %_struct_1036 0 Offset 0 + OpMemberDecorate %_struct_1036 1 Offset 4 + OpMemberDecorate %_struct_1036 2 Offset 8 + OpMemberDecorate %_struct_1036 3 Offset 12 + OpMemberDecorate %_struct_1036 4 Offset 16 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v2uint ArrayStride 8 + OpDecorate %_struct_1960 BufferBlock + OpMemberDecorate %_struct_1960 0 NonReadable + OpMemberDecorate %_struct_1960 0 Offset 0 + OpDecorate %5522 NonReadable + OpDecorate %5522 Binding 0 + OpDecorate %5522 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %v4uint = OpTypeVector %uint 4 + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 + %v3float = OpTypeVector %float 3 + %v4float = OpTypeVector %float 4 + %bool = OpTypeBool + %v3int = OpTypeVector %int 3 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 + %uint_1 = OpConstant %uint 1 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %float_31 = OpConstant %float 31 + %2057 = OpConstantComposite %v4float %float_31 %float_31 %float_31 %float_1 + %float_0_5 = OpConstant %float 0.5 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_2 = OpConstant %uint 2 + %int_10 = OpConstant %int 10 + %uint_3 = OpConstant %uint 3 + %int_15 = OpConstant %int 15 + %float_63 = OpConstant %float 63 + %511 = OpConstantComposite %v3float %float_31 %float_63 %float_31 + %int_11 = OpConstant %int 11 + %958 = OpConstantComposite %v3float %float_31 %float_31 %float_63 + %float_255 = OpConstant %float 255 + %int_8 = OpConstant %int 8 + %int_16 = OpConstant %int 16 + %int_24 = OpConstant %int 24 + %float_15 = OpConstant %float 15 + %int_4 = OpConstant %int 4 + %int_12 = OpConstant %int 12 +%float_65535 = OpConstant %float 65535 + %uint_16 = OpConstant %uint 16 + %uint_24 = OpConstant %uint 24 + %653 = OpConstantComposite %v4uint %uint_0 %uint_8 %uint_16 %uint_24 + %uint_255 = OpConstant %uint 255 +%float_0_00392156886 = OpConstant %float 0.00392156886 + %uint_10 = OpConstant %uint 10 + %uint_20 = OpConstant %uint 20 + %uint_30 = OpConstant %uint 30 + %845 = OpConstantComposite %v4uint %uint_0 %uint_10 %uint_20 %uint_30 + %uint_1023 = OpConstant %uint 1023 + %635 = OpConstantComposite %v4uint %uint_1023 %uint_1023 %uint_1023 %uint_3 +%float_0_000977517106 = OpConstant %float 0.000977517106 +%float_0_333333343 = OpConstant %float 0.333333343 + %2798 = OpConstantComposite %v4float %float_0_000977517106 %float_0_000977517106 %float_0_000977517106 %float_0_333333343 + %2996 = OpConstantComposite %v3uint %uint_0 %uint_10 %uint_20 + %uint_127 = OpConstant %uint 127 + %uint_7 = OpConstant %uint 7 + %v3bool = OpTypeVector %bool 3 + %uint_124 = OpConstant %uint 124 + %uint_23 = OpConstant %uint 23 + %float_n1 = OpConstant %float -1 + %int_0 = OpConstant %int 0 + %1959 = OpConstantComposite %v2int %int_16 %int_0 +%float_0_000976592302 = OpConstant %float 0.000976592302 + %v4int = OpTypeVector %int 4 + %290 = OpConstantComposite %v4int %int_16 %int_0 %int_16 %int_0 + %1837 = OpConstantComposite %v2uint %uint_2 %uint_1 + %v2bool = OpTypeVector %bool 2 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %uint_80 = OpConstant %uint 80 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_448 = OpConstant %int 448 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 + %uint_6 = OpConstant %uint 6 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_runtimearr_uint = OpTypeRuntimeArray %uint +%_struct_1948 = OpTypeStruct %_runtimearr_uint +%_ptr_Uniform__struct_1948 = OpTypePointer Uniform %_struct_1948 + %3271 = OpVariable %_ptr_Uniform__struct_1948 Uniform +%_ptr_Uniform_uint = OpTypePointer Uniform %uint +%_struct_1036 = OpTypeStruct %uint %uint %uint %uint %uint +%_ptr_PushConstant__struct_1036 = OpTypePointer PushConstant %_struct_1036 + %3305 = OpVariable %_ptr_PushConstant__struct_1036 PushConstant +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_15 = OpConstant %uint 15 + %uint_28 = OpConstant %uint 28 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 + %uint_63 = OpConstant %uint 63 + %int_26 = OpConstant %int 26 + %int_23 = OpConstant %int 23 +%uint_16777216 = OpConstant %uint 16777216 + %2275 = OpConstantComposite %v2uint %uint_20 %uint_24 + %false = OpConstantFalse %bool +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %1825 = OpConstantComposite %v2uint %uint_2 %uint_0 +%uint_4294901760 = OpConstant %uint 4294901760 +%_runtimearr_v2uint = OpTypeRuntimeArray %v2uint +%_struct_1960 = OpTypeStruct %_runtimearr_v2uint +%_ptr_Uniform__struct_1960 = OpTypePointer Uniform %_struct_1960 + %5522 = OpVariable %_ptr_Uniform__struct_1960 Uniform +%_ptr_Uniform_v2uint = OpTypePointer Uniform %v2uint +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %1284 = OpConstantComposite %v4float %float_n1 %float_n1 %float_n1 %float_n1 + %770 = OpConstantComposite %v4int %int_16 %int_16 %int_16 %int_16 + %1611 = OpConstantComposite %v4uint %uint_255 %uint_255 %uint_255 %uint_255 + %261 = OpConstantComposite %v3uint %uint_1023 %uint_1023 %uint_1023 + %1126 = OpConstantComposite %v3uint %uint_127 %uint_127 %uint_127 + %2828 = OpConstantComposite %v3uint %uint_7 %uint_7 %uint_7 + %2578 = OpConstantComposite %v3uint %uint_0 %uint_0 %uint_0 + %1018 = OpConstantComposite %v3uint %uint_124 %uint_124 %uint_124 + %393 = OpConstantComposite %v3uint %uint_23 %uint_23 %uint_23 + %141 = OpConstantComposite %v3uint %uint_16 %uint_16 %uint_16 + %73 = OpConstantComposite %v2float %float_n1 %float_n1 + %2151 = OpConstantComposite %v2int %int_16 %int_16 + %2938 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 + %1285 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 + %325 = OpConstantComposite %v4float %float_0_5 %float_0_5 %float_0_5 %float_0_5 + %2605 = OpConstantComposite %v3float %float_0 %float_0 %float_0 + %2584 = OpConstantComposite %v3float %float_1 %float_1 %float_1 + %939 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5 + %2326 = OpConstantComposite %v2uint %uint_16711935 %uint_16711935 + %1975 = OpConstantComposite %v2uint %uint_8 %uint_8 + %2888 = OpConstantComposite %v2uint %uint_4278255360 %uint_4278255360 +%int_1065353216 = OpConstant %int 1065353216 + %uint_1280 = OpConstant %uint 1280 +%uint_2621440 = OpConstant %uint 2621440 +%uint_4294967290 = OpConstant %uint 4294967290 + %2360 = OpConstantComposite %v3uint %uint_4294967290 %uint_4294967290 %uint_4294967290 + %uint_81 = OpConstant %uint 81 + %uint_82 = OpConstant %uint 82 + %uint_83 = OpConstant %uint 83 + %uint_84 = OpConstant %uint 84 + %uint_85 = OpConstant %uint 85 + %uint_86 = OpConstant %uint 86 + %uint_87 = OpConstant %uint 87 + %float_0_25 = OpConstant %float 0.25 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %19978 = OpShiftRightLogical %uint %15627 %uint_10 + %8574 = OpBitwiseAnd %uint %19978 %uint_3 + %21002 = OpShiftRightLogical %uint %15627 %uint_13 + %8575 = OpBitwiseAnd %uint %21002 %uint_2047 + %21003 = OpShiftRightLogical %uint %15627 %uint_24 + %8576 = OpBitwiseAnd %uint %21003 %uint_15 + %18836 = OpShiftRightLogical %uint %15627 %uint_28 + %9130 = OpBitwiseAnd %uint %18836 %uint_1 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9576 = OpShiftRightLogical %v2uint %8871 %1855 + %23379 = OpBitwiseAnd %v2uint %9576 %1954 + %16207 = OpShiftLeftLogical %v2uint %23379 %1870 + %23019 = OpIMul %v2uint %16207 %1828 + %12819 = OpShiftRightLogical %uint %20824 %uint_5 + %16204 = OpBitwiseAnd %uint %12819 %uint_2047 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %24236 = OpLoad %uint %18732 + %22701 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %20919 = OpLoad %uint %22701 + %19164 = OpBitwiseAnd %uint %24236 %uint_7 + %21999 = OpBitwiseAnd %uint %24236 %uint_8 + %20495 = OpINotEqual %bool %21999 %uint_0 + %10307 = OpShiftRightLogical %uint %24236 %uint_4 + %24434 = OpBitwiseAnd %uint %10307 %uint_7 + %19672 = OpShiftRightLogical %uint %24236 %uint_7 + %20627 = OpBitwiseAnd %uint %19672 %uint_63 + %22920 = OpBitcast %int %24236 + %13711 = OpShiftLeftLogical %int %22920 %int_10 + %20636 = OpShiftRightArithmetic %int %13711 %int_26 + %18178 = OpShiftLeftLogical %int %20636 %int_23 + %7462 = OpIAdd %int %18178 %int_1065353216 + %11052 = OpBitcast %float %7462 + %22649 = OpBitwiseAnd %uint %24236 %uint_16777216 + %7513 = OpINotEqual %bool %22649 %uint_0 + %8003 = OpBitwiseAnd %uint %20919 %uint_1023 + %15783 = OpShiftLeftLogical %uint %8003 %uint_5 + %22591 = OpShiftRightLogical %uint %20919 %uint_10 + %19390 = OpBitwiseAnd %uint %22591 %uint_1023 + %25203 = OpShiftLeftLogical %uint %19390 %uint_5 + %10422 = OpCompositeConstruct %v2uint %20919 %20919 + %10385 = OpShiftRightLogical %v2uint %10422 %2275 + %23380 = OpBitwiseAnd %v2uint %10385 %2122 + %16208 = OpShiftLeftLogical %v2uint %23380 %1870 + %23020 = OpIMul %v2uint %16208 %1828 + %12820 = OpShiftRightLogical %uint %20919 %uint_28 + %16205 = OpBitwiseAnd %uint %12820 %uint_7 + %18656 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_4 + %25270 = OpLoad %uint %18656 + %14159 = OpLoad %v3uint %gl_GlobalInvocationID + %12672 = OpVectorShuffle %v2uint %14159 %14159 0 1 + %12025 = OpShiftLeftLogical %v2uint %12672 %1825 + %7640 = OpCompositeExtract %uint %12025 0 + %11658 = OpShiftLeftLogical %uint %16204 %uint_3 + %15379 = OpUGreaterThanEqual %bool %7640 %11658 + OpSelectionMerge %12755 DontFlatten + OpBranchConditional %15379 %21992 %12755 + %21992 = OpLabel + OpBranch %19578 + %12755 = OpLabel + %7340 = OpCompositeExtract %uint %12025 1 + %7992 = OpExtInst %uint %1 UMax %7340 %uint_0 + %20975 = OpCompositeConstruct %v2uint %7640 %7992 + %21036 = OpIAdd %v2uint %20975 %23019 + %16075 = OpULessThanEqual %bool %16205 %uint_3 + OpSelectionMerge %23776 None + OpBranchConditional %16075 %10990 %15087 + %15087 = OpLabel + %13566 = OpIEqual %bool %16205 %uint_5 + %8438 = OpSelect %uint %13566 %uint_2 %uint_0 + OpBranch %23776 + %10990 = OpLabel + OpBranch %23776 + %23776 = OpLabel + %19300 = OpPhi %uint %16205 %10990 %8438 %15087 + %16830 = OpCompositeConstruct %v2uint %8574 %8574 + %11801 = OpUGreaterThanEqual %v2bool %16830 %1837 + %19381 = OpSelect %v2uint %11801 %1828 %1807 + %10986 = OpShiftLeftLogical %v2uint %21036 %19381 + %24669 = OpCompositeConstruct %v2uint %19300 %19300 + %9093 = OpShiftRightLogical %v2uint %24669 %1816 + %15084 = OpBitwiseAnd %v2uint %9093 %1828 + %10197 = OpIAdd %v2uint %10986 %15084 + %8548 = OpCompositeConstruct %v2uint %9130 %uint_0 + %9802 = OpShiftRightLogical %v2uint %2719 %8548 + %10146 = OpUDiv %v2uint %10197 %9802 + %20390 = OpCompositeExtract %uint %10146 1 + %11046 = OpIMul %uint %20390 %20561 + %24665 = OpCompositeExtract %uint %10146 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %8575 %21536 + %23345 = OpIMul %v2uint %10146 %9802 + %11892 = OpISub %v2uint %10197 %23345 + %8053 = OpIMul %uint %8742 %uint_1280 + %24263 = OpCompositeExtract %uint %11892 1 + %23526 = OpCompositeExtract %uint %9802 0 + %22886 = OpIMul %uint %24263 %23526 + %6886 = OpCompositeExtract %uint %11892 0 + %9696 = OpIAdd %uint %22886 %6886 + %18116 = OpShiftLeftLogical %uint %9696 %9130 + %18201 = OpIAdd %uint %8053 %18116 + %23256 = OpUMod %uint %18201 %uint_2621440 + %13153 = OpUGreaterThanEqual %bool %8574 %uint_2 + %24735 = OpSelect %uint %13153 %uint_1 %uint_0 + %20074 = OpIAdd %uint %9130 %24735 + %6555 = OpShiftLeftLogical %uint %uint_1 %20074 + %23279 = OpINotEqual %bool %9130 %uint_0 + OpSelectionMerge %21263 DontFlatten + OpBranchConditional %23279 %15205 %16569 + %16569 = OpLabel + %19162 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20297 DontFlatten + OpBranchConditional %19162 %9761 %12129 + %12129 = OpLabel + %19407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %23256 + %23875 = OpLoad %uint %19407 + %11687 = OpIAdd %uint %23256 %6555 + %6475 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11687 + %24155 = OpLoad %uint %6475 + %6234 = OpIMul %uint %uint_2 %6555 + %8353 = OpIAdd %uint %23256 %6234 + %15309 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8353 + %24156 = OpLoad %uint %15309 + %6235 = OpIMul %uint %uint_3 %6555 + %8354 = OpIAdd %uint %23256 %6235 + %14321 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8354 + %16379 = OpLoad %uint %14321 + %20780 = OpCompositeConstruct %v4uint %23875 %24155 %24156 %16379 + OpBranch %20297 + %9761 = OpLabel + %21829 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %23256 + %23876 = OpLoad %uint %21829 + %11688 = OpIAdd %uint %23256 %uint_1 + %6399 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11688 + %23650 = OpLoad %uint %6399 + %11689 = OpIAdd %uint %23256 %uint_2 + %6400 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11689 + %23651 = OpLoad %uint %6400 + %11690 = OpIAdd %uint %23256 %uint_3 + %24558 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11690 + %16380 = OpLoad %uint %24558 + %20781 = OpCompositeConstruct %v4uint %23876 %23650 %23651 %16380 + OpBranch %20297 + %20297 = OpLabel + %10943 = OpPhi %v4uint %20781 %9761 %20780 %12129 + OpSelectionMerge %16224 None + OpSwitch %8576 %19451 0 %14585 1 %14585 2 %7355 10 %7355 3 %7354 12 %7354 4 %8190 6 %8243 + %8243 = OpLabel + %24406 = OpCompositeExtract %uint %10943 0 + %24679 = OpExtInst %v2float %1 UnpackHalf2x16 %24406 + %10082 = OpCompositeExtract %float %24679 0 + %17478 = OpCompositeExtract %float %24679 1 + %14604 = OpCompositeConstruct %v4float %10082 %17478 %float_0 %float_0 + %17274 = OpCompositeExtract %uint %10943 1 + %18027 = OpExtInst %v2float %1 UnpackHalf2x16 %17274 + %10083 = OpCompositeExtract %float %18027 0 + %17479 = OpCompositeExtract %float %18027 1 + %14605 = OpCompositeConstruct %v4float %10083 %17479 %float_0 %float_0 + %17275 = OpCompositeExtract %uint %10943 2 + %18028 = OpExtInst %v2float %1 UnpackHalf2x16 %17275 + %10084 = OpCompositeExtract %float %18028 0 + %17480 = OpCompositeExtract %float %18028 1 + %14606 = OpCompositeConstruct %v4float %10084 %17480 %float_0 %float_0 + %17276 = OpCompositeExtract %uint %10943 3 + %18029 = OpExtInst %v2float %1 UnpackHalf2x16 %17276 + %10085 = OpCompositeExtract %float %18029 0 + %20670 = OpCompositeExtract %float %18029 1 + %9033 = OpCompositeConstruct %v4float %10085 %20670 %float_0 %float_0 + OpBranch %16224 + %8190 = OpLabel + %12427 = OpCompositeExtract %uint %10943 0 + %22685 = OpBitcast %int %12427 + %18202 = OpCompositeConstruct %v2int %22685 %22685 + %18349 = OpShiftLeftLogical %v2int %18202 %1959 + %13335 = OpShiftRightArithmetic %v2int %18349 %2151 + %10903 = OpConvertSToF %v2float %13335 + %18247 = OpVectorTimesScalar %v2float %10903 %float_0_000976592302 + %24070 = OpExtInst %v2float %1 FMax %73 %18247 + %24330 = OpCompositeExtract %float %24070 0 + %15572 = OpCompositeExtract %float %24070 1 + %16670 = OpCompositeConstruct %v4float %24330 %15572 %float_0 %float_0 + %19522 = OpCompositeExtract %uint %10943 1 + %16033 = OpBitcast %int %19522 + %18203 = OpCompositeConstruct %v2int %16033 %16033 + %18350 = OpShiftLeftLogical %v2int %18203 %1959 + %13336 = OpShiftRightArithmetic %v2int %18350 %2151 + %10904 = OpConvertSToF %v2float %13336 + %18248 = OpVectorTimesScalar %v2float %10904 %float_0_000976592302 + %24071 = OpExtInst %v2float %1 FMax %73 %18248 + %24331 = OpCompositeExtract %float %24071 0 + %15573 = OpCompositeExtract %float %24071 1 + %16671 = OpCompositeConstruct %v4float %24331 %15573 %float_0 %float_0 + %19523 = OpCompositeExtract %uint %10943 2 + %16034 = OpBitcast %int %19523 + %18204 = OpCompositeConstruct %v2int %16034 %16034 + %18351 = OpShiftLeftLogical %v2int %18204 %1959 + %13337 = OpShiftRightArithmetic %v2int %18351 %2151 + %10905 = OpConvertSToF %v2float %13337 + %18249 = OpVectorTimesScalar %v2float %10905 %float_0_000976592302 + %24072 = OpExtInst %v2float %1 FMax %73 %18249 + %24332 = OpCompositeExtract %float %24072 0 + %15574 = OpCompositeExtract %float %24072 1 + %16672 = OpCompositeConstruct %v4float %24332 %15574 %float_0 %float_0 + %19524 = OpCompositeExtract %uint %10943 3 + %16035 = OpBitcast %int %19524 + %18205 = OpCompositeConstruct %v2int %16035 %16035 + %18352 = OpShiftLeftLogical %v2int %18205 %1959 + %13338 = OpShiftRightArithmetic %v2int %18352 %2151 + %10906 = OpConvertSToF %v2float %13338 + %18250 = OpVectorTimesScalar %v2float %10906 %float_0_000976592302 + %24073 = OpExtInst %v2float %1 FMax %73 %18250 + %24333 = OpCompositeExtract %float %24073 0 + %18764 = OpCompositeExtract %float %24073 1 + %9034 = OpCompositeConstruct %v4float %24333 %18764 %float_0 %float_0 + OpBranch %16224 + %7354 = OpLabel + %22205 = OpCompositeExtract %uint %10943 0 + %20234 = OpCompositeConstruct %v3uint %22205 %22205 %22205 + %11021 = OpShiftRightLogical %v3uint %20234 %2996 + %24038 = OpBitwiseAnd %v3uint %11021 %261 + %18588 = OpBitwiseAnd %v3uint %24038 %1126 + %23440 = OpShiftRightLogical %v3uint %24038 %2828 + %16585 = OpIEqual %v3bool %23440 %2578 + %11339 = OpExtInst %v3int %1 FindUMsb %18588 + %10773 = OpBitcast %v3uint %11339 + %6266 = OpISub %v3uint %2828 %10773 + %8720 = OpIAdd %v3uint %10773 %2360 + %10351 = OpSelect %v3uint %16585 %8720 %23440 + %23252 = OpShiftLeftLogical %v3uint %18588 %6266 + %18842 = OpBitwiseAnd %v3uint %23252 %1126 + %10909 = OpSelect %v3uint %16585 %18842 %18588 + %24569 = OpIAdd %v3uint %10351 %1018 + %20351 = OpShiftLeftLogical %v3uint %24569 %393 + %16294 = OpShiftLeftLogical %v3uint %10909 %141 + %22396 = OpBitwiseOr %v3uint %20351 %16294 + %13824 = OpIEqual %v3bool %24038 %2578 + %16962 = OpSelect %v3uint %13824 %2578 %22396 + %10703 = OpBitcast %v3float %16962 + %19364 = OpShiftRightLogical %uint %22205 %uint_30 + %18446 = OpConvertUToF %float %19364 + %15903 = OpFMul %float %18446 %float_0_333333343 + %21442 = OpCompositeExtract %float %10703 0 + %10837 = OpCompositeExtract %float %10703 1 + %7833 = OpCompositeExtract %float %10703 2 + %15834 = OpCompositeConstruct %v4float %21442 %10837 %7833 %15903 + %10229 = OpCompositeExtract %uint %10943 1 + %13582 = OpCompositeConstruct %v3uint %10229 %10229 %10229 + %11022 = OpShiftRightLogical %v3uint %13582 %2996 + %24039 = OpBitwiseAnd %v3uint %11022 %261 + %18589 = OpBitwiseAnd %v3uint %24039 %1126 + %23441 = OpShiftRightLogical %v3uint %24039 %2828 + %16586 = OpIEqual %v3bool %23441 %2578 + %11340 = OpExtInst %v3int %1 FindUMsb %18589 + %10774 = OpBitcast %v3uint %11340 + %6267 = OpISub %v3uint %2828 %10774 + %8721 = OpIAdd %v3uint %10774 %2360 + %10352 = OpSelect %v3uint %16586 %8721 %23441 + %23253 = OpShiftLeftLogical %v3uint %18589 %6267 + %18843 = OpBitwiseAnd %v3uint %23253 %1126 + %10910 = OpSelect %v3uint %16586 %18843 %18589 + %24570 = OpIAdd %v3uint %10352 %1018 + %20352 = OpShiftLeftLogical %v3uint %24570 %393 + %16295 = OpShiftLeftLogical %v3uint %10910 %141 + %22397 = OpBitwiseOr %v3uint %20352 %16295 + %13825 = OpIEqual %v3bool %24039 %2578 + %16963 = OpSelect %v3uint %13825 %2578 %22397 + %10704 = OpBitcast %v3float %16963 + %19365 = OpShiftRightLogical %uint %10229 %uint_30 + %18447 = OpConvertUToF %float %19365 + %15904 = OpFMul %float %18447 %float_0_333333343 + %21443 = OpCompositeExtract %float %10704 0 + %10838 = OpCompositeExtract %float %10704 1 + %7834 = OpCompositeExtract %float %10704 2 + %15835 = OpCompositeConstruct %v4float %21443 %10838 %7834 %15904 + %10230 = OpCompositeExtract %uint %10943 2 + %13583 = OpCompositeConstruct %v3uint %10230 %10230 %10230 + %11023 = OpShiftRightLogical %v3uint %13583 %2996 + %24040 = OpBitwiseAnd %v3uint %11023 %261 + %18590 = OpBitwiseAnd %v3uint %24040 %1126 + %23442 = OpShiftRightLogical %v3uint %24040 %2828 + %16587 = OpIEqual %v3bool %23442 %2578 + %11341 = OpExtInst %v3int %1 FindUMsb %18590 + %10775 = OpBitcast %v3uint %11341 + %6268 = OpISub %v3uint %2828 %10775 + %8722 = OpIAdd %v3uint %10775 %2360 + %10353 = OpSelect %v3uint %16587 %8722 %23442 + %23254 = OpShiftLeftLogical %v3uint %18590 %6268 + %18844 = OpBitwiseAnd %v3uint %23254 %1126 + %10911 = OpSelect %v3uint %16587 %18844 %18590 + %24571 = OpIAdd %v3uint %10353 %1018 + %20353 = OpShiftLeftLogical %v3uint %24571 %393 + %16296 = OpShiftLeftLogical %v3uint %10911 %141 + %22398 = OpBitwiseOr %v3uint %20353 %16296 + %13826 = OpIEqual %v3bool %24040 %2578 + %16964 = OpSelect %v3uint %13826 %2578 %22398 + %10705 = OpBitcast %v3float %16964 + %19366 = OpShiftRightLogical %uint %10230 %uint_30 + %18448 = OpConvertUToF %float %19366 + %15905 = OpFMul %float %18448 %float_0_333333343 + %21444 = OpCompositeExtract %float %10705 0 + %10839 = OpCompositeExtract %float %10705 1 + %7835 = OpCompositeExtract %float %10705 2 + %15836 = OpCompositeConstruct %v4float %21444 %10839 %7835 %15905 + %10231 = OpCompositeExtract %uint %10943 3 + %13584 = OpCompositeConstruct %v3uint %10231 %10231 %10231 + %11024 = OpShiftRightLogical %v3uint %13584 %2996 + %24041 = OpBitwiseAnd %v3uint %11024 %261 + %18591 = OpBitwiseAnd %v3uint %24041 %1126 + %23443 = OpShiftRightLogical %v3uint %24041 %2828 + %16588 = OpIEqual %v3bool %23443 %2578 + %11342 = OpExtInst %v3int %1 FindUMsb %18591 + %10776 = OpBitcast %v3uint %11342 + %6269 = OpISub %v3uint %2828 %10776 + %8723 = OpIAdd %v3uint %10776 %2360 + %10354 = OpSelect %v3uint %16588 %8723 %23443 + %23255 = OpShiftLeftLogical %v3uint %18591 %6269 + %18845 = OpBitwiseAnd %v3uint %23255 %1126 + %10912 = OpSelect %v3uint %16588 %18845 %18591 + %24572 = OpIAdd %v3uint %10354 %1018 + %20354 = OpShiftLeftLogical %v3uint %24572 %393 + %16297 = OpShiftLeftLogical %v3uint %10912 %141 + %22399 = OpBitwiseOr %v3uint %20354 %16297 + %13827 = OpIEqual %v3bool %24041 %2578 + %16965 = OpSelect %v3uint %13827 %2578 %22399 + %10706 = OpBitcast %v3float %16965 + %19367 = OpShiftRightLogical %uint %10231 %uint_30 + %18449 = OpConvertUToF %float %19367 + %15906 = OpFMul %float %18449 %float_0_333333343 + %21445 = OpCompositeExtract %float %10706 0 + %10840 = OpCompositeExtract %float %10706 1 + %11025 = OpCompositeExtract %float %10706 2 + %9035 = OpCompositeConstruct %v4float %21445 %10840 %11025 %15906 + OpBranch %16224 + %7355 = OpLabel + %22206 = OpCompositeExtract %uint %10943 0 + %20235 = OpCompositeConstruct %v4uint %22206 %22206 %22206 %22206 + %9368 = OpShiftRightLogical %v4uint %20235 %845 + %18859 = OpBitwiseAnd %v4uint %9368 %635 + %15543 = OpConvertUToF %v4float %18859 + %16688 = OpFMul %v4float %15543 %2798 + %23762 = OpCompositeExtract %uint %10943 1 + %20813 = OpCompositeConstruct %v4uint %23762 %23762 %23762 %23762 + %9369 = OpShiftRightLogical %v4uint %20813 %845 + %18860 = OpBitwiseAnd %v4uint %9369 %635 + %15544 = OpConvertUToF %v4float %18860 + %16689 = OpFMul %v4float %15544 %2798 + %23763 = OpCompositeExtract %uint %10943 2 + %20814 = OpCompositeConstruct %v4uint %23763 %23763 %23763 %23763 + %9370 = OpShiftRightLogical %v4uint %20814 %845 + %18861 = OpBitwiseAnd %v4uint %9370 %635 + %15545 = OpConvertUToF %v4float %18861 + %16690 = OpFMul %v4float %15545 %2798 + %23764 = OpCompositeExtract %uint %10943 3 + %20815 = OpCompositeConstruct %v4uint %23764 %23764 %23764 %23764 + %9371 = OpShiftRightLogical %v4uint %20815 %845 + %18862 = OpBitwiseAnd %v4uint %9371 %635 + %18735 = OpConvertUToF %v4float %18862 + %9887 = OpFMul %v4float %18735 %2798 + OpBranch %16224 + %14585 = OpLabel + %22207 = OpCompositeExtract %uint %10943 0 + %20236 = OpCompositeConstruct %v4uint %22207 %22207 %22207 %22207 + %9372 = OpShiftRightLogical %v4uint %20236 %653 + %19030 = OpBitwiseAnd %v4uint %9372 %1611 + %13986 = OpConvertUToF %v4float %19030 + %19235 = OpVectorTimesScalar %v4float %13986 %float_0_00392156886 + %8607 = OpCompositeExtract %uint %10943 1 + %24843 = OpCompositeConstruct %v4uint %8607 %8607 %8607 %8607 + %9373 = OpShiftRightLogical %v4uint %24843 %653 + %19031 = OpBitwiseAnd %v4uint %9373 %1611 + %13987 = OpConvertUToF %v4float %19031 + %19236 = OpVectorTimesScalar %v4float %13987 %float_0_00392156886 + %8608 = OpCompositeExtract %uint %10943 2 + %24844 = OpCompositeConstruct %v4uint %8608 %8608 %8608 %8608 + %9374 = OpShiftRightLogical %v4uint %24844 %653 + %19032 = OpBitwiseAnd %v4uint %9374 %1611 + %13988 = OpConvertUToF %v4float %19032 + %19237 = OpVectorTimesScalar %v4float %13988 %float_0_00392156886 + %8609 = OpCompositeExtract %uint %10943 3 + %24845 = OpCompositeConstruct %v4uint %8609 %8609 %8609 %8609 + %9375 = OpShiftRightLogical %v4uint %24845 %653 + %19033 = OpBitwiseAnd %v4uint %9375 %1611 + %17178 = OpConvertUToF %v4float %19033 + %12434 = OpVectorTimesScalar %v4float %17178 %float_0_00392156886 + OpBranch %16224 + %19451 = OpLabel + %12428 = OpCompositeExtract %uint %10943 0 + %20462 = OpBitcast %float %12428 + %17206 = OpCompositeConstruct %v2float %20462 %float_0 + %11664 = OpVectorShuffle %v4float %17206 %17206 0 1 1 1 + %22193 = OpCompositeExtract %uint %10943 1 + %16232 = OpBitcast %float %22193 + %17207 = OpCompositeConstruct %v2float %16232 %float_0 + %11665 = OpVectorShuffle %v4float %17207 %17207 0 1 1 1 + %22194 = OpCompositeExtract %uint %10943 2 + %16233 = OpBitcast %float %22194 + %17208 = OpCompositeConstruct %v2float %16233 %float_0 + %11666 = OpVectorShuffle %v4float %17208 %17208 0 1 1 1 + %22195 = OpCompositeExtract %uint %10943 3 + %16234 = OpBitcast %float %22195 + %20398 = OpCompositeConstruct %v2float %16234 %float_0 + %23098 = OpVectorShuffle %v4float %20398 %20398 0 1 1 1 + OpBranch %16224 + %16224 = OpLabel + %11175 = OpPhi %v4float %23098 %19451 %12434 %14585 %9887 %7355 %9035 %7354 %9034 %8190 %9033 %8243 + %14344 = OpPhi %v4float %11666 %19451 %19237 %14585 %16690 %7355 %15836 %7354 %16672 %8190 %14606 %8243 + %15229 = OpPhi %v4float %11665 %19451 %19236 %14585 %16689 %7355 %15835 %7354 %16671 %8190 %14605 %8243 + %14518 = OpPhi %v4float %11664 %19451 %19235 %14585 %16688 %7355 %15834 %7354 %16670 %8190 %14604 %8243 + OpBranch %21263 + %15205 = OpLabel + %21584 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20259 DontFlatten + OpBranchConditional %21584 %9762 %12130 + %12130 = OpLabel + %19408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %23256 + %23877 = OpLoad %uint %19408 + %11691 = OpIAdd %uint %23256 %uint_1 + %6401 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11691 + %23652 = OpLoad %uint %6401 + %11692 = OpIAdd %uint %23256 %6555 + %6402 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11692 + %23653 = OpLoad %uint %6402 + %11693 = OpIAdd %uint %11692 %uint_1 + %24559 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11693 + %14156 = OpLoad %uint %24559 + %19670 = OpCompositeConstruct %v4uint %23877 %23652 %23653 %14156 + %17048 = OpIMul %uint %uint_2 %6555 + %13991 = OpIAdd %uint %23256 %17048 + %15233 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13991 + %23654 = OpLoad %uint %15233 + %11694 = OpIAdd %uint %13991 %uint_1 + %6476 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11694 + %24157 = OpLoad %uint %6476 + %6236 = OpIMul %uint %uint_3 %6555 + %8355 = OpIAdd %uint %23256 %6236 + %15234 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8355 + %23655 = OpLoad %uint %15234 + %11695 = OpIAdd %uint %8355 %uint_1 + %24560 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11695 + %16381 = OpLoad %uint %24560 + %20782 = OpCompositeConstruct %v4uint %23654 %24157 %23655 %16381 + OpBranch %20259 + %9762 = OpLabel + %21830 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %23256 + %23878 = OpLoad %uint %21830 + %11696 = OpIAdd %uint %23256 %uint_1 + %6403 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11696 + %23656 = OpLoad %uint %6403 + %11697 = OpIAdd %uint %23256 %uint_2 + %6404 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11697 + %23657 = OpLoad %uint %6404 + %11698 = OpIAdd %uint %23256 %uint_3 + %24561 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11698 + %14080 = OpLoad %uint %24561 + %19165 = OpCompositeConstruct %v4uint %23878 %23656 %23657 %14080 + %22501 = OpIAdd %uint %23256 %uint_4 + %24651 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22501 + %23658 = OpLoad %uint %24651 + %11699 = OpIAdd %uint %23256 %uint_5 + %6405 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11699 + %23659 = OpLoad %uint %6405 + %11700 = OpIAdd %uint %23256 %uint_6 + %6406 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11700 + %23660 = OpLoad %uint %6406 + %11701 = OpIAdd %uint %23256 %uint_7 + %24562 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11701 + %16382 = OpLoad %uint %24562 + %20783 = OpCompositeConstruct %v4uint %23658 %23659 %23660 %16382 + OpBranch %20259 + %20259 = OpLabel + %11213 = OpPhi %v4uint %20783 %9762 %20782 %12130 + %14112 = OpPhi %v4uint %19165 %9762 %19670 %12130 + OpSelectionMerge %20260 None + OpSwitch %8576 %20310 5 %8536 7 %8244 + %8244 = OpLabel + %24407 = OpCompositeExtract %uint %14112 0 + %24680 = OpExtInst %v2float %1 UnpackHalf2x16 %24407 + %10101 = OpCompositeExtract %float %24680 0 + %16056 = OpCompositeExtract %float %24680 1 + %17025 = OpCompositeExtract %uint %14112 1 + %15605 = OpExtInst %v2float %1 UnpackHalf2x16 %17025 + %10086 = OpCompositeExtract %float %15605 0 + %17481 = OpCompositeExtract %float %15605 1 + %14607 = OpCompositeConstruct %v4float %10101 %16056 %10086 %17481 + %17277 = OpCompositeExtract %uint %14112 2 + %18030 = OpExtInst %v2float %1 UnpackHalf2x16 %17277 + %10102 = OpCompositeExtract %float %18030 0 + %16057 = OpCompositeExtract %float %18030 1 + %17026 = OpCompositeExtract %uint %14112 3 + %15606 = OpExtInst %v2float %1 UnpackHalf2x16 %17026 + %10087 = OpCompositeExtract %float %15606 0 + %17482 = OpCompositeExtract %float %15606 1 + %14608 = OpCompositeConstruct %v4float %10102 %16057 %10087 %17482 + %17278 = OpCompositeExtract %uint %11213 0 + %18031 = OpExtInst %v2float %1 UnpackHalf2x16 %17278 + %10103 = OpCompositeExtract %float %18031 0 + %16058 = OpCompositeExtract %float %18031 1 + %17027 = OpCompositeExtract %uint %11213 1 + %15607 = OpExtInst %v2float %1 UnpackHalf2x16 %17027 + %10088 = OpCompositeExtract %float %15607 0 + %17483 = OpCompositeExtract %float %15607 1 + %14609 = OpCompositeConstruct %v4float %10103 %16058 %10088 %17483 + %17279 = OpCompositeExtract %uint %11213 2 + %18032 = OpExtInst %v2float %1 UnpackHalf2x16 %17279 + %10104 = OpCompositeExtract %float %18032 0 + %16059 = OpCompositeExtract %float %18032 1 + %17028 = OpCompositeExtract %uint %11213 3 + %15608 = OpExtInst %v2float %1 UnpackHalf2x16 %17028 + %10089 = OpCompositeExtract %float %15608 0 + %20671 = OpCompositeExtract %float %15608 1 + %9036 = OpCompositeConstruct %v4float %10104 %16059 %10089 %20671 + OpBranch %20260 + %8536 = OpLabel + %9723 = OpVectorShuffle %v2uint %14112 %14112 0 1 + %23356 = OpBitcast %v2int %9723 + %24782 = OpVectorShuffle %v4int %23356 %23356 0 0 1 1 + %18598 = OpShiftLeftLogical %v4int %24782 %290 + %15757 = OpShiftRightArithmetic %v4int %18598 %770 + %10907 = OpConvertSToF %v4float %15757 + %18209 = OpVectorTimesScalar %v4float %10907 %float_0_000976592302 + %25233 = OpExtInst %v4float %1 FMax %1284 %18209 + %14187 = OpVectorShuffle %v2uint %14112 %14112 2 3 + %9407 = OpBitcast %v2int %14187 + %24783 = OpVectorShuffle %v4int %9407 %9407 0 0 1 1 + %18599 = OpShiftLeftLogical %v4int %24783 %290 + %15758 = OpShiftRightArithmetic %v4int %18599 %770 + %10908 = OpConvertSToF %v4float %15758 + %18210 = OpVectorTimesScalar %v4float %10908 %float_0_000976592302 + %25234 = OpExtInst %v4float %1 FMax %1284 %18210 + %14188 = OpVectorShuffle %v2uint %11213 %11213 0 1 + %9408 = OpBitcast %v2int %14188 + %24784 = OpVectorShuffle %v4int %9408 %9408 0 0 1 1 + %18600 = OpShiftLeftLogical %v4int %24784 %290 + %15759 = OpShiftRightArithmetic %v4int %18600 %770 + %10913 = OpConvertSToF %v4float %15759 + %18211 = OpVectorTimesScalar %v4float %10913 %float_0_000976592302 + %25235 = OpExtInst %v4float %1 FMax %1284 %18211 + %14189 = OpVectorShuffle %v2uint %11213 %11213 2 3 + %9409 = OpBitcast %v2int %14189 + %24785 = OpVectorShuffle %v4int %9409 %9409 0 0 1 1 + %18601 = OpShiftLeftLogical %v4int %24785 %290 + %15760 = OpShiftRightArithmetic %v4int %18601 %770 + %10914 = OpConvertSToF %v4float %15760 + %21439 = OpVectorTimesScalar %v4float %10914 %float_0_000976592302 + %17250 = OpExtInst %v4float %1 FMax %1284 %21439 + OpBranch %20260 + %20310 = OpLabel + %9763 = OpVectorShuffle %v2uint %14112 %14112 0 1 + %20825 = OpBitcast %v2float %9763 + %7035 = OpCompositeExtract %float %20825 0 + %13418 = OpCompositeExtract %float %20825 1 + %17016 = OpCompositeConstruct %v4float %7035 %13418 %float_0 %float_0 + %16856 = OpVectorShuffle %v2uint %14112 %14112 2 3 + %14173 = OpBitcast %v2float %16856 + %7036 = OpCompositeExtract %float %14173 0 + %13419 = OpCompositeExtract %float %14173 1 + %17017 = OpCompositeConstruct %v4float %7036 %13419 %float_0 %float_0 + %16857 = OpVectorShuffle %v2uint %11213 %11213 0 1 + %14174 = OpBitcast %v2float %16857 + %7037 = OpCompositeExtract %float %14174 0 + %13420 = OpCompositeExtract %float %14174 1 + %17018 = OpCompositeConstruct %v4float %7037 %13420 %float_0 %float_0 + %16858 = OpVectorShuffle %v2uint %11213 %11213 2 3 + %14175 = OpBitcast %v2float %16858 + %7038 = OpCompositeExtract %float %14175 0 + %16648 = OpCompositeExtract %float %14175 1 + %9037 = OpCompositeConstruct %v4float %7038 %16648 %float_0 %float_0 + OpBranch %20260 + %20260 = OpLabel + %11176 = OpPhi %v4float %9037 %20310 %17250 %8536 %9036 %8244 + %14345 = OpPhi %v4float %17018 %20310 %25235 %8536 %14609 %8244 + %15230 = OpPhi %v4float %17017 %20310 %25234 %8536 %14608 %8244 + %14519 = OpPhi %v4float %17016 %20310 %25233 %8536 %14607 %8244 + OpBranch %21263 + %21263 = OpLabel + %11177 = OpPhi %v4float %11176 %20260 %11175 %16224 + %14346 = OpPhi %v4float %14345 %20260 %14344 %16224 + %13804 = OpPhi %v4float %15230 %20260 %15229 %16224 + %8403 = OpPhi %v4float %14519 %20260 %14518 %16224 + %11861 = OpUGreaterThanEqual %bool %16205 %uint_4 + OpSelectionMerge %21267 DontFlatten + OpBranchConditional %11861 %20709 %21267 + %20709 = OpLabel + %25083 = OpFMul %float %11052 %float_0_5 + %24184 = OpIAdd %uint %23256 %uint_80 + OpSelectionMerge %21264 DontFlatten + OpBranchConditional %23279 %15206 %16570 + %16570 = OpLabel + %19163 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20298 DontFlatten + OpBranchConditional %19163 %9764 %12131 + %12131 = OpLabel + %19409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24184 + %23879 = OpLoad %uint %19409 + %11702 = OpIAdd %uint %24184 %6555 + %6477 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11702 + %24158 = OpLoad %uint %6477 + %6237 = OpIMul %uint %uint_2 %6555 + %8356 = OpIAdd %uint %24184 %6237 + %15310 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8356 + %24159 = OpLoad %uint %15310 + %6238 = OpIMul %uint %uint_3 %6555 + %8357 = OpIAdd %uint %24184 %6238 + %14322 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8357 + %16383 = OpLoad %uint %14322 + %20784 = OpCompositeConstruct %v4uint %23879 %24158 %24159 %16383 + OpBranch %20298 + %9764 = OpLabel + %21831 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24184 + %23880 = OpLoad %uint %21831 + %11703 = OpIAdd %uint %23256 %uint_81 + %6407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11703 + %23661 = OpLoad %uint %6407 + %11704 = OpIAdd %uint %23256 %uint_82 + %6408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11704 + %23662 = OpLoad %uint %6408 + %11705 = OpIAdd %uint %23256 %uint_83 + %24563 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11705 + %16384 = OpLoad %uint %24563 + %20785 = OpCompositeConstruct %v4uint %23880 %23661 %23662 %16384 + OpBranch %20298 + %20298 = OpLabel + %10944 = OpPhi %v4uint %20785 %9764 %20784 %12131 + OpSelectionMerge %16225 None + OpSwitch %8576 %19452 0 %14586 1 %14586 2 %7357 10 %7357 3 %7356 12 %7356 4 %8191 6 %8245 + %8245 = OpLabel + %24408 = OpCompositeExtract %uint %10944 0 + %24681 = OpExtInst %v2float %1 UnpackHalf2x16 %24408 + %10090 = OpCompositeExtract %float %24681 0 + %17484 = OpCompositeExtract %float %24681 1 + %14610 = OpCompositeConstruct %v4float %10090 %17484 %float_0 %float_0 + %17280 = OpCompositeExtract %uint %10944 1 + %18033 = OpExtInst %v2float %1 UnpackHalf2x16 %17280 + %10091 = OpCompositeExtract %float %18033 0 + %17485 = OpCompositeExtract %float %18033 1 + %14611 = OpCompositeConstruct %v4float %10091 %17485 %float_0 %float_0 + %17281 = OpCompositeExtract %uint %10944 2 + %18034 = OpExtInst %v2float %1 UnpackHalf2x16 %17281 + %10092 = OpCompositeExtract %float %18034 0 + %17486 = OpCompositeExtract %float %18034 1 + %14612 = OpCompositeConstruct %v4float %10092 %17486 %float_0 %float_0 + %17282 = OpCompositeExtract %uint %10944 3 + %18035 = OpExtInst %v2float %1 UnpackHalf2x16 %17282 + %10093 = OpCompositeExtract %float %18035 0 + %20672 = OpCompositeExtract %float %18035 1 + %9038 = OpCompositeConstruct %v4float %10093 %20672 %float_0 %float_0 + OpBranch %16225 + %8191 = OpLabel + %12429 = OpCompositeExtract %uint %10944 0 + %22686 = OpBitcast %int %12429 + %18206 = OpCompositeConstruct %v2int %22686 %22686 + %18353 = OpShiftLeftLogical %v2int %18206 %1959 + %13339 = OpShiftRightArithmetic %v2int %18353 %2151 + %10915 = OpConvertSToF %v2float %13339 + %18251 = OpVectorTimesScalar %v2float %10915 %float_0_000976592302 + %24074 = OpExtInst %v2float %1 FMax %73 %18251 + %24334 = OpCompositeExtract %float %24074 0 + %15575 = OpCompositeExtract %float %24074 1 + %16673 = OpCompositeConstruct %v4float %24334 %15575 %float_0 %float_0 + %19525 = OpCompositeExtract %uint %10944 1 + %16036 = OpBitcast %int %19525 + %18207 = OpCompositeConstruct %v2int %16036 %16036 + %18354 = OpShiftLeftLogical %v2int %18207 %1959 + %13340 = OpShiftRightArithmetic %v2int %18354 %2151 + %10916 = OpConvertSToF %v2float %13340 + %18252 = OpVectorTimesScalar %v2float %10916 %float_0_000976592302 + %24075 = OpExtInst %v2float %1 FMax %73 %18252 + %24335 = OpCompositeExtract %float %24075 0 + %15576 = OpCompositeExtract %float %24075 1 + %16674 = OpCompositeConstruct %v4float %24335 %15576 %float_0 %float_0 + %19526 = OpCompositeExtract %uint %10944 2 + %16037 = OpBitcast %int %19526 + %18208 = OpCompositeConstruct %v2int %16037 %16037 + %18355 = OpShiftLeftLogical %v2int %18208 %1959 + %13341 = OpShiftRightArithmetic %v2int %18355 %2151 + %10917 = OpConvertSToF %v2float %13341 + %18253 = OpVectorTimesScalar %v2float %10917 %float_0_000976592302 + %24076 = OpExtInst %v2float %1 FMax %73 %18253 + %24336 = OpCompositeExtract %float %24076 0 + %15577 = OpCompositeExtract %float %24076 1 + %16675 = OpCompositeConstruct %v4float %24336 %15577 %float_0 %float_0 + %19527 = OpCompositeExtract %uint %10944 3 + %16038 = OpBitcast %int %19527 + %18212 = OpCompositeConstruct %v2int %16038 %16038 + %18356 = OpShiftLeftLogical %v2int %18212 %1959 + %13342 = OpShiftRightArithmetic %v2int %18356 %2151 + %10918 = OpConvertSToF %v2float %13342 + %18254 = OpVectorTimesScalar %v2float %10918 %float_0_000976592302 + %24077 = OpExtInst %v2float %1 FMax %73 %18254 + %24337 = OpCompositeExtract %float %24077 0 + %18765 = OpCompositeExtract %float %24077 1 + %9039 = OpCompositeConstruct %v4float %24337 %18765 %float_0 %float_0 + OpBranch %16225 + %7356 = OpLabel + %22208 = OpCompositeExtract %uint %10944 0 + %20237 = OpCompositeConstruct %v3uint %22208 %22208 %22208 + %11026 = OpShiftRightLogical %v3uint %20237 %2996 + %24042 = OpBitwiseAnd %v3uint %11026 %261 + %18592 = OpBitwiseAnd %v3uint %24042 %1126 + %23444 = OpShiftRightLogical %v3uint %24042 %2828 + %16589 = OpIEqual %v3bool %23444 %2578 + %11343 = OpExtInst %v3int %1 FindUMsb %18592 + %10777 = OpBitcast %v3uint %11343 + %6270 = OpISub %v3uint %2828 %10777 + %8724 = OpIAdd %v3uint %10777 %2360 + %10355 = OpSelect %v3uint %16589 %8724 %23444 + %23257 = OpShiftLeftLogical %v3uint %18592 %6270 + %18846 = OpBitwiseAnd %v3uint %23257 %1126 + %10919 = OpSelect %v3uint %16589 %18846 %18592 + %24573 = OpIAdd %v3uint %10355 %1018 + %20355 = OpShiftLeftLogical %v3uint %24573 %393 + %16298 = OpShiftLeftLogical %v3uint %10919 %141 + %22400 = OpBitwiseOr %v3uint %20355 %16298 + %13828 = OpIEqual %v3bool %24042 %2578 + %16966 = OpSelect %v3uint %13828 %2578 %22400 + %10707 = OpBitcast %v3float %16966 + %19368 = OpShiftRightLogical %uint %22208 %uint_30 + %18450 = OpConvertUToF %float %19368 + %15907 = OpFMul %float %18450 %float_0_333333343 + %21446 = OpCompositeExtract %float %10707 0 + %10841 = OpCompositeExtract %float %10707 1 + %7836 = OpCompositeExtract %float %10707 2 + %15837 = OpCompositeConstruct %v4float %21446 %10841 %7836 %15907 + %10232 = OpCompositeExtract %uint %10944 1 + %13585 = OpCompositeConstruct %v3uint %10232 %10232 %10232 + %11027 = OpShiftRightLogical %v3uint %13585 %2996 + %24043 = OpBitwiseAnd %v3uint %11027 %261 + %18593 = OpBitwiseAnd %v3uint %24043 %1126 + %23445 = OpShiftRightLogical %v3uint %24043 %2828 + %16590 = OpIEqual %v3bool %23445 %2578 + %11344 = OpExtInst %v3int %1 FindUMsb %18593 + %10778 = OpBitcast %v3uint %11344 + %6271 = OpISub %v3uint %2828 %10778 + %8725 = OpIAdd %v3uint %10778 %2360 + %10356 = OpSelect %v3uint %16590 %8725 %23445 + %23258 = OpShiftLeftLogical %v3uint %18593 %6271 + %18847 = OpBitwiseAnd %v3uint %23258 %1126 + %10920 = OpSelect %v3uint %16590 %18847 %18593 + %24574 = OpIAdd %v3uint %10356 %1018 + %20356 = OpShiftLeftLogical %v3uint %24574 %393 + %16299 = OpShiftLeftLogical %v3uint %10920 %141 + %22401 = OpBitwiseOr %v3uint %20356 %16299 + %13829 = OpIEqual %v3bool %24043 %2578 + %16967 = OpSelect %v3uint %13829 %2578 %22401 + %10708 = OpBitcast %v3float %16967 + %19369 = OpShiftRightLogical %uint %10232 %uint_30 + %18451 = OpConvertUToF %float %19369 + %15908 = OpFMul %float %18451 %float_0_333333343 + %21447 = OpCompositeExtract %float %10708 0 + %10842 = OpCompositeExtract %float %10708 1 + %7837 = OpCompositeExtract %float %10708 2 + %15838 = OpCompositeConstruct %v4float %21447 %10842 %7837 %15908 + %10233 = OpCompositeExtract %uint %10944 2 + %13586 = OpCompositeConstruct %v3uint %10233 %10233 %10233 + %11028 = OpShiftRightLogical %v3uint %13586 %2996 + %24044 = OpBitwiseAnd %v3uint %11028 %261 + %18594 = OpBitwiseAnd %v3uint %24044 %1126 + %23446 = OpShiftRightLogical %v3uint %24044 %2828 + %16591 = OpIEqual %v3bool %23446 %2578 + %11345 = OpExtInst %v3int %1 FindUMsb %18594 + %10779 = OpBitcast %v3uint %11345 + %6272 = OpISub %v3uint %2828 %10779 + %8726 = OpIAdd %v3uint %10779 %2360 + %10357 = OpSelect %v3uint %16591 %8726 %23446 + %23259 = OpShiftLeftLogical %v3uint %18594 %6272 + %18848 = OpBitwiseAnd %v3uint %23259 %1126 + %10921 = OpSelect %v3uint %16591 %18848 %18594 + %24575 = OpIAdd %v3uint %10357 %1018 + %20357 = OpShiftLeftLogical %v3uint %24575 %393 + %16300 = OpShiftLeftLogical %v3uint %10921 %141 + %22402 = OpBitwiseOr %v3uint %20357 %16300 + %13830 = OpIEqual %v3bool %24044 %2578 + %16968 = OpSelect %v3uint %13830 %2578 %22402 + %10709 = OpBitcast %v3float %16968 + %19370 = OpShiftRightLogical %uint %10233 %uint_30 + %18452 = OpConvertUToF %float %19370 + %15909 = OpFMul %float %18452 %float_0_333333343 + %21448 = OpCompositeExtract %float %10709 0 + %10843 = OpCompositeExtract %float %10709 1 + %7838 = OpCompositeExtract %float %10709 2 + %15839 = OpCompositeConstruct %v4float %21448 %10843 %7838 %15909 + %10234 = OpCompositeExtract %uint %10944 3 + %13587 = OpCompositeConstruct %v3uint %10234 %10234 %10234 + %11029 = OpShiftRightLogical %v3uint %13587 %2996 + %24045 = OpBitwiseAnd %v3uint %11029 %261 + %18595 = OpBitwiseAnd %v3uint %24045 %1126 + %23447 = OpShiftRightLogical %v3uint %24045 %2828 + %16592 = OpIEqual %v3bool %23447 %2578 + %11346 = OpExtInst %v3int %1 FindUMsb %18595 + %10780 = OpBitcast %v3uint %11346 + %6273 = OpISub %v3uint %2828 %10780 + %8727 = OpIAdd %v3uint %10780 %2360 + %10358 = OpSelect %v3uint %16592 %8727 %23447 + %23260 = OpShiftLeftLogical %v3uint %18595 %6273 + %18849 = OpBitwiseAnd %v3uint %23260 %1126 + %10922 = OpSelect %v3uint %16592 %18849 %18595 + %24576 = OpIAdd %v3uint %10358 %1018 + %20358 = OpShiftLeftLogical %v3uint %24576 %393 + %16301 = OpShiftLeftLogical %v3uint %10922 %141 + %22403 = OpBitwiseOr %v3uint %20358 %16301 + %13831 = OpIEqual %v3bool %24045 %2578 + %16969 = OpSelect %v3uint %13831 %2578 %22403 + %10710 = OpBitcast %v3float %16969 + %19371 = OpShiftRightLogical %uint %10234 %uint_30 + %18453 = OpConvertUToF %float %19371 + %15910 = OpFMul %float %18453 %float_0_333333343 + %21449 = OpCompositeExtract %float %10710 0 + %10844 = OpCompositeExtract %float %10710 1 + %11030 = OpCompositeExtract %float %10710 2 + %9040 = OpCompositeConstruct %v4float %21449 %10844 %11030 %15910 + OpBranch %16225 + %7357 = OpLabel + %22209 = OpCompositeExtract %uint %10944 0 + %20238 = OpCompositeConstruct %v4uint %22209 %22209 %22209 %22209 + %9376 = OpShiftRightLogical %v4uint %20238 %845 + %18863 = OpBitwiseAnd %v4uint %9376 %635 + %15546 = OpConvertUToF %v4float %18863 + %16691 = OpFMul %v4float %15546 %2798 + %23765 = OpCompositeExtract %uint %10944 1 + %20816 = OpCompositeConstruct %v4uint %23765 %23765 %23765 %23765 + %9377 = OpShiftRightLogical %v4uint %20816 %845 + %18864 = OpBitwiseAnd %v4uint %9377 %635 + %15547 = OpConvertUToF %v4float %18864 + %16692 = OpFMul %v4float %15547 %2798 + %23766 = OpCompositeExtract %uint %10944 2 + %20817 = OpCompositeConstruct %v4uint %23766 %23766 %23766 %23766 + %9378 = OpShiftRightLogical %v4uint %20817 %845 + %18865 = OpBitwiseAnd %v4uint %9378 %635 + %15548 = OpConvertUToF %v4float %18865 + %16693 = OpFMul %v4float %15548 %2798 + %23767 = OpCompositeExtract %uint %10944 3 + %20818 = OpCompositeConstruct %v4uint %23767 %23767 %23767 %23767 + %9379 = OpShiftRightLogical %v4uint %20818 %845 + %18866 = OpBitwiseAnd %v4uint %9379 %635 + %18736 = OpConvertUToF %v4float %18866 + %9888 = OpFMul %v4float %18736 %2798 + OpBranch %16225 + %14586 = OpLabel + %22210 = OpCompositeExtract %uint %10944 0 + %20239 = OpCompositeConstruct %v4uint %22210 %22210 %22210 %22210 + %9380 = OpShiftRightLogical %v4uint %20239 %653 + %19034 = OpBitwiseAnd %v4uint %9380 %1611 + %13989 = OpConvertUToF %v4float %19034 + %19238 = OpVectorTimesScalar %v4float %13989 %float_0_00392156886 + %8610 = OpCompositeExtract %uint %10944 1 + %24846 = OpCompositeConstruct %v4uint %8610 %8610 %8610 %8610 + %9381 = OpShiftRightLogical %v4uint %24846 %653 + %19035 = OpBitwiseAnd %v4uint %9381 %1611 + %13990 = OpConvertUToF %v4float %19035 + %19239 = OpVectorTimesScalar %v4float %13990 %float_0_00392156886 + %8611 = OpCompositeExtract %uint %10944 2 + %24847 = OpCompositeConstruct %v4uint %8611 %8611 %8611 %8611 + %9382 = OpShiftRightLogical %v4uint %24847 %653 + %19036 = OpBitwiseAnd %v4uint %9382 %1611 + %13992 = OpConvertUToF %v4float %19036 + %19240 = OpVectorTimesScalar %v4float %13992 %float_0_00392156886 + %8612 = OpCompositeExtract %uint %10944 3 + %24848 = OpCompositeConstruct %v4uint %8612 %8612 %8612 %8612 + %9383 = OpShiftRightLogical %v4uint %24848 %653 + %19037 = OpBitwiseAnd %v4uint %9383 %1611 + %17179 = OpConvertUToF %v4float %19037 + %12435 = OpVectorTimesScalar %v4float %17179 %float_0_00392156886 + OpBranch %16225 + %19452 = OpLabel + %12430 = OpCompositeExtract %uint %10944 0 + %20463 = OpBitcast %float %12430 + %17209 = OpCompositeConstruct %v2float %20463 %float_0 + %11667 = OpVectorShuffle %v4float %17209 %17209 0 1 1 1 + %22196 = OpCompositeExtract %uint %10944 1 + %16235 = OpBitcast %float %22196 + %17210 = OpCompositeConstruct %v2float %16235 %float_0 + %11668 = OpVectorShuffle %v4float %17210 %17210 0 1 1 1 + %22197 = OpCompositeExtract %uint %10944 2 + %16236 = OpBitcast %float %22197 + %17211 = OpCompositeConstruct %v2float %16236 %float_0 + %11669 = OpVectorShuffle %v4float %17211 %17211 0 1 1 1 + %22198 = OpCompositeExtract %uint %10944 3 + %16237 = OpBitcast %float %22198 + %20399 = OpCompositeConstruct %v2float %16237 %float_0 + %23099 = OpVectorShuffle %v4float %20399 %20399 0 1 1 1 + OpBranch %16225 + %16225 = OpLabel + %11178 = OpPhi %v4float %23099 %19452 %12435 %14586 %9888 %7357 %9040 %7356 %9039 %8191 %9038 %8245 + %14347 = OpPhi %v4float %11669 %19452 %19240 %14586 %16693 %7357 %15839 %7356 %16675 %8191 %14612 %8245 + %15231 = OpPhi %v4float %11668 %19452 %19239 %14586 %16692 %7357 %15838 %7356 %16674 %8191 %14611 %8245 + %14520 = OpPhi %v4float %11667 %19452 %19238 %14586 %16691 %7357 %15837 %7356 %16673 %8191 %14610 %8245 + OpBranch %21264 + %15206 = OpLabel + %21585 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20261 DontFlatten + OpBranchConditional %21585 %9765 %12132 + %12132 = OpLabel + %19410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24184 + %23881 = OpLoad %uint %19410 + %11706 = OpIAdd %uint %23256 %uint_81 + %6409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11706 + %23663 = OpLoad %uint %6409 + %11707 = OpIAdd %uint %24184 %6555 + %6410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11707 + %23664 = OpLoad %uint %6410 + %11708 = OpIAdd %uint %11707 %uint_1 + %24564 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11708 + %14157 = OpLoad %uint %24564 + %19671 = OpCompositeConstruct %v4uint %23881 %23663 %23664 %14157 + %17049 = OpIMul %uint %uint_2 %6555 + %13993 = OpIAdd %uint %24184 %17049 + %15235 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13993 + %23665 = OpLoad %uint %15235 + %11709 = OpIAdd %uint %13993 %uint_1 + %6478 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11709 + %24160 = OpLoad %uint %6478 + %6239 = OpIMul %uint %uint_3 %6555 + %8358 = OpIAdd %uint %24184 %6239 + %15236 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8358 + %23666 = OpLoad %uint %15236 + %11710 = OpIAdd %uint %8358 %uint_1 + %24565 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11710 + %16385 = OpLoad %uint %24565 + %20786 = OpCompositeConstruct %v4uint %23665 %24160 %23666 %16385 + OpBranch %20261 + %9765 = OpLabel + %21832 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24184 + %23882 = OpLoad %uint %21832 + %11711 = OpIAdd %uint %23256 %uint_81 + %6411 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11711 + %23667 = OpLoad %uint %6411 + %11712 = OpIAdd %uint %23256 %uint_82 + %6412 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11712 + %23668 = OpLoad %uint %6412 + %11713 = OpIAdd %uint %23256 %uint_83 + %24566 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11713 + %14081 = OpLoad %uint %24566 + %19166 = OpCompositeConstruct %v4uint %23882 %23667 %23668 %14081 + %22502 = OpIAdd %uint %23256 %uint_84 + %24652 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22502 + %23669 = OpLoad %uint %24652 + %11714 = OpIAdd %uint %23256 %uint_85 + %6413 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11714 + %23670 = OpLoad %uint %6413 + %11715 = OpIAdd %uint %23256 %uint_86 + %6414 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11715 + %23671 = OpLoad %uint %6414 + %11716 = OpIAdd %uint %23256 %uint_87 + %24567 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11716 + %16386 = OpLoad %uint %24567 + %20787 = OpCompositeConstruct %v4uint %23669 %23670 %23671 %16386 + OpBranch %20261 + %20261 = OpLabel + %11214 = OpPhi %v4uint %20787 %9765 %20786 %12132 + %14113 = OpPhi %v4uint %19166 %9765 %19671 %12132 + OpSelectionMerge %20262 None + OpSwitch %8576 %20311 5 %8537 7 %8246 + %8246 = OpLabel + %24409 = OpCompositeExtract %uint %14113 0 + %24682 = OpExtInst %v2float %1 UnpackHalf2x16 %24409 + %10105 = OpCompositeExtract %float %24682 0 + %16060 = OpCompositeExtract %float %24682 1 + %17029 = OpCompositeExtract %uint %14113 1 + %15609 = OpExtInst %v2float %1 UnpackHalf2x16 %17029 + %10094 = OpCompositeExtract %float %15609 0 + %17487 = OpCompositeExtract %float %15609 1 + %14613 = OpCompositeConstruct %v4float %10105 %16060 %10094 %17487 + %17283 = OpCompositeExtract %uint %14113 2 + %18036 = OpExtInst %v2float %1 UnpackHalf2x16 %17283 + %10106 = OpCompositeExtract %float %18036 0 + %16061 = OpCompositeExtract %float %18036 1 + %17030 = OpCompositeExtract %uint %14113 3 + %15610 = OpExtInst %v2float %1 UnpackHalf2x16 %17030 + %10095 = OpCompositeExtract %float %15610 0 + %17488 = OpCompositeExtract %float %15610 1 + %14614 = OpCompositeConstruct %v4float %10106 %16061 %10095 %17488 + %17284 = OpCompositeExtract %uint %11214 0 + %18037 = OpExtInst %v2float %1 UnpackHalf2x16 %17284 + %10107 = OpCompositeExtract %float %18037 0 + %16062 = OpCompositeExtract %float %18037 1 + %17031 = OpCompositeExtract %uint %11214 1 + %15611 = OpExtInst %v2float %1 UnpackHalf2x16 %17031 + %10096 = OpCompositeExtract %float %15611 0 + %17489 = OpCompositeExtract %float %15611 1 + %14615 = OpCompositeConstruct %v4float %10107 %16062 %10096 %17489 + %17285 = OpCompositeExtract %uint %11214 2 + %18038 = OpExtInst %v2float %1 UnpackHalf2x16 %17285 + %10108 = OpCompositeExtract %float %18038 0 + %16063 = OpCompositeExtract %float %18038 1 + %17032 = OpCompositeExtract %uint %11214 3 + %15612 = OpExtInst %v2float %1 UnpackHalf2x16 %17032 + %10097 = OpCompositeExtract %float %15612 0 + %20673 = OpCompositeExtract %float %15612 1 + %9041 = OpCompositeConstruct %v4float %10108 %16063 %10097 %20673 + OpBranch %20262 + %8537 = OpLabel + %9724 = OpVectorShuffle %v2uint %14113 %14113 0 1 + %23357 = OpBitcast %v2int %9724 + %24786 = OpVectorShuffle %v4int %23357 %23357 0 0 1 1 + %18602 = OpShiftLeftLogical %v4int %24786 %290 + %15761 = OpShiftRightArithmetic %v4int %18602 %770 + %10923 = OpConvertSToF %v4float %15761 + %18213 = OpVectorTimesScalar %v4float %10923 %float_0_000976592302 + %25236 = OpExtInst %v4float %1 FMax %1284 %18213 + %14190 = OpVectorShuffle %v2uint %14113 %14113 2 3 + %9410 = OpBitcast %v2int %14190 + %24787 = OpVectorShuffle %v4int %9410 %9410 0 0 1 1 + %18603 = OpShiftLeftLogical %v4int %24787 %290 + %15762 = OpShiftRightArithmetic %v4int %18603 %770 + %10924 = OpConvertSToF %v4float %15762 + %18214 = OpVectorTimesScalar %v4float %10924 %float_0_000976592302 + %25237 = OpExtInst %v4float %1 FMax %1284 %18214 + %14191 = OpVectorShuffle %v2uint %11214 %11214 0 1 + %9411 = OpBitcast %v2int %14191 + %24788 = OpVectorShuffle %v4int %9411 %9411 0 0 1 1 + %18604 = OpShiftLeftLogical %v4int %24788 %290 + %15763 = OpShiftRightArithmetic %v4int %18604 %770 + %10925 = OpConvertSToF %v4float %15763 + %18215 = OpVectorTimesScalar %v4float %10925 %float_0_000976592302 + %25238 = OpExtInst %v4float %1 FMax %1284 %18215 + %14192 = OpVectorShuffle %v2uint %11214 %11214 2 3 + %9412 = OpBitcast %v2int %14192 + %24789 = OpVectorShuffle %v4int %9412 %9412 0 0 1 1 + %18605 = OpShiftLeftLogical %v4int %24789 %290 + %15764 = OpShiftRightArithmetic %v4int %18605 %770 + %10926 = OpConvertSToF %v4float %15764 + %21440 = OpVectorTimesScalar %v4float %10926 %float_0_000976592302 + %17251 = OpExtInst %v4float %1 FMax %1284 %21440 + OpBranch %20262 + %20311 = OpLabel + %9766 = OpVectorShuffle %v2uint %14113 %14113 0 1 + %20826 = OpBitcast %v2float %9766 + %7039 = OpCompositeExtract %float %20826 0 + %13421 = OpCompositeExtract %float %20826 1 + %17019 = OpCompositeConstruct %v4float %7039 %13421 %float_0 %float_0 + %16859 = OpVectorShuffle %v2uint %14113 %14113 2 3 + %14176 = OpBitcast %v2float %16859 + %7040 = OpCompositeExtract %float %14176 0 + %13422 = OpCompositeExtract %float %14176 1 + %17020 = OpCompositeConstruct %v4float %7040 %13422 %float_0 %float_0 + %16860 = OpVectorShuffle %v2uint %11214 %11214 0 1 + %14177 = OpBitcast %v2float %16860 + %7041 = OpCompositeExtract %float %14177 0 + %13423 = OpCompositeExtract %float %14177 1 + %17021 = OpCompositeConstruct %v4float %7041 %13423 %float_0 %float_0 + %16861 = OpVectorShuffle %v2uint %11214 %11214 2 3 + %14178 = OpBitcast %v2float %16861 + %7042 = OpCompositeExtract %float %14178 0 + %16649 = OpCompositeExtract %float %14178 1 + %9042 = OpCompositeConstruct %v4float %7042 %16649 %float_0 %float_0 + OpBranch %20262 + %20262 = OpLabel + %11179 = OpPhi %v4float %9042 %20311 %17251 %8537 %9041 %8246 + %14348 = OpPhi %v4float %17021 %20311 %25238 %8537 %14615 %8246 + %15232 = OpPhi %v4float %17020 %20311 %25237 %8537 %14614 %8246 + %14521 = OpPhi %v4float %17019 %20311 %25236 %8537 %14613 %8246 + OpBranch %21264 + %21264 = OpLabel + %11180 = OpPhi %v4float %11179 %20262 %11178 %16225 + %14349 = OpPhi %v4float %14348 %20262 %14347 %16225 + %12949 = OpPhi %v4float %15232 %20262 %15231 %16225 + %13946 = OpPhi %v4float %14521 %20262 %14520 %16225 + %17241 = OpFAdd %v4float %8403 %13946 + %23297 = OpFAdd %v4float %13804 %12949 + %8082 = OpFAdd %v4float %14346 %14349 + %20755 = OpFAdd %v4float %11177 %11180 + %14461 = OpUGreaterThanEqual %bool %16205 %uint_6 + OpSelectionMerge %24264 DontFlatten + OpBranchConditional %14461 %9905 %24264 + %9905 = OpLabel + %14258 = OpShiftLeftLogical %uint %uint_1 %9130 + %12090 = OpFMul %float %11052 %float_0_25 + %20988 = OpIAdd %uint %23256 %14258 + OpSelectionMerge %21265 DontFlatten + OpBranchConditional %23279 %15207 %16571 + %16571 = OpLabel + %19167 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20299 DontFlatten + OpBranchConditional %19167 %9767 %12133 + %12133 = OpLabel + %19411 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23883 = OpLoad %uint %19411 + %11717 = OpIAdd %uint %20988 %6555 + %6479 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11717 + %24161 = OpLoad %uint %6479 + %6240 = OpIMul %uint %uint_2 %6555 + %8359 = OpIAdd %uint %20988 %6240 + %15311 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8359 + %24162 = OpLoad %uint %15311 + %6241 = OpIMul %uint %uint_3 %6555 + %8360 = OpIAdd %uint %20988 %6241 + %14323 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8360 + %16387 = OpLoad %uint %14323 + %20788 = OpCompositeConstruct %v4uint %23883 %24161 %24162 %16387 + OpBranch %20299 + %9767 = OpLabel + %21833 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23884 = OpLoad %uint %21833 + %11718 = OpIAdd %uint %20988 %uint_1 + %6415 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11718 + %23672 = OpLoad %uint %6415 + %11719 = OpIAdd %uint %20988 %uint_2 + %6416 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11719 + %23673 = OpLoad %uint %6416 + %11720 = OpIAdd %uint %20988 %uint_3 + %24568 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11720 + %16388 = OpLoad %uint %24568 + %20789 = OpCompositeConstruct %v4uint %23884 %23672 %23673 %16388 + OpBranch %20299 + %20299 = OpLabel + %10945 = OpPhi %v4uint %20789 %9767 %20788 %12133 + OpSelectionMerge %16226 None + OpSwitch %8576 %19453 0 %14587 1 %14587 2 %7359 10 %7359 3 %7358 12 %7358 4 %8192 6 %8247 + %8247 = OpLabel + %24410 = OpCompositeExtract %uint %10945 0 + %24683 = OpExtInst %v2float %1 UnpackHalf2x16 %24410 + %10098 = OpCompositeExtract %float %24683 0 + %17490 = OpCompositeExtract %float %24683 1 + %14616 = OpCompositeConstruct %v4float %10098 %17490 %float_0 %float_0 + %17286 = OpCompositeExtract %uint %10945 1 + %18039 = OpExtInst %v2float %1 UnpackHalf2x16 %17286 + %10099 = OpCompositeExtract %float %18039 0 + %17491 = OpCompositeExtract %float %18039 1 + %14617 = OpCompositeConstruct %v4float %10099 %17491 %float_0 %float_0 + %17287 = OpCompositeExtract %uint %10945 2 + %18040 = OpExtInst %v2float %1 UnpackHalf2x16 %17287 + %10100 = OpCompositeExtract %float %18040 0 + %17492 = OpCompositeExtract %float %18040 1 + %14618 = OpCompositeConstruct %v4float %10100 %17492 %float_0 %float_0 + %17288 = OpCompositeExtract %uint %10945 3 + %18041 = OpExtInst %v2float %1 UnpackHalf2x16 %17288 + %10109 = OpCompositeExtract %float %18041 0 + %20674 = OpCompositeExtract %float %18041 1 + %9043 = OpCompositeConstruct %v4float %10109 %20674 %float_0 %float_0 + OpBranch %16226 + %8192 = OpLabel + %12431 = OpCompositeExtract %uint %10945 0 + %22687 = OpBitcast %int %12431 + %18216 = OpCompositeConstruct %v2int %22687 %22687 + %18357 = OpShiftLeftLogical %v2int %18216 %1959 + %13343 = OpShiftRightArithmetic %v2int %18357 %2151 + %10927 = OpConvertSToF %v2float %13343 + %18255 = OpVectorTimesScalar %v2float %10927 %float_0_000976592302 + %24078 = OpExtInst %v2float %1 FMax %73 %18255 + %24338 = OpCompositeExtract %float %24078 0 + %15578 = OpCompositeExtract %float %24078 1 + %16676 = OpCompositeConstruct %v4float %24338 %15578 %float_0 %float_0 + %19528 = OpCompositeExtract %uint %10945 1 + %16039 = OpBitcast %int %19528 + %18217 = OpCompositeConstruct %v2int %16039 %16039 + %18358 = OpShiftLeftLogical %v2int %18217 %1959 + %13344 = OpShiftRightArithmetic %v2int %18358 %2151 + %10928 = OpConvertSToF %v2float %13344 + %18256 = OpVectorTimesScalar %v2float %10928 %float_0_000976592302 + %24079 = OpExtInst %v2float %1 FMax %73 %18256 + %24339 = OpCompositeExtract %float %24079 0 + %15579 = OpCompositeExtract %float %24079 1 + %16677 = OpCompositeConstruct %v4float %24339 %15579 %float_0 %float_0 + %19529 = OpCompositeExtract %uint %10945 2 + %16040 = OpBitcast %int %19529 + %18218 = OpCompositeConstruct %v2int %16040 %16040 + %18359 = OpShiftLeftLogical %v2int %18218 %1959 + %13345 = OpShiftRightArithmetic %v2int %18359 %2151 + %10929 = OpConvertSToF %v2float %13345 + %18257 = OpVectorTimesScalar %v2float %10929 %float_0_000976592302 + %24080 = OpExtInst %v2float %1 FMax %73 %18257 + %24340 = OpCompositeExtract %float %24080 0 + %15580 = OpCompositeExtract %float %24080 1 + %16678 = OpCompositeConstruct %v4float %24340 %15580 %float_0 %float_0 + %19530 = OpCompositeExtract %uint %10945 3 + %16041 = OpBitcast %int %19530 + %18219 = OpCompositeConstruct %v2int %16041 %16041 + %18360 = OpShiftLeftLogical %v2int %18219 %1959 + %13346 = OpShiftRightArithmetic %v2int %18360 %2151 + %10930 = OpConvertSToF %v2float %13346 + %18258 = OpVectorTimesScalar %v2float %10930 %float_0_000976592302 + %24081 = OpExtInst %v2float %1 FMax %73 %18258 + %24341 = OpCompositeExtract %float %24081 0 + %18766 = OpCompositeExtract %float %24081 1 + %9044 = OpCompositeConstruct %v4float %24341 %18766 %float_0 %float_0 + OpBranch %16226 + %7358 = OpLabel + %22211 = OpCompositeExtract %uint %10945 0 + %20240 = OpCompositeConstruct %v3uint %22211 %22211 %22211 + %11031 = OpShiftRightLogical %v3uint %20240 %2996 + %24046 = OpBitwiseAnd %v3uint %11031 %261 + %18596 = OpBitwiseAnd %v3uint %24046 %1126 + %23448 = OpShiftRightLogical %v3uint %24046 %2828 + %16593 = OpIEqual %v3bool %23448 %2578 + %11347 = OpExtInst %v3int %1 FindUMsb %18596 + %10781 = OpBitcast %v3uint %11347 + %6274 = OpISub %v3uint %2828 %10781 + %8728 = OpIAdd %v3uint %10781 %2360 + %10359 = OpSelect %v3uint %16593 %8728 %23448 + %23261 = OpShiftLeftLogical %v3uint %18596 %6274 + %18850 = OpBitwiseAnd %v3uint %23261 %1126 + %10931 = OpSelect %v3uint %16593 %18850 %18596 + %24577 = OpIAdd %v3uint %10359 %1018 + %20359 = OpShiftLeftLogical %v3uint %24577 %393 + %16302 = OpShiftLeftLogical %v3uint %10931 %141 + %22404 = OpBitwiseOr %v3uint %20359 %16302 + %13832 = OpIEqual %v3bool %24046 %2578 + %16970 = OpSelect %v3uint %13832 %2578 %22404 + %10711 = OpBitcast %v3float %16970 + %19372 = OpShiftRightLogical %uint %22211 %uint_30 + %18454 = OpConvertUToF %float %19372 + %15911 = OpFMul %float %18454 %float_0_333333343 + %21450 = OpCompositeExtract %float %10711 0 + %10845 = OpCompositeExtract %float %10711 1 + %7839 = OpCompositeExtract %float %10711 2 + %15840 = OpCompositeConstruct %v4float %21450 %10845 %7839 %15911 + %10235 = OpCompositeExtract %uint %10945 1 + %13588 = OpCompositeConstruct %v3uint %10235 %10235 %10235 + %11032 = OpShiftRightLogical %v3uint %13588 %2996 + %24047 = OpBitwiseAnd %v3uint %11032 %261 + %18597 = OpBitwiseAnd %v3uint %24047 %1126 + %23449 = OpShiftRightLogical %v3uint %24047 %2828 + %16594 = OpIEqual %v3bool %23449 %2578 + %11348 = OpExtInst %v3int %1 FindUMsb %18597 + %10782 = OpBitcast %v3uint %11348 + %6275 = OpISub %v3uint %2828 %10782 + %8729 = OpIAdd %v3uint %10782 %2360 + %10360 = OpSelect %v3uint %16594 %8729 %23449 + %23262 = OpShiftLeftLogical %v3uint %18597 %6275 + %18851 = OpBitwiseAnd %v3uint %23262 %1126 + %10932 = OpSelect %v3uint %16594 %18851 %18597 + %24578 = OpIAdd %v3uint %10360 %1018 + %20360 = OpShiftLeftLogical %v3uint %24578 %393 + %16303 = OpShiftLeftLogical %v3uint %10932 %141 + %22405 = OpBitwiseOr %v3uint %20360 %16303 + %13833 = OpIEqual %v3bool %24047 %2578 + %16971 = OpSelect %v3uint %13833 %2578 %22405 + %10712 = OpBitcast %v3float %16971 + %19373 = OpShiftRightLogical %uint %10235 %uint_30 + %18455 = OpConvertUToF %float %19373 + %15912 = OpFMul %float %18455 %float_0_333333343 + %21451 = OpCompositeExtract %float %10712 0 + %10846 = OpCompositeExtract %float %10712 1 + %7840 = OpCompositeExtract %float %10712 2 + %15841 = OpCompositeConstruct %v4float %21451 %10846 %7840 %15912 + %10236 = OpCompositeExtract %uint %10945 2 + %13589 = OpCompositeConstruct %v3uint %10236 %10236 %10236 + %11033 = OpShiftRightLogical %v3uint %13589 %2996 + %24048 = OpBitwiseAnd %v3uint %11033 %261 + %18606 = OpBitwiseAnd %v3uint %24048 %1126 + %23450 = OpShiftRightLogical %v3uint %24048 %2828 + %16595 = OpIEqual %v3bool %23450 %2578 + %11349 = OpExtInst %v3int %1 FindUMsb %18606 + %10783 = OpBitcast %v3uint %11349 + %6276 = OpISub %v3uint %2828 %10783 + %8730 = OpIAdd %v3uint %10783 %2360 + %10361 = OpSelect %v3uint %16595 %8730 %23450 + %23263 = OpShiftLeftLogical %v3uint %18606 %6276 + %18852 = OpBitwiseAnd %v3uint %23263 %1126 + %10933 = OpSelect %v3uint %16595 %18852 %18606 + %24579 = OpIAdd %v3uint %10361 %1018 + %20361 = OpShiftLeftLogical %v3uint %24579 %393 + %16304 = OpShiftLeftLogical %v3uint %10933 %141 + %22406 = OpBitwiseOr %v3uint %20361 %16304 + %13834 = OpIEqual %v3bool %24048 %2578 + %16972 = OpSelect %v3uint %13834 %2578 %22406 + %10713 = OpBitcast %v3float %16972 + %19374 = OpShiftRightLogical %uint %10236 %uint_30 + %18456 = OpConvertUToF %float %19374 + %15913 = OpFMul %float %18456 %float_0_333333343 + %21452 = OpCompositeExtract %float %10713 0 + %10847 = OpCompositeExtract %float %10713 1 + %7841 = OpCompositeExtract %float %10713 2 + %15842 = OpCompositeConstruct %v4float %21452 %10847 %7841 %15913 + %10237 = OpCompositeExtract %uint %10945 3 + %13590 = OpCompositeConstruct %v3uint %10237 %10237 %10237 + %11034 = OpShiftRightLogical %v3uint %13590 %2996 + %24049 = OpBitwiseAnd %v3uint %11034 %261 + %18607 = OpBitwiseAnd %v3uint %24049 %1126 + %23451 = OpShiftRightLogical %v3uint %24049 %2828 + %16596 = OpIEqual %v3bool %23451 %2578 + %11350 = OpExtInst %v3int %1 FindUMsb %18607 + %10784 = OpBitcast %v3uint %11350 + %6277 = OpISub %v3uint %2828 %10784 + %8731 = OpIAdd %v3uint %10784 %2360 + %10362 = OpSelect %v3uint %16596 %8731 %23451 + %23264 = OpShiftLeftLogical %v3uint %18607 %6277 + %18853 = OpBitwiseAnd %v3uint %23264 %1126 + %10934 = OpSelect %v3uint %16596 %18853 %18607 + %24580 = OpIAdd %v3uint %10362 %1018 + %20362 = OpShiftLeftLogical %v3uint %24580 %393 + %16305 = OpShiftLeftLogical %v3uint %10934 %141 + %22407 = OpBitwiseOr %v3uint %20362 %16305 + %13835 = OpIEqual %v3bool %24049 %2578 + %16973 = OpSelect %v3uint %13835 %2578 %22407 + %10714 = OpBitcast %v3float %16973 + %19375 = OpShiftRightLogical %uint %10237 %uint_30 + %18457 = OpConvertUToF %float %19375 + %15914 = OpFMul %float %18457 %float_0_333333343 + %21453 = OpCompositeExtract %float %10714 0 + %10848 = OpCompositeExtract %float %10714 1 + %11035 = OpCompositeExtract %float %10714 2 + %9045 = OpCompositeConstruct %v4float %21453 %10848 %11035 %15914 + OpBranch %16226 + %7359 = OpLabel + %22212 = OpCompositeExtract %uint %10945 0 + %20241 = OpCompositeConstruct %v4uint %22212 %22212 %22212 %22212 + %9384 = OpShiftRightLogical %v4uint %20241 %845 + %18867 = OpBitwiseAnd %v4uint %9384 %635 + %15549 = OpConvertUToF %v4float %18867 + %16694 = OpFMul %v4float %15549 %2798 + %23768 = OpCompositeExtract %uint %10945 1 + %20819 = OpCompositeConstruct %v4uint %23768 %23768 %23768 %23768 + %9385 = OpShiftRightLogical %v4uint %20819 %845 + %18868 = OpBitwiseAnd %v4uint %9385 %635 + %15550 = OpConvertUToF %v4float %18868 + %16695 = OpFMul %v4float %15550 %2798 + %23769 = OpCompositeExtract %uint %10945 2 + %20820 = OpCompositeConstruct %v4uint %23769 %23769 %23769 %23769 + %9386 = OpShiftRightLogical %v4uint %20820 %845 + %18869 = OpBitwiseAnd %v4uint %9386 %635 + %15551 = OpConvertUToF %v4float %18869 + %16696 = OpFMul %v4float %15551 %2798 + %23770 = OpCompositeExtract %uint %10945 3 + %20821 = OpCompositeConstruct %v4uint %23770 %23770 %23770 %23770 + %9387 = OpShiftRightLogical %v4uint %20821 %845 + %18870 = OpBitwiseAnd %v4uint %9387 %635 + %18737 = OpConvertUToF %v4float %18870 + %9889 = OpFMul %v4float %18737 %2798 + OpBranch %16226 + %14587 = OpLabel + %22213 = OpCompositeExtract %uint %10945 0 + %20242 = OpCompositeConstruct %v4uint %22213 %22213 %22213 %22213 + %9388 = OpShiftRightLogical %v4uint %20242 %653 + %19038 = OpBitwiseAnd %v4uint %9388 %1611 + %13994 = OpConvertUToF %v4float %19038 + %19241 = OpVectorTimesScalar %v4float %13994 %float_0_00392156886 + %8613 = OpCompositeExtract %uint %10945 1 + %24849 = OpCompositeConstruct %v4uint %8613 %8613 %8613 %8613 + %9389 = OpShiftRightLogical %v4uint %24849 %653 + %19039 = OpBitwiseAnd %v4uint %9389 %1611 + %13995 = OpConvertUToF %v4float %19039 + %19242 = OpVectorTimesScalar %v4float %13995 %float_0_00392156886 + %8614 = OpCompositeExtract %uint %10945 2 + %24850 = OpCompositeConstruct %v4uint %8614 %8614 %8614 %8614 + %9390 = OpShiftRightLogical %v4uint %24850 %653 + %19040 = OpBitwiseAnd %v4uint %9390 %1611 + %13996 = OpConvertUToF %v4float %19040 + %19243 = OpVectorTimesScalar %v4float %13996 %float_0_00392156886 + %8615 = OpCompositeExtract %uint %10945 3 + %24851 = OpCompositeConstruct %v4uint %8615 %8615 %8615 %8615 + %9391 = OpShiftRightLogical %v4uint %24851 %653 + %19041 = OpBitwiseAnd %v4uint %9391 %1611 + %17180 = OpConvertUToF %v4float %19041 + %12436 = OpVectorTimesScalar %v4float %17180 %float_0_00392156886 + OpBranch %16226 + %19453 = OpLabel + %12432 = OpCompositeExtract %uint %10945 0 + %20464 = OpBitcast %float %12432 + %17212 = OpCompositeConstruct %v2float %20464 %float_0 + %11670 = OpVectorShuffle %v4float %17212 %17212 0 1 1 1 + %22199 = OpCompositeExtract %uint %10945 1 + %16238 = OpBitcast %float %22199 + %17213 = OpCompositeConstruct %v2float %16238 %float_0 + %11671 = OpVectorShuffle %v4float %17213 %17213 0 1 1 1 + %22200 = OpCompositeExtract %uint %10945 2 + %16239 = OpBitcast %float %22200 + %17214 = OpCompositeConstruct %v2float %16239 %float_0 + %11672 = OpVectorShuffle %v4float %17214 %17214 0 1 1 1 + %22201 = OpCompositeExtract %uint %10945 3 + %16240 = OpBitcast %float %22201 + %20400 = OpCompositeConstruct %v2float %16240 %float_0 + %23100 = OpVectorShuffle %v4float %20400 %20400 0 1 1 1 + OpBranch %16226 + %16226 = OpLabel + %11181 = OpPhi %v4float %23100 %19453 %12436 %14587 %9889 %7359 %9045 %7358 %9044 %8192 %9043 %8247 + %14350 = OpPhi %v4float %11672 %19453 %19243 %14587 %16696 %7359 %15842 %7358 %16678 %8192 %14618 %8247 + %15237 = OpPhi %v4float %11671 %19453 %19242 %14587 %16695 %7359 %15841 %7358 %16677 %8192 %14617 %8247 + %14522 = OpPhi %v4float %11670 %19453 %19241 %14587 %16694 %7359 %15840 %7358 %16676 %8192 %14616 %8247 + OpBranch %21265 + %15207 = OpLabel + %21586 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20263 DontFlatten + OpBranchConditional %21586 %9768 %12134 + %12134 = OpLabel + %19412 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23885 = OpLoad %uint %19412 + %11721 = OpIAdd %uint %20988 %uint_1 + %6417 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11721 + %23674 = OpLoad %uint %6417 + %11722 = OpIAdd %uint %20988 %6555 + %6418 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11722 + %23675 = OpLoad %uint %6418 + %11723 = OpIAdd %uint %11722 %uint_1 + %24581 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11723 + %14158 = OpLoad %uint %24581 + %19673 = OpCompositeConstruct %v4uint %23885 %23674 %23675 %14158 + %17050 = OpIMul %uint %uint_2 %6555 + %13997 = OpIAdd %uint %20988 %17050 + %15238 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13997 + %23676 = OpLoad %uint %15238 + %11724 = OpIAdd %uint %13997 %uint_1 + %6480 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11724 + %24163 = OpLoad %uint %6480 + %6242 = OpIMul %uint %uint_3 %6555 + %8361 = OpIAdd %uint %20988 %6242 + %15239 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8361 + %23677 = OpLoad %uint %15239 + %11725 = OpIAdd %uint %8361 %uint_1 + %24582 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11725 + %16389 = OpLoad %uint %24582 + %20790 = OpCompositeConstruct %v4uint %23676 %24163 %23677 %16389 + OpBranch %20263 + %9768 = OpLabel + %21834 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23886 = OpLoad %uint %21834 + %11726 = OpIAdd %uint %20988 %uint_1 + %6419 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11726 + %23678 = OpLoad %uint %6419 + %11727 = OpIAdd %uint %20988 %uint_2 + %6420 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11727 + %23679 = OpLoad %uint %6420 + %11728 = OpIAdd %uint %20988 %uint_3 + %24583 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11728 + %14082 = OpLoad %uint %24583 + %19168 = OpCompositeConstruct %v4uint %23886 %23678 %23679 %14082 + %22503 = OpIAdd %uint %20988 %uint_4 + %24653 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22503 + %23680 = OpLoad %uint %24653 + %11729 = OpIAdd %uint %20988 %uint_5 + %6421 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11729 + %23681 = OpLoad %uint %6421 + %11730 = OpIAdd %uint %20988 %uint_6 + %6422 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11730 + %23682 = OpLoad %uint %6422 + %11731 = OpIAdd %uint %20988 %uint_7 + %24584 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11731 + %16390 = OpLoad %uint %24584 + %20791 = OpCompositeConstruct %v4uint %23680 %23681 %23682 %16390 + OpBranch %20263 + %20263 = OpLabel + %11215 = OpPhi %v4uint %20791 %9768 %20790 %12134 + %14114 = OpPhi %v4uint %19168 %9768 %19673 %12134 + OpSelectionMerge %20264 None + OpSwitch %8576 %20312 5 %8538 7 %8248 + %8248 = OpLabel + %24411 = OpCompositeExtract %uint %14114 0 + %24684 = OpExtInst %v2float %1 UnpackHalf2x16 %24411 + %10110 = OpCompositeExtract %float %24684 0 + %16064 = OpCompositeExtract %float %24684 1 + %17033 = OpCompositeExtract %uint %14114 1 + %15613 = OpExtInst %v2float %1 UnpackHalf2x16 %17033 + %10111 = OpCompositeExtract %float %15613 0 + %17493 = OpCompositeExtract %float %15613 1 + %14619 = OpCompositeConstruct %v4float %10110 %16064 %10111 %17493 + %17289 = OpCompositeExtract %uint %14114 2 + %18042 = OpExtInst %v2float %1 UnpackHalf2x16 %17289 + %10112 = OpCompositeExtract %float %18042 0 + %16065 = OpCompositeExtract %float %18042 1 + %17034 = OpCompositeExtract %uint %14114 3 + %15614 = OpExtInst %v2float %1 UnpackHalf2x16 %17034 + %10113 = OpCompositeExtract %float %15614 0 + %17494 = OpCompositeExtract %float %15614 1 + %14620 = OpCompositeConstruct %v4float %10112 %16065 %10113 %17494 + %17290 = OpCompositeExtract %uint %11215 0 + %18043 = OpExtInst %v2float %1 UnpackHalf2x16 %17290 + %10114 = OpCompositeExtract %float %18043 0 + %16066 = OpCompositeExtract %float %18043 1 + %17035 = OpCompositeExtract %uint %11215 1 + %15615 = OpExtInst %v2float %1 UnpackHalf2x16 %17035 + %10115 = OpCompositeExtract %float %15615 0 + %17495 = OpCompositeExtract %float %15615 1 + %14621 = OpCompositeConstruct %v4float %10114 %16066 %10115 %17495 + %17291 = OpCompositeExtract %uint %11215 2 + %18044 = OpExtInst %v2float %1 UnpackHalf2x16 %17291 + %10116 = OpCompositeExtract %float %18044 0 + %16067 = OpCompositeExtract %float %18044 1 + %17036 = OpCompositeExtract %uint %11215 3 + %15616 = OpExtInst %v2float %1 UnpackHalf2x16 %17036 + %10117 = OpCompositeExtract %float %15616 0 + %20675 = OpCompositeExtract %float %15616 1 + %9046 = OpCompositeConstruct %v4float %10116 %16067 %10117 %20675 + OpBranch %20264 + %8538 = OpLabel + %9725 = OpVectorShuffle %v2uint %14114 %14114 0 1 + %23358 = OpBitcast %v2int %9725 + %24790 = OpVectorShuffle %v4int %23358 %23358 0 0 1 1 + %18608 = OpShiftLeftLogical %v4int %24790 %290 + %15765 = OpShiftRightArithmetic %v4int %18608 %770 + %10935 = OpConvertSToF %v4float %15765 + %18220 = OpVectorTimesScalar %v4float %10935 %float_0_000976592302 + %25239 = OpExtInst %v4float %1 FMax %1284 %18220 + %14193 = OpVectorShuffle %v2uint %14114 %14114 2 3 + %9413 = OpBitcast %v2int %14193 + %24791 = OpVectorShuffle %v4int %9413 %9413 0 0 1 1 + %18609 = OpShiftLeftLogical %v4int %24791 %290 + %15766 = OpShiftRightArithmetic %v4int %18609 %770 + %10936 = OpConvertSToF %v4float %15766 + %18221 = OpVectorTimesScalar %v4float %10936 %float_0_000976592302 + %25240 = OpExtInst %v4float %1 FMax %1284 %18221 + %14194 = OpVectorShuffle %v2uint %11215 %11215 0 1 + %9414 = OpBitcast %v2int %14194 + %24792 = OpVectorShuffle %v4int %9414 %9414 0 0 1 1 + %18610 = OpShiftLeftLogical %v4int %24792 %290 + %15767 = OpShiftRightArithmetic %v4int %18610 %770 + %10937 = OpConvertSToF %v4float %15767 + %18222 = OpVectorTimesScalar %v4float %10937 %float_0_000976592302 + %25241 = OpExtInst %v4float %1 FMax %1284 %18222 + %14195 = OpVectorShuffle %v2uint %11215 %11215 2 3 + %9415 = OpBitcast %v2int %14195 + %24793 = OpVectorShuffle %v4int %9415 %9415 0 0 1 1 + %18611 = OpShiftLeftLogical %v4int %24793 %290 + %15768 = OpShiftRightArithmetic %v4int %18611 %770 + %10938 = OpConvertSToF %v4float %15768 + %21441 = OpVectorTimesScalar %v4float %10938 %float_0_000976592302 + %17252 = OpExtInst %v4float %1 FMax %1284 %21441 + OpBranch %20264 + %20312 = OpLabel + %9769 = OpVectorShuffle %v2uint %14114 %14114 0 1 + %20827 = OpBitcast %v2float %9769 + %7043 = OpCompositeExtract %float %20827 0 + %13424 = OpCompositeExtract %float %20827 1 + %17022 = OpCompositeConstruct %v4float %7043 %13424 %float_0 %float_0 + %16862 = OpVectorShuffle %v2uint %14114 %14114 2 3 + %14179 = OpBitcast %v2float %16862 + %7044 = OpCompositeExtract %float %14179 0 + %13425 = OpCompositeExtract %float %14179 1 + %17023 = OpCompositeConstruct %v4float %7044 %13425 %float_0 %float_0 + %16863 = OpVectorShuffle %v2uint %11215 %11215 0 1 + %14180 = OpBitcast %v2float %16863 + %7045 = OpCompositeExtract %float %14180 0 + %13426 = OpCompositeExtract %float %14180 1 + %17024 = OpCompositeConstruct %v4float %7045 %13426 %float_0 %float_0 + %16864 = OpVectorShuffle %v2uint %11215 %11215 2 3 + %14181 = OpBitcast %v2float %16864 + %7046 = OpCompositeExtract %float %14181 0 + %16650 = OpCompositeExtract %float %14181 1 + %9047 = OpCompositeConstruct %v4float %7046 %16650 %float_0 %float_0 + OpBranch %20264 + %20264 = OpLabel + %11182 = OpPhi %v4float %9047 %20312 %17252 %8538 %9046 %8248 + %14351 = OpPhi %v4float %17024 %20312 %25241 %8538 %14621 %8248 + %15240 = OpPhi %v4float %17023 %20312 %25240 %8538 %14620 %8248 + %14523 = OpPhi %v4float %17022 %20312 %25239 %8538 %14619 %8248 + OpBranch %21265 + %21265 = OpLabel + %11183 = OpPhi %v4float %11182 %20264 %11181 %16226 + %14352 = OpPhi %v4float %14351 %20264 %14350 %16226 + %12950 = OpPhi %v4float %15240 %20264 %15237 %16226 + %13947 = OpPhi %v4float %14523 %20264 %14522 %16226 + %17242 = OpFAdd %v4float %17241 %13947 + %23298 = OpFAdd %v4float %23297 %12950 + %7208 = OpFAdd %v4float %8082 %14352 + %9642 = OpFAdd %v4float %20755 %11183 + %16376 = OpIAdd %uint %24184 %14258 + OpSelectionMerge %21266 DontFlatten + OpBranchConditional %23279 %15208 %16572 + %16572 = OpLabel + %19169 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20300 DontFlatten + OpBranchConditional %19169 %9770 %12135 + %12135 = OpLabel + %19413 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23887 = OpLoad %uint %19413 + %11732 = OpIAdd %uint %16376 %6555 + %6481 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11732 + %24164 = OpLoad %uint %6481 + %6243 = OpIMul %uint %uint_2 %6555 + %8362 = OpIAdd %uint %16376 %6243 + %15312 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8362 + %24165 = OpLoad %uint %15312 + %6244 = OpIMul %uint %uint_3 %6555 + %8363 = OpIAdd %uint %16376 %6244 + %14324 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8363 + %16391 = OpLoad %uint %14324 + %20792 = OpCompositeConstruct %v4uint %23887 %24164 %24165 %16391 + OpBranch %20300 + %9770 = OpLabel + %21835 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23888 = OpLoad %uint %21835 + %11733 = OpIAdd %uint %16376 %uint_1 + %6423 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11733 + %23683 = OpLoad %uint %6423 + %11734 = OpIAdd %uint %16376 %uint_2 + %6424 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11734 + %23684 = OpLoad %uint %6424 + %11735 = OpIAdd %uint %16376 %uint_3 + %24585 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11735 + %16392 = OpLoad %uint %24585 + %20793 = OpCompositeConstruct %v4uint %23888 %23683 %23684 %16392 + OpBranch %20300 + %20300 = OpLabel + %10946 = OpPhi %v4uint %20793 %9770 %20792 %12135 + OpSelectionMerge %16227 None + OpSwitch %8576 %19454 0 %14588 1 %14588 2 %7361 10 %7361 3 %7360 12 %7360 4 %8193 6 %8249 + %8249 = OpLabel + %24412 = OpCompositeExtract %uint %10946 0 + %24685 = OpExtInst %v2float %1 UnpackHalf2x16 %24412 + %10118 = OpCompositeExtract %float %24685 0 + %17496 = OpCompositeExtract %float %24685 1 + %14622 = OpCompositeConstruct %v4float %10118 %17496 %float_0 %float_0 + %17292 = OpCompositeExtract %uint %10946 1 + %18045 = OpExtInst %v2float %1 UnpackHalf2x16 %17292 + %10119 = OpCompositeExtract %float %18045 0 + %17497 = OpCompositeExtract %float %18045 1 + %14623 = OpCompositeConstruct %v4float %10119 %17497 %float_0 %float_0 + %17293 = OpCompositeExtract %uint %10946 2 + %18046 = OpExtInst %v2float %1 UnpackHalf2x16 %17293 + %10120 = OpCompositeExtract %float %18046 0 + %17498 = OpCompositeExtract %float %18046 1 + %14624 = OpCompositeConstruct %v4float %10120 %17498 %float_0 %float_0 + %17294 = OpCompositeExtract %uint %10946 3 + %18047 = OpExtInst %v2float %1 UnpackHalf2x16 %17294 + %10121 = OpCompositeExtract %float %18047 0 + %20676 = OpCompositeExtract %float %18047 1 + %9048 = OpCompositeConstruct %v4float %10121 %20676 %float_0 %float_0 + OpBranch %16227 + %8193 = OpLabel + %12433 = OpCompositeExtract %uint %10946 0 + %22688 = OpBitcast %int %12433 + %18223 = OpCompositeConstruct %v2int %22688 %22688 + %18361 = OpShiftLeftLogical %v2int %18223 %1959 + %13347 = OpShiftRightArithmetic %v2int %18361 %2151 + %10939 = OpConvertSToF %v2float %13347 + %18259 = OpVectorTimesScalar %v2float %10939 %float_0_000976592302 + %24082 = OpExtInst %v2float %1 FMax %73 %18259 + %24342 = OpCompositeExtract %float %24082 0 + %15581 = OpCompositeExtract %float %24082 1 + %16679 = OpCompositeConstruct %v4float %24342 %15581 %float_0 %float_0 + %19531 = OpCompositeExtract %uint %10946 1 + %16042 = OpBitcast %int %19531 + %18224 = OpCompositeConstruct %v2int %16042 %16042 + %18362 = OpShiftLeftLogical %v2int %18224 %1959 + %13348 = OpShiftRightArithmetic %v2int %18362 %2151 + %10940 = OpConvertSToF %v2float %13348 + %18260 = OpVectorTimesScalar %v2float %10940 %float_0_000976592302 + %24083 = OpExtInst %v2float %1 FMax %73 %18260 + %24343 = OpCompositeExtract %float %24083 0 + %15582 = OpCompositeExtract %float %24083 1 + %16680 = OpCompositeConstruct %v4float %24343 %15582 %float_0 %float_0 + %19532 = OpCompositeExtract %uint %10946 2 + %16043 = OpBitcast %int %19532 + %18225 = OpCompositeConstruct %v2int %16043 %16043 + %18363 = OpShiftLeftLogical %v2int %18225 %1959 + %13349 = OpShiftRightArithmetic %v2int %18363 %2151 + %10941 = OpConvertSToF %v2float %13349 + %18261 = OpVectorTimesScalar %v2float %10941 %float_0_000976592302 + %24084 = OpExtInst %v2float %1 FMax %73 %18261 + %24344 = OpCompositeExtract %float %24084 0 + %15583 = OpCompositeExtract %float %24084 1 + %16681 = OpCompositeConstruct %v4float %24344 %15583 %float_0 %float_0 + %19533 = OpCompositeExtract %uint %10946 3 + %16044 = OpBitcast %int %19533 + %18226 = OpCompositeConstruct %v2int %16044 %16044 + %18364 = OpShiftLeftLogical %v2int %18226 %1959 + %13350 = OpShiftRightArithmetic %v2int %18364 %2151 + %10942 = OpConvertSToF %v2float %13350 + %18262 = OpVectorTimesScalar %v2float %10942 %float_0_000976592302 + %24085 = OpExtInst %v2float %1 FMax %73 %18262 + %24345 = OpCompositeExtract %float %24085 0 + %18767 = OpCompositeExtract %float %24085 1 + %9049 = OpCompositeConstruct %v4float %24345 %18767 %float_0 %float_0 + OpBranch %16227 + %7360 = OpLabel + %22214 = OpCompositeExtract %uint %10946 0 + %20243 = OpCompositeConstruct %v3uint %22214 %22214 %22214 + %11036 = OpShiftRightLogical %v3uint %20243 %2996 + %24050 = OpBitwiseAnd %v3uint %11036 %261 + %18612 = OpBitwiseAnd %v3uint %24050 %1126 + %23452 = OpShiftRightLogical %v3uint %24050 %2828 + %16597 = OpIEqual %v3bool %23452 %2578 + %11351 = OpExtInst %v3int %1 FindUMsb %18612 + %10785 = OpBitcast %v3uint %11351 + %6278 = OpISub %v3uint %2828 %10785 + %8732 = OpIAdd %v3uint %10785 %2360 + %10363 = OpSelect %v3uint %16597 %8732 %23452 + %23265 = OpShiftLeftLogical %v3uint %18612 %6278 + %18854 = OpBitwiseAnd %v3uint %23265 %1126 + %10947 = OpSelect %v3uint %16597 %18854 %18612 + %24586 = OpIAdd %v3uint %10363 %1018 + %20363 = OpShiftLeftLogical %v3uint %24586 %393 + %16306 = OpShiftLeftLogical %v3uint %10947 %141 + %22408 = OpBitwiseOr %v3uint %20363 %16306 + %13836 = OpIEqual %v3bool %24050 %2578 + %16974 = OpSelect %v3uint %13836 %2578 %22408 + %10715 = OpBitcast %v3float %16974 + %19376 = OpShiftRightLogical %uint %22214 %uint_30 + %18458 = OpConvertUToF %float %19376 + %15915 = OpFMul %float %18458 %float_0_333333343 + %21454 = OpCompositeExtract %float %10715 0 + %10849 = OpCompositeExtract %float %10715 1 + %7842 = OpCompositeExtract %float %10715 2 + %15843 = OpCompositeConstruct %v4float %21454 %10849 %7842 %15915 + %10238 = OpCompositeExtract %uint %10946 1 + %13591 = OpCompositeConstruct %v3uint %10238 %10238 %10238 + %11037 = OpShiftRightLogical %v3uint %13591 %2996 + %24051 = OpBitwiseAnd %v3uint %11037 %261 + %18613 = OpBitwiseAnd %v3uint %24051 %1126 + %23453 = OpShiftRightLogical %v3uint %24051 %2828 + %16598 = OpIEqual %v3bool %23453 %2578 + %11352 = OpExtInst %v3int %1 FindUMsb %18613 + %10786 = OpBitcast %v3uint %11352 + %6279 = OpISub %v3uint %2828 %10786 + %8733 = OpIAdd %v3uint %10786 %2360 + %10364 = OpSelect %v3uint %16598 %8733 %23453 + %23266 = OpShiftLeftLogical %v3uint %18613 %6279 + %18855 = OpBitwiseAnd %v3uint %23266 %1126 + %10948 = OpSelect %v3uint %16598 %18855 %18613 + %24587 = OpIAdd %v3uint %10364 %1018 + %20364 = OpShiftLeftLogical %v3uint %24587 %393 + %16307 = OpShiftLeftLogical %v3uint %10948 %141 + %22409 = OpBitwiseOr %v3uint %20364 %16307 + %13837 = OpIEqual %v3bool %24051 %2578 + %16975 = OpSelect %v3uint %13837 %2578 %22409 + %10716 = OpBitcast %v3float %16975 + %19377 = OpShiftRightLogical %uint %10238 %uint_30 + %18459 = OpConvertUToF %float %19377 + %15916 = OpFMul %float %18459 %float_0_333333343 + %21455 = OpCompositeExtract %float %10716 0 + %10850 = OpCompositeExtract %float %10716 1 + %7843 = OpCompositeExtract %float %10716 2 + %15844 = OpCompositeConstruct %v4float %21455 %10850 %7843 %15916 + %10239 = OpCompositeExtract %uint %10946 2 + %13592 = OpCompositeConstruct %v3uint %10239 %10239 %10239 + %11038 = OpShiftRightLogical %v3uint %13592 %2996 + %24052 = OpBitwiseAnd %v3uint %11038 %261 + %18614 = OpBitwiseAnd %v3uint %24052 %1126 + %23454 = OpShiftRightLogical %v3uint %24052 %2828 + %16599 = OpIEqual %v3bool %23454 %2578 + %11353 = OpExtInst %v3int %1 FindUMsb %18614 + %10787 = OpBitcast %v3uint %11353 + %6280 = OpISub %v3uint %2828 %10787 + %8734 = OpIAdd %v3uint %10787 %2360 + %10365 = OpSelect %v3uint %16599 %8734 %23454 + %23267 = OpShiftLeftLogical %v3uint %18614 %6280 + %18856 = OpBitwiseAnd %v3uint %23267 %1126 + %10949 = OpSelect %v3uint %16599 %18856 %18614 + %24588 = OpIAdd %v3uint %10365 %1018 + %20365 = OpShiftLeftLogical %v3uint %24588 %393 + %16308 = OpShiftLeftLogical %v3uint %10949 %141 + %22410 = OpBitwiseOr %v3uint %20365 %16308 + %13838 = OpIEqual %v3bool %24052 %2578 + %16976 = OpSelect %v3uint %13838 %2578 %22410 + %10717 = OpBitcast %v3float %16976 + %19378 = OpShiftRightLogical %uint %10239 %uint_30 + %18460 = OpConvertUToF %float %19378 + %15917 = OpFMul %float %18460 %float_0_333333343 + %21456 = OpCompositeExtract %float %10717 0 + %10851 = OpCompositeExtract %float %10717 1 + %7844 = OpCompositeExtract %float %10717 2 + %15845 = OpCompositeConstruct %v4float %21456 %10851 %7844 %15917 + %10240 = OpCompositeExtract %uint %10946 3 + %13593 = OpCompositeConstruct %v3uint %10240 %10240 %10240 + %11039 = OpShiftRightLogical %v3uint %13593 %2996 + %24053 = OpBitwiseAnd %v3uint %11039 %261 + %18615 = OpBitwiseAnd %v3uint %24053 %1126 + %23455 = OpShiftRightLogical %v3uint %24053 %2828 + %16600 = OpIEqual %v3bool %23455 %2578 + %11354 = OpExtInst %v3int %1 FindUMsb %18615 + %10788 = OpBitcast %v3uint %11354 + %6281 = OpISub %v3uint %2828 %10788 + %8735 = OpIAdd %v3uint %10788 %2360 + %10366 = OpSelect %v3uint %16600 %8735 %23455 + %23268 = OpShiftLeftLogical %v3uint %18615 %6281 + %18857 = OpBitwiseAnd %v3uint %23268 %1126 + %10950 = OpSelect %v3uint %16600 %18857 %18615 + %24589 = OpIAdd %v3uint %10366 %1018 + %20366 = OpShiftLeftLogical %v3uint %24589 %393 + %16309 = OpShiftLeftLogical %v3uint %10950 %141 + %22411 = OpBitwiseOr %v3uint %20366 %16309 + %13839 = OpIEqual %v3bool %24053 %2578 + %16977 = OpSelect %v3uint %13839 %2578 %22411 + %10718 = OpBitcast %v3float %16977 + %19379 = OpShiftRightLogical %uint %10240 %uint_30 + %18461 = OpConvertUToF %float %19379 + %15918 = OpFMul %float %18461 %float_0_333333343 + %21457 = OpCompositeExtract %float %10718 0 + %10852 = OpCompositeExtract %float %10718 1 + %11040 = OpCompositeExtract %float %10718 2 + %9050 = OpCompositeConstruct %v4float %21457 %10852 %11040 %15918 + OpBranch %16227 + %7361 = OpLabel + %22215 = OpCompositeExtract %uint %10946 0 + %20244 = OpCompositeConstruct %v4uint %22215 %22215 %22215 %22215 + %9392 = OpShiftRightLogical %v4uint %20244 %845 + %18871 = OpBitwiseAnd %v4uint %9392 %635 + %15552 = OpConvertUToF %v4float %18871 + %16697 = OpFMul %v4float %15552 %2798 + %23771 = OpCompositeExtract %uint %10946 1 + %20822 = OpCompositeConstruct %v4uint %23771 %23771 %23771 %23771 + %9393 = OpShiftRightLogical %v4uint %20822 %845 + %18872 = OpBitwiseAnd %v4uint %9393 %635 + %15553 = OpConvertUToF %v4float %18872 + %16698 = OpFMul %v4float %15553 %2798 + %23772 = OpCompositeExtract %uint %10946 2 + %20823 = OpCompositeConstruct %v4uint %23772 %23772 %23772 %23772 + %9394 = OpShiftRightLogical %v4uint %20823 %845 + %18873 = OpBitwiseAnd %v4uint %9394 %635 + %15554 = OpConvertUToF %v4float %18873 + %16699 = OpFMul %v4float %15554 %2798 + %23773 = OpCompositeExtract %uint %10946 3 + %20828 = OpCompositeConstruct %v4uint %23773 %23773 %23773 %23773 + %9395 = OpShiftRightLogical %v4uint %20828 %845 + %18874 = OpBitwiseAnd %v4uint %9395 %635 + %18738 = OpConvertUToF %v4float %18874 + %9890 = OpFMul %v4float %18738 %2798 + OpBranch %16227 + %14588 = OpLabel + %22216 = OpCompositeExtract %uint %10946 0 + %20245 = OpCompositeConstruct %v4uint %22216 %22216 %22216 %22216 + %9396 = OpShiftRightLogical %v4uint %20245 %653 + %19042 = OpBitwiseAnd %v4uint %9396 %1611 + %13998 = OpConvertUToF %v4float %19042 + %19244 = OpVectorTimesScalar %v4float %13998 %float_0_00392156886 + %8616 = OpCompositeExtract %uint %10946 1 + %24852 = OpCompositeConstruct %v4uint %8616 %8616 %8616 %8616 + %9397 = OpShiftRightLogical %v4uint %24852 %653 + %19043 = OpBitwiseAnd %v4uint %9397 %1611 + %13999 = OpConvertUToF %v4float %19043 + %19245 = OpVectorTimesScalar %v4float %13999 %float_0_00392156886 + %8617 = OpCompositeExtract %uint %10946 2 + %24853 = OpCompositeConstruct %v4uint %8617 %8617 %8617 %8617 + %9398 = OpShiftRightLogical %v4uint %24853 %653 + %19044 = OpBitwiseAnd %v4uint %9398 %1611 + %14000 = OpConvertUToF %v4float %19044 + %19246 = OpVectorTimesScalar %v4float %14000 %float_0_00392156886 + %8618 = OpCompositeExtract %uint %10946 3 + %24854 = OpCompositeConstruct %v4uint %8618 %8618 %8618 %8618 + %9399 = OpShiftRightLogical %v4uint %24854 %653 + %19045 = OpBitwiseAnd %v4uint %9399 %1611 + %17181 = OpConvertUToF %v4float %19045 + %12437 = OpVectorTimesScalar %v4float %17181 %float_0_00392156886 + OpBranch %16227 + %19454 = OpLabel + %12438 = OpCompositeExtract %uint %10946 0 + %20465 = OpBitcast %float %12438 + %17215 = OpCompositeConstruct %v2float %20465 %float_0 + %11673 = OpVectorShuffle %v4float %17215 %17215 0 1 1 1 + %22202 = OpCompositeExtract %uint %10946 1 + %16241 = OpBitcast %float %22202 + %17216 = OpCompositeConstruct %v2float %16241 %float_0 + %11674 = OpVectorShuffle %v4float %17216 %17216 0 1 1 1 + %22203 = OpCompositeExtract %uint %10946 2 + %16242 = OpBitcast %float %22203 + %17217 = OpCompositeConstruct %v2float %16242 %float_0 + %11675 = OpVectorShuffle %v4float %17217 %17217 0 1 1 1 + %22204 = OpCompositeExtract %uint %10946 3 + %16243 = OpBitcast %float %22204 + %20401 = OpCompositeConstruct %v2float %16243 %float_0 + %23101 = OpVectorShuffle %v4float %20401 %20401 0 1 1 1 + OpBranch %16227 + %16227 = OpLabel + %11184 = OpPhi %v4float %23101 %19454 %12437 %14588 %9890 %7361 %9050 %7360 %9049 %8193 %9048 %8249 + %14353 = OpPhi %v4float %11675 %19454 %19246 %14588 %16699 %7361 %15845 %7360 %16681 %8193 %14624 %8249 + %15241 = OpPhi %v4float %11674 %19454 %19245 %14588 %16698 %7361 %15844 %7360 %16680 %8193 %14623 %8249 + %14524 = OpPhi %v4float %11673 %19454 %19244 %14588 %16697 %7361 %15843 %7360 %16679 %8193 %14622 %8249 + OpBranch %21266 + %15208 = OpLabel + %21587 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20265 DontFlatten + OpBranchConditional %21587 %9771 %12136 + %12136 = OpLabel + %19414 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23889 = OpLoad %uint %19414 + %11736 = OpIAdd %uint %16376 %uint_1 + %6425 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11736 + %23685 = OpLoad %uint %6425 + %11737 = OpIAdd %uint %16376 %6555 + %6426 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11737 + %23686 = OpLoad %uint %6426 + %11738 = OpIAdd %uint %11737 %uint_1 + %24590 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11738 + %14160 = OpLoad %uint %24590 + %19674 = OpCompositeConstruct %v4uint %23889 %23685 %23686 %14160 + %17051 = OpIMul %uint %uint_2 %6555 + %14001 = OpIAdd %uint %16376 %17051 + %15242 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %14001 + %23687 = OpLoad %uint %15242 + %11739 = OpIAdd %uint %14001 %uint_1 + %6482 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11739 + %24166 = OpLoad %uint %6482 + %6245 = OpIMul %uint %uint_3 %6555 + %8364 = OpIAdd %uint %16376 %6245 + %15243 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8364 + %23688 = OpLoad %uint %15243 + %11740 = OpIAdd %uint %8364 %uint_1 + %24591 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11740 + %16393 = OpLoad %uint %24591 + %20794 = OpCompositeConstruct %v4uint %23687 %24166 %23688 %16393 + OpBranch %20265 + %9771 = OpLabel + %21836 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23890 = OpLoad %uint %21836 + %11741 = OpIAdd %uint %16376 %uint_1 + %6427 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11741 + %23689 = OpLoad %uint %6427 + %11742 = OpIAdd %uint %16376 %uint_2 + %6428 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11742 + %23690 = OpLoad %uint %6428 + %11743 = OpIAdd %uint %16376 %uint_3 + %24592 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11743 + %14083 = OpLoad %uint %24592 + %19170 = OpCompositeConstruct %v4uint %23890 %23689 %23690 %14083 + %22504 = OpIAdd %uint %16376 %uint_4 + %24654 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22504 + %23691 = OpLoad %uint %24654 + %11744 = OpIAdd %uint %16376 %uint_5 + %6429 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11744 + %23692 = OpLoad %uint %6429 + %11745 = OpIAdd %uint %16376 %uint_6 + %6430 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11745 + %23693 = OpLoad %uint %6430 + %11746 = OpIAdd %uint %16376 %uint_7 + %24593 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11746 + %16394 = OpLoad %uint %24593 + %20795 = OpCompositeConstruct %v4uint %23691 %23692 %23693 %16394 + OpBranch %20265 + %20265 = OpLabel + %11216 = OpPhi %v4uint %20795 %9771 %20794 %12136 + %14115 = OpPhi %v4uint %19170 %9771 %19674 %12136 + OpSelectionMerge %20266 None + OpSwitch %8576 %20313 5 %8539 7 %8250 + %8250 = OpLabel + %24413 = OpCompositeExtract %uint %14115 0 + %24686 = OpExtInst %v2float %1 UnpackHalf2x16 %24413 + %10122 = OpCompositeExtract %float %24686 0 + %16068 = OpCompositeExtract %float %24686 1 + %17037 = OpCompositeExtract %uint %14115 1 + %15617 = OpExtInst %v2float %1 UnpackHalf2x16 %17037 + %10123 = OpCompositeExtract %float %15617 0 + %17499 = OpCompositeExtract %float %15617 1 + %14625 = OpCompositeConstruct %v4float %10122 %16068 %10123 %17499 + %17295 = OpCompositeExtract %uint %14115 2 + %18048 = OpExtInst %v2float %1 UnpackHalf2x16 %17295 + %10124 = OpCompositeExtract %float %18048 0 + %16069 = OpCompositeExtract %float %18048 1 + %17038 = OpCompositeExtract %uint %14115 3 + %15618 = OpExtInst %v2float %1 UnpackHalf2x16 %17038 + %10125 = OpCompositeExtract %float %15618 0 + %17500 = OpCompositeExtract %float %15618 1 + %14626 = OpCompositeConstruct %v4float %10124 %16069 %10125 %17500 + %17296 = OpCompositeExtract %uint %11216 0 + %18049 = OpExtInst %v2float %1 UnpackHalf2x16 %17296 + %10126 = OpCompositeExtract %float %18049 0 + %16070 = OpCompositeExtract %float %18049 1 + %17039 = OpCompositeExtract %uint %11216 1 + %15619 = OpExtInst %v2float %1 UnpackHalf2x16 %17039 + %10127 = OpCompositeExtract %float %15619 0 + %17501 = OpCompositeExtract %float %15619 1 + %14627 = OpCompositeConstruct %v4float %10126 %16070 %10127 %17501 + %17297 = OpCompositeExtract %uint %11216 2 + %18050 = OpExtInst %v2float %1 UnpackHalf2x16 %17297 + %10128 = OpCompositeExtract %float %18050 0 + %16071 = OpCompositeExtract %float %18050 1 + %17040 = OpCompositeExtract %uint %11216 3 + %15620 = OpExtInst %v2float %1 UnpackHalf2x16 %17040 + %10129 = OpCompositeExtract %float %15620 0 + %20677 = OpCompositeExtract %float %15620 1 + %9051 = OpCompositeConstruct %v4float %10128 %16071 %10129 %20677 + OpBranch %20266 + %8539 = OpLabel + %9726 = OpVectorShuffle %v2uint %14115 %14115 0 1 + %23359 = OpBitcast %v2int %9726 + %24794 = OpVectorShuffle %v4int %23359 %23359 0 0 1 1 + %18616 = OpShiftLeftLogical %v4int %24794 %290 + %15769 = OpShiftRightArithmetic %v4int %18616 %770 + %10951 = OpConvertSToF %v4float %15769 + %18227 = OpVectorTimesScalar %v4float %10951 %float_0_000976592302 + %25242 = OpExtInst %v4float %1 FMax %1284 %18227 + %14196 = OpVectorShuffle %v2uint %14115 %14115 2 3 + %9416 = OpBitcast %v2int %14196 + %24795 = OpVectorShuffle %v4int %9416 %9416 0 0 1 1 + %18617 = OpShiftLeftLogical %v4int %24795 %290 + %15770 = OpShiftRightArithmetic %v4int %18617 %770 + %10952 = OpConvertSToF %v4float %15770 + %18228 = OpVectorTimesScalar %v4float %10952 %float_0_000976592302 + %25243 = OpExtInst %v4float %1 FMax %1284 %18228 + %14197 = OpVectorShuffle %v2uint %11216 %11216 0 1 + %9417 = OpBitcast %v2int %14197 + %24796 = OpVectorShuffle %v4int %9417 %9417 0 0 1 1 + %18618 = OpShiftLeftLogical %v4int %24796 %290 + %15771 = OpShiftRightArithmetic %v4int %18618 %770 + %10953 = OpConvertSToF %v4float %15771 + %18229 = OpVectorTimesScalar %v4float %10953 %float_0_000976592302 + %25244 = OpExtInst %v4float %1 FMax %1284 %18229 + %14198 = OpVectorShuffle %v2uint %11216 %11216 2 3 + %9418 = OpBitcast %v2int %14198 + %24797 = OpVectorShuffle %v4int %9418 %9418 0 0 1 1 + %18619 = OpShiftLeftLogical %v4int %24797 %290 + %15772 = OpShiftRightArithmetic %v4int %18619 %770 + %10954 = OpConvertSToF %v4float %15772 + %21458 = OpVectorTimesScalar %v4float %10954 %float_0_000976592302 + %17253 = OpExtInst %v4float %1 FMax %1284 %21458 + OpBranch %20266 + %20313 = OpLabel + %9772 = OpVectorShuffle %v2uint %14115 %14115 0 1 + %20829 = OpBitcast %v2float %9772 + %7047 = OpCompositeExtract %float %20829 0 + %13427 = OpCompositeExtract %float %20829 1 + %17041 = OpCompositeConstruct %v4float %7047 %13427 %float_0 %float_0 + %16865 = OpVectorShuffle %v2uint %14115 %14115 2 3 + %14182 = OpBitcast %v2float %16865 + %7048 = OpCompositeExtract %float %14182 0 + %13428 = OpCompositeExtract %float %14182 1 + %17042 = OpCompositeConstruct %v4float %7048 %13428 %float_0 %float_0 + %16866 = OpVectorShuffle %v2uint %11216 %11216 0 1 + %14183 = OpBitcast %v2float %16866 + %7049 = OpCompositeExtract %float %14183 0 + %13429 = OpCompositeExtract %float %14183 1 + %17043 = OpCompositeConstruct %v4float %7049 %13429 %float_0 %float_0 + %16867 = OpVectorShuffle %v2uint %11216 %11216 2 3 + %14184 = OpBitcast %v2float %16867 + %7050 = OpCompositeExtract %float %14184 0 + %16651 = OpCompositeExtract %float %14184 1 + %9052 = OpCompositeConstruct %v4float %7050 %16651 %float_0 %float_0 + OpBranch %20266 + %20266 = OpLabel + %11185 = OpPhi %v4float %9052 %20313 %17253 %8539 %9051 %8250 + %14354 = OpPhi %v4float %17043 %20313 %25244 %8539 %14627 %8250 + %15244 = OpPhi %v4float %17042 %20313 %25243 %8539 %14626 %8250 + %14525 = OpPhi %v4float %17041 %20313 %25242 %8539 %14625 %8250 + OpBranch %21266 + %21266 = OpLabel + %11186 = OpPhi %v4float %11185 %20266 %11184 %16227 + %14355 = OpPhi %v4float %14354 %20266 %14353 %16227 + %12951 = OpPhi %v4float %15244 %20266 %15241 %16227 + %13948 = OpPhi %v4float %14525 %20266 %14524 %16227 + %17243 = OpFAdd %v4float %17242 %13948 + %23299 = OpFAdd %v4float %23298 %12951 + %9507 = OpFAdd %v4float %7208 %14355 + %7799 = OpFAdd %v4float %9642 %11186 + OpBranch %24264 + %24264 = OpLabel + %11187 = OpPhi %v4float %20755 %21264 %7799 %21266 + %14356 = OpPhi %v4float %8082 %21264 %9507 %21266 + %15153 = OpPhi %v4float %23297 %21264 %23299 %21266 + %15245 = OpPhi %v4float %17241 %21264 %17243 %21266 + %14526 = OpPhi %float %25083 %21264 %12090 %21266 + OpBranch %21267 + %21267 = OpLabel + %11188 = OpPhi %v4float %11177 %21263 %11187 %24264 + %14357 = OpPhi %v4float %14346 %21263 %14356 %24264 + %15154 = OpPhi %v4float %13804 %21263 %15153 %24264 + %13196 = OpPhi %v4float %8403 %21263 %15245 %24264 + %11944 = OpPhi %float %11052 %21263 %14526 %24264 + %23156 = OpVectorTimesScalar %v4float %13196 %11944 + %6604 = OpVectorTimesScalar %v4float %15154 %11944 + %12399 = OpVectorTimesScalar %v4float %14357 %11944 + %13362 = OpVectorTimesScalar %v4float %11188 %11944 + OpSelectionMerge %16228 DontFlatten + OpBranchConditional %7513 %10049 %16228 + %10049 = OpLabel + %15086 = OpVectorShuffle %v4float %23156 %23156 2 1 0 3 + %14855 = OpVectorShuffle %v4float %6604 %6604 2 1 0 3 + %7398 = OpVectorShuffle %v4float %12399 %12399 2 1 0 3 + %16111 = OpVectorShuffle %v4float %13362 %13362 2 1 0 3 + OpBranch %16228 + %16228 = OpLabel + %11189 = OpPhi %v4float %13362 %21267 %16111 %10049 + %14358 = OpPhi %v4float %12399 %21267 %7398 %10049 + %15191 = OpPhi %v4float %6604 %21267 %14855 %10049 + %14921 = OpPhi %v4float %23156 %21267 %15086 %10049 + OpSelectionMerge %18834 None + OpSwitch %20627 %7374 3 %17899 4 %6452 5 %6451 10 %7373 15 %12647 24 %9492 + %9492 = OpLabel + %15041 = OpCompositeExtract %float %14921 0 + %10277 = OpCompositeExtract %float %15191 0 + %7641 = OpCompositeExtract %float %14358 0 + %6565 = OpCompositeExtract %float %11189 0 + %7479 = OpCompositeConstruct %v4float %15041 %10277 %7641 %6565 + %14406 = OpExtInst %v4float %1 FClamp %7479 %2938 %1285 + %13687 = OpVectorTimesScalar %v4float %14406 %float_65535 + %11840 = OpFAdd %v4float %13687 %325 + %7947 = OpConvertFToU %v4uint %11840 + %6361 = OpVectorShuffle %v2uint %7947 %7947 0 2 + %10064 = OpVectorShuffle %v2uint %7947 %7947 1 3 + %13638 = OpShiftLeftLogical %v2uint %10064 %2151 + %15653 = OpBitwiseOr %v2uint %6361 %13638 + OpBranch %18834 + %12647 = OpLabel + %7311 = OpExtInst %v4float %1 FClamp %14921 %2938 %1285 + %20339 = OpVectorTimesScalar %v4float %7311 %float_15 + %11878 = OpFAdd %v4float %20339 %325 + %7639 = OpConvertFToU %v4uint %11878 + %8700 = OpCompositeExtract %uint %7639 0 + %12251 = OpCompositeExtract %uint %7639 1 + %11561 = OpShiftLeftLogical %uint %12251 %int_4 + %19814 = OpBitwiseOr %uint %8700 %11561 + %21476 = OpCompositeExtract %uint %7639 2 + %8560 = OpShiftLeftLogical %uint %21476 %int_8 + %19815 = OpBitwiseOr %uint %19814 %8560 + %21477 = OpCompositeExtract %uint %7639 3 + %7292 = OpShiftLeftLogical %uint %21477 %int_12 + %9255 = OpBitwiseOr %uint %19815 %7292 + %7522 = OpExtInst %v4float %1 FClamp %15191 %2938 %1285 + %8264 = OpVectorTimesScalar %v4float %7522 %float_15 + %11879 = OpFAdd %v4float %8264 %325 + %7642 = OpConvertFToU %v4uint %11879 + %8701 = OpCompositeExtract %uint %7642 0 + %12252 = OpCompositeExtract %uint %7642 1 + %11562 = OpShiftLeftLogical %uint %12252 %int_4 + %19816 = OpBitwiseOr %uint %8701 %11562 + %21478 = OpCompositeExtract %uint %7642 2 + %8561 = OpShiftLeftLogical %uint %21478 %int_8 + %19817 = OpBitwiseOr %uint %19816 %8561 + %21479 = OpCompositeExtract %uint %7642 3 + %10745 = OpShiftLeftLogical %uint %21479 %int_12 + %19009 = OpBitwiseOr %uint %19817 %10745 + %22729 = OpShiftLeftLogical %uint %19009 %uint_16 + %6254 = OpBitwiseOr %uint %9255 %22729 + %7523 = OpExtInst %v4float %1 FClamp %14358 %2938 %1285 + %8265 = OpVectorTimesScalar %v4float %7523 %float_15 + %11881 = OpFAdd %v4float %8265 %325 + %7643 = OpConvertFToU %v4uint %11881 + %8702 = OpCompositeExtract %uint %7643 0 + %12253 = OpCompositeExtract %uint %7643 1 + %11563 = OpShiftLeftLogical %uint %12253 %int_4 + %19818 = OpBitwiseOr %uint %8702 %11563 + %21480 = OpCompositeExtract %uint %7643 2 + %8562 = OpShiftLeftLogical %uint %21480 %int_8 + %19819 = OpBitwiseOr %uint %19818 %8562 + %21481 = OpCompositeExtract %uint %7643 3 + %7293 = OpShiftLeftLogical %uint %21481 %int_12 + %9256 = OpBitwiseOr %uint %19819 %7293 + %7524 = OpExtInst %v4float %1 FClamp %11189 %2938 %1285 + %8266 = OpVectorTimesScalar %v4float %7524 %float_15 + %11882 = OpFAdd %v4float %8266 %325 + %7644 = OpConvertFToU %v4uint %11882 + %8703 = OpCompositeExtract %uint %7644 0 + %12254 = OpCompositeExtract %uint %7644 1 + %11564 = OpShiftLeftLogical %uint %12254 %int_4 + %19820 = OpBitwiseOr %uint %8703 %11564 + %21482 = OpCompositeExtract %uint %7644 2 + %8563 = OpShiftLeftLogical %uint %21482 %int_8 + %19821 = OpBitwiseOr %uint %19820 %8563 + %21483 = OpCompositeExtract %uint %7644 3 + %10746 = OpShiftLeftLogical %uint %21483 %int_12 + %19010 = OpBitwiseOr %uint %19821 %10746 + %23978 = OpShiftLeftLogical %uint %19010 %uint_16 + %17993 = OpBitwiseOr %uint %9256 %23978 + %21469 = OpCompositeConstruct %v2uint %6254 %17993 + OpBranch %18834 + %7373 = OpLabel + %19885 = OpCompositeExtract %float %14921 0 + %10278 = OpCompositeExtract %float %14921 1 + %7645 = OpCompositeExtract %float %15191 0 + %6566 = OpCompositeExtract %float %15191 1 + %7480 = OpCompositeConstruct %v4float %19885 %10278 %7645 %6566 + %14407 = OpExtInst %v4float %1 FClamp %7480 %2938 %1285 + %13688 = OpVectorTimesScalar %v4float %14407 %float_255 + %11883 = OpFAdd %v4float %13688 %325 + %7646 = OpConvertFToU %v4uint %11883 + %8704 = OpCompositeExtract %uint %7646 0 + %12255 = OpCompositeExtract %uint %7646 1 + %11565 = OpShiftLeftLogical %uint %12255 %int_8 + %19822 = OpBitwiseOr %uint %8704 %11565 + %21484 = OpCompositeExtract %uint %7646 2 + %8564 = OpShiftLeftLogical %uint %21484 %int_16 + %19823 = OpBitwiseOr %uint %19822 %8564 + %21485 = OpCompositeExtract %uint %7646 3 + %8565 = OpShiftLeftLogical %uint %21485 %int_24 + %17629 = OpBitwiseOr %uint %19823 %8565 + %20096 = OpCompositeExtract %float %14358 0 + %23730 = OpCompositeExtract %float %14358 1 + %7647 = OpCompositeExtract %float %11189 0 + %6567 = OpCompositeExtract %float %11189 1 + %7481 = OpCompositeConstruct %v4float %20096 %23730 %7647 %6567 + %14408 = OpExtInst %v4float %1 FClamp %7481 %2938 %1285 + %13689 = OpVectorTimesScalar %v4float %14408 %float_255 + %11884 = OpFAdd %v4float %13689 %325 + %7648 = OpConvertFToU %v4uint %11884 + %8705 = OpCompositeExtract %uint %7648 0 + %12256 = OpCompositeExtract %uint %7648 1 + %11566 = OpShiftLeftLogical %uint %12256 %int_8 + %19824 = OpBitwiseOr %uint %8705 %11566 + %21486 = OpCompositeExtract %uint %7648 2 + %8566 = OpShiftLeftLogical %uint %21486 %int_16 + %19825 = OpBitwiseOr %uint %19824 %8566 + %21487 = OpCompositeExtract %uint %7648 3 + %8541 = OpShiftLeftLogical %uint %21487 %int_24 + %20994 = OpBitwiseOr %uint %19825 %8541 + %21470 = OpCompositeConstruct %v2uint %17629 %20994 + OpBranch %18834 + %6451 = OpLabel + %8655 = OpVectorShuffle %v3float %14921 %14921 0 1 2 + %6215 = OpExtInst %v3float %1 FClamp %8655 %2605 %2584 + %7105 = OpFMul %v3float %6215 %958 + %7962 = OpFAdd %v3float %7105 %939 + %10066 = OpConvertFToU %v3uint %7962 + %8706 = OpCompositeExtract %uint %10066 0 + %12257 = OpCompositeExtract %uint %10066 1 + %11567 = OpShiftLeftLogical %uint %12257 %int_5 + %19826 = OpBitwiseOr %uint %8706 %11567 + %21488 = OpCompositeExtract %uint %10066 2 + %8522 = OpShiftLeftLogical %uint %21488 %int_10 + %16707 = OpBitwiseOr %uint %19826 %8522 + %8866 = OpVectorShuffle %v3float %15191 %15191 0 1 2 + %19668 = OpExtInst %v3float %1 FClamp %8866 %2605 %2584 + %7106 = OpFMul %v3float %19668 %958 + %7963 = OpFAdd %v3float %7106 %939 + %10067 = OpConvertFToU %v3uint %7963 + %8707 = OpCompositeExtract %uint %10067 0 + %12258 = OpCompositeExtract %uint %10067 1 + %11568 = OpShiftLeftLogical %uint %12258 %int_5 + %19827 = OpBitwiseOr %uint %8707 %11568 + %21489 = OpCompositeExtract %uint %10067 2 + %10747 = OpShiftLeftLogical %uint %21489 %int_10 + %19011 = OpBitwiseOr %uint %19827 %10747 + %23959 = OpShiftLeftLogical %uint %19011 %uint_16 + %13706 = OpBitwiseOr %uint %16707 %23959 + %8867 = OpVectorShuffle %v3float %14358 %14358 0 1 2 + %19669 = OpExtInst %v3float %1 FClamp %8867 %2605 %2584 + %7107 = OpFMul %v3float %19669 %958 + %7964 = OpFAdd %v3float %7107 %939 + %10068 = OpConvertFToU %v3uint %7964 + %8708 = OpCompositeExtract %uint %10068 0 + %12259 = OpCompositeExtract %uint %10068 1 + %11569 = OpShiftLeftLogical %uint %12259 %int_5 + %19828 = OpBitwiseOr %uint %8708 %11569 + %21490 = OpCompositeExtract %uint %10068 2 + %8523 = OpShiftLeftLogical %uint %21490 %int_10 + %16708 = OpBitwiseOr %uint %19828 %8523 + %8868 = OpVectorShuffle %v3float %11189 %11189 0 1 2 + %19675 = OpExtInst %v3float %1 FClamp %8868 %2605 %2584 + %7108 = OpFMul %v3float %19675 %958 + %7965 = OpFAdd %v3float %7108 %939 + %10069 = OpConvertFToU %v3uint %7965 + %8709 = OpCompositeExtract %uint %10069 0 + %12260 = OpCompositeExtract %uint %10069 1 + %11570 = OpShiftLeftLogical %uint %12260 %int_5 + %19829 = OpBitwiseOr %uint %8709 %11570 + %21491 = OpCompositeExtract %uint %10069 2 + %10748 = OpShiftLeftLogical %uint %21491 %int_10 + %19012 = OpBitwiseOr %uint %19829 %10748 + %23979 = OpShiftLeftLogical %uint %19012 %uint_16 + %17994 = OpBitwiseOr %uint %16708 %23979 + %21471 = OpCompositeConstruct %v2uint %13706 %17994 + OpBranch %18834 + %6452 = OpLabel + %8656 = OpVectorShuffle %v3float %14921 %14921 0 1 2 + %6216 = OpExtInst %v3float %1 FClamp %8656 %2605 %2584 + %7109 = OpFMul %v3float %6216 %511 + %7966 = OpFAdd %v3float %7109 %939 + %10070 = OpConvertFToU %v3uint %7966 + %8710 = OpCompositeExtract %uint %10070 0 + %12261 = OpCompositeExtract %uint %10070 1 + %11571 = OpShiftLeftLogical %uint %12261 %int_5 + %19830 = OpBitwiseOr %uint %8710 %11571 + %21492 = OpCompositeExtract %uint %10070 2 + %8524 = OpShiftLeftLogical %uint %21492 %int_11 + %16709 = OpBitwiseOr %uint %19830 %8524 + %8869 = OpVectorShuffle %v3float %15191 %15191 0 1 2 + %19676 = OpExtInst %v3float %1 FClamp %8869 %2605 %2584 + %7110 = OpFMul %v3float %19676 %511 + %7967 = OpFAdd %v3float %7110 %939 + %10071 = OpConvertFToU %v3uint %7967 + %8711 = OpCompositeExtract %uint %10071 0 + %12262 = OpCompositeExtract %uint %10071 1 + %11572 = OpShiftLeftLogical %uint %12262 %int_5 + %19831 = OpBitwiseOr %uint %8711 %11572 + %21493 = OpCompositeExtract %uint %10071 2 + %10749 = OpShiftLeftLogical %uint %21493 %int_11 + %19013 = OpBitwiseOr %uint %19831 %10749 + %23960 = OpShiftLeftLogical %uint %19013 %uint_16 + %13707 = OpBitwiseOr %uint %16709 %23960 + %8870 = OpVectorShuffle %v3float %14358 %14358 0 1 2 + %19677 = OpExtInst %v3float %1 FClamp %8870 %2605 %2584 + %7111 = OpFMul %v3float %19677 %511 + %7968 = OpFAdd %v3float %7111 %939 + %10072 = OpConvertFToU %v3uint %7968 + %8712 = OpCompositeExtract %uint %10072 0 + %12263 = OpCompositeExtract %uint %10072 1 + %11573 = OpShiftLeftLogical %uint %12263 %int_5 + %19832 = OpBitwiseOr %uint %8712 %11573 + %21494 = OpCompositeExtract %uint %10072 2 + %8525 = OpShiftLeftLogical %uint %21494 %int_11 + %16710 = OpBitwiseOr %uint %19832 %8525 + %8872 = OpVectorShuffle %v3float %11189 %11189 0 1 2 + %19678 = OpExtInst %v3float %1 FClamp %8872 %2605 %2584 + %7112 = OpFMul %v3float %19678 %511 + %7969 = OpFAdd %v3float %7112 %939 + %10073 = OpConvertFToU %v3uint %7969 + %8713 = OpCompositeExtract %uint %10073 0 + %12264 = OpCompositeExtract %uint %10073 1 + %11574 = OpShiftLeftLogical %uint %12264 %int_5 + %19833 = OpBitwiseOr %uint %8713 %11574 + %21495 = OpCompositeExtract %uint %10073 2 + %10750 = OpShiftLeftLogical %uint %21495 %int_11 + %19014 = OpBitwiseOr %uint %19833 %10750 + %23980 = OpShiftLeftLogical %uint %19014 %uint_16 + %17995 = OpBitwiseOr %uint %16710 %23980 + %21472 = OpCompositeConstruct %v2uint %13707 %17995 + OpBranch %18834 + %17899 = OpLabel + %8873 = OpExtInst %v4float %1 FClamp %14921 %2938 %1285 + %17792 = OpFMul %v4float %8873 %2057 + %7970 = OpFAdd %v4float %17792 %325 + %10074 = OpConvertFToU %v4uint %7970 + %8714 = OpCompositeExtract %uint %10074 0 + %12265 = OpCompositeExtract %uint %10074 1 + %11575 = OpShiftLeftLogical %uint %12265 %int_5 + %19834 = OpBitwiseOr %uint %8714 %11575 + %21496 = OpCompositeExtract %uint %10074 2 + %8567 = OpShiftLeftLogical %uint %21496 %int_10 + %19835 = OpBitwiseOr %uint %19834 %8567 + %21497 = OpCompositeExtract %uint %10074 3 + %7294 = OpShiftLeftLogical %uint %21497 %int_15 + %9084 = OpBitwiseOr %uint %19835 %7294 + %9079 = OpExtInst %v4float %1 FClamp %15191 %2938 %1285 + %24798 = OpFMul %v4float %9079 %2057 + %7971 = OpFAdd %v4float %24798 %325 + %10075 = OpConvertFToU %v4uint %7971 + %8715 = OpCompositeExtract %uint %10075 0 + %12266 = OpCompositeExtract %uint %10075 1 + %11576 = OpShiftLeftLogical %uint %12266 %int_5 + %19836 = OpBitwiseOr %uint %8715 %11576 + %21498 = OpCompositeExtract %uint %10075 2 + %8568 = OpShiftLeftLogical %uint %21498 %int_10 + %19837 = OpBitwiseOr %uint %19836 %8568 + %21499 = OpCompositeExtract %uint %10075 3 + %10751 = OpShiftLeftLogical %uint %21499 %int_15 + %19015 = OpBitwiseOr %uint %19837 %10751 + %22730 = OpShiftLeftLogical %uint %19015 %uint_16 + %25154 = OpBitwiseOr %uint %9084 %22730 + %9080 = OpExtInst %v4float %1 FClamp %14358 %2938 %1285 + %24799 = OpFMul %v4float %9080 %2057 + %7972 = OpFAdd %v4float %24799 %325 + %10076 = OpConvertFToU %v4uint %7972 + %8716 = OpCompositeExtract %uint %10076 0 + %12267 = OpCompositeExtract %uint %10076 1 + %11577 = OpShiftLeftLogical %uint %12267 %int_5 + %19838 = OpBitwiseOr %uint %8716 %11577 + %21500 = OpCompositeExtract %uint %10076 2 + %8569 = OpShiftLeftLogical %uint %21500 %int_10 + %19839 = OpBitwiseOr %uint %19838 %8569 + %21501 = OpCompositeExtract %uint %10076 3 + %7295 = OpShiftLeftLogical %uint %21501 %int_15 + %9085 = OpBitwiseOr %uint %19839 %7295 + %9081 = OpExtInst %v4float %1 FClamp %11189 %2938 %1285 + %24800 = OpFMul %v4float %9081 %2057 + %7973 = OpFAdd %v4float %24800 %325 + %10077 = OpConvertFToU %v4uint %7973 + %8717 = OpCompositeExtract %uint %10077 0 + %12268 = OpCompositeExtract %uint %10077 1 + %11578 = OpShiftLeftLogical %uint %12268 %int_5 + %19840 = OpBitwiseOr %uint %8717 %11578 + %21502 = OpCompositeExtract %uint %10077 2 + %8570 = OpShiftLeftLogical %uint %21502 %int_10 + %19841 = OpBitwiseOr %uint %19840 %8570 + %21503 = OpCompositeExtract %uint %10077 3 + %10752 = OpShiftLeftLogical %uint %21503 %int_15 + %19016 = OpBitwiseOr %uint %19841 %10752 + %23981 = OpShiftLeftLogical %uint %19016 %uint_16 + %17996 = OpBitwiseOr %uint %9085 %23981 + %21473 = OpCompositeConstruct %v2uint %25154 %17996 + OpBranch %18834 + %7374 = OpLabel + %19866 = OpCompositeExtract %float %14921 0 + %9197 = OpCompositeExtract %float %15191 0 + %19232 = OpCompositeConstruct %v2float %19866 %9197 + %8571 = OpExtInst %uint %1 PackHalf2x16 %19232 + %23487 = OpCompositeExtract %float %14358 0 + %14759 = OpCompositeExtract %float %11189 0 + %19213 = OpCompositeConstruct %v2float %23487 %14759 + %11926 = OpExtInst %uint %1 PackHalf2x16 %19213 + %24879 = OpCompositeConstruct %v2uint %8571 %11926 + OpBranch %18834 + %18834 = OpLabel + %22706 = OpPhi %v2uint %24879 %7374 %21473 %17899 %21472 %6452 %21471 %6451 %21470 %7373 %21469 %12647 %15653 %9492 + %19119 = OpIEqual %bool %7640 %uint_0 + %22246 = OpSelect %bool %19119 %false %19119 + OpSelectionMerge %19649 DontFlatten + OpBranchConditional %22246 %11888 %19649 + %11888 = OpLabel + %19227 = OpCompositeExtract %uint %22706 0 + %13351 = OpShiftRightLogical %uint %19227 %uint_16 + %7220 = OpBitwiseAnd %uint %19227 %uint_4294901760 + %17709 = OpBitwiseOr %uint %13351 %7220 + %23346 = OpCompositeInsert %v2uint %17709 %22706 0 + OpBranch %19649 + %19649 = OpLabel + %12383 = OpPhi %v2uint %22706 %18834 %23346 %11888 + %12967 = OpIAdd %v2uint %12025 %23020 + OpSelectionMerge %21237 DontFlatten + OpBranchConditional %20495 %10574 %21373 + %21373 = OpLabel + %10608 = OpBitcast %v2int %12967 + %17090 = OpCompositeExtract %int %10608 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %10608 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %15783 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_8 + %10955 = OpBitwiseAnd %int %17090 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17303 = OpIAdd %int %10955 %17741 + %6375 = OpShiftLeftLogical %int %17303 %uint_1 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15435 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18365 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18365 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12151 + %19171 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19171 %int_2 + %16711 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21588 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21588 %int_6 + %15436 = OpIAdd %int %16711 %21580 + %11782 = OpBitwiseAnd %int %16727 %int_63 + %14671 = OpIAdd %int %15436 %11782 + %22127 = OpBitcast %uint %14671 + OpBranch %21237 + %10574 = OpLabel + %19867 = OpCompositeExtract %uint %12967 0 + %11267 = OpCompositeExtract %uint %12967 1 + %8414 = OpCompositeConstruct %v3uint %19867 %11267 %24434 + %20125 = OpBitcast %v3int %8414 + %10438 = OpCompositeExtract %int %20125 1 + %9470 = OpShiftRightArithmetic %int %10438 %int_4 + %10056 = OpCompositeExtract %int %20125 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %25203 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %15783 %uint_5 + %12439 = OpBitcast %int %9032 + %10367 = OpIMul %int %15143 %12439 + %25155 = OpCompositeExtract %int %20125 0 + %20423 = OpShiftRightArithmetic %int %25155 %int_5 + %18940 = OpIAdd %int %20423 %10367 + %8797 = OpShiftLeftLogical %int %18940 %uint_7 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25155 %int_7 + %12601 = OpBitwiseAnd %int %10438 %int_6 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7051 = OpShiftLeftLogical %int %17227 %uint_7 + %24035 = OpShiftRightArithmetic %int %7051 %int_6 + %8736 = OpShiftRightArithmetic %int %10438 %int_3 + %13731 = OpIAdd %int %8736 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25155 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19172 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19172 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23347 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23347 %23274 + %18366 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18366 %uint_7 + %16729 = OpIAdd %int %10332 %21582 + %19173 = OpBitwiseAnd %int %10438 %int_1 + %21583 = OpShiftLeftLogical %int %19173 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23348 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10956 = OpIAdd %int %23348 %23217 + %23349 = OpShiftLeftLogical %int %10956 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10957 = OpIAdd %int %23349 %23218 + %23350 = OpShiftLeftLogical %int %10957 %int_3 + %21849 = OpBitwiseAnd %int %16730 %int_63 + %24314 = OpIAdd %int %23350 %21849 + %22128 = OpBitcast %uint %24314 + OpBranch %21237 + %21237 = OpLabel + %11376 = OpPhi %uint %22128 %10574 %22127 %21373 + %20616 = OpIAdd %uint %11376 %25270 + %20138 = OpShiftRightLogical %uint %20616 %uint_3 + %19356 = OpIEqual %bool %19164 %uint_1 + OpSelectionMerge %11416 None + OpBranchConditional %19356 %10583 %11416 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v2uint %12383 %2326 + %9425 = OpShiftLeftLogical %v2uint %18271 %1975 + %20652 = OpBitwiseAnd %v2uint %12383 %2888 + %17549 = OpShiftRightLogical %v2uint %20652 %1975 + %16377 = OpBitwiseOr %v2uint %9425 %17549 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v2uint %12383 %21237 %16377 %10583 + %8054 = OpAccessChain %_ptr_Uniform_v2uint %5522 %int_0 %20138 + OpStore %8054 %19767 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_full_16bpp_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000062B7, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00040047, 0x000007D0, 0x00000006, 0x00000004, + 0x00030047, 0x0000079C, 0x00000003, 0x00040048, 0x0000079C, 0x00000000, 0x00000018, 0x00050048, + 0x0000079C, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000CC7, 0x00000018, 0x00040047, + 0x00000CC7, 0x00000021, 0x00000000, 0x00040047, 0x00000CC7, 0x00000022, 0x00000000, 0x00030047, + 0x0000040C, 0x00000002, 0x00050048, 0x0000040C, 0x00000000, 0x00000023, 0x00000000, 0x00050048, + 0x0000040C, 0x00000001, 0x00000023, 0x00000004, 0x00050048, 0x0000040C, 0x00000002, 0x00000023, + 0x00000008, 0x00050048, 0x0000040C, 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x0000040C, + 0x00000004, 0x00000023, 0x00000010, 0x00040047, 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, + 0x000007D6, 0x00000006, 0x00000008, 0x00030047, 0x000007A8, 0x00000003, 0x00040048, 0x000007A8, + 0x00000000, 0x00000019, 0x00050048, 0x000007A8, 0x00000000, 0x00000023, 0x00000000, 0x00030047, + 0x00001592, 0x00000019, 0x00040047, 0x00001592, 0x00000021, 0x00000000, 0x00040047, 0x00001592, + 0x00000022, 0x00000001, 0x00040047, 0x00000AC9, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, + 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, + 0x00000012, 0x0000000C, 0x00000002, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, + 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x00040017, + 0x00000017, 0x0000000B, 0x00000004, 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x00000013, + 0x0000000D, 0x00000002, 0x00040017, 0x00000018, 0x0000000D, 0x00000003, 0x00040017, 0x0000001D, + 0x0000000D, 0x00000004, 0x00020014, 0x00000009, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, + 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, 0x0004002B, 0x0000000D, 0x0000008A, 0x3F800000, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000D, 0x000005B1, 0x41F80000, 0x0007002C, 0x0000001D, 0x00000809, 0x000005B1, + 0x000005B1, 0x000005B1, 0x0000008A, 0x0004002B, 0x0000000D, 0x000000FC, 0x3F000000, 0x0004002B, + 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, + 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000C, 0x00000A29, 0x0000000A, 0x0004002B, + 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, + 0x0000000D, 0x00000770, 0x427C0000, 0x0006002C, 0x00000018, 0x000001FF, 0x000005B1, 0x00000770, + 0x000005B1, 0x0004002B, 0x0000000C, 0x00000A2C, 0x0000000B, 0x0006002C, 0x00000018, 0x000003BE, + 0x000005B1, 0x000005B1, 0x00000770, 0x0004002B, 0x0000000D, 0x00000540, 0x437F0000, 0x0004002B, + 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, + 0x0000000C, 0x00000A53, 0x00000018, 0x0004002B, 0x0000000D, 0x000001C1, 0x41700000, 0x0004002B, + 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x00000A2F, 0x0000000C, 0x0004002B, + 0x0000000D, 0x0000022D, 0x477FFF00, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, + 0x0000000B, 0x00000A52, 0x00000018, 0x0007002C, 0x00000017, 0x0000028D, 0x00000A0A, 0x00000A22, + 0x00000A3A, 0x00000A52, 0x0004002B, 0x0000000B, 0x00000144, 0x000000FF, 0x0004002B, 0x0000000D, + 0x0000017A, 0x3B808081, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, + 0x00000A46, 0x00000014, 0x0004002B, 0x0000000B, 0x00000A64, 0x0000001E, 0x0007002C, 0x00000017, + 0x0000034D, 0x00000A0A, 0x00000A28, 0x00000A46, 0x00000A64, 0x0004002B, 0x0000000B, 0x00000A44, + 0x000003FF, 0x0007002C, 0x00000017, 0x0000027B, 0x00000A44, 0x00000A44, 0x00000A44, 0x00000A13, + 0x0004002B, 0x0000000D, 0x000006FE, 0x3A802008, 0x0004002B, 0x0000000D, 0x00000149, 0x3EAAAAAB, + 0x0007002C, 0x0000001D, 0x00000AEE, 0x000006FE, 0x000006FE, 0x000006FE, 0x00000149, 0x0006002C, + 0x00000014, 0x00000BB4, 0x00000A0A, 0x00000A28, 0x00000A46, 0x0004002B, 0x0000000B, 0x00000B87, + 0x0000007F, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x00040017, 0x00000010, 0x00000009, + 0x00000003, 0x0004002B, 0x0000000B, 0x00000B7E, 0x0000007C, 0x0004002B, 0x0000000B, 0x00000A4F, + 0x00000017, 0x0004002B, 0x0000000D, 0x00000341, 0xBF800000, 0x0004002B, 0x0000000C, 0x00000A0B, + 0x00000000, 0x0005002C, 0x00000012, 0x000007A7, 0x00000A3B, 0x00000A0B, 0x0004002B, 0x0000000D, + 0x000007FE, 0x3A800100, 0x00040017, 0x0000001A, 0x0000000C, 0x00000004, 0x0007002C, 0x0000001A, + 0x00000122, 0x00000A3B, 0x00000A0B, 0x00000A3B, 0x00000A0B, 0x0005002C, 0x00000011, 0x0000072D, + 0x00000A10, 0x00000A0D, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0005002C, 0x00000011, + 0x0000070F, 0x00000A0A, 0x00000A0A, 0x0005002C, 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, + 0x0005002C, 0x00000011, 0x00000718, 0x00000A0D, 0x00000A0A, 0x0004002B, 0x0000000B, 0x00000AFA, + 0x00000050, 0x0005002C, 0x00000011, 0x00000A9F, 0x00000AFA, 0x00000A3A, 0x0004002B, 0x0000000B, + 0x00000A19, 0x00000005, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, + 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, + 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, + 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, + 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, + 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000B, + 0x00000A1C, 0x00000006, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, + 0x00000A05, 0xFFFFFFFE, 0x0003001D, 0x000007D0, 0x0000000B, 0x0003001E, 0x0000079C, 0x000007D0, + 0x00040020, 0x00000A1B, 0x00000002, 0x0000079C, 0x0004003B, 0x00000A1B, 0x00000CC7, 0x00000002, + 0x00040020, 0x00000288, 0x00000002, 0x0000000B, 0x0007001E, 0x0000040C, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000688, 0x00000009, 0x0000040C, 0x0004003B, + 0x00000688, 0x00000CE9, 0x00000009, 0x00040020, 0x00000289, 0x00000009, 0x0000000B, 0x0004002B, + 0x0000000B, 0x00000A31, 0x0000000D, 0x0004002B, 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, + 0x0000000B, 0x00000A37, 0x0000000F, 0x0004002B, 0x0000000B, 0x00000A5E, 0x0000001C, 0x0005002C, + 0x00000011, 0x0000073F, 0x00000A0A, 0x00000A16, 0x0004002B, 0x0000000B, 0x00000AC7, 0x0000003F, + 0x0004002B, 0x0000000C, 0x00000A59, 0x0000001A, 0x0004002B, 0x0000000C, 0x00000A50, 0x00000017, + 0x0004002B, 0x0000000B, 0x00000926, 0x01000000, 0x0005002C, 0x00000011, 0x000008E3, 0x00000A46, + 0x00000A52, 0x0003002A, 0x00000009, 0x00000787, 0x00040020, 0x00000291, 0x00000001, 0x00000014, + 0x0004003B, 0x00000291, 0x00000F48, 0x00000001, 0x0005002C, 0x00000011, 0x00000721, 0x00000A10, + 0x00000A0A, 0x0004002B, 0x0000000B, 0x0000068D, 0xFFFF0000, 0x0003001D, 0x000007D6, 0x00000011, + 0x0003001E, 0x000007A8, 0x000007D6, 0x00040020, 0x00000A25, 0x00000002, 0x000007A8, 0x0004003B, + 0x00000A25, 0x00001592, 0x00000002, 0x00040020, 0x0000028E, 0x00000002, 0x00000011, 0x0006002C, + 0x00000014, 0x00000AC9, 0x00000A22, 0x00000A22, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, + 0x00000A37, 0x00000A0D, 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, 0x0005002C, + 0x00000011, 0x0000084A, 0x00000A37, 0x00000A37, 0x0007002C, 0x0000001D, 0x00000504, 0x00000341, + 0x00000341, 0x00000341, 0x00000341, 0x0007002C, 0x0000001A, 0x00000302, 0x00000A3B, 0x00000A3B, + 0x00000A3B, 0x00000A3B, 0x0007002C, 0x00000017, 0x0000064B, 0x00000144, 0x00000144, 0x00000144, + 0x00000144, 0x0006002C, 0x00000014, 0x00000105, 0x00000A44, 0x00000A44, 0x00000A44, 0x0006002C, + 0x00000014, 0x00000466, 0x00000B87, 0x00000B87, 0x00000B87, 0x0006002C, 0x00000014, 0x00000B0C, + 0x00000A1F, 0x00000A1F, 0x00000A1F, 0x0006002C, 0x00000014, 0x00000A12, 0x00000A0A, 0x00000A0A, + 0x00000A0A, 0x0006002C, 0x00000014, 0x000003FA, 0x00000B7E, 0x00000B7E, 0x00000B7E, 0x0006002C, + 0x00000014, 0x00000189, 0x00000A4F, 0x00000A4F, 0x00000A4F, 0x0006002C, 0x00000014, 0x0000008D, + 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000013, 0x00000049, 0x00000341, 0x00000341, + 0x0005002C, 0x00000012, 0x00000867, 0x00000A3B, 0x00000A3B, 0x0007002C, 0x0000001D, 0x00000B7A, + 0x00000A0C, 0x00000A0C, 0x00000A0C, 0x00000A0C, 0x0007002C, 0x0000001D, 0x00000505, 0x0000008A, + 0x0000008A, 0x0000008A, 0x0000008A, 0x0007002C, 0x0000001D, 0x00000145, 0x000000FC, 0x000000FC, + 0x000000FC, 0x000000FC, 0x0006002C, 0x00000018, 0x00000A2D, 0x00000A0C, 0x00000A0C, 0x00000A0C, + 0x0006002C, 0x00000018, 0x00000A18, 0x0000008A, 0x0000008A, 0x0000008A, 0x0006002C, 0x00000018, + 0x000003AB, 0x000000FC, 0x000000FC, 0x000000FC, 0x0005002C, 0x00000011, 0x00000916, 0x000008A6, + 0x000008A6, 0x0005002C, 0x00000011, 0x000007B7, 0x00000A22, 0x00000A22, 0x0005002C, 0x00000011, + 0x00000B48, 0x000005FD, 0x000005FD, 0x0004002B, 0x0000000C, 0x00000089, 0x3F800000, 0x0004002B, + 0x0000000B, 0x00000184, 0x00000500, 0x0004002B, 0x0000000B, 0x0000086E, 0x00280000, 0x0004002B, + 0x0000000B, 0x000009F8, 0xFFFFFFFA, 0x0006002C, 0x00000014, 0x00000938, 0x000009F8, 0x000009F8, + 0x000009F8, 0x0004002B, 0x0000000B, 0x00000AFD, 0x00000051, 0x0004002B, 0x0000000B, 0x00000B00, + 0x00000052, 0x0004002B, 0x0000000B, 0x00000B03, 0x00000053, 0x0004002B, 0x0000000B, 0x00000B06, + 0x00000054, 0x0004002B, 0x0000000B, 0x00000B09, 0x00000055, 0x0004002B, 0x0000000B, 0x00000B0D, + 0x00000056, 0x0004002B, 0x0000000B, 0x00000B0F, 0x00000057, 0x0004002B, 0x0000000D, 0x0000016E, + 0x3E800000, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, + 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, + 0x00050041, 0x00000289, 0x000056E5, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003D0B, + 0x000056E5, 0x00050041, 0x00000289, 0x000058AC, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, + 0x00005158, 0x000058AC, 0x000500C7, 0x0000000B, 0x00005051, 0x00003D0B, 0x00000A44, 0x000500C2, + 0x0000000B, 0x00004E0A, 0x00003D0B, 0x00000A28, 0x000500C7, 0x0000000B, 0x0000217E, 0x00004E0A, + 0x00000A13, 0x000500C2, 0x0000000B, 0x0000520A, 0x00003D0B, 0x00000A31, 0x000500C7, 0x0000000B, + 0x0000217F, 0x0000520A, 0x00000A81, 0x000500C2, 0x0000000B, 0x0000520B, 0x00003D0B, 0x00000A52, + 0x000500C7, 0x0000000B, 0x00002180, 0x0000520B, 0x00000A37, 0x000500C2, 0x0000000B, 0x00004994, + 0x00003D0B, 0x00000A5E, 0x000500C7, 0x0000000B, 0x000023AA, 0x00004994, 0x00000A0D, 0x00050050, + 0x00000011, 0x000022A7, 0x00005158, 0x00005158, 0x000500C2, 0x00000011, 0x00002568, 0x000022A7, + 0x0000073F, 0x000500C7, 0x00000011, 0x00005B53, 0x00002568, 0x000007A2, 0x000500C4, 0x00000011, + 0x00003F4F, 0x00005B53, 0x0000074E, 0x00050084, 0x00000011, 0x000059EB, 0x00003F4F, 0x00000724, + 0x000500C2, 0x0000000B, 0x00003213, 0x00005158, 0x00000A19, 0x000500C7, 0x0000000B, 0x00003F4C, + 0x00003213, 0x00000A81, 0x00050041, 0x00000289, 0x0000492C, 0x00000CE9, 0x00000A11, 0x0004003D, + 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000289, 0x000058AD, 0x00000CE9, 0x00000A14, + 0x0004003D, 0x0000000B, 0x000051B7, 0x000058AD, 0x000500C7, 0x0000000B, 0x00004ADC, 0x00005EAC, + 0x00000A1F, 0x000500C7, 0x0000000B, 0x000055EF, 0x00005EAC, 0x00000A22, 0x000500AB, 0x00000009, + 0x0000500F, 0x000055EF, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00002843, 0x00005EAC, 0x00000A16, + 0x000500C7, 0x0000000B, 0x00005F72, 0x00002843, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00004CD8, + 0x00005EAC, 0x00000A1F, 0x000500C7, 0x0000000B, 0x00005093, 0x00004CD8, 0x00000AC7, 0x0004007C, + 0x0000000C, 0x00005988, 0x00005EAC, 0x000500C4, 0x0000000C, 0x0000358F, 0x00005988, 0x00000A29, + 0x000500C3, 0x0000000C, 0x0000509C, 0x0000358F, 0x00000A59, 0x000500C4, 0x0000000C, 0x00004702, + 0x0000509C, 0x00000A50, 0x00050080, 0x0000000C, 0x00001D26, 0x00004702, 0x00000089, 0x0004007C, + 0x0000000D, 0x00002B2C, 0x00001D26, 0x000500C7, 0x0000000B, 0x00005879, 0x00005EAC, 0x00000926, + 0x000500AB, 0x00000009, 0x00001D59, 0x00005879, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00001F43, + 0x000051B7, 0x00000A44, 0x000500C4, 0x0000000B, 0x00003DA7, 0x00001F43, 0x00000A19, 0x000500C2, + 0x0000000B, 0x0000583F, 0x000051B7, 0x00000A28, 0x000500C7, 0x0000000B, 0x00004BBE, 0x0000583F, + 0x00000A44, 0x000500C4, 0x0000000B, 0x00006273, 0x00004BBE, 0x00000A19, 0x00050050, 0x00000011, + 0x000028B6, 0x000051B7, 0x000051B7, 0x000500C2, 0x00000011, 0x00002891, 0x000028B6, 0x000008E3, + 0x000500C7, 0x00000011, 0x00005B54, 0x00002891, 0x0000084A, 0x000500C4, 0x00000011, 0x00003F50, + 0x00005B54, 0x0000074E, 0x00050084, 0x00000011, 0x000059EC, 0x00003F50, 0x00000724, 0x000500C2, + 0x0000000B, 0x00003214, 0x000051B7, 0x00000A5E, 0x000500C7, 0x0000000B, 0x00003F4D, 0x00003214, + 0x00000A1F, 0x00050041, 0x00000289, 0x000048E0, 0x00000CE9, 0x00000A17, 0x0004003D, 0x0000000B, + 0x000062B6, 0x000048E0, 0x0004003D, 0x00000014, 0x0000374F, 0x00000F48, 0x0007004F, 0x00000011, + 0x00003180, 0x0000374F, 0x0000374F, 0x00000000, 0x00000001, 0x000500C4, 0x00000011, 0x00002EF9, + 0x00003180, 0x00000721, 0x00050051, 0x0000000B, 0x00001DD8, 0x00002EF9, 0x00000000, 0x000500C4, + 0x0000000B, 0x00002D8A, 0x00003F4C, 0x00000A13, 0x000500AE, 0x00000009, 0x00003C13, 0x00001DD8, + 0x00002D8A, 0x000300F7, 0x000031D3, 0x00000002, 0x000400FA, 0x00003C13, 0x000055E8, 0x000031D3, + 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000031D3, 0x00050051, 0x0000000B, + 0x00001CAC, 0x00002EF9, 0x00000001, 0x0007000C, 0x0000000B, 0x00001F38, 0x00000001, 0x00000029, + 0x00001CAC, 0x00000A0A, 0x00050050, 0x00000011, 0x000051EF, 0x00001DD8, 0x00001F38, 0x00050080, + 0x00000011, 0x0000522C, 0x000051EF, 0x000059EB, 0x000500B2, 0x00000009, 0x00003ECB, 0x00003F4D, + 0x00000A13, 0x000300F7, 0x00005CE0, 0x00000000, 0x000400FA, 0x00003ECB, 0x00002AEE, 0x00003AEF, + 0x000200F8, 0x00003AEF, 0x000500AA, 0x00000009, 0x000034FE, 0x00003F4D, 0x00000A19, 0x000600A9, + 0x0000000B, 0x000020F6, 0x000034FE, 0x00000A10, 0x00000A0A, 0x000200F9, 0x00005CE0, 0x000200F8, + 0x00002AEE, 0x000200F9, 0x00005CE0, 0x000200F8, 0x00005CE0, 0x000700F5, 0x0000000B, 0x00004B64, + 0x00003F4D, 0x00002AEE, 0x000020F6, 0x00003AEF, 0x00050050, 0x00000011, 0x000041BE, 0x0000217E, + 0x0000217E, 0x000500AE, 0x0000000F, 0x00002E19, 0x000041BE, 0x0000072D, 0x000600A9, 0x00000011, + 0x00004BB5, 0x00002E19, 0x00000724, 0x0000070F, 0x000500C4, 0x00000011, 0x00002AEA, 0x0000522C, + 0x00004BB5, 0x00050050, 0x00000011, 0x0000605D, 0x00004B64, 0x00004B64, 0x000500C2, 0x00000011, + 0x00002385, 0x0000605D, 0x00000718, 0x000500C7, 0x00000011, 0x00003AEC, 0x00002385, 0x00000724, + 0x00050080, 0x00000011, 0x000027D5, 0x00002AEA, 0x00003AEC, 0x00050050, 0x00000011, 0x00002164, + 0x000023AA, 0x00000A0A, 0x000500C2, 0x00000011, 0x0000264A, 0x00000A9F, 0x00002164, 0x00050086, + 0x00000011, 0x000027A2, 0x000027D5, 0x0000264A, 0x00050051, 0x0000000B, 0x00004FA6, 0x000027A2, + 0x00000001, 0x00050084, 0x0000000B, 0x00002B26, 0x00004FA6, 0x00005051, 0x00050051, 0x0000000B, + 0x00006059, 0x000027A2, 0x00000000, 0x00050080, 0x0000000B, 0x00005420, 0x00002B26, 0x00006059, + 0x00050080, 0x0000000B, 0x00002226, 0x0000217F, 0x00005420, 0x00050084, 0x00000011, 0x00005B31, + 0x000027A2, 0x0000264A, 0x00050082, 0x00000011, 0x00002E74, 0x000027D5, 0x00005B31, 0x00050084, + 0x0000000B, 0x00001F75, 0x00002226, 0x00000184, 0x00050051, 0x0000000B, 0x00005EC7, 0x00002E74, + 0x00000001, 0x00050051, 0x0000000B, 0x00005BE6, 0x0000264A, 0x00000000, 0x00050084, 0x0000000B, + 0x00005966, 0x00005EC7, 0x00005BE6, 0x00050051, 0x0000000B, 0x00001AE6, 0x00002E74, 0x00000000, + 0x00050080, 0x0000000B, 0x000025E0, 0x00005966, 0x00001AE6, 0x000500C4, 0x0000000B, 0x000046C4, + 0x000025E0, 0x000023AA, 0x00050080, 0x0000000B, 0x00004719, 0x00001F75, 0x000046C4, 0x00050089, + 0x0000000B, 0x00005AD8, 0x00004719, 0x0000086E, 0x000500AE, 0x00000009, 0x00003361, 0x0000217E, + 0x00000A10, 0x000600A9, 0x0000000B, 0x0000609F, 0x00003361, 0x00000A0D, 0x00000A0A, 0x00050080, + 0x0000000B, 0x00004E6A, 0x000023AA, 0x0000609F, 0x000500C4, 0x0000000B, 0x0000199B, 0x00000A0D, + 0x00004E6A, 0x000500AB, 0x00000009, 0x00005AEF, 0x000023AA, 0x00000A0A, 0x000300F7, 0x0000530F, + 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B65, 0x000040B9, 0x000200F8, 0x000040B9, 0x000500AA, + 0x00000009, 0x00004ADA, 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F49, 0x00000002, 0x000400FA, + 0x00004ADA, 0x00002621, 0x00002F61, 0x000200F8, 0x00002F61, 0x00060041, 0x00000288, 0x00004BCF, + 0x00000CC7, 0x00000A0B, 0x00005AD8, 0x0004003D, 0x0000000B, 0x00005D43, 0x00004BCF, 0x00050080, + 0x0000000B, 0x00002DA7, 0x00005AD8, 0x0000199B, 0x00060041, 0x00000288, 0x0000194B, 0x00000CC7, + 0x00000A0B, 0x00002DA7, 0x0004003D, 0x0000000B, 0x00005E5B, 0x0000194B, 0x00050084, 0x0000000B, + 0x0000185A, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A1, 0x00005AD8, 0x0000185A, + 0x00060041, 0x00000288, 0x00003BCD, 0x00000CC7, 0x00000A0B, 0x000020A1, 0x0004003D, 0x0000000B, + 0x00005E5C, 0x00003BCD, 0x00050084, 0x0000000B, 0x0000185B, 0x00000A13, 0x0000199B, 0x00050080, + 0x0000000B, 0x000020A2, 0x00005AD8, 0x0000185B, 0x00060041, 0x00000288, 0x000037F1, 0x00000CC7, + 0x00000A0B, 0x000020A2, 0x0004003D, 0x0000000B, 0x00003FFB, 0x000037F1, 0x00070050, 0x00000017, + 0x0000512C, 0x00005D43, 0x00005E5B, 0x00005E5C, 0x00003FFB, 0x000200F9, 0x00004F49, 0x000200F8, + 0x00002621, 0x00060041, 0x00000288, 0x00005545, 0x00000CC7, 0x00000A0B, 0x00005AD8, 0x0004003D, + 0x0000000B, 0x00005D44, 0x00005545, 0x00050080, 0x0000000B, 0x00002DA8, 0x00005AD8, 0x00000A0D, + 0x00060041, 0x00000288, 0x000018FF, 0x00000CC7, 0x00000A0B, 0x00002DA8, 0x0004003D, 0x0000000B, + 0x00005C62, 0x000018FF, 0x00050080, 0x0000000B, 0x00002DA9, 0x00005AD8, 0x00000A10, 0x00060041, + 0x00000288, 0x00001900, 0x00000CC7, 0x00000A0B, 0x00002DA9, 0x0004003D, 0x0000000B, 0x00005C63, + 0x00001900, 0x00050080, 0x0000000B, 0x00002DAA, 0x00005AD8, 0x00000A13, 0x00060041, 0x00000288, + 0x00005FEE, 0x00000CC7, 0x00000A0B, 0x00002DAA, 0x0004003D, 0x0000000B, 0x00003FFC, 0x00005FEE, + 0x00070050, 0x00000017, 0x0000512D, 0x00005D44, 0x00005C62, 0x00005C63, 0x00003FFC, 0x000200F9, + 0x00004F49, 0x000200F8, 0x00004F49, 0x000700F5, 0x00000017, 0x00002ABF, 0x0000512D, 0x00002621, + 0x0000512C, 0x00002F61, 0x000300F7, 0x00003F60, 0x00000000, 0x001300FB, 0x00002180, 0x00004BFB, + 0x00000000, 0x000038F9, 0x00000001, 0x000038F9, 0x00000002, 0x00001CBB, 0x0000000A, 0x00001CBB, + 0x00000003, 0x00001CBA, 0x0000000C, 0x00001CBA, 0x00000004, 0x00001FFE, 0x00000006, 0x00002033, + 0x000200F8, 0x00002033, 0x00050051, 0x0000000B, 0x00005F56, 0x00002ABF, 0x00000000, 0x0006000C, + 0x00000013, 0x00006067, 0x00000001, 0x0000003E, 0x00005F56, 0x00050051, 0x0000000D, 0x00002762, + 0x00006067, 0x00000000, 0x00050051, 0x0000000D, 0x00004446, 0x00006067, 0x00000001, 0x00070050, + 0x0000001D, 0x0000390C, 0x00002762, 0x00004446, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x0000437A, 0x00002ABF, 0x00000001, 0x0006000C, 0x00000013, 0x0000466B, 0x00000001, 0x0000003E, + 0x0000437A, 0x00050051, 0x0000000D, 0x00002763, 0x0000466B, 0x00000000, 0x00050051, 0x0000000D, + 0x00004447, 0x0000466B, 0x00000001, 0x00070050, 0x0000001D, 0x0000390D, 0x00002763, 0x00004447, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x0000437B, 0x00002ABF, 0x00000002, 0x0006000C, + 0x00000013, 0x0000466C, 0x00000001, 0x0000003E, 0x0000437B, 0x00050051, 0x0000000D, 0x00002764, + 0x0000466C, 0x00000000, 0x00050051, 0x0000000D, 0x00004448, 0x0000466C, 0x00000001, 0x00070050, + 0x0000001D, 0x0000390E, 0x00002764, 0x00004448, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x0000437C, 0x00002ABF, 0x00000003, 0x0006000C, 0x00000013, 0x0000466D, 0x00000001, 0x0000003E, + 0x0000437C, 0x00050051, 0x0000000D, 0x00002765, 0x0000466D, 0x00000000, 0x00050051, 0x0000000D, + 0x000050BE, 0x0000466D, 0x00000001, 0x00070050, 0x0000001D, 0x00002349, 0x00002765, 0x000050BE, + 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F60, 0x000200F8, 0x00001FFE, 0x00050051, 0x0000000B, + 0x0000308B, 0x00002ABF, 0x00000000, 0x0004007C, 0x0000000C, 0x0000589D, 0x0000308B, 0x00050050, + 0x00000012, 0x0000471A, 0x0000589D, 0x0000589D, 0x000500C4, 0x00000012, 0x000047AD, 0x0000471A, + 0x000007A7, 0x000500C3, 0x00000012, 0x00003417, 0x000047AD, 0x00000867, 0x0004006F, 0x00000013, + 0x00002A97, 0x00003417, 0x0005008E, 0x00000013, 0x00004747, 0x00002A97, 0x000007FE, 0x0007000C, + 0x00000013, 0x00005E06, 0x00000001, 0x00000028, 0x00000049, 0x00004747, 0x00050051, 0x0000000D, + 0x00005F0A, 0x00005E06, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD4, 0x00005E06, 0x00000001, + 0x00070050, 0x0000001D, 0x0000411E, 0x00005F0A, 0x00003CD4, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x00004C42, 0x00002ABF, 0x00000001, 0x0004007C, 0x0000000C, 0x00003EA1, 0x00004C42, + 0x00050050, 0x00000012, 0x0000471B, 0x00003EA1, 0x00003EA1, 0x000500C4, 0x00000012, 0x000047AE, + 0x0000471B, 0x000007A7, 0x000500C3, 0x00000012, 0x00003418, 0x000047AE, 0x00000867, 0x0004006F, + 0x00000013, 0x00002A98, 0x00003418, 0x0005008E, 0x00000013, 0x00004748, 0x00002A98, 0x000007FE, + 0x0007000C, 0x00000013, 0x00005E07, 0x00000001, 0x00000028, 0x00000049, 0x00004748, 0x00050051, + 0x0000000D, 0x00005F0B, 0x00005E07, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD5, 0x00005E07, + 0x00000001, 0x00070050, 0x0000001D, 0x0000411F, 0x00005F0B, 0x00003CD5, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x00004C43, 0x00002ABF, 0x00000002, 0x0004007C, 0x0000000C, 0x00003EA2, + 0x00004C43, 0x00050050, 0x00000012, 0x0000471C, 0x00003EA2, 0x00003EA2, 0x000500C4, 0x00000012, + 0x000047AF, 0x0000471C, 0x000007A7, 0x000500C3, 0x00000012, 0x00003419, 0x000047AF, 0x00000867, + 0x0004006F, 0x00000013, 0x00002A99, 0x00003419, 0x0005008E, 0x00000013, 0x00004749, 0x00002A99, + 0x000007FE, 0x0007000C, 0x00000013, 0x00005E08, 0x00000001, 0x00000028, 0x00000049, 0x00004749, + 0x00050051, 0x0000000D, 0x00005F0C, 0x00005E08, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD6, + 0x00005E08, 0x00000001, 0x00070050, 0x0000001D, 0x00004120, 0x00005F0C, 0x00003CD6, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C44, 0x00002ABF, 0x00000003, 0x0004007C, 0x0000000C, + 0x00003EA3, 0x00004C44, 0x00050050, 0x00000012, 0x0000471D, 0x00003EA3, 0x00003EA3, 0x000500C4, + 0x00000012, 0x000047B0, 0x0000471D, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341A, 0x000047B0, + 0x00000867, 0x0004006F, 0x00000013, 0x00002A9A, 0x0000341A, 0x0005008E, 0x00000013, 0x0000474A, + 0x00002A9A, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E09, 0x00000001, 0x00000028, 0x00000049, + 0x0000474A, 0x00050051, 0x0000000D, 0x00005F0D, 0x00005E09, 0x00000000, 0x00050051, 0x0000000D, + 0x0000494C, 0x00005E09, 0x00000001, 0x00070050, 0x0000001D, 0x0000234A, 0x00005F0D, 0x0000494C, + 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F60, 0x000200F8, 0x00001CBA, 0x00050051, 0x0000000B, + 0x000056BD, 0x00002ABF, 0x00000000, 0x00060050, 0x00000014, 0x00004F0A, 0x000056BD, 0x000056BD, + 0x000056BD, 0x000500C2, 0x00000014, 0x00002B0D, 0x00004F0A, 0x00000BB4, 0x000500C7, 0x00000014, + 0x00005DE6, 0x00002B0D, 0x00000105, 0x000500C7, 0x00000014, 0x0000489C, 0x00005DE6, 0x00000466, + 0x000500C2, 0x00000014, 0x00005B90, 0x00005DE6, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040C9, + 0x00005B90, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4B, 0x00000001, 0x0000004B, 0x0000489C, + 0x0004007C, 0x00000014, 0x00002A15, 0x00002C4B, 0x00050082, 0x00000014, 0x0000187A, 0x00000B0C, + 0x00002A15, 0x00050080, 0x00000014, 0x00002210, 0x00002A15, 0x00000938, 0x000600A9, 0x00000014, + 0x0000286F, 0x000040C9, 0x00002210, 0x00005B90, 0x000500C4, 0x00000014, 0x00005AD4, 0x0000489C, + 0x0000187A, 0x000500C7, 0x00000014, 0x0000499A, 0x00005AD4, 0x00000466, 0x000600A9, 0x00000014, + 0x00002A9D, 0x000040C9, 0x0000499A, 0x0000489C, 0x00050080, 0x00000014, 0x00005FF9, 0x0000286F, + 0x000003FA, 0x000500C4, 0x00000014, 0x00004F7F, 0x00005FF9, 0x00000189, 0x000500C4, 0x00000014, + 0x00003FA6, 0x00002A9D, 0x0000008D, 0x000500C5, 0x00000014, 0x0000577C, 0x00004F7F, 0x00003FA6, + 0x000500AA, 0x00000010, 0x00003600, 0x00005DE6, 0x00000A12, 0x000600A9, 0x00000014, 0x00004242, + 0x00003600, 0x00000A12, 0x0000577C, 0x0004007C, 0x00000018, 0x000029CF, 0x00004242, 0x000500C2, + 0x0000000B, 0x00004BA4, 0x000056BD, 0x00000A64, 0x00040070, 0x0000000D, 0x0000480E, 0x00004BA4, + 0x00050085, 0x0000000D, 0x00003E1F, 0x0000480E, 0x00000149, 0x00050051, 0x0000000D, 0x000053C2, + 0x000029CF, 0x00000000, 0x00050051, 0x0000000D, 0x00002A55, 0x000029CF, 0x00000001, 0x00050051, + 0x0000000D, 0x00001E99, 0x000029CF, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDA, 0x000053C2, + 0x00002A55, 0x00001E99, 0x00003E1F, 0x00050051, 0x0000000B, 0x000027F5, 0x00002ABF, 0x00000001, + 0x00060050, 0x00000014, 0x0000350E, 0x000027F5, 0x000027F5, 0x000027F5, 0x000500C2, 0x00000014, + 0x00002B0E, 0x0000350E, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DE7, 0x00002B0E, 0x00000105, + 0x000500C7, 0x00000014, 0x0000489D, 0x00005DE7, 0x00000466, 0x000500C2, 0x00000014, 0x00005B91, + 0x00005DE7, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CA, 0x00005B91, 0x00000A12, 0x0006000C, + 0x00000016, 0x00002C4C, 0x00000001, 0x0000004B, 0x0000489D, 0x0004007C, 0x00000014, 0x00002A16, + 0x00002C4C, 0x00050082, 0x00000014, 0x0000187B, 0x00000B0C, 0x00002A16, 0x00050080, 0x00000014, + 0x00002211, 0x00002A16, 0x00000938, 0x000600A9, 0x00000014, 0x00002870, 0x000040CA, 0x00002211, + 0x00005B91, 0x000500C4, 0x00000014, 0x00005AD5, 0x0000489D, 0x0000187B, 0x000500C7, 0x00000014, + 0x0000499B, 0x00005AD5, 0x00000466, 0x000600A9, 0x00000014, 0x00002A9E, 0x000040CA, 0x0000499B, + 0x0000489D, 0x00050080, 0x00000014, 0x00005FFA, 0x00002870, 0x000003FA, 0x000500C4, 0x00000014, + 0x00004F80, 0x00005FFA, 0x00000189, 0x000500C4, 0x00000014, 0x00003FA7, 0x00002A9E, 0x0000008D, + 0x000500C5, 0x00000014, 0x0000577D, 0x00004F80, 0x00003FA7, 0x000500AA, 0x00000010, 0x00003601, + 0x00005DE7, 0x00000A12, 0x000600A9, 0x00000014, 0x00004243, 0x00003601, 0x00000A12, 0x0000577D, + 0x0004007C, 0x00000018, 0x000029D0, 0x00004243, 0x000500C2, 0x0000000B, 0x00004BA5, 0x000027F5, + 0x00000A64, 0x00040070, 0x0000000D, 0x0000480F, 0x00004BA5, 0x00050085, 0x0000000D, 0x00003E20, + 0x0000480F, 0x00000149, 0x00050051, 0x0000000D, 0x000053C3, 0x000029D0, 0x00000000, 0x00050051, + 0x0000000D, 0x00002A56, 0x000029D0, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9A, 0x000029D0, + 0x00000002, 0x00070050, 0x0000001D, 0x00003DDB, 0x000053C3, 0x00002A56, 0x00001E9A, 0x00003E20, + 0x00050051, 0x0000000B, 0x000027F6, 0x00002ABF, 0x00000002, 0x00060050, 0x00000014, 0x0000350F, + 0x000027F6, 0x000027F6, 0x000027F6, 0x000500C2, 0x00000014, 0x00002B0F, 0x0000350F, 0x00000BB4, + 0x000500C7, 0x00000014, 0x00005DE8, 0x00002B0F, 0x00000105, 0x000500C7, 0x00000014, 0x0000489E, + 0x00005DE8, 0x00000466, 0x000500C2, 0x00000014, 0x00005B92, 0x00005DE8, 0x00000B0C, 0x000500AA, + 0x00000010, 0x000040CB, 0x00005B92, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4D, 0x00000001, + 0x0000004B, 0x0000489E, 0x0004007C, 0x00000014, 0x00002A17, 0x00002C4D, 0x00050082, 0x00000014, + 0x0000187C, 0x00000B0C, 0x00002A17, 0x00050080, 0x00000014, 0x00002212, 0x00002A17, 0x00000938, + 0x000600A9, 0x00000014, 0x00002871, 0x000040CB, 0x00002212, 0x00005B92, 0x000500C4, 0x00000014, + 0x00005AD6, 0x0000489E, 0x0000187C, 0x000500C7, 0x00000014, 0x0000499C, 0x00005AD6, 0x00000466, + 0x000600A9, 0x00000014, 0x00002A9F, 0x000040CB, 0x0000499C, 0x0000489E, 0x00050080, 0x00000014, + 0x00005FFB, 0x00002871, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F81, 0x00005FFB, 0x00000189, + 0x000500C4, 0x00000014, 0x00003FA8, 0x00002A9F, 0x0000008D, 0x000500C5, 0x00000014, 0x0000577E, + 0x00004F81, 0x00003FA8, 0x000500AA, 0x00000010, 0x00003602, 0x00005DE8, 0x00000A12, 0x000600A9, + 0x00000014, 0x00004244, 0x00003602, 0x00000A12, 0x0000577E, 0x0004007C, 0x00000018, 0x000029D1, + 0x00004244, 0x000500C2, 0x0000000B, 0x00004BA6, 0x000027F6, 0x00000A64, 0x00040070, 0x0000000D, + 0x00004810, 0x00004BA6, 0x00050085, 0x0000000D, 0x00003E21, 0x00004810, 0x00000149, 0x00050051, + 0x0000000D, 0x000053C4, 0x000029D1, 0x00000000, 0x00050051, 0x0000000D, 0x00002A57, 0x000029D1, + 0x00000001, 0x00050051, 0x0000000D, 0x00001E9B, 0x000029D1, 0x00000002, 0x00070050, 0x0000001D, + 0x00003DDC, 0x000053C4, 0x00002A57, 0x00001E9B, 0x00003E21, 0x00050051, 0x0000000B, 0x000027F7, + 0x00002ABF, 0x00000003, 0x00060050, 0x00000014, 0x00003510, 0x000027F7, 0x000027F7, 0x000027F7, + 0x000500C2, 0x00000014, 0x00002B10, 0x00003510, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DE9, + 0x00002B10, 0x00000105, 0x000500C7, 0x00000014, 0x0000489F, 0x00005DE9, 0x00000466, 0x000500C2, + 0x00000014, 0x00005B93, 0x00005DE9, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CC, 0x00005B93, + 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4E, 0x00000001, 0x0000004B, 0x0000489F, 0x0004007C, + 0x00000014, 0x00002A18, 0x00002C4E, 0x00050082, 0x00000014, 0x0000187D, 0x00000B0C, 0x00002A18, + 0x00050080, 0x00000014, 0x00002213, 0x00002A18, 0x00000938, 0x000600A9, 0x00000014, 0x00002872, + 0x000040CC, 0x00002213, 0x00005B93, 0x000500C4, 0x00000014, 0x00005AD7, 0x0000489F, 0x0000187D, + 0x000500C7, 0x00000014, 0x0000499D, 0x00005AD7, 0x00000466, 0x000600A9, 0x00000014, 0x00002AA0, + 0x000040CC, 0x0000499D, 0x0000489F, 0x00050080, 0x00000014, 0x00005FFC, 0x00002872, 0x000003FA, + 0x000500C4, 0x00000014, 0x00004F82, 0x00005FFC, 0x00000189, 0x000500C4, 0x00000014, 0x00003FA9, + 0x00002AA0, 0x0000008D, 0x000500C5, 0x00000014, 0x0000577F, 0x00004F82, 0x00003FA9, 0x000500AA, + 0x00000010, 0x00003603, 0x00005DE9, 0x00000A12, 0x000600A9, 0x00000014, 0x00004245, 0x00003603, + 0x00000A12, 0x0000577F, 0x0004007C, 0x00000018, 0x000029D2, 0x00004245, 0x000500C2, 0x0000000B, + 0x00004BA7, 0x000027F7, 0x00000A64, 0x00040070, 0x0000000D, 0x00004811, 0x00004BA7, 0x00050085, + 0x0000000D, 0x00003E22, 0x00004811, 0x00000149, 0x00050051, 0x0000000D, 0x000053C5, 0x000029D2, + 0x00000000, 0x00050051, 0x0000000D, 0x00002A58, 0x000029D2, 0x00000001, 0x00050051, 0x0000000D, + 0x00002B11, 0x000029D2, 0x00000002, 0x00070050, 0x0000001D, 0x0000234B, 0x000053C5, 0x00002A58, + 0x00002B11, 0x00003E22, 0x000200F9, 0x00003F60, 0x000200F8, 0x00001CBB, 0x00050051, 0x0000000B, + 0x000056BE, 0x00002ABF, 0x00000000, 0x00070050, 0x00000017, 0x00004F0B, 0x000056BE, 0x000056BE, + 0x000056BE, 0x000056BE, 0x000500C2, 0x00000017, 0x00002498, 0x00004F0B, 0x0000034D, 0x000500C7, + 0x00000017, 0x000049AB, 0x00002498, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CB7, 0x000049AB, + 0x00050085, 0x0000001D, 0x00004130, 0x00003CB7, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD2, + 0x00002ABF, 0x00000001, 0x00070050, 0x00000017, 0x0000514D, 0x00005CD2, 0x00005CD2, 0x00005CD2, + 0x00005CD2, 0x000500C2, 0x00000017, 0x00002499, 0x0000514D, 0x0000034D, 0x000500C7, 0x00000017, + 0x000049AC, 0x00002499, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CB8, 0x000049AC, 0x00050085, + 0x0000001D, 0x00004131, 0x00003CB8, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD3, 0x00002ABF, + 0x00000002, 0x00070050, 0x00000017, 0x0000514E, 0x00005CD3, 0x00005CD3, 0x00005CD3, 0x00005CD3, + 0x000500C2, 0x00000017, 0x0000249A, 0x0000514E, 0x0000034D, 0x000500C7, 0x00000017, 0x000049AD, + 0x0000249A, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CB9, 0x000049AD, 0x00050085, 0x0000001D, + 0x00004132, 0x00003CB9, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD4, 0x00002ABF, 0x00000003, + 0x00070050, 0x00000017, 0x0000514F, 0x00005CD4, 0x00005CD4, 0x00005CD4, 0x00005CD4, 0x000500C2, + 0x00000017, 0x0000249B, 0x0000514F, 0x0000034D, 0x000500C7, 0x00000017, 0x000049AE, 0x0000249B, + 0x0000027B, 0x00040070, 0x0000001D, 0x0000492F, 0x000049AE, 0x00050085, 0x0000001D, 0x0000269F, + 0x0000492F, 0x00000AEE, 0x000200F9, 0x00003F60, 0x000200F8, 0x000038F9, 0x00050051, 0x0000000B, + 0x000056BF, 0x00002ABF, 0x00000000, 0x00070050, 0x00000017, 0x00004F0C, 0x000056BF, 0x000056BF, + 0x000056BF, 0x000056BF, 0x000500C2, 0x00000017, 0x0000249C, 0x00004F0C, 0x0000028D, 0x000500C7, + 0x00000017, 0x00004A56, 0x0000249C, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A2, 0x00004A56, + 0x0005008E, 0x0000001D, 0x00004B23, 0x000036A2, 0x0000017A, 0x00050051, 0x0000000B, 0x0000219F, + 0x00002ABF, 0x00000001, 0x00070050, 0x00000017, 0x0000610B, 0x0000219F, 0x0000219F, 0x0000219F, + 0x0000219F, 0x000500C2, 0x00000017, 0x0000249D, 0x0000610B, 0x0000028D, 0x000500C7, 0x00000017, + 0x00004A57, 0x0000249D, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A3, 0x00004A57, 0x0005008E, + 0x0000001D, 0x00004B24, 0x000036A3, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A0, 0x00002ABF, + 0x00000002, 0x00070050, 0x00000017, 0x0000610C, 0x000021A0, 0x000021A0, 0x000021A0, 0x000021A0, + 0x000500C2, 0x00000017, 0x0000249E, 0x0000610C, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A58, + 0x0000249E, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A4, 0x00004A58, 0x0005008E, 0x0000001D, + 0x00004B25, 0x000036A4, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A1, 0x00002ABF, 0x00000003, + 0x00070050, 0x00000017, 0x0000610D, 0x000021A1, 0x000021A1, 0x000021A1, 0x000021A1, 0x000500C2, + 0x00000017, 0x0000249F, 0x0000610D, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A59, 0x0000249F, + 0x0000064B, 0x00040070, 0x0000001D, 0x0000431A, 0x00004A59, 0x0005008E, 0x0000001D, 0x00003092, + 0x0000431A, 0x0000017A, 0x000200F9, 0x00003F60, 0x000200F8, 0x00004BFB, 0x00050051, 0x0000000B, + 0x0000308C, 0x00002ABF, 0x00000000, 0x0004007C, 0x0000000D, 0x00004FEE, 0x0000308C, 0x00050050, + 0x00000013, 0x00004336, 0x00004FEE, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D90, 0x00004336, + 0x00004336, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B1, + 0x00002ABF, 0x00000001, 0x0004007C, 0x0000000D, 0x00003F68, 0x000056B1, 0x00050050, 0x00000013, + 0x00004337, 0x00003F68, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D91, 0x00004337, 0x00004337, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B2, 0x00002ABF, + 0x00000002, 0x0004007C, 0x0000000D, 0x00003F69, 0x000056B2, 0x00050050, 0x00000013, 0x00004338, + 0x00003F69, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D92, 0x00004338, 0x00004338, 0x00000000, + 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B3, 0x00002ABF, 0x00000003, + 0x0004007C, 0x0000000D, 0x00003F6A, 0x000056B3, 0x00050050, 0x00000013, 0x00004FAE, 0x00003F6A, + 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3A, 0x00004FAE, 0x00004FAE, 0x00000000, 0x00000001, + 0x00000001, 0x00000001, 0x000200F9, 0x00003F60, 0x000200F8, 0x00003F60, 0x000F00F5, 0x0000001D, + 0x00002BA7, 0x00005A3A, 0x00004BFB, 0x00003092, 0x000038F9, 0x0000269F, 0x00001CBB, 0x0000234B, + 0x00001CBA, 0x0000234A, 0x00001FFE, 0x00002349, 0x00002033, 0x000F00F5, 0x0000001D, 0x00003808, + 0x00002D92, 0x00004BFB, 0x00004B25, 0x000038F9, 0x00004132, 0x00001CBB, 0x00003DDC, 0x00001CBA, + 0x00004120, 0x00001FFE, 0x0000390E, 0x00002033, 0x000F00F5, 0x0000001D, 0x00003B7D, 0x00002D91, + 0x00004BFB, 0x00004B24, 0x000038F9, 0x00004131, 0x00001CBB, 0x00003DDB, 0x00001CBA, 0x0000411F, + 0x00001FFE, 0x0000390D, 0x00002033, 0x000F00F5, 0x0000001D, 0x000038B6, 0x00002D90, 0x00004BFB, + 0x00004B23, 0x000038F9, 0x00004130, 0x00001CBB, 0x00003DDA, 0x00001CBA, 0x0000411E, 0x00001FFE, + 0x0000390C, 0x00002033, 0x000200F9, 0x0000530F, 0x000200F8, 0x00003B65, 0x000500AA, 0x00000009, + 0x00005450, 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F23, 0x00000002, 0x000400FA, 0x00005450, + 0x00002622, 0x00002F62, 0x000200F8, 0x00002F62, 0x00060041, 0x00000288, 0x00004BD0, 0x00000CC7, + 0x00000A0B, 0x00005AD8, 0x0004003D, 0x0000000B, 0x00005D45, 0x00004BD0, 0x00050080, 0x0000000B, + 0x00002DAB, 0x00005AD8, 0x00000A0D, 0x00060041, 0x00000288, 0x00001901, 0x00000CC7, 0x00000A0B, + 0x00002DAB, 0x0004003D, 0x0000000B, 0x00005C64, 0x00001901, 0x00050080, 0x0000000B, 0x00002DAC, + 0x00005AD8, 0x0000199B, 0x00060041, 0x00000288, 0x00001902, 0x00000CC7, 0x00000A0B, 0x00002DAC, + 0x0004003D, 0x0000000B, 0x00005C65, 0x00001902, 0x00050080, 0x0000000B, 0x00002DAD, 0x00002DAC, + 0x00000A0D, 0x00060041, 0x00000288, 0x00005FEF, 0x00000CC7, 0x00000A0B, 0x00002DAD, 0x0004003D, + 0x0000000B, 0x0000374C, 0x00005FEF, 0x00070050, 0x00000017, 0x00004CD6, 0x00005D45, 0x00005C64, + 0x00005C65, 0x0000374C, 0x00050084, 0x0000000B, 0x00004298, 0x00000A10, 0x0000199B, 0x00050080, + 0x0000000B, 0x000036A7, 0x00005AD8, 0x00004298, 0x00060041, 0x00000288, 0x00003B81, 0x00000CC7, + 0x00000A0B, 0x000036A7, 0x0004003D, 0x0000000B, 0x00005C66, 0x00003B81, 0x00050080, 0x0000000B, + 0x00002DAE, 0x000036A7, 0x00000A0D, 0x00060041, 0x00000288, 0x0000194C, 0x00000CC7, 0x00000A0B, + 0x00002DAE, 0x0004003D, 0x0000000B, 0x00005E5D, 0x0000194C, 0x00050084, 0x0000000B, 0x0000185C, + 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A3, 0x00005AD8, 0x0000185C, 0x00060041, + 0x00000288, 0x00003B82, 0x00000CC7, 0x00000A0B, 0x000020A3, 0x0004003D, 0x0000000B, 0x00005C67, + 0x00003B82, 0x00050080, 0x0000000B, 0x00002DAF, 0x000020A3, 0x00000A0D, 0x00060041, 0x00000288, + 0x00005FF0, 0x00000CC7, 0x00000A0B, 0x00002DAF, 0x0004003D, 0x0000000B, 0x00003FFD, 0x00005FF0, + 0x00070050, 0x00000017, 0x0000512E, 0x00005C66, 0x00005E5D, 0x00005C67, 0x00003FFD, 0x000200F9, + 0x00004F23, 0x000200F8, 0x00002622, 0x00060041, 0x00000288, 0x00005546, 0x00000CC7, 0x00000A0B, + 0x00005AD8, 0x0004003D, 0x0000000B, 0x00005D46, 0x00005546, 0x00050080, 0x0000000B, 0x00002DB0, + 0x00005AD8, 0x00000A0D, 0x00060041, 0x00000288, 0x00001903, 0x00000CC7, 0x00000A0B, 0x00002DB0, + 0x0004003D, 0x0000000B, 0x00005C68, 0x00001903, 0x00050080, 0x0000000B, 0x00002DB1, 0x00005AD8, + 0x00000A10, 0x00060041, 0x00000288, 0x00001904, 0x00000CC7, 0x00000A0B, 0x00002DB1, 0x0004003D, + 0x0000000B, 0x00005C69, 0x00001904, 0x00050080, 0x0000000B, 0x00002DB2, 0x00005AD8, 0x00000A13, + 0x00060041, 0x00000288, 0x00005FF1, 0x00000CC7, 0x00000A0B, 0x00002DB2, 0x0004003D, 0x0000000B, + 0x00003700, 0x00005FF1, 0x00070050, 0x00000017, 0x00004ADD, 0x00005D46, 0x00005C68, 0x00005C69, + 0x00003700, 0x00050080, 0x0000000B, 0x000057E5, 0x00005AD8, 0x00000A16, 0x00060041, 0x00000288, + 0x0000604B, 0x00000CC7, 0x00000A0B, 0x000057E5, 0x0004003D, 0x0000000B, 0x00005C6A, 0x0000604B, + 0x00050080, 0x0000000B, 0x00002DB3, 0x00005AD8, 0x00000A19, 0x00060041, 0x00000288, 0x00001905, + 0x00000CC7, 0x00000A0B, 0x00002DB3, 0x0004003D, 0x0000000B, 0x00005C6B, 0x00001905, 0x00050080, + 0x0000000B, 0x00002DB4, 0x00005AD8, 0x00000A1C, 0x00060041, 0x00000288, 0x00001906, 0x00000CC7, + 0x00000A0B, 0x00002DB4, 0x0004003D, 0x0000000B, 0x00005C6C, 0x00001906, 0x00050080, 0x0000000B, + 0x00002DB5, 0x00005AD8, 0x00000A1F, 0x00060041, 0x00000288, 0x00005FF2, 0x00000CC7, 0x00000A0B, + 0x00002DB5, 0x0004003D, 0x0000000B, 0x00003FFE, 0x00005FF2, 0x00070050, 0x00000017, 0x0000512F, + 0x00005C6A, 0x00005C6B, 0x00005C6C, 0x00003FFE, 0x000200F9, 0x00004F23, 0x000200F8, 0x00004F23, + 0x000700F5, 0x00000017, 0x00002BCD, 0x0000512F, 0x00002622, 0x0000512E, 0x00002F62, 0x000700F5, + 0x00000017, 0x00003720, 0x00004ADD, 0x00002622, 0x00004CD6, 0x00002F62, 0x000300F7, 0x00004F24, + 0x00000000, 0x000700FB, 0x00002180, 0x00004F56, 0x00000005, 0x00002158, 0x00000007, 0x00002034, + 0x000200F8, 0x00002034, 0x00050051, 0x0000000B, 0x00005F57, 0x00003720, 0x00000000, 0x0006000C, + 0x00000013, 0x00006068, 0x00000001, 0x0000003E, 0x00005F57, 0x00050051, 0x0000000D, 0x00002775, + 0x00006068, 0x00000000, 0x00050051, 0x0000000D, 0x00003EB8, 0x00006068, 0x00000001, 0x00050051, + 0x0000000B, 0x00004281, 0x00003720, 0x00000001, 0x0006000C, 0x00000013, 0x00003CF5, 0x00000001, + 0x0000003E, 0x00004281, 0x00050051, 0x0000000D, 0x00002766, 0x00003CF5, 0x00000000, 0x00050051, + 0x0000000D, 0x00004449, 0x00003CF5, 0x00000001, 0x00070050, 0x0000001D, 0x0000390F, 0x00002775, + 0x00003EB8, 0x00002766, 0x00004449, 0x00050051, 0x0000000B, 0x0000437D, 0x00003720, 0x00000002, + 0x0006000C, 0x00000013, 0x0000466E, 0x00000001, 0x0000003E, 0x0000437D, 0x00050051, 0x0000000D, + 0x00002776, 0x0000466E, 0x00000000, 0x00050051, 0x0000000D, 0x00003EB9, 0x0000466E, 0x00000001, + 0x00050051, 0x0000000B, 0x00004282, 0x00003720, 0x00000003, 0x0006000C, 0x00000013, 0x00003CF6, + 0x00000001, 0x0000003E, 0x00004282, 0x00050051, 0x0000000D, 0x00002767, 0x00003CF6, 0x00000000, + 0x00050051, 0x0000000D, 0x0000444A, 0x00003CF6, 0x00000001, 0x00070050, 0x0000001D, 0x00003910, + 0x00002776, 0x00003EB9, 0x00002767, 0x0000444A, 0x00050051, 0x0000000B, 0x0000437E, 0x00002BCD, + 0x00000000, 0x0006000C, 0x00000013, 0x0000466F, 0x00000001, 0x0000003E, 0x0000437E, 0x00050051, + 0x0000000D, 0x00002777, 0x0000466F, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBA, 0x0000466F, + 0x00000001, 0x00050051, 0x0000000B, 0x00004283, 0x00002BCD, 0x00000001, 0x0006000C, 0x00000013, + 0x00003CF7, 0x00000001, 0x0000003E, 0x00004283, 0x00050051, 0x0000000D, 0x00002768, 0x00003CF7, + 0x00000000, 0x00050051, 0x0000000D, 0x0000444B, 0x00003CF7, 0x00000001, 0x00070050, 0x0000001D, + 0x00003911, 0x00002777, 0x00003EBA, 0x00002768, 0x0000444B, 0x00050051, 0x0000000B, 0x0000437F, + 0x00002BCD, 0x00000002, 0x0006000C, 0x00000013, 0x00004670, 0x00000001, 0x0000003E, 0x0000437F, + 0x00050051, 0x0000000D, 0x00002778, 0x00004670, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBB, + 0x00004670, 0x00000001, 0x00050051, 0x0000000B, 0x00004284, 0x00002BCD, 0x00000003, 0x0006000C, + 0x00000013, 0x00003CF8, 0x00000001, 0x0000003E, 0x00004284, 0x00050051, 0x0000000D, 0x00002769, + 0x00003CF8, 0x00000000, 0x00050051, 0x0000000D, 0x000050BF, 0x00003CF8, 0x00000001, 0x00070050, + 0x0000001D, 0x0000234C, 0x00002778, 0x00003EBB, 0x00002769, 0x000050BF, 0x000200F9, 0x00004F24, + 0x000200F8, 0x00002158, 0x0007004F, 0x00000011, 0x000025FB, 0x00003720, 0x00003720, 0x00000000, + 0x00000001, 0x0004007C, 0x00000012, 0x00005B3C, 0x000025FB, 0x0009004F, 0x0000001A, 0x000060CE, + 0x00005B3C, 0x00005B3C, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, + 0x000048A6, 0x000060CE, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D8D, 0x000048A6, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002A9B, 0x00003D8D, 0x0005008E, 0x0000001D, 0x00004721, 0x00002A9B, + 0x000007FE, 0x0007000C, 0x0000001D, 0x00006291, 0x00000001, 0x00000028, 0x00000504, 0x00004721, + 0x0007004F, 0x00000011, 0x0000376B, 0x00003720, 0x00003720, 0x00000002, 0x00000003, 0x0004007C, + 0x00000012, 0x000024BF, 0x0000376B, 0x0009004F, 0x0000001A, 0x000060CF, 0x000024BF, 0x000024BF, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048A7, 0x000060CF, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D8E, 0x000048A7, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002A9C, 0x00003D8E, 0x0005008E, 0x0000001D, 0x00004722, 0x00002A9C, 0x000007FE, 0x0007000C, + 0x0000001D, 0x00006292, 0x00000001, 0x00000028, 0x00000504, 0x00004722, 0x0007004F, 0x00000011, + 0x0000376C, 0x00002BCD, 0x00002BCD, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000024C0, + 0x0000376C, 0x0009004F, 0x0000001A, 0x000060D0, 0x000024C0, 0x000024C0, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048A8, 0x000060D0, 0x00000122, 0x000500C3, + 0x0000001A, 0x00003D8F, 0x000048A8, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA1, 0x00003D8F, + 0x0005008E, 0x0000001D, 0x00004723, 0x00002AA1, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006293, + 0x00000001, 0x00000028, 0x00000504, 0x00004723, 0x0007004F, 0x00000011, 0x0000376D, 0x00002BCD, + 0x00002BCD, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C1, 0x0000376D, 0x0009004F, + 0x0000001A, 0x000060D1, 0x000024C1, 0x000024C1, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C4, 0x0000001A, 0x000048A9, 0x000060D1, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D90, + 0x000048A9, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA2, 0x00003D90, 0x0005008E, 0x0000001D, + 0x000053BF, 0x00002AA2, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004362, 0x00000001, 0x00000028, + 0x00000504, 0x000053BF, 0x000200F9, 0x00004F24, 0x000200F8, 0x00004F56, 0x0007004F, 0x00000011, + 0x00002623, 0x00003720, 0x00003720, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x00005159, + 0x00002623, 0x00050051, 0x0000000D, 0x00001B7B, 0x00005159, 0x00000000, 0x00050051, 0x0000000D, + 0x0000346A, 0x00005159, 0x00000001, 0x00070050, 0x0000001D, 0x00004278, 0x00001B7B, 0x0000346A, + 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041D8, 0x00003720, 0x00003720, 0x00000002, + 0x00000003, 0x0004007C, 0x00000013, 0x0000375D, 0x000041D8, 0x00050051, 0x0000000D, 0x00001B7C, + 0x0000375D, 0x00000000, 0x00050051, 0x0000000D, 0x0000346B, 0x0000375D, 0x00000001, 0x00070050, + 0x0000001D, 0x00004279, 0x00001B7C, 0x0000346B, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, + 0x000041D9, 0x00002BCD, 0x00002BCD, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x0000375E, + 0x000041D9, 0x00050051, 0x0000000D, 0x00001B7D, 0x0000375E, 0x00000000, 0x00050051, 0x0000000D, + 0x0000346C, 0x0000375E, 0x00000001, 0x00070050, 0x0000001D, 0x0000427A, 0x00001B7D, 0x0000346C, + 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DA, 0x00002BCD, 0x00002BCD, 0x00000002, + 0x00000003, 0x0004007C, 0x00000013, 0x0000375F, 0x000041DA, 0x00050051, 0x0000000D, 0x00001B7E, + 0x0000375F, 0x00000000, 0x00050051, 0x0000000D, 0x00004108, 0x0000375F, 0x00000001, 0x00070050, + 0x0000001D, 0x0000234D, 0x00001B7E, 0x00004108, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F24, + 0x000200F8, 0x00004F24, 0x000900F5, 0x0000001D, 0x00002BA8, 0x0000234D, 0x00004F56, 0x00004362, + 0x00002158, 0x0000234C, 0x00002034, 0x000900F5, 0x0000001D, 0x00003809, 0x0000427A, 0x00004F56, + 0x00006293, 0x00002158, 0x00003911, 0x00002034, 0x000900F5, 0x0000001D, 0x00003B7E, 0x00004279, + 0x00004F56, 0x00006292, 0x00002158, 0x00003910, 0x00002034, 0x000900F5, 0x0000001D, 0x000038B7, + 0x00004278, 0x00004F56, 0x00006291, 0x00002158, 0x0000390F, 0x00002034, 0x000200F9, 0x0000530F, + 0x000200F8, 0x0000530F, 0x000700F5, 0x0000001D, 0x00002BA9, 0x00002BA8, 0x00004F24, 0x00002BA7, + 0x00003F60, 0x000700F5, 0x0000001D, 0x0000380A, 0x00003809, 0x00004F24, 0x00003808, 0x00003F60, + 0x000700F5, 0x0000001D, 0x000035EC, 0x00003B7E, 0x00004F24, 0x00003B7D, 0x00003F60, 0x000700F5, + 0x0000001D, 0x000020D3, 0x000038B7, 0x00004F24, 0x000038B6, 0x00003F60, 0x000500AE, 0x00000009, + 0x00002E55, 0x00003F4D, 0x00000A16, 0x000300F7, 0x00005313, 0x00000002, 0x000400FA, 0x00002E55, + 0x000050E5, 0x00005313, 0x000200F8, 0x000050E5, 0x00050085, 0x0000000D, 0x000061FB, 0x00002B2C, + 0x000000FC, 0x00050080, 0x0000000B, 0x00005E78, 0x00005AD8, 0x00000AFA, 0x000300F7, 0x00005310, + 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B66, 0x000040BA, 0x000200F8, 0x000040BA, 0x000500AA, + 0x00000009, 0x00004ADB, 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F4A, 0x00000002, 0x000400FA, + 0x00004ADB, 0x00002624, 0x00002F63, 0x000200F8, 0x00002F63, 0x00060041, 0x00000288, 0x00004BD1, + 0x00000CC7, 0x00000A0B, 0x00005E78, 0x0004003D, 0x0000000B, 0x00005D47, 0x00004BD1, 0x00050080, + 0x0000000B, 0x00002DB6, 0x00005E78, 0x0000199B, 0x00060041, 0x00000288, 0x0000194D, 0x00000CC7, + 0x00000A0B, 0x00002DB6, 0x0004003D, 0x0000000B, 0x00005E5E, 0x0000194D, 0x00050084, 0x0000000B, + 0x0000185D, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A4, 0x00005E78, 0x0000185D, + 0x00060041, 0x00000288, 0x00003BCE, 0x00000CC7, 0x00000A0B, 0x000020A4, 0x0004003D, 0x0000000B, + 0x00005E5F, 0x00003BCE, 0x00050084, 0x0000000B, 0x0000185E, 0x00000A13, 0x0000199B, 0x00050080, + 0x0000000B, 0x000020A5, 0x00005E78, 0x0000185E, 0x00060041, 0x00000288, 0x000037F2, 0x00000CC7, + 0x00000A0B, 0x000020A5, 0x0004003D, 0x0000000B, 0x00003FFF, 0x000037F2, 0x00070050, 0x00000017, + 0x00005130, 0x00005D47, 0x00005E5E, 0x00005E5F, 0x00003FFF, 0x000200F9, 0x00004F4A, 0x000200F8, + 0x00002624, 0x00060041, 0x00000288, 0x00005547, 0x00000CC7, 0x00000A0B, 0x00005E78, 0x0004003D, + 0x0000000B, 0x00005D48, 0x00005547, 0x00050080, 0x0000000B, 0x00002DB7, 0x00005AD8, 0x00000AFD, + 0x00060041, 0x00000288, 0x00001907, 0x00000CC7, 0x00000A0B, 0x00002DB7, 0x0004003D, 0x0000000B, + 0x00005C6D, 0x00001907, 0x00050080, 0x0000000B, 0x00002DB8, 0x00005AD8, 0x00000B00, 0x00060041, + 0x00000288, 0x00001908, 0x00000CC7, 0x00000A0B, 0x00002DB8, 0x0004003D, 0x0000000B, 0x00005C6E, + 0x00001908, 0x00050080, 0x0000000B, 0x00002DB9, 0x00005AD8, 0x00000B03, 0x00060041, 0x00000288, + 0x00005FF3, 0x00000CC7, 0x00000A0B, 0x00002DB9, 0x0004003D, 0x0000000B, 0x00004000, 0x00005FF3, + 0x00070050, 0x00000017, 0x00005131, 0x00005D48, 0x00005C6D, 0x00005C6E, 0x00004000, 0x000200F9, + 0x00004F4A, 0x000200F8, 0x00004F4A, 0x000700F5, 0x00000017, 0x00002AC0, 0x00005131, 0x00002624, + 0x00005130, 0x00002F63, 0x000300F7, 0x00003F61, 0x00000000, 0x001300FB, 0x00002180, 0x00004BFC, + 0x00000000, 0x000038FA, 0x00000001, 0x000038FA, 0x00000002, 0x00001CBD, 0x0000000A, 0x00001CBD, + 0x00000003, 0x00001CBC, 0x0000000C, 0x00001CBC, 0x00000004, 0x00001FFF, 0x00000006, 0x00002035, + 0x000200F8, 0x00002035, 0x00050051, 0x0000000B, 0x00005F58, 0x00002AC0, 0x00000000, 0x0006000C, + 0x00000013, 0x00006069, 0x00000001, 0x0000003E, 0x00005F58, 0x00050051, 0x0000000D, 0x0000276A, + 0x00006069, 0x00000000, 0x00050051, 0x0000000D, 0x0000444C, 0x00006069, 0x00000001, 0x00070050, + 0x0000001D, 0x00003912, 0x0000276A, 0x0000444C, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x00004380, 0x00002AC0, 0x00000001, 0x0006000C, 0x00000013, 0x00004671, 0x00000001, 0x0000003E, + 0x00004380, 0x00050051, 0x0000000D, 0x0000276B, 0x00004671, 0x00000000, 0x00050051, 0x0000000D, + 0x0000444D, 0x00004671, 0x00000001, 0x00070050, 0x0000001D, 0x00003913, 0x0000276B, 0x0000444D, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004381, 0x00002AC0, 0x00000002, 0x0006000C, + 0x00000013, 0x00004672, 0x00000001, 0x0000003E, 0x00004381, 0x00050051, 0x0000000D, 0x0000276C, + 0x00004672, 0x00000000, 0x00050051, 0x0000000D, 0x0000444E, 0x00004672, 0x00000001, 0x00070050, + 0x0000001D, 0x00003914, 0x0000276C, 0x0000444E, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x00004382, 0x00002AC0, 0x00000003, 0x0006000C, 0x00000013, 0x00004673, 0x00000001, 0x0000003E, + 0x00004382, 0x00050051, 0x0000000D, 0x0000276D, 0x00004673, 0x00000000, 0x00050051, 0x0000000D, + 0x000050C0, 0x00004673, 0x00000001, 0x00070050, 0x0000001D, 0x0000234E, 0x0000276D, 0x000050C0, + 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F61, 0x000200F8, 0x00001FFF, 0x00050051, 0x0000000B, + 0x0000308D, 0x00002AC0, 0x00000000, 0x0004007C, 0x0000000C, 0x0000589E, 0x0000308D, 0x00050050, + 0x00000012, 0x0000471E, 0x0000589E, 0x0000589E, 0x000500C4, 0x00000012, 0x000047B1, 0x0000471E, + 0x000007A7, 0x000500C3, 0x00000012, 0x0000341B, 0x000047B1, 0x00000867, 0x0004006F, 0x00000013, + 0x00002AA3, 0x0000341B, 0x0005008E, 0x00000013, 0x0000474B, 0x00002AA3, 0x000007FE, 0x0007000C, + 0x00000013, 0x00005E0A, 0x00000001, 0x00000028, 0x00000049, 0x0000474B, 0x00050051, 0x0000000D, + 0x00005F0E, 0x00005E0A, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD7, 0x00005E0A, 0x00000001, + 0x00070050, 0x0000001D, 0x00004121, 0x00005F0E, 0x00003CD7, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x00004C45, 0x00002AC0, 0x00000001, 0x0004007C, 0x0000000C, 0x00003EA4, 0x00004C45, + 0x00050050, 0x00000012, 0x0000471F, 0x00003EA4, 0x00003EA4, 0x000500C4, 0x00000012, 0x000047B2, + 0x0000471F, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341C, 0x000047B2, 0x00000867, 0x0004006F, + 0x00000013, 0x00002AA4, 0x0000341C, 0x0005008E, 0x00000013, 0x0000474C, 0x00002AA4, 0x000007FE, + 0x0007000C, 0x00000013, 0x00005E0B, 0x00000001, 0x00000028, 0x00000049, 0x0000474C, 0x00050051, + 0x0000000D, 0x00005F0F, 0x00005E0B, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD8, 0x00005E0B, + 0x00000001, 0x00070050, 0x0000001D, 0x00004122, 0x00005F0F, 0x00003CD8, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x00004C46, 0x00002AC0, 0x00000002, 0x0004007C, 0x0000000C, 0x00003EA5, + 0x00004C46, 0x00050050, 0x00000012, 0x00004720, 0x00003EA5, 0x00003EA5, 0x000500C4, 0x00000012, + 0x000047B3, 0x00004720, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341D, 0x000047B3, 0x00000867, + 0x0004006F, 0x00000013, 0x00002AA5, 0x0000341D, 0x0005008E, 0x00000013, 0x0000474D, 0x00002AA5, + 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0C, 0x00000001, 0x00000028, 0x00000049, 0x0000474D, + 0x00050051, 0x0000000D, 0x00005F10, 0x00005E0C, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD9, + 0x00005E0C, 0x00000001, 0x00070050, 0x0000001D, 0x00004123, 0x00005F10, 0x00003CD9, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C47, 0x00002AC0, 0x00000003, 0x0004007C, 0x0000000C, + 0x00003EA6, 0x00004C47, 0x00050050, 0x00000012, 0x00004724, 0x00003EA6, 0x00003EA6, 0x000500C4, + 0x00000012, 0x000047B4, 0x00004724, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341E, 0x000047B4, + 0x00000867, 0x0004006F, 0x00000013, 0x00002AA6, 0x0000341E, 0x0005008E, 0x00000013, 0x0000474E, + 0x00002AA6, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0D, 0x00000001, 0x00000028, 0x00000049, + 0x0000474E, 0x00050051, 0x0000000D, 0x00005F11, 0x00005E0D, 0x00000000, 0x00050051, 0x0000000D, + 0x0000494D, 0x00005E0D, 0x00000001, 0x00070050, 0x0000001D, 0x0000234F, 0x00005F11, 0x0000494D, + 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F61, 0x000200F8, 0x00001CBC, 0x00050051, 0x0000000B, + 0x000056C0, 0x00002AC0, 0x00000000, 0x00060050, 0x00000014, 0x00004F0D, 0x000056C0, 0x000056C0, + 0x000056C0, 0x000500C2, 0x00000014, 0x00002B12, 0x00004F0D, 0x00000BB4, 0x000500C7, 0x00000014, + 0x00005DEA, 0x00002B12, 0x00000105, 0x000500C7, 0x00000014, 0x000048A0, 0x00005DEA, 0x00000466, + 0x000500C2, 0x00000014, 0x00005B94, 0x00005DEA, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CD, + 0x00005B94, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4F, 0x00000001, 0x0000004B, 0x000048A0, + 0x0004007C, 0x00000014, 0x00002A19, 0x00002C4F, 0x00050082, 0x00000014, 0x0000187E, 0x00000B0C, + 0x00002A19, 0x00050080, 0x00000014, 0x00002214, 0x00002A19, 0x00000938, 0x000600A9, 0x00000014, + 0x00002873, 0x000040CD, 0x00002214, 0x00005B94, 0x000500C4, 0x00000014, 0x00005AD9, 0x000048A0, + 0x0000187E, 0x000500C7, 0x00000014, 0x0000499E, 0x00005AD9, 0x00000466, 0x000600A9, 0x00000014, + 0x00002AA7, 0x000040CD, 0x0000499E, 0x000048A0, 0x00050080, 0x00000014, 0x00005FFD, 0x00002873, + 0x000003FA, 0x000500C4, 0x00000014, 0x00004F83, 0x00005FFD, 0x00000189, 0x000500C4, 0x00000014, + 0x00003FAA, 0x00002AA7, 0x0000008D, 0x000500C5, 0x00000014, 0x00005780, 0x00004F83, 0x00003FAA, + 0x000500AA, 0x00000010, 0x00003604, 0x00005DEA, 0x00000A12, 0x000600A9, 0x00000014, 0x00004246, + 0x00003604, 0x00000A12, 0x00005780, 0x0004007C, 0x00000018, 0x000029D3, 0x00004246, 0x000500C2, + 0x0000000B, 0x00004BA8, 0x000056C0, 0x00000A64, 0x00040070, 0x0000000D, 0x00004812, 0x00004BA8, + 0x00050085, 0x0000000D, 0x00003E23, 0x00004812, 0x00000149, 0x00050051, 0x0000000D, 0x000053C6, + 0x000029D3, 0x00000000, 0x00050051, 0x0000000D, 0x00002A59, 0x000029D3, 0x00000001, 0x00050051, + 0x0000000D, 0x00001E9C, 0x000029D3, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDD, 0x000053C6, + 0x00002A59, 0x00001E9C, 0x00003E23, 0x00050051, 0x0000000B, 0x000027F8, 0x00002AC0, 0x00000001, + 0x00060050, 0x00000014, 0x00003511, 0x000027F8, 0x000027F8, 0x000027F8, 0x000500C2, 0x00000014, + 0x00002B13, 0x00003511, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEB, 0x00002B13, 0x00000105, + 0x000500C7, 0x00000014, 0x000048A1, 0x00005DEB, 0x00000466, 0x000500C2, 0x00000014, 0x00005B95, + 0x00005DEB, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CE, 0x00005B95, 0x00000A12, 0x0006000C, + 0x00000016, 0x00002C50, 0x00000001, 0x0000004B, 0x000048A1, 0x0004007C, 0x00000014, 0x00002A1A, + 0x00002C50, 0x00050082, 0x00000014, 0x0000187F, 0x00000B0C, 0x00002A1A, 0x00050080, 0x00000014, + 0x00002215, 0x00002A1A, 0x00000938, 0x000600A9, 0x00000014, 0x00002874, 0x000040CE, 0x00002215, + 0x00005B95, 0x000500C4, 0x00000014, 0x00005ADA, 0x000048A1, 0x0000187F, 0x000500C7, 0x00000014, + 0x0000499F, 0x00005ADA, 0x00000466, 0x000600A9, 0x00000014, 0x00002AA8, 0x000040CE, 0x0000499F, + 0x000048A1, 0x00050080, 0x00000014, 0x00005FFE, 0x00002874, 0x000003FA, 0x000500C4, 0x00000014, + 0x00004F84, 0x00005FFE, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAB, 0x00002AA8, 0x0000008D, + 0x000500C5, 0x00000014, 0x00005781, 0x00004F84, 0x00003FAB, 0x000500AA, 0x00000010, 0x00003605, + 0x00005DEB, 0x00000A12, 0x000600A9, 0x00000014, 0x00004247, 0x00003605, 0x00000A12, 0x00005781, + 0x0004007C, 0x00000018, 0x000029D4, 0x00004247, 0x000500C2, 0x0000000B, 0x00004BA9, 0x000027F8, + 0x00000A64, 0x00040070, 0x0000000D, 0x00004813, 0x00004BA9, 0x00050085, 0x0000000D, 0x00003E24, + 0x00004813, 0x00000149, 0x00050051, 0x0000000D, 0x000053C7, 0x000029D4, 0x00000000, 0x00050051, + 0x0000000D, 0x00002A5A, 0x000029D4, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9D, 0x000029D4, + 0x00000002, 0x00070050, 0x0000001D, 0x00003DDE, 0x000053C7, 0x00002A5A, 0x00001E9D, 0x00003E24, + 0x00050051, 0x0000000B, 0x000027F9, 0x00002AC0, 0x00000002, 0x00060050, 0x00000014, 0x00003512, + 0x000027F9, 0x000027F9, 0x000027F9, 0x000500C2, 0x00000014, 0x00002B14, 0x00003512, 0x00000BB4, + 0x000500C7, 0x00000014, 0x00005DEC, 0x00002B14, 0x00000105, 0x000500C7, 0x00000014, 0x000048A2, + 0x00005DEC, 0x00000466, 0x000500C2, 0x00000014, 0x00005B96, 0x00005DEC, 0x00000B0C, 0x000500AA, + 0x00000010, 0x000040CF, 0x00005B96, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C51, 0x00000001, + 0x0000004B, 0x000048A2, 0x0004007C, 0x00000014, 0x00002A1B, 0x00002C51, 0x00050082, 0x00000014, + 0x00001880, 0x00000B0C, 0x00002A1B, 0x00050080, 0x00000014, 0x00002216, 0x00002A1B, 0x00000938, + 0x000600A9, 0x00000014, 0x00002875, 0x000040CF, 0x00002216, 0x00005B96, 0x000500C4, 0x00000014, + 0x00005ADB, 0x000048A2, 0x00001880, 0x000500C7, 0x00000014, 0x000049A0, 0x00005ADB, 0x00000466, + 0x000600A9, 0x00000014, 0x00002AA9, 0x000040CF, 0x000049A0, 0x000048A2, 0x00050080, 0x00000014, + 0x00005FFF, 0x00002875, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F85, 0x00005FFF, 0x00000189, + 0x000500C4, 0x00000014, 0x00003FAC, 0x00002AA9, 0x0000008D, 0x000500C5, 0x00000014, 0x00005782, + 0x00004F85, 0x00003FAC, 0x000500AA, 0x00000010, 0x00003606, 0x00005DEC, 0x00000A12, 0x000600A9, + 0x00000014, 0x00004248, 0x00003606, 0x00000A12, 0x00005782, 0x0004007C, 0x00000018, 0x000029D5, + 0x00004248, 0x000500C2, 0x0000000B, 0x00004BAA, 0x000027F9, 0x00000A64, 0x00040070, 0x0000000D, + 0x00004814, 0x00004BAA, 0x00050085, 0x0000000D, 0x00003E25, 0x00004814, 0x00000149, 0x00050051, + 0x0000000D, 0x000053C8, 0x000029D5, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5B, 0x000029D5, + 0x00000001, 0x00050051, 0x0000000D, 0x00001E9E, 0x000029D5, 0x00000002, 0x00070050, 0x0000001D, + 0x00003DDF, 0x000053C8, 0x00002A5B, 0x00001E9E, 0x00003E25, 0x00050051, 0x0000000B, 0x000027FA, + 0x00002AC0, 0x00000003, 0x00060050, 0x00000014, 0x00003513, 0x000027FA, 0x000027FA, 0x000027FA, + 0x000500C2, 0x00000014, 0x00002B15, 0x00003513, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DED, + 0x00002B15, 0x00000105, 0x000500C7, 0x00000014, 0x000048A3, 0x00005DED, 0x00000466, 0x000500C2, + 0x00000014, 0x00005B97, 0x00005DED, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D0, 0x00005B97, + 0x00000A12, 0x0006000C, 0x00000016, 0x00002C52, 0x00000001, 0x0000004B, 0x000048A3, 0x0004007C, + 0x00000014, 0x00002A1C, 0x00002C52, 0x00050082, 0x00000014, 0x00001881, 0x00000B0C, 0x00002A1C, + 0x00050080, 0x00000014, 0x00002217, 0x00002A1C, 0x00000938, 0x000600A9, 0x00000014, 0x00002876, + 0x000040D0, 0x00002217, 0x00005B97, 0x000500C4, 0x00000014, 0x00005ADC, 0x000048A3, 0x00001881, + 0x000500C7, 0x00000014, 0x000049A1, 0x00005ADC, 0x00000466, 0x000600A9, 0x00000014, 0x00002AAA, + 0x000040D0, 0x000049A1, 0x000048A3, 0x00050080, 0x00000014, 0x00006000, 0x00002876, 0x000003FA, + 0x000500C4, 0x00000014, 0x00004F86, 0x00006000, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAD, + 0x00002AAA, 0x0000008D, 0x000500C5, 0x00000014, 0x00005783, 0x00004F86, 0x00003FAD, 0x000500AA, + 0x00000010, 0x00003607, 0x00005DED, 0x00000A12, 0x000600A9, 0x00000014, 0x00004249, 0x00003607, + 0x00000A12, 0x00005783, 0x0004007C, 0x00000018, 0x000029D6, 0x00004249, 0x000500C2, 0x0000000B, + 0x00004BAB, 0x000027FA, 0x00000A64, 0x00040070, 0x0000000D, 0x00004815, 0x00004BAB, 0x00050085, + 0x0000000D, 0x00003E26, 0x00004815, 0x00000149, 0x00050051, 0x0000000D, 0x000053C9, 0x000029D6, + 0x00000000, 0x00050051, 0x0000000D, 0x00002A5C, 0x000029D6, 0x00000001, 0x00050051, 0x0000000D, + 0x00002B16, 0x000029D6, 0x00000002, 0x00070050, 0x0000001D, 0x00002350, 0x000053C9, 0x00002A5C, + 0x00002B16, 0x00003E26, 0x000200F9, 0x00003F61, 0x000200F8, 0x00001CBD, 0x00050051, 0x0000000B, + 0x000056C1, 0x00002AC0, 0x00000000, 0x00070050, 0x00000017, 0x00004F0E, 0x000056C1, 0x000056C1, + 0x000056C1, 0x000056C1, 0x000500C2, 0x00000017, 0x000024A0, 0x00004F0E, 0x0000034D, 0x000500C7, + 0x00000017, 0x000049AF, 0x000024A0, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBA, 0x000049AF, + 0x00050085, 0x0000001D, 0x00004133, 0x00003CBA, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD5, + 0x00002AC0, 0x00000001, 0x00070050, 0x00000017, 0x00005150, 0x00005CD5, 0x00005CD5, 0x00005CD5, + 0x00005CD5, 0x000500C2, 0x00000017, 0x000024A1, 0x00005150, 0x0000034D, 0x000500C7, 0x00000017, + 0x000049B0, 0x000024A1, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBB, 0x000049B0, 0x00050085, + 0x0000001D, 0x00004134, 0x00003CBB, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD6, 0x00002AC0, + 0x00000002, 0x00070050, 0x00000017, 0x00005151, 0x00005CD6, 0x00005CD6, 0x00005CD6, 0x00005CD6, + 0x000500C2, 0x00000017, 0x000024A2, 0x00005151, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B1, + 0x000024A2, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBC, 0x000049B1, 0x00050085, 0x0000001D, + 0x00004135, 0x00003CBC, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD7, 0x00002AC0, 0x00000003, + 0x00070050, 0x00000017, 0x00005152, 0x00005CD7, 0x00005CD7, 0x00005CD7, 0x00005CD7, 0x000500C2, + 0x00000017, 0x000024A3, 0x00005152, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B2, 0x000024A3, + 0x0000027B, 0x00040070, 0x0000001D, 0x00004930, 0x000049B2, 0x00050085, 0x0000001D, 0x000026A0, + 0x00004930, 0x00000AEE, 0x000200F9, 0x00003F61, 0x000200F8, 0x000038FA, 0x00050051, 0x0000000B, + 0x000056C2, 0x00002AC0, 0x00000000, 0x00070050, 0x00000017, 0x00004F0F, 0x000056C2, 0x000056C2, + 0x000056C2, 0x000056C2, 0x000500C2, 0x00000017, 0x000024A4, 0x00004F0F, 0x0000028D, 0x000500C7, + 0x00000017, 0x00004A5A, 0x000024A4, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A5, 0x00004A5A, + 0x0005008E, 0x0000001D, 0x00004B26, 0x000036A5, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A2, + 0x00002AC0, 0x00000001, 0x00070050, 0x00000017, 0x0000610E, 0x000021A2, 0x000021A2, 0x000021A2, + 0x000021A2, 0x000500C2, 0x00000017, 0x000024A5, 0x0000610E, 0x0000028D, 0x000500C7, 0x00000017, + 0x00004A5B, 0x000024A5, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A6, 0x00004A5B, 0x0005008E, + 0x0000001D, 0x00004B27, 0x000036A6, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A3, 0x00002AC0, + 0x00000002, 0x00070050, 0x00000017, 0x0000610F, 0x000021A3, 0x000021A3, 0x000021A3, 0x000021A3, + 0x000500C2, 0x00000017, 0x000024A6, 0x0000610F, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5C, + 0x000024A6, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A8, 0x00004A5C, 0x0005008E, 0x0000001D, + 0x00004B28, 0x000036A8, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A4, 0x00002AC0, 0x00000003, + 0x00070050, 0x00000017, 0x00006110, 0x000021A4, 0x000021A4, 0x000021A4, 0x000021A4, 0x000500C2, + 0x00000017, 0x000024A7, 0x00006110, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5D, 0x000024A7, + 0x0000064B, 0x00040070, 0x0000001D, 0x0000431B, 0x00004A5D, 0x0005008E, 0x0000001D, 0x00003093, + 0x0000431B, 0x0000017A, 0x000200F9, 0x00003F61, 0x000200F8, 0x00004BFC, 0x00050051, 0x0000000B, + 0x0000308E, 0x00002AC0, 0x00000000, 0x0004007C, 0x0000000D, 0x00004FEF, 0x0000308E, 0x00050050, + 0x00000013, 0x00004339, 0x00004FEF, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D93, 0x00004339, + 0x00004339, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B4, + 0x00002AC0, 0x00000001, 0x0004007C, 0x0000000D, 0x00003F6B, 0x000056B4, 0x00050050, 0x00000013, + 0x0000433A, 0x00003F6B, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D94, 0x0000433A, 0x0000433A, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B5, 0x00002AC0, + 0x00000002, 0x0004007C, 0x0000000D, 0x00003F6C, 0x000056B5, 0x00050050, 0x00000013, 0x0000433B, + 0x00003F6C, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D95, 0x0000433B, 0x0000433B, 0x00000000, + 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B6, 0x00002AC0, 0x00000003, + 0x0004007C, 0x0000000D, 0x00003F6D, 0x000056B6, 0x00050050, 0x00000013, 0x00004FAF, 0x00003F6D, + 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3B, 0x00004FAF, 0x00004FAF, 0x00000000, 0x00000001, + 0x00000001, 0x00000001, 0x000200F9, 0x00003F61, 0x000200F8, 0x00003F61, 0x000F00F5, 0x0000001D, + 0x00002BAA, 0x00005A3B, 0x00004BFC, 0x00003093, 0x000038FA, 0x000026A0, 0x00001CBD, 0x00002350, + 0x00001CBC, 0x0000234F, 0x00001FFF, 0x0000234E, 0x00002035, 0x000F00F5, 0x0000001D, 0x0000380B, + 0x00002D95, 0x00004BFC, 0x00004B28, 0x000038FA, 0x00004135, 0x00001CBD, 0x00003DDF, 0x00001CBC, + 0x00004123, 0x00001FFF, 0x00003914, 0x00002035, 0x000F00F5, 0x0000001D, 0x00003B7F, 0x00002D94, + 0x00004BFC, 0x00004B27, 0x000038FA, 0x00004134, 0x00001CBD, 0x00003DDE, 0x00001CBC, 0x00004122, + 0x00001FFF, 0x00003913, 0x00002035, 0x000F00F5, 0x0000001D, 0x000038B8, 0x00002D93, 0x00004BFC, + 0x00004B26, 0x000038FA, 0x00004133, 0x00001CBD, 0x00003DDD, 0x00001CBC, 0x00004121, 0x00001FFF, + 0x00003912, 0x00002035, 0x000200F9, 0x00005310, 0x000200F8, 0x00003B66, 0x000500AA, 0x00000009, + 0x00005451, 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F25, 0x00000002, 0x000400FA, 0x00005451, + 0x00002625, 0x00002F64, 0x000200F8, 0x00002F64, 0x00060041, 0x00000288, 0x00004BD2, 0x00000CC7, + 0x00000A0B, 0x00005E78, 0x0004003D, 0x0000000B, 0x00005D49, 0x00004BD2, 0x00050080, 0x0000000B, + 0x00002DBA, 0x00005AD8, 0x00000AFD, 0x00060041, 0x00000288, 0x00001909, 0x00000CC7, 0x00000A0B, + 0x00002DBA, 0x0004003D, 0x0000000B, 0x00005C6F, 0x00001909, 0x00050080, 0x0000000B, 0x00002DBB, + 0x00005E78, 0x0000199B, 0x00060041, 0x00000288, 0x0000190A, 0x00000CC7, 0x00000A0B, 0x00002DBB, + 0x0004003D, 0x0000000B, 0x00005C70, 0x0000190A, 0x00050080, 0x0000000B, 0x00002DBC, 0x00002DBB, + 0x00000A0D, 0x00060041, 0x00000288, 0x00005FF4, 0x00000CC7, 0x00000A0B, 0x00002DBC, 0x0004003D, + 0x0000000B, 0x0000374D, 0x00005FF4, 0x00070050, 0x00000017, 0x00004CD7, 0x00005D49, 0x00005C6F, + 0x00005C70, 0x0000374D, 0x00050084, 0x0000000B, 0x00004299, 0x00000A10, 0x0000199B, 0x00050080, + 0x0000000B, 0x000036A9, 0x00005E78, 0x00004299, 0x00060041, 0x00000288, 0x00003B83, 0x00000CC7, + 0x00000A0B, 0x000036A9, 0x0004003D, 0x0000000B, 0x00005C71, 0x00003B83, 0x00050080, 0x0000000B, + 0x00002DBD, 0x000036A9, 0x00000A0D, 0x00060041, 0x00000288, 0x0000194E, 0x00000CC7, 0x00000A0B, + 0x00002DBD, 0x0004003D, 0x0000000B, 0x00005E60, 0x0000194E, 0x00050084, 0x0000000B, 0x0000185F, + 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A6, 0x00005E78, 0x0000185F, 0x00060041, + 0x00000288, 0x00003B84, 0x00000CC7, 0x00000A0B, 0x000020A6, 0x0004003D, 0x0000000B, 0x00005C72, + 0x00003B84, 0x00050080, 0x0000000B, 0x00002DBE, 0x000020A6, 0x00000A0D, 0x00060041, 0x00000288, + 0x00005FF5, 0x00000CC7, 0x00000A0B, 0x00002DBE, 0x0004003D, 0x0000000B, 0x00004001, 0x00005FF5, + 0x00070050, 0x00000017, 0x00005132, 0x00005C71, 0x00005E60, 0x00005C72, 0x00004001, 0x000200F9, + 0x00004F25, 0x000200F8, 0x00002625, 0x00060041, 0x00000288, 0x00005548, 0x00000CC7, 0x00000A0B, + 0x00005E78, 0x0004003D, 0x0000000B, 0x00005D4A, 0x00005548, 0x00050080, 0x0000000B, 0x00002DBF, + 0x00005AD8, 0x00000AFD, 0x00060041, 0x00000288, 0x0000190B, 0x00000CC7, 0x00000A0B, 0x00002DBF, + 0x0004003D, 0x0000000B, 0x00005C73, 0x0000190B, 0x00050080, 0x0000000B, 0x00002DC0, 0x00005AD8, + 0x00000B00, 0x00060041, 0x00000288, 0x0000190C, 0x00000CC7, 0x00000A0B, 0x00002DC0, 0x0004003D, + 0x0000000B, 0x00005C74, 0x0000190C, 0x00050080, 0x0000000B, 0x00002DC1, 0x00005AD8, 0x00000B03, + 0x00060041, 0x00000288, 0x00005FF6, 0x00000CC7, 0x00000A0B, 0x00002DC1, 0x0004003D, 0x0000000B, + 0x00003701, 0x00005FF6, 0x00070050, 0x00000017, 0x00004ADE, 0x00005D4A, 0x00005C73, 0x00005C74, + 0x00003701, 0x00050080, 0x0000000B, 0x000057E6, 0x00005AD8, 0x00000B06, 0x00060041, 0x00000288, + 0x0000604C, 0x00000CC7, 0x00000A0B, 0x000057E6, 0x0004003D, 0x0000000B, 0x00005C75, 0x0000604C, + 0x00050080, 0x0000000B, 0x00002DC2, 0x00005AD8, 0x00000B09, 0x00060041, 0x00000288, 0x0000190D, + 0x00000CC7, 0x00000A0B, 0x00002DC2, 0x0004003D, 0x0000000B, 0x00005C76, 0x0000190D, 0x00050080, + 0x0000000B, 0x00002DC3, 0x00005AD8, 0x00000B0D, 0x00060041, 0x00000288, 0x0000190E, 0x00000CC7, + 0x00000A0B, 0x00002DC3, 0x0004003D, 0x0000000B, 0x00005C77, 0x0000190E, 0x00050080, 0x0000000B, + 0x00002DC4, 0x00005AD8, 0x00000B0F, 0x00060041, 0x00000288, 0x00005FF7, 0x00000CC7, 0x00000A0B, + 0x00002DC4, 0x0004003D, 0x0000000B, 0x00004002, 0x00005FF7, 0x00070050, 0x00000017, 0x00005133, + 0x00005C75, 0x00005C76, 0x00005C77, 0x00004002, 0x000200F9, 0x00004F25, 0x000200F8, 0x00004F25, + 0x000700F5, 0x00000017, 0x00002BCE, 0x00005133, 0x00002625, 0x00005132, 0x00002F64, 0x000700F5, + 0x00000017, 0x00003721, 0x00004ADE, 0x00002625, 0x00004CD7, 0x00002F64, 0x000300F7, 0x00004F26, + 0x00000000, 0x000700FB, 0x00002180, 0x00004F57, 0x00000005, 0x00002159, 0x00000007, 0x00002036, + 0x000200F8, 0x00002036, 0x00050051, 0x0000000B, 0x00005F59, 0x00003721, 0x00000000, 0x0006000C, + 0x00000013, 0x0000606A, 0x00000001, 0x0000003E, 0x00005F59, 0x00050051, 0x0000000D, 0x00002779, + 0x0000606A, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBC, 0x0000606A, 0x00000001, 0x00050051, + 0x0000000B, 0x00004285, 0x00003721, 0x00000001, 0x0006000C, 0x00000013, 0x00003CF9, 0x00000001, + 0x0000003E, 0x00004285, 0x00050051, 0x0000000D, 0x0000276E, 0x00003CF9, 0x00000000, 0x00050051, + 0x0000000D, 0x0000444F, 0x00003CF9, 0x00000001, 0x00070050, 0x0000001D, 0x00003915, 0x00002779, + 0x00003EBC, 0x0000276E, 0x0000444F, 0x00050051, 0x0000000B, 0x00004383, 0x00003721, 0x00000002, + 0x0006000C, 0x00000013, 0x00004674, 0x00000001, 0x0000003E, 0x00004383, 0x00050051, 0x0000000D, + 0x0000277A, 0x00004674, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBD, 0x00004674, 0x00000001, + 0x00050051, 0x0000000B, 0x00004286, 0x00003721, 0x00000003, 0x0006000C, 0x00000013, 0x00003CFA, + 0x00000001, 0x0000003E, 0x00004286, 0x00050051, 0x0000000D, 0x0000276F, 0x00003CFA, 0x00000000, + 0x00050051, 0x0000000D, 0x00004450, 0x00003CFA, 0x00000001, 0x00070050, 0x0000001D, 0x00003916, + 0x0000277A, 0x00003EBD, 0x0000276F, 0x00004450, 0x00050051, 0x0000000B, 0x00004384, 0x00002BCE, + 0x00000000, 0x0006000C, 0x00000013, 0x00004675, 0x00000001, 0x0000003E, 0x00004384, 0x00050051, + 0x0000000D, 0x0000277B, 0x00004675, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBE, 0x00004675, + 0x00000001, 0x00050051, 0x0000000B, 0x00004287, 0x00002BCE, 0x00000001, 0x0006000C, 0x00000013, + 0x00003CFB, 0x00000001, 0x0000003E, 0x00004287, 0x00050051, 0x0000000D, 0x00002770, 0x00003CFB, + 0x00000000, 0x00050051, 0x0000000D, 0x00004451, 0x00003CFB, 0x00000001, 0x00070050, 0x0000001D, + 0x00003917, 0x0000277B, 0x00003EBE, 0x00002770, 0x00004451, 0x00050051, 0x0000000B, 0x00004385, + 0x00002BCE, 0x00000002, 0x0006000C, 0x00000013, 0x00004676, 0x00000001, 0x0000003E, 0x00004385, + 0x00050051, 0x0000000D, 0x0000277C, 0x00004676, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBF, + 0x00004676, 0x00000001, 0x00050051, 0x0000000B, 0x00004288, 0x00002BCE, 0x00000003, 0x0006000C, + 0x00000013, 0x00003CFC, 0x00000001, 0x0000003E, 0x00004288, 0x00050051, 0x0000000D, 0x00002771, + 0x00003CFC, 0x00000000, 0x00050051, 0x0000000D, 0x000050C1, 0x00003CFC, 0x00000001, 0x00070050, + 0x0000001D, 0x00002351, 0x0000277C, 0x00003EBF, 0x00002771, 0x000050C1, 0x000200F9, 0x00004F26, + 0x000200F8, 0x00002159, 0x0007004F, 0x00000011, 0x000025FC, 0x00003721, 0x00003721, 0x00000000, + 0x00000001, 0x0004007C, 0x00000012, 0x00005B3D, 0x000025FC, 0x0009004F, 0x0000001A, 0x000060D2, + 0x00005B3D, 0x00005B3D, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, + 0x000048AA, 0x000060D2, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D91, 0x000048AA, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002AAB, 0x00003D91, 0x0005008E, 0x0000001D, 0x00004725, 0x00002AAB, + 0x000007FE, 0x0007000C, 0x0000001D, 0x00006294, 0x00000001, 0x00000028, 0x00000504, 0x00004725, + 0x0007004F, 0x00000011, 0x0000376E, 0x00003721, 0x00003721, 0x00000002, 0x00000003, 0x0004007C, + 0x00000012, 0x000024C2, 0x0000376E, 0x0009004F, 0x0000001A, 0x000060D3, 0x000024C2, 0x000024C2, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048AB, 0x000060D3, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D92, 0x000048AB, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002AAC, 0x00003D92, 0x0005008E, 0x0000001D, 0x00004726, 0x00002AAC, 0x000007FE, 0x0007000C, + 0x0000001D, 0x00006295, 0x00000001, 0x00000028, 0x00000504, 0x00004726, 0x0007004F, 0x00000011, + 0x0000376F, 0x00002BCE, 0x00002BCE, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000024C3, + 0x0000376F, 0x0009004F, 0x0000001A, 0x000060D4, 0x000024C3, 0x000024C3, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048AC, 0x000060D4, 0x00000122, 0x000500C3, + 0x0000001A, 0x00003D93, 0x000048AC, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AAD, 0x00003D93, + 0x0005008E, 0x0000001D, 0x00004727, 0x00002AAD, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006296, + 0x00000001, 0x00000028, 0x00000504, 0x00004727, 0x0007004F, 0x00000011, 0x00003770, 0x00002BCE, + 0x00002BCE, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C4, 0x00003770, 0x0009004F, + 0x0000001A, 0x000060D5, 0x000024C4, 0x000024C4, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C4, 0x0000001A, 0x000048AD, 0x000060D5, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D94, + 0x000048AD, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AAE, 0x00003D94, 0x0005008E, 0x0000001D, + 0x000053C0, 0x00002AAE, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004363, 0x00000001, 0x00000028, + 0x00000504, 0x000053C0, 0x000200F9, 0x00004F26, 0x000200F8, 0x00004F57, 0x0007004F, 0x00000011, + 0x00002626, 0x00003721, 0x00003721, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x0000515A, + 0x00002626, 0x00050051, 0x0000000D, 0x00001B7F, 0x0000515A, 0x00000000, 0x00050051, 0x0000000D, + 0x0000346D, 0x0000515A, 0x00000001, 0x00070050, 0x0000001D, 0x0000427B, 0x00001B7F, 0x0000346D, + 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DB, 0x00003721, 0x00003721, 0x00000002, + 0x00000003, 0x0004007C, 0x00000013, 0x00003760, 0x000041DB, 0x00050051, 0x0000000D, 0x00001B80, + 0x00003760, 0x00000000, 0x00050051, 0x0000000D, 0x0000346E, 0x00003760, 0x00000001, 0x00070050, + 0x0000001D, 0x0000427C, 0x00001B80, 0x0000346E, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, + 0x000041DC, 0x00002BCE, 0x00002BCE, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x00003761, + 0x000041DC, 0x00050051, 0x0000000D, 0x00001B81, 0x00003761, 0x00000000, 0x00050051, 0x0000000D, + 0x0000346F, 0x00003761, 0x00000001, 0x00070050, 0x0000001D, 0x0000427D, 0x00001B81, 0x0000346F, + 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DD, 0x00002BCE, 0x00002BCE, 0x00000002, + 0x00000003, 0x0004007C, 0x00000013, 0x00003762, 0x000041DD, 0x00050051, 0x0000000D, 0x00001B82, + 0x00003762, 0x00000000, 0x00050051, 0x0000000D, 0x00004109, 0x00003762, 0x00000001, 0x00070050, + 0x0000001D, 0x00002352, 0x00001B82, 0x00004109, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F26, + 0x000200F8, 0x00004F26, 0x000900F5, 0x0000001D, 0x00002BAB, 0x00002352, 0x00004F57, 0x00004363, + 0x00002159, 0x00002351, 0x00002036, 0x000900F5, 0x0000001D, 0x0000380C, 0x0000427D, 0x00004F57, + 0x00006296, 0x00002159, 0x00003917, 0x00002036, 0x000900F5, 0x0000001D, 0x00003B80, 0x0000427C, + 0x00004F57, 0x00006295, 0x00002159, 0x00003916, 0x00002036, 0x000900F5, 0x0000001D, 0x000038B9, + 0x0000427B, 0x00004F57, 0x00006294, 0x00002159, 0x00003915, 0x00002036, 0x000200F9, 0x00005310, + 0x000200F8, 0x00005310, 0x000700F5, 0x0000001D, 0x00002BAC, 0x00002BAB, 0x00004F26, 0x00002BAA, + 0x00003F61, 0x000700F5, 0x0000001D, 0x0000380D, 0x0000380C, 0x00004F26, 0x0000380B, 0x00003F61, + 0x000700F5, 0x0000001D, 0x00003295, 0x00003B80, 0x00004F26, 0x00003B7F, 0x00003F61, 0x000700F5, + 0x0000001D, 0x0000367A, 0x000038B9, 0x00004F26, 0x000038B8, 0x00003F61, 0x00050081, 0x0000001D, + 0x00004359, 0x000020D3, 0x0000367A, 0x00050081, 0x0000001D, 0x00005B01, 0x000035EC, 0x00003295, + 0x00050081, 0x0000001D, 0x00001F92, 0x0000380A, 0x0000380D, 0x00050081, 0x0000001D, 0x00005113, + 0x00002BA9, 0x00002BAC, 0x000500AE, 0x00000009, 0x0000387D, 0x00003F4D, 0x00000A1C, 0x000300F7, + 0x00005EC8, 0x00000002, 0x000400FA, 0x0000387D, 0x000026B1, 0x00005EC8, 0x000200F8, 0x000026B1, + 0x000500C4, 0x0000000B, 0x000037B2, 0x00000A0D, 0x000023AA, 0x00050085, 0x0000000D, 0x00002F3A, + 0x00002B2C, 0x0000016E, 0x00050080, 0x0000000B, 0x000051FC, 0x00005AD8, 0x000037B2, 0x000300F7, + 0x00005311, 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B67, 0x000040BB, 0x000200F8, 0x000040BB, + 0x000500AA, 0x00000009, 0x00004ADF, 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F4B, 0x00000002, + 0x000400FA, 0x00004ADF, 0x00002627, 0x00002F65, 0x000200F8, 0x00002F65, 0x00060041, 0x00000288, + 0x00004BD3, 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, 0x00005D4B, 0x00004BD3, + 0x00050080, 0x0000000B, 0x00002DC5, 0x000051FC, 0x0000199B, 0x00060041, 0x00000288, 0x0000194F, + 0x00000CC7, 0x00000A0B, 0x00002DC5, 0x0004003D, 0x0000000B, 0x00005E61, 0x0000194F, 0x00050084, + 0x0000000B, 0x00001860, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A7, 0x000051FC, + 0x00001860, 0x00060041, 0x00000288, 0x00003BCF, 0x00000CC7, 0x00000A0B, 0x000020A7, 0x0004003D, + 0x0000000B, 0x00005E62, 0x00003BCF, 0x00050084, 0x0000000B, 0x00001861, 0x00000A13, 0x0000199B, + 0x00050080, 0x0000000B, 0x000020A8, 0x000051FC, 0x00001861, 0x00060041, 0x00000288, 0x000037F3, + 0x00000CC7, 0x00000A0B, 0x000020A8, 0x0004003D, 0x0000000B, 0x00004003, 0x000037F3, 0x00070050, + 0x00000017, 0x00005134, 0x00005D4B, 0x00005E61, 0x00005E62, 0x00004003, 0x000200F9, 0x00004F4B, + 0x000200F8, 0x00002627, 0x00060041, 0x00000288, 0x00005549, 0x00000CC7, 0x00000A0B, 0x000051FC, + 0x0004003D, 0x0000000B, 0x00005D4C, 0x00005549, 0x00050080, 0x0000000B, 0x00002DC6, 0x000051FC, + 0x00000A0D, 0x00060041, 0x00000288, 0x0000190F, 0x00000CC7, 0x00000A0B, 0x00002DC6, 0x0004003D, + 0x0000000B, 0x00005C78, 0x0000190F, 0x00050080, 0x0000000B, 0x00002DC7, 0x000051FC, 0x00000A10, + 0x00060041, 0x00000288, 0x00001910, 0x00000CC7, 0x00000A0B, 0x00002DC7, 0x0004003D, 0x0000000B, + 0x00005C79, 0x00001910, 0x00050080, 0x0000000B, 0x00002DC8, 0x000051FC, 0x00000A13, 0x00060041, + 0x00000288, 0x00005FF8, 0x00000CC7, 0x00000A0B, 0x00002DC8, 0x0004003D, 0x0000000B, 0x00004004, + 0x00005FF8, 0x00070050, 0x00000017, 0x00005135, 0x00005D4C, 0x00005C78, 0x00005C79, 0x00004004, + 0x000200F9, 0x00004F4B, 0x000200F8, 0x00004F4B, 0x000700F5, 0x00000017, 0x00002AC1, 0x00005135, + 0x00002627, 0x00005134, 0x00002F65, 0x000300F7, 0x00003F62, 0x00000000, 0x001300FB, 0x00002180, + 0x00004BFD, 0x00000000, 0x000038FB, 0x00000001, 0x000038FB, 0x00000002, 0x00001CBF, 0x0000000A, + 0x00001CBF, 0x00000003, 0x00001CBE, 0x0000000C, 0x00001CBE, 0x00000004, 0x00002000, 0x00000006, + 0x00002037, 0x000200F8, 0x00002037, 0x00050051, 0x0000000B, 0x00005F5A, 0x00002AC1, 0x00000000, + 0x0006000C, 0x00000013, 0x0000606B, 0x00000001, 0x0000003E, 0x00005F5A, 0x00050051, 0x0000000D, + 0x00002772, 0x0000606B, 0x00000000, 0x00050051, 0x0000000D, 0x00004452, 0x0000606B, 0x00000001, + 0x00070050, 0x0000001D, 0x00003918, 0x00002772, 0x00004452, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x00004386, 0x00002AC1, 0x00000001, 0x0006000C, 0x00000013, 0x00004677, 0x00000001, + 0x0000003E, 0x00004386, 0x00050051, 0x0000000D, 0x00002773, 0x00004677, 0x00000000, 0x00050051, + 0x0000000D, 0x00004453, 0x00004677, 0x00000001, 0x00070050, 0x0000001D, 0x00003919, 0x00002773, + 0x00004453, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004387, 0x00002AC1, 0x00000002, + 0x0006000C, 0x00000013, 0x00004678, 0x00000001, 0x0000003E, 0x00004387, 0x00050051, 0x0000000D, + 0x00002774, 0x00004678, 0x00000000, 0x00050051, 0x0000000D, 0x00004454, 0x00004678, 0x00000001, + 0x00070050, 0x0000001D, 0x0000391A, 0x00002774, 0x00004454, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x00004388, 0x00002AC1, 0x00000003, 0x0006000C, 0x00000013, 0x00004679, 0x00000001, + 0x0000003E, 0x00004388, 0x00050051, 0x0000000D, 0x0000277D, 0x00004679, 0x00000000, 0x00050051, + 0x0000000D, 0x000050C2, 0x00004679, 0x00000001, 0x00070050, 0x0000001D, 0x00002353, 0x0000277D, + 0x000050C2, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F62, 0x000200F8, 0x00002000, 0x00050051, + 0x0000000B, 0x0000308F, 0x00002AC1, 0x00000000, 0x0004007C, 0x0000000C, 0x0000589F, 0x0000308F, + 0x00050050, 0x00000012, 0x00004728, 0x0000589F, 0x0000589F, 0x000500C4, 0x00000012, 0x000047B5, + 0x00004728, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341F, 0x000047B5, 0x00000867, 0x0004006F, + 0x00000013, 0x00002AAF, 0x0000341F, 0x0005008E, 0x00000013, 0x0000474F, 0x00002AAF, 0x000007FE, + 0x0007000C, 0x00000013, 0x00005E0E, 0x00000001, 0x00000028, 0x00000049, 0x0000474F, 0x00050051, + 0x0000000D, 0x00005F12, 0x00005E0E, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDA, 0x00005E0E, + 0x00000001, 0x00070050, 0x0000001D, 0x00004124, 0x00005F12, 0x00003CDA, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x00004C48, 0x00002AC1, 0x00000001, 0x0004007C, 0x0000000C, 0x00003EA7, + 0x00004C48, 0x00050050, 0x00000012, 0x00004729, 0x00003EA7, 0x00003EA7, 0x000500C4, 0x00000012, + 0x000047B6, 0x00004729, 0x000007A7, 0x000500C3, 0x00000012, 0x00003420, 0x000047B6, 0x00000867, + 0x0004006F, 0x00000013, 0x00002AB0, 0x00003420, 0x0005008E, 0x00000013, 0x00004750, 0x00002AB0, + 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0F, 0x00000001, 0x00000028, 0x00000049, 0x00004750, + 0x00050051, 0x0000000D, 0x00005F13, 0x00005E0F, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDB, + 0x00005E0F, 0x00000001, 0x00070050, 0x0000001D, 0x00004125, 0x00005F13, 0x00003CDB, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C49, 0x00002AC1, 0x00000002, 0x0004007C, 0x0000000C, + 0x00003EA8, 0x00004C49, 0x00050050, 0x00000012, 0x0000472A, 0x00003EA8, 0x00003EA8, 0x000500C4, + 0x00000012, 0x000047B7, 0x0000472A, 0x000007A7, 0x000500C3, 0x00000012, 0x00003421, 0x000047B7, + 0x00000867, 0x0004006F, 0x00000013, 0x00002AB1, 0x00003421, 0x0005008E, 0x00000013, 0x00004751, + 0x00002AB1, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E10, 0x00000001, 0x00000028, 0x00000049, + 0x00004751, 0x00050051, 0x0000000D, 0x00005F14, 0x00005E10, 0x00000000, 0x00050051, 0x0000000D, + 0x00003CDC, 0x00005E10, 0x00000001, 0x00070050, 0x0000001D, 0x00004126, 0x00005F14, 0x00003CDC, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C4A, 0x00002AC1, 0x00000003, 0x0004007C, + 0x0000000C, 0x00003EA9, 0x00004C4A, 0x00050050, 0x00000012, 0x0000472B, 0x00003EA9, 0x00003EA9, + 0x000500C4, 0x00000012, 0x000047B8, 0x0000472B, 0x000007A7, 0x000500C3, 0x00000012, 0x00003422, + 0x000047B8, 0x00000867, 0x0004006F, 0x00000013, 0x00002AB2, 0x00003422, 0x0005008E, 0x00000013, + 0x00004752, 0x00002AB2, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E11, 0x00000001, 0x00000028, + 0x00000049, 0x00004752, 0x00050051, 0x0000000D, 0x00005F15, 0x00005E11, 0x00000000, 0x00050051, + 0x0000000D, 0x0000494E, 0x00005E11, 0x00000001, 0x00070050, 0x0000001D, 0x00002354, 0x00005F15, + 0x0000494E, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F62, 0x000200F8, 0x00001CBE, 0x00050051, + 0x0000000B, 0x000056C3, 0x00002AC1, 0x00000000, 0x00060050, 0x00000014, 0x00004F10, 0x000056C3, + 0x000056C3, 0x000056C3, 0x000500C2, 0x00000014, 0x00002B17, 0x00004F10, 0x00000BB4, 0x000500C7, + 0x00000014, 0x00005DEE, 0x00002B17, 0x00000105, 0x000500C7, 0x00000014, 0x000048A4, 0x00005DEE, + 0x00000466, 0x000500C2, 0x00000014, 0x00005B98, 0x00005DEE, 0x00000B0C, 0x000500AA, 0x00000010, + 0x000040D1, 0x00005B98, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C53, 0x00000001, 0x0000004B, + 0x000048A4, 0x0004007C, 0x00000014, 0x00002A1D, 0x00002C53, 0x00050082, 0x00000014, 0x00001882, + 0x00000B0C, 0x00002A1D, 0x00050080, 0x00000014, 0x00002218, 0x00002A1D, 0x00000938, 0x000600A9, + 0x00000014, 0x00002877, 0x000040D1, 0x00002218, 0x00005B98, 0x000500C4, 0x00000014, 0x00005ADD, + 0x000048A4, 0x00001882, 0x000500C7, 0x00000014, 0x000049A2, 0x00005ADD, 0x00000466, 0x000600A9, + 0x00000014, 0x00002AB3, 0x000040D1, 0x000049A2, 0x000048A4, 0x00050080, 0x00000014, 0x00006001, + 0x00002877, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F87, 0x00006001, 0x00000189, 0x000500C4, + 0x00000014, 0x00003FAE, 0x00002AB3, 0x0000008D, 0x000500C5, 0x00000014, 0x00005784, 0x00004F87, + 0x00003FAE, 0x000500AA, 0x00000010, 0x00003608, 0x00005DEE, 0x00000A12, 0x000600A9, 0x00000014, + 0x0000424A, 0x00003608, 0x00000A12, 0x00005784, 0x0004007C, 0x00000018, 0x000029D7, 0x0000424A, + 0x000500C2, 0x0000000B, 0x00004BAC, 0x000056C3, 0x00000A64, 0x00040070, 0x0000000D, 0x00004816, + 0x00004BAC, 0x00050085, 0x0000000D, 0x00003E27, 0x00004816, 0x00000149, 0x00050051, 0x0000000D, + 0x000053CA, 0x000029D7, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5D, 0x000029D7, 0x00000001, + 0x00050051, 0x0000000D, 0x00001E9F, 0x000029D7, 0x00000002, 0x00070050, 0x0000001D, 0x00003DE0, + 0x000053CA, 0x00002A5D, 0x00001E9F, 0x00003E27, 0x00050051, 0x0000000B, 0x000027FB, 0x00002AC1, + 0x00000001, 0x00060050, 0x00000014, 0x00003514, 0x000027FB, 0x000027FB, 0x000027FB, 0x000500C2, + 0x00000014, 0x00002B18, 0x00003514, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEF, 0x00002B18, + 0x00000105, 0x000500C7, 0x00000014, 0x000048A5, 0x00005DEF, 0x00000466, 0x000500C2, 0x00000014, + 0x00005B99, 0x00005DEF, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D2, 0x00005B99, 0x00000A12, + 0x0006000C, 0x00000016, 0x00002C54, 0x00000001, 0x0000004B, 0x000048A5, 0x0004007C, 0x00000014, + 0x00002A1E, 0x00002C54, 0x00050082, 0x00000014, 0x00001883, 0x00000B0C, 0x00002A1E, 0x00050080, + 0x00000014, 0x00002219, 0x00002A1E, 0x00000938, 0x000600A9, 0x00000014, 0x00002878, 0x000040D2, + 0x00002219, 0x00005B99, 0x000500C4, 0x00000014, 0x00005ADE, 0x000048A5, 0x00001883, 0x000500C7, + 0x00000014, 0x000049A3, 0x00005ADE, 0x00000466, 0x000600A9, 0x00000014, 0x00002AB4, 0x000040D2, + 0x000049A3, 0x000048A5, 0x00050080, 0x00000014, 0x00006002, 0x00002878, 0x000003FA, 0x000500C4, + 0x00000014, 0x00004F88, 0x00006002, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAF, 0x00002AB4, + 0x0000008D, 0x000500C5, 0x00000014, 0x00005785, 0x00004F88, 0x00003FAF, 0x000500AA, 0x00000010, + 0x00003609, 0x00005DEF, 0x00000A12, 0x000600A9, 0x00000014, 0x0000424B, 0x00003609, 0x00000A12, + 0x00005785, 0x0004007C, 0x00000018, 0x000029D8, 0x0000424B, 0x000500C2, 0x0000000B, 0x00004BAD, + 0x000027FB, 0x00000A64, 0x00040070, 0x0000000D, 0x00004817, 0x00004BAD, 0x00050085, 0x0000000D, + 0x00003E28, 0x00004817, 0x00000149, 0x00050051, 0x0000000D, 0x000053CB, 0x000029D8, 0x00000000, + 0x00050051, 0x0000000D, 0x00002A5E, 0x000029D8, 0x00000001, 0x00050051, 0x0000000D, 0x00001EA0, + 0x000029D8, 0x00000002, 0x00070050, 0x0000001D, 0x00003DE1, 0x000053CB, 0x00002A5E, 0x00001EA0, + 0x00003E28, 0x00050051, 0x0000000B, 0x000027FC, 0x00002AC1, 0x00000002, 0x00060050, 0x00000014, + 0x00003515, 0x000027FC, 0x000027FC, 0x000027FC, 0x000500C2, 0x00000014, 0x00002B19, 0x00003515, + 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF0, 0x00002B19, 0x00000105, 0x000500C7, 0x00000014, + 0x000048AE, 0x00005DF0, 0x00000466, 0x000500C2, 0x00000014, 0x00005B9A, 0x00005DF0, 0x00000B0C, + 0x000500AA, 0x00000010, 0x000040D3, 0x00005B9A, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C55, + 0x00000001, 0x0000004B, 0x000048AE, 0x0004007C, 0x00000014, 0x00002A1F, 0x00002C55, 0x00050082, + 0x00000014, 0x00001884, 0x00000B0C, 0x00002A1F, 0x00050080, 0x00000014, 0x0000221A, 0x00002A1F, + 0x00000938, 0x000600A9, 0x00000014, 0x00002879, 0x000040D3, 0x0000221A, 0x00005B9A, 0x000500C4, + 0x00000014, 0x00005ADF, 0x000048AE, 0x00001884, 0x000500C7, 0x00000014, 0x000049A4, 0x00005ADF, + 0x00000466, 0x000600A9, 0x00000014, 0x00002AB5, 0x000040D3, 0x000049A4, 0x000048AE, 0x00050080, + 0x00000014, 0x00006003, 0x00002879, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F89, 0x00006003, + 0x00000189, 0x000500C4, 0x00000014, 0x00003FB0, 0x00002AB5, 0x0000008D, 0x000500C5, 0x00000014, + 0x00005786, 0x00004F89, 0x00003FB0, 0x000500AA, 0x00000010, 0x0000360A, 0x00005DF0, 0x00000A12, + 0x000600A9, 0x00000014, 0x0000424C, 0x0000360A, 0x00000A12, 0x00005786, 0x0004007C, 0x00000018, + 0x000029D9, 0x0000424C, 0x000500C2, 0x0000000B, 0x00004BAE, 0x000027FC, 0x00000A64, 0x00040070, + 0x0000000D, 0x00004818, 0x00004BAE, 0x00050085, 0x0000000D, 0x00003E29, 0x00004818, 0x00000149, + 0x00050051, 0x0000000D, 0x000053CC, 0x000029D9, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5F, + 0x000029D9, 0x00000001, 0x00050051, 0x0000000D, 0x00001EA1, 0x000029D9, 0x00000002, 0x00070050, + 0x0000001D, 0x00003DE2, 0x000053CC, 0x00002A5F, 0x00001EA1, 0x00003E29, 0x00050051, 0x0000000B, + 0x000027FD, 0x00002AC1, 0x00000003, 0x00060050, 0x00000014, 0x00003516, 0x000027FD, 0x000027FD, + 0x000027FD, 0x000500C2, 0x00000014, 0x00002B1A, 0x00003516, 0x00000BB4, 0x000500C7, 0x00000014, + 0x00005DF1, 0x00002B1A, 0x00000105, 0x000500C7, 0x00000014, 0x000048AF, 0x00005DF1, 0x00000466, + 0x000500C2, 0x00000014, 0x00005B9B, 0x00005DF1, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D4, + 0x00005B9B, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C56, 0x00000001, 0x0000004B, 0x000048AF, + 0x0004007C, 0x00000014, 0x00002A20, 0x00002C56, 0x00050082, 0x00000014, 0x00001885, 0x00000B0C, + 0x00002A20, 0x00050080, 0x00000014, 0x0000221B, 0x00002A20, 0x00000938, 0x000600A9, 0x00000014, + 0x0000287A, 0x000040D4, 0x0000221B, 0x00005B9B, 0x000500C4, 0x00000014, 0x00005AE0, 0x000048AF, + 0x00001885, 0x000500C7, 0x00000014, 0x000049A5, 0x00005AE0, 0x00000466, 0x000600A9, 0x00000014, + 0x00002AB6, 0x000040D4, 0x000049A5, 0x000048AF, 0x00050080, 0x00000014, 0x00006004, 0x0000287A, + 0x000003FA, 0x000500C4, 0x00000014, 0x00004F8A, 0x00006004, 0x00000189, 0x000500C4, 0x00000014, + 0x00003FB1, 0x00002AB6, 0x0000008D, 0x000500C5, 0x00000014, 0x00005787, 0x00004F8A, 0x00003FB1, + 0x000500AA, 0x00000010, 0x0000360B, 0x00005DF1, 0x00000A12, 0x000600A9, 0x00000014, 0x0000424D, + 0x0000360B, 0x00000A12, 0x00005787, 0x0004007C, 0x00000018, 0x000029DA, 0x0000424D, 0x000500C2, + 0x0000000B, 0x00004BAF, 0x000027FD, 0x00000A64, 0x00040070, 0x0000000D, 0x00004819, 0x00004BAF, + 0x00050085, 0x0000000D, 0x00003E2A, 0x00004819, 0x00000149, 0x00050051, 0x0000000D, 0x000053CD, + 0x000029DA, 0x00000000, 0x00050051, 0x0000000D, 0x00002A60, 0x000029DA, 0x00000001, 0x00050051, + 0x0000000D, 0x00002B1B, 0x000029DA, 0x00000002, 0x00070050, 0x0000001D, 0x00002355, 0x000053CD, + 0x00002A60, 0x00002B1B, 0x00003E2A, 0x000200F9, 0x00003F62, 0x000200F8, 0x00001CBF, 0x00050051, + 0x0000000B, 0x000056C4, 0x00002AC1, 0x00000000, 0x00070050, 0x00000017, 0x00004F11, 0x000056C4, + 0x000056C4, 0x000056C4, 0x000056C4, 0x000500C2, 0x00000017, 0x000024A8, 0x00004F11, 0x0000034D, + 0x000500C7, 0x00000017, 0x000049B3, 0x000024A8, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBD, + 0x000049B3, 0x00050085, 0x0000001D, 0x00004136, 0x00003CBD, 0x00000AEE, 0x00050051, 0x0000000B, + 0x00005CD8, 0x00002AC1, 0x00000001, 0x00070050, 0x00000017, 0x00005153, 0x00005CD8, 0x00005CD8, + 0x00005CD8, 0x00005CD8, 0x000500C2, 0x00000017, 0x000024A9, 0x00005153, 0x0000034D, 0x000500C7, + 0x00000017, 0x000049B4, 0x000024A9, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBE, 0x000049B4, + 0x00050085, 0x0000001D, 0x00004137, 0x00003CBE, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD9, + 0x00002AC1, 0x00000002, 0x00070050, 0x00000017, 0x00005154, 0x00005CD9, 0x00005CD9, 0x00005CD9, + 0x00005CD9, 0x000500C2, 0x00000017, 0x000024AA, 0x00005154, 0x0000034D, 0x000500C7, 0x00000017, + 0x000049B5, 0x000024AA, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBF, 0x000049B5, 0x00050085, + 0x0000001D, 0x00004138, 0x00003CBF, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CDA, 0x00002AC1, + 0x00000003, 0x00070050, 0x00000017, 0x00005155, 0x00005CDA, 0x00005CDA, 0x00005CDA, 0x00005CDA, + 0x000500C2, 0x00000017, 0x000024AB, 0x00005155, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B6, + 0x000024AB, 0x0000027B, 0x00040070, 0x0000001D, 0x00004931, 0x000049B6, 0x00050085, 0x0000001D, + 0x000026A1, 0x00004931, 0x00000AEE, 0x000200F9, 0x00003F62, 0x000200F8, 0x000038FB, 0x00050051, + 0x0000000B, 0x000056C5, 0x00002AC1, 0x00000000, 0x00070050, 0x00000017, 0x00004F12, 0x000056C5, + 0x000056C5, 0x000056C5, 0x000056C5, 0x000500C2, 0x00000017, 0x000024AC, 0x00004F12, 0x0000028D, + 0x000500C7, 0x00000017, 0x00004A5E, 0x000024AC, 0x0000064B, 0x00040070, 0x0000001D, 0x000036AA, + 0x00004A5E, 0x0005008E, 0x0000001D, 0x00004B29, 0x000036AA, 0x0000017A, 0x00050051, 0x0000000B, + 0x000021A5, 0x00002AC1, 0x00000001, 0x00070050, 0x00000017, 0x00006111, 0x000021A5, 0x000021A5, + 0x000021A5, 0x000021A5, 0x000500C2, 0x00000017, 0x000024AD, 0x00006111, 0x0000028D, 0x000500C7, + 0x00000017, 0x00004A5F, 0x000024AD, 0x0000064B, 0x00040070, 0x0000001D, 0x000036AB, 0x00004A5F, + 0x0005008E, 0x0000001D, 0x00004B2A, 0x000036AB, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A6, + 0x00002AC1, 0x00000002, 0x00070050, 0x00000017, 0x00006112, 0x000021A6, 0x000021A6, 0x000021A6, + 0x000021A6, 0x000500C2, 0x00000017, 0x000024AE, 0x00006112, 0x0000028D, 0x000500C7, 0x00000017, + 0x00004A60, 0x000024AE, 0x0000064B, 0x00040070, 0x0000001D, 0x000036AC, 0x00004A60, 0x0005008E, + 0x0000001D, 0x00004B2B, 0x000036AC, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A7, 0x00002AC1, + 0x00000003, 0x00070050, 0x00000017, 0x00006113, 0x000021A7, 0x000021A7, 0x000021A7, 0x000021A7, + 0x000500C2, 0x00000017, 0x000024AF, 0x00006113, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A61, + 0x000024AF, 0x0000064B, 0x00040070, 0x0000001D, 0x0000431C, 0x00004A61, 0x0005008E, 0x0000001D, + 0x00003094, 0x0000431C, 0x0000017A, 0x000200F9, 0x00003F62, 0x000200F8, 0x00004BFD, 0x00050051, + 0x0000000B, 0x00003090, 0x00002AC1, 0x00000000, 0x0004007C, 0x0000000D, 0x00004FF0, 0x00003090, + 0x00050050, 0x00000013, 0x0000433C, 0x00004FF0, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D96, + 0x0000433C, 0x0000433C, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, + 0x000056B7, 0x00002AC1, 0x00000001, 0x0004007C, 0x0000000D, 0x00003F6E, 0x000056B7, 0x00050050, + 0x00000013, 0x0000433D, 0x00003F6E, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D97, 0x0000433D, + 0x0000433D, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B8, + 0x00002AC1, 0x00000002, 0x0004007C, 0x0000000D, 0x00003F6F, 0x000056B8, 0x00050050, 0x00000013, + 0x0000433E, 0x00003F6F, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D98, 0x0000433E, 0x0000433E, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B9, 0x00002AC1, + 0x00000003, 0x0004007C, 0x0000000D, 0x00003F70, 0x000056B9, 0x00050050, 0x00000013, 0x00004FB0, + 0x00003F70, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3C, 0x00004FB0, 0x00004FB0, 0x00000000, + 0x00000001, 0x00000001, 0x00000001, 0x000200F9, 0x00003F62, 0x000200F8, 0x00003F62, 0x000F00F5, + 0x0000001D, 0x00002BAD, 0x00005A3C, 0x00004BFD, 0x00003094, 0x000038FB, 0x000026A1, 0x00001CBF, + 0x00002355, 0x00001CBE, 0x00002354, 0x00002000, 0x00002353, 0x00002037, 0x000F00F5, 0x0000001D, + 0x0000380E, 0x00002D98, 0x00004BFD, 0x00004B2B, 0x000038FB, 0x00004138, 0x00001CBF, 0x00003DE2, + 0x00001CBE, 0x00004126, 0x00002000, 0x0000391A, 0x00002037, 0x000F00F5, 0x0000001D, 0x00003B85, + 0x00002D97, 0x00004BFD, 0x00004B2A, 0x000038FB, 0x00004137, 0x00001CBF, 0x00003DE1, 0x00001CBE, + 0x00004125, 0x00002000, 0x00003919, 0x00002037, 0x000F00F5, 0x0000001D, 0x000038BA, 0x00002D96, + 0x00004BFD, 0x00004B29, 0x000038FB, 0x00004136, 0x00001CBF, 0x00003DE0, 0x00001CBE, 0x00004124, + 0x00002000, 0x00003918, 0x00002037, 0x000200F9, 0x00005311, 0x000200F8, 0x00003B67, 0x000500AA, + 0x00000009, 0x00005452, 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F27, 0x00000002, 0x000400FA, + 0x00005452, 0x00002628, 0x00002F66, 0x000200F8, 0x00002F66, 0x00060041, 0x00000288, 0x00004BD4, + 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, 0x00005D4D, 0x00004BD4, 0x00050080, + 0x0000000B, 0x00002DC9, 0x000051FC, 0x00000A0D, 0x00060041, 0x00000288, 0x00001911, 0x00000CC7, + 0x00000A0B, 0x00002DC9, 0x0004003D, 0x0000000B, 0x00005C7A, 0x00001911, 0x00050080, 0x0000000B, + 0x00002DCA, 0x000051FC, 0x0000199B, 0x00060041, 0x00000288, 0x00001912, 0x00000CC7, 0x00000A0B, + 0x00002DCA, 0x0004003D, 0x0000000B, 0x00005C7B, 0x00001912, 0x00050080, 0x0000000B, 0x00002DCB, + 0x00002DCA, 0x00000A0D, 0x00060041, 0x00000288, 0x00006005, 0x00000CC7, 0x00000A0B, 0x00002DCB, + 0x0004003D, 0x0000000B, 0x0000374E, 0x00006005, 0x00070050, 0x00000017, 0x00004CD9, 0x00005D4D, + 0x00005C7A, 0x00005C7B, 0x0000374E, 0x00050084, 0x0000000B, 0x0000429A, 0x00000A10, 0x0000199B, + 0x00050080, 0x0000000B, 0x000036AD, 0x000051FC, 0x0000429A, 0x00060041, 0x00000288, 0x00003B86, + 0x00000CC7, 0x00000A0B, 0x000036AD, 0x0004003D, 0x0000000B, 0x00005C7C, 0x00003B86, 0x00050080, + 0x0000000B, 0x00002DCC, 0x000036AD, 0x00000A0D, 0x00060041, 0x00000288, 0x00001950, 0x00000CC7, + 0x00000A0B, 0x00002DCC, 0x0004003D, 0x0000000B, 0x00005E63, 0x00001950, 0x00050084, 0x0000000B, + 0x00001862, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A9, 0x000051FC, 0x00001862, + 0x00060041, 0x00000288, 0x00003B87, 0x00000CC7, 0x00000A0B, 0x000020A9, 0x0004003D, 0x0000000B, + 0x00005C7D, 0x00003B87, 0x00050080, 0x0000000B, 0x00002DCD, 0x000020A9, 0x00000A0D, 0x00060041, + 0x00000288, 0x00006006, 0x00000CC7, 0x00000A0B, 0x00002DCD, 0x0004003D, 0x0000000B, 0x00004005, + 0x00006006, 0x00070050, 0x00000017, 0x00005136, 0x00005C7C, 0x00005E63, 0x00005C7D, 0x00004005, + 0x000200F9, 0x00004F27, 0x000200F8, 0x00002628, 0x00060041, 0x00000288, 0x0000554A, 0x00000CC7, + 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, 0x00005D4E, 0x0000554A, 0x00050080, 0x0000000B, + 0x00002DCE, 0x000051FC, 0x00000A0D, 0x00060041, 0x00000288, 0x00001913, 0x00000CC7, 0x00000A0B, + 0x00002DCE, 0x0004003D, 0x0000000B, 0x00005C7E, 0x00001913, 0x00050080, 0x0000000B, 0x00002DCF, + 0x000051FC, 0x00000A10, 0x00060041, 0x00000288, 0x00001914, 0x00000CC7, 0x00000A0B, 0x00002DCF, + 0x0004003D, 0x0000000B, 0x00005C7F, 0x00001914, 0x00050080, 0x0000000B, 0x00002DD0, 0x000051FC, + 0x00000A13, 0x00060041, 0x00000288, 0x00006007, 0x00000CC7, 0x00000A0B, 0x00002DD0, 0x0004003D, + 0x0000000B, 0x00003702, 0x00006007, 0x00070050, 0x00000017, 0x00004AE0, 0x00005D4E, 0x00005C7E, + 0x00005C7F, 0x00003702, 0x00050080, 0x0000000B, 0x000057E7, 0x000051FC, 0x00000A16, 0x00060041, + 0x00000288, 0x0000604D, 0x00000CC7, 0x00000A0B, 0x000057E7, 0x0004003D, 0x0000000B, 0x00005C80, + 0x0000604D, 0x00050080, 0x0000000B, 0x00002DD1, 0x000051FC, 0x00000A19, 0x00060041, 0x00000288, + 0x00001915, 0x00000CC7, 0x00000A0B, 0x00002DD1, 0x0004003D, 0x0000000B, 0x00005C81, 0x00001915, + 0x00050080, 0x0000000B, 0x00002DD2, 0x000051FC, 0x00000A1C, 0x00060041, 0x00000288, 0x00001916, + 0x00000CC7, 0x00000A0B, 0x00002DD2, 0x0004003D, 0x0000000B, 0x00005C82, 0x00001916, 0x00050080, + 0x0000000B, 0x00002DD3, 0x000051FC, 0x00000A1F, 0x00060041, 0x00000288, 0x00006008, 0x00000CC7, + 0x00000A0B, 0x00002DD3, 0x0004003D, 0x0000000B, 0x00004006, 0x00006008, 0x00070050, 0x00000017, + 0x00005137, 0x00005C80, 0x00005C81, 0x00005C82, 0x00004006, 0x000200F9, 0x00004F27, 0x000200F8, + 0x00004F27, 0x000700F5, 0x00000017, 0x00002BCF, 0x00005137, 0x00002628, 0x00005136, 0x00002F66, + 0x000700F5, 0x00000017, 0x00003722, 0x00004AE0, 0x00002628, 0x00004CD9, 0x00002F66, 0x000300F7, + 0x00004F28, 0x00000000, 0x000700FB, 0x00002180, 0x00004F58, 0x00000005, 0x0000215A, 0x00000007, + 0x00002038, 0x000200F8, 0x00002038, 0x00050051, 0x0000000B, 0x00005F5B, 0x00003722, 0x00000000, + 0x0006000C, 0x00000013, 0x0000606C, 0x00000001, 0x0000003E, 0x00005F5B, 0x00050051, 0x0000000D, + 0x0000277E, 0x0000606C, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC0, 0x0000606C, 0x00000001, + 0x00050051, 0x0000000B, 0x00004289, 0x00003722, 0x00000001, 0x0006000C, 0x00000013, 0x00003CFD, + 0x00000001, 0x0000003E, 0x00004289, 0x00050051, 0x0000000D, 0x0000277F, 0x00003CFD, 0x00000000, + 0x00050051, 0x0000000D, 0x00004455, 0x00003CFD, 0x00000001, 0x00070050, 0x0000001D, 0x0000391B, + 0x0000277E, 0x00003EC0, 0x0000277F, 0x00004455, 0x00050051, 0x0000000B, 0x00004389, 0x00003722, + 0x00000002, 0x0006000C, 0x00000013, 0x0000467A, 0x00000001, 0x0000003E, 0x00004389, 0x00050051, + 0x0000000D, 0x00002780, 0x0000467A, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC1, 0x0000467A, + 0x00000001, 0x00050051, 0x0000000B, 0x0000428A, 0x00003722, 0x00000003, 0x0006000C, 0x00000013, + 0x00003CFE, 0x00000001, 0x0000003E, 0x0000428A, 0x00050051, 0x0000000D, 0x00002781, 0x00003CFE, + 0x00000000, 0x00050051, 0x0000000D, 0x00004456, 0x00003CFE, 0x00000001, 0x00070050, 0x0000001D, + 0x0000391C, 0x00002780, 0x00003EC1, 0x00002781, 0x00004456, 0x00050051, 0x0000000B, 0x0000438A, + 0x00002BCF, 0x00000000, 0x0006000C, 0x00000013, 0x0000467B, 0x00000001, 0x0000003E, 0x0000438A, + 0x00050051, 0x0000000D, 0x00002782, 0x0000467B, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC2, + 0x0000467B, 0x00000001, 0x00050051, 0x0000000B, 0x0000428B, 0x00002BCF, 0x00000001, 0x0006000C, + 0x00000013, 0x00003CFF, 0x00000001, 0x0000003E, 0x0000428B, 0x00050051, 0x0000000D, 0x00002783, + 0x00003CFF, 0x00000000, 0x00050051, 0x0000000D, 0x00004457, 0x00003CFF, 0x00000001, 0x00070050, + 0x0000001D, 0x0000391D, 0x00002782, 0x00003EC2, 0x00002783, 0x00004457, 0x00050051, 0x0000000B, + 0x0000438B, 0x00002BCF, 0x00000002, 0x0006000C, 0x00000013, 0x0000467C, 0x00000001, 0x0000003E, + 0x0000438B, 0x00050051, 0x0000000D, 0x00002784, 0x0000467C, 0x00000000, 0x00050051, 0x0000000D, + 0x00003EC3, 0x0000467C, 0x00000001, 0x00050051, 0x0000000B, 0x0000428C, 0x00002BCF, 0x00000003, + 0x0006000C, 0x00000013, 0x00003D00, 0x00000001, 0x0000003E, 0x0000428C, 0x00050051, 0x0000000D, + 0x00002785, 0x00003D00, 0x00000000, 0x00050051, 0x0000000D, 0x000050C3, 0x00003D00, 0x00000001, + 0x00070050, 0x0000001D, 0x00002356, 0x00002784, 0x00003EC3, 0x00002785, 0x000050C3, 0x000200F9, + 0x00004F28, 0x000200F8, 0x0000215A, 0x0007004F, 0x00000011, 0x000025FD, 0x00003722, 0x00003722, + 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x00005B3E, 0x000025FD, 0x0009004F, 0x0000001A, + 0x000060D6, 0x00005B3E, 0x00005B3E, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, + 0x0000001A, 0x000048B0, 0x000060D6, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D95, 0x000048B0, + 0x00000302, 0x0004006F, 0x0000001D, 0x00002AB7, 0x00003D95, 0x0005008E, 0x0000001D, 0x0000472C, + 0x00002AB7, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006297, 0x00000001, 0x00000028, 0x00000504, + 0x0000472C, 0x0007004F, 0x00000011, 0x00003771, 0x00003722, 0x00003722, 0x00000002, 0x00000003, + 0x0004007C, 0x00000012, 0x000024C5, 0x00003771, 0x0009004F, 0x0000001A, 0x000060D7, 0x000024C5, + 0x000024C5, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048B1, + 0x000060D7, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D96, 0x000048B1, 0x00000302, 0x0004006F, + 0x0000001D, 0x00002AB8, 0x00003D96, 0x0005008E, 0x0000001D, 0x0000472D, 0x00002AB8, 0x000007FE, + 0x0007000C, 0x0000001D, 0x00006298, 0x00000001, 0x00000028, 0x00000504, 0x0000472D, 0x0007004F, + 0x00000011, 0x00003772, 0x00002BCF, 0x00002BCF, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, + 0x000024C6, 0x00003772, 0x0009004F, 0x0000001A, 0x000060D8, 0x000024C6, 0x000024C6, 0x00000000, + 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048B2, 0x000060D8, 0x00000122, + 0x000500C3, 0x0000001A, 0x00003D97, 0x000048B2, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AB9, + 0x00003D97, 0x0005008E, 0x0000001D, 0x0000472E, 0x00002AB9, 0x000007FE, 0x0007000C, 0x0000001D, + 0x00006299, 0x00000001, 0x00000028, 0x00000504, 0x0000472E, 0x0007004F, 0x00000011, 0x00003773, + 0x00002BCF, 0x00002BCF, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C7, 0x00003773, + 0x0009004F, 0x0000001A, 0x000060D9, 0x000024C7, 0x000024C7, 0x00000000, 0x00000000, 0x00000001, + 0x00000001, 0x000500C4, 0x0000001A, 0x000048B3, 0x000060D9, 0x00000122, 0x000500C3, 0x0000001A, + 0x00003D98, 0x000048B3, 0x00000302, 0x0004006F, 0x0000001D, 0x00002ABA, 0x00003D98, 0x0005008E, + 0x0000001D, 0x000053C1, 0x00002ABA, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004364, 0x00000001, + 0x00000028, 0x00000504, 0x000053C1, 0x000200F9, 0x00004F28, 0x000200F8, 0x00004F58, 0x0007004F, + 0x00000011, 0x00002629, 0x00003722, 0x00003722, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, + 0x0000515B, 0x00002629, 0x00050051, 0x0000000D, 0x00001B83, 0x0000515B, 0x00000000, 0x00050051, + 0x0000000D, 0x00003470, 0x0000515B, 0x00000001, 0x00070050, 0x0000001D, 0x0000427E, 0x00001B83, + 0x00003470, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DE, 0x00003722, 0x00003722, + 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x00003763, 0x000041DE, 0x00050051, 0x0000000D, + 0x00001B84, 0x00003763, 0x00000000, 0x00050051, 0x0000000D, 0x00003471, 0x00003763, 0x00000001, + 0x00070050, 0x0000001D, 0x0000427F, 0x00001B84, 0x00003471, 0x00000A0C, 0x00000A0C, 0x0007004F, + 0x00000011, 0x000041DF, 0x00002BCF, 0x00002BCF, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, + 0x00003764, 0x000041DF, 0x00050051, 0x0000000D, 0x00001B85, 0x00003764, 0x00000000, 0x00050051, + 0x0000000D, 0x00003472, 0x00003764, 0x00000001, 0x00070050, 0x0000001D, 0x00004280, 0x00001B85, + 0x00003472, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041E0, 0x00002BCF, 0x00002BCF, + 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x00003765, 0x000041E0, 0x00050051, 0x0000000D, + 0x00001B86, 0x00003765, 0x00000000, 0x00050051, 0x0000000D, 0x0000410A, 0x00003765, 0x00000001, + 0x00070050, 0x0000001D, 0x00002357, 0x00001B86, 0x0000410A, 0x00000A0C, 0x00000A0C, 0x000200F9, + 0x00004F28, 0x000200F8, 0x00004F28, 0x000900F5, 0x0000001D, 0x00002BAE, 0x00002357, 0x00004F58, + 0x00004364, 0x0000215A, 0x00002356, 0x00002038, 0x000900F5, 0x0000001D, 0x0000380F, 0x00004280, + 0x00004F58, 0x00006299, 0x0000215A, 0x0000391D, 0x00002038, 0x000900F5, 0x0000001D, 0x00003B88, + 0x0000427F, 0x00004F58, 0x00006298, 0x0000215A, 0x0000391C, 0x00002038, 0x000900F5, 0x0000001D, + 0x000038BB, 0x0000427E, 0x00004F58, 0x00006297, 0x0000215A, 0x0000391B, 0x00002038, 0x000200F9, + 0x00005311, 0x000200F8, 0x00005311, 0x000700F5, 0x0000001D, 0x00002BAF, 0x00002BAE, 0x00004F28, + 0x00002BAD, 0x00003F62, 0x000700F5, 0x0000001D, 0x00003810, 0x0000380F, 0x00004F28, 0x0000380E, + 0x00003F62, 0x000700F5, 0x0000001D, 0x00003296, 0x00003B88, 0x00004F28, 0x00003B85, 0x00003F62, + 0x000700F5, 0x0000001D, 0x0000367B, 0x000038BB, 0x00004F28, 0x000038BA, 0x00003F62, 0x00050081, + 0x0000001D, 0x0000435A, 0x00004359, 0x0000367B, 0x00050081, 0x0000001D, 0x00005B02, 0x00005B01, + 0x00003296, 0x00050081, 0x0000001D, 0x00001C28, 0x00001F92, 0x00003810, 0x00050081, 0x0000001D, + 0x000025AA, 0x00005113, 0x00002BAF, 0x00050080, 0x0000000B, 0x00003FF8, 0x00005E78, 0x000037B2, + 0x000300F7, 0x00005312, 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B68, 0x000040BC, 0x000200F8, + 0x000040BC, 0x000500AA, 0x00000009, 0x00004AE1, 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F4C, + 0x00000002, 0x000400FA, 0x00004AE1, 0x0000262A, 0x00002F67, 0x000200F8, 0x00002F67, 0x00060041, + 0x00000288, 0x00004BD5, 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D4F, + 0x00004BD5, 0x00050080, 0x0000000B, 0x00002DD4, 0x00003FF8, 0x0000199B, 0x00060041, 0x00000288, + 0x00001951, 0x00000CC7, 0x00000A0B, 0x00002DD4, 0x0004003D, 0x0000000B, 0x00005E64, 0x00001951, + 0x00050084, 0x0000000B, 0x00001863, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000020AA, + 0x00003FF8, 0x00001863, 0x00060041, 0x00000288, 0x00003BD0, 0x00000CC7, 0x00000A0B, 0x000020AA, + 0x0004003D, 0x0000000B, 0x00005E65, 0x00003BD0, 0x00050084, 0x0000000B, 0x00001864, 0x00000A13, + 0x0000199B, 0x00050080, 0x0000000B, 0x000020AB, 0x00003FF8, 0x00001864, 0x00060041, 0x00000288, + 0x000037F4, 0x00000CC7, 0x00000A0B, 0x000020AB, 0x0004003D, 0x0000000B, 0x00004007, 0x000037F4, + 0x00070050, 0x00000017, 0x00005138, 0x00005D4F, 0x00005E64, 0x00005E65, 0x00004007, 0x000200F9, + 0x00004F4C, 0x000200F8, 0x0000262A, 0x00060041, 0x00000288, 0x0000554B, 0x00000CC7, 0x00000A0B, + 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D50, 0x0000554B, 0x00050080, 0x0000000B, 0x00002DD5, + 0x00003FF8, 0x00000A0D, 0x00060041, 0x00000288, 0x00001917, 0x00000CC7, 0x00000A0B, 0x00002DD5, + 0x0004003D, 0x0000000B, 0x00005C83, 0x00001917, 0x00050080, 0x0000000B, 0x00002DD6, 0x00003FF8, + 0x00000A10, 0x00060041, 0x00000288, 0x00001918, 0x00000CC7, 0x00000A0B, 0x00002DD6, 0x0004003D, + 0x0000000B, 0x00005C84, 0x00001918, 0x00050080, 0x0000000B, 0x00002DD7, 0x00003FF8, 0x00000A13, + 0x00060041, 0x00000288, 0x00006009, 0x00000CC7, 0x00000A0B, 0x00002DD7, 0x0004003D, 0x0000000B, + 0x00004008, 0x00006009, 0x00070050, 0x00000017, 0x00005139, 0x00005D50, 0x00005C83, 0x00005C84, + 0x00004008, 0x000200F9, 0x00004F4C, 0x000200F8, 0x00004F4C, 0x000700F5, 0x00000017, 0x00002AC2, + 0x00005139, 0x0000262A, 0x00005138, 0x00002F67, 0x000300F7, 0x00003F63, 0x00000000, 0x001300FB, + 0x00002180, 0x00004BFE, 0x00000000, 0x000038FC, 0x00000001, 0x000038FC, 0x00000002, 0x00001CC1, + 0x0000000A, 0x00001CC1, 0x00000003, 0x00001CC0, 0x0000000C, 0x00001CC0, 0x00000004, 0x00002001, + 0x00000006, 0x00002039, 0x000200F8, 0x00002039, 0x00050051, 0x0000000B, 0x00005F5C, 0x00002AC2, + 0x00000000, 0x0006000C, 0x00000013, 0x0000606D, 0x00000001, 0x0000003E, 0x00005F5C, 0x00050051, + 0x0000000D, 0x00002786, 0x0000606D, 0x00000000, 0x00050051, 0x0000000D, 0x00004458, 0x0000606D, + 0x00000001, 0x00070050, 0x0000001D, 0x0000391E, 0x00002786, 0x00004458, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x0000438C, 0x00002AC2, 0x00000001, 0x0006000C, 0x00000013, 0x0000467D, + 0x00000001, 0x0000003E, 0x0000438C, 0x00050051, 0x0000000D, 0x00002787, 0x0000467D, 0x00000000, + 0x00050051, 0x0000000D, 0x00004459, 0x0000467D, 0x00000001, 0x00070050, 0x0000001D, 0x0000391F, + 0x00002787, 0x00004459, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x0000438D, 0x00002AC2, + 0x00000002, 0x0006000C, 0x00000013, 0x0000467E, 0x00000001, 0x0000003E, 0x0000438D, 0x00050051, + 0x0000000D, 0x00002788, 0x0000467E, 0x00000000, 0x00050051, 0x0000000D, 0x0000445A, 0x0000467E, + 0x00000001, 0x00070050, 0x0000001D, 0x00003920, 0x00002788, 0x0000445A, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x0000438E, 0x00002AC2, 0x00000003, 0x0006000C, 0x00000013, 0x0000467F, + 0x00000001, 0x0000003E, 0x0000438E, 0x00050051, 0x0000000D, 0x00002789, 0x0000467F, 0x00000000, + 0x00050051, 0x0000000D, 0x000050C4, 0x0000467F, 0x00000001, 0x00070050, 0x0000001D, 0x00002358, + 0x00002789, 0x000050C4, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F63, 0x000200F8, 0x00002001, + 0x00050051, 0x0000000B, 0x00003091, 0x00002AC2, 0x00000000, 0x0004007C, 0x0000000C, 0x000058A0, + 0x00003091, 0x00050050, 0x00000012, 0x0000472F, 0x000058A0, 0x000058A0, 0x000500C4, 0x00000012, + 0x000047B9, 0x0000472F, 0x000007A7, 0x000500C3, 0x00000012, 0x00003423, 0x000047B9, 0x00000867, + 0x0004006F, 0x00000013, 0x00002ABB, 0x00003423, 0x0005008E, 0x00000013, 0x00004753, 0x00002ABB, + 0x000007FE, 0x0007000C, 0x00000013, 0x00005E12, 0x00000001, 0x00000028, 0x00000049, 0x00004753, + 0x00050051, 0x0000000D, 0x00005F16, 0x00005E12, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDD, + 0x00005E12, 0x00000001, 0x00070050, 0x0000001D, 0x00004127, 0x00005F16, 0x00003CDD, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C4B, 0x00002AC2, 0x00000001, 0x0004007C, 0x0000000C, + 0x00003EAA, 0x00004C4B, 0x00050050, 0x00000012, 0x00004730, 0x00003EAA, 0x00003EAA, 0x000500C4, + 0x00000012, 0x000047BA, 0x00004730, 0x000007A7, 0x000500C3, 0x00000012, 0x00003424, 0x000047BA, + 0x00000867, 0x0004006F, 0x00000013, 0x00002ABC, 0x00003424, 0x0005008E, 0x00000013, 0x00004754, + 0x00002ABC, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E13, 0x00000001, 0x00000028, 0x00000049, + 0x00004754, 0x00050051, 0x0000000D, 0x00005F17, 0x00005E13, 0x00000000, 0x00050051, 0x0000000D, + 0x00003CDE, 0x00005E13, 0x00000001, 0x00070050, 0x0000001D, 0x00004128, 0x00005F17, 0x00003CDE, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C4C, 0x00002AC2, 0x00000002, 0x0004007C, + 0x0000000C, 0x00003EAB, 0x00004C4C, 0x00050050, 0x00000012, 0x00004731, 0x00003EAB, 0x00003EAB, + 0x000500C4, 0x00000012, 0x000047BB, 0x00004731, 0x000007A7, 0x000500C3, 0x00000012, 0x00003425, + 0x000047BB, 0x00000867, 0x0004006F, 0x00000013, 0x00002ABD, 0x00003425, 0x0005008E, 0x00000013, + 0x00004755, 0x00002ABD, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E14, 0x00000001, 0x00000028, + 0x00000049, 0x00004755, 0x00050051, 0x0000000D, 0x00005F18, 0x00005E14, 0x00000000, 0x00050051, + 0x0000000D, 0x00003CDF, 0x00005E14, 0x00000001, 0x00070050, 0x0000001D, 0x00004129, 0x00005F18, + 0x00003CDF, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C4D, 0x00002AC2, 0x00000003, + 0x0004007C, 0x0000000C, 0x00003EAC, 0x00004C4D, 0x00050050, 0x00000012, 0x00004732, 0x00003EAC, + 0x00003EAC, 0x000500C4, 0x00000012, 0x000047BC, 0x00004732, 0x000007A7, 0x000500C3, 0x00000012, + 0x00003426, 0x000047BC, 0x00000867, 0x0004006F, 0x00000013, 0x00002ABE, 0x00003426, 0x0005008E, + 0x00000013, 0x00004756, 0x00002ABE, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E15, 0x00000001, + 0x00000028, 0x00000049, 0x00004756, 0x00050051, 0x0000000D, 0x00005F19, 0x00005E15, 0x00000000, + 0x00050051, 0x0000000D, 0x0000494F, 0x00005E15, 0x00000001, 0x00070050, 0x0000001D, 0x00002359, + 0x00005F19, 0x0000494F, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F63, 0x000200F8, 0x00001CC0, + 0x00050051, 0x0000000B, 0x000056C6, 0x00002AC2, 0x00000000, 0x00060050, 0x00000014, 0x00004F13, + 0x000056C6, 0x000056C6, 0x000056C6, 0x000500C2, 0x00000014, 0x00002B1C, 0x00004F13, 0x00000BB4, + 0x000500C7, 0x00000014, 0x00005DF2, 0x00002B1C, 0x00000105, 0x000500C7, 0x00000014, 0x000048B4, + 0x00005DF2, 0x00000466, 0x000500C2, 0x00000014, 0x00005B9C, 0x00005DF2, 0x00000B0C, 0x000500AA, + 0x00000010, 0x000040D5, 0x00005B9C, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C57, 0x00000001, + 0x0000004B, 0x000048B4, 0x0004007C, 0x00000014, 0x00002A21, 0x00002C57, 0x00050082, 0x00000014, + 0x00001886, 0x00000B0C, 0x00002A21, 0x00050080, 0x00000014, 0x0000221C, 0x00002A21, 0x00000938, + 0x000600A9, 0x00000014, 0x0000287B, 0x000040D5, 0x0000221C, 0x00005B9C, 0x000500C4, 0x00000014, + 0x00005AE1, 0x000048B4, 0x00001886, 0x000500C7, 0x00000014, 0x000049A6, 0x00005AE1, 0x00000466, + 0x000600A9, 0x00000014, 0x00002AC3, 0x000040D5, 0x000049A6, 0x000048B4, 0x00050080, 0x00000014, + 0x0000600A, 0x0000287B, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F8B, 0x0000600A, 0x00000189, + 0x000500C4, 0x00000014, 0x00003FB2, 0x00002AC3, 0x0000008D, 0x000500C5, 0x00000014, 0x00005788, + 0x00004F8B, 0x00003FB2, 0x000500AA, 0x00000010, 0x0000360C, 0x00005DF2, 0x00000A12, 0x000600A9, + 0x00000014, 0x0000424E, 0x0000360C, 0x00000A12, 0x00005788, 0x0004007C, 0x00000018, 0x000029DB, + 0x0000424E, 0x000500C2, 0x0000000B, 0x00004BB0, 0x000056C6, 0x00000A64, 0x00040070, 0x0000000D, + 0x0000481A, 0x00004BB0, 0x00050085, 0x0000000D, 0x00003E2B, 0x0000481A, 0x00000149, 0x00050051, + 0x0000000D, 0x000053CE, 0x000029DB, 0x00000000, 0x00050051, 0x0000000D, 0x00002A61, 0x000029DB, + 0x00000001, 0x00050051, 0x0000000D, 0x00001EA2, 0x000029DB, 0x00000002, 0x00070050, 0x0000001D, + 0x00003DE3, 0x000053CE, 0x00002A61, 0x00001EA2, 0x00003E2B, 0x00050051, 0x0000000B, 0x000027FE, + 0x00002AC2, 0x00000001, 0x00060050, 0x00000014, 0x00003517, 0x000027FE, 0x000027FE, 0x000027FE, + 0x000500C2, 0x00000014, 0x00002B1D, 0x00003517, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF3, + 0x00002B1D, 0x00000105, 0x000500C7, 0x00000014, 0x000048B5, 0x00005DF3, 0x00000466, 0x000500C2, + 0x00000014, 0x00005B9D, 0x00005DF3, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D6, 0x00005B9D, + 0x00000A12, 0x0006000C, 0x00000016, 0x00002C58, 0x00000001, 0x0000004B, 0x000048B5, 0x0004007C, + 0x00000014, 0x00002A22, 0x00002C58, 0x00050082, 0x00000014, 0x00001887, 0x00000B0C, 0x00002A22, + 0x00050080, 0x00000014, 0x0000221D, 0x00002A22, 0x00000938, 0x000600A9, 0x00000014, 0x0000287C, + 0x000040D6, 0x0000221D, 0x00005B9D, 0x000500C4, 0x00000014, 0x00005AE2, 0x000048B5, 0x00001887, + 0x000500C7, 0x00000014, 0x000049A7, 0x00005AE2, 0x00000466, 0x000600A9, 0x00000014, 0x00002AC4, + 0x000040D6, 0x000049A7, 0x000048B5, 0x00050080, 0x00000014, 0x0000600B, 0x0000287C, 0x000003FA, + 0x000500C4, 0x00000014, 0x00004F8C, 0x0000600B, 0x00000189, 0x000500C4, 0x00000014, 0x00003FB3, + 0x00002AC4, 0x0000008D, 0x000500C5, 0x00000014, 0x00005789, 0x00004F8C, 0x00003FB3, 0x000500AA, + 0x00000010, 0x0000360D, 0x00005DF3, 0x00000A12, 0x000600A9, 0x00000014, 0x0000424F, 0x0000360D, + 0x00000A12, 0x00005789, 0x0004007C, 0x00000018, 0x000029DC, 0x0000424F, 0x000500C2, 0x0000000B, + 0x00004BB1, 0x000027FE, 0x00000A64, 0x00040070, 0x0000000D, 0x0000481B, 0x00004BB1, 0x00050085, + 0x0000000D, 0x00003E2C, 0x0000481B, 0x00000149, 0x00050051, 0x0000000D, 0x000053CF, 0x000029DC, + 0x00000000, 0x00050051, 0x0000000D, 0x00002A62, 0x000029DC, 0x00000001, 0x00050051, 0x0000000D, + 0x00001EA3, 0x000029DC, 0x00000002, 0x00070050, 0x0000001D, 0x00003DE4, 0x000053CF, 0x00002A62, + 0x00001EA3, 0x00003E2C, 0x00050051, 0x0000000B, 0x000027FF, 0x00002AC2, 0x00000002, 0x00060050, + 0x00000014, 0x00003518, 0x000027FF, 0x000027FF, 0x000027FF, 0x000500C2, 0x00000014, 0x00002B1E, + 0x00003518, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF4, 0x00002B1E, 0x00000105, 0x000500C7, + 0x00000014, 0x000048B6, 0x00005DF4, 0x00000466, 0x000500C2, 0x00000014, 0x00005B9E, 0x00005DF4, + 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D7, 0x00005B9E, 0x00000A12, 0x0006000C, 0x00000016, + 0x00002C59, 0x00000001, 0x0000004B, 0x000048B6, 0x0004007C, 0x00000014, 0x00002A23, 0x00002C59, + 0x00050082, 0x00000014, 0x00001888, 0x00000B0C, 0x00002A23, 0x00050080, 0x00000014, 0x0000221E, + 0x00002A23, 0x00000938, 0x000600A9, 0x00000014, 0x0000287D, 0x000040D7, 0x0000221E, 0x00005B9E, + 0x000500C4, 0x00000014, 0x00005AE3, 0x000048B6, 0x00001888, 0x000500C7, 0x00000014, 0x000049A8, + 0x00005AE3, 0x00000466, 0x000600A9, 0x00000014, 0x00002AC5, 0x000040D7, 0x000049A8, 0x000048B6, + 0x00050080, 0x00000014, 0x0000600C, 0x0000287D, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F8D, + 0x0000600C, 0x00000189, 0x000500C4, 0x00000014, 0x00003FB4, 0x00002AC5, 0x0000008D, 0x000500C5, + 0x00000014, 0x0000578A, 0x00004F8D, 0x00003FB4, 0x000500AA, 0x00000010, 0x0000360E, 0x00005DF4, + 0x00000A12, 0x000600A9, 0x00000014, 0x00004250, 0x0000360E, 0x00000A12, 0x0000578A, 0x0004007C, + 0x00000018, 0x000029DD, 0x00004250, 0x000500C2, 0x0000000B, 0x00004BB2, 0x000027FF, 0x00000A64, + 0x00040070, 0x0000000D, 0x0000481C, 0x00004BB2, 0x00050085, 0x0000000D, 0x00003E2D, 0x0000481C, + 0x00000149, 0x00050051, 0x0000000D, 0x000053D0, 0x000029DD, 0x00000000, 0x00050051, 0x0000000D, + 0x00002A63, 0x000029DD, 0x00000001, 0x00050051, 0x0000000D, 0x00001EA4, 0x000029DD, 0x00000002, + 0x00070050, 0x0000001D, 0x00003DE5, 0x000053D0, 0x00002A63, 0x00001EA4, 0x00003E2D, 0x00050051, + 0x0000000B, 0x00002800, 0x00002AC2, 0x00000003, 0x00060050, 0x00000014, 0x00003519, 0x00002800, + 0x00002800, 0x00002800, 0x000500C2, 0x00000014, 0x00002B1F, 0x00003519, 0x00000BB4, 0x000500C7, + 0x00000014, 0x00005DF5, 0x00002B1F, 0x00000105, 0x000500C7, 0x00000014, 0x000048B7, 0x00005DF5, + 0x00000466, 0x000500C2, 0x00000014, 0x00005B9F, 0x00005DF5, 0x00000B0C, 0x000500AA, 0x00000010, + 0x000040D8, 0x00005B9F, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C5A, 0x00000001, 0x0000004B, + 0x000048B7, 0x0004007C, 0x00000014, 0x00002A24, 0x00002C5A, 0x00050082, 0x00000014, 0x00001889, + 0x00000B0C, 0x00002A24, 0x00050080, 0x00000014, 0x0000221F, 0x00002A24, 0x00000938, 0x000600A9, + 0x00000014, 0x0000287E, 0x000040D8, 0x0000221F, 0x00005B9F, 0x000500C4, 0x00000014, 0x00005AE4, + 0x000048B7, 0x00001889, 0x000500C7, 0x00000014, 0x000049A9, 0x00005AE4, 0x00000466, 0x000600A9, + 0x00000014, 0x00002AC6, 0x000040D8, 0x000049A9, 0x000048B7, 0x00050080, 0x00000014, 0x0000600D, + 0x0000287E, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F8E, 0x0000600D, 0x00000189, 0x000500C4, + 0x00000014, 0x00003FB5, 0x00002AC6, 0x0000008D, 0x000500C5, 0x00000014, 0x0000578B, 0x00004F8E, + 0x00003FB5, 0x000500AA, 0x00000010, 0x0000360F, 0x00005DF5, 0x00000A12, 0x000600A9, 0x00000014, + 0x00004251, 0x0000360F, 0x00000A12, 0x0000578B, 0x0004007C, 0x00000018, 0x000029DE, 0x00004251, + 0x000500C2, 0x0000000B, 0x00004BB3, 0x00002800, 0x00000A64, 0x00040070, 0x0000000D, 0x0000481D, + 0x00004BB3, 0x00050085, 0x0000000D, 0x00003E2E, 0x0000481D, 0x00000149, 0x00050051, 0x0000000D, + 0x000053D1, 0x000029DE, 0x00000000, 0x00050051, 0x0000000D, 0x00002A64, 0x000029DE, 0x00000001, + 0x00050051, 0x0000000D, 0x00002B20, 0x000029DE, 0x00000002, 0x00070050, 0x0000001D, 0x0000235A, + 0x000053D1, 0x00002A64, 0x00002B20, 0x00003E2E, 0x000200F9, 0x00003F63, 0x000200F8, 0x00001CC1, + 0x00050051, 0x0000000B, 0x000056C7, 0x00002AC2, 0x00000000, 0x00070050, 0x00000017, 0x00004F14, + 0x000056C7, 0x000056C7, 0x000056C7, 0x000056C7, 0x000500C2, 0x00000017, 0x000024B0, 0x00004F14, + 0x0000034D, 0x000500C7, 0x00000017, 0x000049B7, 0x000024B0, 0x0000027B, 0x00040070, 0x0000001D, + 0x00003CC0, 0x000049B7, 0x00050085, 0x0000001D, 0x00004139, 0x00003CC0, 0x00000AEE, 0x00050051, + 0x0000000B, 0x00005CDB, 0x00002AC2, 0x00000001, 0x00070050, 0x00000017, 0x00005156, 0x00005CDB, + 0x00005CDB, 0x00005CDB, 0x00005CDB, 0x000500C2, 0x00000017, 0x000024B1, 0x00005156, 0x0000034D, + 0x000500C7, 0x00000017, 0x000049B8, 0x000024B1, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CC1, + 0x000049B8, 0x00050085, 0x0000001D, 0x0000413A, 0x00003CC1, 0x00000AEE, 0x00050051, 0x0000000B, + 0x00005CDC, 0x00002AC2, 0x00000002, 0x00070050, 0x00000017, 0x00005157, 0x00005CDC, 0x00005CDC, + 0x00005CDC, 0x00005CDC, 0x000500C2, 0x00000017, 0x000024B2, 0x00005157, 0x0000034D, 0x000500C7, + 0x00000017, 0x000049B9, 0x000024B2, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CC2, 0x000049B9, + 0x00050085, 0x0000001D, 0x0000413B, 0x00003CC2, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CDD, + 0x00002AC2, 0x00000003, 0x00070050, 0x00000017, 0x0000515C, 0x00005CDD, 0x00005CDD, 0x00005CDD, + 0x00005CDD, 0x000500C2, 0x00000017, 0x000024B3, 0x0000515C, 0x0000034D, 0x000500C7, 0x00000017, + 0x000049BA, 0x000024B3, 0x0000027B, 0x00040070, 0x0000001D, 0x00004932, 0x000049BA, 0x00050085, + 0x0000001D, 0x000026A2, 0x00004932, 0x00000AEE, 0x000200F9, 0x00003F63, 0x000200F8, 0x000038FC, + 0x00050051, 0x0000000B, 0x000056C8, 0x00002AC2, 0x00000000, 0x00070050, 0x00000017, 0x00004F15, + 0x000056C8, 0x000056C8, 0x000056C8, 0x000056C8, 0x000500C2, 0x00000017, 0x000024B4, 0x00004F15, + 0x0000028D, 0x000500C7, 0x00000017, 0x00004A62, 0x000024B4, 0x0000064B, 0x00040070, 0x0000001D, + 0x000036AE, 0x00004A62, 0x0005008E, 0x0000001D, 0x00004B2C, 0x000036AE, 0x0000017A, 0x00050051, + 0x0000000B, 0x000021A8, 0x00002AC2, 0x00000001, 0x00070050, 0x00000017, 0x00006114, 0x000021A8, + 0x000021A8, 0x000021A8, 0x000021A8, 0x000500C2, 0x00000017, 0x000024B5, 0x00006114, 0x0000028D, + 0x000500C7, 0x00000017, 0x00004A63, 0x000024B5, 0x0000064B, 0x00040070, 0x0000001D, 0x000036AF, + 0x00004A63, 0x0005008E, 0x0000001D, 0x00004B2D, 0x000036AF, 0x0000017A, 0x00050051, 0x0000000B, + 0x000021A9, 0x00002AC2, 0x00000002, 0x00070050, 0x00000017, 0x00006115, 0x000021A9, 0x000021A9, + 0x000021A9, 0x000021A9, 0x000500C2, 0x00000017, 0x000024B6, 0x00006115, 0x0000028D, 0x000500C7, + 0x00000017, 0x00004A64, 0x000024B6, 0x0000064B, 0x00040070, 0x0000001D, 0x000036B0, 0x00004A64, + 0x0005008E, 0x0000001D, 0x00004B2E, 0x000036B0, 0x0000017A, 0x00050051, 0x0000000B, 0x000021AA, + 0x00002AC2, 0x00000003, 0x00070050, 0x00000017, 0x00006116, 0x000021AA, 0x000021AA, 0x000021AA, + 0x000021AA, 0x000500C2, 0x00000017, 0x000024B7, 0x00006116, 0x0000028D, 0x000500C7, 0x00000017, + 0x00004A65, 0x000024B7, 0x0000064B, 0x00040070, 0x0000001D, 0x0000431D, 0x00004A65, 0x0005008E, + 0x0000001D, 0x00003095, 0x0000431D, 0x0000017A, 0x000200F9, 0x00003F63, 0x000200F8, 0x00004BFE, + 0x00050051, 0x0000000B, 0x00003096, 0x00002AC2, 0x00000000, 0x0004007C, 0x0000000D, 0x00004FF1, + 0x00003096, 0x00050050, 0x00000013, 0x0000433F, 0x00004FF1, 0x00000A0C, 0x0009004F, 0x0000001D, + 0x00002D99, 0x0000433F, 0x0000433F, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, + 0x0000000B, 0x000056BA, 0x00002AC2, 0x00000001, 0x0004007C, 0x0000000D, 0x00003F71, 0x000056BA, + 0x00050050, 0x00000013, 0x00004340, 0x00003F71, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D9A, + 0x00004340, 0x00004340, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, + 0x000056BB, 0x00002AC2, 0x00000002, 0x0004007C, 0x0000000D, 0x00003F72, 0x000056BB, 0x00050050, + 0x00000013, 0x00004341, 0x00003F72, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D9B, 0x00004341, + 0x00004341, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056BC, + 0x00002AC2, 0x00000003, 0x0004007C, 0x0000000D, 0x00003F73, 0x000056BC, 0x00050050, 0x00000013, + 0x00004FB1, 0x00003F73, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3D, 0x00004FB1, 0x00004FB1, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000200F9, 0x00003F63, 0x000200F8, 0x00003F63, + 0x000F00F5, 0x0000001D, 0x00002BB0, 0x00005A3D, 0x00004BFE, 0x00003095, 0x000038FC, 0x000026A2, + 0x00001CC1, 0x0000235A, 0x00001CC0, 0x00002359, 0x00002001, 0x00002358, 0x00002039, 0x000F00F5, + 0x0000001D, 0x00003811, 0x00002D9B, 0x00004BFE, 0x00004B2E, 0x000038FC, 0x0000413B, 0x00001CC1, + 0x00003DE5, 0x00001CC0, 0x00004129, 0x00002001, 0x00003920, 0x00002039, 0x000F00F5, 0x0000001D, + 0x00003B89, 0x00002D9A, 0x00004BFE, 0x00004B2D, 0x000038FC, 0x0000413A, 0x00001CC1, 0x00003DE4, + 0x00001CC0, 0x00004128, 0x00002001, 0x0000391F, 0x00002039, 0x000F00F5, 0x0000001D, 0x000038BC, + 0x00002D99, 0x00004BFE, 0x00004B2C, 0x000038FC, 0x00004139, 0x00001CC1, 0x00003DE3, 0x00001CC0, + 0x00004127, 0x00002001, 0x0000391E, 0x00002039, 0x000200F9, 0x00005312, 0x000200F8, 0x00003B68, + 0x000500AA, 0x00000009, 0x00005453, 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F29, 0x00000002, + 0x000400FA, 0x00005453, 0x0000262B, 0x00002F68, 0x000200F8, 0x00002F68, 0x00060041, 0x00000288, + 0x00004BD6, 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D51, 0x00004BD6, + 0x00050080, 0x0000000B, 0x00002DD8, 0x00003FF8, 0x00000A0D, 0x00060041, 0x00000288, 0x00001919, + 0x00000CC7, 0x00000A0B, 0x00002DD8, 0x0004003D, 0x0000000B, 0x00005C85, 0x00001919, 0x00050080, + 0x0000000B, 0x00002DD9, 0x00003FF8, 0x0000199B, 0x00060041, 0x00000288, 0x0000191A, 0x00000CC7, + 0x00000A0B, 0x00002DD9, 0x0004003D, 0x0000000B, 0x00005C86, 0x0000191A, 0x00050080, 0x0000000B, + 0x00002DDA, 0x00002DD9, 0x00000A0D, 0x00060041, 0x00000288, 0x0000600E, 0x00000CC7, 0x00000A0B, + 0x00002DDA, 0x0004003D, 0x0000000B, 0x00003750, 0x0000600E, 0x00070050, 0x00000017, 0x00004CDA, + 0x00005D51, 0x00005C85, 0x00005C86, 0x00003750, 0x00050084, 0x0000000B, 0x0000429B, 0x00000A10, + 0x0000199B, 0x00050080, 0x0000000B, 0x000036B1, 0x00003FF8, 0x0000429B, 0x00060041, 0x00000288, + 0x00003B8A, 0x00000CC7, 0x00000A0B, 0x000036B1, 0x0004003D, 0x0000000B, 0x00005C87, 0x00003B8A, + 0x00050080, 0x0000000B, 0x00002DDB, 0x000036B1, 0x00000A0D, 0x00060041, 0x00000288, 0x00001952, + 0x00000CC7, 0x00000A0B, 0x00002DDB, 0x0004003D, 0x0000000B, 0x00005E66, 0x00001952, 0x00050084, + 0x0000000B, 0x00001865, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020AC, 0x00003FF8, + 0x00001865, 0x00060041, 0x00000288, 0x00003B8B, 0x00000CC7, 0x00000A0B, 0x000020AC, 0x0004003D, + 0x0000000B, 0x00005C88, 0x00003B8B, 0x00050080, 0x0000000B, 0x00002DDC, 0x000020AC, 0x00000A0D, + 0x00060041, 0x00000288, 0x0000600F, 0x00000CC7, 0x00000A0B, 0x00002DDC, 0x0004003D, 0x0000000B, + 0x00004009, 0x0000600F, 0x00070050, 0x00000017, 0x0000513A, 0x00005C87, 0x00005E66, 0x00005C88, + 0x00004009, 0x000200F9, 0x00004F29, 0x000200F8, 0x0000262B, 0x00060041, 0x00000288, 0x0000554C, + 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D52, 0x0000554C, 0x00050080, + 0x0000000B, 0x00002DDD, 0x00003FF8, 0x00000A0D, 0x00060041, 0x00000288, 0x0000191B, 0x00000CC7, + 0x00000A0B, 0x00002DDD, 0x0004003D, 0x0000000B, 0x00005C89, 0x0000191B, 0x00050080, 0x0000000B, + 0x00002DDE, 0x00003FF8, 0x00000A10, 0x00060041, 0x00000288, 0x0000191C, 0x00000CC7, 0x00000A0B, + 0x00002DDE, 0x0004003D, 0x0000000B, 0x00005C8A, 0x0000191C, 0x00050080, 0x0000000B, 0x00002DDF, + 0x00003FF8, 0x00000A13, 0x00060041, 0x00000288, 0x00006010, 0x00000CC7, 0x00000A0B, 0x00002DDF, + 0x0004003D, 0x0000000B, 0x00003703, 0x00006010, 0x00070050, 0x00000017, 0x00004AE2, 0x00005D52, + 0x00005C89, 0x00005C8A, 0x00003703, 0x00050080, 0x0000000B, 0x000057E8, 0x00003FF8, 0x00000A16, + 0x00060041, 0x00000288, 0x0000604E, 0x00000CC7, 0x00000A0B, 0x000057E8, 0x0004003D, 0x0000000B, + 0x00005C8B, 0x0000604E, 0x00050080, 0x0000000B, 0x00002DE0, 0x00003FF8, 0x00000A19, 0x00060041, + 0x00000288, 0x0000191D, 0x00000CC7, 0x00000A0B, 0x00002DE0, 0x0004003D, 0x0000000B, 0x00005C8C, + 0x0000191D, 0x00050080, 0x0000000B, 0x00002DE1, 0x00003FF8, 0x00000A1C, 0x00060041, 0x00000288, + 0x0000191E, 0x00000CC7, 0x00000A0B, 0x00002DE1, 0x0004003D, 0x0000000B, 0x00005C8D, 0x0000191E, + 0x00050080, 0x0000000B, 0x00002DE2, 0x00003FF8, 0x00000A1F, 0x00060041, 0x00000288, 0x00006011, + 0x00000CC7, 0x00000A0B, 0x00002DE2, 0x0004003D, 0x0000000B, 0x0000400A, 0x00006011, 0x00070050, + 0x00000017, 0x0000513B, 0x00005C8B, 0x00005C8C, 0x00005C8D, 0x0000400A, 0x000200F9, 0x00004F29, + 0x000200F8, 0x00004F29, 0x000700F5, 0x00000017, 0x00002BD0, 0x0000513B, 0x0000262B, 0x0000513A, + 0x00002F68, 0x000700F5, 0x00000017, 0x00003723, 0x00004AE2, 0x0000262B, 0x00004CDA, 0x00002F68, + 0x000300F7, 0x00004F2A, 0x00000000, 0x000700FB, 0x00002180, 0x00004F59, 0x00000005, 0x0000215B, + 0x00000007, 0x0000203A, 0x000200F8, 0x0000203A, 0x00050051, 0x0000000B, 0x00005F5D, 0x00003723, + 0x00000000, 0x0006000C, 0x00000013, 0x0000606E, 0x00000001, 0x0000003E, 0x00005F5D, 0x00050051, + 0x0000000D, 0x0000278A, 0x0000606E, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC4, 0x0000606E, + 0x00000001, 0x00050051, 0x0000000B, 0x0000428D, 0x00003723, 0x00000001, 0x0006000C, 0x00000013, + 0x00003D01, 0x00000001, 0x0000003E, 0x0000428D, 0x00050051, 0x0000000D, 0x0000278B, 0x00003D01, + 0x00000000, 0x00050051, 0x0000000D, 0x0000445B, 0x00003D01, 0x00000001, 0x00070050, 0x0000001D, + 0x00003921, 0x0000278A, 0x00003EC4, 0x0000278B, 0x0000445B, 0x00050051, 0x0000000B, 0x0000438F, + 0x00003723, 0x00000002, 0x0006000C, 0x00000013, 0x00004680, 0x00000001, 0x0000003E, 0x0000438F, + 0x00050051, 0x0000000D, 0x0000278C, 0x00004680, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC5, + 0x00004680, 0x00000001, 0x00050051, 0x0000000B, 0x0000428E, 0x00003723, 0x00000003, 0x0006000C, + 0x00000013, 0x00003D02, 0x00000001, 0x0000003E, 0x0000428E, 0x00050051, 0x0000000D, 0x0000278D, + 0x00003D02, 0x00000000, 0x00050051, 0x0000000D, 0x0000445C, 0x00003D02, 0x00000001, 0x00070050, + 0x0000001D, 0x00003922, 0x0000278C, 0x00003EC5, 0x0000278D, 0x0000445C, 0x00050051, 0x0000000B, + 0x00004390, 0x00002BD0, 0x00000000, 0x0006000C, 0x00000013, 0x00004681, 0x00000001, 0x0000003E, + 0x00004390, 0x00050051, 0x0000000D, 0x0000278E, 0x00004681, 0x00000000, 0x00050051, 0x0000000D, + 0x00003EC6, 0x00004681, 0x00000001, 0x00050051, 0x0000000B, 0x0000428F, 0x00002BD0, 0x00000001, + 0x0006000C, 0x00000013, 0x00003D03, 0x00000001, 0x0000003E, 0x0000428F, 0x00050051, 0x0000000D, + 0x0000278F, 0x00003D03, 0x00000000, 0x00050051, 0x0000000D, 0x0000445D, 0x00003D03, 0x00000001, + 0x00070050, 0x0000001D, 0x00003923, 0x0000278E, 0x00003EC6, 0x0000278F, 0x0000445D, 0x00050051, + 0x0000000B, 0x00004391, 0x00002BD0, 0x00000002, 0x0006000C, 0x00000013, 0x00004682, 0x00000001, + 0x0000003E, 0x00004391, 0x00050051, 0x0000000D, 0x00002790, 0x00004682, 0x00000000, 0x00050051, + 0x0000000D, 0x00003EC7, 0x00004682, 0x00000001, 0x00050051, 0x0000000B, 0x00004290, 0x00002BD0, + 0x00000003, 0x0006000C, 0x00000013, 0x00003D04, 0x00000001, 0x0000003E, 0x00004290, 0x00050051, + 0x0000000D, 0x00002791, 0x00003D04, 0x00000000, 0x00050051, 0x0000000D, 0x000050C5, 0x00003D04, + 0x00000001, 0x00070050, 0x0000001D, 0x0000235B, 0x00002790, 0x00003EC7, 0x00002791, 0x000050C5, + 0x000200F9, 0x00004F2A, 0x000200F8, 0x0000215B, 0x0007004F, 0x00000011, 0x000025FE, 0x00003723, + 0x00003723, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x00005B3F, 0x000025FE, 0x0009004F, + 0x0000001A, 0x000060DA, 0x00005B3F, 0x00005B3F, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C4, 0x0000001A, 0x000048B8, 0x000060DA, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D99, + 0x000048B8, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AC7, 0x00003D99, 0x0005008E, 0x0000001D, + 0x00004733, 0x00002AC7, 0x000007FE, 0x0007000C, 0x0000001D, 0x0000629A, 0x00000001, 0x00000028, + 0x00000504, 0x00004733, 0x0007004F, 0x00000011, 0x00003774, 0x00003723, 0x00003723, 0x00000002, + 0x00000003, 0x0004007C, 0x00000012, 0x000024C8, 0x00003774, 0x0009004F, 0x0000001A, 0x000060DB, + 0x000024C8, 0x000024C8, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, + 0x000048B9, 0x000060DB, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D9A, 0x000048B9, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002AC8, 0x00003D9A, 0x0005008E, 0x0000001D, 0x00004734, 0x00002AC8, + 0x000007FE, 0x0007000C, 0x0000001D, 0x0000629B, 0x00000001, 0x00000028, 0x00000504, 0x00004734, + 0x0007004F, 0x00000011, 0x00003775, 0x00002BD0, 0x00002BD0, 0x00000000, 0x00000001, 0x0004007C, + 0x00000012, 0x000024C9, 0x00003775, 0x0009004F, 0x0000001A, 0x000060DC, 0x000024C9, 0x000024C9, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048BA, 0x000060DC, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D9B, 0x000048BA, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002AC9, 0x00003D9B, 0x0005008E, 0x0000001D, 0x00004735, 0x00002AC9, 0x000007FE, 0x0007000C, + 0x0000001D, 0x0000629C, 0x00000001, 0x00000028, 0x00000504, 0x00004735, 0x0007004F, 0x00000011, + 0x00003776, 0x00002BD0, 0x00002BD0, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024CA, + 0x00003776, 0x0009004F, 0x0000001A, 0x000060DD, 0x000024CA, 0x000024CA, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048BB, 0x000060DD, 0x00000122, 0x000500C3, + 0x0000001A, 0x00003D9C, 0x000048BB, 0x00000302, 0x0004006F, 0x0000001D, 0x00002ACA, 0x00003D9C, + 0x0005008E, 0x0000001D, 0x000053D2, 0x00002ACA, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004365, + 0x00000001, 0x00000028, 0x00000504, 0x000053D2, 0x000200F9, 0x00004F2A, 0x000200F8, 0x00004F59, + 0x0007004F, 0x00000011, 0x0000262C, 0x00003723, 0x00003723, 0x00000000, 0x00000001, 0x0004007C, + 0x00000013, 0x0000515D, 0x0000262C, 0x00050051, 0x0000000D, 0x00001B87, 0x0000515D, 0x00000000, + 0x00050051, 0x0000000D, 0x00003473, 0x0000515D, 0x00000001, 0x00070050, 0x0000001D, 0x00004291, + 0x00001B87, 0x00003473, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041E1, 0x00003723, + 0x00003723, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x00003766, 0x000041E1, 0x00050051, + 0x0000000D, 0x00001B88, 0x00003766, 0x00000000, 0x00050051, 0x0000000D, 0x00003474, 0x00003766, + 0x00000001, 0x00070050, 0x0000001D, 0x00004292, 0x00001B88, 0x00003474, 0x00000A0C, 0x00000A0C, + 0x0007004F, 0x00000011, 0x000041E2, 0x00002BD0, 0x00002BD0, 0x00000000, 0x00000001, 0x0004007C, + 0x00000013, 0x00003767, 0x000041E2, 0x00050051, 0x0000000D, 0x00001B89, 0x00003767, 0x00000000, + 0x00050051, 0x0000000D, 0x00003475, 0x00003767, 0x00000001, 0x00070050, 0x0000001D, 0x00004293, + 0x00001B89, 0x00003475, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041E3, 0x00002BD0, + 0x00002BD0, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x00003768, 0x000041E3, 0x00050051, + 0x0000000D, 0x00001B8A, 0x00003768, 0x00000000, 0x00050051, 0x0000000D, 0x0000410B, 0x00003768, + 0x00000001, 0x00070050, 0x0000001D, 0x0000235C, 0x00001B8A, 0x0000410B, 0x00000A0C, 0x00000A0C, + 0x000200F9, 0x00004F2A, 0x000200F8, 0x00004F2A, 0x000900F5, 0x0000001D, 0x00002BB1, 0x0000235C, + 0x00004F59, 0x00004365, 0x0000215B, 0x0000235B, 0x0000203A, 0x000900F5, 0x0000001D, 0x00003812, + 0x00004293, 0x00004F59, 0x0000629C, 0x0000215B, 0x00003923, 0x0000203A, 0x000900F5, 0x0000001D, + 0x00003B8C, 0x00004292, 0x00004F59, 0x0000629B, 0x0000215B, 0x00003922, 0x0000203A, 0x000900F5, + 0x0000001D, 0x000038BD, 0x00004291, 0x00004F59, 0x0000629A, 0x0000215B, 0x00003921, 0x0000203A, + 0x000200F9, 0x00005312, 0x000200F8, 0x00005312, 0x000700F5, 0x0000001D, 0x00002BB2, 0x00002BB1, + 0x00004F2A, 0x00002BB0, 0x00003F63, 0x000700F5, 0x0000001D, 0x00003813, 0x00003812, 0x00004F2A, + 0x00003811, 0x00003F63, 0x000700F5, 0x0000001D, 0x00003297, 0x00003B8C, 0x00004F2A, 0x00003B89, + 0x00003F63, 0x000700F5, 0x0000001D, 0x0000367C, 0x000038BD, 0x00004F2A, 0x000038BC, 0x00003F63, + 0x00050081, 0x0000001D, 0x0000435B, 0x0000435A, 0x0000367C, 0x00050081, 0x0000001D, 0x00005B03, + 0x00005B02, 0x00003297, 0x00050081, 0x0000001D, 0x00002523, 0x00001C28, 0x00003813, 0x00050081, + 0x0000001D, 0x00001E77, 0x000025AA, 0x00002BB2, 0x000200F9, 0x00005EC8, 0x000200F8, 0x00005EC8, + 0x000700F5, 0x0000001D, 0x00002BB3, 0x00005113, 0x00005310, 0x00001E77, 0x00005312, 0x000700F5, + 0x0000001D, 0x00003814, 0x00001F92, 0x00005310, 0x00002523, 0x00005312, 0x000700F5, 0x0000001D, + 0x00003B31, 0x00005B01, 0x00005310, 0x00005B03, 0x00005312, 0x000700F5, 0x0000001D, 0x00003B8D, + 0x00004359, 0x00005310, 0x0000435B, 0x00005312, 0x000700F5, 0x0000000D, 0x000038BE, 0x000061FB, + 0x00005310, 0x00002F3A, 0x00005312, 0x000200F9, 0x00005313, 0x000200F8, 0x00005313, 0x000700F5, + 0x0000001D, 0x00002BB4, 0x00002BA9, 0x0000530F, 0x00002BB3, 0x00005EC8, 0x000700F5, 0x0000001D, + 0x00003815, 0x0000380A, 0x0000530F, 0x00003814, 0x00005EC8, 0x000700F5, 0x0000001D, 0x00003B32, + 0x000035EC, 0x0000530F, 0x00003B31, 0x00005EC8, 0x000700F5, 0x0000001D, 0x0000338C, 0x000020D3, + 0x0000530F, 0x00003B8D, 0x00005EC8, 0x000700F5, 0x0000000D, 0x00002EA8, 0x00002B2C, 0x0000530F, + 0x000038BE, 0x00005EC8, 0x0005008E, 0x0000001D, 0x00005A74, 0x0000338C, 0x00002EA8, 0x0005008E, + 0x0000001D, 0x000019CC, 0x00003B32, 0x00002EA8, 0x0005008E, 0x0000001D, 0x0000306F, 0x00003815, + 0x00002EA8, 0x0005008E, 0x0000001D, 0x00003432, 0x00002BB4, 0x00002EA8, 0x000300F7, 0x00003F64, + 0x00000002, 0x000400FA, 0x00001D59, 0x00002741, 0x00003F64, 0x000200F8, 0x00002741, 0x0009004F, + 0x0000001D, 0x00003AEE, 0x00005A74, 0x00005A74, 0x00000002, 0x00000001, 0x00000000, 0x00000003, + 0x0009004F, 0x0000001D, 0x00003A07, 0x000019CC, 0x000019CC, 0x00000002, 0x00000001, 0x00000000, + 0x00000003, 0x0009004F, 0x0000001D, 0x00001CE6, 0x0000306F, 0x0000306F, 0x00000002, 0x00000001, + 0x00000000, 0x00000003, 0x0009004F, 0x0000001D, 0x00003EEF, 0x00003432, 0x00003432, 0x00000002, + 0x00000001, 0x00000000, 0x00000003, 0x000200F9, 0x00003F64, 0x000200F8, 0x00003F64, 0x000700F5, + 0x0000001D, 0x00002BB5, 0x00003432, 0x00005313, 0x00003EEF, 0x00002741, 0x000700F5, 0x0000001D, + 0x00003816, 0x0000306F, 0x00005313, 0x00001CE6, 0x00002741, 0x000700F5, 0x0000001D, 0x00003B57, + 0x000019CC, 0x00005313, 0x00003A07, 0x00002741, 0x000700F5, 0x0000001D, 0x00003A49, 0x00005A74, + 0x00005313, 0x00003AEE, 0x00002741, 0x000300F7, 0x00004992, 0x00000000, 0x000F00FB, 0x00005093, + 0x00001CCE, 0x00000003, 0x000045EB, 0x00000004, 0x00001934, 0x00000005, 0x00001933, 0x0000000A, + 0x00001CCD, 0x0000000F, 0x00003167, 0x00000018, 0x00002514, 0x000200F8, 0x00002514, 0x00050051, + 0x0000000D, 0x00003AC1, 0x00003A49, 0x00000000, 0x00050051, 0x0000000D, 0x00002825, 0x00003B57, + 0x00000000, 0x00050051, 0x0000000D, 0x00001DD9, 0x00003816, 0x00000000, 0x00050051, 0x0000000D, + 0x000019A5, 0x00002BB5, 0x00000000, 0x00070050, 0x0000001D, 0x00001D37, 0x00003AC1, 0x00002825, + 0x00001DD9, 0x000019A5, 0x0008000C, 0x0000001D, 0x00003846, 0x00000001, 0x0000002B, 0x00001D37, + 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, 0x00003577, 0x00003846, 0x0000022D, 0x00050081, + 0x0000001D, 0x00002E40, 0x00003577, 0x00000145, 0x0004006D, 0x00000017, 0x00001F0B, 0x00002E40, + 0x0007004F, 0x00000011, 0x000018D9, 0x00001F0B, 0x00001F0B, 0x00000000, 0x00000002, 0x0007004F, + 0x00000011, 0x00002750, 0x00001F0B, 0x00001F0B, 0x00000001, 0x00000003, 0x000500C4, 0x00000011, + 0x00003546, 0x00002750, 0x00000867, 0x000500C5, 0x00000011, 0x00003D25, 0x000018D9, 0x00003546, + 0x000200F9, 0x00004992, 0x000200F8, 0x00003167, 0x0008000C, 0x0000001D, 0x00001C8F, 0x00000001, + 0x0000002B, 0x00003A49, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, 0x00004F73, 0x00001C8F, + 0x000001C1, 0x00050081, 0x0000001D, 0x00002E66, 0x00004F73, 0x00000145, 0x0004006D, 0x00000017, + 0x00001DD7, 0x00002E66, 0x00050051, 0x0000000B, 0x000021FC, 0x00001DD7, 0x00000000, 0x00050051, + 0x0000000B, 0x00002FDB, 0x00001DD7, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D29, 0x00002FDB, + 0x00000A17, 0x000500C5, 0x0000000B, 0x00004D66, 0x000021FC, 0x00002D29, 0x00050051, 0x0000000B, + 0x000053E4, 0x00001DD7, 0x00000002, 0x000500C4, 0x0000000B, 0x00002170, 0x000053E4, 0x00000A23, + 0x000500C5, 0x0000000B, 0x00004D67, 0x00004D66, 0x00002170, 0x00050051, 0x0000000B, 0x000053E5, + 0x00001DD7, 0x00000003, 0x000500C4, 0x0000000B, 0x00001C7C, 0x000053E5, 0x00000A2F, 0x000500C5, + 0x0000000B, 0x00002427, 0x00004D67, 0x00001C7C, 0x0008000C, 0x0000001D, 0x00001D62, 0x00000001, + 0x0000002B, 0x00003B57, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, 0x00002048, 0x00001D62, + 0x000001C1, 0x00050081, 0x0000001D, 0x00002E67, 0x00002048, 0x00000145, 0x0004006D, 0x00000017, + 0x00001DDA, 0x00002E67, 0x00050051, 0x0000000B, 0x000021FD, 0x00001DDA, 0x00000000, 0x00050051, + 0x0000000B, 0x00002FDC, 0x00001DDA, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D2A, 0x00002FDC, + 0x00000A17, 0x000500C5, 0x0000000B, 0x00004D68, 0x000021FD, 0x00002D2A, 0x00050051, 0x0000000B, + 0x000053E6, 0x00001DDA, 0x00000002, 0x000500C4, 0x0000000B, 0x00002171, 0x000053E6, 0x00000A23, + 0x000500C5, 0x0000000B, 0x00004D69, 0x00004D68, 0x00002171, 0x00050051, 0x0000000B, 0x000053E7, + 0x00001DDA, 0x00000003, 0x000500C4, 0x0000000B, 0x000029F9, 0x000053E7, 0x00000A2F, 0x000500C5, + 0x0000000B, 0x00004A41, 0x00004D69, 0x000029F9, 0x000500C4, 0x0000000B, 0x000058C9, 0x00004A41, + 0x00000A3A, 0x000500C5, 0x0000000B, 0x0000186E, 0x00002427, 0x000058C9, 0x0008000C, 0x0000001D, + 0x00001D63, 0x00000001, 0x0000002B, 0x00003816, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, + 0x00002049, 0x00001D63, 0x000001C1, 0x00050081, 0x0000001D, 0x00002E69, 0x00002049, 0x00000145, + 0x0004006D, 0x00000017, 0x00001DDB, 0x00002E69, 0x00050051, 0x0000000B, 0x000021FE, 0x00001DDB, + 0x00000000, 0x00050051, 0x0000000B, 0x00002FDD, 0x00001DDB, 0x00000001, 0x000500C4, 0x0000000B, + 0x00002D2B, 0x00002FDD, 0x00000A17, 0x000500C5, 0x0000000B, 0x00004D6A, 0x000021FE, 0x00002D2B, + 0x00050051, 0x0000000B, 0x000053E8, 0x00001DDB, 0x00000002, 0x000500C4, 0x0000000B, 0x00002172, + 0x000053E8, 0x00000A23, 0x000500C5, 0x0000000B, 0x00004D6B, 0x00004D6A, 0x00002172, 0x00050051, + 0x0000000B, 0x000053E9, 0x00001DDB, 0x00000003, 0x000500C4, 0x0000000B, 0x00001C7D, 0x000053E9, + 0x00000A2F, 0x000500C5, 0x0000000B, 0x00002428, 0x00004D6B, 0x00001C7D, 0x0008000C, 0x0000001D, + 0x00001D64, 0x00000001, 0x0000002B, 0x00002BB5, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, + 0x0000204A, 0x00001D64, 0x000001C1, 0x00050081, 0x0000001D, 0x00002E6A, 0x0000204A, 0x00000145, + 0x0004006D, 0x00000017, 0x00001DDC, 0x00002E6A, 0x00050051, 0x0000000B, 0x000021FF, 0x00001DDC, + 0x00000000, 0x00050051, 0x0000000B, 0x00002FDE, 0x00001DDC, 0x00000001, 0x000500C4, 0x0000000B, + 0x00002D2C, 0x00002FDE, 0x00000A17, 0x000500C5, 0x0000000B, 0x00004D6C, 0x000021FF, 0x00002D2C, + 0x00050051, 0x0000000B, 0x000053EA, 0x00001DDC, 0x00000002, 0x000500C4, 0x0000000B, 0x00002173, + 0x000053EA, 0x00000A23, 0x000500C5, 0x0000000B, 0x00004D6D, 0x00004D6C, 0x00002173, 0x00050051, + 0x0000000B, 0x000053EB, 0x00001DDC, 0x00000003, 0x000500C4, 0x0000000B, 0x000029FA, 0x000053EB, + 0x00000A2F, 0x000500C5, 0x0000000B, 0x00004A42, 0x00004D6D, 0x000029FA, 0x000500C4, 0x0000000B, + 0x00005DAA, 0x00004A42, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00004649, 0x00002428, 0x00005DAA, + 0x00050050, 0x00000011, 0x000053DD, 0x0000186E, 0x00004649, 0x000200F9, 0x00004992, 0x000200F8, + 0x00001CCD, 0x00050051, 0x0000000D, 0x00004DAD, 0x00003A49, 0x00000000, 0x00050051, 0x0000000D, + 0x00002826, 0x00003A49, 0x00000001, 0x00050051, 0x0000000D, 0x00001DDD, 0x00003B57, 0x00000000, + 0x00050051, 0x0000000D, 0x000019A6, 0x00003B57, 0x00000001, 0x00070050, 0x0000001D, 0x00001D38, + 0x00004DAD, 0x00002826, 0x00001DDD, 0x000019A6, 0x0008000C, 0x0000001D, 0x00003847, 0x00000001, + 0x0000002B, 0x00001D38, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, 0x00003578, 0x00003847, + 0x00000540, 0x00050081, 0x0000001D, 0x00002E6B, 0x00003578, 0x00000145, 0x0004006D, 0x00000017, + 0x00001DDE, 0x00002E6B, 0x00050051, 0x0000000B, 0x00002200, 0x00001DDE, 0x00000000, 0x00050051, + 0x0000000B, 0x00002FDF, 0x00001DDE, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D2D, 0x00002FDF, + 0x00000A23, 0x000500C5, 0x0000000B, 0x00004D6E, 0x00002200, 0x00002D2D, 0x00050051, 0x0000000B, + 0x000053EC, 0x00001DDE, 0x00000002, 0x000500C4, 0x0000000B, 0x00002174, 0x000053EC, 0x00000A3B, + 0x000500C5, 0x0000000B, 0x00004D6F, 0x00004D6E, 0x00002174, 0x00050051, 0x0000000B, 0x000053ED, + 0x00001DDE, 0x00000003, 0x000500C4, 0x0000000B, 0x00002175, 0x000053ED, 0x00000A53, 0x000500C5, + 0x0000000B, 0x000044DD, 0x00004D6F, 0x00002175, 0x00050051, 0x0000000D, 0x00004E80, 0x00003816, + 0x00000000, 0x00050051, 0x0000000D, 0x00005CB2, 0x00003816, 0x00000001, 0x00050051, 0x0000000D, + 0x00001DDF, 0x00002BB5, 0x00000000, 0x00050051, 0x0000000D, 0x000019A7, 0x00002BB5, 0x00000001, + 0x00070050, 0x0000001D, 0x00001D39, 0x00004E80, 0x00005CB2, 0x00001DDF, 0x000019A7, 0x0008000C, + 0x0000001D, 0x00003848, 0x00000001, 0x0000002B, 0x00001D39, 0x00000B7A, 0x00000505, 0x0005008E, + 0x0000001D, 0x00003579, 0x00003848, 0x00000540, 0x00050081, 0x0000001D, 0x00002E6C, 0x00003579, + 0x00000145, 0x0004006D, 0x00000017, 0x00001DE0, 0x00002E6C, 0x00050051, 0x0000000B, 0x00002201, + 0x00001DE0, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE0, 0x00001DE0, 0x00000001, 0x000500C4, + 0x0000000B, 0x00002D2E, 0x00002FE0, 0x00000A23, 0x000500C5, 0x0000000B, 0x00004D70, 0x00002201, + 0x00002D2E, 0x00050051, 0x0000000B, 0x000053EE, 0x00001DE0, 0x00000002, 0x000500C4, 0x0000000B, + 0x00002176, 0x000053EE, 0x00000A3B, 0x000500C5, 0x0000000B, 0x00004D71, 0x00004D70, 0x00002176, + 0x00050051, 0x0000000B, 0x000053EF, 0x00001DE0, 0x00000003, 0x000500C4, 0x0000000B, 0x0000215D, + 0x000053EF, 0x00000A53, 0x000500C5, 0x0000000B, 0x00005202, 0x00004D71, 0x0000215D, 0x00050050, + 0x00000011, 0x000053DE, 0x000044DD, 0x00005202, 0x000200F9, 0x00004992, 0x000200F8, 0x00001933, + 0x0008004F, 0x00000018, 0x000021CF, 0x00003A49, 0x00003A49, 0x00000000, 0x00000001, 0x00000002, + 0x0008000C, 0x00000018, 0x00001847, 0x00000001, 0x0000002B, 0x000021CF, 0x00000A2D, 0x00000A18, + 0x00050085, 0x00000018, 0x00001BC1, 0x00001847, 0x000003BE, 0x00050081, 0x00000018, 0x00001F1A, + 0x00001BC1, 0x000003AB, 0x0004006D, 0x00000014, 0x00002752, 0x00001F1A, 0x00050051, 0x0000000B, + 0x00002202, 0x00002752, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE1, 0x00002752, 0x00000001, + 0x000500C4, 0x0000000B, 0x00002D2F, 0x00002FE1, 0x00000A1A, 0x000500C5, 0x0000000B, 0x00004D72, + 0x00002202, 0x00002D2F, 0x00050051, 0x0000000B, 0x000053F0, 0x00002752, 0x00000002, 0x000500C4, + 0x0000000B, 0x0000214A, 0x000053F0, 0x00000A29, 0x000500C5, 0x0000000B, 0x00004143, 0x00004D72, + 0x0000214A, 0x0008004F, 0x00000018, 0x000022A2, 0x00003B57, 0x00003B57, 0x00000000, 0x00000001, + 0x00000002, 0x0008000C, 0x00000018, 0x00004CD4, 0x00000001, 0x0000002B, 0x000022A2, 0x00000A2D, + 0x00000A18, 0x00050085, 0x00000018, 0x00001BC2, 0x00004CD4, 0x000003BE, 0x00050081, 0x00000018, + 0x00001F1B, 0x00001BC2, 0x000003AB, 0x0004006D, 0x00000014, 0x00002753, 0x00001F1B, 0x00050051, + 0x0000000B, 0x00002203, 0x00002753, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE2, 0x00002753, + 0x00000001, 0x000500C4, 0x0000000B, 0x00002D30, 0x00002FE2, 0x00000A1A, 0x000500C5, 0x0000000B, + 0x00004D73, 0x00002203, 0x00002D30, 0x00050051, 0x0000000B, 0x000053F1, 0x00002753, 0x00000002, + 0x000500C4, 0x0000000B, 0x000029FB, 0x000053F1, 0x00000A29, 0x000500C5, 0x0000000B, 0x00004A43, + 0x00004D73, 0x000029FB, 0x000500C4, 0x0000000B, 0x00005D97, 0x00004A43, 0x00000A3A, 0x000500C5, + 0x0000000B, 0x0000358A, 0x00004143, 0x00005D97, 0x0008004F, 0x00000018, 0x000022A3, 0x00003816, + 0x00003816, 0x00000000, 0x00000001, 0x00000002, 0x0008000C, 0x00000018, 0x00004CD5, 0x00000001, + 0x0000002B, 0x000022A3, 0x00000A2D, 0x00000A18, 0x00050085, 0x00000018, 0x00001BC3, 0x00004CD5, + 0x000003BE, 0x00050081, 0x00000018, 0x00001F1C, 0x00001BC3, 0x000003AB, 0x0004006D, 0x00000014, + 0x00002754, 0x00001F1C, 0x00050051, 0x0000000B, 0x00002204, 0x00002754, 0x00000000, 0x00050051, + 0x0000000B, 0x00002FE3, 0x00002754, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D31, 0x00002FE3, + 0x00000A1A, 0x000500C5, 0x0000000B, 0x00004D74, 0x00002204, 0x00002D31, 0x00050051, 0x0000000B, + 0x000053F2, 0x00002754, 0x00000002, 0x000500C4, 0x0000000B, 0x0000214B, 0x000053F2, 0x00000A29, + 0x000500C5, 0x0000000B, 0x00004144, 0x00004D74, 0x0000214B, 0x0008004F, 0x00000018, 0x000022A4, + 0x00002BB5, 0x00002BB5, 0x00000000, 0x00000001, 0x00000002, 0x0008000C, 0x00000018, 0x00004CDB, + 0x00000001, 0x0000002B, 0x000022A4, 0x00000A2D, 0x00000A18, 0x00050085, 0x00000018, 0x00001BC4, + 0x00004CDB, 0x000003BE, 0x00050081, 0x00000018, 0x00001F1D, 0x00001BC4, 0x000003AB, 0x0004006D, + 0x00000014, 0x00002755, 0x00001F1D, 0x00050051, 0x0000000B, 0x00002205, 0x00002755, 0x00000000, + 0x00050051, 0x0000000B, 0x00002FE4, 0x00002755, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D32, + 0x00002FE4, 0x00000A1A, 0x000500C5, 0x0000000B, 0x00004D75, 0x00002205, 0x00002D32, 0x00050051, + 0x0000000B, 0x000053F3, 0x00002755, 0x00000002, 0x000500C4, 0x0000000B, 0x000029FC, 0x000053F3, + 0x00000A29, 0x000500C5, 0x0000000B, 0x00004A44, 0x00004D75, 0x000029FC, 0x000500C4, 0x0000000B, + 0x00005DAB, 0x00004A44, 0x00000A3A, 0x000500C5, 0x0000000B, 0x0000464A, 0x00004144, 0x00005DAB, + 0x00050050, 0x00000011, 0x000053DF, 0x0000358A, 0x0000464A, 0x000200F9, 0x00004992, 0x000200F8, + 0x00001934, 0x0008004F, 0x00000018, 0x000021D0, 0x00003A49, 0x00003A49, 0x00000000, 0x00000001, + 0x00000002, 0x0008000C, 0x00000018, 0x00001848, 0x00000001, 0x0000002B, 0x000021D0, 0x00000A2D, + 0x00000A18, 0x00050085, 0x00000018, 0x00001BC5, 0x00001848, 0x000001FF, 0x00050081, 0x00000018, + 0x00001F1E, 0x00001BC5, 0x000003AB, 0x0004006D, 0x00000014, 0x00002756, 0x00001F1E, 0x00050051, + 0x0000000B, 0x00002206, 0x00002756, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE5, 0x00002756, + 0x00000001, 0x000500C4, 0x0000000B, 0x00002D33, 0x00002FE5, 0x00000A1A, 0x000500C5, 0x0000000B, + 0x00004D76, 0x00002206, 0x00002D33, 0x00050051, 0x0000000B, 0x000053F4, 0x00002756, 0x00000002, + 0x000500C4, 0x0000000B, 0x0000214C, 0x000053F4, 0x00000A2C, 0x000500C5, 0x0000000B, 0x00004145, + 0x00004D76, 0x0000214C, 0x0008004F, 0x00000018, 0x000022A5, 0x00003B57, 0x00003B57, 0x00000000, + 0x00000001, 0x00000002, 0x0008000C, 0x00000018, 0x00004CDC, 0x00000001, 0x0000002B, 0x000022A5, + 0x00000A2D, 0x00000A18, 0x00050085, 0x00000018, 0x00001BC6, 0x00004CDC, 0x000001FF, 0x00050081, + 0x00000018, 0x00001F1F, 0x00001BC6, 0x000003AB, 0x0004006D, 0x00000014, 0x00002757, 0x00001F1F, + 0x00050051, 0x0000000B, 0x00002207, 0x00002757, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE6, + 0x00002757, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D34, 0x00002FE6, 0x00000A1A, 0x000500C5, + 0x0000000B, 0x00004D77, 0x00002207, 0x00002D34, 0x00050051, 0x0000000B, 0x000053F5, 0x00002757, + 0x00000002, 0x000500C4, 0x0000000B, 0x000029FD, 0x000053F5, 0x00000A2C, 0x000500C5, 0x0000000B, + 0x00004A45, 0x00004D77, 0x000029FD, 0x000500C4, 0x0000000B, 0x00005D98, 0x00004A45, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x0000358B, 0x00004145, 0x00005D98, 0x0008004F, 0x00000018, 0x000022A6, + 0x00003816, 0x00003816, 0x00000000, 0x00000001, 0x00000002, 0x0008000C, 0x00000018, 0x00004CDD, + 0x00000001, 0x0000002B, 0x000022A6, 0x00000A2D, 0x00000A18, 0x00050085, 0x00000018, 0x00001BC7, + 0x00004CDD, 0x000001FF, 0x00050081, 0x00000018, 0x00001F20, 0x00001BC7, 0x000003AB, 0x0004006D, + 0x00000014, 0x00002758, 0x00001F20, 0x00050051, 0x0000000B, 0x00002208, 0x00002758, 0x00000000, + 0x00050051, 0x0000000B, 0x00002FE7, 0x00002758, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D35, + 0x00002FE7, 0x00000A1A, 0x000500C5, 0x0000000B, 0x00004D78, 0x00002208, 0x00002D35, 0x00050051, + 0x0000000B, 0x000053F6, 0x00002758, 0x00000002, 0x000500C4, 0x0000000B, 0x0000214D, 0x000053F6, + 0x00000A2C, 0x000500C5, 0x0000000B, 0x00004146, 0x00004D78, 0x0000214D, 0x0008004F, 0x00000018, + 0x000022A8, 0x00002BB5, 0x00002BB5, 0x00000000, 0x00000001, 0x00000002, 0x0008000C, 0x00000018, + 0x00004CDE, 0x00000001, 0x0000002B, 0x000022A8, 0x00000A2D, 0x00000A18, 0x00050085, 0x00000018, + 0x00001BC8, 0x00004CDE, 0x000001FF, 0x00050081, 0x00000018, 0x00001F21, 0x00001BC8, 0x000003AB, + 0x0004006D, 0x00000014, 0x00002759, 0x00001F21, 0x00050051, 0x0000000B, 0x00002209, 0x00002759, + 0x00000000, 0x00050051, 0x0000000B, 0x00002FE8, 0x00002759, 0x00000001, 0x000500C4, 0x0000000B, + 0x00002D36, 0x00002FE8, 0x00000A1A, 0x000500C5, 0x0000000B, 0x00004D79, 0x00002209, 0x00002D36, + 0x00050051, 0x0000000B, 0x000053F7, 0x00002759, 0x00000002, 0x000500C4, 0x0000000B, 0x000029FE, + 0x000053F7, 0x00000A2C, 0x000500C5, 0x0000000B, 0x00004A46, 0x00004D79, 0x000029FE, 0x000500C4, + 0x0000000B, 0x00005DAC, 0x00004A46, 0x00000A3A, 0x000500C5, 0x0000000B, 0x0000464B, 0x00004146, + 0x00005DAC, 0x00050050, 0x00000011, 0x000053E0, 0x0000358B, 0x0000464B, 0x000200F9, 0x00004992, + 0x000200F8, 0x000045EB, 0x0008000C, 0x0000001D, 0x000022A9, 0x00000001, 0x0000002B, 0x00003A49, + 0x00000B7A, 0x00000505, 0x00050085, 0x0000001D, 0x00004580, 0x000022A9, 0x00000809, 0x00050081, + 0x0000001D, 0x00001F22, 0x00004580, 0x00000145, 0x0004006D, 0x00000017, 0x0000275A, 0x00001F22, + 0x00050051, 0x0000000B, 0x0000220A, 0x0000275A, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE9, + 0x0000275A, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D37, 0x00002FE9, 0x00000A1A, 0x000500C5, + 0x0000000B, 0x00004D7A, 0x0000220A, 0x00002D37, 0x00050051, 0x0000000B, 0x000053F8, 0x0000275A, + 0x00000002, 0x000500C4, 0x0000000B, 0x00002177, 0x000053F8, 0x00000A29, 0x000500C5, 0x0000000B, + 0x00004D7B, 0x00004D7A, 0x00002177, 0x00050051, 0x0000000B, 0x000053F9, 0x0000275A, 0x00000003, + 0x000500C4, 0x0000000B, 0x00001C7E, 0x000053F9, 0x00000A38, 0x000500C5, 0x0000000B, 0x0000237C, + 0x00004D7B, 0x00001C7E, 0x0008000C, 0x0000001D, 0x00002377, 0x00000001, 0x0000002B, 0x00003B57, + 0x00000B7A, 0x00000505, 0x00050085, 0x0000001D, 0x000060DE, 0x00002377, 0x00000809, 0x00050081, + 0x0000001D, 0x00001F23, 0x000060DE, 0x00000145, 0x0004006D, 0x00000017, 0x0000275B, 0x00001F23, + 0x00050051, 0x0000000B, 0x0000220B, 0x0000275B, 0x00000000, 0x00050051, 0x0000000B, 0x00002FEA, + 0x0000275B, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D38, 0x00002FEA, 0x00000A1A, 0x000500C5, + 0x0000000B, 0x00004D7C, 0x0000220B, 0x00002D38, 0x00050051, 0x0000000B, 0x000053FA, 0x0000275B, + 0x00000002, 0x000500C4, 0x0000000B, 0x00002178, 0x000053FA, 0x00000A29, 0x000500C5, 0x0000000B, + 0x00004D7D, 0x00004D7C, 0x00002178, 0x00050051, 0x0000000B, 0x000053FB, 0x0000275B, 0x00000003, + 0x000500C4, 0x0000000B, 0x000029FF, 0x000053FB, 0x00000A38, 0x000500C5, 0x0000000B, 0x00004A47, + 0x00004D7D, 0x000029FF, 0x000500C4, 0x0000000B, 0x000058CA, 0x00004A47, 0x00000A3A, 0x000500C5, + 0x0000000B, 0x00006242, 0x0000237C, 0x000058CA, 0x0008000C, 0x0000001D, 0x00002378, 0x00000001, + 0x0000002B, 0x00003816, 0x00000B7A, 0x00000505, 0x00050085, 0x0000001D, 0x000060DF, 0x00002378, + 0x00000809, 0x00050081, 0x0000001D, 0x00001F24, 0x000060DF, 0x00000145, 0x0004006D, 0x00000017, + 0x0000275C, 0x00001F24, 0x00050051, 0x0000000B, 0x0000220C, 0x0000275C, 0x00000000, 0x00050051, + 0x0000000B, 0x00002FEB, 0x0000275C, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D39, 0x00002FEB, + 0x00000A1A, 0x000500C5, 0x0000000B, 0x00004D7E, 0x0000220C, 0x00002D39, 0x00050051, 0x0000000B, + 0x000053FC, 0x0000275C, 0x00000002, 0x000500C4, 0x0000000B, 0x00002179, 0x000053FC, 0x00000A29, + 0x000500C5, 0x0000000B, 0x00004D7F, 0x00004D7E, 0x00002179, 0x00050051, 0x0000000B, 0x000053FD, + 0x0000275C, 0x00000003, 0x000500C4, 0x0000000B, 0x00001C7F, 0x000053FD, 0x00000A38, 0x000500C5, + 0x0000000B, 0x0000237D, 0x00004D7F, 0x00001C7F, 0x0008000C, 0x0000001D, 0x00002379, 0x00000001, + 0x0000002B, 0x00002BB5, 0x00000B7A, 0x00000505, 0x00050085, 0x0000001D, 0x000060E0, 0x00002379, + 0x00000809, 0x00050081, 0x0000001D, 0x00001F25, 0x000060E0, 0x00000145, 0x0004006D, 0x00000017, + 0x0000275D, 0x00001F25, 0x00050051, 0x0000000B, 0x0000220D, 0x0000275D, 0x00000000, 0x00050051, + 0x0000000B, 0x00002FEC, 0x0000275D, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D3A, 0x00002FEC, + 0x00000A1A, 0x000500C5, 0x0000000B, 0x00004D80, 0x0000220D, 0x00002D3A, 0x00050051, 0x0000000B, + 0x000053FE, 0x0000275D, 0x00000002, 0x000500C4, 0x0000000B, 0x0000217A, 0x000053FE, 0x00000A29, + 0x000500C5, 0x0000000B, 0x00004D81, 0x00004D80, 0x0000217A, 0x00050051, 0x0000000B, 0x000053FF, + 0x0000275D, 0x00000003, 0x000500C4, 0x0000000B, 0x00002A00, 0x000053FF, 0x00000A38, 0x000500C5, + 0x0000000B, 0x00004A48, 0x00004D81, 0x00002A00, 0x000500C4, 0x0000000B, 0x00005DAD, 0x00004A48, + 0x00000A3A, 0x000500C5, 0x0000000B, 0x0000464C, 0x0000237D, 0x00005DAD, 0x00050050, 0x00000011, + 0x000053E1, 0x00006242, 0x0000464C, 0x000200F9, 0x00004992, 0x000200F8, 0x00001CCE, 0x00050051, + 0x0000000D, 0x00004D9A, 0x00003A49, 0x00000000, 0x00050051, 0x0000000D, 0x000023ED, 0x00003B57, + 0x00000000, 0x00050050, 0x00000013, 0x00004B20, 0x00004D9A, 0x000023ED, 0x0006000C, 0x0000000B, + 0x0000217B, 0x00000001, 0x0000003A, 0x00004B20, 0x00050051, 0x0000000D, 0x00005BBF, 0x00003816, + 0x00000000, 0x00050051, 0x0000000D, 0x000039A7, 0x00002BB5, 0x00000000, 0x00050050, 0x00000013, + 0x00004B0D, 0x00005BBF, 0x000039A7, 0x0006000C, 0x0000000B, 0x00002E96, 0x00000001, 0x0000003A, + 0x00004B0D, 0x00050050, 0x00000011, 0x0000612F, 0x0000217B, 0x00002E96, 0x000200F9, 0x00004992, + 0x000200F8, 0x00004992, 0x001100F5, 0x00000011, 0x000058B2, 0x0000612F, 0x00001CCE, 0x000053E1, + 0x000045EB, 0x000053E0, 0x00001934, 0x000053DF, 0x00001933, 0x000053DE, 0x00001CCD, 0x000053DD, + 0x00003167, 0x00003D25, 0x00002514, 0x000500AA, 0x00000009, 0x00004AAF, 0x00001DD8, 0x00000A0A, + 0x000600A9, 0x00000009, 0x000056E6, 0x00004AAF, 0x00000787, 0x00004AAF, 0x000300F7, 0x00004CC1, + 0x00000002, 0x000400FA, 0x000056E6, 0x00002E70, 0x00004CC1, 0x000200F8, 0x00002E70, 0x00050051, + 0x0000000B, 0x00004B1B, 0x000058B2, 0x00000000, 0x000500C2, 0x0000000B, 0x00003427, 0x00004B1B, + 0x00000A3A, 0x000500C7, 0x0000000B, 0x00001C34, 0x00004B1B, 0x0000068D, 0x000500C5, 0x0000000B, + 0x0000452D, 0x00003427, 0x00001C34, 0x00060052, 0x00000011, 0x00005B32, 0x0000452D, 0x000058B2, + 0x00000000, 0x000200F9, 0x00004CC1, 0x000200F8, 0x00004CC1, 0x000700F5, 0x00000011, 0x0000305F, + 0x000058B2, 0x00004992, 0x00005B32, 0x00002E70, 0x00050080, 0x00000011, 0x000032A7, 0x00002EF9, + 0x000059EC, 0x000300F7, 0x000052F5, 0x00000002, 0x000400FA, 0x0000500F, 0x0000294E, 0x0000537D, + 0x000200F8, 0x0000537D, 0x0004007C, 0x00000012, 0x00002970, 0x000032A7, 0x00050051, 0x0000000C, + 0x000042C2, 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, + 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, + 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00003DA7, 0x00000A19, 0x0004007C, + 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AA, + 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, + 0x00003F5E, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002ACB, 0x000042C2, 0x00000A20, 0x000500C7, + 0x0000000C, 0x00003138, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, + 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002ACB, 0x0000454D, 0x000500C4, 0x0000000C, + 0x000018E7, 0x00004397, 0x00000A0D, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, + 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, + 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, + 0x0000000C, 0x00004D30, 0x00003C4B, 0x00003397, 0x000500C7, 0x0000000C, 0x000047BD, 0x00002747, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544A, 0x000047BD, 0x00000A17, 0x00050080, 0x0000000C, + 0x00004157, 0x00004D30, 0x0000544A, 0x000500C7, 0x0000000C, 0x00005022, 0x00004157, 0x0000040B, + 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, + 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, + 0x0000000C, 0x00004158, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004AE3, 0x00004157, + 0x00000388, 0x000500C4, 0x0000000C, 0x0000544B, 0x00004AE3, 0x00000A11, 0x00050080, 0x0000000C, + 0x00004147, 0x00004158, 0x0000544B, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, + 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, + 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, + 0x0000000C, 0x00005454, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544C, 0x00005454, + 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004147, 0x0000544C, 0x000500C7, 0x0000000C, + 0x00002E06, 0x00004157, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4C, 0x00002E06, + 0x0004007C, 0x0000000B, 0x0000566F, 0x0000394F, 0x000200F9, 0x000052F5, 0x000200F8, 0x0000294E, + 0x00050051, 0x0000000B, 0x00004D9B, 0x000032A7, 0x00000000, 0x00050051, 0x0000000B, 0x00002C03, + 0x000032A7, 0x00000001, 0x00060050, 0x00000014, 0x000020DE, 0x00004D9B, 0x00002C03, 0x00005F72, + 0x0004007C, 0x00000016, 0x00004E9D, 0x000020DE, 0x00050051, 0x0000000C, 0x000028C6, 0x00004E9D, + 0x00000001, 0x000500C3, 0x0000000C, 0x000024FE, 0x000028C6, 0x00000A17, 0x00050051, 0x0000000C, + 0x00002748, 0x00004E9D, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A11, + 0x000500C2, 0x0000000B, 0x00005B4E, 0x00006273, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AB, + 0x00005B4E, 0x00050084, 0x0000000C, 0x00005321, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, + 0x00003B27, 0x000024FE, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00003DA7, 0x00000A19, + 0x0004007C, 0x0000000C, 0x00003097, 0x00002348, 0x00050084, 0x0000000C, 0x0000287F, 0x00003B27, + 0x00003097, 0x00050051, 0x0000000C, 0x00006243, 0x00004E9D, 0x00000000, 0x000500C3, 0x0000000C, + 0x00004FC7, 0x00006243, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x0000287F, + 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A1F, 0x000500C7, 0x0000000C, 0x00002CF6, + 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, + 0x0000000C, 0x00004D38, 0x00006243, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x000028C6, + 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, + 0x0000434B, 0x00004D38, 0x0000454E, 0x000500C4, 0x0000000C, 0x00001B8B, 0x0000434B, 0x00000A1F, + 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B8B, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002220, + 0x000028C6, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002220, 0x0000405D, 0x000500C7, + 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006243, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, + 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004AE4, 0x000034BD, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000544D, 0x00004AE4, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4D, + 0x00005A0C, 0x0000544D, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, + 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B33, 0x00004F70, + 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, + 0x0000285C, 0x00005B33, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047BE, 0x00002748, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000544E, 0x000047BE, 0x00000A1F, 0x00050080, 0x0000000C, 0x00004159, + 0x0000285C, 0x0000544E, 0x000500C7, 0x0000000C, 0x00004AE5, 0x000028C6, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x0000544F, 0x00004AE5, 0x00000A17, 0x00050080, 0x0000000C, 0x0000415A, 0x00004159, + 0x0000544F, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4D, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x0000415A, 0x00000A1D, + 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, + 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B34, 0x00003412, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00005AB1, 0x00003C4D, 0x00000A05, 0x00050080, 0x0000000C, 0x00002ACC, 0x00005B34, + 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B35, 0x00002ACC, 0x00000A11, 0x000500C7, 0x0000000C, + 0x00005AB2, 0x0000415A, 0x0000040B, 0x00050080, 0x0000000C, 0x00002ACD, 0x00005B35, 0x00005AB2, + 0x000500C4, 0x0000000C, 0x00005B36, 0x00002ACD, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, + 0x0000415A, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B36, 0x00005559, 0x0004007C, + 0x0000000B, 0x00005670, 0x00005EFA, 0x000200F9, 0x000052F5, 0x000200F8, 0x000052F5, 0x000700F5, + 0x0000000B, 0x00002C70, 0x00005670, 0x0000294E, 0x0000566F, 0x0000537D, 0x00050080, 0x0000000B, + 0x00005088, 0x00002C70, 0x000062B6, 0x000500C2, 0x0000000B, 0x00004EAA, 0x00005088, 0x00000A13, + 0x000500AA, 0x00000009, 0x00004B9C, 0x00004ADC, 0x00000A0D, 0x000300F7, 0x00002C98, 0x00000000, + 0x000400FA, 0x00004B9C, 0x00002957, 0x00002C98, 0x000200F8, 0x00002957, 0x000500C7, 0x00000011, + 0x0000475F, 0x0000305F, 0x00000916, 0x000500C4, 0x00000011, 0x000024D1, 0x0000475F, 0x000007B7, + 0x000500C7, 0x00000011, 0x000050AC, 0x0000305F, 0x00000B48, 0x000500C2, 0x00000011, 0x0000448D, + 0x000050AC, 0x000007B7, 0x000500C5, 0x00000011, 0x00003FF9, 0x000024D1, 0x0000448D, 0x000200F9, + 0x00002C98, 0x000200F8, 0x00002C98, 0x000700F5, 0x00000011, 0x00004D37, 0x0000305F, 0x000052F5, + 0x00003FF9, 0x00002957, 0x00060041, 0x0000028E, 0x00001F76, 0x00001592, 0x00000A0B, 0x00004EAA, + 0x0003003E, 0x00001F76, 0x00004D37, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, + 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_full_16bpp_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_full_16bpp_scaled_cs.h new file mode 100644 index 0000000..586ab0d --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_full_16bpp_scaled_cs.h @@ -0,0 +1,4526 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25245 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_runtimearr_uint ArrayStride 4 + OpDecorate %_struct_1948 BufferBlock + OpMemberDecorate %_struct_1948 0 NonWritable + OpMemberDecorate %_struct_1948 0 Offset 0 + OpDecorate %3271 NonWritable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %_struct_1017 Block + OpMemberDecorate %_struct_1017 0 Offset 0 + OpMemberDecorate %_struct_1017 1 Offset 4 + OpMemberDecorate %_struct_1017 2 Offset 8 + OpMemberDecorate %_struct_1017 3 Offset 12 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v2uint ArrayStride 8 + OpDecorate %_struct_1960 BufferBlock + OpMemberDecorate %_struct_1960 0 NonReadable + OpMemberDecorate %_struct_1960 0 Offset 0 + OpDecorate %5522 NonReadable + OpDecorate %5522 Binding 0 + OpDecorate %5522 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %v4uint = OpTypeVector %uint 4 + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 + %v3float = OpTypeVector %float 3 + %v4float = OpTypeVector %float 4 + %bool = OpTypeBool + %v3int = OpTypeVector %int 3 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 + %uint_1 = OpConstant %uint 1 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %float_31 = OpConstant %float 31 + %2057 = OpConstantComposite %v4float %float_31 %float_31 %float_31 %float_1 + %float_0_5 = OpConstant %float 0.5 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_2 = OpConstant %uint 2 + %int_10 = OpConstant %int 10 + %uint_3 = OpConstant %uint 3 + %int_15 = OpConstant %int 15 + %float_63 = OpConstant %float 63 + %511 = OpConstantComposite %v3float %float_31 %float_63 %float_31 + %int_11 = OpConstant %int 11 + %958 = OpConstantComposite %v3float %float_31 %float_31 %float_63 + %float_255 = OpConstant %float 255 + %int_8 = OpConstant %int 8 + %int_16 = OpConstant %int 16 + %int_24 = OpConstant %int 24 + %float_15 = OpConstant %float 15 + %int_4 = OpConstant %int 4 + %int_12 = OpConstant %int 12 +%float_65535 = OpConstant %float 65535 + %uint_16 = OpConstant %uint 16 + %uint_24 = OpConstant %uint 24 + %653 = OpConstantComposite %v4uint %uint_0 %uint_8 %uint_16 %uint_24 + %uint_255 = OpConstant %uint 255 +%float_0_00392156886 = OpConstant %float 0.00392156886 + %uint_10 = OpConstant %uint 10 + %uint_20 = OpConstant %uint 20 + %uint_30 = OpConstant %uint 30 + %845 = OpConstantComposite %v4uint %uint_0 %uint_10 %uint_20 %uint_30 + %uint_1023 = OpConstant %uint 1023 + %635 = OpConstantComposite %v4uint %uint_1023 %uint_1023 %uint_1023 %uint_3 +%float_0_000977517106 = OpConstant %float 0.000977517106 +%float_0_333333343 = OpConstant %float 0.333333343 + %2798 = OpConstantComposite %v4float %float_0_000977517106 %float_0_000977517106 %float_0_000977517106 %float_0_333333343 + %2996 = OpConstantComposite %v3uint %uint_0 %uint_10 %uint_20 + %uint_127 = OpConstant %uint 127 + %uint_7 = OpConstant %uint 7 + %v3bool = OpTypeVector %bool 3 + %uint_124 = OpConstant %uint 124 + %uint_23 = OpConstant %uint 23 + %float_n1 = OpConstant %float -1 + %int_0 = OpConstant %int 0 + %1959 = OpConstantComposite %v2int %int_16 %int_0 +%float_0_000976592302 = OpConstant %float 0.000976592302 + %v4int = OpTypeVector %int 4 + %290 = OpConstantComposite %v4int %int_16 %int_0 %int_16 %int_0 + %1837 = OpConstantComposite %v2uint %uint_2 %uint_1 + %v2bool = OpTypeVector %bool 2 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %uint_80 = OpConstant %uint 80 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %uint_2048 = OpConstant %uint 2048 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_448 = OpConstant %int 448 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 + %uint_6 = OpConstant %uint 6 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_runtimearr_uint = OpTypeRuntimeArray %uint +%_struct_1948 = OpTypeStruct %_runtimearr_uint +%_ptr_Uniform__struct_1948 = OpTypePointer Uniform %_struct_1948 + %3271 = OpVariable %_ptr_Uniform__struct_1948 Uniform +%_ptr_Uniform_uint = OpTypePointer Uniform %uint +%_struct_1017 = OpTypeStruct %uint %uint %uint %uint +%_ptr_PushConstant__struct_1017 = OpTypePointer PushConstant %_struct_1017 + %3305 = OpVariable %_ptr_PushConstant__struct_1017 PushConstant +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_15 = OpConstant %uint 15 + %uint_28 = OpConstant %uint 28 + %uint_19 = OpConstant %uint 19 + %2179 = OpConstantComposite %v2uint %uint_16 %uint_19 +%uint_536870912 = OpConstant %uint 536870912 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 + %uint_63 = OpConstant %uint 63 + %int_26 = OpConstant %int 26 + %int_23 = OpConstant %int 23 +%uint_16777216 = OpConstant %uint 16777216 + %2275 = OpConstantComposite %v2uint %uint_20 %uint_24 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %1825 = OpConstantComposite %v2uint %uint_2 %uint_0 +%uint_4294901760 = OpConstant %uint 4294901760 + %uint_65535 = OpConstant %uint 65535 +%_runtimearr_v2uint = OpTypeRuntimeArray %v2uint +%_struct_1960 = OpTypeStruct %_runtimearr_v2uint +%_ptr_Uniform__struct_1960 = OpTypePointer Uniform %_struct_1960 + %5522 = OpVariable %_ptr_Uniform__struct_1960 Uniform +%_ptr_Uniform_v2uint = OpTypePointer Uniform %v2uint +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %1955 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %1284 = OpConstantComposite %v4float %float_n1 %float_n1 %float_n1 %float_n1 + %770 = OpConstantComposite %v4int %int_16 %int_16 %int_16 %int_16 + %1611 = OpConstantComposite %v4uint %uint_255 %uint_255 %uint_255 %uint_255 + %261 = OpConstantComposite %v3uint %uint_1023 %uint_1023 %uint_1023 + %1126 = OpConstantComposite %v3uint %uint_127 %uint_127 %uint_127 + %2828 = OpConstantComposite %v3uint %uint_7 %uint_7 %uint_7 + %2578 = OpConstantComposite %v3uint %uint_0 %uint_0 %uint_0 + %1018 = OpConstantComposite %v3uint %uint_124 %uint_124 %uint_124 + %393 = OpConstantComposite %v3uint %uint_23 %uint_23 %uint_23 + %141 = OpConstantComposite %v3uint %uint_16 %uint_16 %uint_16 + %73 = OpConstantComposite %v2float %float_n1 %float_n1 + %2151 = OpConstantComposite %v2int %int_16 %int_16 + %2938 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 + %1285 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 + %325 = OpConstantComposite %v4float %float_0_5 %float_0_5 %float_0_5 %float_0_5 + %2605 = OpConstantComposite %v3float %float_0 %float_0 %float_0 + %2584 = OpConstantComposite %v3float %float_1 %float_1 %float_1 + %939 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5 + %2326 = OpConstantComposite %v2uint %uint_16711935 %uint_16711935 + %1975 = OpConstantComposite %v2uint %uint_8 %uint_8 + %2888 = OpConstantComposite %v2uint %uint_4278255360 %uint_4278255360 +%int_1065353216 = OpConstant %int 1065353216 +%uint_4294967290 = OpConstant %uint 4294967290 + %2360 = OpConstantComposite %v3uint %uint_4294967290 %uint_4294967290 %uint_4294967290 + %float_0_25 = OpConstant %float 0.25 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %19978 = OpShiftRightLogical %uint %15627 %uint_10 + %8574 = OpBitwiseAnd %uint %19978 %uint_3 + %21002 = OpShiftRightLogical %uint %15627 %uint_13 + %8575 = OpBitwiseAnd %uint %21002 %uint_2047 + %21003 = OpShiftRightLogical %uint %15627 %uint_24 + %8576 = OpBitwiseAnd %uint %21003 %uint_15 + %18836 = OpShiftRightLogical %uint %15627 %uint_28 + %9130 = OpBitwiseAnd %uint %18836 %uint_1 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9633 = OpShiftRightLogical %v2uint %8871 %2179 + %23601 = OpBitwiseAnd %v2uint %9633 %1954 + %24030 = OpBitwiseAnd %uint %15627 %uint_536870912 + %12295 = OpINotEqual %bool %24030 %uint_0 + OpSelectionMerge %14676 None + OpBranchConditional %12295 %16739 %21992 + %21992 = OpLabel + OpBranch %14676 + %16739 = OpLabel + %15278 = OpShiftRightLogical %v2uint %23601 %1828 + OpBranch %14676 + %14676 = OpLabel + %19124 = OpPhi %v2uint %15278 %16739 %1807 %21992 + %7038 = OpShiftRightLogical %v2uint %8871 %1855 + %11769 = OpBitwiseAnd %v2uint %7038 %1955 + %16207 = OpShiftLeftLogical %v2uint %11769 %1870 + %23019 = OpIMul %v2uint %16207 %23601 + %13123 = OpShiftRightLogical %uint %20824 %uint_5 + %14785 = OpBitwiseAnd %uint %13123 %uint_2047 + %8858 = OpCompositeExtract %uint %23601 0 + %22993 = OpIMul %uint %14785 %8858 + %20036 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %18628 = OpLoad %uint %20036 + %22701 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %20919 = OpLoad %uint %22701 + %19164 = OpBitwiseAnd %uint %18628 %uint_7 + %21999 = OpBitwiseAnd %uint %18628 %uint_8 + %20495 = OpINotEqual %bool %21999 %uint_0 + %10307 = OpShiftRightLogical %uint %18628 %uint_4 + %24434 = OpBitwiseAnd %uint %10307 %uint_7 + %19672 = OpShiftRightLogical %uint %18628 %uint_7 + %20627 = OpBitwiseAnd %uint %19672 %uint_63 + %22920 = OpBitcast %int %18628 + %13711 = OpShiftLeftLogical %int %22920 %int_10 + %20636 = OpShiftRightArithmetic %int %13711 %int_26 + %18178 = OpShiftLeftLogical %int %20636 %int_23 + %7462 = OpIAdd %int %18178 %int_1065353216 + %11052 = OpBitcast %float %7462 + %22649 = OpBitwiseAnd %uint %18628 %uint_16777216 + %7513 = OpINotEqual %bool %22649 %uint_0 + %8003 = OpBitwiseAnd %uint %20919 %uint_1023 + %15783 = OpShiftLeftLogical %uint %8003 %uint_5 + %22591 = OpShiftRightLogical %uint %20919 %uint_10 + %19390 = OpBitwiseAnd %uint %22591 %uint_1023 + %25203 = OpShiftLeftLogical %uint %19390 %uint_5 + %10422 = OpCompositeConstruct %v2uint %20919 %20919 + %10385 = OpShiftRightLogical %v2uint %10422 %2275 + %23379 = OpBitwiseAnd %v2uint %10385 %2122 + %16208 = OpShiftLeftLogical %v2uint %23379 %1870 + %23020 = OpIMul %v2uint %16208 %23601 + %12743 = OpShiftRightLogical %uint %20919 %uint_28 + %17238 = OpBitwiseAnd %uint %12743 %uint_7 + %12737 = OpLoad %v3uint %gl_GlobalInvocationID + %14500 = OpVectorShuffle %v2uint %12737 %12737 0 1 + %12025 = OpShiftLeftLogical %v2uint %14500 %1825 + %7640 = OpCompositeExtract %uint %12025 0 + %11658 = OpShiftLeftLogical %uint %22993 %uint_3 + %15379 = OpUGreaterThanEqual %bool %7640 %11658 + OpSelectionMerge %14025 DontFlatten + OpBranchConditional %15379 %21993 %14025 + %21993 = OpLabel + OpBranch %19578 + %14025 = OpLabel + %18615 = OpCompositeExtract %uint %12025 1 + %16803 = OpCompositeExtract %uint %19124 1 + %24446 = OpExtInst %uint %1 UMax %18615 %16803 + %20975 = OpCompositeConstruct %v2uint %7640 %24446 + %21036 = OpIAdd %v2uint %20975 %23019 + %16075 = OpULessThanEqual %bool %17238 %uint_3 + OpSelectionMerge %23776 None + OpBranchConditional %16075 %10990 %15087 + %15087 = OpLabel + %13566 = OpIEqual %bool %17238 %uint_5 + %8438 = OpSelect %uint %13566 %uint_2 %uint_0 + OpBranch %23776 + %10990 = OpLabel + OpBranch %23776 + %23776 = OpLabel + %19300 = OpPhi %uint %17238 %10990 %8438 %15087 + %16830 = OpCompositeConstruct %v2uint %8574 %8574 + %11801 = OpUGreaterThanEqual %v2bool %16830 %1837 + %19381 = OpSelect %v2uint %11801 %1828 %1807 + %10986 = OpShiftLeftLogical %v2uint %21036 %19381 + %24669 = OpCompositeConstruct %v2uint %19300 %19300 + %9093 = OpShiftRightLogical %v2uint %24669 %1816 + %16072 = OpBitwiseAnd %v2uint %9093 %1828 + %18106 = OpIAdd %v2uint %10986 %16072 + %22936 = OpIMul %v2uint %2719 %23601 + %11332 = OpCompositeConstruct %v2uint %9130 %uint_0 + %6571 = OpShiftRightLogical %v2uint %22936 %11332 + %10146 = OpUDiv %v2uint %18106 %6571 + %20390 = OpCompositeExtract %uint %10146 1 + %11046 = OpIMul %uint %20390 %20561 + %24665 = OpCompositeExtract %uint %10146 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %8575 %21536 + %22376 = OpIMul %v2uint %10146 %6571 + %20715 = OpISub %v2uint %18106 %22376 + %7303 = OpCompositeExtract %uint %22936 0 + %22882 = OpCompositeExtract %uint %22936 1 + %13170 = OpIMul %uint %7303 %22882 + %14551 = OpIMul %uint %8742 %13170 + %6805 = OpCompositeExtract %uint %20715 1 + %23526 = OpCompositeExtract %uint %6571 0 + %22886 = OpIMul %uint %6805 %23526 + %6886 = OpCompositeExtract %uint %20715 0 + %9696 = OpIAdd %uint %22886 %6886 + %18021 = OpShiftLeftLogical %uint %9696 %9130 + %18363 = OpIAdd %uint %14551 %18021 + %13504 = OpIMul %uint %13170 %uint_2048 + %25231 = OpUMod %uint %18363 %13504 + %16379 = OpUGreaterThanEqual %bool %8574 %uint_2 + %24735 = OpSelect %uint %16379 %uint_1 %uint_0 + %20074 = OpIAdd %uint %9130 %24735 + %6555 = OpShiftLeftLogical %uint %uint_1 %20074 + %23279 = OpINotEqual %bool %9130 %uint_0 + OpSelectionMerge %21263 DontFlatten + OpBranchConditional %23279 %15205 %16569 + %16569 = OpLabel + %19162 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20297 DontFlatten + OpBranchConditional %19162 %9761 %12129 + %12129 = OpLabel + %19407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %25231 + %23875 = OpLoad %uint %19407 + %11687 = OpIAdd %uint %25231 %6555 + %6475 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11687 + %24155 = OpLoad %uint %6475 + %6234 = OpIMul %uint %uint_2 %6555 + %8353 = OpIAdd %uint %25231 %6234 + %15309 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8353 + %24156 = OpLoad %uint %15309 + %6235 = OpIMul %uint %uint_3 %6555 + %8354 = OpIAdd %uint %25231 %6235 + %14321 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8354 + %16380 = OpLoad %uint %14321 + %20780 = OpCompositeConstruct %v4uint %23875 %24155 %24156 %16380 + OpBranch %20297 + %9761 = OpLabel + %21829 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %25231 + %23876 = OpLoad %uint %21829 + %11688 = OpIAdd %uint %25231 %uint_1 + %6399 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11688 + %23650 = OpLoad %uint %6399 + %11689 = OpIAdd %uint %25231 %uint_2 + %6400 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11689 + %23651 = OpLoad %uint %6400 + %11690 = OpIAdd %uint %25231 %uint_3 + %24558 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11690 + %16381 = OpLoad %uint %24558 + %20781 = OpCompositeConstruct %v4uint %23876 %23650 %23651 %16381 + OpBranch %20297 + %20297 = OpLabel + %10943 = OpPhi %v4uint %20781 %9761 %20780 %12129 + OpSelectionMerge %16224 None + OpSwitch %8576 %19451 0 %14585 1 %14585 2 %7355 10 %7355 3 %7354 12 %7354 4 %8190 6 %8243 + %8243 = OpLabel + %24406 = OpCompositeExtract %uint %10943 0 + %24679 = OpExtInst %v2float %1 UnpackHalf2x16 %24406 + %10082 = OpCompositeExtract %float %24679 0 + %17478 = OpCompositeExtract %float %24679 1 + %14604 = OpCompositeConstruct %v4float %10082 %17478 %float_0 %float_0 + %17274 = OpCompositeExtract %uint %10943 1 + %18027 = OpExtInst %v2float %1 UnpackHalf2x16 %17274 + %10083 = OpCompositeExtract %float %18027 0 + %17479 = OpCompositeExtract %float %18027 1 + %14605 = OpCompositeConstruct %v4float %10083 %17479 %float_0 %float_0 + %17275 = OpCompositeExtract %uint %10943 2 + %18028 = OpExtInst %v2float %1 UnpackHalf2x16 %17275 + %10084 = OpCompositeExtract %float %18028 0 + %17480 = OpCompositeExtract %float %18028 1 + %14606 = OpCompositeConstruct %v4float %10084 %17480 %float_0 %float_0 + %17276 = OpCompositeExtract %uint %10943 3 + %18029 = OpExtInst %v2float %1 UnpackHalf2x16 %17276 + %10085 = OpCompositeExtract %float %18029 0 + %20670 = OpCompositeExtract %float %18029 1 + %9033 = OpCompositeConstruct %v4float %10085 %20670 %float_0 %float_0 + OpBranch %16224 + %8190 = OpLabel + %12427 = OpCompositeExtract %uint %10943 0 + %22685 = OpBitcast %int %12427 + %18202 = OpCompositeConstruct %v2int %22685 %22685 + %18349 = OpShiftLeftLogical %v2int %18202 %1959 + %13335 = OpShiftRightArithmetic %v2int %18349 %2151 + %10903 = OpConvertSToF %v2float %13335 + %18247 = OpVectorTimesScalar %v2float %10903 %float_0_000976592302 + %24070 = OpExtInst %v2float %1 FMax %73 %18247 + %24330 = OpCompositeExtract %float %24070 0 + %15572 = OpCompositeExtract %float %24070 1 + %16670 = OpCompositeConstruct %v4float %24330 %15572 %float_0 %float_0 + %19522 = OpCompositeExtract %uint %10943 1 + %16033 = OpBitcast %int %19522 + %18203 = OpCompositeConstruct %v2int %16033 %16033 + %18350 = OpShiftLeftLogical %v2int %18203 %1959 + %13336 = OpShiftRightArithmetic %v2int %18350 %2151 + %10904 = OpConvertSToF %v2float %13336 + %18248 = OpVectorTimesScalar %v2float %10904 %float_0_000976592302 + %24071 = OpExtInst %v2float %1 FMax %73 %18248 + %24331 = OpCompositeExtract %float %24071 0 + %15573 = OpCompositeExtract %float %24071 1 + %16671 = OpCompositeConstruct %v4float %24331 %15573 %float_0 %float_0 + %19523 = OpCompositeExtract %uint %10943 2 + %16034 = OpBitcast %int %19523 + %18204 = OpCompositeConstruct %v2int %16034 %16034 + %18351 = OpShiftLeftLogical %v2int %18204 %1959 + %13337 = OpShiftRightArithmetic %v2int %18351 %2151 + %10905 = OpConvertSToF %v2float %13337 + %18249 = OpVectorTimesScalar %v2float %10905 %float_0_000976592302 + %24072 = OpExtInst %v2float %1 FMax %73 %18249 + %24332 = OpCompositeExtract %float %24072 0 + %15574 = OpCompositeExtract %float %24072 1 + %16672 = OpCompositeConstruct %v4float %24332 %15574 %float_0 %float_0 + %19524 = OpCompositeExtract %uint %10943 3 + %16035 = OpBitcast %int %19524 + %18205 = OpCompositeConstruct %v2int %16035 %16035 + %18352 = OpShiftLeftLogical %v2int %18205 %1959 + %13338 = OpShiftRightArithmetic %v2int %18352 %2151 + %10906 = OpConvertSToF %v2float %13338 + %18250 = OpVectorTimesScalar %v2float %10906 %float_0_000976592302 + %24073 = OpExtInst %v2float %1 FMax %73 %18250 + %24333 = OpCompositeExtract %float %24073 0 + %18764 = OpCompositeExtract %float %24073 1 + %9034 = OpCompositeConstruct %v4float %24333 %18764 %float_0 %float_0 + OpBranch %16224 + %7354 = OpLabel + %22205 = OpCompositeExtract %uint %10943 0 + %20234 = OpCompositeConstruct %v3uint %22205 %22205 %22205 + %11021 = OpShiftRightLogical %v3uint %20234 %2996 + %24038 = OpBitwiseAnd %v3uint %11021 %261 + %18588 = OpBitwiseAnd %v3uint %24038 %1126 + %23440 = OpShiftRightLogical %v3uint %24038 %2828 + %16585 = OpIEqual %v3bool %23440 %2578 + %11339 = OpExtInst %v3int %1 FindUMsb %18588 + %10773 = OpBitcast %v3uint %11339 + %6266 = OpISub %v3uint %2828 %10773 + %8720 = OpIAdd %v3uint %10773 %2360 + %10351 = OpSelect %v3uint %16585 %8720 %23440 + %23252 = OpShiftLeftLogical %v3uint %18588 %6266 + %18842 = OpBitwiseAnd %v3uint %23252 %1126 + %10909 = OpSelect %v3uint %16585 %18842 %18588 + %24569 = OpIAdd %v3uint %10351 %1018 + %20351 = OpShiftLeftLogical %v3uint %24569 %393 + %16294 = OpShiftLeftLogical %v3uint %10909 %141 + %22396 = OpBitwiseOr %v3uint %20351 %16294 + %13824 = OpIEqual %v3bool %24038 %2578 + %16962 = OpSelect %v3uint %13824 %2578 %22396 + %10703 = OpBitcast %v3float %16962 + %19364 = OpShiftRightLogical %uint %22205 %uint_30 + %18446 = OpConvertUToF %float %19364 + %15903 = OpFMul %float %18446 %float_0_333333343 + %21442 = OpCompositeExtract %float %10703 0 + %10837 = OpCompositeExtract %float %10703 1 + %7833 = OpCompositeExtract %float %10703 2 + %15834 = OpCompositeConstruct %v4float %21442 %10837 %7833 %15903 + %10229 = OpCompositeExtract %uint %10943 1 + %13582 = OpCompositeConstruct %v3uint %10229 %10229 %10229 + %11022 = OpShiftRightLogical %v3uint %13582 %2996 + %24039 = OpBitwiseAnd %v3uint %11022 %261 + %18589 = OpBitwiseAnd %v3uint %24039 %1126 + %23441 = OpShiftRightLogical %v3uint %24039 %2828 + %16586 = OpIEqual %v3bool %23441 %2578 + %11340 = OpExtInst %v3int %1 FindUMsb %18589 + %10774 = OpBitcast %v3uint %11340 + %6267 = OpISub %v3uint %2828 %10774 + %8721 = OpIAdd %v3uint %10774 %2360 + %10352 = OpSelect %v3uint %16586 %8721 %23441 + %23253 = OpShiftLeftLogical %v3uint %18589 %6267 + %18843 = OpBitwiseAnd %v3uint %23253 %1126 + %10910 = OpSelect %v3uint %16586 %18843 %18589 + %24570 = OpIAdd %v3uint %10352 %1018 + %20352 = OpShiftLeftLogical %v3uint %24570 %393 + %16295 = OpShiftLeftLogical %v3uint %10910 %141 + %22397 = OpBitwiseOr %v3uint %20352 %16295 + %13825 = OpIEqual %v3bool %24039 %2578 + %16963 = OpSelect %v3uint %13825 %2578 %22397 + %10704 = OpBitcast %v3float %16963 + %19365 = OpShiftRightLogical %uint %10229 %uint_30 + %18447 = OpConvertUToF %float %19365 + %15904 = OpFMul %float %18447 %float_0_333333343 + %21443 = OpCompositeExtract %float %10704 0 + %10838 = OpCompositeExtract %float %10704 1 + %7834 = OpCompositeExtract %float %10704 2 + %15835 = OpCompositeConstruct %v4float %21443 %10838 %7834 %15904 + %10230 = OpCompositeExtract %uint %10943 2 + %13583 = OpCompositeConstruct %v3uint %10230 %10230 %10230 + %11023 = OpShiftRightLogical %v3uint %13583 %2996 + %24040 = OpBitwiseAnd %v3uint %11023 %261 + %18590 = OpBitwiseAnd %v3uint %24040 %1126 + %23442 = OpShiftRightLogical %v3uint %24040 %2828 + %16587 = OpIEqual %v3bool %23442 %2578 + %11341 = OpExtInst %v3int %1 FindUMsb %18590 + %10775 = OpBitcast %v3uint %11341 + %6268 = OpISub %v3uint %2828 %10775 + %8722 = OpIAdd %v3uint %10775 %2360 + %10353 = OpSelect %v3uint %16587 %8722 %23442 + %23254 = OpShiftLeftLogical %v3uint %18590 %6268 + %18844 = OpBitwiseAnd %v3uint %23254 %1126 + %10911 = OpSelect %v3uint %16587 %18844 %18590 + %24571 = OpIAdd %v3uint %10353 %1018 + %20353 = OpShiftLeftLogical %v3uint %24571 %393 + %16296 = OpShiftLeftLogical %v3uint %10911 %141 + %22398 = OpBitwiseOr %v3uint %20353 %16296 + %13826 = OpIEqual %v3bool %24040 %2578 + %16964 = OpSelect %v3uint %13826 %2578 %22398 + %10705 = OpBitcast %v3float %16964 + %19366 = OpShiftRightLogical %uint %10230 %uint_30 + %18448 = OpConvertUToF %float %19366 + %15905 = OpFMul %float %18448 %float_0_333333343 + %21444 = OpCompositeExtract %float %10705 0 + %10839 = OpCompositeExtract %float %10705 1 + %7835 = OpCompositeExtract %float %10705 2 + %15836 = OpCompositeConstruct %v4float %21444 %10839 %7835 %15905 + %10231 = OpCompositeExtract %uint %10943 3 + %13584 = OpCompositeConstruct %v3uint %10231 %10231 %10231 + %11024 = OpShiftRightLogical %v3uint %13584 %2996 + %24041 = OpBitwiseAnd %v3uint %11024 %261 + %18591 = OpBitwiseAnd %v3uint %24041 %1126 + %23443 = OpShiftRightLogical %v3uint %24041 %2828 + %16588 = OpIEqual %v3bool %23443 %2578 + %11342 = OpExtInst %v3int %1 FindUMsb %18591 + %10776 = OpBitcast %v3uint %11342 + %6269 = OpISub %v3uint %2828 %10776 + %8723 = OpIAdd %v3uint %10776 %2360 + %10354 = OpSelect %v3uint %16588 %8723 %23443 + %23255 = OpShiftLeftLogical %v3uint %18591 %6269 + %18845 = OpBitwiseAnd %v3uint %23255 %1126 + %10912 = OpSelect %v3uint %16588 %18845 %18591 + %24572 = OpIAdd %v3uint %10354 %1018 + %20354 = OpShiftLeftLogical %v3uint %24572 %393 + %16297 = OpShiftLeftLogical %v3uint %10912 %141 + %22399 = OpBitwiseOr %v3uint %20354 %16297 + %13827 = OpIEqual %v3bool %24041 %2578 + %16965 = OpSelect %v3uint %13827 %2578 %22399 + %10706 = OpBitcast %v3float %16965 + %19367 = OpShiftRightLogical %uint %10231 %uint_30 + %18449 = OpConvertUToF %float %19367 + %15906 = OpFMul %float %18449 %float_0_333333343 + %21445 = OpCompositeExtract %float %10706 0 + %10840 = OpCompositeExtract %float %10706 1 + %11025 = OpCompositeExtract %float %10706 2 + %9035 = OpCompositeConstruct %v4float %21445 %10840 %11025 %15906 + OpBranch %16224 + %7355 = OpLabel + %22206 = OpCompositeExtract %uint %10943 0 + %20235 = OpCompositeConstruct %v4uint %22206 %22206 %22206 %22206 + %9368 = OpShiftRightLogical %v4uint %20235 %845 + %18859 = OpBitwiseAnd %v4uint %9368 %635 + %15543 = OpConvertUToF %v4float %18859 + %16688 = OpFMul %v4float %15543 %2798 + %23762 = OpCompositeExtract %uint %10943 1 + %20813 = OpCompositeConstruct %v4uint %23762 %23762 %23762 %23762 + %9369 = OpShiftRightLogical %v4uint %20813 %845 + %18860 = OpBitwiseAnd %v4uint %9369 %635 + %15544 = OpConvertUToF %v4float %18860 + %16689 = OpFMul %v4float %15544 %2798 + %23763 = OpCompositeExtract %uint %10943 2 + %20814 = OpCompositeConstruct %v4uint %23763 %23763 %23763 %23763 + %9370 = OpShiftRightLogical %v4uint %20814 %845 + %18861 = OpBitwiseAnd %v4uint %9370 %635 + %15545 = OpConvertUToF %v4float %18861 + %16690 = OpFMul %v4float %15545 %2798 + %23764 = OpCompositeExtract %uint %10943 3 + %20815 = OpCompositeConstruct %v4uint %23764 %23764 %23764 %23764 + %9371 = OpShiftRightLogical %v4uint %20815 %845 + %18862 = OpBitwiseAnd %v4uint %9371 %635 + %18735 = OpConvertUToF %v4float %18862 + %9887 = OpFMul %v4float %18735 %2798 + OpBranch %16224 + %14585 = OpLabel + %22207 = OpCompositeExtract %uint %10943 0 + %20236 = OpCompositeConstruct %v4uint %22207 %22207 %22207 %22207 + %9372 = OpShiftRightLogical %v4uint %20236 %653 + %19030 = OpBitwiseAnd %v4uint %9372 %1611 + %13986 = OpConvertUToF %v4float %19030 + %19235 = OpVectorTimesScalar %v4float %13986 %float_0_00392156886 + %8607 = OpCompositeExtract %uint %10943 1 + %24843 = OpCompositeConstruct %v4uint %8607 %8607 %8607 %8607 + %9373 = OpShiftRightLogical %v4uint %24843 %653 + %19031 = OpBitwiseAnd %v4uint %9373 %1611 + %13987 = OpConvertUToF %v4float %19031 + %19236 = OpVectorTimesScalar %v4float %13987 %float_0_00392156886 + %8608 = OpCompositeExtract %uint %10943 2 + %24844 = OpCompositeConstruct %v4uint %8608 %8608 %8608 %8608 + %9374 = OpShiftRightLogical %v4uint %24844 %653 + %19032 = OpBitwiseAnd %v4uint %9374 %1611 + %13988 = OpConvertUToF %v4float %19032 + %19237 = OpVectorTimesScalar %v4float %13988 %float_0_00392156886 + %8609 = OpCompositeExtract %uint %10943 3 + %24845 = OpCompositeConstruct %v4uint %8609 %8609 %8609 %8609 + %9375 = OpShiftRightLogical %v4uint %24845 %653 + %19033 = OpBitwiseAnd %v4uint %9375 %1611 + %17178 = OpConvertUToF %v4float %19033 + %12434 = OpVectorTimesScalar %v4float %17178 %float_0_00392156886 + OpBranch %16224 + %19451 = OpLabel + %12428 = OpCompositeExtract %uint %10943 0 + %20462 = OpBitcast %float %12428 + %17206 = OpCompositeConstruct %v2float %20462 %float_0 + %11664 = OpVectorShuffle %v4float %17206 %17206 0 1 1 1 + %22193 = OpCompositeExtract %uint %10943 1 + %16232 = OpBitcast %float %22193 + %17207 = OpCompositeConstruct %v2float %16232 %float_0 + %11665 = OpVectorShuffle %v4float %17207 %17207 0 1 1 1 + %22194 = OpCompositeExtract %uint %10943 2 + %16233 = OpBitcast %float %22194 + %17208 = OpCompositeConstruct %v2float %16233 %float_0 + %11666 = OpVectorShuffle %v4float %17208 %17208 0 1 1 1 + %22195 = OpCompositeExtract %uint %10943 3 + %16234 = OpBitcast %float %22195 + %20398 = OpCompositeConstruct %v2float %16234 %float_0 + %23098 = OpVectorShuffle %v4float %20398 %20398 0 1 1 1 + OpBranch %16224 + %16224 = OpLabel + %11175 = OpPhi %v4float %23098 %19451 %12434 %14585 %9887 %7355 %9035 %7354 %9034 %8190 %9033 %8243 + %14344 = OpPhi %v4float %11666 %19451 %19237 %14585 %16690 %7355 %15836 %7354 %16672 %8190 %14606 %8243 + %15229 = OpPhi %v4float %11665 %19451 %19236 %14585 %16689 %7355 %15835 %7354 %16671 %8190 %14605 %8243 + %14518 = OpPhi %v4float %11664 %19451 %19235 %14585 %16688 %7355 %15834 %7354 %16670 %8190 %14604 %8243 + OpBranch %21263 + %15205 = OpLabel + %21584 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20259 DontFlatten + OpBranchConditional %21584 %9762 %12130 + %12130 = OpLabel + %19408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %25231 + %23877 = OpLoad %uint %19408 + %11691 = OpIAdd %uint %25231 %uint_1 + %6401 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11691 + %23652 = OpLoad %uint %6401 + %11692 = OpIAdd %uint %25231 %6555 + %6402 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11692 + %23653 = OpLoad %uint %6402 + %11693 = OpIAdd %uint %11692 %uint_1 + %24559 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11693 + %14156 = OpLoad %uint %24559 + %19670 = OpCompositeConstruct %v4uint %23877 %23652 %23653 %14156 + %17048 = OpIMul %uint %uint_2 %6555 + %13991 = OpIAdd %uint %25231 %17048 + %15233 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13991 + %23654 = OpLoad %uint %15233 + %11694 = OpIAdd %uint %13991 %uint_1 + %6476 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11694 + %24157 = OpLoad %uint %6476 + %6236 = OpIMul %uint %uint_3 %6555 + %8355 = OpIAdd %uint %25231 %6236 + %15234 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8355 + %23655 = OpLoad %uint %15234 + %11695 = OpIAdd %uint %8355 %uint_1 + %24560 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11695 + %16382 = OpLoad %uint %24560 + %20782 = OpCompositeConstruct %v4uint %23654 %24157 %23655 %16382 + OpBranch %20259 + %9762 = OpLabel + %21830 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %25231 + %23878 = OpLoad %uint %21830 + %11696 = OpIAdd %uint %25231 %uint_1 + %6403 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11696 + %23656 = OpLoad %uint %6403 + %11697 = OpIAdd %uint %25231 %uint_2 + %6404 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11697 + %23657 = OpLoad %uint %6404 + %11698 = OpIAdd %uint %25231 %uint_3 + %24561 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11698 + %14080 = OpLoad %uint %24561 + %19165 = OpCompositeConstruct %v4uint %23878 %23656 %23657 %14080 + %22501 = OpIAdd %uint %25231 %uint_4 + %24651 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22501 + %23658 = OpLoad %uint %24651 + %11699 = OpIAdd %uint %25231 %uint_5 + %6405 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11699 + %23659 = OpLoad %uint %6405 + %11700 = OpIAdd %uint %25231 %uint_6 + %6406 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11700 + %23660 = OpLoad %uint %6406 + %11701 = OpIAdd %uint %25231 %uint_7 + %24562 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11701 + %16383 = OpLoad %uint %24562 + %20783 = OpCompositeConstruct %v4uint %23658 %23659 %23660 %16383 + OpBranch %20259 + %20259 = OpLabel + %11213 = OpPhi %v4uint %20783 %9762 %20782 %12130 + %14112 = OpPhi %v4uint %19165 %9762 %19670 %12130 + OpSelectionMerge %20260 None + OpSwitch %8576 %20310 5 %8536 7 %8244 + %8244 = OpLabel + %24407 = OpCompositeExtract %uint %14112 0 + %24680 = OpExtInst %v2float %1 UnpackHalf2x16 %24407 + %10101 = OpCompositeExtract %float %24680 0 + %16056 = OpCompositeExtract %float %24680 1 + %17025 = OpCompositeExtract %uint %14112 1 + %15605 = OpExtInst %v2float %1 UnpackHalf2x16 %17025 + %10086 = OpCompositeExtract %float %15605 0 + %17481 = OpCompositeExtract %float %15605 1 + %14607 = OpCompositeConstruct %v4float %10101 %16056 %10086 %17481 + %17277 = OpCompositeExtract %uint %14112 2 + %18030 = OpExtInst %v2float %1 UnpackHalf2x16 %17277 + %10102 = OpCompositeExtract %float %18030 0 + %16057 = OpCompositeExtract %float %18030 1 + %17026 = OpCompositeExtract %uint %14112 3 + %15606 = OpExtInst %v2float %1 UnpackHalf2x16 %17026 + %10087 = OpCompositeExtract %float %15606 0 + %17482 = OpCompositeExtract %float %15606 1 + %14608 = OpCompositeConstruct %v4float %10102 %16057 %10087 %17482 + %17278 = OpCompositeExtract %uint %11213 0 + %18031 = OpExtInst %v2float %1 UnpackHalf2x16 %17278 + %10103 = OpCompositeExtract %float %18031 0 + %16058 = OpCompositeExtract %float %18031 1 + %17027 = OpCompositeExtract %uint %11213 1 + %15607 = OpExtInst %v2float %1 UnpackHalf2x16 %17027 + %10088 = OpCompositeExtract %float %15607 0 + %17483 = OpCompositeExtract %float %15607 1 + %14609 = OpCompositeConstruct %v4float %10103 %16058 %10088 %17483 + %17279 = OpCompositeExtract %uint %11213 2 + %18032 = OpExtInst %v2float %1 UnpackHalf2x16 %17279 + %10104 = OpCompositeExtract %float %18032 0 + %16059 = OpCompositeExtract %float %18032 1 + %17028 = OpCompositeExtract %uint %11213 3 + %15608 = OpExtInst %v2float %1 UnpackHalf2x16 %17028 + %10089 = OpCompositeExtract %float %15608 0 + %20671 = OpCompositeExtract %float %15608 1 + %9036 = OpCompositeConstruct %v4float %10104 %16059 %10089 %20671 + OpBranch %20260 + %8536 = OpLabel + %9723 = OpVectorShuffle %v2uint %14112 %14112 0 1 + %23356 = OpBitcast %v2int %9723 + %24782 = OpVectorShuffle %v4int %23356 %23356 0 0 1 1 + %18598 = OpShiftLeftLogical %v4int %24782 %290 + %15757 = OpShiftRightArithmetic %v4int %18598 %770 + %10907 = OpConvertSToF %v4float %15757 + %18209 = OpVectorTimesScalar %v4float %10907 %float_0_000976592302 + %25233 = OpExtInst %v4float %1 FMax %1284 %18209 + %14187 = OpVectorShuffle %v2uint %14112 %14112 2 3 + %9407 = OpBitcast %v2int %14187 + %24783 = OpVectorShuffle %v4int %9407 %9407 0 0 1 1 + %18599 = OpShiftLeftLogical %v4int %24783 %290 + %15758 = OpShiftRightArithmetic %v4int %18599 %770 + %10908 = OpConvertSToF %v4float %15758 + %18210 = OpVectorTimesScalar %v4float %10908 %float_0_000976592302 + %25234 = OpExtInst %v4float %1 FMax %1284 %18210 + %14188 = OpVectorShuffle %v2uint %11213 %11213 0 1 + %9408 = OpBitcast %v2int %14188 + %24784 = OpVectorShuffle %v4int %9408 %9408 0 0 1 1 + %18600 = OpShiftLeftLogical %v4int %24784 %290 + %15759 = OpShiftRightArithmetic %v4int %18600 %770 + %10913 = OpConvertSToF %v4float %15759 + %18211 = OpVectorTimesScalar %v4float %10913 %float_0_000976592302 + %25235 = OpExtInst %v4float %1 FMax %1284 %18211 + %14189 = OpVectorShuffle %v2uint %11213 %11213 2 3 + %9409 = OpBitcast %v2int %14189 + %24785 = OpVectorShuffle %v4int %9409 %9409 0 0 1 1 + %18601 = OpShiftLeftLogical %v4int %24785 %290 + %15760 = OpShiftRightArithmetic %v4int %18601 %770 + %10914 = OpConvertSToF %v4float %15760 + %21439 = OpVectorTimesScalar %v4float %10914 %float_0_000976592302 + %17250 = OpExtInst %v4float %1 FMax %1284 %21439 + OpBranch %20260 + %20310 = OpLabel + %9763 = OpVectorShuffle %v2uint %14112 %14112 0 1 + %20825 = OpBitcast %v2float %9763 + %7035 = OpCompositeExtract %float %20825 0 + %13418 = OpCompositeExtract %float %20825 1 + %17016 = OpCompositeConstruct %v4float %7035 %13418 %float_0 %float_0 + %16856 = OpVectorShuffle %v2uint %14112 %14112 2 3 + %14173 = OpBitcast %v2float %16856 + %7036 = OpCompositeExtract %float %14173 0 + %13419 = OpCompositeExtract %float %14173 1 + %17017 = OpCompositeConstruct %v4float %7036 %13419 %float_0 %float_0 + %16857 = OpVectorShuffle %v2uint %11213 %11213 0 1 + %14174 = OpBitcast %v2float %16857 + %7037 = OpCompositeExtract %float %14174 0 + %13420 = OpCompositeExtract %float %14174 1 + %17018 = OpCompositeConstruct %v4float %7037 %13420 %float_0 %float_0 + %16858 = OpVectorShuffle %v2uint %11213 %11213 2 3 + %14175 = OpBitcast %v2float %16858 + %7039 = OpCompositeExtract %float %14175 0 + %16648 = OpCompositeExtract %float %14175 1 + %9037 = OpCompositeConstruct %v4float %7039 %16648 %float_0 %float_0 + OpBranch %20260 + %20260 = OpLabel + %11176 = OpPhi %v4float %9037 %20310 %17250 %8536 %9036 %8244 + %14345 = OpPhi %v4float %17018 %20310 %25235 %8536 %14609 %8244 + %15230 = OpPhi %v4float %17017 %20310 %25234 %8536 %14608 %8244 + %14519 = OpPhi %v4float %17016 %20310 %25233 %8536 %14607 %8244 + OpBranch %21263 + %21263 = OpLabel + %11177 = OpPhi %v4float %11176 %20260 %11175 %16224 + %14346 = OpPhi %v4float %14345 %20260 %14344 %16224 + %13804 = OpPhi %v4float %15230 %20260 %15229 %16224 + %8403 = OpPhi %v4float %14519 %20260 %14518 %16224 + %11861 = OpUGreaterThanEqual %bool %17238 %uint_4 + OpSelectionMerge %21267 DontFlatten + OpBranchConditional %11861 %20977 %21267 + %20977 = OpLabel + %11079 = OpIMul %uint %uint_80 %8858 + %23069 = OpFMul %float %11052 %float_0_5 + %8114 = OpIAdd %uint %25231 %11079 + OpSelectionMerge %21264 DontFlatten + OpBranchConditional %23279 %15206 %16570 + %16570 = OpLabel + %19163 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20298 DontFlatten + OpBranchConditional %19163 %9764 %12131 + %12131 = OpLabel + %19409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8114 + %23879 = OpLoad %uint %19409 + %11702 = OpIAdd %uint %8114 %6555 + %6477 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11702 + %24158 = OpLoad %uint %6477 + %6237 = OpIMul %uint %uint_2 %6555 + %8356 = OpIAdd %uint %8114 %6237 + %15310 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8356 + %24159 = OpLoad %uint %15310 + %6238 = OpIMul %uint %uint_3 %6555 + %8357 = OpIAdd %uint %8114 %6238 + %14322 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8357 + %16384 = OpLoad %uint %14322 + %20784 = OpCompositeConstruct %v4uint %23879 %24158 %24159 %16384 + OpBranch %20298 + %9764 = OpLabel + %21831 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8114 + %23880 = OpLoad %uint %21831 + %11703 = OpIAdd %uint %8114 %uint_1 + %6407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11703 + %23661 = OpLoad %uint %6407 + %11704 = OpIAdd %uint %8114 %uint_2 + %6408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11704 + %23662 = OpLoad %uint %6408 + %11705 = OpIAdd %uint %8114 %uint_3 + %24563 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11705 + %16385 = OpLoad %uint %24563 + %20785 = OpCompositeConstruct %v4uint %23880 %23661 %23662 %16385 + OpBranch %20298 + %20298 = OpLabel + %10944 = OpPhi %v4uint %20785 %9764 %20784 %12131 + OpSelectionMerge %16225 None + OpSwitch %8576 %19452 0 %14586 1 %14586 2 %7357 10 %7357 3 %7356 12 %7356 4 %8191 6 %8245 + %8245 = OpLabel + %24408 = OpCompositeExtract %uint %10944 0 + %24681 = OpExtInst %v2float %1 UnpackHalf2x16 %24408 + %10090 = OpCompositeExtract %float %24681 0 + %17484 = OpCompositeExtract %float %24681 1 + %14610 = OpCompositeConstruct %v4float %10090 %17484 %float_0 %float_0 + %17280 = OpCompositeExtract %uint %10944 1 + %18033 = OpExtInst %v2float %1 UnpackHalf2x16 %17280 + %10091 = OpCompositeExtract %float %18033 0 + %17485 = OpCompositeExtract %float %18033 1 + %14611 = OpCompositeConstruct %v4float %10091 %17485 %float_0 %float_0 + %17281 = OpCompositeExtract %uint %10944 2 + %18034 = OpExtInst %v2float %1 UnpackHalf2x16 %17281 + %10092 = OpCompositeExtract %float %18034 0 + %17486 = OpCompositeExtract %float %18034 1 + %14612 = OpCompositeConstruct %v4float %10092 %17486 %float_0 %float_0 + %17282 = OpCompositeExtract %uint %10944 3 + %18035 = OpExtInst %v2float %1 UnpackHalf2x16 %17282 + %10093 = OpCompositeExtract %float %18035 0 + %20672 = OpCompositeExtract %float %18035 1 + %9038 = OpCompositeConstruct %v4float %10093 %20672 %float_0 %float_0 + OpBranch %16225 + %8191 = OpLabel + %12429 = OpCompositeExtract %uint %10944 0 + %22686 = OpBitcast %int %12429 + %18206 = OpCompositeConstruct %v2int %22686 %22686 + %18353 = OpShiftLeftLogical %v2int %18206 %1959 + %13339 = OpShiftRightArithmetic %v2int %18353 %2151 + %10915 = OpConvertSToF %v2float %13339 + %18251 = OpVectorTimesScalar %v2float %10915 %float_0_000976592302 + %24074 = OpExtInst %v2float %1 FMax %73 %18251 + %24334 = OpCompositeExtract %float %24074 0 + %15575 = OpCompositeExtract %float %24074 1 + %16673 = OpCompositeConstruct %v4float %24334 %15575 %float_0 %float_0 + %19525 = OpCompositeExtract %uint %10944 1 + %16036 = OpBitcast %int %19525 + %18207 = OpCompositeConstruct %v2int %16036 %16036 + %18354 = OpShiftLeftLogical %v2int %18207 %1959 + %13340 = OpShiftRightArithmetic %v2int %18354 %2151 + %10916 = OpConvertSToF %v2float %13340 + %18252 = OpVectorTimesScalar %v2float %10916 %float_0_000976592302 + %24075 = OpExtInst %v2float %1 FMax %73 %18252 + %24335 = OpCompositeExtract %float %24075 0 + %15576 = OpCompositeExtract %float %24075 1 + %16674 = OpCompositeConstruct %v4float %24335 %15576 %float_0 %float_0 + %19526 = OpCompositeExtract %uint %10944 2 + %16037 = OpBitcast %int %19526 + %18208 = OpCompositeConstruct %v2int %16037 %16037 + %18355 = OpShiftLeftLogical %v2int %18208 %1959 + %13341 = OpShiftRightArithmetic %v2int %18355 %2151 + %10917 = OpConvertSToF %v2float %13341 + %18253 = OpVectorTimesScalar %v2float %10917 %float_0_000976592302 + %24076 = OpExtInst %v2float %1 FMax %73 %18253 + %24336 = OpCompositeExtract %float %24076 0 + %15577 = OpCompositeExtract %float %24076 1 + %16675 = OpCompositeConstruct %v4float %24336 %15577 %float_0 %float_0 + %19527 = OpCompositeExtract %uint %10944 3 + %16038 = OpBitcast %int %19527 + %18212 = OpCompositeConstruct %v2int %16038 %16038 + %18356 = OpShiftLeftLogical %v2int %18212 %1959 + %13342 = OpShiftRightArithmetic %v2int %18356 %2151 + %10918 = OpConvertSToF %v2float %13342 + %18254 = OpVectorTimesScalar %v2float %10918 %float_0_000976592302 + %24077 = OpExtInst %v2float %1 FMax %73 %18254 + %24337 = OpCompositeExtract %float %24077 0 + %18765 = OpCompositeExtract %float %24077 1 + %9039 = OpCompositeConstruct %v4float %24337 %18765 %float_0 %float_0 + OpBranch %16225 + %7356 = OpLabel + %22208 = OpCompositeExtract %uint %10944 0 + %20237 = OpCompositeConstruct %v3uint %22208 %22208 %22208 + %11026 = OpShiftRightLogical %v3uint %20237 %2996 + %24042 = OpBitwiseAnd %v3uint %11026 %261 + %18592 = OpBitwiseAnd %v3uint %24042 %1126 + %23444 = OpShiftRightLogical %v3uint %24042 %2828 + %16589 = OpIEqual %v3bool %23444 %2578 + %11343 = OpExtInst %v3int %1 FindUMsb %18592 + %10777 = OpBitcast %v3uint %11343 + %6270 = OpISub %v3uint %2828 %10777 + %8724 = OpIAdd %v3uint %10777 %2360 + %10355 = OpSelect %v3uint %16589 %8724 %23444 + %23256 = OpShiftLeftLogical %v3uint %18592 %6270 + %18846 = OpBitwiseAnd %v3uint %23256 %1126 + %10919 = OpSelect %v3uint %16589 %18846 %18592 + %24573 = OpIAdd %v3uint %10355 %1018 + %20355 = OpShiftLeftLogical %v3uint %24573 %393 + %16298 = OpShiftLeftLogical %v3uint %10919 %141 + %22400 = OpBitwiseOr %v3uint %20355 %16298 + %13828 = OpIEqual %v3bool %24042 %2578 + %16966 = OpSelect %v3uint %13828 %2578 %22400 + %10707 = OpBitcast %v3float %16966 + %19368 = OpShiftRightLogical %uint %22208 %uint_30 + %18450 = OpConvertUToF %float %19368 + %15907 = OpFMul %float %18450 %float_0_333333343 + %21446 = OpCompositeExtract %float %10707 0 + %10841 = OpCompositeExtract %float %10707 1 + %7836 = OpCompositeExtract %float %10707 2 + %15837 = OpCompositeConstruct %v4float %21446 %10841 %7836 %15907 + %10232 = OpCompositeExtract %uint %10944 1 + %13585 = OpCompositeConstruct %v3uint %10232 %10232 %10232 + %11027 = OpShiftRightLogical %v3uint %13585 %2996 + %24043 = OpBitwiseAnd %v3uint %11027 %261 + %18593 = OpBitwiseAnd %v3uint %24043 %1126 + %23445 = OpShiftRightLogical %v3uint %24043 %2828 + %16590 = OpIEqual %v3bool %23445 %2578 + %11344 = OpExtInst %v3int %1 FindUMsb %18593 + %10778 = OpBitcast %v3uint %11344 + %6271 = OpISub %v3uint %2828 %10778 + %8725 = OpIAdd %v3uint %10778 %2360 + %10356 = OpSelect %v3uint %16590 %8725 %23445 + %23257 = OpShiftLeftLogical %v3uint %18593 %6271 + %18847 = OpBitwiseAnd %v3uint %23257 %1126 + %10920 = OpSelect %v3uint %16590 %18847 %18593 + %24574 = OpIAdd %v3uint %10356 %1018 + %20356 = OpShiftLeftLogical %v3uint %24574 %393 + %16299 = OpShiftLeftLogical %v3uint %10920 %141 + %22401 = OpBitwiseOr %v3uint %20356 %16299 + %13829 = OpIEqual %v3bool %24043 %2578 + %16967 = OpSelect %v3uint %13829 %2578 %22401 + %10708 = OpBitcast %v3float %16967 + %19369 = OpShiftRightLogical %uint %10232 %uint_30 + %18451 = OpConvertUToF %float %19369 + %15908 = OpFMul %float %18451 %float_0_333333343 + %21447 = OpCompositeExtract %float %10708 0 + %10842 = OpCompositeExtract %float %10708 1 + %7837 = OpCompositeExtract %float %10708 2 + %15838 = OpCompositeConstruct %v4float %21447 %10842 %7837 %15908 + %10233 = OpCompositeExtract %uint %10944 2 + %13586 = OpCompositeConstruct %v3uint %10233 %10233 %10233 + %11028 = OpShiftRightLogical %v3uint %13586 %2996 + %24044 = OpBitwiseAnd %v3uint %11028 %261 + %18594 = OpBitwiseAnd %v3uint %24044 %1126 + %23446 = OpShiftRightLogical %v3uint %24044 %2828 + %16591 = OpIEqual %v3bool %23446 %2578 + %11345 = OpExtInst %v3int %1 FindUMsb %18594 + %10779 = OpBitcast %v3uint %11345 + %6272 = OpISub %v3uint %2828 %10779 + %8726 = OpIAdd %v3uint %10779 %2360 + %10357 = OpSelect %v3uint %16591 %8726 %23446 + %23258 = OpShiftLeftLogical %v3uint %18594 %6272 + %18848 = OpBitwiseAnd %v3uint %23258 %1126 + %10921 = OpSelect %v3uint %16591 %18848 %18594 + %24575 = OpIAdd %v3uint %10357 %1018 + %20357 = OpShiftLeftLogical %v3uint %24575 %393 + %16300 = OpShiftLeftLogical %v3uint %10921 %141 + %22402 = OpBitwiseOr %v3uint %20357 %16300 + %13830 = OpIEqual %v3bool %24044 %2578 + %16968 = OpSelect %v3uint %13830 %2578 %22402 + %10709 = OpBitcast %v3float %16968 + %19370 = OpShiftRightLogical %uint %10233 %uint_30 + %18452 = OpConvertUToF %float %19370 + %15909 = OpFMul %float %18452 %float_0_333333343 + %21448 = OpCompositeExtract %float %10709 0 + %10843 = OpCompositeExtract %float %10709 1 + %7838 = OpCompositeExtract %float %10709 2 + %15839 = OpCompositeConstruct %v4float %21448 %10843 %7838 %15909 + %10234 = OpCompositeExtract %uint %10944 3 + %13587 = OpCompositeConstruct %v3uint %10234 %10234 %10234 + %11029 = OpShiftRightLogical %v3uint %13587 %2996 + %24045 = OpBitwiseAnd %v3uint %11029 %261 + %18595 = OpBitwiseAnd %v3uint %24045 %1126 + %23447 = OpShiftRightLogical %v3uint %24045 %2828 + %16592 = OpIEqual %v3bool %23447 %2578 + %11346 = OpExtInst %v3int %1 FindUMsb %18595 + %10780 = OpBitcast %v3uint %11346 + %6273 = OpISub %v3uint %2828 %10780 + %8727 = OpIAdd %v3uint %10780 %2360 + %10358 = OpSelect %v3uint %16592 %8727 %23447 + %23259 = OpShiftLeftLogical %v3uint %18595 %6273 + %18849 = OpBitwiseAnd %v3uint %23259 %1126 + %10922 = OpSelect %v3uint %16592 %18849 %18595 + %24576 = OpIAdd %v3uint %10358 %1018 + %20358 = OpShiftLeftLogical %v3uint %24576 %393 + %16301 = OpShiftLeftLogical %v3uint %10922 %141 + %22403 = OpBitwiseOr %v3uint %20358 %16301 + %13831 = OpIEqual %v3bool %24045 %2578 + %16969 = OpSelect %v3uint %13831 %2578 %22403 + %10710 = OpBitcast %v3float %16969 + %19371 = OpShiftRightLogical %uint %10234 %uint_30 + %18453 = OpConvertUToF %float %19371 + %15910 = OpFMul %float %18453 %float_0_333333343 + %21449 = OpCompositeExtract %float %10710 0 + %10844 = OpCompositeExtract %float %10710 1 + %11030 = OpCompositeExtract %float %10710 2 + %9040 = OpCompositeConstruct %v4float %21449 %10844 %11030 %15910 + OpBranch %16225 + %7357 = OpLabel + %22209 = OpCompositeExtract %uint %10944 0 + %20238 = OpCompositeConstruct %v4uint %22209 %22209 %22209 %22209 + %9376 = OpShiftRightLogical %v4uint %20238 %845 + %18863 = OpBitwiseAnd %v4uint %9376 %635 + %15546 = OpConvertUToF %v4float %18863 + %16691 = OpFMul %v4float %15546 %2798 + %23765 = OpCompositeExtract %uint %10944 1 + %20816 = OpCompositeConstruct %v4uint %23765 %23765 %23765 %23765 + %9377 = OpShiftRightLogical %v4uint %20816 %845 + %18864 = OpBitwiseAnd %v4uint %9377 %635 + %15547 = OpConvertUToF %v4float %18864 + %16692 = OpFMul %v4float %15547 %2798 + %23766 = OpCompositeExtract %uint %10944 2 + %20817 = OpCompositeConstruct %v4uint %23766 %23766 %23766 %23766 + %9378 = OpShiftRightLogical %v4uint %20817 %845 + %18865 = OpBitwiseAnd %v4uint %9378 %635 + %15548 = OpConvertUToF %v4float %18865 + %16693 = OpFMul %v4float %15548 %2798 + %23767 = OpCompositeExtract %uint %10944 3 + %20818 = OpCompositeConstruct %v4uint %23767 %23767 %23767 %23767 + %9379 = OpShiftRightLogical %v4uint %20818 %845 + %18866 = OpBitwiseAnd %v4uint %9379 %635 + %18736 = OpConvertUToF %v4float %18866 + %9888 = OpFMul %v4float %18736 %2798 + OpBranch %16225 + %14586 = OpLabel + %22210 = OpCompositeExtract %uint %10944 0 + %20239 = OpCompositeConstruct %v4uint %22210 %22210 %22210 %22210 + %9380 = OpShiftRightLogical %v4uint %20239 %653 + %19034 = OpBitwiseAnd %v4uint %9380 %1611 + %13989 = OpConvertUToF %v4float %19034 + %19238 = OpVectorTimesScalar %v4float %13989 %float_0_00392156886 + %8610 = OpCompositeExtract %uint %10944 1 + %24846 = OpCompositeConstruct %v4uint %8610 %8610 %8610 %8610 + %9381 = OpShiftRightLogical %v4uint %24846 %653 + %19035 = OpBitwiseAnd %v4uint %9381 %1611 + %13990 = OpConvertUToF %v4float %19035 + %19239 = OpVectorTimesScalar %v4float %13990 %float_0_00392156886 + %8611 = OpCompositeExtract %uint %10944 2 + %24847 = OpCompositeConstruct %v4uint %8611 %8611 %8611 %8611 + %9382 = OpShiftRightLogical %v4uint %24847 %653 + %19036 = OpBitwiseAnd %v4uint %9382 %1611 + %13992 = OpConvertUToF %v4float %19036 + %19240 = OpVectorTimesScalar %v4float %13992 %float_0_00392156886 + %8612 = OpCompositeExtract %uint %10944 3 + %24848 = OpCompositeConstruct %v4uint %8612 %8612 %8612 %8612 + %9383 = OpShiftRightLogical %v4uint %24848 %653 + %19037 = OpBitwiseAnd %v4uint %9383 %1611 + %17179 = OpConvertUToF %v4float %19037 + %12435 = OpVectorTimesScalar %v4float %17179 %float_0_00392156886 + OpBranch %16225 + %19452 = OpLabel + %12430 = OpCompositeExtract %uint %10944 0 + %20463 = OpBitcast %float %12430 + %17209 = OpCompositeConstruct %v2float %20463 %float_0 + %11667 = OpVectorShuffle %v4float %17209 %17209 0 1 1 1 + %22196 = OpCompositeExtract %uint %10944 1 + %16235 = OpBitcast %float %22196 + %17210 = OpCompositeConstruct %v2float %16235 %float_0 + %11668 = OpVectorShuffle %v4float %17210 %17210 0 1 1 1 + %22197 = OpCompositeExtract %uint %10944 2 + %16236 = OpBitcast %float %22197 + %17211 = OpCompositeConstruct %v2float %16236 %float_0 + %11669 = OpVectorShuffle %v4float %17211 %17211 0 1 1 1 + %22198 = OpCompositeExtract %uint %10944 3 + %16237 = OpBitcast %float %22198 + %20399 = OpCompositeConstruct %v2float %16237 %float_0 + %23099 = OpVectorShuffle %v4float %20399 %20399 0 1 1 1 + OpBranch %16225 + %16225 = OpLabel + %11178 = OpPhi %v4float %23099 %19452 %12435 %14586 %9888 %7357 %9040 %7356 %9039 %8191 %9038 %8245 + %14347 = OpPhi %v4float %11669 %19452 %19240 %14586 %16693 %7357 %15839 %7356 %16675 %8191 %14612 %8245 + %15231 = OpPhi %v4float %11668 %19452 %19239 %14586 %16692 %7357 %15838 %7356 %16674 %8191 %14611 %8245 + %14520 = OpPhi %v4float %11667 %19452 %19238 %14586 %16691 %7357 %15837 %7356 %16673 %8191 %14610 %8245 + OpBranch %21264 + %15206 = OpLabel + %21585 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20261 DontFlatten + OpBranchConditional %21585 %9765 %12132 + %12132 = OpLabel + %19410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8114 + %23881 = OpLoad %uint %19410 + %11706 = OpIAdd %uint %8114 %uint_1 + %6409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11706 + %23663 = OpLoad %uint %6409 + %11707 = OpIAdd %uint %8114 %6555 + %6410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11707 + %23664 = OpLoad %uint %6410 + %11708 = OpIAdd %uint %11707 %uint_1 + %24564 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11708 + %14157 = OpLoad %uint %24564 + %19671 = OpCompositeConstruct %v4uint %23881 %23663 %23664 %14157 + %17049 = OpIMul %uint %uint_2 %6555 + %13993 = OpIAdd %uint %8114 %17049 + %15235 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13993 + %23665 = OpLoad %uint %15235 + %11709 = OpIAdd %uint %13993 %uint_1 + %6478 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11709 + %24160 = OpLoad %uint %6478 + %6239 = OpIMul %uint %uint_3 %6555 + %8358 = OpIAdd %uint %8114 %6239 + %15236 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8358 + %23666 = OpLoad %uint %15236 + %11710 = OpIAdd %uint %8358 %uint_1 + %24565 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11710 + %16386 = OpLoad %uint %24565 + %20786 = OpCompositeConstruct %v4uint %23665 %24160 %23666 %16386 + OpBranch %20261 + %9765 = OpLabel + %21832 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8114 + %23882 = OpLoad %uint %21832 + %11711 = OpIAdd %uint %8114 %uint_1 + %6411 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11711 + %23667 = OpLoad %uint %6411 + %11712 = OpIAdd %uint %8114 %uint_2 + %6412 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11712 + %23668 = OpLoad %uint %6412 + %11713 = OpIAdd %uint %8114 %uint_3 + %24566 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11713 + %14081 = OpLoad %uint %24566 + %19166 = OpCompositeConstruct %v4uint %23882 %23667 %23668 %14081 + %22502 = OpIAdd %uint %8114 %uint_4 + %24652 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22502 + %23669 = OpLoad %uint %24652 + %11714 = OpIAdd %uint %8114 %uint_5 + %6413 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11714 + %23670 = OpLoad %uint %6413 + %11715 = OpIAdd %uint %8114 %uint_6 + %6414 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11715 + %23671 = OpLoad %uint %6414 + %11716 = OpIAdd %uint %8114 %uint_7 + %24567 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11716 + %16387 = OpLoad %uint %24567 + %20787 = OpCompositeConstruct %v4uint %23669 %23670 %23671 %16387 + OpBranch %20261 + %20261 = OpLabel + %11214 = OpPhi %v4uint %20787 %9765 %20786 %12132 + %14113 = OpPhi %v4uint %19166 %9765 %19671 %12132 + OpSelectionMerge %20262 None + OpSwitch %8576 %20311 5 %8537 7 %8246 + %8246 = OpLabel + %24409 = OpCompositeExtract %uint %14113 0 + %24682 = OpExtInst %v2float %1 UnpackHalf2x16 %24409 + %10105 = OpCompositeExtract %float %24682 0 + %16060 = OpCompositeExtract %float %24682 1 + %17029 = OpCompositeExtract %uint %14113 1 + %15609 = OpExtInst %v2float %1 UnpackHalf2x16 %17029 + %10094 = OpCompositeExtract %float %15609 0 + %17487 = OpCompositeExtract %float %15609 1 + %14613 = OpCompositeConstruct %v4float %10105 %16060 %10094 %17487 + %17283 = OpCompositeExtract %uint %14113 2 + %18036 = OpExtInst %v2float %1 UnpackHalf2x16 %17283 + %10106 = OpCompositeExtract %float %18036 0 + %16061 = OpCompositeExtract %float %18036 1 + %17030 = OpCompositeExtract %uint %14113 3 + %15610 = OpExtInst %v2float %1 UnpackHalf2x16 %17030 + %10095 = OpCompositeExtract %float %15610 0 + %17488 = OpCompositeExtract %float %15610 1 + %14614 = OpCompositeConstruct %v4float %10106 %16061 %10095 %17488 + %17284 = OpCompositeExtract %uint %11214 0 + %18037 = OpExtInst %v2float %1 UnpackHalf2x16 %17284 + %10107 = OpCompositeExtract %float %18037 0 + %16062 = OpCompositeExtract %float %18037 1 + %17031 = OpCompositeExtract %uint %11214 1 + %15611 = OpExtInst %v2float %1 UnpackHalf2x16 %17031 + %10096 = OpCompositeExtract %float %15611 0 + %17489 = OpCompositeExtract %float %15611 1 + %14615 = OpCompositeConstruct %v4float %10107 %16062 %10096 %17489 + %17285 = OpCompositeExtract %uint %11214 2 + %18038 = OpExtInst %v2float %1 UnpackHalf2x16 %17285 + %10108 = OpCompositeExtract %float %18038 0 + %16063 = OpCompositeExtract %float %18038 1 + %17032 = OpCompositeExtract %uint %11214 3 + %15612 = OpExtInst %v2float %1 UnpackHalf2x16 %17032 + %10097 = OpCompositeExtract %float %15612 0 + %20673 = OpCompositeExtract %float %15612 1 + %9041 = OpCompositeConstruct %v4float %10108 %16063 %10097 %20673 + OpBranch %20262 + %8537 = OpLabel + %9724 = OpVectorShuffle %v2uint %14113 %14113 0 1 + %23357 = OpBitcast %v2int %9724 + %24786 = OpVectorShuffle %v4int %23357 %23357 0 0 1 1 + %18602 = OpShiftLeftLogical %v4int %24786 %290 + %15761 = OpShiftRightArithmetic %v4int %18602 %770 + %10923 = OpConvertSToF %v4float %15761 + %18213 = OpVectorTimesScalar %v4float %10923 %float_0_000976592302 + %25236 = OpExtInst %v4float %1 FMax %1284 %18213 + %14190 = OpVectorShuffle %v2uint %14113 %14113 2 3 + %9410 = OpBitcast %v2int %14190 + %24787 = OpVectorShuffle %v4int %9410 %9410 0 0 1 1 + %18603 = OpShiftLeftLogical %v4int %24787 %290 + %15762 = OpShiftRightArithmetic %v4int %18603 %770 + %10924 = OpConvertSToF %v4float %15762 + %18214 = OpVectorTimesScalar %v4float %10924 %float_0_000976592302 + %25237 = OpExtInst %v4float %1 FMax %1284 %18214 + %14191 = OpVectorShuffle %v2uint %11214 %11214 0 1 + %9411 = OpBitcast %v2int %14191 + %24788 = OpVectorShuffle %v4int %9411 %9411 0 0 1 1 + %18604 = OpShiftLeftLogical %v4int %24788 %290 + %15763 = OpShiftRightArithmetic %v4int %18604 %770 + %10925 = OpConvertSToF %v4float %15763 + %18215 = OpVectorTimesScalar %v4float %10925 %float_0_000976592302 + %25238 = OpExtInst %v4float %1 FMax %1284 %18215 + %14192 = OpVectorShuffle %v2uint %11214 %11214 2 3 + %9412 = OpBitcast %v2int %14192 + %24789 = OpVectorShuffle %v4int %9412 %9412 0 0 1 1 + %18605 = OpShiftLeftLogical %v4int %24789 %290 + %15764 = OpShiftRightArithmetic %v4int %18605 %770 + %10926 = OpConvertSToF %v4float %15764 + %21440 = OpVectorTimesScalar %v4float %10926 %float_0_000976592302 + %17251 = OpExtInst %v4float %1 FMax %1284 %21440 + OpBranch %20262 + %20311 = OpLabel + %9766 = OpVectorShuffle %v2uint %14113 %14113 0 1 + %20826 = OpBitcast %v2float %9766 + %7040 = OpCompositeExtract %float %20826 0 + %13421 = OpCompositeExtract %float %20826 1 + %17019 = OpCompositeConstruct %v4float %7040 %13421 %float_0 %float_0 + %16859 = OpVectorShuffle %v2uint %14113 %14113 2 3 + %14176 = OpBitcast %v2float %16859 + %7041 = OpCompositeExtract %float %14176 0 + %13422 = OpCompositeExtract %float %14176 1 + %17020 = OpCompositeConstruct %v4float %7041 %13422 %float_0 %float_0 + %16860 = OpVectorShuffle %v2uint %11214 %11214 0 1 + %14177 = OpBitcast %v2float %16860 + %7042 = OpCompositeExtract %float %14177 0 + %13423 = OpCompositeExtract %float %14177 1 + %17021 = OpCompositeConstruct %v4float %7042 %13423 %float_0 %float_0 + %16861 = OpVectorShuffle %v2uint %11214 %11214 2 3 + %14178 = OpBitcast %v2float %16861 + %7043 = OpCompositeExtract %float %14178 0 + %16649 = OpCompositeExtract %float %14178 1 + %9042 = OpCompositeConstruct %v4float %7043 %16649 %float_0 %float_0 + OpBranch %20262 + %20262 = OpLabel + %11179 = OpPhi %v4float %9042 %20311 %17251 %8537 %9041 %8246 + %14348 = OpPhi %v4float %17021 %20311 %25238 %8537 %14615 %8246 + %15232 = OpPhi %v4float %17020 %20311 %25237 %8537 %14614 %8246 + %14521 = OpPhi %v4float %17019 %20311 %25236 %8537 %14613 %8246 + OpBranch %21264 + %21264 = OpLabel + %11180 = OpPhi %v4float %11179 %20262 %11178 %16225 + %14349 = OpPhi %v4float %14348 %20262 %14347 %16225 + %12949 = OpPhi %v4float %15232 %20262 %15231 %16225 + %13946 = OpPhi %v4float %14521 %20262 %14520 %16225 + %17241 = OpFAdd %v4float %8403 %13946 + %23297 = OpFAdd %v4float %13804 %12949 + %8082 = OpFAdd %v4float %14346 %14349 + %20755 = OpFAdd %v4float %11177 %11180 + %14461 = OpUGreaterThanEqual %bool %17238 %uint_6 + OpSelectionMerge %24264 DontFlatten + OpBranchConditional %14461 %9905 %24264 + %9905 = OpLabel + %14258 = OpShiftLeftLogical %uint %uint_1 %9130 + %12090 = OpFMul %float %11052 %float_0_25 + %20988 = OpIAdd %uint %25231 %14258 + OpSelectionMerge %21265 DontFlatten + OpBranchConditional %23279 %15207 %16571 + %16571 = OpLabel + %19167 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20299 DontFlatten + OpBranchConditional %19167 %9767 %12133 + %12133 = OpLabel + %19411 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23883 = OpLoad %uint %19411 + %11717 = OpIAdd %uint %20988 %6555 + %6479 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11717 + %24161 = OpLoad %uint %6479 + %6240 = OpIMul %uint %uint_2 %6555 + %8359 = OpIAdd %uint %20988 %6240 + %15311 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8359 + %24162 = OpLoad %uint %15311 + %6241 = OpIMul %uint %uint_3 %6555 + %8360 = OpIAdd %uint %20988 %6241 + %14323 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8360 + %16388 = OpLoad %uint %14323 + %20788 = OpCompositeConstruct %v4uint %23883 %24161 %24162 %16388 + OpBranch %20299 + %9767 = OpLabel + %21833 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23884 = OpLoad %uint %21833 + %11718 = OpIAdd %uint %20988 %uint_1 + %6415 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11718 + %23672 = OpLoad %uint %6415 + %11719 = OpIAdd %uint %20988 %uint_2 + %6416 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11719 + %23673 = OpLoad %uint %6416 + %11720 = OpIAdd %uint %20988 %uint_3 + %24568 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11720 + %16389 = OpLoad %uint %24568 + %20789 = OpCompositeConstruct %v4uint %23884 %23672 %23673 %16389 + OpBranch %20299 + %20299 = OpLabel + %10945 = OpPhi %v4uint %20789 %9767 %20788 %12133 + OpSelectionMerge %16226 None + OpSwitch %8576 %19453 0 %14587 1 %14587 2 %7359 10 %7359 3 %7358 12 %7358 4 %8192 6 %8247 + %8247 = OpLabel + %24410 = OpCompositeExtract %uint %10945 0 + %24683 = OpExtInst %v2float %1 UnpackHalf2x16 %24410 + %10098 = OpCompositeExtract %float %24683 0 + %17490 = OpCompositeExtract %float %24683 1 + %14616 = OpCompositeConstruct %v4float %10098 %17490 %float_0 %float_0 + %17286 = OpCompositeExtract %uint %10945 1 + %18039 = OpExtInst %v2float %1 UnpackHalf2x16 %17286 + %10099 = OpCompositeExtract %float %18039 0 + %17491 = OpCompositeExtract %float %18039 1 + %14617 = OpCompositeConstruct %v4float %10099 %17491 %float_0 %float_0 + %17287 = OpCompositeExtract %uint %10945 2 + %18040 = OpExtInst %v2float %1 UnpackHalf2x16 %17287 + %10100 = OpCompositeExtract %float %18040 0 + %17492 = OpCompositeExtract %float %18040 1 + %14618 = OpCompositeConstruct %v4float %10100 %17492 %float_0 %float_0 + %17288 = OpCompositeExtract %uint %10945 3 + %18041 = OpExtInst %v2float %1 UnpackHalf2x16 %17288 + %10109 = OpCompositeExtract %float %18041 0 + %20674 = OpCompositeExtract %float %18041 1 + %9043 = OpCompositeConstruct %v4float %10109 %20674 %float_0 %float_0 + OpBranch %16226 + %8192 = OpLabel + %12431 = OpCompositeExtract %uint %10945 0 + %22687 = OpBitcast %int %12431 + %18216 = OpCompositeConstruct %v2int %22687 %22687 + %18357 = OpShiftLeftLogical %v2int %18216 %1959 + %13343 = OpShiftRightArithmetic %v2int %18357 %2151 + %10927 = OpConvertSToF %v2float %13343 + %18255 = OpVectorTimesScalar %v2float %10927 %float_0_000976592302 + %24078 = OpExtInst %v2float %1 FMax %73 %18255 + %24338 = OpCompositeExtract %float %24078 0 + %15578 = OpCompositeExtract %float %24078 1 + %16676 = OpCompositeConstruct %v4float %24338 %15578 %float_0 %float_0 + %19528 = OpCompositeExtract %uint %10945 1 + %16039 = OpBitcast %int %19528 + %18217 = OpCompositeConstruct %v2int %16039 %16039 + %18358 = OpShiftLeftLogical %v2int %18217 %1959 + %13344 = OpShiftRightArithmetic %v2int %18358 %2151 + %10928 = OpConvertSToF %v2float %13344 + %18256 = OpVectorTimesScalar %v2float %10928 %float_0_000976592302 + %24079 = OpExtInst %v2float %1 FMax %73 %18256 + %24339 = OpCompositeExtract %float %24079 0 + %15579 = OpCompositeExtract %float %24079 1 + %16677 = OpCompositeConstruct %v4float %24339 %15579 %float_0 %float_0 + %19529 = OpCompositeExtract %uint %10945 2 + %16040 = OpBitcast %int %19529 + %18218 = OpCompositeConstruct %v2int %16040 %16040 + %18359 = OpShiftLeftLogical %v2int %18218 %1959 + %13345 = OpShiftRightArithmetic %v2int %18359 %2151 + %10929 = OpConvertSToF %v2float %13345 + %18257 = OpVectorTimesScalar %v2float %10929 %float_0_000976592302 + %24080 = OpExtInst %v2float %1 FMax %73 %18257 + %24340 = OpCompositeExtract %float %24080 0 + %15580 = OpCompositeExtract %float %24080 1 + %16678 = OpCompositeConstruct %v4float %24340 %15580 %float_0 %float_0 + %19530 = OpCompositeExtract %uint %10945 3 + %16041 = OpBitcast %int %19530 + %18219 = OpCompositeConstruct %v2int %16041 %16041 + %18360 = OpShiftLeftLogical %v2int %18219 %1959 + %13346 = OpShiftRightArithmetic %v2int %18360 %2151 + %10930 = OpConvertSToF %v2float %13346 + %18258 = OpVectorTimesScalar %v2float %10930 %float_0_000976592302 + %24081 = OpExtInst %v2float %1 FMax %73 %18258 + %24341 = OpCompositeExtract %float %24081 0 + %18766 = OpCompositeExtract %float %24081 1 + %9044 = OpCompositeConstruct %v4float %24341 %18766 %float_0 %float_0 + OpBranch %16226 + %7358 = OpLabel + %22211 = OpCompositeExtract %uint %10945 0 + %20240 = OpCompositeConstruct %v3uint %22211 %22211 %22211 + %11031 = OpShiftRightLogical %v3uint %20240 %2996 + %24046 = OpBitwiseAnd %v3uint %11031 %261 + %18596 = OpBitwiseAnd %v3uint %24046 %1126 + %23448 = OpShiftRightLogical %v3uint %24046 %2828 + %16593 = OpIEqual %v3bool %23448 %2578 + %11347 = OpExtInst %v3int %1 FindUMsb %18596 + %10781 = OpBitcast %v3uint %11347 + %6274 = OpISub %v3uint %2828 %10781 + %8728 = OpIAdd %v3uint %10781 %2360 + %10359 = OpSelect %v3uint %16593 %8728 %23448 + %23260 = OpShiftLeftLogical %v3uint %18596 %6274 + %18850 = OpBitwiseAnd %v3uint %23260 %1126 + %10931 = OpSelect %v3uint %16593 %18850 %18596 + %24577 = OpIAdd %v3uint %10359 %1018 + %20359 = OpShiftLeftLogical %v3uint %24577 %393 + %16302 = OpShiftLeftLogical %v3uint %10931 %141 + %22404 = OpBitwiseOr %v3uint %20359 %16302 + %13832 = OpIEqual %v3bool %24046 %2578 + %16970 = OpSelect %v3uint %13832 %2578 %22404 + %10711 = OpBitcast %v3float %16970 + %19372 = OpShiftRightLogical %uint %22211 %uint_30 + %18454 = OpConvertUToF %float %19372 + %15911 = OpFMul %float %18454 %float_0_333333343 + %21450 = OpCompositeExtract %float %10711 0 + %10845 = OpCompositeExtract %float %10711 1 + %7839 = OpCompositeExtract %float %10711 2 + %15840 = OpCompositeConstruct %v4float %21450 %10845 %7839 %15911 + %10235 = OpCompositeExtract %uint %10945 1 + %13588 = OpCompositeConstruct %v3uint %10235 %10235 %10235 + %11032 = OpShiftRightLogical %v3uint %13588 %2996 + %24047 = OpBitwiseAnd %v3uint %11032 %261 + %18597 = OpBitwiseAnd %v3uint %24047 %1126 + %23449 = OpShiftRightLogical %v3uint %24047 %2828 + %16594 = OpIEqual %v3bool %23449 %2578 + %11348 = OpExtInst %v3int %1 FindUMsb %18597 + %10782 = OpBitcast %v3uint %11348 + %6275 = OpISub %v3uint %2828 %10782 + %8729 = OpIAdd %v3uint %10782 %2360 + %10360 = OpSelect %v3uint %16594 %8729 %23449 + %23261 = OpShiftLeftLogical %v3uint %18597 %6275 + %18851 = OpBitwiseAnd %v3uint %23261 %1126 + %10932 = OpSelect %v3uint %16594 %18851 %18597 + %24578 = OpIAdd %v3uint %10360 %1018 + %20360 = OpShiftLeftLogical %v3uint %24578 %393 + %16303 = OpShiftLeftLogical %v3uint %10932 %141 + %22405 = OpBitwiseOr %v3uint %20360 %16303 + %13833 = OpIEqual %v3bool %24047 %2578 + %16971 = OpSelect %v3uint %13833 %2578 %22405 + %10712 = OpBitcast %v3float %16971 + %19373 = OpShiftRightLogical %uint %10235 %uint_30 + %18455 = OpConvertUToF %float %19373 + %15912 = OpFMul %float %18455 %float_0_333333343 + %21451 = OpCompositeExtract %float %10712 0 + %10846 = OpCompositeExtract %float %10712 1 + %7840 = OpCompositeExtract %float %10712 2 + %15841 = OpCompositeConstruct %v4float %21451 %10846 %7840 %15912 + %10236 = OpCompositeExtract %uint %10945 2 + %13589 = OpCompositeConstruct %v3uint %10236 %10236 %10236 + %11033 = OpShiftRightLogical %v3uint %13589 %2996 + %24048 = OpBitwiseAnd %v3uint %11033 %261 + %18606 = OpBitwiseAnd %v3uint %24048 %1126 + %23450 = OpShiftRightLogical %v3uint %24048 %2828 + %16595 = OpIEqual %v3bool %23450 %2578 + %11349 = OpExtInst %v3int %1 FindUMsb %18606 + %10783 = OpBitcast %v3uint %11349 + %6276 = OpISub %v3uint %2828 %10783 + %8730 = OpIAdd %v3uint %10783 %2360 + %10361 = OpSelect %v3uint %16595 %8730 %23450 + %23262 = OpShiftLeftLogical %v3uint %18606 %6276 + %18852 = OpBitwiseAnd %v3uint %23262 %1126 + %10933 = OpSelect %v3uint %16595 %18852 %18606 + %24579 = OpIAdd %v3uint %10361 %1018 + %20361 = OpShiftLeftLogical %v3uint %24579 %393 + %16304 = OpShiftLeftLogical %v3uint %10933 %141 + %22406 = OpBitwiseOr %v3uint %20361 %16304 + %13834 = OpIEqual %v3bool %24048 %2578 + %16972 = OpSelect %v3uint %13834 %2578 %22406 + %10713 = OpBitcast %v3float %16972 + %19374 = OpShiftRightLogical %uint %10236 %uint_30 + %18456 = OpConvertUToF %float %19374 + %15913 = OpFMul %float %18456 %float_0_333333343 + %21452 = OpCompositeExtract %float %10713 0 + %10847 = OpCompositeExtract %float %10713 1 + %7841 = OpCompositeExtract %float %10713 2 + %15842 = OpCompositeConstruct %v4float %21452 %10847 %7841 %15913 + %10237 = OpCompositeExtract %uint %10945 3 + %13590 = OpCompositeConstruct %v3uint %10237 %10237 %10237 + %11034 = OpShiftRightLogical %v3uint %13590 %2996 + %24049 = OpBitwiseAnd %v3uint %11034 %261 + %18607 = OpBitwiseAnd %v3uint %24049 %1126 + %23451 = OpShiftRightLogical %v3uint %24049 %2828 + %16596 = OpIEqual %v3bool %23451 %2578 + %11350 = OpExtInst %v3int %1 FindUMsb %18607 + %10784 = OpBitcast %v3uint %11350 + %6277 = OpISub %v3uint %2828 %10784 + %8731 = OpIAdd %v3uint %10784 %2360 + %10362 = OpSelect %v3uint %16596 %8731 %23451 + %23263 = OpShiftLeftLogical %v3uint %18607 %6277 + %18853 = OpBitwiseAnd %v3uint %23263 %1126 + %10934 = OpSelect %v3uint %16596 %18853 %18607 + %24580 = OpIAdd %v3uint %10362 %1018 + %20362 = OpShiftLeftLogical %v3uint %24580 %393 + %16305 = OpShiftLeftLogical %v3uint %10934 %141 + %22407 = OpBitwiseOr %v3uint %20362 %16305 + %13835 = OpIEqual %v3bool %24049 %2578 + %16973 = OpSelect %v3uint %13835 %2578 %22407 + %10714 = OpBitcast %v3float %16973 + %19375 = OpShiftRightLogical %uint %10237 %uint_30 + %18457 = OpConvertUToF %float %19375 + %15914 = OpFMul %float %18457 %float_0_333333343 + %21453 = OpCompositeExtract %float %10714 0 + %10848 = OpCompositeExtract %float %10714 1 + %11035 = OpCompositeExtract %float %10714 2 + %9045 = OpCompositeConstruct %v4float %21453 %10848 %11035 %15914 + OpBranch %16226 + %7359 = OpLabel + %22212 = OpCompositeExtract %uint %10945 0 + %20241 = OpCompositeConstruct %v4uint %22212 %22212 %22212 %22212 + %9384 = OpShiftRightLogical %v4uint %20241 %845 + %18867 = OpBitwiseAnd %v4uint %9384 %635 + %15549 = OpConvertUToF %v4float %18867 + %16694 = OpFMul %v4float %15549 %2798 + %23768 = OpCompositeExtract %uint %10945 1 + %20819 = OpCompositeConstruct %v4uint %23768 %23768 %23768 %23768 + %9385 = OpShiftRightLogical %v4uint %20819 %845 + %18868 = OpBitwiseAnd %v4uint %9385 %635 + %15550 = OpConvertUToF %v4float %18868 + %16695 = OpFMul %v4float %15550 %2798 + %23769 = OpCompositeExtract %uint %10945 2 + %20820 = OpCompositeConstruct %v4uint %23769 %23769 %23769 %23769 + %9386 = OpShiftRightLogical %v4uint %20820 %845 + %18869 = OpBitwiseAnd %v4uint %9386 %635 + %15551 = OpConvertUToF %v4float %18869 + %16696 = OpFMul %v4float %15551 %2798 + %23770 = OpCompositeExtract %uint %10945 3 + %20821 = OpCompositeConstruct %v4uint %23770 %23770 %23770 %23770 + %9387 = OpShiftRightLogical %v4uint %20821 %845 + %18870 = OpBitwiseAnd %v4uint %9387 %635 + %18737 = OpConvertUToF %v4float %18870 + %9889 = OpFMul %v4float %18737 %2798 + OpBranch %16226 + %14587 = OpLabel + %22213 = OpCompositeExtract %uint %10945 0 + %20242 = OpCompositeConstruct %v4uint %22213 %22213 %22213 %22213 + %9388 = OpShiftRightLogical %v4uint %20242 %653 + %19038 = OpBitwiseAnd %v4uint %9388 %1611 + %13994 = OpConvertUToF %v4float %19038 + %19241 = OpVectorTimesScalar %v4float %13994 %float_0_00392156886 + %8613 = OpCompositeExtract %uint %10945 1 + %24849 = OpCompositeConstruct %v4uint %8613 %8613 %8613 %8613 + %9389 = OpShiftRightLogical %v4uint %24849 %653 + %19039 = OpBitwiseAnd %v4uint %9389 %1611 + %13995 = OpConvertUToF %v4float %19039 + %19242 = OpVectorTimesScalar %v4float %13995 %float_0_00392156886 + %8614 = OpCompositeExtract %uint %10945 2 + %24850 = OpCompositeConstruct %v4uint %8614 %8614 %8614 %8614 + %9390 = OpShiftRightLogical %v4uint %24850 %653 + %19040 = OpBitwiseAnd %v4uint %9390 %1611 + %13996 = OpConvertUToF %v4float %19040 + %19243 = OpVectorTimesScalar %v4float %13996 %float_0_00392156886 + %8615 = OpCompositeExtract %uint %10945 3 + %24851 = OpCompositeConstruct %v4uint %8615 %8615 %8615 %8615 + %9391 = OpShiftRightLogical %v4uint %24851 %653 + %19041 = OpBitwiseAnd %v4uint %9391 %1611 + %17180 = OpConvertUToF %v4float %19041 + %12436 = OpVectorTimesScalar %v4float %17180 %float_0_00392156886 + OpBranch %16226 + %19453 = OpLabel + %12432 = OpCompositeExtract %uint %10945 0 + %20464 = OpBitcast %float %12432 + %17212 = OpCompositeConstruct %v2float %20464 %float_0 + %11670 = OpVectorShuffle %v4float %17212 %17212 0 1 1 1 + %22199 = OpCompositeExtract %uint %10945 1 + %16238 = OpBitcast %float %22199 + %17213 = OpCompositeConstruct %v2float %16238 %float_0 + %11671 = OpVectorShuffle %v4float %17213 %17213 0 1 1 1 + %22200 = OpCompositeExtract %uint %10945 2 + %16239 = OpBitcast %float %22200 + %17214 = OpCompositeConstruct %v2float %16239 %float_0 + %11672 = OpVectorShuffle %v4float %17214 %17214 0 1 1 1 + %22201 = OpCompositeExtract %uint %10945 3 + %16240 = OpBitcast %float %22201 + %20400 = OpCompositeConstruct %v2float %16240 %float_0 + %23100 = OpVectorShuffle %v4float %20400 %20400 0 1 1 1 + OpBranch %16226 + %16226 = OpLabel + %11181 = OpPhi %v4float %23100 %19453 %12436 %14587 %9889 %7359 %9045 %7358 %9044 %8192 %9043 %8247 + %14350 = OpPhi %v4float %11672 %19453 %19243 %14587 %16696 %7359 %15842 %7358 %16678 %8192 %14618 %8247 + %15237 = OpPhi %v4float %11671 %19453 %19242 %14587 %16695 %7359 %15841 %7358 %16677 %8192 %14617 %8247 + %14522 = OpPhi %v4float %11670 %19453 %19241 %14587 %16694 %7359 %15840 %7358 %16676 %8192 %14616 %8247 + OpBranch %21265 + %15207 = OpLabel + %21586 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20263 DontFlatten + OpBranchConditional %21586 %9768 %12134 + %12134 = OpLabel + %19412 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23885 = OpLoad %uint %19412 + %11721 = OpIAdd %uint %20988 %uint_1 + %6417 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11721 + %23674 = OpLoad %uint %6417 + %11722 = OpIAdd %uint %20988 %6555 + %6418 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11722 + %23675 = OpLoad %uint %6418 + %11723 = OpIAdd %uint %11722 %uint_1 + %24581 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11723 + %14158 = OpLoad %uint %24581 + %19673 = OpCompositeConstruct %v4uint %23885 %23674 %23675 %14158 + %17050 = OpIMul %uint %uint_2 %6555 + %13997 = OpIAdd %uint %20988 %17050 + %15238 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13997 + %23676 = OpLoad %uint %15238 + %11724 = OpIAdd %uint %13997 %uint_1 + %6480 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11724 + %24163 = OpLoad %uint %6480 + %6242 = OpIMul %uint %uint_3 %6555 + %8361 = OpIAdd %uint %20988 %6242 + %15239 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8361 + %23677 = OpLoad %uint %15239 + %11725 = OpIAdd %uint %8361 %uint_1 + %24582 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11725 + %16390 = OpLoad %uint %24582 + %20790 = OpCompositeConstruct %v4uint %23676 %24163 %23677 %16390 + OpBranch %20263 + %9768 = OpLabel + %21834 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23886 = OpLoad %uint %21834 + %11726 = OpIAdd %uint %20988 %uint_1 + %6419 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11726 + %23678 = OpLoad %uint %6419 + %11727 = OpIAdd %uint %20988 %uint_2 + %6420 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11727 + %23679 = OpLoad %uint %6420 + %11728 = OpIAdd %uint %20988 %uint_3 + %24583 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11728 + %14082 = OpLoad %uint %24583 + %19168 = OpCompositeConstruct %v4uint %23886 %23678 %23679 %14082 + %22503 = OpIAdd %uint %20988 %uint_4 + %24653 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22503 + %23680 = OpLoad %uint %24653 + %11729 = OpIAdd %uint %20988 %uint_5 + %6421 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11729 + %23681 = OpLoad %uint %6421 + %11730 = OpIAdd %uint %20988 %uint_6 + %6422 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11730 + %23682 = OpLoad %uint %6422 + %11731 = OpIAdd %uint %20988 %uint_7 + %24584 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11731 + %16391 = OpLoad %uint %24584 + %20791 = OpCompositeConstruct %v4uint %23680 %23681 %23682 %16391 + OpBranch %20263 + %20263 = OpLabel + %11215 = OpPhi %v4uint %20791 %9768 %20790 %12134 + %14114 = OpPhi %v4uint %19168 %9768 %19673 %12134 + OpSelectionMerge %20264 None + OpSwitch %8576 %20312 5 %8538 7 %8248 + %8248 = OpLabel + %24411 = OpCompositeExtract %uint %14114 0 + %24684 = OpExtInst %v2float %1 UnpackHalf2x16 %24411 + %10110 = OpCompositeExtract %float %24684 0 + %16064 = OpCompositeExtract %float %24684 1 + %17033 = OpCompositeExtract %uint %14114 1 + %15613 = OpExtInst %v2float %1 UnpackHalf2x16 %17033 + %10111 = OpCompositeExtract %float %15613 0 + %17493 = OpCompositeExtract %float %15613 1 + %14619 = OpCompositeConstruct %v4float %10110 %16064 %10111 %17493 + %17289 = OpCompositeExtract %uint %14114 2 + %18042 = OpExtInst %v2float %1 UnpackHalf2x16 %17289 + %10112 = OpCompositeExtract %float %18042 0 + %16065 = OpCompositeExtract %float %18042 1 + %17034 = OpCompositeExtract %uint %14114 3 + %15614 = OpExtInst %v2float %1 UnpackHalf2x16 %17034 + %10113 = OpCompositeExtract %float %15614 0 + %17494 = OpCompositeExtract %float %15614 1 + %14620 = OpCompositeConstruct %v4float %10112 %16065 %10113 %17494 + %17290 = OpCompositeExtract %uint %11215 0 + %18043 = OpExtInst %v2float %1 UnpackHalf2x16 %17290 + %10114 = OpCompositeExtract %float %18043 0 + %16066 = OpCompositeExtract %float %18043 1 + %17035 = OpCompositeExtract %uint %11215 1 + %15615 = OpExtInst %v2float %1 UnpackHalf2x16 %17035 + %10115 = OpCompositeExtract %float %15615 0 + %17495 = OpCompositeExtract %float %15615 1 + %14621 = OpCompositeConstruct %v4float %10114 %16066 %10115 %17495 + %17291 = OpCompositeExtract %uint %11215 2 + %18044 = OpExtInst %v2float %1 UnpackHalf2x16 %17291 + %10116 = OpCompositeExtract %float %18044 0 + %16067 = OpCompositeExtract %float %18044 1 + %17036 = OpCompositeExtract %uint %11215 3 + %15616 = OpExtInst %v2float %1 UnpackHalf2x16 %17036 + %10117 = OpCompositeExtract %float %15616 0 + %20675 = OpCompositeExtract %float %15616 1 + %9046 = OpCompositeConstruct %v4float %10116 %16067 %10117 %20675 + OpBranch %20264 + %8538 = OpLabel + %9725 = OpVectorShuffle %v2uint %14114 %14114 0 1 + %23358 = OpBitcast %v2int %9725 + %24790 = OpVectorShuffle %v4int %23358 %23358 0 0 1 1 + %18608 = OpShiftLeftLogical %v4int %24790 %290 + %15765 = OpShiftRightArithmetic %v4int %18608 %770 + %10935 = OpConvertSToF %v4float %15765 + %18220 = OpVectorTimesScalar %v4float %10935 %float_0_000976592302 + %25239 = OpExtInst %v4float %1 FMax %1284 %18220 + %14193 = OpVectorShuffle %v2uint %14114 %14114 2 3 + %9413 = OpBitcast %v2int %14193 + %24791 = OpVectorShuffle %v4int %9413 %9413 0 0 1 1 + %18609 = OpShiftLeftLogical %v4int %24791 %290 + %15766 = OpShiftRightArithmetic %v4int %18609 %770 + %10936 = OpConvertSToF %v4float %15766 + %18221 = OpVectorTimesScalar %v4float %10936 %float_0_000976592302 + %25240 = OpExtInst %v4float %1 FMax %1284 %18221 + %14194 = OpVectorShuffle %v2uint %11215 %11215 0 1 + %9414 = OpBitcast %v2int %14194 + %24792 = OpVectorShuffle %v4int %9414 %9414 0 0 1 1 + %18610 = OpShiftLeftLogical %v4int %24792 %290 + %15767 = OpShiftRightArithmetic %v4int %18610 %770 + %10937 = OpConvertSToF %v4float %15767 + %18222 = OpVectorTimesScalar %v4float %10937 %float_0_000976592302 + %25241 = OpExtInst %v4float %1 FMax %1284 %18222 + %14195 = OpVectorShuffle %v2uint %11215 %11215 2 3 + %9415 = OpBitcast %v2int %14195 + %24793 = OpVectorShuffle %v4int %9415 %9415 0 0 1 1 + %18611 = OpShiftLeftLogical %v4int %24793 %290 + %15768 = OpShiftRightArithmetic %v4int %18611 %770 + %10938 = OpConvertSToF %v4float %15768 + %21441 = OpVectorTimesScalar %v4float %10938 %float_0_000976592302 + %17252 = OpExtInst %v4float %1 FMax %1284 %21441 + OpBranch %20264 + %20312 = OpLabel + %9769 = OpVectorShuffle %v2uint %14114 %14114 0 1 + %20827 = OpBitcast %v2float %9769 + %7044 = OpCompositeExtract %float %20827 0 + %13424 = OpCompositeExtract %float %20827 1 + %17022 = OpCompositeConstruct %v4float %7044 %13424 %float_0 %float_0 + %16862 = OpVectorShuffle %v2uint %14114 %14114 2 3 + %14179 = OpBitcast %v2float %16862 + %7045 = OpCompositeExtract %float %14179 0 + %13425 = OpCompositeExtract %float %14179 1 + %17023 = OpCompositeConstruct %v4float %7045 %13425 %float_0 %float_0 + %16863 = OpVectorShuffle %v2uint %11215 %11215 0 1 + %14180 = OpBitcast %v2float %16863 + %7046 = OpCompositeExtract %float %14180 0 + %13426 = OpCompositeExtract %float %14180 1 + %17024 = OpCompositeConstruct %v4float %7046 %13426 %float_0 %float_0 + %16864 = OpVectorShuffle %v2uint %11215 %11215 2 3 + %14181 = OpBitcast %v2float %16864 + %7047 = OpCompositeExtract %float %14181 0 + %16650 = OpCompositeExtract %float %14181 1 + %9047 = OpCompositeConstruct %v4float %7047 %16650 %float_0 %float_0 + OpBranch %20264 + %20264 = OpLabel + %11182 = OpPhi %v4float %9047 %20312 %17252 %8538 %9046 %8248 + %14351 = OpPhi %v4float %17024 %20312 %25241 %8538 %14621 %8248 + %15240 = OpPhi %v4float %17023 %20312 %25240 %8538 %14620 %8248 + %14523 = OpPhi %v4float %17022 %20312 %25239 %8538 %14619 %8248 + OpBranch %21265 + %21265 = OpLabel + %11183 = OpPhi %v4float %11182 %20264 %11181 %16226 + %14352 = OpPhi %v4float %14351 %20264 %14350 %16226 + %12950 = OpPhi %v4float %15240 %20264 %15237 %16226 + %13947 = OpPhi %v4float %14523 %20264 %14522 %16226 + %17242 = OpFAdd %v4float %17241 %13947 + %23298 = OpFAdd %v4float %23297 %12950 + %7208 = OpFAdd %v4float %8082 %14352 + %9642 = OpFAdd %v4float %20755 %11183 + %16376 = OpIAdd %uint %8114 %14258 + OpSelectionMerge %21266 DontFlatten + OpBranchConditional %23279 %15208 %16572 + %16572 = OpLabel + %19169 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20300 DontFlatten + OpBranchConditional %19169 %9770 %12135 + %12135 = OpLabel + %19413 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23887 = OpLoad %uint %19413 + %11732 = OpIAdd %uint %16376 %6555 + %6481 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11732 + %24164 = OpLoad %uint %6481 + %6243 = OpIMul %uint %uint_2 %6555 + %8362 = OpIAdd %uint %16376 %6243 + %15312 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8362 + %24165 = OpLoad %uint %15312 + %6244 = OpIMul %uint %uint_3 %6555 + %8363 = OpIAdd %uint %16376 %6244 + %14324 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8363 + %16392 = OpLoad %uint %14324 + %20792 = OpCompositeConstruct %v4uint %23887 %24164 %24165 %16392 + OpBranch %20300 + %9770 = OpLabel + %21835 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23888 = OpLoad %uint %21835 + %11733 = OpIAdd %uint %16376 %uint_1 + %6423 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11733 + %23683 = OpLoad %uint %6423 + %11734 = OpIAdd %uint %16376 %uint_2 + %6424 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11734 + %23684 = OpLoad %uint %6424 + %11735 = OpIAdd %uint %16376 %uint_3 + %24585 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11735 + %16393 = OpLoad %uint %24585 + %20793 = OpCompositeConstruct %v4uint %23888 %23683 %23684 %16393 + OpBranch %20300 + %20300 = OpLabel + %10946 = OpPhi %v4uint %20793 %9770 %20792 %12135 + OpSelectionMerge %16227 None + OpSwitch %8576 %19454 0 %14588 1 %14588 2 %7361 10 %7361 3 %7360 12 %7360 4 %8193 6 %8249 + %8249 = OpLabel + %24412 = OpCompositeExtract %uint %10946 0 + %24685 = OpExtInst %v2float %1 UnpackHalf2x16 %24412 + %10118 = OpCompositeExtract %float %24685 0 + %17496 = OpCompositeExtract %float %24685 1 + %14622 = OpCompositeConstruct %v4float %10118 %17496 %float_0 %float_0 + %17292 = OpCompositeExtract %uint %10946 1 + %18045 = OpExtInst %v2float %1 UnpackHalf2x16 %17292 + %10119 = OpCompositeExtract %float %18045 0 + %17497 = OpCompositeExtract %float %18045 1 + %14623 = OpCompositeConstruct %v4float %10119 %17497 %float_0 %float_0 + %17293 = OpCompositeExtract %uint %10946 2 + %18046 = OpExtInst %v2float %1 UnpackHalf2x16 %17293 + %10120 = OpCompositeExtract %float %18046 0 + %17498 = OpCompositeExtract %float %18046 1 + %14624 = OpCompositeConstruct %v4float %10120 %17498 %float_0 %float_0 + %17294 = OpCompositeExtract %uint %10946 3 + %18047 = OpExtInst %v2float %1 UnpackHalf2x16 %17294 + %10121 = OpCompositeExtract %float %18047 0 + %20676 = OpCompositeExtract %float %18047 1 + %9048 = OpCompositeConstruct %v4float %10121 %20676 %float_0 %float_0 + OpBranch %16227 + %8193 = OpLabel + %12433 = OpCompositeExtract %uint %10946 0 + %22688 = OpBitcast %int %12433 + %18223 = OpCompositeConstruct %v2int %22688 %22688 + %18361 = OpShiftLeftLogical %v2int %18223 %1959 + %13347 = OpShiftRightArithmetic %v2int %18361 %2151 + %10939 = OpConvertSToF %v2float %13347 + %18259 = OpVectorTimesScalar %v2float %10939 %float_0_000976592302 + %24082 = OpExtInst %v2float %1 FMax %73 %18259 + %24342 = OpCompositeExtract %float %24082 0 + %15581 = OpCompositeExtract %float %24082 1 + %16679 = OpCompositeConstruct %v4float %24342 %15581 %float_0 %float_0 + %19531 = OpCompositeExtract %uint %10946 1 + %16042 = OpBitcast %int %19531 + %18224 = OpCompositeConstruct %v2int %16042 %16042 + %18362 = OpShiftLeftLogical %v2int %18224 %1959 + %13348 = OpShiftRightArithmetic %v2int %18362 %2151 + %10940 = OpConvertSToF %v2float %13348 + %18260 = OpVectorTimesScalar %v2float %10940 %float_0_000976592302 + %24083 = OpExtInst %v2float %1 FMax %73 %18260 + %24343 = OpCompositeExtract %float %24083 0 + %15582 = OpCompositeExtract %float %24083 1 + %16680 = OpCompositeConstruct %v4float %24343 %15582 %float_0 %float_0 + %19532 = OpCompositeExtract %uint %10946 2 + %16043 = OpBitcast %int %19532 + %18225 = OpCompositeConstruct %v2int %16043 %16043 + %18364 = OpShiftLeftLogical %v2int %18225 %1959 + %13349 = OpShiftRightArithmetic %v2int %18364 %2151 + %10941 = OpConvertSToF %v2float %13349 + %18261 = OpVectorTimesScalar %v2float %10941 %float_0_000976592302 + %24084 = OpExtInst %v2float %1 FMax %73 %18261 + %24344 = OpCompositeExtract %float %24084 0 + %15583 = OpCompositeExtract %float %24084 1 + %16681 = OpCompositeConstruct %v4float %24344 %15583 %float_0 %float_0 + %19533 = OpCompositeExtract %uint %10946 3 + %16044 = OpBitcast %int %19533 + %18226 = OpCompositeConstruct %v2int %16044 %16044 + %18365 = OpShiftLeftLogical %v2int %18226 %1959 + %13350 = OpShiftRightArithmetic %v2int %18365 %2151 + %10942 = OpConvertSToF %v2float %13350 + %18262 = OpVectorTimesScalar %v2float %10942 %float_0_000976592302 + %24085 = OpExtInst %v2float %1 FMax %73 %18262 + %24345 = OpCompositeExtract %float %24085 0 + %18767 = OpCompositeExtract %float %24085 1 + %9049 = OpCompositeConstruct %v4float %24345 %18767 %float_0 %float_0 + OpBranch %16227 + %7360 = OpLabel + %22214 = OpCompositeExtract %uint %10946 0 + %20243 = OpCompositeConstruct %v3uint %22214 %22214 %22214 + %11036 = OpShiftRightLogical %v3uint %20243 %2996 + %24050 = OpBitwiseAnd %v3uint %11036 %261 + %18612 = OpBitwiseAnd %v3uint %24050 %1126 + %23452 = OpShiftRightLogical %v3uint %24050 %2828 + %16597 = OpIEqual %v3bool %23452 %2578 + %11351 = OpExtInst %v3int %1 FindUMsb %18612 + %10785 = OpBitcast %v3uint %11351 + %6278 = OpISub %v3uint %2828 %10785 + %8732 = OpIAdd %v3uint %10785 %2360 + %10363 = OpSelect %v3uint %16597 %8732 %23452 + %23264 = OpShiftLeftLogical %v3uint %18612 %6278 + %18854 = OpBitwiseAnd %v3uint %23264 %1126 + %10947 = OpSelect %v3uint %16597 %18854 %18612 + %24586 = OpIAdd %v3uint %10363 %1018 + %20363 = OpShiftLeftLogical %v3uint %24586 %393 + %16306 = OpShiftLeftLogical %v3uint %10947 %141 + %22408 = OpBitwiseOr %v3uint %20363 %16306 + %13836 = OpIEqual %v3bool %24050 %2578 + %16974 = OpSelect %v3uint %13836 %2578 %22408 + %10715 = OpBitcast %v3float %16974 + %19376 = OpShiftRightLogical %uint %22214 %uint_30 + %18458 = OpConvertUToF %float %19376 + %15915 = OpFMul %float %18458 %float_0_333333343 + %21454 = OpCompositeExtract %float %10715 0 + %10849 = OpCompositeExtract %float %10715 1 + %7842 = OpCompositeExtract %float %10715 2 + %15843 = OpCompositeConstruct %v4float %21454 %10849 %7842 %15915 + %10238 = OpCompositeExtract %uint %10946 1 + %13591 = OpCompositeConstruct %v3uint %10238 %10238 %10238 + %11037 = OpShiftRightLogical %v3uint %13591 %2996 + %24051 = OpBitwiseAnd %v3uint %11037 %261 + %18613 = OpBitwiseAnd %v3uint %24051 %1126 + %23453 = OpShiftRightLogical %v3uint %24051 %2828 + %16598 = OpIEqual %v3bool %23453 %2578 + %11352 = OpExtInst %v3int %1 FindUMsb %18613 + %10786 = OpBitcast %v3uint %11352 + %6279 = OpISub %v3uint %2828 %10786 + %8733 = OpIAdd %v3uint %10786 %2360 + %10364 = OpSelect %v3uint %16598 %8733 %23453 + %23265 = OpShiftLeftLogical %v3uint %18613 %6279 + %18855 = OpBitwiseAnd %v3uint %23265 %1126 + %10948 = OpSelect %v3uint %16598 %18855 %18613 + %24587 = OpIAdd %v3uint %10364 %1018 + %20364 = OpShiftLeftLogical %v3uint %24587 %393 + %16307 = OpShiftLeftLogical %v3uint %10948 %141 + %22409 = OpBitwiseOr %v3uint %20364 %16307 + %13837 = OpIEqual %v3bool %24051 %2578 + %16975 = OpSelect %v3uint %13837 %2578 %22409 + %10716 = OpBitcast %v3float %16975 + %19377 = OpShiftRightLogical %uint %10238 %uint_30 + %18459 = OpConvertUToF %float %19377 + %15916 = OpFMul %float %18459 %float_0_333333343 + %21455 = OpCompositeExtract %float %10716 0 + %10850 = OpCompositeExtract %float %10716 1 + %7843 = OpCompositeExtract %float %10716 2 + %15844 = OpCompositeConstruct %v4float %21455 %10850 %7843 %15916 + %10239 = OpCompositeExtract %uint %10946 2 + %13592 = OpCompositeConstruct %v3uint %10239 %10239 %10239 + %11038 = OpShiftRightLogical %v3uint %13592 %2996 + %24052 = OpBitwiseAnd %v3uint %11038 %261 + %18614 = OpBitwiseAnd %v3uint %24052 %1126 + %23454 = OpShiftRightLogical %v3uint %24052 %2828 + %16599 = OpIEqual %v3bool %23454 %2578 + %11353 = OpExtInst %v3int %1 FindUMsb %18614 + %10787 = OpBitcast %v3uint %11353 + %6280 = OpISub %v3uint %2828 %10787 + %8734 = OpIAdd %v3uint %10787 %2360 + %10365 = OpSelect %v3uint %16599 %8734 %23454 + %23266 = OpShiftLeftLogical %v3uint %18614 %6280 + %18856 = OpBitwiseAnd %v3uint %23266 %1126 + %10949 = OpSelect %v3uint %16599 %18856 %18614 + %24588 = OpIAdd %v3uint %10365 %1018 + %20365 = OpShiftLeftLogical %v3uint %24588 %393 + %16308 = OpShiftLeftLogical %v3uint %10949 %141 + %22410 = OpBitwiseOr %v3uint %20365 %16308 + %13838 = OpIEqual %v3bool %24052 %2578 + %16976 = OpSelect %v3uint %13838 %2578 %22410 + %10717 = OpBitcast %v3float %16976 + %19378 = OpShiftRightLogical %uint %10239 %uint_30 + %18460 = OpConvertUToF %float %19378 + %15917 = OpFMul %float %18460 %float_0_333333343 + %21456 = OpCompositeExtract %float %10717 0 + %10851 = OpCompositeExtract %float %10717 1 + %7844 = OpCompositeExtract %float %10717 2 + %15845 = OpCompositeConstruct %v4float %21456 %10851 %7844 %15917 + %10240 = OpCompositeExtract %uint %10946 3 + %13593 = OpCompositeConstruct %v3uint %10240 %10240 %10240 + %11039 = OpShiftRightLogical %v3uint %13593 %2996 + %24053 = OpBitwiseAnd %v3uint %11039 %261 + %18616 = OpBitwiseAnd %v3uint %24053 %1126 + %23455 = OpShiftRightLogical %v3uint %24053 %2828 + %16600 = OpIEqual %v3bool %23455 %2578 + %11354 = OpExtInst %v3int %1 FindUMsb %18616 + %10788 = OpBitcast %v3uint %11354 + %6281 = OpISub %v3uint %2828 %10788 + %8735 = OpIAdd %v3uint %10788 %2360 + %10366 = OpSelect %v3uint %16600 %8735 %23455 + %23267 = OpShiftLeftLogical %v3uint %18616 %6281 + %18857 = OpBitwiseAnd %v3uint %23267 %1126 + %10950 = OpSelect %v3uint %16600 %18857 %18616 + %24589 = OpIAdd %v3uint %10366 %1018 + %20366 = OpShiftLeftLogical %v3uint %24589 %393 + %16309 = OpShiftLeftLogical %v3uint %10950 %141 + %22411 = OpBitwiseOr %v3uint %20366 %16309 + %13839 = OpIEqual %v3bool %24053 %2578 + %16977 = OpSelect %v3uint %13839 %2578 %22411 + %10718 = OpBitcast %v3float %16977 + %19379 = OpShiftRightLogical %uint %10240 %uint_30 + %18461 = OpConvertUToF %float %19379 + %15918 = OpFMul %float %18461 %float_0_333333343 + %21457 = OpCompositeExtract %float %10718 0 + %10852 = OpCompositeExtract %float %10718 1 + %11040 = OpCompositeExtract %float %10718 2 + %9050 = OpCompositeConstruct %v4float %21457 %10852 %11040 %15918 + OpBranch %16227 + %7361 = OpLabel + %22215 = OpCompositeExtract %uint %10946 0 + %20244 = OpCompositeConstruct %v4uint %22215 %22215 %22215 %22215 + %9392 = OpShiftRightLogical %v4uint %20244 %845 + %18871 = OpBitwiseAnd %v4uint %9392 %635 + %15552 = OpConvertUToF %v4float %18871 + %16697 = OpFMul %v4float %15552 %2798 + %23771 = OpCompositeExtract %uint %10946 1 + %20822 = OpCompositeConstruct %v4uint %23771 %23771 %23771 %23771 + %9393 = OpShiftRightLogical %v4uint %20822 %845 + %18872 = OpBitwiseAnd %v4uint %9393 %635 + %15553 = OpConvertUToF %v4float %18872 + %16698 = OpFMul %v4float %15553 %2798 + %23772 = OpCompositeExtract %uint %10946 2 + %20823 = OpCompositeConstruct %v4uint %23772 %23772 %23772 %23772 + %9394 = OpShiftRightLogical %v4uint %20823 %845 + %18873 = OpBitwiseAnd %v4uint %9394 %635 + %15554 = OpConvertUToF %v4float %18873 + %16699 = OpFMul %v4float %15554 %2798 + %23773 = OpCompositeExtract %uint %10946 3 + %20828 = OpCompositeConstruct %v4uint %23773 %23773 %23773 %23773 + %9395 = OpShiftRightLogical %v4uint %20828 %845 + %18874 = OpBitwiseAnd %v4uint %9395 %635 + %18738 = OpConvertUToF %v4float %18874 + %9890 = OpFMul %v4float %18738 %2798 + OpBranch %16227 + %14588 = OpLabel + %22216 = OpCompositeExtract %uint %10946 0 + %20245 = OpCompositeConstruct %v4uint %22216 %22216 %22216 %22216 + %9396 = OpShiftRightLogical %v4uint %20245 %653 + %19042 = OpBitwiseAnd %v4uint %9396 %1611 + %13998 = OpConvertUToF %v4float %19042 + %19244 = OpVectorTimesScalar %v4float %13998 %float_0_00392156886 + %8616 = OpCompositeExtract %uint %10946 1 + %24852 = OpCompositeConstruct %v4uint %8616 %8616 %8616 %8616 + %9397 = OpShiftRightLogical %v4uint %24852 %653 + %19043 = OpBitwiseAnd %v4uint %9397 %1611 + %13999 = OpConvertUToF %v4float %19043 + %19245 = OpVectorTimesScalar %v4float %13999 %float_0_00392156886 + %8617 = OpCompositeExtract %uint %10946 2 + %24853 = OpCompositeConstruct %v4uint %8617 %8617 %8617 %8617 + %9398 = OpShiftRightLogical %v4uint %24853 %653 + %19044 = OpBitwiseAnd %v4uint %9398 %1611 + %14000 = OpConvertUToF %v4float %19044 + %19246 = OpVectorTimesScalar %v4float %14000 %float_0_00392156886 + %8618 = OpCompositeExtract %uint %10946 3 + %24854 = OpCompositeConstruct %v4uint %8618 %8618 %8618 %8618 + %9399 = OpShiftRightLogical %v4uint %24854 %653 + %19045 = OpBitwiseAnd %v4uint %9399 %1611 + %17181 = OpConvertUToF %v4float %19045 + %12437 = OpVectorTimesScalar %v4float %17181 %float_0_00392156886 + OpBranch %16227 + %19454 = OpLabel + %12438 = OpCompositeExtract %uint %10946 0 + %20465 = OpBitcast %float %12438 + %17215 = OpCompositeConstruct %v2float %20465 %float_0 + %11673 = OpVectorShuffle %v4float %17215 %17215 0 1 1 1 + %22202 = OpCompositeExtract %uint %10946 1 + %16241 = OpBitcast %float %22202 + %17216 = OpCompositeConstruct %v2float %16241 %float_0 + %11674 = OpVectorShuffle %v4float %17216 %17216 0 1 1 1 + %22203 = OpCompositeExtract %uint %10946 2 + %16242 = OpBitcast %float %22203 + %17217 = OpCompositeConstruct %v2float %16242 %float_0 + %11675 = OpVectorShuffle %v4float %17217 %17217 0 1 1 1 + %22204 = OpCompositeExtract %uint %10946 3 + %16243 = OpBitcast %float %22204 + %20401 = OpCompositeConstruct %v2float %16243 %float_0 + %23101 = OpVectorShuffle %v4float %20401 %20401 0 1 1 1 + OpBranch %16227 + %16227 = OpLabel + %11184 = OpPhi %v4float %23101 %19454 %12437 %14588 %9890 %7361 %9050 %7360 %9049 %8193 %9048 %8249 + %14353 = OpPhi %v4float %11675 %19454 %19246 %14588 %16699 %7361 %15845 %7360 %16681 %8193 %14624 %8249 + %15241 = OpPhi %v4float %11674 %19454 %19245 %14588 %16698 %7361 %15844 %7360 %16680 %8193 %14623 %8249 + %14524 = OpPhi %v4float %11673 %19454 %19244 %14588 %16697 %7361 %15843 %7360 %16679 %8193 %14622 %8249 + OpBranch %21266 + %15208 = OpLabel + %21587 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20265 DontFlatten + OpBranchConditional %21587 %9771 %12136 + %12136 = OpLabel + %19414 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23889 = OpLoad %uint %19414 + %11736 = OpIAdd %uint %16376 %uint_1 + %6425 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11736 + %23685 = OpLoad %uint %6425 + %11737 = OpIAdd %uint %16376 %6555 + %6426 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11737 + %23686 = OpLoad %uint %6426 + %11738 = OpIAdd %uint %11737 %uint_1 + %24590 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11738 + %14159 = OpLoad %uint %24590 + %19674 = OpCompositeConstruct %v4uint %23889 %23685 %23686 %14159 + %17051 = OpIMul %uint %uint_2 %6555 + %14001 = OpIAdd %uint %16376 %17051 + %15242 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %14001 + %23687 = OpLoad %uint %15242 + %11739 = OpIAdd %uint %14001 %uint_1 + %6482 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11739 + %24166 = OpLoad %uint %6482 + %6245 = OpIMul %uint %uint_3 %6555 + %8364 = OpIAdd %uint %16376 %6245 + %15243 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8364 + %23688 = OpLoad %uint %15243 + %11740 = OpIAdd %uint %8364 %uint_1 + %24591 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11740 + %16394 = OpLoad %uint %24591 + %20794 = OpCompositeConstruct %v4uint %23687 %24166 %23688 %16394 + OpBranch %20265 + %9771 = OpLabel + %21836 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23890 = OpLoad %uint %21836 + %11741 = OpIAdd %uint %16376 %uint_1 + %6427 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11741 + %23689 = OpLoad %uint %6427 + %11742 = OpIAdd %uint %16376 %uint_2 + %6428 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11742 + %23690 = OpLoad %uint %6428 + %11743 = OpIAdd %uint %16376 %uint_3 + %24592 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11743 + %14083 = OpLoad %uint %24592 + %19170 = OpCompositeConstruct %v4uint %23890 %23689 %23690 %14083 + %22504 = OpIAdd %uint %16376 %uint_4 + %24654 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22504 + %23691 = OpLoad %uint %24654 + %11744 = OpIAdd %uint %16376 %uint_5 + %6429 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11744 + %23692 = OpLoad %uint %6429 + %11745 = OpIAdd %uint %16376 %uint_6 + %6430 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11745 + %23693 = OpLoad %uint %6430 + %11746 = OpIAdd %uint %16376 %uint_7 + %24593 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11746 + %16395 = OpLoad %uint %24593 + %20795 = OpCompositeConstruct %v4uint %23691 %23692 %23693 %16395 + OpBranch %20265 + %20265 = OpLabel + %11216 = OpPhi %v4uint %20795 %9771 %20794 %12136 + %14115 = OpPhi %v4uint %19170 %9771 %19674 %12136 + OpSelectionMerge %20266 None + OpSwitch %8576 %20313 5 %8539 7 %8250 + %8250 = OpLabel + %24413 = OpCompositeExtract %uint %14115 0 + %24686 = OpExtInst %v2float %1 UnpackHalf2x16 %24413 + %10122 = OpCompositeExtract %float %24686 0 + %16068 = OpCompositeExtract %float %24686 1 + %17037 = OpCompositeExtract %uint %14115 1 + %15617 = OpExtInst %v2float %1 UnpackHalf2x16 %17037 + %10123 = OpCompositeExtract %float %15617 0 + %17499 = OpCompositeExtract %float %15617 1 + %14625 = OpCompositeConstruct %v4float %10122 %16068 %10123 %17499 + %17295 = OpCompositeExtract %uint %14115 2 + %18048 = OpExtInst %v2float %1 UnpackHalf2x16 %17295 + %10124 = OpCompositeExtract %float %18048 0 + %16069 = OpCompositeExtract %float %18048 1 + %17038 = OpCompositeExtract %uint %14115 3 + %15618 = OpExtInst %v2float %1 UnpackHalf2x16 %17038 + %10125 = OpCompositeExtract %float %15618 0 + %17500 = OpCompositeExtract %float %15618 1 + %14626 = OpCompositeConstruct %v4float %10124 %16069 %10125 %17500 + %17296 = OpCompositeExtract %uint %11216 0 + %18049 = OpExtInst %v2float %1 UnpackHalf2x16 %17296 + %10126 = OpCompositeExtract %float %18049 0 + %16070 = OpCompositeExtract %float %18049 1 + %17039 = OpCompositeExtract %uint %11216 1 + %15619 = OpExtInst %v2float %1 UnpackHalf2x16 %17039 + %10127 = OpCompositeExtract %float %15619 0 + %17501 = OpCompositeExtract %float %15619 1 + %14627 = OpCompositeConstruct %v4float %10126 %16070 %10127 %17501 + %17297 = OpCompositeExtract %uint %11216 2 + %18050 = OpExtInst %v2float %1 UnpackHalf2x16 %17297 + %10128 = OpCompositeExtract %float %18050 0 + %16071 = OpCompositeExtract %float %18050 1 + %17040 = OpCompositeExtract %uint %11216 3 + %15620 = OpExtInst %v2float %1 UnpackHalf2x16 %17040 + %10129 = OpCompositeExtract %float %15620 0 + %20677 = OpCompositeExtract %float %15620 1 + %9051 = OpCompositeConstruct %v4float %10128 %16071 %10129 %20677 + OpBranch %20266 + %8539 = OpLabel + %9726 = OpVectorShuffle %v2uint %14115 %14115 0 1 + %23359 = OpBitcast %v2int %9726 + %24794 = OpVectorShuffle %v4int %23359 %23359 0 0 1 1 + %18617 = OpShiftLeftLogical %v4int %24794 %290 + %15769 = OpShiftRightArithmetic %v4int %18617 %770 + %10951 = OpConvertSToF %v4float %15769 + %18227 = OpVectorTimesScalar %v4float %10951 %float_0_000976592302 + %25242 = OpExtInst %v4float %1 FMax %1284 %18227 + %14196 = OpVectorShuffle %v2uint %14115 %14115 2 3 + %9416 = OpBitcast %v2int %14196 + %24795 = OpVectorShuffle %v4int %9416 %9416 0 0 1 1 + %18618 = OpShiftLeftLogical %v4int %24795 %290 + %15770 = OpShiftRightArithmetic %v4int %18618 %770 + %10952 = OpConvertSToF %v4float %15770 + %18228 = OpVectorTimesScalar %v4float %10952 %float_0_000976592302 + %25243 = OpExtInst %v4float %1 FMax %1284 %18228 + %14197 = OpVectorShuffle %v2uint %11216 %11216 0 1 + %9417 = OpBitcast %v2int %14197 + %24796 = OpVectorShuffle %v4int %9417 %9417 0 0 1 1 + %18619 = OpShiftLeftLogical %v4int %24796 %290 + %15771 = OpShiftRightArithmetic %v4int %18619 %770 + %10953 = OpConvertSToF %v4float %15771 + %18229 = OpVectorTimesScalar %v4float %10953 %float_0_000976592302 + %25244 = OpExtInst %v4float %1 FMax %1284 %18229 + %14198 = OpVectorShuffle %v2uint %11216 %11216 2 3 + %9418 = OpBitcast %v2int %14198 + %24797 = OpVectorShuffle %v4int %9418 %9418 0 0 1 1 + %18620 = OpShiftLeftLogical %v4int %24797 %290 + %15772 = OpShiftRightArithmetic %v4int %18620 %770 + %10954 = OpConvertSToF %v4float %15772 + %21458 = OpVectorTimesScalar %v4float %10954 %float_0_000976592302 + %17253 = OpExtInst %v4float %1 FMax %1284 %21458 + OpBranch %20266 + %20313 = OpLabel + %9772 = OpVectorShuffle %v2uint %14115 %14115 0 1 + %20829 = OpBitcast %v2float %9772 + %7048 = OpCompositeExtract %float %20829 0 + %13427 = OpCompositeExtract %float %20829 1 + %17041 = OpCompositeConstruct %v4float %7048 %13427 %float_0 %float_0 + %16865 = OpVectorShuffle %v2uint %14115 %14115 2 3 + %14182 = OpBitcast %v2float %16865 + %7049 = OpCompositeExtract %float %14182 0 + %13428 = OpCompositeExtract %float %14182 1 + %17042 = OpCompositeConstruct %v4float %7049 %13428 %float_0 %float_0 + %16866 = OpVectorShuffle %v2uint %11216 %11216 0 1 + %14183 = OpBitcast %v2float %16866 + %7050 = OpCompositeExtract %float %14183 0 + %13429 = OpCompositeExtract %float %14183 1 + %17043 = OpCompositeConstruct %v4float %7050 %13429 %float_0 %float_0 + %16867 = OpVectorShuffle %v2uint %11216 %11216 2 3 + %14184 = OpBitcast %v2float %16867 + %7051 = OpCompositeExtract %float %14184 0 + %16651 = OpCompositeExtract %float %14184 1 + %9052 = OpCompositeConstruct %v4float %7051 %16651 %float_0 %float_0 + OpBranch %20266 + %20266 = OpLabel + %11185 = OpPhi %v4float %9052 %20313 %17253 %8539 %9051 %8250 + %14354 = OpPhi %v4float %17043 %20313 %25244 %8539 %14627 %8250 + %15244 = OpPhi %v4float %17042 %20313 %25243 %8539 %14626 %8250 + %14525 = OpPhi %v4float %17041 %20313 %25242 %8539 %14625 %8250 + OpBranch %21266 + %21266 = OpLabel + %11186 = OpPhi %v4float %11185 %20266 %11184 %16227 + %14355 = OpPhi %v4float %14354 %20266 %14353 %16227 + %12951 = OpPhi %v4float %15244 %20266 %15241 %16227 + %13948 = OpPhi %v4float %14525 %20266 %14524 %16227 + %17243 = OpFAdd %v4float %17242 %13948 + %23299 = OpFAdd %v4float %23298 %12951 + %9507 = OpFAdd %v4float %7208 %14355 + %7799 = OpFAdd %v4float %9642 %11186 + OpBranch %24264 + %24264 = OpLabel + %11187 = OpPhi %v4float %20755 %21264 %7799 %21266 + %14356 = OpPhi %v4float %8082 %21264 %9507 %21266 + %15153 = OpPhi %v4float %23297 %21264 %23299 %21266 + %15245 = OpPhi %v4float %17241 %21264 %17243 %21266 + %14526 = OpPhi %float %23069 %21264 %12090 %21266 + OpBranch %21267 + %21267 = OpLabel + %11188 = OpPhi %v4float %11177 %21263 %11187 %24264 + %14357 = OpPhi %v4float %14346 %21263 %14356 %24264 + %15154 = OpPhi %v4float %13804 %21263 %15153 %24264 + %13196 = OpPhi %v4float %8403 %21263 %15245 %24264 + %11944 = OpPhi %float %11052 %21263 %14526 %24264 + %23156 = OpVectorTimesScalar %v4float %13196 %11944 + %6604 = OpVectorTimesScalar %v4float %15154 %11944 + %12399 = OpVectorTimesScalar %v4float %14357 %11944 + %13362 = OpVectorTimesScalar %v4float %11188 %11944 + OpSelectionMerge %16228 DontFlatten + OpBranchConditional %7513 %10049 %16228 + %10049 = OpLabel + %15086 = OpVectorShuffle %v4float %23156 %23156 2 1 0 3 + %14855 = OpVectorShuffle %v4float %6604 %6604 2 1 0 3 + %7398 = OpVectorShuffle %v4float %12399 %12399 2 1 0 3 + %16111 = OpVectorShuffle %v4float %13362 %13362 2 1 0 3 + OpBranch %16228 + %16228 = OpLabel + %11189 = OpPhi %v4float %13362 %21267 %16111 %10049 + %14358 = OpPhi %v4float %12399 %21267 %7398 %10049 + %15191 = OpPhi %v4float %6604 %21267 %14855 %10049 + %14921 = OpPhi %v4float %23156 %21267 %15086 %10049 + OpSelectionMerge %18834 None + OpSwitch %20627 %7374 3 %17899 4 %6452 5 %6451 10 %7373 15 %12647 24 %9492 + %9492 = OpLabel + %15041 = OpCompositeExtract %float %14921 0 + %10277 = OpCompositeExtract %float %15191 0 + %7641 = OpCompositeExtract %float %14358 0 + %6565 = OpCompositeExtract %float %11189 0 + %7479 = OpCompositeConstruct %v4float %15041 %10277 %7641 %6565 + %14406 = OpExtInst %v4float %1 FClamp %7479 %2938 %1285 + %13687 = OpVectorTimesScalar %v4float %14406 %float_65535 + %11840 = OpFAdd %v4float %13687 %325 + %7947 = OpConvertFToU %v4uint %11840 + %6361 = OpVectorShuffle %v2uint %7947 %7947 0 2 + %10064 = OpVectorShuffle %v2uint %7947 %7947 1 3 + %13638 = OpShiftLeftLogical %v2uint %10064 %2151 + %15653 = OpBitwiseOr %v2uint %6361 %13638 + OpBranch %18834 + %12647 = OpLabel + %7311 = OpExtInst %v4float %1 FClamp %14921 %2938 %1285 + %20339 = OpVectorTimesScalar %v4float %7311 %float_15 + %11878 = OpFAdd %v4float %20339 %325 + %7639 = OpConvertFToU %v4uint %11878 + %8700 = OpCompositeExtract %uint %7639 0 + %12251 = OpCompositeExtract %uint %7639 1 + %11561 = OpShiftLeftLogical %uint %12251 %int_4 + %19814 = OpBitwiseOr %uint %8700 %11561 + %21476 = OpCompositeExtract %uint %7639 2 + %8560 = OpShiftLeftLogical %uint %21476 %int_8 + %19815 = OpBitwiseOr %uint %19814 %8560 + %21477 = OpCompositeExtract %uint %7639 3 + %7292 = OpShiftLeftLogical %uint %21477 %int_12 + %9255 = OpBitwiseOr %uint %19815 %7292 + %7522 = OpExtInst %v4float %1 FClamp %15191 %2938 %1285 + %8264 = OpVectorTimesScalar %v4float %7522 %float_15 + %11879 = OpFAdd %v4float %8264 %325 + %7642 = OpConvertFToU %v4uint %11879 + %8701 = OpCompositeExtract %uint %7642 0 + %12252 = OpCompositeExtract %uint %7642 1 + %11562 = OpShiftLeftLogical %uint %12252 %int_4 + %19816 = OpBitwiseOr %uint %8701 %11562 + %21478 = OpCompositeExtract %uint %7642 2 + %8561 = OpShiftLeftLogical %uint %21478 %int_8 + %19817 = OpBitwiseOr %uint %19816 %8561 + %21479 = OpCompositeExtract %uint %7642 3 + %10745 = OpShiftLeftLogical %uint %21479 %int_12 + %19009 = OpBitwiseOr %uint %19817 %10745 + %22729 = OpShiftLeftLogical %uint %19009 %uint_16 + %6254 = OpBitwiseOr %uint %9255 %22729 + %7523 = OpExtInst %v4float %1 FClamp %14358 %2938 %1285 + %8265 = OpVectorTimesScalar %v4float %7523 %float_15 + %11881 = OpFAdd %v4float %8265 %325 + %7643 = OpConvertFToU %v4uint %11881 + %8702 = OpCompositeExtract %uint %7643 0 + %12253 = OpCompositeExtract %uint %7643 1 + %11563 = OpShiftLeftLogical %uint %12253 %int_4 + %19818 = OpBitwiseOr %uint %8702 %11563 + %21480 = OpCompositeExtract %uint %7643 2 + %8562 = OpShiftLeftLogical %uint %21480 %int_8 + %19819 = OpBitwiseOr %uint %19818 %8562 + %21481 = OpCompositeExtract %uint %7643 3 + %7293 = OpShiftLeftLogical %uint %21481 %int_12 + %9256 = OpBitwiseOr %uint %19819 %7293 + %7524 = OpExtInst %v4float %1 FClamp %11189 %2938 %1285 + %8266 = OpVectorTimesScalar %v4float %7524 %float_15 + %11882 = OpFAdd %v4float %8266 %325 + %7644 = OpConvertFToU %v4uint %11882 + %8703 = OpCompositeExtract %uint %7644 0 + %12254 = OpCompositeExtract %uint %7644 1 + %11564 = OpShiftLeftLogical %uint %12254 %int_4 + %19820 = OpBitwiseOr %uint %8703 %11564 + %21482 = OpCompositeExtract %uint %7644 2 + %8563 = OpShiftLeftLogical %uint %21482 %int_8 + %19821 = OpBitwiseOr %uint %19820 %8563 + %21483 = OpCompositeExtract %uint %7644 3 + %10746 = OpShiftLeftLogical %uint %21483 %int_12 + %19010 = OpBitwiseOr %uint %19821 %10746 + %23978 = OpShiftLeftLogical %uint %19010 %uint_16 + %17993 = OpBitwiseOr %uint %9256 %23978 + %21469 = OpCompositeConstruct %v2uint %6254 %17993 + OpBranch %18834 + %7373 = OpLabel + %19885 = OpCompositeExtract %float %14921 0 + %10278 = OpCompositeExtract %float %14921 1 + %7645 = OpCompositeExtract %float %15191 0 + %6566 = OpCompositeExtract %float %15191 1 + %7480 = OpCompositeConstruct %v4float %19885 %10278 %7645 %6566 + %14407 = OpExtInst %v4float %1 FClamp %7480 %2938 %1285 + %13688 = OpVectorTimesScalar %v4float %14407 %float_255 + %11883 = OpFAdd %v4float %13688 %325 + %7646 = OpConvertFToU %v4uint %11883 + %8704 = OpCompositeExtract %uint %7646 0 + %12255 = OpCompositeExtract %uint %7646 1 + %11565 = OpShiftLeftLogical %uint %12255 %int_8 + %19822 = OpBitwiseOr %uint %8704 %11565 + %21484 = OpCompositeExtract %uint %7646 2 + %8564 = OpShiftLeftLogical %uint %21484 %int_16 + %19823 = OpBitwiseOr %uint %19822 %8564 + %21485 = OpCompositeExtract %uint %7646 3 + %8565 = OpShiftLeftLogical %uint %21485 %int_24 + %17629 = OpBitwiseOr %uint %19823 %8565 + %20096 = OpCompositeExtract %float %14358 0 + %23730 = OpCompositeExtract %float %14358 1 + %7647 = OpCompositeExtract %float %11189 0 + %6567 = OpCompositeExtract %float %11189 1 + %7481 = OpCompositeConstruct %v4float %20096 %23730 %7647 %6567 + %14408 = OpExtInst %v4float %1 FClamp %7481 %2938 %1285 + %13689 = OpVectorTimesScalar %v4float %14408 %float_255 + %11884 = OpFAdd %v4float %13689 %325 + %7648 = OpConvertFToU %v4uint %11884 + %8705 = OpCompositeExtract %uint %7648 0 + %12256 = OpCompositeExtract %uint %7648 1 + %11566 = OpShiftLeftLogical %uint %12256 %int_8 + %19824 = OpBitwiseOr %uint %8705 %11566 + %21486 = OpCompositeExtract %uint %7648 2 + %8566 = OpShiftLeftLogical %uint %21486 %int_16 + %19825 = OpBitwiseOr %uint %19824 %8566 + %21487 = OpCompositeExtract %uint %7648 3 + %8541 = OpShiftLeftLogical %uint %21487 %int_24 + %20994 = OpBitwiseOr %uint %19825 %8541 + %21470 = OpCompositeConstruct %v2uint %17629 %20994 + OpBranch %18834 + %6451 = OpLabel + %8655 = OpVectorShuffle %v3float %14921 %14921 0 1 2 + %6215 = OpExtInst %v3float %1 FClamp %8655 %2605 %2584 + %7105 = OpFMul %v3float %6215 %958 + %7962 = OpFAdd %v3float %7105 %939 + %10066 = OpConvertFToU %v3uint %7962 + %8706 = OpCompositeExtract %uint %10066 0 + %12257 = OpCompositeExtract %uint %10066 1 + %11567 = OpShiftLeftLogical %uint %12257 %int_5 + %19826 = OpBitwiseOr %uint %8706 %11567 + %21488 = OpCompositeExtract %uint %10066 2 + %8522 = OpShiftLeftLogical %uint %21488 %int_10 + %16707 = OpBitwiseOr %uint %19826 %8522 + %8866 = OpVectorShuffle %v3float %15191 %15191 0 1 2 + %19668 = OpExtInst %v3float %1 FClamp %8866 %2605 %2584 + %7106 = OpFMul %v3float %19668 %958 + %7963 = OpFAdd %v3float %7106 %939 + %10067 = OpConvertFToU %v3uint %7963 + %8707 = OpCompositeExtract %uint %10067 0 + %12258 = OpCompositeExtract %uint %10067 1 + %11568 = OpShiftLeftLogical %uint %12258 %int_5 + %19827 = OpBitwiseOr %uint %8707 %11568 + %21489 = OpCompositeExtract %uint %10067 2 + %10747 = OpShiftLeftLogical %uint %21489 %int_10 + %19011 = OpBitwiseOr %uint %19827 %10747 + %23959 = OpShiftLeftLogical %uint %19011 %uint_16 + %13706 = OpBitwiseOr %uint %16707 %23959 + %8867 = OpVectorShuffle %v3float %14358 %14358 0 1 2 + %19669 = OpExtInst %v3float %1 FClamp %8867 %2605 %2584 + %7107 = OpFMul %v3float %19669 %958 + %7964 = OpFAdd %v3float %7107 %939 + %10068 = OpConvertFToU %v3uint %7964 + %8708 = OpCompositeExtract %uint %10068 0 + %12259 = OpCompositeExtract %uint %10068 1 + %11569 = OpShiftLeftLogical %uint %12259 %int_5 + %19828 = OpBitwiseOr %uint %8708 %11569 + %21490 = OpCompositeExtract %uint %10068 2 + %8523 = OpShiftLeftLogical %uint %21490 %int_10 + %16708 = OpBitwiseOr %uint %19828 %8523 + %8868 = OpVectorShuffle %v3float %11189 %11189 0 1 2 + %19675 = OpExtInst %v3float %1 FClamp %8868 %2605 %2584 + %7108 = OpFMul %v3float %19675 %958 + %7965 = OpFAdd %v3float %7108 %939 + %10069 = OpConvertFToU %v3uint %7965 + %8709 = OpCompositeExtract %uint %10069 0 + %12260 = OpCompositeExtract %uint %10069 1 + %11570 = OpShiftLeftLogical %uint %12260 %int_5 + %19829 = OpBitwiseOr %uint %8709 %11570 + %21491 = OpCompositeExtract %uint %10069 2 + %10748 = OpShiftLeftLogical %uint %21491 %int_10 + %19012 = OpBitwiseOr %uint %19829 %10748 + %23979 = OpShiftLeftLogical %uint %19012 %uint_16 + %17994 = OpBitwiseOr %uint %16708 %23979 + %21471 = OpCompositeConstruct %v2uint %13706 %17994 + OpBranch %18834 + %6452 = OpLabel + %8656 = OpVectorShuffle %v3float %14921 %14921 0 1 2 + %6216 = OpExtInst %v3float %1 FClamp %8656 %2605 %2584 + %7109 = OpFMul %v3float %6216 %511 + %7966 = OpFAdd %v3float %7109 %939 + %10070 = OpConvertFToU %v3uint %7966 + %8710 = OpCompositeExtract %uint %10070 0 + %12261 = OpCompositeExtract %uint %10070 1 + %11571 = OpShiftLeftLogical %uint %12261 %int_5 + %19830 = OpBitwiseOr %uint %8710 %11571 + %21492 = OpCompositeExtract %uint %10070 2 + %8524 = OpShiftLeftLogical %uint %21492 %int_11 + %16709 = OpBitwiseOr %uint %19830 %8524 + %8869 = OpVectorShuffle %v3float %15191 %15191 0 1 2 + %19676 = OpExtInst %v3float %1 FClamp %8869 %2605 %2584 + %7110 = OpFMul %v3float %19676 %511 + %7967 = OpFAdd %v3float %7110 %939 + %10071 = OpConvertFToU %v3uint %7967 + %8711 = OpCompositeExtract %uint %10071 0 + %12262 = OpCompositeExtract %uint %10071 1 + %11572 = OpShiftLeftLogical %uint %12262 %int_5 + %19831 = OpBitwiseOr %uint %8711 %11572 + %21493 = OpCompositeExtract %uint %10071 2 + %10749 = OpShiftLeftLogical %uint %21493 %int_11 + %19013 = OpBitwiseOr %uint %19831 %10749 + %23960 = OpShiftLeftLogical %uint %19013 %uint_16 + %13707 = OpBitwiseOr %uint %16709 %23960 + %8870 = OpVectorShuffle %v3float %14358 %14358 0 1 2 + %19677 = OpExtInst %v3float %1 FClamp %8870 %2605 %2584 + %7111 = OpFMul %v3float %19677 %511 + %7968 = OpFAdd %v3float %7111 %939 + %10072 = OpConvertFToU %v3uint %7968 + %8712 = OpCompositeExtract %uint %10072 0 + %12263 = OpCompositeExtract %uint %10072 1 + %11573 = OpShiftLeftLogical %uint %12263 %int_5 + %19832 = OpBitwiseOr %uint %8712 %11573 + %21494 = OpCompositeExtract %uint %10072 2 + %8525 = OpShiftLeftLogical %uint %21494 %int_11 + %16710 = OpBitwiseOr %uint %19832 %8525 + %8872 = OpVectorShuffle %v3float %11189 %11189 0 1 2 + %19678 = OpExtInst %v3float %1 FClamp %8872 %2605 %2584 + %7112 = OpFMul %v3float %19678 %511 + %7969 = OpFAdd %v3float %7112 %939 + %10073 = OpConvertFToU %v3uint %7969 + %8713 = OpCompositeExtract %uint %10073 0 + %12264 = OpCompositeExtract %uint %10073 1 + %11574 = OpShiftLeftLogical %uint %12264 %int_5 + %19833 = OpBitwiseOr %uint %8713 %11574 + %21495 = OpCompositeExtract %uint %10073 2 + %10750 = OpShiftLeftLogical %uint %21495 %int_11 + %19014 = OpBitwiseOr %uint %19833 %10750 + %23980 = OpShiftLeftLogical %uint %19014 %uint_16 + %17995 = OpBitwiseOr %uint %16710 %23980 + %21472 = OpCompositeConstruct %v2uint %13707 %17995 + OpBranch %18834 + %17899 = OpLabel + %8873 = OpExtInst %v4float %1 FClamp %14921 %2938 %1285 + %17792 = OpFMul %v4float %8873 %2057 + %7970 = OpFAdd %v4float %17792 %325 + %10074 = OpConvertFToU %v4uint %7970 + %8714 = OpCompositeExtract %uint %10074 0 + %12265 = OpCompositeExtract %uint %10074 1 + %11575 = OpShiftLeftLogical %uint %12265 %int_5 + %19834 = OpBitwiseOr %uint %8714 %11575 + %21496 = OpCompositeExtract %uint %10074 2 + %8567 = OpShiftLeftLogical %uint %21496 %int_10 + %19835 = OpBitwiseOr %uint %19834 %8567 + %21497 = OpCompositeExtract %uint %10074 3 + %7294 = OpShiftLeftLogical %uint %21497 %int_15 + %9084 = OpBitwiseOr %uint %19835 %7294 + %9079 = OpExtInst %v4float %1 FClamp %15191 %2938 %1285 + %24798 = OpFMul %v4float %9079 %2057 + %7971 = OpFAdd %v4float %24798 %325 + %10075 = OpConvertFToU %v4uint %7971 + %8715 = OpCompositeExtract %uint %10075 0 + %12266 = OpCompositeExtract %uint %10075 1 + %11576 = OpShiftLeftLogical %uint %12266 %int_5 + %19836 = OpBitwiseOr %uint %8715 %11576 + %21498 = OpCompositeExtract %uint %10075 2 + %8568 = OpShiftLeftLogical %uint %21498 %int_10 + %19837 = OpBitwiseOr %uint %19836 %8568 + %21499 = OpCompositeExtract %uint %10075 3 + %10751 = OpShiftLeftLogical %uint %21499 %int_15 + %19015 = OpBitwiseOr %uint %19837 %10751 + %22730 = OpShiftLeftLogical %uint %19015 %uint_16 + %25154 = OpBitwiseOr %uint %9084 %22730 + %9080 = OpExtInst %v4float %1 FClamp %14358 %2938 %1285 + %24799 = OpFMul %v4float %9080 %2057 + %7972 = OpFAdd %v4float %24799 %325 + %10076 = OpConvertFToU %v4uint %7972 + %8716 = OpCompositeExtract %uint %10076 0 + %12267 = OpCompositeExtract %uint %10076 1 + %11577 = OpShiftLeftLogical %uint %12267 %int_5 + %19838 = OpBitwiseOr %uint %8716 %11577 + %21500 = OpCompositeExtract %uint %10076 2 + %8569 = OpShiftLeftLogical %uint %21500 %int_10 + %19839 = OpBitwiseOr %uint %19838 %8569 + %21501 = OpCompositeExtract %uint %10076 3 + %7295 = OpShiftLeftLogical %uint %21501 %int_15 + %9085 = OpBitwiseOr %uint %19839 %7295 + %9081 = OpExtInst %v4float %1 FClamp %11189 %2938 %1285 + %24800 = OpFMul %v4float %9081 %2057 + %7973 = OpFAdd %v4float %24800 %325 + %10077 = OpConvertFToU %v4uint %7973 + %8717 = OpCompositeExtract %uint %10077 0 + %12268 = OpCompositeExtract %uint %10077 1 + %11578 = OpShiftLeftLogical %uint %12268 %int_5 + %19840 = OpBitwiseOr %uint %8717 %11578 + %21502 = OpCompositeExtract %uint %10077 2 + %8570 = OpShiftLeftLogical %uint %21502 %int_10 + %19841 = OpBitwiseOr %uint %19840 %8570 + %21503 = OpCompositeExtract %uint %10077 3 + %10752 = OpShiftLeftLogical %uint %21503 %int_15 + %19016 = OpBitwiseOr %uint %19841 %10752 + %23981 = OpShiftLeftLogical %uint %19016 %uint_16 + %17996 = OpBitwiseOr %uint %9085 %23981 + %21473 = OpCompositeConstruct %v2uint %25154 %17996 + OpBranch %18834 + %7374 = OpLabel + %19866 = OpCompositeExtract %float %14921 0 + %9197 = OpCompositeExtract %float %15191 0 + %19232 = OpCompositeConstruct %v2float %19866 %9197 + %8571 = OpExtInst %uint %1 PackHalf2x16 %19232 + %23487 = OpCompositeExtract %float %14358 0 + %14759 = OpCompositeExtract %float %11189 0 + %19213 = OpCompositeConstruct %v2float %23487 %14759 + %11926 = OpExtInst %uint %1 PackHalf2x16 %19213 + %24879 = OpCompositeConstruct %v2uint %8571 %11926 + OpBranch %18834 + %18834 = OpLabel + %24188 = OpPhi %v2uint %24879 %7374 %21473 %17899 %21472 %6452 %21471 %6451 %21470 %7373 %21469 %12647 %15653 %9492 + %24753 = OpIEqual %bool %7640 %uint_0 + OpSelectionMerge %13276 None + OpBranchConditional %24753 %11451 %13276 + %11451 = OpLabel + %24167 = OpCompositeExtract %uint %19124 0 + %22470 = OpINotEqual %bool %24167 %uint_0 + OpBranch %13276 + %13276 = OpLabel + %10955 = OpPhi %bool %24753 %18834 %22470 %11451 + OpSelectionMerge %19649 DontFlatten + OpBranchConditional %10955 %11508 %19649 + %11508 = OpLabel + %23599 = OpCompositeExtract %uint %19124 0 + %17346 = OpUGreaterThanEqual %bool %23599 %uint_2 + OpSelectionMerge %18757 None + OpBranchConditional %17346 %15877 %18757 + %15877 = OpLabel + %24532 = OpUGreaterThanEqual %bool %23599 %uint_3 + OpSelectionMerge %18756 None + OpBranchConditional %24532 %11888 %18756 + %11888 = OpLabel + %19227 = OpCompositeExtract %uint %24188 1 + %13351 = OpShiftRightLogical %uint %19227 %uint_16 + %7220 = OpBitwiseAnd %uint %19227 %uint_4294901760 + %17709 = OpBitwiseOr %uint %13351 %7220 + %23345 = OpCompositeInsert %v2uint %17709 %24188 1 + OpBranch %18756 + %18756 = OpLabel + %19602 = OpPhi %v2uint %24188 %15877 %23345 %11888 + %21711 = OpCompositeExtract %uint %19602 0 + %12661 = OpBitwiseAnd %uint %21711 %uint_65535 + %21557 = OpCompositeExtract %uint %19602 1 + %10192 = OpShiftLeftLogical %uint %21557 %uint_16 + %20648 = OpBitwiseOr %uint %12661 %10192 + %24154 = OpCompositeInsert %v2uint %20648 %19602 0 + OpBranch %18757 + %18757 = OpLabel + %19507 = OpPhi %v2uint %24188 %11508 %24154 %18756 + %24818 = OpCompositeExtract %uint %19507 0 + %14160 = OpShiftRightLogical %uint %24818 %uint_16 + %7221 = OpBitwiseAnd %uint %24818 %uint_4294901760 + %17710 = OpBitwiseOr %uint %14160 %7221 + %23346 = OpCompositeInsert %v2uint %17710 %19507 0 + OpBranch %19649 + %19649 = OpLabel + %9229 = OpPhi %v2uint %24188 %13276 %23346 %18757 + %19403 = OpIAdd %v2uint %12025 %23020 + %13244 = OpCompositeExtract %uint %19403 0 + %9555 = OpCompositeExtract %uint %19403 1 + %11053 = OpShiftRightLogical %uint %13244 %uint_3 + %7832 = OpCompositeConstruct %v2uint %11053 %9555 + %24920 = OpUDiv %v2uint %7832 %23601 + %13932 = OpCompositeExtract %uint %24920 0 + %19770 = OpShiftLeftLogical %uint %13932 %uint_3 + %24251 = OpCompositeExtract %uint %24920 1 + %21459 = OpCompositeConstruct %v3uint %19770 %24251 %24434 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %20495 %22217 %10956 + %10956 = OpLabel + %7339 = OpVectorShuffle %v2uint %21459 %21459 0 1 + %22991 = OpBitcast %v2int %7339 + %6431 = OpCompositeExtract %int %22991 0 + %9469 = OpShiftRightArithmetic %int %6431 %int_5 + %10055 = OpCompositeExtract %int %22991 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %15783 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_8 + %10957 = OpBitwiseAnd %int %6431 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17303 = OpIAdd %int %10957 %17741 + %6375 = OpShiftLeftLogical %int %17303 %uint_1 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15435 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18366 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18366 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12151 + %19171 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19171 %int_2 + %16711 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6431 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21588 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21588 %int_6 + %15436 = OpIAdd %int %16711 %21580 + %11782 = OpBitwiseAnd %int %16727 %int_63 + %14671 = OpIAdd %int %15436 %11782 + %22127 = OpBitcast %uint %14671 + OpBranch %21313 + %22217 = OpLabel + %6573 = OpBitcast %v3int %21459 + %17090 = OpCompositeExtract %int %6573 1 + %9470 = OpShiftRightArithmetic %int %17090 %int_4 + %10056 = OpCompositeExtract %int %6573 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %25203 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %15783 %uint_5 + %12439 = OpBitcast %int %9032 + %10367 = OpIMul %int %15143 %12439 + %25155 = OpCompositeExtract %int %6573 0 + %20423 = OpShiftRightArithmetic %int %25155 %int_5 + %18940 = OpIAdd %int %20423 %10367 + %8797 = OpShiftLeftLogical %int %18940 %uint_7 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25155 %int_7 + %12601 = OpBitwiseAnd %int %17090 %int_6 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7052 = OpShiftLeftLogical %int %17227 %uint_7 + %24035 = OpShiftRightArithmetic %int %7052 %int_6 + %8736 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8736 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25155 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19172 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19172 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23347 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23347 %23274 + %18367 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18367 %uint_7 + %16729 = OpIAdd %int %10332 %21582 + %19173 = OpBitwiseAnd %int %17090 %int_1 + %21583 = OpShiftLeftLogical %int %19173 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23348 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10958 = OpIAdd %int %23348 %23217 + %23349 = OpShiftLeftLogical %int %10958 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10959 = OpIAdd %int %23349 %23218 + %23350 = OpShiftLeftLogical %int %10959 %int_3 + %21849 = OpBitwiseAnd %int %16730 %int_63 + %24314 = OpIAdd %int %23350 %21849 + %22128 = OpBitcast %uint %24314 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22128 %22217 %22127 %10956 + %16310 = OpIMul %v2uint %24920 %23601 + %16261 = OpISub %v2uint %7832 %16310 + %17551 = OpCompositeExtract %uint %23601 1 + %23632 = OpIMul %uint %8858 %17551 + %15520 = OpIMul %uint %9468 %23632 + %16084 = OpCompositeExtract %uint %16261 0 + %15890 = OpIMul %uint %16084 %17551 + %6887 = OpCompositeExtract %uint %16261 1 + %11045 = OpIAdd %uint %15890 %6887 + %24733 = OpShiftLeftLogical %uint %11045 %uint_3 + %23219 = OpBitwiseAnd %uint %13244 %uint_7 + %9559 = OpIAdd %uint %24733 %23219 + %17811 = OpShiftLeftLogical %uint %9559 %uint_1 + %8267 = OpIAdd %uint %15520 %17811 + %9676 = OpShiftRightLogical %uint %8267 %uint_3 + %19356 = OpIEqual %bool %19164 %uint_1 + OpSelectionMerge %11416 None + OpBranchConditional %19356 %10583 %11416 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v2uint %9229 %2326 + %9425 = OpShiftLeftLogical %v2uint %18271 %1975 + %20652 = OpBitwiseAnd %v2uint %9229 %2888 + %17549 = OpShiftRightLogical %v2uint %20652 %1975 + %16377 = OpBitwiseOr %v2uint %9425 %17549 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v2uint %9229 %21313 %16377 %10583 + %8053 = OpAccessChain %_ptr_Uniform_v2uint %5522 %int_0 %9676 + OpStore %8053 %19767 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_full_16bpp_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x0000629D, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00040047, 0x000007D0, 0x00000006, 0x00000004, + 0x00030047, 0x0000079C, 0x00000003, 0x00040048, 0x0000079C, 0x00000000, 0x00000018, 0x00050048, + 0x0000079C, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000CC7, 0x00000018, 0x00040047, + 0x00000CC7, 0x00000021, 0x00000000, 0x00040047, 0x00000CC7, 0x00000022, 0x00000000, 0x00030047, + 0x000003F9, 0x00000002, 0x00050048, 0x000003F9, 0x00000000, 0x00000023, 0x00000000, 0x00050048, + 0x000003F9, 0x00000001, 0x00000023, 0x00000004, 0x00050048, 0x000003F9, 0x00000002, 0x00000023, + 0x00000008, 0x00050048, 0x000003F9, 0x00000003, 0x00000023, 0x0000000C, 0x00040047, 0x00000F48, + 0x0000000B, 0x0000001C, 0x00040047, 0x000007D6, 0x00000006, 0x00000008, 0x00030047, 0x000007A8, + 0x00000003, 0x00040048, 0x000007A8, 0x00000000, 0x00000019, 0x00050048, 0x000007A8, 0x00000000, + 0x00000023, 0x00000000, 0x00030047, 0x00001592, 0x00000019, 0x00040047, 0x00001592, 0x00000021, + 0x00000000, 0x00040047, 0x00001592, 0x00000022, 0x00000001, 0x00040047, 0x00000AC9, 0x0000000B, + 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040015, 0x0000000B, + 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, + 0x0000000B, 0x00000003, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00030016, 0x0000000D, + 0x00000020, 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x00040017, 0x00000018, 0x0000000D, + 0x00000003, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x00020014, 0x00000009, 0x00040017, + 0x00000016, 0x0000000C, 0x00000003, 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, 0x0004002B, + 0x0000000D, 0x0000008A, 0x3F800000, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, + 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, + 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000D, 0x000005B1, 0x41F80000, 0x0007002C, + 0x0000001D, 0x00000809, 0x000005B1, 0x000005B1, 0x000005B1, 0x0000008A, 0x0004002B, 0x0000000D, + 0x000000FC, 0x3F000000, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000C, + 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000C, + 0x00000A29, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000C, + 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000D, 0x00000770, 0x427C0000, 0x0006002C, 0x00000018, + 0x000001FF, 0x000005B1, 0x00000770, 0x000005B1, 0x0004002B, 0x0000000C, 0x00000A2C, 0x0000000B, + 0x0006002C, 0x00000018, 0x000003BE, 0x000005B1, 0x000005B1, 0x00000770, 0x0004002B, 0x0000000D, + 0x00000540, 0x437F0000, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, + 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000A53, 0x00000018, 0x0004002B, 0x0000000D, + 0x000001C1, 0x41700000, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, + 0x00000A2F, 0x0000000C, 0x0004002B, 0x0000000D, 0x0000022D, 0x477FFF00, 0x0004002B, 0x0000000B, + 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A52, 0x00000018, 0x0007002C, 0x00000017, + 0x0000028D, 0x00000A0A, 0x00000A22, 0x00000A3A, 0x00000A52, 0x0004002B, 0x0000000B, 0x00000144, + 0x000000FF, 0x0004002B, 0x0000000D, 0x0000017A, 0x3B808081, 0x0004002B, 0x0000000B, 0x00000A28, + 0x0000000A, 0x0004002B, 0x0000000B, 0x00000A46, 0x00000014, 0x0004002B, 0x0000000B, 0x00000A64, + 0x0000001E, 0x0007002C, 0x00000017, 0x0000034D, 0x00000A0A, 0x00000A28, 0x00000A46, 0x00000A64, + 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, 0x0007002C, 0x00000017, 0x0000027B, 0x00000A44, + 0x00000A44, 0x00000A44, 0x00000A13, 0x0004002B, 0x0000000D, 0x000006FE, 0x3A802008, 0x0004002B, + 0x0000000D, 0x00000149, 0x3EAAAAAB, 0x0007002C, 0x0000001D, 0x00000AEE, 0x000006FE, 0x000006FE, + 0x000006FE, 0x00000149, 0x0006002C, 0x00000014, 0x00000BB4, 0x00000A0A, 0x00000A28, 0x00000A46, + 0x0004002B, 0x0000000B, 0x00000B87, 0x0000007F, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x00040017, 0x00000010, 0x00000009, 0x00000003, 0x0004002B, 0x0000000B, 0x00000B7E, 0x0000007C, + 0x0004002B, 0x0000000B, 0x00000A4F, 0x00000017, 0x0004002B, 0x0000000D, 0x00000341, 0xBF800000, + 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x0005002C, 0x00000012, 0x000007A7, 0x00000A3B, + 0x00000A0B, 0x0004002B, 0x0000000D, 0x000007FE, 0x3A800100, 0x00040017, 0x0000001A, 0x0000000C, + 0x00000004, 0x0007002C, 0x0000001A, 0x00000122, 0x00000A3B, 0x00000A0B, 0x00000A3B, 0x00000A0B, + 0x0005002C, 0x00000011, 0x0000072D, 0x00000A10, 0x00000A0D, 0x00040017, 0x0000000F, 0x00000009, + 0x00000002, 0x0005002C, 0x00000011, 0x0000070F, 0x00000A0A, 0x00000A0A, 0x0005002C, 0x00000011, + 0x00000724, 0x00000A0D, 0x00000A0D, 0x0005002C, 0x00000011, 0x00000718, 0x00000A0D, 0x00000A0A, + 0x0004002B, 0x0000000B, 0x00000AFA, 0x00000050, 0x0005002C, 0x00000011, 0x00000A9F, 0x00000AFA, + 0x00000A3A, 0x0004002B, 0x0000000B, 0x00000A84, 0x00000800, 0x0004002B, 0x0000000B, 0x00000A19, + 0x00000005, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, + 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, + 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x0000040B, + 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000388, + 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, + 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000B, 0x00000A1C, + 0x00000006, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, + 0xFFFFFFFE, 0x0003001D, 0x000007D0, 0x0000000B, 0x0003001E, 0x0000079C, 0x000007D0, 0x00040020, + 0x00000A1B, 0x00000002, 0x0000079C, 0x0004003B, 0x00000A1B, 0x00000CC7, 0x00000002, 0x00040020, + 0x00000288, 0x00000002, 0x0000000B, 0x0006001E, 0x000003F9, 0x0000000B, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00040020, 0x00000676, 0x00000009, 0x000003F9, 0x0004003B, 0x00000676, 0x00000CE9, + 0x00000009, 0x00040020, 0x00000289, 0x00000009, 0x0000000B, 0x0004002B, 0x0000000B, 0x00000A31, + 0x0000000D, 0x0004002B, 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A37, + 0x0000000F, 0x0004002B, 0x0000000B, 0x00000A5E, 0x0000001C, 0x0004002B, 0x0000000B, 0x00000A43, + 0x00000013, 0x0005002C, 0x00000011, 0x00000883, 0x00000A3A, 0x00000A43, 0x0004002B, 0x0000000B, + 0x00000510, 0x20000000, 0x0005002C, 0x00000011, 0x0000073F, 0x00000A0A, 0x00000A16, 0x0004002B, + 0x0000000B, 0x00000AC7, 0x0000003F, 0x0004002B, 0x0000000C, 0x00000A59, 0x0000001A, 0x0004002B, + 0x0000000C, 0x00000A50, 0x00000017, 0x0004002B, 0x0000000B, 0x00000926, 0x01000000, 0x0005002C, + 0x00000011, 0x000008E3, 0x00000A46, 0x00000A52, 0x00040020, 0x00000291, 0x00000001, 0x00000014, + 0x0004003B, 0x00000291, 0x00000F48, 0x00000001, 0x0005002C, 0x00000011, 0x00000721, 0x00000A10, + 0x00000A0A, 0x0004002B, 0x0000000B, 0x0000068D, 0xFFFF0000, 0x0004002B, 0x0000000B, 0x000001C2, + 0x0000FFFF, 0x0003001D, 0x000007D6, 0x00000011, 0x0003001E, 0x000007A8, 0x000007D6, 0x00040020, + 0x00000A25, 0x00000002, 0x000007A8, 0x0004003B, 0x00000A25, 0x00001592, 0x00000002, 0x00040020, + 0x0000028E, 0x00000002, 0x00000011, 0x0006002C, 0x00000014, 0x00000AC9, 0x00000A22, 0x00000A22, + 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0005002C, 0x00000011, + 0x000007A3, 0x00000A37, 0x00000A0D, 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, + 0x0005002C, 0x00000011, 0x0000084A, 0x00000A37, 0x00000A37, 0x0007002C, 0x0000001D, 0x00000504, + 0x00000341, 0x00000341, 0x00000341, 0x00000341, 0x0007002C, 0x0000001A, 0x00000302, 0x00000A3B, + 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x0007002C, 0x00000017, 0x0000064B, 0x00000144, 0x00000144, + 0x00000144, 0x00000144, 0x0006002C, 0x00000014, 0x00000105, 0x00000A44, 0x00000A44, 0x00000A44, + 0x0006002C, 0x00000014, 0x00000466, 0x00000B87, 0x00000B87, 0x00000B87, 0x0006002C, 0x00000014, + 0x00000B0C, 0x00000A1F, 0x00000A1F, 0x00000A1F, 0x0006002C, 0x00000014, 0x00000A12, 0x00000A0A, + 0x00000A0A, 0x00000A0A, 0x0006002C, 0x00000014, 0x000003FA, 0x00000B7E, 0x00000B7E, 0x00000B7E, + 0x0006002C, 0x00000014, 0x00000189, 0x00000A4F, 0x00000A4F, 0x00000A4F, 0x0006002C, 0x00000014, + 0x0000008D, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000013, 0x00000049, 0x00000341, + 0x00000341, 0x0005002C, 0x00000012, 0x00000867, 0x00000A3B, 0x00000A3B, 0x0007002C, 0x0000001D, + 0x00000B7A, 0x00000A0C, 0x00000A0C, 0x00000A0C, 0x00000A0C, 0x0007002C, 0x0000001D, 0x00000505, + 0x0000008A, 0x0000008A, 0x0000008A, 0x0000008A, 0x0007002C, 0x0000001D, 0x00000145, 0x000000FC, + 0x000000FC, 0x000000FC, 0x000000FC, 0x0006002C, 0x00000018, 0x00000A2D, 0x00000A0C, 0x00000A0C, + 0x00000A0C, 0x0006002C, 0x00000018, 0x00000A18, 0x0000008A, 0x0000008A, 0x0000008A, 0x0006002C, + 0x00000018, 0x000003AB, 0x000000FC, 0x000000FC, 0x000000FC, 0x0005002C, 0x00000011, 0x00000916, + 0x000008A6, 0x000008A6, 0x0005002C, 0x00000011, 0x000007B7, 0x00000A22, 0x00000A22, 0x0005002C, + 0x00000011, 0x00000B48, 0x000005FD, 0x000005FD, 0x0004002B, 0x0000000C, 0x00000089, 0x3F800000, + 0x0004002B, 0x0000000B, 0x000009F8, 0xFFFFFFFA, 0x0006002C, 0x00000014, 0x00000938, 0x000009F8, + 0x000009F8, 0x000009F8, 0x0004002B, 0x0000000D, 0x0000016E, 0x3E800000, 0x00050036, 0x00000008, + 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, + 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000289, 0x000056E5, + 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003D0B, 0x000056E5, 0x00050041, 0x00000289, + 0x000058AC, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005158, 0x000058AC, 0x000500C7, + 0x0000000B, 0x00005051, 0x00003D0B, 0x00000A44, 0x000500C2, 0x0000000B, 0x00004E0A, 0x00003D0B, + 0x00000A28, 0x000500C7, 0x0000000B, 0x0000217E, 0x00004E0A, 0x00000A13, 0x000500C2, 0x0000000B, + 0x0000520A, 0x00003D0B, 0x00000A31, 0x000500C7, 0x0000000B, 0x0000217F, 0x0000520A, 0x00000A81, + 0x000500C2, 0x0000000B, 0x0000520B, 0x00003D0B, 0x00000A52, 0x000500C7, 0x0000000B, 0x00002180, + 0x0000520B, 0x00000A37, 0x000500C2, 0x0000000B, 0x00004994, 0x00003D0B, 0x00000A5E, 0x000500C7, + 0x0000000B, 0x000023AA, 0x00004994, 0x00000A0D, 0x00050050, 0x00000011, 0x000022A7, 0x00005158, + 0x00005158, 0x000500C2, 0x00000011, 0x000025A1, 0x000022A7, 0x00000883, 0x000500C7, 0x00000011, + 0x00005C31, 0x000025A1, 0x000007A2, 0x000500C7, 0x0000000B, 0x00005DDE, 0x00003D0B, 0x00000510, + 0x000500AB, 0x00000009, 0x00003007, 0x00005DDE, 0x00000A0A, 0x000300F7, 0x00003954, 0x00000000, + 0x000400FA, 0x00003007, 0x00004163, 0x000055E8, 0x000200F8, 0x000055E8, 0x000200F9, 0x00003954, + 0x000200F8, 0x00004163, 0x000500C2, 0x00000011, 0x00003BAE, 0x00005C31, 0x00000724, 0x000200F9, + 0x00003954, 0x000200F8, 0x00003954, 0x000700F5, 0x00000011, 0x00004AB4, 0x00003BAE, 0x00004163, + 0x0000070F, 0x000055E8, 0x000500C2, 0x00000011, 0x00001B7E, 0x000022A7, 0x0000073F, 0x000500C7, + 0x00000011, 0x00002DF9, 0x00001B7E, 0x000007A3, 0x000500C4, 0x00000011, 0x00003F4F, 0x00002DF9, + 0x0000074E, 0x00050084, 0x00000011, 0x000059EB, 0x00003F4F, 0x00005C31, 0x000500C2, 0x0000000B, + 0x00003343, 0x00005158, 0x00000A19, 0x000500C7, 0x0000000B, 0x000039C1, 0x00003343, 0x00000A81, + 0x00050051, 0x0000000B, 0x0000229A, 0x00005C31, 0x00000000, 0x00050084, 0x0000000B, 0x000059D1, + 0x000039C1, 0x0000229A, 0x00050041, 0x00000289, 0x00004E44, 0x00000CE9, 0x00000A11, 0x0004003D, + 0x0000000B, 0x000048C4, 0x00004E44, 0x00050041, 0x00000289, 0x000058AD, 0x00000CE9, 0x00000A14, + 0x0004003D, 0x0000000B, 0x000051B7, 0x000058AD, 0x000500C7, 0x0000000B, 0x00004ADC, 0x000048C4, + 0x00000A1F, 0x000500C7, 0x0000000B, 0x000055EF, 0x000048C4, 0x00000A22, 0x000500AB, 0x00000009, + 0x0000500F, 0x000055EF, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00002843, 0x000048C4, 0x00000A16, + 0x000500C7, 0x0000000B, 0x00005F72, 0x00002843, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00004CD8, + 0x000048C4, 0x00000A1F, 0x000500C7, 0x0000000B, 0x00005093, 0x00004CD8, 0x00000AC7, 0x0004007C, + 0x0000000C, 0x00005988, 0x000048C4, 0x000500C4, 0x0000000C, 0x0000358F, 0x00005988, 0x00000A29, + 0x000500C3, 0x0000000C, 0x0000509C, 0x0000358F, 0x00000A59, 0x000500C4, 0x0000000C, 0x00004702, + 0x0000509C, 0x00000A50, 0x00050080, 0x0000000C, 0x00001D26, 0x00004702, 0x00000089, 0x0004007C, + 0x0000000D, 0x00002B2C, 0x00001D26, 0x000500C7, 0x0000000B, 0x00005879, 0x000048C4, 0x00000926, + 0x000500AB, 0x00000009, 0x00001D59, 0x00005879, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00001F43, + 0x000051B7, 0x00000A44, 0x000500C4, 0x0000000B, 0x00003DA7, 0x00001F43, 0x00000A19, 0x000500C2, + 0x0000000B, 0x0000583F, 0x000051B7, 0x00000A28, 0x000500C7, 0x0000000B, 0x00004BBE, 0x0000583F, + 0x00000A44, 0x000500C4, 0x0000000B, 0x00006273, 0x00004BBE, 0x00000A19, 0x00050050, 0x00000011, + 0x000028B6, 0x000051B7, 0x000051B7, 0x000500C2, 0x00000011, 0x00002891, 0x000028B6, 0x000008E3, + 0x000500C7, 0x00000011, 0x00005B53, 0x00002891, 0x0000084A, 0x000500C4, 0x00000011, 0x00003F50, + 0x00005B53, 0x0000074E, 0x00050084, 0x00000011, 0x000059EC, 0x00003F50, 0x00005C31, 0x000500C2, + 0x0000000B, 0x000031C7, 0x000051B7, 0x00000A5E, 0x000500C7, 0x0000000B, 0x00004356, 0x000031C7, + 0x00000A1F, 0x0004003D, 0x00000014, 0x000031C1, 0x00000F48, 0x0007004F, 0x00000011, 0x000038A4, + 0x000031C1, 0x000031C1, 0x00000000, 0x00000001, 0x000500C4, 0x00000011, 0x00002EF9, 0x000038A4, + 0x00000721, 0x00050051, 0x0000000B, 0x00001DD8, 0x00002EF9, 0x00000000, 0x000500C4, 0x0000000B, + 0x00002D8A, 0x000059D1, 0x00000A13, 0x000500AE, 0x00000009, 0x00003C13, 0x00001DD8, 0x00002D8A, + 0x000300F7, 0x000036C9, 0x00000002, 0x000400FA, 0x00003C13, 0x000055E9, 0x000036C9, 0x000200F8, + 0x000055E9, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000036C9, 0x00050051, 0x0000000B, 0x000048B7, + 0x00002EF9, 0x00000001, 0x00050051, 0x0000000B, 0x000041A3, 0x00004AB4, 0x00000001, 0x0007000C, + 0x0000000B, 0x00005F7E, 0x00000001, 0x00000029, 0x000048B7, 0x000041A3, 0x00050050, 0x00000011, + 0x000051EF, 0x00001DD8, 0x00005F7E, 0x00050080, 0x00000011, 0x0000522C, 0x000051EF, 0x000059EB, + 0x000500B2, 0x00000009, 0x00003ECB, 0x00004356, 0x00000A13, 0x000300F7, 0x00005CE0, 0x00000000, + 0x000400FA, 0x00003ECB, 0x00002AEE, 0x00003AEF, 0x000200F8, 0x00003AEF, 0x000500AA, 0x00000009, + 0x000034FE, 0x00004356, 0x00000A19, 0x000600A9, 0x0000000B, 0x000020F6, 0x000034FE, 0x00000A10, + 0x00000A0A, 0x000200F9, 0x00005CE0, 0x000200F8, 0x00002AEE, 0x000200F9, 0x00005CE0, 0x000200F8, + 0x00005CE0, 0x000700F5, 0x0000000B, 0x00004B64, 0x00004356, 0x00002AEE, 0x000020F6, 0x00003AEF, + 0x00050050, 0x00000011, 0x000041BE, 0x0000217E, 0x0000217E, 0x000500AE, 0x0000000F, 0x00002E19, + 0x000041BE, 0x0000072D, 0x000600A9, 0x00000011, 0x00004BB5, 0x00002E19, 0x00000724, 0x0000070F, + 0x000500C4, 0x00000011, 0x00002AEA, 0x0000522C, 0x00004BB5, 0x00050050, 0x00000011, 0x0000605D, + 0x00004B64, 0x00004B64, 0x000500C2, 0x00000011, 0x00002385, 0x0000605D, 0x00000718, 0x000500C7, + 0x00000011, 0x00003EC8, 0x00002385, 0x00000724, 0x00050080, 0x00000011, 0x000046BA, 0x00002AEA, + 0x00003EC8, 0x00050084, 0x00000011, 0x00005998, 0x00000A9F, 0x00005C31, 0x00050050, 0x00000011, + 0x00002C44, 0x000023AA, 0x00000A0A, 0x000500C2, 0x00000011, 0x000019AB, 0x00005998, 0x00002C44, + 0x00050086, 0x00000011, 0x000027A2, 0x000046BA, 0x000019AB, 0x00050051, 0x0000000B, 0x00004FA6, + 0x000027A2, 0x00000001, 0x00050084, 0x0000000B, 0x00002B26, 0x00004FA6, 0x00005051, 0x00050051, + 0x0000000B, 0x00006059, 0x000027A2, 0x00000000, 0x00050080, 0x0000000B, 0x00005420, 0x00002B26, + 0x00006059, 0x00050080, 0x0000000B, 0x00002226, 0x0000217F, 0x00005420, 0x00050084, 0x00000011, + 0x00005768, 0x000027A2, 0x000019AB, 0x00050082, 0x00000011, 0x000050EB, 0x000046BA, 0x00005768, + 0x00050051, 0x0000000B, 0x00001C87, 0x00005998, 0x00000000, 0x00050051, 0x0000000B, 0x00005962, + 0x00005998, 0x00000001, 0x00050084, 0x0000000B, 0x00003372, 0x00001C87, 0x00005962, 0x00050084, + 0x0000000B, 0x000038D7, 0x00002226, 0x00003372, 0x00050051, 0x0000000B, 0x00001A95, 0x000050EB, + 0x00000001, 0x00050051, 0x0000000B, 0x00005BE6, 0x000019AB, 0x00000000, 0x00050084, 0x0000000B, + 0x00005966, 0x00001A95, 0x00005BE6, 0x00050051, 0x0000000B, 0x00001AE6, 0x000050EB, 0x00000000, + 0x00050080, 0x0000000B, 0x000025E0, 0x00005966, 0x00001AE6, 0x000500C4, 0x0000000B, 0x00004665, + 0x000025E0, 0x000023AA, 0x00050080, 0x0000000B, 0x000047BB, 0x000038D7, 0x00004665, 0x00050084, + 0x0000000B, 0x000034C0, 0x00003372, 0x00000A84, 0x00050089, 0x0000000B, 0x0000628F, 0x000047BB, + 0x000034C0, 0x000500AE, 0x00000009, 0x00003FFB, 0x0000217E, 0x00000A10, 0x000600A9, 0x0000000B, + 0x0000609F, 0x00003FFB, 0x00000A0D, 0x00000A0A, 0x00050080, 0x0000000B, 0x00004E6A, 0x000023AA, + 0x0000609F, 0x000500C4, 0x0000000B, 0x0000199B, 0x00000A0D, 0x00004E6A, 0x000500AB, 0x00000009, + 0x00005AEF, 0x000023AA, 0x00000A0A, 0x000300F7, 0x0000530F, 0x00000002, 0x000400FA, 0x00005AEF, + 0x00003B65, 0x000040B9, 0x000200F8, 0x000040B9, 0x000500AA, 0x00000009, 0x00004ADA, 0x0000199B, + 0x00000A0D, 0x000300F7, 0x00004F49, 0x00000002, 0x000400FA, 0x00004ADA, 0x00002621, 0x00002F61, + 0x000200F8, 0x00002F61, 0x00060041, 0x00000288, 0x00004BCF, 0x00000CC7, 0x00000A0B, 0x0000628F, + 0x0004003D, 0x0000000B, 0x00005D43, 0x00004BCF, 0x00050080, 0x0000000B, 0x00002DA7, 0x0000628F, + 0x0000199B, 0x00060041, 0x00000288, 0x0000194B, 0x00000CC7, 0x00000A0B, 0x00002DA7, 0x0004003D, + 0x0000000B, 0x00005E5B, 0x0000194B, 0x00050084, 0x0000000B, 0x0000185A, 0x00000A10, 0x0000199B, + 0x00050080, 0x0000000B, 0x000020A1, 0x0000628F, 0x0000185A, 0x00060041, 0x00000288, 0x00003BCD, + 0x00000CC7, 0x00000A0B, 0x000020A1, 0x0004003D, 0x0000000B, 0x00005E5C, 0x00003BCD, 0x00050084, + 0x0000000B, 0x0000185B, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A2, 0x0000628F, + 0x0000185B, 0x00060041, 0x00000288, 0x000037F1, 0x00000CC7, 0x00000A0B, 0x000020A2, 0x0004003D, + 0x0000000B, 0x00003FFC, 0x000037F1, 0x00070050, 0x00000017, 0x0000512C, 0x00005D43, 0x00005E5B, + 0x00005E5C, 0x00003FFC, 0x000200F9, 0x00004F49, 0x000200F8, 0x00002621, 0x00060041, 0x00000288, + 0x00005545, 0x00000CC7, 0x00000A0B, 0x0000628F, 0x0004003D, 0x0000000B, 0x00005D44, 0x00005545, + 0x00050080, 0x0000000B, 0x00002DA8, 0x0000628F, 0x00000A0D, 0x00060041, 0x00000288, 0x000018FF, + 0x00000CC7, 0x00000A0B, 0x00002DA8, 0x0004003D, 0x0000000B, 0x00005C62, 0x000018FF, 0x00050080, + 0x0000000B, 0x00002DA9, 0x0000628F, 0x00000A10, 0x00060041, 0x00000288, 0x00001900, 0x00000CC7, + 0x00000A0B, 0x00002DA9, 0x0004003D, 0x0000000B, 0x00005C63, 0x00001900, 0x00050080, 0x0000000B, + 0x00002DAA, 0x0000628F, 0x00000A13, 0x00060041, 0x00000288, 0x00005FEE, 0x00000CC7, 0x00000A0B, + 0x00002DAA, 0x0004003D, 0x0000000B, 0x00003FFD, 0x00005FEE, 0x00070050, 0x00000017, 0x0000512D, + 0x00005D44, 0x00005C62, 0x00005C63, 0x00003FFD, 0x000200F9, 0x00004F49, 0x000200F8, 0x00004F49, + 0x000700F5, 0x00000017, 0x00002ABF, 0x0000512D, 0x00002621, 0x0000512C, 0x00002F61, 0x000300F7, + 0x00003F60, 0x00000000, 0x001300FB, 0x00002180, 0x00004BFB, 0x00000000, 0x000038F9, 0x00000001, + 0x000038F9, 0x00000002, 0x00001CBB, 0x0000000A, 0x00001CBB, 0x00000003, 0x00001CBA, 0x0000000C, + 0x00001CBA, 0x00000004, 0x00001FFE, 0x00000006, 0x00002033, 0x000200F8, 0x00002033, 0x00050051, + 0x0000000B, 0x00005F56, 0x00002ABF, 0x00000000, 0x0006000C, 0x00000013, 0x00006067, 0x00000001, + 0x0000003E, 0x00005F56, 0x00050051, 0x0000000D, 0x00002762, 0x00006067, 0x00000000, 0x00050051, + 0x0000000D, 0x00004446, 0x00006067, 0x00000001, 0x00070050, 0x0000001D, 0x0000390C, 0x00002762, + 0x00004446, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x0000437A, 0x00002ABF, 0x00000001, + 0x0006000C, 0x00000013, 0x0000466B, 0x00000001, 0x0000003E, 0x0000437A, 0x00050051, 0x0000000D, + 0x00002763, 0x0000466B, 0x00000000, 0x00050051, 0x0000000D, 0x00004447, 0x0000466B, 0x00000001, + 0x00070050, 0x0000001D, 0x0000390D, 0x00002763, 0x00004447, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x0000437B, 0x00002ABF, 0x00000002, 0x0006000C, 0x00000013, 0x0000466C, 0x00000001, + 0x0000003E, 0x0000437B, 0x00050051, 0x0000000D, 0x00002764, 0x0000466C, 0x00000000, 0x00050051, + 0x0000000D, 0x00004448, 0x0000466C, 0x00000001, 0x00070050, 0x0000001D, 0x0000390E, 0x00002764, + 0x00004448, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x0000437C, 0x00002ABF, 0x00000003, + 0x0006000C, 0x00000013, 0x0000466D, 0x00000001, 0x0000003E, 0x0000437C, 0x00050051, 0x0000000D, + 0x00002765, 0x0000466D, 0x00000000, 0x00050051, 0x0000000D, 0x000050BE, 0x0000466D, 0x00000001, + 0x00070050, 0x0000001D, 0x00002349, 0x00002765, 0x000050BE, 0x00000A0C, 0x00000A0C, 0x000200F9, + 0x00003F60, 0x000200F8, 0x00001FFE, 0x00050051, 0x0000000B, 0x0000308B, 0x00002ABF, 0x00000000, + 0x0004007C, 0x0000000C, 0x0000589D, 0x0000308B, 0x00050050, 0x00000012, 0x0000471A, 0x0000589D, + 0x0000589D, 0x000500C4, 0x00000012, 0x000047AD, 0x0000471A, 0x000007A7, 0x000500C3, 0x00000012, + 0x00003417, 0x000047AD, 0x00000867, 0x0004006F, 0x00000013, 0x00002A97, 0x00003417, 0x0005008E, + 0x00000013, 0x00004747, 0x00002A97, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E06, 0x00000001, + 0x00000028, 0x00000049, 0x00004747, 0x00050051, 0x0000000D, 0x00005F0A, 0x00005E06, 0x00000000, + 0x00050051, 0x0000000D, 0x00003CD4, 0x00005E06, 0x00000001, 0x00070050, 0x0000001D, 0x0000411E, + 0x00005F0A, 0x00003CD4, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C42, 0x00002ABF, + 0x00000001, 0x0004007C, 0x0000000C, 0x00003EA1, 0x00004C42, 0x00050050, 0x00000012, 0x0000471B, + 0x00003EA1, 0x00003EA1, 0x000500C4, 0x00000012, 0x000047AE, 0x0000471B, 0x000007A7, 0x000500C3, + 0x00000012, 0x00003418, 0x000047AE, 0x00000867, 0x0004006F, 0x00000013, 0x00002A98, 0x00003418, + 0x0005008E, 0x00000013, 0x00004748, 0x00002A98, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E07, + 0x00000001, 0x00000028, 0x00000049, 0x00004748, 0x00050051, 0x0000000D, 0x00005F0B, 0x00005E07, + 0x00000000, 0x00050051, 0x0000000D, 0x00003CD5, 0x00005E07, 0x00000001, 0x00070050, 0x0000001D, + 0x0000411F, 0x00005F0B, 0x00003CD5, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C43, + 0x00002ABF, 0x00000002, 0x0004007C, 0x0000000C, 0x00003EA2, 0x00004C43, 0x00050050, 0x00000012, + 0x0000471C, 0x00003EA2, 0x00003EA2, 0x000500C4, 0x00000012, 0x000047AF, 0x0000471C, 0x000007A7, + 0x000500C3, 0x00000012, 0x00003419, 0x000047AF, 0x00000867, 0x0004006F, 0x00000013, 0x00002A99, + 0x00003419, 0x0005008E, 0x00000013, 0x00004749, 0x00002A99, 0x000007FE, 0x0007000C, 0x00000013, + 0x00005E08, 0x00000001, 0x00000028, 0x00000049, 0x00004749, 0x00050051, 0x0000000D, 0x00005F0C, + 0x00005E08, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD6, 0x00005E08, 0x00000001, 0x00070050, + 0x0000001D, 0x00004120, 0x00005F0C, 0x00003CD6, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x00004C44, 0x00002ABF, 0x00000003, 0x0004007C, 0x0000000C, 0x00003EA3, 0x00004C44, 0x00050050, + 0x00000012, 0x0000471D, 0x00003EA3, 0x00003EA3, 0x000500C4, 0x00000012, 0x000047B0, 0x0000471D, + 0x000007A7, 0x000500C3, 0x00000012, 0x0000341A, 0x000047B0, 0x00000867, 0x0004006F, 0x00000013, + 0x00002A9A, 0x0000341A, 0x0005008E, 0x00000013, 0x0000474A, 0x00002A9A, 0x000007FE, 0x0007000C, + 0x00000013, 0x00005E09, 0x00000001, 0x00000028, 0x00000049, 0x0000474A, 0x00050051, 0x0000000D, + 0x00005F0D, 0x00005E09, 0x00000000, 0x00050051, 0x0000000D, 0x0000494C, 0x00005E09, 0x00000001, + 0x00070050, 0x0000001D, 0x0000234A, 0x00005F0D, 0x0000494C, 0x00000A0C, 0x00000A0C, 0x000200F9, + 0x00003F60, 0x000200F8, 0x00001CBA, 0x00050051, 0x0000000B, 0x000056BD, 0x00002ABF, 0x00000000, + 0x00060050, 0x00000014, 0x00004F0A, 0x000056BD, 0x000056BD, 0x000056BD, 0x000500C2, 0x00000014, + 0x00002B0D, 0x00004F0A, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DE6, 0x00002B0D, 0x00000105, + 0x000500C7, 0x00000014, 0x0000489C, 0x00005DE6, 0x00000466, 0x000500C2, 0x00000014, 0x00005B90, + 0x00005DE6, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040C9, 0x00005B90, 0x00000A12, 0x0006000C, + 0x00000016, 0x00002C4B, 0x00000001, 0x0000004B, 0x0000489C, 0x0004007C, 0x00000014, 0x00002A15, + 0x00002C4B, 0x00050082, 0x00000014, 0x0000187A, 0x00000B0C, 0x00002A15, 0x00050080, 0x00000014, + 0x00002210, 0x00002A15, 0x00000938, 0x000600A9, 0x00000014, 0x0000286F, 0x000040C9, 0x00002210, + 0x00005B90, 0x000500C4, 0x00000014, 0x00005AD4, 0x0000489C, 0x0000187A, 0x000500C7, 0x00000014, + 0x0000499A, 0x00005AD4, 0x00000466, 0x000600A9, 0x00000014, 0x00002A9D, 0x000040C9, 0x0000499A, + 0x0000489C, 0x00050080, 0x00000014, 0x00005FF9, 0x0000286F, 0x000003FA, 0x000500C4, 0x00000014, + 0x00004F7F, 0x00005FF9, 0x00000189, 0x000500C4, 0x00000014, 0x00003FA6, 0x00002A9D, 0x0000008D, + 0x000500C5, 0x00000014, 0x0000577C, 0x00004F7F, 0x00003FA6, 0x000500AA, 0x00000010, 0x00003600, + 0x00005DE6, 0x00000A12, 0x000600A9, 0x00000014, 0x00004242, 0x00003600, 0x00000A12, 0x0000577C, + 0x0004007C, 0x00000018, 0x000029CF, 0x00004242, 0x000500C2, 0x0000000B, 0x00004BA4, 0x000056BD, + 0x00000A64, 0x00040070, 0x0000000D, 0x0000480E, 0x00004BA4, 0x00050085, 0x0000000D, 0x00003E1F, + 0x0000480E, 0x00000149, 0x00050051, 0x0000000D, 0x000053C2, 0x000029CF, 0x00000000, 0x00050051, + 0x0000000D, 0x00002A55, 0x000029CF, 0x00000001, 0x00050051, 0x0000000D, 0x00001E99, 0x000029CF, + 0x00000002, 0x00070050, 0x0000001D, 0x00003DDA, 0x000053C2, 0x00002A55, 0x00001E99, 0x00003E1F, + 0x00050051, 0x0000000B, 0x000027F5, 0x00002ABF, 0x00000001, 0x00060050, 0x00000014, 0x0000350E, + 0x000027F5, 0x000027F5, 0x000027F5, 0x000500C2, 0x00000014, 0x00002B0E, 0x0000350E, 0x00000BB4, + 0x000500C7, 0x00000014, 0x00005DE7, 0x00002B0E, 0x00000105, 0x000500C7, 0x00000014, 0x0000489D, + 0x00005DE7, 0x00000466, 0x000500C2, 0x00000014, 0x00005B91, 0x00005DE7, 0x00000B0C, 0x000500AA, + 0x00000010, 0x000040CA, 0x00005B91, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4C, 0x00000001, + 0x0000004B, 0x0000489D, 0x0004007C, 0x00000014, 0x00002A16, 0x00002C4C, 0x00050082, 0x00000014, + 0x0000187B, 0x00000B0C, 0x00002A16, 0x00050080, 0x00000014, 0x00002211, 0x00002A16, 0x00000938, + 0x000600A9, 0x00000014, 0x00002870, 0x000040CA, 0x00002211, 0x00005B91, 0x000500C4, 0x00000014, + 0x00005AD5, 0x0000489D, 0x0000187B, 0x000500C7, 0x00000014, 0x0000499B, 0x00005AD5, 0x00000466, + 0x000600A9, 0x00000014, 0x00002A9E, 0x000040CA, 0x0000499B, 0x0000489D, 0x00050080, 0x00000014, + 0x00005FFA, 0x00002870, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F80, 0x00005FFA, 0x00000189, + 0x000500C4, 0x00000014, 0x00003FA7, 0x00002A9E, 0x0000008D, 0x000500C5, 0x00000014, 0x0000577D, + 0x00004F80, 0x00003FA7, 0x000500AA, 0x00000010, 0x00003601, 0x00005DE7, 0x00000A12, 0x000600A9, + 0x00000014, 0x00004243, 0x00003601, 0x00000A12, 0x0000577D, 0x0004007C, 0x00000018, 0x000029D0, + 0x00004243, 0x000500C2, 0x0000000B, 0x00004BA5, 0x000027F5, 0x00000A64, 0x00040070, 0x0000000D, + 0x0000480F, 0x00004BA5, 0x00050085, 0x0000000D, 0x00003E20, 0x0000480F, 0x00000149, 0x00050051, + 0x0000000D, 0x000053C3, 0x000029D0, 0x00000000, 0x00050051, 0x0000000D, 0x00002A56, 0x000029D0, + 0x00000001, 0x00050051, 0x0000000D, 0x00001E9A, 0x000029D0, 0x00000002, 0x00070050, 0x0000001D, + 0x00003DDB, 0x000053C3, 0x00002A56, 0x00001E9A, 0x00003E20, 0x00050051, 0x0000000B, 0x000027F6, + 0x00002ABF, 0x00000002, 0x00060050, 0x00000014, 0x0000350F, 0x000027F6, 0x000027F6, 0x000027F6, + 0x000500C2, 0x00000014, 0x00002B0F, 0x0000350F, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DE8, + 0x00002B0F, 0x00000105, 0x000500C7, 0x00000014, 0x0000489E, 0x00005DE8, 0x00000466, 0x000500C2, + 0x00000014, 0x00005B92, 0x00005DE8, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CB, 0x00005B92, + 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4D, 0x00000001, 0x0000004B, 0x0000489E, 0x0004007C, + 0x00000014, 0x00002A17, 0x00002C4D, 0x00050082, 0x00000014, 0x0000187C, 0x00000B0C, 0x00002A17, + 0x00050080, 0x00000014, 0x00002212, 0x00002A17, 0x00000938, 0x000600A9, 0x00000014, 0x00002871, + 0x000040CB, 0x00002212, 0x00005B92, 0x000500C4, 0x00000014, 0x00005AD6, 0x0000489E, 0x0000187C, + 0x000500C7, 0x00000014, 0x0000499C, 0x00005AD6, 0x00000466, 0x000600A9, 0x00000014, 0x00002A9F, + 0x000040CB, 0x0000499C, 0x0000489E, 0x00050080, 0x00000014, 0x00005FFB, 0x00002871, 0x000003FA, + 0x000500C4, 0x00000014, 0x00004F81, 0x00005FFB, 0x00000189, 0x000500C4, 0x00000014, 0x00003FA8, + 0x00002A9F, 0x0000008D, 0x000500C5, 0x00000014, 0x0000577E, 0x00004F81, 0x00003FA8, 0x000500AA, + 0x00000010, 0x00003602, 0x00005DE8, 0x00000A12, 0x000600A9, 0x00000014, 0x00004244, 0x00003602, + 0x00000A12, 0x0000577E, 0x0004007C, 0x00000018, 0x000029D1, 0x00004244, 0x000500C2, 0x0000000B, + 0x00004BA6, 0x000027F6, 0x00000A64, 0x00040070, 0x0000000D, 0x00004810, 0x00004BA6, 0x00050085, + 0x0000000D, 0x00003E21, 0x00004810, 0x00000149, 0x00050051, 0x0000000D, 0x000053C4, 0x000029D1, + 0x00000000, 0x00050051, 0x0000000D, 0x00002A57, 0x000029D1, 0x00000001, 0x00050051, 0x0000000D, + 0x00001E9B, 0x000029D1, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDC, 0x000053C4, 0x00002A57, + 0x00001E9B, 0x00003E21, 0x00050051, 0x0000000B, 0x000027F7, 0x00002ABF, 0x00000003, 0x00060050, + 0x00000014, 0x00003510, 0x000027F7, 0x000027F7, 0x000027F7, 0x000500C2, 0x00000014, 0x00002B10, + 0x00003510, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DE9, 0x00002B10, 0x00000105, 0x000500C7, + 0x00000014, 0x0000489F, 0x00005DE9, 0x00000466, 0x000500C2, 0x00000014, 0x00005B93, 0x00005DE9, + 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CC, 0x00005B93, 0x00000A12, 0x0006000C, 0x00000016, + 0x00002C4E, 0x00000001, 0x0000004B, 0x0000489F, 0x0004007C, 0x00000014, 0x00002A18, 0x00002C4E, + 0x00050082, 0x00000014, 0x0000187D, 0x00000B0C, 0x00002A18, 0x00050080, 0x00000014, 0x00002213, + 0x00002A18, 0x00000938, 0x000600A9, 0x00000014, 0x00002872, 0x000040CC, 0x00002213, 0x00005B93, + 0x000500C4, 0x00000014, 0x00005AD7, 0x0000489F, 0x0000187D, 0x000500C7, 0x00000014, 0x0000499D, + 0x00005AD7, 0x00000466, 0x000600A9, 0x00000014, 0x00002AA0, 0x000040CC, 0x0000499D, 0x0000489F, + 0x00050080, 0x00000014, 0x00005FFC, 0x00002872, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F82, + 0x00005FFC, 0x00000189, 0x000500C4, 0x00000014, 0x00003FA9, 0x00002AA0, 0x0000008D, 0x000500C5, + 0x00000014, 0x0000577F, 0x00004F82, 0x00003FA9, 0x000500AA, 0x00000010, 0x00003603, 0x00005DE9, + 0x00000A12, 0x000600A9, 0x00000014, 0x00004245, 0x00003603, 0x00000A12, 0x0000577F, 0x0004007C, + 0x00000018, 0x000029D2, 0x00004245, 0x000500C2, 0x0000000B, 0x00004BA7, 0x000027F7, 0x00000A64, + 0x00040070, 0x0000000D, 0x00004811, 0x00004BA7, 0x00050085, 0x0000000D, 0x00003E22, 0x00004811, + 0x00000149, 0x00050051, 0x0000000D, 0x000053C5, 0x000029D2, 0x00000000, 0x00050051, 0x0000000D, + 0x00002A58, 0x000029D2, 0x00000001, 0x00050051, 0x0000000D, 0x00002B11, 0x000029D2, 0x00000002, + 0x00070050, 0x0000001D, 0x0000234B, 0x000053C5, 0x00002A58, 0x00002B11, 0x00003E22, 0x000200F9, + 0x00003F60, 0x000200F8, 0x00001CBB, 0x00050051, 0x0000000B, 0x000056BE, 0x00002ABF, 0x00000000, + 0x00070050, 0x00000017, 0x00004F0B, 0x000056BE, 0x000056BE, 0x000056BE, 0x000056BE, 0x000500C2, + 0x00000017, 0x00002498, 0x00004F0B, 0x0000034D, 0x000500C7, 0x00000017, 0x000049AB, 0x00002498, + 0x0000027B, 0x00040070, 0x0000001D, 0x00003CB7, 0x000049AB, 0x00050085, 0x0000001D, 0x00004130, + 0x00003CB7, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD2, 0x00002ABF, 0x00000001, 0x00070050, + 0x00000017, 0x0000514D, 0x00005CD2, 0x00005CD2, 0x00005CD2, 0x00005CD2, 0x000500C2, 0x00000017, + 0x00002499, 0x0000514D, 0x0000034D, 0x000500C7, 0x00000017, 0x000049AC, 0x00002499, 0x0000027B, + 0x00040070, 0x0000001D, 0x00003CB8, 0x000049AC, 0x00050085, 0x0000001D, 0x00004131, 0x00003CB8, + 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD3, 0x00002ABF, 0x00000002, 0x00070050, 0x00000017, + 0x0000514E, 0x00005CD3, 0x00005CD3, 0x00005CD3, 0x00005CD3, 0x000500C2, 0x00000017, 0x0000249A, + 0x0000514E, 0x0000034D, 0x000500C7, 0x00000017, 0x000049AD, 0x0000249A, 0x0000027B, 0x00040070, + 0x0000001D, 0x00003CB9, 0x000049AD, 0x00050085, 0x0000001D, 0x00004132, 0x00003CB9, 0x00000AEE, + 0x00050051, 0x0000000B, 0x00005CD4, 0x00002ABF, 0x00000003, 0x00070050, 0x00000017, 0x0000514F, + 0x00005CD4, 0x00005CD4, 0x00005CD4, 0x00005CD4, 0x000500C2, 0x00000017, 0x0000249B, 0x0000514F, + 0x0000034D, 0x000500C7, 0x00000017, 0x000049AE, 0x0000249B, 0x0000027B, 0x00040070, 0x0000001D, + 0x0000492F, 0x000049AE, 0x00050085, 0x0000001D, 0x0000269F, 0x0000492F, 0x00000AEE, 0x000200F9, + 0x00003F60, 0x000200F8, 0x000038F9, 0x00050051, 0x0000000B, 0x000056BF, 0x00002ABF, 0x00000000, + 0x00070050, 0x00000017, 0x00004F0C, 0x000056BF, 0x000056BF, 0x000056BF, 0x000056BF, 0x000500C2, + 0x00000017, 0x0000249C, 0x00004F0C, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A56, 0x0000249C, + 0x0000064B, 0x00040070, 0x0000001D, 0x000036A2, 0x00004A56, 0x0005008E, 0x0000001D, 0x00004B23, + 0x000036A2, 0x0000017A, 0x00050051, 0x0000000B, 0x0000219F, 0x00002ABF, 0x00000001, 0x00070050, + 0x00000017, 0x0000610B, 0x0000219F, 0x0000219F, 0x0000219F, 0x0000219F, 0x000500C2, 0x00000017, + 0x0000249D, 0x0000610B, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A57, 0x0000249D, 0x0000064B, + 0x00040070, 0x0000001D, 0x000036A3, 0x00004A57, 0x0005008E, 0x0000001D, 0x00004B24, 0x000036A3, + 0x0000017A, 0x00050051, 0x0000000B, 0x000021A0, 0x00002ABF, 0x00000002, 0x00070050, 0x00000017, + 0x0000610C, 0x000021A0, 0x000021A0, 0x000021A0, 0x000021A0, 0x000500C2, 0x00000017, 0x0000249E, + 0x0000610C, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A58, 0x0000249E, 0x0000064B, 0x00040070, + 0x0000001D, 0x000036A4, 0x00004A58, 0x0005008E, 0x0000001D, 0x00004B25, 0x000036A4, 0x0000017A, + 0x00050051, 0x0000000B, 0x000021A1, 0x00002ABF, 0x00000003, 0x00070050, 0x00000017, 0x0000610D, + 0x000021A1, 0x000021A1, 0x000021A1, 0x000021A1, 0x000500C2, 0x00000017, 0x0000249F, 0x0000610D, + 0x0000028D, 0x000500C7, 0x00000017, 0x00004A59, 0x0000249F, 0x0000064B, 0x00040070, 0x0000001D, + 0x0000431A, 0x00004A59, 0x0005008E, 0x0000001D, 0x00003092, 0x0000431A, 0x0000017A, 0x000200F9, + 0x00003F60, 0x000200F8, 0x00004BFB, 0x00050051, 0x0000000B, 0x0000308C, 0x00002ABF, 0x00000000, + 0x0004007C, 0x0000000D, 0x00004FEE, 0x0000308C, 0x00050050, 0x00000013, 0x00004336, 0x00004FEE, + 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D90, 0x00004336, 0x00004336, 0x00000000, 0x00000001, + 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B1, 0x00002ABF, 0x00000001, 0x0004007C, + 0x0000000D, 0x00003F68, 0x000056B1, 0x00050050, 0x00000013, 0x00004337, 0x00003F68, 0x00000A0C, + 0x0009004F, 0x0000001D, 0x00002D91, 0x00004337, 0x00004337, 0x00000000, 0x00000001, 0x00000001, + 0x00000001, 0x00050051, 0x0000000B, 0x000056B2, 0x00002ABF, 0x00000002, 0x0004007C, 0x0000000D, + 0x00003F69, 0x000056B2, 0x00050050, 0x00000013, 0x00004338, 0x00003F69, 0x00000A0C, 0x0009004F, + 0x0000001D, 0x00002D92, 0x00004338, 0x00004338, 0x00000000, 0x00000001, 0x00000001, 0x00000001, + 0x00050051, 0x0000000B, 0x000056B3, 0x00002ABF, 0x00000003, 0x0004007C, 0x0000000D, 0x00003F6A, + 0x000056B3, 0x00050050, 0x00000013, 0x00004FAE, 0x00003F6A, 0x00000A0C, 0x0009004F, 0x0000001D, + 0x00005A3A, 0x00004FAE, 0x00004FAE, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000200F9, + 0x00003F60, 0x000200F8, 0x00003F60, 0x000F00F5, 0x0000001D, 0x00002BA7, 0x00005A3A, 0x00004BFB, + 0x00003092, 0x000038F9, 0x0000269F, 0x00001CBB, 0x0000234B, 0x00001CBA, 0x0000234A, 0x00001FFE, + 0x00002349, 0x00002033, 0x000F00F5, 0x0000001D, 0x00003808, 0x00002D92, 0x00004BFB, 0x00004B25, + 0x000038F9, 0x00004132, 0x00001CBB, 0x00003DDC, 0x00001CBA, 0x00004120, 0x00001FFE, 0x0000390E, + 0x00002033, 0x000F00F5, 0x0000001D, 0x00003B7D, 0x00002D91, 0x00004BFB, 0x00004B24, 0x000038F9, + 0x00004131, 0x00001CBB, 0x00003DDB, 0x00001CBA, 0x0000411F, 0x00001FFE, 0x0000390D, 0x00002033, + 0x000F00F5, 0x0000001D, 0x000038B6, 0x00002D90, 0x00004BFB, 0x00004B23, 0x000038F9, 0x00004130, + 0x00001CBB, 0x00003DDA, 0x00001CBA, 0x0000411E, 0x00001FFE, 0x0000390C, 0x00002033, 0x000200F9, + 0x0000530F, 0x000200F8, 0x00003B65, 0x000500AA, 0x00000009, 0x00005450, 0x0000199B, 0x00000A10, + 0x000300F7, 0x00004F23, 0x00000002, 0x000400FA, 0x00005450, 0x00002622, 0x00002F62, 0x000200F8, + 0x00002F62, 0x00060041, 0x00000288, 0x00004BD0, 0x00000CC7, 0x00000A0B, 0x0000628F, 0x0004003D, + 0x0000000B, 0x00005D45, 0x00004BD0, 0x00050080, 0x0000000B, 0x00002DAB, 0x0000628F, 0x00000A0D, + 0x00060041, 0x00000288, 0x00001901, 0x00000CC7, 0x00000A0B, 0x00002DAB, 0x0004003D, 0x0000000B, + 0x00005C64, 0x00001901, 0x00050080, 0x0000000B, 0x00002DAC, 0x0000628F, 0x0000199B, 0x00060041, + 0x00000288, 0x00001902, 0x00000CC7, 0x00000A0B, 0x00002DAC, 0x0004003D, 0x0000000B, 0x00005C65, + 0x00001902, 0x00050080, 0x0000000B, 0x00002DAD, 0x00002DAC, 0x00000A0D, 0x00060041, 0x00000288, + 0x00005FEF, 0x00000CC7, 0x00000A0B, 0x00002DAD, 0x0004003D, 0x0000000B, 0x0000374C, 0x00005FEF, + 0x00070050, 0x00000017, 0x00004CD6, 0x00005D45, 0x00005C64, 0x00005C65, 0x0000374C, 0x00050084, + 0x0000000B, 0x00004298, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000036A7, 0x0000628F, + 0x00004298, 0x00060041, 0x00000288, 0x00003B81, 0x00000CC7, 0x00000A0B, 0x000036A7, 0x0004003D, + 0x0000000B, 0x00005C66, 0x00003B81, 0x00050080, 0x0000000B, 0x00002DAE, 0x000036A7, 0x00000A0D, + 0x00060041, 0x00000288, 0x0000194C, 0x00000CC7, 0x00000A0B, 0x00002DAE, 0x0004003D, 0x0000000B, + 0x00005E5D, 0x0000194C, 0x00050084, 0x0000000B, 0x0000185C, 0x00000A13, 0x0000199B, 0x00050080, + 0x0000000B, 0x000020A3, 0x0000628F, 0x0000185C, 0x00060041, 0x00000288, 0x00003B82, 0x00000CC7, + 0x00000A0B, 0x000020A3, 0x0004003D, 0x0000000B, 0x00005C67, 0x00003B82, 0x00050080, 0x0000000B, + 0x00002DAF, 0x000020A3, 0x00000A0D, 0x00060041, 0x00000288, 0x00005FF0, 0x00000CC7, 0x00000A0B, + 0x00002DAF, 0x0004003D, 0x0000000B, 0x00003FFE, 0x00005FF0, 0x00070050, 0x00000017, 0x0000512E, + 0x00005C66, 0x00005E5D, 0x00005C67, 0x00003FFE, 0x000200F9, 0x00004F23, 0x000200F8, 0x00002622, + 0x00060041, 0x00000288, 0x00005546, 0x00000CC7, 0x00000A0B, 0x0000628F, 0x0004003D, 0x0000000B, + 0x00005D46, 0x00005546, 0x00050080, 0x0000000B, 0x00002DB0, 0x0000628F, 0x00000A0D, 0x00060041, + 0x00000288, 0x00001903, 0x00000CC7, 0x00000A0B, 0x00002DB0, 0x0004003D, 0x0000000B, 0x00005C68, + 0x00001903, 0x00050080, 0x0000000B, 0x00002DB1, 0x0000628F, 0x00000A10, 0x00060041, 0x00000288, + 0x00001904, 0x00000CC7, 0x00000A0B, 0x00002DB1, 0x0004003D, 0x0000000B, 0x00005C69, 0x00001904, + 0x00050080, 0x0000000B, 0x00002DB2, 0x0000628F, 0x00000A13, 0x00060041, 0x00000288, 0x00005FF1, + 0x00000CC7, 0x00000A0B, 0x00002DB2, 0x0004003D, 0x0000000B, 0x00003700, 0x00005FF1, 0x00070050, + 0x00000017, 0x00004ADD, 0x00005D46, 0x00005C68, 0x00005C69, 0x00003700, 0x00050080, 0x0000000B, + 0x000057E5, 0x0000628F, 0x00000A16, 0x00060041, 0x00000288, 0x0000604B, 0x00000CC7, 0x00000A0B, + 0x000057E5, 0x0004003D, 0x0000000B, 0x00005C6A, 0x0000604B, 0x00050080, 0x0000000B, 0x00002DB3, + 0x0000628F, 0x00000A19, 0x00060041, 0x00000288, 0x00001905, 0x00000CC7, 0x00000A0B, 0x00002DB3, + 0x0004003D, 0x0000000B, 0x00005C6B, 0x00001905, 0x00050080, 0x0000000B, 0x00002DB4, 0x0000628F, + 0x00000A1C, 0x00060041, 0x00000288, 0x00001906, 0x00000CC7, 0x00000A0B, 0x00002DB4, 0x0004003D, + 0x0000000B, 0x00005C6C, 0x00001906, 0x00050080, 0x0000000B, 0x00002DB5, 0x0000628F, 0x00000A1F, + 0x00060041, 0x00000288, 0x00005FF2, 0x00000CC7, 0x00000A0B, 0x00002DB5, 0x0004003D, 0x0000000B, + 0x00003FFF, 0x00005FF2, 0x00070050, 0x00000017, 0x0000512F, 0x00005C6A, 0x00005C6B, 0x00005C6C, + 0x00003FFF, 0x000200F9, 0x00004F23, 0x000200F8, 0x00004F23, 0x000700F5, 0x00000017, 0x00002BCD, + 0x0000512F, 0x00002622, 0x0000512E, 0x00002F62, 0x000700F5, 0x00000017, 0x00003720, 0x00004ADD, + 0x00002622, 0x00004CD6, 0x00002F62, 0x000300F7, 0x00004F24, 0x00000000, 0x000700FB, 0x00002180, + 0x00004F56, 0x00000005, 0x00002158, 0x00000007, 0x00002034, 0x000200F8, 0x00002034, 0x00050051, + 0x0000000B, 0x00005F57, 0x00003720, 0x00000000, 0x0006000C, 0x00000013, 0x00006068, 0x00000001, + 0x0000003E, 0x00005F57, 0x00050051, 0x0000000D, 0x00002775, 0x00006068, 0x00000000, 0x00050051, + 0x0000000D, 0x00003EB8, 0x00006068, 0x00000001, 0x00050051, 0x0000000B, 0x00004281, 0x00003720, + 0x00000001, 0x0006000C, 0x00000013, 0x00003CF5, 0x00000001, 0x0000003E, 0x00004281, 0x00050051, + 0x0000000D, 0x00002766, 0x00003CF5, 0x00000000, 0x00050051, 0x0000000D, 0x00004449, 0x00003CF5, + 0x00000001, 0x00070050, 0x0000001D, 0x0000390F, 0x00002775, 0x00003EB8, 0x00002766, 0x00004449, + 0x00050051, 0x0000000B, 0x0000437D, 0x00003720, 0x00000002, 0x0006000C, 0x00000013, 0x0000466E, + 0x00000001, 0x0000003E, 0x0000437D, 0x00050051, 0x0000000D, 0x00002776, 0x0000466E, 0x00000000, + 0x00050051, 0x0000000D, 0x00003EB9, 0x0000466E, 0x00000001, 0x00050051, 0x0000000B, 0x00004282, + 0x00003720, 0x00000003, 0x0006000C, 0x00000013, 0x00003CF6, 0x00000001, 0x0000003E, 0x00004282, + 0x00050051, 0x0000000D, 0x00002767, 0x00003CF6, 0x00000000, 0x00050051, 0x0000000D, 0x0000444A, + 0x00003CF6, 0x00000001, 0x00070050, 0x0000001D, 0x00003910, 0x00002776, 0x00003EB9, 0x00002767, + 0x0000444A, 0x00050051, 0x0000000B, 0x0000437E, 0x00002BCD, 0x00000000, 0x0006000C, 0x00000013, + 0x0000466F, 0x00000001, 0x0000003E, 0x0000437E, 0x00050051, 0x0000000D, 0x00002777, 0x0000466F, + 0x00000000, 0x00050051, 0x0000000D, 0x00003EBA, 0x0000466F, 0x00000001, 0x00050051, 0x0000000B, + 0x00004283, 0x00002BCD, 0x00000001, 0x0006000C, 0x00000013, 0x00003CF7, 0x00000001, 0x0000003E, + 0x00004283, 0x00050051, 0x0000000D, 0x00002768, 0x00003CF7, 0x00000000, 0x00050051, 0x0000000D, + 0x0000444B, 0x00003CF7, 0x00000001, 0x00070050, 0x0000001D, 0x00003911, 0x00002777, 0x00003EBA, + 0x00002768, 0x0000444B, 0x00050051, 0x0000000B, 0x0000437F, 0x00002BCD, 0x00000002, 0x0006000C, + 0x00000013, 0x00004670, 0x00000001, 0x0000003E, 0x0000437F, 0x00050051, 0x0000000D, 0x00002778, + 0x00004670, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBB, 0x00004670, 0x00000001, 0x00050051, + 0x0000000B, 0x00004284, 0x00002BCD, 0x00000003, 0x0006000C, 0x00000013, 0x00003CF8, 0x00000001, + 0x0000003E, 0x00004284, 0x00050051, 0x0000000D, 0x00002769, 0x00003CF8, 0x00000000, 0x00050051, + 0x0000000D, 0x000050BF, 0x00003CF8, 0x00000001, 0x00070050, 0x0000001D, 0x0000234C, 0x00002778, + 0x00003EBB, 0x00002769, 0x000050BF, 0x000200F9, 0x00004F24, 0x000200F8, 0x00002158, 0x0007004F, + 0x00000011, 0x000025FB, 0x00003720, 0x00003720, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, + 0x00005B3C, 0x000025FB, 0x0009004F, 0x0000001A, 0x000060CE, 0x00005B3C, 0x00005B3C, 0x00000000, + 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048A6, 0x000060CE, 0x00000122, + 0x000500C3, 0x0000001A, 0x00003D8D, 0x000048A6, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A9B, + 0x00003D8D, 0x0005008E, 0x0000001D, 0x00004721, 0x00002A9B, 0x000007FE, 0x0007000C, 0x0000001D, + 0x00006291, 0x00000001, 0x00000028, 0x00000504, 0x00004721, 0x0007004F, 0x00000011, 0x0000376B, + 0x00003720, 0x00003720, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024BF, 0x0000376B, + 0x0009004F, 0x0000001A, 0x000060CF, 0x000024BF, 0x000024BF, 0x00000000, 0x00000000, 0x00000001, + 0x00000001, 0x000500C4, 0x0000001A, 0x000048A7, 0x000060CF, 0x00000122, 0x000500C3, 0x0000001A, + 0x00003D8E, 0x000048A7, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A9C, 0x00003D8E, 0x0005008E, + 0x0000001D, 0x00004722, 0x00002A9C, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006292, 0x00000001, + 0x00000028, 0x00000504, 0x00004722, 0x0007004F, 0x00000011, 0x0000376C, 0x00002BCD, 0x00002BCD, + 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000024C0, 0x0000376C, 0x0009004F, 0x0000001A, + 0x000060D0, 0x000024C0, 0x000024C0, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, + 0x0000001A, 0x000048A8, 0x000060D0, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D8F, 0x000048A8, + 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA1, 0x00003D8F, 0x0005008E, 0x0000001D, 0x00004723, + 0x00002AA1, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006293, 0x00000001, 0x00000028, 0x00000504, + 0x00004723, 0x0007004F, 0x00000011, 0x0000376D, 0x00002BCD, 0x00002BCD, 0x00000002, 0x00000003, + 0x0004007C, 0x00000012, 0x000024C1, 0x0000376D, 0x0009004F, 0x0000001A, 0x000060D1, 0x000024C1, + 0x000024C1, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048A9, + 0x000060D1, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D90, 0x000048A9, 0x00000302, 0x0004006F, + 0x0000001D, 0x00002AA2, 0x00003D90, 0x0005008E, 0x0000001D, 0x000053BF, 0x00002AA2, 0x000007FE, + 0x0007000C, 0x0000001D, 0x00004362, 0x00000001, 0x00000028, 0x00000504, 0x000053BF, 0x000200F9, + 0x00004F24, 0x000200F8, 0x00004F56, 0x0007004F, 0x00000011, 0x00002623, 0x00003720, 0x00003720, + 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x00005159, 0x00002623, 0x00050051, 0x0000000D, + 0x00001B7B, 0x00005159, 0x00000000, 0x00050051, 0x0000000D, 0x0000346A, 0x00005159, 0x00000001, + 0x00070050, 0x0000001D, 0x00004278, 0x00001B7B, 0x0000346A, 0x00000A0C, 0x00000A0C, 0x0007004F, + 0x00000011, 0x000041D8, 0x00003720, 0x00003720, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, + 0x0000375D, 0x000041D8, 0x00050051, 0x0000000D, 0x00001B7C, 0x0000375D, 0x00000000, 0x00050051, + 0x0000000D, 0x0000346B, 0x0000375D, 0x00000001, 0x00070050, 0x0000001D, 0x00004279, 0x00001B7C, + 0x0000346B, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041D9, 0x00002BCD, 0x00002BCD, + 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x0000375E, 0x000041D9, 0x00050051, 0x0000000D, + 0x00001B7D, 0x0000375E, 0x00000000, 0x00050051, 0x0000000D, 0x0000346C, 0x0000375E, 0x00000001, + 0x00070050, 0x0000001D, 0x0000427A, 0x00001B7D, 0x0000346C, 0x00000A0C, 0x00000A0C, 0x0007004F, + 0x00000011, 0x000041DA, 0x00002BCD, 0x00002BCD, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, + 0x0000375F, 0x000041DA, 0x00050051, 0x0000000D, 0x00001B7F, 0x0000375F, 0x00000000, 0x00050051, + 0x0000000D, 0x00004108, 0x0000375F, 0x00000001, 0x00070050, 0x0000001D, 0x0000234D, 0x00001B7F, + 0x00004108, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F24, 0x000200F8, 0x00004F24, 0x000900F5, + 0x0000001D, 0x00002BA8, 0x0000234D, 0x00004F56, 0x00004362, 0x00002158, 0x0000234C, 0x00002034, + 0x000900F5, 0x0000001D, 0x00003809, 0x0000427A, 0x00004F56, 0x00006293, 0x00002158, 0x00003911, + 0x00002034, 0x000900F5, 0x0000001D, 0x00003B7E, 0x00004279, 0x00004F56, 0x00006292, 0x00002158, + 0x00003910, 0x00002034, 0x000900F5, 0x0000001D, 0x000038B7, 0x00004278, 0x00004F56, 0x00006291, + 0x00002158, 0x0000390F, 0x00002034, 0x000200F9, 0x0000530F, 0x000200F8, 0x0000530F, 0x000700F5, + 0x0000001D, 0x00002BA9, 0x00002BA8, 0x00004F24, 0x00002BA7, 0x00003F60, 0x000700F5, 0x0000001D, + 0x0000380A, 0x00003809, 0x00004F24, 0x00003808, 0x00003F60, 0x000700F5, 0x0000001D, 0x000035EC, + 0x00003B7E, 0x00004F24, 0x00003B7D, 0x00003F60, 0x000700F5, 0x0000001D, 0x000020D3, 0x000038B7, + 0x00004F24, 0x000038B6, 0x00003F60, 0x000500AE, 0x00000009, 0x00002E55, 0x00004356, 0x00000A16, + 0x000300F7, 0x00005313, 0x00000002, 0x000400FA, 0x00002E55, 0x000051F1, 0x00005313, 0x000200F8, + 0x000051F1, 0x00050084, 0x0000000B, 0x00002B47, 0x00000AFA, 0x0000229A, 0x00050085, 0x0000000D, + 0x00005A1D, 0x00002B2C, 0x000000FC, 0x00050080, 0x0000000B, 0x00001FB2, 0x0000628F, 0x00002B47, + 0x000300F7, 0x00005310, 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B66, 0x000040BA, 0x000200F8, + 0x000040BA, 0x000500AA, 0x00000009, 0x00004ADB, 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F4A, + 0x00000002, 0x000400FA, 0x00004ADB, 0x00002624, 0x00002F63, 0x000200F8, 0x00002F63, 0x00060041, + 0x00000288, 0x00004BD1, 0x00000CC7, 0x00000A0B, 0x00001FB2, 0x0004003D, 0x0000000B, 0x00005D47, + 0x00004BD1, 0x00050080, 0x0000000B, 0x00002DB6, 0x00001FB2, 0x0000199B, 0x00060041, 0x00000288, + 0x0000194D, 0x00000CC7, 0x00000A0B, 0x00002DB6, 0x0004003D, 0x0000000B, 0x00005E5E, 0x0000194D, + 0x00050084, 0x0000000B, 0x0000185D, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A4, + 0x00001FB2, 0x0000185D, 0x00060041, 0x00000288, 0x00003BCE, 0x00000CC7, 0x00000A0B, 0x000020A4, + 0x0004003D, 0x0000000B, 0x00005E5F, 0x00003BCE, 0x00050084, 0x0000000B, 0x0000185E, 0x00000A13, + 0x0000199B, 0x00050080, 0x0000000B, 0x000020A5, 0x00001FB2, 0x0000185E, 0x00060041, 0x00000288, + 0x000037F2, 0x00000CC7, 0x00000A0B, 0x000020A5, 0x0004003D, 0x0000000B, 0x00004000, 0x000037F2, + 0x00070050, 0x00000017, 0x00005130, 0x00005D47, 0x00005E5E, 0x00005E5F, 0x00004000, 0x000200F9, + 0x00004F4A, 0x000200F8, 0x00002624, 0x00060041, 0x00000288, 0x00005547, 0x00000CC7, 0x00000A0B, + 0x00001FB2, 0x0004003D, 0x0000000B, 0x00005D48, 0x00005547, 0x00050080, 0x0000000B, 0x00002DB7, + 0x00001FB2, 0x00000A0D, 0x00060041, 0x00000288, 0x00001907, 0x00000CC7, 0x00000A0B, 0x00002DB7, + 0x0004003D, 0x0000000B, 0x00005C6D, 0x00001907, 0x00050080, 0x0000000B, 0x00002DB8, 0x00001FB2, + 0x00000A10, 0x00060041, 0x00000288, 0x00001908, 0x00000CC7, 0x00000A0B, 0x00002DB8, 0x0004003D, + 0x0000000B, 0x00005C6E, 0x00001908, 0x00050080, 0x0000000B, 0x00002DB9, 0x00001FB2, 0x00000A13, + 0x00060041, 0x00000288, 0x00005FF3, 0x00000CC7, 0x00000A0B, 0x00002DB9, 0x0004003D, 0x0000000B, + 0x00004001, 0x00005FF3, 0x00070050, 0x00000017, 0x00005131, 0x00005D48, 0x00005C6D, 0x00005C6E, + 0x00004001, 0x000200F9, 0x00004F4A, 0x000200F8, 0x00004F4A, 0x000700F5, 0x00000017, 0x00002AC0, + 0x00005131, 0x00002624, 0x00005130, 0x00002F63, 0x000300F7, 0x00003F61, 0x00000000, 0x001300FB, + 0x00002180, 0x00004BFC, 0x00000000, 0x000038FA, 0x00000001, 0x000038FA, 0x00000002, 0x00001CBD, + 0x0000000A, 0x00001CBD, 0x00000003, 0x00001CBC, 0x0000000C, 0x00001CBC, 0x00000004, 0x00001FFF, + 0x00000006, 0x00002035, 0x000200F8, 0x00002035, 0x00050051, 0x0000000B, 0x00005F58, 0x00002AC0, + 0x00000000, 0x0006000C, 0x00000013, 0x00006069, 0x00000001, 0x0000003E, 0x00005F58, 0x00050051, + 0x0000000D, 0x0000276A, 0x00006069, 0x00000000, 0x00050051, 0x0000000D, 0x0000444C, 0x00006069, + 0x00000001, 0x00070050, 0x0000001D, 0x00003912, 0x0000276A, 0x0000444C, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x00004380, 0x00002AC0, 0x00000001, 0x0006000C, 0x00000013, 0x00004671, + 0x00000001, 0x0000003E, 0x00004380, 0x00050051, 0x0000000D, 0x0000276B, 0x00004671, 0x00000000, + 0x00050051, 0x0000000D, 0x0000444D, 0x00004671, 0x00000001, 0x00070050, 0x0000001D, 0x00003913, + 0x0000276B, 0x0000444D, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004381, 0x00002AC0, + 0x00000002, 0x0006000C, 0x00000013, 0x00004672, 0x00000001, 0x0000003E, 0x00004381, 0x00050051, + 0x0000000D, 0x0000276C, 0x00004672, 0x00000000, 0x00050051, 0x0000000D, 0x0000444E, 0x00004672, + 0x00000001, 0x00070050, 0x0000001D, 0x00003914, 0x0000276C, 0x0000444E, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x00004382, 0x00002AC0, 0x00000003, 0x0006000C, 0x00000013, 0x00004673, + 0x00000001, 0x0000003E, 0x00004382, 0x00050051, 0x0000000D, 0x0000276D, 0x00004673, 0x00000000, + 0x00050051, 0x0000000D, 0x000050C0, 0x00004673, 0x00000001, 0x00070050, 0x0000001D, 0x0000234E, + 0x0000276D, 0x000050C0, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F61, 0x000200F8, 0x00001FFF, + 0x00050051, 0x0000000B, 0x0000308D, 0x00002AC0, 0x00000000, 0x0004007C, 0x0000000C, 0x0000589E, + 0x0000308D, 0x00050050, 0x00000012, 0x0000471E, 0x0000589E, 0x0000589E, 0x000500C4, 0x00000012, + 0x000047B1, 0x0000471E, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341B, 0x000047B1, 0x00000867, + 0x0004006F, 0x00000013, 0x00002AA3, 0x0000341B, 0x0005008E, 0x00000013, 0x0000474B, 0x00002AA3, + 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0A, 0x00000001, 0x00000028, 0x00000049, 0x0000474B, + 0x00050051, 0x0000000D, 0x00005F0E, 0x00005E0A, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD7, + 0x00005E0A, 0x00000001, 0x00070050, 0x0000001D, 0x00004121, 0x00005F0E, 0x00003CD7, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C45, 0x00002AC0, 0x00000001, 0x0004007C, 0x0000000C, + 0x00003EA4, 0x00004C45, 0x00050050, 0x00000012, 0x0000471F, 0x00003EA4, 0x00003EA4, 0x000500C4, + 0x00000012, 0x000047B2, 0x0000471F, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341C, 0x000047B2, + 0x00000867, 0x0004006F, 0x00000013, 0x00002AA4, 0x0000341C, 0x0005008E, 0x00000013, 0x0000474C, + 0x00002AA4, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0B, 0x00000001, 0x00000028, 0x00000049, + 0x0000474C, 0x00050051, 0x0000000D, 0x00005F0F, 0x00005E0B, 0x00000000, 0x00050051, 0x0000000D, + 0x00003CD8, 0x00005E0B, 0x00000001, 0x00070050, 0x0000001D, 0x00004122, 0x00005F0F, 0x00003CD8, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C46, 0x00002AC0, 0x00000002, 0x0004007C, + 0x0000000C, 0x00003EA5, 0x00004C46, 0x00050050, 0x00000012, 0x00004720, 0x00003EA5, 0x00003EA5, + 0x000500C4, 0x00000012, 0x000047B3, 0x00004720, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341D, + 0x000047B3, 0x00000867, 0x0004006F, 0x00000013, 0x00002AA5, 0x0000341D, 0x0005008E, 0x00000013, + 0x0000474D, 0x00002AA5, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0C, 0x00000001, 0x00000028, + 0x00000049, 0x0000474D, 0x00050051, 0x0000000D, 0x00005F10, 0x00005E0C, 0x00000000, 0x00050051, + 0x0000000D, 0x00003CD9, 0x00005E0C, 0x00000001, 0x00070050, 0x0000001D, 0x00004123, 0x00005F10, + 0x00003CD9, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C47, 0x00002AC0, 0x00000003, + 0x0004007C, 0x0000000C, 0x00003EA6, 0x00004C47, 0x00050050, 0x00000012, 0x00004724, 0x00003EA6, + 0x00003EA6, 0x000500C4, 0x00000012, 0x000047B4, 0x00004724, 0x000007A7, 0x000500C3, 0x00000012, + 0x0000341E, 0x000047B4, 0x00000867, 0x0004006F, 0x00000013, 0x00002AA6, 0x0000341E, 0x0005008E, + 0x00000013, 0x0000474E, 0x00002AA6, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0D, 0x00000001, + 0x00000028, 0x00000049, 0x0000474E, 0x00050051, 0x0000000D, 0x00005F11, 0x00005E0D, 0x00000000, + 0x00050051, 0x0000000D, 0x0000494D, 0x00005E0D, 0x00000001, 0x00070050, 0x0000001D, 0x0000234F, + 0x00005F11, 0x0000494D, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F61, 0x000200F8, 0x00001CBC, + 0x00050051, 0x0000000B, 0x000056C0, 0x00002AC0, 0x00000000, 0x00060050, 0x00000014, 0x00004F0D, + 0x000056C0, 0x000056C0, 0x000056C0, 0x000500C2, 0x00000014, 0x00002B12, 0x00004F0D, 0x00000BB4, + 0x000500C7, 0x00000014, 0x00005DEA, 0x00002B12, 0x00000105, 0x000500C7, 0x00000014, 0x000048A0, + 0x00005DEA, 0x00000466, 0x000500C2, 0x00000014, 0x00005B94, 0x00005DEA, 0x00000B0C, 0x000500AA, + 0x00000010, 0x000040CD, 0x00005B94, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4F, 0x00000001, + 0x0000004B, 0x000048A0, 0x0004007C, 0x00000014, 0x00002A19, 0x00002C4F, 0x00050082, 0x00000014, + 0x0000187E, 0x00000B0C, 0x00002A19, 0x00050080, 0x00000014, 0x00002214, 0x00002A19, 0x00000938, + 0x000600A9, 0x00000014, 0x00002873, 0x000040CD, 0x00002214, 0x00005B94, 0x000500C4, 0x00000014, + 0x00005AD8, 0x000048A0, 0x0000187E, 0x000500C7, 0x00000014, 0x0000499E, 0x00005AD8, 0x00000466, + 0x000600A9, 0x00000014, 0x00002AA7, 0x000040CD, 0x0000499E, 0x000048A0, 0x00050080, 0x00000014, + 0x00005FFD, 0x00002873, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F83, 0x00005FFD, 0x00000189, + 0x000500C4, 0x00000014, 0x00003FAA, 0x00002AA7, 0x0000008D, 0x000500C5, 0x00000014, 0x00005780, + 0x00004F83, 0x00003FAA, 0x000500AA, 0x00000010, 0x00003604, 0x00005DEA, 0x00000A12, 0x000600A9, + 0x00000014, 0x00004246, 0x00003604, 0x00000A12, 0x00005780, 0x0004007C, 0x00000018, 0x000029D3, + 0x00004246, 0x000500C2, 0x0000000B, 0x00004BA8, 0x000056C0, 0x00000A64, 0x00040070, 0x0000000D, + 0x00004812, 0x00004BA8, 0x00050085, 0x0000000D, 0x00003E23, 0x00004812, 0x00000149, 0x00050051, + 0x0000000D, 0x000053C6, 0x000029D3, 0x00000000, 0x00050051, 0x0000000D, 0x00002A59, 0x000029D3, + 0x00000001, 0x00050051, 0x0000000D, 0x00001E9C, 0x000029D3, 0x00000002, 0x00070050, 0x0000001D, + 0x00003DDD, 0x000053C6, 0x00002A59, 0x00001E9C, 0x00003E23, 0x00050051, 0x0000000B, 0x000027F8, + 0x00002AC0, 0x00000001, 0x00060050, 0x00000014, 0x00003511, 0x000027F8, 0x000027F8, 0x000027F8, + 0x000500C2, 0x00000014, 0x00002B13, 0x00003511, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEB, + 0x00002B13, 0x00000105, 0x000500C7, 0x00000014, 0x000048A1, 0x00005DEB, 0x00000466, 0x000500C2, + 0x00000014, 0x00005B95, 0x00005DEB, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CE, 0x00005B95, + 0x00000A12, 0x0006000C, 0x00000016, 0x00002C50, 0x00000001, 0x0000004B, 0x000048A1, 0x0004007C, + 0x00000014, 0x00002A1A, 0x00002C50, 0x00050082, 0x00000014, 0x0000187F, 0x00000B0C, 0x00002A1A, + 0x00050080, 0x00000014, 0x00002215, 0x00002A1A, 0x00000938, 0x000600A9, 0x00000014, 0x00002874, + 0x000040CE, 0x00002215, 0x00005B95, 0x000500C4, 0x00000014, 0x00005AD9, 0x000048A1, 0x0000187F, + 0x000500C7, 0x00000014, 0x0000499F, 0x00005AD9, 0x00000466, 0x000600A9, 0x00000014, 0x00002AA8, + 0x000040CE, 0x0000499F, 0x000048A1, 0x00050080, 0x00000014, 0x00005FFE, 0x00002874, 0x000003FA, + 0x000500C4, 0x00000014, 0x00004F84, 0x00005FFE, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAB, + 0x00002AA8, 0x0000008D, 0x000500C5, 0x00000014, 0x00005781, 0x00004F84, 0x00003FAB, 0x000500AA, + 0x00000010, 0x00003605, 0x00005DEB, 0x00000A12, 0x000600A9, 0x00000014, 0x00004247, 0x00003605, + 0x00000A12, 0x00005781, 0x0004007C, 0x00000018, 0x000029D4, 0x00004247, 0x000500C2, 0x0000000B, + 0x00004BA9, 0x000027F8, 0x00000A64, 0x00040070, 0x0000000D, 0x00004813, 0x00004BA9, 0x00050085, + 0x0000000D, 0x00003E24, 0x00004813, 0x00000149, 0x00050051, 0x0000000D, 0x000053C7, 0x000029D4, + 0x00000000, 0x00050051, 0x0000000D, 0x00002A5A, 0x000029D4, 0x00000001, 0x00050051, 0x0000000D, + 0x00001E9D, 0x000029D4, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDE, 0x000053C7, 0x00002A5A, + 0x00001E9D, 0x00003E24, 0x00050051, 0x0000000B, 0x000027F9, 0x00002AC0, 0x00000002, 0x00060050, + 0x00000014, 0x00003512, 0x000027F9, 0x000027F9, 0x000027F9, 0x000500C2, 0x00000014, 0x00002B14, + 0x00003512, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEC, 0x00002B14, 0x00000105, 0x000500C7, + 0x00000014, 0x000048A2, 0x00005DEC, 0x00000466, 0x000500C2, 0x00000014, 0x00005B96, 0x00005DEC, + 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CF, 0x00005B96, 0x00000A12, 0x0006000C, 0x00000016, + 0x00002C51, 0x00000001, 0x0000004B, 0x000048A2, 0x0004007C, 0x00000014, 0x00002A1B, 0x00002C51, + 0x00050082, 0x00000014, 0x00001880, 0x00000B0C, 0x00002A1B, 0x00050080, 0x00000014, 0x00002216, + 0x00002A1B, 0x00000938, 0x000600A9, 0x00000014, 0x00002875, 0x000040CF, 0x00002216, 0x00005B96, + 0x000500C4, 0x00000014, 0x00005ADA, 0x000048A2, 0x00001880, 0x000500C7, 0x00000014, 0x000049A0, + 0x00005ADA, 0x00000466, 0x000600A9, 0x00000014, 0x00002AA9, 0x000040CF, 0x000049A0, 0x000048A2, + 0x00050080, 0x00000014, 0x00005FFF, 0x00002875, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F85, + 0x00005FFF, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAC, 0x00002AA9, 0x0000008D, 0x000500C5, + 0x00000014, 0x00005782, 0x00004F85, 0x00003FAC, 0x000500AA, 0x00000010, 0x00003606, 0x00005DEC, + 0x00000A12, 0x000600A9, 0x00000014, 0x00004248, 0x00003606, 0x00000A12, 0x00005782, 0x0004007C, + 0x00000018, 0x000029D5, 0x00004248, 0x000500C2, 0x0000000B, 0x00004BAA, 0x000027F9, 0x00000A64, + 0x00040070, 0x0000000D, 0x00004814, 0x00004BAA, 0x00050085, 0x0000000D, 0x00003E25, 0x00004814, + 0x00000149, 0x00050051, 0x0000000D, 0x000053C8, 0x000029D5, 0x00000000, 0x00050051, 0x0000000D, + 0x00002A5B, 0x000029D5, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9E, 0x000029D5, 0x00000002, + 0x00070050, 0x0000001D, 0x00003DDF, 0x000053C8, 0x00002A5B, 0x00001E9E, 0x00003E25, 0x00050051, + 0x0000000B, 0x000027FA, 0x00002AC0, 0x00000003, 0x00060050, 0x00000014, 0x00003513, 0x000027FA, + 0x000027FA, 0x000027FA, 0x000500C2, 0x00000014, 0x00002B15, 0x00003513, 0x00000BB4, 0x000500C7, + 0x00000014, 0x00005DED, 0x00002B15, 0x00000105, 0x000500C7, 0x00000014, 0x000048A3, 0x00005DED, + 0x00000466, 0x000500C2, 0x00000014, 0x00005B97, 0x00005DED, 0x00000B0C, 0x000500AA, 0x00000010, + 0x000040D0, 0x00005B97, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C52, 0x00000001, 0x0000004B, + 0x000048A3, 0x0004007C, 0x00000014, 0x00002A1C, 0x00002C52, 0x00050082, 0x00000014, 0x00001881, + 0x00000B0C, 0x00002A1C, 0x00050080, 0x00000014, 0x00002217, 0x00002A1C, 0x00000938, 0x000600A9, + 0x00000014, 0x00002876, 0x000040D0, 0x00002217, 0x00005B97, 0x000500C4, 0x00000014, 0x00005ADB, + 0x000048A3, 0x00001881, 0x000500C7, 0x00000014, 0x000049A1, 0x00005ADB, 0x00000466, 0x000600A9, + 0x00000014, 0x00002AAA, 0x000040D0, 0x000049A1, 0x000048A3, 0x00050080, 0x00000014, 0x00006000, + 0x00002876, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F86, 0x00006000, 0x00000189, 0x000500C4, + 0x00000014, 0x00003FAD, 0x00002AAA, 0x0000008D, 0x000500C5, 0x00000014, 0x00005783, 0x00004F86, + 0x00003FAD, 0x000500AA, 0x00000010, 0x00003607, 0x00005DED, 0x00000A12, 0x000600A9, 0x00000014, + 0x00004249, 0x00003607, 0x00000A12, 0x00005783, 0x0004007C, 0x00000018, 0x000029D6, 0x00004249, + 0x000500C2, 0x0000000B, 0x00004BAB, 0x000027FA, 0x00000A64, 0x00040070, 0x0000000D, 0x00004815, + 0x00004BAB, 0x00050085, 0x0000000D, 0x00003E26, 0x00004815, 0x00000149, 0x00050051, 0x0000000D, + 0x000053C9, 0x000029D6, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5C, 0x000029D6, 0x00000001, + 0x00050051, 0x0000000D, 0x00002B16, 0x000029D6, 0x00000002, 0x00070050, 0x0000001D, 0x00002350, + 0x000053C9, 0x00002A5C, 0x00002B16, 0x00003E26, 0x000200F9, 0x00003F61, 0x000200F8, 0x00001CBD, + 0x00050051, 0x0000000B, 0x000056C1, 0x00002AC0, 0x00000000, 0x00070050, 0x00000017, 0x00004F0E, + 0x000056C1, 0x000056C1, 0x000056C1, 0x000056C1, 0x000500C2, 0x00000017, 0x000024A0, 0x00004F0E, + 0x0000034D, 0x000500C7, 0x00000017, 0x000049AF, 0x000024A0, 0x0000027B, 0x00040070, 0x0000001D, + 0x00003CBA, 0x000049AF, 0x00050085, 0x0000001D, 0x00004133, 0x00003CBA, 0x00000AEE, 0x00050051, + 0x0000000B, 0x00005CD5, 0x00002AC0, 0x00000001, 0x00070050, 0x00000017, 0x00005150, 0x00005CD5, + 0x00005CD5, 0x00005CD5, 0x00005CD5, 0x000500C2, 0x00000017, 0x000024A1, 0x00005150, 0x0000034D, + 0x000500C7, 0x00000017, 0x000049B0, 0x000024A1, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBB, + 0x000049B0, 0x00050085, 0x0000001D, 0x00004134, 0x00003CBB, 0x00000AEE, 0x00050051, 0x0000000B, + 0x00005CD6, 0x00002AC0, 0x00000002, 0x00070050, 0x00000017, 0x00005151, 0x00005CD6, 0x00005CD6, + 0x00005CD6, 0x00005CD6, 0x000500C2, 0x00000017, 0x000024A2, 0x00005151, 0x0000034D, 0x000500C7, + 0x00000017, 0x000049B1, 0x000024A2, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBC, 0x000049B1, + 0x00050085, 0x0000001D, 0x00004135, 0x00003CBC, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD7, + 0x00002AC0, 0x00000003, 0x00070050, 0x00000017, 0x00005152, 0x00005CD7, 0x00005CD7, 0x00005CD7, + 0x00005CD7, 0x000500C2, 0x00000017, 0x000024A3, 0x00005152, 0x0000034D, 0x000500C7, 0x00000017, + 0x000049B2, 0x000024A3, 0x0000027B, 0x00040070, 0x0000001D, 0x00004930, 0x000049B2, 0x00050085, + 0x0000001D, 0x000026A0, 0x00004930, 0x00000AEE, 0x000200F9, 0x00003F61, 0x000200F8, 0x000038FA, + 0x00050051, 0x0000000B, 0x000056C2, 0x00002AC0, 0x00000000, 0x00070050, 0x00000017, 0x00004F0F, + 0x000056C2, 0x000056C2, 0x000056C2, 0x000056C2, 0x000500C2, 0x00000017, 0x000024A4, 0x00004F0F, + 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5A, 0x000024A4, 0x0000064B, 0x00040070, 0x0000001D, + 0x000036A5, 0x00004A5A, 0x0005008E, 0x0000001D, 0x00004B26, 0x000036A5, 0x0000017A, 0x00050051, + 0x0000000B, 0x000021A2, 0x00002AC0, 0x00000001, 0x00070050, 0x00000017, 0x0000610E, 0x000021A2, + 0x000021A2, 0x000021A2, 0x000021A2, 0x000500C2, 0x00000017, 0x000024A5, 0x0000610E, 0x0000028D, + 0x000500C7, 0x00000017, 0x00004A5B, 0x000024A5, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A6, + 0x00004A5B, 0x0005008E, 0x0000001D, 0x00004B27, 0x000036A6, 0x0000017A, 0x00050051, 0x0000000B, + 0x000021A3, 0x00002AC0, 0x00000002, 0x00070050, 0x00000017, 0x0000610F, 0x000021A3, 0x000021A3, + 0x000021A3, 0x000021A3, 0x000500C2, 0x00000017, 0x000024A6, 0x0000610F, 0x0000028D, 0x000500C7, + 0x00000017, 0x00004A5C, 0x000024A6, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A8, 0x00004A5C, + 0x0005008E, 0x0000001D, 0x00004B28, 0x000036A8, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A4, + 0x00002AC0, 0x00000003, 0x00070050, 0x00000017, 0x00006110, 0x000021A4, 0x000021A4, 0x000021A4, + 0x000021A4, 0x000500C2, 0x00000017, 0x000024A7, 0x00006110, 0x0000028D, 0x000500C7, 0x00000017, + 0x00004A5D, 0x000024A7, 0x0000064B, 0x00040070, 0x0000001D, 0x0000431B, 0x00004A5D, 0x0005008E, + 0x0000001D, 0x00003093, 0x0000431B, 0x0000017A, 0x000200F9, 0x00003F61, 0x000200F8, 0x00004BFC, + 0x00050051, 0x0000000B, 0x0000308E, 0x00002AC0, 0x00000000, 0x0004007C, 0x0000000D, 0x00004FEF, + 0x0000308E, 0x00050050, 0x00000013, 0x00004339, 0x00004FEF, 0x00000A0C, 0x0009004F, 0x0000001D, + 0x00002D93, 0x00004339, 0x00004339, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, + 0x0000000B, 0x000056B4, 0x00002AC0, 0x00000001, 0x0004007C, 0x0000000D, 0x00003F6B, 0x000056B4, + 0x00050050, 0x00000013, 0x0000433A, 0x00003F6B, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D94, + 0x0000433A, 0x0000433A, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, + 0x000056B5, 0x00002AC0, 0x00000002, 0x0004007C, 0x0000000D, 0x00003F6C, 0x000056B5, 0x00050050, + 0x00000013, 0x0000433B, 0x00003F6C, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D95, 0x0000433B, + 0x0000433B, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B6, + 0x00002AC0, 0x00000003, 0x0004007C, 0x0000000D, 0x00003F6D, 0x000056B6, 0x00050050, 0x00000013, + 0x00004FAF, 0x00003F6D, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3B, 0x00004FAF, 0x00004FAF, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000200F9, 0x00003F61, 0x000200F8, 0x00003F61, + 0x000F00F5, 0x0000001D, 0x00002BAA, 0x00005A3B, 0x00004BFC, 0x00003093, 0x000038FA, 0x000026A0, + 0x00001CBD, 0x00002350, 0x00001CBC, 0x0000234F, 0x00001FFF, 0x0000234E, 0x00002035, 0x000F00F5, + 0x0000001D, 0x0000380B, 0x00002D95, 0x00004BFC, 0x00004B28, 0x000038FA, 0x00004135, 0x00001CBD, + 0x00003DDF, 0x00001CBC, 0x00004123, 0x00001FFF, 0x00003914, 0x00002035, 0x000F00F5, 0x0000001D, + 0x00003B7F, 0x00002D94, 0x00004BFC, 0x00004B27, 0x000038FA, 0x00004134, 0x00001CBD, 0x00003DDE, + 0x00001CBC, 0x00004122, 0x00001FFF, 0x00003913, 0x00002035, 0x000F00F5, 0x0000001D, 0x000038B8, + 0x00002D93, 0x00004BFC, 0x00004B26, 0x000038FA, 0x00004133, 0x00001CBD, 0x00003DDD, 0x00001CBC, + 0x00004121, 0x00001FFF, 0x00003912, 0x00002035, 0x000200F9, 0x00005310, 0x000200F8, 0x00003B66, + 0x000500AA, 0x00000009, 0x00005451, 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F25, 0x00000002, + 0x000400FA, 0x00005451, 0x00002625, 0x00002F64, 0x000200F8, 0x00002F64, 0x00060041, 0x00000288, + 0x00004BD2, 0x00000CC7, 0x00000A0B, 0x00001FB2, 0x0004003D, 0x0000000B, 0x00005D49, 0x00004BD2, + 0x00050080, 0x0000000B, 0x00002DBA, 0x00001FB2, 0x00000A0D, 0x00060041, 0x00000288, 0x00001909, + 0x00000CC7, 0x00000A0B, 0x00002DBA, 0x0004003D, 0x0000000B, 0x00005C6F, 0x00001909, 0x00050080, + 0x0000000B, 0x00002DBB, 0x00001FB2, 0x0000199B, 0x00060041, 0x00000288, 0x0000190A, 0x00000CC7, + 0x00000A0B, 0x00002DBB, 0x0004003D, 0x0000000B, 0x00005C70, 0x0000190A, 0x00050080, 0x0000000B, + 0x00002DBC, 0x00002DBB, 0x00000A0D, 0x00060041, 0x00000288, 0x00005FF4, 0x00000CC7, 0x00000A0B, + 0x00002DBC, 0x0004003D, 0x0000000B, 0x0000374D, 0x00005FF4, 0x00070050, 0x00000017, 0x00004CD7, + 0x00005D49, 0x00005C6F, 0x00005C70, 0x0000374D, 0x00050084, 0x0000000B, 0x00004299, 0x00000A10, + 0x0000199B, 0x00050080, 0x0000000B, 0x000036A9, 0x00001FB2, 0x00004299, 0x00060041, 0x00000288, + 0x00003B83, 0x00000CC7, 0x00000A0B, 0x000036A9, 0x0004003D, 0x0000000B, 0x00005C71, 0x00003B83, + 0x00050080, 0x0000000B, 0x00002DBD, 0x000036A9, 0x00000A0D, 0x00060041, 0x00000288, 0x0000194E, + 0x00000CC7, 0x00000A0B, 0x00002DBD, 0x0004003D, 0x0000000B, 0x00005E60, 0x0000194E, 0x00050084, + 0x0000000B, 0x0000185F, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A6, 0x00001FB2, + 0x0000185F, 0x00060041, 0x00000288, 0x00003B84, 0x00000CC7, 0x00000A0B, 0x000020A6, 0x0004003D, + 0x0000000B, 0x00005C72, 0x00003B84, 0x00050080, 0x0000000B, 0x00002DBE, 0x000020A6, 0x00000A0D, + 0x00060041, 0x00000288, 0x00005FF5, 0x00000CC7, 0x00000A0B, 0x00002DBE, 0x0004003D, 0x0000000B, + 0x00004002, 0x00005FF5, 0x00070050, 0x00000017, 0x00005132, 0x00005C71, 0x00005E60, 0x00005C72, + 0x00004002, 0x000200F9, 0x00004F25, 0x000200F8, 0x00002625, 0x00060041, 0x00000288, 0x00005548, + 0x00000CC7, 0x00000A0B, 0x00001FB2, 0x0004003D, 0x0000000B, 0x00005D4A, 0x00005548, 0x00050080, + 0x0000000B, 0x00002DBF, 0x00001FB2, 0x00000A0D, 0x00060041, 0x00000288, 0x0000190B, 0x00000CC7, + 0x00000A0B, 0x00002DBF, 0x0004003D, 0x0000000B, 0x00005C73, 0x0000190B, 0x00050080, 0x0000000B, + 0x00002DC0, 0x00001FB2, 0x00000A10, 0x00060041, 0x00000288, 0x0000190C, 0x00000CC7, 0x00000A0B, + 0x00002DC0, 0x0004003D, 0x0000000B, 0x00005C74, 0x0000190C, 0x00050080, 0x0000000B, 0x00002DC1, + 0x00001FB2, 0x00000A13, 0x00060041, 0x00000288, 0x00005FF6, 0x00000CC7, 0x00000A0B, 0x00002DC1, + 0x0004003D, 0x0000000B, 0x00003701, 0x00005FF6, 0x00070050, 0x00000017, 0x00004ADE, 0x00005D4A, + 0x00005C73, 0x00005C74, 0x00003701, 0x00050080, 0x0000000B, 0x000057E6, 0x00001FB2, 0x00000A16, + 0x00060041, 0x00000288, 0x0000604C, 0x00000CC7, 0x00000A0B, 0x000057E6, 0x0004003D, 0x0000000B, + 0x00005C75, 0x0000604C, 0x00050080, 0x0000000B, 0x00002DC2, 0x00001FB2, 0x00000A19, 0x00060041, + 0x00000288, 0x0000190D, 0x00000CC7, 0x00000A0B, 0x00002DC2, 0x0004003D, 0x0000000B, 0x00005C76, + 0x0000190D, 0x00050080, 0x0000000B, 0x00002DC3, 0x00001FB2, 0x00000A1C, 0x00060041, 0x00000288, + 0x0000190E, 0x00000CC7, 0x00000A0B, 0x00002DC3, 0x0004003D, 0x0000000B, 0x00005C77, 0x0000190E, + 0x00050080, 0x0000000B, 0x00002DC4, 0x00001FB2, 0x00000A1F, 0x00060041, 0x00000288, 0x00005FF7, + 0x00000CC7, 0x00000A0B, 0x00002DC4, 0x0004003D, 0x0000000B, 0x00004003, 0x00005FF7, 0x00070050, + 0x00000017, 0x00005133, 0x00005C75, 0x00005C76, 0x00005C77, 0x00004003, 0x000200F9, 0x00004F25, + 0x000200F8, 0x00004F25, 0x000700F5, 0x00000017, 0x00002BCE, 0x00005133, 0x00002625, 0x00005132, + 0x00002F64, 0x000700F5, 0x00000017, 0x00003721, 0x00004ADE, 0x00002625, 0x00004CD7, 0x00002F64, + 0x000300F7, 0x00004F26, 0x00000000, 0x000700FB, 0x00002180, 0x00004F57, 0x00000005, 0x00002159, + 0x00000007, 0x00002036, 0x000200F8, 0x00002036, 0x00050051, 0x0000000B, 0x00005F59, 0x00003721, + 0x00000000, 0x0006000C, 0x00000013, 0x0000606A, 0x00000001, 0x0000003E, 0x00005F59, 0x00050051, + 0x0000000D, 0x00002779, 0x0000606A, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBC, 0x0000606A, + 0x00000001, 0x00050051, 0x0000000B, 0x00004285, 0x00003721, 0x00000001, 0x0006000C, 0x00000013, + 0x00003CF9, 0x00000001, 0x0000003E, 0x00004285, 0x00050051, 0x0000000D, 0x0000276E, 0x00003CF9, + 0x00000000, 0x00050051, 0x0000000D, 0x0000444F, 0x00003CF9, 0x00000001, 0x00070050, 0x0000001D, + 0x00003915, 0x00002779, 0x00003EBC, 0x0000276E, 0x0000444F, 0x00050051, 0x0000000B, 0x00004383, + 0x00003721, 0x00000002, 0x0006000C, 0x00000013, 0x00004674, 0x00000001, 0x0000003E, 0x00004383, + 0x00050051, 0x0000000D, 0x0000277A, 0x00004674, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBD, + 0x00004674, 0x00000001, 0x00050051, 0x0000000B, 0x00004286, 0x00003721, 0x00000003, 0x0006000C, + 0x00000013, 0x00003CFA, 0x00000001, 0x0000003E, 0x00004286, 0x00050051, 0x0000000D, 0x0000276F, + 0x00003CFA, 0x00000000, 0x00050051, 0x0000000D, 0x00004450, 0x00003CFA, 0x00000001, 0x00070050, + 0x0000001D, 0x00003916, 0x0000277A, 0x00003EBD, 0x0000276F, 0x00004450, 0x00050051, 0x0000000B, + 0x00004384, 0x00002BCE, 0x00000000, 0x0006000C, 0x00000013, 0x00004675, 0x00000001, 0x0000003E, + 0x00004384, 0x00050051, 0x0000000D, 0x0000277B, 0x00004675, 0x00000000, 0x00050051, 0x0000000D, + 0x00003EBE, 0x00004675, 0x00000001, 0x00050051, 0x0000000B, 0x00004287, 0x00002BCE, 0x00000001, + 0x0006000C, 0x00000013, 0x00003CFB, 0x00000001, 0x0000003E, 0x00004287, 0x00050051, 0x0000000D, + 0x00002770, 0x00003CFB, 0x00000000, 0x00050051, 0x0000000D, 0x00004451, 0x00003CFB, 0x00000001, + 0x00070050, 0x0000001D, 0x00003917, 0x0000277B, 0x00003EBE, 0x00002770, 0x00004451, 0x00050051, + 0x0000000B, 0x00004385, 0x00002BCE, 0x00000002, 0x0006000C, 0x00000013, 0x00004676, 0x00000001, + 0x0000003E, 0x00004385, 0x00050051, 0x0000000D, 0x0000277C, 0x00004676, 0x00000000, 0x00050051, + 0x0000000D, 0x00003EBF, 0x00004676, 0x00000001, 0x00050051, 0x0000000B, 0x00004288, 0x00002BCE, + 0x00000003, 0x0006000C, 0x00000013, 0x00003CFC, 0x00000001, 0x0000003E, 0x00004288, 0x00050051, + 0x0000000D, 0x00002771, 0x00003CFC, 0x00000000, 0x00050051, 0x0000000D, 0x000050C1, 0x00003CFC, + 0x00000001, 0x00070050, 0x0000001D, 0x00002351, 0x0000277C, 0x00003EBF, 0x00002771, 0x000050C1, + 0x000200F9, 0x00004F26, 0x000200F8, 0x00002159, 0x0007004F, 0x00000011, 0x000025FC, 0x00003721, + 0x00003721, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x00005B3D, 0x000025FC, 0x0009004F, + 0x0000001A, 0x000060D2, 0x00005B3D, 0x00005B3D, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C4, 0x0000001A, 0x000048AA, 0x000060D2, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D91, + 0x000048AA, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AAB, 0x00003D91, 0x0005008E, 0x0000001D, + 0x00004725, 0x00002AAB, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006294, 0x00000001, 0x00000028, + 0x00000504, 0x00004725, 0x0007004F, 0x00000011, 0x0000376E, 0x00003721, 0x00003721, 0x00000002, + 0x00000003, 0x0004007C, 0x00000012, 0x000024C2, 0x0000376E, 0x0009004F, 0x0000001A, 0x000060D3, + 0x000024C2, 0x000024C2, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, + 0x000048AB, 0x000060D3, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D92, 0x000048AB, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002AAC, 0x00003D92, 0x0005008E, 0x0000001D, 0x00004726, 0x00002AAC, + 0x000007FE, 0x0007000C, 0x0000001D, 0x00006295, 0x00000001, 0x00000028, 0x00000504, 0x00004726, + 0x0007004F, 0x00000011, 0x0000376F, 0x00002BCE, 0x00002BCE, 0x00000000, 0x00000001, 0x0004007C, + 0x00000012, 0x000024C3, 0x0000376F, 0x0009004F, 0x0000001A, 0x000060D4, 0x000024C3, 0x000024C3, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048AC, 0x000060D4, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D93, 0x000048AC, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002AAD, 0x00003D93, 0x0005008E, 0x0000001D, 0x00004727, 0x00002AAD, 0x000007FE, 0x0007000C, + 0x0000001D, 0x00006296, 0x00000001, 0x00000028, 0x00000504, 0x00004727, 0x0007004F, 0x00000011, + 0x00003770, 0x00002BCE, 0x00002BCE, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C4, + 0x00003770, 0x0009004F, 0x0000001A, 0x000060D5, 0x000024C4, 0x000024C4, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048AD, 0x000060D5, 0x00000122, 0x000500C3, + 0x0000001A, 0x00003D94, 0x000048AD, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AAE, 0x00003D94, + 0x0005008E, 0x0000001D, 0x000053C0, 0x00002AAE, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004363, + 0x00000001, 0x00000028, 0x00000504, 0x000053C0, 0x000200F9, 0x00004F26, 0x000200F8, 0x00004F57, + 0x0007004F, 0x00000011, 0x00002626, 0x00003721, 0x00003721, 0x00000000, 0x00000001, 0x0004007C, + 0x00000013, 0x0000515A, 0x00002626, 0x00050051, 0x0000000D, 0x00001B80, 0x0000515A, 0x00000000, + 0x00050051, 0x0000000D, 0x0000346D, 0x0000515A, 0x00000001, 0x00070050, 0x0000001D, 0x0000427B, + 0x00001B80, 0x0000346D, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DB, 0x00003721, + 0x00003721, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x00003760, 0x000041DB, 0x00050051, + 0x0000000D, 0x00001B81, 0x00003760, 0x00000000, 0x00050051, 0x0000000D, 0x0000346E, 0x00003760, + 0x00000001, 0x00070050, 0x0000001D, 0x0000427C, 0x00001B81, 0x0000346E, 0x00000A0C, 0x00000A0C, + 0x0007004F, 0x00000011, 0x000041DC, 0x00002BCE, 0x00002BCE, 0x00000000, 0x00000001, 0x0004007C, + 0x00000013, 0x00003761, 0x000041DC, 0x00050051, 0x0000000D, 0x00001B82, 0x00003761, 0x00000000, + 0x00050051, 0x0000000D, 0x0000346F, 0x00003761, 0x00000001, 0x00070050, 0x0000001D, 0x0000427D, + 0x00001B82, 0x0000346F, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DD, 0x00002BCE, + 0x00002BCE, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x00003762, 0x000041DD, 0x00050051, + 0x0000000D, 0x00001B83, 0x00003762, 0x00000000, 0x00050051, 0x0000000D, 0x00004109, 0x00003762, + 0x00000001, 0x00070050, 0x0000001D, 0x00002352, 0x00001B83, 0x00004109, 0x00000A0C, 0x00000A0C, + 0x000200F9, 0x00004F26, 0x000200F8, 0x00004F26, 0x000900F5, 0x0000001D, 0x00002BAB, 0x00002352, + 0x00004F57, 0x00004363, 0x00002159, 0x00002351, 0x00002036, 0x000900F5, 0x0000001D, 0x0000380C, + 0x0000427D, 0x00004F57, 0x00006296, 0x00002159, 0x00003917, 0x00002036, 0x000900F5, 0x0000001D, + 0x00003B80, 0x0000427C, 0x00004F57, 0x00006295, 0x00002159, 0x00003916, 0x00002036, 0x000900F5, + 0x0000001D, 0x000038B9, 0x0000427B, 0x00004F57, 0x00006294, 0x00002159, 0x00003915, 0x00002036, + 0x000200F9, 0x00005310, 0x000200F8, 0x00005310, 0x000700F5, 0x0000001D, 0x00002BAC, 0x00002BAB, + 0x00004F26, 0x00002BAA, 0x00003F61, 0x000700F5, 0x0000001D, 0x0000380D, 0x0000380C, 0x00004F26, + 0x0000380B, 0x00003F61, 0x000700F5, 0x0000001D, 0x00003295, 0x00003B80, 0x00004F26, 0x00003B7F, + 0x00003F61, 0x000700F5, 0x0000001D, 0x0000367A, 0x000038B9, 0x00004F26, 0x000038B8, 0x00003F61, + 0x00050081, 0x0000001D, 0x00004359, 0x000020D3, 0x0000367A, 0x00050081, 0x0000001D, 0x00005B01, + 0x000035EC, 0x00003295, 0x00050081, 0x0000001D, 0x00001F92, 0x0000380A, 0x0000380D, 0x00050081, + 0x0000001D, 0x00005113, 0x00002BA9, 0x00002BAC, 0x000500AE, 0x00000009, 0x0000387D, 0x00004356, + 0x00000A1C, 0x000300F7, 0x00005EC8, 0x00000002, 0x000400FA, 0x0000387D, 0x000026B1, 0x00005EC8, + 0x000200F8, 0x000026B1, 0x000500C4, 0x0000000B, 0x000037B2, 0x00000A0D, 0x000023AA, 0x00050085, + 0x0000000D, 0x00002F3A, 0x00002B2C, 0x0000016E, 0x00050080, 0x0000000B, 0x000051FC, 0x0000628F, + 0x000037B2, 0x000300F7, 0x00005311, 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B67, 0x000040BB, + 0x000200F8, 0x000040BB, 0x000500AA, 0x00000009, 0x00004ADF, 0x0000199B, 0x00000A0D, 0x000300F7, + 0x00004F4B, 0x00000002, 0x000400FA, 0x00004ADF, 0x00002627, 0x00002F65, 0x000200F8, 0x00002F65, + 0x00060041, 0x00000288, 0x00004BD3, 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, + 0x00005D4B, 0x00004BD3, 0x00050080, 0x0000000B, 0x00002DC5, 0x000051FC, 0x0000199B, 0x00060041, + 0x00000288, 0x0000194F, 0x00000CC7, 0x00000A0B, 0x00002DC5, 0x0004003D, 0x0000000B, 0x00005E61, + 0x0000194F, 0x00050084, 0x0000000B, 0x00001860, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, + 0x000020A7, 0x000051FC, 0x00001860, 0x00060041, 0x00000288, 0x00003BCF, 0x00000CC7, 0x00000A0B, + 0x000020A7, 0x0004003D, 0x0000000B, 0x00005E62, 0x00003BCF, 0x00050084, 0x0000000B, 0x00001861, + 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A8, 0x000051FC, 0x00001861, 0x00060041, + 0x00000288, 0x000037F3, 0x00000CC7, 0x00000A0B, 0x000020A8, 0x0004003D, 0x0000000B, 0x00004004, + 0x000037F3, 0x00070050, 0x00000017, 0x00005134, 0x00005D4B, 0x00005E61, 0x00005E62, 0x00004004, + 0x000200F9, 0x00004F4B, 0x000200F8, 0x00002627, 0x00060041, 0x00000288, 0x00005549, 0x00000CC7, + 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, 0x00005D4C, 0x00005549, 0x00050080, 0x0000000B, + 0x00002DC6, 0x000051FC, 0x00000A0D, 0x00060041, 0x00000288, 0x0000190F, 0x00000CC7, 0x00000A0B, + 0x00002DC6, 0x0004003D, 0x0000000B, 0x00005C78, 0x0000190F, 0x00050080, 0x0000000B, 0x00002DC7, + 0x000051FC, 0x00000A10, 0x00060041, 0x00000288, 0x00001910, 0x00000CC7, 0x00000A0B, 0x00002DC7, + 0x0004003D, 0x0000000B, 0x00005C79, 0x00001910, 0x00050080, 0x0000000B, 0x00002DC8, 0x000051FC, + 0x00000A13, 0x00060041, 0x00000288, 0x00005FF8, 0x00000CC7, 0x00000A0B, 0x00002DC8, 0x0004003D, + 0x0000000B, 0x00004005, 0x00005FF8, 0x00070050, 0x00000017, 0x00005135, 0x00005D4C, 0x00005C78, + 0x00005C79, 0x00004005, 0x000200F9, 0x00004F4B, 0x000200F8, 0x00004F4B, 0x000700F5, 0x00000017, + 0x00002AC1, 0x00005135, 0x00002627, 0x00005134, 0x00002F65, 0x000300F7, 0x00003F62, 0x00000000, + 0x001300FB, 0x00002180, 0x00004BFD, 0x00000000, 0x000038FB, 0x00000001, 0x000038FB, 0x00000002, + 0x00001CBF, 0x0000000A, 0x00001CBF, 0x00000003, 0x00001CBE, 0x0000000C, 0x00001CBE, 0x00000004, + 0x00002000, 0x00000006, 0x00002037, 0x000200F8, 0x00002037, 0x00050051, 0x0000000B, 0x00005F5A, + 0x00002AC1, 0x00000000, 0x0006000C, 0x00000013, 0x0000606B, 0x00000001, 0x0000003E, 0x00005F5A, + 0x00050051, 0x0000000D, 0x00002772, 0x0000606B, 0x00000000, 0x00050051, 0x0000000D, 0x00004452, + 0x0000606B, 0x00000001, 0x00070050, 0x0000001D, 0x00003918, 0x00002772, 0x00004452, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x00004386, 0x00002AC1, 0x00000001, 0x0006000C, 0x00000013, + 0x00004677, 0x00000001, 0x0000003E, 0x00004386, 0x00050051, 0x0000000D, 0x00002773, 0x00004677, + 0x00000000, 0x00050051, 0x0000000D, 0x00004453, 0x00004677, 0x00000001, 0x00070050, 0x0000001D, + 0x00003919, 0x00002773, 0x00004453, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004387, + 0x00002AC1, 0x00000002, 0x0006000C, 0x00000013, 0x00004678, 0x00000001, 0x0000003E, 0x00004387, + 0x00050051, 0x0000000D, 0x00002774, 0x00004678, 0x00000000, 0x00050051, 0x0000000D, 0x00004454, + 0x00004678, 0x00000001, 0x00070050, 0x0000001D, 0x0000391A, 0x00002774, 0x00004454, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x00004388, 0x00002AC1, 0x00000003, 0x0006000C, 0x00000013, + 0x00004679, 0x00000001, 0x0000003E, 0x00004388, 0x00050051, 0x0000000D, 0x0000277D, 0x00004679, + 0x00000000, 0x00050051, 0x0000000D, 0x000050C2, 0x00004679, 0x00000001, 0x00070050, 0x0000001D, + 0x00002353, 0x0000277D, 0x000050C2, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F62, 0x000200F8, + 0x00002000, 0x00050051, 0x0000000B, 0x0000308F, 0x00002AC1, 0x00000000, 0x0004007C, 0x0000000C, + 0x0000589F, 0x0000308F, 0x00050050, 0x00000012, 0x00004728, 0x0000589F, 0x0000589F, 0x000500C4, + 0x00000012, 0x000047B5, 0x00004728, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341F, 0x000047B5, + 0x00000867, 0x0004006F, 0x00000013, 0x00002AAF, 0x0000341F, 0x0005008E, 0x00000013, 0x0000474F, + 0x00002AAF, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0E, 0x00000001, 0x00000028, 0x00000049, + 0x0000474F, 0x00050051, 0x0000000D, 0x00005F12, 0x00005E0E, 0x00000000, 0x00050051, 0x0000000D, + 0x00003CDA, 0x00005E0E, 0x00000001, 0x00070050, 0x0000001D, 0x00004124, 0x00005F12, 0x00003CDA, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C48, 0x00002AC1, 0x00000001, 0x0004007C, + 0x0000000C, 0x00003EA7, 0x00004C48, 0x00050050, 0x00000012, 0x00004729, 0x00003EA7, 0x00003EA7, + 0x000500C4, 0x00000012, 0x000047B6, 0x00004729, 0x000007A7, 0x000500C3, 0x00000012, 0x00003420, + 0x000047B6, 0x00000867, 0x0004006F, 0x00000013, 0x00002AB0, 0x00003420, 0x0005008E, 0x00000013, + 0x00004750, 0x00002AB0, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0F, 0x00000001, 0x00000028, + 0x00000049, 0x00004750, 0x00050051, 0x0000000D, 0x00005F13, 0x00005E0F, 0x00000000, 0x00050051, + 0x0000000D, 0x00003CDB, 0x00005E0F, 0x00000001, 0x00070050, 0x0000001D, 0x00004125, 0x00005F13, + 0x00003CDB, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C49, 0x00002AC1, 0x00000002, + 0x0004007C, 0x0000000C, 0x00003EA8, 0x00004C49, 0x00050050, 0x00000012, 0x0000472A, 0x00003EA8, + 0x00003EA8, 0x000500C4, 0x00000012, 0x000047B7, 0x0000472A, 0x000007A7, 0x000500C3, 0x00000012, + 0x00003421, 0x000047B7, 0x00000867, 0x0004006F, 0x00000013, 0x00002AB1, 0x00003421, 0x0005008E, + 0x00000013, 0x00004751, 0x00002AB1, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E10, 0x00000001, + 0x00000028, 0x00000049, 0x00004751, 0x00050051, 0x0000000D, 0x00005F14, 0x00005E10, 0x00000000, + 0x00050051, 0x0000000D, 0x00003CDC, 0x00005E10, 0x00000001, 0x00070050, 0x0000001D, 0x00004126, + 0x00005F14, 0x00003CDC, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C4A, 0x00002AC1, + 0x00000003, 0x0004007C, 0x0000000C, 0x00003EA9, 0x00004C4A, 0x00050050, 0x00000012, 0x0000472B, + 0x00003EA9, 0x00003EA9, 0x000500C4, 0x00000012, 0x000047B8, 0x0000472B, 0x000007A7, 0x000500C3, + 0x00000012, 0x00003422, 0x000047B8, 0x00000867, 0x0004006F, 0x00000013, 0x00002AB2, 0x00003422, + 0x0005008E, 0x00000013, 0x00004752, 0x00002AB2, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E11, + 0x00000001, 0x00000028, 0x00000049, 0x00004752, 0x00050051, 0x0000000D, 0x00005F15, 0x00005E11, + 0x00000000, 0x00050051, 0x0000000D, 0x0000494E, 0x00005E11, 0x00000001, 0x00070050, 0x0000001D, + 0x00002354, 0x00005F15, 0x0000494E, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F62, 0x000200F8, + 0x00001CBE, 0x00050051, 0x0000000B, 0x000056C3, 0x00002AC1, 0x00000000, 0x00060050, 0x00000014, + 0x00004F10, 0x000056C3, 0x000056C3, 0x000056C3, 0x000500C2, 0x00000014, 0x00002B17, 0x00004F10, + 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEE, 0x00002B17, 0x00000105, 0x000500C7, 0x00000014, + 0x000048A4, 0x00005DEE, 0x00000466, 0x000500C2, 0x00000014, 0x00005B98, 0x00005DEE, 0x00000B0C, + 0x000500AA, 0x00000010, 0x000040D1, 0x00005B98, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C53, + 0x00000001, 0x0000004B, 0x000048A4, 0x0004007C, 0x00000014, 0x00002A1D, 0x00002C53, 0x00050082, + 0x00000014, 0x00001882, 0x00000B0C, 0x00002A1D, 0x00050080, 0x00000014, 0x00002218, 0x00002A1D, + 0x00000938, 0x000600A9, 0x00000014, 0x00002877, 0x000040D1, 0x00002218, 0x00005B98, 0x000500C4, + 0x00000014, 0x00005ADC, 0x000048A4, 0x00001882, 0x000500C7, 0x00000014, 0x000049A2, 0x00005ADC, + 0x00000466, 0x000600A9, 0x00000014, 0x00002AB3, 0x000040D1, 0x000049A2, 0x000048A4, 0x00050080, + 0x00000014, 0x00006001, 0x00002877, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F87, 0x00006001, + 0x00000189, 0x000500C4, 0x00000014, 0x00003FAE, 0x00002AB3, 0x0000008D, 0x000500C5, 0x00000014, + 0x00005784, 0x00004F87, 0x00003FAE, 0x000500AA, 0x00000010, 0x00003608, 0x00005DEE, 0x00000A12, + 0x000600A9, 0x00000014, 0x0000424A, 0x00003608, 0x00000A12, 0x00005784, 0x0004007C, 0x00000018, + 0x000029D7, 0x0000424A, 0x000500C2, 0x0000000B, 0x00004BAC, 0x000056C3, 0x00000A64, 0x00040070, + 0x0000000D, 0x00004816, 0x00004BAC, 0x00050085, 0x0000000D, 0x00003E27, 0x00004816, 0x00000149, + 0x00050051, 0x0000000D, 0x000053CA, 0x000029D7, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5D, + 0x000029D7, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9F, 0x000029D7, 0x00000002, 0x00070050, + 0x0000001D, 0x00003DE0, 0x000053CA, 0x00002A5D, 0x00001E9F, 0x00003E27, 0x00050051, 0x0000000B, + 0x000027FB, 0x00002AC1, 0x00000001, 0x00060050, 0x00000014, 0x00003514, 0x000027FB, 0x000027FB, + 0x000027FB, 0x000500C2, 0x00000014, 0x00002B18, 0x00003514, 0x00000BB4, 0x000500C7, 0x00000014, + 0x00005DEF, 0x00002B18, 0x00000105, 0x000500C7, 0x00000014, 0x000048A5, 0x00005DEF, 0x00000466, + 0x000500C2, 0x00000014, 0x00005B99, 0x00005DEF, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D2, + 0x00005B99, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C54, 0x00000001, 0x0000004B, 0x000048A5, + 0x0004007C, 0x00000014, 0x00002A1E, 0x00002C54, 0x00050082, 0x00000014, 0x00001883, 0x00000B0C, + 0x00002A1E, 0x00050080, 0x00000014, 0x00002219, 0x00002A1E, 0x00000938, 0x000600A9, 0x00000014, + 0x00002878, 0x000040D2, 0x00002219, 0x00005B99, 0x000500C4, 0x00000014, 0x00005ADD, 0x000048A5, + 0x00001883, 0x000500C7, 0x00000014, 0x000049A3, 0x00005ADD, 0x00000466, 0x000600A9, 0x00000014, + 0x00002AB4, 0x000040D2, 0x000049A3, 0x000048A5, 0x00050080, 0x00000014, 0x00006002, 0x00002878, + 0x000003FA, 0x000500C4, 0x00000014, 0x00004F88, 0x00006002, 0x00000189, 0x000500C4, 0x00000014, + 0x00003FAF, 0x00002AB4, 0x0000008D, 0x000500C5, 0x00000014, 0x00005785, 0x00004F88, 0x00003FAF, + 0x000500AA, 0x00000010, 0x00003609, 0x00005DEF, 0x00000A12, 0x000600A9, 0x00000014, 0x0000424B, + 0x00003609, 0x00000A12, 0x00005785, 0x0004007C, 0x00000018, 0x000029D8, 0x0000424B, 0x000500C2, + 0x0000000B, 0x00004BAD, 0x000027FB, 0x00000A64, 0x00040070, 0x0000000D, 0x00004817, 0x00004BAD, + 0x00050085, 0x0000000D, 0x00003E28, 0x00004817, 0x00000149, 0x00050051, 0x0000000D, 0x000053CB, + 0x000029D8, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5E, 0x000029D8, 0x00000001, 0x00050051, + 0x0000000D, 0x00001EA0, 0x000029D8, 0x00000002, 0x00070050, 0x0000001D, 0x00003DE1, 0x000053CB, + 0x00002A5E, 0x00001EA0, 0x00003E28, 0x00050051, 0x0000000B, 0x000027FC, 0x00002AC1, 0x00000002, + 0x00060050, 0x00000014, 0x00003515, 0x000027FC, 0x000027FC, 0x000027FC, 0x000500C2, 0x00000014, + 0x00002B19, 0x00003515, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF0, 0x00002B19, 0x00000105, + 0x000500C7, 0x00000014, 0x000048AE, 0x00005DF0, 0x00000466, 0x000500C2, 0x00000014, 0x00005B9A, + 0x00005DF0, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D3, 0x00005B9A, 0x00000A12, 0x0006000C, + 0x00000016, 0x00002C55, 0x00000001, 0x0000004B, 0x000048AE, 0x0004007C, 0x00000014, 0x00002A1F, + 0x00002C55, 0x00050082, 0x00000014, 0x00001884, 0x00000B0C, 0x00002A1F, 0x00050080, 0x00000014, + 0x0000221A, 0x00002A1F, 0x00000938, 0x000600A9, 0x00000014, 0x00002879, 0x000040D3, 0x0000221A, + 0x00005B9A, 0x000500C4, 0x00000014, 0x00005ADE, 0x000048AE, 0x00001884, 0x000500C7, 0x00000014, + 0x000049A4, 0x00005ADE, 0x00000466, 0x000600A9, 0x00000014, 0x00002AB5, 0x000040D3, 0x000049A4, + 0x000048AE, 0x00050080, 0x00000014, 0x00006003, 0x00002879, 0x000003FA, 0x000500C4, 0x00000014, + 0x00004F89, 0x00006003, 0x00000189, 0x000500C4, 0x00000014, 0x00003FB0, 0x00002AB5, 0x0000008D, + 0x000500C5, 0x00000014, 0x00005786, 0x00004F89, 0x00003FB0, 0x000500AA, 0x00000010, 0x0000360A, + 0x00005DF0, 0x00000A12, 0x000600A9, 0x00000014, 0x0000424C, 0x0000360A, 0x00000A12, 0x00005786, + 0x0004007C, 0x00000018, 0x000029D9, 0x0000424C, 0x000500C2, 0x0000000B, 0x00004BAE, 0x000027FC, + 0x00000A64, 0x00040070, 0x0000000D, 0x00004818, 0x00004BAE, 0x00050085, 0x0000000D, 0x00003E29, + 0x00004818, 0x00000149, 0x00050051, 0x0000000D, 0x000053CC, 0x000029D9, 0x00000000, 0x00050051, + 0x0000000D, 0x00002A5F, 0x000029D9, 0x00000001, 0x00050051, 0x0000000D, 0x00001EA1, 0x000029D9, + 0x00000002, 0x00070050, 0x0000001D, 0x00003DE2, 0x000053CC, 0x00002A5F, 0x00001EA1, 0x00003E29, + 0x00050051, 0x0000000B, 0x000027FD, 0x00002AC1, 0x00000003, 0x00060050, 0x00000014, 0x00003516, + 0x000027FD, 0x000027FD, 0x000027FD, 0x000500C2, 0x00000014, 0x00002B1A, 0x00003516, 0x00000BB4, + 0x000500C7, 0x00000014, 0x00005DF1, 0x00002B1A, 0x00000105, 0x000500C7, 0x00000014, 0x000048AF, + 0x00005DF1, 0x00000466, 0x000500C2, 0x00000014, 0x00005B9B, 0x00005DF1, 0x00000B0C, 0x000500AA, + 0x00000010, 0x000040D4, 0x00005B9B, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C56, 0x00000001, + 0x0000004B, 0x000048AF, 0x0004007C, 0x00000014, 0x00002A20, 0x00002C56, 0x00050082, 0x00000014, + 0x00001885, 0x00000B0C, 0x00002A20, 0x00050080, 0x00000014, 0x0000221B, 0x00002A20, 0x00000938, + 0x000600A9, 0x00000014, 0x0000287A, 0x000040D4, 0x0000221B, 0x00005B9B, 0x000500C4, 0x00000014, + 0x00005ADF, 0x000048AF, 0x00001885, 0x000500C7, 0x00000014, 0x000049A5, 0x00005ADF, 0x00000466, + 0x000600A9, 0x00000014, 0x00002AB6, 0x000040D4, 0x000049A5, 0x000048AF, 0x00050080, 0x00000014, + 0x00006004, 0x0000287A, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F8A, 0x00006004, 0x00000189, + 0x000500C4, 0x00000014, 0x00003FB1, 0x00002AB6, 0x0000008D, 0x000500C5, 0x00000014, 0x00005787, + 0x00004F8A, 0x00003FB1, 0x000500AA, 0x00000010, 0x0000360B, 0x00005DF1, 0x00000A12, 0x000600A9, + 0x00000014, 0x0000424D, 0x0000360B, 0x00000A12, 0x00005787, 0x0004007C, 0x00000018, 0x000029DA, + 0x0000424D, 0x000500C2, 0x0000000B, 0x00004BAF, 0x000027FD, 0x00000A64, 0x00040070, 0x0000000D, + 0x00004819, 0x00004BAF, 0x00050085, 0x0000000D, 0x00003E2A, 0x00004819, 0x00000149, 0x00050051, + 0x0000000D, 0x000053CD, 0x000029DA, 0x00000000, 0x00050051, 0x0000000D, 0x00002A60, 0x000029DA, + 0x00000001, 0x00050051, 0x0000000D, 0x00002B1B, 0x000029DA, 0x00000002, 0x00070050, 0x0000001D, + 0x00002355, 0x000053CD, 0x00002A60, 0x00002B1B, 0x00003E2A, 0x000200F9, 0x00003F62, 0x000200F8, + 0x00001CBF, 0x00050051, 0x0000000B, 0x000056C4, 0x00002AC1, 0x00000000, 0x00070050, 0x00000017, + 0x00004F11, 0x000056C4, 0x000056C4, 0x000056C4, 0x000056C4, 0x000500C2, 0x00000017, 0x000024A8, + 0x00004F11, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B3, 0x000024A8, 0x0000027B, 0x00040070, + 0x0000001D, 0x00003CBD, 0x000049B3, 0x00050085, 0x0000001D, 0x00004136, 0x00003CBD, 0x00000AEE, + 0x00050051, 0x0000000B, 0x00005CD8, 0x00002AC1, 0x00000001, 0x00070050, 0x00000017, 0x00005153, + 0x00005CD8, 0x00005CD8, 0x00005CD8, 0x00005CD8, 0x000500C2, 0x00000017, 0x000024A9, 0x00005153, + 0x0000034D, 0x000500C7, 0x00000017, 0x000049B4, 0x000024A9, 0x0000027B, 0x00040070, 0x0000001D, + 0x00003CBE, 0x000049B4, 0x00050085, 0x0000001D, 0x00004137, 0x00003CBE, 0x00000AEE, 0x00050051, + 0x0000000B, 0x00005CD9, 0x00002AC1, 0x00000002, 0x00070050, 0x00000017, 0x00005154, 0x00005CD9, + 0x00005CD9, 0x00005CD9, 0x00005CD9, 0x000500C2, 0x00000017, 0x000024AA, 0x00005154, 0x0000034D, + 0x000500C7, 0x00000017, 0x000049B5, 0x000024AA, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBF, + 0x000049B5, 0x00050085, 0x0000001D, 0x00004138, 0x00003CBF, 0x00000AEE, 0x00050051, 0x0000000B, + 0x00005CDA, 0x00002AC1, 0x00000003, 0x00070050, 0x00000017, 0x00005155, 0x00005CDA, 0x00005CDA, + 0x00005CDA, 0x00005CDA, 0x000500C2, 0x00000017, 0x000024AB, 0x00005155, 0x0000034D, 0x000500C7, + 0x00000017, 0x000049B6, 0x000024AB, 0x0000027B, 0x00040070, 0x0000001D, 0x00004931, 0x000049B6, + 0x00050085, 0x0000001D, 0x000026A1, 0x00004931, 0x00000AEE, 0x000200F9, 0x00003F62, 0x000200F8, + 0x000038FB, 0x00050051, 0x0000000B, 0x000056C5, 0x00002AC1, 0x00000000, 0x00070050, 0x00000017, + 0x00004F12, 0x000056C5, 0x000056C5, 0x000056C5, 0x000056C5, 0x000500C2, 0x00000017, 0x000024AC, + 0x00004F12, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5E, 0x000024AC, 0x0000064B, 0x00040070, + 0x0000001D, 0x000036AA, 0x00004A5E, 0x0005008E, 0x0000001D, 0x00004B29, 0x000036AA, 0x0000017A, + 0x00050051, 0x0000000B, 0x000021A5, 0x00002AC1, 0x00000001, 0x00070050, 0x00000017, 0x00006111, + 0x000021A5, 0x000021A5, 0x000021A5, 0x000021A5, 0x000500C2, 0x00000017, 0x000024AD, 0x00006111, + 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5F, 0x000024AD, 0x0000064B, 0x00040070, 0x0000001D, + 0x000036AB, 0x00004A5F, 0x0005008E, 0x0000001D, 0x00004B2A, 0x000036AB, 0x0000017A, 0x00050051, + 0x0000000B, 0x000021A6, 0x00002AC1, 0x00000002, 0x00070050, 0x00000017, 0x00006112, 0x000021A6, + 0x000021A6, 0x000021A6, 0x000021A6, 0x000500C2, 0x00000017, 0x000024AE, 0x00006112, 0x0000028D, + 0x000500C7, 0x00000017, 0x00004A60, 0x000024AE, 0x0000064B, 0x00040070, 0x0000001D, 0x000036AC, + 0x00004A60, 0x0005008E, 0x0000001D, 0x00004B2B, 0x000036AC, 0x0000017A, 0x00050051, 0x0000000B, + 0x000021A7, 0x00002AC1, 0x00000003, 0x00070050, 0x00000017, 0x00006113, 0x000021A7, 0x000021A7, + 0x000021A7, 0x000021A7, 0x000500C2, 0x00000017, 0x000024AF, 0x00006113, 0x0000028D, 0x000500C7, + 0x00000017, 0x00004A61, 0x000024AF, 0x0000064B, 0x00040070, 0x0000001D, 0x0000431C, 0x00004A61, + 0x0005008E, 0x0000001D, 0x00003094, 0x0000431C, 0x0000017A, 0x000200F9, 0x00003F62, 0x000200F8, + 0x00004BFD, 0x00050051, 0x0000000B, 0x00003090, 0x00002AC1, 0x00000000, 0x0004007C, 0x0000000D, + 0x00004FF0, 0x00003090, 0x00050050, 0x00000013, 0x0000433C, 0x00004FF0, 0x00000A0C, 0x0009004F, + 0x0000001D, 0x00002D96, 0x0000433C, 0x0000433C, 0x00000000, 0x00000001, 0x00000001, 0x00000001, + 0x00050051, 0x0000000B, 0x000056B7, 0x00002AC1, 0x00000001, 0x0004007C, 0x0000000D, 0x00003F6E, + 0x000056B7, 0x00050050, 0x00000013, 0x0000433D, 0x00003F6E, 0x00000A0C, 0x0009004F, 0x0000001D, + 0x00002D97, 0x0000433D, 0x0000433D, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, + 0x0000000B, 0x000056B8, 0x00002AC1, 0x00000002, 0x0004007C, 0x0000000D, 0x00003F6F, 0x000056B8, + 0x00050050, 0x00000013, 0x0000433E, 0x00003F6F, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D98, + 0x0000433E, 0x0000433E, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, + 0x000056B9, 0x00002AC1, 0x00000003, 0x0004007C, 0x0000000D, 0x00003F70, 0x000056B9, 0x00050050, + 0x00000013, 0x00004FB0, 0x00003F70, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3C, 0x00004FB0, + 0x00004FB0, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000200F9, 0x00003F62, 0x000200F8, + 0x00003F62, 0x000F00F5, 0x0000001D, 0x00002BAD, 0x00005A3C, 0x00004BFD, 0x00003094, 0x000038FB, + 0x000026A1, 0x00001CBF, 0x00002355, 0x00001CBE, 0x00002354, 0x00002000, 0x00002353, 0x00002037, + 0x000F00F5, 0x0000001D, 0x0000380E, 0x00002D98, 0x00004BFD, 0x00004B2B, 0x000038FB, 0x00004138, + 0x00001CBF, 0x00003DE2, 0x00001CBE, 0x00004126, 0x00002000, 0x0000391A, 0x00002037, 0x000F00F5, + 0x0000001D, 0x00003B85, 0x00002D97, 0x00004BFD, 0x00004B2A, 0x000038FB, 0x00004137, 0x00001CBF, + 0x00003DE1, 0x00001CBE, 0x00004125, 0x00002000, 0x00003919, 0x00002037, 0x000F00F5, 0x0000001D, + 0x000038BA, 0x00002D96, 0x00004BFD, 0x00004B29, 0x000038FB, 0x00004136, 0x00001CBF, 0x00003DE0, + 0x00001CBE, 0x00004124, 0x00002000, 0x00003918, 0x00002037, 0x000200F9, 0x00005311, 0x000200F8, + 0x00003B67, 0x000500AA, 0x00000009, 0x00005452, 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F27, + 0x00000002, 0x000400FA, 0x00005452, 0x00002628, 0x00002F66, 0x000200F8, 0x00002F66, 0x00060041, + 0x00000288, 0x00004BD4, 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, 0x00005D4D, + 0x00004BD4, 0x00050080, 0x0000000B, 0x00002DC9, 0x000051FC, 0x00000A0D, 0x00060041, 0x00000288, + 0x00001911, 0x00000CC7, 0x00000A0B, 0x00002DC9, 0x0004003D, 0x0000000B, 0x00005C7A, 0x00001911, + 0x00050080, 0x0000000B, 0x00002DCA, 0x000051FC, 0x0000199B, 0x00060041, 0x00000288, 0x00001912, + 0x00000CC7, 0x00000A0B, 0x00002DCA, 0x0004003D, 0x0000000B, 0x00005C7B, 0x00001912, 0x00050080, + 0x0000000B, 0x00002DCB, 0x00002DCA, 0x00000A0D, 0x00060041, 0x00000288, 0x00006005, 0x00000CC7, + 0x00000A0B, 0x00002DCB, 0x0004003D, 0x0000000B, 0x0000374E, 0x00006005, 0x00070050, 0x00000017, + 0x00004CD9, 0x00005D4D, 0x00005C7A, 0x00005C7B, 0x0000374E, 0x00050084, 0x0000000B, 0x0000429A, + 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000036AD, 0x000051FC, 0x0000429A, 0x00060041, + 0x00000288, 0x00003B86, 0x00000CC7, 0x00000A0B, 0x000036AD, 0x0004003D, 0x0000000B, 0x00005C7C, + 0x00003B86, 0x00050080, 0x0000000B, 0x00002DCC, 0x000036AD, 0x00000A0D, 0x00060041, 0x00000288, + 0x00001950, 0x00000CC7, 0x00000A0B, 0x00002DCC, 0x0004003D, 0x0000000B, 0x00005E63, 0x00001950, + 0x00050084, 0x0000000B, 0x00001862, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A9, + 0x000051FC, 0x00001862, 0x00060041, 0x00000288, 0x00003B87, 0x00000CC7, 0x00000A0B, 0x000020A9, + 0x0004003D, 0x0000000B, 0x00005C7D, 0x00003B87, 0x00050080, 0x0000000B, 0x00002DCD, 0x000020A9, + 0x00000A0D, 0x00060041, 0x00000288, 0x00006006, 0x00000CC7, 0x00000A0B, 0x00002DCD, 0x0004003D, + 0x0000000B, 0x00004006, 0x00006006, 0x00070050, 0x00000017, 0x00005136, 0x00005C7C, 0x00005E63, + 0x00005C7D, 0x00004006, 0x000200F9, 0x00004F27, 0x000200F8, 0x00002628, 0x00060041, 0x00000288, + 0x0000554A, 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, 0x00005D4E, 0x0000554A, + 0x00050080, 0x0000000B, 0x00002DCE, 0x000051FC, 0x00000A0D, 0x00060041, 0x00000288, 0x00001913, + 0x00000CC7, 0x00000A0B, 0x00002DCE, 0x0004003D, 0x0000000B, 0x00005C7E, 0x00001913, 0x00050080, + 0x0000000B, 0x00002DCF, 0x000051FC, 0x00000A10, 0x00060041, 0x00000288, 0x00001914, 0x00000CC7, + 0x00000A0B, 0x00002DCF, 0x0004003D, 0x0000000B, 0x00005C7F, 0x00001914, 0x00050080, 0x0000000B, + 0x00002DD0, 0x000051FC, 0x00000A13, 0x00060041, 0x00000288, 0x00006007, 0x00000CC7, 0x00000A0B, + 0x00002DD0, 0x0004003D, 0x0000000B, 0x00003702, 0x00006007, 0x00070050, 0x00000017, 0x00004AE0, + 0x00005D4E, 0x00005C7E, 0x00005C7F, 0x00003702, 0x00050080, 0x0000000B, 0x000057E7, 0x000051FC, + 0x00000A16, 0x00060041, 0x00000288, 0x0000604D, 0x00000CC7, 0x00000A0B, 0x000057E7, 0x0004003D, + 0x0000000B, 0x00005C80, 0x0000604D, 0x00050080, 0x0000000B, 0x00002DD1, 0x000051FC, 0x00000A19, + 0x00060041, 0x00000288, 0x00001915, 0x00000CC7, 0x00000A0B, 0x00002DD1, 0x0004003D, 0x0000000B, + 0x00005C81, 0x00001915, 0x00050080, 0x0000000B, 0x00002DD2, 0x000051FC, 0x00000A1C, 0x00060041, + 0x00000288, 0x00001916, 0x00000CC7, 0x00000A0B, 0x00002DD2, 0x0004003D, 0x0000000B, 0x00005C82, + 0x00001916, 0x00050080, 0x0000000B, 0x00002DD3, 0x000051FC, 0x00000A1F, 0x00060041, 0x00000288, + 0x00006008, 0x00000CC7, 0x00000A0B, 0x00002DD3, 0x0004003D, 0x0000000B, 0x00004007, 0x00006008, + 0x00070050, 0x00000017, 0x00005137, 0x00005C80, 0x00005C81, 0x00005C82, 0x00004007, 0x000200F9, + 0x00004F27, 0x000200F8, 0x00004F27, 0x000700F5, 0x00000017, 0x00002BCF, 0x00005137, 0x00002628, + 0x00005136, 0x00002F66, 0x000700F5, 0x00000017, 0x00003722, 0x00004AE0, 0x00002628, 0x00004CD9, + 0x00002F66, 0x000300F7, 0x00004F28, 0x00000000, 0x000700FB, 0x00002180, 0x00004F58, 0x00000005, + 0x0000215A, 0x00000007, 0x00002038, 0x000200F8, 0x00002038, 0x00050051, 0x0000000B, 0x00005F5B, + 0x00003722, 0x00000000, 0x0006000C, 0x00000013, 0x0000606C, 0x00000001, 0x0000003E, 0x00005F5B, + 0x00050051, 0x0000000D, 0x0000277E, 0x0000606C, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC0, + 0x0000606C, 0x00000001, 0x00050051, 0x0000000B, 0x00004289, 0x00003722, 0x00000001, 0x0006000C, + 0x00000013, 0x00003CFD, 0x00000001, 0x0000003E, 0x00004289, 0x00050051, 0x0000000D, 0x0000277F, + 0x00003CFD, 0x00000000, 0x00050051, 0x0000000D, 0x00004455, 0x00003CFD, 0x00000001, 0x00070050, + 0x0000001D, 0x0000391B, 0x0000277E, 0x00003EC0, 0x0000277F, 0x00004455, 0x00050051, 0x0000000B, + 0x00004389, 0x00003722, 0x00000002, 0x0006000C, 0x00000013, 0x0000467A, 0x00000001, 0x0000003E, + 0x00004389, 0x00050051, 0x0000000D, 0x00002780, 0x0000467A, 0x00000000, 0x00050051, 0x0000000D, + 0x00003EC1, 0x0000467A, 0x00000001, 0x00050051, 0x0000000B, 0x0000428A, 0x00003722, 0x00000003, + 0x0006000C, 0x00000013, 0x00003CFE, 0x00000001, 0x0000003E, 0x0000428A, 0x00050051, 0x0000000D, + 0x00002781, 0x00003CFE, 0x00000000, 0x00050051, 0x0000000D, 0x00004456, 0x00003CFE, 0x00000001, + 0x00070050, 0x0000001D, 0x0000391C, 0x00002780, 0x00003EC1, 0x00002781, 0x00004456, 0x00050051, + 0x0000000B, 0x0000438A, 0x00002BCF, 0x00000000, 0x0006000C, 0x00000013, 0x0000467B, 0x00000001, + 0x0000003E, 0x0000438A, 0x00050051, 0x0000000D, 0x00002782, 0x0000467B, 0x00000000, 0x00050051, + 0x0000000D, 0x00003EC2, 0x0000467B, 0x00000001, 0x00050051, 0x0000000B, 0x0000428B, 0x00002BCF, + 0x00000001, 0x0006000C, 0x00000013, 0x00003CFF, 0x00000001, 0x0000003E, 0x0000428B, 0x00050051, + 0x0000000D, 0x00002783, 0x00003CFF, 0x00000000, 0x00050051, 0x0000000D, 0x00004457, 0x00003CFF, + 0x00000001, 0x00070050, 0x0000001D, 0x0000391D, 0x00002782, 0x00003EC2, 0x00002783, 0x00004457, + 0x00050051, 0x0000000B, 0x0000438B, 0x00002BCF, 0x00000002, 0x0006000C, 0x00000013, 0x0000467C, + 0x00000001, 0x0000003E, 0x0000438B, 0x00050051, 0x0000000D, 0x00002784, 0x0000467C, 0x00000000, + 0x00050051, 0x0000000D, 0x00003EC3, 0x0000467C, 0x00000001, 0x00050051, 0x0000000B, 0x0000428C, + 0x00002BCF, 0x00000003, 0x0006000C, 0x00000013, 0x00003D00, 0x00000001, 0x0000003E, 0x0000428C, + 0x00050051, 0x0000000D, 0x00002785, 0x00003D00, 0x00000000, 0x00050051, 0x0000000D, 0x000050C3, + 0x00003D00, 0x00000001, 0x00070050, 0x0000001D, 0x00002356, 0x00002784, 0x00003EC3, 0x00002785, + 0x000050C3, 0x000200F9, 0x00004F28, 0x000200F8, 0x0000215A, 0x0007004F, 0x00000011, 0x000025FD, + 0x00003722, 0x00003722, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x00005B3E, 0x000025FD, + 0x0009004F, 0x0000001A, 0x000060D6, 0x00005B3E, 0x00005B3E, 0x00000000, 0x00000000, 0x00000001, + 0x00000001, 0x000500C4, 0x0000001A, 0x000048B0, 0x000060D6, 0x00000122, 0x000500C3, 0x0000001A, + 0x00003D95, 0x000048B0, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AB7, 0x00003D95, 0x0005008E, + 0x0000001D, 0x0000472C, 0x00002AB7, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006297, 0x00000001, + 0x00000028, 0x00000504, 0x0000472C, 0x0007004F, 0x00000011, 0x00003771, 0x00003722, 0x00003722, + 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C5, 0x00003771, 0x0009004F, 0x0000001A, + 0x000060D7, 0x000024C5, 0x000024C5, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, + 0x0000001A, 0x000048B1, 0x000060D7, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D96, 0x000048B1, + 0x00000302, 0x0004006F, 0x0000001D, 0x00002AB8, 0x00003D96, 0x0005008E, 0x0000001D, 0x0000472D, + 0x00002AB8, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006298, 0x00000001, 0x00000028, 0x00000504, + 0x0000472D, 0x0007004F, 0x00000011, 0x00003772, 0x00002BCF, 0x00002BCF, 0x00000000, 0x00000001, + 0x0004007C, 0x00000012, 0x000024C6, 0x00003772, 0x0009004F, 0x0000001A, 0x000060D8, 0x000024C6, + 0x000024C6, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048B2, + 0x000060D8, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D97, 0x000048B2, 0x00000302, 0x0004006F, + 0x0000001D, 0x00002AB9, 0x00003D97, 0x0005008E, 0x0000001D, 0x0000472E, 0x00002AB9, 0x000007FE, + 0x0007000C, 0x0000001D, 0x00006299, 0x00000001, 0x00000028, 0x00000504, 0x0000472E, 0x0007004F, + 0x00000011, 0x00003773, 0x00002BCF, 0x00002BCF, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, + 0x000024C7, 0x00003773, 0x0009004F, 0x0000001A, 0x000060D9, 0x000024C7, 0x000024C7, 0x00000000, + 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048B3, 0x000060D9, 0x00000122, + 0x000500C3, 0x0000001A, 0x00003D98, 0x000048B3, 0x00000302, 0x0004006F, 0x0000001D, 0x00002ABA, + 0x00003D98, 0x0005008E, 0x0000001D, 0x000053C1, 0x00002ABA, 0x000007FE, 0x0007000C, 0x0000001D, + 0x00004364, 0x00000001, 0x00000028, 0x00000504, 0x000053C1, 0x000200F9, 0x00004F28, 0x000200F8, + 0x00004F58, 0x0007004F, 0x00000011, 0x00002629, 0x00003722, 0x00003722, 0x00000000, 0x00000001, + 0x0004007C, 0x00000013, 0x0000515B, 0x00002629, 0x00050051, 0x0000000D, 0x00001B84, 0x0000515B, + 0x00000000, 0x00050051, 0x0000000D, 0x00003470, 0x0000515B, 0x00000001, 0x00070050, 0x0000001D, + 0x0000427E, 0x00001B84, 0x00003470, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DE, + 0x00003722, 0x00003722, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x00003763, 0x000041DE, + 0x00050051, 0x0000000D, 0x00001B85, 0x00003763, 0x00000000, 0x00050051, 0x0000000D, 0x00003471, + 0x00003763, 0x00000001, 0x00070050, 0x0000001D, 0x0000427F, 0x00001B85, 0x00003471, 0x00000A0C, + 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DF, 0x00002BCF, 0x00002BCF, 0x00000000, 0x00000001, + 0x0004007C, 0x00000013, 0x00003764, 0x000041DF, 0x00050051, 0x0000000D, 0x00001B86, 0x00003764, + 0x00000000, 0x00050051, 0x0000000D, 0x00003472, 0x00003764, 0x00000001, 0x00070050, 0x0000001D, + 0x00004280, 0x00001B86, 0x00003472, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041E0, + 0x00002BCF, 0x00002BCF, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x00003765, 0x000041E0, + 0x00050051, 0x0000000D, 0x00001B87, 0x00003765, 0x00000000, 0x00050051, 0x0000000D, 0x0000410A, + 0x00003765, 0x00000001, 0x00070050, 0x0000001D, 0x00002357, 0x00001B87, 0x0000410A, 0x00000A0C, + 0x00000A0C, 0x000200F9, 0x00004F28, 0x000200F8, 0x00004F28, 0x000900F5, 0x0000001D, 0x00002BAE, + 0x00002357, 0x00004F58, 0x00004364, 0x0000215A, 0x00002356, 0x00002038, 0x000900F5, 0x0000001D, + 0x0000380F, 0x00004280, 0x00004F58, 0x00006299, 0x0000215A, 0x0000391D, 0x00002038, 0x000900F5, + 0x0000001D, 0x00003B88, 0x0000427F, 0x00004F58, 0x00006298, 0x0000215A, 0x0000391C, 0x00002038, + 0x000900F5, 0x0000001D, 0x000038BB, 0x0000427E, 0x00004F58, 0x00006297, 0x0000215A, 0x0000391B, + 0x00002038, 0x000200F9, 0x00005311, 0x000200F8, 0x00005311, 0x000700F5, 0x0000001D, 0x00002BAF, + 0x00002BAE, 0x00004F28, 0x00002BAD, 0x00003F62, 0x000700F5, 0x0000001D, 0x00003810, 0x0000380F, + 0x00004F28, 0x0000380E, 0x00003F62, 0x000700F5, 0x0000001D, 0x00003296, 0x00003B88, 0x00004F28, + 0x00003B85, 0x00003F62, 0x000700F5, 0x0000001D, 0x0000367B, 0x000038BB, 0x00004F28, 0x000038BA, + 0x00003F62, 0x00050081, 0x0000001D, 0x0000435A, 0x00004359, 0x0000367B, 0x00050081, 0x0000001D, + 0x00005B02, 0x00005B01, 0x00003296, 0x00050081, 0x0000001D, 0x00001C28, 0x00001F92, 0x00003810, + 0x00050081, 0x0000001D, 0x000025AA, 0x00005113, 0x00002BAF, 0x00050080, 0x0000000B, 0x00003FF8, + 0x00001FB2, 0x000037B2, 0x000300F7, 0x00005312, 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B68, + 0x000040BC, 0x000200F8, 0x000040BC, 0x000500AA, 0x00000009, 0x00004AE1, 0x0000199B, 0x00000A0D, + 0x000300F7, 0x00004F4C, 0x00000002, 0x000400FA, 0x00004AE1, 0x0000262A, 0x00002F67, 0x000200F8, + 0x00002F67, 0x00060041, 0x00000288, 0x00004BD5, 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, + 0x0000000B, 0x00005D4F, 0x00004BD5, 0x00050080, 0x0000000B, 0x00002DD4, 0x00003FF8, 0x0000199B, + 0x00060041, 0x00000288, 0x00001951, 0x00000CC7, 0x00000A0B, 0x00002DD4, 0x0004003D, 0x0000000B, + 0x00005E64, 0x00001951, 0x00050084, 0x0000000B, 0x00001863, 0x00000A10, 0x0000199B, 0x00050080, + 0x0000000B, 0x000020AA, 0x00003FF8, 0x00001863, 0x00060041, 0x00000288, 0x00003BD0, 0x00000CC7, + 0x00000A0B, 0x000020AA, 0x0004003D, 0x0000000B, 0x00005E65, 0x00003BD0, 0x00050084, 0x0000000B, + 0x00001864, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020AB, 0x00003FF8, 0x00001864, + 0x00060041, 0x00000288, 0x000037F4, 0x00000CC7, 0x00000A0B, 0x000020AB, 0x0004003D, 0x0000000B, + 0x00004008, 0x000037F4, 0x00070050, 0x00000017, 0x00005138, 0x00005D4F, 0x00005E64, 0x00005E65, + 0x00004008, 0x000200F9, 0x00004F4C, 0x000200F8, 0x0000262A, 0x00060041, 0x00000288, 0x0000554B, + 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D50, 0x0000554B, 0x00050080, + 0x0000000B, 0x00002DD5, 0x00003FF8, 0x00000A0D, 0x00060041, 0x00000288, 0x00001917, 0x00000CC7, + 0x00000A0B, 0x00002DD5, 0x0004003D, 0x0000000B, 0x00005C83, 0x00001917, 0x00050080, 0x0000000B, + 0x00002DD6, 0x00003FF8, 0x00000A10, 0x00060041, 0x00000288, 0x00001918, 0x00000CC7, 0x00000A0B, + 0x00002DD6, 0x0004003D, 0x0000000B, 0x00005C84, 0x00001918, 0x00050080, 0x0000000B, 0x00002DD7, + 0x00003FF8, 0x00000A13, 0x00060041, 0x00000288, 0x00006009, 0x00000CC7, 0x00000A0B, 0x00002DD7, + 0x0004003D, 0x0000000B, 0x00004009, 0x00006009, 0x00070050, 0x00000017, 0x00005139, 0x00005D50, + 0x00005C83, 0x00005C84, 0x00004009, 0x000200F9, 0x00004F4C, 0x000200F8, 0x00004F4C, 0x000700F5, + 0x00000017, 0x00002AC2, 0x00005139, 0x0000262A, 0x00005138, 0x00002F67, 0x000300F7, 0x00003F63, + 0x00000000, 0x001300FB, 0x00002180, 0x00004BFE, 0x00000000, 0x000038FC, 0x00000001, 0x000038FC, + 0x00000002, 0x00001CC1, 0x0000000A, 0x00001CC1, 0x00000003, 0x00001CC0, 0x0000000C, 0x00001CC0, + 0x00000004, 0x00002001, 0x00000006, 0x00002039, 0x000200F8, 0x00002039, 0x00050051, 0x0000000B, + 0x00005F5C, 0x00002AC2, 0x00000000, 0x0006000C, 0x00000013, 0x0000606D, 0x00000001, 0x0000003E, + 0x00005F5C, 0x00050051, 0x0000000D, 0x00002786, 0x0000606D, 0x00000000, 0x00050051, 0x0000000D, + 0x00004458, 0x0000606D, 0x00000001, 0x00070050, 0x0000001D, 0x0000391E, 0x00002786, 0x00004458, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x0000438C, 0x00002AC2, 0x00000001, 0x0006000C, + 0x00000013, 0x0000467D, 0x00000001, 0x0000003E, 0x0000438C, 0x00050051, 0x0000000D, 0x00002787, + 0x0000467D, 0x00000000, 0x00050051, 0x0000000D, 0x00004459, 0x0000467D, 0x00000001, 0x00070050, + 0x0000001D, 0x0000391F, 0x00002787, 0x00004459, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x0000438D, 0x00002AC2, 0x00000002, 0x0006000C, 0x00000013, 0x0000467E, 0x00000001, 0x0000003E, + 0x0000438D, 0x00050051, 0x0000000D, 0x00002788, 0x0000467E, 0x00000000, 0x00050051, 0x0000000D, + 0x0000445A, 0x0000467E, 0x00000001, 0x00070050, 0x0000001D, 0x00003920, 0x00002788, 0x0000445A, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x0000438E, 0x00002AC2, 0x00000003, 0x0006000C, + 0x00000013, 0x0000467F, 0x00000001, 0x0000003E, 0x0000438E, 0x00050051, 0x0000000D, 0x00002789, + 0x0000467F, 0x00000000, 0x00050051, 0x0000000D, 0x000050C4, 0x0000467F, 0x00000001, 0x00070050, + 0x0000001D, 0x00002358, 0x00002789, 0x000050C4, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F63, + 0x000200F8, 0x00002001, 0x00050051, 0x0000000B, 0x00003091, 0x00002AC2, 0x00000000, 0x0004007C, + 0x0000000C, 0x000058A0, 0x00003091, 0x00050050, 0x00000012, 0x0000472F, 0x000058A0, 0x000058A0, + 0x000500C4, 0x00000012, 0x000047B9, 0x0000472F, 0x000007A7, 0x000500C3, 0x00000012, 0x00003423, + 0x000047B9, 0x00000867, 0x0004006F, 0x00000013, 0x00002ABB, 0x00003423, 0x0005008E, 0x00000013, + 0x00004753, 0x00002ABB, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E12, 0x00000001, 0x00000028, + 0x00000049, 0x00004753, 0x00050051, 0x0000000D, 0x00005F16, 0x00005E12, 0x00000000, 0x00050051, + 0x0000000D, 0x00003CDD, 0x00005E12, 0x00000001, 0x00070050, 0x0000001D, 0x00004127, 0x00005F16, + 0x00003CDD, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C4B, 0x00002AC2, 0x00000001, + 0x0004007C, 0x0000000C, 0x00003EAA, 0x00004C4B, 0x00050050, 0x00000012, 0x00004730, 0x00003EAA, + 0x00003EAA, 0x000500C4, 0x00000012, 0x000047BA, 0x00004730, 0x000007A7, 0x000500C3, 0x00000012, + 0x00003424, 0x000047BA, 0x00000867, 0x0004006F, 0x00000013, 0x00002ABC, 0x00003424, 0x0005008E, + 0x00000013, 0x00004754, 0x00002ABC, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E13, 0x00000001, + 0x00000028, 0x00000049, 0x00004754, 0x00050051, 0x0000000D, 0x00005F17, 0x00005E13, 0x00000000, + 0x00050051, 0x0000000D, 0x00003CDE, 0x00005E13, 0x00000001, 0x00070050, 0x0000001D, 0x00004128, + 0x00005F17, 0x00003CDE, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C4C, 0x00002AC2, + 0x00000002, 0x0004007C, 0x0000000C, 0x00003EAB, 0x00004C4C, 0x00050050, 0x00000012, 0x00004731, + 0x00003EAB, 0x00003EAB, 0x000500C4, 0x00000012, 0x000047BC, 0x00004731, 0x000007A7, 0x000500C3, + 0x00000012, 0x00003425, 0x000047BC, 0x00000867, 0x0004006F, 0x00000013, 0x00002ABD, 0x00003425, + 0x0005008E, 0x00000013, 0x00004755, 0x00002ABD, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E14, + 0x00000001, 0x00000028, 0x00000049, 0x00004755, 0x00050051, 0x0000000D, 0x00005F18, 0x00005E14, + 0x00000000, 0x00050051, 0x0000000D, 0x00003CDF, 0x00005E14, 0x00000001, 0x00070050, 0x0000001D, + 0x00004129, 0x00005F18, 0x00003CDF, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C4D, + 0x00002AC2, 0x00000003, 0x0004007C, 0x0000000C, 0x00003EAC, 0x00004C4D, 0x00050050, 0x00000012, + 0x00004732, 0x00003EAC, 0x00003EAC, 0x000500C4, 0x00000012, 0x000047BD, 0x00004732, 0x000007A7, + 0x000500C3, 0x00000012, 0x00003426, 0x000047BD, 0x00000867, 0x0004006F, 0x00000013, 0x00002ABE, + 0x00003426, 0x0005008E, 0x00000013, 0x00004756, 0x00002ABE, 0x000007FE, 0x0007000C, 0x00000013, + 0x00005E15, 0x00000001, 0x00000028, 0x00000049, 0x00004756, 0x00050051, 0x0000000D, 0x00005F19, + 0x00005E15, 0x00000000, 0x00050051, 0x0000000D, 0x0000494F, 0x00005E15, 0x00000001, 0x00070050, + 0x0000001D, 0x00002359, 0x00005F19, 0x0000494F, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F63, + 0x000200F8, 0x00001CC0, 0x00050051, 0x0000000B, 0x000056C6, 0x00002AC2, 0x00000000, 0x00060050, + 0x00000014, 0x00004F13, 0x000056C6, 0x000056C6, 0x000056C6, 0x000500C2, 0x00000014, 0x00002B1C, + 0x00004F13, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF2, 0x00002B1C, 0x00000105, 0x000500C7, + 0x00000014, 0x000048B4, 0x00005DF2, 0x00000466, 0x000500C2, 0x00000014, 0x00005B9C, 0x00005DF2, + 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D5, 0x00005B9C, 0x00000A12, 0x0006000C, 0x00000016, + 0x00002C57, 0x00000001, 0x0000004B, 0x000048B4, 0x0004007C, 0x00000014, 0x00002A21, 0x00002C57, + 0x00050082, 0x00000014, 0x00001886, 0x00000B0C, 0x00002A21, 0x00050080, 0x00000014, 0x0000221C, + 0x00002A21, 0x00000938, 0x000600A9, 0x00000014, 0x0000287B, 0x000040D5, 0x0000221C, 0x00005B9C, + 0x000500C4, 0x00000014, 0x00005AE0, 0x000048B4, 0x00001886, 0x000500C7, 0x00000014, 0x000049A6, + 0x00005AE0, 0x00000466, 0x000600A9, 0x00000014, 0x00002AC3, 0x000040D5, 0x000049A6, 0x000048B4, + 0x00050080, 0x00000014, 0x0000600A, 0x0000287B, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F8B, + 0x0000600A, 0x00000189, 0x000500C4, 0x00000014, 0x00003FB2, 0x00002AC3, 0x0000008D, 0x000500C5, + 0x00000014, 0x00005788, 0x00004F8B, 0x00003FB2, 0x000500AA, 0x00000010, 0x0000360C, 0x00005DF2, + 0x00000A12, 0x000600A9, 0x00000014, 0x0000424E, 0x0000360C, 0x00000A12, 0x00005788, 0x0004007C, + 0x00000018, 0x000029DB, 0x0000424E, 0x000500C2, 0x0000000B, 0x00004BB0, 0x000056C6, 0x00000A64, + 0x00040070, 0x0000000D, 0x0000481A, 0x00004BB0, 0x00050085, 0x0000000D, 0x00003E2B, 0x0000481A, + 0x00000149, 0x00050051, 0x0000000D, 0x000053CE, 0x000029DB, 0x00000000, 0x00050051, 0x0000000D, + 0x00002A61, 0x000029DB, 0x00000001, 0x00050051, 0x0000000D, 0x00001EA2, 0x000029DB, 0x00000002, + 0x00070050, 0x0000001D, 0x00003DE3, 0x000053CE, 0x00002A61, 0x00001EA2, 0x00003E2B, 0x00050051, + 0x0000000B, 0x000027FE, 0x00002AC2, 0x00000001, 0x00060050, 0x00000014, 0x00003517, 0x000027FE, + 0x000027FE, 0x000027FE, 0x000500C2, 0x00000014, 0x00002B1D, 0x00003517, 0x00000BB4, 0x000500C7, + 0x00000014, 0x00005DF3, 0x00002B1D, 0x00000105, 0x000500C7, 0x00000014, 0x000048B5, 0x00005DF3, + 0x00000466, 0x000500C2, 0x00000014, 0x00005B9D, 0x00005DF3, 0x00000B0C, 0x000500AA, 0x00000010, + 0x000040D6, 0x00005B9D, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C58, 0x00000001, 0x0000004B, + 0x000048B5, 0x0004007C, 0x00000014, 0x00002A22, 0x00002C58, 0x00050082, 0x00000014, 0x00001887, + 0x00000B0C, 0x00002A22, 0x00050080, 0x00000014, 0x0000221D, 0x00002A22, 0x00000938, 0x000600A9, + 0x00000014, 0x0000287C, 0x000040D6, 0x0000221D, 0x00005B9D, 0x000500C4, 0x00000014, 0x00005AE1, + 0x000048B5, 0x00001887, 0x000500C7, 0x00000014, 0x000049A7, 0x00005AE1, 0x00000466, 0x000600A9, + 0x00000014, 0x00002AC4, 0x000040D6, 0x000049A7, 0x000048B5, 0x00050080, 0x00000014, 0x0000600B, + 0x0000287C, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F8C, 0x0000600B, 0x00000189, 0x000500C4, + 0x00000014, 0x00003FB3, 0x00002AC4, 0x0000008D, 0x000500C5, 0x00000014, 0x00005789, 0x00004F8C, + 0x00003FB3, 0x000500AA, 0x00000010, 0x0000360D, 0x00005DF3, 0x00000A12, 0x000600A9, 0x00000014, + 0x0000424F, 0x0000360D, 0x00000A12, 0x00005789, 0x0004007C, 0x00000018, 0x000029DC, 0x0000424F, + 0x000500C2, 0x0000000B, 0x00004BB1, 0x000027FE, 0x00000A64, 0x00040070, 0x0000000D, 0x0000481B, + 0x00004BB1, 0x00050085, 0x0000000D, 0x00003E2C, 0x0000481B, 0x00000149, 0x00050051, 0x0000000D, + 0x000053CF, 0x000029DC, 0x00000000, 0x00050051, 0x0000000D, 0x00002A62, 0x000029DC, 0x00000001, + 0x00050051, 0x0000000D, 0x00001EA3, 0x000029DC, 0x00000002, 0x00070050, 0x0000001D, 0x00003DE4, + 0x000053CF, 0x00002A62, 0x00001EA3, 0x00003E2C, 0x00050051, 0x0000000B, 0x000027FF, 0x00002AC2, + 0x00000002, 0x00060050, 0x00000014, 0x00003518, 0x000027FF, 0x000027FF, 0x000027FF, 0x000500C2, + 0x00000014, 0x00002B1E, 0x00003518, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF4, 0x00002B1E, + 0x00000105, 0x000500C7, 0x00000014, 0x000048B6, 0x00005DF4, 0x00000466, 0x000500C2, 0x00000014, + 0x00005B9E, 0x00005DF4, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D7, 0x00005B9E, 0x00000A12, + 0x0006000C, 0x00000016, 0x00002C59, 0x00000001, 0x0000004B, 0x000048B6, 0x0004007C, 0x00000014, + 0x00002A23, 0x00002C59, 0x00050082, 0x00000014, 0x00001888, 0x00000B0C, 0x00002A23, 0x00050080, + 0x00000014, 0x0000221E, 0x00002A23, 0x00000938, 0x000600A9, 0x00000014, 0x0000287D, 0x000040D7, + 0x0000221E, 0x00005B9E, 0x000500C4, 0x00000014, 0x00005AE2, 0x000048B6, 0x00001888, 0x000500C7, + 0x00000014, 0x000049A8, 0x00005AE2, 0x00000466, 0x000600A9, 0x00000014, 0x00002AC5, 0x000040D7, + 0x000049A8, 0x000048B6, 0x00050080, 0x00000014, 0x0000600C, 0x0000287D, 0x000003FA, 0x000500C4, + 0x00000014, 0x00004F8D, 0x0000600C, 0x00000189, 0x000500C4, 0x00000014, 0x00003FB4, 0x00002AC5, + 0x0000008D, 0x000500C5, 0x00000014, 0x0000578A, 0x00004F8D, 0x00003FB4, 0x000500AA, 0x00000010, + 0x0000360E, 0x00005DF4, 0x00000A12, 0x000600A9, 0x00000014, 0x00004250, 0x0000360E, 0x00000A12, + 0x0000578A, 0x0004007C, 0x00000018, 0x000029DD, 0x00004250, 0x000500C2, 0x0000000B, 0x00004BB2, + 0x000027FF, 0x00000A64, 0x00040070, 0x0000000D, 0x0000481C, 0x00004BB2, 0x00050085, 0x0000000D, + 0x00003E2D, 0x0000481C, 0x00000149, 0x00050051, 0x0000000D, 0x000053D0, 0x000029DD, 0x00000000, + 0x00050051, 0x0000000D, 0x00002A63, 0x000029DD, 0x00000001, 0x00050051, 0x0000000D, 0x00001EA4, + 0x000029DD, 0x00000002, 0x00070050, 0x0000001D, 0x00003DE5, 0x000053D0, 0x00002A63, 0x00001EA4, + 0x00003E2D, 0x00050051, 0x0000000B, 0x00002800, 0x00002AC2, 0x00000003, 0x00060050, 0x00000014, + 0x00003519, 0x00002800, 0x00002800, 0x00002800, 0x000500C2, 0x00000014, 0x00002B1F, 0x00003519, + 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF5, 0x00002B1F, 0x00000105, 0x000500C7, 0x00000014, + 0x000048B8, 0x00005DF5, 0x00000466, 0x000500C2, 0x00000014, 0x00005B9F, 0x00005DF5, 0x00000B0C, + 0x000500AA, 0x00000010, 0x000040D8, 0x00005B9F, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C5A, + 0x00000001, 0x0000004B, 0x000048B8, 0x0004007C, 0x00000014, 0x00002A24, 0x00002C5A, 0x00050082, + 0x00000014, 0x00001889, 0x00000B0C, 0x00002A24, 0x00050080, 0x00000014, 0x0000221F, 0x00002A24, + 0x00000938, 0x000600A9, 0x00000014, 0x0000287E, 0x000040D8, 0x0000221F, 0x00005B9F, 0x000500C4, + 0x00000014, 0x00005AE3, 0x000048B8, 0x00001889, 0x000500C7, 0x00000014, 0x000049A9, 0x00005AE3, + 0x00000466, 0x000600A9, 0x00000014, 0x00002AC6, 0x000040D8, 0x000049A9, 0x000048B8, 0x00050080, + 0x00000014, 0x0000600D, 0x0000287E, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F8E, 0x0000600D, + 0x00000189, 0x000500C4, 0x00000014, 0x00003FB5, 0x00002AC6, 0x0000008D, 0x000500C5, 0x00000014, + 0x0000578B, 0x00004F8E, 0x00003FB5, 0x000500AA, 0x00000010, 0x0000360F, 0x00005DF5, 0x00000A12, + 0x000600A9, 0x00000014, 0x00004251, 0x0000360F, 0x00000A12, 0x0000578B, 0x0004007C, 0x00000018, + 0x000029DE, 0x00004251, 0x000500C2, 0x0000000B, 0x00004BB3, 0x00002800, 0x00000A64, 0x00040070, + 0x0000000D, 0x0000481D, 0x00004BB3, 0x00050085, 0x0000000D, 0x00003E2E, 0x0000481D, 0x00000149, + 0x00050051, 0x0000000D, 0x000053D1, 0x000029DE, 0x00000000, 0x00050051, 0x0000000D, 0x00002A64, + 0x000029DE, 0x00000001, 0x00050051, 0x0000000D, 0x00002B20, 0x000029DE, 0x00000002, 0x00070050, + 0x0000001D, 0x0000235A, 0x000053D1, 0x00002A64, 0x00002B20, 0x00003E2E, 0x000200F9, 0x00003F63, + 0x000200F8, 0x00001CC1, 0x00050051, 0x0000000B, 0x000056C7, 0x00002AC2, 0x00000000, 0x00070050, + 0x00000017, 0x00004F14, 0x000056C7, 0x000056C7, 0x000056C7, 0x000056C7, 0x000500C2, 0x00000017, + 0x000024B0, 0x00004F14, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B7, 0x000024B0, 0x0000027B, + 0x00040070, 0x0000001D, 0x00003CC0, 0x000049B7, 0x00050085, 0x0000001D, 0x00004139, 0x00003CC0, + 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CDB, 0x00002AC2, 0x00000001, 0x00070050, 0x00000017, + 0x00005156, 0x00005CDB, 0x00005CDB, 0x00005CDB, 0x00005CDB, 0x000500C2, 0x00000017, 0x000024B1, + 0x00005156, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B8, 0x000024B1, 0x0000027B, 0x00040070, + 0x0000001D, 0x00003CC1, 0x000049B8, 0x00050085, 0x0000001D, 0x0000413A, 0x00003CC1, 0x00000AEE, + 0x00050051, 0x0000000B, 0x00005CDC, 0x00002AC2, 0x00000002, 0x00070050, 0x00000017, 0x00005157, + 0x00005CDC, 0x00005CDC, 0x00005CDC, 0x00005CDC, 0x000500C2, 0x00000017, 0x000024B2, 0x00005157, + 0x0000034D, 0x000500C7, 0x00000017, 0x000049B9, 0x000024B2, 0x0000027B, 0x00040070, 0x0000001D, + 0x00003CC2, 0x000049B9, 0x00050085, 0x0000001D, 0x0000413B, 0x00003CC2, 0x00000AEE, 0x00050051, + 0x0000000B, 0x00005CDD, 0x00002AC2, 0x00000003, 0x00070050, 0x00000017, 0x0000515C, 0x00005CDD, + 0x00005CDD, 0x00005CDD, 0x00005CDD, 0x000500C2, 0x00000017, 0x000024B3, 0x0000515C, 0x0000034D, + 0x000500C7, 0x00000017, 0x000049BA, 0x000024B3, 0x0000027B, 0x00040070, 0x0000001D, 0x00004932, + 0x000049BA, 0x00050085, 0x0000001D, 0x000026A2, 0x00004932, 0x00000AEE, 0x000200F9, 0x00003F63, + 0x000200F8, 0x000038FC, 0x00050051, 0x0000000B, 0x000056C8, 0x00002AC2, 0x00000000, 0x00070050, + 0x00000017, 0x00004F15, 0x000056C8, 0x000056C8, 0x000056C8, 0x000056C8, 0x000500C2, 0x00000017, + 0x000024B4, 0x00004F15, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A62, 0x000024B4, 0x0000064B, + 0x00040070, 0x0000001D, 0x000036AE, 0x00004A62, 0x0005008E, 0x0000001D, 0x00004B2C, 0x000036AE, + 0x0000017A, 0x00050051, 0x0000000B, 0x000021A8, 0x00002AC2, 0x00000001, 0x00070050, 0x00000017, + 0x00006114, 0x000021A8, 0x000021A8, 0x000021A8, 0x000021A8, 0x000500C2, 0x00000017, 0x000024B5, + 0x00006114, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A63, 0x000024B5, 0x0000064B, 0x00040070, + 0x0000001D, 0x000036AF, 0x00004A63, 0x0005008E, 0x0000001D, 0x00004B2D, 0x000036AF, 0x0000017A, + 0x00050051, 0x0000000B, 0x000021A9, 0x00002AC2, 0x00000002, 0x00070050, 0x00000017, 0x00006115, + 0x000021A9, 0x000021A9, 0x000021A9, 0x000021A9, 0x000500C2, 0x00000017, 0x000024B6, 0x00006115, + 0x0000028D, 0x000500C7, 0x00000017, 0x00004A64, 0x000024B6, 0x0000064B, 0x00040070, 0x0000001D, + 0x000036B0, 0x00004A64, 0x0005008E, 0x0000001D, 0x00004B2E, 0x000036B0, 0x0000017A, 0x00050051, + 0x0000000B, 0x000021AA, 0x00002AC2, 0x00000003, 0x00070050, 0x00000017, 0x00006116, 0x000021AA, + 0x000021AA, 0x000021AA, 0x000021AA, 0x000500C2, 0x00000017, 0x000024B7, 0x00006116, 0x0000028D, + 0x000500C7, 0x00000017, 0x00004A65, 0x000024B7, 0x0000064B, 0x00040070, 0x0000001D, 0x0000431D, + 0x00004A65, 0x0005008E, 0x0000001D, 0x00003095, 0x0000431D, 0x0000017A, 0x000200F9, 0x00003F63, + 0x000200F8, 0x00004BFE, 0x00050051, 0x0000000B, 0x00003096, 0x00002AC2, 0x00000000, 0x0004007C, + 0x0000000D, 0x00004FF1, 0x00003096, 0x00050050, 0x00000013, 0x0000433F, 0x00004FF1, 0x00000A0C, + 0x0009004F, 0x0000001D, 0x00002D99, 0x0000433F, 0x0000433F, 0x00000000, 0x00000001, 0x00000001, + 0x00000001, 0x00050051, 0x0000000B, 0x000056BA, 0x00002AC2, 0x00000001, 0x0004007C, 0x0000000D, + 0x00003F71, 0x000056BA, 0x00050050, 0x00000013, 0x00004340, 0x00003F71, 0x00000A0C, 0x0009004F, + 0x0000001D, 0x00002D9A, 0x00004340, 0x00004340, 0x00000000, 0x00000001, 0x00000001, 0x00000001, + 0x00050051, 0x0000000B, 0x000056BB, 0x00002AC2, 0x00000002, 0x0004007C, 0x0000000D, 0x00003F72, + 0x000056BB, 0x00050050, 0x00000013, 0x00004341, 0x00003F72, 0x00000A0C, 0x0009004F, 0x0000001D, + 0x00002D9B, 0x00004341, 0x00004341, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, + 0x0000000B, 0x000056BC, 0x00002AC2, 0x00000003, 0x0004007C, 0x0000000D, 0x00003F73, 0x000056BC, + 0x00050050, 0x00000013, 0x00004FB1, 0x00003F73, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3D, + 0x00004FB1, 0x00004FB1, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000200F9, 0x00003F63, + 0x000200F8, 0x00003F63, 0x000F00F5, 0x0000001D, 0x00002BB0, 0x00005A3D, 0x00004BFE, 0x00003095, + 0x000038FC, 0x000026A2, 0x00001CC1, 0x0000235A, 0x00001CC0, 0x00002359, 0x00002001, 0x00002358, + 0x00002039, 0x000F00F5, 0x0000001D, 0x00003811, 0x00002D9B, 0x00004BFE, 0x00004B2E, 0x000038FC, + 0x0000413B, 0x00001CC1, 0x00003DE5, 0x00001CC0, 0x00004129, 0x00002001, 0x00003920, 0x00002039, + 0x000F00F5, 0x0000001D, 0x00003B89, 0x00002D9A, 0x00004BFE, 0x00004B2D, 0x000038FC, 0x0000413A, + 0x00001CC1, 0x00003DE4, 0x00001CC0, 0x00004128, 0x00002001, 0x0000391F, 0x00002039, 0x000F00F5, + 0x0000001D, 0x000038BC, 0x00002D99, 0x00004BFE, 0x00004B2C, 0x000038FC, 0x00004139, 0x00001CC1, + 0x00003DE3, 0x00001CC0, 0x00004127, 0x00002001, 0x0000391E, 0x00002039, 0x000200F9, 0x00005312, + 0x000200F8, 0x00003B68, 0x000500AA, 0x00000009, 0x00005453, 0x0000199B, 0x00000A10, 0x000300F7, + 0x00004F29, 0x00000002, 0x000400FA, 0x00005453, 0x0000262B, 0x00002F68, 0x000200F8, 0x00002F68, + 0x00060041, 0x00000288, 0x00004BD6, 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, + 0x00005D51, 0x00004BD6, 0x00050080, 0x0000000B, 0x00002DD8, 0x00003FF8, 0x00000A0D, 0x00060041, + 0x00000288, 0x00001919, 0x00000CC7, 0x00000A0B, 0x00002DD8, 0x0004003D, 0x0000000B, 0x00005C85, + 0x00001919, 0x00050080, 0x0000000B, 0x00002DD9, 0x00003FF8, 0x0000199B, 0x00060041, 0x00000288, + 0x0000191A, 0x00000CC7, 0x00000A0B, 0x00002DD9, 0x0004003D, 0x0000000B, 0x00005C86, 0x0000191A, + 0x00050080, 0x0000000B, 0x00002DDA, 0x00002DD9, 0x00000A0D, 0x00060041, 0x00000288, 0x0000600E, + 0x00000CC7, 0x00000A0B, 0x00002DDA, 0x0004003D, 0x0000000B, 0x0000374F, 0x0000600E, 0x00070050, + 0x00000017, 0x00004CDA, 0x00005D51, 0x00005C85, 0x00005C86, 0x0000374F, 0x00050084, 0x0000000B, + 0x0000429B, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000036B1, 0x00003FF8, 0x0000429B, + 0x00060041, 0x00000288, 0x00003B8A, 0x00000CC7, 0x00000A0B, 0x000036B1, 0x0004003D, 0x0000000B, + 0x00005C87, 0x00003B8A, 0x00050080, 0x0000000B, 0x00002DDB, 0x000036B1, 0x00000A0D, 0x00060041, + 0x00000288, 0x00001952, 0x00000CC7, 0x00000A0B, 0x00002DDB, 0x0004003D, 0x0000000B, 0x00005E66, + 0x00001952, 0x00050084, 0x0000000B, 0x00001865, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, + 0x000020AC, 0x00003FF8, 0x00001865, 0x00060041, 0x00000288, 0x00003B8B, 0x00000CC7, 0x00000A0B, + 0x000020AC, 0x0004003D, 0x0000000B, 0x00005C88, 0x00003B8B, 0x00050080, 0x0000000B, 0x00002DDC, + 0x000020AC, 0x00000A0D, 0x00060041, 0x00000288, 0x0000600F, 0x00000CC7, 0x00000A0B, 0x00002DDC, + 0x0004003D, 0x0000000B, 0x0000400A, 0x0000600F, 0x00070050, 0x00000017, 0x0000513A, 0x00005C87, + 0x00005E66, 0x00005C88, 0x0000400A, 0x000200F9, 0x00004F29, 0x000200F8, 0x0000262B, 0x00060041, + 0x00000288, 0x0000554C, 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D52, + 0x0000554C, 0x00050080, 0x0000000B, 0x00002DDD, 0x00003FF8, 0x00000A0D, 0x00060041, 0x00000288, + 0x0000191B, 0x00000CC7, 0x00000A0B, 0x00002DDD, 0x0004003D, 0x0000000B, 0x00005C89, 0x0000191B, + 0x00050080, 0x0000000B, 0x00002DDE, 0x00003FF8, 0x00000A10, 0x00060041, 0x00000288, 0x0000191C, + 0x00000CC7, 0x00000A0B, 0x00002DDE, 0x0004003D, 0x0000000B, 0x00005C8A, 0x0000191C, 0x00050080, + 0x0000000B, 0x00002DDF, 0x00003FF8, 0x00000A13, 0x00060041, 0x00000288, 0x00006010, 0x00000CC7, + 0x00000A0B, 0x00002DDF, 0x0004003D, 0x0000000B, 0x00003703, 0x00006010, 0x00070050, 0x00000017, + 0x00004AE2, 0x00005D52, 0x00005C89, 0x00005C8A, 0x00003703, 0x00050080, 0x0000000B, 0x000057E8, + 0x00003FF8, 0x00000A16, 0x00060041, 0x00000288, 0x0000604E, 0x00000CC7, 0x00000A0B, 0x000057E8, + 0x0004003D, 0x0000000B, 0x00005C8B, 0x0000604E, 0x00050080, 0x0000000B, 0x00002DE0, 0x00003FF8, + 0x00000A19, 0x00060041, 0x00000288, 0x0000191D, 0x00000CC7, 0x00000A0B, 0x00002DE0, 0x0004003D, + 0x0000000B, 0x00005C8C, 0x0000191D, 0x00050080, 0x0000000B, 0x00002DE1, 0x00003FF8, 0x00000A1C, + 0x00060041, 0x00000288, 0x0000191E, 0x00000CC7, 0x00000A0B, 0x00002DE1, 0x0004003D, 0x0000000B, + 0x00005C8D, 0x0000191E, 0x00050080, 0x0000000B, 0x00002DE2, 0x00003FF8, 0x00000A1F, 0x00060041, + 0x00000288, 0x00006011, 0x00000CC7, 0x00000A0B, 0x00002DE2, 0x0004003D, 0x0000000B, 0x0000400B, + 0x00006011, 0x00070050, 0x00000017, 0x0000513B, 0x00005C8B, 0x00005C8C, 0x00005C8D, 0x0000400B, + 0x000200F9, 0x00004F29, 0x000200F8, 0x00004F29, 0x000700F5, 0x00000017, 0x00002BD0, 0x0000513B, + 0x0000262B, 0x0000513A, 0x00002F68, 0x000700F5, 0x00000017, 0x00003723, 0x00004AE2, 0x0000262B, + 0x00004CDA, 0x00002F68, 0x000300F7, 0x00004F2A, 0x00000000, 0x000700FB, 0x00002180, 0x00004F59, + 0x00000005, 0x0000215B, 0x00000007, 0x0000203A, 0x000200F8, 0x0000203A, 0x00050051, 0x0000000B, + 0x00005F5D, 0x00003723, 0x00000000, 0x0006000C, 0x00000013, 0x0000606E, 0x00000001, 0x0000003E, + 0x00005F5D, 0x00050051, 0x0000000D, 0x0000278A, 0x0000606E, 0x00000000, 0x00050051, 0x0000000D, + 0x00003EC4, 0x0000606E, 0x00000001, 0x00050051, 0x0000000B, 0x0000428D, 0x00003723, 0x00000001, + 0x0006000C, 0x00000013, 0x00003D01, 0x00000001, 0x0000003E, 0x0000428D, 0x00050051, 0x0000000D, + 0x0000278B, 0x00003D01, 0x00000000, 0x00050051, 0x0000000D, 0x0000445B, 0x00003D01, 0x00000001, + 0x00070050, 0x0000001D, 0x00003921, 0x0000278A, 0x00003EC4, 0x0000278B, 0x0000445B, 0x00050051, + 0x0000000B, 0x0000438F, 0x00003723, 0x00000002, 0x0006000C, 0x00000013, 0x00004680, 0x00000001, + 0x0000003E, 0x0000438F, 0x00050051, 0x0000000D, 0x0000278C, 0x00004680, 0x00000000, 0x00050051, + 0x0000000D, 0x00003EC5, 0x00004680, 0x00000001, 0x00050051, 0x0000000B, 0x0000428E, 0x00003723, + 0x00000003, 0x0006000C, 0x00000013, 0x00003D02, 0x00000001, 0x0000003E, 0x0000428E, 0x00050051, + 0x0000000D, 0x0000278D, 0x00003D02, 0x00000000, 0x00050051, 0x0000000D, 0x0000445C, 0x00003D02, + 0x00000001, 0x00070050, 0x0000001D, 0x00003922, 0x0000278C, 0x00003EC5, 0x0000278D, 0x0000445C, + 0x00050051, 0x0000000B, 0x00004390, 0x00002BD0, 0x00000000, 0x0006000C, 0x00000013, 0x00004681, + 0x00000001, 0x0000003E, 0x00004390, 0x00050051, 0x0000000D, 0x0000278E, 0x00004681, 0x00000000, + 0x00050051, 0x0000000D, 0x00003EC6, 0x00004681, 0x00000001, 0x00050051, 0x0000000B, 0x0000428F, + 0x00002BD0, 0x00000001, 0x0006000C, 0x00000013, 0x00003D03, 0x00000001, 0x0000003E, 0x0000428F, + 0x00050051, 0x0000000D, 0x0000278F, 0x00003D03, 0x00000000, 0x00050051, 0x0000000D, 0x0000445D, + 0x00003D03, 0x00000001, 0x00070050, 0x0000001D, 0x00003923, 0x0000278E, 0x00003EC6, 0x0000278F, + 0x0000445D, 0x00050051, 0x0000000B, 0x00004391, 0x00002BD0, 0x00000002, 0x0006000C, 0x00000013, + 0x00004682, 0x00000001, 0x0000003E, 0x00004391, 0x00050051, 0x0000000D, 0x00002790, 0x00004682, + 0x00000000, 0x00050051, 0x0000000D, 0x00003EC7, 0x00004682, 0x00000001, 0x00050051, 0x0000000B, + 0x00004290, 0x00002BD0, 0x00000003, 0x0006000C, 0x00000013, 0x00003D04, 0x00000001, 0x0000003E, + 0x00004290, 0x00050051, 0x0000000D, 0x00002791, 0x00003D04, 0x00000000, 0x00050051, 0x0000000D, + 0x000050C5, 0x00003D04, 0x00000001, 0x00070050, 0x0000001D, 0x0000235B, 0x00002790, 0x00003EC7, + 0x00002791, 0x000050C5, 0x000200F9, 0x00004F2A, 0x000200F8, 0x0000215B, 0x0007004F, 0x00000011, + 0x000025FE, 0x00003723, 0x00003723, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x00005B3F, + 0x000025FE, 0x0009004F, 0x0000001A, 0x000060DA, 0x00005B3F, 0x00005B3F, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048B9, 0x000060DA, 0x00000122, 0x000500C3, + 0x0000001A, 0x00003D99, 0x000048B9, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AC7, 0x00003D99, + 0x0005008E, 0x0000001D, 0x00004733, 0x00002AC7, 0x000007FE, 0x0007000C, 0x0000001D, 0x0000629A, + 0x00000001, 0x00000028, 0x00000504, 0x00004733, 0x0007004F, 0x00000011, 0x00003774, 0x00003723, + 0x00003723, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C8, 0x00003774, 0x0009004F, + 0x0000001A, 0x000060DB, 0x000024C8, 0x000024C8, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C4, 0x0000001A, 0x000048BA, 0x000060DB, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D9A, + 0x000048BA, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AC8, 0x00003D9A, 0x0005008E, 0x0000001D, + 0x00004734, 0x00002AC8, 0x000007FE, 0x0007000C, 0x0000001D, 0x0000629B, 0x00000001, 0x00000028, + 0x00000504, 0x00004734, 0x0007004F, 0x00000011, 0x00003775, 0x00002BD0, 0x00002BD0, 0x00000000, + 0x00000001, 0x0004007C, 0x00000012, 0x000024C9, 0x00003775, 0x0009004F, 0x0000001A, 0x000060DC, + 0x000024C9, 0x000024C9, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, + 0x000048BB, 0x000060DC, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D9B, 0x000048BB, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002AC9, 0x00003D9B, 0x0005008E, 0x0000001D, 0x00004735, 0x00002AC9, + 0x000007FE, 0x0007000C, 0x0000001D, 0x0000629C, 0x00000001, 0x00000028, 0x00000504, 0x00004735, + 0x0007004F, 0x00000011, 0x00003776, 0x00002BD0, 0x00002BD0, 0x00000002, 0x00000003, 0x0004007C, + 0x00000012, 0x000024CA, 0x00003776, 0x0009004F, 0x0000001A, 0x000060DD, 0x000024CA, 0x000024CA, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048BC, 0x000060DD, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D9C, 0x000048BC, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002ACA, 0x00003D9C, 0x0005008E, 0x0000001D, 0x000053D2, 0x00002ACA, 0x000007FE, 0x0007000C, + 0x0000001D, 0x00004365, 0x00000001, 0x00000028, 0x00000504, 0x000053D2, 0x000200F9, 0x00004F2A, + 0x000200F8, 0x00004F59, 0x0007004F, 0x00000011, 0x0000262C, 0x00003723, 0x00003723, 0x00000000, + 0x00000001, 0x0004007C, 0x00000013, 0x0000515D, 0x0000262C, 0x00050051, 0x0000000D, 0x00001B88, + 0x0000515D, 0x00000000, 0x00050051, 0x0000000D, 0x00003473, 0x0000515D, 0x00000001, 0x00070050, + 0x0000001D, 0x00004291, 0x00001B88, 0x00003473, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, + 0x000041E1, 0x00003723, 0x00003723, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x00003766, + 0x000041E1, 0x00050051, 0x0000000D, 0x00001B89, 0x00003766, 0x00000000, 0x00050051, 0x0000000D, + 0x00003474, 0x00003766, 0x00000001, 0x00070050, 0x0000001D, 0x00004292, 0x00001B89, 0x00003474, + 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041E2, 0x00002BD0, 0x00002BD0, 0x00000000, + 0x00000001, 0x0004007C, 0x00000013, 0x00003767, 0x000041E2, 0x00050051, 0x0000000D, 0x00001B8A, + 0x00003767, 0x00000000, 0x00050051, 0x0000000D, 0x00003475, 0x00003767, 0x00000001, 0x00070050, + 0x0000001D, 0x00004293, 0x00001B8A, 0x00003475, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, + 0x000041E3, 0x00002BD0, 0x00002BD0, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x00003768, + 0x000041E3, 0x00050051, 0x0000000D, 0x00001B8B, 0x00003768, 0x00000000, 0x00050051, 0x0000000D, + 0x0000410B, 0x00003768, 0x00000001, 0x00070050, 0x0000001D, 0x0000235C, 0x00001B8B, 0x0000410B, + 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F2A, 0x000200F8, 0x00004F2A, 0x000900F5, 0x0000001D, + 0x00002BB1, 0x0000235C, 0x00004F59, 0x00004365, 0x0000215B, 0x0000235B, 0x0000203A, 0x000900F5, + 0x0000001D, 0x00003812, 0x00004293, 0x00004F59, 0x0000629C, 0x0000215B, 0x00003923, 0x0000203A, + 0x000900F5, 0x0000001D, 0x00003B8C, 0x00004292, 0x00004F59, 0x0000629B, 0x0000215B, 0x00003922, + 0x0000203A, 0x000900F5, 0x0000001D, 0x000038BD, 0x00004291, 0x00004F59, 0x0000629A, 0x0000215B, + 0x00003921, 0x0000203A, 0x000200F9, 0x00005312, 0x000200F8, 0x00005312, 0x000700F5, 0x0000001D, + 0x00002BB2, 0x00002BB1, 0x00004F2A, 0x00002BB0, 0x00003F63, 0x000700F5, 0x0000001D, 0x00003813, + 0x00003812, 0x00004F2A, 0x00003811, 0x00003F63, 0x000700F5, 0x0000001D, 0x00003297, 0x00003B8C, + 0x00004F2A, 0x00003B89, 0x00003F63, 0x000700F5, 0x0000001D, 0x0000367C, 0x000038BD, 0x00004F2A, + 0x000038BC, 0x00003F63, 0x00050081, 0x0000001D, 0x0000435B, 0x0000435A, 0x0000367C, 0x00050081, + 0x0000001D, 0x00005B03, 0x00005B02, 0x00003297, 0x00050081, 0x0000001D, 0x00002523, 0x00001C28, + 0x00003813, 0x00050081, 0x0000001D, 0x00001E77, 0x000025AA, 0x00002BB2, 0x000200F9, 0x00005EC8, + 0x000200F8, 0x00005EC8, 0x000700F5, 0x0000001D, 0x00002BB3, 0x00005113, 0x00005310, 0x00001E77, + 0x00005312, 0x000700F5, 0x0000001D, 0x00003814, 0x00001F92, 0x00005310, 0x00002523, 0x00005312, + 0x000700F5, 0x0000001D, 0x00003B31, 0x00005B01, 0x00005310, 0x00005B03, 0x00005312, 0x000700F5, + 0x0000001D, 0x00003B8D, 0x00004359, 0x00005310, 0x0000435B, 0x00005312, 0x000700F5, 0x0000000D, + 0x000038BE, 0x00005A1D, 0x00005310, 0x00002F3A, 0x00005312, 0x000200F9, 0x00005313, 0x000200F8, + 0x00005313, 0x000700F5, 0x0000001D, 0x00002BB4, 0x00002BA9, 0x0000530F, 0x00002BB3, 0x00005EC8, + 0x000700F5, 0x0000001D, 0x00003815, 0x0000380A, 0x0000530F, 0x00003814, 0x00005EC8, 0x000700F5, + 0x0000001D, 0x00003B32, 0x000035EC, 0x0000530F, 0x00003B31, 0x00005EC8, 0x000700F5, 0x0000001D, + 0x0000338C, 0x000020D3, 0x0000530F, 0x00003B8D, 0x00005EC8, 0x000700F5, 0x0000000D, 0x00002EA8, + 0x00002B2C, 0x0000530F, 0x000038BE, 0x00005EC8, 0x0005008E, 0x0000001D, 0x00005A74, 0x0000338C, + 0x00002EA8, 0x0005008E, 0x0000001D, 0x000019CC, 0x00003B32, 0x00002EA8, 0x0005008E, 0x0000001D, + 0x0000306F, 0x00003815, 0x00002EA8, 0x0005008E, 0x0000001D, 0x00003432, 0x00002BB4, 0x00002EA8, + 0x000300F7, 0x00003F64, 0x00000002, 0x000400FA, 0x00001D59, 0x00002741, 0x00003F64, 0x000200F8, + 0x00002741, 0x0009004F, 0x0000001D, 0x00003AEE, 0x00005A74, 0x00005A74, 0x00000002, 0x00000001, + 0x00000000, 0x00000003, 0x0009004F, 0x0000001D, 0x00003A07, 0x000019CC, 0x000019CC, 0x00000002, + 0x00000001, 0x00000000, 0x00000003, 0x0009004F, 0x0000001D, 0x00001CE6, 0x0000306F, 0x0000306F, + 0x00000002, 0x00000001, 0x00000000, 0x00000003, 0x0009004F, 0x0000001D, 0x00003EEF, 0x00003432, + 0x00003432, 0x00000002, 0x00000001, 0x00000000, 0x00000003, 0x000200F9, 0x00003F64, 0x000200F8, + 0x00003F64, 0x000700F5, 0x0000001D, 0x00002BB5, 0x00003432, 0x00005313, 0x00003EEF, 0x00002741, + 0x000700F5, 0x0000001D, 0x00003816, 0x0000306F, 0x00005313, 0x00001CE6, 0x00002741, 0x000700F5, + 0x0000001D, 0x00003B57, 0x000019CC, 0x00005313, 0x00003A07, 0x00002741, 0x000700F5, 0x0000001D, + 0x00003A49, 0x00005A74, 0x00005313, 0x00003AEE, 0x00002741, 0x000300F7, 0x00004992, 0x00000000, + 0x000F00FB, 0x00005093, 0x00001CCE, 0x00000003, 0x000045EB, 0x00000004, 0x00001934, 0x00000005, + 0x00001933, 0x0000000A, 0x00001CCD, 0x0000000F, 0x00003167, 0x00000018, 0x00002514, 0x000200F8, + 0x00002514, 0x00050051, 0x0000000D, 0x00003AC1, 0x00003A49, 0x00000000, 0x00050051, 0x0000000D, + 0x00002825, 0x00003B57, 0x00000000, 0x00050051, 0x0000000D, 0x00001DD9, 0x00003816, 0x00000000, + 0x00050051, 0x0000000D, 0x000019A5, 0x00002BB5, 0x00000000, 0x00070050, 0x0000001D, 0x00001D37, + 0x00003AC1, 0x00002825, 0x00001DD9, 0x000019A5, 0x0008000C, 0x0000001D, 0x00003846, 0x00000001, + 0x0000002B, 0x00001D37, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, 0x00003577, 0x00003846, + 0x0000022D, 0x00050081, 0x0000001D, 0x00002E40, 0x00003577, 0x00000145, 0x0004006D, 0x00000017, + 0x00001F0B, 0x00002E40, 0x0007004F, 0x00000011, 0x000018D9, 0x00001F0B, 0x00001F0B, 0x00000000, + 0x00000002, 0x0007004F, 0x00000011, 0x00002750, 0x00001F0B, 0x00001F0B, 0x00000001, 0x00000003, + 0x000500C4, 0x00000011, 0x00003546, 0x00002750, 0x00000867, 0x000500C5, 0x00000011, 0x00003D25, + 0x000018D9, 0x00003546, 0x000200F9, 0x00004992, 0x000200F8, 0x00003167, 0x0008000C, 0x0000001D, + 0x00001C8F, 0x00000001, 0x0000002B, 0x00003A49, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, + 0x00004F73, 0x00001C8F, 0x000001C1, 0x00050081, 0x0000001D, 0x00002E66, 0x00004F73, 0x00000145, + 0x0004006D, 0x00000017, 0x00001DD7, 0x00002E66, 0x00050051, 0x0000000B, 0x000021FC, 0x00001DD7, + 0x00000000, 0x00050051, 0x0000000B, 0x00002FDB, 0x00001DD7, 0x00000001, 0x000500C4, 0x0000000B, + 0x00002D29, 0x00002FDB, 0x00000A17, 0x000500C5, 0x0000000B, 0x00004D66, 0x000021FC, 0x00002D29, + 0x00050051, 0x0000000B, 0x000053E4, 0x00001DD7, 0x00000002, 0x000500C4, 0x0000000B, 0x00002170, + 0x000053E4, 0x00000A23, 0x000500C5, 0x0000000B, 0x00004D67, 0x00004D66, 0x00002170, 0x00050051, + 0x0000000B, 0x000053E5, 0x00001DD7, 0x00000003, 0x000500C4, 0x0000000B, 0x00001C7C, 0x000053E5, + 0x00000A2F, 0x000500C5, 0x0000000B, 0x00002427, 0x00004D67, 0x00001C7C, 0x0008000C, 0x0000001D, + 0x00001D62, 0x00000001, 0x0000002B, 0x00003B57, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, + 0x00002048, 0x00001D62, 0x000001C1, 0x00050081, 0x0000001D, 0x00002E67, 0x00002048, 0x00000145, + 0x0004006D, 0x00000017, 0x00001DDA, 0x00002E67, 0x00050051, 0x0000000B, 0x000021FD, 0x00001DDA, + 0x00000000, 0x00050051, 0x0000000B, 0x00002FDC, 0x00001DDA, 0x00000001, 0x000500C4, 0x0000000B, + 0x00002D2A, 0x00002FDC, 0x00000A17, 0x000500C5, 0x0000000B, 0x00004D68, 0x000021FD, 0x00002D2A, + 0x00050051, 0x0000000B, 0x000053E6, 0x00001DDA, 0x00000002, 0x000500C4, 0x0000000B, 0x00002171, + 0x000053E6, 0x00000A23, 0x000500C5, 0x0000000B, 0x00004D69, 0x00004D68, 0x00002171, 0x00050051, + 0x0000000B, 0x000053E7, 0x00001DDA, 0x00000003, 0x000500C4, 0x0000000B, 0x000029F9, 0x000053E7, + 0x00000A2F, 0x000500C5, 0x0000000B, 0x00004A41, 0x00004D69, 0x000029F9, 0x000500C4, 0x0000000B, + 0x000058C9, 0x00004A41, 0x00000A3A, 0x000500C5, 0x0000000B, 0x0000186E, 0x00002427, 0x000058C9, + 0x0008000C, 0x0000001D, 0x00001D63, 0x00000001, 0x0000002B, 0x00003816, 0x00000B7A, 0x00000505, + 0x0005008E, 0x0000001D, 0x00002049, 0x00001D63, 0x000001C1, 0x00050081, 0x0000001D, 0x00002E69, + 0x00002049, 0x00000145, 0x0004006D, 0x00000017, 0x00001DDB, 0x00002E69, 0x00050051, 0x0000000B, + 0x000021FE, 0x00001DDB, 0x00000000, 0x00050051, 0x0000000B, 0x00002FDD, 0x00001DDB, 0x00000001, + 0x000500C4, 0x0000000B, 0x00002D2B, 0x00002FDD, 0x00000A17, 0x000500C5, 0x0000000B, 0x00004D6A, + 0x000021FE, 0x00002D2B, 0x00050051, 0x0000000B, 0x000053E8, 0x00001DDB, 0x00000002, 0x000500C4, + 0x0000000B, 0x00002172, 0x000053E8, 0x00000A23, 0x000500C5, 0x0000000B, 0x00004D6B, 0x00004D6A, + 0x00002172, 0x00050051, 0x0000000B, 0x000053E9, 0x00001DDB, 0x00000003, 0x000500C4, 0x0000000B, + 0x00001C7D, 0x000053E9, 0x00000A2F, 0x000500C5, 0x0000000B, 0x00002428, 0x00004D6B, 0x00001C7D, + 0x0008000C, 0x0000001D, 0x00001D64, 0x00000001, 0x0000002B, 0x00002BB5, 0x00000B7A, 0x00000505, + 0x0005008E, 0x0000001D, 0x0000204A, 0x00001D64, 0x000001C1, 0x00050081, 0x0000001D, 0x00002E6A, + 0x0000204A, 0x00000145, 0x0004006D, 0x00000017, 0x00001DDC, 0x00002E6A, 0x00050051, 0x0000000B, + 0x000021FF, 0x00001DDC, 0x00000000, 0x00050051, 0x0000000B, 0x00002FDE, 0x00001DDC, 0x00000001, + 0x000500C4, 0x0000000B, 0x00002D2C, 0x00002FDE, 0x00000A17, 0x000500C5, 0x0000000B, 0x00004D6C, + 0x000021FF, 0x00002D2C, 0x00050051, 0x0000000B, 0x000053EA, 0x00001DDC, 0x00000002, 0x000500C4, + 0x0000000B, 0x00002173, 0x000053EA, 0x00000A23, 0x000500C5, 0x0000000B, 0x00004D6D, 0x00004D6C, + 0x00002173, 0x00050051, 0x0000000B, 0x000053EB, 0x00001DDC, 0x00000003, 0x000500C4, 0x0000000B, + 0x000029FA, 0x000053EB, 0x00000A2F, 0x000500C5, 0x0000000B, 0x00004A42, 0x00004D6D, 0x000029FA, + 0x000500C4, 0x0000000B, 0x00005DAA, 0x00004A42, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00004649, + 0x00002428, 0x00005DAA, 0x00050050, 0x00000011, 0x000053DD, 0x0000186E, 0x00004649, 0x000200F9, + 0x00004992, 0x000200F8, 0x00001CCD, 0x00050051, 0x0000000D, 0x00004DAD, 0x00003A49, 0x00000000, + 0x00050051, 0x0000000D, 0x00002826, 0x00003A49, 0x00000001, 0x00050051, 0x0000000D, 0x00001DDD, + 0x00003B57, 0x00000000, 0x00050051, 0x0000000D, 0x000019A6, 0x00003B57, 0x00000001, 0x00070050, + 0x0000001D, 0x00001D38, 0x00004DAD, 0x00002826, 0x00001DDD, 0x000019A6, 0x0008000C, 0x0000001D, + 0x00003847, 0x00000001, 0x0000002B, 0x00001D38, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, + 0x00003578, 0x00003847, 0x00000540, 0x00050081, 0x0000001D, 0x00002E6B, 0x00003578, 0x00000145, + 0x0004006D, 0x00000017, 0x00001DDE, 0x00002E6B, 0x00050051, 0x0000000B, 0x00002200, 0x00001DDE, + 0x00000000, 0x00050051, 0x0000000B, 0x00002FDF, 0x00001DDE, 0x00000001, 0x000500C4, 0x0000000B, + 0x00002D2D, 0x00002FDF, 0x00000A23, 0x000500C5, 0x0000000B, 0x00004D6E, 0x00002200, 0x00002D2D, + 0x00050051, 0x0000000B, 0x000053EC, 0x00001DDE, 0x00000002, 0x000500C4, 0x0000000B, 0x00002174, + 0x000053EC, 0x00000A3B, 0x000500C5, 0x0000000B, 0x00004D6F, 0x00004D6E, 0x00002174, 0x00050051, + 0x0000000B, 0x000053ED, 0x00001DDE, 0x00000003, 0x000500C4, 0x0000000B, 0x00002175, 0x000053ED, + 0x00000A53, 0x000500C5, 0x0000000B, 0x000044DD, 0x00004D6F, 0x00002175, 0x00050051, 0x0000000D, + 0x00004E80, 0x00003816, 0x00000000, 0x00050051, 0x0000000D, 0x00005CB2, 0x00003816, 0x00000001, + 0x00050051, 0x0000000D, 0x00001DDF, 0x00002BB5, 0x00000000, 0x00050051, 0x0000000D, 0x000019A7, + 0x00002BB5, 0x00000001, 0x00070050, 0x0000001D, 0x00001D39, 0x00004E80, 0x00005CB2, 0x00001DDF, + 0x000019A7, 0x0008000C, 0x0000001D, 0x00003848, 0x00000001, 0x0000002B, 0x00001D39, 0x00000B7A, + 0x00000505, 0x0005008E, 0x0000001D, 0x00003579, 0x00003848, 0x00000540, 0x00050081, 0x0000001D, + 0x00002E6C, 0x00003579, 0x00000145, 0x0004006D, 0x00000017, 0x00001DE0, 0x00002E6C, 0x00050051, + 0x0000000B, 0x00002201, 0x00001DE0, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE0, 0x00001DE0, + 0x00000001, 0x000500C4, 0x0000000B, 0x00002D2E, 0x00002FE0, 0x00000A23, 0x000500C5, 0x0000000B, + 0x00004D70, 0x00002201, 0x00002D2E, 0x00050051, 0x0000000B, 0x000053EE, 0x00001DE0, 0x00000002, + 0x000500C4, 0x0000000B, 0x00002176, 0x000053EE, 0x00000A3B, 0x000500C5, 0x0000000B, 0x00004D71, + 0x00004D70, 0x00002176, 0x00050051, 0x0000000B, 0x000053EF, 0x00001DE0, 0x00000003, 0x000500C4, + 0x0000000B, 0x0000215D, 0x000053EF, 0x00000A53, 0x000500C5, 0x0000000B, 0x00005202, 0x00004D71, + 0x0000215D, 0x00050050, 0x00000011, 0x000053DE, 0x000044DD, 0x00005202, 0x000200F9, 0x00004992, + 0x000200F8, 0x00001933, 0x0008004F, 0x00000018, 0x000021CF, 0x00003A49, 0x00003A49, 0x00000000, + 0x00000001, 0x00000002, 0x0008000C, 0x00000018, 0x00001847, 0x00000001, 0x0000002B, 0x000021CF, + 0x00000A2D, 0x00000A18, 0x00050085, 0x00000018, 0x00001BC1, 0x00001847, 0x000003BE, 0x00050081, + 0x00000018, 0x00001F1A, 0x00001BC1, 0x000003AB, 0x0004006D, 0x00000014, 0x00002752, 0x00001F1A, + 0x00050051, 0x0000000B, 0x00002202, 0x00002752, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE1, + 0x00002752, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D2F, 0x00002FE1, 0x00000A1A, 0x000500C5, + 0x0000000B, 0x00004D72, 0x00002202, 0x00002D2F, 0x00050051, 0x0000000B, 0x000053F0, 0x00002752, + 0x00000002, 0x000500C4, 0x0000000B, 0x0000214A, 0x000053F0, 0x00000A29, 0x000500C5, 0x0000000B, + 0x00004143, 0x00004D72, 0x0000214A, 0x0008004F, 0x00000018, 0x000022A2, 0x00003B57, 0x00003B57, + 0x00000000, 0x00000001, 0x00000002, 0x0008000C, 0x00000018, 0x00004CD4, 0x00000001, 0x0000002B, + 0x000022A2, 0x00000A2D, 0x00000A18, 0x00050085, 0x00000018, 0x00001BC2, 0x00004CD4, 0x000003BE, + 0x00050081, 0x00000018, 0x00001F1B, 0x00001BC2, 0x000003AB, 0x0004006D, 0x00000014, 0x00002753, + 0x00001F1B, 0x00050051, 0x0000000B, 0x00002203, 0x00002753, 0x00000000, 0x00050051, 0x0000000B, + 0x00002FE2, 0x00002753, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D30, 0x00002FE2, 0x00000A1A, + 0x000500C5, 0x0000000B, 0x00004D73, 0x00002203, 0x00002D30, 0x00050051, 0x0000000B, 0x000053F1, + 0x00002753, 0x00000002, 0x000500C4, 0x0000000B, 0x000029FB, 0x000053F1, 0x00000A29, 0x000500C5, + 0x0000000B, 0x00004A43, 0x00004D73, 0x000029FB, 0x000500C4, 0x0000000B, 0x00005D97, 0x00004A43, + 0x00000A3A, 0x000500C5, 0x0000000B, 0x0000358A, 0x00004143, 0x00005D97, 0x0008004F, 0x00000018, + 0x000022A3, 0x00003816, 0x00003816, 0x00000000, 0x00000001, 0x00000002, 0x0008000C, 0x00000018, + 0x00004CD5, 0x00000001, 0x0000002B, 0x000022A3, 0x00000A2D, 0x00000A18, 0x00050085, 0x00000018, + 0x00001BC3, 0x00004CD5, 0x000003BE, 0x00050081, 0x00000018, 0x00001F1C, 0x00001BC3, 0x000003AB, + 0x0004006D, 0x00000014, 0x00002754, 0x00001F1C, 0x00050051, 0x0000000B, 0x00002204, 0x00002754, + 0x00000000, 0x00050051, 0x0000000B, 0x00002FE3, 0x00002754, 0x00000001, 0x000500C4, 0x0000000B, + 0x00002D31, 0x00002FE3, 0x00000A1A, 0x000500C5, 0x0000000B, 0x00004D74, 0x00002204, 0x00002D31, + 0x00050051, 0x0000000B, 0x000053F2, 0x00002754, 0x00000002, 0x000500C4, 0x0000000B, 0x0000214B, + 0x000053F2, 0x00000A29, 0x000500C5, 0x0000000B, 0x00004144, 0x00004D74, 0x0000214B, 0x0008004F, + 0x00000018, 0x000022A4, 0x00002BB5, 0x00002BB5, 0x00000000, 0x00000001, 0x00000002, 0x0008000C, + 0x00000018, 0x00004CDB, 0x00000001, 0x0000002B, 0x000022A4, 0x00000A2D, 0x00000A18, 0x00050085, + 0x00000018, 0x00001BC4, 0x00004CDB, 0x000003BE, 0x00050081, 0x00000018, 0x00001F1D, 0x00001BC4, + 0x000003AB, 0x0004006D, 0x00000014, 0x00002755, 0x00001F1D, 0x00050051, 0x0000000B, 0x00002205, + 0x00002755, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE4, 0x00002755, 0x00000001, 0x000500C4, + 0x0000000B, 0x00002D32, 0x00002FE4, 0x00000A1A, 0x000500C5, 0x0000000B, 0x00004D75, 0x00002205, + 0x00002D32, 0x00050051, 0x0000000B, 0x000053F3, 0x00002755, 0x00000002, 0x000500C4, 0x0000000B, + 0x000029FC, 0x000053F3, 0x00000A29, 0x000500C5, 0x0000000B, 0x00004A44, 0x00004D75, 0x000029FC, + 0x000500C4, 0x0000000B, 0x00005DAB, 0x00004A44, 0x00000A3A, 0x000500C5, 0x0000000B, 0x0000464A, + 0x00004144, 0x00005DAB, 0x00050050, 0x00000011, 0x000053DF, 0x0000358A, 0x0000464A, 0x000200F9, + 0x00004992, 0x000200F8, 0x00001934, 0x0008004F, 0x00000018, 0x000021D0, 0x00003A49, 0x00003A49, + 0x00000000, 0x00000001, 0x00000002, 0x0008000C, 0x00000018, 0x00001848, 0x00000001, 0x0000002B, + 0x000021D0, 0x00000A2D, 0x00000A18, 0x00050085, 0x00000018, 0x00001BC5, 0x00001848, 0x000001FF, + 0x00050081, 0x00000018, 0x00001F1E, 0x00001BC5, 0x000003AB, 0x0004006D, 0x00000014, 0x00002756, + 0x00001F1E, 0x00050051, 0x0000000B, 0x00002206, 0x00002756, 0x00000000, 0x00050051, 0x0000000B, + 0x00002FE5, 0x00002756, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D33, 0x00002FE5, 0x00000A1A, + 0x000500C5, 0x0000000B, 0x00004D76, 0x00002206, 0x00002D33, 0x00050051, 0x0000000B, 0x000053F4, + 0x00002756, 0x00000002, 0x000500C4, 0x0000000B, 0x0000214C, 0x000053F4, 0x00000A2C, 0x000500C5, + 0x0000000B, 0x00004145, 0x00004D76, 0x0000214C, 0x0008004F, 0x00000018, 0x000022A5, 0x00003B57, + 0x00003B57, 0x00000000, 0x00000001, 0x00000002, 0x0008000C, 0x00000018, 0x00004CDC, 0x00000001, + 0x0000002B, 0x000022A5, 0x00000A2D, 0x00000A18, 0x00050085, 0x00000018, 0x00001BC6, 0x00004CDC, + 0x000001FF, 0x00050081, 0x00000018, 0x00001F1F, 0x00001BC6, 0x000003AB, 0x0004006D, 0x00000014, + 0x00002757, 0x00001F1F, 0x00050051, 0x0000000B, 0x00002207, 0x00002757, 0x00000000, 0x00050051, + 0x0000000B, 0x00002FE6, 0x00002757, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D34, 0x00002FE6, + 0x00000A1A, 0x000500C5, 0x0000000B, 0x00004D77, 0x00002207, 0x00002D34, 0x00050051, 0x0000000B, + 0x000053F5, 0x00002757, 0x00000002, 0x000500C4, 0x0000000B, 0x000029FD, 0x000053F5, 0x00000A2C, + 0x000500C5, 0x0000000B, 0x00004A45, 0x00004D77, 0x000029FD, 0x000500C4, 0x0000000B, 0x00005D98, + 0x00004A45, 0x00000A3A, 0x000500C5, 0x0000000B, 0x0000358B, 0x00004145, 0x00005D98, 0x0008004F, + 0x00000018, 0x000022A6, 0x00003816, 0x00003816, 0x00000000, 0x00000001, 0x00000002, 0x0008000C, + 0x00000018, 0x00004CDD, 0x00000001, 0x0000002B, 0x000022A6, 0x00000A2D, 0x00000A18, 0x00050085, + 0x00000018, 0x00001BC7, 0x00004CDD, 0x000001FF, 0x00050081, 0x00000018, 0x00001F20, 0x00001BC7, + 0x000003AB, 0x0004006D, 0x00000014, 0x00002758, 0x00001F20, 0x00050051, 0x0000000B, 0x00002208, + 0x00002758, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE7, 0x00002758, 0x00000001, 0x000500C4, + 0x0000000B, 0x00002D35, 0x00002FE7, 0x00000A1A, 0x000500C5, 0x0000000B, 0x00004D78, 0x00002208, + 0x00002D35, 0x00050051, 0x0000000B, 0x000053F6, 0x00002758, 0x00000002, 0x000500C4, 0x0000000B, + 0x0000214D, 0x000053F6, 0x00000A2C, 0x000500C5, 0x0000000B, 0x00004146, 0x00004D78, 0x0000214D, + 0x0008004F, 0x00000018, 0x000022A8, 0x00002BB5, 0x00002BB5, 0x00000000, 0x00000001, 0x00000002, + 0x0008000C, 0x00000018, 0x00004CDE, 0x00000001, 0x0000002B, 0x000022A8, 0x00000A2D, 0x00000A18, + 0x00050085, 0x00000018, 0x00001BC8, 0x00004CDE, 0x000001FF, 0x00050081, 0x00000018, 0x00001F21, + 0x00001BC8, 0x000003AB, 0x0004006D, 0x00000014, 0x00002759, 0x00001F21, 0x00050051, 0x0000000B, + 0x00002209, 0x00002759, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE8, 0x00002759, 0x00000001, + 0x000500C4, 0x0000000B, 0x00002D36, 0x00002FE8, 0x00000A1A, 0x000500C5, 0x0000000B, 0x00004D79, + 0x00002209, 0x00002D36, 0x00050051, 0x0000000B, 0x000053F7, 0x00002759, 0x00000002, 0x000500C4, + 0x0000000B, 0x000029FE, 0x000053F7, 0x00000A2C, 0x000500C5, 0x0000000B, 0x00004A46, 0x00004D79, + 0x000029FE, 0x000500C4, 0x0000000B, 0x00005DAC, 0x00004A46, 0x00000A3A, 0x000500C5, 0x0000000B, + 0x0000464B, 0x00004146, 0x00005DAC, 0x00050050, 0x00000011, 0x000053E0, 0x0000358B, 0x0000464B, + 0x000200F9, 0x00004992, 0x000200F8, 0x000045EB, 0x0008000C, 0x0000001D, 0x000022A9, 0x00000001, + 0x0000002B, 0x00003A49, 0x00000B7A, 0x00000505, 0x00050085, 0x0000001D, 0x00004580, 0x000022A9, + 0x00000809, 0x00050081, 0x0000001D, 0x00001F22, 0x00004580, 0x00000145, 0x0004006D, 0x00000017, + 0x0000275A, 0x00001F22, 0x00050051, 0x0000000B, 0x0000220A, 0x0000275A, 0x00000000, 0x00050051, + 0x0000000B, 0x00002FE9, 0x0000275A, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D37, 0x00002FE9, + 0x00000A1A, 0x000500C5, 0x0000000B, 0x00004D7A, 0x0000220A, 0x00002D37, 0x00050051, 0x0000000B, + 0x000053F8, 0x0000275A, 0x00000002, 0x000500C4, 0x0000000B, 0x00002177, 0x000053F8, 0x00000A29, + 0x000500C5, 0x0000000B, 0x00004D7B, 0x00004D7A, 0x00002177, 0x00050051, 0x0000000B, 0x000053F9, + 0x0000275A, 0x00000003, 0x000500C4, 0x0000000B, 0x00001C7E, 0x000053F9, 0x00000A38, 0x000500C5, + 0x0000000B, 0x0000237C, 0x00004D7B, 0x00001C7E, 0x0008000C, 0x0000001D, 0x00002377, 0x00000001, + 0x0000002B, 0x00003B57, 0x00000B7A, 0x00000505, 0x00050085, 0x0000001D, 0x000060DE, 0x00002377, + 0x00000809, 0x00050081, 0x0000001D, 0x00001F23, 0x000060DE, 0x00000145, 0x0004006D, 0x00000017, + 0x0000275B, 0x00001F23, 0x00050051, 0x0000000B, 0x0000220B, 0x0000275B, 0x00000000, 0x00050051, + 0x0000000B, 0x00002FEA, 0x0000275B, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D38, 0x00002FEA, + 0x00000A1A, 0x000500C5, 0x0000000B, 0x00004D7C, 0x0000220B, 0x00002D38, 0x00050051, 0x0000000B, + 0x000053FA, 0x0000275B, 0x00000002, 0x000500C4, 0x0000000B, 0x00002178, 0x000053FA, 0x00000A29, + 0x000500C5, 0x0000000B, 0x00004D7D, 0x00004D7C, 0x00002178, 0x00050051, 0x0000000B, 0x000053FB, + 0x0000275B, 0x00000003, 0x000500C4, 0x0000000B, 0x000029FF, 0x000053FB, 0x00000A38, 0x000500C5, + 0x0000000B, 0x00004A47, 0x00004D7D, 0x000029FF, 0x000500C4, 0x0000000B, 0x000058CA, 0x00004A47, + 0x00000A3A, 0x000500C5, 0x0000000B, 0x00006242, 0x0000237C, 0x000058CA, 0x0008000C, 0x0000001D, + 0x00002378, 0x00000001, 0x0000002B, 0x00003816, 0x00000B7A, 0x00000505, 0x00050085, 0x0000001D, + 0x000060DF, 0x00002378, 0x00000809, 0x00050081, 0x0000001D, 0x00001F24, 0x000060DF, 0x00000145, + 0x0004006D, 0x00000017, 0x0000275C, 0x00001F24, 0x00050051, 0x0000000B, 0x0000220C, 0x0000275C, + 0x00000000, 0x00050051, 0x0000000B, 0x00002FEB, 0x0000275C, 0x00000001, 0x000500C4, 0x0000000B, + 0x00002D39, 0x00002FEB, 0x00000A1A, 0x000500C5, 0x0000000B, 0x00004D7E, 0x0000220C, 0x00002D39, + 0x00050051, 0x0000000B, 0x000053FC, 0x0000275C, 0x00000002, 0x000500C4, 0x0000000B, 0x00002179, + 0x000053FC, 0x00000A29, 0x000500C5, 0x0000000B, 0x00004D7F, 0x00004D7E, 0x00002179, 0x00050051, + 0x0000000B, 0x000053FD, 0x0000275C, 0x00000003, 0x000500C4, 0x0000000B, 0x00001C7F, 0x000053FD, + 0x00000A38, 0x000500C5, 0x0000000B, 0x0000237D, 0x00004D7F, 0x00001C7F, 0x0008000C, 0x0000001D, + 0x00002379, 0x00000001, 0x0000002B, 0x00002BB5, 0x00000B7A, 0x00000505, 0x00050085, 0x0000001D, + 0x000060E0, 0x00002379, 0x00000809, 0x00050081, 0x0000001D, 0x00001F25, 0x000060E0, 0x00000145, + 0x0004006D, 0x00000017, 0x0000275D, 0x00001F25, 0x00050051, 0x0000000B, 0x0000220D, 0x0000275D, + 0x00000000, 0x00050051, 0x0000000B, 0x00002FEC, 0x0000275D, 0x00000001, 0x000500C4, 0x0000000B, + 0x00002D3A, 0x00002FEC, 0x00000A1A, 0x000500C5, 0x0000000B, 0x00004D80, 0x0000220D, 0x00002D3A, + 0x00050051, 0x0000000B, 0x000053FE, 0x0000275D, 0x00000002, 0x000500C4, 0x0000000B, 0x0000217A, + 0x000053FE, 0x00000A29, 0x000500C5, 0x0000000B, 0x00004D81, 0x00004D80, 0x0000217A, 0x00050051, + 0x0000000B, 0x000053FF, 0x0000275D, 0x00000003, 0x000500C4, 0x0000000B, 0x00002A00, 0x000053FF, + 0x00000A38, 0x000500C5, 0x0000000B, 0x00004A48, 0x00004D81, 0x00002A00, 0x000500C4, 0x0000000B, + 0x00005DAD, 0x00004A48, 0x00000A3A, 0x000500C5, 0x0000000B, 0x0000464C, 0x0000237D, 0x00005DAD, + 0x00050050, 0x00000011, 0x000053E1, 0x00006242, 0x0000464C, 0x000200F9, 0x00004992, 0x000200F8, + 0x00001CCE, 0x00050051, 0x0000000D, 0x00004D9A, 0x00003A49, 0x00000000, 0x00050051, 0x0000000D, + 0x000023ED, 0x00003B57, 0x00000000, 0x00050050, 0x00000013, 0x00004B20, 0x00004D9A, 0x000023ED, + 0x0006000C, 0x0000000B, 0x0000217B, 0x00000001, 0x0000003A, 0x00004B20, 0x00050051, 0x0000000D, + 0x00005BBF, 0x00003816, 0x00000000, 0x00050051, 0x0000000D, 0x000039A7, 0x00002BB5, 0x00000000, + 0x00050050, 0x00000013, 0x00004B0D, 0x00005BBF, 0x000039A7, 0x0006000C, 0x0000000B, 0x00002E96, + 0x00000001, 0x0000003A, 0x00004B0D, 0x00050050, 0x00000011, 0x0000612F, 0x0000217B, 0x00002E96, + 0x000200F9, 0x00004992, 0x000200F8, 0x00004992, 0x001100F5, 0x00000011, 0x00005E7C, 0x0000612F, + 0x00001CCE, 0x000053E1, 0x000045EB, 0x000053E0, 0x00001934, 0x000053DF, 0x00001933, 0x000053DE, + 0x00001CCD, 0x000053DD, 0x00003167, 0x00003D25, 0x00002514, 0x000500AA, 0x00000009, 0x000060B1, + 0x00001DD8, 0x00000A0A, 0x000300F7, 0x000033DC, 0x00000000, 0x000400FA, 0x000060B1, 0x00002CBB, + 0x000033DC, 0x000200F8, 0x00002CBB, 0x00050051, 0x0000000B, 0x00005E67, 0x00004AB4, 0x00000000, + 0x000500AB, 0x00000009, 0x000057C6, 0x00005E67, 0x00000A0A, 0x000200F9, 0x000033DC, 0x000200F8, + 0x000033DC, 0x000700F5, 0x00000009, 0x00002ACB, 0x000060B1, 0x00004992, 0x000057C6, 0x00002CBB, + 0x000300F7, 0x00004CC1, 0x00000002, 0x000400FA, 0x00002ACB, 0x00002CF4, 0x00004CC1, 0x000200F8, + 0x00002CF4, 0x00050051, 0x0000000B, 0x00005C2F, 0x00004AB4, 0x00000000, 0x000500AE, 0x00000009, + 0x000043C2, 0x00005C2F, 0x00000A10, 0x000300F7, 0x00004945, 0x00000000, 0x000400FA, 0x000043C2, + 0x00003E05, 0x00004945, 0x000200F8, 0x00003E05, 0x000500AE, 0x00000009, 0x00005FD4, 0x00005C2F, + 0x00000A13, 0x000300F7, 0x00004944, 0x00000000, 0x000400FA, 0x00005FD4, 0x00002E70, 0x00004944, + 0x000200F8, 0x00002E70, 0x00050051, 0x0000000B, 0x00004B1B, 0x00005E7C, 0x00000001, 0x000500C2, + 0x0000000B, 0x00003427, 0x00004B1B, 0x00000A3A, 0x000500C7, 0x0000000B, 0x00001C34, 0x00004B1B, + 0x0000068D, 0x000500C5, 0x0000000B, 0x0000452D, 0x00003427, 0x00001C34, 0x00060052, 0x00000011, + 0x00005B31, 0x0000452D, 0x00005E7C, 0x00000001, 0x000200F9, 0x00004944, 0x000200F8, 0x00004944, + 0x000700F5, 0x00000011, 0x00004C92, 0x00005E7C, 0x00003E05, 0x00005B31, 0x00002E70, 0x00050051, + 0x0000000B, 0x000054CF, 0x00004C92, 0x00000000, 0x000500C7, 0x0000000B, 0x00003175, 0x000054CF, + 0x000001C2, 0x00050051, 0x0000000B, 0x00005435, 0x00004C92, 0x00000001, 0x000500C4, 0x0000000B, + 0x000027D0, 0x00005435, 0x00000A3A, 0x000500C5, 0x0000000B, 0x000050A8, 0x00003175, 0x000027D0, + 0x00060052, 0x00000011, 0x00005E5A, 0x000050A8, 0x00004C92, 0x00000000, 0x000200F9, 0x00004945, + 0x000200F8, 0x00004945, 0x000700F5, 0x00000011, 0x00004C33, 0x00005E7C, 0x00002CF4, 0x00005E5A, + 0x00004944, 0x00050051, 0x0000000B, 0x000060F2, 0x00004C33, 0x00000000, 0x000500C2, 0x0000000B, + 0x00003750, 0x000060F2, 0x00000A3A, 0x000500C7, 0x0000000B, 0x00001C35, 0x000060F2, 0x0000068D, + 0x000500C5, 0x0000000B, 0x0000452E, 0x00003750, 0x00001C35, 0x00060052, 0x00000011, 0x00005B32, + 0x0000452E, 0x00004C33, 0x00000000, 0x000200F9, 0x00004CC1, 0x000200F8, 0x00004CC1, 0x000700F5, + 0x00000011, 0x0000240D, 0x00005E7C, 0x000033DC, 0x00005B32, 0x00004945, 0x00050080, 0x00000011, + 0x00004BCB, 0x00002EF9, 0x000059EC, 0x00050051, 0x0000000B, 0x000033BC, 0x00004BCB, 0x00000000, + 0x00050051, 0x0000000B, 0x00002553, 0x00004BCB, 0x00000001, 0x000500C2, 0x0000000B, 0x00002B2D, + 0x000033BC, 0x00000A13, 0x00050050, 0x00000011, 0x00001E98, 0x00002B2D, 0x00002553, 0x00050086, + 0x00000011, 0x00006158, 0x00001E98, 0x00005C31, 0x00050051, 0x0000000B, 0x0000366C, 0x00006158, + 0x00000000, 0x000500C4, 0x0000000B, 0x00004D3A, 0x0000366C, 0x00000A13, 0x00050051, 0x0000000B, + 0x00005EBB, 0x00006158, 0x00000001, 0x00060050, 0x00000014, 0x000053D3, 0x00004D3A, 0x00005EBB, + 0x00005F72, 0x000300F7, 0x00005341, 0x00000002, 0x000400FA, 0x0000500F, 0x000056C9, 0x00002ACC, + 0x000200F8, 0x00002ACC, 0x0007004F, 0x00000011, 0x00001CAB, 0x000053D3, 0x000053D3, 0x00000000, + 0x00000001, 0x0004007C, 0x00000012, 0x000059CF, 0x00001CAB, 0x00050051, 0x0000000C, 0x0000191F, + 0x000059CF, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x0000191F, 0x00000A1A, 0x00050051, + 0x0000000C, 0x00002747, 0x000059CF, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, + 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, + 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AA, 0x00050080, + 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, + 0x00000A22, 0x000500C7, 0x0000000C, 0x00002ACD, 0x0000191F, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003138, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004397, 0x00002ACD, 0x0000454D, 0x000500C4, 0x0000000C, 0x000018E7, + 0x00004397, 0x00000A0D, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, + 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00004A8E, + 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, + 0x00004D30, 0x00003C4B, 0x00003397, 0x000500C7, 0x0000000C, 0x000047BE, 0x00002747, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544A, 0x000047BE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004157, + 0x00004D30, 0x0000544A, 0x000500C7, 0x0000000C, 0x00005022, 0x00004157, 0x0000040B, 0x000500C4, + 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, + 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, + 0x00004158, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004AE3, 0x00004157, 0x00000388, + 0x000500C4, 0x0000000C, 0x0000544B, 0x00004AE3, 0x00000A11, 0x00050080, 0x0000000C, 0x00004147, + 0x00004158, 0x0000544B, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, + 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x0000191F, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, + 0x00005454, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544C, 0x00005454, 0x00000A1D, + 0x00050080, 0x0000000C, 0x00003C4C, 0x00004147, 0x0000544C, 0x000500C7, 0x0000000C, 0x00002E06, + 0x00004157, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4C, 0x00002E06, 0x0004007C, + 0x0000000B, 0x0000566F, 0x0000394F, 0x000200F9, 0x00005341, 0x000200F8, 0x000056C9, 0x0004007C, + 0x00000016, 0x000019AD, 0x000053D3, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000001, + 0x000500C3, 0x0000000C, 0x000024FE, 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002748, + 0x000019AD, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A11, 0x000500C2, + 0x0000000B, 0x00005B4E, 0x00006273, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, + 0x00050084, 0x0000000C, 0x00005321, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003B27, + 0x000024FE, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00003DA7, 0x00000A19, 0x0004007C, + 0x0000000C, 0x00003097, 0x00002348, 0x00050084, 0x0000000C, 0x0000287F, 0x00003B27, 0x00003097, + 0x00050051, 0x0000000C, 0x00006243, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, + 0x00006243, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x0000287F, 0x000500C4, + 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A1F, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, + 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, + 0x00004D38, 0x00006243, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x000042C2, 0x00000A1D, + 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, + 0x00004D38, 0x0000454E, 0x000500C4, 0x0000000C, 0x00001B8C, 0x0000434B, 0x00000A1F, 0x000500C3, + 0x0000000C, 0x00005DE3, 0x00001B8C, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002220, 0x000042C2, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002220, 0x0000405D, 0x000500C7, 0x0000000C, + 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006243, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, + 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004AE4, 0x000034BD, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544D, 0x00004AE4, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4D, 0x00005A0C, + 0x0000544D, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, + 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B33, 0x00004F70, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, + 0x00005B33, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047BF, 0x00002748, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544E, 0x000047BF, 0x00000A1F, 0x00050080, 0x0000000C, 0x00004159, 0x0000285C, + 0x0000544E, 0x000500C7, 0x0000000C, 0x00004AE5, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544F, 0x00004AE5, 0x00000A17, 0x00050080, 0x0000000C, 0x0000415A, 0x00004159, 0x0000544F, + 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4D, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, + 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x0000415A, 0x00000A1D, 0x000500C7, + 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, + 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B34, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005AB1, 0x00003C4D, 0x00000A05, 0x00050080, 0x0000000C, 0x00002ACE, 0x00005B34, 0x00005AB1, + 0x000500C4, 0x0000000C, 0x00005B35, 0x00002ACE, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, + 0x0000415A, 0x0000040B, 0x00050080, 0x0000000C, 0x00002ACF, 0x00005B35, 0x00005AB2, 0x000500C4, + 0x0000000C, 0x00005B36, 0x00002ACF, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x0000415A, + 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B36, 0x00005559, 0x0004007C, 0x0000000B, + 0x00005670, 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, + 0x000024FC, 0x00005670, 0x000056C9, 0x0000566F, 0x00002ACC, 0x00050084, 0x00000011, 0x00003FB6, + 0x00006158, 0x00005C31, 0x00050082, 0x00000011, 0x00003F85, 0x00001E98, 0x00003FB6, 0x00050051, + 0x0000000B, 0x0000448F, 0x00005C31, 0x00000001, 0x00050084, 0x0000000B, 0x00005C50, 0x0000229A, + 0x0000448F, 0x00050084, 0x0000000B, 0x00003CA0, 0x000024FC, 0x00005C50, 0x00050051, 0x0000000B, + 0x00003ED4, 0x00003F85, 0x00000000, 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, 0x0000448F, + 0x00050051, 0x0000000B, 0x00001AE7, 0x00003F85, 0x00000001, 0x00050080, 0x0000000B, 0x00002B25, + 0x00003E12, 0x00001AE7, 0x000500C4, 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A13, 0x000500C7, + 0x0000000B, 0x00005AB3, 0x000033BC, 0x00000A1F, 0x00050080, 0x0000000B, 0x00002557, 0x0000609D, + 0x00005AB3, 0x000500C4, 0x0000000B, 0x00004593, 0x00002557, 0x00000A0D, 0x00050080, 0x0000000B, + 0x0000204B, 0x00003CA0, 0x00004593, 0x000500C2, 0x0000000B, 0x000025CC, 0x0000204B, 0x00000A13, + 0x000500AA, 0x00000009, 0x00004B9C, 0x00004ADC, 0x00000A0D, 0x000300F7, 0x00002C98, 0x00000000, + 0x000400FA, 0x00004B9C, 0x00002957, 0x00002C98, 0x000200F8, 0x00002957, 0x000500C7, 0x00000011, + 0x0000475F, 0x0000240D, 0x00000916, 0x000500C4, 0x00000011, 0x000024D1, 0x0000475F, 0x000007B7, + 0x000500C7, 0x00000011, 0x000050AC, 0x0000240D, 0x00000B48, 0x000500C2, 0x00000011, 0x0000448D, + 0x000050AC, 0x000007B7, 0x000500C5, 0x00000011, 0x00003FF9, 0x000024D1, 0x0000448D, 0x000200F9, + 0x00002C98, 0x000200F8, 0x00002C98, 0x000700F5, 0x00000011, 0x00004D37, 0x0000240D, 0x00005341, + 0x00003FF9, 0x00002957, 0x00060041, 0x0000028E, 0x00001F75, 0x00001592, 0x00000A0B, 0x000025CC, + 0x0003003E, 0x00001F75, 0x00004D37, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, + 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_full_32bpp_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_full_32bpp_cs.h new file mode 100644 index 0000000..c966202 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_full_32bpp_cs.h @@ -0,0 +1,4427 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25271 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_runtimearr_uint ArrayStride 4 + OpDecorate %_struct_1948 BufferBlock + OpMemberDecorate %_struct_1948 0 NonWritable + OpMemberDecorate %_struct_1948 0 Offset 0 + OpDecorate %3271 NonWritable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %_struct_1036 Block + OpMemberDecorate %_struct_1036 0 Offset 0 + OpMemberDecorate %_struct_1036 1 Offset 4 + OpMemberDecorate %_struct_1036 2 Offset 8 + OpMemberDecorate %_struct_1036 3 Offset 12 + OpMemberDecorate %_struct_1036 4 Offset 16 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonReadable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %5522 NonReadable + OpDecorate %5522 Binding 0 + OpDecorate %5522 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %v4uint = OpTypeVector %uint 4 + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 + %v3float = OpTypeVector %float 3 + %v4float = OpTypeVector %float 4 + %bool = OpTypeBool + %v3int = OpTypeVector %int 3 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %float_255 = OpConstant %float 255 + %float_0_5 = OpConstant %float 0.5 + %uint_0 = OpConstant %uint 0 + %int_8 = OpConstant %int 8 + %int_16 = OpConstant %int 16 + %int_24 = OpConstant %int 24 + %float_1023 = OpConstant %float 1023 + %float_3 = OpConstant %float 3 + %344 = OpConstantComposite %v4float %float_1023 %float_1023 %float_1023 %float_3 + %int_10 = OpConstant %int 10 + %int_20 = OpConstant %int 20 + %int_30 = OpConstant %int 30 + %float_2047 = OpConstant %float 2047 + %2275 = OpConstantComposite %v3float %float_2047 %float_2047 %float_1023 + %int_11 = OpConstant %int 11 + %int_22 = OpConstant %int 22 + %14 = OpConstantComposite %v3float %float_1023 %float_2047 %float_2047 + %int_21 = OpConstant %int 21 +%float_65535 = OpConstant %float 65535 + %uint_24 = OpConstant %uint 24 + %653 = OpConstantComposite %v4uint %uint_0 %uint_8 %uint_16 %uint_24 + %uint_255 = OpConstant %uint 255 +%float_0_00392156886 = OpConstant %float 0.00392156886 + %uint_10 = OpConstant %uint 10 + %uint_20 = OpConstant %uint 20 + %uint_30 = OpConstant %uint 30 + %845 = OpConstantComposite %v4uint %uint_0 %uint_10 %uint_20 %uint_30 + %uint_1023 = OpConstant %uint 1023 + %635 = OpConstantComposite %v4uint %uint_1023 %uint_1023 %uint_1023 %uint_3 +%float_0_000977517106 = OpConstant %float 0.000977517106 +%float_0_333333343 = OpConstant %float 0.333333343 + %2798 = OpConstantComposite %v4float %float_0_000977517106 %float_0_000977517106 %float_0_000977517106 %float_0_333333343 + %2996 = OpConstantComposite %v3uint %uint_0 %uint_10 %uint_20 + %uint_127 = OpConstant %uint 127 + %uint_7 = OpConstant %uint 7 + %v3bool = OpTypeVector %bool 3 + %uint_124 = OpConstant %uint 124 + %uint_23 = OpConstant %uint 23 + %float_n1 = OpConstant %float -1 + %int_0 = OpConstant %int 0 + %1959 = OpConstantComposite %v2int %int_16 %int_0 +%float_0_000976592302 = OpConstant %float 0.000976592302 + %v4int = OpTypeVector %int 4 + %290 = OpConstantComposite %v4int %int_16 %int_0 %int_16 %int_0 + %1837 = OpConstantComposite %v2uint %uint_2 %uint_1 + %v2bool = OpTypeVector %bool 2 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %uint_80 = OpConstant %uint 80 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_448 = OpConstant %int 448 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 + %uint_6 = OpConstant %uint 6 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_runtimearr_uint = OpTypeRuntimeArray %uint +%_struct_1948 = OpTypeStruct %_runtimearr_uint +%_ptr_Uniform__struct_1948 = OpTypePointer Uniform %_struct_1948 + %3271 = OpVariable %_ptr_Uniform__struct_1948 Uniform +%_ptr_Uniform_uint = OpTypePointer Uniform %uint +%_struct_1036 = OpTypeStruct %uint %uint %uint %uint %uint +%_ptr_PushConstant__struct_1036 = OpTypePointer PushConstant %_struct_1036 + %3305 = OpVariable %_ptr_PushConstant__struct_1036 PushConstant +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_15 = OpConstant %uint 15 + %uint_28 = OpConstant %uint 28 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 + %uint_63 = OpConstant %uint 63 + %int_26 = OpConstant %int 26 + %int_23 = OpConstant %int 23 +%uint_16777216 = OpConstant %uint 16777216 + %2276 = OpConstantComposite %v2uint %uint_20 %uint_24 + %false = OpConstantFalse %bool +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %1825 = OpConstantComposite %v2uint %uint_2 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %5522 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %1284 = OpConstantComposite %v4float %float_n1 %float_n1 %float_n1 %float_n1 + %770 = OpConstantComposite %v4int %int_16 %int_16 %int_16 %int_16 + %1611 = OpConstantComposite %v4uint %uint_255 %uint_255 %uint_255 %uint_255 + %261 = OpConstantComposite %v3uint %uint_1023 %uint_1023 %uint_1023 + %1126 = OpConstantComposite %v3uint %uint_127 %uint_127 %uint_127 + %2828 = OpConstantComposite %v3uint %uint_7 %uint_7 %uint_7 + %2578 = OpConstantComposite %v3uint %uint_0 %uint_0 %uint_0 + %1018 = OpConstantComposite %v3uint %uint_124 %uint_124 %uint_124 + %393 = OpConstantComposite %v3uint %uint_23 %uint_23 %uint_23 + %141 = OpConstantComposite %v3uint %uint_16 %uint_16 %uint_16 + %73 = OpConstantComposite %v2float %float_n1 %float_n1 + %2151 = OpConstantComposite %v2int %int_16 %int_16 + %2938 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 + %1285 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 + %325 = OpConstantComposite %v4float %float_0_5 %float_0_5 %float_0_5 %float_0_5 + %2605 = OpConstantComposite %v3float %float_0 %float_0 %float_0 + %2584 = OpConstantComposite %v3float %float_1 %float_1 %float_1 + %939 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5 + %1823 = OpConstantComposite %v2float %float_0 %float_0 + %768 = OpConstantComposite %v2float %float_1 %float_1 + %1566 = OpConstantComposite %v2float %float_0_5 %float_0_5 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 +%int_1065353216 = OpConstant %int 1065353216 + %uint_1280 = OpConstant %uint 1280 +%uint_2621440 = OpConstant %uint 2621440 +%uint_4294967290 = OpConstant %uint 4294967290 + %2360 = OpConstantComposite %v3uint %uint_4294967290 %uint_4294967290 %uint_4294967290 + %uint_81 = OpConstant %uint 81 + %uint_82 = OpConstant %uint 82 + %uint_83 = OpConstant %uint 83 + %uint_84 = OpConstant %uint 84 + %uint_85 = OpConstant %uint 85 + %uint_86 = OpConstant %uint 86 + %uint_87 = OpConstant %uint 87 + %float_0_25 = OpConstant %float 0.25 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %19978 = OpShiftRightLogical %uint %15627 %uint_10 + %8574 = OpBitwiseAnd %uint %19978 %uint_3 + %21002 = OpShiftRightLogical %uint %15627 %uint_13 + %8575 = OpBitwiseAnd %uint %21002 %uint_2047 + %21003 = OpShiftRightLogical %uint %15627 %uint_24 + %8576 = OpBitwiseAnd %uint %21003 %uint_15 + %18836 = OpShiftRightLogical %uint %15627 %uint_28 + %9130 = OpBitwiseAnd %uint %18836 %uint_1 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9576 = OpShiftRightLogical %v2uint %8871 %1855 + %23379 = OpBitwiseAnd %v2uint %9576 %1954 + %16207 = OpShiftLeftLogical %v2uint %23379 %1870 + %23019 = OpIMul %v2uint %16207 %1828 + %12819 = OpShiftRightLogical %uint %20824 %uint_5 + %16204 = OpBitwiseAnd %uint %12819 %uint_2047 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %24236 = OpLoad %uint %18732 + %22701 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %20919 = OpLoad %uint %22701 + %19164 = OpBitwiseAnd %uint %24236 %uint_7 + %21999 = OpBitwiseAnd %uint %24236 %uint_8 + %20495 = OpINotEqual %bool %21999 %uint_0 + %10307 = OpShiftRightLogical %uint %24236 %uint_4 + %24434 = OpBitwiseAnd %uint %10307 %uint_7 + %19672 = OpShiftRightLogical %uint %24236 %uint_7 + %20627 = OpBitwiseAnd %uint %19672 %uint_63 + %22920 = OpBitcast %int %24236 + %13711 = OpShiftLeftLogical %int %22920 %int_10 + %20636 = OpShiftRightArithmetic %int %13711 %int_26 + %18178 = OpShiftLeftLogical %int %20636 %int_23 + %7462 = OpIAdd %int %18178 %int_1065353216 + %11052 = OpBitcast %float %7462 + %22649 = OpBitwiseAnd %uint %24236 %uint_16777216 + %7513 = OpINotEqual %bool %22649 %uint_0 + %8003 = OpBitwiseAnd %uint %20919 %uint_1023 + %15783 = OpShiftLeftLogical %uint %8003 %uint_5 + %22591 = OpShiftRightLogical %uint %20919 %uint_10 + %19390 = OpBitwiseAnd %uint %22591 %uint_1023 + %25203 = OpShiftLeftLogical %uint %19390 %uint_5 + %10422 = OpCompositeConstruct %v2uint %20919 %20919 + %10385 = OpShiftRightLogical %v2uint %10422 %2276 + %23380 = OpBitwiseAnd %v2uint %10385 %2122 + %16208 = OpShiftLeftLogical %v2uint %23380 %1870 + %23020 = OpIMul %v2uint %16208 %1828 + %12820 = OpShiftRightLogical %uint %20919 %uint_28 + %16205 = OpBitwiseAnd %uint %12820 %uint_7 + %18656 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_4 + %25270 = OpLoad %uint %18656 + %14159 = OpLoad %v3uint %gl_GlobalInvocationID + %12672 = OpVectorShuffle %v2uint %14159 %14159 0 1 + %12025 = OpShiftLeftLogical %v2uint %12672 %1825 + %7640 = OpCompositeExtract %uint %12025 0 + %11658 = OpShiftLeftLogical %uint %16204 %uint_3 + %15379 = OpUGreaterThanEqual %bool %7640 %11658 + OpSelectionMerge %12755 DontFlatten + OpBranchConditional %15379 %21992 %12755 + %21992 = OpLabel + OpBranch %19578 + %12755 = OpLabel + %7340 = OpCompositeExtract %uint %12025 1 + %7992 = OpExtInst %uint %1 UMax %7340 %uint_0 + %20975 = OpCompositeConstruct %v2uint %7640 %7992 + %21036 = OpIAdd %v2uint %20975 %23019 + %16075 = OpULessThanEqual %bool %16205 %uint_3 + OpSelectionMerge %23776 None + OpBranchConditional %16075 %10990 %15087 + %15087 = OpLabel + %13566 = OpIEqual %bool %16205 %uint_5 + %8438 = OpSelect %uint %13566 %uint_2 %uint_0 + OpBranch %23776 + %10990 = OpLabel + OpBranch %23776 + %23776 = OpLabel + %19300 = OpPhi %uint %16205 %10990 %8438 %15087 + %16830 = OpCompositeConstruct %v2uint %8574 %8574 + %11801 = OpUGreaterThanEqual %v2bool %16830 %1837 + %19381 = OpSelect %v2uint %11801 %1828 %1807 + %10986 = OpShiftLeftLogical %v2uint %21036 %19381 + %24669 = OpCompositeConstruct %v2uint %19300 %19300 + %9093 = OpShiftRightLogical %v2uint %24669 %1816 + %15084 = OpBitwiseAnd %v2uint %9093 %1828 + %10197 = OpIAdd %v2uint %10986 %15084 + %8548 = OpCompositeConstruct %v2uint %9130 %uint_0 + %9802 = OpShiftRightLogical %v2uint %2719 %8548 + %10146 = OpUDiv %v2uint %10197 %9802 + %20390 = OpCompositeExtract %uint %10146 1 + %11046 = OpIMul %uint %20390 %20561 + %24665 = OpCompositeExtract %uint %10146 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %8575 %21536 + %23345 = OpIMul %v2uint %10146 %9802 + %11892 = OpISub %v2uint %10197 %23345 + %8053 = OpIMul %uint %8742 %uint_1280 + %24263 = OpCompositeExtract %uint %11892 1 + %23526 = OpCompositeExtract %uint %9802 0 + %22886 = OpIMul %uint %24263 %23526 + %6886 = OpCompositeExtract %uint %11892 0 + %9696 = OpIAdd %uint %22886 %6886 + %18116 = OpShiftLeftLogical %uint %9696 %9130 + %18201 = OpIAdd %uint %8053 %18116 + %23256 = OpUMod %uint %18201 %uint_2621440 + %13153 = OpUGreaterThanEqual %bool %8574 %uint_2 + %24735 = OpSelect %uint %13153 %uint_1 %uint_0 + %20074 = OpIAdd %uint %9130 %24735 + %6555 = OpShiftLeftLogical %uint %uint_1 %20074 + %23279 = OpINotEqual %bool %9130 %uint_0 + OpSelectionMerge %21263 DontFlatten + OpBranchConditional %23279 %15205 %16569 + %16569 = OpLabel + %19162 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20297 DontFlatten + OpBranchConditional %19162 %9761 %12129 + %12129 = OpLabel + %19407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %23256 + %23875 = OpLoad %uint %19407 + %11687 = OpIAdd %uint %23256 %6555 + %6475 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11687 + %24155 = OpLoad %uint %6475 + %6234 = OpIMul %uint %uint_2 %6555 + %8353 = OpIAdd %uint %23256 %6234 + %15309 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8353 + %24156 = OpLoad %uint %15309 + %6235 = OpIMul %uint %uint_3 %6555 + %8354 = OpIAdd %uint %23256 %6235 + %14321 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8354 + %16379 = OpLoad %uint %14321 + %20780 = OpCompositeConstruct %v4uint %23875 %24155 %24156 %16379 + OpBranch %20297 + %9761 = OpLabel + %21829 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %23256 + %23876 = OpLoad %uint %21829 + %11688 = OpIAdd %uint %23256 %uint_1 + %6399 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11688 + %23650 = OpLoad %uint %6399 + %11689 = OpIAdd %uint %23256 %uint_2 + %6400 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11689 + %23651 = OpLoad %uint %6400 + %11690 = OpIAdd %uint %23256 %uint_3 + %24558 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11690 + %16380 = OpLoad %uint %24558 + %20781 = OpCompositeConstruct %v4uint %23876 %23650 %23651 %16380 + OpBranch %20297 + %20297 = OpLabel + %10943 = OpPhi %v4uint %20781 %9761 %20780 %12129 + OpSelectionMerge %16224 None + OpSwitch %8576 %19451 0 %14585 1 %14585 2 %7355 10 %7355 3 %7354 12 %7354 4 %8190 6 %8243 + %8243 = OpLabel + %24406 = OpCompositeExtract %uint %10943 0 + %24679 = OpExtInst %v2float %1 UnpackHalf2x16 %24406 + %10082 = OpCompositeExtract %float %24679 0 + %17478 = OpCompositeExtract %float %24679 1 + %14604 = OpCompositeConstruct %v4float %10082 %17478 %float_0 %float_0 + %17274 = OpCompositeExtract %uint %10943 1 + %18027 = OpExtInst %v2float %1 UnpackHalf2x16 %17274 + %10083 = OpCompositeExtract %float %18027 0 + %17479 = OpCompositeExtract %float %18027 1 + %14605 = OpCompositeConstruct %v4float %10083 %17479 %float_0 %float_0 + %17275 = OpCompositeExtract %uint %10943 2 + %18028 = OpExtInst %v2float %1 UnpackHalf2x16 %17275 + %10084 = OpCompositeExtract %float %18028 0 + %17480 = OpCompositeExtract %float %18028 1 + %14606 = OpCompositeConstruct %v4float %10084 %17480 %float_0 %float_0 + %17276 = OpCompositeExtract %uint %10943 3 + %18029 = OpExtInst %v2float %1 UnpackHalf2x16 %17276 + %10085 = OpCompositeExtract %float %18029 0 + %20670 = OpCompositeExtract %float %18029 1 + %9033 = OpCompositeConstruct %v4float %10085 %20670 %float_0 %float_0 + OpBranch %16224 + %8190 = OpLabel + %12427 = OpCompositeExtract %uint %10943 0 + %22685 = OpBitcast %int %12427 + %18202 = OpCompositeConstruct %v2int %22685 %22685 + %18349 = OpShiftLeftLogical %v2int %18202 %1959 + %13335 = OpShiftRightArithmetic %v2int %18349 %2151 + %10903 = OpConvertSToF %v2float %13335 + %18247 = OpVectorTimesScalar %v2float %10903 %float_0_000976592302 + %24070 = OpExtInst %v2float %1 FMax %73 %18247 + %24330 = OpCompositeExtract %float %24070 0 + %15572 = OpCompositeExtract %float %24070 1 + %16670 = OpCompositeConstruct %v4float %24330 %15572 %float_0 %float_0 + %19522 = OpCompositeExtract %uint %10943 1 + %16033 = OpBitcast %int %19522 + %18203 = OpCompositeConstruct %v2int %16033 %16033 + %18350 = OpShiftLeftLogical %v2int %18203 %1959 + %13336 = OpShiftRightArithmetic %v2int %18350 %2151 + %10904 = OpConvertSToF %v2float %13336 + %18248 = OpVectorTimesScalar %v2float %10904 %float_0_000976592302 + %24071 = OpExtInst %v2float %1 FMax %73 %18248 + %24331 = OpCompositeExtract %float %24071 0 + %15573 = OpCompositeExtract %float %24071 1 + %16671 = OpCompositeConstruct %v4float %24331 %15573 %float_0 %float_0 + %19523 = OpCompositeExtract %uint %10943 2 + %16034 = OpBitcast %int %19523 + %18204 = OpCompositeConstruct %v2int %16034 %16034 + %18351 = OpShiftLeftLogical %v2int %18204 %1959 + %13337 = OpShiftRightArithmetic %v2int %18351 %2151 + %10905 = OpConvertSToF %v2float %13337 + %18249 = OpVectorTimesScalar %v2float %10905 %float_0_000976592302 + %24072 = OpExtInst %v2float %1 FMax %73 %18249 + %24332 = OpCompositeExtract %float %24072 0 + %15574 = OpCompositeExtract %float %24072 1 + %16672 = OpCompositeConstruct %v4float %24332 %15574 %float_0 %float_0 + %19524 = OpCompositeExtract %uint %10943 3 + %16035 = OpBitcast %int %19524 + %18205 = OpCompositeConstruct %v2int %16035 %16035 + %18352 = OpShiftLeftLogical %v2int %18205 %1959 + %13338 = OpShiftRightArithmetic %v2int %18352 %2151 + %10906 = OpConvertSToF %v2float %13338 + %18250 = OpVectorTimesScalar %v2float %10906 %float_0_000976592302 + %24073 = OpExtInst %v2float %1 FMax %73 %18250 + %24333 = OpCompositeExtract %float %24073 0 + %18764 = OpCompositeExtract %float %24073 1 + %9034 = OpCompositeConstruct %v4float %24333 %18764 %float_0 %float_0 + OpBranch %16224 + %7354 = OpLabel + %22205 = OpCompositeExtract %uint %10943 0 + %20234 = OpCompositeConstruct %v3uint %22205 %22205 %22205 + %11021 = OpShiftRightLogical %v3uint %20234 %2996 + %24038 = OpBitwiseAnd %v3uint %11021 %261 + %18588 = OpBitwiseAnd %v3uint %24038 %1126 + %23440 = OpShiftRightLogical %v3uint %24038 %2828 + %16585 = OpIEqual %v3bool %23440 %2578 + %11339 = OpExtInst %v3int %1 FindUMsb %18588 + %10773 = OpBitcast %v3uint %11339 + %6266 = OpISub %v3uint %2828 %10773 + %8720 = OpIAdd %v3uint %10773 %2360 + %10351 = OpSelect %v3uint %16585 %8720 %23440 + %23252 = OpShiftLeftLogical %v3uint %18588 %6266 + %18842 = OpBitwiseAnd %v3uint %23252 %1126 + %10909 = OpSelect %v3uint %16585 %18842 %18588 + %24569 = OpIAdd %v3uint %10351 %1018 + %20351 = OpShiftLeftLogical %v3uint %24569 %393 + %16294 = OpShiftLeftLogical %v3uint %10909 %141 + %22396 = OpBitwiseOr %v3uint %20351 %16294 + %13824 = OpIEqual %v3bool %24038 %2578 + %16962 = OpSelect %v3uint %13824 %2578 %22396 + %10703 = OpBitcast %v3float %16962 + %19364 = OpShiftRightLogical %uint %22205 %uint_30 + %18446 = OpConvertUToF %float %19364 + %15903 = OpFMul %float %18446 %float_0_333333343 + %21442 = OpCompositeExtract %float %10703 0 + %10837 = OpCompositeExtract %float %10703 1 + %7833 = OpCompositeExtract %float %10703 2 + %15834 = OpCompositeConstruct %v4float %21442 %10837 %7833 %15903 + %10229 = OpCompositeExtract %uint %10943 1 + %13582 = OpCompositeConstruct %v3uint %10229 %10229 %10229 + %11022 = OpShiftRightLogical %v3uint %13582 %2996 + %24039 = OpBitwiseAnd %v3uint %11022 %261 + %18589 = OpBitwiseAnd %v3uint %24039 %1126 + %23441 = OpShiftRightLogical %v3uint %24039 %2828 + %16586 = OpIEqual %v3bool %23441 %2578 + %11340 = OpExtInst %v3int %1 FindUMsb %18589 + %10774 = OpBitcast %v3uint %11340 + %6267 = OpISub %v3uint %2828 %10774 + %8721 = OpIAdd %v3uint %10774 %2360 + %10352 = OpSelect %v3uint %16586 %8721 %23441 + %23253 = OpShiftLeftLogical %v3uint %18589 %6267 + %18843 = OpBitwiseAnd %v3uint %23253 %1126 + %10910 = OpSelect %v3uint %16586 %18843 %18589 + %24570 = OpIAdd %v3uint %10352 %1018 + %20352 = OpShiftLeftLogical %v3uint %24570 %393 + %16295 = OpShiftLeftLogical %v3uint %10910 %141 + %22397 = OpBitwiseOr %v3uint %20352 %16295 + %13825 = OpIEqual %v3bool %24039 %2578 + %16963 = OpSelect %v3uint %13825 %2578 %22397 + %10704 = OpBitcast %v3float %16963 + %19365 = OpShiftRightLogical %uint %10229 %uint_30 + %18447 = OpConvertUToF %float %19365 + %15904 = OpFMul %float %18447 %float_0_333333343 + %21443 = OpCompositeExtract %float %10704 0 + %10838 = OpCompositeExtract %float %10704 1 + %7834 = OpCompositeExtract %float %10704 2 + %15835 = OpCompositeConstruct %v4float %21443 %10838 %7834 %15904 + %10230 = OpCompositeExtract %uint %10943 2 + %13583 = OpCompositeConstruct %v3uint %10230 %10230 %10230 + %11023 = OpShiftRightLogical %v3uint %13583 %2996 + %24040 = OpBitwiseAnd %v3uint %11023 %261 + %18590 = OpBitwiseAnd %v3uint %24040 %1126 + %23442 = OpShiftRightLogical %v3uint %24040 %2828 + %16587 = OpIEqual %v3bool %23442 %2578 + %11341 = OpExtInst %v3int %1 FindUMsb %18590 + %10775 = OpBitcast %v3uint %11341 + %6268 = OpISub %v3uint %2828 %10775 + %8722 = OpIAdd %v3uint %10775 %2360 + %10353 = OpSelect %v3uint %16587 %8722 %23442 + %23254 = OpShiftLeftLogical %v3uint %18590 %6268 + %18844 = OpBitwiseAnd %v3uint %23254 %1126 + %10911 = OpSelect %v3uint %16587 %18844 %18590 + %24571 = OpIAdd %v3uint %10353 %1018 + %20353 = OpShiftLeftLogical %v3uint %24571 %393 + %16296 = OpShiftLeftLogical %v3uint %10911 %141 + %22398 = OpBitwiseOr %v3uint %20353 %16296 + %13826 = OpIEqual %v3bool %24040 %2578 + %16964 = OpSelect %v3uint %13826 %2578 %22398 + %10705 = OpBitcast %v3float %16964 + %19366 = OpShiftRightLogical %uint %10230 %uint_30 + %18448 = OpConvertUToF %float %19366 + %15905 = OpFMul %float %18448 %float_0_333333343 + %21444 = OpCompositeExtract %float %10705 0 + %10839 = OpCompositeExtract %float %10705 1 + %7835 = OpCompositeExtract %float %10705 2 + %15836 = OpCompositeConstruct %v4float %21444 %10839 %7835 %15905 + %10231 = OpCompositeExtract %uint %10943 3 + %13584 = OpCompositeConstruct %v3uint %10231 %10231 %10231 + %11024 = OpShiftRightLogical %v3uint %13584 %2996 + %24041 = OpBitwiseAnd %v3uint %11024 %261 + %18591 = OpBitwiseAnd %v3uint %24041 %1126 + %23443 = OpShiftRightLogical %v3uint %24041 %2828 + %16588 = OpIEqual %v3bool %23443 %2578 + %11342 = OpExtInst %v3int %1 FindUMsb %18591 + %10776 = OpBitcast %v3uint %11342 + %6269 = OpISub %v3uint %2828 %10776 + %8723 = OpIAdd %v3uint %10776 %2360 + %10354 = OpSelect %v3uint %16588 %8723 %23443 + %23255 = OpShiftLeftLogical %v3uint %18591 %6269 + %18845 = OpBitwiseAnd %v3uint %23255 %1126 + %10912 = OpSelect %v3uint %16588 %18845 %18591 + %24572 = OpIAdd %v3uint %10354 %1018 + %20354 = OpShiftLeftLogical %v3uint %24572 %393 + %16297 = OpShiftLeftLogical %v3uint %10912 %141 + %22399 = OpBitwiseOr %v3uint %20354 %16297 + %13827 = OpIEqual %v3bool %24041 %2578 + %16965 = OpSelect %v3uint %13827 %2578 %22399 + %10706 = OpBitcast %v3float %16965 + %19367 = OpShiftRightLogical %uint %10231 %uint_30 + %18449 = OpConvertUToF %float %19367 + %15906 = OpFMul %float %18449 %float_0_333333343 + %21445 = OpCompositeExtract %float %10706 0 + %10840 = OpCompositeExtract %float %10706 1 + %11025 = OpCompositeExtract %float %10706 2 + %9035 = OpCompositeConstruct %v4float %21445 %10840 %11025 %15906 + OpBranch %16224 + %7355 = OpLabel + %22206 = OpCompositeExtract %uint %10943 0 + %20235 = OpCompositeConstruct %v4uint %22206 %22206 %22206 %22206 + %9368 = OpShiftRightLogical %v4uint %20235 %845 + %18859 = OpBitwiseAnd %v4uint %9368 %635 + %15543 = OpConvertUToF %v4float %18859 + %16688 = OpFMul %v4float %15543 %2798 + %23762 = OpCompositeExtract %uint %10943 1 + %20813 = OpCompositeConstruct %v4uint %23762 %23762 %23762 %23762 + %9369 = OpShiftRightLogical %v4uint %20813 %845 + %18860 = OpBitwiseAnd %v4uint %9369 %635 + %15544 = OpConvertUToF %v4float %18860 + %16689 = OpFMul %v4float %15544 %2798 + %23763 = OpCompositeExtract %uint %10943 2 + %20814 = OpCompositeConstruct %v4uint %23763 %23763 %23763 %23763 + %9370 = OpShiftRightLogical %v4uint %20814 %845 + %18861 = OpBitwiseAnd %v4uint %9370 %635 + %15545 = OpConvertUToF %v4float %18861 + %16690 = OpFMul %v4float %15545 %2798 + %23764 = OpCompositeExtract %uint %10943 3 + %20815 = OpCompositeConstruct %v4uint %23764 %23764 %23764 %23764 + %9371 = OpShiftRightLogical %v4uint %20815 %845 + %18862 = OpBitwiseAnd %v4uint %9371 %635 + %18735 = OpConvertUToF %v4float %18862 + %9887 = OpFMul %v4float %18735 %2798 + OpBranch %16224 + %14585 = OpLabel + %22207 = OpCompositeExtract %uint %10943 0 + %20236 = OpCompositeConstruct %v4uint %22207 %22207 %22207 %22207 + %9372 = OpShiftRightLogical %v4uint %20236 %653 + %19030 = OpBitwiseAnd %v4uint %9372 %1611 + %13986 = OpConvertUToF %v4float %19030 + %19235 = OpVectorTimesScalar %v4float %13986 %float_0_00392156886 + %8607 = OpCompositeExtract %uint %10943 1 + %24843 = OpCompositeConstruct %v4uint %8607 %8607 %8607 %8607 + %9373 = OpShiftRightLogical %v4uint %24843 %653 + %19031 = OpBitwiseAnd %v4uint %9373 %1611 + %13987 = OpConvertUToF %v4float %19031 + %19236 = OpVectorTimesScalar %v4float %13987 %float_0_00392156886 + %8608 = OpCompositeExtract %uint %10943 2 + %24844 = OpCompositeConstruct %v4uint %8608 %8608 %8608 %8608 + %9374 = OpShiftRightLogical %v4uint %24844 %653 + %19032 = OpBitwiseAnd %v4uint %9374 %1611 + %13988 = OpConvertUToF %v4float %19032 + %19237 = OpVectorTimesScalar %v4float %13988 %float_0_00392156886 + %8609 = OpCompositeExtract %uint %10943 3 + %24845 = OpCompositeConstruct %v4uint %8609 %8609 %8609 %8609 + %9375 = OpShiftRightLogical %v4uint %24845 %653 + %19033 = OpBitwiseAnd %v4uint %9375 %1611 + %17178 = OpConvertUToF %v4float %19033 + %12434 = OpVectorTimesScalar %v4float %17178 %float_0_00392156886 + OpBranch %16224 + %19451 = OpLabel + %12428 = OpCompositeExtract %uint %10943 0 + %20462 = OpBitcast %float %12428 + %17206 = OpCompositeConstruct %v2float %20462 %float_0 + %11664 = OpVectorShuffle %v4float %17206 %17206 0 1 1 1 + %22193 = OpCompositeExtract %uint %10943 1 + %16232 = OpBitcast %float %22193 + %17207 = OpCompositeConstruct %v2float %16232 %float_0 + %11665 = OpVectorShuffle %v4float %17207 %17207 0 1 1 1 + %22194 = OpCompositeExtract %uint %10943 2 + %16233 = OpBitcast %float %22194 + %17208 = OpCompositeConstruct %v2float %16233 %float_0 + %11666 = OpVectorShuffle %v4float %17208 %17208 0 1 1 1 + %22195 = OpCompositeExtract %uint %10943 3 + %16234 = OpBitcast %float %22195 + %20398 = OpCompositeConstruct %v2float %16234 %float_0 + %23098 = OpVectorShuffle %v4float %20398 %20398 0 1 1 1 + OpBranch %16224 + %16224 = OpLabel + %11175 = OpPhi %v4float %23098 %19451 %12434 %14585 %9887 %7355 %9035 %7354 %9034 %8190 %9033 %8243 + %14344 = OpPhi %v4float %11666 %19451 %19237 %14585 %16690 %7355 %15836 %7354 %16672 %8190 %14606 %8243 + %15229 = OpPhi %v4float %11665 %19451 %19236 %14585 %16689 %7355 %15835 %7354 %16671 %8190 %14605 %8243 + %14518 = OpPhi %v4float %11664 %19451 %19235 %14585 %16688 %7355 %15834 %7354 %16670 %8190 %14604 %8243 + OpBranch %21263 + %15205 = OpLabel + %21584 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20259 DontFlatten + OpBranchConditional %21584 %9762 %12130 + %12130 = OpLabel + %19408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %23256 + %23877 = OpLoad %uint %19408 + %11691 = OpIAdd %uint %23256 %uint_1 + %6401 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11691 + %23652 = OpLoad %uint %6401 + %11692 = OpIAdd %uint %23256 %6555 + %6402 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11692 + %23653 = OpLoad %uint %6402 + %11693 = OpIAdd %uint %11692 %uint_1 + %24559 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11693 + %14156 = OpLoad %uint %24559 + %19670 = OpCompositeConstruct %v4uint %23877 %23652 %23653 %14156 + %17048 = OpIMul %uint %uint_2 %6555 + %13991 = OpIAdd %uint %23256 %17048 + %15233 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13991 + %23654 = OpLoad %uint %15233 + %11694 = OpIAdd %uint %13991 %uint_1 + %6476 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11694 + %24157 = OpLoad %uint %6476 + %6236 = OpIMul %uint %uint_3 %6555 + %8355 = OpIAdd %uint %23256 %6236 + %15234 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8355 + %23655 = OpLoad %uint %15234 + %11695 = OpIAdd %uint %8355 %uint_1 + %24560 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11695 + %16381 = OpLoad %uint %24560 + %20782 = OpCompositeConstruct %v4uint %23654 %24157 %23655 %16381 + OpBranch %20259 + %9762 = OpLabel + %21830 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %23256 + %23878 = OpLoad %uint %21830 + %11696 = OpIAdd %uint %23256 %uint_1 + %6403 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11696 + %23656 = OpLoad %uint %6403 + %11697 = OpIAdd %uint %23256 %uint_2 + %6404 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11697 + %23657 = OpLoad %uint %6404 + %11698 = OpIAdd %uint %23256 %uint_3 + %24561 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11698 + %14080 = OpLoad %uint %24561 + %19165 = OpCompositeConstruct %v4uint %23878 %23656 %23657 %14080 + %22501 = OpIAdd %uint %23256 %uint_4 + %24651 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22501 + %23658 = OpLoad %uint %24651 + %11699 = OpIAdd %uint %23256 %uint_5 + %6405 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11699 + %23659 = OpLoad %uint %6405 + %11700 = OpIAdd %uint %23256 %uint_6 + %6406 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11700 + %23660 = OpLoad %uint %6406 + %11701 = OpIAdd %uint %23256 %uint_7 + %24562 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11701 + %16382 = OpLoad %uint %24562 + %20783 = OpCompositeConstruct %v4uint %23658 %23659 %23660 %16382 + OpBranch %20259 + %20259 = OpLabel + %11213 = OpPhi %v4uint %20783 %9762 %20782 %12130 + %14112 = OpPhi %v4uint %19165 %9762 %19670 %12130 + OpSelectionMerge %20260 None + OpSwitch %8576 %20310 5 %8536 7 %8244 + %8244 = OpLabel + %24407 = OpCompositeExtract %uint %14112 0 + %24680 = OpExtInst %v2float %1 UnpackHalf2x16 %24407 + %10101 = OpCompositeExtract %float %24680 0 + %16056 = OpCompositeExtract %float %24680 1 + %17025 = OpCompositeExtract %uint %14112 1 + %15605 = OpExtInst %v2float %1 UnpackHalf2x16 %17025 + %10086 = OpCompositeExtract %float %15605 0 + %17481 = OpCompositeExtract %float %15605 1 + %14607 = OpCompositeConstruct %v4float %10101 %16056 %10086 %17481 + %17277 = OpCompositeExtract %uint %14112 2 + %18030 = OpExtInst %v2float %1 UnpackHalf2x16 %17277 + %10102 = OpCompositeExtract %float %18030 0 + %16057 = OpCompositeExtract %float %18030 1 + %17026 = OpCompositeExtract %uint %14112 3 + %15606 = OpExtInst %v2float %1 UnpackHalf2x16 %17026 + %10087 = OpCompositeExtract %float %15606 0 + %17482 = OpCompositeExtract %float %15606 1 + %14608 = OpCompositeConstruct %v4float %10102 %16057 %10087 %17482 + %17278 = OpCompositeExtract %uint %11213 0 + %18031 = OpExtInst %v2float %1 UnpackHalf2x16 %17278 + %10103 = OpCompositeExtract %float %18031 0 + %16058 = OpCompositeExtract %float %18031 1 + %17027 = OpCompositeExtract %uint %11213 1 + %15607 = OpExtInst %v2float %1 UnpackHalf2x16 %17027 + %10088 = OpCompositeExtract %float %15607 0 + %17483 = OpCompositeExtract %float %15607 1 + %14609 = OpCompositeConstruct %v4float %10103 %16058 %10088 %17483 + %17279 = OpCompositeExtract %uint %11213 2 + %18032 = OpExtInst %v2float %1 UnpackHalf2x16 %17279 + %10104 = OpCompositeExtract %float %18032 0 + %16059 = OpCompositeExtract %float %18032 1 + %17028 = OpCompositeExtract %uint %11213 3 + %15608 = OpExtInst %v2float %1 UnpackHalf2x16 %17028 + %10089 = OpCompositeExtract %float %15608 0 + %20671 = OpCompositeExtract %float %15608 1 + %9036 = OpCompositeConstruct %v4float %10104 %16059 %10089 %20671 + OpBranch %20260 + %8536 = OpLabel + %9723 = OpVectorShuffle %v2uint %14112 %14112 0 1 + %23356 = OpBitcast %v2int %9723 + %24782 = OpVectorShuffle %v4int %23356 %23356 0 0 1 1 + %18598 = OpShiftLeftLogical %v4int %24782 %290 + %15757 = OpShiftRightArithmetic %v4int %18598 %770 + %10907 = OpConvertSToF %v4float %15757 + %18209 = OpVectorTimesScalar %v4float %10907 %float_0_000976592302 + %25233 = OpExtInst %v4float %1 FMax %1284 %18209 + %14187 = OpVectorShuffle %v2uint %14112 %14112 2 3 + %9407 = OpBitcast %v2int %14187 + %24783 = OpVectorShuffle %v4int %9407 %9407 0 0 1 1 + %18599 = OpShiftLeftLogical %v4int %24783 %290 + %15758 = OpShiftRightArithmetic %v4int %18599 %770 + %10908 = OpConvertSToF %v4float %15758 + %18210 = OpVectorTimesScalar %v4float %10908 %float_0_000976592302 + %25234 = OpExtInst %v4float %1 FMax %1284 %18210 + %14188 = OpVectorShuffle %v2uint %11213 %11213 0 1 + %9408 = OpBitcast %v2int %14188 + %24784 = OpVectorShuffle %v4int %9408 %9408 0 0 1 1 + %18600 = OpShiftLeftLogical %v4int %24784 %290 + %15759 = OpShiftRightArithmetic %v4int %18600 %770 + %10913 = OpConvertSToF %v4float %15759 + %18211 = OpVectorTimesScalar %v4float %10913 %float_0_000976592302 + %25235 = OpExtInst %v4float %1 FMax %1284 %18211 + %14189 = OpVectorShuffle %v2uint %11213 %11213 2 3 + %9409 = OpBitcast %v2int %14189 + %24785 = OpVectorShuffle %v4int %9409 %9409 0 0 1 1 + %18601 = OpShiftLeftLogical %v4int %24785 %290 + %15760 = OpShiftRightArithmetic %v4int %18601 %770 + %10914 = OpConvertSToF %v4float %15760 + %21439 = OpVectorTimesScalar %v4float %10914 %float_0_000976592302 + %17250 = OpExtInst %v4float %1 FMax %1284 %21439 + OpBranch %20260 + %20310 = OpLabel + %9763 = OpVectorShuffle %v2uint %14112 %14112 0 1 + %20825 = OpBitcast %v2float %9763 + %7035 = OpCompositeExtract %float %20825 0 + %13418 = OpCompositeExtract %float %20825 1 + %17016 = OpCompositeConstruct %v4float %7035 %13418 %float_0 %float_0 + %16856 = OpVectorShuffle %v2uint %14112 %14112 2 3 + %14173 = OpBitcast %v2float %16856 + %7036 = OpCompositeExtract %float %14173 0 + %13419 = OpCompositeExtract %float %14173 1 + %17017 = OpCompositeConstruct %v4float %7036 %13419 %float_0 %float_0 + %16857 = OpVectorShuffle %v2uint %11213 %11213 0 1 + %14174 = OpBitcast %v2float %16857 + %7037 = OpCompositeExtract %float %14174 0 + %13420 = OpCompositeExtract %float %14174 1 + %17018 = OpCompositeConstruct %v4float %7037 %13420 %float_0 %float_0 + %16858 = OpVectorShuffle %v2uint %11213 %11213 2 3 + %14175 = OpBitcast %v2float %16858 + %7038 = OpCompositeExtract %float %14175 0 + %16648 = OpCompositeExtract %float %14175 1 + %9037 = OpCompositeConstruct %v4float %7038 %16648 %float_0 %float_0 + OpBranch %20260 + %20260 = OpLabel + %11176 = OpPhi %v4float %9037 %20310 %17250 %8536 %9036 %8244 + %14345 = OpPhi %v4float %17018 %20310 %25235 %8536 %14609 %8244 + %15230 = OpPhi %v4float %17017 %20310 %25234 %8536 %14608 %8244 + %14519 = OpPhi %v4float %17016 %20310 %25233 %8536 %14607 %8244 + OpBranch %21263 + %21263 = OpLabel + %11177 = OpPhi %v4float %11176 %20260 %11175 %16224 + %14346 = OpPhi %v4float %14345 %20260 %14344 %16224 + %13804 = OpPhi %v4float %15230 %20260 %15229 %16224 + %8403 = OpPhi %v4float %14519 %20260 %14518 %16224 + %11861 = OpUGreaterThanEqual %bool %16205 %uint_4 + OpSelectionMerge %21267 DontFlatten + OpBranchConditional %11861 %20709 %21267 + %20709 = OpLabel + %25083 = OpFMul %float %11052 %float_0_5 + %24184 = OpIAdd %uint %23256 %uint_80 + OpSelectionMerge %21264 DontFlatten + OpBranchConditional %23279 %15206 %16570 + %16570 = OpLabel + %19163 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20298 DontFlatten + OpBranchConditional %19163 %9764 %12131 + %12131 = OpLabel + %19409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24184 + %23879 = OpLoad %uint %19409 + %11702 = OpIAdd %uint %24184 %6555 + %6477 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11702 + %24158 = OpLoad %uint %6477 + %6237 = OpIMul %uint %uint_2 %6555 + %8356 = OpIAdd %uint %24184 %6237 + %15310 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8356 + %24159 = OpLoad %uint %15310 + %6238 = OpIMul %uint %uint_3 %6555 + %8357 = OpIAdd %uint %24184 %6238 + %14322 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8357 + %16383 = OpLoad %uint %14322 + %20784 = OpCompositeConstruct %v4uint %23879 %24158 %24159 %16383 + OpBranch %20298 + %9764 = OpLabel + %21831 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24184 + %23880 = OpLoad %uint %21831 + %11703 = OpIAdd %uint %23256 %uint_81 + %6407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11703 + %23661 = OpLoad %uint %6407 + %11704 = OpIAdd %uint %23256 %uint_82 + %6408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11704 + %23662 = OpLoad %uint %6408 + %11705 = OpIAdd %uint %23256 %uint_83 + %24563 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11705 + %16384 = OpLoad %uint %24563 + %20785 = OpCompositeConstruct %v4uint %23880 %23661 %23662 %16384 + OpBranch %20298 + %20298 = OpLabel + %10944 = OpPhi %v4uint %20785 %9764 %20784 %12131 + OpSelectionMerge %16225 None + OpSwitch %8576 %19452 0 %14586 1 %14586 2 %7357 10 %7357 3 %7356 12 %7356 4 %8191 6 %8245 + %8245 = OpLabel + %24408 = OpCompositeExtract %uint %10944 0 + %24681 = OpExtInst %v2float %1 UnpackHalf2x16 %24408 + %10090 = OpCompositeExtract %float %24681 0 + %17484 = OpCompositeExtract %float %24681 1 + %14610 = OpCompositeConstruct %v4float %10090 %17484 %float_0 %float_0 + %17280 = OpCompositeExtract %uint %10944 1 + %18033 = OpExtInst %v2float %1 UnpackHalf2x16 %17280 + %10091 = OpCompositeExtract %float %18033 0 + %17485 = OpCompositeExtract %float %18033 1 + %14611 = OpCompositeConstruct %v4float %10091 %17485 %float_0 %float_0 + %17281 = OpCompositeExtract %uint %10944 2 + %18034 = OpExtInst %v2float %1 UnpackHalf2x16 %17281 + %10092 = OpCompositeExtract %float %18034 0 + %17486 = OpCompositeExtract %float %18034 1 + %14612 = OpCompositeConstruct %v4float %10092 %17486 %float_0 %float_0 + %17282 = OpCompositeExtract %uint %10944 3 + %18035 = OpExtInst %v2float %1 UnpackHalf2x16 %17282 + %10093 = OpCompositeExtract %float %18035 0 + %20672 = OpCompositeExtract %float %18035 1 + %9038 = OpCompositeConstruct %v4float %10093 %20672 %float_0 %float_0 + OpBranch %16225 + %8191 = OpLabel + %12429 = OpCompositeExtract %uint %10944 0 + %22686 = OpBitcast %int %12429 + %18206 = OpCompositeConstruct %v2int %22686 %22686 + %18353 = OpShiftLeftLogical %v2int %18206 %1959 + %13339 = OpShiftRightArithmetic %v2int %18353 %2151 + %10915 = OpConvertSToF %v2float %13339 + %18251 = OpVectorTimesScalar %v2float %10915 %float_0_000976592302 + %24074 = OpExtInst %v2float %1 FMax %73 %18251 + %24334 = OpCompositeExtract %float %24074 0 + %15575 = OpCompositeExtract %float %24074 1 + %16673 = OpCompositeConstruct %v4float %24334 %15575 %float_0 %float_0 + %19525 = OpCompositeExtract %uint %10944 1 + %16036 = OpBitcast %int %19525 + %18207 = OpCompositeConstruct %v2int %16036 %16036 + %18354 = OpShiftLeftLogical %v2int %18207 %1959 + %13340 = OpShiftRightArithmetic %v2int %18354 %2151 + %10916 = OpConvertSToF %v2float %13340 + %18252 = OpVectorTimesScalar %v2float %10916 %float_0_000976592302 + %24075 = OpExtInst %v2float %1 FMax %73 %18252 + %24335 = OpCompositeExtract %float %24075 0 + %15576 = OpCompositeExtract %float %24075 1 + %16674 = OpCompositeConstruct %v4float %24335 %15576 %float_0 %float_0 + %19526 = OpCompositeExtract %uint %10944 2 + %16037 = OpBitcast %int %19526 + %18208 = OpCompositeConstruct %v2int %16037 %16037 + %18355 = OpShiftLeftLogical %v2int %18208 %1959 + %13341 = OpShiftRightArithmetic %v2int %18355 %2151 + %10917 = OpConvertSToF %v2float %13341 + %18253 = OpVectorTimesScalar %v2float %10917 %float_0_000976592302 + %24076 = OpExtInst %v2float %1 FMax %73 %18253 + %24336 = OpCompositeExtract %float %24076 0 + %15577 = OpCompositeExtract %float %24076 1 + %16675 = OpCompositeConstruct %v4float %24336 %15577 %float_0 %float_0 + %19527 = OpCompositeExtract %uint %10944 3 + %16038 = OpBitcast %int %19527 + %18212 = OpCompositeConstruct %v2int %16038 %16038 + %18356 = OpShiftLeftLogical %v2int %18212 %1959 + %13342 = OpShiftRightArithmetic %v2int %18356 %2151 + %10918 = OpConvertSToF %v2float %13342 + %18254 = OpVectorTimesScalar %v2float %10918 %float_0_000976592302 + %24077 = OpExtInst %v2float %1 FMax %73 %18254 + %24337 = OpCompositeExtract %float %24077 0 + %18765 = OpCompositeExtract %float %24077 1 + %9039 = OpCompositeConstruct %v4float %24337 %18765 %float_0 %float_0 + OpBranch %16225 + %7356 = OpLabel + %22208 = OpCompositeExtract %uint %10944 0 + %20237 = OpCompositeConstruct %v3uint %22208 %22208 %22208 + %11026 = OpShiftRightLogical %v3uint %20237 %2996 + %24042 = OpBitwiseAnd %v3uint %11026 %261 + %18592 = OpBitwiseAnd %v3uint %24042 %1126 + %23444 = OpShiftRightLogical %v3uint %24042 %2828 + %16589 = OpIEqual %v3bool %23444 %2578 + %11343 = OpExtInst %v3int %1 FindUMsb %18592 + %10777 = OpBitcast %v3uint %11343 + %6270 = OpISub %v3uint %2828 %10777 + %8724 = OpIAdd %v3uint %10777 %2360 + %10355 = OpSelect %v3uint %16589 %8724 %23444 + %23257 = OpShiftLeftLogical %v3uint %18592 %6270 + %18846 = OpBitwiseAnd %v3uint %23257 %1126 + %10919 = OpSelect %v3uint %16589 %18846 %18592 + %24573 = OpIAdd %v3uint %10355 %1018 + %20355 = OpShiftLeftLogical %v3uint %24573 %393 + %16298 = OpShiftLeftLogical %v3uint %10919 %141 + %22400 = OpBitwiseOr %v3uint %20355 %16298 + %13828 = OpIEqual %v3bool %24042 %2578 + %16966 = OpSelect %v3uint %13828 %2578 %22400 + %10707 = OpBitcast %v3float %16966 + %19368 = OpShiftRightLogical %uint %22208 %uint_30 + %18450 = OpConvertUToF %float %19368 + %15907 = OpFMul %float %18450 %float_0_333333343 + %21446 = OpCompositeExtract %float %10707 0 + %10841 = OpCompositeExtract %float %10707 1 + %7836 = OpCompositeExtract %float %10707 2 + %15837 = OpCompositeConstruct %v4float %21446 %10841 %7836 %15907 + %10232 = OpCompositeExtract %uint %10944 1 + %13585 = OpCompositeConstruct %v3uint %10232 %10232 %10232 + %11027 = OpShiftRightLogical %v3uint %13585 %2996 + %24043 = OpBitwiseAnd %v3uint %11027 %261 + %18593 = OpBitwiseAnd %v3uint %24043 %1126 + %23445 = OpShiftRightLogical %v3uint %24043 %2828 + %16590 = OpIEqual %v3bool %23445 %2578 + %11344 = OpExtInst %v3int %1 FindUMsb %18593 + %10778 = OpBitcast %v3uint %11344 + %6271 = OpISub %v3uint %2828 %10778 + %8725 = OpIAdd %v3uint %10778 %2360 + %10356 = OpSelect %v3uint %16590 %8725 %23445 + %23258 = OpShiftLeftLogical %v3uint %18593 %6271 + %18847 = OpBitwiseAnd %v3uint %23258 %1126 + %10920 = OpSelect %v3uint %16590 %18847 %18593 + %24574 = OpIAdd %v3uint %10356 %1018 + %20356 = OpShiftLeftLogical %v3uint %24574 %393 + %16299 = OpShiftLeftLogical %v3uint %10920 %141 + %22401 = OpBitwiseOr %v3uint %20356 %16299 + %13829 = OpIEqual %v3bool %24043 %2578 + %16967 = OpSelect %v3uint %13829 %2578 %22401 + %10708 = OpBitcast %v3float %16967 + %19369 = OpShiftRightLogical %uint %10232 %uint_30 + %18451 = OpConvertUToF %float %19369 + %15908 = OpFMul %float %18451 %float_0_333333343 + %21447 = OpCompositeExtract %float %10708 0 + %10842 = OpCompositeExtract %float %10708 1 + %7837 = OpCompositeExtract %float %10708 2 + %15838 = OpCompositeConstruct %v4float %21447 %10842 %7837 %15908 + %10233 = OpCompositeExtract %uint %10944 2 + %13586 = OpCompositeConstruct %v3uint %10233 %10233 %10233 + %11028 = OpShiftRightLogical %v3uint %13586 %2996 + %24044 = OpBitwiseAnd %v3uint %11028 %261 + %18594 = OpBitwiseAnd %v3uint %24044 %1126 + %23446 = OpShiftRightLogical %v3uint %24044 %2828 + %16591 = OpIEqual %v3bool %23446 %2578 + %11345 = OpExtInst %v3int %1 FindUMsb %18594 + %10779 = OpBitcast %v3uint %11345 + %6272 = OpISub %v3uint %2828 %10779 + %8726 = OpIAdd %v3uint %10779 %2360 + %10357 = OpSelect %v3uint %16591 %8726 %23446 + %23259 = OpShiftLeftLogical %v3uint %18594 %6272 + %18848 = OpBitwiseAnd %v3uint %23259 %1126 + %10921 = OpSelect %v3uint %16591 %18848 %18594 + %24575 = OpIAdd %v3uint %10357 %1018 + %20357 = OpShiftLeftLogical %v3uint %24575 %393 + %16300 = OpShiftLeftLogical %v3uint %10921 %141 + %22402 = OpBitwiseOr %v3uint %20357 %16300 + %13830 = OpIEqual %v3bool %24044 %2578 + %16968 = OpSelect %v3uint %13830 %2578 %22402 + %10709 = OpBitcast %v3float %16968 + %19370 = OpShiftRightLogical %uint %10233 %uint_30 + %18452 = OpConvertUToF %float %19370 + %15909 = OpFMul %float %18452 %float_0_333333343 + %21448 = OpCompositeExtract %float %10709 0 + %10843 = OpCompositeExtract %float %10709 1 + %7838 = OpCompositeExtract %float %10709 2 + %15839 = OpCompositeConstruct %v4float %21448 %10843 %7838 %15909 + %10234 = OpCompositeExtract %uint %10944 3 + %13587 = OpCompositeConstruct %v3uint %10234 %10234 %10234 + %11029 = OpShiftRightLogical %v3uint %13587 %2996 + %24045 = OpBitwiseAnd %v3uint %11029 %261 + %18595 = OpBitwiseAnd %v3uint %24045 %1126 + %23447 = OpShiftRightLogical %v3uint %24045 %2828 + %16592 = OpIEqual %v3bool %23447 %2578 + %11346 = OpExtInst %v3int %1 FindUMsb %18595 + %10780 = OpBitcast %v3uint %11346 + %6273 = OpISub %v3uint %2828 %10780 + %8727 = OpIAdd %v3uint %10780 %2360 + %10358 = OpSelect %v3uint %16592 %8727 %23447 + %23260 = OpShiftLeftLogical %v3uint %18595 %6273 + %18849 = OpBitwiseAnd %v3uint %23260 %1126 + %10922 = OpSelect %v3uint %16592 %18849 %18595 + %24576 = OpIAdd %v3uint %10358 %1018 + %20358 = OpShiftLeftLogical %v3uint %24576 %393 + %16301 = OpShiftLeftLogical %v3uint %10922 %141 + %22403 = OpBitwiseOr %v3uint %20358 %16301 + %13831 = OpIEqual %v3bool %24045 %2578 + %16969 = OpSelect %v3uint %13831 %2578 %22403 + %10710 = OpBitcast %v3float %16969 + %19371 = OpShiftRightLogical %uint %10234 %uint_30 + %18453 = OpConvertUToF %float %19371 + %15910 = OpFMul %float %18453 %float_0_333333343 + %21449 = OpCompositeExtract %float %10710 0 + %10844 = OpCompositeExtract %float %10710 1 + %11030 = OpCompositeExtract %float %10710 2 + %9040 = OpCompositeConstruct %v4float %21449 %10844 %11030 %15910 + OpBranch %16225 + %7357 = OpLabel + %22209 = OpCompositeExtract %uint %10944 0 + %20238 = OpCompositeConstruct %v4uint %22209 %22209 %22209 %22209 + %9376 = OpShiftRightLogical %v4uint %20238 %845 + %18863 = OpBitwiseAnd %v4uint %9376 %635 + %15546 = OpConvertUToF %v4float %18863 + %16691 = OpFMul %v4float %15546 %2798 + %23765 = OpCompositeExtract %uint %10944 1 + %20816 = OpCompositeConstruct %v4uint %23765 %23765 %23765 %23765 + %9377 = OpShiftRightLogical %v4uint %20816 %845 + %18864 = OpBitwiseAnd %v4uint %9377 %635 + %15547 = OpConvertUToF %v4float %18864 + %16692 = OpFMul %v4float %15547 %2798 + %23766 = OpCompositeExtract %uint %10944 2 + %20817 = OpCompositeConstruct %v4uint %23766 %23766 %23766 %23766 + %9378 = OpShiftRightLogical %v4uint %20817 %845 + %18865 = OpBitwiseAnd %v4uint %9378 %635 + %15548 = OpConvertUToF %v4float %18865 + %16693 = OpFMul %v4float %15548 %2798 + %23767 = OpCompositeExtract %uint %10944 3 + %20818 = OpCompositeConstruct %v4uint %23767 %23767 %23767 %23767 + %9379 = OpShiftRightLogical %v4uint %20818 %845 + %18866 = OpBitwiseAnd %v4uint %9379 %635 + %18736 = OpConvertUToF %v4float %18866 + %9888 = OpFMul %v4float %18736 %2798 + OpBranch %16225 + %14586 = OpLabel + %22210 = OpCompositeExtract %uint %10944 0 + %20239 = OpCompositeConstruct %v4uint %22210 %22210 %22210 %22210 + %9380 = OpShiftRightLogical %v4uint %20239 %653 + %19034 = OpBitwiseAnd %v4uint %9380 %1611 + %13989 = OpConvertUToF %v4float %19034 + %19238 = OpVectorTimesScalar %v4float %13989 %float_0_00392156886 + %8610 = OpCompositeExtract %uint %10944 1 + %24846 = OpCompositeConstruct %v4uint %8610 %8610 %8610 %8610 + %9381 = OpShiftRightLogical %v4uint %24846 %653 + %19035 = OpBitwiseAnd %v4uint %9381 %1611 + %13990 = OpConvertUToF %v4float %19035 + %19239 = OpVectorTimesScalar %v4float %13990 %float_0_00392156886 + %8611 = OpCompositeExtract %uint %10944 2 + %24847 = OpCompositeConstruct %v4uint %8611 %8611 %8611 %8611 + %9382 = OpShiftRightLogical %v4uint %24847 %653 + %19036 = OpBitwiseAnd %v4uint %9382 %1611 + %13992 = OpConvertUToF %v4float %19036 + %19240 = OpVectorTimesScalar %v4float %13992 %float_0_00392156886 + %8612 = OpCompositeExtract %uint %10944 3 + %24848 = OpCompositeConstruct %v4uint %8612 %8612 %8612 %8612 + %9383 = OpShiftRightLogical %v4uint %24848 %653 + %19037 = OpBitwiseAnd %v4uint %9383 %1611 + %17179 = OpConvertUToF %v4float %19037 + %12435 = OpVectorTimesScalar %v4float %17179 %float_0_00392156886 + OpBranch %16225 + %19452 = OpLabel + %12430 = OpCompositeExtract %uint %10944 0 + %20463 = OpBitcast %float %12430 + %17209 = OpCompositeConstruct %v2float %20463 %float_0 + %11667 = OpVectorShuffle %v4float %17209 %17209 0 1 1 1 + %22196 = OpCompositeExtract %uint %10944 1 + %16235 = OpBitcast %float %22196 + %17210 = OpCompositeConstruct %v2float %16235 %float_0 + %11668 = OpVectorShuffle %v4float %17210 %17210 0 1 1 1 + %22197 = OpCompositeExtract %uint %10944 2 + %16236 = OpBitcast %float %22197 + %17211 = OpCompositeConstruct %v2float %16236 %float_0 + %11669 = OpVectorShuffle %v4float %17211 %17211 0 1 1 1 + %22198 = OpCompositeExtract %uint %10944 3 + %16237 = OpBitcast %float %22198 + %20399 = OpCompositeConstruct %v2float %16237 %float_0 + %23099 = OpVectorShuffle %v4float %20399 %20399 0 1 1 1 + OpBranch %16225 + %16225 = OpLabel + %11178 = OpPhi %v4float %23099 %19452 %12435 %14586 %9888 %7357 %9040 %7356 %9039 %8191 %9038 %8245 + %14347 = OpPhi %v4float %11669 %19452 %19240 %14586 %16693 %7357 %15839 %7356 %16675 %8191 %14612 %8245 + %15231 = OpPhi %v4float %11668 %19452 %19239 %14586 %16692 %7357 %15838 %7356 %16674 %8191 %14611 %8245 + %14520 = OpPhi %v4float %11667 %19452 %19238 %14586 %16691 %7357 %15837 %7356 %16673 %8191 %14610 %8245 + OpBranch %21264 + %15206 = OpLabel + %21585 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20261 DontFlatten + OpBranchConditional %21585 %9765 %12132 + %12132 = OpLabel + %19410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24184 + %23881 = OpLoad %uint %19410 + %11706 = OpIAdd %uint %23256 %uint_81 + %6409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11706 + %23663 = OpLoad %uint %6409 + %11707 = OpIAdd %uint %24184 %6555 + %6410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11707 + %23664 = OpLoad %uint %6410 + %11708 = OpIAdd %uint %11707 %uint_1 + %24564 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11708 + %14157 = OpLoad %uint %24564 + %19671 = OpCompositeConstruct %v4uint %23881 %23663 %23664 %14157 + %17049 = OpIMul %uint %uint_2 %6555 + %13993 = OpIAdd %uint %24184 %17049 + %15235 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13993 + %23665 = OpLoad %uint %15235 + %11709 = OpIAdd %uint %13993 %uint_1 + %6478 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11709 + %24160 = OpLoad %uint %6478 + %6239 = OpIMul %uint %uint_3 %6555 + %8358 = OpIAdd %uint %24184 %6239 + %15236 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8358 + %23666 = OpLoad %uint %15236 + %11710 = OpIAdd %uint %8358 %uint_1 + %24565 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11710 + %16385 = OpLoad %uint %24565 + %20786 = OpCompositeConstruct %v4uint %23665 %24160 %23666 %16385 + OpBranch %20261 + %9765 = OpLabel + %21832 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24184 + %23882 = OpLoad %uint %21832 + %11711 = OpIAdd %uint %23256 %uint_81 + %6411 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11711 + %23667 = OpLoad %uint %6411 + %11712 = OpIAdd %uint %23256 %uint_82 + %6412 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11712 + %23668 = OpLoad %uint %6412 + %11713 = OpIAdd %uint %23256 %uint_83 + %24566 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11713 + %14081 = OpLoad %uint %24566 + %19166 = OpCompositeConstruct %v4uint %23882 %23667 %23668 %14081 + %22502 = OpIAdd %uint %23256 %uint_84 + %24652 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22502 + %23669 = OpLoad %uint %24652 + %11714 = OpIAdd %uint %23256 %uint_85 + %6413 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11714 + %23670 = OpLoad %uint %6413 + %11715 = OpIAdd %uint %23256 %uint_86 + %6414 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11715 + %23671 = OpLoad %uint %6414 + %11716 = OpIAdd %uint %23256 %uint_87 + %24567 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11716 + %16386 = OpLoad %uint %24567 + %20787 = OpCompositeConstruct %v4uint %23669 %23670 %23671 %16386 + OpBranch %20261 + %20261 = OpLabel + %11214 = OpPhi %v4uint %20787 %9765 %20786 %12132 + %14113 = OpPhi %v4uint %19166 %9765 %19671 %12132 + OpSelectionMerge %20262 None + OpSwitch %8576 %20311 5 %8537 7 %8246 + %8246 = OpLabel + %24409 = OpCompositeExtract %uint %14113 0 + %24682 = OpExtInst %v2float %1 UnpackHalf2x16 %24409 + %10105 = OpCompositeExtract %float %24682 0 + %16060 = OpCompositeExtract %float %24682 1 + %17029 = OpCompositeExtract %uint %14113 1 + %15609 = OpExtInst %v2float %1 UnpackHalf2x16 %17029 + %10094 = OpCompositeExtract %float %15609 0 + %17487 = OpCompositeExtract %float %15609 1 + %14613 = OpCompositeConstruct %v4float %10105 %16060 %10094 %17487 + %17283 = OpCompositeExtract %uint %14113 2 + %18036 = OpExtInst %v2float %1 UnpackHalf2x16 %17283 + %10106 = OpCompositeExtract %float %18036 0 + %16061 = OpCompositeExtract %float %18036 1 + %17030 = OpCompositeExtract %uint %14113 3 + %15610 = OpExtInst %v2float %1 UnpackHalf2x16 %17030 + %10095 = OpCompositeExtract %float %15610 0 + %17488 = OpCompositeExtract %float %15610 1 + %14614 = OpCompositeConstruct %v4float %10106 %16061 %10095 %17488 + %17284 = OpCompositeExtract %uint %11214 0 + %18037 = OpExtInst %v2float %1 UnpackHalf2x16 %17284 + %10107 = OpCompositeExtract %float %18037 0 + %16062 = OpCompositeExtract %float %18037 1 + %17031 = OpCompositeExtract %uint %11214 1 + %15611 = OpExtInst %v2float %1 UnpackHalf2x16 %17031 + %10096 = OpCompositeExtract %float %15611 0 + %17489 = OpCompositeExtract %float %15611 1 + %14615 = OpCompositeConstruct %v4float %10107 %16062 %10096 %17489 + %17285 = OpCompositeExtract %uint %11214 2 + %18038 = OpExtInst %v2float %1 UnpackHalf2x16 %17285 + %10108 = OpCompositeExtract %float %18038 0 + %16063 = OpCompositeExtract %float %18038 1 + %17032 = OpCompositeExtract %uint %11214 3 + %15612 = OpExtInst %v2float %1 UnpackHalf2x16 %17032 + %10097 = OpCompositeExtract %float %15612 0 + %20673 = OpCompositeExtract %float %15612 1 + %9041 = OpCompositeConstruct %v4float %10108 %16063 %10097 %20673 + OpBranch %20262 + %8537 = OpLabel + %9724 = OpVectorShuffle %v2uint %14113 %14113 0 1 + %23357 = OpBitcast %v2int %9724 + %24786 = OpVectorShuffle %v4int %23357 %23357 0 0 1 1 + %18602 = OpShiftLeftLogical %v4int %24786 %290 + %15761 = OpShiftRightArithmetic %v4int %18602 %770 + %10923 = OpConvertSToF %v4float %15761 + %18213 = OpVectorTimesScalar %v4float %10923 %float_0_000976592302 + %25236 = OpExtInst %v4float %1 FMax %1284 %18213 + %14190 = OpVectorShuffle %v2uint %14113 %14113 2 3 + %9410 = OpBitcast %v2int %14190 + %24787 = OpVectorShuffle %v4int %9410 %9410 0 0 1 1 + %18603 = OpShiftLeftLogical %v4int %24787 %290 + %15762 = OpShiftRightArithmetic %v4int %18603 %770 + %10924 = OpConvertSToF %v4float %15762 + %18214 = OpVectorTimesScalar %v4float %10924 %float_0_000976592302 + %25237 = OpExtInst %v4float %1 FMax %1284 %18214 + %14191 = OpVectorShuffle %v2uint %11214 %11214 0 1 + %9411 = OpBitcast %v2int %14191 + %24788 = OpVectorShuffle %v4int %9411 %9411 0 0 1 1 + %18604 = OpShiftLeftLogical %v4int %24788 %290 + %15763 = OpShiftRightArithmetic %v4int %18604 %770 + %10925 = OpConvertSToF %v4float %15763 + %18215 = OpVectorTimesScalar %v4float %10925 %float_0_000976592302 + %25238 = OpExtInst %v4float %1 FMax %1284 %18215 + %14192 = OpVectorShuffle %v2uint %11214 %11214 2 3 + %9412 = OpBitcast %v2int %14192 + %24789 = OpVectorShuffle %v4int %9412 %9412 0 0 1 1 + %18605 = OpShiftLeftLogical %v4int %24789 %290 + %15764 = OpShiftRightArithmetic %v4int %18605 %770 + %10926 = OpConvertSToF %v4float %15764 + %21440 = OpVectorTimesScalar %v4float %10926 %float_0_000976592302 + %17251 = OpExtInst %v4float %1 FMax %1284 %21440 + OpBranch %20262 + %20311 = OpLabel + %9766 = OpVectorShuffle %v2uint %14113 %14113 0 1 + %20826 = OpBitcast %v2float %9766 + %7039 = OpCompositeExtract %float %20826 0 + %13421 = OpCompositeExtract %float %20826 1 + %17019 = OpCompositeConstruct %v4float %7039 %13421 %float_0 %float_0 + %16859 = OpVectorShuffle %v2uint %14113 %14113 2 3 + %14176 = OpBitcast %v2float %16859 + %7040 = OpCompositeExtract %float %14176 0 + %13422 = OpCompositeExtract %float %14176 1 + %17020 = OpCompositeConstruct %v4float %7040 %13422 %float_0 %float_0 + %16860 = OpVectorShuffle %v2uint %11214 %11214 0 1 + %14177 = OpBitcast %v2float %16860 + %7041 = OpCompositeExtract %float %14177 0 + %13423 = OpCompositeExtract %float %14177 1 + %17021 = OpCompositeConstruct %v4float %7041 %13423 %float_0 %float_0 + %16861 = OpVectorShuffle %v2uint %11214 %11214 2 3 + %14178 = OpBitcast %v2float %16861 + %7042 = OpCompositeExtract %float %14178 0 + %16649 = OpCompositeExtract %float %14178 1 + %9042 = OpCompositeConstruct %v4float %7042 %16649 %float_0 %float_0 + OpBranch %20262 + %20262 = OpLabel + %11179 = OpPhi %v4float %9042 %20311 %17251 %8537 %9041 %8246 + %14348 = OpPhi %v4float %17021 %20311 %25238 %8537 %14615 %8246 + %15232 = OpPhi %v4float %17020 %20311 %25237 %8537 %14614 %8246 + %14521 = OpPhi %v4float %17019 %20311 %25236 %8537 %14613 %8246 + OpBranch %21264 + %21264 = OpLabel + %11180 = OpPhi %v4float %11179 %20262 %11178 %16225 + %14349 = OpPhi %v4float %14348 %20262 %14347 %16225 + %12949 = OpPhi %v4float %15232 %20262 %15231 %16225 + %13946 = OpPhi %v4float %14521 %20262 %14520 %16225 + %17241 = OpFAdd %v4float %8403 %13946 + %23297 = OpFAdd %v4float %13804 %12949 + %8082 = OpFAdd %v4float %14346 %14349 + %20755 = OpFAdd %v4float %11177 %11180 + %14461 = OpUGreaterThanEqual %bool %16205 %uint_6 + OpSelectionMerge %24264 DontFlatten + OpBranchConditional %14461 %9905 %24264 + %9905 = OpLabel + %14258 = OpShiftLeftLogical %uint %uint_1 %9130 + %12090 = OpFMul %float %11052 %float_0_25 + %20988 = OpIAdd %uint %23256 %14258 + OpSelectionMerge %21265 DontFlatten + OpBranchConditional %23279 %15207 %16571 + %16571 = OpLabel + %19167 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20299 DontFlatten + OpBranchConditional %19167 %9767 %12133 + %12133 = OpLabel + %19411 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23883 = OpLoad %uint %19411 + %11717 = OpIAdd %uint %20988 %6555 + %6479 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11717 + %24161 = OpLoad %uint %6479 + %6240 = OpIMul %uint %uint_2 %6555 + %8359 = OpIAdd %uint %20988 %6240 + %15311 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8359 + %24162 = OpLoad %uint %15311 + %6241 = OpIMul %uint %uint_3 %6555 + %8360 = OpIAdd %uint %20988 %6241 + %14323 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8360 + %16387 = OpLoad %uint %14323 + %20788 = OpCompositeConstruct %v4uint %23883 %24161 %24162 %16387 + OpBranch %20299 + %9767 = OpLabel + %21833 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23884 = OpLoad %uint %21833 + %11718 = OpIAdd %uint %20988 %uint_1 + %6415 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11718 + %23672 = OpLoad %uint %6415 + %11719 = OpIAdd %uint %20988 %uint_2 + %6416 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11719 + %23673 = OpLoad %uint %6416 + %11720 = OpIAdd %uint %20988 %uint_3 + %24568 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11720 + %16388 = OpLoad %uint %24568 + %20789 = OpCompositeConstruct %v4uint %23884 %23672 %23673 %16388 + OpBranch %20299 + %20299 = OpLabel + %10945 = OpPhi %v4uint %20789 %9767 %20788 %12133 + OpSelectionMerge %16226 None + OpSwitch %8576 %19453 0 %14587 1 %14587 2 %7359 10 %7359 3 %7358 12 %7358 4 %8192 6 %8247 + %8247 = OpLabel + %24410 = OpCompositeExtract %uint %10945 0 + %24683 = OpExtInst %v2float %1 UnpackHalf2x16 %24410 + %10098 = OpCompositeExtract %float %24683 0 + %17490 = OpCompositeExtract %float %24683 1 + %14616 = OpCompositeConstruct %v4float %10098 %17490 %float_0 %float_0 + %17286 = OpCompositeExtract %uint %10945 1 + %18039 = OpExtInst %v2float %1 UnpackHalf2x16 %17286 + %10099 = OpCompositeExtract %float %18039 0 + %17491 = OpCompositeExtract %float %18039 1 + %14617 = OpCompositeConstruct %v4float %10099 %17491 %float_0 %float_0 + %17287 = OpCompositeExtract %uint %10945 2 + %18040 = OpExtInst %v2float %1 UnpackHalf2x16 %17287 + %10100 = OpCompositeExtract %float %18040 0 + %17492 = OpCompositeExtract %float %18040 1 + %14618 = OpCompositeConstruct %v4float %10100 %17492 %float_0 %float_0 + %17288 = OpCompositeExtract %uint %10945 3 + %18041 = OpExtInst %v2float %1 UnpackHalf2x16 %17288 + %10109 = OpCompositeExtract %float %18041 0 + %20674 = OpCompositeExtract %float %18041 1 + %9043 = OpCompositeConstruct %v4float %10109 %20674 %float_0 %float_0 + OpBranch %16226 + %8192 = OpLabel + %12431 = OpCompositeExtract %uint %10945 0 + %22687 = OpBitcast %int %12431 + %18216 = OpCompositeConstruct %v2int %22687 %22687 + %18357 = OpShiftLeftLogical %v2int %18216 %1959 + %13343 = OpShiftRightArithmetic %v2int %18357 %2151 + %10927 = OpConvertSToF %v2float %13343 + %18255 = OpVectorTimesScalar %v2float %10927 %float_0_000976592302 + %24078 = OpExtInst %v2float %1 FMax %73 %18255 + %24338 = OpCompositeExtract %float %24078 0 + %15578 = OpCompositeExtract %float %24078 1 + %16676 = OpCompositeConstruct %v4float %24338 %15578 %float_0 %float_0 + %19528 = OpCompositeExtract %uint %10945 1 + %16039 = OpBitcast %int %19528 + %18217 = OpCompositeConstruct %v2int %16039 %16039 + %18358 = OpShiftLeftLogical %v2int %18217 %1959 + %13344 = OpShiftRightArithmetic %v2int %18358 %2151 + %10928 = OpConvertSToF %v2float %13344 + %18256 = OpVectorTimesScalar %v2float %10928 %float_0_000976592302 + %24079 = OpExtInst %v2float %1 FMax %73 %18256 + %24339 = OpCompositeExtract %float %24079 0 + %15579 = OpCompositeExtract %float %24079 1 + %16677 = OpCompositeConstruct %v4float %24339 %15579 %float_0 %float_0 + %19529 = OpCompositeExtract %uint %10945 2 + %16040 = OpBitcast %int %19529 + %18218 = OpCompositeConstruct %v2int %16040 %16040 + %18359 = OpShiftLeftLogical %v2int %18218 %1959 + %13345 = OpShiftRightArithmetic %v2int %18359 %2151 + %10929 = OpConvertSToF %v2float %13345 + %18257 = OpVectorTimesScalar %v2float %10929 %float_0_000976592302 + %24080 = OpExtInst %v2float %1 FMax %73 %18257 + %24340 = OpCompositeExtract %float %24080 0 + %15580 = OpCompositeExtract %float %24080 1 + %16678 = OpCompositeConstruct %v4float %24340 %15580 %float_0 %float_0 + %19530 = OpCompositeExtract %uint %10945 3 + %16041 = OpBitcast %int %19530 + %18219 = OpCompositeConstruct %v2int %16041 %16041 + %18360 = OpShiftLeftLogical %v2int %18219 %1959 + %13346 = OpShiftRightArithmetic %v2int %18360 %2151 + %10930 = OpConvertSToF %v2float %13346 + %18258 = OpVectorTimesScalar %v2float %10930 %float_0_000976592302 + %24081 = OpExtInst %v2float %1 FMax %73 %18258 + %24341 = OpCompositeExtract %float %24081 0 + %18766 = OpCompositeExtract %float %24081 1 + %9044 = OpCompositeConstruct %v4float %24341 %18766 %float_0 %float_0 + OpBranch %16226 + %7358 = OpLabel + %22211 = OpCompositeExtract %uint %10945 0 + %20240 = OpCompositeConstruct %v3uint %22211 %22211 %22211 + %11031 = OpShiftRightLogical %v3uint %20240 %2996 + %24046 = OpBitwiseAnd %v3uint %11031 %261 + %18596 = OpBitwiseAnd %v3uint %24046 %1126 + %23448 = OpShiftRightLogical %v3uint %24046 %2828 + %16593 = OpIEqual %v3bool %23448 %2578 + %11347 = OpExtInst %v3int %1 FindUMsb %18596 + %10781 = OpBitcast %v3uint %11347 + %6274 = OpISub %v3uint %2828 %10781 + %8728 = OpIAdd %v3uint %10781 %2360 + %10359 = OpSelect %v3uint %16593 %8728 %23448 + %23261 = OpShiftLeftLogical %v3uint %18596 %6274 + %18850 = OpBitwiseAnd %v3uint %23261 %1126 + %10931 = OpSelect %v3uint %16593 %18850 %18596 + %24577 = OpIAdd %v3uint %10359 %1018 + %20359 = OpShiftLeftLogical %v3uint %24577 %393 + %16302 = OpShiftLeftLogical %v3uint %10931 %141 + %22404 = OpBitwiseOr %v3uint %20359 %16302 + %13832 = OpIEqual %v3bool %24046 %2578 + %16970 = OpSelect %v3uint %13832 %2578 %22404 + %10711 = OpBitcast %v3float %16970 + %19372 = OpShiftRightLogical %uint %22211 %uint_30 + %18454 = OpConvertUToF %float %19372 + %15911 = OpFMul %float %18454 %float_0_333333343 + %21450 = OpCompositeExtract %float %10711 0 + %10845 = OpCompositeExtract %float %10711 1 + %7839 = OpCompositeExtract %float %10711 2 + %15840 = OpCompositeConstruct %v4float %21450 %10845 %7839 %15911 + %10235 = OpCompositeExtract %uint %10945 1 + %13588 = OpCompositeConstruct %v3uint %10235 %10235 %10235 + %11032 = OpShiftRightLogical %v3uint %13588 %2996 + %24047 = OpBitwiseAnd %v3uint %11032 %261 + %18597 = OpBitwiseAnd %v3uint %24047 %1126 + %23449 = OpShiftRightLogical %v3uint %24047 %2828 + %16594 = OpIEqual %v3bool %23449 %2578 + %11348 = OpExtInst %v3int %1 FindUMsb %18597 + %10782 = OpBitcast %v3uint %11348 + %6275 = OpISub %v3uint %2828 %10782 + %8729 = OpIAdd %v3uint %10782 %2360 + %10360 = OpSelect %v3uint %16594 %8729 %23449 + %23262 = OpShiftLeftLogical %v3uint %18597 %6275 + %18851 = OpBitwiseAnd %v3uint %23262 %1126 + %10932 = OpSelect %v3uint %16594 %18851 %18597 + %24578 = OpIAdd %v3uint %10360 %1018 + %20360 = OpShiftLeftLogical %v3uint %24578 %393 + %16303 = OpShiftLeftLogical %v3uint %10932 %141 + %22405 = OpBitwiseOr %v3uint %20360 %16303 + %13833 = OpIEqual %v3bool %24047 %2578 + %16971 = OpSelect %v3uint %13833 %2578 %22405 + %10712 = OpBitcast %v3float %16971 + %19373 = OpShiftRightLogical %uint %10235 %uint_30 + %18455 = OpConvertUToF %float %19373 + %15912 = OpFMul %float %18455 %float_0_333333343 + %21451 = OpCompositeExtract %float %10712 0 + %10846 = OpCompositeExtract %float %10712 1 + %7840 = OpCompositeExtract %float %10712 2 + %15841 = OpCompositeConstruct %v4float %21451 %10846 %7840 %15912 + %10236 = OpCompositeExtract %uint %10945 2 + %13589 = OpCompositeConstruct %v3uint %10236 %10236 %10236 + %11033 = OpShiftRightLogical %v3uint %13589 %2996 + %24048 = OpBitwiseAnd %v3uint %11033 %261 + %18606 = OpBitwiseAnd %v3uint %24048 %1126 + %23450 = OpShiftRightLogical %v3uint %24048 %2828 + %16595 = OpIEqual %v3bool %23450 %2578 + %11349 = OpExtInst %v3int %1 FindUMsb %18606 + %10783 = OpBitcast %v3uint %11349 + %6276 = OpISub %v3uint %2828 %10783 + %8730 = OpIAdd %v3uint %10783 %2360 + %10361 = OpSelect %v3uint %16595 %8730 %23450 + %23263 = OpShiftLeftLogical %v3uint %18606 %6276 + %18852 = OpBitwiseAnd %v3uint %23263 %1126 + %10933 = OpSelect %v3uint %16595 %18852 %18606 + %24579 = OpIAdd %v3uint %10361 %1018 + %20361 = OpShiftLeftLogical %v3uint %24579 %393 + %16304 = OpShiftLeftLogical %v3uint %10933 %141 + %22406 = OpBitwiseOr %v3uint %20361 %16304 + %13834 = OpIEqual %v3bool %24048 %2578 + %16972 = OpSelect %v3uint %13834 %2578 %22406 + %10713 = OpBitcast %v3float %16972 + %19374 = OpShiftRightLogical %uint %10236 %uint_30 + %18456 = OpConvertUToF %float %19374 + %15913 = OpFMul %float %18456 %float_0_333333343 + %21452 = OpCompositeExtract %float %10713 0 + %10847 = OpCompositeExtract %float %10713 1 + %7841 = OpCompositeExtract %float %10713 2 + %15842 = OpCompositeConstruct %v4float %21452 %10847 %7841 %15913 + %10237 = OpCompositeExtract %uint %10945 3 + %13590 = OpCompositeConstruct %v3uint %10237 %10237 %10237 + %11034 = OpShiftRightLogical %v3uint %13590 %2996 + %24049 = OpBitwiseAnd %v3uint %11034 %261 + %18607 = OpBitwiseAnd %v3uint %24049 %1126 + %23451 = OpShiftRightLogical %v3uint %24049 %2828 + %16596 = OpIEqual %v3bool %23451 %2578 + %11350 = OpExtInst %v3int %1 FindUMsb %18607 + %10784 = OpBitcast %v3uint %11350 + %6277 = OpISub %v3uint %2828 %10784 + %8731 = OpIAdd %v3uint %10784 %2360 + %10362 = OpSelect %v3uint %16596 %8731 %23451 + %23264 = OpShiftLeftLogical %v3uint %18607 %6277 + %18853 = OpBitwiseAnd %v3uint %23264 %1126 + %10934 = OpSelect %v3uint %16596 %18853 %18607 + %24580 = OpIAdd %v3uint %10362 %1018 + %20362 = OpShiftLeftLogical %v3uint %24580 %393 + %16305 = OpShiftLeftLogical %v3uint %10934 %141 + %22407 = OpBitwiseOr %v3uint %20362 %16305 + %13835 = OpIEqual %v3bool %24049 %2578 + %16973 = OpSelect %v3uint %13835 %2578 %22407 + %10714 = OpBitcast %v3float %16973 + %19375 = OpShiftRightLogical %uint %10237 %uint_30 + %18457 = OpConvertUToF %float %19375 + %15914 = OpFMul %float %18457 %float_0_333333343 + %21453 = OpCompositeExtract %float %10714 0 + %10848 = OpCompositeExtract %float %10714 1 + %11035 = OpCompositeExtract %float %10714 2 + %9045 = OpCompositeConstruct %v4float %21453 %10848 %11035 %15914 + OpBranch %16226 + %7359 = OpLabel + %22212 = OpCompositeExtract %uint %10945 0 + %20241 = OpCompositeConstruct %v4uint %22212 %22212 %22212 %22212 + %9384 = OpShiftRightLogical %v4uint %20241 %845 + %18867 = OpBitwiseAnd %v4uint %9384 %635 + %15549 = OpConvertUToF %v4float %18867 + %16694 = OpFMul %v4float %15549 %2798 + %23768 = OpCompositeExtract %uint %10945 1 + %20819 = OpCompositeConstruct %v4uint %23768 %23768 %23768 %23768 + %9385 = OpShiftRightLogical %v4uint %20819 %845 + %18868 = OpBitwiseAnd %v4uint %9385 %635 + %15550 = OpConvertUToF %v4float %18868 + %16695 = OpFMul %v4float %15550 %2798 + %23769 = OpCompositeExtract %uint %10945 2 + %20820 = OpCompositeConstruct %v4uint %23769 %23769 %23769 %23769 + %9386 = OpShiftRightLogical %v4uint %20820 %845 + %18869 = OpBitwiseAnd %v4uint %9386 %635 + %15551 = OpConvertUToF %v4float %18869 + %16696 = OpFMul %v4float %15551 %2798 + %23770 = OpCompositeExtract %uint %10945 3 + %20821 = OpCompositeConstruct %v4uint %23770 %23770 %23770 %23770 + %9387 = OpShiftRightLogical %v4uint %20821 %845 + %18870 = OpBitwiseAnd %v4uint %9387 %635 + %18737 = OpConvertUToF %v4float %18870 + %9889 = OpFMul %v4float %18737 %2798 + OpBranch %16226 + %14587 = OpLabel + %22213 = OpCompositeExtract %uint %10945 0 + %20242 = OpCompositeConstruct %v4uint %22213 %22213 %22213 %22213 + %9388 = OpShiftRightLogical %v4uint %20242 %653 + %19038 = OpBitwiseAnd %v4uint %9388 %1611 + %13994 = OpConvertUToF %v4float %19038 + %19241 = OpVectorTimesScalar %v4float %13994 %float_0_00392156886 + %8613 = OpCompositeExtract %uint %10945 1 + %24849 = OpCompositeConstruct %v4uint %8613 %8613 %8613 %8613 + %9389 = OpShiftRightLogical %v4uint %24849 %653 + %19039 = OpBitwiseAnd %v4uint %9389 %1611 + %13995 = OpConvertUToF %v4float %19039 + %19242 = OpVectorTimesScalar %v4float %13995 %float_0_00392156886 + %8614 = OpCompositeExtract %uint %10945 2 + %24850 = OpCompositeConstruct %v4uint %8614 %8614 %8614 %8614 + %9390 = OpShiftRightLogical %v4uint %24850 %653 + %19040 = OpBitwiseAnd %v4uint %9390 %1611 + %13996 = OpConvertUToF %v4float %19040 + %19243 = OpVectorTimesScalar %v4float %13996 %float_0_00392156886 + %8615 = OpCompositeExtract %uint %10945 3 + %24851 = OpCompositeConstruct %v4uint %8615 %8615 %8615 %8615 + %9391 = OpShiftRightLogical %v4uint %24851 %653 + %19041 = OpBitwiseAnd %v4uint %9391 %1611 + %17180 = OpConvertUToF %v4float %19041 + %12436 = OpVectorTimesScalar %v4float %17180 %float_0_00392156886 + OpBranch %16226 + %19453 = OpLabel + %12432 = OpCompositeExtract %uint %10945 0 + %20464 = OpBitcast %float %12432 + %17212 = OpCompositeConstruct %v2float %20464 %float_0 + %11670 = OpVectorShuffle %v4float %17212 %17212 0 1 1 1 + %22199 = OpCompositeExtract %uint %10945 1 + %16238 = OpBitcast %float %22199 + %17213 = OpCompositeConstruct %v2float %16238 %float_0 + %11671 = OpVectorShuffle %v4float %17213 %17213 0 1 1 1 + %22200 = OpCompositeExtract %uint %10945 2 + %16239 = OpBitcast %float %22200 + %17214 = OpCompositeConstruct %v2float %16239 %float_0 + %11672 = OpVectorShuffle %v4float %17214 %17214 0 1 1 1 + %22201 = OpCompositeExtract %uint %10945 3 + %16240 = OpBitcast %float %22201 + %20400 = OpCompositeConstruct %v2float %16240 %float_0 + %23100 = OpVectorShuffle %v4float %20400 %20400 0 1 1 1 + OpBranch %16226 + %16226 = OpLabel + %11181 = OpPhi %v4float %23100 %19453 %12436 %14587 %9889 %7359 %9045 %7358 %9044 %8192 %9043 %8247 + %14350 = OpPhi %v4float %11672 %19453 %19243 %14587 %16696 %7359 %15842 %7358 %16678 %8192 %14618 %8247 + %15237 = OpPhi %v4float %11671 %19453 %19242 %14587 %16695 %7359 %15841 %7358 %16677 %8192 %14617 %8247 + %14522 = OpPhi %v4float %11670 %19453 %19241 %14587 %16694 %7359 %15840 %7358 %16676 %8192 %14616 %8247 + OpBranch %21265 + %15207 = OpLabel + %21586 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20263 DontFlatten + OpBranchConditional %21586 %9768 %12134 + %12134 = OpLabel + %19412 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23885 = OpLoad %uint %19412 + %11721 = OpIAdd %uint %20988 %uint_1 + %6417 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11721 + %23674 = OpLoad %uint %6417 + %11722 = OpIAdd %uint %20988 %6555 + %6418 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11722 + %23675 = OpLoad %uint %6418 + %11723 = OpIAdd %uint %11722 %uint_1 + %24581 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11723 + %14158 = OpLoad %uint %24581 + %19673 = OpCompositeConstruct %v4uint %23885 %23674 %23675 %14158 + %17050 = OpIMul %uint %uint_2 %6555 + %13997 = OpIAdd %uint %20988 %17050 + %15238 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13997 + %23676 = OpLoad %uint %15238 + %11724 = OpIAdd %uint %13997 %uint_1 + %6480 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11724 + %24163 = OpLoad %uint %6480 + %6242 = OpIMul %uint %uint_3 %6555 + %8361 = OpIAdd %uint %20988 %6242 + %15239 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8361 + %23677 = OpLoad %uint %15239 + %11725 = OpIAdd %uint %8361 %uint_1 + %24582 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11725 + %16389 = OpLoad %uint %24582 + %20790 = OpCompositeConstruct %v4uint %23676 %24163 %23677 %16389 + OpBranch %20263 + %9768 = OpLabel + %21834 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23886 = OpLoad %uint %21834 + %11726 = OpIAdd %uint %20988 %uint_1 + %6419 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11726 + %23678 = OpLoad %uint %6419 + %11727 = OpIAdd %uint %20988 %uint_2 + %6420 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11727 + %23679 = OpLoad %uint %6420 + %11728 = OpIAdd %uint %20988 %uint_3 + %24583 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11728 + %14082 = OpLoad %uint %24583 + %19168 = OpCompositeConstruct %v4uint %23886 %23678 %23679 %14082 + %22503 = OpIAdd %uint %20988 %uint_4 + %24653 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22503 + %23680 = OpLoad %uint %24653 + %11729 = OpIAdd %uint %20988 %uint_5 + %6421 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11729 + %23681 = OpLoad %uint %6421 + %11730 = OpIAdd %uint %20988 %uint_6 + %6422 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11730 + %23682 = OpLoad %uint %6422 + %11731 = OpIAdd %uint %20988 %uint_7 + %24584 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11731 + %16390 = OpLoad %uint %24584 + %20791 = OpCompositeConstruct %v4uint %23680 %23681 %23682 %16390 + OpBranch %20263 + %20263 = OpLabel + %11215 = OpPhi %v4uint %20791 %9768 %20790 %12134 + %14114 = OpPhi %v4uint %19168 %9768 %19673 %12134 + OpSelectionMerge %20264 None + OpSwitch %8576 %20312 5 %8538 7 %8248 + %8248 = OpLabel + %24411 = OpCompositeExtract %uint %14114 0 + %24684 = OpExtInst %v2float %1 UnpackHalf2x16 %24411 + %10110 = OpCompositeExtract %float %24684 0 + %16064 = OpCompositeExtract %float %24684 1 + %17033 = OpCompositeExtract %uint %14114 1 + %15613 = OpExtInst %v2float %1 UnpackHalf2x16 %17033 + %10111 = OpCompositeExtract %float %15613 0 + %17493 = OpCompositeExtract %float %15613 1 + %14619 = OpCompositeConstruct %v4float %10110 %16064 %10111 %17493 + %17289 = OpCompositeExtract %uint %14114 2 + %18042 = OpExtInst %v2float %1 UnpackHalf2x16 %17289 + %10112 = OpCompositeExtract %float %18042 0 + %16065 = OpCompositeExtract %float %18042 1 + %17034 = OpCompositeExtract %uint %14114 3 + %15614 = OpExtInst %v2float %1 UnpackHalf2x16 %17034 + %10113 = OpCompositeExtract %float %15614 0 + %17494 = OpCompositeExtract %float %15614 1 + %14620 = OpCompositeConstruct %v4float %10112 %16065 %10113 %17494 + %17290 = OpCompositeExtract %uint %11215 0 + %18043 = OpExtInst %v2float %1 UnpackHalf2x16 %17290 + %10114 = OpCompositeExtract %float %18043 0 + %16066 = OpCompositeExtract %float %18043 1 + %17035 = OpCompositeExtract %uint %11215 1 + %15615 = OpExtInst %v2float %1 UnpackHalf2x16 %17035 + %10115 = OpCompositeExtract %float %15615 0 + %17495 = OpCompositeExtract %float %15615 1 + %14621 = OpCompositeConstruct %v4float %10114 %16066 %10115 %17495 + %17291 = OpCompositeExtract %uint %11215 2 + %18044 = OpExtInst %v2float %1 UnpackHalf2x16 %17291 + %10116 = OpCompositeExtract %float %18044 0 + %16067 = OpCompositeExtract %float %18044 1 + %17036 = OpCompositeExtract %uint %11215 3 + %15616 = OpExtInst %v2float %1 UnpackHalf2x16 %17036 + %10117 = OpCompositeExtract %float %15616 0 + %20675 = OpCompositeExtract %float %15616 1 + %9046 = OpCompositeConstruct %v4float %10116 %16067 %10117 %20675 + OpBranch %20264 + %8538 = OpLabel + %9725 = OpVectorShuffle %v2uint %14114 %14114 0 1 + %23358 = OpBitcast %v2int %9725 + %24790 = OpVectorShuffle %v4int %23358 %23358 0 0 1 1 + %18608 = OpShiftLeftLogical %v4int %24790 %290 + %15765 = OpShiftRightArithmetic %v4int %18608 %770 + %10935 = OpConvertSToF %v4float %15765 + %18220 = OpVectorTimesScalar %v4float %10935 %float_0_000976592302 + %25239 = OpExtInst %v4float %1 FMax %1284 %18220 + %14193 = OpVectorShuffle %v2uint %14114 %14114 2 3 + %9413 = OpBitcast %v2int %14193 + %24791 = OpVectorShuffle %v4int %9413 %9413 0 0 1 1 + %18609 = OpShiftLeftLogical %v4int %24791 %290 + %15766 = OpShiftRightArithmetic %v4int %18609 %770 + %10936 = OpConvertSToF %v4float %15766 + %18221 = OpVectorTimesScalar %v4float %10936 %float_0_000976592302 + %25240 = OpExtInst %v4float %1 FMax %1284 %18221 + %14194 = OpVectorShuffle %v2uint %11215 %11215 0 1 + %9414 = OpBitcast %v2int %14194 + %24792 = OpVectorShuffle %v4int %9414 %9414 0 0 1 1 + %18610 = OpShiftLeftLogical %v4int %24792 %290 + %15767 = OpShiftRightArithmetic %v4int %18610 %770 + %10937 = OpConvertSToF %v4float %15767 + %18222 = OpVectorTimesScalar %v4float %10937 %float_0_000976592302 + %25241 = OpExtInst %v4float %1 FMax %1284 %18222 + %14195 = OpVectorShuffle %v2uint %11215 %11215 2 3 + %9415 = OpBitcast %v2int %14195 + %24793 = OpVectorShuffle %v4int %9415 %9415 0 0 1 1 + %18611 = OpShiftLeftLogical %v4int %24793 %290 + %15768 = OpShiftRightArithmetic %v4int %18611 %770 + %10938 = OpConvertSToF %v4float %15768 + %21441 = OpVectorTimesScalar %v4float %10938 %float_0_000976592302 + %17252 = OpExtInst %v4float %1 FMax %1284 %21441 + OpBranch %20264 + %20312 = OpLabel + %9769 = OpVectorShuffle %v2uint %14114 %14114 0 1 + %20827 = OpBitcast %v2float %9769 + %7043 = OpCompositeExtract %float %20827 0 + %13424 = OpCompositeExtract %float %20827 1 + %17022 = OpCompositeConstruct %v4float %7043 %13424 %float_0 %float_0 + %16862 = OpVectorShuffle %v2uint %14114 %14114 2 3 + %14179 = OpBitcast %v2float %16862 + %7044 = OpCompositeExtract %float %14179 0 + %13425 = OpCompositeExtract %float %14179 1 + %17023 = OpCompositeConstruct %v4float %7044 %13425 %float_0 %float_0 + %16863 = OpVectorShuffle %v2uint %11215 %11215 0 1 + %14180 = OpBitcast %v2float %16863 + %7045 = OpCompositeExtract %float %14180 0 + %13426 = OpCompositeExtract %float %14180 1 + %17024 = OpCompositeConstruct %v4float %7045 %13426 %float_0 %float_0 + %16864 = OpVectorShuffle %v2uint %11215 %11215 2 3 + %14181 = OpBitcast %v2float %16864 + %7046 = OpCompositeExtract %float %14181 0 + %16650 = OpCompositeExtract %float %14181 1 + %9047 = OpCompositeConstruct %v4float %7046 %16650 %float_0 %float_0 + OpBranch %20264 + %20264 = OpLabel + %11182 = OpPhi %v4float %9047 %20312 %17252 %8538 %9046 %8248 + %14351 = OpPhi %v4float %17024 %20312 %25241 %8538 %14621 %8248 + %15240 = OpPhi %v4float %17023 %20312 %25240 %8538 %14620 %8248 + %14523 = OpPhi %v4float %17022 %20312 %25239 %8538 %14619 %8248 + OpBranch %21265 + %21265 = OpLabel + %11183 = OpPhi %v4float %11182 %20264 %11181 %16226 + %14352 = OpPhi %v4float %14351 %20264 %14350 %16226 + %12950 = OpPhi %v4float %15240 %20264 %15237 %16226 + %13947 = OpPhi %v4float %14523 %20264 %14522 %16226 + %17242 = OpFAdd %v4float %17241 %13947 + %23298 = OpFAdd %v4float %23297 %12950 + %7208 = OpFAdd %v4float %8082 %14352 + %9642 = OpFAdd %v4float %20755 %11183 + %16376 = OpIAdd %uint %24184 %14258 + OpSelectionMerge %21266 DontFlatten + OpBranchConditional %23279 %15208 %16572 + %16572 = OpLabel + %19169 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20300 DontFlatten + OpBranchConditional %19169 %9770 %12135 + %12135 = OpLabel + %19413 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23887 = OpLoad %uint %19413 + %11732 = OpIAdd %uint %16376 %6555 + %6481 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11732 + %24164 = OpLoad %uint %6481 + %6243 = OpIMul %uint %uint_2 %6555 + %8362 = OpIAdd %uint %16376 %6243 + %15312 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8362 + %24165 = OpLoad %uint %15312 + %6244 = OpIMul %uint %uint_3 %6555 + %8363 = OpIAdd %uint %16376 %6244 + %14324 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8363 + %16391 = OpLoad %uint %14324 + %20792 = OpCompositeConstruct %v4uint %23887 %24164 %24165 %16391 + OpBranch %20300 + %9770 = OpLabel + %21835 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23888 = OpLoad %uint %21835 + %11733 = OpIAdd %uint %16376 %uint_1 + %6423 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11733 + %23683 = OpLoad %uint %6423 + %11734 = OpIAdd %uint %16376 %uint_2 + %6424 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11734 + %23684 = OpLoad %uint %6424 + %11735 = OpIAdd %uint %16376 %uint_3 + %24585 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11735 + %16392 = OpLoad %uint %24585 + %20793 = OpCompositeConstruct %v4uint %23888 %23683 %23684 %16392 + OpBranch %20300 + %20300 = OpLabel + %10946 = OpPhi %v4uint %20793 %9770 %20792 %12135 + OpSelectionMerge %16227 None + OpSwitch %8576 %19454 0 %14588 1 %14588 2 %7361 10 %7361 3 %7360 12 %7360 4 %8193 6 %8249 + %8249 = OpLabel + %24412 = OpCompositeExtract %uint %10946 0 + %24685 = OpExtInst %v2float %1 UnpackHalf2x16 %24412 + %10118 = OpCompositeExtract %float %24685 0 + %17496 = OpCompositeExtract %float %24685 1 + %14622 = OpCompositeConstruct %v4float %10118 %17496 %float_0 %float_0 + %17292 = OpCompositeExtract %uint %10946 1 + %18045 = OpExtInst %v2float %1 UnpackHalf2x16 %17292 + %10119 = OpCompositeExtract %float %18045 0 + %17497 = OpCompositeExtract %float %18045 1 + %14623 = OpCompositeConstruct %v4float %10119 %17497 %float_0 %float_0 + %17293 = OpCompositeExtract %uint %10946 2 + %18046 = OpExtInst %v2float %1 UnpackHalf2x16 %17293 + %10120 = OpCompositeExtract %float %18046 0 + %17498 = OpCompositeExtract %float %18046 1 + %14624 = OpCompositeConstruct %v4float %10120 %17498 %float_0 %float_0 + %17294 = OpCompositeExtract %uint %10946 3 + %18047 = OpExtInst %v2float %1 UnpackHalf2x16 %17294 + %10121 = OpCompositeExtract %float %18047 0 + %20676 = OpCompositeExtract %float %18047 1 + %9048 = OpCompositeConstruct %v4float %10121 %20676 %float_0 %float_0 + OpBranch %16227 + %8193 = OpLabel + %12433 = OpCompositeExtract %uint %10946 0 + %22688 = OpBitcast %int %12433 + %18223 = OpCompositeConstruct %v2int %22688 %22688 + %18361 = OpShiftLeftLogical %v2int %18223 %1959 + %13347 = OpShiftRightArithmetic %v2int %18361 %2151 + %10939 = OpConvertSToF %v2float %13347 + %18259 = OpVectorTimesScalar %v2float %10939 %float_0_000976592302 + %24082 = OpExtInst %v2float %1 FMax %73 %18259 + %24342 = OpCompositeExtract %float %24082 0 + %15581 = OpCompositeExtract %float %24082 1 + %16679 = OpCompositeConstruct %v4float %24342 %15581 %float_0 %float_0 + %19531 = OpCompositeExtract %uint %10946 1 + %16042 = OpBitcast %int %19531 + %18224 = OpCompositeConstruct %v2int %16042 %16042 + %18362 = OpShiftLeftLogical %v2int %18224 %1959 + %13348 = OpShiftRightArithmetic %v2int %18362 %2151 + %10940 = OpConvertSToF %v2float %13348 + %18260 = OpVectorTimesScalar %v2float %10940 %float_0_000976592302 + %24083 = OpExtInst %v2float %1 FMax %73 %18260 + %24343 = OpCompositeExtract %float %24083 0 + %15582 = OpCompositeExtract %float %24083 1 + %16680 = OpCompositeConstruct %v4float %24343 %15582 %float_0 %float_0 + %19532 = OpCompositeExtract %uint %10946 2 + %16043 = OpBitcast %int %19532 + %18225 = OpCompositeConstruct %v2int %16043 %16043 + %18363 = OpShiftLeftLogical %v2int %18225 %1959 + %13349 = OpShiftRightArithmetic %v2int %18363 %2151 + %10941 = OpConvertSToF %v2float %13349 + %18261 = OpVectorTimesScalar %v2float %10941 %float_0_000976592302 + %24084 = OpExtInst %v2float %1 FMax %73 %18261 + %24344 = OpCompositeExtract %float %24084 0 + %15583 = OpCompositeExtract %float %24084 1 + %16681 = OpCompositeConstruct %v4float %24344 %15583 %float_0 %float_0 + %19533 = OpCompositeExtract %uint %10946 3 + %16044 = OpBitcast %int %19533 + %18226 = OpCompositeConstruct %v2int %16044 %16044 + %18364 = OpShiftLeftLogical %v2int %18226 %1959 + %13350 = OpShiftRightArithmetic %v2int %18364 %2151 + %10942 = OpConvertSToF %v2float %13350 + %18262 = OpVectorTimesScalar %v2float %10942 %float_0_000976592302 + %24085 = OpExtInst %v2float %1 FMax %73 %18262 + %24345 = OpCompositeExtract %float %24085 0 + %18767 = OpCompositeExtract %float %24085 1 + %9049 = OpCompositeConstruct %v4float %24345 %18767 %float_0 %float_0 + OpBranch %16227 + %7360 = OpLabel + %22214 = OpCompositeExtract %uint %10946 0 + %20243 = OpCompositeConstruct %v3uint %22214 %22214 %22214 + %11036 = OpShiftRightLogical %v3uint %20243 %2996 + %24050 = OpBitwiseAnd %v3uint %11036 %261 + %18612 = OpBitwiseAnd %v3uint %24050 %1126 + %23452 = OpShiftRightLogical %v3uint %24050 %2828 + %16597 = OpIEqual %v3bool %23452 %2578 + %11351 = OpExtInst %v3int %1 FindUMsb %18612 + %10785 = OpBitcast %v3uint %11351 + %6278 = OpISub %v3uint %2828 %10785 + %8732 = OpIAdd %v3uint %10785 %2360 + %10363 = OpSelect %v3uint %16597 %8732 %23452 + %23265 = OpShiftLeftLogical %v3uint %18612 %6278 + %18854 = OpBitwiseAnd %v3uint %23265 %1126 + %10947 = OpSelect %v3uint %16597 %18854 %18612 + %24586 = OpIAdd %v3uint %10363 %1018 + %20363 = OpShiftLeftLogical %v3uint %24586 %393 + %16306 = OpShiftLeftLogical %v3uint %10947 %141 + %22408 = OpBitwiseOr %v3uint %20363 %16306 + %13836 = OpIEqual %v3bool %24050 %2578 + %16974 = OpSelect %v3uint %13836 %2578 %22408 + %10715 = OpBitcast %v3float %16974 + %19376 = OpShiftRightLogical %uint %22214 %uint_30 + %18458 = OpConvertUToF %float %19376 + %15915 = OpFMul %float %18458 %float_0_333333343 + %21454 = OpCompositeExtract %float %10715 0 + %10849 = OpCompositeExtract %float %10715 1 + %7842 = OpCompositeExtract %float %10715 2 + %15843 = OpCompositeConstruct %v4float %21454 %10849 %7842 %15915 + %10238 = OpCompositeExtract %uint %10946 1 + %13591 = OpCompositeConstruct %v3uint %10238 %10238 %10238 + %11037 = OpShiftRightLogical %v3uint %13591 %2996 + %24051 = OpBitwiseAnd %v3uint %11037 %261 + %18613 = OpBitwiseAnd %v3uint %24051 %1126 + %23453 = OpShiftRightLogical %v3uint %24051 %2828 + %16598 = OpIEqual %v3bool %23453 %2578 + %11352 = OpExtInst %v3int %1 FindUMsb %18613 + %10786 = OpBitcast %v3uint %11352 + %6279 = OpISub %v3uint %2828 %10786 + %8733 = OpIAdd %v3uint %10786 %2360 + %10364 = OpSelect %v3uint %16598 %8733 %23453 + %23266 = OpShiftLeftLogical %v3uint %18613 %6279 + %18855 = OpBitwiseAnd %v3uint %23266 %1126 + %10948 = OpSelect %v3uint %16598 %18855 %18613 + %24587 = OpIAdd %v3uint %10364 %1018 + %20364 = OpShiftLeftLogical %v3uint %24587 %393 + %16307 = OpShiftLeftLogical %v3uint %10948 %141 + %22409 = OpBitwiseOr %v3uint %20364 %16307 + %13837 = OpIEqual %v3bool %24051 %2578 + %16975 = OpSelect %v3uint %13837 %2578 %22409 + %10716 = OpBitcast %v3float %16975 + %19377 = OpShiftRightLogical %uint %10238 %uint_30 + %18459 = OpConvertUToF %float %19377 + %15916 = OpFMul %float %18459 %float_0_333333343 + %21455 = OpCompositeExtract %float %10716 0 + %10850 = OpCompositeExtract %float %10716 1 + %7843 = OpCompositeExtract %float %10716 2 + %15844 = OpCompositeConstruct %v4float %21455 %10850 %7843 %15916 + %10239 = OpCompositeExtract %uint %10946 2 + %13592 = OpCompositeConstruct %v3uint %10239 %10239 %10239 + %11038 = OpShiftRightLogical %v3uint %13592 %2996 + %24052 = OpBitwiseAnd %v3uint %11038 %261 + %18614 = OpBitwiseAnd %v3uint %24052 %1126 + %23454 = OpShiftRightLogical %v3uint %24052 %2828 + %16599 = OpIEqual %v3bool %23454 %2578 + %11353 = OpExtInst %v3int %1 FindUMsb %18614 + %10787 = OpBitcast %v3uint %11353 + %6280 = OpISub %v3uint %2828 %10787 + %8734 = OpIAdd %v3uint %10787 %2360 + %10365 = OpSelect %v3uint %16599 %8734 %23454 + %23267 = OpShiftLeftLogical %v3uint %18614 %6280 + %18856 = OpBitwiseAnd %v3uint %23267 %1126 + %10949 = OpSelect %v3uint %16599 %18856 %18614 + %24588 = OpIAdd %v3uint %10365 %1018 + %20365 = OpShiftLeftLogical %v3uint %24588 %393 + %16308 = OpShiftLeftLogical %v3uint %10949 %141 + %22410 = OpBitwiseOr %v3uint %20365 %16308 + %13838 = OpIEqual %v3bool %24052 %2578 + %16976 = OpSelect %v3uint %13838 %2578 %22410 + %10717 = OpBitcast %v3float %16976 + %19378 = OpShiftRightLogical %uint %10239 %uint_30 + %18460 = OpConvertUToF %float %19378 + %15917 = OpFMul %float %18460 %float_0_333333343 + %21456 = OpCompositeExtract %float %10717 0 + %10851 = OpCompositeExtract %float %10717 1 + %7844 = OpCompositeExtract %float %10717 2 + %15845 = OpCompositeConstruct %v4float %21456 %10851 %7844 %15917 + %10240 = OpCompositeExtract %uint %10946 3 + %13593 = OpCompositeConstruct %v3uint %10240 %10240 %10240 + %11039 = OpShiftRightLogical %v3uint %13593 %2996 + %24053 = OpBitwiseAnd %v3uint %11039 %261 + %18615 = OpBitwiseAnd %v3uint %24053 %1126 + %23455 = OpShiftRightLogical %v3uint %24053 %2828 + %16600 = OpIEqual %v3bool %23455 %2578 + %11354 = OpExtInst %v3int %1 FindUMsb %18615 + %10788 = OpBitcast %v3uint %11354 + %6281 = OpISub %v3uint %2828 %10788 + %8735 = OpIAdd %v3uint %10788 %2360 + %10366 = OpSelect %v3uint %16600 %8735 %23455 + %23268 = OpShiftLeftLogical %v3uint %18615 %6281 + %18857 = OpBitwiseAnd %v3uint %23268 %1126 + %10950 = OpSelect %v3uint %16600 %18857 %18615 + %24589 = OpIAdd %v3uint %10366 %1018 + %20366 = OpShiftLeftLogical %v3uint %24589 %393 + %16309 = OpShiftLeftLogical %v3uint %10950 %141 + %22411 = OpBitwiseOr %v3uint %20366 %16309 + %13839 = OpIEqual %v3bool %24053 %2578 + %16977 = OpSelect %v3uint %13839 %2578 %22411 + %10718 = OpBitcast %v3float %16977 + %19379 = OpShiftRightLogical %uint %10240 %uint_30 + %18461 = OpConvertUToF %float %19379 + %15918 = OpFMul %float %18461 %float_0_333333343 + %21457 = OpCompositeExtract %float %10718 0 + %10852 = OpCompositeExtract %float %10718 1 + %11040 = OpCompositeExtract %float %10718 2 + %9050 = OpCompositeConstruct %v4float %21457 %10852 %11040 %15918 + OpBranch %16227 + %7361 = OpLabel + %22215 = OpCompositeExtract %uint %10946 0 + %20244 = OpCompositeConstruct %v4uint %22215 %22215 %22215 %22215 + %9392 = OpShiftRightLogical %v4uint %20244 %845 + %18871 = OpBitwiseAnd %v4uint %9392 %635 + %15552 = OpConvertUToF %v4float %18871 + %16697 = OpFMul %v4float %15552 %2798 + %23771 = OpCompositeExtract %uint %10946 1 + %20822 = OpCompositeConstruct %v4uint %23771 %23771 %23771 %23771 + %9393 = OpShiftRightLogical %v4uint %20822 %845 + %18872 = OpBitwiseAnd %v4uint %9393 %635 + %15553 = OpConvertUToF %v4float %18872 + %16698 = OpFMul %v4float %15553 %2798 + %23772 = OpCompositeExtract %uint %10946 2 + %20823 = OpCompositeConstruct %v4uint %23772 %23772 %23772 %23772 + %9394 = OpShiftRightLogical %v4uint %20823 %845 + %18873 = OpBitwiseAnd %v4uint %9394 %635 + %15554 = OpConvertUToF %v4float %18873 + %16699 = OpFMul %v4float %15554 %2798 + %23773 = OpCompositeExtract %uint %10946 3 + %20828 = OpCompositeConstruct %v4uint %23773 %23773 %23773 %23773 + %9395 = OpShiftRightLogical %v4uint %20828 %845 + %18874 = OpBitwiseAnd %v4uint %9395 %635 + %18738 = OpConvertUToF %v4float %18874 + %9890 = OpFMul %v4float %18738 %2798 + OpBranch %16227 + %14588 = OpLabel + %22216 = OpCompositeExtract %uint %10946 0 + %20245 = OpCompositeConstruct %v4uint %22216 %22216 %22216 %22216 + %9396 = OpShiftRightLogical %v4uint %20245 %653 + %19042 = OpBitwiseAnd %v4uint %9396 %1611 + %13998 = OpConvertUToF %v4float %19042 + %19244 = OpVectorTimesScalar %v4float %13998 %float_0_00392156886 + %8616 = OpCompositeExtract %uint %10946 1 + %24852 = OpCompositeConstruct %v4uint %8616 %8616 %8616 %8616 + %9397 = OpShiftRightLogical %v4uint %24852 %653 + %19043 = OpBitwiseAnd %v4uint %9397 %1611 + %13999 = OpConvertUToF %v4float %19043 + %19245 = OpVectorTimesScalar %v4float %13999 %float_0_00392156886 + %8617 = OpCompositeExtract %uint %10946 2 + %24853 = OpCompositeConstruct %v4uint %8617 %8617 %8617 %8617 + %9398 = OpShiftRightLogical %v4uint %24853 %653 + %19044 = OpBitwiseAnd %v4uint %9398 %1611 + %14000 = OpConvertUToF %v4float %19044 + %19246 = OpVectorTimesScalar %v4float %14000 %float_0_00392156886 + %8618 = OpCompositeExtract %uint %10946 3 + %24854 = OpCompositeConstruct %v4uint %8618 %8618 %8618 %8618 + %9399 = OpShiftRightLogical %v4uint %24854 %653 + %19045 = OpBitwiseAnd %v4uint %9399 %1611 + %17181 = OpConvertUToF %v4float %19045 + %12437 = OpVectorTimesScalar %v4float %17181 %float_0_00392156886 + OpBranch %16227 + %19454 = OpLabel + %12438 = OpCompositeExtract %uint %10946 0 + %20465 = OpBitcast %float %12438 + %17215 = OpCompositeConstruct %v2float %20465 %float_0 + %11673 = OpVectorShuffle %v4float %17215 %17215 0 1 1 1 + %22202 = OpCompositeExtract %uint %10946 1 + %16241 = OpBitcast %float %22202 + %17216 = OpCompositeConstruct %v2float %16241 %float_0 + %11674 = OpVectorShuffle %v4float %17216 %17216 0 1 1 1 + %22203 = OpCompositeExtract %uint %10946 2 + %16242 = OpBitcast %float %22203 + %17217 = OpCompositeConstruct %v2float %16242 %float_0 + %11675 = OpVectorShuffle %v4float %17217 %17217 0 1 1 1 + %22204 = OpCompositeExtract %uint %10946 3 + %16243 = OpBitcast %float %22204 + %20401 = OpCompositeConstruct %v2float %16243 %float_0 + %23101 = OpVectorShuffle %v4float %20401 %20401 0 1 1 1 + OpBranch %16227 + %16227 = OpLabel + %11184 = OpPhi %v4float %23101 %19454 %12437 %14588 %9890 %7361 %9050 %7360 %9049 %8193 %9048 %8249 + %14353 = OpPhi %v4float %11675 %19454 %19246 %14588 %16699 %7361 %15845 %7360 %16681 %8193 %14624 %8249 + %15241 = OpPhi %v4float %11674 %19454 %19245 %14588 %16698 %7361 %15844 %7360 %16680 %8193 %14623 %8249 + %14524 = OpPhi %v4float %11673 %19454 %19244 %14588 %16697 %7361 %15843 %7360 %16679 %8193 %14622 %8249 + OpBranch %21266 + %15208 = OpLabel + %21587 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20265 DontFlatten + OpBranchConditional %21587 %9771 %12136 + %12136 = OpLabel + %19414 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23889 = OpLoad %uint %19414 + %11736 = OpIAdd %uint %16376 %uint_1 + %6425 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11736 + %23685 = OpLoad %uint %6425 + %11737 = OpIAdd %uint %16376 %6555 + %6426 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11737 + %23686 = OpLoad %uint %6426 + %11738 = OpIAdd %uint %11737 %uint_1 + %24590 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11738 + %14160 = OpLoad %uint %24590 + %19674 = OpCompositeConstruct %v4uint %23889 %23685 %23686 %14160 + %17051 = OpIMul %uint %uint_2 %6555 + %14001 = OpIAdd %uint %16376 %17051 + %15242 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %14001 + %23687 = OpLoad %uint %15242 + %11739 = OpIAdd %uint %14001 %uint_1 + %6482 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11739 + %24166 = OpLoad %uint %6482 + %6245 = OpIMul %uint %uint_3 %6555 + %8364 = OpIAdd %uint %16376 %6245 + %15243 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8364 + %23688 = OpLoad %uint %15243 + %11740 = OpIAdd %uint %8364 %uint_1 + %24591 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11740 + %16393 = OpLoad %uint %24591 + %20794 = OpCompositeConstruct %v4uint %23687 %24166 %23688 %16393 + OpBranch %20265 + %9771 = OpLabel + %21836 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23890 = OpLoad %uint %21836 + %11741 = OpIAdd %uint %16376 %uint_1 + %6427 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11741 + %23689 = OpLoad %uint %6427 + %11742 = OpIAdd %uint %16376 %uint_2 + %6428 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11742 + %23690 = OpLoad %uint %6428 + %11743 = OpIAdd %uint %16376 %uint_3 + %24592 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11743 + %14083 = OpLoad %uint %24592 + %19170 = OpCompositeConstruct %v4uint %23890 %23689 %23690 %14083 + %22504 = OpIAdd %uint %16376 %uint_4 + %24654 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22504 + %23691 = OpLoad %uint %24654 + %11744 = OpIAdd %uint %16376 %uint_5 + %6429 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11744 + %23692 = OpLoad %uint %6429 + %11745 = OpIAdd %uint %16376 %uint_6 + %6430 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11745 + %23693 = OpLoad %uint %6430 + %11746 = OpIAdd %uint %16376 %uint_7 + %24593 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11746 + %16394 = OpLoad %uint %24593 + %20795 = OpCompositeConstruct %v4uint %23691 %23692 %23693 %16394 + OpBranch %20265 + %20265 = OpLabel + %11216 = OpPhi %v4uint %20795 %9771 %20794 %12136 + %14115 = OpPhi %v4uint %19170 %9771 %19674 %12136 + OpSelectionMerge %20266 None + OpSwitch %8576 %20313 5 %8539 7 %8250 + %8250 = OpLabel + %24413 = OpCompositeExtract %uint %14115 0 + %24686 = OpExtInst %v2float %1 UnpackHalf2x16 %24413 + %10122 = OpCompositeExtract %float %24686 0 + %16068 = OpCompositeExtract %float %24686 1 + %17037 = OpCompositeExtract %uint %14115 1 + %15617 = OpExtInst %v2float %1 UnpackHalf2x16 %17037 + %10123 = OpCompositeExtract %float %15617 0 + %17499 = OpCompositeExtract %float %15617 1 + %14625 = OpCompositeConstruct %v4float %10122 %16068 %10123 %17499 + %17295 = OpCompositeExtract %uint %14115 2 + %18048 = OpExtInst %v2float %1 UnpackHalf2x16 %17295 + %10124 = OpCompositeExtract %float %18048 0 + %16069 = OpCompositeExtract %float %18048 1 + %17038 = OpCompositeExtract %uint %14115 3 + %15618 = OpExtInst %v2float %1 UnpackHalf2x16 %17038 + %10125 = OpCompositeExtract %float %15618 0 + %17500 = OpCompositeExtract %float %15618 1 + %14626 = OpCompositeConstruct %v4float %10124 %16069 %10125 %17500 + %17296 = OpCompositeExtract %uint %11216 0 + %18049 = OpExtInst %v2float %1 UnpackHalf2x16 %17296 + %10126 = OpCompositeExtract %float %18049 0 + %16070 = OpCompositeExtract %float %18049 1 + %17039 = OpCompositeExtract %uint %11216 1 + %15619 = OpExtInst %v2float %1 UnpackHalf2x16 %17039 + %10127 = OpCompositeExtract %float %15619 0 + %17501 = OpCompositeExtract %float %15619 1 + %14627 = OpCompositeConstruct %v4float %10126 %16070 %10127 %17501 + %17297 = OpCompositeExtract %uint %11216 2 + %18050 = OpExtInst %v2float %1 UnpackHalf2x16 %17297 + %10128 = OpCompositeExtract %float %18050 0 + %16071 = OpCompositeExtract %float %18050 1 + %17040 = OpCompositeExtract %uint %11216 3 + %15620 = OpExtInst %v2float %1 UnpackHalf2x16 %17040 + %10129 = OpCompositeExtract %float %15620 0 + %20677 = OpCompositeExtract %float %15620 1 + %9051 = OpCompositeConstruct %v4float %10128 %16071 %10129 %20677 + OpBranch %20266 + %8539 = OpLabel + %9726 = OpVectorShuffle %v2uint %14115 %14115 0 1 + %23359 = OpBitcast %v2int %9726 + %24794 = OpVectorShuffle %v4int %23359 %23359 0 0 1 1 + %18616 = OpShiftLeftLogical %v4int %24794 %290 + %15769 = OpShiftRightArithmetic %v4int %18616 %770 + %10951 = OpConvertSToF %v4float %15769 + %18227 = OpVectorTimesScalar %v4float %10951 %float_0_000976592302 + %25242 = OpExtInst %v4float %1 FMax %1284 %18227 + %14196 = OpVectorShuffle %v2uint %14115 %14115 2 3 + %9416 = OpBitcast %v2int %14196 + %24795 = OpVectorShuffle %v4int %9416 %9416 0 0 1 1 + %18617 = OpShiftLeftLogical %v4int %24795 %290 + %15770 = OpShiftRightArithmetic %v4int %18617 %770 + %10952 = OpConvertSToF %v4float %15770 + %18228 = OpVectorTimesScalar %v4float %10952 %float_0_000976592302 + %25243 = OpExtInst %v4float %1 FMax %1284 %18228 + %14197 = OpVectorShuffle %v2uint %11216 %11216 0 1 + %9417 = OpBitcast %v2int %14197 + %24796 = OpVectorShuffle %v4int %9417 %9417 0 0 1 1 + %18618 = OpShiftLeftLogical %v4int %24796 %290 + %15771 = OpShiftRightArithmetic %v4int %18618 %770 + %10953 = OpConvertSToF %v4float %15771 + %18229 = OpVectorTimesScalar %v4float %10953 %float_0_000976592302 + %25244 = OpExtInst %v4float %1 FMax %1284 %18229 + %14198 = OpVectorShuffle %v2uint %11216 %11216 2 3 + %9418 = OpBitcast %v2int %14198 + %24797 = OpVectorShuffle %v4int %9418 %9418 0 0 1 1 + %18619 = OpShiftLeftLogical %v4int %24797 %290 + %15772 = OpShiftRightArithmetic %v4int %18619 %770 + %10954 = OpConvertSToF %v4float %15772 + %21458 = OpVectorTimesScalar %v4float %10954 %float_0_000976592302 + %17253 = OpExtInst %v4float %1 FMax %1284 %21458 + OpBranch %20266 + %20313 = OpLabel + %9772 = OpVectorShuffle %v2uint %14115 %14115 0 1 + %20829 = OpBitcast %v2float %9772 + %7047 = OpCompositeExtract %float %20829 0 + %13427 = OpCompositeExtract %float %20829 1 + %17041 = OpCompositeConstruct %v4float %7047 %13427 %float_0 %float_0 + %16865 = OpVectorShuffle %v2uint %14115 %14115 2 3 + %14182 = OpBitcast %v2float %16865 + %7048 = OpCompositeExtract %float %14182 0 + %13428 = OpCompositeExtract %float %14182 1 + %17042 = OpCompositeConstruct %v4float %7048 %13428 %float_0 %float_0 + %16866 = OpVectorShuffle %v2uint %11216 %11216 0 1 + %14183 = OpBitcast %v2float %16866 + %7049 = OpCompositeExtract %float %14183 0 + %13429 = OpCompositeExtract %float %14183 1 + %17043 = OpCompositeConstruct %v4float %7049 %13429 %float_0 %float_0 + %16867 = OpVectorShuffle %v2uint %11216 %11216 2 3 + %14184 = OpBitcast %v2float %16867 + %7050 = OpCompositeExtract %float %14184 0 + %16651 = OpCompositeExtract %float %14184 1 + %9052 = OpCompositeConstruct %v4float %7050 %16651 %float_0 %float_0 + OpBranch %20266 + %20266 = OpLabel + %11185 = OpPhi %v4float %9052 %20313 %17253 %8539 %9051 %8250 + %14354 = OpPhi %v4float %17043 %20313 %25244 %8539 %14627 %8250 + %15244 = OpPhi %v4float %17042 %20313 %25243 %8539 %14626 %8250 + %14525 = OpPhi %v4float %17041 %20313 %25242 %8539 %14625 %8250 + OpBranch %21266 + %21266 = OpLabel + %11186 = OpPhi %v4float %11185 %20266 %11184 %16227 + %14355 = OpPhi %v4float %14354 %20266 %14353 %16227 + %12951 = OpPhi %v4float %15244 %20266 %15241 %16227 + %13948 = OpPhi %v4float %14525 %20266 %14524 %16227 + %17243 = OpFAdd %v4float %17242 %13948 + %23299 = OpFAdd %v4float %23298 %12951 + %9507 = OpFAdd %v4float %7208 %14355 + %7799 = OpFAdd %v4float %9642 %11186 + OpBranch %24264 + %24264 = OpLabel + %11187 = OpPhi %v4float %20755 %21264 %7799 %21266 + %14356 = OpPhi %v4float %8082 %21264 %9507 %21266 + %15153 = OpPhi %v4float %23297 %21264 %23299 %21266 + %15245 = OpPhi %v4float %17241 %21264 %17243 %21266 + %14526 = OpPhi %float %25083 %21264 %12090 %21266 + OpBranch %21267 + %21267 = OpLabel + %11188 = OpPhi %v4float %11177 %21263 %11187 %24264 + %14357 = OpPhi %v4float %14346 %21263 %14356 %24264 + %15154 = OpPhi %v4float %13804 %21263 %15153 %24264 + %13196 = OpPhi %v4float %8403 %21263 %15245 %24264 + %11944 = OpPhi %float %11052 %21263 %14526 %24264 + %23156 = OpVectorTimesScalar %v4float %13196 %11944 + %6604 = OpVectorTimesScalar %v4float %15154 %11944 + %12399 = OpVectorTimesScalar %v4float %14357 %11944 + %13362 = OpVectorTimesScalar %v4float %11188 %11944 + OpSelectionMerge %16228 DontFlatten + OpBranchConditional %7513 %10049 %16228 + %10049 = OpLabel + %15086 = OpVectorShuffle %v4float %23156 %23156 2 1 0 3 + %14855 = OpVectorShuffle %v4float %6604 %6604 2 1 0 3 + %7398 = OpVectorShuffle %v4float %12399 %12399 2 1 0 3 + %16111 = OpVectorShuffle %v4float %13362 %13362 2 1 0 3 + OpBranch %16228 + %16228 = OpLabel + %11189 = OpPhi %v4float %13362 %21267 %16111 %10049 + %14358 = OpPhi %v4float %12399 %21267 %7398 %10049 + %15191 = OpPhi %v4float %6604 %21267 %14855 %10049 + %14921 = OpPhi %v4float %23156 %21267 %15086 %10049 + OpSelectionMerge %18834 None + OpSwitch %20627 %8194 6 %18070 14 %18070 50 %18070 7 %17899 54 %17899 16 %6453 55 %6453 17 %6452 56 %6452 25 %6451 31 %9492 + %9492 = OpLabel + %15022 = OpCompositeExtract %float %14921 0 + %9197 = OpCompositeExtract %float %14921 1 + %19232 = OpCompositeConstruct %v2float %15022 %9197 + %8561 = OpExtInst %uint %1 PackHalf2x16 %19232 + %23487 = OpCompositeExtract %float %15191 0 + %14759 = OpCompositeExtract %float %15191 1 + %19233 = OpCompositeConstruct %v2float %23487 %14759 + %8562 = OpExtInst %uint %1 PackHalf2x16 %19233 + %23488 = OpCompositeExtract %float %14358 0 + %14760 = OpCompositeExtract %float %14358 1 + %19234 = OpCompositeConstruct %v2float %23488 %14760 + %8563 = OpExtInst %uint %1 PackHalf2x16 %19234 + %23489 = OpCompositeExtract %float %11189 0 + %14761 = OpCompositeExtract %float %11189 1 + %19213 = OpCompositeConstruct %v2float %23489 %14761 + %11926 = OpExtInst %uint %1 PackHalf2x16 %19213 + %24879 = OpCompositeConstruct %v4uint %8561 %8562 %8563 %11926 + OpBranch %18834 + %6451 = OpLabel + %8826 = OpVectorShuffle %v2float %14921 %14921 0 1 + %23729 = OpExtInst %v2float %1 FClamp %8826 %1823 %768 + %9652 = OpVectorTimesScalar %v2float %23729 %float_65535 + %11878 = OpFAdd %v2float %9652 %1566 + %7639 = OpConvertFToU %v2uint %11878 + %8700 = OpCompositeExtract %uint %7639 0 + %12251 = OpCompositeExtract %uint %7639 1 + %11523 = OpShiftLeftLogical %uint %12251 %int_16 + %16707 = OpBitwiseOr %uint %8700 %11523 + %9053 = OpVectorShuffle %v2float %15191 %15191 0 1 + %18111 = OpExtInst %v2float %1 FClamp %9053 %1823 %768 + %9653 = OpVectorTimesScalar %v2float %18111 %float_65535 + %11879 = OpFAdd %v2float %9653 %1566 + %7641 = OpConvertFToU %v2uint %11879 + %8701 = OpCompositeExtract %uint %7641 0 + %12252 = OpCompositeExtract %uint %7641 1 + %11524 = OpShiftLeftLogical %uint %12252 %int_16 + %16708 = OpBitwiseOr %uint %8701 %11524 + %9054 = OpVectorShuffle %v2float %14358 %14358 0 1 + %18112 = OpExtInst %v2float %1 FClamp %9054 %1823 %768 + %9654 = OpVectorTimesScalar %v2float %18112 %float_65535 + %11881 = OpFAdd %v2float %9654 %1566 + %7642 = OpConvertFToU %v2uint %11881 + %8702 = OpCompositeExtract %uint %7642 0 + %12253 = OpCompositeExtract %uint %7642 1 + %11525 = OpShiftLeftLogical %uint %12253 %int_16 + %16709 = OpBitwiseOr %uint %8702 %11525 + %9055 = OpVectorShuffle %v2float %11189 %11189 0 1 + %18113 = OpExtInst %v2float %1 FClamp %9055 %1823 %768 + %9655 = OpVectorTimesScalar %v2float %18113 %float_65535 + %11882 = OpFAdd %v2float %9655 %1566 + %7643 = OpConvertFToU %v2uint %11882 + %8703 = OpCompositeExtract %uint %7643 0 + %12254 = OpCompositeExtract %uint %7643 1 + %11542 = OpShiftLeftLogical %uint %12254 %int_16 + %20994 = OpBitwiseOr %uint %8703 %11542 + %21469 = OpCompositeConstruct %v4uint %16707 %16708 %16709 %20994 + OpBranch %18834 + %6452 = OpLabel + %8655 = OpVectorShuffle %v3float %14921 %14921 0 1 2 + %6215 = OpExtInst %v3float %1 FClamp %8655 %2605 %2584 + %7105 = OpFMul %v3float %6215 %14 + %7962 = OpFAdd %v3float %7105 %939 + %10066 = OpConvertFToU %v3uint %7962 + %8704 = OpCompositeExtract %uint %10066 0 + %12255 = OpCompositeExtract %uint %10066 1 + %11561 = OpShiftLeftLogical %uint %12255 %int_10 + %19814 = OpBitwiseOr %uint %8704 %11561 + %21476 = OpCompositeExtract %uint %10066 2 + %8522 = OpShiftLeftLogical %uint %21476 %int_21 + %16710 = OpBitwiseOr %uint %19814 %8522 + %8866 = OpVectorShuffle %v3float %15191 %15191 0 1 2 + %19668 = OpExtInst %v3float %1 FClamp %8866 %2605 %2584 + %7106 = OpFMul %v3float %19668 %14 + %7963 = OpFAdd %v3float %7106 %939 + %10067 = OpConvertFToU %v3uint %7963 + %8705 = OpCompositeExtract %uint %10067 0 + %12256 = OpCompositeExtract %uint %10067 1 + %11562 = OpShiftLeftLogical %uint %12256 %int_10 + %19815 = OpBitwiseOr %uint %8705 %11562 + %21477 = OpCompositeExtract %uint %10067 2 + %8523 = OpShiftLeftLogical %uint %21477 %int_21 + %16711 = OpBitwiseOr %uint %19815 %8523 + %8867 = OpVectorShuffle %v3float %14358 %14358 0 1 2 + %19669 = OpExtInst %v3float %1 FClamp %8867 %2605 %2584 + %7107 = OpFMul %v3float %19669 %14 + %7964 = OpFAdd %v3float %7107 %939 + %10068 = OpConvertFToU %v3uint %7964 + %8706 = OpCompositeExtract %uint %10068 0 + %12257 = OpCompositeExtract %uint %10068 1 + %11563 = OpShiftLeftLogical %uint %12257 %int_10 + %19816 = OpBitwiseOr %uint %8706 %11563 + %21478 = OpCompositeExtract %uint %10068 2 + %8524 = OpShiftLeftLogical %uint %21478 %int_21 + %16712 = OpBitwiseOr %uint %19816 %8524 + %8868 = OpVectorShuffle %v3float %11189 %11189 0 1 2 + %19675 = OpExtInst %v3float %1 FClamp %8868 %2605 %2584 + %7108 = OpFMul %v3float %19675 %14 + %7965 = OpFAdd %v3float %7108 %939 + %10069 = OpConvertFToU %v3uint %7965 + %8707 = OpCompositeExtract %uint %10069 0 + %12258 = OpCompositeExtract %uint %10069 1 + %11564 = OpShiftLeftLogical %uint %12258 %int_10 + %19817 = OpBitwiseOr %uint %8707 %11564 + %21479 = OpCompositeExtract %uint %10069 2 + %8541 = OpShiftLeftLogical %uint %21479 %int_21 + %20995 = OpBitwiseOr %uint %19817 %8541 + %21470 = OpCompositeConstruct %v4uint %16710 %16711 %16712 %20995 + OpBranch %18834 + %6453 = OpLabel + %8656 = OpVectorShuffle %v3float %14921 %14921 0 1 2 + %6216 = OpExtInst %v3float %1 FClamp %8656 %2605 %2584 + %7109 = OpFMul %v3float %6216 %2275 + %7966 = OpFAdd %v3float %7109 %939 + %10070 = OpConvertFToU %v3uint %7966 + %8708 = OpCompositeExtract %uint %10070 0 + %12259 = OpCompositeExtract %uint %10070 1 + %11565 = OpShiftLeftLogical %uint %12259 %int_11 + %19818 = OpBitwiseOr %uint %8708 %11565 + %21480 = OpCompositeExtract %uint %10070 2 + %8525 = OpShiftLeftLogical %uint %21480 %int_22 + %16713 = OpBitwiseOr %uint %19818 %8525 + %8869 = OpVectorShuffle %v3float %15191 %15191 0 1 2 + %19676 = OpExtInst %v3float %1 FClamp %8869 %2605 %2584 + %7110 = OpFMul %v3float %19676 %2275 + %7967 = OpFAdd %v3float %7110 %939 + %10071 = OpConvertFToU %v3uint %7967 + %8709 = OpCompositeExtract %uint %10071 0 + %12260 = OpCompositeExtract %uint %10071 1 + %11566 = OpShiftLeftLogical %uint %12260 %int_11 + %19819 = OpBitwiseOr %uint %8709 %11566 + %21481 = OpCompositeExtract %uint %10071 2 + %8526 = OpShiftLeftLogical %uint %21481 %int_22 + %16714 = OpBitwiseOr %uint %19819 %8526 + %8870 = OpVectorShuffle %v3float %14358 %14358 0 1 2 + %19677 = OpExtInst %v3float %1 FClamp %8870 %2605 %2584 + %7111 = OpFMul %v3float %19677 %2275 + %7968 = OpFAdd %v3float %7111 %939 + %10072 = OpConvertFToU %v3uint %7968 + %8710 = OpCompositeExtract %uint %10072 0 + %12261 = OpCompositeExtract %uint %10072 1 + %11567 = OpShiftLeftLogical %uint %12261 %int_11 + %19820 = OpBitwiseOr %uint %8710 %11567 + %21482 = OpCompositeExtract %uint %10072 2 + %8527 = OpShiftLeftLogical %uint %21482 %int_22 + %16715 = OpBitwiseOr %uint %19820 %8527 + %8872 = OpVectorShuffle %v3float %11189 %11189 0 1 2 + %19678 = OpExtInst %v3float %1 FClamp %8872 %2605 %2584 + %7112 = OpFMul %v3float %19678 %2275 + %7969 = OpFAdd %v3float %7112 %939 + %10073 = OpConvertFToU %v3uint %7969 + %8711 = OpCompositeExtract %uint %10073 0 + %12262 = OpCompositeExtract %uint %10073 1 + %11568 = OpShiftLeftLogical %uint %12262 %int_11 + %19821 = OpBitwiseOr %uint %8711 %11568 + %21483 = OpCompositeExtract %uint %10073 2 + %8542 = OpShiftLeftLogical %uint %21483 %int_22 + %20996 = OpBitwiseOr %uint %19821 %8542 + %21471 = OpCompositeConstruct %v4uint %16713 %16714 %16715 %20996 + OpBranch %18834 + %17899 = OpLabel + %8873 = OpExtInst %v4float %1 FClamp %14921 %2938 %1285 + %17792 = OpFMul %v4float %8873 %344 + %7970 = OpFAdd %v4float %17792 %325 + %10074 = OpConvertFToU %v4uint %7970 + %8712 = OpCompositeExtract %uint %10074 0 + %12263 = OpCompositeExtract %uint %10074 1 + %11569 = OpShiftLeftLogical %uint %12263 %int_10 + %19822 = OpBitwiseOr %uint %8712 %11569 + %21484 = OpCompositeExtract %uint %10074 2 + %8560 = OpShiftLeftLogical %uint %21484 %int_20 + %19823 = OpBitwiseOr %uint %19822 %8560 + %21485 = OpCompositeExtract %uint %10074 3 + %7292 = OpShiftLeftLogical %uint %21485 %int_30 + %9084 = OpBitwiseOr %uint %19823 %7292 + %9079 = OpExtInst %v4float %1 FClamp %15191 %2938 %1285 + %24798 = OpFMul %v4float %9079 %344 + %7971 = OpFAdd %v4float %24798 %325 + %10075 = OpConvertFToU %v4uint %7971 + %8713 = OpCompositeExtract %uint %10075 0 + %12264 = OpCompositeExtract %uint %10075 1 + %11570 = OpShiftLeftLogical %uint %12264 %int_10 + %19824 = OpBitwiseOr %uint %8713 %11570 + %21486 = OpCompositeExtract %uint %10075 2 + %8564 = OpShiftLeftLogical %uint %21486 %int_20 + %19825 = OpBitwiseOr %uint %19824 %8564 + %21487 = OpCompositeExtract %uint %10075 3 + %7293 = OpShiftLeftLogical %uint %21487 %int_30 + %9085 = OpBitwiseOr %uint %19825 %7293 + %9080 = OpExtInst %v4float %1 FClamp %14358 %2938 %1285 + %24799 = OpFMul %v4float %9080 %344 + %7972 = OpFAdd %v4float %24799 %325 + %10076 = OpConvertFToU %v4uint %7972 + %8714 = OpCompositeExtract %uint %10076 0 + %12265 = OpCompositeExtract %uint %10076 1 + %11571 = OpShiftLeftLogical %uint %12265 %int_10 + %19826 = OpBitwiseOr %uint %8714 %11571 + %21488 = OpCompositeExtract %uint %10076 2 + %8565 = OpShiftLeftLogical %uint %21488 %int_20 + %19827 = OpBitwiseOr %uint %19826 %8565 + %21489 = OpCompositeExtract %uint %10076 3 + %7294 = OpShiftLeftLogical %uint %21489 %int_30 + %9086 = OpBitwiseOr %uint %19827 %7294 + %9081 = OpExtInst %v4float %1 FClamp %11189 %2938 %1285 + %24800 = OpFMul %v4float %9081 %344 + %7973 = OpFAdd %v4float %24800 %325 + %10077 = OpConvertFToU %v4uint %7973 + %8715 = OpCompositeExtract %uint %10077 0 + %12266 = OpCompositeExtract %uint %10077 1 + %11572 = OpShiftLeftLogical %uint %12266 %int_10 + %19828 = OpBitwiseOr %uint %8715 %11572 + %21490 = OpCompositeExtract %uint %10077 2 + %8566 = OpShiftLeftLogical %uint %21490 %int_20 + %19829 = OpBitwiseOr %uint %19828 %8566 + %21491 = OpCompositeExtract %uint %10077 3 + %8543 = OpShiftLeftLogical %uint %21491 %int_30 + %20997 = OpBitwiseOr %uint %19829 %8543 + %21472 = OpCompositeConstruct %v4uint %9084 %9085 %9086 %20997 + OpBranch %18834 + %18070 = OpLabel + %7311 = OpExtInst %v4float %1 FClamp %14921 %2938 %1285 + %20339 = OpVectorTimesScalar %v4float %7311 %float_255 + %11883 = OpFAdd %v4float %20339 %325 + %7644 = OpConvertFToU %v4uint %11883 + %8716 = OpCompositeExtract %uint %7644 0 + %12267 = OpCompositeExtract %uint %7644 1 + %11573 = OpShiftLeftLogical %uint %12267 %int_8 + %19830 = OpBitwiseOr %uint %8716 %11573 + %21492 = OpCompositeExtract %uint %7644 2 + %8567 = OpShiftLeftLogical %uint %21492 %int_16 + %19831 = OpBitwiseOr %uint %19830 %8567 + %21493 = OpCompositeExtract %uint %7644 3 + %7295 = OpShiftLeftLogical %uint %21493 %int_24 + %9255 = OpBitwiseOr %uint %19831 %7295 + %7522 = OpExtInst %v4float %1 FClamp %15191 %2938 %1285 + %8264 = OpVectorTimesScalar %v4float %7522 %float_255 + %11884 = OpFAdd %v4float %8264 %325 + %7645 = OpConvertFToU %v4uint %11884 + %8717 = OpCompositeExtract %uint %7645 0 + %12268 = OpCompositeExtract %uint %7645 1 + %11574 = OpShiftLeftLogical %uint %12268 %int_8 + %19832 = OpBitwiseOr %uint %8717 %11574 + %21494 = OpCompositeExtract %uint %7645 2 + %8568 = OpShiftLeftLogical %uint %21494 %int_16 + %19833 = OpBitwiseOr %uint %19832 %8568 + %21495 = OpCompositeExtract %uint %7645 3 + %7296 = OpShiftLeftLogical %uint %21495 %int_24 + %9256 = OpBitwiseOr %uint %19833 %7296 + %7523 = OpExtInst %v4float %1 FClamp %14358 %2938 %1285 + %8265 = OpVectorTimesScalar %v4float %7523 %float_255 + %11885 = OpFAdd %v4float %8265 %325 + %7646 = OpConvertFToU %v4uint %11885 + %8718 = OpCompositeExtract %uint %7646 0 + %12269 = OpCompositeExtract %uint %7646 1 + %11575 = OpShiftLeftLogical %uint %12269 %int_8 + %19834 = OpBitwiseOr %uint %8718 %11575 + %21496 = OpCompositeExtract %uint %7646 2 + %8569 = OpShiftLeftLogical %uint %21496 %int_16 + %19835 = OpBitwiseOr %uint %19834 %8569 + %21497 = OpCompositeExtract %uint %7646 3 + %7297 = OpShiftLeftLogical %uint %21497 %int_24 + %9257 = OpBitwiseOr %uint %19835 %7297 + %7524 = OpExtInst %v4float %1 FClamp %11189 %2938 %1285 + %8266 = OpVectorTimesScalar %v4float %7524 %float_255 + %11886 = OpFAdd %v4float %8266 %325 + %7647 = OpConvertFToU %v4uint %11886 + %8719 = OpCompositeExtract %uint %7647 0 + %12270 = OpCompositeExtract %uint %7647 1 + %11576 = OpShiftLeftLogical %uint %12270 %int_8 + %19836 = OpBitwiseOr %uint %8719 %11576 + %21498 = OpCompositeExtract %uint %7647 2 + %8570 = OpShiftLeftLogical %uint %21498 %int_16 + %19837 = OpBitwiseOr %uint %19836 %8570 + %21499 = OpCompositeExtract %uint %7647 3 + %8544 = OpShiftLeftLogical %uint %21499 %int_24 + %20998 = OpBitwiseOr %uint %19837 %8544 + %21473 = OpCompositeConstruct %v4uint %9255 %9256 %9257 %20998 + OpBranch %18834 + %8194 = OpLabel + %12446 = OpCompositeExtract %float %14921 0 + %21144 = OpBitcast %uint %12446 + %20301 = OpCompositeExtract %float %15191 0 + %17693 = OpBitcast %uint %20301 + %20302 = OpCompositeExtract %float %14358 0 + %17694 = OpBitcast %uint %20302 + %20280 = OpCompositeExtract %float %11189 0 + %20246 = OpBitcast %uint %20280 + %10040 = OpCompositeConstruct %v4uint %21144 %17693 %17694 %20246 + OpBranch %18834 + %18834 = OpLabel + %22706 = OpPhi %v4uint %10040 %8194 %21473 %18070 %21472 %17899 %21471 %6453 %21470 %6452 %21469 %6451 %24879 %9492 + %19119 = OpIEqual %bool %7640 %uint_0 + %22246 = OpSelect %bool %19119 %false %19119 + OpSelectionMerge %19649 DontFlatten + OpBranchConditional %22246 %9760 %19649 + %9760 = OpLabel + %20482 = OpCompositeExtract %uint %22706 1 + %14335 = OpCompositeInsert %v4uint %20482 %22706 0 + OpBranch %19649 + %19649 = OpLabel + %12383 = OpPhi %v4uint %22706 %18834 %14335 %9760 + %12967 = OpIAdd %v2uint %12025 %23020 + OpSelectionMerge %21237 DontFlatten + OpBranchConditional %20495 %10574 %21373 + %21373 = OpLabel + %10608 = OpBitcast %v2int %12967 + %17090 = OpCompositeExtract %int %10608 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %10608 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %15783 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10955 = OpBitwiseAnd %int %17090 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17303 = OpIAdd %int %10955 %17741 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15435 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18365 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18365 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12151 + %19171 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19171 %int_2 + %16716 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21588 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21588 %int_6 + %15436 = OpIAdd %int %16716 %21580 + %11782 = OpBitwiseAnd %int %16727 %int_63 + %14671 = OpIAdd %int %15436 %11782 + %22127 = OpBitcast %uint %14671 + OpBranch %21237 + %10574 = OpLabel + %19866 = OpCompositeExtract %uint %12967 0 + %11267 = OpCompositeExtract %uint %12967 1 + %8414 = OpCompositeConstruct %v3uint %19866 %11267 %24434 + %20125 = OpBitcast %v3int %8414 + %10438 = OpCompositeExtract %int %20125 1 + %9470 = OpShiftRightArithmetic %int %10438 %int_4 + %10056 = OpCompositeExtract %int %20125 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %25203 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %15783 %uint_5 + %12439 = OpBitcast %int %9032 + %10367 = OpIMul %int %15143 %12439 + %25154 = OpCompositeExtract %int %20125 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10367 + %8797 = OpShiftLeftLogical %int %18940 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12601 = OpBitwiseAnd %int %10438 %int_6 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7051 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7051 %int_6 + %8736 = OpShiftRightArithmetic %int %10438 %int_3 + %13731 = OpIAdd %int %8736 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19172 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19172 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23346 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23346 %23274 + %18366 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18366 %uint_8 + %16729 = OpIAdd %int %10332 %21582 + %19173 = OpBitwiseAnd %int %10438 %int_1 + %21583 = OpShiftLeftLogical %int %19173 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23347 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10956 = OpIAdd %int %23347 %23217 + %23348 = OpShiftLeftLogical %int %10956 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10957 = OpIAdd %int %23348 %23218 + %23349 = OpShiftLeftLogical %int %10957 %int_3 + %21849 = OpBitwiseAnd %int %16730 %int_63 + %24314 = OpIAdd %int %23349 %21849 + %22128 = OpBitcast %uint %24314 + OpBranch %21237 + %21237 = OpLabel + %11376 = OpPhi %uint %22128 %10574 %22127 %21373 + %20616 = OpIAdd %uint %11376 %25270 + %18675 = OpShiftRightLogical %uint %20616 %uint_4 + %12010 = OpIEqual %bool %19164 %uint_1 + %22390 = OpIEqual %bool %19164 %uint_2 + %22150 = OpLogicalOr %bool %12010 %22390 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %12383 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %12383 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16377 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22650 = OpPhi %v4uint %12383 %21237 %16377 %10583 + %19638 = OpIEqual %bool %19164 %uint_3 + %15139 = OpLogicalOr %bool %22390 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22650 %749 + %15335 = OpShiftRightLogical %v4uint %22650 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22650 %13411 %10728 %11064 + %8054 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %18675 + OpStore %8054 %19767 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_full_32bpp_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000062B7, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00040047, 0x000007D0, 0x00000006, 0x00000004, + 0x00030047, 0x0000079C, 0x00000003, 0x00040048, 0x0000079C, 0x00000000, 0x00000018, 0x00050048, + 0x0000079C, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000CC7, 0x00000018, 0x00040047, + 0x00000CC7, 0x00000021, 0x00000000, 0x00040047, 0x00000CC7, 0x00000022, 0x00000000, 0x00030047, + 0x0000040C, 0x00000002, 0x00050048, 0x0000040C, 0x00000000, 0x00000023, 0x00000000, 0x00050048, + 0x0000040C, 0x00000001, 0x00000023, 0x00000004, 0x00050048, 0x0000040C, 0x00000002, 0x00000023, + 0x00000008, 0x00050048, 0x0000040C, 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x0000040C, + 0x00000004, 0x00000023, 0x00000010, 0x00040047, 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, + 0x000007DC, 0x00000006, 0x00000010, 0x00030047, 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, + 0x00000000, 0x00000019, 0x00050048, 0x000007B4, 0x00000000, 0x00000023, 0x00000000, 0x00030047, + 0x00001592, 0x00000019, 0x00040047, 0x00001592, 0x00000021, 0x00000000, 0x00040047, 0x00001592, + 0x00000022, 0x00000001, 0x00040047, 0x00000AC9, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, + 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, + 0x00000012, 0x0000000C, 0x00000002, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, + 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x00040017, + 0x00000017, 0x0000000B, 0x00000004, 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x00000013, + 0x0000000D, 0x00000002, 0x00040017, 0x00000018, 0x0000000D, 0x00000003, 0x00040017, 0x0000001D, + 0x0000000D, 0x00000004, 0x00020014, 0x00000009, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, + 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, 0x0004002B, 0x0000000D, 0x0000008A, 0x3F800000, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, + 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000D, 0x00000540, 0x437F0000, + 0x0004002B, 0x0000000D, 0x000000FC, 0x3F000000, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000A53, 0x00000018, 0x0004002B, 0x0000000D, 0x00000409, 0x447FC000, + 0x0004002B, 0x0000000D, 0x00000BA2, 0x40400000, 0x0007002C, 0x0000001D, 0x00000158, 0x00000409, + 0x00000409, 0x00000409, 0x00000BA2, 0x0004002B, 0x0000000C, 0x00000A29, 0x0000000A, 0x0004002B, + 0x0000000C, 0x00000A47, 0x00000014, 0x0004002B, 0x0000000C, 0x00000A65, 0x0000001E, 0x0004002B, + 0x0000000D, 0x0000057F, 0x44FFE000, 0x0006002C, 0x00000018, 0x000008E3, 0x0000057F, 0x0000057F, + 0x00000409, 0x0004002B, 0x0000000C, 0x00000A2C, 0x0000000B, 0x0004002B, 0x0000000C, 0x00000A4D, + 0x00000016, 0x0006002C, 0x00000018, 0x0000000E, 0x00000409, 0x0000057F, 0x0000057F, 0x0004002B, + 0x0000000C, 0x00000A4A, 0x00000015, 0x0004002B, 0x0000000D, 0x0000022D, 0x477FFF00, 0x0004002B, + 0x0000000B, 0x00000A52, 0x00000018, 0x0007002C, 0x00000017, 0x0000028D, 0x00000A0A, 0x00000A22, + 0x00000A3A, 0x00000A52, 0x0004002B, 0x0000000B, 0x00000144, 0x000000FF, 0x0004002B, 0x0000000D, + 0x0000017A, 0x3B808081, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, + 0x00000A46, 0x00000014, 0x0004002B, 0x0000000B, 0x00000A64, 0x0000001E, 0x0007002C, 0x00000017, + 0x0000034D, 0x00000A0A, 0x00000A28, 0x00000A46, 0x00000A64, 0x0004002B, 0x0000000B, 0x00000A44, + 0x000003FF, 0x0007002C, 0x00000017, 0x0000027B, 0x00000A44, 0x00000A44, 0x00000A44, 0x00000A13, + 0x0004002B, 0x0000000D, 0x000006FE, 0x3A802008, 0x0004002B, 0x0000000D, 0x00000149, 0x3EAAAAAB, + 0x0007002C, 0x0000001D, 0x00000AEE, 0x000006FE, 0x000006FE, 0x000006FE, 0x00000149, 0x0006002C, + 0x00000014, 0x00000BB4, 0x00000A0A, 0x00000A28, 0x00000A46, 0x0004002B, 0x0000000B, 0x00000B87, + 0x0000007F, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x00040017, 0x00000010, 0x00000009, + 0x00000003, 0x0004002B, 0x0000000B, 0x00000B7E, 0x0000007C, 0x0004002B, 0x0000000B, 0x00000A4F, + 0x00000017, 0x0004002B, 0x0000000D, 0x00000341, 0xBF800000, 0x0004002B, 0x0000000C, 0x00000A0B, + 0x00000000, 0x0005002C, 0x00000012, 0x000007A7, 0x00000A3B, 0x00000A0B, 0x0004002B, 0x0000000D, + 0x000007FE, 0x3A800100, 0x00040017, 0x0000001A, 0x0000000C, 0x00000004, 0x0007002C, 0x0000001A, + 0x00000122, 0x00000A3B, 0x00000A0B, 0x00000A3B, 0x00000A0B, 0x0005002C, 0x00000011, 0x0000072D, + 0x00000A10, 0x00000A0D, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0005002C, 0x00000011, + 0x0000070F, 0x00000A0A, 0x00000A0A, 0x0005002C, 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, + 0x0005002C, 0x00000011, 0x00000718, 0x00000A0D, 0x00000A0A, 0x0004002B, 0x0000000B, 0x00000AFA, + 0x00000050, 0x0005002C, 0x00000011, 0x00000A9F, 0x00000AFA, 0x00000A3A, 0x0004002B, 0x0000000C, + 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000C, + 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, + 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, + 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, + 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, + 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, + 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, + 0x00000A16, 0x00000004, 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, 0x0004002B, 0x0000000C, + 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0003001D, 0x000007D0, + 0x0000000B, 0x0003001E, 0x0000079C, 0x000007D0, 0x00040020, 0x00000A1B, 0x00000002, 0x0000079C, + 0x0004003B, 0x00000A1B, 0x00000CC7, 0x00000002, 0x00040020, 0x00000288, 0x00000002, 0x0000000B, + 0x0007001E, 0x0000040C, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, + 0x00000688, 0x00000009, 0x0000040C, 0x0004003B, 0x00000688, 0x00000CE9, 0x00000009, 0x00040020, + 0x00000289, 0x00000009, 0x0000000B, 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, 0x0004002B, + 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, 0x0004002B, + 0x0000000B, 0x00000A5E, 0x0000001C, 0x0005002C, 0x00000011, 0x0000073F, 0x00000A0A, 0x00000A16, + 0x0004002B, 0x0000000B, 0x00000AC7, 0x0000003F, 0x0004002B, 0x0000000C, 0x00000A59, 0x0000001A, + 0x0004002B, 0x0000000C, 0x00000A50, 0x00000017, 0x0004002B, 0x0000000B, 0x00000926, 0x01000000, + 0x0005002C, 0x00000011, 0x000008E4, 0x00000A46, 0x00000A52, 0x0003002A, 0x00000009, 0x00000787, + 0x00040020, 0x00000291, 0x00000001, 0x00000014, 0x0004003B, 0x00000291, 0x00000F48, 0x00000001, + 0x0005002C, 0x00000011, 0x00000721, 0x00000A10, 0x00000A0A, 0x0003001D, 0x000007DC, 0x00000017, + 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, 0x0004003B, + 0x00000A32, 0x00001592, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0006002C, + 0x00000014, 0x00000AC9, 0x00000A22, 0x00000A22, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, + 0x00000A37, 0x00000A0D, 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, 0x0005002C, + 0x00000011, 0x0000084A, 0x00000A37, 0x00000A37, 0x0007002C, 0x0000001D, 0x00000504, 0x00000341, + 0x00000341, 0x00000341, 0x00000341, 0x0007002C, 0x0000001A, 0x00000302, 0x00000A3B, 0x00000A3B, + 0x00000A3B, 0x00000A3B, 0x0007002C, 0x00000017, 0x0000064B, 0x00000144, 0x00000144, 0x00000144, + 0x00000144, 0x0006002C, 0x00000014, 0x00000105, 0x00000A44, 0x00000A44, 0x00000A44, 0x0006002C, + 0x00000014, 0x00000466, 0x00000B87, 0x00000B87, 0x00000B87, 0x0006002C, 0x00000014, 0x00000B0C, + 0x00000A1F, 0x00000A1F, 0x00000A1F, 0x0006002C, 0x00000014, 0x00000A12, 0x00000A0A, 0x00000A0A, + 0x00000A0A, 0x0006002C, 0x00000014, 0x000003FA, 0x00000B7E, 0x00000B7E, 0x00000B7E, 0x0006002C, + 0x00000014, 0x00000189, 0x00000A4F, 0x00000A4F, 0x00000A4F, 0x0006002C, 0x00000014, 0x0000008D, + 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000013, 0x00000049, 0x00000341, 0x00000341, + 0x0005002C, 0x00000012, 0x00000867, 0x00000A3B, 0x00000A3B, 0x0007002C, 0x0000001D, 0x00000B7A, + 0x00000A0C, 0x00000A0C, 0x00000A0C, 0x00000A0C, 0x0007002C, 0x0000001D, 0x00000505, 0x0000008A, + 0x0000008A, 0x0000008A, 0x0000008A, 0x0007002C, 0x0000001D, 0x00000145, 0x000000FC, 0x000000FC, + 0x000000FC, 0x000000FC, 0x0006002C, 0x00000018, 0x00000A2D, 0x00000A0C, 0x00000A0C, 0x00000A0C, + 0x0006002C, 0x00000018, 0x00000A18, 0x0000008A, 0x0000008A, 0x0000008A, 0x0006002C, 0x00000018, + 0x000003AB, 0x000000FC, 0x000000FC, 0x000000FC, 0x0005002C, 0x00000013, 0x0000071F, 0x00000A0C, + 0x00000A0C, 0x0005002C, 0x00000013, 0x00000300, 0x0000008A, 0x0000008A, 0x0005002C, 0x00000013, + 0x0000061E, 0x000000FC, 0x000000FC, 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0007002C, + 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, + 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, + 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0004002B, 0x0000000C, 0x00000089, 0x3F800000, 0x0004002B, + 0x0000000B, 0x00000184, 0x00000500, 0x0004002B, 0x0000000B, 0x0000086E, 0x00280000, 0x0004002B, + 0x0000000B, 0x000009F8, 0xFFFFFFFA, 0x0006002C, 0x00000014, 0x00000938, 0x000009F8, 0x000009F8, + 0x000009F8, 0x0004002B, 0x0000000B, 0x00000AFD, 0x00000051, 0x0004002B, 0x0000000B, 0x00000B00, + 0x00000052, 0x0004002B, 0x0000000B, 0x00000B03, 0x00000053, 0x0004002B, 0x0000000B, 0x00000B06, + 0x00000054, 0x0004002B, 0x0000000B, 0x00000B09, 0x00000055, 0x0004002B, 0x0000000B, 0x00000B0D, + 0x00000056, 0x0004002B, 0x0000000B, 0x00000B0F, 0x00000057, 0x0004002B, 0x0000000D, 0x0000016E, + 0x3E800000, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, + 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, + 0x00050041, 0x00000289, 0x000056E5, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003D0B, + 0x000056E5, 0x00050041, 0x00000289, 0x000058AC, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, + 0x00005158, 0x000058AC, 0x000500C7, 0x0000000B, 0x00005051, 0x00003D0B, 0x00000A44, 0x000500C2, + 0x0000000B, 0x00004E0A, 0x00003D0B, 0x00000A28, 0x000500C7, 0x0000000B, 0x0000217E, 0x00004E0A, + 0x00000A13, 0x000500C2, 0x0000000B, 0x0000520A, 0x00003D0B, 0x00000A31, 0x000500C7, 0x0000000B, + 0x0000217F, 0x0000520A, 0x00000A81, 0x000500C2, 0x0000000B, 0x0000520B, 0x00003D0B, 0x00000A52, + 0x000500C7, 0x0000000B, 0x00002180, 0x0000520B, 0x00000A37, 0x000500C2, 0x0000000B, 0x00004994, + 0x00003D0B, 0x00000A5E, 0x000500C7, 0x0000000B, 0x000023AA, 0x00004994, 0x00000A0D, 0x00050050, + 0x00000011, 0x000022A7, 0x00005158, 0x00005158, 0x000500C2, 0x00000011, 0x00002568, 0x000022A7, + 0x0000073F, 0x000500C7, 0x00000011, 0x00005B53, 0x00002568, 0x000007A2, 0x000500C4, 0x00000011, + 0x00003F4F, 0x00005B53, 0x0000074E, 0x00050084, 0x00000011, 0x000059EB, 0x00003F4F, 0x00000724, + 0x000500C2, 0x0000000B, 0x00003213, 0x00005158, 0x00000A19, 0x000500C7, 0x0000000B, 0x00003F4C, + 0x00003213, 0x00000A81, 0x00050041, 0x00000289, 0x0000492C, 0x00000CE9, 0x00000A11, 0x0004003D, + 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000289, 0x000058AD, 0x00000CE9, 0x00000A14, + 0x0004003D, 0x0000000B, 0x000051B7, 0x000058AD, 0x000500C7, 0x0000000B, 0x00004ADC, 0x00005EAC, + 0x00000A1F, 0x000500C7, 0x0000000B, 0x000055EF, 0x00005EAC, 0x00000A22, 0x000500AB, 0x00000009, + 0x0000500F, 0x000055EF, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00002843, 0x00005EAC, 0x00000A16, + 0x000500C7, 0x0000000B, 0x00005F72, 0x00002843, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00004CD8, + 0x00005EAC, 0x00000A1F, 0x000500C7, 0x0000000B, 0x00005093, 0x00004CD8, 0x00000AC7, 0x0004007C, + 0x0000000C, 0x00005988, 0x00005EAC, 0x000500C4, 0x0000000C, 0x0000358F, 0x00005988, 0x00000A29, + 0x000500C3, 0x0000000C, 0x0000509C, 0x0000358F, 0x00000A59, 0x000500C4, 0x0000000C, 0x00004702, + 0x0000509C, 0x00000A50, 0x00050080, 0x0000000C, 0x00001D26, 0x00004702, 0x00000089, 0x0004007C, + 0x0000000D, 0x00002B2C, 0x00001D26, 0x000500C7, 0x0000000B, 0x00005879, 0x00005EAC, 0x00000926, + 0x000500AB, 0x00000009, 0x00001D59, 0x00005879, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00001F43, + 0x000051B7, 0x00000A44, 0x000500C4, 0x0000000B, 0x00003DA7, 0x00001F43, 0x00000A19, 0x000500C2, + 0x0000000B, 0x0000583F, 0x000051B7, 0x00000A28, 0x000500C7, 0x0000000B, 0x00004BBE, 0x0000583F, + 0x00000A44, 0x000500C4, 0x0000000B, 0x00006273, 0x00004BBE, 0x00000A19, 0x00050050, 0x00000011, + 0x000028B6, 0x000051B7, 0x000051B7, 0x000500C2, 0x00000011, 0x00002891, 0x000028B6, 0x000008E4, + 0x000500C7, 0x00000011, 0x00005B54, 0x00002891, 0x0000084A, 0x000500C4, 0x00000011, 0x00003F50, + 0x00005B54, 0x0000074E, 0x00050084, 0x00000011, 0x000059EC, 0x00003F50, 0x00000724, 0x000500C2, + 0x0000000B, 0x00003214, 0x000051B7, 0x00000A5E, 0x000500C7, 0x0000000B, 0x00003F4D, 0x00003214, + 0x00000A1F, 0x00050041, 0x00000289, 0x000048E0, 0x00000CE9, 0x00000A17, 0x0004003D, 0x0000000B, + 0x000062B6, 0x000048E0, 0x0004003D, 0x00000014, 0x0000374F, 0x00000F48, 0x0007004F, 0x00000011, + 0x00003180, 0x0000374F, 0x0000374F, 0x00000000, 0x00000001, 0x000500C4, 0x00000011, 0x00002EF9, + 0x00003180, 0x00000721, 0x00050051, 0x0000000B, 0x00001DD8, 0x00002EF9, 0x00000000, 0x000500C4, + 0x0000000B, 0x00002D8A, 0x00003F4C, 0x00000A13, 0x000500AE, 0x00000009, 0x00003C13, 0x00001DD8, + 0x00002D8A, 0x000300F7, 0x000031D3, 0x00000002, 0x000400FA, 0x00003C13, 0x000055E8, 0x000031D3, + 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000031D3, 0x00050051, 0x0000000B, + 0x00001CAC, 0x00002EF9, 0x00000001, 0x0007000C, 0x0000000B, 0x00001F38, 0x00000001, 0x00000029, + 0x00001CAC, 0x00000A0A, 0x00050050, 0x00000011, 0x000051EF, 0x00001DD8, 0x00001F38, 0x00050080, + 0x00000011, 0x0000522C, 0x000051EF, 0x000059EB, 0x000500B2, 0x00000009, 0x00003ECB, 0x00003F4D, + 0x00000A13, 0x000300F7, 0x00005CE0, 0x00000000, 0x000400FA, 0x00003ECB, 0x00002AEE, 0x00003AEF, + 0x000200F8, 0x00003AEF, 0x000500AA, 0x00000009, 0x000034FE, 0x00003F4D, 0x00000A19, 0x000600A9, + 0x0000000B, 0x000020F6, 0x000034FE, 0x00000A10, 0x00000A0A, 0x000200F9, 0x00005CE0, 0x000200F8, + 0x00002AEE, 0x000200F9, 0x00005CE0, 0x000200F8, 0x00005CE0, 0x000700F5, 0x0000000B, 0x00004B64, + 0x00003F4D, 0x00002AEE, 0x000020F6, 0x00003AEF, 0x00050050, 0x00000011, 0x000041BE, 0x0000217E, + 0x0000217E, 0x000500AE, 0x0000000F, 0x00002E19, 0x000041BE, 0x0000072D, 0x000600A9, 0x00000011, + 0x00004BB5, 0x00002E19, 0x00000724, 0x0000070F, 0x000500C4, 0x00000011, 0x00002AEA, 0x0000522C, + 0x00004BB5, 0x00050050, 0x00000011, 0x0000605D, 0x00004B64, 0x00004B64, 0x000500C2, 0x00000011, + 0x00002385, 0x0000605D, 0x00000718, 0x000500C7, 0x00000011, 0x00003AEC, 0x00002385, 0x00000724, + 0x00050080, 0x00000011, 0x000027D5, 0x00002AEA, 0x00003AEC, 0x00050050, 0x00000011, 0x00002164, + 0x000023AA, 0x00000A0A, 0x000500C2, 0x00000011, 0x0000264A, 0x00000A9F, 0x00002164, 0x00050086, + 0x00000011, 0x000027A2, 0x000027D5, 0x0000264A, 0x00050051, 0x0000000B, 0x00004FA6, 0x000027A2, + 0x00000001, 0x00050084, 0x0000000B, 0x00002B26, 0x00004FA6, 0x00005051, 0x00050051, 0x0000000B, + 0x00006059, 0x000027A2, 0x00000000, 0x00050080, 0x0000000B, 0x00005420, 0x00002B26, 0x00006059, + 0x00050080, 0x0000000B, 0x00002226, 0x0000217F, 0x00005420, 0x00050084, 0x00000011, 0x00005B31, + 0x000027A2, 0x0000264A, 0x00050082, 0x00000011, 0x00002E74, 0x000027D5, 0x00005B31, 0x00050084, + 0x0000000B, 0x00001F75, 0x00002226, 0x00000184, 0x00050051, 0x0000000B, 0x00005EC7, 0x00002E74, + 0x00000001, 0x00050051, 0x0000000B, 0x00005BE6, 0x0000264A, 0x00000000, 0x00050084, 0x0000000B, + 0x00005966, 0x00005EC7, 0x00005BE6, 0x00050051, 0x0000000B, 0x00001AE6, 0x00002E74, 0x00000000, + 0x00050080, 0x0000000B, 0x000025E0, 0x00005966, 0x00001AE6, 0x000500C4, 0x0000000B, 0x000046C4, + 0x000025E0, 0x000023AA, 0x00050080, 0x0000000B, 0x00004719, 0x00001F75, 0x000046C4, 0x00050089, + 0x0000000B, 0x00005AD8, 0x00004719, 0x0000086E, 0x000500AE, 0x00000009, 0x00003361, 0x0000217E, + 0x00000A10, 0x000600A9, 0x0000000B, 0x0000609F, 0x00003361, 0x00000A0D, 0x00000A0A, 0x00050080, + 0x0000000B, 0x00004E6A, 0x000023AA, 0x0000609F, 0x000500C4, 0x0000000B, 0x0000199B, 0x00000A0D, + 0x00004E6A, 0x000500AB, 0x00000009, 0x00005AEF, 0x000023AA, 0x00000A0A, 0x000300F7, 0x0000530F, + 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B65, 0x000040B9, 0x000200F8, 0x000040B9, 0x000500AA, + 0x00000009, 0x00004ADA, 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F49, 0x00000002, 0x000400FA, + 0x00004ADA, 0x00002621, 0x00002F61, 0x000200F8, 0x00002F61, 0x00060041, 0x00000288, 0x00004BCF, + 0x00000CC7, 0x00000A0B, 0x00005AD8, 0x0004003D, 0x0000000B, 0x00005D43, 0x00004BCF, 0x00050080, + 0x0000000B, 0x00002DA7, 0x00005AD8, 0x0000199B, 0x00060041, 0x00000288, 0x0000194B, 0x00000CC7, + 0x00000A0B, 0x00002DA7, 0x0004003D, 0x0000000B, 0x00005E5B, 0x0000194B, 0x00050084, 0x0000000B, + 0x0000185A, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A1, 0x00005AD8, 0x0000185A, + 0x00060041, 0x00000288, 0x00003BCD, 0x00000CC7, 0x00000A0B, 0x000020A1, 0x0004003D, 0x0000000B, + 0x00005E5C, 0x00003BCD, 0x00050084, 0x0000000B, 0x0000185B, 0x00000A13, 0x0000199B, 0x00050080, + 0x0000000B, 0x000020A2, 0x00005AD8, 0x0000185B, 0x00060041, 0x00000288, 0x000037F1, 0x00000CC7, + 0x00000A0B, 0x000020A2, 0x0004003D, 0x0000000B, 0x00003FFB, 0x000037F1, 0x00070050, 0x00000017, + 0x0000512C, 0x00005D43, 0x00005E5B, 0x00005E5C, 0x00003FFB, 0x000200F9, 0x00004F49, 0x000200F8, + 0x00002621, 0x00060041, 0x00000288, 0x00005545, 0x00000CC7, 0x00000A0B, 0x00005AD8, 0x0004003D, + 0x0000000B, 0x00005D44, 0x00005545, 0x00050080, 0x0000000B, 0x00002DA8, 0x00005AD8, 0x00000A0D, + 0x00060041, 0x00000288, 0x000018FF, 0x00000CC7, 0x00000A0B, 0x00002DA8, 0x0004003D, 0x0000000B, + 0x00005C62, 0x000018FF, 0x00050080, 0x0000000B, 0x00002DA9, 0x00005AD8, 0x00000A10, 0x00060041, + 0x00000288, 0x00001900, 0x00000CC7, 0x00000A0B, 0x00002DA9, 0x0004003D, 0x0000000B, 0x00005C63, + 0x00001900, 0x00050080, 0x0000000B, 0x00002DAA, 0x00005AD8, 0x00000A13, 0x00060041, 0x00000288, + 0x00005FEE, 0x00000CC7, 0x00000A0B, 0x00002DAA, 0x0004003D, 0x0000000B, 0x00003FFC, 0x00005FEE, + 0x00070050, 0x00000017, 0x0000512D, 0x00005D44, 0x00005C62, 0x00005C63, 0x00003FFC, 0x000200F9, + 0x00004F49, 0x000200F8, 0x00004F49, 0x000700F5, 0x00000017, 0x00002ABF, 0x0000512D, 0x00002621, + 0x0000512C, 0x00002F61, 0x000300F7, 0x00003F60, 0x00000000, 0x001300FB, 0x00002180, 0x00004BFB, + 0x00000000, 0x000038F9, 0x00000001, 0x000038F9, 0x00000002, 0x00001CBB, 0x0000000A, 0x00001CBB, + 0x00000003, 0x00001CBA, 0x0000000C, 0x00001CBA, 0x00000004, 0x00001FFE, 0x00000006, 0x00002033, + 0x000200F8, 0x00002033, 0x00050051, 0x0000000B, 0x00005F56, 0x00002ABF, 0x00000000, 0x0006000C, + 0x00000013, 0x00006067, 0x00000001, 0x0000003E, 0x00005F56, 0x00050051, 0x0000000D, 0x00002762, + 0x00006067, 0x00000000, 0x00050051, 0x0000000D, 0x00004446, 0x00006067, 0x00000001, 0x00070050, + 0x0000001D, 0x0000390C, 0x00002762, 0x00004446, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x0000437A, 0x00002ABF, 0x00000001, 0x0006000C, 0x00000013, 0x0000466B, 0x00000001, 0x0000003E, + 0x0000437A, 0x00050051, 0x0000000D, 0x00002763, 0x0000466B, 0x00000000, 0x00050051, 0x0000000D, + 0x00004447, 0x0000466B, 0x00000001, 0x00070050, 0x0000001D, 0x0000390D, 0x00002763, 0x00004447, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x0000437B, 0x00002ABF, 0x00000002, 0x0006000C, + 0x00000013, 0x0000466C, 0x00000001, 0x0000003E, 0x0000437B, 0x00050051, 0x0000000D, 0x00002764, + 0x0000466C, 0x00000000, 0x00050051, 0x0000000D, 0x00004448, 0x0000466C, 0x00000001, 0x00070050, + 0x0000001D, 0x0000390E, 0x00002764, 0x00004448, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x0000437C, 0x00002ABF, 0x00000003, 0x0006000C, 0x00000013, 0x0000466D, 0x00000001, 0x0000003E, + 0x0000437C, 0x00050051, 0x0000000D, 0x00002765, 0x0000466D, 0x00000000, 0x00050051, 0x0000000D, + 0x000050BE, 0x0000466D, 0x00000001, 0x00070050, 0x0000001D, 0x00002349, 0x00002765, 0x000050BE, + 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F60, 0x000200F8, 0x00001FFE, 0x00050051, 0x0000000B, + 0x0000308B, 0x00002ABF, 0x00000000, 0x0004007C, 0x0000000C, 0x0000589D, 0x0000308B, 0x00050050, + 0x00000012, 0x0000471A, 0x0000589D, 0x0000589D, 0x000500C4, 0x00000012, 0x000047AD, 0x0000471A, + 0x000007A7, 0x000500C3, 0x00000012, 0x00003417, 0x000047AD, 0x00000867, 0x0004006F, 0x00000013, + 0x00002A97, 0x00003417, 0x0005008E, 0x00000013, 0x00004747, 0x00002A97, 0x000007FE, 0x0007000C, + 0x00000013, 0x00005E06, 0x00000001, 0x00000028, 0x00000049, 0x00004747, 0x00050051, 0x0000000D, + 0x00005F0A, 0x00005E06, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD4, 0x00005E06, 0x00000001, + 0x00070050, 0x0000001D, 0x0000411E, 0x00005F0A, 0x00003CD4, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x00004C42, 0x00002ABF, 0x00000001, 0x0004007C, 0x0000000C, 0x00003EA1, 0x00004C42, + 0x00050050, 0x00000012, 0x0000471B, 0x00003EA1, 0x00003EA1, 0x000500C4, 0x00000012, 0x000047AE, + 0x0000471B, 0x000007A7, 0x000500C3, 0x00000012, 0x00003418, 0x000047AE, 0x00000867, 0x0004006F, + 0x00000013, 0x00002A98, 0x00003418, 0x0005008E, 0x00000013, 0x00004748, 0x00002A98, 0x000007FE, + 0x0007000C, 0x00000013, 0x00005E07, 0x00000001, 0x00000028, 0x00000049, 0x00004748, 0x00050051, + 0x0000000D, 0x00005F0B, 0x00005E07, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD5, 0x00005E07, + 0x00000001, 0x00070050, 0x0000001D, 0x0000411F, 0x00005F0B, 0x00003CD5, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x00004C43, 0x00002ABF, 0x00000002, 0x0004007C, 0x0000000C, 0x00003EA2, + 0x00004C43, 0x00050050, 0x00000012, 0x0000471C, 0x00003EA2, 0x00003EA2, 0x000500C4, 0x00000012, + 0x000047AF, 0x0000471C, 0x000007A7, 0x000500C3, 0x00000012, 0x00003419, 0x000047AF, 0x00000867, + 0x0004006F, 0x00000013, 0x00002A99, 0x00003419, 0x0005008E, 0x00000013, 0x00004749, 0x00002A99, + 0x000007FE, 0x0007000C, 0x00000013, 0x00005E08, 0x00000001, 0x00000028, 0x00000049, 0x00004749, + 0x00050051, 0x0000000D, 0x00005F0C, 0x00005E08, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD6, + 0x00005E08, 0x00000001, 0x00070050, 0x0000001D, 0x00004120, 0x00005F0C, 0x00003CD6, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C44, 0x00002ABF, 0x00000003, 0x0004007C, 0x0000000C, + 0x00003EA3, 0x00004C44, 0x00050050, 0x00000012, 0x0000471D, 0x00003EA3, 0x00003EA3, 0x000500C4, + 0x00000012, 0x000047B0, 0x0000471D, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341A, 0x000047B0, + 0x00000867, 0x0004006F, 0x00000013, 0x00002A9A, 0x0000341A, 0x0005008E, 0x00000013, 0x0000474A, + 0x00002A9A, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E09, 0x00000001, 0x00000028, 0x00000049, + 0x0000474A, 0x00050051, 0x0000000D, 0x00005F0D, 0x00005E09, 0x00000000, 0x00050051, 0x0000000D, + 0x0000494C, 0x00005E09, 0x00000001, 0x00070050, 0x0000001D, 0x0000234A, 0x00005F0D, 0x0000494C, + 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F60, 0x000200F8, 0x00001CBA, 0x00050051, 0x0000000B, + 0x000056BD, 0x00002ABF, 0x00000000, 0x00060050, 0x00000014, 0x00004F0A, 0x000056BD, 0x000056BD, + 0x000056BD, 0x000500C2, 0x00000014, 0x00002B0D, 0x00004F0A, 0x00000BB4, 0x000500C7, 0x00000014, + 0x00005DE6, 0x00002B0D, 0x00000105, 0x000500C7, 0x00000014, 0x0000489C, 0x00005DE6, 0x00000466, + 0x000500C2, 0x00000014, 0x00005B90, 0x00005DE6, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040C9, + 0x00005B90, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4B, 0x00000001, 0x0000004B, 0x0000489C, + 0x0004007C, 0x00000014, 0x00002A15, 0x00002C4B, 0x00050082, 0x00000014, 0x0000187A, 0x00000B0C, + 0x00002A15, 0x00050080, 0x00000014, 0x00002210, 0x00002A15, 0x00000938, 0x000600A9, 0x00000014, + 0x0000286F, 0x000040C9, 0x00002210, 0x00005B90, 0x000500C4, 0x00000014, 0x00005AD4, 0x0000489C, + 0x0000187A, 0x000500C7, 0x00000014, 0x0000499A, 0x00005AD4, 0x00000466, 0x000600A9, 0x00000014, + 0x00002A9D, 0x000040C9, 0x0000499A, 0x0000489C, 0x00050080, 0x00000014, 0x00005FF9, 0x0000286F, + 0x000003FA, 0x000500C4, 0x00000014, 0x00004F7F, 0x00005FF9, 0x00000189, 0x000500C4, 0x00000014, + 0x00003FA6, 0x00002A9D, 0x0000008D, 0x000500C5, 0x00000014, 0x0000577C, 0x00004F7F, 0x00003FA6, + 0x000500AA, 0x00000010, 0x00003600, 0x00005DE6, 0x00000A12, 0x000600A9, 0x00000014, 0x00004242, + 0x00003600, 0x00000A12, 0x0000577C, 0x0004007C, 0x00000018, 0x000029CF, 0x00004242, 0x000500C2, + 0x0000000B, 0x00004BA4, 0x000056BD, 0x00000A64, 0x00040070, 0x0000000D, 0x0000480E, 0x00004BA4, + 0x00050085, 0x0000000D, 0x00003E1F, 0x0000480E, 0x00000149, 0x00050051, 0x0000000D, 0x000053C2, + 0x000029CF, 0x00000000, 0x00050051, 0x0000000D, 0x00002A55, 0x000029CF, 0x00000001, 0x00050051, + 0x0000000D, 0x00001E99, 0x000029CF, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDA, 0x000053C2, + 0x00002A55, 0x00001E99, 0x00003E1F, 0x00050051, 0x0000000B, 0x000027F5, 0x00002ABF, 0x00000001, + 0x00060050, 0x00000014, 0x0000350E, 0x000027F5, 0x000027F5, 0x000027F5, 0x000500C2, 0x00000014, + 0x00002B0E, 0x0000350E, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DE7, 0x00002B0E, 0x00000105, + 0x000500C7, 0x00000014, 0x0000489D, 0x00005DE7, 0x00000466, 0x000500C2, 0x00000014, 0x00005B91, + 0x00005DE7, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CA, 0x00005B91, 0x00000A12, 0x0006000C, + 0x00000016, 0x00002C4C, 0x00000001, 0x0000004B, 0x0000489D, 0x0004007C, 0x00000014, 0x00002A16, + 0x00002C4C, 0x00050082, 0x00000014, 0x0000187B, 0x00000B0C, 0x00002A16, 0x00050080, 0x00000014, + 0x00002211, 0x00002A16, 0x00000938, 0x000600A9, 0x00000014, 0x00002870, 0x000040CA, 0x00002211, + 0x00005B91, 0x000500C4, 0x00000014, 0x00005AD5, 0x0000489D, 0x0000187B, 0x000500C7, 0x00000014, + 0x0000499B, 0x00005AD5, 0x00000466, 0x000600A9, 0x00000014, 0x00002A9E, 0x000040CA, 0x0000499B, + 0x0000489D, 0x00050080, 0x00000014, 0x00005FFA, 0x00002870, 0x000003FA, 0x000500C4, 0x00000014, + 0x00004F80, 0x00005FFA, 0x00000189, 0x000500C4, 0x00000014, 0x00003FA7, 0x00002A9E, 0x0000008D, + 0x000500C5, 0x00000014, 0x0000577D, 0x00004F80, 0x00003FA7, 0x000500AA, 0x00000010, 0x00003601, + 0x00005DE7, 0x00000A12, 0x000600A9, 0x00000014, 0x00004243, 0x00003601, 0x00000A12, 0x0000577D, + 0x0004007C, 0x00000018, 0x000029D0, 0x00004243, 0x000500C2, 0x0000000B, 0x00004BA5, 0x000027F5, + 0x00000A64, 0x00040070, 0x0000000D, 0x0000480F, 0x00004BA5, 0x00050085, 0x0000000D, 0x00003E20, + 0x0000480F, 0x00000149, 0x00050051, 0x0000000D, 0x000053C3, 0x000029D0, 0x00000000, 0x00050051, + 0x0000000D, 0x00002A56, 0x000029D0, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9A, 0x000029D0, + 0x00000002, 0x00070050, 0x0000001D, 0x00003DDB, 0x000053C3, 0x00002A56, 0x00001E9A, 0x00003E20, + 0x00050051, 0x0000000B, 0x000027F6, 0x00002ABF, 0x00000002, 0x00060050, 0x00000014, 0x0000350F, + 0x000027F6, 0x000027F6, 0x000027F6, 0x000500C2, 0x00000014, 0x00002B0F, 0x0000350F, 0x00000BB4, + 0x000500C7, 0x00000014, 0x00005DE8, 0x00002B0F, 0x00000105, 0x000500C7, 0x00000014, 0x0000489E, + 0x00005DE8, 0x00000466, 0x000500C2, 0x00000014, 0x00005B92, 0x00005DE8, 0x00000B0C, 0x000500AA, + 0x00000010, 0x000040CB, 0x00005B92, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4D, 0x00000001, + 0x0000004B, 0x0000489E, 0x0004007C, 0x00000014, 0x00002A17, 0x00002C4D, 0x00050082, 0x00000014, + 0x0000187C, 0x00000B0C, 0x00002A17, 0x00050080, 0x00000014, 0x00002212, 0x00002A17, 0x00000938, + 0x000600A9, 0x00000014, 0x00002871, 0x000040CB, 0x00002212, 0x00005B92, 0x000500C4, 0x00000014, + 0x00005AD6, 0x0000489E, 0x0000187C, 0x000500C7, 0x00000014, 0x0000499C, 0x00005AD6, 0x00000466, + 0x000600A9, 0x00000014, 0x00002A9F, 0x000040CB, 0x0000499C, 0x0000489E, 0x00050080, 0x00000014, + 0x00005FFB, 0x00002871, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F81, 0x00005FFB, 0x00000189, + 0x000500C4, 0x00000014, 0x00003FA8, 0x00002A9F, 0x0000008D, 0x000500C5, 0x00000014, 0x0000577E, + 0x00004F81, 0x00003FA8, 0x000500AA, 0x00000010, 0x00003602, 0x00005DE8, 0x00000A12, 0x000600A9, + 0x00000014, 0x00004244, 0x00003602, 0x00000A12, 0x0000577E, 0x0004007C, 0x00000018, 0x000029D1, + 0x00004244, 0x000500C2, 0x0000000B, 0x00004BA6, 0x000027F6, 0x00000A64, 0x00040070, 0x0000000D, + 0x00004810, 0x00004BA6, 0x00050085, 0x0000000D, 0x00003E21, 0x00004810, 0x00000149, 0x00050051, + 0x0000000D, 0x000053C4, 0x000029D1, 0x00000000, 0x00050051, 0x0000000D, 0x00002A57, 0x000029D1, + 0x00000001, 0x00050051, 0x0000000D, 0x00001E9B, 0x000029D1, 0x00000002, 0x00070050, 0x0000001D, + 0x00003DDC, 0x000053C4, 0x00002A57, 0x00001E9B, 0x00003E21, 0x00050051, 0x0000000B, 0x000027F7, + 0x00002ABF, 0x00000003, 0x00060050, 0x00000014, 0x00003510, 0x000027F7, 0x000027F7, 0x000027F7, + 0x000500C2, 0x00000014, 0x00002B10, 0x00003510, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DE9, + 0x00002B10, 0x00000105, 0x000500C7, 0x00000014, 0x0000489F, 0x00005DE9, 0x00000466, 0x000500C2, + 0x00000014, 0x00005B93, 0x00005DE9, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CC, 0x00005B93, + 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4E, 0x00000001, 0x0000004B, 0x0000489F, 0x0004007C, + 0x00000014, 0x00002A18, 0x00002C4E, 0x00050082, 0x00000014, 0x0000187D, 0x00000B0C, 0x00002A18, + 0x00050080, 0x00000014, 0x00002213, 0x00002A18, 0x00000938, 0x000600A9, 0x00000014, 0x00002872, + 0x000040CC, 0x00002213, 0x00005B93, 0x000500C4, 0x00000014, 0x00005AD7, 0x0000489F, 0x0000187D, + 0x000500C7, 0x00000014, 0x0000499D, 0x00005AD7, 0x00000466, 0x000600A9, 0x00000014, 0x00002AA0, + 0x000040CC, 0x0000499D, 0x0000489F, 0x00050080, 0x00000014, 0x00005FFC, 0x00002872, 0x000003FA, + 0x000500C4, 0x00000014, 0x00004F82, 0x00005FFC, 0x00000189, 0x000500C4, 0x00000014, 0x00003FA9, + 0x00002AA0, 0x0000008D, 0x000500C5, 0x00000014, 0x0000577F, 0x00004F82, 0x00003FA9, 0x000500AA, + 0x00000010, 0x00003603, 0x00005DE9, 0x00000A12, 0x000600A9, 0x00000014, 0x00004245, 0x00003603, + 0x00000A12, 0x0000577F, 0x0004007C, 0x00000018, 0x000029D2, 0x00004245, 0x000500C2, 0x0000000B, + 0x00004BA7, 0x000027F7, 0x00000A64, 0x00040070, 0x0000000D, 0x00004811, 0x00004BA7, 0x00050085, + 0x0000000D, 0x00003E22, 0x00004811, 0x00000149, 0x00050051, 0x0000000D, 0x000053C5, 0x000029D2, + 0x00000000, 0x00050051, 0x0000000D, 0x00002A58, 0x000029D2, 0x00000001, 0x00050051, 0x0000000D, + 0x00002B11, 0x000029D2, 0x00000002, 0x00070050, 0x0000001D, 0x0000234B, 0x000053C5, 0x00002A58, + 0x00002B11, 0x00003E22, 0x000200F9, 0x00003F60, 0x000200F8, 0x00001CBB, 0x00050051, 0x0000000B, + 0x000056BE, 0x00002ABF, 0x00000000, 0x00070050, 0x00000017, 0x00004F0B, 0x000056BE, 0x000056BE, + 0x000056BE, 0x000056BE, 0x000500C2, 0x00000017, 0x00002498, 0x00004F0B, 0x0000034D, 0x000500C7, + 0x00000017, 0x000049AB, 0x00002498, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CB7, 0x000049AB, + 0x00050085, 0x0000001D, 0x00004130, 0x00003CB7, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD2, + 0x00002ABF, 0x00000001, 0x00070050, 0x00000017, 0x0000514D, 0x00005CD2, 0x00005CD2, 0x00005CD2, + 0x00005CD2, 0x000500C2, 0x00000017, 0x00002499, 0x0000514D, 0x0000034D, 0x000500C7, 0x00000017, + 0x000049AC, 0x00002499, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CB8, 0x000049AC, 0x00050085, + 0x0000001D, 0x00004131, 0x00003CB8, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD3, 0x00002ABF, + 0x00000002, 0x00070050, 0x00000017, 0x0000514E, 0x00005CD3, 0x00005CD3, 0x00005CD3, 0x00005CD3, + 0x000500C2, 0x00000017, 0x0000249A, 0x0000514E, 0x0000034D, 0x000500C7, 0x00000017, 0x000049AD, + 0x0000249A, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CB9, 0x000049AD, 0x00050085, 0x0000001D, + 0x00004132, 0x00003CB9, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD4, 0x00002ABF, 0x00000003, + 0x00070050, 0x00000017, 0x0000514F, 0x00005CD4, 0x00005CD4, 0x00005CD4, 0x00005CD4, 0x000500C2, + 0x00000017, 0x0000249B, 0x0000514F, 0x0000034D, 0x000500C7, 0x00000017, 0x000049AE, 0x0000249B, + 0x0000027B, 0x00040070, 0x0000001D, 0x0000492F, 0x000049AE, 0x00050085, 0x0000001D, 0x0000269F, + 0x0000492F, 0x00000AEE, 0x000200F9, 0x00003F60, 0x000200F8, 0x000038F9, 0x00050051, 0x0000000B, + 0x000056BF, 0x00002ABF, 0x00000000, 0x00070050, 0x00000017, 0x00004F0C, 0x000056BF, 0x000056BF, + 0x000056BF, 0x000056BF, 0x000500C2, 0x00000017, 0x0000249C, 0x00004F0C, 0x0000028D, 0x000500C7, + 0x00000017, 0x00004A56, 0x0000249C, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A2, 0x00004A56, + 0x0005008E, 0x0000001D, 0x00004B23, 0x000036A2, 0x0000017A, 0x00050051, 0x0000000B, 0x0000219F, + 0x00002ABF, 0x00000001, 0x00070050, 0x00000017, 0x0000610B, 0x0000219F, 0x0000219F, 0x0000219F, + 0x0000219F, 0x000500C2, 0x00000017, 0x0000249D, 0x0000610B, 0x0000028D, 0x000500C7, 0x00000017, + 0x00004A57, 0x0000249D, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A3, 0x00004A57, 0x0005008E, + 0x0000001D, 0x00004B24, 0x000036A3, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A0, 0x00002ABF, + 0x00000002, 0x00070050, 0x00000017, 0x0000610C, 0x000021A0, 0x000021A0, 0x000021A0, 0x000021A0, + 0x000500C2, 0x00000017, 0x0000249E, 0x0000610C, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A58, + 0x0000249E, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A4, 0x00004A58, 0x0005008E, 0x0000001D, + 0x00004B25, 0x000036A4, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A1, 0x00002ABF, 0x00000003, + 0x00070050, 0x00000017, 0x0000610D, 0x000021A1, 0x000021A1, 0x000021A1, 0x000021A1, 0x000500C2, + 0x00000017, 0x0000249F, 0x0000610D, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A59, 0x0000249F, + 0x0000064B, 0x00040070, 0x0000001D, 0x0000431A, 0x00004A59, 0x0005008E, 0x0000001D, 0x00003092, + 0x0000431A, 0x0000017A, 0x000200F9, 0x00003F60, 0x000200F8, 0x00004BFB, 0x00050051, 0x0000000B, + 0x0000308C, 0x00002ABF, 0x00000000, 0x0004007C, 0x0000000D, 0x00004FEE, 0x0000308C, 0x00050050, + 0x00000013, 0x00004336, 0x00004FEE, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D90, 0x00004336, + 0x00004336, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B1, + 0x00002ABF, 0x00000001, 0x0004007C, 0x0000000D, 0x00003F68, 0x000056B1, 0x00050050, 0x00000013, + 0x00004337, 0x00003F68, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D91, 0x00004337, 0x00004337, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B2, 0x00002ABF, + 0x00000002, 0x0004007C, 0x0000000D, 0x00003F69, 0x000056B2, 0x00050050, 0x00000013, 0x00004338, + 0x00003F69, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D92, 0x00004338, 0x00004338, 0x00000000, + 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B3, 0x00002ABF, 0x00000003, + 0x0004007C, 0x0000000D, 0x00003F6A, 0x000056B3, 0x00050050, 0x00000013, 0x00004FAE, 0x00003F6A, + 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3A, 0x00004FAE, 0x00004FAE, 0x00000000, 0x00000001, + 0x00000001, 0x00000001, 0x000200F9, 0x00003F60, 0x000200F8, 0x00003F60, 0x000F00F5, 0x0000001D, + 0x00002BA7, 0x00005A3A, 0x00004BFB, 0x00003092, 0x000038F9, 0x0000269F, 0x00001CBB, 0x0000234B, + 0x00001CBA, 0x0000234A, 0x00001FFE, 0x00002349, 0x00002033, 0x000F00F5, 0x0000001D, 0x00003808, + 0x00002D92, 0x00004BFB, 0x00004B25, 0x000038F9, 0x00004132, 0x00001CBB, 0x00003DDC, 0x00001CBA, + 0x00004120, 0x00001FFE, 0x0000390E, 0x00002033, 0x000F00F5, 0x0000001D, 0x00003B7D, 0x00002D91, + 0x00004BFB, 0x00004B24, 0x000038F9, 0x00004131, 0x00001CBB, 0x00003DDB, 0x00001CBA, 0x0000411F, + 0x00001FFE, 0x0000390D, 0x00002033, 0x000F00F5, 0x0000001D, 0x000038B6, 0x00002D90, 0x00004BFB, + 0x00004B23, 0x000038F9, 0x00004130, 0x00001CBB, 0x00003DDA, 0x00001CBA, 0x0000411E, 0x00001FFE, + 0x0000390C, 0x00002033, 0x000200F9, 0x0000530F, 0x000200F8, 0x00003B65, 0x000500AA, 0x00000009, + 0x00005450, 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F23, 0x00000002, 0x000400FA, 0x00005450, + 0x00002622, 0x00002F62, 0x000200F8, 0x00002F62, 0x00060041, 0x00000288, 0x00004BD0, 0x00000CC7, + 0x00000A0B, 0x00005AD8, 0x0004003D, 0x0000000B, 0x00005D45, 0x00004BD0, 0x00050080, 0x0000000B, + 0x00002DAB, 0x00005AD8, 0x00000A0D, 0x00060041, 0x00000288, 0x00001901, 0x00000CC7, 0x00000A0B, + 0x00002DAB, 0x0004003D, 0x0000000B, 0x00005C64, 0x00001901, 0x00050080, 0x0000000B, 0x00002DAC, + 0x00005AD8, 0x0000199B, 0x00060041, 0x00000288, 0x00001902, 0x00000CC7, 0x00000A0B, 0x00002DAC, + 0x0004003D, 0x0000000B, 0x00005C65, 0x00001902, 0x00050080, 0x0000000B, 0x00002DAD, 0x00002DAC, + 0x00000A0D, 0x00060041, 0x00000288, 0x00005FEF, 0x00000CC7, 0x00000A0B, 0x00002DAD, 0x0004003D, + 0x0000000B, 0x0000374C, 0x00005FEF, 0x00070050, 0x00000017, 0x00004CD6, 0x00005D45, 0x00005C64, + 0x00005C65, 0x0000374C, 0x00050084, 0x0000000B, 0x00004298, 0x00000A10, 0x0000199B, 0x00050080, + 0x0000000B, 0x000036A7, 0x00005AD8, 0x00004298, 0x00060041, 0x00000288, 0x00003B81, 0x00000CC7, + 0x00000A0B, 0x000036A7, 0x0004003D, 0x0000000B, 0x00005C66, 0x00003B81, 0x00050080, 0x0000000B, + 0x00002DAE, 0x000036A7, 0x00000A0D, 0x00060041, 0x00000288, 0x0000194C, 0x00000CC7, 0x00000A0B, + 0x00002DAE, 0x0004003D, 0x0000000B, 0x00005E5D, 0x0000194C, 0x00050084, 0x0000000B, 0x0000185C, + 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A3, 0x00005AD8, 0x0000185C, 0x00060041, + 0x00000288, 0x00003B82, 0x00000CC7, 0x00000A0B, 0x000020A3, 0x0004003D, 0x0000000B, 0x00005C67, + 0x00003B82, 0x00050080, 0x0000000B, 0x00002DAF, 0x000020A3, 0x00000A0D, 0x00060041, 0x00000288, + 0x00005FF0, 0x00000CC7, 0x00000A0B, 0x00002DAF, 0x0004003D, 0x0000000B, 0x00003FFD, 0x00005FF0, + 0x00070050, 0x00000017, 0x0000512E, 0x00005C66, 0x00005E5D, 0x00005C67, 0x00003FFD, 0x000200F9, + 0x00004F23, 0x000200F8, 0x00002622, 0x00060041, 0x00000288, 0x00005546, 0x00000CC7, 0x00000A0B, + 0x00005AD8, 0x0004003D, 0x0000000B, 0x00005D46, 0x00005546, 0x00050080, 0x0000000B, 0x00002DB0, + 0x00005AD8, 0x00000A0D, 0x00060041, 0x00000288, 0x00001903, 0x00000CC7, 0x00000A0B, 0x00002DB0, + 0x0004003D, 0x0000000B, 0x00005C68, 0x00001903, 0x00050080, 0x0000000B, 0x00002DB1, 0x00005AD8, + 0x00000A10, 0x00060041, 0x00000288, 0x00001904, 0x00000CC7, 0x00000A0B, 0x00002DB1, 0x0004003D, + 0x0000000B, 0x00005C69, 0x00001904, 0x00050080, 0x0000000B, 0x00002DB2, 0x00005AD8, 0x00000A13, + 0x00060041, 0x00000288, 0x00005FF1, 0x00000CC7, 0x00000A0B, 0x00002DB2, 0x0004003D, 0x0000000B, + 0x00003700, 0x00005FF1, 0x00070050, 0x00000017, 0x00004ADD, 0x00005D46, 0x00005C68, 0x00005C69, + 0x00003700, 0x00050080, 0x0000000B, 0x000057E5, 0x00005AD8, 0x00000A16, 0x00060041, 0x00000288, + 0x0000604B, 0x00000CC7, 0x00000A0B, 0x000057E5, 0x0004003D, 0x0000000B, 0x00005C6A, 0x0000604B, + 0x00050080, 0x0000000B, 0x00002DB3, 0x00005AD8, 0x00000A19, 0x00060041, 0x00000288, 0x00001905, + 0x00000CC7, 0x00000A0B, 0x00002DB3, 0x0004003D, 0x0000000B, 0x00005C6B, 0x00001905, 0x00050080, + 0x0000000B, 0x00002DB4, 0x00005AD8, 0x00000A1C, 0x00060041, 0x00000288, 0x00001906, 0x00000CC7, + 0x00000A0B, 0x00002DB4, 0x0004003D, 0x0000000B, 0x00005C6C, 0x00001906, 0x00050080, 0x0000000B, + 0x00002DB5, 0x00005AD8, 0x00000A1F, 0x00060041, 0x00000288, 0x00005FF2, 0x00000CC7, 0x00000A0B, + 0x00002DB5, 0x0004003D, 0x0000000B, 0x00003FFE, 0x00005FF2, 0x00070050, 0x00000017, 0x0000512F, + 0x00005C6A, 0x00005C6B, 0x00005C6C, 0x00003FFE, 0x000200F9, 0x00004F23, 0x000200F8, 0x00004F23, + 0x000700F5, 0x00000017, 0x00002BCD, 0x0000512F, 0x00002622, 0x0000512E, 0x00002F62, 0x000700F5, + 0x00000017, 0x00003720, 0x00004ADD, 0x00002622, 0x00004CD6, 0x00002F62, 0x000300F7, 0x00004F24, + 0x00000000, 0x000700FB, 0x00002180, 0x00004F56, 0x00000005, 0x00002158, 0x00000007, 0x00002034, + 0x000200F8, 0x00002034, 0x00050051, 0x0000000B, 0x00005F57, 0x00003720, 0x00000000, 0x0006000C, + 0x00000013, 0x00006068, 0x00000001, 0x0000003E, 0x00005F57, 0x00050051, 0x0000000D, 0x00002775, + 0x00006068, 0x00000000, 0x00050051, 0x0000000D, 0x00003EB8, 0x00006068, 0x00000001, 0x00050051, + 0x0000000B, 0x00004281, 0x00003720, 0x00000001, 0x0006000C, 0x00000013, 0x00003CF5, 0x00000001, + 0x0000003E, 0x00004281, 0x00050051, 0x0000000D, 0x00002766, 0x00003CF5, 0x00000000, 0x00050051, + 0x0000000D, 0x00004449, 0x00003CF5, 0x00000001, 0x00070050, 0x0000001D, 0x0000390F, 0x00002775, + 0x00003EB8, 0x00002766, 0x00004449, 0x00050051, 0x0000000B, 0x0000437D, 0x00003720, 0x00000002, + 0x0006000C, 0x00000013, 0x0000466E, 0x00000001, 0x0000003E, 0x0000437D, 0x00050051, 0x0000000D, + 0x00002776, 0x0000466E, 0x00000000, 0x00050051, 0x0000000D, 0x00003EB9, 0x0000466E, 0x00000001, + 0x00050051, 0x0000000B, 0x00004282, 0x00003720, 0x00000003, 0x0006000C, 0x00000013, 0x00003CF6, + 0x00000001, 0x0000003E, 0x00004282, 0x00050051, 0x0000000D, 0x00002767, 0x00003CF6, 0x00000000, + 0x00050051, 0x0000000D, 0x0000444A, 0x00003CF6, 0x00000001, 0x00070050, 0x0000001D, 0x00003910, + 0x00002776, 0x00003EB9, 0x00002767, 0x0000444A, 0x00050051, 0x0000000B, 0x0000437E, 0x00002BCD, + 0x00000000, 0x0006000C, 0x00000013, 0x0000466F, 0x00000001, 0x0000003E, 0x0000437E, 0x00050051, + 0x0000000D, 0x00002777, 0x0000466F, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBA, 0x0000466F, + 0x00000001, 0x00050051, 0x0000000B, 0x00004283, 0x00002BCD, 0x00000001, 0x0006000C, 0x00000013, + 0x00003CF7, 0x00000001, 0x0000003E, 0x00004283, 0x00050051, 0x0000000D, 0x00002768, 0x00003CF7, + 0x00000000, 0x00050051, 0x0000000D, 0x0000444B, 0x00003CF7, 0x00000001, 0x00070050, 0x0000001D, + 0x00003911, 0x00002777, 0x00003EBA, 0x00002768, 0x0000444B, 0x00050051, 0x0000000B, 0x0000437F, + 0x00002BCD, 0x00000002, 0x0006000C, 0x00000013, 0x00004670, 0x00000001, 0x0000003E, 0x0000437F, + 0x00050051, 0x0000000D, 0x00002778, 0x00004670, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBB, + 0x00004670, 0x00000001, 0x00050051, 0x0000000B, 0x00004284, 0x00002BCD, 0x00000003, 0x0006000C, + 0x00000013, 0x00003CF8, 0x00000001, 0x0000003E, 0x00004284, 0x00050051, 0x0000000D, 0x00002769, + 0x00003CF8, 0x00000000, 0x00050051, 0x0000000D, 0x000050BF, 0x00003CF8, 0x00000001, 0x00070050, + 0x0000001D, 0x0000234C, 0x00002778, 0x00003EBB, 0x00002769, 0x000050BF, 0x000200F9, 0x00004F24, + 0x000200F8, 0x00002158, 0x0007004F, 0x00000011, 0x000025FB, 0x00003720, 0x00003720, 0x00000000, + 0x00000001, 0x0004007C, 0x00000012, 0x00005B3C, 0x000025FB, 0x0009004F, 0x0000001A, 0x000060CE, + 0x00005B3C, 0x00005B3C, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, + 0x000048A6, 0x000060CE, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D8D, 0x000048A6, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002A9B, 0x00003D8D, 0x0005008E, 0x0000001D, 0x00004721, 0x00002A9B, + 0x000007FE, 0x0007000C, 0x0000001D, 0x00006291, 0x00000001, 0x00000028, 0x00000504, 0x00004721, + 0x0007004F, 0x00000011, 0x0000376B, 0x00003720, 0x00003720, 0x00000002, 0x00000003, 0x0004007C, + 0x00000012, 0x000024BF, 0x0000376B, 0x0009004F, 0x0000001A, 0x000060CF, 0x000024BF, 0x000024BF, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048A7, 0x000060CF, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D8E, 0x000048A7, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002A9C, 0x00003D8E, 0x0005008E, 0x0000001D, 0x00004722, 0x00002A9C, 0x000007FE, 0x0007000C, + 0x0000001D, 0x00006292, 0x00000001, 0x00000028, 0x00000504, 0x00004722, 0x0007004F, 0x00000011, + 0x0000376C, 0x00002BCD, 0x00002BCD, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000024C0, + 0x0000376C, 0x0009004F, 0x0000001A, 0x000060D0, 0x000024C0, 0x000024C0, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048A8, 0x000060D0, 0x00000122, 0x000500C3, + 0x0000001A, 0x00003D8F, 0x000048A8, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA1, 0x00003D8F, + 0x0005008E, 0x0000001D, 0x00004723, 0x00002AA1, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006293, + 0x00000001, 0x00000028, 0x00000504, 0x00004723, 0x0007004F, 0x00000011, 0x0000376D, 0x00002BCD, + 0x00002BCD, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C1, 0x0000376D, 0x0009004F, + 0x0000001A, 0x000060D1, 0x000024C1, 0x000024C1, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C4, 0x0000001A, 0x000048A9, 0x000060D1, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D90, + 0x000048A9, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA2, 0x00003D90, 0x0005008E, 0x0000001D, + 0x000053BF, 0x00002AA2, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004362, 0x00000001, 0x00000028, + 0x00000504, 0x000053BF, 0x000200F9, 0x00004F24, 0x000200F8, 0x00004F56, 0x0007004F, 0x00000011, + 0x00002623, 0x00003720, 0x00003720, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x00005159, + 0x00002623, 0x00050051, 0x0000000D, 0x00001B7B, 0x00005159, 0x00000000, 0x00050051, 0x0000000D, + 0x0000346A, 0x00005159, 0x00000001, 0x00070050, 0x0000001D, 0x00004278, 0x00001B7B, 0x0000346A, + 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041D8, 0x00003720, 0x00003720, 0x00000002, + 0x00000003, 0x0004007C, 0x00000013, 0x0000375D, 0x000041D8, 0x00050051, 0x0000000D, 0x00001B7C, + 0x0000375D, 0x00000000, 0x00050051, 0x0000000D, 0x0000346B, 0x0000375D, 0x00000001, 0x00070050, + 0x0000001D, 0x00004279, 0x00001B7C, 0x0000346B, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, + 0x000041D9, 0x00002BCD, 0x00002BCD, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x0000375E, + 0x000041D9, 0x00050051, 0x0000000D, 0x00001B7D, 0x0000375E, 0x00000000, 0x00050051, 0x0000000D, + 0x0000346C, 0x0000375E, 0x00000001, 0x00070050, 0x0000001D, 0x0000427A, 0x00001B7D, 0x0000346C, + 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DA, 0x00002BCD, 0x00002BCD, 0x00000002, + 0x00000003, 0x0004007C, 0x00000013, 0x0000375F, 0x000041DA, 0x00050051, 0x0000000D, 0x00001B7E, + 0x0000375F, 0x00000000, 0x00050051, 0x0000000D, 0x00004108, 0x0000375F, 0x00000001, 0x00070050, + 0x0000001D, 0x0000234D, 0x00001B7E, 0x00004108, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F24, + 0x000200F8, 0x00004F24, 0x000900F5, 0x0000001D, 0x00002BA8, 0x0000234D, 0x00004F56, 0x00004362, + 0x00002158, 0x0000234C, 0x00002034, 0x000900F5, 0x0000001D, 0x00003809, 0x0000427A, 0x00004F56, + 0x00006293, 0x00002158, 0x00003911, 0x00002034, 0x000900F5, 0x0000001D, 0x00003B7E, 0x00004279, + 0x00004F56, 0x00006292, 0x00002158, 0x00003910, 0x00002034, 0x000900F5, 0x0000001D, 0x000038B7, + 0x00004278, 0x00004F56, 0x00006291, 0x00002158, 0x0000390F, 0x00002034, 0x000200F9, 0x0000530F, + 0x000200F8, 0x0000530F, 0x000700F5, 0x0000001D, 0x00002BA9, 0x00002BA8, 0x00004F24, 0x00002BA7, + 0x00003F60, 0x000700F5, 0x0000001D, 0x0000380A, 0x00003809, 0x00004F24, 0x00003808, 0x00003F60, + 0x000700F5, 0x0000001D, 0x000035EC, 0x00003B7E, 0x00004F24, 0x00003B7D, 0x00003F60, 0x000700F5, + 0x0000001D, 0x000020D3, 0x000038B7, 0x00004F24, 0x000038B6, 0x00003F60, 0x000500AE, 0x00000009, + 0x00002E55, 0x00003F4D, 0x00000A16, 0x000300F7, 0x00005313, 0x00000002, 0x000400FA, 0x00002E55, + 0x000050E5, 0x00005313, 0x000200F8, 0x000050E5, 0x00050085, 0x0000000D, 0x000061FB, 0x00002B2C, + 0x000000FC, 0x00050080, 0x0000000B, 0x00005E78, 0x00005AD8, 0x00000AFA, 0x000300F7, 0x00005310, + 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B66, 0x000040BA, 0x000200F8, 0x000040BA, 0x000500AA, + 0x00000009, 0x00004ADB, 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F4A, 0x00000002, 0x000400FA, + 0x00004ADB, 0x00002624, 0x00002F63, 0x000200F8, 0x00002F63, 0x00060041, 0x00000288, 0x00004BD1, + 0x00000CC7, 0x00000A0B, 0x00005E78, 0x0004003D, 0x0000000B, 0x00005D47, 0x00004BD1, 0x00050080, + 0x0000000B, 0x00002DB6, 0x00005E78, 0x0000199B, 0x00060041, 0x00000288, 0x0000194D, 0x00000CC7, + 0x00000A0B, 0x00002DB6, 0x0004003D, 0x0000000B, 0x00005E5E, 0x0000194D, 0x00050084, 0x0000000B, + 0x0000185D, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A4, 0x00005E78, 0x0000185D, + 0x00060041, 0x00000288, 0x00003BCE, 0x00000CC7, 0x00000A0B, 0x000020A4, 0x0004003D, 0x0000000B, + 0x00005E5F, 0x00003BCE, 0x00050084, 0x0000000B, 0x0000185E, 0x00000A13, 0x0000199B, 0x00050080, + 0x0000000B, 0x000020A5, 0x00005E78, 0x0000185E, 0x00060041, 0x00000288, 0x000037F2, 0x00000CC7, + 0x00000A0B, 0x000020A5, 0x0004003D, 0x0000000B, 0x00003FFF, 0x000037F2, 0x00070050, 0x00000017, + 0x00005130, 0x00005D47, 0x00005E5E, 0x00005E5F, 0x00003FFF, 0x000200F9, 0x00004F4A, 0x000200F8, + 0x00002624, 0x00060041, 0x00000288, 0x00005547, 0x00000CC7, 0x00000A0B, 0x00005E78, 0x0004003D, + 0x0000000B, 0x00005D48, 0x00005547, 0x00050080, 0x0000000B, 0x00002DB7, 0x00005AD8, 0x00000AFD, + 0x00060041, 0x00000288, 0x00001907, 0x00000CC7, 0x00000A0B, 0x00002DB7, 0x0004003D, 0x0000000B, + 0x00005C6D, 0x00001907, 0x00050080, 0x0000000B, 0x00002DB8, 0x00005AD8, 0x00000B00, 0x00060041, + 0x00000288, 0x00001908, 0x00000CC7, 0x00000A0B, 0x00002DB8, 0x0004003D, 0x0000000B, 0x00005C6E, + 0x00001908, 0x00050080, 0x0000000B, 0x00002DB9, 0x00005AD8, 0x00000B03, 0x00060041, 0x00000288, + 0x00005FF3, 0x00000CC7, 0x00000A0B, 0x00002DB9, 0x0004003D, 0x0000000B, 0x00004000, 0x00005FF3, + 0x00070050, 0x00000017, 0x00005131, 0x00005D48, 0x00005C6D, 0x00005C6E, 0x00004000, 0x000200F9, + 0x00004F4A, 0x000200F8, 0x00004F4A, 0x000700F5, 0x00000017, 0x00002AC0, 0x00005131, 0x00002624, + 0x00005130, 0x00002F63, 0x000300F7, 0x00003F61, 0x00000000, 0x001300FB, 0x00002180, 0x00004BFC, + 0x00000000, 0x000038FA, 0x00000001, 0x000038FA, 0x00000002, 0x00001CBD, 0x0000000A, 0x00001CBD, + 0x00000003, 0x00001CBC, 0x0000000C, 0x00001CBC, 0x00000004, 0x00001FFF, 0x00000006, 0x00002035, + 0x000200F8, 0x00002035, 0x00050051, 0x0000000B, 0x00005F58, 0x00002AC0, 0x00000000, 0x0006000C, + 0x00000013, 0x00006069, 0x00000001, 0x0000003E, 0x00005F58, 0x00050051, 0x0000000D, 0x0000276A, + 0x00006069, 0x00000000, 0x00050051, 0x0000000D, 0x0000444C, 0x00006069, 0x00000001, 0x00070050, + 0x0000001D, 0x00003912, 0x0000276A, 0x0000444C, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x00004380, 0x00002AC0, 0x00000001, 0x0006000C, 0x00000013, 0x00004671, 0x00000001, 0x0000003E, + 0x00004380, 0x00050051, 0x0000000D, 0x0000276B, 0x00004671, 0x00000000, 0x00050051, 0x0000000D, + 0x0000444D, 0x00004671, 0x00000001, 0x00070050, 0x0000001D, 0x00003913, 0x0000276B, 0x0000444D, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004381, 0x00002AC0, 0x00000002, 0x0006000C, + 0x00000013, 0x00004672, 0x00000001, 0x0000003E, 0x00004381, 0x00050051, 0x0000000D, 0x0000276C, + 0x00004672, 0x00000000, 0x00050051, 0x0000000D, 0x0000444E, 0x00004672, 0x00000001, 0x00070050, + 0x0000001D, 0x00003914, 0x0000276C, 0x0000444E, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x00004382, 0x00002AC0, 0x00000003, 0x0006000C, 0x00000013, 0x00004673, 0x00000001, 0x0000003E, + 0x00004382, 0x00050051, 0x0000000D, 0x0000276D, 0x00004673, 0x00000000, 0x00050051, 0x0000000D, + 0x000050C0, 0x00004673, 0x00000001, 0x00070050, 0x0000001D, 0x0000234E, 0x0000276D, 0x000050C0, + 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F61, 0x000200F8, 0x00001FFF, 0x00050051, 0x0000000B, + 0x0000308D, 0x00002AC0, 0x00000000, 0x0004007C, 0x0000000C, 0x0000589E, 0x0000308D, 0x00050050, + 0x00000012, 0x0000471E, 0x0000589E, 0x0000589E, 0x000500C4, 0x00000012, 0x000047B1, 0x0000471E, + 0x000007A7, 0x000500C3, 0x00000012, 0x0000341B, 0x000047B1, 0x00000867, 0x0004006F, 0x00000013, + 0x00002AA3, 0x0000341B, 0x0005008E, 0x00000013, 0x0000474B, 0x00002AA3, 0x000007FE, 0x0007000C, + 0x00000013, 0x00005E0A, 0x00000001, 0x00000028, 0x00000049, 0x0000474B, 0x00050051, 0x0000000D, + 0x00005F0E, 0x00005E0A, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD7, 0x00005E0A, 0x00000001, + 0x00070050, 0x0000001D, 0x00004121, 0x00005F0E, 0x00003CD7, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x00004C45, 0x00002AC0, 0x00000001, 0x0004007C, 0x0000000C, 0x00003EA4, 0x00004C45, + 0x00050050, 0x00000012, 0x0000471F, 0x00003EA4, 0x00003EA4, 0x000500C4, 0x00000012, 0x000047B2, + 0x0000471F, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341C, 0x000047B2, 0x00000867, 0x0004006F, + 0x00000013, 0x00002AA4, 0x0000341C, 0x0005008E, 0x00000013, 0x0000474C, 0x00002AA4, 0x000007FE, + 0x0007000C, 0x00000013, 0x00005E0B, 0x00000001, 0x00000028, 0x00000049, 0x0000474C, 0x00050051, + 0x0000000D, 0x00005F0F, 0x00005E0B, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD8, 0x00005E0B, + 0x00000001, 0x00070050, 0x0000001D, 0x00004122, 0x00005F0F, 0x00003CD8, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x00004C46, 0x00002AC0, 0x00000002, 0x0004007C, 0x0000000C, 0x00003EA5, + 0x00004C46, 0x00050050, 0x00000012, 0x00004720, 0x00003EA5, 0x00003EA5, 0x000500C4, 0x00000012, + 0x000047B3, 0x00004720, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341D, 0x000047B3, 0x00000867, + 0x0004006F, 0x00000013, 0x00002AA5, 0x0000341D, 0x0005008E, 0x00000013, 0x0000474D, 0x00002AA5, + 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0C, 0x00000001, 0x00000028, 0x00000049, 0x0000474D, + 0x00050051, 0x0000000D, 0x00005F10, 0x00005E0C, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD9, + 0x00005E0C, 0x00000001, 0x00070050, 0x0000001D, 0x00004123, 0x00005F10, 0x00003CD9, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C47, 0x00002AC0, 0x00000003, 0x0004007C, 0x0000000C, + 0x00003EA6, 0x00004C47, 0x00050050, 0x00000012, 0x00004724, 0x00003EA6, 0x00003EA6, 0x000500C4, + 0x00000012, 0x000047B4, 0x00004724, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341E, 0x000047B4, + 0x00000867, 0x0004006F, 0x00000013, 0x00002AA6, 0x0000341E, 0x0005008E, 0x00000013, 0x0000474E, + 0x00002AA6, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0D, 0x00000001, 0x00000028, 0x00000049, + 0x0000474E, 0x00050051, 0x0000000D, 0x00005F11, 0x00005E0D, 0x00000000, 0x00050051, 0x0000000D, + 0x0000494D, 0x00005E0D, 0x00000001, 0x00070050, 0x0000001D, 0x0000234F, 0x00005F11, 0x0000494D, + 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F61, 0x000200F8, 0x00001CBC, 0x00050051, 0x0000000B, + 0x000056C0, 0x00002AC0, 0x00000000, 0x00060050, 0x00000014, 0x00004F0D, 0x000056C0, 0x000056C0, + 0x000056C0, 0x000500C2, 0x00000014, 0x00002B12, 0x00004F0D, 0x00000BB4, 0x000500C7, 0x00000014, + 0x00005DEA, 0x00002B12, 0x00000105, 0x000500C7, 0x00000014, 0x000048A0, 0x00005DEA, 0x00000466, + 0x000500C2, 0x00000014, 0x00005B94, 0x00005DEA, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CD, + 0x00005B94, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4F, 0x00000001, 0x0000004B, 0x000048A0, + 0x0004007C, 0x00000014, 0x00002A19, 0x00002C4F, 0x00050082, 0x00000014, 0x0000187E, 0x00000B0C, + 0x00002A19, 0x00050080, 0x00000014, 0x00002214, 0x00002A19, 0x00000938, 0x000600A9, 0x00000014, + 0x00002873, 0x000040CD, 0x00002214, 0x00005B94, 0x000500C4, 0x00000014, 0x00005AD9, 0x000048A0, + 0x0000187E, 0x000500C7, 0x00000014, 0x0000499E, 0x00005AD9, 0x00000466, 0x000600A9, 0x00000014, + 0x00002AA7, 0x000040CD, 0x0000499E, 0x000048A0, 0x00050080, 0x00000014, 0x00005FFD, 0x00002873, + 0x000003FA, 0x000500C4, 0x00000014, 0x00004F83, 0x00005FFD, 0x00000189, 0x000500C4, 0x00000014, + 0x00003FAA, 0x00002AA7, 0x0000008D, 0x000500C5, 0x00000014, 0x00005780, 0x00004F83, 0x00003FAA, + 0x000500AA, 0x00000010, 0x00003604, 0x00005DEA, 0x00000A12, 0x000600A9, 0x00000014, 0x00004246, + 0x00003604, 0x00000A12, 0x00005780, 0x0004007C, 0x00000018, 0x000029D3, 0x00004246, 0x000500C2, + 0x0000000B, 0x00004BA8, 0x000056C0, 0x00000A64, 0x00040070, 0x0000000D, 0x00004812, 0x00004BA8, + 0x00050085, 0x0000000D, 0x00003E23, 0x00004812, 0x00000149, 0x00050051, 0x0000000D, 0x000053C6, + 0x000029D3, 0x00000000, 0x00050051, 0x0000000D, 0x00002A59, 0x000029D3, 0x00000001, 0x00050051, + 0x0000000D, 0x00001E9C, 0x000029D3, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDD, 0x000053C6, + 0x00002A59, 0x00001E9C, 0x00003E23, 0x00050051, 0x0000000B, 0x000027F8, 0x00002AC0, 0x00000001, + 0x00060050, 0x00000014, 0x00003511, 0x000027F8, 0x000027F8, 0x000027F8, 0x000500C2, 0x00000014, + 0x00002B13, 0x00003511, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEB, 0x00002B13, 0x00000105, + 0x000500C7, 0x00000014, 0x000048A1, 0x00005DEB, 0x00000466, 0x000500C2, 0x00000014, 0x00005B95, + 0x00005DEB, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CE, 0x00005B95, 0x00000A12, 0x0006000C, + 0x00000016, 0x00002C50, 0x00000001, 0x0000004B, 0x000048A1, 0x0004007C, 0x00000014, 0x00002A1A, + 0x00002C50, 0x00050082, 0x00000014, 0x0000187F, 0x00000B0C, 0x00002A1A, 0x00050080, 0x00000014, + 0x00002215, 0x00002A1A, 0x00000938, 0x000600A9, 0x00000014, 0x00002874, 0x000040CE, 0x00002215, + 0x00005B95, 0x000500C4, 0x00000014, 0x00005ADA, 0x000048A1, 0x0000187F, 0x000500C7, 0x00000014, + 0x0000499F, 0x00005ADA, 0x00000466, 0x000600A9, 0x00000014, 0x00002AA8, 0x000040CE, 0x0000499F, + 0x000048A1, 0x00050080, 0x00000014, 0x00005FFE, 0x00002874, 0x000003FA, 0x000500C4, 0x00000014, + 0x00004F84, 0x00005FFE, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAB, 0x00002AA8, 0x0000008D, + 0x000500C5, 0x00000014, 0x00005781, 0x00004F84, 0x00003FAB, 0x000500AA, 0x00000010, 0x00003605, + 0x00005DEB, 0x00000A12, 0x000600A9, 0x00000014, 0x00004247, 0x00003605, 0x00000A12, 0x00005781, + 0x0004007C, 0x00000018, 0x000029D4, 0x00004247, 0x000500C2, 0x0000000B, 0x00004BA9, 0x000027F8, + 0x00000A64, 0x00040070, 0x0000000D, 0x00004813, 0x00004BA9, 0x00050085, 0x0000000D, 0x00003E24, + 0x00004813, 0x00000149, 0x00050051, 0x0000000D, 0x000053C7, 0x000029D4, 0x00000000, 0x00050051, + 0x0000000D, 0x00002A5A, 0x000029D4, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9D, 0x000029D4, + 0x00000002, 0x00070050, 0x0000001D, 0x00003DDE, 0x000053C7, 0x00002A5A, 0x00001E9D, 0x00003E24, + 0x00050051, 0x0000000B, 0x000027F9, 0x00002AC0, 0x00000002, 0x00060050, 0x00000014, 0x00003512, + 0x000027F9, 0x000027F9, 0x000027F9, 0x000500C2, 0x00000014, 0x00002B14, 0x00003512, 0x00000BB4, + 0x000500C7, 0x00000014, 0x00005DEC, 0x00002B14, 0x00000105, 0x000500C7, 0x00000014, 0x000048A2, + 0x00005DEC, 0x00000466, 0x000500C2, 0x00000014, 0x00005B96, 0x00005DEC, 0x00000B0C, 0x000500AA, + 0x00000010, 0x000040CF, 0x00005B96, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C51, 0x00000001, + 0x0000004B, 0x000048A2, 0x0004007C, 0x00000014, 0x00002A1B, 0x00002C51, 0x00050082, 0x00000014, + 0x00001880, 0x00000B0C, 0x00002A1B, 0x00050080, 0x00000014, 0x00002216, 0x00002A1B, 0x00000938, + 0x000600A9, 0x00000014, 0x00002875, 0x000040CF, 0x00002216, 0x00005B96, 0x000500C4, 0x00000014, + 0x00005ADB, 0x000048A2, 0x00001880, 0x000500C7, 0x00000014, 0x000049A0, 0x00005ADB, 0x00000466, + 0x000600A9, 0x00000014, 0x00002AA9, 0x000040CF, 0x000049A0, 0x000048A2, 0x00050080, 0x00000014, + 0x00005FFF, 0x00002875, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F85, 0x00005FFF, 0x00000189, + 0x000500C4, 0x00000014, 0x00003FAC, 0x00002AA9, 0x0000008D, 0x000500C5, 0x00000014, 0x00005782, + 0x00004F85, 0x00003FAC, 0x000500AA, 0x00000010, 0x00003606, 0x00005DEC, 0x00000A12, 0x000600A9, + 0x00000014, 0x00004248, 0x00003606, 0x00000A12, 0x00005782, 0x0004007C, 0x00000018, 0x000029D5, + 0x00004248, 0x000500C2, 0x0000000B, 0x00004BAA, 0x000027F9, 0x00000A64, 0x00040070, 0x0000000D, + 0x00004814, 0x00004BAA, 0x00050085, 0x0000000D, 0x00003E25, 0x00004814, 0x00000149, 0x00050051, + 0x0000000D, 0x000053C8, 0x000029D5, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5B, 0x000029D5, + 0x00000001, 0x00050051, 0x0000000D, 0x00001E9E, 0x000029D5, 0x00000002, 0x00070050, 0x0000001D, + 0x00003DDF, 0x000053C8, 0x00002A5B, 0x00001E9E, 0x00003E25, 0x00050051, 0x0000000B, 0x000027FA, + 0x00002AC0, 0x00000003, 0x00060050, 0x00000014, 0x00003513, 0x000027FA, 0x000027FA, 0x000027FA, + 0x000500C2, 0x00000014, 0x00002B15, 0x00003513, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DED, + 0x00002B15, 0x00000105, 0x000500C7, 0x00000014, 0x000048A3, 0x00005DED, 0x00000466, 0x000500C2, + 0x00000014, 0x00005B97, 0x00005DED, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D0, 0x00005B97, + 0x00000A12, 0x0006000C, 0x00000016, 0x00002C52, 0x00000001, 0x0000004B, 0x000048A3, 0x0004007C, + 0x00000014, 0x00002A1C, 0x00002C52, 0x00050082, 0x00000014, 0x00001881, 0x00000B0C, 0x00002A1C, + 0x00050080, 0x00000014, 0x00002217, 0x00002A1C, 0x00000938, 0x000600A9, 0x00000014, 0x00002876, + 0x000040D0, 0x00002217, 0x00005B97, 0x000500C4, 0x00000014, 0x00005ADC, 0x000048A3, 0x00001881, + 0x000500C7, 0x00000014, 0x000049A1, 0x00005ADC, 0x00000466, 0x000600A9, 0x00000014, 0x00002AAA, + 0x000040D0, 0x000049A1, 0x000048A3, 0x00050080, 0x00000014, 0x00006000, 0x00002876, 0x000003FA, + 0x000500C4, 0x00000014, 0x00004F86, 0x00006000, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAD, + 0x00002AAA, 0x0000008D, 0x000500C5, 0x00000014, 0x00005783, 0x00004F86, 0x00003FAD, 0x000500AA, + 0x00000010, 0x00003607, 0x00005DED, 0x00000A12, 0x000600A9, 0x00000014, 0x00004249, 0x00003607, + 0x00000A12, 0x00005783, 0x0004007C, 0x00000018, 0x000029D6, 0x00004249, 0x000500C2, 0x0000000B, + 0x00004BAB, 0x000027FA, 0x00000A64, 0x00040070, 0x0000000D, 0x00004815, 0x00004BAB, 0x00050085, + 0x0000000D, 0x00003E26, 0x00004815, 0x00000149, 0x00050051, 0x0000000D, 0x000053C9, 0x000029D6, + 0x00000000, 0x00050051, 0x0000000D, 0x00002A5C, 0x000029D6, 0x00000001, 0x00050051, 0x0000000D, + 0x00002B16, 0x000029D6, 0x00000002, 0x00070050, 0x0000001D, 0x00002350, 0x000053C9, 0x00002A5C, + 0x00002B16, 0x00003E26, 0x000200F9, 0x00003F61, 0x000200F8, 0x00001CBD, 0x00050051, 0x0000000B, + 0x000056C1, 0x00002AC0, 0x00000000, 0x00070050, 0x00000017, 0x00004F0E, 0x000056C1, 0x000056C1, + 0x000056C1, 0x000056C1, 0x000500C2, 0x00000017, 0x000024A0, 0x00004F0E, 0x0000034D, 0x000500C7, + 0x00000017, 0x000049AF, 0x000024A0, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBA, 0x000049AF, + 0x00050085, 0x0000001D, 0x00004133, 0x00003CBA, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD5, + 0x00002AC0, 0x00000001, 0x00070050, 0x00000017, 0x00005150, 0x00005CD5, 0x00005CD5, 0x00005CD5, + 0x00005CD5, 0x000500C2, 0x00000017, 0x000024A1, 0x00005150, 0x0000034D, 0x000500C7, 0x00000017, + 0x000049B0, 0x000024A1, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBB, 0x000049B0, 0x00050085, + 0x0000001D, 0x00004134, 0x00003CBB, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD6, 0x00002AC0, + 0x00000002, 0x00070050, 0x00000017, 0x00005151, 0x00005CD6, 0x00005CD6, 0x00005CD6, 0x00005CD6, + 0x000500C2, 0x00000017, 0x000024A2, 0x00005151, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B1, + 0x000024A2, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBC, 0x000049B1, 0x00050085, 0x0000001D, + 0x00004135, 0x00003CBC, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD7, 0x00002AC0, 0x00000003, + 0x00070050, 0x00000017, 0x00005152, 0x00005CD7, 0x00005CD7, 0x00005CD7, 0x00005CD7, 0x000500C2, + 0x00000017, 0x000024A3, 0x00005152, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B2, 0x000024A3, + 0x0000027B, 0x00040070, 0x0000001D, 0x00004930, 0x000049B2, 0x00050085, 0x0000001D, 0x000026A0, + 0x00004930, 0x00000AEE, 0x000200F9, 0x00003F61, 0x000200F8, 0x000038FA, 0x00050051, 0x0000000B, + 0x000056C2, 0x00002AC0, 0x00000000, 0x00070050, 0x00000017, 0x00004F0F, 0x000056C2, 0x000056C2, + 0x000056C2, 0x000056C2, 0x000500C2, 0x00000017, 0x000024A4, 0x00004F0F, 0x0000028D, 0x000500C7, + 0x00000017, 0x00004A5A, 0x000024A4, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A5, 0x00004A5A, + 0x0005008E, 0x0000001D, 0x00004B26, 0x000036A5, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A2, + 0x00002AC0, 0x00000001, 0x00070050, 0x00000017, 0x0000610E, 0x000021A2, 0x000021A2, 0x000021A2, + 0x000021A2, 0x000500C2, 0x00000017, 0x000024A5, 0x0000610E, 0x0000028D, 0x000500C7, 0x00000017, + 0x00004A5B, 0x000024A5, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A6, 0x00004A5B, 0x0005008E, + 0x0000001D, 0x00004B27, 0x000036A6, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A3, 0x00002AC0, + 0x00000002, 0x00070050, 0x00000017, 0x0000610F, 0x000021A3, 0x000021A3, 0x000021A3, 0x000021A3, + 0x000500C2, 0x00000017, 0x000024A6, 0x0000610F, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5C, + 0x000024A6, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A8, 0x00004A5C, 0x0005008E, 0x0000001D, + 0x00004B28, 0x000036A8, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A4, 0x00002AC0, 0x00000003, + 0x00070050, 0x00000017, 0x00006110, 0x000021A4, 0x000021A4, 0x000021A4, 0x000021A4, 0x000500C2, + 0x00000017, 0x000024A7, 0x00006110, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5D, 0x000024A7, + 0x0000064B, 0x00040070, 0x0000001D, 0x0000431B, 0x00004A5D, 0x0005008E, 0x0000001D, 0x00003093, + 0x0000431B, 0x0000017A, 0x000200F9, 0x00003F61, 0x000200F8, 0x00004BFC, 0x00050051, 0x0000000B, + 0x0000308E, 0x00002AC0, 0x00000000, 0x0004007C, 0x0000000D, 0x00004FEF, 0x0000308E, 0x00050050, + 0x00000013, 0x00004339, 0x00004FEF, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D93, 0x00004339, + 0x00004339, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B4, + 0x00002AC0, 0x00000001, 0x0004007C, 0x0000000D, 0x00003F6B, 0x000056B4, 0x00050050, 0x00000013, + 0x0000433A, 0x00003F6B, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D94, 0x0000433A, 0x0000433A, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B5, 0x00002AC0, + 0x00000002, 0x0004007C, 0x0000000D, 0x00003F6C, 0x000056B5, 0x00050050, 0x00000013, 0x0000433B, + 0x00003F6C, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D95, 0x0000433B, 0x0000433B, 0x00000000, + 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B6, 0x00002AC0, 0x00000003, + 0x0004007C, 0x0000000D, 0x00003F6D, 0x000056B6, 0x00050050, 0x00000013, 0x00004FAF, 0x00003F6D, + 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3B, 0x00004FAF, 0x00004FAF, 0x00000000, 0x00000001, + 0x00000001, 0x00000001, 0x000200F9, 0x00003F61, 0x000200F8, 0x00003F61, 0x000F00F5, 0x0000001D, + 0x00002BAA, 0x00005A3B, 0x00004BFC, 0x00003093, 0x000038FA, 0x000026A0, 0x00001CBD, 0x00002350, + 0x00001CBC, 0x0000234F, 0x00001FFF, 0x0000234E, 0x00002035, 0x000F00F5, 0x0000001D, 0x0000380B, + 0x00002D95, 0x00004BFC, 0x00004B28, 0x000038FA, 0x00004135, 0x00001CBD, 0x00003DDF, 0x00001CBC, + 0x00004123, 0x00001FFF, 0x00003914, 0x00002035, 0x000F00F5, 0x0000001D, 0x00003B7F, 0x00002D94, + 0x00004BFC, 0x00004B27, 0x000038FA, 0x00004134, 0x00001CBD, 0x00003DDE, 0x00001CBC, 0x00004122, + 0x00001FFF, 0x00003913, 0x00002035, 0x000F00F5, 0x0000001D, 0x000038B8, 0x00002D93, 0x00004BFC, + 0x00004B26, 0x000038FA, 0x00004133, 0x00001CBD, 0x00003DDD, 0x00001CBC, 0x00004121, 0x00001FFF, + 0x00003912, 0x00002035, 0x000200F9, 0x00005310, 0x000200F8, 0x00003B66, 0x000500AA, 0x00000009, + 0x00005451, 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F25, 0x00000002, 0x000400FA, 0x00005451, + 0x00002625, 0x00002F64, 0x000200F8, 0x00002F64, 0x00060041, 0x00000288, 0x00004BD2, 0x00000CC7, + 0x00000A0B, 0x00005E78, 0x0004003D, 0x0000000B, 0x00005D49, 0x00004BD2, 0x00050080, 0x0000000B, + 0x00002DBA, 0x00005AD8, 0x00000AFD, 0x00060041, 0x00000288, 0x00001909, 0x00000CC7, 0x00000A0B, + 0x00002DBA, 0x0004003D, 0x0000000B, 0x00005C6F, 0x00001909, 0x00050080, 0x0000000B, 0x00002DBB, + 0x00005E78, 0x0000199B, 0x00060041, 0x00000288, 0x0000190A, 0x00000CC7, 0x00000A0B, 0x00002DBB, + 0x0004003D, 0x0000000B, 0x00005C70, 0x0000190A, 0x00050080, 0x0000000B, 0x00002DBC, 0x00002DBB, + 0x00000A0D, 0x00060041, 0x00000288, 0x00005FF4, 0x00000CC7, 0x00000A0B, 0x00002DBC, 0x0004003D, + 0x0000000B, 0x0000374D, 0x00005FF4, 0x00070050, 0x00000017, 0x00004CD7, 0x00005D49, 0x00005C6F, + 0x00005C70, 0x0000374D, 0x00050084, 0x0000000B, 0x00004299, 0x00000A10, 0x0000199B, 0x00050080, + 0x0000000B, 0x000036A9, 0x00005E78, 0x00004299, 0x00060041, 0x00000288, 0x00003B83, 0x00000CC7, + 0x00000A0B, 0x000036A9, 0x0004003D, 0x0000000B, 0x00005C71, 0x00003B83, 0x00050080, 0x0000000B, + 0x00002DBD, 0x000036A9, 0x00000A0D, 0x00060041, 0x00000288, 0x0000194E, 0x00000CC7, 0x00000A0B, + 0x00002DBD, 0x0004003D, 0x0000000B, 0x00005E60, 0x0000194E, 0x00050084, 0x0000000B, 0x0000185F, + 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A6, 0x00005E78, 0x0000185F, 0x00060041, + 0x00000288, 0x00003B84, 0x00000CC7, 0x00000A0B, 0x000020A6, 0x0004003D, 0x0000000B, 0x00005C72, + 0x00003B84, 0x00050080, 0x0000000B, 0x00002DBE, 0x000020A6, 0x00000A0D, 0x00060041, 0x00000288, + 0x00005FF5, 0x00000CC7, 0x00000A0B, 0x00002DBE, 0x0004003D, 0x0000000B, 0x00004001, 0x00005FF5, + 0x00070050, 0x00000017, 0x00005132, 0x00005C71, 0x00005E60, 0x00005C72, 0x00004001, 0x000200F9, + 0x00004F25, 0x000200F8, 0x00002625, 0x00060041, 0x00000288, 0x00005548, 0x00000CC7, 0x00000A0B, + 0x00005E78, 0x0004003D, 0x0000000B, 0x00005D4A, 0x00005548, 0x00050080, 0x0000000B, 0x00002DBF, + 0x00005AD8, 0x00000AFD, 0x00060041, 0x00000288, 0x0000190B, 0x00000CC7, 0x00000A0B, 0x00002DBF, + 0x0004003D, 0x0000000B, 0x00005C73, 0x0000190B, 0x00050080, 0x0000000B, 0x00002DC0, 0x00005AD8, + 0x00000B00, 0x00060041, 0x00000288, 0x0000190C, 0x00000CC7, 0x00000A0B, 0x00002DC0, 0x0004003D, + 0x0000000B, 0x00005C74, 0x0000190C, 0x00050080, 0x0000000B, 0x00002DC1, 0x00005AD8, 0x00000B03, + 0x00060041, 0x00000288, 0x00005FF6, 0x00000CC7, 0x00000A0B, 0x00002DC1, 0x0004003D, 0x0000000B, + 0x00003701, 0x00005FF6, 0x00070050, 0x00000017, 0x00004ADE, 0x00005D4A, 0x00005C73, 0x00005C74, + 0x00003701, 0x00050080, 0x0000000B, 0x000057E6, 0x00005AD8, 0x00000B06, 0x00060041, 0x00000288, + 0x0000604C, 0x00000CC7, 0x00000A0B, 0x000057E6, 0x0004003D, 0x0000000B, 0x00005C75, 0x0000604C, + 0x00050080, 0x0000000B, 0x00002DC2, 0x00005AD8, 0x00000B09, 0x00060041, 0x00000288, 0x0000190D, + 0x00000CC7, 0x00000A0B, 0x00002DC2, 0x0004003D, 0x0000000B, 0x00005C76, 0x0000190D, 0x00050080, + 0x0000000B, 0x00002DC3, 0x00005AD8, 0x00000B0D, 0x00060041, 0x00000288, 0x0000190E, 0x00000CC7, + 0x00000A0B, 0x00002DC3, 0x0004003D, 0x0000000B, 0x00005C77, 0x0000190E, 0x00050080, 0x0000000B, + 0x00002DC4, 0x00005AD8, 0x00000B0F, 0x00060041, 0x00000288, 0x00005FF7, 0x00000CC7, 0x00000A0B, + 0x00002DC4, 0x0004003D, 0x0000000B, 0x00004002, 0x00005FF7, 0x00070050, 0x00000017, 0x00005133, + 0x00005C75, 0x00005C76, 0x00005C77, 0x00004002, 0x000200F9, 0x00004F25, 0x000200F8, 0x00004F25, + 0x000700F5, 0x00000017, 0x00002BCE, 0x00005133, 0x00002625, 0x00005132, 0x00002F64, 0x000700F5, + 0x00000017, 0x00003721, 0x00004ADE, 0x00002625, 0x00004CD7, 0x00002F64, 0x000300F7, 0x00004F26, + 0x00000000, 0x000700FB, 0x00002180, 0x00004F57, 0x00000005, 0x00002159, 0x00000007, 0x00002036, + 0x000200F8, 0x00002036, 0x00050051, 0x0000000B, 0x00005F59, 0x00003721, 0x00000000, 0x0006000C, + 0x00000013, 0x0000606A, 0x00000001, 0x0000003E, 0x00005F59, 0x00050051, 0x0000000D, 0x00002779, + 0x0000606A, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBC, 0x0000606A, 0x00000001, 0x00050051, + 0x0000000B, 0x00004285, 0x00003721, 0x00000001, 0x0006000C, 0x00000013, 0x00003CF9, 0x00000001, + 0x0000003E, 0x00004285, 0x00050051, 0x0000000D, 0x0000276E, 0x00003CF9, 0x00000000, 0x00050051, + 0x0000000D, 0x0000444F, 0x00003CF9, 0x00000001, 0x00070050, 0x0000001D, 0x00003915, 0x00002779, + 0x00003EBC, 0x0000276E, 0x0000444F, 0x00050051, 0x0000000B, 0x00004383, 0x00003721, 0x00000002, + 0x0006000C, 0x00000013, 0x00004674, 0x00000001, 0x0000003E, 0x00004383, 0x00050051, 0x0000000D, + 0x0000277A, 0x00004674, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBD, 0x00004674, 0x00000001, + 0x00050051, 0x0000000B, 0x00004286, 0x00003721, 0x00000003, 0x0006000C, 0x00000013, 0x00003CFA, + 0x00000001, 0x0000003E, 0x00004286, 0x00050051, 0x0000000D, 0x0000276F, 0x00003CFA, 0x00000000, + 0x00050051, 0x0000000D, 0x00004450, 0x00003CFA, 0x00000001, 0x00070050, 0x0000001D, 0x00003916, + 0x0000277A, 0x00003EBD, 0x0000276F, 0x00004450, 0x00050051, 0x0000000B, 0x00004384, 0x00002BCE, + 0x00000000, 0x0006000C, 0x00000013, 0x00004675, 0x00000001, 0x0000003E, 0x00004384, 0x00050051, + 0x0000000D, 0x0000277B, 0x00004675, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBE, 0x00004675, + 0x00000001, 0x00050051, 0x0000000B, 0x00004287, 0x00002BCE, 0x00000001, 0x0006000C, 0x00000013, + 0x00003CFB, 0x00000001, 0x0000003E, 0x00004287, 0x00050051, 0x0000000D, 0x00002770, 0x00003CFB, + 0x00000000, 0x00050051, 0x0000000D, 0x00004451, 0x00003CFB, 0x00000001, 0x00070050, 0x0000001D, + 0x00003917, 0x0000277B, 0x00003EBE, 0x00002770, 0x00004451, 0x00050051, 0x0000000B, 0x00004385, + 0x00002BCE, 0x00000002, 0x0006000C, 0x00000013, 0x00004676, 0x00000001, 0x0000003E, 0x00004385, + 0x00050051, 0x0000000D, 0x0000277C, 0x00004676, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBF, + 0x00004676, 0x00000001, 0x00050051, 0x0000000B, 0x00004288, 0x00002BCE, 0x00000003, 0x0006000C, + 0x00000013, 0x00003CFC, 0x00000001, 0x0000003E, 0x00004288, 0x00050051, 0x0000000D, 0x00002771, + 0x00003CFC, 0x00000000, 0x00050051, 0x0000000D, 0x000050C1, 0x00003CFC, 0x00000001, 0x00070050, + 0x0000001D, 0x00002351, 0x0000277C, 0x00003EBF, 0x00002771, 0x000050C1, 0x000200F9, 0x00004F26, + 0x000200F8, 0x00002159, 0x0007004F, 0x00000011, 0x000025FC, 0x00003721, 0x00003721, 0x00000000, + 0x00000001, 0x0004007C, 0x00000012, 0x00005B3D, 0x000025FC, 0x0009004F, 0x0000001A, 0x000060D2, + 0x00005B3D, 0x00005B3D, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, + 0x000048AA, 0x000060D2, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D91, 0x000048AA, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002AAB, 0x00003D91, 0x0005008E, 0x0000001D, 0x00004725, 0x00002AAB, + 0x000007FE, 0x0007000C, 0x0000001D, 0x00006294, 0x00000001, 0x00000028, 0x00000504, 0x00004725, + 0x0007004F, 0x00000011, 0x0000376E, 0x00003721, 0x00003721, 0x00000002, 0x00000003, 0x0004007C, + 0x00000012, 0x000024C2, 0x0000376E, 0x0009004F, 0x0000001A, 0x000060D3, 0x000024C2, 0x000024C2, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048AB, 0x000060D3, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D92, 0x000048AB, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002AAC, 0x00003D92, 0x0005008E, 0x0000001D, 0x00004726, 0x00002AAC, 0x000007FE, 0x0007000C, + 0x0000001D, 0x00006295, 0x00000001, 0x00000028, 0x00000504, 0x00004726, 0x0007004F, 0x00000011, + 0x0000376F, 0x00002BCE, 0x00002BCE, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000024C3, + 0x0000376F, 0x0009004F, 0x0000001A, 0x000060D4, 0x000024C3, 0x000024C3, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048AC, 0x000060D4, 0x00000122, 0x000500C3, + 0x0000001A, 0x00003D93, 0x000048AC, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AAD, 0x00003D93, + 0x0005008E, 0x0000001D, 0x00004727, 0x00002AAD, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006296, + 0x00000001, 0x00000028, 0x00000504, 0x00004727, 0x0007004F, 0x00000011, 0x00003770, 0x00002BCE, + 0x00002BCE, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C4, 0x00003770, 0x0009004F, + 0x0000001A, 0x000060D5, 0x000024C4, 0x000024C4, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C4, 0x0000001A, 0x000048AD, 0x000060D5, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D94, + 0x000048AD, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AAE, 0x00003D94, 0x0005008E, 0x0000001D, + 0x000053C0, 0x00002AAE, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004363, 0x00000001, 0x00000028, + 0x00000504, 0x000053C0, 0x000200F9, 0x00004F26, 0x000200F8, 0x00004F57, 0x0007004F, 0x00000011, + 0x00002626, 0x00003721, 0x00003721, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x0000515A, + 0x00002626, 0x00050051, 0x0000000D, 0x00001B7F, 0x0000515A, 0x00000000, 0x00050051, 0x0000000D, + 0x0000346D, 0x0000515A, 0x00000001, 0x00070050, 0x0000001D, 0x0000427B, 0x00001B7F, 0x0000346D, + 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DB, 0x00003721, 0x00003721, 0x00000002, + 0x00000003, 0x0004007C, 0x00000013, 0x00003760, 0x000041DB, 0x00050051, 0x0000000D, 0x00001B80, + 0x00003760, 0x00000000, 0x00050051, 0x0000000D, 0x0000346E, 0x00003760, 0x00000001, 0x00070050, + 0x0000001D, 0x0000427C, 0x00001B80, 0x0000346E, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, + 0x000041DC, 0x00002BCE, 0x00002BCE, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x00003761, + 0x000041DC, 0x00050051, 0x0000000D, 0x00001B81, 0x00003761, 0x00000000, 0x00050051, 0x0000000D, + 0x0000346F, 0x00003761, 0x00000001, 0x00070050, 0x0000001D, 0x0000427D, 0x00001B81, 0x0000346F, + 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DD, 0x00002BCE, 0x00002BCE, 0x00000002, + 0x00000003, 0x0004007C, 0x00000013, 0x00003762, 0x000041DD, 0x00050051, 0x0000000D, 0x00001B82, + 0x00003762, 0x00000000, 0x00050051, 0x0000000D, 0x00004109, 0x00003762, 0x00000001, 0x00070050, + 0x0000001D, 0x00002352, 0x00001B82, 0x00004109, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F26, + 0x000200F8, 0x00004F26, 0x000900F5, 0x0000001D, 0x00002BAB, 0x00002352, 0x00004F57, 0x00004363, + 0x00002159, 0x00002351, 0x00002036, 0x000900F5, 0x0000001D, 0x0000380C, 0x0000427D, 0x00004F57, + 0x00006296, 0x00002159, 0x00003917, 0x00002036, 0x000900F5, 0x0000001D, 0x00003B80, 0x0000427C, + 0x00004F57, 0x00006295, 0x00002159, 0x00003916, 0x00002036, 0x000900F5, 0x0000001D, 0x000038B9, + 0x0000427B, 0x00004F57, 0x00006294, 0x00002159, 0x00003915, 0x00002036, 0x000200F9, 0x00005310, + 0x000200F8, 0x00005310, 0x000700F5, 0x0000001D, 0x00002BAC, 0x00002BAB, 0x00004F26, 0x00002BAA, + 0x00003F61, 0x000700F5, 0x0000001D, 0x0000380D, 0x0000380C, 0x00004F26, 0x0000380B, 0x00003F61, + 0x000700F5, 0x0000001D, 0x00003295, 0x00003B80, 0x00004F26, 0x00003B7F, 0x00003F61, 0x000700F5, + 0x0000001D, 0x0000367A, 0x000038B9, 0x00004F26, 0x000038B8, 0x00003F61, 0x00050081, 0x0000001D, + 0x00004359, 0x000020D3, 0x0000367A, 0x00050081, 0x0000001D, 0x00005B01, 0x000035EC, 0x00003295, + 0x00050081, 0x0000001D, 0x00001F92, 0x0000380A, 0x0000380D, 0x00050081, 0x0000001D, 0x00005113, + 0x00002BA9, 0x00002BAC, 0x000500AE, 0x00000009, 0x0000387D, 0x00003F4D, 0x00000A1C, 0x000300F7, + 0x00005EC8, 0x00000002, 0x000400FA, 0x0000387D, 0x000026B1, 0x00005EC8, 0x000200F8, 0x000026B1, + 0x000500C4, 0x0000000B, 0x000037B2, 0x00000A0D, 0x000023AA, 0x00050085, 0x0000000D, 0x00002F3A, + 0x00002B2C, 0x0000016E, 0x00050080, 0x0000000B, 0x000051FC, 0x00005AD8, 0x000037B2, 0x000300F7, + 0x00005311, 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B67, 0x000040BB, 0x000200F8, 0x000040BB, + 0x000500AA, 0x00000009, 0x00004ADF, 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F4B, 0x00000002, + 0x000400FA, 0x00004ADF, 0x00002627, 0x00002F65, 0x000200F8, 0x00002F65, 0x00060041, 0x00000288, + 0x00004BD3, 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, 0x00005D4B, 0x00004BD3, + 0x00050080, 0x0000000B, 0x00002DC5, 0x000051FC, 0x0000199B, 0x00060041, 0x00000288, 0x0000194F, + 0x00000CC7, 0x00000A0B, 0x00002DC5, 0x0004003D, 0x0000000B, 0x00005E61, 0x0000194F, 0x00050084, + 0x0000000B, 0x00001860, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A7, 0x000051FC, + 0x00001860, 0x00060041, 0x00000288, 0x00003BCF, 0x00000CC7, 0x00000A0B, 0x000020A7, 0x0004003D, + 0x0000000B, 0x00005E62, 0x00003BCF, 0x00050084, 0x0000000B, 0x00001861, 0x00000A13, 0x0000199B, + 0x00050080, 0x0000000B, 0x000020A8, 0x000051FC, 0x00001861, 0x00060041, 0x00000288, 0x000037F3, + 0x00000CC7, 0x00000A0B, 0x000020A8, 0x0004003D, 0x0000000B, 0x00004003, 0x000037F3, 0x00070050, + 0x00000017, 0x00005134, 0x00005D4B, 0x00005E61, 0x00005E62, 0x00004003, 0x000200F9, 0x00004F4B, + 0x000200F8, 0x00002627, 0x00060041, 0x00000288, 0x00005549, 0x00000CC7, 0x00000A0B, 0x000051FC, + 0x0004003D, 0x0000000B, 0x00005D4C, 0x00005549, 0x00050080, 0x0000000B, 0x00002DC6, 0x000051FC, + 0x00000A0D, 0x00060041, 0x00000288, 0x0000190F, 0x00000CC7, 0x00000A0B, 0x00002DC6, 0x0004003D, + 0x0000000B, 0x00005C78, 0x0000190F, 0x00050080, 0x0000000B, 0x00002DC7, 0x000051FC, 0x00000A10, + 0x00060041, 0x00000288, 0x00001910, 0x00000CC7, 0x00000A0B, 0x00002DC7, 0x0004003D, 0x0000000B, + 0x00005C79, 0x00001910, 0x00050080, 0x0000000B, 0x00002DC8, 0x000051FC, 0x00000A13, 0x00060041, + 0x00000288, 0x00005FF8, 0x00000CC7, 0x00000A0B, 0x00002DC8, 0x0004003D, 0x0000000B, 0x00004004, + 0x00005FF8, 0x00070050, 0x00000017, 0x00005135, 0x00005D4C, 0x00005C78, 0x00005C79, 0x00004004, + 0x000200F9, 0x00004F4B, 0x000200F8, 0x00004F4B, 0x000700F5, 0x00000017, 0x00002AC1, 0x00005135, + 0x00002627, 0x00005134, 0x00002F65, 0x000300F7, 0x00003F62, 0x00000000, 0x001300FB, 0x00002180, + 0x00004BFD, 0x00000000, 0x000038FB, 0x00000001, 0x000038FB, 0x00000002, 0x00001CBF, 0x0000000A, + 0x00001CBF, 0x00000003, 0x00001CBE, 0x0000000C, 0x00001CBE, 0x00000004, 0x00002000, 0x00000006, + 0x00002037, 0x000200F8, 0x00002037, 0x00050051, 0x0000000B, 0x00005F5A, 0x00002AC1, 0x00000000, + 0x0006000C, 0x00000013, 0x0000606B, 0x00000001, 0x0000003E, 0x00005F5A, 0x00050051, 0x0000000D, + 0x00002772, 0x0000606B, 0x00000000, 0x00050051, 0x0000000D, 0x00004452, 0x0000606B, 0x00000001, + 0x00070050, 0x0000001D, 0x00003918, 0x00002772, 0x00004452, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x00004386, 0x00002AC1, 0x00000001, 0x0006000C, 0x00000013, 0x00004677, 0x00000001, + 0x0000003E, 0x00004386, 0x00050051, 0x0000000D, 0x00002773, 0x00004677, 0x00000000, 0x00050051, + 0x0000000D, 0x00004453, 0x00004677, 0x00000001, 0x00070050, 0x0000001D, 0x00003919, 0x00002773, + 0x00004453, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004387, 0x00002AC1, 0x00000002, + 0x0006000C, 0x00000013, 0x00004678, 0x00000001, 0x0000003E, 0x00004387, 0x00050051, 0x0000000D, + 0x00002774, 0x00004678, 0x00000000, 0x00050051, 0x0000000D, 0x00004454, 0x00004678, 0x00000001, + 0x00070050, 0x0000001D, 0x0000391A, 0x00002774, 0x00004454, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x00004388, 0x00002AC1, 0x00000003, 0x0006000C, 0x00000013, 0x00004679, 0x00000001, + 0x0000003E, 0x00004388, 0x00050051, 0x0000000D, 0x0000277D, 0x00004679, 0x00000000, 0x00050051, + 0x0000000D, 0x000050C2, 0x00004679, 0x00000001, 0x00070050, 0x0000001D, 0x00002353, 0x0000277D, + 0x000050C2, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F62, 0x000200F8, 0x00002000, 0x00050051, + 0x0000000B, 0x0000308F, 0x00002AC1, 0x00000000, 0x0004007C, 0x0000000C, 0x0000589F, 0x0000308F, + 0x00050050, 0x00000012, 0x00004728, 0x0000589F, 0x0000589F, 0x000500C4, 0x00000012, 0x000047B5, + 0x00004728, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341F, 0x000047B5, 0x00000867, 0x0004006F, + 0x00000013, 0x00002AAF, 0x0000341F, 0x0005008E, 0x00000013, 0x0000474F, 0x00002AAF, 0x000007FE, + 0x0007000C, 0x00000013, 0x00005E0E, 0x00000001, 0x00000028, 0x00000049, 0x0000474F, 0x00050051, + 0x0000000D, 0x00005F12, 0x00005E0E, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDA, 0x00005E0E, + 0x00000001, 0x00070050, 0x0000001D, 0x00004124, 0x00005F12, 0x00003CDA, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x00004C48, 0x00002AC1, 0x00000001, 0x0004007C, 0x0000000C, 0x00003EA7, + 0x00004C48, 0x00050050, 0x00000012, 0x00004729, 0x00003EA7, 0x00003EA7, 0x000500C4, 0x00000012, + 0x000047B6, 0x00004729, 0x000007A7, 0x000500C3, 0x00000012, 0x00003420, 0x000047B6, 0x00000867, + 0x0004006F, 0x00000013, 0x00002AB0, 0x00003420, 0x0005008E, 0x00000013, 0x00004750, 0x00002AB0, + 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0F, 0x00000001, 0x00000028, 0x00000049, 0x00004750, + 0x00050051, 0x0000000D, 0x00005F13, 0x00005E0F, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDB, + 0x00005E0F, 0x00000001, 0x00070050, 0x0000001D, 0x00004125, 0x00005F13, 0x00003CDB, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C49, 0x00002AC1, 0x00000002, 0x0004007C, 0x0000000C, + 0x00003EA8, 0x00004C49, 0x00050050, 0x00000012, 0x0000472A, 0x00003EA8, 0x00003EA8, 0x000500C4, + 0x00000012, 0x000047B7, 0x0000472A, 0x000007A7, 0x000500C3, 0x00000012, 0x00003421, 0x000047B7, + 0x00000867, 0x0004006F, 0x00000013, 0x00002AB1, 0x00003421, 0x0005008E, 0x00000013, 0x00004751, + 0x00002AB1, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E10, 0x00000001, 0x00000028, 0x00000049, + 0x00004751, 0x00050051, 0x0000000D, 0x00005F14, 0x00005E10, 0x00000000, 0x00050051, 0x0000000D, + 0x00003CDC, 0x00005E10, 0x00000001, 0x00070050, 0x0000001D, 0x00004126, 0x00005F14, 0x00003CDC, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C4A, 0x00002AC1, 0x00000003, 0x0004007C, + 0x0000000C, 0x00003EA9, 0x00004C4A, 0x00050050, 0x00000012, 0x0000472B, 0x00003EA9, 0x00003EA9, + 0x000500C4, 0x00000012, 0x000047B8, 0x0000472B, 0x000007A7, 0x000500C3, 0x00000012, 0x00003422, + 0x000047B8, 0x00000867, 0x0004006F, 0x00000013, 0x00002AB2, 0x00003422, 0x0005008E, 0x00000013, + 0x00004752, 0x00002AB2, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E11, 0x00000001, 0x00000028, + 0x00000049, 0x00004752, 0x00050051, 0x0000000D, 0x00005F15, 0x00005E11, 0x00000000, 0x00050051, + 0x0000000D, 0x0000494E, 0x00005E11, 0x00000001, 0x00070050, 0x0000001D, 0x00002354, 0x00005F15, + 0x0000494E, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F62, 0x000200F8, 0x00001CBE, 0x00050051, + 0x0000000B, 0x000056C3, 0x00002AC1, 0x00000000, 0x00060050, 0x00000014, 0x00004F10, 0x000056C3, + 0x000056C3, 0x000056C3, 0x000500C2, 0x00000014, 0x00002B17, 0x00004F10, 0x00000BB4, 0x000500C7, + 0x00000014, 0x00005DEE, 0x00002B17, 0x00000105, 0x000500C7, 0x00000014, 0x000048A4, 0x00005DEE, + 0x00000466, 0x000500C2, 0x00000014, 0x00005B98, 0x00005DEE, 0x00000B0C, 0x000500AA, 0x00000010, + 0x000040D1, 0x00005B98, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C53, 0x00000001, 0x0000004B, + 0x000048A4, 0x0004007C, 0x00000014, 0x00002A1D, 0x00002C53, 0x00050082, 0x00000014, 0x00001882, + 0x00000B0C, 0x00002A1D, 0x00050080, 0x00000014, 0x00002218, 0x00002A1D, 0x00000938, 0x000600A9, + 0x00000014, 0x00002877, 0x000040D1, 0x00002218, 0x00005B98, 0x000500C4, 0x00000014, 0x00005ADD, + 0x000048A4, 0x00001882, 0x000500C7, 0x00000014, 0x000049A2, 0x00005ADD, 0x00000466, 0x000600A9, + 0x00000014, 0x00002AB3, 0x000040D1, 0x000049A2, 0x000048A4, 0x00050080, 0x00000014, 0x00006001, + 0x00002877, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F87, 0x00006001, 0x00000189, 0x000500C4, + 0x00000014, 0x00003FAE, 0x00002AB3, 0x0000008D, 0x000500C5, 0x00000014, 0x00005784, 0x00004F87, + 0x00003FAE, 0x000500AA, 0x00000010, 0x00003608, 0x00005DEE, 0x00000A12, 0x000600A9, 0x00000014, + 0x0000424A, 0x00003608, 0x00000A12, 0x00005784, 0x0004007C, 0x00000018, 0x000029D7, 0x0000424A, + 0x000500C2, 0x0000000B, 0x00004BAC, 0x000056C3, 0x00000A64, 0x00040070, 0x0000000D, 0x00004816, + 0x00004BAC, 0x00050085, 0x0000000D, 0x00003E27, 0x00004816, 0x00000149, 0x00050051, 0x0000000D, + 0x000053CA, 0x000029D7, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5D, 0x000029D7, 0x00000001, + 0x00050051, 0x0000000D, 0x00001E9F, 0x000029D7, 0x00000002, 0x00070050, 0x0000001D, 0x00003DE0, + 0x000053CA, 0x00002A5D, 0x00001E9F, 0x00003E27, 0x00050051, 0x0000000B, 0x000027FB, 0x00002AC1, + 0x00000001, 0x00060050, 0x00000014, 0x00003514, 0x000027FB, 0x000027FB, 0x000027FB, 0x000500C2, + 0x00000014, 0x00002B18, 0x00003514, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEF, 0x00002B18, + 0x00000105, 0x000500C7, 0x00000014, 0x000048A5, 0x00005DEF, 0x00000466, 0x000500C2, 0x00000014, + 0x00005B99, 0x00005DEF, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D2, 0x00005B99, 0x00000A12, + 0x0006000C, 0x00000016, 0x00002C54, 0x00000001, 0x0000004B, 0x000048A5, 0x0004007C, 0x00000014, + 0x00002A1E, 0x00002C54, 0x00050082, 0x00000014, 0x00001883, 0x00000B0C, 0x00002A1E, 0x00050080, + 0x00000014, 0x00002219, 0x00002A1E, 0x00000938, 0x000600A9, 0x00000014, 0x00002878, 0x000040D2, + 0x00002219, 0x00005B99, 0x000500C4, 0x00000014, 0x00005ADE, 0x000048A5, 0x00001883, 0x000500C7, + 0x00000014, 0x000049A3, 0x00005ADE, 0x00000466, 0x000600A9, 0x00000014, 0x00002AB4, 0x000040D2, + 0x000049A3, 0x000048A5, 0x00050080, 0x00000014, 0x00006002, 0x00002878, 0x000003FA, 0x000500C4, + 0x00000014, 0x00004F88, 0x00006002, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAF, 0x00002AB4, + 0x0000008D, 0x000500C5, 0x00000014, 0x00005785, 0x00004F88, 0x00003FAF, 0x000500AA, 0x00000010, + 0x00003609, 0x00005DEF, 0x00000A12, 0x000600A9, 0x00000014, 0x0000424B, 0x00003609, 0x00000A12, + 0x00005785, 0x0004007C, 0x00000018, 0x000029D8, 0x0000424B, 0x000500C2, 0x0000000B, 0x00004BAD, + 0x000027FB, 0x00000A64, 0x00040070, 0x0000000D, 0x00004817, 0x00004BAD, 0x00050085, 0x0000000D, + 0x00003E28, 0x00004817, 0x00000149, 0x00050051, 0x0000000D, 0x000053CB, 0x000029D8, 0x00000000, + 0x00050051, 0x0000000D, 0x00002A5E, 0x000029D8, 0x00000001, 0x00050051, 0x0000000D, 0x00001EA0, + 0x000029D8, 0x00000002, 0x00070050, 0x0000001D, 0x00003DE1, 0x000053CB, 0x00002A5E, 0x00001EA0, + 0x00003E28, 0x00050051, 0x0000000B, 0x000027FC, 0x00002AC1, 0x00000002, 0x00060050, 0x00000014, + 0x00003515, 0x000027FC, 0x000027FC, 0x000027FC, 0x000500C2, 0x00000014, 0x00002B19, 0x00003515, + 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF0, 0x00002B19, 0x00000105, 0x000500C7, 0x00000014, + 0x000048AE, 0x00005DF0, 0x00000466, 0x000500C2, 0x00000014, 0x00005B9A, 0x00005DF0, 0x00000B0C, + 0x000500AA, 0x00000010, 0x000040D3, 0x00005B9A, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C55, + 0x00000001, 0x0000004B, 0x000048AE, 0x0004007C, 0x00000014, 0x00002A1F, 0x00002C55, 0x00050082, + 0x00000014, 0x00001884, 0x00000B0C, 0x00002A1F, 0x00050080, 0x00000014, 0x0000221A, 0x00002A1F, + 0x00000938, 0x000600A9, 0x00000014, 0x00002879, 0x000040D3, 0x0000221A, 0x00005B9A, 0x000500C4, + 0x00000014, 0x00005ADF, 0x000048AE, 0x00001884, 0x000500C7, 0x00000014, 0x000049A4, 0x00005ADF, + 0x00000466, 0x000600A9, 0x00000014, 0x00002AB5, 0x000040D3, 0x000049A4, 0x000048AE, 0x00050080, + 0x00000014, 0x00006003, 0x00002879, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F89, 0x00006003, + 0x00000189, 0x000500C4, 0x00000014, 0x00003FB0, 0x00002AB5, 0x0000008D, 0x000500C5, 0x00000014, + 0x00005786, 0x00004F89, 0x00003FB0, 0x000500AA, 0x00000010, 0x0000360A, 0x00005DF0, 0x00000A12, + 0x000600A9, 0x00000014, 0x0000424C, 0x0000360A, 0x00000A12, 0x00005786, 0x0004007C, 0x00000018, + 0x000029D9, 0x0000424C, 0x000500C2, 0x0000000B, 0x00004BAE, 0x000027FC, 0x00000A64, 0x00040070, + 0x0000000D, 0x00004818, 0x00004BAE, 0x00050085, 0x0000000D, 0x00003E29, 0x00004818, 0x00000149, + 0x00050051, 0x0000000D, 0x000053CC, 0x000029D9, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5F, + 0x000029D9, 0x00000001, 0x00050051, 0x0000000D, 0x00001EA1, 0x000029D9, 0x00000002, 0x00070050, + 0x0000001D, 0x00003DE2, 0x000053CC, 0x00002A5F, 0x00001EA1, 0x00003E29, 0x00050051, 0x0000000B, + 0x000027FD, 0x00002AC1, 0x00000003, 0x00060050, 0x00000014, 0x00003516, 0x000027FD, 0x000027FD, + 0x000027FD, 0x000500C2, 0x00000014, 0x00002B1A, 0x00003516, 0x00000BB4, 0x000500C7, 0x00000014, + 0x00005DF1, 0x00002B1A, 0x00000105, 0x000500C7, 0x00000014, 0x000048AF, 0x00005DF1, 0x00000466, + 0x000500C2, 0x00000014, 0x00005B9B, 0x00005DF1, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D4, + 0x00005B9B, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C56, 0x00000001, 0x0000004B, 0x000048AF, + 0x0004007C, 0x00000014, 0x00002A20, 0x00002C56, 0x00050082, 0x00000014, 0x00001885, 0x00000B0C, + 0x00002A20, 0x00050080, 0x00000014, 0x0000221B, 0x00002A20, 0x00000938, 0x000600A9, 0x00000014, + 0x0000287A, 0x000040D4, 0x0000221B, 0x00005B9B, 0x000500C4, 0x00000014, 0x00005AE0, 0x000048AF, + 0x00001885, 0x000500C7, 0x00000014, 0x000049A5, 0x00005AE0, 0x00000466, 0x000600A9, 0x00000014, + 0x00002AB6, 0x000040D4, 0x000049A5, 0x000048AF, 0x00050080, 0x00000014, 0x00006004, 0x0000287A, + 0x000003FA, 0x000500C4, 0x00000014, 0x00004F8A, 0x00006004, 0x00000189, 0x000500C4, 0x00000014, + 0x00003FB1, 0x00002AB6, 0x0000008D, 0x000500C5, 0x00000014, 0x00005787, 0x00004F8A, 0x00003FB1, + 0x000500AA, 0x00000010, 0x0000360B, 0x00005DF1, 0x00000A12, 0x000600A9, 0x00000014, 0x0000424D, + 0x0000360B, 0x00000A12, 0x00005787, 0x0004007C, 0x00000018, 0x000029DA, 0x0000424D, 0x000500C2, + 0x0000000B, 0x00004BAF, 0x000027FD, 0x00000A64, 0x00040070, 0x0000000D, 0x00004819, 0x00004BAF, + 0x00050085, 0x0000000D, 0x00003E2A, 0x00004819, 0x00000149, 0x00050051, 0x0000000D, 0x000053CD, + 0x000029DA, 0x00000000, 0x00050051, 0x0000000D, 0x00002A60, 0x000029DA, 0x00000001, 0x00050051, + 0x0000000D, 0x00002B1B, 0x000029DA, 0x00000002, 0x00070050, 0x0000001D, 0x00002355, 0x000053CD, + 0x00002A60, 0x00002B1B, 0x00003E2A, 0x000200F9, 0x00003F62, 0x000200F8, 0x00001CBF, 0x00050051, + 0x0000000B, 0x000056C4, 0x00002AC1, 0x00000000, 0x00070050, 0x00000017, 0x00004F11, 0x000056C4, + 0x000056C4, 0x000056C4, 0x000056C4, 0x000500C2, 0x00000017, 0x000024A8, 0x00004F11, 0x0000034D, + 0x000500C7, 0x00000017, 0x000049B3, 0x000024A8, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBD, + 0x000049B3, 0x00050085, 0x0000001D, 0x00004136, 0x00003CBD, 0x00000AEE, 0x00050051, 0x0000000B, + 0x00005CD8, 0x00002AC1, 0x00000001, 0x00070050, 0x00000017, 0x00005153, 0x00005CD8, 0x00005CD8, + 0x00005CD8, 0x00005CD8, 0x000500C2, 0x00000017, 0x000024A9, 0x00005153, 0x0000034D, 0x000500C7, + 0x00000017, 0x000049B4, 0x000024A9, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBE, 0x000049B4, + 0x00050085, 0x0000001D, 0x00004137, 0x00003CBE, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD9, + 0x00002AC1, 0x00000002, 0x00070050, 0x00000017, 0x00005154, 0x00005CD9, 0x00005CD9, 0x00005CD9, + 0x00005CD9, 0x000500C2, 0x00000017, 0x000024AA, 0x00005154, 0x0000034D, 0x000500C7, 0x00000017, + 0x000049B5, 0x000024AA, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBF, 0x000049B5, 0x00050085, + 0x0000001D, 0x00004138, 0x00003CBF, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CDA, 0x00002AC1, + 0x00000003, 0x00070050, 0x00000017, 0x00005155, 0x00005CDA, 0x00005CDA, 0x00005CDA, 0x00005CDA, + 0x000500C2, 0x00000017, 0x000024AB, 0x00005155, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B6, + 0x000024AB, 0x0000027B, 0x00040070, 0x0000001D, 0x00004931, 0x000049B6, 0x00050085, 0x0000001D, + 0x000026A1, 0x00004931, 0x00000AEE, 0x000200F9, 0x00003F62, 0x000200F8, 0x000038FB, 0x00050051, + 0x0000000B, 0x000056C5, 0x00002AC1, 0x00000000, 0x00070050, 0x00000017, 0x00004F12, 0x000056C5, + 0x000056C5, 0x000056C5, 0x000056C5, 0x000500C2, 0x00000017, 0x000024AC, 0x00004F12, 0x0000028D, + 0x000500C7, 0x00000017, 0x00004A5E, 0x000024AC, 0x0000064B, 0x00040070, 0x0000001D, 0x000036AA, + 0x00004A5E, 0x0005008E, 0x0000001D, 0x00004B29, 0x000036AA, 0x0000017A, 0x00050051, 0x0000000B, + 0x000021A5, 0x00002AC1, 0x00000001, 0x00070050, 0x00000017, 0x00006111, 0x000021A5, 0x000021A5, + 0x000021A5, 0x000021A5, 0x000500C2, 0x00000017, 0x000024AD, 0x00006111, 0x0000028D, 0x000500C7, + 0x00000017, 0x00004A5F, 0x000024AD, 0x0000064B, 0x00040070, 0x0000001D, 0x000036AB, 0x00004A5F, + 0x0005008E, 0x0000001D, 0x00004B2A, 0x000036AB, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A6, + 0x00002AC1, 0x00000002, 0x00070050, 0x00000017, 0x00006112, 0x000021A6, 0x000021A6, 0x000021A6, + 0x000021A6, 0x000500C2, 0x00000017, 0x000024AE, 0x00006112, 0x0000028D, 0x000500C7, 0x00000017, + 0x00004A60, 0x000024AE, 0x0000064B, 0x00040070, 0x0000001D, 0x000036AC, 0x00004A60, 0x0005008E, + 0x0000001D, 0x00004B2B, 0x000036AC, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A7, 0x00002AC1, + 0x00000003, 0x00070050, 0x00000017, 0x00006113, 0x000021A7, 0x000021A7, 0x000021A7, 0x000021A7, + 0x000500C2, 0x00000017, 0x000024AF, 0x00006113, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A61, + 0x000024AF, 0x0000064B, 0x00040070, 0x0000001D, 0x0000431C, 0x00004A61, 0x0005008E, 0x0000001D, + 0x00003094, 0x0000431C, 0x0000017A, 0x000200F9, 0x00003F62, 0x000200F8, 0x00004BFD, 0x00050051, + 0x0000000B, 0x00003090, 0x00002AC1, 0x00000000, 0x0004007C, 0x0000000D, 0x00004FF0, 0x00003090, + 0x00050050, 0x00000013, 0x0000433C, 0x00004FF0, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D96, + 0x0000433C, 0x0000433C, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, + 0x000056B7, 0x00002AC1, 0x00000001, 0x0004007C, 0x0000000D, 0x00003F6E, 0x000056B7, 0x00050050, + 0x00000013, 0x0000433D, 0x00003F6E, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D97, 0x0000433D, + 0x0000433D, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B8, + 0x00002AC1, 0x00000002, 0x0004007C, 0x0000000D, 0x00003F6F, 0x000056B8, 0x00050050, 0x00000013, + 0x0000433E, 0x00003F6F, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D98, 0x0000433E, 0x0000433E, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B9, 0x00002AC1, + 0x00000003, 0x0004007C, 0x0000000D, 0x00003F70, 0x000056B9, 0x00050050, 0x00000013, 0x00004FB0, + 0x00003F70, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3C, 0x00004FB0, 0x00004FB0, 0x00000000, + 0x00000001, 0x00000001, 0x00000001, 0x000200F9, 0x00003F62, 0x000200F8, 0x00003F62, 0x000F00F5, + 0x0000001D, 0x00002BAD, 0x00005A3C, 0x00004BFD, 0x00003094, 0x000038FB, 0x000026A1, 0x00001CBF, + 0x00002355, 0x00001CBE, 0x00002354, 0x00002000, 0x00002353, 0x00002037, 0x000F00F5, 0x0000001D, + 0x0000380E, 0x00002D98, 0x00004BFD, 0x00004B2B, 0x000038FB, 0x00004138, 0x00001CBF, 0x00003DE2, + 0x00001CBE, 0x00004126, 0x00002000, 0x0000391A, 0x00002037, 0x000F00F5, 0x0000001D, 0x00003B85, + 0x00002D97, 0x00004BFD, 0x00004B2A, 0x000038FB, 0x00004137, 0x00001CBF, 0x00003DE1, 0x00001CBE, + 0x00004125, 0x00002000, 0x00003919, 0x00002037, 0x000F00F5, 0x0000001D, 0x000038BA, 0x00002D96, + 0x00004BFD, 0x00004B29, 0x000038FB, 0x00004136, 0x00001CBF, 0x00003DE0, 0x00001CBE, 0x00004124, + 0x00002000, 0x00003918, 0x00002037, 0x000200F9, 0x00005311, 0x000200F8, 0x00003B67, 0x000500AA, + 0x00000009, 0x00005452, 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F27, 0x00000002, 0x000400FA, + 0x00005452, 0x00002628, 0x00002F66, 0x000200F8, 0x00002F66, 0x00060041, 0x00000288, 0x00004BD4, + 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, 0x00005D4D, 0x00004BD4, 0x00050080, + 0x0000000B, 0x00002DC9, 0x000051FC, 0x00000A0D, 0x00060041, 0x00000288, 0x00001911, 0x00000CC7, + 0x00000A0B, 0x00002DC9, 0x0004003D, 0x0000000B, 0x00005C7A, 0x00001911, 0x00050080, 0x0000000B, + 0x00002DCA, 0x000051FC, 0x0000199B, 0x00060041, 0x00000288, 0x00001912, 0x00000CC7, 0x00000A0B, + 0x00002DCA, 0x0004003D, 0x0000000B, 0x00005C7B, 0x00001912, 0x00050080, 0x0000000B, 0x00002DCB, + 0x00002DCA, 0x00000A0D, 0x00060041, 0x00000288, 0x00006005, 0x00000CC7, 0x00000A0B, 0x00002DCB, + 0x0004003D, 0x0000000B, 0x0000374E, 0x00006005, 0x00070050, 0x00000017, 0x00004CD9, 0x00005D4D, + 0x00005C7A, 0x00005C7B, 0x0000374E, 0x00050084, 0x0000000B, 0x0000429A, 0x00000A10, 0x0000199B, + 0x00050080, 0x0000000B, 0x000036AD, 0x000051FC, 0x0000429A, 0x00060041, 0x00000288, 0x00003B86, + 0x00000CC7, 0x00000A0B, 0x000036AD, 0x0004003D, 0x0000000B, 0x00005C7C, 0x00003B86, 0x00050080, + 0x0000000B, 0x00002DCC, 0x000036AD, 0x00000A0D, 0x00060041, 0x00000288, 0x00001950, 0x00000CC7, + 0x00000A0B, 0x00002DCC, 0x0004003D, 0x0000000B, 0x00005E63, 0x00001950, 0x00050084, 0x0000000B, + 0x00001862, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A9, 0x000051FC, 0x00001862, + 0x00060041, 0x00000288, 0x00003B87, 0x00000CC7, 0x00000A0B, 0x000020A9, 0x0004003D, 0x0000000B, + 0x00005C7D, 0x00003B87, 0x00050080, 0x0000000B, 0x00002DCD, 0x000020A9, 0x00000A0D, 0x00060041, + 0x00000288, 0x00006006, 0x00000CC7, 0x00000A0B, 0x00002DCD, 0x0004003D, 0x0000000B, 0x00004005, + 0x00006006, 0x00070050, 0x00000017, 0x00005136, 0x00005C7C, 0x00005E63, 0x00005C7D, 0x00004005, + 0x000200F9, 0x00004F27, 0x000200F8, 0x00002628, 0x00060041, 0x00000288, 0x0000554A, 0x00000CC7, + 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, 0x00005D4E, 0x0000554A, 0x00050080, 0x0000000B, + 0x00002DCE, 0x000051FC, 0x00000A0D, 0x00060041, 0x00000288, 0x00001913, 0x00000CC7, 0x00000A0B, + 0x00002DCE, 0x0004003D, 0x0000000B, 0x00005C7E, 0x00001913, 0x00050080, 0x0000000B, 0x00002DCF, + 0x000051FC, 0x00000A10, 0x00060041, 0x00000288, 0x00001914, 0x00000CC7, 0x00000A0B, 0x00002DCF, + 0x0004003D, 0x0000000B, 0x00005C7F, 0x00001914, 0x00050080, 0x0000000B, 0x00002DD0, 0x000051FC, + 0x00000A13, 0x00060041, 0x00000288, 0x00006007, 0x00000CC7, 0x00000A0B, 0x00002DD0, 0x0004003D, + 0x0000000B, 0x00003702, 0x00006007, 0x00070050, 0x00000017, 0x00004AE0, 0x00005D4E, 0x00005C7E, + 0x00005C7F, 0x00003702, 0x00050080, 0x0000000B, 0x000057E7, 0x000051FC, 0x00000A16, 0x00060041, + 0x00000288, 0x0000604D, 0x00000CC7, 0x00000A0B, 0x000057E7, 0x0004003D, 0x0000000B, 0x00005C80, + 0x0000604D, 0x00050080, 0x0000000B, 0x00002DD1, 0x000051FC, 0x00000A19, 0x00060041, 0x00000288, + 0x00001915, 0x00000CC7, 0x00000A0B, 0x00002DD1, 0x0004003D, 0x0000000B, 0x00005C81, 0x00001915, + 0x00050080, 0x0000000B, 0x00002DD2, 0x000051FC, 0x00000A1C, 0x00060041, 0x00000288, 0x00001916, + 0x00000CC7, 0x00000A0B, 0x00002DD2, 0x0004003D, 0x0000000B, 0x00005C82, 0x00001916, 0x00050080, + 0x0000000B, 0x00002DD3, 0x000051FC, 0x00000A1F, 0x00060041, 0x00000288, 0x00006008, 0x00000CC7, + 0x00000A0B, 0x00002DD3, 0x0004003D, 0x0000000B, 0x00004006, 0x00006008, 0x00070050, 0x00000017, + 0x00005137, 0x00005C80, 0x00005C81, 0x00005C82, 0x00004006, 0x000200F9, 0x00004F27, 0x000200F8, + 0x00004F27, 0x000700F5, 0x00000017, 0x00002BCF, 0x00005137, 0x00002628, 0x00005136, 0x00002F66, + 0x000700F5, 0x00000017, 0x00003722, 0x00004AE0, 0x00002628, 0x00004CD9, 0x00002F66, 0x000300F7, + 0x00004F28, 0x00000000, 0x000700FB, 0x00002180, 0x00004F58, 0x00000005, 0x0000215A, 0x00000007, + 0x00002038, 0x000200F8, 0x00002038, 0x00050051, 0x0000000B, 0x00005F5B, 0x00003722, 0x00000000, + 0x0006000C, 0x00000013, 0x0000606C, 0x00000001, 0x0000003E, 0x00005F5B, 0x00050051, 0x0000000D, + 0x0000277E, 0x0000606C, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC0, 0x0000606C, 0x00000001, + 0x00050051, 0x0000000B, 0x00004289, 0x00003722, 0x00000001, 0x0006000C, 0x00000013, 0x00003CFD, + 0x00000001, 0x0000003E, 0x00004289, 0x00050051, 0x0000000D, 0x0000277F, 0x00003CFD, 0x00000000, + 0x00050051, 0x0000000D, 0x00004455, 0x00003CFD, 0x00000001, 0x00070050, 0x0000001D, 0x0000391B, + 0x0000277E, 0x00003EC0, 0x0000277F, 0x00004455, 0x00050051, 0x0000000B, 0x00004389, 0x00003722, + 0x00000002, 0x0006000C, 0x00000013, 0x0000467A, 0x00000001, 0x0000003E, 0x00004389, 0x00050051, + 0x0000000D, 0x00002780, 0x0000467A, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC1, 0x0000467A, + 0x00000001, 0x00050051, 0x0000000B, 0x0000428A, 0x00003722, 0x00000003, 0x0006000C, 0x00000013, + 0x00003CFE, 0x00000001, 0x0000003E, 0x0000428A, 0x00050051, 0x0000000D, 0x00002781, 0x00003CFE, + 0x00000000, 0x00050051, 0x0000000D, 0x00004456, 0x00003CFE, 0x00000001, 0x00070050, 0x0000001D, + 0x0000391C, 0x00002780, 0x00003EC1, 0x00002781, 0x00004456, 0x00050051, 0x0000000B, 0x0000438A, + 0x00002BCF, 0x00000000, 0x0006000C, 0x00000013, 0x0000467B, 0x00000001, 0x0000003E, 0x0000438A, + 0x00050051, 0x0000000D, 0x00002782, 0x0000467B, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC2, + 0x0000467B, 0x00000001, 0x00050051, 0x0000000B, 0x0000428B, 0x00002BCF, 0x00000001, 0x0006000C, + 0x00000013, 0x00003CFF, 0x00000001, 0x0000003E, 0x0000428B, 0x00050051, 0x0000000D, 0x00002783, + 0x00003CFF, 0x00000000, 0x00050051, 0x0000000D, 0x00004457, 0x00003CFF, 0x00000001, 0x00070050, + 0x0000001D, 0x0000391D, 0x00002782, 0x00003EC2, 0x00002783, 0x00004457, 0x00050051, 0x0000000B, + 0x0000438B, 0x00002BCF, 0x00000002, 0x0006000C, 0x00000013, 0x0000467C, 0x00000001, 0x0000003E, + 0x0000438B, 0x00050051, 0x0000000D, 0x00002784, 0x0000467C, 0x00000000, 0x00050051, 0x0000000D, + 0x00003EC3, 0x0000467C, 0x00000001, 0x00050051, 0x0000000B, 0x0000428C, 0x00002BCF, 0x00000003, + 0x0006000C, 0x00000013, 0x00003D00, 0x00000001, 0x0000003E, 0x0000428C, 0x00050051, 0x0000000D, + 0x00002785, 0x00003D00, 0x00000000, 0x00050051, 0x0000000D, 0x000050C3, 0x00003D00, 0x00000001, + 0x00070050, 0x0000001D, 0x00002356, 0x00002784, 0x00003EC3, 0x00002785, 0x000050C3, 0x000200F9, + 0x00004F28, 0x000200F8, 0x0000215A, 0x0007004F, 0x00000011, 0x000025FD, 0x00003722, 0x00003722, + 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x00005B3E, 0x000025FD, 0x0009004F, 0x0000001A, + 0x000060D6, 0x00005B3E, 0x00005B3E, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, + 0x0000001A, 0x000048B0, 0x000060D6, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D95, 0x000048B0, + 0x00000302, 0x0004006F, 0x0000001D, 0x00002AB7, 0x00003D95, 0x0005008E, 0x0000001D, 0x0000472C, + 0x00002AB7, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006297, 0x00000001, 0x00000028, 0x00000504, + 0x0000472C, 0x0007004F, 0x00000011, 0x00003771, 0x00003722, 0x00003722, 0x00000002, 0x00000003, + 0x0004007C, 0x00000012, 0x000024C5, 0x00003771, 0x0009004F, 0x0000001A, 0x000060D7, 0x000024C5, + 0x000024C5, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048B1, + 0x000060D7, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D96, 0x000048B1, 0x00000302, 0x0004006F, + 0x0000001D, 0x00002AB8, 0x00003D96, 0x0005008E, 0x0000001D, 0x0000472D, 0x00002AB8, 0x000007FE, + 0x0007000C, 0x0000001D, 0x00006298, 0x00000001, 0x00000028, 0x00000504, 0x0000472D, 0x0007004F, + 0x00000011, 0x00003772, 0x00002BCF, 0x00002BCF, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, + 0x000024C6, 0x00003772, 0x0009004F, 0x0000001A, 0x000060D8, 0x000024C6, 0x000024C6, 0x00000000, + 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048B2, 0x000060D8, 0x00000122, + 0x000500C3, 0x0000001A, 0x00003D97, 0x000048B2, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AB9, + 0x00003D97, 0x0005008E, 0x0000001D, 0x0000472E, 0x00002AB9, 0x000007FE, 0x0007000C, 0x0000001D, + 0x00006299, 0x00000001, 0x00000028, 0x00000504, 0x0000472E, 0x0007004F, 0x00000011, 0x00003773, + 0x00002BCF, 0x00002BCF, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C7, 0x00003773, + 0x0009004F, 0x0000001A, 0x000060D9, 0x000024C7, 0x000024C7, 0x00000000, 0x00000000, 0x00000001, + 0x00000001, 0x000500C4, 0x0000001A, 0x000048B3, 0x000060D9, 0x00000122, 0x000500C3, 0x0000001A, + 0x00003D98, 0x000048B3, 0x00000302, 0x0004006F, 0x0000001D, 0x00002ABA, 0x00003D98, 0x0005008E, + 0x0000001D, 0x000053C1, 0x00002ABA, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004364, 0x00000001, + 0x00000028, 0x00000504, 0x000053C1, 0x000200F9, 0x00004F28, 0x000200F8, 0x00004F58, 0x0007004F, + 0x00000011, 0x00002629, 0x00003722, 0x00003722, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, + 0x0000515B, 0x00002629, 0x00050051, 0x0000000D, 0x00001B83, 0x0000515B, 0x00000000, 0x00050051, + 0x0000000D, 0x00003470, 0x0000515B, 0x00000001, 0x00070050, 0x0000001D, 0x0000427E, 0x00001B83, + 0x00003470, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DE, 0x00003722, 0x00003722, + 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x00003763, 0x000041DE, 0x00050051, 0x0000000D, + 0x00001B84, 0x00003763, 0x00000000, 0x00050051, 0x0000000D, 0x00003471, 0x00003763, 0x00000001, + 0x00070050, 0x0000001D, 0x0000427F, 0x00001B84, 0x00003471, 0x00000A0C, 0x00000A0C, 0x0007004F, + 0x00000011, 0x000041DF, 0x00002BCF, 0x00002BCF, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, + 0x00003764, 0x000041DF, 0x00050051, 0x0000000D, 0x00001B85, 0x00003764, 0x00000000, 0x00050051, + 0x0000000D, 0x00003472, 0x00003764, 0x00000001, 0x00070050, 0x0000001D, 0x00004280, 0x00001B85, + 0x00003472, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041E0, 0x00002BCF, 0x00002BCF, + 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x00003765, 0x000041E0, 0x00050051, 0x0000000D, + 0x00001B86, 0x00003765, 0x00000000, 0x00050051, 0x0000000D, 0x0000410A, 0x00003765, 0x00000001, + 0x00070050, 0x0000001D, 0x00002357, 0x00001B86, 0x0000410A, 0x00000A0C, 0x00000A0C, 0x000200F9, + 0x00004F28, 0x000200F8, 0x00004F28, 0x000900F5, 0x0000001D, 0x00002BAE, 0x00002357, 0x00004F58, + 0x00004364, 0x0000215A, 0x00002356, 0x00002038, 0x000900F5, 0x0000001D, 0x0000380F, 0x00004280, + 0x00004F58, 0x00006299, 0x0000215A, 0x0000391D, 0x00002038, 0x000900F5, 0x0000001D, 0x00003B88, + 0x0000427F, 0x00004F58, 0x00006298, 0x0000215A, 0x0000391C, 0x00002038, 0x000900F5, 0x0000001D, + 0x000038BB, 0x0000427E, 0x00004F58, 0x00006297, 0x0000215A, 0x0000391B, 0x00002038, 0x000200F9, + 0x00005311, 0x000200F8, 0x00005311, 0x000700F5, 0x0000001D, 0x00002BAF, 0x00002BAE, 0x00004F28, + 0x00002BAD, 0x00003F62, 0x000700F5, 0x0000001D, 0x00003810, 0x0000380F, 0x00004F28, 0x0000380E, + 0x00003F62, 0x000700F5, 0x0000001D, 0x00003296, 0x00003B88, 0x00004F28, 0x00003B85, 0x00003F62, + 0x000700F5, 0x0000001D, 0x0000367B, 0x000038BB, 0x00004F28, 0x000038BA, 0x00003F62, 0x00050081, + 0x0000001D, 0x0000435A, 0x00004359, 0x0000367B, 0x00050081, 0x0000001D, 0x00005B02, 0x00005B01, + 0x00003296, 0x00050081, 0x0000001D, 0x00001C28, 0x00001F92, 0x00003810, 0x00050081, 0x0000001D, + 0x000025AA, 0x00005113, 0x00002BAF, 0x00050080, 0x0000000B, 0x00003FF8, 0x00005E78, 0x000037B2, + 0x000300F7, 0x00005312, 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B68, 0x000040BC, 0x000200F8, + 0x000040BC, 0x000500AA, 0x00000009, 0x00004AE1, 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F4C, + 0x00000002, 0x000400FA, 0x00004AE1, 0x0000262A, 0x00002F67, 0x000200F8, 0x00002F67, 0x00060041, + 0x00000288, 0x00004BD5, 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D4F, + 0x00004BD5, 0x00050080, 0x0000000B, 0x00002DD4, 0x00003FF8, 0x0000199B, 0x00060041, 0x00000288, + 0x00001951, 0x00000CC7, 0x00000A0B, 0x00002DD4, 0x0004003D, 0x0000000B, 0x00005E64, 0x00001951, + 0x00050084, 0x0000000B, 0x00001863, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000020AA, + 0x00003FF8, 0x00001863, 0x00060041, 0x00000288, 0x00003BD0, 0x00000CC7, 0x00000A0B, 0x000020AA, + 0x0004003D, 0x0000000B, 0x00005E65, 0x00003BD0, 0x00050084, 0x0000000B, 0x00001864, 0x00000A13, + 0x0000199B, 0x00050080, 0x0000000B, 0x000020AB, 0x00003FF8, 0x00001864, 0x00060041, 0x00000288, + 0x000037F4, 0x00000CC7, 0x00000A0B, 0x000020AB, 0x0004003D, 0x0000000B, 0x00004007, 0x000037F4, + 0x00070050, 0x00000017, 0x00005138, 0x00005D4F, 0x00005E64, 0x00005E65, 0x00004007, 0x000200F9, + 0x00004F4C, 0x000200F8, 0x0000262A, 0x00060041, 0x00000288, 0x0000554B, 0x00000CC7, 0x00000A0B, + 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D50, 0x0000554B, 0x00050080, 0x0000000B, 0x00002DD5, + 0x00003FF8, 0x00000A0D, 0x00060041, 0x00000288, 0x00001917, 0x00000CC7, 0x00000A0B, 0x00002DD5, + 0x0004003D, 0x0000000B, 0x00005C83, 0x00001917, 0x00050080, 0x0000000B, 0x00002DD6, 0x00003FF8, + 0x00000A10, 0x00060041, 0x00000288, 0x00001918, 0x00000CC7, 0x00000A0B, 0x00002DD6, 0x0004003D, + 0x0000000B, 0x00005C84, 0x00001918, 0x00050080, 0x0000000B, 0x00002DD7, 0x00003FF8, 0x00000A13, + 0x00060041, 0x00000288, 0x00006009, 0x00000CC7, 0x00000A0B, 0x00002DD7, 0x0004003D, 0x0000000B, + 0x00004008, 0x00006009, 0x00070050, 0x00000017, 0x00005139, 0x00005D50, 0x00005C83, 0x00005C84, + 0x00004008, 0x000200F9, 0x00004F4C, 0x000200F8, 0x00004F4C, 0x000700F5, 0x00000017, 0x00002AC2, + 0x00005139, 0x0000262A, 0x00005138, 0x00002F67, 0x000300F7, 0x00003F63, 0x00000000, 0x001300FB, + 0x00002180, 0x00004BFE, 0x00000000, 0x000038FC, 0x00000001, 0x000038FC, 0x00000002, 0x00001CC1, + 0x0000000A, 0x00001CC1, 0x00000003, 0x00001CC0, 0x0000000C, 0x00001CC0, 0x00000004, 0x00002001, + 0x00000006, 0x00002039, 0x000200F8, 0x00002039, 0x00050051, 0x0000000B, 0x00005F5C, 0x00002AC2, + 0x00000000, 0x0006000C, 0x00000013, 0x0000606D, 0x00000001, 0x0000003E, 0x00005F5C, 0x00050051, + 0x0000000D, 0x00002786, 0x0000606D, 0x00000000, 0x00050051, 0x0000000D, 0x00004458, 0x0000606D, + 0x00000001, 0x00070050, 0x0000001D, 0x0000391E, 0x00002786, 0x00004458, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x0000438C, 0x00002AC2, 0x00000001, 0x0006000C, 0x00000013, 0x0000467D, + 0x00000001, 0x0000003E, 0x0000438C, 0x00050051, 0x0000000D, 0x00002787, 0x0000467D, 0x00000000, + 0x00050051, 0x0000000D, 0x00004459, 0x0000467D, 0x00000001, 0x00070050, 0x0000001D, 0x0000391F, + 0x00002787, 0x00004459, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x0000438D, 0x00002AC2, + 0x00000002, 0x0006000C, 0x00000013, 0x0000467E, 0x00000001, 0x0000003E, 0x0000438D, 0x00050051, + 0x0000000D, 0x00002788, 0x0000467E, 0x00000000, 0x00050051, 0x0000000D, 0x0000445A, 0x0000467E, + 0x00000001, 0x00070050, 0x0000001D, 0x00003920, 0x00002788, 0x0000445A, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x0000438E, 0x00002AC2, 0x00000003, 0x0006000C, 0x00000013, 0x0000467F, + 0x00000001, 0x0000003E, 0x0000438E, 0x00050051, 0x0000000D, 0x00002789, 0x0000467F, 0x00000000, + 0x00050051, 0x0000000D, 0x000050C4, 0x0000467F, 0x00000001, 0x00070050, 0x0000001D, 0x00002358, + 0x00002789, 0x000050C4, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F63, 0x000200F8, 0x00002001, + 0x00050051, 0x0000000B, 0x00003091, 0x00002AC2, 0x00000000, 0x0004007C, 0x0000000C, 0x000058A0, + 0x00003091, 0x00050050, 0x00000012, 0x0000472F, 0x000058A0, 0x000058A0, 0x000500C4, 0x00000012, + 0x000047B9, 0x0000472F, 0x000007A7, 0x000500C3, 0x00000012, 0x00003423, 0x000047B9, 0x00000867, + 0x0004006F, 0x00000013, 0x00002ABB, 0x00003423, 0x0005008E, 0x00000013, 0x00004753, 0x00002ABB, + 0x000007FE, 0x0007000C, 0x00000013, 0x00005E12, 0x00000001, 0x00000028, 0x00000049, 0x00004753, + 0x00050051, 0x0000000D, 0x00005F16, 0x00005E12, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDD, + 0x00005E12, 0x00000001, 0x00070050, 0x0000001D, 0x00004127, 0x00005F16, 0x00003CDD, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C4B, 0x00002AC2, 0x00000001, 0x0004007C, 0x0000000C, + 0x00003EAA, 0x00004C4B, 0x00050050, 0x00000012, 0x00004730, 0x00003EAA, 0x00003EAA, 0x000500C4, + 0x00000012, 0x000047BA, 0x00004730, 0x000007A7, 0x000500C3, 0x00000012, 0x00003424, 0x000047BA, + 0x00000867, 0x0004006F, 0x00000013, 0x00002ABC, 0x00003424, 0x0005008E, 0x00000013, 0x00004754, + 0x00002ABC, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E13, 0x00000001, 0x00000028, 0x00000049, + 0x00004754, 0x00050051, 0x0000000D, 0x00005F17, 0x00005E13, 0x00000000, 0x00050051, 0x0000000D, + 0x00003CDE, 0x00005E13, 0x00000001, 0x00070050, 0x0000001D, 0x00004128, 0x00005F17, 0x00003CDE, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C4C, 0x00002AC2, 0x00000002, 0x0004007C, + 0x0000000C, 0x00003EAB, 0x00004C4C, 0x00050050, 0x00000012, 0x00004731, 0x00003EAB, 0x00003EAB, + 0x000500C4, 0x00000012, 0x000047BB, 0x00004731, 0x000007A7, 0x000500C3, 0x00000012, 0x00003425, + 0x000047BB, 0x00000867, 0x0004006F, 0x00000013, 0x00002ABD, 0x00003425, 0x0005008E, 0x00000013, + 0x00004755, 0x00002ABD, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E14, 0x00000001, 0x00000028, + 0x00000049, 0x00004755, 0x00050051, 0x0000000D, 0x00005F18, 0x00005E14, 0x00000000, 0x00050051, + 0x0000000D, 0x00003CDF, 0x00005E14, 0x00000001, 0x00070050, 0x0000001D, 0x00004129, 0x00005F18, + 0x00003CDF, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C4D, 0x00002AC2, 0x00000003, + 0x0004007C, 0x0000000C, 0x00003EAC, 0x00004C4D, 0x00050050, 0x00000012, 0x00004732, 0x00003EAC, + 0x00003EAC, 0x000500C4, 0x00000012, 0x000047BC, 0x00004732, 0x000007A7, 0x000500C3, 0x00000012, + 0x00003426, 0x000047BC, 0x00000867, 0x0004006F, 0x00000013, 0x00002ABE, 0x00003426, 0x0005008E, + 0x00000013, 0x00004756, 0x00002ABE, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E15, 0x00000001, + 0x00000028, 0x00000049, 0x00004756, 0x00050051, 0x0000000D, 0x00005F19, 0x00005E15, 0x00000000, + 0x00050051, 0x0000000D, 0x0000494F, 0x00005E15, 0x00000001, 0x00070050, 0x0000001D, 0x00002359, + 0x00005F19, 0x0000494F, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F63, 0x000200F8, 0x00001CC0, + 0x00050051, 0x0000000B, 0x000056C6, 0x00002AC2, 0x00000000, 0x00060050, 0x00000014, 0x00004F13, + 0x000056C6, 0x000056C6, 0x000056C6, 0x000500C2, 0x00000014, 0x00002B1C, 0x00004F13, 0x00000BB4, + 0x000500C7, 0x00000014, 0x00005DF2, 0x00002B1C, 0x00000105, 0x000500C7, 0x00000014, 0x000048B4, + 0x00005DF2, 0x00000466, 0x000500C2, 0x00000014, 0x00005B9C, 0x00005DF2, 0x00000B0C, 0x000500AA, + 0x00000010, 0x000040D5, 0x00005B9C, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C57, 0x00000001, + 0x0000004B, 0x000048B4, 0x0004007C, 0x00000014, 0x00002A21, 0x00002C57, 0x00050082, 0x00000014, + 0x00001886, 0x00000B0C, 0x00002A21, 0x00050080, 0x00000014, 0x0000221C, 0x00002A21, 0x00000938, + 0x000600A9, 0x00000014, 0x0000287B, 0x000040D5, 0x0000221C, 0x00005B9C, 0x000500C4, 0x00000014, + 0x00005AE1, 0x000048B4, 0x00001886, 0x000500C7, 0x00000014, 0x000049A6, 0x00005AE1, 0x00000466, + 0x000600A9, 0x00000014, 0x00002AC3, 0x000040D5, 0x000049A6, 0x000048B4, 0x00050080, 0x00000014, + 0x0000600A, 0x0000287B, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F8B, 0x0000600A, 0x00000189, + 0x000500C4, 0x00000014, 0x00003FB2, 0x00002AC3, 0x0000008D, 0x000500C5, 0x00000014, 0x00005788, + 0x00004F8B, 0x00003FB2, 0x000500AA, 0x00000010, 0x0000360C, 0x00005DF2, 0x00000A12, 0x000600A9, + 0x00000014, 0x0000424E, 0x0000360C, 0x00000A12, 0x00005788, 0x0004007C, 0x00000018, 0x000029DB, + 0x0000424E, 0x000500C2, 0x0000000B, 0x00004BB0, 0x000056C6, 0x00000A64, 0x00040070, 0x0000000D, + 0x0000481A, 0x00004BB0, 0x00050085, 0x0000000D, 0x00003E2B, 0x0000481A, 0x00000149, 0x00050051, + 0x0000000D, 0x000053CE, 0x000029DB, 0x00000000, 0x00050051, 0x0000000D, 0x00002A61, 0x000029DB, + 0x00000001, 0x00050051, 0x0000000D, 0x00001EA2, 0x000029DB, 0x00000002, 0x00070050, 0x0000001D, + 0x00003DE3, 0x000053CE, 0x00002A61, 0x00001EA2, 0x00003E2B, 0x00050051, 0x0000000B, 0x000027FE, + 0x00002AC2, 0x00000001, 0x00060050, 0x00000014, 0x00003517, 0x000027FE, 0x000027FE, 0x000027FE, + 0x000500C2, 0x00000014, 0x00002B1D, 0x00003517, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF3, + 0x00002B1D, 0x00000105, 0x000500C7, 0x00000014, 0x000048B5, 0x00005DF3, 0x00000466, 0x000500C2, + 0x00000014, 0x00005B9D, 0x00005DF3, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D6, 0x00005B9D, + 0x00000A12, 0x0006000C, 0x00000016, 0x00002C58, 0x00000001, 0x0000004B, 0x000048B5, 0x0004007C, + 0x00000014, 0x00002A22, 0x00002C58, 0x00050082, 0x00000014, 0x00001887, 0x00000B0C, 0x00002A22, + 0x00050080, 0x00000014, 0x0000221D, 0x00002A22, 0x00000938, 0x000600A9, 0x00000014, 0x0000287C, + 0x000040D6, 0x0000221D, 0x00005B9D, 0x000500C4, 0x00000014, 0x00005AE2, 0x000048B5, 0x00001887, + 0x000500C7, 0x00000014, 0x000049A7, 0x00005AE2, 0x00000466, 0x000600A9, 0x00000014, 0x00002AC4, + 0x000040D6, 0x000049A7, 0x000048B5, 0x00050080, 0x00000014, 0x0000600B, 0x0000287C, 0x000003FA, + 0x000500C4, 0x00000014, 0x00004F8C, 0x0000600B, 0x00000189, 0x000500C4, 0x00000014, 0x00003FB3, + 0x00002AC4, 0x0000008D, 0x000500C5, 0x00000014, 0x00005789, 0x00004F8C, 0x00003FB3, 0x000500AA, + 0x00000010, 0x0000360D, 0x00005DF3, 0x00000A12, 0x000600A9, 0x00000014, 0x0000424F, 0x0000360D, + 0x00000A12, 0x00005789, 0x0004007C, 0x00000018, 0x000029DC, 0x0000424F, 0x000500C2, 0x0000000B, + 0x00004BB1, 0x000027FE, 0x00000A64, 0x00040070, 0x0000000D, 0x0000481B, 0x00004BB1, 0x00050085, + 0x0000000D, 0x00003E2C, 0x0000481B, 0x00000149, 0x00050051, 0x0000000D, 0x000053CF, 0x000029DC, + 0x00000000, 0x00050051, 0x0000000D, 0x00002A62, 0x000029DC, 0x00000001, 0x00050051, 0x0000000D, + 0x00001EA3, 0x000029DC, 0x00000002, 0x00070050, 0x0000001D, 0x00003DE4, 0x000053CF, 0x00002A62, + 0x00001EA3, 0x00003E2C, 0x00050051, 0x0000000B, 0x000027FF, 0x00002AC2, 0x00000002, 0x00060050, + 0x00000014, 0x00003518, 0x000027FF, 0x000027FF, 0x000027FF, 0x000500C2, 0x00000014, 0x00002B1E, + 0x00003518, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF4, 0x00002B1E, 0x00000105, 0x000500C7, + 0x00000014, 0x000048B6, 0x00005DF4, 0x00000466, 0x000500C2, 0x00000014, 0x00005B9E, 0x00005DF4, + 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D7, 0x00005B9E, 0x00000A12, 0x0006000C, 0x00000016, + 0x00002C59, 0x00000001, 0x0000004B, 0x000048B6, 0x0004007C, 0x00000014, 0x00002A23, 0x00002C59, + 0x00050082, 0x00000014, 0x00001888, 0x00000B0C, 0x00002A23, 0x00050080, 0x00000014, 0x0000221E, + 0x00002A23, 0x00000938, 0x000600A9, 0x00000014, 0x0000287D, 0x000040D7, 0x0000221E, 0x00005B9E, + 0x000500C4, 0x00000014, 0x00005AE3, 0x000048B6, 0x00001888, 0x000500C7, 0x00000014, 0x000049A8, + 0x00005AE3, 0x00000466, 0x000600A9, 0x00000014, 0x00002AC5, 0x000040D7, 0x000049A8, 0x000048B6, + 0x00050080, 0x00000014, 0x0000600C, 0x0000287D, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F8D, + 0x0000600C, 0x00000189, 0x000500C4, 0x00000014, 0x00003FB4, 0x00002AC5, 0x0000008D, 0x000500C5, + 0x00000014, 0x0000578A, 0x00004F8D, 0x00003FB4, 0x000500AA, 0x00000010, 0x0000360E, 0x00005DF4, + 0x00000A12, 0x000600A9, 0x00000014, 0x00004250, 0x0000360E, 0x00000A12, 0x0000578A, 0x0004007C, + 0x00000018, 0x000029DD, 0x00004250, 0x000500C2, 0x0000000B, 0x00004BB2, 0x000027FF, 0x00000A64, + 0x00040070, 0x0000000D, 0x0000481C, 0x00004BB2, 0x00050085, 0x0000000D, 0x00003E2D, 0x0000481C, + 0x00000149, 0x00050051, 0x0000000D, 0x000053D0, 0x000029DD, 0x00000000, 0x00050051, 0x0000000D, + 0x00002A63, 0x000029DD, 0x00000001, 0x00050051, 0x0000000D, 0x00001EA4, 0x000029DD, 0x00000002, + 0x00070050, 0x0000001D, 0x00003DE5, 0x000053D0, 0x00002A63, 0x00001EA4, 0x00003E2D, 0x00050051, + 0x0000000B, 0x00002800, 0x00002AC2, 0x00000003, 0x00060050, 0x00000014, 0x00003519, 0x00002800, + 0x00002800, 0x00002800, 0x000500C2, 0x00000014, 0x00002B1F, 0x00003519, 0x00000BB4, 0x000500C7, + 0x00000014, 0x00005DF5, 0x00002B1F, 0x00000105, 0x000500C7, 0x00000014, 0x000048B7, 0x00005DF5, + 0x00000466, 0x000500C2, 0x00000014, 0x00005B9F, 0x00005DF5, 0x00000B0C, 0x000500AA, 0x00000010, + 0x000040D8, 0x00005B9F, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C5A, 0x00000001, 0x0000004B, + 0x000048B7, 0x0004007C, 0x00000014, 0x00002A24, 0x00002C5A, 0x00050082, 0x00000014, 0x00001889, + 0x00000B0C, 0x00002A24, 0x00050080, 0x00000014, 0x0000221F, 0x00002A24, 0x00000938, 0x000600A9, + 0x00000014, 0x0000287E, 0x000040D8, 0x0000221F, 0x00005B9F, 0x000500C4, 0x00000014, 0x00005AE4, + 0x000048B7, 0x00001889, 0x000500C7, 0x00000014, 0x000049A9, 0x00005AE4, 0x00000466, 0x000600A9, + 0x00000014, 0x00002AC6, 0x000040D8, 0x000049A9, 0x000048B7, 0x00050080, 0x00000014, 0x0000600D, + 0x0000287E, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F8E, 0x0000600D, 0x00000189, 0x000500C4, + 0x00000014, 0x00003FB5, 0x00002AC6, 0x0000008D, 0x000500C5, 0x00000014, 0x0000578B, 0x00004F8E, + 0x00003FB5, 0x000500AA, 0x00000010, 0x0000360F, 0x00005DF5, 0x00000A12, 0x000600A9, 0x00000014, + 0x00004251, 0x0000360F, 0x00000A12, 0x0000578B, 0x0004007C, 0x00000018, 0x000029DE, 0x00004251, + 0x000500C2, 0x0000000B, 0x00004BB3, 0x00002800, 0x00000A64, 0x00040070, 0x0000000D, 0x0000481D, + 0x00004BB3, 0x00050085, 0x0000000D, 0x00003E2E, 0x0000481D, 0x00000149, 0x00050051, 0x0000000D, + 0x000053D1, 0x000029DE, 0x00000000, 0x00050051, 0x0000000D, 0x00002A64, 0x000029DE, 0x00000001, + 0x00050051, 0x0000000D, 0x00002B20, 0x000029DE, 0x00000002, 0x00070050, 0x0000001D, 0x0000235A, + 0x000053D1, 0x00002A64, 0x00002B20, 0x00003E2E, 0x000200F9, 0x00003F63, 0x000200F8, 0x00001CC1, + 0x00050051, 0x0000000B, 0x000056C7, 0x00002AC2, 0x00000000, 0x00070050, 0x00000017, 0x00004F14, + 0x000056C7, 0x000056C7, 0x000056C7, 0x000056C7, 0x000500C2, 0x00000017, 0x000024B0, 0x00004F14, + 0x0000034D, 0x000500C7, 0x00000017, 0x000049B7, 0x000024B0, 0x0000027B, 0x00040070, 0x0000001D, + 0x00003CC0, 0x000049B7, 0x00050085, 0x0000001D, 0x00004139, 0x00003CC0, 0x00000AEE, 0x00050051, + 0x0000000B, 0x00005CDB, 0x00002AC2, 0x00000001, 0x00070050, 0x00000017, 0x00005156, 0x00005CDB, + 0x00005CDB, 0x00005CDB, 0x00005CDB, 0x000500C2, 0x00000017, 0x000024B1, 0x00005156, 0x0000034D, + 0x000500C7, 0x00000017, 0x000049B8, 0x000024B1, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CC1, + 0x000049B8, 0x00050085, 0x0000001D, 0x0000413A, 0x00003CC1, 0x00000AEE, 0x00050051, 0x0000000B, + 0x00005CDC, 0x00002AC2, 0x00000002, 0x00070050, 0x00000017, 0x00005157, 0x00005CDC, 0x00005CDC, + 0x00005CDC, 0x00005CDC, 0x000500C2, 0x00000017, 0x000024B2, 0x00005157, 0x0000034D, 0x000500C7, + 0x00000017, 0x000049B9, 0x000024B2, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CC2, 0x000049B9, + 0x00050085, 0x0000001D, 0x0000413B, 0x00003CC2, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CDD, + 0x00002AC2, 0x00000003, 0x00070050, 0x00000017, 0x0000515C, 0x00005CDD, 0x00005CDD, 0x00005CDD, + 0x00005CDD, 0x000500C2, 0x00000017, 0x000024B3, 0x0000515C, 0x0000034D, 0x000500C7, 0x00000017, + 0x000049BA, 0x000024B3, 0x0000027B, 0x00040070, 0x0000001D, 0x00004932, 0x000049BA, 0x00050085, + 0x0000001D, 0x000026A2, 0x00004932, 0x00000AEE, 0x000200F9, 0x00003F63, 0x000200F8, 0x000038FC, + 0x00050051, 0x0000000B, 0x000056C8, 0x00002AC2, 0x00000000, 0x00070050, 0x00000017, 0x00004F15, + 0x000056C8, 0x000056C8, 0x000056C8, 0x000056C8, 0x000500C2, 0x00000017, 0x000024B4, 0x00004F15, + 0x0000028D, 0x000500C7, 0x00000017, 0x00004A62, 0x000024B4, 0x0000064B, 0x00040070, 0x0000001D, + 0x000036AE, 0x00004A62, 0x0005008E, 0x0000001D, 0x00004B2C, 0x000036AE, 0x0000017A, 0x00050051, + 0x0000000B, 0x000021A8, 0x00002AC2, 0x00000001, 0x00070050, 0x00000017, 0x00006114, 0x000021A8, + 0x000021A8, 0x000021A8, 0x000021A8, 0x000500C2, 0x00000017, 0x000024B5, 0x00006114, 0x0000028D, + 0x000500C7, 0x00000017, 0x00004A63, 0x000024B5, 0x0000064B, 0x00040070, 0x0000001D, 0x000036AF, + 0x00004A63, 0x0005008E, 0x0000001D, 0x00004B2D, 0x000036AF, 0x0000017A, 0x00050051, 0x0000000B, + 0x000021A9, 0x00002AC2, 0x00000002, 0x00070050, 0x00000017, 0x00006115, 0x000021A9, 0x000021A9, + 0x000021A9, 0x000021A9, 0x000500C2, 0x00000017, 0x000024B6, 0x00006115, 0x0000028D, 0x000500C7, + 0x00000017, 0x00004A64, 0x000024B6, 0x0000064B, 0x00040070, 0x0000001D, 0x000036B0, 0x00004A64, + 0x0005008E, 0x0000001D, 0x00004B2E, 0x000036B0, 0x0000017A, 0x00050051, 0x0000000B, 0x000021AA, + 0x00002AC2, 0x00000003, 0x00070050, 0x00000017, 0x00006116, 0x000021AA, 0x000021AA, 0x000021AA, + 0x000021AA, 0x000500C2, 0x00000017, 0x000024B7, 0x00006116, 0x0000028D, 0x000500C7, 0x00000017, + 0x00004A65, 0x000024B7, 0x0000064B, 0x00040070, 0x0000001D, 0x0000431D, 0x00004A65, 0x0005008E, + 0x0000001D, 0x00003095, 0x0000431D, 0x0000017A, 0x000200F9, 0x00003F63, 0x000200F8, 0x00004BFE, + 0x00050051, 0x0000000B, 0x00003096, 0x00002AC2, 0x00000000, 0x0004007C, 0x0000000D, 0x00004FF1, + 0x00003096, 0x00050050, 0x00000013, 0x0000433F, 0x00004FF1, 0x00000A0C, 0x0009004F, 0x0000001D, + 0x00002D99, 0x0000433F, 0x0000433F, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, + 0x0000000B, 0x000056BA, 0x00002AC2, 0x00000001, 0x0004007C, 0x0000000D, 0x00003F71, 0x000056BA, + 0x00050050, 0x00000013, 0x00004340, 0x00003F71, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D9A, + 0x00004340, 0x00004340, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, + 0x000056BB, 0x00002AC2, 0x00000002, 0x0004007C, 0x0000000D, 0x00003F72, 0x000056BB, 0x00050050, + 0x00000013, 0x00004341, 0x00003F72, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D9B, 0x00004341, + 0x00004341, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056BC, + 0x00002AC2, 0x00000003, 0x0004007C, 0x0000000D, 0x00003F73, 0x000056BC, 0x00050050, 0x00000013, + 0x00004FB1, 0x00003F73, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3D, 0x00004FB1, 0x00004FB1, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000200F9, 0x00003F63, 0x000200F8, 0x00003F63, + 0x000F00F5, 0x0000001D, 0x00002BB0, 0x00005A3D, 0x00004BFE, 0x00003095, 0x000038FC, 0x000026A2, + 0x00001CC1, 0x0000235A, 0x00001CC0, 0x00002359, 0x00002001, 0x00002358, 0x00002039, 0x000F00F5, + 0x0000001D, 0x00003811, 0x00002D9B, 0x00004BFE, 0x00004B2E, 0x000038FC, 0x0000413B, 0x00001CC1, + 0x00003DE5, 0x00001CC0, 0x00004129, 0x00002001, 0x00003920, 0x00002039, 0x000F00F5, 0x0000001D, + 0x00003B89, 0x00002D9A, 0x00004BFE, 0x00004B2D, 0x000038FC, 0x0000413A, 0x00001CC1, 0x00003DE4, + 0x00001CC0, 0x00004128, 0x00002001, 0x0000391F, 0x00002039, 0x000F00F5, 0x0000001D, 0x000038BC, + 0x00002D99, 0x00004BFE, 0x00004B2C, 0x000038FC, 0x00004139, 0x00001CC1, 0x00003DE3, 0x00001CC0, + 0x00004127, 0x00002001, 0x0000391E, 0x00002039, 0x000200F9, 0x00005312, 0x000200F8, 0x00003B68, + 0x000500AA, 0x00000009, 0x00005453, 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F29, 0x00000002, + 0x000400FA, 0x00005453, 0x0000262B, 0x00002F68, 0x000200F8, 0x00002F68, 0x00060041, 0x00000288, + 0x00004BD6, 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D51, 0x00004BD6, + 0x00050080, 0x0000000B, 0x00002DD8, 0x00003FF8, 0x00000A0D, 0x00060041, 0x00000288, 0x00001919, + 0x00000CC7, 0x00000A0B, 0x00002DD8, 0x0004003D, 0x0000000B, 0x00005C85, 0x00001919, 0x00050080, + 0x0000000B, 0x00002DD9, 0x00003FF8, 0x0000199B, 0x00060041, 0x00000288, 0x0000191A, 0x00000CC7, + 0x00000A0B, 0x00002DD9, 0x0004003D, 0x0000000B, 0x00005C86, 0x0000191A, 0x00050080, 0x0000000B, + 0x00002DDA, 0x00002DD9, 0x00000A0D, 0x00060041, 0x00000288, 0x0000600E, 0x00000CC7, 0x00000A0B, + 0x00002DDA, 0x0004003D, 0x0000000B, 0x00003750, 0x0000600E, 0x00070050, 0x00000017, 0x00004CDA, + 0x00005D51, 0x00005C85, 0x00005C86, 0x00003750, 0x00050084, 0x0000000B, 0x0000429B, 0x00000A10, + 0x0000199B, 0x00050080, 0x0000000B, 0x000036B1, 0x00003FF8, 0x0000429B, 0x00060041, 0x00000288, + 0x00003B8A, 0x00000CC7, 0x00000A0B, 0x000036B1, 0x0004003D, 0x0000000B, 0x00005C87, 0x00003B8A, + 0x00050080, 0x0000000B, 0x00002DDB, 0x000036B1, 0x00000A0D, 0x00060041, 0x00000288, 0x00001952, + 0x00000CC7, 0x00000A0B, 0x00002DDB, 0x0004003D, 0x0000000B, 0x00005E66, 0x00001952, 0x00050084, + 0x0000000B, 0x00001865, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020AC, 0x00003FF8, + 0x00001865, 0x00060041, 0x00000288, 0x00003B8B, 0x00000CC7, 0x00000A0B, 0x000020AC, 0x0004003D, + 0x0000000B, 0x00005C88, 0x00003B8B, 0x00050080, 0x0000000B, 0x00002DDC, 0x000020AC, 0x00000A0D, + 0x00060041, 0x00000288, 0x0000600F, 0x00000CC7, 0x00000A0B, 0x00002DDC, 0x0004003D, 0x0000000B, + 0x00004009, 0x0000600F, 0x00070050, 0x00000017, 0x0000513A, 0x00005C87, 0x00005E66, 0x00005C88, + 0x00004009, 0x000200F9, 0x00004F29, 0x000200F8, 0x0000262B, 0x00060041, 0x00000288, 0x0000554C, + 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D52, 0x0000554C, 0x00050080, + 0x0000000B, 0x00002DDD, 0x00003FF8, 0x00000A0D, 0x00060041, 0x00000288, 0x0000191B, 0x00000CC7, + 0x00000A0B, 0x00002DDD, 0x0004003D, 0x0000000B, 0x00005C89, 0x0000191B, 0x00050080, 0x0000000B, + 0x00002DDE, 0x00003FF8, 0x00000A10, 0x00060041, 0x00000288, 0x0000191C, 0x00000CC7, 0x00000A0B, + 0x00002DDE, 0x0004003D, 0x0000000B, 0x00005C8A, 0x0000191C, 0x00050080, 0x0000000B, 0x00002DDF, + 0x00003FF8, 0x00000A13, 0x00060041, 0x00000288, 0x00006010, 0x00000CC7, 0x00000A0B, 0x00002DDF, + 0x0004003D, 0x0000000B, 0x00003703, 0x00006010, 0x00070050, 0x00000017, 0x00004AE2, 0x00005D52, + 0x00005C89, 0x00005C8A, 0x00003703, 0x00050080, 0x0000000B, 0x000057E8, 0x00003FF8, 0x00000A16, + 0x00060041, 0x00000288, 0x0000604E, 0x00000CC7, 0x00000A0B, 0x000057E8, 0x0004003D, 0x0000000B, + 0x00005C8B, 0x0000604E, 0x00050080, 0x0000000B, 0x00002DE0, 0x00003FF8, 0x00000A19, 0x00060041, + 0x00000288, 0x0000191D, 0x00000CC7, 0x00000A0B, 0x00002DE0, 0x0004003D, 0x0000000B, 0x00005C8C, + 0x0000191D, 0x00050080, 0x0000000B, 0x00002DE1, 0x00003FF8, 0x00000A1C, 0x00060041, 0x00000288, + 0x0000191E, 0x00000CC7, 0x00000A0B, 0x00002DE1, 0x0004003D, 0x0000000B, 0x00005C8D, 0x0000191E, + 0x00050080, 0x0000000B, 0x00002DE2, 0x00003FF8, 0x00000A1F, 0x00060041, 0x00000288, 0x00006011, + 0x00000CC7, 0x00000A0B, 0x00002DE2, 0x0004003D, 0x0000000B, 0x0000400A, 0x00006011, 0x00070050, + 0x00000017, 0x0000513B, 0x00005C8B, 0x00005C8C, 0x00005C8D, 0x0000400A, 0x000200F9, 0x00004F29, + 0x000200F8, 0x00004F29, 0x000700F5, 0x00000017, 0x00002BD0, 0x0000513B, 0x0000262B, 0x0000513A, + 0x00002F68, 0x000700F5, 0x00000017, 0x00003723, 0x00004AE2, 0x0000262B, 0x00004CDA, 0x00002F68, + 0x000300F7, 0x00004F2A, 0x00000000, 0x000700FB, 0x00002180, 0x00004F59, 0x00000005, 0x0000215B, + 0x00000007, 0x0000203A, 0x000200F8, 0x0000203A, 0x00050051, 0x0000000B, 0x00005F5D, 0x00003723, + 0x00000000, 0x0006000C, 0x00000013, 0x0000606E, 0x00000001, 0x0000003E, 0x00005F5D, 0x00050051, + 0x0000000D, 0x0000278A, 0x0000606E, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC4, 0x0000606E, + 0x00000001, 0x00050051, 0x0000000B, 0x0000428D, 0x00003723, 0x00000001, 0x0006000C, 0x00000013, + 0x00003D01, 0x00000001, 0x0000003E, 0x0000428D, 0x00050051, 0x0000000D, 0x0000278B, 0x00003D01, + 0x00000000, 0x00050051, 0x0000000D, 0x0000445B, 0x00003D01, 0x00000001, 0x00070050, 0x0000001D, + 0x00003921, 0x0000278A, 0x00003EC4, 0x0000278B, 0x0000445B, 0x00050051, 0x0000000B, 0x0000438F, + 0x00003723, 0x00000002, 0x0006000C, 0x00000013, 0x00004680, 0x00000001, 0x0000003E, 0x0000438F, + 0x00050051, 0x0000000D, 0x0000278C, 0x00004680, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC5, + 0x00004680, 0x00000001, 0x00050051, 0x0000000B, 0x0000428E, 0x00003723, 0x00000003, 0x0006000C, + 0x00000013, 0x00003D02, 0x00000001, 0x0000003E, 0x0000428E, 0x00050051, 0x0000000D, 0x0000278D, + 0x00003D02, 0x00000000, 0x00050051, 0x0000000D, 0x0000445C, 0x00003D02, 0x00000001, 0x00070050, + 0x0000001D, 0x00003922, 0x0000278C, 0x00003EC5, 0x0000278D, 0x0000445C, 0x00050051, 0x0000000B, + 0x00004390, 0x00002BD0, 0x00000000, 0x0006000C, 0x00000013, 0x00004681, 0x00000001, 0x0000003E, + 0x00004390, 0x00050051, 0x0000000D, 0x0000278E, 0x00004681, 0x00000000, 0x00050051, 0x0000000D, + 0x00003EC6, 0x00004681, 0x00000001, 0x00050051, 0x0000000B, 0x0000428F, 0x00002BD0, 0x00000001, + 0x0006000C, 0x00000013, 0x00003D03, 0x00000001, 0x0000003E, 0x0000428F, 0x00050051, 0x0000000D, + 0x0000278F, 0x00003D03, 0x00000000, 0x00050051, 0x0000000D, 0x0000445D, 0x00003D03, 0x00000001, + 0x00070050, 0x0000001D, 0x00003923, 0x0000278E, 0x00003EC6, 0x0000278F, 0x0000445D, 0x00050051, + 0x0000000B, 0x00004391, 0x00002BD0, 0x00000002, 0x0006000C, 0x00000013, 0x00004682, 0x00000001, + 0x0000003E, 0x00004391, 0x00050051, 0x0000000D, 0x00002790, 0x00004682, 0x00000000, 0x00050051, + 0x0000000D, 0x00003EC7, 0x00004682, 0x00000001, 0x00050051, 0x0000000B, 0x00004290, 0x00002BD0, + 0x00000003, 0x0006000C, 0x00000013, 0x00003D04, 0x00000001, 0x0000003E, 0x00004290, 0x00050051, + 0x0000000D, 0x00002791, 0x00003D04, 0x00000000, 0x00050051, 0x0000000D, 0x000050C5, 0x00003D04, + 0x00000001, 0x00070050, 0x0000001D, 0x0000235B, 0x00002790, 0x00003EC7, 0x00002791, 0x000050C5, + 0x000200F9, 0x00004F2A, 0x000200F8, 0x0000215B, 0x0007004F, 0x00000011, 0x000025FE, 0x00003723, + 0x00003723, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x00005B3F, 0x000025FE, 0x0009004F, + 0x0000001A, 0x000060DA, 0x00005B3F, 0x00005B3F, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C4, 0x0000001A, 0x000048B8, 0x000060DA, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D99, + 0x000048B8, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AC7, 0x00003D99, 0x0005008E, 0x0000001D, + 0x00004733, 0x00002AC7, 0x000007FE, 0x0007000C, 0x0000001D, 0x0000629A, 0x00000001, 0x00000028, + 0x00000504, 0x00004733, 0x0007004F, 0x00000011, 0x00003774, 0x00003723, 0x00003723, 0x00000002, + 0x00000003, 0x0004007C, 0x00000012, 0x000024C8, 0x00003774, 0x0009004F, 0x0000001A, 0x000060DB, + 0x000024C8, 0x000024C8, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, + 0x000048B9, 0x000060DB, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D9A, 0x000048B9, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002AC8, 0x00003D9A, 0x0005008E, 0x0000001D, 0x00004734, 0x00002AC8, + 0x000007FE, 0x0007000C, 0x0000001D, 0x0000629B, 0x00000001, 0x00000028, 0x00000504, 0x00004734, + 0x0007004F, 0x00000011, 0x00003775, 0x00002BD0, 0x00002BD0, 0x00000000, 0x00000001, 0x0004007C, + 0x00000012, 0x000024C9, 0x00003775, 0x0009004F, 0x0000001A, 0x000060DC, 0x000024C9, 0x000024C9, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048BA, 0x000060DC, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D9B, 0x000048BA, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002AC9, 0x00003D9B, 0x0005008E, 0x0000001D, 0x00004735, 0x00002AC9, 0x000007FE, 0x0007000C, + 0x0000001D, 0x0000629C, 0x00000001, 0x00000028, 0x00000504, 0x00004735, 0x0007004F, 0x00000011, + 0x00003776, 0x00002BD0, 0x00002BD0, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024CA, + 0x00003776, 0x0009004F, 0x0000001A, 0x000060DD, 0x000024CA, 0x000024CA, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048BB, 0x000060DD, 0x00000122, 0x000500C3, + 0x0000001A, 0x00003D9C, 0x000048BB, 0x00000302, 0x0004006F, 0x0000001D, 0x00002ACA, 0x00003D9C, + 0x0005008E, 0x0000001D, 0x000053D2, 0x00002ACA, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004365, + 0x00000001, 0x00000028, 0x00000504, 0x000053D2, 0x000200F9, 0x00004F2A, 0x000200F8, 0x00004F59, + 0x0007004F, 0x00000011, 0x0000262C, 0x00003723, 0x00003723, 0x00000000, 0x00000001, 0x0004007C, + 0x00000013, 0x0000515D, 0x0000262C, 0x00050051, 0x0000000D, 0x00001B87, 0x0000515D, 0x00000000, + 0x00050051, 0x0000000D, 0x00003473, 0x0000515D, 0x00000001, 0x00070050, 0x0000001D, 0x00004291, + 0x00001B87, 0x00003473, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041E1, 0x00003723, + 0x00003723, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x00003766, 0x000041E1, 0x00050051, + 0x0000000D, 0x00001B88, 0x00003766, 0x00000000, 0x00050051, 0x0000000D, 0x00003474, 0x00003766, + 0x00000001, 0x00070050, 0x0000001D, 0x00004292, 0x00001B88, 0x00003474, 0x00000A0C, 0x00000A0C, + 0x0007004F, 0x00000011, 0x000041E2, 0x00002BD0, 0x00002BD0, 0x00000000, 0x00000001, 0x0004007C, + 0x00000013, 0x00003767, 0x000041E2, 0x00050051, 0x0000000D, 0x00001B89, 0x00003767, 0x00000000, + 0x00050051, 0x0000000D, 0x00003475, 0x00003767, 0x00000001, 0x00070050, 0x0000001D, 0x00004293, + 0x00001B89, 0x00003475, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041E3, 0x00002BD0, + 0x00002BD0, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x00003768, 0x000041E3, 0x00050051, + 0x0000000D, 0x00001B8A, 0x00003768, 0x00000000, 0x00050051, 0x0000000D, 0x0000410B, 0x00003768, + 0x00000001, 0x00070050, 0x0000001D, 0x0000235C, 0x00001B8A, 0x0000410B, 0x00000A0C, 0x00000A0C, + 0x000200F9, 0x00004F2A, 0x000200F8, 0x00004F2A, 0x000900F5, 0x0000001D, 0x00002BB1, 0x0000235C, + 0x00004F59, 0x00004365, 0x0000215B, 0x0000235B, 0x0000203A, 0x000900F5, 0x0000001D, 0x00003812, + 0x00004293, 0x00004F59, 0x0000629C, 0x0000215B, 0x00003923, 0x0000203A, 0x000900F5, 0x0000001D, + 0x00003B8C, 0x00004292, 0x00004F59, 0x0000629B, 0x0000215B, 0x00003922, 0x0000203A, 0x000900F5, + 0x0000001D, 0x000038BD, 0x00004291, 0x00004F59, 0x0000629A, 0x0000215B, 0x00003921, 0x0000203A, + 0x000200F9, 0x00005312, 0x000200F8, 0x00005312, 0x000700F5, 0x0000001D, 0x00002BB2, 0x00002BB1, + 0x00004F2A, 0x00002BB0, 0x00003F63, 0x000700F5, 0x0000001D, 0x00003813, 0x00003812, 0x00004F2A, + 0x00003811, 0x00003F63, 0x000700F5, 0x0000001D, 0x00003297, 0x00003B8C, 0x00004F2A, 0x00003B89, + 0x00003F63, 0x000700F5, 0x0000001D, 0x0000367C, 0x000038BD, 0x00004F2A, 0x000038BC, 0x00003F63, + 0x00050081, 0x0000001D, 0x0000435B, 0x0000435A, 0x0000367C, 0x00050081, 0x0000001D, 0x00005B03, + 0x00005B02, 0x00003297, 0x00050081, 0x0000001D, 0x00002523, 0x00001C28, 0x00003813, 0x00050081, + 0x0000001D, 0x00001E77, 0x000025AA, 0x00002BB2, 0x000200F9, 0x00005EC8, 0x000200F8, 0x00005EC8, + 0x000700F5, 0x0000001D, 0x00002BB3, 0x00005113, 0x00005310, 0x00001E77, 0x00005312, 0x000700F5, + 0x0000001D, 0x00003814, 0x00001F92, 0x00005310, 0x00002523, 0x00005312, 0x000700F5, 0x0000001D, + 0x00003B31, 0x00005B01, 0x00005310, 0x00005B03, 0x00005312, 0x000700F5, 0x0000001D, 0x00003B8D, + 0x00004359, 0x00005310, 0x0000435B, 0x00005312, 0x000700F5, 0x0000000D, 0x000038BE, 0x000061FB, + 0x00005310, 0x00002F3A, 0x00005312, 0x000200F9, 0x00005313, 0x000200F8, 0x00005313, 0x000700F5, + 0x0000001D, 0x00002BB4, 0x00002BA9, 0x0000530F, 0x00002BB3, 0x00005EC8, 0x000700F5, 0x0000001D, + 0x00003815, 0x0000380A, 0x0000530F, 0x00003814, 0x00005EC8, 0x000700F5, 0x0000001D, 0x00003B32, + 0x000035EC, 0x0000530F, 0x00003B31, 0x00005EC8, 0x000700F5, 0x0000001D, 0x0000338C, 0x000020D3, + 0x0000530F, 0x00003B8D, 0x00005EC8, 0x000700F5, 0x0000000D, 0x00002EA8, 0x00002B2C, 0x0000530F, + 0x000038BE, 0x00005EC8, 0x0005008E, 0x0000001D, 0x00005A74, 0x0000338C, 0x00002EA8, 0x0005008E, + 0x0000001D, 0x000019CC, 0x00003B32, 0x00002EA8, 0x0005008E, 0x0000001D, 0x0000306F, 0x00003815, + 0x00002EA8, 0x0005008E, 0x0000001D, 0x00003432, 0x00002BB4, 0x00002EA8, 0x000300F7, 0x00003F64, + 0x00000002, 0x000400FA, 0x00001D59, 0x00002741, 0x00003F64, 0x000200F8, 0x00002741, 0x0009004F, + 0x0000001D, 0x00003AEE, 0x00005A74, 0x00005A74, 0x00000002, 0x00000001, 0x00000000, 0x00000003, + 0x0009004F, 0x0000001D, 0x00003A07, 0x000019CC, 0x000019CC, 0x00000002, 0x00000001, 0x00000000, + 0x00000003, 0x0009004F, 0x0000001D, 0x00001CE6, 0x0000306F, 0x0000306F, 0x00000002, 0x00000001, + 0x00000000, 0x00000003, 0x0009004F, 0x0000001D, 0x00003EEF, 0x00003432, 0x00003432, 0x00000002, + 0x00000001, 0x00000000, 0x00000003, 0x000200F9, 0x00003F64, 0x000200F8, 0x00003F64, 0x000700F5, + 0x0000001D, 0x00002BB5, 0x00003432, 0x00005313, 0x00003EEF, 0x00002741, 0x000700F5, 0x0000001D, + 0x00003816, 0x0000306F, 0x00005313, 0x00001CE6, 0x00002741, 0x000700F5, 0x0000001D, 0x00003B57, + 0x000019CC, 0x00005313, 0x00003A07, 0x00002741, 0x000700F5, 0x0000001D, 0x00003A49, 0x00005A74, + 0x00005313, 0x00003AEE, 0x00002741, 0x000300F7, 0x00004992, 0x00000000, 0x001900FB, 0x00005093, + 0x00002002, 0x00000006, 0x00004696, 0x0000000E, 0x00004696, 0x00000032, 0x00004696, 0x00000007, + 0x000045EB, 0x00000036, 0x000045EB, 0x00000010, 0x00001935, 0x00000037, 0x00001935, 0x00000011, + 0x00001934, 0x00000038, 0x00001934, 0x00000019, 0x00001933, 0x0000001F, 0x00002514, 0x000200F8, + 0x00002514, 0x00050051, 0x0000000D, 0x00003AAE, 0x00003A49, 0x00000000, 0x00050051, 0x0000000D, + 0x000023ED, 0x00003A49, 0x00000001, 0x00050050, 0x00000013, 0x00004B20, 0x00003AAE, 0x000023ED, + 0x0006000C, 0x0000000B, 0x00002171, 0x00000001, 0x0000003A, 0x00004B20, 0x00050051, 0x0000000D, + 0x00005BBF, 0x00003B57, 0x00000000, 0x00050051, 0x0000000D, 0x000039A7, 0x00003B57, 0x00000001, + 0x00050050, 0x00000013, 0x00004B21, 0x00005BBF, 0x000039A7, 0x0006000C, 0x0000000B, 0x00002172, + 0x00000001, 0x0000003A, 0x00004B21, 0x00050051, 0x0000000D, 0x00005BC0, 0x00003816, 0x00000000, + 0x00050051, 0x0000000D, 0x000039A8, 0x00003816, 0x00000001, 0x00050050, 0x00000013, 0x00004B22, + 0x00005BC0, 0x000039A8, 0x0006000C, 0x0000000B, 0x00002173, 0x00000001, 0x0000003A, 0x00004B22, + 0x00050051, 0x0000000D, 0x00005BC1, 0x00002BB5, 0x00000000, 0x00050051, 0x0000000D, 0x000039A9, + 0x00002BB5, 0x00000001, 0x00050050, 0x00000013, 0x00004B0D, 0x00005BC1, 0x000039A9, 0x0006000C, + 0x0000000B, 0x00002E96, 0x00000001, 0x0000003A, 0x00004B0D, 0x00070050, 0x00000017, 0x0000612F, + 0x00002171, 0x00002172, 0x00002173, 0x00002E96, 0x000200F9, 0x00004992, 0x000200F8, 0x00001933, + 0x0007004F, 0x00000013, 0x0000227A, 0x00003A49, 0x00003A49, 0x00000000, 0x00000001, 0x0008000C, + 0x00000013, 0x00005CB1, 0x00000001, 0x0000002B, 0x0000227A, 0x0000071F, 0x00000300, 0x0005008E, + 0x00000013, 0x000025B4, 0x00005CB1, 0x0000022D, 0x00050081, 0x00000013, 0x00002E66, 0x000025B4, + 0x0000061E, 0x0004006D, 0x00000011, 0x00001DD7, 0x00002E66, 0x00050051, 0x0000000B, 0x000021FC, + 0x00001DD7, 0x00000000, 0x00050051, 0x0000000B, 0x00002FDB, 0x00001DD7, 0x00000001, 0x000500C4, + 0x0000000B, 0x00002D03, 0x00002FDB, 0x00000A3B, 0x000500C5, 0x0000000B, 0x00004143, 0x000021FC, + 0x00002D03, 0x0007004F, 0x00000013, 0x0000235D, 0x00003B57, 0x00003B57, 0x00000000, 0x00000001, + 0x0008000C, 0x00000013, 0x000046BF, 0x00000001, 0x0000002B, 0x0000235D, 0x0000071F, 0x00000300, + 0x0005008E, 0x00000013, 0x000025B5, 0x000046BF, 0x0000022D, 0x00050081, 0x00000013, 0x00002E67, + 0x000025B5, 0x0000061E, 0x0004006D, 0x00000011, 0x00001DD9, 0x00002E67, 0x00050051, 0x0000000B, + 0x000021FD, 0x00001DD9, 0x00000000, 0x00050051, 0x0000000B, 0x00002FDC, 0x00001DD9, 0x00000001, + 0x000500C4, 0x0000000B, 0x00002D04, 0x00002FDC, 0x00000A3B, 0x000500C5, 0x0000000B, 0x00004144, + 0x000021FD, 0x00002D04, 0x0007004F, 0x00000013, 0x0000235E, 0x00003816, 0x00003816, 0x00000000, + 0x00000001, 0x0008000C, 0x00000013, 0x000046C0, 0x00000001, 0x0000002B, 0x0000235E, 0x0000071F, + 0x00000300, 0x0005008E, 0x00000013, 0x000025B6, 0x000046C0, 0x0000022D, 0x00050081, 0x00000013, + 0x00002E69, 0x000025B6, 0x0000061E, 0x0004006D, 0x00000011, 0x00001DDA, 0x00002E69, 0x00050051, + 0x0000000B, 0x000021FE, 0x00001DDA, 0x00000000, 0x00050051, 0x0000000B, 0x00002FDD, 0x00001DDA, + 0x00000001, 0x000500C4, 0x0000000B, 0x00002D05, 0x00002FDD, 0x00000A3B, 0x000500C5, 0x0000000B, + 0x00004145, 0x000021FE, 0x00002D05, 0x0007004F, 0x00000013, 0x0000235F, 0x00002BB5, 0x00002BB5, + 0x00000000, 0x00000001, 0x0008000C, 0x00000013, 0x000046C1, 0x00000001, 0x0000002B, 0x0000235F, + 0x0000071F, 0x00000300, 0x0005008E, 0x00000013, 0x000025B7, 0x000046C1, 0x0000022D, 0x00050081, + 0x00000013, 0x00002E6A, 0x000025B7, 0x0000061E, 0x0004006D, 0x00000011, 0x00001DDB, 0x00002E6A, + 0x00050051, 0x0000000B, 0x000021FF, 0x00001DDB, 0x00000000, 0x00050051, 0x0000000B, 0x00002FDE, + 0x00001DDB, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D16, 0x00002FDE, 0x00000A3B, 0x000500C5, + 0x0000000B, 0x00005202, 0x000021FF, 0x00002D16, 0x00070050, 0x00000017, 0x000053DD, 0x00004143, + 0x00004144, 0x00004145, 0x00005202, 0x000200F9, 0x00004992, 0x000200F8, 0x00001934, 0x0008004F, + 0x00000018, 0x000021CF, 0x00003A49, 0x00003A49, 0x00000000, 0x00000001, 0x00000002, 0x0008000C, + 0x00000018, 0x00001847, 0x00000001, 0x0000002B, 0x000021CF, 0x00000A2D, 0x00000A18, 0x00050085, + 0x00000018, 0x00001BC1, 0x00001847, 0x0000000E, 0x00050081, 0x00000018, 0x00001F1A, 0x00001BC1, + 0x000003AB, 0x0004006D, 0x00000014, 0x00002752, 0x00001F1A, 0x00050051, 0x0000000B, 0x00002200, + 0x00002752, 0x00000000, 0x00050051, 0x0000000B, 0x00002FDF, 0x00002752, 0x00000001, 0x000500C4, + 0x0000000B, 0x00002D29, 0x00002FDF, 0x00000A29, 0x000500C5, 0x0000000B, 0x00004D66, 0x00002200, + 0x00002D29, 0x00050051, 0x0000000B, 0x000053E4, 0x00002752, 0x00000002, 0x000500C4, 0x0000000B, + 0x0000214A, 0x000053E4, 0x00000A4A, 0x000500C5, 0x0000000B, 0x00004146, 0x00004D66, 0x0000214A, + 0x0008004F, 0x00000018, 0x000022A2, 0x00003B57, 0x00003B57, 0x00000000, 0x00000001, 0x00000002, + 0x0008000C, 0x00000018, 0x00004CD4, 0x00000001, 0x0000002B, 0x000022A2, 0x00000A2D, 0x00000A18, + 0x00050085, 0x00000018, 0x00001BC2, 0x00004CD4, 0x0000000E, 0x00050081, 0x00000018, 0x00001F1B, + 0x00001BC2, 0x000003AB, 0x0004006D, 0x00000014, 0x00002753, 0x00001F1B, 0x00050051, 0x0000000B, + 0x00002201, 0x00002753, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE0, 0x00002753, 0x00000001, + 0x000500C4, 0x0000000B, 0x00002D2A, 0x00002FE0, 0x00000A29, 0x000500C5, 0x0000000B, 0x00004D67, + 0x00002201, 0x00002D2A, 0x00050051, 0x0000000B, 0x000053E5, 0x00002753, 0x00000002, 0x000500C4, + 0x0000000B, 0x0000214B, 0x000053E5, 0x00000A4A, 0x000500C5, 0x0000000B, 0x00004147, 0x00004D67, + 0x0000214B, 0x0008004F, 0x00000018, 0x000022A3, 0x00003816, 0x00003816, 0x00000000, 0x00000001, + 0x00000002, 0x0008000C, 0x00000018, 0x00004CD5, 0x00000001, 0x0000002B, 0x000022A3, 0x00000A2D, + 0x00000A18, 0x00050085, 0x00000018, 0x00001BC3, 0x00004CD5, 0x0000000E, 0x00050081, 0x00000018, + 0x00001F1C, 0x00001BC3, 0x000003AB, 0x0004006D, 0x00000014, 0x00002754, 0x00001F1C, 0x00050051, + 0x0000000B, 0x00002202, 0x00002754, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE1, 0x00002754, + 0x00000001, 0x000500C4, 0x0000000B, 0x00002D2B, 0x00002FE1, 0x00000A29, 0x000500C5, 0x0000000B, + 0x00004D68, 0x00002202, 0x00002D2B, 0x00050051, 0x0000000B, 0x000053E6, 0x00002754, 0x00000002, + 0x000500C4, 0x0000000B, 0x0000214C, 0x000053E6, 0x00000A4A, 0x000500C5, 0x0000000B, 0x00004148, + 0x00004D68, 0x0000214C, 0x0008004F, 0x00000018, 0x000022A4, 0x00002BB5, 0x00002BB5, 0x00000000, + 0x00000001, 0x00000002, 0x0008000C, 0x00000018, 0x00004CDB, 0x00000001, 0x0000002B, 0x000022A4, + 0x00000A2D, 0x00000A18, 0x00050085, 0x00000018, 0x00001BC4, 0x00004CDB, 0x0000000E, 0x00050081, + 0x00000018, 0x00001F1D, 0x00001BC4, 0x000003AB, 0x0004006D, 0x00000014, 0x00002755, 0x00001F1D, + 0x00050051, 0x0000000B, 0x00002203, 0x00002755, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE2, + 0x00002755, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D2C, 0x00002FE2, 0x00000A29, 0x000500C5, + 0x0000000B, 0x00004D69, 0x00002203, 0x00002D2C, 0x00050051, 0x0000000B, 0x000053E7, 0x00002755, + 0x00000002, 0x000500C4, 0x0000000B, 0x0000215D, 0x000053E7, 0x00000A4A, 0x000500C5, 0x0000000B, + 0x00005203, 0x00004D69, 0x0000215D, 0x00070050, 0x00000017, 0x000053DE, 0x00004146, 0x00004147, + 0x00004148, 0x00005203, 0x000200F9, 0x00004992, 0x000200F8, 0x00001935, 0x0008004F, 0x00000018, + 0x000021D0, 0x00003A49, 0x00003A49, 0x00000000, 0x00000001, 0x00000002, 0x0008000C, 0x00000018, + 0x00001848, 0x00000001, 0x0000002B, 0x000021D0, 0x00000A2D, 0x00000A18, 0x00050085, 0x00000018, + 0x00001BC5, 0x00001848, 0x000008E3, 0x00050081, 0x00000018, 0x00001F1E, 0x00001BC5, 0x000003AB, + 0x0004006D, 0x00000014, 0x00002756, 0x00001F1E, 0x00050051, 0x0000000B, 0x00002204, 0x00002756, + 0x00000000, 0x00050051, 0x0000000B, 0x00002FE3, 0x00002756, 0x00000001, 0x000500C4, 0x0000000B, + 0x00002D2D, 0x00002FE3, 0x00000A2C, 0x000500C5, 0x0000000B, 0x00004D6A, 0x00002204, 0x00002D2D, + 0x00050051, 0x0000000B, 0x000053E8, 0x00002756, 0x00000002, 0x000500C4, 0x0000000B, 0x0000214D, + 0x000053E8, 0x00000A4D, 0x000500C5, 0x0000000B, 0x00004149, 0x00004D6A, 0x0000214D, 0x0008004F, + 0x00000018, 0x000022A5, 0x00003B57, 0x00003B57, 0x00000000, 0x00000001, 0x00000002, 0x0008000C, + 0x00000018, 0x00004CDC, 0x00000001, 0x0000002B, 0x000022A5, 0x00000A2D, 0x00000A18, 0x00050085, + 0x00000018, 0x00001BC6, 0x00004CDC, 0x000008E3, 0x00050081, 0x00000018, 0x00001F1F, 0x00001BC6, + 0x000003AB, 0x0004006D, 0x00000014, 0x00002757, 0x00001F1F, 0x00050051, 0x0000000B, 0x00002205, + 0x00002757, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE4, 0x00002757, 0x00000001, 0x000500C4, + 0x0000000B, 0x00002D2E, 0x00002FE4, 0x00000A2C, 0x000500C5, 0x0000000B, 0x00004D6B, 0x00002205, + 0x00002D2E, 0x00050051, 0x0000000B, 0x000053E9, 0x00002757, 0x00000002, 0x000500C4, 0x0000000B, + 0x0000214E, 0x000053E9, 0x00000A4D, 0x000500C5, 0x0000000B, 0x0000414A, 0x00004D6B, 0x0000214E, + 0x0008004F, 0x00000018, 0x000022A6, 0x00003816, 0x00003816, 0x00000000, 0x00000001, 0x00000002, + 0x0008000C, 0x00000018, 0x00004CDD, 0x00000001, 0x0000002B, 0x000022A6, 0x00000A2D, 0x00000A18, + 0x00050085, 0x00000018, 0x00001BC7, 0x00004CDD, 0x000008E3, 0x00050081, 0x00000018, 0x00001F20, + 0x00001BC7, 0x000003AB, 0x0004006D, 0x00000014, 0x00002758, 0x00001F20, 0x00050051, 0x0000000B, + 0x00002206, 0x00002758, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE5, 0x00002758, 0x00000001, + 0x000500C4, 0x0000000B, 0x00002D2F, 0x00002FE5, 0x00000A2C, 0x000500C5, 0x0000000B, 0x00004D6C, + 0x00002206, 0x00002D2F, 0x00050051, 0x0000000B, 0x000053EA, 0x00002758, 0x00000002, 0x000500C4, + 0x0000000B, 0x0000214F, 0x000053EA, 0x00000A4D, 0x000500C5, 0x0000000B, 0x0000414B, 0x00004D6C, + 0x0000214F, 0x0008004F, 0x00000018, 0x000022A8, 0x00002BB5, 0x00002BB5, 0x00000000, 0x00000001, + 0x00000002, 0x0008000C, 0x00000018, 0x00004CDE, 0x00000001, 0x0000002B, 0x000022A8, 0x00000A2D, + 0x00000A18, 0x00050085, 0x00000018, 0x00001BC8, 0x00004CDE, 0x000008E3, 0x00050081, 0x00000018, + 0x00001F21, 0x00001BC8, 0x000003AB, 0x0004006D, 0x00000014, 0x00002759, 0x00001F21, 0x00050051, + 0x0000000B, 0x00002207, 0x00002759, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE6, 0x00002759, + 0x00000001, 0x000500C4, 0x0000000B, 0x00002D30, 0x00002FE6, 0x00000A2C, 0x000500C5, 0x0000000B, + 0x00004D6D, 0x00002207, 0x00002D30, 0x00050051, 0x0000000B, 0x000053EB, 0x00002759, 0x00000002, + 0x000500C4, 0x0000000B, 0x0000215E, 0x000053EB, 0x00000A4D, 0x000500C5, 0x0000000B, 0x00005204, + 0x00004D6D, 0x0000215E, 0x00070050, 0x00000017, 0x000053DF, 0x00004149, 0x0000414A, 0x0000414B, + 0x00005204, 0x000200F9, 0x00004992, 0x000200F8, 0x000045EB, 0x0008000C, 0x0000001D, 0x000022A9, + 0x00000001, 0x0000002B, 0x00003A49, 0x00000B7A, 0x00000505, 0x00050085, 0x0000001D, 0x00004580, + 0x000022A9, 0x00000158, 0x00050081, 0x0000001D, 0x00001F22, 0x00004580, 0x00000145, 0x0004006D, + 0x00000017, 0x0000275A, 0x00001F22, 0x00050051, 0x0000000B, 0x00002208, 0x0000275A, 0x00000000, + 0x00050051, 0x0000000B, 0x00002FE7, 0x0000275A, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D31, + 0x00002FE7, 0x00000A29, 0x000500C5, 0x0000000B, 0x00004D6E, 0x00002208, 0x00002D31, 0x00050051, + 0x0000000B, 0x000053EC, 0x0000275A, 0x00000002, 0x000500C4, 0x0000000B, 0x00002170, 0x000053EC, + 0x00000A47, 0x000500C5, 0x0000000B, 0x00004D6F, 0x00004D6E, 0x00002170, 0x00050051, 0x0000000B, + 0x000053ED, 0x0000275A, 0x00000003, 0x000500C4, 0x0000000B, 0x00001C7C, 0x000053ED, 0x00000A65, + 0x000500C5, 0x0000000B, 0x0000237C, 0x00004D6F, 0x00001C7C, 0x0008000C, 0x0000001D, 0x00002377, + 0x00000001, 0x0000002B, 0x00003B57, 0x00000B7A, 0x00000505, 0x00050085, 0x0000001D, 0x000060DE, + 0x00002377, 0x00000158, 0x00050081, 0x0000001D, 0x00001F23, 0x000060DE, 0x00000145, 0x0004006D, + 0x00000017, 0x0000275B, 0x00001F23, 0x00050051, 0x0000000B, 0x00002209, 0x0000275B, 0x00000000, + 0x00050051, 0x0000000B, 0x00002FE8, 0x0000275B, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D32, + 0x00002FE8, 0x00000A29, 0x000500C5, 0x0000000B, 0x00004D70, 0x00002209, 0x00002D32, 0x00050051, + 0x0000000B, 0x000053EE, 0x0000275B, 0x00000002, 0x000500C4, 0x0000000B, 0x00002174, 0x000053EE, + 0x00000A47, 0x000500C5, 0x0000000B, 0x00004D71, 0x00004D70, 0x00002174, 0x00050051, 0x0000000B, + 0x000053EF, 0x0000275B, 0x00000003, 0x000500C4, 0x0000000B, 0x00001C7D, 0x000053EF, 0x00000A65, + 0x000500C5, 0x0000000B, 0x0000237D, 0x00004D71, 0x00001C7D, 0x0008000C, 0x0000001D, 0x00002378, + 0x00000001, 0x0000002B, 0x00003816, 0x00000B7A, 0x00000505, 0x00050085, 0x0000001D, 0x000060DF, + 0x00002378, 0x00000158, 0x00050081, 0x0000001D, 0x00001F24, 0x000060DF, 0x00000145, 0x0004006D, + 0x00000017, 0x0000275C, 0x00001F24, 0x00050051, 0x0000000B, 0x0000220A, 0x0000275C, 0x00000000, + 0x00050051, 0x0000000B, 0x00002FE9, 0x0000275C, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D33, + 0x00002FE9, 0x00000A29, 0x000500C5, 0x0000000B, 0x00004D72, 0x0000220A, 0x00002D33, 0x00050051, + 0x0000000B, 0x000053F0, 0x0000275C, 0x00000002, 0x000500C4, 0x0000000B, 0x00002175, 0x000053F0, + 0x00000A47, 0x000500C5, 0x0000000B, 0x00004D73, 0x00004D72, 0x00002175, 0x00050051, 0x0000000B, + 0x000053F1, 0x0000275C, 0x00000003, 0x000500C4, 0x0000000B, 0x00001C7E, 0x000053F1, 0x00000A65, + 0x000500C5, 0x0000000B, 0x0000237E, 0x00004D73, 0x00001C7E, 0x0008000C, 0x0000001D, 0x00002379, + 0x00000001, 0x0000002B, 0x00002BB5, 0x00000B7A, 0x00000505, 0x00050085, 0x0000001D, 0x000060E0, + 0x00002379, 0x00000158, 0x00050081, 0x0000001D, 0x00001F25, 0x000060E0, 0x00000145, 0x0004006D, + 0x00000017, 0x0000275D, 0x00001F25, 0x00050051, 0x0000000B, 0x0000220B, 0x0000275D, 0x00000000, + 0x00050051, 0x0000000B, 0x00002FEA, 0x0000275D, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D34, + 0x00002FEA, 0x00000A29, 0x000500C5, 0x0000000B, 0x00004D74, 0x0000220B, 0x00002D34, 0x00050051, + 0x0000000B, 0x000053F2, 0x0000275D, 0x00000002, 0x000500C4, 0x0000000B, 0x00002176, 0x000053F2, + 0x00000A47, 0x000500C5, 0x0000000B, 0x00004D75, 0x00004D74, 0x00002176, 0x00050051, 0x0000000B, + 0x000053F3, 0x0000275D, 0x00000003, 0x000500C4, 0x0000000B, 0x0000215F, 0x000053F3, 0x00000A65, + 0x000500C5, 0x0000000B, 0x00005205, 0x00004D75, 0x0000215F, 0x00070050, 0x00000017, 0x000053E0, + 0x0000237C, 0x0000237D, 0x0000237E, 0x00005205, 0x000200F9, 0x00004992, 0x000200F8, 0x00004696, + 0x0008000C, 0x0000001D, 0x00001C8F, 0x00000001, 0x0000002B, 0x00003A49, 0x00000B7A, 0x00000505, + 0x0005008E, 0x0000001D, 0x00004F73, 0x00001C8F, 0x00000540, 0x00050081, 0x0000001D, 0x00002E6B, + 0x00004F73, 0x00000145, 0x0004006D, 0x00000017, 0x00001DDC, 0x00002E6B, 0x00050051, 0x0000000B, + 0x0000220C, 0x00001DDC, 0x00000000, 0x00050051, 0x0000000B, 0x00002FEB, 0x00001DDC, 0x00000001, + 0x000500C4, 0x0000000B, 0x00002D35, 0x00002FEB, 0x00000A23, 0x000500C5, 0x0000000B, 0x00004D76, + 0x0000220C, 0x00002D35, 0x00050051, 0x0000000B, 0x000053F4, 0x00001DDC, 0x00000002, 0x000500C4, + 0x0000000B, 0x00002177, 0x000053F4, 0x00000A3B, 0x000500C5, 0x0000000B, 0x00004D77, 0x00004D76, + 0x00002177, 0x00050051, 0x0000000B, 0x000053F5, 0x00001DDC, 0x00000003, 0x000500C4, 0x0000000B, + 0x00001C7F, 0x000053F5, 0x00000A53, 0x000500C5, 0x0000000B, 0x00002427, 0x00004D77, 0x00001C7F, + 0x0008000C, 0x0000001D, 0x00001D62, 0x00000001, 0x0000002B, 0x00003B57, 0x00000B7A, 0x00000505, + 0x0005008E, 0x0000001D, 0x00002048, 0x00001D62, 0x00000540, 0x00050081, 0x0000001D, 0x00002E6C, + 0x00002048, 0x00000145, 0x0004006D, 0x00000017, 0x00001DDD, 0x00002E6C, 0x00050051, 0x0000000B, + 0x0000220D, 0x00001DDD, 0x00000000, 0x00050051, 0x0000000B, 0x00002FEC, 0x00001DDD, 0x00000001, + 0x000500C4, 0x0000000B, 0x00002D36, 0x00002FEC, 0x00000A23, 0x000500C5, 0x0000000B, 0x00004D78, + 0x0000220D, 0x00002D36, 0x00050051, 0x0000000B, 0x000053F6, 0x00001DDD, 0x00000002, 0x000500C4, + 0x0000000B, 0x00002178, 0x000053F6, 0x00000A3B, 0x000500C5, 0x0000000B, 0x00004D79, 0x00004D78, + 0x00002178, 0x00050051, 0x0000000B, 0x000053F7, 0x00001DDD, 0x00000003, 0x000500C4, 0x0000000B, + 0x00001C80, 0x000053F7, 0x00000A53, 0x000500C5, 0x0000000B, 0x00002428, 0x00004D79, 0x00001C80, + 0x0008000C, 0x0000001D, 0x00001D63, 0x00000001, 0x0000002B, 0x00003816, 0x00000B7A, 0x00000505, + 0x0005008E, 0x0000001D, 0x00002049, 0x00001D63, 0x00000540, 0x00050081, 0x0000001D, 0x00002E6D, + 0x00002049, 0x00000145, 0x0004006D, 0x00000017, 0x00001DDE, 0x00002E6D, 0x00050051, 0x0000000B, + 0x0000220E, 0x00001DDE, 0x00000000, 0x00050051, 0x0000000B, 0x00002FED, 0x00001DDE, 0x00000001, + 0x000500C4, 0x0000000B, 0x00002D37, 0x00002FED, 0x00000A23, 0x000500C5, 0x0000000B, 0x00004D7A, + 0x0000220E, 0x00002D37, 0x00050051, 0x0000000B, 0x000053F8, 0x00001DDE, 0x00000002, 0x000500C4, + 0x0000000B, 0x00002179, 0x000053F8, 0x00000A3B, 0x000500C5, 0x0000000B, 0x00004D7B, 0x00004D7A, + 0x00002179, 0x00050051, 0x0000000B, 0x000053F9, 0x00001DDE, 0x00000003, 0x000500C4, 0x0000000B, + 0x00001C81, 0x000053F9, 0x00000A53, 0x000500C5, 0x0000000B, 0x00002429, 0x00004D7B, 0x00001C81, + 0x0008000C, 0x0000001D, 0x00001D64, 0x00000001, 0x0000002B, 0x00002BB5, 0x00000B7A, 0x00000505, + 0x0005008E, 0x0000001D, 0x0000204A, 0x00001D64, 0x00000540, 0x00050081, 0x0000001D, 0x00002E6E, + 0x0000204A, 0x00000145, 0x0004006D, 0x00000017, 0x00001DDF, 0x00002E6E, 0x00050051, 0x0000000B, + 0x0000220F, 0x00001DDF, 0x00000000, 0x00050051, 0x0000000B, 0x00002FEE, 0x00001DDF, 0x00000001, + 0x000500C4, 0x0000000B, 0x00002D38, 0x00002FEE, 0x00000A23, 0x000500C5, 0x0000000B, 0x00004D7C, + 0x0000220F, 0x00002D38, 0x00050051, 0x0000000B, 0x000053FA, 0x00001DDF, 0x00000002, 0x000500C4, + 0x0000000B, 0x0000217A, 0x000053FA, 0x00000A3B, 0x000500C5, 0x0000000B, 0x00004D7D, 0x00004D7C, + 0x0000217A, 0x00050051, 0x0000000B, 0x000053FB, 0x00001DDF, 0x00000003, 0x000500C4, 0x0000000B, + 0x00002160, 0x000053FB, 0x00000A53, 0x000500C5, 0x0000000B, 0x00005206, 0x00004D7D, 0x00002160, + 0x00070050, 0x00000017, 0x000053E1, 0x00002427, 0x00002428, 0x00002429, 0x00005206, 0x000200F9, + 0x00004992, 0x000200F8, 0x00002002, 0x00050051, 0x0000000D, 0x0000309E, 0x00003A49, 0x00000000, + 0x0004007C, 0x0000000B, 0x00005298, 0x0000309E, 0x00050051, 0x0000000D, 0x00004F4D, 0x00003B57, + 0x00000000, 0x0004007C, 0x0000000B, 0x0000451D, 0x00004F4D, 0x00050051, 0x0000000D, 0x00004F4E, + 0x00003816, 0x00000000, 0x0004007C, 0x0000000B, 0x0000451E, 0x00004F4E, 0x00050051, 0x0000000D, + 0x00004F38, 0x00002BB5, 0x00000000, 0x0004007C, 0x0000000B, 0x00004F16, 0x00004F38, 0x00070050, + 0x00000017, 0x00002738, 0x00005298, 0x0000451D, 0x0000451E, 0x00004F16, 0x000200F9, 0x00004992, + 0x000200F8, 0x00004992, 0x001100F5, 0x00000017, 0x000058B2, 0x00002738, 0x00002002, 0x000053E1, + 0x00004696, 0x000053E0, 0x000045EB, 0x000053DF, 0x00001935, 0x000053DE, 0x00001934, 0x000053DD, + 0x00001933, 0x0000612F, 0x00002514, 0x000500AA, 0x00000009, 0x00004AAF, 0x00001DD8, 0x00000A0A, + 0x000600A9, 0x00000009, 0x000056E6, 0x00004AAF, 0x00000787, 0x00004AAF, 0x000300F7, 0x00004CC1, + 0x00000002, 0x000400FA, 0x000056E6, 0x00002620, 0x00004CC1, 0x000200F8, 0x00002620, 0x00050051, + 0x0000000B, 0x00005002, 0x000058B2, 0x00000001, 0x00060052, 0x00000017, 0x000037FF, 0x00005002, + 0x000058B2, 0x00000000, 0x000200F9, 0x00004CC1, 0x000200F8, 0x00004CC1, 0x000700F5, 0x00000017, + 0x0000305F, 0x000058B2, 0x00004992, 0x000037FF, 0x00002620, 0x00050080, 0x00000011, 0x000032A7, + 0x00002EF9, 0x000059EC, 0x000300F7, 0x000052F5, 0x00000002, 0x000400FA, 0x0000500F, 0x0000294E, + 0x0000537D, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000012, 0x00002970, 0x000032A7, 0x00050051, + 0x0000000C, 0x000042C2, 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, + 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, + 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00003DA7, 0x00000A19, + 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, + 0x000018AA, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, + 0x00004A8E, 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002ACB, 0x000042C2, 0x00000A20, + 0x000500C7, 0x0000000C, 0x00003138, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454D, + 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002ACB, 0x0000454D, 0x000500C4, + 0x0000000C, 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, + 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, + 0x00003C4B, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, + 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4B, 0x00003397, 0x000500C7, 0x0000000C, 0x000047BD, + 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544A, 0x000047BD, 0x00000A17, 0x00050080, + 0x0000000C, 0x00004157, 0x00004D30, 0x0000544A, 0x000500C7, 0x0000000C, 0x00005022, 0x00004157, + 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, + 0x00050080, 0x0000000C, 0x00004158, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004AE3, + 0x00004157, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544B, 0x00004AE3, 0x00000A11, 0x00050080, + 0x0000000C, 0x0000414C, 0x00004158, 0x0000544B, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, + 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, + 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, + 0x000500C7, 0x0000000C, 0x00005454, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544C, + 0x00005454, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4C, 0x0000414C, 0x0000544C, 0x000500C7, + 0x0000000C, 0x00002E06, 0x00004157, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4C, + 0x00002E06, 0x0004007C, 0x0000000B, 0x0000566F, 0x0000394F, 0x000200F9, 0x000052F5, 0x000200F8, + 0x0000294E, 0x00050051, 0x0000000B, 0x00004D9A, 0x000032A7, 0x00000000, 0x00050051, 0x0000000B, + 0x00002C03, 0x000032A7, 0x00000001, 0x00060050, 0x00000014, 0x000020DE, 0x00004D9A, 0x00002C03, + 0x00005F72, 0x0004007C, 0x00000016, 0x00004E9D, 0x000020DE, 0x00050051, 0x0000000C, 0x000028C6, + 0x00004E9D, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FE, 0x000028C6, 0x00000A17, 0x00050051, + 0x0000000C, 0x00002748, 0x00004E9D, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, + 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00006273, 0x00000A16, 0x0004007C, 0x0000000C, + 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005321, 0x0000405D, 0x000018AB, 0x00050080, + 0x0000000C, 0x00003B27, 0x000024FE, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00003DA7, + 0x00000A19, 0x0004007C, 0x0000000C, 0x00003097, 0x00002348, 0x00050084, 0x0000000C, 0x0000287F, + 0x00003B27, 0x00003097, 0x00050051, 0x0000000C, 0x00006242, 0x00004E9D, 0x00000000, 0x000500C3, + 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, + 0x0000287F, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A22, 0x000500C7, 0x0000000C, + 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, + 0x000028C6, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, + 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454E, 0x000500C4, 0x0000000C, 0x00001B8B, 0x0000434B, + 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B8B, 0x00000A1D, 0x000500C3, 0x0000000C, + 0x00002220, 0x000028C6, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002220, 0x0000405D, + 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, + 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, + 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004AE4, 0x000034BD, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544D, 0x00004AE4, 0x00000A0E, 0x00050080, 0x0000000C, + 0x00003C4D, 0x00005A0C, 0x0000544D, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, + 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B32, + 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, + 0x0000000C, 0x0000285C, 0x00005B32, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047BE, 0x00002748, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544E, 0x000047BE, 0x00000A22, 0x00050080, 0x0000000C, + 0x00004159, 0x0000285C, 0x0000544E, 0x000500C7, 0x0000000C, 0x00004AE5, 0x000028C6, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544F, 0x00004AE5, 0x00000A17, 0x00050080, 0x0000000C, 0x0000415A, + 0x00004159, 0x0000544F, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4D, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x0000415A, + 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, + 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B33, 0x00003412, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4D, 0x00000A05, 0x00050080, 0x0000000C, 0x00002ACC, + 0x00005B33, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002ACC, 0x00000A11, 0x000500C7, + 0x0000000C, 0x00005AB2, 0x0000415A, 0x0000040B, 0x00050080, 0x0000000C, 0x00002ACD, 0x00005B34, + 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B35, 0x00002ACD, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005559, 0x0000415A, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B35, 0x00005559, + 0x0004007C, 0x0000000B, 0x00005670, 0x00005EFA, 0x000200F9, 0x000052F5, 0x000200F8, 0x000052F5, + 0x000700F5, 0x0000000B, 0x00002C70, 0x00005670, 0x0000294E, 0x0000566F, 0x0000537D, 0x00050080, + 0x0000000B, 0x00005088, 0x00002C70, 0x000062B6, 0x000500C2, 0x0000000B, 0x000048F3, 0x00005088, + 0x00000A16, 0x000500AA, 0x00000009, 0x00002EEA, 0x00004ADC, 0x00000A0D, 0x000500AA, 0x00000009, + 0x00005776, 0x00004ADC, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x00002EEA, 0x00005776, + 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, + 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x0000305F, 0x000009CE, 0x000500C4, 0x00000017, + 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x0000305F, 0x0000072E, + 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, + 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, + 0x0000587A, 0x0000305F, 0x000052F5, 0x00003FF9, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, + 0x00004ADC, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005776, 0x00004CB6, 0x000300F7, + 0x00002C98, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x00002C98, 0x000200F8, 0x00002B38, + 0x000500C4, 0x00000017, 0x00005E17, 0x0000587A, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, + 0x0000587A, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, + 0x00002C98, 0x000200F8, 0x00002C98, 0x000700F5, 0x00000017, 0x00004D37, 0x0000587A, 0x00003463, + 0x000029E8, 0x00002B38, 0x00060041, 0x00000294, 0x00001F76, 0x00001592, 0x00000A0B, 0x000048F3, + 0x0003003E, 0x00001F76, 0x00004D37, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, + 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_full_32bpp_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_full_32bpp_scaled_cs.h new file mode 100644 index 0000000..db1f109 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_full_32bpp_scaled_cs.h @@ -0,0 +1,4520 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25245 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_runtimearr_uint ArrayStride 4 + OpDecorate %_struct_1948 BufferBlock + OpMemberDecorate %_struct_1948 0 NonWritable + OpMemberDecorate %_struct_1948 0 Offset 0 + OpDecorate %3271 NonWritable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %_struct_1017 Block + OpMemberDecorate %_struct_1017 0 Offset 0 + OpMemberDecorate %_struct_1017 1 Offset 4 + OpMemberDecorate %_struct_1017 2 Offset 8 + OpMemberDecorate %_struct_1017 3 Offset 12 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonReadable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %5522 NonReadable + OpDecorate %5522 Binding 0 + OpDecorate %5522 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %v4uint = OpTypeVector %uint 4 + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 + %v3float = OpTypeVector %float 3 + %v4float = OpTypeVector %float 4 + %bool = OpTypeBool + %v3int = OpTypeVector %int 3 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %float_255 = OpConstant %float 255 + %float_0_5 = OpConstant %float 0.5 + %uint_0 = OpConstant %uint 0 + %int_8 = OpConstant %int 8 + %int_16 = OpConstant %int 16 + %int_24 = OpConstant %int 24 + %float_1023 = OpConstant %float 1023 + %float_3 = OpConstant %float 3 + %344 = OpConstantComposite %v4float %float_1023 %float_1023 %float_1023 %float_3 + %int_10 = OpConstant %int 10 + %int_20 = OpConstant %int 20 + %int_30 = OpConstant %int 30 + %float_2047 = OpConstant %float 2047 + %2275 = OpConstantComposite %v3float %float_2047 %float_2047 %float_1023 + %int_11 = OpConstant %int 11 + %int_22 = OpConstant %int 22 + %14 = OpConstantComposite %v3float %float_1023 %float_2047 %float_2047 + %int_21 = OpConstant %int 21 +%float_65535 = OpConstant %float 65535 + %uint_24 = OpConstant %uint 24 + %653 = OpConstantComposite %v4uint %uint_0 %uint_8 %uint_16 %uint_24 + %uint_255 = OpConstant %uint 255 +%float_0_00392156886 = OpConstant %float 0.00392156886 + %uint_10 = OpConstant %uint 10 + %uint_20 = OpConstant %uint 20 + %uint_30 = OpConstant %uint 30 + %845 = OpConstantComposite %v4uint %uint_0 %uint_10 %uint_20 %uint_30 + %uint_1023 = OpConstant %uint 1023 + %635 = OpConstantComposite %v4uint %uint_1023 %uint_1023 %uint_1023 %uint_3 +%float_0_000977517106 = OpConstant %float 0.000977517106 +%float_0_333333343 = OpConstant %float 0.333333343 + %2798 = OpConstantComposite %v4float %float_0_000977517106 %float_0_000977517106 %float_0_000977517106 %float_0_333333343 + %2996 = OpConstantComposite %v3uint %uint_0 %uint_10 %uint_20 + %uint_127 = OpConstant %uint 127 + %uint_7 = OpConstant %uint 7 + %v3bool = OpTypeVector %bool 3 + %uint_124 = OpConstant %uint 124 + %uint_23 = OpConstant %uint 23 + %float_n1 = OpConstant %float -1 + %int_0 = OpConstant %int 0 + %1959 = OpConstantComposite %v2int %int_16 %int_0 +%float_0_000976592302 = OpConstant %float 0.000976592302 + %v4int = OpTypeVector %int 4 + %290 = OpConstantComposite %v4int %int_16 %int_0 %int_16 %int_0 + %1837 = OpConstantComposite %v2uint %uint_2 %uint_1 + %v2bool = OpTypeVector %bool 2 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %uint_80 = OpConstant %uint 80 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %uint_2048 = OpConstant %uint 2048 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_448 = OpConstant %int 448 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 + %uint_6 = OpConstant %uint 6 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_runtimearr_uint = OpTypeRuntimeArray %uint +%_struct_1948 = OpTypeStruct %_runtimearr_uint +%_ptr_Uniform__struct_1948 = OpTypePointer Uniform %_struct_1948 + %3271 = OpVariable %_ptr_Uniform__struct_1948 Uniform +%_ptr_Uniform_uint = OpTypePointer Uniform %uint +%_struct_1017 = OpTypeStruct %uint %uint %uint %uint +%_ptr_PushConstant__struct_1017 = OpTypePointer PushConstant %_struct_1017 + %3305 = OpVariable %_ptr_PushConstant__struct_1017 PushConstant +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_15 = OpConstant %uint 15 + %uint_28 = OpConstant %uint 28 + %uint_19 = OpConstant %uint 19 + %2179 = OpConstantComposite %v2uint %uint_16 %uint_19 +%uint_536870912 = OpConstant %uint 536870912 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 + %uint_63 = OpConstant %uint 63 + %int_26 = OpConstant %int 26 + %int_23 = OpConstant %int 23 +%uint_16777216 = OpConstant %uint 16777216 + %2276 = OpConstantComposite %v2uint %uint_20 %uint_24 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %1825 = OpConstantComposite %v2uint %uint_2 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %5522 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %1955 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %1284 = OpConstantComposite %v4float %float_n1 %float_n1 %float_n1 %float_n1 + %770 = OpConstantComposite %v4int %int_16 %int_16 %int_16 %int_16 + %1611 = OpConstantComposite %v4uint %uint_255 %uint_255 %uint_255 %uint_255 + %261 = OpConstantComposite %v3uint %uint_1023 %uint_1023 %uint_1023 + %1126 = OpConstantComposite %v3uint %uint_127 %uint_127 %uint_127 + %2828 = OpConstantComposite %v3uint %uint_7 %uint_7 %uint_7 + %2578 = OpConstantComposite %v3uint %uint_0 %uint_0 %uint_0 + %1018 = OpConstantComposite %v3uint %uint_124 %uint_124 %uint_124 + %393 = OpConstantComposite %v3uint %uint_23 %uint_23 %uint_23 + %141 = OpConstantComposite %v3uint %uint_16 %uint_16 %uint_16 + %73 = OpConstantComposite %v2float %float_n1 %float_n1 + %2151 = OpConstantComposite %v2int %int_16 %int_16 + %2938 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 + %1285 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 + %325 = OpConstantComposite %v4float %float_0_5 %float_0_5 %float_0_5 %float_0_5 + %2605 = OpConstantComposite %v3float %float_0 %float_0 %float_0 + %2584 = OpConstantComposite %v3float %float_1 %float_1 %float_1 + %939 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5 + %1823 = OpConstantComposite %v2float %float_0 %float_0 + %768 = OpConstantComposite %v2float %float_1 %float_1 + %1566 = OpConstantComposite %v2float %float_0_5 %float_0_5 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 +%int_1065353216 = OpConstant %int 1065353216 +%uint_4294967290 = OpConstant %uint 4294967290 + %2360 = OpConstantComposite %v3uint %uint_4294967290 %uint_4294967290 %uint_4294967290 + %float_0_25 = OpConstant %float 0.25 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %19978 = OpShiftRightLogical %uint %15627 %uint_10 + %8574 = OpBitwiseAnd %uint %19978 %uint_3 + %21002 = OpShiftRightLogical %uint %15627 %uint_13 + %8575 = OpBitwiseAnd %uint %21002 %uint_2047 + %21003 = OpShiftRightLogical %uint %15627 %uint_24 + %8576 = OpBitwiseAnd %uint %21003 %uint_15 + %18836 = OpShiftRightLogical %uint %15627 %uint_28 + %9130 = OpBitwiseAnd %uint %18836 %uint_1 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9633 = OpShiftRightLogical %v2uint %8871 %2179 + %23601 = OpBitwiseAnd %v2uint %9633 %1954 + %24030 = OpBitwiseAnd %uint %15627 %uint_536870912 + %12295 = OpINotEqual %bool %24030 %uint_0 + OpSelectionMerge %14676 None + OpBranchConditional %12295 %16739 %21992 + %21992 = OpLabel + OpBranch %14676 + %16739 = OpLabel + %15278 = OpShiftRightLogical %v2uint %23601 %1828 + OpBranch %14676 + %14676 = OpLabel + %19124 = OpPhi %v2uint %15278 %16739 %1807 %21992 + %7038 = OpShiftRightLogical %v2uint %8871 %1855 + %11769 = OpBitwiseAnd %v2uint %7038 %1955 + %16207 = OpShiftLeftLogical %v2uint %11769 %1870 + %23019 = OpIMul %v2uint %16207 %23601 + %13123 = OpShiftRightLogical %uint %20824 %uint_5 + %14785 = OpBitwiseAnd %uint %13123 %uint_2047 + %8858 = OpCompositeExtract %uint %23601 0 + %22993 = OpIMul %uint %14785 %8858 + %20036 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %18628 = OpLoad %uint %20036 + %22701 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %20919 = OpLoad %uint %22701 + %19164 = OpBitwiseAnd %uint %18628 %uint_7 + %21999 = OpBitwiseAnd %uint %18628 %uint_8 + %20495 = OpINotEqual %bool %21999 %uint_0 + %10307 = OpShiftRightLogical %uint %18628 %uint_4 + %24434 = OpBitwiseAnd %uint %10307 %uint_7 + %19672 = OpShiftRightLogical %uint %18628 %uint_7 + %20627 = OpBitwiseAnd %uint %19672 %uint_63 + %22920 = OpBitcast %int %18628 + %13711 = OpShiftLeftLogical %int %22920 %int_10 + %20636 = OpShiftRightArithmetic %int %13711 %int_26 + %18178 = OpShiftLeftLogical %int %20636 %int_23 + %7462 = OpIAdd %int %18178 %int_1065353216 + %11052 = OpBitcast %float %7462 + %22649 = OpBitwiseAnd %uint %18628 %uint_16777216 + %7513 = OpINotEqual %bool %22649 %uint_0 + %8003 = OpBitwiseAnd %uint %20919 %uint_1023 + %15783 = OpShiftLeftLogical %uint %8003 %uint_5 + %22591 = OpShiftRightLogical %uint %20919 %uint_10 + %19390 = OpBitwiseAnd %uint %22591 %uint_1023 + %25203 = OpShiftLeftLogical %uint %19390 %uint_5 + %10422 = OpCompositeConstruct %v2uint %20919 %20919 + %10385 = OpShiftRightLogical %v2uint %10422 %2276 + %23379 = OpBitwiseAnd %v2uint %10385 %2122 + %16208 = OpShiftLeftLogical %v2uint %23379 %1870 + %23020 = OpIMul %v2uint %16208 %23601 + %12743 = OpShiftRightLogical %uint %20919 %uint_28 + %17238 = OpBitwiseAnd %uint %12743 %uint_7 + %12737 = OpLoad %v3uint %gl_GlobalInvocationID + %14500 = OpVectorShuffle %v2uint %12737 %12737 0 1 + %12025 = OpShiftLeftLogical %v2uint %14500 %1825 + %7640 = OpCompositeExtract %uint %12025 0 + %11658 = OpShiftLeftLogical %uint %22993 %uint_3 + %15379 = OpUGreaterThanEqual %bool %7640 %11658 + OpSelectionMerge %14025 DontFlatten + OpBranchConditional %15379 %21993 %14025 + %21993 = OpLabel + OpBranch %19578 + %14025 = OpLabel + %18615 = OpCompositeExtract %uint %12025 1 + %16803 = OpCompositeExtract %uint %19124 1 + %24446 = OpExtInst %uint %1 UMax %18615 %16803 + %20975 = OpCompositeConstruct %v2uint %7640 %24446 + %21036 = OpIAdd %v2uint %20975 %23019 + %16075 = OpULessThanEqual %bool %17238 %uint_3 + OpSelectionMerge %23776 None + OpBranchConditional %16075 %10990 %15087 + %15087 = OpLabel + %13566 = OpIEqual %bool %17238 %uint_5 + %8438 = OpSelect %uint %13566 %uint_2 %uint_0 + OpBranch %23776 + %10990 = OpLabel + OpBranch %23776 + %23776 = OpLabel + %19300 = OpPhi %uint %17238 %10990 %8438 %15087 + %16830 = OpCompositeConstruct %v2uint %8574 %8574 + %11801 = OpUGreaterThanEqual %v2bool %16830 %1837 + %19381 = OpSelect %v2uint %11801 %1828 %1807 + %10986 = OpShiftLeftLogical %v2uint %21036 %19381 + %24669 = OpCompositeConstruct %v2uint %19300 %19300 + %9093 = OpShiftRightLogical %v2uint %24669 %1816 + %16072 = OpBitwiseAnd %v2uint %9093 %1828 + %18106 = OpIAdd %v2uint %10986 %16072 + %22936 = OpIMul %v2uint %2719 %23601 + %11332 = OpCompositeConstruct %v2uint %9130 %uint_0 + %6571 = OpShiftRightLogical %v2uint %22936 %11332 + %10146 = OpUDiv %v2uint %18106 %6571 + %20390 = OpCompositeExtract %uint %10146 1 + %11046 = OpIMul %uint %20390 %20561 + %24665 = OpCompositeExtract %uint %10146 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %8575 %21536 + %22376 = OpIMul %v2uint %10146 %6571 + %20715 = OpISub %v2uint %18106 %22376 + %7303 = OpCompositeExtract %uint %22936 0 + %22882 = OpCompositeExtract %uint %22936 1 + %13170 = OpIMul %uint %7303 %22882 + %14551 = OpIMul %uint %8742 %13170 + %6805 = OpCompositeExtract %uint %20715 1 + %23526 = OpCompositeExtract %uint %6571 0 + %22886 = OpIMul %uint %6805 %23526 + %6886 = OpCompositeExtract %uint %20715 0 + %9696 = OpIAdd %uint %22886 %6886 + %18021 = OpShiftLeftLogical %uint %9696 %9130 + %18363 = OpIAdd %uint %14551 %18021 + %13504 = OpIMul %uint %13170 %uint_2048 + %25231 = OpUMod %uint %18363 %13504 + %16379 = OpUGreaterThanEqual %bool %8574 %uint_2 + %24735 = OpSelect %uint %16379 %uint_1 %uint_0 + %20074 = OpIAdd %uint %9130 %24735 + %6555 = OpShiftLeftLogical %uint %uint_1 %20074 + %23279 = OpINotEqual %bool %9130 %uint_0 + OpSelectionMerge %21263 DontFlatten + OpBranchConditional %23279 %15205 %16569 + %16569 = OpLabel + %19162 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20297 DontFlatten + OpBranchConditional %19162 %9761 %12129 + %12129 = OpLabel + %19407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %25231 + %23875 = OpLoad %uint %19407 + %11687 = OpIAdd %uint %25231 %6555 + %6475 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11687 + %24155 = OpLoad %uint %6475 + %6234 = OpIMul %uint %uint_2 %6555 + %8353 = OpIAdd %uint %25231 %6234 + %15309 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8353 + %24156 = OpLoad %uint %15309 + %6235 = OpIMul %uint %uint_3 %6555 + %8354 = OpIAdd %uint %25231 %6235 + %14321 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8354 + %16380 = OpLoad %uint %14321 + %20780 = OpCompositeConstruct %v4uint %23875 %24155 %24156 %16380 + OpBranch %20297 + %9761 = OpLabel + %21829 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %25231 + %23876 = OpLoad %uint %21829 + %11688 = OpIAdd %uint %25231 %uint_1 + %6399 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11688 + %23650 = OpLoad %uint %6399 + %11689 = OpIAdd %uint %25231 %uint_2 + %6400 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11689 + %23651 = OpLoad %uint %6400 + %11690 = OpIAdd %uint %25231 %uint_3 + %24558 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11690 + %16381 = OpLoad %uint %24558 + %20781 = OpCompositeConstruct %v4uint %23876 %23650 %23651 %16381 + OpBranch %20297 + %20297 = OpLabel + %10943 = OpPhi %v4uint %20781 %9761 %20780 %12129 + OpSelectionMerge %16224 None + OpSwitch %8576 %19451 0 %14585 1 %14585 2 %7355 10 %7355 3 %7354 12 %7354 4 %8190 6 %8243 + %8243 = OpLabel + %24406 = OpCompositeExtract %uint %10943 0 + %24679 = OpExtInst %v2float %1 UnpackHalf2x16 %24406 + %10082 = OpCompositeExtract %float %24679 0 + %17478 = OpCompositeExtract %float %24679 1 + %14604 = OpCompositeConstruct %v4float %10082 %17478 %float_0 %float_0 + %17274 = OpCompositeExtract %uint %10943 1 + %18027 = OpExtInst %v2float %1 UnpackHalf2x16 %17274 + %10083 = OpCompositeExtract %float %18027 0 + %17479 = OpCompositeExtract %float %18027 1 + %14605 = OpCompositeConstruct %v4float %10083 %17479 %float_0 %float_0 + %17275 = OpCompositeExtract %uint %10943 2 + %18028 = OpExtInst %v2float %1 UnpackHalf2x16 %17275 + %10084 = OpCompositeExtract %float %18028 0 + %17480 = OpCompositeExtract %float %18028 1 + %14606 = OpCompositeConstruct %v4float %10084 %17480 %float_0 %float_0 + %17276 = OpCompositeExtract %uint %10943 3 + %18029 = OpExtInst %v2float %1 UnpackHalf2x16 %17276 + %10085 = OpCompositeExtract %float %18029 0 + %20670 = OpCompositeExtract %float %18029 1 + %9033 = OpCompositeConstruct %v4float %10085 %20670 %float_0 %float_0 + OpBranch %16224 + %8190 = OpLabel + %12427 = OpCompositeExtract %uint %10943 0 + %22685 = OpBitcast %int %12427 + %18202 = OpCompositeConstruct %v2int %22685 %22685 + %18349 = OpShiftLeftLogical %v2int %18202 %1959 + %13335 = OpShiftRightArithmetic %v2int %18349 %2151 + %10903 = OpConvertSToF %v2float %13335 + %18247 = OpVectorTimesScalar %v2float %10903 %float_0_000976592302 + %24070 = OpExtInst %v2float %1 FMax %73 %18247 + %24330 = OpCompositeExtract %float %24070 0 + %15572 = OpCompositeExtract %float %24070 1 + %16670 = OpCompositeConstruct %v4float %24330 %15572 %float_0 %float_0 + %19522 = OpCompositeExtract %uint %10943 1 + %16033 = OpBitcast %int %19522 + %18203 = OpCompositeConstruct %v2int %16033 %16033 + %18350 = OpShiftLeftLogical %v2int %18203 %1959 + %13336 = OpShiftRightArithmetic %v2int %18350 %2151 + %10904 = OpConvertSToF %v2float %13336 + %18248 = OpVectorTimesScalar %v2float %10904 %float_0_000976592302 + %24071 = OpExtInst %v2float %1 FMax %73 %18248 + %24331 = OpCompositeExtract %float %24071 0 + %15573 = OpCompositeExtract %float %24071 1 + %16671 = OpCompositeConstruct %v4float %24331 %15573 %float_0 %float_0 + %19523 = OpCompositeExtract %uint %10943 2 + %16034 = OpBitcast %int %19523 + %18204 = OpCompositeConstruct %v2int %16034 %16034 + %18351 = OpShiftLeftLogical %v2int %18204 %1959 + %13337 = OpShiftRightArithmetic %v2int %18351 %2151 + %10905 = OpConvertSToF %v2float %13337 + %18249 = OpVectorTimesScalar %v2float %10905 %float_0_000976592302 + %24072 = OpExtInst %v2float %1 FMax %73 %18249 + %24332 = OpCompositeExtract %float %24072 0 + %15574 = OpCompositeExtract %float %24072 1 + %16672 = OpCompositeConstruct %v4float %24332 %15574 %float_0 %float_0 + %19524 = OpCompositeExtract %uint %10943 3 + %16035 = OpBitcast %int %19524 + %18205 = OpCompositeConstruct %v2int %16035 %16035 + %18352 = OpShiftLeftLogical %v2int %18205 %1959 + %13338 = OpShiftRightArithmetic %v2int %18352 %2151 + %10906 = OpConvertSToF %v2float %13338 + %18250 = OpVectorTimesScalar %v2float %10906 %float_0_000976592302 + %24073 = OpExtInst %v2float %1 FMax %73 %18250 + %24333 = OpCompositeExtract %float %24073 0 + %18764 = OpCompositeExtract %float %24073 1 + %9034 = OpCompositeConstruct %v4float %24333 %18764 %float_0 %float_0 + OpBranch %16224 + %7354 = OpLabel + %22205 = OpCompositeExtract %uint %10943 0 + %20234 = OpCompositeConstruct %v3uint %22205 %22205 %22205 + %11021 = OpShiftRightLogical %v3uint %20234 %2996 + %24038 = OpBitwiseAnd %v3uint %11021 %261 + %18588 = OpBitwiseAnd %v3uint %24038 %1126 + %23440 = OpShiftRightLogical %v3uint %24038 %2828 + %16585 = OpIEqual %v3bool %23440 %2578 + %11339 = OpExtInst %v3int %1 FindUMsb %18588 + %10773 = OpBitcast %v3uint %11339 + %6266 = OpISub %v3uint %2828 %10773 + %8720 = OpIAdd %v3uint %10773 %2360 + %10351 = OpSelect %v3uint %16585 %8720 %23440 + %23252 = OpShiftLeftLogical %v3uint %18588 %6266 + %18842 = OpBitwiseAnd %v3uint %23252 %1126 + %10909 = OpSelect %v3uint %16585 %18842 %18588 + %24569 = OpIAdd %v3uint %10351 %1018 + %20351 = OpShiftLeftLogical %v3uint %24569 %393 + %16294 = OpShiftLeftLogical %v3uint %10909 %141 + %22396 = OpBitwiseOr %v3uint %20351 %16294 + %13824 = OpIEqual %v3bool %24038 %2578 + %16962 = OpSelect %v3uint %13824 %2578 %22396 + %10703 = OpBitcast %v3float %16962 + %19364 = OpShiftRightLogical %uint %22205 %uint_30 + %18446 = OpConvertUToF %float %19364 + %15903 = OpFMul %float %18446 %float_0_333333343 + %21442 = OpCompositeExtract %float %10703 0 + %10837 = OpCompositeExtract %float %10703 1 + %7833 = OpCompositeExtract %float %10703 2 + %15834 = OpCompositeConstruct %v4float %21442 %10837 %7833 %15903 + %10229 = OpCompositeExtract %uint %10943 1 + %13582 = OpCompositeConstruct %v3uint %10229 %10229 %10229 + %11022 = OpShiftRightLogical %v3uint %13582 %2996 + %24039 = OpBitwiseAnd %v3uint %11022 %261 + %18589 = OpBitwiseAnd %v3uint %24039 %1126 + %23441 = OpShiftRightLogical %v3uint %24039 %2828 + %16586 = OpIEqual %v3bool %23441 %2578 + %11340 = OpExtInst %v3int %1 FindUMsb %18589 + %10774 = OpBitcast %v3uint %11340 + %6267 = OpISub %v3uint %2828 %10774 + %8721 = OpIAdd %v3uint %10774 %2360 + %10352 = OpSelect %v3uint %16586 %8721 %23441 + %23253 = OpShiftLeftLogical %v3uint %18589 %6267 + %18843 = OpBitwiseAnd %v3uint %23253 %1126 + %10910 = OpSelect %v3uint %16586 %18843 %18589 + %24570 = OpIAdd %v3uint %10352 %1018 + %20352 = OpShiftLeftLogical %v3uint %24570 %393 + %16295 = OpShiftLeftLogical %v3uint %10910 %141 + %22397 = OpBitwiseOr %v3uint %20352 %16295 + %13825 = OpIEqual %v3bool %24039 %2578 + %16963 = OpSelect %v3uint %13825 %2578 %22397 + %10704 = OpBitcast %v3float %16963 + %19365 = OpShiftRightLogical %uint %10229 %uint_30 + %18447 = OpConvertUToF %float %19365 + %15904 = OpFMul %float %18447 %float_0_333333343 + %21443 = OpCompositeExtract %float %10704 0 + %10838 = OpCompositeExtract %float %10704 1 + %7834 = OpCompositeExtract %float %10704 2 + %15835 = OpCompositeConstruct %v4float %21443 %10838 %7834 %15904 + %10230 = OpCompositeExtract %uint %10943 2 + %13583 = OpCompositeConstruct %v3uint %10230 %10230 %10230 + %11023 = OpShiftRightLogical %v3uint %13583 %2996 + %24040 = OpBitwiseAnd %v3uint %11023 %261 + %18590 = OpBitwiseAnd %v3uint %24040 %1126 + %23442 = OpShiftRightLogical %v3uint %24040 %2828 + %16587 = OpIEqual %v3bool %23442 %2578 + %11341 = OpExtInst %v3int %1 FindUMsb %18590 + %10775 = OpBitcast %v3uint %11341 + %6268 = OpISub %v3uint %2828 %10775 + %8722 = OpIAdd %v3uint %10775 %2360 + %10353 = OpSelect %v3uint %16587 %8722 %23442 + %23254 = OpShiftLeftLogical %v3uint %18590 %6268 + %18844 = OpBitwiseAnd %v3uint %23254 %1126 + %10911 = OpSelect %v3uint %16587 %18844 %18590 + %24571 = OpIAdd %v3uint %10353 %1018 + %20353 = OpShiftLeftLogical %v3uint %24571 %393 + %16296 = OpShiftLeftLogical %v3uint %10911 %141 + %22398 = OpBitwiseOr %v3uint %20353 %16296 + %13826 = OpIEqual %v3bool %24040 %2578 + %16964 = OpSelect %v3uint %13826 %2578 %22398 + %10705 = OpBitcast %v3float %16964 + %19366 = OpShiftRightLogical %uint %10230 %uint_30 + %18448 = OpConvertUToF %float %19366 + %15905 = OpFMul %float %18448 %float_0_333333343 + %21444 = OpCompositeExtract %float %10705 0 + %10839 = OpCompositeExtract %float %10705 1 + %7835 = OpCompositeExtract %float %10705 2 + %15836 = OpCompositeConstruct %v4float %21444 %10839 %7835 %15905 + %10231 = OpCompositeExtract %uint %10943 3 + %13584 = OpCompositeConstruct %v3uint %10231 %10231 %10231 + %11024 = OpShiftRightLogical %v3uint %13584 %2996 + %24041 = OpBitwiseAnd %v3uint %11024 %261 + %18591 = OpBitwiseAnd %v3uint %24041 %1126 + %23443 = OpShiftRightLogical %v3uint %24041 %2828 + %16588 = OpIEqual %v3bool %23443 %2578 + %11342 = OpExtInst %v3int %1 FindUMsb %18591 + %10776 = OpBitcast %v3uint %11342 + %6269 = OpISub %v3uint %2828 %10776 + %8723 = OpIAdd %v3uint %10776 %2360 + %10354 = OpSelect %v3uint %16588 %8723 %23443 + %23255 = OpShiftLeftLogical %v3uint %18591 %6269 + %18845 = OpBitwiseAnd %v3uint %23255 %1126 + %10912 = OpSelect %v3uint %16588 %18845 %18591 + %24572 = OpIAdd %v3uint %10354 %1018 + %20354 = OpShiftLeftLogical %v3uint %24572 %393 + %16297 = OpShiftLeftLogical %v3uint %10912 %141 + %22399 = OpBitwiseOr %v3uint %20354 %16297 + %13827 = OpIEqual %v3bool %24041 %2578 + %16965 = OpSelect %v3uint %13827 %2578 %22399 + %10706 = OpBitcast %v3float %16965 + %19367 = OpShiftRightLogical %uint %10231 %uint_30 + %18449 = OpConvertUToF %float %19367 + %15906 = OpFMul %float %18449 %float_0_333333343 + %21445 = OpCompositeExtract %float %10706 0 + %10840 = OpCompositeExtract %float %10706 1 + %11025 = OpCompositeExtract %float %10706 2 + %9035 = OpCompositeConstruct %v4float %21445 %10840 %11025 %15906 + OpBranch %16224 + %7355 = OpLabel + %22206 = OpCompositeExtract %uint %10943 0 + %20235 = OpCompositeConstruct %v4uint %22206 %22206 %22206 %22206 + %9368 = OpShiftRightLogical %v4uint %20235 %845 + %18859 = OpBitwiseAnd %v4uint %9368 %635 + %15543 = OpConvertUToF %v4float %18859 + %16688 = OpFMul %v4float %15543 %2798 + %23762 = OpCompositeExtract %uint %10943 1 + %20813 = OpCompositeConstruct %v4uint %23762 %23762 %23762 %23762 + %9369 = OpShiftRightLogical %v4uint %20813 %845 + %18860 = OpBitwiseAnd %v4uint %9369 %635 + %15544 = OpConvertUToF %v4float %18860 + %16689 = OpFMul %v4float %15544 %2798 + %23763 = OpCompositeExtract %uint %10943 2 + %20814 = OpCompositeConstruct %v4uint %23763 %23763 %23763 %23763 + %9370 = OpShiftRightLogical %v4uint %20814 %845 + %18861 = OpBitwiseAnd %v4uint %9370 %635 + %15545 = OpConvertUToF %v4float %18861 + %16690 = OpFMul %v4float %15545 %2798 + %23764 = OpCompositeExtract %uint %10943 3 + %20815 = OpCompositeConstruct %v4uint %23764 %23764 %23764 %23764 + %9371 = OpShiftRightLogical %v4uint %20815 %845 + %18862 = OpBitwiseAnd %v4uint %9371 %635 + %18735 = OpConvertUToF %v4float %18862 + %9887 = OpFMul %v4float %18735 %2798 + OpBranch %16224 + %14585 = OpLabel + %22207 = OpCompositeExtract %uint %10943 0 + %20236 = OpCompositeConstruct %v4uint %22207 %22207 %22207 %22207 + %9372 = OpShiftRightLogical %v4uint %20236 %653 + %19030 = OpBitwiseAnd %v4uint %9372 %1611 + %13986 = OpConvertUToF %v4float %19030 + %19235 = OpVectorTimesScalar %v4float %13986 %float_0_00392156886 + %8607 = OpCompositeExtract %uint %10943 1 + %24843 = OpCompositeConstruct %v4uint %8607 %8607 %8607 %8607 + %9373 = OpShiftRightLogical %v4uint %24843 %653 + %19031 = OpBitwiseAnd %v4uint %9373 %1611 + %13987 = OpConvertUToF %v4float %19031 + %19236 = OpVectorTimesScalar %v4float %13987 %float_0_00392156886 + %8608 = OpCompositeExtract %uint %10943 2 + %24844 = OpCompositeConstruct %v4uint %8608 %8608 %8608 %8608 + %9374 = OpShiftRightLogical %v4uint %24844 %653 + %19032 = OpBitwiseAnd %v4uint %9374 %1611 + %13988 = OpConvertUToF %v4float %19032 + %19237 = OpVectorTimesScalar %v4float %13988 %float_0_00392156886 + %8609 = OpCompositeExtract %uint %10943 3 + %24845 = OpCompositeConstruct %v4uint %8609 %8609 %8609 %8609 + %9375 = OpShiftRightLogical %v4uint %24845 %653 + %19033 = OpBitwiseAnd %v4uint %9375 %1611 + %17178 = OpConvertUToF %v4float %19033 + %12434 = OpVectorTimesScalar %v4float %17178 %float_0_00392156886 + OpBranch %16224 + %19451 = OpLabel + %12428 = OpCompositeExtract %uint %10943 0 + %20462 = OpBitcast %float %12428 + %17206 = OpCompositeConstruct %v2float %20462 %float_0 + %11664 = OpVectorShuffle %v4float %17206 %17206 0 1 1 1 + %22193 = OpCompositeExtract %uint %10943 1 + %16232 = OpBitcast %float %22193 + %17207 = OpCompositeConstruct %v2float %16232 %float_0 + %11665 = OpVectorShuffle %v4float %17207 %17207 0 1 1 1 + %22194 = OpCompositeExtract %uint %10943 2 + %16233 = OpBitcast %float %22194 + %17208 = OpCompositeConstruct %v2float %16233 %float_0 + %11666 = OpVectorShuffle %v4float %17208 %17208 0 1 1 1 + %22195 = OpCompositeExtract %uint %10943 3 + %16234 = OpBitcast %float %22195 + %20398 = OpCompositeConstruct %v2float %16234 %float_0 + %23098 = OpVectorShuffle %v4float %20398 %20398 0 1 1 1 + OpBranch %16224 + %16224 = OpLabel + %11175 = OpPhi %v4float %23098 %19451 %12434 %14585 %9887 %7355 %9035 %7354 %9034 %8190 %9033 %8243 + %14344 = OpPhi %v4float %11666 %19451 %19237 %14585 %16690 %7355 %15836 %7354 %16672 %8190 %14606 %8243 + %15229 = OpPhi %v4float %11665 %19451 %19236 %14585 %16689 %7355 %15835 %7354 %16671 %8190 %14605 %8243 + %14518 = OpPhi %v4float %11664 %19451 %19235 %14585 %16688 %7355 %15834 %7354 %16670 %8190 %14604 %8243 + OpBranch %21263 + %15205 = OpLabel + %21584 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20259 DontFlatten + OpBranchConditional %21584 %9762 %12130 + %12130 = OpLabel + %19408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %25231 + %23877 = OpLoad %uint %19408 + %11691 = OpIAdd %uint %25231 %uint_1 + %6401 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11691 + %23652 = OpLoad %uint %6401 + %11692 = OpIAdd %uint %25231 %6555 + %6402 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11692 + %23653 = OpLoad %uint %6402 + %11693 = OpIAdd %uint %11692 %uint_1 + %24559 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11693 + %14156 = OpLoad %uint %24559 + %19670 = OpCompositeConstruct %v4uint %23877 %23652 %23653 %14156 + %17048 = OpIMul %uint %uint_2 %6555 + %13991 = OpIAdd %uint %25231 %17048 + %15233 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13991 + %23654 = OpLoad %uint %15233 + %11694 = OpIAdd %uint %13991 %uint_1 + %6476 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11694 + %24157 = OpLoad %uint %6476 + %6236 = OpIMul %uint %uint_3 %6555 + %8355 = OpIAdd %uint %25231 %6236 + %15234 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8355 + %23655 = OpLoad %uint %15234 + %11695 = OpIAdd %uint %8355 %uint_1 + %24560 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11695 + %16382 = OpLoad %uint %24560 + %20782 = OpCompositeConstruct %v4uint %23654 %24157 %23655 %16382 + OpBranch %20259 + %9762 = OpLabel + %21830 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %25231 + %23878 = OpLoad %uint %21830 + %11696 = OpIAdd %uint %25231 %uint_1 + %6403 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11696 + %23656 = OpLoad %uint %6403 + %11697 = OpIAdd %uint %25231 %uint_2 + %6404 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11697 + %23657 = OpLoad %uint %6404 + %11698 = OpIAdd %uint %25231 %uint_3 + %24561 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11698 + %14080 = OpLoad %uint %24561 + %19165 = OpCompositeConstruct %v4uint %23878 %23656 %23657 %14080 + %22501 = OpIAdd %uint %25231 %uint_4 + %24651 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22501 + %23658 = OpLoad %uint %24651 + %11699 = OpIAdd %uint %25231 %uint_5 + %6405 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11699 + %23659 = OpLoad %uint %6405 + %11700 = OpIAdd %uint %25231 %uint_6 + %6406 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11700 + %23660 = OpLoad %uint %6406 + %11701 = OpIAdd %uint %25231 %uint_7 + %24562 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11701 + %16383 = OpLoad %uint %24562 + %20783 = OpCompositeConstruct %v4uint %23658 %23659 %23660 %16383 + OpBranch %20259 + %20259 = OpLabel + %11213 = OpPhi %v4uint %20783 %9762 %20782 %12130 + %14112 = OpPhi %v4uint %19165 %9762 %19670 %12130 + OpSelectionMerge %20260 None + OpSwitch %8576 %20310 5 %8536 7 %8244 + %8244 = OpLabel + %24407 = OpCompositeExtract %uint %14112 0 + %24680 = OpExtInst %v2float %1 UnpackHalf2x16 %24407 + %10101 = OpCompositeExtract %float %24680 0 + %16056 = OpCompositeExtract %float %24680 1 + %17025 = OpCompositeExtract %uint %14112 1 + %15605 = OpExtInst %v2float %1 UnpackHalf2x16 %17025 + %10086 = OpCompositeExtract %float %15605 0 + %17481 = OpCompositeExtract %float %15605 1 + %14607 = OpCompositeConstruct %v4float %10101 %16056 %10086 %17481 + %17277 = OpCompositeExtract %uint %14112 2 + %18030 = OpExtInst %v2float %1 UnpackHalf2x16 %17277 + %10102 = OpCompositeExtract %float %18030 0 + %16057 = OpCompositeExtract %float %18030 1 + %17026 = OpCompositeExtract %uint %14112 3 + %15606 = OpExtInst %v2float %1 UnpackHalf2x16 %17026 + %10087 = OpCompositeExtract %float %15606 0 + %17482 = OpCompositeExtract %float %15606 1 + %14608 = OpCompositeConstruct %v4float %10102 %16057 %10087 %17482 + %17278 = OpCompositeExtract %uint %11213 0 + %18031 = OpExtInst %v2float %1 UnpackHalf2x16 %17278 + %10103 = OpCompositeExtract %float %18031 0 + %16058 = OpCompositeExtract %float %18031 1 + %17027 = OpCompositeExtract %uint %11213 1 + %15607 = OpExtInst %v2float %1 UnpackHalf2x16 %17027 + %10088 = OpCompositeExtract %float %15607 0 + %17483 = OpCompositeExtract %float %15607 1 + %14609 = OpCompositeConstruct %v4float %10103 %16058 %10088 %17483 + %17279 = OpCompositeExtract %uint %11213 2 + %18032 = OpExtInst %v2float %1 UnpackHalf2x16 %17279 + %10104 = OpCompositeExtract %float %18032 0 + %16059 = OpCompositeExtract %float %18032 1 + %17028 = OpCompositeExtract %uint %11213 3 + %15608 = OpExtInst %v2float %1 UnpackHalf2x16 %17028 + %10089 = OpCompositeExtract %float %15608 0 + %20671 = OpCompositeExtract %float %15608 1 + %9036 = OpCompositeConstruct %v4float %10104 %16059 %10089 %20671 + OpBranch %20260 + %8536 = OpLabel + %9723 = OpVectorShuffle %v2uint %14112 %14112 0 1 + %23356 = OpBitcast %v2int %9723 + %24782 = OpVectorShuffle %v4int %23356 %23356 0 0 1 1 + %18598 = OpShiftLeftLogical %v4int %24782 %290 + %15757 = OpShiftRightArithmetic %v4int %18598 %770 + %10907 = OpConvertSToF %v4float %15757 + %18209 = OpVectorTimesScalar %v4float %10907 %float_0_000976592302 + %25233 = OpExtInst %v4float %1 FMax %1284 %18209 + %14187 = OpVectorShuffle %v2uint %14112 %14112 2 3 + %9407 = OpBitcast %v2int %14187 + %24783 = OpVectorShuffle %v4int %9407 %9407 0 0 1 1 + %18599 = OpShiftLeftLogical %v4int %24783 %290 + %15758 = OpShiftRightArithmetic %v4int %18599 %770 + %10908 = OpConvertSToF %v4float %15758 + %18210 = OpVectorTimesScalar %v4float %10908 %float_0_000976592302 + %25234 = OpExtInst %v4float %1 FMax %1284 %18210 + %14188 = OpVectorShuffle %v2uint %11213 %11213 0 1 + %9408 = OpBitcast %v2int %14188 + %24784 = OpVectorShuffle %v4int %9408 %9408 0 0 1 1 + %18600 = OpShiftLeftLogical %v4int %24784 %290 + %15759 = OpShiftRightArithmetic %v4int %18600 %770 + %10913 = OpConvertSToF %v4float %15759 + %18211 = OpVectorTimesScalar %v4float %10913 %float_0_000976592302 + %25235 = OpExtInst %v4float %1 FMax %1284 %18211 + %14189 = OpVectorShuffle %v2uint %11213 %11213 2 3 + %9409 = OpBitcast %v2int %14189 + %24785 = OpVectorShuffle %v4int %9409 %9409 0 0 1 1 + %18601 = OpShiftLeftLogical %v4int %24785 %290 + %15760 = OpShiftRightArithmetic %v4int %18601 %770 + %10914 = OpConvertSToF %v4float %15760 + %21439 = OpVectorTimesScalar %v4float %10914 %float_0_000976592302 + %17250 = OpExtInst %v4float %1 FMax %1284 %21439 + OpBranch %20260 + %20310 = OpLabel + %9763 = OpVectorShuffle %v2uint %14112 %14112 0 1 + %20825 = OpBitcast %v2float %9763 + %7035 = OpCompositeExtract %float %20825 0 + %13418 = OpCompositeExtract %float %20825 1 + %17016 = OpCompositeConstruct %v4float %7035 %13418 %float_0 %float_0 + %16856 = OpVectorShuffle %v2uint %14112 %14112 2 3 + %14173 = OpBitcast %v2float %16856 + %7036 = OpCompositeExtract %float %14173 0 + %13419 = OpCompositeExtract %float %14173 1 + %17017 = OpCompositeConstruct %v4float %7036 %13419 %float_0 %float_0 + %16857 = OpVectorShuffle %v2uint %11213 %11213 0 1 + %14174 = OpBitcast %v2float %16857 + %7037 = OpCompositeExtract %float %14174 0 + %13420 = OpCompositeExtract %float %14174 1 + %17018 = OpCompositeConstruct %v4float %7037 %13420 %float_0 %float_0 + %16858 = OpVectorShuffle %v2uint %11213 %11213 2 3 + %14175 = OpBitcast %v2float %16858 + %7039 = OpCompositeExtract %float %14175 0 + %16648 = OpCompositeExtract %float %14175 1 + %9037 = OpCompositeConstruct %v4float %7039 %16648 %float_0 %float_0 + OpBranch %20260 + %20260 = OpLabel + %11176 = OpPhi %v4float %9037 %20310 %17250 %8536 %9036 %8244 + %14345 = OpPhi %v4float %17018 %20310 %25235 %8536 %14609 %8244 + %15230 = OpPhi %v4float %17017 %20310 %25234 %8536 %14608 %8244 + %14519 = OpPhi %v4float %17016 %20310 %25233 %8536 %14607 %8244 + OpBranch %21263 + %21263 = OpLabel + %11177 = OpPhi %v4float %11176 %20260 %11175 %16224 + %14346 = OpPhi %v4float %14345 %20260 %14344 %16224 + %13804 = OpPhi %v4float %15230 %20260 %15229 %16224 + %8403 = OpPhi %v4float %14519 %20260 %14518 %16224 + %11861 = OpUGreaterThanEqual %bool %17238 %uint_4 + OpSelectionMerge %21267 DontFlatten + OpBranchConditional %11861 %20977 %21267 + %20977 = OpLabel + %11079 = OpIMul %uint %uint_80 %8858 + %23069 = OpFMul %float %11052 %float_0_5 + %8114 = OpIAdd %uint %25231 %11079 + OpSelectionMerge %21264 DontFlatten + OpBranchConditional %23279 %15206 %16570 + %16570 = OpLabel + %19163 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20298 DontFlatten + OpBranchConditional %19163 %9764 %12131 + %12131 = OpLabel + %19409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8114 + %23879 = OpLoad %uint %19409 + %11702 = OpIAdd %uint %8114 %6555 + %6477 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11702 + %24158 = OpLoad %uint %6477 + %6237 = OpIMul %uint %uint_2 %6555 + %8356 = OpIAdd %uint %8114 %6237 + %15310 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8356 + %24159 = OpLoad %uint %15310 + %6238 = OpIMul %uint %uint_3 %6555 + %8357 = OpIAdd %uint %8114 %6238 + %14322 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8357 + %16384 = OpLoad %uint %14322 + %20784 = OpCompositeConstruct %v4uint %23879 %24158 %24159 %16384 + OpBranch %20298 + %9764 = OpLabel + %21831 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8114 + %23880 = OpLoad %uint %21831 + %11703 = OpIAdd %uint %8114 %uint_1 + %6407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11703 + %23661 = OpLoad %uint %6407 + %11704 = OpIAdd %uint %8114 %uint_2 + %6408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11704 + %23662 = OpLoad %uint %6408 + %11705 = OpIAdd %uint %8114 %uint_3 + %24563 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11705 + %16385 = OpLoad %uint %24563 + %20785 = OpCompositeConstruct %v4uint %23880 %23661 %23662 %16385 + OpBranch %20298 + %20298 = OpLabel + %10944 = OpPhi %v4uint %20785 %9764 %20784 %12131 + OpSelectionMerge %16225 None + OpSwitch %8576 %19452 0 %14586 1 %14586 2 %7357 10 %7357 3 %7356 12 %7356 4 %8191 6 %8245 + %8245 = OpLabel + %24408 = OpCompositeExtract %uint %10944 0 + %24681 = OpExtInst %v2float %1 UnpackHalf2x16 %24408 + %10090 = OpCompositeExtract %float %24681 0 + %17484 = OpCompositeExtract %float %24681 1 + %14610 = OpCompositeConstruct %v4float %10090 %17484 %float_0 %float_0 + %17280 = OpCompositeExtract %uint %10944 1 + %18033 = OpExtInst %v2float %1 UnpackHalf2x16 %17280 + %10091 = OpCompositeExtract %float %18033 0 + %17485 = OpCompositeExtract %float %18033 1 + %14611 = OpCompositeConstruct %v4float %10091 %17485 %float_0 %float_0 + %17281 = OpCompositeExtract %uint %10944 2 + %18034 = OpExtInst %v2float %1 UnpackHalf2x16 %17281 + %10092 = OpCompositeExtract %float %18034 0 + %17486 = OpCompositeExtract %float %18034 1 + %14612 = OpCompositeConstruct %v4float %10092 %17486 %float_0 %float_0 + %17282 = OpCompositeExtract %uint %10944 3 + %18035 = OpExtInst %v2float %1 UnpackHalf2x16 %17282 + %10093 = OpCompositeExtract %float %18035 0 + %20672 = OpCompositeExtract %float %18035 1 + %9038 = OpCompositeConstruct %v4float %10093 %20672 %float_0 %float_0 + OpBranch %16225 + %8191 = OpLabel + %12429 = OpCompositeExtract %uint %10944 0 + %22686 = OpBitcast %int %12429 + %18206 = OpCompositeConstruct %v2int %22686 %22686 + %18353 = OpShiftLeftLogical %v2int %18206 %1959 + %13339 = OpShiftRightArithmetic %v2int %18353 %2151 + %10915 = OpConvertSToF %v2float %13339 + %18251 = OpVectorTimesScalar %v2float %10915 %float_0_000976592302 + %24074 = OpExtInst %v2float %1 FMax %73 %18251 + %24334 = OpCompositeExtract %float %24074 0 + %15575 = OpCompositeExtract %float %24074 1 + %16673 = OpCompositeConstruct %v4float %24334 %15575 %float_0 %float_0 + %19525 = OpCompositeExtract %uint %10944 1 + %16036 = OpBitcast %int %19525 + %18207 = OpCompositeConstruct %v2int %16036 %16036 + %18354 = OpShiftLeftLogical %v2int %18207 %1959 + %13340 = OpShiftRightArithmetic %v2int %18354 %2151 + %10916 = OpConvertSToF %v2float %13340 + %18252 = OpVectorTimesScalar %v2float %10916 %float_0_000976592302 + %24075 = OpExtInst %v2float %1 FMax %73 %18252 + %24335 = OpCompositeExtract %float %24075 0 + %15576 = OpCompositeExtract %float %24075 1 + %16674 = OpCompositeConstruct %v4float %24335 %15576 %float_0 %float_0 + %19526 = OpCompositeExtract %uint %10944 2 + %16037 = OpBitcast %int %19526 + %18208 = OpCompositeConstruct %v2int %16037 %16037 + %18355 = OpShiftLeftLogical %v2int %18208 %1959 + %13341 = OpShiftRightArithmetic %v2int %18355 %2151 + %10917 = OpConvertSToF %v2float %13341 + %18253 = OpVectorTimesScalar %v2float %10917 %float_0_000976592302 + %24076 = OpExtInst %v2float %1 FMax %73 %18253 + %24336 = OpCompositeExtract %float %24076 0 + %15577 = OpCompositeExtract %float %24076 1 + %16675 = OpCompositeConstruct %v4float %24336 %15577 %float_0 %float_0 + %19527 = OpCompositeExtract %uint %10944 3 + %16038 = OpBitcast %int %19527 + %18212 = OpCompositeConstruct %v2int %16038 %16038 + %18356 = OpShiftLeftLogical %v2int %18212 %1959 + %13342 = OpShiftRightArithmetic %v2int %18356 %2151 + %10918 = OpConvertSToF %v2float %13342 + %18254 = OpVectorTimesScalar %v2float %10918 %float_0_000976592302 + %24077 = OpExtInst %v2float %1 FMax %73 %18254 + %24337 = OpCompositeExtract %float %24077 0 + %18765 = OpCompositeExtract %float %24077 1 + %9039 = OpCompositeConstruct %v4float %24337 %18765 %float_0 %float_0 + OpBranch %16225 + %7356 = OpLabel + %22208 = OpCompositeExtract %uint %10944 0 + %20237 = OpCompositeConstruct %v3uint %22208 %22208 %22208 + %11026 = OpShiftRightLogical %v3uint %20237 %2996 + %24042 = OpBitwiseAnd %v3uint %11026 %261 + %18592 = OpBitwiseAnd %v3uint %24042 %1126 + %23444 = OpShiftRightLogical %v3uint %24042 %2828 + %16589 = OpIEqual %v3bool %23444 %2578 + %11343 = OpExtInst %v3int %1 FindUMsb %18592 + %10777 = OpBitcast %v3uint %11343 + %6270 = OpISub %v3uint %2828 %10777 + %8724 = OpIAdd %v3uint %10777 %2360 + %10355 = OpSelect %v3uint %16589 %8724 %23444 + %23256 = OpShiftLeftLogical %v3uint %18592 %6270 + %18846 = OpBitwiseAnd %v3uint %23256 %1126 + %10919 = OpSelect %v3uint %16589 %18846 %18592 + %24573 = OpIAdd %v3uint %10355 %1018 + %20355 = OpShiftLeftLogical %v3uint %24573 %393 + %16298 = OpShiftLeftLogical %v3uint %10919 %141 + %22400 = OpBitwiseOr %v3uint %20355 %16298 + %13828 = OpIEqual %v3bool %24042 %2578 + %16966 = OpSelect %v3uint %13828 %2578 %22400 + %10707 = OpBitcast %v3float %16966 + %19368 = OpShiftRightLogical %uint %22208 %uint_30 + %18450 = OpConvertUToF %float %19368 + %15907 = OpFMul %float %18450 %float_0_333333343 + %21446 = OpCompositeExtract %float %10707 0 + %10841 = OpCompositeExtract %float %10707 1 + %7836 = OpCompositeExtract %float %10707 2 + %15837 = OpCompositeConstruct %v4float %21446 %10841 %7836 %15907 + %10232 = OpCompositeExtract %uint %10944 1 + %13585 = OpCompositeConstruct %v3uint %10232 %10232 %10232 + %11027 = OpShiftRightLogical %v3uint %13585 %2996 + %24043 = OpBitwiseAnd %v3uint %11027 %261 + %18593 = OpBitwiseAnd %v3uint %24043 %1126 + %23445 = OpShiftRightLogical %v3uint %24043 %2828 + %16590 = OpIEqual %v3bool %23445 %2578 + %11344 = OpExtInst %v3int %1 FindUMsb %18593 + %10778 = OpBitcast %v3uint %11344 + %6271 = OpISub %v3uint %2828 %10778 + %8725 = OpIAdd %v3uint %10778 %2360 + %10356 = OpSelect %v3uint %16590 %8725 %23445 + %23257 = OpShiftLeftLogical %v3uint %18593 %6271 + %18847 = OpBitwiseAnd %v3uint %23257 %1126 + %10920 = OpSelect %v3uint %16590 %18847 %18593 + %24574 = OpIAdd %v3uint %10356 %1018 + %20356 = OpShiftLeftLogical %v3uint %24574 %393 + %16299 = OpShiftLeftLogical %v3uint %10920 %141 + %22401 = OpBitwiseOr %v3uint %20356 %16299 + %13829 = OpIEqual %v3bool %24043 %2578 + %16967 = OpSelect %v3uint %13829 %2578 %22401 + %10708 = OpBitcast %v3float %16967 + %19369 = OpShiftRightLogical %uint %10232 %uint_30 + %18451 = OpConvertUToF %float %19369 + %15908 = OpFMul %float %18451 %float_0_333333343 + %21447 = OpCompositeExtract %float %10708 0 + %10842 = OpCompositeExtract %float %10708 1 + %7837 = OpCompositeExtract %float %10708 2 + %15838 = OpCompositeConstruct %v4float %21447 %10842 %7837 %15908 + %10233 = OpCompositeExtract %uint %10944 2 + %13586 = OpCompositeConstruct %v3uint %10233 %10233 %10233 + %11028 = OpShiftRightLogical %v3uint %13586 %2996 + %24044 = OpBitwiseAnd %v3uint %11028 %261 + %18594 = OpBitwiseAnd %v3uint %24044 %1126 + %23446 = OpShiftRightLogical %v3uint %24044 %2828 + %16591 = OpIEqual %v3bool %23446 %2578 + %11345 = OpExtInst %v3int %1 FindUMsb %18594 + %10779 = OpBitcast %v3uint %11345 + %6272 = OpISub %v3uint %2828 %10779 + %8726 = OpIAdd %v3uint %10779 %2360 + %10357 = OpSelect %v3uint %16591 %8726 %23446 + %23258 = OpShiftLeftLogical %v3uint %18594 %6272 + %18848 = OpBitwiseAnd %v3uint %23258 %1126 + %10921 = OpSelect %v3uint %16591 %18848 %18594 + %24575 = OpIAdd %v3uint %10357 %1018 + %20357 = OpShiftLeftLogical %v3uint %24575 %393 + %16300 = OpShiftLeftLogical %v3uint %10921 %141 + %22402 = OpBitwiseOr %v3uint %20357 %16300 + %13830 = OpIEqual %v3bool %24044 %2578 + %16968 = OpSelect %v3uint %13830 %2578 %22402 + %10709 = OpBitcast %v3float %16968 + %19370 = OpShiftRightLogical %uint %10233 %uint_30 + %18452 = OpConvertUToF %float %19370 + %15909 = OpFMul %float %18452 %float_0_333333343 + %21448 = OpCompositeExtract %float %10709 0 + %10843 = OpCompositeExtract %float %10709 1 + %7838 = OpCompositeExtract %float %10709 2 + %15839 = OpCompositeConstruct %v4float %21448 %10843 %7838 %15909 + %10234 = OpCompositeExtract %uint %10944 3 + %13587 = OpCompositeConstruct %v3uint %10234 %10234 %10234 + %11029 = OpShiftRightLogical %v3uint %13587 %2996 + %24045 = OpBitwiseAnd %v3uint %11029 %261 + %18595 = OpBitwiseAnd %v3uint %24045 %1126 + %23447 = OpShiftRightLogical %v3uint %24045 %2828 + %16592 = OpIEqual %v3bool %23447 %2578 + %11346 = OpExtInst %v3int %1 FindUMsb %18595 + %10780 = OpBitcast %v3uint %11346 + %6273 = OpISub %v3uint %2828 %10780 + %8727 = OpIAdd %v3uint %10780 %2360 + %10358 = OpSelect %v3uint %16592 %8727 %23447 + %23259 = OpShiftLeftLogical %v3uint %18595 %6273 + %18849 = OpBitwiseAnd %v3uint %23259 %1126 + %10922 = OpSelect %v3uint %16592 %18849 %18595 + %24576 = OpIAdd %v3uint %10358 %1018 + %20358 = OpShiftLeftLogical %v3uint %24576 %393 + %16301 = OpShiftLeftLogical %v3uint %10922 %141 + %22403 = OpBitwiseOr %v3uint %20358 %16301 + %13831 = OpIEqual %v3bool %24045 %2578 + %16969 = OpSelect %v3uint %13831 %2578 %22403 + %10710 = OpBitcast %v3float %16969 + %19371 = OpShiftRightLogical %uint %10234 %uint_30 + %18453 = OpConvertUToF %float %19371 + %15910 = OpFMul %float %18453 %float_0_333333343 + %21449 = OpCompositeExtract %float %10710 0 + %10844 = OpCompositeExtract %float %10710 1 + %11030 = OpCompositeExtract %float %10710 2 + %9040 = OpCompositeConstruct %v4float %21449 %10844 %11030 %15910 + OpBranch %16225 + %7357 = OpLabel + %22209 = OpCompositeExtract %uint %10944 0 + %20238 = OpCompositeConstruct %v4uint %22209 %22209 %22209 %22209 + %9376 = OpShiftRightLogical %v4uint %20238 %845 + %18863 = OpBitwiseAnd %v4uint %9376 %635 + %15546 = OpConvertUToF %v4float %18863 + %16691 = OpFMul %v4float %15546 %2798 + %23765 = OpCompositeExtract %uint %10944 1 + %20816 = OpCompositeConstruct %v4uint %23765 %23765 %23765 %23765 + %9377 = OpShiftRightLogical %v4uint %20816 %845 + %18864 = OpBitwiseAnd %v4uint %9377 %635 + %15547 = OpConvertUToF %v4float %18864 + %16692 = OpFMul %v4float %15547 %2798 + %23766 = OpCompositeExtract %uint %10944 2 + %20817 = OpCompositeConstruct %v4uint %23766 %23766 %23766 %23766 + %9378 = OpShiftRightLogical %v4uint %20817 %845 + %18865 = OpBitwiseAnd %v4uint %9378 %635 + %15548 = OpConvertUToF %v4float %18865 + %16693 = OpFMul %v4float %15548 %2798 + %23767 = OpCompositeExtract %uint %10944 3 + %20818 = OpCompositeConstruct %v4uint %23767 %23767 %23767 %23767 + %9379 = OpShiftRightLogical %v4uint %20818 %845 + %18866 = OpBitwiseAnd %v4uint %9379 %635 + %18736 = OpConvertUToF %v4float %18866 + %9888 = OpFMul %v4float %18736 %2798 + OpBranch %16225 + %14586 = OpLabel + %22210 = OpCompositeExtract %uint %10944 0 + %20239 = OpCompositeConstruct %v4uint %22210 %22210 %22210 %22210 + %9380 = OpShiftRightLogical %v4uint %20239 %653 + %19034 = OpBitwiseAnd %v4uint %9380 %1611 + %13989 = OpConvertUToF %v4float %19034 + %19238 = OpVectorTimesScalar %v4float %13989 %float_0_00392156886 + %8610 = OpCompositeExtract %uint %10944 1 + %24846 = OpCompositeConstruct %v4uint %8610 %8610 %8610 %8610 + %9381 = OpShiftRightLogical %v4uint %24846 %653 + %19035 = OpBitwiseAnd %v4uint %9381 %1611 + %13990 = OpConvertUToF %v4float %19035 + %19239 = OpVectorTimesScalar %v4float %13990 %float_0_00392156886 + %8611 = OpCompositeExtract %uint %10944 2 + %24847 = OpCompositeConstruct %v4uint %8611 %8611 %8611 %8611 + %9382 = OpShiftRightLogical %v4uint %24847 %653 + %19036 = OpBitwiseAnd %v4uint %9382 %1611 + %13992 = OpConvertUToF %v4float %19036 + %19240 = OpVectorTimesScalar %v4float %13992 %float_0_00392156886 + %8612 = OpCompositeExtract %uint %10944 3 + %24848 = OpCompositeConstruct %v4uint %8612 %8612 %8612 %8612 + %9383 = OpShiftRightLogical %v4uint %24848 %653 + %19037 = OpBitwiseAnd %v4uint %9383 %1611 + %17179 = OpConvertUToF %v4float %19037 + %12435 = OpVectorTimesScalar %v4float %17179 %float_0_00392156886 + OpBranch %16225 + %19452 = OpLabel + %12430 = OpCompositeExtract %uint %10944 0 + %20463 = OpBitcast %float %12430 + %17209 = OpCompositeConstruct %v2float %20463 %float_0 + %11667 = OpVectorShuffle %v4float %17209 %17209 0 1 1 1 + %22196 = OpCompositeExtract %uint %10944 1 + %16235 = OpBitcast %float %22196 + %17210 = OpCompositeConstruct %v2float %16235 %float_0 + %11668 = OpVectorShuffle %v4float %17210 %17210 0 1 1 1 + %22197 = OpCompositeExtract %uint %10944 2 + %16236 = OpBitcast %float %22197 + %17211 = OpCompositeConstruct %v2float %16236 %float_0 + %11669 = OpVectorShuffle %v4float %17211 %17211 0 1 1 1 + %22198 = OpCompositeExtract %uint %10944 3 + %16237 = OpBitcast %float %22198 + %20399 = OpCompositeConstruct %v2float %16237 %float_0 + %23099 = OpVectorShuffle %v4float %20399 %20399 0 1 1 1 + OpBranch %16225 + %16225 = OpLabel + %11178 = OpPhi %v4float %23099 %19452 %12435 %14586 %9888 %7357 %9040 %7356 %9039 %8191 %9038 %8245 + %14347 = OpPhi %v4float %11669 %19452 %19240 %14586 %16693 %7357 %15839 %7356 %16675 %8191 %14612 %8245 + %15231 = OpPhi %v4float %11668 %19452 %19239 %14586 %16692 %7357 %15838 %7356 %16674 %8191 %14611 %8245 + %14520 = OpPhi %v4float %11667 %19452 %19238 %14586 %16691 %7357 %15837 %7356 %16673 %8191 %14610 %8245 + OpBranch %21264 + %15206 = OpLabel + %21585 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20261 DontFlatten + OpBranchConditional %21585 %9765 %12132 + %12132 = OpLabel + %19410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8114 + %23881 = OpLoad %uint %19410 + %11706 = OpIAdd %uint %8114 %uint_1 + %6409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11706 + %23663 = OpLoad %uint %6409 + %11707 = OpIAdd %uint %8114 %6555 + %6410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11707 + %23664 = OpLoad %uint %6410 + %11708 = OpIAdd %uint %11707 %uint_1 + %24564 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11708 + %14157 = OpLoad %uint %24564 + %19671 = OpCompositeConstruct %v4uint %23881 %23663 %23664 %14157 + %17049 = OpIMul %uint %uint_2 %6555 + %13993 = OpIAdd %uint %8114 %17049 + %15235 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13993 + %23665 = OpLoad %uint %15235 + %11709 = OpIAdd %uint %13993 %uint_1 + %6478 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11709 + %24160 = OpLoad %uint %6478 + %6239 = OpIMul %uint %uint_3 %6555 + %8358 = OpIAdd %uint %8114 %6239 + %15236 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8358 + %23666 = OpLoad %uint %15236 + %11710 = OpIAdd %uint %8358 %uint_1 + %24565 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11710 + %16386 = OpLoad %uint %24565 + %20786 = OpCompositeConstruct %v4uint %23665 %24160 %23666 %16386 + OpBranch %20261 + %9765 = OpLabel + %21832 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8114 + %23882 = OpLoad %uint %21832 + %11711 = OpIAdd %uint %8114 %uint_1 + %6411 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11711 + %23667 = OpLoad %uint %6411 + %11712 = OpIAdd %uint %8114 %uint_2 + %6412 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11712 + %23668 = OpLoad %uint %6412 + %11713 = OpIAdd %uint %8114 %uint_3 + %24566 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11713 + %14081 = OpLoad %uint %24566 + %19166 = OpCompositeConstruct %v4uint %23882 %23667 %23668 %14081 + %22502 = OpIAdd %uint %8114 %uint_4 + %24652 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22502 + %23669 = OpLoad %uint %24652 + %11714 = OpIAdd %uint %8114 %uint_5 + %6413 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11714 + %23670 = OpLoad %uint %6413 + %11715 = OpIAdd %uint %8114 %uint_6 + %6414 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11715 + %23671 = OpLoad %uint %6414 + %11716 = OpIAdd %uint %8114 %uint_7 + %24567 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11716 + %16387 = OpLoad %uint %24567 + %20787 = OpCompositeConstruct %v4uint %23669 %23670 %23671 %16387 + OpBranch %20261 + %20261 = OpLabel + %11214 = OpPhi %v4uint %20787 %9765 %20786 %12132 + %14113 = OpPhi %v4uint %19166 %9765 %19671 %12132 + OpSelectionMerge %20262 None + OpSwitch %8576 %20311 5 %8537 7 %8246 + %8246 = OpLabel + %24409 = OpCompositeExtract %uint %14113 0 + %24682 = OpExtInst %v2float %1 UnpackHalf2x16 %24409 + %10105 = OpCompositeExtract %float %24682 0 + %16060 = OpCompositeExtract %float %24682 1 + %17029 = OpCompositeExtract %uint %14113 1 + %15609 = OpExtInst %v2float %1 UnpackHalf2x16 %17029 + %10094 = OpCompositeExtract %float %15609 0 + %17487 = OpCompositeExtract %float %15609 1 + %14613 = OpCompositeConstruct %v4float %10105 %16060 %10094 %17487 + %17283 = OpCompositeExtract %uint %14113 2 + %18036 = OpExtInst %v2float %1 UnpackHalf2x16 %17283 + %10106 = OpCompositeExtract %float %18036 0 + %16061 = OpCompositeExtract %float %18036 1 + %17030 = OpCompositeExtract %uint %14113 3 + %15610 = OpExtInst %v2float %1 UnpackHalf2x16 %17030 + %10095 = OpCompositeExtract %float %15610 0 + %17488 = OpCompositeExtract %float %15610 1 + %14614 = OpCompositeConstruct %v4float %10106 %16061 %10095 %17488 + %17284 = OpCompositeExtract %uint %11214 0 + %18037 = OpExtInst %v2float %1 UnpackHalf2x16 %17284 + %10107 = OpCompositeExtract %float %18037 0 + %16062 = OpCompositeExtract %float %18037 1 + %17031 = OpCompositeExtract %uint %11214 1 + %15611 = OpExtInst %v2float %1 UnpackHalf2x16 %17031 + %10096 = OpCompositeExtract %float %15611 0 + %17489 = OpCompositeExtract %float %15611 1 + %14615 = OpCompositeConstruct %v4float %10107 %16062 %10096 %17489 + %17285 = OpCompositeExtract %uint %11214 2 + %18038 = OpExtInst %v2float %1 UnpackHalf2x16 %17285 + %10108 = OpCompositeExtract %float %18038 0 + %16063 = OpCompositeExtract %float %18038 1 + %17032 = OpCompositeExtract %uint %11214 3 + %15612 = OpExtInst %v2float %1 UnpackHalf2x16 %17032 + %10097 = OpCompositeExtract %float %15612 0 + %20673 = OpCompositeExtract %float %15612 1 + %9041 = OpCompositeConstruct %v4float %10108 %16063 %10097 %20673 + OpBranch %20262 + %8537 = OpLabel + %9724 = OpVectorShuffle %v2uint %14113 %14113 0 1 + %23357 = OpBitcast %v2int %9724 + %24786 = OpVectorShuffle %v4int %23357 %23357 0 0 1 1 + %18602 = OpShiftLeftLogical %v4int %24786 %290 + %15761 = OpShiftRightArithmetic %v4int %18602 %770 + %10923 = OpConvertSToF %v4float %15761 + %18213 = OpVectorTimesScalar %v4float %10923 %float_0_000976592302 + %25236 = OpExtInst %v4float %1 FMax %1284 %18213 + %14190 = OpVectorShuffle %v2uint %14113 %14113 2 3 + %9410 = OpBitcast %v2int %14190 + %24787 = OpVectorShuffle %v4int %9410 %9410 0 0 1 1 + %18603 = OpShiftLeftLogical %v4int %24787 %290 + %15762 = OpShiftRightArithmetic %v4int %18603 %770 + %10924 = OpConvertSToF %v4float %15762 + %18214 = OpVectorTimesScalar %v4float %10924 %float_0_000976592302 + %25237 = OpExtInst %v4float %1 FMax %1284 %18214 + %14191 = OpVectorShuffle %v2uint %11214 %11214 0 1 + %9411 = OpBitcast %v2int %14191 + %24788 = OpVectorShuffle %v4int %9411 %9411 0 0 1 1 + %18604 = OpShiftLeftLogical %v4int %24788 %290 + %15763 = OpShiftRightArithmetic %v4int %18604 %770 + %10925 = OpConvertSToF %v4float %15763 + %18215 = OpVectorTimesScalar %v4float %10925 %float_0_000976592302 + %25238 = OpExtInst %v4float %1 FMax %1284 %18215 + %14192 = OpVectorShuffle %v2uint %11214 %11214 2 3 + %9412 = OpBitcast %v2int %14192 + %24789 = OpVectorShuffle %v4int %9412 %9412 0 0 1 1 + %18605 = OpShiftLeftLogical %v4int %24789 %290 + %15764 = OpShiftRightArithmetic %v4int %18605 %770 + %10926 = OpConvertSToF %v4float %15764 + %21440 = OpVectorTimesScalar %v4float %10926 %float_0_000976592302 + %17251 = OpExtInst %v4float %1 FMax %1284 %21440 + OpBranch %20262 + %20311 = OpLabel + %9766 = OpVectorShuffle %v2uint %14113 %14113 0 1 + %20826 = OpBitcast %v2float %9766 + %7040 = OpCompositeExtract %float %20826 0 + %13421 = OpCompositeExtract %float %20826 1 + %17019 = OpCompositeConstruct %v4float %7040 %13421 %float_0 %float_0 + %16859 = OpVectorShuffle %v2uint %14113 %14113 2 3 + %14176 = OpBitcast %v2float %16859 + %7041 = OpCompositeExtract %float %14176 0 + %13422 = OpCompositeExtract %float %14176 1 + %17020 = OpCompositeConstruct %v4float %7041 %13422 %float_0 %float_0 + %16860 = OpVectorShuffle %v2uint %11214 %11214 0 1 + %14177 = OpBitcast %v2float %16860 + %7042 = OpCompositeExtract %float %14177 0 + %13423 = OpCompositeExtract %float %14177 1 + %17021 = OpCompositeConstruct %v4float %7042 %13423 %float_0 %float_0 + %16861 = OpVectorShuffle %v2uint %11214 %11214 2 3 + %14178 = OpBitcast %v2float %16861 + %7043 = OpCompositeExtract %float %14178 0 + %16649 = OpCompositeExtract %float %14178 1 + %9042 = OpCompositeConstruct %v4float %7043 %16649 %float_0 %float_0 + OpBranch %20262 + %20262 = OpLabel + %11179 = OpPhi %v4float %9042 %20311 %17251 %8537 %9041 %8246 + %14348 = OpPhi %v4float %17021 %20311 %25238 %8537 %14615 %8246 + %15232 = OpPhi %v4float %17020 %20311 %25237 %8537 %14614 %8246 + %14521 = OpPhi %v4float %17019 %20311 %25236 %8537 %14613 %8246 + OpBranch %21264 + %21264 = OpLabel + %11180 = OpPhi %v4float %11179 %20262 %11178 %16225 + %14349 = OpPhi %v4float %14348 %20262 %14347 %16225 + %12949 = OpPhi %v4float %15232 %20262 %15231 %16225 + %13946 = OpPhi %v4float %14521 %20262 %14520 %16225 + %17241 = OpFAdd %v4float %8403 %13946 + %23297 = OpFAdd %v4float %13804 %12949 + %8082 = OpFAdd %v4float %14346 %14349 + %20755 = OpFAdd %v4float %11177 %11180 + %14461 = OpUGreaterThanEqual %bool %17238 %uint_6 + OpSelectionMerge %24264 DontFlatten + OpBranchConditional %14461 %9905 %24264 + %9905 = OpLabel + %14258 = OpShiftLeftLogical %uint %uint_1 %9130 + %12090 = OpFMul %float %11052 %float_0_25 + %20988 = OpIAdd %uint %25231 %14258 + OpSelectionMerge %21265 DontFlatten + OpBranchConditional %23279 %15207 %16571 + %16571 = OpLabel + %19167 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20299 DontFlatten + OpBranchConditional %19167 %9767 %12133 + %12133 = OpLabel + %19411 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23883 = OpLoad %uint %19411 + %11717 = OpIAdd %uint %20988 %6555 + %6479 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11717 + %24161 = OpLoad %uint %6479 + %6240 = OpIMul %uint %uint_2 %6555 + %8359 = OpIAdd %uint %20988 %6240 + %15311 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8359 + %24162 = OpLoad %uint %15311 + %6241 = OpIMul %uint %uint_3 %6555 + %8360 = OpIAdd %uint %20988 %6241 + %14323 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8360 + %16388 = OpLoad %uint %14323 + %20788 = OpCompositeConstruct %v4uint %23883 %24161 %24162 %16388 + OpBranch %20299 + %9767 = OpLabel + %21833 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23884 = OpLoad %uint %21833 + %11718 = OpIAdd %uint %20988 %uint_1 + %6415 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11718 + %23672 = OpLoad %uint %6415 + %11719 = OpIAdd %uint %20988 %uint_2 + %6416 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11719 + %23673 = OpLoad %uint %6416 + %11720 = OpIAdd %uint %20988 %uint_3 + %24568 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11720 + %16389 = OpLoad %uint %24568 + %20789 = OpCompositeConstruct %v4uint %23884 %23672 %23673 %16389 + OpBranch %20299 + %20299 = OpLabel + %10945 = OpPhi %v4uint %20789 %9767 %20788 %12133 + OpSelectionMerge %16226 None + OpSwitch %8576 %19453 0 %14587 1 %14587 2 %7359 10 %7359 3 %7358 12 %7358 4 %8192 6 %8247 + %8247 = OpLabel + %24410 = OpCompositeExtract %uint %10945 0 + %24683 = OpExtInst %v2float %1 UnpackHalf2x16 %24410 + %10098 = OpCompositeExtract %float %24683 0 + %17490 = OpCompositeExtract %float %24683 1 + %14616 = OpCompositeConstruct %v4float %10098 %17490 %float_0 %float_0 + %17286 = OpCompositeExtract %uint %10945 1 + %18039 = OpExtInst %v2float %1 UnpackHalf2x16 %17286 + %10099 = OpCompositeExtract %float %18039 0 + %17491 = OpCompositeExtract %float %18039 1 + %14617 = OpCompositeConstruct %v4float %10099 %17491 %float_0 %float_0 + %17287 = OpCompositeExtract %uint %10945 2 + %18040 = OpExtInst %v2float %1 UnpackHalf2x16 %17287 + %10100 = OpCompositeExtract %float %18040 0 + %17492 = OpCompositeExtract %float %18040 1 + %14618 = OpCompositeConstruct %v4float %10100 %17492 %float_0 %float_0 + %17288 = OpCompositeExtract %uint %10945 3 + %18041 = OpExtInst %v2float %1 UnpackHalf2x16 %17288 + %10109 = OpCompositeExtract %float %18041 0 + %20674 = OpCompositeExtract %float %18041 1 + %9043 = OpCompositeConstruct %v4float %10109 %20674 %float_0 %float_0 + OpBranch %16226 + %8192 = OpLabel + %12431 = OpCompositeExtract %uint %10945 0 + %22687 = OpBitcast %int %12431 + %18216 = OpCompositeConstruct %v2int %22687 %22687 + %18357 = OpShiftLeftLogical %v2int %18216 %1959 + %13343 = OpShiftRightArithmetic %v2int %18357 %2151 + %10927 = OpConvertSToF %v2float %13343 + %18255 = OpVectorTimesScalar %v2float %10927 %float_0_000976592302 + %24078 = OpExtInst %v2float %1 FMax %73 %18255 + %24338 = OpCompositeExtract %float %24078 0 + %15578 = OpCompositeExtract %float %24078 1 + %16676 = OpCompositeConstruct %v4float %24338 %15578 %float_0 %float_0 + %19528 = OpCompositeExtract %uint %10945 1 + %16039 = OpBitcast %int %19528 + %18217 = OpCompositeConstruct %v2int %16039 %16039 + %18358 = OpShiftLeftLogical %v2int %18217 %1959 + %13344 = OpShiftRightArithmetic %v2int %18358 %2151 + %10928 = OpConvertSToF %v2float %13344 + %18256 = OpVectorTimesScalar %v2float %10928 %float_0_000976592302 + %24079 = OpExtInst %v2float %1 FMax %73 %18256 + %24339 = OpCompositeExtract %float %24079 0 + %15579 = OpCompositeExtract %float %24079 1 + %16677 = OpCompositeConstruct %v4float %24339 %15579 %float_0 %float_0 + %19529 = OpCompositeExtract %uint %10945 2 + %16040 = OpBitcast %int %19529 + %18218 = OpCompositeConstruct %v2int %16040 %16040 + %18359 = OpShiftLeftLogical %v2int %18218 %1959 + %13345 = OpShiftRightArithmetic %v2int %18359 %2151 + %10929 = OpConvertSToF %v2float %13345 + %18257 = OpVectorTimesScalar %v2float %10929 %float_0_000976592302 + %24080 = OpExtInst %v2float %1 FMax %73 %18257 + %24340 = OpCompositeExtract %float %24080 0 + %15580 = OpCompositeExtract %float %24080 1 + %16678 = OpCompositeConstruct %v4float %24340 %15580 %float_0 %float_0 + %19530 = OpCompositeExtract %uint %10945 3 + %16041 = OpBitcast %int %19530 + %18219 = OpCompositeConstruct %v2int %16041 %16041 + %18360 = OpShiftLeftLogical %v2int %18219 %1959 + %13346 = OpShiftRightArithmetic %v2int %18360 %2151 + %10930 = OpConvertSToF %v2float %13346 + %18258 = OpVectorTimesScalar %v2float %10930 %float_0_000976592302 + %24081 = OpExtInst %v2float %1 FMax %73 %18258 + %24341 = OpCompositeExtract %float %24081 0 + %18766 = OpCompositeExtract %float %24081 1 + %9044 = OpCompositeConstruct %v4float %24341 %18766 %float_0 %float_0 + OpBranch %16226 + %7358 = OpLabel + %22211 = OpCompositeExtract %uint %10945 0 + %20240 = OpCompositeConstruct %v3uint %22211 %22211 %22211 + %11031 = OpShiftRightLogical %v3uint %20240 %2996 + %24046 = OpBitwiseAnd %v3uint %11031 %261 + %18596 = OpBitwiseAnd %v3uint %24046 %1126 + %23448 = OpShiftRightLogical %v3uint %24046 %2828 + %16593 = OpIEqual %v3bool %23448 %2578 + %11347 = OpExtInst %v3int %1 FindUMsb %18596 + %10781 = OpBitcast %v3uint %11347 + %6274 = OpISub %v3uint %2828 %10781 + %8728 = OpIAdd %v3uint %10781 %2360 + %10359 = OpSelect %v3uint %16593 %8728 %23448 + %23260 = OpShiftLeftLogical %v3uint %18596 %6274 + %18850 = OpBitwiseAnd %v3uint %23260 %1126 + %10931 = OpSelect %v3uint %16593 %18850 %18596 + %24577 = OpIAdd %v3uint %10359 %1018 + %20359 = OpShiftLeftLogical %v3uint %24577 %393 + %16302 = OpShiftLeftLogical %v3uint %10931 %141 + %22404 = OpBitwiseOr %v3uint %20359 %16302 + %13832 = OpIEqual %v3bool %24046 %2578 + %16970 = OpSelect %v3uint %13832 %2578 %22404 + %10711 = OpBitcast %v3float %16970 + %19372 = OpShiftRightLogical %uint %22211 %uint_30 + %18454 = OpConvertUToF %float %19372 + %15911 = OpFMul %float %18454 %float_0_333333343 + %21450 = OpCompositeExtract %float %10711 0 + %10845 = OpCompositeExtract %float %10711 1 + %7839 = OpCompositeExtract %float %10711 2 + %15840 = OpCompositeConstruct %v4float %21450 %10845 %7839 %15911 + %10235 = OpCompositeExtract %uint %10945 1 + %13588 = OpCompositeConstruct %v3uint %10235 %10235 %10235 + %11032 = OpShiftRightLogical %v3uint %13588 %2996 + %24047 = OpBitwiseAnd %v3uint %11032 %261 + %18597 = OpBitwiseAnd %v3uint %24047 %1126 + %23449 = OpShiftRightLogical %v3uint %24047 %2828 + %16594 = OpIEqual %v3bool %23449 %2578 + %11348 = OpExtInst %v3int %1 FindUMsb %18597 + %10782 = OpBitcast %v3uint %11348 + %6275 = OpISub %v3uint %2828 %10782 + %8729 = OpIAdd %v3uint %10782 %2360 + %10360 = OpSelect %v3uint %16594 %8729 %23449 + %23261 = OpShiftLeftLogical %v3uint %18597 %6275 + %18851 = OpBitwiseAnd %v3uint %23261 %1126 + %10932 = OpSelect %v3uint %16594 %18851 %18597 + %24578 = OpIAdd %v3uint %10360 %1018 + %20360 = OpShiftLeftLogical %v3uint %24578 %393 + %16303 = OpShiftLeftLogical %v3uint %10932 %141 + %22405 = OpBitwiseOr %v3uint %20360 %16303 + %13833 = OpIEqual %v3bool %24047 %2578 + %16971 = OpSelect %v3uint %13833 %2578 %22405 + %10712 = OpBitcast %v3float %16971 + %19373 = OpShiftRightLogical %uint %10235 %uint_30 + %18455 = OpConvertUToF %float %19373 + %15912 = OpFMul %float %18455 %float_0_333333343 + %21451 = OpCompositeExtract %float %10712 0 + %10846 = OpCompositeExtract %float %10712 1 + %7840 = OpCompositeExtract %float %10712 2 + %15841 = OpCompositeConstruct %v4float %21451 %10846 %7840 %15912 + %10236 = OpCompositeExtract %uint %10945 2 + %13589 = OpCompositeConstruct %v3uint %10236 %10236 %10236 + %11033 = OpShiftRightLogical %v3uint %13589 %2996 + %24048 = OpBitwiseAnd %v3uint %11033 %261 + %18606 = OpBitwiseAnd %v3uint %24048 %1126 + %23450 = OpShiftRightLogical %v3uint %24048 %2828 + %16595 = OpIEqual %v3bool %23450 %2578 + %11349 = OpExtInst %v3int %1 FindUMsb %18606 + %10783 = OpBitcast %v3uint %11349 + %6276 = OpISub %v3uint %2828 %10783 + %8730 = OpIAdd %v3uint %10783 %2360 + %10361 = OpSelect %v3uint %16595 %8730 %23450 + %23262 = OpShiftLeftLogical %v3uint %18606 %6276 + %18852 = OpBitwiseAnd %v3uint %23262 %1126 + %10933 = OpSelect %v3uint %16595 %18852 %18606 + %24579 = OpIAdd %v3uint %10361 %1018 + %20361 = OpShiftLeftLogical %v3uint %24579 %393 + %16304 = OpShiftLeftLogical %v3uint %10933 %141 + %22406 = OpBitwiseOr %v3uint %20361 %16304 + %13834 = OpIEqual %v3bool %24048 %2578 + %16972 = OpSelect %v3uint %13834 %2578 %22406 + %10713 = OpBitcast %v3float %16972 + %19374 = OpShiftRightLogical %uint %10236 %uint_30 + %18456 = OpConvertUToF %float %19374 + %15913 = OpFMul %float %18456 %float_0_333333343 + %21452 = OpCompositeExtract %float %10713 0 + %10847 = OpCompositeExtract %float %10713 1 + %7841 = OpCompositeExtract %float %10713 2 + %15842 = OpCompositeConstruct %v4float %21452 %10847 %7841 %15913 + %10237 = OpCompositeExtract %uint %10945 3 + %13590 = OpCompositeConstruct %v3uint %10237 %10237 %10237 + %11034 = OpShiftRightLogical %v3uint %13590 %2996 + %24049 = OpBitwiseAnd %v3uint %11034 %261 + %18607 = OpBitwiseAnd %v3uint %24049 %1126 + %23451 = OpShiftRightLogical %v3uint %24049 %2828 + %16596 = OpIEqual %v3bool %23451 %2578 + %11350 = OpExtInst %v3int %1 FindUMsb %18607 + %10784 = OpBitcast %v3uint %11350 + %6277 = OpISub %v3uint %2828 %10784 + %8731 = OpIAdd %v3uint %10784 %2360 + %10362 = OpSelect %v3uint %16596 %8731 %23451 + %23263 = OpShiftLeftLogical %v3uint %18607 %6277 + %18853 = OpBitwiseAnd %v3uint %23263 %1126 + %10934 = OpSelect %v3uint %16596 %18853 %18607 + %24580 = OpIAdd %v3uint %10362 %1018 + %20362 = OpShiftLeftLogical %v3uint %24580 %393 + %16305 = OpShiftLeftLogical %v3uint %10934 %141 + %22407 = OpBitwiseOr %v3uint %20362 %16305 + %13835 = OpIEqual %v3bool %24049 %2578 + %16973 = OpSelect %v3uint %13835 %2578 %22407 + %10714 = OpBitcast %v3float %16973 + %19375 = OpShiftRightLogical %uint %10237 %uint_30 + %18457 = OpConvertUToF %float %19375 + %15914 = OpFMul %float %18457 %float_0_333333343 + %21453 = OpCompositeExtract %float %10714 0 + %10848 = OpCompositeExtract %float %10714 1 + %11035 = OpCompositeExtract %float %10714 2 + %9045 = OpCompositeConstruct %v4float %21453 %10848 %11035 %15914 + OpBranch %16226 + %7359 = OpLabel + %22212 = OpCompositeExtract %uint %10945 0 + %20241 = OpCompositeConstruct %v4uint %22212 %22212 %22212 %22212 + %9384 = OpShiftRightLogical %v4uint %20241 %845 + %18867 = OpBitwiseAnd %v4uint %9384 %635 + %15549 = OpConvertUToF %v4float %18867 + %16694 = OpFMul %v4float %15549 %2798 + %23768 = OpCompositeExtract %uint %10945 1 + %20819 = OpCompositeConstruct %v4uint %23768 %23768 %23768 %23768 + %9385 = OpShiftRightLogical %v4uint %20819 %845 + %18868 = OpBitwiseAnd %v4uint %9385 %635 + %15550 = OpConvertUToF %v4float %18868 + %16695 = OpFMul %v4float %15550 %2798 + %23769 = OpCompositeExtract %uint %10945 2 + %20820 = OpCompositeConstruct %v4uint %23769 %23769 %23769 %23769 + %9386 = OpShiftRightLogical %v4uint %20820 %845 + %18869 = OpBitwiseAnd %v4uint %9386 %635 + %15551 = OpConvertUToF %v4float %18869 + %16696 = OpFMul %v4float %15551 %2798 + %23770 = OpCompositeExtract %uint %10945 3 + %20821 = OpCompositeConstruct %v4uint %23770 %23770 %23770 %23770 + %9387 = OpShiftRightLogical %v4uint %20821 %845 + %18870 = OpBitwiseAnd %v4uint %9387 %635 + %18737 = OpConvertUToF %v4float %18870 + %9889 = OpFMul %v4float %18737 %2798 + OpBranch %16226 + %14587 = OpLabel + %22213 = OpCompositeExtract %uint %10945 0 + %20242 = OpCompositeConstruct %v4uint %22213 %22213 %22213 %22213 + %9388 = OpShiftRightLogical %v4uint %20242 %653 + %19038 = OpBitwiseAnd %v4uint %9388 %1611 + %13994 = OpConvertUToF %v4float %19038 + %19241 = OpVectorTimesScalar %v4float %13994 %float_0_00392156886 + %8613 = OpCompositeExtract %uint %10945 1 + %24849 = OpCompositeConstruct %v4uint %8613 %8613 %8613 %8613 + %9389 = OpShiftRightLogical %v4uint %24849 %653 + %19039 = OpBitwiseAnd %v4uint %9389 %1611 + %13995 = OpConvertUToF %v4float %19039 + %19242 = OpVectorTimesScalar %v4float %13995 %float_0_00392156886 + %8614 = OpCompositeExtract %uint %10945 2 + %24850 = OpCompositeConstruct %v4uint %8614 %8614 %8614 %8614 + %9390 = OpShiftRightLogical %v4uint %24850 %653 + %19040 = OpBitwiseAnd %v4uint %9390 %1611 + %13996 = OpConvertUToF %v4float %19040 + %19243 = OpVectorTimesScalar %v4float %13996 %float_0_00392156886 + %8615 = OpCompositeExtract %uint %10945 3 + %24851 = OpCompositeConstruct %v4uint %8615 %8615 %8615 %8615 + %9391 = OpShiftRightLogical %v4uint %24851 %653 + %19041 = OpBitwiseAnd %v4uint %9391 %1611 + %17180 = OpConvertUToF %v4float %19041 + %12436 = OpVectorTimesScalar %v4float %17180 %float_0_00392156886 + OpBranch %16226 + %19453 = OpLabel + %12432 = OpCompositeExtract %uint %10945 0 + %20464 = OpBitcast %float %12432 + %17212 = OpCompositeConstruct %v2float %20464 %float_0 + %11670 = OpVectorShuffle %v4float %17212 %17212 0 1 1 1 + %22199 = OpCompositeExtract %uint %10945 1 + %16238 = OpBitcast %float %22199 + %17213 = OpCompositeConstruct %v2float %16238 %float_0 + %11671 = OpVectorShuffle %v4float %17213 %17213 0 1 1 1 + %22200 = OpCompositeExtract %uint %10945 2 + %16239 = OpBitcast %float %22200 + %17214 = OpCompositeConstruct %v2float %16239 %float_0 + %11672 = OpVectorShuffle %v4float %17214 %17214 0 1 1 1 + %22201 = OpCompositeExtract %uint %10945 3 + %16240 = OpBitcast %float %22201 + %20400 = OpCompositeConstruct %v2float %16240 %float_0 + %23100 = OpVectorShuffle %v4float %20400 %20400 0 1 1 1 + OpBranch %16226 + %16226 = OpLabel + %11181 = OpPhi %v4float %23100 %19453 %12436 %14587 %9889 %7359 %9045 %7358 %9044 %8192 %9043 %8247 + %14350 = OpPhi %v4float %11672 %19453 %19243 %14587 %16696 %7359 %15842 %7358 %16678 %8192 %14618 %8247 + %15237 = OpPhi %v4float %11671 %19453 %19242 %14587 %16695 %7359 %15841 %7358 %16677 %8192 %14617 %8247 + %14522 = OpPhi %v4float %11670 %19453 %19241 %14587 %16694 %7359 %15840 %7358 %16676 %8192 %14616 %8247 + OpBranch %21265 + %15207 = OpLabel + %21586 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20263 DontFlatten + OpBranchConditional %21586 %9768 %12134 + %12134 = OpLabel + %19412 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23885 = OpLoad %uint %19412 + %11721 = OpIAdd %uint %20988 %uint_1 + %6417 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11721 + %23674 = OpLoad %uint %6417 + %11722 = OpIAdd %uint %20988 %6555 + %6418 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11722 + %23675 = OpLoad %uint %6418 + %11723 = OpIAdd %uint %11722 %uint_1 + %24581 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11723 + %14158 = OpLoad %uint %24581 + %19673 = OpCompositeConstruct %v4uint %23885 %23674 %23675 %14158 + %17050 = OpIMul %uint %uint_2 %6555 + %13997 = OpIAdd %uint %20988 %17050 + %15238 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13997 + %23676 = OpLoad %uint %15238 + %11724 = OpIAdd %uint %13997 %uint_1 + %6480 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11724 + %24163 = OpLoad %uint %6480 + %6242 = OpIMul %uint %uint_3 %6555 + %8361 = OpIAdd %uint %20988 %6242 + %15239 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8361 + %23677 = OpLoad %uint %15239 + %11725 = OpIAdd %uint %8361 %uint_1 + %24582 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11725 + %16390 = OpLoad %uint %24582 + %20790 = OpCompositeConstruct %v4uint %23676 %24163 %23677 %16390 + OpBranch %20263 + %9768 = OpLabel + %21834 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23886 = OpLoad %uint %21834 + %11726 = OpIAdd %uint %20988 %uint_1 + %6419 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11726 + %23678 = OpLoad %uint %6419 + %11727 = OpIAdd %uint %20988 %uint_2 + %6420 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11727 + %23679 = OpLoad %uint %6420 + %11728 = OpIAdd %uint %20988 %uint_3 + %24583 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11728 + %14082 = OpLoad %uint %24583 + %19168 = OpCompositeConstruct %v4uint %23886 %23678 %23679 %14082 + %22503 = OpIAdd %uint %20988 %uint_4 + %24653 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22503 + %23680 = OpLoad %uint %24653 + %11729 = OpIAdd %uint %20988 %uint_5 + %6421 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11729 + %23681 = OpLoad %uint %6421 + %11730 = OpIAdd %uint %20988 %uint_6 + %6422 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11730 + %23682 = OpLoad %uint %6422 + %11731 = OpIAdd %uint %20988 %uint_7 + %24584 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11731 + %16391 = OpLoad %uint %24584 + %20791 = OpCompositeConstruct %v4uint %23680 %23681 %23682 %16391 + OpBranch %20263 + %20263 = OpLabel + %11215 = OpPhi %v4uint %20791 %9768 %20790 %12134 + %14114 = OpPhi %v4uint %19168 %9768 %19673 %12134 + OpSelectionMerge %20264 None + OpSwitch %8576 %20312 5 %8538 7 %8248 + %8248 = OpLabel + %24411 = OpCompositeExtract %uint %14114 0 + %24684 = OpExtInst %v2float %1 UnpackHalf2x16 %24411 + %10110 = OpCompositeExtract %float %24684 0 + %16064 = OpCompositeExtract %float %24684 1 + %17033 = OpCompositeExtract %uint %14114 1 + %15613 = OpExtInst %v2float %1 UnpackHalf2x16 %17033 + %10111 = OpCompositeExtract %float %15613 0 + %17493 = OpCompositeExtract %float %15613 1 + %14619 = OpCompositeConstruct %v4float %10110 %16064 %10111 %17493 + %17289 = OpCompositeExtract %uint %14114 2 + %18042 = OpExtInst %v2float %1 UnpackHalf2x16 %17289 + %10112 = OpCompositeExtract %float %18042 0 + %16065 = OpCompositeExtract %float %18042 1 + %17034 = OpCompositeExtract %uint %14114 3 + %15614 = OpExtInst %v2float %1 UnpackHalf2x16 %17034 + %10113 = OpCompositeExtract %float %15614 0 + %17494 = OpCompositeExtract %float %15614 1 + %14620 = OpCompositeConstruct %v4float %10112 %16065 %10113 %17494 + %17290 = OpCompositeExtract %uint %11215 0 + %18043 = OpExtInst %v2float %1 UnpackHalf2x16 %17290 + %10114 = OpCompositeExtract %float %18043 0 + %16066 = OpCompositeExtract %float %18043 1 + %17035 = OpCompositeExtract %uint %11215 1 + %15615 = OpExtInst %v2float %1 UnpackHalf2x16 %17035 + %10115 = OpCompositeExtract %float %15615 0 + %17495 = OpCompositeExtract %float %15615 1 + %14621 = OpCompositeConstruct %v4float %10114 %16066 %10115 %17495 + %17291 = OpCompositeExtract %uint %11215 2 + %18044 = OpExtInst %v2float %1 UnpackHalf2x16 %17291 + %10116 = OpCompositeExtract %float %18044 0 + %16067 = OpCompositeExtract %float %18044 1 + %17036 = OpCompositeExtract %uint %11215 3 + %15616 = OpExtInst %v2float %1 UnpackHalf2x16 %17036 + %10117 = OpCompositeExtract %float %15616 0 + %20675 = OpCompositeExtract %float %15616 1 + %9046 = OpCompositeConstruct %v4float %10116 %16067 %10117 %20675 + OpBranch %20264 + %8538 = OpLabel + %9725 = OpVectorShuffle %v2uint %14114 %14114 0 1 + %23358 = OpBitcast %v2int %9725 + %24790 = OpVectorShuffle %v4int %23358 %23358 0 0 1 1 + %18608 = OpShiftLeftLogical %v4int %24790 %290 + %15765 = OpShiftRightArithmetic %v4int %18608 %770 + %10935 = OpConvertSToF %v4float %15765 + %18220 = OpVectorTimesScalar %v4float %10935 %float_0_000976592302 + %25239 = OpExtInst %v4float %1 FMax %1284 %18220 + %14193 = OpVectorShuffle %v2uint %14114 %14114 2 3 + %9413 = OpBitcast %v2int %14193 + %24791 = OpVectorShuffle %v4int %9413 %9413 0 0 1 1 + %18609 = OpShiftLeftLogical %v4int %24791 %290 + %15766 = OpShiftRightArithmetic %v4int %18609 %770 + %10936 = OpConvertSToF %v4float %15766 + %18221 = OpVectorTimesScalar %v4float %10936 %float_0_000976592302 + %25240 = OpExtInst %v4float %1 FMax %1284 %18221 + %14194 = OpVectorShuffle %v2uint %11215 %11215 0 1 + %9414 = OpBitcast %v2int %14194 + %24792 = OpVectorShuffle %v4int %9414 %9414 0 0 1 1 + %18610 = OpShiftLeftLogical %v4int %24792 %290 + %15767 = OpShiftRightArithmetic %v4int %18610 %770 + %10937 = OpConvertSToF %v4float %15767 + %18222 = OpVectorTimesScalar %v4float %10937 %float_0_000976592302 + %25241 = OpExtInst %v4float %1 FMax %1284 %18222 + %14195 = OpVectorShuffle %v2uint %11215 %11215 2 3 + %9415 = OpBitcast %v2int %14195 + %24793 = OpVectorShuffle %v4int %9415 %9415 0 0 1 1 + %18611 = OpShiftLeftLogical %v4int %24793 %290 + %15768 = OpShiftRightArithmetic %v4int %18611 %770 + %10938 = OpConvertSToF %v4float %15768 + %21441 = OpVectorTimesScalar %v4float %10938 %float_0_000976592302 + %17252 = OpExtInst %v4float %1 FMax %1284 %21441 + OpBranch %20264 + %20312 = OpLabel + %9769 = OpVectorShuffle %v2uint %14114 %14114 0 1 + %20827 = OpBitcast %v2float %9769 + %7044 = OpCompositeExtract %float %20827 0 + %13424 = OpCompositeExtract %float %20827 1 + %17022 = OpCompositeConstruct %v4float %7044 %13424 %float_0 %float_0 + %16862 = OpVectorShuffle %v2uint %14114 %14114 2 3 + %14179 = OpBitcast %v2float %16862 + %7045 = OpCompositeExtract %float %14179 0 + %13425 = OpCompositeExtract %float %14179 1 + %17023 = OpCompositeConstruct %v4float %7045 %13425 %float_0 %float_0 + %16863 = OpVectorShuffle %v2uint %11215 %11215 0 1 + %14180 = OpBitcast %v2float %16863 + %7046 = OpCompositeExtract %float %14180 0 + %13426 = OpCompositeExtract %float %14180 1 + %17024 = OpCompositeConstruct %v4float %7046 %13426 %float_0 %float_0 + %16864 = OpVectorShuffle %v2uint %11215 %11215 2 3 + %14181 = OpBitcast %v2float %16864 + %7047 = OpCompositeExtract %float %14181 0 + %16650 = OpCompositeExtract %float %14181 1 + %9047 = OpCompositeConstruct %v4float %7047 %16650 %float_0 %float_0 + OpBranch %20264 + %20264 = OpLabel + %11182 = OpPhi %v4float %9047 %20312 %17252 %8538 %9046 %8248 + %14351 = OpPhi %v4float %17024 %20312 %25241 %8538 %14621 %8248 + %15240 = OpPhi %v4float %17023 %20312 %25240 %8538 %14620 %8248 + %14523 = OpPhi %v4float %17022 %20312 %25239 %8538 %14619 %8248 + OpBranch %21265 + %21265 = OpLabel + %11183 = OpPhi %v4float %11182 %20264 %11181 %16226 + %14352 = OpPhi %v4float %14351 %20264 %14350 %16226 + %12950 = OpPhi %v4float %15240 %20264 %15237 %16226 + %13947 = OpPhi %v4float %14523 %20264 %14522 %16226 + %17242 = OpFAdd %v4float %17241 %13947 + %23298 = OpFAdd %v4float %23297 %12950 + %7208 = OpFAdd %v4float %8082 %14352 + %9642 = OpFAdd %v4float %20755 %11183 + %16376 = OpIAdd %uint %8114 %14258 + OpSelectionMerge %21266 DontFlatten + OpBranchConditional %23279 %15208 %16572 + %16572 = OpLabel + %19169 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20300 DontFlatten + OpBranchConditional %19169 %9770 %12135 + %12135 = OpLabel + %19413 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23887 = OpLoad %uint %19413 + %11732 = OpIAdd %uint %16376 %6555 + %6481 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11732 + %24164 = OpLoad %uint %6481 + %6243 = OpIMul %uint %uint_2 %6555 + %8362 = OpIAdd %uint %16376 %6243 + %15312 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8362 + %24165 = OpLoad %uint %15312 + %6244 = OpIMul %uint %uint_3 %6555 + %8363 = OpIAdd %uint %16376 %6244 + %14324 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8363 + %16392 = OpLoad %uint %14324 + %20792 = OpCompositeConstruct %v4uint %23887 %24164 %24165 %16392 + OpBranch %20300 + %9770 = OpLabel + %21835 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23888 = OpLoad %uint %21835 + %11733 = OpIAdd %uint %16376 %uint_1 + %6423 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11733 + %23683 = OpLoad %uint %6423 + %11734 = OpIAdd %uint %16376 %uint_2 + %6424 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11734 + %23684 = OpLoad %uint %6424 + %11735 = OpIAdd %uint %16376 %uint_3 + %24585 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11735 + %16393 = OpLoad %uint %24585 + %20793 = OpCompositeConstruct %v4uint %23888 %23683 %23684 %16393 + OpBranch %20300 + %20300 = OpLabel + %10946 = OpPhi %v4uint %20793 %9770 %20792 %12135 + OpSelectionMerge %16227 None + OpSwitch %8576 %19454 0 %14588 1 %14588 2 %7361 10 %7361 3 %7360 12 %7360 4 %8193 6 %8249 + %8249 = OpLabel + %24412 = OpCompositeExtract %uint %10946 0 + %24685 = OpExtInst %v2float %1 UnpackHalf2x16 %24412 + %10118 = OpCompositeExtract %float %24685 0 + %17496 = OpCompositeExtract %float %24685 1 + %14622 = OpCompositeConstruct %v4float %10118 %17496 %float_0 %float_0 + %17292 = OpCompositeExtract %uint %10946 1 + %18045 = OpExtInst %v2float %1 UnpackHalf2x16 %17292 + %10119 = OpCompositeExtract %float %18045 0 + %17497 = OpCompositeExtract %float %18045 1 + %14623 = OpCompositeConstruct %v4float %10119 %17497 %float_0 %float_0 + %17293 = OpCompositeExtract %uint %10946 2 + %18046 = OpExtInst %v2float %1 UnpackHalf2x16 %17293 + %10120 = OpCompositeExtract %float %18046 0 + %17498 = OpCompositeExtract %float %18046 1 + %14624 = OpCompositeConstruct %v4float %10120 %17498 %float_0 %float_0 + %17294 = OpCompositeExtract %uint %10946 3 + %18047 = OpExtInst %v2float %1 UnpackHalf2x16 %17294 + %10121 = OpCompositeExtract %float %18047 0 + %20676 = OpCompositeExtract %float %18047 1 + %9048 = OpCompositeConstruct %v4float %10121 %20676 %float_0 %float_0 + OpBranch %16227 + %8193 = OpLabel + %12433 = OpCompositeExtract %uint %10946 0 + %22688 = OpBitcast %int %12433 + %18223 = OpCompositeConstruct %v2int %22688 %22688 + %18361 = OpShiftLeftLogical %v2int %18223 %1959 + %13347 = OpShiftRightArithmetic %v2int %18361 %2151 + %10939 = OpConvertSToF %v2float %13347 + %18259 = OpVectorTimesScalar %v2float %10939 %float_0_000976592302 + %24082 = OpExtInst %v2float %1 FMax %73 %18259 + %24342 = OpCompositeExtract %float %24082 0 + %15581 = OpCompositeExtract %float %24082 1 + %16679 = OpCompositeConstruct %v4float %24342 %15581 %float_0 %float_0 + %19531 = OpCompositeExtract %uint %10946 1 + %16042 = OpBitcast %int %19531 + %18224 = OpCompositeConstruct %v2int %16042 %16042 + %18362 = OpShiftLeftLogical %v2int %18224 %1959 + %13348 = OpShiftRightArithmetic %v2int %18362 %2151 + %10940 = OpConvertSToF %v2float %13348 + %18260 = OpVectorTimesScalar %v2float %10940 %float_0_000976592302 + %24083 = OpExtInst %v2float %1 FMax %73 %18260 + %24343 = OpCompositeExtract %float %24083 0 + %15582 = OpCompositeExtract %float %24083 1 + %16680 = OpCompositeConstruct %v4float %24343 %15582 %float_0 %float_0 + %19532 = OpCompositeExtract %uint %10946 2 + %16043 = OpBitcast %int %19532 + %18225 = OpCompositeConstruct %v2int %16043 %16043 + %18364 = OpShiftLeftLogical %v2int %18225 %1959 + %13349 = OpShiftRightArithmetic %v2int %18364 %2151 + %10941 = OpConvertSToF %v2float %13349 + %18261 = OpVectorTimesScalar %v2float %10941 %float_0_000976592302 + %24084 = OpExtInst %v2float %1 FMax %73 %18261 + %24344 = OpCompositeExtract %float %24084 0 + %15583 = OpCompositeExtract %float %24084 1 + %16681 = OpCompositeConstruct %v4float %24344 %15583 %float_0 %float_0 + %19533 = OpCompositeExtract %uint %10946 3 + %16044 = OpBitcast %int %19533 + %18226 = OpCompositeConstruct %v2int %16044 %16044 + %18365 = OpShiftLeftLogical %v2int %18226 %1959 + %13350 = OpShiftRightArithmetic %v2int %18365 %2151 + %10942 = OpConvertSToF %v2float %13350 + %18262 = OpVectorTimesScalar %v2float %10942 %float_0_000976592302 + %24085 = OpExtInst %v2float %1 FMax %73 %18262 + %24345 = OpCompositeExtract %float %24085 0 + %18767 = OpCompositeExtract %float %24085 1 + %9049 = OpCompositeConstruct %v4float %24345 %18767 %float_0 %float_0 + OpBranch %16227 + %7360 = OpLabel + %22214 = OpCompositeExtract %uint %10946 0 + %20243 = OpCompositeConstruct %v3uint %22214 %22214 %22214 + %11036 = OpShiftRightLogical %v3uint %20243 %2996 + %24050 = OpBitwiseAnd %v3uint %11036 %261 + %18612 = OpBitwiseAnd %v3uint %24050 %1126 + %23452 = OpShiftRightLogical %v3uint %24050 %2828 + %16597 = OpIEqual %v3bool %23452 %2578 + %11351 = OpExtInst %v3int %1 FindUMsb %18612 + %10785 = OpBitcast %v3uint %11351 + %6278 = OpISub %v3uint %2828 %10785 + %8732 = OpIAdd %v3uint %10785 %2360 + %10363 = OpSelect %v3uint %16597 %8732 %23452 + %23264 = OpShiftLeftLogical %v3uint %18612 %6278 + %18854 = OpBitwiseAnd %v3uint %23264 %1126 + %10947 = OpSelect %v3uint %16597 %18854 %18612 + %24586 = OpIAdd %v3uint %10363 %1018 + %20363 = OpShiftLeftLogical %v3uint %24586 %393 + %16306 = OpShiftLeftLogical %v3uint %10947 %141 + %22408 = OpBitwiseOr %v3uint %20363 %16306 + %13836 = OpIEqual %v3bool %24050 %2578 + %16974 = OpSelect %v3uint %13836 %2578 %22408 + %10715 = OpBitcast %v3float %16974 + %19376 = OpShiftRightLogical %uint %22214 %uint_30 + %18458 = OpConvertUToF %float %19376 + %15915 = OpFMul %float %18458 %float_0_333333343 + %21454 = OpCompositeExtract %float %10715 0 + %10849 = OpCompositeExtract %float %10715 1 + %7842 = OpCompositeExtract %float %10715 2 + %15843 = OpCompositeConstruct %v4float %21454 %10849 %7842 %15915 + %10238 = OpCompositeExtract %uint %10946 1 + %13591 = OpCompositeConstruct %v3uint %10238 %10238 %10238 + %11037 = OpShiftRightLogical %v3uint %13591 %2996 + %24051 = OpBitwiseAnd %v3uint %11037 %261 + %18613 = OpBitwiseAnd %v3uint %24051 %1126 + %23453 = OpShiftRightLogical %v3uint %24051 %2828 + %16598 = OpIEqual %v3bool %23453 %2578 + %11352 = OpExtInst %v3int %1 FindUMsb %18613 + %10786 = OpBitcast %v3uint %11352 + %6279 = OpISub %v3uint %2828 %10786 + %8733 = OpIAdd %v3uint %10786 %2360 + %10364 = OpSelect %v3uint %16598 %8733 %23453 + %23265 = OpShiftLeftLogical %v3uint %18613 %6279 + %18855 = OpBitwiseAnd %v3uint %23265 %1126 + %10948 = OpSelect %v3uint %16598 %18855 %18613 + %24587 = OpIAdd %v3uint %10364 %1018 + %20364 = OpShiftLeftLogical %v3uint %24587 %393 + %16307 = OpShiftLeftLogical %v3uint %10948 %141 + %22409 = OpBitwiseOr %v3uint %20364 %16307 + %13837 = OpIEqual %v3bool %24051 %2578 + %16975 = OpSelect %v3uint %13837 %2578 %22409 + %10716 = OpBitcast %v3float %16975 + %19377 = OpShiftRightLogical %uint %10238 %uint_30 + %18459 = OpConvertUToF %float %19377 + %15916 = OpFMul %float %18459 %float_0_333333343 + %21455 = OpCompositeExtract %float %10716 0 + %10850 = OpCompositeExtract %float %10716 1 + %7843 = OpCompositeExtract %float %10716 2 + %15844 = OpCompositeConstruct %v4float %21455 %10850 %7843 %15916 + %10239 = OpCompositeExtract %uint %10946 2 + %13592 = OpCompositeConstruct %v3uint %10239 %10239 %10239 + %11038 = OpShiftRightLogical %v3uint %13592 %2996 + %24052 = OpBitwiseAnd %v3uint %11038 %261 + %18614 = OpBitwiseAnd %v3uint %24052 %1126 + %23454 = OpShiftRightLogical %v3uint %24052 %2828 + %16599 = OpIEqual %v3bool %23454 %2578 + %11353 = OpExtInst %v3int %1 FindUMsb %18614 + %10787 = OpBitcast %v3uint %11353 + %6280 = OpISub %v3uint %2828 %10787 + %8734 = OpIAdd %v3uint %10787 %2360 + %10365 = OpSelect %v3uint %16599 %8734 %23454 + %23266 = OpShiftLeftLogical %v3uint %18614 %6280 + %18856 = OpBitwiseAnd %v3uint %23266 %1126 + %10949 = OpSelect %v3uint %16599 %18856 %18614 + %24588 = OpIAdd %v3uint %10365 %1018 + %20365 = OpShiftLeftLogical %v3uint %24588 %393 + %16308 = OpShiftLeftLogical %v3uint %10949 %141 + %22410 = OpBitwiseOr %v3uint %20365 %16308 + %13838 = OpIEqual %v3bool %24052 %2578 + %16976 = OpSelect %v3uint %13838 %2578 %22410 + %10717 = OpBitcast %v3float %16976 + %19378 = OpShiftRightLogical %uint %10239 %uint_30 + %18460 = OpConvertUToF %float %19378 + %15917 = OpFMul %float %18460 %float_0_333333343 + %21456 = OpCompositeExtract %float %10717 0 + %10851 = OpCompositeExtract %float %10717 1 + %7844 = OpCompositeExtract %float %10717 2 + %15845 = OpCompositeConstruct %v4float %21456 %10851 %7844 %15917 + %10240 = OpCompositeExtract %uint %10946 3 + %13593 = OpCompositeConstruct %v3uint %10240 %10240 %10240 + %11039 = OpShiftRightLogical %v3uint %13593 %2996 + %24053 = OpBitwiseAnd %v3uint %11039 %261 + %18616 = OpBitwiseAnd %v3uint %24053 %1126 + %23455 = OpShiftRightLogical %v3uint %24053 %2828 + %16600 = OpIEqual %v3bool %23455 %2578 + %11354 = OpExtInst %v3int %1 FindUMsb %18616 + %10788 = OpBitcast %v3uint %11354 + %6281 = OpISub %v3uint %2828 %10788 + %8735 = OpIAdd %v3uint %10788 %2360 + %10366 = OpSelect %v3uint %16600 %8735 %23455 + %23267 = OpShiftLeftLogical %v3uint %18616 %6281 + %18857 = OpBitwiseAnd %v3uint %23267 %1126 + %10950 = OpSelect %v3uint %16600 %18857 %18616 + %24589 = OpIAdd %v3uint %10366 %1018 + %20366 = OpShiftLeftLogical %v3uint %24589 %393 + %16309 = OpShiftLeftLogical %v3uint %10950 %141 + %22411 = OpBitwiseOr %v3uint %20366 %16309 + %13839 = OpIEqual %v3bool %24053 %2578 + %16977 = OpSelect %v3uint %13839 %2578 %22411 + %10718 = OpBitcast %v3float %16977 + %19379 = OpShiftRightLogical %uint %10240 %uint_30 + %18461 = OpConvertUToF %float %19379 + %15918 = OpFMul %float %18461 %float_0_333333343 + %21457 = OpCompositeExtract %float %10718 0 + %10852 = OpCompositeExtract %float %10718 1 + %11040 = OpCompositeExtract %float %10718 2 + %9050 = OpCompositeConstruct %v4float %21457 %10852 %11040 %15918 + OpBranch %16227 + %7361 = OpLabel + %22215 = OpCompositeExtract %uint %10946 0 + %20244 = OpCompositeConstruct %v4uint %22215 %22215 %22215 %22215 + %9392 = OpShiftRightLogical %v4uint %20244 %845 + %18871 = OpBitwiseAnd %v4uint %9392 %635 + %15552 = OpConvertUToF %v4float %18871 + %16697 = OpFMul %v4float %15552 %2798 + %23771 = OpCompositeExtract %uint %10946 1 + %20822 = OpCompositeConstruct %v4uint %23771 %23771 %23771 %23771 + %9393 = OpShiftRightLogical %v4uint %20822 %845 + %18872 = OpBitwiseAnd %v4uint %9393 %635 + %15553 = OpConvertUToF %v4float %18872 + %16698 = OpFMul %v4float %15553 %2798 + %23772 = OpCompositeExtract %uint %10946 2 + %20823 = OpCompositeConstruct %v4uint %23772 %23772 %23772 %23772 + %9394 = OpShiftRightLogical %v4uint %20823 %845 + %18873 = OpBitwiseAnd %v4uint %9394 %635 + %15554 = OpConvertUToF %v4float %18873 + %16699 = OpFMul %v4float %15554 %2798 + %23773 = OpCompositeExtract %uint %10946 3 + %20828 = OpCompositeConstruct %v4uint %23773 %23773 %23773 %23773 + %9395 = OpShiftRightLogical %v4uint %20828 %845 + %18874 = OpBitwiseAnd %v4uint %9395 %635 + %18738 = OpConvertUToF %v4float %18874 + %9890 = OpFMul %v4float %18738 %2798 + OpBranch %16227 + %14588 = OpLabel + %22216 = OpCompositeExtract %uint %10946 0 + %20245 = OpCompositeConstruct %v4uint %22216 %22216 %22216 %22216 + %9396 = OpShiftRightLogical %v4uint %20245 %653 + %19042 = OpBitwiseAnd %v4uint %9396 %1611 + %13998 = OpConvertUToF %v4float %19042 + %19244 = OpVectorTimesScalar %v4float %13998 %float_0_00392156886 + %8616 = OpCompositeExtract %uint %10946 1 + %24852 = OpCompositeConstruct %v4uint %8616 %8616 %8616 %8616 + %9397 = OpShiftRightLogical %v4uint %24852 %653 + %19043 = OpBitwiseAnd %v4uint %9397 %1611 + %13999 = OpConvertUToF %v4float %19043 + %19245 = OpVectorTimesScalar %v4float %13999 %float_0_00392156886 + %8617 = OpCompositeExtract %uint %10946 2 + %24853 = OpCompositeConstruct %v4uint %8617 %8617 %8617 %8617 + %9398 = OpShiftRightLogical %v4uint %24853 %653 + %19044 = OpBitwiseAnd %v4uint %9398 %1611 + %14000 = OpConvertUToF %v4float %19044 + %19246 = OpVectorTimesScalar %v4float %14000 %float_0_00392156886 + %8618 = OpCompositeExtract %uint %10946 3 + %24854 = OpCompositeConstruct %v4uint %8618 %8618 %8618 %8618 + %9399 = OpShiftRightLogical %v4uint %24854 %653 + %19045 = OpBitwiseAnd %v4uint %9399 %1611 + %17181 = OpConvertUToF %v4float %19045 + %12437 = OpVectorTimesScalar %v4float %17181 %float_0_00392156886 + OpBranch %16227 + %19454 = OpLabel + %12438 = OpCompositeExtract %uint %10946 0 + %20465 = OpBitcast %float %12438 + %17215 = OpCompositeConstruct %v2float %20465 %float_0 + %11673 = OpVectorShuffle %v4float %17215 %17215 0 1 1 1 + %22202 = OpCompositeExtract %uint %10946 1 + %16241 = OpBitcast %float %22202 + %17216 = OpCompositeConstruct %v2float %16241 %float_0 + %11674 = OpVectorShuffle %v4float %17216 %17216 0 1 1 1 + %22203 = OpCompositeExtract %uint %10946 2 + %16242 = OpBitcast %float %22203 + %17217 = OpCompositeConstruct %v2float %16242 %float_0 + %11675 = OpVectorShuffle %v4float %17217 %17217 0 1 1 1 + %22204 = OpCompositeExtract %uint %10946 3 + %16243 = OpBitcast %float %22204 + %20401 = OpCompositeConstruct %v2float %16243 %float_0 + %23101 = OpVectorShuffle %v4float %20401 %20401 0 1 1 1 + OpBranch %16227 + %16227 = OpLabel + %11184 = OpPhi %v4float %23101 %19454 %12437 %14588 %9890 %7361 %9050 %7360 %9049 %8193 %9048 %8249 + %14353 = OpPhi %v4float %11675 %19454 %19246 %14588 %16699 %7361 %15845 %7360 %16681 %8193 %14624 %8249 + %15241 = OpPhi %v4float %11674 %19454 %19245 %14588 %16698 %7361 %15844 %7360 %16680 %8193 %14623 %8249 + %14524 = OpPhi %v4float %11673 %19454 %19244 %14588 %16697 %7361 %15843 %7360 %16679 %8193 %14622 %8249 + OpBranch %21266 + %15208 = OpLabel + %21587 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20265 DontFlatten + OpBranchConditional %21587 %9771 %12136 + %12136 = OpLabel + %19414 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23889 = OpLoad %uint %19414 + %11736 = OpIAdd %uint %16376 %uint_1 + %6425 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11736 + %23685 = OpLoad %uint %6425 + %11737 = OpIAdd %uint %16376 %6555 + %6426 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11737 + %23686 = OpLoad %uint %6426 + %11738 = OpIAdd %uint %11737 %uint_1 + %24590 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11738 + %14159 = OpLoad %uint %24590 + %19674 = OpCompositeConstruct %v4uint %23889 %23685 %23686 %14159 + %17051 = OpIMul %uint %uint_2 %6555 + %14001 = OpIAdd %uint %16376 %17051 + %15242 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %14001 + %23687 = OpLoad %uint %15242 + %11739 = OpIAdd %uint %14001 %uint_1 + %6482 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11739 + %24166 = OpLoad %uint %6482 + %6245 = OpIMul %uint %uint_3 %6555 + %8364 = OpIAdd %uint %16376 %6245 + %15243 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8364 + %23688 = OpLoad %uint %15243 + %11740 = OpIAdd %uint %8364 %uint_1 + %24591 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11740 + %16394 = OpLoad %uint %24591 + %20794 = OpCompositeConstruct %v4uint %23687 %24166 %23688 %16394 + OpBranch %20265 + %9771 = OpLabel + %21836 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23890 = OpLoad %uint %21836 + %11741 = OpIAdd %uint %16376 %uint_1 + %6427 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11741 + %23689 = OpLoad %uint %6427 + %11742 = OpIAdd %uint %16376 %uint_2 + %6428 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11742 + %23690 = OpLoad %uint %6428 + %11743 = OpIAdd %uint %16376 %uint_3 + %24592 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11743 + %14083 = OpLoad %uint %24592 + %19170 = OpCompositeConstruct %v4uint %23890 %23689 %23690 %14083 + %22504 = OpIAdd %uint %16376 %uint_4 + %24654 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22504 + %23691 = OpLoad %uint %24654 + %11744 = OpIAdd %uint %16376 %uint_5 + %6429 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11744 + %23692 = OpLoad %uint %6429 + %11745 = OpIAdd %uint %16376 %uint_6 + %6430 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11745 + %23693 = OpLoad %uint %6430 + %11746 = OpIAdd %uint %16376 %uint_7 + %24593 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11746 + %16395 = OpLoad %uint %24593 + %20795 = OpCompositeConstruct %v4uint %23691 %23692 %23693 %16395 + OpBranch %20265 + %20265 = OpLabel + %11216 = OpPhi %v4uint %20795 %9771 %20794 %12136 + %14115 = OpPhi %v4uint %19170 %9771 %19674 %12136 + OpSelectionMerge %20266 None + OpSwitch %8576 %20313 5 %8539 7 %8250 + %8250 = OpLabel + %24413 = OpCompositeExtract %uint %14115 0 + %24686 = OpExtInst %v2float %1 UnpackHalf2x16 %24413 + %10122 = OpCompositeExtract %float %24686 0 + %16068 = OpCompositeExtract %float %24686 1 + %17037 = OpCompositeExtract %uint %14115 1 + %15617 = OpExtInst %v2float %1 UnpackHalf2x16 %17037 + %10123 = OpCompositeExtract %float %15617 0 + %17499 = OpCompositeExtract %float %15617 1 + %14625 = OpCompositeConstruct %v4float %10122 %16068 %10123 %17499 + %17295 = OpCompositeExtract %uint %14115 2 + %18048 = OpExtInst %v2float %1 UnpackHalf2x16 %17295 + %10124 = OpCompositeExtract %float %18048 0 + %16069 = OpCompositeExtract %float %18048 1 + %17038 = OpCompositeExtract %uint %14115 3 + %15618 = OpExtInst %v2float %1 UnpackHalf2x16 %17038 + %10125 = OpCompositeExtract %float %15618 0 + %17500 = OpCompositeExtract %float %15618 1 + %14626 = OpCompositeConstruct %v4float %10124 %16069 %10125 %17500 + %17296 = OpCompositeExtract %uint %11216 0 + %18049 = OpExtInst %v2float %1 UnpackHalf2x16 %17296 + %10126 = OpCompositeExtract %float %18049 0 + %16070 = OpCompositeExtract %float %18049 1 + %17039 = OpCompositeExtract %uint %11216 1 + %15619 = OpExtInst %v2float %1 UnpackHalf2x16 %17039 + %10127 = OpCompositeExtract %float %15619 0 + %17501 = OpCompositeExtract %float %15619 1 + %14627 = OpCompositeConstruct %v4float %10126 %16070 %10127 %17501 + %17297 = OpCompositeExtract %uint %11216 2 + %18050 = OpExtInst %v2float %1 UnpackHalf2x16 %17297 + %10128 = OpCompositeExtract %float %18050 0 + %16071 = OpCompositeExtract %float %18050 1 + %17040 = OpCompositeExtract %uint %11216 3 + %15620 = OpExtInst %v2float %1 UnpackHalf2x16 %17040 + %10129 = OpCompositeExtract %float %15620 0 + %20677 = OpCompositeExtract %float %15620 1 + %9051 = OpCompositeConstruct %v4float %10128 %16071 %10129 %20677 + OpBranch %20266 + %8539 = OpLabel + %9726 = OpVectorShuffle %v2uint %14115 %14115 0 1 + %23359 = OpBitcast %v2int %9726 + %24794 = OpVectorShuffle %v4int %23359 %23359 0 0 1 1 + %18617 = OpShiftLeftLogical %v4int %24794 %290 + %15769 = OpShiftRightArithmetic %v4int %18617 %770 + %10951 = OpConvertSToF %v4float %15769 + %18227 = OpVectorTimesScalar %v4float %10951 %float_0_000976592302 + %25242 = OpExtInst %v4float %1 FMax %1284 %18227 + %14196 = OpVectorShuffle %v2uint %14115 %14115 2 3 + %9416 = OpBitcast %v2int %14196 + %24795 = OpVectorShuffle %v4int %9416 %9416 0 0 1 1 + %18618 = OpShiftLeftLogical %v4int %24795 %290 + %15770 = OpShiftRightArithmetic %v4int %18618 %770 + %10952 = OpConvertSToF %v4float %15770 + %18228 = OpVectorTimesScalar %v4float %10952 %float_0_000976592302 + %25243 = OpExtInst %v4float %1 FMax %1284 %18228 + %14197 = OpVectorShuffle %v2uint %11216 %11216 0 1 + %9417 = OpBitcast %v2int %14197 + %24796 = OpVectorShuffle %v4int %9417 %9417 0 0 1 1 + %18619 = OpShiftLeftLogical %v4int %24796 %290 + %15771 = OpShiftRightArithmetic %v4int %18619 %770 + %10953 = OpConvertSToF %v4float %15771 + %18229 = OpVectorTimesScalar %v4float %10953 %float_0_000976592302 + %25244 = OpExtInst %v4float %1 FMax %1284 %18229 + %14198 = OpVectorShuffle %v2uint %11216 %11216 2 3 + %9418 = OpBitcast %v2int %14198 + %24797 = OpVectorShuffle %v4int %9418 %9418 0 0 1 1 + %18620 = OpShiftLeftLogical %v4int %24797 %290 + %15772 = OpShiftRightArithmetic %v4int %18620 %770 + %10954 = OpConvertSToF %v4float %15772 + %21458 = OpVectorTimesScalar %v4float %10954 %float_0_000976592302 + %17253 = OpExtInst %v4float %1 FMax %1284 %21458 + OpBranch %20266 + %20313 = OpLabel + %9772 = OpVectorShuffle %v2uint %14115 %14115 0 1 + %20829 = OpBitcast %v2float %9772 + %7048 = OpCompositeExtract %float %20829 0 + %13427 = OpCompositeExtract %float %20829 1 + %17041 = OpCompositeConstruct %v4float %7048 %13427 %float_0 %float_0 + %16865 = OpVectorShuffle %v2uint %14115 %14115 2 3 + %14182 = OpBitcast %v2float %16865 + %7049 = OpCompositeExtract %float %14182 0 + %13428 = OpCompositeExtract %float %14182 1 + %17042 = OpCompositeConstruct %v4float %7049 %13428 %float_0 %float_0 + %16866 = OpVectorShuffle %v2uint %11216 %11216 0 1 + %14183 = OpBitcast %v2float %16866 + %7050 = OpCompositeExtract %float %14183 0 + %13429 = OpCompositeExtract %float %14183 1 + %17043 = OpCompositeConstruct %v4float %7050 %13429 %float_0 %float_0 + %16867 = OpVectorShuffle %v2uint %11216 %11216 2 3 + %14184 = OpBitcast %v2float %16867 + %7051 = OpCompositeExtract %float %14184 0 + %16651 = OpCompositeExtract %float %14184 1 + %9052 = OpCompositeConstruct %v4float %7051 %16651 %float_0 %float_0 + OpBranch %20266 + %20266 = OpLabel + %11185 = OpPhi %v4float %9052 %20313 %17253 %8539 %9051 %8250 + %14354 = OpPhi %v4float %17043 %20313 %25244 %8539 %14627 %8250 + %15244 = OpPhi %v4float %17042 %20313 %25243 %8539 %14626 %8250 + %14525 = OpPhi %v4float %17041 %20313 %25242 %8539 %14625 %8250 + OpBranch %21266 + %21266 = OpLabel + %11186 = OpPhi %v4float %11185 %20266 %11184 %16227 + %14355 = OpPhi %v4float %14354 %20266 %14353 %16227 + %12951 = OpPhi %v4float %15244 %20266 %15241 %16227 + %13948 = OpPhi %v4float %14525 %20266 %14524 %16227 + %17243 = OpFAdd %v4float %17242 %13948 + %23299 = OpFAdd %v4float %23298 %12951 + %9507 = OpFAdd %v4float %7208 %14355 + %7799 = OpFAdd %v4float %9642 %11186 + OpBranch %24264 + %24264 = OpLabel + %11187 = OpPhi %v4float %20755 %21264 %7799 %21266 + %14356 = OpPhi %v4float %8082 %21264 %9507 %21266 + %15153 = OpPhi %v4float %23297 %21264 %23299 %21266 + %15245 = OpPhi %v4float %17241 %21264 %17243 %21266 + %14526 = OpPhi %float %23069 %21264 %12090 %21266 + OpBranch %21267 + %21267 = OpLabel + %11188 = OpPhi %v4float %11177 %21263 %11187 %24264 + %14357 = OpPhi %v4float %14346 %21263 %14356 %24264 + %15154 = OpPhi %v4float %13804 %21263 %15153 %24264 + %13196 = OpPhi %v4float %8403 %21263 %15245 %24264 + %11944 = OpPhi %float %11052 %21263 %14526 %24264 + %23156 = OpVectorTimesScalar %v4float %13196 %11944 + %6604 = OpVectorTimesScalar %v4float %15154 %11944 + %12399 = OpVectorTimesScalar %v4float %14357 %11944 + %13362 = OpVectorTimesScalar %v4float %11188 %11944 + OpSelectionMerge %16228 DontFlatten + OpBranchConditional %7513 %10049 %16228 + %10049 = OpLabel + %15086 = OpVectorShuffle %v4float %23156 %23156 2 1 0 3 + %14855 = OpVectorShuffle %v4float %6604 %6604 2 1 0 3 + %7398 = OpVectorShuffle %v4float %12399 %12399 2 1 0 3 + %16111 = OpVectorShuffle %v4float %13362 %13362 2 1 0 3 + OpBranch %16228 + %16228 = OpLabel + %11189 = OpPhi %v4float %13362 %21267 %16111 %10049 + %14358 = OpPhi %v4float %12399 %21267 %7398 %10049 + %15191 = OpPhi %v4float %6604 %21267 %14855 %10049 + %14921 = OpPhi %v4float %23156 %21267 %15086 %10049 + OpSelectionMerge %18834 None + OpSwitch %20627 %8194 6 %18070 14 %18070 50 %18070 7 %17899 54 %17899 16 %6453 55 %6453 17 %6452 56 %6452 25 %6451 31 %9492 + %9492 = OpLabel + %15022 = OpCompositeExtract %float %14921 0 + %9197 = OpCompositeExtract %float %14921 1 + %19232 = OpCompositeConstruct %v2float %15022 %9197 + %8561 = OpExtInst %uint %1 PackHalf2x16 %19232 + %23487 = OpCompositeExtract %float %15191 0 + %14759 = OpCompositeExtract %float %15191 1 + %19233 = OpCompositeConstruct %v2float %23487 %14759 + %8562 = OpExtInst %uint %1 PackHalf2x16 %19233 + %23488 = OpCompositeExtract %float %14358 0 + %14760 = OpCompositeExtract %float %14358 1 + %19234 = OpCompositeConstruct %v2float %23488 %14760 + %8563 = OpExtInst %uint %1 PackHalf2x16 %19234 + %23489 = OpCompositeExtract %float %11189 0 + %14761 = OpCompositeExtract %float %11189 1 + %19213 = OpCompositeConstruct %v2float %23489 %14761 + %11926 = OpExtInst %uint %1 PackHalf2x16 %19213 + %24879 = OpCompositeConstruct %v4uint %8561 %8562 %8563 %11926 + OpBranch %18834 + %6451 = OpLabel + %8826 = OpVectorShuffle %v2float %14921 %14921 0 1 + %23729 = OpExtInst %v2float %1 FClamp %8826 %1823 %768 + %9652 = OpVectorTimesScalar %v2float %23729 %float_65535 + %11878 = OpFAdd %v2float %9652 %1566 + %7639 = OpConvertFToU %v2uint %11878 + %8700 = OpCompositeExtract %uint %7639 0 + %12251 = OpCompositeExtract %uint %7639 1 + %11523 = OpShiftLeftLogical %uint %12251 %int_16 + %16707 = OpBitwiseOr %uint %8700 %11523 + %9053 = OpVectorShuffle %v2float %15191 %15191 0 1 + %18111 = OpExtInst %v2float %1 FClamp %9053 %1823 %768 + %9653 = OpVectorTimesScalar %v2float %18111 %float_65535 + %11879 = OpFAdd %v2float %9653 %1566 + %7641 = OpConvertFToU %v2uint %11879 + %8701 = OpCompositeExtract %uint %7641 0 + %12252 = OpCompositeExtract %uint %7641 1 + %11524 = OpShiftLeftLogical %uint %12252 %int_16 + %16708 = OpBitwiseOr %uint %8701 %11524 + %9054 = OpVectorShuffle %v2float %14358 %14358 0 1 + %18112 = OpExtInst %v2float %1 FClamp %9054 %1823 %768 + %9654 = OpVectorTimesScalar %v2float %18112 %float_65535 + %11881 = OpFAdd %v2float %9654 %1566 + %7642 = OpConvertFToU %v2uint %11881 + %8702 = OpCompositeExtract %uint %7642 0 + %12253 = OpCompositeExtract %uint %7642 1 + %11525 = OpShiftLeftLogical %uint %12253 %int_16 + %16709 = OpBitwiseOr %uint %8702 %11525 + %9055 = OpVectorShuffle %v2float %11189 %11189 0 1 + %18113 = OpExtInst %v2float %1 FClamp %9055 %1823 %768 + %9655 = OpVectorTimesScalar %v2float %18113 %float_65535 + %11882 = OpFAdd %v2float %9655 %1566 + %7643 = OpConvertFToU %v2uint %11882 + %8703 = OpCompositeExtract %uint %7643 0 + %12254 = OpCompositeExtract %uint %7643 1 + %11542 = OpShiftLeftLogical %uint %12254 %int_16 + %20994 = OpBitwiseOr %uint %8703 %11542 + %21469 = OpCompositeConstruct %v4uint %16707 %16708 %16709 %20994 + OpBranch %18834 + %6452 = OpLabel + %8655 = OpVectorShuffle %v3float %14921 %14921 0 1 2 + %6215 = OpExtInst %v3float %1 FClamp %8655 %2605 %2584 + %7105 = OpFMul %v3float %6215 %14 + %7962 = OpFAdd %v3float %7105 %939 + %10066 = OpConvertFToU %v3uint %7962 + %8704 = OpCompositeExtract %uint %10066 0 + %12255 = OpCompositeExtract %uint %10066 1 + %11561 = OpShiftLeftLogical %uint %12255 %int_10 + %19814 = OpBitwiseOr %uint %8704 %11561 + %21476 = OpCompositeExtract %uint %10066 2 + %8522 = OpShiftLeftLogical %uint %21476 %int_21 + %16710 = OpBitwiseOr %uint %19814 %8522 + %8866 = OpVectorShuffle %v3float %15191 %15191 0 1 2 + %19668 = OpExtInst %v3float %1 FClamp %8866 %2605 %2584 + %7106 = OpFMul %v3float %19668 %14 + %7963 = OpFAdd %v3float %7106 %939 + %10067 = OpConvertFToU %v3uint %7963 + %8705 = OpCompositeExtract %uint %10067 0 + %12256 = OpCompositeExtract %uint %10067 1 + %11562 = OpShiftLeftLogical %uint %12256 %int_10 + %19815 = OpBitwiseOr %uint %8705 %11562 + %21477 = OpCompositeExtract %uint %10067 2 + %8523 = OpShiftLeftLogical %uint %21477 %int_21 + %16711 = OpBitwiseOr %uint %19815 %8523 + %8867 = OpVectorShuffle %v3float %14358 %14358 0 1 2 + %19669 = OpExtInst %v3float %1 FClamp %8867 %2605 %2584 + %7107 = OpFMul %v3float %19669 %14 + %7964 = OpFAdd %v3float %7107 %939 + %10068 = OpConvertFToU %v3uint %7964 + %8706 = OpCompositeExtract %uint %10068 0 + %12257 = OpCompositeExtract %uint %10068 1 + %11563 = OpShiftLeftLogical %uint %12257 %int_10 + %19816 = OpBitwiseOr %uint %8706 %11563 + %21478 = OpCompositeExtract %uint %10068 2 + %8524 = OpShiftLeftLogical %uint %21478 %int_21 + %16712 = OpBitwiseOr %uint %19816 %8524 + %8868 = OpVectorShuffle %v3float %11189 %11189 0 1 2 + %19675 = OpExtInst %v3float %1 FClamp %8868 %2605 %2584 + %7108 = OpFMul %v3float %19675 %14 + %7965 = OpFAdd %v3float %7108 %939 + %10069 = OpConvertFToU %v3uint %7965 + %8707 = OpCompositeExtract %uint %10069 0 + %12258 = OpCompositeExtract %uint %10069 1 + %11564 = OpShiftLeftLogical %uint %12258 %int_10 + %19817 = OpBitwiseOr %uint %8707 %11564 + %21479 = OpCompositeExtract %uint %10069 2 + %8541 = OpShiftLeftLogical %uint %21479 %int_21 + %20995 = OpBitwiseOr %uint %19817 %8541 + %21470 = OpCompositeConstruct %v4uint %16710 %16711 %16712 %20995 + OpBranch %18834 + %6453 = OpLabel + %8656 = OpVectorShuffle %v3float %14921 %14921 0 1 2 + %6216 = OpExtInst %v3float %1 FClamp %8656 %2605 %2584 + %7109 = OpFMul %v3float %6216 %2275 + %7966 = OpFAdd %v3float %7109 %939 + %10070 = OpConvertFToU %v3uint %7966 + %8708 = OpCompositeExtract %uint %10070 0 + %12259 = OpCompositeExtract %uint %10070 1 + %11565 = OpShiftLeftLogical %uint %12259 %int_11 + %19818 = OpBitwiseOr %uint %8708 %11565 + %21480 = OpCompositeExtract %uint %10070 2 + %8525 = OpShiftLeftLogical %uint %21480 %int_22 + %16713 = OpBitwiseOr %uint %19818 %8525 + %8869 = OpVectorShuffle %v3float %15191 %15191 0 1 2 + %19676 = OpExtInst %v3float %1 FClamp %8869 %2605 %2584 + %7110 = OpFMul %v3float %19676 %2275 + %7967 = OpFAdd %v3float %7110 %939 + %10071 = OpConvertFToU %v3uint %7967 + %8709 = OpCompositeExtract %uint %10071 0 + %12260 = OpCompositeExtract %uint %10071 1 + %11566 = OpShiftLeftLogical %uint %12260 %int_11 + %19819 = OpBitwiseOr %uint %8709 %11566 + %21481 = OpCompositeExtract %uint %10071 2 + %8526 = OpShiftLeftLogical %uint %21481 %int_22 + %16714 = OpBitwiseOr %uint %19819 %8526 + %8870 = OpVectorShuffle %v3float %14358 %14358 0 1 2 + %19677 = OpExtInst %v3float %1 FClamp %8870 %2605 %2584 + %7111 = OpFMul %v3float %19677 %2275 + %7968 = OpFAdd %v3float %7111 %939 + %10072 = OpConvertFToU %v3uint %7968 + %8710 = OpCompositeExtract %uint %10072 0 + %12261 = OpCompositeExtract %uint %10072 1 + %11567 = OpShiftLeftLogical %uint %12261 %int_11 + %19820 = OpBitwiseOr %uint %8710 %11567 + %21482 = OpCompositeExtract %uint %10072 2 + %8527 = OpShiftLeftLogical %uint %21482 %int_22 + %16715 = OpBitwiseOr %uint %19820 %8527 + %8872 = OpVectorShuffle %v3float %11189 %11189 0 1 2 + %19678 = OpExtInst %v3float %1 FClamp %8872 %2605 %2584 + %7112 = OpFMul %v3float %19678 %2275 + %7969 = OpFAdd %v3float %7112 %939 + %10073 = OpConvertFToU %v3uint %7969 + %8711 = OpCompositeExtract %uint %10073 0 + %12262 = OpCompositeExtract %uint %10073 1 + %11568 = OpShiftLeftLogical %uint %12262 %int_11 + %19821 = OpBitwiseOr %uint %8711 %11568 + %21483 = OpCompositeExtract %uint %10073 2 + %8542 = OpShiftLeftLogical %uint %21483 %int_22 + %20996 = OpBitwiseOr %uint %19821 %8542 + %21471 = OpCompositeConstruct %v4uint %16713 %16714 %16715 %20996 + OpBranch %18834 + %17899 = OpLabel + %8873 = OpExtInst %v4float %1 FClamp %14921 %2938 %1285 + %17792 = OpFMul %v4float %8873 %344 + %7970 = OpFAdd %v4float %17792 %325 + %10074 = OpConvertFToU %v4uint %7970 + %8712 = OpCompositeExtract %uint %10074 0 + %12263 = OpCompositeExtract %uint %10074 1 + %11569 = OpShiftLeftLogical %uint %12263 %int_10 + %19822 = OpBitwiseOr %uint %8712 %11569 + %21484 = OpCompositeExtract %uint %10074 2 + %8560 = OpShiftLeftLogical %uint %21484 %int_20 + %19823 = OpBitwiseOr %uint %19822 %8560 + %21485 = OpCompositeExtract %uint %10074 3 + %7292 = OpShiftLeftLogical %uint %21485 %int_30 + %9084 = OpBitwiseOr %uint %19823 %7292 + %9079 = OpExtInst %v4float %1 FClamp %15191 %2938 %1285 + %24798 = OpFMul %v4float %9079 %344 + %7971 = OpFAdd %v4float %24798 %325 + %10075 = OpConvertFToU %v4uint %7971 + %8713 = OpCompositeExtract %uint %10075 0 + %12264 = OpCompositeExtract %uint %10075 1 + %11570 = OpShiftLeftLogical %uint %12264 %int_10 + %19824 = OpBitwiseOr %uint %8713 %11570 + %21486 = OpCompositeExtract %uint %10075 2 + %8564 = OpShiftLeftLogical %uint %21486 %int_20 + %19825 = OpBitwiseOr %uint %19824 %8564 + %21487 = OpCompositeExtract %uint %10075 3 + %7293 = OpShiftLeftLogical %uint %21487 %int_30 + %9085 = OpBitwiseOr %uint %19825 %7293 + %9080 = OpExtInst %v4float %1 FClamp %14358 %2938 %1285 + %24799 = OpFMul %v4float %9080 %344 + %7972 = OpFAdd %v4float %24799 %325 + %10076 = OpConvertFToU %v4uint %7972 + %8714 = OpCompositeExtract %uint %10076 0 + %12265 = OpCompositeExtract %uint %10076 1 + %11571 = OpShiftLeftLogical %uint %12265 %int_10 + %19826 = OpBitwiseOr %uint %8714 %11571 + %21488 = OpCompositeExtract %uint %10076 2 + %8565 = OpShiftLeftLogical %uint %21488 %int_20 + %19827 = OpBitwiseOr %uint %19826 %8565 + %21489 = OpCompositeExtract %uint %10076 3 + %7294 = OpShiftLeftLogical %uint %21489 %int_30 + %9086 = OpBitwiseOr %uint %19827 %7294 + %9081 = OpExtInst %v4float %1 FClamp %11189 %2938 %1285 + %24800 = OpFMul %v4float %9081 %344 + %7973 = OpFAdd %v4float %24800 %325 + %10077 = OpConvertFToU %v4uint %7973 + %8715 = OpCompositeExtract %uint %10077 0 + %12266 = OpCompositeExtract %uint %10077 1 + %11572 = OpShiftLeftLogical %uint %12266 %int_10 + %19828 = OpBitwiseOr %uint %8715 %11572 + %21490 = OpCompositeExtract %uint %10077 2 + %8566 = OpShiftLeftLogical %uint %21490 %int_20 + %19829 = OpBitwiseOr %uint %19828 %8566 + %21491 = OpCompositeExtract %uint %10077 3 + %8543 = OpShiftLeftLogical %uint %21491 %int_30 + %20997 = OpBitwiseOr %uint %19829 %8543 + %21472 = OpCompositeConstruct %v4uint %9084 %9085 %9086 %20997 + OpBranch %18834 + %18070 = OpLabel + %7311 = OpExtInst %v4float %1 FClamp %14921 %2938 %1285 + %20339 = OpVectorTimesScalar %v4float %7311 %float_255 + %11883 = OpFAdd %v4float %20339 %325 + %7644 = OpConvertFToU %v4uint %11883 + %8716 = OpCompositeExtract %uint %7644 0 + %12267 = OpCompositeExtract %uint %7644 1 + %11573 = OpShiftLeftLogical %uint %12267 %int_8 + %19830 = OpBitwiseOr %uint %8716 %11573 + %21492 = OpCompositeExtract %uint %7644 2 + %8567 = OpShiftLeftLogical %uint %21492 %int_16 + %19831 = OpBitwiseOr %uint %19830 %8567 + %21493 = OpCompositeExtract %uint %7644 3 + %7295 = OpShiftLeftLogical %uint %21493 %int_24 + %9255 = OpBitwiseOr %uint %19831 %7295 + %7522 = OpExtInst %v4float %1 FClamp %15191 %2938 %1285 + %8264 = OpVectorTimesScalar %v4float %7522 %float_255 + %11884 = OpFAdd %v4float %8264 %325 + %7645 = OpConvertFToU %v4uint %11884 + %8717 = OpCompositeExtract %uint %7645 0 + %12268 = OpCompositeExtract %uint %7645 1 + %11574 = OpShiftLeftLogical %uint %12268 %int_8 + %19832 = OpBitwiseOr %uint %8717 %11574 + %21494 = OpCompositeExtract %uint %7645 2 + %8568 = OpShiftLeftLogical %uint %21494 %int_16 + %19833 = OpBitwiseOr %uint %19832 %8568 + %21495 = OpCompositeExtract %uint %7645 3 + %7296 = OpShiftLeftLogical %uint %21495 %int_24 + %9256 = OpBitwiseOr %uint %19833 %7296 + %7523 = OpExtInst %v4float %1 FClamp %14358 %2938 %1285 + %8265 = OpVectorTimesScalar %v4float %7523 %float_255 + %11885 = OpFAdd %v4float %8265 %325 + %7646 = OpConvertFToU %v4uint %11885 + %8718 = OpCompositeExtract %uint %7646 0 + %12269 = OpCompositeExtract %uint %7646 1 + %11575 = OpShiftLeftLogical %uint %12269 %int_8 + %19834 = OpBitwiseOr %uint %8718 %11575 + %21496 = OpCompositeExtract %uint %7646 2 + %8569 = OpShiftLeftLogical %uint %21496 %int_16 + %19835 = OpBitwiseOr %uint %19834 %8569 + %21497 = OpCompositeExtract %uint %7646 3 + %7297 = OpShiftLeftLogical %uint %21497 %int_24 + %9257 = OpBitwiseOr %uint %19835 %7297 + %7524 = OpExtInst %v4float %1 FClamp %11189 %2938 %1285 + %8266 = OpVectorTimesScalar %v4float %7524 %float_255 + %11886 = OpFAdd %v4float %8266 %325 + %7647 = OpConvertFToU %v4uint %11886 + %8719 = OpCompositeExtract %uint %7647 0 + %12270 = OpCompositeExtract %uint %7647 1 + %11576 = OpShiftLeftLogical %uint %12270 %int_8 + %19836 = OpBitwiseOr %uint %8719 %11576 + %21498 = OpCompositeExtract %uint %7647 2 + %8570 = OpShiftLeftLogical %uint %21498 %int_16 + %19837 = OpBitwiseOr %uint %19836 %8570 + %21499 = OpCompositeExtract %uint %7647 3 + %8544 = OpShiftLeftLogical %uint %21499 %int_24 + %20998 = OpBitwiseOr %uint %19837 %8544 + %21473 = OpCompositeConstruct %v4uint %9255 %9256 %9257 %20998 + OpBranch %18834 + %8194 = OpLabel + %12446 = OpCompositeExtract %float %14921 0 + %21144 = OpBitcast %uint %12446 + %20301 = OpCompositeExtract %float %15191 0 + %17693 = OpBitcast %uint %20301 + %20302 = OpCompositeExtract %float %14358 0 + %17694 = OpBitcast %uint %20302 + %20280 = OpCompositeExtract %float %11189 0 + %20246 = OpBitcast %uint %20280 + %10040 = OpCompositeConstruct %v4uint %21144 %17693 %17694 %20246 + OpBranch %18834 + %18834 = OpLabel + %24188 = OpPhi %v4uint %10040 %8194 %21473 %18070 %21472 %17899 %21471 %6453 %21470 %6452 %21469 %6451 %24879 %9492 + %24753 = OpIEqual %bool %7640 %uint_0 + OpSelectionMerge %13276 None + OpBranchConditional %24753 %11451 %13276 + %11451 = OpLabel + %24167 = OpCompositeExtract %uint %19124 0 + %22470 = OpINotEqual %bool %24167 %uint_0 + OpBranch %13276 + %13276 = OpLabel + %10955 = OpPhi %bool %24753 %18834 %22470 %11451 + OpSelectionMerge %19649 DontFlatten + OpBranchConditional %10955 %11508 %19649 + %11508 = OpLabel + %23599 = OpCompositeExtract %uint %19124 0 + %17346 = OpUGreaterThanEqual %bool %23599 %uint_2 + OpSelectionMerge %18757 None + OpBranchConditional %17346 %15877 %18757 + %15877 = OpLabel + %24532 = OpUGreaterThanEqual %bool %23599 %uint_3 + OpSelectionMerge %18756 None + OpBranchConditional %24532 %9760 %18756 + %9760 = OpLabel + %20482 = OpCompositeExtract %uint %24188 3 + %14335 = OpCompositeInsert %v4uint %20482 %24188 2 + OpBranch %18756 + %18756 = OpLabel + %17379 = OpPhi %v4uint %24188 %15877 %14335 %9760 + %7002 = OpCompositeExtract %uint %17379 2 + %15144 = OpCompositeInsert %v4uint %7002 %17379 1 + OpBranch %18757 + %18757 = OpLabel + %17380 = OpPhi %v4uint %24188 %11508 %15144 %18756 + %7003 = OpCompositeExtract %uint %17380 1 + %15145 = OpCompositeInsert %v4uint %7003 %17380 0 + OpBranch %19649 + %19649 = OpLabel + %9229 = OpPhi %v4uint %24188 %13276 %15145 %18757 + %19403 = OpIAdd %v2uint %12025 %23020 + %13244 = OpCompositeExtract %uint %19403 0 + %9555 = OpCompositeExtract %uint %19403 1 + %11053 = OpShiftRightLogical %uint %13244 %uint_2 + %7832 = OpCompositeConstruct %v2uint %11053 %9555 + %24920 = OpUDiv %v2uint %7832 %23601 + %13932 = OpCompositeExtract %uint %24920 0 + %19770 = OpShiftLeftLogical %uint %13932 %uint_2 + %24251 = OpCompositeExtract %uint %24920 1 + %21459 = OpCompositeConstruct %v3uint %19770 %24251 %24434 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %20495 %22217 %10956 + %10956 = OpLabel + %7339 = OpVectorShuffle %v2uint %21459 %21459 0 1 + %22991 = OpBitcast %v2int %7339 + %6431 = OpCompositeExtract %int %22991 0 + %9469 = OpShiftRightArithmetic %int %6431 %int_5 + %10055 = OpCompositeExtract %int %22991 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %15783 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10957 = OpBitwiseAnd %int %6431 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17303 = OpIAdd %int %10957 %17741 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15435 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18366 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18366 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12151 + %19171 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19171 %int_2 + %16716 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6431 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21588 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21588 %int_6 + %15436 = OpIAdd %int %16716 %21580 + %11782 = OpBitwiseAnd %int %16727 %int_63 + %14671 = OpIAdd %int %15436 %11782 + %22127 = OpBitcast %uint %14671 + OpBranch %21313 + %22217 = OpLabel + %6573 = OpBitcast %v3int %21459 + %17090 = OpCompositeExtract %int %6573 1 + %9470 = OpShiftRightArithmetic %int %17090 %int_4 + %10056 = OpCompositeExtract %int %6573 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %25203 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %15783 %uint_5 + %12439 = OpBitcast %int %9032 + %10367 = OpIMul %int %15143 %12439 + %25154 = OpCompositeExtract %int %6573 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10367 + %8797 = OpShiftLeftLogical %int %18940 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12601 = OpBitwiseAnd %int %17090 %int_6 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7052 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7052 %int_6 + %8736 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8736 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19172 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19172 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18367 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18367 %uint_8 + %16729 = OpIAdd %int %10332 %21582 + %19173 = OpBitwiseAnd %int %17090 %int_1 + %21583 = OpShiftLeftLogical %int %19173 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10958 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10958 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10959 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10959 %int_3 + %21849 = OpBitwiseAnd %int %16730 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22128 = OpBitcast %uint %24314 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22128 %22217 %22127 %10956 + %16310 = OpIMul %v2uint %24920 %23601 + %16261 = OpISub %v2uint %7832 %16310 + %17551 = OpCompositeExtract %uint %23601 1 + %23632 = OpIMul %uint %8858 %17551 + %15520 = OpIMul %uint %9468 %23632 + %16084 = OpCompositeExtract %uint %16261 0 + %15890 = OpIMul %uint %16084 %17551 + %6887 = OpCompositeExtract %uint %16261 1 + %11045 = OpIAdd %uint %15890 %6887 + %24733 = OpShiftLeftLogical %uint %11045 %uint_2 + %23219 = OpBitwiseAnd %uint %13244 %uint_3 + %9559 = OpIAdd %uint %24733 %23219 + %17811 = OpShiftLeftLogical %uint %9559 %uint_2 + %8267 = OpIAdd %uint %15520 %17811 + %8213 = OpShiftRightLogical %uint %8267 %uint_4 + %12010 = OpIEqual %bool %19164 %uint_1 + %22390 = OpIEqual %bool %19164 %uint_2 + %22150 = OpLogicalOr %bool %12010 %22390 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %9229 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %9229 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16377 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22650 = OpPhi %v4uint %9229 %21313 %16377 %10583 + %19638 = OpIEqual %bool %19164 %uint_3 + %15139 = OpLogicalOr %bool %22390 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22650 %749 + %15335 = OpShiftRightLogical %v4uint %22650 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22650 %13411 %10728 %11064 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %8213 + OpStore %8053 %19767 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_full_32bpp_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x0000629D, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00040047, 0x000007D0, 0x00000006, 0x00000004, + 0x00030047, 0x0000079C, 0x00000003, 0x00040048, 0x0000079C, 0x00000000, 0x00000018, 0x00050048, + 0x0000079C, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000CC7, 0x00000018, 0x00040047, + 0x00000CC7, 0x00000021, 0x00000000, 0x00040047, 0x00000CC7, 0x00000022, 0x00000000, 0x00030047, + 0x000003F9, 0x00000002, 0x00050048, 0x000003F9, 0x00000000, 0x00000023, 0x00000000, 0x00050048, + 0x000003F9, 0x00000001, 0x00000023, 0x00000004, 0x00050048, 0x000003F9, 0x00000002, 0x00000023, + 0x00000008, 0x00050048, 0x000003F9, 0x00000003, 0x00000023, 0x0000000C, 0x00040047, 0x00000F48, + 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, 0x000007B4, + 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000019, 0x00050048, 0x000007B4, 0x00000000, + 0x00000023, 0x00000000, 0x00030047, 0x00001592, 0x00000019, 0x00040047, 0x00001592, 0x00000021, + 0x00000000, 0x00040047, 0x00001592, 0x00000022, 0x00000001, 0x00040047, 0x00000AC9, 0x0000000B, + 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040015, 0x0000000B, + 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, + 0x0000000B, 0x00000003, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00030016, 0x0000000D, + 0x00000020, 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x00040017, 0x00000018, 0x0000000D, + 0x00000003, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x00020014, 0x00000009, 0x00040017, + 0x00000016, 0x0000000C, 0x00000003, 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, 0x0004002B, + 0x0000000D, 0x0000008A, 0x3F800000, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, + 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, + 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, + 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, + 0x0000000D, 0x00000540, 0x437F0000, 0x0004002B, 0x0000000D, 0x000000FC, 0x3F000000, 0x0004002B, + 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, + 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000A53, 0x00000018, 0x0004002B, + 0x0000000D, 0x00000409, 0x447FC000, 0x0004002B, 0x0000000D, 0x00000BA2, 0x40400000, 0x0007002C, + 0x0000001D, 0x00000158, 0x00000409, 0x00000409, 0x00000409, 0x00000BA2, 0x0004002B, 0x0000000C, + 0x00000A29, 0x0000000A, 0x0004002B, 0x0000000C, 0x00000A47, 0x00000014, 0x0004002B, 0x0000000C, + 0x00000A65, 0x0000001E, 0x0004002B, 0x0000000D, 0x0000057F, 0x44FFE000, 0x0006002C, 0x00000018, + 0x000008E3, 0x0000057F, 0x0000057F, 0x00000409, 0x0004002B, 0x0000000C, 0x00000A2C, 0x0000000B, + 0x0004002B, 0x0000000C, 0x00000A4D, 0x00000016, 0x0006002C, 0x00000018, 0x0000000E, 0x00000409, + 0x0000057F, 0x0000057F, 0x0004002B, 0x0000000C, 0x00000A4A, 0x00000015, 0x0004002B, 0x0000000D, + 0x0000022D, 0x477FFF00, 0x0004002B, 0x0000000B, 0x00000A52, 0x00000018, 0x0007002C, 0x00000017, + 0x0000028D, 0x00000A0A, 0x00000A22, 0x00000A3A, 0x00000A52, 0x0004002B, 0x0000000B, 0x00000144, + 0x000000FF, 0x0004002B, 0x0000000D, 0x0000017A, 0x3B808081, 0x0004002B, 0x0000000B, 0x00000A28, + 0x0000000A, 0x0004002B, 0x0000000B, 0x00000A46, 0x00000014, 0x0004002B, 0x0000000B, 0x00000A64, + 0x0000001E, 0x0007002C, 0x00000017, 0x0000034D, 0x00000A0A, 0x00000A28, 0x00000A46, 0x00000A64, + 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, 0x0007002C, 0x00000017, 0x0000027B, 0x00000A44, + 0x00000A44, 0x00000A44, 0x00000A13, 0x0004002B, 0x0000000D, 0x000006FE, 0x3A802008, 0x0004002B, + 0x0000000D, 0x00000149, 0x3EAAAAAB, 0x0007002C, 0x0000001D, 0x00000AEE, 0x000006FE, 0x000006FE, + 0x000006FE, 0x00000149, 0x0006002C, 0x00000014, 0x00000BB4, 0x00000A0A, 0x00000A28, 0x00000A46, + 0x0004002B, 0x0000000B, 0x00000B87, 0x0000007F, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x00040017, 0x00000010, 0x00000009, 0x00000003, 0x0004002B, 0x0000000B, 0x00000B7E, 0x0000007C, + 0x0004002B, 0x0000000B, 0x00000A4F, 0x00000017, 0x0004002B, 0x0000000D, 0x00000341, 0xBF800000, + 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x0005002C, 0x00000012, 0x000007A7, 0x00000A3B, + 0x00000A0B, 0x0004002B, 0x0000000D, 0x000007FE, 0x3A800100, 0x00040017, 0x0000001A, 0x0000000C, + 0x00000004, 0x0007002C, 0x0000001A, 0x00000122, 0x00000A3B, 0x00000A0B, 0x00000A3B, 0x00000A0B, + 0x0005002C, 0x00000011, 0x0000072D, 0x00000A10, 0x00000A0D, 0x00040017, 0x0000000F, 0x00000009, + 0x00000002, 0x0005002C, 0x00000011, 0x0000070F, 0x00000A0A, 0x00000A0A, 0x0005002C, 0x00000011, + 0x00000724, 0x00000A0D, 0x00000A0D, 0x0005002C, 0x00000011, 0x00000718, 0x00000A0D, 0x00000A0A, + 0x0004002B, 0x0000000B, 0x00000AFA, 0x00000050, 0x0005002C, 0x00000011, 0x00000A9F, 0x00000AFA, + 0x00000A3A, 0x0004002B, 0x0000000B, 0x00000A84, 0x00000800, 0x0004002B, 0x0000000C, 0x00000A1A, + 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000C, 0x00000A20, + 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, + 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, + 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, + 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, + 0x00000003, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A1D, + 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, + 0x00000004, 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, 0x0004002B, 0x0000000C, 0x0000078B, + 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0003001D, 0x000007D0, 0x0000000B, + 0x0003001E, 0x0000079C, 0x000007D0, 0x00040020, 0x00000A1B, 0x00000002, 0x0000079C, 0x0004003B, + 0x00000A1B, 0x00000CC7, 0x00000002, 0x00040020, 0x00000288, 0x00000002, 0x0000000B, 0x0006001E, + 0x000003F9, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000676, 0x00000009, + 0x000003F9, 0x0004003B, 0x00000676, 0x00000CE9, 0x00000009, 0x00040020, 0x00000289, 0x00000009, + 0x0000000B, 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, 0x0004002B, 0x0000000B, 0x00000A81, + 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, 0x0004002B, 0x0000000B, 0x00000A5E, + 0x0000001C, 0x0004002B, 0x0000000B, 0x00000A43, 0x00000013, 0x0005002C, 0x00000011, 0x00000883, + 0x00000A3A, 0x00000A43, 0x0004002B, 0x0000000B, 0x00000510, 0x20000000, 0x0005002C, 0x00000011, + 0x0000073F, 0x00000A0A, 0x00000A16, 0x0004002B, 0x0000000B, 0x00000AC7, 0x0000003F, 0x0004002B, + 0x0000000C, 0x00000A59, 0x0000001A, 0x0004002B, 0x0000000C, 0x00000A50, 0x00000017, 0x0004002B, + 0x0000000B, 0x00000926, 0x01000000, 0x0005002C, 0x00000011, 0x000008E4, 0x00000A46, 0x00000A52, + 0x00040020, 0x00000291, 0x00000001, 0x00000014, 0x0004003B, 0x00000291, 0x00000F48, 0x00000001, + 0x0005002C, 0x00000011, 0x00000721, 0x00000A10, 0x00000A0A, 0x0003001D, 0x000007DC, 0x00000017, + 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, 0x0004003B, + 0x00000A32, 0x00001592, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0006002C, + 0x00000014, 0x00000AC9, 0x00000A22, 0x00000A22, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, + 0x00000A1F, 0x00000A1F, 0x0005002C, 0x00000011, 0x000007A3, 0x00000A37, 0x00000A0D, 0x0005002C, + 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, 0x0005002C, 0x00000011, 0x0000084A, 0x00000A37, + 0x00000A37, 0x0007002C, 0x0000001D, 0x00000504, 0x00000341, 0x00000341, 0x00000341, 0x00000341, + 0x0007002C, 0x0000001A, 0x00000302, 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x0007002C, + 0x00000017, 0x0000064B, 0x00000144, 0x00000144, 0x00000144, 0x00000144, 0x0006002C, 0x00000014, + 0x00000105, 0x00000A44, 0x00000A44, 0x00000A44, 0x0006002C, 0x00000014, 0x00000466, 0x00000B87, + 0x00000B87, 0x00000B87, 0x0006002C, 0x00000014, 0x00000B0C, 0x00000A1F, 0x00000A1F, 0x00000A1F, + 0x0006002C, 0x00000014, 0x00000A12, 0x00000A0A, 0x00000A0A, 0x00000A0A, 0x0006002C, 0x00000014, + 0x000003FA, 0x00000B7E, 0x00000B7E, 0x00000B7E, 0x0006002C, 0x00000014, 0x00000189, 0x00000A4F, + 0x00000A4F, 0x00000A4F, 0x0006002C, 0x00000014, 0x0000008D, 0x00000A3A, 0x00000A3A, 0x00000A3A, + 0x0005002C, 0x00000013, 0x00000049, 0x00000341, 0x00000341, 0x0005002C, 0x00000012, 0x00000867, + 0x00000A3B, 0x00000A3B, 0x0007002C, 0x0000001D, 0x00000B7A, 0x00000A0C, 0x00000A0C, 0x00000A0C, + 0x00000A0C, 0x0007002C, 0x0000001D, 0x00000505, 0x0000008A, 0x0000008A, 0x0000008A, 0x0000008A, + 0x0007002C, 0x0000001D, 0x00000145, 0x000000FC, 0x000000FC, 0x000000FC, 0x000000FC, 0x0006002C, + 0x00000018, 0x00000A2D, 0x00000A0C, 0x00000A0C, 0x00000A0C, 0x0006002C, 0x00000018, 0x00000A18, + 0x0000008A, 0x0000008A, 0x0000008A, 0x0006002C, 0x00000018, 0x000003AB, 0x000000FC, 0x000000FC, + 0x000000FC, 0x0005002C, 0x00000013, 0x0000071F, 0x00000A0C, 0x00000A0C, 0x0005002C, 0x00000013, + 0x00000300, 0x0000008A, 0x0000008A, 0x0005002C, 0x00000013, 0x0000061E, 0x000000FC, 0x000000FC, + 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, + 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, + 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, + 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, + 0x0004002B, 0x0000000C, 0x00000089, 0x3F800000, 0x0004002B, 0x0000000B, 0x000009F8, 0xFFFFFFFA, + 0x0006002C, 0x00000014, 0x00000938, 0x000009F8, 0x000009F8, 0x000009F8, 0x0004002B, 0x0000000D, + 0x0000016E, 0x3E800000, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, + 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, + 0x00002E68, 0x00050041, 0x00000289, 0x000056E5, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, + 0x00003D0B, 0x000056E5, 0x00050041, 0x00000289, 0x000058AC, 0x00000CE9, 0x00000A0E, 0x0004003D, + 0x0000000B, 0x00005158, 0x000058AC, 0x000500C7, 0x0000000B, 0x00005051, 0x00003D0B, 0x00000A44, + 0x000500C2, 0x0000000B, 0x00004E0A, 0x00003D0B, 0x00000A28, 0x000500C7, 0x0000000B, 0x0000217E, + 0x00004E0A, 0x00000A13, 0x000500C2, 0x0000000B, 0x0000520A, 0x00003D0B, 0x00000A31, 0x000500C7, + 0x0000000B, 0x0000217F, 0x0000520A, 0x00000A81, 0x000500C2, 0x0000000B, 0x0000520B, 0x00003D0B, + 0x00000A52, 0x000500C7, 0x0000000B, 0x00002180, 0x0000520B, 0x00000A37, 0x000500C2, 0x0000000B, + 0x00004994, 0x00003D0B, 0x00000A5E, 0x000500C7, 0x0000000B, 0x000023AA, 0x00004994, 0x00000A0D, + 0x00050050, 0x00000011, 0x000022A7, 0x00005158, 0x00005158, 0x000500C2, 0x00000011, 0x000025A1, + 0x000022A7, 0x00000883, 0x000500C7, 0x00000011, 0x00005C31, 0x000025A1, 0x000007A2, 0x000500C7, + 0x0000000B, 0x00005DDE, 0x00003D0B, 0x00000510, 0x000500AB, 0x00000009, 0x00003007, 0x00005DDE, + 0x00000A0A, 0x000300F7, 0x00003954, 0x00000000, 0x000400FA, 0x00003007, 0x00004163, 0x000055E8, + 0x000200F8, 0x000055E8, 0x000200F9, 0x00003954, 0x000200F8, 0x00004163, 0x000500C2, 0x00000011, + 0x00003BAE, 0x00005C31, 0x00000724, 0x000200F9, 0x00003954, 0x000200F8, 0x00003954, 0x000700F5, + 0x00000011, 0x00004AB4, 0x00003BAE, 0x00004163, 0x0000070F, 0x000055E8, 0x000500C2, 0x00000011, + 0x00001B7E, 0x000022A7, 0x0000073F, 0x000500C7, 0x00000011, 0x00002DF9, 0x00001B7E, 0x000007A3, + 0x000500C4, 0x00000011, 0x00003F4F, 0x00002DF9, 0x0000074E, 0x00050084, 0x00000011, 0x000059EB, + 0x00003F4F, 0x00005C31, 0x000500C2, 0x0000000B, 0x00003343, 0x00005158, 0x00000A19, 0x000500C7, + 0x0000000B, 0x000039C1, 0x00003343, 0x00000A81, 0x00050051, 0x0000000B, 0x0000229A, 0x00005C31, + 0x00000000, 0x00050084, 0x0000000B, 0x000059D1, 0x000039C1, 0x0000229A, 0x00050041, 0x00000289, + 0x00004E44, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x000048C4, 0x00004E44, 0x00050041, + 0x00000289, 0x000058AD, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x000051B7, 0x000058AD, + 0x000500C7, 0x0000000B, 0x00004ADC, 0x000048C4, 0x00000A1F, 0x000500C7, 0x0000000B, 0x000055EF, + 0x000048C4, 0x00000A22, 0x000500AB, 0x00000009, 0x0000500F, 0x000055EF, 0x00000A0A, 0x000500C2, + 0x0000000B, 0x00002843, 0x000048C4, 0x00000A16, 0x000500C7, 0x0000000B, 0x00005F72, 0x00002843, + 0x00000A1F, 0x000500C2, 0x0000000B, 0x00004CD8, 0x000048C4, 0x00000A1F, 0x000500C7, 0x0000000B, + 0x00005093, 0x00004CD8, 0x00000AC7, 0x0004007C, 0x0000000C, 0x00005988, 0x000048C4, 0x000500C4, + 0x0000000C, 0x0000358F, 0x00005988, 0x00000A29, 0x000500C3, 0x0000000C, 0x0000509C, 0x0000358F, + 0x00000A59, 0x000500C4, 0x0000000C, 0x00004702, 0x0000509C, 0x00000A50, 0x00050080, 0x0000000C, + 0x00001D26, 0x00004702, 0x00000089, 0x0004007C, 0x0000000D, 0x00002B2C, 0x00001D26, 0x000500C7, + 0x0000000B, 0x00005879, 0x000048C4, 0x00000926, 0x000500AB, 0x00000009, 0x00001D59, 0x00005879, + 0x00000A0A, 0x000500C7, 0x0000000B, 0x00001F43, 0x000051B7, 0x00000A44, 0x000500C4, 0x0000000B, + 0x00003DA7, 0x00001F43, 0x00000A19, 0x000500C2, 0x0000000B, 0x0000583F, 0x000051B7, 0x00000A28, + 0x000500C7, 0x0000000B, 0x00004BBE, 0x0000583F, 0x00000A44, 0x000500C4, 0x0000000B, 0x00006273, + 0x00004BBE, 0x00000A19, 0x00050050, 0x00000011, 0x000028B6, 0x000051B7, 0x000051B7, 0x000500C2, + 0x00000011, 0x00002891, 0x000028B6, 0x000008E4, 0x000500C7, 0x00000011, 0x00005B53, 0x00002891, + 0x0000084A, 0x000500C4, 0x00000011, 0x00003F50, 0x00005B53, 0x0000074E, 0x00050084, 0x00000011, + 0x000059EC, 0x00003F50, 0x00005C31, 0x000500C2, 0x0000000B, 0x000031C7, 0x000051B7, 0x00000A5E, + 0x000500C7, 0x0000000B, 0x00004356, 0x000031C7, 0x00000A1F, 0x0004003D, 0x00000014, 0x000031C1, + 0x00000F48, 0x0007004F, 0x00000011, 0x000038A4, 0x000031C1, 0x000031C1, 0x00000000, 0x00000001, + 0x000500C4, 0x00000011, 0x00002EF9, 0x000038A4, 0x00000721, 0x00050051, 0x0000000B, 0x00001DD8, + 0x00002EF9, 0x00000000, 0x000500C4, 0x0000000B, 0x00002D8A, 0x000059D1, 0x00000A13, 0x000500AE, + 0x00000009, 0x00003C13, 0x00001DD8, 0x00002D8A, 0x000300F7, 0x000036C9, 0x00000002, 0x000400FA, + 0x00003C13, 0x000055E9, 0x000036C9, 0x000200F8, 0x000055E9, 0x000200F9, 0x00004C7A, 0x000200F8, + 0x000036C9, 0x00050051, 0x0000000B, 0x000048B7, 0x00002EF9, 0x00000001, 0x00050051, 0x0000000B, + 0x000041A3, 0x00004AB4, 0x00000001, 0x0007000C, 0x0000000B, 0x00005F7E, 0x00000001, 0x00000029, + 0x000048B7, 0x000041A3, 0x00050050, 0x00000011, 0x000051EF, 0x00001DD8, 0x00005F7E, 0x00050080, + 0x00000011, 0x0000522C, 0x000051EF, 0x000059EB, 0x000500B2, 0x00000009, 0x00003ECB, 0x00004356, + 0x00000A13, 0x000300F7, 0x00005CE0, 0x00000000, 0x000400FA, 0x00003ECB, 0x00002AEE, 0x00003AEF, + 0x000200F8, 0x00003AEF, 0x000500AA, 0x00000009, 0x000034FE, 0x00004356, 0x00000A19, 0x000600A9, + 0x0000000B, 0x000020F6, 0x000034FE, 0x00000A10, 0x00000A0A, 0x000200F9, 0x00005CE0, 0x000200F8, + 0x00002AEE, 0x000200F9, 0x00005CE0, 0x000200F8, 0x00005CE0, 0x000700F5, 0x0000000B, 0x00004B64, + 0x00004356, 0x00002AEE, 0x000020F6, 0x00003AEF, 0x00050050, 0x00000011, 0x000041BE, 0x0000217E, + 0x0000217E, 0x000500AE, 0x0000000F, 0x00002E19, 0x000041BE, 0x0000072D, 0x000600A9, 0x00000011, + 0x00004BB5, 0x00002E19, 0x00000724, 0x0000070F, 0x000500C4, 0x00000011, 0x00002AEA, 0x0000522C, + 0x00004BB5, 0x00050050, 0x00000011, 0x0000605D, 0x00004B64, 0x00004B64, 0x000500C2, 0x00000011, + 0x00002385, 0x0000605D, 0x00000718, 0x000500C7, 0x00000011, 0x00003EC8, 0x00002385, 0x00000724, + 0x00050080, 0x00000011, 0x000046BA, 0x00002AEA, 0x00003EC8, 0x00050084, 0x00000011, 0x00005998, + 0x00000A9F, 0x00005C31, 0x00050050, 0x00000011, 0x00002C44, 0x000023AA, 0x00000A0A, 0x000500C2, + 0x00000011, 0x000019AB, 0x00005998, 0x00002C44, 0x00050086, 0x00000011, 0x000027A2, 0x000046BA, + 0x000019AB, 0x00050051, 0x0000000B, 0x00004FA6, 0x000027A2, 0x00000001, 0x00050084, 0x0000000B, + 0x00002B26, 0x00004FA6, 0x00005051, 0x00050051, 0x0000000B, 0x00006059, 0x000027A2, 0x00000000, + 0x00050080, 0x0000000B, 0x00005420, 0x00002B26, 0x00006059, 0x00050080, 0x0000000B, 0x00002226, + 0x0000217F, 0x00005420, 0x00050084, 0x00000011, 0x00005768, 0x000027A2, 0x000019AB, 0x00050082, + 0x00000011, 0x000050EB, 0x000046BA, 0x00005768, 0x00050051, 0x0000000B, 0x00001C87, 0x00005998, + 0x00000000, 0x00050051, 0x0000000B, 0x00005962, 0x00005998, 0x00000001, 0x00050084, 0x0000000B, + 0x00003372, 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, 0x000038D7, 0x00002226, 0x00003372, + 0x00050051, 0x0000000B, 0x00001A95, 0x000050EB, 0x00000001, 0x00050051, 0x0000000B, 0x00005BE6, + 0x000019AB, 0x00000000, 0x00050084, 0x0000000B, 0x00005966, 0x00001A95, 0x00005BE6, 0x00050051, + 0x0000000B, 0x00001AE6, 0x000050EB, 0x00000000, 0x00050080, 0x0000000B, 0x000025E0, 0x00005966, + 0x00001AE6, 0x000500C4, 0x0000000B, 0x00004665, 0x000025E0, 0x000023AA, 0x00050080, 0x0000000B, + 0x000047BB, 0x000038D7, 0x00004665, 0x00050084, 0x0000000B, 0x000034C0, 0x00003372, 0x00000A84, + 0x00050089, 0x0000000B, 0x0000628F, 0x000047BB, 0x000034C0, 0x000500AE, 0x00000009, 0x00003FFB, + 0x0000217E, 0x00000A10, 0x000600A9, 0x0000000B, 0x0000609F, 0x00003FFB, 0x00000A0D, 0x00000A0A, + 0x00050080, 0x0000000B, 0x00004E6A, 0x000023AA, 0x0000609F, 0x000500C4, 0x0000000B, 0x0000199B, + 0x00000A0D, 0x00004E6A, 0x000500AB, 0x00000009, 0x00005AEF, 0x000023AA, 0x00000A0A, 0x000300F7, + 0x0000530F, 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B65, 0x000040B9, 0x000200F8, 0x000040B9, + 0x000500AA, 0x00000009, 0x00004ADA, 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F49, 0x00000002, + 0x000400FA, 0x00004ADA, 0x00002621, 0x00002F61, 0x000200F8, 0x00002F61, 0x00060041, 0x00000288, + 0x00004BCF, 0x00000CC7, 0x00000A0B, 0x0000628F, 0x0004003D, 0x0000000B, 0x00005D43, 0x00004BCF, + 0x00050080, 0x0000000B, 0x00002DA7, 0x0000628F, 0x0000199B, 0x00060041, 0x00000288, 0x0000194B, + 0x00000CC7, 0x00000A0B, 0x00002DA7, 0x0004003D, 0x0000000B, 0x00005E5B, 0x0000194B, 0x00050084, + 0x0000000B, 0x0000185A, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A1, 0x0000628F, + 0x0000185A, 0x00060041, 0x00000288, 0x00003BCD, 0x00000CC7, 0x00000A0B, 0x000020A1, 0x0004003D, + 0x0000000B, 0x00005E5C, 0x00003BCD, 0x00050084, 0x0000000B, 0x0000185B, 0x00000A13, 0x0000199B, + 0x00050080, 0x0000000B, 0x000020A2, 0x0000628F, 0x0000185B, 0x00060041, 0x00000288, 0x000037F1, + 0x00000CC7, 0x00000A0B, 0x000020A2, 0x0004003D, 0x0000000B, 0x00003FFC, 0x000037F1, 0x00070050, + 0x00000017, 0x0000512C, 0x00005D43, 0x00005E5B, 0x00005E5C, 0x00003FFC, 0x000200F9, 0x00004F49, + 0x000200F8, 0x00002621, 0x00060041, 0x00000288, 0x00005545, 0x00000CC7, 0x00000A0B, 0x0000628F, + 0x0004003D, 0x0000000B, 0x00005D44, 0x00005545, 0x00050080, 0x0000000B, 0x00002DA8, 0x0000628F, + 0x00000A0D, 0x00060041, 0x00000288, 0x000018FF, 0x00000CC7, 0x00000A0B, 0x00002DA8, 0x0004003D, + 0x0000000B, 0x00005C62, 0x000018FF, 0x00050080, 0x0000000B, 0x00002DA9, 0x0000628F, 0x00000A10, + 0x00060041, 0x00000288, 0x00001900, 0x00000CC7, 0x00000A0B, 0x00002DA9, 0x0004003D, 0x0000000B, + 0x00005C63, 0x00001900, 0x00050080, 0x0000000B, 0x00002DAA, 0x0000628F, 0x00000A13, 0x00060041, + 0x00000288, 0x00005FEE, 0x00000CC7, 0x00000A0B, 0x00002DAA, 0x0004003D, 0x0000000B, 0x00003FFD, + 0x00005FEE, 0x00070050, 0x00000017, 0x0000512D, 0x00005D44, 0x00005C62, 0x00005C63, 0x00003FFD, + 0x000200F9, 0x00004F49, 0x000200F8, 0x00004F49, 0x000700F5, 0x00000017, 0x00002ABF, 0x0000512D, + 0x00002621, 0x0000512C, 0x00002F61, 0x000300F7, 0x00003F60, 0x00000000, 0x001300FB, 0x00002180, + 0x00004BFB, 0x00000000, 0x000038F9, 0x00000001, 0x000038F9, 0x00000002, 0x00001CBB, 0x0000000A, + 0x00001CBB, 0x00000003, 0x00001CBA, 0x0000000C, 0x00001CBA, 0x00000004, 0x00001FFE, 0x00000006, + 0x00002033, 0x000200F8, 0x00002033, 0x00050051, 0x0000000B, 0x00005F56, 0x00002ABF, 0x00000000, + 0x0006000C, 0x00000013, 0x00006067, 0x00000001, 0x0000003E, 0x00005F56, 0x00050051, 0x0000000D, + 0x00002762, 0x00006067, 0x00000000, 0x00050051, 0x0000000D, 0x00004446, 0x00006067, 0x00000001, + 0x00070050, 0x0000001D, 0x0000390C, 0x00002762, 0x00004446, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x0000437A, 0x00002ABF, 0x00000001, 0x0006000C, 0x00000013, 0x0000466B, 0x00000001, + 0x0000003E, 0x0000437A, 0x00050051, 0x0000000D, 0x00002763, 0x0000466B, 0x00000000, 0x00050051, + 0x0000000D, 0x00004447, 0x0000466B, 0x00000001, 0x00070050, 0x0000001D, 0x0000390D, 0x00002763, + 0x00004447, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x0000437B, 0x00002ABF, 0x00000002, + 0x0006000C, 0x00000013, 0x0000466C, 0x00000001, 0x0000003E, 0x0000437B, 0x00050051, 0x0000000D, + 0x00002764, 0x0000466C, 0x00000000, 0x00050051, 0x0000000D, 0x00004448, 0x0000466C, 0x00000001, + 0x00070050, 0x0000001D, 0x0000390E, 0x00002764, 0x00004448, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x0000437C, 0x00002ABF, 0x00000003, 0x0006000C, 0x00000013, 0x0000466D, 0x00000001, + 0x0000003E, 0x0000437C, 0x00050051, 0x0000000D, 0x00002765, 0x0000466D, 0x00000000, 0x00050051, + 0x0000000D, 0x000050BE, 0x0000466D, 0x00000001, 0x00070050, 0x0000001D, 0x00002349, 0x00002765, + 0x000050BE, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F60, 0x000200F8, 0x00001FFE, 0x00050051, + 0x0000000B, 0x0000308B, 0x00002ABF, 0x00000000, 0x0004007C, 0x0000000C, 0x0000589D, 0x0000308B, + 0x00050050, 0x00000012, 0x0000471A, 0x0000589D, 0x0000589D, 0x000500C4, 0x00000012, 0x000047AD, + 0x0000471A, 0x000007A7, 0x000500C3, 0x00000012, 0x00003417, 0x000047AD, 0x00000867, 0x0004006F, + 0x00000013, 0x00002A97, 0x00003417, 0x0005008E, 0x00000013, 0x00004747, 0x00002A97, 0x000007FE, + 0x0007000C, 0x00000013, 0x00005E06, 0x00000001, 0x00000028, 0x00000049, 0x00004747, 0x00050051, + 0x0000000D, 0x00005F0A, 0x00005E06, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD4, 0x00005E06, + 0x00000001, 0x00070050, 0x0000001D, 0x0000411E, 0x00005F0A, 0x00003CD4, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x00004C42, 0x00002ABF, 0x00000001, 0x0004007C, 0x0000000C, 0x00003EA1, + 0x00004C42, 0x00050050, 0x00000012, 0x0000471B, 0x00003EA1, 0x00003EA1, 0x000500C4, 0x00000012, + 0x000047AE, 0x0000471B, 0x000007A7, 0x000500C3, 0x00000012, 0x00003418, 0x000047AE, 0x00000867, + 0x0004006F, 0x00000013, 0x00002A98, 0x00003418, 0x0005008E, 0x00000013, 0x00004748, 0x00002A98, + 0x000007FE, 0x0007000C, 0x00000013, 0x00005E07, 0x00000001, 0x00000028, 0x00000049, 0x00004748, + 0x00050051, 0x0000000D, 0x00005F0B, 0x00005E07, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD5, + 0x00005E07, 0x00000001, 0x00070050, 0x0000001D, 0x0000411F, 0x00005F0B, 0x00003CD5, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C43, 0x00002ABF, 0x00000002, 0x0004007C, 0x0000000C, + 0x00003EA2, 0x00004C43, 0x00050050, 0x00000012, 0x0000471C, 0x00003EA2, 0x00003EA2, 0x000500C4, + 0x00000012, 0x000047AF, 0x0000471C, 0x000007A7, 0x000500C3, 0x00000012, 0x00003419, 0x000047AF, + 0x00000867, 0x0004006F, 0x00000013, 0x00002A99, 0x00003419, 0x0005008E, 0x00000013, 0x00004749, + 0x00002A99, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E08, 0x00000001, 0x00000028, 0x00000049, + 0x00004749, 0x00050051, 0x0000000D, 0x00005F0C, 0x00005E08, 0x00000000, 0x00050051, 0x0000000D, + 0x00003CD6, 0x00005E08, 0x00000001, 0x00070050, 0x0000001D, 0x00004120, 0x00005F0C, 0x00003CD6, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C44, 0x00002ABF, 0x00000003, 0x0004007C, + 0x0000000C, 0x00003EA3, 0x00004C44, 0x00050050, 0x00000012, 0x0000471D, 0x00003EA3, 0x00003EA3, + 0x000500C4, 0x00000012, 0x000047B0, 0x0000471D, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341A, + 0x000047B0, 0x00000867, 0x0004006F, 0x00000013, 0x00002A9A, 0x0000341A, 0x0005008E, 0x00000013, + 0x0000474A, 0x00002A9A, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E09, 0x00000001, 0x00000028, + 0x00000049, 0x0000474A, 0x00050051, 0x0000000D, 0x00005F0D, 0x00005E09, 0x00000000, 0x00050051, + 0x0000000D, 0x0000494C, 0x00005E09, 0x00000001, 0x00070050, 0x0000001D, 0x0000234A, 0x00005F0D, + 0x0000494C, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F60, 0x000200F8, 0x00001CBA, 0x00050051, + 0x0000000B, 0x000056BD, 0x00002ABF, 0x00000000, 0x00060050, 0x00000014, 0x00004F0A, 0x000056BD, + 0x000056BD, 0x000056BD, 0x000500C2, 0x00000014, 0x00002B0D, 0x00004F0A, 0x00000BB4, 0x000500C7, + 0x00000014, 0x00005DE6, 0x00002B0D, 0x00000105, 0x000500C7, 0x00000014, 0x0000489C, 0x00005DE6, + 0x00000466, 0x000500C2, 0x00000014, 0x00005B90, 0x00005DE6, 0x00000B0C, 0x000500AA, 0x00000010, + 0x000040C9, 0x00005B90, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4B, 0x00000001, 0x0000004B, + 0x0000489C, 0x0004007C, 0x00000014, 0x00002A15, 0x00002C4B, 0x00050082, 0x00000014, 0x0000187A, + 0x00000B0C, 0x00002A15, 0x00050080, 0x00000014, 0x00002210, 0x00002A15, 0x00000938, 0x000600A9, + 0x00000014, 0x0000286F, 0x000040C9, 0x00002210, 0x00005B90, 0x000500C4, 0x00000014, 0x00005AD4, + 0x0000489C, 0x0000187A, 0x000500C7, 0x00000014, 0x0000499A, 0x00005AD4, 0x00000466, 0x000600A9, + 0x00000014, 0x00002A9D, 0x000040C9, 0x0000499A, 0x0000489C, 0x00050080, 0x00000014, 0x00005FF9, + 0x0000286F, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F7F, 0x00005FF9, 0x00000189, 0x000500C4, + 0x00000014, 0x00003FA6, 0x00002A9D, 0x0000008D, 0x000500C5, 0x00000014, 0x0000577C, 0x00004F7F, + 0x00003FA6, 0x000500AA, 0x00000010, 0x00003600, 0x00005DE6, 0x00000A12, 0x000600A9, 0x00000014, + 0x00004242, 0x00003600, 0x00000A12, 0x0000577C, 0x0004007C, 0x00000018, 0x000029CF, 0x00004242, + 0x000500C2, 0x0000000B, 0x00004BA4, 0x000056BD, 0x00000A64, 0x00040070, 0x0000000D, 0x0000480E, + 0x00004BA4, 0x00050085, 0x0000000D, 0x00003E1F, 0x0000480E, 0x00000149, 0x00050051, 0x0000000D, + 0x000053C2, 0x000029CF, 0x00000000, 0x00050051, 0x0000000D, 0x00002A55, 0x000029CF, 0x00000001, + 0x00050051, 0x0000000D, 0x00001E99, 0x000029CF, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDA, + 0x000053C2, 0x00002A55, 0x00001E99, 0x00003E1F, 0x00050051, 0x0000000B, 0x000027F5, 0x00002ABF, + 0x00000001, 0x00060050, 0x00000014, 0x0000350E, 0x000027F5, 0x000027F5, 0x000027F5, 0x000500C2, + 0x00000014, 0x00002B0E, 0x0000350E, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DE7, 0x00002B0E, + 0x00000105, 0x000500C7, 0x00000014, 0x0000489D, 0x00005DE7, 0x00000466, 0x000500C2, 0x00000014, + 0x00005B91, 0x00005DE7, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CA, 0x00005B91, 0x00000A12, + 0x0006000C, 0x00000016, 0x00002C4C, 0x00000001, 0x0000004B, 0x0000489D, 0x0004007C, 0x00000014, + 0x00002A16, 0x00002C4C, 0x00050082, 0x00000014, 0x0000187B, 0x00000B0C, 0x00002A16, 0x00050080, + 0x00000014, 0x00002211, 0x00002A16, 0x00000938, 0x000600A9, 0x00000014, 0x00002870, 0x000040CA, + 0x00002211, 0x00005B91, 0x000500C4, 0x00000014, 0x00005AD5, 0x0000489D, 0x0000187B, 0x000500C7, + 0x00000014, 0x0000499B, 0x00005AD5, 0x00000466, 0x000600A9, 0x00000014, 0x00002A9E, 0x000040CA, + 0x0000499B, 0x0000489D, 0x00050080, 0x00000014, 0x00005FFA, 0x00002870, 0x000003FA, 0x000500C4, + 0x00000014, 0x00004F80, 0x00005FFA, 0x00000189, 0x000500C4, 0x00000014, 0x00003FA7, 0x00002A9E, + 0x0000008D, 0x000500C5, 0x00000014, 0x0000577D, 0x00004F80, 0x00003FA7, 0x000500AA, 0x00000010, + 0x00003601, 0x00005DE7, 0x00000A12, 0x000600A9, 0x00000014, 0x00004243, 0x00003601, 0x00000A12, + 0x0000577D, 0x0004007C, 0x00000018, 0x000029D0, 0x00004243, 0x000500C2, 0x0000000B, 0x00004BA5, + 0x000027F5, 0x00000A64, 0x00040070, 0x0000000D, 0x0000480F, 0x00004BA5, 0x00050085, 0x0000000D, + 0x00003E20, 0x0000480F, 0x00000149, 0x00050051, 0x0000000D, 0x000053C3, 0x000029D0, 0x00000000, + 0x00050051, 0x0000000D, 0x00002A56, 0x000029D0, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9A, + 0x000029D0, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDB, 0x000053C3, 0x00002A56, 0x00001E9A, + 0x00003E20, 0x00050051, 0x0000000B, 0x000027F6, 0x00002ABF, 0x00000002, 0x00060050, 0x00000014, + 0x0000350F, 0x000027F6, 0x000027F6, 0x000027F6, 0x000500C2, 0x00000014, 0x00002B0F, 0x0000350F, + 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DE8, 0x00002B0F, 0x00000105, 0x000500C7, 0x00000014, + 0x0000489E, 0x00005DE8, 0x00000466, 0x000500C2, 0x00000014, 0x00005B92, 0x00005DE8, 0x00000B0C, + 0x000500AA, 0x00000010, 0x000040CB, 0x00005B92, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4D, + 0x00000001, 0x0000004B, 0x0000489E, 0x0004007C, 0x00000014, 0x00002A17, 0x00002C4D, 0x00050082, + 0x00000014, 0x0000187C, 0x00000B0C, 0x00002A17, 0x00050080, 0x00000014, 0x00002212, 0x00002A17, + 0x00000938, 0x000600A9, 0x00000014, 0x00002871, 0x000040CB, 0x00002212, 0x00005B92, 0x000500C4, + 0x00000014, 0x00005AD6, 0x0000489E, 0x0000187C, 0x000500C7, 0x00000014, 0x0000499C, 0x00005AD6, + 0x00000466, 0x000600A9, 0x00000014, 0x00002A9F, 0x000040CB, 0x0000499C, 0x0000489E, 0x00050080, + 0x00000014, 0x00005FFB, 0x00002871, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F81, 0x00005FFB, + 0x00000189, 0x000500C4, 0x00000014, 0x00003FA8, 0x00002A9F, 0x0000008D, 0x000500C5, 0x00000014, + 0x0000577E, 0x00004F81, 0x00003FA8, 0x000500AA, 0x00000010, 0x00003602, 0x00005DE8, 0x00000A12, + 0x000600A9, 0x00000014, 0x00004244, 0x00003602, 0x00000A12, 0x0000577E, 0x0004007C, 0x00000018, + 0x000029D1, 0x00004244, 0x000500C2, 0x0000000B, 0x00004BA6, 0x000027F6, 0x00000A64, 0x00040070, + 0x0000000D, 0x00004810, 0x00004BA6, 0x00050085, 0x0000000D, 0x00003E21, 0x00004810, 0x00000149, + 0x00050051, 0x0000000D, 0x000053C4, 0x000029D1, 0x00000000, 0x00050051, 0x0000000D, 0x00002A57, + 0x000029D1, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9B, 0x000029D1, 0x00000002, 0x00070050, + 0x0000001D, 0x00003DDC, 0x000053C4, 0x00002A57, 0x00001E9B, 0x00003E21, 0x00050051, 0x0000000B, + 0x000027F7, 0x00002ABF, 0x00000003, 0x00060050, 0x00000014, 0x00003510, 0x000027F7, 0x000027F7, + 0x000027F7, 0x000500C2, 0x00000014, 0x00002B10, 0x00003510, 0x00000BB4, 0x000500C7, 0x00000014, + 0x00005DE9, 0x00002B10, 0x00000105, 0x000500C7, 0x00000014, 0x0000489F, 0x00005DE9, 0x00000466, + 0x000500C2, 0x00000014, 0x00005B93, 0x00005DE9, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CC, + 0x00005B93, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4E, 0x00000001, 0x0000004B, 0x0000489F, + 0x0004007C, 0x00000014, 0x00002A18, 0x00002C4E, 0x00050082, 0x00000014, 0x0000187D, 0x00000B0C, + 0x00002A18, 0x00050080, 0x00000014, 0x00002213, 0x00002A18, 0x00000938, 0x000600A9, 0x00000014, + 0x00002872, 0x000040CC, 0x00002213, 0x00005B93, 0x000500C4, 0x00000014, 0x00005AD7, 0x0000489F, + 0x0000187D, 0x000500C7, 0x00000014, 0x0000499D, 0x00005AD7, 0x00000466, 0x000600A9, 0x00000014, + 0x00002AA0, 0x000040CC, 0x0000499D, 0x0000489F, 0x00050080, 0x00000014, 0x00005FFC, 0x00002872, + 0x000003FA, 0x000500C4, 0x00000014, 0x00004F82, 0x00005FFC, 0x00000189, 0x000500C4, 0x00000014, + 0x00003FA9, 0x00002AA0, 0x0000008D, 0x000500C5, 0x00000014, 0x0000577F, 0x00004F82, 0x00003FA9, + 0x000500AA, 0x00000010, 0x00003603, 0x00005DE9, 0x00000A12, 0x000600A9, 0x00000014, 0x00004245, + 0x00003603, 0x00000A12, 0x0000577F, 0x0004007C, 0x00000018, 0x000029D2, 0x00004245, 0x000500C2, + 0x0000000B, 0x00004BA7, 0x000027F7, 0x00000A64, 0x00040070, 0x0000000D, 0x00004811, 0x00004BA7, + 0x00050085, 0x0000000D, 0x00003E22, 0x00004811, 0x00000149, 0x00050051, 0x0000000D, 0x000053C5, + 0x000029D2, 0x00000000, 0x00050051, 0x0000000D, 0x00002A58, 0x000029D2, 0x00000001, 0x00050051, + 0x0000000D, 0x00002B11, 0x000029D2, 0x00000002, 0x00070050, 0x0000001D, 0x0000234B, 0x000053C5, + 0x00002A58, 0x00002B11, 0x00003E22, 0x000200F9, 0x00003F60, 0x000200F8, 0x00001CBB, 0x00050051, + 0x0000000B, 0x000056BE, 0x00002ABF, 0x00000000, 0x00070050, 0x00000017, 0x00004F0B, 0x000056BE, + 0x000056BE, 0x000056BE, 0x000056BE, 0x000500C2, 0x00000017, 0x00002498, 0x00004F0B, 0x0000034D, + 0x000500C7, 0x00000017, 0x000049AB, 0x00002498, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CB7, + 0x000049AB, 0x00050085, 0x0000001D, 0x00004130, 0x00003CB7, 0x00000AEE, 0x00050051, 0x0000000B, + 0x00005CD2, 0x00002ABF, 0x00000001, 0x00070050, 0x00000017, 0x0000514D, 0x00005CD2, 0x00005CD2, + 0x00005CD2, 0x00005CD2, 0x000500C2, 0x00000017, 0x00002499, 0x0000514D, 0x0000034D, 0x000500C7, + 0x00000017, 0x000049AC, 0x00002499, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CB8, 0x000049AC, + 0x00050085, 0x0000001D, 0x00004131, 0x00003CB8, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD3, + 0x00002ABF, 0x00000002, 0x00070050, 0x00000017, 0x0000514E, 0x00005CD3, 0x00005CD3, 0x00005CD3, + 0x00005CD3, 0x000500C2, 0x00000017, 0x0000249A, 0x0000514E, 0x0000034D, 0x000500C7, 0x00000017, + 0x000049AD, 0x0000249A, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CB9, 0x000049AD, 0x00050085, + 0x0000001D, 0x00004132, 0x00003CB9, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD4, 0x00002ABF, + 0x00000003, 0x00070050, 0x00000017, 0x0000514F, 0x00005CD4, 0x00005CD4, 0x00005CD4, 0x00005CD4, + 0x000500C2, 0x00000017, 0x0000249B, 0x0000514F, 0x0000034D, 0x000500C7, 0x00000017, 0x000049AE, + 0x0000249B, 0x0000027B, 0x00040070, 0x0000001D, 0x0000492F, 0x000049AE, 0x00050085, 0x0000001D, + 0x0000269F, 0x0000492F, 0x00000AEE, 0x000200F9, 0x00003F60, 0x000200F8, 0x000038F9, 0x00050051, + 0x0000000B, 0x000056BF, 0x00002ABF, 0x00000000, 0x00070050, 0x00000017, 0x00004F0C, 0x000056BF, + 0x000056BF, 0x000056BF, 0x000056BF, 0x000500C2, 0x00000017, 0x0000249C, 0x00004F0C, 0x0000028D, + 0x000500C7, 0x00000017, 0x00004A56, 0x0000249C, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A2, + 0x00004A56, 0x0005008E, 0x0000001D, 0x00004B23, 0x000036A2, 0x0000017A, 0x00050051, 0x0000000B, + 0x0000219F, 0x00002ABF, 0x00000001, 0x00070050, 0x00000017, 0x0000610B, 0x0000219F, 0x0000219F, + 0x0000219F, 0x0000219F, 0x000500C2, 0x00000017, 0x0000249D, 0x0000610B, 0x0000028D, 0x000500C7, + 0x00000017, 0x00004A57, 0x0000249D, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A3, 0x00004A57, + 0x0005008E, 0x0000001D, 0x00004B24, 0x000036A3, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A0, + 0x00002ABF, 0x00000002, 0x00070050, 0x00000017, 0x0000610C, 0x000021A0, 0x000021A0, 0x000021A0, + 0x000021A0, 0x000500C2, 0x00000017, 0x0000249E, 0x0000610C, 0x0000028D, 0x000500C7, 0x00000017, + 0x00004A58, 0x0000249E, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A4, 0x00004A58, 0x0005008E, + 0x0000001D, 0x00004B25, 0x000036A4, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A1, 0x00002ABF, + 0x00000003, 0x00070050, 0x00000017, 0x0000610D, 0x000021A1, 0x000021A1, 0x000021A1, 0x000021A1, + 0x000500C2, 0x00000017, 0x0000249F, 0x0000610D, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A59, + 0x0000249F, 0x0000064B, 0x00040070, 0x0000001D, 0x0000431A, 0x00004A59, 0x0005008E, 0x0000001D, + 0x00003092, 0x0000431A, 0x0000017A, 0x000200F9, 0x00003F60, 0x000200F8, 0x00004BFB, 0x00050051, + 0x0000000B, 0x0000308C, 0x00002ABF, 0x00000000, 0x0004007C, 0x0000000D, 0x00004FEE, 0x0000308C, + 0x00050050, 0x00000013, 0x00004336, 0x00004FEE, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D90, + 0x00004336, 0x00004336, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, + 0x000056B1, 0x00002ABF, 0x00000001, 0x0004007C, 0x0000000D, 0x00003F68, 0x000056B1, 0x00050050, + 0x00000013, 0x00004337, 0x00003F68, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D91, 0x00004337, + 0x00004337, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B2, + 0x00002ABF, 0x00000002, 0x0004007C, 0x0000000D, 0x00003F69, 0x000056B2, 0x00050050, 0x00000013, + 0x00004338, 0x00003F69, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D92, 0x00004338, 0x00004338, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B3, 0x00002ABF, + 0x00000003, 0x0004007C, 0x0000000D, 0x00003F6A, 0x000056B3, 0x00050050, 0x00000013, 0x00004FAE, + 0x00003F6A, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3A, 0x00004FAE, 0x00004FAE, 0x00000000, + 0x00000001, 0x00000001, 0x00000001, 0x000200F9, 0x00003F60, 0x000200F8, 0x00003F60, 0x000F00F5, + 0x0000001D, 0x00002BA7, 0x00005A3A, 0x00004BFB, 0x00003092, 0x000038F9, 0x0000269F, 0x00001CBB, + 0x0000234B, 0x00001CBA, 0x0000234A, 0x00001FFE, 0x00002349, 0x00002033, 0x000F00F5, 0x0000001D, + 0x00003808, 0x00002D92, 0x00004BFB, 0x00004B25, 0x000038F9, 0x00004132, 0x00001CBB, 0x00003DDC, + 0x00001CBA, 0x00004120, 0x00001FFE, 0x0000390E, 0x00002033, 0x000F00F5, 0x0000001D, 0x00003B7D, + 0x00002D91, 0x00004BFB, 0x00004B24, 0x000038F9, 0x00004131, 0x00001CBB, 0x00003DDB, 0x00001CBA, + 0x0000411F, 0x00001FFE, 0x0000390D, 0x00002033, 0x000F00F5, 0x0000001D, 0x000038B6, 0x00002D90, + 0x00004BFB, 0x00004B23, 0x000038F9, 0x00004130, 0x00001CBB, 0x00003DDA, 0x00001CBA, 0x0000411E, + 0x00001FFE, 0x0000390C, 0x00002033, 0x000200F9, 0x0000530F, 0x000200F8, 0x00003B65, 0x000500AA, + 0x00000009, 0x00005450, 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F23, 0x00000002, 0x000400FA, + 0x00005450, 0x00002622, 0x00002F62, 0x000200F8, 0x00002F62, 0x00060041, 0x00000288, 0x00004BD0, + 0x00000CC7, 0x00000A0B, 0x0000628F, 0x0004003D, 0x0000000B, 0x00005D45, 0x00004BD0, 0x00050080, + 0x0000000B, 0x00002DAB, 0x0000628F, 0x00000A0D, 0x00060041, 0x00000288, 0x00001901, 0x00000CC7, + 0x00000A0B, 0x00002DAB, 0x0004003D, 0x0000000B, 0x00005C64, 0x00001901, 0x00050080, 0x0000000B, + 0x00002DAC, 0x0000628F, 0x0000199B, 0x00060041, 0x00000288, 0x00001902, 0x00000CC7, 0x00000A0B, + 0x00002DAC, 0x0004003D, 0x0000000B, 0x00005C65, 0x00001902, 0x00050080, 0x0000000B, 0x00002DAD, + 0x00002DAC, 0x00000A0D, 0x00060041, 0x00000288, 0x00005FEF, 0x00000CC7, 0x00000A0B, 0x00002DAD, + 0x0004003D, 0x0000000B, 0x0000374C, 0x00005FEF, 0x00070050, 0x00000017, 0x00004CD6, 0x00005D45, + 0x00005C64, 0x00005C65, 0x0000374C, 0x00050084, 0x0000000B, 0x00004298, 0x00000A10, 0x0000199B, + 0x00050080, 0x0000000B, 0x000036A7, 0x0000628F, 0x00004298, 0x00060041, 0x00000288, 0x00003B81, + 0x00000CC7, 0x00000A0B, 0x000036A7, 0x0004003D, 0x0000000B, 0x00005C66, 0x00003B81, 0x00050080, + 0x0000000B, 0x00002DAE, 0x000036A7, 0x00000A0D, 0x00060041, 0x00000288, 0x0000194C, 0x00000CC7, + 0x00000A0B, 0x00002DAE, 0x0004003D, 0x0000000B, 0x00005E5D, 0x0000194C, 0x00050084, 0x0000000B, + 0x0000185C, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A3, 0x0000628F, 0x0000185C, + 0x00060041, 0x00000288, 0x00003B82, 0x00000CC7, 0x00000A0B, 0x000020A3, 0x0004003D, 0x0000000B, + 0x00005C67, 0x00003B82, 0x00050080, 0x0000000B, 0x00002DAF, 0x000020A3, 0x00000A0D, 0x00060041, + 0x00000288, 0x00005FF0, 0x00000CC7, 0x00000A0B, 0x00002DAF, 0x0004003D, 0x0000000B, 0x00003FFE, + 0x00005FF0, 0x00070050, 0x00000017, 0x0000512E, 0x00005C66, 0x00005E5D, 0x00005C67, 0x00003FFE, + 0x000200F9, 0x00004F23, 0x000200F8, 0x00002622, 0x00060041, 0x00000288, 0x00005546, 0x00000CC7, + 0x00000A0B, 0x0000628F, 0x0004003D, 0x0000000B, 0x00005D46, 0x00005546, 0x00050080, 0x0000000B, + 0x00002DB0, 0x0000628F, 0x00000A0D, 0x00060041, 0x00000288, 0x00001903, 0x00000CC7, 0x00000A0B, + 0x00002DB0, 0x0004003D, 0x0000000B, 0x00005C68, 0x00001903, 0x00050080, 0x0000000B, 0x00002DB1, + 0x0000628F, 0x00000A10, 0x00060041, 0x00000288, 0x00001904, 0x00000CC7, 0x00000A0B, 0x00002DB1, + 0x0004003D, 0x0000000B, 0x00005C69, 0x00001904, 0x00050080, 0x0000000B, 0x00002DB2, 0x0000628F, + 0x00000A13, 0x00060041, 0x00000288, 0x00005FF1, 0x00000CC7, 0x00000A0B, 0x00002DB2, 0x0004003D, + 0x0000000B, 0x00003700, 0x00005FF1, 0x00070050, 0x00000017, 0x00004ADD, 0x00005D46, 0x00005C68, + 0x00005C69, 0x00003700, 0x00050080, 0x0000000B, 0x000057E5, 0x0000628F, 0x00000A16, 0x00060041, + 0x00000288, 0x0000604B, 0x00000CC7, 0x00000A0B, 0x000057E5, 0x0004003D, 0x0000000B, 0x00005C6A, + 0x0000604B, 0x00050080, 0x0000000B, 0x00002DB3, 0x0000628F, 0x00000A19, 0x00060041, 0x00000288, + 0x00001905, 0x00000CC7, 0x00000A0B, 0x00002DB3, 0x0004003D, 0x0000000B, 0x00005C6B, 0x00001905, + 0x00050080, 0x0000000B, 0x00002DB4, 0x0000628F, 0x00000A1C, 0x00060041, 0x00000288, 0x00001906, + 0x00000CC7, 0x00000A0B, 0x00002DB4, 0x0004003D, 0x0000000B, 0x00005C6C, 0x00001906, 0x00050080, + 0x0000000B, 0x00002DB5, 0x0000628F, 0x00000A1F, 0x00060041, 0x00000288, 0x00005FF2, 0x00000CC7, + 0x00000A0B, 0x00002DB5, 0x0004003D, 0x0000000B, 0x00003FFF, 0x00005FF2, 0x00070050, 0x00000017, + 0x0000512F, 0x00005C6A, 0x00005C6B, 0x00005C6C, 0x00003FFF, 0x000200F9, 0x00004F23, 0x000200F8, + 0x00004F23, 0x000700F5, 0x00000017, 0x00002BCD, 0x0000512F, 0x00002622, 0x0000512E, 0x00002F62, + 0x000700F5, 0x00000017, 0x00003720, 0x00004ADD, 0x00002622, 0x00004CD6, 0x00002F62, 0x000300F7, + 0x00004F24, 0x00000000, 0x000700FB, 0x00002180, 0x00004F56, 0x00000005, 0x00002158, 0x00000007, + 0x00002034, 0x000200F8, 0x00002034, 0x00050051, 0x0000000B, 0x00005F57, 0x00003720, 0x00000000, + 0x0006000C, 0x00000013, 0x00006068, 0x00000001, 0x0000003E, 0x00005F57, 0x00050051, 0x0000000D, + 0x00002775, 0x00006068, 0x00000000, 0x00050051, 0x0000000D, 0x00003EB8, 0x00006068, 0x00000001, + 0x00050051, 0x0000000B, 0x00004281, 0x00003720, 0x00000001, 0x0006000C, 0x00000013, 0x00003CF5, + 0x00000001, 0x0000003E, 0x00004281, 0x00050051, 0x0000000D, 0x00002766, 0x00003CF5, 0x00000000, + 0x00050051, 0x0000000D, 0x00004449, 0x00003CF5, 0x00000001, 0x00070050, 0x0000001D, 0x0000390F, + 0x00002775, 0x00003EB8, 0x00002766, 0x00004449, 0x00050051, 0x0000000B, 0x0000437D, 0x00003720, + 0x00000002, 0x0006000C, 0x00000013, 0x0000466E, 0x00000001, 0x0000003E, 0x0000437D, 0x00050051, + 0x0000000D, 0x00002776, 0x0000466E, 0x00000000, 0x00050051, 0x0000000D, 0x00003EB9, 0x0000466E, + 0x00000001, 0x00050051, 0x0000000B, 0x00004282, 0x00003720, 0x00000003, 0x0006000C, 0x00000013, + 0x00003CF6, 0x00000001, 0x0000003E, 0x00004282, 0x00050051, 0x0000000D, 0x00002767, 0x00003CF6, + 0x00000000, 0x00050051, 0x0000000D, 0x0000444A, 0x00003CF6, 0x00000001, 0x00070050, 0x0000001D, + 0x00003910, 0x00002776, 0x00003EB9, 0x00002767, 0x0000444A, 0x00050051, 0x0000000B, 0x0000437E, + 0x00002BCD, 0x00000000, 0x0006000C, 0x00000013, 0x0000466F, 0x00000001, 0x0000003E, 0x0000437E, + 0x00050051, 0x0000000D, 0x00002777, 0x0000466F, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBA, + 0x0000466F, 0x00000001, 0x00050051, 0x0000000B, 0x00004283, 0x00002BCD, 0x00000001, 0x0006000C, + 0x00000013, 0x00003CF7, 0x00000001, 0x0000003E, 0x00004283, 0x00050051, 0x0000000D, 0x00002768, + 0x00003CF7, 0x00000000, 0x00050051, 0x0000000D, 0x0000444B, 0x00003CF7, 0x00000001, 0x00070050, + 0x0000001D, 0x00003911, 0x00002777, 0x00003EBA, 0x00002768, 0x0000444B, 0x00050051, 0x0000000B, + 0x0000437F, 0x00002BCD, 0x00000002, 0x0006000C, 0x00000013, 0x00004670, 0x00000001, 0x0000003E, + 0x0000437F, 0x00050051, 0x0000000D, 0x00002778, 0x00004670, 0x00000000, 0x00050051, 0x0000000D, + 0x00003EBB, 0x00004670, 0x00000001, 0x00050051, 0x0000000B, 0x00004284, 0x00002BCD, 0x00000003, + 0x0006000C, 0x00000013, 0x00003CF8, 0x00000001, 0x0000003E, 0x00004284, 0x00050051, 0x0000000D, + 0x00002769, 0x00003CF8, 0x00000000, 0x00050051, 0x0000000D, 0x000050BF, 0x00003CF8, 0x00000001, + 0x00070050, 0x0000001D, 0x0000234C, 0x00002778, 0x00003EBB, 0x00002769, 0x000050BF, 0x000200F9, + 0x00004F24, 0x000200F8, 0x00002158, 0x0007004F, 0x00000011, 0x000025FB, 0x00003720, 0x00003720, + 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x00005B3C, 0x000025FB, 0x0009004F, 0x0000001A, + 0x000060CE, 0x00005B3C, 0x00005B3C, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, + 0x0000001A, 0x000048A6, 0x000060CE, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D8D, 0x000048A6, + 0x00000302, 0x0004006F, 0x0000001D, 0x00002A9B, 0x00003D8D, 0x0005008E, 0x0000001D, 0x00004721, + 0x00002A9B, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006291, 0x00000001, 0x00000028, 0x00000504, + 0x00004721, 0x0007004F, 0x00000011, 0x0000376B, 0x00003720, 0x00003720, 0x00000002, 0x00000003, + 0x0004007C, 0x00000012, 0x000024BF, 0x0000376B, 0x0009004F, 0x0000001A, 0x000060CF, 0x000024BF, + 0x000024BF, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048A7, + 0x000060CF, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D8E, 0x000048A7, 0x00000302, 0x0004006F, + 0x0000001D, 0x00002A9C, 0x00003D8E, 0x0005008E, 0x0000001D, 0x00004722, 0x00002A9C, 0x000007FE, + 0x0007000C, 0x0000001D, 0x00006292, 0x00000001, 0x00000028, 0x00000504, 0x00004722, 0x0007004F, + 0x00000011, 0x0000376C, 0x00002BCD, 0x00002BCD, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, + 0x000024C0, 0x0000376C, 0x0009004F, 0x0000001A, 0x000060D0, 0x000024C0, 0x000024C0, 0x00000000, + 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048A8, 0x000060D0, 0x00000122, + 0x000500C3, 0x0000001A, 0x00003D8F, 0x000048A8, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA1, + 0x00003D8F, 0x0005008E, 0x0000001D, 0x00004723, 0x00002AA1, 0x000007FE, 0x0007000C, 0x0000001D, + 0x00006293, 0x00000001, 0x00000028, 0x00000504, 0x00004723, 0x0007004F, 0x00000011, 0x0000376D, + 0x00002BCD, 0x00002BCD, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C1, 0x0000376D, + 0x0009004F, 0x0000001A, 0x000060D1, 0x000024C1, 0x000024C1, 0x00000000, 0x00000000, 0x00000001, + 0x00000001, 0x000500C4, 0x0000001A, 0x000048A9, 0x000060D1, 0x00000122, 0x000500C3, 0x0000001A, + 0x00003D90, 0x000048A9, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA2, 0x00003D90, 0x0005008E, + 0x0000001D, 0x000053BF, 0x00002AA2, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004362, 0x00000001, + 0x00000028, 0x00000504, 0x000053BF, 0x000200F9, 0x00004F24, 0x000200F8, 0x00004F56, 0x0007004F, + 0x00000011, 0x00002623, 0x00003720, 0x00003720, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, + 0x00005159, 0x00002623, 0x00050051, 0x0000000D, 0x00001B7B, 0x00005159, 0x00000000, 0x00050051, + 0x0000000D, 0x0000346A, 0x00005159, 0x00000001, 0x00070050, 0x0000001D, 0x00004278, 0x00001B7B, + 0x0000346A, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041D8, 0x00003720, 0x00003720, + 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x0000375D, 0x000041D8, 0x00050051, 0x0000000D, + 0x00001B7C, 0x0000375D, 0x00000000, 0x00050051, 0x0000000D, 0x0000346B, 0x0000375D, 0x00000001, + 0x00070050, 0x0000001D, 0x00004279, 0x00001B7C, 0x0000346B, 0x00000A0C, 0x00000A0C, 0x0007004F, + 0x00000011, 0x000041D9, 0x00002BCD, 0x00002BCD, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, + 0x0000375E, 0x000041D9, 0x00050051, 0x0000000D, 0x00001B7D, 0x0000375E, 0x00000000, 0x00050051, + 0x0000000D, 0x0000346C, 0x0000375E, 0x00000001, 0x00070050, 0x0000001D, 0x0000427A, 0x00001B7D, + 0x0000346C, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DA, 0x00002BCD, 0x00002BCD, + 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x0000375F, 0x000041DA, 0x00050051, 0x0000000D, + 0x00001B7F, 0x0000375F, 0x00000000, 0x00050051, 0x0000000D, 0x00004108, 0x0000375F, 0x00000001, + 0x00070050, 0x0000001D, 0x0000234D, 0x00001B7F, 0x00004108, 0x00000A0C, 0x00000A0C, 0x000200F9, + 0x00004F24, 0x000200F8, 0x00004F24, 0x000900F5, 0x0000001D, 0x00002BA8, 0x0000234D, 0x00004F56, + 0x00004362, 0x00002158, 0x0000234C, 0x00002034, 0x000900F5, 0x0000001D, 0x00003809, 0x0000427A, + 0x00004F56, 0x00006293, 0x00002158, 0x00003911, 0x00002034, 0x000900F5, 0x0000001D, 0x00003B7E, + 0x00004279, 0x00004F56, 0x00006292, 0x00002158, 0x00003910, 0x00002034, 0x000900F5, 0x0000001D, + 0x000038B7, 0x00004278, 0x00004F56, 0x00006291, 0x00002158, 0x0000390F, 0x00002034, 0x000200F9, + 0x0000530F, 0x000200F8, 0x0000530F, 0x000700F5, 0x0000001D, 0x00002BA9, 0x00002BA8, 0x00004F24, + 0x00002BA7, 0x00003F60, 0x000700F5, 0x0000001D, 0x0000380A, 0x00003809, 0x00004F24, 0x00003808, + 0x00003F60, 0x000700F5, 0x0000001D, 0x000035EC, 0x00003B7E, 0x00004F24, 0x00003B7D, 0x00003F60, + 0x000700F5, 0x0000001D, 0x000020D3, 0x000038B7, 0x00004F24, 0x000038B6, 0x00003F60, 0x000500AE, + 0x00000009, 0x00002E55, 0x00004356, 0x00000A16, 0x000300F7, 0x00005313, 0x00000002, 0x000400FA, + 0x00002E55, 0x000051F1, 0x00005313, 0x000200F8, 0x000051F1, 0x00050084, 0x0000000B, 0x00002B47, + 0x00000AFA, 0x0000229A, 0x00050085, 0x0000000D, 0x00005A1D, 0x00002B2C, 0x000000FC, 0x00050080, + 0x0000000B, 0x00001FB2, 0x0000628F, 0x00002B47, 0x000300F7, 0x00005310, 0x00000002, 0x000400FA, + 0x00005AEF, 0x00003B66, 0x000040BA, 0x000200F8, 0x000040BA, 0x000500AA, 0x00000009, 0x00004ADB, + 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F4A, 0x00000002, 0x000400FA, 0x00004ADB, 0x00002624, + 0x00002F63, 0x000200F8, 0x00002F63, 0x00060041, 0x00000288, 0x00004BD1, 0x00000CC7, 0x00000A0B, + 0x00001FB2, 0x0004003D, 0x0000000B, 0x00005D47, 0x00004BD1, 0x00050080, 0x0000000B, 0x00002DB6, + 0x00001FB2, 0x0000199B, 0x00060041, 0x00000288, 0x0000194D, 0x00000CC7, 0x00000A0B, 0x00002DB6, + 0x0004003D, 0x0000000B, 0x00005E5E, 0x0000194D, 0x00050084, 0x0000000B, 0x0000185D, 0x00000A10, + 0x0000199B, 0x00050080, 0x0000000B, 0x000020A4, 0x00001FB2, 0x0000185D, 0x00060041, 0x00000288, + 0x00003BCE, 0x00000CC7, 0x00000A0B, 0x000020A4, 0x0004003D, 0x0000000B, 0x00005E5F, 0x00003BCE, + 0x00050084, 0x0000000B, 0x0000185E, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A5, + 0x00001FB2, 0x0000185E, 0x00060041, 0x00000288, 0x000037F2, 0x00000CC7, 0x00000A0B, 0x000020A5, + 0x0004003D, 0x0000000B, 0x00004000, 0x000037F2, 0x00070050, 0x00000017, 0x00005130, 0x00005D47, + 0x00005E5E, 0x00005E5F, 0x00004000, 0x000200F9, 0x00004F4A, 0x000200F8, 0x00002624, 0x00060041, + 0x00000288, 0x00005547, 0x00000CC7, 0x00000A0B, 0x00001FB2, 0x0004003D, 0x0000000B, 0x00005D48, + 0x00005547, 0x00050080, 0x0000000B, 0x00002DB7, 0x00001FB2, 0x00000A0D, 0x00060041, 0x00000288, + 0x00001907, 0x00000CC7, 0x00000A0B, 0x00002DB7, 0x0004003D, 0x0000000B, 0x00005C6D, 0x00001907, + 0x00050080, 0x0000000B, 0x00002DB8, 0x00001FB2, 0x00000A10, 0x00060041, 0x00000288, 0x00001908, + 0x00000CC7, 0x00000A0B, 0x00002DB8, 0x0004003D, 0x0000000B, 0x00005C6E, 0x00001908, 0x00050080, + 0x0000000B, 0x00002DB9, 0x00001FB2, 0x00000A13, 0x00060041, 0x00000288, 0x00005FF3, 0x00000CC7, + 0x00000A0B, 0x00002DB9, 0x0004003D, 0x0000000B, 0x00004001, 0x00005FF3, 0x00070050, 0x00000017, + 0x00005131, 0x00005D48, 0x00005C6D, 0x00005C6E, 0x00004001, 0x000200F9, 0x00004F4A, 0x000200F8, + 0x00004F4A, 0x000700F5, 0x00000017, 0x00002AC0, 0x00005131, 0x00002624, 0x00005130, 0x00002F63, + 0x000300F7, 0x00003F61, 0x00000000, 0x001300FB, 0x00002180, 0x00004BFC, 0x00000000, 0x000038FA, + 0x00000001, 0x000038FA, 0x00000002, 0x00001CBD, 0x0000000A, 0x00001CBD, 0x00000003, 0x00001CBC, + 0x0000000C, 0x00001CBC, 0x00000004, 0x00001FFF, 0x00000006, 0x00002035, 0x000200F8, 0x00002035, + 0x00050051, 0x0000000B, 0x00005F58, 0x00002AC0, 0x00000000, 0x0006000C, 0x00000013, 0x00006069, + 0x00000001, 0x0000003E, 0x00005F58, 0x00050051, 0x0000000D, 0x0000276A, 0x00006069, 0x00000000, + 0x00050051, 0x0000000D, 0x0000444C, 0x00006069, 0x00000001, 0x00070050, 0x0000001D, 0x00003912, + 0x0000276A, 0x0000444C, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004380, 0x00002AC0, + 0x00000001, 0x0006000C, 0x00000013, 0x00004671, 0x00000001, 0x0000003E, 0x00004380, 0x00050051, + 0x0000000D, 0x0000276B, 0x00004671, 0x00000000, 0x00050051, 0x0000000D, 0x0000444D, 0x00004671, + 0x00000001, 0x00070050, 0x0000001D, 0x00003913, 0x0000276B, 0x0000444D, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x00004381, 0x00002AC0, 0x00000002, 0x0006000C, 0x00000013, 0x00004672, + 0x00000001, 0x0000003E, 0x00004381, 0x00050051, 0x0000000D, 0x0000276C, 0x00004672, 0x00000000, + 0x00050051, 0x0000000D, 0x0000444E, 0x00004672, 0x00000001, 0x00070050, 0x0000001D, 0x00003914, + 0x0000276C, 0x0000444E, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004382, 0x00002AC0, + 0x00000003, 0x0006000C, 0x00000013, 0x00004673, 0x00000001, 0x0000003E, 0x00004382, 0x00050051, + 0x0000000D, 0x0000276D, 0x00004673, 0x00000000, 0x00050051, 0x0000000D, 0x000050C0, 0x00004673, + 0x00000001, 0x00070050, 0x0000001D, 0x0000234E, 0x0000276D, 0x000050C0, 0x00000A0C, 0x00000A0C, + 0x000200F9, 0x00003F61, 0x000200F8, 0x00001FFF, 0x00050051, 0x0000000B, 0x0000308D, 0x00002AC0, + 0x00000000, 0x0004007C, 0x0000000C, 0x0000589E, 0x0000308D, 0x00050050, 0x00000012, 0x0000471E, + 0x0000589E, 0x0000589E, 0x000500C4, 0x00000012, 0x000047B1, 0x0000471E, 0x000007A7, 0x000500C3, + 0x00000012, 0x0000341B, 0x000047B1, 0x00000867, 0x0004006F, 0x00000013, 0x00002AA3, 0x0000341B, + 0x0005008E, 0x00000013, 0x0000474B, 0x00002AA3, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0A, + 0x00000001, 0x00000028, 0x00000049, 0x0000474B, 0x00050051, 0x0000000D, 0x00005F0E, 0x00005E0A, + 0x00000000, 0x00050051, 0x0000000D, 0x00003CD7, 0x00005E0A, 0x00000001, 0x00070050, 0x0000001D, + 0x00004121, 0x00005F0E, 0x00003CD7, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C45, + 0x00002AC0, 0x00000001, 0x0004007C, 0x0000000C, 0x00003EA4, 0x00004C45, 0x00050050, 0x00000012, + 0x0000471F, 0x00003EA4, 0x00003EA4, 0x000500C4, 0x00000012, 0x000047B2, 0x0000471F, 0x000007A7, + 0x000500C3, 0x00000012, 0x0000341C, 0x000047B2, 0x00000867, 0x0004006F, 0x00000013, 0x00002AA4, + 0x0000341C, 0x0005008E, 0x00000013, 0x0000474C, 0x00002AA4, 0x000007FE, 0x0007000C, 0x00000013, + 0x00005E0B, 0x00000001, 0x00000028, 0x00000049, 0x0000474C, 0x00050051, 0x0000000D, 0x00005F0F, + 0x00005E0B, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD8, 0x00005E0B, 0x00000001, 0x00070050, + 0x0000001D, 0x00004122, 0x00005F0F, 0x00003CD8, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x00004C46, 0x00002AC0, 0x00000002, 0x0004007C, 0x0000000C, 0x00003EA5, 0x00004C46, 0x00050050, + 0x00000012, 0x00004720, 0x00003EA5, 0x00003EA5, 0x000500C4, 0x00000012, 0x000047B3, 0x00004720, + 0x000007A7, 0x000500C3, 0x00000012, 0x0000341D, 0x000047B3, 0x00000867, 0x0004006F, 0x00000013, + 0x00002AA5, 0x0000341D, 0x0005008E, 0x00000013, 0x0000474D, 0x00002AA5, 0x000007FE, 0x0007000C, + 0x00000013, 0x00005E0C, 0x00000001, 0x00000028, 0x00000049, 0x0000474D, 0x00050051, 0x0000000D, + 0x00005F10, 0x00005E0C, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD9, 0x00005E0C, 0x00000001, + 0x00070050, 0x0000001D, 0x00004123, 0x00005F10, 0x00003CD9, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x00004C47, 0x00002AC0, 0x00000003, 0x0004007C, 0x0000000C, 0x00003EA6, 0x00004C47, + 0x00050050, 0x00000012, 0x00004724, 0x00003EA6, 0x00003EA6, 0x000500C4, 0x00000012, 0x000047B4, + 0x00004724, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341E, 0x000047B4, 0x00000867, 0x0004006F, + 0x00000013, 0x00002AA6, 0x0000341E, 0x0005008E, 0x00000013, 0x0000474E, 0x00002AA6, 0x000007FE, + 0x0007000C, 0x00000013, 0x00005E0D, 0x00000001, 0x00000028, 0x00000049, 0x0000474E, 0x00050051, + 0x0000000D, 0x00005F11, 0x00005E0D, 0x00000000, 0x00050051, 0x0000000D, 0x0000494D, 0x00005E0D, + 0x00000001, 0x00070050, 0x0000001D, 0x0000234F, 0x00005F11, 0x0000494D, 0x00000A0C, 0x00000A0C, + 0x000200F9, 0x00003F61, 0x000200F8, 0x00001CBC, 0x00050051, 0x0000000B, 0x000056C0, 0x00002AC0, + 0x00000000, 0x00060050, 0x00000014, 0x00004F0D, 0x000056C0, 0x000056C0, 0x000056C0, 0x000500C2, + 0x00000014, 0x00002B12, 0x00004F0D, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEA, 0x00002B12, + 0x00000105, 0x000500C7, 0x00000014, 0x000048A0, 0x00005DEA, 0x00000466, 0x000500C2, 0x00000014, + 0x00005B94, 0x00005DEA, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CD, 0x00005B94, 0x00000A12, + 0x0006000C, 0x00000016, 0x00002C4F, 0x00000001, 0x0000004B, 0x000048A0, 0x0004007C, 0x00000014, + 0x00002A19, 0x00002C4F, 0x00050082, 0x00000014, 0x0000187E, 0x00000B0C, 0x00002A19, 0x00050080, + 0x00000014, 0x00002214, 0x00002A19, 0x00000938, 0x000600A9, 0x00000014, 0x00002873, 0x000040CD, + 0x00002214, 0x00005B94, 0x000500C4, 0x00000014, 0x00005AD8, 0x000048A0, 0x0000187E, 0x000500C7, + 0x00000014, 0x0000499E, 0x00005AD8, 0x00000466, 0x000600A9, 0x00000014, 0x00002AA7, 0x000040CD, + 0x0000499E, 0x000048A0, 0x00050080, 0x00000014, 0x00005FFD, 0x00002873, 0x000003FA, 0x000500C4, + 0x00000014, 0x00004F83, 0x00005FFD, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAA, 0x00002AA7, + 0x0000008D, 0x000500C5, 0x00000014, 0x00005780, 0x00004F83, 0x00003FAA, 0x000500AA, 0x00000010, + 0x00003604, 0x00005DEA, 0x00000A12, 0x000600A9, 0x00000014, 0x00004246, 0x00003604, 0x00000A12, + 0x00005780, 0x0004007C, 0x00000018, 0x000029D3, 0x00004246, 0x000500C2, 0x0000000B, 0x00004BA8, + 0x000056C0, 0x00000A64, 0x00040070, 0x0000000D, 0x00004812, 0x00004BA8, 0x00050085, 0x0000000D, + 0x00003E23, 0x00004812, 0x00000149, 0x00050051, 0x0000000D, 0x000053C6, 0x000029D3, 0x00000000, + 0x00050051, 0x0000000D, 0x00002A59, 0x000029D3, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9C, + 0x000029D3, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDD, 0x000053C6, 0x00002A59, 0x00001E9C, + 0x00003E23, 0x00050051, 0x0000000B, 0x000027F8, 0x00002AC0, 0x00000001, 0x00060050, 0x00000014, + 0x00003511, 0x000027F8, 0x000027F8, 0x000027F8, 0x000500C2, 0x00000014, 0x00002B13, 0x00003511, + 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEB, 0x00002B13, 0x00000105, 0x000500C7, 0x00000014, + 0x000048A1, 0x00005DEB, 0x00000466, 0x000500C2, 0x00000014, 0x00005B95, 0x00005DEB, 0x00000B0C, + 0x000500AA, 0x00000010, 0x000040CE, 0x00005B95, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C50, + 0x00000001, 0x0000004B, 0x000048A1, 0x0004007C, 0x00000014, 0x00002A1A, 0x00002C50, 0x00050082, + 0x00000014, 0x0000187F, 0x00000B0C, 0x00002A1A, 0x00050080, 0x00000014, 0x00002215, 0x00002A1A, + 0x00000938, 0x000600A9, 0x00000014, 0x00002874, 0x000040CE, 0x00002215, 0x00005B95, 0x000500C4, + 0x00000014, 0x00005AD9, 0x000048A1, 0x0000187F, 0x000500C7, 0x00000014, 0x0000499F, 0x00005AD9, + 0x00000466, 0x000600A9, 0x00000014, 0x00002AA8, 0x000040CE, 0x0000499F, 0x000048A1, 0x00050080, + 0x00000014, 0x00005FFE, 0x00002874, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F84, 0x00005FFE, + 0x00000189, 0x000500C4, 0x00000014, 0x00003FAB, 0x00002AA8, 0x0000008D, 0x000500C5, 0x00000014, + 0x00005781, 0x00004F84, 0x00003FAB, 0x000500AA, 0x00000010, 0x00003605, 0x00005DEB, 0x00000A12, + 0x000600A9, 0x00000014, 0x00004247, 0x00003605, 0x00000A12, 0x00005781, 0x0004007C, 0x00000018, + 0x000029D4, 0x00004247, 0x000500C2, 0x0000000B, 0x00004BA9, 0x000027F8, 0x00000A64, 0x00040070, + 0x0000000D, 0x00004813, 0x00004BA9, 0x00050085, 0x0000000D, 0x00003E24, 0x00004813, 0x00000149, + 0x00050051, 0x0000000D, 0x000053C7, 0x000029D4, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5A, + 0x000029D4, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9D, 0x000029D4, 0x00000002, 0x00070050, + 0x0000001D, 0x00003DDE, 0x000053C7, 0x00002A5A, 0x00001E9D, 0x00003E24, 0x00050051, 0x0000000B, + 0x000027F9, 0x00002AC0, 0x00000002, 0x00060050, 0x00000014, 0x00003512, 0x000027F9, 0x000027F9, + 0x000027F9, 0x000500C2, 0x00000014, 0x00002B14, 0x00003512, 0x00000BB4, 0x000500C7, 0x00000014, + 0x00005DEC, 0x00002B14, 0x00000105, 0x000500C7, 0x00000014, 0x000048A2, 0x00005DEC, 0x00000466, + 0x000500C2, 0x00000014, 0x00005B96, 0x00005DEC, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CF, + 0x00005B96, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C51, 0x00000001, 0x0000004B, 0x000048A2, + 0x0004007C, 0x00000014, 0x00002A1B, 0x00002C51, 0x00050082, 0x00000014, 0x00001880, 0x00000B0C, + 0x00002A1B, 0x00050080, 0x00000014, 0x00002216, 0x00002A1B, 0x00000938, 0x000600A9, 0x00000014, + 0x00002875, 0x000040CF, 0x00002216, 0x00005B96, 0x000500C4, 0x00000014, 0x00005ADA, 0x000048A2, + 0x00001880, 0x000500C7, 0x00000014, 0x000049A0, 0x00005ADA, 0x00000466, 0x000600A9, 0x00000014, + 0x00002AA9, 0x000040CF, 0x000049A0, 0x000048A2, 0x00050080, 0x00000014, 0x00005FFF, 0x00002875, + 0x000003FA, 0x000500C4, 0x00000014, 0x00004F85, 0x00005FFF, 0x00000189, 0x000500C4, 0x00000014, + 0x00003FAC, 0x00002AA9, 0x0000008D, 0x000500C5, 0x00000014, 0x00005782, 0x00004F85, 0x00003FAC, + 0x000500AA, 0x00000010, 0x00003606, 0x00005DEC, 0x00000A12, 0x000600A9, 0x00000014, 0x00004248, + 0x00003606, 0x00000A12, 0x00005782, 0x0004007C, 0x00000018, 0x000029D5, 0x00004248, 0x000500C2, + 0x0000000B, 0x00004BAA, 0x000027F9, 0x00000A64, 0x00040070, 0x0000000D, 0x00004814, 0x00004BAA, + 0x00050085, 0x0000000D, 0x00003E25, 0x00004814, 0x00000149, 0x00050051, 0x0000000D, 0x000053C8, + 0x000029D5, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5B, 0x000029D5, 0x00000001, 0x00050051, + 0x0000000D, 0x00001E9E, 0x000029D5, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDF, 0x000053C8, + 0x00002A5B, 0x00001E9E, 0x00003E25, 0x00050051, 0x0000000B, 0x000027FA, 0x00002AC0, 0x00000003, + 0x00060050, 0x00000014, 0x00003513, 0x000027FA, 0x000027FA, 0x000027FA, 0x000500C2, 0x00000014, + 0x00002B15, 0x00003513, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DED, 0x00002B15, 0x00000105, + 0x000500C7, 0x00000014, 0x000048A3, 0x00005DED, 0x00000466, 0x000500C2, 0x00000014, 0x00005B97, + 0x00005DED, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D0, 0x00005B97, 0x00000A12, 0x0006000C, + 0x00000016, 0x00002C52, 0x00000001, 0x0000004B, 0x000048A3, 0x0004007C, 0x00000014, 0x00002A1C, + 0x00002C52, 0x00050082, 0x00000014, 0x00001881, 0x00000B0C, 0x00002A1C, 0x00050080, 0x00000014, + 0x00002217, 0x00002A1C, 0x00000938, 0x000600A9, 0x00000014, 0x00002876, 0x000040D0, 0x00002217, + 0x00005B97, 0x000500C4, 0x00000014, 0x00005ADB, 0x000048A3, 0x00001881, 0x000500C7, 0x00000014, + 0x000049A1, 0x00005ADB, 0x00000466, 0x000600A9, 0x00000014, 0x00002AAA, 0x000040D0, 0x000049A1, + 0x000048A3, 0x00050080, 0x00000014, 0x00006000, 0x00002876, 0x000003FA, 0x000500C4, 0x00000014, + 0x00004F86, 0x00006000, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAD, 0x00002AAA, 0x0000008D, + 0x000500C5, 0x00000014, 0x00005783, 0x00004F86, 0x00003FAD, 0x000500AA, 0x00000010, 0x00003607, + 0x00005DED, 0x00000A12, 0x000600A9, 0x00000014, 0x00004249, 0x00003607, 0x00000A12, 0x00005783, + 0x0004007C, 0x00000018, 0x000029D6, 0x00004249, 0x000500C2, 0x0000000B, 0x00004BAB, 0x000027FA, + 0x00000A64, 0x00040070, 0x0000000D, 0x00004815, 0x00004BAB, 0x00050085, 0x0000000D, 0x00003E26, + 0x00004815, 0x00000149, 0x00050051, 0x0000000D, 0x000053C9, 0x000029D6, 0x00000000, 0x00050051, + 0x0000000D, 0x00002A5C, 0x000029D6, 0x00000001, 0x00050051, 0x0000000D, 0x00002B16, 0x000029D6, + 0x00000002, 0x00070050, 0x0000001D, 0x00002350, 0x000053C9, 0x00002A5C, 0x00002B16, 0x00003E26, + 0x000200F9, 0x00003F61, 0x000200F8, 0x00001CBD, 0x00050051, 0x0000000B, 0x000056C1, 0x00002AC0, + 0x00000000, 0x00070050, 0x00000017, 0x00004F0E, 0x000056C1, 0x000056C1, 0x000056C1, 0x000056C1, + 0x000500C2, 0x00000017, 0x000024A0, 0x00004F0E, 0x0000034D, 0x000500C7, 0x00000017, 0x000049AF, + 0x000024A0, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBA, 0x000049AF, 0x00050085, 0x0000001D, + 0x00004133, 0x00003CBA, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD5, 0x00002AC0, 0x00000001, + 0x00070050, 0x00000017, 0x00005150, 0x00005CD5, 0x00005CD5, 0x00005CD5, 0x00005CD5, 0x000500C2, + 0x00000017, 0x000024A1, 0x00005150, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B0, 0x000024A1, + 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBB, 0x000049B0, 0x00050085, 0x0000001D, 0x00004134, + 0x00003CBB, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD6, 0x00002AC0, 0x00000002, 0x00070050, + 0x00000017, 0x00005151, 0x00005CD6, 0x00005CD6, 0x00005CD6, 0x00005CD6, 0x000500C2, 0x00000017, + 0x000024A2, 0x00005151, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B1, 0x000024A2, 0x0000027B, + 0x00040070, 0x0000001D, 0x00003CBC, 0x000049B1, 0x00050085, 0x0000001D, 0x00004135, 0x00003CBC, + 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD7, 0x00002AC0, 0x00000003, 0x00070050, 0x00000017, + 0x00005152, 0x00005CD7, 0x00005CD7, 0x00005CD7, 0x00005CD7, 0x000500C2, 0x00000017, 0x000024A3, + 0x00005152, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B2, 0x000024A3, 0x0000027B, 0x00040070, + 0x0000001D, 0x00004930, 0x000049B2, 0x00050085, 0x0000001D, 0x000026A0, 0x00004930, 0x00000AEE, + 0x000200F9, 0x00003F61, 0x000200F8, 0x000038FA, 0x00050051, 0x0000000B, 0x000056C2, 0x00002AC0, + 0x00000000, 0x00070050, 0x00000017, 0x00004F0F, 0x000056C2, 0x000056C2, 0x000056C2, 0x000056C2, + 0x000500C2, 0x00000017, 0x000024A4, 0x00004F0F, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5A, + 0x000024A4, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A5, 0x00004A5A, 0x0005008E, 0x0000001D, + 0x00004B26, 0x000036A5, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A2, 0x00002AC0, 0x00000001, + 0x00070050, 0x00000017, 0x0000610E, 0x000021A2, 0x000021A2, 0x000021A2, 0x000021A2, 0x000500C2, + 0x00000017, 0x000024A5, 0x0000610E, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5B, 0x000024A5, + 0x0000064B, 0x00040070, 0x0000001D, 0x000036A6, 0x00004A5B, 0x0005008E, 0x0000001D, 0x00004B27, + 0x000036A6, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A3, 0x00002AC0, 0x00000002, 0x00070050, + 0x00000017, 0x0000610F, 0x000021A3, 0x000021A3, 0x000021A3, 0x000021A3, 0x000500C2, 0x00000017, + 0x000024A6, 0x0000610F, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5C, 0x000024A6, 0x0000064B, + 0x00040070, 0x0000001D, 0x000036A8, 0x00004A5C, 0x0005008E, 0x0000001D, 0x00004B28, 0x000036A8, + 0x0000017A, 0x00050051, 0x0000000B, 0x000021A4, 0x00002AC0, 0x00000003, 0x00070050, 0x00000017, + 0x00006110, 0x000021A4, 0x000021A4, 0x000021A4, 0x000021A4, 0x000500C2, 0x00000017, 0x000024A7, + 0x00006110, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5D, 0x000024A7, 0x0000064B, 0x00040070, + 0x0000001D, 0x0000431B, 0x00004A5D, 0x0005008E, 0x0000001D, 0x00003093, 0x0000431B, 0x0000017A, + 0x000200F9, 0x00003F61, 0x000200F8, 0x00004BFC, 0x00050051, 0x0000000B, 0x0000308E, 0x00002AC0, + 0x00000000, 0x0004007C, 0x0000000D, 0x00004FEF, 0x0000308E, 0x00050050, 0x00000013, 0x00004339, + 0x00004FEF, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D93, 0x00004339, 0x00004339, 0x00000000, + 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B4, 0x00002AC0, 0x00000001, + 0x0004007C, 0x0000000D, 0x00003F6B, 0x000056B4, 0x00050050, 0x00000013, 0x0000433A, 0x00003F6B, + 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D94, 0x0000433A, 0x0000433A, 0x00000000, 0x00000001, + 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B5, 0x00002AC0, 0x00000002, 0x0004007C, + 0x0000000D, 0x00003F6C, 0x000056B5, 0x00050050, 0x00000013, 0x0000433B, 0x00003F6C, 0x00000A0C, + 0x0009004F, 0x0000001D, 0x00002D95, 0x0000433B, 0x0000433B, 0x00000000, 0x00000001, 0x00000001, + 0x00000001, 0x00050051, 0x0000000B, 0x000056B6, 0x00002AC0, 0x00000003, 0x0004007C, 0x0000000D, + 0x00003F6D, 0x000056B6, 0x00050050, 0x00000013, 0x00004FAF, 0x00003F6D, 0x00000A0C, 0x0009004F, + 0x0000001D, 0x00005A3B, 0x00004FAF, 0x00004FAF, 0x00000000, 0x00000001, 0x00000001, 0x00000001, + 0x000200F9, 0x00003F61, 0x000200F8, 0x00003F61, 0x000F00F5, 0x0000001D, 0x00002BAA, 0x00005A3B, + 0x00004BFC, 0x00003093, 0x000038FA, 0x000026A0, 0x00001CBD, 0x00002350, 0x00001CBC, 0x0000234F, + 0x00001FFF, 0x0000234E, 0x00002035, 0x000F00F5, 0x0000001D, 0x0000380B, 0x00002D95, 0x00004BFC, + 0x00004B28, 0x000038FA, 0x00004135, 0x00001CBD, 0x00003DDF, 0x00001CBC, 0x00004123, 0x00001FFF, + 0x00003914, 0x00002035, 0x000F00F5, 0x0000001D, 0x00003B7F, 0x00002D94, 0x00004BFC, 0x00004B27, + 0x000038FA, 0x00004134, 0x00001CBD, 0x00003DDE, 0x00001CBC, 0x00004122, 0x00001FFF, 0x00003913, + 0x00002035, 0x000F00F5, 0x0000001D, 0x000038B8, 0x00002D93, 0x00004BFC, 0x00004B26, 0x000038FA, + 0x00004133, 0x00001CBD, 0x00003DDD, 0x00001CBC, 0x00004121, 0x00001FFF, 0x00003912, 0x00002035, + 0x000200F9, 0x00005310, 0x000200F8, 0x00003B66, 0x000500AA, 0x00000009, 0x00005451, 0x0000199B, + 0x00000A10, 0x000300F7, 0x00004F25, 0x00000002, 0x000400FA, 0x00005451, 0x00002625, 0x00002F64, + 0x000200F8, 0x00002F64, 0x00060041, 0x00000288, 0x00004BD2, 0x00000CC7, 0x00000A0B, 0x00001FB2, + 0x0004003D, 0x0000000B, 0x00005D49, 0x00004BD2, 0x00050080, 0x0000000B, 0x00002DBA, 0x00001FB2, + 0x00000A0D, 0x00060041, 0x00000288, 0x00001909, 0x00000CC7, 0x00000A0B, 0x00002DBA, 0x0004003D, + 0x0000000B, 0x00005C6F, 0x00001909, 0x00050080, 0x0000000B, 0x00002DBB, 0x00001FB2, 0x0000199B, + 0x00060041, 0x00000288, 0x0000190A, 0x00000CC7, 0x00000A0B, 0x00002DBB, 0x0004003D, 0x0000000B, + 0x00005C70, 0x0000190A, 0x00050080, 0x0000000B, 0x00002DBC, 0x00002DBB, 0x00000A0D, 0x00060041, + 0x00000288, 0x00005FF4, 0x00000CC7, 0x00000A0B, 0x00002DBC, 0x0004003D, 0x0000000B, 0x0000374D, + 0x00005FF4, 0x00070050, 0x00000017, 0x00004CD7, 0x00005D49, 0x00005C6F, 0x00005C70, 0x0000374D, + 0x00050084, 0x0000000B, 0x00004299, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000036A9, + 0x00001FB2, 0x00004299, 0x00060041, 0x00000288, 0x00003B83, 0x00000CC7, 0x00000A0B, 0x000036A9, + 0x0004003D, 0x0000000B, 0x00005C71, 0x00003B83, 0x00050080, 0x0000000B, 0x00002DBD, 0x000036A9, + 0x00000A0D, 0x00060041, 0x00000288, 0x0000194E, 0x00000CC7, 0x00000A0B, 0x00002DBD, 0x0004003D, + 0x0000000B, 0x00005E60, 0x0000194E, 0x00050084, 0x0000000B, 0x0000185F, 0x00000A13, 0x0000199B, + 0x00050080, 0x0000000B, 0x000020A6, 0x00001FB2, 0x0000185F, 0x00060041, 0x00000288, 0x00003B84, + 0x00000CC7, 0x00000A0B, 0x000020A6, 0x0004003D, 0x0000000B, 0x00005C72, 0x00003B84, 0x00050080, + 0x0000000B, 0x00002DBE, 0x000020A6, 0x00000A0D, 0x00060041, 0x00000288, 0x00005FF5, 0x00000CC7, + 0x00000A0B, 0x00002DBE, 0x0004003D, 0x0000000B, 0x00004002, 0x00005FF5, 0x00070050, 0x00000017, + 0x00005132, 0x00005C71, 0x00005E60, 0x00005C72, 0x00004002, 0x000200F9, 0x00004F25, 0x000200F8, + 0x00002625, 0x00060041, 0x00000288, 0x00005548, 0x00000CC7, 0x00000A0B, 0x00001FB2, 0x0004003D, + 0x0000000B, 0x00005D4A, 0x00005548, 0x00050080, 0x0000000B, 0x00002DBF, 0x00001FB2, 0x00000A0D, + 0x00060041, 0x00000288, 0x0000190B, 0x00000CC7, 0x00000A0B, 0x00002DBF, 0x0004003D, 0x0000000B, + 0x00005C73, 0x0000190B, 0x00050080, 0x0000000B, 0x00002DC0, 0x00001FB2, 0x00000A10, 0x00060041, + 0x00000288, 0x0000190C, 0x00000CC7, 0x00000A0B, 0x00002DC0, 0x0004003D, 0x0000000B, 0x00005C74, + 0x0000190C, 0x00050080, 0x0000000B, 0x00002DC1, 0x00001FB2, 0x00000A13, 0x00060041, 0x00000288, + 0x00005FF6, 0x00000CC7, 0x00000A0B, 0x00002DC1, 0x0004003D, 0x0000000B, 0x00003701, 0x00005FF6, + 0x00070050, 0x00000017, 0x00004ADE, 0x00005D4A, 0x00005C73, 0x00005C74, 0x00003701, 0x00050080, + 0x0000000B, 0x000057E6, 0x00001FB2, 0x00000A16, 0x00060041, 0x00000288, 0x0000604C, 0x00000CC7, + 0x00000A0B, 0x000057E6, 0x0004003D, 0x0000000B, 0x00005C75, 0x0000604C, 0x00050080, 0x0000000B, + 0x00002DC2, 0x00001FB2, 0x00000A19, 0x00060041, 0x00000288, 0x0000190D, 0x00000CC7, 0x00000A0B, + 0x00002DC2, 0x0004003D, 0x0000000B, 0x00005C76, 0x0000190D, 0x00050080, 0x0000000B, 0x00002DC3, + 0x00001FB2, 0x00000A1C, 0x00060041, 0x00000288, 0x0000190E, 0x00000CC7, 0x00000A0B, 0x00002DC3, + 0x0004003D, 0x0000000B, 0x00005C77, 0x0000190E, 0x00050080, 0x0000000B, 0x00002DC4, 0x00001FB2, + 0x00000A1F, 0x00060041, 0x00000288, 0x00005FF7, 0x00000CC7, 0x00000A0B, 0x00002DC4, 0x0004003D, + 0x0000000B, 0x00004003, 0x00005FF7, 0x00070050, 0x00000017, 0x00005133, 0x00005C75, 0x00005C76, + 0x00005C77, 0x00004003, 0x000200F9, 0x00004F25, 0x000200F8, 0x00004F25, 0x000700F5, 0x00000017, + 0x00002BCE, 0x00005133, 0x00002625, 0x00005132, 0x00002F64, 0x000700F5, 0x00000017, 0x00003721, + 0x00004ADE, 0x00002625, 0x00004CD7, 0x00002F64, 0x000300F7, 0x00004F26, 0x00000000, 0x000700FB, + 0x00002180, 0x00004F57, 0x00000005, 0x00002159, 0x00000007, 0x00002036, 0x000200F8, 0x00002036, + 0x00050051, 0x0000000B, 0x00005F59, 0x00003721, 0x00000000, 0x0006000C, 0x00000013, 0x0000606A, + 0x00000001, 0x0000003E, 0x00005F59, 0x00050051, 0x0000000D, 0x00002779, 0x0000606A, 0x00000000, + 0x00050051, 0x0000000D, 0x00003EBC, 0x0000606A, 0x00000001, 0x00050051, 0x0000000B, 0x00004285, + 0x00003721, 0x00000001, 0x0006000C, 0x00000013, 0x00003CF9, 0x00000001, 0x0000003E, 0x00004285, + 0x00050051, 0x0000000D, 0x0000276E, 0x00003CF9, 0x00000000, 0x00050051, 0x0000000D, 0x0000444F, + 0x00003CF9, 0x00000001, 0x00070050, 0x0000001D, 0x00003915, 0x00002779, 0x00003EBC, 0x0000276E, + 0x0000444F, 0x00050051, 0x0000000B, 0x00004383, 0x00003721, 0x00000002, 0x0006000C, 0x00000013, + 0x00004674, 0x00000001, 0x0000003E, 0x00004383, 0x00050051, 0x0000000D, 0x0000277A, 0x00004674, + 0x00000000, 0x00050051, 0x0000000D, 0x00003EBD, 0x00004674, 0x00000001, 0x00050051, 0x0000000B, + 0x00004286, 0x00003721, 0x00000003, 0x0006000C, 0x00000013, 0x00003CFA, 0x00000001, 0x0000003E, + 0x00004286, 0x00050051, 0x0000000D, 0x0000276F, 0x00003CFA, 0x00000000, 0x00050051, 0x0000000D, + 0x00004450, 0x00003CFA, 0x00000001, 0x00070050, 0x0000001D, 0x00003916, 0x0000277A, 0x00003EBD, + 0x0000276F, 0x00004450, 0x00050051, 0x0000000B, 0x00004384, 0x00002BCE, 0x00000000, 0x0006000C, + 0x00000013, 0x00004675, 0x00000001, 0x0000003E, 0x00004384, 0x00050051, 0x0000000D, 0x0000277B, + 0x00004675, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBE, 0x00004675, 0x00000001, 0x00050051, + 0x0000000B, 0x00004287, 0x00002BCE, 0x00000001, 0x0006000C, 0x00000013, 0x00003CFB, 0x00000001, + 0x0000003E, 0x00004287, 0x00050051, 0x0000000D, 0x00002770, 0x00003CFB, 0x00000000, 0x00050051, + 0x0000000D, 0x00004451, 0x00003CFB, 0x00000001, 0x00070050, 0x0000001D, 0x00003917, 0x0000277B, + 0x00003EBE, 0x00002770, 0x00004451, 0x00050051, 0x0000000B, 0x00004385, 0x00002BCE, 0x00000002, + 0x0006000C, 0x00000013, 0x00004676, 0x00000001, 0x0000003E, 0x00004385, 0x00050051, 0x0000000D, + 0x0000277C, 0x00004676, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBF, 0x00004676, 0x00000001, + 0x00050051, 0x0000000B, 0x00004288, 0x00002BCE, 0x00000003, 0x0006000C, 0x00000013, 0x00003CFC, + 0x00000001, 0x0000003E, 0x00004288, 0x00050051, 0x0000000D, 0x00002771, 0x00003CFC, 0x00000000, + 0x00050051, 0x0000000D, 0x000050C1, 0x00003CFC, 0x00000001, 0x00070050, 0x0000001D, 0x00002351, + 0x0000277C, 0x00003EBF, 0x00002771, 0x000050C1, 0x000200F9, 0x00004F26, 0x000200F8, 0x00002159, + 0x0007004F, 0x00000011, 0x000025FC, 0x00003721, 0x00003721, 0x00000000, 0x00000001, 0x0004007C, + 0x00000012, 0x00005B3D, 0x000025FC, 0x0009004F, 0x0000001A, 0x000060D2, 0x00005B3D, 0x00005B3D, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048AA, 0x000060D2, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D91, 0x000048AA, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002AAB, 0x00003D91, 0x0005008E, 0x0000001D, 0x00004725, 0x00002AAB, 0x000007FE, 0x0007000C, + 0x0000001D, 0x00006294, 0x00000001, 0x00000028, 0x00000504, 0x00004725, 0x0007004F, 0x00000011, + 0x0000376E, 0x00003721, 0x00003721, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C2, + 0x0000376E, 0x0009004F, 0x0000001A, 0x000060D3, 0x000024C2, 0x000024C2, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048AB, 0x000060D3, 0x00000122, 0x000500C3, + 0x0000001A, 0x00003D92, 0x000048AB, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AAC, 0x00003D92, + 0x0005008E, 0x0000001D, 0x00004726, 0x00002AAC, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006295, + 0x00000001, 0x00000028, 0x00000504, 0x00004726, 0x0007004F, 0x00000011, 0x0000376F, 0x00002BCE, + 0x00002BCE, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000024C3, 0x0000376F, 0x0009004F, + 0x0000001A, 0x000060D4, 0x000024C3, 0x000024C3, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C4, 0x0000001A, 0x000048AC, 0x000060D4, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D93, + 0x000048AC, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AAD, 0x00003D93, 0x0005008E, 0x0000001D, + 0x00004727, 0x00002AAD, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006296, 0x00000001, 0x00000028, + 0x00000504, 0x00004727, 0x0007004F, 0x00000011, 0x00003770, 0x00002BCE, 0x00002BCE, 0x00000002, + 0x00000003, 0x0004007C, 0x00000012, 0x000024C4, 0x00003770, 0x0009004F, 0x0000001A, 0x000060D5, + 0x000024C4, 0x000024C4, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, + 0x000048AD, 0x000060D5, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D94, 0x000048AD, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002AAE, 0x00003D94, 0x0005008E, 0x0000001D, 0x000053C0, 0x00002AAE, + 0x000007FE, 0x0007000C, 0x0000001D, 0x00004363, 0x00000001, 0x00000028, 0x00000504, 0x000053C0, + 0x000200F9, 0x00004F26, 0x000200F8, 0x00004F57, 0x0007004F, 0x00000011, 0x00002626, 0x00003721, + 0x00003721, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x0000515A, 0x00002626, 0x00050051, + 0x0000000D, 0x00001B80, 0x0000515A, 0x00000000, 0x00050051, 0x0000000D, 0x0000346D, 0x0000515A, + 0x00000001, 0x00070050, 0x0000001D, 0x0000427B, 0x00001B80, 0x0000346D, 0x00000A0C, 0x00000A0C, + 0x0007004F, 0x00000011, 0x000041DB, 0x00003721, 0x00003721, 0x00000002, 0x00000003, 0x0004007C, + 0x00000013, 0x00003760, 0x000041DB, 0x00050051, 0x0000000D, 0x00001B81, 0x00003760, 0x00000000, + 0x00050051, 0x0000000D, 0x0000346E, 0x00003760, 0x00000001, 0x00070050, 0x0000001D, 0x0000427C, + 0x00001B81, 0x0000346E, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DC, 0x00002BCE, + 0x00002BCE, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x00003761, 0x000041DC, 0x00050051, + 0x0000000D, 0x00001B82, 0x00003761, 0x00000000, 0x00050051, 0x0000000D, 0x0000346F, 0x00003761, + 0x00000001, 0x00070050, 0x0000001D, 0x0000427D, 0x00001B82, 0x0000346F, 0x00000A0C, 0x00000A0C, + 0x0007004F, 0x00000011, 0x000041DD, 0x00002BCE, 0x00002BCE, 0x00000002, 0x00000003, 0x0004007C, + 0x00000013, 0x00003762, 0x000041DD, 0x00050051, 0x0000000D, 0x00001B83, 0x00003762, 0x00000000, + 0x00050051, 0x0000000D, 0x00004109, 0x00003762, 0x00000001, 0x00070050, 0x0000001D, 0x00002352, + 0x00001B83, 0x00004109, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F26, 0x000200F8, 0x00004F26, + 0x000900F5, 0x0000001D, 0x00002BAB, 0x00002352, 0x00004F57, 0x00004363, 0x00002159, 0x00002351, + 0x00002036, 0x000900F5, 0x0000001D, 0x0000380C, 0x0000427D, 0x00004F57, 0x00006296, 0x00002159, + 0x00003917, 0x00002036, 0x000900F5, 0x0000001D, 0x00003B80, 0x0000427C, 0x00004F57, 0x00006295, + 0x00002159, 0x00003916, 0x00002036, 0x000900F5, 0x0000001D, 0x000038B9, 0x0000427B, 0x00004F57, + 0x00006294, 0x00002159, 0x00003915, 0x00002036, 0x000200F9, 0x00005310, 0x000200F8, 0x00005310, + 0x000700F5, 0x0000001D, 0x00002BAC, 0x00002BAB, 0x00004F26, 0x00002BAA, 0x00003F61, 0x000700F5, + 0x0000001D, 0x0000380D, 0x0000380C, 0x00004F26, 0x0000380B, 0x00003F61, 0x000700F5, 0x0000001D, + 0x00003295, 0x00003B80, 0x00004F26, 0x00003B7F, 0x00003F61, 0x000700F5, 0x0000001D, 0x0000367A, + 0x000038B9, 0x00004F26, 0x000038B8, 0x00003F61, 0x00050081, 0x0000001D, 0x00004359, 0x000020D3, + 0x0000367A, 0x00050081, 0x0000001D, 0x00005B01, 0x000035EC, 0x00003295, 0x00050081, 0x0000001D, + 0x00001F92, 0x0000380A, 0x0000380D, 0x00050081, 0x0000001D, 0x00005113, 0x00002BA9, 0x00002BAC, + 0x000500AE, 0x00000009, 0x0000387D, 0x00004356, 0x00000A1C, 0x000300F7, 0x00005EC8, 0x00000002, + 0x000400FA, 0x0000387D, 0x000026B1, 0x00005EC8, 0x000200F8, 0x000026B1, 0x000500C4, 0x0000000B, + 0x000037B2, 0x00000A0D, 0x000023AA, 0x00050085, 0x0000000D, 0x00002F3A, 0x00002B2C, 0x0000016E, + 0x00050080, 0x0000000B, 0x000051FC, 0x0000628F, 0x000037B2, 0x000300F7, 0x00005311, 0x00000002, + 0x000400FA, 0x00005AEF, 0x00003B67, 0x000040BB, 0x000200F8, 0x000040BB, 0x000500AA, 0x00000009, + 0x00004ADF, 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F4B, 0x00000002, 0x000400FA, 0x00004ADF, + 0x00002627, 0x00002F65, 0x000200F8, 0x00002F65, 0x00060041, 0x00000288, 0x00004BD3, 0x00000CC7, + 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, 0x00005D4B, 0x00004BD3, 0x00050080, 0x0000000B, + 0x00002DC5, 0x000051FC, 0x0000199B, 0x00060041, 0x00000288, 0x0000194F, 0x00000CC7, 0x00000A0B, + 0x00002DC5, 0x0004003D, 0x0000000B, 0x00005E61, 0x0000194F, 0x00050084, 0x0000000B, 0x00001860, + 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A7, 0x000051FC, 0x00001860, 0x00060041, + 0x00000288, 0x00003BCF, 0x00000CC7, 0x00000A0B, 0x000020A7, 0x0004003D, 0x0000000B, 0x00005E62, + 0x00003BCF, 0x00050084, 0x0000000B, 0x00001861, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, + 0x000020A8, 0x000051FC, 0x00001861, 0x00060041, 0x00000288, 0x000037F3, 0x00000CC7, 0x00000A0B, + 0x000020A8, 0x0004003D, 0x0000000B, 0x00004004, 0x000037F3, 0x00070050, 0x00000017, 0x00005134, + 0x00005D4B, 0x00005E61, 0x00005E62, 0x00004004, 0x000200F9, 0x00004F4B, 0x000200F8, 0x00002627, + 0x00060041, 0x00000288, 0x00005549, 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, + 0x00005D4C, 0x00005549, 0x00050080, 0x0000000B, 0x00002DC6, 0x000051FC, 0x00000A0D, 0x00060041, + 0x00000288, 0x0000190F, 0x00000CC7, 0x00000A0B, 0x00002DC6, 0x0004003D, 0x0000000B, 0x00005C78, + 0x0000190F, 0x00050080, 0x0000000B, 0x00002DC7, 0x000051FC, 0x00000A10, 0x00060041, 0x00000288, + 0x00001910, 0x00000CC7, 0x00000A0B, 0x00002DC7, 0x0004003D, 0x0000000B, 0x00005C79, 0x00001910, + 0x00050080, 0x0000000B, 0x00002DC8, 0x000051FC, 0x00000A13, 0x00060041, 0x00000288, 0x00005FF8, + 0x00000CC7, 0x00000A0B, 0x00002DC8, 0x0004003D, 0x0000000B, 0x00004005, 0x00005FF8, 0x00070050, + 0x00000017, 0x00005135, 0x00005D4C, 0x00005C78, 0x00005C79, 0x00004005, 0x000200F9, 0x00004F4B, + 0x000200F8, 0x00004F4B, 0x000700F5, 0x00000017, 0x00002AC1, 0x00005135, 0x00002627, 0x00005134, + 0x00002F65, 0x000300F7, 0x00003F62, 0x00000000, 0x001300FB, 0x00002180, 0x00004BFD, 0x00000000, + 0x000038FB, 0x00000001, 0x000038FB, 0x00000002, 0x00001CBF, 0x0000000A, 0x00001CBF, 0x00000003, + 0x00001CBE, 0x0000000C, 0x00001CBE, 0x00000004, 0x00002000, 0x00000006, 0x00002037, 0x000200F8, + 0x00002037, 0x00050051, 0x0000000B, 0x00005F5A, 0x00002AC1, 0x00000000, 0x0006000C, 0x00000013, + 0x0000606B, 0x00000001, 0x0000003E, 0x00005F5A, 0x00050051, 0x0000000D, 0x00002772, 0x0000606B, + 0x00000000, 0x00050051, 0x0000000D, 0x00004452, 0x0000606B, 0x00000001, 0x00070050, 0x0000001D, + 0x00003918, 0x00002772, 0x00004452, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004386, + 0x00002AC1, 0x00000001, 0x0006000C, 0x00000013, 0x00004677, 0x00000001, 0x0000003E, 0x00004386, + 0x00050051, 0x0000000D, 0x00002773, 0x00004677, 0x00000000, 0x00050051, 0x0000000D, 0x00004453, + 0x00004677, 0x00000001, 0x00070050, 0x0000001D, 0x00003919, 0x00002773, 0x00004453, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x00004387, 0x00002AC1, 0x00000002, 0x0006000C, 0x00000013, + 0x00004678, 0x00000001, 0x0000003E, 0x00004387, 0x00050051, 0x0000000D, 0x00002774, 0x00004678, + 0x00000000, 0x00050051, 0x0000000D, 0x00004454, 0x00004678, 0x00000001, 0x00070050, 0x0000001D, + 0x0000391A, 0x00002774, 0x00004454, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004388, + 0x00002AC1, 0x00000003, 0x0006000C, 0x00000013, 0x00004679, 0x00000001, 0x0000003E, 0x00004388, + 0x00050051, 0x0000000D, 0x0000277D, 0x00004679, 0x00000000, 0x00050051, 0x0000000D, 0x000050C2, + 0x00004679, 0x00000001, 0x00070050, 0x0000001D, 0x00002353, 0x0000277D, 0x000050C2, 0x00000A0C, + 0x00000A0C, 0x000200F9, 0x00003F62, 0x000200F8, 0x00002000, 0x00050051, 0x0000000B, 0x0000308F, + 0x00002AC1, 0x00000000, 0x0004007C, 0x0000000C, 0x0000589F, 0x0000308F, 0x00050050, 0x00000012, + 0x00004728, 0x0000589F, 0x0000589F, 0x000500C4, 0x00000012, 0x000047B5, 0x00004728, 0x000007A7, + 0x000500C3, 0x00000012, 0x0000341F, 0x000047B5, 0x00000867, 0x0004006F, 0x00000013, 0x00002AAF, + 0x0000341F, 0x0005008E, 0x00000013, 0x0000474F, 0x00002AAF, 0x000007FE, 0x0007000C, 0x00000013, + 0x00005E0E, 0x00000001, 0x00000028, 0x00000049, 0x0000474F, 0x00050051, 0x0000000D, 0x00005F12, + 0x00005E0E, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDA, 0x00005E0E, 0x00000001, 0x00070050, + 0x0000001D, 0x00004124, 0x00005F12, 0x00003CDA, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x00004C48, 0x00002AC1, 0x00000001, 0x0004007C, 0x0000000C, 0x00003EA7, 0x00004C48, 0x00050050, + 0x00000012, 0x00004729, 0x00003EA7, 0x00003EA7, 0x000500C4, 0x00000012, 0x000047B6, 0x00004729, + 0x000007A7, 0x000500C3, 0x00000012, 0x00003420, 0x000047B6, 0x00000867, 0x0004006F, 0x00000013, + 0x00002AB0, 0x00003420, 0x0005008E, 0x00000013, 0x00004750, 0x00002AB0, 0x000007FE, 0x0007000C, + 0x00000013, 0x00005E0F, 0x00000001, 0x00000028, 0x00000049, 0x00004750, 0x00050051, 0x0000000D, + 0x00005F13, 0x00005E0F, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDB, 0x00005E0F, 0x00000001, + 0x00070050, 0x0000001D, 0x00004125, 0x00005F13, 0x00003CDB, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x00004C49, 0x00002AC1, 0x00000002, 0x0004007C, 0x0000000C, 0x00003EA8, 0x00004C49, + 0x00050050, 0x00000012, 0x0000472A, 0x00003EA8, 0x00003EA8, 0x000500C4, 0x00000012, 0x000047B7, + 0x0000472A, 0x000007A7, 0x000500C3, 0x00000012, 0x00003421, 0x000047B7, 0x00000867, 0x0004006F, + 0x00000013, 0x00002AB1, 0x00003421, 0x0005008E, 0x00000013, 0x00004751, 0x00002AB1, 0x000007FE, + 0x0007000C, 0x00000013, 0x00005E10, 0x00000001, 0x00000028, 0x00000049, 0x00004751, 0x00050051, + 0x0000000D, 0x00005F14, 0x00005E10, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDC, 0x00005E10, + 0x00000001, 0x00070050, 0x0000001D, 0x00004126, 0x00005F14, 0x00003CDC, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x00004C4A, 0x00002AC1, 0x00000003, 0x0004007C, 0x0000000C, 0x00003EA9, + 0x00004C4A, 0x00050050, 0x00000012, 0x0000472B, 0x00003EA9, 0x00003EA9, 0x000500C4, 0x00000012, + 0x000047B8, 0x0000472B, 0x000007A7, 0x000500C3, 0x00000012, 0x00003422, 0x000047B8, 0x00000867, + 0x0004006F, 0x00000013, 0x00002AB2, 0x00003422, 0x0005008E, 0x00000013, 0x00004752, 0x00002AB2, + 0x000007FE, 0x0007000C, 0x00000013, 0x00005E11, 0x00000001, 0x00000028, 0x00000049, 0x00004752, + 0x00050051, 0x0000000D, 0x00005F15, 0x00005E11, 0x00000000, 0x00050051, 0x0000000D, 0x0000494E, + 0x00005E11, 0x00000001, 0x00070050, 0x0000001D, 0x00002354, 0x00005F15, 0x0000494E, 0x00000A0C, + 0x00000A0C, 0x000200F9, 0x00003F62, 0x000200F8, 0x00001CBE, 0x00050051, 0x0000000B, 0x000056C3, + 0x00002AC1, 0x00000000, 0x00060050, 0x00000014, 0x00004F10, 0x000056C3, 0x000056C3, 0x000056C3, + 0x000500C2, 0x00000014, 0x00002B17, 0x00004F10, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEE, + 0x00002B17, 0x00000105, 0x000500C7, 0x00000014, 0x000048A4, 0x00005DEE, 0x00000466, 0x000500C2, + 0x00000014, 0x00005B98, 0x00005DEE, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D1, 0x00005B98, + 0x00000A12, 0x0006000C, 0x00000016, 0x00002C53, 0x00000001, 0x0000004B, 0x000048A4, 0x0004007C, + 0x00000014, 0x00002A1D, 0x00002C53, 0x00050082, 0x00000014, 0x00001882, 0x00000B0C, 0x00002A1D, + 0x00050080, 0x00000014, 0x00002218, 0x00002A1D, 0x00000938, 0x000600A9, 0x00000014, 0x00002877, + 0x000040D1, 0x00002218, 0x00005B98, 0x000500C4, 0x00000014, 0x00005ADC, 0x000048A4, 0x00001882, + 0x000500C7, 0x00000014, 0x000049A2, 0x00005ADC, 0x00000466, 0x000600A9, 0x00000014, 0x00002AB3, + 0x000040D1, 0x000049A2, 0x000048A4, 0x00050080, 0x00000014, 0x00006001, 0x00002877, 0x000003FA, + 0x000500C4, 0x00000014, 0x00004F87, 0x00006001, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAE, + 0x00002AB3, 0x0000008D, 0x000500C5, 0x00000014, 0x00005784, 0x00004F87, 0x00003FAE, 0x000500AA, + 0x00000010, 0x00003608, 0x00005DEE, 0x00000A12, 0x000600A9, 0x00000014, 0x0000424A, 0x00003608, + 0x00000A12, 0x00005784, 0x0004007C, 0x00000018, 0x000029D7, 0x0000424A, 0x000500C2, 0x0000000B, + 0x00004BAC, 0x000056C3, 0x00000A64, 0x00040070, 0x0000000D, 0x00004816, 0x00004BAC, 0x00050085, + 0x0000000D, 0x00003E27, 0x00004816, 0x00000149, 0x00050051, 0x0000000D, 0x000053CA, 0x000029D7, + 0x00000000, 0x00050051, 0x0000000D, 0x00002A5D, 0x000029D7, 0x00000001, 0x00050051, 0x0000000D, + 0x00001E9F, 0x000029D7, 0x00000002, 0x00070050, 0x0000001D, 0x00003DE0, 0x000053CA, 0x00002A5D, + 0x00001E9F, 0x00003E27, 0x00050051, 0x0000000B, 0x000027FB, 0x00002AC1, 0x00000001, 0x00060050, + 0x00000014, 0x00003514, 0x000027FB, 0x000027FB, 0x000027FB, 0x000500C2, 0x00000014, 0x00002B18, + 0x00003514, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEF, 0x00002B18, 0x00000105, 0x000500C7, + 0x00000014, 0x000048A5, 0x00005DEF, 0x00000466, 0x000500C2, 0x00000014, 0x00005B99, 0x00005DEF, + 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D2, 0x00005B99, 0x00000A12, 0x0006000C, 0x00000016, + 0x00002C54, 0x00000001, 0x0000004B, 0x000048A5, 0x0004007C, 0x00000014, 0x00002A1E, 0x00002C54, + 0x00050082, 0x00000014, 0x00001883, 0x00000B0C, 0x00002A1E, 0x00050080, 0x00000014, 0x00002219, + 0x00002A1E, 0x00000938, 0x000600A9, 0x00000014, 0x00002878, 0x000040D2, 0x00002219, 0x00005B99, + 0x000500C4, 0x00000014, 0x00005ADD, 0x000048A5, 0x00001883, 0x000500C7, 0x00000014, 0x000049A3, + 0x00005ADD, 0x00000466, 0x000600A9, 0x00000014, 0x00002AB4, 0x000040D2, 0x000049A3, 0x000048A5, + 0x00050080, 0x00000014, 0x00006002, 0x00002878, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F88, + 0x00006002, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAF, 0x00002AB4, 0x0000008D, 0x000500C5, + 0x00000014, 0x00005785, 0x00004F88, 0x00003FAF, 0x000500AA, 0x00000010, 0x00003609, 0x00005DEF, + 0x00000A12, 0x000600A9, 0x00000014, 0x0000424B, 0x00003609, 0x00000A12, 0x00005785, 0x0004007C, + 0x00000018, 0x000029D8, 0x0000424B, 0x000500C2, 0x0000000B, 0x00004BAD, 0x000027FB, 0x00000A64, + 0x00040070, 0x0000000D, 0x00004817, 0x00004BAD, 0x00050085, 0x0000000D, 0x00003E28, 0x00004817, + 0x00000149, 0x00050051, 0x0000000D, 0x000053CB, 0x000029D8, 0x00000000, 0x00050051, 0x0000000D, + 0x00002A5E, 0x000029D8, 0x00000001, 0x00050051, 0x0000000D, 0x00001EA0, 0x000029D8, 0x00000002, + 0x00070050, 0x0000001D, 0x00003DE1, 0x000053CB, 0x00002A5E, 0x00001EA0, 0x00003E28, 0x00050051, + 0x0000000B, 0x000027FC, 0x00002AC1, 0x00000002, 0x00060050, 0x00000014, 0x00003515, 0x000027FC, + 0x000027FC, 0x000027FC, 0x000500C2, 0x00000014, 0x00002B19, 0x00003515, 0x00000BB4, 0x000500C7, + 0x00000014, 0x00005DF0, 0x00002B19, 0x00000105, 0x000500C7, 0x00000014, 0x000048AE, 0x00005DF0, + 0x00000466, 0x000500C2, 0x00000014, 0x00005B9A, 0x00005DF0, 0x00000B0C, 0x000500AA, 0x00000010, + 0x000040D3, 0x00005B9A, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C55, 0x00000001, 0x0000004B, + 0x000048AE, 0x0004007C, 0x00000014, 0x00002A1F, 0x00002C55, 0x00050082, 0x00000014, 0x00001884, + 0x00000B0C, 0x00002A1F, 0x00050080, 0x00000014, 0x0000221A, 0x00002A1F, 0x00000938, 0x000600A9, + 0x00000014, 0x00002879, 0x000040D3, 0x0000221A, 0x00005B9A, 0x000500C4, 0x00000014, 0x00005ADE, + 0x000048AE, 0x00001884, 0x000500C7, 0x00000014, 0x000049A4, 0x00005ADE, 0x00000466, 0x000600A9, + 0x00000014, 0x00002AB5, 0x000040D3, 0x000049A4, 0x000048AE, 0x00050080, 0x00000014, 0x00006003, + 0x00002879, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F89, 0x00006003, 0x00000189, 0x000500C4, + 0x00000014, 0x00003FB0, 0x00002AB5, 0x0000008D, 0x000500C5, 0x00000014, 0x00005786, 0x00004F89, + 0x00003FB0, 0x000500AA, 0x00000010, 0x0000360A, 0x00005DF0, 0x00000A12, 0x000600A9, 0x00000014, + 0x0000424C, 0x0000360A, 0x00000A12, 0x00005786, 0x0004007C, 0x00000018, 0x000029D9, 0x0000424C, + 0x000500C2, 0x0000000B, 0x00004BAE, 0x000027FC, 0x00000A64, 0x00040070, 0x0000000D, 0x00004818, + 0x00004BAE, 0x00050085, 0x0000000D, 0x00003E29, 0x00004818, 0x00000149, 0x00050051, 0x0000000D, + 0x000053CC, 0x000029D9, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5F, 0x000029D9, 0x00000001, + 0x00050051, 0x0000000D, 0x00001EA1, 0x000029D9, 0x00000002, 0x00070050, 0x0000001D, 0x00003DE2, + 0x000053CC, 0x00002A5F, 0x00001EA1, 0x00003E29, 0x00050051, 0x0000000B, 0x000027FD, 0x00002AC1, + 0x00000003, 0x00060050, 0x00000014, 0x00003516, 0x000027FD, 0x000027FD, 0x000027FD, 0x000500C2, + 0x00000014, 0x00002B1A, 0x00003516, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF1, 0x00002B1A, + 0x00000105, 0x000500C7, 0x00000014, 0x000048AF, 0x00005DF1, 0x00000466, 0x000500C2, 0x00000014, + 0x00005B9B, 0x00005DF1, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D4, 0x00005B9B, 0x00000A12, + 0x0006000C, 0x00000016, 0x00002C56, 0x00000001, 0x0000004B, 0x000048AF, 0x0004007C, 0x00000014, + 0x00002A20, 0x00002C56, 0x00050082, 0x00000014, 0x00001885, 0x00000B0C, 0x00002A20, 0x00050080, + 0x00000014, 0x0000221B, 0x00002A20, 0x00000938, 0x000600A9, 0x00000014, 0x0000287A, 0x000040D4, + 0x0000221B, 0x00005B9B, 0x000500C4, 0x00000014, 0x00005ADF, 0x000048AF, 0x00001885, 0x000500C7, + 0x00000014, 0x000049A5, 0x00005ADF, 0x00000466, 0x000600A9, 0x00000014, 0x00002AB6, 0x000040D4, + 0x000049A5, 0x000048AF, 0x00050080, 0x00000014, 0x00006004, 0x0000287A, 0x000003FA, 0x000500C4, + 0x00000014, 0x00004F8A, 0x00006004, 0x00000189, 0x000500C4, 0x00000014, 0x00003FB1, 0x00002AB6, + 0x0000008D, 0x000500C5, 0x00000014, 0x00005787, 0x00004F8A, 0x00003FB1, 0x000500AA, 0x00000010, + 0x0000360B, 0x00005DF1, 0x00000A12, 0x000600A9, 0x00000014, 0x0000424D, 0x0000360B, 0x00000A12, + 0x00005787, 0x0004007C, 0x00000018, 0x000029DA, 0x0000424D, 0x000500C2, 0x0000000B, 0x00004BAF, + 0x000027FD, 0x00000A64, 0x00040070, 0x0000000D, 0x00004819, 0x00004BAF, 0x00050085, 0x0000000D, + 0x00003E2A, 0x00004819, 0x00000149, 0x00050051, 0x0000000D, 0x000053CD, 0x000029DA, 0x00000000, + 0x00050051, 0x0000000D, 0x00002A60, 0x000029DA, 0x00000001, 0x00050051, 0x0000000D, 0x00002B1B, + 0x000029DA, 0x00000002, 0x00070050, 0x0000001D, 0x00002355, 0x000053CD, 0x00002A60, 0x00002B1B, + 0x00003E2A, 0x000200F9, 0x00003F62, 0x000200F8, 0x00001CBF, 0x00050051, 0x0000000B, 0x000056C4, + 0x00002AC1, 0x00000000, 0x00070050, 0x00000017, 0x00004F11, 0x000056C4, 0x000056C4, 0x000056C4, + 0x000056C4, 0x000500C2, 0x00000017, 0x000024A8, 0x00004F11, 0x0000034D, 0x000500C7, 0x00000017, + 0x000049B3, 0x000024A8, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBD, 0x000049B3, 0x00050085, + 0x0000001D, 0x00004136, 0x00003CBD, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD8, 0x00002AC1, + 0x00000001, 0x00070050, 0x00000017, 0x00005153, 0x00005CD8, 0x00005CD8, 0x00005CD8, 0x00005CD8, + 0x000500C2, 0x00000017, 0x000024A9, 0x00005153, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B4, + 0x000024A9, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBE, 0x000049B4, 0x00050085, 0x0000001D, + 0x00004137, 0x00003CBE, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD9, 0x00002AC1, 0x00000002, + 0x00070050, 0x00000017, 0x00005154, 0x00005CD9, 0x00005CD9, 0x00005CD9, 0x00005CD9, 0x000500C2, + 0x00000017, 0x000024AA, 0x00005154, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B5, 0x000024AA, + 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBF, 0x000049B5, 0x00050085, 0x0000001D, 0x00004138, + 0x00003CBF, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CDA, 0x00002AC1, 0x00000003, 0x00070050, + 0x00000017, 0x00005155, 0x00005CDA, 0x00005CDA, 0x00005CDA, 0x00005CDA, 0x000500C2, 0x00000017, + 0x000024AB, 0x00005155, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B6, 0x000024AB, 0x0000027B, + 0x00040070, 0x0000001D, 0x00004931, 0x000049B6, 0x00050085, 0x0000001D, 0x000026A1, 0x00004931, + 0x00000AEE, 0x000200F9, 0x00003F62, 0x000200F8, 0x000038FB, 0x00050051, 0x0000000B, 0x000056C5, + 0x00002AC1, 0x00000000, 0x00070050, 0x00000017, 0x00004F12, 0x000056C5, 0x000056C5, 0x000056C5, + 0x000056C5, 0x000500C2, 0x00000017, 0x000024AC, 0x00004F12, 0x0000028D, 0x000500C7, 0x00000017, + 0x00004A5E, 0x000024AC, 0x0000064B, 0x00040070, 0x0000001D, 0x000036AA, 0x00004A5E, 0x0005008E, + 0x0000001D, 0x00004B29, 0x000036AA, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A5, 0x00002AC1, + 0x00000001, 0x00070050, 0x00000017, 0x00006111, 0x000021A5, 0x000021A5, 0x000021A5, 0x000021A5, + 0x000500C2, 0x00000017, 0x000024AD, 0x00006111, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5F, + 0x000024AD, 0x0000064B, 0x00040070, 0x0000001D, 0x000036AB, 0x00004A5F, 0x0005008E, 0x0000001D, + 0x00004B2A, 0x000036AB, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A6, 0x00002AC1, 0x00000002, + 0x00070050, 0x00000017, 0x00006112, 0x000021A6, 0x000021A6, 0x000021A6, 0x000021A6, 0x000500C2, + 0x00000017, 0x000024AE, 0x00006112, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A60, 0x000024AE, + 0x0000064B, 0x00040070, 0x0000001D, 0x000036AC, 0x00004A60, 0x0005008E, 0x0000001D, 0x00004B2B, + 0x000036AC, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A7, 0x00002AC1, 0x00000003, 0x00070050, + 0x00000017, 0x00006113, 0x000021A7, 0x000021A7, 0x000021A7, 0x000021A7, 0x000500C2, 0x00000017, + 0x000024AF, 0x00006113, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A61, 0x000024AF, 0x0000064B, + 0x00040070, 0x0000001D, 0x0000431C, 0x00004A61, 0x0005008E, 0x0000001D, 0x00003094, 0x0000431C, + 0x0000017A, 0x000200F9, 0x00003F62, 0x000200F8, 0x00004BFD, 0x00050051, 0x0000000B, 0x00003090, + 0x00002AC1, 0x00000000, 0x0004007C, 0x0000000D, 0x00004FF0, 0x00003090, 0x00050050, 0x00000013, + 0x0000433C, 0x00004FF0, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D96, 0x0000433C, 0x0000433C, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B7, 0x00002AC1, + 0x00000001, 0x0004007C, 0x0000000D, 0x00003F6E, 0x000056B7, 0x00050050, 0x00000013, 0x0000433D, + 0x00003F6E, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D97, 0x0000433D, 0x0000433D, 0x00000000, + 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B8, 0x00002AC1, 0x00000002, + 0x0004007C, 0x0000000D, 0x00003F6F, 0x000056B8, 0x00050050, 0x00000013, 0x0000433E, 0x00003F6F, + 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D98, 0x0000433E, 0x0000433E, 0x00000000, 0x00000001, + 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B9, 0x00002AC1, 0x00000003, 0x0004007C, + 0x0000000D, 0x00003F70, 0x000056B9, 0x00050050, 0x00000013, 0x00004FB0, 0x00003F70, 0x00000A0C, + 0x0009004F, 0x0000001D, 0x00005A3C, 0x00004FB0, 0x00004FB0, 0x00000000, 0x00000001, 0x00000001, + 0x00000001, 0x000200F9, 0x00003F62, 0x000200F8, 0x00003F62, 0x000F00F5, 0x0000001D, 0x00002BAD, + 0x00005A3C, 0x00004BFD, 0x00003094, 0x000038FB, 0x000026A1, 0x00001CBF, 0x00002355, 0x00001CBE, + 0x00002354, 0x00002000, 0x00002353, 0x00002037, 0x000F00F5, 0x0000001D, 0x0000380E, 0x00002D98, + 0x00004BFD, 0x00004B2B, 0x000038FB, 0x00004138, 0x00001CBF, 0x00003DE2, 0x00001CBE, 0x00004126, + 0x00002000, 0x0000391A, 0x00002037, 0x000F00F5, 0x0000001D, 0x00003B85, 0x00002D97, 0x00004BFD, + 0x00004B2A, 0x000038FB, 0x00004137, 0x00001CBF, 0x00003DE1, 0x00001CBE, 0x00004125, 0x00002000, + 0x00003919, 0x00002037, 0x000F00F5, 0x0000001D, 0x000038BA, 0x00002D96, 0x00004BFD, 0x00004B29, + 0x000038FB, 0x00004136, 0x00001CBF, 0x00003DE0, 0x00001CBE, 0x00004124, 0x00002000, 0x00003918, + 0x00002037, 0x000200F9, 0x00005311, 0x000200F8, 0x00003B67, 0x000500AA, 0x00000009, 0x00005452, + 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F27, 0x00000002, 0x000400FA, 0x00005452, 0x00002628, + 0x00002F66, 0x000200F8, 0x00002F66, 0x00060041, 0x00000288, 0x00004BD4, 0x00000CC7, 0x00000A0B, + 0x000051FC, 0x0004003D, 0x0000000B, 0x00005D4D, 0x00004BD4, 0x00050080, 0x0000000B, 0x00002DC9, + 0x000051FC, 0x00000A0D, 0x00060041, 0x00000288, 0x00001911, 0x00000CC7, 0x00000A0B, 0x00002DC9, + 0x0004003D, 0x0000000B, 0x00005C7A, 0x00001911, 0x00050080, 0x0000000B, 0x00002DCA, 0x000051FC, + 0x0000199B, 0x00060041, 0x00000288, 0x00001912, 0x00000CC7, 0x00000A0B, 0x00002DCA, 0x0004003D, + 0x0000000B, 0x00005C7B, 0x00001912, 0x00050080, 0x0000000B, 0x00002DCB, 0x00002DCA, 0x00000A0D, + 0x00060041, 0x00000288, 0x00006005, 0x00000CC7, 0x00000A0B, 0x00002DCB, 0x0004003D, 0x0000000B, + 0x0000374E, 0x00006005, 0x00070050, 0x00000017, 0x00004CD9, 0x00005D4D, 0x00005C7A, 0x00005C7B, + 0x0000374E, 0x00050084, 0x0000000B, 0x0000429A, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, + 0x000036AD, 0x000051FC, 0x0000429A, 0x00060041, 0x00000288, 0x00003B86, 0x00000CC7, 0x00000A0B, + 0x000036AD, 0x0004003D, 0x0000000B, 0x00005C7C, 0x00003B86, 0x00050080, 0x0000000B, 0x00002DCC, + 0x000036AD, 0x00000A0D, 0x00060041, 0x00000288, 0x00001950, 0x00000CC7, 0x00000A0B, 0x00002DCC, + 0x0004003D, 0x0000000B, 0x00005E63, 0x00001950, 0x00050084, 0x0000000B, 0x00001862, 0x00000A13, + 0x0000199B, 0x00050080, 0x0000000B, 0x000020A9, 0x000051FC, 0x00001862, 0x00060041, 0x00000288, + 0x00003B87, 0x00000CC7, 0x00000A0B, 0x000020A9, 0x0004003D, 0x0000000B, 0x00005C7D, 0x00003B87, + 0x00050080, 0x0000000B, 0x00002DCD, 0x000020A9, 0x00000A0D, 0x00060041, 0x00000288, 0x00006006, + 0x00000CC7, 0x00000A0B, 0x00002DCD, 0x0004003D, 0x0000000B, 0x00004006, 0x00006006, 0x00070050, + 0x00000017, 0x00005136, 0x00005C7C, 0x00005E63, 0x00005C7D, 0x00004006, 0x000200F9, 0x00004F27, + 0x000200F8, 0x00002628, 0x00060041, 0x00000288, 0x0000554A, 0x00000CC7, 0x00000A0B, 0x000051FC, + 0x0004003D, 0x0000000B, 0x00005D4E, 0x0000554A, 0x00050080, 0x0000000B, 0x00002DCE, 0x000051FC, + 0x00000A0D, 0x00060041, 0x00000288, 0x00001913, 0x00000CC7, 0x00000A0B, 0x00002DCE, 0x0004003D, + 0x0000000B, 0x00005C7E, 0x00001913, 0x00050080, 0x0000000B, 0x00002DCF, 0x000051FC, 0x00000A10, + 0x00060041, 0x00000288, 0x00001914, 0x00000CC7, 0x00000A0B, 0x00002DCF, 0x0004003D, 0x0000000B, + 0x00005C7F, 0x00001914, 0x00050080, 0x0000000B, 0x00002DD0, 0x000051FC, 0x00000A13, 0x00060041, + 0x00000288, 0x00006007, 0x00000CC7, 0x00000A0B, 0x00002DD0, 0x0004003D, 0x0000000B, 0x00003702, + 0x00006007, 0x00070050, 0x00000017, 0x00004AE0, 0x00005D4E, 0x00005C7E, 0x00005C7F, 0x00003702, + 0x00050080, 0x0000000B, 0x000057E7, 0x000051FC, 0x00000A16, 0x00060041, 0x00000288, 0x0000604D, + 0x00000CC7, 0x00000A0B, 0x000057E7, 0x0004003D, 0x0000000B, 0x00005C80, 0x0000604D, 0x00050080, + 0x0000000B, 0x00002DD1, 0x000051FC, 0x00000A19, 0x00060041, 0x00000288, 0x00001915, 0x00000CC7, + 0x00000A0B, 0x00002DD1, 0x0004003D, 0x0000000B, 0x00005C81, 0x00001915, 0x00050080, 0x0000000B, + 0x00002DD2, 0x000051FC, 0x00000A1C, 0x00060041, 0x00000288, 0x00001916, 0x00000CC7, 0x00000A0B, + 0x00002DD2, 0x0004003D, 0x0000000B, 0x00005C82, 0x00001916, 0x00050080, 0x0000000B, 0x00002DD3, + 0x000051FC, 0x00000A1F, 0x00060041, 0x00000288, 0x00006008, 0x00000CC7, 0x00000A0B, 0x00002DD3, + 0x0004003D, 0x0000000B, 0x00004007, 0x00006008, 0x00070050, 0x00000017, 0x00005137, 0x00005C80, + 0x00005C81, 0x00005C82, 0x00004007, 0x000200F9, 0x00004F27, 0x000200F8, 0x00004F27, 0x000700F5, + 0x00000017, 0x00002BCF, 0x00005137, 0x00002628, 0x00005136, 0x00002F66, 0x000700F5, 0x00000017, + 0x00003722, 0x00004AE0, 0x00002628, 0x00004CD9, 0x00002F66, 0x000300F7, 0x00004F28, 0x00000000, + 0x000700FB, 0x00002180, 0x00004F58, 0x00000005, 0x0000215A, 0x00000007, 0x00002038, 0x000200F8, + 0x00002038, 0x00050051, 0x0000000B, 0x00005F5B, 0x00003722, 0x00000000, 0x0006000C, 0x00000013, + 0x0000606C, 0x00000001, 0x0000003E, 0x00005F5B, 0x00050051, 0x0000000D, 0x0000277E, 0x0000606C, + 0x00000000, 0x00050051, 0x0000000D, 0x00003EC0, 0x0000606C, 0x00000001, 0x00050051, 0x0000000B, + 0x00004289, 0x00003722, 0x00000001, 0x0006000C, 0x00000013, 0x00003CFD, 0x00000001, 0x0000003E, + 0x00004289, 0x00050051, 0x0000000D, 0x0000277F, 0x00003CFD, 0x00000000, 0x00050051, 0x0000000D, + 0x00004455, 0x00003CFD, 0x00000001, 0x00070050, 0x0000001D, 0x0000391B, 0x0000277E, 0x00003EC0, + 0x0000277F, 0x00004455, 0x00050051, 0x0000000B, 0x00004389, 0x00003722, 0x00000002, 0x0006000C, + 0x00000013, 0x0000467A, 0x00000001, 0x0000003E, 0x00004389, 0x00050051, 0x0000000D, 0x00002780, + 0x0000467A, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC1, 0x0000467A, 0x00000001, 0x00050051, + 0x0000000B, 0x0000428A, 0x00003722, 0x00000003, 0x0006000C, 0x00000013, 0x00003CFE, 0x00000001, + 0x0000003E, 0x0000428A, 0x00050051, 0x0000000D, 0x00002781, 0x00003CFE, 0x00000000, 0x00050051, + 0x0000000D, 0x00004456, 0x00003CFE, 0x00000001, 0x00070050, 0x0000001D, 0x0000391C, 0x00002780, + 0x00003EC1, 0x00002781, 0x00004456, 0x00050051, 0x0000000B, 0x0000438A, 0x00002BCF, 0x00000000, + 0x0006000C, 0x00000013, 0x0000467B, 0x00000001, 0x0000003E, 0x0000438A, 0x00050051, 0x0000000D, + 0x00002782, 0x0000467B, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC2, 0x0000467B, 0x00000001, + 0x00050051, 0x0000000B, 0x0000428B, 0x00002BCF, 0x00000001, 0x0006000C, 0x00000013, 0x00003CFF, + 0x00000001, 0x0000003E, 0x0000428B, 0x00050051, 0x0000000D, 0x00002783, 0x00003CFF, 0x00000000, + 0x00050051, 0x0000000D, 0x00004457, 0x00003CFF, 0x00000001, 0x00070050, 0x0000001D, 0x0000391D, + 0x00002782, 0x00003EC2, 0x00002783, 0x00004457, 0x00050051, 0x0000000B, 0x0000438B, 0x00002BCF, + 0x00000002, 0x0006000C, 0x00000013, 0x0000467C, 0x00000001, 0x0000003E, 0x0000438B, 0x00050051, + 0x0000000D, 0x00002784, 0x0000467C, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC3, 0x0000467C, + 0x00000001, 0x00050051, 0x0000000B, 0x0000428C, 0x00002BCF, 0x00000003, 0x0006000C, 0x00000013, + 0x00003D00, 0x00000001, 0x0000003E, 0x0000428C, 0x00050051, 0x0000000D, 0x00002785, 0x00003D00, + 0x00000000, 0x00050051, 0x0000000D, 0x000050C3, 0x00003D00, 0x00000001, 0x00070050, 0x0000001D, + 0x00002356, 0x00002784, 0x00003EC3, 0x00002785, 0x000050C3, 0x000200F9, 0x00004F28, 0x000200F8, + 0x0000215A, 0x0007004F, 0x00000011, 0x000025FD, 0x00003722, 0x00003722, 0x00000000, 0x00000001, + 0x0004007C, 0x00000012, 0x00005B3E, 0x000025FD, 0x0009004F, 0x0000001A, 0x000060D6, 0x00005B3E, + 0x00005B3E, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048B0, + 0x000060D6, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D95, 0x000048B0, 0x00000302, 0x0004006F, + 0x0000001D, 0x00002AB7, 0x00003D95, 0x0005008E, 0x0000001D, 0x0000472C, 0x00002AB7, 0x000007FE, + 0x0007000C, 0x0000001D, 0x00006297, 0x00000001, 0x00000028, 0x00000504, 0x0000472C, 0x0007004F, + 0x00000011, 0x00003771, 0x00003722, 0x00003722, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, + 0x000024C5, 0x00003771, 0x0009004F, 0x0000001A, 0x000060D7, 0x000024C5, 0x000024C5, 0x00000000, + 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048B1, 0x000060D7, 0x00000122, + 0x000500C3, 0x0000001A, 0x00003D96, 0x000048B1, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AB8, + 0x00003D96, 0x0005008E, 0x0000001D, 0x0000472D, 0x00002AB8, 0x000007FE, 0x0007000C, 0x0000001D, + 0x00006298, 0x00000001, 0x00000028, 0x00000504, 0x0000472D, 0x0007004F, 0x00000011, 0x00003772, + 0x00002BCF, 0x00002BCF, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000024C6, 0x00003772, + 0x0009004F, 0x0000001A, 0x000060D8, 0x000024C6, 0x000024C6, 0x00000000, 0x00000000, 0x00000001, + 0x00000001, 0x000500C4, 0x0000001A, 0x000048B2, 0x000060D8, 0x00000122, 0x000500C3, 0x0000001A, + 0x00003D97, 0x000048B2, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AB9, 0x00003D97, 0x0005008E, + 0x0000001D, 0x0000472E, 0x00002AB9, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006299, 0x00000001, + 0x00000028, 0x00000504, 0x0000472E, 0x0007004F, 0x00000011, 0x00003773, 0x00002BCF, 0x00002BCF, + 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C7, 0x00003773, 0x0009004F, 0x0000001A, + 0x000060D9, 0x000024C7, 0x000024C7, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, + 0x0000001A, 0x000048B3, 0x000060D9, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D98, 0x000048B3, + 0x00000302, 0x0004006F, 0x0000001D, 0x00002ABA, 0x00003D98, 0x0005008E, 0x0000001D, 0x000053C1, + 0x00002ABA, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004364, 0x00000001, 0x00000028, 0x00000504, + 0x000053C1, 0x000200F9, 0x00004F28, 0x000200F8, 0x00004F58, 0x0007004F, 0x00000011, 0x00002629, + 0x00003722, 0x00003722, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x0000515B, 0x00002629, + 0x00050051, 0x0000000D, 0x00001B84, 0x0000515B, 0x00000000, 0x00050051, 0x0000000D, 0x00003470, + 0x0000515B, 0x00000001, 0x00070050, 0x0000001D, 0x0000427E, 0x00001B84, 0x00003470, 0x00000A0C, + 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DE, 0x00003722, 0x00003722, 0x00000002, 0x00000003, + 0x0004007C, 0x00000013, 0x00003763, 0x000041DE, 0x00050051, 0x0000000D, 0x00001B85, 0x00003763, + 0x00000000, 0x00050051, 0x0000000D, 0x00003471, 0x00003763, 0x00000001, 0x00070050, 0x0000001D, + 0x0000427F, 0x00001B85, 0x00003471, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DF, + 0x00002BCF, 0x00002BCF, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x00003764, 0x000041DF, + 0x00050051, 0x0000000D, 0x00001B86, 0x00003764, 0x00000000, 0x00050051, 0x0000000D, 0x00003472, + 0x00003764, 0x00000001, 0x00070050, 0x0000001D, 0x00004280, 0x00001B86, 0x00003472, 0x00000A0C, + 0x00000A0C, 0x0007004F, 0x00000011, 0x000041E0, 0x00002BCF, 0x00002BCF, 0x00000002, 0x00000003, + 0x0004007C, 0x00000013, 0x00003765, 0x000041E0, 0x00050051, 0x0000000D, 0x00001B87, 0x00003765, + 0x00000000, 0x00050051, 0x0000000D, 0x0000410A, 0x00003765, 0x00000001, 0x00070050, 0x0000001D, + 0x00002357, 0x00001B87, 0x0000410A, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F28, 0x000200F8, + 0x00004F28, 0x000900F5, 0x0000001D, 0x00002BAE, 0x00002357, 0x00004F58, 0x00004364, 0x0000215A, + 0x00002356, 0x00002038, 0x000900F5, 0x0000001D, 0x0000380F, 0x00004280, 0x00004F58, 0x00006299, + 0x0000215A, 0x0000391D, 0x00002038, 0x000900F5, 0x0000001D, 0x00003B88, 0x0000427F, 0x00004F58, + 0x00006298, 0x0000215A, 0x0000391C, 0x00002038, 0x000900F5, 0x0000001D, 0x000038BB, 0x0000427E, + 0x00004F58, 0x00006297, 0x0000215A, 0x0000391B, 0x00002038, 0x000200F9, 0x00005311, 0x000200F8, + 0x00005311, 0x000700F5, 0x0000001D, 0x00002BAF, 0x00002BAE, 0x00004F28, 0x00002BAD, 0x00003F62, + 0x000700F5, 0x0000001D, 0x00003810, 0x0000380F, 0x00004F28, 0x0000380E, 0x00003F62, 0x000700F5, + 0x0000001D, 0x00003296, 0x00003B88, 0x00004F28, 0x00003B85, 0x00003F62, 0x000700F5, 0x0000001D, + 0x0000367B, 0x000038BB, 0x00004F28, 0x000038BA, 0x00003F62, 0x00050081, 0x0000001D, 0x0000435A, + 0x00004359, 0x0000367B, 0x00050081, 0x0000001D, 0x00005B02, 0x00005B01, 0x00003296, 0x00050081, + 0x0000001D, 0x00001C28, 0x00001F92, 0x00003810, 0x00050081, 0x0000001D, 0x000025AA, 0x00005113, + 0x00002BAF, 0x00050080, 0x0000000B, 0x00003FF8, 0x00001FB2, 0x000037B2, 0x000300F7, 0x00005312, + 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B68, 0x000040BC, 0x000200F8, 0x000040BC, 0x000500AA, + 0x00000009, 0x00004AE1, 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F4C, 0x00000002, 0x000400FA, + 0x00004AE1, 0x0000262A, 0x00002F67, 0x000200F8, 0x00002F67, 0x00060041, 0x00000288, 0x00004BD5, + 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D4F, 0x00004BD5, 0x00050080, + 0x0000000B, 0x00002DD4, 0x00003FF8, 0x0000199B, 0x00060041, 0x00000288, 0x00001951, 0x00000CC7, + 0x00000A0B, 0x00002DD4, 0x0004003D, 0x0000000B, 0x00005E64, 0x00001951, 0x00050084, 0x0000000B, + 0x00001863, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000020AA, 0x00003FF8, 0x00001863, + 0x00060041, 0x00000288, 0x00003BD0, 0x00000CC7, 0x00000A0B, 0x000020AA, 0x0004003D, 0x0000000B, + 0x00005E65, 0x00003BD0, 0x00050084, 0x0000000B, 0x00001864, 0x00000A13, 0x0000199B, 0x00050080, + 0x0000000B, 0x000020AB, 0x00003FF8, 0x00001864, 0x00060041, 0x00000288, 0x000037F4, 0x00000CC7, + 0x00000A0B, 0x000020AB, 0x0004003D, 0x0000000B, 0x00004008, 0x000037F4, 0x00070050, 0x00000017, + 0x00005138, 0x00005D4F, 0x00005E64, 0x00005E65, 0x00004008, 0x000200F9, 0x00004F4C, 0x000200F8, + 0x0000262A, 0x00060041, 0x00000288, 0x0000554B, 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, + 0x0000000B, 0x00005D50, 0x0000554B, 0x00050080, 0x0000000B, 0x00002DD5, 0x00003FF8, 0x00000A0D, + 0x00060041, 0x00000288, 0x00001917, 0x00000CC7, 0x00000A0B, 0x00002DD5, 0x0004003D, 0x0000000B, + 0x00005C83, 0x00001917, 0x00050080, 0x0000000B, 0x00002DD6, 0x00003FF8, 0x00000A10, 0x00060041, + 0x00000288, 0x00001918, 0x00000CC7, 0x00000A0B, 0x00002DD6, 0x0004003D, 0x0000000B, 0x00005C84, + 0x00001918, 0x00050080, 0x0000000B, 0x00002DD7, 0x00003FF8, 0x00000A13, 0x00060041, 0x00000288, + 0x00006009, 0x00000CC7, 0x00000A0B, 0x00002DD7, 0x0004003D, 0x0000000B, 0x00004009, 0x00006009, + 0x00070050, 0x00000017, 0x00005139, 0x00005D50, 0x00005C83, 0x00005C84, 0x00004009, 0x000200F9, + 0x00004F4C, 0x000200F8, 0x00004F4C, 0x000700F5, 0x00000017, 0x00002AC2, 0x00005139, 0x0000262A, + 0x00005138, 0x00002F67, 0x000300F7, 0x00003F63, 0x00000000, 0x001300FB, 0x00002180, 0x00004BFE, + 0x00000000, 0x000038FC, 0x00000001, 0x000038FC, 0x00000002, 0x00001CC1, 0x0000000A, 0x00001CC1, + 0x00000003, 0x00001CC0, 0x0000000C, 0x00001CC0, 0x00000004, 0x00002001, 0x00000006, 0x00002039, + 0x000200F8, 0x00002039, 0x00050051, 0x0000000B, 0x00005F5C, 0x00002AC2, 0x00000000, 0x0006000C, + 0x00000013, 0x0000606D, 0x00000001, 0x0000003E, 0x00005F5C, 0x00050051, 0x0000000D, 0x00002786, + 0x0000606D, 0x00000000, 0x00050051, 0x0000000D, 0x00004458, 0x0000606D, 0x00000001, 0x00070050, + 0x0000001D, 0x0000391E, 0x00002786, 0x00004458, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x0000438C, 0x00002AC2, 0x00000001, 0x0006000C, 0x00000013, 0x0000467D, 0x00000001, 0x0000003E, + 0x0000438C, 0x00050051, 0x0000000D, 0x00002787, 0x0000467D, 0x00000000, 0x00050051, 0x0000000D, + 0x00004459, 0x0000467D, 0x00000001, 0x00070050, 0x0000001D, 0x0000391F, 0x00002787, 0x00004459, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x0000438D, 0x00002AC2, 0x00000002, 0x0006000C, + 0x00000013, 0x0000467E, 0x00000001, 0x0000003E, 0x0000438D, 0x00050051, 0x0000000D, 0x00002788, + 0x0000467E, 0x00000000, 0x00050051, 0x0000000D, 0x0000445A, 0x0000467E, 0x00000001, 0x00070050, + 0x0000001D, 0x00003920, 0x00002788, 0x0000445A, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x0000438E, 0x00002AC2, 0x00000003, 0x0006000C, 0x00000013, 0x0000467F, 0x00000001, 0x0000003E, + 0x0000438E, 0x00050051, 0x0000000D, 0x00002789, 0x0000467F, 0x00000000, 0x00050051, 0x0000000D, + 0x000050C4, 0x0000467F, 0x00000001, 0x00070050, 0x0000001D, 0x00002358, 0x00002789, 0x000050C4, + 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F63, 0x000200F8, 0x00002001, 0x00050051, 0x0000000B, + 0x00003091, 0x00002AC2, 0x00000000, 0x0004007C, 0x0000000C, 0x000058A0, 0x00003091, 0x00050050, + 0x00000012, 0x0000472F, 0x000058A0, 0x000058A0, 0x000500C4, 0x00000012, 0x000047B9, 0x0000472F, + 0x000007A7, 0x000500C3, 0x00000012, 0x00003423, 0x000047B9, 0x00000867, 0x0004006F, 0x00000013, + 0x00002ABB, 0x00003423, 0x0005008E, 0x00000013, 0x00004753, 0x00002ABB, 0x000007FE, 0x0007000C, + 0x00000013, 0x00005E12, 0x00000001, 0x00000028, 0x00000049, 0x00004753, 0x00050051, 0x0000000D, + 0x00005F16, 0x00005E12, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDD, 0x00005E12, 0x00000001, + 0x00070050, 0x0000001D, 0x00004127, 0x00005F16, 0x00003CDD, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x00004C4B, 0x00002AC2, 0x00000001, 0x0004007C, 0x0000000C, 0x00003EAA, 0x00004C4B, + 0x00050050, 0x00000012, 0x00004730, 0x00003EAA, 0x00003EAA, 0x000500C4, 0x00000012, 0x000047BA, + 0x00004730, 0x000007A7, 0x000500C3, 0x00000012, 0x00003424, 0x000047BA, 0x00000867, 0x0004006F, + 0x00000013, 0x00002ABC, 0x00003424, 0x0005008E, 0x00000013, 0x00004754, 0x00002ABC, 0x000007FE, + 0x0007000C, 0x00000013, 0x00005E13, 0x00000001, 0x00000028, 0x00000049, 0x00004754, 0x00050051, + 0x0000000D, 0x00005F17, 0x00005E13, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDE, 0x00005E13, + 0x00000001, 0x00070050, 0x0000001D, 0x00004128, 0x00005F17, 0x00003CDE, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x00004C4C, 0x00002AC2, 0x00000002, 0x0004007C, 0x0000000C, 0x00003EAB, + 0x00004C4C, 0x00050050, 0x00000012, 0x00004731, 0x00003EAB, 0x00003EAB, 0x000500C4, 0x00000012, + 0x000047BC, 0x00004731, 0x000007A7, 0x000500C3, 0x00000012, 0x00003425, 0x000047BC, 0x00000867, + 0x0004006F, 0x00000013, 0x00002ABD, 0x00003425, 0x0005008E, 0x00000013, 0x00004755, 0x00002ABD, + 0x000007FE, 0x0007000C, 0x00000013, 0x00005E14, 0x00000001, 0x00000028, 0x00000049, 0x00004755, + 0x00050051, 0x0000000D, 0x00005F18, 0x00005E14, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDF, + 0x00005E14, 0x00000001, 0x00070050, 0x0000001D, 0x00004129, 0x00005F18, 0x00003CDF, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C4D, 0x00002AC2, 0x00000003, 0x0004007C, 0x0000000C, + 0x00003EAC, 0x00004C4D, 0x00050050, 0x00000012, 0x00004732, 0x00003EAC, 0x00003EAC, 0x000500C4, + 0x00000012, 0x000047BD, 0x00004732, 0x000007A7, 0x000500C3, 0x00000012, 0x00003426, 0x000047BD, + 0x00000867, 0x0004006F, 0x00000013, 0x00002ABE, 0x00003426, 0x0005008E, 0x00000013, 0x00004756, + 0x00002ABE, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E15, 0x00000001, 0x00000028, 0x00000049, + 0x00004756, 0x00050051, 0x0000000D, 0x00005F19, 0x00005E15, 0x00000000, 0x00050051, 0x0000000D, + 0x0000494F, 0x00005E15, 0x00000001, 0x00070050, 0x0000001D, 0x00002359, 0x00005F19, 0x0000494F, + 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F63, 0x000200F8, 0x00001CC0, 0x00050051, 0x0000000B, + 0x000056C6, 0x00002AC2, 0x00000000, 0x00060050, 0x00000014, 0x00004F13, 0x000056C6, 0x000056C6, + 0x000056C6, 0x000500C2, 0x00000014, 0x00002B1C, 0x00004F13, 0x00000BB4, 0x000500C7, 0x00000014, + 0x00005DF2, 0x00002B1C, 0x00000105, 0x000500C7, 0x00000014, 0x000048B4, 0x00005DF2, 0x00000466, + 0x000500C2, 0x00000014, 0x00005B9C, 0x00005DF2, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D5, + 0x00005B9C, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C57, 0x00000001, 0x0000004B, 0x000048B4, + 0x0004007C, 0x00000014, 0x00002A21, 0x00002C57, 0x00050082, 0x00000014, 0x00001886, 0x00000B0C, + 0x00002A21, 0x00050080, 0x00000014, 0x0000221C, 0x00002A21, 0x00000938, 0x000600A9, 0x00000014, + 0x0000287B, 0x000040D5, 0x0000221C, 0x00005B9C, 0x000500C4, 0x00000014, 0x00005AE0, 0x000048B4, + 0x00001886, 0x000500C7, 0x00000014, 0x000049A6, 0x00005AE0, 0x00000466, 0x000600A9, 0x00000014, + 0x00002AC3, 0x000040D5, 0x000049A6, 0x000048B4, 0x00050080, 0x00000014, 0x0000600A, 0x0000287B, + 0x000003FA, 0x000500C4, 0x00000014, 0x00004F8B, 0x0000600A, 0x00000189, 0x000500C4, 0x00000014, + 0x00003FB2, 0x00002AC3, 0x0000008D, 0x000500C5, 0x00000014, 0x00005788, 0x00004F8B, 0x00003FB2, + 0x000500AA, 0x00000010, 0x0000360C, 0x00005DF2, 0x00000A12, 0x000600A9, 0x00000014, 0x0000424E, + 0x0000360C, 0x00000A12, 0x00005788, 0x0004007C, 0x00000018, 0x000029DB, 0x0000424E, 0x000500C2, + 0x0000000B, 0x00004BB0, 0x000056C6, 0x00000A64, 0x00040070, 0x0000000D, 0x0000481A, 0x00004BB0, + 0x00050085, 0x0000000D, 0x00003E2B, 0x0000481A, 0x00000149, 0x00050051, 0x0000000D, 0x000053CE, + 0x000029DB, 0x00000000, 0x00050051, 0x0000000D, 0x00002A61, 0x000029DB, 0x00000001, 0x00050051, + 0x0000000D, 0x00001EA2, 0x000029DB, 0x00000002, 0x00070050, 0x0000001D, 0x00003DE3, 0x000053CE, + 0x00002A61, 0x00001EA2, 0x00003E2B, 0x00050051, 0x0000000B, 0x000027FE, 0x00002AC2, 0x00000001, + 0x00060050, 0x00000014, 0x00003517, 0x000027FE, 0x000027FE, 0x000027FE, 0x000500C2, 0x00000014, + 0x00002B1D, 0x00003517, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF3, 0x00002B1D, 0x00000105, + 0x000500C7, 0x00000014, 0x000048B5, 0x00005DF3, 0x00000466, 0x000500C2, 0x00000014, 0x00005B9D, + 0x00005DF3, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D6, 0x00005B9D, 0x00000A12, 0x0006000C, + 0x00000016, 0x00002C58, 0x00000001, 0x0000004B, 0x000048B5, 0x0004007C, 0x00000014, 0x00002A22, + 0x00002C58, 0x00050082, 0x00000014, 0x00001887, 0x00000B0C, 0x00002A22, 0x00050080, 0x00000014, + 0x0000221D, 0x00002A22, 0x00000938, 0x000600A9, 0x00000014, 0x0000287C, 0x000040D6, 0x0000221D, + 0x00005B9D, 0x000500C4, 0x00000014, 0x00005AE1, 0x000048B5, 0x00001887, 0x000500C7, 0x00000014, + 0x000049A7, 0x00005AE1, 0x00000466, 0x000600A9, 0x00000014, 0x00002AC4, 0x000040D6, 0x000049A7, + 0x000048B5, 0x00050080, 0x00000014, 0x0000600B, 0x0000287C, 0x000003FA, 0x000500C4, 0x00000014, + 0x00004F8C, 0x0000600B, 0x00000189, 0x000500C4, 0x00000014, 0x00003FB3, 0x00002AC4, 0x0000008D, + 0x000500C5, 0x00000014, 0x00005789, 0x00004F8C, 0x00003FB3, 0x000500AA, 0x00000010, 0x0000360D, + 0x00005DF3, 0x00000A12, 0x000600A9, 0x00000014, 0x0000424F, 0x0000360D, 0x00000A12, 0x00005789, + 0x0004007C, 0x00000018, 0x000029DC, 0x0000424F, 0x000500C2, 0x0000000B, 0x00004BB1, 0x000027FE, + 0x00000A64, 0x00040070, 0x0000000D, 0x0000481B, 0x00004BB1, 0x00050085, 0x0000000D, 0x00003E2C, + 0x0000481B, 0x00000149, 0x00050051, 0x0000000D, 0x000053CF, 0x000029DC, 0x00000000, 0x00050051, + 0x0000000D, 0x00002A62, 0x000029DC, 0x00000001, 0x00050051, 0x0000000D, 0x00001EA3, 0x000029DC, + 0x00000002, 0x00070050, 0x0000001D, 0x00003DE4, 0x000053CF, 0x00002A62, 0x00001EA3, 0x00003E2C, + 0x00050051, 0x0000000B, 0x000027FF, 0x00002AC2, 0x00000002, 0x00060050, 0x00000014, 0x00003518, + 0x000027FF, 0x000027FF, 0x000027FF, 0x000500C2, 0x00000014, 0x00002B1E, 0x00003518, 0x00000BB4, + 0x000500C7, 0x00000014, 0x00005DF4, 0x00002B1E, 0x00000105, 0x000500C7, 0x00000014, 0x000048B6, + 0x00005DF4, 0x00000466, 0x000500C2, 0x00000014, 0x00005B9E, 0x00005DF4, 0x00000B0C, 0x000500AA, + 0x00000010, 0x000040D7, 0x00005B9E, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C59, 0x00000001, + 0x0000004B, 0x000048B6, 0x0004007C, 0x00000014, 0x00002A23, 0x00002C59, 0x00050082, 0x00000014, + 0x00001888, 0x00000B0C, 0x00002A23, 0x00050080, 0x00000014, 0x0000221E, 0x00002A23, 0x00000938, + 0x000600A9, 0x00000014, 0x0000287D, 0x000040D7, 0x0000221E, 0x00005B9E, 0x000500C4, 0x00000014, + 0x00005AE2, 0x000048B6, 0x00001888, 0x000500C7, 0x00000014, 0x000049A8, 0x00005AE2, 0x00000466, + 0x000600A9, 0x00000014, 0x00002AC5, 0x000040D7, 0x000049A8, 0x000048B6, 0x00050080, 0x00000014, + 0x0000600C, 0x0000287D, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F8D, 0x0000600C, 0x00000189, + 0x000500C4, 0x00000014, 0x00003FB4, 0x00002AC5, 0x0000008D, 0x000500C5, 0x00000014, 0x0000578A, + 0x00004F8D, 0x00003FB4, 0x000500AA, 0x00000010, 0x0000360E, 0x00005DF4, 0x00000A12, 0x000600A9, + 0x00000014, 0x00004250, 0x0000360E, 0x00000A12, 0x0000578A, 0x0004007C, 0x00000018, 0x000029DD, + 0x00004250, 0x000500C2, 0x0000000B, 0x00004BB2, 0x000027FF, 0x00000A64, 0x00040070, 0x0000000D, + 0x0000481C, 0x00004BB2, 0x00050085, 0x0000000D, 0x00003E2D, 0x0000481C, 0x00000149, 0x00050051, + 0x0000000D, 0x000053D0, 0x000029DD, 0x00000000, 0x00050051, 0x0000000D, 0x00002A63, 0x000029DD, + 0x00000001, 0x00050051, 0x0000000D, 0x00001EA4, 0x000029DD, 0x00000002, 0x00070050, 0x0000001D, + 0x00003DE5, 0x000053D0, 0x00002A63, 0x00001EA4, 0x00003E2D, 0x00050051, 0x0000000B, 0x00002800, + 0x00002AC2, 0x00000003, 0x00060050, 0x00000014, 0x00003519, 0x00002800, 0x00002800, 0x00002800, + 0x000500C2, 0x00000014, 0x00002B1F, 0x00003519, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF5, + 0x00002B1F, 0x00000105, 0x000500C7, 0x00000014, 0x000048B8, 0x00005DF5, 0x00000466, 0x000500C2, + 0x00000014, 0x00005B9F, 0x00005DF5, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D8, 0x00005B9F, + 0x00000A12, 0x0006000C, 0x00000016, 0x00002C5A, 0x00000001, 0x0000004B, 0x000048B8, 0x0004007C, + 0x00000014, 0x00002A24, 0x00002C5A, 0x00050082, 0x00000014, 0x00001889, 0x00000B0C, 0x00002A24, + 0x00050080, 0x00000014, 0x0000221F, 0x00002A24, 0x00000938, 0x000600A9, 0x00000014, 0x0000287E, + 0x000040D8, 0x0000221F, 0x00005B9F, 0x000500C4, 0x00000014, 0x00005AE3, 0x000048B8, 0x00001889, + 0x000500C7, 0x00000014, 0x000049A9, 0x00005AE3, 0x00000466, 0x000600A9, 0x00000014, 0x00002AC6, + 0x000040D8, 0x000049A9, 0x000048B8, 0x00050080, 0x00000014, 0x0000600D, 0x0000287E, 0x000003FA, + 0x000500C4, 0x00000014, 0x00004F8E, 0x0000600D, 0x00000189, 0x000500C4, 0x00000014, 0x00003FB5, + 0x00002AC6, 0x0000008D, 0x000500C5, 0x00000014, 0x0000578B, 0x00004F8E, 0x00003FB5, 0x000500AA, + 0x00000010, 0x0000360F, 0x00005DF5, 0x00000A12, 0x000600A9, 0x00000014, 0x00004251, 0x0000360F, + 0x00000A12, 0x0000578B, 0x0004007C, 0x00000018, 0x000029DE, 0x00004251, 0x000500C2, 0x0000000B, + 0x00004BB3, 0x00002800, 0x00000A64, 0x00040070, 0x0000000D, 0x0000481D, 0x00004BB3, 0x00050085, + 0x0000000D, 0x00003E2E, 0x0000481D, 0x00000149, 0x00050051, 0x0000000D, 0x000053D1, 0x000029DE, + 0x00000000, 0x00050051, 0x0000000D, 0x00002A64, 0x000029DE, 0x00000001, 0x00050051, 0x0000000D, + 0x00002B20, 0x000029DE, 0x00000002, 0x00070050, 0x0000001D, 0x0000235A, 0x000053D1, 0x00002A64, + 0x00002B20, 0x00003E2E, 0x000200F9, 0x00003F63, 0x000200F8, 0x00001CC1, 0x00050051, 0x0000000B, + 0x000056C7, 0x00002AC2, 0x00000000, 0x00070050, 0x00000017, 0x00004F14, 0x000056C7, 0x000056C7, + 0x000056C7, 0x000056C7, 0x000500C2, 0x00000017, 0x000024B0, 0x00004F14, 0x0000034D, 0x000500C7, + 0x00000017, 0x000049B7, 0x000024B0, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CC0, 0x000049B7, + 0x00050085, 0x0000001D, 0x00004139, 0x00003CC0, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CDB, + 0x00002AC2, 0x00000001, 0x00070050, 0x00000017, 0x00005156, 0x00005CDB, 0x00005CDB, 0x00005CDB, + 0x00005CDB, 0x000500C2, 0x00000017, 0x000024B1, 0x00005156, 0x0000034D, 0x000500C7, 0x00000017, + 0x000049B8, 0x000024B1, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CC1, 0x000049B8, 0x00050085, + 0x0000001D, 0x0000413A, 0x00003CC1, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CDC, 0x00002AC2, + 0x00000002, 0x00070050, 0x00000017, 0x00005157, 0x00005CDC, 0x00005CDC, 0x00005CDC, 0x00005CDC, + 0x000500C2, 0x00000017, 0x000024B2, 0x00005157, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B9, + 0x000024B2, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CC2, 0x000049B9, 0x00050085, 0x0000001D, + 0x0000413B, 0x00003CC2, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CDD, 0x00002AC2, 0x00000003, + 0x00070050, 0x00000017, 0x0000515C, 0x00005CDD, 0x00005CDD, 0x00005CDD, 0x00005CDD, 0x000500C2, + 0x00000017, 0x000024B3, 0x0000515C, 0x0000034D, 0x000500C7, 0x00000017, 0x000049BA, 0x000024B3, + 0x0000027B, 0x00040070, 0x0000001D, 0x00004932, 0x000049BA, 0x00050085, 0x0000001D, 0x000026A2, + 0x00004932, 0x00000AEE, 0x000200F9, 0x00003F63, 0x000200F8, 0x000038FC, 0x00050051, 0x0000000B, + 0x000056C8, 0x00002AC2, 0x00000000, 0x00070050, 0x00000017, 0x00004F15, 0x000056C8, 0x000056C8, + 0x000056C8, 0x000056C8, 0x000500C2, 0x00000017, 0x000024B4, 0x00004F15, 0x0000028D, 0x000500C7, + 0x00000017, 0x00004A62, 0x000024B4, 0x0000064B, 0x00040070, 0x0000001D, 0x000036AE, 0x00004A62, + 0x0005008E, 0x0000001D, 0x00004B2C, 0x000036AE, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A8, + 0x00002AC2, 0x00000001, 0x00070050, 0x00000017, 0x00006114, 0x000021A8, 0x000021A8, 0x000021A8, + 0x000021A8, 0x000500C2, 0x00000017, 0x000024B5, 0x00006114, 0x0000028D, 0x000500C7, 0x00000017, + 0x00004A63, 0x000024B5, 0x0000064B, 0x00040070, 0x0000001D, 0x000036AF, 0x00004A63, 0x0005008E, + 0x0000001D, 0x00004B2D, 0x000036AF, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A9, 0x00002AC2, + 0x00000002, 0x00070050, 0x00000017, 0x00006115, 0x000021A9, 0x000021A9, 0x000021A9, 0x000021A9, + 0x000500C2, 0x00000017, 0x000024B6, 0x00006115, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A64, + 0x000024B6, 0x0000064B, 0x00040070, 0x0000001D, 0x000036B0, 0x00004A64, 0x0005008E, 0x0000001D, + 0x00004B2E, 0x000036B0, 0x0000017A, 0x00050051, 0x0000000B, 0x000021AA, 0x00002AC2, 0x00000003, + 0x00070050, 0x00000017, 0x00006116, 0x000021AA, 0x000021AA, 0x000021AA, 0x000021AA, 0x000500C2, + 0x00000017, 0x000024B7, 0x00006116, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A65, 0x000024B7, + 0x0000064B, 0x00040070, 0x0000001D, 0x0000431D, 0x00004A65, 0x0005008E, 0x0000001D, 0x00003095, + 0x0000431D, 0x0000017A, 0x000200F9, 0x00003F63, 0x000200F8, 0x00004BFE, 0x00050051, 0x0000000B, + 0x00003096, 0x00002AC2, 0x00000000, 0x0004007C, 0x0000000D, 0x00004FF1, 0x00003096, 0x00050050, + 0x00000013, 0x0000433F, 0x00004FF1, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D99, 0x0000433F, + 0x0000433F, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056BA, + 0x00002AC2, 0x00000001, 0x0004007C, 0x0000000D, 0x00003F71, 0x000056BA, 0x00050050, 0x00000013, + 0x00004340, 0x00003F71, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D9A, 0x00004340, 0x00004340, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056BB, 0x00002AC2, + 0x00000002, 0x0004007C, 0x0000000D, 0x00003F72, 0x000056BB, 0x00050050, 0x00000013, 0x00004341, + 0x00003F72, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D9B, 0x00004341, 0x00004341, 0x00000000, + 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056BC, 0x00002AC2, 0x00000003, + 0x0004007C, 0x0000000D, 0x00003F73, 0x000056BC, 0x00050050, 0x00000013, 0x00004FB1, 0x00003F73, + 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3D, 0x00004FB1, 0x00004FB1, 0x00000000, 0x00000001, + 0x00000001, 0x00000001, 0x000200F9, 0x00003F63, 0x000200F8, 0x00003F63, 0x000F00F5, 0x0000001D, + 0x00002BB0, 0x00005A3D, 0x00004BFE, 0x00003095, 0x000038FC, 0x000026A2, 0x00001CC1, 0x0000235A, + 0x00001CC0, 0x00002359, 0x00002001, 0x00002358, 0x00002039, 0x000F00F5, 0x0000001D, 0x00003811, + 0x00002D9B, 0x00004BFE, 0x00004B2E, 0x000038FC, 0x0000413B, 0x00001CC1, 0x00003DE5, 0x00001CC0, + 0x00004129, 0x00002001, 0x00003920, 0x00002039, 0x000F00F5, 0x0000001D, 0x00003B89, 0x00002D9A, + 0x00004BFE, 0x00004B2D, 0x000038FC, 0x0000413A, 0x00001CC1, 0x00003DE4, 0x00001CC0, 0x00004128, + 0x00002001, 0x0000391F, 0x00002039, 0x000F00F5, 0x0000001D, 0x000038BC, 0x00002D99, 0x00004BFE, + 0x00004B2C, 0x000038FC, 0x00004139, 0x00001CC1, 0x00003DE3, 0x00001CC0, 0x00004127, 0x00002001, + 0x0000391E, 0x00002039, 0x000200F9, 0x00005312, 0x000200F8, 0x00003B68, 0x000500AA, 0x00000009, + 0x00005453, 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F29, 0x00000002, 0x000400FA, 0x00005453, + 0x0000262B, 0x00002F68, 0x000200F8, 0x00002F68, 0x00060041, 0x00000288, 0x00004BD6, 0x00000CC7, + 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D51, 0x00004BD6, 0x00050080, 0x0000000B, + 0x00002DD8, 0x00003FF8, 0x00000A0D, 0x00060041, 0x00000288, 0x00001919, 0x00000CC7, 0x00000A0B, + 0x00002DD8, 0x0004003D, 0x0000000B, 0x00005C85, 0x00001919, 0x00050080, 0x0000000B, 0x00002DD9, + 0x00003FF8, 0x0000199B, 0x00060041, 0x00000288, 0x0000191A, 0x00000CC7, 0x00000A0B, 0x00002DD9, + 0x0004003D, 0x0000000B, 0x00005C86, 0x0000191A, 0x00050080, 0x0000000B, 0x00002DDA, 0x00002DD9, + 0x00000A0D, 0x00060041, 0x00000288, 0x0000600E, 0x00000CC7, 0x00000A0B, 0x00002DDA, 0x0004003D, + 0x0000000B, 0x0000374F, 0x0000600E, 0x00070050, 0x00000017, 0x00004CDA, 0x00005D51, 0x00005C85, + 0x00005C86, 0x0000374F, 0x00050084, 0x0000000B, 0x0000429B, 0x00000A10, 0x0000199B, 0x00050080, + 0x0000000B, 0x000036B1, 0x00003FF8, 0x0000429B, 0x00060041, 0x00000288, 0x00003B8A, 0x00000CC7, + 0x00000A0B, 0x000036B1, 0x0004003D, 0x0000000B, 0x00005C87, 0x00003B8A, 0x00050080, 0x0000000B, + 0x00002DDB, 0x000036B1, 0x00000A0D, 0x00060041, 0x00000288, 0x00001952, 0x00000CC7, 0x00000A0B, + 0x00002DDB, 0x0004003D, 0x0000000B, 0x00005E66, 0x00001952, 0x00050084, 0x0000000B, 0x00001865, + 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020AC, 0x00003FF8, 0x00001865, 0x00060041, + 0x00000288, 0x00003B8B, 0x00000CC7, 0x00000A0B, 0x000020AC, 0x0004003D, 0x0000000B, 0x00005C88, + 0x00003B8B, 0x00050080, 0x0000000B, 0x00002DDC, 0x000020AC, 0x00000A0D, 0x00060041, 0x00000288, + 0x0000600F, 0x00000CC7, 0x00000A0B, 0x00002DDC, 0x0004003D, 0x0000000B, 0x0000400A, 0x0000600F, + 0x00070050, 0x00000017, 0x0000513A, 0x00005C87, 0x00005E66, 0x00005C88, 0x0000400A, 0x000200F9, + 0x00004F29, 0x000200F8, 0x0000262B, 0x00060041, 0x00000288, 0x0000554C, 0x00000CC7, 0x00000A0B, + 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D52, 0x0000554C, 0x00050080, 0x0000000B, 0x00002DDD, + 0x00003FF8, 0x00000A0D, 0x00060041, 0x00000288, 0x0000191B, 0x00000CC7, 0x00000A0B, 0x00002DDD, + 0x0004003D, 0x0000000B, 0x00005C89, 0x0000191B, 0x00050080, 0x0000000B, 0x00002DDE, 0x00003FF8, + 0x00000A10, 0x00060041, 0x00000288, 0x0000191C, 0x00000CC7, 0x00000A0B, 0x00002DDE, 0x0004003D, + 0x0000000B, 0x00005C8A, 0x0000191C, 0x00050080, 0x0000000B, 0x00002DDF, 0x00003FF8, 0x00000A13, + 0x00060041, 0x00000288, 0x00006010, 0x00000CC7, 0x00000A0B, 0x00002DDF, 0x0004003D, 0x0000000B, + 0x00003703, 0x00006010, 0x00070050, 0x00000017, 0x00004AE2, 0x00005D52, 0x00005C89, 0x00005C8A, + 0x00003703, 0x00050080, 0x0000000B, 0x000057E8, 0x00003FF8, 0x00000A16, 0x00060041, 0x00000288, + 0x0000604E, 0x00000CC7, 0x00000A0B, 0x000057E8, 0x0004003D, 0x0000000B, 0x00005C8B, 0x0000604E, + 0x00050080, 0x0000000B, 0x00002DE0, 0x00003FF8, 0x00000A19, 0x00060041, 0x00000288, 0x0000191D, + 0x00000CC7, 0x00000A0B, 0x00002DE0, 0x0004003D, 0x0000000B, 0x00005C8C, 0x0000191D, 0x00050080, + 0x0000000B, 0x00002DE1, 0x00003FF8, 0x00000A1C, 0x00060041, 0x00000288, 0x0000191E, 0x00000CC7, + 0x00000A0B, 0x00002DE1, 0x0004003D, 0x0000000B, 0x00005C8D, 0x0000191E, 0x00050080, 0x0000000B, + 0x00002DE2, 0x00003FF8, 0x00000A1F, 0x00060041, 0x00000288, 0x00006011, 0x00000CC7, 0x00000A0B, + 0x00002DE2, 0x0004003D, 0x0000000B, 0x0000400B, 0x00006011, 0x00070050, 0x00000017, 0x0000513B, + 0x00005C8B, 0x00005C8C, 0x00005C8D, 0x0000400B, 0x000200F9, 0x00004F29, 0x000200F8, 0x00004F29, + 0x000700F5, 0x00000017, 0x00002BD0, 0x0000513B, 0x0000262B, 0x0000513A, 0x00002F68, 0x000700F5, + 0x00000017, 0x00003723, 0x00004AE2, 0x0000262B, 0x00004CDA, 0x00002F68, 0x000300F7, 0x00004F2A, + 0x00000000, 0x000700FB, 0x00002180, 0x00004F59, 0x00000005, 0x0000215B, 0x00000007, 0x0000203A, + 0x000200F8, 0x0000203A, 0x00050051, 0x0000000B, 0x00005F5D, 0x00003723, 0x00000000, 0x0006000C, + 0x00000013, 0x0000606E, 0x00000001, 0x0000003E, 0x00005F5D, 0x00050051, 0x0000000D, 0x0000278A, + 0x0000606E, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC4, 0x0000606E, 0x00000001, 0x00050051, + 0x0000000B, 0x0000428D, 0x00003723, 0x00000001, 0x0006000C, 0x00000013, 0x00003D01, 0x00000001, + 0x0000003E, 0x0000428D, 0x00050051, 0x0000000D, 0x0000278B, 0x00003D01, 0x00000000, 0x00050051, + 0x0000000D, 0x0000445B, 0x00003D01, 0x00000001, 0x00070050, 0x0000001D, 0x00003921, 0x0000278A, + 0x00003EC4, 0x0000278B, 0x0000445B, 0x00050051, 0x0000000B, 0x0000438F, 0x00003723, 0x00000002, + 0x0006000C, 0x00000013, 0x00004680, 0x00000001, 0x0000003E, 0x0000438F, 0x00050051, 0x0000000D, + 0x0000278C, 0x00004680, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC5, 0x00004680, 0x00000001, + 0x00050051, 0x0000000B, 0x0000428E, 0x00003723, 0x00000003, 0x0006000C, 0x00000013, 0x00003D02, + 0x00000001, 0x0000003E, 0x0000428E, 0x00050051, 0x0000000D, 0x0000278D, 0x00003D02, 0x00000000, + 0x00050051, 0x0000000D, 0x0000445C, 0x00003D02, 0x00000001, 0x00070050, 0x0000001D, 0x00003922, + 0x0000278C, 0x00003EC5, 0x0000278D, 0x0000445C, 0x00050051, 0x0000000B, 0x00004390, 0x00002BD0, + 0x00000000, 0x0006000C, 0x00000013, 0x00004681, 0x00000001, 0x0000003E, 0x00004390, 0x00050051, + 0x0000000D, 0x0000278E, 0x00004681, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC6, 0x00004681, + 0x00000001, 0x00050051, 0x0000000B, 0x0000428F, 0x00002BD0, 0x00000001, 0x0006000C, 0x00000013, + 0x00003D03, 0x00000001, 0x0000003E, 0x0000428F, 0x00050051, 0x0000000D, 0x0000278F, 0x00003D03, + 0x00000000, 0x00050051, 0x0000000D, 0x0000445D, 0x00003D03, 0x00000001, 0x00070050, 0x0000001D, + 0x00003923, 0x0000278E, 0x00003EC6, 0x0000278F, 0x0000445D, 0x00050051, 0x0000000B, 0x00004391, + 0x00002BD0, 0x00000002, 0x0006000C, 0x00000013, 0x00004682, 0x00000001, 0x0000003E, 0x00004391, + 0x00050051, 0x0000000D, 0x00002790, 0x00004682, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC7, + 0x00004682, 0x00000001, 0x00050051, 0x0000000B, 0x00004290, 0x00002BD0, 0x00000003, 0x0006000C, + 0x00000013, 0x00003D04, 0x00000001, 0x0000003E, 0x00004290, 0x00050051, 0x0000000D, 0x00002791, + 0x00003D04, 0x00000000, 0x00050051, 0x0000000D, 0x000050C5, 0x00003D04, 0x00000001, 0x00070050, + 0x0000001D, 0x0000235B, 0x00002790, 0x00003EC7, 0x00002791, 0x000050C5, 0x000200F9, 0x00004F2A, + 0x000200F8, 0x0000215B, 0x0007004F, 0x00000011, 0x000025FE, 0x00003723, 0x00003723, 0x00000000, + 0x00000001, 0x0004007C, 0x00000012, 0x00005B3F, 0x000025FE, 0x0009004F, 0x0000001A, 0x000060DA, + 0x00005B3F, 0x00005B3F, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, + 0x000048B9, 0x000060DA, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D99, 0x000048B9, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002AC7, 0x00003D99, 0x0005008E, 0x0000001D, 0x00004733, 0x00002AC7, + 0x000007FE, 0x0007000C, 0x0000001D, 0x0000629A, 0x00000001, 0x00000028, 0x00000504, 0x00004733, + 0x0007004F, 0x00000011, 0x00003774, 0x00003723, 0x00003723, 0x00000002, 0x00000003, 0x0004007C, + 0x00000012, 0x000024C8, 0x00003774, 0x0009004F, 0x0000001A, 0x000060DB, 0x000024C8, 0x000024C8, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048BA, 0x000060DB, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D9A, 0x000048BA, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002AC8, 0x00003D9A, 0x0005008E, 0x0000001D, 0x00004734, 0x00002AC8, 0x000007FE, 0x0007000C, + 0x0000001D, 0x0000629B, 0x00000001, 0x00000028, 0x00000504, 0x00004734, 0x0007004F, 0x00000011, + 0x00003775, 0x00002BD0, 0x00002BD0, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000024C9, + 0x00003775, 0x0009004F, 0x0000001A, 0x000060DC, 0x000024C9, 0x000024C9, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048BB, 0x000060DC, 0x00000122, 0x000500C3, + 0x0000001A, 0x00003D9B, 0x000048BB, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AC9, 0x00003D9B, + 0x0005008E, 0x0000001D, 0x00004735, 0x00002AC9, 0x000007FE, 0x0007000C, 0x0000001D, 0x0000629C, + 0x00000001, 0x00000028, 0x00000504, 0x00004735, 0x0007004F, 0x00000011, 0x00003776, 0x00002BD0, + 0x00002BD0, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024CA, 0x00003776, 0x0009004F, + 0x0000001A, 0x000060DD, 0x000024CA, 0x000024CA, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C4, 0x0000001A, 0x000048BC, 0x000060DD, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D9C, + 0x000048BC, 0x00000302, 0x0004006F, 0x0000001D, 0x00002ACA, 0x00003D9C, 0x0005008E, 0x0000001D, + 0x000053D2, 0x00002ACA, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004365, 0x00000001, 0x00000028, + 0x00000504, 0x000053D2, 0x000200F9, 0x00004F2A, 0x000200F8, 0x00004F59, 0x0007004F, 0x00000011, + 0x0000262C, 0x00003723, 0x00003723, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x0000515D, + 0x0000262C, 0x00050051, 0x0000000D, 0x00001B88, 0x0000515D, 0x00000000, 0x00050051, 0x0000000D, + 0x00003473, 0x0000515D, 0x00000001, 0x00070050, 0x0000001D, 0x00004291, 0x00001B88, 0x00003473, + 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041E1, 0x00003723, 0x00003723, 0x00000002, + 0x00000003, 0x0004007C, 0x00000013, 0x00003766, 0x000041E1, 0x00050051, 0x0000000D, 0x00001B89, + 0x00003766, 0x00000000, 0x00050051, 0x0000000D, 0x00003474, 0x00003766, 0x00000001, 0x00070050, + 0x0000001D, 0x00004292, 0x00001B89, 0x00003474, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, + 0x000041E2, 0x00002BD0, 0x00002BD0, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x00003767, + 0x000041E2, 0x00050051, 0x0000000D, 0x00001B8A, 0x00003767, 0x00000000, 0x00050051, 0x0000000D, + 0x00003475, 0x00003767, 0x00000001, 0x00070050, 0x0000001D, 0x00004293, 0x00001B8A, 0x00003475, + 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041E3, 0x00002BD0, 0x00002BD0, 0x00000002, + 0x00000003, 0x0004007C, 0x00000013, 0x00003768, 0x000041E3, 0x00050051, 0x0000000D, 0x00001B8B, + 0x00003768, 0x00000000, 0x00050051, 0x0000000D, 0x0000410B, 0x00003768, 0x00000001, 0x00070050, + 0x0000001D, 0x0000235C, 0x00001B8B, 0x0000410B, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F2A, + 0x000200F8, 0x00004F2A, 0x000900F5, 0x0000001D, 0x00002BB1, 0x0000235C, 0x00004F59, 0x00004365, + 0x0000215B, 0x0000235B, 0x0000203A, 0x000900F5, 0x0000001D, 0x00003812, 0x00004293, 0x00004F59, + 0x0000629C, 0x0000215B, 0x00003923, 0x0000203A, 0x000900F5, 0x0000001D, 0x00003B8C, 0x00004292, + 0x00004F59, 0x0000629B, 0x0000215B, 0x00003922, 0x0000203A, 0x000900F5, 0x0000001D, 0x000038BD, + 0x00004291, 0x00004F59, 0x0000629A, 0x0000215B, 0x00003921, 0x0000203A, 0x000200F9, 0x00005312, + 0x000200F8, 0x00005312, 0x000700F5, 0x0000001D, 0x00002BB2, 0x00002BB1, 0x00004F2A, 0x00002BB0, + 0x00003F63, 0x000700F5, 0x0000001D, 0x00003813, 0x00003812, 0x00004F2A, 0x00003811, 0x00003F63, + 0x000700F5, 0x0000001D, 0x00003297, 0x00003B8C, 0x00004F2A, 0x00003B89, 0x00003F63, 0x000700F5, + 0x0000001D, 0x0000367C, 0x000038BD, 0x00004F2A, 0x000038BC, 0x00003F63, 0x00050081, 0x0000001D, + 0x0000435B, 0x0000435A, 0x0000367C, 0x00050081, 0x0000001D, 0x00005B03, 0x00005B02, 0x00003297, + 0x00050081, 0x0000001D, 0x00002523, 0x00001C28, 0x00003813, 0x00050081, 0x0000001D, 0x00001E77, + 0x000025AA, 0x00002BB2, 0x000200F9, 0x00005EC8, 0x000200F8, 0x00005EC8, 0x000700F5, 0x0000001D, + 0x00002BB3, 0x00005113, 0x00005310, 0x00001E77, 0x00005312, 0x000700F5, 0x0000001D, 0x00003814, + 0x00001F92, 0x00005310, 0x00002523, 0x00005312, 0x000700F5, 0x0000001D, 0x00003B31, 0x00005B01, + 0x00005310, 0x00005B03, 0x00005312, 0x000700F5, 0x0000001D, 0x00003B8D, 0x00004359, 0x00005310, + 0x0000435B, 0x00005312, 0x000700F5, 0x0000000D, 0x000038BE, 0x00005A1D, 0x00005310, 0x00002F3A, + 0x00005312, 0x000200F9, 0x00005313, 0x000200F8, 0x00005313, 0x000700F5, 0x0000001D, 0x00002BB4, + 0x00002BA9, 0x0000530F, 0x00002BB3, 0x00005EC8, 0x000700F5, 0x0000001D, 0x00003815, 0x0000380A, + 0x0000530F, 0x00003814, 0x00005EC8, 0x000700F5, 0x0000001D, 0x00003B32, 0x000035EC, 0x0000530F, + 0x00003B31, 0x00005EC8, 0x000700F5, 0x0000001D, 0x0000338C, 0x000020D3, 0x0000530F, 0x00003B8D, + 0x00005EC8, 0x000700F5, 0x0000000D, 0x00002EA8, 0x00002B2C, 0x0000530F, 0x000038BE, 0x00005EC8, + 0x0005008E, 0x0000001D, 0x00005A74, 0x0000338C, 0x00002EA8, 0x0005008E, 0x0000001D, 0x000019CC, + 0x00003B32, 0x00002EA8, 0x0005008E, 0x0000001D, 0x0000306F, 0x00003815, 0x00002EA8, 0x0005008E, + 0x0000001D, 0x00003432, 0x00002BB4, 0x00002EA8, 0x000300F7, 0x00003F64, 0x00000002, 0x000400FA, + 0x00001D59, 0x00002741, 0x00003F64, 0x000200F8, 0x00002741, 0x0009004F, 0x0000001D, 0x00003AEE, + 0x00005A74, 0x00005A74, 0x00000002, 0x00000001, 0x00000000, 0x00000003, 0x0009004F, 0x0000001D, + 0x00003A07, 0x000019CC, 0x000019CC, 0x00000002, 0x00000001, 0x00000000, 0x00000003, 0x0009004F, + 0x0000001D, 0x00001CE6, 0x0000306F, 0x0000306F, 0x00000002, 0x00000001, 0x00000000, 0x00000003, + 0x0009004F, 0x0000001D, 0x00003EEF, 0x00003432, 0x00003432, 0x00000002, 0x00000001, 0x00000000, + 0x00000003, 0x000200F9, 0x00003F64, 0x000200F8, 0x00003F64, 0x000700F5, 0x0000001D, 0x00002BB5, + 0x00003432, 0x00005313, 0x00003EEF, 0x00002741, 0x000700F5, 0x0000001D, 0x00003816, 0x0000306F, + 0x00005313, 0x00001CE6, 0x00002741, 0x000700F5, 0x0000001D, 0x00003B57, 0x000019CC, 0x00005313, + 0x00003A07, 0x00002741, 0x000700F5, 0x0000001D, 0x00003A49, 0x00005A74, 0x00005313, 0x00003AEE, + 0x00002741, 0x000300F7, 0x00004992, 0x00000000, 0x001900FB, 0x00005093, 0x00002002, 0x00000006, + 0x00004696, 0x0000000E, 0x00004696, 0x00000032, 0x00004696, 0x00000007, 0x000045EB, 0x00000036, + 0x000045EB, 0x00000010, 0x00001935, 0x00000037, 0x00001935, 0x00000011, 0x00001934, 0x00000038, + 0x00001934, 0x00000019, 0x00001933, 0x0000001F, 0x00002514, 0x000200F8, 0x00002514, 0x00050051, + 0x0000000D, 0x00003AAE, 0x00003A49, 0x00000000, 0x00050051, 0x0000000D, 0x000023ED, 0x00003A49, + 0x00000001, 0x00050050, 0x00000013, 0x00004B20, 0x00003AAE, 0x000023ED, 0x0006000C, 0x0000000B, + 0x00002171, 0x00000001, 0x0000003A, 0x00004B20, 0x00050051, 0x0000000D, 0x00005BBF, 0x00003B57, + 0x00000000, 0x00050051, 0x0000000D, 0x000039A7, 0x00003B57, 0x00000001, 0x00050050, 0x00000013, + 0x00004B21, 0x00005BBF, 0x000039A7, 0x0006000C, 0x0000000B, 0x00002172, 0x00000001, 0x0000003A, + 0x00004B21, 0x00050051, 0x0000000D, 0x00005BC0, 0x00003816, 0x00000000, 0x00050051, 0x0000000D, + 0x000039A8, 0x00003816, 0x00000001, 0x00050050, 0x00000013, 0x00004B22, 0x00005BC0, 0x000039A8, + 0x0006000C, 0x0000000B, 0x00002173, 0x00000001, 0x0000003A, 0x00004B22, 0x00050051, 0x0000000D, + 0x00005BC1, 0x00002BB5, 0x00000000, 0x00050051, 0x0000000D, 0x000039A9, 0x00002BB5, 0x00000001, + 0x00050050, 0x00000013, 0x00004B0D, 0x00005BC1, 0x000039A9, 0x0006000C, 0x0000000B, 0x00002E96, + 0x00000001, 0x0000003A, 0x00004B0D, 0x00070050, 0x00000017, 0x0000612F, 0x00002171, 0x00002172, + 0x00002173, 0x00002E96, 0x000200F9, 0x00004992, 0x000200F8, 0x00001933, 0x0007004F, 0x00000013, + 0x0000227A, 0x00003A49, 0x00003A49, 0x00000000, 0x00000001, 0x0008000C, 0x00000013, 0x00005CB1, + 0x00000001, 0x0000002B, 0x0000227A, 0x0000071F, 0x00000300, 0x0005008E, 0x00000013, 0x000025B4, + 0x00005CB1, 0x0000022D, 0x00050081, 0x00000013, 0x00002E66, 0x000025B4, 0x0000061E, 0x0004006D, + 0x00000011, 0x00001DD7, 0x00002E66, 0x00050051, 0x0000000B, 0x000021FC, 0x00001DD7, 0x00000000, + 0x00050051, 0x0000000B, 0x00002FDB, 0x00001DD7, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D03, + 0x00002FDB, 0x00000A3B, 0x000500C5, 0x0000000B, 0x00004143, 0x000021FC, 0x00002D03, 0x0007004F, + 0x00000013, 0x0000235D, 0x00003B57, 0x00003B57, 0x00000000, 0x00000001, 0x0008000C, 0x00000013, + 0x000046BF, 0x00000001, 0x0000002B, 0x0000235D, 0x0000071F, 0x00000300, 0x0005008E, 0x00000013, + 0x000025B5, 0x000046BF, 0x0000022D, 0x00050081, 0x00000013, 0x00002E67, 0x000025B5, 0x0000061E, + 0x0004006D, 0x00000011, 0x00001DD9, 0x00002E67, 0x00050051, 0x0000000B, 0x000021FD, 0x00001DD9, + 0x00000000, 0x00050051, 0x0000000B, 0x00002FDC, 0x00001DD9, 0x00000001, 0x000500C4, 0x0000000B, + 0x00002D04, 0x00002FDC, 0x00000A3B, 0x000500C5, 0x0000000B, 0x00004144, 0x000021FD, 0x00002D04, + 0x0007004F, 0x00000013, 0x0000235E, 0x00003816, 0x00003816, 0x00000000, 0x00000001, 0x0008000C, + 0x00000013, 0x000046C0, 0x00000001, 0x0000002B, 0x0000235E, 0x0000071F, 0x00000300, 0x0005008E, + 0x00000013, 0x000025B6, 0x000046C0, 0x0000022D, 0x00050081, 0x00000013, 0x00002E69, 0x000025B6, + 0x0000061E, 0x0004006D, 0x00000011, 0x00001DDA, 0x00002E69, 0x00050051, 0x0000000B, 0x000021FE, + 0x00001DDA, 0x00000000, 0x00050051, 0x0000000B, 0x00002FDD, 0x00001DDA, 0x00000001, 0x000500C4, + 0x0000000B, 0x00002D05, 0x00002FDD, 0x00000A3B, 0x000500C5, 0x0000000B, 0x00004145, 0x000021FE, + 0x00002D05, 0x0007004F, 0x00000013, 0x0000235F, 0x00002BB5, 0x00002BB5, 0x00000000, 0x00000001, + 0x0008000C, 0x00000013, 0x000046C1, 0x00000001, 0x0000002B, 0x0000235F, 0x0000071F, 0x00000300, + 0x0005008E, 0x00000013, 0x000025B7, 0x000046C1, 0x0000022D, 0x00050081, 0x00000013, 0x00002E6A, + 0x000025B7, 0x0000061E, 0x0004006D, 0x00000011, 0x00001DDB, 0x00002E6A, 0x00050051, 0x0000000B, + 0x000021FF, 0x00001DDB, 0x00000000, 0x00050051, 0x0000000B, 0x00002FDE, 0x00001DDB, 0x00000001, + 0x000500C4, 0x0000000B, 0x00002D16, 0x00002FDE, 0x00000A3B, 0x000500C5, 0x0000000B, 0x00005202, + 0x000021FF, 0x00002D16, 0x00070050, 0x00000017, 0x000053DD, 0x00004143, 0x00004144, 0x00004145, + 0x00005202, 0x000200F9, 0x00004992, 0x000200F8, 0x00001934, 0x0008004F, 0x00000018, 0x000021CF, + 0x00003A49, 0x00003A49, 0x00000000, 0x00000001, 0x00000002, 0x0008000C, 0x00000018, 0x00001847, + 0x00000001, 0x0000002B, 0x000021CF, 0x00000A2D, 0x00000A18, 0x00050085, 0x00000018, 0x00001BC1, + 0x00001847, 0x0000000E, 0x00050081, 0x00000018, 0x00001F1A, 0x00001BC1, 0x000003AB, 0x0004006D, + 0x00000014, 0x00002752, 0x00001F1A, 0x00050051, 0x0000000B, 0x00002200, 0x00002752, 0x00000000, + 0x00050051, 0x0000000B, 0x00002FDF, 0x00002752, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D29, + 0x00002FDF, 0x00000A29, 0x000500C5, 0x0000000B, 0x00004D66, 0x00002200, 0x00002D29, 0x00050051, + 0x0000000B, 0x000053E4, 0x00002752, 0x00000002, 0x000500C4, 0x0000000B, 0x0000214A, 0x000053E4, + 0x00000A4A, 0x000500C5, 0x0000000B, 0x00004146, 0x00004D66, 0x0000214A, 0x0008004F, 0x00000018, + 0x000022A2, 0x00003B57, 0x00003B57, 0x00000000, 0x00000001, 0x00000002, 0x0008000C, 0x00000018, + 0x00004CD4, 0x00000001, 0x0000002B, 0x000022A2, 0x00000A2D, 0x00000A18, 0x00050085, 0x00000018, + 0x00001BC2, 0x00004CD4, 0x0000000E, 0x00050081, 0x00000018, 0x00001F1B, 0x00001BC2, 0x000003AB, + 0x0004006D, 0x00000014, 0x00002753, 0x00001F1B, 0x00050051, 0x0000000B, 0x00002201, 0x00002753, + 0x00000000, 0x00050051, 0x0000000B, 0x00002FE0, 0x00002753, 0x00000001, 0x000500C4, 0x0000000B, + 0x00002D2A, 0x00002FE0, 0x00000A29, 0x000500C5, 0x0000000B, 0x00004D67, 0x00002201, 0x00002D2A, + 0x00050051, 0x0000000B, 0x000053E5, 0x00002753, 0x00000002, 0x000500C4, 0x0000000B, 0x0000214B, + 0x000053E5, 0x00000A4A, 0x000500C5, 0x0000000B, 0x00004147, 0x00004D67, 0x0000214B, 0x0008004F, + 0x00000018, 0x000022A3, 0x00003816, 0x00003816, 0x00000000, 0x00000001, 0x00000002, 0x0008000C, + 0x00000018, 0x00004CD5, 0x00000001, 0x0000002B, 0x000022A3, 0x00000A2D, 0x00000A18, 0x00050085, + 0x00000018, 0x00001BC3, 0x00004CD5, 0x0000000E, 0x00050081, 0x00000018, 0x00001F1C, 0x00001BC3, + 0x000003AB, 0x0004006D, 0x00000014, 0x00002754, 0x00001F1C, 0x00050051, 0x0000000B, 0x00002202, + 0x00002754, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE1, 0x00002754, 0x00000001, 0x000500C4, + 0x0000000B, 0x00002D2B, 0x00002FE1, 0x00000A29, 0x000500C5, 0x0000000B, 0x00004D68, 0x00002202, + 0x00002D2B, 0x00050051, 0x0000000B, 0x000053E6, 0x00002754, 0x00000002, 0x000500C4, 0x0000000B, + 0x0000214C, 0x000053E6, 0x00000A4A, 0x000500C5, 0x0000000B, 0x00004148, 0x00004D68, 0x0000214C, + 0x0008004F, 0x00000018, 0x000022A4, 0x00002BB5, 0x00002BB5, 0x00000000, 0x00000001, 0x00000002, + 0x0008000C, 0x00000018, 0x00004CDB, 0x00000001, 0x0000002B, 0x000022A4, 0x00000A2D, 0x00000A18, + 0x00050085, 0x00000018, 0x00001BC4, 0x00004CDB, 0x0000000E, 0x00050081, 0x00000018, 0x00001F1D, + 0x00001BC4, 0x000003AB, 0x0004006D, 0x00000014, 0x00002755, 0x00001F1D, 0x00050051, 0x0000000B, + 0x00002203, 0x00002755, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE2, 0x00002755, 0x00000001, + 0x000500C4, 0x0000000B, 0x00002D2C, 0x00002FE2, 0x00000A29, 0x000500C5, 0x0000000B, 0x00004D69, + 0x00002203, 0x00002D2C, 0x00050051, 0x0000000B, 0x000053E7, 0x00002755, 0x00000002, 0x000500C4, + 0x0000000B, 0x0000215D, 0x000053E7, 0x00000A4A, 0x000500C5, 0x0000000B, 0x00005203, 0x00004D69, + 0x0000215D, 0x00070050, 0x00000017, 0x000053DE, 0x00004146, 0x00004147, 0x00004148, 0x00005203, + 0x000200F9, 0x00004992, 0x000200F8, 0x00001935, 0x0008004F, 0x00000018, 0x000021D0, 0x00003A49, + 0x00003A49, 0x00000000, 0x00000001, 0x00000002, 0x0008000C, 0x00000018, 0x00001848, 0x00000001, + 0x0000002B, 0x000021D0, 0x00000A2D, 0x00000A18, 0x00050085, 0x00000018, 0x00001BC5, 0x00001848, + 0x000008E3, 0x00050081, 0x00000018, 0x00001F1E, 0x00001BC5, 0x000003AB, 0x0004006D, 0x00000014, + 0x00002756, 0x00001F1E, 0x00050051, 0x0000000B, 0x00002204, 0x00002756, 0x00000000, 0x00050051, + 0x0000000B, 0x00002FE3, 0x00002756, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D2D, 0x00002FE3, + 0x00000A2C, 0x000500C5, 0x0000000B, 0x00004D6A, 0x00002204, 0x00002D2D, 0x00050051, 0x0000000B, + 0x000053E8, 0x00002756, 0x00000002, 0x000500C4, 0x0000000B, 0x0000214D, 0x000053E8, 0x00000A4D, + 0x000500C5, 0x0000000B, 0x00004149, 0x00004D6A, 0x0000214D, 0x0008004F, 0x00000018, 0x000022A5, + 0x00003B57, 0x00003B57, 0x00000000, 0x00000001, 0x00000002, 0x0008000C, 0x00000018, 0x00004CDC, + 0x00000001, 0x0000002B, 0x000022A5, 0x00000A2D, 0x00000A18, 0x00050085, 0x00000018, 0x00001BC6, + 0x00004CDC, 0x000008E3, 0x00050081, 0x00000018, 0x00001F1F, 0x00001BC6, 0x000003AB, 0x0004006D, + 0x00000014, 0x00002757, 0x00001F1F, 0x00050051, 0x0000000B, 0x00002205, 0x00002757, 0x00000000, + 0x00050051, 0x0000000B, 0x00002FE4, 0x00002757, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D2E, + 0x00002FE4, 0x00000A2C, 0x000500C5, 0x0000000B, 0x00004D6B, 0x00002205, 0x00002D2E, 0x00050051, + 0x0000000B, 0x000053E9, 0x00002757, 0x00000002, 0x000500C4, 0x0000000B, 0x0000214E, 0x000053E9, + 0x00000A4D, 0x000500C5, 0x0000000B, 0x0000414A, 0x00004D6B, 0x0000214E, 0x0008004F, 0x00000018, + 0x000022A6, 0x00003816, 0x00003816, 0x00000000, 0x00000001, 0x00000002, 0x0008000C, 0x00000018, + 0x00004CDD, 0x00000001, 0x0000002B, 0x000022A6, 0x00000A2D, 0x00000A18, 0x00050085, 0x00000018, + 0x00001BC7, 0x00004CDD, 0x000008E3, 0x00050081, 0x00000018, 0x00001F20, 0x00001BC7, 0x000003AB, + 0x0004006D, 0x00000014, 0x00002758, 0x00001F20, 0x00050051, 0x0000000B, 0x00002206, 0x00002758, + 0x00000000, 0x00050051, 0x0000000B, 0x00002FE5, 0x00002758, 0x00000001, 0x000500C4, 0x0000000B, + 0x00002D2F, 0x00002FE5, 0x00000A2C, 0x000500C5, 0x0000000B, 0x00004D6C, 0x00002206, 0x00002D2F, + 0x00050051, 0x0000000B, 0x000053EA, 0x00002758, 0x00000002, 0x000500C4, 0x0000000B, 0x0000214F, + 0x000053EA, 0x00000A4D, 0x000500C5, 0x0000000B, 0x0000414B, 0x00004D6C, 0x0000214F, 0x0008004F, + 0x00000018, 0x000022A8, 0x00002BB5, 0x00002BB5, 0x00000000, 0x00000001, 0x00000002, 0x0008000C, + 0x00000018, 0x00004CDE, 0x00000001, 0x0000002B, 0x000022A8, 0x00000A2D, 0x00000A18, 0x00050085, + 0x00000018, 0x00001BC8, 0x00004CDE, 0x000008E3, 0x00050081, 0x00000018, 0x00001F21, 0x00001BC8, + 0x000003AB, 0x0004006D, 0x00000014, 0x00002759, 0x00001F21, 0x00050051, 0x0000000B, 0x00002207, + 0x00002759, 0x00000000, 0x00050051, 0x0000000B, 0x00002FE6, 0x00002759, 0x00000001, 0x000500C4, + 0x0000000B, 0x00002D30, 0x00002FE6, 0x00000A2C, 0x000500C5, 0x0000000B, 0x00004D6D, 0x00002207, + 0x00002D30, 0x00050051, 0x0000000B, 0x000053EB, 0x00002759, 0x00000002, 0x000500C4, 0x0000000B, + 0x0000215E, 0x000053EB, 0x00000A4D, 0x000500C5, 0x0000000B, 0x00005204, 0x00004D6D, 0x0000215E, + 0x00070050, 0x00000017, 0x000053DF, 0x00004149, 0x0000414A, 0x0000414B, 0x00005204, 0x000200F9, + 0x00004992, 0x000200F8, 0x000045EB, 0x0008000C, 0x0000001D, 0x000022A9, 0x00000001, 0x0000002B, + 0x00003A49, 0x00000B7A, 0x00000505, 0x00050085, 0x0000001D, 0x00004580, 0x000022A9, 0x00000158, + 0x00050081, 0x0000001D, 0x00001F22, 0x00004580, 0x00000145, 0x0004006D, 0x00000017, 0x0000275A, + 0x00001F22, 0x00050051, 0x0000000B, 0x00002208, 0x0000275A, 0x00000000, 0x00050051, 0x0000000B, + 0x00002FE7, 0x0000275A, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D31, 0x00002FE7, 0x00000A29, + 0x000500C5, 0x0000000B, 0x00004D6E, 0x00002208, 0x00002D31, 0x00050051, 0x0000000B, 0x000053EC, + 0x0000275A, 0x00000002, 0x000500C4, 0x0000000B, 0x00002170, 0x000053EC, 0x00000A47, 0x000500C5, + 0x0000000B, 0x00004D6F, 0x00004D6E, 0x00002170, 0x00050051, 0x0000000B, 0x000053ED, 0x0000275A, + 0x00000003, 0x000500C4, 0x0000000B, 0x00001C7C, 0x000053ED, 0x00000A65, 0x000500C5, 0x0000000B, + 0x0000237C, 0x00004D6F, 0x00001C7C, 0x0008000C, 0x0000001D, 0x00002377, 0x00000001, 0x0000002B, + 0x00003B57, 0x00000B7A, 0x00000505, 0x00050085, 0x0000001D, 0x000060DE, 0x00002377, 0x00000158, + 0x00050081, 0x0000001D, 0x00001F23, 0x000060DE, 0x00000145, 0x0004006D, 0x00000017, 0x0000275B, + 0x00001F23, 0x00050051, 0x0000000B, 0x00002209, 0x0000275B, 0x00000000, 0x00050051, 0x0000000B, + 0x00002FE8, 0x0000275B, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D32, 0x00002FE8, 0x00000A29, + 0x000500C5, 0x0000000B, 0x00004D70, 0x00002209, 0x00002D32, 0x00050051, 0x0000000B, 0x000053EE, + 0x0000275B, 0x00000002, 0x000500C4, 0x0000000B, 0x00002174, 0x000053EE, 0x00000A47, 0x000500C5, + 0x0000000B, 0x00004D71, 0x00004D70, 0x00002174, 0x00050051, 0x0000000B, 0x000053EF, 0x0000275B, + 0x00000003, 0x000500C4, 0x0000000B, 0x00001C7D, 0x000053EF, 0x00000A65, 0x000500C5, 0x0000000B, + 0x0000237D, 0x00004D71, 0x00001C7D, 0x0008000C, 0x0000001D, 0x00002378, 0x00000001, 0x0000002B, + 0x00003816, 0x00000B7A, 0x00000505, 0x00050085, 0x0000001D, 0x000060DF, 0x00002378, 0x00000158, + 0x00050081, 0x0000001D, 0x00001F24, 0x000060DF, 0x00000145, 0x0004006D, 0x00000017, 0x0000275C, + 0x00001F24, 0x00050051, 0x0000000B, 0x0000220A, 0x0000275C, 0x00000000, 0x00050051, 0x0000000B, + 0x00002FE9, 0x0000275C, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D33, 0x00002FE9, 0x00000A29, + 0x000500C5, 0x0000000B, 0x00004D72, 0x0000220A, 0x00002D33, 0x00050051, 0x0000000B, 0x000053F0, + 0x0000275C, 0x00000002, 0x000500C4, 0x0000000B, 0x00002175, 0x000053F0, 0x00000A47, 0x000500C5, + 0x0000000B, 0x00004D73, 0x00004D72, 0x00002175, 0x00050051, 0x0000000B, 0x000053F1, 0x0000275C, + 0x00000003, 0x000500C4, 0x0000000B, 0x00001C7E, 0x000053F1, 0x00000A65, 0x000500C5, 0x0000000B, + 0x0000237E, 0x00004D73, 0x00001C7E, 0x0008000C, 0x0000001D, 0x00002379, 0x00000001, 0x0000002B, + 0x00002BB5, 0x00000B7A, 0x00000505, 0x00050085, 0x0000001D, 0x000060E0, 0x00002379, 0x00000158, + 0x00050081, 0x0000001D, 0x00001F25, 0x000060E0, 0x00000145, 0x0004006D, 0x00000017, 0x0000275D, + 0x00001F25, 0x00050051, 0x0000000B, 0x0000220B, 0x0000275D, 0x00000000, 0x00050051, 0x0000000B, + 0x00002FEA, 0x0000275D, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D34, 0x00002FEA, 0x00000A29, + 0x000500C5, 0x0000000B, 0x00004D74, 0x0000220B, 0x00002D34, 0x00050051, 0x0000000B, 0x000053F2, + 0x0000275D, 0x00000002, 0x000500C4, 0x0000000B, 0x00002176, 0x000053F2, 0x00000A47, 0x000500C5, + 0x0000000B, 0x00004D75, 0x00004D74, 0x00002176, 0x00050051, 0x0000000B, 0x000053F3, 0x0000275D, + 0x00000003, 0x000500C4, 0x0000000B, 0x0000215F, 0x000053F3, 0x00000A65, 0x000500C5, 0x0000000B, + 0x00005205, 0x00004D75, 0x0000215F, 0x00070050, 0x00000017, 0x000053E0, 0x0000237C, 0x0000237D, + 0x0000237E, 0x00005205, 0x000200F9, 0x00004992, 0x000200F8, 0x00004696, 0x0008000C, 0x0000001D, + 0x00001C8F, 0x00000001, 0x0000002B, 0x00003A49, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, + 0x00004F73, 0x00001C8F, 0x00000540, 0x00050081, 0x0000001D, 0x00002E6B, 0x00004F73, 0x00000145, + 0x0004006D, 0x00000017, 0x00001DDC, 0x00002E6B, 0x00050051, 0x0000000B, 0x0000220C, 0x00001DDC, + 0x00000000, 0x00050051, 0x0000000B, 0x00002FEB, 0x00001DDC, 0x00000001, 0x000500C4, 0x0000000B, + 0x00002D35, 0x00002FEB, 0x00000A23, 0x000500C5, 0x0000000B, 0x00004D76, 0x0000220C, 0x00002D35, + 0x00050051, 0x0000000B, 0x000053F4, 0x00001DDC, 0x00000002, 0x000500C4, 0x0000000B, 0x00002177, + 0x000053F4, 0x00000A3B, 0x000500C5, 0x0000000B, 0x00004D77, 0x00004D76, 0x00002177, 0x00050051, + 0x0000000B, 0x000053F5, 0x00001DDC, 0x00000003, 0x000500C4, 0x0000000B, 0x00001C7F, 0x000053F5, + 0x00000A53, 0x000500C5, 0x0000000B, 0x00002427, 0x00004D77, 0x00001C7F, 0x0008000C, 0x0000001D, + 0x00001D62, 0x00000001, 0x0000002B, 0x00003B57, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, + 0x00002048, 0x00001D62, 0x00000540, 0x00050081, 0x0000001D, 0x00002E6C, 0x00002048, 0x00000145, + 0x0004006D, 0x00000017, 0x00001DDD, 0x00002E6C, 0x00050051, 0x0000000B, 0x0000220D, 0x00001DDD, + 0x00000000, 0x00050051, 0x0000000B, 0x00002FEC, 0x00001DDD, 0x00000001, 0x000500C4, 0x0000000B, + 0x00002D36, 0x00002FEC, 0x00000A23, 0x000500C5, 0x0000000B, 0x00004D78, 0x0000220D, 0x00002D36, + 0x00050051, 0x0000000B, 0x000053F6, 0x00001DDD, 0x00000002, 0x000500C4, 0x0000000B, 0x00002178, + 0x000053F6, 0x00000A3B, 0x000500C5, 0x0000000B, 0x00004D79, 0x00004D78, 0x00002178, 0x00050051, + 0x0000000B, 0x000053F7, 0x00001DDD, 0x00000003, 0x000500C4, 0x0000000B, 0x00001C80, 0x000053F7, + 0x00000A53, 0x000500C5, 0x0000000B, 0x00002428, 0x00004D79, 0x00001C80, 0x0008000C, 0x0000001D, + 0x00001D63, 0x00000001, 0x0000002B, 0x00003816, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, + 0x00002049, 0x00001D63, 0x00000540, 0x00050081, 0x0000001D, 0x00002E6D, 0x00002049, 0x00000145, + 0x0004006D, 0x00000017, 0x00001DDE, 0x00002E6D, 0x00050051, 0x0000000B, 0x0000220E, 0x00001DDE, + 0x00000000, 0x00050051, 0x0000000B, 0x00002FED, 0x00001DDE, 0x00000001, 0x000500C4, 0x0000000B, + 0x00002D37, 0x00002FED, 0x00000A23, 0x000500C5, 0x0000000B, 0x00004D7A, 0x0000220E, 0x00002D37, + 0x00050051, 0x0000000B, 0x000053F8, 0x00001DDE, 0x00000002, 0x000500C4, 0x0000000B, 0x00002179, + 0x000053F8, 0x00000A3B, 0x000500C5, 0x0000000B, 0x00004D7B, 0x00004D7A, 0x00002179, 0x00050051, + 0x0000000B, 0x000053F9, 0x00001DDE, 0x00000003, 0x000500C4, 0x0000000B, 0x00001C81, 0x000053F9, + 0x00000A53, 0x000500C5, 0x0000000B, 0x00002429, 0x00004D7B, 0x00001C81, 0x0008000C, 0x0000001D, + 0x00001D64, 0x00000001, 0x0000002B, 0x00002BB5, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, + 0x0000204A, 0x00001D64, 0x00000540, 0x00050081, 0x0000001D, 0x00002E6E, 0x0000204A, 0x00000145, + 0x0004006D, 0x00000017, 0x00001DDF, 0x00002E6E, 0x00050051, 0x0000000B, 0x0000220F, 0x00001DDF, + 0x00000000, 0x00050051, 0x0000000B, 0x00002FEE, 0x00001DDF, 0x00000001, 0x000500C4, 0x0000000B, + 0x00002D38, 0x00002FEE, 0x00000A23, 0x000500C5, 0x0000000B, 0x00004D7C, 0x0000220F, 0x00002D38, + 0x00050051, 0x0000000B, 0x000053FA, 0x00001DDF, 0x00000002, 0x000500C4, 0x0000000B, 0x0000217A, + 0x000053FA, 0x00000A3B, 0x000500C5, 0x0000000B, 0x00004D7D, 0x00004D7C, 0x0000217A, 0x00050051, + 0x0000000B, 0x000053FB, 0x00001DDF, 0x00000003, 0x000500C4, 0x0000000B, 0x00002160, 0x000053FB, + 0x00000A53, 0x000500C5, 0x0000000B, 0x00005206, 0x00004D7D, 0x00002160, 0x00070050, 0x00000017, + 0x000053E1, 0x00002427, 0x00002428, 0x00002429, 0x00005206, 0x000200F9, 0x00004992, 0x000200F8, + 0x00002002, 0x00050051, 0x0000000D, 0x0000309E, 0x00003A49, 0x00000000, 0x0004007C, 0x0000000B, + 0x00005298, 0x0000309E, 0x00050051, 0x0000000D, 0x00004F4D, 0x00003B57, 0x00000000, 0x0004007C, + 0x0000000B, 0x0000451D, 0x00004F4D, 0x00050051, 0x0000000D, 0x00004F4E, 0x00003816, 0x00000000, + 0x0004007C, 0x0000000B, 0x0000451E, 0x00004F4E, 0x00050051, 0x0000000D, 0x00004F38, 0x00002BB5, + 0x00000000, 0x0004007C, 0x0000000B, 0x00004F16, 0x00004F38, 0x00070050, 0x00000017, 0x00002738, + 0x00005298, 0x0000451D, 0x0000451E, 0x00004F16, 0x000200F9, 0x00004992, 0x000200F8, 0x00004992, + 0x001100F5, 0x00000017, 0x00005E7C, 0x00002738, 0x00002002, 0x000053E1, 0x00004696, 0x000053E0, + 0x000045EB, 0x000053DF, 0x00001935, 0x000053DE, 0x00001934, 0x000053DD, 0x00001933, 0x0000612F, + 0x00002514, 0x000500AA, 0x00000009, 0x000060B1, 0x00001DD8, 0x00000A0A, 0x000300F7, 0x000033DC, + 0x00000000, 0x000400FA, 0x000060B1, 0x00002CBB, 0x000033DC, 0x000200F8, 0x00002CBB, 0x00050051, + 0x0000000B, 0x00005E67, 0x00004AB4, 0x00000000, 0x000500AB, 0x00000009, 0x000057C6, 0x00005E67, + 0x00000A0A, 0x000200F9, 0x000033DC, 0x000200F8, 0x000033DC, 0x000700F5, 0x00000009, 0x00002ACB, + 0x000060B1, 0x00004992, 0x000057C6, 0x00002CBB, 0x000300F7, 0x00004CC1, 0x00000002, 0x000400FA, + 0x00002ACB, 0x00002CF4, 0x00004CC1, 0x000200F8, 0x00002CF4, 0x00050051, 0x0000000B, 0x00005C2F, + 0x00004AB4, 0x00000000, 0x000500AE, 0x00000009, 0x000043C2, 0x00005C2F, 0x00000A10, 0x000300F7, + 0x00004945, 0x00000000, 0x000400FA, 0x000043C2, 0x00003E05, 0x00004945, 0x000200F8, 0x00003E05, + 0x000500AE, 0x00000009, 0x00005FD4, 0x00005C2F, 0x00000A13, 0x000300F7, 0x00004944, 0x00000000, + 0x000400FA, 0x00005FD4, 0x00002620, 0x00004944, 0x000200F8, 0x00002620, 0x00050051, 0x0000000B, + 0x00005002, 0x00005E7C, 0x00000003, 0x00060052, 0x00000017, 0x000037FF, 0x00005002, 0x00005E7C, + 0x00000002, 0x000200F9, 0x00004944, 0x000200F8, 0x00004944, 0x000700F5, 0x00000017, 0x000043E3, + 0x00005E7C, 0x00003E05, 0x000037FF, 0x00002620, 0x00050051, 0x0000000B, 0x00001B5A, 0x000043E3, + 0x00000002, 0x00060052, 0x00000017, 0x00003B28, 0x00001B5A, 0x000043E3, 0x00000001, 0x000200F9, + 0x00004945, 0x000200F8, 0x00004945, 0x000700F5, 0x00000017, 0x000043E4, 0x00005E7C, 0x00002CF4, + 0x00003B28, 0x00004944, 0x00050051, 0x0000000B, 0x00001B5B, 0x000043E4, 0x00000001, 0x00060052, + 0x00000017, 0x00003B29, 0x00001B5B, 0x000043E4, 0x00000000, 0x000200F9, 0x00004CC1, 0x000200F8, + 0x00004CC1, 0x000700F5, 0x00000017, 0x0000240D, 0x00005E7C, 0x000033DC, 0x00003B29, 0x00004945, + 0x00050080, 0x00000011, 0x00004BCB, 0x00002EF9, 0x000059EC, 0x00050051, 0x0000000B, 0x000033BC, + 0x00004BCB, 0x00000000, 0x00050051, 0x0000000B, 0x00002553, 0x00004BCB, 0x00000001, 0x000500C2, + 0x0000000B, 0x00002B2D, 0x000033BC, 0x00000A10, 0x00050050, 0x00000011, 0x00001E98, 0x00002B2D, + 0x00002553, 0x00050086, 0x00000011, 0x00006158, 0x00001E98, 0x00005C31, 0x00050051, 0x0000000B, + 0x0000366C, 0x00006158, 0x00000000, 0x000500C4, 0x0000000B, 0x00004D3A, 0x0000366C, 0x00000A10, + 0x00050051, 0x0000000B, 0x00005EBB, 0x00006158, 0x00000001, 0x00060050, 0x00000014, 0x000053D3, + 0x00004D3A, 0x00005EBB, 0x00005F72, 0x000300F7, 0x00005341, 0x00000002, 0x000400FA, 0x0000500F, + 0x000056C9, 0x00002ACC, 0x000200F8, 0x00002ACC, 0x0007004F, 0x00000011, 0x00001CAB, 0x000053D3, + 0x000053D3, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000059CF, 0x00001CAB, 0x00050051, + 0x0000000C, 0x0000191F, 0x000059CF, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x0000191F, + 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000059CF, 0x00000001, 0x000500C3, 0x0000000C, + 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00003DA7, 0x00000A19, + 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, + 0x000018AA, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, + 0x00004A8E, 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002ACD, 0x0000191F, 0x00000A20, + 0x000500C7, 0x0000000C, 0x00003138, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454D, + 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002ACD, 0x0000454D, 0x000500C4, + 0x0000000C, 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, + 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, + 0x00003C4B, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, + 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4B, 0x00003397, 0x000500C7, 0x0000000C, 0x000047BE, + 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544A, 0x000047BE, 0x00000A17, 0x00050080, + 0x0000000C, 0x00004157, 0x00004D30, 0x0000544A, 0x000500C7, 0x0000000C, 0x00005022, 0x00004157, + 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, + 0x00050080, 0x0000000C, 0x00004158, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004AE3, + 0x00004157, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544B, 0x00004AE3, 0x00000A11, 0x00050080, + 0x0000000C, 0x0000414C, 0x00004158, 0x0000544B, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, + 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, + 0x00001EEC, 0x0000191F, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, + 0x000500C7, 0x0000000C, 0x00005454, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544C, + 0x00005454, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4C, 0x0000414C, 0x0000544C, 0x000500C7, + 0x0000000C, 0x00002E06, 0x00004157, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4C, + 0x00002E06, 0x0004007C, 0x0000000B, 0x0000566F, 0x0000394F, 0x000200F9, 0x00005341, 0x000200F8, + 0x000056C9, 0x0004007C, 0x00000016, 0x000019AD, 0x000053D3, 0x00050051, 0x0000000C, 0x000042C2, + 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FE, 0x000042C2, 0x00000A17, 0x00050051, + 0x0000000C, 0x00002748, 0x000019AD, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, + 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00006273, 0x00000A16, 0x0004007C, 0x0000000C, + 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005321, 0x0000405D, 0x000018AB, 0x00050080, + 0x0000000C, 0x00003B27, 0x000024FE, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00003DA7, + 0x00000A19, 0x0004007C, 0x0000000C, 0x00003097, 0x00002348, 0x00050084, 0x0000000C, 0x0000287F, + 0x00003B27, 0x00003097, 0x00050051, 0x0000000C, 0x00006242, 0x000019AD, 0x00000000, 0x000500C3, + 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, + 0x0000287F, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A22, 0x000500C7, 0x0000000C, + 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, + 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, + 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454E, 0x000500C4, 0x0000000C, 0x00001B8C, 0x0000434B, + 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B8C, 0x00000A1D, 0x000500C3, 0x0000000C, + 0x00002220, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002220, 0x0000405D, + 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, + 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, + 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004AE4, 0x000034BD, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544D, 0x00004AE4, 0x00000A0E, 0x00050080, 0x0000000C, + 0x00003C4D, 0x00005A0C, 0x0000544D, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, + 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, + 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, + 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047BF, 0x00002748, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544E, 0x000047BF, 0x00000A22, 0x00050080, 0x0000000C, + 0x00004159, 0x0000285C, 0x0000544E, 0x000500C7, 0x0000000C, 0x00004AE5, 0x000042C2, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544F, 0x00004AE5, 0x00000A17, 0x00050080, 0x0000000C, 0x0000415A, + 0x00004159, 0x0000544F, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4D, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x0000415A, + 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, + 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4D, 0x00000A05, 0x00050080, 0x0000000C, 0x00002ACE, + 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002ACE, 0x00000A11, 0x000500C7, + 0x0000000C, 0x00005AB2, 0x0000415A, 0x0000040B, 0x00050080, 0x0000000C, 0x00002ACF, 0x00005B33, + 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002ACF, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005559, 0x0000415A, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, + 0x0004007C, 0x0000000B, 0x00005670, 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, 0x00005341, + 0x000700F5, 0x0000000B, 0x000024FC, 0x00005670, 0x000056C9, 0x0000566F, 0x00002ACC, 0x00050084, + 0x00000011, 0x00003FB6, 0x00006158, 0x00005C31, 0x00050082, 0x00000011, 0x00003F85, 0x00001E98, + 0x00003FB6, 0x00050051, 0x0000000B, 0x0000448F, 0x00005C31, 0x00000001, 0x00050084, 0x0000000B, + 0x00005C50, 0x0000229A, 0x0000448F, 0x00050084, 0x0000000B, 0x00003CA0, 0x000024FC, 0x00005C50, + 0x00050051, 0x0000000B, 0x00003ED4, 0x00003F85, 0x00000000, 0x00050084, 0x0000000B, 0x00003E12, + 0x00003ED4, 0x0000448F, 0x00050051, 0x0000000B, 0x00001AE7, 0x00003F85, 0x00000001, 0x00050080, + 0x0000000B, 0x00002B25, 0x00003E12, 0x00001AE7, 0x000500C4, 0x0000000B, 0x0000609D, 0x00002B25, + 0x00000A10, 0x000500C7, 0x0000000B, 0x00005AB3, 0x000033BC, 0x00000A13, 0x00050080, 0x0000000B, + 0x00002557, 0x0000609D, 0x00005AB3, 0x000500C4, 0x0000000B, 0x00004593, 0x00002557, 0x00000A10, + 0x00050080, 0x0000000B, 0x0000204B, 0x00003CA0, 0x00004593, 0x000500C2, 0x0000000B, 0x00002015, + 0x0000204B, 0x00000A16, 0x000500AA, 0x00000009, 0x00002EEA, 0x00004ADC, 0x00000A0D, 0x000500AA, + 0x00000009, 0x00005776, 0x00004ADC, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x00002EEA, + 0x00005776, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, + 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x0000240D, 0x000009CE, 0x000500C4, + 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x0000240D, + 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, + 0x00003FF9, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, + 0x00000017, 0x0000587A, 0x0000240D, 0x00005341, 0x00003FF9, 0x00002957, 0x000500AA, 0x00000009, + 0x00004CB6, 0x00004ADC, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005776, 0x00004CB6, + 0x000300F7, 0x00002C98, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x00002C98, 0x000200F8, + 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x0000587A, 0x000002ED, 0x000500C2, 0x00000017, + 0x00003BE7, 0x0000587A, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, + 0x000200F9, 0x00002C98, 0x000200F8, 0x00002C98, 0x000700F5, 0x00000017, 0x00004D37, 0x0000587A, + 0x00003463, 0x000029E8, 0x00002B38, 0x00060041, 0x00000294, 0x00001F75, 0x00001592, 0x00000A0B, + 0x00002015, 0x0003003E, 0x00001F75, 0x00004D37, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, + 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_full_64bpp_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_full_64bpp_cs.h new file mode 100644 index 0000000..6038ecc --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_full_64bpp_cs.h @@ -0,0 +1,4138 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25271 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_runtimearr_uint ArrayStride 4 + OpDecorate %_struct_1948 BufferBlock + OpMemberDecorate %_struct_1948 0 NonWritable + OpMemberDecorate %_struct_1948 0 Offset 0 + OpDecorate %3271 NonWritable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %_struct_1036 Block + OpMemberDecorate %_struct_1036 0 Offset 0 + OpMemberDecorate %_struct_1036 1 Offset 4 + OpMemberDecorate %_struct_1036 2 Offset 8 + OpMemberDecorate %_struct_1036 3 Offset 12 + OpMemberDecorate %_struct_1036 4 Offset 16 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonReadable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %5522 NonReadable + OpDecorate %5522 Binding 0 + OpDecorate %5522 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %v4uint = OpTypeVector %uint 4 + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 + %v4float = OpTypeVector %float 4 + %bool = OpTypeBool + %v3int = OpTypeVector %int 3 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_4 = OpConstant %uint 4 +%float_65535 = OpConstant %float 65535 + %float_0_5 = OpConstant %float 0.5 + %int_16 = OpConstant %int 16 + %uint_0 = OpConstant %uint 0 + %uint_24 = OpConstant %uint 24 + %653 = OpConstantComposite %v4uint %uint_0 %uint_8 %uint_16 %uint_24 + %uint_255 = OpConstant %uint 255 +%float_0_00392156886 = OpConstant %float 0.00392156886 + %uint_10 = OpConstant %uint 10 + %uint_20 = OpConstant %uint 20 + %uint_30 = OpConstant %uint 30 + %845 = OpConstantComposite %v4uint %uint_0 %uint_10 %uint_20 %uint_30 + %uint_1023 = OpConstant %uint 1023 + %635 = OpConstantComposite %v4uint %uint_1023 %uint_1023 %uint_1023 %uint_3 +%float_0_000977517106 = OpConstant %float 0.000977517106 +%float_0_333333343 = OpConstant %float 0.333333343 + %2798 = OpConstantComposite %v4float %float_0_000977517106 %float_0_000977517106 %float_0_000977517106 %float_0_333333343 + %2996 = OpConstantComposite %v3uint %uint_0 %uint_10 %uint_20 + %uint_127 = OpConstant %uint 127 + %uint_7 = OpConstant %uint 7 + %v3bool = OpTypeVector %bool 3 + %uint_124 = OpConstant %uint 124 + %uint_23 = OpConstant %uint 23 + %v3float = OpTypeVector %float 3 + %float_n1 = OpConstant %float -1 + %int_0 = OpConstant %int 0 + %1959 = OpConstantComposite %v2int %int_16 %int_0 +%float_0_000976592302 = OpConstant %float 0.000976592302 + %v4int = OpTypeVector %int 4 + %290 = OpConstantComposite %v4int %int_16 %int_0 %int_16 %int_0 + %1837 = OpConstantComposite %v2uint %uint_2 %uint_1 + %v2bool = OpTypeVector %bool 2 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %uint_80 = OpConstant %uint 80 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_6 = OpConstant %uint 6 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_runtimearr_uint = OpTypeRuntimeArray %uint +%_struct_1948 = OpTypeStruct %_runtimearr_uint +%_ptr_Uniform__struct_1948 = OpTypePointer Uniform %_struct_1948 + %3271 = OpVariable %_ptr_Uniform__struct_1948 Uniform +%_ptr_Uniform_uint = OpTypePointer Uniform %uint +%_struct_1036 = OpTypeStruct %uint %uint %uint %uint %uint +%_ptr_PushConstant__struct_1036 = OpTypePointer PushConstant %_struct_1036 + %3305 = OpVariable %_ptr_PushConstant__struct_1036 PushConstant +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_15 = OpConstant %uint 15 + %uint_28 = OpConstant %uint 28 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 + %int_10 = OpConstant %int 10 + %uint_63 = OpConstant %uint 63 + %int_26 = OpConstant %int 26 + %int_23 = OpConstant %int 23 +%uint_16777216 = OpConstant %uint 16777216 + %2275 = OpConstantComposite %v2uint %uint_20 %uint_24 + %false = OpConstantFalse %bool +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %1825 = OpConstantComposite %v2uint %uint_2 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %5522 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %1284 = OpConstantComposite %v4float %float_n1 %float_n1 %float_n1 %float_n1 + %770 = OpConstantComposite %v4int %int_16 %int_16 %int_16 %int_16 + %1611 = OpConstantComposite %v4uint %uint_255 %uint_255 %uint_255 %uint_255 + %261 = OpConstantComposite %v3uint %uint_1023 %uint_1023 %uint_1023 + %1126 = OpConstantComposite %v3uint %uint_127 %uint_127 %uint_127 + %2828 = OpConstantComposite %v3uint %uint_7 %uint_7 %uint_7 + %2578 = OpConstantComposite %v3uint %uint_0 %uint_0 %uint_0 + %1018 = OpConstantComposite %v3uint %uint_124 %uint_124 %uint_124 + %393 = OpConstantComposite %v3uint %uint_23 %uint_23 %uint_23 + %141 = OpConstantComposite %v3uint %uint_16 %uint_16 %uint_16 + %73 = OpConstantComposite %v2float %float_n1 %float_n1 + %2151 = OpConstantComposite %v2int %int_16 %int_16 + %2938 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 + %1285 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 + %325 = OpConstantComposite %v4float %float_0_5 %float_0_5 %float_0_5 %float_0_5 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 +%int_1065353216 = OpConstant %int 1065353216 + %uint_1280 = OpConstant %uint 1280 +%uint_2621440 = OpConstant %uint 2621440 +%uint_4294967290 = OpConstant %uint 4294967290 + %2360 = OpConstantComposite %v3uint %uint_4294967290 %uint_4294967290 %uint_4294967290 + %uint_81 = OpConstant %uint 81 + %uint_82 = OpConstant %uint 82 + %uint_83 = OpConstant %uint 83 + %uint_84 = OpConstant %uint 84 + %uint_85 = OpConstant %uint 85 + %uint_86 = OpConstant %uint 86 + %uint_87 = OpConstant %uint 87 + %float_0_25 = OpConstant %float 0.25 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %19978 = OpShiftRightLogical %uint %15627 %uint_10 + %8574 = OpBitwiseAnd %uint %19978 %uint_3 + %21002 = OpShiftRightLogical %uint %15627 %uint_13 + %8575 = OpBitwiseAnd %uint %21002 %uint_2047 + %21003 = OpShiftRightLogical %uint %15627 %uint_24 + %8576 = OpBitwiseAnd %uint %21003 %uint_15 + %18836 = OpShiftRightLogical %uint %15627 %uint_28 + %9130 = OpBitwiseAnd %uint %18836 %uint_1 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9576 = OpShiftRightLogical %v2uint %8871 %1855 + %23379 = OpBitwiseAnd %v2uint %9576 %1954 + %16207 = OpShiftLeftLogical %v2uint %23379 %1870 + %23019 = OpIMul %v2uint %16207 %1828 + %12819 = OpShiftRightLogical %uint %20824 %uint_5 + %16204 = OpBitwiseAnd %uint %12819 %uint_2047 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %24236 = OpLoad %uint %18732 + %22701 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %20919 = OpLoad %uint %22701 + %19164 = OpBitwiseAnd %uint %24236 %uint_7 + %21999 = OpBitwiseAnd %uint %24236 %uint_8 + %20495 = OpINotEqual %bool %21999 %uint_0 + %10307 = OpShiftRightLogical %uint %24236 %uint_4 + %24434 = OpBitwiseAnd %uint %10307 %uint_7 + %19672 = OpShiftRightLogical %uint %24236 %uint_7 + %20627 = OpBitwiseAnd %uint %19672 %uint_63 + %22920 = OpBitcast %int %24236 + %13711 = OpShiftLeftLogical %int %22920 %int_10 + %20636 = OpShiftRightArithmetic %int %13711 %int_26 + %18178 = OpShiftLeftLogical %int %20636 %int_23 + %7462 = OpIAdd %int %18178 %int_1065353216 + %11052 = OpBitcast %float %7462 + %22649 = OpBitwiseAnd %uint %24236 %uint_16777216 + %7513 = OpINotEqual %bool %22649 %uint_0 + %8003 = OpBitwiseAnd %uint %20919 %uint_1023 + %15783 = OpShiftLeftLogical %uint %8003 %uint_5 + %22591 = OpShiftRightLogical %uint %20919 %uint_10 + %19390 = OpBitwiseAnd %uint %22591 %uint_1023 + %25203 = OpShiftLeftLogical %uint %19390 %uint_5 + %10422 = OpCompositeConstruct %v2uint %20919 %20919 + %10385 = OpShiftRightLogical %v2uint %10422 %2275 + %23380 = OpBitwiseAnd %v2uint %10385 %2122 + %16208 = OpShiftLeftLogical %v2uint %23380 %1870 + %23020 = OpIMul %v2uint %16208 %1828 + %12820 = OpShiftRightLogical %uint %20919 %uint_28 + %16205 = OpBitwiseAnd %uint %12820 %uint_7 + %18656 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_4 + %25270 = OpLoad %uint %18656 + %14159 = OpLoad %v3uint %gl_GlobalInvocationID + %12672 = OpVectorShuffle %v2uint %14159 %14159 0 1 + %12025 = OpShiftLeftLogical %v2uint %12672 %1825 + %7640 = OpCompositeExtract %uint %12025 0 + %11658 = OpShiftLeftLogical %uint %16204 %uint_3 + %15379 = OpUGreaterThanEqual %bool %7640 %11658 + OpSelectionMerge %12755 DontFlatten + OpBranchConditional %15379 %21992 %12755 + %21992 = OpLabel + OpBranch %19578 + %12755 = OpLabel + %7340 = OpCompositeExtract %uint %12025 1 + %7992 = OpExtInst %uint %1 UMax %7340 %uint_0 + %20975 = OpCompositeConstruct %v2uint %7640 %7992 + %21036 = OpIAdd %v2uint %20975 %23019 + %16075 = OpULessThanEqual %bool %16205 %uint_3 + OpSelectionMerge %23776 None + OpBranchConditional %16075 %10990 %15087 + %15087 = OpLabel + %13566 = OpIEqual %bool %16205 %uint_5 + %8438 = OpSelect %uint %13566 %uint_2 %uint_0 + OpBranch %23776 + %10990 = OpLabel + OpBranch %23776 + %23776 = OpLabel + %19300 = OpPhi %uint %16205 %10990 %8438 %15087 + %16830 = OpCompositeConstruct %v2uint %8574 %8574 + %11801 = OpUGreaterThanEqual %v2bool %16830 %1837 + %19381 = OpSelect %v2uint %11801 %1828 %1807 + %10986 = OpShiftLeftLogical %v2uint %21036 %19381 + %24669 = OpCompositeConstruct %v2uint %19300 %19300 + %9093 = OpShiftRightLogical %v2uint %24669 %1816 + %15084 = OpBitwiseAnd %v2uint %9093 %1828 + %10197 = OpIAdd %v2uint %10986 %15084 + %8548 = OpCompositeConstruct %v2uint %9130 %uint_0 + %9802 = OpShiftRightLogical %v2uint %2719 %8548 + %10146 = OpUDiv %v2uint %10197 %9802 + %20390 = OpCompositeExtract %uint %10146 1 + %11046 = OpIMul %uint %20390 %20561 + %24665 = OpCompositeExtract %uint %10146 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %8575 %21536 + %23345 = OpIMul %v2uint %10146 %9802 + %11892 = OpISub %v2uint %10197 %23345 + %8053 = OpIMul %uint %8742 %uint_1280 + %24263 = OpCompositeExtract %uint %11892 1 + %23526 = OpCompositeExtract %uint %9802 0 + %22886 = OpIMul %uint %24263 %23526 + %6886 = OpCompositeExtract %uint %11892 0 + %9696 = OpIAdd %uint %22886 %6886 + %18116 = OpShiftLeftLogical %uint %9696 %9130 + %18201 = OpIAdd %uint %8053 %18116 + %23256 = OpUMod %uint %18201 %uint_2621440 + %13153 = OpUGreaterThanEqual %bool %8574 %uint_2 + %24735 = OpSelect %uint %13153 %uint_1 %uint_0 + %20074 = OpIAdd %uint %9130 %24735 + %6555 = OpShiftLeftLogical %uint %uint_1 %20074 + %23279 = OpINotEqual %bool %9130 %uint_0 + OpSelectionMerge %21263 DontFlatten + OpBranchConditional %23279 %15205 %16569 + %16569 = OpLabel + %19162 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20297 DontFlatten + OpBranchConditional %19162 %9761 %12129 + %12129 = OpLabel + %19407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %23256 + %23875 = OpLoad %uint %19407 + %11687 = OpIAdd %uint %23256 %6555 + %6475 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11687 + %24155 = OpLoad %uint %6475 + %6234 = OpIMul %uint %uint_2 %6555 + %8353 = OpIAdd %uint %23256 %6234 + %15309 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8353 + %24156 = OpLoad %uint %15309 + %6235 = OpIMul %uint %uint_3 %6555 + %8354 = OpIAdd %uint %23256 %6235 + %14321 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8354 + %16379 = OpLoad %uint %14321 + %20780 = OpCompositeConstruct %v4uint %23875 %24155 %24156 %16379 + OpBranch %20297 + %9761 = OpLabel + %21829 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %23256 + %23876 = OpLoad %uint %21829 + %11688 = OpIAdd %uint %23256 %uint_1 + %6399 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11688 + %23650 = OpLoad %uint %6399 + %11689 = OpIAdd %uint %23256 %uint_2 + %6400 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11689 + %23651 = OpLoad %uint %6400 + %11690 = OpIAdd %uint %23256 %uint_3 + %24558 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11690 + %16380 = OpLoad %uint %24558 + %20781 = OpCompositeConstruct %v4uint %23876 %23650 %23651 %16380 + OpBranch %20297 + %20297 = OpLabel + %10943 = OpPhi %v4uint %20781 %9761 %20780 %12129 + OpSelectionMerge %16224 None + OpSwitch %8576 %19451 0 %14585 1 %14585 2 %7355 10 %7355 3 %7354 12 %7354 4 %8190 6 %8243 + %8243 = OpLabel + %24406 = OpCompositeExtract %uint %10943 0 + %24679 = OpExtInst %v2float %1 UnpackHalf2x16 %24406 + %10082 = OpCompositeExtract %float %24679 0 + %17478 = OpCompositeExtract %float %24679 1 + %14604 = OpCompositeConstruct %v4float %10082 %17478 %float_0 %float_0 + %17274 = OpCompositeExtract %uint %10943 1 + %18027 = OpExtInst %v2float %1 UnpackHalf2x16 %17274 + %10083 = OpCompositeExtract %float %18027 0 + %17479 = OpCompositeExtract %float %18027 1 + %14605 = OpCompositeConstruct %v4float %10083 %17479 %float_0 %float_0 + %17275 = OpCompositeExtract %uint %10943 2 + %18028 = OpExtInst %v2float %1 UnpackHalf2x16 %17275 + %10084 = OpCompositeExtract %float %18028 0 + %17480 = OpCompositeExtract %float %18028 1 + %14606 = OpCompositeConstruct %v4float %10084 %17480 %float_0 %float_0 + %17276 = OpCompositeExtract %uint %10943 3 + %18029 = OpExtInst %v2float %1 UnpackHalf2x16 %17276 + %10085 = OpCompositeExtract %float %18029 0 + %20670 = OpCompositeExtract %float %18029 1 + %9033 = OpCompositeConstruct %v4float %10085 %20670 %float_0 %float_0 + OpBranch %16224 + %8190 = OpLabel + %12427 = OpCompositeExtract %uint %10943 0 + %22685 = OpBitcast %int %12427 + %18202 = OpCompositeConstruct %v2int %22685 %22685 + %18349 = OpShiftLeftLogical %v2int %18202 %1959 + %13335 = OpShiftRightArithmetic %v2int %18349 %2151 + %10903 = OpConvertSToF %v2float %13335 + %18247 = OpVectorTimesScalar %v2float %10903 %float_0_000976592302 + %24070 = OpExtInst %v2float %1 FMax %73 %18247 + %24330 = OpCompositeExtract %float %24070 0 + %15572 = OpCompositeExtract %float %24070 1 + %16670 = OpCompositeConstruct %v4float %24330 %15572 %float_0 %float_0 + %19522 = OpCompositeExtract %uint %10943 1 + %16033 = OpBitcast %int %19522 + %18203 = OpCompositeConstruct %v2int %16033 %16033 + %18350 = OpShiftLeftLogical %v2int %18203 %1959 + %13336 = OpShiftRightArithmetic %v2int %18350 %2151 + %10904 = OpConvertSToF %v2float %13336 + %18248 = OpVectorTimesScalar %v2float %10904 %float_0_000976592302 + %24071 = OpExtInst %v2float %1 FMax %73 %18248 + %24331 = OpCompositeExtract %float %24071 0 + %15573 = OpCompositeExtract %float %24071 1 + %16671 = OpCompositeConstruct %v4float %24331 %15573 %float_0 %float_0 + %19523 = OpCompositeExtract %uint %10943 2 + %16034 = OpBitcast %int %19523 + %18204 = OpCompositeConstruct %v2int %16034 %16034 + %18351 = OpShiftLeftLogical %v2int %18204 %1959 + %13337 = OpShiftRightArithmetic %v2int %18351 %2151 + %10905 = OpConvertSToF %v2float %13337 + %18249 = OpVectorTimesScalar %v2float %10905 %float_0_000976592302 + %24072 = OpExtInst %v2float %1 FMax %73 %18249 + %24332 = OpCompositeExtract %float %24072 0 + %15574 = OpCompositeExtract %float %24072 1 + %16672 = OpCompositeConstruct %v4float %24332 %15574 %float_0 %float_0 + %19524 = OpCompositeExtract %uint %10943 3 + %16035 = OpBitcast %int %19524 + %18205 = OpCompositeConstruct %v2int %16035 %16035 + %18352 = OpShiftLeftLogical %v2int %18205 %1959 + %13338 = OpShiftRightArithmetic %v2int %18352 %2151 + %10906 = OpConvertSToF %v2float %13338 + %18250 = OpVectorTimesScalar %v2float %10906 %float_0_000976592302 + %24073 = OpExtInst %v2float %1 FMax %73 %18250 + %24333 = OpCompositeExtract %float %24073 0 + %18764 = OpCompositeExtract %float %24073 1 + %9034 = OpCompositeConstruct %v4float %24333 %18764 %float_0 %float_0 + OpBranch %16224 + %7354 = OpLabel + %22205 = OpCompositeExtract %uint %10943 0 + %20234 = OpCompositeConstruct %v3uint %22205 %22205 %22205 + %11021 = OpShiftRightLogical %v3uint %20234 %2996 + %24038 = OpBitwiseAnd %v3uint %11021 %261 + %18588 = OpBitwiseAnd %v3uint %24038 %1126 + %23440 = OpShiftRightLogical %v3uint %24038 %2828 + %16585 = OpIEqual %v3bool %23440 %2578 + %11339 = OpExtInst %v3int %1 FindUMsb %18588 + %10773 = OpBitcast %v3uint %11339 + %6266 = OpISub %v3uint %2828 %10773 + %8720 = OpIAdd %v3uint %10773 %2360 + %10351 = OpSelect %v3uint %16585 %8720 %23440 + %23252 = OpShiftLeftLogical %v3uint %18588 %6266 + %18842 = OpBitwiseAnd %v3uint %23252 %1126 + %10909 = OpSelect %v3uint %16585 %18842 %18588 + %24569 = OpIAdd %v3uint %10351 %1018 + %20351 = OpShiftLeftLogical %v3uint %24569 %393 + %16294 = OpShiftLeftLogical %v3uint %10909 %141 + %22396 = OpBitwiseOr %v3uint %20351 %16294 + %13824 = OpIEqual %v3bool %24038 %2578 + %16962 = OpSelect %v3uint %13824 %2578 %22396 + %10703 = OpBitcast %v3float %16962 + %19364 = OpShiftRightLogical %uint %22205 %uint_30 + %18446 = OpConvertUToF %float %19364 + %15903 = OpFMul %float %18446 %float_0_333333343 + %21442 = OpCompositeExtract %float %10703 0 + %10837 = OpCompositeExtract %float %10703 1 + %7833 = OpCompositeExtract %float %10703 2 + %15834 = OpCompositeConstruct %v4float %21442 %10837 %7833 %15903 + %10229 = OpCompositeExtract %uint %10943 1 + %13582 = OpCompositeConstruct %v3uint %10229 %10229 %10229 + %11022 = OpShiftRightLogical %v3uint %13582 %2996 + %24039 = OpBitwiseAnd %v3uint %11022 %261 + %18589 = OpBitwiseAnd %v3uint %24039 %1126 + %23441 = OpShiftRightLogical %v3uint %24039 %2828 + %16586 = OpIEqual %v3bool %23441 %2578 + %11340 = OpExtInst %v3int %1 FindUMsb %18589 + %10774 = OpBitcast %v3uint %11340 + %6267 = OpISub %v3uint %2828 %10774 + %8721 = OpIAdd %v3uint %10774 %2360 + %10352 = OpSelect %v3uint %16586 %8721 %23441 + %23253 = OpShiftLeftLogical %v3uint %18589 %6267 + %18843 = OpBitwiseAnd %v3uint %23253 %1126 + %10910 = OpSelect %v3uint %16586 %18843 %18589 + %24570 = OpIAdd %v3uint %10352 %1018 + %20352 = OpShiftLeftLogical %v3uint %24570 %393 + %16295 = OpShiftLeftLogical %v3uint %10910 %141 + %22397 = OpBitwiseOr %v3uint %20352 %16295 + %13825 = OpIEqual %v3bool %24039 %2578 + %16963 = OpSelect %v3uint %13825 %2578 %22397 + %10704 = OpBitcast %v3float %16963 + %19365 = OpShiftRightLogical %uint %10229 %uint_30 + %18447 = OpConvertUToF %float %19365 + %15904 = OpFMul %float %18447 %float_0_333333343 + %21443 = OpCompositeExtract %float %10704 0 + %10838 = OpCompositeExtract %float %10704 1 + %7834 = OpCompositeExtract %float %10704 2 + %15835 = OpCompositeConstruct %v4float %21443 %10838 %7834 %15904 + %10230 = OpCompositeExtract %uint %10943 2 + %13583 = OpCompositeConstruct %v3uint %10230 %10230 %10230 + %11023 = OpShiftRightLogical %v3uint %13583 %2996 + %24040 = OpBitwiseAnd %v3uint %11023 %261 + %18590 = OpBitwiseAnd %v3uint %24040 %1126 + %23442 = OpShiftRightLogical %v3uint %24040 %2828 + %16587 = OpIEqual %v3bool %23442 %2578 + %11341 = OpExtInst %v3int %1 FindUMsb %18590 + %10775 = OpBitcast %v3uint %11341 + %6268 = OpISub %v3uint %2828 %10775 + %8722 = OpIAdd %v3uint %10775 %2360 + %10353 = OpSelect %v3uint %16587 %8722 %23442 + %23254 = OpShiftLeftLogical %v3uint %18590 %6268 + %18844 = OpBitwiseAnd %v3uint %23254 %1126 + %10911 = OpSelect %v3uint %16587 %18844 %18590 + %24571 = OpIAdd %v3uint %10353 %1018 + %20353 = OpShiftLeftLogical %v3uint %24571 %393 + %16296 = OpShiftLeftLogical %v3uint %10911 %141 + %22398 = OpBitwiseOr %v3uint %20353 %16296 + %13826 = OpIEqual %v3bool %24040 %2578 + %16964 = OpSelect %v3uint %13826 %2578 %22398 + %10705 = OpBitcast %v3float %16964 + %19366 = OpShiftRightLogical %uint %10230 %uint_30 + %18448 = OpConvertUToF %float %19366 + %15905 = OpFMul %float %18448 %float_0_333333343 + %21444 = OpCompositeExtract %float %10705 0 + %10839 = OpCompositeExtract %float %10705 1 + %7835 = OpCompositeExtract %float %10705 2 + %15836 = OpCompositeConstruct %v4float %21444 %10839 %7835 %15905 + %10231 = OpCompositeExtract %uint %10943 3 + %13584 = OpCompositeConstruct %v3uint %10231 %10231 %10231 + %11024 = OpShiftRightLogical %v3uint %13584 %2996 + %24041 = OpBitwiseAnd %v3uint %11024 %261 + %18591 = OpBitwiseAnd %v3uint %24041 %1126 + %23443 = OpShiftRightLogical %v3uint %24041 %2828 + %16588 = OpIEqual %v3bool %23443 %2578 + %11342 = OpExtInst %v3int %1 FindUMsb %18591 + %10776 = OpBitcast %v3uint %11342 + %6269 = OpISub %v3uint %2828 %10776 + %8723 = OpIAdd %v3uint %10776 %2360 + %10354 = OpSelect %v3uint %16588 %8723 %23443 + %23255 = OpShiftLeftLogical %v3uint %18591 %6269 + %18845 = OpBitwiseAnd %v3uint %23255 %1126 + %10912 = OpSelect %v3uint %16588 %18845 %18591 + %24572 = OpIAdd %v3uint %10354 %1018 + %20354 = OpShiftLeftLogical %v3uint %24572 %393 + %16297 = OpShiftLeftLogical %v3uint %10912 %141 + %22399 = OpBitwiseOr %v3uint %20354 %16297 + %13827 = OpIEqual %v3bool %24041 %2578 + %16965 = OpSelect %v3uint %13827 %2578 %22399 + %10706 = OpBitcast %v3float %16965 + %19367 = OpShiftRightLogical %uint %10231 %uint_30 + %18449 = OpConvertUToF %float %19367 + %15906 = OpFMul %float %18449 %float_0_333333343 + %21445 = OpCompositeExtract %float %10706 0 + %10840 = OpCompositeExtract %float %10706 1 + %11025 = OpCompositeExtract %float %10706 2 + %9035 = OpCompositeConstruct %v4float %21445 %10840 %11025 %15906 + OpBranch %16224 + %7355 = OpLabel + %22206 = OpCompositeExtract %uint %10943 0 + %20235 = OpCompositeConstruct %v4uint %22206 %22206 %22206 %22206 + %9368 = OpShiftRightLogical %v4uint %20235 %845 + %18859 = OpBitwiseAnd %v4uint %9368 %635 + %15543 = OpConvertUToF %v4float %18859 + %16688 = OpFMul %v4float %15543 %2798 + %23762 = OpCompositeExtract %uint %10943 1 + %20813 = OpCompositeConstruct %v4uint %23762 %23762 %23762 %23762 + %9369 = OpShiftRightLogical %v4uint %20813 %845 + %18860 = OpBitwiseAnd %v4uint %9369 %635 + %15544 = OpConvertUToF %v4float %18860 + %16689 = OpFMul %v4float %15544 %2798 + %23763 = OpCompositeExtract %uint %10943 2 + %20814 = OpCompositeConstruct %v4uint %23763 %23763 %23763 %23763 + %9370 = OpShiftRightLogical %v4uint %20814 %845 + %18861 = OpBitwiseAnd %v4uint %9370 %635 + %15545 = OpConvertUToF %v4float %18861 + %16690 = OpFMul %v4float %15545 %2798 + %23764 = OpCompositeExtract %uint %10943 3 + %20815 = OpCompositeConstruct %v4uint %23764 %23764 %23764 %23764 + %9371 = OpShiftRightLogical %v4uint %20815 %845 + %18862 = OpBitwiseAnd %v4uint %9371 %635 + %18735 = OpConvertUToF %v4float %18862 + %9887 = OpFMul %v4float %18735 %2798 + OpBranch %16224 + %14585 = OpLabel + %22207 = OpCompositeExtract %uint %10943 0 + %20236 = OpCompositeConstruct %v4uint %22207 %22207 %22207 %22207 + %9372 = OpShiftRightLogical %v4uint %20236 %653 + %19030 = OpBitwiseAnd %v4uint %9372 %1611 + %13986 = OpConvertUToF %v4float %19030 + %19235 = OpVectorTimesScalar %v4float %13986 %float_0_00392156886 + %8607 = OpCompositeExtract %uint %10943 1 + %24843 = OpCompositeConstruct %v4uint %8607 %8607 %8607 %8607 + %9373 = OpShiftRightLogical %v4uint %24843 %653 + %19031 = OpBitwiseAnd %v4uint %9373 %1611 + %13987 = OpConvertUToF %v4float %19031 + %19236 = OpVectorTimesScalar %v4float %13987 %float_0_00392156886 + %8608 = OpCompositeExtract %uint %10943 2 + %24844 = OpCompositeConstruct %v4uint %8608 %8608 %8608 %8608 + %9374 = OpShiftRightLogical %v4uint %24844 %653 + %19032 = OpBitwiseAnd %v4uint %9374 %1611 + %13988 = OpConvertUToF %v4float %19032 + %19237 = OpVectorTimesScalar %v4float %13988 %float_0_00392156886 + %8609 = OpCompositeExtract %uint %10943 3 + %24845 = OpCompositeConstruct %v4uint %8609 %8609 %8609 %8609 + %9375 = OpShiftRightLogical %v4uint %24845 %653 + %19033 = OpBitwiseAnd %v4uint %9375 %1611 + %17178 = OpConvertUToF %v4float %19033 + %12434 = OpVectorTimesScalar %v4float %17178 %float_0_00392156886 + OpBranch %16224 + %19451 = OpLabel + %12428 = OpCompositeExtract %uint %10943 0 + %20462 = OpBitcast %float %12428 + %17206 = OpCompositeConstruct %v2float %20462 %float_0 + %11664 = OpVectorShuffle %v4float %17206 %17206 0 1 1 1 + %22193 = OpCompositeExtract %uint %10943 1 + %16232 = OpBitcast %float %22193 + %17207 = OpCompositeConstruct %v2float %16232 %float_0 + %11665 = OpVectorShuffle %v4float %17207 %17207 0 1 1 1 + %22194 = OpCompositeExtract %uint %10943 2 + %16233 = OpBitcast %float %22194 + %17208 = OpCompositeConstruct %v2float %16233 %float_0 + %11666 = OpVectorShuffle %v4float %17208 %17208 0 1 1 1 + %22195 = OpCompositeExtract %uint %10943 3 + %16234 = OpBitcast %float %22195 + %20398 = OpCompositeConstruct %v2float %16234 %float_0 + %23098 = OpVectorShuffle %v4float %20398 %20398 0 1 1 1 + OpBranch %16224 + %16224 = OpLabel + %11175 = OpPhi %v4float %23098 %19451 %12434 %14585 %9887 %7355 %9035 %7354 %9034 %8190 %9033 %8243 + %14344 = OpPhi %v4float %11666 %19451 %19237 %14585 %16690 %7355 %15836 %7354 %16672 %8190 %14606 %8243 + %15229 = OpPhi %v4float %11665 %19451 %19236 %14585 %16689 %7355 %15835 %7354 %16671 %8190 %14605 %8243 + %14518 = OpPhi %v4float %11664 %19451 %19235 %14585 %16688 %7355 %15834 %7354 %16670 %8190 %14604 %8243 + OpBranch %21263 + %15205 = OpLabel + %21584 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20259 DontFlatten + OpBranchConditional %21584 %9762 %12130 + %12130 = OpLabel + %19408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %23256 + %23877 = OpLoad %uint %19408 + %11691 = OpIAdd %uint %23256 %uint_1 + %6401 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11691 + %23652 = OpLoad %uint %6401 + %11692 = OpIAdd %uint %23256 %6555 + %6402 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11692 + %23653 = OpLoad %uint %6402 + %11693 = OpIAdd %uint %11692 %uint_1 + %24559 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11693 + %14156 = OpLoad %uint %24559 + %19670 = OpCompositeConstruct %v4uint %23877 %23652 %23653 %14156 + %17048 = OpIMul %uint %uint_2 %6555 + %13991 = OpIAdd %uint %23256 %17048 + %15233 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13991 + %23654 = OpLoad %uint %15233 + %11694 = OpIAdd %uint %13991 %uint_1 + %6476 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11694 + %24157 = OpLoad %uint %6476 + %6236 = OpIMul %uint %uint_3 %6555 + %8355 = OpIAdd %uint %23256 %6236 + %15234 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8355 + %23655 = OpLoad %uint %15234 + %11695 = OpIAdd %uint %8355 %uint_1 + %24560 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11695 + %16381 = OpLoad %uint %24560 + %20782 = OpCompositeConstruct %v4uint %23654 %24157 %23655 %16381 + OpBranch %20259 + %9762 = OpLabel + %21830 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %23256 + %23878 = OpLoad %uint %21830 + %11696 = OpIAdd %uint %23256 %uint_1 + %6403 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11696 + %23656 = OpLoad %uint %6403 + %11697 = OpIAdd %uint %23256 %uint_2 + %6404 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11697 + %23657 = OpLoad %uint %6404 + %11698 = OpIAdd %uint %23256 %uint_3 + %24561 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11698 + %14080 = OpLoad %uint %24561 + %19165 = OpCompositeConstruct %v4uint %23878 %23656 %23657 %14080 + %22501 = OpIAdd %uint %23256 %uint_4 + %24651 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22501 + %23658 = OpLoad %uint %24651 + %11699 = OpIAdd %uint %23256 %uint_5 + %6405 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11699 + %23659 = OpLoad %uint %6405 + %11700 = OpIAdd %uint %23256 %uint_6 + %6406 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11700 + %23660 = OpLoad %uint %6406 + %11701 = OpIAdd %uint %23256 %uint_7 + %24562 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11701 + %16382 = OpLoad %uint %24562 + %20783 = OpCompositeConstruct %v4uint %23658 %23659 %23660 %16382 + OpBranch %20259 + %20259 = OpLabel + %11213 = OpPhi %v4uint %20783 %9762 %20782 %12130 + %14112 = OpPhi %v4uint %19165 %9762 %19670 %12130 + OpSelectionMerge %20260 None + OpSwitch %8576 %20310 5 %8536 7 %8244 + %8244 = OpLabel + %24407 = OpCompositeExtract %uint %14112 0 + %24680 = OpExtInst %v2float %1 UnpackHalf2x16 %24407 + %10101 = OpCompositeExtract %float %24680 0 + %16056 = OpCompositeExtract %float %24680 1 + %17025 = OpCompositeExtract %uint %14112 1 + %15605 = OpExtInst %v2float %1 UnpackHalf2x16 %17025 + %10086 = OpCompositeExtract %float %15605 0 + %17481 = OpCompositeExtract %float %15605 1 + %14607 = OpCompositeConstruct %v4float %10101 %16056 %10086 %17481 + %17277 = OpCompositeExtract %uint %14112 2 + %18030 = OpExtInst %v2float %1 UnpackHalf2x16 %17277 + %10102 = OpCompositeExtract %float %18030 0 + %16057 = OpCompositeExtract %float %18030 1 + %17026 = OpCompositeExtract %uint %14112 3 + %15606 = OpExtInst %v2float %1 UnpackHalf2x16 %17026 + %10087 = OpCompositeExtract %float %15606 0 + %17482 = OpCompositeExtract %float %15606 1 + %14608 = OpCompositeConstruct %v4float %10102 %16057 %10087 %17482 + %17278 = OpCompositeExtract %uint %11213 0 + %18031 = OpExtInst %v2float %1 UnpackHalf2x16 %17278 + %10103 = OpCompositeExtract %float %18031 0 + %16058 = OpCompositeExtract %float %18031 1 + %17027 = OpCompositeExtract %uint %11213 1 + %15607 = OpExtInst %v2float %1 UnpackHalf2x16 %17027 + %10088 = OpCompositeExtract %float %15607 0 + %17483 = OpCompositeExtract %float %15607 1 + %14609 = OpCompositeConstruct %v4float %10103 %16058 %10088 %17483 + %17279 = OpCompositeExtract %uint %11213 2 + %18032 = OpExtInst %v2float %1 UnpackHalf2x16 %17279 + %10104 = OpCompositeExtract %float %18032 0 + %16059 = OpCompositeExtract %float %18032 1 + %17028 = OpCompositeExtract %uint %11213 3 + %15608 = OpExtInst %v2float %1 UnpackHalf2x16 %17028 + %10089 = OpCompositeExtract %float %15608 0 + %20671 = OpCompositeExtract %float %15608 1 + %9036 = OpCompositeConstruct %v4float %10104 %16059 %10089 %20671 + OpBranch %20260 + %8536 = OpLabel + %9723 = OpVectorShuffle %v2uint %14112 %14112 0 1 + %23356 = OpBitcast %v2int %9723 + %24782 = OpVectorShuffle %v4int %23356 %23356 0 0 1 1 + %18598 = OpShiftLeftLogical %v4int %24782 %290 + %15757 = OpShiftRightArithmetic %v4int %18598 %770 + %10907 = OpConvertSToF %v4float %15757 + %18209 = OpVectorTimesScalar %v4float %10907 %float_0_000976592302 + %25233 = OpExtInst %v4float %1 FMax %1284 %18209 + %14187 = OpVectorShuffle %v2uint %14112 %14112 2 3 + %9407 = OpBitcast %v2int %14187 + %24783 = OpVectorShuffle %v4int %9407 %9407 0 0 1 1 + %18599 = OpShiftLeftLogical %v4int %24783 %290 + %15758 = OpShiftRightArithmetic %v4int %18599 %770 + %10908 = OpConvertSToF %v4float %15758 + %18210 = OpVectorTimesScalar %v4float %10908 %float_0_000976592302 + %25234 = OpExtInst %v4float %1 FMax %1284 %18210 + %14188 = OpVectorShuffle %v2uint %11213 %11213 0 1 + %9408 = OpBitcast %v2int %14188 + %24784 = OpVectorShuffle %v4int %9408 %9408 0 0 1 1 + %18600 = OpShiftLeftLogical %v4int %24784 %290 + %15759 = OpShiftRightArithmetic %v4int %18600 %770 + %10913 = OpConvertSToF %v4float %15759 + %18211 = OpVectorTimesScalar %v4float %10913 %float_0_000976592302 + %25235 = OpExtInst %v4float %1 FMax %1284 %18211 + %14189 = OpVectorShuffle %v2uint %11213 %11213 2 3 + %9409 = OpBitcast %v2int %14189 + %24785 = OpVectorShuffle %v4int %9409 %9409 0 0 1 1 + %18601 = OpShiftLeftLogical %v4int %24785 %290 + %15760 = OpShiftRightArithmetic %v4int %18601 %770 + %10914 = OpConvertSToF %v4float %15760 + %21439 = OpVectorTimesScalar %v4float %10914 %float_0_000976592302 + %17250 = OpExtInst %v4float %1 FMax %1284 %21439 + OpBranch %20260 + %20310 = OpLabel + %9763 = OpVectorShuffle %v2uint %14112 %14112 0 1 + %20825 = OpBitcast %v2float %9763 + %7035 = OpCompositeExtract %float %20825 0 + %13418 = OpCompositeExtract %float %20825 1 + %17016 = OpCompositeConstruct %v4float %7035 %13418 %float_0 %float_0 + %16856 = OpVectorShuffle %v2uint %14112 %14112 2 3 + %14173 = OpBitcast %v2float %16856 + %7036 = OpCompositeExtract %float %14173 0 + %13419 = OpCompositeExtract %float %14173 1 + %17017 = OpCompositeConstruct %v4float %7036 %13419 %float_0 %float_0 + %16857 = OpVectorShuffle %v2uint %11213 %11213 0 1 + %14174 = OpBitcast %v2float %16857 + %7037 = OpCompositeExtract %float %14174 0 + %13420 = OpCompositeExtract %float %14174 1 + %17018 = OpCompositeConstruct %v4float %7037 %13420 %float_0 %float_0 + %16858 = OpVectorShuffle %v2uint %11213 %11213 2 3 + %14175 = OpBitcast %v2float %16858 + %7038 = OpCompositeExtract %float %14175 0 + %16648 = OpCompositeExtract %float %14175 1 + %9037 = OpCompositeConstruct %v4float %7038 %16648 %float_0 %float_0 + OpBranch %20260 + %20260 = OpLabel + %11176 = OpPhi %v4float %9037 %20310 %17250 %8536 %9036 %8244 + %14345 = OpPhi %v4float %17018 %20310 %25235 %8536 %14609 %8244 + %15230 = OpPhi %v4float %17017 %20310 %25234 %8536 %14608 %8244 + %14519 = OpPhi %v4float %17016 %20310 %25233 %8536 %14607 %8244 + OpBranch %21263 + %21263 = OpLabel + %11177 = OpPhi %v4float %11176 %20260 %11175 %16224 + %14346 = OpPhi %v4float %14345 %20260 %14344 %16224 + %13804 = OpPhi %v4float %15230 %20260 %15229 %16224 + %8403 = OpPhi %v4float %14519 %20260 %14518 %16224 + %11861 = OpUGreaterThanEqual %bool %16205 %uint_4 + OpSelectionMerge %21267 DontFlatten + OpBranchConditional %11861 %20709 %21267 + %20709 = OpLabel + %25083 = OpFMul %float %11052 %float_0_5 + %24184 = OpIAdd %uint %23256 %uint_80 + OpSelectionMerge %21264 DontFlatten + OpBranchConditional %23279 %15206 %16570 + %16570 = OpLabel + %19163 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20298 DontFlatten + OpBranchConditional %19163 %9764 %12131 + %12131 = OpLabel + %19409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24184 + %23879 = OpLoad %uint %19409 + %11702 = OpIAdd %uint %24184 %6555 + %6477 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11702 + %24158 = OpLoad %uint %6477 + %6237 = OpIMul %uint %uint_2 %6555 + %8356 = OpIAdd %uint %24184 %6237 + %15310 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8356 + %24159 = OpLoad %uint %15310 + %6238 = OpIMul %uint %uint_3 %6555 + %8357 = OpIAdd %uint %24184 %6238 + %14322 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8357 + %16383 = OpLoad %uint %14322 + %20784 = OpCompositeConstruct %v4uint %23879 %24158 %24159 %16383 + OpBranch %20298 + %9764 = OpLabel + %21831 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24184 + %23880 = OpLoad %uint %21831 + %11703 = OpIAdd %uint %23256 %uint_81 + %6407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11703 + %23661 = OpLoad %uint %6407 + %11704 = OpIAdd %uint %23256 %uint_82 + %6408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11704 + %23662 = OpLoad %uint %6408 + %11705 = OpIAdd %uint %23256 %uint_83 + %24563 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11705 + %16384 = OpLoad %uint %24563 + %20785 = OpCompositeConstruct %v4uint %23880 %23661 %23662 %16384 + OpBranch %20298 + %20298 = OpLabel + %10944 = OpPhi %v4uint %20785 %9764 %20784 %12131 + OpSelectionMerge %16225 None + OpSwitch %8576 %19452 0 %14586 1 %14586 2 %7357 10 %7357 3 %7356 12 %7356 4 %8191 6 %8245 + %8245 = OpLabel + %24408 = OpCompositeExtract %uint %10944 0 + %24681 = OpExtInst %v2float %1 UnpackHalf2x16 %24408 + %10090 = OpCompositeExtract %float %24681 0 + %17484 = OpCompositeExtract %float %24681 1 + %14610 = OpCompositeConstruct %v4float %10090 %17484 %float_0 %float_0 + %17280 = OpCompositeExtract %uint %10944 1 + %18033 = OpExtInst %v2float %1 UnpackHalf2x16 %17280 + %10091 = OpCompositeExtract %float %18033 0 + %17485 = OpCompositeExtract %float %18033 1 + %14611 = OpCompositeConstruct %v4float %10091 %17485 %float_0 %float_0 + %17281 = OpCompositeExtract %uint %10944 2 + %18034 = OpExtInst %v2float %1 UnpackHalf2x16 %17281 + %10092 = OpCompositeExtract %float %18034 0 + %17486 = OpCompositeExtract %float %18034 1 + %14612 = OpCompositeConstruct %v4float %10092 %17486 %float_0 %float_0 + %17282 = OpCompositeExtract %uint %10944 3 + %18035 = OpExtInst %v2float %1 UnpackHalf2x16 %17282 + %10093 = OpCompositeExtract %float %18035 0 + %20672 = OpCompositeExtract %float %18035 1 + %9038 = OpCompositeConstruct %v4float %10093 %20672 %float_0 %float_0 + OpBranch %16225 + %8191 = OpLabel + %12429 = OpCompositeExtract %uint %10944 0 + %22686 = OpBitcast %int %12429 + %18206 = OpCompositeConstruct %v2int %22686 %22686 + %18353 = OpShiftLeftLogical %v2int %18206 %1959 + %13339 = OpShiftRightArithmetic %v2int %18353 %2151 + %10915 = OpConvertSToF %v2float %13339 + %18251 = OpVectorTimesScalar %v2float %10915 %float_0_000976592302 + %24074 = OpExtInst %v2float %1 FMax %73 %18251 + %24334 = OpCompositeExtract %float %24074 0 + %15575 = OpCompositeExtract %float %24074 1 + %16673 = OpCompositeConstruct %v4float %24334 %15575 %float_0 %float_0 + %19525 = OpCompositeExtract %uint %10944 1 + %16036 = OpBitcast %int %19525 + %18207 = OpCompositeConstruct %v2int %16036 %16036 + %18354 = OpShiftLeftLogical %v2int %18207 %1959 + %13340 = OpShiftRightArithmetic %v2int %18354 %2151 + %10916 = OpConvertSToF %v2float %13340 + %18252 = OpVectorTimesScalar %v2float %10916 %float_0_000976592302 + %24075 = OpExtInst %v2float %1 FMax %73 %18252 + %24335 = OpCompositeExtract %float %24075 0 + %15576 = OpCompositeExtract %float %24075 1 + %16674 = OpCompositeConstruct %v4float %24335 %15576 %float_0 %float_0 + %19526 = OpCompositeExtract %uint %10944 2 + %16037 = OpBitcast %int %19526 + %18208 = OpCompositeConstruct %v2int %16037 %16037 + %18355 = OpShiftLeftLogical %v2int %18208 %1959 + %13341 = OpShiftRightArithmetic %v2int %18355 %2151 + %10917 = OpConvertSToF %v2float %13341 + %18253 = OpVectorTimesScalar %v2float %10917 %float_0_000976592302 + %24076 = OpExtInst %v2float %1 FMax %73 %18253 + %24336 = OpCompositeExtract %float %24076 0 + %15577 = OpCompositeExtract %float %24076 1 + %16675 = OpCompositeConstruct %v4float %24336 %15577 %float_0 %float_0 + %19527 = OpCompositeExtract %uint %10944 3 + %16038 = OpBitcast %int %19527 + %18212 = OpCompositeConstruct %v2int %16038 %16038 + %18356 = OpShiftLeftLogical %v2int %18212 %1959 + %13342 = OpShiftRightArithmetic %v2int %18356 %2151 + %10918 = OpConvertSToF %v2float %13342 + %18254 = OpVectorTimesScalar %v2float %10918 %float_0_000976592302 + %24077 = OpExtInst %v2float %1 FMax %73 %18254 + %24337 = OpCompositeExtract %float %24077 0 + %18765 = OpCompositeExtract %float %24077 1 + %9039 = OpCompositeConstruct %v4float %24337 %18765 %float_0 %float_0 + OpBranch %16225 + %7356 = OpLabel + %22208 = OpCompositeExtract %uint %10944 0 + %20237 = OpCompositeConstruct %v3uint %22208 %22208 %22208 + %11026 = OpShiftRightLogical %v3uint %20237 %2996 + %24042 = OpBitwiseAnd %v3uint %11026 %261 + %18592 = OpBitwiseAnd %v3uint %24042 %1126 + %23444 = OpShiftRightLogical %v3uint %24042 %2828 + %16589 = OpIEqual %v3bool %23444 %2578 + %11343 = OpExtInst %v3int %1 FindUMsb %18592 + %10777 = OpBitcast %v3uint %11343 + %6270 = OpISub %v3uint %2828 %10777 + %8724 = OpIAdd %v3uint %10777 %2360 + %10355 = OpSelect %v3uint %16589 %8724 %23444 + %23257 = OpShiftLeftLogical %v3uint %18592 %6270 + %18846 = OpBitwiseAnd %v3uint %23257 %1126 + %10919 = OpSelect %v3uint %16589 %18846 %18592 + %24573 = OpIAdd %v3uint %10355 %1018 + %20355 = OpShiftLeftLogical %v3uint %24573 %393 + %16298 = OpShiftLeftLogical %v3uint %10919 %141 + %22400 = OpBitwiseOr %v3uint %20355 %16298 + %13828 = OpIEqual %v3bool %24042 %2578 + %16966 = OpSelect %v3uint %13828 %2578 %22400 + %10707 = OpBitcast %v3float %16966 + %19368 = OpShiftRightLogical %uint %22208 %uint_30 + %18450 = OpConvertUToF %float %19368 + %15907 = OpFMul %float %18450 %float_0_333333343 + %21446 = OpCompositeExtract %float %10707 0 + %10841 = OpCompositeExtract %float %10707 1 + %7836 = OpCompositeExtract %float %10707 2 + %15837 = OpCompositeConstruct %v4float %21446 %10841 %7836 %15907 + %10232 = OpCompositeExtract %uint %10944 1 + %13585 = OpCompositeConstruct %v3uint %10232 %10232 %10232 + %11027 = OpShiftRightLogical %v3uint %13585 %2996 + %24043 = OpBitwiseAnd %v3uint %11027 %261 + %18593 = OpBitwiseAnd %v3uint %24043 %1126 + %23445 = OpShiftRightLogical %v3uint %24043 %2828 + %16590 = OpIEqual %v3bool %23445 %2578 + %11344 = OpExtInst %v3int %1 FindUMsb %18593 + %10778 = OpBitcast %v3uint %11344 + %6271 = OpISub %v3uint %2828 %10778 + %8725 = OpIAdd %v3uint %10778 %2360 + %10356 = OpSelect %v3uint %16590 %8725 %23445 + %23258 = OpShiftLeftLogical %v3uint %18593 %6271 + %18847 = OpBitwiseAnd %v3uint %23258 %1126 + %10920 = OpSelect %v3uint %16590 %18847 %18593 + %24574 = OpIAdd %v3uint %10356 %1018 + %20356 = OpShiftLeftLogical %v3uint %24574 %393 + %16299 = OpShiftLeftLogical %v3uint %10920 %141 + %22401 = OpBitwiseOr %v3uint %20356 %16299 + %13829 = OpIEqual %v3bool %24043 %2578 + %16967 = OpSelect %v3uint %13829 %2578 %22401 + %10708 = OpBitcast %v3float %16967 + %19369 = OpShiftRightLogical %uint %10232 %uint_30 + %18451 = OpConvertUToF %float %19369 + %15908 = OpFMul %float %18451 %float_0_333333343 + %21447 = OpCompositeExtract %float %10708 0 + %10842 = OpCompositeExtract %float %10708 1 + %7837 = OpCompositeExtract %float %10708 2 + %15838 = OpCompositeConstruct %v4float %21447 %10842 %7837 %15908 + %10233 = OpCompositeExtract %uint %10944 2 + %13586 = OpCompositeConstruct %v3uint %10233 %10233 %10233 + %11028 = OpShiftRightLogical %v3uint %13586 %2996 + %24044 = OpBitwiseAnd %v3uint %11028 %261 + %18594 = OpBitwiseAnd %v3uint %24044 %1126 + %23446 = OpShiftRightLogical %v3uint %24044 %2828 + %16591 = OpIEqual %v3bool %23446 %2578 + %11345 = OpExtInst %v3int %1 FindUMsb %18594 + %10779 = OpBitcast %v3uint %11345 + %6272 = OpISub %v3uint %2828 %10779 + %8726 = OpIAdd %v3uint %10779 %2360 + %10357 = OpSelect %v3uint %16591 %8726 %23446 + %23259 = OpShiftLeftLogical %v3uint %18594 %6272 + %18848 = OpBitwiseAnd %v3uint %23259 %1126 + %10921 = OpSelect %v3uint %16591 %18848 %18594 + %24575 = OpIAdd %v3uint %10357 %1018 + %20357 = OpShiftLeftLogical %v3uint %24575 %393 + %16300 = OpShiftLeftLogical %v3uint %10921 %141 + %22402 = OpBitwiseOr %v3uint %20357 %16300 + %13830 = OpIEqual %v3bool %24044 %2578 + %16968 = OpSelect %v3uint %13830 %2578 %22402 + %10709 = OpBitcast %v3float %16968 + %19370 = OpShiftRightLogical %uint %10233 %uint_30 + %18452 = OpConvertUToF %float %19370 + %15909 = OpFMul %float %18452 %float_0_333333343 + %21448 = OpCompositeExtract %float %10709 0 + %10843 = OpCompositeExtract %float %10709 1 + %7838 = OpCompositeExtract %float %10709 2 + %15839 = OpCompositeConstruct %v4float %21448 %10843 %7838 %15909 + %10234 = OpCompositeExtract %uint %10944 3 + %13587 = OpCompositeConstruct %v3uint %10234 %10234 %10234 + %11029 = OpShiftRightLogical %v3uint %13587 %2996 + %24045 = OpBitwiseAnd %v3uint %11029 %261 + %18595 = OpBitwiseAnd %v3uint %24045 %1126 + %23447 = OpShiftRightLogical %v3uint %24045 %2828 + %16592 = OpIEqual %v3bool %23447 %2578 + %11346 = OpExtInst %v3int %1 FindUMsb %18595 + %10780 = OpBitcast %v3uint %11346 + %6273 = OpISub %v3uint %2828 %10780 + %8727 = OpIAdd %v3uint %10780 %2360 + %10358 = OpSelect %v3uint %16592 %8727 %23447 + %23260 = OpShiftLeftLogical %v3uint %18595 %6273 + %18849 = OpBitwiseAnd %v3uint %23260 %1126 + %10922 = OpSelect %v3uint %16592 %18849 %18595 + %24576 = OpIAdd %v3uint %10358 %1018 + %20358 = OpShiftLeftLogical %v3uint %24576 %393 + %16301 = OpShiftLeftLogical %v3uint %10922 %141 + %22403 = OpBitwiseOr %v3uint %20358 %16301 + %13831 = OpIEqual %v3bool %24045 %2578 + %16969 = OpSelect %v3uint %13831 %2578 %22403 + %10710 = OpBitcast %v3float %16969 + %19371 = OpShiftRightLogical %uint %10234 %uint_30 + %18453 = OpConvertUToF %float %19371 + %15910 = OpFMul %float %18453 %float_0_333333343 + %21449 = OpCompositeExtract %float %10710 0 + %10844 = OpCompositeExtract %float %10710 1 + %11030 = OpCompositeExtract %float %10710 2 + %9040 = OpCompositeConstruct %v4float %21449 %10844 %11030 %15910 + OpBranch %16225 + %7357 = OpLabel + %22209 = OpCompositeExtract %uint %10944 0 + %20238 = OpCompositeConstruct %v4uint %22209 %22209 %22209 %22209 + %9376 = OpShiftRightLogical %v4uint %20238 %845 + %18863 = OpBitwiseAnd %v4uint %9376 %635 + %15546 = OpConvertUToF %v4float %18863 + %16691 = OpFMul %v4float %15546 %2798 + %23765 = OpCompositeExtract %uint %10944 1 + %20816 = OpCompositeConstruct %v4uint %23765 %23765 %23765 %23765 + %9377 = OpShiftRightLogical %v4uint %20816 %845 + %18864 = OpBitwiseAnd %v4uint %9377 %635 + %15547 = OpConvertUToF %v4float %18864 + %16692 = OpFMul %v4float %15547 %2798 + %23766 = OpCompositeExtract %uint %10944 2 + %20817 = OpCompositeConstruct %v4uint %23766 %23766 %23766 %23766 + %9378 = OpShiftRightLogical %v4uint %20817 %845 + %18865 = OpBitwiseAnd %v4uint %9378 %635 + %15548 = OpConvertUToF %v4float %18865 + %16693 = OpFMul %v4float %15548 %2798 + %23767 = OpCompositeExtract %uint %10944 3 + %20818 = OpCompositeConstruct %v4uint %23767 %23767 %23767 %23767 + %9379 = OpShiftRightLogical %v4uint %20818 %845 + %18866 = OpBitwiseAnd %v4uint %9379 %635 + %18736 = OpConvertUToF %v4float %18866 + %9888 = OpFMul %v4float %18736 %2798 + OpBranch %16225 + %14586 = OpLabel + %22210 = OpCompositeExtract %uint %10944 0 + %20239 = OpCompositeConstruct %v4uint %22210 %22210 %22210 %22210 + %9380 = OpShiftRightLogical %v4uint %20239 %653 + %19034 = OpBitwiseAnd %v4uint %9380 %1611 + %13989 = OpConvertUToF %v4float %19034 + %19238 = OpVectorTimesScalar %v4float %13989 %float_0_00392156886 + %8610 = OpCompositeExtract %uint %10944 1 + %24846 = OpCompositeConstruct %v4uint %8610 %8610 %8610 %8610 + %9381 = OpShiftRightLogical %v4uint %24846 %653 + %19035 = OpBitwiseAnd %v4uint %9381 %1611 + %13990 = OpConvertUToF %v4float %19035 + %19239 = OpVectorTimesScalar %v4float %13990 %float_0_00392156886 + %8611 = OpCompositeExtract %uint %10944 2 + %24847 = OpCompositeConstruct %v4uint %8611 %8611 %8611 %8611 + %9382 = OpShiftRightLogical %v4uint %24847 %653 + %19036 = OpBitwiseAnd %v4uint %9382 %1611 + %13992 = OpConvertUToF %v4float %19036 + %19240 = OpVectorTimesScalar %v4float %13992 %float_0_00392156886 + %8612 = OpCompositeExtract %uint %10944 3 + %24848 = OpCompositeConstruct %v4uint %8612 %8612 %8612 %8612 + %9383 = OpShiftRightLogical %v4uint %24848 %653 + %19037 = OpBitwiseAnd %v4uint %9383 %1611 + %17179 = OpConvertUToF %v4float %19037 + %12435 = OpVectorTimesScalar %v4float %17179 %float_0_00392156886 + OpBranch %16225 + %19452 = OpLabel + %12430 = OpCompositeExtract %uint %10944 0 + %20463 = OpBitcast %float %12430 + %17209 = OpCompositeConstruct %v2float %20463 %float_0 + %11667 = OpVectorShuffle %v4float %17209 %17209 0 1 1 1 + %22196 = OpCompositeExtract %uint %10944 1 + %16235 = OpBitcast %float %22196 + %17210 = OpCompositeConstruct %v2float %16235 %float_0 + %11668 = OpVectorShuffle %v4float %17210 %17210 0 1 1 1 + %22197 = OpCompositeExtract %uint %10944 2 + %16236 = OpBitcast %float %22197 + %17211 = OpCompositeConstruct %v2float %16236 %float_0 + %11669 = OpVectorShuffle %v4float %17211 %17211 0 1 1 1 + %22198 = OpCompositeExtract %uint %10944 3 + %16237 = OpBitcast %float %22198 + %20399 = OpCompositeConstruct %v2float %16237 %float_0 + %23099 = OpVectorShuffle %v4float %20399 %20399 0 1 1 1 + OpBranch %16225 + %16225 = OpLabel + %11178 = OpPhi %v4float %23099 %19452 %12435 %14586 %9888 %7357 %9040 %7356 %9039 %8191 %9038 %8245 + %14347 = OpPhi %v4float %11669 %19452 %19240 %14586 %16693 %7357 %15839 %7356 %16675 %8191 %14612 %8245 + %15231 = OpPhi %v4float %11668 %19452 %19239 %14586 %16692 %7357 %15838 %7356 %16674 %8191 %14611 %8245 + %14520 = OpPhi %v4float %11667 %19452 %19238 %14586 %16691 %7357 %15837 %7356 %16673 %8191 %14610 %8245 + OpBranch %21264 + %15206 = OpLabel + %21585 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20261 DontFlatten + OpBranchConditional %21585 %9765 %12132 + %12132 = OpLabel + %19410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24184 + %23881 = OpLoad %uint %19410 + %11706 = OpIAdd %uint %23256 %uint_81 + %6409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11706 + %23663 = OpLoad %uint %6409 + %11707 = OpIAdd %uint %24184 %6555 + %6410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11707 + %23664 = OpLoad %uint %6410 + %11708 = OpIAdd %uint %11707 %uint_1 + %24564 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11708 + %14157 = OpLoad %uint %24564 + %19671 = OpCompositeConstruct %v4uint %23881 %23663 %23664 %14157 + %17049 = OpIMul %uint %uint_2 %6555 + %13993 = OpIAdd %uint %24184 %17049 + %15235 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13993 + %23665 = OpLoad %uint %15235 + %11709 = OpIAdd %uint %13993 %uint_1 + %6478 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11709 + %24160 = OpLoad %uint %6478 + %6239 = OpIMul %uint %uint_3 %6555 + %8358 = OpIAdd %uint %24184 %6239 + %15236 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8358 + %23666 = OpLoad %uint %15236 + %11710 = OpIAdd %uint %8358 %uint_1 + %24565 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11710 + %16385 = OpLoad %uint %24565 + %20786 = OpCompositeConstruct %v4uint %23665 %24160 %23666 %16385 + OpBranch %20261 + %9765 = OpLabel + %21832 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24184 + %23882 = OpLoad %uint %21832 + %11711 = OpIAdd %uint %23256 %uint_81 + %6411 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11711 + %23667 = OpLoad %uint %6411 + %11712 = OpIAdd %uint %23256 %uint_82 + %6412 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11712 + %23668 = OpLoad %uint %6412 + %11713 = OpIAdd %uint %23256 %uint_83 + %24566 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11713 + %14081 = OpLoad %uint %24566 + %19166 = OpCompositeConstruct %v4uint %23882 %23667 %23668 %14081 + %22502 = OpIAdd %uint %23256 %uint_84 + %24652 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22502 + %23669 = OpLoad %uint %24652 + %11714 = OpIAdd %uint %23256 %uint_85 + %6413 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11714 + %23670 = OpLoad %uint %6413 + %11715 = OpIAdd %uint %23256 %uint_86 + %6414 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11715 + %23671 = OpLoad %uint %6414 + %11716 = OpIAdd %uint %23256 %uint_87 + %24567 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11716 + %16386 = OpLoad %uint %24567 + %20787 = OpCompositeConstruct %v4uint %23669 %23670 %23671 %16386 + OpBranch %20261 + %20261 = OpLabel + %11214 = OpPhi %v4uint %20787 %9765 %20786 %12132 + %14113 = OpPhi %v4uint %19166 %9765 %19671 %12132 + OpSelectionMerge %20262 None + OpSwitch %8576 %20311 5 %8537 7 %8246 + %8246 = OpLabel + %24409 = OpCompositeExtract %uint %14113 0 + %24682 = OpExtInst %v2float %1 UnpackHalf2x16 %24409 + %10105 = OpCompositeExtract %float %24682 0 + %16060 = OpCompositeExtract %float %24682 1 + %17029 = OpCompositeExtract %uint %14113 1 + %15609 = OpExtInst %v2float %1 UnpackHalf2x16 %17029 + %10094 = OpCompositeExtract %float %15609 0 + %17487 = OpCompositeExtract %float %15609 1 + %14613 = OpCompositeConstruct %v4float %10105 %16060 %10094 %17487 + %17283 = OpCompositeExtract %uint %14113 2 + %18036 = OpExtInst %v2float %1 UnpackHalf2x16 %17283 + %10106 = OpCompositeExtract %float %18036 0 + %16061 = OpCompositeExtract %float %18036 1 + %17030 = OpCompositeExtract %uint %14113 3 + %15610 = OpExtInst %v2float %1 UnpackHalf2x16 %17030 + %10095 = OpCompositeExtract %float %15610 0 + %17488 = OpCompositeExtract %float %15610 1 + %14614 = OpCompositeConstruct %v4float %10106 %16061 %10095 %17488 + %17284 = OpCompositeExtract %uint %11214 0 + %18037 = OpExtInst %v2float %1 UnpackHalf2x16 %17284 + %10107 = OpCompositeExtract %float %18037 0 + %16062 = OpCompositeExtract %float %18037 1 + %17031 = OpCompositeExtract %uint %11214 1 + %15611 = OpExtInst %v2float %1 UnpackHalf2x16 %17031 + %10096 = OpCompositeExtract %float %15611 0 + %17489 = OpCompositeExtract %float %15611 1 + %14615 = OpCompositeConstruct %v4float %10107 %16062 %10096 %17489 + %17285 = OpCompositeExtract %uint %11214 2 + %18038 = OpExtInst %v2float %1 UnpackHalf2x16 %17285 + %10108 = OpCompositeExtract %float %18038 0 + %16063 = OpCompositeExtract %float %18038 1 + %17032 = OpCompositeExtract %uint %11214 3 + %15612 = OpExtInst %v2float %1 UnpackHalf2x16 %17032 + %10097 = OpCompositeExtract %float %15612 0 + %20673 = OpCompositeExtract %float %15612 1 + %9041 = OpCompositeConstruct %v4float %10108 %16063 %10097 %20673 + OpBranch %20262 + %8537 = OpLabel + %9724 = OpVectorShuffle %v2uint %14113 %14113 0 1 + %23357 = OpBitcast %v2int %9724 + %24786 = OpVectorShuffle %v4int %23357 %23357 0 0 1 1 + %18602 = OpShiftLeftLogical %v4int %24786 %290 + %15761 = OpShiftRightArithmetic %v4int %18602 %770 + %10923 = OpConvertSToF %v4float %15761 + %18213 = OpVectorTimesScalar %v4float %10923 %float_0_000976592302 + %25236 = OpExtInst %v4float %1 FMax %1284 %18213 + %14190 = OpVectorShuffle %v2uint %14113 %14113 2 3 + %9410 = OpBitcast %v2int %14190 + %24787 = OpVectorShuffle %v4int %9410 %9410 0 0 1 1 + %18603 = OpShiftLeftLogical %v4int %24787 %290 + %15762 = OpShiftRightArithmetic %v4int %18603 %770 + %10924 = OpConvertSToF %v4float %15762 + %18214 = OpVectorTimesScalar %v4float %10924 %float_0_000976592302 + %25237 = OpExtInst %v4float %1 FMax %1284 %18214 + %14191 = OpVectorShuffle %v2uint %11214 %11214 0 1 + %9411 = OpBitcast %v2int %14191 + %24788 = OpVectorShuffle %v4int %9411 %9411 0 0 1 1 + %18604 = OpShiftLeftLogical %v4int %24788 %290 + %15763 = OpShiftRightArithmetic %v4int %18604 %770 + %10925 = OpConvertSToF %v4float %15763 + %18215 = OpVectorTimesScalar %v4float %10925 %float_0_000976592302 + %25238 = OpExtInst %v4float %1 FMax %1284 %18215 + %14192 = OpVectorShuffle %v2uint %11214 %11214 2 3 + %9412 = OpBitcast %v2int %14192 + %24789 = OpVectorShuffle %v4int %9412 %9412 0 0 1 1 + %18605 = OpShiftLeftLogical %v4int %24789 %290 + %15764 = OpShiftRightArithmetic %v4int %18605 %770 + %10926 = OpConvertSToF %v4float %15764 + %21440 = OpVectorTimesScalar %v4float %10926 %float_0_000976592302 + %17251 = OpExtInst %v4float %1 FMax %1284 %21440 + OpBranch %20262 + %20311 = OpLabel + %9766 = OpVectorShuffle %v2uint %14113 %14113 0 1 + %20826 = OpBitcast %v2float %9766 + %7039 = OpCompositeExtract %float %20826 0 + %13421 = OpCompositeExtract %float %20826 1 + %17019 = OpCompositeConstruct %v4float %7039 %13421 %float_0 %float_0 + %16859 = OpVectorShuffle %v2uint %14113 %14113 2 3 + %14176 = OpBitcast %v2float %16859 + %7040 = OpCompositeExtract %float %14176 0 + %13422 = OpCompositeExtract %float %14176 1 + %17020 = OpCompositeConstruct %v4float %7040 %13422 %float_0 %float_0 + %16860 = OpVectorShuffle %v2uint %11214 %11214 0 1 + %14177 = OpBitcast %v2float %16860 + %7041 = OpCompositeExtract %float %14177 0 + %13423 = OpCompositeExtract %float %14177 1 + %17021 = OpCompositeConstruct %v4float %7041 %13423 %float_0 %float_0 + %16861 = OpVectorShuffle %v2uint %11214 %11214 2 3 + %14178 = OpBitcast %v2float %16861 + %7042 = OpCompositeExtract %float %14178 0 + %16649 = OpCompositeExtract %float %14178 1 + %9042 = OpCompositeConstruct %v4float %7042 %16649 %float_0 %float_0 + OpBranch %20262 + %20262 = OpLabel + %11179 = OpPhi %v4float %9042 %20311 %17251 %8537 %9041 %8246 + %14348 = OpPhi %v4float %17021 %20311 %25238 %8537 %14615 %8246 + %15232 = OpPhi %v4float %17020 %20311 %25237 %8537 %14614 %8246 + %14521 = OpPhi %v4float %17019 %20311 %25236 %8537 %14613 %8246 + OpBranch %21264 + %21264 = OpLabel + %11180 = OpPhi %v4float %11179 %20262 %11178 %16225 + %14349 = OpPhi %v4float %14348 %20262 %14347 %16225 + %12949 = OpPhi %v4float %15232 %20262 %15231 %16225 + %13946 = OpPhi %v4float %14521 %20262 %14520 %16225 + %17241 = OpFAdd %v4float %8403 %13946 + %23297 = OpFAdd %v4float %13804 %12949 + %8082 = OpFAdd %v4float %14346 %14349 + %20755 = OpFAdd %v4float %11177 %11180 + %14461 = OpUGreaterThanEqual %bool %16205 %uint_6 + OpSelectionMerge %24264 DontFlatten + OpBranchConditional %14461 %9905 %24264 + %9905 = OpLabel + %14258 = OpShiftLeftLogical %uint %uint_1 %9130 + %12090 = OpFMul %float %11052 %float_0_25 + %20988 = OpIAdd %uint %23256 %14258 + OpSelectionMerge %21265 DontFlatten + OpBranchConditional %23279 %15207 %16571 + %16571 = OpLabel + %19167 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20299 DontFlatten + OpBranchConditional %19167 %9767 %12133 + %12133 = OpLabel + %19411 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23883 = OpLoad %uint %19411 + %11717 = OpIAdd %uint %20988 %6555 + %6479 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11717 + %24161 = OpLoad %uint %6479 + %6240 = OpIMul %uint %uint_2 %6555 + %8359 = OpIAdd %uint %20988 %6240 + %15311 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8359 + %24162 = OpLoad %uint %15311 + %6241 = OpIMul %uint %uint_3 %6555 + %8360 = OpIAdd %uint %20988 %6241 + %14323 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8360 + %16387 = OpLoad %uint %14323 + %20788 = OpCompositeConstruct %v4uint %23883 %24161 %24162 %16387 + OpBranch %20299 + %9767 = OpLabel + %21833 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23884 = OpLoad %uint %21833 + %11718 = OpIAdd %uint %20988 %uint_1 + %6415 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11718 + %23672 = OpLoad %uint %6415 + %11719 = OpIAdd %uint %20988 %uint_2 + %6416 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11719 + %23673 = OpLoad %uint %6416 + %11720 = OpIAdd %uint %20988 %uint_3 + %24568 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11720 + %16388 = OpLoad %uint %24568 + %20789 = OpCompositeConstruct %v4uint %23884 %23672 %23673 %16388 + OpBranch %20299 + %20299 = OpLabel + %10945 = OpPhi %v4uint %20789 %9767 %20788 %12133 + OpSelectionMerge %16226 None + OpSwitch %8576 %19453 0 %14587 1 %14587 2 %7359 10 %7359 3 %7358 12 %7358 4 %8192 6 %8247 + %8247 = OpLabel + %24410 = OpCompositeExtract %uint %10945 0 + %24683 = OpExtInst %v2float %1 UnpackHalf2x16 %24410 + %10098 = OpCompositeExtract %float %24683 0 + %17490 = OpCompositeExtract %float %24683 1 + %14616 = OpCompositeConstruct %v4float %10098 %17490 %float_0 %float_0 + %17286 = OpCompositeExtract %uint %10945 1 + %18039 = OpExtInst %v2float %1 UnpackHalf2x16 %17286 + %10099 = OpCompositeExtract %float %18039 0 + %17491 = OpCompositeExtract %float %18039 1 + %14617 = OpCompositeConstruct %v4float %10099 %17491 %float_0 %float_0 + %17287 = OpCompositeExtract %uint %10945 2 + %18040 = OpExtInst %v2float %1 UnpackHalf2x16 %17287 + %10100 = OpCompositeExtract %float %18040 0 + %17492 = OpCompositeExtract %float %18040 1 + %14618 = OpCompositeConstruct %v4float %10100 %17492 %float_0 %float_0 + %17288 = OpCompositeExtract %uint %10945 3 + %18041 = OpExtInst %v2float %1 UnpackHalf2x16 %17288 + %10109 = OpCompositeExtract %float %18041 0 + %20674 = OpCompositeExtract %float %18041 1 + %9043 = OpCompositeConstruct %v4float %10109 %20674 %float_0 %float_0 + OpBranch %16226 + %8192 = OpLabel + %12431 = OpCompositeExtract %uint %10945 0 + %22687 = OpBitcast %int %12431 + %18216 = OpCompositeConstruct %v2int %22687 %22687 + %18357 = OpShiftLeftLogical %v2int %18216 %1959 + %13343 = OpShiftRightArithmetic %v2int %18357 %2151 + %10927 = OpConvertSToF %v2float %13343 + %18255 = OpVectorTimesScalar %v2float %10927 %float_0_000976592302 + %24078 = OpExtInst %v2float %1 FMax %73 %18255 + %24338 = OpCompositeExtract %float %24078 0 + %15578 = OpCompositeExtract %float %24078 1 + %16676 = OpCompositeConstruct %v4float %24338 %15578 %float_0 %float_0 + %19528 = OpCompositeExtract %uint %10945 1 + %16039 = OpBitcast %int %19528 + %18217 = OpCompositeConstruct %v2int %16039 %16039 + %18358 = OpShiftLeftLogical %v2int %18217 %1959 + %13344 = OpShiftRightArithmetic %v2int %18358 %2151 + %10928 = OpConvertSToF %v2float %13344 + %18256 = OpVectorTimesScalar %v2float %10928 %float_0_000976592302 + %24079 = OpExtInst %v2float %1 FMax %73 %18256 + %24339 = OpCompositeExtract %float %24079 0 + %15579 = OpCompositeExtract %float %24079 1 + %16677 = OpCompositeConstruct %v4float %24339 %15579 %float_0 %float_0 + %19529 = OpCompositeExtract %uint %10945 2 + %16040 = OpBitcast %int %19529 + %18218 = OpCompositeConstruct %v2int %16040 %16040 + %18359 = OpShiftLeftLogical %v2int %18218 %1959 + %13345 = OpShiftRightArithmetic %v2int %18359 %2151 + %10929 = OpConvertSToF %v2float %13345 + %18257 = OpVectorTimesScalar %v2float %10929 %float_0_000976592302 + %24080 = OpExtInst %v2float %1 FMax %73 %18257 + %24340 = OpCompositeExtract %float %24080 0 + %15580 = OpCompositeExtract %float %24080 1 + %16678 = OpCompositeConstruct %v4float %24340 %15580 %float_0 %float_0 + %19530 = OpCompositeExtract %uint %10945 3 + %16041 = OpBitcast %int %19530 + %18219 = OpCompositeConstruct %v2int %16041 %16041 + %18360 = OpShiftLeftLogical %v2int %18219 %1959 + %13346 = OpShiftRightArithmetic %v2int %18360 %2151 + %10930 = OpConvertSToF %v2float %13346 + %18258 = OpVectorTimesScalar %v2float %10930 %float_0_000976592302 + %24081 = OpExtInst %v2float %1 FMax %73 %18258 + %24341 = OpCompositeExtract %float %24081 0 + %18766 = OpCompositeExtract %float %24081 1 + %9044 = OpCompositeConstruct %v4float %24341 %18766 %float_0 %float_0 + OpBranch %16226 + %7358 = OpLabel + %22211 = OpCompositeExtract %uint %10945 0 + %20240 = OpCompositeConstruct %v3uint %22211 %22211 %22211 + %11031 = OpShiftRightLogical %v3uint %20240 %2996 + %24046 = OpBitwiseAnd %v3uint %11031 %261 + %18596 = OpBitwiseAnd %v3uint %24046 %1126 + %23448 = OpShiftRightLogical %v3uint %24046 %2828 + %16593 = OpIEqual %v3bool %23448 %2578 + %11347 = OpExtInst %v3int %1 FindUMsb %18596 + %10781 = OpBitcast %v3uint %11347 + %6274 = OpISub %v3uint %2828 %10781 + %8728 = OpIAdd %v3uint %10781 %2360 + %10359 = OpSelect %v3uint %16593 %8728 %23448 + %23261 = OpShiftLeftLogical %v3uint %18596 %6274 + %18850 = OpBitwiseAnd %v3uint %23261 %1126 + %10931 = OpSelect %v3uint %16593 %18850 %18596 + %24577 = OpIAdd %v3uint %10359 %1018 + %20359 = OpShiftLeftLogical %v3uint %24577 %393 + %16302 = OpShiftLeftLogical %v3uint %10931 %141 + %22404 = OpBitwiseOr %v3uint %20359 %16302 + %13832 = OpIEqual %v3bool %24046 %2578 + %16970 = OpSelect %v3uint %13832 %2578 %22404 + %10711 = OpBitcast %v3float %16970 + %19372 = OpShiftRightLogical %uint %22211 %uint_30 + %18454 = OpConvertUToF %float %19372 + %15911 = OpFMul %float %18454 %float_0_333333343 + %21450 = OpCompositeExtract %float %10711 0 + %10845 = OpCompositeExtract %float %10711 1 + %7839 = OpCompositeExtract %float %10711 2 + %15840 = OpCompositeConstruct %v4float %21450 %10845 %7839 %15911 + %10235 = OpCompositeExtract %uint %10945 1 + %13588 = OpCompositeConstruct %v3uint %10235 %10235 %10235 + %11032 = OpShiftRightLogical %v3uint %13588 %2996 + %24047 = OpBitwiseAnd %v3uint %11032 %261 + %18597 = OpBitwiseAnd %v3uint %24047 %1126 + %23449 = OpShiftRightLogical %v3uint %24047 %2828 + %16594 = OpIEqual %v3bool %23449 %2578 + %11348 = OpExtInst %v3int %1 FindUMsb %18597 + %10782 = OpBitcast %v3uint %11348 + %6275 = OpISub %v3uint %2828 %10782 + %8729 = OpIAdd %v3uint %10782 %2360 + %10360 = OpSelect %v3uint %16594 %8729 %23449 + %23262 = OpShiftLeftLogical %v3uint %18597 %6275 + %18851 = OpBitwiseAnd %v3uint %23262 %1126 + %10932 = OpSelect %v3uint %16594 %18851 %18597 + %24578 = OpIAdd %v3uint %10360 %1018 + %20360 = OpShiftLeftLogical %v3uint %24578 %393 + %16303 = OpShiftLeftLogical %v3uint %10932 %141 + %22405 = OpBitwiseOr %v3uint %20360 %16303 + %13833 = OpIEqual %v3bool %24047 %2578 + %16971 = OpSelect %v3uint %13833 %2578 %22405 + %10712 = OpBitcast %v3float %16971 + %19373 = OpShiftRightLogical %uint %10235 %uint_30 + %18455 = OpConvertUToF %float %19373 + %15912 = OpFMul %float %18455 %float_0_333333343 + %21451 = OpCompositeExtract %float %10712 0 + %10846 = OpCompositeExtract %float %10712 1 + %7840 = OpCompositeExtract %float %10712 2 + %15841 = OpCompositeConstruct %v4float %21451 %10846 %7840 %15912 + %10236 = OpCompositeExtract %uint %10945 2 + %13589 = OpCompositeConstruct %v3uint %10236 %10236 %10236 + %11033 = OpShiftRightLogical %v3uint %13589 %2996 + %24048 = OpBitwiseAnd %v3uint %11033 %261 + %18606 = OpBitwiseAnd %v3uint %24048 %1126 + %23450 = OpShiftRightLogical %v3uint %24048 %2828 + %16595 = OpIEqual %v3bool %23450 %2578 + %11349 = OpExtInst %v3int %1 FindUMsb %18606 + %10783 = OpBitcast %v3uint %11349 + %6276 = OpISub %v3uint %2828 %10783 + %8730 = OpIAdd %v3uint %10783 %2360 + %10361 = OpSelect %v3uint %16595 %8730 %23450 + %23263 = OpShiftLeftLogical %v3uint %18606 %6276 + %18852 = OpBitwiseAnd %v3uint %23263 %1126 + %10933 = OpSelect %v3uint %16595 %18852 %18606 + %24579 = OpIAdd %v3uint %10361 %1018 + %20361 = OpShiftLeftLogical %v3uint %24579 %393 + %16304 = OpShiftLeftLogical %v3uint %10933 %141 + %22406 = OpBitwiseOr %v3uint %20361 %16304 + %13834 = OpIEqual %v3bool %24048 %2578 + %16972 = OpSelect %v3uint %13834 %2578 %22406 + %10713 = OpBitcast %v3float %16972 + %19374 = OpShiftRightLogical %uint %10236 %uint_30 + %18456 = OpConvertUToF %float %19374 + %15913 = OpFMul %float %18456 %float_0_333333343 + %21452 = OpCompositeExtract %float %10713 0 + %10847 = OpCompositeExtract %float %10713 1 + %7841 = OpCompositeExtract %float %10713 2 + %15842 = OpCompositeConstruct %v4float %21452 %10847 %7841 %15913 + %10237 = OpCompositeExtract %uint %10945 3 + %13590 = OpCompositeConstruct %v3uint %10237 %10237 %10237 + %11034 = OpShiftRightLogical %v3uint %13590 %2996 + %24049 = OpBitwiseAnd %v3uint %11034 %261 + %18607 = OpBitwiseAnd %v3uint %24049 %1126 + %23451 = OpShiftRightLogical %v3uint %24049 %2828 + %16596 = OpIEqual %v3bool %23451 %2578 + %11350 = OpExtInst %v3int %1 FindUMsb %18607 + %10784 = OpBitcast %v3uint %11350 + %6277 = OpISub %v3uint %2828 %10784 + %8731 = OpIAdd %v3uint %10784 %2360 + %10362 = OpSelect %v3uint %16596 %8731 %23451 + %23264 = OpShiftLeftLogical %v3uint %18607 %6277 + %18853 = OpBitwiseAnd %v3uint %23264 %1126 + %10934 = OpSelect %v3uint %16596 %18853 %18607 + %24580 = OpIAdd %v3uint %10362 %1018 + %20362 = OpShiftLeftLogical %v3uint %24580 %393 + %16305 = OpShiftLeftLogical %v3uint %10934 %141 + %22407 = OpBitwiseOr %v3uint %20362 %16305 + %13835 = OpIEqual %v3bool %24049 %2578 + %16973 = OpSelect %v3uint %13835 %2578 %22407 + %10714 = OpBitcast %v3float %16973 + %19375 = OpShiftRightLogical %uint %10237 %uint_30 + %18457 = OpConvertUToF %float %19375 + %15914 = OpFMul %float %18457 %float_0_333333343 + %21453 = OpCompositeExtract %float %10714 0 + %10848 = OpCompositeExtract %float %10714 1 + %11035 = OpCompositeExtract %float %10714 2 + %9045 = OpCompositeConstruct %v4float %21453 %10848 %11035 %15914 + OpBranch %16226 + %7359 = OpLabel + %22212 = OpCompositeExtract %uint %10945 0 + %20241 = OpCompositeConstruct %v4uint %22212 %22212 %22212 %22212 + %9384 = OpShiftRightLogical %v4uint %20241 %845 + %18867 = OpBitwiseAnd %v4uint %9384 %635 + %15549 = OpConvertUToF %v4float %18867 + %16694 = OpFMul %v4float %15549 %2798 + %23768 = OpCompositeExtract %uint %10945 1 + %20819 = OpCompositeConstruct %v4uint %23768 %23768 %23768 %23768 + %9385 = OpShiftRightLogical %v4uint %20819 %845 + %18868 = OpBitwiseAnd %v4uint %9385 %635 + %15550 = OpConvertUToF %v4float %18868 + %16695 = OpFMul %v4float %15550 %2798 + %23769 = OpCompositeExtract %uint %10945 2 + %20820 = OpCompositeConstruct %v4uint %23769 %23769 %23769 %23769 + %9386 = OpShiftRightLogical %v4uint %20820 %845 + %18869 = OpBitwiseAnd %v4uint %9386 %635 + %15551 = OpConvertUToF %v4float %18869 + %16696 = OpFMul %v4float %15551 %2798 + %23770 = OpCompositeExtract %uint %10945 3 + %20821 = OpCompositeConstruct %v4uint %23770 %23770 %23770 %23770 + %9387 = OpShiftRightLogical %v4uint %20821 %845 + %18870 = OpBitwiseAnd %v4uint %9387 %635 + %18737 = OpConvertUToF %v4float %18870 + %9889 = OpFMul %v4float %18737 %2798 + OpBranch %16226 + %14587 = OpLabel + %22213 = OpCompositeExtract %uint %10945 0 + %20242 = OpCompositeConstruct %v4uint %22213 %22213 %22213 %22213 + %9388 = OpShiftRightLogical %v4uint %20242 %653 + %19038 = OpBitwiseAnd %v4uint %9388 %1611 + %13994 = OpConvertUToF %v4float %19038 + %19241 = OpVectorTimesScalar %v4float %13994 %float_0_00392156886 + %8613 = OpCompositeExtract %uint %10945 1 + %24849 = OpCompositeConstruct %v4uint %8613 %8613 %8613 %8613 + %9389 = OpShiftRightLogical %v4uint %24849 %653 + %19039 = OpBitwiseAnd %v4uint %9389 %1611 + %13995 = OpConvertUToF %v4float %19039 + %19242 = OpVectorTimesScalar %v4float %13995 %float_0_00392156886 + %8614 = OpCompositeExtract %uint %10945 2 + %24850 = OpCompositeConstruct %v4uint %8614 %8614 %8614 %8614 + %9390 = OpShiftRightLogical %v4uint %24850 %653 + %19040 = OpBitwiseAnd %v4uint %9390 %1611 + %13996 = OpConvertUToF %v4float %19040 + %19243 = OpVectorTimesScalar %v4float %13996 %float_0_00392156886 + %8615 = OpCompositeExtract %uint %10945 3 + %24851 = OpCompositeConstruct %v4uint %8615 %8615 %8615 %8615 + %9391 = OpShiftRightLogical %v4uint %24851 %653 + %19041 = OpBitwiseAnd %v4uint %9391 %1611 + %17180 = OpConvertUToF %v4float %19041 + %12436 = OpVectorTimesScalar %v4float %17180 %float_0_00392156886 + OpBranch %16226 + %19453 = OpLabel + %12432 = OpCompositeExtract %uint %10945 0 + %20464 = OpBitcast %float %12432 + %17212 = OpCompositeConstruct %v2float %20464 %float_0 + %11670 = OpVectorShuffle %v4float %17212 %17212 0 1 1 1 + %22199 = OpCompositeExtract %uint %10945 1 + %16238 = OpBitcast %float %22199 + %17213 = OpCompositeConstruct %v2float %16238 %float_0 + %11671 = OpVectorShuffle %v4float %17213 %17213 0 1 1 1 + %22200 = OpCompositeExtract %uint %10945 2 + %16239 = OpBitcast %float %22200 + %17214 = OpCompositeConstruct %v2float %16239 %float_0 + %11672 = OpVectorShuffle %v4float %17214 %17214 0 1 1 1 + %22201 = OpCompositeExtract %uint %10945 3 + %16240 = OpBitcast %float %22201 + %20400 = OpCompositeConstruct %v2float %16240 %float_0 + %23100 = OpVectorShuffle %v4float %20400 %20400 0 1 1 1 + OpBranch %16226 + %16226 = OpLabel + %11181 = OpPhi %v4float %23100 %19453 %12436 %14587 %9889 %7359 %9045 %7358 %9044 %8192 %9043 %8247 + %14350 = OpPhi %v4float %11672 %19453 %19243 %14587 %16696 %7359 %15842 %7358 %16678 %8192 %14618 %8247 + %15237 = OpPhi %v4float %11671 %19453 %19242 %14587 %16695 %7359 %15841 %7358 %16677 %8192 %14617 %8247 + %14522 = OpPhi %v4float %11670 %19453 %19241 %14587 %16694 %7359 %15840 %7358 %16676 %8192 %14616 %8247 + OpBranch %21265 + %15207 = OpLabel + %21586 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20263 DontFlatten + OpBranchConditional %21586 %9768 %12134 + %12134 = OpLabel + %19412 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23885 = OpLoad %uint %19412 + %11721 = OpIAdd %uint %20988 %uint_1 + %6417 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11721 + %23674 = OpLoad %uint %6417 + %11722 = OpIAdd %uint %20988 %6555 + %6418 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11722 + %23675 = OpLoad %uint %6418 + %11723 = OpIAdd %uint %11722 %uint_1 + %24581 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11723 + %14158 = OpLoad %uint %24581 + %19673 = OpCompositeConstruct %v4uint %23885 %23674 %23675 %14158 + %17050 = OpIMul %uint %uint_2 %6555 + %13997 = OpIAdd %uint %20988 %17050 + %15238 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13997 + %23676 = OpLoad %uint %15238 + %11724 = OpIAdd %uint %13997 %uint_1 + %6480 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11724 + %24163 = OpLoad %uint %6480 + %6242 = OpIMul %uint %uint_3 %6555 + %8361 = OpIAdd %uint %20988 %6242 + %15239 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8361 + %23677 = OpLoad %uint %15239 + %11725 = OpIAdd %uint %8361 %uint_1 + %24582 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11725 + %16389 = OpLoad %uint %24582 + %20790 = OpCompositeConstruct %v4uint %23676 %24163 %23677 %16389 + OpBranch %20263 + %9768 = OpLabel + %21834 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23886 = OpLoad %uint %21834 + %11726 = OpIAdd %uint %20988 %uint_1 + %6419 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11726 + %23678 = OpLoad %uint %6419 + %11727 = OpIAdd %uint %20988 %uint_2 + %6420 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11727 + %23679 = OpLoad %uint %6420 + %11728 = OpIAdd %uint %20988 %uint_3 + %24583 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11728 + %14082 = OpLoad %uint %24583 + %19168 = OpCompositeConstruct %v4uint %23886 %23678 %23679 %14082 + %22503 = OpIAdd %uint %20988 %uint_4 + %24653 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22503 + %23680 = OpLoad %uint %24653 + %11729 = OpIAdd %uint %20988 %uint_5 + %6421 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11729 + %23681 = OpLoad %uint %6421 + %11730 = OpIAdd %uint %20988 %uint_6 + %6422 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11730 + %23682 = OpLoad %uint %6422 + %11731 = OpIAdd %uint %20988 %uint_7 + %24584 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11731 + %16390 = OpLoad %uint %24584 + %20791 = OpCompositeConstruct %v4uint %23680 %23681 %23682 %16390 + OpBranch %20263 + %20263 = OpLabel + %11215 = OpPhi %v4uint %20791 %9768 %20790 %12134 + %14114 = OpPhi %v4uint %19168 %9768 %19673 %12134 + OpSelectionMerge %20264 None + OpSwitch %8576 %20312 5 %8538 7 %8248 + %8248 = OpLabel + %24411 = OpCompositeExtract %uint %14114 0 + %24684 = OpExtInst %v2float %1 UnpackHalf2x16 %24411 + %10110 = OpCompositeExtract %float %24684 0 + %16064 = OpCompositeExtract %float %24684 1 + %17033 = OpCompositeExtract %uint %14114 1 + %15613 = OpExtInst %v2float %1 UnpackHalf2x16 %17033 + %10111 = OpCompositeExtract %float %15613 0 + %17493 = OpCompositeExtract %float %15613 1 + %14619 = OpCompositeConstruct %v4float %10110 %16064 %10111 %17493 + %17289 = OpCompositeExtract %uint %14114 2 + %18042 = OpExtInst %v2float %1 UnpackHalf2x16 %17289 + %10112 = OpCompositeExtract %float %18042 0 + %16065 = OpCompositeExtract %float %18042 1 + %17034 = OpCompositeExtract %uint %14114 3 + %15614 = OpExtInst %v2float %1 UnpackHalf2x16 %17034 + %10113 = OpCompositeExtract %float %15614 0 + %17494 = OpCompositeExtract %float %15614 1 + %14620 = OpCompositeConstruct %v4float %10112 %16065 %10113 %17494 + %17290 = OpCompositeExtract %uint %11215 0 + %18043 = OpExtInst %v2float %1 UnpackHalf2x16 %17290 + %10114 = OpCompositeExtract %float %18043 0 + %16066 = OpCompositeExtract %float %18043 1 + %17035 = OpCompositeExtract %uint %11215 1 + %15615 = OpExtInst %v2float %1 UnpackHalf2x16 %17035 + %10115 = OpCompositeExtract %float %15615 0 + %17495 = OpCompositeExtract %float %15615 1 + %14621 = OpCompositeConstruct %v4float %10114 %16066 %10115 %17495 + %17291 = OpCompositeExtract %uint %11215 2 + %18044 = OpExtInst %v2float %1 UnpackHalf2x16 %17291 + %10116 = OpCompositeExtract %float %18044 0 + %16067 = OpCompositeExtract %float %18044 1 + %17036 = OpCompositeExtract %uint %11215 3 + %15616 = OpExtInst %v2float %1 UnpackHalf2x16 %17036 + %10117 = OpCompositeExtract %float %15616 0 + %20675 = OpCompositeExtract %float %15616 1 + %9046 = OpCompositeConstruct %v4float %10116 %16067 %10117 %20675 + OpBranch %20264 + %8538 = OpLabel + %9725 = OpVectorShuffle %v2uint %14114 %14114 0 1 + %23358 = OpBitcast %v2int %9725 + %24790 = OpVectorShuffle %v4int %23358 %23358 0 0 1 1 + %18608 = OpShiftLeftLogical %v4int %24790 %290 + %15765 = OpShiftRightArithmetic %v4int %18608 %770 + %10935 = OpConvertSToF %v4float %15765 + %18220 = OpVectorTimesScalar %v4float %10935 %float_0_000976592302 + %25239 = OpExtInst %v4float %1 FMax %1284 %18220 + %14193 = OpVectorShuffle %v2uint %14114 %14114 2 3 + %9413 = OpBitcast %v2int %14193 + %24791 = OpVectorShuffle %v4int %9413 %9413 0 0 1 1 + %18609 = OpShiftLeftLogical %v4int %24791 %290 + %15766 = OpShiftRightArithmetic %v4int %18609 %770 + %10936 = OpConvertSToF %v4float %15766 + %18221 = OpVectorTimesScalar %v4float %10936 %float_0_000976592302 + %25240 = OpExtInst %v4float %1 FMax %1284 %18221 + %14194 = OpVectorShuffle %v2uint %11215 %11215 0 1 + %9414 = OpBitcast %v2int %14194 + %24792 = OpVectorShuffle %v4int %9414 %9414 0 0 1 1 + %18610 = OpShiftLeftLogical %v4int %24792 %290 + %15767 = OpShiftRightArithmetic %v4int %18610 %770 + %10937 = OpConvertSToF %v4float %15767 + %18222 = OpVectorTimesScalar %v4float %10937 %float_0_000976592302 + %25241 = OpExtInst %v4float %1 FMax %1284 %18222 + %14195 = OpVectorShuffle %v2uint %11215 %11215 2 3 + %9415 = OpBitcast %v2int %14195 + %24793 = OpVectorShuffle %v4int %9415 %9415 0 0 1 1 + %18611 = OpShiftLeftLogical %v4int %24793 %290 + %15768 = OpShiftRightArithmetic %v4int %18611 %770 + %10938 = OpConvertSToF %v4float %15768 + %21441 = OpVectorTimesScalar %v4float %10938 %float_0_000976592302 + %17252 = OpExtInst %v4float %1 FMax %1284 %21441 + OpBranch %20264 + %20312 = OpLabel + %9769 = OpVectorShuffle %v2uint %14114 %14114 0 1 + %20827 = OpBitcast %v2float %9769 + %7043 = OpCompositeExtract %float %20827 0 + %13424 = OpCompositeExtract %float %20827 1 + %17022 = OpCompositeConstruct %v4float %7043 %13424 %float_0 %float_0 + %16862 = OpVectorShuffle %v2uint %14114 %14114 2 3 + %14179 = OpBitcast %v2float %16862 + %7044 = OpCompositeExtract %float %14179 0 + %13425 = OpCompositeExtract %float %14179 1 + %17023 = OpCompositeConstruct %v4float %7044 %13425 %float_0 %float_0 + %16863 = OpVectorShuffle %v2uint %11215 %11215 0 1 + %14180 = OpBitcast %v2float %16863 + %7045 = OpCompositeExtract %float %14180 0 + %13426 = OpCompositeExtract %float %14180 1 + %17024 = OpCompositeConstruct %v4float %7045 %13426 %float_0 %float_0 + %16864 = OpVectorShuffle %v2uint %11215 %11215 2 3 + %14181 = OpBitcast %v2float %16864 + %7046 = OpCompositeExtract %float %14181 0 + %16650 = OpCompositeExtract %float %14181 1 + %9047 = OpCompositeConstruct %v4float %7046 %16650 %float_0 %float_0 + OpBranch %20264 + %20264 = OpLabel + %11182 = OpPhi %v4float %9047 %20312 %17252 %8538 %9046 %8248 + %14351 = OpPhi %v4float %17024 %20312 %25241 %8538 %14621 %8248 + %15240 = OpPhi %v4float %17023 %20312 %25240 %8538 %14620 %8248 + %14523 = OpPhi %v4float %17022 %20312 %25239 %8538 %14619 %8248 + OpBranch %21265 + %21265 = OpLabel + %11183 = OpPhi %v4float %11182 %20264 %11181 %16226 + %14352 = OpPhi %v4float %14351 %20264 %14350 %16226 + %12950 = OpPhi %v4float %15240 %20264 %15237 %16226 + %13947 = OpPhi %v4float %14523 %20264 %14522 %16226 + %17242 = OpFAdd %v4float %17241 %13947 + %23298 = OpFAdd %v4float %23297 %12950 + %7208 = OpFAdd %v4float %8082 %14352 + %9642 = OpFAdd %v4float %20755 %11183 + %16376 = OpIAdd %uint %24184 %14258 + OpSelectionMerge %21266 DontFlatten + OpBranchConditional %23279 %15208 %16572 + %16572 = OpLabel + %19169 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20300 DontFlatten + OpBranchConditional %19169 %9770 %12135 + %12135 = OpLabel + %19413 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23887 = OpLoad %uint %19413 + %11732 = OpIAdd %uint %16376 %6555 + %6481 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11732 + %24164 = OpLoad %uint %6481 + %6243 = OpIMul %uint %uint_2 %6555 + %8362 = OpIAdd %uint %16376 %6243 + %15312 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8362 + %24165 = OpLoad %uint %15312 + %6244 = OpIMul %uint %uint_3 %6555 + %8363 = OpIAdd %uint %16376 %6244 + %14324 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8363 + %16391 = OpLoad %uint %14324 + %20792 = OpCompositeConstruct %v4uint %23887 %24164 %24165 %16391 + OpBranch %20300 + %9770 = OpLabel + %21835 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23888 = OpLoad %uint %21835 + %11733 = OpIAdd %uint %16376 %uint_1 + %6423 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11733 + %23683 = OpLoad %uint %6423 + %11734 = OpIAdd %uint %16376 %uint_2 + %6424 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11734 + %23684 = OpLoad %uint %6424 + %11735 = OpIAdd %uint %16376 %uint_3 + %24585 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11735 + %16392 = OpLoad %uint %24585 + %20793 = OpCompositeConstruct %v4uint %23888 %23683 %23684 %16392 + OpBranch %20300 + %20300 = OpLabel + %10946 = OpPhi %v4uint %20793 %9770 %20792 %12135 + OpSelectionMerge %16227 None + OpSwitch %8576 %19454 0 %14588 1 %14588 2 %7361 10 %7361 3 %7360 12 %7360 4 %8193 6 %8249 + %8249 = OpLabel + %24412 = OpCompositeExtract %uint %10946 0 + %24685 = OpExtInst %v2float %1 UnpackHalf2x16 %24412 + %10118 = OpCompositeExtract %float %24685 0 + %17496 = OpCompositeExtract %float %24685 1 + %14622 = OpCompositeConstruct %v4float %10118 %17496 %float_0 %float_0 + %17292 = OpCompositeExtract %uint %10946 1 + %18045 = OpExtInst %v2float %1 UnpackHalf2x16 %17292 + %10119 = OpCompositeExtract %float %18045 0 + %17497 = OpCompositeExtract %float %18045 1 + %14623 = OpCompositeConstruct %v4float %10119 %17497 %float_0 %float_0 + %17293 = OpCompositeExtract %uint %10946 2 + %18046 = OpExtInst %v2float %1 UnpackHalf2x16 %17293 + %10120 = OpCompositeExtract %float %18046 0 + %17498 = OpCompositeExtract %float %18046 1 + %14624 = OpCompositeConstruct %v4float %10120 %17498 %float_0 %float_0 + %17294 = OpCompositeExtract %uint %10946 3 + %18047 = OpExtInst %v2float %1 UnpackHalf2x16 %17294 + %10121 = OpCompositeExtract %float %18047 0 + %20676 = OpCompositeExtract %float %18047 1 + %9048 = OpCompositeConstruct %v4float %10121 %20676 %float_0 %float_0 + OpBranch %16227 + %8193 = OpLabel + %12433 = OpCompositeExtract %uint %10946 0 + %22688 = OpBitcast %int %12433 + %18223 = OpCompositeConstruct %v2int %22688 %22688 + %18361 = OpShiftLeftLogical %v2int %18223 %1959 + %13347 = OpShiftRightArithmetic %v2int %18361 %2151 + %10939 = OpConvertSToF %v2float %13347 + %18259 = OpVectorTimesScalar %v2float %10939 %float_0_000976592302 + %24082 = OpExtInst %v2float %1 FMax %73 %18259 + %24342 = OpCompositeExtract %float %24082 0 + %15581 = OpCompositeExtract %float %24082 1 + %16679 = OpCompositeConstruct %v4float %24342 %15581 %float_0 %float_0 + %19531 = OpCompositeExtract %uint %10946 1 + %16042 = OpBitcast %int %19531 + %18224 = OpCompositeConstruct %v2int %16042 %16042 + %18362 = OpShiftLeftLogical %v2int %18224 %1959 + %13348 = OpShiftRightArithmetic %v2int %18362 %2151 + %10940 = OpConvertSToF %v2float %13348 + %18260 = OpVectorTimesScalar %v2float %10940 %float_0_000976592302 + %24083 = OpExtInst %v2float %1 FMax %73 %18260 + %24343 = OpCompositeExtract %float %24083 0 + %15582 = OpCompositeExtract %float %24083 1 + %16680 = OpCompositeConstruct %v4float %24343 %15582 %float_0 %float_0 + %19532 = OpCompositeExtract %uint %10946 2 + %16043 = OpBitcast %int %19532 + %18225 = OpCompositeConstruct %v2int %16043 %16043 + %18363 = OpShiftLeftLogical %v2int %18225 %1959 + %13349 = OpShiftRightArithmetic %v2int %18363 %2151 + %10941 = OpConvertSToF %v2float %13349 + %18261 = OpVectorTimesScalar %v2float %10941 %float_0_000976592302 + %24084 = OpExtInst %v2float %1 FMax %73 %18261 + %24344 = OpCompositeExtract %float %24084 0 + %15583 = OpCompositeExtract %float %24084 1 + %16681 = OpCompositeConstruct %v4float %24344 %15583 %float_0 %float_0 + %19533 = OpCompositeExtract %uint %10946 3 + %16044 = OpBitcast %int %19533 + %18226 = OpCompositeConstruct %v2int %16044 %16044 + %18364 = OpShiftLeftLogical %v2int %18226 %1959 + %13350 = OpShiftRightArithmetic %v2int %18364 %2151 + %10942 = OpConvertSToF %v2float %13350 + %18262 = OpVectorTimesScalar %v2float %10942 %float_0_000976592302 + %24085 = OpExtInst %v2float %1 FMax %73 %18262 + %24345 = OpCompositeExtract %float %24085 0 + %18767 = OpCompositeExtract %float %24085 1 + %9049 = OpCompositeConstruct %v4float %24345 %18767 %float_0 %float_0 + OpBranch %16227 + %7360 = OpLabel + %22214 = OpCompositeExtract %uint %10946 0 + %20243 = OpCompositeConstruct %v3uint %22214 %22214 %22214 + %11036 = OpShiftRightLogical %v3uint %20243 %2996 + %24050 = OpBitwiseAnd %v3uint %11036 %261 + %18612 = OpBitwiseAnd %v3uint %24050 %1126 + %23452 = OpShiftRightLogical %v3uint %24050 %2828 + %16597 = OpIEqual %v3bool %23452 %2578 + %11351 = OpExtInst %v3int %1 FindUMsb %18612 + %10785 = OpBitcast %v3uint %11351 + %6278 = OpISub %v3uint %2828 %10785 + %8732 = OpIAdd %v3uint %10785 %2360 + %10363 = OpSelect %v3uint %16597 %8732 %23452 + %23265 = OpShiftLeftLogical %v3uint %18612 %6278 + %18854 = OpBitwiseAnd %v3uint %23265 %1126 + %10947 = OpSelect %v3uint %16597 %18854 %18612 + %24586 = OpIAdd %v3uint %10363 %1018 + %20363 = OpShiftLeftLogical %v3uint %24586 %393 + %16306 = OpShiftLeftLogical %v3uint %10947 %141 + %22408 = OpBitwiseOr %v3uint %20363 %16306 + %13836 = OpIEqual %v3bool %24050 %2578 + %16974 = OpSelect %v3uint %13836 %2578 %22408 + %10715 = OpBitcast %v3float %16974 + %19376 = OpShiftRightLogical %uint %22214 %uint_30 + %18458 = OpConvertUToF %float %19376 + %15915 = OpFMul %float %18458 %float_0_333333343 + %21454 = OpCompositeExtract %float %10715 0 + %10849 = OpCompositeExtract %float %10715 1 + %7842 = OpCompositeExtract %float %10715 2 + %15843 = OpCompositeConstruct %v4float %21454 %10849 %7842 %15915 + %10238 = OpCompositeExtract %uint %10946 1 + %13591 = OpCompositeConstruct %v3uint %10238 %10238 %10238 + %11037 = OpShiftRightLogical %v3uint %13591 %2996 + %24051 = OpBitwiseAnd %v3uint %11037 %261 + %18613 = OpBitwiseAnd %v3uint %24051 %1126 + %23453 = OpShiftRightLogical %v3uint %24051 %2828 + %16598 = OpIEqual %v3bool %23453 %2578 + %11352 = OpExtInst %v3int %1 FindUMsb %18613 + %10786 = OpBitcast %v3uint %11352 + %6279 = OpISub %v3uint %2828 %10786 + %8733 = OpIAdd %v3uint %10786 %2360 + %10364 = OpSelect %v3uint %16598 %8733 %23453 + %23266 = OpShiftLeftLogical %v3uint %18613 %6279 + %18855 = OpBitwiseAnd %v3uint %23266 %1126 + %10948 = OpSelect %v3uint %16598 %18855 %18613 + %24587 = OpIAdd %v3uint %10364 %1018 + %20364 = OpShiftLeftLogical %v3uint %24587 %393 + %16307 = OpShiftLeftLogical %v3uint %10948 %141 + %22409 = OpBitwiseOr %v3uint %20364 %16307 + %13837 = OpIEqual %v3bool %24051 %2578 + %16975 = OpSelect %v3uint %13837 %2578 %22409 + %10716 = OpBitcast %v3float %16975 + %19377 = OpShiftRightLogical %uint %10238 %uint_30 + %18459 = OpConvertUToF %float %19377 + %15916 = OpFMul %float %18459 %float_0_333333343 + %21455 = OpCompositeExtract %float %10716 0 + %10850 = OpCompositeExtract %float %10716 1 + %7843 = OpCompositeExtract %float %10716 2 + %15844 = OpCompositeConstruct %v4float %21455 %10850 %7843 %15916 + %10239 = OpCompositeExtract %uint %10946 2 + %13592 = OpCompositeConstruct %v3uint %10239 %10239 %10239 + %11038 = OpShiftRightLogical %v3uint %13592 %2996 + %24052 = OpBitwiseAnd %v3uint %11038 %261 + %18614 = OpBitwiseAnd %v3uint %24052 %1126 + %23454 = OpShiftRightLogical %v3uint %24052 %2828 + %16599 = OpIEqual %v3bool %23454 %2578 + %11353 = OpExtInst %v3int %1 FindUMsb %18614 + %10787 = OpBitcast %v3uint %11353 + %6280 = OpISub %v3uint %2828 %10787 + %8734 = OpIAdd %v3uint %10787 %2360 + %10365 = OpSelect %v3uint %16599 %8734 %23454 + %23267 = OpShiftLeftLogical %v3uint %18614 %6280 + %18856 = OpBitwiseAnd %v3uint %23267 %1126 + %10949 = OpSelect %v3uint %16599 %18856 %18614 + %24588 = OpIAdd %v3uint %10365 %1018 + %20365 = OpShiftLeftLogical %v3uint %24588 %393 + %16308 = OpShiftLeftLogical %v3uint %10949 %141 + %22410 = OpBitwiseOr %v3uint %20365 %16308 + %13838 = OpIEqual %v3bool %24052 %2578 + %16976 = OpSelect %v3uint %13838 %2578 %22410 + %10717 = OpBitcast %v3float %16976 + %19378 = OpShiftRightLogical %uint %10239 %uint_30 + %18460 = OpConvertUToF %float %19378 + %15917 = OpFMul %float %18460 %float_0_333333343 + %21456 = OpCompositeExtract %float %10717 0 + %10851 = OpCompositeExtract %float %10717 1 + %7844 = OpCompositeExtract %float %10717 2 + %15845 = OpCompositeConstruct %v4float %21456 %10851 %7844 %15917 + %10240 = OpCompositeExtract %uint %10946 3 + %13593 = OpCompositeConstruct %v3uint %10240 %10240 %10240 + %11039 = OpShiftRightLogical %v3uint %13593 %2996 + %24053 = OpBitwiseAnd %v3uint %11039 %261 + %18615 = OpBitwiseAnd %v3uint %24053 %1126 + %23455 = OpShiftRightLogical %v3uint %24053 %2828 + %16600 = OpIEqual %v3bool %23455 %2578 + %11354 = OpExtInst %v3int %1 FindUMsb %18615 + %10788 = OpBitcast %v3uint %11354 + %6281 = OpISub %v3uint %2828 %10788 + %8735 = OpIAdd %v3uint %10788 %2360 + %10366 = OpSelect %v3uint %16600 %8735 %23455 + %23268 = OpShiftLeftLogical %v3uint %18615 %6281 + %18857 = OpBitwiseAnd %v3uint %23268 %1126 + %10950 = OpSelect %v3uint %16600 %18857 %18615 + %24589 = OpIAdd %v3uint %10366 %1018 + %20366 = OpShiftLeftLogical %v3uint %24589 %393 + %16309 = OpShiftLeftLogical %v3uint %10950 %141 + %22411 = OpBitwiseOr %v3uint %20366 %16309 + %13839 = OpIEqual %v3bool %24053 %2578 + %16977 = OpSelect %v3uint %13839 %2578 %22411 + %10718 = OpBitcast %v3float %16977 + %19379 = OpShiftRightLogical %uint %10240 %uint_30 + %18461 = OpConvertUToF %float %19379 + %15918 = OpFMul %float %18461 %float_0_333333343 + %21457 = OpCompositeExtract %float %10718 0 + %10852 = OpCompositeExtract %float %10718 1 + %11040 = OpCompositeExtract %float %10718 2 + %9050 = OpCompositeConstruct %v4float %21457 %10852 %11040 %15918 + OpBranch %16227 + %7361 = OpLabel + %22215 = OpCompositeExtract %uint %10946 0 + %20244 = OpCompositeConstruct %v4uint %22215 %22215 %22215 %22215 + %9392 = OpShiftRightLogical %v4uint %20244 %845 + %18871 = OpBitwiseAnd %v4uint %9392 %635 + %15552 = OpConvertUToF %v4float %18871 + %16697 = OpFMul %v4float %15552 %2798 + %23771 = OpCompositeExtract %uint %10946 1 + %20822 = OpCompositeConstruct %v4uint %23771 %23771 %23771 %23771 + %9393 = OpShiftRightLogical %v4uint %20822 %845 + %18872 = OpBitwiseAnd %v4uint %9393 %635 + %15553 = OpConvertUToF %v4float %18872 + %16698 = OpFMul %v4float %15553 %2798 + %23772 = OpCompositeExtract %uint %10946 2 + %20823 = OpCompositeConstruct %v4uint %23772 %23772 %23772 %23772 + %9394 = OpShiftRightLogical %v4uint %20823 %845 + %18873 = OpBitwiseAnd %v4uint %9394 %635 + %15554 = OpConvertUToF %v4float %18873 + %16699 = OpFMul %v4float %15554 %2798 + %23773 = OpCompositeExtract %uint %10946 3 + %20828 = OpCompositeConstruct %v4uint %23773 %23773 %23773 %23773 + %9395 = OpShiftRightLogical %v4uint %20828 %845 + %18874 = OpBitwiseAnd %v4uint %9395 %635 + %18738 = OpConvertUToF %v4float %18874 + %9890 = OpFMul %v4float %18738 %2798 + OpBranch %16227 + %14588 = OpLabel + %22216 = OpCompositeExtract %uint %10946 0 + %20245 = OpCompositeConstruct %v4uint %22216 %22216 %22216 %22216 + %9396 = OpShiftRightLogical %v4uint %20245 %653 + %19042 = OpBitwiseAnd %v4uint %9396 %1611 + %13998 = OpConvertUToF %v4float %19042 + %19244 = OpVectorTimesScalar %v4float %13998 %float_0_00392156886 + %8616 = OpCompositeExtract %uint %10946 1 + %24852 = OpCompositeConstruct %v4uint %8616 %8616 %8616 %8616 + %9397 = OpShiftRightLogical %v4uint %24852 %653 + %19043 = OpBitwiseAnd %v4uint %9397 %1611 + %13999 = OpConvertUToF %v4float %19043 + %19245 = OpVectorTimesScalar %v4float %13999 %float_0_00392156886 + %8617 = OpCompositeExtract %uint %10946 2 + %24853 = OpCompositeConstruct %v4uint %8617 %8617 %8617 %8617 + %9398 = OpShiftRightLogical %v4uint %24853 %653 + %19044 = OpBitwiseAnd %v4uint %9398 %1611 + %14000 = OpConvertUToF %v4float %19044 + %19246 = OpVectorTimesScalar %v4float %14000 %float_0_00392156886 + %8618 = OpCompositeExtract %uint %10946 3 + %24854 = OpCompositeConstruct %v4uint %8618 %8618 %8618 %8618 + %9399 = OpShiftRightLogical %v4uint %24854 %653 + %19045 = OpBitwiseAnd %v4uint %9399 %1611 + %17181 = OpConvertUToF %v4float %19045 + %12437 = OpVectorTimesScalar %v4float %17181 %float_0_00392156886 + OpBranch %16227 + %19454 = OpLabel + %12438 = OpCompositeExtract %uint %10946 0 + %20465 = OpBitcast %float %12438 + %17215 = OpCompositeConstruct %v2float %20465 %float_0 + %11673 = OpVectorShuffle %v4float %17215 %17215 0 1 1 1 + %22202 = OpCompositeExtract %uint %10946 1 + %16241 = OpBitcast %float %22202 + %17216 = OpCompositeConstruct %v2float %16241 %float_0 + %11674 = OpVectorShuffle %v4float %17216 %17216 0 1 1 1 + %22203 = OpCompositeExtract %uint %10946 2 + %16242 = OpBitcast %float %22203 + %17217 = OpCompositeConstruct %v2float %16242 %float_0 + %11675 = OpVectorShuffle %v4float %17217 %17217 0 1 1 1 + %22204 = OpCompositeExtract %uint %10946 3 + %16243 = OpBitcast %float %22204 + %20401 = OpCompositeConstruct %v2float %16243 %float_0 + %23101 = OpVectorShuffle %v4float %20401 %20401 0 1 1 1 + OpBranch %16227 + %16227 = OpLabel + %11184 = OpPhi %v4float %23101 %19454 %12437 %14588 %9890 %7361 %9050 %7360 %9049 %8193 %9048 %8249 + %14353 = OpPhi %v4float %11675 %19454 %19246 %14588 %16699 %7361 %15845 %7360 %16681 %8193 %14624 %8249 + %15241 = OpPhi %v4float %11674 %19454 %19245 %14588 %16698 %7361 %15844 %7360 %16680 %8193 %14623 %8249 + %14524 = OpPhi %v4float %11673 %19454 %19244 %14588 %16697 %7361 %15843 %7360 %16679 %8193 %14622 %8249 + OpBranch %21266 + %15208 = OpLabel + %21587 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20265 DontFlatten + OpBranchConditional %21587 %9771 %12136 + %12136 = OpLabel + %19414 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23889 = OpLoad %uint %19414 + %11736 = OpIAdd %uint %16376 %uint_1 + %6425 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11736 + %23685 = OpLoad %uint %6425 + %11737 = OpIAdd %uint %16376 %6555 + %6426 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11737 + %23686 = OpLoad %uint %6426 + %11738 = OpIAdd %uint %11737 %uint_1 + %24590 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11738 + %14160 = OpLoad %uint %24590 + %19674 = OpCompositeConstruct %v4uint %23889 %23685 %23686 %14160 + %17051 = OpIMul %uint %uint_2 %6555 + %14001 = OpIAdd %uint %16376 %17051 + %15242 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %14001 + %23687 = OpLoad %uint %15242 + %11739 = OpIAdd %uint %14001 %uint_1 + %6482 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11739 + %24166 = OpLoad %uint %6482 + %6245 = OpIMul %uint %uint_3 %6555 + %8364 = OpIAdd %uint %16376 %6245 + %15243 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8364 + %23688 = OpLoad %uint %15243 + %11740 = OpIAdd %uint %8364 %uint_1 + %24591 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11740 + %16393 = OpLoad %uint %24591 + %20794 = OpCompositeConstruct %v4uint %23687 %24166 %23688 %16393 + OpBranch %20265 + %9771 = OpLabel + %21836 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23890 = OpLoad %uint %21836 + %11741 = OpIAdd %uint %16376 %uint_1 + %6427 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11741 + %23689 = OpLoad %uint %6427 + %11742 = OpIAdd %uint %16376 %uint_2 + %6428 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11742 + %23690 = OpLoad %uint %6428 + %11743 = OpIAdd %uint %16376 %uint_3 + %24592 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11743 + %14083 = OpLoad %uint %24592 + %19170 = OpCompositeConstruct %v4uint %23890 %23689 %23690 %14083 + %22504 = OpIAdd %uint %16376 %uint_4 + %24654 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22504 + %23691 = OpLoad %uint %24654 + %11744 = OpIAdd %uint %16376 %uint_5 + %6429 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11744 + %23692 = OpLoad %uint %6429 + %11745 = OpIAdd %uint %16376 %uint_6 + %6430 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11745 + %23693 = OpLoad %uint %6430 + %11746 = OpIAdd %uint %16376 %uint_7 + %24593 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11746 + %16394 = OpLoad %uint %24593 + %20795 = OpCompositeConstruct %v4uint %23691 %23692 %23693 %16394 + OpBranch %20265 + %20265 = OpLabel + %11216 = OpPhi %v4uint %20795 %9771 %20794 %12136 + %14115 = OpPhi %v4uint %19170 %9771 %19674 %12136 + OpSelectionMerge %20266 None + OpSwitch %8576 %20313 5 %8539 7 %8250 + %8250 = OpLabel + %24413 = OpCompositeExtract %uint %14115 0 + %24686 = OpExtInst %v2float %1 UnpackHalf2x16 %24413 + %10122 = OpCompositeExtract %float %24686 0 + %16068 = OpCompositeExtract %float %24686 1 + %17037 = OpCompositeExtract %uint %14115 1 + %15617 = OpExtInst %v2float %1 UnpackHalf2x16 %17037 + %10123 = OpCompositeExtract %float %15617 0 + %17499 = OpCompositeExtract %float %15617 1 + %14625 = OpCompositeConstruct %v4float %10122 %16068 %10123 %17499 + %17295 = OpCompositeExtract %uint %14115 2 + %18048 = OpExtInst %v2float %1 UnpackHalf2x16 %17295 + %10124 = OpCompositeExtract %float %18048 0 + %16069 = OpCompositeExtract %float %18048 1 + %17038 = OpCompositeExtract %uint %14115 3 + %15618 = OpExtInst %v2float %1 UnpackHalf2x16 %17038 + %10125 = OpCompositeExtract %float %15618 0 + %17500 = OpCompositeExtract %float %15618 1 + %14626 = OpCompositeConstruct %v4float %10124 %16069 %10125 %17500 + %17296 = OpCompositeExtract %uint %11216 0 + %18049 = OpExtInst %v2float %1 UnpackHalf2x16 %17296 + %10126 = OpCompositeExtract %float %18049 0 + %16070 = OpCompositeExtract %float %18049 1 + %17039 = OpCompositeExtract %uint %11216 1 + %15619 = OpExtInst %v2float %1 UnpackHalf2x16 %17039 + %10127 = OpCompositeExtract %float %15619 0 + %17501 = OpCompositeExtract %float %15619 1 + %14627 = OpCompositeConstruct %v4float %10126 %16070 %10127 %17501 + %17297 = OpCompositeExtract %uint %11216 2 + %18050 = OpExtInst %v2float %1 UnpackHalf2x16 %17297 + %10128 = OpCompositeExtract %float %18050 0 + %16071 = OpCompositeExtract %float %18050 1 + %17040 = OpCompositeExtract %uint %11216 3 + %15620 = OpExtInst %v2float %1 UnpackHalf2x16 %17040 + %10129 = OpCompositeExtract %float %15620 0 + %20677 = OpCompositeExtract %float %15620 1 + %9051 = OpCompositeConstruct %v4float %10128 %16071 %10129 %20677 + OpBranch %20266 + %8539 = OpLabel + %9726 = OpVectorShuffle %v2uint %14115 %14115 0 1 + %23359 = OpBitcast %v2int %9726 + %24794 = OpVectorShuffle %v4int %23359 %23359 0 0 1 1 + %18616 = OpShiftLeftLogical %v4int %24794 %290 + %15769 = OpShiftRightArithmetic %v4int %18616 %770 + %10951 = OpConvertSToF %v4float %15769 + %18227 = OpVectorTimesScalar %v4float %10951 %float_0_000976592302 + %25242 = OpExtInst %v4float %1 FMax %1284 %18227 + %14196 = OpVectorShuffle %v2uint %14115 %14115 2 3 + %9416 = OpBitcast %v2int %14196 + %24795 = OpVectorShuffle %v4int %9416 %9416 0 0 1 1 + %18617 = OpShiftLeftLogical %v4int %24795 %290 + %15770 = OpShiftRightArithmetic %v4int %18617 %770 + %10952 = OpConvertSToF %v4float %15770 + %18228 = OpVectorTimesScalar %v4float %10952 %float_0_000976592302 + %25243 = OpExtInst %v4float %1 FMax %1284 %18228 + %14197 = OpVectorShuffle %v2uint %11216 %11216 0 1 + %9417 = OpBitcast %v2int %14197 + %24796 = OpVectorShuffle %v4int %9417 %9417 0 0 1 1 + %18618 = OpShiftLeftLogical %v4int %24796 %290 + %15771 = OpShiftRightArithmetic %v4int %18618 %770 + %10953 = OpConvertSToF %v4float %15771 + %18229 = OpVectorTimesScalar %v4float %10953 %float_0_000976592302 + %25244 = OpExtInst %v4float %1 FMax %1284 %18229 + %14198 = OpVectorShuffle %v2uint %11216 %11216 2 3 + %9418 = OpBitcast %v2int %14198 + %24797 = OpVectorShuffle %v4int %9418 %9418 0 0 1 1 + %18619 = OpShiftLeftLogical %v4int %24797 %290 + %15772 = OpShiftRightArithmetic %v4int %18619 %770 + %10954 = OpConvertSToF %v4float %15772 + %21458 = OpVectorTimesScalar %v4float %10954 %float_0_000976592302 + %17253 = OpExtInst %v4float %1 FMax %1284 %21458 + OpBranch %20266 + %20313 = OpLabel + %9772 = OpVectorShuffle %v2uint %14115 %14115 0 1 + %20829 = OpBitcast %v2float %9772 + %7047 = OpCompositeExtract %float %20829 0 + %13427 = OpCompositeExtract %float %20829 1 + %17041 = OpCompositeConstruct %v4float %7047 %13427 %float_0 %float_0 + %16865 = OpVectorShuffle %v2uint %14115 %14115 2 3 + %14182 = OpBitcast %v2float %16865 + %7048 = OpCompositeExtract %float %14182 0 + %13428 = OpCompositeExtract %float %14182 1 + %17042 = OpCompositeConstruct %v4float %7048 %13428 %float_0 %float_0 + %16866 = OpVectorShuffle %v2uint %11216 %11216 0 1 + %14183 = OpBitcast %v2float %16866 + %7049 = OpCompositeExtract %float %14183 0 + %13429 = OpCompositeExtract %float %14183 1 + %17043 = OpCompositeConstruct %v4float %7049 %13429 %float_0 %float_0 + %16867 = OpVectorShuffle %v2uint %11216 %11216 2 3 + %14184 = OpBitcast %v2float %16867 + %7050 = OpCompositeExtract %float %14184 0 + %16651 = OpCompositeExtract %float %14184 1 + %9052 = OpCompositeConstruct %v4float %7050 %16651 %float_0 %float_0 + OpBranch %20266 + %20266 = OpLabel + %11185 = OpPhi %v4float %9052 %20313 %17253 %8539 %9051 %8250 + %14354 = OpPhi %v4float %17043 %20313 %25244 %8539 %14627 %8250 + %15244 = OpPhi %v4float %17042 %20313 %25243 %8539 %14626 %8250 + %14525 = OpPhi %v4float %17041 %20313 %25242 %8539 %14625 %8250 + OpBranch %21266 + %21266 = OpLabel + %11186 = OpPhi %v4float %11185 %20266 %11184 %16227 + %14355 = OpPhi %v4float %14354 %20266 %14353 %16227 + %12951 = OpPhi %v4float %15244 %20266 %15241 %16227 + %13948 = OpPhi %v4float %14525 %20266 %14524 %16227 + %17243 = OpFAdd %v4float %17242 %13948 + %23299 = OpFAdd %v4float %23298 %12951 + %9507 = OpFAdd %v4float %7208 %14355 + %7799 = OpFAdd %v4float %9642 %11186 + OpBranch %24264 + %24264 = OpLabel + %11187 = OpPhi %v4float %20755 %21264 %7799 %21266 + %14356 = OpPhi %v4float %8082 %21264 %9507 %21266 + %15153 = OpPhi %v4float %23297 %21264 %23299 %21266 + %15245 = OpPhi %v4float %17241 %21264 %17243 %21266 + %14526 = OpPhi %float %25083 %21264 %12090 %21266 + OpBranch %21267 + %21267 = OpLabel + %11188 = OpPhi %v4float %11177 %21263 %11187 %24264 + %14357 = OpPhi %v4float %14346 %21263 %14356 %24264 + %15154 = OpPhi %v4float %13804 %21263 %15153 %24264 + %13196 = OpPhi %v4float %8403 %21263 %15245 %24264 + %11944 = OpPhi %float %11052 %21263 %14526 %24264 + %23156 = OpVectorTimesScalar %v4float %13196 %11944 + %6604 = OpVectorTimesScalar %v4float %15154 %11944 + %12399 = OpVectorTimesScalar %v4float %14357 %11944 + %13362 = OpVectorTimesScalar %v4float %11188 %11944 + OpSelectionMerge %16228 DontFlatten + OpBranchConditional %7513 %10049 %16228 + %10049 = OpLabel + %15086 = OpVectorShuffle %v4float %23156 %23156 2 1 0 3 + %14855 = OpVectorShuffle %v4float %6604 %6604 2 1 0 3 + %7398 = OpVectorShuffle %v4float %12399 %12399 2 1 0 3 + %16111 = OpVectorShuffle %v4float %13362 %13362 2 1 0 3 + OpBranch %16228 + %16228 = OpLabel + %11189 = OpPhi %v4float %13362 %21267 %16111 %10049 + %14358 = OpPhi %v4float %12399 %21267 %7398 %10049 + %15191 = OpPhi %v4float %6604 %21267 %14855 %10049 + %14921 = OpPhi %v4float %23156 %21267 %15086 %10049 + OpSelectionMerge %23460 None + OpSwitch %20627 %7373 26 %18070 32 %9492 + %9492 = OpLabel + %15022 = OpCompositeExtract %float %14921 0 + %9197 = OpCompositeExtract %float %14921 1 + %19232 = OpCompositeConstruct %v2float %15022 %9197 + %8561 = OpExtInst %uint %1 PackHalf2x16 %19232 + %23487 = OpCompositeExtract %float %14921 2 + %14759 = OpCompositeExtract %float %14921 3 + %19233 = OpCompositeConstruct %v2float %23487 %14759 + %8562 = OpExtInst %uint %1 PackHalf2x16 %19233 + %23488 = OpCompositeExtract %float %15191 0 + %14760 = OpCompositeExtract %float %15191 1 + %19234 = OpCompositeConstruct %v2float %23488 %14760 + %8563 = OpExtInst %uint %1 PackHalf2x16 %19234 + %23489 = OpCompositeExtract %float %15191 2 + %14761 = OpCompositeExtract %float %15191 3 + %19213 = OpCompositeConstruct %v2float %23489 %14761 + %8736 = OpExtInst %uint %1 PackHalf2x16 %19213 + %12628 = OpCompositeConstruct %v4uint %8561 %8562 %8563 %8736 + %16072 = OpCompositeExtract %float %14358 0 + %21616 = OpCompositeExtract %float %14358 1 + %19247 = OpCompositeConstruct %v2float %16072 %21616 + %8564 = OpExtInst %uint %1 PackHalf2x16 %19247 + %23490 = OpCompositeExtract %float %14358 2 + %14762 = OpCompositeExtract %float %14358 3 + %19248 = OpCompositeConstruct %v2float %23490 %14762 + %8565 = OpExtInst %uint %1 PackHalf2x16 %19248 + %23491 = OpCompositeExtract %float %11189 0 + %14763 = OpCompositeExtract %float %11189 1 + %19249 = OpCompositeConstruct %v2float %23491 %14763 + %8566 = OpExtInst %uint %1 PackHalf2x16 %19249 + %23492 = OpCompositeExtract %float %11189 2 + %14764 = OpCompositeExtract %float %11189 3 + %19214 = OpCompositeConstruct %v2float %23492 %14764 + %11926 = OpExtInst %uint %1 PackHalf2x16 %19214 + %24879 = OpCompositeConstruct %v4uint %8564 %8565 %8566 %11926 + OpBranch %23460 + %18070 = OpLabel + %7311 = OpExtInst %v4float %1 FClamp %14921 %2938 %1285 + %20339 = OpVectorTimesScalar %v4float %7311 %float_65535 + %11840 = OpFAdd %v4float %20339 %325 + %7947 = OpConvertFToU %v4uint %11840 + %6361 = OpVectorShuffle %v2uint %7947 %7947 0 2 + %10064 = OpVectorShuffle %v2uint %7947 %7947 1 3 + %10446 = OpShiftLeftLogical %v2uint %10064 %2151 + %22473 = OpBitwiseOr %v2uint %6361 %10446 + %18828 = OpCompositeExtract %uint %22473 0 + %15356 = OpCompositeExtract %uint %22473 1 + %14161 = OpExtInst %v4float %1 FClamp %15191 %2938 %1285 + %11265 = OpVectorTimesScalar %v4float %14161 %float_65535 + %11841 = OpFAdd %v4float %11265 %325 + %7948 = OpConvertFToU %v4uint %11841 + %6362 = OpVectorShuffle %v2uint %7948 %7948 0 2 + %10065 = OpVectorShuffle %v2uint %7948 %7948 1 3 + %10447 = OpShiftLeftLogical %v2uint %10065 %2151 + %22474 = OpBitwiseOr %v2uint %6362 %10447 + %20077 = OpCompositeExtract %uint %22474 0 + %22635 = OpCompositeExtract %uint %22474 1 + %7479 = OpCompositeConstruct %v4uint %18828 %15356 %20077 %22635 + %14406 = OpExtInst %v4float %1 FClamp %14358 %2938 %1285 + %13687 = OpVectorTimesScalar %v4float %14406 %float_65535 + %11842 = OpFAdd %v4float %13687 %325 + %7949 = OpConvertFToU %v4uint %11842 + %6363 = OpVectorShuffle %v2uint %7949 %7949 0 2 + %10066 = OpVectorShuffle %v2uint %7949 %7949 1 3 + %10448 = OpShiftLeftLogical %v2uint %10066 %2151 + %22475 = OpBitwiseOr %v2uint %6363 %10448 + %18829 = OpCompositeExtract %uint %22475 0 + %15357 = OpCompositeExtract %uint %22475 1 + %14162 = OpExtInst %v4float %1 FClamp %11189 %2938 %1285 + %11266 = OpVectorTimesScalar %v4float %14162 %float_65535 + %11843 = OpFAdd %v4float %11266 %325 + %7950 = OpConvertFToU %v4uint %11843 + %6364 = OpVectorShuffle %v2uint %7950 %7950 0 2 + %10067 = OpVectorShuffle %v2uint %7950 %7950 1 3 + %10449 = OpShiftLeftLogical %v2uint %10067 %2151 + %22476 = OpBitwiseOr %v2uint %6364 %10449 + %20078 = OpCompositeExtract %uint %22476 0 + %8024 = OpCompositeExtract %uint %22476 1 + %9053 = OpCompositeConstruct %v4uint %18829 %15357 %20078 %8024 + OpBranch %23460 + %7373 = OpLabel + %19885 = OpCompositeExtract %float %14921 0 + %10277 = OpCompositeExtract %float %14921 1 + %7641 = OpCompositeExtract %float %15191 0 + %8650 = OpCompositeExtract %float %15191 1 + %8414 = OpCompositeConstruct %v4float %19885 %10277 %7641 %8650 + %17959 = OpBitcast %v4uint %8414 + %11089 = OpCompositeExtract %float %14358 0 + %13283 = OpCompositeExtract %float %14358 1 + %7642 = OpCompositeExtract %float %11189 0 + %8651 = OpCompositeExtract %float %11189 1 + %11606 = OpCompositeConstruct %v4float %11089 %13283 %7642 %8651 + %11139 = OpBitcast %v4uint %11606 + OpBranch %23460 + %23460 = OpLabel + %9750 = OpPhi %v4uint %11139 %7373 %9053 %18070 %24879 %9492 + %13261 = OpPhi %v4uint %17959 %7373 %7479 %18070 %12628 %9492 + %19928 = OpIEqual %bool %7640 %uint_0 + %22246 = OpSelect %bool %19928 %false %19928 + OpSelectionMerge %19649 DontFlatten + OpBranchConditional %22246 %9760 %19649 + %9760 = OpLabel + %17298 = OpCompositeExtract %uint %13261 2 + %21174 = OpCompositeInsert %v4uint %17298 %13261 0 + %23044 = OpCompositeExtract %uint %13261 3 + %9296 = OpCompositeInsert %v4uint %23044 %21174 1 + OpBranch %19649 + %19649 = OpLabel + %12383 = OpPhi %v4uint %13261 %23460 %9296 %9760 + %12967 = OpIAdd %v2uint %12025 %23020 + OpSelectionMerge %21237 DontFlatten + OpBranchConditional %20495 %10574 %21373 + %21373 = OpLabel + %10608 = OpBitcast %v2int %12967 + %17090 = OpCompositeExtract %int %10608 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %10608 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %15783 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_10 + %10955 = OpBitwiseAnd %int %17090 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17303 = OpIAdd %int %10955 %17741 + %6375 = OpShiftLeftLogical %int %17303 %uint_3 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15435 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18365 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18365 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12151 + %19171 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19171 %int_2 + %16708 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21588 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21588 %int_6 + %15436 = OpIAdd %int %16708 %21580 + %11782 = OpBitwiseAnd %int %16727 %int_63 + %14671 = OpIAdd %int %15436 %11782 + %22127 = OpBitcast %uint %14671 + OpBranch %21237 + %10574 = OpLabel + %19866 = OpCompositeExtract %uint %12967 0 + %11267 = OpCompositeExtract %uint %12967 1 + %8415 = OpCompositeConstruct %v3uint %19866 %11267 %24434 + %20125 = OpBitcast %v3int %8415 + %10438 = OpCompositeExtract %int %20125 1 + %9470 = OpShiftRightArithmetic %int %10438 %int_4 + %10056 = OpCompositeExtract %int %20125 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %25203 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %15783 %uint_5 + %12439 = OpBitcast %int %9032 + %10367 = OpIMul %int %15143 %12439 + %25154 = OpCompositeExtract %int %20125 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10367 + %8797 = OpShiftLeftLogical %int %18940 %uint_9 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12601 = OpBitwiseAnd %int %10438 %int_6 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7051 = OpShiftLeftLogical %int %17227 %uint_9 + %24035 = OpShiftRightArithmetic %int %7051 %int_6 + %8737 = OpShiftRightArithmetic %int %10438 %int_3 + %13731 = OpIAdd %int %8737 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19172 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19172 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23346 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23346 %23274 + %18366 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18366 %uint_9 + %16729 = OpIAdd %int %10332 %21582 + %19173 = OpBitwiseAnd %int %10438 %int_1 + %21583 = OpShiftLeftLogical %int %19173 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23347 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10956 = OpIAdd %int %23347 %23217 + %23348 = OpShiftLeftLogical %int %10956 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10957 = OpIAdd %int %23348 %23218 + %23349 = OpShiftLeftLogical %int %10957 %int_3 + %21849 = OpBitwiseAnd %int %16730 %int_63 + %24314 = OpIAdd %int %23349 %21849 + %22128 = OpBitcast %uint %24314 + OpBranch %21237 + %21237 = OpLabel + %11376 = OpPhi %uint %22128 %10574 %22127 %21373 + %20616 = OpIAdd %uint %11376 %25270 + %20138 = OpShiftRightLogical %uint %20616 %uint_4 + %19356 = OpIEqual %bool %19164 %uint_4 + OpSelectionMerge %14780 None + OpBranchConditional %19356 %13279 %14780 + %13279 = OpLabel + %7958 = OpVectorShuffle %v4uint %12383 %12383 1 0 3 2 + OpBranch %14780 + %14780 = OpLabel + %22898 = OpPhi %v4uint %12383 %21237 %7958 %13279 + %6605 = OpSelect %uint %19356 %uint_2 %19164 + %13412 = OpIEqual %bool %6605 %uint_1 + %18370 = OpIEqual %bool %6605 %uint_2 + %22150 = OpLogicalOr %bool %13412 %18370 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %22898 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %22898 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16377 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22650 = OpPhi %v4uint %22898 %14780 %16377 %10583 + %19638 = OpIEqual %bool %6605 %uint_3 + %15139 = OpLogicalOr %bool %18370 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22650 %749 + %15335 = OpShiftRightLogical %v4uint %22650 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22650 %13411 %10728 %11064 + %24825 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %20138 + OpStore %24825 %19767 + %21685 = OpIAdd %uint %20138 %uint_2 + OpSelectionMerge %16262 None + OpBranchConditional %19356 %13280 %16262 + %13280 = OpLabel + %7959 = OpVectorShuffle %v4uint %9750 %9750 1 0 3 2 + OpBranch %16262 + %16262 = OpLabel + %10958 = OpPhi %v4uint %9750 %11416 %7959 %13280 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %10958 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %10958 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16378 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10959 = OpPhi %v4uint %10958 %16262 %16378 %10584 + OpSelectionMerge %11417 None + OpBranchConditional %15139 %11065 %11417 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10959 %749 + %15336 = OpShiftRightLogical %v4uint %10959 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %10959 %14874 %10729 %11065 + %8054 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %21685 + OpStore %8054 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_full_64bpp_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000062B7, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00040047, 0x000007D0, 0x00000006, 0x00000004, + 0x00030047, 0x0000079C, 0x00000003, 0x00040048, 0x0000079C, 0x00000000, 0x00000018, 0x00050048, + 0x0000079C, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000CC7, 0x00000018, 0x00040047, + 0x00000CC7, 0x00000021, 0x00000000, 0x00040047, 0x00000CC7, 0x00000022, 0x00000000, 0x00030047, + 0x0000040C, 0x00000002, 0x00050048, 0x0000040C, 0x00000000, 0x00000023, 0x00000000, 0x00050048, + 0x0000040C, 0x00000001, 0x00000023, 0x00000004, 0x00050048, 0x0000040C, 0x00000002, 0x00000023, + 0x00000008, 0x00050048, 0x0000040C, 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x0000040C, + 0x00000004, 0x00000023, 0x00000010, 0x00040047, 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, + 0x000007DC, 0x00000006, 0x00000010, 0x00030047, 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, + 0x00000000, 0x00000019, 0x00050048, 0x000007B4, 0x00000000, 0x00000023, 0x00000000, 0x00030047, + 0x00001592, 0x00000019, 0x00040047, 0x00001592, 0x00000021, 0x00000000, 0x00040047, 0x00001592, + 0x00000022, 0x00000001, 0x00040047, 0x00000AC9, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, + 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, + 0x00000012, 0x0000000C, 0x00000002, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, + 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x00040017, + 0x00000017, 0x0000000B, 0x00000004, 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x00000013, + 0x0000000D, 0x00000002, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x00020014, 0x00000009, + 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, + 0x0004002B, 0x0000000D, 0x0000008A, 0x3F800000, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, + 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000D, 0x0000022D, 0x477FFF00, + 0x0004002B, 0x0000000D, 0x000000FC, 0x3F000000, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A52, 0x00000018, + 0x0007002C, 0x00000017, 0x0000028D, 0x00000A0A, 0x00000A22, 0x00000A3A, 0x00000A52, 0x0004002B, + 0x0000000B, 0x00000144, 0x000000FF, 0x0004002B, 0x0000000D, 0x0000017A, 0x3B808081, 0x0004002B, + 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000A46, 0x00000014, 0x0004002B, + 0x0000000B, 0x00000A64, 0x0000001E, 0x0007002C, 0x00000017, 0x0000034D, 0x00000A0A, 0x00000A28, + 0x00000A46, 0x00000A64, 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, 0x0007002C, 0x00000017, + 0x0000027B, 0x00000A44, 0x00000A44, 0x00000A44, 0x00000A13, 0x0004002B, 0x0000000D, 0x000006FE, + 0x3A802008, 0x0004002B, 0x0000000D, 0x00000149, 0x3EAAAAAB, 0x0007002C, 0x0000001D, 0x00000AEE, + 0x000006FE, 0x000006FE, 0x000006FE, 0x00000149, 0x0006002C, 0x00000014, 0x00000BB4, 0x00000A0A, + 0x00000A28, 0x00000A46, 0x0004002B, 0x0000000B, 0x00000B87, 0x0000007F, 0x0004002B, 0x0000000B, + 0x00000A1F, 0x00000007, 0x00040017, 0x00000010, 0x00000009, 0x00000003, 0x0004002B, 0x0000000B, + 0x00000B7E, 0x0000007C, 0x0004002B, 0x0000000B, 0x00000A4F, 0x00000017, 0x00040017, 0x00000018, + 0x0000000D, 0x00000003, 0x0004002B, 0x0000000D, 0x00000341, 0xBF800000, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x0005002C, 0x00000012, 0x000007A7, 0x00000A3B, 0x00000A0B, 0x0004002B, + 0x0000000D, 0x000007FE, 0x3A800100, 0x00040017, 0x0000001A, 0x0000000C, 0x00000004, 0x0007002C, + 0x0000001A, 0x00000122, 0x00000A3B, 0x00000A0B, 0x00000A3B, 0x00000A0B, 0x0005002C, 0x00000011, + 0x0000072D, 0x00000A10, 0x00000A0D, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0005002C, + 0x00000011, 0x0000070F, 0x00000A0A, 0x00000A0A, 0x0005002C, 0x00000011, 0x00000724, 0x00000A0D, + 0x00000A0D, 0x0005002C, 0x00000011, 0x00000718, 0x00000A0D, 0x00000A0A, 0x0004002B, 0x0000000B, + 0x00000AFA, 0x00000050, 0x0005002C, 0x00000011, 0x00000A9F, 0x00000AFA, 0x00000A3A, 0x0004002B, + 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, + 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, + 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, + 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, + 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, + 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, + 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, + 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, 0x0004002B, + 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0003001D, + 0x000007D0, 0x0000000B, 0x0003001E, 0x0000079C, 0x000007D0, 0x00040020, 0x00000A1B, 0x00000002, + 0x0000079C, 0x0004003B, 0x00000A1B, 0x00000CC7, 0x00000002, 0x00040020, 0x00000288, 0x00000002, + 0x0000000B, 0x0007001E, 0x0000040C, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, + 0x00040020, 0x00000688, 0x00000009, 0x0000040C, 0x0004003B, 0x00000688, 0x00000CE9, 0x00000009, + 0x00040020, 0x00000289, 0x00000009, 0x0000000B, 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, + 0x0004002B, 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, + 0x0004002B, 0x0000000B, 0x00000A5E, 0x0000001C, 0x0005002C, 0x00000011, 0x0000073F, 0x00000A0A, + 0x00000A16, 0x0004002B, 0x0000000C, 0x00000A29, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000AC7, + 0x0000003F, 0x0004002B, 0x0000000C, 0x00000A59, 0x0000001A, 0x0004002B, 0x0000000C, 0x00000A50, + 0x00000017, 0x0004002B, 0x0000000B, 0x00000926, 0x01000000, 0x0005002C, 0x00000011, 0x000008E3, + 0x00000A46, 0x00000A52, 0x0003002A, 0x00000009, 0x00000787, 0x00040020, 0x00000291, 0x00000001, + 0x00000014, 0x0004003B, 0x00000291, 0x00000F48, 0x00000001, 0x0005002C, 0x00000011, 0x00000721, + 0x00000A10, 0x00000A0A, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A32, 0x00001592, 0x00000002, + 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0006002C, 0x00000014, 0x00000AC9, 0x00000A22, + 0x00000A22, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A37, 0x00000A0D, 0x0005002C, + 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, 0x0005002C, 0x00000011, 0x0000084A, 0x00000A37, + 0x00000A37, 0x0007002C, 0x0000001D, 0x00000504, 0x00000341, 0x00000341, 0x00000341, 0x00000341, + 0x0007002C, 0x0000001A, 0x00000302, 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x0007002C, + 0x00000017, 0x0000064B, 0x00000144, 0x00000144, 0x00000144, 0x00000144, 0x0006002C, 0x00000014, + 0x00000105, 0x00000A44, 0x00000A44, 0x00000A44, 0x0006002C, 0x00000014, 0x00000466, 0x00000B87, + 0x00000B87, 0x00000B87, 0x0006002C, 0x00000014, 0x00000B0C, 0x00000A1F, 0x00000A1F, 0x00000A1F, + 0x0006002C, 0x00000014, 0x00000A12, 0x00000A0A, 0x00000A0A, 0x00000A0A, 0x0006002C, 0x00000014, + 0x000003FA, 0x00000B7E, 0x00000B7E, 0x00000B7E, 0x0006002C, 0x00000014, 0x00000189, 0x00000A4F, + 0x00000A4F, 0x00000A4F, 0x0006002C, 0x00000014, 0x0000008D, 0x00000A3A, 0x00000A3A, 0x00000A3A, + 0x0005002C, 0x00000013, 0x00000049, 0x00000341, 0x00000341, 0x0005002C, 0x00000012, 0x00000867, + 0x00000A3B, 0x00000A3B, 0x0007002C, 0x0000001D, 0x00000B7A, 0x00000A0C, 0x00000A0C, 0x00000A0C, + 0x00000A0C, 0x0007002C, 0x0000001D, 0x00000505, 0x0000008A, 0x0000008A, 0x0000008A, 0x0000008A, + 0x0007002C, 0x0000001D, 0x00000145, 0x000000FC, 0x000000FC, 0x000000FC, 0x000000FC, 0x0004002B, + 0x0000000B, 0x00000A25, 0x00000009, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, + 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, + 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, + 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0004002B, + 0x0000000C, 0x00000089, 0x3F800000, 0x0004002B, 0x0000000B, 0x00000184, 0x00000500, 0x0004002B, + 0x0000000B, 0x0000086E, 0x00280000, 0x0004002B, 0x0000000B, 0x000009F8, 0xFFFFFFFA, 0x0006002C, + 0x00000014, 0x00000938, 0x000009F8, 0x000009F8, 0x000009F8, 0x0004002B, 0x0000000B, 0x00000AFD, + 0x00000051, 0x0004002B, 0x0000000B, 0x00000B00, 0x00000052, 0x0004002B, 0x0000000B, 0x00000B03, + 0x00000053, 0x0004002B, 0x0000000B, 0x00000B06, 0x00000054, 0x0004002B, 0x0000000B, 0x00000B09, + 0x00000055, 0x0004002B, 0x0000000B, 0x00000B0D, 0x00000056, 0x0004002B, 0x0000000B, 0x00000B0F, + 0x00000057, 0x0004002B, 0x0000000D, 0x0000016E, 0x3E800000, 0x00050036, 0x00000008, 0x0000161F, + 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, + 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000289, 0x000056E5, 0x00000CE9, + 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003D0B, 0x000056E5, 0x00050041, 0x00000289, 0x000058AC, + 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005158, 0x000058AC, 0x000500C7, 0x0000000B, + 0x00005051, 0x00003D0B, 0x00000A44, 0x000500C2, 0x0000000B, 0x00004E0A, 0x00003D0B, 0x00000A28, + 0x000500C7, 0x0000000B, 0x0000217E, 0x00004E0A, 0x00000A13, 0x000500C2, 0x0000000B, 0x0000520A, + 0x00003D0B, 0x00000A31, 0x000500C7, 0x0000000B, 0x0000217F, 0x0000520A, 0x00000A81, 0x000500C2, + 0x0000000B, 0x0000520B, 0x00003D0B, 0x00000A52, 0x000500C7, 0x0000000B, 0x00002180, 0x0000520B, + 0x00000A37, 0x000500C2, 0x0000000B, 0x00004994, 0x00003D0B, 0x00000A5E, 0x000500C7, 0x0000000B, + 0x000023AA, 0x00004994, 0x00000A0D, 0x00050050, 0x00000011, 0x000022A7, 0x00005158, 0x00005158, + 0x000500C2, 0x00000011, 0x00002568, 0x000022A7, 0x0000073F, 0x000500C7, 0x00000011, 0x00005B53, + 0x00002568, 0x000007A2, 0x000500C4, 0x00000011, 0x00003F4F, 0x00005B53, 0x0000074E, 0x00050084, + 0x00000011, 0x000059EB, 0x00003F4F, 0x00000724, 0x000500C2, 0x0000000B, 0x00003213, 0x00005158, + 0x00000A19, 0x000500C7, 0x0000000B, 0x00003F4C, 0x00003213, 0x00000A81, 0x00050041, 0x00000289, + 0x0000492C, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, + 0x00000289, 0x000058AD, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x000051B7, 0x000058AD, + 0x000500C7, 0x0000000B, 0x00004ADC, 0x00005EAC, 0x00000A1F, 0x000500C7, 0x0000000B, 0x000055EF, + 0x00005EAC, 0x00000A22, 0x000500AB, 0x00000009, 0x0000500F, 0x000055EF, 0x00000A0A, 0x000500C2, + 0x0000000B, 0x00002843, 0x00005EAC, 0x00000A16, 0x000500C7, 0x0000000B, 0x00005F72, 0x00002843, + 0x00000A1F, 0x000500C2, 0x0000000B, 0x00004CD8, 0x00005EAC, 0x00000A1F, 0x000500C7, 0x0000000B, + 0x00005093, 0x00004CD8, 0x00000AC7, 0x0004007C, 0x0000000C, 0x00005988, 0x00005EAC, 0x000500C4, + 0x0000000C, 0x0000358F, 0x00005988, 0x00000A29, 0x000500C3, 0x0000000C, 0x0000509C, 0x0000358F, + 0x00000A59, 0x000500C4, 0x0000000C, 0x00004702, 0x0000509C, 0x00000A50, 0x00050080, 0x0000000C, + 0x00001D26, 0x00004702, 0x00000089, 0x0004007C, 0x0000000D, 0x00002B2C, 0x00001D26, 0x000500C7, + 0x0000000B, 0x00005879, 0x00005EAC, 0x00000926, 0x000500AB, 0x00000009, 0x00001D59, 0x00005879, + 0x00000A0A, 0x000500C7, 0x0000000B, 0x00001F43, 0x000051B7, 0x00000A44, 0x000500C4, 0x0000000B, + 0x00003DA7, 0x00001F43, 0x00000A19, 0x000500C2, 0x0000000B, 0x0000583F, 0x000051B7, 0x00000A28, + 0x000500C7, 0x0000000B, 0x00004BBE, 0x0000583F, 0x00000A44, 0x000500C4, 0x0000000B, 0x00006273, + 0x00004BBE, 0x00000A19, 0x00050050, 0x00000011, 0x000028B6, 0x000051B7, 0x000051B7, 0x000500C2, + 0x00000011, 0x00002891, 0x000028B6, 0x000008E3, 0x000500C7, 0x00000011, 0x00005B54, 0x00002891, + 0x0000084A, 0x000500C4, 0x00000011, 0x00003F50, 0x00005B54, 0x0000074E, 0x00050084, 0x00000011, + 0x000059EC, 0x00003F50, 0x00000724, 0x000500C2, 0x0000000B, 0x00003214, 0x000051B7, 0x00000A5E, + 0x000500C7, 0x0000000B, 0x00003F4D, 0x00003214, 0x00000A1F, 0x00050041, 0x00000289, 0x000048E0, + 0x00000CE9, 0x00000A17, 0x0004003D, 0x0000000B, 0x000062B6, 0x000048E0, 0x0004003D, 0x00000014, + 0x0000374F, 0x00000F48, 0x0007004F, 0x00000011, 0x00003180, 0x0000374F, 0x0000374F, 0x00000000, + 0x00000001, 0x000500C4, 0x00000011, 0x00002EF9, 0x00003180, 0x00000721, 0x00050051, 0x0000000B, + 0x00001DD8, 0x00002EF9, 0x00000000, 0x000500C4, 0x0000000B, 0x00002D8A, 0x00003F4C, 0x00000A13, + 0x000500AE, 0x00000009, 0x00003C13, 0x00001DD8, 0x00002D8A, 0x000300F7, 0x000031D3, 0x00000002, + 0x000400FA, 0x00003C13, 0x000055E8, 0x000031D3, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, + 0x000200F8, 0x000031D3, 0x00050051, 0x0000000B, 0x00001CAC, 0x00002EF9, 0x00000001, 0x0007000C, + 0x0000000B, 0x00001F38, 0x00000001, 0x00000029, 0x00001CAC, 0x00000A0A, 0x00050050, 0x00000011, + 0x000051EF, 0x00001DD8, 0x00001F38, 0x00050080, 0x00000011, 0x0000522C, 0x000051EF, 0x000059EB, + 0x000500B2, 0x00000009, 0x00003ECB, 0x00003F4D, 0x00000A13, 0x000300F7, 0x00005CE0, 0x00000000, + 0x000400FA, 0x00003ECB, 0x00002AEE, 0x00003AEF, 0x000200F8, 0x00003AEF, 0x000500AA, 0x00000009, + 0x000034FE, 0x00003F4D, 0x00000A19, 0x000600A9, 0x0000000B, 0x000020F6, 0x000034FE, 0x00000A10, + 0x00000A0A, 0x000200F9, 0x00005CE0, 0x000200F8, 0x00002AEE, 0x000200F9, 0x00005CE0, 0x000200F8, + 0x00005CE0, 0x000700F5, 0x0000000B, 0x00004B64, 0x00003F4D, 0x00002AEE, 0x000020F6, 0x00003AEF, + 0x00050050, 0x00000011, 0x000041BE, 0x0000217E, 0x0000217E, 0x000500AE, 0x0000000F, 0x00002E19, + 0x000041BE, 0x0000072D, 0x000600A9, 0x00000011, 0x00004BB5, 0x00002E19, 0x00000724, 0x0000070F, + 0x000500C4, 0x00000011, 0x00002AEA, 0x0000522C, 0x00004BB5, 0x00050050, 0x00000011, 0x0000605D, + 0x00004B64, 0x00004B64, 0x000500C2, 0x00000011, 0x00002385, 0x0000605D, 0x00000718, 0x000500C7, + 0x00000011, 0x00003AEC, 0x00002385, 0x00000724, 0x00050080, 0x00000011, 0x000027D5, 0x00002AEA, + 0x00003AEC, 0x00050050, 0x00000011, 0x00002164, 0x000023AA, 0x00000A0A, 0x000500C2, 0x00000011, + 0x0000264A, 0x00000A9F, 0x00002164, 0x00050086, 0x00000011, 0x000027A2, 0x000027D5, 0x0000264A, + 0x00050051, 0x0000000B, 0x00004FA6, 0x000027A2, 0x00000001, 0x00050084, 0x0000000B, 0x00002B26, + 0x00004FA6, 0x00005051, 0x00050051, 0x0000000B, 0x00006059, 0x000027A2, 0x00000000, 0x00050080, + 0x0000000B, 0x00005420, 0x00002B26, 0x00006059, 0x00050080, 0x0000000B, 0x00002226, 0x0000217F, + 0x00005420, 0x00050084, 0x00000011, 0x00005B31, 0x000027A2, 0x0000264A, 0x00050082, 0x00000011, + 0x00002E74, 0x000027D5, 0x00005B31, 0x00050084, 0x0000000B, 0x00001F75, 0x00002226, 0x00000184, + 0x00050051, 0x0000000B, 0x00005EC7, 0x00002E74, 0x00000001, 0x00050051, 0x0000000B, 0x00005BE6, + 0x0000264A, 0x00000000, 0x00050084, 0x0000000B, 0x00005966, 0x00005EC7, 0x00005BE6, 0x00050051, + 0x0000000B, 0x00001AE6, 0x00002E74, 0x00000000, 0x00050080, 0x0000000B, 0x000025E0, 0x00005966, + 0x00001AE6, 0x000500C4, 0x0000000B, 0x000046C4, 0x000025E0, 0x000023AA, 0x00050080, 0x0000000B, + 0x00004719, 0x00001F75, 0x000046C4, 0x00050089, 0x0000000B, 0x00005AD8, 0x00004719, 0x0000086E, + 0x000500AE, 0x00000009, 0x00003361, 0x0000217E, 0x00000A10, 0x000600A9, 0x0000000B, 0x0000609F, + 0x00003361, 0x00000A0D, 0x00000A0A, 0x00050080, 0x0000000B, 0x00004E6A, 0x000023AA, 0x0000609F, + 0x000500C4, 0x0000000B, 0x0000199B, 0x00000A0D, 0x00004E6A, 0x000500AB, 0x00000009, 0x00005AEF, + 0x000023AA, 0x00000A0A, 0x000300F7, 0x0000530F, 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B65, + 0x000040B9, 0x000200F8, 0x000040B9, 0x000500AA, 0x00000009, 0x00004ADA, 0x0000199B, 0x00000A0D, + 0x000300F7, 0x00004F49, 0x00000002, 0x000400FA, 0x00004ADA, 0x00002621, 0x00002F61, 0x000200F8, + 0x00002F61, 0x00060041, 0x00000288, 0x00004BCF, 0x00000CC7, 0x00000A0B, 0x00005AD8, 0x0004003D, + 0x0000000B, 0x00005D43, 0x00004BCF, 0x00050080, 0x0000000B, 0x00002DA7, 0x00005AD8, 0x0000199B, + 0x00060041, 0x00000288, 0x0000194B, 0x00000CC7, 0x00000A0B, 0x00002DA7, 0x0004003D, 0x0000000B, + 0x00005E5B, 0x0000194B, 0x00050084, 0x0000000B, 0x0000185A, 0x00000A10, 0x0000199B, 0x00050080, + 0x0000000B, 0x000020A1, 0x00005AD8, 0x0000185A, 0x00060041, 0x00000288, 0x00003BCD, 0x00000CC7, + 0x00000A0B, 0x000020A1, 0x0004003D, 0x0000000B, 0x00005E5C, 0x00003BCD, 0x00050084, 0x0000000B, + 0x0000185B, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A2, 0x00005AD8, 0x0000185B, + 0x00060041, 0x00000288, 0x000037F1, 0x00000CC7, 0x00000A0B, 0x000020A2, 0x0004003D, 0x0000000B, + 0x00003FFB, 0x000037F1, 0x00070050, 0x00000017, 0x0000512C, 0x00005D43, 0x00005E5B, 0x00005E5C, + 0x00003FFB, 0x000200F9, 0x00004F49, 0x000200F8, 0x00002621, 0x00060041, 0x00000288, 0x00005545, + 0x00000CC7, 0x00000A0B, 0x00005AD8, 0x0004003D, 0x0000000B, 0x00005D44, 0x00005545, 0x00050080, + 0x0000000B, 0x00002DA8, 0x00005AD8, 0x00000A0D, 0x00060041, 0x00000288, 0x000018FF, 0x00000CC7, + 0x00000A0B, 0x00002DA8, 0x0004003D, 0x0000000B, 0x00005C62, 0x000018FF, 0x00050080, 0x0000000B, + 0x00002DA9, 0x00005AD8, 0x00000A10, 0x00060041, 0x00000288, 0x00001900, 0x00000CC7, 0x00000A0B, + 0x00002DA9, 0x0004003D, 0x0000000B, 0x00005C63, 0x00001900, 0x00050080, 0x0000000B, 0x00002DAA, + 0x00005AD8, 0x00000A13, 0x00060041, 0x00000288, 0x00005FEE, 0x00000CC7, 0x00000A0B, 0x00002DAA, + 0x0004003D, 0x0000000B, 0x00003FFC, 0x00005FEE, 0x00070050, 0x00000017, 0x0000512D, 0x00005D44, + 0x00005C62, 0x00005C63, 0x00003FFC, 0x000200F9, 0x00004F49, 0x000200F8, 0x00004F49, 0x000700F5, + 0x00000017, 0x00002ABF, 0x0000512D, 0x00002621, 0x0000512C, 0x00002F61, 0x000300F7, 0x00003F60, + 0x00000000, 0x001300FB, 0x00002180, 0x00004BFB, 0x00000000, 0x000038F9, 0x00000001, 0x000038F9, + 0x00000002, 0x00001CBB, 0x0000000A, 0x00001CBB, 0x00000003, 0x00001CBA, 0x0000000C, 0x00001CBA, + 0x00000004, 0x00001FFE, 0x00000006, 0x00002033, 0x000200F8, 0x00002033, 0x00050051, 0x0000000B, + 0x00005F56, 0x00002ABF, 0x00000000, 0x0006000C, 0x00000013, 0x00006067, 0x00000001, 0x0000003E, + 0x00005F56, 0x00050051, 0x0000000D, 0x00002762, 0x00006067, 0x00000000, 0x00050051, 0x0000000D, + 0x00004446, 0x00006067, 0x00000001, 0x00070050, 0x0000001D, 0x0000390C, 0x00002762, 0x00004446, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x0000437A, 0x00002ABF, 0x00000001, 0x0006000C, + 0x00000013, 0x0000466B, 0x00000001, 0x0000003E, 0x0000437A, 0x00050051, 0x0000000D, 0x00002763, + 0x0000466B, 0x00000000, 0x00050051, 0x0000000D, 0x00004447, 0x0000466B, 0x00000001, 0x00070050, + 0x0000001D, 0x0000390D, 0x00002763, 0x00004447, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x0000437B, 0x00002ABF, 0x00000002, 0x0006000C, 0x00000013, 0x0000466C, 0x00000001, 0x0000003E, + 0x0000437B, 0x00050051, 0x0000000D, 0x00002764, 0x0000466C, 0x00000000, 0x00050051, 0x0000000D, + 0x00004448, 0x0000466C, 0x00000001, 0x00070050, 0x0000001D, 0x0000390E, 0x00002764, 0x00004448, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x0000437C, 0x00002ABF, 0x00000003, 0x0006000C, + 0x00000013, 0x0000466D, 0x00000001, 0x0000003E, 0x0000437C, 0x00050051, 0x0000000D, 0x00002765, + 0x0000466D, 0x00000000, 0x00050051, 0x0000000D, 0x000050BE, 0x0000466D, 0x00000001, 0x00070050, + 0x0000001D, 0x00002349, 0x00002765, 0x000050BE, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F60, + 0x000200F8, 0x00001FFE, 0x00050051, 0x0000000B, 0x0000308B, 0x00002ABF, 0x00000000, 0x0004007C, + 0x0000000C, 0x0000589D, 0x0000308B, 0x00050050, 0x00000012, 0x0000471A, 0x0000589D, 0x0000589D, + 0x000500C4, 0x00000012, 0x000047AD, 0x0000471A, 0x000007A7, 0x000500C3, 0x00000012, 0x00003417, + 0x000047AD, 0x00000867, 0x0004006F, 0x00000013, 0x00002A97, 0x00003417, 0x0005008E, 0x00000013, + 0x00004747, 0x00002A97, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E06, 0x00000001, 0x00000028, + 0x00000049, 0x00004747, 0x00050051, 0x0000000D, 0x00005F0A, 0x00005E06, 0x00000000, 0x00050051, + 0x0000000D, 0x00003CD4, 0x00005E06, 0x00000001, 0x00070050, 0x0000001D, 0x0000411E, 0x00005F0A, + 0x00003CD4, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C42, 0x00002ABF, 0x00000001, + 0x0004007C, 0x0000000C, 0x00003EA1, 0x00004C42, 0x00050050, 0x00000012, 0x0000471B, 0x00003EA1, + 0x00003EA1, 0x000500C4, 0x00000012, 0x000047AE, 0x0000471B, 0x000007A7, 0x000500C3, 0x00000012, + 0x00003418, 0x000047AE, 0x00000867, 0x0004006F, 0x00000013, 0x00002A98, 0x00003418, 0x0005008E, + 0x00000013, 0x00004748, 0x00002A98, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E07, 0x00000001, + 0x00000028, 0x00000049, 0x00004748, 0x00050051, 0x0000000D, 0x00005F0B, 0x00005E07, 0x00000000, + 0x00050051, 0x0000000D, 0x00003CD5, 0x00005E07, 0x00000001, 0x00070050, 0x0000001D, 0x0000411F, + 0x00005F0B, 0x00003CD5, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C43, 0x00002ABF, + 0x00000002, 0x0004007C, 0x0000000C, 0x00003EA2, 0x00004C43, 0x00050050, 0x00000012, 0x0000471C, + 0x00003EA2, 0x00003EA2, 0x000500C4, 0x00000012, 0x000047AF, 0x0000471C, 0x000007A7, 0x000500C3, + 0x00000012, 0x00003419, 0x000047AF, 0x00000867, 0x0004006F, 0x00000013, 0x00002A99, 0x00003419, + 0x0005008E, 0x00000013, 0x00004749, 0x00002A99, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E08, + 0x00000001, 0x00000028, 0x00000049, 0x00004749, 0x00050051, 0x0000000D, 0x00005F0C, 0x00005E08, + 0x00000000, 0x00050051, 0x0000000D, 0x00003CD6, 0x00005E08, 0x00000001, 0x00070050, 0x0000001D, + 0x00004120, 0x00005F0C, 0x00003CD6, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C44, + 0x00002ABF, 0x00000003, 0x0004007C, 0x0000000C, 0x00003EA3, 0x00004C44, 0x00050050, 0x00000012, + 0x0000471D, 0x00003EA3, 0x00003EA3, 0x000500C4, 0x00000012, 0x000047B0, 0x0000471D, 0x000007A7, + 0x000500C3, 0x00000012, 0x0000341A, 0x000047B0, 0x00000867, 0x0004006F, 0x00000013, 0x00002A9A, + 0x0000341A, 0x0005008E, 0x00000013, 0x0000474A, 0x00002A9A, 0x000007FE, 0x0007000C, 0x00000013, + 0x00005E09, 0x00000001, 0x00000028, 0x00000049, 0x0000474A, 0x00050051, 0x0000000D, 0x00005F0D, + 0x00005E09, 0x00000000, 0x00050051, 0x0000000D, 0x0000494C, 0x00005E09, 0x00000001, 0x00070050, + 0x0000001D, 0x0000234A, 0x00005F0D, 0x0000494C, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F60, + 0x000200F8, 0x00001CBA, 0x00050051, 0x0000000B, 0x000056BD, 0x00002ABF, 0x00000000, 0x00060050, + 0x00000014, 0x00004F0A, 0x000056BD, 0x000056BD, 0x000056BD, 0x000500C2, 0x00000014, 0x00002B0D, + 0x00004F0A, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DE6, 0x00002B0D, 0x00000105, 0x000500C7, + 0x00000014, 0x0000489C, 0x00005DE6, 0x00000466, 0x000500C2, 0x00000014, 0x00005B90, 0x00005DE6, + 0x00000B0C, 0x000500AA, 0x00000010, 0x000040C9, 0x00005B90, 0x00000A12, 0x0006000C, 0x00000016, + 0x00002C4B, 0x00000001, 0x0000004B, 0x0000489C, 0x0004007C, 0x00000014, 0x00002A15, 0x00002C4B, + 0x00050082, 0x00000014, 0x0000187A, 0x00000B0C, 0x00002A15, 0x00050080, 0x00000014, 0x00002210, + 0x00002A15, 0x00000938, 0x000600A9, 0x00000014, 0x0000286F, 0x000040C9, 0x00002210, 0x00005B90, + 0x000500C4, 0x00000014, 0x00005AD4, 0x0000489C, 0x0000187A, 0x000500C7, 0x00000014, 0x0000499A, + 0x00005AD4, 0x00000466, 0x000600A9, 0x00000014, 0x00002A9D, 0x000040C9, 0x0000499A, 0x0000489C, + 0x00050080, 0x00000014, 0x00005FF9, 0x0000286F, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F7F, + 0x00005FF9, 0x00000189, 0x000500C4, 0x00000014, 0x00003FA6, 0x00002A9D, 0x0000008D, 0x000500C5, + 0x00000014, 0x0000577C, 0x00004F7F, 0x00003FA6, 0x000500AA, 0x00000010, 0x00003600, 0x00005DE6, + 0x00000A12, 0x000600A9, 0x00000014, 0x00004242, 0x00003600, 0x00000A12, 0x0000577C, 0x0004007C, + 0x00000018, 0x000029CF, 0x00004242, 0x000500C2, 0x0000000B, 0x00004BA4, 0x000056BD, 0x00000A64, + 0x00040070, 0x0000000D, 0x0000480E, 0x00004BA4, 0x00050085, 0x0000000D, 0x00003E1F, 0x0000480E, + 0x00000149, 0x00050051, 0x0000000D, 0x000053C2, 0x000029CF, 0x00000000, 0x00050051, 0x0000000D, + 0x00002A55, 0x000029CF, 0x00000001, 0x00050051, 0x0000000D, 0x00001E99, 0x000029CF, 0x00000002, + 0x00070050, 0x0000001D, 0x00003DDA, 0x000053C2, 0x00002A55, 0x00001E99, 0x00003E1F, 0x00050051, + 0x0000000B, 0x000027F5, 0x00002ABF, 0x00000001, 0x00060050, 0x00000014, 0x0000350E, 0x000027F5, + 0x000027F5, 0x000027F5, 0x000500C2, 0x00000014, 0x00002B0E, 0x0000350E, 0x00000BB4, 0x000500C7, + 0x00000014, 0x00005DE7, 0x00002B0E, 0x00000105, 0x000500C7, 0x00000014, 0x0000489D, 0x00005DE7, + 0x00000466, 0x000500C2, 0x00000014, 0x00005B91, 0x00005DE7, 0x00000B0C, 0x000500AA, 0x00000010, + 0x000040CA, 0x00005B91, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4C, 0x00000001, 0x0000004B, + 0x0000489D, 0x0004007C, 0x00000014, 0x00002A16, 0x00002C4C, 0x00050082, 0x00000014, 0x0000187B, + 0x00000B0C, 0x00002A16, 0x00050080, 0x00000014, 0x00002211, 0x00002A16, 0x00000938, 0x000600A9, + 0x00000014, 0x00002870, 0x000040CA, 0x00002211, 0x00005B91, 0x000500C4, 0x00000014, 0x00005AD5, + 0x0000489D, 0x0000187B, 0x000500C7, 0x00000014, 0x0000499B, 0x00005AD5, 0x00000466, 0x000600A9, + 0x00000014, 0x00002A9E, 0x000040CA, 0x0000499B, 0x0000489D, 0x00050080, 0x00000014, 0x00005FFA, + 0x00002870, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F80, 0x00005FFA, 0x00000189, 0x000500C4, + 0x00000014, 0x00003FA7, 0x00002A9E, 0x0000008D, 0x000500C5, 0x00000014, 0x0000577D, 0x00004F80, + 0x00003FA7, 0x000500AA, 0x00000010, 0x00003601, 0x00005DE7, 0x00000A12, 0x000600A9, 0x00000014, + 0x00004243, 0x00003601, 0x00000A12, 0x0000577D, 0x0004007C, 0x00000018, 0x000029D0, 0x00004243, + 0x000500C2, 0x0000000B, 0x00004BA5, 0x000027F5, 0x00000A64, 0x00040070, 0x0000000D, 0x0000480F, + 0x00004BA5, 0x00050085, 0x0000000D, 0x00003E20, 0x0000480F, 0x00000149, 0x00050051, 0x0000000D, + 0x000053C3, 0x000029D0, 0x00000000, 0x00050051, 0x0000000D, 0x00002A56, 0x000029D0, 0x00000001, + 0x00050051, 0x0000000D, 0x00001E9A, 0x000029D0, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDB, + 0x000053C3, 0x00002A56, 0x00001E9A, 0x00003E20, 0x00050051, 0x0000000B, 0x000027F6, 0x00002ABF, + 0x00000002, 0x00060050, 0x00000014, 0x0000350F, 0x000027F6, 0x000027F6, 0x000027F6, 0x000500C2, + 0x00000014, 0x00002B0F, 0x0000350F, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DE8, 0x00002B0F, + 0x00000105, 0x000500C7, 0x00000014, 0x0000489E, 0x00005DE8, 0x00000466, 0x000500C2, 0x00000014, + 0x00005B92, 0x00005DE8, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CB, 0x00005B92, 0x00000A12, + 0x0006000C, 0x00000016, 0x00002C4D, 0x00000001, 0x0000004B, 0x0000489E, 0x0004007C, 0x00000014, + 0x00002A17, 0x00002C4D, 0x00050082, 0x00000014, 0x0000187C, 0x00000B0C, 0x00002A17, 0x00050080, + 0x00000014, 0x00002212, 0x00002A17, 0x00000938, 0x000600A9, 0x00000014, 0x00002871, 0x000040CB, + 0x00002212, 0x00005B92, 0x000500C4, 0x00000014, 0x00005AD6, 0x0000489E, 0x0000187C, 0x000500C7, + 0x00000014, 0x0000499C, 0x00005AD6, 0x00000466, 0x000600A9, 0x00000014, 0x00002A9F, 0x000040CB, + 0x0000499C, 0x0000489E, 0x00050080, 0x00000014, 0x00005FFB, 0x00002871, 0x000003FA, 0x000500C4, + 0x00000014, 0x00004F81, 0x00005FFB, 0x00000189, 0x000500C4, 0x00000014, 0x00003FA8, 0x00002A9F, + 0x0000008D, 0x000500C5, 0x00000014, 0x0000577E, 0x00004F81, 0x00003FA8, 0x000500AA, 0x00000010, + 0x00003602, 0x00005DE8, 0x00000A12, 0x000600A9, 0x00000014, 0x00004244, 0x00003602, 0x00000A12, + 0x0000577E, 0x0004007C, 0x00000018, 0x000029D1, 0x00004244, 0x000500C2, 0x0000000B, 0x00004BA6, + 0x000027F6, 0x00000A64, 0x00040070, 0x0000000D, 0x00004810, 0x00004BA6, 0x00050085, 0x0000000D, + 0x00003E21, 0x00004810, 0x00000149, 0x00050051, 0x0000000D, 0x000053C4, 0x000029D1, 0x00000000, + 0x00050051, 0x0000000D, 0x00002A57, 0x000029D1, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9B, + 0x000029D1, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDC, 0x000053C4, 0x00002A57, 0x00001E9B, + 0x00003E21, 0x00050051, 0x0000000B, 0x000027F7, 0x00002ABF, 0x00000003, 0x00060050, 0x00000014, + 0x00003510, 0x000027F7, 0x000027F7, 0x000027F7, 0x000500C2, 0x00000014, 0x00002B10, 0x00003510, + 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DE9, 0x00002B10, 0x00000105, 0x000500C7, 0x00000014, + 0x0000489F, 0x00005DE9, 0x00000466, 0x000500C2, 0x00000014, 0x00005B93, 0x00005DE9, 0x00000B0C, + 0x000500AA, 0x00000010, 0x000040CC, 0x00005B93, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4E, + 0x00000001, 0x0000004B, 0x0000489F, 0x0004007C, 0x00000014, 0x00002A18, 0x00002C4E, 0x00050082, + 0x00000014, 0x0000187D, 0x00000B0C, 0x00002A18, 0x00050080, 0x00000014, 0x00002213, 0x00002A18, + 0x00000938, 0x000600A9, 0x00000014, 0x00002872, 0x000040CC, 0x00002213, 0x00005B93, 0x000500C4, + 0x00000014, 0x00005AD7, 0x0000489F, 0x0000187D, 0x000500C7, 0x00000014, 0x0000499D, 0x00005AD7, + 0x00000466, 0x000600A9, 0x00000014, 0x00002AA0, 0x000040CC, 0x0000499D, 0x0000489F, 0x00050080, + 0x00000014, 0x00005FFC, 0x00002872, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F82, 0x00005FFC, + 0x00000189, 0x000500C4, 0x00000014, 0x00003FA9, 0x00002AA0, 0x0000008D, 0x000500C5, 0x00000014, + 0x0000577F, 0x00004F82, 0x00003FA9, 0x000500AA, 0x00000010, 0x00003603, 0x00005DE9, 0x00000A12, + 0x000600A9, 0x00000014, 0x00004245, 0x00003603, 0x00000A12, 0x0000577F, 0x0004007C, 0x00000018, + 0x000029D2, 0x00004245, 0x000500C2, 0x0000000B, 0x00004BA7, 0x000027F7, 0x00000A64, 0x00040070, + 0x0000000D, 0x00004811, 0x00004BA7, 0x00050085, 0x0000000D, 0x00003E22, 0x00004811, 0x00000149, + 0x00050051, 0x0000000D, 0x000053C5, 0x000029D2, 0x00000000, 0x00050051, 0x0000000D, 0x00002A58, + 0x000029D2, 0x00000001, 0x00050051, 0x0000000D, 0x00002B11, 0x000029D2, 0x00000002, 0x00070050, + 0x0000001D, 0x0000234B, 0x000053C5, 0x00002A58, 0x00002B11, 0x00003E22, 0x000200F9, 0x00003F60, + 0x000200F8, 0x00001CBB, 0x00050051, 0x0000000B, 0x000056BE, 0x00002ABF, 0x00000000, 0x00070050, + 0x00000017, 0x00004F0B, 0x000056BE, 0x000056BE, 0x000056BE, 0x000056BE, 0x000500C2, 0x00000017, + 0x00002498, 0x00004F0B, 0x0000034D, 0x000500C7, 0x00000017, 0x000049AB, 0x00002498, 0x0000027B, + 0x00040070, 0x0000001D, 0x00003CB7, 0x000049AB, 0x00050085, 0x0000001D, 0x00004130, 0x00003CB7, + 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD2, 0x00002ABF, 0x00000001, 0x00070050, 0x00000017, + 0x0000514D, 0x00005CD2, 0x00005CD2, 0x00005CD2, 0x00005CD2, 0x000500C2, 0x00000017, 0x00002499, + 0x0000514D, 0x0000034D, 0x000500C7, 0x00000017, 0x000049AC, 0x00002499, 0x0000027B, 0x00040070, + 0x0000001D, 0x00003CB8, 0x000049AC, 0x00050085, 0x0000001D, 0x00004131, 0x00003CB8, 0x00000AEE, + 0x00050051, 0x0000000B, 0x00005CD3, 0x00002ABF, 0x00000002, 0x00070050, 0x00000017, 0x0000514E, + 0x00005CD3, 0x00005CD3, 0x00005CD3, 0x00005CD3, 0x000500C2, 0x00000017, 0x0000249A, 0x0000514E, + 0x0000034D, 0x000500C7, 0x00000017, 0x000049AD, 0x0000249A, 0x0000027B, 0x00040070, 0x0000001D, + 0x00003CB9, 0x000049AD, 0x00050085, 0x0000001D, 0x00004132, 0x00003CB9, 0x00000AEE, 0x00050051, + 0x0000000B, 0x00005CD4, 0x00002ABF, 0x00000003, 0x00070050, 0x00000017, 0x0000514F, 0x00005CD4, + 0x00005CD4, 0x00005CD4, 0x00005CD4, 0x000500C2, 0x00000017, 0x0000249B, 0x0000514F, 0x0000034D, + 0x000500C7, 0x00000017, 0x000049AE, 0x0000249B, 0x0000027B, 0x00040070, 0x0000001D, 0x0000492F, + 0x000049AE, 0x00050085, 0x0000001D, 0x0000269F, 0x0000492F, 0x00000AEE, 0x000200F9, 0x00003F60, + 0x000200F8, 0x000038F9, 0x00050051, 0x0000000B, 0x000056BF, 0x00002ABF, 0x00000000, 0x00070050, + 0x00000017, 0x00004F0C, 0x000056BF, 0x000056BF, 0x000056BF, 0x000056BF, 0x000500C2, 0x00000017, + 0x0000249C, 0x00004F0C, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A56, 0x0000249C, 0x0000064B, + 0x00040070, 0x0000001D, 0x000036A2, 0x00004A56, 0x0005008E, 0x0000001D, 0x00004B23, 0x000036A2, + 0x0000017A, 0x00050051, 0x0000000B, 0x0000219F, 0x00002ABF, 0x00000001, 0x00070050, 0x00000017, + 0x0000610B, 0x0000219F, 0x0000219F, 0x0000219F, 0x0000219F, 0x000500C2, 0x00000017, 0x0000249D, + 0x0000610B, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A57, 0x0000249D, 0x0000064B, 0x00040070, + 0x0000001D, 0x000036A3, 0x00004A57, 0x0005008E, 0x0000001D, 0x00004B24, 0x000036A3, 0x0000017A, + 0x00050051, 0x0000000B, 0x000021A0, 0x00002ABF, 0x00000002, 0x00070050, 0x00000017, 0x0000610C, + 0x000021A0, 0x000021A0, 0x000021A0, 0x000021A0, 0x000500C2, 0x00000017, 0x0000249E, 0x0000610C, + 0x0000028D, 0x000500C7, 0x00000017, 0x00004A58, 0x0000249E, 0x0000064B, 0x00040070, 0x0000001D, + 0x000036A4, 0x00004A58, 0x0005008E, 0x0000001D, 0x00004B25, 0x000036A4, 0x0000017A, 0x00050051, + 0x0000000B, 0x000021A1, 0x00002ABF, 0x00000003, 0x00070050, 0x00000017, 0x0000610D, 0x000021A1, + 0x000021A1, 0x000021A1, 0x000021A1, 0x000500C2, 0x00000017, 0x0000249F, 0x0000610D, 0x0000028D, + 0x000500C7, 0x00000017, 0x00004A59, 0x0000249F, 0x0000064B, 0x00040070, 0x0000001D, 0x0000431A, + 0x00004A59, 0x0005008E, 0x0000001D, 0x00003092, 0x0000431A, 0x0000017A, 0x000200F9, 0x00003F60, + 0x000200F8, 0x00004BFB, 0x00050051, 0x0000000B, 0x0000308C, 0x00002ABF, 0x00000000, 0x0004007C, + 0x0000000D, 0x00004FEE, 0x0000308C, 0x00050050, 0x00000013, 0x00004336, 0x00004FEE, 0x00000A0C, + 0x0009004F, 0x0000001D, 0x00002D90, 0x00004336, 0x00004336, 0x00000000, 0x00000001, 0x00000001, + 0x00000001, 0x00050051, 0x0000000B, 0x000056B1, 0x00002ABF, 0x00000001, 0x0004007C, 0x0000000D, + 0x00003F68, 0x000056B1, 0x00050050, 0x00000013, 0x00004337, 0x00003F68, 0x00000A0C, 0x0009004F, + 0x0000001D, 0x00002D91, 0x00004337, 0x00004337, 0x00000000, 0x00000001, 0x00000001, 0x00000001, + 0x00050051, 0x0000000B, 0x000056B2, 0x00002ABF, 0x00000002, 0x0004007C, 0x0000000D, 0x00003F69, + 0x000056B2, 0x00050050, 0x00000013, 0x00004338, 0x00003F69, 0x00000A0C, 0x0009004F, 0x0000001D, + 0x00002D92, 0x00004338, 0x00004338, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, + 0x0000000B, 0x000056B3, 0x00002ABF, 0x00000003, 0x0004007C, 0x0000000D, 0x00003F6A, 0x000056B3, + 0x00050050, 0x00000013, 0x00004FAE, 0x00003F6A, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3A, + 0x00004FAE, 0x00004FAE, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000200F9, 0x00003F60, + 0x000200F8, 0x00003F60, 0x000F00F5, 0x0000001D, 0x00002BA7, 0x00005A3A, 0x00004BFB, 0x00003092, + 0x000038F9, 0x0000269F, 0x00001CBB, 0x0000234B, 0x00001CBA, 0x0000234A, 0x00001FFE, 0x00002349, + 0x00002033, 0x000F00F5, 0x0000001D, 0x00003808, 0x00002D92, 0x00004BFB, 0x00004B25, 0x000038F9, + 0x00004132, 0x00001CBB, 0x00003DDC, 0x00001CBA, 0x00004120, 0x00001FFE, 0x0000390E, 0x00002033, + 0x000F00F5, 0x0000001D, 0x00003B7D, 0x00002D91, 0x00004BFB, 0x00004B24, 0x000038F9, 0x00004131, + 0x00001CBB, 0x00003DDB, 0x00001CBA, 0x0000411F, 0x00001FFE, 0x0000390D, 0x00002033, 0x000F00F5, + 0x0000001D, 0x000038B6, 0x00002D90, 0x00004BFB, 0x00004B23, 0x000038F9, 0x00004130, 0x00001CBB, + 0x00003DDA, 0x00001CBA, 0x0000411E, 0x00001FFE, 0x0000390C, 0x00002033, 0x000200F9, 0x0000530F, + 0x000200F8, 0x00003B65, 0x000500AA, 0x00000009, 0x00005450, 0x0000199B, 0x00000A10, 0x000300F7, + 0x00004F23, 0x00000002, 0x000400FA, 0x00005450, 0x00002622, 0x00002F62, 0x000200F8, 0x00002F62, + 0x00060041, 0x00000288, 0x00004BD0, 0x00000CC7, 0x00000A0B, 0x00005AD8, 0x0004003D, 0x0000000B, + 0x00005D45, 0x00004BD0, 0x00050080, 0x0000000B, 0x00002DAB, 0x00005AD8, 0x00000A0D, 0x00060041, + 0x00000288, 0x00001901, 0x00000CC7, 0x00000A0B, 0x00002DAB, 0x0004003D, 0x0000000B, 0x00005C64, + 0x00001901, 0x00050080, 0x0000000B, 0x00002DAC, 0x00005AD8, 0x0000199B, 0x00060041, 0x00000288, + 0x00001902, 0x00000CC7, 0x00000A0B, 0x00002DAC, 0x0004003D, 0x0000000B, 0x00005C65, 0x00001902, + 0x00050080, 0x0000000B, 0x00002DAD, 0x00002DAC, 0x00000A0D, 0x00060041, 0x00000288, 0x00005FEF, + 0x00000CC7, 0x00000A0B, 0x00002DAD, 0x0004003D, 0x0000000B, 0x0000374C, 0x00005FEF, 0x00070050, + 0x00000017, 0x00004CD6, 0x00005D45, 0x00005C64, 0x00005C65, 0x0000374C, 0x00050084, 0x0000000B, + 0x00004298, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000036A7, 0x00005AD8, 0x00004298, + 0x00060041, 0x00000288, 0x00003B81, 0x00000CC7, 0x00000A0B, 0x000036A7, 0x0004003D, 0x0000000B, + 0x00005C66, 0x00003B81, 0x00050080, 0x0000000B, 0x00002DAE, 0x000036A7, 0x00000A0D, 0x00060041, + 0x00000288, 0x0000194C, 0x00000CC7, 0x00000A0B, 0x00002DAE, 0x0004003D, 0x0000000B, 0x00005E5D, + 0x0000194C, 0x00050084, 0x0000000B, 0x0000185C, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, + 0x000020A3, 0x00005AD8, 0x0000185C, 0x00060041, 0x00000288, 0x00003B82, 0x00000CC7, 0x00000A0B, + 0x000020A3, 0x0004003D, 0x0000000B, 0x00005C67, 0x00003B82, 0x00050080, 0x0000000B, 0x00002DAF, + 0x000020A3, 0x00000A0D, 0x00060041, 0x00000288, 0x00005FF0, 0x00000CC7, 0x00000A0B, 0x00002DAF, + 0x0004003D, 0x0000000B, 0x00003FFD, 0x00005FF0, 0x00070050, 0x00000017, 0x0000512E, 0x00005C66, + 0x00005E5D, 0x00005C67, 0x00003FFD, 0x000200F9, 0x00004F23, 0x000200F8, 0x00002622, 0x00060041, + 0x00000288, 0x00005546, 0x00000CC7, 0x00000A0B, 0x00005AD8, 0x0004003D, 0x0000000B, 0x00005D46, + 0x00005546, 0x00050080, 0x0000000B, 0x00002DB0, 0x00005AD8, 0x00000A0D, 0x00060041, 0x00000288, + 0x00001903, 0x00000CC7, 0x00000A0B, 0x00002DB0, 0x0004003D, 0x0000000B, 0x00005C68, 0x00001903, + 0x00050080, 0x0000000B, 0x00002DB1, 0x00005AD8, 0x00000A10, 0x00060041, 0x00000288, 0x00001904, + 0x00000CC7, 0x00000A0B, 0x00002DB1, 0x0004003D, 0x0000000B, 0x00005C69, 0x00001904, 0x00050080, + 0x0000000B, 0x00002DB2, 0x00005AD8, 0x00000A13, 0x00060041, 0x00000288, 0x00005FF1, 0x00000CC7, + 0x00000A0B, 0x00002DB2, 0x0004003D, 0x0000000B, 0x00003700, 0x00005FF1, 0x00070050, 0x00000017, + 0x00004ADD, 0x00005D46, 0x00005C68, 0x00005C69, 0x00003700, 0x00050080, 0x0000000B, 0x000057E5, + 0x00005AD8, 0x00000A16, 0x00060041, 0x00000288, 0x0000604B, 0x00000CC7, 0x00000A0B, 0x000057E5, + 0x0004003D, 0x0000000B, 0x00005C6A, 0x0000604B, 0x00050080, 0x0000000B, 0x00002DB3, 0x00005AD8, + 0x00000A19, 0x00060041, 0x00000288, 0x00001905, 0x00000CC7, 0x00000A0B, 0x00002DB3, 0x0004003D, + 0x0000000B, 0x00005C6B, 0x00001905, 0x00050080, 0x0000000B, 0x00002DB4, 0x00005AD8, 0x00000A1C, + 0x00060041, 0x00000288, 0x00001906, 0x00000CC7, 0x00000A0B, 0x00002DB4, 0x0004003D, 0x0000000B, + 0x00005C6C, 0x00001906, 0x00050080, 0x0000000B, 0x00002DB5, 0x00005AD8, 0x00000A1F, 0x00060041, + 0x00000288, 0x00005FF2, 0x00000CC7, 0x00000A0B, 0x00002DB5, 0x0004003D, 0x0000000B, 0x00003FFE, + 0x00005FF2, 0x00070050, 0x00000017, 0x0000512F, 0x00005C6A, 0x00005C6B, 0x00005C6C, 0x00003FFE, + 0x000200F9, 0x00004F23, 0x000200F8, 0x00004F23, 0x000700F5, 0x00000017, 0x00002BCD, 0x0000512F, + 0x00002622, 0x0000512E, 0x00002F62, 0x000700F5, 0x00000017, 0x00003720, 0x00004ADD, 0x00002622, + 0x00004CD6, 0x00002F62, 0x000300F7, 0x00004F24, 0x00000000, 0x000700FB, 0x00002180, 0x00004F56, + 0x00000005, 0x00002158, 0x00000007, 0x00002034, 0x000200F8, 0x00002034, 0x00050051, 0x0000000B, + 0x00005F57, 0x00003720, 0x00000000, 0x0006000C, 0x00000013, 0x00006068, 0x00000001, 0x0000003E, + 0x00005F57, 0x00050051, 0x0000000D, 0x00002775, 0x00006068, 0x00000000, 0x00050051, 0x0000000D, + 0x00003EB8, 0x00006068, 0x00000001, 0x00050051, 0x0000000B, 0x00004281, 0x00003720, 0x00000001, + 0x0006000C, 0x00000013, 0x00003CF5, 0x00000001, 0x0000003E, 0x00004281, 0x00050051, 0x0000000D, + 0x00002766, 0x00003CF5, 0x00000000, 0x00050051, 0x0000000D, 0x00004449, 0x00003CF5, 0x00000001, + 0x00070050, 0x0000001D, 0x0000390F, 0x00002775, 0x00003EB8, 0x00002766, 0x00004449, 0x00050051, + 0x0000000B, 0x0000437D, 0x00003720, 0x00000002, 0x0006000C, 0x00000013, 0x0000466E, 0x00000001, + 0x0000003E, 0x0000437D, 0x00050051, 0x0000000D, 0x00002776, 0x0000466E, 0x00000000, 0x00050051, + 0x0000000D, 0x00003EB9, 0x0000466E, 0x00000001, 0x00050051, 0x0000000B, 0x00004282, 0x00003720, + 0x00000003, 0x0006000C, 0x00000013, 0x00003CF6, 0x00000001, 0x0000003E, 0x00004282, 0x00050051, + 0x0000000D, 0x00002767, 0x00003CF6, 0x00000000, 0x00050051, 0x0000000D, 0x0000444A, 0x00003CF6, + 0x00000001, 0x00070050, 0x0000001D, 0x00003910, 0x00002776, 0x00003EB9, 0x00002767, 0x0000444A, + 0x00050051, 0x0000000B, 0x0000437E, 0x00002BCD, 0x00000000, 0x0006000C, 0x00000013, 0x0000466F, + 0x00000001, 0x0000003E, 0x0000437E, 0x00050051, 0x0000000D, 0x00002777, 0x0000466F, 0x00000000, + 0x00050051, 0x0000000D, 0x00003EBA, 0x0000466F, 0x00000001, 0x00050051, 0x0000000B, 0x00004283, + 0x00002BCD, 0x00000001, 0x0006000C, 0x00000013, 0x00003CF7, 0x00000001, 0x0000003E, 0x00004283, + 0x00050051, 0x0000000D, 0x00002768, 0x00003CF7, 0x00000000, 0x00050051, 0x0000000D, 0x0000444B, + 0x00003CF7, 0x00000001, 0x00070050, 0x0000001D, 0x00003911, 0x00002777, 0x00003EBA, 0x00002768, + 0x0000444B, 0x00050051, 0x0000000B, 0x0000437F, 0x00002BCD, 0x00000002, 0x0006000C, 0x00000013, + 0x00004670, 0x00000001, 0x0000003E, 0x0000437F, 0x00050051, 0x0000000D, 0x00002778, 0x00004670, + 0x00000000, 0x00050051, 0x0000000D, 0x00003EBB, 0x00004670, 0x00000001, 0x00050051, 0x0000000B, + 0x00004284, 0x00002BCD, 0x00000003, 0x0006000C, 0x00000013, 0x00003CF8, 0x00000001, 0x0000003E, + 0x00004284, 0x00050051, 0x0000000D, 0x00002769, 0x00003CF8, 0x00000000, 0x00050051, 0x0000000D, + 0x000050BF, 0x00003CF8, 0x00000001, 0x00070050, 0x0000001D, 0x0000234C, 0x00002778, 0x00003EBB, + 0x00002769, 0x000050BF, 0x000200F9, 0x00004F24, 0x000200F8, 0x00002158, 0x0007004F, 0x00000011, + 0x000025FB, 0x00003720, 0x00003720, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x00005B3C, + 0x000025FB, 0x0009004F, 0x0000001A, 0x000060CE, 0x00005B3C, 0x00005B3C, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048A6, 0x000060CE, 0x00000122, 0x000500C3, + 0x0000001A, 0x00003D8D, 0x000048A6, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A9B, 0x00003D8D, + 0x0005008E, 0x0000001D, 0x00004721, 0x00002A9B, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006291, + 0x00000001, 0x00000028, 0x00000504, 0x00004721, 0x0007004F, 0x00000011, 0x0000376B, 0x00003720, + 0x00003720, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024BF, 0x0000376B, 0x0009004F, + 0x0000001A, 0x000060CF, 0x000024BF, 0x000024BF, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C4, 0x0000001A, 0x000048A7, 0x000060CF, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D8E, + 0x000048A7, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A9C, 0x00003D8E, 0x0005008E, 0x0000001D, + 0x00004722, 0x00002A9C, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006292, 0x00000001, 0x00000028, + 0x00000504, 0x00004722, 0x0007004F, 0x00000011, 0x0000376C, 0x00002BCD, 0x00002BCD, 0x00000000, + 0x00000001, 0x0004007C, 0x00000012, 0x000024C0, 0x0000376C, 0x0009004F, 0x0000001A, 0x000060D0, + 0x000024C0, 0x000024C0, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, + 0x000048A8, 0x000060D0, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D8F, 0x000048A8, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002AA1, 0x00003D8F, 0x0005008E, 0x0000001D, 0x00004723, 0x00002AA1, + 0x000007FE, 0x0007000C, 0x0000001D, 0x00006293, 0x00000001, 0x00000028, 0x00000504, 0x00004723, + 0x0007004F, 0x00000011, 0x0000376D, 0x00002BCD, 0x00002BCD, 0x00000002, 0x00000003, 0x0004007C, + 0x00000012, 0x000024C1, 0x0000376D, 0x0009004F, 0x0000001A, 0x000060D1, 0x000024C1, 0x000024C1, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048A9, 0x000060D1, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D90, 0x000048A9, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002AA2, 0x00003D90, 0x0005008E, 0x0000001D, 0x000053BF, 0x00002AA2, 0x000007FE, 0x0007000C, + 0x0000001D, 0x00004362, 0x00000001, 0x00000028, 0x00000504, 0x000053BF, 0x000200F9, 0x00004F24, + 0x000200F8, 0x00004F56, 0x0007004F, 0x00000011, 0x00002623, 0x00003720, 0x00003720, 0x00000000, + 0x00000001, 0x0004007C, 0x00000013, 0x00005159, 0x00002623, 0x00050051, 0x0000000D, 0x00001B7B, + 0x00005159, 0x00000000, 0x00050051, 0x0000000D, 0x0000346A, 0x00005159, 0x00000001, 0x00070050, + 0x0000001D, 0x00004278, 0x00001B7B, 0x0000346A, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, + 0x000041D8, 0x00003720, 0x00003720, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x0000375D, + 0x000041D8, 0x00050051, 0x0000000D, 0x00001B7C, 0x0000375D, 0x00000000, 0x00050051, 0x0000000D, + 0x0000346B, 0x0000375D, 0x00000001, 0x00070050, 0x0000001D, 0x00004279, 0x00001B7C, 0x0000346B, + 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041D9, 0x00002BCD, 0x00002BCD, 0x00000000, + 0x00000001, 0x0004007C, 0x00000013, 0x0000375E, 0x000041D9, 0x00050051, 0x0000000D, 0x00001B7D, + 0x0000375E, 0x00000000, 0x00050051, 0x0000000D, 0x0000346C, 0x0000375E, 0x00000001, 0x00070050, + 0x0000001D, 0x0000427A, 0x00001B7D, 0x0000346C, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, + 0x000041DA, 0x00002BCD, 0x00002BCD, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x0000375F, + 0x000041DA, 0x00050051, 0x0000000D, 0x00001B7E, 0x0000375F, 0x00000000, 0x00050051, 0x0000000D, + 0x00004108, 0x0000375F, 0x00000001, 0x00070050, 0x0000001D, 0x0000234D, 0x00001B7E, 0x00004108, + 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F24, 0x000200F8, 0x00004F24, 0x000900F5, 0x0000001D, + 0x00002BA8, 0x0000234D, 0x00004F56, 0x00004362, 0x00002158, 0x0000234C, 0x00002034, 0x000900F5, + 0x0000001D, 0x00003809, 0x0000427A, 0x00004F56, 0x00006293, 0x00002158, 0x00003911, 0x00002034, + 0x000900F5, 0x0000001D, 0x00003B7E, 0x00004279, 0x00004F56, 0x00006292, 0x00002158, 0x00003910, + 0x00002034, 0x000900F5, 0x0000001D, 0x000038B7, 0x00004278, 0x00004F56, 0x00006291, 0x00002158, + 0x0000390F, 0x00002034, 0x000200F9, 0x0000530F, 0x000200F8, 0x0000530F, 0x000700F5, 0x0000001D, + 0x00002BA9, 0x00002BA8, 0x00004F24, 0x00002BA7, 0x00003F60, 0x000700F5, 0x0000001D, 0x0000380A, + 0x00003809, 0x00004F24, 0x00003808, 0x00003F60, 0x000700F5, 0x0000001D, 0x000035EC, 0x00003B7E, + 0x00004F24, 0x00003B7D, 0x00003F60, 0x000700F5, 0x0000001D, 0x000020D3, 0x000038B7, 0x00004F24, + 0x000038B6, 0x00003F60, 0x000500AE, 0x00000009, 0x00002E55, 0x00003F4D, 0x00000A16, 0x000300F7, + 0x00005313, 0x00000002, 0x000400FA, 0x00002E55, 0x000050E5, 0x00005313, 0x000200F8, 0x000050E5, + 0x00050085, 0x0000000D, 0x000061FB, 0x00002B2C, 0x000000FC, 0x00050080, 0x0000000B, 0x00005E78, + 0x00005AD8, 0x00000AFA, 0x000300F7, 0x00005310, 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B66, + 0x000040BA, 0x000200F8, 0x000040BA, 0x000500AA, 0x00000009, 0x00004ADB, 0x0000199B, 0x00000A0D, + 0x000300F7, 0x00004F4A, 0x00000002, 0x000400FA, 0x00004ADB, 0x00002624, 0x00002F63, 0x000200F8, + 0x00002F63, 0x00060041, 0x00000288, 0x00004BD1, 0x00000CC7, 0x00000A0B, 0x00005E78, 0x0004003D, + 0x0000000B, 0x00005D47, 0x00004BD1, 0x00050080, 0x0000000B, 0x00002DB6, 0x00005E78, 0x0000199B, + 0x00060041, 0x00000288, 0x0000194D, 0x00000CC7, 0x00000A0B, 0x00002DB6, 0x0004003D, 0x0000000B, + 0x00005E5E, 0x0000194D, 0x00050084, 0x0000000B, 0x0000185D, 0x00000A10, 0x0000199B, 0x00050080, + 0x0000000B, 0x000020A4, 0x00005E78, 0x0000185D, 0x00060041, 0x00000288, 0x00003BCE, 0x00000CC7, + 0x00000A0B, 0x000020A4, 0x0004003D, 0x0000000B, 0x00005E5F, 0x00003BCE, 0x00050084, 0x0000000B, + 0x0000185E, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A5, 0x00005E78, 0x0000185E, + 0x00060041, 0x00000288, 0x000037F2, 0x00000CC7, 0x00000A0B, 0x000020A5, 0x0004003D, 0x0000000B, + 0x00003FFF, 0x000037F2, 0x00070050, 0x00000017, 0x00005130, 0x00005D47, 0x00005E5E, 0x00005E5F, + 0x00003FFF, 0x000200F9, 0x00004F4A, 0x000200F8, 0x00002624, 0x00060041, 0x00000288, 0x00005547, + 0x00000CC7, 0x00000A0B, 0x00005E78, 0x0004003D, 0x0000000B, 0x00005D48, 0x00005547, 0x00050080, + 0x0000000B, 0x00002DB7, 0x00005AD8, 0x00000AFD, 0x00060041, 0x00000288, 0x00001907, 0x00000CC7, + 0x00000A0B, 0x00002DB7, 0x0004003D, 0x0000000B, 0x00005C6D, 0x00001907, 0x00050080, 0x0000000B, + 0x00002DB8, 0x00005AD8, 0x00000B00, 0x00060041, 0x00000288, 0x00001908, 0x00000CC7, 0x00000A0B, + 0x00002DB8, 0x0004003D, 0x0000000B, 0x00005C6E, 0x00001908, 0x00050080, 0x0000000B, 0x00002DB9, + 0x00005AD8, 0x00000B03, 0x00060041, 0x00000288, 0x00005FF3, 0x00000CC7, 0x00000A0B, 0x00002DB9, + 0x0004003D, 0x0000000B, 0x00004000, 0x00005FF3, 0x00070050, 0x00000017, 0x00005131, 0x00005D48, + 0x00005C6D, 0x00005C6E, 0x00004000, 0x000200F9, 0x00004F4A, 0x000200F8, 0x00004F4A, 0x000700F5, + 0x00000017, 0x00002AC0, 0x00005131, 0x00002624, 0x00005130, 0x00002F63, 0x000300F7, 0x00003F61, + 0x00000000, 0x001300FB, 0x00002180, 0x00004BFC, 0x00000000, 0x000038FA, 0x00000001, 0x000038FA, + 0x00000002, 0x00001CBD, 0x0000000A, 0x00001CBD, 0x00000003, 0x00001CBC, 0x0000000C, 0x00001CBC, + 0x00000004, 0x00001FFF, 0x00000006, 0x00002035, 0x000200F8, 0x00002035, 0x00050051, 0x0000000B, + 0x00005F58, 0x00002AC0, 0x00000000, 0x0006000C, 0x00000013, 0x00006069, 0x00000001, 0x0000003E, + 0x00005F58, 0x00050051, 0x0000000D, 0x0000276A, 0x00006069, 0x00000000, 0x00050051, 0x0000000D, + 0x0000444C, 0x00006069, 0x00000001, 0x00070050, 0x0000001D, 0x00003912, 0x0000276A, 0x0000444C, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004380, 0x00002AC0, 0x00000001, 0x0006000C, + 0x00000013, 0x00004671, 0x00000001, 0x0000003E, 0x00004380, 0x00050051, 0x0000000D, 0x0000276B, + 0x00004671, 0x00000000, 0x00050051, 0x0000000D, 0x0000444D, 0x00004671, 0x00000001, 0x00070050, + 0x0000001D, 0x00003913, 0x0000276B, 0x0000444D, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x00004381, 0x00002AC0, 0x00000002, 0x0006000C, 0x00000013, 0x00004672, 0x00000001, 0x0000003E, + 0x00004381, 0x00050051, 0x0000000D, 0x0000276C, 0x00004672, 0x00000000, 0x00050051, 0x0000000D, + 0x0000444E, 0x00004672, 0x00000001, 0x00070050, 0x0000001D, 0x00003914, 0x0000276C, 0x0000444E, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004382, 0x00002AC0, 0x00000003, 0x0006000C, + 0x00000013, 0x00004673, 0x00000001, 0x0000003E, 0x00004382, 0x00050051, 0x0000000D, 0x0000276D, + 0x00004673, 0x00000000, 0x00050051, 0x0000000D, 0x000050C0, 0x00004673, 0x00000001, 0x00070050, + 0x0000001D, 0x0000234E, 0x0000276D, 0x000050C0, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F61, + 0x000200F8, 0x00001FFF, 0x00050051, 0x0000000B, 0x0000308D, 0x00002AC0, 0x00000000, 0x0004007C, + 0x0000000C, 0x0000589E, 0x0000308D, 0x00050050, 0x00000012, 0x0000471E, 0x0000589E, 0x0000589E, + 0x000500C4, 0x00000012, 0x000047B1, 0x0000471E, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341B, + 0x000047B1, 0x00000867, 0x0004006F, 0x00000013, 0x00002AA3, 0x0000341B, 0x0005008E, 0x00000013, + 0x0000474B, 0x00002AA3, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0A, 0x00000001, 0x00000028, + 0x00000049, 0x0000474B, 0x00050051, 0x0000000D, 0x00005F0E, 0x00005E0A, 0x00000000, 0x00050051, + 0x0000000D, 0x00003CD7, 0x00005E0A, 0x00000001, 0x00070050, 0x0000001D, 0x00004121, 0x00005F0E, + 0x00003CD7, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C45, 0x00002AC0, 0x00000001, + 0x0004007C, 0x0000000C, 0x00003EA4, 0x00004C45, 0x00050050, 0x00000012, 0x0000471F, 0x00003EA4, + 0x00003EA4, 0x000500C4, 0x00000012, 0x000047B2, 0x0000471F, 0x000007A7, 0x000500C3, 0x00000012, + 0x0000341C, 0x000047B2, 0x00000867, 0x0004006F, 0x00000013, 0x00002AA4, 0x0000341C, 0x0005008E, + 0x00000013, 0x0000474C, 0x00002AA4, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0B, 0x00000001, + 0x00000028, 0x00000049, 0x0000474C, 0x00050051, 0x0000000D, 0x00005F0F, 0x00005E0B, 0x00000000, + 0x00050051, 0x0000000D, 0x00003CD8, 0x00005E0B, 0x00000001, 0x00070050, 0x0000001D, 0x00004122, + 0x00005F0F, 0x00003CD8, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C46, 0x00002AC0, + 0x00000002, 0x0004007C, 0x0000000C, 0x00003EA5, 0x00004C46, 0x00050050, 0x00000012, 0x00004720, + 0x00003EA5, 0x00003EA5, 0x000500C4, 0x00000012, 0x000047B3, 0x00004720, 0x000007A7, 0x000500C3, + 0x00000012, 0x0000341D, 0x000047B3, 0x00000867, 0x0004006F, 0x00000013, 0x00002AA5, 0x0000341D, + 0x0005008E, 0x00000013, 0x0000474D, 0x00002AA5, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0C, + 0x00000001, 0x00000028, 0x00000049, 0x0000474D, 0x00050051, 0x0000000D, 0x00005F10, 0x00005E0C, + 0x00000000, 0x00050051, 0x0000000D, 0x00003CD9, 0x00005E0C, 0x00000001, 0x00070050, 0x0000001D, + 0x00004123, 0x00005F10, 0x00003CD9, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C47, + 0x00002AC0, 0x00000003, 0x0004007C, 0x0000000C, 0x00003EA6, 0x00004C47, 0x00050050, 0x00000012, + 0x00004724, 0x00003EA6, 0x00003EA6, 0x000500C4, 0x00000012, 0x000047B4, 0x00004724, 0x000007A7, + 0x000500C3, 0x00000012, 0x0000341E, 0x000047B4, 0x00000867, 0x0004006F, 0x00000013, 0x00002AA6, + 0x0000341E, 0x0005008E, 0x00000013, 0x0000474E, 0x00002AA6, 0x000007FE, 0x0007000C, 0x00000013, + 0x00005E0D, 0x00000001, 0x00000028, 0x00000049, 0x0000474E, 0x00050051, 0x0000000D, 0x00005F11, + 0x00005E0D, 0x00000000, 0x00050051, 0x0000000D, 0x0000494D, 0x00005E0D, 0x00000001, 0x00070050, + 0x0000001D, 0x0000234F, 0x00005F11, 0x0000494D, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F61, + 0x000200F8, 0x00001CBC, 0x00050051, 0x0000000B, 0x000056C0, 0x00002AC0, 0x00000000, 0x00060050, + 0x00000014, 0x00004F0D, 0x000056C0, 0x000056C0, 0x000056C0, 0x000500C2, 0x00000014, 0x00002B12, + 0x00004F0D, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEA, 0x00002B12, 0x00000105, 0x000500C7, + 0x00000014, 0x000048A0, 0x00005DEA, 0x00000466, 0x000500C2, 0x00000014, 0x00005B94, 0x00005DEA, + 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CD, 0x00005B94, 0x00000A12, 0x0006000C, 0x00000016, + 0x00002C4F, 0x00000001, 0x0000004B, 0x000048A0, 0x0004007C, 0x00000014, 0x00002A19, 0x00002C4F, + 0x00050082, 0x00000014, 0x0000187E, 0x00000B0C, 0x00002A19, 0x00050080, 0x00000014, 0x00002214, + 0x00002A19, 0x00000938, 0x000600A9, 0x00000014, 0x00002873, 0x000040CD, 0x00002214, 0x00005B94, + 0x000500C4, 0x00000014, 0x00005AD9, 0x000048A0, 0x0000187E, 0x000500C7, 0x00000014, 0x0000499E, + 0x00005AD9, 0x00000466, 0x000600A9, 0x00000014, 0x00002AA7, 0x000040CD, 0x0000499E, 0x000048A0, + 0x00050080, 0x00000014, 0x00005FFD, 0x00002873, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F83, + 0x00005FFD, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAA, 0x00002AA7, 0x0000008D, 0x000500C5, + 0x00000014, 0x00005780, 0x00004F83, 0x00003FAA, 0x000500AA, 0x00000010, 0x00003604, 0x00005DEA, + 0x00000A12, 0x000600A9, 0x00000014, 0x00004246, 0x00003604, 0x00000A12, 0x00005780, 0x0004007C, + 0x00000018, 0x000029D3, 0x00004246, 0x000500C2, 0x0000000B, 0x00004BA8, 0x000056C0, 0x00000A64, + 0x00040070, 0x0000000D, 0x00004812, 0x00004BA8, 0x00050085, 0x0000000D, 0x00003E23, 0x00004812, + 0x00000149, 0x00050051, 0x0000000D, 0x000053C6, 0x000029D3, 0x00000000, 0x00050051, 0x0000000D, + 0x00002A59, 0x000029D3, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9C, 0x000029D3, 0x00000002, + 0x00070050, 0x0000001D, 0x00003DDD, 0x000053C6, 0x00002A59, 0x00001E9C, 0x00003E23, 0x00050051, + 0x0000000B, 0x000027F8, 0x00002AC0, 0x00000001, 0x00060050, 0x00000014, 0x00003511, 0x000027F8, + 0x000027F8, 0x000027F8, 0x000500C2, 0x00000014, 0x00002B13, 0x00003511, 0x00000BB4, 0x000500C7, + 0x00000014, 0x00005DEB, 0x00002B13, 0x00000105, 0x000500C7, 0x00000014, 0x000048A1, 0x00005DEB, + 0x00000466, 0x000500C2, 0x00000014, 0x00005B95, 0x00005DEB, 0x00000B0C, 0x000500AA, 0x00000010, + 0x000040CE, 0x00005B95, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C50, 0x00000001, 0x0000004B, + 0x000048A1, 0x0004007C, 0x00000014, 0x00002A1A, 0x00002C50, 0x00050082, 0x00000014, 0x0000187F, + 0x00000B0C, 0x00002A1A, 0x00050080, 0x00000014, 0x00002215, 0x00002A1A, 0x00000938, 0x000600A9, + 0x00000014, 0x00002874, 0x000040CE, 0x00002215, 0x00005B95, 0x000500C4, 0x00000014, 0x00005ADA, + 0x000048A1, 0x0000187F, 0x000500C7, 0x00000014, 0x0000499F, 0x00005ADA, 0x00000466, 0x000600A9, + 0x00000014, 0x00002AA8, 0x000040CE, 0x0000499F, 0x000048A1, 0x00050080, 0x00000014, 0x00005FFE, + 0x00002874, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F84, 0x00005FFE, 0x00000189, 0x000500C4, + 0x00000014, 0x00003FAB, 0x00002AA8, 0x0000008D, 0x000500C5, 0x00000014, 0x00005781, 0x00004F84, + 0x00003FAB, 0x000500AA, 0x00000010, 0x00003605, 0x00005DEB, 0x00000A12, 0x000600A9, 0x00000014, + 0x00004247, 0x00003605, 0x00000A12, 0x00005781, 0x0004007C, 0x00000018, 0x000029D4, 0x00004247, + 0x000500C2, 0x0000000B, 0x00004BA9, 0x000027F8, 0x00000A64, 0x00040070, 0x0000000D, 0x00004813, + 0x00004BA9, 0x00050085, 0x0000000D, 0x00003E24, 0x00004813, 0x00000149, 0x00050051, 0x0000000D, + 0x000053C7, 0x000029D4, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5A, 0x000029D4, 0x00000001, + 0x00050051, 0x0000000D, 0x00001E9D, 0x000029D4, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDE, + 0x000053C7, 0x00002A5A, 0x00001E9D, 0x00003E24, 0x00050051, 0x0000000B, 0x000027F9, 0x00002AC0, + 0x00000002, 0x00060050, 0x00000014, 0x00003512, 0x000027F9, 0x000027F9, 0x000027F9, 0x000500C2, + 0x00000014, 0x00002B14, 0x00003512, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEC, 0x00002B14, + 0x00000105, 0x000500C7, 0x00000014, 0x000048A2, 0x00005DEC, 0x00000466, 0x000500C2, 0x00000014, + 0x00005B96, 0x00005DEC, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CF, 0x00005B96, 0x00000A12, + 0x0006000C, 0x00000016, 0x00002C51, 0x00000001, 0x0000004B, 0x000048A2, 0x0004007C, 0x00000014, + 0x00002A1B, 0x00002C51, 0x00050082, 0x00000014, 0x00001880, 0x00000B0C, 0x00002A1B, 0x00050080, + 0x00000014, 0x00002216, 0x00002A1B, 0x00000938, 0x000600A9, 0x00000014, 0x00002875, 0x000040CF, + 0x00002216, 0x00005B96, 0x000500C4, 0x00000014, 0x00005ADB, 0x000048A2, 0x00001880, 0x000500C7, + 0x00000014, 0x000049A0, 0x00005ADB, 0x00000466, 0x000600A9, 0x00000014, 0x00002AA9, 0x000040CF, + 0x000049A0, 0x000048A2, 0x00050080, 0x00000014, 0x00005FFF, 0x00002875, 0x000003FA, 0x000500C4, + 0x00000014, 0x00004F85, 0x00005FFF, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAC, 0x00002AA9, + 0x0000008D, 0x000500C5, 0x00000014, 0x00005782, 0x00004F85, 0x00003FAC, 0x000500AA, 0x00000010, + 0x00003606, 0x00005DEC, 0x00000A12, 0x000600A9, 0x00000014, 0x00004248, 0x00003606, 0x00000A12, + 0x00005782, 0x0004007C, 0x00000018, 0x000029D5, 0x00004248, 0x000500C2, 0x0000000B, 0x00004BAA, + 0x000027F9, 0x00000A64, 0x00040070, 0x0000000D, 0x00004814, 0x00004BAA, 0x00050085, 0x0000000D, + 0x00003E25, 0x00004814, 0x00000149, 0x00050051, 0x0000000D, 0x000053C8, 0x000029D5, 0x00000000, + 0x00050051, 0x0000000D, 0x00002A5B, 0x000029D5, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9E, + 0x000029D5, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDF, 0x000053C8, 0x00002A5B, 0x00001E9E, + 0x00003E25, 0x00050051, 0x0000000B, 0x000027FA, 0x00002AC0, 0x00000003, 0x00060050, 0x00000014, + 0x00003513, 0x000027FA, 0x000027FA, 0x000027FA, 0x000500C2, 0x00000014, 0x00002B15, 0x00003513, + 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DED, 0x00002B15, 0x00000105, 0x000500C7, 0x00000014, + 0x000048A3, 0x00005DED, 0x00000466, 0x000500C2, 0x00000014, 0x00005B97, 0x00005DED, 0x00000B0C, + 0x000500AA, 0x00000010, 0x000040D0, 0x00005B97, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C52, + 0x00000001, 0x0000004B, 0x000048A3, 0x0004007C, 0x00000014, 0x00002A1C, 0x00002C52, 0x00050082, + 0x00000014, 0x00001881, 0x00000B0C, 0x00002A1C, 0x00050080, 0x00000014, 0x00002217, 0x00002A1C, + 0x00000938, 0x000600A9, 0x00000014, 0x00002876, 0x000040D0, 0x00002217, 0x00005B97, 0x000500C4, + 0x00000014, 0x00005ADC, 0x000048A3, 0x00001881, 0x000500C7, 0x00000014, 0x000049A1, 0x00005ADC, + 0x00000466, 0x000600A9, 0x00000014, 0x00002AAA, 0x000040D0, 0x000049A1, 0x000048A3, 0x00050080, + 0x00000014, 0x00006000, 0x00002876, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F86, 0x00006000, + 0x00000189, 0x000500C4, 0x00000014, 0x00003FAD, 0x00002AAA, 0x0000008D, 0x000500C5, 0x00000014, + 0x00005783, 0x00004F86, 0x00003FAD, 0x000500AA, 0x00000010, 0x00003607, 0x00005DED, 0x00000A12, + 0x000600A9, 0x00000014, 0x00004249, 0x00003607, 0x00000A12, 0x00005783, 0x0004007C, 0x00000018, + 0x000029D6, 0x00004249, 0x000500C2, 0x0000000B, 0x00004BAB, 0x000027FA, 0x00000A64, 0x00040070, + 0x0000000D, 0x00004815, 0x00004BAB, 0x00050085, 0x0000000D, 0x00003E26, 0x00004815, 0x00000149, + 0x00050051, 0x0000000D, 0x000053C9, 0x000029D6, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5C, + 0x000029D6, 0x00000001, 0x00050051, 0x0000000D, 0x00002B16, 0x000029D6, 0x00000002, 0x00070050, + 0x0000001D, 0x00002350, 0x000053C9, 0x00002A5C, 0x00002B16, 0x00003E26, 0x000200F9, 0x00003F61, + 0x000200F8, 0x00001CBD, 0x00050051, 0x0000000B, 0x000056C1, 0x00002AC0, 0x00000000, 0x00070050, + 0x00000017, 0x00004F0E, 0x000056C1, 0x000056C1, 0x000056C1, 0x000056C1, 0x000500C2, 0x00000017, + 0x000024A0, 0x00004F0E, 0x0000034D, 0x000500C7, 0x00000017, 0x000049AF, 0x000024A0, 0x0000027B, + 0x00040070, 0x0000001D, 0x00003CBA, 0x000049AF, 0x00050085, 0x0000001D, 0x00004133, 0x00003CBA, + 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD5, 0x00002AC0, 0x00000001, 0x00070050, 0x00000017, + 0x00005150, 0x00005CD5, 0x00005CD5, 0x00005CD5, 0x00005CD5, 0x000500C2, 0x00000017, 0x000024A1, + 0x00005150, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B0, 0x000024A1, 0x0000027B, 0x00040070, + 0x0000001D, 0x00003CBB, 0x000049B0, 0x00050085, 0x0000001D, 0x00004134, 0x00003CBB, 0x00000AEE, + 0x00050051, 0x0000000B, 0x00005CD6, 0x00002AC0, 0x00000002, 0x00070050, 0x00000017, 0x00005151, + 0x00005CD6, 0x00005CD6, 0x00005CD6, 0x00005CD6, 0x000500C2, 0x00000017, 0x000024A2, 0x00005151, + 0x0000034D, 0x000500C7, 0x00000017, 0x000049B1, 0x000024A2, 0x0000027B, 0x00040070, 0x0000001D, + 0x00003CBC, 0x000049B1, 0x00050085, 0x0000001D, 0x00004135, 0x00003CBC, 0x00000AEE, 0x00050051, + 0x0000000B, 0x00005CD7, 0x00002AC0, 0x00000003, 0x00070050, 0x00000017, 0x00005152, 0x00005CD7, + 0x00005CD7, 0x00005CD7, 0x00005CD7, 0x000500C2, 0x00000017, 0x000024A3, 0x00005152, 0x0000034D, + 0x000500C7, 0x00000017, 0x000049B2, 0x000024A3, 0x0000027B, 0x00040070, 0x0000001D, 0x00004930, + 0x000049B2, 0x00050085, 0x0000001D, 0x000026A0, 0x00004930, 0x00000AEE, 0x000200F9, 0x00003F61, + 0x000200F8, 0x000038FA, 0x00050051, 0x0000000B, 0x000056C2, 0x00002AC0, 0x00000000, 0x00070050, + 0x00000017, 0x00004F0F, 0x000056C2, 0x000056C2, 0x000056C2, 0x000056C2, 0x000500C2, 0x00000017, + 0x000024A4, 0x00004F0F, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5A, 0x000024A4, 0x0000064B, + 0x00040070, 0x0000001D, 0x000036A5, 0x00004A5A, 0x0005008E, 0x0000001D, 0x00004B26, 0x000036A5, + 0x0000017A, 0x00050051, 0x0000000B, 0x000021A2, 0x00002AC0, 0x00000001, 0x00070050, 0x00000017, + 0x0000610E, 0x000021A2, 0x000021A2, 0x000021A2, 0x000021A2, 0x000500C2, 0x00000017, 0x000024A5, + 0x0000610E, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5B, 0x000024A5, 0x0000064B, 0x00040070, + 0x0000001D, 0x000036A6, 0x00004A5B, 0x0005008E, 0x0000001D, 0x00004B27, 0x000036A6, 0x0000017A, + 0x00050051, 0x0000000B, 0x000021A3, 0x00002AC0, 0x00000002, 0x00070050, 0x00000017, 0x0000610F, + 0x000021A3, 0x000021A3, 0x000021A3, 0x000021A3, 0x000500C2, 0x00000017, 0x000024A6, 0x0000610F, + 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5C, 0x000024A6, 0x0000064B, 0x00040070, 0x0000001D, + 0x000036A8, 0x00004A5C, 0x0005008E, 0x0000001D, 0x00004B28, 0x000036A8, 0x0000017A, 0x00050051, + 0x0000000B, 0x000021A4, 0x00002AC0, 0x00000003, 0x00070050, 0x00000017, 0x00006110, 0x000021A4, + 0x000021A4, 0x000021A4, 0x000021A4, 0x000500C2, 0x00000017, 0x000024A7, 0x00006110, 0x0000028D, + 0x000500C7, 0x00000017, 0x00004A5D, 0x000024A7, 0x0000064B, 0x00040070, 0x0000001D, 0x0000431B, + 0x00004A5D, 0x0005008E, 0x0000001D, 0x00003093, 0x0000431B, 0x0000017A, 0x000200F9, 0x00003F61, + 0x000200F8, 0x00004BFC, 0x00050051, 0x0000000B, 0x0000308E, 0x00002AC0, 0x00000000, 0x0004007C, + 0x0000000D, 0x00004FEF, 0x0000308E, 0x00050050, 0x00000013, 0x00004339, 0x00004FEF, 0x00000A0C, + 0x0009004F, 0x0000001D, 0x00002D93, 0x00004339, 0x00004339, 0x00000000, 0x00000001, 0x00000001, + 0x00000001, 0x00050051, 0x0000000B, 0x000056B4, 0x00002AC0, 0x00000001, 0x0004007C, 0x0000000D, + 0x00003F6B, 0x000056B4, 0x00050050, 0x00000013, 0x0000433A, 0x00003F6B, 0x00000A0C, 0x0009004F, + 0x0000001D, 0x00002D94, 0x0000433A, 0x0000433A, 0x00000000, 0x00000001, 0x00000001, 0x00000001, + 0x00050051, 0x0000000B, 0x000056B5, 0x00002AC0, 0x00000002, 0x0004007C, 0x0000000D, 0x00003F6C, + 0x000056B5, 0x00050050, 0x00000013, 0x0000433B, 0x00003F6C, 0x00000A0C, 0x0009004F, 0x0000001D, + 0x00002D95, 0x0000433B, 0x0000433B, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, + 0x0000000B, 0x000056B6, 0x00002AC0, 0x00000003, 0x0004007C, 0x0000000D, 0x00003F6D, 0x000056B6, + 0x00050050, 0x00000013, 0x00004FAF, 0x00003F6D, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3B, + 0x00004FAF, 0x00004FAF, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000200F9, 0x00003F61, + 0x000200F8, 0x00003F61, 0x000F00F5, 0x0000001D, 0x00002BAA, 0x00005A3B, 0x00004BFC, 0x00003093, + 0x000038FA, 0x000026A0, 0x00001CBD, 0x00002350, 0x00001CBC, 0x0000234F, 0x00001FFF, 0x0000234E, + 0x00002035, 0x000F00F5, 0x0000001D, 0x0000380B, 0x00002D95, 0x00004BFC, 0x00004B28, 0x000038FA, + 0x00004135, 0x00001CBD, 0x00003DDF, 0x00001CBC, 0x00004123, 0x00001FFF, 0x00003914, 0x00002035, + 0x000F00F5, 0x0000001D, 0x00003B7F, 0x00002D94, 0x00004BFC, 0x00004B27, 0x000038FA, 0x00004134, + 0x00001CBD, 0x00003DDE, 0x00001CBC, 0x00004122, 0x00001FFF, 0x00003913, 0x00002035, 0x000F00F5, + 0x0000001D, 0x000038B8, 0x00002D93, 0x00004BFC, 0x00004B26, 0x000038FA, 0x00004133, 0x00001CBD, + 0x00003DDD, 0x00001CBC, 0x00004121, 0x00001FFF, 0x00003912, 0x00002035, 0x000200F9, 0x00005310, + 0x000200F8, 0x00003B66, 0x000500AA, 0x00000009, 0x00005451, 0x0000199B, 0x00000A10, 0x000300F7, + 0x00004F25, 0x00000002, 0x000400FA, 0x00005451, 0x00002625, 0x00002F64, 0x000200F8, 0x00002F64, + 0x00060041, 0x00000288, 0x00004BD2, 0x00000CC7, 0x00000A0B, 0x00005E78, 0x0004003D, 0x0000000B, + 0x00005D49, 0x00004BD2, 0x00050080, 0x0000000B, 0x00002DBA, 0x00005AD8, 0x00000AFD, 0x00060041, + 0x00000288, 0x00001909, 0x00000CC7, 0x00000A0B, 0x00002DBA, 0x0004003D, 0x0000000B, 0x00005C6F, + 0x00001909, 0x00050080, 0x0000000B, 0x00002DBB, 0x00005E78, 0x0000199B, 0x00060041, 0x00000288, + 0x0000190A, 0x00000CC7, 0x00000A0B, 0x00002DBB, 0x0004003D, 0x0000000B, 0x00005C70, 0x0000190A, + 0x00050080, 0x0000000B, 0x00002DBC, 0x00002DBB, 0x00000A0D, 0x00060041, 0x00000288, 0x00005FF4, + 0x00000CC7, 0x00000A0B, 0x00002DBC, 0x0004003D, 0x0000000B, 0x0000374D, 0x00005FF4, 0x00070050, + 0x00000017, 0x00004CD7, 0x00005D49, 0x00005C6F, 0x00005C70, 0x0000374D, 0x00050084, 0x0000000B, + 0x00004299, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000036A9, 0x00005E78, 0x00004299, + 0x00060041, 0x00000288, 0x00003B83, 0x00000CC7, 0x00000A0B, 0x000036A9, 0x0004003D, 0x0000000B, + 0x00005C71, 0x00003B83, 0x00050080, 0x0000000B, 0x00002DBD, 0x000036A9, 0x00000A0D, 0x00060041, + 0x00000288, 0x0000194E, 0x00000CC7, 0x00000A0B, 0x00002DBD, 0x0004003D, 0x0000000B, 0x00005E60, + 0x0000194E, 0x00050084, 0x0000000B, 0x0000185F, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, + 0x000020A6, 0x00005E78, 0x0000185F, 0x00060041, 0x00000288, 0x00003B84, 0x00000CC7, 0x00000A0B, + 0x000020A6, 0x0004003D, 0x0000000B, 0x00005C72, 0x00003B84, 0x00050080, 0x0000000B, 0x00002DBE, + 0x000020A6, 0x00000A0D, 0x00060041, 0x00000288, 0x00005FF5, 0x00000CC7, 0x00000A0B, 0x00002DBE, + 0x0004003D, 0x0000000B, 0x00004001, 0x00005FF5, 0x00070050, 0x00000017, 0x00005132, 0x00005C71, + 0x00005E60, 0x00005C72, 0x00004001, 0x000200F9, 0x00004F25, 0x000200F8, 0x00002625, 0x00060041, + 0x00000288, 0x00005548, 0x00000CC7, 0x00000A0B, 0x00005E78, 0x0004003D, 0x0000000B, 0x00005D4A, + 0x00005548, 0x00050080, 0x0000000B, 0x00002DBF, 0x00005AD8, 0x00000AFD, 0x00060041, 0x00000288, + 0x0000190B, 0x00000CC7, 0x00000A0B, 0x00002DBF, 0x0004003D, 0x0000000B, 0x00005C73, 0x0000190B, + 0x00050080, 0x0000000B, 0x00002DC0, 0x00005AD8, 0x00000B00, 0x00060041, 0x00000288, 0x0000190C, + 0x00000CC7, 0x00000A0B, 0x00002DC0, 0x0004003D, 0x0000000B, 0x00005C74, 0x0000190C, 0x00050080, + 0x0000000B, 0x00002DC1, 0x00005AD8, 0x00000B03, 0x00060041, 0x00000288, 0x00005FF6, 0x00000CC7, + 0x00000A0B, 0x00002DC1, 0x0004003D, 0x0000000B, 0x00003701, 0x00005FF6, 0x00070050, 0x00000017, + 0x00004ADE, 0x00005D4A, 0x00005C73, 0x00005C74, 0x00003701, 0x00050080, 0x0000000B, 0x000057E6, + 0x00005AD8, 0x00000B06, 0x00060041, 0x00000288, 0x0000604C, 0x00000CC7, 0x00000A0B, 0x000057E6, + 0x0004003D, 0x0000000B, 0x00005C75, 0x0000604C, 0x00050080, 0x0000000B, 0x00002DC2, 0x00005AD8, + 0x00000B09, 0x00060041, 0x00000288, 0x0000190D, 0x00000CC7, 0x00000A0B, 0x00002DC2, 0x0004003D, + 0x0000000B, 0x00005C76, 0x0000190D, 0x00050080, 0x0000000B, 0x00002DC3, 0x00005AD8, 0x00000B0D, + 0x00060041, 0x00000288, 0x0000190E, 0x00000CC7, 0x00000A0B, 0x00002DC3, 0x0004003D, 0x0000000B, + 0x00005C77, 0x0000190E, 0x00050080, 0x0000000B, 0x00002DC4, 0x00005AD8, 0x00000B0F, 0x00060041, + 0x00000288, 0x00005FF7, 0x00000CC7, 0x00000A0B, 0x00002DC4, 0x0004003D, 0x0000000B, 0x00004002, + 0x00005FF7, 0x00070050, 0x00000017, 0x00005133, 0x00005C75, 0x00005C76, 0x00005C77, 0x00004002, + 0x000200F9, 0x00004F25, 0x000200F8, 0x00004F25, 0x000700F5, 0x00000017, 0x00002BCE, 0x00005133, + 0x00002625, 0x00005132, 0x00002F64, 0x000700F5, 0x00000017, 0x00003721, 0x00004ADE, 0x00002625, + 0x00004CD7, 0x00002F64, 0x000300F7, 0x00004F26, 0x00000000, 0x000700FB, 0x00002180, 0x00004F57, + 0x00000005, 0x00002159, 0x00000007, 0x00002036, 0x000200F8, 0x00002036, 0x00050051, 0x0000000B, + 0x00005F59, 0x00003721, 0x00000000, 0x0006000C, 0x00000013, 0x0000606A, 0x00000001, 0x0000003E, + 0x00005F59, 0x00050051, 0x0000000D, 0x00002779, 0x0000606A, 0x00000000, 0x00050051, 0x0000000D, + 0x00003EBC, 0x0000606A, 0x00000001, 0x00050051, 0x0000000B, 0x00004285, 0x00003721, 0x00000001, + 0x0006000C, 0x00000013, 0x00003CF9, 0x00000001, 0x0000003E, 0x00004285, 0x00050051, 0x0000000D, + 0x0000276E, 0x00003CF9, 0x00000000, 0x00050051, 0x0000000D, 0x0000444F, 0x00003CF9, 0x00000001, + 0x00070050, 0x0000001D, 0x00003915, 0x00002779, 0x00003EBC, 0x0000276E, 0x0000444F, 0x00050051, + 0x0000000B, 0x00004383, 0x00003721, 0x00000002, 0x0006000C, 0x00000013, 0x00004674, 0x00000001, + 0x0000003E, 0x00004383, 0x00050051, 0x0000000D, 0x0000277A, 0x00004674, 0x00000000, 0x00050051, + 0x0000000D, 0x00003EBD, 0x00004674, 0x00000001, 0x00050051, 0x0000000B, 0x00004286, 0x00003721, + 0x00000003, 0x0006000C, 0x00000013, 0x00003CFA, 0x00000001, 0x0000003E, 0x00004286, 0x00050051, + 0x0000000D, 0x0000276F, 0x00003CFA, 0x00000000, 0x00050051, 0x0000000D, 0x00004450, 0x00003CFA, + 0x00000001, 0x00070050, 0x0000001D, 0x00003916, 0x0000277A, 0x00003EBD, 0x0000276F, 0x00004450, + 0x00050051, 0x0000000B, 0x00004384, 0x00002BCE, 0x00000000, 0x0006000C, 0x00000013, 0x00004675, + 0x00000001, 0x0000003E, 0x00004384, 0x00050051, 0x0000000D, 0x0000277B, 0x00004675, 0x00000000, + 0x00050051, 0x0000000D, 0x00003EBE, 0x00004675, 0x00000001, 0x00050051, 0x0000000B, 0x00004287, + 0x00002BCE, 0x00000001, 0x0006000C, 0x00000013, 0x00003CFB, 0x00000001, 0x0000003E, 0x00004287, + 0x00050051, 0x0000000D, 0x00002770, 0x00003CFB, 0x00000000, 0x00050051, 0x0000000D, 0x00004451, + 0x00003CFB, 0x00000001, 0x00070050, 0x0000001D, 0x00003917, 0x0000277B, 0x00003EBE, 0x00002770, + 0x00004451, 0x00050051, 0x0000000B, 0x00004385, 0x00002BCE, 0x00000002, 0x0006000C, 0x00000013, + 0x00004676, 0x00000001, 0x0000003E, 0x00004385, 0x00050051, 0x0000000D, 0x0000277C, 0x00004676, + 0x00000000, 0x00050051, 0x0000000D, 0x00003EBF, 0x00004676, 0x00000001, 0x00050051, 0x0000000B, + 0x00004288, 0x00002BCE, 0x00000003, 0x0006000C, 0x00000013, 0x00003CFC, 0x00000001, 0x0000003E, + 0x00004288, 0x00050051, 0x0000000D, 0x00002771, 0x00003CFC, 0x00000000, 0x00050051, 0x0000000D, + 0x000050C1, 0x00003CFC, 0x00000001, 0x00070050, 0x0000001D, 0x00002351, 0x0000277C, 0x00003EBF, + 0x00002771, 0x000050C1, 0x000200F9, 0x00004F26, 0x000200F8, 0x00002159, 0x0007004F, 0x00000011, + 0x000025FC, 0x00003721, 0x00003721, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x00005B3D, + 0x000025FC, 0x0009004F, 0x0000001A, 0x000060D2, 0x00005B3D, 0x00005B3D, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048AA, 0x000060D2, 0x00000122, 0x000500C3, + 0x0000001A, 0x00003D91, 0x000048AA, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AAB, 0x00003D91, + 0x0005008E, 0x0000001D, 0x00004725, 0x00002AAB, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006294, + 0x00000001, 0x00000028, 0x00000504, 0x00004725, 0x0007004F, 0x00000011, 0x0000376E, 0x00003721, + 0x00003721, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C2, 0x0000376E, 0x0009004F, + 0x0000001A, 0x000060D3, 0x000024C2, 0x000024C2, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C4, 0x0000001A, 0x000048AB, 0x000060D3, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D92, + 0x000048AB, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AAC, 0x00003D92, 0x0005008E, 0x0000001D, + 0x00004726, 0x00002AAC, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006295, 0x00000001, 0x00000028, + 0x00000504, 0x00004726, 0x0007004F, 0x00000011, 0x0000376F, 0x00002BCE, 0x00002BCE, 0x00000000, + 0x00000001, 0x0004007C, 0x00000012, 0x000024C3, 0x0000376F, 0x0009004F, 0x0000001A, 0x000060D4, + 0x000024C3, 0x000024C3, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, + 0x000048AC, 0x000060D4, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D93, 0x000048AC, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002AAD, 0x00003D93, 0x0005008E, 0x0000001D, 0x00004727, 0x00002AAD, + 0x000007FE, 0x0007000C, 0x0000001D, 0x00006296, 0x00000001, 0x00000028, 0x00000504, 0x00004727, + 0x0007004F, 0x00000011, 0x00003770, 0x00002BCE, 0x00002BCE, 0x00000002, 0x00000003, 0x0004007C, + 0x00000012, 0x000024C4, 0x00003770, 0x0009004F, 0x0000001A, 0x000060D5, 0x000024C4, 0x000024C4, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048AD, 0x000060D5, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D94, 0x000048AD, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002AAE, 0x00003D94, 0x0005008E, 0x0000001D, 0x000053C0, 0x00002AAE, 0x000007FE, 0x0007000C, + 0x0000001D, 0x00004363, 0x00000001, 0x00000028, 0x00000504, 0x000053C0, 0x000200F9, 0x00004F26, + 0x000200F8, 0x00004F57, 0x0007004F, 0x00000011, 0x00002626, 0x00003721, 0x00003721, 0x00000000, + 0x00000001, 0x0004007C, 0x00000013, 0x0000515A, 0x00002626, 0x00050051, 0x0000000D, 0x00001B7F, + 0x0000515A, 0x00000000, 0x00050051, 0x0000000D, 0x0000346D, 0x0000515A, 0x00000001, 0x00070050, + 0x0000001D, 0x0000427B, 0x00001B7F, 0x0000346D, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, + 0x000041DB, 0x00003721, 0x00003721, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x00003760, + 0x000041DB, 0x00050051, 0x0000000D, 0x00001B80, 0x00003760, 0x00000000, 0x00050051, 0x0000000D, + 0x0000346E, 0x00003760, 0x00000001, 0x00070050, 0x0000001D, 0x0000427C, 0x00001B80, 0x0000346E, + 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DC, 0x00002BCE, 0x00002BCE, 0x00000000, + 0x00000001, 0x0004007C, 0x00000013, 0x00003761, 0x000041DC, 0x00050051, 0x0000000D, 0x00001B81, + 0x00003761, 0x00000000, 0x00050051, 0x0000000D, 0x0000346F, 0x00003761, 0x00000001, 0x00070050, + 0x0000001D, 0x0000427D, 0x00001B81, 0x0000346F, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, + 0x000041DD, 0x00002BCE, 0x00002BCE, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x00003762, + 0x000041DD, 0x00050051, 0x0000000D, 0x00001B82, 0x00003762, 0x00000000, 0x00050051, 0x0000000D, + 0x00004109, 0x00003762, 0x00000001, 0x00070050, 0x0000001D, 0x00002352, 0x00001B82, 0x00004109, + 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F26, 0x000200F8, 0x00004F26, 0x000900F5, 0x0000001D, + 0x00002BAB, 0x00002352, 0x00004F57, 0x00004363, 0x00002159, 0x00002351, 0x00002036, 0x000900F5, + 0x0000001D, 0x0000380C, 0x0000427D, 0x00004F57, 0x00006296, 0x00002159, 0x00003917, 0x00002036, + 0x000900F5, 0x0000001D, 0x00003B80, 0x0000427C, 0x00004F57, 0x00006295, 0x00002159, 0x00003916, + 0x00002036, 0x000900F5, 0x0000001D, 0x000038B9, 0x0000427B, 0x00004F57, 0x00006294, 0x00002159, + 0x00003915, 0x00002036, 0x000200F9, 0x00005310, 0x000200F8, 0x00005310, 0x000700F5, 0x0000001D, + 0x00002BAC, 0x00002BAB, 0x00004F26, 0x00002BAA, 0x00003F61, 0x000700F5, 0x0000001D, 0x0000380D, + 0x0000380C, 0x00004F26, 0x0000380B, 0x00003F61, 0x000700F5, 0x0000001D, 0x00003295, 0x00003B80, + 0x00004F26, 0x00003B7F, 0x00003F61, 0x000700F5, 0x0000001D, 0x0000367A, 0x000038B9, 0x00004F26, + 0x000038B8, 0x00003F61, 0x00050081, 0x0000001D, 0x00004359, 0x000020D3, 0x0000367A, 0x00050081, + 0x0000001D, 0x00005B01, 0x000035EC, 0x00003295, 0x00050081, 0x0000001D, 0x00001F92, 0x0000380A, + 0x0000380D, 0x00050081, 0x0000001D, 0x00005113, 0x00002BA9, 0x00002BAC, 0x000500AE, 0x00000009, + 0x0000387D, 0x00003F4D, 0x00000A1C, 0x000300F7, 0x00005EC8, 0x00000002, 0x000400FA, 0x0000387D, + 0x000026B1, 0x00005EC8, 0x000200F8, 0x000026B1, 0x000500C4, 0x0000000B, 0x000037B2, 0x00000A0D, + 0x000023AA, 0x00050085, 0x0000000D, 0x00002F3A, 0x00002B2C, 0x0000016E, 0x00050080, 0x0000000B, + 0x000051FC, 0x00005AD8, 0x000037B2, 0x000300F7, 0x00005311, 0x00000002, 0x000400FA, 0x00005AEF, + 0x00003B67, 0x000040BB, 0x000200F8, 0x000040BB, 0x000500AA, 0x00000009, 0x00004ADF, 0x0000199B, + 0x00000A0D, 0x000300F7, 0x00004F4B, 0x00000002, 0x000400FA, 0x00004ADF, 0x00002627, 0x00002F65, + 0x000200F8, 0x00002F65, 0x00060041, 0x00000288, 0x00004BD3, 0x00000CC7, 0x00000A0B, 0x000051FC, + 0x0004003D, 0x0000000B, 0x00005D4B, 0x00004BD3, 0x00050080, 0x0000000B, 0x00002DC5, 0x000051FC, + 0x0000199B, 0x00060041, 0x00000288, 0x0000194F, 0x00000CC7, 0x00000A0B, 0x00002DC5, 0x0004003D, + 0x0000000B, 0x00005E61, 0x0000194F, 0x00050084, 0x0000000B, 0x00001860, 0x00000A10, 0x0000199B, + 0x00050080, 0x0000000B, 0x000020A7, 0x000051FC, 0x00001860, 0x00060041, 0x00000288, 0x00003BCF, + 0x00000CC7, 0x00000A0B, 0x000020A7, 0x0004003D, 0x0000000B, 0x00005E62, 0x00003BCF, 0x00050084, + 0x0000000B, 0x00001861, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A8, 0x000051FC, + 0x00001861, 0x00060041, 0x00000288, 0x000037F3, 0x00000CC7, 0x00000A0B, 0x000020A8, 0x0004003D, + 0x0000000B, 0x00004003, 0x000037F3, 0x00070050, 0x00000017, 0x00005134, 0x00005D4B, 0x00005E61, + 0x00005E62, 0x00004003, 0x000200F9, 0x00004F4B, 0x000200F8, 0x00002627, 0x00060041, 0x00000288, + 0x00005549, 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, 0x00005D4C, 0x00005549, + 0x00050080, 0x0000000B, 0x00002DC6, 0x000051FC, 0x00000A0D, 0x00060041, 0x00000288, 0x0000190F, + 0x00000CC7, 0x00000A0B, 0x00002DC6, 0x0004003D, 0x0000000B, 0x00005C78, 0x0000190F, 0x00050080, + 0x0000000B, 0x00002DC7, 0x000051FC, 0x00000A10, 0x00060041, 0x00000288, 0x00001910, 0x00000CC7, + 0x00000A0B, 0x00002DC7, 0x0004003D, 0x0000000B, 0x00005C79, 0x00001910, 0x00050080, 0x0000000B, + 0x00002DC8, 0x000051FC, 0x00000A13, 0x00060041, 0x00000288, 0x00005FF8, 0x00000CC7, 0x00000A0B, + 0x00002DC8, 0x0004003D, 0x0000000B, 0x00004004, 0x00005FF8, 0x00070050, 0x00000017, 0x00005135, + 0x00005D4C, 0x00005C78, 0x00005C79, 0x00004004, 0x000200F9, 0x00004F4B, 0x000200F8, 0x00004F4B, + 0x000700F5, 0x00000017, 0x00002AC1, 0x00005135, 0x00002627, 0x00005134, 0x00002F65, 0x000300F7, + 0x00003F62, 0x00000000, 0x001300FB, 0x00002180, 0x00004BFD, 0x00000000, 0x000038FB, 0x00000001, + 0x000038FB, 0x00000002, 0x00001CBF, 0x0000000A, 0x00001CBF, 0x00000003, 0x00001CBE, 0x0000000C, + 0x00001CBE, 0x00000004, 0x00002000, 0x00000006, 0x00002037, 0x000200F8, 0x00002037, 0x00050051, + 0x0000000B, 0x00005F5A, 0x00002AC1, 0x00000000, 0x0006000C, 0x00000013, 0x0000606B, 0x00000001, + 0x0000003E, 0x00005F5A, 0x00050051, 0x0000000D, 0x00002772, 0x0000606B, 0x00000000, 0x00050051, + 0x0000000D, 0x00004452, 0x0000606B, 0x00000001, 0x00070050, 0x0000001D, 0x00003918, 0x00002772, + 0x00004452, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004386, 0x00002AC1, 0x00000001, + 0x0006000C, 0x00000013, 0x00004677, 0x00000001, 0x0000003E, 0x00004386, 0x00050051, 0x0000000D, + 0x00002773, 0x00004677, 0x00000000, 0x00050051, 0x0000000D, 0x00004453, 0x00004677, 0x00000001, + 0x00070050, 0x0000001D, 0x00003919, 0x00002773, 0x00004453, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x00004387, 0x00002AC1, 0x00000002, 0x0006000C, 0x00000013, 0x00004678, 0x00000001, + 0x0000003E, 0x00004387, 0x00050051, 0x0000000D, 0x00002774, 0x00004678, 0x00000000, 0x00050051, + 0x0000000D, 0x00004454, 0x00004678, 0x00000001, 0x00070050, 0x0000001D, 0x0000391A, 0x00002774, + 0x00004454, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004388, 0x00002AC1, 0x00000003, + 0x0006000C, 0x00000013, 0x00004679, 0x00000001, 0x0000003E, 0x00004388, 0x00050051, 0x0000000D, + 0x0000277D, 0x00004679, 0x00000000, 0x00050051, 0x0000000D, 0x000050C2, 0x00004679, 0x00000001, + 0x00070050, 0x0000001D, 0x00002353, 0x0000277D, 0x000050C2, 0x00000A0C, 0x00000A0C, 0x000200F9, + 0x00003F62, 0x000200F8, 0x00002000, 0x00050051, 0x0000000B, 0x0000308F, 0x00002AC1, 0x00000000, + 0x0004007C, 0x0000000C, 0x0000589F, 0x0000308F, 0x00050050, 0x00000012, 0x00004728, 0x0000589F, + 0x0000589F, 0x000500C4, 0x00000012, 0x000047B5, 0x00004728, 0x000007A7, 0x000500C3, 0x00000012, + 0x0000341F, 0x000047B5, 0x00000867, 0x0004006F, 0x00000013, 0x00002AAF, 0x0000341F, 0x0005008E, + 0x00000013, 0x0000474F, 0x00002AAF, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0E, 0x00000001, + 0x00000028, 0x00000049, 0x0000474F, 0x00050051, 0x0000000D, 0x00005F12, 0x00005E0E, 0x00000000, + 0x00050051, 0x0000000D, 0x00003CDA, 0x00005E0E, 0x00000001, 0x00070050, 0x0000001D, 0x00004124, + 0x00005F12, 0x00003CDA, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C48, 0x00002AC1, + 0x00000001, 0x0004007C, 0x0000000C, 0x00003EA7, 0x00004C48, 0x00050050, 0x00000012, 0x00004729, + 0x00003EA7, 0x00003EA7, 0x000500C4, 0x00000012, 0x000047B6, 0x00004729, 0x000007A7, 0x000500C3, + 0x00000012, 0x00003420, 0x000047B6, 0x00000867, 0x0004006F, 0x00000013, 0x00002AB0, 0x00003420, + 0x0005008E, 0x00000013, 0x00004750, 0x00002AB0, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0F, + 0x00000001, 0x00000028, 0x00000049, 0x00004750, 0x00050051, 0x0000000D, 0x00005F13, 0x00005E0F, + 0x00000000, 0x00050051, 0x0000000D, 0x00003CDB, 0x00005E0F, 0x00000001, 0x00070050, 0x0000001D, + 0x00004125, 0x00005F13, 0x00003CDB, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C49, + 0x00002AC1, 0x00000002, 0x0004007C, 0x0000000C, 0x00003EA8, 0x00004C49, 0x00050050, 0x00000012, + 0x0000472A, 0x00003EA8, 0x00003EA8, 0x000500C4, 0x00000012, 0x000047B7, 0x0000472A, 0x000007A7, + 0x000500C3, 0x00000012, 0x00003421, 0x000047B7, 0x00000867, 0x0004006F, 0x00000013, 0x00002AB1, + 0x00003421, 0x0005008E, 0x00000013, 0x00004751, 0x00002AB1, 0x000007FE, 0x0007000C, 0x00000013, + 0x00005E10, 0x00000001, 0x00000028, 0x00000049, 0x00004751, 0x00050051, 0x0000000D, 0x00005F14, + 0x00005E10, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDC, 0x00005E10, 0x00000001, 0x00070050, + 0x0000001D, 0x00004126, 0x00005F14, 0x00003CDC, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x00004C4A, 0x00002AC1, 0x00000003, 0x0004007C, 0x0000000C, 0x00003EA9, 0x00004C4A, 0x00050050, + 0x00000012, 0x0000472B, 0x00003EA9, 0x00003EA9, 0x000500C4, 0x00000012, 0x000047B8, 0x0000472B, + 0x000007A7, 0x000500C3, 0x00000012, 0x00003422, 0x000047B8, 0x00000867, 0x0004006F, 0x00000013, + 0x00002AB2, 0x00003422, 0x0005008E, 0x00000013, 0x00004752, 0x00002AB2, 0x000007FE, 0x0007000C, + 0x00000013, 0x00005E11, 0x00000001, 0x00000028, 0x00000049, 0x00004752, 0x00050051, 0x0000000D, + 0x00005F15, 0x00005E11, 0x00000000, 0x00050051, 0x0000000D, 0x0000494E, 0x00005E11, 0x00000001, + 0x00070050, 0x0000001D, 0x00002354, 0x00005F15, 0x0000494E, 0x00000A0C, 0x00000A0C, 0x000200F9, + 0x00003F62, 0x000200F8, 0x00001CBE, 0x00050051, 0x0000000B, 0x000056C3, 0x00002AC1, 0x00000000, + 0x00060050, 0x00000014, 0x00004F10, 0x000056C3, 0x000056C3, 0x000056C3, 0x000500C2, 0x00000014, + 0x00002B17, 0x00004F10, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEE, 0x00002B17, 0x00000105, + 0x000500C7, 0x00000014, 0x000048A4, 0x00005DEE, 0x00000466, 0x000500C2, 0x00000014, 0x00005B98, + 0x00005DEE, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D1, 0x00005B98, 0x00000A12, 0x0006000C, + 0x00000016, 0x00002C53, 0x00000001, 0x0000004B, 0x000048A4, 0x0004007C, 0x00000014, 0x00002A1D, + 0x00002C53, 0x00050082, 0x00000014, 0x00001882, 0x00000B0C, 0x00002A1D, 0x00050080, 0x00000014, + 0x00002218, 0x00002A1D, 0x00000938, 0x000600A9, 0x00000014, 0x00002877, 0x000040D1, 0x00002218, + 0x00005B98, 0x000500C4, 0x00000014, 0x00005ADD, 0x000048A4, 0x00001882, 0x000500C7, 0x00000014, + 0x000049A2, 0x00005ADD, 0x00000466, 0x000600A9, 0x00000014, 0x00002AB3, 0x000040D1, 0x000049A2, + 0x000048A4, 0x00050080, 0x00000014, 0x00006001, 0x00002877, 0x000003FA, 0x000500C4, 0x00000014, + 0x00004F87, 0x00006001, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAE, 0x00002AB3, 0x0000008D, + 0x000500C5, 0x00000014, 0x00005784, 0x00004F87, 0x00003FAE, 0x000500AA, 0x00000010, 0x00003608, + 0x00005DEE, 0x00000A12, 0x000600A9, 0x00000014, 0x0000424A, 0x00003608, 0x00000A12, 0x00005784, + 0x0004007C, 0x00000018, 0x000029D7, 0x0000424A, 0x000500C2, 0x0000000B, 0x00004BAC, 0x000056C3, + 0x00000A64, 0x00040070, 0x0000000D, 0x00004816, 0x00004BAC, 0x00050085, 0x0000000D, 0x00003E27, + 0x00004816, 0x00000149, 0x00050051, 0x0000000D, 0x000053CA, 0x000029D7, 0x00000000, 0x00050051, + 0x0000000D, 0x00002A5D, 0x000029D7, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9F, 0x000029D7, + 0x00000002, 0x00070050, 0x0000001D, 0x00003DE0, 0x000053CA, 0x00002A5D, 0x00001E9F, 0x00003E27, + 0x00050051, 0x0000000B, 0x000027FB, 0x00002AC1, 0x00000001, 0x00060050, 0x00000014, 0x00003514, + 0x000027FB, 0x000027FB, 0x000027FB, 0x000500C2, 0x00000014, 0x00002B18, 0x00003514, 0x00000BB4, + 0x000500C7, 0x00000014, 0x00005DEF, 0x00002B18, 0x00000105, 0x000500C7, 0x00000014, 0x000048A5, + 0x00005DEF, 0x00000466, 0x000500C2, 0x00000014, 0x00005B99, 0x00005DEF, 0x00000B0C, 0x000500AA, + 0x00000010, 0x000040D2, 0x00005B99, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C54, 0x00000001, + 0x0000004B, 0x000048A5, 0x0004007C, 0x00000014, 0x00002A1E, 0x00002C54, 0x00050082, 0x00000014, + 0x00001883, 0x00000B0C, 0x00002A1E, 0x00050080, 0x00000014, 0x00002219, 0x00002A1E, 0x00000938, + 0x000600A9, 0x00000014, 0x00002878, 0x000040D2, 0x00002219, 0x00005B99, 0x000500C4, 0x00000014, + 0x00005ADE, 0x000048A5, 0x00001883, 0x000500C7, 0x00000014, 0x000049A3, 0x00005ADE, 0x00000466, + 0x000600A9, 0x00000014, 0x00002AB4, 0x000040D2, 0x000049A3, 0x000048A5, 0x00050080, 0x00000014, + 0x00006002, 0x00002878, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F88, 0x00006002, 0x00000189, + 0x000500C4, 0x00000014, 0x00003FAF, 0x00002AB4, 0x0000008D, 0x000500C5, 0x00000014, 0x00005785, + 0x00004F88, 0x00003FAF, 0x000500AA, 0x00000010, 0x00003609, 0x00005DEF, 0x00000A12, 0x000600A9, + 0x00000014, 0x0000424B, 0x00003609, 0x00000A12, 0x00005785, 0x0004007C, 0x00000018, 0x000029D8, + 0x0000424B, 0x000500C2, 0x0000000B, 0x00004BAD, 0x000027FB, 0x00000A64, 0x00040070, 0x0000000D, + 0x00004817, 0x00004BAD, 0x00050085, 0x0000000D, 0x00003E28, 0x00004817, 0x00000149, 0x00050051, + 0x0000000D, 0x000053CB, 0x000029D8, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5E, 0x000029D8, + 0x00000001, 0x00050051, 0x0000000D, 0x00001EA0, 0x000029D8, 0x00000002, 0x00070050, 0x0000001D, + 0x00003DE1, 0x000053CB, 0x00002A5E, 0x00001EA0, 0x00003E28, 0x00050051, 0x0000000B, 0x000027FC, + 0x00002AC1, 0x00000002, 0x00060050, 0x00000014, 0x00003515, 0x000027FC, 0x000027FC, 0x000027FC, + 0x000500C2, 0x00000014, 0x00002B19, 0x00003515, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF0, + 0x00002B19, 0x00000105, 0x000500C7, 0x00000014, 0x000048AE, 0x00005DF0, 0x00000466, 0x000500C2, + 0x00000014, 0x00005B9A, 0x00005DF0, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D3, 0x00005B9A, + 0x00000A12, 0x0006000C, 0x00000016, 0x00002C55, 0x00000001, 0x0000004B, 0x000048AE, 0x0004007C, + 0x00000014, 0x00002A1F, 0x00002C55, 0x00050082, 0x00000014, 0x00001884, 0x00000B0C, 0x00002A1F, + 0x00050080, 0x00000014, 0x0000221A, 0x00002A1F, 0x00000938, 0x000600A9, 0x00000014, 0x00002879, + 0x000040D3, 0x0000221A, 0x00005B9A, 0x000500C4, 0x00000014, 0x00005ADF, 0x000048AE, 0x00001884, + 0x000500C7, 0x00000014, 0x000049A4, 0x00005ADF, 0x00000466, 0x000600A9, 0x00000014, 0x00002AB5, + 0x000040D3, 0x000049A4, 0x000048AE, 0x00050080, 0x00000014, 0x00006003, 0x00002879, 0x000003FA, + 0x000500C4, 0x00000014, 0x00004F89, 0x00006003, 0x00000189, 0x000500C4, 0x00000014, 0x00003FB0, + 0x00002AB5, 0x0000008D, 0x000500C5, 0x00000014, 0x00005786, 0x00004F89, 0x00003FB0, 0x000500AA, + 0x00000010, 0x0000360A, 0x00005DF0, 0x00000A12, 0x000600A9, 0x00000014, 0x0000424C, 0x0000360A, + 0x00000A12, 0x00005786, 0x0004007C, 0x00000018, 0x000029D9, 0x0000424C, 0x000500C2, 0x0000000B, + 0x00004BAE, 0x000027FC, 0x00000A64, 0x00040070, 0x0000000D, 0x00004818, 0x00004BAE, 0x00050085, + 0x0000000D, 0x00003E29, 0x00004818, 0x00000149, 0x00050051, 0x0000000D, 0x000053CC, 0x000029D9, + 0x00000000, 0x00050051, 0x0000000D, 0x00002A5F, 0x000029D9, 0x00000001, 0x00050051, 0x0000000D, + 0x00001EA1, 0x000029D9, 0x00000002, 0x00070050, 0x0000001D, 0x00003DE2, 0x000053CC, 0x00002A5F, + 0x00001EA1, 0x00003E29, 0x00050051, 0x0000000B, 0x000027FD, 0x00002AC1, 0x00000003, 0x00060050, + 0x00000014, 0x00003516, 0x000027FD, 0x000027FD, 0x000027FD, 0x000500C2, 0x00000014, 0x00002B1A, + 0x00003516, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF1, 0x00002B1A, 0x00000105, 0x000500C7, + 0x00000014, 0x000048AF, 0x00005DF1, 0x00000466, 0x000500C2, 0x00000014, 0x00005B9B, 0x00005DF1, + 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D4, 0x00005B9B, 0x00000A12, 0x0006000C, 0x00000016, + 0x00002C56, 0x00000001, 0x0000004B, 0x000048AF, 0x0004007C, 0x00000014, 0x00002A20, 0x00002C56, + 0x00050082, 0x00000014, 0x00001885, 0x00000B0C, 0x00002A20, 0x00050080, 0x00000014, 0x0000221B, + 0x00002A20, 0x00000938, 0x000600A9, 0x00000014, 0x0000287A, 0x000040D4, 0x0000221B, 0x00005B9B, + 0x000500C4, 0x00000014, 0x00005AE0, 0x000048AF, 0x00001885, 0x000500C7, 0x00000014, 0x000049A5, + 0x00005AE0, 0x00000466, 0x000600A9, 0x00000014, 0x00002AB6, 0x000040D4, 0x000049A5, 0x000048AF, + 0x00050080, 0x00000014, 0x00006004, 0x0000287A, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F8A, + 0x00006004, 0x00000189, 0x000500C4, 0x00000014, 0x00003FB1, 0x00002AB6, 0x0000008D, 0x000500C5, + 0x00000014, 0x00005787, 0x00004F8A, 0x00003FB1, 0x000500AA, 0x00000010, 0x0000360B, 0x00005DF1, + 0x00000A12, 0x000600A9, 0x00000014, 0x0000424D, 0x0000360B, 0x00000A12, 0x00005787, 0x0004007C, + 0x00000018, 0x000029DA, 0x0000424D, 0x000500C2, 0x0000000B, 0x00004BAF, 0x000027FD, 0x00000A64, + 0x00040070, 0x0000000D, 0x00004819, 0x00004BAF, 0x00050085, 0x0000000D, 0x00003E2A, 0x00004819, + 0x00000149, 0x00050051, 0x0000000D, 0x000053CD, 0x000029DA, 0x00000000, 0x00050051, 0x0000000D, + 0x00002A60, 0x000029DA, 0x00000001, 0x00050051, 0x0000000D, 0x00002B1B, 0x000029DA, 0x00000002, + 0x00070050, 0x0000001D, 0x00002355, 0x000053CD, 0x00002A60, 0x00002B1B, 0x00003E2A, 0x000200F9, + 0x00003F62, 0x000200F8, 0x00001CBF, 0x00050051, 0x0000000B, 0x000056C4, 0x00002AC1, 0x00000000, + 0x00070050, 0x00000017, 0x00004F11, 0x000056C4, 0x000056C4, 0x000056C4, 0x000056C4, 0x000500C2, + 0x00000017, 0x000024A8, 0x00004F11, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B3, 0x000024A8, + 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBD, 0x000049B3, 0x00050085, 0x0000001D, 0x00004136, + 0x00003CBD, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD8, 0x00002AC1, 0x00000001, 0x00070050, + 0x00000017, 0x00005153, 0x00005CD8, 0x00005CD8, 0x00005CD8, 0x00005CD8, 0x000500C2, 0x00000017, + 0x000024A9, 0x00005153, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B4, 0x000024A9, 0x0000027B, + 0x00040070, 0x0000001D, 0x00003CBE, 0x000049B4, 0x00050085, 0x0000001D, 0x00004137, 0x00003CBE, + 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD9, 0x00002AC1, 0x00000002, 0x00070050, 0x00000017, + 0x00005154, 0x00005CD9, 0x00005CD9, 0x00005CD9, 0x00005CD9, 0x000500C2, 0x00000017, 0x000024AA, + 0x00005154, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B5, 0x000024AA, 0x0000027B, 0x00040070, + 0x0000001D, 0x00003CBF, 0x000049B5, 0x00050085, 0x0000001D, 0x00004138, 0x00003CBF, 0x00000AEE, + 0x00050051, 0x0000000B, 0x00005CDA, 0x00002AC1, 0x00000003, 0x00070050, 0x00000017, 0x00005155, + 0x00005CDA, 0x00005CDA, 0x00005CDA, 0x00005CDA, 0x000500C2, 0x00000017, 0x000024AB, 0x00005155, + 0x0000034D, 0x000500C7, 0x00000017, 0x000049B6, 0x000024AB, 0x0000027B, 0x00040070, 0x0000001D, + 0x00004931, 0x000049B6, 0x00050085, 0x0000001D, 0x000026A1, 0x00004931, 0x00000AEE, 0x000200F9, + 0x00003F62, 0x000200F8, 0x000038FB, 0x00050051, 0x0000000B, 0x000056C5, 0x00002AC1, 0x00000000, + 0x00070050, 0x00000017, 0x00004F12, 0x000056C5, 0x000056C5, 0x000056C5, 0x000056C5, 0x000500C2, + 0x00000017, 0x000024AC, 0x00004F12, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5E, 0x000024AC, + 0x0000064B, 0x00040070, 0x0000001D, 0x000036AA, 0x00004A5E, 0x0005008E, 0x0000001D, 0x00004B29, + 0x000036AA, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A5, 0x00002AC1, 0x00000001, 0x00070050, + 0x00000017, 0x00006111, 0x000021A5, 0x000021A5, 0x000021A5, 0x000021A5, 0x000500C2, 0x00000017, + 0x000024AD, 0x00006111, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5F, 0x000024AD, 0x0000064B, + 0x00040070, 0x0000001D, 0x000036AB, 0x00004A5F, 0x0005008E, 0x0000001D, 0x00004B2A, 0x000036AB, + 0x0000017A, 0x00050051, 0x0000000B, 0x000021A6, 0x00002AC1, 0x00000002, 0x00070050, 0x00000017, + 0x00006112, 0x000021A6, 0x000021A6, 0x000021A6, 0x000021A6, 0x000500C2, 0x00000017, 0x000024AE, + 0x00006112, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A60, 0x000024AE, 0x0000064B, 0x00040070, + 0x0000001D, 0x000036AC, 0x00004A60, 0x0005008E, 0x0000001D, 0x00004B2B, 0x000036AC, 0x0000017A, + 0x00050051, 0x0000000B, 0x000021A7, 0x00002AC1, 0x00000003, 0x00070050, 0x00000017, 0x00006113, + 0x000021A7, 0x000021A7, 0x000021A7, 0x000021A7, 0x000500C2, 0x00000017, 0x000024AF, 0x00006113, + 0x0000028D, 0x000500C7, 0x00000017, 0x00004A61, 0x000024AF, 0x0000064B, 0x00040070, 0x0000001D, + 0x0000431C, 0x00004A61, 0x0005008E, 0x0000001D, 0x00003094, 0x0000431C, 0x0000017A, 0x000200F9, + 0x00003F62, 0x000200F8, 0x00004BFD, 0x00050051, 0x0000000B, 0x00003090, 0x00002AC1, 0x00000000, + 0x0004007C, 0x0000000D, 0x00004FF0, 0x00003090, 0x00050050, 0x00000013, 0x0000433C, 0x00004FF0, + 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D96, 0x0000433C, 0x0000433C, 0x00000000, 0x00000001, + 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B7, 0x00002AC1, 0x00000001, 0x0004007C, + 0x0000000D, 0x00003F6E, 0x000056B7, 0x00050050, 0x00000013, 0x0000433D, 0x00003F6E, 0x00000A0C, + 0x0009004F, 0x0000001D, 0x00002D97, 0x0000433D, 0x0000433D, 0x00000000, 0x00000001, 0x00000001, + 0x00000001, 0x00050051, 0x0000000B, 0x000056B8, 0x00002AC1, 0x00000002, 0x0004007C, 0x0000000D, + 0x00003F6F, 0x000056B8, 0x00050050, 0x00000013, 0x0000433E, 0x00003F6F, 0x00000A0C, 0x0009004F, + 0x0000001D, 0x00002D98, 0x0000433E, 0x0000433E, 0x00000000, 0x00000001, 0x00000001, 0x00000001, + 0x00050051, 0x0000000B, 0x000056B9, 0x00002AC1, 0x00000003, 0x0004007C, 0x0000000D, 0x00003F70, + 0x000056B9, 0x00050050, 0x00000013, 0x00004FB0, 0x00003F70, 0x00000A0C, 0x0009004F, 0x0000001D, + 0x00005A3C, 0x00004FB0, 0x00004FB0, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000200F9, + 0x00003F62, 0x000200F8, 0x00003F62, 0x000F00F5, 0x0000001D, 0x00002BAD, 0x00005A3C, 0x00004BFD, + 0x00003094, 0x000038FB, 0x000026A1, 0x00001CBF, 0x00002355, 0x00001CBE, 0x00002354, 0x00002000, + 0x00002353, 0x00002037, 0x000F00F5, 0x0000001D, 0x0000380E, 0x00002D98, 0x00004BFD, 0x00004B2B, + 0x000038FB, 0x00004138, 0x00001CBF, 0x00003DE2, 0x00001CBE, 0x00004126, 0x00002000, 0x0000391A, + 0x00002037, 0x000F00F5, 0x0000001D, 0x00003B85, 0x00002D97, 0x00004BFD, 0x00004B2A, 0x000038FB, + 0x00004137, 0x00001CBF, 0x00003DE1, 0x00001CBE, 0x00004125, 0x00002000, 0x00003919, 0x00002037, + 0x000F00F5, 0x0000001D, 0x000038BA, 0x00002D96, 0x00004BFD, 0x00004B29, 0x000038FB, 0x00004136, + 0x00001CBF, 0x00003DE0, 0x00001CBE, 0x00004124, 0x00002000, 0x00003918, 0x00002037, 0x000200F9, + 0x00005311, 0x000200F8, 0x00003B67, 0x000500AA, 0x00000009, 0x00005452, 0x0000199B, 0x00000A10, + 0x000300F7, 0x00004F27, 0x00000002, 0x000400FA, 0x00005452, 0x00002628, 0x00002F66, 0x000200F8, + 0x00002F66, 0x00060041, 0x00000288, 0x00004BD4, 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, + 0x0000000B, 0x00005D4D, 0x00004BD4, 0x00050080, 0x0000000B, 0x00002DC9, 0x000051FC, 0x00000A0D, + 0x00060041, 0x00000288, 0x00001911, 0x00000CC7, 0x00000A0B, 0x00002DC9, 0x0004003D, 0x0000000B, + 0x00005C7A, 0x00001911, 0x00050080, 0x0000000B, 0x00002DCA, 0x000051FC, 0x0000199B, 0x00060041, + 0x00000288, 0x00001912, 0x00000CC7, 0x00000A0B, 0x00002DCA, 0x0004003D, 0x0000000B, 0x00005C7B, + 0x00001912, 0x00050080, 0x0000000B, 0x00002DCB, 0x00002DCA, 0x00000A0D, 0x00060041, 0x00000288, + 0x00006005, 0x00000CC7, 0x00000A0B, 0x00002DCB, 0x0004003D, 0x0000000B, 0x0000374E, 0x00006005, + 0x00070050, 0x00000017, 0x00004CD9, 0x00005D4D, 0x00005C7A, 0x00005C7B, 0x0000374E, 0x00050084, + 0x0000000B, 0x0000429A, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000036AD, 0x000051FC, + 0x0000429A, 0x00060041, 0x00000288, 0x00003B86, 0x00000CC7, 0x00000A0B, 0x000036AD, 0x0004003D, + 0x0000000B, 0x00005C7C, 0x00003B86, 0x00050080, 0x0000000B, 0x00002DCC, 0x000036AD, 0x00000A0D, + 0x00060041, 0x00000288, 0x00001950, 0x00000CC7, 0x00000A0B, 0x00002DCC, 0x0004003D, 0x0000000B, + 0x00005E63, 0x00001950, 0x00050084, 0x0000000B, 0x00001862, 0x00000A13, 0x0000199B, 0x00050080, + 0x0000000B, 0x000020A9, 0x000051FC, 0x00001862, 0x00060041, 0x00000288, 0x00003B87, 0x00000CC7, + 0x00000A0B, 0x000020A9, 0x0004003D, 0x0000000B, 0x00005C7D, 0x00003B87, 0x00050080, 0x0000000B, + 0x00002DCD, 0x000020A9, 0x00000A0D, 0x00060041, 0x00000288, 0x00006006, 0x00000CC7, 0x00000A0B, + 0x00002DCD, 0x0004003D, 0x0000000B, 0x00004005, 0x00006006, 0x00070050, 0x00000017, 0x00005136, + 0x00005C7C, 0x00005E63, 0x00005C7D, 0x00004005, 0x000200F9, 0x00004F27, 0x000200F8, 0x00002628, + 0x00060041, 0x00000288, 0x0000554A, 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, + 0x00005D4E, 0x0000554A, 0x00050080, 0x0000000B, 0x00002DCE, 0x000051FC, 0x00000A0D, 0x00060041, + 0x00000288, 0x00001913, 0x00000CC7, 0x00000A0B, 0x00002DCE, 0x0004003D, 0x0000000B, 0x00005C7E, + 0x00001913, 0x00050080, 0x0000000B, 0x00002DCF, 0x000051FC, 0x00000A10, 0x00060041, 0x00000288, + 0x00001914, 0x00000CC7, 0x00000A0B, 0x00002DCF, 0x0004003D, 0x0000000B, 0x00005C7F, 0x00001914, + 0x00050080, 0x0000000B, 0x00002DD0, 0x000051FC, 0x00000A13, 0x00060041, 0x00000288, 0x00006007, + 0x00000CC7, 0x00000A0B, 0x00002DD0, 0x0004003D, 0x0000000B, 0x00003702, 0x00006007, 0x00070050, + 0x00000017, 0x00004AE0, 0x00005D4E, 0x00005C7E, 0x00005C7F, 0x00003702, 0x00050080, 0x0000000B, + 0x000057E7, 0x000051FC, 0x00000A16, 0x00060041, 0x00000288, 0x0000604D, 0x00000CC7, 0x00000A0B, + 0x000057E7, 0x0004003D, 0x0000000B, 0x00005C80, 0x0000604D, 0x00050080, 0x0000000B, 0x00002DD1, + 0x000051FC, 0x00000A19, 0x00060041, 0x00000288, 0x00001915, 0x00000CC7, 0x00000A0B, 0x00002DD1, + 0x0004003D, 0x0000000B, 0x00005C81, 0x00001915, 0x00050080, 0x0000000B, 0x00002DD2, 0x000051FC, + 0x00000A1C, 0x00060041, 0x00000288, 0x00001916, 0x00000CC7, 0x00000A0B, 0x00002DD2, 0x0004003D, + 0x0000000B, 0x00005C82, 0x00001916, 0x00050080, 0x0000000B, 0x00002DD3, 0x000051FC, 0x00000A1F, + 0x00060041, 0x00000288, 0x00006008, 0x00000CC7, 0x00000A0B, 0x00002DD3, 0x0004003D, 0x0000000B, + 0x00004006, 0x00006008, 0x00070050, 0x00000017, 0x00005137, 0x00005C80, 0x00005C81, 0x00005C82, + 0x00004006, 0x000200F9, 0x00004F27, 0x000200F8, 0x00004F27, 0x000700F5, 0x00000017, 0x00002BCF, + 0x00005137, 0x00002628, 0x00005136, 0x00002F66, 0x000700F5, 0x00000017, 0x00003722, 0x00004AE0, + 0x00002628, 0x00004CD9, 0x00002F66, 0x000300F7, 0x00004F28, 0x00000000, 0x000700FB, 0x00002180, + 0x00004F58, 0x00000005, 0x0000215A, 0x00000007, 0x00002038, 0x000200F8, 0x00002038, 0x00050051, + 0x0000000B, 0x00005F5B, 0x00003722, 0x00000000, 0x0006000C, 0x00000013, 0x0000606C, 0x00000001, + 0x0000003E, 0x00005F5B, 0x00050051, 0x0000000D, 0x0000277E, 0x0000606C, 0x00000000, 0x00050051, + 0x0000000D, 0x00003EC0, 0x0000606C, 0x00000001, 0x00050051, 0x0000000B, 0x00004289, 0x00003722, + 0x00000001, 0x0006000C, 0x00000013, 0x00003CFD, 0x00000001, 0x0000003E, 0x00004289, 0x00050051, + 0x0000000D, 0x0000277F, 0x00003CFD, 0x00000000, 0x00050051, 0x0000000D, 0x00004455, 0x00003CFD, + 0x00000001, 0x00070050, 0x0000001D, 0x0000391B, 0x0000277E, 0x00003EC0, 0x0000277F, 0x00004455, + 0x00050051, 0x0000000B, 0x00004389, 0x00003722, 0x00000002, 0x0006000C, 0x00000013, 0x0000467A, + 0x00000001, 0x0000003E, 0x00004389, 0x00050051, 0x0000000D, 0x00002780, 0x0000467A, 0x00000000, + 0x00050051, 0x0000000D, 0x00003EC1, 0x0000467A, 0x00000001, 0x00050051, 0x0000000B, 0x0000428A, + 0x00003722, 0x00000003, 0x0006000C, 0x00000013, 0x00003CFE, 0x00000001, 0x0000003E, 0x0000428A, + 0x00050051, 0x0000000D, 0x00002781, 0x00003CFE, 0x00000000, 0x00050051, 0x0000000D, 0x00004456, + 0x00003CFE, 0x00000001, 0x00070050, 0x0000001D, 0x0000391C, 0x00002780, 0x00003EC1, 0x00002781, + 0x00004456, 0x00050051, 0x0000000B, 0x0000438A, 0x00002BCF, 0x00000000, 0x0006000C, 0x00000013, + 0x0000467B, 0x00000001, 0x0000003E, 0x0000438A, 0x00050051, 0x0000000D, 0x00002782, 0x0000467B, + 0x00000000, 0x00050051, 0x0000000D, 0x00003EC2, 0x0000467B, 0x00000001, 0x00050051, 0x0000000B, + 0x0000428B, 0x00002BCF, 0x00000001, 0x0006000C, 0x00000013, 0x00003CFF, 0x00000001, 0x0000003E, + 0x0000428B, 0x00050051, 0x0000000D, 0x00002783, 0x00003CFF, 0x00000000, 0x00050051, 0x0000000D, + 0x00004457, 0x00003CFF, 0x00000001, 0x00070050, 0x0000001D, 0x0000391D, 0x00002782, 0x00003EC2, + 0x00002783, 0x00004457, 0x00050051, 0x0000000B, 0x0000438B, 0x00002BCF, 0x00000002, 0x0006000C, + 0x00000013, 0x0000467C, 0x00000001, 0x0000003E, 0x0000438B, 0x00050051, 0x0000000D, 0x00002784, + 0x0000467C, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC3, 0x0000467C, 0x00000001, 0x00050051, + 0x0000000B, 0x0000428C, 0x00002BCF, 0x00000003, 0x0006000C, 0x00000013, 0x00003D00, 0x00000001, + 0x0000003E, 0x0000428C, 0x00050051, 0x0000000D, 0x00002785, 0x00003D00, 0x00000000, 0x00050051, + 0x0000000D, 0x000050C3, 0x00003D00, 0x00000001, 0x00070050, 0x0000001D, 0x00002356, 0x00002784, + 0x00003EC3, 0x00002785, 0x000050C3, 0x000200F9, 0x00004F28, 0x000200F8, 0x0000215A, 0x0007004F, + 0x00000011, 0x000025FD, 0x00003722, 0x00003722, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, + 0x00005B3E, 0x000025FD, 0x0009004F, 0x0000001A, 0x000060D6, 0x00005B3E, 0x00005B3E, 0x00000000, + 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048B0, 0x000060D6, 0x00000122, + 0x000500C3, 0x0000001A, 0x00003D95, 0x000048B0, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AB7, + 0x00003D95, 0x0005008E, 0x0000001D, 0x0000472C, 0x00002AB7, 0x000007FE, 0x0007000C, 0x0000001D, + 0x00006297, 0x00000001, 0x00000028, 0x00000504, 0x0000472C, 0x0007004F, 0x00000011, 0x00003771, + 0x00003722, 0x00003722, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C5, 0x00003771, + 0x0009004F, 0x0000001A, 0x000060D7, 0x000024C5, 0x000024C5, 0x00000000, 0x00000000, 0x00000001, + 0x00000001, 0x000500C4, 0x0000001A, 0x000048B1, 0x000060D7, 0x00000122, 0x000500C3, 0x0000001A, + 0x00003D96, 0x000048B1, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AB8, 0x00003D96, 0x0005008E, + 0x0000001D, 0x0000472D, 0x00002AB8, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006298, 0x00000001, + 0x00000028, 0x00000504, 0x0000472D, 0x0007004F, 0x00000011, 0x00003772, 0x00002BCF, 0x00002BCF, + 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000024C6, 0x00003772, 0x0009004F, 0x0000001A, + 0x000060D8, 0x000024C6, 0x000024C6, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, + 0x0000001A, 0x000048B2, 0x000060D8, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D97, 0x000048B2, + 0x00000302, 0x0004006F, 0x0000001D, 0x00002AB9, 0x00003D97, 0x0005008E, 0x0000001D, 0x0000472E, + 0x00002AB9, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006299, 0x00000001, 0x00000028, 0x00000504, + 0x0000472E, 0x0007004F, 0x00000011, 0x00003773, 0x00002BCF, 0x00002BCF, 0x00000002, 0x00000003, + 0x0004007C, 0x00000012, 0x000024C7, 0x00003773, 0x0009004F, 0x0000001A, 0x000060D9, 0x000024C7, + 0x000024C7, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048B3, + 0x000060D9, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D98, 0x000048B3, 0x00000302, 0x0004006F, + 0x0000001D, 0x00002ABA, 0x00003D98, 0x0005008E, 0x0000001D, 0x000053C1, 0x00002ABA, 0x000007FE, + 0x0007000C, 0x0000001D, 0x00004364, 0x00000001, 0x00000028, 0x00000504, 0x000053C1, 0x000200F9, + 0x00004F28, 0x000200F8, 0x00004F58, 0x0007004F, 0x00000011, 0x00002629, 0x00003722, 0x00003722, + 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x0000515B, 0x00002629, 0x00050051, 0x0000000D, + 0x00001B83, 0x0000515B, 0x00000000, 0x00050051, 0x0000000D, 0x00003470, 0x0000515B, 0x00000001, + 0x00070050, 0x0000001D, 0x0000427E, 0x00001B83, 0x00003470, 0x00000A0C, 0x00000A0C, 0x0007004F, + 0x00000011, 0x000041DE, 0x00003722, 0x00003722, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, + 0x00003763, 0x000041DE, 0x00050051, 0x0000000D, 0x00001B84, 0x00003763, 0x00000000, 0x00050051, + 0x0000000D, 0x00003471, 0x00003763, 0x00000001, 0x00070050, 0x0000001D, 0x0000427F, 0x00001B84, + 0x00003471, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DF, 0x00002BCF, 0x00002BCF, + 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x00003764, 0x000041DF, 0x00050051, 0x0000000D, + 0x00001B85, 0x00003764, 0x00000000, 0x00050051, 0x0000000D, 0x00003472, 0x00003764, 0x00000001, + 0x00070050, 0x0000001D, 0x00004280, 0x00001B85, 0x00003472, 0x00000A0C, 0x00000A0C, 0x0007004F, + 0x00000011, 0x000041E0, 0x00002BCF, 0x00002BCF, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, + 0x00003765, 0x000041E0, 0x00050051, 0x0000000D, 0x00001B86, 0x00003765, 0x00000000, 0x00050051, + 0x0000000D, 0x0000410A, 0x00003765, 0x00000001, 0x00070050, 0x0000001D, 0x00002357, 0x00001B86, + 0x0000410A, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F28, 0x000200F8, 0x00004F28, 0x000900F5, + 0x0000001D, 0x00002BAE, 0x00002357, 0x00004F58, 0x00004364, 0x0000215A, 0x00002356, 0x00002038, + 0x000900F5, 0x0000001D, 0x0000380F, 0x00004280, 0x00004F58, 0x00006299, 0x0000215A, 0x0000391D, + 0x00002038, 0x000900F5, 0x0000001D, 0x00003B88, 0x0000427F, 0x00004F58, 0x00006298, 0x0000215A, + 0x0000391C, 0x00002038, 0x000900F5, 0x0000001D, 0x000038BB, 0x0000427E, 0x00004F58, 0x00006297, + 0x0000215A, 0x0000391B, 0x00002038, 0x000200F9, 0x00005311, 0x000200F8, 0x00005311, 0x000700F5, + 0x0000001D, 0x00002BAF, 0x00002BAE, 0x00004F28, 0x00002BAD, 0x00003F62, 0x000700F5, 0x0000001D, + 0x00003810, 0x0000380F, 0x00004F28, 0x0000380E, 0x00003F62, 0x000700F5, 0x0000001D, 0x00003296, + 0x00003B88, 0x00004F28, 0x00003B85, 0x00003F62, 0x000700F5, 0x0000001D, 0x0000367B, 0x000038BB, + 0x00004F28, 0x000038BA, 0x00003F62, 0x00050081, 0x0000001D, 0x0000435A, 0x00004359, 0x0000367B, + 0x00050081, 0x0000001D, 0x00005B02, 0x00005B01, 0x00003296, 0x00050081, 0x0000001D, 0x00001C28, + 0x00001F92, 0x00003810, 0x00050081, 0x0000001D, 0x000025AA, 0x00005113, 0x00002BAF, 0x00050080, + 0x0000000B, 0x00003FF8, 0x00005E78, 0x000037B2, 0x000300F7, 0x00005312, 0x00000002, 0x000400FA, + 0x00005AEF, 0x00003B68, 0x000040BC, 0x000200F8, 0x000040BC, 0x000500AA, 0x00000009, 0x00004AE1, + 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F4C, 0x00000002, 0x000400FA, 0x00004AE1, 0x0000262A, + 0x00002F67, 0x000200F8, 0x00002F67, 0x00060041, 0x00000288, 0x00004BD5, 0x00000CC7, 0x00000A0B, + 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D4F, 0x00004BD5, 0x00050080, 0x0000000B, 0x00002DD4, + 0x00003FF8, 0x0000199B, 0x00060041, 0x00000288, 0x00001951, 0x00000CC7, 0x00000A0B, 0x00002DD4, + 0x0004003D, 0x0000000B, 0x00005E64, 0x00001951, 0x00050084, 0x0000000B, 0x00001863, 0x00000A10, + 0x0000199B, 0x00050080, 0x0000000B, 0x000020AA, 0x00003FF8, 0x00001863, 0x00060041, 0x00000288, + 0x00003BD0, 0x00000CC7, 0x00000A0B, 0x000020AA, 0x0004003D, 0x0000000B, 0x00005E65, 0x00003BD0, + 0x00050084, 0x0000000B, 0x00001864, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020AB, + 0x00003FF8, 0x00001864, 0x00060041, 0x00000288, 0x000037F4, 0x00000CC7, 0x00000A0B, 0x000020AB, + 0x0004003D, 0x0000000B, 0x00004007, 0x000037F4, 0x00070050, 0x00000017, 0x00005138, 0x00005D4F, + 0x00005E64, 0x00005E65, 0x00004007, 0x000200F9, 0x00004F4C, 0x000200F8, 0x0000262A, 0x00060041, + 0x00000288, 0x0000554B, 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D50, + 0x0000554B, 0x00050080, 0x0000000B, 0x00002DD5, 0x00003FF8, 0x00000A0D, 0x00060041, 0x00000288, + 0x00001917, 0x00000CC7, 0x00000A0B, 0x00002DD5, 0x0004003D, 0x0000000B, 0x00005C83, 0x00001917, + 0x00050080, 0x0000000B, 0x00002DD6, 0x00003FF8, 0x00000A10, 0x00060041, 0x00000288, 0x00001918, + 0x00000CC7, 0x00000A0B, 0x00002DD6, 0x0004003D, 0x0000000B, 0x00005C84, 0x00001918, 0x00050080, + 0x0000000B, 0x00002DD7, 0x00003FF8, 0x00000A13, 0x00060041, 0x00000288, 0x00006009, 0x00000CC7, + 0x00000A0B, 0x00002DD7, 0x0004003D, 0x0000000B, 0x00004008, 0x00006009, 0x00070050, 0x00000017, + 0x00005139, 0x00005D50, 0x00005C83, 0x00005C84, 0x00004008, 0x000200F9, 0x00004F4C, 0x000200F8, + 0x00004F4C, 0x000700F5, 0x00000017, 0x00002AC2, 0x00005139, 0x0000262A, 0x00005138, 0x00002F67, + 0x000300F7, 0x00003F63, 0x00000000, 0x001300FB, 0x00002180, 0x00004BFE, 0x00000000, 0x000038FC, + 0x00000001, 0x000038FC, 0x00000002, 0x00001CC1, 0x0000000A, 0x00001CC1, 0x00000003, 0x00001CC0, + 0x0000000C, 0x00001CC0, 0x00000004, 0x00002001, 0x00000006, 0x00002039, 0x000200F8, 0x00002039, + 0x00050051, 0x0000000B, 0x00005F5C, 0x00002AC2, 0x00000000, 0x0006000C, 0x00000013, 0x0000606D, + 0x00000001, 0x0000003E, 0x00005F5C, 0x00050051, 0x0000000D, 0x00002786, 0x0000606D, 0x00000000, + 0x00050051, 0x0000000D, 0x00004458, 0x0000606D, 0x00000001, 0x00070050, 0x0000001D, 0x0000391E, + 0x00002786, 0x00004458, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x0000438C, 0x00002AC2, + 0x00000001, 0x0006000C, 0x00000013, 0x0000467D, 0x00000001, 0x0000003E, 0x0000438C, 0x00050051, + 0x0000000D, 0x00002787, 0x0000467D, 0x00000000, 0x00050051, 0x0000000D, 0x00004459, 0x0000467D, + 0x00000001, 0x00070050, 0x0000001D, 0x0000391F, 0x00002787, 0x00004459, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x0000438D, 0x00002AC2, 0x00000002, 0x0006000C, 0x00000013, 0x0000467E, + 0x00000001, 0x0000003E, 0x0000438D, 0x00050051, 0x0000000D, 0x00002788, 0x0000467E, 0x00000000, + 0x00050051, 0x0000000D, 0x0000445A, 0x0000467E, 0x00000001, 0x00070050, 0x0000001D, 0x00003920, + 0x00002788, 0x0000445A, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x0000438E, 0x00002AC2, + 0x00000003, 0x0006000C, 0x00000013, 0x0000467F, 0x00000001, 0x0000003E, 0x0000438E, 0x00050051, + 0x0000000D, 0x00002789, 0x0000467F, 0x00000000, 0x00050051, 0x0000000D, 0x000050C4, 0x0000467F, + 0x00000001, 0x00070050, 0x0000001D, 0x00002358, 0x00002789, 0x000050C4, 0x00000A0C, 0x00000A0C, + 0x000200F9, 0x00003F63, 0x000200F8, 0x00002001, 0x00050051, 0x0000000B, 0x00003091, 0x00002AC2, + 0x00000000, 0x0004007C, 0x0000000C, 0x000058A0, 0x00003091, 0x00050050, 0x00000012, 0x0000472F, + 0x000058A0, 0x000058A0, 0x000500C4, 0x00000012, 0x000047B9, 0x0000472F, 0x000007A7, 0x000500C3, + 0x00000012, 0x00003423, 0x000047B9, 0x00000867, 0x0004006F, 0x00000013, 0x00002ABB, 0x00003423, + 0x0005008E, 0x00000013, 0x00004753, 0x00002ABB, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E12, + 0x00000001, 0x00000028, 0x00000049, 0x00004753, 0x00050051, 0x0000000D, 0x00005F16, 0x00005E12, + 0x00000000, 0x00050051, 0x0000000D, 0x00003CDD, 0x00005E12, 0x00000001, 0x00070050, 0x0000001D, + 0x00004127, 0x00005F16, 0x00003CDD, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C4B, + 0x00002AC2, 0x00000001, 0x0004007C, 0x0000000C, 0x00003EAA, 0x00004C4B, 0x00050050, 0x00000012, + 0x00004730, 0x00003EAA, 0x00003EAA, 0x000500C4, 0x00000012, 0x000047BA, 0x00004730, 0x000007A7, + 0x000500C3, 0x00000012, 0x00003424, 0x000047BA, 0x00000867, 0x0004006F, 0x00000013, 0x00002ABC, + 0x00003424, 0x0005008E, 0x00000013, 0x00004754, 0x00002ABC, 0x000007FE, 0x0007000C, 0x00000013, + 0x00005E13, 0x00000001, 0x00000028, 0x00000049, 0x00004754, 0x00050051, 0x0000000D, 0x00005F17, + 0x00005E13, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDE, 0x00005E13, 0x00000001, 0x00070050, + 0x0000001D, 0x00004128, 0x00005F17, 0x00003CDE, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x00004C4C, 0x00002AC2, 0x00000002, 0x0004007C, 0x0000000C, 0x00003EAB, 0x00004C4C, 0x00050050, + 0x00000012, 0x00004731, 0x00003EAB, 0x00003EAB, 0x000500C4, 0x00000012, 0x000047BB, 0x00004731, + 0x000007A7, 0x000500C3, 0x00000012, 0x00003425, 0x000047BB, 0x00000867, 0x0004006F, 0x00000013, + 0x00002ABD, 0x00003425, 0x0005008E, 0x00000013, 0x00004755, 0x00002ABD, 0x000007FE, 0x0007000C, + 0x00000013, 0x00005E14, 0x00000001, 0x00000028, 0x00000049, 0x00004755, 0x00050051, 0x0000000D, + 0x00005F18, 0x00005E14, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDF, 0x00005E14, 0x00000001, + 0x00070050, 0x0000001D, 0x00004129, 0x00005F18, 0x00003CDF, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x00004C4D, 0x00002AC2, 0x00000003, 0x0004007C, 0x0000000C, 0x00003EAC, 0x00004C4D, + 0x00050050, 0x00000012, 0x00004732, 0x00003EAC, 0x00003EAC, 0x000500C4, 0x00000012, 0x000047BC, + 0x00004732, 0x000007A7, 0x000500C3, 0x00000012, 0x00003426, 0x000047BC, 0x00000867, 0x0004006F, + 0x00000013, 0x00002ABE, 0x00003426, 0x0005008E, 0x00000013, 0x00004756, 0x00002ABE, 0x000007FE, + 0x0007000C, 0x00000013, 0x00005E15, 0x00000001, 0x00000028, 0x00000049, 0x00004756, 0x00050051, + 0x0000000D, 0x00005F19, 0x00005E15, 0x00000000, 0x00050051, 0x0000000D, 0x0000494F, 0x00005E15, + 0x00000001, 0x00070050, 0x0000001D, 0x00002359, 0x00005F19, 0x0000494F, 0x00000A0C, 0x00000A0C, + 0x000200F9, 0x00003F63, 0x000200F8, 0x00001CC0, 0x00050051, 0x0000000B, 0x000056C6, 0x00002AC2, + 0x00000000, 0x00060050, 0x00000014, 0x00004F13, 0x000056C6, 0x000056C6, 0x000056C6, 0x000500C2, + 0x00000014, 0x00002B1C, 0x00004F13, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF2, 0x00002B1C, + 0x00000105, 0x000500C7, 0x00000014, 0x000048B4, 0x00005DF2, 0x00000466, 0x000500C2, 0x00000014, + 0x00005B9C, 0x00005DF2, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D5, 0x00005B9C, 0x00000A12, + 0x0006000C, 0x00000016, 0x00002C57, 0x00000001, 0x0000004B, 0x000048B4, 0x0004007C, 0x00000014, + 0x00002A21, 0x00002C57, 0x00050082, 0x00000014, 0x00001886, 0x00000B0C, 0x00002A21, 0x00050080, + 0x00000014, 0x0000221C, 0x00002A21, 0x00000938, 0x000600A9, 0x00000014, 0x0000287B, 0x000040D5, + 0x0000221C, 0x00005B9C, 0x000500C4, 0x00000014, 0x00005AE1, 0x000048B4, 0x00001886, 0x000500C7, + 0x00000014, 0x000049A6, 0x00005AE1, 0x00000466, 0x000600A9, 0x00000014, 0x00002AC3, 0x000040D5, + 0x000049A6, 0x000048B4, 0x00050080, 0x00000014, 0x0000600A, 0x0000287B, 0x000003FA, 0x000500C4, + 0x00000014, 0x00004F8B, 0x0000600A, 0x00000189, 0x000500C4, 0x00000014, 0x00003FB2, 0x00002AC3, + 0x0000008D, 0x000500C5, 0x00000014, 0x00005788, 0x00004F8B, 0x00003FB2, 0x000500AA, 0x00000010, + 0x0000360C, 0x00005DF2, 0x00000A12, 0x000600A9, 0x00000014, 0x0000424E, 0x0000360C, 0x00000A12, + 0x00005788, 0x0004007C, 0x00000018, 0x000029DB, 0x0000424E, 0x000500C2, 0x0000000B, 0x00004BB0, + 0x000056C6, 0x00000A64, 0x00040070, 0x0000000D, 0x0000481A, 0x00004BB0, 0x00050085, 0x0000000D, + 0x00003E2B, 0x0000481A, 0x00000149, 0x00050051, 0x0000000D, 0x000053CE, 0x000029DB, 0x00000000, + 0x00050051, 0x0000000D, 0x00002A61, 0x000029DB, 0x00000001, 0x00050051, 0x0000000D, 0x00001EA2, + 0x000029DB, 0x00000002, 0x00070050, 0x0000001D, 0x00003DE3, 0x000053CE, 0x00002A61, 0x00001EA2, + 0x00003E2B, 0x00050051, 0x0000000B, 0x000027FE, 0x00002AC2, 0x00000001, 0x00060050, 0x00000014, + 0x00003517, 0x000027FE, 0x000027FE, 0x000027FE, 0x000500C2, 0x00000014, 0x00002B1D, 0x00003517, + 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF3, 0x00002B1D, 0x00000105, 0x000500C7, 0x00000014, + 0x000048B5, 0x00005DF3, 0x00000466, 0x000500C2, 0x00000014, 0x00005B9D, 0x00005DF3, 0x00000B0C, + 0x000500AA, 0x00000010, 0x000040D6, 0x00005B9D, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C58, + 0x00000001, 0x0000004B, 0x000048B5, 0x0004007C, 0x00000014, 0x00002A22, 0x00002C58, 0x00050082, + 0x00000014, 0x00001887, 0x00000B0C, 0x00002A22, 0x00050080, 0x00000014, 0x0000221D, 0x00002A22, + 0x00000938, 0x000600A9, 0x00000014, 0x0000287C, 0x000040D6, 0x0000221D, 0x00005B9D, 0x000500C4, + 0x00000014, 0x00005AE2, 0x000048B5, 0x00001887, 0x000500C7, 0x00000014, 0x000049A7, 0x00005AE2, + 0x00000466, 0x000600A9, 0x00000014, 0x00002AC4, 0x000040D6, 0x000049A7, 0x000048B5, 0x00050080, + 0x00000014, 0x0000600B, 0x0000287C, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F8C, 0x0000600B, + 0x00000189, 0x000500C4, 0x00000014, 0x00003FB3, 0x00002AC4, 0x0000008D, 0x000500C5, 0x00000014, + 0x00005789, 0x00004F8C, 0x00003FB3, 0x000500AA, 0x00000010, 0x0000360D, 0x00005DF3, 0x00000A12, + 0x000600A9, 0x00000014, 0x0000424F, 0x0000360D, 0x00000A12, 0x00005789, 0x0004007C, 0x00000018, + 0x000029DC, 0x0000424F, 0x000500C2, 0x0000000B, 0x00004BB1, 0x000027FE, 0x00000A64, 0x00040070, + 0x0000000D, 0x0000481B, 0x00004BB1, 0x00050085, 0x0000000D, 0x00003E2C, 0x0000481B, 0x00000149, + 0x00050051, 0x0000000D, 0x000053CF, 0x000029DC, 0x00000000, 0x00050051, 0x0000000D, 0x00002A62, + 0x000029DC, 0x00000001, 0x00050051, 0x0000000D, 0x00001EA3, 0x000029DC, 0x00000002, 0x00070050, + 0x0000001D, 0x00003DE4, 0x000053CF, 0x00002A62, 0x00001EA3, 0x00003E2C, 0x00050051, 0x0000000B, + 0x000027FF, 0x00002AC2, 0x00000002, 0x00060050, 0x00000014, 0x00003518, 0x000027FF, 0x000027FF, + 0x000027FF, 0x000500C2, 0x00000014, 0x00002B1E, 0x00003518, 0x00000BB4, 0x000500C7, 0x00000014, + 0x00005DF4, 0x00002B1E, 0x00000105, 0x000500C7, 0x00000014, 0x000048B6, 0x00005DF4, 0x00000466, + 0x000500C2, 0x00000014, 0x00005B9E, 0x00005DF4, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D7, + 0x00005B9E, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C59, 0x00000001, 0x0000004B, 0x000048B6, + 0x0004007C, 0x00000014, 0x00002A23, 0x00002C59, 0x00050082, 0x00000014, 0x00001888, 0x00000B0C, + 0x00002A23, 0x00050080, 0x00000014, 0x0000221E, 0x00002A23, 0x00000938, 0x000600A9, 0x00000014, + 0x0000287D, 0x000040D7, 0x0000221E, 0x00005B9E, 0x000500C4, 0x00000014, 0x00005AE3, 0x000048B6, + 0x00001888, 0x000500C7, 0x00000014, 0x000049A8, 0x00005AE3, 0x00000466, 0x000600A9, 0x00000014, + 0x00002AC5, 0x000040D7, 0x000049A8, 0x000048B6, 0x00050080, 0x00000014, 0x0000600C, 0x0000287D, + 0x000003FA, 0x000500C4, 0x00000014, 0x00004F8D, 0x0000600C, 0x00000189, 0x000500C4, 0x00000014, + 0x00003FB4, 0x00002AC5, 0x0000008D, 0x000500C5, 0x00000014, 0x0000578A, 0x00004F8D, 0x00003FB4, + 0x000500AA, 0x00000010, 0x0000360E, 0x00005DF4, 0x00000A12, 0x000600A9, 0x00000014, 0x00004250, + 0x0000360E, 0x00000A12, 0x0000578A, 0x0004007C, 0x00000018, 0x000029DD, 0x00004250, 0x000500C2, + 0x0000000B, 0x00004BB2, 0x000027FF, 0x00000A64, 0x00040070, 0x0000000D, 0x0000481C, 0x00004BB2, + 0x00050085, 0x0000000D, 0x00003E2D, 0x0000481C, 0x00000149, 0x00050051, 0x0000000D, 0x000053D0, + 0x000029DD, 0x00000000, 0x00050051, 0x0000000D, 0x00002A63, 0x000029DD, 0x00000001, 0x00050051, + 0x0000000D, 0x00001EA4, 0x000029DD, 0x00000002, 0x00070050, 0x0000001D, 0x00003DE5, 0x000053D0, + 0x00002A63, 0x00001EA4, 0x00003E2D, 0x00050051, 0x0000000B, 0x00002800, 0x00002AC2, 0x00000003, + 0x00060050, 0x00000014, 0x00003519, 0x00002800, 0x00002800, 0x00002800, 0x000500C2, 0x00000014, + 0x00002B1F, 0x00003519, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF5, 0x00002B1F, 0x00000105, + 0x000500C7, 0x00000014, 0x000048B7, 0x00005DF5, 0x00000466, 0x000500C2, 0x00000014, 0x00005B9F, + 0x00005DF5, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D8, 0x00005B9F, 0x00000A12, 0x0006000C, + 0x00000016, 0x00002C5A, 0x00000001, 0x0000004B, 0x000048B7, 0x0004007C, 0x00000014, 0x00002A24, + 0x00002C5A, 0x00050082, 0x00000014, 0x00001889, 0x00000B0C, 0x00002A24, 0x00050080, 0x00000014, + 0x0000221F, 0x00002A24, 0x00000938, 0x000600A9, 0x00000014, 0x0000287E, 0x000040D8, 0x0000221F, + 0x00005B9F, 0x000500C4, 0x00000014, 0x00005AE4, 0x000048B7, 0x00001889, 0x000500C7, 0x00000014, + 0x000049A9, 0x00005AE4, 0x00000466, 0x000600A9, 0x00000014, 0x00002AC6, 0x000040D8, 0x000049A9, + 0x000048B7, 0x00050080, 0x00000014, 0x0000600D, 0x0000287E, 0x000003FA, 0x000500C4, 0x00000014, + 0x00004F8E, 0x0000600D, 0x00000189, 0x000500C4, 0x00000014, 0x00003FB5, 0x00002AC6, 0x0000008D, + 0x000500C5, 0x00000014, 0x0000578B, 0x00004F8E, 0x00003FB5, 0x000500AA, 0x00000010, 0x0000360F, + 0x00005DF5, 0x00000A12, 0x000600A9, 0x00000014, 0x00004251, 0x0000360F, 0x00000A12, 0x0000578B, + 0x0004007C, 0x00000018, 0x000029DE, 0x00004251, 0x000500C2, 0x0000000B, 0x00004BB3, 0x00002800, + 0x00000A64, 0x00040070, 0x0000000D, 0x0000481D, 0x00004BB3, 0x00050085, 0x0000000D, 0x00003E2E, + 0x0000481D, 0x00000149, 0x00050051, 0x0000000D, 0x000053D1, 0x000029DE, 0x00000000, 0x00050051, + 0x0000000D, 0x00002A64, 0x000029DE, 0x00000001, 0x00050051, 0x0000000D, 0x00002B20, 0x000029DE, + 0x00000002, 0x00070050, 0x0000001D, 0x0000235A, 0x000053D1, 0x00002A64, 0x00002B20, 0x00003E2E, + 0x000200F9, 0x00003F63, 0x000200F8, 0x00001CC1, 0x00050051, 0x0000000B, 0x000056C7, 0x00002AC2, + 0x00000000, 0x00070050, 0x00000017, 0x00004F14, 0x000056C7, 0x000056C7, 0x000056C7, 0x000056C7, + 0x000500C2, 0x00000017, 0x000024B0, 0x00004F14, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B7, + 0x000024B0, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CC0, 0x000049B7, 0x00050085, 0x0000001D, + 0x00004139, 0x00003CC0, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CDB, 0x00002AC2, 0x00000001, + 0x00070050, 0x00000017, 0x00005156, 0x00005CDB, 0x00005CDB, 0x00005CDB, 0x00005CDB, 0x000500C2, + 0x00000017, 0x000024B1, 0x00005156, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B8, 0x000024B1, + 0x0000027B, 0x00040070, 0x0000001D, 0x00003CC1, 0x000049B8, 0x00050085, 0x0000001D, 0x0000413A, + 0x00003CC1, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CDC, 0x00002AC2, 0x00000002, 0x00070050, + 0x00000017, 0x00005157, 0x00005CDC, 0x00005CDC, 0x00005CDC, 0x00005CDC, 0x000500C2, 0x00000017, + 0x000024B2, 0x00005157, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B9, 0x000024B2, 0x0000027B, + 0x00040070, 0x0000001D, 0x00003CC2, 0x000049B9, 0x00050085, 0x0000001D, 0x0000413B, 0x00003CC2, + 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CDD, 0x00002AC2, 0x00000003, 0x00070050, 0x00000017, + 0x0000515C, 0x00005CDD, 0x00005CDD, 0x00005CDD, 0x00005CDD, 0x000500C2, 0x00000017, 0x000024B3, + 0x0000515C, 0x0000034D, 0x000500C7, 0x00000017, 0x000049BA, 0x000024B3, 0x0000027B, 0x00040070, + 0x0000001D, 0x00004932, 0x000049BA, 0x00050085, 0x0000001D, 0x000026A2, 0x00004932, 0x00000AEE, + 0x000200F9, 0x00003F63, 0x000200F8, 0x000038FC, 0x00050051, 0x0000000B, 0x000056C8, 0x00002AC2, + 0x00000000, 0x00070050, 0x00000017, 0x00004F15, 0x000056C8, 0x000056C8, 0x000056C8, 0x000056C8, + 0x000500C2, 0x00000017, 0x000024B4, 0x00004F15, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A62, + 0x000024B4, 0x0000064B, 0x00040070, 0x0000001D, 0x000036AE, 0x00004A62, 0x0005008E, 0x0000001D, + 0x00004B2C, 0x000036AE, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A8, 0x00002AC2, 0x00000001, + 0x00070050, 0x00000017, 0x00006114, 0x000021A8, 0x000021A8, 0x000021A8, 0x000021A8, 0x000500C2, + 0x00000017, 0x000024B5, 0x00006114, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A63, 0x000024B5, + 0x0000064B, 0x00040070, 0x0000001D, 0x000036AF, 0x00004A63, 0x0005008E, 0x0000001D, 0x00004B2D, + 0x000036AF, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A9, 0x00002AC2, 0x00000002, 0x00070050, + 0x00000017, 0x00006115, 0x000021A9, 0x000021A9, 0x000021A9, 0x000021A9, 0x000500C2, 0x00000017, + 0x000024B6, 0x00006115, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A64, 0x000024B6, 0x0000064B, + 0x00040070, 0x0000001D, 0x000036B0, 0x00004A64, 0x0005008E, 0x0000001D, 0x00004B2E, 0x000036B0, + 0x0000017A, 0x00050051, 0x0000000B, 0x000021AA, 0x00002AC2, 0x00000003, 0x00070050, 0x00000017, + 0x00006116, 0x000021AA, 0x000021AA, 0x000021AA, 0x000021AA, 0x000500C2, 0x00000017, 0x000024B7, + 0x00006116, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A65, 0x000024B7, 0x0000064B, 0x00040070, + 0x0000001D, 0x0000431D, 0x00004A65, 0x0005008E, 0x0000001D, 0x00003095, 0x0000431D, 0x0000017A, + 0x000200F9, 0x00003F63, 0x000200F8, 0x00004BFE, 0x00050051, 0x0000000B, 0x00003096, 0x00002AC2, + 0x00000000, 0x0004007C, 0x0000000D, 0x00004FF1, 0x00003096, 0x00050050, 0x00000013, 0x0000433F, + 0x00004FF1, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D99, 0x0000433F, 0x0000433F, 0x00000000, + 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056BA, 0x00002AC2, 0x00000001, + 0x0004007C, 0x0000000D, 0x00003F71, 0x000056BA, 0x00050050, 0x00000013, 0x00004340, 0x00003F71, + 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D9A, 0x00004340, 0x00004340, 0x00000000, 0x00000001, + 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056BB, 0x00002AC2, 0x00000002, 0x0004007C, + 0x0000000D, 0x00003F72, 0x000056BB, 0x00050050, 0x00000013, 0x00004341, 0x00003F72, 0x00000A0C, + 0x0009004F, 0x0000001D, 0x00002D9B, 0x00004341, 0x00004341, 0x00000000, 0x00000001, 0x00000001, + 0x00000001, 0x00050051, 0x0000000B, 0x000056BC, 0x00002AC2, 0x00000003, 0x0004007C, 0x0000000D, + 0x00003F73, 0x000056BC, 0x00050050, 0x00000013, 0x00004FB1, 0x00003F73, 0x00000A0C, 0x0009004F, + 0x0000001D, 0x00005A3D, 0x00004FB1, 0x00004FB1, 0x00000000, 0x00000001, 0x00000001, 0x00000001, + 0x000200F9, 0x00003F63, 0x000200F8, 0x00003F63, 0x000F00F5, 0x0000001D, 0x00002BB0, 0x00005A3D, + 0x00004BFE, 0x00003095, 0x000038FC, 0x000026A2, 0x00001CC1, 0x0000235A, 0x00001CC0, 0x00002359, + 0x00002001, 0x00002358, 0x00002039, 0x000F00F5, 0x0000001D, 0x00003811, 0x00002D9B, 0x00004BFE, + 0x00004B2E, 0x000038FC, 0x0000413B, 0x00001CC1, 0x00003DE5, 0x00001CC0, 0x00004129, 0x00002001, + 0x00003920, 0x00002039, 0x000F00F5, 0x0000001D, 0x00003B89, 0x00002D9A, 0x00004BFE, 0x00004B2D, + 0x000038FC, 0x0000413A, 0x00001CC1, 0x00003DE4, 0x00001CC0, 0x00004128, 0x00002001, 0x0000391F, + 0x00002039, 0x000F00F5, 0x0000001D, 0x000038BC, 0x00002D99, 0x00004BFE, 0x00004B2C, 0x000038FC, + 0x00004139, 0x00001CC1, 0x00003DE3, 0x00001CC0, 0x00004127, 0x00002001, 0x0000391E, 0x00002039, + 0x000200F9, 0x00005312, 0x000200F8, 0x00003B68, 0x000500AA, 0x00000009, 0x00005453, 0x0000199B, + 0x00000A10, 0x000300F7, 0x00004F29, 0x00000002, 0x000400FA, 0x00005453, 0x0000262B, 0x00002F68, + 0x000200F8, 0x00002F68, 0x00060041, 0x00000288, 0x00004BD6, 0x00000CC7, 0x00000A0B, 0x00003FF8, + 0x0004003D, 0x0000000B, 0x00005D51, 0x00004BD6, 0x00050080, 0x0000000B, 0x00002DD8, 0x00003FF8, + 0x00000A0D, 0x00060041, 0x00000288, 0x00001919, 0x00000CC7, 0x00000A0B, 0x00002DD8, 0x0004003D, + 0x0000000B, 0x00005C85, 0x00001919, 0x00050080, 0x0000000B, 0x00002DD9, 0x00003FF8, 0x0000199B, + 0x00060041, 0x00000288, 0x0000191A, 0x00000CC7, 0x00000A0B, 0x00002DD9, 0x0004003D, 0x0000000B, + 0x00005C86, 0x0000191A, 0x00050080, 0x0000000B, 0x00002DDA, 0x00002DD9, 0x00000A0D, 0x00060041, + 0x00000288, 0x0000600E, 0x00000CC7, 0x00000A0B, 0x00002DDA, 0x0004003D, 0x0000000B, 0x00003750, + 0x0000600E, 0x00070050, 0x00000017, 0x00004CDA, 0x00005D51, 0x00005C85, 0x00005C86, 0x00003750, + 0x00050084, 0x0000000B, 0x0000429B, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000036B1, + 0x00003FF8, 0x0000429B, 0x00060041, 0x00000288, 0x00003B8A, 0x00000CC7, 0x00000A0B, 0x000036B1, + 0x0004003D, 0x0000000B, 0x00005C87, 0x00003B8A, 0x00050080, 0x0000000B, 0x00002DDB, 0x000036B1, + 0x00000A0D, 0x00060041, 0x00000288, 0x00001952, 0x00000CC7, 0x00000A0B, 0x00002DDB, 0x0004003D, + 0x0000000B, 0x00005E66, 0x00001952, 0x00050084, 0x0000000B, 0x00001865, 0x00000A13, 0x0000199B, + 0x00050080, 0x0000000B, 0x000020AC, 0x00003FF8, 0x00001865, 0x00060041, 0x00000288, 0x00003B8B, + 0x00000CC7, 0x00000A0B, 0x000020AC, 0x0004003D, 0x0000000B, 0x00005C88, 0x00003B8B, 0x00050080, + 0x0000000B, 0x00002DDC, 0x000020AC, 0x00000A0D, 0x00060041, 0x00000288, 0x0000600F, 0x00000CC7, + 0x00000A0B, 0x00002DDC, 0x0004003D, 0x0000000B, 0x00004009, 0x0000600F, 0x00070050, 0x00000017, + 0x0000513A, 0x00005C87, 0x00005E66, 0x00005C88, 0x00004009, 0x000200F9, 0x00004F29, 0x000200F8, + 0x0000262B, 0x00060041, 0x00000288, 0x0000554C, 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, + 0x0000000B, 0x00005D52, 0x0000554C, 0x00050080, 0x0000000B, 0x00002DDD, 0x00003FF8, 0x00000A0D, + 0x00060041, 0x00000288, 0x0000191B, 0x00000CC7, 0x00000A0B, 0x00002DDD, 0x0004003D, 0x0000000B, + 0x00005C89, 0x0000191B, 0x00050080, 0x0000000B, 0x00002DDE, 0x00003FF8, 0x00000A10, 0x00060041, + 0x00000288, 0x0000191C, 0x00000CC7, 0x00000A0B, 0x00002DDE, 0x0004003D, 0x0000000B, 0x00005C8A, + 0x0000191C, 0x00050080, 0x0000000B, 0x00002DDF, 0x00003FF8, 0x00000A13, 0x00060041, 0x00000288, + 0x00006010, 0x00000CC7, 0x00000A0B, 0x00002DDF, 0x0004003D, 0x0000000B, 0x00003703, 0x00006010, + 0x00070050, 0x00000017, 0x00004AE2, 0x00005D52, 0x00005C89, 0x00005C8A, 0x00003703, 0x00050080, + 0x0000000B, 0x000057E8, 0x00003FF8, 0x00000A16, 0x00060041, 0x00000288, 0x0000604E, 0x00000CC7, + 0x00000A0B, 0x000057E8, 0x0004003D, 0x0000000B, 0x00005C8B, 0x0000604E, 0x00050080, 0x0000000B, + 0x00002DE0, 0x00003FF8, 0x00000A19, 0x00060041, 0x00000288, 0x0000191D, 0x00000CC7, 0x00000A0B, + 0x00002DE0, 0x0004003D, 0x0000000B, 0x00005C8C, 0x0000191D, 0x00050080, 0x0000000B, 0x00002DE1, + 0x00003FF8, 0x00000A1C, 0x00060041, 0x00000288, 0x0000191E, 0x00000CC7, 0x00000A0B, 0x00002DE1, + 0x0004003D, 0x0000000B, 0x00005C8D, 0x0000191E, 0x00050080, 0x0000000B, 0x00002DE2, 0x00003FF8, + 0x00000A1F, 0x00060041, 0x00000288, 0x00006011, 0x00000CC7, 0x00000A0B, 0x00002DE2, 0x0004003D, + 0x0000000B, 0x0000400A, 0x00006011, 0x00070050, 0x00000017, 0x0000513B, 0x00005C8B, 0x00005C8C, + 0x00005C8D, 0x0000400A, 0x000200F9, 0x00004F29, 0x000200F8, 0x00004F29, 0x000700F5, 0x00000017, + 0x00002BD0, 0x0000513B, 0x0000262B, 0x0000513A, 0x00002F68, 0x000700F5, 0x00000017, 0x00003723, + 0x00004AE2, 0x0000262B, 0x00004CDA, 0x00002F68, 0x000300F7, 0x00004F2A, 0x00000000, 0x000700FB, + 0x00002180, 0x00004F59, 0x00000005, 0x0000215B, 0x00000007, 0x0000203A, 0x000200F8, 0x0000203A, + 0x00050051, 0x0000000B, 0x00005F5D, 0x00003723, 0x00000000, 0x0006000C, 0x00000013, 0x0000606E, + 0x00000001, 0x0000003E, 0x00005F5D, 0x00050051, 0x0000000D, 0x0000278A, 0x0000606E, 0x00000000, + 0x00050051, 0x0000000D, 0x00003EC4, 0x0000606E, 0x00000001, 0x00050051, 0x0000000B, 0x0000428D, + 0x00003723, 0x00000001, 0x0006000C, 0x00000013, 0x00003D01, 0x00000001, 0x0000003E, 0x0000428D, + 0x00050051, 0x0000000D, 0x0000278B, 0x00003D01, 0x00000000, 0x00050051, 0x0000000D, 0x0000445B, + 0x00003D01, 0x00000001, 0x00070050, 0x0000001D, 0x00003921, 0x0000278A, 0x00003EC4, 0x0000278B, + 0x0000445B, 0x00050051, 0x0000000B, 0x0000438F, 0x00003723, 0x00000002, 0x0006000C, 0x00000013, + 0x00004680, 0x00000001, 0x0000003E, 0x0000438F, 0x00050051, 0x0000000D, 0x0000278C, 0x00004680, + 0x00000000, 0x00050051, 0x0000000D, 0x00003EC5, 0x00004680, 0x00000001, 0x00050051, 0x0000000B, + 0x0000428E, 0x00003723, 0x00000003, 0x0006000C, 0x00000013, 0x00003D02, 0x00000001, 0x0000003E, + 0x0000428E, 0x00050051, 0x0000000D, 0x0000278D, 0x00003D02, 0x00000000, 0x00050051, 0x0000000D, + 0x0000445C, 0x00003D02, 0x00000001, 0x00070050, 0x0000001D, 0x00003922, 0x0000278C, 0x00003EC5, + 0x0000278D, 0x0000445C, 0x00050051, 0x0000000B, 0x00004390, 0x00002BD0, 0x00000000, 0x0006000C, + 0x00000013, 0x00004681, 0x00000001, 0x0000003E, 0x00004390, 0x00050051, 0x0000000D, 0x0000278E, + 0x00004681, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC6, 0x00004681, 0x00000001, 0x00050051, + 0x0000000B, 0x0000428F, 0x00002BD0, 0x00000001, 0x0006000C, 0x00000013, 0x00003D03, 0x00000001, + 0x0000003E, 0x0000428F, 0x00050051, 0x0000000D, 0x0000278F, 0x00003D03, 0x00000000, 0x00050051, + 0x0000000D, 0x0000445D, 0x00003D03, 0x00000001, 0x00070050, 0x0000001D, 0x00003923, 0x0000278E, + 0x00003EC6, 0x0000278F, 0x0000445D, 0x00050051, 0x0000000B, 0x00004391, 0x00002BD0, 0x00000002, + 0x0006000C, 0x00000013, 0x00004682, 0x00000001, 0x0000003E, 0x00004391, 0x00050051, 0x0000000D, + 0x00002790, 0x00004682, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC7, 0x00004682, 0x00000001, + 0x00050051, 0x0000000B, 0x00004290, 0x00002BD0, 0x00000003, 0x0006000C, 0x00000013, 0x00003D04, + 0x00000001, 0x0000003E, 0x00004290, 0x00050051, 0x0000000D, 0x00002791, 0x00003D04, 0x00000000, + 0x00050051, 0x0000000D, 0x000050C5, 0x00003D04, 0x00000001, 0x00070050, 0x0000001D, 0x0000235B, + 0x00002790, 0x00003EC7, 0x00002791, 0x000050C5, 0x000200F9, 0x00004F2A, 0x000200F8, 0x0000215B, + 0x0007004F, 0x00000011, 0x000025FE, 0x00003723, 0x00003723, 0x00000000, 0x00000001, 0x0004007C, + 0x00000012, 0x00005B3F, 0x000025FE, 0x0009004F, 0x0000001A, 0x000060DA, 0x00005B3F, 0x00005B3F, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048B8, 0x000060DA, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D99, 0x000048B8, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002AC7, 0x00003D99, 0x0005008E, 0x0000001D, 0x00004733, 0x00002AC7, 0x000007FE, 0x0007000C, + 0x0000001D, 0x0000629A, 0x00000001, 0x00000028, 0x00000504, 0x00004733, 0x0007004F, 0x00000011, + 0x00003774, 0x00003723, 0x00003723, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C8, + 0x00003774, 0x0009004F, 0x0000001A, 0x000060DB, 0x000024C8, 0x000024C8, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048B9, 0x000060DB, 0x00000122, 0x000500C3, + 0x0000001A, 0x00003D9A, 0x000048B9, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AC8, 0x00003D9A, + 0x0005008E, 0x0000001D, 0x00004734, 0x00002AC8, 0x000007FE, 0x0007000C, 0x0000001D, 0x0000629B, + 0x00000001, 0x00000028, 0x00000504, 0x00004734, 0x0007004F, 0x00000011, 0x00003775, 0x00002BD0, + 0x00002BD0, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000024C9, 0x00003775, 0x0009004F, + 0x0000001A, 0x000060DC, 0x000024C9, 0x000024C9, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C4, 0x0000001A, 0x000048BA, 0x000060DC, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D9B, + 0x000048BA, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AC9, 0x00003D9B, 0x0005008E, 0x0000001D, + 0x00004735, 0x00002AC9, 0x000007FE, 0x0007000C, 0x0000001D, 0x0000629C, 0x00000001, 0x00000028, + 0x00000504, 0x00004735, 0x0007004F, 0x00000011, 0x00003776, 0x00002BD0, 0x00002BD0, 0x00000002, + 0x00000003, 0x0004007C, 0x00000012, 0x000024CA, 0x00003776, 0x0009004F, 0x0000001A, 0x000060DD, + 0x000024CA, 0x000024CA, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, + 0x000048BB, 0x000060DD, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D9C, 0x000048BB, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002ACA, 0x00003D9C, 0x0005008E, 0x0000001D, 0x000053D2, 0x00002ACA, + 0x000007FE, 0x0007000C, 0x0000001D, 0x00004365, 0x00000001, 0x00000028, 0x00000504, 0x000053D2, + 0x000200F9, 0x00004F2A, 0x000200F8, 0x00004F59, 0x0007004F, 0x00000011, 0x0000262C, 0x00003723, + 0x00003723, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x0000515D, 0x0000262C, 0x00050051, + 0x0000000D, 0x00001B87, 0x0000515D, 0x00000000, 0x00050051, 0x0000000D, 0x00003473, 0x0000515D, + 0x00000001, 0x00070050, 0x0000001D, 0x00004291, 0x00001B87, 0x00003473, 0x00000A0C, 0x00000A0C, + 0x0007004F, 0x00000011, 0x000041E1, 0x00003723, 0x00003723, 0x00000002, 0x00000003, 0x0004007C, + 0x00000013, 0x00003766, 0x000041E1, 0x00050051, 0x0000000D, 0x00001B88, 0x00003766, 0x00000000, + 0x00050051, 0x0000000D, 0x00003474, 0x00003766, 0x00000001, 0x00070050, 0x0000001D, 0x00004292, + 0x00001B88, 0x00003474, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041E2, 0x00002BD0, + 0x00002BD0, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x00003767, 0x000041E2, 0x00050051, + 0x0000000D, 0x00001B89, 0x00003767, 0x00000000, 0x00050051, 0x0000000D, 0x00003475, 0x00003767, + 0x00000001, 0x00070050, 0x0000001D, 0x00004293, 0x00001B89, 0x00003475, 0x00000A0C, 0x00000A0C, + 0x0007004F, 0x00000011, 0x000041E3, 0x00002BD0, 0x00002BD0, 0x00000002, 0x00000003, 0x0004007C, + 0x00000013, 0x00003768, 0x000041E3, 0x00050051, 0x0000000D, 0x00001B8A, 0x00003768, 0x00000000, + 0x00050051, 0x0000000D, 0x0000410B, 0x00003768, 0x00000001, 0x00070050, 0x0000001D, 0x0000235C, + 0x00001B8A, 0x0000410B, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F2A, 0x000200F8, 0x00004F2A, + 0x000900F5, 0x0000001D, 0x00002BB1, 0x0000235C, 0x00004F59, 0x00004365, 0x0000215B, 0x0000235B, + 0x0000203A, 0x000900F5, 0x0000001D, 0x00003812, 0x00004293, 0x00004F59, 0x0000629C, 0x0000215B, + 0x00003923, 0x0000203A, 0x000900F5, 0x0000001D, 0x00003B8C, 0x00004292, 0x00004F59, 0x0000629B, + 0x0000215B, 0x00003922, 0x0000203A, 0x000900F5, 0x0000001D, 0x000038BD, 0x00004291, 0x00004F59, + 0x0000629A, 0x0000215B, 0x00003921, 0x0000203A, 0x000200F9, 0x00005312, 0x000200F8, 0x00005312, + 0x000700F5, 0x0000001D, 0x00002BB2, 0x00002BB1, 0x00004F2A, 0x00002BB0, 0x00003F63, 0x000700F5, + 0x0000001D, 0x00003813, 0x00003812, 0x00004F2A, 0x00003811, 0x00003F63, 0x000700F5, 0x0000001D, + 0x00003297, 0x00003B8C, 0x00004F2A, 0x00003B89, 0x00003F63, 0x000700F5, 0x0000001D, 0x0000367C, + 0x000038BD, 0x00004F2A, 0x000038BC, 0x00003F63, 0x00050081, 0x0000001D, 0x0000435B, 0x0000435A, + 0x0000367C, 0x00050081, 0x0000001D, 0x00005B03, 0x00005B02, 0x00003297, 0x00050081, 0x0000001D, + 0x00002523, 0x00001C28, 0x00003813, 0x00050081, 0x0000001D, 0x00001E77, 0x000025AA, 0x00002BB2, + 0x000200F9, 0x00005EC8, 0x000200F8, 0x00005EC8, 0x000700F5, 0x0000001D, 0x00002BB3, 0x00005113, + 0x00005310, 0x00001E77, 0x00005312, 0x000700F5, 0x0000001D, 0x00003814, 0x00001F92, 0x00005310, + 0x00002523, 0x00005312, 0x000700F5, 0x0000001D, 0x00003B31, 0x00005B01, 0x00005310, 0x00005B03, + 0x00005312, 0x000700F5, 0x0000001D, 0x00003B8D, 0x00004359, 0x00005310, 0x0000435B, 0x00005312, + 0x000700F5, 0x0000000D, 0x000038BE, 0x000061FB, 0x00005310, 0x00002F3A, 0x00005312, 0x000200F9, + 0x00005313, 0x000200F8, 0x00005313, 0x000700F5, 0x0000001D, 0x00002BB4, 0x00002BA9, 0x0000530F, + 0x00002BB3, 0x00005EC8, 0x000700F5, 0x0000001D, 0x00003815, 0x0000380A, 0x0000530F, 0x00003814, + 0x00005EC8, 0x000700F5, 0x0000001D, 0x00003B32, 0x000035EC, 0x0000530F, 0x00003B31, 0x00005EC8, + 0x000700F5, 0x0000001D, 0x0000338C, 0x000020D3, 0x0000530F, 0x00003B8D, 0x00005EC8, 0x000700F5, + 0x0000000D, 0x00002EA8, 0x00002B2C, 0x0000530F, 0x000038BE, 0x00005EC8, 0x0005008E, 0x0000001D, + 0x00005A74, 0x0000338C, 0x00002EA8, 0x0005008E, 0x0000001D, 0x000019CC, 0x00003B32, 0x00002EA8, + 0x0005008E, 0x0000001D, 0x0000306F, 0x00003815, 0x00002EA8, 0x0005008E, 0x0000001D, 0x00003432, + 0x00002BB4, 0x00002EA8, 0x000300F7, 0x00003F64, 0x00000002, 0x000400FA, 0x00001D59, 0x00002741, + 0x00003F64, 0x000200F8, 0x00002741, 0x0009004F, 0x0000001D, 0x00003AEE, 0x00005A74, 0x00005A74, + 0x00000002, 0x00000001, 0x00000000, 0x00000003, 0x0009004F, 0x0000001D, 0x00003A07, 0x000019CC, + 0x000019CC, 0x00000002, 0x00000001, 0x00000000, 0x00000003, 0x0009004F, 0x0000001D, 0x00001CE6, + 0x0000306F, 0x0000306F, 0x00000002, 0x00000001, 0x00000000, 0x00000003, 0x0009004F, 0x0000001D, + 0x00003EEF, 0x00003432, 0x00003432, 0x00000002, 0x00000001, 0x00000000, 0x00000003, 0x000200F9, + 0x00003F64, 0x000200F8, 0x00003F64, 0x000700F5, 0x0000001D, 0x00002BB5, 0x00003432, 0x00005313, + 0x00003EEF, 0x00002741, 0x000700F5, 0x0000001D, 0x00003816, 0x0000306F, 0x00005313, 0x00001CE6, + 0x00002741, 0x000700F5, 0x0000001D, 0x00003B57, 0x000019CC, 0x00005313, 0x00003A07, 0x00002741, + 0x000700F5, 0x0000001D, 0x00003A49, 0x00005A74, 0x00005313, 0x00003AEE, 0x00002741, 0x000300F7, + 0x00005BA4, 0x00000000, 0x000700FB, 0x00005093, 0x00001CCD, 0x0000001A, 0x00004696, 0x00000020, + 0x00002514, 0x000200F8, 0x00002514, 0x00050051, 0x0000000D, 0x00003AAE, 0x00003A49, 0x00000000, + 0x00050051, 0x0000000D, 0x000023ED, 0x00003A49, 0x00000001, 0x00050050, 0x00000013, 0x00004B20, + 0x00003AAE, 0x000023ED, 0x0006000C, 0x0000000B, 0x00002171, 0x00000001, 0x0000003A, 0x00004B20, + 0x00050051, 0x0000000D, 0x00005BBF, 0x00003A49, 0x00000002, 0x00050051, 0x0000000D, 0x000039A7, + 0x00003A49, 0x00000003, 0x00050050, 0x00000013, 0x00004B21, 0x00005BBF, 0x000039A7, 0x0006000C, + 0x0000000B, 0x00002172, 0x00000001, 0x0000003A, 0x00004B21, 0x00050051, 0x0000000D, 0x00005BC0, + 0x00003B57, 0x00000000, 0x00050051, 0x0000000D, 0x000039A8, 0x00003B57, 0x00000001, 0x00050050, + 0x00000013, 0x00004B22, 0x00005BC0, 0x000039A8, 0x0006000C, 0x0000000B, 0x00002173, 0x00000001, + 0x0000003A, 0x00004B22, 0x00050051, 0x0000000D, 0x00005BC1, 0x00003B57, 0x00000002, 0x00050051, + 0x0000000D, 0x000039A9, 0x00003B57, 0x00000003, 0x00050050, 0x00000013, 0x00004B0D, 0x00005BC1, + 0x000039A9, 0x0006000C, 0x0000000B, 0x00002220, 0x00000001, 0x0000003A, 0x00004B0D, 0x00070050, + 0x00000017, 0x00003154, 0x00002171, 0x00002172, 0x00002173, 0x00002220, 0x00050051, 0x0000000D, + 0x00003EC8, 0x00003816, 0x00000000, 0x00050051, 0x0000000D, 0x00005470, 0x00003816, 0x00000001, + 0x00050050, 0x00000013, 0x00004B2F, 0x00003EC8, 0x00005470, 0x0006000C, 0x0000000B, 0x00002174, + 0x00000001, 0x0000003A, 0x00004B2F, 0x00050051, 0x0000000D, 0x00005BC2, 0x00003816, 0x00000002, + 0x00050051, 0x0000000D, 0x000039AA, 0x00003816, 0x00000003, 0x00050050, 0x00000013, 0x00004B30, + 0x00005BC2, 0x000039AA, 0x0006000C, 0x0000000B, 0x00002175, 0x00000001, 0x0000003A, 0x00004B30, + 0x00050051, 0x0000000D, 0x00005BC3, 0x00002BB5, 0x00000000, 0x00050051, 0x0000000D, 0x000039AB, + 0x00002BB5, 0x00000001, 0x00050050, 0x00000013, 0x00004B31, 0x00005BC3, 0x000039AB, 0x0006000C, + 0x0000000B, 0x00002176, 0x00000001, 0x0000003A, 0x00004B31, 0x00050051, 0x0000000D, 0x00005BC4, + 0x00002BB5, 0x00000002, 0x00050051, 0x0000000D, 0x000039AC, 0x00002BB5, 0x00000003, 0x00050050, + 0x00000013, 0x00004B0E, 0x00005BC4, 0x000039AC, 0x0006000C, 0x0000000B, 0x00002E96, 0x00000001, + 0x0000003A, 0x00004B0E, 0x00070050, 0x00000017, 0x0000612F, 0x00002174, 0x00002175, 0x00002176, + 0x00002E96, 0x000200F9, 0x00005BA4, 0x000200F8, 0x00004696, 0x0008000C, 0x0000001D, 0x00001C8F, + 0x00000001, 0x0000002B, 0x00003A49, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, 0x00004F73, + 0x00001C8F, 0x0000022D, 0x00050081, 0x0000001D, 0x00002E40, 0x00004F73, 0x00000145, 0x0004006D, + 0x00000017, 0x00001F0B, 0x00002E40, 0x0007004F, 0x00000011, 0x000018D9, 0x00001F0B, 0x00001F0B, + 0x00000000, 0x00000002, 0x0007004F, 0x00000011, 0x00002750, 0x00001F0B, 0x00001F0B, 0x00000001, + 0x00000003, 0x000500C4, 0x00000011, 0x000028CE, 0x00002750, 0x00000867, 0x000500C5, 0x00000011, + 0x000057C9, 0x000018D9, 0x000028CE, 0x00050051, 0x0000000B, 0x0000498C, 0x000057C9, 0x00000000, + 0x00050051, 0x0000000B, 0x00003BFC, 0x000057C9, 0x00000001, 0x0008000C, 0x0000001D, 0x00003751, + 0x00000001, 0x0000002B, 0x00003B57, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, 0x00002C01, + 0x00003751, 0x0000022D, 0x00050081, 0x0000001D, 0x00002E41, 0x00002C01, 0x00000145, 0x0004006D, + 0x00000017, 0x00001F0C, 0x00002E41, 0x0007004F, 0x00000011, 0x000018DA, 0x00001F0C, 0x00001F0C, + 0x00000000, 0x00000002, 0x0007004F, 0x00000011, 0x00002751, 0x00001F0C, 0x00001F0C, 0x00000001, + 0x00000003, 0x000500C4, 0x00000011, 0x000028CF, 0x00002751, 0x00000867, 0x000500C5, 0x00000011, + 0x000057CA, 0x000018DA, 0x000028CF, 0x00050051, 0x0000000B, 0x00004E6D, 0x000057CA, 0x00000000, + 0x00050051, 0x0000000B, 0x0000586B, 0x000057CA, 0x00000001, 0x00070050, 0x00000017, 0x00001D37, + 0x0000498C, 0x00003BFC, 0x00004E6D, 0x0000586B, 0x0008000C, 0x0000001D, 0x00003846, 0x00000001, + 0x0000002B, 0x00003816, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, 0x00003577, 0x00003846, + 0x0000022D, 0x00050081, 0x0000001D, 0x00002E42, 0x00003577, 0x00000145, 0x0004006D, 0x00000017, + 0x00001F0D, 0x00002E42, 0x0007004F, 0x00000011, 0x000018DB, 0x00001F0D, 0x00001F0D, 0x00000000, + 0x00000002, 0x0007004F, 0x00000011, 0x00002752, 0x00001F0D, 0x00001F0D, 0x00000001, 0x00000003, + 0x000500C4, 0x00000011, 0x000028D0, 0x00002752, 0x00000867, 0x000500C5, 0x00000011, 0x000057CB, + 0x000018DB, 0x000028D0, 0x00050051, 0x0000000B, 0x0000498D, 0x000057CB, 0x00000000, 0x00050051, + 0x0000000B, 0x00003BFD, 0x000057CB, 0x00000001, 0x0008000C, 0x0000001D, 0x00003752, 0x00000001, + 0x0000002B, 0x00002BB5, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, 0x00002C02, 0x00003752, + 0x0000022D, 0x00050081, 0x0000001D, 0x00002E43, 0x00002C02, 0x00000145, 0x0004006D, 0x00000017, + 0x00001F0E, 0x00002E43, 0x0007004F, 0x00000011, 0x000018DC, 0x00001F0E, 0x00001F0E, 0x00000000, + 0x00000002, 0x0007004F, 0x00000011, 0x00002753, 0x00001F0E, 0x00001F0E, 0x00000001, 0x00000003, + 0x000500C4, 0x00000011, 0x000028D1, 0x00002753, 0x00000867, 0x000500C5, 0x00000011, 0x000057CC, + 0x000018DC, 0x000028D1, 0x00050051, 0x0000000B, 0x00004E6E, 0x000057CC, 0x00000000, 0x00050051, + 0x0000000B, 0x00001F58, 0x000057CC, 0x00000001, 0x00070050, 0x00000017, 0x0000235D, 0x0000498D, + 0x00003BFD, 0x00004E6E, 0x00001F58, 0x000200F9, 0x00005BA4, 0x000200F8, 0x00001CCD, 0x00050051, + 0x0000000D, 0x00004DAD, 0x00003A49, 0x00000000, 0x00050051, 0x0000000D, 0x00002825, 0x00003A49, + 0x00000001, 0x00050051, 0x0000000D, 0x00001DD9, 0x00003B57, 0x00000000, 0x00050051, 0x0000000D, + 0x000021CA, 0x00003B57, 0x00000001, 0x00070050, 0x0000001D, 0x000020DE, 0x00004DAD, 0x00002825, + 0x00001DD9, 0x000021CA, 0x0004007C, 0x00000017, 0x00004627, 0x000020DE, 0x00050051, 0x0000000D, + 0x00002B51, 0x00003816, 0x00000000, 0x00050051, 0x0000000D, 0x000033E3, 0x00003816, 0x00000001, + 0x00050051, 0x0000000D, 0x00001DDA, 0x00002BB5, 0x00000000, 0x00050051, 0x0000000D, 0x000021CB, + 0x00002BB5, 0x00000001, 0x00070050, 0x0000001D, 0x00002D56, 0x00002B51, 0x000033E3, 0x00001DDA, + 0x000021CB, 0x0004007C, 0x00000017, 0x00002B83, 0x00002D56, 0x000200F9, 0x00005BA4, 0x000200F8, + 0x00005BA4, 0x000900F5, 0x00000017, 0x00002616, 0x00002B83, 0x00001CCD, 0x0000235D, 0x00004696, + 0x0000612F, 0x00002514, 0x000900F5, 0x00000017, 0x000033CD, 0x00004627, 0x00001CCD, 0x00001D37, + 0x00004696, 0x00003154, 0x00002514, 0x000500AA, 0x00000009, 0x00004DD8, 0x00001DD8, 0x00000A0A, + 0x000600A9, 0x00000009, 0x000056E6, 0x00004DD8, 0x00000787, 0x00004DD8, 0x000300F7, 0x00004CC1, + 0x00000002, 0x000400FA, 0x000056E6, 0x00002620, 0x00004CC1, 0x000200F8, 0x00002620, 0x00050051, + 0x0000000B, 0x00004392, 0x000033CD, 0x00000002, 0x00060052, 0x00000017, 0x000052B6, 0x00004392, + 0x000033CD, 0x00000000, 0x00050051, 0x0000000B, 0x00005A04, 0x000033CD, 0x00000003, 0x00060052, + 0x00000017, 0x00002450, 0x00005A04, 0x000052B6, 0x00000001, 0x000200F9, 0x00004CC1, 0x000200F8, + 0x00004CC1, 0x000700F5, 0x00000017, 0x0000305F, 0x000033CD, 0x00005BA4, 0x00002450, 0x00002620, + 0x00050080, 0x00000011, 0x000032A7, 0x00002EF9, 0x000059EC, 0x000300F7, 0x000052F5, 0x00000002, + 0x000400FA, 0x0000500F, 0x0000294E, 0x0000537D, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000012, + 0x00002970, 0x000032A7, 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000000, 0x000500C3, + 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, + 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, + 0x00005B4D, 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, + 0x0000000C, 0x00005347, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, + 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A28, 0x000500C7, 0x0000000C, + 0x00002ACB, 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x00002747, 0x00000A35, + 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, + 0x00002ACB, 0x0000454D, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A13, 0x000500C7, + 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, + 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, + 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4B, 0x00003397, + 0x000500C7, 0x0000000C, 0x000047BD, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544A, + 0x000047BD, 0x00000A17, 0x00050080, 0x0000000C, 0x00004157, 0x00004D30, 0x0000544A, 0x000500C7, + 0x0000000C, 0x00005022, 0x00004157, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, + 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x00004158, 0x00002416, 0x00002F77, + 0x000500C7, 0x0000000C, 0x00004AE3, 0x00004157, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544B, + 0x00004AE3, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x00004158, 0x0000544B, 0x000500C7, + 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, + 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, + 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005454, 0x000035B6, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000544C, 0x00005454, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4C, + 0x00004144, 0x0000544C, 0x000500C7, 0x0000000C, 0x00002E06, 0x00004157, 0x00000AC8, 0x00050080, + 0x0000000C, 0x0000394F, 0x00003C4C, 0x00002E06, 0x0004007C, 0x0000000B, 0x0000566F, 0x0000394F, + 0x000200F9, 0x000052F5, 0x000200F8, 0x0000294E, 0x00050051, 0x0000000B, 0x00004D9A, 0x000032A7, + 0x00000000, 0x00050051, 0x0000000B, 0x00002C03, 0x000032A7, 0x00000001, 0x00060050, 0x00000014, + 0x000020DF, 0x00004D9A, 0x00002C03, 0x00005F72, 0x0004007C, 0x00000016, 0x00004E9D, 0x000020DF, + 0x00050051, 0x0000000C, 0x000028C6, 0x00004E9D, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FE, + 0x000028C6, 0x00000A17, 0x00050051, 0x0000000C, 0x00002748, 0x00004E9D, 0x00000002, 0x000500C3, + 0x0000000C, 0x0000405D, 0x00002748, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00006273, + 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005321, + 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FE, 0x00005321, 0x000500C2, + 0x0000000B, 0x00002348, 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, 0x00003097, 0x00002348, + 0x00050084, 0x0000000C, 0x0000287F, 0x00003B27, 0x00003097, 0x00050051, 0x0000000C, 0x00006242, + 0x00004E9D, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, + 0x0000000C, 0x000049FC, 0x00004FC7, 0x0000287F, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, + 0x00000A25, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, + 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, + 0x000500C7, 0x0000000C, 0x00003139, 0x000028C6, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454E, + 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454E, 0x000500C4, + 0x0000000C, 0x00001B8B, 0x0000434B, 0x00000A25, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B8B, + 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002221, 0x000028C6, 0x00000A14, 0x00050080, 0x0000000C, + 0x000035A3, 0x00002221, 0x0000405D, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, + 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, + 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, + 0x0000000C, 0x00004AE4, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544D, 0x00004AE4, + 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4D, 0x00005A0C, 0x0000544D, 0x000500C7, 0x0000000C, + 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, + 0x000500C4, 0x0000000C, 0x00005B32, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, + 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B32, 0x00005AEA, 0x000500C7, + 0x0000000C, 0x000047BE, 0x00002748, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544E, 0x000047BE, + 0x00000A25, 0x00050080, 0x0000000C, 0x00004159, 0x0000285C, 0x0000544E, 0x000500C7, 0x0000000C, + 0x00004AE5, 0x000028C6, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544F, 0x00004AE5, 0x00000A17, + 0x00050080, 0x0000000C, 0x0000415A, 0x00004159, 0x0000544F, 0x000500C7, 0x0000000C, 0x00004FD6, + 0x00003C4D, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, + 0x0000000C, 0x00003332, 0x0000415A, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, + 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, + 0x00005B33, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4D, 0x00000A05, + 0x00050080, 0x0000000C, 0x00002ACC, 0x00005B33, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B34, + 0x00002ACC, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x0000415A, 0x0000040B, 0x00050080, + 0x0000000C, 0x00002ACD, 0x00005B34, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B35, 0x00002ACD, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x0000415A, 0x00000AC8, 0x00050080, 0x0000000C, + 0x00005EFA, 0x00005B35, 0x00005559, 0x0004007C, 0x0000000B, 0x00005670, 0x00005EFA, 0x000200F9, + 0x000052F5, 0x000200F8, 0x000052F5, 0x000700F5, 0x0000000B, 0x00002C70, 0x00005670, 0x0000294E, + 0x0000566F, 0x0000537D, 0x00050080, 0x0000000B, 0x00005088, 0x00002C70, 0x000062B6, 0x000500C2, + 0x0000000B, 0x00004EAA, 0x00005088, 0x00000A16, 0x000500AA, 0x00000009, 0x00004B9C, 0x00004ADC, + 0x00000A16, 0x000300F7, 0x000039BC, 0x00000000, 0x000400FA, 0x00004B9C, 0x000033DF, 0x000039BC, + 0x000200F8, 0x000033DF, 0x0009004F, 0x00000017, 0x00001F16, 0x0000305F, 0x0000305F, 0x00000001, + 0x00000000, 0x00000003, 0x00000002, 0x000200F9, 0x000039BC, 0x000200F8, 0x000039BC, 0x000700F5, + 0x00000017, 0x00005972, 0x0000305F, 0x000052F5, 0x00001F16, 0x000033DF, 0x000600A9, 0x0000000B, + 0x000019CD, 0x00004B9C, 0x00000A10, 0x00004ADC, 0x000500AA, 0x00000009, 0x00003464, 0x000019CD, + 0x00000A0D, 0x000500AA, 0x00000009, 0x000047C2, 0x000019CD, 0x00000A10, 0x000500A6, 0x00000009, + 0x00005686, 0x00003464, 0x000047C2, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, + 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00005972, + 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, + 0x000050AC, 0x00005972, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, + 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, + 0x00003463, 0x000700F5, 0x00000017, 0x0000587A, 0x00005972, 0x000039BC, 0x00003FF9, 0x00002957, + 0x000500AA, 0x00000009, 0x00004CB6, 0x000019CD, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, + 0x000047C2, 0x00004CB6, 0x000300F7, 0x00002C98, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, + 0x00002C98, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x0000587A, 0x000002ED, + 0x000500C2, 0x00000017, 0x00003BE7, 0x0000587A, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, + 0x00005E17, 0x00003BE7, 0x000200F9, 0x00002C98, 0x000200F8, 0x00002C98, 0x000700F5, 0x00000017, + 0x00004D37, 0x0000587A, 0x00003463, 0x000029E8, 0x00002B38, 0x00060041, 0x00000294, 0x000060F9, + 0x00001592, 0x00000A0B, 0x00004EAA, 0x0003003E, 0x000060F9, 0x00004D37, 0x00050080, 0x0000000B, + 0x000054B5, 0x00004EAA, 0x00000A10, 0x000300F7, 0x00003F86, 0x00000000, 0x000400FA, 0x00004B9C, + 0x000033E0, 0x00003F86, 0x000200F8, 0x000033E0, 0x0009004F, 0x00000017, 0x00001F17, 0x00002616, + 0x00002616, 0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x000200F9, 0x00003F86, 0x000200F8, + 0x00003F86, 0x000700F5, 0x00000017, 0x00002ACE, 0x00002616, 0x00002C98, 0x00001F17, 0x000033E0, + 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, + 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x00002ACE, 0x000009CE, 0x000500C4, 0x00000017, + 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x00002ACE, 0x0000072E, + 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FFA, + 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, + 0x00002ACF, 0x00002ACE, 0x00003F86, 0x00003FFA, 0x00002958, 0x000300F7, 0x00002C99, 0x00000000, + 0x000400FA, 0x00003B23, 0x00002B39, 0x00002C99, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, + 0x00005E18, 0x00002ACF, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002ACF, 0x000002ED, + 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002C99, 0x000200F8, + 0x00002C99, 0x000700F5, 0x00000017, 0x00004D39, 0x00002ACF, 0x00003A1A, 0x000029E9, 0x00002B39, + 0x00060041, 0x00000294, 0x00001F76, 0x00001592, 0x00000A0B, 0x000054B5, 0x0003003E, 0x00001F76, + 0x00004D39, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_full_64bpp_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_full_64bpp_scaled_cs.h new file mode 100644 index 0000000..6892b11 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_full_64bpp_scaled_cs.h @@ -0,0 +1,4285 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25245 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_runtimearr_uint ArrayStride 4 + OpDecorate %_struct_1948 BufferBlock + OpMemberDecorate %_struct_1948 0 NonWritable + OpMemberDecorate %_struct_1948 0 Offset 0 + OpDecorate %3271 NonWritable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %_struct_1017 Block + OpMemberDecorate %_struct_1017 0 Offset 0 + OpMemberDecorate %_struct_1017 1 Offset 4 + OpMemberDecorate %_struct_1017 2 Offset 8 + OpMemberDecorate %_struct_1017 3 Offset 12 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonReadable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %5522 NonReadable + OpDecorate %5522 Binding 0 + OpDecorate %5522 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %v4uint = OpTypeVector %uint 4 + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 + %v4float = OpTypeVector %float 4 + %bool = OpTypeBool + %v3int = OpTypeVector %int 3 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_4 = OpConstant %uint 4 +%float_65535 = OpConstant %float 65535 + %float_0_5 = OpConstant %float 0.5 + %int_16 = OpConstant %int 16 + %uint_0 = OpConstant %uint 0 + %uint_24 = OpConstant %uint 24 + %653 = OpConstantComposite %v4uint %uint_0 %uint_8 %uint_16 %uint_24 + %uint_255 = OpConstant %uint 255 +%float_0_00392156886 = OpConstant %float 0.00392156886 + %uint_10 = OpConstant %uint 10 + %uint_20 = OpConstant %uint 20 + %uint_30 = OpConstant %uint 30 + %845 = OpConstantComposite %v4uint %uint_0 %uint_10 %uint_20 %uint_30 + %uint_1023 = OpConstant %uint 1023 + %635 = OpConstantComposite %v4uint %uint_1023 %uint_1023 %uint_1023 %uint_3 +%float_0_000977517106 = OpConstant %float 0.000977517106 +%float_0_333333343 = OpConstant %float 0.333333343 + %2798 = OpConstantComposite %v4float %float_0_000977517106 %float_0_000977517106 %float_0_000977517106 %float_0_333333343 + %2996 = OpConstantComposite %v3uint %uint_0 %uint_10 %uint_20 + %uint_127 = OpConstant %uint 127 + %uint_7 = OpConstant %uint 7 + %v3bool = OpTypeVector %bool 3 + %uint_124 = OpConstant %uint 124 + %uint_23 = OpConstant %uint 23 + %v3float = OpTypeVector %float 3 + %float_n1 = OpConstant %float -1 + %int_0 = OpConstant %int 0 + %1959 = OpConstantComposite %v2int %int_16 %int_0 +%float_0_000976592302 = OpConstant %float 0.000976592302 + %v4int = OpTypeVector %int 4 + %290 = OpConstantComposite %v4int %int_16 %int_0 %int_16 %int_0 + %1837 = OpConstantComposite %v2uint %uint_2 %uint_1 + %v2bool = OpTypeVector %bool 2 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %uint_80 = OpConstant %uint 80 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %uint_2048 = OpConstant %uint 2048 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_6 = OpConstant %uint 6 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_runtimearr_uint = OpTypeRuntimeArray %uint +%_struct_1948 = OpTypeStruct %_runtimearr_uint +%_ptr_Uniform__struct_1948 = OpTypePointer Uniform %_struct_1948 + %3271 = OpVariable %_ptr_Uniform__struct_1948 Uniform +%_ptr_Uniform_uint = OpTypePointer Uniform %uint +%_struct_1017 = OpTypeStruct %uint %uint %uint %uint +%_ptr_PushConstant__struct_1017 = OpTypePointer PushConstant %_struct_1017 + %3305 = OpVariable %_ptr_PushConstant__struct_1017 PushConstant +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_15 = OpConstant %uint 15 + %uint_28 = OpConstant %uint 28 + %uint_19 = OpConstant %uint 19 + %2179 = OpConstantComposite %v2uint %uint_16 %uint_19 +%uint_536870912 = OpConstant %uint 536870912 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 + %int_10 = OpConstant %int 10 + %uint_63 = OpConstant %uint 63 + %int_26 = OpConstant %int 26 + %int_23 = OpConstant %int 23 +%uint_16777216 = OpConstant %uint 16777216 + %2275 = OpConstantComposite %v2uint %uint_20 %uint_24 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %1825 = OpConstantComposite %v2uint %uint_2 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %5522 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %1955 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %1284 = OpConstantComposite %v4float %float_n1 %float_n1 %float_n1 %float_n1 + %770 = OpConstantComposite %v4int %int_16 %int_16 %int_16 %int_16 + %1611 = OpConstantComposite %v4uint %uint_255 %uint_255 %uint_255 %uint_255 + %261 = OpConstantComposite %v3uint %uint_1023 %uint_1023 %uint_1023 + %1126 = OpConstantComposite %v3uint %uint_127 %uint_127 %uint_127 + %2828 = OpConstantComposite %v3uint %uint_7 %uint_7 %uint_7 + %2578 = OpConstantComposite %v3uint %uint_0 %uint_0 %uint_0 + %1018 = OpConstantComposite %v3uint %uint_124 %uint_124 %uint_124 + %393 = OpConstantComposite %v3uint %uint_23 %uint_23 %uint_23 + %141 = OpConstantComposite %v3uint %uint_16 %uint_16 %uint_16 + %73 = OpConstantComposite %v2float %float_n1 %float_n1 + %2151 = OpConstantComposite %v2int %int_16 %int_16 + %2938 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 + %1285 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 + %325 = OpConstantComposite %v4float %float_0_5 %float_0_5 %float_0_5 %float_0_5 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 +%int_1065353216 = OpConstant %int 1065353216 +%uint_4294967290 = OpConstant %uint 4294967290 + %2360 = OpConstantComposite %v3uint %uint_4294967290 %uint_4294967290 %uint_4294967290 + %float_0_25 = OpConstant %float 0.25 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %19978 = OpShiftRightLogical %uint %15627 %uint_10 + %8574 = OpBitwiseAnd %uint %19978 %uint_3 + %21002 = OpShiftRightLogical %uint %15627 %uint_13 + %8575 = OpBitwiseAnd %uint %21002 %uint_2047 + %21003 = OpShiftRightLogical %uint %15627 %uint_24 + %8576 = OpBitwiseAnd %uint %21003 %uint_15 + %18836 = OpShiftRightLogical %uint %15627 %uint_28 + %9130 = OpBitwiseAnd %uint %18836 %uint_1 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9633 = OpShiftRightLogical %v2uint %8871 %2179 + %23601 = OpBitwiseAnd %v2uint %9633 %1954 + %24030 = OpBitwiseAnd %uint %15627 %uint_536870912 + %12295 = OpINotEqual %bool %24030 %uint_0 + OpSelectionMerge %14676 None + OpBranchConditional %12295 %16739 %21992 + %21992 = OpLabel + OpBranch %14676 + %16739 = OpLabel + %15278 = OpShiftRightLogical %v2uint %23601 %1828 + OpBranch %14676 + %14676 = OpLabel + %19124 = OpPhi %v2uint %15278 %16739 %1807 %21992 + %7038 = OpShiftRightLogical %v2uint %8871 %1855 + %11769 = OpBitwiseAnd %v2uint %7038 %1955 + %16207 = OpShiftLeftLogical %v2uint %11769 %1870 + %23019 = OpIMul %v2uint %16207 %23601 + %13123 = OpShiftRightLogical %uint %20824 %uint_5 + %14785 = OpBitwiseAnd %uint %13123 %uint_2047 + %8858 = OpCompositeExtract %uint %23601 0 + %22993 = OpIMul %uint %14785 %8858 + %20036 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %18628 = OpLoad %uint %20036 + %22701 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %20919 = OpLoad %uint %22701 + %19164 = OpBitwiseAnd %uint %18628 %uint_7 + %21999 = OpBitwiseAnd %uint %18628 %uint_8 + %20495 = OpINotEqual %bool %21999 %uint_0 + %10307 = OpShiftRightLogical %uint %18628 %uint_4 + %24434 = OpBitwiseAnd %uint %10307 %uint_7 + %19672 = OpShiftRightLogical %uint %18628 %uint_7 + %20627 = OpBitwiseAnd %uint %19672 %uint_63 + %22920 = OpBitcast %int %18628 + %13711 = OpShiftLeftLogical %int %22920 %int_10 + %20636 = OpShiftRightArithmetic %int %13711 %int_26 + %18178 = OpShiftLeftLogical %int %20636 %int_23 + %7462 = OpIAdd %int %18178 %int_1065353216 + %11052 = OpBitcast %float %7462 + %22649 = OpBitwiseAnd %uint %18628 %uint_16777216 + %7513 = OpINotEqual %bool %22649 %uint_0 + %8003 = OpBitwiseAnd %uint %20919 %uint_1023 + %15783 = OpShiftLeftLogical %uint %8003 %uint_5 + %22591 = OpShiftRightLogical %uint %20919 %uint_10 + %19390 = OpBitwiseAnd %uint %22591 %uint_1023 + %25203 = OpShiftLeftLogical %uint %19390 %uint_5 + %10422 = OpCompositeConstruct %v2uint %20919 %20919 + %10385 = OpShiftRightLogical %v2uint %10422 %2275 + %23379 = OpBitwiseAnd %v2uint %10385 %2122 + %16208 = OpShiftLeftLogical %v2uint %23379 %1870 + %23020 = OpIMul %v2uint %16208 %23601 + %12743 = OpShiftRightLogical %uint %20919 %uint_28 + %17238 = OpBitwiseAnd %uint %12743 %uint_7 + %12737 = OpLoad %v3uint %gl_GlobalInvocationID + %14500 = OpVectorShuffle %v2uint %12737 %12737 0 1 + %12025 = OpShiftLeftLogical %v2uint %14500 %1825 + %7640 = OpCompositeExtract %uint %12025 0 + %11658 = OpShiftLeftLogical %uint %22993 %uint_3 + %15379 = OpUGreaterThanEqual %bool %7640 %11658 + OpSelectionMerge %14025 DontFlatten + OpBranchConditional %15379 %21993 %14025 + %21993 = OpLabel + OpBranch %19578 + %14025 = OpLabel + %18615 = OpCompositeExtract %uint %12025 1 + %16803 = OpCompositeExtract %uint %19124 1 + %24446 = OpExtInst %uint %1 UMax %18615 %16803 + %20975 = OpCompositeConstruct %v2uint %7640 %24446 + %21036 = OpIAdd %v2uint %20975 %23019 + %16075 = OpULessThanEqual %bool %17238 %uint_3 + OpSelectionMerge %23776 None + OpBranchConditional %16075 %10990 %15087 + %15087 = OpLabel + %13566 = OpIEqual %bool %17238 %uint_5 + %8438 = OpSelect %uint %13566 %uint_2 %uint_0 + OpBranch %23776 + %10990 = OpLabel + OpBranch %23776 + %23776 = OpLabel + %19300 = OpPhi %uint %17238 %10990 %8438 %15087 + %16830 = OpCompositeConstruct %v2uint %8574 %8574 + %11801 = OpUGreaterThanEqual %v2bool %16830 %1837 + %19381 = OpSelect %v2uint %11801 %1828 %1807 + %10986 = OpShiftLeftLogical %v2uint %21036 %19381 + %24669 = OpCompositeConstruct %v2uint %19300 %19300 + %9093 = OpShiftRightLogical %v2uint %24669 %1816 + %16072 = OpBitwiseAnd %v2uint %9093 %1828 + %18106 = OpIAdd %v2uint %10986 %16072 + %22936 = OpIMul %v2uint %2719 %23601 + %11332 = OpCompositeConstruct %v2uint %9130 %uint_0 + %6571 = OpShiftRightLogical %v2uint %22936 %11332 + %10146 = OpUDiv %v2uint %18106 %6571 + %20390 = OpCompositeExtract %uint %10146 1 + %11046 = OpIMul %uint %20390 %20561 + %24665 = OpCompositeExtract %uint %10146 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %8575 %21536 + %22376 = OpIMul %v2uint %10146 %6571 + %20715 = OpISub %v2uint %18106 %22376 + %7303 = OpCompositeExtract %uint %22936 0 + %22882 = OpCompositeExtract %uint %22936 1 + %13170 = OpIMul %uint %7303 %22882 + %14551 = OpIMul %uint %8742 %13170 + %6805 = OpCompositeExtract %uint %20715 1 + %23526 = OpCompositeExtract %uint %6571 0 + %22886 = OpIMul %uint %6805 %23526 + %6886 = OpCompositeExtract %uint %20715 0 + %9696 = OpIAdd %uint %22886 %6886 + %18021 = OpShiftLeftLogical %uint %9696 %9130 + %18363 = OpIAdd %uint %14551 %18021 + %13504 = OpIMul %uint %13170 %uint_2048 + %25231 = OpUMod %uint %18363 %13504 + %16379 = OpUGreaterThanEqual %bool %8574 %uint_2 + %24735 = OpSelect %uint %16379 %uint_1 %uint_0 + %20074 = OpIAdd %uint %9130 %24735 + %6555 = OpShiftLeftLogical %uint %uint_1 %20074 + %23279 = OpINotEqual %bool %9130 %uint_0 + OpSelectionMerge %21263 DontFlatten + OpBranchConditional %23279 %15205 %16569 + %16569 = OpLabel + %19162 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20297 DontFlatten + OpBranchConditional %19162 %9761 %12129 + %12129 = OpLabel + %19407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %25231 + %23875 = OpLoad %uint %19407 + %11687 = OpIAdd %uint %25231 %6555 + %6475 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11687 + %24155 = OpLoad %uint %6475 + %6234 = OpIMul %uint %uint_2 %6555 + %8353 = OpIAdd %uint %25231 %6234 + %15309 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8353 + %24156 = OpLoad %uint %15309 + %6235 = OpIMul %uint %uint_3 %6555 + %8354 = OpIAdd %uint %25231 %6235 + %14321 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8354 + %16380 = OpLoad %uint %14321 + %20780 = OpCompositeConstruct %v4uint %23875 %24155 %24156 %16380 + OpBranch %20297 + %9761 = OpLabel + %21829 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %25231 + %23876 = OpLoad %uint %21829 + %11688 = OpIAdd %uint %25231 %uint_1 + %6399 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11688 + %23650 = OpLoad %uint %6399 + %11689 = OpIAdd %uint %25231 %uint_2 + %6400 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11689 + %23651 = OpLoad %uint %6400 + %11690 = OpIAdd %uint %25231 %uint_3 + %24558 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11690 + %16381 = OpLoad %uint %24558 + %20781 = OpCompositeConstruct %v4uint %23876 %23650 %23651 %16381 + OpBranch %20297 + %20297 = OpLabel + %10943 = OpPhi %v4uint %20781 %9761 %20780 %12129 + OpSelectionMerge %16224 None + OpSwitch %8576 %19451 0 %14585 1 %14585 2 %7355 10 %7355 3 %7354 12 %7354 4 %8190 6 %8243 + %8243 = OpLabel + %24406 = OpCompositeExtract %uint %10943 0 + %24679 = OpExtInst %v2float %1 UnpackHalf2x16 %24406 + %10082 = OpCompositeExtract %float %24679 0 + %17478 = OpCompositeExtract %float %24679 1 + %14604 = OpCompositeConstruct %v4float %10082 %17478 %float_0 %float_0 + %17274 = OpCompositeExtract %uint %10943 1 + %18027 = OpExtInst %v2float %1 UnpackHalf2x16 %17274 + %10083 = OpCompositeExtract %float %18027 0 + %17479 = OpCompositeExtract %float %18027 1 + %14605 = OpCompositeConstruct %v4float %10083 %17479 %float_0 %float_0 + %17275 = OpCompositeExtract %uint %10943 2 + %18028 = OpExtInst %v2float %1 UnpackHalf2x16 %17275 + %10084 = OpCompositeExtract %float %18028 0 + %17480 = OpCompositeExtract %float %18028 1 + %14606 = OpCompositeConstruct %v4float %10084 %17480 %float_0 %float_0 + %17276 = OpCompositeExtract %uint %10943 3 + %18029 = OpExtInst %v2float %1 UnpackHalf2x16 %17276 + %10085 = OpCompositeExtract %float %18029 0 + %20670 = OpCompositeExtract %float %18029 1 + %9033 = OpCompositeConstruct %v4float %10085 %20670 %float_0 %float_0 + OpBranch %16224 + %8190 = OpLabel + %12427 = OpCompositeExtract %uint %10943 0 + %22685 = OpBitcast %int %12427 + %18202 = OpCompositeConstruct %v2int %22685 %22685 + %18349 = OpShiftLeftLogical %v2int %18202 %1959 + %13335 = OpShiftRightArithmetic %v2int %18349 %2151 + %10903 = OpConvertSToF %v2float %13335 + %18247 = OpVectorTimesScalar %v2float %10903 %float_0_000976592302 + %24070 = OpExtInst %v2float %1 FMax %73 %18247 + %24330 = OpCompositeExtract %float %24070 0 + %15572 = OpCompositeExtract %float %24070 1 + %16670 = OpCompositeConstruct %v4float %24330 %15572 %float_0 %float_0 + %19522 = OpCompositeExtract %uint %10943 1 + %16033 = OpBitcast %int %19522 + %18203 = OpCompositeConstruct %v2int %16033 %16033 + %18350 = OpShiftLeftLogical %v2int %18203 %1959 + %13336 = OpShiftRightArithmetic %v2int %18350 %2151 + %10904 = OpConvertSToF %v2float %13336 + %18248 = OpVectorTimesScalar %v2float %10904 %float_0_000976592302 + %24071 = OpExtInst %v2float %1 FMax %73 %18248 + %24331 = OpCompositeExtract %float %24071 0 + %15573 = OpCompositeExtract %float %24071 1 + %16671 = OpCompositeConstruct %v4float %24331 %15573 %float_0 %float_0 + %19523 = OpCompositeExtract %uint %10943 2 + %16034 = OpBitcast %int %19523 + %18204 = OpCompositeConstruct %v2int %16034 %16034 + %18351 = OpShiftLeftLogical %v2int %18204 %1959 + %13337 = OpShiftRightArithmetic %v2int %18351 %2151 + %10905 = OpConvertSToF %v2float %13337 + %18249 = OpVectorTimesScalar %v2float %10905 %float_0_000976592302 + %24072 = OpExtInst %v2float %1 FMax %73 %18249 + %24332 = OpCompositeExtract %float %24072 0 + %15574 = OpCompositeExtract %float %24072 1 + %16672 = OpCompositeConstruct %v4float %24332 %15574 %float_0 %float_0 + %19524 = OpCompositeExtract %uint %10943 3 + %16035 = OpBitcast %int %19524 + %18205 = OpCompositeConstruct %v2int %16035 %16035 + %18352 = OpShiftLeftLogical %v2int %18205 %1959 + %13338 = OpShiftRightArithmetic %v2int %18352 %2151 + %10906 = OpConvertSToF %v2float %13338 + %18250 = OpVectorTimesScalar %v2float %10906 %float_0_000976592302 + %24073 = OpExtInst %v2float %1 FMax %73 %18250 + %24333 = OpCompositeExtract %float %24073 0 + %18764 = OpCompositeExtract %float %24073 1 + %9034 = OpCompositeConstruct %v4float %24333 %18764 %float_0 %float_0 + OpBranch %16224 + %7354 = OpLabel + %22205 = OpCompositeExtract %uint %10943 0 + %20234 = OpCompositeConstruct %v3uint %22205 %22205 %22205 + %11021 = OpShiftRightLogical %v3uint %20234 %2996 + %24038 = OpBitwiseAnd %v3uint %11021 %261 + %18588 = OpBitwiseAnd %v3uint %24038 %1126 + %23440 = OpShiftRightLogical %v3uint %24038 %2828 + %16585 = OpIEqual %v3bool %23440 %2578 + %11339 = OpExtInst %v3int %1 FindUMsb %18588 + %10773 = OpBitcast %v3uint %11339 + %6266 = OpISub %v3uint %2828 %10773 + %8720 = OpIAdd %v3uint %10773 %2360 + %10351 = OpSelect %v3uint %16585 %8720 %23440 + %23252 = OpShiftLeftLogical %v3uint %18588 %6266 + %18842 = OpBitwiseAnd %v3uint %23252 %1126 + %10909 = OpSelect %v3uint %16585 %18842 %18588 + %24569 = OpIAdd %v3uint %10351 %1018 + %20351 = OpShiftLeftLogical %v3uint %24569 %393 + %16294 = OpShiftLeftLogical %v3uint %10909 %141 + %22396 = OpBitwiseOr %v3uint %20351 %16294 + %13824 = OpIEqual %v3bool %24038 %2578 + %16962 = OpSelect %v3uint %13824 %2578 %22396 + %10703 = OpBitcast %v3float %16962 + %19364 = OpShiftRightLogical %uint %22205 %uint_30 + %18446 = OpConvertUToF %float %19364 + %15903 = OpFMul %float %18446 %float_0_333333343 + %21442 = OpCompositeExtract %float %10703 0 + %10837 = OpCompositeExtract %float %10703 1 + %7833 = OpCompositeExtract %float %10703 2 + %15834 = OpCompositeConstruct %v4float %21442 %10837 %7833 %15903 + %10229 = OpCompositeExtract %uint %10943 1 + %13582 = OpCompositeConstruct %v3uint %10229 %10229 %10229 + %11022 = OpShiftRightLogical %v3uint %13582 %2996 + %24039 = OpBitwiseAnd %v3uint %11022 %261 + %18589 = OpBitwiseAnd %v3uint %24039 %1126 + %23441 = OpShiftRightLogical %v3uint %24039 %2828 + %16586 = OpIEqual %v3bool %23441 %2578 + %11340 = OpExtInst %v3int %1 FindUMsb %18589 + %10774 = OpBitcast %v3uint %11340 + %6267 = OpISub %v3uint %2828 %10774 + %8721 = OpIAdd %v3uint %10774 %2360 + %10352 = OpSelect %v3uint %16586 %8721 %23441 + %23253 = OpShiftLeftLogical %v3uint %18589 %6267 + %18843 = OpBitwiseAnd %v3uint %23253 %1126 + %10910 = OpSelect %v3uint %16586 %18843 %18589 + %24570 = OpIAdd %v3uint %10352 %1018 + %20352 = OpShiftLeftLogical %v3uint %24570 %393 + %16295 = OpShiftLeftLogical %v3uint %10910 %141 + %22397 = OpBitwiseOr %v3uint %20352 %16295 + %13825 = OpIEqual %v3bool %24039 %2578 + %16963 = OpSelect %v3uint %13825 %2578 %22397 + %10704 = OpBitcast %v3float %16963 + %19365 = OpShiftRightLogical %uint %10229 %uint_30 + %18447 = OpConvertUToF %float %19365 + %15904 = OpFMul %float %18447 %float_0_333333343 + %21443 = OpCompositeExtract %float %10704 0 + %10838 = OpCompositeExtract %float %10704 1 + %7834 = OpCompositeExtract %float %10704 2 + %15835 = OpCompositeConstruct %v4float %21443 %10838 %7834 %15904 + %10230 = OpCompositeExtract %uint %10943 2 + %13583 = OpCompositeConstruct %v3uint %10230 %10230 %10230 + %11023 = OpShiftRightLogical %v3uint %13583 %2996 + %24040 = OpBitwiseAnd %v3uint %11023 %261 + %18590 = OpBitwiseAnd %v3uint %24040 %1126 + %23442 = OpShiftRightLogical %v3uint %24040 %2828 + %16587 = OpIEqual %v3bool %23442 %2578 + %11341 = OpExtInst %v3int %1 FindUMsb %18590 + %10775 = OpBitcast %v3uint %11341 + %6268 = OpISub %v3uint %2828 %10775 + %8722 = OpIAdd %v3uint %10775 %2360 + %10353 = OpSelect %v3uint %16587 %8722 %23442 + %23254 = OpShiftLeftLogical %v3uint %18590 %6268 + %18844 = OpBitwiseAnd %v3uint %23254 %1126 + %10911 = OpSelect %v3uint %16587 %18844 %18590 + %24571 = OpIAdd %v3uint %10353 %1018 + %20353 = OpShiftLeftLogical %v3uint %24571 %393 + %16296 = OpShiftLeftLogical %v3uint %10911 %141 + %22398 = OpBitwiseOr %v3uint %20353 %16296 + %13826 = OpIEqual %v3bool %24040 %2578 + %16964 = OpSelect %v3uint %13826 %2578 %22398 + %10705 = OpBitcast %v3float %16964 + %19366 = OpShiftRightLogical %uint %10230 %uint_30 + %18448 = OpConvertUToF %float %19366 + %15905 = OpFMul %float %18448 %float_0_333333343 + %21444 = OpCompositeExtract %float %10705 0 + %10839 = OpCompositeExtract %float %10705 1 + %7835 = OpCompositeExtract %float %10705 2 + %15836 = OpCompositeConstruct %v4float %21444 %10839 %7835 %15905 + %10231 = OpCompositeExtract %uint %10943 3 + %13584 = OpCompositeConstruct %v3uint %10231 %10231 %10231 + %11024 = OpShiftRightLogical %v3uint %13584 %2996 + %24041 = OpBitwiseAnd %v3uint %11024 %261 + %18591 = OpBitwiseAnd %v3uint %24041 %1126 + %23443 = OpShiftRightLogical %v3uint %24041 %2828 + %16588 = OpIEqual %v3bool %23443 %2578 + %11342 = OpExtInst %v3int %1 FindUMsb %18591 + %10776 = OpBitcast %v3uint %11342 + %6269 = OpISub %v3uint %2828 %10776 + %8723 = OpIAdd %v3uint %10776 %2360 + %10354 = OpSelect %v3uint %16588 %8723 %23443 + %23255 = OpShiftLeftLogical %v3uint %18591 %6269 + %18845 = OpBitwiseAnd %v3uint %23255 %1126 + %10912 = OpSelect %v3uint %16588 %18845 %18591 + %24572 = OpIAdd %v3uint %10354 %1018 + %20354 = OpShiftLeftLogical %v3uint %24572 %393 + %16297 = OpShiftLeftLogical %v3uint %10912 %141 + %22399 = OpBitwiseOr %v3uint %20354 %16297 + %13827 = OpIEqual %v3bool %24041 %2578 + %16965 = OpSelect %v3uint %13827 %2578 %22399 + %10706 = OpBitcast %v3float %16965 + %19367 = OpShiftRightLogical %uint %10231 %uint_30 + %18449 = OpConvertUToF %float %19367 + %15906 = OpFMul %float %18449 %float_0_333333343 + %21445 = OpCompositeExtract %float %10706 0 + %10840 = OpCompositeExtract %float %10706 1 + %11025 = OpCompositeExtract %float %10706 2 + %9035 = OpCompositeConstruct %v4float %21445 %10840 %11025 %15906 + OpBranch %16224 + %7355 = OpLabel + %22206 = OpCompositeExtract %uint %10943 0 + %20235 = OpCompositeConstruct %v4uint %22206 %22206 %22206 %22206 + %9368 = OpShiftRightLogical %v4uint %20235 %845 + %18859 = OpBitwiseAnd %v4uint %9368 %635 + %15543 = OpConvertUToF %v4float %18859 + %16688 = OpFMul %v4float %15543 %2798 + %23762 = OpCompositeExtract %uint %10943 1 + %20813 = OpCompositeConstruct %v4uint %23762 %23762 %23762 %23762 + %9369 = OpShiftRightLogical %v4uint %20813 %845 + %18860 = OpBitwiseAnd %v4uint %9369 %635 + %15544 = OpConvertUToF %v4float %18860 + %16689 = OpFMul %v4float %15544 %2798 + %23763 = OpCompositeExtract %uint %10943 2 + %20814 = OpCompositeConstruct %v4uint %23763 %23763 %23763 %23763 + %9370 = OpShiftRightLogical %v4uint %20814 %845 + %18861 = OpBitwiseAnd %v4uint %9370 %635 + %15545 = OpConvertUToF %v4float %18861 + %16690 = OpFMul %v4float %15545 %2798 + %23764 = OpCompositeExtract %uint %10943 3 + %20815 = OpCompositeConstruct %v4uint %23764 %23764 %23764 %23764 + %9371 = OpShiftRightLogical %v4uint %20815 %845 + %18862 = OpBitwiseAnd %v4uint %9371 %635 + %18735 = OpConvertUToF %v4float %18862 + %9887 = OpFMul %v4float %18735 %2798 + OpBranch %16224 + %14585 = OpLabel + %22207 = OpCompositeExtract %uint %10943 0 + %20236 = OpCompositeConstruct %v4uint %22207 %22207 %22207 %22207 + %9372 = OpShiftRightLogical %v4uint %20236 %653 + %19030 = OpBitwiseAnd %v4uint %9372 %1611 + %13986 = OpConvertUToF %v4float %19030 + %19235 = OpVectorTimesScalar %v4float %13986 %float_0_00392156886 + %8607 = OpCompositeExtract %uint %10943 1 + %24843 = OpCompositeConstruct %v4uint %8607 %8607 %8607 %8607 + %9373 = OpShiftRightLogical %v4uint %24843 %653 + %19031 = OpBitwiseAnd %v4uint %9373 %1611 + %13987 = OpConvertUToF %v4float %19031 + %19236 = OpVectorTimesScalar %v4float %13987 %float_0_00392156886 + %8608 = OpCompositeExtract %uint %10943 2 + %24844 = OpCompositeConstruct %v4uint %8608 %8608 %8608 %8608 + %9374 = OpShiftRightLogical %v4uint %24844 %653 + %19032 = OpBitwiseAnd %v4uint %9374 %1611 + %13988 = OpConvertUToF %v4float %19032 + %19237 = OpVectorTimesScalar %v4float %13988 %float_0_00392156886 + %8609 = OpCompositeExtract %uint %10943 3 + %24845 = OpCompositeConstruct %v4uint %8609 %8609 %8609 %8609 + %9375 = OpShiftRightLogical %v4uint %24845 %653 + %19033 = OpBitwiseAnd %v4uint %9375 %1611 + %17178 = OpConvertUToF %v4float %19033 + %12434 = OpVectorTimesScalar %v4float %17178 %float_0_00392156886 + OpBranch %16224 + %19451 = OpLabel + %12428 = OpCompositeExtract %uint %10943 0 + %20462 = OpBitcast %float %12428 + %17206 = OpCompositeConstruct %v2float %20462 %float_0 + %11664 = OpVectorShuffle %v4float %17206 %17206 0 1 1 1 + %22193 = OpCompositeExtract %uint %10943 1 + %16232 = OpBitcast %float %22193 + %17207 = OpCompositeConstruct %v2float %16232 %float_0 + %11665 = OpVectorShuffle %v4float %17207 %17207 0 1 1 1 + %22194 = OpCompositeExtract %uint %10943 2 + %16233 = OpBitcast %float %22194 + %17208 = OpCompositeConstruct %v2float %16233 %float_0 + %11666 = OpVectorShuffle %v4float %17208 %17208 0 1 1 1 + %22195 = OpCompositeExtract %uint %10943 3 + %16234 = OpBitcast %float %22195 + %20398 = OpCompositeConstruct %v2float %16234 %float_0 + %23098 = OpVectorShuffle %v4float %20398 %20398 0 1 1 1 + OpBranch %16224 + %16224 = OpLabel + %11175 = OpPhi %v4float %23098 %19451 %12434 %14585 %9887 %7355 %9035 %7354 %9034 %8190 %9033 %8243 + %14344 = OpPhi %v4float %11666 %19451 %19237 %14585 %16690 %7355 %15836 %7354 %16672 %8190 %14606 %8243 + %15229 = OpPhi %v4float %11665 %19451 %19236 %14585 %16689 %7355 %15835 %7354 %16671 %8190 %14605 %8243 + %14518 = OpPhi %v4float %11664 %19451 %19235 %14585 %16688 %7355 %15834 %7354 %16670 %8190 %14604 %8243 + OpBranch %21263 + %15205 = OpLabel + %21584 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20259 DontFlatten + OpBranchConditional %21584 %9762 %12130 + %12130 = OpLabel + %19408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %25231 + %23877 = OpLoad %uint %19408 + %11691 = OpIAdd %uint %25231 %uint_1 + %6401 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11691 + %23652 = OpLoad %uint %6401 + %11692 = OpIAdd %uint %25231 %6555 + %6402 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11692 + %23653 = OpLoad %uint %6402 + %11693 = OpIAdd %uint %11692 %uint_1 + %24559 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11693 + %14156 = OpLoad %uint %24559 + %19670 = OpCompositeConstruct %v4uint %23877 %23652 %23653 %14156 + %17048 = OpIMul %uint %uint_2 %6555 + %13991 = OpIAdd %uint %25231 %17048 + %15233 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13991 + %23654 = OpLoad %uint %15233 + %11694 = OpIAdd %uint %13991 %uint_1 + %6476 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11694 + %24157 = OpLoad %uint %6476 + %6236 = OpIMul %uint %uint_3 %6555 + %8355 = OpIAdd %uint %25231 %6236 + %15234 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8355 + %23655 = OpLoad %uint %15234 + %11695 = OpIAdd %uint %8355 %uint_1 + %24560 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11695 + %16382 = OpLoad %uint %24560 + %20782 = OpCompositeConstruct %v4uint %23654 %24157 %23655 %16382 + OpBranch %20259 + %9762 = OpLabel + %21830 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %25231 + %23878 = OpLoad %uint %21830 + %11696 = OpIAdd %uint %25231 %uint_1 + %6403 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11696 + %23656 = OpLoad %uint %6403 + %11697 = OpIAdd %uint %25231 %uint_2 + %6404 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11697 + %23657 = OpLoad %uint %6404 + %11698 = OpIAdd %uint %25231 %uint_3 + %24561 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11698 + %14080 = OpLoad %uint %24561 + %19165 = OpCompositeConstruct %v4uint %23878 %23656 %23657 %14080 + %22501 = OpIAdd %uint %25231 %uint_4 + %24651 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22501 + %23658 = OpLoad %uint %24651 + %11699 = OpIAdd %uint %25231 %uint_5 + %6405 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11699 + %23659 = OpLoad %uint %6405 + %11700 = OpIAdd %uint %25231 %uint_6 + %6406 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11700 + %23660 = OpLoad %uint %6406 + %11701 = OpIAdd %uint %25231 %uint_7 + %24562 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11701 + %16383 = OpLoad %uint %24562 + %20783 = OpCompositeConstruct %v4uint %23658 %23659 %23660 %16383 + OpBranch %20259 + %20259 = OpLabel + %11213 = OpPhi %v4uint %20783 %9762 %20782 %12130 + %14112 = OpPhi %v4uint %19165 %9762 %19670 %12130 + OpSelectionMerge %20260 None + OpSwitch %8576 %20310 5 %8536 7 %8244 + %8244 = OpLabel + %24407 = OpCompositeExtract %uint %14112 0 + %24680 = OpExtInst %v2float %1 UnpackHalf2x16 %24407 + %10101 = OpCompositeExtract %float %24680 0 + %16056 = OpCompositeExtract %float %24680 1 + %17025 = OpCompositeExtract %uint %14112 1 + %15605 = OpExtInst %v2float %1 UnpackHalf2x16 %17025 + %10086 = OpCompositeExtract %float %15605 0 + %17481 = OpCompositeExtract %float %15605 1 + %14607 = OpCompositeConstruct %v4float %10101 %16056 %10086 %17481 + %17277 = OpCompositeExtract %uint %14112 2 + %18030 = OpExtInst %v2float %1 UnpackHalf2x16 %17277 + %10102 = OpCompositeExtract %float %18030 0 + %16057 = OpCompositeExtract %float %18030 1 + %17026 = OpCompositeExtract %uint %14112 3 + %15606 = OpExtInst %v2float %1 UnpackHalf2x16 %17026 + %10087 = OpCompositeExtract %float %15606 0 + %17482 = OpCompositeExtract %float %15606 1 + %14608 = OpCompositeConstruct %v4float %10102 %16057 %10087 %17482 + %17278 = OpCompositeExtract %uint %11213 0 + %18031 = OpExtInst %v2float %1 UnpackHalf2x16 %17278 + %10103 = OpCompositeExtract %float %18031 0 + %16058 = OpCompositeExtract %float %18031 1 + %17027 = OpCompositeExtract %uint %11213 1 + %15607 = OpExtInst %v2float %1 UnpackHalf2x16 %17027 + %10088 = OpCompositeExtract %float %15607 0 + %17483 = OpCompositeExtract %float %15607 1 + %14609 = OpCompositeConstruct %v4float %10103 %16058 %10088 %17483 + %17279 = OpCompositeExtract %uint %11213 2 + %18032 = OpExtInst %v2float %1 UnpackHalf2x16 %17279 + %10104 = OpCompositeExtract %float %18032 0 + %16059 = OpCompositeExtract %float %18032 1 + %17028 = OpCompositeExtract %uint %11213 3 + %15608 = OpExtInst %v2float %1 UnpackHalf2x16 %17028 + %10089 = OpCompositeExtract %float %15608 0 + %20671 = OpCompositeExtract %float %15608 1 + %9036 = OpCompositeConstruct %v4float %10104 %16059 %10089 %20671 + OpBranch %20260 + %8536 = OpLabel + %9723 = OpVectorShuffle %v2uint %14112 %14112 0 1 + %23356 = OpBitcast %v2int %9723 + %24782 = OpVectorShuffle %v4int %23356 %23356 0 0 1 1 + %18598 = OpShiftLeftLogical %v4int %24782 %290 + %15757 = OpShiftRightArithmetic %v4int %18598 %770 + %10907 = OpConvertSToF %v4float %15757 + %18209 = OpVectorTimesScalar %v4float %10907 %float_0_000976592302 + %25233 = OpExtInst %v4float %1 FMax %1284 %18209 + %14187 = OpVectorShuffle %v2uint %14112 %14112 2 3 + %9407 = OpBitcast %v2int %14187 + %24783 = OpVectorShuffle %v4int %9407 %9407 0 0 1 1 + %18599 = OpShiftLeftLogical %v4int %24783 %290 + %15758 = OpShiftRightArithmetic %v4int %18599 %770 + %10908 = OpConvertSToF %v4float %15758 + %18210 = OpVectorTimesScalar %v4float %10908 %float_0_000976592302 + %25234 = OpExtInst %v4float %1 FMax %1284 %18210 + %14188 = OpVectorShuffle %v2uint %11213 %11213 0 1 + %9408 = OpBitcast %v2int %14188 + %24784 = OpVectorShuffle %v4int %9408 %9408 0 0 1 1 + %18600 = OpShiftLeftLogical %v4int %24784 %290 + %15759 = OpShiftRightArithmetic %v4int %18600 %770 + %10913 = OpConvertSToF %v4float %15759 + %18211 = OpVectorTimesScalar %v4float %10913 %float_0_000976592302 + %25235 = OpExtInst %v4float %1 FMax %1284 %18211 + %14189 = OpVectorShuffle %v2uint %11213 %11213 2 3 + %9409 = OpBitcast %v2int %14189 + %24785 = OpVectorShuffle %v4int %9409 %9409 0 0 1 1 + %18601 = OpShiftLeftLogical %v4int %24785 %290 + %15760 = OpShiftRightArithmetic %v4int %18601 %770 + %10914 = OpConvertSToF %v4float %15760 + %21439 = OpVectorTimesScalar %v4float %10914 %float_0_000976592302 + %17250 = OpExtInst %v4float %1 FMax %1284 %21439 + OpBranch %20260 + %20310 = OpLabel + %9763 = OpVectorShuffle %v2uint %14112 %14112 0 1 + %20825 = OpBitcast %v2float %9763 + %7035 = OpCompositeExtract %float %20825 0 + %13418 = OpCompositeExtract %float %20825 1 + %17016 = OpCompositeConstruct %v4float %7035 %13418 %float_0 %float_0 + %16856 = OpVectorShuffle %v2uint %14112 %14112 2 3 + %14173 = OpBitcast %v2float %16856 + %7036 = OpCompositeExtract %float %14173 0 + %13419 = OpCompositeExtract %float %14173 1 + %17017 = OpCompositeConstruct %v4float %7036 %13419 %float_0 %float_0 + %16857 = OpVectorShuffle %v2uint %11213 %11213 0 1 + %14174 = OpBitcast %v2float %16857 + %7037 = OpCompositeExtract %float %14174 0 + %13420 = OpCompositeExtract %float %14174 1 + %17018 = OpCompositeConstruct %v4float %7037 %13420 %float_0 %float_0 + %16858 = OpVectorShuffle %v2uint %11213 %11213 2 3 + %14175 = OpBitcast %v2float %16858 + %7039 = OpCompositeExtract %float %14175 0 + %16648 = OpCompositeExtract %float %14175 1 + %9037 = OpCompositeConstruct %v4float %7039 %16648 %float_0 %float_0 + OpBranch %20260 + %20260 = OpLabel + %11176 = OpPhi %v4float %9037 %20310 %17250 %8536 %9036 %8244 + %14345 = OpPhi %v4float %17018 %20310 %25235 %8536 %14609 %8244 + %15230 = OpPhi %v4float %17017 %20310 %25234 %8536 %14608 %8244 + %14519 = OpPhi %v4float %17016 %20310 %25233 %8536 %14607 %8244 + OpBranch %21263 + %21263 = OpLabel + %11177 = OpPhi %v4float %11176 %20260 %11175 %16224 + %14346 = OpPhi %v4float %14345 %20260 %14344 %16224 + %13804 = OpPhi %v4float %15230 %20260 %15229 %16224 + %8403 = OpPhi %v4float %14519 %20260 %14518 %16224 + %11861 = OpUGreaterThanEqual %bool %17238 %uint_4 + OpSelectionMerge %21267 DontFlatten + OpBranchConditional %11861 %20977 %21267 + %20977 = OpLabel + %11079 = OpIMul %uint %uint_80 %8858 + %23069 = OpFMul %float %11052 %float_0_5 + %8114 = OpIAdd %uint %25231 %11079 + OpSelectionMerge %21264 DontFlatten + OpBranchConditional %23279 %15206 %16570 + %16570 = OpLabel + %19163 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20298 DontFlatten + OpBranchConditional %19163 %9764 %12131 + %12131 = OpLabel + %19409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8114 + %23879 = OpLoad %uint %19409 + %11702 = OpIAdd %uint %8114 %6555 + %6477 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11702 + %24158 = OpLoad %uint %6477 + %6237 = OpIMul %uint %uint_2 %6555 + %8356 = OpIAdd %uint %8114 %6237 + %15310 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8356 + %24159 = OpLoad %uint %15310 + %6238 = OpIMul %uint %uint_3 %6555 + %8357 = OpIAdd %uint %8114 %6238 + %14322 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8357 + %16384 = OpLoad %uint %14322 + %20784 = OpCompositeConstruct %v4uint %23879 %24158 %24159 %16384 + OpBranch %20298 + %9764 = OpLabel + %21831 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8114 + %23880 = OpLoad %uint %21831 + %11703 = OpIAdd %uint %8114 %uint_1 + %6407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11703 + %23661 = OpLoad %uint %6407 + %11704 = OpIAdd %uint %8114 %uint_2 + %6408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11704 + %23662 = OpLoad %uint %6408 + %11705 = OpIAdd %uint %8114 %uint_3 + %24563 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11705 + %16385 = OpLoad %uint %24563 + %20785 = OpCompositeConstruct %v4uint %23880 %23661 %23662 %16385 + OpBranch %20298 + %20298 = OpLabel + %10944 = OpPhi %v4uint %20785 %9764 %20784 %12131 + OpSelectionMerge %16225 None + OpSwitch %8576 %19452 0 %14586 1 %14586 2 %7357 10 %7357 3 %7356 12 %7356 4 %8191 6 %8245 + %8245 = OpLabel + %24408 = OpCompositeExtract %uint %10944 0 + %24681 = OpExtInst %v2float %1 UnpackHalf2x16 %24408 + %10090 = OpCompositeExtract %float %24681 0 + %17484 = OpCompositeExtract %float %24681 1 + %14610 = OpCompositeConstruct %v4float %10090 %17484 %float_0 %float_0 + %17280 = OpCompositeExtract %uint %10944 1 + %18033 = OpExtInst %v2float %1 UnpackHalf2x16 %17280 + %10091 = OpCompositeExtract %float %18033 0 + %17485 = OpCompositeExtract %float %18033 1 + %14611 = OpCompositeConstruct %v4float %10091 %17485 %float_0 %float_0 + %17281 = OpCompositeExtract %uint %10944 2 + %18034 = OpExtInst %v2float %1 UnpackHalf2x16 %17281 + %10092 = OpCompositeExtract %float %18034 0 + %17486 = OpCompositeExtract %float %18034 1 + %14612 = OpCompositeConstruct %v4float %10092 %17486 %float_0 %float_0 + %17282 = OpCompositeExtract %uint %10944 3 + %18035 = OpExtInst %v2float %1 UnpackHalf2x16 %17282 + %10093 = OpCompositeExtract %float %18035 0 + %20672 = OpCompositeExtract %float %18035 1 + %9038 = OpCompositeConstruct %v4float %10093 %20672 %float_0 %float_0 + OpBranch %16225 + %8191 = OpLabel + %12429 = OpCompositeExtract %uint %10944 0 + %22686 = OpBitcast %int %12429 + %18206 = OpCompositeConstruct %v2int %22686 %22686 + %18353 = OpShiftLeftLogical %v2int %18206 %1959 + %13339 = OpShiftRightArithmetic %v2int %18353 %2151 + %10915 = OpConvertSToF %v2float %13339 + %18251 = OpVectorTimesScalar %v2float %10915 %float_0_000976592302 + %24074 = OpExtInst %v2float %1 FMax %73 %18251 + %24334 = OpCompositeExtract %float %24074 0 + %15575 = OpCompositeExtract %float %24074 1 + %16673 = OpCompositeConstruct %v4float %24334 %15575 %float_0 %float_0 + %19525 = OpCompositeExtract %uint %10944 1 + %16036 = OpBitcast %int %19525 + %18207 = OpCompositeConstruct %v2int %16036 %16036 + %18354 = OpShiftLeftLogical %v2int %18207 %1959 + %13340 = OpShiftRightArithmetic %v2int %18354 %2151 + %10916 = OpConvertSToF %v2float %13340 + %18252 = OpVectorTimesScalar %v2float %10916 %float_0_000976592302 + %24075 = OpExtInst %v2float %1 FMax %73 %18252 + %24335 = OpCompositeExtract %float %24075 0 + %15576 = OpCompositeExtract %float %24075 1 + %16674 = OpCompositeConstruct %v4float %24335 %15576 %float_0 %float_0 + %19526 = OpCompositeExtract %uint %10944 2 + %16037 = OpBitcast %int %19526 + %18208 = OpCompositeConstruct %v2int %16037 %16037 + %18355 = OpShiftLeftLogical %v2int %18208 %1959 + %13341 = OpShiftRightArithmetic %v2int %18355 %2151 + %10917 = OpConvertSToF %v2float %13341 + %18253 = OpVectorTimesScalar %v2float %10917 %float_0_000976592302 + %24076 = OpExtInst %v2float %1 FMax %73 %18253 + %24336 = OpCompositeExtract %float %24076 0 + %15577 = OpCompositeExtract %float %24076 1 + %16675 = OpCompositeConstruct %v4float %24336 %15577 %float_0 %float_0 + %19527 = OpCompositeExtract %uint %10944 3 + %16038 = OpBitcast %int %19527 + %18212 = OpCompositeConstruct %v2int %16038 %16038 + %18356 = OpShiftLeftLogical %v2int %18212 %1959 + %13342 = OpShiftRightArithmetic %v2int %18356 %2151 + %10918 = OpConvertSToF %v2float %13342 + %18254 = OpVectorTimesScalar %v2float %10918 %float_0_000976592302 + %24077 = OpExtInst %v2float %1 FMax %73 %18254 + %24337 = OpCompositeExtract %float %24077 0 + %18765 = OpCompositeExtract %float %24077 1 + %9039 = OpCompositeConstruct %v4float %24337 %18765 %float_0 %float_0 + OpBranch %16225 + %7356 = OpLabel + %22208 = OpCompositeExtract %uint %10944 0 + %20237 = OpCompositeConstruct %v3uint %22208 %22208 %22208 + %11026 = OpShiftRightLogical %v3uint %20237 %2996 + %24042 = OpBitwiseAnd %v3uint %11026 %261 + %18592 = OpBitwiseAnd %v3uint %24042 %1126 + %23444 = OpShiftRightLogical %v3uint %24042 %2828 + %16589 = OpIEqual %v3bool %23444 %2578 + %11343 = OpExtInst %v3int %1 FindUMsb %18592 + %10777 = OpBitcast %v3uint %11343 + %6270 = OpISub %v3uint %2828 %10777 + %8724 = OpIAdd %v3uint %10777 %2360 + %10355 = OpSelect %v3uint %16589 %8724 %23444 + %23256 = OpShiftLeftLogical %v3uint %18592 %6270 + %18846 = OpBitwiseAnd %v3uint %23256 %1126 + %10919 = OpSelect %v3uint %16589 %18846 %18592 + %24573 = OpIAdd %v3uint %10355 %1018 + %20355 = OpShiftLeftLogical %v3uint %24573 %393 + %16298 = OpShiftLeftLogical %v3uint %10919 %141 + %22400 = OpBitwiseOr %v3uint %20355 %16298 + %13828 = OpIEqual %v3bool %24042 %2578 + %16966 = OpSelect %v3uint %13828 %2578 %22400 + %10707 = OpBitcast %v3float %16966 + %19368 = OpShiftRightLogical %uint %22208 %uint_30 + %18450 = OpConvertUToF %float %19368 + %15907 = OpFMul %float %18450 %float_0_333333343 + %21446 = OpCompositeExtract %float %10707 0 + %10841 = OpCompositeExtract %float %10707 1 + %7836 = OpCompositeExtract %float %10707 2 + %15837 = OpCompositeConstruct %v4float %21446 %10841 %7836 %15907 + %10232 = OpCompositeExtract %uint %10944 1 + %13585 = OpCompositeConstruct %v3uint %10232 %10232 %10232 + %11027 = OpShiftRightLogical %v3uint %13585 %2996 + %24043 = OpBitwiseAnd %v3uint %11027 %261 + %18593 = OpBitwiseAnd %v3uint %24043 %1126 + %23445 = OpShiftRightLogical %v3uint %24043 %2828 + %16590 = OpIEqual %v3bool %23445 %2578 + %11344 = OpExtInst %v3int %1 FindUMsb %18593 + %10778 = OpBitcast %v3uint %11344 + %6271 = OpISub %v3uint %2828 %10778 + %8725 = OpIAdd %v3uint %10778 %2360 + %10356 = OpSelect %v3uint %16590 %8725 %23445 + %23257 = OpShiftLeftLogical %v3uint %18593 %6271 + %18847 = OpBitwiseAnd %v3uint %23257 %1126 + %10920 = OpSelect %v3uint %16590 %18847 %18593 + %24574 = OpIAdd %v3uint %10356 %1018 + %20356 = OpShiftLeftLogical %v3uint %24574 %393 + %16299 = OpShiftLeftLogical %v3uint %10920 %141 + %22401 = OpBitwiseOr %v3uint %20356 %16299 + %13829 = OpIEqual %v3bool %24043 %2578 + %16967 = OpSelect %v3uint %13829 %2578 %22401 + %10708 = OpBitcast %v3float %16967 + %19369 = OpShiftRightLogical %uint %10232 %uint_30 + %18451 = OpConvertUToF %float %19369 + %15908 = OpFMul %float %18451 %float_0_333333343 + %21447 = OpCompositeExtract %float %10708 0 + %10842 = OpCompositeExtract %float %10708 1 + %7837 = OpCompositeExtract %float %10708 2 + %15838 = OpCompositeConstruct %v4float %21447 %10842 %7837 %15908 + %10233 = OpCompositeExtract %uint %10944 2 + %13586 = OpCompositeConstruct %v3uint %10233 %10233 %10233 + %11028 = OpShiftRightLogical %v3uint %13586 %2996 + %24044 = OpBitwiseAnd %v3uint %11028 %261 + %18594 = OpBitwiseAnd %v3uint %24044 %1126 + %23446 = OpShiftRightLogical %v3uint %24044 %2828 + %16591 = OpIEqual %v3bool %23446 %2578 + %11345 = OpExtInst %v3int %1 FindUMsb %18594 + %10779 = OpBitcast %v3uint %11345 + %6272 = OpISub %v3uint %2828 %10779 + %8726 = OpIAdd %v3uint %10779 %2360 + %10357 = OpSelect %v3uint %16591 %8726 %23446 + %23258 = OpShiftLeftLogical %v3uint %18594 %6272 + %18848 = OpBitwiseAnd %v3uint %23258 %1126 + %10921 = OpSelect %v3uint %16591 %18848 %18594 + %24575 = OpIAdd %v3uint %10357 %1018 + %20357 = OpShiftLeftLogical %v3uint %24575 %393 + %16300 = OpShiftLeftLogical %v3uint %10921 %141 + %22402 = OpBitwiseOr %v3uint %20357 %16300 + %13830 = OpIEqual %v3bool %24044 %2578 + %16968 = OpSelect %v3uint %13830 %2578 %22402 + %10709 = OpBitcast %v3float %16968 + %19370 = OpShiftRightLogical %uint %10233 %uint_30 + %18452 = OpConvertUToF %float %19370 + %15909 = OpFMul %float %18452 %float_0_333333343 + %21448 = OpCompositeExtract %float %10709 0 + %10843 = OpCompositeExtract %float %10709 1 + %7838 = OpCompositeExtract %float %10709 2 + %15839 = OpCompositeConstruct %v4float %21448 %10843 %7838 %15909 + %10234 = OpCompositeExtract %uint %10944 3 + %13587 = OpCompositeConstruct %v3uint %10234 %10234 %10234 + %11029 = OpShiftRightLogical %v3uint %13587 %2996 + %24045 = OpBitwiseAnd %v3uint %11029 %261 + %18595 = OpBitwiseAnd %v3uint %24045 %1126 + %23447 = OpShiftRightLogical %v3uint %24045 %2828 + %16592 = OpIEqual %v3bool %23447 %2578 + %11346 = OpExtInst %v3int %1 FindUMsb %18595 + %10780 = OpBitcast %v3uint %11346 + %6273 = OpISub %v3uint %2828 %10780 + %8727 = OpIAdd %v3uint %10780 %2360 + %10358 = OpSelect %v3uint %16592 %8727 %23447 + %23259 = OpShiftLeftLogical %v3uint %18595 %6273 + %18849 = OpBitwiseAnd %v3uint %23259 %1126 + %10922 = OpSelect %v3uint %16592 %18849 %18595 + %24576 = OpIAdd %v3uint %10358 %1018 + %20358 = OpShiftLeftLogical %v3uint %24576 %393 + %16301 = OpShiftLeftLogical %v3uint %10922 %141 + %22403 = OpBitwiseOr %v3uint %20358 %16301 + %13831 = OpIEqual %v3bool %24045 %2578 + %16969 = OpSelect %v3uint %13831 %2578 %22403 + %10710 = OpBitcast %v3float %16969 + %19371 = OpShiftRightLogical %uint %10234 %uint_30 + %18453 = OpConvertUToF %float %19371 + %15910 = OpFMul %float %18453 %float_0_333333343 + %21449 = OpCompositeExtract %float %10710 0 + %10844 = OpCompositeExtract %float %10710 1 + %11030 = OpCompositeExtract %float %10710 2 + %9040 = OpCompositeConstruct %v4float %21449 %10844 %11030 %15910 + OpBranch %16225 + %7357 = OpLabel + %22209 = OpCompositeExtract %uint %10944 0 + %20238 = OpCompositeConstruct %v4uint %22209 %22209 %22209 %22209 + %9376 = OpShiftRightLogical %v4uint %20238 %845 + %18863 = OpBitwiseAnd %v4uint %9376 %635 + %15546 = OpConvertUToF %v4float %18863 + %16691 = OpFMul %v4float %15546 %2798 + %23765 = OpCompositeExtract %uint %10944 1 + %20816 = OpCompositeConstruct %v4uint %23765 %23765 %23765 %23765 + %9377 = OpShiftRightLogical %v4uint %20816 %845 + %18864 = OpBitwiseAnd %v4uint %9377 %635 + %15547 = OpConvertUToF %v4float %18864 + %16692 = OpFMul %v4float %15547 %2798 + %23766 = OpCompositeExtract %uint %10944 2 + %20817 = OpCompositeConstruct %v4uint %23766 %23766 %23766 %23766 + %9378 = OpShiftRightLogical %v4uint %20817 %845 + %18865 = OpBitwiseAnd %v4uint %9378 %635 + %15548 = OpConvertUToF %v4float %18865 + %16693 = OpFMul %v4float %15548 %2798 + %23767 = OpCompositeExtract %uint %10944 3 + %20818 = OpCompositeConstruct %v4uint %23767 %23767 %23767 %23767 + %9379 = OpShiftRightLogical %v4uint %20818 %845 + %18866 = OpBitwiseAnd %v4uint %9379 %635 + %18736 = OpConvertUToF %v4float %18866 + %9888 = OpFMul %v4float %18736 %2798 + OpBranch %16225 + %14586 = OpLabel + %22210 = OpCompositeExtract %uint %10944 0 + %20239 = OpCompositeConstruct %v4uint %22210 %22210 %22210 %22210 + %9380 = OpShiftRightLogical %v4uint %20239 %653 + %19034 = OpBitwiseAnd %v4uint %9380 %1611 + %13989 = OpConvertUToF %v4float %19034 + %19238 = OpVectorTimesScalar %v4float %13989 %float_0_00392156886 + %8610 = OpCompositeExtract %uint %10944 1 + %24846 = OpCompositeConstruct %v4uint %8610 %8610 %8610 %8610 + %9381 = OpShiftRightLogical %v4uint %24846 %653 + %19035 = OpBitwiseAnd %v4uint %9381 %1611 + %13990 = OpConvertUToF %v4float %19035 + %19239 = OpVectorTimesScalar %v4float %13990 %float_0_00392156886 + %8611 = OpCompositeExtract %uint %10944 2 + %24847 = OpCompositeConstruct %v4uint %8611 %8611 %8611 %8611 + %9382 = OpShiftRightLogical %v4uint %24847 %653 + %19036 = OpBitwiseAnd %v4uint %9382 %1611 + %13992 = OpConvertUToF %v4float %19036 + %19240 = OpVectorTimesScalar %v4float %13992 %float_0_00392156886 + %8612 = OpCompositeExtract %uint %10944 3 + %24848 = OpCompositeConstruct %v4uint %8612 %8612 %8612 %8612 + %9383 = OpShiftRightLogical %v4uint %24848 %653 + %19037 = OpBitwiseAnd %v4uint %9383 %1611 + %17179 = OpConvertUToF %v4float %19037 + %12435 = OpVectorTimesScalar %v4float %17179 %float_0_00392156886 + OpBranch %16225 + %19452 = OpLabel + %12430 = OpCompositeExtract %uint %10944 0 + %20463 = OpBitcast %float %12430 + %17209 = OpCompositeConstruct %v2float %20463 %float_0 + %11667 = OpVectorShuffle %v4float %17209 %17209 0 1 1 1 + %22196 = OpCompositeExtract %uint %10944 1 + %16235 = OpBitcast %float %22196 + %17210 = OpCompositeConstruct %v2float %16235 %float_0 + %11668 = OpVectorShuffle %v4float %17210 %17210 0 1 1 1 + %22197 = OpCompositeExtract %uint %10944 2 + %16236 = OpBitcast %float %22197 + %17211 = OpCompositeConstruct %v2float %16236 %float_0 + %11669 = OpVectorShuffle %v4float %17211 %17211 0 1 1 1 + %22198 = OpCompositeExtract %uint %10944 3 + %16237 = OpBitcast %float %22198 + %20399 = OpCompositeConstruct %v2float %16237 %float_0 + %23099 = OpVectorShuffle %v4float %20399 %20399 0 1 1 1 + OpBranch %16225 + %16225 = OpLabel + %11178 = OpPhi %v4float %23099 %19452 %12435 %14586 %9888 %7357 %9040 %7356 %9039 %8191 %9038 %8245 + %14347 = OpPhi %v4float %11669 %19452 %19240 %14586 %16693 %7357 %15839 %7356 %16675 %8191 %14612 %8245 + %15231 = OpPhi %v4float %11668 %19452 %19239 %14586 %16692 %7357 %15838 %7356 %16674 %8191 %14611 %8245 + %14520 = OpPhi %v4float %11667 %19452 %19238 %14586 %16691 %7357 %15837 %7356 %16673 %8191 %14610 %8245 + OpBranch %21264 + %15206 = OpLabel + %21585 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20261 DontFlatten + OpBranchConditional %21585 %9765 %12132 + %12132 = OpLabel + %19410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8114 + %23881 = OpLoad %uint %19410 + %11706 = OpIAdd %uint %8114 %uint_1 + %6409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11706 + %23663 = OpLoad %uint %6409 + %11707 = OpIAdd %uint %8114 %6555 + %6410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11707 + %23664 = OpLoad %uint %6410 + %11708 = OpIAdd %uint %11707 %uint_1 + %24564 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11708 + %14157 = OpLoad %uint %24564 + %19671 = OpCompositeConstruct %v4uint %23881 %23663 %23664 %14157 + %17049 = OpIMul %uint %uint_2 %6555 + %13993 = OpIAdd %uint %8114 %17049 + %15235 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13993 + %23665 = OpLoad %uint %15235 + %11709 = OpIAdd %uint %13993 %uint_1 + %6478 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11709 + %24160 = OpLoad %uint %6478 + %6239 = OpIMul %uint %uint_3 %6555 + %8358 = OpIAdd %uint %8114 %6239 + %15236 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8358 + %23666 = OpLoad %uint %15236 + %11710 = OpIAdd %uint %8358 %uint_1 + %24565 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11710 + %16386 = OpLoad %uint %24565 + %20786 = OpCompositeConstruct %v4uint %23665 %24160 %23666 %16386 + OpBranch %20261 + %9765 = OpLabel + %21832 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8114 + %23882 = OpLoad %uint %21832 + %11711 = OpIAdd %uint %8114 %uint_1 + %6411 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11711 + %23667 = OpLoad %uint %6411 + %11712 = OpIAdd %uint %8114 %uint_2 + %6412 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11712 + %23668 = OpLoad %uint %6412 + %11713 = OpIAdd %uint %8114 %uint_3 + %24566 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11713 + %14081 = OpLoad %uint %24566 + %19166 = OpCompositeConstruct %v4uint %23882 %23667 %23668 %14081 + %22502 = OpIAdd %uint %8114 %uint_4 + %24652 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22502 + %23669 = OpLoad %uint %24652 + %11714 = OpIAdd %uint %8114 %uint_5 + %6413 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11714 + %23670 = OpLoad %uint %6413 + %11715 = OpIAdd %uint %8114 %uint_6 + %6414 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11715 + %23671 = OpLoad %uint %6414 + %11716 = OpIAdd %uint %8114 %uint_7 + %24567 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11716 + %16387 = OpLoad %uint %24567 + %20787 = OpCompositeConstruct %v4uint %23669 %23670 %23671 %16387 + OpBranch %20261 + %20261 = OpLabel + %11214 = OpPhi %v4uint %20787 %9765 %20786 %12132 + %14113 = OpPhi %v4uint %19166 %9765 %19671 %12132 + OpSelectionMerge %20262 None + OpSwitch %8576 %20311 5 %8537 7 %8246 + %8246 = OpLabel + %24409 = OpCompositeExtract %uint %14113 0 + %24682 = OpExtInst %v2float %1 UnpackHalf2x16 %24409 + %10105 = OpCompositeExtract %float %24682 0 + %16060 = OpCompositeExtract %float %24682 1 + %17029 = OpCompositeExtract %uint %14113 1 + %15609 = OpExtInst %v2float %1 UnpackHalf2x16 %17029 + %10094 = OpCompositeExtract %float %15609 0 + %17487 = OpCompositeExtract %float %15609 1 + %14613 = OpCompositeConstruct %v4float %10105 %16060 %10094 %17487 + %17283 = OpCompositeExtract %uint %14113 2 + %18036 = OpExtInst %v2float %1 UnpackHalf2x16 %17283 + %10106 = OpCompositeExtract %float %18036 0 + %16061 = OpCompositeExtract %float %18036 1 + %17030 = OpCompositeExtract %uint %14113 3 + %15610 = OpExtInst %v2float %1 UnpackHalf2x16 %17030 + %10095 = OpCompositeExtract %float %15610 0 + %17488 = OpCompositeExtract %float %15610 1 + %14614 = OpCompositeConstruct %v4float %10106 %16061 %10095 %17488 + %17284 = OpCompositeExtract %uint %11214 0 + %18037 = OpExtInst %v2float %1 UnpackHalf2x16 %17284 + %10107 = OpCompositeExtract %float %18037 0 + %16062 = OpCompositeExtract %float %18037 1 + %17031 = OpCompositeExtract %uint %11214 1 + %15611 = OpExtInst %v2float %1 UnpackHalf2x16 %17031 + %10096 = OpCompositeExtract %float %15611 0 + %17489 = OpCompositeExtract %float %15611 1 + %14615 = OpCompositeConstruct %v4float %10107 %16062 %10096 %17489 + %17285 = OpCompositeExtract %uint %11214 2 + %18038 = OpExtInst %v2float %1 UnpackHalf2x16 %17285 + %10108 = OpCompositeExtract %float %18038 0 + %16063 = OpCompositeExtract %float %18038 1 + %17032 = OpCompositeExtract %uint %11214 3 + %15612 = OpExtInst %v2float %1 UnpackHalf2x16 %17032 + %10097 = OpCompositeExtract %float %15612 0 + %20673 = OpCompositeExtract %float %15612 1 + %9041 = OpCompositeConstruct %v4float %10108 %16063 %10097 %20673 + OpBranch %20262 + %8537 = OpLabel + %9724 = OpVectorShuffle %v2uint %14113 %14113 0 1 + %23357 = OpBitcast %v2int %9724 + %24786 = OpVectorShuffle %v4int %23357 %23357 0 0 1 1 + %18602 = OpShiftLeftLogical %v4int %24786 %290 + %15761 = OpShiftRightArithmetic %v4int %18602 %770 + %10923 = OpConvertSToF %v4float %15761 + %18213 = OpVectorTimesScalar %v4float %10923 %float_0_000976592302 + %25236 = OpExtInst %v4float %1 FMax %1284 %18213 + %14190 = OpVectorShuffle %v2uint %14113 %14113 2 3 + %9410 = OpBitcast %v2int %14190 + %24787 = OpVectorShuffle %v4int %9410 %9410 0 0 1 1 + %18603 = OpShiftLeftLogical %v4int %24787 %290 + %15762 = OpShiftRightArithmetic %v4int %18603 %770 + %10924 = OpConvertSToF %v4float %15762 + %18214 = OpVectorTimesScalar %v4float %10924 %float_0_000976592302 + %25237 = OpExtInst %v4float %1 FMax %1284 %18214 + %14191 = OpVectorShuffle %v2uint %11214 %11214 0 1 + %9411 = OpBitcast %v2int %14191 + %24788 = OpVectorShuffle %v4int %9411 %9411 0 0 1 1 + %18604 = OpShiftLeftLogical %v4int %24788 %290 + %15763 = OpShiftRightArithmetic %v4int %18604 %770 + %10925 = OpConvertSToF %v4float %15763 + %18215 = OpVectorTimesScalar %v4float %10925 %float_0_000976592302 + %25238 = OpExtInst %v4float %1 FMax %1284 %18215 + %14192 = OpVectorShuffle %v2uint %11214 %11214 2 3 + %9412 = OpBitcast %v2int %14192 + %24789 = OpVectorShuffle %v4int %9412 %9412 0 0 1 1 + %18605 = OpShiftLeftLogical %v4int %24789 %290 + %15764 = OpShiftRightArithmetic %v4int %18605 %770 + %10926 = OpConvertSToF %v4float %15764 + %21440 = OpVectorTimesScalar %v4float %10926 %float_0_000976592302 + %17251 = OpExtInst %v4float %1 FMax %1284 %21440 + OpBranch %20262 + %20311 = OpLabel + %9766 = OpVectorShuffle %v2uint %14113 %14113 0 1 + %20826 = OpBitcast %v2float %9766 + %7040 = OpCompositeExtract %float %20826 0 + %13421 = OpCompositeExtract %float %20826 1 + %17019 = OpCompositeConstruct %v4float %7040 %13421 %float_0 %float_0 + %16859 = OpVectorShuffle %v2uint %14113 %14113 2 3 + %14176 = OpBitcast %v2float %16859 + %7041 = OpCompositeExtract %float %14176 0 + %13422 = OpCompositeExtract %float %14176 1 + %17020 = OpCompositeConstruct %v4float %7041 %13422 %float_0 %float_0 + %16860 = OpVectorShuffle %v2uint %11214 %11214 0 1 + %14177 = OpBitcast %v2float %16860 + %7042 = OpCompositeExtract %float %14177 0 + %13423 = OpCompositeExtract %float %14177 1 + %17021 = OpCompositeConstruct %v4float %7042 %13423 %float_0 %float_0 + %16861 = OpVectorShuffle %v2uint %11214 %11214 2 3 + %14178 = OpBitcast %v2float %16861 + %7043 = OpCompositeExtract %float %14178 0 + %16649 = OpCompositeExtract %float %14178 1 + %9042 = OpCompositeConstruct %v4float %7043 %16649 %float_0 %float_0 + OpBranch %20262 + %20262 = OpLabel + %11179 = OpPhi %v4float %9042 %20311 %17251 %8537 %9041 %8246 + %14348 = OpPhi %v4float %17021 %20311 %25238 %8537 %14615 %8246 + %15232 = OpPhi %v4float %17020 %20311 %25237 %8537 %14614 %8246 + %14521 = OpPhi %v4float %17019 %20311 %25236 %8537 %14613 %8246 + OpBranch %21264 + %21264 = OpLabel + %11180 = OpPhi %v4float %11179 %20262 %11178 %16225 + %14349 = OpPhi %v4float %14348 %20262 %14347 %16225 + %12949 = OpPhi %v4float %15232 %20262 %15231 %16225 + %13946 = OpPhi %v4float %14521 %20262 %14520 %16225 + %17241 = OpFAdd %v4float %8403 %13946 + %23297 = OpFAdd %v4float %13804 %12949 + %8082 = OpFAdd %v4float %14346 %14349 + %20755 = OpFAdd %v4float %11177 %11180 + %14461 = OpUGreaterThanEqual %bool %17238 %uint_6 + OpSelectionMerge %24264 DontFlatten + OpBranchConditional %14461 %9905 %24264 + %9905 = OpLabel + %14258 = OpShiftLeftLogical %uint %uint_1 %9130 + %12090 = OpFMul %float %11052 %float_0_25 + %20988 = OpIAdd %uint %25231 %14258 + OpSelectionMerge %21265 DontFlatten + OpBranchConditional %23279 %15207 %16571 + %16571 = OpLabel + %19167 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20299 DontFlatten + OpBranchConditional %19167 %9767 %12133 + %12133 = OpLabel + %19411 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23883 = OpLoad %uint %19411 + %11717 = OpIAdd %uint %20988 %6555 + %6479 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11717 + %24161 = OpLoad %uint %6479 + %6240 = OpIMul %uint %uint_2 %6555 + %8359 = OpIAdd %uint %20988 %6240 + %15311 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8359 + %24162 = OpLoad %uint %15311 + %6241 = OpIMul %uint %uint_3 %6555 + %8360 = OpIAdd %uint %20988 %6241 + %14323 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8360 + %16388 = OpLoad %uint %14323 + %20788 = OpCompositeConstruct %v4uint %23883 %24161 %24162 %16388 + OpBranch %20299 + %9767 = OpLabel + %21833 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23884 = OpLoad %uint %21833 + %11718 = OpIAdd %uint %20988 %uint_1 + %6415 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11718 + %23672 = OpLoad %uint %6415 + %11719 = OpIAdd %uint %20988 %uint_2 + %6416 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11719 + %23673 = OpLoad %uint %6416 + %11720 = OpIAdd %uint %20988 %uint_3 + %24568 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11720 + %16389 = OpLoad %uint %24568 + %20789 = OpCompositeConstruct %v4uint %23884 %23672 %23673 %16389 + OpBranch %20299 + %20299 = OpLabel + %10945 = OpPhi %v4uint %20789 %9767 %20788 %12133 + OpSelectionMerge %16226 None + OpSwitch %8576 %19453 0 %14587 1 %14587 2 %7359 10 %7359 3 %7358 12 %7358 4 %8192 6 %8247 + %8247 = OpLabel + %24410 = OpCompositeExtract %uint %10945 0 + %24683 = OpExtInst %v2float %1 UnpackHalf2x16 %24410 + %10098 = OpCompositeExtract %float %24683 0 + %17490 = OpCompositeExtract %float %24683 1 + %14616 = OpCompositeConstruct %v4float %10098 %17490 %float_0 %float_0 + %17286 = OpCompositeExtract %uint %10945 1 + %18039 = OpExtInst %v2float %1 UnpackHalf2x16 %17286 + %10099 = OpCompositeExtract %float %18039 0 + %17491 = OpCompositeExtract %float %18039 1 + %14617 = OpCompositeConstruct %v4float %10099 %17491 %float_0 %float_0 + %17287 = OpCompositeExtract %uint %10945 2 + %18040 = OpExtInst %v2float %1 UnpackHalf2x16 %17287 + %10100 = OpCompositeExtract %float %18040 0 + %17492 = OpCompositeExtract %float %18040 1 + %14618 = OpCompositeConstruct %v4float %10100 %17492 %float_0 %float_0 + %17288 = OpCompositeExtract %uint %10945 3 + %18041 = OpExtInst %v2float %1 UnpackHalf2x16 %17288 + %10109 = OpCompositeExtract %float %18041 0 + %20674 = OpCompositeExtract %float %18041 1 + %9043 = OpCompositeConstruct %v4float %10109 %20674 %float_0 %float_0 + OpBranch %16226 + %8192 = OpLabel + %12431 = OpCompositeExtract %uint %10945 0 + %22687 = OpBitcast %int %12431 + %18216 = OpCompositeConstruct %v2int %22687 %22687 + %18357 = OpShiftLeftLogical %v2int %18216 %1959 + %13343 = OpShiftRightArithmetic %v2int %18357 %2151 + %10927 = OpConvertSToF %v2float %13343 + %18255 = OpVectorTimesScalar %v2float %10927 %float_0_000976592302 + %24078 = OpExtInst %v2float %1 FMax %73 %18255 + %24338 = OpCompositeExtract %float %24078 0 + %15578 = OpCompositeExtract %float %24078 1 + %16676 = OpCompositeConstruct %v4float %24338 %15578 %float_0 %float_0 + %19528 = OpCompositeExtract %uint %10945 1 + %16039 = OpBitcast %int %19528 + %18217 = OpCompositeConstruct %v2int %16039 %16039 + %18358 = OpShiftLeftLogical %v2int %18217 %1959 + %13344 = OpShiftRightArithmetic %v2int %18358 %2151 + %10928 = OpConvertSToF %v2float %13344 + %18256 = OpVectorTimesScalar %v2float %10928 %float_0_000976592302 + %24079 = OpExtInst %v2float %1 FMax %73 %18256 + %24339 = OpCompositeExtract %float %24079 0 + %15579 = OpCompositeExtract %float %24079 1 + %16677 = OpCompositeConstruct %v4float %24339 %15579 %float_0 %float_0 + %19529 = OpCompositeExtract %uint %10945 2 + %16040 = OpBitcast %int %19529 + %18218 = OpCompositeConstruct %v2int %16040 %16040 + %18359 = OpShiftLeftLogical %v2int %18218 %1959 + %13345 = OpShiftRightArithmetic %v2int %18359 %2151 + %10929 = OpConvertSToF %v2float %13345 + %18257 = OpVectorTimesScalar %v2float %10929 %float_0_000976592302 + %24080 = OpExtInst %v2float %1 FMax %73 %18257 + %24340 = OpCompositeExtract %float %24080 0 + %15580 = OpCompositeExtract %float %24080 1 + %16678 = OpCompositeConstruct %v4float %24340 %15580 %float_0 %float_0 + %19530 = OpCompositeExtract %uint %10945 3 + %16041 = OpBitcast %int %19530 + %18219 = OpCompositeConstruct %v2int %16041 %16041 + %18360 = OpShiftLeftLogical %v2int %18219 %1959 + %13346 = OpShiftRightArithmetic %v2int %18360 %2151 + %10930 = OpConvertSToF %v2float %13346 + %18258 = OpVectorTimesScalar %v2float %10930 %float_0_000976592302 + %24081 = OpExtInst %v2float %1 FMax %73 %18258 + %24341 = OpCompositeExtract %float %24081 0 + %18766 = OpCompositeExtract %float %24081 1 + %9044 = OpCompositeConstruct %v4float %24341 %18766 %float_0 %float_0 + OpBranch %16226 + %7358 = OpLabel + %22211 = OpCompositeExtract %uint %10945 0 + %20240 = OpCompositeConstruct %v3uint %22211 %22211 %22211 + %11031 = OpShiftRightLogical %v3uint %20240 %2996 + %24046 = OpBitwiseAnd %v3uint %11031 %261 + %18596 = OpBitwiseAnd %v3uint %24046 %1126 + %23448 = OpShiftRightLogical %v3uint %24046 %2828 + %16593 = OpIEqual %v3bool %23448 %2578 + %11347 = OpExtInst %v3int %1 FindUMsb %18596 + %10781 = OpBitcast %v3uint %11347 + %6274 = OpISub %v3uint %2828 %10781 + %8728 = OpIAdd %v3uint %10781 %2360 + %10359 = OpSelect %v3uint %16593 %8728 %23448 + %23260 = OpShiftLeftLogical %v3uint %18596 %6274 + %18850 = OpBitwiseAnd %v3uint %23260 %1126 + %10931 = OpSelect %v3uint %16593 %18850 %18596 + %24577 = OpIAdd %v3uint %10359 %1018 + %20359 = OpShiftLeftLogical %v3uint %24577 %393 + %16302 = OpShiftLeftLogical %v3uint %10931 %141 + %22404 = OpBitwiseOr %v3uint %20359 %16302 + %13832 = OpIEqual %v3bool %24046 %2578 + %16970 = OpSelect %v3uint %13832 %2578 %22404 + %10711 = OpBitcast %v3float %16970 + %19372 = OpShiftRightLogical %uint %22211 %uint_30 + %18454 = OpConvertUToF %float %19372 + %15911 = OpFMul %float %18454 %float_0_333333343 + %21450 = OpCompositeExtract %float %10711 0 + %10845 = OpCompositeExtract %float %10711 1 + %7839 = OpCompositeExtract %float %10711 2 + %15840 = OpCompositeConstruct %v4float %21450 %10845 %7839 %15911 + %10235 = OpCompositeExtract %uint %10945 1 + %13588 = OpCompositeConstruct %v3uint %10235 %10235 %10235 + %11032 = OpShiftRightLogical %v3uint %13588 %2996 + %24047 = OpBitwiseAnd %v3uint %11032 %261 + %18597 = OpBitwiseAnd %v3uint %24047 %1126 + %23449 = OpShiftRightLogical %v3uint %24047 %2828 + %16594 = OpIEqual %v3bool %23449 %2578 + %11348 = OpExtInst %v3int %1 FindUMsb %18597 + %10782 = OpBitcast %v3uint %11348 + %6275 = OpISub %v3uint %2828 %10782 + %8729 = OpIAdd %v3uint %10782 %2360 + %10360 = OpSelect %v3uint %16594 %8729 %23449 + %23261 = OpShiftLeftLogical %v3uint %18597 %6275 + %18851 = OpBitwiseAnd %v3uint %23261 %1126 + %10932 = OpSelect %v3uint %16594 %18851 %18597 + %24578 = OpIAdd %v3uint %10360 %1018 + %20360 = OpShiftLeftLogical %v3uint %24578 %393 + %16303 = OpShiftLeftLogical %v3uint %10932 %141 + %22405 = OpBitwiseOr %v3uint %20360 %16303 + %13833 = OpIEqual %v3bool %24047 %2578 + %16971 = OpSelect %v3uint %13833 %2578 %22405 + %10712 = OpBitcast %v3float %16971 + %19373 = OpShiftRightLogical %uint %10235 %uint_30 + %18455 = OpConvertUToF %float %19373 + %15912 = OpFMul %float %18455 %float_0_333333343 + %21451 = OpCompositeExtract %float %10712 0 + %10846 = OpCompositeExtract %float %10712 1 + %7840 = OpCompositeExtract %float %10712 2 + %15841 = OpCompositeConstruct %v4float %21451 %10846 %7840 %15912 + %10236 = OpCompositeExtract %uint %10945 2 + %13589 = OpCompositeConstruct %v3uint %10236 %10236 %10236 + %11033 = OpShiftRightLogical %v3uint %13589 %2996 + %24048 = OpBitwiseAnd %v3uint %11033 %261 + %18606 = OpBitwiseAnd %v3uint %24048 %1126 + %23450 = OpShiftRightLogical %v3uint %24048 %2828 + %16595 = OpIEqual %v3bool %23450 %2578 + %11349 = OpExtInst %v3int %1 FindUMsb %18606 + %10783 = OpBitcast %v3uint %11349 + %6276 = OpISub %v3uint %2828 %10783 + %8730 = OpIAdd %v3uint %10783 %2360 + %10361 = OpSelect %v3uint %16595 %8730 %23450 + %23262 = OpShiftLeftLogical %v3uint %18606 %6276 + %18852 = OpBitwiseAnd %v3uint %23262 %1126 + %10933 = OpSelect %v3uint %16595 %18852 %18606 + %24579 = OpIAdd %v3uint %10361 %1018 + %20361 = OpShiftLeftLogical %v3uint %24579 %393 + %16304 = OpShiftLeftLogical %v3uint %10933 %141 + %22406 = OpBitwiseOr %v3uint %20361 %16304 + %13834 = OpIEqual %v3bool %24048 %2578 + %16972 = OpSelect %v3uint %13834 %2578 %22406 + %10713 = OpBitcast %v3float %16972 + %19374 = OpShiftRightLogical %uint %10236 %uint_30 + %18456 = OpConvertUToF %float %19374 + %15913 = OpFMul %float %18456 %float_0_333333343 + %21452 = OpCompositeExtract %float %10713 0 + %10847 = OpCompositeExtract %float %10713 1 + %7841 = OpCompositeExtract %float %10713 2 + %15842 = OpCompositeConstruct %v4float %21452 %10847 %7841 %15913 + %10237 = OpCompositeExtract %uint %10945 3 + %13590 = OpCompositeConstruct %v3uint %10237 %10237 %10237 + %11034 = OpShiftRightLogical %v3uint %13590 %2996 + %24049 = OpBitwiseAnd %v3uint %11034 %261 + %18607 = OpBitwiseAnd %v3uint %24049 %1126 + %23451 = OpShiftRightLogical %v3uint %24049 %2828 + %16596 = OpIEqual %v3bool %23451 %2578 + %11350 = OpExtInst %v3int %1 FindUMsb %18607 + %10784 = OpBitcast %v3uint %11350 + %6277 = OpISub %v3uint %2828 %10784 + %8731 = OpIAdd %v3uint %10784 %2360 + %10362 = OpSelect %v3uint %16596 %8731 %23451 + %23263 = OpShiftLeftLogical %v3uint %18607 %6277 + %18853 = OpBitwiseAnd %v3uint %23263 %1126 + %10934 = OpSelect %v3uint %16596 %18853 %18607 + %24580 = OpIAdd %v3uint %10362 %1018 + %20362 = OpShiftLeftLogical %v3uint %24580 %393 + %16305 = OpShiftLeftLogical %v3uint %10934 %141 + %22407 = OpBitwiseOr %v3uint %20362 %16305 + %13835 = OpIEqual %v3bool %24049 %2578 + %16973 = OpSelect %v3uint %13835 %2578 %22407 + %10714 = OpBitcast %v3float %16973 + %19375 = OpShiftRightLogical %uint %10237 %uint_30 + %18457 = OpConvertUToF %float %19375 + %15914 = OpFMul %float %18457 %float_0_333333343 + %21453 = OpCompositeExtract %float %10714 0 + %10848 = OpCompositeExtract %float %10714 1 + %11035 = OpCompositeExtract %float %10714 2 + %9045 = OpCompositeConstruct %v4float %21453 %10848 %11035 %15914 + OpBranch %16226 + %7359 = OpLabel + %22212 = OpCompositeExtract %uint %10945 0 + %20241 = OpCompositeConstruct %v4uint %22212 %22212 %22212 %22212 + %9384 = OpShiftRightLogical %v4uint %20241 %845 + %18867 = OpBitwiseAnd %v4uint %9384 %635 + %15549 = OpConvertUToF %v4float %18867 + %16694 = OpFMul %v4float %15549 %2798 + %23768 = OpCompositeExtract %uint %10945 1 + %20819 = OpCompositeConstruct %v4uint %23768 %23768 %23768 %23768 + %9385 = OpShiftRightLogical %v4uint %20819 %845 + %18868 = OpBitwiseAnd %v4uint %9385 %635 + %15550 = OpConvertUToF %v4float %18868 + %16695 = OpFMul %v4float %15550 %2798 + %23769 = OpCompositeExtract %uint %10945 2 + %20820 = OpCompositeConstruct %v4uint %23769 %23769 %23769 %23769 + %9386 = OpShiftRightLogical %v4uint %20820 %845 + %18869 = OpBitwiseAnd %v4uint %9386 %635 + %15551 = OpConvertUToF %v4float %18869 + %16696 = OpFMul %v4float %15551 %2798 + %23770 = OpCompositeExtract %uint %10945 3 + %20821 = OpCompositeConstruct %v4uint %23770 %23770 %23770 %23770 + %9387 = OpShiftRightLogical %v4uint %20821 %845 + %18870 = OpBitwiseAnd %v4uint %9387 %635 + %18737 = OpConvertUToF %v4float %18870 + %9889 = OpFMul %v4float %18737 %2798 + OpBranch %16226 + %14587 = OpLabel + %22213 = OpCompositeExtract %uint %10945 0 + %20242 = OpCompositeConstruct %v4uint %22213 %22213 %22213 %22213 + %9388 = OpShiftRightLogical %v4uint %20242 %653 + %19038 = OpBitwiseAnd %v4uint %9388 %1611 + %13994 = OpConvertUToF %v4float %19038 + %19241 = OpVectorTimesScalar %v4float %13994 %float_0_00392156886 + %8613 = OpCompositeExtract %uint %10945 1 + %24849 = OpCompositeConstruct %v4uint %8613 %8613 %8613 %8613 + %9389 = OpShiftRightLogical %v4uint %24849 %653 + %19039 = OpBitwiseAnd %v4uint %9389 %1611 + %13995 = OpConvertUToF %v4float %19039 + %19242 = OpVectorTimesScalar %v4float %13995 %float_0_00392156886 + %8614 = OpCompositeExtract %uint %10945 2 + %24850 = OpCompositeConstruct %v4uint %8614 %8614 %8614 %8614 + %9390 = OpShiftRightLogical %v4uint %24850 %653 + %19040 = OpBitwiseAnd %v4uint %9390 %1611 + %13996 = OpConvertUToF %v4float %19040 + %19243 = OpVectorTimesScalar %v4float %13996 %float_0_00392156886 + %8615 = OpCompositeExtract %uint %10945 3 + %24851 = OpCompositeConstruct %v4uint %8615 %8615 %8615 %8615 + %9391 = OpShiftRightLogical %v4uint %24851 %653 + %19041 = OpBitwiseAnd %v4uint %9391 %1611 + %17180 = OpConvertUToF %v4float %19041 + %12436 = OpVectorTimesScalar %v4float %17180 %float_0_00392156886 + OpBranch %16226 + %19453 = OpLabel + %12432 = OpCompositeExtract %uint %10945 0 + %20464 = OpBitcast %float %12432 + %17212 = OpCompositeConstruct %v2float %20464 %float_0 + %11670 = OpVectorShuffle %v4float %17212 %17212 0 1 1 1 + %22199 = OpCompositeExtract %uint %10945 1 + %16238 = OpBitcast %float %22199 + %17213 = OpCompositeConstruct %v2float %16238 %float_0 + %11671 = OpVectorShuffle %v4float %17213 %17213 0 1 1 1 + %22200 = OpCompositeExtract %uint %10945 2 + %16239 = OpBitcast %float %22200 + %17214 = OpCompositeConstruct %v2float %16239 %float_0 + %11672 = OpVectorShuffle %v4float %17214 %17214 0 1 1 1 + %22201 = OpCompositeExtract %uint %10945 3 + %16240 = OpBitcast %float %22201 + %20400 = OpCompositeConstruct %v2float %16240 %float_0 + %23100 = OpVectorShuffle %v4float %20400 %20400 0 1 1 1 + OpBranch %16226 + %16226 = OpLabel + %11181 = OpPhi %v4float %23100 %19453 %12436 %14587 %9889 %7359 %9045 %7358 %9044 %8192 %9043 %8247 + %14350 = OpPhi %v4float %11672 %19453 %19243 %14587 %16696 %7359 %15842 %7358 %16678 %8192 %14618 %8247 + %15237 = OpPhi %v4float %11671 %19453 %19242 %14587 %16695 %7359 %15841 %7358 %16677 %8192 %14617 %8247 + %14522 = OpPhi %v4float %11670 %19453 %19241 %14587 %16694 %7359 %15840 %7358 %16676 %8192 %14616 %8247 + OpBranch %21265 + %15207 = OpLabel + %21586 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20263 DontFlatten + OpBranchConditional %21586 %9768 %12134 + %12134 = OpLabel + %19412 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23885 = OpLoad %uint %19412 + %11721 = OpIAdd %uint %20988 %uint_1 + %6417 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11721 + %23674 = OpLoad %uint %6417 + %11722 = OpIAdd %uint %20988 %6555 + %6418 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11722 + %23675 = OpLoad %uint %6418 + %11723 = OpIAdd %uint %11722 %uint_1 + %24581 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11723 + %14158 = OpLoad %uint %24581 + %19673 = OpCompositeConstruct %v4uint %23885 %23674 %23675 %14158 + %17050 = OpIMul %uint %uint_2 %6555 + %13997 = OpIAdd %uint %20988 %17050 + %15238 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13997 + %23676 = OpLoad %uint %15238 + %11724 = OpIAdd %uint %13997 %uint_1 + %6480 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11724 + %24163 = OpLoad %uint %6480 + %6242 = OpIMul %uint %uint_3 %6555 + %8361 = OpIAdd %uint %20988 %6242 + %15239 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8361 + %23677 = OpLoad %uint %15239 + %11725 = OpIAdd %uint %8361 %uint_1 + %24582 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11725 + %16390 = OpLoad %uint %24582 + %20790 = OpCompositeConstruct %v4uint %23676 %24163 %23677 %16390 + OpBranch %20263 + %9768 = OpLabel + %21834 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23886 = OpLoad %uint %21834 + %11726 = OpIAdd %uint %20988 %uint_1 + %6419 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11726 + %23678 = OpLoad %uint %6419 + %11727 = OpIAdd %uint %20988 %uint_2 + %6420 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11727 + %23679 = OpLoad %uint %6420 + %11728 = OpIAdd %uint %20988 %uint_3 + %24583 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11728 + %14082 = OpLoad %uint %24583 + %19168 = OpCompositeConstruct %v4uint %23886 %23678 %23679 %14082 + %22503 = OpIAdd %uint %20988 %uint_4 + %24653 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22503 + %23680 = OpLoad %uint %24653 + %11729 = OpIAdd %uint %20988 %uint_5 + %6421 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11729 + %23681 = OpLoad %uint %6421 + %11730 = OpIAdd %uint %20988 %uint_6 + %6422 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11730 + %23682 = OpLoad %uint %6422 + %11731 = OpIAdd %uint %20988 %uint_7 + %24584 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11731 + %16391 = OpLoad %uint %24584 + %20791 = OpCompositeConstruct %v4uint %23680 %23681 %23682 %16391 + OpBranch %20263 + %20263 = OpLabel + %11215 = OpPhi %v4uint %20791 %9768 %20790 %12134 + %14114 = OpPhi %v4uint %19168 %9768 %19673 %12134 + OpSelectionMerge %20264 None + OpSwitch %8576 %20312 5 %8538 7 %8248 + %8248 = OpLabel + %24411 = OpCompositeExtract %uint %14114 0 + %24684 = OpExtInst %v2float %1 UnpackHalf2x16 %24411 + %10110 = OpCompositeExtract %float %24684 0 + %16064 = OpCompositeExtract %float %24684 1 + %17033 = OpCompositeExtract %uint %14114 1 + %15613 = OpExtInst %v2float %1 UnpackHalf2x16 %17033 + %10111 = OpCompositeExtract %float %15613 0 + %17493 = OpCompositeExtract %float %15613 1 + %14619 = OpCompositeConstruct %v4float %10110 %16064 %10111 %17493 + %17289 = OpCompositeExtract %uint %14114 2 + %18042 = OpExtInst %v2float %1 UnpackHalf2x16 %17289 + %10112 = OpCompositeExtract %float %18042 0 + %16065 = OpCompositeExtract %float %18042 1 + %17034 = OpCompositeExtract %uint %14114 3 + %15614 = OpExtInst %v2float %1 UnpackHalf2x16 %17034 + %10113 = OpCompositeExtract %float %15614 0 + %17494 = OpCompositeExtract %float %15614 1 + %14620 = OpCompositeConstruct %v4float %10112 %16065 %10113 %17494 + %17290 = OpCompositeExtract %uint %11215 0 + %18043 = OpExtInst %v2float %1 UnpackHalf2x16 %17290 + %10114 = OpCompositeExtract %float %18043 0 + %16066 = OpCompositeExtract %float %18043 1 + %17035 = OpCompositeExtract %uint %11215 1 + %15615 = OpExtInst %v2float %1 UnpackHalf2x16 %17035 + %10115 = OpCompositeExtract %float %15615 0 + %17495 = OpCompositeExtract %float %15615 1 + %14621 = OpCompositeConstruct %v4float %10114 %16066 %10115 %17495 + %17291 = OpCompositeExtract %uint %11215 2 + %18044 = OpExtInst %v2float %1 UnpackHalf2x16 %17291 + %10116 = OpCompositeExtract %float %18044 0 + %16067 = OpCompositeExtract %float %18044 1 + %17036 = OpCompositeExtract %uint %11215 3 + %15616 = OpExtInst %v2float %1 UnpackHalf2x16 %17036 + %10117 = OpCompositeExtract %float %15616 0 + %20675 = OpCompositeExtract %float %15616 1 + %9046 = OpCompositeConstruct %v4float %10116 %16067 %10117 %20675 + OpBranch %20264 + %8538 = OpLabel + %9725 = OpVectorShuffle %v2uint %14114 %14114 0 1 + %23358 = OpBitcast %v2int %9725 + %24790 = OpVectorShuffle %v4int %23358 %23358 0 0 1 1 + %18608 = OpShiftLeftLogical %v4int %24790 %290 + %15765 = OpShiftRightArithmetic %v4int %18608 %770 + %10935 = OpConvertSToF %v4float %15765 + %18220 = OpVectorTimesScalar %v4float %10935 %float_0_000976592302 + %25239 = OpExtInst %v4float %1 FMax %1284 %18220 + %14193 = OpVectorShuffle %v2uint %14114 %14114 2 3 + %9413 = OpBitcast %v2int %14193 + %24791 = OpVectorShuffle %v4int %9413 %9413 0 0 1 1 + %18609 = OpShiftLeftLogical %v4int %24791 %290 + %15766 = OpShiftRightArithmetic %v4int %18609 %770 + %10936 = OpConvertSToF %v4float %15766 + %18221 = OpVectorTimesScalar %v4float %10936 %float_0_000976592302 + %25240 = OpExtInst %v4float %1 FMax %1284 %18221 + %14194 = OpVectorShuffle %v2uint %11215 %11215 0 1 + %9414 = OpBitcast %v2int %14194 + %24792 = OpVectorShuffle %v4int %9414 %9414 0 0 1 1 + %18610 = OpShiftLeftLogical %v4int %24792 %290 + %15767 = OpShiftRightArithmetic %v4int %18610 %770 + %10937 = OpConvertSToF %v4float %15767 + %18222 = OpVectorTimesScalar %v4float %10937 %float_0_000976592302 + %25241 = OpExtInst %v4float %1 FMax %1284 %18222 + %14195 = OpVectorShuffle %v2uint %11215 %11215 2 3 + %9415 = OpBitcast %v2int %14195 + %24793 = OpVectorShuffle %v4int %9415 %9415 0 0 1 1 + %18611 = OpShiftLeftLogical %v4int %24793 %290 + %15768 = OpShiftRightArithmetic %v4int %18611 %770 + %10938 = OpConvertSToF %v4float %15768 + %21441 = OpVectorTimesScalar %v4float %10938 %float_0_000976592302 + %17252 = OpExtInst %v4float %1 FMax %1284 %21441 + OpBranch %20264 + %20312 = OpLabel + %9769 = OpVectorShuffle %v2uint %14114 %14114 0 1 + %20827 = OpBitcast %v2float %9769 + %7044 = OpCompositeExtract %float %20827 0 + %13424 = OpCompositeExtract %float %20827 1 + %17022 = OpCompositeConstruct %v4float %7044 %13424 %float_0 %float_0 + %16862 = OpVectorShuffle %v2uint %14114 %14114 2 3 + %14179 = OpBitcast %v2float %16862 + %7045 = OpCompositeExtract %float %14179 0 + %13425 = OpCompositeExtract %float %14179 1 + %17023 = OpCompositeConstruct %v4float %7045 %13425 %float_0 %float_0 + %16863 = OpVectorShuffle %v2uint %11215 %11215 0 1 + %14180 = OpBitcast %v2float %16863 + %7046 = OpCompositeExtract %float %14180 0 + %13426 = OpCompositeExtract %float %14180 1 + %17024 = OpCompositeConstruct %v4float %7046 %13426 %float_0 %float_0 + %16864 = OpVectorShuffle %v2uint %11215 %11215 2 3 + %14181 = OpBitcast %v2float %16864 + %7047 = OpCompositeExtract %float %14181 0 + %16650 = OpCompositeExtract %float %14181 1 + %9047 = OpCompositeConstruct %v4float %7047 %16650 %float_0 %float_0 + OpBranch %20264 + %20264 = OpLabel + %11182 = OpPhi %v4float %9047 %20312 %17252 %8538 %9046 %8248 + %14351 = OpPhi %v4float %17024 %20312 %25241 %8538 %14621 %8248 + %15240 = OpPhi %v4float %17023 %20312 %25240 %8538 %14620 %8248 + %14523 = OpPhi %v4float %17022 %20312 %25239 %8538 %14619 %8248 + OpBranch %21265 + %21265 = OpLabel + %11183 = OpPhi %v4float %11182 %20264 %11181 %16226 + %14352 = OpPhi %v4float %14351 %20264 %14350 %16226 + %12950 = OpPhi %v4float %15240 %20264 %15237 %16226 + %13947 = OpPhi %v4float %14523 %20264 %14522 %16226 + %17242 = OpFAdd %v4float %17241 %13947 + %23298 = OpFAdd %v4float %23297 %12950 + %7208 = OpFAdd %v4float %8082 %14352 + %9642 = OpFAdd %v4float %20755 %11183 + %16376 = OpIAdd %uint %8114 %14258 + OpSelectionMerge %21266 DontFlatten + OpBranchConditional %23279 %15208 %16572 + %16572 = OpLabel + %19169 = OpIEqual %bool %6555 %uint_1 + OpSelectionMerge %20300 DontFlatten + OpBranchConditional %19169 %9770 %12135 + %12135 = OpLabel + %19413 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23887 = OpLoad %uint %19413 + %11732 = OpIAdd %uint %16376 %6555 + %6481 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11732 + %24164 = OpLoad %uint %6481 + %6243 = OpIMul %uint %uint_2 %6555 + %8362 = OpIAdd %uint %16376 %6243 + %15312 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8362 + %24165 = OpLoad %uint %15312 + %6244 = OpIMul %uint %uint_3 %6555 + %8363 = OpIAdd %uint %16376 %6244 + %14324 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8363 + %16392 = OpLoad %uint %14324 + %20792 = OpCompositeConstruct %v4uint %23887 %24164 %24165 %16392 + OpBranch %20300 + %9770 = OpLabel + %21835 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23888 = OpLoad %uint %21835 + %11733 = OpIAdd %uint %16376 %uint_1 + %6423 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11733 + %23683 = OpLoad %uint %6423 + %11734 = OpIAdd %uint %16376 %uint_2 + %6424 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11734 + %23684 = OpLoad %uint %6424 + %11735 = OpIAdd %uint %16376 %uint_3 + %24585 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11735 + %16393 = OpLoad %uint %24585 + %20793 = OpCompositeConstruct %v4uint %23888 %23683 %23684 %16393 + OpBranch %20300 + %20300 = OpLabel + %10946 = OpPhi %v4uint %20793 %9770 %20792 %12135 + OpSelectionMerge %16227 None + OpSwitch %8576 %19454 0 %14588 1 %14588 2 %7361 10 %7361 3 %7360 12 %7360 4 %8193 6 %8249 + %8249 = OpLabel + %24412 = OpCompositeExtract %uint %10946 0 + %24685 = OpExtInst %v2float %1 UnpackHalf2x16 %24412 + %10118 = OpCompositeExtract %float %24685 0 + %17496 = OpCompositeExtract %float %24685 1 + %14622 = OpCompositeConstruct %v4float %10118 %17496 %float_0 %float_0 + %17292 = OpCompositeExtract %uint %10946 1 + %18045 = OpExtInst %v2float %1 UnpackHalf2x16 %17292 + %10119 = OpCompositeExtract %float %18045 0 + %17497 = OpCompositeExtract %float %18045 1 + %14623 = OpCompositeConstruct %v4float %10119 %17497 %float_0 %float_0 + %17293 = OpCompositeExtract %uint %10946 2 + %18046 = OpExtInst %v2float %1 UnpackHalf2x16 %17293 + %10120 = OpCompositeExtract %float %18046 0 + %17498 = OpCompositeExtract %float %18046 1 + %14624 = OpCompositeConstruct %v4float %10120 %17498 %float_0 %float_0 + %17294 = OpCompositeExtract %uint %10946 3 + %18047 = OpExtInst %v2float %1 UnpackHalf2x16 %17294 + %10121 = OpCompositeExtract %float %18047 0 + %20676 = OpCompositeExtract %float %18047 1 + %9048 = OpCompositeConstruct %v4float %10121 %20676 %float_0 %float_0 + OpBranch %16227 + %8193 = OpLabel + %12433 = OpCompositeExtract %uint %10946 0 + %22688 = OpBitcast %int %12433 + %18223 = OpCompositeConstruct %v2int %22688 %22688 + %18361 = OpShiftLeftLogical %v2int %18223 %1959 + %13347 = OpShiftRightArithmetic %v2int %18361 %2151 + %10939 = OpConvertSToF %v2float %13347 + %18259 = OpVectorTimesScalar %v2float %10939 %float_0_000976592302 + %24082 = OpExtInst %v2float %1 FMax %73 %18259 + %24342 = OpCompositeExtract %float %24082 0 + %15581 = OpCompositeExtract %float %24082 1 + %16679 = OpCompositeConstruct %v4float %24342 %15581 %float_0 %float_0 + %19531 = OpCompositeExtract %uint %10946 1 + %16042 = OpBitcast %int %19531 + %18224 = OpCompositeConstruct %v2int %16042 %16042 + %18362 = OpShiftLeftLogical %v2int %18224 %1959 + %13348 = OpShiftRightArithmetic %v2int %18362 %2151 + %10940 = OpConvertSToF %v2float %13348 + %18260 = OpVectorTimesScalar %v2float %10940 %float_0_000976592302 + %24083 = OpExtInst %v2float %1 FMax %73 %18260 + %24343 = OpCompositeExtract %float %24083 0 + %15582 = OpCompositeExtract %float %24083 1 + %16680 = OpCompositeConstruct %v4float %24343 %15582 %float_0 %float_0 + %19532 = OpCompositeExtract %uint %10946 2 + %16043 = OpBitcast %int %19532 + %18225 = OpCompositeConstruct %v2int %16043 %16043 + %18364 = OpShiftLeftLogical %v2int %18225 %1959 + %13349 = OpShiftRightArithmetic %v2int %18364 %2151 + %10941 = OpConvertSToF %v2float %13349 + %18261 = OpVectorTimesScalar %v2float %10941 %float_0_000976592302 + %24084 = OpExtInst %v2float %1 FMax %73 %18261 + %24344 = OpCompositeExtract %float %24084 0 + %15583 = OpCompositeExtract %float %24084 1 + %16681 = OpCompositeConstruct %v4float %24344 %15583 %float_0 %float_0 + %19533 = OpCompositeExtract %uint %10946 3 + %16044 = OpBitcast %int %19533 + %18226 = OpCompositeConstruct %v2int %16044 %16044 + %18365 = OpShiftLeftLogical %v2int %18226 %1959 + %13350 = OpShiftRightArithmetic %v2int %18365 %2151 + %10942 = OpConvertSToF %v2float %13350 + %18262 = OpVectorTimesScalar %v2float %10942 %float_0_000976592302 + %24085 = OpExtInst %v2float %1 FMax %73 %18262 + %24345 = OpCompositeExtract %float %24085 0 + %18767 = OpCompositeExtract %float %24085 1 + %9049 = OpCompositeConstruct %v4float %24345 %18767 %float_0 %float_0 + OpBranch %16227 + %7360 = OpLabel + %22214 = OpCompositeExtract %uint %10946 0 + %20243 = OpCompositeConstruct %v3uint %22214 %22214 %22214 + %11036 = OpShiftRightLogical %v3uint %20243 %2996 + %24050 = OpBitwiseAnd %v3uint %11036 %261 + %18612 = OpBitwiseAnd %v3uint %24050 %1126 + %23452 = OpShiftRightLogical %v3uint %24050 %2828 + %16597 = OpIEqual %v3bool %23452 %2578 + %11351 = OpExtInst %v3int %1 FindUMsb %18612 + %10785 = OpBitcast %v3uint %11351 + %6278 = OpISub %v3uint %2828 %10785 + %8732 = OpIAdd %v3uint %10785 %2360 + %10363 = OpSelect %v3uint %16597 %8732 %23452 + %23264 = OpShiftLeftLogical %v3uint %18612 %6278 + %18854 = OpBitwiseAnd %v3uint %23264 %1126 + %10947 = OpSelect %v3uint %16597 %18854 %18612 + %24586 = OpIAdd %v3uint %10363 %1018 + %20363 = OpShiftLeftLogical %v3uint %24586 %393 + %16306 = OpShiftLeftLogical %v3uint %10947 %141 + %22408 = OpBitwiseOr %v3uint %20363 %16306 + %13836 = OpIEqual %v3bool %24050 %2578 + %16974 = OpSelect %v3uint %13836 %2578 %22408 + %10715 = OpBitcast %v3float %16974 + %19376 = OpShiftRightLogical %uint %22214 %uint_30 + %18458 = OpConvertUToF %float %19376 + %15915 = OpFMul %float %18458 %float_0_333333343 + %21454 = OpCompositeExtract %float %10715 0 + %10849 = OpCompositeExtract %float %10715 1 + %7842 = OpCompositeExtract %float %10715 2 + %15843 = OpCompositeConstruct %v4float %21454 %10849 %7842 %15915 + %10238 = OpCompositeExtract %uint %10946 1 + %13591 = OpCompositeConstruct %v3uint %10238 %10238 %10238 + %11037 = OpShiftRightLogical %v3uint %13591 %2996 + %24051 = OpBitwiseAnd %v3uint %11037 %261 + %18613 = OpBitwiseAnd %v3uint %24051 %1126 + %23453 = OpShiftRightLogical %v3uint %24051 %2828 + %16598 = OpIEqual %v3bool %23453 %2578 + %11352 = OpExtInst %v3int %1 FindUMsb %18613 + %10786 = OpBitcast %v3uint %11352 + %6279 = OpISub %v3uint %2828 %10786 + %8733 = OpIAdd %v3uint %10786 %2360 + %10364 = OpSelect %v3uint %16598 %8733 %23453 + %23265 = OpShiftLeftLogical %v3uint %18613 %6279 + %18855 = OpBitwiseAnd %v3uint %23265 %1126 + %10948 = OpSelect %v3uint %16598 %18855 %18613 + %24587 = OpIAdd %v3uint %10364 %1018 + %20364 = OpShiftLeftLogical %v3uint %24587 %393 + %16307 = OpShiftLeftLogical %v3uint %10948 %141 + %22409 = OpBitwiseOr %v3uint %20364 %16307 + %13837 = OpIEqual %v3bool %24051 %2578 + %16975 = OpSelect %v3uint %13837 %2578 %22409 + %10716 = OpBitcast %v3float %16975 + %19377 = OpShiftRightLogical %uint %10238 %uint_30 + %18459 = OpConvertUToF %float %19377 + %15916 = OpFMul %float %18459 %float_0_333333343 + %21455 = OpCompositeExtract %float %10716 0 + %10850 = OpCompositeExtract %float %10716 1 + %7843 = OpCompositeExtract %float %10716 2 + %15844 = OpCompositeConstruct %v4float %21455 %10850 %7843 %15916 + %10239 = OpCompositeExtract %uint %10946 2 + %13592 = OpCompositeConstruct %v3uint %10239 %10239 %10239 + %11038 = OpShiftRightLogical %v3uint %13592 %2996 + %24052 = OpBitwiseAnd %v3uint %11038 %261 + %18614 = OpBitwiseAnd %v3uint %24052 %1126 + %23454 = OpShiftRightLogical %v3uint %24052 %2828 + %16599 = OpIEqual %v3bool %23454 %2578 + %11353 = OpExtInst %v3int %1 FindUMsb %18614 + %10787 = OpBitcast %v3uint %11353 + %6280 = OpISub %v3uint %2828 %10787 + %8734 = OpIAdd %v3uint %10787 %2360 + %10365 = OpSelect %v3uint %16599 %8734 %23454 + %23266 = OpShiftLeftLogical %v3uint %18614 %6280 + %18856 = OpBitwiseAnd %v3uint %23266 %1126 + %10949 = OpSelect %v3uint %16599 %18856 %18614 + %24588 = OpIAdd %v3uint %10365 %1018 + %20365 = OpShiftLeftLogical %v3uint %24588 %393 + %16308 = OpShiftLeftLogical %v3uint %10949 %141 + %22410 = OpBitwiseOr %v3uint %20365 %16308 + %13838 = OpIEqual %v3bool %24052 %2578 + %16976 = OpSelect %v3uint %13838 %2578 %22410 + %10717 = OpBitcast %v3float %16976 + %19378 = OpShiftRightLogical %uint %10239 %uint_30 + %18460 = OpConvertUToF %float %19378 + %15917 = OpFMul %float %18460 %float_0_333333343 + %21456 = OpCompositeExtract %float %10717 0 + %10851 = OpCompositeExtract %float %10717 1 + %7844 = OpCompositeExtract %float %10717 2 + %15845 = OpCompositeConstruct %v4float %21456 %10851 %7844 %15917 + %10240 = OpCompositeExtract %uint %10946 3 + %13593 = OpCompositeConstruct %v3uint %10240 %10240 %10240 + %11039 = OpShiftRightLogical %v3uint %13593 %2996 + %24053 = OpBitwiseAnd %v3uint %11039 %261 + %18616 = OpBitwiseAnd %v3uint %24053 %1126 + %23455 = OpShiftRightLogical %v3uint %24053 %2828 + %16600 = OpIEqual %v3bool %23455 %2578 + %11354 = OpExtInst %v3int %1 FindUMsb %18616 + %10788 = OpBitcast %v3uint %11354 + %6281 = OpISub %v3uint %2828 %10788 + %8735 = OpIAdd %v3uint %10788 %2360 + %10366 = OpSelect %v3uint %16600 %8735 %23455 + %23267 = OpShiftLeftLogical %v3uint %18616 %6281 + %18857 = OpBitwiseAnd %v3uint %23267 %1126 + %10950 = OpSelect %v3uint %16600 %18857 %18616 + %24589 = OpIAdd %v3uint %10366 %1018 + %20366 = OpShiftLeftLogical %v3uint %24589 %393 + %16309 = OpShiftLeftLogical %v3uint %10950 %141 + %22411 = OpBitwiseOr %v3uint %20366 %16309 + %13839 = OpIEqual %v3bool %24053 %2578 + %16977 = OpSelect %v3uint %13839 %2578 %22411 + %10718 = OpBitcast %v3float %16977 + %19379 = OpShiftRightLogical %uint %10240 %uint_30 + %18461 = OpConvertUToF %float %19379 + %15918 = OpFMul %float %18461 %float_0_333333343 + %21457 = OpCompositeExtract %float %10718 0 + %10852 = OpCompositeExtract %float %10718 1 + %11040 = OpCompositeExtract %float %10718 2 + %9050 = OpCompositeConstruct %v4float %21457 %10852 %11040 %15918 + OpBranch %16227 + %7361 = OpLabel + %22215 = OpCompositeExtract %uint %10946 0 + %20244 = OpCompositeConstruct %v4uint %22215 %22215 %22215 %22215 + %9392 = OpShiftRightLogical %v4uint %20244 %845 + %18871 = OpBitwiseAnd %v4uint %9392 %635 + %15552 = OpConvertUToF %v4float %18871 + %16697 = OpFMul %v4float %15552 %2798 + %23771 = OpCompositeExtract %uint %10946 1 + %20822 = OpCompositeConstruct %v4uint %23771 %23771 %23771 %23771 + %9393 = OpShiftRightLogical %v4uint %20822 %845 + %18872 = OpBitwiseAnd %v4uint %9393 %635 + %15553 = OpConvertUToF %v4float %18872 + %16698 = OpFMul %v4float %15553 %2798 + %23772 = OpCompositeExtract %uint %10946 2 + %20823 = OpCompositeConstruct %v4uint %23772 %23772 %23772 %23772 + %9394 = OpShiftRightLogical %v4uint %20823 %845 + %18873 = OpBitwiseAnd %v4uint %9394 %635 + %15554 = OpConvertUToF %v4float %18873 + %16699 = OpFMul %v4float %15554 %2798 + %23773 = OpCompositeExtract %uint %10946 3 + %20828 = OpCompositeConstruct %v4uint %23773 %23773 %23773 %23773 + %9395 = OpShiftRightLogical %v4uint %20828 %845 + %18874 = OpBitwiseAnd %v4uint %9395 %635 + %18738 = OpConvertUToF %v4float %18874 + %9890 = OpFMul %v4float %18738 %2798 + OpBranch %16227 + %14588 = OpLabel + %22216 = OpCompositeExtract %uint %10946 0 + %20245 = OpCompositeConstruct %v4uint %22216 %22216 %22216 %22216 + %9396 = OpShiftRightLogical %v4uint %20245 %653 + %19042 = OpBitwiseAnd %v4uint %9396 %1611 + %13998 = OpConvertUToF %v4float %19042 + %19244 = OpVectorTimesScalar %v4float %13998 %float_0_00392156886 + %8616 = OpCompositeExtract %uint %10946 1 + %24852 = OpCompositeConstruct %v4uint %8616 %8616 %8616 %8616 + %9397 = OpShiftRightLogical %v4uint %24852 %653 + %19043 = OpBitwiseAnd %v4uint %9397 %1611 + %13999 = OpConvertUToF %v4float %19043 + %19245 = OpVectorTimesScalar %v4float %13999 %float_0_00392156886 + %8617 = OpCompositeExtract %uint %10946 2 + %24853 = OpCompositeConstruct %v4uint %8617 %8617 %8617 %8617 + %9398 = OpShiftRightLogical %v4uint %24853 %653 + %19044 = OpBitwiseAnd %v4uint %9398 %1611 + %14000 = OpConvertUToF %v4float %19044 + %19246 = OpVectorTimesScalar %v4float %14000 %float_0_00392156886 + %8618 = OpCompositeExtract %uint %10946 3 + %24854 = OpCompositeConstruct %v4uint %8618 %8618 %8618 %8618 + %9399 = OpShiftRightLogical %v4uint %24854 %653 + %19045 = OpBitwiseAnd %v4uint %9399 %1611 + %17181 = OpConvertUToF %v4float %19045 + %12437 = OpVectorTimesScalar %v4float %17181 %float_0_00392156886 + OpBranch %16227 + %19454 = OpLabel + %12438 = OpCompositeExtract %uint %10946 0 + %20465 = OpBitcast %float %12438 + %17215 = OpCompositeConstruct %v2float %20465 %float_0 + %11673 = OpVectorShuffle %v4float %17215 %17215 0 1 1 1 + %22202 = OpCompositeExtract %uint %10946 1 + %16241 = OpBitcast %float %22202 + %17216 = OpCompositeConstruct %v2float %16241 %float_0 + %11674 = OpVectorShuffle %v4float %17216 %17216 0 1 1 1 + %22203 = OpCompositeExtract %uint %10946 2 + %16242 = OpBitcast %float %22203 + %17217 = OpCompositeConstruct %v2float %16242 %float_0 + %11675 = OpVectorShuffle %v4float %17217 %17217 0 1 1 1 + %22204 = OpCompositeExtract %uint %10946 3 + %16243 = OpBitcast %float %22204 + %20401 = OpCompositeConstruct %v2float %16243 %float_0 + %23101 = OpVectorShuffle %v4float %20401 %20401 0 1 1 1 + OpBranch %16227 + %16227 = OpLabel + %11184 = OpPhi %v4float %23101 %19454 %12437 %14588 %9890 %7361 %9050 %7360 %9049 %8193 %9048 %8249 + %14353 = OpPhi %v4float %11675 %19454 %19246 %14588 %16699 %7361 %15845 %7360 %16681 %8193 %14624 %8249 + %15241 = OpPhi %v4float %11674 %19454 %19245 %14588 %16698 %7361 %15844 %7360 %16680 %8193 %14623 %8249 + %14524 = OpPhi %v4float %11673 %19454 %19244 %14588 %16697 %7361 %15843 %7360 %16679 %8193 %14622 %8249 + OpBranch %21266 + %15208 = OpLabel + %21587 = OpIEqual %bool %6555 %uint_2 + OpSelectionMerge %20265 DontFlatten + OpBranchConditional %21587 %9771 %12136 + %12136 = OpLabel + %19414 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23889 = OpLoad %uint %19414 + %11736 = OpIAdd %uint %16376 %uint_1 + %6425 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11736 + %23685 = OpLoad %uint %6425 + %11737 = OpIAdd %uint %16376 %6555 + %6426 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11737 + %23686 = OpLoad %uint %6426 + %11738 = OpIAdd %uint %11737 %uint_1 + %24590 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11738 + %14159 = OpLoad %uint %24590 + %19674 = OpCompositeConstruct %v4uint %23889 %23685 %23686 %14159 + %17051 = OpIMul %uint %uint_2 %6555 + %14001 = OpIAdd %uint %16376 %17051 + %15242 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %14001 + %23687 = OpLoad %uint %15242 + %11739 = OpIAdd %uint %14001 %uint_1 + %6482 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11739 + %24166 = OpLoad %uint %6482 + %6245 = OpIMul %uint %uint_3 %6555 + %8364 = OpIAdd %uint %16376 %6245 + %15243 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8364 + %23688 = OpLoad %uint %15243 + %11740 = OpIAdd %uint %8364 %uint_1 + %24591 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11740 + %16394 = OpLoad %uint %24591 + %20794 = OpCompositeConstruct %v4uint %23687 %24166 %23688 %16394 + OpBranch %20265 + %9771 = OpLabel + %21836 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23890 = OpLoad %uint %21836 + %11741 = OpIAdd %uint %16376 %uint_1 + %6427 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11741 + %23689 = OpLoad %uint %6427 + %11742 = OpIAdd %uint %16376 %uint_2 + %6428 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11742 + %23690 = OpLoad %uint %6428 + %11743 = OpIAdd %uint %16376 %uint_3 + %24592 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11743 + %14083 = OpLoad %uint %24592 + %19170 = OpCompositeConstruct %v4uint %23890 %23689 %23690 %14083 + %22504 = OpIAdd %uint %16376 %uint_4 + %24654 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22504 + %23691 = OpLoad %uint %24654 + %11744 = OpIAdd %uint %16376 %uint_5 + %6429 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11744 + %23692 = OpLoad %uint %6429 + %11745 = OpIAdd %uint %16376 %uint_6 + %6430 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11745 + %23693 = OpLoad %uint %6430 + %11746 = OpIAdd %uint %16376 %uint_7 + %24593 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11746 + %16395 = OpLoad %uint %24593 + %20795 = OpCompositeConstruct %v4uint %23691 %23692 %23693 %16395 + OpBranch %20265 + %20265 = OpLabel + %11216 = OpPhi %v4uint %20795 %9771 %20794 %12136 + %14115 = OpPhi %v4uint %19170 %9771 %19674 %12136 + OpSelectionMerge %20266 None + OpSwitch %8576 %20313 5 %8539 7 %8250 + %8250 = OpLabel + %24413 = OpCompositeExtract %uint %14115 0 + %24686 = OpExtInst %v2float %1 UnpackHalf2x16 %24413 + %10122 = OpCompositeExtract %float %24686 0 + %16068 = OpCompositeExtract %float %24686 1 + %17037 = OpCompositeExtract %uint %14115 1 + %15617 = OpExtInst %v2float %1 UnpackHalf2x16 %17037 + %10123 = OpCompositeExtract %float %15617 0 + %17499 = OpCompositeExtract %float %15617 1 + %14625 = OpCompositeConstruct %v4float %10122 %16068 %10123 %17499 + %17295 = OpCompositeExtract %uint %14115 2 + %18048 = OpExtInst %v2float %1 UnpackHalf2x16 %17295 + %10124 = OpCompositeExtract %float %18048 0 + %16069 = OpCompositeExtract %float %18048 1 + %17038 = OpCompositeExtract %uint %14115 3 + %15618 = OpExtInst %v2float %1 UnpackHalf2x16 %17038 + %10125 = OpCompositeExtract %float %15618 0 + %17500 = OpCompositeExtract %float %15618 1 + %14626 = OpCompositeConstruct %v4float %10124 %16069 %10125 %17500 + %17296 = OpCompositeExtract %uint %11216 0 + %18049 = OpExtInst %v2float %1 UnpackHalf2x16 %17296 + %10126 = OpCompositeExtract %float %18049 0 + %16070 = OpCompositeExtract %float %18049 1 + %17039 = OpCompositeExtract %uint %11216 1 + %15619 = OpExtInst %v2float %1 UnpackHalf2x16 %17039 + %10127 = OpCompositeExtract %float %15619 0 + %17501 = OpCompositeExtract %float %15619 1 + %14627 = OpCompositeConstruct %v4float %10126 %16070 %10127 %17501 + %17297 = OpCompositeExtract %uint %11216 2 + %18050 = OpExtInst %v2float %1 UnpackHalf2x16 %17297 + %10128 = OpCompositeExtract %float %18050 0 + %16071 = OpCompositeExtract %float %18050 1 + %17040 = OpCompositeExtract %uint %11216 3 + %15620 = OpExtInst %v2float %1 UnpackHalf2x16 %17040 + %10129 = OpCompositeExtract %float %15620 0 + %20677 = OpCompositeExtract %float %15620 1 + %9051 = OpCompositeConstruct %v4float %10128 %16071 %10129 %20677 + OpBranch %20266 + %8539 = OpLabel + %9726 = OpVectorShuffle %v2uint %14115 %14115 0 1 + %23359 = OpBitcast %v2int %9726 + %24794 = OpVectorShuffle %v4int %23359 %23359 0 0 1 1 + %18617 = OpShiftLeftLogical %v4int %24794 %290 + %15769 = OpShiftRightArithmetic %v4int %18617 %770 + %10951 = OpConvertSToF %v4float %15769 + %18227 = OpVectorTimesScalar %v4float %10951 %float_0_000976592302 + %25242 = OpExtInst %v4float %1 FMax %1284 %18227 + %14196 = OpVectorShuffle %v2uint %14115 %14115 2 3 + %9416 = OpBitcast %v2int %14196 + %24795 = OpVectorShuffle %v4int %9416 %9416 0 0 1 1 + %18618 = OpShiftLeftLogical %v4int %24795 %290 + %15770 = OpShiftRightArithmetic %v4int %18618 %770 + %10952 = OpConvertSToF %v4float %15770 + %18228 = OpVectorTimesScalar %v4float %10952 %float_0_000976592302 + %25243 = OpExtInst %v4float %1 FMax %1284 %18228 + %14197 = OpVectorShuffle %v2uint %11216 %11216 0 1 + %9417 = OpBitcast %v2int %14197 + %24796 = OpVectorShuffle %v4int %9417 %9417 0 0 1 1 + %18619 = OpShiftLeftLogical %v4int %24796 %290 + %15771 = OpShiftRightArithmetic %v4int %18619 %770 + %10953 = OpConvertSToF %v4float %15771 + %18229 = OpVectorTimesScalar %v4float %10953 %float_0_000976592302 + %25244 = OpExtInst %v4float %1 FMax %1284 %18229 + %14198 = OpVectorShuffle %v2uint %11216 %11216 2 3 + %9418 = OpBitcast %v2int %14198 + %24797 = OpVectorShuffle %v4int %9418 %9418 0 0 1 1 + %18620 = OpShiftLeftLogical %v4int %24797 %290 + %15772 = OpShiftRightArithmetic %v4int %18620 %770 + %10954 = OpConvertSToF %v4float %15772 + %21458 = OpVectorTimesScalar %v4float %10954 %float_0_000976592302 + %17253 = OpExtInst %v4float %1 FMax %1284 %21458 + OpBranch %20266 + %20313 = OpLabel + %9772 = OpVectorShuffle %v2uint %14115 %14115 0 1 + %20829 = OpBitcast %v2float %9772 + %7048 = OpCompositeExtract %float %20829 0 + %13427 = OpCompositeExtract %float %20829 1 + %17041 = OpCompositeConstruct %v4float %7048 %13427 %float_0 %float_0 + %16865 = OpVectorShuffle %v2uint %14115 %14115 2 3 + %14182 = OpBitcast %v2float %16865 + %7049 = OpCompositeExtract %float %14182 0 + %13428 = OpCompositeExtract %float %14182 1 + %17042 = OpCompositeConstruct %v4float %7049 %13428 %float_0 %float_0 + %16866 = OpVectorShuffle %v2uint %11216 %11216 0 1 + %14183 = OpBitcast %v2float %16866 + %7050 = OpCompositeExtract %float %14183 0 + %13429 = OpCompositeExtract %float %14183 1 + %17043 = OpCompositeConstruct %v4float %7050 %13429 %float_0 %float_0 + %16867 = OpVectorShuffle %v2uint %11216 %11216 2 3 + %14184 = OpBitcast %v2float %16867 + %7051 = OpCompositeExtract %float %14184 0 + %16651 = OpCompositeExtract %float %14184 1 + %9052 = OpCompositeConstruct %v4float %7051 %16651 %float_0 %float_0 + OpBranch %20266 + %20266 = OpLabel + %11185 = OpPhi %v4float %9052 %20313 %17253 %8539 %9051 %8250 + %14354 = OpPhi %v4float %17043 %20313 %25244 %8539 %14627 %8250 + %15244 = OpPhi %v4float %17042 %20313 %25243 %8539 %14626 %8250 + %14525 = OpPhi %v4float %17041 %20313 %25242 %8539 %14625 %8250 + OpBranch %21266 + %21266 = OpLabel + %11186 = OpPhi %v4float %11185 %20266 %11184 %16227 + %14355 = OpPhi %v4float %14354 %20266 %14353 %16227 + %12951 = OpPhi %v4float %15244 %20266 %15241 %16227 + %13948 = OpPhi %v4float %14525 %20266 %14524 %16227 + %17243 = OpFAdd %v4float %17242 %13948 + %23299 = OpFAdd %v4float %23298 %12951 + %9507 = OpFAdd %v4float %7208 %14355 + %7799 = OpFAdd %v4float %9642 %11186 + OpBranch %24264 + %24264 = OpLabel + %11187 = OpPhi %v4float %20755 %21264 %7799 %21266 + %14356 = OpPhi %v4float %8082 %21264 %9507 %21266 + %15153 = OpPhi %v4float %23297 %21264 %23299 %21266 + %15245 = OpPhi %v4float %17241 %21264 %17243 %21266 + %14526 = OpPhi %float %23069 %21264 %12090 %21266 + OpBranch %21267 + %21267 = OpLabel + %11188 = OpPhi %v4float %11177 %21263 %11187 %24264 + %14357 = OpPhi %v4float %14346 %21263 %14356 %24264 + %15154 = OpPhi %v4float %13804 %21263 %15153 %24264 + %13196 = OpPhi %v4float %8403 %21263 %15245 %24264 + %11944 = OpPhi %float %11052 %21263 %14526 %24264 + %23156 = OpVectorTimesScalar %v4float %13196 %11944 + %6604 = OpVectorTimesScalar %v4float %15154 %11944 + %12399 = OpVectorTimesScalar %v4float %14357 %11944 + %13362 = OpVectorTimesScalar %v4float %11188 %11944 + OpSelectionMerge %16228 DontFlatten + OpBranchConditional %7513 %10049 %16228 + %10049 = OpLabel + %15086 = OpVectorShuffle %v4float %23156 %23156 2 1 0 3 + %14855 = OpVectorShuffle %v4float %6604 %6604 2 1 0 3 + %7398 = OpVectorShuffle %v4float %12399 %12399 2 1 0 3 + %16111 = OpVectorShuffle %v4float %13362 %13362 2 1 0 3 + OpBranch %16228 + %16228 = OpLabel + %11189 = OpPhi %v4float %13362 %21267 %16111 %10049 + %14358 = OpPhi %v4float %12399 %21267 %7398 %10049 + %15191 = OpPhi %v4float %6604 %21267 %14855 %10049 + %14921 = OpPhi %v4float %23156 %21267 %15086 %10049 + OpSelectionMerge %23460 None + OpSwitch %20627 %7373 26 %18070 32 %9492 + %9492 = OpLabel + %15022 = OpCompositeExtract %float %14921 0 + %9197 = OpCompositeExtract %float %14921 1 + %19232 = OpCompositeConstruct %v2float %15022 %9197 + %8561 = OpExtInst %uint %1 PackHalf2x16 %19232 + %23487 = OpCompositeExtract %float %14921 2 + %14759 = OpCompositeExtract %float %14921 3 + %19233 = OpCompositeConstruct %v2float %23487 %14759 + %8562 = OpExtInst %uint %1 PackHalf2x16 %19233 + %23488 = OpCompositeExtract %float %15191 0 + %14760 = OpCompositeExtract %float %15191 1 + %19234 = OpCompositeConstruct %v2float %23488 %14760 + %8563 = OpExtInst %uint %1 PackHalf2x16 %19234 + %23489 = OpCompositeExtract %float %15191 2 + %14761 = OpCompositeExtract %float %15191 3 + %19213 = OpCompositeConstruct %v2float %23489 %14761 + %8736 = OpExtInst %uint %1 PackHalf2x16 %19213 + %12628 = OpCompositeConstruct %v4uint %8561 %8562 %8563 %8736 + %16073 = OpCompositeExtract %float %14358 0 + %21616 = OpCompositeExtract %float %14358 1 + %19247 = OpCompositeConstruct %v2float %16073 %21616 + %8564 = OpExtInst %uint %1 PackHalf2x16 %19247 + %23490 = OpCompositeExtract %float %14358 2 + %14762 = OpCompositeExtract %float %14358 3 + %19248 = OpCompositeConstruct %v2float %23490 %14762 + %8565 = OpExtInst %uint %1 PackHalf2x16 %19248 + %23491 = OpCompositeExtract %float %11189 0 + %14763 = OpCompositeExtract %float %11189 1 + %19249 = OpCompositeConstruct %v2float %23491 %14763 + %8566 = OpExtInst %uint %1 PackHalf2x16 %19249 + %23492 = OpCompositeExtract %float %11189 2 + %14764 = OpCompositeExtract %float %11189 3 + %19214 = OpCompositeConstruct %v2float %23492 %14764 + %11926 = OpExtInst %uint %1 PackHalf2x16 %19214 + %24879 = OpCompositeConstruct %v4uint %8564 %8565 %8566 %11926 + OpBranch %23460 + %18070 = OpLabel + %7311 = OpExtInst %v4float %1 FClamp %14921 %2938 %1285 + %20339 = OpVectorTimesScalar %v4float %7311 %float_65535 + %11840 = OpFAdd %v4float %20339 %325 + %7947 = OpConvertFToU %v4uint %11840 + %6361 = OpVectorShuffle %v2uint %7947 %7947 0 2 + %10064 = OpVectorShuffle %v2uint %7947 %7947 1 3 + %10446 = OpShiftLeftLogical %v2uint %10064 %2151 + %22473 = OpBitwiseOr %v2uint %6361 %10446 + %18828 = OpCompositeExtract %uint %22473 0 + %15356 = OpCompositeExtract %uint %22473 1 + %14160 = OpExtInst %v4float %1 FClamp %15191 %2938 %1285 + %11265 = OpVectorTimesScalar %v4float %14160 %float_65535 + %11841 = OpFAdd %v4float %11265 %325 + %7948 = OpConvertFToU %v4uint %11841 + %6362 = OpVectorShuffle %v2uint %7948 %7948 0 2 + %10065 = OpVectorShuffle %v2uint %7948 %7948 1 3 + %10447 = OpShiftLeftLogical %v2uint %10065 %2151 + %22474 = OpBitwiseOr %v2uint %6362 %10447 + %20077 = OpCompositeExtract %uint %22474 0 + %22635 = OpCompositeExtract %uint %22474 1 + %7479 = OpCompositeConstruct %v4uint %18828 %15356 %20077 %22635 + %14406 = OpExtInst %v4float %1 FClamp %14358 %2938 %1285 + %13687 = OpVectorTimesScalar %v4float %14406 %float_65535 + %11842 = OpFAdd %v4float %13687 %325 + %7949 = OpConvertFToU %v4uint %11842 + %6363 = OpVectorShuffle %v2uint %7949 %7949 0 2 + %10066 = OpVectorShuffle %v2uint %7949 %7949 1 3 + %10448 = OpShiftLeftLogical %v2uint %10066 %2151 + %22475 = OpBitwiseOr %v2uint %6363 %10448 + %18829 = OpCompositeExtract %uint %22475 0 + %15357 = OpCompositeExtract %uint %22475 1 + %14161 = OpExtInst %v4float %1 FClamp %11189 %2938 %1285 + %11266 = OpVectorTimesScalar %v4float %14161 %float_65535 + %11843 = OpFAdd %v4float %11266 %325 + %7950 = OpConvertFToU %v4uint %11843 + %6364 = OpVectorShuffle %v2uint %7950 %7950 0 2 + %10067 = OpVectorShuffle %v2uint %7950 %7950 1 3 + %10449 = OpShiftLeftLogical %v2uint %10067 %2151 + %22476 = OpBitwiseOr %v2uint %6364 %10449 + %20078 = OpCompositeExtract %uint %22476 0 + %8024 = OpCompositeExtract %uint %22476 1 + %9053 = OpCompositeConstruct %v4uint %18829 %15357 %20078 %8024 + OpBranch %23460 + %7373 = OpLabel + %19885 = OpCompositeExtract %float %14921 0 + %10277 = OpCompositeExtract %float %14921 1 + %7641 = OpCompositeExtract %float %15191 0 + %8650 = OpCompositeExtract %float %15191 1 + %8414 = OpCompositeConstruct %v4float %19885 %10277 %7641 %8650 + %17959 = OpBitcast %v4uint %8414 + %11089 = OpCompositeExtract %float %14358 0 + %13283 = OpCompositeExtract %float %14358 1 + %7642 = OpCompositeExtract %float %11189 0 + %8651 = OpCompositeExtract %float %11189 1 + %11606 = OpCompositeConstruct %v4float %11089 %13283 %7642 %8651 + %11139 = OpBitcast %v4uint %11606 + OpBranch %23460 + %23460 = OpLabel + %9750 = OpPhi %v4uint %11139 %7373 %9053 %18070 %24879 %9492 + %14743 = OpPhi %v4uint %17959 %7373 %7479 %18070 %12628 %9492 + %6491 = OpIEqual %bool %7640 %uint_0 + OpSelectionMerge %13276 None + OpBranchConditional %6491 %11451 %13276 + %11451 = OpLabel + %24167 = OpCompositeExtract %uint %19124 0 + %22470 = OpINotEqual %bool %24167 %uint_0 + OpBranch %13276 + %13276 = OpLabel + %10955 = OpPhi %bool %6491 %23460 %22470 %11451 + OpSelectionMerge %21873 DontFlatten + OpBranchConditional %10955 %11508 %21873 + %11508 = OpLabel + %23599 = OpCompositeExtract %uint %19124 0 + %17346 = OpUGreaterThanEqual %bool %23599 %uint_2 + OpSelectionMerge %21872 None + OpBranchConditional %17346 %15877 %21872 + %15877 = OpLabel + %24532 = OpUGreaterThanEqual %bool %23599 %uint_3 + OpSelectionMerge %18756 None + OpBranchConditional %24532 %9760 %18756 + %9760 = OpLabel + %17298 = OpCompositeExtract %uint %9750 2 + %21174 = OpCompositeInsert %v4uint %17298 %9750 0 + %23044 = OpCompositeExtract %uint %9750 3 + %9296 = OpCompositeInsert %v4uint %23044 %21174 1 + OpBranch %18756 + %18756 = OpLabel + %17379 = OpPhi %v4uint %9750 %15877 %9296 %9760 + %22881 = OpCompositeExtract %uint %17379 0 + %21983 = OpCompositeInsert %v4uint %22881 %14743 2 + %23045 = OpCompositeExtract %uint %17379 1 + %9297 = OpCompositeInsert %v4uint %23045 %21983 3 + OpBranch %21872 + %21872 = OpLabel + %8059 = OpPhi %v4uint %9750 %11508 %17379 %18756 + %7934 = OpPhi %v4uint %14743 %11508 %9297 %18756 + %23694 = OpCompositeExtract %uint %7934 2 + %21984 = OpCompositeInsert %v4uint %23694 %7934 0 + %23046 = OpCompositeExtract %uint %7934 3 + %9298 = OpCompositeInsert %v4uint %23046 %21984 1 + OpBranch %21873 + %21873 = OpLabel + %8952 = OpPhi %v4uint %9750 %13276 %8059 %21872 + %18858 = OpPhi %v4uint %14743 %13276 %9298 %21872 + %13755 = OpIAdd %v2uint %12025 %23020 + %13244 = OpCompositeExtract %uint %13755 0 + %9555 = OpCompositeExtract %uint %13755 1 + %11053 = OpShiftRightLogical %uint %13244 %uint_1 + %7832 = OpCompositeConstruct %v2uint %11053 %9555 + %24920 = OpUDiv %v2uint %7832 %23601 + %13932 = OpCompositeExtract %uint %24920 0 + %19770 = OpShiftLeftLogical %uint %13932 %uint_1 + %24251 = OpCompositeExtract %uint %24920 1 + %21459 = OpCompositeConstruct %v3uint %19770 %24251 %24434 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %20495 %22217 %10956 + %10956 = OpLabel + %7339 = OpVectorShuffle %v2uint %21459 %21459 0 1 + %22991 = OpBitcast %v2int %7339 + %6431 = OpCompositeExtract %int %22991 0 + %9469 = OpShiftRightArithmetic %int %6431 %int_5 + %10055 = OpCompositeExtract %int %22991 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %15783 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_10 + %10957 = OpBitwiseAnd %int %6431 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17303 = OpIAdd %int %10957 %17741 + %6375 = OpShiftLeftLogical %int %17303 %uint_3 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15435 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18366 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18366 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12151 + %19171 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19171 %int_2 + %16708 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6431 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21588 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21588 %int_6 + %15436 = OpIAdd %int %16708 %21580 + %11782 = OpBitwiseAnd %int %16727 %int_63 + %14671 = OpIAdd %int %15436 %11782 + %22127 = OpBitcast %uint %14671 + OpBranch %21313 + %22217 = OpLabel + %6573 = OpBitcast %v3int %21459 + %17090 = OpCompositeExtract %int %6573 1 + %9470 = OpShiftRightArithmetic %int %17090 %int_4 + %10056 = OpCompositeExtract %int %6573 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %25203 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %15783 %uint_5 + %12439 = OpBitcast %int %9032 + %10367 = OpIMul %int %15143 %12439 + %25154 = OpCompositeExtract %int %6573 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10367 + %8797 = OpShiftLeftLogical %int %18940 %uint_9 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12601 = OpBitwiseAnd %int %17090 %int_6 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7052 = OpShiftLeftLogical %int %17227 %uint_9 + %24035 = OpShiftRightArithmetic %int %7052 %int_6 + %8737 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8737 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19172 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19172 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18367 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18367 %uint_9 + %16729 = OpIAdd %int %10332 %21582 + %19173 = OpBitwiseAnd %int %17090 %int_1 + %21583 = OpShiftLeftLogical %int %19173 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10958 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10958 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10959 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10959 %int_3 + %21849 = OpBitwiseAnd %int %16730 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22128 = OpBitcast %uint %24314 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22128 %22217 %22127 %10956 + %16310 = OpIMul %v2uint %24920 %23601 + %16261 = OpISub %v2uint %7832 %16310 + %17551 = OpCompositeExtract %uint %23601 1 + %23632 = OpIMul %uint %8858 %17551 + %15520 = OpIMul %uint %9468 %23632 + %16084 = OpCompositeExtract %uint %16261 0 + %15890 = OpIMul %uint %16084 %17551 + %6887 = OpCompositeExtract %uint %16261 1 + %11045 = OpIAdd %uint %15890 %6887 + %24733 = OpShiftLeftLogical %uint %11045 %uint_1 + %23219 = OpBitwiseAnd %uint %13244 %uint_1 + %9559 = OpIAdd %uint %24733 %23219 + %17811 = OpShiftLeftLogical %uint %9559 %uint_3 + %8264 = OpIAdd %uint %15520 %17811 + %9676 = OpShiftRightLogical %uint %8264 %uint_4 + %19356 = OpIEqual %bool %19164 %uint_4 + OpSelectionMerge %14780 None + OpBranchConditional %19356 %13279 %14780 + %13279 = OpLabel + %7958 = OpVectorShuffle %v4uint %18858 %18858 1 0 3 2 + OpBranch %14780 + %14780 = OpLabel + %22898 = OpPhi %v4uint %18858 %21313 %7958 %13279 + %6605 = OpSelect %uint %19356 %uint_2 %19164 + %13412 = OpIEqual %bool %6605 %uint_1 + %18370 = OpIEqual %bool %6605 %uint_2 + %22150 = OpLogicalOr %bool %13412 %18370 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %22898 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %22898 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16377 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22650 = OpPhi %v4uint %22898 %14780 %16377 %10583 + %19638 = OpIEqual %bool %6605 %uint_3 + %15139 = OpLogicalOr %bool %18370 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22650 %749 + %15335 = OpShiftRightLogical %v4uint %22650 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22650 %13411 %10728 %11064 + %6590 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %9676 + OpStore %6590 %19767 + %23542 = OpUGreaterThan %bool %8858 %uint_1 + OpSelectionMerge %19116 DontFlatten + OpBranchConditional %23542 %14554 %21994 + %21994 = OpLabel + OpBranch %19116 + %14554 = OpLabel + %13898 = OpShiftRightLogical %uint %7640 %uint_1 + %7937 = OpUDiv %uint %13898 %8858 + %16891 = OpIMul %uint %7937 %8858 + %12657 = OpISub %uint %13898 %16891 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %8858 + OpSelectionMerge %9304 None + OpBranchConditional %13375 %7387 %21995 + %21995 = OpLabel + OpBranch %9304 + %7387 = OpLabel + %15254 = OpIMul %uint %uint_32 %8858 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18757 = OpISub %uint %15254 %21519 + OpBranch %9304 + %9304 = OpLabel + %10540 = OpPhi %uint %18757 %7387 %uint_16 %21995 + OpBranch %19116 + %19116 = OpLabel + %10684 = OpPhi %uint %10540 %9304 %uint_32 %21994 + %18731 = OpIMul %uint %10684 %17551 + %19951 = OpShiftRightLogical %uint %18731 %uint_4 + %23410 = OpIAdd %uint %9676 %19951 + OpSelectionMerge %16262 None + OpBranchConditional %19356 %13280 %16262 + %13280 = OpLabel + %7959 = OpVectorShuffle %v4uint %8952 %8952 1 0 3 2 + OpBranch %16262 + %16262 = OpLabel + %10960 = OpPhi %v4uint %8952 %19116 %7959 %13280 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %10960 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %10960 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16378 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10961 = OpPhi %v4uint %10960 %16262 %16378 %10584 + OpSelectionMerge %11417 None + OpBranchConditional %15139 %11065 %11417 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10961 %749 + %15336 = OpShiftRightLogical %v4uint %10961 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %10961 %14874 %10729 %11065 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5522 %int_0 %23410 + OpStore %8053 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_full_64bpp_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x0000629D, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00040047, 0x000007D0, 0x00000006, 0x00000004, + 0x00030047, 0x0000079C, 0x00000003, 0x00040048, 0x0000079C, 0x00000000, 0x00000018, 0x00050048, + 0x0000079C, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000CC7, 0x00000018, 0x00040047, + 0x00000CC7, 0x00000021, 0x00000000, 0x00040047, 0x00000CC7, 0x00000022, 0x00000000, 0x00030047, + 0x000003F9, 0x00000002, 0x00050048, 0x000003F9, 0x00000000, 0x00000023, 0x00000000, 0x00050048, + 0x000003F9, 0x00000001, 0x00000023, 0x00000004, 0x00050048, 0x000003F9, 0x00000002, 0x00000023, + 0x00000008, 0x00050048, 0x000003F9, 0x00000003, 0x00000023, 0x0000000C, 0x00040047, 0x00000F48, + 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, 0x000007B4, + 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000019, 0x00050048, 0x000007B4, 0x00000000, + 0x00000023, 0x00000000, 0x00030047, 0x00001592, 0x00000019, 0x00040047, 0x00001592, 0x00000021, + 0x00000000, 0x00040047, 0x00001592, 0x00000022, 0x00000001, 0x00040047, 0x00000AC9, 0x0000000B, + 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040015, 0x0000000B, + 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, + 0x0000000B, 0x00000003, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00030016, 0x0000000D, + 0x00000020, 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x00040017, 0x0000001D, 0x0000000D, + 0x00000004, 0x00020014, 0x00000009, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x0004002B, + 0x0000000D, 0x00000A0C, 0x00000000, 0x0004002B, 0x0000000D, 0x0000008A, 0x3F800000, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, + 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, + 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, + 0x0000000D, 0x0000022D, 0x477FFF00, 0x0004002B, 0x0000000D, 0x000000FC, 0x3F000000, 0x0004002B, + 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, + 0x0000000B, 0x00000A52, 0x00000018, 0x0007002C, 0x00000017, 0x0000028D, 0x00000A0A, 0x00000A22, + 0x00000A3A, 0x00000A52, 0x0004002B, 0x0000000B, 0x00000144, 0x000000FF, 0x0004002B, 0x0000000D, + 0x0000017A, 0x3B808081, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, + 0x00000A46, 0x00000014, 0x0004002B, 0x0000000B, 0x00000A64, 0x0000001E, 0x0007002C, 0x00000017, + 0x0000034D, 0x00000A0A, 0x00000A28, 0x00000A46, 0x00000A64, 0x0004002B, 0x0000000B, 0x00000A44, + 0x000003FF, 0x0007002C, 0x00000017, 0x0000027B, 0x00000A44, 0x00000A44, 0x00000A44, 0x00000A13, + 0x0004002B, 0x0000000D, 0x000006FE, 0x3A802008, 0x0004002B, 0x0000000D, 0x00000149, 0x3EAAAAAB, + 0x0007002C, 0x0000001D, 0x00000AEE, 0x000006FE, 0x000006FE, 0x000006FE, 0x00000149, 0x0006002C, + 0x00000014, 0x00000BB4, 0x00000A0A, 0x00000A28, 0x00000A46, 0x0004002B, 0x0000000B, 0x00000B87, + 0x0000007F, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x00040017, 0x00000010, 0x00000009, + 0x00000003, 0x0004002B, 0x0000000B, 0x00000B7E, 0x0000007C, 0x0004002B, 0x0000000B, 0x00000A4F, + 0x00000017, 0x00040017, 0x00000018, 0x0000000D, 0x00000003, 0x0004002B, 0x0000000D, 0x00000341, + 0xBF800000, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x0005002C, 0x00000012, 0x000007A7, + 0x00000A3B, 0x00000A0B, 0x0004002B, 0x0000000D, 0x000007FE, 0x3A800100, 0x00040017, 0x0000001A, + 0x0000000C, 0x00000004, 0x0007002C, 0x0000001A, 0x00000122, 0x00000A3B, 0x00000A0B, 0x00000A3B, + 0x00000A0B, 0x0005002C, 0x00000011, 0x0000072D, 0x00000A10, 0x00000A0D, 0x00040017, 0x0000000F, + 0x00000009, 0x00000002, 0x0005002C, 0x00000011, 0x0000070F, 0x00000A0A, 0x00000A0A, 0x0005002C, + 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, 0x0005002C, 0x00000011, 0x00000718, 0x00000A0D, + 0x00000A0A, 0x0004002B, 0x0000000B, 0x00000AFA, 0x00000050, 0x0005002C, 0x00000011, 0x00000A9F, + 0x00000AFA, 0x00000A3A, 0x0004002B, 0x0000000B, 0x00000A84, 0x00000800, 0x0004002B, 0x0000000C, + 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000C, + 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, + 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, + 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, + 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, + 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, + 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, + 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, 0x0004002B, 0x0000000C, + 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, + 0x00000A6A, 0x00000020, 0x0003001D, 0x000007D0, 0x0000000B, 0x0003001E, 0x0000079C, 0x000007D0, + 0x00040020, 0x00000A1B, 0x00000002, 0x0000079C, 0x0004003B, 0x00000A1B, 0x00000CC7, 0x00000002, + 0x00040020, 0x00000288, 0x00000002, 0x0000000B, 0x0006001E, 0x000003F9, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000676, 0x00000009, 0x000003F9, 0x0004003B, 0x00000676, + 0x00000CE9, 0x00000009, 0x00040020, 0x00000289, 0x00000009, 0x0000000B, 0x0004002B, 0x0000000B, + 0x00000A31, 0x0000000D, 0x0004002B, 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, + 0x00000A37, 0x0000000F, 0x0004002B, 0x0000000B, 0x00000A5E, 0x0000001C, 0x0004002B, 0x0000000B, + 0x00000A43, 0x00000013, 0x0005002C, 0x00000011, 0x00000883, 0x00000A3A, 0x00000A43, 0x0004002B, + 0x0000000B, 0x00000510, 0x20000000, 0x0005002C, 0x00000011, 0x0000073F, 0x00000A0A, 0x00000A16, + 0x0004002B, 0x0000000C, 0x00000A29, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000AC7, 0x0000003F, + 0x0004002B, 0x0000000C, 0x00000A59, 0x0000001A, 0x0004002B, 0x0000000C, 0x00000A50, 0x00000017, + 0x0004002B, 0x0000000B, 0x00000926, 0x01000000, 0x0005002C, 0x00000011, 0x000008E3, 0x00000A46, + 0x00000A52, 0x00040020, 0x00000291, 0x00000001, 0x00000014, 0x0004003B, 0x00000291, 0x00000F48, + 0x00000001, 0x0005002C, 0x00000011, 0x00000721, 0x00000A10, 0x00000A0A, 0x0003001D, 0x000007DC, + 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, + 0x0004003B, 0x00000A32, 0x00001592, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, + 0x0006002C, 0x00000014, 0x00000AC9, 0x00000A22, 0x00000A22, 0x00000A0D, 0x0005002C, 0x00000011, + 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0005002C, 0x00000011, 0x000007A3, 0x00000A37, 0x00000A0D, + 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, 0x0005002C, 0x00000011, 0x0000084A, + 0x00000A37, 0x00000A37, 0x0007002C, 0x0000001D, 0x00000504, 0x00000341, 0x00000341, 0x00000341, + 0x00000341, 0x0007002C, 0x0000001A, 0x00000302, 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x00000A3B, + 0x0007002C, 0x00000017, 0x0000064B, 0x00000144, 0x00000144, 0x00000144, 0x00000144, 0x0006002C, + 0x00000014, 0x00000105, 0x00000A44, 0x00000A44, 0x00000A44, 0x0006002C, 0x00000014, 0x00000466, + 0x00000B87, 0x00000B87, 0x00000B87, 0x0006002C, 0x00000014, 0x00000B0C, 0x00000A1F, 0x00000A1F, + 0x00000A1F, 0x0006002C, 0x00000014, 0x00000A12, 0x00000A0A, 0x00000A0A, 0x00000A0A, 0x0006002C, + 0x00000014, 0x000003FA, 0x00000B7E, 0x00000B7E, 0x00000B7E, 0x0006002C, 0x00000014, 0x00000189, + 0x00000A4F, 0x00000A4F, 0x00000A4F, 0x0006002C, 0x00000014, 0x0000008D, 0x00000A3A, 0x00000A3A, + 0x00000A3A, 0x0005002C, 0x00000013, 0x00000049, 0x00000341, 0x00000341, 0x0005002C, 0x00000012, + 0x00000867, 0x00000A3B, 0x00000A3B, 0x0007002C, 0x0000001D, 0x00000B7A, 0x00000A0C, 0x00000A0C, + 0x00000A0C, 0x00000A0C, 0x0007002C, 0x0000001D, 0x00000505, 0x0000008A, 0x0000008A, 0x0000008A, + 0x0000008A, 0x0007002C, 0x0000001D, 0x00000145, 0x000000FC, 0x000000FC, 0x000000FC, 0x000000FC, + 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, + 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, + 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, + 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, + 0x0004002B, 0x0000000C, 0x00000089, 0x3F800000, 0x0004002B, 0x0000000B, 0x000009F8, 0xFFFFFFFA, + 0x0006002C, 0x00000014, 0x00000938, 0x000009F8, 0x000009F8, 0x000009F8, 0x0004002B, 0x0000000D, + 0x0000016E, 0x3E800000, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, + 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, + 0x00002E68, 0x00050041, 0x00000289, 0x000056E5, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, + 0x00003D0B, 0x000056E5, 0x00050041, 0x00000289, 0x000058AC, 0x00000CE9, 0x00000A0E, 0x0004003D, + 0x0000000B, 0x00005158, 0x000058AC, 0x000500C7, 0x0000000B, 0x00005051, 0x00003D0B, 0x00000A44, + 0x000500C2, 0x0000000B, 0x00004E0A, 0x00003D0B, 0x00000A28, 0x000500C7, 0x0000000B, 0x0000217E, + 0x00004E0A, 0x00000A13, 0x000500C2, 0x0000000B, 0x0000520A, 0x00003D0B, 0x00000A31, 0x000500C7, + 0x0000000B, 0x0000217F, 0x0000520A, 0x00000A81, 0x000500C2, 0x0000000B, 0x0000520B, 0x00003D0B, + 0x00000A52, 0x000500C7, 0x0000000B, 0x00002180, 0x0000520B, 0x00000A37, 0x000500C2, 0x0000000B, + 0x00004994, 0x00003D0B, 0x00000A5E, 0x000500C7, 0x0000000B, 0x000023AA, 0x00004994, 0x00000A0D, + 0x00050050, 0x00000011, 0x000022A7, 0x00005158, 0x00005158, 0x000500C2, 0x00000011, 0x000025A1, + 0x000022A7, 0x00000883, 0x000500C7, 0x00000011, 0x00005C31, 0x000025A1, 0x000007A2, 0x000500C7, + 0x0000000B, 0x00005DDE, 0x00003D0B, 0x00000510, 0x000500AB, 0x00000009, 0x00003007, 0x00005DDE, + 0x00000A0A, 0x000300F7, 0x00003954, 0x00000000, 0x000400FA, 0x00003007, 0x00004163, 0x000055E8, + 0x000200F8, 0x000055E8, 0x000200F9, 0x00003954, 0x000200F8, 0x00004163, 0x000500C2, 0x00000011, + 0x00003BAE, 0x00005C31, 0x00000724, 0x000200F9, 0x00003954, 0x000200F8, 0x00003954, 0x000700F5, + 0x00000011, 0x00004AB4, 0x00003BAE, 0x00004163, 0x0000070F, 0x000055E8, 0x000500C2, 0x00000011, + 0x00001B7E, 0x000022A7, 0x0000073F, 0x000500C7, 0x00000011, 0x00002DF9, 0x00001B7E, 0x000007A3, + 0x000500C4, 0x00000011, 0x00003F4F, 0x00002DF9, 0x0000074E, 0x00050084, 0x00000011, 0x000059EB, + 0x00003F4F, 0x00005C31, 0x000500C2, 0x0000000B, 0x00003343, 0x00005158, 0x00000A19, 0x000500C7, + 0x0000000B, 0x000039C1, 0x00003343, 0x00000A81, 0x00050051, 0x0000000B, 0x0000229A, 0x00005C31, + 0x00000000, 0x00050084, 0x0000000B, 0x000059D1, 0x000039C1, 0x0000229A, 0x00050041, 0x00000289, + 0x00004E44, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x000048C4, 0x00004E44, 0x00050041, + 0x00000289, 0x000058AD, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x000051B7, 0x000058AD, + 0x000500C7, 0x0000000B, 0x00004ADC, 0x000048C4, 0x00000A1F, 0x000500C7, 0x0000000B, 0x000055EF, + 0x000048C4, 0x00000A22, 0x000500AB, 0x00000009, 0x0000500F, 0x000055EF, 0x00000A0A, 0x000500C2, + 0x0000000B, 0x00002843, 0x000048C4, 0x00000A16, 0x000500C7, 0x0000000B, 0x00005F72, 0x00002843, + 0x00000A1F, 0x000500C2, 0x0000000B, 0x00004CD8, 0x000048C4, 0x00000A1F, 0x000500C7, 0x0000000B, + 0x00005093, 0x00004CD8, 0x00000AC7, 0x0004007C, 0x0000000C, 0x00005988, 0x000048C4, 0x000500C4, + 0x0000000C, 0x0000358F, 0x00005988, 0x00000A29, 0x000500C3, 0x0000000C, 0x0000509C, 0x0000358F, + 0x00000A59, 0x000500C4, 0x0000000C, 0x00004702, 0x0000509C, 0x00000A50, 0x00050080, 0x0000000C, + 0x00001D26, 0x00004702, 0x00000089, 0x0004007C, 0x0000000D, 0x00002B2C, 0x00001D26, 0x000500C7, + 0x0000000B, 0x00005879, 0x000048C4, 0x00000926, 0x000500AB, 0x00000009, 0x00001D59, 0x00005879, + 0x00000A0A, 0x000500C7, 0x0000000B, 0x00001F43, 0x000051B7, 0x00000A44, 0x000500C4, 0x0000000B, + 0x00003DA7, 0x00001F43, 0x00000A19, 0x000500C2, 0x0000000B, 0x0000583F, 0x000051B7, 0x00000A28, + 0x000500C7, 0x0000000B, 0x00004BBE, 0x0000583F, 0x00000A44, 0x000500C4, 0x0000000B, 0x00006273, + 0x00004BBE, 0x00000A19, 0x00050050, 0x00000011, 0x000028B6, 0x000051B7, 0x000051B7, 0x000500C2, + 0x00000011, 0x00002891, 0x000028B6, 0x000008E3, 0x000500C7, 0x00000011, 0x00005B53, 0x00002891, + 0x0000084A, 0x000500C4, 0x00000011, 0x00003F50, 0x00005B53, 0x0000074E, 0x00050084, 0x00000011, + 0x000059EC, 0x00003F50, 0x00005C31, 0x000500C2, 0x0000000B, 0x000031C7, 0x000051B7, 0x00000A5E, + 0x000500C7, 0x0000000B, 0x00004356, 0x000031C7, 0x00000A1F, 0x0004003D, 0x00000014, 0x000031C1, + 0x00000F48, 0x0007004F, 0x00000011, 0x000038A4, 0x000031C1, 0x000031C1, 0x00000000, 0x00000001, + 0x000500C4, 0x00000011, 0x00002EF9, 0x000038A4, 0x00000721, 0x00050051, 0x0000000B, 0x00001DD8, + 0x00002EF9, 0x00000000, 0x000500C4, 0x0000000B, 0x00002D8A, 0x000059D1, 0x00000A13, 0x000500AE, + 0x00000009, 0x00003C13, 0x00001DD8, 0x00002D8A, 0x000300F7, 0x000036C9, 0x00000002, 0x000400FA, + 0x00003C13, 0x000055E9, 0x000036C9, 0x000200F8, 0x000055E9, 0x000200F9, 0x00004C7A, 0x000200F8, + 0x000036C9, 0x00050051, 0x0000000B, 0x000048B7, 0x00002EF9, 0x00000001, 0x00050051, 0x0000000B, + 0x000041A3, 0x00004AB4, 0x00000001, 0x0007000C, 0x0000000B, 0x00005F7E, 0x00000001, 0x00000029, + 0x000048B7, 0x000041A3, 0x00050050, 0x00000011, 0x000051EF, 0x00001DD8, 0x00005F7E, 0x00050080, + 0x00000011, 0x0000522C, 0x000051EF, 0x000059EB, 0x000500B2, 0x00000009, 0x00003ECB, 0x00004356, + 0x00000A13, 0x000300F7, 0x00005CE0, 0x00000000, 0x000400FA, 0x00003ECB, 0x00002AEE, 0x00003AEF, + 0x000200F8, 0x00003AEF, 0x000500AA, 0x00000009, 0x000034FE, 0x00004356, 0x00000A19, 0x000600A9, + 0x0000000B, 0x000020F6, 0x000034FE, 0x00000A10, 0x00000A0A, 0x000200F9, 0x00005CE0, 0x000200F8, + 0x00002AEE, 0x000200F9, 0x00005CE0, 0x000200F8, 0x00005CE0, 0x000700F5, 0x0000000B, 0x00004B64, + 0x00004356, 0x00002AEE, 0x000020F6, 0x00003AEF, 0x00050050, 0x00000011, 0x000041BE, 0x0000217E, + 0x0000217E, 0x000500AE, 0x0000000F, 0x00002E19, 0x000041BE, 0x0000072D, 0x000600A9, 0x00000011, + 0x00004BB5, 0x00002E19, 0x00000724, 0x0000070F, 0x000500C4, 0x00000011, 0x00002AEA, 0x0000522C, + 0x00004BB5, 0x00050050, 0x00000011, 0x0000605D, 0x00004B64, 0x00004B64, 0x000500C2, 0x00000011, + 0x00002385, 0x0000605D, 0x00000718, 0x000500C7, 0x00000011, 0x00003EC8, 0x00002385, 0x00000724, + 0x00050080, 0x00000011, 0x000046BA, 0x00002AEA, 0x00003EC8, 0x00050084, 0x00000011, 0x00005998, + 0x00000A9F, 0x00005C31, 0x00050050, 0x00000011, 0x00002C44, 0x000023AA, 0x00000A0A, 0x000500C2, + 0x00000011, 0x000019AB, 0x00005998, 0x00002C44, 0x00050086, 0x00000011, 0x000027A2, 0x000046BA, + 0x000019AB, 0x00050051, 0x0000000B, 0x00004FA6, 0x000027A2, 0x00000001, 0x00050084, 0x0000000B, + 0x00002B26, 0x00004FA6, 0x00005051, 0x00050051, 0x0000000B, 0x00006059, 0x000027A2, 0x00000000, + 0x00050080, 0x0000000B, 0x00005420, 0x00002B26, 0x00006059, 0x00050080, 0x0000000B, 0x00002226, + 0x0000217F, 0x00005420, 0x00050084, 0x00000011, 0x00005768, 0x000027A2, 0x000019AB, 0x00050082, + 0x00000011, 0x000050EB, 0x000046BA, 0x00005768, 0x00050051, 0x0000000B, 0x00001C87, 0x00005998, + 0x00000000, 0x00050051, 0x0000000B, 0x00005962, 0x00005998, 0x00000001, 0x00050084, 0x0000000B, + 0x00003372, 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, 0x000038D7, 0x00002226, 0x00003372, + 0x00050051, 0x0000000B, 0x00001A95, 0x000050EB, 0x00000001, 0x00050051, 0x0000000B, 0x00005BE6, + 0x000019AB, 0x00000000, 0x00050084, 0x0000000B, 0x00005966, 0x00001A95, 0x00005BE6, 0x00050051, + 0x0000000B, 0x00001AE6, 0x000050EB, 0x00000000, 0x00050080, 0x0000000B, 0x000025E0, 0x00005966, + 0x00001AE6, 0x000500C4, 0x0000000B, 0x00004665, 0x000025E0, 0x000023AA, 0x00050080, 0x0000000B, + 0x000047BB, 0x000038D7, 0x00004665, 0x00050084, 0x0000000B, 0x000034C0, 0x00003372, 0x00000A84, + 0x00050089, 0x0000000B, 0x0000628F, 0x000047BB, 0x000034C0, 0x000500AE, 0x00000009, 0x00003FFB, + 0x0000217E, 0x00000A10, 0x000600A9, 0x0000000B, 0x0000609F, 0x00003FFB, 0x00000A0D, 0x00000A0A, + 0x00050080, 0x0000000B, 0x00004E6A, 0x000023AA, 0x0000609F, 0x000500C4, 0x0000000B, 0x0000199B, + 0x00000A0D, 0x00004E6A, 0x000500AB, 0x00000009, 0x00005AEF, 0x000023AA, 0x00000A0A, 0x000300F7, + 0x0000530F, 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B65, 0x000040B9, 0x000200F8, 0x000040B9, + 0x000500AA, 0x00000009, 0x00004ADA, 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F49, 0x00000002, + 0x000400FA, 0x00004ADA, 0x00002621, 0x00002F61, 0x000200F8, 0x00002F61, 0x00060041, 0x00000288, + 0x00004BCF, 0x00000CC7, 0x00000A0B, 0x0000628F, 0x0004003D, 0x0000000B, 0x00005D43, 0x00004BCF, + 0x00050080, 0x0000000B, 0x00002DA7, 0x0000628F, 0x0000199B, 0x00060041, 0x00000288, 0x0000194B, + 0x00000CC7, 0x00000A0B, 0x00002DA7, 0x0004003D, 0x0000000B, 0x00005E5B, 0x0000194B, 0x00050084, + 0x0000000B, 0x0000185A, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A1, 0x0000628F, + 0x0000185A, 0x00060041, 0x00000288, 0x00003BCD, 0x00000CC7, 0x00000A0B, 0x000020A1, 0x0004003D, + 0x0000000B, 0x00005E5C, 0x00003BCD, 0x00050084, 0x0000000B, 0x0000185B, 0x00000A13, 0x0000199B, + 0x00050080, 0x0000000B, 0x000020A2, 0x0000628F, 0x0000185B, 0x00060041, 0x00000288, 0x000037F1, + 0x00000CC7, 0x00000A0B, 0x000020A2, 0x0004003D, 0x0000000B, 0x00003FFC, 0x000037F1, 0x00070050, + 0x00000017, 0x0000512C, 0x00005D43, 0x00005E5B, 0x00005E5C, 0x00003FFC, 0x000200F9, 0x00004F49, + 0x000200F8, 0x00002621, 0x00060041, 0x00000288, 0x00005545, 0x00000CC7, 0x00000A0B, 0x0000628F, + 0x0004003D, 0x0000000B, 0x00005D44, 0x00005545, 0x00050080, 0x0000000B, 0x00002DA8, 0x0000628F, + 0x00000A0D, 0x00060041, 0x00000288, 0x000018FF, 0x00000CC7, 0x00000A0B, 0x00002DA8, 0x0004003D, + 0x0000000B, 0x00005C62, 0x000018FF, 0x00050080, 0x0000000B, 0x00002DA9, 0x0000628F, 0x00000A10, + 0x00060041, 0x00000288, 0x00001900, 0x00000CC7, 0x00000A0B, 0x00002DA9, 0x0004003D, 0x0000000B, + 0x00005C63, 0x00001900, 0x00050080, 0x0000000B, 0x00002DAA, 0x0000628F, 0x00000A13, 0x00060041, + 0x00000288, 0x00005FEE, 0x00000CC7, 0x00000A0B, 0x00002DAA, 0x0004003D, 0x0000000B, 0x00003FFD, + 0x00005FEE, 0x00070050, 0x00000017, 0x0000512D, 0x00005D44, 0x00005C62, 0x00005C63, 0x00003FFD, + 0x000200F9, 0x00004F49, 0x000200F8, 0x00004F49, 0x000700F5, 0x00000017, 0x00002ABF, 0x0000512D, + 0x00002621, 0x0000512C, 0x00002F61, 0x000300F7, 0x00003F60, 0x00000000, 0x001300FB, 0x00002180, + 0x00004BFB, 0x00000000, 0x000038F9, 0x00000001, 0x000038F9, 0x00000002, 0x00001CBB, 0x0000000A, + 0x00001CBB, 0x00000003, 0x00001CBA, 0x0000000C, 0x00001CBA, 0x00000004, 0x00001FFE, 0x00000006, + 0x00002033, 0x000200F8, 0x00002033, 0x00050051, 0x0000000B, 0x00005F56, 0x00002ABF, 0x00000000, + 0x0006000C, 0x00000013, 0x00006067, 0x00000001, 0x0000003E, 0x00005F56, 0x00050051, 0x0000000D, + 0x00002762, 0x00006067, 0x00000000, 0x00050051, 0x0000000D, 0x00004446, 0x00006067, 0x00000001, + 0x00070050, 0x0000001D, 0x0000390C, 0x00002762, 0x00004446, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x0000437A, 0x00002ABF, 0x00000001, 0x0006000C, 0x00000013, 0x0000466B, 0x00000001, + 0x0000003E, 0x0000437A, 0x00050051, 0x0000000D, 0x00002763, 0x0000466B, 0x00000000, 0x00050051, + 0x0000000D, 0x00004447, 0x0000466B, 0x00000001, 0x00070050, 0x0000001D, 0x0000390D, 0x00002763, + 0x00004447, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x0000437B, 0x00002ABF, 0x00000002, + 0x0006000C, 0x00000013, 0x0000466C, 0x00000001, 0x0000003E, 0x0000437B, 0x00050051, 0x0000000D, + 0x00002764, 0x0000466C, 0x00000000, 0x00050051, 0x0000000D, 0x00004448, 0x0000466C, 0x00000001, + 0x00070050, 0x0000001D, 0x0000390E, 0x00002764, 0x00004448, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x0000437C, 0x00002ABF, 0x00000003, 0x0006000C, 0x00000013, 0x0000466D, 0x00000001, + 0x0000003E, 0x0000437C, 0x00050051, 0x0000000D, 0x00002765, 0x0000466D, 0x00000000, 0x00050051, + 0x0000000D, 0x000050BE, 0x0000466D, 0x00000001, 0x00070050, 0x0000001D, 0x00002349, 0x00002765, + 0x000050BE, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F60, 0x000200F8, 0x00001FFE, 0x00050051, + 0x0000000B, 0x0000308B, 0x00002ABF, 0x00000000, 0x0004007C, 0x0000000C, 0x0000589D, 0x0000308B, + 0x00050050, 0x00000012, 0x0000471A, 0x0000589D, 0x0000589D, 0x000500C4, 0x00000012, 0x000047AD, + 0x0000471A, 0x000007A7, 0x000500C3, 0x00000012, 0x00003417, 0x000047AD, 0x00000867, 0x0004006F, + 0x00000013, 0x00002A97, 0x00003417, 0x0005008E, 0x00000013, 0x00004747, 0x00002A97, 0x000007FE, + 0x0007000C, 0x00000013, 0x00005E06, 0x00000001, 0x00000028, 0x00000049, 0x00004747, 0x00050051, + 0x0000000D, 0x00005F0A, 0x00005E06, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD4, 0x00005E06, + 0x00000001, 0x00070050, 0x0000001D, 0x0000411E, 0x00005F0A, 0x00003CD4, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x00004C42, 0x00002ABF, 0x00000001, 0x0004007C, 0x0000000C, 0x00003EA1, + 0x00004C42, 0x00050050, 0x00000012, 0x0000471B, 0x00003EA1, 0x00003EA1, 0x000500C4, 0x00000012, + 0x000047AE, 0x0000471B, 0x000007A7, 0x000500C3, 0x00000012, 0x00003418, 0x000047AE, 0x00000867, + 0x0004006F, 0x00000013, 0x00002A98, 0x00003418, 0x0005008E, 0x00000013, 0x00004748, 0x00002A98, + 0x000007FE, 0x0007000C, 0x00000013, 0x00005E07, 0x00000001, 0x00000028, 0x00000049, 0x00004748, + 0x00050051, 0x0000000D, 0x00005F0B, 0x00005E07, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD5, + 0x00005E07, 0x00000001, 0x00070050, 0x0000001D, 0x0000411F, 0x00005F0B, 0x00003CD5, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C43, 0x00002ABF, 0x00000002, 0x0004007C, 0x0000000C, + 0x00003EA2, 0x00004C43, 0x00050050, 0x00000012, 0x0000471C, 0x00003EA2, 0x00003EA2, 0x000500C4, + 0x00000012, 0x000047AF, 0x0000471C, 0x000007A7, 0x000500C3, 0x00000012, 0x00003419, 0x000047AF, + 0x00000867, 0x0004006F, 0x00000013, 0x00002A99, 0x00003419, 0x0005008E, 0x00000013, 0x00004749, + 0x00002A99, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E08, 0x00000001, 0x00000028, 0x00000049, + 0x00004749, 0x00050051, 0x0000000D, 0x00005F0C, 0x00005E08, 0x00000000, 0x00050051, 0x0000000D, + 0x00003CD6, 0x00005E08, 0x00000001, 0x00070050, 0x0000001D, 0x00004120, 0x00005F0C, 0x00003CD6, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C44, 0x00002ABF, 0x00000003, 0x0004007C, + 0x0000000C, 0x00003EA3, 0x00004C44, 0x00050050, 0x00000012, 0x0000471D, 0x00003EA3, 0x00003EA3, + 0x000500C4, 0x00000012, 0x000047B0, 0x0000471D, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341A, + 0x000047B0, 0x00000867, 0x0004006F, 0x00000013, 0x00002A9A, 0x0000341A, 0x0005008E, 0x00000013, + 0x0000474A, 0x00002A9A, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E09, 0x00000001, 0x00000028, + 0x00000049, 0x0000474A, 0x00050051, 0x0000000D, 0x00005F0D, 0x00005E09, 0x00000000, 0x00050051, + 0x0000000D, 0x0000494C, 0x00005E09, 0x00000001, 0x00070050, 0x0000001D, 0x0000234A, 0x00005F0D, + 0x0000494C, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F60, 0x000200F8, 0x00001CBA, 0x00050051, + 0x0000000B, 0x000056BD, 0x00002ABF, 0x00000000, 0x00060050, 0x00000014, 0x00004F0A, 0x000056BD, + 0x000056BD, 0x000056BD, 0x000500C2, 0x00000014, 0x00002B0D, 0x00004F0A, 0x00000BB4, 0x000500C7, + 0x00000014, 0x00005DE6, 0x00002B0D, 0x00000105, 0x000500C7, 0x00000014, 0x0000489C, 0x00005DE6, + 0x00000466, 0x000500C2, 0x00000014, 0x00005B90, 0x00005DE6, 0x00000B0C, 0x000500AA, 0x00000010, + 0x000040C9, 0x00005B90, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4B, 0x00000001, 0x0000004B, + 0x0000489C, 0x0004007C, 0x00000014, 0x00002A15, 0x00002C4B, 0x00050082, 0x00000014, 0x0000187A, + 0x00000B0C, 0x00002A15, 0x00050080, 0x00000014, 0x00002210, 0x00002A15, 0x00000938, 0x000600A9, + 0x00000014, 0x0000286F, 0x000040C9, 0x00002210, 0x00005B90, 0x000500C4, 0x00000014, 0x00005AD4, + 0x0000489C, 0x0000187A, 0x000500C7, 0x00000014, 0x0000499A, 0x00005AD4, 0x00000466, 0x000600A9, + 0x00000014, 0x00002A9D, 0x000040C9, 0x0000499A, 0x0000489C, 0x00050080, 0x00000014, 0x00005FF9, + 0x0000286F, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F7F, 0x00005FF9, 0x00000189, 0x000500C4, + 0x00000014, 0x00003FA6, 0x00002A9D, 0x0000008D, 0x000500C5, 0x00000014, 0x0000577C, 0x00004F7F, + 0x00003FA6, 0x000500AA, 0x00000010, 0x00003600, 0x00005DE6, 0x00000A12, 0x000600A9, 0x00000014, + 0x00004242, 0x00003600, 0x00000A12, 0x0000577C, 0x0004007C, 0x00000018, 0x000029CF, 0x00004242, + 0x000500C2, 0x0000000B, 0x00004BA4, 0x000056BD, 0x00000A64, 0x00040070, 0x0000000D, 0x0000480E, + 0x00004BA4, 0x00050085, 0x0000000D, 0x00003E1F, 0x0000480E, 0x00000149, 0x00050051, 0x0000000D, + 0x000053C2, 0x000029CF, 0x00000000, 0x00050051, 0x0000000D, 0x00002A55, 0x000029CF, 0x00000001, + 0x00050051, 0x0000000D, 0x00001E99, 0x000029CF, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDA, + 0x000053C2, 0x00002A55, 0x00001E99, 0x00003E1F, 0x00050051, 0x0000000B, 0x000027F5, 0x00002ABF, + 0x00000001, 0x00060050, 0x00000014, 0x0000350E, 0x000027F5, 0x000027F5, 0x000027F5, 0x000500C2, + 0x00000014, 0x00002B0E, 0x0000350E, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DE7, 0x00002B0E, + 0x00000105, 0x000500C7, 0x00000014, 0x0000489D, 0x00005DE7, 0x00000466, 0x000500C2, 0x00000014, + 0x00005B91, 0x00005DE7, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CA, 0x00005B91, 0x00000A12, + 0x0006000C, 0x00000016, 0x00002C4C, 0x00000001, 0x0000004B, 0x0000489D, 0x0004007C, 0x00000014, + 0x00002A16, 0x00002C4C, 0x00050082, 0x00000014, 0x0000187B, 0x00000B0C, 0x00002A16, 0x00050080, + 0x00000014, 0x00002211, 0x00002A16, 0x00000938, 0x000600A9, 0x00000014, 0x00002870, 0x000040CA, + 0x00002211, 0x00005B91, 0x000500C4, 0x00000014, 0x00005AD5, 0x0000489D, 0x0000187B, 0x000500C7, + 0x00000014, 0x0000499B, 0x00005AD5, 0x00000466, 0x000600A9, 0x00000014, 0x00002A9E, 0x000040CA, + 0x0000499B, 0x0000489D, 0x00050080, 0x00000014, 0x00005FFA, 0x00002870, 0x000003FA, 0x000500C4, + 0x00000014, 0x00004F80, 0x00005FFA, 0x00000189, 0x000500C4, 0x00000014, 0x00003FA7, 0x00002A9E, + 0x0000008D, 0x000500C5, 0x00000014, 0x0000577D, 0x00004F80, 0x00003FA7, 0x000500AA, 0x00000010, + 0x00003601, 0x00005DE7, 0x00000A12, 0x000600A9, 0x00000014, 0x00004243, 0x00003601, 0x00000A12, + 0x0000577D, 0x0004007C, 0x00000018, 0x000029D0, 0x00004243, 0x000500C2, 0x0000000B, 0x00004BA5, + 0x000027F5, 0x00000A64, 0x00040070, 0x0000000D, 0x0000480F, 0x00004BA5, 0x00050085, 0x0000000D, + 0x00003E20, 0x0000480F, 0x00000149, 0x00050051, 0x0000000D, 0x000053C3, 0x000029D0, 0x00000000, + 0x00050051, 0x0000000D, 0x00002A56, 0x000029D0, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9A, + 0x000029D0, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDB, 0x000053C3, 0x00002A56, 0x00001E9A, + 0x00003E20, 0x00050051, 0x0000000B, 0x000027F6, 0x00002ABF, 0x00000002, 0x00060050, 0x00000014, + 0x0000350F, 0x000027F6, 0x000027F6, 0x000027F6, 0x000500C2, 0x00000014, 0x00002B0F, 0x0000350F, + 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DE8, 0x00002B0F, 0x00000105, 0x000500C7, 0x00000014, + 0x0000489E, 0x00005DE8, 0x00000466, 0x000500C2, 0x00000014, 0x00005B92, 0x00005DE8, 0x00000B0C, + 0x000500AA, 0x00000010, 0x000040CB, 0x00005B92, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4D, + 0x00000001, 0x0000004B, 0x0000489E, 0x0004007C, 0x00000014, 0x00002A17, 0x00002C4D, 0x00050082, + 0x00000014, 0x0000187C, 0x00000B0C, 0x00002A17, 0x00050080, 0x00000014, 0x00002212, 0x00002A17, + 0x00000938, 0x000600A9, 0x00000014, 0x00002871, 0x000040CB, 0x00002212, 0x00005B92, 0x000500C4, + 0x00000014, 0x00005AD6, 0x0000489E, 0x0000187C, 0x000500C7, 0x00000014, 0x0000499C, 0x00005AD6, + 0x00000466, 0x000600A9, 0x00000014, 0x00002A9F, 0x000040CB, 0x0000499C, 0x0000489E, 0x00050080, + 0x00000014, 0x00005FFB, 0x00002871, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F81, 0x00005FFB, + 0x00000189, 0x000500C4, 0x00000014, 0x00003FA8, 0x00002A9F, 0x0000008D, 0x000500C5, 0x00000014, + 0x0000577E, 0x00004F81, 0x00003FA8, 0x000500AA, 0x00000010, 0x00003602, 0x00005DE8, 0x00000A12, + 0x000600A9, 0x00000014, 0x00004244, 0x00003602, 0x00000A12, 0x0000577E, 0x0004007C, 0x00000018, + 0x000029D1, 0x00004244, 0x000500C2, 0x0000000B, 0x00004BA6, 0x000027F6, 0x00000A64, 0x00040070, + 0x0000000D, 0x00004810, 0x00004BA6, 0x00050085, 0x0000000D, 0x00003E21, 0x00004810, 0x00000149, + 0x00050051, 0x0000000D, 0x000053C4, 0x000029D1, 0x00000000, 0x00050051, 0x0000000D, 0x00002A57, + 0x000029D1, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9B, 0x000029D1, 0x00000002, 0x00070050, + 0x0000001D, 0x00003DDC, 0x000053C4, 0x00002A57, 0x00001E9B, 0x00003E21, 0x00050051, 0x0000000B, + 0x000027F7, 0x00002ABF, 0x00000003, 0x00060050, 0x00000014, 0x00003510, 0x000027F7, 0x000027F7, + 0x000027F7, 0x000500C2, 0x00000014, 0x00002B10, 0x00003510, 0x00000BB4, 0x000500C7, 0x00000014, + 0x00005DE9, 0x00002B10, 0x00000105, 0x000500C7, 0x00000014, 0x0000489F, 0x00005DE9, 0x00000466, + 0x000500C2, 0x00000014, 0x00005B93, 0x00005DE9, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CC, + 0x00005B93, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C4E, 0x00000001, 0x0000004B, 0x0000489F, + 0x0004007C, 0x00000014, 0x00002A18, 0x00002C4E, 0x00050082, 0x00000014, 0x0000187D, 0x00000B0C, + 0x00002A18, 0x00050080, 0x00000014, 0x00002213, 0x00002A18, 0x00000938, 0x000600A9, 0x00000014, + 0x00002872, 0x000040CC, 0x00002213, 0x00005B93, 0x000500C4, 0x00000014, 0x00005AD7, 0x0000489F, + 0x0000187D, 0x000500C7, 0x00000014, 0x0000499D, 0x00005AD7, 0x00000466, 0x000600A9, 0x00000014, + 0x00002AA0, 0x000040CC, 0x0000499D, 0x0000489F, 0x00050080, 0x00000014, 0x00005FFC, 0x00002872, + 0x000003FA, 0x000500C4, 0x00000014, 0x00004F82, 0x00005FFC, 0x00000189, 0x000500C4, 0x00000014, + 0x00003FA9, 0x00002AA0, 0x0000008D, 0x000500C5, 0x00000014, 0x0000577F, 0x00004F82, 0x00003FA9, + 0x000500AA, 0x00000010, 0x00003603, 0x00005DE9, 0x00000A12, 0x000600A9, 0x00000014, 0x00004245, + 0x00003603, 0x00000A12, 0x0000577F, 0x0004007C, 0x00000018, 0x000029D2, 0x00004245, 0x000500C2, + 0x0000000B, 0x00004BA7, 0x000027F7, 0x00000A64, 0x00040070, 0x0000000D, 0x00004811, 0x00004BA7, + 0x00050085, 0x0000000D, 0x00003E22, 0x00004811, 0x00000149, 0x00050051, 0x0000000D, 0x000053C5, + 0x000029D2, 0x00000000, 0x00050051, 0x0000000D, 0x00002A58, 0x000029D2, 0x00000001, 0x00050051, + 0x0000000D, 0x00002B11, 0x000029D2, 0x00000002, 0x00070050, 0x0000001D, 0x0000234B, 0x000053C5, + 0x00002A58, 0x00002B11, 0x00003E22, 0x000200F9, 0x00003F60, 0x000200F8, 0x00001CBB, 0x00050051, + 0x0000000B, 0x000056BE, 0x00002ABF, 0x00000000, 0x00070050, 0x00000017, 0x00004F0B, 0x000056BE, + 0x000056BE, 0x000056BE, 0x000056BE, 0x000500C2, 0x00000017, 0x00002498, 0x00004F0B, 0x0000034D, + 0x000500C7, 0x00000017, 0x000049AB, 0x00002498, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CB7, + 0x000049AB, 0x00050085, 0x0000001D, 0x00004130, 0x00003CB7, 0x00000AEE, 0x00050051, 0x0000000B, + 0x00005CD2, 0x00002ABF, 0x00000001, 0x00070050, 0x00000017, 0x0000514D, 0x00005CD2, 0x00005CD2, + 0x00005CD2, 0x00005CD2, 0x000500C2, 0x00000017, 0x00002499, 0x0000514D, 0x0000034D, 0x000500C7, + 0x00000017, 0x000049AC, 0x00002499, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CB8, 0x000049AC, + 0x00050085, 0x0000001D, 0x00004131, 0x00003CB8, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD3, + 0x00002ABF, 0x00000002, 0x00070050, 0x00000017, 0x0000514E, 0x00005CD3, 0x00005CD3, 0x00005CD3, + 0x00005CD3, 0x000500C2, 0x00000017, 0x0000249A, 0x0000514E, 0x0000034D, 0x000500C7, 0x00000017, + 0x000049AD, 0x0000249A, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CB9, 0x000049AD, 0x00050085, + 0x0000001D, 0x00004132, 0x00003CB9, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD4, 0x00002ABF, + 0x00000003, 0x00070050, 0x00000017, 0x0000514F, 0x00005CD4, 0x00005CD4, 0x00005CD4, 0x00005CD4, + 0x000500C2, 0x00000017, 0x0000249B, 0x0000514F, 0x0000034D, 0x000500C7, 0x00000017, 0x000049AE, + 0x0000249B, 0x0000027B, 0x00040070, 0x0000001D, 0x0000492F, 0x000049AE, 0x00050085, 0x0000001D, + 0x0000269F, 0x0000492F, 0x00000AEE, 0x000200F9, 0x00003F60, 0x000200F8, 0x000038F9, 0x00050051, + 0x0000000B, 0x000056BF, 0x00002ABF, 0x00000000, 0x00070050, 0x00000017, 0x00004F0C, 0x000056BF, + 0x000056BF, 0x000056BF, 0x000056BF, 0x000500C2, 0x00000017, 0x0000249C, 0x00004F0C, 0x0000028D, + 0x000500C7, 0x00000017, 0x00004A56, 0x0000249C, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A2, + 0x00004A56, 0x0005008E, 0x0000001D, 0x00004B23, 0x000036A2, 0x0000017A, 0x00050051, 0x0000000B, + 0x0000219F, 0x00002ABF, 0x00000001, 0x00070050, 0x00000017, 0x0000610B, 0x0000219F, 0x0000219F, + 0x0000219F, 0x0000219F, 0x000500C2, 0x00000017, 0x0000249D, 0x0000610B, 0x0000028D, 0x000500C7, + 0x00000017, 0x00004A57, 0x0000249D, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A3, 0x00004A57, + 0x0005008E, 0x0000001D, 0x00004B24, 0x000036A3, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A0, + 0x00002ABF, 0x00000002, 0x00070050, 0x00000017, 0x0000610C, 0x000021A0, 0x000021A0, 0x000021A0, + 0x000021A0, 0x000500C2, 0x00000017, 0x0000249E, 0x0000610C, 0x0000028D, 0x000500C7, 0x00000017, + 0x00004A58, 0x0000249E, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A4, 0x00004A58, 0x0005008E, + 0x0000001D, 0x00004B25, 0x000036A4, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A1, 0x00002ABF, + 0x00000003, 0x00070050, 0x00000017, 0x0000610D, 0x000021A1, 0x000021A1, 0x000021A1, 0x000021A1, + 0x000500C2, 0x00000017, 0x0000249F, 0x0000610D, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A59, + 0x0000249F, 0x0000064B, 0x00040070, 0x0000001D, 0x0000431A, 0x00004A59, 0x0005008E, 0x0000001D, + 0x00003092, 0x0000431A, 0x0000017A, 0x000200F9, 0x00003F60, 0x000200F8, 0x00004BFB, 0x00050051, + 0x0000000B, 0x0000308C, 0x00002ABF, 0x00000000, 0x0004007C, 0x0000000D, 0x00004FEE, 0x0000308C, + 0x00050050, 0x00000013, 0x00004336, 0x00004FEE, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D90, + 0x00004336, 0x00004336, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, + 0x000056B1, 0x00002ABF, 0x00000001, 0x0004007C, 0x0000000D, 0x00003F68, 0x000056B1, 0x00050050, + 0x00000013, 0x00004337, 0x00003F68, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D91, 0x00004337, + 0x00004337, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B2, + 0x00002ABF, 0x00000002, 0x0004007C, 0x0000000D, 0x00003F69, 0x000056B2, 0x00050050, 0x00000013, + 0x00004338, 0x00003F69, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D92, 0x00004338, 0x00004338, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B3, 0x00002ABF, + 0x00000003, 0x0004007C, 0x0000000D, 0x00003F6A, 0x000056B3, 0x00050050, 0x00000013, 0x00004FAE, + 0x00003F6A, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3A, 0x00004FAE, 0x00004FAE, 0x00000000, + 0x00000001, 0x00000001, 0x00000001, 0x000200F9, 0x00003F60, 0x000200F8, 0x00003F60, 0x000F00F5, + 0x0000001D, 0x00002BA7, 0x00005A3A, 0x00004BFB, 0x00003092, 0x000038F9, 0x0000269F, 0x00001CBB, + 0x0000234B, 0x00001CBA, 0x0000234A, 0x00001FFE, 0x00002349, 0x00002033, 0x000F00F5, 0x0000001D, + 0x00003808, 0x00002D92, 0x00004BFB, 0x00004B25, 0x000038F9, 0x00004132, 0x00001CBB, 0x00003DDC, + 0x00001CBA, 0x00004120, 0x00001FFE, 0x0000390E, 0x00002033, 0x000F00F5, 0x0000001D, 0x00003B7D, + 0x00002D91, 0x00004BFB, 0x00004B24, 0x000038F9, 0x00004131, 0x00001CBB, 0x00003DDB, 0x00001CBA, + 0x0000411F, 0x00001FFE, 0x0000390D, 0x00002033, 0x000F00F5, 0x0000001D, 0x000038B6, 0x00002D90, + 0x00004BFB, 0x00004B23, 0x000038F9, 0x00004130, 0x00001CBB, 0x00003DDA, 0x00001CBA, 0x0000411E, + 0x00001FFE, 0x0000390C, 0x00002033, 0x000200F9, 0x0000530F, 0x000200F8, 0x00003B65, 0x000500AA, + 0x00000009, 0x00005450, 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F23, 0x00000002, 0x000400FA, + 0x00005450, 0x00002622, 0x00002F62, 0x000200F8, 0x00002F62, 0x00060041, 0x00000288, 0x00004BD0, + 0x00000CC7, 0x00000A0B, 0x0000628F, 0x0004003D, 0x0000000B, 0x00005D45, 0x00004BD0, 0x00050080, + 0x0000000B, 0x00002DAB, 0x0000628F, 0x00000A0D, 0x00060041, 0x00000288, 0x00001901, 0x00000CC7, + 0x00000A0B, 0x00002DAB, 0x0004003D, 0x0000000B, 0x00005C64, 0x00001901, 0x00050080, 0x0000000B, + 0x00002DAC, 0x0000628F, 0x0000199B, 0x00060041, 0x00000288, 0x00001902, 0x00000CC7, 0x00000A0B, + 0x00002DAC, 0x0004003D, 0x0000000B, 0x00005C65, 0x00001902, 0x00050080, 0x0000000B, 0x00002DAD, + 0x00002DAC, 0x00000A0D, 0x00060041, 0x00000288, 0x00005FEF, 0x00000CC7, 0x00000A0B, 0x00002DAD, + 0x0004003D, 0x0000000B, 0x0000374C, 0x00005FEF, 0x00070050, 0x00000017, 0x00004CD6, 0x00005D45, + 0x00005C64, 0x00005C65, 0x0000374C, 0x00050084, 0x0000000B, 0x00004298, 0x00000A10, 0x0000199B, + 0x00050080, 0x0000000B, 0x000036A7, 0x0000628F, 0x00004298, 0x00060041, 0x00000288, 0x00003B81, + 0x00000CC7, 0x00000A0B, 0x000036A7, 0x0004003D, 0x0000000B, 0x00005C66, 0x00003B81, 0x00050080, + 0x0000000B, 0x00002DAE, 0x000036A7, 0x00000A0D, 0x00060041, 0x00000288, 0x0000194C, 0x00000CC7, + 0x00000A0B, 0x00002DAE, 0x0004003D, 0x0000000B, 0x00005E5D, 0x0000194C, 0x00050084, 0x0000000B, + 0x0000185C, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A3, 0x0000628F, 0x0000185C, + 0x00060041, 0x00000288, 0x00003B82, 0x00000CC7, 0x00000A0B, 0x000020A3, 0x0004003D, 0x0000000B, + 0x00005C67, 0x00003B82, 0x00050080, 0x0000000B, 0x00002DAF, 0x000020A3, 0x00000A0D, 0x00060041, + 0x00000288, 0x00005FF0, 0x00000CC7, 0x00000A0B, 0x00002DAF, 0x0004003D, 0x0000000B, 0x00003FFE, + 0x00005FF0, 0x00070050, 0x00000017, 0x0000512E, 0x00005C66, 0x00005E5D, 0x00005C67, 0x00003FFE, + 0x000200F9, 0x00004F23, 0x000200F8, 0x00002622, 0x00060041, 0x00000288, 0x00005546, 0x00000CC7, + 0x00000A0B, 0x0000628F, 0x0004003D, 0x0000000B, 0x00005D46, 0x00005546, 0x00050080, 0x0000000B, + 0x00002DB0, 0x0000628F, 0x00000A0D, 0x00060041, 0x00000288, 0x00001903, 0x00000CC7, 0x00000A0B, + 0x00002DB0, 0x0004003D, 0x0000000B, 0x00005C68, 0x00001903, 0x00050080, 0x0000000B, 0x00002DB1, + 0x0000628F, 0x00000A10, 0x00060041, 0x00000288, 0x00001904, 0x00000CC7, 0x00000A0B, 0x00002DB1, + 0x0004003D, 0x0000000B, 0x00005C69, 0x00001904, 0x00050080, 0x0000000B, 0x00002DB2, 0x0000628F, + 0x00000A13, 0x00060041, 0x00000288, 0x00005FF1, 0x00000CC7, 0x00000A0B, 0x00002DB2, 0x0004003D, + 0x0000000B, 0x00003700, 0x00005FF1, 0x00070050, 0x00000017, 0x00004ADD, 0x00005D46, 0x00005C68, + 0x00005C69, 0x00003700, 0x00050080, 0x0000000B, 0x000057E5, 0x0000628F, 0x00000A16, 0x00060041, + 0x00000288, 0x0000604B, 0x00000CC7, 0x00000A0B, 0x000057E5, 0x0004003D, 0x0000000B, 0x00005C6A, + 0x0000604B, 0x00050080, 0x0000000B, 0x00002DB3, 0x0000628F, 0x00000A19, 0x00060041, 0x00000288, + 0x00001905, 0x00000CC7, 0x00000A0B, 0x00002DB3, 0x0004003D, 0x0000000B, 0x00005C6B, 0x00001905, + 0x00050080, 0x0000000B, 0x00002DB4, 0x0000628F, 0x00000A1C, 0x00060041, 0x00000288, 0x00001906, + 0x00000CC7, 0x00000A0B, 0x00002DB4, 0x0004003D, 0x0000000B, 0x00005C6C, 0x00001906, 0x00050080, + 0x0000000B, 0x00002DB5, 0x0000628F, 0x00000A1F, 0x00060041, 0x00000288, 0x00005FF2, 0x00000CC7, + 0x00000A0B, 0x00002DB5, 0x0004003D, 0x0000000B, 0x00003FFF, 0x00005FF2, 0x00070050, 0x00000017, + 0x0000512F, 0x00005C6A, 0x00005C6B, 0x00005C6C, 0x00003FFF, 0x000200F9, 0x00004F23, 0x000200F8, + 0x00004F23, 0x000700F5, 0x00000017, 0x00002BCD, 0x0000512F, 0x00002622, 0x0000512E, 0x00002F62, + 0x000700F5, 0x00000017, 0x00003720, 0x00004ADD, 0x00002622, 0x00004CD6, 0x00002F62, 0x000300F7, + 0x00004F24, 0x00000000, 0x000700FB, 0x00002180, 0x00004F56, 0x00000005, 0x00002158, 0x00000007, + 0x00002034, 0x000200F8, 0x00002034, 0x00050051, 0x0000000B, 0x00005F57, 0x00003720, 0x00000000, + 0x0006000C, 0x00000013, 0x00006068, 0x00000001, 0x0000003E, 0x00005F57, 0x00050051, 0x0000000D, + 0x00002775, 0x00006068, 0x00000000, 0x00050051, 0x0000000D, 0x00003EB8, 0x00006068, 0x00000001, + 0x00050051, 0x0000000B, 0x00004281, 0x00003720, 0x00000001, 0x0006000C, 0x00000013, 0x00003CF5, + 0x00000001, 0x0000003E, 0x00004281, 0x00050051, 0x0000000D, 0x00002766, 0x00003CF5, 0x00000000, + 0x00050051, 0x0000000D, 0x00004449, 0x00003CF5, 0x00000001, 0x00070050, 0x0000001D, 0x0000390F, + 0x00002775, 0x00003EB8, 0x00002766, 0x00004449, 0x00050051, 0x0000000B, 0x0000437D, 0x00003720, + 0x00000002, 0x0006000C, 0x00000013, 0x0000466E, 0x00000001, 0x0000003E, 0x0000437D, 0x00050051, + 0x0000000D, 0x00002776, 0x0000466E, 0x00000000, 0x00050051, 0x0000000D, 0x00003EB9, 0x0000466E, + 0x00000001, 0x00050051, 0x0000000B, 0x00004282, 0x00003720, 0x00000003, 0x0006000C, 0x00000013, + 0x00003CF6, 0x00000001, 0x0000003E, 0x00004282, 0x00050051, 0x0000000D, 0x00002767, 0x00003CF6, + 0x00000000, 0x00050051, 0x0000000D, 0x0000444A, 0x00003CF6, 0x00000001, 0x00070050, 0x0000001D, + 0x00003910, 0x00002776, 0x00003EB9, 0x00002767, 0x0000444A, 0x00050051, 0x0000000B, 0x0000437E, + 0x00002BCD, 0x00000000, 0x0006000C, 0x00000013, 0x0000466F, 0x00000001, 0x0000003E, 0x0000437E, + 0x00050051, 0x0000000D, 0x00002777, 0x0000466F, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBA, + 0x0000466F, 0x00000001, 0x00050051, 0x0000000B, 0x00004283, 0x00002BCD, 0x00000001, 0x0006000C, + 0x00000013, 0x00003CF7, 0x00000001, 0x0000003E, 0x00004283, 0x00050051, 0x0000000D, 0x00002768, + 0x00003CF7, 0x00000000, 0x00050051, 0x0000000D, 0x0000444B, 0x00003CF7, 0x00000001, 0x00070050, + 0x0000001D, 0x00003911, 0x00002777, 0x00003EBA, 0x00002768, 0x0000444B, 0x00050051, 0x0000000B, + 0x0000437F, 0x00002BCD, 0x00000002, 0x0006000C, 0x00000013, 0x00004670, 0x00000001, 0x0000003E, + 0x0000437F, 0x00050051, 0x0000000D, 0x00002778, 0x00004670, 0x00000000, 0x00050051, 0x0000000D, + 0x00003EBB, 0x00004670, 0x00000001, 0x00050051, 0x0000000B, 0x00004284, 0x00002BCD, 0x00000003, + 0x0006000C, 0x00000013, 0x00003CF8, 0x00000001, 0x0000003E, 0x00004284, 0x00050051, 0x0000000D, + 0x00002769, 0x00003CF8, 0x00000000, 0x00050051, 0x0000000D, 0x000050BF, 0x00003CF8, 0x00000001, + 0x00070050, 0x0000001D, 0x0000234C, 0x00002778, 0x00003EBB, 0x00002769, 0x000050BF, 0x000200F9, + 0x00004F24, 0x000200F8, 0x00002158, 0x0007004F, 0x00000011, 0x000025FB, 0x00003720, 0x00003720, + 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x00005B3C, 0x000025FB, 0x0009004F, 0x0000001A, + 0x000060CE, 0x00005B3C, 0x00005B3C, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, + 0x0000001A, 0x000048A6, 0x000060CE, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D8D, 0x000048A6, + 0x00000302, 0x0004006F, 0x0000001D, 0x00002A9B, 0x00003D8D, 0x0005008E, 0x0000001D, 0x00004721, + 0x00002A9B, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006291, 0x00000001, 0x00000028, 0x00000504, + 0x00004721, 0x0007004F, 0x00000011, 0x0000376B, 0x00003720, 0x00003720, 0x00000002, 0x00000003, + 0x0004007C, 0x00000012, 0x000024BF, 0x0000376B, 0x0009004F, 0x0000001A, 0x000060CF, 0x000024BF, + 0x000024BF, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048A7, + 0x000060CF, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D8E, 0x000048A7, 0x00000302, 0x0004006F, + 0x0000001D, 0x00002A9C, 0x00003D8E, 0x0005008E, 0x0000001D, 0x00004722, 0x00002A9C, 0x000007FE, + 0x0007000C, 0x0000001D, 0x00006292, 0x00000001, 0x00000028, 0x00000504, 0x00004722, 0x0007004F, + 0x00000011, 0x0000376C, 0x00002BCD, 0x00002BCD, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, + 0x000024C0, 0x0000376C, 0x0009004F, 0x0000001A, 0x000060D0, 0x000024C0, 0x000024C0, 0x00000000, + 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048A8, 0x000060D0, 0x00000122, + 0x000500C3, 0x0000001A, 0x00003D8F, 0x000048A8, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA1, + 0x00003D8F, 0x0005008E, 0x0000001D, 0x00004723, 0x00002AA1, 0x000007FE, 0x0007000C, 0x0000001D, + 0x00006293, 0x00000001, 0x00000028, 0x00000504, 0x00004723, 0x0007004F, 0x00000011, 0x0000376D, + 0x00002BCD, 0x00002BCD, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C1, 0x0000376D, + 0x0009004F, 0x0000001A, 0x000060D1, 0x000024C1, 0x000024C1, 0x00000000, 0x00000000, 0x00000001, + 0x00000001, 0x000500C4, 0x0000001A, 0x000048A9, 0x000060D1, 0x00000122, 0x000500C3, 0x0000001A, + 0x00003D90, 0x000048A9, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA2, 0x00003D90, 0x0005008E, + 0x0000001D, 0x000053BF, 0x00002AA2, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004362, 0x00000001, + 0x00000028, 0x00000504, 0x000053BF, 0x000200F9, 0x00004F24, 0x000200F8, 0x00004F56, 0x0007004F, + 0x00000011, 0x00002623, 0x00003720, 0x00003720, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, + 0x00005159, 0x00002623, 0x00050051, 0x0000000D, 0x00001B7B, 0x00005159, 0x00000000, 0x00050051, + 0x0000000D, 0x0000346A, 0x00005159, 0x00000001, 0x00070050, 0x0000001D, 0x00004278, 0x00001B7B, + 0x0000346A, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041D8, 0x00003720, 0x00003720, + 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x0000375D, 0x000041D8, 0x00050051, 0x0000000D, + 0x00001B7C, 0x0000375D, 0x00000000, 0x00050051, 0x0000000D, 0x0000346B, 0x0000375D, 0x00000001, + 0x00070050, 0x0000001D, 0x00004279, 0x00001B7C, 0x0000346B, 0x00000A0C, 0x00000A0C, 0x0007004F, + 0x00000011, 0x000041D9, 0x00002BCD, 0x00002BCD, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, + 0x0000375E, 0x000041D9, 0x00050051, 0x0000000D, 0x00001B7D, 0x0000375E, 0x00000000, 0x00050051, + 0x0000000D, 0x0000346C, 0x0000375E, 0x00000001, 0x00070050, 0x0000001D, 0x0000427A, 0x00001B7D, + 0x0000346C, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DA, 0x00002BCD, 0x00002BCD, + 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x0000375F, 0x000041DA, 0x00050051, 0x0000000D, + 0x00001B7F, 0x0000375F, 0x00000000, 0x00050051, 0x0000000D, 0x00004108, 0x0000375F, 0x00000001, + 0x00070050, 0x0000001D, 0x0000234D, 0x00001B7F, 0x00004108, 0x00000A0C, 0x00000A0C, 0x000200F9, + 0x00004F24, 0x000200F8, 0x00004F24, 0x000900F5, 0x0000001D, 0x00002BA8, 0x0000234D, 0x00004F56, + 0x00004362, 0x00002158, 0x0000234C, 0x00002034, 0x000900F5, 0x0000001D, 0x00003809, 0x0000427A, + 0x00004F56, 0x00006293, 0x00002158, 0x00003911, 0x00002034, 0x000900F5, 0x0000001D, 0x00003B7E, + 0x00004279, 0x00004F56, 0x00006292, 0x00002158, 0x00003910, 0x00002034, 0x000900F5, 0x0000001D, + 0x000038B7, 0x00004278, 0x00004F56, 0x00006291, 0x00002158, 0x0000390F, 0x00002034, 0x000200F9, + 0x0000530F, 0x000200F8, 0x0000530F, 0x000700F5, 0x0000001D, 0x00002BA9, 0x00002BA8, 0x00004F24, + 0x00002BA7, 0x00003F60, 0x000700F5, 0x0000001D, 0x0000380A, 0x00003809, 0x00004F24, 0x00003808, + 0x00003F60, 0x000700F5, 0x0000001D, 0x000035EC, 0x00003B7E, 0x00004F24, 0x00003B7D, 0x00003F60, + 0x000700F5, 0x0000001D, 0x000020D3, 0x000038B7, 0x00004F24, 0x000038B6, 0x00003F60, 0x000500AE, + 0x00000009, 0x00002E55, 0x00004356, 0x00000A16, 0x000300F7, 0x00005313, 0x00000002, 0x000400FA, + 0x00002E55, 0x000051F1, 0x00005313, 0x000200F8, 0x000051F1, 0x00050084, 0x0000000B, 0x00002B47, + 0x00000AFA, 0x0000229A, 0x00050085, 0x0000000D, 0x00005A1D, 0x00002B2C, 0x000000FC, 0x00050080, + 0x0000000B, 0x00001FB2, 0x0000628F, 0x00002B47, 0x000300F7, 0x00005310, 0x00000002, 0x000400FA, + 0x00005AEF, 0x00003B66, 0x000040BA, 0x000200F8, 0x000040BA, 0x000500AA, 0x00000009, 0x00004ADB, + 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F4A, 0x00000002, 0x000400FA, 0x00004ADB, 0x00002624, + 0x00002F63, 0x000200F8, 0x00002F63, 0x00060041, 0x00000288, 0x00004BD1, 0x00000CC7, 0x00000A0B, + 0x00001FB2, 0x0004003D, 0x0000000B, 0x00005D47, 0x00004BD1, 0x00050080, 0x0000000B, 0x00002DB6, + 0x00001FB2, 0x0000199B, 0x00060041, 0x00000288, 0x0000194D, 0x00000CC7, 0x00000A0B, 0x00002DB6, + 0x0004003D, 0x0000000B, 0x00005E5E, 0x0000194D, 0x00050084, 0x0000000B, 0x0000185D, 0x00000A10, + 0x0000199B, 0x00050080, 0x0000000B, 0x000020A4, 0x00001FB2, 0x0000185D, 0x00060041, 0x00000288, + 0x00003BCE, 0x00000CC7, 0x00000A0B, 0x000020A4, 0x0004003D, 0x0000000B, 0x00005E5F, 0x00003BCE, + 0x00050084, 0x0000000B, 0x0000185E, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A5, + 0x00001FB2, 0x0000185E, 0x00060041, 0x00000288, 0x000037F2, 0x00000CC7, 0x00000A0B, 0x000020A5, + 0x0004003D, 0x0000000B, 0x00004000, 0x000037F2, 0x00070050, 0x00000017, 0x00005130, 0x00005D47, + 0x00005E5E, 0x00005E5F, 0x00004000, 0x000200F9, 0x00004F4A, 0x000200F8, 0x00002624, 0x00060041, + 0x00000288, 0x00005547, 0x00000CC7, 0x00000A0B, 0x00001FB2, 0x0004003D, 0x0000000B, 0x00005D48, + 0x00005547, 0x00050080, 0x0000000B, 0x00002DB7, 0x00001FB2, 0x00000A0D, 0x00060041, 0x00000288, + 0x00001907, 0x00000CC7, 0x00000A0B, 0x00002DB7, 0x0004003D, 0x0000000B, 0x00005C6D, 0x00001907, + 0x00050080, 0x0000000B, 0x00002DB8, 0x00001FB2, 0x00000A10, 0x00060041, 0x00000288, 0x00001908, + 0x00000CC7, 0x00000A0B, 0x00002DB8, 0x0004003D, 0x0000000B, 0x00005C6E, 0x00001908, 0x00050080, + 0x0000000B, 0x00002DB9, 0x00001FB2, 0x00000A13, 0x00060041, 0x00000288, 0x00005FF3, 0x00000CC7, + 0x00000A0B, 0x00002DB9, 0x0004003D, 0x0000000B, 0x00004001, 0x00005FF3, 0x00070050, 0x00000017, + 0x00005131, 0x00005D48, 0x00005C6D, 0x00005C6E, 0x00004001, 0x000200F9, 0x00004F4A, 0x000200F8, + 0x00004F4A, 0x000700F5, 0x00000017, 0x00002AC0, 0x00005131, 0x00002624, 0x00005130, 0x00002F63, + 0x000300F7, 0x00003F61, 0x00000000, 0x001300FB, 0x00002180, 0x00004BFC, 0x00000000, 0x000038FA, + 0x00000001, 0x000038FA, 0x00000002, 0x00001CBD, 0x0000000A, 0x00001CBD, 0x00000003, 0x00001CBC, + 0x0000000C, 0x00001CBC, 0x00000004, 0x00001FFF, 0x00000006, 0x00002035, 0x000200F8, 0x00002035, + 0x00050051, 0x0000000B, 0x00005F58, 0x00002AC0, 0x00000000, 0x0006000C, 0x00000013, 0x00006069, + 0x00000001, 0x0000003E, 0x00005F58, 0x00050051, 0x0000000D, 0x0000276A, 0x00006069, 0x00000000, + 0x00050051, 0x0000000D, 0x0000444C, 0x00006069, 0x00000001, 0x00070050, 0x0000001D, 0x00003912, + 0x0000276A, 0x0000444C, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004380, 0x00002AC0, + 0x00000001, 0x0006000C, 0x00000013, 0x00004671, 0x00000001, 0x0000003E, 0x00004380, 0x00050051, + 0x0000000D, 0x0000276B, 0x00004671, 0x00000000, 0x00050051, 0x0000000D, 0x0000444D, 0x00004671, + 0x00000001, 0x00070050, 0x0000001D, 0x00003913, 0x0000276B, 0x0000444D, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x00004381, 0x00002AC0, 0x00000002, 0x0006000C, 0x00000013, 0x00004672, + 0x00000001, 0x0000003E, 0x00004381, 0x00050051, 0x0000000D, 0x0000276C, 0x00004672, 0x00000000, + 0x00050051, 0x0000000D, 0x0000444E, 0x00004672, 0x00000001, 0x00070050, 0x0000001D, 0x00003914, + 0x0000276C, 0x0000444E, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004382, 0x00002AC0, + 0x00000003, 0x0006000C, 0x00000013, 0x00004673, 0x00000001, 0x0000003E, 0x00004382, 0x00050051, + 0x0000000D, 0x0000276D, 0x00004673, 0x00000000, 0x00050051, 0x0000000D, 0x000050C0, 0x00004673, + 0x00000001, 0x00070050, 0x0000001D, 0x0000234E, 0x0000276D, 0x000050C0, 0x00000A0C, 0x00000A0C, + 0x000200F9, 0x00003F61, 0x000200F8, 0x00001FFF, 0x00050051, 0x0000000B, 0x0000308D, 0x00002AC0, + 0x00000000, 0x0004007C, 0x0000000C, 0x0000589E, 0x0000308D, 0x00050050, 0x00000012, 0x0000471E, + 0x0000589E, 0x0000589E, 0x000500C4, 0x00000012, 0x000047B1, 0x0000471E, 0x000007A7, 0x000500C3, + 0x00000012, 0x0000341B, 0x000047B1, 0x00000867, 0x0004006F, 0x00000013, 0x00002AA3, 0x0000341B, + 0x0005008E, 0x00000013, 0x0000474B, 0x00002AA3, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E0A, + 0x00000001, 0x00000028, 0x00000049, 0x0000474B, 0x00050051, 0x0000000D, 0x00005F0E, 0x00005E0A, + 0x00000000, 0x00050051, 0x0000000D, 0x00003CD7, 0x00005E0A, 0x00000001, 0x00070050, 0x0000001D, + 0x00004121, 0x00005F0E, 0x00003CD7, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C45, + 0x00002AC0, 0x00000001, 0x0004007C, 0x0000000C, 0x00003EA4, 0x00004C45, 0x00050050, 0x00000012, + 0x0000471F, 0x00003EA4, 0x00003EA4, 0x000500C4, 0x00000012, 0x000047B2, 0x0000471F, 0x000007A7, + 0x000500C3, 0x00000012, 0x0000341C, 0x000047B2, 0x00000867, 0x0004006F, 0x00000013, 0x00002AA4, + 0x0000341C, 0x0005008E, 0x00000013, 0x0000474C, 0x00002AA4, 0x000007FE, 0x0007000C, 0x00000013, + 0x00005E0B, 0x00000001, 0x00000028, 0x00000049, 0x0000474C, 0x00050051, 0x0000000D, 0x00005F0F, + 0x00005E0B, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD8, 0x00005E0B, 0x00000001, 0x00070050, + 0x0000001D, 0x00004122, 0x00005F0F, 0x00003CD8, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x00004C46, 0x00002AC0, 0x00000002, 0x0004007C, 0x0000000C, 0x00003EA5, 0x00004C46, 0x00050050, + 0x00000012, 0x00004720, 0x00003EA5, 0x00003EA5, 0x000500C4, 0x00000012, 0x000047B3, 0x00004720, + 0x000007A7, 0x000500C3, 0x00000012, 0x0000341D, 0x000047B3, 0x00000867, 0x0004006F, 0x00000013, + 0x00002AA5, 0x0000341D, 0x0005008E, 0x00000013, 0x0000474D, 0x00002AA5, 0x000007FE, 0x0007000C, + 0x00000013, 0x00005E0C, 0x00000001, 0x00000028, 0x00000049, 0x0000474D, 0x00050051, 0x0000000D, + 0x00005F10, 0x00005E0C, 0x00000000, 0x00050051, 0x0000000D, 0x00003CD9, 0x00005E0C, 0x00000001, + 0x00070050, 0x0000001D, 0x00004123, 0x00005F10, 0x00003CD9, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x00004C47, 0x00002AC0, 0x00000003, 0x0004007C, 0x0000000C, 0x00003EA6, 0x00004C47, + 0x00050050, 0x00000012, 0x00004724, 0x00003EA6, 0x00003EA6, 0x000500C4, 0x00000012, 0x000047B4, + 0x00004724, 0x000007A7, 0x000500C3, 0x00000012, 0x0000341E, 0x000047B4, 0x00000867, 0x0004006F, + 0x00000013, 0x00002AA6, 0x0000341E, 0x0005008E, 0x00000013, 0x0000474E, 0x00002AA6, 0x000007FE, + 0x0007000C, 0x00000013, 0x00005E0D, 0x00000001, 0x00000028, 0x00000049, 0x0000474E, 0x00050051, + 0x0000000D, 0x00005F11, 0x00005E0D, 0x00000000, 0x00050051, 0x0000000D, 0x0000494D, 0x00005E0D, + 0x00000001, 0x00070050, 0x0000001D, 0x0000234F, 0x00005F11, 0x0000494D, 0x00000A0C, 0x00000A0C, + 0x000200F9, 0x00003F61, 0x000200F8, 0x00001CBC, 0x00050051, 0x0000000B, 0x000056C0, 0x00002AC0, + 0x00000000, 0x00060050, 0x00000014, 0x00004F0D, 0x000056C0, 0x000056C0, 0x000056C0, 0x000500C2, + 0x00000014, 0x00002B12, 0x00004F0D, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEA, 0x00002B12, + 0x00000105, 0x000500C7, 0x00000014, 0x000048A0, 0x00005DEA, 0x00000466, 0x000500C2, 0x00000014, + 0x00005B94, 0x00005DEA, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CD, 0x00005B94, 0x00000A12, + 0x0006000C, 0x00000016, 0x00002C4F, 0x00000001, 0x0000004B, 0x000048A0, 0x0004007C, 0x00000014, + 0x00002A19, 0x00002C4F, 0x00050082, 0x00000014, 0x0000187E, 0x00000B0C, 0x00002A19, 0x00050080, + 0x00000014, 0x00002214, 0x00002A19, 0x00000938, 0x000600A9, 0x00000014, 0x00002873, 0x000040CD, + 0x00002214, 0x00005B94, 0x000500C4, 0x00000014, 0x00005AD8, 0x000048A0, 0x0000187E, 0x000500C7, + 0x00000014, 0x0000499E, 0x00005AD8, 0x00000466, 0x000600A9, 0x00000014, 0x00002AA7, 0x000040CD, + 0x0000499E, 0x000048A0, 0x00050080, 0x00000014, 0x00005FFD, 0x00002873, 0x000003FA, 0x000500C4, + 0x00000014, 0x00004F83, 0x00005FFD, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAA, 0x00002AA7, + 0x0000008D, 0x000500C5, 0x00000014, 0x00005780, 0x00004F83, 0x00003FAA, 0x000500AA, 0x00000010, + 0x00003604, 0x00005DEA, 0x00000A12, 0x000600A9, 0x00000014, 0x00004246, 0x00003604, 0x00000A12, + 0x00005780, 0x0004007C, 0x00000018, 0x000029D3, 0x00004246, 0x000500C2, 0x0000000B, 0x00004BA8, + 0x000056C0, 0x00000A64, 0x00040070, 0x0000000D, 0x00004812, 0x00004BA8, 0x00050085, 0x0000000D, + 0x00003E23, 0x00004812, 0x00000149, 0x00050051, 0x0000000D, 0x000053C6, 0x000029D3, 0x00000000, + 0x00050051, 0x0000000D, 0x00002A59, 0x000029D3, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9C, + 0x000029D3, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDD, 0x000053C6, 0x00002A59, 0x00001E9C, + 0x00003E23, 0x00050051, 0x0000000B, 0x000027F8, 0x00002AC0, 0x00000001, 0x00060050, 0x00000014, + 0x00003511, 0x000027F8, 0x000027F8, 0x000027F8, 0x000500C2, 0x00000014, 0x00002B13, 0x00003511, + 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEB, 0x00002B13, 0x00000105, 0x000500C7, 0x00000014, + 0x000048A1, 0x00005DEB, 0x00000466, 0x000500C2, 0x00000014, 0x00005B95, 0x00005DEB, 0x00000B0C, + 0x000500AA, 0x00000010, 0x000040CE, 0x00005B95, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C50, + 0x00000001, 0x0000004B, 0x000048A1, 0x0004007C, 0x00000014, 0x00002A1A, 0x00002C50, 0x00050082, + 0x00000014, 0x0000187F, 0x00000B0C, 0x00002A1A, 0x00050080, 0x00000014, 0x00002215, 0x00002A1A, + 0x00000938, 0x000600A9, 0x00000014, 0x00002874, 0x000040CE, 0x00002215, 0x00005B95, 0x000500C4, + 0x00000014, 0x00005AD9, 0x000048A1, 0x0000187F, 0x000500C7, 0x00000014, 0x0000499F, 0x00005AD9, + 0x00000466, 0x000600A9, 0x00000014, 0x00002AA8, 0x000040CE, 0x0000499F, 0x000048A1, 0x00050080, + 0x00000014, 0x00005FFE, 0x00002874, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F84, 0x00005FFE, + 0x00000189, 0x000500C4, 0x00000014, 0x00003FAB, 0x00002AA8, 0x0000008D, 0x000500C5, 0x00000014, + 0x00005781, 0x00004F84, 0x00003FAB, 0x000500AA, 0x00000010, 0x00003605, 0x00005DEB, 0x00000A12, + 0x000600A9, 0x00000014, 0x00004247, 0x00003605, 0x00000A12, 0x00005781, 0x0004007C, 0x00000018, + 0x000029D4, 0x00004247, 0x000500C2, 0x0000000B, 0x00004BA9, 0x000027F8, 0x00000A64, 0x00040070, + 0x0000000D, 0x00004813, 0x00004BA9, 0x00050085, 0x0000000D, 0x00003E24, 0x00004813, 0x00000149, + 0x00050051, 0x0000000D, 0x000053C7, 0x000029D4, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5A, + 0x000029D4, 0x00000001, 0x00050051, 0x0000000D, 0x00001E9D, 0x000029D4, 0x00000002, 0x00070050, + 0x0000001D, 0x00003DDE, 0x000053C7, 0x00002A5A, 0x00001E9D, 0x00003E24, 0x00050051, 0x0000000B, + 0x000027F9, 0x00002AC0, 0x00000002, 0x00060050, 0x00000014, 0x00003512, 0x000027F9, 0x000027F9, + 0x000027F9, 0x000500C2, 0x00000014, 0x00002B14, 0x00003512, 0x00000BB4, 0x000500C7, 0x00000014, + 0x00005DEC, 0x00002B14, 0x00000105, 0x000500C7, 0x00000014, 0x000048A2, 0x00005DEC, 0x00000466, + 0x000500C2, 0x00000014, 0x00005B96, 0x00005DEC, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040CF, + 0x00005B96, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C51, 0x00000001, 0x0000004B, 0x000048A2, + 0x0004007C, 0x00000014, 0x00002A1B, 0x00002C51, 0x00050082, 0x00000014, 0x00001880, 0x00000B0C, + 0x00002A1B, 0x00050080, 0x00000014, 0x00002216, 0x00002A1B, 0x00000938, 0x000600A9, 0x00000014, + 0x00002875, 0x000040CF, 0x00002216, 0x00005B96, 0x000500C4, 0x00000014, 0x00005ADA, 0x000048A2, + 0x00001880, 0x000500C7, 0x00000014, 0x000049A0, 0x00005ADA, 0x00000466, 0x000600A9, 0x00000014, + 0x00002AA9, 0x000040CF, 0x000049A0, 0x000048A2, 0x00050080, 0x00000014, 0x00005FFF, 0x00002875, + 0x000003FA, 0x000500C4, 0x00000014, 0x00004F85, 0x00005FFF, 0x00000189, 0x000500C4, 0x00000014, + 0x00003FAC, 0x00002AA9, 0x0000008D, 0x000500C5, 0x00000014, 0x00005782, 0x00004F85, 0x00003FAC, + 0x000500AA, 0x00000010, 0x00003606, 0x00005DEC, 0x00000A12, 0x000600A9, 0x00000014, 0x00004248, + 0x00003606, 0x00000A12, 0x00005782, 0x0004007C, 0x00000018, 0x000029D5, 0x00004248, 0x000500C2, + 0x0000000B, 0x00004BAA, 0x000027F9, 0x00000A64, 0x00040070, 0x0000000D, 0x00004814, 0x00004BAA, + 0x00050085, 0x0000000D, 0x00003E25, 0x00004814, 0x00000149, 0x00050051, 0x0000000D, 0x000053C8, + 0x000029D5, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5B, 0x000029D5, 0x00000001, 0x00050051, + 0x0000000D, 0x00001E9E, 0x000029D5, 0x00000002, 0x00070050, 0x0000001D, 0x00003DDF, 0x000053C8, + 0x00002A5B, 0x00001E9E, 0x00003E25, 0x00050051, 0x0000000B, 0x000027FA, 0x00002AC0, 0x00000003, + 0x00060050, 0x00000014, 0x00003513, 0x000027FA, 0x000027FA, 0x000027FA, 0x000500C2, 0x00000014, + 0x00002B15, 0x00003513, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DED, 0x00002B15, 0x00000105, + 0x000500C7, 0x00000014, 0x000048A3, 0x00005DED, 0x00000466, 0x000500C2, 0x00000014, 0x00005B97, + 0x00005DED, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D0, 0x00005B97, 0x00000A12, 0x0006000C, + 0x00000016, 0x00002C52, 0x00000001, 0x0000004B, 0x000048A3, 0x0004007C, 0x00000014, 0x00002A1C, + 0x00002C52, 0x00050082, 0x00000014, 0x00001881, 0x00000B0C, 0x00002A1C, 0x00050080, 0x00000014, + 0x00002217, 0x00002A1C, 0x00000938, 0x000600A9, 0x00000014, 0x00002876, 0x000040D0, 0x00002217, + 0x00005B97, 0x000500C4, 0x00000014, 0x00005ADB, 0x000048A3, 0x00001881, 0x000500C7, 0x00000014, + 0x000049A1, 0x00005ADB, 0x00000466, 0x000600A9, 0x00000014, 0x00002AAA, 0x000040D0, 0x000049A1, + 0x000048A3, 0x00050080, 0x00000014, 0x00006000, 0x00002876, 0x000003FA, 0x000500C4, 0x00000014, + 0x00004F86, 0x00006000, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAD, 0x00002AAA, 0x0000008D, + 0x000500C5, 0x00000014, 0x00005783, 0x00004F86, 0x00003FAD, 0x000500AA, 0x00000010, 0x00003607, + 0x00005DED, 0x00000A12, 0x000600A9, 0x00000014, 0x00004249, 0x00003607, 0x00000A12, 0x00005783, + 0x0004007C, 0x00000018, 0x000029D6, 0x00004249, 0x000500C2, 0x0000000B, 0x00004BAB, 0x000027FA, + 0x00000A64, 0x00040070, 0x0000000D, 0x00004815, 0x00004BAB, 0x00050085, 0x0000000D, 0x00003E26, + 0x00004815, 0x00000149, 0x00050051, 0x0000000D, 0x000053C9, 0x000029D6, 0x00000000, 0x00050051, + 0x0000000D, 0x00002A5C, 0x000029D6, 0x00000001, 0x00050051, 0x0000000D, 0x00002B16, 0x000029D6, + 0x00000002, 0x00070050, 0x0000001D, 0x00002350, 0x000053C9, 0x00002A5C, 0x00002B16, 0x00003E26, + 0x000200F9, 0x00003F61, 0x000200F8, 0x00001CBD, 0x00050051, 0x0000000B, 0x000056C1, 0x00002AC0, + 0x00000000, 0x00070050, 0x00000017, 0x00004F0E, 0x000056C1, 0x000056C1, 0x000056C1, 0x000056C1, + 0x000500C2, 0x00000017, 0x000024A0, 0x00004F0E, 0x0000034D, 0x000500C7, 0x00000017, 0x000049AF, + 0x000024A0, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBA, 0x000049AF, 0x00050085, 0x0000001D, + 0x00004133, 0x00003CBA, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD5, 0x00002AC0, 0x00000001, + 0x00070050, 0x00000017, 0x00005150, 0x00005CD5, 0x00005CD5, 0x00005CD5, 0x00005CD5, 0x000500C2, + 0x00000017, 0x000024A1, 0x00005150, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B0, 0x000024A1, + 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBB, 0x000049B0, 0x00050085, 0x0000001D, 0x00004134, + 0x00003CBB, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD6, 0x00002AC0, 0x00000002, 0x00070050, + 0x00000017, 0x00005151, 0x00005CD6, 0x00005CD6, 0x00005CD6, 0x00005CD6, 0x000500C2, 0x00000017, + 0x000024A2, 0x00005151, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B1, 0x000024A2, 0x0000027B, + 0x00040070, 0x0000001D, 0x00003CBC, 0x000049B1, 0x00050085, 0x0000001D, 0x00004135, 0x00003CBC, + 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD7, 0x00002AC0, 0x00000003, 0x00070050, 0x00000017, + 0x00005152, 0x00005CD7, 0x00005CD7, 0x00005CD7, 0x00005CD7, 0x000500C2, 0x00000017, 0x000024A3, + 0x00005152, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B2, 0x000024A3, 0x0000027B, 0x00040070, + 0x0000001D, 0x00004930, 0x000049B2, 0x00050085, 0x0000001D, 0x000026A0, 0x00004930, 0x00000AEE, + 0x000200F9, 0x00003F61, 0x000200F8, 0x000038FA, 0x00050051, 0x0000000B, 0x000056C2, 0x00002AC0, + 0x00000000, 0x00070050, 0x00000017, 0x00004F0F, 0x000056C2, 0x000056C2, 0x000056C2, 0x000056C2, + 0x000500C2, 0x00000017, 0x000024A4, 0x00004F0F, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5A, + 0x000024A4, 0x0000064B, 0x00040070, 0x0000001D, 0x000036A5, 0x00004A5A, 0x0005008E, 0x0000001D, + 0x00004B26, 0x000036A5, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A2, 0x00002AC0, 0x00000001, + 0x00070050, 0x00000017, 0x0000610E, 0x000021A2, 0x000021A2, 0x000021A2, 0x000021A2, 0x000500C2, + 0x00000017, 0x000024A5, 0x0000610E, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5B, 0x000024A5, + 0x0000064B, 0x00040070, 0x0000001D, 0x000036A6, 0x00004A5B, 0x0005008E, 0x0000001D, 0x00004B27, + 0x000036A6, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A3, 0x00002AC0, 0x00000002, 0x00070050, + 0x00000017, 0x0000610F, 0x000021A3, 0x000021A3, 0x000021A3, 0x000021A3, 0x000500C2, 0x00000017, + 0x000024A6, 0x0000610F, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5C, 0x000024A6, 0x0000064B, + 0x00040070, 0x0000001D, 0x000036A8, 0x00004A5C, 0x0005008E, 0x0000001D, 0x00004B28, 0x000036A8, + 0x0000017A, 0x00050051, 0x0000000B, 0x000021A4, 0x00002AC0, 0x00000003, 0x00070050, 0x00000017, + 0x00006110, 0x000021A4, 0x000021A4, 0x000021A4, 0x000021A4, 0x000500C2, 0x00000017, 0x000024A7, + 0x00006110, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5D, 0x000024A7, 0x0000064B, 0x00040070, + 0x0000001D, 0x0000431B, 0x00004A5D, 0x0005008E, 0x0000001D, 0x00003093, 0x0000431B, 0x0000017A, + 0x000200F9, 0x00003F61, 0x000200F8, 0x00004BFC, 0x00050051, 0x0000000B, 0x0000308E, 0x00002AC0, + 0x00000000, 0x0004007C, 0x0000000D, 0x00004FEF, 0x0000308E, 0x00050050, 0x00000013, 0x00004339, + 0x00004FEF, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D93, 0x00004339, 0x00004339, 0x00000000, + 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B4, 0x00002AC0, 0x00000001, + 0x0004007C, 0x0000000D, 0x00003F6B, 0x000056B4, 0x00050050, 0x00000013, 0x0000433A, 0x00003F6B, + 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D94, 0x0000433A, 0x0000433A, 0x00000000, 0x00000001, + 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B5, 0x00002AC0, 0x00000002, 0x0004007C, + 0x0000000D, 0x00003F6C, 0x000056B5, 0x00050050, 0x00000013, 0x0000433B, 0x00003F6C, 0x00000A0C, + 0x0009004F, 0x0000001D, 0x00002D95, 0x0000433B, 0x0000433B, 0x00000000, 0x00000001, 0x00000001, + 0x00000001, 0x00050051, 0x0000000B, 0x000056B6, 0x00002AC0, 0x00000003, 0x0004007C, 0x0000000D, + 0x00003F6D, 0x000056B6, 0x00050050, 0x00000013, 0x00004FAF, 0x00003F6D, 0x00000A0C, 0x0009004F, + 0x0000001D, 0x00005A3B, 0x00004FAF, 0x00004FAF, 0x00000000, 0x00000001, 0x00000001, 0x00000001, + 0x000200F9, 0x00003F61, 0x000200F8, 0x00003F61, 0x000F00F5, 0x0000001D, 0x00002BAA, 0x00005A3B, + 0x00004BFC, 0x00003093, 0x000038FA, 0x000026A0, 0x00001CBD, 0x00002350, 0x00001CBC, 0x0000234F, + 0x00001FFF, 0x0000234E, 0x00002035, 0x000F00F5, 0x0000001D, 0x0000380B, 0x00002D95, 0x00004BFC, + 0x00004B28, 0x000038FA, 0x00004135, 0x00001CBD, 0x00003DDF, 0x00001CBC, 0x00004123, 0x00001FFF, + 0x00003914, 0x00002035, 0x000F00F5, 0x0000001D, 0x00003B7F, 0x00002D94, 0x00004BFC, 0x00004B27, + 0x000038FA, 0x00004134, 0x00001CBD, 0x00003DDE, 0x00001CBC, 0x00004122, 0x00001FFF, 0x00003913, + 0x00002035, 0x000F00F5, 0x0000001D, 0x000038B8, 0x00002D93, 0x00004BFC, 0x00004B26, 0x000038FA, + 0x00004133, 0x00001CBD, 0x00003DDD, 0x00001CBC, 0x00004121, 0x00001FFF, 0x00003912, 0x00002035, + 0x000200F9, 0x00005310, 0x000200F8, 0x00003B66, 0x000500AA, 0x00000009, 0x00005451, 0x0000199B, + 0x00000A10, 0x000300F7, 0x00004F25, 0x00000002, 0x000400FA, 0x00005451, 0x00002625, 0x00002F64, + 0x000200F8, 0x00002F64, 0x00060041, 0x00000288, 0x00004BD2, 0x00000CC7, 0x00000A0B, 0x00001FB2, + 0x0004003D, 0x0000000B, 0x00005D49, 0x00004BD2, 0x00050080, 0x0000000B, 0x00002DBA, 0x00001FB2, + 0x00000A0D, 0x00060041, 0x00000288, 0x00001909, 0x00000CC7, 0x00000A0B, 0x00002DBA, 0x0004003D, + 0x0000000B, 0x00005C6F, 0x00001909, 0x00050080, 0x0000000B, 0x00002DBB, 0x00001FB2, 0x0000199B, + 0x00060041, 0x00000288, 0x0000190A, 0x00000CC7, 0x00000A0B, 0x00002DBB, 0x0004003D, 0x0000000B, + 0x00005C70, 0x0000190A, 0x00050080, 0x0000000B, 0x00002DBC, 0x00002DBB, 0x00000A0D, 0x00060041, + 0x00000288, 0x00005FF4, 0x00000CC7, 0x00000A0B, 0x00002DBC, 0x0004003D, 0x0000000B, 0x0000374D, + 0x00005FF4, 0x00070050, 0x00000017, 0x00004CD7, 0x00005D49, 0x00005C6F, 0x00005C70, 0x0000374D, + 0x00050084, 0x0000000B, 0x00004299, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000036A9, + 0x00001FB2, 0x00004299, 0x00060041, 0x00000288, 0x00003B83, 0x00000CC7, 0x00000A0B, 0x000036A9, + 0x0004003D, 0x0000000B, 0x00005C71, 0x00003B83, 0x00050080, 0x0000000B, 0x00002DBD, 0x000036A9, + 0x00000A0D, 0x00060041, 0x00000288, 0x0000194E, 0x00000CC7, 0x00000A0B, 0x00002DBD, 0x0004003D, + 0x0000000B, 0x00005E60, 0x0000194E, 0x00050084, 0x0000000B, 0x0000185F, 0x00000A13, 0x0000199B, + 0x00050080, 0x0000000B, 0x000020A6, 0x00001FB2, 0x0000185F, 0x00060041, 0x00000288, 0x00003B84, + 0x00000CC7, 0x00000A0B, 0x000020A6, 0x0004003D, 0x0000000B, 0x00005C72, 0x00003B84, 0x00050080, + 0x0000000B, 0x00002DBE, 0x000020A6, 0x00000A0D, 0x00060041, 0x00000288, 0x00005FF5, 0x00000CC7, + 0x00000A0B, 0x00002DBE, 0x0004003D, 0x0000000B, 0x00004002, 0x00005FF5, 0x00070050, 0x00000017, + 0x00005132, 0x00005C71, 0x00005E60, 0x00005C72, 0x00004002, 0x000200F9, 0x00004F25, 0x000200F8, + 0x00002625, 0x00060041, 0x00000288, 0x00005548, 0x00000CC7, 0x00000A0B, 0x00001FB2, 0x0004003D, + 0x0000000B, 0x00005D4A, 0x00005548, 0x00050080, 0x0000000B, 0x00002DBF, 0x00001FB2, 0x00000A0D, + 0x00060041, 0x00000288, 0x0000190B, 0x00000CC7, 0x00000A0B, 0x00002DBF, 0x0004003D, 0x0000000B, + 0x00005C73, 0x0000190B, 0x00050080, 0x0000000B, 0x00002DC0, 0x00001FB2, 0x00000A10, 0x00060041, + 0x00000288, 0x0000190C, 0x00000CC7, 0x00000A0B, 0x00002DC0, 0x0004003D, 0x0000000B, 0x00005C74, + 0x0000190C, 0x00050080, 0x0000000B, 0x00002DC1, 0x00001FB2, 0x00000A13, 0x00060041, 0x00000288, + 0x00005FF6, 0x00000CC7, 0x00000A0B, 0x00002DC1, 0x0004003D, 0x0000000B, 0x00003701, 0x00005FF6, + 0x00070050, 0x00000017, 0x00004ADE, 0x00005D4A, 0x00005C73, 0x00005C74, 0x00003701, 0x00050080, + 0x0000000B, 0x000057E6, 0x00001FB2, 0x00000A16, 0x00060041, 0x00000288, 0x0000604C, 0x00000CC7, + 0x00000A0B, 0x000057E6, 0x0004003D, 0x0000000B, 0x00005C75, 0x0000604C, 0x00050080, 0x0000000B, + 0x00002DC2, 0x00001FB2, 0x00000A19, 0x00060041, 0x00000288, 0x0000190D, 0x00000CC7, 0x00000A0B, + 0x00002DC2, 0x0004003D, 0x0000000B, 0x00005C76, 0x0000190D, 0x00050080, 0x0000000B, 0x00002DC3, + 0x00001FB2, 0x00000A1C, 0x00060041, 0x00000288, 0x0000190E, 0x00000CC7, 0x00000A0B, 0x00002DC3, + 0x0004003D, 0x0000000B, 0x00005C77, 0x0000190E, 0x00050080, 0x0000000B, 0x00002DC4, 0x00001FB2, + 0x00000A1F, 0x00060041, 0x00000288, 0x00005FF7, 0x00000CC7, 0x00000A0B, 0x00002DC4, 0x0004003D, + 0x0000000B, 0x00004003, 0x00005FF7, 0x00070050, 0x00000017, 0x00005133, 0x00005C75, 0x00005C76, + 0x00005C77, 0x00004003, 0x000200F9, 0x00004F25, 0x000200F8, 0x00004F25, 0x000700F5, 0x00000017, + 0x00002BCE, 0x00005133, 0x00002625, 0x00005132, 0x00002F64, 0x000700F5, 0x00000017, 0x00003721, + 0x00004ADE, 0x00002625, 0x00004CD7, 0x00002F64, 0x000300F7, 0x00004F26, 0x00000000, 0x000700FB, + 0x00002180, 0x00004F57, 0x00000005, 0x00002159, 0x00000007, 0x00002036, 0x000200F8, 0x00002036, + 0x00050051, 0x0000000B, 0x00005F59, 0x00003721, 0x00000000, 0x0006000C, 0x00000013, 0x0000606A, + 0x00000001, 0x0000003E, 0x00005F59, 0x00050051, 0x0000000D, 0x00002779, 0x0000606A, 0x00000000, + 0x00050051, 0x0000000D, 0x00003EBC, 0x0000606A, 0x00000001, 0x00050051, 0x0000000B, 0x00004285, + 0x00003721, 0x00000001, 0x0006000C, 0x00000013, 0x00003CF9, 0x00000001, 0x0000003E, 0x00004285, + 0x00050051, 0x0000000D, 0x0000276E, 0x00003CF9, 0x00000000, 0x00050051, 0x0000000D, 0x0000444F, + 0x00003CF9, 0x00000001, 0x00070050, 0x0000001D, 0x00003915, 0x00002779, 0x00003EBC, 0x0000276E, + 0x0000444F, 0x00050051, 0x0000000B, 0x00004383, 0x00003721, 0x00000002, 0x0006000C, 0x00000013, + 0x00004674, 0x00000001, 0x0000003E, 0x00004383, 0x00050051, 0x0000000D, 0x0000277A, 0x00004674, + 0x00000000, 0x00050051, 0x0000000D, 0x00003EBD, 0x00004674, 0x00000001, 0x00050051, 0x0000000B, + 0x00004286, 0x00003721, 0x00000003, 0x0006000C, 0x00000013, 0x00003CFA, 0x00000001, 0x0000003E, + 0x00004286, 0x00050051, 0x0000000D, 0x0000276F, 0x00003CFA, 0x00000000, 0x00050051, 0x0000000D, + 0x00004450, 0x00003CFA, 0x00000001, 0x00070050, 0x0000001D, 0x00003916, 0x0000277A, 0x00003EBD, + 0x0000276F, 0x00004450, 0x00050051, 0x0000000B, 0x00004384, 0x00002BCE, 0x00000000, 0x0006000C, + 0x00000013, 0x00004675, 0x00000001, 0x0000003E, 0x00004384, 0x00050051, 0x0000000D, 0x0000277B, + 0x00004675, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBE, 0x00004675, 0x00000001, 0x00050051, + 0x0000000B, 0x00004287, 0x00002BCE, 0x00000001, 0x0006000C, 0x00000013, 0x00003CFB, 0x00000001, + 0x0000003E, 0x00004287, 0x00050051, 0x0000000D, 0x00002770, 0x00003CFB, 0x00000000, 0x00050051, + 0x0000000D, 0x00004451, 0x00003CFB, 0x00000001, 0x00070050, 0x0000001D, 0x00003917, 0x0000277B, + 0x00003EBE, 0x00002770, 0x00004451, 0x00050051, 0x0000000B, 0x00004385, 0x00002BCE, 0x00000002, + 0x0006000C, 0x00000013, 0x00004676, 0x00000001, 0x0000003E, 0x00004385, 0x00050051, 0x0000000D, + 0x0000277C, 0x00004676, 0x00000000, 0x00050051, 0x0000000D, 0x00003EBF, 0x00004676, 0x00000001, + 0x00050051, 0x0000000B, 0x00004288, 0x00002BCE, 0x00000003, 0x0006000C, 0x00000013, 0x00003CFC, + 0x00000001, 0x0000003E, 0x00004288, 0x00050051, 0x0000000D, 0x00002771, 0x00003CFC, 0x00000000, + 0x00050051, 0x0000000D, 0x000050C1, 0x00003CFC, 0x00000001, 0x00070050, 0x0000001D, 0x00002351, + 0x0000277C, 0x00003EBF, 0x00002771, 0x000050C1, 0x000200F9, 0x00004F26, 0x000200F8, 0x00002159, + 0x0007004F, 0x00000011, 0x000025FC, 0x00003721, 0x00003721, 0x00000000, 0x00000001, 0x0004007C, + 0x00000012, 0x00005B3D, 0x000025FC, 0x0009004F, 0x0000001A, 0x000060D2, 0x00005B3D, 0x00005B3D, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048AA, 0x000060D2, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D91, 0x000048AA, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002AAB, 0x00003D91, 0x0005008E, 0x0000001D, 0x00004725, 0x00002AAB, 0x000007FE, 0x0007000C, + 0x0000001D, 0x00006294, 0x00000001, 0x00000028, 0x00000504, 0x00004725, 0x0007004F, 0x00000011, + 0x0000376E, 0x00003721, 0x00003721, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C2, + 0x0000376E, 0x0009004F, 0x0000001A, 0x000060D3, 0x000024C2, 0x000024C2, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048AB, 0x000060D3, 0x00000122, 0x000500C3, + 0x0000001A, 0x00003D92, 0x000048AB, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AAC, 0x00003D92, + 0x0005008E, 0x0000001D, 0x00004726, 0x00002AAC, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006295, + 0x00000001, 0x00000028, 0x00000504, 0x00004726, 0x0007004F, 0x00000011, 0x0000376F, 0x00002BCE, + 0x00002BCE, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000024C3, 0x0000376F, 0x0009004F, + 0x0000001A, 0x000060D4, 0x000024C3, 0x000024C3, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C4, 0x0000001A, 0x000048AC, 0x000060D4, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D93, + 0x000048AC, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AAD, 0x00003D93, 0x0005008E, 0x0000001D, + 0x00004727, 0x00002AAD, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006296, 0x00000001, 0x00000028, + 0x00000504, 0x00004727, 0x0007004F, 0x00000011, 0x00003770, 0x00002BCE, 0x00002BCE, 0x00000002, + 0x00000003, 0x0004007C, 0x00000012, 0x000024C4, 0x00003770, 0x0009004F, 0x0000001A, 0x000060D5, + 0x000024C4, 0x000024C4, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, + 0x000048AD, 0x000060D5, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D94, 0x000048AD, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002AAE, 0x00003D94, 0x0005008E, 0x0000001D, 0x000053C0, 0x00002AAE, + 0x000007FE, 0x0007000C, 0x0000001D, 0x00004363, 0x00000001, 0x00000028, 0x00000504, 0x000053C0, + 0x000200F9, 0x00004F26, 0x000200F8, 0x00004F57, 0x0007004F, 0x00000011, 0x00002626, 0x00003721, + 0x00003721, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x0000515A, 0x00002626, 0x00050051, + 0x0000000D, 0x00001B80, 0x0000515A, 0x00000000, 0x00050051, 0x0000000D, 0x0000346D, 0x0000515A, + 0x00000001, 0x00070050, 0x0000001D, 0x0000427B, 0x00001B80, 0x0000346D, 0x00000A0C, 0x00000A0C, + 0x0007004F, 0x00000011, 0x000041DB, 0x00003721, 0x00003721, 0x00000002, 0x00000003, 0x0004007C, + 0x00000013, 0x00003760, 0x000041DB, 0x00050051, 0x0000000D, 0x00001B81, 0x00003760, 0x00000000, + 0x00050051, 0x0000000D, 0x0000346E, 0x00003760, 0x00000001, 0x00070050, 0x0000001D, 0x0000427C, + 0x00001B81, 0x0000346E, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DC, 0x00002BCE, + 0x00002BCE, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x00003761, 0x000041DC, 0x00050051, + 0x0000000D, 0x00001B82, 0x00003761, 0x00000000, 0x00050051, 0x0000000D, 0x0000346F, 0x00003761, + 0x00000001, 0x00070050, 0x0000001D, 0x0000427D, 0x00001B82, 0x0000346F, 0x00000A0C, 0x00000A0C, + 0x0007004F, 0x00000011, 0x000041DD, 0x00002BCE, 0x00002BCE, 0x00000002, 0x00000003, 0x0004007C, + 0x00000013, 0x00003762, 0x000041DD, 0x00050051, 0x0000000D, 0x00001B83, 0x00003762, 0x00000000, + 0x00050051, 0x0000000D, 0x00004109, 0x00003762, 0x00000001, 0x00070050, 0x0000001D, 0x00002352, + 0x00001B83, 0x00004109, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F26, 0x000200F8, 0x00004F26, + 0x000900F5, 0x0000001D, 0x00002BAB, 0x00002352, 0x00004F57, 0x00004363, 0x00002159, 0x00002351, + 0x00002036, 0x000900F5, 0x0000001D, 0x0000380C, 0x0000427D, 0x00004F57, 0x00006296, 0x00002159, + 0x00003917, 0x00002036, 0x000900F5, 0x0000001D, 0x00003B80, 0x0000427C, 0x00004F57, 0x00006295, + 0x00002159, 0x00003916, 0x00002036, 0x000900F5, 0x0000001D, 0x000038B9, 0x0000427B, 0x00004F57, + 0x00006294, 0x00002159, 0x00003915, 0x00002036, 0x000200F9, 0x00005310, 0x000200F8, 0x00005310, + 0x000700F5, 0x0000001D, 0x00002BAC, 0x00002BAB, 0x00004F26, 0x00002BAA, 0x00003F61, 0x000700F5, + 0x0000001D, 0x0000380D, 0x0000380C, 0x00004F26, 0x0000380B, 0x00003F61, 0x000700F5, 0x0000001D, + 0x00003295, 0x00003B80, 0x00004F26, 0x00003B7F, 0x00003F61, 0x000700F5, 0x0000001D, 0x0000367A, + 0x000038B9, 0x00004F26, 0x000038B8, 0x00003F61, 0x00050081, 0x0000001D, 0x00004359, 0x000020D3, + 0x0000367A, 0x00050081, 0x0000001D, 0x00005B01, 0x000035EC, 0x00003295, 0x00050081, 0x0000001D, + 0x00001F92, 0x0000380A, 0x0000380D, 0x00050081, 0x0000001D, 0x00005113, 0x00002BA9, 0x00002BAC, + 0x000500AE, 0x00000009, 0x0000387D, 0x00004356, 0x00000A1C, 0x000300F7, 0x00005EC8, 0x00000002, + 0x000400FA, 0x0000387D, 0x000026B1, 0x00005EC8, 0x000200F8, 0x000026B1, 0x000500C4, 0x0000000B, + 0x000037B2, 0x00000A0D, 0x000023AA, 0x00050085, 0x0000000D, 0x00002F3A, 0x00002B2C, 0x0000016E, + 0x00050080, 0x0000000B, 0x000051FC, 0x0000628F, 0x000037B2, 0x000300F7, 0x00005311, 0x00000002, + 0x000400FA, 0x00005AEF, 0x00003B67, 0x000040BB, 0x000200F8, 0x000040BB, 0x000500AA, 0x00000009, + 0x00004ADF, 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F4B, 0x00000002, 0x000400FA, 0x00004ADF, + 0x00002627, 0x00002F65, 0x000200F8, 0x00002F65, 0x00060041, 0x00000288, 0x00004BD3, 0x00000CC7, + 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, 0x00005D4B, 0x00004BD3, 0x00050080, 0x0000000B, + 0x00002DC5, 0x000051FC, 0x0000199B, 0x00060041, 0x00000288, 0x0000194F, 0x00000CC7, 0x00000A0B, + 0x00002DC5, 0x0004003D, 0x0000000B, 0x00005E61, 0x0000194F, 0x00050084, 0x0000000B, 0x00001860, + 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000020A7, 0x000051FC, 0x00001860, 0x00060041, + 0x00000288, 0x00003BCF, 0x00000CC7, 0x00000A0B, 0x000020A7, 0x0004003D, 0x0000000B, 0x00005E62, + 0x00003BCF, 0x00050084, 0x0000000B, 0x00001861, 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, + 0x000020A8, 0x000051FC, 0x00001861, 0x00060041, 0x00000288, 0x000037F3, 0x00000CC7, 0x00000A0B, + 0x000020A8, 0x0004003D, 0x0000000B, 0x00004004, 0x000037F3, 0x00070050, 0x00000017, 0x00005134, + 0x00005D4B, 0x00005E61, 0x00005E62, 0x00004004, 0x000200F9, 0x00004F4B, 0x000200F8, 0x00002627, + 0x00060041, 0x00000288, 0x00005549, 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, + 0x00005D4C, 0x00005549, 0x00050080, 0x0000000B, 0x00002DC6, 0x000051FC, 0x00000A0D, 0x00060041, + 0x00000288, 0x0000190F, 0x00000CC7, 0x00000A0B, 0x00002DC6, 0x0004003D, 0x0000000B, 0x00005C78, + 0x0000190F, 0x00050080, 0x0000000B, 0x00002DC7, 0x000051FC, 0x00000A10, 0x00060041, 0x00000288, + 0x00001910, 0x00000CC7, 0x00000A0B, 0x00002DC7, 0x0004003D, 0x0000000B, 0x00005C79, 0x00001910, + 0x00050080, 0x0000000B, 0x00002DC8, 0x000051FC, 0x00000A13, 0x00060041, 0x00000288, 0x00005FF8, + 0x00000CC7, 0x00000A0B, 0x00002DC8, 0x0004003D, 0x0000000B, 0x00004005, 0x00005FF8, 0x00070050, + 0x00000017, 0x00005135, 0x00005D4C, 0x00005C78, 0x00005C79, 0x00004005, 0x000200F9, 0x00004F4B, + 0x000200F8, 0x00004F4B, 0x000700F5, 0x00000017, 0x00002AC1, 0x00005135, 0x00002627, 0x00005134, + 0x00002F65, 0x000300F7, 0x00003F62, 0x00000000, 0x001300FB, 0x00002180, 0x00004BFD, 0x00000000, + 0x000038FB, 0x00000001, 0x000038FB, 0x00000002, 0x00001CBF, 0x0000000A, 0x00001CBF, 0x00000003, + 0x00001CBE, 0x0000000C, 0x00001CBE, 0x00000004, 0x00002000, 0x00000006, 0x00002037, 0x000200F8, + 0x00002037, 0x00050051, 0x0000000B, 0x00005F5A, 0x00002AC1, 0x00000000, 0x0006000C, 0x00000013, + 0x0000606B, 0x00000001, 0x0000003E, 0x00005F5A, 0x00050051, 0x0000000D, 0x00002772, 0x0000606B, + 0x00000000, 0x00050051, 0x0000000D, 0x00004452, 0x0000606B, 0x00000001, 0x00070050, 0x0000001D, + 0x00003918, 0x00002772, 0x00004452, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004386, + 0x00002AC1, 0x00000001, 0x0006000C, 0x00000013, 0x00004677, 0x00000001, 0x0000003E, 0x00004386, + 0x00050051, 0x0000000D, 0x00002773, 0x00004677, 0x00000000, 0x00050051, 0x0000000D, 0x00004453, + 0x00004677, 0x00000001, 0x00070050, 0x0000001D, 0x00003919, 0x00002773, 0x00004453, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x00004387, 0x00002AC1, 0x00000002, 0x0006000C, 0x00000013, + 0x00004678, 0x00000001, 0x0000003E, 0x00004387, 0x00050051, 0x0000000D, 0x00002774, 0x00004678, + 0x00000000, 0x00050051, 0x0000000D, 0x00004454, 0x00004678, 0x00000001, 0x00070050, 0x0000001D, + 0x0000391A, 0x00002774, 0x00004454, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x00004388, + 0x00002AC1, 0x00000003, 0x0006000C, 0x00000013, 0x00004679, 0x00000001, 0x0000003E, 0x00004388, + 0x00050051, 0x0000000D, 0x0000277D, 0x00004679, 0x00000000, 0x00050051, 0x0000000D, 0x000050C2, + 0x00004679, 0x00000001, 0x00070050, 0x0000001D, 0x00002353, 0x0000277D, 0x000050C2, 0x00000A0C, + 0x00000A0C, 0x000200F9, 0x00003F62, 0x000200F8, 0x00002000, 0x00050051, 0x0000000B, 0x0000308F, + 0x00002AC1, 0x00000000, 0x0004007C, 0x0000000C, 0x0000589F, 0x0000308F, 0x00050050, 0x00000012, + 0x00004728, 0x0000589F, 0x0000589F, 0x000500C4, 0x00000012, 0x000047B5, 0x00004728, 0x000007A7, + 0x000500C3, 0x00000012, 0x0000341F, 0x000047B5, 0x00000867, 0x0004006F, 0x00000013, 0x00002AAF, + 0x0000341F, 0x0005008E, 0x00000013, 0x0000474F, 0x00002AAF, 0x000007FE, 0x0007000C, 0x00000013, + 0x00005E0E, 0x00000001, 0x00000028, 0x00000049, 0x0000474F, 0x00050051, 0x0000000D, 0x00005F12, + 0x00005E0E, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDA, 0x00005E0E, 0x00000001, 0x00070050, + 0x0000001D, 0x00004124, 0x00005F12, 0x00003CDA, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x00004C48, 0x00002AC1, 0x00000001, 0x0004007C, 0x0000000C, 0x00003EA7, 0x00004C48, 0x00050050, + 0x00000012, 0x00004729, 0x00003EA7, 0x00003EA7, 0x000500C4, 0x00000012, 0x000047B6, 0x00004729, + 0x000007A7, 0x000500C3, 0x00000012, 0x00003420, 0x000047B6, 0x00000867, 0x0004006F, 0x00000013, + 0x00002AB0, 0x00003420, 0x0005008E, 0x00000013, 0x00004750, 0x00002AB0, 0x000007FE, 0x0007000C, + 0x00000013, 0x00005E0F, 0x00000001, 0x00000028, 0x00000049, 0x00004750, 0x00050051, 0x0000000D, + 0x00005F13, 0x00005E0F, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDB, 0x00005E0F, 0x00000001, + 0x00070050, 0x0000001D, 0x00004125, 0x00005F13, 0x00003CDB, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x00004C49, 0x00002AC1, 0x00000002, 0x0004007C, 0x0000000C, 0x00003EA8, 0x00004C49, + 0x00050050, 0x00000012, 0x0000472A, 0x00003EA8, 0x00003EA8, 0x000500C4, 0x00000012, 0x000047B7, + 0x0000472A, 0x000007A7, 0x000500C3, 0x00000012, 0x00003421, 0x000047B7, 0x00000867, 0x0004006F, + 0x00000013, 0x00002AB1, 0x00003421, 0x0005008E, 0x00000013, 0x00004751, 0x00002AB1, 0x000007FE, + 0x0007000C, 0x00000013, 0x00005E10, 0x00000001, 0x00000028, 0x00000049, 0x00004751, 0x00050051, + 0x0000000D, 0x00005F14, 0x00005E10, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDC, 0x00005E10, + 0x00000001, 0x00070050, 0x0000001D, 0x00004126, 0x00005F14, 0x00003CDC, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x00004C4A, 0x00002AC1, 0x00000003, 0x0004007C, 0x0000000C, 0x00003EA9, + 0x00004C4A, 0x00050050, 0x00000012, 0x0000472B, 0x00003EA9, 0x00003EA9, 0x000500C4, 0x00000012, + 0x000047B8, 0x0000472B, 0x000007A7, 0x000500C3, 0x00000012, 0x00003422, 0x000047B8, 0x00000867, + 0x0004006F, 0x00000013, 0x00002AB2, 0x00003422, 0x0005008E, 0x00000013, 0x00004752, 0x00002AB2, + 0x000007FE, 0x0007000C, 0x00000013, 0x00005E11, 0x00000001, 0x00000028, 0x00000049, 0x00004752, + 0x00050051, 0x0000000D, 0x00005F15, 0x00005E11, 0x00000000, 0x00050051, 0x0000000D, 0x0000494E, + 0x00005E11, 0x00000001, 0x00070050, 0x0000001D, 0x00002354, 0x00005F15, 0x0000494E, 0x00000A0C, + 0x00000A0C, 0x000200F9, 0x00003F62, 0x000200F8, 0x00001CBE, 0x00050051, 0x0000000B, 0x000056C3, + 0x00002AC1, 0x00000000, 0x00060050, 0x00000014, 0x00004F10, 0x000056C3, 0x000056C3, 0x000056C3, + 0x000500C2, 0x00000014, 0x00002B17, 0x00004F10, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEE, + 0x00002B17, 0x00000105, 0x000500C7, 0x00000014, 0x000048A4, 0x00005DEE, 0x00000466, 0x000500C2, + 0x00000014, 0x00005B98, 0x00005DEE, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D1, 0x00005B98, + 0x00000A12, 0x0006000C, 0x00000016, 0x00002C53, 0x00000001, 0x0000004B, 0x000048A4, 0x0004007C, + 0x00000014, 0x00002A1D, 0x00002C53, 0x00050082, 0x00000014, 0x00001882, 0x00000B0C, 0x00002A1D, + 0x00050080, 0x00000014, 0x00002218, 0x00002A1D, 0x00000938, 0x000600A9, 0x00000014, 0x00002877, + 0x000040D1, 0x00002218, 0x00005B98, 0x000500C4, 0x00000014, 0x00005ADC, 0x000048A4, 0x00001882, + 0x000500C7, 0x00000014, 0x000049A2, 0x00005ADC, 0x00000466, 0x000600A9, 0x00000014, 0x00002AB3, + 0x000040D1, 0x000049A2, 0x000048A4, 0x00050080, 0x00000014, 0x00006001, 0x00002877, 0x000003FA, + 0x000500C4, 0x00000014, 0x00004F87, 0x00006001, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAE, + 0x00002AB3, 0x0000008D, 0x000500C5, 0x00000014, 0x00005784, 0x00004F87, 0x00003FAE, 0x000500AA, + 0x00000010, 0x00003608, 0x00005DEE, 0x00000A12, 0x000600A9, 0x00000014, 0x0000424A, 0x00003608, + 0x00000A12, 0x00005784, 0x0004007C, 0x00000018, 0x000029D7, 0x0000424A, 0x000500C2, 0x0000000B, + 0x00004BAC, 0x000056C3, 0x00000A64, 0x00040070, 0x0000000D, 0x00004816, 0x00004BAC, 0x00050085, + 0x0000000D, 0x00003E27, 0x00004816, 0x00000149, 0x00050051, 0x0000000D, 0x000053CA, 0x000029D7, + 0x00000000, 0x00050051, 0x0000000D, 0x00002A5D, 0x000029D7, 0x00000001, 0x00050051, 0x0000000D, + 0x00001E9F, 0x000029D7, 0x00000002, 0x00070050, 0x0000001D, 0x00003DE0, 0x000053CA, 0x00002A5D, + 0x00001E9F, 0x00003E27, 0x00050051, 0x0000000B, 0x000027FB, 0x00002AC1, 0x00000001, 0x00060050, + 0x00000014, 0x00003514, 0x000027FB, 0x000027FB, 0x000027FB, 0x000500C2, 0x00000014, 0x00002B18, + 0x00003514, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DEF, 0x00002B18, 0x00000105, 0x000500C7, + 0x00000014, 0x000048A5, 0x00005DEF, 0x00000466, 0x000500C2, 0x00000014, 0x00005B99, 0x00005DEF, + 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D2, 0x00005B99, 0x00000A12, 0x0006000C, 0x00000016, + 0x00002C54, 0x00000001, 0x0000004B, 0x000048A5, 0x0004007C, 0x00000014, 0x00002A1E, 0x00002C54, + 0x00050082, 0x00000014, 0x00001883, 0x00000B0C, 0x00002A1E, 0x00050080, 0x00000014, 0x00002219, + 0x00002A1E, 0x00000938, 0x000600A9, 0x00000014, 0x00002878, 0x000040D2, 0x00002219, 0x00005B99, + 0x000500C4, 0x00000014, 0x00005ADD, 0x000048A5, 0x00001883, 0x000500C7, 0x00000014, 0x000049A3, + 0x00005ADD, 0x00000466, 0x000600A9, 0x00000014, 0x00002AB4, 0x000040D2, 0x000049A3, 0x000048A5, + 0x00050080, 0x00000014, 0x00006002, 0x00002878, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F88, + 0x00006002, 0x00000189, 0x000500C4, 0x00000014, 0x00003FAF, 0x00002AB4, 0x0000008D, 0x000500C5, + 0x00000014, 0x00005785, 0x00004F88, 0x00003FAF, 0x000500AA, 0x00000010, 0x00003609, 0x00005DEF, + 0x00000A12, 0x000600A9, 0x00000014, 0x0000424B, 0x00003609, 0x00000A12, 0x00005785, 0x0004007C, + 0x00000018, 0x000029D8, 0x0000424B, 0x000500C2, 0x0000000B, 0x00004BAD, 0x000027FB, 0x00000A64, + 0x00040070, 0x0000000D, 0x00004817, 0x00004BAD, 0x00050085, 0x0000000D, 0x00003E28, 0x00004817, + 0x00000149, 0x00050051, 0x0000000D, 0x000053CB, 0x000029D8, 0x00000000, 0x00050051, 0x0000000D, + 0x00002A5E, 0x000029D8, 0x00000001, 0x00050051, 0x0000000D, 0x00001EA0, 0x000029D8, 0x00000002, + 0x00070050, 0x0000001D, 0x00003DE1, 0x000053CB, 0x00002A5E, 0x00001EA0, 0x00003E28, 0x00050051, + 0x0000000B, 0x000027FC, 0x00002AC1, 0x00000002, 0x00060050, 0x00000014, 0x00003515, 0x000027FC, + 0x000027FC, 0x000027FC, 0x000500C2, 0x00000014, 0x00002B19, 0x00003515, 0x00000BB4, 0x000500C7, + 0x00000014, 0x00005DF0, 0x00002B19, 0x00000105, 0x000500C7, 0x00000014, 0x000048AE, 0x00005DF0, + 0x00000466, 0x000500C2, 0x00000014, 0x00005B9A, 0x00005DF0, 0x00000B0C, 0x000500AA, 0x00000010, + 0x000040D3, 0x00005B9A, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C55, 0x00000001, 0x0000004B, + 0x000048AE, 0x0004007C, 0x00000014, 0x00002A1F, 0x00002C55, 0x00050082, 0x00000014, 0x00001884, + 0x00000B0C, 0x00002A1F, 0x00050080, 0x00000014, 0x0000221A, 0x00002A1F, 0x00000938, 0x000600A9, + 0x00000014, 0x00002879, 0x000040D3, 0x0000221A, 0x00005B9A, 0x000500C4, 0x00000014, 0x00005ADE, + 0x000048AE, 0x00001884, 0x000500C7, 0x00000014, 0x000049A4, 0x00005ADE, 0x00000466, 0x000600A9, + 0x00000014, 0x00002AB5, 0x000040D3, 0x000049A4, 0x000048AE, 0x00050080, 0x00000014, 0x00006003, + 0x00002879, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F89, 0x00006003, 0x00000189, 0x000500C4, + 0x00000014, 0x00003FB0, 0x00002AB5, 0x0000008D, 0x000500C5, 0x00000014, 0x00005786, 0x00004F89, + 0x00003FB0, 0x000500AA, 0x00000010, 0x0000360A, 0x00005DF0, 0x00000A12, 0x000600A9, 0x00000014, + 0x0000424C, 0x0000360A, 0x00000A12, 0x00005786, 0x0004007C, 0x00000018, 0x000029D9, 0x0000424C, + 0x000500C2, 0x0000000B, 0x00004BAE, 0x000027FC, 0x00000A64, 0x00040070, 0x0000000D, 0x00004818, + 0x00004BAE, 0x00050085, 0x0000000D, 0x00003E29, 0x00004818, 0x00000149, 0x00050051, 0x0000000D, + 0x000053CC, 0x000029D9, 0x00000000, 0x00050051, 0x0000000D, 0x00002A5F, 0x000029D9, 0x00000001, + 0x00050051, 0x0000000D, 0x00001EA1, 0x000029D9, 0x00000002, 0x00070050, 0x0000001D, 0x00003DE2, + 0x000053CC, 0x00002A5F, 0x00001EA1, 0x00003E29, 0x00050051, 0x0000000B, 0x000027FD, 0x00002AC1, + 0x00000003, 0x00060050, 0x00000014, 0x00003516, 0x000027FD, 0x000027FD, 0x000027FD, 0x000500C2, + 0x00000014, 0x00002B1A, 0x00003516, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF1, 0x00002B1A, + 0x00000105, 0x000500C7, 0x00000014, 0x000048AF, 0x00005DF1, 0x00000466, 0x000500C2, 0x00000014, + 0x00005B9B, 0x00005DF1, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D4, 0x00005B9B, 0x00000A12, + 0x0006000C, 0x00000016, 0x00002C56, 0x00000001, 0x0000004B, 0x000048AF, 0x0004007C, 0x00000014, + 0x00002A20, 0x00002C56, 0x00050082, 0x00000014, 0x00001885, 0x00000B0C, 0x00002A20, 0x00050080, + 0x00000014, 0x0000221B, 0x00002A20, 0x00000938, 0x000600A9, 0x00000014, 0x0000287A, 0x000040D4, + 0x0000221B, 0x00005B9B, 0x000500C4, 0x00000014, 0x00005ADF, 0x000048AF, 0x00001885, 0x000500C7, + 0x00000014, 0x000049A5, 0x00005ADF, 0x00000466, 0x000600A9, 0x00000014, 0x00002AB6, 0x000040D4, + 0x000049A5, 0x000048AF, 0x00050080, 0x00000014, 0x00006004, 0x0000287A, 0x000003FA, 0x000500C4, + 0x00000014, 0x00004F8A, 0x00006004, 0x00000189, 0x000500C4, 0x00000014, 0x00003FB1, 0x00002AB6, + 0x0000008D, 0x000500C5, 0x00000014, 0x00005787, 0x00004F8A, 0x00003FB1, 0x000500AA, 0x00000010, + 0x0000360B, 0x00005DF1, 0x00000A12, 0x000600A9, 0x00000014, 0x0000424D, 0x0000360B, 0x00000A12, + 0x00005787, 0x0004007C, 0x00000018, 0x000029DA, 0x0000424D, 0x000500C2, 0x0000000B, 0x00004BAF, + 0x000027FD, 0x00000A64, 0x00040070, 0x0000000D, 0x00004819, 0x00004BAF, 0x00050085, 0x0000000D, + 0x00003E2A, 0x00004819, 0x00000149, 0x00050051, 0x0000000D, 0x000053CD, 0x000029DA, 0x00000000, + 0x00050051, 0x0000000D, 0x00002A60, 0x000029DA, 0x00000001, 0x00050051, 0x0000000D, 0x00002B1B, + 0x000029DA, 0x00000002, 0x00070050, 0x0000001D, 0x00002355, 0x000053CD, 0x00002A60, 0x00002B1B, + 0x00003E2A, 0x000200F9, 0x00003F62, 0x000200F8, 0x00001CBF, 0x00050051, 0x0000000B, 0x000056C4, + 0x00002AC1, 0x00000000, 0x00070050, 0x00000017, 0x00004F11, 0x000056C4, 0x000056C4, 0x000056C4, + 0x000056C4, 0x000500C2, 0x00000017, 0x000024A8, 0x00004F11, 0x0000034D, 0x000500C7, 0x00000017, + 0x000049B3, 0x000024A8, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBD, 0x000049B3, 0x00050085, + 0x0000001D, 0x00004136, 0x00003CBD, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD8, 0x00002AC1, + 0x00000001, 0x00070050, 0x00000017, 0x00005153, 0x00005CD8, 0x00005CD8, 0x00005CD8, 0x00005CD8, + 0x000500C2, 0x00000017, 0x000024A9, 0x00005153, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B4, + 0x000024A9, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBE, 0x000049B4, 0x00050085, 0x0000001D, + 0x00004137, 0x00003CBE, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CD9, 0x00002AC1, 0x00000002, + 0x00070050, 0x00000017, 0x00005154, 0x00005CD9, 0x00005CD9, 0x00005CD9, 0x00005CD9, 0x000500C2, + 0x00000017, 0x000024AA, 0x00005154, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B5, 0x000024AA, + 0x0000027B, 0x00040070, 0x0000001D, 0x00003CBF, 0x000049B5, 0x00050085, 0x0000001D, 0x00004138, + 0x00003CBF, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CDA, 0x00002AC1, 0x00000003, 0x00070050, + 0x00000017, 0x00005155, 0x00005CDA, 0x00005CDA, 0x00005CDA, 0x00005CDA, 0x000500C2, 0x00000017, + 0x000024AB, 0x00005155, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B6, 0x000024AB, 0x0000027B, + 0x00040070, 0x0000001D, 0x00004931, 0x000049B6, 0x00050085, 0x0000001D, 0x000026A1, 0x00004931, + 0x00000AEE, 0x000200F9, 0x00003F62, 0x000200F8, 0x000038FB, 0x00050051, 0x0000000B, 0x000056C5, + 0x00002AC1, 0x00000000, 0x00070050, 0x00000017, 0x00004F12, 0x000056C5, 0x000056C5, 0x000056C5, + 0x000056C5, 0x000500C2, 0x00000017, 0x000024AC, 0x00004F12, 0x0000028D, 0x000500C7, 0x00000017, + 0x00004A5E, 0x000024AC, 0x0000064B, 0x00040070, 0x0000001D, 0x000036AA, 0x00004A5E, 0x0005008E, + 0x0000001D, 0x00004B29, 0x000036AA, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A5, 0x00002AC1, + 0x00000001, 0x00070050, 0x00000017, 0x00006111, 0x000021A5, 0x000021A5, 0x000021A5, 0x000021A5, + 0x000500C2, 0x00000017, 0x000024AD, 0x00006111, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A5F, + 0x000024AD, 0x0000064B, 0x00040070, 0x0000001D, 0x000036AB, 0x00004A5F, 0x0005008E, 0x0000001D, + 0x00004B2A, 0x000036AB, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A6, 0x00002AC1, 0x00000002, + 0x00070050, 0x00000017, 0x00006112, 0x000021A6, 0x000021A6, 0x000021A6, 0x000021A6, 0x000500C2, + 0x00000017, 0x000024AE, 0x00006112, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A60, 0x000024AE, + 0x0000064B, 0x00040070, 0x0000001D, 0x000036AC, 0x00004A60, 0x0005008E, 0x0000001D, 0x00004B2B, + 0x000036AC, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A7, 0x00002AC1, 0x00000003, 0x00070050, + 0x00000017, 0x00006113, 0x000021A7, 0x000021A7, 0x000021A7, 0x000021A7, 0x000500C2, 0x00000017, + 0x000024AF, 0x00006113, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A61, 0x000024AF, 0x0000064B, + 0x00040070, 0x0000001D, 0x0000431C, 0x00004A61, 0x0005008E, 0x0000001D, 0x00003094, 0x0000431C, + 0x0000017A, 0x000200F9, 0x00003F62, 0x000200F8, 0x00004BFD, 0x00050051, 0x0000000B, 0x00003090, + 0x00002AC1, 0x00000000, 0x0004007C, 0x0000000D, 0x00004FF0, 0x00003090, 0x00050050, 0x00000013, + 0x0000433C, 0x00004FF0, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D96, 0x0000433C, 0x0000433C, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B7, 0x00002AC1, + 0x00000001, 0x0004007C, 0x0000000D, 0x00003F6E, 0x000056B7, 0x00050050, 0x00000013, 0x0000433D, + 0x00003F6E, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D97, 0x0000433D, 0x0000433D, 0x00000000, + 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B8, 0x00002AC1, 0x00000002, + 0x0004007C, 0x0000000D, 0x00003F6F, 0x000056B8, 0x00050050, 0x00000013, 0x0000433E, 0x00003F6F, + 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D98, 0x0000433E, 0x0000433E, 0x00000000, 0x00000001, + 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056B9, 0x00002AC1, 0x00000003, 0x0004007C, + 0x0000000D, 0x00003F70, 0x000056B9, 0x00050050, 0x00000013, 0x00004FB0, 0x00003F70, 0x00000A0C, + 0x0009004F, 0x0000001D, 0x00005A3C, 0x00004FB0, 0x00004FB0, 0x00000000, 0x00000001, 0x00000001, + 0x00000001, 0x000200F9, 0x00003F62, 0x000200F8, 0x00003F62, 0x000F00F5, 0x0000001D, 0x00002BAD, + 0x00005A3C, 0x00004BFD, 0x00003094, 0x000038FB, 0x000026A1, 0x00001CBF, 0x00002355, 0x00001CBE, + 0x00002354, 0x00002000, 0x00002353, 0x00002037, 0x000F00F5, 0x0000001D, 0x0000380E, 0x00002D98, + 0x00004BFD, 0x00004B2B, 0x000038FB, 0x00004138, 0x00001CBF, 0x00003DE2, 0x00001CBE, 0x00004126, + 0x00002000, 0x0000391A, 0x00002037, 0x000F00F5, 0x0000001D, 0x00003B85, 0x00002D97, 0x00004BFD, + 0x00004B2A, 0x000038FB, 0x00004137, 0x00001CBF, 0x00003DE1, 0x00001CBE, 0x00004125, 0x00002000, + 0x00003919, 0x00002037, 0x000F00F5, 0x0000001D, 0x000038BA, 0x00002D96, 0x00004BFD, 0x00004B29, + 0x000038FB, 0x00004136, 0x00001CBF, 0x00003DE0, 0x00001CBE, 0x00004124, 0x00002000, 0x00003918, + 0x00002037, 0x000200F9, 0x00005311, 0x000200F8, 0x00003B67, 0x000500AA, 0x00000009, 0x00005452, + 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F27, 0x00000002, 0x000400FA, 0x00005452, 0x00002628, + 0x00002F66, 0x000200F8, 0x00002F66, 0x00060041, 0x00000288, 0x00004BD4, 0x00000CC7, 0x00000A0B, + 0x000051FC, 0x0004003D, 0x0000000B, 0x00005D4D, 0x00004BD4, 0x00050080, 0x0000000B, 0x00002DC9, + 0x000051FC, 0x00000A0D, 0x00060041, 0x00000288, 0x00001911, 0x00000CC7, 0x00000A0B, 0x00002DC9, + 0x0004003D, 0x0000000B, 0x00005C7A, 0x00001911, 0x00050080, 0x0000000B, 0x00002DCA, 0x000051FC, + 0x0000199B, 0x00060041, 0x00000288, 0x00001912, 0x00000CC7, 0x00000A0B, 0x00002DCA, 0x0004003D, + 0x0000000B, 0x00005C7B, 0x00001912, 0x00050080, 0x0000000B, 0x00002DCB, 0x00002DCA, 0x00000A0D, + 0x00060041, 0x00000288, 0x00006005, 0x00000CC7, 0x00000A0B, 0x00002DCB, 0x0004003D, 0x0000000B, + 0x0000374E, 0x00006005, 0x00070050, 0x00000017, 0x00004CD9, 0x00005D4D, 0x00005C7A, 0x00005C7B, + 0x0000374E, 0x00050084, 0x0000000B, 0x0000429A, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, + 0x000036AD, 0x000051FC, 0x0000429A, 0x00060041, 0x00000288, 0x00003B86, 0x00000CC7, 0x00000A0B, + 0x000036AD, 0x0004003D, 0x0000000B, 0x00005C7C, 0x00003B86, 0x00050080, 0x0000000B, 0x00002DCC, + 0x000036AD, 0x00000A0D, 0x00060041, 0x00000288, 0x00001950, 0x00000CC7, 0x00000A0B, 0x00002DCC, + 0x0004003D, 0x0000000B, 0x00005E63, 0x00001950, 0x00050084, 0x0000000B, 0x00001862, 0x00000A13, + 0x0000199B, 0x00050080, 0x0000000B, 0x000020A9, 0x000051FC, 0x00001862, 0x00060041, 0x00000288, + 0x00003B87, 0x00000CC7, 0x00000A0B, 0x000020A9, 0x0004003D, 0x0000000B, 0x00005C7D, 0x00003B87, + 0x00050080, 0x0000000B, 0x00002DCD, 0x000020A9, 0x00000A0D, 0x00060041, 0x00000288, 0x00006006, + 0x00000CC7, 0x00000A0B, 0x00002DCD, 0x0004003D, 0x0000000B, 0x00004006, 0x00006006, 0x00070050, + 0x00000017, 0x00005136, 0x00005C7C, 0x00005E63, 0x00005C7D, 0x00004006, 0x000200F9, 0x00004F27, + 0x000200F8, 0x00002628, 0x00060041, 0x00000288, 0x0000554A, 0x00000CC7, 0x00000A0B, 0x000051FC, + 0x0004003D, 0x0000000B, 0x00005D4E, 0x0000554A, 0x00050080, 0x0000000B, 0x00002DCE, 0x000051FC, + 0x00000A0D, 0x00060041, 0x00000288, 0x00001913, 0x00000CC7, 0x00000A0B, 0x00002DCE, 0x0004003D, + 0x0000000B, 0x00005C7E, 0x00001913, 0x00050080, 0x0000000B, 0x00002DCF, 0x000051FC, 0x00000A10, + 0x00060041, 0x00000288, 0x00001914, 0x00000CC7, 0x00000A0B, 0x00002DCF, 0x0004003D, 0x0000000B, + 0x00005C7F, 0x00001914, 0x00050080, 0x0000000B, 0x00002DD0, 0x000051FC, 0x00000A13, 0x00060041, + 0x00000288, 0x00006007, 0x00000CC7, 0x00000A0B, 0x00002DD0, 0x0004003D, 0x0000000B, 0x00003702, + 0x00006007, 0x00070050, 0x00000017, 0x00004AE0, 0x00005D4E, 0x00005C7E, 0x00005C7F, 0x00003702, + 0x00050080, 0x0000000B, 0x000057E7, 0x000051FC, 0x00000A16, 0x00060041, 0x00000288, 0x0000604D, + 0x00000CC7, 0x00000A0B, 0x000057E7, 0x0004003D, 0x0000000B, 0x00005C80, 0x0000604D, 0x00050080, + 0x0000000B, 0x00002DD1, 0x000051FC, 0x00000A19, 0x00060041, 0x00000288, 0x00001915, 0x00000CC7, + 0x00000A0B, 0x00002DD1, 0x0004003D, 0x0000000B, 0x00005C81, 0x00001915, 0x00050080, 0x0000000B, + 0x00002DD2, 0x000051FC, 0x00000A1C, 0x00060041, 0x00000288, 0x00001916, 0x00000CC7, 0x00000A0B, + 0x00002DD2, 0x0004003D, 0x0000000B, 0x00005C82, 0x00001916, 0x00050080, 0x0000000B, 0x00002DD3, + 0x000051FC, 0x00000A1F, 0x00060041, 0x00000288, 0x00006008, 0x00000CC7, 0x00000A0B, 0x00002DD3, + 0x0004003D, 0x0000000B, 0x00004007, 0x00006008, 0x00070050, 0x00000017, 0x00005137, 0x00005C80, + 0x00005C81, 0x00005C82, 0x00004007, 0x000200F9, 0x00004F27, 0x000200F8, 0x00004F27, 0x000700F5, + 0x00000017, 0x00002BCF, 0x00005137, 0x00002628, 0x00005136, 0x00002F66, 0x000700F5, 0x00000017, + 0x00003722, 0x00004AE0, 0x00002628, 0x00004CD9, 0x00002F66, 0x000300F7, 0x00004F28, 0x00000000, + 0x000700FB, 0x00002180, 0x00004F58, 0x00000005, 0x0000215A, 0x00000007, 0x00002038, 0x000200F8, + 0x00002038, 0x00050051, 0x0000000B, 0x00005F5B, 0x00003722, 0x00000000, 0x0006000C, 0x00000013, + 0x0000606C, 0x00000001, 0x0000003E, 0x00005F5B, 0x00050051, 0x0000000D, 0x0000277E, 0x0000606C, + 0x00000000, 0x00050051, 0x0000000D, 0x00003EC0, 0x0000606C, 0x00000001, 0x00050051, 0x0000000B, + 0x00004289, 0x00003722, 0x00000001, 0x0006000C, 0x00000013, 0x00003CFD, 0x00000001, 0x0000003E, + 0x00004289, 0x00050051, 0x0000000D, 0x0000277F, 0x00003CFD, 0x00000000, 0x00050051, 0x0000000D, + 0x00004455, 0x00003CFD, 0x00000001, 0x00070050, 0x0000001D, 0x0000391B, 0x0000277E, 0x00003EC0, + 0x0000277F, 0x00004455, 0x00050051, 0x0000000B, 0x00004389, 0x00003722, 0x00000002, 0x0006000C, + 0x00000013, 0x0000467A, 0x00000001, 0x0000003E, 0x00004389, 0x00050051, 0x0000000D, 0x00002780, + 0x0000467A, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC1, 0x0000467A, 0x00000001, 0x00050051, + 0x0000000B, 0x0000428A, 0x00003722, 0x00000003, 0x0006000C, 0x00000013, 0x00003CFE, 0x00000001, + 0x0000003E, 0x0000428A, 0x00050051, 0x0000000D, 0x00002781, 0x00003CFE, 0x00000000, 0x00050051, + 0x0000000D, 0x00004456, 0x00003CFE, 0x00000001, 0x00070050, 0x0000001D, 0x0000391C, 0x00002780, + 0x00003EC1, 0x00002781, 0x00004456, 0x00050051, 0x0000000B, 0x0000438A, 0x00002BCF, 0x00000000, + 0x0006000C, 0x00000013, 0x0000467B, 0x00000001, 0x0000003E, 0x0000438A, 0x00050051, 0x0000000D, + 0x00002782, 0x0000467B, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC2, 0x0000467B, 0x00000001, + 0x00050051, 0x0000000B, 0x0000428B, 0x00002BCF, 0x00000001, 0x0006000C, 0x00000013, 0x00003CFF, + 0x00000001, 0x0000003E, 0x0000428B, 0x00050051, 0x0000000D, 0x00002783, 0x00003CFF, 0x00000000, + 0x00050051, 0x0000000D, 0x00004457, 0x00003CFF, 0x00000001, 0x00070050, 0x0000001D, 0x0000391D, + 0x00002782, 0x00003EC2, 0x00002783, 0x00004457, 0x00050051, 0x0000000B, 0x0000438B, 0x00002BCF, + 0x00000002, 0x0006000C, 0x00000013, 0x0000467C, 0x00000001, 0x0000003E, 0x0000438B, 0x00050051, + 0x0000000D, 0x00002784, 0x0000467C, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC3, 0x0000467C, + 0x00000001, 0x00050051, 0x0000000B, 0x0000428C, 0x00002BCF, 0x00000003, 0x0006000C, 0x00000013, + 0x00003D00, 0x00000001, 0x0000003E, 0x0000428C, 0x00050051, 0x0000000D, 0x00002785, 0x00003D00, + 0x00000000, 0x00050051, 0x0000000D, 0x000050C3, 0x00003D00, 0x00000001, 0x00070050, 0x0000001D, + 0x00002356, 0x00002784, 0x00003EC3, 0x00002785, 0x000050C3, 0x000200F9, 0x00004F28, 0x000200F8, + 0x0000215A, 0x0007004F, 0x00000011, 0x000025FD, 0x00003722, 0x00003722, 0x00000000, 0x00000001, + 0x0004007C, 0x00000012, 0x00005B3E, 0x000025FD, 0x0009004F, 0x0000001A, 0x000060D6, 0x00005B3E, + 0x00005B3E, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048B0, + 0x000060D6, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D95, 0x000048B0, 0x00000302, 0x0004006F, + 0x0000001D, 0x00002AB7, 0x00003D95, 0x0005008E, 0x0000001D, 0x0000472C, 0x00002AB7, 0x000007FE, + 0x0007000C, 0x0000001D, 0x00006297, 0x00000001, 0x00000028, 0x00000504, 0x0000472C, 0x0007004F, + 0x00000011, 0x00003771, 0x00003722, 0x00003722, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, + 0x000024C5, 0x00003771, 0x0009004F, 0x0000001A, 0x000060D7, 0x000024C5, 0x000024C5, 0x00000000, + 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048B1, 0x000060D7, 0x00000122, + 0x000500C3, 0x0000001A, 0x00003D96, 0x000048B1, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AB8, + 0x00003D96, 0x0005008E, 0x0000001D, 0x0000472D, 0x00002AB8, 0x000007FE, 0x0007000C, 0x0000001D, + 0x00006298, 0x00000001, 0x00000028, 0x00000504, 0x0000472D, 0x0007004F, 0x00000011, 0x00003772, + 0x00002BCF, 0x00002BCF, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000024C6, 0x00003772, + 0x0009004F, 0x0000001A, 0x000060D8, 0x000024C6, 0x000024C6, 0x00000000, 0x00000000, 0x00000001, + 0x00000001, 0x000500C4, 0x0000001A, 0x000048B2, 0x000060D8, 0x00000122, 0x000500C3, 0x0000001A, + 0x00003D97, 0x000048B2, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AB9, 0x00003D97, 0x0005008E, + 0x0000001D, 0x0000472E, 0x00002AB9, 0x000007FE, 0x0007000C, 0x0000001D, 0x00006299, 0x00000001, + 0x00000028, 0x00000504, 0x0000472E, 0x0007004F, 0x00000011, 0x00003773, 0x00002BCF, 0x00002BCF, + 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024C7, 0x00003773, 0x0009004F, 0x0000001A, + 0x000060D9, 0x000024C7, 0x000024C7, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, + 0x0000001A, 0x000048B3, 0x000060D9, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D98, 0x000048B3, + 0x00000302, 0x0004006F, 0x0000001D, 0x00002ABA, 0x00003D98, 0x0005008E, 0x0000001D, 0x000053C1, + 0x00002ABA, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004364, 0x00000001, 0x00000028, 0x00000504, + 0x000053C1, 0x000200F9, 0x00004F28, 0x000200F8, 0x00004F58, 0x0007004F, 0x00000011, 0x00002629, + 0x00003722, 0x00003722, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x0000515B, 0x00002629, + 0x00050051, 0x0000000D, 0x00001B84, 0x0000515B, 0x00000000, 0x00050051, 0x0000000D, 0x00003470, + 0x0000515B, 0x00000001, 0x00070050, 0x0000001D, 0x0000427E, 0x00001B84, 0x00003470, 0x00000A0C, + 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DE, 0x00003722, 0x00003722, 0x00000002, 0x00000003, + 0x0004007C, 0x00000013, 0x00003763, 0x000041DE, 0x00050051, 0x0000000D, 0x00001B85, 0x00003763, + 0x00000000, 0x00050051, 0x0000000D, 0x00003471, 0x00003763, 0x00000001, 0x00070050, 0x0000001D, + 0x0000427F, 0x00001B85, 0x00003471, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041DF, + 0x00002BCF, 0x00002BCF, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x00003764, 0x000041DF, + 0x00050051, 0x0000000D, 0x00001B86, 0x00003764, 0x00000000, 0x00050051, 0x0000000D, 0x00003472, + 0x00003764, 0x00000001, 0x00070050, 0x0000001D, 0x00004280, 0x00001B86, 0x00003472, 0x00000A0C, + 0x00000A0C, 0x0007004F, 0x00000011, 0x000041E0, 0x00002BCF, 0x00002BCF, 0x00000002, 0x00000003, + 0x0004007C, 0x00000013, 0x00003765, 0x000041E0, 0x00050051, 0x0000000D, 0x00001B87, 0x00003765, + 0x00000000, 0x00050051, 0x0000000D, 0x0000410A, 0x00003765, 0x00000001, 0x00070050, 0x0000001D, + 0x00002357, 0x00001B87, 0x0000410A, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F28, 0x000200F8, + 0x00004F28, 0x000900F5, 0x0000001D, 0x00002BAE, 0x00002357, 0x00004F58, 0x00004364, 0x0000215A, + 0x00002356, 0x00002038, 0x000900F5, 0x0000001D, 0x0000380F, 0x00004280, 0x00004F58, 0x00006299, + 0x0000215A, 0x0000391D, 0x00002038, 0x000900F5, 0x0000001D, 0x00003B88, 0x0000427F, 0x00004F58, + 0x00006298, 0x0000215A, 0x0000391C, 0x00002038, 0x000900F5, 0x0000001D, 0x000038BB, 0x0000427E, + 0x00004F58, 0x00006297, 0x0000215A, 0x0000391B, 0x00002038, 0x000200F9, 0x00005311, 0x000200F8, + 0x00005311, 0x000700F5, 0x0000001D, 0x00002BAF, 0x00002BAE, 0x00004F28, 0x00002BAD, 0x00003F62, + 0x000700F5, 0x0000001D, 0x00003810, 0x0000380F, 0x00004F28, 0x0000380E, 0x00003F62, 0x000700F5, + 0x0000001D, 0x00003296, 0x00003B88, 0x00004F28, 0x00003B85, 0x00003F62, 0x000700F5, 0x0000001D, + 0x0000367B, 0x000038BB, 0x00004F28, 0x000038BA, 0x00003F62, 0x00050081, 0x0000001D, 0x0000435A, + 0x00004359, 0x0000367B, 0x00050081, 0x0000001D, 0x00005B02, 0x00005B01, 0x00003296, 0x00050081, + 0x0000001D, 0x00001C28, 0x00001F92, 0x00003810, 0x00050081, 0x0000001D, 0x000025AA, 0x00005113, + 0x00002BAF, 0x00050080, 0x0000000B, 0x00003FF8, 0x00001FB2, 0x000037B2, 0x000300F7, 0x00005312, + 0x00000002, 0x000400FA, 0x00005AEF, 0x00003B68, 0x000040BC, 0x000200F8, 0x000040BC, 0x000500AA, + 0x00000009, 0x00004AE1, 0x0000199B, 0x00000A0D, 0x000300F7, 0x00004F4C, 0x00000002, 0x000400FA, + 0x00004AE1, 0x0000262A, 0x00002F67, 0x000200F8, 0x00002F67, 0x00060041, 0x00000288, 0x00004BD5, + 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D4F, 0x00004BD5, 0x00050080, + 0x0000000B, 0x00002DD4, 0x00003FF8, 0x0000199B, 0x00060041, 0x00000288, 0x00001951, 0x00000CC7, + 0x00000A0B, 0x00002DD4, 0x0004003D, 0x0000000B, 0x00005E64, 0x00001951, 0x00050084, 0x0000000B, + 0x00001863, 0x00000A10, 0x0000199B, 0x00050080, 0x0000000B, 0x000020AA, 0x00003FF8, 0x00001863, + 0x00060041, 0x00000288, 0x00003BD0, 0x00000CC7, 0x00000A0B, 0x000020AA, 0x0004003D, 0x0000000B, + 0x00005E65, 0x00003BD0, 0x00050084, 0x0000000B, 0x00001864, 0x00000A13, 0x0000199B, 0x00050080, + 0x0000000B, 0x000020AB, 0x00003FF8, 0x00001864, 0x00060041, 0x00000288, 0x000037F4, 0x00000CC7, + 0x00000A0B, 0x000020AB, 0x0004003D, 0x0000000B, 0x00004008, 0x000037F4, 0x00070050, 0x00000017, + 0x00005138, 0x00005D4F, 0x00005E64, 0x00005E65, 0x00004008, 0x000200F9, 0x00004F4C, 0x000200F8, + 0x0000262A, 0x00060041, 0x00000288, 0x0000554B, 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, + 0x0000000B, 0x00005D50, 0x0000554B, 0x00050080, 0x0000000B, 0x00002DD5, 0x00003FF8, 0x00000A0D, + 0x00060041, 0x00000288, 0x00001917, 0x00000CC7, 0x00000A0B, 0x00002DD5, 0x0004003D, 0x0000000B, + 0x00005C83, 0x00001917, 0x00050080, 0x0000000B, 0x00002DD6, 0x00003FF8, 0x00000A10, 0x00060041, + 0x00000288, 0x00001918, 0x00000CC7, 0x00000A0B, 0x00002DD6, 0x0004003D, 0x0000000B, 0x00005C84, + 0x00001918, 0x00050080, 0x0000000B, 0x00002DD7, 0x00003FF8, 0x00000A13, 0x00060041, 0x00000288, + 0x00006009, 0x00000CC7, 0x00000A0B, 0x00002DD7, 0x0004003D, 0x0000000B, 0x00004009, 0x00006009, + 0x00070050, 0x00000017, 0x00005139, 0x00005D50, 0x00005C83, 0x00005C84, 0x00004009, 0x000200F9, + 0x00004F4C, 0x000200F8, 0x00004F4C, 0x000700F5, 0x00000017, 0x00002AC2, 0x00005139, 0x0000262A, + 0x00005138, 0x00002F67, 0x000300F7, 0x00003F63, 0x00000000, 0x001300FB, 0x00002180, 0x00004BFE, + 0x00000000, 0x000038FC, 0x00000001, 0x000038FC, 0x00000002, 0x00001CC1, 0x0000000A, 0x00001CC1, + 0x00000003, 0x00001CC0, 0x0000000C, 0x00001CC0, 0x00000004, 0x00002001, 0x00000006, 0x00002039, + 0x000200F8, 0x00002039, 0x00050051, 0x0000000B, 0x00005F5C, 0x00002AC2, 0x00000000, 0x0006000C, + 0x00000013, 0x0000606D, 0x00000001, 0x0000003E, 0x00005F5C, 0x00050051, 0x0000000D, 0x00002786, + 0x0000606D, 0x00000000, 0x00050051, 0x0000000D, 0x00004458, 0x0000606D, 0x00000001, 0x00070050, + 0x0000001D, 0x0000391E, 0x00002786, 0x00004458, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x0000438C, 0x00002AC2, 0x00000001, 0x0006000C, 0x00000013, 0x0000467D, 0x00000001, 0x0000003E, + 0x0000438C, 0x00050051, 0x0000000D, 0x00002787, 0x0000467D, 0x00000000, 0x00050051, 0x0000000D, + 0x00004459, 0x0000467D, 0x00000001, 0x00070050, 0x0000001D, 0x0000391F, 0x00002787, 0x00004459, + 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, 0x0000438D, 0x00002AC2, 0x00000002, 0x0006000C, + 0x00000013, 0x0000467E, 0x00000001, 0x0000003E, 0x0000438D, 0x00050051, 0x0000000D, 0x00002788, + 0x0000467E, 0x00000000, 0x00050051, 0x0000000D, 0x0000445A, 0x0000467E, 0x00000001, 0x00070050, + 0x0000001D, 0x00003920, 0x00002788, 0x0000445A, 0x00000A0C, 0x00000A0C, 0x00050051, 0x0000000B, + 0x0000438E, 0x00002AC2, 0x00000003, 0x0006000C, 0x00000013, 0x0000467F, 0x00000001, 0x0000003E, + 0x0000438E, 0x00050051, 0x0000000D, 0x00002789, 0x0000467F, 0x00000000, 0x00050051, 0x0000000D, + 0x000050C4, 0x0000467F, 0x00000001, 0x00070050, 0x0000001D, 0x00002358, 0x00002789, 0x000050C4, + 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F63, 0x000200F8, 0x00002001, 0x00050051, 0x0000000B, + 0x00003091, 0x00002AC2, 0x00000000, 0x0004007C, 0x0000000C, 0x000058A0, 0x00003091, 0x00050050, + 0x00000012, 0x0000472F, 0x000058A0, 0x000058A0, 0x000500C4, 0x00000012, 0x000047B9, 0x0000472F, + 0x000007A7, 0x000500C3, 0x00000012, 0x00003423, 0x000047B9, 0x00000867, 0x0004006F, 0x00000013, + 0x00002ABB, 0x00003423, 0x0005008E, 0x00000013, 0x00004753, 0x00002ABB, 0x000007FE, 0x0007000C, + 0x00000013, 0x00005E12, 0x00000001, 0x00000028, 0x00000049, 0x00004753, 0x00050051, 0x0000000D, + 0x00005F16, 0x00005E12, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDD, 0x00005E12, 0x00000001, + 0x00070050, 0x0000001D, 0x00004127, 0x00005F16, 0x00003CDD, 0x00000A0C, 0x00000A0C, 0x00050051, + 0x0000000B, 0x00004C4B, 0x00002AC2, 0x00000001, 0x0004007C, 0x0000000C, 0x00003EAA, 0x00004C4B, + 0x00050050, 0x00000012, 0x00004730, 0x00003EAA, 0x00003EAA, 0x000500C4, 0x00000012, 0x000047BA, + 0x00004730, 0x000007A7, 0x000500C3, 0x00000012, 0x00003424, 0x000047BA, 0x00000867, 0x0004006F, + 0x00000013, 0x00002ABC, 0x00003424, 0x0005008E, 0x00000013, 0x00004754, 0x00002ABC, 0x000007FE, + 0x0007000C, 0x00000013, 0x00005E13, 0x00000001, 0x00000028, 0x00000049, 0x00004754, 0x00050051, + 0x0000000D, 0x00005F17, 0x00005E13, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDE, 0x00005E13, + 0x00000001, 0x00070050, 0x0000001D, 0x00004128, 0x00005F17, 0x00003CDE, 0x00000A0C, 0x00000A0C, + 0x00050051, 0x0000000B, 0x00004C4C, 0x00002AC2, 0x00000002, 0x0004007C, 0x0000000C, 0x00003EAB, + 0x00004C4C, 0x00050050, 0x00000012, 0x00004731, 0x00003EAB, 0x00003EAB, 0x000500C4, 0x00000012, + 0x000047BC, 0x00004731, 0x000007A7, 0x000500C3, 0x00000012, 0x00003425, 0x000047BC, 0x00000867, + 0x0004006F, 0x00000013, 0x00002ABD, 0x00003425, 0x0005008E, 0x00000013, 0x00004755, 0x00002ABD, + 0x000007FE, 0x0007000C, 0x00000013, 0x00005E14, 0x00000001, 0x00000028, 0x00000049, 0x00004755, + 0x00050051, 0x0000000D, 0x00005F18, 0x00005E14, 0x00000000, 0x00050051, 0x0000000D, 0x00003CDF, + 0x00005E14, 0x00000001, 0x00070050, 0x0000001D, 0x00004129, 0x00005F18, 0x00003CDF, 0x00000A0C, + 0x00000A0C, 0x00050051, 0x0000000B, 0x00004C4D, 0x00002AC2, 0x00000003, 0x0004007C, 0x0000000C, + 0x00003EAC, 0x00004C4D, 0x00050050, 0x00000012, 0x00004732, 0x00003EAC, 0x00003EAC, 0x000500C4, + 0x00000012, 0x000047BD, 0x00004732, 0x000007A7, 0x000500C3, 0x00000012, 0x00003426, 0x000047BD, + 0x00000867, 0x0004006F, 0x00000013, 0x00002ABE, 0x00003426, 0x0005008E, 0x00000013, 0x00004756, + 0x00002ABE, 0x000007FE, 0x0007000C, 0x00000013, 0x00005E15, 0x00000001, 0x00000028, 0x00000049, + 0x00004756, 0x00050051, 0x0000000D, 0x00005F19, 0x00005E15, 0x00000000, 0x00050051, 0x0000000D, + 0x0000494F, 0x00005E15, 0x00000001, 0x00070050, 0x0000001D, 0x00002359, 0x00005F19, 0x0000494F, + 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00003F63, 0x000200F8, 0x00001CC0, 0x00050051, 0x0000000B, + 0x000056C6, 0x00002AC2, 0x00000000, 0x00060050, 0x00000014, 0x00004F13, 0x000056C6, 0x000056C6, + 0x000056C6, 0x000500C2, 0x00000014, 0x00002B1C, 0x00004F13, 0x00000BB4, 0x000500C7, 0x00000014, + 0x00005DF2, 0x00002B1C, 0x00000105, 0x000500C7, 0x00000014, 0x000048B4, 0x00005DF2, 0x00000466, + 0x000500C2, 0x00000014, 0x00005B9C, 0x00005DF2, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D5, + 0x00005B9C, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C57, 0x00000001, 0x0000004B, 0x000048B4, + 0x0004007C, 0x00000014, 0x00002A21, 0x00002C57, 0x00050082, 0x00000014, 0x00001886, 0x00000B0C, + 0x00002A21, 0x00050080, 0x00000014, 0x0000221C, 0x00002A21, 0x00000938, 0x000600A9, 0x00000014, + 0x0000287B, 0x000040D5, 0x0000221C, 0x00005B9C, 0x000500C4, 0x00000014, 0x00005AE0, 0x000048B4, + 0x00001886, 0x000500C7, 0x00000014, 0x000049A6, 0x00005AE0, 0x00000466, 0x000600A9, 0x00000014, + 0x00002AC3, 0x000040D5, 0x000049A6, 0x000048B4, 0x00050080, 0x00000014, 0x0000600A, 0x0000287B, + 0x000003FA, 0x000500C4, 0x00000014, 0x00004F8B, 0x0000600A, 0x00000189, 0x000500C4, 0x00000014, + 0x00003FB2, 0x00002AC3, 0x0000008D, 0x000500C5, 0x00000014, 0x00005788, 0x00004F8B, 0x00003FB2, + 0x000500AA, 0x00000010, 0x0000360C, 0x00005DF2, 0x00000A12, 0x000600A9, 0x00000014, 0x0000424E, + 0x0000360C, 0x00000A12, 0x00005788, 0x0004007C, 0x00000018, 0x000029DB, 0x0000424E, 0x000500C2, + 0x0000000B, 0x00004BB0, 0x000056C6, 0x00000A64, 0x00040070, 0x0000000D, 0x0000481A, 0x00004BB0, + 0x00050085, 0x0000000D, 0x00003E2B, 0x0000481A, 0x00000149, 0x00050051, 0x0000000D, 0x000053CE, + 0x000029DB, 0x00000000, 0x00050051, 0x0000000D, 0x00002A61, 0x000029DB, 0x00000001, 0x00050051, + 0x0000000D, 0x00001EA2, 0x000029DB, 0x00000002, 0x00070050, 0x0000001D, 0x00003DE3, 0x000053CE, + 0x00002A61, 0x00001EA2, 0x00003E2B, 0x00050051, 0x0000000B, 0x000027FE, 0x00002AC2, 0x00000001, + 0x00060050, 0x00000014, 0x00003517, 0x000027FE, 0x000027FE, 0x000027FE, 0x000500C2, 0x00000014, + 0x00002B1D, 0x00003517, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF3, 0x00002B1D, 0x00000105, + 0x000500C7, 0x00000014, 0x000048B5, 0x00005DF3, 0x00000466, 0x000500C2, 0x00000014, 0x00005B9D, + 0x00005DF3, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D6, 0x00005B9D, 0x00000A12, 0x0006000C, + 0x00000016, 0x00002C58, 0x00000001, 0x0000004B, 0x000048B5, 0x0004007C, 0x00000014, 0x00002A22, + 0x00002C58, 0x00050082, 0x00000014, 0x00001887, 0x00000B0C, 0x00002A22, 0x00050080, 0x00000014, + 0x0000221D, 0x00002A22, 0x00000938, 0x000600A9, 0x00000014, 0x0000287C, 0x000040D6, 0x0000221D, + 0x00005B9D, 0x000500C4, 0x00000014, 0x00005AE1, 0x000048B5, 0x00001887, 0x000500C7, 0x00000014, + 0x000049A7, 0x00005AE1, 0x00000466, 0x000600A9, 0x00000014, 0x00002AC4, 0x000040D6, 0x000049A7, + 0x000048B5, 0x00050080, 0x00000014, 0x0000600B, 0x0000287C, 0x000003FA, 0x000500C4, 0x00000014, + 0x00004F8C, 0x0000600B, 0x00000189, 0x000500C4, 0x00000014, 0x00003FB3, 0x00002AC4, 0x0000008D, + 0x000500C5, 0x00000014, 0x00005789, 0x00004F8C, 0x00003FB3, 0x000500AA, 0x00000010, 0x0000360D, + 0x00005DF3, 0x00000A12, 0x000600A9, 0x00000014, 0x0000424F, 0x0000360D, 0x00000A12, 0x00005789, + 0x0004007C, 0x00000018, 0x000029DC, 0x0000424F, 0x000500C2, 0x0000000B, 0x00004BB1, 0x000027FE, + 0x00000A64, 0x00040070, 0x0000000D, 0x0000481B, 0x00004BB1, 0x00050085, 0x0000000D, 0x00003E2C, + 0x0000481B, 0x00000149, 0x00050051, 0x0000000D, 0x000053CF, 0x000029DC, 0x00000000, 0x00050051, + 0x0000000D, 0x00002A62, 0x000029DC, 0x00000001, 0x00050051, 0x0000000D, 0x00001EA3, 0x000029DC, + 0x00000002, 0x00070050, 0x0000001D, 0x00003DE4, 0x000053CF, 0x00002A62, 0x00001EA3, 0x00003E2C, + 0x00050051, 0x0000000B, 0x000027FF, 0x00002AC2, 0x00000002, 0x00060050, 0x00000014, 0x00003518, + 0x000027FF, 0x000027FF, 0x000027FF, 0x000500C2, 0x00000014, 0x00002B1E, 0x00003518, 0x00000BB4, + 0x000500C7, 0x00000014, 0x00005DF4, 0x00002B1E, 0x00000105, 0x000500C7, 0x00000014, 0x000048B6, + 0x00005DF4, 0x00000466, 0x000500C2, 0x00000014, 0x00005B9E, 0x00005DF4, 0x00000B0C, 0x000500AA, + 0x00000010, 0x000040D7, 0x00005B9E, 0x00000A12, 0x0006000C, 0x00000016, 0x00002C59, 0x00000001, + 0x0000004B, 0x000048B6, 0x0004007C, 0x00000014, 0x00002A23, 0x00002C59, 0x00050082, 0x00000014, + 0x00001888, 0x00000B0C, 0x00002A23, 0x00050080, 0x00000014, 0x0000221E, 0x00002A23, 0x00000938, + 0x000600A9, 0x00000014, 0x0000287D, 0x000040D7, 0x0000221E, 0x00005B9E, 0x000500C4, 0x00000014, + 0x00005AE2, 0x000048B6, 0x00001888, 0x000500C7, 0x00000014, 0x000049A8, 0x00005AE2, 0x00000466, + 0x000600A9, 0x00000014, 0x00002AC5, 0x000040D7, 0x000049A8, 0x000048B6, 0x00050080, 0x00000014, + 0x0000600C, 0x0000287D, 0x000003FA, 0x000500C4, 0x00000014, 0x00004F8D, 0x0000600C, 0x00000189, + 0x000500C4, 0x00000014, 0x00003FB4, 0x00002AC5, 0x0000008D, 0x000500C5, 0x00000014, 0x0000578A, + 0x00004F8D, 0x00003FB4, 0x000500AA, 0x00000010, 0x0000360E, 0x00005DF4, 0x00000A12, 0x000600A9, + 0x00000014, 0x00004250, 0x0000360E, 0x00000A12, 0x0000578A, 0x0004007C, 0x00000018, 0x000029DD, + 0x00004250, 0x000500C2, 0x0000000B, 0x00004BB2, 0x000027FF, 0x00000A64, 0x00040070, 0x0000000D, + 0x0000481C, 0x00004BB2, 0x00050085, 0x0000000D, 0x00003E2D, 0x0000481C, 0x00000149, 0x00050051, + 0x0000000D, 0x000053D0, 0x000029DD, 0x00000000, 0x00050051, 0x0000000D, 0x00002A63, 0x000029DD, + 0x00000001, 0x00050051, 0x0000000D, 0x00001EA4, 0x000029DD, 0x00000002, 0x00070050, 0x0000001D, + 0x00003DE5, 0x000053D0, 0x00002A63, 0x00001EA4, 0x00003E2D, 0x00050051, 0x0000000B, 0x00002800, + 0x00002AC2, 0x00000003, 0x00060050, 0x00000014, 0x00003519, 0x00002800, 0x00002800, 0x00002800, + 0x000500C2, 0x00000014, 0x00002B1F, 0x00003519, 0x00000BB4, 0x000500C7, 0x00000014, 0x00005DF5, + 0x00002B1F, 0x00000105, 0x000500C7, 0x00000014, 0x000048B8, 0x00005DF5, 0x00000466, 0x000500C2, + 0x00000014, 0x00005B9F, 0x00005DF5, 0x00000B0C, 0x000500AA, 0x00000010, 0x000040D8, 0x00005B9F, + 0x00000A12, 0x0006000C, 0x00000016, 0x00002C5A, 0x00000001, 0x0000004B, 0x000048B8, 0x0004007C, + 0x00000014, 0x00002A24, 0x00002C5A, 0x00050082, 0x00000014, 0x00001889, 0x00000B0C, 0x00002A24, + 0x00050080, 0x00000014, 0x0000221F, 0x00002A24, 0x00000938, 0x000600A9, 0x00000014, 0x0000287E, + 0x000040D8, 0x0000221F, 0x00005B9F, 0x000500C4, 0x00000014, 0x00005AE3, 0x000048B8, 0x00001889, + 0x000500C7, 0x00000014, 0x000049A9, 0x00005AE3, 0x00000466, 0x000600A9, 0x00000014, 0x00002AC6, + 0x000040D8, 0x000049A9, 0x000048B8, 0x00050080, 0x00000014, 0x0000600D, 0x0000287E, 0x000003FA, + 0x000500C4, 0x00000014, 0x00004F8E, 0x0000600D, 0x00000189, 0x000500C4, 0x00000014, 0x00003FB5, + 0x00002AC6, 0x0000008D, 0x000500C5, 0x00000014, 0x0000578B, 0x00004F8E, 0x00003FB5, 0x000500AA, + 0x00000010, 0x0000360F, 0x00005DF5, 0x00000A12, 0x000600A9, 0x00000014, 0x00004251, 0x0000360F, + 0x00000A12, 0x0000578B, 0x0004007C, 0x00000018, 0x000029DE, 0x00004251, 0x000500C2, 0x0000000B, + 0x00004BB3, 0x00002800, 0x00000A64, 0x00040070, 0x0000000D, 0x0000481D, 0x00004BB3, 0x00050085, + 0x0000000D, 0x00003E2E, 0x0000481D, 0x00000149, 0x00050051, 0x0000000D, 0x000053D1, 0x000029DE, + 0x00000000, 0x00050051, 0x0000000D, 0x00002A64, 0x000029DE, 0x00000001, 0x00050051, 0x0000000D, + 0x00002B20, 0x000029DE, 0x00000002, 0x00070050, 0x0000001D, 0x0000235A, 0x000053D1, 0x00002A64, + 0x00002B20, 0x00003E2E, 0x000200F9, 0x00003F63, 0x000200F8, 0x00001CC1, 0x00050051, 0x0000000B, + 0x000056C7, 0x00002AC2, 0x00000000, 0x00070050, 0x00000017, 0x00004F14, 0x000056C7, 0x000056C7, + 0x000056C7, 0x000056C7, 0x000500C2, 0x00000017, 0x000024B0, 0x00004F14, 0x0000034D, 0x000500C7, + 0x00000017, 0x000049B7, 0x000024B0, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CC0, 0x000049B7, + 0x00050085, 0x0000001D, 0x00004139, 0x00003CC0, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CDB, + 0x00002AC2, 0x00000001, 0x00070050, 0x00000017, 0x00005156, 0x00005CDB, 0x00005CDB, 0x00005CDB, + 0x00005CDB, 0x000500C2, 0x00000017, 0x000024B1, 0x00005156, 0x0000034D, 0x000500C7, 0x00000017, + 0x000049B8, 0x000024B1, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CC1, 0x000049B8, 0x00050085, + 0x0000001D, 0x0000413A, 0x00003CC1, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CDC, 0x00002AC2, + 0x00000002, 0x00070050, 0x00000017, 0x00005157, 0x00005CDC, 0x00005CDC, 0x00005CDC, 0x00005CDC, + 0x000500C2, 0x00000017, 0x000024B2, 0x00005157, 0x0000034D, 0x000500C7, 0x00000017, 0x000049B9, + 0x000024B2, 0x0000027B, 0x00040070, 0x0000001D, 0x00003CC2, 0x000049B9, 0x00050085, 0x0000001D, + 0x0000413B, 0x00003CC2, 0x00000AEE, 0x00050051, 0x0000000B, 0x00005CDD, 0x00002AC2, 0x00000003, + 0x00070050, 0x00000017, 0x0000515C, 0x00005CDD, 0x00005CDD, 0x00005CDD, 0x00005CDD, 0x000500C2, + 0x00000017, 0x000024B3, 0x0000515C, 0x0000034D, 0x000500C7, 0x00000017, 0x000049BA, 0x000024B3, + 0x0000027B, 0x00040070, 0x0000001D, 0x00004932, 0x000049BA, 0x00050085, 0x0000001D, 0x000026A2, + 0x00004932, 0x00000AEE, 0x000200F9, 0x00003F63, 0x000200F8, 0x000038FC, 0x00050051, 0x0000000B, + 0x000056C8, 0x00002AC2, 0x00000000, 0x00070050, 0x00000017, 0x00004F15, 0x000056C8, 0x000056C8, + 0x000056C8, 0x000056C8, 0x000500C2, 0x00000017, 0x000024B4, 0x00004F15, 0x0000028D, 0x000500C7, + 0x00000017, 0x00004A62, 0x000024B4, 0x0000064B, 0x00040070, 0x0000001D, 0x000036AE, 0x00004A62, + 0x0005008E, 0x0000001D, 0x00004B2C, 0x000036AE, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A8, + 0x00002AC2, 0x00000001, 0x00070050, 0x00000017, 0x00006114, 0x000021A8, 0x000021A8, 0x000021A8, + 0x000021A8, 0x000500C2, 0x00000017, 0x000024B5, 0x00006114, 0x0000028D, 0x000500C7, 0x00000017, + 0x00004A63, 0x000024B5, 0x0000064B, 0x00040070, 0x0000001D, 0x000036AF, 0x00004A63, 0x0005008E, + 0x0000001D, 0x00004B2D, 0x000036AF, 0x0000017A, 0x00050051, 0x0000000B, 0x000021A9, 0x00002AC2, + 0x00000002, 0x00070050, 0x00000017, 0x00006115, 0x000021A9, 0x000021A9, 0x000021A9, 0x000021A9, + 0x000500C2, 0x00000017, 0x000024B6, 0x00006115, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A64, + 0x000024B6, 0x0000064B, 0x00040070, 0x0000001D, 0x000036B0, 0x00004A64, 0x0005008E, 0x0000001D, + 0x00004B2E, 0x000036B0, 0x0000017A, 0x00050051, 0x0000000B, 0x000021AA, 0x00002AC2, 0x00000003, + 0x00070050, 0x00000017, 0x00006116, 0x000021AA, 0x000021AA, 0x000021AA, 0x000021AA, 0x000500C2, + 0x00000017, 0x000024B7, 0x00006116, 0x0000028D, 0x000500C7, 0x00000017, 0x00004A65, 0x000024B7, + 0x0000064B, 0x00040070, 0x0000001D, 0x0000431D, 0x00004A65, 0x0005008E, 0x0000001D, 0x00003095, + 0x0000431D, 0x0000017A, 0x000200F9, 0x00003F63, 0x000200F8, 0x00004BFE, 0x00050051, 0x0000000B, + 0x00003096, 0x00002AC2, 0x00000000, 0x0004007C, 0x0000000D, 0x00004FF1, 0x00003096, 0x00050050, + 0x00000013, 0x0000433F, 0x00004FF1, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D99, 0x0000433F, + 0x0000433F, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056BA, + 0x00002AC2, 0x00000001, 0x0004007C, 0x0000000D, 0x00003F71, 0x000056BA, 0x00050050, 0x00000013, + 0x00004340, 0x00003F71, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D9A, 0x00004340, 0x00004340, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056BB, 0x00002AC2, + 0x00000002, 0x0004007C, 0x0000000D, 0x00003F72, 0x000056BB, 0x00050050, 0x00000013, 0x00004341, + 0x00003F72, 0x00000A0C, 0x0009004F, 0x0000001D, 0x00002D9B, 0x00004341, 0x00004341, 0x00000000, + 0x00000001, 0x00000001, 0x00000001, 0x00050051, 0x0000000B, 0x000056BC, 0x00002AC2, 0x00000003, + 0x0004007C, 0x0000000D, 0x00003F73, 0x000056BC, 0x00050050, 0x00000013, 0x00004FB1, 0x00003F73, + 0x00000A0C, 0x0009004F, 0x0000001D, 0x00005A3D, 0x00004FB1, 0x00004FB1, 0x00000000, 0x00000001, + 0x00000001, 0x00000001, 0x000200F9, 0x00003F63, 0x000200F8, 0x00003F63, 0x000F00F5, 0x0000001D, + 0x00002BB0, 0x00005A3D, 0x00004BFE, 0x00003095, 0x000038FC, 0x000026A2, 0x00001CC1, 0x0000235A, + 0x00001CC0, 0x00002359, 0x00002001, 0x00002358, 0x00002039, 0x000F00F5, 0x0000001D, 0x00003811, + 0x00002D9B, 0x00004BFE, 0x00004B2E, 0x000038FC, 0x0000413B, 0x00001CC1, 0x00003DE5, 0x00001CC0, + 0x00004129, 0x00002001, 0x00003920, 0x00002039, 0x000F00F5, 0x0000001D, 0x00003B89, 0x00002D9A, + 0x00004BFE, 0x00004B2D, 0x000038FC, 0x0000413A, 0x00001CC1, 0x00003DE4, 0x00001CC0, 0x00004128, + 0x00002001, 0x0000391F, 0x00002039, 0x000F00F5, 0x0000001D, 0x000038BC, 0x00002D99, 0x00004BFE, + 0x00004B2C, 0x000038FC, 0x00004139, 0x00001CC1, 0x00003DE3, 0x00001CC0, 0x00004127, 0x00002001, + 0x0000391E, 0x00002039, 0x000200F9, 0x00005312, 0x000200F8, 0x00003B68, 0x000500AA, 0x00000009, + 0x00005453, 0x0000199B, 0x00000A10, 0x000300F7, 0x00004F29, 0x00000002, 0x000400FA, 0x00005453, + 0x0000262B, 0x00002F68, 0x000200F8, 0x00002F68, 0x00060041, 0x00000288, 0x00004BD6, 0x00000CC7, + 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D51, 0x00004BD6, 0x00050080, 0x0000000B, + 0x00002DD8, 0x00003FF8, 0x00000A0D, 0x00060041, 0x00000288, 0x00001919, 0x00000CC7, 0x00000A0B, + 0x00002DD8, 0x0004003D, 0x0000000B, 0x00005C85, 0x00001919, 0x00050080, 0x0000000B, 0x00002DD9, + 0x00003FF8, 0x0000199B, 0x00060041, 0x00000288, 0x0000191A, 0x00000CC7, 0x00000A0B, 0x00002DD9, + 0x0004003D, 0x0000000B, 0x00005C86, 0x0000191A, 0x00050080, 0x0000000B, 0x00002DDA, 0x00002DD9, + 0x00000A0D, 0x00060041, 0x00000288, 0x0000600E, 0x00000CC7, 0x00000A0B, 0x00002DDA, 0x0004003D, + 0x0000000B, 0x0000374F, 0x0000600E, 0x00070050, 0x00000017, 0x00004CDA, 0x00005D51, 0x00005C85, + 0x00005C86, 0x0000374F, 0x00050084, 0x0000000B, 0x0000429B, 0x00000A10, 0x0000199B, 0x00050080, + 0x0000000B, 0x000036B1, 0x00003FF8, 0x0000429B, 0x00060041, 0x00000288, 0x00003B8A, 0x00000CC7, + 0x00000A0B, 0x000036B1, 0x0004003D, 0x0000000B, 0x00005C87, 0x00003B8A, 0x00050080, 0x0000000B, + 0x00002DDB, 0x000036B1, 0x00000A0D, 0x00060041, 0x00000288, 0x00001952, 0x00000CC7, 0x00000A0B, + 0x00002DDB, 0x0004003D, 0x0000000B, 0x00005E66, 0x00001952, 0x00050084, 0x0000000B, 0x00001865, + 0x00000A13, 0x0000199B, 0x00050080, 0x0000000B, 0x000020AC, 0x00003FF8, 0x00001865, 0x00060041, + 0x00000288, 0x00003B8B, 0x00000CC7, 0x00000A0B, 0x000020AC, 0x0004003D, 0x0000000B, 0x00005C88, + 0x00003B8B, 0x00050080, 0x0000000B, 0x00002DDC, 0x000020AC, 0x00000A0D, 0x00060041, 0x00000288, + 0x0000600F, 0x00000CC7, 0x00000A0B, 0x00002DDC, 0x0004003D, 0x0000000B, 0x0000400A, 0x0000600F, + 0x00070050, 0x00000017, 0x0000513A, 0x00005C87, 0x00005E66, 0x00005C88, 0x0000400A, 0x000200F9, + 0x00004F29, 0x000200F8, 0x0000262B, 0x00060041, 0x00000288, 0x0000554C, 0x00000CC7, 0x00000A0B, + 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D52, 0x0000554C, 0x00050080, 0x0000000B, 0x00002DDD, + 0x00003FF8, 0x00000A0D, 0x00060041, 0x00000288, 0x0000191B, 0x00000CC7, 0x00000A0B, 0x00002DDD, + 0x0004003D, 0x0000000B, 0x00005C89, 0x0000191B, 0x00050080, 0x0000000B, 0x00002DDE, 0x00003FF8, + 0x00000A10, 0x00060041, 0x00000288, 0x0000191C, 0x00000CC7, 0x00000A0B, 0x00002DDE, 0x0004003D, + 0x0000000B, 0x00005C8A, 0x0000191C, 0x00050080, 0x0000000B, 0x00002DDF, 0x00003FF8, 0x00000A13, + 0x00060041, 0x00000288, 0x00006010, 0x00000CC7, 0x00000A0B, 0x00002DDF, 0x0004003D, 0x0000000B, + 0x00003703, 0x00006010, 0x00070050, 0x00000017, 0x00004AE2, 0x00005D52, 0x00005C89, 0x00005C8A, + 0x00003703, 0x00050080, 0x0000000B, 0x000057E8, 0x00003FF8, 0x00000A16, 0x00060041, 0x00000288, + 0x0000604E, 0x00000CC7, 0x00000A0B, 0x000057E8, 0x0004003D, 0x0000000B, 0x00005C8B, 0x0000604E, + 0x00050080, 0x0000000B, 0x00002DE0, 0x00003FF8, 0x00000A19, 0x00060041, 0x00000288, 0x0000191D, + 0x00000CC7, 0x00000A0B, 0x00002DE0, 0x0004003D, 0x0000000B, 0x00005C8C, 0x0000191D, 0x00050080, + 0x0000000B, 0x00002DE1, 0x00003FF8, 0x00000A1C, 0x00060041, 0x00000288, 0x0000191E, 0x00000CC7, + 0x00000A0B, 0x00002DE1, 0x0004003D, 0x0000000B, 0x00005C8D, 0x0000191E, 0x00050080, 0x0000000B, + 0x00002DE2, 0x00003FF8, 0x00000A1F, 0x00060041, 0x00000288, 0x00006011, 0x00000CC7, 0x00000A0B, + 0x00002DE2, 0x0004003D, 0x0000000B, 0x0000400B, 0x00006011, 0x00070050, 0x00000017, 0x0000513B, + 0x00005C8B, 0x00005C8C, 0x00005C8D, 0x0000400B, 0x000200F9, 0x00004F29, 0x000200F8, 0x00004F29, + 0x000700F5, 0x00000017, 0x00002BD0, 0x0000513B, 0x0000262B, 0x0000513A, 0x00002F68, 0x000700F5, + 0x00000017, 0x00003723, 0x00004AE2, 0x0000262B, 0x00004CDA, 0x00002F68, 0x000300F7, 0x00004F2A, + 0x00000000, 0x000700FB, 0x00002180, 0x00004F59, 0x00000005, 0x0000215B, 0x00000007, 0x0000203A, + 0x000200F8, 0x0000203A, 0x00050051, 0x0000000B, 0x00005F5D, 0x00003723, 0x00000000, 0x0006000C, + 0x00000013, 0x0000606E, 0x00000001, 0x0000003E, 0x00005F5D, 0x00050051, 0x0000000D, 0x0000278A, + 0x0000606E, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC4, 0x0000606E, 0x00000001, 0x00050051, + 0x0000000B, 0x0000428D, 0x00003723, 0x00000001, 0x0006000C, 0x00000013, 0x00003D01, 0x00000001, + 0x0000003E, 0x0000428D, 0x00050051, 0x0000000D, 0x0000278B, 0x00003D01, 0x00000000, 0x00050051, + 0x0000000D, 0x0000445B, 0x00003D01, 0x00000001, 0x00070050, 0x0000001D, 0x00003921, 0x0000278A, + 0x00003EC4, 0x0000278B, 0x0000445B, 0x00050051, 0x0000000B, 0x0000438F, 0x00003723, 0x00000002, + 0x0006000C, 0x00000013, 0x00004680, 0x00000001, 0x0000003E, 0x0000438F, 0x00050051, 0x0000000D, + 0x0000278C, 0x00004680, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC5, 0x00004680, 0x00000001, + 0x00050051, 0x0000000B, 0x0000428E, 0x00003723, 0x00000003, 0x0006000C, 0x00000013, 0x00003D02, + 0x00000001, 0x0000003E, 0x0000428E, 0x00050051, 0x0000000D, 0x0000278D, 0x00003D02, 0x00000000, + 0x00050051, 0x0000000D, 0x0000445C, 0x00003D02, 0x00000001, 0x00070050, 0x0000001D, 0x00003922, + 0x0000278C, 0x00003EC5, 0x0000278D, 0x0000445C, 0x00050051, 0x0000000B, 0x00004390, 0x00002BD0, + 0x00000000, 0x0006000C, 0x00000013, 0x00004681, 0x00000001, 0x0000003E, 0x00004390, 0x00050051, + 0x0000000D, 0x0000278E, 0x00004681, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC6, 0x00004681, + 0x00000001, 0x00050051, 0x0000000B, 0x0000428F, 0x00002BD0, 0x00000001, 0x0006000C, 0x00000013, + 0x00003D03, 0x00000001, 0x0000003E, 0x0000428F, 0x00050051, 0x0000000D, 0x0000278F, 0x00003D03, + 0x00000000, 0x00050051, 0x0000000D, 0x0000445D, 0x00003D03, 0x00000001, 0x00070050, 0x0000001D, + 0x00003923, 0x0000278E, 0x00003EC6, 0x0000278F, 0x0000445D, 0x00050051, 0x0000000B, 0x00004391, + 0x00002BD0, 0x00000002, 0x0006000C, 0x00000013, 0x00004682, 0x00000001, 0x0000003E, 0x00004391, + 0x00050051, 0x0000000D, 0x00002790, 0x00004682, 0x00000000, 0x00050051, 0x0000000D, 0x00003EC7, + 0x00004682, 0x00000001, 0x00050051, 0x0000000B, 0x00004290, 0x00002BD0, 0x00000003, 0x0006000C, + 0x00000013, 0x00003D04, 0x00000001, 0x0000003E, 0x00004290, 0x00050051, 0x0000000D, 0x00002791, + 0x00003D04, 0x00000000, 0x00050051, 0x0000000D, 0x000050C5, 0x00003D04, 0x00000001, 0x00070050, + 0x0000001D, 0x0000235B, 0x00002790, 0x00003EC7, 0x00002791, 0x000050C5, 0x000200F9, 0x00004F2A, + 0x000200F8, 0x0000215B, 0x0007004F, 0x00000011, 0x000025FE, 0x00003723, 0x00003723, 0x00000000, + 0x00000001, 0x0004007C, 0x00000012, 0x00005B3F, 0x000025FE, 0x0009004F, 0x0000001A, 0x000060DA, + 0x00005B3F, 0x00005B3F, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, + 0x000048B9, 0x000060DA, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D99, 0x000048B9, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002AC7, 0x00003D99, 0x0005008E, 0x0000001D, 0x00004733, 0x00002AC7, + 0x000007FE, 0x0007000C, 0x0000001D, 0x0000629A, 0x00000001, 0x00000028, 0x00000504, 0x00004733, + 0x0007004F, 0x00000011, 0x00003774, 0x00003723, 0x00003723, 0x00000002, 0x00000003, 0x0004007C, + 0x00000012, 0x000024C8, 0x00003774, 0x0009004F, 0x0000001A, 0x000060DB, 0x000024C8, 0x000024C8, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048BA, 0x000060DB, + 0x00000122, 0x000500C3, 0x0000001A, 0x00003D9A, 0x000048BA, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002AC8, 0x00003D9A, 0x0005008E, 0x0000001D, 0x00004734, 0x00002AC8, 0x000007FE, 0x0007000C, + 0x0000001D, 0x0000629B, 0x00000001, 0x00000028, 0x00000504, 0x00004734, 0x0007004F, 0x00000011, + 0x00003775, 0x00002BD0, 0x00002BD0, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000024C9, + 0x00003775, 0x0009004F, 0x0000001A, 0x000060DC, 0x000024C9, 0x000024C9, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C4, 0x0000001A, 0x000048BB, 0x000060DC, 0x00000122, 0x000500C3, + 0x0000001A, 0x00003D9B, 0x000048BB, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AC9, 0x00003D9B, + 0x0005008E, 0x0000001D, 0x00004735, 0x00002AC9, 0x000007FE, 0x0007000C, 0x0000001D, 0x0000629C, + 0x00000001, 0x00000028, 0x00000504, 0x00004735, 0x0007004F, 0x00000011, 0x00003776, 0x00002BD0, + 0x00002BD0, 0x00000002, 0x00000003, 0x0004007C, 0x00000012, 0x000024CA, 0x00003776, 0x0009004F, + 0x0000001A, 0x000060DD, 0x000024CA, 0x000024CA, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C4, 0x0000001A, 0x000048BC, 0x000060DD, 0x00000122, 0x000500C3, 0x0000001A, 0x00003D9C, + 0x000048BC, 0x00000302, 0x0004006F, 0x0000001D, 0x00002ACA, 0x00003D9C, 0x0005008E, 0x0000001D, + 0x000053D2, 0x00002ACA, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004365, 0x00000001, 0x00000028, + 0x00000504, 0x000053D2, 0x000200F9, 0x00004F2A, 0x000200F8, 0x00004F59, 0x0007004F, 0x00000011, + 0x0000262C, 0x00003723, 0x00003723, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x0000515D, + 0x0000262C, 0x00050051, 0x0000000D, 0x00001B88, 0x0000515D, 0x00000000, 0x00050051, 0x0000000D, + 0x00003473, 0x0000515D, 0x00000001, 0x00070050, 0x0000001D, 0x00004291, 0x00001B88, 0x00003473, + 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041E1, 0x00003723, 0x00003723, 0x00000002, + 0x00000003, 0x0004007C, 0x00000013, 0x00003766, 0x000041E1, 0x00050051, 0x0000000D, 0x00001B89, + 0x00003766, 0x00000000, 0x00050051, 0x0000000D, 0x00003474, 0x00003766, 0x00000001, 0x00070050, + 0x0000001D, 0x00004292, 0x00001B89, 0x00003474, 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, + 0x000041E2, 0x00002BD0, 0x00002BD0, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x00003767, + 0x000041E2, 0x00050051, 0x0000000D, 0x00001B8A, 0x00003767, 0x00000000, 0x00050051, 0x0000000D, + 0x00003475, 0x00003767, 0x00000001, 0x00070050, 0x0000001D, 0x00004293, 0x00001B8A, 0x00003475, + 0x00000A0C, 0x00000A0C, 0x0007004F, 0x00000011, 0x000041E3, 0x00002BD0, 0x00002BD0, 0x00000002, + 0x00000003, 0x0004007C, 0x00000013, 0x00003768, 0x000041E3, 0x00050051, 0x0000000D, 0x00001B8B, + 0x00003768, 0x00000000, 0x00050051, 0x0000000D, 0x0000410B, 0x00003768, 0x00000001, 0x00070050, + 0x0000001D, 0x0000235C, 0x00001B8B, 0x0000410B, 0x00000A0C, 0x00000A0C, 0x000200F9, 0x00004F2A, + 0x000200F8, 0x00004F2A, 0x000900F5, 0x0000001D, 0x00002BB1, 0x0000235C, 0x00004F59, 0x00004365, + 0x0000215B, 0x0000235B, 0x0000203A, 0x000900F5, 0x0000001D, 0x00003812, 0x00004293, 0x00004F59, + 0x0000629C, 0x0000215B, 0x00003923, 0x0000203A, 0x000900F5, 0x0000001D, 0x00003B8C, 0x00004292, + 0x00004F59, 0x0000629B, 0x0000215B, 0x00003922, 0x0000203A, 0x000900F5, 0x0000001D, 0x000038BD, + 0x00004291, 0x00004F59, 0x0000629A, 0x0000215B, 0x00003921, 0x0000203A, 0x000200F9, 0x00005312, + 0x000200F8, 0x00005312, 0x000700F5, 0x0000001D, 0x00002BB2, 0x00002BB1, 0x00004F2A, 0x00002BB0, + 0x00003F63, 0x000700F5, 0x0000001D, 0x00003813, 0x00003812, 0x00004F2A, 0x00003811, 0x00003F63, + 0x000700F5, 0x0000001D, 0x00003297, 0x00003B8C, 0x00004F2A, 0x00003B89, 0x00003F63, 0x000700F5, + 0x0000001D, 0x0000367C, 0x000038BD, 0x00004F2A, 0x000038BC, 0x00003F63, 0x00050081, 0x0000001D, + 0x0000435B, 0x0000435A, 0x0000367C, 0x00050081, 0x0000001D, 0x00005B03, 0x00005B02, 0x00003297, + 0x00050081, 0x0000001D, 0x00002523, 0x00001C28, 0x00003813, 0x00050081, 0x0000001D, 0x00001E77, + 0x000025AA, 0x00002BB2, 0x000200F9, 0x00005EC8, 0x000200F8, 0x00005EC8, 0x000700F5, 0x0000001D, + 0x00002BB3, 0x00005113, 0x00005310, 0x00001E77, 0x00005312, 0x000700F5, 0x0000001D, 0x00003814, + 0x00001F92, 0x00005310, 0x00002523, 0x00005312, 0x000700F5, 0x0000001D, 0x00003B31, 0x00005B01, + 0x00005310, 0x00005B03, 0x00005312, 0x000700F5, 0x0000001D, 0x00003B8D, 0x00004359, 0x00005310, + 0x0000435B, 0x00005312, 0x000700F5, 0x0000000D, 0x000038BE, 0x00005A1D, 0x00005310, 0x00002F3A, + 0x00005312, 0x000200F9, 0x00005313, 0x000200F8, 0x00005313, 0x000700F5, 0x0000001D, 0x00002BB4, + 0x00002BA9, 0x0000530F, 0x00002BB3, 0x00005EC8, 0x000700F5, 0x0000001D, 0x00003815, 0x0000380A, + 0x0000530F, 0x00003814, 0x00005EC8, 0x000700F5, 0x0000001D, 0x00003B32, 0x000035EC, 0x0000530F, + 0x00003B31, 0x00005EC8, 0x000700F5, 0x0000001D, 0x0000338C, 0x000020D3, 0x0000530F, 0x00003B8D, + 0x00005EC8, 0x000700F5, 0x0000000D, 0x00002EA8, 0x00002B2C, 0x0000530F, 0x000038BE, 0x00005EC8, + 0x0005008E, 0x0000001D, 0x00005A74, 0x0000338C, 0x00002EA8, 0x0005008E, 0x0000001D, 0x000019CC, + 0x00003B32, 0x00002EA8, 0x0005008E, 0x0000001D, 0x0000306F, 0x00003815, 0x00002EA8, 0x0005008E, + 0x0000001D, 0x00003432, 0x00002BB4, 0x00002EA8, 0x000300F7, 0x00003F64, 0x00000002, 0x000400FA, + 0x00001D59, 0x00002741, 0x00003F64, 0x000200F8, 0x00002741, 0x0009004F, 0x0000001D, 0x00003AEE, + 0x00005A74, 0x00005A74, 0x00000002, 0x00000001, 0x00000000, 0x00000003, 0x0009004F, 0x0000001D, + 0x00003A07, 0x000019CC, 0x000019CC, 0x00000002, 0x00000001, 0x00000000, 0x00000003, 0x0009004F, + 0x0000001D, 0x00001CE6, 0x0000306F, 0x0000306F, 0x00000002, 0x00000001, 0x00000000, 0x00000003, + 0x0009004F, 0x0000001D, 0x00003EEF, 0x00003432, 0x00003432, 0x00000002, 0x00000001, 0x00000000, + 0x00000003, 0x000200F9, 0x00003F64, 0x000200F8, 0x00003F64, 0x000700F5, 0x0000001D, 0x00002BB5, + 0x00003432, 0x00005313, 0x00003EEF, 0x00002741, 0x000700F5, 0x0000001D, 0x00003816, 0x0000306F, + 0x00005313, 0x00001CE6, 0x00002741, 0x000700F5, 0x0000001D, 0x00003B57, 0x000019CC, 0x00005313, + 0x00003A07, 0x00002741, 0x000700F5, 0x0000001D, 0x00003A49, 0x00005A74, 0x00005313, 0x00003AEE, + 0x00002741, 0x000300F7, 0x00005BA4, 0x00000000, 0x000700FB, 0x00005093, 0x00001CCD, 0x0000001A, + 0x00004696, 0x00000020, 0x00002514, 0x000200F8, 0x00002514, 0x00050051, 0x0000000D, 0x00003AAE, + 0x00003A49, 0x00000000, 0x00050051, 0x0000000D, 0x000023ED, 0x00003A49, 0x00000001, 0x00050050, + 0x00000013, 0x00004B20, 0x00003AAE, 0x000023ED, 0x0006000C, 0x0000000B, 0x00002171, 0x00000001, + 0x0000003A, 0x00004B20, 0x00050051, 0x0000000D, 0x00005BBF, 0x00003A49, 0x00000002, 0x00050051, + 0x0000000D, 0x000039A7, 0x00003A49, 0x00000003, 0x00050050, 0x00000013, 0x00004B21, 0x00005BBF, + 0x000039A7, 0x0006000C, 0x0000000B, 0x00002172, 0x00000001, 0x0000003A, 0x00004B21, 0x00050051, + 0x0000000D, 0x00005BC0, 0x00003B57, 0x00000000, 0x00050051, 0x0000000D, 0x000039A8, 0x00003B57, + 0x00000001, 0x00050050, 0x00000013, 0x00004B22, 0x00005BC0, 0x000039A8, 0x0006000C, 0x0000000B, + 0x00002173, 0x00000001, 0x0000003A, 0x00004B22, 0x00050051, 0x0000000D, 0x00005BC1, 0x00003B57, + 0x00000002, 0x00050051, 0x0000000D, 0x000039A9, 0x00003B57, 0x00000003, 0x00050050, 0x00000013, + 0x00004B0D, 0x00005BC1, 0x000039A9, 0x0006000C, 0x0000000B, 0x00002220, 0x00000001, 0x0000003A, + 0x00004B0D, 0x00070050, 0x00000017, 0x00003154, 0x00002171, 0x00002172, 0x00002173, 0x00002220, + 0x00050051, 0x0000000D, 0x00003EC9, 0x00003816, 0x00000000, 0x00050051, 0x0000000D, 0x00005470, + 0x00003816, 0x00000001, 0x00050050, 0x00000013, 0x00004B2F, 0x00003EC9, 0x00005470, 0x0006000C, + 0x0000000B, 0x00002174, 0x00000001, 0x0000003A, 0x00004B2F, 0x00050051, 0x0000000D, 0x00005BC2, + 0x00003816, 0x00000002, 0x00050051, 0x0000000D, 0x000039AA, 0x00003816, 0x00000003, 0x00050050, + 0x00000013, 0x00004B30, 0x00005BC2, 0x000039AA, 0x0006000C, 0x0000000B, 0x00002175, 0x00000001, + 0x0000003A, 0x00004B30, 0x00050051, 0x0000000D, 0x00005BC3, 0x00002BB5, 0x00000000, 0x00050051, + 0x0000000D, 0x000039AB, 0x00002BB5, 0x00000001, 0x00050050, 0x00000013, 0x00004B31, 0x00005BC3, + 0x000039AB, 0x0006000C, 0x0000000B, 0x00002176, 0x00000001, 0x0000003A, 0x00004B31, 0x00050051, + 0x0000000D, 0x00005BC4, 0x00002BB5, 0x00000002, 0x00050051, 0x0000000D, 0x000039AC, 0x00002BB5, + 0x00000003, 0x00050050, 0x00000013, 0x00004B0E, 0x00005BC4, 0x000039AC, 0x0006000C, 0x0000000B, + 0x00002E96, 0x00000001, 0x0000003A, 0x00004B0E, 0x00070050, 0x00000017, 0x0000612F, 0x00002174, + 0x00002175, 0x00002176, 0x00002E96, 0x000200F9, 0x00005BA4, 0x000200F8, 0x00004696, 0x0008000C, + 0x0000001D, 0x00001C8F, 0x00000001, 0x0000002B, 0x00003A49, 0x00000B7A, 0x00000505, 0x0005008E, + 0x0000001D, 0x00004F73, 0x00001C8F, 0x0000022D, 0x00050081, 0x0000001D, 0x00002E40, 0x00004F73, + 0x00000145, 0x0004006D, 0x00000017, 0x00001F0B, 0x00002E40, 0x0007004F, 0x00000011, 0x000018D9, + 0x00001F0B, 0x00001F0B, 0x00000000, 0x00000002, 0x0007004F, 0x00000011, 0x00002750, 0x00001F0B, + 0x00001F0B, 0x00000001, 0x00000003, 0x000500C4, 0x00000011, 0x000028CE, 0x00002750, 0x00000867, + 0x000500C5, 0x00000011, 0x000057C9, 0x000018D9, 0x000028CE, 0x00050051, 0x0000000B, 0x0000498C, + 0x000057C9, 0x00000000, 0x00050051, 0x0000000B, 0x00003BFC, 0x000057C9, 0x00000001, 0x0008000C, + 0x0000001D, 0x00003750, 0x00000001, 0x0000002B, 0x00003B57, 0x00000B7A, 0x00000505, 0x0005008E, + 0x0000001D, 0x00002C01, 0x00003750, 0x0000022D, 0x00050081, 0x0000001D, 0x00002E41, 0x00002C01, + 0x00000145, 0x0004006D, 0x00000017, 0x00001F0C, 0x00002E41, 0x0007004F, 0x00000011, 0x000018DA, + 0x00001F0C, 0x00001F0C, 0x00000000, 0x00000002, 0x0007004F, 0x00000011, 0x00002751, 0x00001F0C, + 0x00001F0C, 0x00000001, 0x00000003, 0x000500C4, 0x00000011, 0x000028CF, 0x00002751, 0x00000867, + 0x000500C5, 0x00000011, 0x000057CA, 0x000018DA, 0x000028CF, 0x00050051, 0x0000000B, 0x00004E6D, + 0x000057CA, 0x00000000, 0x00050051, 0x0000000B, 0x0000586B, 0x000057CA, 0x00000001, 0x00070050, + 0x00000017, 0x00001D37, 0x0000498C, 0x00003BFC, 0x00004E6D, 0x0000586B, 0x0008000C, 0x0000001D, + 0x00003846, 0x00000001, 0x0000002B, 0x00003816, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, + 0x00003577, 0x00003846, 0x0000022D, 0x00050081, 0x0000001D, 0x00002E42, 0x00003577, 0x00000145, + 0x0004006D, 0x00000017, 0x00001F0D, 0x00002E42, 0x0007004F, 0x00000011, 0x000018DB, 0x00001F0D, + 0x00001F0D, 0x00000000, 0x00000002, 0x0007004F, 0x00000011, 0x00002752, 0x00001F0D, 0x00001F0D, + 0x00000001, 0x00000003, 0x000500C4, 0x00000011, 0x000028D0, 0x00002752, 0x00000867, 0x000500C5, + 0x00000011, 0x000057CB, 0x000018DB, 0x000028D0, 0x00050051, 0x0000000B, 0x0000498D, 0x000057CB, + 0x00000000, 0x00050051, 0x0000000B, 0x00003BFD, 0x000057CB, 0x00000001, 0x0008000C, 0x0000001D, + 0x00003751, 0x00000001, 0x0000002B, 0x00002BB5, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, + 0x00002C02, 0x00003751, 0x0000022D, 0x00050081, 0x0000001D, 0x00002E43, 0x00002C02, 0x00000145, + 0x0004006D, 0x00000017, 0x00001F0E, 0x00002E43, 0x0007004F, 0x00000011, 0x000018DC, 0x00001F0E, + 0x00001F0E, 0x00000000, 0x00000002, 0x0007004F, 0x00000011, 0x00002753, 0x00001F0E, 0x00001F0E, + 0x00000001, 0x00000003, 0x000500C4, 0x00000011, 0x000028D1, 0x00002753, 0x00000867, 0x000500C5, + 0x00000011, 0x000057CC, 0x000018DC, 0x000028D1, 0x00050051, 0x0000000B, 0x00004E6E, 0x000057CC, + 0x00000000, 0x00050051, 0x0000000B, 0x00001F58, 0x000057CC, 0x00000001, 0x00070050, 0x00000017, + 0x0000235D, 0x0000498D, 0x00003BFD, 0x00004E6E, 0x00001F58, 0x000200F9, 0x00005BA4, 0x000200F8, + 0x00001CCD, 0x00050051, 0x0000000D, 0x00004DAD, 0x00003A49, 0x00000000, 0x00050051, 0x0000000D, + 0x00002825, 0x00003A49, 0x00000001, 0x00050051, 0x0000000D, 0x00001DD9, 0x00003B57, 0x00000000, + 0x00050051, 0x0000000D, 0x000021CA, 0x00003B57, 0x00000001, 0x00070050, 0x0000001D, 0x000020DE, + 0x00004DAD, 0x00002825, 0x00001DD9, 0x000021CA, 0x0004007C, 0x00000017, 0x00004627, 0x000020DE, + 0x00050051, 0x0000000D, 0x00002B51, 0x00003816, 0x00000000, 0x00050051, 0x0000000D, 0x000033E3, + 0x00003816, 0x00000001, 0x00050051, 0x0000000D, 0x00001DDA, 0x00002BB5, 0x00000000, 0x00050051, + 0x0000000D, 0x000021CB, 0x00002BB5, 0x00000001, 0x00070050, 0x0000001D, 0x00002D56, 0x00002B51, + 0x000033E3, 0x00001DDA, 0x000021CB, 0x0004007C, 0x00000017, 0x00002B83, 0x00002D56, 0x000200F9, + 0x00005BA4, 0x000200F8, 0x00005BA4, 0x000900F5, 0x00000017, 0x00002616, 0x00002B83, 0x00001CCD, + 0x0000235D, 0x00004696, 0x0000612F, 0x00002514, 0x000900F5, 0x00000017, 0x00003997, 0x00004627, + 0x00001CCD, 0x00001D37, 0x00004696, 0x00003154, 0x00002514, 0x000500AA, 0x00000009, 0x0000195B, + 0x00001DD8, 0x00000A0A, 0x000300F7, 0x000033DC, 0x00000000, 0x000400FA, 0x0000195B, 0x00002CBB, + 0x000033DC, 0x000200F8, 0x00002CBB, 0x00050051, 0x0000000B, 0x00005E67, 0x00004AB4, 0x00000000, + 0x000500AB, 0x00000009, 0x000057C6, 0x00005E67, 0x00000A0A, 0x000200F9, 0x000033DC, 0x000200F8, + 0x000033DC, 0x000700F5, 0x00000009, 0x00002ACB, 0x0000195B, 0x00005BA4, 0x000057C6, 0x00002CBB, + 0x000300F7, 0x00005571, 0x00000002, 0x000400FA, 0x00002ACB, 0x00002CF4, 0x00005571, 0x000200F8, + 0x00002CF4, 0x00050051, 0x0000000B, 0x00005C2F, 0x00004AB4, 0x00000000, 0x000500AE, 0x00000009, + 0x000043C2, 0x00005C2F, 0x00000A10, 0x000300F7, 0x00005570, 0x00000000, 0x000400FA, 0x000043C2, + 0x00003E05, 0x00005570, 0x000200F8, 0x00003E05, 0x000500AE, 0x00000009, 0x00005FD4, 0x00005C2F, + 0x00000A13, 0x000300F7, 0x00004944, 0x00000000, 0x000400FA, 0x00005FD4, 0x00002620, 0x00004944, + 0x000200F8, 0x00002620, 0x00050051, 0x0000000B, 0x00004392, 0x00002616, 0x00000002, 0x00060052, + 0x00000017, 0x000052B6, 0x00004392, 0x00002616, 0x00000000, 0x00050051, 0x0000000B, 0x00005A04, + 0x00002616, 0x00000003, 0x00060052, 0x00000017, 0x00002450, 0x00005A04, 0x000052B6, 0x00000001, + 0x000200F9, 0x00004944, 0x000200F8, 0x00004944, 0x000700F5, 0x00000017, 0x000043E3, 0x00002616, + 0x00003E05, 0x00002450, 0x00002620, 0x00050051, 0x0000000B, 0x00005961, 0x000043E3, 0x00000000, + 0x00060052, 0x00000017, 0x000055DF, 0x00005961, 0x00003997, 0x00000002, 0x00050051, 0x0000000B, + 0x00005A05, 0x000043E3, 0x00000001, 0x00060052, 0x00000017, 0x00002451, 0x00005A05, 0x000055DF, + 0x00000003, 0x000200F9, 0x00005570, 0x000200F8, 0x00005570, 0x000700F5, 0x00000017, 0x00001F7B, + 0x00002616, 0x00002CF4, 0x000043E3, 0x00004944, 0x000700F5, 0x00000017, 0x00001EFE, 0x00003997, + 0x00002CF4, 0x00002451, 0x00004944, 0x00050051, 0x0000000B, 0x00005C8E, 0x00001EFE, 0x00000002, + 0x00060052, 0x00000017, 0x000055E0, 0x00005C8E, 0x00001EFE, 0x00000000, 0x00050051, 0x0000000B, + 0x00005A06, 0x00001EFE, 0x00000003, 0x00060052, 0x00000017, 0x00002452, 0x00005A06, 0x000055E0, + 0x00000001, 0x000200F9, 0x00005571, 0x000200F8, 0x00005571, 0x000700F5, 0x00000017, 0x000022F8, + 0x00002616, 0x000033DC, 0x00001F7B, 0x00005570, 0x000700F5, 0x00000017, 0x000049AA, 0x00003997, + 0x000033DC, 0x00002452, 0x00005570, 0x00050080, 0x00000011, 0x000035BB, 0x00002EF9, 0x000059EC, + 0x00050051, 0x0000000B, 0x000033BC, 0x000035BB, 0x00000000, 0x00050051, 0x0000000B, 0x00002553, + 0x000035BB, 0x00000001, 0x000500C2, 0x0000000B, 0x00002B2D, 0x000033BC, 0x00000A0D, 0x00050050, + 0x00000011, 0x00001E98, 0x00002B2D, 0x00002553, 0x00050086, 0x00000011, 0x00006158, 0x00001E98, + 0x00005C31, 0x00050051, 0x0000000B, 0x0000366C, 0x00006158, 0x00000000, 0x000500C4, 0x0000000B, + 0x00004D3A, 0x0000366C, 0x00000A0D, 0x00050051, 0x0000000B, 0x00005EBB, 0x00006158, 0x00000001, + 0x00060050, 0x00000014, 0x000053D3, 0x00004D3A, 0x00005EBB, 0x00005F72, 0x000300F7, 0x00005341, + 0x00000002, 0x000400FA, 0x0000500F, 0x000056C9, 0x00002ACC, 0x000200F8, 0x00002ACC, 0x0007004F, + 0x00000011, 0x00001CAB, 0x000053D3, 0x000053D3, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, + 0x000059CF, 0x00001CAB, 0x00050051, 0x0000000C, 0x0000191F, 0x000059CF, 0x00000000, 0x000500C3, + 0x0000000C, 0x000024FD, 0x0000191F, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000059CF, + 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, + 0x00005B4D, 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, + 0x0000000C, 0x00005347, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, + 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A28, 0x000500C7, 0x0000000C, + 0x00002ACD, 0x0000191F, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x00002747, 0x00000A35, + 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, + 0x00002ACD, 0x0000454D, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A13, 0x000500C7, + 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, + 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, + 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4B, 0x00003397, + 0x000500C7, 0x0000000C, 0x000047BE, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544A, + 0x000047BE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004157, 0x00004D30, 0x0000544A, 0x000500C7, + 0x0000000C, 0x00005022, 0x00004157, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, + 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x00004158, 0x00002416, 0x00002F77, + 0x000500C7, 0x0000000C, 0x00004AE3, 0x00004157, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544B, + 0x00004AE3, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x00004158, 0x0000544B, 0x000500C7, + 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, + 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x0000191F, 0x00000A14, 0x00050080, 0x0000000C, + 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005454, 0x000035B6, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000544C, 0x00005454, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4C, + 0x00004144, 0x0000544C, 0x000500C7, 0x0000000C, 0x00002E06, 0x00004157, 0x00000AC8, 0x00050080, + 0x0000000C, 0x0000394F, 0x00003C4C, 0x00002E06, 0x0004007C, 0x0000000B, 0x0000566F, 0x0000394F, + 0x000200F9, 0x00005341, 0x000200F8, 0x000056C9, 0x0004007C, 0x00000016, 0x000019AD, 0x000053D3, + 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FE, + 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002748, 0x000019AD, 0x00000002, 0x000500C3, + 0x0000000C, 0x0000405D, 0x00002748, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00006273, + 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005321, + 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FE, 0x00005321, 0x000500C2, + 0x0000000B, 0x00002348, 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, 0x00003097, 0x00002348, + 0x00050084, 0x0000000C, 0x0000287F, 0x00003B27, 0x00003097, 0x00050051, 0x0000000C, 0x00006242, + 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, + 0x0000000C, 0x000049FC, 0x00004FC7, 0x0000287F, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, + 0x00000A25, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, + 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, + 0x000500C7, 0x0000000C, 0x00003139, 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454E, + 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454E, 0x000500C4, + 0x0000000C, 0x00001B8C, 0x0000434B, 0x00000A25, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B8C, + 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002221, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, + 0x000035A3, 0x00002221, 0x0000405D, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, + 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, + 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, + 0x0000000C, 0x00004AE4, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544D, 0x00004AE4, + 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4D, 0x00005A0C, 0x0000544D, 0x000500C7, 0x0000000C, + 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, + 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, + 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, + 0x0000000C, 0x000047BF, 0x00002748, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544E, 0x000047BF, + 0x00000A25, 0x00050080, 0x0000000C, 0x00004159, 0x0000285C, 0x0000544E, 0x000500C7, 0x0000000C, + 0x00004AE5, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544F, 0x00004AE5, 0x00000A17, + 0x00050080, 0x0000000C, 0x0000415A, 0x00004159, 0x0000544F, 0x000500C7, 0x0000000C, 0x00004FD6, + 0x00003C4D, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, + 0x0000000C, 0x00003332, 0x0000415A, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, + 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, + 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4D, 0x00000A05, + 0x00050080, 0x0000000C, 0x00002ACE, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, + 0x00002ACE, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x0000415A, 0x0000040B, 0x00050080, + 0x0000000C, 0x00002ACF, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002ACF, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x0000415A, 0x00000AC8, 0x00050080, 0x0000000C, + 0x00005EFA, 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, 0x00005670, 0x00005EFA, 0x000200F9, + 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, 0x000024FC, 0x00005670, 0x000056C9, + 0x0000566F, 0x00002ACC, 0x00050084, 0x00000011, 0x00003FB6, 0x00006158, 0x00005C31, 0x00050082, + 0x00000011, 0x00003F85, 0x00001E98, 0x00003FB6, 0x00050051, 0x0000000B, 0x0000448F, 0x00005C31, + 0x00000001, 0x00050084, 0x0000000B, 0x00005C50, 0x0000229A, 0x0000448F, 0x00050084, 0x0000000B, + 0x00003CA0, 0x000024FC, 0x00005C50, 0x00050051, 0x0000000B, 0x00003ED4, 0x00003F85, 0x00000000, + 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, 0x0000448F, 0x00050051, 0x0000000B, 0x00001AE7, + 0x00003F85, 0x00000001, 0x00050080, 0x0000000B, 0x00002B25, 0x00003E12, 0x00001AE7, 0x000500C4, + 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00005AB3, 0x000033BC, + 0x00000A0D, 0x00050080, 0x0000000B, 0x00002557, 0x0000609D, 0x00005AB3, 0x000500C4, 0x0000000B, + 0x00004593, 0x00002557, 0x00000A13, 0x00050080, 0x0000000B, 0x00002048, 0x00003CA0, 0x00004593, + 0x000500C2, 0x0000000B, 0x000025CC, 0x00002048, 0x00000A16, 0x000500AA, 0x00000009, 0x00004B9C, + 0x00004ADC, 0x00000A16, 0x000300F7, 0x000039BC, 0x00000000, 0x000400FA, 0x00004B9C, 0x000033DF, + 0x000039BC, 0x000200F8, 0x000033DF, 0x0009004F, 0x00000017, 0x00001F16, 0x000049AA, 0x000049AA, + 0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x000200F9, 0x000039BC, 0x000200F8, 0x000039BC, + 0x000700F5, 0x00000017, 0x00005972, 0x000049AA, 0x00005341, 0x00001F16, 0x000033DF, 0x000600A9, + 0x0000000B, 0x000019CD, 0x00004B9C, 0x00000A10, 0x00004ADC, 0x000500AA, 0x00000009, 0x00003464, + 0x000019CD, 0x00000A0D, 0x000500AA, 0x00000009, 0x000047C2, 0x000019CD, 0x00000A10, 0x000500A6, + 0x00000009, 0x00005686, 0x00003464, 0x000047C2, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, + 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, + 0x00005972, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, + 0x00000017, 0x000050AC, 0x00005972, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, + 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, + 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x0000587A, 0x00005972, 0x000039BC, 0x00003FF9, + 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000019CD, 0x00000A13, 0x000500A6, 0x00000009, + 0x00003B23, 0x000047C2, 0x00004CB6, 0x000300F7, 0x00002C98, 0x00000000, 0x000400FA, 0x00003B23, + 0x00002B38, 0x00002C98, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x0000587A, + 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x0000587A, 0x000002ED, 0x000500C5, 0x00000017, + 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x00002C98, 0x000200F8, 0x00002C98, 0x000700F5, + 0x00000017, 0x00004D37, 0x0000587A, 0x00003463, 0x000029E8, 0x00002B38, 0x00060041, 0x00000294, + 0x000019BE, 0x00001592, 0x00000A0B, 0x000025CC, 0x0003003E, 0x000019BE, 0x00004D37, 0x000500AC, + 0x00000009, 0x00005BF6, 0x0000229A, 0x00000A0D, 0x000300F7, 0x00004AAC, 0x00000002, 0x000400FA, + 0x00005BF6, 0x000038DA, 0x000055EA, 0x000200F8, 0x000055EA, 0x000200F9, 0x00004AAC, 0x000200F8, + 0x000038DA, 0x000500C2, 0x0000000B, 0x0000364A, 0x00001DD8, 0x00000A0D, 0x00050086, 0x0000000B, + 0x00001F01, 0x0000364A, 0x0000229A, 0x00050084, 0x0000000B, 0x000041FB, 0x00001F01, 0x0000229A, + 0x00050082, 0x0000000B, 0x00003171, 0x0000364A, 0x000041FB, 0x00050080, 0x0000000B, 0x00002527, + 0x00003171, 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, 0x0000229A, 0x000300F7, + 0x00002458, 0x00000000, 0x000400FA, 0x0000343F, 0x00001CDB, 0x000055EB, 0x000200F8, 0x000055EB, + 0x000200F9, 0x00002458, 0x000200F8, 0x00001CDB, 0x00050084, 0x0000000B, 0x00003B96, 0x00000A6A, + 0x0000229A, 0x000500C4, 0x0000000B, 0x0000540F, 0x00003171, 0x00000A16, 0x00050082, 0x0000000B, + 0x00004945, 0x00003B96, 0x0000540F, 0x000200F9, 0x00002458, 0x000200F8, 0x00002458, 0x000700F5, + 0x0000000B, 0x0000292C, 0x00004945, 0x00001CDB, 0x00000A3A, 0x000055EB, 0x000200F9, 0x00004AAC, + 0x000200F8, 0x00004AAC, 0x000700F5, 0x0000000B, 0x000029BC, 0x0000292C, 0x00002458, 0x00000A6A, + 0x000055EA, 0x00050084, 0x0000000B, 0x0000492B, 0x000029BC, 0x0000448F, 0x000500C2, 0x0000000B, + 0x00004DEF, 0x0000492B, 0x00000A16, 0x00050080, 0x0000000B, 0x00005B72, 0x000025CC, 0x00004DEF, + 0x000300F7, 0x00003F86, 0x00000000, 0x000400FA, 0x00004B9C, 0x000033E0, 0x00003F86, 0x000200F8, + 0x000033E0, 0x0009004F, 0x00000017, 0x00001F17, 0x000022F8, 0x000022F8, 0x00000001, 0x00000000, + 0x00000003, 0x00000002, 0x000200F9, 0x00003F86, 0x000200F8, 0x00003F86, 0x000700F5, 0x00000017, + 0x00002AD0, 0x000022F8, 0x00004AAC, 0x00001F17, 0x000033E0, 0x000300F7, 0x00003A1A, 0x00000000, + 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, + 0x00004760, 0x00002AD0, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AD, 0x00002AD0, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, + 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FFA, 0x000024D2, 0x0000448E, 0x000200F9, + 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AD1, 0x00002AD0, 0x00003F86, + 0x00003FFA, 0x00002958, 0x000300F7, 0x00002C99, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, + 0x00002C99, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AD1, 0x000002ED, + 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AD1, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, + 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002C99, 0x000200F8, 0x00002C99, 0x000700F5, 0x00000017, + 0x00004D39, 0x00002AD1, 0x00003A1A, 0x000029E9, 0x00002B39, 0x00060041, 0x00000294, 0x00001F75, + 0x00001592, 0x00000A0B, 0x00005B72, 0x0003003E, 0x00001F75, 0x00004D39, 0x000200F9, 0x00004C7A, + 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_full_8bpp_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_full_8bpp_cs.h new file mode 100644 index 0000000..de5a239 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_full_8bpp_cs.h @@ -0,0 +1,2324 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25262 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_runtimearr_uint ArrayStride 4 + OpDecorate %_struct_1948 BufferBlock + OpMemberDecorate %_struct_1948 0 NonWritable + OpMemberDecorate %_struct_1948 0 Offset 0 + OpDecorate %3271 NonWritable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %_struct_1036 Block + OpMemberDecorate %_struct_1036 0 Offset 0 + OpMemberDecorate %_struct_1036 1 Offset 4 + OpMemberDecorate %_struct_1036 2 Offset 8 + OpMemberDecorate %_struct_1036 3 Offset 12 + OpMemberDecorate %_struct_1036 4 Offset 16 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v2uint ArrayStride 8 + OpDecorate %_struct_1960 BufferBlock + OpMemberDecorate %_struct_1960 0 NonReadable + OpMemberDecorate %_struct_1960 0 Offset 0 + OpDecorate %5522 NonReadable + OpDecorate %5522 Binding 0 + OpDecorate %5522 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %bool = OpTypeBool + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 + %v4int = OpTypeVector %int 4 + %float_255 = OpConstant %float 255 + %float_0_5 = OpConstant %float 0.5 + %uint_0 = OpConstant %uint 0 + %uint_1 = OpConstant %uint 1 + %int_8 = OpConstant %int 8 + %uint_2 = OpConstant %uint 2 + %int_16 = OpConstant %int 16 + %uint_3 = OpConstant %uint 3 + %int_24 = OpConstant %int 24 + %uint_255 = OpConstant %uint 255 +%float_0_00392156886 = OpConstant %float 0.00392156886 + %uint_1023 = OpConstant %uint 1023 +%float_0_000977517106 = OpConstant %float 0.000977517106 + %uint_127 = OpConstant %uint 127 + %uint_7 = OpConstant %uint 7 + %v4bool = OpTypeVector %bool 4 + %uint_124 = OpConstant %uint 124 + %uint_23 = OpConstant %uint 23 + %uint_16 = OpConstant %uint 16 + %float_n1 = OpConstant %float -1 +%float_0_000976592302 = OpConstant %float 0.000976592302 + %1837 = OpConstantComposite %v2uint %uint_2 %uint_1 + %v2bool = OpTypeVector %bool 2 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %uint_80 = OpConstant %uint 80 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_448 = OpConstant %int 448 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 + %uint_6 = OpConstant %uint 6 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_runtimearr_uint = OpTypeRuntimeArray %uint +%_struct_1948 = OpTypeStruct %_runtimearr_uint +%_ptr_Uniform__struct_1948 = OpTypePointer Uniform %_struct_1948 + %3271 = OpVariable %_ptr_Uniform__struct_1948 Uniform + %int_0 = OpConstant %int 0 +%_ptr_Uniform_uint = OpTypePointer Uniform %uint +%_struct_1036 = OpTypeStruct %uint %uint %uint %uint %uint +%_ptr_PushConstant__struct_1036 = OpTypePointer PushConstant %_struct_1036 + %3305 = OpVariable %_ptr_PushConstant__struct_1036 PushConstant +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %uint_10 = OpConstant %uint 10 + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_24 = OpConstant %uint 24 + %uint_15 = OpConstant %uint 15 + %uint_28 = OpConstant %uint 28 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 + %int_10 = OpConstant %int 10 + %uint_8 = OpConstant %uint 8 + %int_26 = OpConstant %int 26 + %int_23 = OpConstant %int 23 +%uint_16777216 = OpConstant %uint 16777216 + %uint_20 = OpConstant %uint 20 + %2275 = OpConstantComposite %v2uint %uint_20 %uint_24 + %v3uint = OpTypeVector %uint 3 + %false = OpConstantFalse %bool + %v2float = OpTypeVector %float 2 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_ptr_Input_uint = OpTypePointer Input %uint + %1834 = OpConstantComposite %v2uint %uint_3 %uint_0 +%_runtimearr_v2uint = OpTypeRuntimeArray %v2uint +%_struct_1960 = OpTypeStruct %_runtimearr_v2uint +%_ptr_Uniform__struct_1960 = OpTypePointer Uniform %_struct_1960 + %5522 = OpVariable %_ptr_Uniform__struct_1960 Uniform +%_ptr_Uniform_v2uint = OpTypePointer Uniform %v2uint +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %1284 = OpConstantComposite %v4float %float_n1 %float_n1 %float_n1 %float_n1 + %770 = OpConstantComposite %v4int %int_16 %int_16 %int_16 %int_16 + %1611 = OpConstantComposite %v4uint %uint_255 %uint_255 %uint_255 %uint_255 + %929 = OpConstantComposite %v4uint %uint_1023 %uint_1023 %uint_1023 %uint_1023 + %721 = OpConstantComposite %v4uint %uint_127 %uint_127 %uint_127 %uint_127 + %263 = OpConstantComposite %v4uint %uint_7 %uint_7 %uint_7 %uint_7 + %2896 = OpConstantComposite %v4uint %uint_0 %uint_0 %uint_0 %uint_0 + %559 = OpConstantComposite %v4uint %uint_124 %uint_124 %uint_124 %uint_124 + %1127 = OpConstantComposite %v4uint %uint_23 %uint_23 %uint_23 %uint_23 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %2938 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 + %1285 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 + %325 = OpConstantComposite %v4float %float_0_5 %float_0_5 %float_0_5 %float_0_5 +%int_1065353216 = OpConstant %int 1065353216 + %uint_1280 = OpConstant %uint 1280 +%uint_2621440 = OpConstant %uint 2621440 +%uint_4294967290 = OpConstant %uint 4294967290 + %2575 = OpConstantComposite %v4uint %uint_4294967290 %uint_4294967290 %uint_4294967290 %uint_4294967290 + %uint_81 = OpConstant %uint 81 + %uint_82 = OpConstant %uint 82 + %uint_83 = OpConstant %uint 83 + %uint_84 = OpConstant %uint 84 + %uint_85 = OpConstant %uint 85 + %uint_86 = OpConstant %uint 86 + %uint_87 = OpConstant %uint 87 + %float_0_25 = OpConstant %float 0.25 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %19978 = OpShiftRightLogical %uint %15627 %uint_10 + %8574 = OpBitwiseAnd %uint %19978 %uint_3 + %21002 = OpShiftRightLogical %uint %15627 %uint_13 + %8575 = OpBitwiseAnd %uint %21002 %uint_2047 + %21003 = OpShiftRightLogical %uint %15627 %uint_24 + %8576 = OpBitwiseAnd %uint %21003 %uint_15 + %18836 = OpShiftRightLogical %uint %15627 %uint_28 + %9130 = OpBitwiseAnd %uint %18836 %uint_1 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9576 = OpShiftRightLogical %v2uint %8871 %1855 + %23379 = OpBitwiseAnd %v2uint %9576 %1954 + %16207 = OpShiftLeftLogical %v2uint %23379 %1870 + %23019 = OpIMul %v2uint %16207 %1828 + %12819 = OpShiftRightLogical %uint %20824 %uint_5 + %16204 = OpBitwiseAnd %uint %12819 %uint_2047 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %24236 = OpLoad %uint %18732 + %22701 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %20387 = OpLoad %uint %22701 + %24445 = OpBitwiseAnd %uint %24236 %uint_8 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8977 = OpShiftRightLogical %uint %24236 %uint_4 + %17416 = OpBitwiseAnd %uint %8977 %uint_7 + %22920 = OpBitcast %int %24236 + %13711 = OpShiftLeftLogical %int %22920 %int_10 + %20636 = OpShiftRightArithmetic %int %13711 %int_26 + %18178 = OpShiftLeftLogical %int %20636 %int_23 + %7462 = OpIAdd %int %18178 %int_1065353216 + %11052 = OpBitcast %float %7462 + %22649 = OpBitwiseAnd %uint %24236 %uint_16777216 + %7513 = OpINotEqual %bool %22649 %uint_0 + %8003 = OpBitwiseAnd %uint %20387 %uint_1023 + %15783 = OpShiftLeftLogical %uint %8003 %uint_5 + %22591 = OpShiftRightLogical %uint %20387 %uint_10 + %19390 = OpBitwiseAnd %uint %22591 %uint_1023 + %25203 = OpShiftLeftLogical %uint %19390 %uint_5 + %10422 = OpCompositeConstruct %v2uint %20387 %20387 + %10385 = OpShiftRightLogical %v2uint %10422 %2275 + %23380 = OpBitwiseAnd %v2uint %10385 %2122 + %16208 = OpShiftLeftLogical %v2uint %23380 %1870 + %23020 = OpIMul %v2uint %16208 %1828 + %12820 = OpShiftRightLogical %uint %20387 %uint_28 + %16205 = OpBitwiseAnd %uint %12820 %uint_7 + %18733 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_4 + %24237 = OpLoad %uint %18733 + %22225 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0 + %7085 = OpLoad %uint %22225 + %7405 = OpUGreaterThanEqual %bool %7085 %16204 + OpSelectionMerge %17447 DontFlatten + OpBranchConditional %7405 %21992 %17447 + %21992 = OpLabel + OpBranch %19578 + %17447 = OpLabel + %14637 = OpLoad %v3uint %gl_GlobalInvocationID + %18505 = OpVectorShuffle %v2uint %14637 %14637 0 1 + %9840 = OpShiftLeftLogical %v2uint %18505 %1834 + %24498 = OpCompositeExtract %uint %9840 0 + %7150 = OpCompositeExtract %uint %9840 1 + %24446 = OpExtInst %uint %1 UMax %7150 %uint_0 + %20975 = OpCompositeConstruct %v2uint %24498 %24446 + %21036 = OpIAdd %v2uint %20975 %23019 + %16075 = OpULessThanEqual %bool %16205 %uint_3 + OpSelectionMerge %23776 None + OpBranchConditional %16075 %10990 %15087 + %15087 = OpLabel + %13566 = OpIEqual %bool %16205 %uint_5 + %8438 = OpSelect %uint %13566 %uint_2 %uint_0 + OpBranch %23776 + %10990 = OpLabel + OpBranch %23776 + %23776 = OpLabel + %19300 = OpPhi %uint %16205 %10990 %8438 %15087 + %16830 = OpCompositeConstruct %v2uint %8574 %8574 + %11801 = OpUGreaterThanEqual %v2bool %16830 %1837 + %19381 = OpSelect %v2uint %11801 %1828 %1807 + %10986 = OpShiftLeftLogical %v2uint %21036 %19381 + %24669 = OpCompositeConstruct %v2uint %19300 %19300 + %9093 = OpShiftRightLogical %v2uint %24669 %1816 + %15084 = OpBitwiseAnd %v2uint %9093 %1828 + %10197 = OpIAdd %v2uint %10986 %15084 + %8548 = OpCompositeConstruct %v2uint %9130 %uint_0 + %9802 = OpShiftRightLogical %v2uint %2719 %8548 + %10146 = OpUDiv %v2uint %10197 %9802 + %20390 = OpCompositeExtract %uint %10146 1 + %11046 = OpIMul %uint %20390 %20561 + %24665 = OpCompositeExtract %uint %10146 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %8575 %21536 + %23345 = OpIMul %v2uint %10146 %9802 + %11892 = OpISub %v2uint %10197 %23345 + %8053 = OpIMul %uint %8742 %uint_1280 + %24263 = OpCompositeExtract %uint %11892 1 + %23526 = OpCompositeExtract %uint %9802 0 + %22886 = OpIMul %uint %24263 %23526 + %6886 = OpCompositeExtract %uint %11892 0 + %9696 = OpIAdd %uint %22886 %6886 + %18116 = OpShiftLeftLogical %uint %9696 %9130 + %18201 = OpIAdd %uint %8053 %18116 + %23256 = OpUMod %uint %18201 %uint_2621440 + %13153 = OpUGreaterThanEqual %bool %8574 %uint_2 + %24735 = OpSelect %uint %13153 %uint_1 %uint_0 + %21518 = OpIAdd %uint %9130 %24735 + %12535 = OpShiftLeftLogical %uint %uint_1 %21518 + OpSelectionMerge %25261 None + OpBranchConditional %7513 %23873 %25261 + %23873 = OpLabel + %6992 = OpIAdd %uint %23256 %9130 + OpBranch %25261 + %25261 = OpLabel + %24188 = OpPhi %uint %23256 %23776 %6992 %23873 + %24753 = OpIEqual %bool %12535 %uint_1 + OpSelectionMerge %20259 DontFlatten + OpBranchConditional %24753 %9761 %12129 + %12129 = OpLabel + %19407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24188 + %23875 = OpLoad %uint %19407 + %11687 = OpIAdd %uint %24188 %12535 + %6475 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11687 + %24155 = OpLoad %uint %6475 + %6234 = OpIMul %uint %uint_2 %12535 + %8353 = OpIAdd %uint %24188 %6234 + %15309 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8353 + %24156 = OpLoad %uint %15309 + %6235 = OpIMul %uint %uint_3 %12535 + %8354 = OpIAdd %uint %24188 %6235 + %14321 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8354 + %14156 = OpLoad %uint %14321 + %19670 = OpCompositeConstruct %v4uint %23875 %24155 %24156 %14156 + %17048 = OpIMul %uint %uint_4 %12535 + %13991 = OpIAdd %uint %24188 %17048 + %15310 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13991 + %24157 = OpLoad %uint %15310 + %6236 = OpIMul %uint %uint_5 %12535 + %8355 = OpIAdd %uint %24188 %6236 + %15311 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8355 + %24158 = OpLoad %uint %15311 + %6237 = OpIMul %uint %uint_6 %12535 + %8356 = OpIAdd %uint %24188 %6237 + %15312 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8356 + %24159 = OpLoad %uint %15312 + %6238 = OpIMul %uint %uint_7 %12535 + %8357 = OpIAdd %uint %24188 %6238 + %14322 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8357 + %16379 = OpLoad %uint %14322 + %20780 = OpCompositeConstruct %v4uint %24157 %24158 %24159 %16379 + OpBranch %20259 + %9761 = OpLabel + %21829 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24188 + %23876 = OpLoad %uint %21829 + %11688 = OpIAdd %uint %24188 %uint_1 + %6399 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11688 + %23650 = OpLoad %uint %6399 + %11689 = OpIAdd %uint %24188 %uint_2 + %6400 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11689 + %23651 = OpLoad %uint %6400 + %11690 = OpIAdd %uint %24188 %uint_3 + %24558 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11690 + %14080 = OpLoad %uint %24558 + %19165 = OpCompositeConstruct %v4uint %23876 %23650 %23651 %14080 + %22501 = OpIAdd %uint %24188 %uint_4 + %24651 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22501 + %23652 = OpLoad %uint %24651 + %11691 = OpIAdd %uint %24188 %uint_5 + %6401 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11691 + %23653 = OpLoad %uint %6401 + %11692 = OpIAdd %uint %24188 %uint_6 + %6402 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11692 + %23654 = OpLoad %uint %6402 + %11693 = OpIAdd %uint %24188 %uint_7 + %24559 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11693 + %16380 = OpLoad %uint %24559 + %20781 = OpCompositeConstruct %v4uint %23652 %23653 %23654 %16380 + OpBranch %20259 + %20259 = OpLabel + %9769 = OpPhi %v4uint %20781 %9761 %20780 %12129 + %14570 = OpPhi %v4uint %19165 %9761 %19670 %12129 + %17369 = OpINotEqual %bool %9130 %uint_0 + OpSelectionMerge %21263 DontFlatten + OpBranchConditional %17369 %21031 %22395 + %22395 = OpLabel + OpSelectionMerge %23460 None + OpSwitch %8576 %24626 0 %16005 1 %16005 2 %14402 10 %14402 3 %22975 12 %22975 4 %21190 6 %8243 + %8243 = OpLabel + %24406 = OpCompositeExtract %uint %14570 0 + %24679 = OpExtInst %v2float %1 UnpackHalf2x16 %24406 + %8852 = OpCompositeExtract %float %24679 0 + %7599 = OpCompositeExtract %uint %14570 1 + %15605 = OpExtInst %v2float %1 UnpackHalf2x16 %7599 + %8853 = OpCompositeExtract %float %15605 0 + %7600 = OpCompositeExtract %uint %14570 2 + %15606 = OpExtInst %v2float %1 UnpackHalf2x16 %7600 + %8854 = OpCompositeExtract %float %15606 0 + %7601 = OpCompositeExtract %uint %14570 3 + %15586 = OpExtInst %v2float %1 UnpackHalf2x16 %7601 + %10274 = OpCompositeExtract %float %15586 0 + %24249 = OpCompositeConstruct %v4float %8852 %8853 %8854 %10274 + %17274 = OpCompositeExtract %uint %9769 0 + %18027 = OpExtInst %v2float %1 UnpackHalf2x16 %17274 + %8855 = OpCompositeExtract %float %18027 0 + %7602 = OpCompositeExtract %uint %9769 1 + %15607 = OpExtInst %v2float %1 UnpackHalf2x16 %7602 + %8856 = OpCompositeExtract %float %15607 0 + %7603 = OpCompositeExtract %uint %9769 2 + %15608 = OpExtInst %v2float %1 UnpackHalf2x16 %7603 + %8857 = OpCompositeExtract %float %15608 0 + %7604 = OpCompositeExtract %uint %9769 3 + %15587 = OpExtInst %v2float %1 UnpackHalf2x16 %7604 + %13466 = OpCompositeExtract %float %15587 0 + %18678 = OpCompositeConstruct %v4float %8855 %8856 %8857 %13466 + OpBranch %23460 + %21190 = OpLabel + %24820 = OpBitcast %v4int %14570 + %22558 = OpShiftLeftLogical %v4int %24820 %770 + %16536 = OpShiftRightArithmetic %v4int %22558 %770 + %10903 = OpConvertSToF %v4float %16536 + %19064 = OpVectorTimesScalar %v4float %10903 %float_0_000976592302 + %18816 = OpExtInst %v4float %1 FMax %1284 %19064 + %10213 = OpBitcast %v4int %9769 + %8609 = OpShiftLeftLogical %v4int %10213 %770 + %16537 = OpShiftRightArithmetic %v4int %8609 %770 + %10904 = OpConvertSToF %v4float %16537 + %21439 = OpVectorTimesScalar %v4float %10904 %float_0_000976592302 + %17250 = OpExtInst %v4float %1 FMax %1284 %21439 + OpBranch %23460 + %22975 = OpLabel + %19462 = OpSelect %uint %7513 %uint_20 %uint_0 + %9136 = OpCompositeConstruct %v4uint %19462 %19462 %19462 %19462 + %23880 = OpShiftRightLogical %v4uint %14570 %9136 + %24038 = OpBitwiseAnd %v4uint %23880 %929 + %18588 = OpBitwiseAnd %v4uint %24038 %721 + %23440 = OpShiftRightLogical %v4uint %24038 %263 + %16585 = OpIEqual %v4bool %23440 %2896 + %11339 = OpExtInst %v4int %1 FindUMsb %18588 + %10773 = OpBitcast %v4uint %11339 + %6266 = OpISub %v4uint %263 %10773 + %8720 = OpIAdd %v4uint %10773 %2575 + %10351 = OpSelect %v4uint %16585 %8720 %23440 + %23252 = OpShiftLeftLogical %v4uint %18588 %6266 + %18842 = OpBitwiseAnd %v4uint %23252 %721 + %10909 = OpSelect %v4uint %16585 %18842 %18588 + %24569 = OpIAdd %v4uint %10351 %559 + %20351 = OpShiftLeftLogical %v4uint %24569 %1127 + %16294 = OpShiftLeftLogical %v4uint %10909 %749 + %22396 = OpBitwiseOr %v4uint %20351 %16294 + %13824 = OpIEqual %v4bool %24038 %2896 + %16962 = OpSelect %v4uint %13824 %2896 %22396 + %12356 = OpBitcast %v4float %16962 + %24638 = OpShiftRightLogical %v4uint %9769 %9136 + %14625 = OpBitwiseAnd %v4uint %24638 %929 + %18589 = OpBitwiseAnd %v4uint %14625 %721 + %23441 = OpShiftRightLogical %v4uint %14625 %263 + %16586 = OpIEqual %v4bool %23441 %2896 + %11340 = OpExtInst %v4int %1 FindUMsb %18589 + %10774 = OpBitcast %v4uint %11340 + %6267 = OpISub %v4uint %263 %10774 + %8721 = OpIAdd %v4uint %10774 %2575 + %10352 = OpSelect %v4uint %16586 %8721 %23441 + %23253 = OpShiftLeftLogical %v4uint %18589 %6267 + %18843 = OpBitwiseAnd %v4uint %23253 %721 + %10910 = OpSelect %v4uint %16586 %18843 %18589 + %24570 = OpIAdd %v4uint %10352 %559 + %20352 = OpShiftLeftLogical %v4uint %24570 %1127 + %16295 = OpShiftLeftLogical %v4uint %10910 %749 + %22397 = OpBitwiseOr %v4uint %20352 %16295 + %13825 = OpIEqual %v4bool %14625 %2896 + %18007 = OpSelect %v4uint %13825 %2896 %22397 + %22843 = OpBitcast %v4float %18007 + OpBranch %23460 + %14402 = OpLabel + %19463 = OpSelect %uint %7513 %uint_20 %uint_0 + %9137 = OpCompositeConstruct %v4uint %19463 %19463 %19463 %19463 + %22227 = OpShiftRightLogical %v4uint %14570 %9137 + %19030 = OpBitwiseAnd %v4uint %22227 %929 + %16133 = OpConvertUToF %v4float %19030 + %21018 = OpVectorTimesScalar %v4float %16133 %float_0_000977517106 + %7746 = OpShiftRightLogical %v4uint %9769 %9137 + %11220 = OpBitwiseAnd %v4uint %7746 %929 + %17178 = OpConvertUToF %v4float %11220 + %12434 = OpVectorTimesScalar %v4float %17178 %float_0_000977517106 + OpBranch %23460 + %16005 = OpLabel + %19464 = OpSelect %uint %7513 %uint_16 %uint_0 + %9138 = OpCompositeConstruct %v4uint %19464 %19464 %19464 %19464 + %22228 = OpShiftRightLogical %v4uint %14570 %9138 + %19031 = OpBitwiseAnd %v4uint %22228 %1611 + %16134 = OpConvertUToF %v4float %19031 + %21019 = OpVectorTimesScalar %v4float %16134 %float_0_00392156886 + %7747 = OpShiftRightLogical %v4uint %9769 %9138 + %11221 = OpBitwiseAnd %v4uint %7747 %1611 + %17179 = OpConvertUToF %v4float %11221 + %12435 = OpVectorTimesScalar %v4float %17179 %float_0_00392156886 + OpBranch %23460 + %24626 = OpLabel + %19231 = OpBitcast %v4float %14570 + %14514 = OpBitcast %v4float %9769 + OpBranch %23460 + %23460 = OpLabel + %11251 = OpPhi %v4float %14514 %24626 %12435 %16005 %12434 %14402 %22843 %22975 %17250 %21190 %18678 %8243 + %13709 = OpPhi %v4float %19231 %24626 %21019 %16005 %21018 %14402 %12356 %22975 %18816 %21190 %24249 %8243 + OpBranch %21263 + %21031 = OpLabel + OpSelectionMerge %23461 None + OpSwitch %8576 %12525 5 %21191 7 %8244 + %8244 = OpLabel + %24407 = OpCompositeExtract %uint %14570 0 + %24680 = OpExtInst %v2float %1 UnpackHalf2x16 %24407 + %8858 = OpCompositeExtract %float %24680 0 + %7605 = OpCompositeExtract %uint %14570 1 + %15609 = OpExtInst %v2float %1 UnpackHalf2x16 %7605 + %8859 = OpCompositeExtract %float %15609 0 + %7606 = OpCompositeExtract %uint %14570 2 + %15610 = OpExtInst %v2float %1 UnpackHalf2x16 %7606 + %8860 = OpCompositeExtract %float %15610 0 + %7607 = OpCompositeExtract %uint %14570 3 + %15588 = OpExtInst %v2float %1 UnpackHalf2x16 %7607 + %10275 = OpCompositeExtract %float %15588 0 + %24250 = OpCompositeConstruct %v4float %8858 %8859 %8860 %10275 + %17275 = OpCompositeExtract %uint %9769 0 + %18028 = OpExtInst %v2float %1 UnpackHalf2x16 %17275 + %8861 = OpCompositeExtract %float %18028 0 + %7608 = OpCompositeExtract %uint %9769 1 + %15611 = OpExtInst %v2float %1 UnpackHalf2x16 %7608 + %8862 = OpCompositeExtract %float %15611 0 + %7609 = OpCompositeExtract %uint %9769 2 + %15612 = OpExtInst %v2float %1 UnpackHalf2x16 %7609 + %8863 = OpCompositeExtract %float %15612 0 + %7610 = OpCompositeExtract %uint %9769 3 + %15589 = OpExtInst %v2float %1 UnpackHalf2x16 %7610 + %13467 = OpCompositeExtract %float %15589 0 + %18679 = OpCompositeConstruct %v4float %8861 %8862 %8863 %13467 + OpBranch %23461 + %21191 = OpLabel + %24821 = OpBitcast %v4int %14570 + %22559 = OpShiftLeftLogical %v4int %24821 %770 + %16538 = OpShiftRightArithmetic %v4int %22559 %770 + %10905 = OpConvertSToF %v4float %16538 + %19065 = OpVectorTimesScalar %v4float %10905 %float_0_000976592302 + %18817 = OpExtInst %v4float %1 FMax %1284 %19065 + %10214 = OpBitcast %v4int %9769 + %8610 = OpShiftLeftLogical %v4int %10214 %770 + %16539 = OpShiftRightArithmetic %v4int %8610 %770 + %10906 = OpConvertSToF %v4float %16539 + %21440 = OpVectorTimesScalar %v4float %10906 %float_0_000976592302 + %17251 = OpExtInst %v4float %1 FMax %1284 %21440 + OpBranch %23461 + %12525 = OpLabel + %19232 = OpBitcast %v4float %14570 + %14515 = OpBitcast %v4float %9769 + OpBranch %23461 + %23461 = OpLabel + %11252 = OpPhi %v4float %14515 %12525 %17251 %21191 %18679 %8244 + %13710 = OpPhi %v4float %19232 %12525 %18817 %21191 %24250 %8244 + OpBranch %21263 + %21263 = OpLabel + %9826 = OpPhi %v4float %11252 %23461 %11251 %23460 + %14051 = OpPhi %v4float %13710 %23461 %13709 %23460 + %11861 = OpUGreaterThanEqual %bool %16205 %uint_4 + OpSelectionMerge %21267 DontFlatten + OpBranchConditional %11861 %20709 %21267 + %20709 = OpLabel + %25083 = OpFMul %float %11052 %float_0_5 + %24184 = OpIAdd %uint %24188 %uint_80 + OpSelectionMerge %20260 DontFlatten + OpBranchConditional %24753 %9762 %12130 + %12130 = OpLabel + %19408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24184 + %23877 = OpLoad %uint %19408 + %11694 = OpIAdd %uint %24184 %12535 + %6476 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11694 + %24160 = OpLoad %uint %6476 + %6239 = OpIMul %uint %uint_2 %12535 + %8358 = OpIAdd %uint %24184 %6239 + %15313 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8358 + %24161 = OpLoad %uint %15313 + %6240 = OpIMul %uint %uint_3 %12535 + %8359 = OpIAdd %uint %24184 %6240 + %14323 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8359 + %14157 = OpLoad %uint %14323 + %19671 = OpCompositeConstruct %v4uint %23877 %24160 %24161 %14157 + %17049 = OpIMul %uint %uint_4 %12535 + %13992 = OpIAdd %uint %24184 %17049 + %15314 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13992 + %24162 = OpLoad %uint %15314 + %6241 = OpIMul %uint %uint_5 %12535 + %8360 = OpIAdd %uint %24184 %6241 + %15315 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8360 + %24163 = OpLoad %uint %15315 + %6242 = OpIMul %uint %uint_6 %12535 + %8361 = OpIAdd %uint %24184 %6242 + %15316 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8361 + %24164 = OpLoad %uint %15316 + %6243 = OpIMul %uint %uint_7 %12535 + %8362 = OpIAdd %uint %24184 %6243 + %14324 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8362 + %16381 = OpLoad %uint %14324 + %20782 = OpCompositeConstruct %v4uint %24162 %24163 %24164 %16381 + OpBranch %20260 + %9762 = OpLabel + %21830 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24184 + %23878 = OpLoad %uint %21830 + %11695 = OpIAdd %uint %24188 %uint_81 + %6403 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11695 + %23655 = OpLoad %uint %6403 + %11696 = OpIAdd %uint %24188 %uint_82 + %6404 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11696 + %23656 = OpLoad %uint %6404 + %11697 = OpIAdd %uint %24188 %uint_83 + %24560 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11697 + %14081 = OpLoad %uint %24560 + %19166 = OpCompositeConstruct %v4uint %23878 %23655 %23656 %14081 + %22502 = OpIAdd %uint %24188 %uint_84 + %24652 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22502 + %23657 = OpLoad %uint %24652 + %11698 = OpIAdd %uint %24188 %uint_85 + %6405 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11698 + %23658 = OpLoad %uint %6405 + %11699 = OpIAdd %uint %24188 %uint_86 + %6406 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11699 + %23659 = OpLoad %uint %6406 + %11700 = OpIAdd %uint %24188 %uint_87 + %24561 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11700 + %16382 = OpLoad %uint %24561 + %20783 = OpCompositeConstruct %v4uint %23657 %23658 %23659 %16382 + OpBranch %20260 + %20260 = OpLabel + %11213 = OpPhi %v4uint %20783 %9762 %20782 %12130 + %14093 = OpPhi %v4uint %19166 %9762 %19671 %12130 + OpSelectionMerge %21264 DontFlatten + OpBranchConditional %17369 %21032 %22398 + %22398 = OpLabel + OpSelectionMerge %23462 None + OpSwitch %8576 %24627 0 %16006 1 %16006 2 %14403 10 %14403 3 %22976 12 %22976 4 %21192 6 %8245 + %8245 = OpLabel + %24408 = OpCompositeExtract %uint %14093 0 + %24681 = OpExtInst %v2float %1 UnpackHalf2x16 %24408 + %8864 = OpCompositeExtract %float %24681 0 + %7611 = OpCompositeExtract %uint %14093 1 + %15613 = OpExtInst %v2float %1 UnpackHalf2x16 %7611 + %8865 = OpCompositeExtract %float %15613 0 + %7612 = OpCompositeExtract %uint %14093 2 + %15614 = OpExtInst %v2float %1 UnpackHalf2x16 %7612 + %8866 = OpCompositeExtract %float %15614 0 + %7613 = OpCompositeExtract %uint %14093 3 + %15590 = OpExtInst %v2float %1 UnpackHalf2x16 %7613 + %10276 = OpCompositeExtract %float %15590 0 + %24251 = OpCompositeConstruct %v4float %8864 %8865 %8866 %10276 + %17276 = OpCompositeExtract %uint %11213 0 + %18029 = OpExtInst %v2float %1 UnpackHalf2x16 %17276 + %8867 = OpCompositeExtract %float %18029 0 + %7614 = OpCompositeExtract %uint %11213 1 + %15615 = OpExtInst %v2float %1 UnpackHalf2x16 %7614 + %8868 = OpCompositeExtract %float %15615 0 + %7615 = OpCompositeExtract %uint %11213 2 + %15616 = OpExtInst %v2float %1 UnpackHalf2x16 %7615 + %8869 = OpCompositeExtract %float %15616 0 + %7616 = OpCompositeExtract %uint %11213 3 + %15591 = OpExtInst %v2float %1 UnpackHalf2x16 %7616 + %13468 = OpCompositeExtract %float %15591 0 + %18680 = OpCompositeConstruct %v4float %8867 %8868 %8869 %13468 + OpBranch %23462 + %21192 = OpLabel + %24822 = OpBitcast %v4int %14093 + %22560 = OpShiftLeftLogical %v4int %24822 %770 + %16540 = OpShiftRightArithmetic %v4int %22560 %770 + %10907 = OpConvertSToF %v4float %16540 + %19066 = OpVectorTimesScalar %v4float %10907 %float_0_000976592302 + %18818 = OpExtInst %v4float %1 FMax %1284 %19066 + %10215 = OpBitcast %v4int %11213 + %8611 = OpShiftLeftLogical %v4int %10215 %770 + %16541 = OpShiftRightArithmetic %v4int %8611 %770 + %10908 = OpConvertSToF %v4float %16541 + %21441 = OpVectorTimesScalar %v4float %10908 %float_0_000976592302 + %17252 = OpExtInst %v4float %1 FMax %1284 %21441 + OpBranch %23462 + %22976 = OpLabel + %19465 = OpSelect %uint %7513 %uint_20 %uint_0 + %9139 = OpCompositeConstruct %v4uint %19465 %19465 %19465 %19465 + %23881 = OpShiftRightLogical %v4uint %14093 %9139 + %24039 = OpBitwiseAnd %v4uint %23881 %929 + %18590 = OpBitwiseAnd %v4uint %24039 %721 + %23442 = OpShiftRightLogical %v4uint %24039 %263 + %16587 = OpIEqual %v4bool %23442 %2896 + %11341 = OpExtInst %v4int %1 FindUMsb %18590 + %10775 = OpBitcast %v4uint %11341 + %6268 = OpISub %v4uint %263 %10775 + %8722 = OpIAdd %v4uint %10775 %2575 + %10353 = OpSelect %v4uint %16587 %8722 %23442 + %23254 = OpShiftLeftLogical %v4uint %18590 %6268 + %18844 = OpBitwiseAnd %v4uint %23254 %721 + %10911 = OpSelect %v4uint %16587 %18844 %18590 + %24571 = OpIAdd %v4uint %10353 %559 + %20353 = OpShiftLeftLogical %v4uint %24571 %1127 + %16296 = OpShiftLeftLogical %v4uint %10911 %749 + %22399 = OpBitwiseOr %v4uint %20353 %16296 + %13826 = OpIEqual %v4bool %24039 %2896 + %16963 = OpSelect %v4uint %13826 %2896 %22399 + %12357 = OpBitcast %v4float %16963 + %24639 = OpShiftRightLogical %v4uint %11213 %9139 + %14626 = OpBitwiseAnd %v4uint %24639 %929 + %18591 = OpBitwiseAnd %v4uint %14626 %721 + %23443 = OpShiftRightLogical %v4uint %14626 %263 + %16588 = OpIEqual %v4bool %23443 %2896 + %11342 = OpExtInst %v4int %1 FindUMsb %18591 + %10776 = OpBitcast %v4uint %11342 + %6269 = OpISub %v4uint %263 %10776 + %8723 = OpIAdd %v4uint %10776 %2575 + %10354 = OpSelect %v4uint %16588 %8723 %23443 + %23255 = OpShiftLeftLogical %v4uint %18591 %6269 + %18845 = OpBitwiseAnd %v4uint %23255 %721 + %10912 = OpSelect %v4uint %16588 %18845 %18591 + %24572 = OpIAdd %v4uint %10354 %559 + %20354 = OpShiftLeftLogical %v4uint %24572 %1127 + %16297 = OpShiftLeftLogical %v4uint %10912 %749 + %22400 = OpBitwiseOr %v4uint %20354 %16297 + %13827 = OpIEqual %v4bool %14626 %2896 + %18008 = OpSelect %v4uint %13827 %2896 %22400 + %22844 = OpBitcast %v4float %18008 + OpBranch %23462 + %14403 = OpLabel + %19466 = OpSelect %uint %7513 %uint_20 %uint_0 + %9140 = OpCompositeConstruct %v4uint %19466 %19466 %19466 %19466 + %22229 = OpShiftRightLogical %v4uint %14093 %9140 + %19032 = OpBitwiseAnd %v4uint %22229 %929 + %16135 = OpConvertUToF %v4float %19032 + %21020 = OpVectorTimesScalar %v4float %16135 %float_0_000977517106 + %7748 = OpShiftRightLogical %v4uint %11213 %9140 + %11222 = OpBitwiseAnd %v4uint %7748 %929 + %17180 = OpConvertUToF %v4float %11222 + %12436 = OpVectorTimesScalar %v4float %17180 %float_0_000977517106 + OpBranch %23462 + %16006 = OpLabel + %19467 = OpSelect %uint %7513 %uint_16 %uint_0 + %9141 = OpCompositeConstruct %v4uint %19467 %19467 %19467 %19467 + %22230 = OpShiftRightLogical %v4uint %14093 %9141 + %19033 = OpBitwiseAnd %v4uint %22230 %1611 + %16136 = OpConvertUToF %v4float %19033 + %21021 = OpVectorTimesScalar %v4float %16136 %float_0_00392156886 + %7749 = OpShiftRightLogical %v4uint %11213 %9141 + %11223 = OpBitwiseAnd %v4uint %7749 %1611 + %17181 = OpConvertUToF %v4float %11223 + %12437 = OpVectorTimesScalar %v4float %17181 %float_0_00392156886 + OpBranch %23462 + %24627 = OpLabel + %19233 = OpBitcast %v4float %14093 + %14516 = OpBitcast %v4float %11213 + OpBranch %23462 + %23462 = OpLabel + %11253 = OpPhi %v4float %14516 %24627 %12437 %16006 %12436 %14403 %22844 %22976 %17252 %21192 %18680 %8245 + %13712 = OpPhi %v4float %19233 %24627 %21021 %16006 %21020 %14403 %12357 %22976 %18818 %21192 %24251 %8245 + OpBranch %21264 + %21032 = OpLabel + OpSelectionMerge %23463 None + OpSwitch %8576 %12526 5 %21193 7 %8246 + %8246 = OpLabel + %24409 = OpCompositeExtract %uint %14093 0 + %24682 = OpExtInst %v2float %1 UnpackHalf2x16 %24409 + %8870 = OpCompositeExtract %float %24682 0 + %7617 = OpCompositeExtract %uint %14093 1 + %15617 = OpExtInst %v2float %1 UnpackHalf2x16 %7617 + %8872 = OpCompositeExtract %float %15617 0 + %7618 = OpCompositeExtract %uint %14093 2 + %15618 = OpExtInst %v2float %1 UnpackHalf2x16 %7618 + %8873 = OpCompositeExtract %float %15618 0 + %7619 = OpCompositeExtract %uint %14093 3 + %15592 = OpExtInst %v2float %1 UnpackHalf2x16 %7619 + %10277 = OpCompositeExtract %float %15592 0 + %24252 = OpCompositeConstruct %v4float %8870 %8872 %8873 %10277 + %17277 = OpCompositeExtract %uint %11213 0 + %18030 = OpExtInst %v2float %1 UnpackHalf2x16 %17277 + %8874 = OpCompositeExtract %float %18030 0 + %7620 = OpCompositeExtract %uint %11213 1 + %15619 = OpExtInst %v2float %1 UnpackHalf2x16 %7620 + %8875 = OpCompositeExtract %float %15619 0 + %7621 = OpCompositeExtract %uint %11213 2 + %15620 = OpExtInst %v2float %1 UnpackHalf2x16 %7621 + %8876 = OpCompositeExtract %float %15620 0 + %7622 = OpCompositeExtract %uint %11213 3 + %15593 = OpExtInst %v2float %1 UnpackHalf2x16 %7622 + %13469 = OpCompositeExtract %float %15593 0 + %18681 = OpCompositeConstruct %v4float %8874 %8875 %8876 %13469 + OpBranch %23463 + %21193 = OpLabel + %24823 = OpBitcast %v4int %14093 + %22561 = OpShiftLeftLogical %v4int %24823 %770 + %16542 = OpShiftRightArithmetic %v4int %22561 %770 + %10913 = OpConvertSToF %v4float %16542 + %19067 = OpVectorTimesScalar %v4float %10913 %float_0_000976592302 + %18819 = OpExtInst %v4float %1 FMax %1284 %19067 + %10216 = OpBitcast %v4int %11213 + %8612 = OpShiftLeftLogical %v4int %10216 %770 + %16543 = OpShiftRightArithmetic %v4int %8612 %770 + %10914 = OpConvertSToF %v4float %16543 + %21442 = OpVectorTimesScalar %v4float %10914 %float_0_000976592302 + %17253 = OpExtInst %v4float %1 FMax %1284 %21442 + OpBranch %23463 + %12526 = OpLabel + %19234 = OpBitcast %v4float %14093 + %14517 = OpBitcast %v4float %11213 + OpBranch %23463 + %23463 = OpLabel + %11254 = OpPhi %v4float %14517 %12526 %17253 %21193 %18681 %8246 + %13713 = OpPhi %v4float %19234 %12526 %18819 %21193 %24252 %8246 + OpBranch %21264 + %21264 = OpLabel + %8971 = OpPhi %v4float %11254 %23463 %11253 %23462 + %19594 = OpPhi %v4float %13713 %23463 %13712 %23462 + %18096 = OpFAdd %v4float %14051 %19594 + %17754 = OpFAdd %v4float %9826 %8971 + %14461 = OpUGreaterThanEqual %bool %16205 %uint_6 + OpSelectionMerge %24264 DontFlatten + OpBranchConditional %14461 %9905 %24264 + %9905 = OpLabel + %14258 = OpShiftLeftLogical %uint %uint_1 %9130 + %12090 = OpFMul %float %11052 %float_0_25 + %20988 = OpIAdd %uint %24188 %14258 + OpSelectionMerge %20261 DontFlatten + OpBranchConditional %24753 %9763 %12131 + %12131 = OpLabel + %19409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23879 = OpLoad %uint %19409 + %11701 = OpIAdd %uint %20988 %12535 + %6477 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11701 + %24165 = OpLoad %uint %6477 + %6244 = OpIMul %uint %uint_2 %12535 + %8363 = OpIAdd %uint %20988 %6244 + %15317 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8363 + %24166 = OpLoad %uint %15317 + %6245 = OpIMul %uint %uint_3 %12535 + %8364 = OpIAdd %uint %20988 %6245 + %14325 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8364 + %14158 = OpLoad %uint %14325 + %19672 = OpCompositeConstruct %v4uint %23879 %24165 %24166 %14158 + %17050 = OpIMul %uint %uint_4 %12535 + %13993 = OpIAdd %uint %20988 %17050 + %15318 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13993 + %24167 = OpLoad %uint %15318 + %6246 = OpIMul %uint %uint_5 %12535 + %8365 = OpIAdd %uint %20988 %6246 + %15319 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8365 + %24168 = OpLoad %uint %15319 + %6247 = OpIMul %uint %uint_6 %12535 + %8366 = OpIAdd %uint %20988 %6247 + %15320 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8366 + %24169 = OpLoad %uint %15320 + %6248 = OpIMul %uint %uint_7 %12535 + %8367 = OpIAdd %uint %20988 %6248 + %14326 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8367 + %16383 = OpLoad %uint %14326 + %20784 = OpCompositeConstruct %v4uint %24167 %24168 %24169 %16383 + OpBranch %20261 + %9763 = OpLabel + %21831 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23882 = OpLoad %uint %21831 + %11702 = OpIAdd %uint %20988 %uint_1 + %6407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11702 + %23660 = OpLoad %uint %6407 + %11703 = OpIAdd %uint %20988 %uint_2 + %6408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11703 + %23661 = OpLoad %uint %6408 + %11704 = OpIAdd %uint %20988 %uint_3 + %24562 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11704 + %14082 = OpLoad %uint %24562 + %19167 = OpCompositeConstruct %v4uint %23882 %23660 %23661 %14082 + %22503 = OpIAdd %uint %20988 %uint_4 + %24653 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22503 + %23662 = OpLoad %uint %24653 + %11705 = OpIAdd %uint %20988 %uint_5 + %6409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11705 + %23663 = OpLoad %uint %6409 + %11706 = OpIAdd %uint %20988 %uint_6 + %6410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11706 + %23664 = OpLoad %uint %6410 + %11707 = OpIAdd %uint %20988 %uint_7 + %24563 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11707 + %16384 = OpLoad %uint %24563 + %20785 = OpCompositeConstruct %v4uint %23662 %23663 %23664 %16384 + OpBranch %20261 + %20261 = OpLabel + %11214 = OpPhi %v4uint %20785 %9763 %20784 %12131 + %14094 = OpPhi %v4uint %19167 %9763 %19672 %12131 + OpSelectionMerge %21265 DontFlatten + OpBranchConditional %17369 %21033 %22401 + %22401 = OpLabel + OpSelectionMerge %23464 None + OpSwitch %8576 %24628 0 %16007 1 %16007 2 %14404 10 %14404 3 %22977 12 %22977 4 %21194 6 %8247 + %8247 = OpLabel + %24410 = OpCompositeExtract %uint %14094 0 + %24683 = OpExtInst %v2float %1 UnpackHalf2x16 %24410 + %8877 = OpCompositeExtract %float %24683 0 + %7623 = OpCompositeExtract %uint %14094 1 + %15621 = OpExtInst %v2float %1 UnpackHalf2x16 %7623 + %8878 = OpCompositeExtract %float %15621 0 + %7624 = OpCompositeExtract %uint %14094 2 + %15622 = OpExtInst %v2float %1 UnpackHalf2x16 %7624 + %8879 = OpCompositeExtract %float %15622 0 + %7625 = OpCompositeExtract %uint %14094 3 + %15594 = OpExtInst %v2float %1 UnpackHalf2x16 %7625 + %10278 = OpCompositeExtract %float %15594 0 + %24253 = OpCompositeConstruct %v4float %8877 %8878 %8879 %10278 + %17278 = OpCompositeExtract %uint %11214 0 + %18031 = OpExtInst %v2float %1 UnpackHalf2x16 %17278 + %8880 = OpCompositeExtract %float %18031 0 + %7626 = OpCompositeExtract %uint %11214 1 + %15623 = OpExtInst %v2float %1 UnpackHalf2x16 %7626 + %8881 = OpCompositeExtract %float %15623 0 + %7627 = OpCompositeExtract %uint %11214 2 + %15624 = OpExtInst %v2float %1 UnpackHalf2x16 %7627 + %8882 = OpCompositeExtract %float %15624 0 + %7628 = OpCompositeExtract %uint %11214 3 + %15595 = OpExtInst %v2float %1 UnpackHalf2x16 %7628 + %13470 = OpCompositeExtract %float %15595 0 + %18682 = OpCompositeConstruct %v4float %8880 %8881 %8882 %13470 + OpBranch %23464 + %21194 = OpLabel + %24824 = OpBitcast %v4int %14094 + %22562 = OpShiftLeftLogical %v4int %24824 %770 + %16544 = OpShiftRightArithmetic %v4int %22562 %770 + %10915 = OpConvertSToF %v4float %16544 + %19068 = OpVectorTimesScalar %v4float %10915 %float_0_000976592302 + %18820 = OpExtInst %v4float %1 FMax %1284 %19068 + %10217 = OpBitcast %v4int %11214 + %8613 = OpShiftLeftLogical %v4int %10217 %770 + %16545 = OpShiftRightArithmetic %v4int %8613 %770 + %10916 = OpConvertSToF %v4float %16545 + %21443 = OpVectorTimesScalar %v4float %10916 %float_0_000976592302 + %17254 = OpExtInst %v4float %1 FMax %1284 %21443 + OpBranch %23464 + %22977 = OpLabel + %19468 = OpSelect %uint %7513 %uint_20 %uint_0 + %9142 = OpCompositeConstruct %v4uint %19468 %19468 %19468 %19468 + %23883 = OpShiftRightLogical %v4uint %14094 %9142 + %24040 = OpBitwiseAnd %v4uint %23883 %929 + %18592 = OpBitwiseAnd %v4uint %24040 %721 + %23444 = OpShiftRightLogical %v4uint %24040 %263 + %16589 = OpIEqual %v4bool %23444 %2896 + %11343 = OpExtInst %v4int %1 FindUMsb %18592 + %10777 = OpBitcast %v4uint %11343 + %6270 = OpISub %v4uint %263 %10777 + %8724 = OpIAdd %v4uint %10777 %2575 + %10355 = OpSelect %v4uint %16589 %8724 %23444 + %23257 = OpShiftLeftLogical %v4uint %18592 %6270 + %18846 = OpBitwiseAnd %v4uint %23257 %721 + %10917 = OpSelect %v4uint %16589 %18846 %18592 + %24573 = OpIAdd %v4uint %10355 %559 + %20355 = OpShiftLeftLogical %v4uint %24573 %1127 + %16298 = OpShiftLeftLogical %v4uint %10917 %749 + %22402 = OpBitwiseOr %v4uint %20355 %16298 + %13828 = OpIEqual %v4bool %24040 %2896 + %16964 = OpSelect %v4uint %13828 %2896 %22402 + %12358 = OpBitcast %v4float %16964 + %24640 = OpShiftRightLogical %v4uint %11214 %9142 + %14627 = OpBitwiseAnd %v4uint %24640 %929 + %18593 = OpBitwiseAnd %v4uint %14627 %721 + %23445 = OpShiftRightLogical %v4uint %14627 %263 + %16590 = OpIEqual %v4bool %23445 %2896 + %11344 = OpExtInst %v4int %1 FindUMsb %18593 + %10778 = OpBitcast %v4uint %11344 + %6271 = OpISub %v4uint %263 %10778 + %8725 = OpIAdd %v4uint %10778 %2575 + %10356 = OpSelect %v4uint %16590 %8725 %23445 + %23258 = OpShiftLeftLogical %v4uint %18593 %6271 + %18847 = OpBitwiseAnd %v4uint %23258 %721 + %10918 = OpSelect %v4uint %16590 %18847 %18593 + %24574 = OpIAdd %v4uint %10356 %559 + %20356 = OpShiftLeftLogical %v4uint %24574 %1127 + %16299 = OpShiftLeftLogical %v4uint %10918 %749 + %22403 = OpBitwiseOr %v4uint %20356 %16299 + %13829 = OpIEqual %v4bool %14627 %2896 + %18009 = OpSelect %v4uint %13829 %2896 %22403 + %22845 = OpBitcast %v4float %18009 + OpBranch %23464 + %14404 = OpLabel + %19469 = OpSelect %uint %7513 %uint_20 %uint_0 + %9143 = OpCompositeConstruct %v4uint %19469 %19469 %19469 %19469 + %22231 = OpShiftRightLogical %v4uint %14094 %9143 + %19034 = OpBitwiseAnd %v4uint %22231 %929 + %16137 = OpConvertUToF %v4float %19034 + %21022 = OpVectorTimesScalar %v4float %16137 %float_0_000977517106 + %7750 = OpShiftRightLogical %v4uint %11214 %9143 + %11224 = OpBitwiseAnd %v4uint %7750 %929 + %17182 = OpConvertUToF %v4float %11224 + %12438 = OpVectorTimesScalar %v4float %17182 %float_0_000977517106 + OpBranch %23464 + %16007 = OpLabel + %19470 = OpSelect %uint %7513 %uint_16 %uint_0 + %9144 = OpCompositeConstruct %v4uint %19470 %19470 %19470 %19470 + %22232 = OpShiftRightLogical %v4uint %14094 %9144 + %19035 = OpBitwiseAnd %v4uint %22232 %1611 + %16138 = OpConvertUToF %v4float %19035 + %21023 = OpVectorTimesScalar %v4float %16138 %float_0_00392156886 + %7751 = OpShiftRightLogical %v4uint %11214 %9144 + %11225 = OpBitwiseAnd %v4uint %7751 %1611 + %17183 = OpConvertUToF %v4float %11225 + %12439 = OpVectorTimesScalar %v4float %17183 %float_0_00392156886 + OpBranch %23464 + %24628 = OpLabel + %19235 = OpBitcast %v4float %14094 + %14518 = OpBitcast %v4float %11214 + OpBranch %23464 + %23464 = OpLabel + %11255 = OpPhi %v4float %14518 %24628 %12439 %16007 %12438 %14404 %22845 %22977 %17254 %21194 %18682 %8247 + %13714 = OpPhi %v4float %19235 %24628 %21023 %16007 %21022 %14404 %12358 %22977 %18820 %21194 %24253 %8247 + OpBranch %21265 + %21033 = OpLabel + OpSelectionMerge %23465 None + OpSwitch %8576 %12527 5 %21195 7 %8248 + %8248 = OpLabel + %24411 = OpCompositeExtract %uint %14094 0 + %24684 = OpExtInst %v2float %1 UnpackHalf2x16 %24411 + %8883 = OpCompositeExtract %float %24684 0 + %7629 = OpCompositeExtract %uint %14094 1 + %15625 = OpExtInst %v2float %1 UnpackHalf2x16 %7629 + %8884 = OpCompositeExtract %float %15625 0 + %7630 = OpCompositeExtract %uint %14094 2 + %15626 = OpExtInst %v2float %1 UnpackHalf2x16 %7630 + %8885 = OpCompositeExtract %float %15626 0 + %7631 = OpCompositeExtract %uint %14094 3 + %15596 = OpExtInst %v2float %1 UnpackHalf2x16 %7631 + %10279 = OpCompositeExtract %float %15596 0 + %24254 = OpCompositeConstruct %v4float %8883 %8884 %8885 %10279 + %17279 = OpCompositeExtract %uint %11214 0 + %18032 = OpExtInst %v2float %1 UnpackHalf2x16 %17279 + %8886 = OpCompositeExtract %float %18032 0 + %7632 = OpCompositeExtract %uint %11214 1 + %15628 = OpExtInst %v2float %1 UnpackHalf2x16 %7632 + %8887 = OpCompositeExtract %float %15628 0 + %7633 = OpCompositeExtract %uint %11214 2 + %15629 = OpExtInst %v2float %1 UnpackHalf2x16 %7633 + %8888 = OpCompositeExtract %float %15629 0 + %7634 = OpCompositeExtract %uint %11214 3 + %15597 = OpExtInst %v2float %1 UnpackHalf2x16 %7634 + %13471 = OpCompositeExtract %float %15597 0 + %18683 = OpCompositeConstruct %v4float %8886 %8887 %8888 %13471 + OpBranch %23465 + %21195 = OpLabel + %24825 = OpBitcast %v4int %14094 + %22563 = OpShiftLeftLogical %v4int %24825 %770 + %16546 = OpShiftRightArithmetic %v4int %22563 %770 + %10919 = OpConvertSToF %v4float %16546 + %19069 = OpVectorTimesScalar %v4float %10919 %float_0_000976592302 + %18821 = OpExtInst %v4float %1 FMax %1284 %19069 + %10218 = OpBitcast %v4int %11214 + %8614 = OpShiftLeftLogical %v4int %10218 %770 + %16547 = OpShiftRightArithmetic %v4int %8614 %770 + %10920 = OpConvertSToF %v4float %16547 + %21444 = OpVectorTimesScalar %v4float %10920 %float_0_000976592302 + %17255 = OpExtInst %v4float %1 FMax %1284 %21444 + OpBranch %23465 + %12527 = OpLabel + %19236 = OpBitcast %v4float %14094 + %14519 = OpBitcast %v4float %11214 + OpBranch %23465 + %23465 = OpLabel + %11256 = OpPhi %v4float %14519 %12527 %17255 %21195 %18683 %8248 + %13715 = OpPhi %v4float %19236 %12527 %18821 %21195 %24254 %8248 + OpBranch %21265 + %21265 = OpLabel + %8972 = OpPhi %v4float %11256 %23465 %11255 %23464 + %19595 = OpPhi %v4float %13715 %23465 %13714 %23464 + %17222 = OpFAdd %v4float %18096 %19595 + %6641 = OpFAdd %v4float %17754 %8972 + %16376 = OpIAdd %uint %24184 %14258 + OpSelectionMerge %20262 DontFlatten + OpBranchConditional %24753 %9764 %12132 + %12132 = OpLabel + %19410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23884 = OpLoad %uint %19410 + %11708 = OpIAdd %uint %16376 %12535 + %6478 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11708 + %24170 = OpLoad %uint %6478 + %6249 = OpIMul %uint %uint_2 %12535 + %8368 = OpIAdd %uint %16376 %6249 + %15321 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8368 + %24171 = OpLoad %uint %15321 + %6250 = OpIMul %uint %uint_3 %12535 + %8369 = OpIAdd %uint %16376 %6250 + %14327 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8369 + %14159 = OpLoad %uint %14327 + %19673 = OpCompositeConstruct %v4uint %23884 %24170 %24171 %14159 + %17051 = OpIMul %uint %uint_4 %12535 + %13994 = OpIAdd %uint %16376 %17051 + %15322 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13994 + %24172 = OpLoad %uint %15322 + %6251 = OpIMul %uint %uint_5 %12535 + %8370 = OpIAdd %uint %16376 %6251 + %15323 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8370 + %24173 = OpLoad %uint %15323 + %6252 = OpIMul %uint %uint_6 %12535 + %8371 = OpIAdd %uint %16376 %6252 + %15324 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8371 + %24174 = OpLoad %uint %15324 + %6253 = OpIMul %uint %uint_7 %12535 + %8372 = OpIAdd %uint %16376 %6253 + %14328 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8372 + %16385 = OpLoad %uint %14328 + %20786 = OpCompositeConstruct %v4uint %24172 %24173 %24174 %16385 + OpBranch %20262 + %9764 = OpLabel + %21832 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23885 = OpLoad %uint %21832 + %11709 = OpIAdd %uint %16376 %uint_1 + %6411 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11709 + %23665 = OpLoad %uint %6411 + %11710 = OpIAdd %uint %16376 %uint_2 + %6412 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11710 + %23666 = OpLoad %uint %6412 + %11711 = OpIAdd %uint %16376 %uint_3 + %24564 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11711 + %14083 = OpLoad %uint %24564 + %19168 = OpCompositeConstruct %v4uint %23885 %23665 %23666 %14083 + %22504 = OpIAdd %uint %16376 %uint_4 + %24654 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22504 + %23667 = OpLoad %uint %24654 + %11712 = OpIAdd %uint %16376 %uint_5 + %6413 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11712 + %23668 = OpLoad %uint %6413 + %11713 = OpIAdd %uint %16376 %uint_6 + %6414 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11713 + %23669 = OpLoad %uint %6414 + %11714 = OpIAdd %uint %16376 %uint_7 + %24565 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11714 + %16386 = OpLoad %uint %24565 + %20787 = OpCompositeConstruct %v4uint %23667 %23668 %23669 %16386 + OpBranch %20262 + %20262 = OpLabel + %11215 = OpPhi %v4uint %20787 %9764 %20786 %12132 + %14095 = OpPhi %v4uint %19168 %9764 %19673 %12132 + OpSelectionMerge %21266 DontFlatten + OpBranchConditional %17369 %21034 %22404 + %22404 = OpLabel + OpSelectionMerge %23466 None + OpSwitch %8576 %24629 0 %16008 1 %16008 2 %14405 10 %14405 3 %22978 12 %22978 4 %21196 6 %8249 + %8249 = OpLabel + %24412 = OpCompositeExtract %uint %14095 0 + %24685 = OpExtInst %v2float %1 UnpackHalf2x16 %24412 + %8889 = OpCompositeExtract %float %24685 0 + %7635 = OpCompositeExtract %uint %14095 1 + %15630 = OpExtInst %v2float %1 UnpackHalf2x16 %7635 + %8890 = OpCompositeExtract %float %15630 0 + %7636 = OpCompositeExtract %uint %14095 2 + %15631 = OpExtInst %v2float %1 UnpackHalf2x16 %7636 + %8891 = OpCompositeExtract %float %15631 0 + %7637 = OpCompositeExtract %uint %14095 3 + %15598 = OpExtInst %v2float %1 UnpackHalf2x16 %7637 + %10280 = OpCompositeExtract %float %15598 0 + %24255 = OpCompositeConstruct %v4float %8889 %8890 %8891 %10280 + %17280 = OpCompositeExtract %uint %11215 0 + %18033 = OpExtInst %v2float %1 UnpackHalf2x16 %17280 + %8892 = OpCompositeExtract %float %18033 0 + %7638 = OpCompositeExtract %uint %11215 1 + %15632 = OpExtInst %v2float %1 UnpackHalf2x16 %7638 + %8893 = OpCompositeExtract %float %15632 0 + %7639 = OpCompositeExtract %uint %11215 2 + %15633 = OpExtInst %v2float %1 UnpackHalf2x16 %7639 + %8894 = OpCompositeExtract %float %15633 0 + %7640 = OpCompositeExtract %uint %11215 3 + %15599 = OpExtInst %v2float %1 UnpackHalf2x16 %7640 + %13472 = OpCompositeExtract %float %15599 0 + %18684 = OpCompositeConstruct %v4float %8892 %8893 %8894 %13472 + OpBranch %23466 + %21196 = OpLabel + %24826 = OpBitcast %v4int %14095 + %22564 = OpShiftLeftLogical %v4int %24826 %770 + %16548 = OpShiftRightArithmetic %v4int %22564 %770 + %10921 = OpConvertSToF %v4float %16548 + %19070 = OpVectorTimesScalar %v4float %10921 %float_0_000976592302 + %18822 = OpExtInst %v4float %1 FMax %1284 %19070 + %10219 = OpBitcast %v4int %11215 + %8615 = OpShiftLeftLogical %v4int %10219 %770 + %16549 = OpShiftRightArithmetic %v4int %8615 %770 + %10922 = OpConvertSToF %v4float %16549 + %21445 = OpVectorTimesScalar %v4float %10922 %float_0_000976592302 + %17256 = OpExtInst %v4float %1 FMax %1284 %21445 + OpBranch %23466 + %22978 = OpLabel + %19471 = OpSelect %uint %7513 %uint_20 %uint_0 + %9145 = OpCompositeConstruct %v4uint %19471 %19471 %19471 %19471 + %23886 = OpShiftRightLogical %v4uint %14095 %9145 + %24041 = OpBitwiseAnd %v4uint %23886 %929 + %18594 = OpBitwiseAnd %v4uint %24041 %721 + %23446 = OpShiftRightLogical %v4uint %24041 %263 + %16591 = OpIEqual %v4bool %23446 %2896 + %11345 = OpExtInst %v4int %1 FindUMsb %18594 + %10779 = OpBitcast %v4uint %11345 + %6272 = OpISub %v4uint %263 %10779 + %8726 = OpIAdd %v4uint %10779 %2575 + %10357 = OpSelect %v4uint %16591 %8726 %23446 + %23259 = OpShiftLeftLogical %v4uint %18594 %6272 + %18848 = OpBitwiseAnd %v4uint %23259 %721 + %10923 = OpSelect %v4uint %16591 %18848 %18594 + %24575 = OpIAdd %v4uint %10357 %559 + %20357 = OpShiftLeftLogical %v4uint %24575 %1127 + %16300 = OpShiftLeftLogical %v4uint %10923 %749 + %22405 = OpBitwiseOr %v4uint %20357 %16300 + %13830 = OpIEqual %v4bool %24041 %2896 + %16965 = OpSelect %v4uint %13830 %2896 %22405 + %12359 = OpBitcast %v4float %16965 + %24641 = OpShiftRightLogical %v4uint %11215 %9145 + %14628 = OpBitwiseAnd %v4uint %24641 %929 + %18595 = OpBitwiseAnd %v4uint %14628 %721 + %23447 = OpShiftRightLogical %v4uint %14628 %263 + %16592 = OpIEqual %v4bool %23447 %2896 + %11346 = OpExtInst %v4int %1 FindUMsb %18595 + %10780 = OpBitcast %v4uint %11346 + %6273 = OpISub %v4uint %263 %10780 + %8727 = OpIAdd %v4uint %10780 %2575 + %10358 = OpSelect %v4uint %16592 %8727 %23447 + %23260 = OpShiftLeftLogical %v4uint %18595 %6273 + %18849 = OpBitwiseAnd %v4uint %23260 %721 + %10924 = OpSelect %v4uint %16592 %18849 %18595 + %24576 = OpIAdd %v4uint %10358 %559 + %20358 = OpShiftLeftLogical %v4uint %24576 %1127 + %16301 = OpShiftLeftLogical %v4uint %10924 %749 + %22406 = OpBitwiseOr %v4uint %20358 %16301 + %13831 = OpIEqual %v4bool %14628 %2896 + %18010 = OpSelect %v4uint %13831 %2896 %22406 + %22846 = OpBitcast %v4float %18010 + OpBranch %23466 + %14405 = OpLabel + %19472 = OpSelect %uint %7513 %uint_20 %uint_0 + %9146 = OpCompositeConstruct %v4uint %19472 %19472 %19472 %19472 + %22233 = OpShiftRightLogical %v4uint %14095 %9146 + %19036 = OpBitwiseAnd %v4uint %22233 %929 + %16139 = OpConvertUToF %v4float %19036 + %21024 = OpVectorTimesScalar %v4float %16139 %float_0_000977517106 + %7752 = OpShiftRightLogical %v4uint %11215 %9146 + %11226 = OpBitwiseAnd %v4uint %7752 %929 + %17184 = OpConvertUToF %v4float %11226 + %12440 = OpVectorTimesScalar %v4float %17184 %float_0_000977517106 + OpBranch %23466 + %16008 = OpLabel + %19473 = OpSelect %uint %7513 %uint_16 %uint_0 + %9147 = OpCompositeConstruct %v4uint %19473 %19473 %19473 %19473 + %22234 = OpShiftRightLogical %v4uint %14095 %9147 + %19037 = OpBitwiseAnd %v4uint %22234 %1611 + %16140 = OpConvertUToF %v4float %19037 + %21025 = OpVectorTimesScalar %v4float %16140 %float_0_00392156886 + %7753 = OpShiftRightLogical %v4uint %11215 %9147 + %11227 = OpBitwiseAnd %v4uint %7753 %1611 + %17185 = OpConvertUToF %v4float %11227 + %12441 = OpVectorTimesScalar %v4float %17185 %float_0_00392156886 + OpBranch %23466 + %24629 = OpLabel + %19237 = OpBitcast %v4float %14095 + %14520 = OpBitcast %v4float %11215 + OpBranch %23466 + %23466 = OpLabel + %11257 = OpPhi %v4float %14520 %24629 %12441 %16008 %12440 %14405 %22846 %22978 %17256 %21196 %18684 %8249 + %13716 = OpPhi %v4float %19237 %24629 %21025 %16008 %21024 %14405 %12359 %22978 %18822 %21196 %24255 %8249 + OpBranch %21266 + %21034 = OpLabel + OpSelectionMerge %23467 None + OpSwitch %8576 %12528 5 %21197 7 %8250 + %8250 = OpLabel + %24413 = OpCompositeExtract %uint %14095 0 + %24686 = OpExtInst %v2float %1 UnpackHalf2x16 %24413 + %8895 = OpCompositeExtract %float %24686 0 + %7641 = OpCompositeExtract %uint %14095 1 + %15634 = OpExtInst %v2float %1 UnpackHalf2x16 %7641 + %8896 = OpCompositeExtract %float %15634 0 + %7642 = OpCompositeExtract %uint %14095 2 + %15635 = OpExtInst %v2float %1 UnpackHalf2x16 %7642 + %8897 = OpCompositeExtract %float %15635 0 + %7643 = OpCompositeExtract %uint %14095 3 + %15600 = OpExtInst %v2float %1 UnpackHalf2x16 %7643 + %10281 = OpCompositeExtract %float %15600 0 + %24256 = OpCompositeConstruct %v4float %8895 %8896 %8897 %10281 + %17281 = OpCompositeExtract %uint %11215 0 + %18034 = OpExtInst %v2float %1 UnpackHalf2x16 %17281 + %8898 = OpCompositeExtract %float %18034 0 + %7644 = OpCompositeExtract %uint %11215 1 + %15636 = OpExtInst %v2float %1 UnpackHalf2x16 %7644 + %8899 = OpCompositeExtract %float %15636 0 + %7645 = OpCompositeExtract %uint %11215 2 + %15637 = OpExtInst %v2float %1 UnpackHalf2x16 %7645 + %8900 = OpCompositeExtract %float %15637 0 + %7646 = OpCompositeExtract %uint %11215 3 + %15601 = OpExtInst %v2float %1 UnpackHalf2x16 %7646 + %13473 = OpCompositeExtract %float %15601 0 + %18685 = OpCompositeConstruct %v4float %8898 %8899 %8900 %13473 + OpBranch %23467 + %21197 = OpLabel + %24827 = OpBitcast %v4int %14095 + %22565 = OpShiftLeftLogical %v4int %24827 %770 + %16550 = OpShiftRightArithmetic %v4int %22565 %770 + %10925 = OpConvertSToF %v4float %16550 + %19071 = OpVectorTimesScalar %v4float %10925 %float_0_000976592302 + %18823 = OpExtInst %v4float %1 FMax %1284 %19071 + %10220 = OpBitcast %v4int %11215 + %8616 = OpShiftLeftLogical %v4int %10220 %770 + %16551 = OpShiftRightArithmetic %v4int %8616 %770 + %10926 = OpConvertSToF %v4float %16551 + %21446 = OpVectorTimesScalar %v4float %10926 %float_0_000976592302 + %17257 = OpExtInst %v4float %1 FMax %1284 %21446 + OpBranch %23467 + %12528 = OpLabel + %19238 = OpBitcast %v4float %14095 + %14521 = OpBitcast %v4float %11215 + OpBranch %23467 + %23467 = OpLabel + %11258 = OpPhi %v4float %14521 %12528 %17257 %21197 %18685 %8250 + %13717 = OpPhi %v4float %19238 %12528 %18823 %21197 %24256 %8250 + OpBranch %21266 + %21266 = OpLabel + %8973 = OpPhi %v4float %11258 %23467 %11257 %23466 + %19596 = OpPhi %v4float %13717 %23467 %13716 %23466 + %19521 = OpFAdd %v4float %17222 %19596 + %23869 = OpFAdd %v4float %6641 %8973 + OpBranch %24264 + %24264 = OpLabel + %11175 = OpPhi %v4float %17754 %21264 %23869 %21266 + %14420 = OpPhi %v4float %18096 %21264 %19521 %21266 + %14522 = OpPhi %float %25083 %21264 %12090 %21266 + OpBranch %21267 + %21267 = OpLabel + %11176 = OpPhi %v4float %9826 %21263 %11175 %24264 + %12387 = OpPhi %v4float %14051 %21263 %14420 %24264 + %11944 = OpPhi %float %11052 %21263 %14522 %24264 + %23688 = OpVectorTimesScalar %v4float %12387 %11944 + %21344 = OpVectorTimesScalar %v4float %11176 %11944 + %7176 = OpIEqual %bool %24498 %uint_0 + %13431 = OpSelect %bool %7176 %false %7176 + OpSelectionMerge %19649 DontFlatten + OpBranchConditional %13431 %9760 %19649 + %9760 = OpLabel + %20482 = OpCompositeExtract %float %23688 1 + %14335 = OpCompositeInsert %v4float %20482 %23688 0 + OpBranch %19649 + %19649 = OpLabel + %12383 = OpPhi %v4float %23688 %21267 %14335 %9760 + %12967 = OpIAdd %v2uint %9840 %23020 + OpSelectionMerge %21237 DontFlatten + OpBranchConditional %18667 %10574 %21373 + %21373 = OpLabel + %10608 = OpBitcast %v2int %12967 + %17090 = OpCompositeExtract %int %10608 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %10608 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %15783 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_7 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %16373 = OpShiftLeftLogical %int %12600 %int_2 + %10688 = OpIAdd %int %10934 %16373 + %11527 = OpBitcast %int %10688 + %16975 = OpBitwiseAnd %int %11527 %int_n16 + %24809 = OpShiftLeftLogical %int %16975 %int_1 + %15435 = OpIAdd %int %19086 %24809 + %13207 = OpBitwiseAnd %int %11527 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18356 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18356 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12150 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12150 + %19169 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19169 %int_2 + %16708 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21587 %int_6 + %15436 = OpIAdd %int %16708 %21580 + %11782 = OpBitwiseAnd %int %16727 %int_63 + %14671 = OpIAdd %int %15436 %11782 + %22127 = OpBitcast %uint %14671 + OpBranch %21237 + %10574 = OpLabel + %19866 = OpCompositeExtract %uint %12967 0 + %11267 = OpCompositeExtract %uint %12967 1 + %8414 = OpCompositeConstruct %v3uint %19866 %11267 %17416 + %20125 = OpBitcast %v3int %8414 + %10438 = OpCompositeExtract %int %20125 1 + %9470 = OpShiftRightArithmetic %int %10438 %int_4 + %10056 = OpCompositeExtract %int %20125 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %25203 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %15783 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %20125 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_6 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12601 = OpBitwiseAnd %int %10438 %int_6 + %17741 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_6 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8728 = OpShiftRightArithmetic %int %10438 %int_3 + %13731 = OpIAdd %int %8728 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19170 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19170 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23346 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23346 %23274 + %18357 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18357 %uint_6 + %16729 = OpIAdd %int %10332 %21582 + %19171 = OpBitwiseAnd %int %10438 %int_1 + %21583 = OpShiftLeftLogical %int %19171 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23347 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10927 = OpIAdd %int %23347 %23217 + %23348 = OpShiftLeftLogical %int %10927 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10928 = OpIAdd %int %23348 %23218 + %23349 = OpShiftLeftLogical %int %10928 %int_3 + %21849 = OpBitwiseAnd %int %16730 %int_63 + %24314 = OpIAdd %int %23349 %21849 + %22128 = OpBitcast %uint %24314 + OpBranch %21237 + %21237 = OpLabel + %11376 = OpPhi %uint %22128 %10574 %22127 %21373 + %17657 = OpIAdd %uint %11376 %24237 + %24007 = OpShiftRightLogical %uint %17657 %uint_3 + %24154 = OpExtInst %v4float %1 FClamp %12383 %2938 %1285 + %9073 = OpVectorTimesScalar %v4float %24154 %float_255 + %11878 = OpFAdd %v4float %9073 %325 + %7647 = OpConvertFToU %v4uint %11878 + %8700 = OpCompositeExtract %uint %7647 0 + %12251 = OpCompositeExtract %uint %7647 1 + %11561 = OpShiftLeftLogical %uint %12251 %int_8 + %19814 = OpBitwiseOr %uint %8700 %11561 + %21476 = OpCompositeExtract %uint %7647 2 + %8560 = OpShiftLeftLogical %uint %21476 %int_16 + %19815 = OpBitwiseOr %uint %19814 %8560 + %21477 = OpCompositeExtract %uint %7647 3 + %7292 = OpShiftLeftLogical %uint %21477 %int_24 + %9255 = OpBitwiseOr %uint %19815 %7292 + %7522 = OpExtInst %v4float %1 FClamp %21344 %2938 %1285 + %8264 = OpVectorTimesScalar %v4float %7522 %float_255 + %11879 = OpFAdd %v4float %8264 %325 + %7648 = OpConvertFToU %v4uint %11879 + %8701 = OpCompositeExtract %uint %7648 0 + %12252 = OpCompositeExtract %uint %7648 1 + %11562 = OpShiftLeftLogical %uint %12252 %int_8 + %19816 = OpBitwiseOr %uint %8701 %11562 + %21478 = OpCompositeExtract %uint %7648 2 + %8561 = OpShiftLeftLogical %uint %21478 %int_16 + %19817 = OpBitwiseOr %uint %19816 %8561 + %21479 = OpCompositeExtract %uint %7648 3 + %8541 = OpShiftLeftLogical %uint %21479 %int_24 + %17498 = OpBitwiseOr %uint %19817 %8541 + %11625 = OpCompositeConstruct %v2uint %9255 %17498 + %8978 = OpAccessChain %_ptr_Uniform_v2uint %5522 %int_0 %24007 + OpStore %8978 %11625 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_full_8bpp_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000062AE, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00040047, 0x000007D0, 0x00000006, 0x00000004, + 0x00030047, 0x0000079C, 0x00000003, 0x00040048, 0x0000079C, 0x00000000, 0x00000018, 0x00050048, + 0x0000079C, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000CC7, 0x00000018, 0x00040047, + 0x00000CC7, 0x00000021, 0x00000000, 0x00040047, 0x00000CC7, 0x00000022, 0x00000000, 0x00030047, + 0x0000040C, 0x00000002, 0x00050048, 0x0000040C, 0x00000000, 0x00000023, 0x00000000, 0x00050048, + 0x0000040C, 0x00000001, 0x00000023, 0x00000004, 0x00050048, 0x0000040C, 0x00000002, 0x00000023, + 0x00000008, 0x00050048, 0x0000040C, 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x0000040C, + 0x00000004, 0x00000023, 0x00000010, 0x00040047, 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, + 0x000007D6, 0x00000006, 0x00000008, 0x00030047, 0x000007A8, 0x00000003, 0x00040048, 0x000007A8, + 0x00000000, 0x00000019, 0x00050048, 0x000007A8, 0x00000000, 0x00000023, 0x00000000, 0x00030047, + 0x00001592, 0x00000019, 0x00040047, 0x00001592, 0x00000021, 0x00000000, 0x00040047, 0x00001592, + 0x00000022, 0x00000001, 0x00040047, 0x00000AC7, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, + 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, + 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00030016, + 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x00020014, 0x00000009, + 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, + 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, + 0x0004002B, 0x0000000D, 0x0000008A, 0x3F800000, 0x00040017, 0x0000001A, 0x0000000C, 0x00000004, + 0x0004002B, 0x0000000D, 0x00000540, 0x437F0000, 0x0004002B, 0x0000000D, 0x000000FC, 0x3F000000, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000C, 0x00000A53, 0x00000018, 0x0004002B, 0x0000000B, 0x00000144, 0x000000FF, + 0x0004002B, 0x0000000D, 0x0000017A, 0x3B808081, 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, + 0x0004002B, 0x0000000D, 0x000006FE, 0x3A802008, 0x0004002B, 0x0000000B, 0x00000B87, 0x0000007F, + 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x00040017, 0x00000013, 0x00000009, 0x00000004, + 0x0004002B, 0x0000000B, 0x00000B7E, 0x0000007C, 0x0004002B, 0x0000000B, 0x00000A4F, 0x00000017, + 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000D, 0x00000341, 0xBF800000, + 0x0004002B, 0x0000000D, 0x000007FE, 0x3A800100, 0x0005002C, 0x00000011, 0x0000072D, 0x00000A10, + 0x00000A0D, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0005002C, 0x00000011, 0x0000070F, + 0x00000A0A, 0x00000A0A, 0x0005002C, 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, 0x0005002C, + 0x00000011, 0x00000718, 0x00000A0D, 0x00000A0A, 0x0004002B, 0x0000000B, 0x00000AFA, 0x00000050, + 0x0005002C, 0x00000011, 0x00000A9F, 0x00000AFA, 0x00000A3A, 0x0004002B, 0x0000000C, 0x00000A1A, + 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000C, 0x00000A20, + 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, + 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, + 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, + 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, + 0x00000003, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A1D, + 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, + 0x00000004, 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, 0x0004002B, 0x0000000C, 0x0000078B, + 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0003001D, 0x000007D0, 0x0000000B, + 0x0003001E, 0x0000079C, 0x000007D0, 0x00040020, 0x00000A1B, 0x00000002, 0x0000079C, 0x0004003B, + 0x00000A1B, 0x00000CC7, 0x00000002, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, + 0x00000288, 0x00000002, 0x0000000B, 0x0007001E, 0x0000040C, 0x0000000B, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000688, 0x00000009, 0x0000040C, 0x0004003B, 0x00000688, + 0x00000CE9, 0x00000009, 0x00040020, 0x00000289, 0x00000009, 0x0000000B, 0x0004002B, 0x0000000B, + 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, 0x0004002B, 0x0000000B, + 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A52, 0x00000018, 0x0004002B, 0x0000000B, + 0x00000A37, 0x0000000F, 0x0004002B, 0x0000000B, 0x00000A5E, 0x0000001C, 0x0005002C, 0x00000011, + 0x0000073F, 0x00000A0A, 0x00000A16, 0x0004002B, 0x0000000C, 0x00000A29, 0x0000000A, 0x0004002B, + 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A59, 0x0000001A, 0x0004002B, + 0x0000000C, 0x00000A50, 0x00000017, 0x0004002B, 0x0000000B, 0x00000926, 0x01000000, 0x0004002B, + 0x0000000B, 0x00000A46, 0x00000014, 0x0005002C, 0x00000011, 0x000008E3, 0x00000A46, 0x00000A52, + 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x0003002A, 0x00000009, 0x00000787, 0x00040017, + 0x00000015, 0x0000000D, 0x00000002, 0x00040020, 0x00000291, 0x00000001, 0x00000014, 0x0004003B, + 0x00000291, 0x00000F48, 0x00000001, 0x00040020, 0x0000028A, 0x00000001, 0x0000000B, 0x0005002C, + 0x00000011, 0x0000072A, 0x00000A13, 0x00000A0A, 0x0003001D, 0x000007D6, 0x00000011, 0x0003001E, + 0x000007A8, 0x000007D6, 0x00040020, 0x00000A25, 0x00000002, 0x000007A8, 0x0004003B, 0x00000A25, + 0x00001592, 0x00000002, 0x00040020, 0x0000028E, 0x00000002, 0x00000011, 0x0006002C, 0x00000014, + 0x00000AC7, 0x00000A22, 0x00000A22, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A37, + 0x00000A0D, 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, 0x0005002C, 0x00000011, + 0x0000084A, 0x00000A37, 0x00000A37, 0x0007002C, 0x0000001D, 0x00000504, 0x00000341, 0x00000341, + 0x00000341, 0x00000341, 0x0007002C, 0x0000001A, 0x00000302, 0x00000A3B, 0x00000A3B, 0x00000A3B, + 0x00000A3B, 0x0007002C, 0x00000017, 0x0000064B, 0x00000144, 0x00000144, 0x00000144, 0x00000144, + 0x0007002C, 0x00000017, 0x000003A1, 0x00000A44, 0x00000A44, 0x00000A44, 0x00000A44, 0x0007002C, + 0x00000017, 0x000002D1, 0x00000B87, 0x00000B87, 0x00000B87, 0x00000B87, 0x0007002C, 0x00000017, + 0x00000107, 0x00000A1F, 0x00000A1F, 0x00000A1F, 0x00000A1F, 0x0007002C, 0x00000017, 0x00000B50, + 0x00000A0A, 0x00000A0A, 0x00000A0A, 0x00000A0A, 0x0007002C, 0x00000017, 0x0000022F, 0x00000B7E, + 0x00000B7E, 0x00000B7E, 0x00000B7E, 0x0007002C, 0x00000017, 0x00000467, 0x00000A4F, 0x00000A4F, + 0x00000A4F, 0x00000A4F, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, + 0x00000A3A, 0x0007002C, 0x0000001D, 0x00000B7A, 0x00000A0C, 0x00000A0C, 0x00000A0C, 0x00000A0C, + 0x0007002C, 0x0000001D, 0x00000505, 0x0000008A, 0x0000008A, 0x0000008A, 0x0000008A, 0x0007002C, + 0x0000001D, 0x00000145, 0x000000FC, 0x000000FC, 0x000000FC, 0x000000FC, 0x0004002B, 0x0000000C, + 0x00000089, 0x3F800000, 0x0004002B, 0x0000000B, 0x00000184, 0x00000500, 0x0004002B, 0x0000000B, + 0x0000086E, 0x00280000, 0x0004002B, 0x0000000B, 0x000009F8, 0xFFFFFFFA, 0x0007002C, 0x00000017, + 0x00000A0F, 0x000009F8, 0x000009F8, 0x000009F8, 0x000009F8, 0x0004002B, 0x0000000B, 0x00000AFD, + 0x00000051, 0x0004002B, 0x0000000B, 0x00000B00, 0x00000052, 0x0004002B, 0x0000000B, 0x00000B03, + 0x00000053, 0x0004002B, 0x0000000B, 0x00000B06, 0x00000054, 0x0004002B, 0x0000000B, 0x00000B09, + 0x00000055, 0x0004002B, 0x0000000B, 0x00000B0C, 0x00000056, 0x0004002B, 0x0000000B, 0x00000B0F, + 0x00000057, 0x0004002B, 0x0000000D, 0x0000016E, 0x3E800000, 0x00050036, 0x00000008, 0x0000161F, + 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, + 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000289, 0x000056E5, 0x00000CE9, + 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003D0B, 0x000056E5, 0x00050041, 0x00000289, 0x000058AC, + 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005158, 0x000058AC, 0x000500C7, 0x0000000B, + 0x00005051, 0x00003D0B, 0x00000A44, 0x000500C2, 0x0000000B, 0x00004E0A, 0x00003D0B, 0x00000A28, + 0x000500C7, 0x0000000B, 0x0000217E, 0x00004E0A, 0x00000A13, 0x000500C2, 0x0000000B, 0x0000520A, + 0x00003D0B, 0x00000A31, 0x000500C7, 0x0000000B, 0x0000217F, 0x0000520A, 0x00000A81, 0x000500C2, + 0x0000000B, 0x0000520B, 0x00003D0B, 0x00000A52, 0x000500C7, 0x0000000B, 0x00002180, 0x0000520B, + 0x00000A37, 0x000500C2, 0x0000000B, 0x00004994, 0x00003D0B, 0x00000A5E, 0x000500C7, 0x0000000B, + 0x000023AA, 0x00004994, 0x00000A0D, 0x00050050, 0x00000011, 0x000022A7, 0x00005158, 0x00005158, + 0x000500C2, 0x00000011, 0x00002568, 0x000022A7, 0x0000073F, 0x000500C7, 0x00000011, 0x00005B53, + 0x00002568, 0x000007A2, 0x000500C4, 0x00000011, 0x00003F4F, 0x00005B53, 0x0000074E, 0x00050084, + 0x00000011, 0x000059EB, 0x00003F4F, 0x00000724, 0x000500C2, 0x0000000B, 0x00003213, 0x00005158, + 0x00000A19, 0x000500C7, 0x0000000B, 0x00003F4C, 0x00003213, 0x00000A81, 0x00050041, 0x00000289, + 0x0000492C, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, + 0x00000289, 0x000058AD, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00004FA3, 0x000058AD, + 0x000500C7, 0x0000000B, 0x00005F7D, 0x00005EAC, 0x00000A22, 0x000500AB, 0x00000009, 0x000048EB, + 0x00005F7D, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00002311, 0x00005EAC, 0x00000A16, 0x000500C7, + 0x0000000B, 0x00004408, 0x00002311, 0x00000A1F, 0x0004007C, 0x0000000C, 0x00005988, 0x00005EAC, + 0x000500C4, 0x0000000C, 0x0000358F, 0x00005988, 0x00000A29, 0x000500C3, 0x0000000C, 0x0000509C, + 0x0000358F, 0x00000A59, 0x000500C4, 0x0000000C, 0x00004702, 0x0000509C, 0x00000A50, 0x00050080, + 0x0000000C, 0x00001D26, 0x00004702, 0x00000089, 0x0004007C, 0x0000000D, 0x00002B2C, 0x00001D26, + 0x000500C7, 0x0000000B, 0x00005879, 0x00005EAC, 0x00000926, 0x000500AB, 0x00000009, 0x00001D59, + 0x00005879, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00001F43, 0x00004FA3, 0x00000A44, 0x000500C4, + 0x0000000B, 0x00003DA7, 0x00001F43, 0x00000A19, 0x000500C2, 0x0000000B, 0x0000583F, 0x00004FA3, + 0x00000A28, 0x000500C7, 0x0000000B, 0x00004BBE, 0x0000583F, 0x00000A44, 0x000500C4, 0x0000000B, + 0x00006273, 0x00004BBE, 0x00000A19, 0x00050050, 0x00000011, 0x000028B6, 0x00004FA3, 0x00004FA3, + 0x000500C2, 0x00000011, 0x00002891, 0x000028B6, 0x000008E3, 0x000500C7, 0x00000011, 0x00005B54, + 0x00002891, 0x0000084A, 0x000500C4, 0x00000011, 0x00003F50, 0x00005B54, 0x0000074E, 0x00050084, + 0x00000011, 0x000059EC, 0x00003F50, 0x00000724, 0x000500C2, 0x0000000B, 0x00003214, 0x00004FA3, + 0x00000A5E, 0x000500C7, 0x0000000B, 0x00003F4D, 0x00003214, 0x00000A1F, 0x00050041, 0x00000289, + 0x0000492D, 0x00000CE9, 0x00000A17, 0x0004003D, 0x0000000B, 0x00005EAD, 0x0000492D, 0x00050041, + 0x0000028A, 0x000056D1, 0x00000F48, 0x00000A0A, 0x0004003D, 0x0000000B, 0x00001BAD, 0x000056D1, + 0x000500AE, 0x00000009, 0x00001CED, 0x00001BAD, 0x00003F4C, 0x000300F7, 0x00004427, 0x00000002, + 0x000400FA, 0x00001CED, 0x000055E8, 0x00004427, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, + 0x000200F8, 0x00004427, 0x0004003D, 0x00000014, 0x0000392D, 0x00000F48, 0x0007004F, 0x00000011, + 0x00004849, 0x0000392D, 0x0000392D, 0x00000000, 0x00000001, 0x000500C4, 0x00000011, 0x00002670, + 0x00004849, 0x0000072A, 0x00050051, 0x0000000B, 0x00005FB2, 0x00002670, 0x00000000, 0x00050051, + 0x0000000B, 0x00001BEE, 0x00002670, 0x00000001, 0x0007000C, 0x0000000B, 0x00005F7E, 0x00000001, + 0x00000029, 0x00001BEE, 0x00000A0A, 0x00050050, 0x00000011, 0x000051EF, 0x00005FB2, 0x00005F7E, + 0x00050080, 0x00000011, 0x0000522C, 0x000051EF, 0x000059EB, 0x000500B2, 0x00000009, 0x00003ECB, + 0x00003F4D, 0x00000A13, 0x000300F7, 0x00005CE0, 0x00000000, 0x000400FA, 0x00003ECB, 0x00002AEE, + 0x00003AEF, 0x000200F8, 0x00003AEF, 0x000500AA, 0x00000009, 0x000034FE, 0x00003F4D, 0x00000A19, + 0x000600A9, 0x0000000B, 0x000020F6, 0x000034FE, 0x00000A10, 0x00000A0A, 0x000200F9, 0x00005CE0, + 0x000200F8, 0x00002AEE, 0x000200F9, 0x00005CE0, 0x000200F8, 0x00005CE0, 0x000700F5, 0x0000000B, + 0x00004B64, 0x00003F4D, 0x00002AEE, 0x000020F6, 0x00003AEF, 0x00050050, 0x00000011, 0x000041BE, + 0x0000217E, 0x0000217E, 0x000500AE, 0x0000000F, 0x00002E19, 0x000041BE, 0x0000072D, 0x000600A9, + 0x00000011, 0x00004BB5, 0x00002E19, 0x00000724, 0x0000070F, 0x000500C4, 0x00000011, 0x00002AEA, + 0x0000522C, 0x00004BB5, 0x00050050, 0x00000011, 0x0000605D, 0x00004B64, 0x00004B64, 0x000500C2, + 0x00000011, 0x00002385, 0x0000605D, 0x00000718, 0x000500C7, 0x00000011, 0x00003AEC, 0x00002385, + 0x00000724, 0x00050080, 0x00000011, 0x000027D5, 0x00002AEA, 0x00003AEC, 0x00050050, 0x00000011, + 0x00002164, 0x000023AA, 0x00000A0A, 0x000500C2, 0x00000011, 0x0000264A, 0x00000A9F, 0x00002164, + 0x00050086, 0x00000011, 0x000027A2, 0x000027D5, 0x0000264A, 0x00050051, 0x0000000B, 0x00004FA6, + 0x000027A2, 0x00000001, 0x00050084, 0x0000000B, 0x00002B26, 0x00004FA6, 0x00005051, 0x00050051, + 0x0000000B, 0x00006059, 0x000027A2, 0x00000000, 0x00050080, 0x0000000B, 0x00005420, 0x00002B26, + 0x00006059, 0x00050080, 0x0000000B, 0x00002226, 0x0000217F, 0x00005420, 0x00050084, 0x00000011, + 0x00005B31, 0x000027A2, 0x0000264A, 0x00050082, 0x00000011, 0x00002E74, 0x000027D5, 0x00005B31, + 0x00050084, 0x0000000B, 0x00001F75, 0x00002226, 0x00000184, 0x00050051, 0x0000000B, 0x00005EC7, + 0x00002E74, 0x00000001, 0x00050051, 0x0000000B, 0x00005BE6, 0x0000264A, 0x00000000, 0x00050084, + 0x0000000B, 0x00005966, 0x00005EC7, 0x00005BE6, 0x00050051, 0x0000000B, 0x00001AE6, 0x00002E74, + 0x00000000, 0x00050080, 0x0000000B, 0x000025E0, 0x00005966, 0x00001AE6, 0x000500C4, 0x0000000B, + 0x000046C4, 0x000025E0, 0x000023AA, 0x00050080, 0x0000000B, 0x00004719, 0x00001F75, 0x000046C4, + 0x00050089, 0x0000000B, 0x00005AD8, 0x00004719, 0x0000086E, 0x000500AE, 0x00000009, 0x00003361, + 0x0000217E, 0x00000A10, 0x000600A9, 0x0000000B, 0x0000609F, 0x00003361, 0x00000A0D, 0x00000A0A, + 0x00050080, 0x0000000B, 0x0000540E, 0x000023AA, 0x0000609F, 0x000500C4, 0x0000000B, 0x000030F7, + 0x00000A0D, 0x0000540E, 0x000300F7, 0x000062AD, 0x00000000, 0x000400FA, 0x00001D59, 0x00005D41, + 0x000062AD, 0x000200F8, 0x00005D41, 0x00050080, 0x0000000B, 0x00001B50, 0x00005AD8, 0x000023AA, + 0x000200F9, 0x000062AD, 0x000200F8, 0x000062AD, 0x000700F5, 0x0000000B, 0x00005E7C, 0x00005AD8, + 0x00005CE0, 0x00001B50, 0x00005D41, 0x000500AA, 0x00000009, 0x000060B1, 0x000030F7, 0x00000A0D, + 0x000300F7, 0x00004F23, 0x00000002, 0x000400FA, 0x000060B1, 0x00002621, 0x00002F61, 0x000200F8, + 0x00002F61, 0x00060041, 0x00000288, 0x00004BCF, 0x00000CC7, 0x00000A0B, 0x00005E7C, 0x0004003D, + 0x0000000B, 0x00005D43, 0x00004BCF, 0x00050080, 0x0000000B, 0x00002DA7, 0x00005E7C, 0x000030F7, + 0x00060041, 0x00000288, 0x0000194B, 0x00000CC7, 0x00000A0B, 0x00002DA7, 0x0004003D, 0x0000000B, + 0x00005E5B, 0x0000194B, 0x00050084, 0x0000000B, 0x0000185A, 0x00000A10, 0x000030F7, 0x00050080, + 0x0000000B, 0x000020A1, 0x00005E7C, 0x0000185A, 0x00060041, 0x00000288, 0x00003BCD, 0x00000CC7, + 0x00000A0B, 0x000020A1, 0x0004003D, 0x0000000B, 0x00005E5C, 0x00003BCD, 0x00050084, 0x0000000B, + 0x0000185B, 0x00000A13, 0x000030F7, 0x00050080, 0x0000000B, 0x000020A2, 0x00005E7C, 0x0000185B, + 0x00060041, 0x00000288, 0x000037F1, 0x00000CC7, 0x00000A0B, 0x000020A2, 0x0004003D, 0x0000000B, + 0x0000374C, 0x000037F1, 0x00070050, 0x00000017, 0x00004CD6, 0x00005D43, 0x00005E5B, 0x00005E5C, + 0x0000374C, 0x00050084, 0x0000000B, 0x00004298, 0x00000A16, 0x000030F7, 0x00050080, 0x0000000B, + 0x000036A7, 0x00005E7C, 0x00004298, 0x00060041, 0x00000288, 0x00003BCE, 0x00000CC7, 0x00000A0B, + 0x000036A7, 0x0004003D, 0x0000000B, 0x00005E5D, 0x00003BCE, 0x00050084, 0x0000000B, 0x0000185C, + 0x00000A19, 0x000030F7, 0x00050080, 0x0000000B, 0x000020A3, 0x00005E7C, 0x0000185C, 0x00060041, + 0x00000288, 0x00003BCF, 0x00000CC7, 0x00000A0B, 0x000020A3, 0x0004003D, 0x0000000B, 0x00005E5E, + 0x00003BCF, 0x00050084, 0x0000000B, 0x0000185D, 0x00000A1C, 0x000030F7, 0x00050080, 0x0000000B, + 0x000020A4, 0x00005E7C, 0x0000185D, 0x00060041, 0x00000288, 0x00003BD0, 0x00000CC7, 0x00000A0B, + 0x000020A4, 0x0004003D, 0x0000000B, 0x00005E5F, 0x00003BD0, 0x00050084, 0x0000000B, 0x0000185E, + 0x00000A1F, 0x000030F7, 0x00050080, 0x0000000B, 0x000020A5, 0x00005E7C, 0x0000185E, 0x00060041, + 0x00000288, 0x000037F2, 0x00000CC7, 0x00000A0B, 0x000020A5, 0x0004003D, 0x0000000B, 0x00003FFB, + 0x000037F2, 0x00070050, 0x00000017, 0x0000512C, 0x00005E5D, 0x00005E5E, 0x00005E5F, 0x00003FFB, + 0x000200F9, 0x00004F23, 0x000200F8, 0x00002621, 0x00060041, 0x00000288, 0x00005545, 0x00000CC7, + 0x00000A0B, 0x00005E7C, 0x0004003D, 0x0000000B, 0x00005D44, 0x00005545, 0x00050080, 0x0000000B, + 0x00002DA8, 0x00005E7C, 0x00000A0D, 0x00060041, 0x00000288, 0x000018FF, 0x00000CC7, 0x00000A0B, + 0x00002DA8, 0x0004003D, 0x0000000B, 0x00005C62, 0x000018FF, 0x00050080, 0x0000000B, 0x00002DA9, + 0x00005E7C, 0x00000A10, 0x00060041, 0x00000288, 0x00001900, 0x00000CC7, 0x00000A0B, 0x00002DA9, + 0x0004003D, 0x0000000B, 0x00005C63, 0x00001900, 0x00050080, 0x0000000B, 0x00002DAA, 0x00005E7C, + 0x00000A13, 0x00060041, 0x00000288, 0x00005FEE, 0x00000CC7, 0x00000A0B, 0x00002DAA, 0x0004003D, + 0x0000000B, 0x00003700, 0x00005FEE, 0x00070050, 0x00000017, 0x00004ADD, 0x00005D44, 0x00005C62, + 0x00005C63, 0x00003700, 0x00050080, 0x0000000B, 0x000057E5, 0x00005E7C, 0x00000A16, 0x00060041, + 0x00000288, 0x0000604B, 0x00000CC7, 0x00000A0B, 0x000057E5, 0x0004003D, 0x0000000B, 0x00005C64, + 0x0000604B, 0x00050080, 0x0000000B, 0x00002DAB, 0x00005E7C, 0x00000A19, 0x00060041, 0x00000288, + 0x00001901, 0x00000CC7, 0x00000A0B, 0x00002DAB, 0x0004003D, 0x0000000B, 0x00005C65, 0x00001901, + 0x00050080, 0x0000000B, 0x00002DAC, 0x00005E7C, 0x00000A1C, 0x00060041, 0x00000288, 0x00001902, + 0x00000CC7, 0x00000A0B, 0x00002DAC, 0x0004003D, 0x0000000B, 0x00005C66, 0x00001902, 0x00050080, + 0x0000000B, 0x00002DAD, 0x00005E7C, 0x00000A1F, 0x00060041, 0x00000288, 0x00005FEF, 0x00000CC7, + 0x00000A0B, 0x00002DAD, 0x0004003D, 0x0000000B, 0x00003FFC, 0x00005FEF, 0x00070050, 0x00000017, + 0x0000512D, 0x00005C64, 0x00005C65, 0x00005C66, 0x00003FFC, 0x000200F9, 0x00004F23, 0x000200F8, + 0x00004F23, 0x000700F5, 0x00000017, 0x00002629, 0x0000512D, 0x00002621, 0x0000512C, 0x00002F61, + 0x000700F5, 0x00000017, 0x000038EA, 0x00004ADD, 0x00002621, 0x00004CD6, 0x00002F61, 0x000500AB, + 0x00000009, 0x000043D9, 0x000023AA, 0x00000A0A, 0x000300F7, 0x0000530F, 0x00000002, 0x000400FA, + 0x000043D9, 0x00005227, 0x0000577B, 0x000200F8, 0x0000577B, 0x000300F7, 0x00005BA4, 0x00000000, + 0x001300FB, 0x00002180, 0x00006032, 0x00000000, 0x00003E85, 0x00000001, 0x00003E85, 0x00000002, + 0x00003842, 0x0000000A, 0x00003842, 0x00000003, 0x000059BF, 0x0000000C, 0x000059BF, 0x00000004, + 0x000052C6, 0x00000006, 0x00002033, 0x000200F8, 0x00002033, 0x00050051, 0x0000000B, 0x00005F56, + 0x000038EA, 0x00000000, 0x0006000C, 0x00000015, 0x00006067, 0x00000001, 0x0000003E, 0x00005F56, + 0x00050051, 0x0000000D, 0x00002294, 0x00006067, 0x00000000, 0x00050051, 0x0000000B, 0x00001DAF, + 0x000038EA, 0x00000001, 0x0006000C, 0x00000015, 0x00003CF5, 0x00000001, 0x0000003E, 0x00001DAF, + 0x00050051, 0x0000000D, 0x00002295, 0x00003CF5, 0x00000000, 0x00050051, 0x0000000B, 0x00001DB0, + 0x000038EA, 0x00000002, 0x0006000C, 0x00000015, 0x00003CF6, 0x00000001, 0x0000003E, 0x00001DB0, + 0x00050051, 0x0000000D, 0x00002296, 0x00003CF6, 0x00000000, 0x00050051, 0x0000000B, 0x00001DB1, + 0x000038EA, 0x00000003, 0x0006000C, 0x00000015, 0x00003CE2, 0x00000001, 0x0000003E, 0x00001DB1, + 0x00050051, 0x0000000D, 0x00002822, 0x00003CE2, 0x00000000, 0x00070050, 0x0000001D, 0x00005EB9, + 0x00002294, 0x00002295, 0x00002296, 0x00002822, 0x00050051, 0x0000000B, 0x0000437A, 0x00002629, + 0x00000000, 0x0006000C, 0x00000015, 0x0000466B, 0x00000001, 0x0000003E, 0x0000437A, 0x00050051, + 0x0000000D, 0x00002297, 0x0000466B, 0x00000000, 0x00050051, 0x0000000B, 0x00001DB2, 0x00002629, + 0x00000001, 0x0006000C, 0x00000015, 0x00003CF7, 0x00000001, 0x0000003E, 0x00001DB2, 0x00050051, + 0x0000000D, 0x00002298, 0x00003CF7, 0x00000000, 0x00050051, 0x0000000B, 0x00001DB3, 0x00002629, + 0x00000002, 0x0006000C, 0x00000015, 0x00003CF8, 0x00000001, 0x0000003E, 0x00001DB3, 0x00050051, + 0x0000000D, 0x00002299, 0x00003CF8, 0x00000000, 0x00050051, 0x0000000B, 0x00001DB4, 0x00002629, + 0x00000003, 0x0006000C, 0x00000015, 0x00003CE3, 0x00000001, 0x0000003E, 0x00001DB4, 0x00050051, + 0x0000000D, 0x0000349A, 0x00003CE3, 0x00000000, 0x00070050, 0x0000001D, 0x000048F6, 0x00002297, + 0x00002298, 0x00002299, 0x0000349A, 0x000200F9, 0x00005BA4, 0x000200F8, 0x000052C6, 0x0004007C, + 0x0000001A, 0x000060F4, 0x000038EA, 0x000500C4, 0x0000001A, 0x0000581E, 0x000060F4, 0x00000302, + 0x000500C3, 0x0000001A, 0x00004098, 0x0000581E, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A97, + 0x00004098, 0x0005008E, 0x0000001D, 0x00004A78, 0x00002A97, 0x000007FE, 0x0007000C, 0x0000001D, + 0x00004980, 0x00000001, 0x00000028, 0x00000504, 0x00004A78, 0x0004007C, 0x0000001A, 0x000027E5, + 0x00002629, 0x000500C4, 0x0000001A, 0x000021A1, 0x000027E5, 0x00000302, 0x000500C3, 0x0000001A, + 0x00004099, 0x000021A1, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A98, 0x00004099, 0x0005008E, + 0x0000001D, 0x000053BF, 0x00002A98, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004362, 0x00000001, + 0x00000028, 0x00000504, 0x000053BF, 0x000200F9, 0x00005BA4, 0x000200F8, 0x000059BF, 0x000600A9, + 0x0000000B, 0x00004C06, 0x00001D59, 0x00000A46, 0x00000A0A, 0x00070050, 0x00000017, 0x000023B0, + 0x00004C06, 0x00004C06, 0x00004C06, 0x00004C06, 0x000500C2, 0x00000017, 0x00005D48, 0x000038EA, + 0x000023B0, 0x000500C7, 0x00000017, 0x00005DE6, 0x00005D48, 0x000003A1, 0x000500C7, 0x00000017, + 0x0000489C, 0x00005DE6, 0x000002D1, 0x000500C2, 0x00000017, 0x00005B90, 0x00005DE6, 0x00000107, + 0x000500AA, 0x00000013, 0x000040C9, 0x00005B90, 0x00000B50, 0x0006000C, 0x0000001A, 0x00002C4B, + 0x00000001, 0x0000004B, 0x0000489C, 0x0004007C, 0x00000017, 0x00002A15, 0x00002C4B, 0x00050082, + 0x00000017, 0x0000187A, 0x00000107, 0x00002A15, 0x00050080, 0x00000017, 0x00002210, 0x00002A15, + 0x00000A0F, 0x000600A9, 0x00000017, 0x0000286F, 0x000040C9, 0x00002210, 0x00005B90, 0x000500C4, + 0x00000017, 0x00005AD4, 0x0000489C, 0x0000187A, 0x000500C7, 0x00000017, 0x0000499A, 0x00005AD4, + 0x000002D1, 0x000600A9, 0x00000017, 0x00002A9D, 0x000040C9, 0x0000499A, 0x0000489C, 0x00050080, + 0x00000017, 0x00005FF9, 0x0000286F, 0x0000022F, 0x000500C4, 0x00000017, 0x00004F7F, 0x00005FF9, + 0x00000467, 0x000500C4, 0x00000017, 0x00003FA6, 0x00002A9D, 0x000002ED, 0x000500C5, 0x00000017, + 0x0000577C, 0x00004F7F, 0x00003FA6, 0x000500AA, 0x00000013, 0x00003600, 0x00005DE6, 0x00000B50, + 0x000600A9, 0x00000017, 0x00004242, 0x00003600, 0x00000B50, 0x0000577C, 0x0004007C, 0x0000001D, + 0x00003044, 0x00004242, 0x000500C2, 0x00000017, 0x0000603E, 0x00002629, 0x000023B0, 0x000500C7, + 0x00000017, 0x00003921, 0x0000603E, 0x000003A1, 0x000500C7, 0x00000017, 0x0000489D, 0x00003921, + 0x000002D1, 0x000500C2, 0x00000017, 0x00005B91, 0x00003921, 0x00000107, 0x000500AA, 0x00000013, + 0x000040CA, 0x00005B91, 0x00000B50, 0x0006000C, 0x0000001A, 0x00002C4C, 0x00000001, 0x0000004B, + 0x0000489D, 0x0004007C, 0x00000017, 0x00002A16, 0x00002C4C, 0x00050082, 0x00000017, 0x0000187B, + 0x00000107, 0x00002A16, 0x00050080, 0x00000017, 0x00002211, 0x00002A16, 0x00000A0F, 0x000600A9, + 0x00000017, 0x00002870, 0x000040CA, 0x00002211, 0x00005B91, 0x000500C4, 0x00000017, 0x00005AD5, + 0x0000489D, 0x0000187B, 0x000500C7, 0x00000017, 0x0000499B, 0x00005AD5, 0x000002D1, 0x000600A9, + 0x00000017, 0x00002A9E, 0x000040CA, 0x0000499B, 0x0000489D, 0x00050080, 0x00000017, 0x00005FFA, + 0x00002870, 0x0000022F, 0x000500C4, 0x00000017, 0x00004F80, 0x00005FFA, 0x00000467, 0x000500C4, + 0x00000017, 0x00003FA7, 0x00002A9E, 0x000002ED, 0x000500C5, 0x00000017, 0x0000577D, 0x00004F80, + 0x00003FA7, 0x000500AA, 0x00000013, 0x00003601, 0x00003921, 0x00000B50, 0x000600A9, 0x00000017, + 0x00004657, 0x00003601, 0x00000B50, 0x0000577D, 0x0004007C, 0x0000001D, 0x0000593B, 0x00004657, + 0x000200F9, 0x00005BA4, 0x000200F8, 0x00003842, 0x000600A9, 0x0000000B, 0x00004C07, 0x00001D59, + 0x00000A46, 0x00000A0A, 0x00070050, 0x00000017, 0x000023B1, 0x00004C07, 0x00004C07, 0x00004C07, + 0x00004C07, 0x000500C2, 0x00000017, 0x000056D3, 0x000038EA, 0x000023B1, 0x000500C7, 0x00000017, + 0x00004A56, 0x000056D3, 0x000003A1, 0x00040070, 0x0000001D, 0x00003F05, 0x00004A56, 0x0005008E, + 0x0000001D, 0x0000521A, 0x00003F05, 0x000006FE, 0x000500C2, 0x00000017, 0x00001E42, 0x00002629, + 0x000023B1, 0x000500C7, 0x00000017, 0x00002BD4, 0x00001E42, 0x000003A1, 0x00040070, 0x0000001D, + 0x0000431A, 0x00002BD4, 0x0005008E, 0x0000001D, 0x00003092, 0x0000431A, 0x000006FE, 0x000200F9, + 0x00005BA4, 0x000200F8, 0x00003E85, 0x000600A9, 0x0000000B, 0x00004C08, 0x00001D59, 0x00000A3A, + 0x00000A0A, 0x00070050, 0x00000017, 0x000023B2, 0x00004C08, 0x00004C08, 0x00004C08, 0x00004C08, + 0x000500C2, 0x00000017, 0x000056D4, 0x000038EA, 0x000023B2, 0x000500C7, 0x00000017, 0x00004A57, + 0x000056D4, 0x0000064B, 0x00040070, 0x0000001D, 0x00003F06, 0x00004A57, 0x0005008E, 0x0000001D, + 0x0000521B, 0x00003F06, 0x0000017A, 0x000500C2, 0x00000017, 0x00001E43, 0x00002629, 0x000023B2, + 0x000500C7, 0x00000017, 0x00002BD5, 0x00001E43, 0x0000064B, 0x00040070, 0x0000001D, 0x0000431B, + 0x00002BD5, 0x0005008E, 0x0000001D, 0x00003093, 0x0000431B, 0x0000017A, 0x000200F9, 0x00005BA4, + 0x000200F8, 0x00006032, 0x0004007C, 0x0000001D, 0x00004B1F, 0x000038EA, 0x0004007C, 0x0000001D, + 0x000038B2, 0x00002629, 0x000200F9, 0x00005BA4, 0x000200F8, 0x00005BA4, 0x000F00F5, 0x0000001D, + 0x00002BF3, 0x000038B2, 0x00006032, 0x00003093, 0x00003E85, 0x00003092, 0x00003842, 0x0000593B, + 0x000059BF, 0x00004362, 0x000052C6, 0x000048F6, 0x00002033, 0x000F00F5, 0x0000001D, 0x0000358D, + 0x00004B1F, 0x00006032, 0x0000521B, 0x00003E85, 0x0000521A, 0x00003842, 0x00003044, 0x000059BF, + 0x00004980, 0x000052C6, 0x00005EB9, 0x00002033, 0x000200F9, 0x0000530F, 0x000200F8, 0x00005227, + 0x000300F7, 0x00005BA5, 0x00000000, 0x000700FB, 0x00002180, 0x000030ED, 0x00000005, 0x000052C7, + 0x00000007, 0x00002034, 0x000200F8, 0x00002034, 0x00050051, 0x0000000B, 0x00005F57, 0x000038EA, + 0x00000000, 0x0006000C, 0x00000015, 0x00006068, 0x00000001, 0x0000003E, 0x00005F57, 0x00050051, + 0x0000000D, 0x0000229A, 0x00006068, 0x00000000, 0x00050051, 0x0000000B, 0x00001DB5, 0x000038EA, + 0x00000001, 0x0006000C, 0x00000015, 0x00003CF9, 0x00000001, 0x0000003E, 0x00001DB5, 0x00050051, + 0x0000000D, 0x0000229B, 0x00003CF9, 0x00000000, 0x00050051, 0x0000000B, 0x00001DB6, 0x000038EA, + 0x00000002, 0x0006000C, 0x00000015, 0x00003CFA, 0x00000001, 0x0000003E, 0x00001DB6, 0x00050051, + 0x0000000D, 0x0000229C, 0x00003CFA, 0x00000000, 0x00050051, 0x0000000B, 0x00001DB7, 0x000038EA, + 0x00000003, 0x0006000C, 0x00000015, 0x00003CE4, 0x00000001, 0x0000003E, 0x00001DB7, 0x00050051, + 0x0000000D, 0x00002823, 0x00003CE4, 0x00000000, 0x00070050, 0x0000001D, 0x00005EBA, 0x0000229A, + 0x0000229B, 0x0000229C, 0x00002823, 0x00050051, 0x0000000B, 0x0000437B, 0x00002629, 0x00000000, + 0x0006000C, 0x00000015, 0x0000466C, 0x00000001, 0x0000003E, 0x0000437B, 0x00050051, 0x0000000D, + 0x0000229D, 0x0000466C, 0x00000000, 0x00050051, 0x0000000B, 0x00001DB8, 0x00002629, 0x00000001, + 0x0006000C, 0x00000015, 0x00003CFB, 0x00000001, 0x0000003E, 0x00001DB8, 0x00050051, 0x0000000D, + 0x0000229E, 0x00003CFB, 0x00000000, 0x00050051, 0x0000000B, 0x00001DB9, 0x00002629, 0x00000002, + 0x0006000C, 0x00000015, 0x00003CFC, 0x00000001, 0x0000003E, 0x00001DB9, 0x00050051, 0x0000000D, + 0x0000229F, 0x00003CFC, 0x00000000, 0x00050051, 0x0000000B, 0x00001DBA, 0x00002629, 0x00000003, + 0x0006000C, 0x00000015, 0x00003CE5, 0x00000001, 0x0000003E, 0x00001DBA, 0x00050051, 0x0000000D, + 0x0000349B, 0x00003CE5, 0x00000000, 0x00070050, 0x0000001D, 0x000048F7, 0x0000229D, 0x0000229E, + 0x0000229F, 0x0000349B, 0x000200F9, 0x00005BA5, 0x000200F8, 0x000052C7, 0x0004007C, 0x0000001A, + 0x000060F5, 0x000038EA, 0x000500C4, 0x0000001A, 0x0000581F, 0x000060F5, 0x00000302, 0x000500C3, + 0x0000001A, 0x0000409A, 0x0000581F, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A99, 0x0000409A, + 0x0005008E, 0x0000001D, 0x00004A79, 0x00002A99, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004981, + 0x00000001, 0x00000028, 0x00000504, 0x00004A79, 0x0004007C, 0x0000001A, 0x000027E6, 0x00002629, + 0x000500C4, 0x0000001A, 0x000021A2, 0x000027E6, 0x00000302, 0x000500C3, 0x0000001A, 0x0000409B, + 0x000021A2, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A9A, 0x0000409B, 0x0005008E, 0x0000001D, + 0x000053C0, 0x00002A9A, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004363, 0x00000001, 0x00000028, + 0x00000504, 0x000053C0, 0x000200F9, 0x00005BA5, 0x000200F8, 0x000030ED, 0x0004007C, 0x0000001D, + 0x00004B20, 0x000038EA, 0x0004007C, 0x0000001D, 0x000038B3, 0x00002629, 0x000200F9, 0x00005BA5, + 0x000200F8, 0x00005BA5, 0x000900F5, 0x0000001D, 0x00002BF4, 0x000038B3, 0x000030ED, 0x00004363, + 0x000052C7, 0x000048F7, 0x00002034, 0x000900F5, 0x0000001D, 0x0000358E, 0x00004B20, 0x000030ED, + 0x00004981, 0x000052C7, 0x00005EBA, 0x00002034, 0x000200F9, 0x0000530F, 0x000200F8, 0x0000530F, + 0x000700F5, 0x0000001D, 0x00002662, 0x00002BF4, 0x00005BA5, 0x00002BF3, 0x00005BA4, 0x000700F5, + 0x0000001D, 0x000036E3, 0x0000358E, 0x00005BA5, 0x0000358D, 0x00005BA4, 0x000500AE, 0x00000009, + 0x00002E55, 0x00003F4D, 0x00000A16, 0x000300F7, 0x00005313, 0x00000002, 0x000400FA, 0x00002E55, + 0x000050E5, 0x00005313, 0x000200F8, 0x000050E5, 0x00050085, 0x0000000D, 0x000061FB, 0x00002B2C, + 0x000000FC, 0x00050080, 0x0000000B, 0x00005E78, 0x00005E7C, 0x00000AFA, 0x000300F7, 0x00004F24, + 0x00000002, 0x000400FA, 0x000060B1, 0x00002622, 0x00002F62, 0x000200F8, 0x00002F62, 0x00060041, + 0x00000288, 0x00004BD0, 0x00000CC7, 0x00000A0B, 0x00005E78, 0x0004003D, 0x0000000B, 0x00005D45, + 0x00004BD0, 0x00050080, 0x0000000B, 0x00002DAE, 0x00005E78, 0x000030F7, 0x00060041, 0x00000288, + 0x0000194C, 0x00000CC7, 0x00000A0B, 0x00002DAE, 0x0004003D, 0x0000000B, 0x00005E60, 0x0000194C, + 0x00050084, 0x0000000B, 0x0000185F, 0x00000A10, 0x000030F7, 0x00050080, 0x0000000B, 0x000020A6, + 0x00005E78, 0x0000185F, 0x00060041, 0x00000288, 0x00003BD1, 0x00000CC7, 0x00000A0B, 0x000020A6, + 0x0004003D, 0x0000000B, 0x00005E61, 0x00003BD1, 0x00050084, 0x0000000B, 0x00001860, 0x00000A13, + 0x000030F7, 0x00050080, 0x0000000B, 0x000020A7, 0x00005E78, 0x00001860, 0x00060041, 0x00000288, + 0x000037F3, 0x00000CC7, 0x00000A0B, 0x000020A7, 0x0004003D, 0x0000000B, 0x0000374D, 0x000037F3, + 0x00070050, 0x00000017, 0x00004CD7, 0x00005D45, 0x00005E60, 0x00005E61, 0x0000374D, 0x00050084, + 0x0000000B, 0x00004299, 0x00000A16, 0x000030F7, 0x00050080, 0x0000000B, 0x000036A8, 0x00005E78, + 0x00004299, 0x00060041, 0x00000288, 0x00003BD2, 0x00000CC7, 0x00000A0B, 0x000036A8, 0x0004003D, + 0x0000000B, 0x00005E62, 0x00003BD2, 0x00050084, 0x0000000B, 0x00001861, 0x00000A19, 0x000030F7, + 0x00050080, 0x0000000B, 0x000020A8, 0x00005E78, 0x00001861, 0x00060041, 0x00000288, 0x00003BD3, + 0x00000CC7, 0x00000A0B, 0x000020A8, 0x0004003D, 0x0000000B, 0x00005E63, 0x00003BD3, 0x00050084, + 0x0000000B, 0x00001862, 0x00000A1C, 0x000030F7, 0x00050080, 0x0000000B, 0x000020A9, 0x00005E78, + 0x00001862, 0x00060041, 0x00000288, 0x00003BD4, 0x00000CC7, 0x00000A0B, 0x000020A9, 0x0004003D, + 0x0000000B, 0x00005E64, 0x00003BD4, 0x00050084, 0x0000000B, 0x00001863, 0x00000A1F, 0x000030F7, + 0x00050080, 0x0000000B, 0x000020AA, 0x00005E78, 0x00001863, 0x00060041, 0x00000288, 0x000037F4, + 0x00000CC7, 0x00000A0B, 0x000020AA, 0x0004003D, 0x0000000B, 0x00003FFD, 0x000037F4, 0x00070050, + 0x00000017, 0x0000512E, 0x00005E62, 0x00005E63, 0x00005E64, 0x00003FFD, 0x000200F9, 0x00004F24, + 0x000200F8, 0x00002622, 0x00060041, 0x00000288, 0x00005546, 0x00000CC7, 0x00000A0B, 0x00005E78, + 0x0004003D, 0x0000000B, 0x00005D46, 0x00005546, 0x00050080, 0x0000000B, 0x00002DAF, 0x00005E7C, + 0x00000AFD, 0x00060041, 0x00000288, 0x00001903, 0x00000CC7, 0x00000A0B, 0x00002DAF, 0x0004003D, + 0x0000000B, 0x00005C67, 0x00001903, 0x00050080, 0x0000000B, 0x00002DB0, 0x00005E7C, 0x00000B00, + 0x00060041, 0x00000288, 0x00001904, 0x00000CC7, 0x00000A0B, 0x00002DB0, 0x0004003D, 0x0000000B, + 0x00005C68, 0x00001904, 0x00050080, 0x0000000B, 0x00002DB1, 0x00005E7C, 0x00000B03, 0x00060041, + 0x00000288, 0x00005FF0, 0x00000CC7, 0x00000A0B, 0x00002DB1, 0x0004003D, 0x0000000B, 0x00003701, + 0x00005FF0, 0x00070050, 0x00000017, 0x00004ADE, 0x00005D46, 0x00005C67, 0x00005C68, 0x00003701, + 0x00050080, 0x0000000B, 0x000057E6, 0x00005E7C, 0x00000B06, 0x00060041, 0x00000288, 0x0000604C, + 0x00000CC7, 0x00000A0B, 0x000057E6, 0x0004003D, 0x0000000B, 0x00005C69, 0x0000604C, 0x00050080, + 0x0000000B, 0x00002DB2, 0x00005E7C, 0x00000B09, 0x00060041, 0x00000288, 0x00001905, 0x00000CC7, + 0x00000A0B, 0x00002DB2, 0x0004003D, 0x0000000B, 0x00005C6A, 0x00001905, 0x00050080, 0x0000000B, + 0x00002DB3, 0x00005E7C, 0x00000B0C, 0x00060041, 0x00000288, 0x00001906, 0x00000CC7, 0x00000A0B, + 0x00002DB3, 0x0004003D, 0x0000000B, 0x00005C6B, 0x00001906, 0x00050080, 0x0000000B, 0x00002DB4, + 0x00005E7C, 0x00000B0F, 0x00060041, 0x00000288, 0x00005FF1, 0x00000CC7, 0x00000A0B, 0x00002DB4, + 0x0004003D, 0x0000000B, 0x00003FFE, 0x00005FF1, 0x00070050, 0x00000017, 0x0000512F, 0x00005C69, + 0x00005C6A, 0x00005C6B, 0x00003FFE, 0x000200F9, 0x00004F24, 0x000200F8, 0x00004F24, 0x000700F5, + 0x00000017, 0x00002BCD, 0x0000512F, 0x00002622, 0x0000512E, 0x00002F62, 0x000700F5, 0x00000017, + 0x0000370D, 0x00004ADE, 0x00002622, 0x00004CD7, 0x00002F62, 0x000300F7, 0x00005310, 0x00000002, + 0x000400FA, 0x000043D9, 0x00005228, 0x0000577E, 0x000200F8, 0x0000577E, 0x000300F7, 0x00005BA6, + 0x00000000, 0x001300FB, 0x00002180, 0x00006033, 0x00000000, 0x00003E86, 0x00000001, 0x00003E86, + 0x00000002, 0x00003843, 0x0000000A, 0x00003843, 0x00000003, 0x000059C0, 0x0000000C, 0x000059C0, + 0x00000004, 0x000052C8, 0x00000006, 0x00002035, 0x000200F8, 0x00002035, 0x00050051, 0x0000000B, + 0x00005F58, 0x0000370D, 0x00000000, 0x0006000C, 0x00000015, 0x00006069, 0x00000001, 0x0000003E, + 0x00005F58, 0x00050051, 0x0000000D, 0x000022A0, 0x00006069, 0x00000000, 0x00050051, 0x0000000B, + 0x00001DBB, 0x0000370D, 0x00000001, 0x0006000C, 0x00000015, 0x00003CFD, 0x00000001, 0x0000003E, + 0x00001DBB, 0x00050051, 0x0000000D, 0x000022A1, 0x00003CFD, 0x00000000, 0x00050051, 0x0000000B, + 0x00001DBC, 0x0000370D, 0x00000002, 0x0006000C, 0x00000015, 0x00003CFE, 0x00000001, 0x0000003E, + 0x00001DBC, 0x00050051, 0x0000000D, 0x000022A2, 0x00003CFE, 0x00000000, 0x00050051, 0x0000000B, + 0x00001DBD, 0x0000370D, 0x00000003, 0x0006000C, 0x00000015, 0x00003CE6, 0x00000001, 0x0000003E, + 0x00001DBD, 0x00050051, 0x0000000D, 0x00002824, 0x00003CE6, 0x00000000, 0x00070050, 0x0000001D, + 0x00005EBB, 0x000022A0, 0x000022A1, 0x000022A2, 0x00002824, 0x00050051, 0x0000000B, 0x0000437C, + 0x00002BCD, 0x00000000, 0x0006000C, 0x00000015, 0x0000466D, 0x00000001, 0x0000003E, 0x0000437C, + 0x00050051, 0x0000000D, 0x000022A3, 0x0000466D, 0x00000000, 0x00050051, 0x0000000B, 0x00001DBE, + 0x00002BCD, 0x00000001, 0x0006000C, 0x00000015, 0x00003CFF, 0x00000001, 0x0000003E, 0x00001DBE, + 0x00050051, 0x0000000D, 0x000022A4, 0x00003CFF, 0x00000000, 0x00050051, 0x0000000B, 0x00001DBF, + 0x00002BCD, 0x00000002, 0x0006000C, 0x00000015, 0x00003D00, 0x00000001, 0x0000003E, 0x00001DBF, + 0x00050051, 0x0000000D, 0x000022A5, 0x00003D00, 0x00000000, 0x00050051, 0x0000000B, 0x00001DC0, + 0x00002BCD, 0x00000003, 0x0006000C, 0x00000015, 0x00003CE7, 0x00000001, 0x0000003E, 0x00001DC0, + 0x00050051, 0x0000000D, 0x0000349C, 0x00003CE7, 0x00000000, 0x00070050, 0x0000001D, 0x000048F8, + 0x000022A3, 0x000022A4, 0x000022A5, 0x0000349C, 0x000200F9, 0x00005BA6, 0x000200F8, 0x000052C8, + 0x0004007C, 0x0000001A, 0x000060F6, 0x0000370D, 0x000500C4, 0x0000001A, 0x00005820, 0x000060F6, + 0x00000302, 0x000500C3, 0x0000001A, 0x0000409C, 0x00005820, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002A9B, 0x0000409C, 0x0005008E, 0x0000001D, 0x00004A7A, 0x00002A9B, 0x000007FE, 0x0007000C, + 0x0000001D, 0x00004982, 0x00000001, 0x00000028, 0x00000504, 0x00004A7A, 0x0004007C, 0x0000001A, + 0x000027E7, 0x00002BCD, 0x000500C4, 0x0000001A, 0x000021A3, 0x000027E7, 0x00000302, 0x000500C3, + 0x0000001A, 0x0000409D, 0x000021A3, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A9C, 0x0000409D, + 0x0005008E, 0x0000001D, 0x000053C1, 0x00002A9C, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004364, + 0x00000001, 0x00000028, 0x00000504, 0x000053C1, 0x000200F9, 0x00005BA6, 0x000200F8, 0x000059C0, + 0x000600A9, 0x0000000B, 0x00004C09, 0x00001D59, 0x00000A46, 0x00000A0A, 0x00070050, 0x00000017, + 0x000023B3, 0x00004C09, 0x00004C09, 0x00004C09, 0x00004C09, 0x000500C2, 0x00000017, 0x00005D49, + 0x0000370D, 0x000023B3, 0x000500C7, 0x00000017, 0x00005DE7, 0x00005D49, 0x000003A1, 0x000500C7, + 0x00000017, 0x0000489E, 0x00005DE7, 0x000002D1, 0x000500C2, 0x00000017, 0x00005B92, 0x00005DE7, + 0x00000107, 0x000500AA, 0x00000013, 0x000040CB, 0x00005B92, 0x00000B50, 0x0006000C, 0x0000001A, + 0x00002C4D, 0x00000001, 0x0000004B, 0x0000489E, 0x0004007C, 0x00000017, 0x00002A17, 0x00002C4D, + 0x00050082, 0x00000017, 0x0000187C, 0x00000107, 0x00002A17, 0x00050080, 0x00000017, 0x00002212, + 0x00002A17, 0x00000A0F, 0x000600A9, 0x00000017, 0x00002871, 0x000040CB, 0x00002212, 0x00005B92, + 0x000500C4, 0x00000017, 0x00005AD6, 0x0000489E, 0x0000187C, 0x000500C7, 0x00000017, 0x0000499C, + 0x00005AD6, 0x000002D1, 0x000600A9, 0x00000017, 0x00002A9F, 0x000040CB, 0x0000499C, 0x0000489E, + 0x00050080, 0x00000017, 0x00005FFB, 0x00002871, 0x0000022F, 0x000500C4, 0x00000017, 0x00004F81, + 0x00005FFB, 0x00000467, 0x000500C4, 0x00000017, 0x00003FA8, 0x00002A9F, 0x000002ED, 0x000500C5, + 0x00000017, 0x0000577F, 0x00004F81, 0x00003FA8, 0x000500AA, 0x00000013, 0x00003602, 0x00005DE7, + 0x00000B50, 0x000600A9, 0x00000017, 0x00004243, 0x00003602, 0x00000B50, 0x0000577F, 0x0004007C, + 0x0000001D, 0x00003045, 0x00004243, 0x000500C2, 0x00000017, 0x0000603F, 0x00002BCD, 0x000023B3, + 0x000500C7, 0x00000017, 0x00003922, 0x0000603F, 0x000003A1, 0x000500C7, 0x00000017, 0x0000489F, + 0x00003922, 0x000002D1, 0x000500C2, 0x00000017, 0x00005B93, 0x00003922, 0x00000107, 0x000500AA, + 0x00000013, 0x000040CC, 0x00005B93, 0x00000B50, 0x0006000C, 0x0000001A, 0x00002C4E, 0x00000001, + 0x0000004B, 0x0000489F, 0x0004007C, 0x00000017, 0x00002A18, 0x00002C4E, 0x00050082, 0x00000017, + 0x0000187D, 0x00000107, 0x00002A18, 0x00050080, 0x00000017, 0x00002213, 0x00002A18, 0x00000A0F, + 0x000600A9, 0x00000017, 0x00002872, 0x000040CC, 0x00002213, 0x00005B93, 0x000500C4, 0x00000017, + 0x00005AD7, 0x0000489F, 0x0000187D, 0x000500C7, 0x00000017, 0x0000499D, 0x00005AD7, 0x000002D1, + 0x000600A9, 0x00000017, 0x00002AA0, 0x000040CC, 0x0000499D, 0x0000489F, 0x00050080, 0x00000017, + 0x00005FFC, 0x00002872, 0x0000022F, 0x000500C4, 0x00000017, 0x00004F82, 0x00005FFC, 0x00000467, + 0x000500C4, 0x00000017, 0x00003FA9, 0x00002AA0, 0x000002ED, 0x000500C5, 0x00000017, 0x00005780, + 0x00004F82, 0x00003FA9, 0x000500AA, 0x00000013, 0x00003603, 0x00003922, 0x00000B50, 0x000600A9, + 0x00000017, 0x00004658, 0x00003603, 0x00000B50, 0x00005780, 0x0004007C, 0x0000001D, 0x0000593C, + 0x00004658, 0x000200F9, 0x00005BA6, 0x000200F8, 0x00003843, 0x000600A9, 0x0000000B, 0x00004C0A, + 0x00001D59, 0x00000A46, 0x00000A0A, 0x00070050, 0x00000017, 0x000023B4, 0x00004C0A, 0x00004C0A, + 0x00004C0A, 0x00004C0A, 0x000500C2, 0x00000017, 0x000056D5, 0x0000370D, 0x000023B4, 0x000500C7, + 0x00000017, 0x00004A58, 0x000056D5, 0x000003A1, 0x00040070, 0x0000001D, 0x00003F07, 0x00004A58, + 0x0005008E, 0x0000001D, 0x0000521C, 0x00003F07, 0x000006FE, 0x000500C2, 0x00000017, 0x00001E44, + 0x00002BCD, 0x000023B4, 0x000500C7, 0x00000017, 0x00002BD6, 0x00001E44, 0x000003A1, 0x00040070, + 0x0000001D, 0x0000431C, 0x00002BD6, 0x0005008E, 0x0000001D, 0x00003094, 0x0000431C, 0x000006FE, + 0x000200F9, 0x00005BA6, 0x000200F8, 0x00003E86, 0x000600A9, 0x0000000B, 0x00004C0B, 0x00001D59, + 0x00000A3A, 0x00000A0A, 0x00070050, 0x00000017, 0x000023B5, 0x00004C0B, 0x00004C0B, 0x00004C0B, + 0x00004C0B, 0x000500C2, 0x00000017, 0x000056D6, 0x0000370D, 0x000023B5, 0x000500C7, 0x00000017, + 0x00004A59, 0x000056D6, 0x0000064B, 0x00040070, 0x0000001D, 0x00003F08, 0x00004A59, 0x0005008E, + 0x0000001D, 0x0000521D, 0x00003F08, 0x0000017A, 0x000500C2, 0x00000017, 0x00001E45, 0x00002BCD, + 0x000023B5, 0x000500C7, 0x00000017, 0x00002BD7, 0x00001E45, 0x0000064B, 0x00040070, 0x0000001D, + 0x0000431D, 0x00002BD7, 0x0005008E, 0x0000001D, 0x00003095, 0x0000431D, 0x0000017A, 0x000200F9, + 0x00005BA6, 0x000200F8, 0x00006033, 0x0004007C, 0x0000001D, 0x00004B21, 0x0000370D, 0x0004007C, + 0x0000001D, 0x000038B4, 0x00002BCD, 0x000200F9, 0x00005BA6, 0x000200F8, 0x00005BA6, 0x000F00F5, + 0x0000001D, 0x00002BF5, 0x000038B4, 0x00006033, 0x00003095, 0x00003E86, 0x00003094, 0x00003843, + 0x0000593C, 0x000059C0, 0x00004364, 0x000052C8, 0x000048F8, 0x00002035, 0x000F00F5, 0x0000001D, + 0x00003590, 0x00004B21, 0x00006033, 0x0000521D, 0x00003E86, 0x0000521C, 0x00003843, 0x00003045, + 0x000059C0, 0x00004982, 0x000052C8, 0x00005EBB, 0x00002035, 0x000200F9, 0x00005310, 0x000200F8, + 0x00005228, 0x000300F7, 0x00005BA7, 0x00000000, 0x000700FB, 0x00002180, 0x000030EE, 0x00000005, + 0x000052C9, 0x00000007, 0x00002036, 0x000200F8, 0x00002036, 0x00050051, 0x0000000B, 0x00005F59, + 0x0000370D, 0x00000000, 0x0006000C, 0x00000015, 0x0000606A, 0x00000001, 0x0000003E, 0x00005F59, + 0x00050051, 0x0000000D, 0x000022A6, 0x0000606A, 0x00000000, 0x00050051, 0x0000000B, 0x00001DC1, + 0x0000370D, 0x00000001, 0x0006000C, 0x00000015, 0x00003D01, 0x00000001, 0x0000003E, 0x00001DC1, + 0x00050051, 0x0000000D, 0x000022A8, 0x00003D01, 0x00000000, 0x00050051, 0x0000000B, 0x00001DC2, + 0x0000370D, 0x00000002, 0x0006000C, 0x00000015, 0x00003D02, 0x00000001, 0x0000003E, 0x00001DC2, + 0x00050051, 0x0000000D, 0x000022A9, 0x00003D02, 0x00000000, 0x00050051, 0x0000000B, 0x00001DC3, + 0x0000370D, 0x00000003, 0x0006000C, 0x00000015, 0x00003CE8, 0x00000001, 0x0000003E, 0x00001DC3, + 0x00050051, 0x0000000D, 0x00002825, 0x00003CE8, 0x00000000, 0x00070050, 0x0000001D, 0x00005EBC, + 0x000022A6, 0x000022A8, 0x000022A9, 0x00002825, 0x00050051, 0x0000000B, 0x0000437D, 0x00002BCD, + 0x00000000, 0x0006000C, 0x00000015, 0x0000466E, 0x00000001, 0x0000003E, 0x0000437D, 0x00050051, + 0x0000000D, 0x000022AA, 0x0000466E, 0x00000000, 0x00050051, 0x0000000B, 0x00001DC4, 0x00002BCD, + 0x00000001, 0x0006000C, 0x00000015, 0x00003D03, 0x00000001, 0x0000003E, 0x00001DC4, 0x00050051, + 0x0000000D, 0x000022AB, 0x00003D03, 0x00000000, 0x00050051, 0x0000000B, 0x00001DC5, 0x00002BCD, + 0x00000002, 0x0006000C, 0x00000015, 0x00003D04, 0x00000001, 0x0000003E, 0x00001DC5, 0x00050051, + 0x0000000D, 0x000022AC, 0x00003D04, 0x00000000, 0x00050051, 0x0000000B, 0x00001DC6, 0x00002BCD, + 0x00000003, 0x0006000C, 0x00000015, 0x00003CE9, 0x00000001, 0x0000003E, 0x00001DC6, 0x00050051, + 0x0000000D, 0x0000349D, 0x00003CE9, 0x00000000, 0x00070050, 0x0000001D, 0x000048F9, 0x000022AA, + 0x000022AB, 0x000022AC, 0x0000349D, 0x000200F9, 0x00005BA7, 0x000200F8, 0x000052C9, 0x0004007C, + 0x0000001A, 0x000060F7, 0x0000370D, 0x000500C4, 0x0000001A, 0x00005821, 0x000060F7, 0x00000302, + 0x000500C3, 0x0000001A, 0x0000409E, 0x00005821, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA1, + 0x0000409E, 0x0005008E, 0x0000001D, 0x00004A7B, 0x00002AA1, 0x000007FE, 0x0007000C, 0x0000001D, + 0x00004983, 0x00000001, 0x00000028, 0x00000504, 0x00004A7B, 0x0004007C, 0x0000001A, 0x000027E8, + 0x00002BCD, 0x000500C4, 0x0000001A, 0x000021A4, 0x000027E8, 0x00000302, 0x000500C3, 0x0000001A, + 0x0000409F, 0x000021A4, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA2, 0x0000409F, 0x0005008E, + 0x0000001D, 0x000053C2, 0x00002AA2, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004365, 0x00000001, + 0x00000028, 0x00000504, 0x000053C2, 0x000200F9, 0x00005BA7, 0x000200F8, 0x000030EE, 0x0004007C, + 0x0000001D, 0x00004B22, 0x0000370D, 0x0004007C, 0x0000001D, 0x000038B5, 0x00002BCD, 0x000200F9, + 0x00005BA7, 0x000200F8, 0x00005BA7, 0x000900F5, 0x0000001D, 0x00002BF6, 0x000038B5, 0x000030EE, + 0x00004365, 0x000052C9, 0x000048F9, 0x00002036, 0x000900F5, 0x0000001D, 0x00003591, 0x00004B22, + 0x000030EE, 0x00004983, 0x000052C9, 0x00005EBC, 0x00002036, 0x000200F9, 0x00005310, 0x000200F8, + 0x00005310, 0x000700F5, 0x0000001D, 0x0000230B, 0x00002BF6, 0x00005BA7, 0x00002BF5, 0x00005BA6, + 0x000700F5, 0x0000001D, 0x00004C8A, 0x00003591, 0x00005BA7, 0x00003590, 0x00005BA6, 0x00050081, + 0x0000001D, 0x000046B0, 0x000036E3, 0x00004C8A, 0x00050081, 0x0000001D, 0x0000455A, 0x00002662, + 0x0000230B, 0x000500AE, 0x00000009, 0x0000387D, 0x00003F4D, 0x00000A1C, 0x000300F7, 0x00005EC8, + 0x00000002, 0x000400FA, 0x0000387D, 0x000026B1, 0x00005EC8, 0x000200F8, 0x000026B1, 0x000500C4, + 0x0000000B, 0x000037B2, 0x00000A0D, 0x000023AA, 0x00050085, 0x0000000D, 0x00002F3A, 0x00002B2C, + 0x0000016E, 0x00050080, 0x0000000B, 0x000051FC, 0x00005E7C, 0x000037B2, 0x000300F7, 0x00004F25, + 0x00000002, 0x000400FA, 0x000060B1, 0x00002623, 0x00002F63, 0x000200F8, 0x00002F63, 0x00060041, + 0x00000288, 0x00004BD1, 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, 0x00005D47, + 0x00004BD1, 0x00050080, 0x0000000B, 0x00002DB5, 0x000051FC, 0x000030F7, 0x00060041, 0x00000288, + 0x0000194D, 0x00000CC7, 0x00000A0B, 0x00002DB5, 0x0004003D, 0x0000000B, 0x00005E65, 0x0000194D, + 0x00050084, 0x0000000B, 0x00001864, 0x00000A10, 0x000030F7, 0x00050080, 0x0000000B, 0x000020AB, + 0x000051FC, 0x00001864, 0x00060041, 0x00000288, 0x00003BD5, 0x00000CC7, 0x00000A0B, 0x000020AB, + 0x0004003D, 0x0000000B, 0x00005E66, 0x00003BD5, 0x00050084, 0x0000000B, 0x00001865, 0x00000A13, + 0x000030F7, 0x00050080, 0x0000000B, 0x000020AC, 0x000051FC, 0x00001865, 0x00060041, 0x00000288, + 0x000037F5, 0x00000CC7, 0x00000A0B, 0x000020AC, 0x0004003D, 0x0000000B, 0x0000374E, 0x000037F5, + 0x00070050, 0x00000017, 0x00004CD8, 0x00005D47, 0x00005E65, 0x00005E66, 0x0000374E, 0x00050084, + 0x0000000B, 0x0000429A, 0x00000A16, 0x000030F7, 0x00050080, 0x0000000B, 0x000036A9, 0x000051FC, + 0x0000429A, 0x00060041, 0x00000288, 0x00003BD6, 0x00000CC7, 0x00000A0B, 0x000036A9, 0x0004003D, + 0x0000000B, 0x00005E67, 0x00003BD6, 0x00050084, 0x0000000B, 0x00001866, 0x00000A19, 0x000030F7, + 0x00050080, 0x0000000B, 0x000020AD, 0x000051FC, 0x00001866, 0x00060041, 0x00000288, 0x00003BD7, + 0x00000CC7, 0x00000A0B, 0x000020AD, 0x0004003D, 0x0000000B, 0x00005E68, 0x00003BD7, 0x00050084, + 0x0000000B, 0x00001867, 0x00000A1C, 0x000030F7, 0x00050080, 0x0000000B, 0x000020AE, 0x000051FC, + 0x00001867, 0x00060041, 0x00000288, 0x00003BD8, 0x00000CC7, 0x00000A0B, 0x000020AE, 0x0004003D, + 0x0000000B, 0x00005E69, 0x00003BD8, 0x00050084, 0x0000000B, 0x00001868, 0x00000A1F, 0x000030F7, + 0x00050080, 0x0000000B, 0x000020AF, 0x000051FC, 0x00001868, 0x00060041, 0x00000288, 0x000037F6, + 0x00000CC7, 0x00000A0B, 0x000020AF, 0x0004003D, 0x0000000B, 0x00003FFF, 0x000037F6, 0x00070050, + 0x00000017, 0x00005130, 0x00005E67, 0x00005E68, 0x00005E69, 0x00003FFF, 0x000200F9, 0x00004F25, + 0x000200F8, 0x00002623, 0x00060041, 0x00000288, 0x00005547, 0x00000CC7, 0x00000A0B, 0x000051FC, + 0x0004003D, 0x0000000B, 0x00005D4A, 0x00005547, 0x00050080, 0x0000000B, 0x00002DB6, 0x000051FC, + 0x00000A0D, 0x00060041, 0x00000288, 0x00001907, 0x00000CC7, 0x00000A0B, 0x00002DB6, 0x0004003D, + 0x0000000B, 0x00005C6C, 0x00001907, 0x00050080, 0x0000000B, 0x00002DB7, 0x000051FC, 0x00000A10, + 0x00060041, 0x00000288, 0x00001908, 0x00000CC7, 0x00000A0B, 0x00002DB7, 0x0004003D, 0x0000000B, + 0x00005C6D, 0x00001908, 0x00050080, 0x0000000B, 0x00002DB8, 0x000051FC, 0x00000A13, 0x00060041, + 0x00000288, 0x00005FF2, 0x00000CC7, 0x00000A0B, 0x00002DB8, 0x0004003D, 0x0000000B, 0x00003702, + 0x00005FF2, 0x00070050, 0x00000017, 0x00004ADF, 0x00005D4A, 0x00005C6C, 0x00005C6D, 0x00003702, + 0x00050080, 0x0000000B, 0x000057E7, 0x000051FC, 0x00000A16, 0x00060041, 0x00000288, 0x0000604D, + 0x00000CC7, 0x00000A0B, 0x000057E7, 0x0004003D, 0x0000000B, 0x00005C6E, 0x0000604D, 0x00050080, + 0x0000000B, 0x00002DB9, 0x000051FC, 0x00000A19, 0x00060041, 0x00000288, 0x00001909, 0x00000CC7, + 0x00000A0B, 0x00002DB9, 0x0004003D, 0x0000000B, 0x00005C6F, 0x00001909, 0x00050080, 0x0000000B, + 0x00002DBA, 0x000051FC, 0x00000A1C, 0x00060041, 0x00000288, 0x0000190A, 0x00000CC7, 0x00000A0B, + 0x00002DBA, 0x0004003D, 0x0000000B, 0x00005C70, 0x0000190A, 0x00050080, 0x0000000B, 0x00002DBB, + 0x000051FC, 0x00000A1F, 0x00060041, 0x00000288, 0x00005FF3, 0x00000CC7, 0x00000A0B, 0x00002DBB, + 0x0004003D, 0x0000000B, 0x00004000, 0x00005FF3, 0x00070050, 0x00000017, 0x00005131, 0x00005C6E, + 0x00005C6F, 0x00005C70, 0x00004000, 0x000200F9, 0x00004F25, 0x000200F8, 0x00004F25, 0x000700F5, + 0x00000017, 0x00002BCE, 0x00005131, 0x00002623, 0x00005130, 0x00002F63, 0x000700F5, 0x00000017, + 0x0000370E, 0x00004ADF, 0x00002623, 0x00004CD8, 0x00002F63, 0x000300F7, 0x00005311, 0x00000002, + 0x000400FA, 0x000043D9, 0x00005229, 0x00005781, 0x000200F8, 0x00005781, 0x000300F7, 0x00005BA8, + 0x00000000, 0x001300FB, 0x00002180, 0x00006034, 0x00000000, 0x00003E87, 0x00000001, 0x00003E87, + 0x00000002, 0x00003844, 0x0000000A, 0x00003844, 0x00000003, 0x000059C1, 0x0000000C, 0x000059C1, + 0x00000004, 0x000052CA, 0x00000006, 0x00002037, 0x000200F8, 0x00002037, 0x00050051, 0x0000000B, + 0x00005F5A, 0x0000370E, 0x00000000, 0x0006000C, 0x00000015, 0x0000606B, 0x00000001, 0x0000003E, + 0x00005F5A, 0x00050051, 0x0000000D, 0x000022AD, 0x0000606B, 0x00000000, 0x00050051, 0x0000000B, + 0x00001DC7, 0x0000370E, 0x00000001, 0x0006000C, 0x00000015, 0x00003D05, 0x00000001, 0x0000003E, + 0x00001DC7, 0x00050051, 0x0000000D, 0x000022AE, 0x00003D05, 0x00000000, 0x00050051, 0x0000000B, + 0x00001DC8, 0x0000370E, 0x00000002, 0x0006000C, 0x00000015, 0x00003D06, 0x00000001, 0x0000003E, + 0x00001DC8, 0x00050051, 0x0000000D, 0x000022AF, 0x00003D06, 0x00000000, 0x00050051, 0x0000000B, + 0x00001DC9, 0x0000370E, 0x00000003, 0x0006000C, 0x00000015, 0x00003CEA, 0x00000001, 0x0000003E, + 0x00001DC9, 0x00050051, 0x0000000D, 0x00002826, 0x00003CEA, 0x00000000, 0x00070050, 0x0000001D, + 0x00005EBD, 0x000022AD, 0x000022AE, 0x000022AF, 0x00002826, 0x00050051, 0x0000000B, 0x0000437E, + 0x00002BCE, 0x00000000, 0x0006000C, 0x00000015, 0x0000466F, 0x00000001, 0x0000003E, 0x0000437E, + 0x00050051, 0x0000000D, 0x000022B0, 0x0000466F, 0x00000000, 0x00050051, 0x0000000B, 0x00001DCA, + 0x00002BCE, 0x00000001, 0x0006000C, 0x00000015, 0x00003D07, 0x00000001, 0x0000003E, 0x00001DCA, + 0x00050051, 0x0000000D, 0x000022B1, 0x00003D07, 0x00000000, 0x00050051, 0x0000000B, 0x00001DCB, + 0x00002BCE, 0x00000002, 0x0006000C, 0x00000015, 0x00003D08, 0x00000001, 0x0000003E, 0x00001DCB, + 0x00050051, 0x0000000D, 0x000022B2, 0x00003D08, 0x00000000, 0x00050051, 0x0000000B, 0x00001DCC, + 0x00002BCE, 0x00000003, 0x0006000C, 0x00000015, 0x00003CEB, 0x00000001, 0x0000003E, 0x00001DCC, + 0x00050051, 0x0000000D, 0x0000349E, 0x00003CEB, 0x00000000, 0x00070050, 0x0000001D, 0x000048FA, + 0x000022B0, 0x000022B1, 0x000022B2, 0x0000349E, 0x000200F9, 0x00005BA8, 0x000200F8, 0x000052CA, + 0x0004007C, 0x0000001A, 0x000060F8, 0x0000370E, 0x000500C4, 0x0000001A, 0x00005822, 0x000060F8, + 0x00000302, 0x000500C3, 0x0000001A, 0x000040A0, 0x00005822, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002AA3, 0x000040A0, 0x0005008E, 0x0000001D, 0x00004A7C, 0x00002AA3, 0x000007FE, 0x0007000C, + 0x0000001D, 0x00004984, 0x00000001, 0x00000028, 0x00000504, 0x00004A7C, 0x0004007C, 0x0000001A, + 0x000027E9, 0x00002BCE, 0x000500C4, 0x0000001A, 0x000021A5, 0x000027E9, 0x00000302, 0x000500C3, + 0x0000001A, 0x000040A1, 0x000021A5, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA4, 0x000040A1, + 0x0005008E, 0x0000001D, 0x000053C3, 0x00002AA4, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004366, + 0x00000001, 0x00000028, 0x00000504, 0x000053C3, 0x000200F9, 0x00005BA8, 0x000200F8, 0x000059C1, + 0x000600A9, 0x0000000B, 0x00004C0C, 0x00001D59, 0x00000A46, 0x00000A0A, 0x00070050, 0x00000017, + 0x000023B6, 0x00004C0C, 0x00004C0C, 0x00004C0C, 0x00004C0C, 0x000500C2, 0x00000017, 0x00005D4B, + 0x0000370E, 0x000023B6, 0x000500C7, 0x00000017, 0x00005DE8, 0x00005D4B, 0x000003A1, 0x000500C7, + 0x00000017, 0x000048A0, 0x00005DE8, 0x000002D1, 0x000500C2, 0x00000017, 0x00005B94, 0x00005DE8, + 0x00000107, 0x000500AA, 0x00000013, 0x000040CD, 0x00005B94, 0x00000B50, 0x0006000C, 0x0000001A, + 0x00002C4F, 0x00000001, 0x0000004B, 0x000048A0, 0x0004007C, 0x00000017, 0x00002A19, 0x00002C4F, + 0x00050082, 0x00000017, 0x0000187E, 0x00000107, 0x00002A19, 0x00050080, 0x00000017, 0x00002214, + 0x00002A19, 0x00000A0F, 0x000600A9, 0x00000017, 0x00002873, 0x000040CD, 0x00002214, 0x00005B94, + 0x000500C4, 0x00000017, 0x00005AD9, 0x000048A0, 0x0000187E, 0x000500C7, 0x00000017, 0x0000499E, + 0x00005AD9, 0x000002D1, 0x000600A9, 0x00000017, 0x00002AA5, 0x000040CD, 0x0000499E, 0x000048A0, + 0x00050080, 0x00000017, 0x00005FFD, 0x00002873, 0x0000022F, 0x000500C4, 0x00000017, 0x00004F83, + 0x00005FFD, 0x00000467, 0x000500C4, 0x00000017, 0x00003FAA, 0x00002AA5, 0x000002ED, 0x000500C5, + 0x00000017, 0x00005782, 0x00004F83, 0x00003FAA, 0x000500AA, 0x00000013, 0x00003604, 0x00005DE8, + 0x00000B50, 0x000600A9, 0x00000017, 0x00004244, 0x00003604, 0x00000B50, 0x00005782, 0x0004007C, + 0x0000001D, 0x00003046, 0x00004244, 0x000500C2, 0x00000017, 0x00006040, 0x00002BCE, 0x000023B6, + 0x000500C7, 0x00000017, 0x00003923, 0x00006040, 0x000003A1, 0x000500C7, 0x00000017, 0x000048A1, + 0x00003923, 0x000002D1, 0x000500C2, 0x00000017, 0x00005B95, 0x00003923, 0x00000107, 0x000500AA, + 0x00000013, 0x000040CE, 0x00005B95, 0x00000B50, 0x0006000C, 0x0000001A, 0x00002C50, 0x00000001, + 0x0000004B, 0x000048A1, 0x0004007C, 0x00000017, 0x00002A1A, 0x00002C50, 0x00050082, 0x00000017, + 0x0000187F, 0x00000107, 0x00002A1A, 0x00050080, 0x00000017, 0x00002215, 0x00002A1A, 0x00000A0F, + 0x000600A9, 0x00000017, 0x00002874, 0x000040CE, 0x00002215, 0x00005B95, 0x000500C4, 0x00000017, + 0x00005ADA, 0x000048A1, 0x0000187F, 0x000500C7, 0x00000017, 0x0000499F, 0x00005ADA, 0x000002D1, + 0x000600A9, 0x00000017, 0x00002AA6, 0x000040CE, 0x0000499F, 0x000048A1, 0x00050080, 0x00000017, + 0x00005FFE, 0x00002874, 0x0000022F, 0x000500C4, 0x00000017, 0x00004F84, 0x00005FFE, 0x00000467, + 0x000500C4, 0x00000017, 0x00003FAB, 0x00002AA6, 0x000002ED, 0x000500C5, 0x00000017, 0x00005783, + 0x00004F84, 0x00003FAB, 0x000500AA, 0x00000013, 0x00003605, 0x00003923, 0x00000B50, 0x000600A9, + 0x00000017, 0x00004659, 0x00003605, 0x00000B50, 0x00005783, 0x0004007C, 0x0000001D, 0x0000593D, + 0x00004659, 0x000200F9, 0x00005BA8, 0x000200F8, 0x00003844, 0x000600A9, 0x0000000B, 0x00004C0D, + 0x00001D59, 0x00000A46, 0x00000A0A, 0x00070050, 0x00000017, 0x000023B7, 0x00004C0D, 0x00004C0D, + 0x00004C0D, 0x00004C0D, 0x000500C2, 0x00000017, 0x000056D7, 0x0000370E, 0x000023B7, 0x000500C7, + 0x00000017, 0x00004A5A, 0x000056D7, 0x000003A1, 0x00040070, 0x0000001D, 0x00003F09, 0x00004A5A, + 0x0005008E, 0x0000001D, 0x0000521E, 0x00003F09, 0x000006FE, 0x000500C2, 0x00000017, 0x00001E46, + 0x00002BCE, 0x000023B7, 0x000500C7, 0x00000017, 0x00002BD8, 0x00001E46, 0x000003A1, 0x00040070, + 0x0000001D, 0x0000431E, 0x00002BD8, 0x0005008E, 0x0000001D, 0x00003096, 0x0000431E, 0x000006FE, + 0x000200F9, 0x00005BA8, 0x000200F8, 0x00003E87, 0x000600A9, 0x0000000B, 0x00004C0E, 0x00001D59, + 0x00000A3A, 0x00000A0A, 0x00070050, 0x00000017, 0x000023B8, 0x00004C0E, 0x00004C0E, 0x00004C0E, + 0x00004C0E, 0x000500C2, 0x00000017, 0x000056D8, 0x0000370E, 0x000023B8, 0x000500C7, 0x00000017, + 0x00004A5B, 0x000056D8, 0x0000064B, 0x00040070, 0x0000001D, 0x00003F0A, 0x00004A5B, 0x0005008E, + 0x0000001D, 0x0000521F, 0x00003F0A, 0x0000017A, 0x000500C2, 0x00000017, 0x00001E47, 0x00002BCE, + 0x000023B8, 0x000500C7, 0x00000017, 0x00002BD9, 0x00001E47, 0x0000064B, 0x00040070, 0x0000001D, + 0x0000431F, 0x00002BD9, 0x0005008E, 0x0000001D, 0x00003097, 0x0000431F, 0x0000017A, 0x000200F9, + 0x00005BA8, 0x000200F8, 0x00006034, 0x0004007C, 0x0000001D, 0x00004B23, 0x0000370E, 0x0004007C, + 0x0000001D, 0x000038B6, 0x00002BCE, 0x000200F9, 0x00005BA8, 0x000200F8, 0x00005BA8, 0x000F00F5, + 0x0000001D, 0x00002BF7, 0x000038B6, 0x00006034, 0x00003097, 0x00003E87, 0x00003096, 0x00003844, + 0x0000593D, 0x000059C1, 0x00004366, 0x000052CA, 0x000048FA, 0x00002037, 0x000F00F5, 0x0000001D, + 0x00003592, 0x00004B23, 0x00006034, 0x0000521F, 0x00003E87, 0x0000521E, 0x00003844, 0x00003046, + 0x000059C1, 0x00004984, 0x000052CA, 0x00005EBD, 0x00002037, 0x000200F9, 0x00005311, 0x000200F8, + 0x00005229, 0x000300F7, 0x00005BA9, 0x00000000, 0x000700FB, 0x00002180, 0x000030EF, 0x00000005, + 0x000052CB, 0x00000007, 0x00002038, 0x000200F8, 0x00002038, 0x00050051, 0x0000000B, 0x00005F5B, + 0x0000370E, 0x00000000, 0x0006000C, 0x00000015, 0x0000606C, 0x00000001, 0x0000003E, 0x00005F5B, + 0x00050051, 0x0000000D, 0x000022B3, 0x0000606C, 0x00000000, 0x00050051, 0x0000000B, 0x00001DCD, + 0x0000370E, 0x00000001, 0x0006000C, 0x00000015, 0x00003D09, 0x00000001, 0x0000003E, 0x00001DCD, + 0x00050051, 0x0000000D, 0x000022B4, 0x00003D09, 0x00000000, 0x00050051, 0x0000000B, 0x00001DCE, + 0x0000370E, 0x00000002, 0x0006000C, 0x00000015, 0x00003D0A, 0x00000001, 0x0000003E, 0x00001DCE, + 0x00050051, 0x0000000D, 0x000022B5, 0x00003D0A, 0x00000000, 0x00050051, 0x0000000B, 0x00001DCF, + 0x0000370E, 0x00000003, 0x0006000C, 0x00000015, 0x00003CEC, 0x00000001, 0x0000003E, 0x00001DCF, + 0x00050051, 0x0000000D, 0x00002827, 0x00003CEC, 0x00000000, 0x00070050, 0x0000001D, 0x00005EBE, + 0x000022B3, 0x000022B4, 0x000022B5, 0x00002827, 0x00050051, 0x0000000B, 0x0000437F, 0x00002BCE, + 0x00000000, 0x0006000C, 0x00000015, 0x00004670, 0x00000001, 0x0000003E, 0x0000437F, 0x00050051, + 0x0000000D, 0x000022B6, 0x00004670, 0x00000000, 0x00050051, 0x0000000B, 0x00001DD0, 0x00002BCE, + 0x00000001, 0x0006000C, 0x00000015, 0x00003D0C, 0x00000001, 0x0000003E, 0x00001DD0, 0x00050051, + 0x0000000D, 0x000022B7, 0x00003D0C, 0x00000000, 0x00050051, 0x0000000B, 0x00001DD1, 0x00002BCE, + 0x00000002, 0x0006000C, 0x00000015, 0x00003D0D, 0x00000001, 0x0000003E, 0x00001DD1, 0x00050051, + 0x0000000D, 0x000022B8, 0x00003D0D, 0x00000000, 0x00050051, 0x0000000B, 0x00001DD2, 0x00002BCE, + 0x00000003, 0x0006000C, 0x00000015, 0x00003CED, 0x00000001, 0x0000003E, 0x00001DD2, 0x00050051, + 0x0000000D, 0x0000349F, 0x00003CED, 0x00000000, 0x00070050, 0x0000001D, 0x000048FB, 0x000022B6, + 0x000022B7, 0x000022B8, 0x0000349F, 0x000200F9, 0x00005BA9, 0x000200F8, 0x000052CB, 0x0004007C, + 0x0000001A, 0x000060F9, 0x0000370E, 0x000500C4, 0x0000001A, 0x00005823, 0x000060F9, 0x00000302, + 0x000500C3, 0x0000001A, 0x000040A2, 0x00005823, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA7, + 0x000040A2, 0x0005008E, 0x0000001D, 0x00004A7D, 0x00002AA7, 0x000007FE, 0x0007000C, 0x0000001D, + 0x00004985, 0x00000001, 0x00000028, 0x00000504, 0x00004A7D, 0x0004007C, 0x0000001A, 0x000027EA, + 0x00002BCE, 0x000500C4, 0x0000001A, 0x000021A6, 0x000027EA, 0x00000302, 0x000500C3, 0x0000001A, + 0x000040A3, 0x000021A6, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA8, 0x000040A3, 0x0005008E, + 0x0000001D, 0x000053C4, 0x00002AA8, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004367, 0x00000001, + 0x00000028, 0x00000504, 0x000053C4, 0x000200F9, 0x00005BA9, 0x000200F8, 0x000030EF, 0x0004007C, + 0x0000001D, 0x00004B24, 0x0000370E, 0x0004007C, 0x0000001D, 0x000038B7, 0x00002BCE, 0x000200F9, + 0x00005BA9, 0x000200F8, 0x00005BA9, 0x000900F5, 0x0000001D, 0x00002BF8, 0x000038B7, 0x000030EF, + 0x00004367, 0x000052CB, 0x000048FB, 0x00002038, 0x000900F5, 0x0000001D, 0x00003593, 0x00004B24, + 0x000030EF, 0x00004985, 0x000052CB, 0x00005EBE, 0x00002038, 0x000200F9, 0x00005311, 0x000200F8, + 0x00005311, 0x000700F5, 0x0000001D, 0x0000230C, 0x00002BF8, 0x00005BA9, 0x00002BF7, 0x00005BA8, + 0x000700F5, 0x0000001D, 0x00004C8B, 0x00003593, 0x00005BA9, 0x00003592, 0x00005BA8, 0x00050081, + 0x0000001D, 0x00004346, 0x000046B0, 0x00004C8B, 0x00050081, 0x0000001D, 0x000019F1, 0x0000455A, + 0x0000230C, 0x00050080, 0x0000000B, 0x00003FF8, 0x00005E78, 0x000037B2, 0x000300F7, 0x00004F26, + 0x00000002, 0x000400FA, 0x000060B1, 0x00002624, 0x00002F64, 0x000200F8, 0x00002F64, 0x00060041, + 0x00000288, 0x00004BD2, 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D4C, + 0x00004BD2, 0x00050080, 0x0000000B, 0x00002DBC, 0x00003FF8, 0x000030F7, 0x00060041, 0x00000288, + 0x0000194E, 0x00000CC7, 0x00000A0B, 0x00002DBC, 0x0004003D, 0x0000000B, 0x00005E6A, 0x0000194E, + 0x00050084, 0x0000000B, 0x00001869, 0x00000A10, 0x000030F7, 0x00050080, 0x0000000B, 0x000020B0, + 0x00003FF8, 0x00001869, 0x00060041, 0x00000288, 0x00003BD9, 0x00000CC7, 0x00000A0B, 0x000020B0, + 0x0004003D, 0x0000000B, 0x00005E6B, 0x00003BD9, 0x00050084, 0x0000000B, 0x0000186A, 0x00000A13, + 0x000030F7, 0x00050080, 0x0000000B, 0x000020B1, 0x00003FF8, 0x0000186A, 0x00060041, 0x00000288, + 0x000037F7, 0x00000CC7, 0x00000A0B, 0x000020B1, 0x0004003D, 0x0000000B, 0x0000374F, 0x000037F7, + 0x00070050, 0x00000017, 0x00004CD9, 0x00005D4C, 0x00005E6A, 0x00005E6B, 0x0000374F, 0x00050084, + 0x0000000B, 0x0000429B, 0x00000A16, 0x000030F7, 0x00050080, 0x0000000B, 0x000036AA, 0x00003FF8, + 0x0000429B, 0x00060041, 0x00000288, 0x00003BDA, 0x00000CC7, 0x00000A0B, 0x000036AA, 0x0004003D, + 0x0000000B, 0x00005E6C, 0x00003BDA, 0x00050084, 0x0000000B, 0x0000186B, 0x00000A19, 0x000030F7, + 0x00050080, 0x0000000B, 0x000020B2, 0x00003FF8, 0x0000186B, 0x00060041, 0x00000288, 0x00003BDB, + 0x00000CC7, 0x00000A0B, 0x000020B2, 0x0004003D, 0x0000000B, 0x00005E6D, 0x00003BDB, 0x00050084, + 0x0000000B, 0x0000186C, 0x00000A1C, 0x000030F7, 0x00050080, 0x0000000B, 0x000020B3, 0x00003FF8, + 0x0000186C, 0x00060041, 0x00000288, 0x00003BDC, 0x00000CC7, 0x00000A0B, 0x000020B3, 0x0004003D, + 0x0000000B, 0x00005E6E, 0x00003BDC, 0x00050084, 0x0000000B, 0x0000186D, 0x00000A1F, 0x000030F7, + 0x00050080, 0x0000000B, 0x000020B4, 0x00003FF8, 0x0000186D, 0x00060041, 0x00000288, 0x000037F8, + 0x00000CC7, 0x00000A0B, 0x000020B4, 0x0004003D, 0x0000000B, 0x00004001, 0x000037F8, 0x00070050, + 0x00000017, 0x00005132, 0x00005E6C, 0x00005E6D, 0x00005E6E, 0x00004001, 0x000200F9, 0x00004F26, + 0x000200F8, 0x00002624, 0x00060041, 0x00000288, 0x00005548, 0x00000CC7, 0x00000A0B, 0x00003FF8, + 0x0004003D, 0x0000000B, 0x00005D4D, 0x00005548, 0x00050080, 0x0000000B, 0x00002DBD, 0x00003FF8, + 0x00000A0D, 0x00060041, 0x00000288, 0x0000190B, 0x00000CC7, 0x00000A0B, 0x00002DBD, 0x0004003D, + 0x0000000B, 0x00005C71, 0x0000190B, 0x00050080, 0x0000000B, 0x00002DBE, 0x00003FF8, 0x00000A10, + 0x00060041, 0x00000288, 0x0000190C, 0x00000CC7, 0x00000A0B, 0x00002DBE, 0x0004003D, 0x0000000B, + 0x00005C72, 0x0000190C, 0x00050080, 0x0000000B, 0x00002DBF, 0x00003FF8, 0x00000A13, 0x00060041, + 0x00000288, 0x00005FF4, 0x00000CC7, 0x00000A0B, 0x00002DBF, 0x0004003D, 0x0000000B, 0x00003703, + 0x00005FF4, 0x00070050, 0x00000017, 0x00004AE0, 0x00005D4D, 0x00005C71, 0x00005C72, 0x00003703, + 0x00050080, 0x0000000B, 0x000057E8, 0x00003FF8, 0x00000A16, 0x00060041, 0x00000288, 0x0000604E, + 0x00000CC7, 0x00000A0B, 0x000057E8, 0x0004003D, 0x0000000B, 0x00005C73, 0x0000604E, 0x00050080, + 0x0000000B, 0x00002DC0, 0x00003FF8, 0x00000A19, 0x00060041, 0x00000288, 0x0000190D, 0x00000CC7, + 0x00000A0B, 0x00002DC0, 0x0004003D, 0x0000000B, 0x00005C74, 0x0000190D, 0x00050080, 0x0000000B, + 0x00002DC1, 0x00003FF8, 0x00000A1C, 0x00060041, 0x00000288, 0x0000190E, 0x00000CC7, 0x00000A0B, + 0x00002DC1, 0x0004003D, 0x0000000B, 0x00005C75, 0x0000190E, 0x00050080, 0x0000000B, 0x00002DC2, + 0x00003FF8, 0x00000A1F, 0x00060041, 0x00000288, 0x00005FF5, 0x00000CC7, 0x00000A0B, 0x00002DC2, + 0x0004003D, 0x0000000B, 0x00004002, 0x00005FF5, 0x00070050, 0x00000017, 0x00005133, 0x00005C73, + 0x00005C74, 0x00005C75, 0x00004002, 0x000200F9, 0x00004F26, 0x000200F8, 0x00004F26, 0x000700F5, + 0x00000017, 0x00002BCF, 0x00005133, 0x00002624, 0x00005132, 0x00002F64, 0x000700F5, 0x00000017, + 0x0000370F, 0x00004AE0, 0x00002624, 0x00004CD9, 0x00002F64, 0x000300F7, 0x00005312, 0x00000002, + 0x000400FA, 0x000043D9, 0x0000522A, 0x00005784, 0x000200F8, 0x00005784, 0x000300F7, 0x00005BAA, + 0x00000000, 0x001300FB, 0x00002180, 0x00006035, 0x00000000, 0x00003E88, 0x00000001, 0x00003E88, + 0x00000002, 0x00003845, 0x0000000A, 0x00003845, 0x00000003, 0x000059C2, 0x0000000C, 0x000059C2, + 0x00000004, 0x000052CC, 0x00000006, 0x00002039, 0x000200F8, 0x00002039, 0x00050051, 0x0000000B, + 0x00005F5C, 0x0000370F, 0x00000000, 0x0006000C, 0x00000015, 0x0000606D, 0x00000001, 0x0000003E, + 0x00005F5C, 0x00050051, 0x0000000D, 0x000022B9, 0x0000606D, 0x00000000, 0x00050051, 0x0000000B, + 0x00001DD3, 0x0000370F, 0x00000001, 0x0006000C, 0x00000015, 0x00003D0E, 0x00000001, 0x0000003E, + 0x00001DD3, 0x00050051, 0x0000000D, 0x000022BA, 0x00003D0E, 0x00000000, 0x00050051, 0x0000000B, + 0x00001DD4, 0x0000370F, 0x00000002, 0x0006000C, 0x00000015, 0x00003D0F, 0x00000001, 0x0000003E, + 0x00001DD4, 0x00050051, 0x0000000D, 0x000022BB, 0x00003D0F, 0x00000000, 0x00050051, 0x0000000B, + 0x00001DD5, 0x0000370F, 0x00000003, 0x0006000C, 0x00000015, 0x00003CEE, 0x00000001, 0x0000003E, + 0x00001DD5, 0x00050051, 0x0000000D, 0x00002828, 0x00003CEE, 0x00000000, 0x00070050, 0x0000001D, + 0x00005EBF, 0x000022B9, 0x000022BA, 0x000022BB, 0x00002828, 0x00050051, 0x0000000B, 0x00004380, + 0x00002BCF, 0x00000000, 0x0006000C, 0x00000015, 0x00004671, 0x00000001, 0x0000003E, 0x00004380, + 0x00050051, 0x0000000D, 0x000022BC, 0x00004671, 0x00000000, 0x00050051, 0x0000000B, 0x00001DD6, + 0x00002BCF, 0x00000001, 0x0006000C, 0x00000015, 0x00003D10, 0x00000001, 0x0000003E, 0x00001DD6, + 0x00050051, 0x0000000D, 0x000022BD, 0x00003D10, 0x00000000, 0x00050051, 0x0000000B, 0x00001DD7, + 0x00002BCF, 0x00000002, 0x0006000C, 0x00000015, 0x00003D11, 0x00000001, 0x0000003E, 0x00001DD7, + 0x00050051, 0x0000000D, 0x000022BE, 0x00003D11, 0x00000000, 0x00050051, 0x0000000B, 0x00001DD8, + 0x00002BCF, 0x00000003, 0x0006000C, 0x00000015, 0x00003CEF, 0x00000001, 0x0000003E, 0x00001DD8, + 0x00050051, 0x0000000D, 0x000034A0, 0x00003CEF, 0x00000000, 0x00070050, 0x0000001D, 0x000048FC, + 0x000022BC, 0x000022BD, 0x000022BE, 0x000034A0, 0x000200F9, 0x00005BAA, 0x000200F8, 0x000052CC, + 0x0004007C, 0x0000001A, 0x000060FA, 0x0000370F, 0x000500C4, 0x0000001A, 0x00005824, 0x000060FA, + 0x00000302, 0x000500C3, 0x0000001A, 0x000040A4, 0x00005824, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002AA9, 0x000040A4, 0x0005008E, 0x0000001D, 0x00004A7E, 0x00002AA9, 0x000007FE, 0x0007000C, + 0x0000001D, 0x00004986, 0x00000001, 0x00000028, 0x00000504, 0x00004A7E, 0x0004007C, 0x0000001A, + 0x000027EB, 0x00002BCF, 0x000500C4, 0x0000001A, 0x000021A7, 0x000027EB, 0x00000302, 0x000500C3, + 0x0000001A, 0x000040A5, 0x000021A7, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AAA, 0x000040A5, + 0x0005008E, 0x0000001D, 0x000053C5, 0x00002AAA, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004368, + 0x00000001, 0x00000028, 0x00000504, 0x000053C5, 0x000200F9, 0x00005BAA, 0x000200F8, 0x000059C2, + 0x000600A9, 0x0000000B, 0x00004C0F, 0x00001D59, 0x00000A46, 0x00000A0A, 0x00070050, 0x00000017, + 0x000023B9, 0x00004C0F, 0x00004C0F, 0x00004C0F, 0x00004C0F, 0x000500C2, 0x00000017, 0x00005D4E, + 0x0000370F, 0x000023B9, 0x000500C7, 0x00000017, 0x00005DE9, 0x00005D4E, 0x000003A1, 0x000500C7, + 0x00000017, 0x000048A2, 0x00005DE9, 0x000002D1, 0x000500C2, 0x00000017, 0x00005B96, 0x00005DE9, + 0x00000107, 0x000500AA, 0x00000013, 0x000040CF, 0x00005B96, 0x00000B50, 0x0006000C, 0x0000001A, + 0x00002C51, 0x00000001, 0x0000004B, 0x000048A2, 0x0004007C, 0x00000017, 0x00002A1B, 0x00002C51, + 0x00050082, 0x00000017, 0x00001880, 0x00000107, 0x00002A1B, 0x00050080, 0x00000017, 0x00002216, + 0x00002A1B, 0x00000A0F, 0x000600A9, 0x00000017, 0x00002875, 0x000040CF, 0x00002216, 0x00005B96, + 0x000500C4, 0x00000017, 0x00005ADB, 0x000048A2, 0x00001880, 0x000500C7, 0x00000017, 0x000049A0, + 0x00005ADB, 0x000002D1, 0x000600A9, 0x00000017, 0x00002AAB, 0x000040CF, 0x000049A0, 0x000048A2, + 0x00050080, 0x00000017, 0x00005FFF, 0x00002875, 0x0000022F, 0x000500C4, 0x00000017, 0x00004F85, + 0x00005FFF, 0x00000467, 0x000500C4, 0x00000017, 0x00003FAC, 0x00002AAB, 0x000002ED, 0x000500C5, + 0x00000017, 0x00005785, 0x00004F85, 0x00003FAC, 0x000500AA, 0x00000013, 0x00003606, 0x00005DE9, + 0x00000B50, 0x000600A9, 0x00000017, 0x00004245, 0x00003606, 0x00000B50, 0x00005785, 0x0004007C, + 0x0000001D, 0x00003047, 0x00004245, 0x000500C2, 0x00000017, 0x00006041, 0x00002BCF, 0x000023B9, + 0x000500C7, 0x00000017, 0x00003924, 0x00006041, 0x000003A1, 0x000500C7, 0x00000017, 0x000048A3, + 0x00003924, 0x000002D1, 0x000500C2, 0x00000017, 0x00005B97, 0x00003924, 0x00000107, 0x000500AA, + 0x00000013, 0x000040D0, 0x00005B97, 0x00000B50, 0x0006000C, 0x0000001A, 0x00002C52, 0x00000001, + 0x0000004B, 0x000048A3, 0x0004007C, 0x00000017, 0x00002A1C, 0x00002C52, 0x00050082, 0x00000017, + 0x00001881, 0x00000107, 0x00002A1C, 0x00050080, 0x00000017, 0x00002217, 0x00002A1C, 0x00000A0F, + 0x000600A9, 0x00000017, 0x00002876, 0x000040D0, 0x00002217, 0x00005B97, 0x000500C4, 0x00000017, + 0x00005ADC, 0x000048A3, 0x00001881, 0x000500C7, 0x00000017, 0x000049A1, 0x00005ADC, 0x000002D1, + 0x000600A9, 0x00000017, 0x00002AAC, 0x000040D0, 0x000049A1, 0x000048A3, 0x00050080, 0x00000017, + 0x00006000, 0x00002876, 0x0000022F, 0x000500C4, 0x00000017, 0x00004F86, 0x00006000, 0x00000467, + 0x000500C4, 0x00000017, 0x00003FAD, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x00005786, + 0x00004F86, 0x00003FAD, 0x000500AA, 0x00000013, 0x00003607, 0x00003924, 0x00000B50, 0x000600A9, + 0x00000017, 0x0000465A, 0x00003607, 0x00000B50, 0x00005786, 0x0004007C, 0x0000001D, 0x0000593E, + 0x0000465A, 0x000200F9, 0x00005BAA, 0x000200F8, 0x00003845, 0x000600A9, 0x0000000B, 0x00004C10, + 0x00001D59, 0x00000A46, 0x00000A0A, 0x00070050, 0x00000017, 0x000023BA, 0x00004C10, 0x00004C10, + 0x00004C10, 0x00004C10, 0x000500C2, 0x00000017, 0x000056D9, 0x0000370F, 0x000023BA, 0x000500C7, + 0x00000017, 0x00004A5C, 0x000056D9, 0x000003A1, 0x00040070, 0x0000001D, 0x00003F0B, 0x00004A5C, + 0x0005008E, 0x0000001D, 0x00005220, 0x00003F0B, 0x000006FE, 0x000500C2, 0x00000017, 0x00001E48, + 0x00002BCF, 0x000023BA, 0x000500C7, 0x00000017, 0x00002BDA, 0x00001E48, 0x000003A1, 0x00040070, + 0x0000001D, 0x00004320, 0x00002BDA, 0x0005008E, 0x0000001D, 0x00003098, 0x00004320, 0x000006FE, + 0x000200F9, 0x00005BAA, 0x000200F8, 0x00003E88, 0x000600A9, 0x0000000B, 0x00004C11, 0x00001D59, + 0x00000A3A, 0x00000A0A, 0x00070050, 0x00000017, 0x000023BB, 0x00004C11, 0x00004C11, 0x00004C11, + 0x00004C11, 0x000500C2, 0x00000017, 0x000056DA, 0x0000370F, 0x000023BB, 0x000500C7, 0x00000017, + 0x00004A5D, 0x000056DA, 0x0000064B, 0x00040070, 0x0000001D, 0x00003F0C, 0x00004A5D, 0x0005008E, + 0x0000001D, 0x00005221, 0x00003F0C, 0x0000017A, 0x000500C2, 0x00000017, 0x00001E49, 0x00002BCF, + 0x000023BB, 0x000500C7, 0x00000017, 0x00002BDB, 0x00001E49, 0x0000064B, 0x00040070, 0x0000001D, + 0x00004321, 0x00002BDB, 0x0005008E, 0x0000001D, 0x00003099, 0x00004321, 0x0000017A, 0x000200F9, + 0x00005BAA, 0x000200F8, 0x00006035, 0x0004007C, 0x0000001D, 0x00004B25, 0x0000370F, 0x0004007C, + 0x0000001D, 0x000038B8, 0x00002BCF, 0x000200F9, 0x00005BAA, 0x000200F8, 0x00005BAA, 0x000F00F5, + 0x0000001D, 0x00002BF9, 0x000038B8, 0x00006035, 0x00003099, 0x00003E88, 0x00003098, 0x00003845, + 0x0000593E, 0x000059C2, 0x00004368, 0x000052CC, 0x000048FC, 0x00002039, 0x000F00F5, 0x0000001D, + 0x00003594, 0x00004B25, 0x00006035, 0x00005221, 0x00003E88, 0x00005220, 0x00003845, 0x00003047, + 0x000059C2, 0x00004986, 0x000052CC, 0x00005EBF, 0x00002039, 0x000200F9, 0x00005312, 0x000200F8, + 0x0000522A, 0x000300F7, 0x00005BAB, 0x00000000, 0x000700FB, 0x00002180, 0x000030F0, 0x00000005, + 0x000052CD, 0x00000007, 0x0000203A, 0x000200F8, 0x0000203A, 0x00050051, 0x0000000B, 0x00005F5D, + 0x0000370F, 0x00000000, 0x0006000C, 0x00000015, 0x0000606E, 0x00000001, 0x0000003E, 0x00005F5D, + 0x00050051, 0x0000000D, 0x000022BF, 0x0000606E, 0x00000000, 0x00050051, 0x0000000B, 0x00001DD9, + 0x0000370F, 0x00000001, 0x0006000C, 0x00000015, 0x00003D12, 0x00000001, 0x0000003E, 0x00001DD9, + 0x00050051, 0x0000000D, 0x000022C0, 0x00003D12, 0x00000000, 0x00050051, 0x0000000B, 0x00001DDA, + 0x0000370F, 0x00000002, 0x0006000C, 0x00000015, 0x00003D13, 0x00000001, 0x0000003E, 0x00001DDA, + 0x00050051, 0x0000000D, 0x000022C1, 0x00003D13, 0x00000000, 0x00050051, 0x0000000B, 0x00001DDB, + 0x0000370F, 0x00000003, 0x0006000C, 0x00000015, 0x00003CF0, 0x00000001, 0x0000003E, 0x00001DDB, + 0x00050051, 0x0000000D, 0x00002829, 0x00003CF0, 0x00000000, 0x00070050, 0x0000001D, 0x00005EC0, + 0x000022BF, 0x000022C0, 0x000022C1, 0x00002829, 0x00050051, 0x0000000B, 0x00004381, 0x00002BCF, + 0x00000000, 0x0006000C, 0x00000015, 0x00004672, 0x00000001, 0x0000003E, 0x00004381, 0x00050051, + 0x0000000D, 0x000022C2, 0x00004672, 0x00000000, 0x00050051, 0x0000000B, 0x00001DDC, 0x00002BCF, + 0x00000001, 0x0006000C, 0x00000015, 0x00003D14, 0x00000001, 0x0000003E, 0x00001DDC, 0x00050051, + 0x0000000D, 0x000022C3, 0x00003D14, 0x00000000, 0x00050051, 0x0000000B, 0x00001DDD, 0x00002BCF, + 0x00000002, 0x0006000C, 0x00000015, 0x00003D15, 0x00000001, 0x0000003E, 0x00001DDD, 0x00050051, + 0x0000000D, 0x000022C4, 0x00003D15, 0x00000000, 0x00050051, 0x0000000B, 0x00001DDE, 0x00002BCF, + 0x00000003, 0x0006000C, 0x00000015, 0x00003CF1, 0x00000001, 0x0000003E, 0x00001DDE, 0x00050051, + 0x0000000D, 0x000034A1, 0x00003CF1, 0x00000000, 0x00070050, 0x0000001D, 0x000048FD, 0x000022C2, + 0x000022C3, 0x000022C4, 0x000034A1, 0x000200F9, 0x00005BAB, 0x000200F8, 0x000052CD, 0x0004007C, + 0x0000001A, 0x000060FB, 0x0000370F, 0x000500C4, 0x0000001A, 0x00005825, 0x000060FB, 0x00000302, + 0x000500C3, 0x0000001A, 0x000040A6, 0x00005825, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AAD, + 0x000040A6, 0x0005008E, 0x0000001D, 0x00004A7F, 0x00002AAD, 0x000007FE, 0x0007000C, 0x0000001D, + 0x00004987, 0x00000001, 0x00000028, 0x00000504, 0x00004A7F, 0x0004007C, 0x0000001A, 0x000027EC, + 0x00002BCF, 0x000500C4, 0x0000001A, 0x000021A8, 0x000027EC, 0x00000302, 0x000500C3, 0x0000001A, + 0x000040A7, 0x000021A8, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AAE, 0x000040A7, 0x0005008E, + 0x0000001D, 0x000053C6, 0x00002AAE, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004369, 0x00000001, + 0x00000028, 0x00000504, 0x000053C6, 0x000200F9, 0x00005BAB, 0x000200F8, 0x000030F0, 0x0004007C, + 0x0000001D, 0x00004B26, 0x0000370F, 0x0004007C, 0x0000001D, 0x000038B9, 0x00002BCF, 0x000200F9, + 0x00005BAB, 0x000200F8, 0x00005BAB, 0x000900F5, 0x0000001D, 0x00002BFA, 0x000038B9, 0x000030F0, + 0x00004369, 0x000052CD, 0x000048FD, 0x0000203A, 0x000900F5, 0x0000001D, 0x00003595, 0x00004B26, + 0x000030F0, 0x00004987, 0x000052CD, 0x00005EC0, 0x0000203A, 0x000200F9, 0x00005312, 0x000200F8, + 0x00005312, 0x000700F5, 0x0000001D, 0x0000230D, 0x00002BFA, 0x00005BAB, 0x00002BF9, 0x00005BAA, + 0x000700F5, 0x0000001D, 0x00004C8C, 0x00003595, 0x00005BAB, 0x00003594, 0x00005BAA, 0x00050081, + 0x0000001D, 0x00004C41, 0x00004346, 0x00004C8C, 0x00050081, 0x0000001D, 0x00005D3D, 0x000019F1, + 0x0000230D, 0x000200F9, 0x00005EC8, 0x000200F8, 0x00005EC8, 0x000700F5, 0x0000001D, 0x00002BA7, + 0x0000455A, 0x00005310, 0x00005D3D, 0x00005312, 0x000700F5, 0x0000001D, 0x00003854, 0x000046B0, + 0x00005310, 0x00004C41, 0x00005312, 0x000700F5, 0x0000000D, 0x000038BA, 0x000061FB, 0x00005310, + 0x00002F3A, 0x00005312, 0x000200F9, 0x00005313, 0x000200F8, 0x00005313, 0x000700F5, 0x0000001D, + 0x00002BA8, 0x00002662, 0x0000530F, 0x00002BA7, 0x00005EC8, 0x000700F5, 0x0000001D, 0x00003063, + 0x000036E3, 0x0000530F, 0x00003854, 0x00005EC8, 0x000700F5, 0x0000000D, 0x00002EA8, 0x00002B2C, + 0x0000530F, 0x000038BA, 0x00005EC8, 0x0005008E, 0x0000001D, 0x00005C88, 0x00003063, 0x00002EA8, + 0x0005008E, 0x0000001D, 0x00005360, 0x00002BA8, 0x00002EA8, 0x000500AA, 0x00000009, 0x00001C08, + 0x00005FB2, 0x00000A0A, 0x000600A9, 0x00000009, 0x00003477, 0x00001C08, 0x00000787, 0x00001C08, + 0x000300F7, 0x00004CC1, 0x00000002, 0x000400FA, 0x00003477, 0x00002620, 0x00004CC1, 0x000200F8, + 0x00002620, 0x00050051, 0x0000000D, 0x00005002, 0x00005C88, 0x00000001, 0x00060052, 0x0000001D, + 0x000037FF, 0x00005002, 0x00005C88, 0x00000000, 0x000200F9, 0x00004CC1, 0x000200F8, 0x00004CC1, + 0x000700F5, 0x0000001D, 0x0000305F, 0x00005C88, 0x00005313, 0x000037FF, 0x00002620, 0x00050080, + 0x00000011, 0x000032A7, 0x00002670, 0x000059EC, 0x000300F7, 0x000052F5, 0x00000002, 0x000400FA, + 0x000048EB, 0x0000294E, 0x0000537D, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000012, 0x00002970, + 0x000032A7, 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, + 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000001, + 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, + 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, + 0x00005347, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, + 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A1F, 0x000500C7, 0x0000000C, 0x00002AB6, + 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x00002747, 0x00000A35, 0x000500C4, + 0x0000000C, 0x00003FF5, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x000029C0, 0x00002AB6, + 0x00003FF5, 0x0004007C, 0x0000000C, 0x00002D07, 0x000029C0, 0x000500C7, 0x0000000C, 0x0000424F, + 0x00002D07, 0x000009DB, 0x000500C4, 0x0000000C, 0x000060E9, 0x0000424F, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4B, 0x00004A8E, 0x000060E9, 0x000500C7, 0x0000000C, 0x00003397, 0x00002D07, + 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4B, 0x00003397, 0x000500C7, 0x0000000C, + 0x000047B4, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544A, 0x000047B4, 0x00000A17, + 0x00050080, 0x0000000C, 0x00004157, 0x00004D30, 0x0000544A, 0x000500C7, 0x0000000C, 0x00005022, + 0x00004157, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F76, 0x00004A33, + 0x00000A20, 0x00050080, 0x0000000C, 0x00004158, 0x00002416, 0x00002F76, 0x000500C7, 0x0000000C, + 0x00004AE1, 0x00004157, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544B, 0x00004AE1, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004144, 0x00004158, 0x0000544B, 0x000500C7, 0x0000000C, 0x00005083, + 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, + 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, + 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544C, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004144, 0x0000544C, + 0x000500C7, 0x0000000C, 0x00002E06, 0x00004157, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, + 0x00003C4C, 0x00002E06, 0x0004007C, 0x0000000B, 0x0000566F, 0x0000394F, 0x000200F9, 0x000052F5, + 0x000200F8, 0x0000294E, 0x00050051, 0x0000000B, 0x00004D9A, 0x000032A7, 0x00000000, 0x00050051, + 0x0000000B, 0x00002C03, 0x000032A7, 0x00000001, 0x00060050, 0x00000014, 0x000020DE, 0x00004D9A, + 0x00002C03, 0x00004408, 0x0004007C, 0x00000016, 0x00004E9D, 0x000020DE, 0x00050051, 0x0000000C, + 0x000028C6, 0x00004E9D, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FE, 0x000028C6, 0x00000A17, + 0x00050051, 0x0000000C, 0x00002748, 0x00004E9D, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405D, + 0x00002748, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00006273, 0x00000A16, 0x0004007C, + 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005321, 0x0000405D, 0x000018AB, + 0x00050080, 0x0000000C, 0x00003B27, 0x000024FE, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, + 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, + 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, 0x00004E9D, 0x00000000, + 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, + 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A1C, 0x000500C7, + 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, + 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003139, 0x000028C6, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003139, 0x00000A11, + 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, + 0x0000434B, 0x00000A1C, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, + 0x0000000C, 0x00002218, 0x000028C6, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002218, + 0x0000405D, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, + 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, + 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004AE2, + 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544D, 0x00004AE2, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4D, 0x00005A0C, 0x0000544D, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, + 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, + 0x00005B32, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, + 0x00050080, 0x0000000C, 0x0000285C, 0x00005B32, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B5, + 0x00002748, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544E, 0x000047B5, 0x00000A1C, 0x00050080, + 0x0000000C, 0x00004159, 0x0000285C, 0x0000544E, 0x000500C7, 0x0000000C, 0x00004AE3, 0x000028C6, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544F, 0x00004AE3, 0x00000A17, 0x00050080, 0x0000000C, + 0x0000415A, 0x00004159, 0x0000544F, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4D, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, + 0x0000415A, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, + 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B33, 0x00003412, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4D, 0x00000A05, 0x00050080, 0x0000000C, + 0x00002AAF, 0x00005B33, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002AAF, 0x00000A11, + 0x000500C7, 0x0000000C, 0x00005AB2, 0x0000415A, 0x0000040B, 0x00050080, 0x0000000C, 0x00002AB0, + 0x00005B34, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B35, 0x00002AB0, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00005559, 0x0000415A, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B35, + 0x00005559, 0x0004007C, 0x0000000B, 0x00005670, 0x00005EFA, 0x000200F9, 0x000052F5, 0x000200F8, + 0x000052F5, 0x000700F5, 0x0000000B, 0x00002C70, 0x00005670, 0x0000294E, 0x0000566F, 0x0000537D, + 0x00050080, 0x0000000B, 0x000044F9, 0x00002C70, 0x00005EAD, 0x000500C2, 0x0000000B, 0x00005DC7, + 0x000044F9, 0x00000A13, 0x0008000C, 0x0000001D, 0x00005E5A, 0x00000001, 0x0000002B, 0x0000305F, + 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, 0x00002371, 0x00005E5A, 0x00000540, 0x00050081, + 0x0000001D, 0x00002E66, 0x00002371, 0x00000145, 0x0004006D, 0x00000017, 0x00001DDF, 0x00002E66, + 0x00050051, 0x0000000B, 0x000021FC, 0x00001DDF, 0x00000000, 0x00050051, 0x0000000B, 0x00002FDB, + 0x00001DDF, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D29, 0x00002FDB, 0x00000A23, 0x000500C5, + 0x0000000B, 0x00004D66, 0x000021FC, 0x00002D29, 0x00050051, 0x0000000B, 0x000053E4, 0x00001DDF, + 0x00000002, 0x000500C4, 0x0000000B, 0x00002170, 0x000053E4, 0x00000A3B, 0x000500C5, 0x0000000B, + 0x00004D67, 0x00004D66, 0x00002170, 0x00050051, 0x0000000B, 0x000053E5, 0x00001DDF, 0x00000003, + 0x000500C4, 0x0000000B, 0x00001C7C, 0x000053E5, 0x00000A53, 0x000500C5, 0x0000000B, 0x00002427, + 0x00004D67, 0x00001C7C, 0x0008000C, 0x0000001D, 0x00001D62, 0x00000001, 0x0000002B, 0x00005360, + 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, 0x00002048, 0x00001D62, 0x00000540, 0x00050081, + 0x0000001D, 0x00002E67, 0x00002048, 0x00000145, 0x0004006D, 0x00000017, 0x00001DE0, 0x00002E67, + 0x00050051, 0x0000000B, 0x000021FD, 0x00001DE0, 0x00000000, 0x00050051, 0x0000000B, 0x00002FDC, + 0x00001DE0, 0x00000001, 0x000500C4, 0x0000000B, 0x00002D2A, 0x00002FDC, 0x00000A23, 0x000500C5, + 0x0000000B, 0x00004D68, 0x000021FD, 0x00002D2A, 0x00050051, 0x0000000B, 0x000053E6, 0x00001DE0, + 0x00000002, 0x000500C4, 0x0000000B, 0x00002171, 0x000053E6, 0x00000A3B, 0x000500C5, 0x0000000B, + 0x00004D69, 0x00004D68, 0x00002171, 0x00050051, 0x0000000B, 0x000053E7, 0x00001DE0, 0x00000003, + 0x000500C4, 0x0000000B, 0x0000215D, 0x000053E7, 0x00000A53, 0x000500C5, 0x0000000B, 0x0000445A, + 0x00004D69, 0x0000215D, 0x00050050, 0x00000011, 0x00002D69, 0x00002427, 0x0000445A, 0x00060041, + 0x0000028E, 0x00002312, 0x00001592, 0x00000A0B, 0x00005DC7, 0x0003003E, 0x00002312, 0x00002D69, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/resolve_full_8bpp_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/resolve_full_8bpp_scaled_cs.h new file mode 100644 index 0000000..ce03f32 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/resolve_full_8bpp_scaled_cs.h @@ -0,0 +1,2416 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25262 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 8 8 1 + OpDecorate %_runtimearr_uint ArrayStride 4 + OpDecorate %_struct_1948 BufferBlock + OpMemberDecorate %_struct_1948 0 NonWritable + OpMemberDecorate %_struct_1948 0 Offset 0 + OpDecorate %3271 NonWritable + OpDecorate %3271 Binding 0 + OpDecorate %3271 DescriptorSet 0 + OpDecorate %_struct_1017 Block + OpMemberDecorate %_struct_1017 0 Offset 0 + OpMemberDecorate %_struct_1017 1 Offset 4 + OpMemberDecorate %_struct_1017 2 Offset 8 + OpMemberDecorate %_struct_1017 3 Offset 12 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v2uint ArrayStride 8 + OpDecorate %_struct_1960 BufferBlock + OpMemberDecorate %_struct_1960 0 NonReadable + OpMemberDecorate %_struct_1960 0 Offset 0 + OpDecorate %5522 NonReadable + OpDecorate %5522 Binding 0 + OpDecorate %5522 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %bool = OpTypeBool + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %v3uint = OpTypeVector %uint 3 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 + %v4int = OpTypeVector %int 4 + %float_255 = OpConstant %float 255 + %float_0_5 = OpConstant %float 0.5 + %uint_0 = OpConstant %uint 0 + %uint_1 = OpConstant %uint 1 + %int_8 = OpConstant %int 8 + %uint_2 = OpConstant %uint 2 + %int_16 = OpConstant %int 16 + %uint_3 = OpConstant %uint 3 + %int_24 = OpConstant %int 24 + %uint_255 = OpConstant %uint 255 +%float_0_00392156886 = OpConstant %float 0.00392156886 + %uint_1023 = OpConstant %uint 1023 +%float_0_000977517106 = OpConstant %float 0.000977517106 + %uint_127 = OpConstant %uint 127 + %uint_7 = OpConstant %uint 7 + %v4bool = OpTypeVector %bool 4 + %uint_124 = OpConstant %uint 124 + %uint_23 = OpConstant %uint 23 + %uint_16 = OpConstant %uint 16 + %float_n1 = OpConstant %float -1 +%float_0_000976592302 = OpConstant %float 0.000976592302 + %1837 = OpConstantComposite %v2uint %uint_2 %uint_1 + %v2bool = OpTypeVector %bool 2 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1816 = OpConstantComposite %v2uint %uint_1 %uint_0 + %uint_80 = OpConstant %uint 80 + %2719 = OpConstantComposite %v2uint %uint_80 %uint_16 + %uint_2048 = OpConstant %uint 2048 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_448 = OpConstant %int 448 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 + %uint_6 = OpConstant %uint 6 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_runtimearr_uint = OpTypeRuntimeArray %uint +%_struct_1948 = OpTypeStruct %_runtimearr_uint +%_ptr_Uniform__struct_1948 = OpTypePointer Uniform %_struct_1948 + %3271 = OpVariable %_ptr_Uniform__struct_1948 Uniform + %int_0 = OpConstant %int 0 +%_ptr_Uniform_uint = OpTypePointer Uniform %uint +%_struct_1017 = OpTypeStruct %uint %uint %uint %uint +%_ptr_PushConstant__struct_1017 = OpTypePointer PushConstant %_struct_1017 + %3305 = OpVariable %_ptr_PushConstant__struct_1017 PushConstant +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %uint_10 = OpConstant %uint 10 + %uint_13 = OpConstant %uint 13 + %uint_2047 = OpConstant %uint 2047 + %uint_24 = OpConstant %uint 24 + %uint_15 = OpConstant %uint 15 + %uint_28 = OpConstant %uint 28 + %uint_19 = OpConstant %uint 19 + %2179 = OpConstantComposite %v2uint %uint_16 %uint_19 +%uint_536870912 = OpConstant %uint 536870912 + %1855 = OpConstantComposite %v2uint %uint_0 %uint_4 + %int_10 = OpConstant %int 10 + %uint_8 = OpConstant %uint 8 + %int_26 = OpConstant %int 26 + %int_23 = OpConstant %int 23 +%uint_16777216 = OpConstant %uint 16777216 + %uint_20 = OpConstant %uint 20 + %2275 = OpConstantComposite %v2uint %uint_20 %uint_24 + %v2float = OpTypeVector %float 2 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_ptr_Input_uint = OpTypePointer Input %uint + %1834 = OpConstantComposite %v2uint %uint_3 %uint_0 +%_runtimearr_v2uint = OpTypeRuntimeArray %v2uint +%_struct_1960 = OpTypeStruct %_runtimearr_v2uint +%_ptr_Uniform__struct_1960 = OpTypePointer Uniform %_struct_1960 + %5522 = OpVariable %_ptr_Uniform__struct_1960 Uniform +%_ptr_Uniform_v2uint = OpTypePointer Uniform %v2uint +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_8 %uint_8 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %1955 = OpConstantComposite %v2uint %uint_15 %uint_1 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %1284 = OpConstantComposite %v4float %float_n1 %float_n1 %float_n1 %float_n1 + %770 = OpConstantComposite %v4int %int_16 %int_16 %int_16 %int_16 + %1611 = OpConstantComposite %v4uint %uint_255 %uint_255 %uint_255 %uint_255 + %929 = OpConstantComposite %v4uint %uint_1023 %uint_1023 %uint_1023 %uint_1023 + %721 = OpConstantComposite %v4uint %uint_127 %uint_127 %uint_127 %uint_127 + %263 = OpConstantComposite %v4uint %uint_7 %uint_7 %uint_7 %uint_7 + %2896 = OpConstantComposite %v4uint %uint_0 %uint_0 %uint_0 %uint_0 + %559 = OpConstantComposite %v4uint %uint_124 %uint_124 %uint_124 %uint_124 + %1127 = OpConstantComposite %v4uint %uint_23 %uint_23 %uint_23 %uint_23 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %2938 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 + %1285 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 + %325 = OpConstantComposite %v4float %float_0_5 %float_0_5 %float_0_5 %float_0_5 +%int_1065353216 = OpConstant %int 1065353216 +%uint_4294967290 = OpConstant %uint 4294967290 + %2575 = OpConstantComposite %v4uint %uint_4294967290 %uint_4294967290 %uint_4294967290 %uint_4294967290 + %float_0_25 = OpConstant %float 0.25 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %22245 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %15627 = OpLoad %uint %22245 + %22700 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %20824 = OpLoad %uint %22700 + %20561 = OpBitwiseAnd %uint %15627 %uint_1023 + %19978 = OpShiftRightLogical %uint %15627 %uint_10 + %8574 = OpBitwiseAnd %uint %19978 %uint_3 + %21002 = OpShiftRightLogical %uint %15627 %uint_13 + %8575 = OpBitwiseAnd %uint %21002 %uint_2047 + %21003 = OpShiftRightLogical %uint %15627 %uint_24 + %8576 = OpBitwiseAnd %uint %21003 %uint_15 + %18836 = OpShiftRightLogical %uint %15627 %uint_28 + %9130 = OpBitwiseAnd %uint %18836 %uint_1 + %8871 = OpCompositeConstruct %v2uint %20824 %20824 + %9633 = OpShiftRightLogical %v2uint %8871 %2179 + %23601 = OpBitwiseAnd %v2uint %9633 %1954 + %24030 = OpBitwiseAnd %uint %15627 %uint_536870912 + %12295 = OpINotEqual %bool %24030 %uint_0 + OpSelectionMerge %14676 None + OpBranchConditional %12295 %16739 %21992 + %21992 = OpLabel + OpBranch %14676 + %16739 = OpLabel + %15278 = OpShiftRightLogical %v2uint %23601 %1828 + OpBranch %14676 + %14676 = OpLabel + %19124 = OpPhi %v2uint %15278 %16739 %1807 %21992 + %7038 = OpShiftRightLogical %v2uint %8871 %1855 + %11769 = OpBitwiseAnd %v2uint %7038 %1955 + %16207 = OpShiftLeftLogical %v2uint %11769 %1870 + %23019 = OpIMul %v2uint %16207 %23601 + %13123 = OpShiftRightLogical %uint %20824 %uint_5 + %14785 = OpBitwiseAnd %uint %13123 %uint_2047 + %8858 = OpCompositeExtract %uint %23601 0 + %22993 = OpIMul %uint %14785 %8858 + %20036 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %18628 = OpLoad %uint %20036 + %22701 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %20387 = OpLoad %uint %22701 + %24445 = OpBitwiseAnd %uint %18628 %uint_8 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8977 = OpShiftRightLogical %uint %18628 %uint_4 + %17416 = OpBitwiseAnd %uint %8977 %uint_7 + %22920 = OpBitcast %int %18628 + %13711 = OpShiftLeftLogical %int %22920 %int_10 + %20636 = OpShiftRightArithmetic %int %13711 %int_26 + %18178 = OpShiftLeftLogical %int %20636 %int_23 + %7462 = OpIAdd %int %18178 %int_1065353216 + %11052 = OpBitcast %float %7462 + %22649 = OpBitwiseAnd %uint %18628 %uint_16777216 + %7513 = OpINotEqual %bool %22649 %uint_0 + %8003 = OpBitwiseAnd %uint %20387 %uint_1023 + %15783 = OpShiftLeftLogical %uint %8003 %uint_5 + %22591 = OpShiftRightLogical %uint %20387 %uint_10 + %19390 = OpBitwiseAnd %uint %22591 %uint_1023 + %25203 = OpShiftLeftLogical %uint %19390 %uint_5 + %10422 = OpCompositeConstruct %v2uint %20387 %20387 + %10385 = OpShiftRightLogical %v2uint %10422 %2275 + %23379 = OpBitwiseAnd %v2uint %10385 %2122 + %16208 = OpShiftLeftLogical %v2uint %23379 %1870 + %23020 = OpIMul %v2uint %16208 %23601 + %12819 = OpShiftRightLogical %uint %20387 %uint_28 + %16204 = OpBitwiseAnd %uint %12819 %uint_7 + %20803 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0 + %8913 = OpLoad %uint %20803 + %7405 = OpUGreaterThanEqual %bool %8913 %22993 + OpSelectionMerge %17447 DontFlatten + OpBranchConditional %7405 %21993 %17447 + %21993 = OpLabel + OpBranch %19578 + %17447 = OpLabel + %14637 = OpLoad %v3uint %gl_GlobalInvocationID + %18505 = OpVectorShuffle %v2uint %14637 %14637 0 1 + %9840 = OpShiftLeftLogical %v2uint %18505 %1834 + %6697 = OpCompositeExtract %uint %9840 0 + %18425 = OpCompositeExtract %uint %9840 1 + %14186 = OpCompositeExtract %uint %19124 1 + %24446 = OpExtInst %uint %1 UMax %18425 %14186 + %20975 = OpCompositeConstruct %v2uint %6697 %24446 + %21036 = OpIAdd %v2uint %20975 %23019 + %16075 = OpULessThanEqual %bool %16204 %uint_3 + OpSelectionMerge %23776 None + OpBranchConditional %16075 %10990 %15087 + %15087 = OpLabel + %13566 = OpIEqual %bool %16204 %uint_5 + %8438 = OpSelect %uint %13566 %uint_2 %uint_0 + OpBranch %23776 + %10990 = OpLabel + OpBranch %23776 + %23776 = OpLabel + %19300 = OpPhi %uint %16204 %10990 %8438 %15087 + %16830 = OpCompositeConstruct %v2uint %8574 %8574 + %11801 = OpUGreaterThanEqual %v2bool %16830 %1837 + %19381 = OpSelect %v2uint %11801 %1828 %1807 + %10986 = OpShiftLeftLogical %v2uint %21036 %19381 + %24669 = OpCompositeConstruct %v2uint %19300 %19300 + %9093 = OpShiftRightLogical %v2uint %24669 %1816 + %16072 = OpBitwiseAnd %v2uint %9093 %1828 + %18106 = OpIAdd %v2uint %10986 %16072 + %22936 = OpIMul %v2uint %2719 %23601 + %11332 = OpCompositeConstruct %v2uint %9130 %uint_0 + %6571 = OpShiftRightLogical %v2uint %22936 %11332 + %10146 = OpUDiv %v2uint %18106 %6571 + %20390 = OpCompositeExtract %uint %10146 1 + %11046 = OpIMul %uint %20390 %20561 + %24665 = OpCompositeExtract %uint %10146 0 + %21536 = OpIAdd %uint %11046 %24665 + %8742 = OpIAdd %uint %8575 %21536 + %22376 = OpIMul %v2uint %10146 %6571 + %20715 = OpISub %v2uint %18106 %22376 + %7303 = OpCompositeExtract %uint %22936 0 + %22882 = OpCompositeExtract %uint %22936 1 + %13170 = OpIMul %uint %7303 %22882 + %14551 = OpIMul %uint %8742 %13170 + %6805 = OpCompositeExtract %uint %20715 1 + %23526 = OpCompositeExtract %uint %6571 0 + %22886 = OpIMul %uint %6805 %23526 + %6886 = OpCompositeExtract %uint %20715 0 + %9696 = OpIAdd %uint %22886 %6886 + %18021 = OpShiftLeftLogical %uint %9696 %9130 + %18363 = OpIAdd %uint %14551 %18021 + %13504 = OpIMul %uint %13170 %uint_2048 + %25231 = OpUMod %uint %18363 %13504 + %16379 = OpUGreaterThanEqual %bool %8574 %uint_2 + %24735 = OpSelect %uint %16379 %uint_1 %uint_0 + %21518 = OpIAdd %uint %9130 %24735 + %12535 = OpShiftLeftLogical %uint %uint_1 %21518 + OpSelectionMerge %25261 None + OpBranchConditional %7513 %23873 %25261 + %23873 = OpLabel + %6992 = OpIAdd %uint %25231 %9130 + OpBranch %25261 + %25261 = OpLabel + %24188 = OpPhi %uint %25231 %23776 %6992 %23873 + %24753 = OpIEqual %bool %12535 %uint_1 + OpSelectionMerge %20259 DontFlatten + OpBranchConditional %24753 %9761 %12129 + %12129 = OpLabel + %19407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24188 + %23875 = OpLoad %uint %19407 + %11687 = OpIAdd %uint %24188 %12535 + %6475 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11687 + %24155 = OpLoad %uint %6475 + %6234 = OpIMul %uint %uint_2 %12535 + %8353 = OpIAdd %uint %24188 %6234 + %15309 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8353 + %24156 = OpLoad %uint %15309 + %6235 = OpIMul %uint %uint_3 %12535 + %8354 = OpIAdd %uint %24188 %6235 + %14321 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8354 + %14156 = OpLoad %uint %14321 + %19670 = OpCompositeConstruct %v4uint %23875 %24155 %24156 %14156 + %17048 = OpIMul %uint %uint_4 %12535 + %13991 = OpIAdd %uint %24188 %17048 + %15310 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13991 + %24157 = OpLoad %uint %15310 + %6236 = OpIMul %uint %uint_5 %12535 + %8355 = OpIAdd %uint %24188 %6236 + %15311 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8355 + %24158 = OpLoad %uint %15311 + %6237 = OpIMul %uint %uint_6 %12535 + %8356 = OpIAdd %uint %24188 %6237 + %15312 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8356 + %24159 = OpLoad %uint %15312 + %6238 = OpIMul %uint %uint_7 %12535 + %8357 = OpIAdd %uint %24188 %6238 + %14322 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8357 + %16380 = OpLoad %uint %14322 + %20780 = OpCompositeConstruct %v4uint %24157 %24158 %24159 %16380 + OpBranch %20259 + %9761 = OpLabel + %21829 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %24188 + %23876 = OpLoad %uint %21829 + %11688 = OpIAdd %uint %24188 %uint_1 + %6399 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11688 + %23650 = OpLoad %uint %6399 + %11689 = OpIAdd %uint %24188 %uint_2 + %6400 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11689 + %23651 = OpLoad %uint %6400 + %11690 = OpIAdd %uint %24188 %uint_3 + %24558 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11690 + %14080 = OpLoad %uint %24558 + %19165 = OpCompositeConstruct %v4uint %23876 %23650 %23651 %14080 + %22501 = OpIAdd %uint %24188 %uint_4 + %24651 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22501 + %23652 = OpLoad %uint %24651 + %11691 = OpIAdd %uint %24188 %uint_5 + %6401 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11691 + %23653 = OpLoad %uint %6401 + %11692 = OpIAdd %uint %24188 %uint_6 + %6402 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11692 + %23654 = OpLoad %uint %6402 + %11693 = OpIAdd %uint %24188 %uint_7 + %24559 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11693 + %16381 = OpLoad %uint %24559 + %20781 = OpCompositeConstruct %v4uint %23652 %23653 %23654 %16381 + OpBranch %20259 + %20259 = OpLabel + %9769 = OpPhi %v4uint %20781 %9761 %20780 %12129 + %14570 = OpPhi %v4uint %19165 %9761 %19670 %12129 + %17369 = OpINotEqual %bool %9130 %uint_0 + OpSelectionMerge %21263 DontFlatten + OpBranchConditional %17369 %21031 %22395 + %22395 = OpLabel + OpSelectionMerge %23460 None + OpSwitch %8576 %24626 0 %16005 1 %16005 2 %14402 10 %14402 3 %22975 12 %22975 4 %21190 6 %8243 + %8243 = OpLabel + %24406 = OpCompositeExtract %uint %14570 0 + %24679 = OpExtInst %v2float %1 UnpackHalf2x16 %24406 + %8852 = OpCompositeExtract %float %24679 0 + %7599 = OpCompositeExtract %uint %14570 1 + %15605 = OpExtInst %v2float %1 UnpackHalf2x16 %7599 + %8853 = OpCompositeExtract %float %15605 0 + %7600 = OpCompositeExtract %uint %14570 2 + %15606 = OpExtInst %v2float %1 UnpackHalf2x16 %7600 + %8854 = OpCompositeExtract %float %15606 0 + %7601 = OpCompositeExtract %uint %14570 3 + %15586 = OpExtInst %v2float %1 UnpackHalf2x16 %7601 + %10274 = OpCompositeExtract %float %15586 0 + %24249 = OpCompositeConstruct %v4float %8852 %8853 %8854 %10274 + %17274 = OpCompositeExtract %uint %9769 0 + %18027 = OpExtInst %v2float %1 UnpackHalf2x16 %17274 + %8855 = OpCompositeExtract %float %18027 0 + %7602 = OpCompositeExtract %uint %9769 1 + %15607 = OpExtInst %v2float %1 UnpackHalf2x16 %7602 + %8856 = OpCompositeExtract %float %15607 0 + %7603 = OpCompositeExtract %uint %9769 2 + %15608 = OpExtInst %v2float %1 UnpackHalf2x16 %7603 + %8857 = OpCompositeExtract %float %15608 0 + %7604 = OpCompositeExtract %uint %9769 3 + %15587 = OpExtInst %v2float %1 UnpackHalf2x16 %7604 + %13466 = OpCompositeExtract %float %15587 0 + %18678 = OpCompositeConstruct %v4float %8855 %8856 %8857 %13466 + OpBranch %23460 + %21190 = OpLabel + %24820 = OpBitcast %v4int %14570 + %22558 = OpShiftLeftLogical %v4int %24820 %770 + %16536 = OpShiftRightArithmetic %v4int %22558 %770 + %10903 = OpConvertSToF %v4float %16536 + %19064 = OpVectorTimesScalar %v4float %10903 %float_0_000976592302 + %18816 = OpExtInst %v4float %1 FMax %1284 %19064 + %10213 = OpBitcast %v4int %9769 + %8609 = OpShiftLeftLogical %v4int %10213 %770 + %16537 = OpShiftRightArithmetic %v4int %8609 %770 + %10904 = OpConvertSToF %v4float %16537 + %21439 = OpVectorTimesScalar %v4float %10904 %float_0_000976592302 + %17250 = OpExtInst %v4float %1 FMax %1284 %21439 + OpBranch %23460 + %22975 = OpLabel + %19462 = OpSelect %uint %7513 %uint_20 %uint_0 + %9136 = OpCompositeConstruct %v4uint %19462 %19462 %19462 %19462 + %23880 = OpShiftRightLogical %v4uint %14570 %9136 + %24038 = OpBitwiseAnd %v4uint %23880 %929 + %18588 = OpBitwiseAnd %v4uint %24038 %721 + %23440 = OpShiftRightLogical %v4uint %24038 %263 + %16585 = OpIEqual %v4bool %23440 %2896 + %11339 = OpExtInst %v4int %1 FindUMsb %18588 + %10773 = OpBitcast %v4uint %11339 + %6266 = OpISub %v4uint %263 %10773 + %8720 = OpIAdd %v4uint %10773 %2575 + %10351 = OpSelect %v4uint %16585 %8720 %23440 + %23252 = OpShiftLeftLogical %v4uint %18588 %6266 + %18842 = OpBitwiseAnd %v4uint %23252 %721 + %10909 = OpSelect %v4uint %16585 %18842 %18588 + %24569 = OpIAdd %v4uint %10351 %559 + %20351 = OpShiftLeftLogical %v4uint %24569 %1127 + %16294 = OpShiftLeftLogical %v4uint %10909 %749 + %22396 = OpBitwiseOr %v4uint %20351 %16294 + %13824 = OpIEqual %v4bool %24038 %2896 + %16962 = OpSelect %v4uint %13824 %2896 %22396 + %12356 = OpBitcast %v4float %16962 + %24638 = OpShiftRightLogical %v4uint %9769 %9136 + %14625 = OpBitwiseAnd %v4uint %24638 %929 + %18589 = OpBitwiseAnd %v4uint %14625 %721 + %23441 = OpShiftRightLogical %v4uint %14625 %263 + %16586 = OpIEqual %v4bool %23441 %2896 + %11340 = OpExtInst %v4int %1 FindUMsb %18589 + %10774 = OpBitcast %v4uint %11340 + %6267 = OpISub %v4uint %263 %10774 + %8721 = OpIAdd %v4uint %10774 %2575 + %10352 = OpSelect %v4uint %16586 %8721 %23441 + %23253 = OpShiftLeftLogical %v4uint %18589 %6267 + %18843 = OpBitwiseAnd %v4uint %23253 %721 + %10910 = OpSelect %v4uint %16586 %18843 %18589 + %24570 = OpIAdd %v4uint %10352 %559 + %20352 = OpShiftLeftLogical %v4uint %24570 %1127 + %16295 = OpShiftLeftLogical %v4uint %10910 %749 + %22397 = OpBitwiseOr %v4uint %20352 %16295 + %13825 = OpIEqual %v4bool %14625 %2896 + %18007 = OpSelect %v4uint %13825 %2896 %22397 + %22843 = OpBitcast %v4float %18007 + OpBranch %23460 + %14402 = OpLabel + %19463 = OpSelect %uint %7513 %uint_20 %uint_0 + %9137 = OpCompositeConstruct %v4uint %19463 %19463 %19463 %19463 + %22227 = OpShiftRightLogical %v4uint %14570 %9137 + %19030 = OpBitwiseAnd %v4uint %22227 %929 + %16133 = OpConvertUToF %v4float %19030 + %21018 = OpVectorTimesScalar %v4float %16133 %float_0_000977517106 + %7746 = OpShiftRightLogical %v4uint %9769 %9137 + %11220 = OpBitwiseAnd %v4uint %7746 %929 + %17178 = OpConvertUToF %v4float %11220 + %12434 = OpVectorTimesScalar %v4float %17178 %float_0_000977517106 + OpBranch %23460 + %16005 = OpLabel + %19464 = OpSelect %uint %7513 %uint_16 %uint_0 + %9138 = OpCompositeConstruct %v4uint %19464 %19464 %19464 %19464 + %22228 = OpShiftRightLogical %v4uint %14570 %9138 + %19031 = OpBitwiseAnd %v4uint %22228 %1611 + %16134 = OpConvertUToF %v4float %19031 + %21019 = OpVectorTimesScalar %v4float %16134 %float_0_00392156886 + %7747 = OpShiftRightLogical %v4uint %9769 %9138 + %11221 = OpBitwiseAnd %v4uint %7747 %1611 + %17179 = OpConvertUToF %v4float %11221 + %12435 = OpVectorTimesScalar %v4float %17179 %float_0_00392156886 + OpBranch %23460 + %24626 = OpLabel + %19231 = OpBitcast %v4float %14570 + %14514 = OpBitcast %v4float %9769 + OpBranch %23460 + %23460 = OpLabel + %11251 = OpPhi %v4float %14514 %24626 %12435 %16005 %12434 %14402 %22843 %22975 %17250 %21190 %18678 %8243 + %13709 = OpPhi %v4float %19231 %24626 %21019 %16005 %21018 %14402 %12356 %22975 %18816 %21190 %24249 %8243 + OpBranch %21263 + %21031 = OpLabel + OpSelectionMerge %23461 None + OpSwitch %8576 %12525 5 %21191 7 %8244 + %8244 = OpLabel + %24407 = OpCompositeExtract %uint %14570 0 + %24680 = OpExtInst %v2float %1 UnpackHalf2x16 %24407 + %8859 = OpCompositeExtract %float %24680 0 + %7605 = OpCompositeExtract %uint %14570 1 + %15609 = OpExtInst %v2float %1 UnpackHalf2x16 %7605 + %8860 = OpCompositeExtract %float %15609 0 + %7606 = OpCompositeExtract %uint %14570 2 + %15610 = OpExtInst %v2float %1 UnpackHalf2x16 %7606 + %8861 = OpCompositeExtract %float %15610 0 + %7607 = OpCompositeExtract %uint %14570 3 + %15588 = OpExtInst %v2float %1 UnpackHalf2x16 %7607 + %10275 = OpCompositeExtract %float %15588 0 + %24250 = OpCompositeConstruct %v4float %8859 %8860 %8861 %10275 + %17275 = OpCompositeExtract %uint %9769 0 + %18028 = OpExtInst %v2float %1 UnpackHalf2x16 %17275 + %8862 = OpCompositeExtract %float %18028 0 + %7608 = OpCompositeExtract %uint %9769 1 + %15611 = OpExtInst %v2float %1 UnpackHalf2x16 %7608 + %8863 = OpCompositeExtract %float %15611 0 + %7609 = OpCompositeExtract %uint %9769 2 + %15612 = OpExtInst %v2float %1 UnpackHalf2x16 %7609 + %8864 = OpCompositeExtract %float %15612 0 + %7610 = OpCompositeExtract %uint %9769 3 + %15589 = OpExtInst %v2float %1 UnpackHalf2x16 %7610 + %13467 = OpCompositeExtract %float %15589 0 + %18679 = OpCompositeConstruct %v4float %8862 %8863 %8864 %13467 + OpBranch %23461 + %21191 = OpLabel + %24821 = OpBitcast %v4int %14570 + %22559 = OpShiftLeftLogical %v4int %24821 %770 + %16538 = OpShiftRightArithmetic %v4int %22559 %770 + %10905 = OpConvertSToF %v4float %16538 + %19065 = OpVectorTimesScalar %v4float %10905 %float_0_000976592302 + %18817 = OpExtInst %v4float %1 FMax %1284 %19065 + %10214 = OpBitcast %v4int %9769 + %8610 = OpShiftLeftLogical %v4int %10214 %770 + %16539 = OpShiftRightArithmetic %v4int %8610 %770 + %10906 = OpConvertSToF %v4float %16539 + %21440 = OpVectorTimesScalar %v4float %10906 %float_0_000976592302 + %17251 = OpExtInst %v4float %1 FMax %1284 %21440 + OpBranch %23461 + %12525 = OpLabel + %19232 = OpBitcast %v4float %14570 + %14515 = OpBitcast %v4float %9769 + OpBranch %23461 + %23461 = OpLabel + %11252 = OpPhi %v4float %14515 %12525 %17251 %21191 %18679 %8244 + %13710 = OpPhi %v4float %19232 %12525 %18817 %21191 %24250 %8244 + OpBranch %21263 + %21263 = OpLabel + %9826 = OpPhi %v4float %11252 %23461 %11251 %23460 + %14051 = OpPhi %v4float %13710 %23461 %13709 %23460 + %11861 = OpUGreaterThanEqual %bool %16204 %uint_4 + OpSelectionMerge %21267 DontFlatten + OpBranchConditional %11861 %20977 %21267 + %20977 = OpLabel + %11079 = OpIMul %uint %uint_80 %8858 + %23069 = OpFMul %float %11052 %float_0_5 + %8114 = OpIAdd %uint %24188 %11079 + OpSelectionMerge %20260 DontFlatten + OpBranchConditional %24753 %9762 %12130 + %12130 = OpLabel + %19408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8114 + %23877 = OpLoad %uint %19408 + %11694 = OpIAdd %uint %8114 %12535 + %6476 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11694 + %24160 = OpLoad %uint %6476 + %6239 = OpIMul %uint %uint_2 %12535 + %8358 = OpIAdd %uint %8114 %6239 + %15313 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8358 + %24161 = OpLoad %uint %15313 + %6240 = OpIMul %uint %uint_3 %12535 + %8359 = OpIAdd %uint %8114 %6240 + %14323 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8359 + %14157 = OpLoad %uint %14323 + %19671 = OpCompositeConstruct %v4uint %23877 %24160 %24161 %14157 + %17049 = OpIMul %uint %uint_4 %12535 + %13992 = OpIAdd %uint %8114 %17049 + %15314 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13992 + %24162 = OpLoad %uint %15314 + %6241 = OpIMul %uint %uint_5 %12535 + %8360 = OpIAdd %uint %8114 %6241 + %15315 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8360 + %24163 = OpLoad %uint %15315 + %6242 = OpIMul %uint %uint_6 %12535 + %8361 = OpIAdd %uint %8114 %6242 + %15316 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8361 + %24164 = OpLoad %uint %15316 + %6243 = OpIMul %uint %uint_7 %12535 + %8362 = OpIAdd %uint %8114 %6243 + %14324 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8362 + %16382 = OpLoad %uint %14324 + %20782 = OpCompositeConstruct %v4uint %24162 %24163 %24164 %16382 + OpBranch %20260 + %9762 = OpLabel + %21830 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8114 + %23878 = OpLoad %uint %21830 + %11695 = OpIAdd %uint %8114 %uint_1 + %6403 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11695 + %23655 = OpLoad %uint %6403 + %11696 = OpIAdd %uint %8114 %uint_2 + %6404 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11696 + %23656 = OpLoad %uint %6404 + %11697 = OpIAdd %uint %8114 %uint_3 + %24560 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11697 + %14081 = OpLoad %uint %24560 + %19166 = OpCompositeConstruct %v4uint %23878 %23655 %23656 %14081 + %22502 = OpIAdd %uint %8114 %uint_4 + %24652 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22502 + %23657 = OpLoad %uint %24652 + %11698 = OpIAdd %uint %8114 %uint_5 + %6405 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11698 + %23658 = OpLoad %uint %6405 + %11699 = OpIAdd %uint %8114 %uint_6 + %6406 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11699 + %23659 = OpLoad %uint %6406 + %11700 = OpIAdd %uint %8114 %uint_7 + %24561 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11700 + %16383 = OpLoad %uint %24561 + %20783 = OpCompositeConstruct %v4uint %23657 %23658 %23659 %16383 + OpBranch %20260 + %20260 = OpLabel + %11213 = OpPhi %v4uint %20783 %9762 %20782 %12130 + %14093 = OpPhi %v4uint %19166 %9762 %19671 %12130 + OpSelectionMerge %21264 DontFlatten + OpBranchConditional %17369 %21032 %22398 + %22398 = OpLabel + OpSelectionMerge %23462 None + OpSwitch %8576 %24627 0 %16006 1 %16006 2 %14403 10 %14403 3 %22976 12 %22976 4 %21192 6 %8245 + %8245 = OpLabel + %24408 = OpCompositeExtract %uint %14093 0 + %24681 = OpExtInst %v2float %1 UnpackHalf2x16 %24408 + %8865 = OpCompositeExtract %float %24681 0 + %7611 = OpCompositeExtract %uint %14093 1 + %15613 = OpExtInst %v2float %1 UnpackHalf2x16 %7611 + %8866 = OpCompositeExtract %float %15613 0 + %7612 = OpCompositeExtract %uint %14093 2 + %15614 = OpExtInst %v2float %1 UnpackHalf2x16 %7612 + %8867 = OpCompositeExtract %float %15614 0 + %7613 = OpCompositeExtract %uint %14093 3 + %15590 = OpExtInst %v2float %1 UnpackHalf2x16 %7613 + %10276 = OpCompositeExtract %float %15590 0 + %24251 = OpCompositeConstruct %v4float %8865 %8866 %8867 %10276 + %17276 = OpCompositeExtract %uint %11213 0 + %18029 = OpExtInst %v2float %1 UnpackHalf2x16 %17276 + %8868 = OpCompositeExtract %float %18029 0 + %7614 = OpCompositeExtract %uint %11213 1 + %15615 = OpExtInst %v2float %1 UnpackHalf2x16 %7614 + %8869 = OpCompositeExtract %float %15615 0 + %7615 = OpCompositeExtract %uint %11213 2 + %15616 = OpExtInst %v2float %1 UnpackHalf2x16 %7615 + %8870 = OpCompositeExtract %float %15616 0 + %7616 = OpCompositeExtract %uint %11213 3 + %15591 = OpExtInst %v2float %1 UnpackHalf2x16 %7616 + %13468 = OpCompositeExtract %float %15591 0 + %18680 = OpCompositeConstruct %v4float %8868 %8869 %8870 %13468 + OpBranch %23462 + %21192 = OpLabel + %24822 = OpBitcast %v4int %14093 + %22560 = OpShiftLeftLogical %v4int %24822 %770 + %16540 = OpShiftRightArithmetic %v4int %22560 %770 + %10907 = OpConvertSToF %v4float %16540 + %19066 = OpVectorTimesScalar %v4float %10907 %float_0_000976592302 + %18818 = OpExtInst %v4float %1 FMax %1284 %19066 + %10215 = OpBitcast %v4int %11213 + %8611 = OpShiftLeftLogical %v4int %10215 %770 + %16541 = OpShiftRightArithmetic %v4int %8611 %770 + %10908 = OpConvertSToF %v4float %16541 + %21441 = OpVectorTimesScalar %v4float %10908 %float_0_000976592302 + %17252 = OpExtInst %v4float %1 FMax %1284 %21441 + OpBranch %23462 + %22976 = OpLabel + %19465 = OpSelect %uint %7513 %uint_20 %uint_0 + %9139 = OpCompositeConstruct %v4uint %19465 %19465 %19465 %19465 + %23881 = OpShiftRightLogical %v4uint %14093 %9139 + %24039 = OpBitwiseAnd %v4uint %23881 %929 + %18590 = OpBitwiseAnd %v4uint %24039 %721 + %23442 = OpShiftRightLogical %v4uint %24039 %263 + %16587 = OpIEqual %v4bool %23442 %2896 + %11341 = OpExtInst %v4int %1 FindUMsb %18590 + %10775 = OpBitcast %v4uint %11341 + %6268 = OpISub %v4uint %263 %10775 + %8722 = OpIAdd %v4uint %10775 %2575 + %10353 = OpSelect %v4uint %16587 %8722 %23442 + %23254 = OpShiftLeftLogical %v4uint %18590 %6268 + %18844 = OpBitwiseAnd %v4uint %23254 %721 + %10911 = OpSelect %v4uint %16587 %18844 %18590 + %24571 = OpIAdd %v4uint %10353 %559 + %20353 = OpShiftLeftLogical %v4uint %24571 %1127 + %16296 = OpShiftLeftLogical %v4uint %10911 %749 + %22399 = OpBitwiseOr %v4uint %20353 %16296 + %13826 = OpIEqual %v4bool %24039 %2896 + %16963 = OpSelect %v4uint %13826 %2896 %22399 + %12357 = OpBitcast %v4float %16963 + %24639 = OpShiftRightLogical %v4uint %11213 %9139 + %14626 = OpBitwiseAnd %v4uint %24639 %929 + %18591 = OpBitwiseAnd %v4uint %14626 %721 + %23443 = OpShiftRightLogical %v4uint %14626 %263 + %16588 = OpIEqual %v4bool %23443 %2896 + %11342 = OpExtInst %v4int %1 FindUMsb %18591 + %10776 = OpBitcast %v4uint %11342 + %6269 = OpISub %v4uint %263 %10776 + %8723 = OpIAdd %v4uint %10776 %2575 + %10354 = OpSelect %v4uint %16588 %8723 %23443 + %23255 = OpShiftLeftLogical %v4uint %18591 %6269 + %18845 = OpBitwiseAnd %v4uint %23255 %721 + %10912 = OpSelect %v4uint %16588 %18845 %18591 + %24572 = OpIAdd %v4uint %10354 %559 + %20354 = OpShiftLeftLogical %v4uint %24572 %1127 + %16297 = OpShiftLeftLogical %v4uint %10912 %749 + %22400 = OpBitwiseOr %v4uint %20354 %16297 + %13827 = OpIEqual %v4bool %14626 %2896 + %18008 = OpSelect %v4uint %13827 %2896 %22400 + %22844 = OpBitcast %v4float %18008 + OpBranch %23462 + %14403 = OpLabel + %19466 = OpSelect %uint %7513 %uint_20 %uint_0 + %9140 = OpCompositeConstruct %v4uint %19466 %19466 %19466 %19466 + %22229 = OpShiftRightLogical %v4uint %14093 %9140 + %19032 = OpBitwiseAnd %v4uint %22229 %929 + %16135 = OpConvertUToF %v4float %19032 + %21020 = OpVectorTimesScalar %v4float %16135 %float_0_000977517106 + %7748 = OpShiftRightLogical %v4uint %11213 %9140 + %11222 = OpBitwiseAnd %v4uint %7748 %929 + %17180 = OpConvertUToF %v4float %11222 + %12436 = OpVectorTimesScalar %v4float %17180 %float_0_000977517106 + OpBranch %23462 + %16006 = OpLabel + %19467 = OpSelect %uint %7513 %uint_16 %uint_0 + %9141 = OpCompositeConstruct %v4uint %19467 %19467 %19467 %19467 + %22230 = OpShiftRightLogical %v4uint %14093 %9141 + %19033 = OpBitwiseAnd %v4uint %22230 %1611 + %16136 = OpConvertUToF %v4float %19033 + %21021 = OpVectorTimesScalar %v4float %16136 %float_0_00392156886 + %7749 = OpShiftRightLogical %v4uint %11213 %9141 + %11223 = OpBitwiseAnd %v4uint %7749 %1611 + %17181 = OpConvertUToF %v4float %11223 + %12437 = OpVectorTimesScalar %v4float %17181 %float_0_00392156886 + OpBranch %23462 + %24627 = OpLabel + %19233 = OpBitcast %v4float %14093 + %14516 = OpBitcast %v4float %11213 + OpBranch %23462 + %23462 = OpLabel + %11253 = OpPhi %v4float %14516 %24627 %12437 %16006 %12436 %14403 %22844 %22976 %17252 %21192 %18680 %8245 + %13712 = OpPhi %v4float %19233 %24627 %21021 %16006 %21020 %14403 %12357 %22976 %18818 %21192 %24251 %8245 + OpBranch %21264 + %21032 = OpLabel + OpSelectionMerge %23463 None + OpSwitch %8576 %12526 5 %21193 7 %8246 + %8246 = OpLabel + %24409 = OpCompositeExtract %uint %14093 0 + %24682 = OpExtInst %v2float %1 UnpackHalf2x16 %24409 + %8872 = OpCompositeExtract %float %24682 0 + %7617 = OpCompositeExtract %uint %14093 1 + %15617 = OpExtInst %v2float %1 UnpackHalf2x16 %7617 + %8873 = OpCompositeExtract %float %15617 0 + %7618 = OpCompositeExtract %uint %14093 2 + %15618 = OpExtInst %v2float %1 UnpackHalf2x16 %7618 + %8874 = OpCompositeExtract %float %15618 0 + %7619 = OpCompositeExtract %uint %14093 3 + %15592 = OpExtInst %v2float %1 UnpackHalf2x16 %7619 + %10277 = OpCompositeExtract %float %15592 0 + %24252 = OpCompositeConstruct %v4float %8872 %8873 %8874 %10277 + %17277 = OpCompositeExtract %uint %11213 0 + %18030 = OpExtInst %v2float %1 UnpackHalf2x16 %17277 + %8875 = OpCompositeExtract %float %18030 0 + %7620 = OpCompositeExtract %uint %11213 1 + %15619 = OpExtInst %v2float %1 UnpackHalf2x16 %7620 + %8876 = OpCompositeExtract %float %15619 0 + %7621 = OpCompositeExtract %uint %11213 2 + %15620 = OpExtInst %v2float %1 UnpackHalf2x16 %7621 + %8877 = OpCompositeExtract %float %15620 0 + %7622 = OpCompositeExtract %uint %11213 3 + %15593 = OpExtInst %v2float %1 UnpackHalf2x16 %7622 + %13469 = OpCompositeExtract %float %15593 0 + %18681 = OpCompositeConstruct %v4float %8875 %8876 %8877 %13469 + OpBranch %23463 + %21193 = OpLabel + %24823 = OpBitcast %v4int %14093 + %22561 = OpShiftLeftLogical %v4int %24823 %770 + %16542 = OpShiftRightArithmetic %v4int %22561 %770 + %10913 = OpConvertSToF %v4float %16542 + %19067 = OpVectorTimesScalar %v4float %10913 %float_0_000976592302 + %18819 = OpExtInst %v4float %1 FMax %1284 %19067 + %10216 = OpBitcast %v4int %11213 + %8612 = OpShiftLeftLogical %v4int %10216 %770 + %16543 = OpShiftRightArithmetic %v4int %8612 %770 + %10914 = OpConvertSToF %v4float %16543 + %21442 = OpVectorTimesScalar %v4float %10914 %float_0_000976592302 + %17253 = OpExtInst %v4float %1 FMax %1284 %21442 + OpBranch %23463 + %12526 = OpLabel + %19234 = OpBitcast %v4float %14093 + %14517 = OpBitcast %v4float %11213 + OpBranch %23463 + %23463 = OpLabel + %11254 = OpPhi %v4float %14517 %12526 %17253 %21193 %18681 %8246 + %13713 = OpPhi %v4float %19234 %12526 %18819 %21193 %24252 %8246 + OpBranch %21264 + %21264 = OpLabel + %8971 = OpPhi %v4float %11254 %23463 %11253 %23462 + %19594 = OpPhi %v4float %13713 %23463 %13712 %23462 + %18096 = OpFAdd %v4float %14051 %19594 + %17754 = OpFAdd %v4float %9826 %8971 + %14461 = OpUGreaterThanEqual %bool %16204 %uint_6 + OpSelectionMerge %24264 DontFlatten + OpBranchConditional %14461 %9905 %24264 + %9905 = OpLabel + %14258 = OpShiftLeftLogical %uint %uint_1 %9130 + %12090 = OpFMul %float %11052 %float_0_25 + %20988 = OpIAdd %uint %24188 %14258 + OpSelectionMerge %20261 DontFlatten + OpBranchConditional %24753 %9763 %12131 + %12131 = OpLabel + %19409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23879 = OpLoad %uint %19409 + %11701 = OpIAdd %uint %20988 %12535 + %6477 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11701 + %24165 = OpLoad %uint %6477 + %6244 = OpIMul %uint %uint_2 %12535 + %8363 = OpIAdd %uint %20988 %6244 + %15317 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8363 + %24166 = OpLoad %uint %15317 + %6245 = OpIMul %uint %uint_3 %12535 + %8364 = OpIAdd %uint %20988 %6245 + %14325 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8364 + %14158 = OpLoad %uint %14325 + %19672 = OpCompositeConstruct %v4uint %23879 %24165 %24166 %14158 + %17050 = OpIMul %uint %uint_4 %12535 + %13993 = OpIAdd %uint %20988 %17050 + %15318 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13993 + %24167 = OpLoad %uint %15318 + %6246 = OpIMul %uint %uint_5 %12535 + %8365 = OpIAdd %uint %20988 %6246 + %15319 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8365 + %24168 = OpLoad %uint %15319 + %6247 = OpIMul %uint %uint_6 %12535 + %8366 = OpIAdd %uint %20988 %6247 + %15320 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8366 + %24169 = OpLoad %uint %15320 + %6248 = OpIMul %uint %uint_7 %12535 + %8367 = OpIAdd %uint %20988 %6248 + %14326 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8367 + %16384 = OpLoad %uint %14326 + %20784 = OpCompositeConstruct %v4uint %24167 %24168 %24169 %16384 + OpBranch %20261 + %9763 = OpLabel + %21831 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %20988 + %23882 = OpLoad %uint %21831 + %11702 = OpIAdd %uint %20988 %uint_1 + %6407 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11702 + %23660 = OpLoad %uint %6407 + %11703 = OpIAdd %uint %20988 %uint_2 + %6408 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11703 + %23661 = OpLoad %uint %6408 + %11704 = OpIAdd %uint %20988 %uint_3 + %24562 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11704 + %14082 = OpLoad %uint %24562 + %19167 = OpCompositeConstruct %v4uint %23882 %23660 %23661 %14082 + %22503 = OpIAdd %uint %20988 %uint_4 + %24653 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22503 + %23662 = OpLoad %uint %24653 + %11705 = OpIAdd %uint %20988 %uint_5 + %6409 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11705 + %23663 = OpLoad %uint %6409 + %11706 = OpIAdd %uint %20988 %uint_6 + %6410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11706 + %23664 = OpLoad %uint %6410 + %11707 = OpIAdd %uint %20988 %uint_7 + %24563 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11707 + %16385 = OpLoad %uint %24563 + %20785 = OpCompositeConstruct %v4uint %23662 %23663 %23664 %16385 + OpBranch %20261 + %20261 = OpLabel + %11214 = OpPhi %v4uint %20785 %9763 %20784 %12131 + %14094 = OpPhi %v4uint %19167 %9763 %19672 %12131 + OpSelectionMerge %21265 DontFlatten + OpBranchConditional %17369 %21033 %22401 + %22401 = OpLabel + OpSelectionMerge %23464 None + OpSwitch %8576 %24628 0 %16007 1 %16007 2 %14404 10 %14404 3 %22977 12 %22977 4 %21194 6 %8247 + %8247 = OpLabel + %24410 = OpCompositeExtract %uint %14094 0 + %24683 = OpExtInst %v2float %1 UnpackHalf2x16 %24410 + %8878 = OpCompositeExtract %float %24683 0 + %7623 = OpCompositeExtract %uint %14094 1 + %15621 = OpExtInst %v2float %1 UnpackHalf2x16 %7623 + %8879 = OpCompositeExtract %float %15621 0 + %7624 = OpCompositeExtract %uint %14094 2 + %15622 = OpExtInst %v2float %1 UnpackHalf2x16 %7624 + %8880 = OpCompositeExtract %float %15622 0 + %7625 = OpCompositeExtract %uint %14094 3 + %15594 = OpExtInst %v2float %1 UnpackHalf2x16 %7625 + %10278 = OpCompositeExtract %float %15594 0 + %24253 = OpCompositeConstruct %v4float %8878 %8879 %8880 %10278 + %17278 = OpCompositeExtract %uint %11214 0 + %18031 = OpExtInst %v2float %1 UnpackHalf2x16 %17278 + %8881 = OpCompositeExtract %float %18031 0 + %7626 = OpCompositeExtract %uint %11214 1 + %15623 = OpExtInst %v2float %1 UnpackHalf2x16 %7626 + %8882 = OpCompositeExtract %float %15623 0 + %7627 = OpCompositeExtract %uint %11214 2 + %15624 = OpExtInst %v2float %1 UnpackHalf2x16 %7627 + %8883 = OpCompositeExtract %float %15624 0 + %7628 = OpCompositeExtract %uint %11214 3 + %15595 = OpExtInst %v2float %1 UnpackHalf2x16 %7628 + %13470 = OpCompositeExtract %float %15595 0 + %18682 = OpCompositeConstruct %v4float %8881 %8882 %8883 %13470 + OpBranch %23464 + %21194 = OpLabel + %24824 = OpBitcast %v4int %14094 + %22562 = OpShiftLeftLogical %v4int %24824 %770 + %16544 = OpShiftRightArithmetic %v4int %22562 %770 + %10915 = OpConvertSToF %v4float %16544 + %19068 = OpVectorTimesScalar %v4float %10915 %float_0_000976592302 + %18820 = OpExtInst %v4float %1 FMax %1284 %19068 + %10217 = OpBitcast %v4int %11214 + %8613 = OpShiftLeftLogical %v4int %10217 %770 + %16545 = OpShiftRightArithmetic %v4int %8613 %770 + %10916 = OpConvertSToF %v4float %16545 + %21443 = OpVectorTimesScalar %v4float %10916 %float_0_000976592302 + %17254 = OpExtInst %v4float %1 FMax %1284 %21443 + OpBranch %23464 + %22977 = OpLabel + %19468 = OpSelect %uint %7513 %uint_20 %uint_0 + %9142 = OpCompositeConstruct %v4uint %19468 %19468 %19468 %19468 + %23883 = OpShiftRightLogical %v4uint %14094 %9142 + %24040 = OpBitwiseAnd %v4uint %23883 %929 + %18592 = OpBitwiseAnd %v4uint %24040 %721 + %23444 = OpShiftRightLogical %v4uint %24040 %263 + %16589 = OpIEqual %v4bool %23444 %2896 + %11343 = OpExtInst %v4int %1 FindUMsb %18592 + %10777 = OpBitcast %v4uint %11343 + %6270 = OpISub %v4uint %263 %10777 + %8724 = OpIAdd %v4uint %10777 %2575 + %10355 = OpSelect %v4uint %16589 %8724 %23444 + %23256 = OpShiftLeftLogical %v4uint %18592 %6270 + %18846 = OpBitwiseAnd %v4uint %23256 %721 + %10917 = OpSelect %v4uint %16589 %18846 %18592 + %24573 = OpIAdd %v4uint %10355 %559 + %20355 = OpShiftLeftLogical %v4uint %24573 %1127 + %16298 = OpShiftLeftLogical %v4uint %10917 %749 + %22402 = OpBitwiseOr %v4uint %20355 %16298 + %13828 = OpIEqual %v4bool %24040 %2896 + %16964 = OpSelect %v4uint %13828 %2896 %22402 + %12358 = OpBitcast %v4float %16964 + %24640 = OpShiftRightLogical %v4uint %11214 %9142 + %14627 = OpBitwiseAnd %v4uint %24640 %929 + %18593 = OpBitwiseAnd %v4uint %14627 %721 + %23445 = OpShiftRightLogical %v4uint %14627 %263 + %16590 = OpIEqual %v4bool %23445 %2896 + %11344 = OpExtInst %v4int %1 FindUMsb %18593 + %10778 = OpBitcast %v4uint %11344 + %6271 = OpISub %v4uint %263 %10778 + %8725 = OpIAdd %v4uint %10778 %2575 + %10356 = OpSelect %v4uint %16590 %8725 %23445 + %23257 = OpShiftLeftLogical %v4uint %18593 %6271 + %18847 = OpBitwiseAnd %v4uint %23257 %721 + %10918 = OpSelect %v4uint %16590 %18847 %18593 + %24574 = OpIAdd %v4uint %10356 %559 + %20356 = OpShiftLeftLogical %v4uint %24574 %1127 + %16299 = OpShiftLeftLogical %v4uint %10918 %749 + %22403 = OpBitwiseOr %v4uint %20356 %16299 + %13829 = OpIEqual %v4bool %14627 %2896 + %18009 = OpSelect %v4uint %13829 %2896 %22403 + %22845 = OpBitcast %v4float %18009 + OpBranch %23464 + %14404 = OpLabel + %19469 = OpSelect %uint %7513 %uint_20 %uint_0 + %9143 = OpCompositeConstruct %v4uint %19469 %19469 %19469 %19469 + %22231 = OpShiftRightLogical %v4uint %14094 %9143 + %19034 = OpBitwiseAnd %v4uint %22231 %929 + %16137 = OpConvertUToF %v4float %19034 + %21022 = OpVectorTimesScalar %v4float %16137 %float_0_000977517106 + %7750 = OpShiftRightLogical %v4uint %11214 %9143 + %11224 = OpBitwiseAnd %v4uint %7750 %929 + %17182 = OpConvertUToF %v4float %11224 + %12438 = OpVectorTimesScalar %v4float %17182 %float_0_000977517106 + OpBranch %23464 + %16007 = OpLabel + %19470 = OpSelect %uint %7513 %uint_16 %uint_0 + %9144 = OpCompositeConstruct %v4uint %19470 %19470 %19470 %19470 + %22232 = OpShiftRightLogical %v4uint %14094 %9144 + %19035 = OpBitwiseAnd %v4uint %22232 %1611 + %16138 = OpConvertUToF %v4float %19035 + %21023 = OpVectorTimesScalar %v4float %16138 %float_0_00392156886 + %7751 = OpShiftRightLogical %v4uint %11214 %9144 + %11225 = OpBitwiseAnd %v4uint %7751 %1611 + %17183 = OpConvertUToF %v4float %11225 + %12439 = OpVectorTimesScalar %v4float %17183 %float_0_00392156886 + OpBranch %23464 + %24628 = OpLabel + %19235 = OpBitcast %v4float %14094 + %14518 = OpBitcast %v4float %11214 + OpBranch %23464 + %23464 = OpLabel + %11255 = OpPhi %v4float %14518 %24628 %12439 %16007 %12438 %14404 %22845 %22977 %17254 %21194 %18682 %8247 + %13714 = OpPhi %v4float %19235 %24628 %21023 %16007 %21022 %14404 %12358 %22977 %18820 %21194 %24253 %8247 + OpBranch %21265 + %21033 = OpLabel + OpSelectionMerge %23465 None + OpSwitch %8576 %12527 5 %21195 7 %8248 + %8248 = OpLabel + %24411 = OpCompositeExtract %uint %14094 0 + %24684 = OpExtInst %v2float %1 UnpackHalf2x16 %24411 + %8884 = OpCompositeExtract %float %24684 0 + %7629 = OpCompositeExtract %uint %14094 1 + %15625 = OpExtInst %v2float %1 UnpackHalf2x16 %7629 + %8885 = OpCompositeExtract %float %15625 0 + %7630 = OpCompositeExtract %uint %14094 2 + %15626 = OpExtInst %v2float %1 UnpackHalf2x16 %7630 + %8886 = OpCompositeExtract %float %15626 0 + %7631 = OpCompositeExtract %uint %14094 3 + %15596 = OpExtInst %v2float %1 UnpackHalf2x16 %7631 + %10279 = OpCompositeExtract %float %15596 0 + %24254 = OpCompositeConstruct %v4float %8884 %8885 %8886 %10279 + %17279 = OpCompositeExtract %uint %11214 0 + %18032 = OpExtInst %v2float %1 UnpackHalf2x16 %17279 + %8887 = OpCompositeExtract %float %18032 0 + %7632 = OpCompositeExtract %uint %11214 1 + %15628 = OpExtInst %v2float %1 UnpackHalf2x16 %7632 + %8888 = OpCompositeExtract %float %15628 0 + %7633 = OpCompositeExtract %uint %11214 2 + %15629 = OpExtInst %v2float %1 UnpackHalf2x16 %7633 + %8889 = OpCompositeExtract %float %15629 0 + %7634 = OpCompositeExtract %uint %11214 3 + %15597 = OpExtInst %v2float %1 UnpackHalf2x16 %7634 + %13471 = OpCompositeExtract %float %15597 0 + %18683 = OpCompositeConstruct %v4float %8887 %8888 %8889 %13471 + OpBranch %23465 + %21195 = OpLabel + %24825 = OpBitcast %v4int %14094 + %22563 = OpShiftLeftLogical %v4int %24825 %770 + %16546 = OpShiftRightArithmetic %v4int %22563 %770 + %10919 = OpConvertSToF %v4float %16546 + %19069 = OpVectorTimesScalar %v4float %10919 %float_0_000976592302 + %18821 = OpExtInst %v4float %1 FMax %1284 %19069 + %10218 = OpBitcast %v4int %11214 + %8614 = OpShiftLeftLogical %v4int %10218 %770 + %16547 = OpShiftRightArithmetic %v4int %8614 %770 + %10920 = OpConvertSToF %v4float %16547 + %21444 = OpVectorTimesScalar %v4float %10920 %float_0_000976592302 + %17255 = OpExtInst %v4float %1 FMax %1284 %21444 + OpBranch %23465 + %12527 = OpLabel + %19236 = OpBitcast %v4float %14094 + %14519 = OpBitcast %v4float %11214 + OpBranch %23465 + %23465 = OpLabel + %11256 = OpPhi %v4float %14519 %12527 %17255 %21195 %18683 %8248 + %13715 = OpPhi %v4float %19236 %12527 %18821 %21195 %24254 %8248 + OpBranch %21265 + %21265 = OpLabel + %8972 = OpPhi %v4float %11256 %23465 %11255 %23464 + %19595 = OpPhi %v4float %13715 %23465 %13714 %23464 + %17222 = OpFAdd %v4float %18096 %19595 + %6641 = OpFAdd %v4float %17754 %8972 + %16376 = OpIAdd %uint %8114 %14258 + OpSelectionMerge %20262 DontFlatten + OpBranchConditional %24753 %9764 %12132 + %12132 = OpLabel + %19410 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23884 = OpLoad %uint %19410 + %11708 = OpIAdd %uint %16376 %12535 + %6478 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11708 + %24170 = OpLoad %uint %6478 + %6249 = OpIMul %uint %uint_2 %12535 + %8368 = OpIAdd %uint %16376 %6249 + %15321 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8368 + %24171 = OpLoad %uint %15321 + %6250 = OpIMul %uint %uint_3 %12535 + %8369 = OpIAdd %uint %16376 %6250 + %14327 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8369 + %14159 = OpLoad %uint %14327 + %19673 = OpCompositeConstruct %v4uint %23884 %24170 %24171 %14159 + %17051 = OpIMul %uint %uint_4 %12535 + %13994 = OpIAdd %uint %16376 %17051 + %15322 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %13994 + %24172 = OpLoad %uint %15322 + %6251 = OpIMul %uint %uint_5 %12535 + %8370 = OpIAdd %uint %16376 %6251 + %15323 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8370 + %24173 = OpLoad %uint %15323 + %6252 = OpIMul %uint %uint_6 %12535 + %8371 = OpIAdd %uint %16376 %6252 + %15324 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8371 + %24174 = OpLoad %uint %15324 + %6253 = OpIMul %uint %uint_7 %12535 + %8372 = OpIAdd %uint %16376 %6253 + %14328 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %8372 + %16386 = OpLoad %uint %14328 + %20786 = OpCompositeConstruct %v4uint %24172 %24173 %24174 %16386 + OpBranch %20262 + %9764 = OpLabel + %21832 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %16376 + %23885 = OpLoad %uint %21832 + %11709 = OpIAdd %uint %16376 %uint_1 + %6411 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11709 + %23665 = OpLoad %uint %6411 + %11710 = OpIAdd %uint %16376 %uint_2 + %6412 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11710 + %23666 = OpLoad %uint %6412 + %11711 = OpIAdd %uint %16376 %uint_3 + %24564 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11711 + %14083 = OpLoad %uint %24564 + %19168 = OpCompositeConstruct %v4uint %23885 %23665 %23666 %14083 + %22504 = OpIAdd %uint %16376 %uint_4 + %24654 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %22504 + %23667 = OpLoad %uint %24654 + %11712 = OpIAdd %uint %16376 %uint_5 + %6413 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11712 + %23668 = OpLoad %uint %6413 + %11713 = OpIAdd %uint %16376 %uint_6 + %6414 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11713 + %23669 = OpLoad %uint %6414 + %11714 = OpIAdd %uint %16376 %uint_7 + %24565 = OpAccessChain %_ptr_Uniform_uint %3271 %int_0 %11714 + %16387 = OpLoad %uint %24565 + %20787 = OpCompositeConstruct %v4uint %23667 %23668 %23669 %16387 + OpBranch %20262 + %20262 = OpLabel + %11215 = OpPhi %v4uint %20787 %9764 %20786 %12132 + %14095 = OpPhi %v4uint %19168 %9764 %19673 %12132 + OpSelectionMerge %21266 DontFlatten + OpBranchConditional %17369 %21034 %22404 + %22404 = OpLabel + OpSelectionMerge %23466 None + OpSwitch %8576 %24629 0 %16008 1 %16008 2 %14405 10 %14405 3 %22978 12 %22978 4 %21196 6 %8249 + %8249 = OpLabel + %24412 = OpCompositeExtract %uint %14095 0 + %24685 = OpExtInst %v2float %1 UnpackHalf2x16 %24412 + %8890 = OpCompositeExtract %float %24685 0 + %7635 = OpCompositeExtract %uint %14095 1 + %15630 = OpExtInst %v2float %1 UnpackHalf2x16 %7635 + %8891 = OpCompositeExtract %float %15630 0 + %7636 = OpCompositeExtract %uint %14095 2 + %15631 = OpExtInst %v2float %1 UnpackHalf2x16 %7636 + %8892 = OpCompositeExtract %float %15631 0 + %7637 = OpCompositeExtract %uint %14095 3 + %15598 = OpExtInst %v2float %1 UnpackHalf2x16 %7637 + %10280 = OpCompositeExtract %float %15598 0 + %24255 = OpCompositeConstruct %v4float %8890 %8891 %8892 %10280 + %17280 = OpCompositeExtract %uint %11215 0 + %18033 = OpExtInst %v2float %1 UnpackHalf2x16 %17280 + %8893 = OpCompositeExtract %float %18033 0 + %7638 = OpCompositeExtract %uint %11215 1 + %15632 = OpExtInst %v2float %1 UnpackHalf2x16 %7638 + %8894 = OpCompositeExtract %float %15632 0 + %7639 = OpCompositeExtract %uint %11215 2 + %15633 = OpExtInst %v2float %1 UnpackHalf2x16 %7639 + %8895 = OpCompositeExtract %float %15633 0 + %7640 = OpCompositeExtract %uint %11215 3 + %15599 = OpExtInst %v2float %1 UnpackHalf2x16 %7640 + %13472 = OpCompositeExtract %float %15599 0 + %18684 = OpCompositeConstruct %v4float %8893 %8894 %8895 %13472 + OpBranch %23466 + %21196 = OpLabel + %24826 = OpBitcast %v4int %14095 + %22564 = OpShiftLeftLogical %v4int %24826 %770 + %16548 = OpShiftRightArithmetic %v4int %22564 %770 + %10921 = OpConvertSToF %v4float %16548 + %19070 = OpVectorTimesScalar %v4float %10921 %float_0_000976592302 + %18822 = OpExtInst %v4float %1 FMax %1284 %19070 + %10219 = OpBitcast %v4int %11215 + %8615 = OpShiftLeftLogical %v4int %10219 %770 + %16549 = OpShiftRightArithmetic %v4int %8615 %770 + %10922 = OpConvertSToF %v4float %16549 + %21445 = OpVectorTimesScalar %v4float %10922 %float_0_000976592302 + %17256 = OpExtInst %v4float %1 FMax %1284 %21445 + OpBranch %23466 + %22978 = OpLabel + %19471 = OpSelect %uint %7513 %uint_20 %uint_0 + %9145 = OpCompositeConstruct %v4uint %19471 %19471 %19471 %19471 + %23886 = OpShiftRightLogical %v4uint %14095 %9145 + %24041 = OpBitwiseAnd %v4uint %23886 %929 + %18594 = OpBitwiseAnd %v4uint %24041 %721 + %23446 = OpShiftRightLogical %v4uint %24041 %263 + %16591 = OpIEqual %v4bool %23446 %2896 + %11345 = OpExtInst %v4int %1 FindUMsb %18594 + %10779 = OpBitcast %v4uint %11345 + %6272 = OpISub %v4uint %263 %10779 + %8726 = OpIAdd %v4uint %10779 %2575 + %10357 = OpSelect %v4uint %16591 %8726 %23446 + %23258 = OpShiftLeftLogical %v4uint %18594 %6272 + %18848 = OpBitwiseAnd %v4uint %23258 %721 + %10923 = OpSelect %v4uint %16591 %18848 %18594 + %24575 = OpIAdd %v4uint %10357 %559 + %20357 = OpShiftLeftLogical %v4uint %24575 %1127 + %16300 = OpShiftLeftLogical %v4uint %10923 %749 + %22405 = OpBitwiseOr %v4uint %20357 %16300 + %13830 = OpIEqual %v4bool %24041 %2896 + %16965 = OpSelect %v4uint %13830 %2896 %22405 + %12359 = OpBitcast %v4float %16965 + %24641 = OpShiftRightLogical %v4uint %11215 %9145 + %14628 = OpBitwiseAnd %v4uint %24641 %929 + %18595 = OpBitwiseAnd %v4uint %14628 %721 + %23447 = OpShiftRightLogical %v4uint %14628 %263 + %16592 = OpIEqual %v4bool %23447 %2896 + %11346 = OpExtInst %v4int %1 FindUMsb %18595 + %10780 = OpBitcast %v4uint %11346 + %6273 = OpISub %v4uint %263 %10780 + %8727 = OpIAdd %v4uint %10780 %2575 + %10358 = OpSelect %v4uint %16592 %8727 %23447 + %23259 = OpShiftLeftLogical %v4uint %18595 %6273 + %18849 = OpBitwiseAnd %v4uint %23259 %721 + %10924 = OpSelect %v4uint %16592 %18849 %18595 + %24576 = OpIAdd %v4uint %10358 %559 + %20358 = OpShiftLeftLogical %v4uint %24576 %1127 + %16301 = OpShiftLeftLogical %v4uint %10924 %749 + %22406 = OpBitwiseOr %v4uint %20358 %16301 + %13831 = OpIEqual %v4bool %14628 %2896 + %18010 = OpSelect %v4uint %13831 %2896 %22406 + %22846 = OpBitcast %v4float %18010 + OpBranch %23466 + %14405 = OpLabel + %19472 = OpSelect %uint %7513 %uint_20 %uint_0 + %9146 = OpCompositeConstruct %v4uint %19472 %19472 %19472 %19472 + %22233 = OpShiftRightLogical %v4uint %14095 %9146 + %19036 = OpBitwiseAnd %v4uint %22233 %929 + %16139 = OpConvertUToF %v4float %19036 + %21024 = OpVectorTimesScalar %v4float %16139 %float_0_000977517106 + %7752 = OpShiftRightLogical %v4uint %11215 %9146 + %11226 = OpBitwiseAnd %v4uint %7752 %929 + %17184 = OpConvertUToF %v4float %11226 + %12440 = OpVectorTimesScalar %v4float %17184 %float_0_000977517106 + OpBranch %23466 + %16008 = OpLabel + %19473 = OpSelect %uint %7513 %uint_16 %uint_0 + %9147 = OpCompositeConstruct %v4uint %19473 %19473 %19473 %19473 + %22234 = OpShiftRightLogical %v4uint %14095 %9147 + %19037 = OpBitwiseAnd %v4uint %22234 %1611 + %16140 = OpConvertUToF %v4float %19037 + %21025 = OpVectorTimesScalar %v4float %16140 %float_0_00392156886 + %7753 = OpShiftRightLogical %v4uint %11215 %9147 + %11227 = OpBitwiseAnd %v4uint %7753 %1611 + %17185 = OpConvertUToF %v4float %11227 + %12441 = OpVectorTimesScalar %v4float %17185 %float_0_00392156886 + OpBranch %23466 + %24629 = OpLabel + %19237 = OpBitcast %v4float %14095 + %14520 = OpBitcast %v4float %11215 + OpBranch %23466 + %23466 = OpLabel + %11257 = OpPhi %v4float %14520 %24629 %12441 %16008 %12440 %14405 %22846 %22978 %17256 %21196 %18684 %8249 + %13716 = OpPhi %v4float %19237 %24629 %21025 %16008 %21024 %14405 %12359 %22978 %18822 %21196 %24255 %8249 + OpBranch %21266 + %21034 = OpLabel + OpSelectionMerge %23467 None + OpSwitch %8576 %12528 5 %21197 7 %8250 + %8250 = OpLabel + %24413 = OpCompositeExtract %uint %14095 0 + %24686 = OpExtInst %v2float %1 UnpackHalf2x16 %24413 + %8896 = OpCompositeExtract %float %24686 0 + %7641 = OpCompositeExtract %uint %14095 1 + %15634 = OpExtInst %v2float %1 UnpackHalf2x16 %7641 + %8897 = OpCompositeExtract %float %15634 0 + %7642 = OpCompositeExtract %uint %14095 2 + %15635 = OpExtInst %v2float %1 UnpackHalf2x16 %7642 + %8898 = OpCompositeExtract %float %15635 0 + %7643 = OpCompositeExtract %uint %14095 3 + %15600 = OpExtInst %v2float %1 UnpackHalf2x16 %7643 + %10281 = OpCompositeExtract %float %15600 0 + %24256 = OpCompositeConstruct %v4float %8896 %8897 %8898 %10281 + %17281 = OpCompositeExtract %uint %11215 0 + %18034 = OpExtInst %v2float %1 UnpackHalf2x16 %17281 + %8899 = OpCompositeExtract %float %18034 0 + %7644 = OpCompositeExtract %uint %11215 1 + %15636 = OpExtInst %v2float %1 UnpackHalf2x16 %7644 + %8900 = OpCompositeExtract %float %15636 0 + %7645 = OpCompositeExtract %uint %11215 2 + %15637 = OpExtInst %v2float %1 UnpackHalf2x16 %7645 + %8901 = OpCompositeExtract %float %15637 0 + %7646 = OpCompositeExtract %uint %11215 3 + %15601 = OpExtInst %v2float %1 UnpackHalf2x16 %7646 + %13473 = OpCompositeExtract %float %15601 0 + %18685 = OpCompositeConstruct %v4float %8899 %8900 %8901 %13473 + OpBranch %23467 + %21197 = OpLabel + %24827 = OpBitcast %v4int %14095 + %22565 = OpShiftLeftLogical %v4int %24827 %770 + %16550 = OpShiftRightArithmetic %v4int %22565 %770 + %10925 = OpConvertSToF %v4float %16550 + %19071 = OpVectorTimesScalar %v4float %10925 %float_0_000976592302 + %18823 = OpExtInst %v4float %1 FMax %1284 %19071 + %10220 = OpBitcast %v4int %11215 + %8616 = OpShiftLeftLogical %v4int %10220 %770 + %16551 = OpShiftRightArithmetic %v4int %8616 %770 + %10926 = OpConvertSToF %v4float %16551 + %21446 = OpVectorTimesScalar %v4float %10926 %float_0_000976592302 + %17257 = OpExtInst %v4float %1 FMax %1284 %21446 + OpBranch %23467 + %12528 = OpLabel + %19238 = OpBitcast %v4float %14095 + %14521 = OpBitcast %v4float %11215 + OpBranch %23467 + %23467 = OpLabel + %11258 = OpPhi %v4float %14521 %12528 %17257 %21197 %18685 %8250 + %13717 = OpPhi %v4float %19238 %12528 %18823 %21197 %24256 %8250 + OpBranch %21266 + %21266 = OpLabel + %8973 = OpPhi %v4float %11258 %23467 %11257 %23466 + %19596 = OpPhi %v4float %13717 %23467 %13716 %23466 + %19521 = OpFAdd %v4float %17222 %19596 + %23869 = OpFAdd %v4float %6641 %8973 + OpBranch %24264 + %24264 = OpLabel + %11175 = OpPhi %v4float %17754 %21264 %23869 %21266 + %14420 = OpPhi %v4float %18096 %21264 %19521 %21266 + %14522 = OpPhi %float %23069 %21264 %12090 %21266 + OpBranch %21267 + %21267 = OpLabel + %11176 = OpPhi %v4float %9826 %21263 %11175 %24264 + %12387 = OpPhi %v4float %14051 %21263 %14420 %24264 + %11944 = OpPhi %float %11052 %21263 %14522 %24264 + %23688 = OpVectorTimesScalar %v4float %12387 %11944 + %22826 = OpVectorTimesScalar %v4float %11176 %11944 + %12810 = OpIEqual %bool %6697 %uint_0 + OpSelectionMerge %13276 None + OpBranchConditional %12810 %11451 %13276 + %11451 = OpLabel + %24175 = OpCompositeExtract %uint %19124 0 + %22470 = OpINotEqual %bool %24175 %uint_0 + OpBranch %13276 + %13276 = OpLabel + %10927 = OpPhi %bool %12810 %21267 %22470 %11451 + OpSelectionMerge %19649 DontFlatten + OpBranchConditional %10927 %11508 %19649 + %11508 = OpLabel + %23599 = OpCompositeExtract %uint %19124 0 + %17346 = OpUGreaterThanEqual %bool %23599 %uint_2 + OpSelectionMerge %18757 None + OpBranchConditional %17346 %15877 %18757 + %15877 = OpLabel + %24532 = OpUGreaterThanEqual %bool %23599 %uint_3 + OpSelectionMerge %18756 None + OpBranchConditional %24532 %9760 %18756 + %9760 = OpLabel + %20482 = OpCompositeExtract %float %23688 3 + %14335 = OpCompositeInsert %v4float %20482 %23688 2 + OpBranch %18756 + %18756 = OpLabel + %17379 = OpPhi %v4float %23688 %15877 %14335 %9760 + %7002 = OpCompositeExtract %float %17379 2 + %15144 = OpCompositeInsert %v4float %7002 %17379 1 + OpBranch %18757 + %18757 = OpLabel + %17380 = OpPhi %v4float %23688 %11508 %15144 %18756 + %7003 = OpCompositeExtract %float %17380 1 + %15145 = OpCompositeInsert %v4float %7003 %17380 0 + OpBranch %19649 + %19649 = OpLabel + %9229 = OpPhi %v4float %23688 %13276 %15145 %18757 + %19403 = OpIAdd %v2uint %9840 %23020 + %13244 = OpCompositeExtract %uint %19403 0 + %9555 = OpCompositeExtract %uint %19403 1 + %11053 = OpShiftRightLogical %uint %13244 %uint_3 + %7832 = OpCompositeConstruct %v2uint %11053 %9555 + %24920 = OpUDiv %v2uint %7832 %23601 + %13932 = OpCompositeExtract %uint %24920 0 + %19770 = OpShiftLeftLogical %uint %13932 %uint_3 + %24257 = OpCompositeExtract %uint %24920 1 + %21452 = OpCompositeConstruct %v3uint %19770 %24257 %17416 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %22206 %10928 + %10928 = OpLabel + %7339 = OpVectorShuffle %v2uint %21452 %21452 0 1 + %22991 = OpBitcast %v2int %7339 + %6415 = OpCompositeExtract %int %22991 0 + %9469 = OpShiftRightArithmetic %int %6415 %int_5 + %10055 = OpCompositeExtract %int %22991 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %15783 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_7 + %10934 = OpBitwiseAnd %int %6415 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %16373 = OpShiftLeftLogical %int %12600 %int_2 + %10688 = OpIAdd %int %10934 %16373 + %11527 = OpBitcast %int %10688 + %16975 = OpBitwiseAnd %int %11527 %int_n16 + %24809 = OpShiftLeftLogical %int %16975 %int_1 + %15435 = OpIAdd %int %19086 %24809 + %13207 = OpBitwiseAnd %int %11527 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18356 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18356 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12150 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12150 + %19169 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19169 %int_2 + %16708 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6415 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21587 %int_6 + %15436 = OpIAdd %int %16708 %21580 + %11782 = OpBitwiseAnd %int %16727 %int_63 + %14671 = OpIAdd %int %15436 %11782 + %22127 = OpBitcast %uint %14671 + OpBranch %21313 + %22206 = OpLabel + %6573 = OpBitcast %v3int %21452 + %17090 = OpCompositeExtract %int %6573 1 + %9470 = OpShiftRightArithmetic %int %17090 %int_4 + %10056 = OpCompositeExtract %int %6573 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %25203 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %15783 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %6573 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_6 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12601 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_6 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8728 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8728 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19170 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19170 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18357 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18357 %uint_6 + %16729 = OpIAdd %int %10332 %21582 + %19171 = OpBitwiseAnd %int %17090 %int_1 + %21583 = OpShiftLeftLogical %int %19171 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10929 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10929 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10930 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10930 %int_3 + %21849 = OpBitwiseAnd %int %16730 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22128 = OpBitcast %uint %24314 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22128 %22206 %22127 %10928 + %16302 = OpIMul %v2uint %24920 %23601 + %16261 = OpISub %v2uint %7832 %16302 + %17551 = OpCompositeExtract %uint %23601 1 + %23632 = OpIMul %uint %8858 %17551 + %15520 = OpIMul %uint %9468 %23632 + %16084 = OpCompositeExtract %uint %16261 0 + %15890 = OpIMul %uint %16084 %17551 + %6887 = OpCompositeExtract %uint %16261 1 + %11045 = OpIAdd %uint %15890 %6887 + %24733 = OpShiftLeftLogical %uint %11045 %uint_3 + %21925 = OpBitwiseAnd %uint %13244 %uint_7 + %22577 = OpIAdd %uint %24733 %21925 + %13500 = OpIAdd %uint %15520 %22577 + %22973 = OpShiftRightLogical %uint %13500 %uint_3 + %24154 = OpExtInst %v4float %1 FClamp %9229 %2938 %1285 + %9073 = OpVectorTimesScalar %v4float %24154 %float_255 + %11878 = OpFAdd %v4float %9073 %325 + %7647 = OpConvertFToU %v4uint %11878 + %8700 = OpCompositeExtract %uint %7647 0 + %12251 = OpCompositeExtract %uint %7647 1 + %11561 = OpShiftLeftLogical %uint %12251 %int_8 + %19814 = OpBitwiseOr %uint %8700 %11561 + %21476 = OpCompositeExtract %uint %7647 2 + %8560 = OpShiftLeftLogical %uint %21476 %int_16 + %19815 = OpBitwiseOr %uint %19814 %8560 + %21477 = OpCompositeExtract %uint %7647 3 + %7292 = OpShiftLeftLogical %uint %21477 %int_24 + %9255 = OpBitwiseOr %uint %19815 %7292 + %7522 = OpExtInst %v4float %1 FClamp %22826 %2938 %1285 + %8264 = OpVectorTimesScalar %v4float %7522 %float_255 + %11879 = OpFAdd %v4float %8264 %325 + %7648 = OpConvertFToU %v4uint %11879 + %8701 = OpCompositeExtract %uint %7648 0 + %12252 = OpCompositeExtract %uint %7648 1 + %11562 = OpShiftLeftLogical %uint %12252 %int_8 + %19816 = OpBitwiseOr %uint %8701 %11562 + %21478 = OpCompositeExtract %uint %7648 2 + %8561 = OpShiftLeftLogical %uint %21478 %int_16 + %19817 = OpBitwiseOr %uint %19816 %8561 + %21479 = OpCompositeExtract %uint %7648 3 + %8541 = OpShiftLeftLogical %uint %21479 %int_24 + %17498 = OpBitwiseOr %uint %19817 %8541 + %11625 = OpCompositeConstruct %v2uint %9255 %17498 + %8978 = OpAccessChain %_ptr_Uniform_v2uint %5522 %int_0 %22973 + OpStore %8978 %11625 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t resolve_full_8bpp_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000062AE, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00040047, 0x000007D0, 0x00000006, 0x00000004, + 0x00030047, 0x0000079C, 0x00000003, 0x00040048, 0x0000079C, 0x00000000, 0x00000018, 0x00050048, + 0x0000079C, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000CC7, 0x00000018, 0x00040047, + 0x00000CC7, 0x00000021, 0x00000000, 0x00040047, 0x00000CC7, 0x00000022, 0x00000000, 0x00030047, + 0x000003F9, 0x00000002, 0x00050048, 0x000003F9, 0x00000000, 0x00000023, 0x00000000, 0x00050048, + 0x000003F9, 0x00000001, 0x00000023, 0x00000004, 0x00050048, 0x000003F9, 0x00000002, 0x00000023, + 0x00000008, 0x00050048, 0x000003F9, 0x00000003, 0x00000023, 0x0000000C, 0x00040047, 0x00000F48, + 0x0000000B, 0x0000001C, 0x00040047, 0x000007D6, 0x00000006, 0x00000008, 0x00030047, 0x000007A8, + 0x00000003, 0x00040048, 0x000007A8, 0x00000000, 0x00000019, 0x00050048, 0x000007A8, 0x00000000, + 0x00000023, 0x00000000, 0x00030047, 0x00001592, 0x00000019, 0x00040047, 0x00001592, 0x00000021, + 0x00000000, 0x00040047, 0x00001592, 0x00000022, 0x00000001, 0x00040047, 0x00000AC7, 0x0000000B, + 0x00000019, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000B, + 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, + 0x00000004, 0x00020014, 0x00000009, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, + 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00040017, + 0x00000014, 0x0000000B, 0x00000003, 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, 0x0004002B, + 0x0000000D, 0x0000008A, 0x3F800000, 0x00040017, 0x0000001A, 0x0000000C, 0x00000004, 0x0004002B, + 0x0000000D, 0x00000540, 0x437F0000, 0x0004002B, 0x0000000D, 0x000000FC, 0x3F000000, 0x0004002B, + 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, + 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, + 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, + 0x0000000C, 0x00000A53, 0x00000018, 0x0004002B, 0x0000000B, 0x00000144, 0x000000FF, 0x0004002B, + 0x0000000D, 0x0000017A, 0x3B808081, 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, 0x0004002B, + 0x0000000D, 0x000006FE, 0x3A802008, 0x0004002B, 0x0000000B, 0x00000B87, 0x0000007F, 0x0004002B, + 0x0000000B, 0x00000A1F, 0x00000007, 0x00040017, 0x00000013, 0x00000009, 0x00000004, 0x0004002B, + 0x0000000B, 0x00000B7E, 0x0000007C, 0x0004002B, 0x0000000B, 0x00000A4F, 0x00000017, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000D, 0x00000341, 0xBF800000, 0x0004002B, + 0x0000000D, 0x000007FE, 0x3A800100, 0x0005002C, 0x00000011, 0x0000072D, 0x00000A10, 0x00000A0D, + 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0005002C, 0x00000011, 0x0000070F, 0x00000A0A, + 0x00000A0A, 0x0005002C, 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, 0x0005002C, 0x00000011, + 0x00000718, 0x00000A0D, 0x00000A0A, 0x0004002B, 0x0000000B, 0x00000AFA, 0x00000050, 0x0005002C, + 0x00000011, 0x00000A9F, 0x00000AFA, 0x00000A3A, 0x0004002B, 0x0000000B, 0x00000A84, 0x00000800, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, + 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, + 0x0003001D, 0x000007D0, 0x0000000B, 0x0003001E, 0x0000079C, 0x000007D0, 0x00040020, 0x00000A1B, + 0x00000002, 0x0000079C, 0x0004003B, 0x00000A1B, 0x00000CC7, 0x00000002, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000002, 0x0000000B, 0x0006001E, 0x000003F9, + 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000676, 0x00000009, 0x000003F9, + 0x0004003B, 0x00000676, 0x00000CE9, 0x00000009, 0x00040020, 0x00000289, 0x00000009, 0x0000000B, + 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, + 0x0004002B, 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A52, 0x00000018, + 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, 0x0004002B, 0x0000000B, 0x00000A5E, 0x0000001C, + 0x0004002B, 0x0000000B, 0x00000A43, 0x00000013, 0x0005002C, 0x00000011, 0x00000883, 0x00000A3A, + 0x00000A43, 0x0004002B, 0x0000000B, 0x00000510, 0x20000000, 0x0005002C, 0x00000011, 0x0000073F, + 0x00000A0A, 0x00000A16, 0x0004002B, 0x0000000C, 0x00000A29, 0x0000000A, 0x0004002B, 0x0000000B, + 0x00000A22, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A59, 0x0000001A, 0x0004002B, 0x0000000C, + 0x00000A50, 0x00000017, 0x0004002B, 0x0000000B, 0x00000926, 0x01000000, 0x0004002B, 0x0000000B, + 0x00000A46, 0x00000014, 0x0005002C, 0x00000011, 0x000008E3, 0x00000A46, 0x00000A52, 0x00040017, + 0x00000015, 0x0000000D, 0x00000002, 0x00040020, 0x00000291, 0x00000001, 0x00000014, 0x0004003B, + 0x00000291, 0x00000F48, 0x00000001, 0x00040020, 0x0000028A, 0x00000001, 0x0000000B, 0x0005002C, + 0x00000011, 0x0000072A, 0x00000A13, 0x00000A0A, 0x0003001D, 0x000007D6, 0x00000011, 0x0003001E, + 0x000007A8, 0x000007D6, 0x00040020, 0x00000A25, 0x00000002, 0x000007A8, 0x0004003B, 0x00000A25, + 0x00001592, 0x00000002, 0x00040020, 0x0000028E, 0x00000002, 0x00000011, 0x0006002C, 0x00000014, + 0x00000AC7, 0x00000A22, 0x00000A22, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A1F, + 0x00000A1F, 0x0005002C, 0x00000011, 0x000007A3, 0x00000A37, 0x00000A0D, 0x0005002C, 0x00000011, + 0x0000074E, 0x00000A13, 0x00000A13, 0x0005002C, 0x00000011, 0x0000084A, 0x00000A37, 0x00000A37, + 0x0007002C, 0x0000001D, 0x00000504, 0x00000341, 0x00000341, 0x00000341, 0x00000341, 0x0007002C, + 0x0000001A, 0x00000302, 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x0007002C, 0x00000017, + 0x0000064B, 0x00000144, 0x00000144, 0x00000144, 0x00000144, 0x0007002C, 0x00000017, 0x000003A1, + 0x00000A44, 0x00000A44, 0x00000A44, 0x00000A44, 0x0007002C, 0x00000017, 0x000002D1, 0x00000B87, + 0x00000B87, 0x00000B87, 0x00000B87, 0x0007002C, 0x00000017, 0x00000107, 0x00000A1F, 0x00000A1F, + 0x00000A1F, 0x00000A1F, 0x0007002C, 0x00000017, 0x00000B50, 0x00000A0A, 0x00000A0A, 0x00000A0A, + 0x00000A0A, 0x0007002C, 0x00000017, 0x0000022F, 0x00000B7E, 0x00000B7E, 0x00000B7E, 0x00000B7E, + 0x0007002C, 0x00000017, 0x00000467, 0x00000A4F, 0x00000A4F, 0x00000A4F, 0x00000A4F, 0x0007002C, + 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0007002C, 0x0000001D, + 0x00000B7A, 0x00000A0C, 0x00000A0C, 0x00000A0C, 0x00000A0C, 0x0007002C, 0x0000001D, 0x00000505, + 0x0000008A, 0x0000008A, 0x0000008A, 0x0000008A, 0x0007002C, 0x0000001D, 0x00000145, 0x000000FC, + 0x000000FC, 0x000000FC, 0x000000FC, 0x0004002B, 0x0000000C, 0x00000089, 0x3F800000, 0x0004002B, + 0x0000000B, 0x000009F8, 0xFFFFFFFA, 0x0007002C, 0x00000017, 0x00000A0F, 0x000009F8, 0x000009F8, + 0x000009F8, 0x000009F8, 0x0004002B, 0x0000000D, 0x0000016E, 0x3E800000, 0x00050036, 0x00000008, + 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, + 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000289, 0x000056E5, + 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003D0B, 0x000056E5, 0x00050041, 0x00000289, + 0x000058AC, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005158, 0x000058AC, 0x000500C7, + 0x0000000B, 0x00005051, 0x00003D0B, 0x00000A44, 0x000500C2, 0x0000000B, 0x00004E0A, 0x00003D0B, + 0x00000A28, 0x000500C7, 0x0000000B, 0x0000217E, 0x00004E0A, 0x00000A13, 0x000500C2, 0x0000000B, + 0x0000520A, 0x00003D0B, 0x00000A31, 0x000500C7, 0x0000000B, 0x0000217F, 0x0000520A, 0x00000A81, + 0x000500C2, 0x0000000B, 0x0000520B, 0x00003D0B, 0x00000A52, 0x000500C7, 0x0000000B, 0x00002180, + 0x0000520B, 0x00000A37, 0x000500C2, 0x0000000B, 0x00004994, 0x00003D0B, 0x00000A5E, 0x000500C7, + 0x0000000B, 0x000023AA, 0x00004994, 0x00000A0D, 0x00050050, 0x00000011, 0x000022A7, 0x00005158, + 0x00005158, 0x000500C2, 0x00000011, 0x000025A1, 0x000022A7, 0x00000883, 0x000500C7, 0x00000011, + 0x00005C31, 0x000025A1, 0x000007A2, 0x000500C7, 0x0000000B, 0x00005DDE, 0x00003D0B, 0x00000510, + 0x000500AB, 0x00000009, 0x00003007, 0x00005DDE, 0x00000A0A, 0x000300F7, 0x00003954, 0x00000000, + 0x000400FA, 0x00003007, 0x00004163, 0x000055E8, 0x000200F8, 0x000055E8, 0x000200F9, 0x00003954, + 0x000200F8, 0x00004163, 0x000500C2, 0x00000011, 0x00003BAE, 0x00005C31, 0x00000724, 0x000200F9, + 0x00003954, 0x000200F8, 0x00003954, 0x000700F5, 0x00000011, 0x00004AB4, 0x00003BAE, 0x00004163, + 0x0000070F, 0x000055E8, 0x000500C2, 0x00000011, 0x00001B7E, 0x000022A7, 0x0000073F, 0x000500C7, + 0x00000011, 0x00002DF9, 0x00001B7E, 0x000007A3, 0x000500C4, 0x00000011, 0x00003F4F, 0x00002DF9, + 0x0000074E, 0x00050084, 0x00000011, 0x000059EB, 0x00003F4F, 0x00005C31, 0x000500C2, 0x0000000B, + 0x00003343, 0x00005158, 0x00000A19, 0x000500C7, 0x0000000B, 0x000039C1, 0x00003343, 0x00000A81, + 0x00050051, 0x0000000B, 0x0000229A, 0x00005C31, 0x00000000, 0x00050084, 0x0000000B, 0x000059D1, + 0x000039C1, 0x0000229A, 0x00050041, 0x00000289, 0x00004E44, 0x00000CE9, 0x00000A11, 0x0004003D, + 0x0000000B, 0x000048C4, 0x00004E44, 0x00050041, 0x00000289, 0x000058AD, 0x00000CE9, 0x00000A14, + 0x0004003D, 0x0000000B, 0x00004FA3, 0x000058AD, 0x000500C7, 0x0000000B, 0x00005F7D, 0x000048C4, + 0x00000A22, 0x000500AB, 0x00000009, 0x000048EB, 0x00005F7D, 0x00000A0A, 0x000500C2, 0x0000000B, + 0x00002311, 0x000048C4, 0x00000A16, 0x000500C7, 0x0000000B, 0x00004408, 0x00002311, 0x00000A1F, + 0x0004007C, 0x0000000C, 0x00005988, 0x000048C4, 0x000500C4, 0x0000000C, 0x0000358F, 0x00005988, + 0x00000A29, 0x000500C3, 0x0000000C, 0x0000509C, 0x0000358F, 0x00000A59, 0x000500C4, 0x0000000C, + 0x00004702, 0x0000509C, 0x00000A50, 0x00050080, 0x0000000C, 0x00001D26, 0x00004702, 0x00000089, + 0x0004007C, 0x0000000D, 0x00002B2C, 0x00001D26, 0x000500C7, 0x0000000B, 0x00005879, 0x000048C4, + 0x00000926, 0x000500AB, 0x00000009, 0x00001D59, 0x00005879, 0x00000A0A, 0x000500C7, 0x0000000B, + 0x00001F43, 0x00004FA3, 0x00000A44, 0x000500C4, 0x0000000B, 0x00003DA7, 0x00001F43, 0x00000A19, + 0x000500C2, 0x0000000B, 0x0000583F, 0x00004FA3, 0x00000A28, 0x000500C7, 0x0000000B, 0x00004BBE, + 0x0000583F, 0x00000A44, 0x000500C4, 0x0000000B, 0x00006273, 0x00004BBE, 0x00000A19, 0x00050050, + 0x00000011, 0x000028B6, 0x00004FA3, 0x00004FA3, 0x000500C2, 0x00000011, 0x00002891, 0x000028B6, + 0x000008E3, 0x000500C7, 0x00000011, 0x00005B53, 0x00002891, 0x0000084A, 0x000500C4, 0x00000011, + 0x00003F50, 0x00005B53, 0x0000074E, 0x00050084, 0x00000011, 0x000059EC, 0x00003F50, 0x00005C31, + 0x000500C2, 0x0000000B, 0x00003213, 0x00004FA3, 0x00000A5E, 0x000500C7, 0x0000000B, 0x00003F4C, + 0x00003213, 0x00000A1F, 0x00050041, 0x0000028A, 0x00005143, 0x00000F48, 0x00000A0A, 0x0004003D, + 0x0000000B, 0x000022D1, 0x00005143, 0x000500AE, 0x00000009, 0x00001CED, 0x000022D1, 0x000059D1, + 0x000300F7, 0x00004427, 0x00000002, 0x000400FA, 0x00001CED, 0x000055E9, 0x00004427, 0x000200F8, + 0x000055E9, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004427, 0x0004003D, 0x00000014, 0x0000392D, + 0x00000F48, 0x0007004F, 0x00000011, 0x00004849, 0x0000392D, 0x0000392D, 0x00000000, 0x00000001, + 0x000500C4, 0x00000011, 0x00002670, 0x00004849, 0x0000072A, 0x00050051, 0x0000000B, 0x00001A29, + 0x00002670, 0x00000000, 0x00050051, 0x0000000B, 0x000047F9, 0x00002670, 0x00000001, 0x00050051, + 0x0000000B, 0x0000376A, 0x00004AB4, 0x00000001, 0x0007000C, 0x0000000B, 0x00005F7E, 0x00000001, + 0x00000029, 0x000047F9, 0x0000376A, 0x00050050, 0x00000011, 0x000051EF, 0x00001A29, 0x00005F7E, + 0x00050080, 0x00000011, 0x0000522C, 0x000051EF, 0x000059EB, 0x000500B2, 0x00000009, 0x00003ECB, + 0x00003F4C, 0x00000A13, 0x000300F7, 0x00005CE0, 0x00000000, 0x000400FA, 0x00003ECB, 0x00002AEE, + 0x00003AEF, 0x000200F8, 0x00003AEF, 0x000500AA, 0x00000009, 0x000034FE, 0x00003F4C, 0x00000A19, + 0x000600A9, 0x0000000B, 0x000020F6, 0x000034FE, 0x00000A10, 0x00000A0A, 0x000200F9, 0x00005CE0, + 0x000200F8, 0x00002AEE, 0x000200F9, 0x00005CE0, 0x000200F8, 0x00005CE0, 0x000700F5, 0x0000000B, + 0x00004B64, 0x00003F4C, 0x00002AEE, 0x000020F6, 0x00003AEF, 0x00050050, 0x00000011, 0x000041BE, + 0x0000217E, 0x0000217E, 0x000500AE, 0x0000000F, 0x00002E19, 0x000041BE, 0x0000072D, 0x000600A9, + 0x00000011, 0x00004BB5, 0x00002E19, 0x00000724, 0x0000070F, 0x000500C4, 0x00000011, 0x00002AEA, + 0x0000522C, 0x00004BB5, 0x00050050, 0x00000011, 0x0000605D, 0x00004B64, 0x00004B64, 0x000500C2, + 0x00000011, 0x00002385, 0x0000605D, 0x00000718, 0x000500C7, 0x00000011, 0x00003EC8, 0x00002385, + 0x00000724, 0x00050080, 0x00000011, 0x000046BA, 0x00002AEA, 0x00003EC8, 0x00050084, 0x00000011, + 0x00005998, 0x00000A9F, 0x00005C31, 0x00050050, 0x00000011, 0x00002C44, 0x000023AA, 0x00000A0A, + 0x000500C2, 0x00000011, 0x000019AB, 0x00005998, 0x00002C44, 0x00050086, 0x00000011, 0x000027A2, + 0x000046BA, 0x000019AB, 0x00050051, 0x0000000B, 0x00004FA6, 0x000027A2, 0x00000001, 0x00050084, + 0x0000000B, 0x00002B26, 0x00004FA6, 0x00005051, 0x00050051, 0x0000000B, 0x00006059, 0x000027A2, + 0x00000000, 0x00050080, 0x0000000B, 0x00005420, 0x00002B26, 0x00006059, 0x00050080, 0x0000000B, + 0x00002226, 0x0000217F, 0x00005420, 0x00050084, 0x00000011, 0x00005768, 0x000027A2, 0x000019AB, + 0x00050082, 0x00000011, 0x000050EB, 0x000046BA, 0x00005768, 0x00050051, 0x0000000B, 0x00001C87, + 0x00005998, 0x00000000, 0x00050051, 0x0000000B, 0x00005962, 0x00005998, 0x00000001, 0x00050084, + 0x0000000B, 0x00003372, 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, 0x000038D7, 0x00002226, + 0x00003372, 0x00050051, 0x0000000B, 0x00001A95, 0x000050EB, 0x00000001, 0x00050051, 0x0000000B, + 0x00005BE6, 0x000019AB, 0x00000000, 0x00050084, 0x0000000B, 0x00005966, 0x00001A95, 0x00005BE6, + 0x00050051, 0x0000000B, 0x00001AE6, 0x000050EB, 0x00000000, 0x00050080, 0x0000000B, 0x000025E0, + 0x00005966, 0x00001AE6, 0x000500C4, 0x0000000B, 0x00004665, 0x000025E0, 0x000023AA, 0x00050080, + 0x0000000B, 0x000047BB, 0x000038D7, 0x00004665, 0x00050084, 0x0000000B, 0x000034C0, 0x00003372, + 0x00000A84, 0x00050089, 0x0000000B, 0x0000628F, 0x000047BB, 0x000034C0, 0x000500AE, 0x00000009, + 0x00003FFB, 0x0000217E, 0x00000A10, 0x000600A9, 0x0000000B, 0x0000609F, 0x00003FFB, 0x00000A0D, + 0x00000A0A, 0x00050080, 0x0000000B, 0x0000540E, 0x000023AA, 0x0000609F, 0x000500C4, 0x0000000B, + 0x000030F7, 0x00000A0D, 0x0000540E, 0x000300F7, 0x000062AD, 0x00000000, 0x000400FA, 0x00001D59, + 0x00005D41, 0x000062AD, 0x000200F8, 0x00005D41, 0x00050080, 0x0000000B, 0x00001B50, 0x0000628F, + 0x000023AA, 0x000200F9, 0x000062AD, 0x000200F8, 0x000062AD, 0x000700F5, 0x0000000B, 0x00005E7C, + 0x0000628F, 0x00005CE0, 0x00001B50, 0x00005D41, 0x000500AA, 0x00000009, 0x000060B1, 0x000030F7, + 0x00000A0D, 0x000300F7, 0x00004F23, 0x00000002, 0x000400FA, 0x000060B1, 0x00002621, 0x00002F61, + 0x000200F8, 0x00002F61, 0x00060041, 0x00000288, 0x00004BCF, 0x00000CC7, 0x00000A0B, 0x00005E7C, + 0x0004003D, 0x0000000B, 0x00005D43, 0x00004BCF, 0x00050080, 0x0000000B, 0x00002DA7, 0x00005E7C, + 0x000030F7, 0x00060041, 0x00000288, 0x0000194B, 0x00000CC7, 0x00000A0B, 0x00002DA7, 0x0004003D, + 0x0000000B, 0x00005E5B, 0x0000194B, 0x00050084, 0x0000000B, 0x0000185A, 0x00000A10, 0x000030F7, + 0x00050080, 0x0000000B, 0x000020A1, 0x00005E7C, 0x0000185A, 0x00060041, 0x00000288, 0x00003BCD, + 0x00000CC7, 0x00000A0B, 0x000020A1, 0x0004003D, 0x0000000B, 0x00005E5C, 0x00003BCD, 0x00050084, + 0x0000000B, 0x0000185B, 0x00000A13, 0x000030F7, 0x00050080, 0x0000000B, 0x000020A2, 0x00005E7C, + 0x0000185B, 0x00060041, 0x00000288, 0x000037F1, 0x00000CC7, 0x00000A0B, 0x000020A2, 0x0004003D, + 0x0000000B, 0x0000374C, 0x000037F1, 0x00070050, 0x00000017, 0x00004CD6, 0x00005D43, 0x00005E5B, + 0x00005E5C, 0x0000374C, 0x00050084, 0x0000000B, 0x00004298, 0x00000A16, 0x000030F7, 0x00050080, + 0x0000000B, 0x000036A7, 0x00005E7C, 0x00004298, 0x00060041, 0x00000288, 0x00003BCE, 0x00000CC7, + 0x00000A0B, 0x000036A7, 0x0004003D, 0x0000000B, 0x00005E5D, 0x00003BCE, 0x00050084, 0x0000000B, + 0x0000185C, 0x00000A19, 0x000030F7, 0x00050080, 0x0000000B, 0x000020A3, 0x00005E7C, 0x0000185C, + 0x00060041, 0x00000288, 0x00003BCF, 0x00000CC7, 0x00000A0B, 0x000020A3, 0x0004003D, 0x0000000B, + 0x00005E5E, 0x00003BCF, 0x00050084, 0x0000000B, 0x0000185D, 0x00000A1C, 0x000030F7, 0x00050080, + 0x0000000B, 0x000020A4, 0x00005E7C, 0x0000185D, 0x00060041, 0x00000288, 0x00003BD0, 0x00000CC7, + 0x00000A0B, 0x000020A4, 0x0004003D, 0x0000000B, 0x00005E5F, 0x00003BD0, 0x00050084, 0x0000000B, + 0x0000185E, 0x00000A1F, 0x000030F7, 0x00050080, 0x0000000B, 0x000020A5, 0x00005E7C, 0x0000185E, + 0x00060041, 0x00000288, 0x000037F2, 0x00000CC7, 0x00000A0B, 0x000020A5, 0x0004003D, 0x0000000B, + 0x00003FFC, 0x000037F2, 0x00070050, 0x00000017, 0x0000512C, 0x00005E5D, 0x00005E5E, 0x00005E5F, + 0x00003FFC, 0x000200F9, 0x00004F23, 0x000200F8, 0x00002621, 0x00060041, 0x00000288, 0x00005545, + 0x00000CC7, 0x00000A0B, 0x00005E7C, 0x0004003D, 0x0000000B, 0x00005D44, 0x00005545, 0x00050080, + 0x0000000B, 0x00002DA8, 0x00005E7C, 0x00000A0D, 0x00060041, 0x00000288, 0x000018FF, 0x00000CC7, + 0x00000A0B, 0x00002DA8, 0x0004003D, 0x0000000B, 0x00005C62, 0x000018FF, 0x00050080, 0x0000000B, + 0x00002DA9, 0x00005E7C, 0x00000A10, 0x00060041, 0x00000288, 0x00001900, 0x00000CC7, 0x00000A0B, + 0x00002DA9, 0x0004003D, 0x0000000B, 0x00005C63, 0x00001900, 0x00050080, 0x0000000B, 0x00002DAA, + 0x00005E7C, 0x00000A13, 0x00060041, 0x00000288, 0x00005FEE, 0x00000CC7, 0x00000A0B, 0x00002DAA, + 0x0004003D, 0x0000000B, 0x00003700, 0x00005FEE, 0x00070050, 0x00000017, 0x00004ADD, 0x00005D44, + 0x00005C62, 0x00005C63, 0x00003700, 0x00050080, 0x0000000B, 0x000057E5, 0x00005E7C, 0x00000A16, + 0x00060041, 0x00000288, 0x0000604B, 0x00000CC7, 0x00000A0B, 0x000057E5, 0x0004003D, 0x0000000B, + 0x00005C64, 0x0000604B, 0x00050080, 0x0000000B, 0x00002DAB, 0x00005E7C, 0x00000A19, 0x00060041, + 0x00000288, 0x00001901, 0x00000CC7, 0x00000A0B, 0x00002DAB, 0x0004003D, 0x0000000B, 0x00005C65, + 0x00001901, 0x00050080, 0x0000000B, 0x00002DAC, 0x00005E7C, 0x00000A1C, 0x00060041, 0x00000288, + 0x00001902, 0x00000CC7, 0x00000A0B, 0x00002DAC, 0x0004003D, 0x0000000B, 0x00005C66, 0x00001902, + 0x00050080, 0x0000000B, 0x00002DAD, 0x00005E7C, 0x00000A1F, 0x00060041, 0x00000288, 0x00005FEF, + 0x00000CC7, 0x00000A0B, 0x00002DAD, 0x0004003D, 0x0000000B, 0x00003FFD, 0x00005FEF, 0x00070050, + 0x00000017, 0x0000512D, 0x00005C64, 0x00005C65, 0x00005C66, 0x00003FFD, 0x000200F9, 0x00004F23, + 0x000200F8, 0x00004F23, 0x000700F5, 0x00000017, 0x00002629, 0x0000512D, 0x00002621, 0x0000512C, + 0x00002F61, 0x000700F5, 0x00000017, 0x000038EA, 0x00004ADD, 0x00002621, 0x00004CD6, 0x00002F61, + 0x000500AB, 0x00000009, 0x000043D9, 0x000023AA, 0x00000A0A, 0x000300F7, 0x0000530F, 0x00000002, + 0x000400FA, 0x000043D9, 0x00005227, 0x0000577B, 0x000200F8, 0x0000577B, 0x000300F7, 0x00005BA4, + 0x00000000, 0x001300FB, 0x00002180, 0x00006032, 0x00000000, 0x00003E85, 0x00000001, 0x00003E85, + 0x00000002, 0x00003842, 0x0000000A, 0x00003842, 0x00000003, 0x000059BF, 0x0000000C, 0x000059BF, + 0x00000004, 0x000052C6, 0x00000006, 0x00002033, 0x000200F8, 0x00002033, 0x00050051, 0x0000000B, + 0x00005F56, 0x000038EA, 0x00000000, 0x0006000C, 0x00000015, 0x00006067, 0x00000001, 0x0000003E, + 0x00005F56, 0x00050051, 0x0000000D, 0x00002294, 0x00006067, 0x00000000, 0x00050051, 0x0000000B, + 0x00001DAF, 0x000038EA, 0x00000001, 0x0006000C, 0x00000015, 0x00003CF5, 0x00000001, 0x0000003E, + 0x00001DAF, 0x00050051, 0x0000000D, 0x00002295, 0x00003CF5, 0x00000000, 0x00050051, 0x0000000B, + 0x00001DB0, 0x000038EA, 0x00000002, 0x0006000C, 0x00000015, 0x00003CF6, 0x00000001, 0x0000003E, + 0x00001DB0, 0x00050051, 0x0000000D, 0x00002296, 0x00003CF6, 0x00000000, 0x00050051, 0x0000000B, + 0x00001DB1, 0x000038EA, 0x00000003, 0x0006000C, 0x00000015, 0x00003CE2, 0x00000001, 0x0000003E, + 0x00001DB1, 0x00050051, 0x0000000D, 0x00002822, 0x00003CE2, 0x00000000, 0x00070050, 0x0000001D, + 0x00005EB9, 0x00002294, 0x00002295, 0x00002296, 0x00002822, 0x00050051, 0x0000000B, 0x0000437A, + 0x00002629, 0x00000000, 0x0006000C, 0x00000015, 0x0000466B, 0x00000001, 0x0000003E, 0x0000437A, + 0x00050051, 0x0000000D, 0x00002297, 0x0000466B, 0x00000000, 0x00050051, 0x0000000B, 0x00001DB2, + 0x00002629, 0x00000001, 0x0006000C, 0x00000015, 0x00003CF7, 0x00000001, 0x0000003E, 0x00001DB2, + 0x00050051, 0x0000000D, 0x00002298, 0x00003CF7, 0x00000000, 0x00050051, 0x0000000B, 0x00001DB3, + 0x00002629, 0x00000002, 0x0006000C, 0x00000015, 0x00003CF8, 0x00000001, 0x0000003E, 0x00001DB3, + 0x00050051, 0x0000000D, 0x00002299, 0x00003CF8, 0x00000000, 0x00050051, 0x0000000B, 0x00001DB4, + 0x00002629, 0x00000003, 0x0006000C, 0x00000015, 0x00003CE3, 0x00000001, 0x0000003E, 0x00001DB4, + 0x00050051, 0x0000000D, 0x0000349A, 0x00003CE3, 0x00000000, 0x00070050, 0x0000001D, 0x000048F6, + 0x00002297, 0x00002298, 0x00002299, 0x0000349A, 0x000200F9, 0x00005BA4, 0x000200F8, 0x000052C6, + 0x0004007C, 0x0000001A, 0x000060F4, 0x000038EA, 0x000500C4, 0x0000001A, 0x0000581E, 0x000060F4, + 0x00000302, 0x000500C3, 0x0000001A, 0x00004098, 0x0000581E, 0x00000302, 0x0004006F, 0x0000001D, + 0x00002A97, 0x00004098, 0x0005008E, 0x0000001D, 0x00004A78, 0x00002A97, 0x000007FE, 0x0007000C, + 0x0000001D, 0x00004980, 0x00000001, 0x00000028, 0x00000504, 0x00004A78, 0x0004007C, 0x0000001A, + 0x000027E5, 0x00002629, 0x000500C4, 0x0000001A, 0x000021A1, 0x000027E5, 0x00000302, 0x000500C3, + 0x0000001A, 0x00004099, 0x000021A1, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A98, 0x00004099, + 0x0005008E, 0x0000001D, 0x000053BF, 0x00002A98, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004362, + 0x00000001, 0x00000028, 0x00000504, 0x000053BF, 0x000200F9, 0x00005BA4, 0x000200F8, 0x000059BF, + 0x000600A9, 0x0000000B, 0x00004C06, 0x00001D59, 0x00000A46, 0x00000A0A, 0x00070050, 0x00000017, + 0x000023B0, 0x00004C06, 0x00004C06, 0x00004C06, 0x00004C06, 0x000500C2, 0x00000017, 0x00005D48, + 0x000038EA, 0x000023B0, 0x000500C7, 0x00000017, 0x00005DE6, 0x00005D48, 0x000003A1, 0x000500C7, + 0x00000017, 0x0000489C, 0x00005DE6, 0x000002D1, 0x000500C2, 0x00000017, 0x00005B90, 0x00005DE6, + 0x00000107, 0x000500AA, 0x00000013, 0x000040C9, 0x00005B90, 0x00000B50, 0x0006000C, 0x0000001A, + 0x00002C4B, 0x00000001, 0x0000004B, 0x0000489C, 0x0004007C, 0x00000017, 0x00002A15, 0x00002C4B, + 0x00050082, 0x00000017, 0x0000187A, 0x00000107, 0x00002A15, 0x00050080, 0x00000017, 0x00002210, + 0x00002A15, 0x00000A0F, 0x000600A9, 0x00000017, 0x0000286F, 0x000040C9, 0x00002210, 0x00005B90, + 0x000500C4, 0x00000017, 0x00005AD4, 0x0000489C, 0x0000187A, 0x000500C7, 0x00000017, 0x0000499A, + 0x00005AD4, 0x000002D1, 0x000600A9, 0x00000017, 0x00002A9D, 0x000040C9, 0x0000499A, 0x0000489C, + 0x00050080, 0x00000017, 0x00005FF9, 0x0000286F, 0x0000022F, 0x000500C4, 0x00000017, 0x00004F7F, + 0x00005FF9, 0x00000467, 0x000500C4, 0x00000017, 0x00003FA6, 0x00002A9D, 0x000002ED, 0x000500C5, + 0x00000017, 0x0000577C, 0x00004F7F, 0x00003FA6, 0x000500AA, 0x00000013, 0x00003600, 0x00005DE6, + 0x00000B50, 0x000600A9, 0x00000017, 0x00004242, 0x00003600, 0x00000B50, 0x0000577C, 0x0004007C, + 0x0000001D, 0x00003044, 0x00004242, 0x000500C2, 0x00000017, 0x0000603E, 0x00002629, 0x000023B0, + 0x000500C7, 0x00000017, 0x00003921, 0x0000603E, 0x000003A1, 0x000500C7, 0x00000017, 0x0000489D, + 0x00003921, 0x000002D1, 0x000500C2, 0x00000017, 0x00005B91, 0x00003921, 0x00000107, 0x000500AA, + 0x00000013, 0x000040CA, 0x00005B91, 0x00000B50, 0x0006000C, 0x0000001A, 0x00002C4C, 0x00000001, + 0x0000004B, 0x0000489D, 0x0004007C, 0x00000017, 0x00002A16, 0x00002C4C, 0x00050082, 0x00000017, + 0x0000187B, 0x00000107, 0x00002A16, 0x00050080, 0x00000017, 0x00002211, 0x00002A16, 0x00000A0F, + 0x000600A9, 0x00000017, 0x00002870, 0x000040CA, 0x00002211, 0x00005B91, 0x000500C4, 0x00000017, + 0x00005AD5, 0x0000489D, 0x0000187B, 0x000500C7, 0x00000017, 0x0000499B, 0x00005AD5, 0x000002D1, + 0x000600A9, 0x00000017, 0x00002A9E, 0x000040CA, 0x0000499B, 0x0000489D, 0x00050080, 0x00000017, + 0x00005FFA, 0x00002870, 0x0000022F, 0x000500C4, 0x00000017, 0x00004F80, 0x00005FFA, 0x00000467, + 0x000500C4, 0x00000017, 0x00003FA7, 0x00002A9E, 0x000002ED, 0x000500C5, 0x00000017, 0x0000577D, + 0x00004F80, 0x00003FA7, 0x000500AA, 0x00000013, 0x00003601, 0x00003921, 0x00000B50, 0x000600A9, + 0x00000017, 0x00004657, 0x00003601, 0x00000B50, 0x0000577D, 0x0004007C, 0x0000001D, 0x0000593B, + 0x00004657, 0x000200F9, 0x00005BA4, 0x000200F8, 0x00003842, 0x000600A9, 0x0000000B, 0x00004C07, + 0x00001D59, 0x00000A46, 0x00000A0A, 0x00070050, 0x00000017, 0x000023B1, 0x00004C07, 0x00004C07, + 0x00004C07, 0x00004C07, 0x000500C2, 0x00000017, 0x000056D3, 0x000038EA, 0x000023B1, 0x000500C7, + 0x00000017, 0x00004A56, 0x000056D3, 0x000003A1, 0x00040070, 0x0000001D, 0x00003F05, 0x00004A56, + 0x0005008E, 0x0000001D, 0x0000521A, 0x00003F05, 0x000006FE, 0x000500C2, 0x00000017, 0x00001E42, + 0x00002629, 0x000023B1, 0x000500C7, 0x00000017, 0x00002BD4, 0x00001E42, 0x000003A1, 0x00040070, + 0x0000001D, 0x0000431A, 0x00002BD4, 0x0005008E, 0x0000001D, 0x00003092, 0x0000431A, 0x000006FE, + 0x000200F9, 0x00005BA4, 0x000200F8, 0x00003E85, 0x000600A9, 0x0000000B, 0x00004C08, 0x00001D59, + 0x00000A3A, 0x00000A0A, 0x00070050, 0x00000017, 0x000023B2, 0x00004C08, 0x00004C08, 0x00004C08, + 0x00004C08, 0x000500C2, 0x00000017, 0x000056D4, 0x000038EA, 0x000023B2, 0x000500C7, 0x00000017, + 0x00004A57, 0x000056D4, 0x0000064B, 0x00040070, 0x0000001D, 0x00003F06, 0x00004A57, 0x0005008E, + 0x0000001D, 0x0000521B, 0x00003F06, 0x0000017A, 0x000500C2, 0x00000017, 0x00001E43, 0x00002629, + 0x000023B2, 0x000500C7, 0x00000017, 0x00002BD5, 0x00001E43, 0x0000064B, 0x00040070, 0x0000001D, + 0x0000431B, 0x00002BD5, 0x0005008E, 0x0000001D, 0x00003093, 0x0000431B, 0x0000017A, 0x000200F9, + 0x00005BA4, 0x000200F8, 0x00006032, 0x0004007C, 0x0000001D, 0x00004B1F, 0x000038EA, 0x0004007C, + 0x0000001D, 0x000038B2, 0x00002629, 0x000200F9, 0x00005BA4, 0x000200F8, 0x00005BA4, 0x000F00F5, + 0x0000001D, 0x00002BF3, 0x000038B2, 0x00006032, 0x00003093, 0x00003E85, 0x00003092, 0x00003842, + 0x0000593B, 0x000059BF, 0x00004362, 0x000052C6, 0x000048F6, 0x00002033, 0x000F00F5, 0x0000001D, + 0x0000358D, 0x00004B1F, 0x00006032, 0x0000521B, 0x00003E85, 0x0000521A, 0x00003842, 0x00003044, + 0x000059BF, 0x00004980, 0x000052C6, 0x00005EB9, 0x00002033, 0x000200F9, 0x0000530F, 0x000200F8, + 0x00005227, 0x000300F7, 0x00005BA5, 0x00000000, 0x000700FB, 0x00002180, 0x000030ED, 0x00000005, + 0x000052C7, 0x00000007, 0x00002034, 0x000200F8, 0x00002034, 0x00050051, 0x0000000B, 0x00005F57, + 0x000038EA, 0x00000000, 0x0006000C, 0x00000015, 0x00006068, 0x00000001, 0x0000003E, 0x00005F57, + 0x00050051, 0x0000000D, 0x0000229B, 0x00006068, 0x00000000, 0x00050051, 0x0000000B, 0x00001DB5, + 0x000038EA, 0x00000001, 0x0006000C, 0x00000015, 0x00003CF9, 0x00000001, 0x0000003E, 0x00001DB5, + 0x00050051, 0x0000000D, 0x0000229C, 0x00003CF9, 0x00000000, 0x00050051, 0x0000000B, 0x00001DB6, + 0x000038EA, 0x00000002, 0x0006000C, 0x00000015, 0x00003CFA, 0x00000001, 0x0000003E, 0x00001DB6, + 0x00050051, 0x0000000D, 0x0000229D, 0x00003CFA, 0x00000000, 0x00050051, 0x0000000B, 0x00001DB7, + 0x000038EA, 0x00000003, 0x0006000C, 0x00000015, 0x00003CE4, 0x00000001, 0x0000003E, 0x00001DB7, + 0x00050051, 0x0000000D, 0x00002823, 0x00003CE4, 0x00000000, 0x00070050, 0x0000001D, 0x00005EBA, + 0x0000229B, 0x0000229C, 0x0000229D, 0x00002823, 0x00050051, 0x0000000B, 0x0000437B, 0x00002629, + 0x00000000, 0x0006000C, 0x00000015, 0x0000466C, 0x00000001, 0x0000003E, 0x0000437B, 0x00050051, + 0x0000000D, 0x0000229E, 0x0000466C, 0x00000000, 0x00050051, 0x0000000B, 0x00001DB8, 0x00002629, + 0x00000001, 0x0006000C, 0x00000015, 0x00003CFB, 0x00000001, 0x0000003E, 0x00001DB8, 0x00050051, + 0x0000000D, 0x0000229F, 0x00003CFB, 0x00000000, 0x00050051, 0x0000000B, 0x00001DB9, 0x00002629, + 0x00000002, 0x0006000C, 0x00000015, 0x00003CFC, 0x00000001, 0x0000003E, 0x00001DB9, 0x00050051, + 0x0000000D, 0x000022A0, 0x00003CFC, 0x00000000, 0x00050051, 0x0000000B, 0x00001DBA, 0x00002629, + 0x00000003, 0x0006000C, 0x00000015, 0x00003CE5, 0x00000001, 0x0000003E, 0x00001DBA, 0x00050051, + 0x0000000D, 0x0000349B, 0x00003CE5, 0x00000000, 0x00070050, 0x0000001D, 0x000048F7, 0x0000229E, + 0x0000229F, 0x000022A0, 0x0000349B, 0x000200F9, 0x00005BA5, 0x000200F8, 0x000052C7, 0x0004007C, + 0x0000001A, 0x000060F5, 0x000038EA, 0x000500C4, 0x0000001A, 0x0000581F, 0x000060F5, 0x00000302, + 0x000500C3, 0x0000001A, 0x0000409A, 0x0000581F, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A99, + 0x0000409A, 0x0005008E, 0x0000001D, 0x00004A79, 0x00002A99, 0x000007FE, 0x0007000C, 0x0000001D, + 0x00004981, 0x00000001, 0x00000028, 0x00000504, 0x00004A79, 0x0004007C, 0x0000001A, 0x000027E6, + 0x00002629, 0x000500C4, 0x0000001A, 0x000021A2, 0x000027E6, 0x00000302, 0x000500C3, 0x0000001A, + 0x0000409B, 0x000021A2, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A9A, 0x0000409B, 0x0005008E, + 0x0000001D, 0x000053C0, 0x00002A9A, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004363, 0x00000001, + 0x00000028, 0x00000504, 0x000053C0, 0x000200F9, 0x00005BA5, 0x000200F8, 0x000030ED, 0x0004007C, + 0x0000001D, 0x00004B20, 0x000038EA, 0x0004007C, 0x0000001D, 0x000038B3, 0x00002629, 0x000200F9, + 0x00005BA5, 0x000200F8, 0x00005BA5, 0x000900F5, 0x0000001D, 0x00002BF4, 0x000038B3, 0x000030ED, + 0x00004363, 0x000052C7, 0x000048F7, 0x00002034, 0x000900F5, 0x0000001D, 0x0000358E, 0x00004B20, + 0x000030ED, 0x00004981, 0x000052C7, 0x00005EBA, 0x00002034, 0x000200F9, 0x0000530F, 0x000200F8, + 0x0000530F, 0x000700F5, 0x0000001D, 0x00002662, 0x00002BF4, 0x00005BA5, 0x00002BF3, 0x00005BA4, + 0x000700F5, 0x0000001D, 0x000036E3, 0x0000358E, 0x00005BA5, 0x0000358D, 0x00005BA4, 0x000500AE, + 0x00000009, 0x00002E55, 0x00003F4C, 0x00000A16, 0x000300F7, 0x00005313, 0x00000002, 0x000400FA, + 0x00002E55, 0x000051F1, 0x00005313, 0x000200F8, 0x000051F1, 0x00050084, 0x0000000B, 0x00002B47, + 0x00000AFA, 0x0000229A, 0x00050085, 0x0000000D, 0x00005A1D, 0x00002B2C, 0x000000FC, 0x00050080, + 0x0000000B, 0x00001FB2, 0x00005E7C, 0x00002B47, 0x000300F7, 0x00004F24, 0x00000002, 0x000400FA, + 0x000060B1, 0x00002622, 0x00002F62, 0x000200F8, 0x00002F62, 0x00060041, 0x00000288, 0x00004BD0, + 0x00000CC7, 0x00000A0B, 0x00001FB2, 0x0004003D, 0x0000000B, 0x00005D45, 0x00004BD0, 0x00050080, + 0x0000000B, 0x00002DAE, 0x00001FB2, 0x000030F7, 0x00060041, 0x00000288, 0x0000194C, 0x00000CC7, + 0x00000A0B, 0x00002DAE, 0x0004003D, 0x0000000B, 0x00005E60, 0x0000194C, 0x00050084, 0x0000000B, + 0x0000185F, 0x00000A10, 0x000030F7, 0x00050080, 0x0000000B, 0x000020A6, 0x00001FB2, 0x0000185F, + 0x00060041, 0x00000288, 0x00003BD1, 0x00000CC7, 0x00000A0B, 0x000020A6, 0x0004003D, 0x0000000B, + 0x00005E61, 0x00003BD1, 0x00050084, 0x0000000B, 0x00001860, 0x00000A13, 0x000030F7, 0x00050080, + 0x0000000B, 0x000020A7, 0x00001FB2, 0x00001860, 0x00060041, 0x00000288, 0x000037F3, 0x00000CC7, + 0x00000A0B, 0x000020A7, 0x0004003D, 0x0000000B, 0x0000374D, 0x000037F3, 0x00070050, 0x00000017, + 0x00004CD7, 0x00005D45, 0x00005E60, 0x00005E61, 0x0000374D, 0x00050084, 0x0000000B, 0x00004299, + 0x00000A16, 0x000030F7, 0x00050080, 0x0000000B, 0x000036A8, 0x00001FB2, 0x00004299, 0x00060041, + 0x00000288, 0x00003BD2, 0x00000CC7, 0x00000A0B, 0x000036A8, 0x0004003D, 0x0000000B, 0x00005E62, + 0x00003BD2, 0x00050084, 0x0000000B, 0x00001861, 0x00000A19, 0x000030F7, 0x00050080, 0x0000000B, + 0x000020A8, 0x00001FB2, 0x00001861, 0x00060041, 0x00000288, 0x00003BD3, 0x00000CC7, 0x00000A0B, + 0x000020A8, 0x0004003D, 0x0000000B, 0x00005E63, 0x00003BD3, 0x00050084, 0x0000000B, 0x00001862, + 0x00000A1C, 0x000030F7, 0x00050080, 0x0000000B, 0x000020A9, 0x00001FB2, 0x00001862, 0x00060041, + 0x00000288, 0x00003BD4, 0x00000CC7, 0x00000A0B, 0x000020A9, 0x0004003D, 0x0000000B, 0x00005E64, + 0x00003BD4, 0x00050084, 0x0000000B, 0x00001863, 0x00000A1F, 0x000030F7, 0x00050080, 0x0000000B, + 0x000020AA, 0x00001FB2, 0x00001863, 0x00060041, 0x00000288, 0x000037F4, 0x00000CC7, 0x00000A0B, + 0x000020AA, 0x0004003D, 0x0000000B, 0x00003FFE, 0x000037F4, 0x00070050, 0x00000017, 0x0000512E, + 0x00005E62, 0x00005E63, 0x00005E64, 0x00003FFE, 0x000200F9, 0x00004F24, 0x000200F8, 0x00002622, + 0x00060041, 0x00000288, 0x00005546, 0x00000CC7, 0x00000A0B, 0x00001FB2, 0x0004003D, 0x0000000B, + 0x00005D46, 0x00005546, 0x00050080, 0x0000000B, 0x00002DAF, 0x00001FB2, 0x00000A0D, 0x00060041, + 0x00000288, 0x00001903, 0x00000CC7, 0x00000A0B, 0x00002DAF, 0x0004003D, 0x0000000B, 0x00005C67, + 0x00001903, 0x00050080, 0x0000000B, 0x00002DB0, 0x00001FB2, 0x00000A10, 0x00060041, 0x00000288, + 0x00001904, 0x00000CC7, 0x00000A0B, 0x00002DB0, 0x0004003D, 0x0000000B, 0x00005C68, 0x00001904, + 0x00050080, 0x0000000B, 0x00002DB1, 0x00001FB2, 0x00000A13, 0x00060041, 0x00000288, 0x00005FF0, + 0x00000CC7, 0x00000A0B, 0x00002DB1, 0x0004003D, 0x0000000B, 0x00003701, 0x00005FF0, 0x00070050, + 0x00000017, 0x00004ADE, 0x00005D46, 0x00005C67, 0x00005C68, 0x00003701, 0x00050080, 0x0000000B, + 0x000057E6, 0x00001FB2, 0x00000A16, 0x00060041, 0x00000288, 0x0000604C, 0x00000CC7, 0x00000A0B, + 0x000057E6, 0x0004003D, 0x0000000B, 0x00005C69, 0x0000604C, 0x00050080, 0x0000000B, 0x00002DB2, + 0x00001FB2, 0x00000A19, 0x00060041, 0x00000288, 0x00001905, 0x00000CC7, 0x00000A0B, 0x00002DB2, + 0x0004003D, 0x0000000B, 0x00005C6A, 0x00001905, 0x00050080, 0x0000000B, 0x00002DB3, 0x00001FB2, + 0x00000A1C, 0x00060041, 0x00000288, 0x00001906, 0x00000CC7, 0x00000A0B, 0x00002DB3, 0x0004003D, + 0x0000000B, 0x00005C6B, 0x00001906, 0x00050080, 0x0000000B, 0x00002DB4, 0x00001FB2, 0x00000A1F, + 0x00060041, 0x00000288, 0x00005FF1, 0x00000CC7, 0x00000A0B, 0x00002DB4, 0x0004003D, 0x0000000B, + 0x00003FFF, 0x00005FF1, 0x00070050, 0x00000017, 0x0000512F, 0x00005C69, 0x00005C6A, 0x00005C6B, + 0x00003FFF, 0x000200F9, 0x00004F24, 0x000200F8, 0x00004F24, 0x000700F5, 0x00000017, 0x00002BCD, + 0x0000512F, 0x00002622, 0x0000512E, 0x00002F62, 0x000700F5, 0x00000017, 0x0000370D, 0x00004ADE, + 0x00002622, 0x00004CD7, 0x00002F62, 0x000300F7, 0x00005310, 0x00000002, 0x000400FA, 0x000043D9, + 0x00005228, 0x0000577E, 0x000200F8, 0x0000577E, 0x000300F7, 0x00005BA6, 0x00000000, 0x001300FB, + 0x00002180, 0x00006033, 0x00000000, 0x00003E86, 0x00000001, 0x00003E86, 0x00000002, 0x00003843, + 0x0000000A, 0x00003843, 0x00000003, 0x000059C0, 0x0000000C, 0x000059C0, 0x00000004, 0x000052C8, + 0x00000006, 0x00002035, 0x000200F8, 0x00002035, 0x00050051, 0x0000000B, 0x00005F58, 0x0000370D, + 0x00000000, 0x0006000C, 0x00000015, 0x00006069, 0x00000001, 0x0000003E, 0x00005F58, 0x00050051, + 0x0000000D, 0x000022A1, 0x00006069, 0x00000000, 0x00050051, 0x0000000B, 0x00001DBB, 0x0000370D, + 0x00000001, 0x0006000C, 0x00000015, 0x00003CFD, 0x00000001, 0x0000003E, 0x00001DBB, 0x00050051, + 0x0000000D, 0x000022A2, 0x00003CFD, 0x00000000, 0x00050051, 0x0000000B, 0x00001DBC, 0x0000370D, + 0x00000002, 0x0006000C, 0x00000015, 0x00003CFE, 0x00000001, 0x0000003E, 0x00001DBC, 0x00050051, + 0x0000000D, 0x000022A3, 0x00003CFE, 0x00000000, 0x00050051, 0x0000000B, 0x00001DBD, 0x0000370D, + 0x00000003, 0x0006000C, 0x00000015, 0x00003CE6, 0x00000001, 0x0000003E, 0x00001DBD, 0x00050051, + 0x0000000D, 0x00002824, 0x00003CE6, 0x00000000, 0x00070050, 0x0000001D, 0x00005EBB, 0x000022A1, + 0x000022A2, 0x000022A3, 0x00002824, 0x00050051, 0x0000000B, 0x0000437C, 0x00002BCD, 0x00000000, + 0x0006000C, 0x00000015, 0x0000466D, 0x00000001, 0x0000003E, 0x0000437C, 0x00050051, 0x0000000D, + 0x000022A4, 0x0000466D, 0x00000000, 0x00050051, 0x0000000B, 0x00001DBE, 0x00002BCD, 0x00000001, + 0x0006000C, 0x00000015, 0x00003CFF, 0x00000001, 0x0000003E, 0x00001DBE, 0x00050051, 0x0000000D, + 0x000022A5, 0x00003CFF, 0x00000000, 0x00050051, 0x0000000B, 0x00001DBF, 0x00002BCD, 0x00000002, + 0x0006000C, 0x00000015, 0x00003D00, 0x00000001, 0x0000003E, 0x00001DBF, 0x00050051, 0x0000000D, + 0x000022A6, 0x00003D00, 0x00000000, 0x00050051, 0x0000000B, 0x00001DC0, 0x00002BCD, 0x00000003, + 0x0006000C, 0x00000015, 0x00003CE7, 0x00000001, 0x0000003E, 0x00001DC0, 0x00050051, 0x0000000D, + 0x0000349C, 0x00003CE7, 0x00000000, 0x00070050, 0x0000001D, 0x000048F8, 0x000022A4, 0x000022A5, + 0x000022A6, 0x0000349C, 0x000200F9, 0x00005BA6, 0x000200F8, 0x000052C8, 0x0004007C, 0x0000001A, + 0x000060F6, 0x0000370D, 0x000500C4, 0x0000001A, 0x00005820, 0x000060F6, 0x00000302, 0x000500C3, + 0x0000001A, 0x0000409C, 0x00005820, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A9B, 0x0000409C, + 0x0005008E, 0x0000001D, 0x00004A7A, 0x00002A9B, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004982, + 0x00000001, 0x00000028, 0x00000504, 0x00004A7A, 0x0004007C, 0x0000001A, 0x000027E7, 0x00002BCD, + 0x000500C4, 0x0000001A, 0x000021A3, 0x000027E7, 0x00000302, 0x000500C3, 0x0000001A, 0x0000409D, + 0x000021A3, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A9C, 0x0000409D, 0x0005008E, 0x0000001D, + 0x000053C1, 0x00002A9C, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004364, 0x00000001, 0x00000028, + 0x00000504, 0x000053C1, 0x000200F9, 0x00005BA6, 0x000200F8, 0x000059C0, 0x000600A9, 0x0000000B, + 0x00004C09, 0x00001D59, 0x00000A46, 0x00000A0A, 0x00070050, 0x00000017, 0x000023B3, 0x00004C09, + 0x00004C09, 0x00004C09, 0x00004C09, 0x000500C2, 0x00000017, 0x00005D49, 0x0000370D, 0x000023B3, + 0x000500C7, 0x00000017, 0x00005DE7, 0x00005D49, 0x000003A1, 0x000500C7, 0x00000017, 0x0000489E, + 0x00005DE7, 0x000002D1, 0x000500C2, 0x00000017, 0x00005B92, 0x00005DE7, 0x00000107, 0x000500AA, + 0x00000013, 0x000040CB, 0x00005B92, 0x00000B50, 0x0006000C, 0x0000001A, 0x00002C4D, 0x00000001, + 0x0000004B, 0x0000489E, 0x0004007C, 0x00000017, 0x00002A17, 0x00002C4D, 0x00050082, 0x00000017, + 0x0000187C, 0x00000107, 0x00002A17, 0x00050080, 0x00000017, 0x00002212, 0x00002A17, 0x00000A0F, + 0x000600A9, 0x00000017, 0x00002871, 0x000040CB, 0x00002212, 0x00005B92, 0x000500C4, 0x00000017, + 0x00005AD6, 0x0000489E, 0x0000187C, 0x000500C7, 0x00000017, 0x0000499C, 0x00005AD6, 0x000002D1, + 0x000600A9, 0x00000017, 0x00002A9F, 0x000040CB, 0x0000499C, 0x0000489E, 0x00050080, 0x00000017, + 0x00005FFB, 0x00002871, 0x0000022F, 0x000500C4, 0x00000017, 0x00004F81, 0x00005FFB, 0x00000467, + 0x000500C4, 0x00000017, 0x00003FA8, 0x00002A9F, 0x000002ED, 0x000500C5, 0x00000017, 0x0000577F, + 0x00004F81, 0x00003FA8, 0x000500AA, 0x00000013, 0x00003602, 0x00005DE7, 0x00000B50, 0x000600A9, + 0x00000017, 0x00004243, 0x00003602, 0x00000B50, 0x0000577F, 0x0004007C, 0x0000001D, 0x00003045, + 0x00004243, 0x000500C2, 0x00000017, 0x0000603F, 0x00002BCD, 0x000023B3, 0x000500C7, 0x00000017, + 0x00003922, 0x0000603F, 0x000003A1, 0x000500C7, 0x00000017, 0x0000489F, 0x00003922, 0x000002D1, + 0x000500C2, 0x00000017, 0x00005B93, 0x00003922, 0x00000107, 0x000500AA, 0x00000013, 0x000040CC, + 0x00005B93, 0x00000B50, 0x0006000C, 0x0000001A, 0x00002C4E, 0x00000001, 0x0000004B, 0x0000489F, + 0x0004007C, 0x00000017, 0x00002A18, 0x00002C4E, 0x00050082, 0x00000017, 0x0000187D, 0x00000107, + 0x00002A18, 0x00050080, 0x00000017, 0x00002213, 0x00002A18, 0x00000A0F, 0x000600A9, 0x00000017, + 0x00002872, 0x000040CC, 0x00002213, 0x00005B93, 0x000500C4, 0x00000017, 0x00005AD7, 0x0000489F, + 0x0000187D, 0x000500C7, 0x00000017, 0x0000499D, 0x00005AD7, 0x000002D1, 0x000600A9, 0x00000017, + 0x00002AA0, 0x000040CC, 0x0000499D, 0x0000489F, 0x00050080, 0x00000017, 0x00005FFC, 0x00002872, + 0x0000022F, 0x000500C4, 0x00000017, 0x00004F82, 0x00005FFC, 0x00000467, 0x000500C4, 0x00000017, + 0x00003FA9, 0x00002AA0, 0x000002ED, 0x000500C5, 0x00000017, 0x00005780, 0x00004F82, 0x00003FA9, + 0x000500AA, 0x00000013, 0x00003603, 0x00003922, 0x00000B50, 0x000600A9, 0x00000017, 0x00004658, + 0x00003603, 0x00000B50, 0x00005780, 0x0004007C, 0x0000001D, 0x0000593C, 0x00004658, 0x000200F9, + 0x00005BA6, 0x000200F8, 0x00003843, 0x000600A9, 0x0000000B, 0x00004C0A, 0x00001D59, 0x00000A46, + 0x00000A0A, 0x00070050, 0x00000017, 0x000023B4, 0x00004C0A, 0x00004C0A, 0x00004C0A, 0x00004C0A, + 0x000500C2, 0x00000017, 0x000056D5, 0x0000370D, 0x000023B4, 0x000500C7, 0x00000017, 0x00004A58, + 0x000056D5, 0x000003A1, 0x00040070, 0x0000001D, 0x00003F07, 0x00004A58, 0x0005008E, 0x0000001D, + 0x0000521C, 0x00003F07, 0x000006FE, 0x000500C2, 0x00000017, 0x00001E44, 0x00002BCD, 0x000023B4, + 0x000500C7, 0x00000017, 0x00002BD6, 0x00001E44, 0x000003A1, 0x00040070, 0x0000001D, 0x0000431C, + 0x00002BD6, 0x0005008E, 0x0000001D, 0x00003094, 0x0000431C, 0x000006FE, 0x000200F9, 0x00005BA6, + 0x000200F8, 0x00003E86, 0x000600A9, 0x0000000B, 0x00004C0B, 0x00001D59, 0x00000A3A, 0x00000A0A, + 0x00070050, 0x00000017, 0x000023B5, 0x00004C0B, 0x00004C0B, 0x00004C0B, 0x00004C0B, 0x000500C2, + 0x00000017, 0x000056D6, 0x0000370D, 0x000023B5, 0x000500C7, 0x00000017, 0x00004A59, 0x000056D6, + 0x0000064B, 0x00040070, 0x0000001D, 0x00003F08, 0x00004A59, 0x0005008E, 0x0000001D, 0x0000521D, + 0x00003F08, 0x0000017A, 0x000500C2, 0x00000017, 0x00001E45, 0x00002BCD, 0x000023B5, 0x000500C7, + 0x00000017, 0x00002BD7, 0x00001E45, 0x0000064B, 0x00040070, 0x0000001D, 0x0000431D, 0x00002BD7, + 0x0005008E, 0x0000001D, 0x00003095, 0x0000431D, 0x0000017A, 0x000200F9, 0x00005BA6, 0x000200F8, + 0x00006033, 0x0004007C, 0x0000001D, 0x00004B21, 0x0000370D, 0x0004007C, 0x0000001D, 0x000038B4, + 0x00002BCD, 0x000200F9, 0x00005BA6, 0x000200F8, 0x00005BA6, 0x000F00F5, 0x0000001D, 0x00002BF5, + 0x000038B4, 0x00006033, 0x00003095, 0x00003E86, 0x00003094, 0x00003843, 0x0000593C, 0x000059C0, + 0x00004364, 0x000052C8, 0x000048F8, 0x00002035, 0x000F00F5, 0x0000001D, 0x00003590, 0x00004B21, + 0x00006033, 0x0000521D, 0x00003E86, 0x0000521C, 0x00003843, 0x00003045, 0x000059C0, 0x00004982, + 0x000052C8, 0x00005EBB, 0x00002035, 0x000200F9, 0x00005310, 0x000200F8, 0x00005228, 0x000300F7, + 0x00005BA7, 0x00000000, 0x000700FB, 0x00002180, 0x000030EE, 0x00000005, 0x000052C9, 0x00000007, + 0x00002036, 0x000200F8, 0x00002036, 0x00050051, 0x0000000B, 0x00005F59, 0x0000370D, 0x00000000, + 0x0006000C, 0x00000015, 0x0000606A, 0x00000001, 0x0000003E, 0x00005F59, 0x00050051, 0x0000000D, + 0x000022A8, 0x0000606A, 0x00000000, 0x00050051, 0x0000000B, 0x00001DC1, 0x0000370D, 0x00000001, + 0x0006000C, 0x00000015, 0x00003D01, 0x00000001, 0x0000003E, 0x00001DC1, 0x00050051, 0x0000000D, + 0x000022A9, 0x00003D01, 0x00000000, 0x00050051, 0x0000000B, 0x00001DC2, 0x0000370D, 0x00000002, + 0x0006000C, 0x00000015, 0x00003D02, 0x00000001, 0x0000003E, 0x00001DC2, 0x00050051, 0x0000000D, + 0x000022AA, 0x00003D02, 0x00000000, 0x00050051, 0x0000000B, 0x00001DC3, 0x0000370D, 0x00000003, + 0x0006000C, 0x00000015, 0x00003CE8, 0x00000001, 0x0000003E, 0x00001DC3, 0x00050051, 0x0000000D, + 0x00002825, 0x00003CE8, 0x00000000, 0x00070050, 0x0000001D, 0x00005EBC, 0x000022A8, 0x000022A9, + 0x000022AA, 0x00002825, 0x00050051, 0x0000000B, 0x0000437D, 0x00002BCD, 0x00000000, 0x0006000C, + 0x00000015, 0x0000466E, 0x00000001, 0x0000003E, 0x0000437D, 0x00050051, 0x0000000D, 0x000022AB, + 0x0000466E, 0x00000000, 0x00050051, 0x0000000B, 0x00001DC4, 0x00002BCD, 0x00000001, 0x0006000C, + 0x00000015, 0x00003D03, 0x00000001, 0x0000003E, 0x00001DC4, 0x00050051, 0x0000000D, 0x000022AC, + 0x00003D03, 0x00000000, 0x00050051, 0x0000000B, 0x00001DC5, 0x00002BCD, 0x00000002, 0x0006000C, + 0x00000015, 0x00003D04, 0x00000001, 0x0000003E, 0x00001DC5, 0x00050051, 0x0000000D, 0x000022AD, + 0x00003D04, 0x00000000, 0x00050051, 0x0000000B, 0x00001DC6, 0x00002BCD, 0x00000003, 0x0006000C, + 0x00000015, 0x00003CE9, 0x00000001, 0x0000003E, 0x00001DC6, 0x00050051, 0x0000000D, 0x0000349D, + 0x00003CE9, 0x00000000, 0x00070050, 0x0000001D, 0x000048F9, 0x000022AB, 0x000022AC, 0x000022AD, + 0x0000349D, 0x000200F9, 0x00005BA7, 0x000200F8, 0x000052C9, 0x0004007C, 0x0000001A, 0x000060F7, + 0x0000370D, 0x000500C4, 0x0000001A, 0x00005821, 0x000060F7, 0x00000302, 0x000500C3, 0x0000001A, + 0x0000409E, 0x00005821, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA1, 0x0000409E, 0x0005008E, + 0x0000001D, 0x00004A7B, 0x00002AA1, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004983, 0x00000001, + 0x00000028, 0x00000504, 0x00004A7B, 0x0004007C, 0x0000001A, 0x000027E8, 0x00002BCD, 0x000500C4, + 0x0000001A, 0x000021A4, 0x000027E8, 0x00000302, 0x000500C3, 0x0000001A, 0x0000409F, 0x000021A4, + 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA2, 0x0000409F, 0x0005008E, 0x0000001D, 0x000053C2, + 0x00002AA2, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004365, 0x00000001, 0x00000028, 0x00000504, + 0x000053C2, 0x000200F9, 0x00005BA7, 0x000200F8, 0x000030EE, 0x0004007C, 0x0000001D, 0x00004B22, + 0x0000370D, 0x0004007C, 0x0000001D, 0x000038B5, 0x00002BCD, 0x000200F9, 0x00005BA7, 0x000200F8, + 0x00005BA7, 0x000900F5, 0x0000001D, 0x00002BF6, 0x000038B5, 0x000030EE, 0x00004365, 0x000052C9, + 0x000048F9, 0x00002036, 0x000900F5, 0x0000001D, 0x00003591, 0x00004B22, 0x000030EE, 0x00004983, + 0x000052C9, 0x00005EBC, 0x00002036, 0x000200F9, 0x00005310, 0x000200F8, 0x00005310, 0x000700F5, + 0x0000001D, 0x0000230B, 0x00002BF6, 0x00005BA7, 0x00002BF5, 0x00005BA6, 0x000700F5, 0x0000001D, + 0x00004C8A, 0x00003591, 0x00005BA7, 0x00003590, 0x00005BA6, 0x00050081, 0x0000001D, 0x000046B0, + 0x000036E3, 0x00004C8A, 0x00050081, 0x0000001D, 0x0000455A, 0x00002662, 0x0000230B, 0x000500AE, + 0x00000009, 0x0000387D, 0x00003F4C, 0x00000A1C, 0x000300F7, 0x00005EC8, 0x00000002, 0x000400FA, + 0x0000387D, 0x000026B1, 0x00005EC8, 0x000200F8, 0x000026B1, 0x000500C4, 0x0000000B, 0x000037B2, + 0x00000A0D, 0x000023AA, 0x00050085, 0x0000000D, 0x00002F3A, 0x00002B2C, 0x0000016E, 0x00050080, + 0x0000000B, 0x000051FC, 0x00005E7C, 0x000037B2, 0x000300F7, 0x00004F25, 0x00000002, 0x000400FA, + 0x000060B1, 0x00002623, 0x00002F63, 0x000200F8, 0x00002F63, 0x00060041, 0x00000288, 0x00004BD1, + 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, 0x00005D47, 0x00004BD1, 0x00050080, + 0x0000000B, 0x00002DB5, 0x000051FC, 0x000030F7, 0x00060041, 0x00000288, 0x0000194D, 0x00000CC7, + 0x00000A0B, 0x00002DB5, 0x0004003D, 0x0000000B, 0x00005E65, 0x0000194D, 0x00050084, 0x0000000B, + 0x00001864, 0x00000A10, 0x000030F7, 0x00050080, 0x0000000B, 0x000020AB, 0x000051FC, 0x00001864, + 0x00060041, 0x00000288, 0x00003BD5, 0x00000CC7, 0x00000A0B, 0x000020AB, 0x0004003D, 0x0000000B, + 0x00005E66, 0x00003BD5, 0x00050084, 0x0000000B, 0x00001865, 0x00000A13, 0x000030F7, 0x00050080, + 0x0000000B, 0x000020AC, 0x000051FC, 0x00001865, 0x00060041, 0x00000288, 0x000037F5, 0x00000CC7, + 0x00000A0B, 0x000020AC, 0x0004003D, 0x0000000B, 0x0000374E, 0x000037F5, 0x00070050, 0x00000017, + 0x00004CD8, 0x00005D47, 0x00005E65, 0x00005E66, 0x0000374E, 0x00050084, 0x0000000B, 0x0000429A, + 0x00000A16, 0x000030F7, 0x00050080, 0x0000000B, 0x000036A9, 0x000051FC, 0x0000429A, 0x00060041, + 0x00000288, 0x00003BD6, 0x00000CC7, 0x00000A0B, 0x000036A9, 0x0004003D, 0x0000000B, 0x00005E67, + 0x00003BD6, 0x00050084, 0x0000000B, 0x00001866, 0x00000A19, 0x000030F7, 0x00050080, 0x0000000B, + 0x000020AD, 0x000051FC, 0x00001866, 0x00060041, 0x00000288, 0x00003BD7, 0x00000CC7, 0x00000A0B, + 0x000020AD, 0x0004003D, 0x0000000B, 0x00005E68, 0x00003BD7, 0x00050084, 0x0000000B, 0x00001867, + 0x00000A1C, 0x000030F7, 0x00050080, 0x0000000B, 0x000020AE, 0x000051FC, 0x00001867, 0x00060041, + 0x00000288, 0x00003BD8, 0x00000CC7, 0x00000A0B, 0x000020AE, 0x0004003D, 0x0000000B, 0x00005E69, + 0x00003BD8, 0x00050084, 0x0000000B, 0x00001868, 0x00000A1F, 0x000030F7, 0x00050080, 0x0000000B, + 0x000020AF, 0x000051FC, 0x00001868, 0x00060041, 0x00000288, 0x000037F6, 0x00000CC7, 0x00000A0B, + 0x000020AF, 0x0004003D, 0x0000000B, 0x00004000, 0x000037F6, 0x00070050, 0x00000017, 0x00005130, + 0x00005E67, 0x00005E68, 0x00005E69, 0x00004000, 0x000200F9, 0x00004F25, 0x000200F8, 0x00002623, + 0x00060041, 0x00000288, 0x00005547, 0x00000CC7, 0x00000A0B, 0x000051FC, 0x0004003D, 0x0000000B, + 0x00005D4A, 0x00005547, 0x00050080, 0x0000000B, 0x00002DB6, 0x000051FC, 0x00000A0D, 0x00060041, + 0x00000288, 0x00001907, 0x00000CC7, 0x00000A0B, 0x00002DB6, 0x0004003D, 0x0000000B, 0x00005C6C, + 0x00001907, 0x00050080, 0x0000000B, 0x00002DB7, 0x000051FC, 0x00000A10, 0x00060041, 0x00000288, + 0x00001908, 0x00000CC7, 0x00000A0B, 0x00002DB7, 0x0004003D, 0x0000000B, 0x00005C6D, 0x00001908, + 0x00050080, 0x0000000B, 0x00002DB8, 0x000051FC, 0x00000A13, 0x00060041, 0x00000288, 0x00005FF2, + 0x00000CC7, 0x00000A0B, 0x00002DB8, 0x0004003D, 0x0000000B, 0x00003702, 0x00005FF2, 0x00070050, + 0x00000017, 0x00004ADF, 0x00005D4A, 0x00005C6C, 0x00005C6D, 0x00003702, 0x00050080, 0x0000000B, + 0x000057E7, 0x000051FC, 0x00000A16, 0x00060041, 0x00000288, 0x0000604D, 0x00000CC7, 0x00000A0B, + 0x000057E7, 0x0004003D, 0x0000000B, 0x00005C6E, 0x0000604D, 0x00050080, 0x0000000B, 0x00002DB9, + 0x000051FC, 0x00000A19, 0x00060041, 0x00000288, 0x00001909, 0x00000CC7, 0x00000A0B, 0x00002DB9, + 0x0004003D, 0x0000000B, 0x00005C6F, 0x00001909, 0x00050080, 0x0000000B, 0x00002DBA, 0x000051FC, + 0x00000A1C, 0x00060041, 0x00000288, 0x0000190A, 0x00000CC7, 0x00000A0B, 0x00002DBA, 0x0004003D, + 0x0000000B, 0x00005C70, 0x0000190A, 0x00050080, 0x0000000B, 0x00002DBB, 0x000051FC, 0x00000A1F, + 0x00060041, 0x00000288, 0x00005FF3, 0x00000CC7, 0x00000A0B, 0x00002DBB, 0x0004003D, 0x0000000B, + 0x00004001, 0x00005FF3, 0x00070050, 0x00000017, 0x00005131, 0x00005C6E, 0x00005C6F, 0x00005C70, + 0x00004001, 0x000200F9, 0x00004F25, 0x000200F8, 0x00004F25, 0x000700F5, 0x00000017, 0x00002BCE, + 0x00005131, 0x00002623, 0x00005130, 0x00002F63, 0x000700F5, 0x00000017, 0x0000370E, 0x00004ADF, + 0x00002623, 0x00004CD8, 0x00002F63, 0x000300F7, 0x00005311, 0x00000002, 0x000400FA, 0x000043D9, + 0x00005229, 0x00005781, 0x000200F8, 0x00005781, 0x000300F7, 0x00005BA8, 0x00000000, 0x001300FB, + 0x00002180, 0x00006034, 0x00000000, 0x00003E87, 0x00000001, 0x00003E87, 0x00000002, 0x00003844, + 0x0000000A, 0x00003844, 0x00000003, 0x000059C1, 0x0000000C, 0x000059C1, 0x00000004, 0x000052CA, + 0x00000006, 0x00002037, 0x000200F8, 0x00002037, 0x00050051, 0x0000000B, 0x00005F5A, 0x0000370E, + 0x00000000, 0x0006000C, 0x00000015, 0x0000606B, 0x00000001, 0x0000003E, 0x00005F5A, 0x00050051, + 0x0000000D, 0x000022AE, 0x0000606B, 0x00000000, 0x00050051, 0x0000000B, 0x00001DC7, 0x0000370E, + 0x00000001, 0x0006000C, 0x00000015, 0x00003D05, 0x00000001, 0x0000003E, 0x00001DC7, 0x00050051, + 0x0000000D, 0x000022AF, 0x00003D05, 0x00000000, 0x00050051, 0x0000000B, 0x00001DC8, 0x0000370E, + 0x00000002, 0x0006000C, 0x00000015, 0x00003D06, 0x00000001, 0x0000003E, 0x00001DC8, 0x00050051, + 0x0000000D, 0x000022B0, 0x00003D06, 0x00000000, 0x00050051, 0x0000000B, 0x00001DC9, 0x0000370E, + 0x00000003, 0x0006000C, 0x00000015, 0x00003CEA, 0x00000001, 0x0000003E, 0x00001DC9, 0x00050051, + 0x0000000D, 0x00002826, 0x00003CEA, 0x00000000, 0x00070050, 0x0000001D, 0x00005EBD, 0x000022AE, + 0x000022AF, 0x000022B0, 0x00002826, 0x00050051, 0x0000000B, 0x0000437E, 0x00002BCE, 0x00000000, + 0x0006000C, 0x00000015, 0x0000466F, 0x00000001, 0x0000003E, 0x0000437E, 0x00050051, 0x0000000D, + 0x000022B1, 0x0000466F, 0x00000000, 0x00050051, 0x0000000B, 0x00001DCA, 0x00002BCE, 0x00000001, + 0x0006000C, 0x00000015, 0x00003D07, 0x00000001, 0x0000003E, 0x00001DCA, 0x00050051, 0x0000000D, + 0x000022B2, 0x00003D07, 0x00000000, 0x00050051, 0x0000000B, 0x00001DCB, 0x00002BCE, 0x00000002, + 0x0006000C, 0x00000015, 0x00003D08, 0x00000001, 0x0000003E, 0x00001DCB, 0x00050051, 0x0000000D, + 0x000022B3, 0x00003D08, 0x00000000, 0x00050051, 0x0000000B, 0x00001DCC, 0x00002BCE, 0x00000003, + 0x0006000C, 0x00000015, 0x00003CEB, 0x00000001, 0x0000003E, 0x00001DCC, 0x00050051, 0x0000000D, + 0x0000349E, 0x00003CEB, 0x00000000, 0x00070050, 0x0000001D, 0x000048FA, 0x000022B1, 0x000022B2, + 0x000022B3, 0x0000349E, 0x000200F9, 0x00005BA8, 0x000200F8, 0x000052CA, 0x0004007C, 0x0000001A, + 0x000060F8, 0x0000370E, 0x000500C4, 0x0000001A, 0x00005822, 0x000060F8, 0x00000302, 0x000500C3, + 0x0000001A, 0x000040A0, 0x00005822, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA3, 0x000040A0, + 0x0005008E, 0x0000001D, 0x00004A7C, 0x00002AA3, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004984, + 0x00000001, 0x00000028, 0x00000504, 0x00004A7C, 0x0004007C, 0x0000001A, 0x000027E9, 0x00002BCE, + 0x000500C4, 0x0000001A, 0x000021A5, 0x000027E9, 0x00000302, 0x000500C3, 0x0000001A, 0x000040A1, + 0x000021A5, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA4, 0x000040A1, 0x0005008E, 0x0000001D, + 0x000053C3, 0x00002AA4, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004366, 0x00000001, 0x00000028, + 0x00000504, 0x000053C3, 0x000200F9, 0x00005BA8, 0x000200F8, 0x000059C1, 0x000600A9, 0x0000000B, + 0x00004C0C, 0x00001D59, 0x00000A46, 0x00000A0A, 0x00070050, 0x00000017, 0x000023B6, 0x00004C0C, + 0x00004C0C, 0x00004C0C, 0x00004C0C, 0x000500C2, 0x00000017, 0x00005D4B, 0x0000370E, 0x000023B6, + 0x000500C7, 0x00000017, 0x00005DE8, 0x00005D4B, 0x000003A1, 0x000500C7, 0x00000017, 0x000048A0, + 0x00005DE8, 0x000002D1, 0x000500C2, 0x00000017, 0x00005B94, 0x00005DE8, 0x00000107, 0x000500AA, + 0x00000013, 0x000040CD, 0x00005B94, 0x00000B50, 0x0006000C, 0x0000001A, 0x00002C4F, 0x00000001, + 0x0000004B, 0x000048A0, 0x0004007C, 0x00000017, 0x00002A19, 0x00002C4F, 0x00050082, 0x00000017, + 0x0000187E, 0x00000107, 0x00002A19, 0x00050080, 0x00000017, 0x00002214, 0x00002A19, 0x00000A0F, + 0x000600A9, 0x00000017, 0x00002873, 0x000040CD, 0x00002214, 0x00005B94, 0x000500C4, 0x00000017, + 0x00005AD8, 0x000048A0, 0x0000187E, 0x000500C7, 0x00000017, 0x0000499E, 0x00005AD8, 0x000002D1, + 0x000600A9, 0x00000017, 0x00002AA5, 0x000040CD, 0x0000499E, 0x000048A0, 0x00050080, 0x00000017, + 0x00005FFD, 0x00002873, 0x0000022F, 0x000500C4, 0x00000017, 0x00004F83, 0x00005FFD, 0x00000467, + 0x000500C4, 0x00000017, 0x00003FAA, 0x00002AA5, 0x000002ED, 0x000500C5, 0x00000017, 0x00005782, + 0x00004F83, 0x00003FAA, 0x000500AA, 0x00000013, 0x00003604, 0x00005DE8, 0x00000B50, 0x000600A9, + 0x00000017, 0x00004244, 0x00003604, 0x00000B50, 0x00005782, 0x0004007C, 0x0000001D, 0x00003046, + 0x00004244, 0x000500C2, 0x00000017, 0x00006040, 0x00002BCE, 0x000023B6, 0x000500C7, 0x00000017, + 0x00003923, 0x00006040, 0x000003A1, 0x000500C7, 0x00000017, 0x000048A1, 0x00003923, 0x000002D1, + 0x000500C2, 0x00000017, 0x00005B95, 0x00003923, 0x00000107, 0x000500AA, 0x00000013, 0x000040CE, + 0x00005B95, 0x00000B50, 0x0006000C, 0x0000001A, 0x00002C50, 0x00000001, 0x0000004B, 0x000048A1, + 0x0004007C, 0x00000017, 0x00002A1A, 0x00002C50, 0x00050082, 0x00000017, 0x0000187F, 0x00000107, + 0x00002A1A, 0x00050080, 0x00000017, 0x00002215, 0x00002A1A, 0x00000A0F, 0x000600A9, 0x00000017, + 0x00002874, 0x000040CE, 0x00002215, 0x00005B95, 0x000500C4, 0x00000017, 0x00005AD9, 0x000048A1, + 0x0000187F, 0x000500C7, 0x00000017, 0x0000499F, 0x00005AD9, 0x000002D1, 0x000600A9, 0x00000017, + 0x00002AA6, 0x000040CE, 0x0000499F, 0x000048A1, 0x00050080, 0x00000017, 0x00005FFE, 0x00002874, + 0x0000022F, 0x000500C4, 0x00000017, 0x00004F84, 0x00005FFE, 0x00000467, 0x000500C4, 0x00000017, + 0x00003FAB, 0x00002AA6, 0x000002ED, 0x000500C5, 0x00000017, 0x00005783, 0x00004F84, 0x00003FAB, + 0x000500AA, 0x00000013, 0x00003605, 0x00003923, 0x00000B50, 0x000600A9, 0x00000017, 0x00004659, + 0x00003605, 0x00000B50, 0x00005783, 0x0004007C, 0x0000001D, 0x0000593D, 0x00004659, 0x000200F9, + 0x00005BA8, 0x000200F8, 0x00003844, 0x000600A9, 0x0000000B, 0x00004C0D, 0x00001D59, 0x00000A46, + 0x00000A0A, 0x00070050, 0x00000017, 0x000023B7, 0x00004C0D, 0x00004C0D, 0x00004C0D, 0x00004C0D, + 0x000500C2, 0x00000017, 0x000056D7, 0x0000370E, 0x000023B7, 0x000500C7, 0x00000017, 0x00004A5A, + 0x000056D7, 0x000003A1, 0x00040070, 0x0000001D, 0x00003F09, 0x00004A5A, 0x0005008E, 0x0000001D, + 0x0000521E, 0x00003F09, 0x000006FE, 0x000500C2, 0x00000017, 0x00001E46, 0x00002BCE, 0x000023B7, + 0x000500C7, 0x00000017, 0x00002BD8, 0x00001E46, 0x000003A1, 0x00040070, 0x0000001D, 0x0000431E, + 0x00002BD8, 0x0005008E, 0x0000001D, 0x00003096, 0x0000431E, 0x000006FE, 0x000200F9, 0x00005BA8, + 0x000200F8, 0x00003E87, 0x000600A9, 0x0000000B, 0x00004C0E, 0x00001D59, 0x00000A3A, 0x00000A0A, + 0x00070050, 0x00000017, 0x000023B8, 0x00004C0E, 0x00004C0E, 0x00004C0E, 0x00004C0E, 0x000500C2, + 0x00000017, 0x000056D8, 0x0000370E, 0x000023B8, 0x000500C7, 0x00000017, 0x00004A5B, 0x000056D8, + 0x0000064B, 0x00040070, 0x0000001D, 0x00003F0A, 0x00004A5B, 0x0005008E, 0x0000001D, 0x0000521F, + 0x00003F0A, 0x0000017A, 0x000500C2, 0x00000017, 0x00001E47, 0x00002BCE, 0x000023B8, 0x000500C7, + 0x00000017, 0x00002BD9, 0x00001E47, 0x0000064B, 0x00040070, 0x0000001D, 0x0000431F, 0x00002BD9, + 0x0005008E, 0x0000001D, 0x00003097, 0x0000431F, 0x0000017A, 0x000200F9, 0x00005BA8, 0x000200F8, + 0x00006034, 0x0004007C, 0x0000001D, 0x00004B23, 0x0000370E, 0x0004007C, 0x0000001D, 0x000038B6, + 0x00002BCE, 0x000200F9, 0x00005BA8, 0x000200F8, 0x00005BA8, 0x000F00F5, 0x0000001D, 0x00002BF7, + 0x000038B6, 0x00006034, 0x00003097, 0x00003E87, 0x00003096, 0x00003844, 0x0000593D, 0x000059C1, + 0x00004366, 0x000052CA, 0x000048FA, 0x00002037, 0x000F00F5, 0x0000001D, 0x00003592, 0x00004B23, + 0x00006034, 0x0000521F, 0x00003E87, 0x0000521E, 0x00003844, 0x00003046, 0x000059C1, 0x00004984, + 0x000052CA, 0x00005EBD, 0x00002037, 0x000200F9, 0x00005311, 0x000200F8, 0x00005229, 0x000300F7, + 0x00005BA9, 0x00000000, 0x000700FB, 0x00002180, 0x000030EF, 0x00000005, 0x000052CB, 0x00000007, + 0x00002038, 0x000200F8, 0x00002038, 0x00050051, 0x0000000B, 0x00005F5B, 0x0000370E, 0x00000000, + 0x0006000C, 0x00000015, 0x0000606C, 0x00000001, 0x0000003E, 0x00005F5B, 0x00050051, 0x0000000D, + 0x000022B4, 0x0000606C, 0x00000000, 0x00050051, 0x0000000B, 0x00001DCD, 0x0000370E, 0x00000001, + 0x0006000C, 0x00000015, 0x00003D09, 0x00000001, 0x0000003E, 0x00001DCD, 0x00050051, 0x0000000D, + 0x000022B5, 0x00003D09, 0x00000000, 0x00050051, 0x0000000B, 0x00001DCE, 0x0000370E, 0x00000002, + 0x0006000C, 0x00000015, 0x00003D0A, 0x00000001, 0x0000003E, 0x00001DCE, 0x00050051, 0x0000000D, + 0x000022B6, 0x00003D0A, 0x00000000, 0x00050051, 0x0000000B, 0x00001DCF, 0x0000370E, 0x00000003, + 0x0006000C, 0x00000015, 0x00003CEC, 0x00000001, 0x0000003E, 0x00001DCF, 0x00050051, 0x0000000D, + 0x00002827, 0x00003CEC, 0x00000000, 0x00070050, 0x0000001D, 0x00005EBE, 0x000022B4, 0x000022B5, + 0x000022B6, 0x00002827, 0x00050051, 0x0000000B, 0x0000437F, 0x00002BCE, 0x00000000, 0x0006000C, + 0x00000015, 0x00004670, 0x00000001, 0x0000003E, 0x0000437F, 0x00050051, 0x0000000D, 0x000022B7, + 0x00004670, 0x00000000, 0x00050051, 0x0000000B, 0x00001DD0, 0x00002BCE, 0x00000001, 0x0006000C, + 0x00000015, 0x00003D0C, 0x00000001, 0x0000003E, 0x00001DD0, 0x00050051, 0x0000000D, 0x000022B8, + 0x00003D0C, 0x00000000, 0x00050051, 0x0000000B, 0x00001DD1, 0x00002BCE, 0x00000002, 0x0006000C, + 0x00000015, 0x00003D0D, 0x00000001, 0x0000003E, 0x00001DD1, 0x00050051, 0x0000000D, 0x000022B9, + 0x00003D0D, 0x00000000, 0x00050051, 0x0000000B, 0x00001DD2, 0x00002BCE, 0x00000003, 0x0006000C, + 0x00000015, 0x00003CED, 0x00000001, 0x0000003E, 0x00001DD2, 0x00050051, 0x0000000D, 0x0000349F, + 0x00003CED, 0x00000000, 0x00070050, 0x0000001D, 0x000048FB, 0x000022B7, 0x000022B8, 0x000022B9, + 0x0000349F, 0x000200F9, 0x00005BA9, 0x000200F8, 0x000052CB, 0x0004007C, 0x0000001A, 0x000060F9, + 0x0000370E, 0x000500C4, 0x0000001A, 0x00005823, 0x000060F9, 0x00000302, 0x000500C3, 0x0000001A, + 0x000040A2, 0x00005823, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA7, 0x000040A2, 0x0005008E, + 0x0000001D, 0x00004A7D, 0x00002AA7, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004985, 0x00000001, + 0x00000028, 0x00000504, 0x00004A7D, 0x0004007C, 0x0000001A, 0x000027EA, 0x00002BCE, 0x000500C4, + 0x0000001A, 0x000021A6, 0x000027EA, 0x00000302, 0x000500C3, 0x0000001A, 0x000040A3, 0x000021A6, + 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA8, 0x000040A3, 0x0005008E, 0x0000001D, 0x000053C4, + 0x00002AA8, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004367, 0x00000001, 0x00000028, 0x00000504, + 0x000053C4, 0x000200F9, 0x00005BA9, 0x000200F8, 0x000030EF, 0x0004007C, 0x0000001D, 0x00004B24, + 0x0000370E, 0x0004007C, 0x0000001D, 0x000038B7, 0x00002BCE, 0x000200F9, 0x00005BA9, 0x000200F8, + 0x00005BA9, 0x000900F5, 0x0000001D, 0x00002BF8, 0x000038B7, 0x000030EF, 0x00004367, 0x000052CB, + 0x000048FB, 0x00002038, 0x000900F5, 0x0000001D, 0x00003593, 0x00004B24, 0x000030EF, 0x00004985, + 0x000052CB, 0x00005EBE, 0x00002038, 0x000200F9, 0x00005311, 0x000200F8, 0x00005311, 0x000700F5, + 0x0000001D, 0x0000230C, 0x00002BF8, 0x00005BA9, 0x00002BF7, 0x00005BA8, 0x000700F5, 0x0000001D, + 0x00004C8B, 0x00003593, 0x00005BA9, 0x00003592, 0x00005BA8, 0x00050081, 0x0000001D, 0x00004346, + 0x000046B0, 0x00004C8B, 0x00050081, 0x0000001D, 0x000019F1, 0x0000455A, 0x0000230C, 0x00050080, + 0x0000000B, 0x00003FF8, 0x00001FB2, 0x000037B2, 0x000300F7, 0x00004F26, 0x00000002, 0x000400FA, + 0x000060B1, 0x00002624, 0x00002F64, 0x000200F8, 0x00002F64, 0x00060041, 0x00000288, 0x00004BD2, + 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, 0x00005D4C, 0x00004BD2, 0x00050080, + 0x0000000B, 0x00002DBC, 0x00003FF8, 0x000030F7, 0x00060041, 0x00000288, 0x0000194E, 0x00000CC7, + 0x00000A0B, 0x00002DBC, 0x0004003D, 0x0000000B, 0x00005E6A, 0x0000194E, 0x00050084, 0x0000000B, + 0x00001869, 0x00000A10, 0x000030F7, 0x00050080, 0x0000000B, 0x000020B0, 0x00003FF8, 0x00001869, + 0x00060041, 0x00000288, 0x00003BD9, 0x00000CC7, 0x00000A0B, 0x000020B0, 0x0004003D, 0x0000000B, + 0x00005E6B, 0x00003BD9, 0x00050084, 0x0000000B, 0x0000186A, 0x00000A13, 0x000030F7, 0x00050080, + 0x0000000B, 0x000020B1, 0x00003FF8, 0x0000186A, 0x00060041, 0x00000288, 0x000037F7, 0x00000CC7, + 0x00000A0B, 0x000020B1, 0x0004003D, 0x0000000B, 0x0000374F, 0x000037F7, 0x00070050, 0x00000017, + 0x00004CD9, 0x00005D4C, 0x00005E6A, 0x00005E6B, 0x0000374F, 0x00050084, 0x0000000B, 0x0000429B, + 0x00000A16, 0x000030F7, 0x00050080, 0x0000000B, 0x000036AA, 0x00003FF8, 0x0000429B, 0x00060041, + 0x00000288, 0x00003BDA, 0x00000CC7, 0x00000A0B, 0x000036AA, 0x0004003D, 0x0000000B, 0x00005E6C, + 0x00003BDA, 0x00050084, 0x0000000B, 0x0000186B, 0x00000A19, 0x000030F7, 0x00050080, 0x0000000B, + 0x000020B2, 0x00003FF8, 0x0000186B, 0x00060041, 0x00000288, 0x00003BDB, 0x00000CC7, 0x00000A0B, + 0x000020B2, 0x0004003D, 0x0000000B, 0x00005E6D, 0x00003BDB, 0x00050084, 0x0000000B, 0x0000186C, + 0x00000A1C, 0x000030F7, 0x00050080, 0x0000000B, 0x000020B3, 0x00003FF8, 0x0000186C, 0x00060041, + 0x00000288, 0x00003BDC, 0x00000CC7, 0x00000A0B, 0x000020B3, 0x0004003D, 0x0000000B, 0x00005E6E, + 0x00003BDC, 0x00050084, 0x0000000B, 0x0000186D, 0x00000A1F, 0x000030F7, 0x00050080, 0x0000000B, + 0x000020B4, 0x00003FF8, 0x0000186D, 0x00060041, 0x00000288, 0x000037F8, 0x00000CC7, 0x00000A0B, + 0x000020B4, 0x0004003D, 0x0000000B, 0x00004002, 0x000037F8, 0x00070050, 0x00000017, 0x00005132, + 0x00005E6C, 0x00005E6D, 0x00005E6E, 0x00004002, 0x000200F9, 0x00004F26, 0x000200F8, 0x00002624, + 0x00060041, 0x00000288, 0x00005548, 0x00000CC7, 0x00000A0B, 0x00003FF8, 0x0004003D, 0x0000000B, + 0x00005D4D, 0x00005548, 0x00050080, 0x0000000B, 0x00002DBD, 0x00003FF8, 0x00000A0D, 0x00060041, + 0x00000288, 0x0000190B, 0x00000CC7, 0x00000A0B, 0x00002DBD, 0x0004003D, 0x0000000B, 0x00005C71, + 0x0000190B, 0x00050080, 0x0000000B, 0x00002DBE, 0x00003FF8, 0x00000A10, 0x00060041, 0x00000288, + 0x0000190C, 0x00000CC7, 0x00000A0B, 0x00002DBE, 0x0004003D, 0x0000000B, 0x00005C72, 0x0000190C, + 0x00050080, 0x0000000B, 0x00002DBF, 0x00003FF8, 0x00000A13, 0x00060041, 0x00000288, 0x00005FF4, + 0x00000CC7, 0x00000A0B, 0x00002DBF, 0x0004003D, 0x0000000B, 0x00003703, 0x00005FF4, 0x00070050, + 0x00000017, 0x00004AE0, 0x00005D4D, 0x00005C71, 0x00005C72, 0x00003703, 0x00050080, 0x0000000B, + 0x000057E8, 0x00003FF8, 0x00000A16, 0x00060041, 0x00000288, 0x0000604E, 0x00000CC7, 0x00000A0B, + 0x000057E8, 0x0004003D, 0x0000000B, 0x00005C73, 0x0000604E, 0x00050080, 0x0000000B, 0x00002DC0, + 0x00003FF8, 0x00000A19, 0x00060041, 0x00000288, 0x0000190D, 0x00000CC7, 0x00000A0B, 0x00002DC0, + 0x0004003D, 0x0000000B, 0x00005C74, 0x0000190D, 0x00050080, 0x0000000B, 0x00002DC1, 0x00003FF8, + 0x00000A1C, 0x00060041, 0x00000288, 0x0000190E, 0x00000CC7, 0x00000A0B, 0x00002DC1, 0x0004003D, + 0x0000000B, 0x00005C75, 0x0000190E, 0x00050080, 0x0000000B, 0x00002DC2, 0x00003FF8, 0x00000A1F, + 0x00060041, 0x00000288, 0x00005FF5, 0x00000CC7, 0x00000A0B, 0x00002DC2, 0x0004003D, 0x0000000B, + 0x00004003, 0x00005FF5, 0x00070050, 0x00000017, 0x00005133, 0x00005C73, 0x00005C74, 0x00005C75, + 0x00004003, 0x000200F9, 0x00004F26, 0x000200F8, 0x00004F26, 0x000700F5, 0x00000017, 0x00002BCF, + 0x00005133, 0x00002624, 0x00005132, 0x00002F64, 0x000700F5, 0x00000017, 0x0000370F, 0x00004AE0, + 0x00002624, 0x00004CD9, 0x00002F64, 0x000300F7, 0x00005312, 0x00000002, 0x000400FA, 0x000043D9, + 0x0000522A, 0x00005784, 0x000200F8, 0x00005784, 0x000300F7, 0x00005BAA, 0x00000000, 0x001300FB, + 0x00002180, 0x00006035, 0x00000000, 0x00003E88, 0x00000001, 0x00003E88, 0x00000002, 0x00003845, + 0x0000000A, 0x00003845, 0x00000003, 0x000059C2, 0x0000000C, 0x000059C2, 0x00000004, 0x000052CC, + 0x00000006, 0x00002039, 0x000200F8, 0x00002039, 0x00050051, 0x0000000B, 0x00005F5C, 0x0000370F, + 0x00000000, 0x0006000C, 0x00000015, 0x0000606D, 0x00000001, 0x0000003E, 0x00005F5C, 0x00050051, + 0x0000000D, 0x000022BA, 0x0000606D, 0x00000000, 0x00050051, 0x0000000B, 0x00001DD3, 0x0000370F, + 0x00000001, 0x0006000C, 0x00000015, 0x00003D0E, 0x00000001, 0x0000003E, 0x00001DD3, 0x00050051, + 0x0000000D, 0x000022BB, 0x00003D0E, 0x00000000, 0x00050051, 0x0000000B, 0x00001DD4, 0x0000370F, + 0x00000002, 0x0006000C, 0x00000015, 0x00003D0F, 0x00000001, 0x0000003E, 0x00001DD4, 0x00050051, + 0x0000000D, 0x000022BC, 0x00003D0F, 0x00000000, 0x00050051, 0x0000000B, 0x00001DD5, 0x0000370F, + 0x00000003, 0x0006000C, 0x00000015, 0x00003CEE, 0x00000001, 0x0000003E, 0x00001DD5, 0x00050051, + 0x0000000D, 0x00002828, 0x00003CEE, 0x00000000, 0x00070050, 0x0000001D, 0x00005EBF, 0x000022BA, + 0x000022BB, 0x000022BC, 0x00002828, 0x00050051, 0x0000000B, 0x00004380, 0x00002BCF, 0x00000000, + 0x0006000C, 0x00000015, 0x00004671, 0x00000001, 0x0000003E, 0x00004380, 0x00050051, 0x0000000D, + 0x000022BD, 0x00004671, 0x00000000, 0x00050051, 0x0000000B, 0x00001DD6, 0x00002BCF, 0x00000001, + 0x0006000C, 0x00000015, 0x00003D10, 0x00000001, 0x0000003E, 0x00001DD6, 0x00050051, 0x0000000D, + 0x000022BE, 0x00003D10, 0x00000000, 0x00050051, 0x0000000B, 0x00001DD7, 0x00002BCF, 0x00000002, + 0x0006000C, 0x00000015, 0x00003D11, 0x00000001, 0x0000003E, 0x00001DD7, 0x00050051, 0x0000000D, + 0x000022BF, 0x00003D11, 0x00000000, 0x00050051, 0x0000000B, 0x00001DD8, 0x00002BCF, 0x00000003, + 0x0006000C, 0x00000015, 0x00003CEF, 0x00000001, 0x0000003E, 0x00001DD8, 0x00050051, 0x0000000D, + 0x000034A0, 0x00003CEF, 0x00000000, 0x00070050, 0x0000001D, 0x000048FC, 0x000022BD, 0x000022BE, + 0x000022BF, 0x000034A0, 0x000200F9, 0x00005BAA, 0x000200F8, 0x000052CC, 0x0004007C, 0x0000001A, + 0x000060FA, 0x0000370F, 0x000500C4, 0x0000001A, 0x00005824, 0x000060FA, 0x00000302, 0x000500C3, + 0x0000001A, 0x000040A4, 0x00005824, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AA9, 0x000040A4, + 0x0005008E, 0x0000001D, 0x00004A7E, 0x00002AA9, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004986, + 0x00000001, 0x00000028, 0x00000504, 0x00004A7E, 0x0004007C, 0x0000001A, 0x000027EB, 0x00002BCF, + 0x000500C4, 0x0000001A, 0x000021A7, 0x000027EB, 0x00000302, 0x000500C3, 0x0000001A, 0x000040A5, + 0x000021A7, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AAA, 0x000040A5, 0x0005008E, 0x0000001D, + 0x000053C5, 0x00002AAA, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004368, 0x00000001, 0x00000028, + 0x00000504, 0x000053C5, 0x000200F9, 0x00005BAA, 0x000200F8, 0x000059C2, 0x000600A9, 0x0000000B, + 0x00004C0F, 0x00001D59, 0x00000A46, 0x00000A0A, 0x00070050, 0x00000017, 0x000023B9, 0x00004C0F, + 0x00004C0F, 0x00004C0F, 0x00004C0F, 0x000500C2, 0x00000017, 0x00005D4E, 0x0000370F, 0x000023B9, + 0x000500C7, 0x00000017, 0x00005DE9, 0x00005D4E, 0x000003A1, 0x000500C7, 0x00000017, 0x000048A2, + 0x00005DE9, 0x000002D1, 0x000500C2, 0x00000017, 0x00005B96, 0x00005DE9, 0x00000107, 0x000500AA, + 0x00000013, 0x000040CF, 0x00005B96, 0x00000B50, 0x0006000C, 0x0000001A, 0x00002C51, 0x00000001, + 0x0000004B, 0x000048A2, 0x0004007C, 0x00000017, 0x00002A1B, 0x00002C51, 0x00050082, 0x00000017, + 0x00001880, 0x00000107, 0x00002A1B, 0x00050080, 0x00000017, 0x00002216, 0x00002A1B, 0x00000A0F, + 0x000600A9, 0x00000017, 0x00002875, 0x000040CF, 0x00002216, 0x00005B96, 0x000500C4, 0x00000017, + 0x00005ADA, 0x000048A2, 0x00001880, 0x000500C7, 0x00000017, 0x000049A0, 0x00005ADA, 0x000002D1, + 0x000600A9, 0x00000017, 0x00002AAB, 0x000040CF, 0x000049A0, 0x000048A2, 0x00050080, 0x00000017, + 0x00005FFF, 0x00002875, 0x0000022F, 0x000500C4, 0x00000017, 0x00004F85, 0x00005FFF, 0x00000467, + 0x000500C4, 0x00000017, 0x00003FAC, 0x00002AAB, 0x000002ED, 0x000500C5, 0x00000017, 0x00005785, + 0x00004F85, 0x00003FAC, 0x000500AA, 0x00000013, 0x00003606, 0x00005DE9, 0x00000B50, 0x000600A9, + 0x00000017, 0x00004245, 0x00003606, 0x00000B50, 0x00005785, 0x0004007C, 0x0000001D, 0x00003047, + 0x00004245, 0x000500C2, 0x00000017, 0x00006041, 0x00002BCF, 0x000023B9, 0x000500C7, 0x00000017, + 0x00003924, 0x00006041, 0x000003A1, 0x000500C7, 0x00000017, 0x000048A3, 0x00003924, 0x000002D1, + 0x000500C2, 0x00000017, 0x00005B97, 0x00003924, 0x00000107, 0x000500AA, 0x00000013, 0x000040D0, + 0x00005B97, 0x00000B50, 0x0006000C, 0x0000001A, 0x00002C52, 0x00000001, 0x0000004B, 0x000048A3, + 0x0004007C, 0x00000017, 0x00002A1C, 0x00002C52, 0x00050082, 0x00000017, 0x00001881, 0x00000107, + 0x00002A1C, 0x00050080, 0x00000017, 0x00002217, 0x00002A1C, 0x00000A0F, 0x000600A9, 0x00000017, + 0x00002876, 0x000040D0, 0x00002217, 0x00005B97, 0x000500C4, 0x00000017, 0x00005ADB, 0x000048A3, + 0x00001881, 0x000500C7, 0x00000017, 0x000049A1, 0x00005ADB, 0x000002D1, 0x000600A9, 0x00000017, + 0x00002AAC, 0x000040D0, 0x000049A1, 0x000048A3, 0x00050080, 0x00000017, 0x00006000, 0x00002876, + 0x0000022F, 0x000500C4, 0x00000017, 0x00004F86, 0x00006000, 0x00000467, 0x000500C4, 0x00000017, + 0x00003FAD, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x00005786, 0x00004F86, 0x00003FAD, + 0x000500AA, 0x00000013, 0x00003607, 0x00003924, 0x00000B50, 0x000600A9, 0x00000017, 0x0000465A, + 0x00003607, 0x00000B50, 0x00005786, 0x0004007C, 0x0000001D, 0x0000593E, 0x0000465A, 0x000200F9, + 0x00005BAA, 0x000200F8, 0x00003845, 0x000600A9, 0x0000000B, 0x00004C10, 0x00001D59, 0x00000A46, + 0x00000A0A, 0x00070050, 0x00000017, 0x000023BA, 0x00004C10, 0x00004C10, 0x00004C10, 0x00004C10, + 0x000500C2, 0x00000017, 0x000056D9, 0x0000370F, 0x000023BA, 0x000500C7, 0x00000017, 0x00004A5C, + 0x000056D9, 0x000003A1, 0x00040070, 0x0000001D, 0x00003F0B, 0x00004A5C, 0x0005008E, 0x0000001D, + 0x00005220, 0x00003F0B, 0x000006FE, 0x000500C2, 0x00000017, 0x00001E48, 0x00002BCF, 0x000023BA, + 0x000500C7, 0x00000017, 0x00002BDA, 0x00001E48, 0x000003A1, 0x00040070, 0x0000001D, 0x00004320, + 0x00002BDA, 0x0005008E, 0x0000001D, 0x00003098, 0x00004320, 0x000006FE, 0x000200F9, 0x00005BAA, + 0x000200F8, 0x00003E88, 0x000600A9, 0x0000000B, 0x00004C11, 0x00001D59, 0x00000A3A, 0x00000A0A, + 0x00070050, 0x00000017, 0x000023BB, 0x00004C11, 0x00004C11, 0x00004C11, 0x00004C11, 0x000500C2, + 0x00000017, 0x000056DA, 0x0000370F, 0x000023BB, 0x000500C7, 0x00000017, 0x00004A5D, 0x000056DA, + 0x0000064B, 0x00040070, 0x0000001D, 0x00003F0C, 0x00004A5D, 0x0005008E, 0x0000001D, 0x00005221, + 0x00003F0C, 0x0000017A, 0x000500C2, 0x00000017, 0x00001E49, 0x00002BCF, 0x000023BB, 0x000500C7, + 0x00000017, 0x00002BDB, 0x00001E49, 0x0000064B, 0x00040070, 0x0000001D, 0x00004321, 0x00002BDB, + 0x0005008E, 0x0000001D, 0x00003099, 0x00004321, 0x0000017A, 0x000200F9, 0x00005BAA, 0x000200F8, + 0x00006035, 0x0004007C, 0x0000001D, 0x00004B25, 0x0000370F, 0x0004007C, 0x0000001D, 0x000038B8, + 0x00002BCF, 0x000200F9, 0x00005BAA, 0x000200F8, 0x00005BAA, 0x000F00F5, 0x0000001D, 0x00002BF9, + 0x000038B8, 0x00006035, 0x00003099, 0x00003E88, 0x00003098, 0x00003845, 0x0000593E, 0x000059C2, + 0x00004368, 0x000052CC, 0x000048FC, 0x00002039, 0x000F00F5, 0x0000001D, 0x00003594, 0x00004B25, + 0x00006035, 0x00005221, 0x00003E88, 0x00005220, 0x00003845, 0x00003047, 0x000059C2, 0x00004986, + 0x000052CC, 0x00005EBF, 0x00002039, 0x000200F9, 0x00005312, 0x000200F8, 0x0000522A, 0x000300F7, + 0x00005BAB, 0x00000000, 0x000700FB, 0x00002180, 0x000030F0, 0x00000005, 0x000052CD, 0x00000007, + 0x0000203A, 0x000200F8, 0x0000203A, 0x00050051, 0x0000000B, 0x00005F5D, 0x0000370F, 0x00000000, + 0x0006000C, 0x00000015, 0x0000606E, 0x00000001, 0x0000003E, 0x00005F5D, 0x00050051, 0x0000000D, + 0x000022C0, 0x0000606E, 0x00000000, 0x00050051, 0x0000000B, 0x00001DD9, 0x0000370F, 0x00000001, + 0x0006000C, 0x00000015, 0x00003D12, 0x00000001, 0x0000003E, 0x00001DD9, 0x00050051, 0x0000000D, + 0x000022C1, 0x00003D12, 0x00000000, 0x00050051, 0x0000000B, 0x00001DDA, 0x0000370F, 0x00000002, + 0x0006000C, 0x00000015, 0x00003D13, 0x00000001, 0x0000003E, 0x00001DDA, 0x00050051, 0x0000000D, + 0x000022C2, 0x00003D13, 0x00000000, 0x00050051, 0x0000000B, 0x00001DDB, 0x0000370F, 0x00000003, + 0x0006000C, 0x00000015, 0x00003CF0, 0x00000001, 0x0000003E, 0x00001DDB, 0x00050051, 0x0000000D, + 0x00002829, 0x00003CF0, 0x00000000, 0x00070050, 0x0000001D, 0x00005EC0, 0x000022C0, 0x000022C1, + 0x000022C2, 0x00002829, 0x00050051, 0x0000000B, 0x00004381, 0x00002BCF, 0x00000000, 0x0006000C, + 0x00000015, 0x00004672, 0x00000001, 0x0000003E, 0x00004381, 0x00050051, 0x0000000D, 0x000022C3, + 0x00004672, 0x00000000, 0x00050051, 0x0000000B, 0x00001DDC, 0x00002BCF, 0x00000001, 0x0006000C, + 0x00000015, 0x00003D14, 0x00000001, 0x0000003E, 0x00001DDC, 0x00050051, 0x0000000D, 0x000022C4, + 0x00003D14, 0x00000000, 0x00050051, 0x0000000B, 0x00001DDD, 0x00002BCF, 0x00000002, 0x0006000C, + 0x00000015, 0x00003D15, 0x00000001, 0x0000003E, 0x00001DDD, 0x00050051, 0x0000000D, 0x000022C5, + 0x00003D15, 0x00000000, 0x00050051, 0x0000000B, 0x00001DDE, 0x00002BCF, 0x00000003, 0x0006000C, + 0x00000015, 0x00003CF1, 0x00000001, 0x0000003E, 0x00001DDE, 0x00050051, 0x0000000D, 0x000034A1, + 0x00003CF1, 0x00000000, 0x00070050, 0x0000001D, 0x000048FD, 0x000022C3, 0x000022C4, 0x000022C5, + 0x000034A1, 0x000200F9, 0x00005BAB, 0x000200F8, 0x000052CD, 0x0004007C, 0x0000001A, 0x000060FB, + 0x0000370F, 0x000500C4, 0x0000001A, 0x00005825, 0x000060FB, 0x00000302, 0x000500C3, 0x0000001A, + 0x000040A6, 0x00005825, 0x00000302, 0x0004006F, 0x0000001D, 0x00002AAD, 0x000040A6, 0x0005008E, + 0x0000001D, 0x00004A7F, 0x00002AAD, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004987, 0x00000001, + 0x00000028, 0x00000504, 0x00004A7F, 0x0004007C, 0x0000001A, 0x000027EC, 0x00002BCF, 0x000500C4, + 0x0000001A, 0x000021A8, 0x000027EC, 0x00000302, 0x000500C3, 0x0000001A, 0x000040A7, 0x000021A8, + 0x00000302, 0x0004006F, 0x0000001D, 0x00002AAE, 0x000040A7, 0x0005008E, 0x0000001D, 0x000053C6, + 0x00002AAE, 0x000007FE, 0x0007000C, 0x0000001D, 0x00004369, 0x00000001, 0x00000028, 0x00000504, + 0x000053C6, 0x000200F9, 0x00005BAB, 0x000200F8, 0x000030F0, 0x0004007C, 0x0000001D, 0x00004B26, + 0x0000370F, 0x0004007C, 0x0000001D, 0x000038B9, 0x00002BCF, 0x000200F9, 0x00005BAB, 0x000200F8, + 0x00005BAB, 0x000900F5, 0x0000001D, 0x00002BFA, 0x000038B9, 0x000030F0, 0x00004369, 0x000052CD, + 0x000048FD, 0x0000203A, 0x000900F5, 0x0000001D, 0x00003595, 0x00004B26, 0x000030F0, 0x00004987, + 0x000052CD, 0x00005EC0, 0x0000203A, 0x000200F9, 0x00005312, 0x000200F8, 0x00005312, 0x000700F5, + 0x0000001D, 0x0000230D, 0x00002BFA, 0x00005BAB, 0x00002BF9, 0x00005BAA, 0x000700F5, 0x0000001D, + 0x00004C8C, 0x00003595, 0x00005BAB, 0x00003594, 0x00005BAA, 0x00050081, 0x0000001D, 0x00004C41, + 0x00004346, 0x00004C8C, 0x00050081, 0x0000001D, 0x00005D3D, 0x000019F1, 0x0000230D, 0x000200F9, + 0x00005EC8, 0x000200F8, 0x00005EC8, 0x000700F5, 0x0000001D, 0x00002BA7, 0x0000455A, 0x00005310, + 0x00005D3D, 0x00005312, 0x000700F5, 0x0000001D, 0x00003854, 0x000046B0, 0x00005310, 0x00004C41, + 0x00005312, 0x000700F5, 0x0000000D, 0x000038BA, 0x00005A1D, 0x00005310, 0x00002F3A, 0x00005312, + 0x000200F9, 0x00005313, 0x000200F8, 0x00005313, 0x000700F5, 0x0000001D, 0x00002BA8, 0x00002662, + 0x0000530F, 0x00002BA7, 0x00005EC8, 0x000700F5, 0x0000001D, 0x00003063, 0x000036E3, 0x0000530F, + 0x00003854, 0x00005EC8, 0x000700F5, 0x0000000D, 0x00002EA8, 0x00002B2C, 0x0000530F, 0x000038BA, + 0x00005EC8, 0x0005008E, 0x0000001D, 0x00005C88, 0x00003063, 0x00002EA8, 0x0005008E, 0x0000001D, + 0x0000592A, 0x00002BA8, 0x00002EA8, 0x000500AA, 0x00000009, 0x0000320A, 0x00001A29, 0x00000A0A, + 0x000300F7, 0x000033DC, 0x00000000, 0x000400FA, 0x0000320A, 0x00002CBB, 0x000033DC, 0x000200F8, + 0x00002CBB, 0x00050051, 0x0000000B, 0x00005E6F, 0x00004AB4, 0x00000000, 0x000500AB, 0x00000009, + 0x000057C6, 0x00005E6F, 0x00000A0A, 0x000200F9, 0x000033DC, 0x000200F8, 0x000033DC, 0x000700F5, + 0x00000009, 0x00002AAF, 0x0000320A, 0x00005313, 0x000057C6, 0x00002CBB, 0x000300F7, 0x00004CC1, + 0x00000002, 0x000400FA, 0x00002AAF, 0x00002CF4, 0x00004CC1, 0x000200F8, 0x00002CF4, 0x00050051, + 0x0000000B, 0x00005C2F, 0x00004AB4, 0x00000000, 0x000500AE, 0x00000009, 0x000043C2, 0x00005C2F, + 0x00000A10, 0x000300F7, 0x00004945, 0x00000000, 0x000400FA, 0x000043C2, 0x00003E05, 0x00004945, + 0x000200F8, 0x00003E05, 0x000500AE, 0x00000009, 0x00005FD4, 0x00005C2F, 0x00000A13, 0x000300F7, + 0x00004944, 0x00000000, 0x000400FA, 0x00005FD4, 0x00002620, 0x00004944, 0x000200F8, 0x00002620, + 0x00050051, 0x0000000D, 0x00005002, 0x00005C88, 0x00000003, 0x00060052, 0x0000001D, 0x000037FF, + 0x00005002, 0x00005C88, 0x00000002, 0x000200F9, 0x00004944, 0x000200F8, 0x00004944, 0x000700F5, + 0x0000001D, 0x000043E3, 0x00005C88, 0x00003E05, 0x000037FF, 0x00002620, 0x00050051, 0x0000000D, + 0x00001B5A, 0x000043E3, 0x00000002, 0x00060052, 0x0000001D, 0x00003B28, 0x00001B5A, 0x000043E3, + 0x00000001, 0x000200F9, 0x00004945, 0x000200F8, 0x00004945, 0x000700F5, 0x0000001D, 0x000043E4, + 0x00005C88, 0x00002CF4, 0x00003B28, 0x00004944, 0x00050051, 0x0000000D, 0x00001B5B, 0x000043E4, + 0x00000001, 0x00060052, 0x0000001D, 0x00003B29, 0x00001B5B, 0x000043E4, 0x00000000, 0x000200F9, + 0x00004CC1, 0x000200F8, 0x00004CC1, 0x000700F5, 0x0000001D, 0x0000240D, 0x00005C88, 0x000033DC, + 0x00003B29, 0x00004945, 0x00050080, 0x00000011, 0x00004BCB, 0x00002670, 0x000059EC, 0x00050051, + 0x0000000B, 0x000033BC, 0x00004BCB, 0x00000000, 0x00050051, 0x0000000B, 0x00002553, 0x00004BCB, + 0x00000001, 0x000500C2, 0x0000000B, 0x00002B2D, 0x000033BC, 0x00000A13, 0x00050050, 0x00000011, + 0x00001E98, 0x00002B2D, 0x00002553, 0x00050086, 0x00000011, 0x00006158, 0x00001E98, 0x00005C31, + 0x00050051, 0x0000000B, 0x0000366C, 0x00006158, 0x00000000, 0x000500C4, 0x0000000B, 0x00004D3A, + 0x0000366C, 0x00000A13, 0x00050051, 0x0000000B, 0x00005EC1, 0x00006158, 0x00000001, 0x00060050, + 0x00000014, 0x000053CC, 0x00004D3A, 0x00005EC1, 0x00004408, 0x000300F7, 0x00005341, 0x00000002, + 0x000400FA, 0x000048EB, 0x000056BE, 0x00002AB0, 0x000200F8, 0x00002AB0, 0x0007004F, 0x00000011, + 0x00001CAB, 0x000053CC, 0x000053CC, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000059CF, + 0x00001CAB, 0x00050051, 0x0000000C, 0x0000190F, 0x000059CF, 0x00000000, 0x000500C3, 0x0000000C, + 0x000024FD, 0x0000190F, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000059CF, 0x00000001, + 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, + 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, + 0x00005347, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, + 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A1F, 0x000500C7, 0x0000000C, 0x00002AB6, + 0x0000190F, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x00002747, 0x00000A35, 0x000500C4, + 0x0000000C, 0x00003FF5, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x000029C0, 0x00002AB6, + 0x00003FF5, 0x0004007C, 0x0000000C, 0x00002D07, 0x000029C0, 0x000500C7, 0x0000000C, 0x0000424F, + 0x00002D07, 0x000009DB, 0x000500C4, 0x0000000C, 0x000060E9, 0x0000424F, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4B, 0x00004A8E, 0x000060E9, 0x000500C7, 0x0000000C, 0x00003397, 0x00002D07, + 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4B, 0x00003397, 0x000500C7, 0x0000000C, + 0x000047B4, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544A, 0x000047B4, 0x00000A17, + 0x00050080, 0x0000000C, 0x00004157, 0x00004D30, 0x0000544A, 0x000500C7, 0x0000000C, 0x00005022, + 0x00004157, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F76, 0x00004A33, + 0x00000A20, 0x00050080, 0x0000000C, 0x00004158, 0x00002416, 0x00002F76, 0x000500C7, 0x0000000C, + 0x00004AE1, 0x00004157, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544B, 0x00004AE1, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004144, 0x00004158, 0x0000544B, 0x000500C7, 0x0000000C, 0x00005083, + 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, + 0x0000000C, 0x00001EEC, 0x0000190F, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, + 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544C, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004144, 0x0000544C, + 0x000500C7, 0x0000000C, 0x00002E06, 0x00004157, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, + 0x00003C4C, 0x00002E06, 0x0004007C, 0x0000000B, 0x0000566F, 0x0000394F, 0x000200F9, 0x00005341, + 0x000200F8, 0x000056BE, 0x0004007C, 0x00000016, 0x000019AD, 0x000053CC, 0x00050051, 0x0000000C, + 0x000042C2, 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FE, 0x000042C2, 0x00000A17, + 0x00050051, 0x0000000C, 0x00002748, 0x000019AD, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405D, + 0x00002748, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00006273, 0x00000A16, 0x0004007C, + 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005321, 0x0000405D, 0x000018AB, + 0x00050080, 0x0000000C, 0x00003B27, 0x000024FE, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, + 0x00003DA7, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, + 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, 0x000019AD, 0x00000000, + 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, + 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A1C, 0x000500C7, + 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, + 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003139, 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003139, 0x00000A11, + 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, + 0x0000434B, 0x00000A1C, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, + 0x0000000C, 0x00002218, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002218, + 0x0000405D, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, + 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, + 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004AE2, + 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544D, 0x00004AE2, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4D, 0x00005A0C, 0x0000544D, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, + 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, + 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, + 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B5, + 0x00002748, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544E, 0x000047B5, 0x00000A1C, 0x00050080, + 0x0000000C, 0x00004159, 0x0000285C, 0x0000544E, 0x000500C7, 0x0000000C, 0x00004AE3, 0x000042C2, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544F, 0x00004AE3, 0x00000A17, 0x00050080, 0x0000000C, + 0x0000415A, 0x00004159, 0x0000544F, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4D, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, + 0x0000415A, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, + 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4D, 0x00000A05, 0x00050080, 0x0000000C, + 0x00002AB1, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002AB1, 0x00000A11, + 0x000500C7, 0x0000000C, 0x00005AB2, 0x0000415A, 0x0000040B, 0x00050080, 0x0000000C, 0x00002AB2, + 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002AB2, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00005559, 0x0000415A, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, + 0x00005559, 0x0004007C, 0x0000000B, 0x00005670, 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, + 0x00005341, 0x000700F5, 0x0000000B, 0x000024FC, 0x00005670, 0x000056BE, 0x0000566F, 0x00002AB0, + 0x00050084, 0x00000011, 0x00003FAE, 0x00006158, 0x00005C31, 0x00050082, 0x00000011, 0x00003F85, + 0x00001E98, 0x00003FAE, 0x00050051, 0x0000000B, 0x0000448F, 0x00005C31, 0x00000001, 0x00050084, + 0x0000000B, 0x00005C50, 0x0000229A, 0x0000448F, 0x00050084, 0x0000000B, 0x00003CA0, 0x000024FC, + 0x00005C50, 0x00050051, 0x0000000B, 0x00003ED4, 0x00003F85, 0x00000000, 0x00050084, 0x0000000B, + 0x00003E12, 0x00003ED4, 0x0000448F, 0x00050051, 0x0000000B, 0x00001AE7, 0x00003F85, 0x00000001, + 0x00050080, 0x0000000B, 0x00002B25, 0x00003E12, 0x00001AE7, 0x000500C4, 0x0000000B, 0x0000609D, + 0x00002B25, 0x00000A13, 0x000500C7, 0x0000000B, 0x000055A5, 0x000033BC, 0x00000A1F, 0x00050080, + 0x0000000B, 0x00005831, 0x0000609D, 0x000055A5, 0x00050080, 0x0000000B, 0x000034BC, 0x00003CA0, + 0x00005831, 0x000500C2, 0x0000000B, 0x000059BD, 0x000034BC, 0x00000A13, 0x0008000C, 0x0000001D, + 0x00005E5A, 0x00000001, 0x0000002B, 0x0000240D, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, + 0x00002371, 0x00005E5A, 0x00000540, 0x00050081, 0x0000001D, 0x00002E66, 0x00002371, 0x00000145, + 0x0004006D, 0x00000017, 0x00001DDF, 0x00002E66, 0x00050051, 0x0000000B, 0x000021FC, 0x00001DDF, + 0x00000000, 0x00050051, 0x0000000B, 0x00002FDB, 0x00001DDF, 0x00000001, 0x000500C4, 0x0000000B, + 0x00002D29, 0x00002FDB, 0x00000A23, 0x000500C5, 0x0000000B, 0x00004D66, 0x000021FC, 0x00002D29, + 0x00050051, 0x0000000B, 0x000053E4, 0x00001DDF, 0x00000002, 0x000500C4, 0x0000000B, 0x00002170, + 0x000053E4, 0x00000A3B, 0x000500C5, 0x0000000B, 0x00004D67, 0x00004D66, 0x00002170, 0x00050051, + 0x0000000B, 0x000053E5, 0x00001DDF, 0x00000003, 0x000500C4, 0x0000000B, 0x00001C7C, 0x000053E5, + 0x00000A53, 0x000500C5, 0x0000000B, 0x00002427, 0x00004D67, 0x00001C7C, 0x0008000C, 0x0000001D, + 0x00001D62, 0x00000001, 0x0000002B, 0x0000592A, 0x00000B7A, 0x00000505, 0x0005008E, 0x0000001D, + 0x00002048, 0x00001D62, 0x00000540, 0x00050081, 0x0000001D, 0x00002E67, 0x00002048, 0x00000145, + 0x0004006D, 0x00000017, 0x00001DE0, 0x00002E67, 0x00050051, 0x0000000B, 0x000021FD, 0x00001DE0, + 0x00000000, 0x00050051, 0x0000000B, 0x00002FDC, 0x00001DE0, 0x00000001, 0x000500C4, 0x0000000B, + 0x00002D2A, 0x00002FDC, 0x00000A23, 0x000500C5, 0x0000000B, 0x00004D68, 0x000021FD, 0x00002D2A, + 0x00050051, 0x0000000B, 0x000053E6, 0x00001DE0, 0x00000002, 0x000500C4, 0x0000000B, 0x00002171, + 0x000053E6, 0x00000A3B, 0x000500C5, 0x0000000B, 0x00004D69, 0x00004D68, 0x00002171, 0x00050051, + 0x0000000B, 0x000053E7, 0x00001DE0, 0x00000003, 0x000500C4, 0x0000000B, 0x0000215D, 0x000053E7, + 0x00000A53, 0x000500C5, 0x0000000B, 0x0000445A, 0x00004D69, 0x0000215D, 0x00050050, 0x00000011, + 0x00002D69, 0x00002427, 0x0000445A, 0x00060041, 0x0000028E, 0x00002312, 0x00001592, 0x00000A0B, + 0x000059BD, 0x0003003E, 0x00002312, 0x00002D69, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, + 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_128bpb_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_128bpb_cs.h new file mode 100644 index 0000000..df0540f --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_128bpb_cs.h @@ -0,0 +1,526 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25059 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonReadable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonWritable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2587 = OpConstantComposite %v3uint %uint_1 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %5134 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %4218 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_10 = OpConstant %uint 10 + %uint_11 = OpConstant %uint 11 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2587 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_16 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_10 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_10 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_10 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_11 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_4 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %6362 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %22810 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %24825 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %24825 %19767 + %21686 = OpIAdd %uint %21685 %int_1 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_32 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %6871 %16377 %10584 + OpSelectionMerge %11417 None + OpBranchConditional %15139 %11065 %11417 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21686 + OpStore %8053 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_128bpb_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000061E3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000019, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, 0x00000019, 0x00040047, 0x0000140E, + 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, 0x00000000, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000018, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, + 0x00000018, 0x00040047, 0x0000107A, 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, + 0x00000001, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, + 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, + 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, + 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, + 0x00000009, 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, + 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, + 0x00000A1B, 0x00000A0D, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000140E, 0x00000002, 0x0003001D, 0x000007DD, + 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, + 0x0004003B, 0x00000A32, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, + 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0004002B, 0x0000000B, + 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000A2B, 0x0000000B, 0x0007002C, 0x00000017, + 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, + 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, + 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, + 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, + 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, + 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, 0x000500AB, + 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, 0x00003526, + 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, 0x0000000B, + 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, 0x00000A13, + 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, + 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, + 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, + 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, + 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, + 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, + 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, + 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A1B, 0x0007004F, + 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, + 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, + 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, + 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, + 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, + 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, + 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A3B, 0x00050051, 0x0000000C, + 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, + 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, + 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, + 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, + 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, + 0x00050080, 0x0000000B, 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x000054B5, + 0x00002764, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, 0x00005768, + 0x000051F2, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, 0x00004384, + 0x00002BF8, 0x000018D9, 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, 0x000032B3, 0x000044BE, + 0x00000A17, 0x000500C3, 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, 0x000500C2, 0x0000000B, + 0x00004947, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00004947, 0x00050084, + 0x0000000C, 0x00005321, 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000032B3, + 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, + 0x00003901, 0x00002348, 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, 0x00003901, 0x000500C3, + 0x0000000C, 0x000032BA, 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, 0x00005FEE, 0x000032BA, + 0x000020F4, 0x000500C4, 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A28, 0x000500C7, 0x0000000C, + 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, + 0x000044BE, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, + 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, + 0x00000A28, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, + 0x00002215, 0x000044BE, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000601E, + 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, + 0x00005BEB, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, + 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, + 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, + 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, + 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, + 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x000018DA, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A28, 0x00050080, 0x0000000C, + 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000044BE, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, + 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, + 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, + 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, + 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, + 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, + 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, 0x00005EA0, + 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, 0x000019AD, 0x000042F0, + 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, + 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, 0x00000001, 0x000500C3, + 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005788, + 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, + 0x0000405C, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, + 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A2B, 0x000500C7, 0x0000000C, 0x00002AB6, 0x000042C2, + 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, + 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, + 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A16, 0x000500C7, 0x0000000C, 0x000027B1, + 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, + 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, + 0x000047B5, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, + 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, + 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, + 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, + 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, + 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, + 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, + 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, + 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x00002F42, + 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, 0x0000000C, + 0x0000292C, 0x000054ED, 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, 0x00005F43, 0x000200F8, + 0x000051F2, 0x0004007C, 0x0000000C, 0x00003CBC, 0x00005789, 0x00050084, 0x0000000C, 0x000060B8, + 0x000018DA, 0x00003CBC, 0x00050080, 0x0000000C, 0x0000208E, 0x000060B8, 0x000044BE, 0x0004007C, + 0x0000000C, 0x000022F8, 0x00005788, 0x00050084, 0x0000000C, 0x00001E9F, 0x0000208E, 0x000022F8, + 0x00050080, 0x0000000C, 0x00001F30, 0x0000591A, 0x00001E9F, 0x000200F9, 0x00005F43, 0x000200F8, + 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, 0x00001F30, 0x000051F2, + 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, 0x000056CD, 0x00001A3F, + 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, 0x0000000B, 0x00005665, + 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, 0x00004315, 0x0000107A, 0x00000A0B, 0x00005665, + 0x0004003D, 0x00000017, 0x00001CAA, 0x00004315, 0x000500AA, 0x00000009, 0x000035C0, 0x000061E2, + 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x000061E2, 0x00000A10, 0x000500A6, 0x00000009, + 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, + 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, + 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, + 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, + 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, + 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, 0x00005F43, 0x00003FF8, 0x00002957, + 0x000500AA, 0x00000009, 0x00004CB6, 0x000061E2, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, + 0x00005376, 0x00004CB6, 0x000300F7, 0x00002C98, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, + 0x00002C98, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, + 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, + 0x00005E17, 0x00003BE7, 0x000200F9, 0x00002C98, 0x000200F8, 0x00002C98, 0x000700F5, 0x00000017, + 0x00004D37, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x00060041, 0x00000294, 0x000060F9, + 0x0000140E, 0x00000A0B, 0x000054B5, 0x0003003E, 0x000060F9, 0x00004D37, 0x00050080, 0x0000000B, + 0x000054B6, 0x000054B5, 0x00000A0E, 0x000300F7, 0x00001AD7, 0x00000002, 0x000400FA, 0x00004376, + 0x000055E9, 0x00001C25, 0x000200F8, 0x000055E9, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001C25, + 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001AD7, 0x000700F5, 0x0000000B, 0x0000456F, 0x00000A6A, + 0x000055E9, 0x00000A3A, 0x00001C25, 0x000500C2, 0x0000000B, 0x000041C0, 0x0000456F, 0x00000A16, + 0x00050080, 0x0000000B, 0x00002ADB, 0x00005665, 0x000041C0, 0x00060041, 0x00000294, 0x0000571A, + 0x0000107A, 0x00000A0B, 0x00002ADB, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, + 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, + 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, + 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, + 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, + 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, + 0x000019B2, 0x00001AD7, 0x00003FF9, 0x00002958, 0x000300F7, 0x00002C99, 0x00000000, 0x000400FA, + 0x00003B23, 0x00002B39, 0x00002C99, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, + 0x00002AAC, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, + 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002C99, 0x000200F8, 0x00002C99, + 0x000700F5, 0x00000017, 0x00004D39, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x00060041, + 0x00000294, 0x00001F75, 0x0000140E, 0x00000A0B, 0x000054B6, 0x0003003E, 0x00001F75, 0x00004D39, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_128bpb_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_128bpb_scaled_cs.h new file mode 100644 index 0000000..24cf68d --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_128bpb_scaled_cs.h @@ -0,0 +1,580 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonReadable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonWritable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2587 = OpConstantComposite %v3uint %uint_1 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %5134 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %4218 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %uint_10 = OpConstant %uint 10 + %uint_11 = OpConstant %uint 11 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2587 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_16 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %9050 = OpShiftRightLogical %uint %6930 %uint_4 + %17638 = OpCompositeExtract %uint %21387 0 + %6648 = OpCompositeExtract %uint %21387 1 + %6684 = OpCompositeConstruct %v2uint %17638 %6648 + %24927 = OpUDiv %v2uint %6684 %6551 + %14756 = OpCompositeExtract %uint %24927 0 + %14872 = OpCompositeExtract %uint %24927 1 + %10987 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %14756 %14872 %10987 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_10 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_10 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_10 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_11 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_4 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %24927 %6551 + %15292 = OpISub %v2uint %6684 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %9696 = OpIAdd %uint %15890 %6886 + %17945 = OpShiftLeftLogical %uint %9696 %uint_4 + %20138 = OpIAdd %uint %15520 %17945 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %7338 = OpLoad %v4uint %20399 + %13760 = OpIEqual %bool %24990 %uint_1 + %21366 = OpIEqual %bool %24990 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %21313 %16376 %10583 + %19638 = OpIEqual %bool %24990 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %24825 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %9050 + OpStore %24825 %19767 + %15532 = OpIAdd %uint %9050 %int_1 + %6417 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %6417 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %17638 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %17638 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_32 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_32 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %24764 %16377 %10584 + OpSelectionMerge %11417 None + OpBranchConditional %15139 %11065 %11417 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15532 + OpStore %8053 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_128bpb_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000019, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, 0x00000019, 0x00040047, 0x0000140E, + 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, 0x00000000, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000018, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, + 0x00000018, 0x00040047, 0x0000107A, 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, + 0x00000001, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, + 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, + 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, + 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, + 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, + 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, + 0x00000787, 0x00000A16, 0x00000A1F, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, + 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, + 0x00000014, 0x00000A1B, 0x00000A0D, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, + 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, + 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000140E, 0x00000002, 0x0003001D, + 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, + 0x000007B5, 0x0004003B, 0x00000A32, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, + 0x00000017, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, + 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, + 0x0004002B, 0x0000000B, 0x00000A2B, 0x0000000B, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, + 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, + 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, + 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, + 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, + 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, + 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, + 0x000500C7, 0x0000000B, 0x00005F7D, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x000048EB, + 0x00005F7D, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001FCD, 0x00003526, 0x00000A10, 0x000500C7, + 0x0000000B, 0x0000619E, 0x00001FCD, 0x00000A13, 0x00050050, 0x00000011, 0x000022A7, 0x00003526, + 0x00003526, 0x000500C2, 0x00000011, 0x00001BAF, 0x000022A7, 0x00000787, 0x000500C7, 0x00000011, + 0x00001997, 0x00001BAF, 0x000007A2, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, + 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, + 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, + 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, + 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, + 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, + 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, + 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, + 0x00002A0E, 0x00000A1B, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, + 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, + 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, + 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, + 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, + 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, + 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, + 0x00000A3B, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, + 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, + 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, + 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, + 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, + 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00001B12, 0x00002A92, 0x0000578B, + 0x000500C2, 0x0000000B, 0x0000235A, 0x00001B12, 0x00000A16, 0x00050051, 0x0000000B, 0x000044E6, + 0x0000538B, 0x00000000, 0x00050051, 0x0000000B, 0x000019F8, 0x0000538B, 0x00000001, 0x00050050, + 0x00000011, 0x00001A1C, 0x000044E6, 0x000019F8, 0x00050086, 0x00000011, 0x0000615F, 0x00001A1C, + 0x00001997, 0x00050051, 0x0000000B, 0x000039A4, 0x0000615F, 0x00000000, 0x00050051, 0x0000000B, + 0x00003A18, 0x0000615F, 0x00000001, 0x00050051, 0x0000000B, 0x00002AEB, 0x0000538B, 0x00000002, + 0x00060050, 0x00000014, 0x000024C9, 0x000039A4, 0x00003A18, 0x00002AEB, 0x000300F7, 0x00005341, + 0x00000002, 0x000400FA, 0x000048EB, 0x0000537D, 0x00002DD9, 0x000200F8, 0x0000537D, 0x0004007C, + 0x00000016, 0x00002970, 0x000024C9, 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, + 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, + 0x00002970, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, + 0x0000000B, 0x00005B4D, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, + 0x00050084, 0x0000000C, 0x00005321, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, + 0x000024FD, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, + 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, + 0x00050051, 0x0000000C, 0x00006242, 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, + 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, + 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A28, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, + 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, + 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, + 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, + 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A28, 0x000500C3, + 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, + 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, + 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, + 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, + 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, + 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A28, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, + 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, + 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, + 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, + 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, + 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, + 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, + 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, + 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x00004158, + 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, + 0x0000566F, 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, 0x00002DD9, 0x0007004F, 0x00000011, + 0x00002621, 0x000024C9, 0x000024C9, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000059CF, + 0x00002621, 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, 0x00000000, 0x000500C3, 0x0000000C, + 0x000024FE, 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002748, 0x000059CF, 0x00000001, + 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4E, + 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, + 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FE, 0x00005347, + 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A2B, 0x000500C7, 0x0000000C, 0x00002AB6, + 0x00001903, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002748, 0x00000A35, 0x000500C4, + 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, + 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A16, 0x000500C7, 0x0000000C, + 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, + 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, + 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, + 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, + 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, + 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, + 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, + 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, + 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, + 0x000500C3, 0x0000000C, 0x00001EEC, 0x00001903, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, + 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, + 0x0000544F, 0x000500C7, 0x0000000C, 0x00002E06, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, + 0x0000394F, 0x00003C4D, 0x00002E06, 0x0004007C, 0x0000000B, 0x00005670, 0x0000394F, 0x000200F9, + 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, 0x000024FC, 0x0000566F, 0x0000537D, + 0x00005670, 0x00002DD9, 0x00050084, 0x00000011, 0x00003FA8, 0x0000615F, 0x00001997, 0x00050082, + 0x00000011, 0x00003BBC, 0x00001A1C, 0x00003FA8, 0x00050051, 0x0000000B, 0x00001C87, 0x00001997, + 0x00000000, 0x00050051, 0x0000000B, 0x00005962, 0x00001997, 0x00000001, 0x00050084, 0x0000000B, + 0x00003372, 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, 0x00003CA0, 0x000024FC, 0x00003372, + 0x00050051, 0x0000000B, 0x00003ED4, 0x00003BBC, 0x00000000, 0x00050084, 0x0000000B, 0x00003E12, + 0x00003ED4, 0x00005962, 0x00050051, 0x0000000B, 0x00001AE6, 0x00003BBC, 0x00000001, 0x00050080, + 0x0000000B, 0x000025E0, 0x00003E12, 0x00001AE6, 0x000500C4, 0x0000000B, 0x00004619, 0x000025E0, + 0x00000A16, 0x00050080, 0x0000000B, 0x00004EAA, 0x00003CA0, 0x00004619, 0x00050080, 0x0000000B, + 0x00003BA9, 0x00005EAC, 0x00004EAA, 0x000500C2, 0x0000000B, 0x00003948, 0x00003BA9, 0x00000A16, + 0x00060041, 0x00000294, 0x00004FAF, 0x0000107A, 0x00000A0B, 0x00003948, 0x0004003D, 0x00000017, + 0x00001CAA, 0x00004FAF, 0x000500AA, 0x00000009, 0x000035C0, 0x0000619E, 0x00000A0D, 0x000500AA, + 0x00000009, 0x00005376, 0x0000619E, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, + 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, + 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, + 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, + 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, + 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, + 0x00000017, 0x00005879, 0x00001CAA, 0x00005341, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, + 0x00004CB6, 0x0000619E, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, + 0x000300F7, 0x00002C98, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x00002C98, 0x000200F8, + 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, + 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, + 0x000200F9, 0x00002C98, 0x000200F8, 0x00002C98, 0x000700F5, 0x00000017, 0x00004D37, 0x00005879, + 0x00003463, 0x000029E8, 0x00002B38, 0x00060041, 0x00000294, 0x000060F9, 0x0000140E, 0x00000A0B, + 0x0000235A, 0x0003003E, 0x000060F9, 0x00004D37, 0x00050080, 0x0000000B, 0x00003CAC, 0x0000235A, + 0x00000A0E, 0x000500AC, 0x00000009, 0x00001911, 0x00001C87, 0x00000A0D, 0x000300F7, 0x000060BC, + 0x00000002, 0x000400FA, 0x00001911, 0x00005084, 0x00005094, 0x000200F8, 0x00005084, 0x00050086, + 0x0000000B, 0x00003697, 0x000044E6, 0x00001C87, 0x00050084, 0x0000000B, 0x0000237E, 0x00003697, + 0x00001C87, 0x00050082, 0x0000000B, 0x00003171, 0x000044E6, 0x0000237E, 0x00050080, 0x0000000B, + 0x00002527, 0x00003171, 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, 0x00001C87, + 0x000300F7, 0x00001EED, 0x00000000, 0x000400FA, 0x0000343F, 0x0000569E, 0x00002191, 0x000200F8, + 0x0000569E, 0x00050084, 0x0000000B, 0x00004B59, 0x00000A6A, 0x00001C87, 0x000500C4, 0x0000000B, + 0x0000540F, 0x00003171, 0x00000A16, 0x00050082, 0x0000000B, 0x00004944, 0x00004B59, 0x0000540F, + 0x000200F9, 0x00001EED, 0x000200F8, 0x00002191, 0x000200F9, 0x00001EED, 0x000200F8, 0x00001EED, + 0x000700F5, 0x0000000B, 0x0000292C, 0x00004944, 0x0000569E, 0x00000A3A, 0x00002191, 0x000200F9, + 0x000060BC, 0x000200F8, 0x00005094, 0x000200F9, 0x000060BC, 0x000200F8, 0x000060BC, 0x000700F5, + 0x0000000B, 0x000029BC, 0x0000292C, 0x00001EED, 0x00000A6A, 0x00005094, 0x00050084, 0x0000000B, + 0x0000492B, 0x000029BC, 0x00005962, 0x000500C2, 0x0000000B, 0x0000406D, 0x0000492B, 0x00000A16, + 0x00050080, 0x0000000B, 0x0000336B, 0x00003948, 0x0000406D, 0x00060041, 0x00000294, 0x0000571A, + 0x0000107A, 0x00000A0B, 0x0000336B, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, + 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, + 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, + 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, + 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, + 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, + 0x000019B2, 0x000060BC, 0x00003FF9, 0x00002958, 0x000300F7, 0x00002C99, 0x00000000, 0x000400FA, + 0x00003B23, 0x00002B39, 0x00002C99, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, + 0x00002AAC, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, + 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002C99, 0x000200F8, 0x00002C99, + 0x000700F5, 0x00000017, 0x00004D39, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x00060041, + 0x00000294, 0x00001F75, 0x0000140E, 0x00000A0B, 0x00003CAC, 0x0003003E, 0x00001F75, 0x00004D39, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_16bpb_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_16bpb_cs.h new file mode 100644 index 0000000..c52182c --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_16bpb_cs.h @@ -0,0 +1,491 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25059 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %uint_1 = OpConstant %uint 1 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_2 = OpConstant %uint 2 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_3 = OpConstant %uint 3 + %uint_32 = OpConstant %uint 32 + %uint_64 = OpConstant %uint 64 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2612 = OpConstantComposite %v3uint %uint_4 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %uint_16 = OpConstant %uint 16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2612 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_2 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_7 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_7 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_7 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_8 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_1 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %6362 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %22810 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %8801 = OpLoad %v4uint %17173 + %21106 = OpIEqual %bool %25058 %uint_1 + OpSelectionMerge %11416 None + OpBranchConditional %21106 %10583 %11416 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %8801 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %8801 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %8801 %24387 %16376 %10583 + %24825 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %24825 %19767 + %21686 = OpIAdd %uint %21685 %int_1 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_64 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %11417 None + OpBranchConditional %21106 %10584 %11417 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %6578 %6871 %16377 %10584 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21686 + OpStore %8053 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_16bpb_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000061E3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, + 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, + 0x0004002B, 0x0000000B, 0x00000ACA, 0x00000040, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, + 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x00040020, 0x00000291, + 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, + 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A34, 0x00000A16, 0x00000A0A, 0x00000A0A, + 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, + 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, + 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, + 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, + 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, + 0x00000A6A, 0x00000A0D, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, + 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, + 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, + 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, + 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, + 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, + 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, + 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, + 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, + 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, + 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, + 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, + 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, + 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, + 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, + 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, + 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A34, + 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, + 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, + 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, + 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, + 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, + 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A11, 0x00050051, + 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, + 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, + 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, + 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, + 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, + 0x00002042, 0x00050080, 0x0000000B, 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, + 0x000054B5, 0x00002764, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, + 0x00005768, 0x000051F2, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, + 0x00004384, 0x00002BF8, 0x000018D9, 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, 0x000032B3, + 0x000044BE, 0x00000A17, 0x000500C3, 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, 0x000500C2, + 0x0000000B, 0x00004947, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00004947, + 0x00050084, 0x0000000C, 0x00005321, 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, + 0x000032B3, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, + 0x0000000C, 0x00003901, 0x00002348, 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, 0x00003901, + 0x000500C3, 0x0000000C, 0x000032BA, 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, 0x00005FEE, + 0x000032BA, 0x000020F4, 0x000500C4, 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A1F, 0x000500C7, + 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, + 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003138, 0x000044BE, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, + 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, + 0x0000434B, 0x00000A1F, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, + 0x0000000C, 0x00002215, 0x000044BE, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, + 0x0000601E, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, + 0x00004112, 0x00005BEB, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, + 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, + 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, + 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, + 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, + 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, + 0x000018DA, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A1F, 0x00050080, + 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000044BE, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, + 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, + 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, + 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, + 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, + 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, + 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, + 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, 0x000019AD, + 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, + 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, 0x00000001, + 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, + 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, 0x0000000C, + 0x00005347, 0x0000405C, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, + 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002AB6, + 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, 0x000500C4, + 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, + 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A0D, 0x000500C7, 0x0000000C, + 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, + 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, + 0x0000000C, 0x000047B5, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, + 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, + 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, + 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, + 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, + 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, + 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, + 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, + 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, + 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, + 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, + 0x0000000C, 0x0000292C, 0x000054ED, 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, 0x00005F43, + 0x000200F8, 0x000051F2, 0x0004007C, 0x0000000C, 0x00003CBC, 0x00005789, 0x00050084, 0x0000000C, + 0x000060B8, 0x000018DA, 0x00003CBC, 0x00050080, 0x0000000C, 0x0000208E, 0x000060B8, 0x000044BE, + 0x0004007C, 0x0000000C, 0x000022F8, 0x00005788, 0x00050084, 0x0000000C, 0x00001E9F, 0x0000208E, + 0x000022F8, 0x00050080, 0x0000000C, 0x00001F30, 0x0000591A, 0x00001E9F, 0x000200F9, 0x00005F43, + 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, 0x00001F30, + 0x000051F2, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, 0x000056CD, + 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, 0x0000000B, + 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, 0x00004315, 0x0000107A, 0x00000A0B, + 0x00005665, 0x0004003D, 0x00000017, 0x00002261, 0x00004315, 0x000500AA, 0x00000009, 0x00005272, + 0x000061E2, 0x00000A0D, 0x000300F7, 0x00002C98, 0x00000000, 0x000400FA, 0x00005272, 0x00002957, + 0x00002C98, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00002261, 0x000009CE, + 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, + 0x00002261, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, + 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00002C98, 0x000200F8, 0x00002C98, + 0x000700F5, 0x00000017, 0x00004D37, 0x00002261, 0x00005F43, 0x00003FF8, 0x00002957, 0x00060041, + 0x00000294, 0x000060F9, 0x0000140E, 0x00000A0B, 0x000054B5, 0x0003003E, 0x000060F9, 0x00004D37, + 0x00050080, 0x0000000B, 0x000054B6, 0x000054B5, 0x00000A0E, 0x000300F7, 0x00001AD7, 0x00000002, + 0x000400FA, 0x00004376, 0x000055E9, 0x00001C25, 0x000200F8, 0x000055E9, 0x000200F9, 0x00001AD7, + 0x000200F8, 0x00001C25, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001AD7, 0x000700F5, 0x0000000B, + 0x0000456F, 0x00000ACA, 0x000055E9, 0x00000A3A, 0x00001C25, 0x000500C2, 0x0000000B, 0x000041C0, + 0x0000456F, 0x00000A16, 0x00050080, 0x0000000B, 0x00002ADB, 0x00005665, 0x000041C0, 0x00060041, + 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, 0x00002ADB, 0x0004003D, 0x00000017, 0x000019B2, + 0x0000571A, 0x000300F7, 0x00002C99, 0x00000000, 0x000400FA, 0x00005272, 0x00002958, 0x00002C99, + 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, + 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, + 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, + 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x00002C99, 0x000200F8, 0x00002C99, 0x000700F5, + 0x00000017, 0x00004D39, 0x000019B2, 0x00001AD7, 0x00003FF9, 0x00002958, 0x00060041, 0x00000294, + 0x00001F75, 0x0000140E, 0x00000A0B, 0x000054B6, 0x0003003E, 0x00001F75, 0x00004D39, 0x000200F9, + 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_16bpb_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_16bpb_scaled_cs.h new file mode 100644 index 0000000..eac6d33 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_16bpb_scaled_cs.h @@ -0,0 +1,552 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_1 = OpConstant %uint 1 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_2 = OpConstant %uint 2 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_3 = OpConstant %uint 3 + %uint_32 = OpConstant %uint 32 + %uint_64 = OpConstant %uint 64 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2612 = OpConstantComposite %v3uint %uint_4 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %uint_16 = OpConstant %uint 16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2612 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_2 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_3 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_3 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_7 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_7 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_7 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_8 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_1 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_3 + %23219 = OpBitwiseAnd %uint %10722 %uint_7 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_1 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %8801 = OpLoad %v4uint %20399 + %21106 = OpIEqual %bool %24990 %uint_1 + OpSelectionMerge %11416 None + OpBranchConditional %21106 %10583 %11416 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %8801 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %8801 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %8801 %21313 %16376 %10583 + %24825 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %24825 %19767 + %15532 = OpIAdd %uint %11197 %int_1 + %6417 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %6417 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_64 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_64 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %11417 None + OpBranchConditional %21106 %10584 %11417 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %6578 %24764 %16377 %10584 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15532 + OpStore %8053 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_16bpb_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, + 0x0004002B, 0x0000000B, 0x00000ACA, 0x00000040, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, + 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, + 0x00000787, 0x00000A16, 0x00000A1F, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, + 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, + 0x00000014, 0x00000A34, 0x00000A16, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, + 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, + 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, + 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, + 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, + 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, + 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, + 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, + 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, + 0x000005FD, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x00050036, 0x00000008, 0x0000161F, + 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, + 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, + 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005F7D, + 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x000048EB, 0x00005F7D, 0x00000A0A, 0x000500C2, + 0x0000000B, 0x00001FCD, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x0000619E, 0x00001FCD, + 0x00000A13, 0x00050050, 0x00000011, 0x000022A7, 0x00003526, 0x00003526, 0x000500C2, 0x00000011, + 0x00001BAF, 0x000022A7, 0x00000787, 0x000500C7, 0x00000011, 0x00001997, 0x00001BAF, 0x000007A2, + 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, + 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, + 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, + 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, + 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, + 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, + 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, + 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A34, 0x0007004F, + 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, + 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, + 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, + 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, + 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, + 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, + 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A11, 0x00050051, 0x0000000C, + 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, + 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, + 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, + 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, + 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, + 0x00050080, 0x0000000B, 0x00001B12, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x00002BBD, + 0x00001B12, 0x00000A16, 0x00050051, 0x0000000B, 0x000029E2, 0x0000538B, 0x00000000, 0x000500C2, + 0x0000000B, 0x00001DEE, 0x000029E2, 0x00000A13, 0x00050051, 0x0000000B, 0x00002704, 0x0000538B, + 0x00000001, 0x00050050, 0x00000011, 0x00005C0B, 0x00001DEE, 0x00002704, 0x00050086, 0x00000011, + 0x00001F69, 0x00005C0B, 0x00001997, 0x00050051, 0x0000000B, 0x0000366C, 0x00001F69, 0x00000000, + 0x000500C4, 0x0000000B, 0x00004D4D, 0x0000366C, 0x00000A13, 0x00050051, 0x0000000B, 0x000051A9, + 0x00001F69, 0x00000001, 0x00050051, 0x0000000B, 0x000059EE, 0x0000538B, 0x00000002, 0x00060050, + 0x00000014, 0x000024C9, 0x00004D4D, 0x000051A9, 0x000059EE, 0x000300F7, 0x00005341, 0x00000002, + 0x000400FA, 0x000048EB, 0x0000537D, 0x00002DD9, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, + 0x00002970, 0x000024C9, 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, + 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, + 0x00000002, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, + 0x00005B4D, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, + 0x0000000C, 0x00005321, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, + 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, + 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, + 0x0000000C, 0x00006242, 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, + 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, + 0x0000225D, 0x000049FC, 0x00000A1F, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, + 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, + 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, + 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, + 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A1F, 0x000500C3, 0x0000000C, + 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, + 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, + 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, + 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, + 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, + 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, + 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, + 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544B, 0x000047B4, 0x00000A1F, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, + 0x000500C7, 0x0000000C, 0x00004ADE, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, + 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, + 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, + 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, + 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, + 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, + 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, + 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, + 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, + 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x00004158, 0x00000AC8, + 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, 0x0000566F, + 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, 0x00002DD9, 0x0007004F, 0x00000011, 0x00002621, + 0x000024C9, 0x000024C9, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000059CF, 0x00002621, + 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FE, + 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002748, 0x000059CF, 0x00000001, 0x000500C3, + 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00005788, + 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005347, + 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FE, 0x00005347, 0x000500C4, + 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002AB6, 0x00001903, + 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002748, 0x00000A35, 0x000500C4, 0x0000000C, + 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, + 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A0D, 0x000500C7, 0x0000000C, 0x000027B1, + 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, + 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, + 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, + 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, + 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, + 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, + 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, + 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, + 0x0000000C, 0x00001EEC, 0x00001903, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, + 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, + 0x000500C7, 0x0000000C, 0x00002E06, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, + 0x00003C4D, 0x00002E06, 0x0004007C, 0x0000000B, 0x00005670, 0x0000394F, 0x000200F9, 0x00005341, + 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, 0x000024FC, 0x0000566F, 0x0000537D, 0x00005670, + 0x00002DD9, 0x00050084, 0x00000011, 0x00003FA8, 0x00001F69, 0x00001997, 0x00050082, 0x00000011, + 0x00003BBC, 0x00005C0B, 0x00003FA8, 0x00050051, 0x0000000B, 0x00001C87, 0x00001997, 0x00000000, + 0x00050051, 0x0000000B, 0x00005962, 0x00001997, 0x00000001, 0x00050084, 0x0000000B, 0x00003372, + 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, 0x00003CA0, 0x000024FC, 0x00003372, 0x00050051, + 0x0000000B, 0x00003ED4, 0x00003BBC, 0x00000000, 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, + 0x00005962, 0x00050051, 0x0000000B, 0x00001AE6, 0x00003BBC, 0x00000001, 0x00050080, 0x0000000B, + 0x00002B25, 0x00003E12, 0x00001AE6, 0x000500C4, 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A13, + 0x000500C7, 0x0000000B, 0x00005AB3, 0x000029E2, 0x00000A1F, 0x00050080, 0x0000000B, 0x00002557, + 0x0000609D, 0x00005AB3, 0x000500C4, 0x0000000B, 0x000040AD, 0x00002557, 0x00000A0D, 0x00050080, + 0x0000000B, 0x00004EAA, 0x00003CA0, 0x000040AD, 0x00050080, 0x0000000B, 0x00003BA9, 0x00005EAC, + 0x00004EAA, 0x000500C2, 0x0000000B, 0x00003948, 0x00003BA9, 0x00000A16, 0x00060041, 0x00000294, + 0x00004FAF, 0x0000107A, 0x00000A0B, 0x00003948, 0x0004003D, 0x00000017, 0x00002261, 0x00004FAF, + 0x000500AA, 0x00000009, 0x00005272, 0x0000619E, 0x00000A0D, 0x000300F7, 0x00002C98, 0x00000000, + 0x000400FA, 0x00005272, 0x00002957, 0x00002C98, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, + 0x0000475F, 0x00002261, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AC, 0x00002261, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, + 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, + 0x00002C98, 0x000200F8, 0x00002C98, 0x000700F5, 0x00000017, 0x00004D37, 0x00002261, 0x00005341, + 0x00003FF8, 0x00002957, 0x00060041, 0x00000294, 0x000060F9, 0x0000140E, 0x00000A0B, 0x00002BBD, + 0x0003003E, 0x000060F9, 0x00004D37, 0x00050080, 0x0000000B, 0x00003CAC, 0x00002BBD, 0x00000A0E, + 0x000500AC, 0x00000009, 0x00001911, 0x00001C87, 0x00000A0D, 0x000300F7, 0x000060BC, 0x00000002, + 0x000400FA, 0x00001911, 0x00005084, 0x00005094, 0x000200F8, 0x00005084, 0x00050086, 0x0000000B, + 0x00003697, 0x00001DEE, 0x00001C87, 0x00050084, 0x0000000B, 0x0000237E, 0x00003697, 0x00001C87, + 0x00050082, 0x0000000B, 0x00003171, 0x00001DEE, 0x0000237E, 0x00050080, 0x0000000B, 0x00002527, + 0x00003171, 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, 0x00001C87, 0x000300F7, + 0x00001EED, 0x00000000, 0x000400FA, 0x0000343F, 0x0000569E, 0x00002191, 0x000200F8, 0x0000569E, + 0x00050084, 0x0000000B, 0x00004B59, 0x00000ACA, 0x00001C87, 0x000500C4, 0x0000000B, 0x0000540F, + 0x00003171, 0x00000A16, 0x00050082, 0x0000000B, 0x00004944, 0x00004B59, 0x0000540F, 0x000200F9, + 0x00001EED, 0x000200F8, 0x00002191, 0x000200F9, 0x00001EED, 0x000200F8, 0x00001EED, 0x000700F5, + 0x0000000B, 0x0000292C, 0x00004944, 0x0000569E, 0x00000A3A, 0x00002191, 0x000200F9, 0x000060BC, + 0x000200F8, 0x00005094, 0x000200F9, 0x000060BC, 0x000200F8, 0x000060BC, 0x000700F5, 0x0000000B, + 0x000029BC, 0x0000292C, 0x00001EED, 0x00000ACA, 0x00005094, 0x00050084, 0x0000000B, 0x0000492B, + 0x000029BC, 0x00005962, 0x000500C2, 0x0000000B, 0x0000406D, 0x0000492B, 0x00000A16, 0x00050080, + 0x0000000B, 0x0000336B, 0x00003948, 0x0000406D, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, + 0x00000A0B, 0x0000336B, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x00002C99, + 0x00000000, 0x000400FA, 0x00005272, 0x00002958, 0x00002C99, 0x000200F8, 0x00002958, 0x000500C7, + 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, + 0x000200F9, 0x00002C99, 0x000200F8, 0x00002C99, 0x000700F5, 0x00000017, 0x00004D39, 0x000019B2, + 0x000060BC, 0x00003FF9, 0x00002958, 0x00060041, 0x00000294, 0x00001F75, 0x0000140E, 0x00000A0B, + 0x00003CAC, 0x0003003E, 0x00001F75, 0x00004D39, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, + 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_32bpb_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_32bpb_cs.h new file mode 100644 index 0000000..5e94e0e --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_32bpb_cs.h @@ -0,0 +1,525 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25059 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2603 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2603 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_4 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %6362 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %22810 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %24825 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %24825 %19767 + %21686 = OpIAdd %uint %21685 %int_1 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_32 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %6871 %16377 %10584 + OpSelectionMerge %11417 None + OpBranchConditional %15139 %11065 %11417 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21686 + OpStore %8053 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_32bpb_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000061E3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, + 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, + 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, + 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, + 0x00000009, 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, + 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, + 0x00000A2B, 0x00000A13, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, + 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, + 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0004002B, 0x0000000B, + 0x00000A25, 0x00000009, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, + 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, + 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, + 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00050036, 0x00000008, + 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, + 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, + 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, + 0x00005FDC, 0x00003526, 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, + 0x000500C7, 0x0000000B, 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, + 0x00003028, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, + 0x0000000B, 0x000061E2, 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, + 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, + 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, + 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, + 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, + 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, + 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, + 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, + 0x0000538B, 0x00002A0E, 0x00000A2B, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, + 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, + 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, + 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, + 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, + 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, + 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, + 0x00005BEB, 0x00000A17, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, + 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, + 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, + 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, + 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, + 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00002764, 0x00002A92, + 0x0000578B, 0x000500C2, 0x0000000B, 0x000054B5, 0x00002764, 0x00000A16, 0x000300F7, 0x00005F43, + 0x00000002, 0x000400FA, 0x00004376, 0x00005768, 0x000051F2, 0x000200F8, 0x00005768, 0x000300F7, + 0x00001E0B, 0x00000002, 0x000400FA, 0x00004384, 0x00002BF8, 0x000018D9, 0x000200F8, 0x00002BF8, + 0x000500C3, 0x0000000C, 0x000032B3, 0x000044BE, 0x00000A17, 0x000500C3, 0x0000000C, 0x0000601E, + 0x000018DA, 0x00000A11, 0x000500C2, 0x0000000B, 0x00004947, 0x00005789, 0x00000A16, 0x0004007C, + 0x0000000C, 0x000018AA, 0x00004947, 0x00050084, 0x0000000C, 0x00005321, 0x0000601E, 0x000018AA, + 0x00050080, 0x0000000C, 0x00003B27, 0x000032B3, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, + 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x00003901, 0x00002348, 0x00050084, 0x0000000C, + 0x000020F4, 0x00003B27, 0x00003901, 0x000500C3, 0x0000000C, 0x000032BA, 0x00005BEB, 0x00000A1A, + 0x00050080, 0x0000000C, 0x00005FEE, 0x000032BA, 0x000020F4, 0x000500C4, 0x0000000C, 0x0000225D, + 0x00005FEE, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, + 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00005BEB, + 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000044BE, 0x00000A1D, 0x000500C4, 0x0000000C, + 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, + 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, + 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000044BE, 0x00000A14, 0x00050080, + 0x0000000C, 0x000035A3, 0x00002215, 0x0000601E, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, + 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00005BEB, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, + 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, + 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, + 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, + 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, + 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, + 0x000500C7, 0x0000000C, 0x000047B4, 0x000018DA, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, + 0x000047B4, 0x00000A22, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, + 0x0000000C, 0x00004ADE, 0x000044BE, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, + 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, + 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, + 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, + 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, + 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, + 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, + 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, + 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, + 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, + 0x0000000C, 0x000054ED, 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, + 0x0004007C, 0x00000012, 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, + 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, + 0x00002747, 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, + 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, + 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AB, 0x00050080, 0x0000000C, + 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A25, + 0x000500C7, 0x0000000C, 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, + 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, + 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, + 0x00000A10, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, + 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, + 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, + 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002747, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, + 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, + 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, + 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, + 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, + 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, + 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, + 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, + 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, + 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, + 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, + 0x00000AC8, 0x00050080, 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, + 0x000200F8, 0x00001E0B, 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, 0x00002BF8, 0x00002F42, + 0x000018D9, 0x000200F9, 0x00005F43, 0x000200F8, 0x000051F2, 0x0004007C, 0x0000000C, 0x00003CBC, + 0x00005789, 0x00050084, 0x0000000C, 0x000060B8, 0x000018DA, 0x00003CBC, 0x00050080, 0x0000000C, + 0x0000208E, 0x000060B8, 0x000044BE, 0x0004007C, 0x0000000C, 0x000022F8, 0x00005788, 0x00050084, + 0x0000000C, 0x00001E9F, 0x0000208E, 0x000022F8, 0x00050080, 0x0000000C, 0x00001F30, 0x0000591A, + 0x00001E9F, 0x000200F9, 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, + 0x0000292C, 0x00001E0B, 0x00001F30, 0x000051F2, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, + 0x00050080, 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, + 0x000056CD, 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, + 0x00004315, 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004315, + 0x000500AA, 0x00000009, 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, + 0x000061E2, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, + 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, + 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, + 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, + 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, + 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, + 0x00001CAA, 0x00005F43, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000061E2, + 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x00002C98, + 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x00002C98, 0x000200F8, 0x00002B38, 0x000500C4, + 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, + 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x00002C98, + 0x000200F8, 0x00002C98, 0x000700F5, 0x00000017, 0x00004D37, 0x00005879, 0x00003463, 0x000029E8, + 0x00002B38, 0x00060041, 0x00000294, 0x000060F9, 0x0000140E, 0x00000A0B, 0x000054B5, 0x0003003E, + 0x000060F9, 0x00004D37, 0x00050080, 0x0000000B, 0x000054B6, 0x000054B5, 0x00000A0E, 0x000300F7, + 0x00001AD7, 0x00000002, 0x000400FA, 0x00004376, 0x000055E9, 0x00001C25, 0x000200F8, 0x000055E9, + 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001C25, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001AD7, + 0x000700F5, 0x0000000B, 0x0000456F, 0x00000A6A, 0x000055E9, 0x00000A3A, 0x00001C25, 0x000500C2, + 0x0000000B, 0x000041C0, 0x0000456F, 0x00000A16, 0x00050080, 0x0000000B, 0x00002ADB, 0x00005665, + 0x000041C0, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, 0x00002ADB, 0x0004003D, + 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, + 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, + 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, + 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, + 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, + 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x00001AD7, 0x00003FF9, 0x00002958, + 0x000300F7, 0x00002C99, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, 0x00002C99, 0x000200F8, + 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, 0x000500C2, 0x00000017, + 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, + 0x000200F9, 0x00002C99, 0x000200F8, 0x00002C99, 0x000700F5, 0x00000017, 0x00004D39, 0x00002AAC, + 0x00003A1A, 0x000029E9, 0x00002B39, 0x00060041, 0x00000294, 0x00001F75, 0x0000140E, 0x00000A0B, + 0x000054B6, 0x0003003E, 0x00001F75, 0x00004D39, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, + 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_32bpb_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_32bpb_scaled_cs.h new file mode 100644 index 0000000..c5d2a01 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_32bpb_scaled_cs.h @@ -0,0 +1,587 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2603 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2603 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_4 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_2 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_2 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_2 + %23219 = OpBitwiseAnd %uint %10722 %uint_3 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_2 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %7338 = OpLoad %v4uint %20399 + %13760 = OpIEqual %bool %24990 %uint_1 + %21366 = OpIEqual %bool %24990 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %21313 %16376 %10583 + %19638 = OpIEqual %bool %24990 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %24825 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %24825 %19767 + %15532 = OpIAdd %uint %11197 %int_1 + %6417 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %6417 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_32 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_32 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %24764 %16377 %10584 + OpSelectionMerge %11417 None + OpBranchConditional %15139 %11065 %11417 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15532 + OpStore %8053 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_32bpb_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, + 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, + 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, + 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, + 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, + 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, + 0x00000787, 0x00000A16, 0x00000A1F, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, + 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, + 0x00000014, 0x00000A2B, 0x00000A13, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, + 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, + 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, + 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, + 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, + 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, + 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, + 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, + 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, + 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, + 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, + 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, + 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, + 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005F7D, 0x00003526, + 0x00000A10, 0x000500AB, 0x00000009, 0x000048EB, 0x00005F7D, 0x00000A0A, 0x000500C2, 0x0000000B, + 0x00001FCD, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x0000619E, 0x00001FCD, 0x00000A13, + 0x00050050, 0x00000011, 0x000022A7, 0x00003526, 0x00003526, 0x000500C2, 0x00000011, 0x00001BAF, + 0x000022A7, 0x00000787, 0x000500C7, 0x00000011, 0x00001997, 0x00001BAF, 0x000007A2, 0x00050041, + 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, + 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, + 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, + 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, + 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, + 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, + 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, + 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A2B, 0x0007004F, 0x00000011, + 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, + 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, + 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, + 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, + 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, + 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, + 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A17, 0x00050051, 0x0000000C, 0x000018DA, + 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, + 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, + 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, + 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, + 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, + 0x0000000B, 0x00001B12, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x00002BBD, 0x00001B12, + 0x00000A16, 0x00050051, 0x0000000B, 0x000029E2, 0x0000538B, 0x00000000, 0x000500C2, 0x0000000B, + 0x00001DEE, 0x000029E2, 0x00000A10, 0x00050051, 0x0000000B, 0x00002704, 0x0000538B, 0x00000001, + 0x00050050, 0x00000011, 0x00005C0B, 0x00001DEE, 0x00002704, 0x00050086, 0x00000011, 0x00001F69, + 0x00005C0B, 0x00001997, 0x00050051, 0x0000000B, 0x0000366C, 0x00001F69, 0x00000000, 0x000500C4, + 0x0000000B, 0x00004D4D, 0x0000366C, 0x00000A10, 0x00050051, 0x0000000B, 0x000051A9, 0x00001F69, + 0x00000001, 0x00050051, 0x0000000B, 0x000059EE, 0x0000538B, 0x00000002, 0x00060050, 0x00000014, + 0x000024C9, 0x00004D4D, 0x000051A9, 0x000059EE, 0x000300F7, 0x00005341, 0x00000002, 0x000400FA, + 0x000048EB, 0x0000537D, 0x00002DD9, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, 0x00002970, + 0x000024C9, 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, + 0x000024FD, 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000002, + 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4D, + 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, + 0x00005321, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, 0x00005321, + 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, + 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, + 0x00006242, 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, + 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, + 0x000049FC, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, + 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, + 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, + 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, + 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, + 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, 0x00050080, + 0x0000000C, 0x000035A3, 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, + 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, + 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, + 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, + 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, + 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, + 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, + 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, + 0x000047B4, 0x00000A22, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, + 0x0000000C, 0x00004ADE, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, + 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, + 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, + 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, + 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, + 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, + 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, + 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, + 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, + 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x00004158, 0x00000AC8, 0x00050080, + 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, 0x0000566F, 0x00005EFA, + 0x000200F9, 0x00005341, 0x000200F8, 0x00002DD9, 0x0007004F, 0x00000011, 0x00002621, 0x000024C9, + 0x000024C9, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000059CF, 0x00002621, 0x00050051, + 0x0000000C, 0x00001903, 0x000059CF, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FE, 0x00001903, + 0x00000A1A, 0x00050051, 0x0000000C, 0x00002748, 0x000059CF, 0x00000001, 0x000500C3, 0x0000000C, + 0x0000405D, 0x00002748, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00005788, 0x00000A19, + 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005347, 0x0000405D, + 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FE, 0x00005347, 0x000500C4, 0x0000000C, + 0x00004A8E, 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002AB6, 0x00001903, 0x00000A20, + 0x000500C7, 0x0000000C, 0x00003139, 0x00002748, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, + 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, + 0x0000000C, 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, + 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, + 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, + 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, + 0x00002748, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, + 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, + 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00004A33, 0x00002748, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, + 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, + 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, + 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002748, + 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, + 0x00001EEC, 0x00001903, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, + 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, + 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, + 0x0000000C, 0x00002E06, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4D, + 0x00002E06, 0x0004007C, 0x0000000B, 0x00005670, 0x0000394F, 0x000200F9, 0x00005341, 0x000200F8, + 0x00005341, 0x000700F5, 0x0000000B, 0x000024FC, 0x0000566F, 0x0000537D, 0x00005670, 0x00002DD9, + 0x00050084, 0x00000011, 0x00003FA8, 0x00001F69, 0x00001997, 0x00050082, 0x00000011, 0x00003BBC, + 0x00005C0B, 0x00003FA8, 0x00050051, 0x0000000B, 0x00001C87, 0x00001997, 0x00000000, 0x00050051, + 0x0000000B, 0x00005962, 0x00001997, 0x00000001, 0x00050084, 0x0000000B, 0x00003372, 0x00001C87, + 0x00005962, 0x00050084, 0x0000000B, 0x00003CA0, 0x000024FC, 0x00003372, 0x00050051, 0x0000000B, + 0x00003ED4, 0x00003BBC, 0x00000000, 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, 0x00005962, + 0x00050051, 0x0000000B, 0x00001AE6, 0x00003BBC, 0x00000001, 0x00050080, 0x0000000B, 0x00002B25, + 0x00003E12, 0x00001AE6, 0x000500C4, 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A10, 0x000500C7, + 0x0000000B, 0x00005AB3, 0x000029E2, 0x00000A13, 0x00050080, 0x0000000B, 0x00002557, 0x0000609D, + 0x00005AB3, 0x000500C4, 0x0000000B, 0x000040AD, 0x00002557, 0x00000A10, 0x00050080, 0x0000000B, + 0x00004EAA, 0x00003CA0, 0x000040AD, 0x00050080, 0x0000000B, 0x00003BA9, 0x00005EAC, 0x00004EAA, + 0x000500C2, 0x0000000B, 0x00003948, 0x00003BA9, 0x00000A16, 0x00060041, 0x00000294, 0x00004FAF, + 0x0000107A, 0x00000A0B, 0x00003948, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004FAF, 0x000500AA, + 0x00000009, 0x000035C0, 0x0000619E, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x0000619E, + 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, + 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, + 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, + 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, + 0x00005341, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x0000619E, 0x00000A13, + 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x00002C98, 0x00000000, + 0x000400FA, 0x00003B23, 0x00002B38, 0x00002C98, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, + 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, + 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x00002C98, 0x000200F8, + 0x00002C98, 0x000700F5, 0x00000017, 0x00004D37, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, + 0x00060041, 0x00000294, 0x000060F9, 0x0000140E, 0x00000A0B, 0x00002BBD, 0x0003003E, 0x000060F9, + 0x00004D37, 0x00050080, 0x0000000B, 0x00003CAC, 0x00002BBD, 0x00000A0E, 0x000500AC, 0x00000009, + 0x00001911, 0x00001C87, 0x00000A0D, 0x000300F7, 0x000060BC, 0x00000002, 0x000400FA, 0x00001911, + 0x00005084, 0x00005094, 0x000200F8, 0x00005084, 0x00050086, 0x0000000B, 0x00003697, 0x00001DEE, + 0x00001C87, 0x00050084, 0x0000000B, 0x0000237E, 0x00003697, 0x00001C87, 0x00050082, 0x0000000B, + 0x00003171, 0x00001DEE, 0x0000237E, 0x00050080, 0x0000000B, 0x00002527, 0x00003171, 0x00000A0D, + 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, 0x00001C87, 0x000300F7, 0x00001EED, 0x00000000, + 0x000400FA, 0x0000343F, 0x0000569E, 0x00002191, 0x000200F8, 0x0000569E, 0x00050084, 0x0000000B, + 0x00004B59, 0x00000A6A, 0x00001C87, 0x000500C4, 0x0000000B, 0x0000540F, 0x00003171, 0x00000A16, + 0x00050082, 0x0000000B, 0x00004944, 0x00004B59, 0x0000540F, 0x000200F9, 0x00001EED, 0x000200F8, + 0x00002191, 0x000200F9, 0x00001EED, 0x000200F8, 0x00001EED, 0x000700F5, 0x0000000B, 0x0000292C, + 0x00004944, 0x0000569E, 0x00000A3A, 0x00002191, 0x000200F9, 0x000060BC, 0x000200F8, 0x00005094, + 0x000200F9, 0x000060BC, 0x000200F8, 0x000060BC, 0x000700F5, 0x0000000B, 0x000029BC, 0x0000292C, + 0x00001EED, 0x00000A6A, 0x00005094, 0x00050084, 0x0000000B, 0x0000492B, 0x000029BC, 0x00005962, + 0x000500C2, 0x0000000B, 0x0000406D, 0x0000492B, 0x00000A16, 0x00050080, 0x0000000B, 0x0000336B, + 0x00003948, 0x0000406D, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, 0x0000336B, + 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, + 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, + 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, + 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, + 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, + 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x000060BC, 0x00003FF9, + 0x00002958, 0x000300F7, 0x00002C99, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, 0x00002C99, + 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, 0x000500C2, + 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, + 0x00003BE8, 0x000200F9, 0x00002C99, 0x000200F8, 0x00002C99, 0x000700F5, 0x00000017, 0x00004D39, + 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x00060041, 0x00000294, 0x00001F75, 0x0000140E, + 0x00000A0B, 0x00003CAC, 0x0003003E, 0x00001F75, 0x00004D39, 0x000200F9, 0x00004C7A, 0x000200F8, + 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_64bpb_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_64bpb_cs.h new file mode 100644 index 0000000..274a52a --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_64bpb_cs.h @@ -0,0 +1,526 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25059 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2596 = OpConstantComposite %v3uint %uint_2 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_9 = OpConstant %uint 9 + %uint_10 = OpConstant %uint 10 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2596 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_8 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_9 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_9 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_9 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_10 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_3 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %6362 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %22810 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %24825 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %24825 %19767 + %21686 = OpIAdd %uint %21685 %int_1 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_32 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %6871 %16377 %10584 + OpSelectionMerge %11417 None + OpBranchConditional %15139 %11065 %11417 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21686 + OpStore %8053 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_64bpb_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000061E3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, + 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, + 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, + 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, + 0x00000009, 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, + 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, + 0x00000A24, 0x00000A10, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, + 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, + 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0004002B, 0x0000000B, + 0x00000A25, 0x00000009, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0007002C, 0x00000017, + 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, + 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, + 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, + 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, + 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, + 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, 0x000500AB, + 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, 0x00003526, + 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, 0x0000000B, + 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, 0x00000A13, + 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, + 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, + 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, + 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, + 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, + 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, + 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, + 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A24, 0x0007004F, + 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, + 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, + 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, + 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, + 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, + 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, + 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A23, 0x00050051, 0x0000000C, + 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, + 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, + 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, + 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, + 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, + 0x00050080, 0x0000000B, 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x000054B5, + 0x00002764, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, 0x00005768, + 0x000051F2, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, 0x00004384, + 0x00002BF8, 0x000018D9, 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, 0x000032B3, 0x000044BE, + 0x00000A17, 0x000500C3, 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, 0x000500C2, 0x0000000B, + 0x00004947, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00004947, 0x00050084, + 0x0000000C, 0x00005321, 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000032B3, + 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, + 0x00003901, 0x00002348, 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, 0x00003901, 0x000500C3, + 0x0000000C, 0x000032BA, 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, 0x00005FEE, 0x000032BA, + 0x000020F4, 0x000500C4, 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A25, 0x000500C7, 0x0000000C, + 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, + 0x000044BE, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, + 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, + 0x00000A25, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, + 0x00002215, 0x000044BE, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000601E, + 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, + 0x00005BEB, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, + 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, + 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, + 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, + 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, + 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x000018DA, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A25, 0x00050080, 0x0000000C, + 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000044BE, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, + 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, + 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, + 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, + 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, + 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, + 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, 0x00005EA0, + 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, 0x000019AD, 0x000042F0, + 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, + 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, 0x00000001, 0x000500C3, + 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005788, + 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, + 0x0000405C, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, + 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A28, 0x000500C7, 0x0000000C, 0x00002AB6, 0x000042C2, + 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, + 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, + 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A13, 0x000500C7, 0x0000000C, 0x000027B1, + 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, + 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, + 0x000047B5, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, + 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, + 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, + 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, + 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, + 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, + 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, + 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, + 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x00002F42, + 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, 0x0000000C, + 0x0000292C, 0x000054ED, 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, 0x00005F43, 0x000200F8, + 0x000051F2, 0x0004007C, 0x0000000C, 0x00003CBC, 0x00005789, 0x00050084, 0x0000000C, 0x000060B8, + 0x000018DA, 0x00003CBC, 0x00050080, 0x0000000C, 0x0000208E, 0x000060B8, 0x000044BE, 0x0004007C, + 0x0000000C, 0x000022F8, 0x00005788, 0x00050084, 0x0000000C, 0x00001E9F, 0x0000208E, 0x000022F8, + 0x00050080, 0x0000000C, 0x00001F30, 0x0000591A, 0x00001E9F, 0x000200F9, 0x00005F43, 0x000200F8, + 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, 0x00001F30, 0x000051F2, + 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, 0x000056CD, 0x00001A3F, + 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, 0x0000000B, 0x00005665, + 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, 0x00004315, 0x0000107A, 0x00000A0B, 0x00005665, + 0x0004003D, 0x00000017, 0x00001CAA, 0x00004315, 0x000500AA, 0x00000009, 0x000035C0, 0x000061E2, + 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x000061E2, 0x00000A10, 0x000500A6, 0x00000009, + 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, + 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, + 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, + 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, + 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, + 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, 0x00005F43, 0x00003FF8, 0x00002957, + 0x000500AA, 0x00000009, 0x00004CB6, 0x000061E2, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, + 0x00005376, 0x00004CB6, 0x000300F7, 0x00002C98, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, + 0x00002C98, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, + 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, + 0x00005E17, 0x00003BE7, 0x000200F9, 0x00002C98, 0x000200F8, 0x00002C98, 0x000700F5, 0x00000017, + 0x00004D37, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x00060041, 0x00000294, 0x000060F9, + 0x0000140E, 0x00000A0B, 0x000054B5, 0x0003003E, 0x000060F9, 0x00004D37, 0x00050080, 0x0000000B, + 0x000054B6, 0x000054B5, 0x00000A0E, 0x000300F7, 0x00001AD7, 0x00000002, 0x000400FA, 0x00004376, + 0x000055E9, 0x00001C25, 0x000200F8, 0x000055E9, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001C25, + 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001AD7, 0x000700F5, 0x0000000B, 0x0000456F, 0x00000A6A, + 0x000055E9, 0x00000A3A, 0x00001C25, 0x000500C2, 0x0000000B, 0x000041C0, 0x0000456F, 0x00000A16, + 0x00050080, 0x0000000B, 0x00002ADB, 0x00005665, 0x000041C0, 0x00060041, 0x00000294, 0x0000571A, + 0x0000107A, 0x00000A0B, 0x00002ADB, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, + 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, + 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, + 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, + 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, + 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, + 0x000019B2, 0x00001AD7, 0x00003FF9, 0x00002958, 0x000300F7, 0x00002C99, 0x00000000, 0x000400FA, + 0x00003B23, 0x00002B39, 0x00002C99, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, + 0x00002AAC, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, + 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002C99, 0x000200F8, 0x00002C99, + 0x000700F5, 0x00000017, 0x00004D39, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x00060041, + 0x00000294, 0x00001F75, 0x0000140E, 0x00000A0B, 0x000054B6, 0x0003003E, 0x00001F75, 0x00004D39, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_64bpb_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_64bpb_scaled_cs.h new file mode 100644 index 0000000..8be75e3 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_64bpb_scaled_cs.h @@ -0,0 +1,588 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2596 = OpConstantComposite %v3uint %uint_2 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %uint_9 = OpConstant %uint 9 + %uint_10 = OpConstant %uint 10 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2596 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_8 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_1 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_1 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_9 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_9 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_9 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_10 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_3 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_1 + %23219 = OpBitwiseAnd %uint %10722 %uint_1 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_3 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %7338 = OpLoad %v4uint %20399 + %13760 = OpIEqual %bool %24990 %uint_1 + %21366 = OpIEqual %bool %24990 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %21313 %16376 %10583 + %19638 = OpIEqual %bool %24990 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %11416 None + OpBranchConditional %15139 %11064 %11416 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %24825 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %24825 %19767 + %15532 = OpIAdd %uint %11197 %int_1 + %6417 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %6417 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_32 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_32 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %24764 %16377 %10584 + OpSelectionMerge %11417 None + OpBranchConditional %15139 %11065 %11417 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15532 + OpStore %8053 %19769 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_64bpb_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, + 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, + 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, + 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, + 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, + 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, + 0x00000787, 0x00000A16, 0x00000A1F, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, + 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, + 0x00000014, 0x00000A24, 0x00000A10, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, + 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, + 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, + 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, + 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, + 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, + 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, + 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, + 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, + 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, + 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, + 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, + 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, + 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, + 0x000500C7, 0x0000000B, 0x00005F7D, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x000048EB, + 0x00005F7D, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001FCD, 0x00003526, 0x00000A10, 0x000500C7, + 0x0000000B, 0x0000619E, 0x00001FCD, 0x00000A13, 0x00050050, 0x00000011, 0x000022A7, 0x00003526, + 0x00003526, 0x000500C2, 0x00000011, 0x00001BAF, 0x000022A7, 0x00000787, 0x000500C7, 0x00000011, + 0x00001997, 0x00001BAF, 0x000007A2, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, + 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, + 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, + 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, + 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, + 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, + 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, + 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, + 0x00002A0E, 0x00000A24, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, + 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, + 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, + 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, + 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, + 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, + 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, + 0x00000A23, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, + 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, + 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, + 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, + 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, + 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00001B12, 0x00002A92, 0x0000578B, + 0x000500C2, 0x0000000B, 0x00002BBD, 0x00001B12, 0x00000A16, 0x00050051, 0x0000000B, 0x000029E2, + 0x0000538B, 0x00000000, 0x000500C2, 0x0000000B, 0x00001DEE, 0x000029E2, 0x00000A0D, 0x00050051, + 0x0000000B, 0x00002704, 0x0000538B, 0x00000001, 0x00050050, 0x00000011, 0x00005C0B, 0x00001DEE, + 0x00002704, 0x00050086, 0x00000011, 0x00001F69, 0x00005C0B, 0x00001997, 0x00050051, 0x0000000B, + 0x0000366C, 0x00001F69, 0x00000000, 0x000500C4, 0x0000000B, 0x00004D4D, 0x0000366C, 0x00000A0D, + 0x00050051, 0x0000000B, 0x000051A9, 0x00001F69, 0x00000001, 0x00050051, 0x0000000B, 0x000059EE, + 0x0000538B, 0x00000002, 0x00060050, 0x00000014, 0x000024C9, 0x00004D4D, 0x000051A9, 0x000059EE, + 0x000300F7, 0x00005341, 0x00000002, 0x000400FA, 0x000048EB, 0x0000537D, 0x00002DD9, 0x000200F8, + 0x0000537D, 0x0004007C, 0x00000016, 0x00002970, 0x000024C9, 0x00050051, 0x0000000C, 0x000042C2, + 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A17, 0x00050051, + 0x0000000C, 0x00002747, 0x00002970, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, + 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, + 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005321, 0x0000405C, 0x000018AA, 0x00050080, + 0x0000000C, 0x00003B27, 0x000024FD, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, + 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, + 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, 0x00002970, 0x00000000, 0x000500C3, + 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, + 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A25, 0x000500C7, 0x0000000C, + 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, + 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, + 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, + 0x00000A25, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, + 0x00002215, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405C, + 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, + 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, + 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, + 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, + 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, + 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, + 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A25, 0x00050080, 0x0000000C, + 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000042C2, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, + 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, + 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, + 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, + 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, + 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, + 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005559, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, + 0x0004007C, 0x0000000B, 0x0000566F, 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, 0x00002DD9, + 0x0007004F, 0x00000011, 0x00002621, 0x000024C9, 0x000024C9, 0x00000000, 0x00000001, 0x0004007C, + 0x00000012, 0x000059CF, 0x00002621, 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, 0x00000000, + 0x000500C3, 0x0000000C, 0x000024FE, 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002748, + 0x000059CF, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, 0x000500C2, + 0x0000000B, 0x00005B4E, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, + 0x00050084, 0x0000000C, 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, + 0x000024FE, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A28, 0x000500C7, + 0x0000000C, 0x00002AB6, 0x00001903, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002748, + 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, + 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A13, + 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, + 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, + 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, + 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, + 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, + 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, 0x000500C4, + 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, + 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, + 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, + 0x000500C7, 0x0000000C, 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, + 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x00001903, 0x00000A14, 0x00050080, + 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, + 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x00002E06, 0x00004159, 0x00000AC8, + 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4D, 0x00002E06, 0x0004007C, 0x0000000B, 0x00005670, + 0x0000394F, 0x000200F9, 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, 0x000024FC, + 0x0000566F, 0x0000537D, 0x00005670, 0x00002DD9, 0x00050084, 0x00000011, 0x00003FA8, 0x00001F69, + 0x00001997, 0x00050082, 0x00000011, 0x00003BBC, 0x00005C0B, 0x00003FA8, 0x00050051, 0x0000000B, + 0x00001C87, 0x00001997, 0x00000000, 0x00050051, 0x0000000B, 0x00005962, 0x00001997, 0x00000001, + 0x00050084, 0x0000000B, 0x00003372, 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, 0x00003CA0, + 0x000024FC, 0x00003372, 0x00050051, 0x0000000B, 0x00003ED4, 0x00003BBC, 0x00000000, 0x00050084, + 0x0000000B, 0x00003E12, 0x00003ED4, 0x00005962, 0x00050051, 0x0000000B, 0x00001AE6, 0x00003BBC, + 0x00000001, 0x00050080, 0x0000000B, 0x00002B25, 0x00003E12, 0x00001AE6, 0x000500C4, 0x0000000B, + 0x0000609D, 0x00002B25, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00005AB3, 0x000029E2, 0x00000A0D, + 0x00050080, 0x0000000B, 0x00002557, 0x0000609D, 0x00005AB3, 0x000500C4, 0x0000000B, 0x000040AD, + 0x00002557, 0x00000A13, 0x00050080, 0x0000000B, 0x00004EAA, 0x00003CA0, 0x000040AD, 0x00050080, + 0x0000000B, 0x00003BA9, 0x00005EAC, 0x00004EAA, 0x000500C2, 0x0000000B, 0x00003948, 0x00003BA9, + 0x00000A16, 0x00060041, 0x00000294, 0x00004FAF, 0x0000107A, 0x00000A0B, 0x00003948, 0x0004003D, + 0x00000017, 0x00001CAA, 0x00004FAF, 0x000500AA, 0x00000009, 0x000035C0, 0x0000619E, 0x00000A0D, + 0x000500AA, 0x00000009, 0x00005376, 0x0000619E, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, + 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, + 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, + 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, + 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, + 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, + 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, 0x00005341, 0x00003FF8, 0x00002957, 0x000500AA, + 0x00000009, 0x00004CB6, 0x0000619E, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, + 0x00004CB6, 0x000300F7, 0x00002C98, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x00002C98, + 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, + 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, + 0x00003BE7, 0x000200F9, 0x00002C98, 0x000200F8, 0x00002C98, 0x000700F5, 0x00000017, 0x00004D37, + 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x00060041, 0x00000294, 0x000060F9, 0x0000140E, + 0x00000A0B, 0x00002BBD, 0x0003003E, 0x000060F9, 0x00004D37, 0x00050080, 0x0000000B, 0x00003CAC, + 0x00002BBD, 0x00000A0E, 0x000500AC, 0x00000009, 0x00001911, 0x00001C87, 0x00000A0D, 0x000300F7, + 0x000060BC, 0x00000002, 0x000400FA, 0x00001911, 0x00005084, 0x00005094, 0x000200F8, 0x00005084, + 0x00050086, 0x0000000B, 0x00003697, 0x00001DEE, 0x00001C87, 0x00050084, 0x0000000B, 0x0000237E, + 0x00003697, 0x00001C87, 0x00050082, 0x0000000B, 0x00003171, 0x00001DEE, 0x0000237E, 0x00050080, + 0x0000000B, 0x00002527, 0x00003171, 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, + 0x00001C87, 0x000300F7, 0x00001EED, 0x00000000, 0x000400FA, 0x0000343F, 0x0000569E, 0x00002191, + 0x000200F8, 0x0000569E, 0x00050084, 0x0000000B, 0x00004B59, 0x00000A6A, 0x00001C87, 0x000500C4, + 0x0000000B, 0x0000540F, 0x00003171, 0x00000A16, 0x00050082, 0x0000000B, 0x00004944, 0x00004B59, + 0x0000540F, 0x000200F9, 0x00001EED, 0x000200F8, 0x00002191, 0x000200F9, 0x00001EED, 0x000200F8, + 0x00001EED, 0x000700F5, 0x0000000B, 0x0000292C, 0x00004944, 0x0000569E, 0x00000A3A, 0x00002191, + 0x000200F9, 0x000060BC, 0x000200F8, 0x00005094, 0x000200F9, 0x000060BC, 0x000200F8, 0x000060BC, + 0x000700F5, 0x0000000B, 0x000029BC, 0x0000292C, 0x00001EED, 0x00000A6A, 0x00005094, 0x00050084, + 0x0000000B, 0x0000492B, 0x000029BC, 0x00005962, 0x000500C2, 0x0000000B, 0x0000406D, 0x0000492B, + 0x00000A16, 0x00050080, 0x0000000B, 0x0000336B, 0x00003948, 0x0000406D, 0x00060041, 0x00000294, + 0x0000571A, 0x0000107A, 0x00000A0B, 0x0000336B, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, + 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, + 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, + 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, + 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, + 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, + 0x00002AAC, 0x000019B2, 0x000060BC, 0x00003FF9, 0x00002958, 0x000300F7, 0x00002C99, 0x00000000, + 0x000400FA, 0x00003B23, 0x00002B39, 0x00002C99, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, + 0x00005E18, 0x00002AAC, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, + 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002C99, 0x000200F8, + 0x00002C99, 0x000700F5, 0x00000017, 0x00004D39, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, + 0x00060041, 0x00000294, 0x00001F75, 0x0000140E, 0x00000A0B, 0x00003CAC, 0x0003003E, 0x00001F75, + 0x00004D39, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_8bpb_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_8bpb_cs.h new file mode 100644 index 0000000..d6a07d6 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_8bpb_cs.h @@ -0,0 +1,448 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 24810 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonReadable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %_runtimearr_v2uint ArrayStride 8 + OpDecorate %_struct_1960 BufferBlock + OpMemberDecorate %_struct_1960 0 NonWritable + OpMemberDecorate %_struct_1960 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %uint = OpTypeInt 32 0 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_1 = OpConstant %uint 1 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_2 = OpConstant %uint 2 + %uint_4 = OpConstant %uint 4 + %uint_6 = OpConstant %uint 6 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_3 = OpConstant %uint 3 + %uint_32 = OpConstant %uint 32 + %uint_64 = OpConstant %uint 64 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2612 = OpConstantComposite %v3uint %uint_4 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 + %v4uint = OpTypeVector %uint 4 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %5134 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_runtimearr_v2uint = OpTypeRuntimeArray %v2uint +%_struct_1960 = OpTypeStruct %_runtimearr_v2uint +%_ptr_Uniform__struct_1960 = OpTypePointer Uniform %_struct_1960 + %4218 = OpVariable %_ptr_Uniform__struct_1960 Uniform +%_ptr_Uniform_v2uint = OpTypePointer Uniform %v2uint +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_8 = OpConstant %uint 8 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %9877 = OpBitwiseAnd %uint %13606 %uint_2 + %17908 = OpINotEqual %bool %9877 %uint_0 + %8037 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %21025 = OpLoad %uint %8037 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2612 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %17741 = OpCompositeExtract %uint %22410 1 + %14100 = OpCompositeExtract %int %23478 0 + %20261 = OpCompositeExtract %int %23478 2 + %21501 = OpBitcast %int %17741 + %11279 = OpIMul %int %20261 %21501 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %14100 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17908 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %20261 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %14100 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_6 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %14100 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17742 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7048 = OpShiftLeftLogical %int %17227 %uint_6 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %14100 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %20261 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_6 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_7 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %16373 = OpShiftLeftLogical %int %12601 %int_2 + %10688 = OpIAdd %int %10934 %16373 + %11527 = OpBitcast %int %10688 + %16975 = OpBitwiseAnd %int %11527 %int_n16 + %24809 = OpShiftLeftLogical %int %16975 %int_1 + %15436 = OpIAdd %int %19086 %24809 + %13207 = OpBitwiseAnd %int %11527 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12150 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12150 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %20261 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %14100 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %21025 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_3 + %18636 = OpAccessChain %_ptr_Uniform_v2uint %4218 %int_0 %22117 + %14608 = OpLoad %v2uint %18636 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_64 %21993 %uint_8 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_3 + %10971 = OpIAdd %uint %22117 %16832 + %19144 = OpAccessChain %_ptr_Uniform_v2uint %4218 %int_0 %10971 + %13014 = OpLoad %v2uint %19144 + %19407 = OpCompositeExtract %uint %14608 0 + %23515 = OpCompositeExtract %uint %14608 1 + %7641 = OpCompositeExtract %uint %13014 0 + %7529 = OpCompositeExtract %uint %13014 1 + %18260 = OpCompositeConstruct %v4uint %19407 %23515 %7641 %7529 + %11979 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %11979 %18260 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_8bpb_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000060EA, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000019, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, 0x00000019, 0x00040047, 0x0000140E, + 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, 0x00000000, 0x00040047, 0x000007D6, + 0x00000006, 0x00000008, 0x00030047, 0x000007A8, 0x00000003, 0x00040048, 0x000007A8, 0x00000000, + 0x00000018, 0x00050048, 0x000007A8, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, + 0x00000018, 0x00040047, 0x0000107A, 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, + 0x00000001, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, + 0x0000000C, 0x00000002, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, + 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0004002B, 0x0000000B, 0x00000ACA, 0x00000040, + 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, + 0x00000009, 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, + 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, + 0x00000A34, 0x00000A16, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, + 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, + 0x0000140E, 0x00000002, 0x0003001D, 0x000007D6, 0x00000011, 0x0003001E, 0x000007A8, 0x000007D6, + 0x00040020, 0x00000A25, 0x00000002, 0x000007A8, 0x0004003B, 0x00000A25, 0x0000107A, 0x00000002, + 0x00040020, 0x0000028E, 0x00000002, 0x00000011, 0x00040020, 0x00000294, 0x00000002, 0x00000017, + 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0004002B, 0x0000000B, + 0x00000A22, 0x00000008, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, + 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, + 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, + 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, 0x000500AB, + 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00002695, 0x00003526, + 0x00000A10, 0x000500AB, 0x00000009, 0x000045F4, 0x00002695, 0x00000A0A, 0x00050041, 0x00000288, + 0x00001F65, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005221, 0x00001F65, 0x00050041, + 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, + 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, + 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, + 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, + 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, + 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, + 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A34, 0x0007004F, 0x00000011, 0x000042F0, + 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, + 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, + 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, + 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, + 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x0000454D, + 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00003714, 0x00005BB6, 0x00000000, 0x00050051, + 0x0000000C, 0x00004F25, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000053FD, 0x0000454D, + 0x00050084, 0x0000000C, 0x00002C0F, 0x00004F25, 0x000053FD, 0x00050051, 0x0000000C, 0x000044BE, + 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, + 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, + 0x00050080, 0x0000000C, 0x00002042, 0x00003714, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, + 0x00002042, 0x00050080, 0x0000000B, 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, + 0x000054B5, 0x00002764, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, + 0x00005768, 0x000051F2, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, + 0x000045F4, 0x00002BF8, 0x000018D9, 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, 0x000032B3, + 0x000044BE, 0x00000A17, 0x000500C3, 0x0000000C, 0x0000601E, 0x00004F25, 0x00000A11, 0x000500C2, + 0x0000000B, 0x00004947, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00004947, + 0x00050084, 0x0000000C, 0x00005321, 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, + 0x000032B3, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, + 0x0000000C, 0x00003901, 0x00002348, 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, 0x00003901, + 0x000500C3, 0x0000000C, 0x000032BA, 0x00003714, 0x00000A1A, 0x00050080, 0x0000000C, 0x00005FEE, + 0x000032BA, 0x000020F4, 0x000500C4, 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A1C, 0x000500C7, + 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, + 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00003714, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003138, 0x000044BE, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003138, 0x00000A11, + 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454E, 0x000500C4, 0x0000000C, 0x00001B88, + 0x0000434B, 0x00000A1C, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, + 0x0000000C, 0x00002215, 0x000044BE, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, + 0x0000601E, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, + 0x00004112, 0x00003714, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, + 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, + 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, + 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, + 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, + 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, + 0x00004F25, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A1C, 0x00050080, + 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000044BE, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, + 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, + 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, + 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, + 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, + 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, + 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, + 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, 0x000019AD, + 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, + 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, 0x00000001, + 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, + 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, 0x0000000C, + 0x00005347, 0x0000405C, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, + 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A1F, 0x000500C7, 0x0000000C, 0x00002AB6, + 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, 0x000500C4, + 0x0000000C, 0x00003FF5, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x000029C0, 0x00002AB6, + 0x00003FF5, 0x0004007C, 0x0000000C, 0x00002D07, 0x000029C0, 0x000500C7, 0x0000000C, 0x0000424F, + 0x00002D07, 0x000009DB, 0x000500C4, 0x0000000C, 0x000060E9, 0x0000424F, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4C, 0x00004A8E, 0x000060E9, 0x000500C7, 0x0000000C, 0x00003397, 0x00002D07, + 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, + 0x000047B5, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, + 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, + 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F76, 0x00004A33, + 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F76, 0x000500C7, 0x0000000C, + 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, + 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, + 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, + 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, + 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x00002F42, + 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, 0x0000000C, + 0x0000292C, 0x000054ED, 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, 0x00005F43, 0x000200F8, + 0x000051F2, 0x0004007C, 0x0000000C, 0x00003CBC, 0x00005789, 0x00050084, 0x0000000C, 0x000060B8, + 0x00004F25, 0x00003CBC, 0x00050080, 0x0000000C, 0x0000208E, 0x000060B8, 0x000044BE, 0x0004007C, + 0x0000000C, 0x000022F8, 0x00005788, 0x00050084, 0x0000000C, 0x00001E9F, 0x0000208E, 0x000022F8, + 0x00050080, 0x0000000C, 0x00001F30, 0x00003714, 0x00001E9F, 0x000200F9, 0x00005F43, 0x000200F8, + 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, 0x00001F30, 0x000051F2, + 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005221, 0x00050080, 0x0000000C, 0x000056CD, 0x00001A3F, + 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, 0x0000000B, 0x00005665, + 0x00003EE9, 0x00000A13, 0x00060041, 0x0000028E, 0x000048CC, 0x0000107A, 0x00000A0B, 0x00005665, + 0x0004003D, 0x00000011, 0x00003910, 0x000048CC, 0x000300F7, 0x00001AD7, 0x00000002, 0x000400FA, + 0x00004376, 0x000055E9, 0x00001C25, 0x000200F8, 0x000055E9, 0x000200F9, 0x00001AD7, 0x000200F8, + 0x00001C25, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001AD7, 0x000700F5, 0x0000000B, 0x0000456F, + 0x00000ACA, 0x000055E9, 0x00000A22, 0x00001C25, 0x000500C2, 0x0000000B, 0x000041C0, 0x0000456F, + 0x00000A13, 0x00050080, 0x0000000B, 0x00002ADB, 0x00005665, 0x000041C0, 0x00060041, 0x0000028E, + 0x00004AC8, 0x0000107A, 0x00000A0B, 0x00002ADB, 0x0004003D, 0x00000011, 0x000032D6, 0x00004AC8, + 0x00050051, 0x0000000B, 0x00004BCF, 0x00003910, 0x00000000, 0x00050051, 0x0000000B, 0x00005BDB, + 0x00003910, 0x00000001, 0x00050051, 0x0000000B, 0x00001DD9, 0x000032D6, 0x00000000, 0x00050051, + 0x0000000B, 0x00001D69, 0x000032D6, 0x00000001, 0x00070050, 0x00000017, 0x00004754, 0x00004BCF, + 0x00005BDB, 0x00001DD9, 0x00001D69, 0x00060041, 0x00000294, 0x00002ECB, 0x0000140E, 0x00000A0B, + 0x000054B5, 0x0003003E, 0x00002ECB, 0x00004754, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, + 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_8bpb_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_8bpb_scaled_cs.h new file mode 100644 index 0000000..529981a --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_8bpb_scaled_cs.h @@ -0,0 +1,507 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonReadable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %_runtimearr_v2uint ArrayStride 8 + OpDecorate %_struct_1960 BufferBlock + OpMemberDecorate %_struct_1960 0 NonWritable + OpMemberDecorate %_struct_1960 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_1 = OpConstant %uint 1 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_2 = OpConstant %uint 2 + %uint_4 = OpConstant %uint 4 + %uint_6 = OpConstant %uint 6 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_3 = OpConstant %uint 3 + %uint_32 = OpConstant %uint 32 + %uint_64 = OpConstant %uint 64 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2612 = OpConstantComposite %v3uint %uint_4 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 + %v4uint = OpTypeVector %uint 4 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %5134 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_runtimearr_v2uint = OpTypeRuntimeArray %v2uint +%_struct_1960 = OpTypeStruct %_runtimearr_v2uint +%_ptr_Uniform__struct_1960 = OpTypePointer Uniform %_struct_1960 + %4218 = OpVariable %_ptr_Uniform__struct_1960 Uniform +%_ptr_Uniform_v2uint = OpTypePointer Uniform %v2uint +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %uint_8 = OpConstant %uint 8 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %22279 = OpBitwiseAnd %uint %13606 %uint_2 + %19223 = OpINotEqual %bool %22279 %uint_0 + %17247 = OpCompositeConstruct %v2uint %13606 %13606 + %22947 = OpShiftRightLogical %v2uint %17247 %1927 + %6551 = OpBitwiseAnd %v2uint %22947 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2612 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %17741 = OpCompositeExtract %uint %22410 1 + %14100 = OpCompositeExtract %int %23478 0 + %20261 = OpCompositeExtract %int %23478 2 + %21501 = OpBitcast %int %17741 + %11279 = OpIMul %int %20261 %21501 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %14100 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_3 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_3 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %19223 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_6 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17742 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7048 = OpShiftLeftLogical %int %17227 %uint_6 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_6 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_7 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %16373 = OpShiftLeftLogical %int %12601 %int_2 + %10688 = OpIAdd %int %10934 %16373 + %11527 = OpBitcast %int %10688 + %16975 = OpBitwiseAnd %int %11527 %int_n16 + %24809 = OpShiftLeftLogical %int %16975 %int_1 + %15436 = OpIAdd %int %19086 %24809 + %13207 = OpBitwiseAnd %int %11527 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12150 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12150 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_3 + %21925 = OpBitwiseAnd %uint %10722 %uint_7 + %21323 = OpIAdd %uint %24733 %21925 + %9262 = OpIAdd %uint %15520 %21323 + %24701 = OpIAdd %uint %24236 %9262 + %14664 = OpShiftRightLogical %uint %24701 %uint_3 + %20437 = OpAccessChain %_ptr_Uniform_v2uint %4218 %int_0 %14664 + %8455 = OpLoad %v2uint %20437 + %23791 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %23791 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_64 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_3 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_8 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_64 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_3 + %13163 = OpIAdd %uint %14664 %16493 + %19144 = OpAccessChain %_ptr_Uniform_v2uint %4218 %int_0 %13163 + %13014 = OpLoad %v2uint %19144 + %19407 = OpCompositeExtract %uint %8455 0 + %23515 = OpCompositeExtract %uint %8455 1 + %7641 = OpCompositeExtract %uint %13014 0 + %7529 = OpCompositeExtract %uint %13014 1 + %18260 = OpCompositeConstruct %v4uint %19407 %23515 %7641 %7529 + %11979 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %11979 %18260 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_8bpb_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000019, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, 0x00000019, 0x00040047, 0x0000140E, + 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, 0x00000000, 0x00040047, 0x000007D6, + 0x00000006, 0x00000008, 0x00030047, 0x000007A8, 0x00000003, 0x00040048, 0x000007A8, 0x00000000, + 0x00000018, 0x00050048, 0x000007A8, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, + 0x00000018, 0x00040047, 0x0000107A, 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, + 0x00000001, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, + 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, + 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0004002B, 0x0000000B, 0x00000ACA, 0x00000040, + 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, + 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, 0x00000787, 0x00000A16, 0x00000A1F, 0x00040020, + 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, + 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A34, 0x00000A16, 0x00000A0A, + 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, + 0x00000004, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, + 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000140E, 0x00000002, 0x0003001D, + 0x000007D6, 0x00000011, 0x0003001E, 0x000007A8, 0x000007D6, 0x00040020, 0x00000A25, 0x00000002, + 0x000007A8, 0x0004003B, 0x00000A25, 0x0000107A, 0x00000002, 0x00040020, 0x0000028E, 0x00000002, + 0x00000011, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0006002C, 0x00000014, 0x00000BC3, + 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, + 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, + 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, + 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005707, 0x00003526, + 0x00000A10, 0x000500AB, 0x00000009, 0x00004B17, 0x00005707, 0x00000A0A, 0x00050050, 0x00000011, + 0x0000435F, 0x00003526, 0x00003526, 0x000500C2, 0x00000011, 0x000059A3, 0x0000435F, 0x00000787, + 0x000500C7, 0x00000011, 0x00001997, 0x000059A3, 0x000007A2, 0x00050041, 0x00000288, 0x0000492C, + 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, + 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, + 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, + 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, + 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, + 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, + 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, + 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A34, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, + 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, + 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, + 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, + 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, + 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x0000454D, 0x0000578A, + 0x00000001, 0x00050051, 0x0000000C, 0x00003714, 0x00005BB6, 0x00000000, 0x00050051, 0x0000000C, + 0x00004F25, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000053FD, 0x0000454D, 0x00050084, + 0x0000000C, 0x00002C0F, 0x00004F25, 0x000053FD, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, + 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, + 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, + 0x0000000C, 0x00002042, 0x00003714, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, + 0x00050080, 0x0000000B, 0x00001B12, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x00002BBD, + 0x00001B12, 0x00000A16, 0x00050051, 0x0000000B, 0x000029E2, 0x0000538B, 0x00000000, 0x000500C2, + 0x0000000B, 0x00001DEE, 0x000029E2, 0x00000A13, 0x00050051, 0x0000000B, 0x00002704, 0x0000538B, + 0x00000001, 0x00050050, 0x00000011, 0x00005C0B, 0x00001DEE, 0x00002704, 0x00050086, 0x00000011, + 0x00001F69, 0x00005C0B, 0x00001997, 0x00050051, 0x0000000B, 0x0000366C, 0x00001F69, 0x00000000, + 0x000500C4, 0x0000000B, 0x00004D4D, 0x0000366C, 0x00000A13, 0x00050051, 0x0000000B, 0x000051A9, + 0x00001F69, 0x00000001, 0x00050051, 0x0000000B, 0x000059EE, 0x0000538B, 0x00000002, 0x00060050, + 0x00000014, 0x000024C9, 0x00004D4D, 0x000051A9, 0x000059EE, 0x000300F7, 0x00005341, 0x00000002, + 0x000400FA, 0x00004B17, 0x0000537D, 0x00002DD9, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, + 0x00002970, 0x000024C9, 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, + 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, + 0x00000002, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, + 0x00005B4D, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, + 0x0000000C, 0x00005321, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, + 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, + 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, + 0x0000000C, 0x00006242, 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, + 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, + 0x0000225D, 0x000049FC, 0x00000A1C, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, + 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, + 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, + 0x0000000C, 0x0000454E, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, + 0x0000454E, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A1C, 0x000500C3, 0x0000000C, + 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, + 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, + 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, + 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, + 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, + 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, + 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, + 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544B, 0x000047B4, 0x00000A1C, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, + 0x000500C7, 0x0000000C, 0x00004ADE, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, + 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, + 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, + 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, + 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, + 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, + 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, + 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, + 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, + 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x00004158, 0x00000AC8, + 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, 0x0000566F, + 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, 0x00002DD9, 0x0007004F, 0x00000011, 0x00002621, + 0x000024C9, 0x000024C9, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000059CF, 0x00002621, + 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FE, + 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002748, 0x000059CF, 0x00000001, 0x000500C3, + 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00005788, + 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005347, + 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FE, 0x00005347, 0x000500C4, + 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A1F, 0x000500C7, 0x0000000C, 0x00002AB6, 0x00001903, + 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002748, 0x00000A35, 0x000500C4, 0x0000000C, + 0x00003FF5, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x000029C0, 0x00002AB6, 0x00003FF5, + 0x0004007C, 0x0000000C, 0x00002D07, 0x000029C0, 0x000500C7, 0x0000000C, 0x0000424F, 0x00002D07, + 0x000009DB, 0x000500C4, 0x0000000C, 0x000060E9, 0x0000424F, 0x00000A0E, 0x00050080, 0x0000000C, + 0x00003C4C, 0x00004A8E, 0x000060E9, 0x000500C7, 0x0000000C, 0x00003397, 0x00002D07, 0x00000A38, + 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, + 0x00002748, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, + 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, + 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00004A33, 0x00002748, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F76, 0x00004A33, 0x00000A20, + 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F76, 0x000500C7, 0x0000000C, 0x00004ADF, + 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, + 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002748, + 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, + 0x00001EEC, 0x00001903, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, + 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, + 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, + 0x0000000C, 0x00002E06, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4D, + 0x00002E06, 0x0004007C, 0x0000000B, 0x00005670, 0x0000394F, 0x000200F9, 0x00005341, 0x000200F8, + 0x00005341, 0x000700F5, 0x0000000B, 0x000024FC, 0x0000566F, 0x0000537D, 0x00005670, 0x00002DD9, + 0x00050084, 0x00000011, 0x00003FA8, 0x00001F69, 0x00001997, 0x00050082, 0x00000011, 0x00003BBC, + 0x00005C0B, 0x00003FA8, 0x00050051, 0x0000000B, 0x00001C87, 0x00001997, 0x00000000, 0x00050051, + 0x0000000B, 0x00005962, 0x00001997, 0x00000001, 0x00050084, 0x0000000B, 0x00003372, 0x00001C87, + 0x00005962, 0x00050084, 0x0000000B, 0x00003CA0, 0x000024FC, 0x00003372, 0x00050051, 0x0000000B, + 0x00003ED4, 0x00003BBC, 0x00000000, 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, 0x00005962, + 0x00050051, 0x0000000B, 0x00001AE6, 0x00003BBC, 0x00000001, 0x00050080, 0x0000000B, 0x00002B25, + 0x00003E12, 0x00001AE6, 0x000500C4, 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A13, 0x000500C7, + 0x0000000B, 0x000055A5, 0x000029E2, 0x00000A1F, 0x00050080, 0x0000000B, 0x0000534B, 0x0000609D, + 0x000055A5, 0x00050080, 0x0000000B, 0x0000242E, 0x00003CA0, 0x0000534B, 0x00050080, 0x0000000B, + 0x0000607D, 0x00005EAC, 0x0000242E, 0x000500C2, 0x0000000B, 0x00003948, 0x0000607D, 0x00000A13, + 0x00060041, 0x0000028E, 0x00004FD5, 0x0000107A, 0x00000A0B, 0x00003948, 0x0004003D, 0x00000011, + 0x00002107, 0x00004FD5, 0x000500AC, 0x00000009, 0x00005CEF, 0x00001C87, 0x00000A0D, 0x000300F7, + 0x000060BC, 0x00000002, 0x000400FA, 0x00005CEF, 0x00005084, 0x00005094, 0x000200F8, 0x00005084, + 0x00050086, 0x0000000B, 0x00003697, 0x00001DEE, 0x00001C87, 0x00050084, 0x0000000B, 0x0000237E, + 0x00003697, 0x00001C87, 0x00050082, 0x0000000B, 0x00003171, 0x00001DEE, 0x0000237E, 0x00050080, + 0x0000000B, 0x00002527, 0x00003171, 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, + 0x00001C87, 0x000300F7, 0x00001EED, 0x00000000, 0x000400FA, 0x0000343F, 0x0000569E, 0x00002191, + 0x000200F8, 0x0000569E, 0x00050084, 0x0000000B, 0x00004B59, 0x00000ACA, 0x00001C87, 0x000500C4, + 0x0000000B, 0x0000540F, 0x00003171, 0x00000A13, 0x00050082, 0x0000000B, 0x00004944, 0x00004B59, + 0x0000540F, 0x000200F9, 0x00001EED, 0x000200F8, 0x00002191, 0x000200F9, 0x00001EED, 0x000200F8, + 0x00001EED, 0x000700F5, 0x0000000B, 0x0000292C, 0x00004944, 0x0000569E, 0x00000A22, 0x00002191, + 0x000200F9, 0x000060BC, 0x000200F8, 0x00005094, 0x000200F9, 0x000060BC, 0x000200F8, 0x000060BC, + 0x000700F5, 0x0000000B, 0x000029BC, 0x0000292C, 0x00001EED, 0x00000ACA, 0x00005094, 0x00050084, + 0x0000000B, 0x0000492B, 0x000029BC, 0x00005962, 0x000500C2, 0x0000000B, 0x0000406D, 0x0000492B, + 0x00000A13, 0x00050080, 0x0000000B, 0x0000336B, 0x00003948, 0x0000406D, 0x00060041, 0x0000028E, + 0x00004AC8, 0x0000107A, 0x00000A0B, 0x0000336B, 0x0004003D, 0x00000011, 0x000032D6, 0x00004AC8, + 0x00050051, 0x0000000B, 0x00004BCF, 0x00002107, 0x00000000, 0x00050051, 0x0000000B, 0x00005BDB, + 0x00002107, 0x00000001, 0x00050051, 0x0000000B, 0x00001DD9, 0x000032D6, 0x00000000, 0x00050051, + 0x0000000B, 0x00001D69, 0x000032D6, 0x00000001, 0x00070050, 0x00000017, 0x00004754, 0x00004BCF, + 0x00005BDB, 0x00001DD9, 0x00001D69, 0x00060041, 0x00000294, 0x00002ECB, 0x0000140E, 0x00000A0B, + 0x00002BBD, 0x0003003E, 0x00002ECB, 0x00004754, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, + 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_bgrg8_rgb8_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_bgrg8_rgb8_cs.h new file mode 100644 index 0000000..11b4392 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_bgrg8_rgb8_cs.h @@ -0,0 +1,676 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25175 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 +%uint_16711680 = OpConstant %uint 16711680 + %uint_16 = OpConstant %uint 16 + %uint_255 = OpConstant %uint 255 + %uint_257 = OpConstant %uint 257 + %uint_65280 = OpConstant %uint 65280 +%uint_4278190080 = OpConstant %uint 4278190080 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2603 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %2993 = OpConstantComposite %v2uint %uint_16711680 %uint_16711680 + %2143 = OpConstantComposite %v2uint %uint_16 %uint_16 + %1140 = OpConstantComposite %v2uint %uint_255 %uint_255 + %1182 = OpConstantComposite %v2uint %uint_257 %uint_257 + %2682 = OpConstantComposite %v2uint %uint_65280 %uint_65280 + %2014 = OpConstantComposite %v2uint %uint_4278190080 %uint_4278190080 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2603 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_8 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %19442 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %19442 = OpLabel + %8677 = OpIMul %int %23531 %int_4 + %17569 = OpBitcast %int %22409 + %8690 = OpIMul %int %6362 %17569 + %8334 = OpIAdd %int %8690 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %8677 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %19442 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %11682 None + OpBranchConditional %15139 %11064 %11682 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11682 + %11682 = OpLabel + %19948 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %21173 = OpVectorShuffle %v2uint %19948 %19948 0 1 + %12738 = OpBitwiseAnd %v2uint %21173 %2993 + %21619 = OpShiftRightLogical %v2uint %12738 %2143 + %6955 = OpBitwiseAnd %v2uint %21173 %1140 + %16264 = OpShiftLeftLogical %v2uint %6955 %2143 + %22500 = OpIMul %v2uint %16264 %1182 + %9857 = OpBitwiseOr %v2uint %21619 %22500 + %7416 = OpBitwiseAnd %v2uint %21173 %2682 + %16088 = OpBitwiseAnd %v2uint %21173 %2014 + %21002 = OpShiftRightLogical %v2uint %16088 %2143 + %7420 = OpCompositeExtract %uint %7416 0 + %24539 = OpCompositeExtract %uint %7416 1 + %7641 = OpCompositeExtract %uint %21002 0 + %7795 = OpCompositeExtract %uint %21002 1 + %16161 = OpCompositeConstruct %v4uint %7420 %24539 %7641 %7795 + %7774 = OpVectorShuffle %v4uint %16161 %16161 0 2 1 3 + %6860 = OpVectorShuffle %v4uint %9857 %9857 0 0 1 1 + %24909 = OpBitwiseOr %v4uint %6860 %7774 + %17181 = OpVectorShuffle %v2uint %19948 %19948 2 3 + %6311 = OpBitwiseAnd %v2uint %17181 %2993 + %21620 = OpShiftRightLogical %v2uint %6311 %2143 + %6956 = OpBitwiseAnd %v2uint %17181 %1140 + %16265 = OpShiftLeftLogical %v2uint %6956 %2143 + %22501 = OpIMul %v2uint %16265 %1182 + %9858 = OpBitwiseOr %v2uint %21620 %22501 + %7417 = OpBitwiseAnd %v2uint %17181 %2682 + %16089 = OpBitwiseAnd %v2uint %17181 %2014 + %21003 = OpShiftRightLogical %v2uint %16089 %2143 + %7421 = OpCompositeExtract %uint %7417 0 + %24541 = OpCompositeExtract %uint %7417 1 + %7642 = OpCompositeExtract %uint %21003 0 + %7796 = OpCompositeExtract %uint %21003 1 + %16162 = OpCompositeConstruct %v4uint %7421 %24541 %7642 %7796 + %7775 = OpVectorShuffle %v4uint %16162 %16162 0 2 1 3 + %6595 = OpVectorShuffle %v4uint %9858 %9858 0 0 1 1 + %24728 = OpBitwiseOr %v4uint %6595 %7775 + %8219 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %8219 %24909 + %11457 = OpIAdd %uint %21685 %uint_1 + %25136 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11457 + OpStore %25136 %24728 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_32 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %6871 %16377 %10584 + OpSelectionMerge %11683 None + OpBranchConditional %15139 %11065 %11683 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11683 + %11683 = OpLabel + %19949 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %21174 = OpVectorShuffle %v2uint %19949 %19949 0 1 + %12739 = OpBitwiseAnd %v2uint %21174 %2993 + %21621 = OpShiftRightLogical %v2uint %12739 %2143 + %6957 = OpBitwiseAnd %v2uint %21174 %1140 + %16266 = OpShiftLeftLogical %v2uint %6957 %2143 + %22502 = OpIMul %v2uint %16266 %1182 + %9859 = OpBitwiseOr %v2uint %21621 %22502 + %7418 = OpBitwiseAnd %v2uint %21174 %2682 + %16090 = OpBitwiseAnd %v2uint %21174 %2014 + %21004 = OpShiftRightLogical %v2uint %16090 %2143 + %7422 = OpCompositeExtract %uint %7418 0 + %24542 = OpCompositeExtract %uint %7418 1 + %7643 = OpCompositeExtract %uint %21004 0 + %7797 = OpCompositeExtract %uint %21004 1 + %16163 = OpCompositeConstruct %v4uint %7422 %24542 %7643 %7797 + %7776 = OpVectorShuffle %v4uint %16163 %16163 0 2 1 3 + %6861 = OpVectorShuffle %v4uint %9859 %9859 0 0 1 1 + %24910 = OpBitwiseOr %v4uint %6861 %7776 + %17182 = OpVectorShuffle %v2uint %19949 %19949 2 3 + %6312 = OpBitwiseAnd %v2uint %17182 %2993 + %21622 = OpShiftRightLogical %v2uint %6312 %2143 + %6958 = OpBitwiseAnd %v2uint %17182 %1140 + %16267 = OpShiftLeftLogical %v2uint %6958 %2143 + %22503 = OpIMul %v2uint %16267 %1182 + %9860 = OpBitwiseOr %v2uint %21622 %22503 + %7419 = OpBitwiseAnd %v2uint %17182 %2682 + %16091 = OpBitwiseAnd %v2uint %17182 %2014 + %21005 = OpShiftRightLogical %v2uint %16091 %2143 + %7423 = OpCompositeExtract %uint %7419 0 + %24543 = OpCompositeExtract %uint %7419 1 + %7644 = OpCompositeExtract %uint %21005 0 + %7798 = OpCompositeExtract %uint %21005 1 + %16164 = OpCompositeConstruct %v4uint %7423 %24543 %7644 %7798 + %7777 = OpVectorShuffle %v4uint %16164 %16164 0 2 1 3 + %7791 = OpVectorShuffle %v4uint %9860 %9860 0 0 1 1 + %13886 = OpBitwiseOr %v4uint %7791 %7777 + %17818 = OpIAdd %uint %21685 %uint_2 + %6441 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %17818 + OpStore %6441 %24910 + %11458 = OpIAdd %uint %21685 %uint_3 + %25174 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11458 + OpStore %25174 %13886 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_bgrg8_rgb8_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006257, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x000005A9, 0x00FF0000, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, + 0x0004002B, 0x0000000B, 0x00000144, 0x000000FF, 0x0004002B, 0x0000000B, 0x0000014A, 0x00000101, + 0x0004002B, 0x0000000B, 0x00000A87, 0x0000FF00, 0x0004002B, 0x0000000B, 0x00000580, 0xFF000000, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, + 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, + 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, + 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, + 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, + 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x00040020, 0x00000291, + 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, + 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A2B, 0x00000A13, 0x00000A0A, 0x00000A0A, + 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, + 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, + 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, + 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, + 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, + 0x00000A6A, 0x00000A0D, 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0007002C, 0x00000017, + 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, + 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, + 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000011, 0x00000BB1, 0x000005A9, 0x000005A9, 0x0005002C, + 0x00000011, 0x0000085F, 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000011, 0x00000474, 0x00000144, + 0x00000144, 0x0005002C, 0x00000011, 0x0000049E, 0x0000014A, 0x0000014A, 0x0005002C, 0x00000011, + 0x00000A7A, 0x00000A87, 0x00000A87, 0x0005002C, 0x00000011, 0x000007DE, 0x00000580, 0x00000580, + 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, + 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, + 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, + 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, + 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, + 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, + 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, + 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, + 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, + 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, + 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, + 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, + 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, + 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, + 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A2B, 0x0007004F, 0x00000011, 0x000042F0, + 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, + 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, + 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, + 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, + 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, + 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, + 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A23, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, + 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, + 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, + 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, + 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, + 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, + 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x000054B5, 0x00002764, 0x00000A16, + 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, 0x00005768, 0x00004BF2, 0x000200F8, + 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, 0x00004384, 0x00002BF8, 0x000018D9, + 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, 0x000032B3, 0x000044BE, 0x00000A17, 0x000500C3, + 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, 0x000500C2, 0x0000000B, 0x00004947, 0x00005789, + 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00004947, 0x00050084, 0x0000000C, 0x00005321, + 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000032B3, 0x00005321, 0x000500C2, + 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x00003901, 0x00002348, + 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, 0x00003901, 0x000500C3, 0x0000000C, 0x000032BA, + 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, 0x00005FEE, 0x000032BA, 0x000020F4, 0x000500C4, + 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, + 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, + 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000044BE, 0x00000A1D, + 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, + 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A22, 0x000500C3, + 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000044BE, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000601E, 0x000500C7, 0x0000000C, + 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00005BEB, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, + 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, + 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, + 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, + 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x000018DA, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, + 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000044BE, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, + 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, + 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, + 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, + 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, + 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, + 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, + 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, + 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, + 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, + 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, + 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, + 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005788, 0x00000A19, 0x0004007C, + 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AB, + 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, + 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, + 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, + 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, + 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, + 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, + 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, + 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002747, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, + 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, + 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, + 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, + 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, + 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, + 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, + 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, + 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, + 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, + 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, + 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, + 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, + 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, 0x00005F43, 0x000200F8, 0x00004BF2, 0x00050084, + 0x0000000C, 0x000021E5, 0x00005BEB, 0x00000A17, 0x0004007C, 0x0000000C, 0x000044A1, 0x00005789, + 0x00050084, 0x0000000C, 0x000021F2, 0x000018DA, 0x000044A1, 0x00050080, 0x0000000C, 0x0000208E, + 0x000021F2, 0x000044BE, 0x0004007C, 0x0000000C, 0x000022F8, 0x00005788, 0x00050084, 0x0000000C, + 0x00001E9F, 0x0000208E, 0x000022F8, 0x00050080, 0x0000000C, 0x00001F30, 0x000021E5, 0x00001E9F, + 0x000200F9, 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, + 0x00001E0B, 0x00001F30, 0x00004BF2, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, + 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, + 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, 0x00004315, + 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004315, 0x000500AA, + 0x00000009, 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x000061E2, + 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, + 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, + 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, + 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, + 0x00005F43, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000061E2, 0x00000A13, + 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x00002DA2, 0x00000000, + 0x000400FA, 0x00003B23, 0x00002B38, 0x00002DA2, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, + 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, + 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x00002DA2, 0x000200F8, + 0x00002DA2, 0x000700F5, 0x00000017, 0x00004DEC, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, + 0x0007004F, 0x00000011, 0x000052B5, 0x00004DEC, 0x00004DEC, 0x00000000, 0x00000001, 0x000500C7, + 0x00000011, 0x000031C2, 0x000052B5, 0x00000BB1, 0x000500C2, 0x00000011, 0x00005473, 0x000031C2, + 0x0000085F, 0x000500C7, 0x00000011, 0x00001B2B, 0x000052B5, 0x00000474, 0x000500C4, 0x00000011, + 0x00003F88, 0x00001B2B, 0x0000085F, 0x00050084, 0x00000011, 0x000057E4, 0x00003F88, 0x0000049E, + 0x000500C5, 0x00000011, 0x00002681, 0x00005473, 0x000057E4, 0x000500C7, 0x00000011, 0x00001CF8, + 0x000052B5, 0x00000A7A, 0x000500C7, 0x00000011, 0x00003ED8, 0x000052B5, 0x000007DE, 0x000500C2, + 0x00000011, 0x0000520A, 0x00003ED8, 0x0000085F, 0x00050051, 0x0000000B, 0x00001CFC, 0x00001CF8, + 0x00000000, 0x00050051, 0x0000000B, 0x00005FDB, 0x00001CF8, 0x00000001, 0x00050051, 0x0000000B, + 0x00001DD9, 0x0000520A, 0x00000000, 0x00050051, 0x0000000B, 0x00001E73, 0x0000520A, 0x00000001, + 0x00070050, 0x00000017, 0x00003F21, 0x00001CFC, 0x00005FDB, 0x00001DD9, 0x00001E73, 0x0009004F, + 0x00000017, 0x00001E5E, 0x00003F21, 0x00003F21, 0x00000000, 0x00000002, 0x00000001, 0x00000003, + 0x0009004F, 0x00000017, 0x00001ACC, 0x00002681, 0x00002681, 0x00000000, 0x00000000, 0x00000001, + 0x00000001, 0x000500C5, 0x00000017, 0x0000614D, 0x00001ACC, 0x00001E5E, 0x0007004F, 0x00000011, + 0x0000431D, 0x00004DEC, 0x00004DEC, 0x00000002, 0x00000003, 0x000500C7, 0x00000011, 0x000018A7, + 0x0000431D, 0x00000BB1, 0x000500C2, 0x00000011, 0x00005474, 0x000018A7, 0x0000085F, 0x000500C7, + 0x00000011, 0x00001B2C, 0x0000431D, 0x00000474, 0x000500C4, 0x00000011, 0x00003F89, 0x00001B2C, + 0x0000085F, 0x00050084, 0x00000011, 0x000057E5, 0x00003F89, 0x0000049E, 0x000500C5, 0x00000011, + 0x00002682, 0x00005474, 0x000057E5, 0x000500C7, 0x00000011, 0x00001CF9, 0x0000431D, 0x00000A7A, + 0x000500C7, 0x00000011, 0x00003ED9, 0x0000431D, 0x000007DE, 0x000500C2, 0x00000011, 0x0000520B, + 0x00003ED9, 0x0000085F, 0x00050051, 0x0000000B, 0x00001CFD, 0x00001CF9, 0x00000000, 0x00050051, + 0x0000000B, 0x00005FDD, 0x00001CF9, 0x00000001, 0x00050051, 0x0000000B, 0x00001DDA, 0x0000520B, + 0x00000000, 0x00050051, 0x0000000B, 0x00001E74, 0x0000520B, 0x00000001, 0x00070050, 0x00000017, + 0x00003F22, 0x00001CFD, 0x00005FDD, 0x00001DDA, 0x00001E74, 0x0009004F, 0x00000017, 0x00001E5F, + 0x00003F22, 0x00003F22, 0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x0009004F, 0x00000017, + 0x000019C3, 0x00002682, 0x00002682, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C5, + 0x00000017, 0x00006098, 0x000019C3, 0x00001E5F, 0x00060041, 0x00000294, 0x0000201B, 0x0000140E, + 0x00000A0B, 0x000054B5, 0x0003003E, 0x0000201B, 0x0000614D, 0x00050080, 0x0000000B, 0x00002CC1, + 0x000054B5, 0x00000A0D, 0x00060041, 0x00000294, 0x00006230, 0x0000140E, 0x00000A0B, 0x00002CC1, + 0x0003003E, 0x00006230, 0x00006098, 0x000300F7, 0x00001AD7, 0x00000002, 0x000400FA, 0x00004376, + 0x000055E9, 0x00001C25, 0x000200F8, 0x000055E9, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001C25, + 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001AD7, 0x000700F5, 0x0000000B, 0x0000456F, 0x00000A6A, + 0x000055E9, 0x00000A3A, 0x00001C25, 0x000500C2, 0x0000000B, 0x000041C0, 0x0000456F, 0x00000A16, + 0x00050080, 0x0000000B, 0x00002ADB, 0x00005665, 0x000041C0, 0x00060041, 0x00000294, 0x0000571A, + 0x0000107A, 0x00000A0B, 0x00002ADB, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, + 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, + 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, + 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, + 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, + 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, + 0x000019B2, 0x00001AD7, 0x00003FF9, 0x00002958, 0x000300F7, 0x00002DA3, 0x00000000, 0x000400FA, + 0x00003B23, 0x00002B39, 0x00002DA3, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, + 0x00002AAC, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, + 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002DA3, 0x000200F8, 0x00002DA3, + 0x000700F5, 0x00000017, 0x00004DED, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x0007004F, + 0x00000011, 0x000052B6, 0x00004DED, 0x00004DED, 0x00000000, 0x00000001, 0x000500C7, 0x00000011, + 0x000031C3, 0x000052B6, 0x00000BB1, 0x000500C2, 0x00000011, 0x00005475, 0x000031C3, 0x0000085F, + 0x000500C7, 0x00000011, 0x00001B2D, 0x000052B6, 0x00000474, 0x000500C4, 0x00000011, 0x00003F8A, + 0x00001B2D, 0x0000085F, 0x00050084, 0x00000011, 0x000057E6, 0x00003F8A, 0x0000049E, 0x000500C5, + 0x00000011, 0x00002683, 0x00005475, 0x000057E6, 0x000500C7, 0x00000011, 0x00001CFA, 0x000052B6, + 0x00000A7A, 0x000500C7, 0x00000011, 0x00003EDA, 0x000052B6, 0x000007DE, 0x000500C2, 0x00000011, + 0x0000520C, 0x00003EDA, 0x0000085F, 0x00050051, 0x0000000B, 0x00001CFE, 0x00001CFA, 0x00000000, + 0x00050051, 0x0000000B, 0x00005FDE, 0x00001CFA, 0x00000001, 0x00050051, 0x0000000B, 0x00001DDB, + 0x0000520C, 0x00000000, 0x00050051, 0x0000000B, 0x00001E75, 0x0000520C, 0x00000001, 0x00070050, + 0x00000017, 0x00003F23, 0x00001CFE, 0x00005FDE, 0x00001DDB, 0x00001E75, 0x0009004F, 0x00000017, + 0x00001E60, 0x00003F23, 0x00003F23, 0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x0009004F, + 0x00000017, 0x00001ACD, 0x00002683, 0x00002683, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C5, 0x00000017, 0x0000614E, 0x00001ACD, 0x00001E60, 0x0007004F, 0x00000011, 0x0000431E, + 0x00004DED, 0x00004DED, 0x00000002, 0x00000003, 0x000500C7, 0x00000011, 0x000018A8, 0x0000431E, + 0x00000BB1, 0x000500C2, 0x00000011, 0x00005476, 0x000018A8, 0x0000085F, 0x000500C7, 0x00000011, + 0x00001B2E, 0x0000431E, 0x00000474, 0x000500C4, 0x00000011, 0x00003F8B, 0x00001B2E, 0x0000085F, + 0x00050084, 0x00000011, 0x000057E7, 0x00003F8B, 0x0000049E, 0x000500C5, 0x00000011, 0x00002684, + 0x00005476, 0x000057E7, 0x000500C7, 0x00000011, 0x00001CFB, 0x0000431E, 0x00000A7A, 0x000500C7, + 0x00000011, 0x00003EDB, 0x0000431E, 0x000007DE, 0x000500C2, 0x00000011, 0x0000520D, 0x00003EDB, + 0x0000085F, 0x00050051, 0x0000000B, 0x00001CFF, 0x00001CFB, 0x00000000, 0x00050051, 0x0000000B, + 0x00005FDF, 0x00001CFB, 0x00000001, 0x00050051, 0x0000000B, 0x00001DDC, 0x0000520D, 0x00000000, + 0x00050051, 0x0000000B, 0x00001E76, 0x0000520D, 0x00000001, 0x00070050, 0x00000017, 0x00003F24, + 0x00001CFF, 0x00005FDF, 0x00001DDC, 0x00001E76, 0x0009004F, 0x00000017, 0x00001E61, 0x00003F24, + 0x00003F24, 0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x0009004F, 0x00000017, 0x00001E6F, + 0x00002684, 0x00002684, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C5, 0x00000017, + 0x0000363E, 0x00001E6F, 0x00001E61, 0x00050080, 0x0000000B, 0x0000459A, 0x000054B5, 0x00000A10, + 0x00060041, 0x00000294, 0x00001929, 0x0000140E, 0x00000A0B, 0x0000459A, 0x0003003E, 0x00001929, + 0x0000614E, 0x00050080, 0x0000000B, 0x00002CC2, 0x000054B5, 0x00000A13, 0x00060041, 0x00000294, + 0x00006256, 0x0000140E, 0x00000A0B, 0x00002CC2, 0x0003003E, 0x00006256, 0x0000363E, 0x000200F9, + 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_bgrg8_rgbg8_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_bgrg8_rgbg8_cs.h new file mode 100644 index 0000000..fef88f9 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_bgrg8_rgbg8_cs.h @@ -0,0 +1,554 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25059 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_255 = OpConstant %uint 255 + %uint_16 = OpConstant %uint 16 +%uint_16711680 = OpConstant %uint 16711680 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 + %uint_3 = OpConstant %uint 3 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2603 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %1611 = OpConstantComposite %v4uint %uint_255 %uint_255 %uint_255 %uint_255 + %784 = OpConstantComposite %v4uint %uint_16711680 %uint_16711680 %uint_16711680 %uint_16711680 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2603 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_4 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %6362 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %22810 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %13962 None + OpBranchConditional %15139 %11064 %13962 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %13962 + %13962 = OpLabel + %18259 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %23286 = OpBitwiseAnd %v4uint %18259 %1838 + %24373 = OpBitwiseAnd %v4uint %18259 %1611 + %24932 = OpShiftLeftLogical %v4uint %24373 %749 + %17045 = OpBitwiseOr %v4uint %23286 %24932 + %21212 = OpBitwiseAnd %v4uint %18259 %784 + %18088 = OpShiftRightLogical %v4uint %21212 %749 + %6532 = OpBitwiseOr %v4uint %17045 %18088 + %20254 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %20254 %6532 + %21686 = OpIAdd %uint %21685 %int_1 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_32 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %6871 %16377 %10584 + OpSelectionMerge %13963 None + OpBranchConditional %15139 %11065 %13963 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %13963 + %13963 = OpLabel + %18260 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %23287 = OpBitwiseAnd %v4uint %18260 %1838 + %24374 = OpBitwiseAnd %v4uint %18260 %1611 + %24933 = OpShiftLeftLogical %v4uint %24374 %749 + %17046 = OpBitwiseOr %v4uint %23287 %24933 + %21213 = OpBitwiseAnd %v4uint %18260 %784 + %18089 = OpShiftRightLogical %v4uint %21213 %749 + %6533 = OpBitwiseOr %v4uint %17046 %18089 + %22553 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21686 + OpStore %22553 %6533 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_bgrg8_rgbg8_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000061E3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, + 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000144, 0x000000FF, + 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x000005A9, 0x00FF0000, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, + 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, + 0x00000009, 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, + 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, + 0x00000A2B, 0x00000A13, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, + 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, + 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0004002B, 0x0000000B, + 0x00000A25, 0x00000009, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, + 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, + 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, + 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0007002C, 0x00000017, + 0x0000064B, 0x00000144, 0x00000144, 0x00000144, 0x00000144, 0x0007002C, 0x00000017, 0x00000310, + 0x000005A9, 0x000005A9, 0x000005A9, 0x000005A9, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, + 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, + 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, + 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, + 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, + 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, + 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, + 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, + 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, + 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, + 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, + 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, + 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, + 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, + 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, + 0x00000A2B, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, + 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, + 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, + 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, + 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, + 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, + 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A17, + 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, + 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, + 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, + 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, + 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, + 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, + 0x0000000B, 0x000054B5, 0x00002764, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, + 0x00004376, 0x00005768, 0x000051F2, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, + 0x000400FA, 0x00004384, 0x00002BF8, 0x000018D9, 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, + 0x000032B3, 0x000044BE, 0x00000A17, 0x000500C3, 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, + 0x000500C2, 0x0000000B, 0x00004947, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, + 0x00004947, 0x00050084, 0x0000000C, 0x00005321, 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, + 0x00003B27, 0x000032B3, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, + 0x0004007C, 0x0000000C, 0x00003901, 0x00002348, 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, + 0x00003901, 0x000500C3, 0x0000000C, 0x000032BA, 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, + 0x00005FEE, 0x000032BA, 0x000020F4, 0x000500C4, 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A22, + 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, + 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, + 0x0000000C, 0x00003138, 0x000044BE, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, + 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, + 0x00001B88, 0x0000434B, 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, + 0x000500C3, 0x0000000C, 0x00002215, 0x000044BE, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, + 0x00002215, 0x0000601E, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, + 0x0000000C, 0x00004112, 0x00005BEB, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, + 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, + 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, + 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, + 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, + 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, + 0x000047B4, 0x000018DA, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, + 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, + 0x000044BE, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, + 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, + 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, + 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, + 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, + 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, + 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, + 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, + 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, + 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, + 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, + 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, + 0x00005B4D, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, + 0x0000000C, 0x00005347, 0x0000405C, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, + 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, + 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, + 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, + 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, + 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, + 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, + 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, + 0x000500C7, 0x0000000C, 0x000047B5, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, + 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, + 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, + 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, + 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, + 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, + 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, + 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, + 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, + 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, + 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, + 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, + 0x00005F43, 0x000200F8, 0x000051F2, 0x0004007C, 0x0000000C, 0x00003CBC, 0x00005789, 0x00050084, + 0x0000000C, 0x000060B8, 0x000018DA, 0x00003CBC, 0x00050080, 0x0000000C, 0x0000208E, 0x000060B8, + 0x000044BE, 0x0004007C, 0x0000000C, 0x000022F8, 0x00005788, 0x00050084, 0x0000000C, 0x00001E9F, + 0x0000208E, 0x000022F8, 0x00050080, 0x0000000C, 0x00001F30, 0x0000591A, 0x00001E9F, 0x000200F9, + 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, + 0x00001F30, 0x000051F2, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, + 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, + 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, 0x00004315, 0x0000107A, + 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004315, 0x000500AA, 0x00000009, + 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x000061E2, 0x00000A10, + 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, 0x00000000, + 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, + 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, + 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, + 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, 0x00005F43, + 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000061E2, 0x00000A13, 0x000500A6, + 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x0000368A, 0x00000000, 0x000400FA, + 0x00003B23, 0x00002B38, 0x0000368A, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, + 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, + 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x0000368A, 0x000200F8, 0x0000368A, + 0x000700F5, 0x00000017, 0x00004753, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x000500C7, + 0x00000017, 0x00005AF6, 0x00004753, 0x0000072E, 0x000500C7, 0x00000017, 0x00005F35, 0x00004753, + 0x0000064B, 0x000500C4, 0x00000017, 0x00006164, 0x00005F35, 0x000002ED, 0x000500C5, 0x00000017, + 0x00004295, 0x00005AF6, 0x00006164, 0x000500C7, 0x00000017, 0x000052DC, 0x00004753, 0x00000310, + 0x000500C2, 0x00000017, 0x000046A8, 0x000052DC, 0x000002ED, 0x000500C5, 0x00000017, 0x00001984, + 0x00004295, 0x000046A8, 0x00060041, 0x00000294, 0x00004F1E, 0x0000140E, 0x00000A0B, 0x000054B5, + 0x0003003E, 0x00004F1E, 0x00001984, 0x00050080, 0x0000000B, 0x000054B6, 0x000054B5, 0x00000A0E, + 0x000300F7, 0x00001AD7, 0x00000002, 0x000400FA, 0x00004376, 0x000055E9, 0x00001C25, 0x000200F8, + 0x000055E9, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001C25, 0x000200F9, 0x00001AD7, 0x000200F8, + 0x00001AD7, 0x000700F5, 0x0000000B, 0x0000456F, 0x00000A6A, 0x000055E9, 0x00000A3A, 0x00001C25, + 0x000500C2, 0x0000000B, 0x000041C0, 0x0000456F, 0x00000A16, 0x00050080, 0x0000000B, 0x00002ADB, + 0x00005665, 0x000041C0, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, 0x00002ADB, + 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, + 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, + 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, + 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, + 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, + 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x00001AD7, 0x00003FF9, + 0x00002958, 0x000300F7, 0x0000368B, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, 0x0000368B, + 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, 0x000500C2, + 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, + 0x00003BE8, 0x000200F9, 0x0000368B, 0x000200F8, 0x0000368B, 0x000700F5, 0x00000017, 0x00004754, + 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x000500C7, 0x00000017, 0x00005AF7, 0x00004754, + 0x0000072E, 0x000500C7, 0x00000017, 0x00005F36, 0x00004754, 0x0000064B, 0x000500C4, 0x00000017, + 0x00006165, 0x00005F36, 0x000002ED, 0x000500C5, 0x00000017, 0x00004296, 0x00005AF7, 0x00006165, + 0x000500C7, 0x00000017, 0x000052DD, 0x00004754, 0x00000310, 0x000500C2, 0x00000017, 0x000046A9, + 0x000052DD, 0x000002ED, 0x000500C5, 0x00000017, 0x00001985, 0x00004296, 0x000046A9, 0x00060041, + 0x00000294, 0x00005819, 0x0000140E, 0x00000A0B, 0x000054B6, 0x0003003E, 0x00005819, 0x00001985, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_ctx1_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_ctx1_cs.h new file mode 100644 index 0000000..958dc7a --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_ctx1_cs.h @@ -0,0 +1,1516 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25268 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %v2uint = OpTypeVector %uint 2 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 +%uint_1431655765 = OpConstant %uint 1431655765 + %uint_1 = OpConstant %uint 1 +%uint_2863311530 = OpConstant %uint 2863311530 + %uint_0 = OpConstant %uint 0 + %uint_2 = OpConstant %uint 2 + %uint_4 = OpConstant %uint 4 + %uint_6 = OpConstant %uint 6 + %77 = OpConstantComposite %v4uint %uint_0 %uint_2 %uint_4 %uint_6 + %uint_3 = OpConstant %uint 3 + %uint_65535 = OpConstant %uint 65535 + %uint_16 = OpConstant %uint 16 + %uint_8 = OpConstant %uint 8 + %uint_24 = OpConstant %uint 24 +%uint_16711935 = OpConstant %uint 16711935 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2596 = OpConstantComposite %v3uint %uint_2 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 + %2620 = OpConstantComposite %v3uint %uint_2 %uint_2 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint + %uint_255 = OpConstant %uint 255 +%uint_16711680 = OpConstant %uint 16711680 +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform + %uint_32 = OpConstant %uint 32 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_9 = OpConstant %uint 9 + %uint_10 = OpConstant %uint 10 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %1975 = OpConstantComposite %v2uint %uint_8 %uint_8 + %1140 = OpConstantComposite %v2uint %uint_255 %uint_255 + %2143 = OpConstantComposite %v2uint %uint_16 %uint_16 + %2311 = OpConstantComposite %v2uint %uint_24 %uint_24 + %2993 = OpConstantComposite %v2uint %uint_16711680 %uint_16711680 + %2878 = OpConstantComposite %v4uint %uint_1431655765 %uint_1431655765 %uint_1431655765 %uint_1431655765 + %2950 = OpConstantComposite %v4uint %uint_1 %uint_1 %uint_1 %uint_1 + %2860 = OpConstantComposite %v4uint %uint_2863311530 %uint_2863311530 %uint_2863311530 %uint_2863311530 + %47 = OpConstantComposite %v4uint %uint_3 %uint_3 %uint_3 %uint_3 + %2015 = OpConstantComposite %v2uint %uint_65535 %uint_65535 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %200 = OpConstantNull %v2uint + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %14903 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20158 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %22412 = OpLoad %uint %20158 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_7 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2596 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %14018 DontFlatten + OpBranchConditional %24679 %21992 %14018 + %21992 = OpLabel + OpBranch %14903 + %14018 = OpLabel + %17344 = OpShiftLeftLogical %v3uint %21387 %2620 + %15489 = OpBitcast %v3int %17344 + %18336 = OpCompositeExtract %int %15489 0 + %9362 = OpIMul %int %18336 %int_2 + %6362 = OpCompositeExtract %int %15489 2 + %14505 = OpBitcast %int %6594 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %15489 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %22412 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %9362 %24535 + %10898 = OpBitcast %uint %8258 + %9077 = OpIAdd %uint %10898 %22411 + %11726 = OpShiftRightLogical %uint %9077 %uint_4 + %6977 = OpShiftRightLogical %uint %22412 %uint_4 + OpSelectionMerge %18964 DontFlatten + OpBranchConditional %17270 %7364 %21373 + %21373 = OpLabel + %9411 = OpBitcast %v3int %21387 + %8918 = OpCompositeExtract %int %9411 0 + %9363 = OpIMul %int %8918 %int_8 + %6363 = OpCompositeExtract %int %9411 2 + %14506 = OpBitcast %int %22409 + %11280 = OpIMul %int %6363 %14506 + %17599 = OpCompositeExtract %int %9411 1 + %22229 = OpIAdd %int %11280 %17599 + %22406 = OpBitcast %int %22408 + %7839 = OpIMul %int %22229 %22406 + %7984 = OpIAdd %int %9363 %7839 + OpBranch %18964 + %7364 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %6361 %21374 + %21374 = OpLabel + %10608 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %10608 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %10608 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_10 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17303 = OpIAdd %int %10934 %17741 + %6375 = OpShiftLeftLogical %int %17303 %uint_3 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15435 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18356 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18356 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12151 + %19165 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19165 %int_2 + %16708 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21587 %int_6 + %15436 = OpIAdd %int %16708 %21580 + %14157 = OpBitwiseAnd %int %16727 %int_63 + %12098 = OpIAdd %int %15436 %14157 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v3int %21387 + %17091 = OpCompositeExtract %int %6573 1 + %9470 = OpShiftRightArithmetic %int %17091 %int_4 + %10056 = OpCompositeExtract %int %6573 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %22409 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %6573 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_9 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12601 = OpBitwiseAnd %int %17091 %int_6 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7048 = OpShiftLeftLogical %int %17227 %uint_9 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17091 %int_3 + %13731 = OpIAdd %int %8725 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19166 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19166 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18357 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18357 %uint_9 + %16729 = OpIAdd %int %10332 %21582 + %19167 = OpBitwiseAnd %int %17091 %int_1 + %21583 = OpShiftLeftLogical %int %19167 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16730 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %6361 %12098 %21374 + OpBranch %18964 + %18964 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %21373 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %18964 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %11682 None + OpBranchConditional %15139 %11064 %11682 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11682 + %11682 = OpLabel + %19853 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %22133 = OpVectorShuffle %v2uint %19853 %19853 0 2 + %14696 = OpShiftRightLogical %v2uint %22133 %1975 + %7427 = OpBitwiseAnd %v2uint %14696 %1140 + %18755 = OpBitwiseAnd %v2uint %22133 %1140 + %22690 = OpShiftLeftLogical %v2uint %18755 %2143 + %16241 = OpBitwiseOr %v2uint %7427 %22690 + %22243 = OpCompositeExtract %uint %16241 0 + %6423 = OpCompositeExtract %uint %16241 1 + %10734 = OpShiftRightLogical %v2uint %22133 %2311 + %7201 = OpBitwiseAnd %v2uint %22133 %2993 + %14690 = OpBitwiseOr %v2uint %10734 %7201 + %19249 = OpCompositeExtract %uint %14690 0 + %7247 = OpCompositeExtract %uint %14690 1 + %24888 = OpVectorShuffle %v4uint %19853 %200 1 3 1 1 + %8966 = OpBitwiseAnd %v4uint %24888 %2878 + %24266 = OpShiftLeftLogical %v4uint %8966 %2950 + %20653 = OpBitwiseAnd %v4uint %24888 %2860 + %16599 = OpShiftRightLogical %v4uint %20653 %2950 + %24000 = OpBitwiseOr %v4uint %24266 %16599 + %19618 = OpBitwiseAnd %v4uint %24000 %2860 + %18181 = OpShiftRightLogical %v4uint %19618 %2950 + %17610 = OpBitwiseXor %v4uint %24000 %18181 + %13995 = OpVectorShuffle %v2uint %17610 %17610 0 1 + %21953 = OpNot %v2uint %13995 + %17394 = OpVectorShuffle %v4uint %21953 %21953 0 0 0 0 + %24270 = OpShiftRightLogical %v4uint %17394 %77 + %7727 = OpBitwiseAnd %v4uint %24270 %47 + %17317 = OpCompositeConstruct %v4uint %22243 %22243 %22243 %22243 + %23349 = OpIMul %v4uint %7727 %17317 + %14333 = OpVectorShuffle %v4uint %17610 %200 0 0 0 0 + %14627 = OpShiftRightLogical %v4uint %14333 %77 + %7728 = OpBitwiseAnd %v4uint %14627 %47 + %18248 = OpCompositeConstruct %v4uint %19249 %19249 %19249 %19249 + %12685 = OpIMul %v4uint %7728 %18248 + %14191 = OpIAdd %v4uint %23349 %12685 + %10268 = OpVectorShuffle %v2uint %14191 %14191 0 2 + %9375 = OpBitwiseAnd %v2uint %10268 %2015 + %17040 = OpUDiv %v2uint %9375 %1870 + %25246 = OpShiftRightLogical %v2uint %10268 %2143 + %15366 = OpUDiv %v2uint %25246 %1870 + %14005 = OpShiftLeftLogical %v2uint %15366 %1975 + %8377 = OpBitwiseOr %v2uint %17040 %14005 + %17075 = OpVectorShuffle %v2uint %14191 %14191 1 3 + %16634 = OpBitwiseAnd %v2uint %17075 %2015 + %17891 = OpUDiv %v2uint %16634 %1870 + %16994 = OpShiftLeftLogical %v2uint %17891 %2143 + %6318 = OpBitwiseOr %v2uint %8377 %16994 + %15325 = OpShiftRightLogical %v2uint %17075 %2143 + %24205 = OpUDiv %v2uint %15325 %1870 + %14043 = OpShiftLeftLogical %v2uint %24205 %2311 + %24860 = OpBitwiseOr %v2uint %6318 %14043 + %20058 = OpCompositeExtract %uint %24860 0 + %7152 = OpCompositeExtract %uint %24860 1 + %6739 = OpVectorShuffle %v4uint %21953 %21953 1 1 1 1 + %9009 = OpShiftRightLogical %v4uint %6739 %77 + %7729 = OpBitwiseAnd %v4uint %9009 %47 + %17318 = OpCompositeConstruct %v4uint %6423 %6423 %6423 %6423 + %23350 = OpIMul %v4uint %7729 %17318 + %14334 = OpVectorShuffle %v4uint %17610 %200 1 1 1 1 + %14628 = OpShiftRightLogical %v4uint %14334 %77 + %7730 = OpBitwiseAnd %v4uint %14628 %47 + %18249 = OpCompositeConstruct %v4uint %7247 %7247 %7247 %7247 + %12686 = OpIMul %v4uint %7730 %18249 + %14192 = OpIAdd %v4uint %23350 %12686 + %10269 = OpVectorShuffle %v2uint %14192 %14192 0 2 + %9376 = OpBitwiseAnd %v2uint %10269 %2015 + %17041 = OpUDiv %v2uint %9376 %1870 + %25247 = OpShiftRightLogical %v2uint %10269 %2143 + %15367 = OpUDiv %v2uint %25247 %1870 + %14006 = OpShiftLeftLogical %v2uint %15367 %1975 + %8378 = OpBitwiseOr %v2uint %17041 %14006 + %17076 = OpVectorShuffle %v2uint %14192 %14192 1 3 + %16635 = OpBitwiseAnd %v2uint %17076 %2015 + %17892 = OpUDiv %v2uint %16635 %1870 + %16995 = OpShiftLeftLogical %v2uint %17892 %2143 + %6319 = OpBitwiseOr %v2uint %8378 %16995 + %15326 = OpShiftRightLogical %v2uint %17076 %2143 + %24206 = OpUDiv %v2uint %15326 %1870 + %14044 = OpShiftLeftLogical %v2uint %24206 %2311 + %24861 = OpBitwiseOr %v2uint %6319 %14044 + %20077 = OpCompositeExtract %uint %24861 0 + %23599 = OpCompositeExtract %uint %24861 1 + %18260 = OpCompositeConstruct %v4uint %20058 %7152 %20077 %23599 + %8787 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11726 + OpStore %8787 %18260 + %12832 = OpCompositeExtract %uint %17344 1 + %23232 = OpIAdd %uint %12832 %uint_1 + %17425 = OpULessThan %bool %23232 %6594 + OpSelectionMerge %7566 DontFlatten + OpBranchConditional %17425 %22828 %7566 + %22828 = OpLabel + %15595 = OpIAdd %uint %11726 %6977 + %10947 = OpShiftRightLogical %v2uint %13995 %1975 + %23961 = OpNot %v2uint %10947 + %10358 = OpVectorShuffle %v4uint %23961 %23961 0 0 0 0 + %25258 = OpShiftRightLogical %v4uint %10358 %77 + %16795 = OpBitwiseAnd %v4uint %25258 %47 + %15740 = OpIMul %v4uint %16795 %17317 + %10523 = OpVectorShuffle %v4uint %10947 %10947 0 0 0 0 + %15615 = OpShiftRightLogical %v4uint %10523 %77 + %17726 = OpBitwiseAnd %v4uint %15615 %47 + %24149 = OpIMul %v4uint %17726 %18248 + %10381 = OpIAdd %v4uint %15740 %24149 + %10270 = OpVectorShuffle %v2uint %10381 %10381 0 2 + %9377 = OpBitwiseAnd %v2uint %10270 %2015 + %17042 = OpUDiv %v2uint %9377 %1870 + %25248 = OpShiftRightLogical %v2uint %10270 %2143 + %15368 = OpUDiv %v2uint %25248 %1870 + %14007 = OpShiftLeftLogical %v2uint %15368 %1975 + %8379 = OpBitwiseOr %v2uint %17042 %14007 + %17077 = OpVectorShuffle %v2uint %10381 %10381 1 3 + %16636 = OpBitwiseAnd %v2uint %17077 %2015 + %17893 = OpUDiv %v2uint %16636 %1870 + %16996 = OpShiftLeftLogical %v2uint %17893 %2143 + %6320 = OpBitwiseOr %v2uint %8379 %16996 + %15327 = OpShiftRightLogical %v2uint %17077 %2143 + %24207 = OpUDiv %v2uint %15327 %1870 + %14045 = OpShiftLeftLogical %v2uint %24207 %2311 + %24862 = OpBitwiseOr %v2uint %6320 %14045 + %20059 = OpCompositeExtract %uint %24862 0 + %7153 = OpCompositeExtract %uint %24862 1 + %6740 = OpVectorShuffle %v4uint %23961 %23961 1 1 1 1 + %9997 = OpShiftRightLogical %v4uint %6740 %77 + %16796 = OpBitwiseAnd %v4uint %9997 %47 + %15741 = OpIMul %v4uint %16796 %17318 + %10524 = OpVectorShuffle %v4uint %10947 %10947 1 1 1 1 + %15616 = OpShiftRightLogical %v4uint %10524 %77 + %17727 = OpBitwiseAnd %v4uint %15616 %47 + %24150 = OpIMul %v4uint %17727 %18249 + %10382 = OpIAdd %v4uint %15741 %24150 + %10271 = OpVectorShuffle %v2uint %10382 %10382 0 2 + %9378 = OpBitwiseAnd %v2uint %10271 %2015 + %17043 = OpUDiv %v2uint %9378 %1870 + %25249 = OpShiftRightLogical %v2uint %10271 %2143 + %15369 = OpUDiv %v2uint %25249 %1870 + %14008 = OpShiftLeftLogical %v2uint %15369 %1975 + %8380 = OpBitwiseOr %v2uint %17043 %14008 + %17078 = OpVectorShuffle %v2uint %10382 %10382 1 3 + %16637 = OpBitwiseAnd %v2uint %17078 %2015 + %17894 = OpUDiv %v2uint %16637 %1870 + %16997 = OpShiftLeftLogical %v2uint %17894 %2143 + %6321 = OpBitwiseOr %v2uint %8380 %16997 + %15328 = OpShiftRightLogical %v2uint %17078 %2143 + %24208 = OpUDiv %v2uint %15328 %1870 + %14046 = OpShiftLeftLogical %v2uint %24208 %2311 + %24863 = OpBitwiseOr %v2uint %6321 %14046 + %20079 = OpCompositeExtract %uint %24863 0 + %23600 = OpCompositeExtract %uint %24863 1 + %18261 = OpCompositeConstruct %v4uint %20059 %7153 %20079 %23600 + %9680 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15595 + OpStore %9680 %18261 + %14840 = OpIAdd %uint %12832 %uint_2 + %11787 = OpULessThan %bool %14840 %6594 + OpSelectionMerge %7205 DontFlatten + OpBranchConditional %11787 %20882 %7205 + %20882 = OpLabel + %13198 = OpIMul %uint %uint_2 %6977 + %13581 = OpIAdd %uint %11726 %13198 + %13948 = OpShiftRightLogical %v2uint %13995 %2143 + %23962 = OpNot %v2uint %13948 + %10359 = OpVectorShuffle %v4uint %23962 %23962 0 0 0 0 + %25259 = OpShiftRightLogical %v4uint %10359 %77 + %16797 = OpBitwiseAnd %v4uint %25259 %47 + %15742 = OpIMul %v4uint %16797 %17317 + %10525 = OpVectorShuffle %v4uint %13948 %13948 0 0 0 0 + %15617 = OpShiftRightLogical %v4uint %10525 %77 + %17728 = OpBitwiseAnd %v4uint %15617 %47 + %24151 = OpIMul %v4uint %17728 %18248 + %10383 = OpIAdd %v4uint %15742 %24151 + %10272 = OpVectorShuffle %v2uint %10383 %10383 0 2 + %9379 = OpBitwiseAnd %v2uint %10272 %2015 + %17044 = OpUDiv %v2uint %9379 %1870 + %25250 = OpShiftRightLogical %v2uint %10272 %2143 + %15370 = OpUDiv %v2uint %25250 %1870 + %14009 = OpShiftLeftLogical %v2uint %15370 %1975 + %8381 = OpBitwiseOr %v2uint %17044 %14009 + %17079 = OpVectorShuffle %v2uint %10383 %10383 1 3 + %16638 = OpBitwiseAnd %v2uint %17079 %2015 + %17895 = OpUDiv %v2uint %16638 %1870 + %16998 = OpShiftLeftLogical %v2uint %17895 %2143 + %6322 = OpBitwiseOr %v2uint %8381 %16998 + %15329 = OpShiftRightLogical %v2uint %17079 %2143 + %24209 = OpUDiv %v2uint %15329 %1870 + %14047 = OpShiftLeftLogical %v2uint %24209 %2311 + %24864 = OpBitwiseOr %v2uint %6322 %14047 + %20060 = OpCompositeExtract %uint %24864 0 + %7154 = OpCompositeExtract %uint %24864 1 + %6741 = OpVectorShuffle %v4uint %23962 %23962 1 1 1 1 + %9998 = OpShiftRightLogical %v4uint %6741 %77 + %16798 = OpBitwiseAnd %v4uint %9998 %47 + %15743 = OpIMul %v4uint %16798 %17318 + %10526 = OpVectorShuffle %v4uint %13948 %13948 1 1 1 1 + %15618 = OpShiftRightLogical %v4uint %10526 %77 + %17729 = OpBitwiseAnd %v4uint %15618 %47 + %24152 = OpIMul %v4uint %17729 %18249 + %10384 = OpIAdd %v4uint %15743 %24152 + %10273 = OpVectorShuffle %v2uint %10384 %10384 0 2 + %9380 = OpBitwiseAnd %v2uint %10273 %2015 + %17045 = OpUDiv %v2uint %9380 %1870 + %25251 = OpShiftRightLogical %v2uint %10273 %2143 + %15371 = OpUDiv %v2uint %25251 %1870 + %14010 = OpShiftLeftLogical %v2uint %15371 %1975 + %8382 = OpBitwiseOr %v2uint %17045 %14010 + %17080 = OpVectorShuffle %v2uint %10384 %10384 1 3 + %16639 = OpBitwiseAnd %v2uint %17080 %2015 + %17896 = OpUDiv %v2uint %16639 %1870 + %16999 = OpShiftLeftLogical %v2uint %17896 %2143 + %6323 = OpBitwiseOr %v2uint %8382 %16999 + %15330 = OpShiftRightLogical %v2uint %17080 %2143 + %24210 = OpUDiv %v2uint %15330 %1870 + %14048 = OpShiftLeftLogical %v2uint %24210 %2311 + %24865 = OpBitwiseOr %v2uint %6323 %14048 + %20080 = OpCompositeExtract %uint %24865 0 + %23601 = OpCompositeExtract %uint %24865 1 + %18262 = OpCompositeConstruct %v4uint %20060 %7154 %20080 %23601 + %9681 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13581 + OpStore %9681 %18262 + %14841 = OpIAdd %uint %12832 %uint_3 + %11788 = OpULessThan %bool %14841 %6594 + OpSelectionMerge %18021 DontFlatten + OpBranchConditional %11788 %20883 %18021 + %20883 = OpLabel + %13199 = OpIMul %uint %uint_3 %6977 + %13582 = OpIAdd %uint %11726 %13199 + %13949 = OpShiftRightLogical %v2uint %13995 %2311 + %23963 = OpNot %v2uint %13949 + %10361 = OpVectorShuffle %v4uint %23963 %23963 0 0 0 0 + %25260 = OpShiftRightLogical %v4uint %10361 %77 + %16799 = OpBitwiseAnd %v4uint %25260 %47 + %15744 = OpIMul %v4uint %16799 %17317 + %10527 = OpVectorShuffle %v4uint %13949 %13949 0 0 0 0 + %15619 = OpShiftRightLogical %v4uint %10527 %77 + %17730 = OpBitwiseAnd %v4uint %15619 %47 + %24153 = OpIMul %v4uint %17730 %18248 + %10385 = OpIAdd %v4uint %15744 %24153 + %10274 = OpVectorShuffle %v2uint %10385 %10385 0 2 + %9381 = OpBitwiseAnd %v2uint %10274 %2015 + %17046 = OpUDiv %v2uint %9381 %1870 + %25252 = OpShiftRightLogical %v2uint %10274 %2143 + %15372 = OpUDiv %v2uint %25252 %1870 + %14011 = OpShiftLeftLogical %v2uint %15372 %1975 + %8383 = OpBitwiseOr %v2uint %17046 %14011 + %17081 = OpVectorShuffle %v2uint %10385 %10385 1 3 + %16640 = OpBitwiseAnd %v2uint %17081 %2015 + %17897 = OpUDiv %v2uint %16640 %1870 + %17000 = OpShiftLeftLogical %v2uint %17897 %2143 + %6324 = OpBitwiseOr %v2uint %8383 %17000 + %15331 = OpShiftRightLogical %v2uint %17081 %2143 + %24211 = OpUDiv %v2uint %15331 %1870 + %14049 = OpShiftLeftLogical %v2uint %24211 %2311 + %24866 = OpBitwiseOr %v2uint %6324 %14049 + %20061 = OpCompositeExtract %uint %24866 0 + %7155 = OpCompositeExtract %uint %24866 1 + %6742 = OpVectorShuffle %v4uint %23963 %23963 1 1 1 1 + %9999 = OpShiftRightLogical %v4uint %6742 %77 + %16800 = OpBitwiseAnd %v4uint %9999 %47 + %15745 = OpIMul %v4uint %16800 %17318 + %10528 = OpVectorShuffle %v4uint %13949 %13949 1 1 1 1 + %15620 = OpShiftRightLogical %v4uint %10528 %77 + %17731 = OpBitwiseAnd %v4uint %15620 %47 + %24154 = OpIMul %v4uint %17731 %18249 + %10386 = OpIAdd %v4uint %15745 %24154 + %10275 = OpVectorShuffle %v2uint %10386 %10386 0 2 + %9382 = OpBitwiseAnd %v2uint %10275 %2015 + %17047 = OpUDiv %v2uint %9382 %1870 + %25253 = OpShiftRightLogical %v2uint %10275 %2143 + %15373 = OpUDiv %v2uint %25253 %1870 + %14012 = OpShiftLeftLogical %v2uint %15373 %1975 + %8384 = OpBitwiseOr %v2uint %17047 %14012 + %17082 = OpVectorShuffle %v2uint %10386 %10386 1 3 + %16641 = OpBitwiseAnd %v2uint %17082 %2015 + %17898 = OpUDiv %v2uint %16641 %1870 + %17001 = OpShiftLeftLogical %v2uint %17898 %2143 + %6325 = OpBitwiseOr %v2uint %8384 %17001 + %15332 = OpShiftRightLogical %v2uint %17082 %2143 + %24212 = OpUDiv %v2uint %15332 %1870 + %14050 = OpShiftLeftLogical %v2uint %24212 %2311 + %24867 = OpBitwiseOr %v2uint %6325 %14050 + %20081 = OpCompositeExtract %uint %24867 0 + %23602 = OpCompositeExtract %uint %24867 1 + %18263 = OpCompositeConstruct %v4uint %20061 %7155 %20081 %23602 + %11979 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13582 + OpStore %11979 %18263 + OpBranch %18021 + %18021 = OpLabel + OpBranch %7205 + %7205 = OpLabel + OpBranch %7566 + %7566 = OpLabel + %14517 = OpIAdd %uint %11726 %int_1 + %18182 = OpSelect %uint %17270 %uint_2 %uint_1 + %16762 = OpIAdd %uint %22117 %18182 + %18278 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %16762 + %6578 = OpLoad %v4uint %18278 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20654 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20654 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %7566 %16377 %10584 + OpSelectionMerge %11683 None + OpBranchConditional %15139 %11065 %11683 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11683 + %11683 = OpLabel + %19854 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %22134 = OpVectorShuffle %v2uint %19854 %19854 0 2 + %14697 = OpShiftRightLogical %v2uint %22134 %1975 + %7428 = OpBitwiseAnd %v2uint %14697 %1140 + %18756 = OpBitwiseAnd %v2uint %22134 %1140 + %22691 = OpShiftLeftLogical %v2uint %18756 %2143 + %16242 = OpBitwiseOr %v2uint %7428 %22691 + %22244 = OpCompositeExtract %uint %16242 0 + %6424 = OpCompositeExtract %uint %16242 1 + %10735 = OpShiftRightLogical %v2uint %22134 %2311 + %7202 = OpBitwiseAnd %v2uint %22134 %2993 + %14691 = OpBitwiseOr %v2uint %10735 %7202 + %19250 = OpCompositeExtract %uint %14691 0 + %7248 = OpCompositeExtract %uint %14691 1 + %24889 = OpVectorShuffle %v4uint %19854 %200 1 3 1 1 + %8967 = OpBitwiseAnd %v4uint %24889 %2878 + %24267 = OpShiftLeftLogical %v4uint %8967 %2950 + %20655 = OpBitwiseAnd %v4uint %24889 %2860 + %16600 = OpShiftRightLogical %v4uint %20655 %2950 + %24001 = OpBitwiseOr %v4uint %24267 %16600 + %19619 = OpBitwiseAnd %v4uint %24001 %2860 + %18183 = OpShiftRightLogical %v4uint %19619 %2950 + %17611 = OpBitwiseXor %v4uint %24001 %18183 + %13996 = OpVectorShuffle %v2uint %17611 %17611 0 1 + %21954 = OpNot %v2uint %13996 + %17395 = OpVectorShuffle %v4uint %21954 %21954 0 0 0 0 + %24271 = OpShiftRightLogical %v4uint %17395 %77 + %7731 = OpBitwiseAnd %v4uint %24271 %47 + %17319 = OpCompositeConstruct %v4uint %22244 %22244 %22244 %22244 + %23351 = OpIMul %v4uint %7731 %17319 + %14335 = OpVectorShuffle %v4uint %17611 %200 0 0 0 0 + %14629 = OpShiftRightLogical %v4uint %14335 %77 + %7732 = OpBitwiseAnd %v4uint %14629 %47 + %18250 = OpCompositeConstruct %v4uint %19250 %19250 %19250 %19250 + %12687 = OpIMul %v4uint %7732 %18250 + %14193 = OpIAdd %v4uint %23351 %12687 + %10276 = OpVectorShuffle %v2uint %14193 %14193 0 2 + %9383 = OpBitwiseAnd %v2uint %10276 %2015 + %17048 = OpUDiv %v2uint %9383 %1870 + %25254 = OpShiftRightLogical %v2uint %10276 %2143 + %15374 = OpUDiv %v2uint %25254 %1870 + %14013 = OpShiftLeftLogical %v2uint %15374 %1975 + %8385 = OpBitwiseOr %v2uint %17048 %14013 + %17083 = OpVectorShuffle %v2uint %14193 %14193 1 3 + %16642 = OpBitwiseAnd %v2uint %17083 %2015 + %17899 = OpUDiv %v2uint %16642 %1870 + %17002 = OpShiftLeftLogical %v2uint %17899 %2143 + %6326 = OpBitwiseOr %v2uint %8385 %17002 + %15333 = OpShiftRightLogical %v2uint %17083 %2143 + %24213 = OpUDiv %v2uint %15333 %1870 + %14051 = OpShiftLeftLogical %v2uint %24213 %2311 + %24868 = OpBitwiseOr %v2uint %6326 %14051 + %20062 = OpCompositeExtract %uint %24868 0 + %7156 = OpCompositeExtract %uint %24868 1 + %6743 = OpVectorShuffle %v4uint %21954 %21954 1 1 1 1 + %9010 = OpShiftRightLogical %v4uint %6743 %77 + %7733 = OpBitwiseAnd %v4uint %9010 %47 + %17320 = OpCompositeConstruct %v4uint %6424 %6424 %6424 %6424 + %23352 = OpIMul %v4uint %7733 %17320 + %14336 = OpVectorShuffle %v4uint %17611 %200 1 1 1 1 + %14630 = OpShiftRightLogical %v4uint %14336 %77 + %7734 = OpBitwiseAnd %v4uint %14630 %47 + %18251 = OpCompositeConstruct %v4uint %7248 %7248 %7248 %7248 + %12688 = OpIMul %v4uint %7734 %18251 + %14194 = OpIAdd %v4uint %23352 %12688 + %10277 = OpVectorShuffle %v2uint %14194 %14194 0 2 + %9384 = OpBitwiseAnd %v2uint %10277 %2015 + %17049 = OpUDiv %v2uint %9384 %1870 + %25255 = OpShiftRightLogical %v2uint %10277 %2143 + %15375 = OpUDiv %v2uint %25255 %1870 + %14014 = OpShiftLeftLogical %v2uint %15375 %1975 + %8386 = OpBitwiseOr %v2uint %17049 %14014 + %17084 = OpVectorShuffle %v2uint %14194 %14194 1 3 + %16643 = OpBitwiseAnd %v2uint %17084 %2015 + %17900 = OpUDiv %v2uint %16643 %1870 + %17003 = OpShiftLeftLogical %v2uint %17900 %2143 + %6327 = OpBitwiseOr %v2uint %8386 %17003 + %15334 = OpShiftRightLogical %v2uint %17084 %2143 + %24214 = OpUDiv %v2uint %15334 %1870 + %14052 = OpShiftLeftLogical %v2uint %24214 %2311 + %24869 = OpBitwiseOr %v2uint %6327 %14052 + %20082 = OpCompositeExtract %uint %24869 0 + %23603 = OpCompositeExtract %uint %24869 1 + %18264 = OpCompositeConstruct %v4uint %20062 %7156 %20082 %23603 + %11941 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %14517 + OpStore %11941 %18264 + OpSelectionMerge %7207 DontFlatten + OpBranchConditional %17425 %22829 %7207 + %22829 = OpLabel + %15596 = OpIAdd %uint %14517 %6977 + %10948 = OpShiftRightLogical %v2uint %13996 %1975 + %23964 = OpNot %v2uint %10948 + %10362 = OpVectorShuffle %v4uint %23964 %23964 0 0 0 0 + %25261 = OpShiftRightLogical %v4uint %10362 %77 + %16801 = OpBitwiseAnd %v4uint %25261 %47 + %15746 = OpIMul %v4uint %16801 %17319 + %10529 = OpVectorShuffle %v4uint %10948 %10948 0 0 0 0 + %15621 = OpShiftRightLogical %v4uint %10529 %77 + %17732 = OpBitwiseAnd %v4uint %15621 %47 + %24155 = OpIMul %v4uint %17732 %18250 + %10387 = OpIAdd %v4uint %15746 %24155 + %10278 = OpVectorShuffle %v2uint %10387 %10387 0 2 + %9385 = OpBitwiseAnd %v2uint %10278 %2015 + %17050 = OpUDiv %v2uint %9385 %1870 + %25256 = OpShiftRightLogical %v2uint %10278 %2143 + %15376 = OpUDiv %v2uint %25256 %1870 + %14015 = OpShiftLeftLogical %v2uint %15376 %1975 + %8387 = OpBitwiseOr %v2uint %17050 %14015 + %17085 = OpVectorShuffle %v2uint %10387 %10387 1 3 + %16644 = OpBitwiseAnd %v2uint %17085 %2015 + %17901 = OpUDiv %v2uint %16644 %1870 + %17004 = OpShiftLeftLogical %v2uint %17901 %2143 + %6328 = OpBitwiseOr %v2uint %8387 %17004 + %15337 = OpShiftRightLogical %v2uint %17085 %2143 + %24215 = OpUDiv %v2uint %15337 %1870 + %14053 = OpShiftLeftLogical %v2uint %24215 %2311 + %24870 = OpBitwiseOr %v2uint %6328 %14053 + %20063 = OpCompositeExtract %uint %24870 0 + %7157 = OpCompositeExtract %uint %24870 1 + %6744 = OpVectorShuffle %v4uint %23964 %23964 1 1 1 1 + %10000 = OpShiftRightLogical %v4uint %6744 %77 + %16802 = OpBitwiseAnd %v4uint %10000 %47 + %15747 = OpIMul %v4uint %16802 %17320 + %10530 = OpVectorShuffle %v4uint %10948 %10948 1 1 1 1 + %15622 = OpShiftRightLogical %v4uint %10530 %77 + %17733 = OpBitwiseAnd %v4uint %15622 %47 + %24156 = OpIMul %v4uint %17733 %18251 + %10388 = OpIAdd %v4uint %15747 %24156 + %10279 = OpVectorShuffle %v2uint %10388 %10388 0 2 + %9386 = OpBitwiseAnd %v2uint %10279 %2015 + %17051 = OpUDiv %v2uint %9386 %1870 + %25257 = OpShiftRightLogical %v2uint %10279 %2143 + %15377 = OpUDiv %v2uint %25257 %1870 + %14016 = OpShiftLeftLogical %v2uint %15377 %1975 + %8388 = OpBitwiseOr %v2uint %17051 %14016 + %17086 = OpVectorShuffle %v2uint %10388 %10388 1 3 + %16645 = OpBitwiseAnd %v2uint %17086 %2015 + %17902 = OpUDiv %v2uint %16645 %1870 + %17005 = OpShiftLeftLogical %v2uint %17902 %2143 + %6329 = OpBitwiseOr %v2uint %8388 %17005 + %15338 = OpShiftRightLogical %v2uint %17086 %2143 + %24216 = OpUDiv %v2uint %15338 %1870 + %14054 = OpShiftLeftLogical %v2uint %24216 %2311 + %24871 = OpBitwiseOr %v2uint %6329 %14054 + %20083 = OpCompositeExtract %uint %24871 0 + %23604 = OpCompositeExtract %uint %24871 1 + %18265 = OpCompositeConstruct %v4uint %20063 %7157 %20083 %23604 + %9682 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15596 + OpStore %9682 %18265 + %14842 = OpIAdd %uint %12832 %uint_2 + %11789 = OpULessThan %bool %14842 %6594 + OpSelectionMerge %7206 DontFlatten + OpBranchConditional %11789 %20884 %7206 + %20884 = OpLabel + %13200 = OpIMul %uint %uint_2 %6977 + %13583 = OpIAdd %uint %14517 %13200 + %13950 = OpShiftRightLogical %v2uint %13996 %2143 + %23965 = OpNot %v2uint %13950 + %10363 = OpVectorShuffle %v4uint %23965 %23965 0 0 0 0 + %25262 = OpShiftRightLogical %v4uint %10363 %77 + %16803 = OpBitwiseAnd %v4uint %25262 %47 + %15748 = OpIMul %v4uint %16803 %17319 + %10531 = OpVectorShuffle %v4uint %13950 %13950 0 0 0 0 + %15623 = OpShiftRightLogical %v4uint %10531 %77 + %17734 = OpBitwiseAnd %v4uint %15623 %47 + %24157 = OpIMul %v4uint %17734 %18250 + %10389 = OpIAdd %v4uint %15748 %24157 + %10280 = OpVectorShuffle %v2uint %10389 %10389 0 2 + %9387 = OpBitwiseAnd %v2uint %10280 %2015 + %17052 = OpUDiv %v2uint %9387 %1870 + %25263 = OpShiftRightLogical %v2uint %10280 %2143 + %15378 = OpUDiv %v2uint %25263 %1870 + %14017 = OpShiftLeftLogical %v2uint %15378 %1975 + %8389 = OpBitwiseOr %v2uint %17052 %14017 + %17087 = OpVectorShuffle %v2uint %10389 %10389 1 3 + %16646 = OpBitwiseAnd %v2uint %17087 %2015 + %17903 = OpUDiv %v2uint %16646 %1870 + %17006 = OpShiftLeftLogical %v2uint %17903 %2143 + %6330 = OpBitwiseOr %v2uint %8389 %17006 + %15339 = OpShiftRightLogical %v2uint %17087 %2143 + %24217 = OpUDiv %v2uint %15339 %1870 + %14055 = OpShiftLeftLogical %v2uint %24217 %2311 + %24872 = OpBitwiseOr %v2uint %6330 %14055 + %20064 = OpCompositeExtract %uint %24872 0 + %7158 = OpCompositeExtract %uint %24872 1 + %6745 = OpVectorShuffle %v4uint %23965 %23965 1 1 1 1 + %10001 = OpShiftRightLogical %v4uint %6745 %77 + %16804 = OpBitwiseAnd %v4uint %10001 %47 + %15749 = OpIMul %v4uint %16804 %17320 + %10532 = OpVectorShuffle %v4uint %13950 %13950 1 1 1 1 + %15624 = OpShiftRightLogical %v4uint %10532 %77 + %17735 = OpBitwiseAnd %v4uint %15624 %47 + %24158 = OpIMul %v4uint %17735 %18251 + %10390 = OpIAdd %v4uint %15749 %24158 + %10281 = OpVectorShuffle %v2uint %10390 %10390 0 2 + %9388 = OpBitwiseAnd %v2uint %10281 %2015 + %17053 = OpUDiv %v2uint %9388 %1870 + %25264 = OpShiftRightLogical %v2uint %10281 %2143 + %15379 = OpUDiv %v2uint %25264 %1870 + %14019 = OpShiftLeftLogical %v2uint %15379 %1975 + %8390 = OpBitwiseOr %v2uint %17053 %14019 + %17088 = OpVectorShuffle %v2uint %10390 %10390 1 3 + %16647 = OpBitwiseAnd %v2uint %17088 %2015 + %17904 = OpUDiv %v2uint %16647 %1870 + %17007 = OpShiftLeftLogical %v2uint %17904 %2143 + %6331 = OpBitwiseOr %v2uint %8390 %17007 + %15340 = OpShiftRightLogical %v2uint %17088 %2143 + %24218 = OpUDiv %v2uint %15340 %1870 + %14056 = OpShiftLeftLogical %v2uint %24218 %2311 + %24873 = OpBitwiseOr %v2uint %6331 %14056 + %20084 = OpCompositeExtract %uint %24873 0 + %23605 = OpCompositeExtract %uint %24873 1 + %18266 = OpCompositeConstruct %v4uint %20064 %7158 %20084 %23605 + %9683 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13583 + OpStore %9683 %18266 + %14843 = OpIAdd %uint %12832 %uint_3 + %11790 = OpULessThan %bool %14843 %6594 + OpSelectionMerge %18022 DontFlatten + OpBranchConditional %11790 %20885 %18022 + %20885 = OpLabel + %13201 = OpIMul %uint %uint_3 %6977 + %13584 = OpIAdd %uint %14517 %13201 + %13951 = OpShiftRightLogical %v2uint %13996 %2311 + %23966 = OpNot %v2uint %13951 + %10364 = OpVectorShuffle %v4uint %23966 %23966 0 0 0 0 + %25265 = OpShiftRightLogical %v4uint %10364 %77 + %16805 = OpBitwiseAnd %v4uint %25265 %47 + %15750 = OpIMul %v4uint %16805 %17319 + %10533 = OpVectorShuffle %v4uint %13951 %13951 0 0 0 0 + %15625 = OpShiftRightLogical %v4uint %10533 %77 + %17736 = OpBitwiseAnd %v4uint %15625 %47 + %24159 = OpIMul %v4uint %17736 %18250 + %10391 = OpIAdd %v4uint %15750 %24159 + %10282 = OpVectorShuffle %v2uint %10391 %10391 0 2 + %9389 = OpBitwiseAnd %v2uint %10282 %2015 + %17054 = OpUDiv %v2uint %9389 %1870 + %25266 = OpShiftRightLogical %v2uint %10282 %2143 + %15380 = OpUDiv %v2uint %25266 %1870 + %14020 = OpShiftLeftLogical %v2uint %15380 %1975 + %8391 = OpBitwiseOr %v2uint %17054 %14020 + %17089 = OpVectorShuffle %v2uint %10391 %10391 1 3 + %16648 = OpBitwiseAnd %v2uint %17089 %2015 + %17905 = OpUDiv %v2uint %16648 %1870 + %17008 = OpShiftLeftLogical %v2uint %17905 %2143 + %6332 = OpBitwiseOr %v2uint %8391 %17008 + %15341 = OpShiftRightLogical %v2uint %17089 %2143 + %24219 = OpUDiv %v2uint %15341 %1870 + %14057 = OpShiftLeftLogical %v2uint %24219 %2311 + %24874 = OpBitwiseOr %v2uint %6332 %14057 + %20065 = OpCompositeExtract %uint %24874 0 + %7159 = OpCompositeExtract %uint %24874 1 + %6746 = OpVectorShuffle %v4uint %23966 %23966 1 1 1 1 + %10002 = OpShiftRightLogical %v4uint %6746 %77 + %16806 = OpBitwiseAnd %v4uint %10002 %47 + %15751 = OpIMul %v4uint %16806 %17320 + %10534 = OpVectorShuffle %v4uint %13951 %13951 1 1 1 1 + %15626 = OpShiftRightLogical %v4uint %10534 %77 + %17737 = OpBitwiseAnd %v4uint %15626 %47 + %24160 = OpIMul %v4uint %17737 %18251 + %10392 = OpIAdd %v4uint %15751 %24160 + %10283 = OpVectorShuffle %v2uint %10392 %10392 0 2 + %9390 = OpBitwiseAnd %v2uint %10283 %2015 + %17055 = OpUDiv %v2uint %9390 %1870 + %25267 = OpShiftRightLogical %v2uint %10283 %2143 + %15381 = OpUDiv %v2uint %25267 %1870 + %14021 = OpShiftLeftLogical %v2uint %15381 %1975 + %8392 = OpBitwiseOr %v2uint %17055 %14021 + %17092 = OpVectorShuffle %v2uint %10392 %10392 1 3 + %16649 = OpBitwiseAnd %v2uint %17092 %2015 + %17906 = OpUDiv %v2uint %16649 %1870 + %17009 = OpShiftLeftLogical %v2uint %17906 %2143 + %6333 = OpBitwiseOr %v2uint %8392 %17009 + %15342 = OpShiftRightLogical %v2uint %17092 %2143 + %24220 = OpUDiv %v2uint %15342 %1870 + %14058 = OpShiftLeftLogical %v2uint %24220 %2311 + %24875 = OpBitwiseOr %v2uint %6333 %14058 + %20085 = OpCompositeExtract %uint %24875 0 + %23606 = OpCompositeExtract %uint %24875 1 + %18267 = OpCompositeConstruct %v4uint %20065 %7159 %20085 %23606 + %11980 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13584 + OpStore %11980 %18267 + OpBranch %18022 + %18022 = OpLabel + OpBranch %7206 + %7206 = OpLabel + OpBranch %7207 + %7207 = OpLabel + OpBranch %14903 + %14903 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_ctx1_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000062B4, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A09, 0x55555555, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0004002B, 0x0000000B, 0x00000A08, 0xAAAAAAAA, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, 0x0007002C, 0x00000017, 0x0000004D, 0x00000A0A, + 0x00000A10, 0x00000A16, 0x00000A1C, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, + 0x0000000B, 0x000001C1, 0x0000FFFF, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, + 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x00000A52, 0x00000018, 0x0004002B, + 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, + 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, + 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, + 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, + 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, + 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, + 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, + 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, + 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, + 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x000A001E, + 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, + 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, + 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, + 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A24, + 0x00000A10, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0006002C, + 0x00000014, 0x00000A3C, 0x00000A10, 0x00000A10, 0x00000A0A, 0x0003001D, 0x000007DC, 0x00000017, + 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, + 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0004002B, + 0x0000000B, 0x00000144, 0x000000FF, 0x0004002B, 0x0000000B, 0x000005A9, 0x00FF0000, 0x0003001D, + 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, + 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A6A, + 0x00000020, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0004002B, + 0x0000000B, 0x00000A25, 0x00000009, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0007002C, + 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, + 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, + 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000011, 0x000007B7, 0x00000A22, 0x00000A22, + 0x0005002C, 0x00000011, 0x00000474, 0x00000144, 0x00000144, 0x0005002C, 0x00000011, 0x0000085F, + 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000011, 0x00000907, 0x00000A52, 0x00000A52, 0x0005002C, + 0x00000011, 0x00000BB1, 0x000005A9, 0x000005A9, 0x0007002C, 0x00000017, 0x00000B3E, 0x00000A09, + 0x00000A09, 0x00000A09, 0x00000A09, 0x0007002C, 0x00000017, 0x00000B86, 0x00000A0D, 0x00000A0D, + 0x00000A0D, 0x00000A0D, 0x0007002C, 0x00000017, 0x00000B2C, 0x00000A08, 0x00000A08, 0x00000A08, + 0x00000A08, 0x0007002C, 0x00000017, 0x0000002F, 0x00000A13, 0x00000A13, 0x00000A13, 0x00000A13, + 0x0005002C, 0x00000011, 0x000007DF, 0x000001C1, 0x000001C1, 0x0005002C, 0x00000011, 0x0000074E, + 0x00000A13, 0x00000A13, 0x0003002E, 0x00000011, 0x000000C8, 0x00050036, 0x00000008, 0x0000161F, + 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00003A37, 0x00000000, 0x000300FB, + 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, + 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, + 0x00003526, 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, + 0x0000000B, 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, + 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, + 0x000061E2, 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, + 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, + 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, + 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, + 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, + 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, + 0x00050041, 0x00000288, 0x00004EBE, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x0000578C, + 0x00004EBE, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A20, 0x0004003D, 0x0000000B, + 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, + 0x0000538B, 0x00002A0E, 0x00000A24, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, + 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, + 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, + 0x00006067, 0x00004288, 0x000300F7, 0x000036C2, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, + 0x000036C2, 0x000200F8, 0x000055E8, 0x000200F9, 0x00003A37, 0x000200F8, 0x000036C2, 0x000500C4, + 0x00000014, 0x000043C0, 0x0000538B, 0x00000A3C, 0x0004007C, 0x00000016, 0x00003C81, 0x000043C0, + 0x00050051, 0x0000000C, 0x000047A0, 0x00003C81, 0x00000000, 0x00050084, 0x0000000C, 0x00002492, + 0x000047A0, 0x00000A11, 0x00050051, 0x0000000C, 0x000018DA, 0x00003C81, 0x00000002, 0x0004007C, + 0x0000000C, 0x000038A9, 0x000019C2, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, + 0x00050051, 0x0000000C, 0x000044BE, 0x00003C81, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, + 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x0000578C, 0x00050084, 0x0000000C, + 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x00002492, 0x00005FD7, + 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00002375, 0x00002A92, + 0x0000578B, 0x000500C2, 0x0000000B, 0x00002DCE, 0x00002375, 0x00000A16, 0x000500C2, 0x0000000B, + 0x00001B41, 0x0000578C, 0x00000A16, 0x000300F7, 0x00004A14, 0x00000002, 0x000400FA, 0x00004376, + 0x00001CC4, 0x0000537D, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, 0x000024C3, 0x0000538B, + 0x00050051, 0x0000000C, 0x000022D6, 0x000024C3, 0x00000000, 0x00050084, 0x0000000C, 0x00002493, + 0x000022D6, 0x00000A23, 0x00050051, 0x0000000C, 0x000018DB, 0x000024C3, 0x00000002, 0x0004007C, + 0x0000000C, 0x000038AA, 0x00005789, 0x00050084, 0x0000000C, 0x00002C10, 0x000018DB, 0x000038AA, + 0x00050051, 0x0000000C, 0x000044BF, 0x000024C3, 0x00000001, 0x00050080, 0x0000000C, 0x000056D5, + 0x00002C10, 0x000044BF, 0x0004007C, 0x0000000C, 0x00005786, 0x00005788, 0x00050084, 0x0000000C, + 0x00001E9F, 0x000056D5, 0x00005786, 0x00050080, 0x0000000C, 0x00001F30, 0x00002493, 0x00001E9F, + 0x000200F9, 0x00004A14, 0x000200F8, 0x00001CC4, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, + 0x00004384, 0x000018D9, 0x0000537E, 0x000200F8, 0x0000537E, 0x0004007C, 0x00000012, 0x00002970, + 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, + 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000001, + 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, + 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, + 0x00005347, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, + 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A28, 0x000500C7, 0x0000000C, 0x00002AB6, + 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x00002747, 0x00000A35, 0x000500C4, + 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, + 0x0000454D, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A13, 0x000500C7, 0x0000000C, + 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4B, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, + 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4B, 0x00003397, 0x000500C7, + 0x0000000C, 0x000047B4, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544A, 0x000047B4, + 0x00000A17, 0x00050080, 0x0000000C, 0x00004157, 0x00004D30, 0x0000544A, 0x000500C7, 0x0000000C, + 0x00005022, 0x00004157, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, + 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x00004158, 0x00002416, 0x00002F77, 0x000500C7, + 0x0000000C, 0x00004ADD, 0x00004157, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544B, 0x00004ADD, + 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x00004158, 0x0000544B, 0x000500C7, 0x0000000C, + 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, + 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, + 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544C, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004144, + 0x0000544C, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004157, 0x00000AC8, 0x00050080, 0x0000000C, + 0x00002F42, 0x00003C4C, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, + 0x00000016, 0x000019AD, 0x0000538B, 0x00050051, 0x0000000C, 0x000042C3, 0x000019AD, 0x00000001, + 0x000500C3, 0x0000000C, 0x000024FE, 0x000042C3, 0x00000A17, 0x00050051, 0x0000000C, 0x00002748, + 0x000019AD, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A11, 0x000500C2, + 0x0000000B, 0x00005B4E, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, + 0x00050084, 0x0000000C, 0x00005321, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003B27, + 0x000024FE, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, + 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, + 0x00050051, 0x0000000C, 0x00006242, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, + 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, + 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, + 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, + 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x000042C3, 0x00000A1D, + 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, + 0x00004D38, 0x0000454E, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A25, 0x000500C3, + 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000042C3, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405D, 0x000500C7, 0x0000000C, + 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, + 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000034BD, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544D, 0x00004ADE, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4D, 0x00005A0C, + 0x0000544D, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, + 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, + 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544E, 0x000047B5, 0x00000A25, 0x00050080, 0x0000000C, 0x00004159, 0x0000285C, + 0x0000544E, 0x000500C7, 0x0000000C, 0x00004ADF, 0x000042C3, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544F, 0x00004ADF, 0x00000A17, 0x00050080, 0x0000000C, 0x0000415A, 0x00004159, 0x0000544F, + 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4D, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, + 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x0000415A, 0x00000A1D, 0x000500C7, + 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, + 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005AB1, 0x00003C4D, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, + 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, + 0x0000415A, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, + 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005EA0, 0x0000415A, + 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, + 0x000200F8, 0x00001E0B, 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, 0x000018D9, 0x00002F42, + 0x0000537E, 0x000200F9, 0x00004A14, 0x000200F8, 0x00004A14, 0x000700F5, 0x0000000C, 0x00002A3E, + 0x0000292C, 0x00001E0B, 0x00001F30, 0x0000537D, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, + 0x00050080, 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, + 0x000056CD, 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, + 0x00004315, 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004315, + 0x000500AA, 0x00000009, 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, + 0x000061E2, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, + 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, + 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, + 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, + 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, + 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, + 0x00001CAA, 0x00004A14, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000061E2, + 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x00002DA2, + 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x00002DA2, 0x000200F8, 0x00002B38, 0x000500C4, + 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, + 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x00002DA2, + 0x000200F8, 0x00002DA2, 0x000700F5, 0x00000017, 0x00004D8D, 0x00005879, 0x00003463, 0x000029E8, + 0x00002B38, 0x0007004F, 0x00000011, 0x00005675, 0x00004D8D, 0x00004D8D, 0x00000000, 0x00000002, + 0x000500C2, 0x00000011, 0x00003968, 0x00005675, 0x000007B7, 0x000500C7, 0x00000011, 0x00001D03, + 0x00003968, 0x00000474, 0x000500C7, 0x00000011, 0x00004943, 0x00005675, 0x00000474, 0x000500C4, + 0x00000011, 0x000058A2, 0x00004943, 0x0000085F, 0x000500C5, 0x00000011, 0x00003F71, 0x00001D03, + 0x000058A2, 0x00050051, 0x0000000B, 0x000056E3, 0x00003F71, 0x00000000, 0x00050051, 0x0000000B, + 0x00001917, 0x00003F71, 0x00000001, 0x000500C2, 0x00000011, 0x000029EE, 0x00005675, 0x00000907, + 0x000500C7, 0x00000011, 0x00001C21, 0x00005675, 0x00000BB1, 0x000500C5, 0x00000011, 0x00003962, + 0x000029EE, 0x00001C21, 0x00050051, 0x0000000B, 0x00004B31, 0x00003962, 0x00000000, 0x00050051, + 0x0000000B, 0x00001C4F, 0x00003962, 0x00000001, 0x0009004F, 0x00000017, 0x00006138, 0x00004D8D, + 0x000000C8, 0x00000001, 0x00000003, 0x00000001, 0x00000001, 0x000500C7, 0x00000017, 0x00002306, + 0x00006138, 0x00000B3E, 0x000500C4, 0x00000017, 0x00005ECA, 0x00002306, 0x00000B86, 0x000500C7, + 0x00000017, 0x000050AD, 0x00006138, 0x00000B2C, 0x000500C2, 0x00000017, 0x000040D7, 0x000050AD, + 0x00000B86, 0x000500C5, 0x00000017, 0x00005DC0, 0x00005ECA, 0x000040D7, 0x000500C7, 0x00000017, + 0x00004CA2, 0x00005DC0, 0x00000B2C, 0x000500C2, 0x00000017, 0x00004705, 0x00004CA2, 0x00000B86, + 0x000500C6, 0x00000017, 0x000044CA, 0x00005DC0, 0x00004705, 0x0007004F, 0x00000011, 0x000036AB, + 0x000044CA, 0x000044CA, 0x00000000, 0x00000001, 0x000400C8, 0x00000011, 0x000055C1, 0x000036AB, + 0x0009004F, 0x00000017, 0x000043F2, 0x000055C1, 0x000055C1, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x000500C2, 0x00000017, 0x00005ECE, 0x000043F2, 0x0000004D, 0x000500C7, 0x00000017, + 0x00001E2F, 0x00005ECE, 0x0000002F, 0x00070050, 0x00000017, 0x000043A5, 0x000056E3, 0x000056E3, + 0x000056E3, 0x000056E3, 0x00050084, 0x00000017, 0x00005B35, 0x00001E2F, 0x000043A5, 0x0009004F, + 0x00000017, 0x000037FD, 0x000044CA, 0x000000C8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x000500C2, 0x00000017, 0x00003923, 0x000037FD, 0x0000004D, 0x000500C7, 0x00000017, 0x00001E30, + 0x00003923, 0x0000002F, 0x00070050, 0x00000017, 0x00004748, 0x00004B31, 0x00004B31, 0x00004B31, + 0x00004B31, 0x00050084, 0x00000017, 0x0000318D, 0x00001E30, 0x00004748, 0x00050080, 0x00000017, + 0x0000376F, 0x00005B35, 0x0000318D, 0x0007004F, 0x00000011, 0x0000281C, 0x0000376F, 0x0000376F, + 0x00000000, 0x00000002, 0x000500C7, 0x00000011, 0x0000249F, 0x0000281C, 0x000007DF, 0x00050086, + 0x00000011, 0x00004290, 0x0000249F, 0x0000074E, 0x000500C2, 0x00000011, 0x0000629E, 0x0000281C, + 0x0000085F, 0x00050086, 0x00000011, 0x00003C06, 0x0000629E, 0x0000074E, 0x000500C4, 0x00000011, + 0x000036B5, 0x00003C06, 0x000007B7, 0x000500C5, 0x00000011, 0x000020B9, 0x00004290, 0x000036B5, + 0x0007004F, 0x00000011, 0x000042B3, 0x0000376F, 0x0000376F, 0x00000001, 0x00000003, 0x000500C7, + 0x00000011, 0x000040FA, 0x000042B3, 0x000007DF, 0x00050086, 0x00000011, 0x000045E3, 0x000040FA, + 0x0000074E, 0x000500C4, 0x00000011, 0x00004262, 0x000045E3, 0x0000085F, 0x000500C5, 0x00000011, + 0x000018AE, 0x000020B9, 0x00004262, 0x000500C2, 0x00000011, 0x00003BDD, 0x000042B3, 0x0000085F, + 0x00050086, 0x00000011, 0x00005E8D, 0x00003BDD, 0x0000074E, 0x000500C4, 0x00000011, 0x000036DB, + 0x00005E8D, 0x00000907, 0x000500C5, 0x00000011, 0x0000611C, 0x000018AE, 0x000036DB, 0x00050051, + 0x0000000B, 0x00004E5A, 0x0000611C, 0x00000000, 0x00050051, 0x0000000B, 0x00001BF0, 0x0000611C, + 0x00000001, 0x0009004F, 0x00000017, 0x00001A53, 0x000055C1, 0x000055C1, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x000500C2, 0x00000017, 0x00002331, 0x00001A53, 0x0000004D, 0x000500C7, + 0x00000017, 0x00001E31, 0x00002331, 0x0000002F, 0x00070050, 0x00000017, 0x000043A6, 0x00001917, + 0x00001917, 0x00001917, 0x00001917, 0x00050084, 0x00000017, 0x00005B36, 0x00001E31, 0x000043A6, + 0x0009004F, 0x00000017, 0x000037FE, 0x000044CA, 0x000000C8, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x000500C2, 0x00000017, 0x00003924, 0x000037FE, 0x0000004D, 0x000500C7, 0x00000017, + 0x00001E32, 0x00003924, 0x0000002F, 0x00070050, 0x00000017, 0x00004749, 0x00001C4F, 0x00001C4F, + 0x00001C4F, 0x00001C4F, 0x00050084, 0x00000017, 0x0000318E, 0x00001E32, 0x00004749, 0x00050080, + 0x00000017, 0x00003770, 0x00005B36, 0x0000318E, 0x0007004F, 0x00000011, 0x0000281D, 0x00003770, + 0x00003770, 0x00000000, 0x00000002, 0x000500C7, 0x00000011, 0x000024A0, 0x0000281D, 0x000007DF, + 0x00050086, 0x00000011, 0x00004291, 0x000024A0, 0x0000074E, 0x000500C2, 0x00000011, 0x0000629F, + 0x0000281D, 0x0000085F, 0x00050086, 0x00000011, 0x00003C07, 0x0000629F, 0x0000074E, 0x000500C4, + 0x00000011, 0x000036B6, 0x00003C07, 0x000007B7, 0x000500C5, 0x00000011, 0x000020BA, 0x00004291, + 0x000036B6, 0x0007004F, 0x00000011, 0x000042B4, 0x00003770, 0x00003770, 0x00000001, 0x00000003, + 0x000500C7, 0x00000011, 0x000040FB, 0x000042B4, 0x000007DF, 0x00050086, 0x00000011, 0x000045E4, + 0x000040FB, 0x0000074E, 0x000500C4, 0x00000011, 0x00004263, 0x000045E4, 0x0000085F, 0x000500C5, + 0x00000011, 0x000018AF, 0x000020BA, 0x00004263, 0x000500C2, 0x00000011, 0x00003BDE, 0x000042B4, + 0x0000085F, 0x00050086, 0x00000011, 0x00005E8E, 0x00003BDE, 0x0000074E, 0x000500C4, 0x00000011, + 0x000036DC, 0x00005E8E, 0x00000907, 0x000500C5, 0x00000011, 0x0000611D, 0x000018AF, 0x000036DC, + 0x00050051, 0x0000000B, 0x00004E6D, 0x0000611D, 0x00000000, 0x00050051, 0x0000000B, 0x00005C2F, + 0x0000611D, 0x00000001, 0x00070050, 0x00000017, 0x00004754, 0x00004E5A, 0x00001BF0, 0x00004E6D, + 0x00005C2F, 0x00060041, 0x00000294, 0x00002253, 0x0000140E, 0x00000A0B, 0x00002DCE, 0x0003003E, + 0x00002253, 0x00004754, 0x00050051, 0x0000000B, 0x00003220, 0x000043C0, 0x00000001, 0x00050080, + 0x0000000B, 0x00005AC0, 0x00003220, 0x00000A0D, 0x000500B0, 0x00000009, 0x00004411, 0x00005AC0, + 0x000019C2, 0x000300F7, 0x00001D8E, 0x00000002, 0x000400FA, 0x00004411, 0x0000592C, 0x00001D8E, + 0x000200F8, 0x0000592C, 0x00050080, 0x0000000B, 0x00003CEB, 0x00002DCE, 0x00001B41, 0x000500C2, + 0x00000011, 0x00002AC3, 0x000036AB, 0x000007B7, 0x000400C8, 0x00000011, 0x00005D99, 0x00002AC3, + 0x0009004F, 0x00000017, 0x00002876, 0x00005D99, 0x00005D99, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x000500C2, 0x00000017, 0x000062AA, 0x00002876, 0x0000004D, 0x000500C7, 0x00000017, + 0x0000419B, 0x000062AA, 0x0000002F, 0x00050084, 0x00000017, 0x00003D7C, 0x0000419B, 0x000043A5, + 0x0009004F, 0x00000017, 0x0000291B, 0x00002AC3, 0x00002AC3, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x000500C2, 0x00000017, 0x00003CFF, 0x0000291B, 0x0000004D, 0x000500C7, 0x00000017, + 0x0000453E, 0x00003CFF, 0x0000002F, 0x00050084, 0x00000017, 0x00005E55, 0x0000453E, 0x00004748, + 0x00050080, 0x00000017, 0x0000288D, 0x00003D7C, 0x00005E55, 0x0007004F, 0x00000011, 0x0000281E, + 0x0000288D, 0x0000288D, 0x00000000, 0x00000002, 0x000500C7, 0x00000011, 0x000024A1, 0x0000281E, + 0x000007DF, 0x00050086, 0x00000011, 0x00004292, 0x000024A1, 0x0000074E, 0x000500C2, 0x00000011, + 0x000062A0, 0x0000281E, 0x0000085F, 0x00050086, 0x00000011, 0x00003C08, 0x000062A0, 0x0000074E, + 0x000500C4, 0x00000011, 0x000036B7, 0x00003C08, 0x000007B7, 0x000500C5, 0x00000011, 0x000020BB, + 0x00004292, 0x000036B7, 0x0007004F, 0x00000011, 0x000042B5, 0x0000288D, 0x0000288D, 0x00000001, + 0x00000003, 0x000500C7, 0x00000011, 0x000040FC, 0x000042B5, 0x000007DF, 0x00050086, 0x00000011, + 0x000045E5, 0x000040FC, 0x0000074E, 0x000500C4, 0x00000011, 0x00004264, 0x000045E5, 0x0000085F, + 0x000500C5, 0x00000011, 0x000018B0, 0x000020BB, 0x00004264, 0x000500C2, 0x00000011, 0x00003BDF, + 0x000042B5, 0x0000085F, 0x00050086, 0x00000011, 0x00005E8F, 0x00003BDF, 0x0000074E, 0x000500C4, + 0x00000011, 0x000036DD, 0x00005E8F, 0x00000907, 0x000500C5, 0x00000011, 0x0000611E, 0x000018B0, + 0x000036DD, 0x00050051, 0x0000000B, 0x00004E5B, 0x0000611E, 0x00000000, 0x00050051, 0x0000000B, + 0x00001BF1, 0x0000611E, 0x00000001, 0x0009004F, 0x00000017, 0x00001A54, 0x00005D99, 0x00005D99, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x000500C2, 0x00000017, 0x0000270D, 0x00001A54, + 0x0000004D, 0x000500C7, 0x00000017, 0x0000419C, 0x0000270D, 0x0000002F, 0x00050084, 0x00000017, + 0x00003D7D, 0x0000419C, 0x000043A6, 0x0009004F, 0x00000017, 0x0000291C, 0x00002AC3, 0x00002AC3, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x000500C2, 0x00000017, 0x00003D00, 0x0000291C, + 0x0000004D, 0x000500C7, 0x00000017, 0x0000453F, 0x00003D00, 0x0000002F, 0x00050084, 0x00000017, + 0x00005E56, 0x0000453F, 0x00004749, 0x00050080, 0x00000017, 0x0000288E, 0x00003D7D, 0x00005E56, + 0x0007004F, 0x00000011, 0x0000281F, 0x0000288E, 0x0000288E, 0x00000000, 0x00000002, 0x000500C7, + 0x00000011, 0x000024A2, 0x0000281F, 0x000007DF, 0x00050086, 0x00000011, 0x00004293, 0x000024A2, + 0x0000074E, 0x000500C2, 0x00000011, 0x000062A1, 0x0000281F, 0x0000085F, 0x00050086, 0x00000011, + 0x00003C09, 0x000062A1, 0x0000074E, 0x000500C4, 0x00000011, 0x000036B8, 0x00003C09, 0x000007B7, + 0x000500C5, 0x00000011, 0x000020BC, 0x00004293, 0x000036B8, 0x0007004F, 0x00000011, 0x000042B6, + 0x0000288E, 0x0000288E, 0x00000001, 0x00000003, 0x000500C7, 0x00000011, 0x000040FD, 0x000042B6, + 0x000007DF, 0x00050086, 0x00000011, 0x000045E6, 0x000040FD, 0x0000074E, 0x000500C4, 0x00000011, + 0x00004265, 0x000045E6, 0x0000085F, 0x000500C5, 0x00000011, 0x000018B1, 0x000020BC, 0x00004265, + 0x000500C2, 0x00000011, 0x00003BE0, 0x000042B6, 0x0000085F, 0x00050086, 0x00000011, 0x00005E90, + 0x00003BE0, 0x0000074E, 0x000500C4, 0x00000011, 0x000036DE, 0x00005E90, 0x00000907, 0x000500C5, + 0x00000011, 0x0000611F, 0x000018B1, 0x000036DE, 0x00050051, 0x0000000B, 0x00004E6F, 0x0000611F, + 0x00000000, 0x00050051, 0x0000000B, 0x00005C30, 0x0000611F, 0x00000001, 0x00070050, 0x00000017, + 0x00004755, 0x00004E5B, 0x00001BF1, 0x00004E6F, 0x00005C30, 0x00060041, 0x00000294, 0x000025D0, + 0x0000140E, 0x00000A0B, 0x00003CEB, 0x0003003E, 0x000025D0, 0x00004755, 0x00050080, 0x0000000B, + 0x000039F8, 0x00003220, 0x00000A10, 0x000500B0, 0x00000009, 0x00002E0B, 0x000039F8, 0x000019C2, + 0x000300F7, 0x00001C25, 0x00000002, 0x000400FA, 0x00002E0B, 0x00005192, 0x00001C25, 0x000200F8, + 0x00005192, 0x00050084, 0x0000000B, 0x0000338E, 0x00000A10, 0x00001B41, 0x00050080, 0x0000000B, + 0x0000350D, 0x00002DCE, 0x0000338E, 0x000500C2, 0x00000011, 0x0000367C, 0x000036AB, 0x0000085F, + 0x000400C8, 0x00000011, 0x00005D9A, 0x0000367C, 0x0009004F, 0x00000017, 0x00002877, 0x00005D9A, + 0x00005D9A, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000500C2, 0x00000017, 0x000062AB, + 0x00002877, 0x0000004D, 0x000500C7, 0x00000017, 0x0000419D, 0x000062AB, 0x0000002F, 0x00050084, + 0x00000017, 0x00003D7E, 0x0000419D, 0x000043A5, 0x0009004F, 0x00000017, 0x0000291D, 0x0000367C, + 0x0000367C, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000500C2, 0x00000017, 0x00003D01, + 0x0000291D, 0x0000004D, 0x000500C7, 0x00000017, 0x00004540, 0x00003D01, 0x0000002F, 0x00050084, + 0x00000017, 0x00005E57, 0x00004540, 0x00004748, 0x00050080, 0x00000017, 0x0000288F, 0x00003D7E, + 0x00005E57, 0x0007004F, 0x00000011, 0x00002820, 0x0000288F, 0x0000288F, 0x00000000, 0x00000002, + 0x000500C7, 0x00000011, 0x000024A3, 0x00002820, 0x000007DF, 0x00050086, 0x00000011, 0x00004294, + 0x000024A3, 0x0000074E, 0x000500C2, 0x00000011, 0x000062A2, 0x00002820, 0x0000085F, 0x00050086, + 0x00000011, 0x00003C0A, 0x000062A2, 0x0000074E, 0x000500C4, 0x00000011, 0x000036B9, 0x00003C0A, + 0x000007B7, 0x000500C5, 0x00000011, 0x000020BD, 0x00004294, 0x000036B9, 0x0007004F, 0x00000011, + 0x000042B7, 0x0000288F, 0x0000288F, 0x00000001, 0x00000003, 0x000500C7, 0x00000011, 0x000040FE, + 0x000042B7, 0x000007DF, 0x00050086, 0x00000011, 0x000045E7, 0x000040FE, 0x0000074E, 0x000500C4, + 0x00000011, 0x00004266, 0x000045E7, 0x0000085F, 0x000500C5, 0x00000011, 0x000018B2, 0x000020BD, + 0x00004266, 0x000500C2, 0x00000011, 0x00003BE1, 0x000042B7, 0x0000085F, 0x00050086, 0x00000011, + 0x00005E91, 0x00003BE1, 0x0000074E, 0x000500C4, 0x00000011, 0x000036DF, 0x00005E91, 0x00000907, + 0x000500C5, 0x00000011, 0x00006120, 0x000018B2, 0x000036DF, 0x00050051, 0x0000000B, 0x00004E5C, + 0x00006120, 0x00000000, 0x00050051, 0x0000000B, 0x00001BF2, 0x00006120, 0x00000001, 0x0009004F, + 0x00000017, 0x00001A55, 0x00005D9A, 0x00005D9A, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x000500C2, 0x00000017, 0x0000270E, 0x00001A55, 0x0000004D, 0x000500C7, 0x00000017, 0x0000419E, + 0x0000270E, 0x0000002F, 0x00050084, 0x00000017, 0x00003D7F, 0x0000419E, 0x000043A6, 0x0009004F, + 0x00000017, 0x0000291E, 0x0000367C, 0x0000367C, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x000500C2, 0x00000017, 0x00003D02, 0x0000291E, 0x0000004D, 0x000500C7, 0x00000017, 0x00004541, + 0x00003D02, 0x0000002F, 0x00050084, 0x00000017, 0x00005E58, 0x00004541, 0x00004749, 0x00050080, + 0x00000017, 0x00002890, 0x00003D7F, 0x00005E58, 0x0007004F, 0x00000011, 0x00002821, 0x00002890, + 0x00002890, 0x00000000, 0x00000002, 0x000500C7, 0x00000011, 0x000024A4, 0x00002821, 0x000007DF, + 0x00050086, 0x00000011, 0x00004295, 0x000024A4, 0x0000074E, 0x000500C2, 0x00000011, 0x000062A3, + 0x00002821, 0x0000085F, 0x00050086, 0x00000011, 0x00003C0B, 0x000062A3, 0x0000074E, 0x000500C4, + 0x00000011, 0x000036BA, 0x00003C0B, 0x000007B7, 0x000500C5, 0x00000011, 0x000020BE, 0x00004295, + 0x000036BA, 0x0007004F, 0x00000011, 0x000042B8, 0x00002890, 0x00002890, 0x00000001, 0x00000003, + 0x000500C7, 0x00000011, 0x000040FF, 0x000042B8, 0x000007DF, 0x00050086, 0x00000011, 0x000045E8, + 0x000040FF, 0x0000074E, 0x000500C4, 0x00000011, 0x00004267, 0x000045E8, 0x0000085F, 0x000500C5, + 0x00000011, 0x000018B3, 0x000020BE, 0x00004267, 0x000500C2, 0x00000011, 0x00003BE2, 0x000042B8, + 0x0000085F, 0x00050086, 0x00000011, 0x00005E92, 0x00003BE2, 0x0000074E, 0x000500C4, 0x00000011, + 0x000036E0, 0x00005E92, 0x00000907, 0x000500C5, 0x00000011, 0x00006121, 0x000018B3, 0x000036E0, + 0x00050051, 0x0000000B, 0x00004E70, 0x00006121, 0x00000000, 0x00050051, 0x0000000B, 0x00005C31, + 0x00006121, 0x00000001, 0x00070050, 0x00000017, 0x00004756, 0x00004E5C, 0x00001BF2, 0x00004E70, + 0x00005C31, 0x00060041, 0x00000294, 0x000025D1, 0x0000140E, 0x00000A0B, 0x0000350D, 0x0003003E, + 0x000025D1, 0x00004756, 0x00050080, 0x0000000B, 0x000039F9, 0x00003220, 0x00000A13, 0x000500B0, + 0x00000009, 0x00002E0C, 0x000039F9, 0x000019C2, 0x000300F7, 0x00004665, 0x00000002, 0x000400FA, + 0x00002E0C, 0x00005193, 0x00004665, 0x000200F8, 0x00005193, 0x00050084, 0x0000000B, 0x0000338F, + 0x00000A13, 0x00001B41, 0x00050080, 0x0000000B, 0x0000350E, 0x00002DCE, 0x0000338F, 0x000500C2, + 0x00000011, 0x0000367D, 0x000036AB, 0x00000907, 0x000400C8, 0x00000011, 0x00005D9B, 0x0000367D, + 0x0009004F, 0x00000017, 0x00002879, 0x00005D9B, 0x00005D9B, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x000500C2, 0x00000017, 0x000062AC, 0x00002879, 0x0000004D, 0x000500C7, 0x00000017, + 0x0000419F, 0x000062AC, 0x0000002F, 0x00050084, 0x00000017, 0x00003D80, 0x0000419F, 0x000043A5, + 0x0009004F, 0x00000017, 0x0000291F, 0x0000367D, 0x0000367D, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x000500C2, 0x00000017, 0x00003D03, 0x0000291F, 0x0000004D, 0x000500C7, 0x00000017, + 0x00004542, 0x00003D03, 0x0000002F, 0x00050084, 0x00000017, 0x00005E59, 0x00004542, 0x00004748, + 0x00050080, 0x00000017, 0x00002891, 0x00003D80, 0x00005E59, 0x0007004F, 0x00000011, 0x00002822, + 0x00002891, 0x00002891, 0x00000000, 0x00000002, 0x000500C7, 0x00000011, 0x000024A5, 0x00002822, + 0x000007DF, 0x00050086, 0x00000011, 0x00004296, 0x000024A5, 0x0000074E, 0x000500C2, 0x00000011, + 0x000062A4, 0x00002822, 0x0000085F, 0x00050086, 0x00000011, 0x00003C0C, 0x000062A4, 0x0000074E, + 0x000500C4, 0x00000011, 0x000036BB, 0x00003C0C, 0x000007B7, 0x000500C5, 0x00000011, 0x000020BF, + 0x00004296, 0x000036BB, 0x0007004F, 0x00000011, 0x000042B9, 0x00002891, 0x00002891, 0x00000001, + 0x00000003, 0x000500C7, 0x00000011, 0x00004100, 0x000042B9, 0x000007DF, 0x00050086, 0x00000011, + 0x000045E9, 0x00004100, 0x0000074E, 0x000500C4, 0x00000011, 0x00004268, 0x000045E9, 0x0000085F, + 0x000500C5, 0x00000011, 0x000018B4, 0x000020BF, 0x00004268, 0x000500C2, 0x00000011, 0x00003BE3, + 0x000042B9, 0x0000085F, 0x00050086, 0x00000011, 0x00005E93, 0x00003BE3, 0x0000074E, 0x000500C4, + 0x00000011, 0x000036E1, 0x00005E93, 0x00000907, 0x000500C5, 0x00000011, 0x00006122, 0x000018B4, + 0x000036E1, 0x00050051, 0x0000000B, 0x00004E5D, 0x00006122, 0x00000000, 0x00050051, 0x0000000B, + 0x00001BF3, 0x00006122, 0x00000001, 0x0009004F, 0x00000017, 0x00001A56, 0x00005D9B, 0x00005D9B, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x000500C2, 0x00000017, 0x0000270F, 0x00001A56, + 0x0000004D, 0x000500C7, 0x00000017, 0x000041A0, 0x0000270F, 0x0000002F, 0x00050084, 0x00000017, + 0x00003D81, 0x000041A0, 0x000043A6, 0x0009004F, 0x00000017, 0x00002920, 0x0000367D, 0x0000367D, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x000500C2, 0x00000017, 0x00003D04, 0x00002920, + 0x0000004D, 0x000500C7, 0x00000017, 0x00004543, 0x00003D04, 0x0000002F, 0x00050084, 0x00000017, + 0x00005E5A, 0x00004543, 0x00004749, 0x00050080, 0x00000017, 0x00002892, 0x00003D81, 0x00005E5A, + 0x0007004F, 0x00000011, 0x00002823, 0x00002892, 0x00002892, 0x00000000, 0x00000002, 0x000500C7, + 0x00000011, 0x000024A6, 0x00002823, 0x000007DF, 0x00050086, 0x00000011, 0x00004297, 0x000024A6, + 0x0000074E, 0x000500C2, 0x00000011, 0x000062A5, 0x00002823, 0x0000085F, 0x00050086, 0x00000011, + 0x00003C0D, 0x000062A5, 0x0000074E, 0x000500C4, 0x00000011, 0x000036BC, 0x00003C0D, 0x000007B7, + 0x000500C5, 0x00000011, 0x000020C0, 0x00004297, 0x000036BC, 0x0007004F, 0x00000011, 0x000042BA, + 0x00002892, 0x00002892, 0x00000001, 0x00000003, 0x000500C7, 0x00000011, 0x00004101, 0x000042BA, + 0x000007DF, 0x00050086, 0x00000011, 0x000045EA, 0x00004101, 0x0000074E, 0x000500C4, 0x00000011, + 0x00004269, 0x000045EA, 0x0000085F, 0x000500C5, 0x00000011, 0x000018B5, 0x000020C0, 0x00004269, + 0x000500C2, 0x00000011, 0x00003BE4, 0x000042BA, 0x0000085F, 0x00050086, 0x00000011, 0x00005E94, + 0x00003BE4, 0x0000074E, 0x000500C4, 0x00000011, 0x000036E2, 0x00005E94, 0x00000907, 0x000500C5, + 0x00000011, 0x00006123, 0x000018B5, 0x000036E2, 0x00050051, 0x0000000B, 0x00004E71, 0x00006123, + 0x00000000, 0x00050051, 0x0000000B, 0x00005C32, 0x00006123, 0x00000001, 0x00070050, 0x00000017, + 0x00004757, 0x00004E5D, 0x00001BF3, 0x00004E71, 0x00005C32, 0x00060041, 0x00000294, 0x00002ECB, + 0x0000140E, 0x00000A0B, 0x0000350E, 0x0003003E, 0x00002ECB, 0x00004757, 0x000200F9, 0x00004665, + 0x000200F8, 0x00004665, 0x000200F9, 0x00001C25, 0x000200F8, 0x00001C25, 0x000200F9, 0x00001D8E, + 0x000200F8, 0x00001D8E, 0x00050080, 0x0000000B, 0x000038B5, 0x00002DCE, 0x00000A0E, 0x000600A9, + 0x0000000B, 0x00004706, 0x00004376, 0x00000A10, 0x00000A0D, 0x00050080, 0x0000000B, 0x0000417A, + 0x00005665, 0x00004706, 0x00060041, 0x00000294, 0x00004766, 0x0000107A, 0x00000A0B, 0x0000417A, + 0x0004003D, 0x00000017, 0x000019B2, 0x00004766, 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, + 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, + 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, + 0x00000017, 0x000050AE, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AE, + 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, + 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x00001D8E, 0x00003FF9, + 0x00002958, 0x000300F7, 0x00002DA3, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, 0x00002DA3, + 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, 0x000500C2, + 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, + 0x00003BE8, 0x000200F9, 0x00002DA3, 0x000200F8, 0x00002DA3, 0x000700F5, 0x00000017, 0x00004D8E, + 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x0007004F, 0x00000011, 0x00005676, 0x00004D8E, + 0x00004D8E, 0x00000000, 0x00000002, 0x000500C2, 0x00000011, 0x00003969, 0x00005676, 0x000007B7, + 0x000500C7, 0x00000011, 0x00001D04, 0x00003969, 0x00000474, 0x000500C7, 0x00000011, 0x00004944, + 0x00005676, 0x00000474, 0x000500C4, 0x00000011, 0x000058A3, 0x00004944, 0x0000085F, 0x000500C5, + 0x00000011, 0x00003F72, 0x00001D04, 0x000058A3, 0x00050051, 0x0000000B, 0x000056E4, 0x00003F72, + 0x00000000, 0x00050051, 0x0000000B, 0x00001918, 0x00003F72, 0x00000001, 0x000500C2, 0x00000011, + 0x000029EF, 0x00005676, 0x00000907, 0x000500C7, 0x00000011, 0x00001C22, 0x00005676, 0x00000BB1, + 0x000500C5, 0x00000011, 0x00003963, 0x000029EF, 0x00001C22, 0x00050051, 0x0000000B, 0x00004B32, + 0x00003963, 0x00000000, 0x00050051, 0x0000000B, 0x00001C50, 0x00003963, 0x00000001, 0x0009004F, + 0x00000017, 0x00006139, 0x00004D8E, 0x000000C8, 0x00000001, 0x00000003, 0x00000001, 0x00000001, + 0x000500C7, 0x00000017, 0x00002307, 0x00006139, 0x00000B3E, 0x000500C4, 0x00000017, 0x00005ECB, + 0x00002307, 0x00000B86, 0x000500C7, 0x00000017, 0x000050AF, 0x00006139, 0x00000B2C, 0x000500C2, + 0x00000017, 0x000040D8, 0x000050AF, 0x00000B86, 0x000500C5, 0x00000017, 0x00005DC1, 0x00005ECB, + 0x000040D8, 0x000500C7, 0x00000017, 0x00004CA3, 0x00005DC1, 0x00000B2C, 0x000500C2, 0x00000017, + 0x00004707, 0x00004CA3, 0x00000B86, 0x000500C6, 0x00000017, 0x000044CB, 0x00005DC1, 0x00004707, + 0x0007004F, 0x00000011, 0x000036AC, 0x000044CB, 0x000044CB, 0x00000000, 0x00000001, 0x000400C8, + 0x00000011, 0x000055C2, 0x000036AC, 0x0009004F, 0x00000017, 0x000043F3, 0x000055C2, 0x000055C2, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000500C2, 0x00000017, 0x00005ECF, 0x000043F3, + 0x0000004D, 0x000500C7, 0x00000017, 0x00001E33, 0x00005ECF, 0x0000002F, 0x00070050, 0x00000017, + 0x000043A7, 0x000056E4, 0x000056E4, 0x000056E4, 0x000056E4, 0x00050084, 0x00000017, 0x00005B37, + 0x00001E33, 0x000043A7, 0x0009004F, 0x00000017, 0x000037FF, 0x000044CB, 0x000000C8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x000500C2, 0x00000017, 0x00003925, 0x000037FF, 0x0000004D, + 0x000500C7, 0x00000017, 0x00001E34, 0x00003925, 0x0000002F, 0x00070050, 0x00000017, 0x0000474A, + 0x00004B32, 0x00004B32, 0x00004B32, 0x00004B32, 0x00050084, 0x00000017, 0x0000318F, 0x00001E34, + 0x0000474A, 0x00050080, 0x00000017, 0x00003771, 0x00005B37, 0x0000318F, 0x0007004F, 0x00000011, + 0x00002824, 0x00003771, 0x00003771, 0x00000000, 0x00000002, 0x000500C7, 0x00000011, 0x000024A7, + 0x00002824, 0x000007DF, 0x00050086, 0x00000011, 0x00004298, 0x000024A7, 0x0000074E, 0x000500C2, + 0x00000011, 0x000062A6, 0x00002824, 0x0000085F, 0x00050086, 0x00000011, 0x00003C0E, 0x000062A6, + 0x0000074E, 0x000500C4, 0x00000011, 0x000036BD, 0x00003C0E, 0x000007B7, 0x000500C5, 0x00000011, + 0x000020C1, 0x00004298, 0x000036BD, 0x0007004F, 0x00000011, 0x000042BB, 0x00003771, 0x00003771, + 0x00000001, 0x00000003, 0x000500C7, 0x00000011, 0x00004102, 0x000042BB, 0x000007DF, 0x00050086, + 0x00000011, 0x000045EB, 0x00004102, 0x0000074E, 0x000500C4, 0x00000011, 0x0000426A, 0x000045EB, + 0x0000085F, 0x000500C5, 0x00000011, 0x000018B6, 0x000020C1, 0x0000426A, 0x000500C2, 0x00000011, + 0x00003BE5, 0x000042BB, 0x0000085F, 0x00050086, 0x00000011, 0x00005E95, 0x00003BE5, 0x0000074E, + 0x000500C4, 0x00000011, 0x000036E3, 0x00005E95, 0x00000907, 0x000500C5, 0x00000011, 0x00006124, + 0x000018B6, 0x000036E3, 0x00050051, 0x0000000B, 0x00004E5E, 0x00006124, 0x00000000, 0x00050051, + 0x0000000B, 0x00001BF4, 0x00006124, 0x00000001, 0x0009004F, 0x00000017, 0x00001A57, 0x000055C2, + 0x000055C2, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x000500C2, 0x00000017, 0x00002332, + 0x00001A57, 0x0000004D, 0x000500C7, 0x00000017, 0x00001E35, 0x00002332, 0x0000002F, 0x00070050, + 0x00000017, 0x000043A8, 0x00001918, 0x00001918, 0x00001918, 0x00001918, 0x00050084, 0x00000017, + 0x00005B38, 0x00001E35, 0x000043A8, 0x0009004F, 0x00000017, 0x00003800, 0x000044CB, 0x000000C8, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x000500C2, 0x00000017, 0x00003926, 0x00003800, + 0x0000004D, 0x000500C7, 0x00000017, 0x00001E36, 0x00003926, 0x0000002F, 0x00070050, 0x00000017, + 0x0000474B, 0x00001C50, 0x00001C50, 0x00001C50, 0x00001C50, 0x00050084, 0x00000017, 0x00003190, + 0x00001E36, 0x0000474B, 0x00050080, 0x00000017, 0x00003772, 0x00005B38, 0x00003190, 0x0007004F, + 0x00000011, 0x00002825, 0x00003772, 0x00003772, 0x00000000, 0x00000002, 0x000500C7, 0x00000011, + 0x000024A8, 0x00002825, 0x000007DF, 0x00050086, 0x00000011, 0x00004299, 0x000024A8, 0x0000074E, + 0x000500C2, 0x00000011, 0x000062A7, 0x00002825, 0x0000085F, 0x00050086, 0x00000011, 0x00003C0F, + 0x000062A7, 0x0000074E, 0x000500C4, 0x00000011, 0x000036BE, 0x00003C0F, 0x000007B7, 0x000500C5, + 0x00000011, 0x000020C2, 0x00004299, 0x000036BE, 0x0007004F, 0x00000011, 0x000042BC, 0x00003772, + 0x00003772, 0x00000001, 0x00000003, 0x000500C7, 0x00000011, 0x00004103, 0x000042BC, 0x000007DF, + 0x00050086, 0x00000011, 0x000045EC, 0x00004103, 0x0000074E, 0x000500C4, 0x00000011, 0x0000426B, + 0x000045EC, 0x0000085F, 0x000500C5, 0x00000011, 0x000018B7, 0x000020C2, 0x0000426B, 0x000500C2, + 0x00000011, 0x00003BE6, 0x000042BC, 0x0000085F, 0x00050086, 0x00000011, 0x00005E96, 0x00003BE6, + 0x0000074E, 0x000500C4, 0x00000011, 0x000036E4, 0x00005E96, 0x00000907, 0x000500C5, 0x00000011, + 0x00006125, 0x000018B7, 0x000036E4, 0x00050051, 0x0000000B, 0x00004E72, 0x00006125, 0x00000000, + 0x00050051, 0x0000000B, 0x00005C33, 0x00006125, 0x00000001, 0x00070050, 0x00000017, 0x00004758, + 0x00004E5E, 0x00001BF4, 0x00004E72, 0x00005C33, 0x00060041, 0x00000294, 0x00002EA5, 0x0000140E, + 0x00000A0B, 0x000038B5, 0x0003003E, 0x00002EA5, 0x00004758, 0x000300F7, 0x00001C27, 0x00000002, + 0x000400FA, 0x00004411, 0x0000592D, 0x00001C27, 0x000200F8, 0x0000592D, 0x00050080, 0x0000000B, + 0x00003CEC, 0x000038B5, 0x00001B41, 0x000500C2, 0x00000011, 0x00002AC4, 0x000036AC, 0x000007B7, + 0x000400C8, 0x00000011, 0x00005D9C, 0x00002AC4, 0x0009004F, 0x00000017, 0x0000287A, 0x00005D9C, + 0x00005D9C, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000500C2, 0x00000017, 0x000062AD, + 0x0000287A, 0x0000004D, 0x000500C7, 0x00000017, 0x000041A1, 0x000062AD, 0x0000002F, 0x00050084, + 0x00000017, 0x00003D82, 0x000041A1, 0x000043A7, 0x0009004F, 0x00000017, 0x00002921, 0x00002AC4, + 0x00002AC4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000500C2, 0x00000017, 0x00003D05, + 0x00002921, 0x0000004D, 0x000500C7, 0x00000017, 0x00004544, 0x00003D05, 0x0000002F, 0x00050084, + 0x00000017, 0x00005E5B, 0x00004544, 0x0000474A, 0x00050080, 0x00000017, 0x00002893, 0x00003D82, + 0x00005E5B, 0x0007004F, 0x00000011, 0x00002826, 0x00002893, 0x00002893, 0x00000000, 0x00000002, + 0x000500C7, 0x00000011, 0x000024A9, 0x00002826, 0x000007DF, 0x00050086, 0x00000011, 0x0000429A, + 0x000024A9, 0x0000074E, 0x000500C2, 0x00000011, 0x000062A8, 0x00002826, 0x0000085F, 0x00050086, + 0x00000011, 0x00003C10, 0x000062A8, 0x0000074E, 0x000500C4, 0x00000011, 0x000036BF, 0x00003C10, + 0x000007B7, 0x000500C5, 0x00000011, 0x000020C3, 0x0000429A, 0x000036BF, 0x0007004F, 0x00000011, + 0x000042BD, 0x00002893, 0x00002893, 0x00000001, 0x00000003, 0x000500C7, 0x00000011, 0x00004104, + 0x000042BD, 0x000007DF, 0x00050086, 0x00000011, 0x000045ED, 0x00004104, 0x0000074E, 0x000500C4, + 0x00000011, 0x0000426C, 0x000045ED, 0x0000085F, 0x000500C5, 0x00000011, 0x000018B8, 0x000020C3, + 0x0000426C, 0x000500C2, 0x00000011, 0x00003BE9, 0x000042BD, 0x0000085F, 0x00050086, 0x00000011, + 0x00005E97, 0x00003BE9, 0x0000074E, 0x000500C4, 0x00000011, 0x000036E5, 0x00005E97, 0x00000907, + 0x000500C5, 0x00000011, 0x00006126, 0x000018B8, 0x000036E5, 0x00050051, 0x0000000B, 0x00004E5F, + 0x00006126, 0x00000000, 0x00050051, 0x0000000B, 0x00001BF5, 0x00006126, 0x00000001, 0x0009004F, + 0x00000017, 0x00001A58, 0x00005D9C, 0x00005D9C, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x000500C2, 0x00000017, 0x00002710, 0x00001A58, 0x0000004D, 0x000500C7, 0x00000017, 0x000041A2, + 0x00002710, 0x0000002F, 0x00050084, 0x00000017, 0x00003D83, 0x000041A2, 0x000043A8, 0x0009004F, + 0x00000017, 0x00002922, 0x00002AC4, 0x00002AC4, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x000500C2, 0x00000017, 0x00003D06, 0x00002922, 0x0000004D, 0x000500C7, 0x00000017, 0x00004545, + 0x00003D06, 0x0000002F, 0x00050084, 0x00000017, 0x00005E5C, 0x00004545, 0x0000474B, 0x00050080, + 0x00000017, 0x00002894, 0x00003D83, 0x00005E5C, 0x0007004F, 0x00000011, 0x00002827, 0x00002894, + 0x00002894, 0x00000000, 0x00000002, 0x000500C7, 0x00000011, 0x000024AA, 0x00002827, 0x000007DF, + 0x00050086, 0x00000011, 0x0000429B, 0x000024AA, 0x0000074E, 0x000500C2, 0x00000011, 0x000062A9, + 0x00002827, 0x0000085F, 0x00050086, 0x00000011, 0x00003C11, 0x000062A9, 0x0000074E, 0x000500C4, + 0x00000011, 0x000036C0, 0x00003C11, 0x000007B7, 0x000500C5, 0x00000011, 0x000020C4, 0x0000429B, + 0x000036C0, 0x0007004F, 0x00000011, 0x000042BE, 0x00002894, 0x00002894, 0x00000001, 0x00000003, + 0x000500C7, 0x00000011, 0x00004105, 0x000042BE, 0x000007DF, 0x00050086, 0x00000011, 0x000045EE, + 0x00004105, 0x0000074E, 0x000500C4, 0x00000011, 0x0000426D, 0x000045EE, 0x0000085F, 0x000500C5, + 0x00000011, 0x000018B9, 0x000020C4, 0x0000426D, 0x000500C2, 0x00000011, 0x00003BEA, 0x000042BE, + 0x0000085F, 0x00050086, 0x00000011, 0x00005E98, 0x00003BEA, 0x0000074E, 0x000500C4, 0x00000011, + 0x000036E6, 0x00005E98, 0x00000907, 0x000500C5, 0x00000011, 0x00006127, 0x000018B9, 0x000036E6, + 0x00050051, 0x0000000B, 0x00004E73, 0x00006127, 0x00000000, 0x00050051, 0x0000000B, 0x00005C34, + 0x00006127, 0x00000001, 0x00070050, 0x00000017, 0x00004759, 0x00004E5F, 0x00001BF5, 0x00004E73, + 0x00005C34, 0x00060041, 0x00000294, 0x000025D2, 0x0000140E, 0x00000A0B, 0x00003CEC, 0x0003003E, + 0x000025D2, 0x00004759, 0x00050080, 0x0000000B, 0x000039FA, 0x00003220, 0x00000A10, 0x000500B0, + 0x00000009, 0x00002E0D, 0x000039FA, 0x000019C2, 0x000300F7, 0x00001C26, 0x00000002, 0x000400FA, + 0x00002E0D, 0x00005194, 0x00001C26, 0x000200F8, 0x00005194, 0x00050084, 0x0000000B, 0x00003390, + 0x00000A10, 0x00001B41, 0x00050080, 0x0000000B, 0x0000350F, 0x000038B5, 0x00003390, 0x000500C2, + 0x00000011, 0x0000367E, 0x000036AC, 0x0000085F, 0x000400C8, 0x00000011, 0x00005D9D, 0x0000367E, + 0x0009004F, 0x00000017, 0x0000287B, 0x00005D9D, 0x00005D9D, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x000500C2, 0x00000017, 0x000062AE, 0x0000287B, 0x0000004D, 0x000500C7, 0x00000017, + 0x000041A3, 0x000062AE, 0x0000002F, 0x00050084, 0x00000017, 0x00003D84, 0x000041A3, 0x000043A7, + 0x0009004F, 0x00000017, 0x00002923, 0x0000367E, 0x0000367E, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x000500C2, 0x00000017, 0x00003D07, 0x00002923, 0x0000004D, 0x000500C7, 0x00000017, + 0x00004546, 0x00003D07, 0x0000002F, 0x00050084, 0x00000017, 0x00005E5D, 0x00004546, 0x0000474A, + 0x00050080, 0x00000017, 0x00002895, 0x00003D84, 0x00005E5D, 0x0007004F, 0x00000011, 0x00002828, + 0x00002895, 0x00002895, 0x00000000, 0x00000002, 0x000500C7, 0x00000011, 0x000024AB, 0x00002828, + 0x000007DF, 0x00050086, 0x00000011, 0x0000429C, 0x000024AB, 0x0000074E, 0x000500C2, 0x00000011, + 0x000062AF, 0x00002828, 0x0000085F, 0x00050086, 0x00000011, 0x00003C12, 0x000062AF, 0x0000074E, + 0x000500C4, 0x00000011, 0x000036C1, 0x00003C12, 0x000007B7, 0x000500C5, 0x00000011, 0x000020C5, + 0x0000429C, 0x000036C1, 0x0007004F, 0x00000011, 0x000042BF, 0x00002895, 0x00002895, 0x00000001, + 0x00000003, 0x000500C7, 0x00000011, 0x00004106, 0x000042BF, 0x000007DF, 0x00050086, 0x00000011, + 0x000045EF, 0x00004106, 0x0000074E, 0x000500C4, 0x00000011, 0x0000426E, 0x000045EF, 0x0000085F, + 0x000500C5, 0x00000011, 0x000018BA, 0x000020C5, 0x0000426E, 0x000500C2, 0x00000011, 0x00003BEB, + 0x000042BF, 0x0000085F, 0x00050086, 0x00000011, 0x00005E99, 0x00003BEB, 0x0000074E, 0x000500C4, + 0x00000011, 0x000036E7, 0x00005E99, 0x00000907, 0x000500C5, 0x00000011, 0x00006128, 0x000018BA, + 0x000036E7, 0x00050051, 0x0000000B, 0x00004E60, 0x00006128, 0x00000000, 0x00050051, 0x0000000B, + 0x00001BF6, 0x00006128, 0x00000001, 0x0009004F, 0x00000017, 0x00001A59, 0x00005D9D, 0x00005D9D, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x000500C2, 0x00000017, 0x00002711, 0x00001A59, + 0x0000004D, 0x000500C7, 0x00000017, 0x000041A4, 0x00002711, 0x0000002F, 0x00050084, 0x00000017, + 0x00003D85, 0x000041A4, 0x000043A8, 0x0009004F, 0x00000017, 0x00002924, 0x0000367E, 0x0000367E, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x000500C2, 0x00000017, 0x00003D08, 0x00002924, + 0x0000004D, 0x000500C7, 0x00000017, 0x00004547, 0x00003D08, 0x0000002F, 0x00050084, 0x00000017, + 0x00005E5E, 0x00004547, 0x0000474B, 0x00050080, 0x00000017, 0x00002896, 0x00003D85, 0x00005E5E, + 0x0007004F, 0x00000011, 0x00002829, 0x00002896, 0x00002896, 0x00000000, 0x00000002, 0x000500C7, + 0x00000011, 0x000024AC, 0x00002829, 0x000007DF, 0x00050086, 0x00000011, 0x0000429D, 0x000024AC, + 0x0000074E, 0x000500C2, 0x00000011, 0x000062B0, 0x00002829, 0x0000085F, 0x00050086, 0x00000011, + 0x00003C13, 0x000062B0, 0x0000074E, 0x000500C4, 0x00000011, 0x000036C3, 0x00003C13, 0x000007B7, + 0x000500C5, 0x00000011, 0x000020C6, 0x0000429D, 0x000036C3, 0x0007004F, 0x00000011, 0x000042C0, + 0x00002896, 0x00002896, 0x00000001, 0x00000003, 0x000500C7, 0x00000011, 0x00004107, 0x000042C0, + 0x000007DF, 0x00050086, 0x00000011, 0x000045F0, 0x00004107, 0x0000074E, 0x000500C4, 0x00000011, + 0x0000426F, 0x000045F0, 0x0000085F, 0x000500C5, 0x00000011, 0x000018BB, 0x000020C6, 0x0000426F, + 0x000500C2, 0x00000011, 0x00003BEC, 0x000042C0, 0x0000085F, 0x00050086, 0x00000011, 0x00005E9A, + 0x00003BEC, 0x0000074E, 0x000500C4, 0x00000011, 0x000036E8, 0x00005E9A, 0x00000907, 0x000500C5, + 0x00000011, 0x00006129, 0x000018BB, 0x000036E8, 0x00050051, 0x0000000B, 0x00004E74, 0x00006129, + 0x00000000, 0x00050051, 0x0000000B, 0x00005C35, 0x00006129, 0x00000001, 0x00070050, 0x00000017, + 0x0000475A, 0x00004E60, 0x00001BF6, 0x00004E74, 0x00005C35, 0x00060041, 0x00000294, 0x000025D3, + 0x0000140E, 0x00000A0B, 0x0000350F, 0x0003003E, 0x000025D3, 0x0000475A, 0x00050080, 0x0000000B, + 0x000039FB, 0x00003220, 0x00000A13, 0x000500B0, 0x00000009, 0x00002E0E, 0x000039FB, 0x000019C2, + 0x000300F7, 0x00004666, 0x00000002, 0x000400FA, 0x00002E0E, 0x00005195, 0x00004666, 0x000200F8, + 0x00005195, 0x00050084, 0x0000000B, 0x00003391, 0x00000A13, 0x00001B41, 0x00050080, 0x0000000B, + 0x00003510, 0x000038B5, 0x00003391, 0x000500C2, 0x00000011, 0x0000367F, 0x000036AC, 0x00000907, + 0x000400C8, 0x00000011, 0x00005D9E, 0x0000367F, 0x0009004F, 0x00000017, 0x0000287C, 0x00005D9E, + 0x00005D9E, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000500C2, 0x00000017, 0x000062B1, + 0x0000287C, 0x0000004D, 0x000500C7, 0x00000017, 0x000041A5, 0x000062B1, 0x0000002F, 0x00050084, + 0x00000017, 0x00003D86, 0x000041A5, 0x000043A7, 0x0009004F, 0x00000017, 0x00002925, 0x0000367F, + 0x0000367F, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000500C2, 0x00000017, 0x00003D09, + 0x00002925, 0x0000004D, 0x000500C7, 0x00000017, 0x00004548, 0x00003D09, 0x0000002F, 0x00050084, + 0x00000017, 0x00005E5F, 0x00004548, 0x0000474A, 0x00050080, 0x00000017, 0x00002897, 0x00003D86, + 0x00005E5F, 0x0007004F, 0x00000011, 0x0000282A, 0x00002897, 0x00002897, 0x00000000, 0x00000002, + 0x000500C7, 0x00000011, 0x000024AD, 0x0000282A, 0x000007DF, 0x00050086, 0x00000011, 0x0000429E, + 0x000024AD, 0x0000074E, 0x000500C2, 0x00000011, 0x000062B2, 0x0000282A, 0x0000085F, 0x00050086, + 0x00000011, 0x00003C14, 0x000062B2, 0x0000074E, 0x000500C4, 0x00000011, 0x000036C4, 0x00003C14, + 0x000007B7, 0x000500C5, 0x00000011, 0x000020C7, 0x0000429E, 0x000036C4, 0x0007004F, 0x00000011, + 0x000042C1, 0x00002897, 0x00002897, 0x00000001, 0x00000003, 0x000500C7, 0x00000011, 0x00004108, + 0x000042C1, 0x000007DF, 0x00050086, 0x00000011, 0x000045F1, 0x00004108, 0x0000074E, 0x000500C4, + 0x00000011, 0x00004270, 0x000045F1, 0x0000085F, 0x000500C5, 0x00000011, 0x000018BC, 0x000020C7, + 0x00004270, 0x000500C2, 0x00000011, 0x00003BED, 0x000042C1, 0x0000085F, 0x00050086, 0x00000011, + 0x00005E9B, 0x00003BED, 0x0000074E, 0x000500C4, 0x00000011, 0x000036E9, 0x00005E9B, 0x00000907, + 0x000500C5, 0x00000011, 0x0000612A, 0x000018BC, 0x000036E9, 0x00050051, 0x0000000B, 0x00004E61, + 0x0000612A, 0x00000000, 0x00050051, 0x0000000B, 0x00001BF7, 0x0000612A, 0x00000001, 0x0009004F, + 0x00000017, 0x00001A5A, 0x00005D9E, 0x00005D9E, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x000500C2, 0x00000017, 0x00002712, 0x00001A5A, 0x0000004D, 0x000500C7, 0x00000017, 0x000041A6, + 0x00002712, 0x0000002F, 0x00050084, 0x00000017, 0x00003D87, 0x000041A6, 0x000043A8, 0x0009004F, + 0x00000017, 0x00002926, 0x0000367F, 0x0000367F, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x000500C2, 0x00000017, 0x00003D0A, 0x00002926, 0x0000004D, 0x000500C7, 0x00000017, 0x00004549, + 0x00003D0A, 0x0000002F, 0x00050084, 0x00000017, 0x00005E60, 0x00004549, 0x0000474B, 0x00050080, + 0x00000017, 0x00002898, 0x00003D87, 0x00005E60, 0x0007004F, 0x00000011, 0x0000282B, 0x00002898, + 0x00002898, 0x00000000, 0x00000002, 0x000500C7, 0x00000011, 0x000024AE, 0x0000282B, 0x000007DF, + 0x00050086, 0x00000011, 0x0000429F, 0x000024AE, 0x0000074E, 0x000500C2, 0x00000011, 0x000062B3, + 0x0000282B, 0x0000085F, 0x00050086, 0x00000011, 0x00003C15, 0x000062B3, 0x0000074E, 0x000500C4, + 0x00000011, 0x000036C5, 0x00003C15, 0x000007B7, 0x000500C5, 0x00000011, 0x000020C8, 0x0000429F, + 0x000036C5, 0x0007004F, 0x00000011, 0x000042C4, 0x00002898, 0x00002898, 0x00000001, 0x00000003, + 0x000500C7, 0x00000011, 0x00004109, 0x000042C4, 0x000007DF, 0x00050086, 0x00000011, 0x000045F2, + 0x00004109, 0x0000074E, 0x000500C4, 0x00000011, 0x00004271, 0x000045F2, 0x0000085F, 0x000500C5, + 0x00000011, 0x000018BD, 0x000020C8, 0x00004271, 0x000500C2, 0x00000011, 0x00003BEE, 0x000042C4, + 0x0000085F, 0x00050086, 0x00000011, 0x00005E9C, 0x00003BEE, 0x0000074E, 0x000500C4, 0x00000011, + 0x000036EA, 0x00005E9C, 0x00000907, 0x000500C5, 0x00000011, 0x0000612B, 0x000018BD, 0x000036EA, + 0x00050051, 0x0000000B, 0x00004E75, 0x0000612B, 0x00000000, 0x00050051, 0x0000000B, 0x00005C36, + 0x0000612B, 0x00000001, 0x00070050, 0x00000017, 0x0000475B, 0x00004E61, 0x00001BF7, 0x00004E75, + 0x00005C36, 0x00060041, 0x00000294, 0x00002ECC, 0x0000140E, 0x00000A0B, 0x00003510, 0x0003003E, + 0x00002ECC, 0x0000475B, 0x000200F9, 0x00004666, 0x000200F8, 0x00004666, 0x000200F9, 0x00001C26, + 0x000200F8, 0x00001C26, 0x000200F9, 0x00001C27, 0x000200F8, 0x00001C27, 0x000200F9, 0x00003A37, + 0x000200F8, 0x00003A37, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_depth_float_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_depth_float_cs.h new file mode 100644 index 0000000..fde7910 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_depth_float_cs.h @@ -0,0 +1,608 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25059 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %v4int = OpTypeVector %int 4 +%uint_1048575 = OpConstant %uint 1048575 + %uint_20 = OpConstant %uint 20 + %v4bool = OpTypeVector %bool 4 + %uint_0 = OpConstant %uint 0 + %uint_1 = OpConstant %uint 1 + %uint_112 = OpConstant %uint 112 + %uint_23 = OpConstant %uint 23 + %uint_3 = OpConstant %uint 3 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_16 = OpConstant %uint 16 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2603 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %1080 = OpConstantComposite %v4uint %uint_1048575 %uint_1048575 %uint_1048575 %uint_1048575 + %965 = OpConstantComposite %v4uint %uint_20 %uint_20 %uint_20 %uint_20 + %2896 = OpConstantComposite %v4uint %uint_0 %uint_0 %uint_0 %uint_0 + %2922 = OpConstantComposite %v4uint %uint_112 %uint_112 %uint_112 %uint_112 + %1127 = OpConstantComposite %v4uint %uint_23 %uint_23 %uint_23 %uint_23 + %47 = OpConstantComposite %v4uint %uint_3 %uint_3 %uint_3 %uint_3 +%uint_4294967277 = OpConstant %uint 4294967277 + %1870 = OpConstantComposite %v4uint %uint_4294967277 %uint_4294967277 %uint_4294967277 %uint_4294967277 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2603 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_4 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %6362 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %22810 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %13867 None + OpBranchConditional %15139 %11064 %13867 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %13867 + %13867 = OpLabel + %19124 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %7000 = OpShiftRightLogical %v4uint %19124 %317 + %12837 = OpBitwiseAnd %v4uint %7000 %1080 + %22636 = OpShiftRightLogical %v4uint %7000 %965 + %16585 = OpIEqual %v4bool %22636 %2896 + %11339 = OpExtInst %v4int %1 FindUMsb %12837 + %10773 = OpBitcast %v4uint %11339 + %6266 = OpISub %v4uint %965 %10773 + %8720 = OpIAdd %v4uint %10773 %1870 + %10351 = OpSelect %v4uint %16585 %8720 %22636 + %23252 = OpShiftLeftLogical %v4uint %12837 %6266 + %18842 = OpBitwiseAnd %v4uint %23252 %1080 + %10910 = OpSelect %v4uint %16585 %18842 %12837 + %24569 = OpIAdd %v4uint %10351 %2922 + %20351 = OpShiftLeftLogical %v4uint %24569 %1127 + %16294 = OpShiftLeftLogical %v4uint %10910 %47 + %22396 = OpBitwiseOr %v4uint %20351 %16294 + %12703 = OpIEqual %v4bool %7000 %2896 + %24661 = OpSelect %v4uint %12703 %2896 %22396 + %8770 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %8770 %24661 + %21686 = OpIAdd %uint %21685 %int_1 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_32 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %6871 %16377 %10584 + OpSelectionMerge %13868 None + OpBranchConditional %15139 %11065 %13868 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %13868 + %13868 = OpLabel + %19125 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %7001 = OpShiftRightLogical %v4uint %19125 %317 + %12838 = OpBitwiseAnd %v4uint %7001 %1080 + %22637 = OpShiftRightLogical %v4uint %7001 %965 + %16586 = OpIEqual %v4bool %22637 %2896 + %11340 = OpExtInst %v4int %1 FindUMsb %12838 + %10774 = OpBitcast %v4uint %11340 + %6267 = OpISub %v4uint %965 %10774 + %8721 = OpIAdd %v4uint %10774 %1870 + %10352 = OpSelect %v4uint %16586 %8721 %22637 + %23253 = OpShiftLeftLogical %v4uint %12838 %6267 + %18843 = OpBitwiseAnd %v4uint %23253 %1080 + %10911 = OpSelect %v4uint %16586 %18843 %12838 + %24570 = OpIAdd %v4uint %10352 %2922 + %20352 = OpShiftLeftLogical %v4uint %24570 %1127 + %16295 = OpShiftLeftLogical %v4uint %10911 %47 + %22397 = OpBitwiseOr %v4uint %20352 %16295 + %12704 = OpIEqual %v4bool %7001 %2896 + %24662 = OpSelect %v4uint %12704 %2896 %22397 + %11069 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21686 + OpStore %11069 %24662 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_depth_float_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000061E3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, + 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x00040017, 0x0000001A, 0x0000000C, 0x00000004, 0x0004002B, 0x0000000B, 0x00000708, 0x000FFFFF, + 0x0004002B, 0x0000000B, 0x00000A46, 0x00000014, 0x00040017, 0x00000013, 0x00000009, 0x00000004, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0004002B, 0x0000000B, 0x00000B5A, 0x00000070, 0x0004002B, 0x0000000B, 0x00000A4F, 0x00000017, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, + 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, + 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, + 0x00000009, 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, + 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, + 0x00000A2B, 0x00000A13, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, + 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, + 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0004002B, 0x0000000B, + 0x00000A25, 0x00000009, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, + 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, + 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, + 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0007002C, 0x00000017, + 0x00000438, 0x00000708, 0x00000708, 0x00000708, 0x00000708, 0x0007002C, 0x00000017, 0x000003C5, + 0x00000A46, 0x00000A46, 0x00000A46, 0x00000A46, 0x0007002C, 0x00000017, 0x00000B50, 0x00000A0A, + 0x00000A0A, 0x00000A0A, 0x00000A0A, 0x0007002C, 0x00000017, 0x00000B6A, 0x00000B5A, 0x00000B5A, + 0x00000B5A, 0x00000B5A, 0x0007002C, 0x00000017, 0x00000467, 0x00000A4F, 0x00000A4F, 0x00000A4F, + 0x00000A4F, 0x0007002C, 0x00000017, 0x0000002F, 0x00000A13, 0x00000A13, 0x00000A13, 0x00000A13, + 0x0004002B, 0x0000000B, 0x000009D1, 0xFFFFFFED, 0x0007002C, 0x00000017, 0x0000074E, 0x000009D1, + 0x000009D1, 0x000009D1, 0x000009D1, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, + 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, + 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, + 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, + 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, + 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, + 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, + 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, + 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, + 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, + 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, + 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, + 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, + 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, + 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A2B, + 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, + 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, + 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, + 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, + 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, + 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A17, 0x00050051, + 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, + 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, + 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, + 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, + 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, + 0x00002042, 0x00050080, 0x0000000B, 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, + 0x000054B5, 0x00002764, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, + 0x00005768, 0x000051F2, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, + 0x00004384, 0x00002BF8, 0x000018D9, 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, 0x000032B3, + 0x000044BE, 0x00000A17, 0x000500C3, 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, 0x000500C2, + 0x0000000B, 0x00004947, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00004947, + 0x00050084, 0x0000000C, 0x00005321, 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, + 0x000032B3, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, + 0x0000000C, 0x00003901, 0x00002348, 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, 0x00003901, + 0x000500C3, 0x0000000C, 0x000032BA, 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, 0x00005FEE, + 0x000032BA, 0x000020F4, 0x000500C4, 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A22, 0x000500C7, + 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, + 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003138, 0x000044BE, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, + 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, + 0x0000434B, 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, + 0x0000000C, 0x00002215, 0x000044BE, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, + 0x0000601E, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, + 0x00004112, 0x00005BEB, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, + 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, + 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, + 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, + 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, + 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, + 0x000018DA, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, 0x00050080, + 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000044BE, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, + 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, + 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, + 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, + 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, + 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, + 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, + 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, 0x000019AD, + 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, + 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, 0x00000001, + 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, + 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, 0x0000000C, + 0x00005347, 0x0000405C, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, + 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002AB6, + 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, 0x000500C4, + 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, + 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, 0x0000000C, + 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, + 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, + 0x0000000C, 0x000047B5, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, + 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, + 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, + 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, + 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, + 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, + 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, + 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, + 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, + 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, + 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, + 0x0000000C, 0x0000292C, 0x000054ED, 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, 0x00005F43, + 0x000200F8, 0x000051F2, 0x0004007C, 0x0000000C, 0x00003CBC, 0x00005789, 0x00050084, 0x0000000C, + 0x000060B8, 0x000018DA, 0x00003CBC, 0x00050080, 0x0000000C, 0x0000208E, 0x000060B8, 0x000044BE, + 0x0004007C, 0x0000000C, 0x000022F8, 0x00005788, 0x00050084, 0x0000000C, 0x00001E9F, 0x0000208E, + 0x000022F8, 0x00050080, 0x0000000C, 0x00001F30, 0x0000591A, 0x00001E9F, 0x000200F9, 0x00005F43, + 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, 0x00001F30, + 0x000051F2, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, 0x000056CD, + 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, 0x0000000B, + 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, 0x00004315, 0x0000107A, 0x00000A0B, + 0x00005665, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004315, 0x000500AA, 0x00000009, 0x000035C0, + 0x000061E2, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x000061E2, 0x00000A10, 0x000500A6, + 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, + 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, + 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, + 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, + 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, + 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, 0x00005F43, 0x00003FF8, + 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000061E2, 0x00000A13, 0x000500A6, 0x00000009, + 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x0000362B, 0x00000000, 0x000400FA, 0x00003B23, + 0x00002B38, 0x0000362B, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, + 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, + 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x0000362B, 0x000200F8, 0x0000362B, 0x000700F5, + 0x00000017, 0x00004AB4, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x000500C2, 0x00000017, + 0x00001B58, 0x00004AB4, 0x0000013D, 0x000500C7, 0x00000017, 0x00003225, 0x00001B58, 0x00000438, + 0x000500C2, 0x00000017, 0x0000586C, 0x00001B58, 0x000003C5, 0x000500AA, 0x00000013, 0x000040C9, + 0x0000586C, 0x00000B50, 0x0006000C, 0x0000001A, 0x00002C4B, 0x00000001, 0x0000004B, 0x00003225, + 0x0004007C, 0x00000017, 0x00002A15, 0x00002C4B, 0x00050082, 0x00000017, 0x0000187A, 0x000003C5, + 0x00002A15, 0x00050080, 0x00000017, 0x00002210, 0x00002A15, 0x0000074E, 0x000600A9, 0x00000017, + 0x0000286F, 0x000040C9, 0x00002210, 0x0000586C, 0x000500C4, 0x00000017, 0x00005AD4, 0x00003225, + 0x0000187A, 0x000500C7, 0x00000017, 0x0000499A, 0x00005AD4, 0x00000438, 0x000600A9, 0x00000017, + 0x00002A9E, 0x000040C9, 0x0000499A, 0x00003225, 0x00050080, 0x00000017, 0x00005FF9, 0x0000286F, + 0x00000B6A, 0x000500C4, 0x00000017, 0x00004F7F, 0x00005FF9, 0x00000467, 0x000500C4, 0x00000017, + 0x00003FA6, 0x00002A9E, 0x0000002F, 0x000500C5, 0x00000017, 0x0000577C, 0x00004F7F, 0x00003FA6, + 0x000500AA, 0x00000013, 0x0000319F, 0x00001B58, 0x00000B50, 0x000600A9, 0x00000017, 0x00006055, + 0x0000319F, 0x00000B50, 0x0000577C, 0x00060041, 0x00000294, 0x00002242, 0x0000140E, 0x00000A0B, + 0x000054B5, 0x0003003E, 0x00002242, 0x00006055, 0x00050080, 0x0000000B, 0x000054B6, 0x000054B5, + 0x00000A0E, 0x000300F7, 0x00001AD7, 0x00000002, 0x000400FA, 0x00004376, 0x000055E9, 0x00001C25, + 0x000200F8, 0x000055E9, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001C25, 0x000200F9, 0x00001AD7, + 0x000200F8, 0x00001AD7, 0x000700F5, 0x0000000B, 0x0000456F, 0x00000A6A, 0x000055E9, 0x00000A3A, + 0x00001C25, 0x000500C2, 0x0000000B, 0x000041C0, 0x0000456F, 0x00000A16, 0x00050080, 0x0000000B, + 0x00002ADB, 0x00005665, 0x000041C0, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, + 0x00002ADB, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x00003A1A, 0x00000000, + 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, + 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, + 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, + 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x00001AD7, + 0x00003FF9, 0x00002958, 0x000300F7, 0x0000362C, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, + 0x0000362C, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, + 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, + 0x00005E18, 0x00003BE8, 0x000200F9, 0x0000362C, 0x000200F8, 0x0000362C, 0x000700F5, 0x00000017, + 0x00004AB5, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x000500C2, 0x00000017, 0x00001B59, + 0x00004AB5, 0x0000013D, 0x000500C7, 0x00000017, 0x00003226, 0x00001B59, 0x00000438, 0x000500C2, + 0x00000017, 0x0000586D, 0x00001B59, 0x000003C5, 0x000500AA, 0x00000013, 0x000040CA, 0x0000586D, + 0x00000B50, 0x0006000C, 0x0000001A, 0x00002C4C, 0x00000001, 0x0000004B, 0x00003226, 0x0004007C, + 0x00000017, 0x00002A16, 0x00002C4C, 0x00050082, 0x00000017, 0x0000187B, 0x000003C5, 0x00002A16, + 0x00050080, 0x00000017, 0x00002211, 0x00002A16, 0x0000074E, 0x000600A9, 0x00000017, 0x00002870, + 0x000040CA, 0x00002211, 0x0000586D, 0x000500C4, 0x00000017, 0x00005AD5, 0x00003226, 0x0000187B, + 0x000500C7, 0x00000017, 0x0000499B, 0x00005AD5, 0x00000438, 0x000600A9, 0x00000017, 0x00002A9F, + 0x000040CA, 0x0000499B, 0x00003226, 0x00050080, 0x00000017, 0x00005FFA, 0x00002870, 0x00000B6A, + 0x000500C4, 0x00000017, 0x00004F80, 0x00005FFA, 0x00000467, 0x000500C4, 0x00000017, 0x00003FA7, + 0x00002A9F, 0x0000002F, 0x000500C5, 0x00000017, 0x0000577D, 0x00004F80, 0x00003FA7, 0x000500AA, + 0x00000013, 0x000031A0, 0x00001B59, 0x00000B50, 0x000600A9, 0x00000017, 0x00006056, 0x000031A0, + 0x00000B50, 0x0000577D, 0x00060041, 0x00000294, 0x00002B3D, 0x0000140E, 0x00000A0B, 0x000054B6, + 0x0003003E, 0x00002B3D, 0x00006056, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, + 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_depth_float_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_depth_float_scaled_cs.h new file mode 100644 index 0000000..cd95ade --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_depth_float_scaled_cs.h @@ -0,0 +1,670 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %v4int = OpTypeVector %int 4 +%uint_1048575 = OpConstant %uint 1048575 + %uint_20 = OpConstant %uint 20 + %v4bool = OpTypeVector %bool 4 + %uint_0 = OpConstant %uint 0 + %uint_1 = OpConstant %uint 1 + %uint_112 = OpConstant %uint 112 + %uint_23 = OpConstant %uint 23 + %uint_3 = OpConstant %uint 3 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_16 = OpConstant %uint 16 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2603 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %1080 = OpConstantComposite %v4uint %uint_1048575 %uint_1048575 %uint_1048575 %uint_1048575 + %965 = OpConstantComposite %v4uint %uint_20 %uint_20 %uint_20 %uint_20 + %2896 = OpConstantComposite %v4uint %uint_0 %uint_0 %uint_0 %uint_0 + %2922 = OpConstantComposite %v4uint %uint_112 %uint_112 %uint_112 %uint_112 + %1127 = OpConstantComposite %v4uint %uint_23 %uint_23 %uint_23 %uint_23 + %47 = OpConstantComposite %v4uint %uint_3 %uint_3 %uint_3 %uint_3 +%uint_4294967277 = OpConstant %uint 4294967277 + %1870 = OpConstantComposite %v4uint %uint_4294967277 %uint_4294967277 %uint_4294967277 %uint_4294967277 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2603 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_4 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_2 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_2 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_2 + %23219 = OpBitwiseAnd %uint %10722 %uint_3 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_2 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %7338 = OpLoad %v4uint %20399 + %13760 = OpIEqual %bool %24990 %uint_1 + %21366 = OpIEqual %bool %24990 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %21313 %16376 %10583 + %19638 = OpIEqual %bool %24990 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %13867 None + OpBranchConditional %15139 %11064 %13867 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %13867 + %13867 = OpLabel + %19124 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %7000 = OpShiftRightLogical %v4uint %19124 %317 + %12837 = OpBitwiseAnd %v4uint %7000 %1080 + %22636 = OpShiftRightLogical %v4uint %7000 %965 + %16585 = OpIEqual %v4bool %22636 %2896 + %11339 = OpExtInst %v4int %1 FindUMsb %12837 + %10773 = OpBitcast %v4uint %11339 + %6266 = OpISub %v4uint %965 %10773 + %8720 = OpIAdd %v4uint %10773 %1870 + %10351 = OpSelect %v4uint %16585 %8720 %22636 + %23252 = OpShiftLeftLogical %v4uint %12837 %6266 + %18842 = OpBitwiseAnd %v4uint %23252 %1080 + %10910 = OpSelect %v4uint %16585 %18842 %12837 + %24569 = OpIAdd %v4uint %10351 %2922 + %20351 = OpShiftLeftLogical %v4uint %24569 %1127 + %16294 = OpShiftLeftLogical %v4uint %10910 %47 + %22396 = OpBitwiseOr %v4uint %20351 %16294 + %12703 = OpIEqual %v4bool %7000 %2896 + %24661 = OpSelect %v4uint %12703 %2896 %22396 + %8770 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %8770 %24661 + %15532 = OpIAdd %uint %11197 %int_1 + %6417 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %6417 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_32 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_32 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %24764 %16377 %10584 + OpSelectionMerge %13868 None + OpBranchConditional %15139 %11065 %13868 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %13868 + %13868 = OpLabel + %19125 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %7001 = OpShiftRightLogical %v4uint %19125 %317 + %12838 = OpBitwiseAnd %v4uint %7001 %1080 + %22637 = OpShiftRightLogical %v4uint %7001 %965 + %16586 = OpIEqual %v4bool %22637 %2896 + %11340 = OpExtInst %v4int %1 FindUMsb %12838 + %10774 = OpBitcast %v4uint %11340 + %6267 = OpISub %v4uint %965 %10774 + %8721 = OpIAdd %v4uint %10774 %1870 + %10352 = OpSelect %v4uint %16586 %8721 %22637 + %23253 = OpShiftLeftLogical %v4uint %12838 %6267 + %18843 = OpBitwiseAnd %v4uint %23253 %1080 + %10911 = OpSelect %v4uint %16586 %18843 %12838 + %24570 = OpIAdd %v4uint %10352 %2922 + %20352 = OpShiftLeftLogical %v4uint %24570 %1127 + %16295 = OpShiftLeftLogical %v4uint %10911 %47 + %22397 = OpBitwiseOr %v4uint %20352 %16295 + %12704 = OpIEqual %v4bool %7001 %2896 + %24662 = OpSelect %v4uint %12704 %2896 %22397 + %11069 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15532 + OpStore %11069 %24662 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_depth_float_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x00040017, 0x0000001A, 0x0000000C, 0x00000004, 0x0004002B, 0x0000000B, 0x00000708, 0x000FFFFF, + 0x0004002B, 0x0000000B, 0x00000A46, 0x00000014, 0x00040017, 0x00000013, 0x00000009, 0x00000004, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0004002B, 0x0000000B, 0x00000B5A, 0x00000070, 0x0004002B, 0x0000000B, 0x00000A4F, 0x00000017, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, + 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, + 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, + 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, + 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, + 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, + 0x00000787, 0x00000A16, 0x00000A1F, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, + 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, + 0x00000014, 0x00000A2B, 0x00000A13, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, + 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, + 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, + 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, + 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, + 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, + 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, + 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, + 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, + 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, + 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0007002C, 0x00000017, 0x00000438, 0x00000708, + 0x00000708, 0x00000708, 0x00000708, 0x0007002C, 0x00000017, 0x000003C5, 0x00000A46, 0x00000A46, + 0x00000A46, 0x00000A46, 0x0007002C, 0x00000017, 0x00000B50, 0x00000A0A, 0x00000A0A, 0x00000A0A, + 0x00000A0A, 0x0007002C, 0x00000017, 0x00000B6A, 0x00000B5A, 0x00000B5A, 0x00000B5A, 0x00000B5A, + 0x0007002C, 0x00000017, 0x00000467, 0x00000A4F, 0x00000A4F, 0x00000A4F, 0x00000A4F, 0x0007002C, + 0x00000017, 0x0000002F, 0x00000A13, 0x00000A13, 0x00000A13, 0x00000A13, 0x0004002B, 0x0000000B, + 0x000009D1, 0xFFFFFFED, 0x0007002C, 0x00000017, 0x0000074E, 0x000009D1, 0x000009D1, 0x000009D1, + 0x000009D1, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, + 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, + 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, + 0x000060D7, 0x000500C7, 0x0000000B, 0x00005F7D, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, + 0x000048EB, 0x00005F7D, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001FCD, 0x00003526, 0x00000A10, + 0x000500C7, 0x0000000B, 0x0000619E, 0x00001FCD, 0x00000A13, 0x00050050, 0x00000011, 0x000022A7, + 0x00003526, 0x00003526, 0x000500C2, 0x00000011, 0x00001BAF, 0x000022A7, 0x00000787, 0x000500C7, + 0x00000011, 0x00001997, 0x00001BAF, 0x000007A2, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, + 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, + 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, + 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, + 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, + 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, + 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, + 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, + 0x0000538B, 0x00002A0E, 0x00000A2B, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, + 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, + 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, + 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, + 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, + 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, + 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, + 0x00005BEB, 0x00000A17, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, + 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, + 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, + 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, + 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, + 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00001B12, 0x00002A92, + 0x0000578B, 0x000500C2, 0x0000000B, 0x00002BBD, 0x00001B12, 0x00000A16, 0x00050051, 0x0000000B, + 0x000029E2, 0x0000538B, 0x00000000, 0x000500C2, 0x0000000B, 0x00001DEE, 0x000029E2, 0x00000A10, + 0x00050051, 0x0000000B, 0x00002704, 0x0000538B, 0x00000001, 0x00050050, 0x00000011, 0x00005C0B, + 0x00001DEE, 0x00002704, 0x00050086, 0x00000011, 0x00001F69, 0x00005C0B, 0x00001997, 0x00050051, + 0x0000000B, 0x0000366C, 0x00001F69, 0x00000000, 0x000500C4, 0x0000000B, 0x00004D4D, 0x0000366C, + 0x00000A10, 0x00050051, 0x0000000B, 0x000051A9, 0x00001F69, 0x00000001, 0x00050051, 0x0000000B, + 0x000059EE, 0x0000538B, 0x00000002, 0x00060050, 0x00000014, 0x000024C9, 0x00004D4D, 0x000051A9, + 0x000059EE, 0x000300F7, 0x00005341, 0x00000002, 0x000400FA, 0x000048EB, 0x0000537D, 0x00002DD9, + 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, 0x00002970, 0x000024C9, 0x00050051, 0x0000000C, + 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A17, + 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405C, + 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005789, 0x00000A16, 0x0004007C, + 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005321, 0x0000405C, 0x000018AA, + 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, + 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, + 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, 0x00002970, 0x00000000, + 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, + 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A22, 0x000500C7, + 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, + 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, + 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, + 0x0000434B, 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, + 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, + 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, + 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, + 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, + 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, + 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, + 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, + 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, + 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, 0x00050080, + 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000042C2, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, + 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, + 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, + 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, + 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, + 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, + 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00005559, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, + 0x00005559, 0x0004007C, 0x0000000B, 0x0000566F, 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, + 0x00002DD9, 0x0007004F, 0x00000011, 0x00002621, 0x000024C9, 0x000024C9, 0x00000000, 0x00000001, + 0x0004007C, 0x00000012, 0x000059CF, 0x00002621, 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, + 0x00000000, 0x000500C3, 0x0000000C, 0x000024FE, 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, + 0x00002748, 0x000059CF, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, + 0x000500C2, 0x0000000B, 0x00005B4E, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, + 0x00005B4E, 0x00050084, 0x0000000C, 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, + 0x00003F5E, 0x000024FE, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A25, + 0x000500C7, 0x0000000C, 0x00002AB6, 0x00001903, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, + 0x00002748, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, + 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, + 0x00000A10, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, + 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, + 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, + 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, + 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, + 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, + 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, + 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, + 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, + 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, + 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x00001903, 0x00000A14, + 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, + 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, + 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x00002E06, 0x00004159, + 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4D, 0x00002E06, 0x0004007C, 0x0000000B, + 0x00005670, 0x0000394F, 0x000200F9, 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, + 0x000024FC, 0x0000566F, 0x0000537D, 0x00005670, 0x00002DD9, 0x00050084, 0x00000011, 0x00003FA8, + 0x00001F69, 0x00001997, 0x00050082, 0x00000011, 0x00003BBC, 0x00005C0B, 0x00003FA8, 0x00050051, + 0x0000000B, 0x00001C87, 0x00001997, 0x00000000, 0x00050051, 0x0000000B, 0x00005962, 0x00001997, + 0x00000001, 0x00050084, 0x0000000B, 0x00003372, 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, + 0x00003CA0, 0x000024FC, 0x00003372, 0x00050051, 0x0000000B, 0x00003ED4, 0x00003BBC, 0x00000000, + 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, 0x00005962, 0x00050051, 0x0000000B, 0x00001AE6, + 0x00003BBC, 0x00000001, 0x00050080, 0x0000000B, 0x00002B25, 0x00003E12, 0x00001AE6, 0x000500C4, + 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A10, 0x000500C7, 0x0000000B, 0x00005AB3, 0x000029E2, + 0x00000A13, 0x00050080, 0x0000000B, 0x00002557, 0x0000609D, 0x00005AB3, 0x000500C4, 0x0000000B, + 0x000040AD, 0x00002557, 0x00000A10, 0x00050080, 0x0000000B, 0x00004EAA, 0x00003CA0, 0x000040AD, + 0x00050080, 0x0000000B, 0x00003BA9, 0x00005EAC, 0x00004EAA, 0x000500C2, 0x0000000B, 0x00003948, + 0x00003BA9, 0x00000A16, 0x00060041, 0x00000294, 0x00004FAF, 0x0000107A, 0x00000A0B, 0x00003948, + 0x0004003D, 0x00000017, 0x00001CAA, 0x00004FAF, 0x000500AA, 0x00000009, 0x000035C0, 0x0000619E, + 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x0000619E, 0x00000A10, 0x000500A6, 0x00000009, + 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, + 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, + 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, + 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, + 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, + 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, 0x00005341, 0x00003FF8, 0x00002957, + 0x000500AA, 0x00000009, 0x00004CB6, 0x0000619E, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, + 0x00005376, 0x00004CB6, 0x000300F7, 0x0000362B, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, + 0x0000362B, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, + 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, + 0x00005E17, 0x00003BE7, 0x000200F9, 0x0000362B, 0x000200F8, 0x0000362B, 0x000700F5, 0x00000017, + 0x00004AB4, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x000500C2, 0x00000017, 0x00001B58, + 0x00004AB4, 0x0000013D, 0x000500C7, 0x00000017, 0x00003225, 0x00001B58, 0x00000438, 0x000500C2, + 0x00000017, 0x0000586C, 0x00001B58, 0x000003C5, 0x000500AA, 0x00000013, 0x000040C9, 0x0000586C, + 0x00000B50, 0x0006000C, 0x0000001A, 0x00002C4B, 0x00000001, 0x0000004B, 0x00003225, 0x0004007C, + 0x00000017, 0x00002A15, 0x00002C4B, 0x00050082, 0x00000017, 0x0000187A, 0x000003C5, 0x00002A15, + 0x00050080, 0x00000017, 0x00002210, 0x00002A15, 0x0000074E, 0x000600A9, 0x00000017, 0x0000286F, + 0x000040C9, 0x00002210, 0x0000586C, 0x000500C4, 0x00000017, 0x00005AD4, 0x00003225, 0x0000187A, + 0x000500C7, 0x00000017, 0x0000499A, 0x00005AD4, 0x00000438, 0x000600A9, 0x00000017, 0x00002A9E, + 0x000040C9, 0x0000499A, 0x00003225, 0x00050080, 0x00000017, 0x00005FF9, 0x0000286F, 0x00000B6A, + 0x000500C4, 0x00000017, 0x00004F7F, 0x00005FF9, 0x00000467, 0x000500C4, 0x00000017, 0x00003FA6, + 0x00002A9E, 0x0000002F, 0x000500C5, 0x00000017, 0x0000577C, 0x00004F7F, 0x00003FA6, 0x000500AA, + 0x00000013, 0x0000319F, 0x00001B58, 0x00000B50, 0x000600A9, 0x00000017, 0x00006055, 0x0000319F, + 0x00000B50, 0x0000577C, 0x00060041, 0x00000294, 0x00002242, 0x0000140E, 0x00000A0B, 0x00002BBD, + 0x0003003E, 0x00002242, 0x00006055, 0x00050080, 0x0000000B, 0x00003CAC, 0x00002BBD, 0x00000A0E, + 0x000500AC, 0x00000009, 0x00001911, 0x00001C87, 0x00000A0D, 0x000300F7, 0x000060BC, 0x00000002, + 0x000400FA, 0x00001911, 0x00005084, 0x00005094, 0x000200F8, 0x00005084, 0x00050086, 0x0000000B, + 0x00003697, 0x00001DEE, 0x00001C87, 0x00050084, 0x0000000B, 0x0000237E, 0x00003697, 0x00001C87, + 0x00050082, 0x0000000B, 0x00003171, 0x00001DEE, 0x0000237E, 0x00050080, 0x0000000B, 0x00002527, + 0x00003171, 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, 0x00001C87, 0x000300F7, + 0x00001EED, 0x00000000, 0x000400FA, 0x0000343F, 0x0000569E, 0x00002191, 0x000200F8, 0x0000569E, + 0x00050084, 0x0000000B, 0x00004B59, 0x00000A6A, 0x00001C87, 0x000500C4, 0x0000000B, 0x0000540F, + 0x00003171, 0x00000A16, 0x00050082, 0x0000000B, 0x00004944, 0x00004B59, 0x0000540F, 0x000200F9, + 0x00001EED, 0x000200F8, 0x00002191, 0x000200F9, 0x00001EED, 0x000200F8, 0x00001EED, 0x000700F5, + 0x0000000B, 0x0000292C, 0x00004944, 0x0000569E, 0x00000A3A, 0x00002191, 0x000200F9, 0x000060BC, + 0x000200F8, 0x00005094, 0x000200F9, 0x000060BC, 0x000200F8, 0x000060BC, 0x000700F5, 0x0000000B, + 0x000029BC, 0x0000292C, 0x00001EED, 0x00000A6A, 0x00005094, 0x00050084, 0x0000000B, 0x0000492B, + 0x000029BC, 0x00005962, 0x000500C2, 0x0000000B, 0x0000406D, 0x0000492B, 0x00000A16, 0x00050080, + 0x0000000B, 0x0000336B, 0x00003948, 0x0000406D, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, + 0x00000A0B, 0x0000336B, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x00003A1A, + 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, + 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, + 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, + 0x000060BC, 0x00003FF9, 0x00002958, 0x000300F7, 0x0000362C, 0x00000000, 0x000400FA, 0x00003B23, + 0x00002B39, 0x0000362C, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, + 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, + 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x0000362C, 0x000200F8, 0x0000362C, 0x000700F5, + 0x00000017, 0x00004AB5, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x000500C2, 0x00000017, + 0x00001B59, 0x00004AB5, 0x0000013D, 0x000500C7, 0x00000017, 0x00003226, 0x00001B59, 0x00000438, + 0x000500C2, 0x00000017, 0x0000586D, 0x00001B59, 0x000003C5, 0x000500AA, 0x00000013, 0x000040CA, + 0x0000586D, 0x00000B50, 0x0006000C, 0x0000001A, 0x00002C4C, 0x00000001, 0x0000004B, 0x00003226, + 0x0004007C, 0x00000017, 0x00002A16, 0x00002C4C, 0x00050082, 0x00000017, 0x0000187B, 0x000003C5, + 0x00002A16, 0x00050080, 0x00000017, 0x00002211, 0x00002A16, 0x0000074E, 0x000600A9, 0x00000017, + 0x00002870, 0x000040CA, 0x00002211, 0x0000586D, 0x000500C4, 0x00000017, 0x00005AD5, 0x00003226, + 0x0000187B, 0x000500C7, 0x00000017, 0x0000499B, 0x00005AD5, 0x00000438, 0x000600A9, 0x00000017, + 0x00002A9F, 0x000040CA, 0x0000499B, 0x00003226, 0x00050080, 0x00000017, 0x00005FFA, 0x00002870, + 0x00000B6A, 0x000500C4, 0x00000017, 0x00004F80, 0x00005FFA, 0x00000467, 0x000500C4, 0x00000017, + 0x00003FA7, 0x00002A9F, 0x0000002F, 0x000500C5, 0x00000017, 0x0000577D, 0x00004F80, 0x00003FA7, + 0x000500AA, 0x00000013, 0x000031A0, 0x00001B59, 0x00000B50, 0x000600A9, 0x00000017, 0x00006056, + 0x000031A0, 0x00000B50, 0x0000577D, 0x00060041, 0x00000294, 0x00002B3D, 0x0000140E, 0x00000A0B, + 0x00003CAC, 0x0003003E, 0x00002B3D, 0x00006056, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, + 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_depth_unorm_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_depth_unorm_cs.h new file mode 100644 index 0000000..f14806a --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_depth_unorm_cs.h @@ -0,0 +1,551 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25059 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %uint_23 = OpConstant %uint 23 +%float_5_96046448en08 = OpConstant %float 5.96046448e-08 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2603 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %1127 = OpConstantComposite %v4uint %uint_23 %uint_23 %uint_23 %uint_23 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2603 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_4 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %6362 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %22810 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %13867 None + OpBranchConditional %15139 %11064 %13867 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %13867 + %13867 = OpLabel + %19029 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %6611 = OpShiftRightLogical %v4uint %19029 %317 + %6905 = OpShiftRightLogical %v4uint %6611 %1127 + %11375 = OpIAdd %v4uint %6611 %6905 + %21368 = OpConvertUToF %v4float %11375 + %21748 = OpVectorTimesScalar %v4float %21368 %float_5_96046448en08 + %12287 = OpBitcast %v4uint %21748 + %24121 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %24121 %12287 + %21686 = OpIAdd %uint %21685 %int_1 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_32 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %6871 %16377 %10584 + OpSelectionMerge %13868 None + OpBranchConditional %15139 %11065 %13868 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %13868 + %13868 = OpLabel + %19030 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %6612 = OpShiftRightLogical %v4uint %19030 %317 + %6906 = OpShiftRightLogical %v4uint %6612 %1127 + %11376 = OpIAdd %v4uint %6612 %6906 + %21369 = OpConvertUToF %v4float %11376 + %21749 = OpVectorTimesScalar %v4float %21369 %float_5_96046448en08 + %12288 = OpBitcast %v4uint %21749 + %7349 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21686 + OpStore %7349 %12288 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_depth_unorm_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000061E3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, + 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, + 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, + 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x0004002B, + 0x0000000B, 0x00000A4F, 0x00000017, 0x0004002B, 0x0000000D, 0x00000B3A, 0x33800000, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, + 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, + 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, + 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, + 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, + 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, + 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, + 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, + 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, + 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, + 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, + 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, + 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, + 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, + 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, + 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, + 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A2B, + 0x00000A13, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0003001D, + 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, + 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, + 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, + 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, + 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0004002B, 0x0000000B, 0x00000A25, + 0x00000009, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, + 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, + 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, + 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0007002C, 0x00000017, 0x00000467, + 0x00000A4F, 0x00000A4F, 0x00000A4F, 0x00000A4F, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, + 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, + 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, + 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, + 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, + 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, + 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, + 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, + 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, + 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, + 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, + 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, + 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, + 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, + 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, + 0x00000A2B, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, + 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, + 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, + 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, + 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, + 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, + 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A17, + 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, + 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, + 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, + 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, + 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, + 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, + 0x0000000B, 0x000054B5, 0x00002764, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, + 0x00004376, 0x00005768, 0x000051F2, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, + 0x000400FA, 0x00004384, 0x00002BF8, 0x000018D9, 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, + 0x000032B3, 0x000044BE, 0x00000A17, 0x000500C3, 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, + 0x000500C2, 0x0000000B, 0x00004947, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, + 0x00004947, 0x00050084, 0x0000000C, 0x00005321, 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, + 0x00003B27, 0x000032B3, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, + 0x0004007C, 0x0000000C, 0x00003901, 0x00002348, 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, + 0x00003901, 0x000500C3, 0x0000000C, 0x000032BA, 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, + 0x00005FEE, 0x000032BA, 0x000020F4, 0x000500C4, 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A22, + 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, + 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, + 0x0000000C, 0x00003138, 0x000044BE, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, + 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, + 0x00001B88, 0x0000434B, 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, + 0x000500C3, 0x0000000C, 0x00002215, 0x000044BE, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, + 0x00002215, 0x0000601E, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, + 0x0000000C, 0x00004112, 0x00005BEB, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, + 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, + 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, + 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, + 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, + 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, + 0x000047B4, 0x000018DA, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, + 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, + 0x000044BE, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, + 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, + 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, + 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, + 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, + 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, + 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, + 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, + 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, + 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, + 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, + 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, + 0x00005B4D, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, + 0x0000000C, 0x00005347, 0x0000405C, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, + 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, + 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, + 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, + 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, + 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, + 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, + 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, + 0x000500C7, 0x0000000C, 0x000047B5, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, + 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, + 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, + 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, + 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, + 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, + 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, + 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, + 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, + 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, + 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, + 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, + 0x00005F43, 0x000200F8, 0x000051F2, 0x0004007C, 0x0000000C, 0x00003CBC, 0x00005789, 0x00050084, + 0x0000000C, 0x000060B8, 0x000018DA, 0x00003CBC, 0x00050080, 0x0000000C, 0x0000208E, 0x000060B8, + 0x000044BE, 0x0004007C, 0x0000000C, 0x000022F8, 0x00005788, 0x00050084, 0x0000000C, 0x00001E9F, + 0x0000208E, 0x000022F8, 0x00050080, 0x0000000C, 0x00001F30, 0x0000591A, 0x00001E9F, 0x000200F9, + 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, + 0x00001F30, 0x000051F2, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, + 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, + 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, 0x00004315, 0x0000107A, + 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004315, 0x000500AA, 0x00000009, + 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x000061E2, 0x00000A10, + 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, 0x00000000, + 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, + 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, + 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, + 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, 0x00005F43, + 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000061E2, 0x00000A13, 0x000500A6, + 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x0000362B, 0x00000000, 0x000400FA, + 0x00003B23, 0x00002B38, 0x0000362B, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, + 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, + 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x0000362B, 0x000200F8, 0x0000362B, + 0x000700F5, 0x00000017, 0x00004A55, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x000500C2, + 0x00000017, 0x000019D3, 0x00004A55, 0x0000013D, 0x000500C2, 0x00000017, 0x00001AF9, 0x000019D3, + 0x00000467, 0x00050080, 0x00000017, 0x00002C6F, 0x000019D3, 0x00001AF9, 0x00040070, 0x0000001D, + 0x00005378, 0x00002C6F, 0x0005008E, 0x0000001D, 0x000054F4, 0x00005378, 0x00000B3A, 0x0004007C, + 0x00000017, 0x00002FFF, 0x000054F4, 0x00060041, 0x00000294, 0x00005E39, 0x0000140E, 0x00000A0B, + 0x000054B5, 0x0003003E, 0x00005E39, 0x00002FFF, 0x00050080, 0x0000000B, 0x000054B6, 0x000054B5, + 0x00000A0E, 0x000300F7, 0x00001AD7, 0x00000002, 0x000400FA, 0x00004376, 0x000055E9, 0x00001C25, + 0x000200F8, 0x000055E9, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001C25, 0x000200F9, 0x00001AD7, + 0x000200F8, 0x00001AD7, 0x000700F5, 0x0000000B, 0x0000456F, 0x00000A6A, 0x000055E9, 0x00000A3A, + 0x00001C25, 0x000500C2, 0x0000000B, 0x000041C0, 0x0000456F, 0x00000A16, 0x00050080, 0x0000000B, + 0x00002ADB, 0x00005665, 0x000041C0, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, + 0x00002ADB, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x00003A1A, 0x00000000, + 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, + 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, + 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, + 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x00001AD7, + 0x00003FF9, 0x00002958, 0x000300F7, 0x0000362C, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, + 0x0000362C, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, + 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, + 0x00005E18, 0x00003BE8, 0x000200F9, 0x0000362C, 0x000200F8, 0x0000362C, 0x000700F5, 0x00000017, + 0x00004A56, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x000500C2, 0x00000017, 0x000019D4, + 0x00004A56, 0x0000013D, 0x000500C2, 0x00000017, 0x00001AFA, 0x000019D4, 0x00000467, 0x00050080, + 0x00000017, 0x00002C70, 0x000019D4, 0x00001AFA, 0x00040070, 0x0000001D, 0x00005379, 0x00002C70, + 0x0005008E, 0x0000001D, 0x000054F5, 0x00005379, 0x00000B3A, 0x0004007C, 0x00000017, 0x00003000, + 0x000054F5, 0x00060041, 0x00000294, 0x00001CB5, 0x0000140E, 0x00000A0B, 0x000054B6, 0x0003003E, + 0x00001CB5, 0x00003000, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_depth_unorm_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_depth_unorm_scaled_cs.h new file mode 100644 index 0000000..7fe0207 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_depth_unorm_scaled_cs.h @@ -0,0 +1,614 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_23 = OpConstant %uint 23 +%float_5_96046448en08 = OpConstant %float 5.96046448e-08 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2603 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %1127 = OpConstantComposite %v4uint %uint_23 %uint_23 %uint_23 %uint_23 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2603 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_4 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_2 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_2 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_2 + %23219 = OpBitwiseAnd %uint %10722 %uint_3 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_2 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %7338 = OpLoad %v4uint %20399 + %13760 = OpIEqual %bool %24990 %uint_1 + %21366 = OpIEqual %bool %24990 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %21313 %16376 %10583 + %19638 = OpIEqual %bool %24990 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %13867 None + OpBranchConditional %15139 %11064 %13867 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %13867 + %13867 = OpLabel + %19029 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %6611 = OpShiftRightLogical %v4uint %19029 %317 + %6905 = OpShiftRightLogical %v4uint %6611 %1127 + %11375 = OpIAdd %v4uint %6611 %6905 + %21368 = OpConvertUToF %v4float %11375 + %21748 = OpVectorTimesScalar %v4float %21368 %float_5_96046448en08 + %12287 = OpBitcast %v4uint %21748 + %24121 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %24121 %12287 + %15532 = OpIAdd %uint %11197 %int_1 + %6417 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %6417 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_32 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_32 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %24764 %16377 %10584 + OpSelectionMerge %13868 None + OpBranchConditional %15139 %11065 %13868 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %13868 + %13868 = OpLabel + %19030 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %6612 = OpShiftRightLogical %v4uint %19030 %317 + %6906 = OpShiftRightLogical %v4uint %6612 %1127 + %11376 = OpIAdd %v4uint %6612 %6906 + %21369 = OpConvertUToF %v4float %11376 + %21749 = OpVectorTimesScalar %v4float %21369 %float_5_96046448en08 + %12288 = OpBitcast %v4uint %21749 + %7349 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15532 + OpStore %7349 %12288 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_depth_unorm_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00030016, 0x0000000D, + 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, + 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, + 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x0004002B, + 0x0000000B, 0x00000A4F, 0x00000017, 0x0004002B, 0x0000000D, 0x00000B3A, 0x33800000, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, + 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, + 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, + 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, + 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, + 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, + 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, + 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, + 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, + 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, + 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, + 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, + 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, + 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, + 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, + 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, 0x00000787, + 0x00000A16, 0x00000A1F, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, + 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, + 0x00000A2B, 0x00000A13, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, + 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, + 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, 0x00000011, + 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0007002C, + 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, + 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, + 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0007002C, 0x00000017, 0x00000467, 0x00000A4F, 0x00000A4F, + 0x00000A4F, 0x00000A4F, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, + 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, + 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, + 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005F7D, 0x00003526, 0x00000A10, 0x000500AB, + 0x00000009, 0x000048EB, 0x00005F7D, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001FCD, 0x00003526, + 0x00000A10, 0x000500C7, 0x0000000B, 0x0000619E, 0x00001FCD, 0x00000A13, 0x00050050, 0x00000011, + 0x000022A7, 0x00003526, 0x00003526, 0x000500C2, 0x00000011, 0x00001BAF, 0x000022A7, 0x00000787, + 0x000500C7, 0x00000011, 0x00001997, 0x00001BAF, 0x000007A2, 0x00050041, 0x00000288, 0x0000492C, + 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, + 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, + 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, + 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, + 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, + 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, + 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, + 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A2B, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, + 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, + 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, + 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, + 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, + 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, + 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, + 0x0000591A, 0x00005BEB, 0x00000A17, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, + 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, + 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, + 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, + 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, + 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00001B12, + 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x00002BBD, 0x00001B12, 0x00000A16, 0x00050051, + 0x0000000B, 0x000029E2, 0x0000538B, 0x00000000, 0x000500C2, 0x0000000B, 0x00001DEE, 0x000029E2, + 0x00000A10, 0x00050051, 0x0000000B, 0x00002704, 0x0000538B, 0x00000001, 0x00050050, 0x00000011, + 0x00005C0B, 0x00001DEE, 0x00002704, 0x00050086, 0x00000011, 0x00001F69, 0x00005C0B, 0x00001997, + 0x00050051, 0x0000000B, 0x0000366C, 0x00001F69, 0x00000000, 0x000500C4, 0x0000000B, 0x00004D4D, + 0x0000366C, 0x00000A10, 0x00050051, 0x0000000B, 0x000051A9, 0x00001F69, 0x00000001, 0x00050051, + 0x0000000B, 0x000059EE, 0x0000538B, 0x00000002, 0x00060050, 0x00000014, 0x000024C9, 0x00004D4D, + 0x000051A9, 0x000059EE, 0x000300F7, 0x00005341, 0x00000002, 0x000400FA, 0x000048EB, 0x0000537D, + 0x00002DD9, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, 0x00002970, 0x000024C9, 0x00050051, + 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, + 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000002, 0x000500C3, 0x0000000C, + 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005789, 0x00000A16, + 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005321, 0x0000405C, + 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, 0x00005321, 0x000500C2, 0x0000000B, + 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, + 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, 0x00002970, + 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, + 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A22, + 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, + 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, + 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, + 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, + 0x00001B88, 0x0000434B, 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, + 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, + 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, + 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, + 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, + 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, + 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, + 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, + 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, + 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, + 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, + 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, + 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, + 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, + 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, + 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, + 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, + 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, + 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005559, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, + 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, 0x0000566F, 0x00005EFA, 0x000200F9, 0x00005341, + 0x000200F8, 0x00002DD9, 0x0007004F, 0x00000011, 0x00002621, 0x000024C9, 0x000024C9, 0x00000000, + 0x00000001, 0x0004007C, 0x00000012, 0x000059CF, 0x00002621, 0x00050051, 0x0000000C, 0x00001903, + 0x000059CF, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FE, 0x00001903, 0x00000A1A, 0x00050051, + 0x0000000C, 0x00002748, 0x000059CF, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, + 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, + 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, + 0x0000000C, 0x00003F5E, 0x000024FE, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, + 0x00000A25, 0x000500C7, 0x0000000C, 0x00002AB6, 0x00001903, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003139, 0x00002748, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, + 0x00004397, 0x00000A10, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, + 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, + 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, + 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, + 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, + 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, + 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, + 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, + 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, + 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, + 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x00001903, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, + 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, + 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x00002E06, + 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4D, 0x00002E06, 0x0004007C, + 0x0000000B, 0x00005670, 0x0000394F, 0x000200F9, 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, + 0x0000000B, 0x000024FC, 0x0000566F, 0x0000537D, 0x00005670, 0x00002DD9, 0x00050084, 0x00000011, + 0x00003FA8, 0x00001F69, 0x00001997, 0x00050082, 0x00000011, 0x00003BBC, 0x00005C0B, 0x00003FA8, + 0x00050051, 0x0000000B, 0x00001C87, 0x00001997, 0x00000000, 0x00050051, 0x0000000B, 0x00005962, + 0x00001997, 0x00000001, 0x00050084, 0x0000000B, 0x00003372, 0x00001C87, 0x00005962, 0x00050084, + 0x0000000B, 0x00003CA0, 0x000024FC, 0x00003372, 0x00050051, 0x0000000B, 0x00003ED4, 0x00003BBC, + 0x00000000, 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, 0x00005962, 0x00050051, 0x0000000B, + 0x00001AE6, 0x00003BBC, 0x00000001, 0x00050080, 0x0000000B, 0x00002B25, 0x00003E12, 0x00001AE6, + 0x000500C4, 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A10, 0x000500C7, 0x0000000B, 0x00005AB3, + 0x000029E2, 0x00000A13, 0x00050080, 0x0000000B, 0x00002557, 0x0000609D, 0x00005AB3, 0x000500C4, + 0x0000000B, 0x000040AD, 0x00002557, 0x00000A10, 0x00050080, 0x0000000B, 0x00004EAA, 0x00003CA0, + 0x000040AD, 0x00050080, 0x0000000B, 0x00003BA9, 0x00005EAC, 0x00004EAA, 0x000500C2, 0x0000000B, + 0x00003948, 0x00003BA9, 0x00000A16, 0x00060041, 0x00000294, 0x00004FAF, 0x0000107A, 0x00000A0B, + 0x00003948, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004FAF, 0x000500AA, 0x00000009, 0x000035C0, + 0x0000619E, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x0000619E, 0x00000A10, 0x000500A6, + 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, + 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, + 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, + 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, + 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, + 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, 0x00005341, 0x00003FF8, + 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x0000619E, 0x00000A13, 0x000500A6, 0x00000009, + 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x0000362B, 0x00000000, 0x000400FA, 0x00003B23, + 0x00002B38, 0x0000362B, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, + 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, + 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x0000362B, 0x000200F8, 0x0000362B, 0x000700F5, + 0x00000017, 0x00004A55, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x000500C2, 0x00000017, + 0x000019D3, 0x00004A55, 0x0000013D, 0x000500C2, 0x00000017, 0x00001AF9, 0x000019D3, 0x00000467, + 0x00050080, 0x00000017, 0x00002C6F, 0x000019D3, 0x00001AF9, 0x00040070, 0x0000001D, 0x00005378, + 0x00002C6F, 0x0005008E, 0x0000001D, 0x000054F4, 0x00005378, 0x00000B3A, 0x0004007C, 0x00000017, + 0x00002FFF, 0x000054F4, 0x00060041, 0x00000294, 0x00005E39, 0x0000140E, 0x00000A0B, 0x00002BBD, + 0x0003003E, 0x00005E39, 0x00002FFF, 0x00050080, 0x0000000B, 0x00003CAC, 0x00002BBD, 0x00000A0E, + 0x000500AC, 0x00000009, 0x00001911, 0x00001C87, 0x00000A0D, 0x000300F7, 0x000060BC, 0x00000002, + 0x000400FA, 0x00001911, 0x00005084, 0x00005094, 0x000200F8, 0x00005084, 0x00050086, 0x0000000B, + 0x00003697, 0x00001DEE, 0x00001C87, 0x00050084, 0x0000000B, 0x0000237E, 0x00003697, 0x00001C87, + 0x00050082, 0x0000000B, 0x00003171, 0x00001DEE, 0x0000237E, 0x00050080, 0x0000000B, 0x00002527, + 0x00003171, 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, 0x00001C87, 0x000300F7, + 0x00001EED, 0x00000000, 0x000400FA, 0x0000343F, 0x0000569E, 0x00002191, 0x000200F8, 0x0000569E, + 0x00050084, 0x0000000B, 0x00004B59, 0x00000A6A, 0x00001C87, 0x000500C4, 0x0000000B, 0x0000540F, + 0x00003171, 0x00000A16, 0x00050082, 0x0000000B, 0x00004944, 0x00004B59, 0x0000540F, 0x000200F9, + 0x00001EED, 0x000200F8, 0x00002191, 0x000200F9, 0x00001EED, 0x000200F8, 0x00001EED, 0x000700F5, + 0x0000000B, 0x0000292C, 0x00004944, 0x0000569E, 0x00000A3A, 0x00002191, 0x000200F9, 0x000060BC, + 0x000200F8, 0x00005094, 0x000200F9, 0x000060BC, 0x000200F8, 0x000060BC, 0x000700F5, 0x0000000B, + 0x000029BC, 0x0000292C, 0x00001EED, 0x00000A6A, 0x00005094, 0x00050084, 0x0000000B, 0x0000492B, + 0x000029BC, 0x00005962, 0x000500C2, 0x0000000B, 0x0000406D, 0x0000492B, 0x00000A16, 0x00050080, + 0x0000000B, 0x0000336B, 0x00003948, 0x0000406D, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, + 0x00000A0B, 0x0000336B, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x00003A1A, + 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, + 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, + 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, + 0x000060BC, 0x00003FF9, 0x00002958, 0x000300F7, 0x0000362C, 0x00000000, 0x000400FA, 0x00003B23, + 0x00002B39, 0x0000362C, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, + 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, + 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x0000362C, 0x000200F8, 0x0000362C, 0x000700F5, + 0x00000017, 0x00004A56, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x000500C2, 0x00000017, + 0x000019D4, 0x00004A56, 0x0000013D, 0x000500C2, 0x00000017, 0x00001AFA, 0x000019D4, 0x00000467, + 0x00050080, 0x00000017, 0x00002C70, 0x000019D4, 0x00001AFA, 0x00040070, 0x0000001D, 0x00005379, + 0x00002C70, 0x0005008E, 0x0000001D, 0x000054F5, 0x00005379, 0x00000B3A, 0x0004007C, 0x00000017, + 0x00003000, 0x000054F5, 0x00060041, 0x00000294, 0x00001CB5, 0x0000140E, 0x00000A0B, 0x00003CAC, + 0x0003003E, 0x00001CB5, 0x00003000, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, + 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_dxn_rg8_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_dxn_rg8_cs.h new file mode 100644 index 0000000..7884857 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_dxn_rg8_cs.h @@ -0,0 +1,4116 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25290 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 +%uint_2396745 = OpConstant %uint 2396745 +%uint_4793490 = OpConstant %uint 4793490 + %uint_1 = OpConstant %uint 1 +%uint_9586980 = OpConstant %uint 9586980 + %uint_2 = OpConstant %uint 2 +%uint_14380470 = OpConstant %uint 14380470 + %uint_0 = OpConstant %uint 0 + %uint_7 = OpConstant %uint 7 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_6 = OpConstant %uint 6 + %uint_9 = OpConstant %uint 9 + %uint_1170 = OpConstant %uint 1170 + %uint_2340 = OpConstant %uint 2340 + %uint_2925 = OpConstant %uint 2925 + %uint_5 = OpConstant %uint 5 + %uint_8 = OpConstant %uint 8 + %uint_13 = OpConstant %uint 13 + %uint_512 = OpConstant %uint 512 + %uint_255 = OpConstant %uint 255 +%uint_16711935 = OpConstant %uint 16711935 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2587 = OpConstantComposite %v3uint %uint_1 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 + %2620 = OpConstantComposite %v3uint %uint_2 %uint_2 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint + %125 = OpConstantComposite %v4uint %uint_0 %uint_8 %uint_0 %uint_8 +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform + %uint_12 = OpConstant %uint 12 + %uint_32 = OpConstant %uint 32 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_10 = OpConstant %uint 10 + %uint_11 = OpConstant %uint 11 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %1611 = OpConstantComposite %v4uint %uint_255 %uint_255 %uint_255 %uint_255 + %1140 = OpConstantComposite %v2uint %uint_255 %uint_255 + %1975 = OpConstantComposite %v2uint %uint_8 %uint_8 + %533 = OpConstantComposite %v4uint %uint_12 %uint_12 %uint_12 %uint_12 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %14903 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20158 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %22412 = OpLoad %uint %20158 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_7 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2587 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %14018 DontFlatten + OpBranchConditional %24679 %21992 %14018 + %21992 = OpLabel + OpBranch %14903 + %14018 = OpLabel + %17344 = OpShiftLeftLogical %v3uint %21387 %2620 + %15489 = OpBitcast %v3int %17344 + %18336 = OpCompositeExtract %int %15489 0 + %9362 = OpIMul %int %18336 %int_2 + %6362 = OpCompositeExtract %int %15489 2 + %14505 = OpBitcast %int %6594 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %15489 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %22412 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %9362 %24535 + %10898 = OpBitcast %uint %8258 + %9077 = OpIAdd %uint %10898 %22411 + %11726 = OpShiftRightLogical %uint %9077 %uint_4 + %6977 = OpShiftRightLogical %uint %22412 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20009 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %21373 %6361 + %21373 = OpLabel + %10608 = OpBitcast %v3int %21387 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_10 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_10 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_10 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17091 = OpCompositeExtract %int %6573 0 + %9470 = OpShiftRightArithmetic %int %17091 %int_5 + %10056 = OpCompositeExtract %int %6573 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_11 + %10934 = OpBitwiseAnd %int %17091 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_4 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17091 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %21373 %12098 %6361 + OpBranch %24387 + %20009 = OpLabel + %24447 = OpBitcast %v3int %21387 + %8918 = OpCompositeExtract %int %24447 0 + %9363 = OpIMul %int %8918 %int_16 + %6363 = OpCompositeExtract %int %24447 2 + %14506 = OpBitcast %int %22409 + %11280 = OpIMul %int %6363 %14506 + %17599 = OpCompositeExtract %int %24447 1 + %22229 = OpIAdd %int %11280 %17599 + %22406 = OpBitcast %int %22408 + %7839 = OpIMul %int %22229 %22406 + %7984 = OpIAdd %int %9363 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20009 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %13392 None + OpBranchConditional %15139 %11064 %13392 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %13392 + %13392 = OpLabel + %22100 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %11876 = OpSelect %uint %17270 %uint_2 %uint_1 + %11339 = OpIAdd %uint %22117 %11876 + %18278 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %11339 + %6578 = OpLoad %v4uint %18278 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %13392 %16377 %10584 + OpSelectionMerge %11682 None + OpBranchConditional %15139 %11065 %11682 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11682 + %11682 = OpLabel + %19853 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %22133 = OpVectorShuffle %v4uint %22100 %22100 0 0 2 2 + %12416 = OpShiftRightLogical %v4uint %22133 %125 + %9078 = OpBitwiseAnd %v4uint %12416 %1611 + %17064 = OpVectorShuffle %v4uint %19853 %19853 0 0 2 2 + %7640 = OpShiftRightLogical %v4uint %17064 %125 + %6585 = OpBitwiseAnd %v4uint %7640 %1611 + %17985 = OpCompositeExtract %uint %22100 0 + %6272 = OpCompositeExtract %uint %22100 2 + %7641 = OpCompositeExtract %uint %19853 0 + %9980 = OpCompositeExtract %uint %19853 2 + %15375 = OpCompositeConstruct %v4uint %17985 %6272 %7641 %9980 + %10122 = OpShiftRightLogical %v4uint %15375 %749 + %23844 = OpCompositeExtract %uint %22100 1 + %24539 = OpCompositeExtract %uint %22100 3 + %7642 = OpCompositeExtract %uint %19853 1 + %10075 = OpCompositeExtract %uint %19853 3 + %16695 = OpCompositeConstruct %v4uint %23844 %24539 %7642 %10075 + %8679 = OpBitwiseAnd %v4uint %16695 %1611 + %20043 = OpShiftLeftLogical %v4uint %8679 %749 + %16241 = OpBitwiseOr %v4uint %10122 %20043 + %20096 = OpCompositeExtract %uint %16241 0 + %6502 = OpCompositeExtract %uint %9078 0 + %13104 = OpCompositeExtract %uint %9078 1 + %20099 = OpULessThanEqual %bool %6502 %13104 + OpSelectionMerge %11720 None + OpBranchConditional %20099 %10640 %21920 + %10640 = OpLabel + %17657 = OpBitwiseAnd %uint %20096 %uint_4793490 + %23948 = OpBitwiseAnd %uint %20096 %uint_9586980 + %21844 = OpShiftRightLogical %uint %23948 %uint_1 + %8133 = OpBitwiseAnd %uint %17657 %21844 + %24609 = OpShiftLeftLogical %uint %8133 %uint_1 + %22956 = OpShiftRightLogical %uint %8133 %uint_1 + %18793 = OpBitwiseOr %uint %24609 %22956 + %16049 = OpBitwiseOr %uint %8133 %18793 + %18309 = OpBitwiseAnd %uint %20096 %uint_2396745 + %14685 = OpBitwiseOr %uint %18309 %uint_14380470 + %20403 = OpBitwiseAnd %uint %14685 %16049 + %20539 = OpShiftRightLogical %uint %17657 %uint_1 + %24922 = OpBitwiseOr %uint %18309 %20539 + %21922 = OpShiftRightLogical %uint %23948 %uint_2 + %22674 = OpBitwiseOr %uint %24922 %21922 + %7721 = OpBitwiseXor %uint %22674 %uint_2396745 + %9540 = OpNot %uint %20539 + %14621 = OpBitwiseAnd %uint %18309 %9540 + %8425 = OpNot %uint %21922 + %11407 = OpBitwiseAnd %uint %14621 %8425 + %6799 = OpBitwiseOr %uint %20096 %7721 + %19509 = OpISub %uint %6799 %uint_2396745 + %14871 = OpBitwiseOr %uint %19509 %11407 + %18228 = OpShiftLeftLogical %uint %11407 %uint_2 + %15354 = OpBitwiseOr %uint %14871 %18228 + %12154 = OpNot %uint %16049 + %18512 = OpBitwiseAnd %uint %15354 %12154 + %6252 = OpBitwiseOr %uint %18512 %20403 + OpBranch %11720 + %21920 = OpLabel + %20079 = OpBitwiseAnd %uint %20096 %uint_2396745 + %23910 = OpBitwiseAnd %uint %20096 %uint_4793490 + %22247 = OpShiftRightLogical %uint %23910 %uint_1 + %24000 = OpBitwiseOr %uint %20079 %22247 + %19599 = OpBitwiseAnd %uint %20096 %uint_9586980 + %20615 = OpShiftRightLogical %uint %19599 %uint_2 + %24287 = OpBitwiseOr %uint %24000 %20615 + %7722 = OpBitwiseXor %uint %24287 %uint_2396745 + %9541 = OpNot %uint %22247 + %14622 = OpBitwiseAnd %uint %20079 %9541 + %8426 = OpNot %uint %20615 + %11408 = OpBitwiseAnd %uint %14622 %8426 + %6800 = OpBitwiseOr %uint %20096 %7722 + %19510 = OpISub %uint %6800 %uint_2396745 + %14872 = OpBitwiseOr %uint %19510 %11408 + %18152 = OpShiftLeftLogical %uint %11408 %uint_1 + %16008 = OpBitwiseOr %uint %14872 %18152 + %8118 = OpShiftLeftLogical %uint %11408 %uint_2 + %7808 = OpBitwiseOr %uint %16008 %8118 + OpBranch %11720 + %11720 = OpLabel + %17360 = OpPhi %uint %6252 %10640 %7808 %21920 + %23054 = OpCompositeExtract %uint %16241 1 + %12929 = OpCompositeExtract %uint %9078 2 + %13105 = OpCompositeExtract %uint %9078 3 + %20100 = OpULessThanEqual %bool %12929 %13105 + OpSelectionMerge %11721 None + OpBranchConditional %20100 %10641 %21921 + %10641 = OpLabel + %17658 = OpBitwiseAnd %uint %23054 %uint_4793490 + %23949 = OpBitwiseAnd %uint %23054 %uint_9586980 + %21845 = OpShiftRightLogical %uint %23949 %uint_1 + %8134 = OpBitwiseAnd %uint %17658 %21845 + %24610 = OpShiftLeftLogical %uint %8134 %uint_1 + %22957 = OpShiftRightLogical %uint %8134 %uint_1 + %18795 = OpBitwiseOr %uint %24610 %22957 + %16050 = OpBitwiseOr %uint %8134 %18795 + %18310 = OpBitwiseAnd %uint %23054 %uint_2396745 + %14686 = OpBitwiseOr %uint %18310 %uint_14380470 + %20404 = OpBitwiseAnd %uint %14686 %16050 + %20540 = OpShiftRightLogical %uint %17658 %uint_1 + %24923 = OpBitwiseOr %uint %18310 %20540 + %21923 = OpShiftRightLogical %uint %23949 %uint_2 + %22675 = OpBitwiseOr %uint %24923 %21923 + %7723 = OpBitwiseXor %uint %22675 %uint_2396745 + %9542 = OpNot %uint %20540 + %14623 = OpBitwiseAnd %uint %18310 %9542 + %8427 = OpNot %uint %21923 + %11409 = OpBitwiseAnd %uint %14623 %8427 + %6801 = OpBitwiseOr %uint %23054 %7723 + %19511 = OpISub %uint %6801 %uint_2396745 + %14873 = OpBitwiseOr %uint %19511 %11409 + %18229 = OpShiftLeftLogical %uint %11409 %uint_2 + %15355 = OpBitwiseOr %uint %14873 %18229 + %12155 = OpNot %uint %16050 + %18513 = OpBitwiseAnd %uint %15355 %12155 + %6253 = OpBitwiseOr %uint %18513 %20404 + OpBranch %11721 + %21921 = OpLabel + %20080 = OpBitwiseAnd %uint %23054 %uint_2396745 + %23911 = OpBitwiseAnd %uint %23054 %uint_4793490 + %22248 = OpShiftRightLogical %uint %23911 %uint_1 + %24001 = OpBitwiseOr %uint %20080 %22248 + %19600 = OpBitwiseAnd %uint %23054 %uint_9586980 + %20616 = OpShiftRightLogical %uint %19600 %uint_2 + %24288 = OpBitwiseOr %uint %24001 %20616 + %7724 = OpBitwiseXor %uint %24288 %uint_2396745 + %9543 = OpNot %uint %22248 + %14624 = OpBitwiseAnd %uint %20080 %9543 + %8428 = OpNot %uint %20616 + %11410 = OpBitwiseAnd %uint %14624 %8428 + %6802 = OpBitwiseOr %uint %23054 %7724 + %19512 = OpISub %uint %6802 %uint_2396745 + %14875 = OpBitwiseOr %uint %19512 %11410 + %18153 = OpShiftLeftLogical %uint %11410 %uint_1 + %16009 = OpBitwiseOr %uint %14875 %18153 + %8119 = OpShiftLeftLogical %uint %11410 %uint_2 + %7809 = OpBitwiseOr %uint %16009 %8119 + OpBranch %11721 + %11721 = OpLabel + %17361 = OpPhi %uint %6253 %10641 %7809 %21921 + %23055 = OpCompositeExtract %uint %16241 2 + %12930 = OpCompositeExtract %uint %6585 0 + %13107 = OpCompositeExtract %uint %6585 1 + %20101 = OpULessThanEqual %bool %12930 %13107 + OpSelectionMerge %11722 None + OpBranchConditional %20101 %10642 %21925 + %10642 = OpLabel + %17659 = OpBitwiseAnd %uint %23055 %uint_4793490 + %23950 = OpBitwiseAnd %uint %23055 %uint_9586980 + %21846 = OpShiftRightLogical %uint %23950 %uint_1 + %8135 = OpBitwiseAnd %uint %17659 %21846 + %24611 = OpShiftLeftLogical %uint %8135 %uint_1 + %22958 = OpShiftRightLogical %uint %8135 %uint_1 + %18796 = OpBitwiseOr %uint %24611 %22958 + %16051 = OpBitwiseOr %uint %8135 %18796 + %18311 = OpBitwiseAnd %uint %23055 %uint_2396745 + %14687 = OpBitwiseOr %uint %18311 %uint_14380470 + %20405 = OpBitwiseAnd %uint %14687 %16051 + %20541 = OpShiftRightLogical %uint %17659 %uint_1 + %24924 = OpBitwiseOr %uint %18311 %20541 + %21924 = OpShiftRightLogical %uint %23950 %uint_2 + %22676 = OpBitwiseOr %uint %24924 %21924 + %7725 = OpBitwiseXor %uint %22676 %uint_2396745 + %9544 = OpNot %uint %20541 + %14625 = OpBitwiseAnd %uint %18311 %9544 + %8429 = OpNot %uint %21924 + %11411 = OpBitwiseAnd %uint %14625 %8429 + %6803 = OpBitwiseOr %uint %23055 %7725 + %19513 = OpISub %uint %6803 %uint_2396745 + %14876 = OpBitwiseOr %uint %19513 %11411 + %18230 = OpShiftLeftLogical %uint %11411 %uint_2 + %15356 = OpBitwiseOr %uint %14876 %18230 + %12156 = OpNot %uint %16051 + %18514 = OpBitwiseAnd %uint %15356 %12156 + %6254 = OpBitwiseOr %uint %18514 %20405 + OpBranch %11722 + %21925 = OpLabel + %20081 = OpBitwiseAnd %uint %23055 %uint_2396745 + %23912 = OpBitwiseAnd %uint %23055 %uint_4793490 + %22249 = OpShiftRightLogical %uint %23912 %uint_1 + %24002 = OpBitwiseOr %uint %20081 %22249 + %19601 = OpBitwiseAnd %uint %23055 %uint_9586980 + %20617 = OpShiftRightLogical %uint %19601 %uint_2 + %24289 = OpBitwiseOr %uint %24002 %20617 + %7726 = OpBitwiseXor %uint %24289 %uint_2396745 + %9545 = OpNot %uint %22249 + %14626 = OpBitwiseAnd %uint %20081 %9545 + %8430 = OpNot %uint %20617 + %11412 = OpBitwiseAnd %uint %14626 %8430 + %6804 = OpBitwiseOr %uint %23055 %7726 + %19514 = OpISub %uint %6804 %uint_2396745 + %14877 = OpBitwiseOr %uint %19514 %11412 + %18154 = OpShiftLeftLogical %uint %11412 %uint_1 + %16010 = OpBitwiseOr %uint %14877 %18154 + %8120 = OpShiftLeftLogical %uint %11412 %uint_2 + %7810 = OpBitwiseOr %uint %16010 %8120 + OpBranch %11722 + %11722 = OpLabel + %17362 = OpPhi %uint %6254 %10642 %7810 %21925 + %23056 = OpCompositeExtract %uint %16241 3 + %12931 = OpCompositeExtract %uint %6585 2 + %13108 = OpCompositeExtract %uint %6585 3 + %20102 = OpULessThanEqual %bool %12931 %13108 + OpSelectionMerge %11701 None + OpBranchConditional %20102 %10643 %21927 + %10643 = OpLabel + %17660 = OpBitwiseAnd %uint %23056 %uint_4793490 + %23951 = OpBitwiseAnd %uint %23056 %uint_9586980 + %21847 = OpShiftRightLogical %uint %23951 %uint_1 + %8136 = OpBitwiseAnd %uint %17660 %21847 + %24612 = OpShiftLeftLogical %uint %8136 %uint_1 + %22959 = OpShiftRightLogical %uint %8136 %uint_1 + %18797 = OpBitwiseOr %uint %24612 %22959 + %16052 = OpBitwiseOr %uint %8136 %18797 + %18312 = OpBitwiseAnd %uint %23056 %uint_2396745 + %14688 = OpBitwiseOr %uint %18312 %uint_14380470 + %20406 = OpBitwiseAnd %uint %14688 %16052 + %20542 = OpShiftRightLogical %uint %17660 %uint_1 + %24925 = OpBitwiseOr %uint %18312 %20542 + %21926 = OpShiftRightLogical %uint %23951 %uint_2 + %22677 = OpBitwiseOr %uint %24925 %21926 + %7727 = OpBitwiseXor %uint %22677 %uint_2396745 + %9546 = OpNot %uint %20542 + %14627 = OpBitwiseAnd %uint %18312 %9546 + %8431 = OpNot %uint %21926 + %11413 = OpBitwiseAnd %uint %14627 %8431 + %6805 = OpBitwiseOr %uint %23056 %7727 + %19515 = OpISub %uint %6805 %uint_2396745 + %14878 = OpBitwiseOr %uint %19515 %11413 + %18231 = OpShiftLeftLogical %uint %11413 %uint_2 + %15357 = OpBitwiseOr %uint %14878 %18231 + %12157 = OpNot %uint %16052 + %18515 = OpBitwiseAnd %uint %15357 %12157 + %6255 = OpBitwiseOr %uint %18515 %20406 + OpBranch %11701 + %21927 = OpLabel + %20082 = OpBitwiseAnd %uint %23056 %uint_2396745 + %23913 = OpBitwiseAnd %uint %23056 %uint_4793490 + %22250 = OpShiftRightLogical %uint %23913 %uint_1 + %24003 = OpBitwiseOr %uint %20082 %22250 + %19602 = OpBitwiseAnd %uint %23056 %uint_9586980 + %20618 = OpShiftRightLogical %uint %19602 %uint_2 + %24290 = OpBitwiseOr %uint %24003 %20618 + %7728 = OpBitwiseXor %uint %24290 %uint_2396745 + %9547 = OpNot %uint %22250 + %14628 = OpBitwiseAnd %uint %20082 %9547 + %8432 = OpNot %uint %20618 + %11414 = OpBitwiseAnd %uint %14628 %8432 + %6806 = OpBitwiseOr %uint %23056 %7728 + %19516 = OpISub %uint %6806 %uint_2396745 + %14879 = OpBitwiseOr %uint %19516 %11414 + %18155 = OpShiftLeftLogical %uint %11414 %uint_1 + %16011 = OpBitwiseOr %uint %14879 %18155 + %8121 = OpShiftLeftLogical %uint %11414 %uint_2 + %7811 = OpBitwiseOr %uint %16011 %8121 + OpBranch %11701 + %11701 = OpLabel + %20687 = OpPhi %uint %6255 %10643 %7811 %21927 + %24811 = OpCompositeConstruct %v4uint %17360 %17361 %17362 %20687 + OpSelectionMerge %20297 None + OpBranchConditional %20099 %10644 %14526 + %10644 = OpLabel + %17661 = OpBitwiseAnd %uint %17360 %uint_1170 + %23952 = OpBitwiseAnd %uint %17360 %uint_2340 + %21848 = OpShiftRightLogical %uint %23952 %uint_1 + %8137 = OpBitwiseAnd %uint %17661 %21848 + %24613 = OpShiftLeftLogical %uint %8137 %uint_1 + %22960 = OpShiftRightLogical %uint %8137 %uint_1 + %18812 = OpBitwiseOr %uint %24613 %22960 + %15914 = OpBitwiseOr %uint %8137 %18812 + %8459 = OpNot %uint %15914 + %10082 = OpBitwiseAnd %uint %17360 %8459 + %16300 = OpISub %uint %uint_2925 %10082 + %17415 = OpBitwiseAnd %uint %16300 %8459 + %16991 = OpBitwiseAnd %uint %17415 %uint_7 + %13677 = OpIMul %uint %6502 %16991 + %21975 = OpBitwiseAnd %uint %10082 %uint_7 + %20390 = OpIMul %uint %13104 %21975 + %19842 = OpIAdd %uint %13677 %20390 + %13000 = OpUDiv %uint %19842 %uint_5 + %23022 = OpShiftRightLogical %uint %17415 %uint_3 + %8753 = OpBitwiseAnd %uint %23022 %uint_7 + %15011 = OpIMul %uint %6502 %8753 + %13283 = OpShiftRightLogical %uint %10082 %uint_3 + %24957 = OpBitwiseAnd %uint %13283 %uint_7 + %25194 = OpIMul %uint %13104 %24957 + %19880 = OpIAdd %uint %15011 %25194 + %12616 = OpUDiv %uint %19880 %uint_5 + %8160 = OpShiftLeftLogical %uint %12616 %uint_16 + %7553 = OpBitwiseOr %uint %13000 %8160 + %21935 = OpShiftRightLogical %uint %17415 %uint_6 + %17592 = OpBitwiseAnd %uint %21935 %uint_7 + %15012 = OpIMul %uint %6502 %17592 + %13284 = OpShiftRightLogical %uint %10082 %uint_6 + %24958 = OpBitwiseAnd %uint %13284 %uint_7 + %25195 = OpIMul %uint %13104 %24958 + %19843 = OpIAdd %uint %15012 %25195 + %13001 = OpUDiv %uint %19843 %uint_5 + %23023 = OpShiftRightLogical %uint %17415 %uint_9 + %8754 = OpBitwiseAnd %uint %23023 %uint_7 + %15013 = OpIMul %uint %6502 %8754 + %13285 = OpShiftRightLogical %uint %10082 %uint_9 + %24959 = OpBitwiseAnd %uint %13285 %uint_7 + %25196 = OpIMul %uint %13104 %24959 + %19881 = OpIAdd %uint %15013 %25196 + %12617 = OpUDiv %uint %19881 %uint_5 + %25065 = OpShiftLeftLogical %uint %12617 %uint_16 + %8204 = OpBitwiseOr %uint %13001 %25065 + %10117 = OpCompositeConstruct %v2uint %7553 %8204 + %24268 = OpBitwiseAnd %uint %17360 %15914 + %16374 = OpBitwiseAnd %uint %24268 %uint_1 + %19559 = OpBitwiseAnd %uint %24268 %uint_8 + %24837 = OpShiftLeftLogical %uint %19559 %uint_13 + %18005 = OpBitwiseOr %uint %16374 %24837 + %23208 = OpShiftRightLogical %uint %24268 %uint_6 + %25110 = OpBitwiseAnd %uint %23208 %uint_1 + %18755 = OpBitwiseAnd %uint %24268 %uint_512 + %22671 = OpShiftLeftLogical %uint %18755 %uint_7 + %17383 = OpBitwiseOr %uint %25110 %22671 + %20359 = OpCompositeConstruct %v2uint %18005 %17383 + %20759 = OpIMul %v2uint %20359 %1140 + %23854 = OpIAdd %v2uint %10117 %20759 + OpBranch %20297 + %14526 = OpLabel + %10708 = OpNot %uint %17360 + %15358 = OpBitwiseAnd %uint %10708 %uint_7 + %17712 = OpIMul %uint %6502 %15358 + %21976 = OpBitwiseAnd %uint %17360 %uint_7 + %20391 = OpIMul %uint %13104 %21976 + %19844 = OpIAdd %uint %17712 %20391 + %13002 = OpUDiv %uint %19844 %uint_7 + %23024 = OpShiftRightLogical %uint %10708 %uint_3 + %8755 = OpBitwiseAnd %uint %23024 %uint_7 + %15014 = OpIMul %uint %6502 %8755 + %13286 = OpShiftRightLogical %uint %17360 %uint_3 + %24960 = OpBitwiseAnd %uint %13286 %uint_7 + %25197 = OpIMul %uint %13104 %24960 + %19882 = OpIAdd %uint %15014 %25197 + %12618 = OpUDiv %uint %19882 %uint_7 + %8161 = OpShiftLeftLogical %uint %12618 %uint_16 + %7554 = OpBitwiseOr %uint %13002 %8161 + %21936 = OpShiftRightLogical %uint %10708 %uint_6 + %17593 = OpBitwiseAnd %uint %21936 %uint_7 + %15015 = OpIMul %uint %6502 %17593 + %13287 = OpShiftRightLogical %uint %17360 %uint_6 + %24961 = OpBitwiseAnd %uint %13287 %uint_7 + %25198 = OpIMul %uint %13104 %24961 + %19845 = OpIAdd %uint %15015 %25198 + %13003 = OpUDiv %uint %19845 %uint_7 + %23025 = OpShiftRightLogical %uint %10708 %uint_9 + %8756 = OpBitwiseAnd %uint %23025 %uint_7 + %15016 = OpIMul %uint %6502 %8756 + %13288 = OpShiftRightLogical %uint %17360 %uint_9 + %24962 = OpBitwiseAnd %uint %13288 %uint_7 + %25199 = OpIMul %uint %13104 %24962 + %19883 = OpIAdd %uint %15016 %25199 + %12619 = OpUDiv %uint %19883 %uint_7 + %25066 = OpShiftLeftLogical %uint %12619 %uint_16 + %9154 = OpBitwiseOr %uint %13003 %25066 + %21469 = OpCompositeConstruct %v2uint %7554 %9154 + OpBranch %20297 + %20297 = OpLabel + %10925 = OpPhi %v2uint %23854 %10644 %21469 %14526 + OpSelectionMerge %19328 None + OpBranchConditional %20100 %10645 %14527 + %10645 = OpLabel + %17662 = OpBitwiseAnd %uint %17361 %uint_1170 + %23953 = OpBitwiseAnd %uint %17361 %uint_2340 + %21849 = OpShiftRightLogical %uint %23953 %uint_1 + %8138 = OpBitwiseAnd %uint %17662 %21849 + %24614 = OpShiftLeftLogical %uint %8138 %uint_1 + %22961 = OpShiftRightLogical %uint %8138 %uint_1 + %18813 = OpBitwiseOr %uint %24614 %22961 + %15915 = OpBitwiseOr %uint %8138 %18813 + %8460 = OpNot %uint %15915 + %10083 = OpBitwiseAnd %uint %17361 %8460 + %16301 = OpISub %uint %uint_2925 %10083 + %17416 = OpBitwiseAnd %uint %16301 %8460 + %16992 = OpBitwiseAnd %uint %17416 %uint_7 + %13678 = OpIMul %uint %12929 %16992 + %21977 = OpBitwiseAnd %uint %10083 %uint_7 + %20392 = OpIMul %uint %13105 %21977 + %19846 = OpIAdd %uint %13678 %20392 + %13004 = OpUDiv %uint %19846 %uint_5 + %23026 = OpShiftRightLogical %uint %17416 %uint_3 + %8757 = OpBitwiseAnd %uint %23026 %uint_7 + %15017 = OpIMul %uint %12929 %8757 + %13289 = OpShiftRightLogical %uint %10083 %uint_3 + %24963 = OpBitwiseAnd %uint %13289 %uint_7 + %25200 = OpIMul %uint %13105 %24963 + %19884 = OpIAdd %uint %15017 %25200 + %12620 = OpUDiv %uint %19884 %uint_5 + %8162 = OpShiftLeftLogical %uint %12620 %uint_16 + %7555 = OpBitwiseOr %uint %13004 %8162 + %21937 = OpShiftRightLogical %uint %17416 %uint_6 + %17594 = OpBitwiseAnd %uint %21937 %uint_7 + %15018 = OpIMul %uint %12929 %17594 + %13290 = OpShiftRightLogical %uint %10083 %uint_6 + %24964 = OpBitwiseAnd %uint %13290 %uint_7 + %25201 = OpIMul %uint %13105 %24964 + %19847 = OpIAdd %uint %15018 %25201 + %13005 = OpUDiv %uint %19847 %uint_5 + %23027 = OpShiftRightLogical %uint %17416 %uint_9 + %8758 = OpBitwiseAnd %uint %23027 %uint_7 + %15019 = OpIMul %uint %12929 %8758 + %13291 = OpShiftRightLogical %uint %10083 %uint_9 + %24965 = OpBitwiseAnd %uint %13291 %uint_7 + %25202 = OpIMul %uint %13105 %24965 + %19885 = OpIAdd %uint %15019 %25202 + %12621 = OpUDiv %uint %19885 %uint_5 + %25067 = OpShiftLeftLogical %uint %12621 %uint_16 + %8205 = OpBitwiseOr %uint %13005 %25067 + %10118 = OpCompositeConstruct %v2uint %7555 %8205 + %24269 = OpBitwiseAnd %uint %17361 %15915 + %16375 = OpBitwiseAnd %uint %24269 %uint_1 + %19560 = OpBitwiseAnd %uint %24269 %uint_8 + %24838 = OpShiftLeftLogical %uint %19560 %uint_13 + %18006 = OpBitwiseOr %uint %16375 %24838 + %23209 = OpShiftRightLogical %uint %24269 %uint_6 + %25111 = OpBitwiseAnd %uint %23209 %uint_1 + %18756 = OpBitwiseAnd %uint %24269 %uint_512 + %22672 = OpShiftLeftLogical %uint %18756 %uint_7 + %17384 = OpBitwiseOr %uint %25111 %22672 + %20360 = OpCompositeConstruct %v2uint %18006 %17384 + %20760 = OpIMul %v2uint %20360 %1140 + %23855 = OpIAdd %v2uint %10118 %20760 + OpBranch %19328 + %14527 = OpLabel + %10709 = OpNot %uint %17361 + %15359 = OpBitwiseAnd %uint %10709 %uint_7 + %17713 = OpIMul %uint %12929 %15359 + %21978 = OpBitwiseAnd %uint %17361 %uint_7 + %20393 = OpIMul %uint %13105 %21978 + %19848 = OpIAdd %uint %17713 %20393 + %13006 = OpUDiv %uint %19848 %uint_7 + %23028 = OpShiftRightLogical %uint %10709 %uint_3 + %8759 = OpBitwiseAnd %uint %23028 %uint_7 + %15020 = OpIMul %uint %12929 %8759 + %13292 = OpShiftRightLogical %uint %17361 %uint_3 + %24966 = OpBitwiseAnd %uint %13292 %uint_7 + %25203 = OpIMul %uint %13105 %24966 + %19886 = OpIAdd %uint %15020 %25203 + %12622 = OpUDiv %uint %19886 %uint_7 + %8163 = OpShiftLeftLogical %uint %12622 %uint_16 + %7556 = OpBitwiseOr %uint %13006 %8163 + %21938 = OpShiftRightLogical %uint %10709 %uint_6 + %17595 = OpBitwiseAnd %uint %21938 %uint_7 + %15021 = OpIMul %uint %12929 %17595 + %13293 = OpShiftRightLogical %uint %17361 %uint_6 + %24967 = OpBitwiseAnd %uint %13293 %uint_7 + %25204 = OpIMul %uint %13105 %24967 + %19849 = OpIAdd %uint %15021 %25204 + %13007 = OpUDiv %uint %19849 %uint_7 + %23029 = OpShiftRightLogical %uint %10709 %uint_9 + %8760 = OpBitwiseAnd %uint %23029 %uint_7 + %15022 = OpIMul %uint %12929 %8760 + %13294 = OpShiftRightLogical %uint %17361 %uint_9 + %24968 = OpBitwiseAnd %uint %13294 %uint_7 + %25205 = OpIMul %uint %13105 %24968 + %19887 = OpIAdd %uint %15022 %25205 + %12623 = OpUDiv %uint %19887 %uint_7 + %25068 = OpShiftLeftLogical %uint %12623 %uint_16 + %9155 = OpBitwiseOr %uint %13007 %25068 + %21470 = OpCompositeConstruct %v2uint %7556 %9155 + OpBranch %19328 + %19328 = OpLabel + %18740 = OpPhi %v2uint %23855 %10645 %21470 %14527 + %11038 = OpShiftLeftLogical %v2uint %18740 %1975 + %21076 = OpBitwiseOr %v2uint %10925 %11038 + OpSelectionMerge %20298 None + OpBranchConditional %20101 %10646 %14528 + %10646 = OpLabel + %17663 = OpBitwiseAnd %uint %17362 %uint_1170 + %23954 = OpBitwiseAnd %uint %17362 %uint_2340 + %21850 = OpShiftRightLogical %uint %23954 %uint_1 + %8139 = OpBitwiseAnd %uint %17663 %21850 + %24615 = OpShiftLeftLogical %uint %8139 %uint_1 + %22962 = OpShiftRightLogical %uint %8139 %uint_1 + %18814 = OpBitwiseOr %uint %24615 %22962 + %15916 = OpBitwiseOr %uint %8139 %18814 + %8461 = OpNot %uint %15916 + %10084 = OpBitwiseAnd %uint %17362 %8461 + %16302 = OpISub %uint %uint_2925 %10084 + %17417 = OpBitwiseAnd %uint %16302 %8461 + %16993 = OpBitwiseAnd %uint %17417 %uint_7 + %13679 = OpIMul %uint %12930 %16993 + %21979 = OpBitwiseAnd %uint %10084 %uint_7 + %20394 = OpIMul %uint %13107 %21979 + %19850 = OpIAdd %uint %13679 %20394 + %13008 = OpUDiv %uint %19850 %uint_5 + %23030 = OpShiftRightLogical %uint %17417 %uint_3 + %8761 = OpBitwiseAnd %uint %23030 %uint_7 + %15023 = OpIMul %uint %12930 %8761 + %13295 = OpShiftRightLogical %uint %10084 %uint_3 + %24969 = OpBitwiseAnd %uint %13295 %uint_7 + %25206 = OpIMul %uint %13107 %24969 + %19888 = OpIAdd %uint %15023 %25206 + %12624 = OpUDiv %uint %19888 %uint_5 + %8164 = OpShiftLeftLogical %uint %12624 %uint_16 + %7557 = OpBitwiseOr %uint %13008 %8164 + %21939 = OpShiftRightLogical %uint %17417 %uint_6 + %17596 = OpBitwiseAnd %uint %21939 %uint_7 + %15024 = OpIMul %uint %12930 %17596 + %13296 = OpShiftRightLogical %uint %10084 %uint_6 + %24970 = OpBitwiseAnd %uint %13296 %uint_7 + %25207 = OpIMul %uint %13107 %24970 + %19851 = OpIAdd %uint %15024 %25207 + %13009 = OpUDiv %uint %19851 %uint_5 + %23031 = OpShiftRightLogical %uint %17417 %uint_9 + %8762 = OpBitwiseAnd %uint %23031 %uint_7 + %15025 = OpIMul %uint %12930 %8762 + %13297 = OpShiftRightLogical %uint %10084 %uint_9 + %24971 = OpBitwiseAnd %uint %13297 %uint_7 + %25208 = OpIMul %uint %13107 %24971 + %19889 = OpIAdd %uint %15025 %25208 + %12625 = OpUDiv %uint %19889 %uint_5 + %25069 = OpShiftLeftLogical %uint %12625 %uint_16 + %8206 = OpBitwiseOr %uint %13009 %25069 + %10119 = OpCompositeConstruct %v2uint %7557 %8206 + %24270 = OpBitwiseAnd %uint %17362 %15916 + %16378 = OpBitwiseAnd %uint %24270 %uint_1 + %19561 = OpBitwiseAnd %uint %24270 %uint_8 + %24839 = OpShiftLeftLogical %uint %19561 %uint_13 + %18007 = OpBitwiseOr %uint %16378 %24839 + %23210 = OpShiftRightLogical %uint %24270 %uint_6 + %25112 = OpBitwiseAnd %uint %23210 %uint_1 + %18757 = OpBitwiseAnd %uint %24270 %uint_512 + %22673 = OpShiftLeftLogical %uint %18757 %uint_7 + %17385 = OpBitwiseOr %uint %25112 %22673 + %20361 = OpCompositeConstruct %v2uint %18007 %17385 + %20761 = OpIMul %v2uint %20361 %1140 + %23856 = OpIAdd %v2uint %10119 %20761 + OpBranch %20298 + %14528 = OpLabel + %10710 = OpNot %uint %17362 + %15360 = OpBitwiseAnd %uint %10710 %uint_7 + %17714 = OpIMul %uint %12930 %15360 + %21980 = OpBitwiseAnd %uint %17362 %uint_7 + %20395 = OpIMul %uint %13107 %21980 + %19852 = OpIAdd %uint %17714 %20395 + %13010 = OpUDiv %uint %19852 %uint_7 + %23032 = OpShiftRightLogical %uint %10710 %uint_3 + %8763 = OpBitwiseAnd %uint %23032 %uint_7 + %15026 = OpIMul %uint %12930 %8763 + %13298 = OpShiftRightLogical %uint %17362 %uint_3 + %24972 = OpBitwiseAnd %uint %13298 %uint_7 + %25209 = OpIMul %uint %13107 %24972 + %19890 = OpIAdd %uint %15026 %25209 + %12626 = OpUDiv %uint %19890 %uint_7 + %8165 = OpShiftLeftLogical %uint %12626 %uint_16 + %7558 = OpBitwiseOr %uint %13010 %8165 + %21940 = OpShiftRightLogical %uint %10710 %uint_6 + %17597 = OpBitwiseAnd %uint %21940 %uint_7 + %15027 = OpIMul %uint %12930 %17597 + %13299 = OpShiftRightLogical %uint %17362 %uint_6 + %24973 = OpBitwiseAnd %uint %13299 %uint_7 + %25210 = OpIMul %uint %13107 %24973 + %19854 = OpIAdd %uint %15027 %25210 + %13011 = OpUDiv %uint %19854 %uint_7 + %23033 = OpShiftRightLogical %uint %10710 %uint_9 + %8764 = OpBitwiseAnd %uint %23033 %uint_7 + %15028 = OpIMul %uint %12930 %8764 + %13300 = OpShiftRightLogical %uint %17362 %uint_9 + %24974 = OpBitwiseAnd %uint %13300 %uint_7 + %25211 = OpIMul %uint %13107 %24974 + %19891 = OpIAdd %uint %15028 %25211 + %12627 = OpUDiv %uint %19891 %uint_7 + %25070 = OpShiftLeftLogical %uint %12627 %uint_16 + %9156 = OpBitwiseOr %uint %13011 %25070 + %21471 = OpCompositeConstruct %v2uint %7558 %9156 + OpBranch %20298 + %20298 = OpLabel + %10926 = OpPhi %v2uint %23856 %10646 %21471 %14528 + OpSelectionMerge %19329 None + OpBranchConditional %20102 %10647 %14529 + %10647 = OpLabel + %17664 = OpBitwiseAnd %uint %20687 %uint_1170 + %23955 = OpBitwiseAnd %uint %20687 %uint_2340 + %21851 = OpShiftRightLogical %uint %23955 %uint_1 + %8140 = OpBitwiseAnd %uint %17664 %21851 + %24616 = OpShiftLeftLogical %uint %8140 %uint_1 + %22963 = OpShiftRightLogical %uint %8140 %uint_1 + %18815 = OpBitwiseOr %uint %24616 %22963 + %15917 = OpBitwiseOr %uint %8140 %18815 + %8462 = OpNot %uint %15917 + %10085 = OpBitwiseAnd %uint %20687 %8462 + %16303 = OpISub %uint %uint_2925 %10085 + %17418 = OpBitwiseAnd %uint %16303 %8462 + %16994 = OpBitwiseAnd %uint %17418 %uint_7 + %13680 = OpIMul %uint %12931 %16994 + %21981 = OpBitwiseAnd %uint %10085 %uint_7 + %20396 = OpIMul %uint %13108 %21981 + %19855 = OpIAdd %uint %13680 %20396 + %13012 = OpUDiv %uint %19855 %uint_5 + %23034 = OpShiftRightLogical %uint %17418 %uint_3 + %8765 = OpBitwiseAnd %uint %23034 %uint_7 + %15029 = OpIMul %uint %12931 %8765 + %13301 = OpShiftRightLogical %uint %10085 %uint_3 + %24975 = OpBitwiseAnd %uint %13301 %uint_7 + %25212 = OpIMul %uint %13108 %24975 + %19892 = OpIAdd %uint %15029 %25212 + %12628 = OpUDiv %uint %19892 %uint_5 + %8166 = OpShiftLeftLogical %uint %12628 %uint_16 + %7559 = OpBitwiseOr %uint %13012 %8166 + %21941 = OpShiftRightLogical %uint %17418 %uint_6 + %17600 = OpBitwiseAnd %uint %21941 %uint_7 + %15030 = OpIMul %uint %12931 %17600 + %13302 = OpShiftRightLogical %uint %10085 %uint_6 + %24976 = OpBitwiseAnd %uint %13302 %uint_7 + %25213 = OpIMul %uint %13108 %24976 + %19856 = OpIAdd %uint %15030 %25213 + %13013 = OpUDiv %uint %19856 %uint_5 + %23035 = OpShiftRightLogical %uint %17418 %uint_9 + %8766 = OpBitwiseAnd %uint %23035 %uint_7 + %15031 = OpIMul %uint %12931 %8766 + %13303 = OpShiftRightLogical %uint %10085 %uint_9 + %24977 = OpBitwiseAnd %uint %13303 %uint_7 + %25214 = OpIMul %uint %13108 %24977 + %19893 = OpIAdd %uint %15031 %25214 + %12629 = OpUDiv %uint %19893 %uint_5 + %25071 = OpShiftLeftLogical %uint %12629 %uint_16 + %8207 = OpBitwiseOr %uint %13013 %25071 + %10120 = OpCompositeConstruct %v2uint %7559 %8207 + %24271 = OpBitwiseAnd %uint %20687 %15917 + %16379 = OpBitwiseAnd %uint %24271 %uint_1 + %19562 = OpBitwiseAnd %uint %24271 %uint_8 + %24840 = OpShiftLeftLogical %uint %19562 %uint_13 + %18008 = OpBitwiseOr %uint %16379 %24840 + %23211 = OpShiftRightLogical %uint %24271 %uint_6 + %25113 = OpBitwiseAnd %uint %23211 %uint_1 + %18758 = OpBitwiseAnd %uint %24271 %uint_512 + %22678 = OpShiftLeftLogical %uint %18758 %uint_7 + %17386 = OpBitwiseOr %uint %25113 %22678 + %20362 = OpCompositeConstruct %v2uint %18008 %17386 + %20762 = OpIMul %v2uint %20362 %1140 + %23857 = OpIAdd %v2uint %10120 %20762 + OpBranch %19329 + %14529 = OpLabel + %10711 = OpNot %uint %20687 + %15361 = OpBitwiseAnd %uint %10711 %uint_7 + %17715 = OpIMul %uint %12931 %15361 + %21982 = OpBitwiseAnd %uint %20687 %uint_7 + %20397 = OpIMul %uint %13108 %21982 + %19857 = OpIAdd %uint %17715 %20397 + %13014 = OpUDiv %uint %19857 %uint_7 + %23036 = OpShiftRightLogical %uint %10711 %uint_3 + %8767 = OpBitwiseAnd %uint %23036 %uint_7 + %15032 = OpIMul %uint %12931 %8767 + %13304 = OpShiftRightLogical %uint %20687 %uint_3 + %24978 = OpBitwiseAnd %uint %13304 %uint_7 + %25215 = OpIMul %uint %13108 %24978 + %19894 = OpIAdd %uint %15032 %25215 + %12630 = OpUDiv %uint %19894 %uint_7 + %8167 = OpShiftLeftLogical %uint %12630 %uint_16 + %7560 = OpBitwiseOr %uint %13014 %8167 + %21942 = OpShiftRightLogical %uint %10711 %uint_6 + %17601 = OpBitwiseAnd %uint %21942 %uint_7 + %15033 = OpIMul %uint %12931 %17601 + %13305 = OpShiftRightLogical %uint %20687 %uint_6 + %24979 = OpBitwiseAnd %uint %13305 %uint_7 + %25216 = OpIMul %uint %13108 %24979 + %19858 = OpIAdd %uint %15033 %25216 + %13015 = OpUDiv %uint %19858 %uint_7 + %23037 = OpShiftRightLogical %uint %10711 %uint_9 + %8768 = OpBitwiseAnd %uint %23037 %uint_7 + %15034 = OpIMul %uint %12931 %8768 + %13306 = OpShiftRightLogical %uint %20687 %uint_9 + %24980 = OpBitwiseAnd %uint %13306 %uint_7 + %25217 = OpIMul %uint %13108 %24980 + %19895 = OpIAdd %uint %15034 %25217 + %12631 = OpUDiv %uint %19895 %uint_7 + %25072 = OpShiftLeftLogical %uint %12631 %uint_16 + %9157 = OpBitwiseOr %uint %13015 %25072 + %21472 = OpCompositeConstruct %v2uint %7560 %9157 + OpBranch %19329 + %19329 = OpLabel + %18741 = OpPhi %v2uint %23857 %10647 %21472 %14529 + %7884 = OpShiftLeftLogical %v2uint %18741 %1975 + %8441 = OpBitwiseOr %v2uint %10926 %7884 + %20097 = OpCompositeExtract %uint %21076 0 + %23730 = OpCompositeExtract %uint %21076 1 + %7643 = OpCompositeExtract %uint %8441 0 + %7529 = OpCompositeExtract %uint %8441 1 + %18260 = OpCompositeConstruct %v4uint %20097 %23730 %7643 %7529 + %8787 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11726 + OpStore %8787 %18260 + %12832 = OpCompositeExtract %uint %17344 1 + %23232 = OpIAdd %uint %12832 %int_1 + %17425 = OpULessThan %bool %23232 %6594 + OpSelectionMerge %7206 DontFlatten + OpBranchConditional %17425 %22828 %7206 + %22828 = OpLabel + %13334 = OpIAdd %uint %11726 %6977 + %15655 = OpShiftRightLogical %v4uint %24811 %533 + %23835 = OpCompositeExtract %uint %15655 0 + OpSelectionMerge %17143 None + OpBranchConditional %20099 %10648 %14530 + %10648 = OpLabel + %17665 = OpBitwiseAnd %uint %23835 %uint_1170 + %23956 = OpBitwiseAnd %uint %23835 %uint_2340 + %21852 = OpShiftRightLogical %uint %23956 %uint_1 + %8141 = OpBitwiseAnd %uint %17665 %21852 + %24617 = OpShiftLeftLogical %uint %8141 %uint_1 + %22964 = OpShiftRightLogical %uint %8141 %uint_1 + %18816 = OpBitwiseOr %uint %24617 %22964 + %15918 = OpBitwiseOr %uint %8141 %18816 + %8463 = OpNot %uint %15918 + %10086 = OpBitwiseAnd %uint %23835 %8463 + %16304 = OpISub %uint %uint_2925 %10086 + %17419 = OpBitwiseAnd %uint %16304 %8463 + %16995 = OpBitwiseAnd %uint %17419 %uint_7 + %13681 = OpIMul %uint %6502 %16995 + %21983 = OpBitwiseAnd %uint %10086 %uint_7 + %20398 = OpIMul %uint %13104 %21983 + %19859 = OpIAdd %uint %13681 %20398 + %13016 = OpUDiv %uint %19859 %uint_5 + %23038 = OpShiftRightLogical %uint %17419 %uint_3 + %8769 = OpBitwiseAnd %uint %23038 %uint_7 + %15035 = OpIMul %uint %6502 %8769 + %13307 = OpShiftRightLogical %uint %10086 %uint_3 + %24981 = OpBitwiseAnd %uint %13307 %uint_7 + %25218 = OpIMul %uint %13104 %24981 + %19896 = OpIAdd %uint %15035 %25218 + %12632 = OpUDiv %uint %19896 %uint_5 + %8168 = OpShiftLeftLogical %uint %12632 %uint_16 + %7561 = OpBitwiseOr %uint %13016 %8168 + %21943 = OpShiftRightLogical %uint %17419 %uint_6 + %17602 = OpBitwiseAnd %uint %21943 %uint_7 + %15036 = OpIMul %uint %6502 %17602 + %13308 = OpShiftRightLogical %uint %10086 %uint_6 + %24982 = OpBitwiseAnd %uint %13308 %uint_7 + %25219 = OpIMul %uint %13104 %24982 + %19860 = OpIAdd %uint %15036 %25219 + %13017 = OpUDiv %uint %19860 %uint_5 + %23039 = OpShiftRightLogical %uint %17419 %uint_9 + %8770 = OpBitwiseAnd %uint %23039 %uint_7 + %15037 = OpIMul %uint %6502 %8770 + %13309 = OpShiftRightLogical %uint %10086 %uint_9 + %24983 = OpBitwiseAnd %uint %13309 %uint_7 + %25220 = OpIMul %uint %13104 %24983 + %19897 = OpIAdd %uint %15037 %25220 + %12633 = OpUDiv %uint %19897 %uint_5 + %25073 = OpShiftLeftLogical %uint %12633 %uint_16 + %8208 = OpBitwiseOr %uint %13017 %25073 + %10121 = OpCompositeConstruct %v2uint %7561 %8208 + %24272 = OpBitwiseAnd %uint %23835 %15918 + %16380 = OpBitwiseAnd %uint %24272 %uint_1 + %19563 = OpBitwiseAnd %uint %24272 %uint_8 + %24841 = OpShiftLeftLogical %uint %19563 %uint_13 + %18009 = OpBitwiseOr %uint %16380 %24841 + %23212 = OpShiftRightLogical %uint %24272 %uint_6 + %25114 = OpBitwiseAnd %uint %23212 %uint_1 + %18759 = OpBitwiseAnd %uint %24272 %uint_512 + %22679 = OpShiftLeftLogical %uint %18759 %uint_7 + %17387 = OpBitwiseOr %uint %25114 %22679 + %20363 = OpCompositeConstruct %v2uint %18009 %17387 + %20763 = OpIMul %v2uint %20363 %1140 + %23858 = OpIAdd %v2uint %10121 %20763 + OpBranch %17143 + %14530 = OpLabel + %10712 = OpNot %uint %23835 + %15362 = OpBitwiseAnd %uint %10712 %uint_7 + %17716 = OpIMul %uint %6502 %15362 + %21984 = OpBitwiseAnd %uint %23835 %uint_7 + %20399 = OpIMul %uint %13104 %21984 + %19861 = OpIAdd %uint %17716 %20399 + %13018 = OpUDiv %uint %19861 %uint_7 + %23040 = OpShiftRightLogical %uint %10712 %uint_3 + %8771 = OpBitwiseAnd %uint %23040 %uint_7 + %15038 = OpIMul %uint %6502 %8771 + %13310 = OpShiftRightLogical %uint %23835 %uint_3 + %24984 = OpBitwiseAnd %uint %13310 %uint_7 + %25221 = OpIMul %uint %13104 %24984 + %19898 = OpIAdd %uint %15038 %25221 + %12634 = OpUDiv %uint %19898 %uint_7 + %8169 = OpShiftLeftLogical %uint %12634 %uint_16 + %7562 = OpBitwiseOr %uint %13018 %8169 + %21944 = OpShiftRightLogical %uint %10712 %uint_6 + %17603 = OpBitwiseAnd %uint %21944 %uint_7 + %15039 = OpIMul %uint %6502 %17603 + %13311 = OpShiftRightLogical %uint %23835 %uint_6 + %24985 = OpBitwiseAnd %uint %13311 %uint_7 + %25222 = OpIMul %uint %13104 %24985 + %19862 = OpIAdd %uint %15039 %25222 + %13019 = OpUDiv %uint %19862 %uint_7 + %23041 = OpShiftRightLogical %uint %10712 %uint_9 + %8772 = OpBitwiseAnd %uint %23041 %uint_7 + %15040 = OpIMul %uint %6502 %8772 + %13312 = OpShiftRightLogical %uint %23835 %uint_9 + %24986 = OpBitwiseAnd %uint %13312 %uint_7 + %25223 = OpIMul %uint %13104 %24986 + %19899 = OpIAdd %uint %15040 %25223 + %12635 = OpUDiv %uint %19899 %uint_7 + %25074 = OpShiftLeftLogical %uint %12635 %uint_16 + %9158 = OpBitwiseOr %uint %13019 %25074 + %21473 = OpCompositeConstruct %v2uint %7562 %9158 + OpBranch %17143 + %17143 = OpLabel + %20515 = OpPhi %v2uint %23858 %10648 %21473 %14530 + %16618 = OpCompositeExtract %uint %15655 1 + OpSelectionMerge %19330 None + OpBranchConditional %20100 %10649 %14531 + %10649 = OpLabel + %17666 = OpBitwiseAnd %uint %16618 %uint_1170 + %23957 = OpBitwiseAnd %uint %16618 %uint_2340 + %21853 = OpShiftRightLogical %uint %23957 %uint_1 + %8142 = OpBitwiseAnd %uint %17666 %21853 + %24618 = OpShiftLeftLogical %uint %8142 %uint_1 + %22965 = OpShiftRightLogical %uint %8142 %uint_1 + %18817 = OpBitwiseOr %uint %24618 %22965 + %15919 = OpBitwiseOr %uint %8142 %18817 + %8464 = OpNot %uint %15919 + %10087 = OpBitwiseAnd %uint %16618 %8464 + %16305 = OpISub %uint %uint_2925 %10087 + %17420 = OpBitwiseAnd %uint %16305 %8464 + %16996 = OpBitwiseAnd %uint %17420 %uint_7 + %13682 = OpIMul %uint %12929 %16996 + %21985 = OpBitwiseAnd %uint %10087 %uint_7 + %20400 = OpIMul %uint %13105 %21985 + %19863 = OpIAdd %uint %13682 %20400 + %13020 = OpUDiv %uint %19863 %uint_5 + %23042 = OpShiftRightLogical %uint %17420 %uint_3 + %8773 = OpBitwiseAnd %uint %23042 %uint_7 + %15041 = OpIMul %uint %12929 %8773 + %13313 = OpShiftRightLogical %uint %10087 %uint_3 + %24987 = OpBitwiseAnd %uint %13313 %uint_7 + %25224 = OpIMul %uint %13105 %24987 + %19900 = OpIAdd %uint %15041 %25224 + %12636 = OpUDiv %uint %19900 %uint_5 + %8170 = OpShiftLeftLogical %uint %12636 %uint_16 + %7563 = OpBitwiseOr %uint %13020 %8170 + %21945 = OpShiftRightLogical %uint %17420 %uint_6 + %17604 = OpBitwiseAnd %uint %21945 %uint_7 + %15042 = OpIMul %uint %12929 %17604 + %13314 = OpShiftRightLogical %uint %10087 %uint_6 + %24988 = OpBitwiseAnd %uint %13314 %uint_7 + %25225 = OpIMul %uint %13105 %24988 + %19864 = OpIAdd %uint %15042 %25225 + %13021 = OpUDiv %uint %19864 %uint_5 + %23043 = OpShiftRightLogical %uint %17420 %uint_9 + %8774 = OpBitwiseAnd %uint %23043 %uint_7 + %15043 = OpIMul %uint %12929 %8774 + %13315 = OpShiftRightLogical %uint %10087 %uint_9 + %24989 = OpBitwiseAnd %uint %13315 %uint_7 + %25226 = OpIMul %uint %13105 %24989 + %19901 = OpIAdd %uint %15043 %25226 + %12637 = OpUDiv %uint %19901 %uint_5 + %25075 = OpShiftLeftLogical %uint %12637 %uint_16 + %8209 = OpBitwiseOr %uint %13021 %25075 + %10123 = OpCompositeConstruct %v2uint %7563 %8209 + %24273 = OpBitwiseAnd %uint %16618 %15919 + %16381 = OpBitwiseAnd %uint %24273 %uint_1 + %19564 = OpBitwiseAnd %uint %24273 %uint_8 + %24842 = OpShiftLeftLogical %uint %19564 %uint_13 + %18010 = OpBitwiseOr %uint %16381 %24842 + %23213 = OpShiftRightLogical %uint %24273 %uint_6 + %25115 = OpBitwiseAnd %uint %23213 %uint_1 + %18760 = OpBitwiseAnd %uint %24273 %uint_512 + %22680 = OpShiftLeftLogical %uint %18760 %uint_7 + %17388 = OpBitwiseOr %uint %25115 %22680 + %20364 = OpCompositeConstruct %v2uint %18010 %17388 + %20764 = OpIMul %v2uint %20364 %1140 + %23859 = OpIAdd %v2uint %10123 %20764 + OpBranch %19330 + %14531 = OpLabel + %10713 = OpNot %uint %16618 + %15363 = OpBitwiseAnd %uint %10713 %uint_7 + %17717 = OpIMul %uint %12929 %15363 + %21986 = OpBitwiseAnd %uint %16618 %uint_7 + %20401 = OpIMul %uint %13105 %21986 + %19865 = OpIAdd %uint %17717 %20401 + %13022 = OpUDiv %uint %19865 %uint_7 + %23044 = OpShiftRightLogical %uint %10713 %uint_3 + %8775 = OpBitwiseAnd %uint %23044 %uint_7 + %15044 = OpIMul %uint %12929 %8775 + %13316 = OpShiftRightLogical %uint %16618 %uint_3 + %24990 = OpBitwiseAnd %uint %13316 %uint_7 + %25227 = OpIMul %uint %13105 %24990 + %19902 = OpIAdd %uint %15044 %25227 + %12638 = OpUDiv %uint %19902 %uint_7 + %8171 = OpShiftLeftLogical %uint %12638 %uint_16 + %7564 = OpBitwiseOr %uint %13022 %8171 + %21946 = OpShiftRightLogical %uint %10713 %uint_6 + %17605 = OpBitwiseAnd %uint %21946 %uint_7 + %15045 = OpIMul %uint %12929 %17605 + %13317 = OpShiftRightLogical %uint %16618 %uint_6 + %24991 = OpBitwiseAnd %uint %13317 %uint_7 + %25228 = OpIMul %uint %13105 %24991 + %19866 = OpIAdd %uint %15045 %25228 + %13023 = OpUDiv %uint %19866 %uint_7 + %23045 = OpShiftRightLogical %uint %10713 %uint_9 + %8776 = OpBitwiseAnd %uint %23045 %uint_7 + %15046 = OpIMul %uint %12929 %8776 + %13318 = OpShiftRightLogical %uint %16618 %uint_9 + %24992 = OpBitwiseAnd %uint %13318 %uint_7 + %25229 = OpIMul %uint %13105 %24992 + %19903 = OpIAdd %uint %15046 %25229 + %12639 = OpUDiv %uint %19903 %uint_7 + %25076 = OpShiftLeftLogical %uint %12639 %uint_16 + %9159 = OpBitwiseOr %uint %13023 %25076 + %21474 = OpCompositeConstruct %v2uint %7564 %9159 + OpBranch %19330 + %19330 = OpLabel + %18742 = OpPhi %v2uint %23859 %10649 %21474 %14531 + %7885 = OpShiftLeftLogical %v2uint %18742 %1975 + %11595 = OpBitwiseOr %v2uint %20515 %7885 + %13660 = OpCompositeExtract %uint %15655 2 + OpSelectionMerge %17144 None + OpBranchConditional %20101 %10650 %14532 + %10650 = OpLabel + %17667 = OpBitwiseAnd %uint %13660 %uint_1170 + %23958 = OpBitwiseAnd %uint %13660 %uint_2340 + %21854 = OpShiftRightLogical %uint %23958 %uint_1 + %8143 = OpBitwiseAnd %uint %17667 %21854 + %24619 = OpShiftLeftLogical %uint %8143 %uint_1 + %22966 = OpShiftRightLogical %uint %8143 %uint_1 + %18818 = OpBitwiseOr %uint %24619 %22966 + %15920 = OpBitwiseOr %uint %8143 %18818 + %8465 = OpNot %uint %15920 + %10088 = OpBitwiseAnd %uint %13660 %8465 + %16306 = OpISub %uint %uint_2925 %10088 + %17421 = OpBitwiseAnd %uint %16306 %8465 + %16997 = OpBitwiseAnd %uint %17421 %uint_7 + %13683 = OpIMul %uint %12930 %16997 + %21987 = OpBitwiseAnd %uint %10088 %uint_7 + %20402 = OpIMul %uint %13107 %21987 + %19867 = OpIAdd %uint %13683 %20402 + %13024 = OpUDiv %uint %19867 %uint_5 + %23046 = OpShiftRightLogical %uint %17421 %uint_3 + %8777 = OpBitwiseAnd %uint %23046 %uint_7 + %15047 = OpIMul %uint %12930 %8777 + %13319 = OpShiftRightLogical %uint %10088 %uint_3 + %24993 = OpBitwiseAnd %uint %13319 %uint_7 + %25230 = OpIMul %uint %13107 %24993 + %19904 = OpIAdd %uint %15047 %25230 + %12640 = OpUDiv %uint %19904 %uint_5 + %8172 = OpShiftLeftLogical %uint %12640 %uint_16 + %7565 = OpBitwiseOr %uint %13024 %8172 + %21947 = OpShiftRightLogical %uint %17421 %uint_6 + %17606 = OpBitwiseAnd %uint %21947 %uint_7 + %15048 = OpIMul %uint %12930 %17606 + %13320 = OpShiftRightLogical %uint %10088 %uint_6 + %24994 = OpBitwiseAnd %uint %13320 %uint_7 + %25231 = OpIMul %uint %13107 %24994 + %19868 = OpIAdd %uint %15048 %25231 + %13025 = OpUDiv %uint %19868 %uint_5 + %23047 = OpShiftRightLogical %uint %17421 %uint_9 + %8778 = OpBitwiseAnd %uint %23047 %uint_7 + %15049 = OpIMul %uint %12930 %8778 + %13321 = OpShiftRightLogical %uint %10088 %uint_9 + %24995 = OpBitwiseAnd %uint %13321 %uint_7 + %25232 = OpIMul %uint %13107 %24995 + %19905 = OpIAdd %uint %15049 %25232 + %12641 = OpUDiv %uint %19905 %uint_5 + %25077 = OpShiftLeftLogical %uint %12641 %uint_16 + %8210 = OpBitwiseOr %uint %13025 %25077 + %10124 = OpCompositeConstruct %v2uint %7565 %8210 + %24274 = OpBitwiseAnd %uint %13660 %15920 + %16382 = OpBitwiseAnd %uint %24274 %uint_1 + %19565 = OpBitwiseAnd %uint %24274 %uint_8 + %24843 = OpShiftLeftLogical %uint %19565 %uint_13 + %18011 = OpBitwiseOr %uint %16382 %24843 + %23214 = OpShiftRightLogical %uint %24274 %uint_6 + %25116 = OpBitwiseAnd %uint %23214 %uint_1 + %18761 = OpBitwiseAnd %uint %24274 %uint_512 + %22681 = OpShiftLeftLogical %uint %18761 %uint_7 + %17389 = OpBitwiseOr %uint %25116 %22681 + %20365 = OpCompositeConstruct %v2uint %18011 %17389 + %20765 = OpIMul %v2uint %20365 %1140 + %23860 = OpIAdd %v2uint %10124 %20765 + OpBranch %17144 + %14532 = OpLabel + %10714 = OpNot %uint %13660 + %15364 = OpBitwiseAnd %uint %10714 %uint_7 + %17718 = OpIMul %uint %12930 %15364 + %21988 = OpBitwiseAnd %uint %13660 %uint_7 + %20407 = OpIMul %uint %13107 %21988 + %19869 = OpIAdd %uint %17718 %20407 + %13026 = OpUDiv %uint %19869 %uint_7 + %23048 = OpShiftRightLogical %uint %10714 %uint_3 + %8779 = OpBitwiseAnd %uint %23048 %uint_7 + %15050 = OpIMul %uint %12930 %8779 + %13322 = OpShiftRightLogical %uint %13660 %uint_3 + %24996 = OpBitwiseAnd %uint %13322 %uint_7 + %25233 = OpIMul %uint %13107 %24996 + %19906 = OpIAdd %uint %15050 %25233 + %12642 = OpUDiv %uint %19906 %uint_7 + %8173 = OpShiftLeftLogical %uint %12642 %uint_16 + %7566 = OpBitwiseOr %uint %13026 %8173 + %21948 = OpShiftRightLogical %uint %10714 %uint_6 + %17607 = OpBitwiseAnd %uint %21948 %uint_7 + %15051 = OpIMul %uint %12930 %17607 + %13323 = OpShiftRightLogical %uint %13660 %uint_6 + %24997 = OpBitwiseAnd %uint %13323 %uint_7 + %25234 = OpIMul %uint %13107 %24997 + %19870 = OpIAdd %uint %15051 %25234 + %13027 = OpUDiv %uint %19870 %uint_7 + %23049 = OpShiftRightLogical %uint %10714 %uint_9 + %8780 = OpBitwiseAnd %uint %23049 %uint_7 + %15052 = OpIMul %uint %12930 %8780 + %13324 = OpShiftRightLogical %uint %13660 %uint_9 + %24998 = OpBitwiseAnd %uint %13324 %uint_7 + %25235 = OpIMul %uint %13107 %24998 + %19907 = OpIAdd %uint %15052 %25235 + %12643 = OpUDiv %uint %19907 %uint_7 + %25078 = OpShiftLeftLogical %uint %12643 %uint_16 + %9160 = OpBitwiseOr %uint %13027 %25078 + %21475 = OpCompositeConstruct %v2uint %7566 %9160 + OpBranch %17144 + %17144 = OpLabel + %20516 = OpPhi %v2uint %23860 %10650 %21475 %14532 + %16619 = OpCompositeExtract %uint %15655 3 + OpSelectionMerge %19331 None + OpBranchConditional %20102 %10651 %14533 + %10651 = OpLabel + %17668 = OpBitwiseAnd %uint %16619 %uint_1170 + %23959 = OpBitwiseAnd %uint %16619 %uint_2340 + %21855 = OpShiftRightLogical %uint %23959 %uint_1 + %8144 = OpBitwiseAnd %uint %17668 %21855 + %24620 = OpShiftLeftLogical %uint %8144 %uint_1 + %22967 = OpShiftRightLogical %uint %8144 %uint_1 + %18819 = OpBitwiseOr %uint %24620 %22967 + %15921 = OpBitwiseOr %uint %8144 %18819 + %8466 = OpNot %uint %15921 + %10089 = OpBitwiseAnd %uint %16619 %8466 + %16307 = OpISub %uint %uint_2925 %10089 + %17422 = OpBitwiseAnd %uint %16307 %8466 + %16998 = OpBitwiseAnd %uint %17422 %uint_7 + %13684 = OpIMul %uint %12931 %16998 + %21989 = OpBitwiseAnd %uint %10089 %uint_7 + %20408 = OpIMul %uint %13108 %21989 + %19871 = OpIAdd %uint %13684 %20408 + %13028 = OpUDiv %uint %19871 %uint_5 + %23050 = OpShiftRightLogical %uint %17422 %uint_3 + %8781 = OpBitwiseAnd %uint %23050 %uint_7 + %15053 = OpIMul %uint %12931 %8781 + %13325 = OpShiftRightLogical %uint %10089 %uint_3 + %24999 = OpBitwiseAnd %uint %13325 %uint_7 + %25236 = OpIMul %uint %13108 %24999 + %19908 = OpIAdd %uint %15053 %25236 + %12644 = OpUDiv %uint %19908 %uint_5 + %8174 = OpShiftLeftLogical %uint %12644 %uint_16 + %7567 = OpBitwiseOr %uint %13028 %8174 + %21949 = OpShiftRightLogical %uint %17422 %uint_6 + %17608 = OpBitwiseAnd %uint %21949 %uint_7 + %15054 = OpIMul %uint %12931 %17608 + %13326 = OpShiftRightLogical %uint %10089 %uint_6 + %25000 = OpBitwiseAnd %uint %13326 %uint_7 + %25237 = OpIMul %uint %13108 %25000 + %19872 = OpIAdd %uint %15054 %25237 + %13029 = OpUDiv %uint %19872 %uint_5 + %23051 = OpShiftRightLogical %uint %17422 %uint_9 + %8782 = OpBitwiseAnd %uint %23051 %uint_7 + %15055 = OpIMul %uint %12931 %8782 + %13327 = OpShiftRightLogical %uint %10089 %uint_9 + %25001 = OpBitwiseAnd %uint %13327 %uint_7 + %25238 = OpIMul %uint %13108 %25001 + %19909 = OpIAdd %uint %15055 %25238 + %12645 = OpUDiv %uint %19909 %uint_5 + %25079 = OpShiftLeftLogical %uint %12645 %uint_16 + %8211 = OpBitwiseOr %uint %13029 %25079 + %10125 = OpCompositeConstruct %v2uint %7567 %8211 + %24275 = OpBitwiseAnd %uint %16619 %15921 + %16383 = OpBitwiseAnd %uint %24275 %uint_1 + %19566 = OpBitwiseAnd %uint %24275 %uint_8 + %24844 = OpShiftLeftLogical %uint %19566 %uint_13 + %18012 = OpBitwiseOr %uint %16383 %24844 + %23215 = OpShiftRightLogical %uint %24275 %uint_6 + %25117 = OpBitwiseAnd %uint %23215 %uint_1 + %18762 = OpBitwiseAnd %uint %24275 %uint_512 + %22682 = OpShiftLeftLogical %uint %18762 %uint_7 + %17390 = OpBitwiseOr %uint %25117 %22682 + %20366 = OpCompositeConstruct %v2uint %18012 %17390 + %20766 = OpIMul %v2uint %20366 %1140 + %23861 = OpIAdd %v2uint %10125 %20766 + OpBranch %19331 + %14533 = OpLabel + %10715 = OpNot %uint %16619 + %15365 = OpBitwiseAnd %uint %10715 %uint_7 + %17719 = OpIMul %uint %12931 %15365 + %21990 = OpBitwiseAnd %uint %16619 %uint_7 + %20409 = OpIMul %uint %13108 %21990 + %19873 = OpIAdd %uint %17719 %20409 + %13030 = OpUDiv %uint %19873 %uint_7 + %23053 = OpShiftRightLogical %uint %10715 %uint_3 + %8783 = OpBitwiseAnd %uint %23053 %uint_7 + %15056 = OpIMul %uint %12931 %8783 + %13328 = OpShiftRightLogical %uint %16619 %uint_3 + %25002 = OpBitwiseAnd %uint %13328 %uint_7 + %25239 = OpIMul %uint %13108 %25002 + %19910 = OpIAdd %uint %15056 %25239 + %12646 = OpUDiv %uint %19910 %uint_7 + %8175 = OpShiftLeftLogical %uint %12646 %uint_16 + %7568 = OpBitwiseOr %uint %13030 %8175 + %21950 = OpShiftRightLogical %uint %10715 %uint_6 + %17609 = OpBitwiseAnd %uint %21950 %uint_7 + %15057 = OpIMul %uint %12931 %17609 + %13329 = OpShiftRightLogical %uint %16619 %uint_6 + %25003 = OpBitwiseAnd %uint %13329 %uint_7 + %25240 = OpIMul %uint %13108 %25003 + %19874 = OpIAdd %uint %15057 %25240 + %13031 = OpUDiv %uint %19874 %uint_7 + %23057 = OpShiftRightLogical %uint %10715 %uint_9 + %8784 = OpBitwiseAnd %uint %23057 %uint_7 + %15058 = OpIMul %uint %12931 %8784 + %13331 = OpShiftRightLogical %uint %16619 %uint_9 + %25004 = OpBitwiseAnd %uint %13331 %uint_7 + %25241 = OpIMul %uint %13108 %25004 + %19911 = OpIAdd %uint %15058 %25241 + %12647 = OpUDiv %uint %19911 %uint_7 + %25080 = OpShiftLeftLogical %uint %12647 %uint_16 + %9161 = OpBitwiseOr %uint %13031 %25080 + %21476 = OpCompositeConstruct %v2uint %7568 %9161 + OpBranch %19331 + %19331 = OpLabel + %18743 = OpPhi %v2uint %23861 %10651 %21476 %14533 + %7886 = OpShiftLeftLogical %v2uint %18743 %1975 + %8442 = OpBitwiseOr %v2uint %20516 %7886 + %20098 = OpCompositeExtract %uint %11595 0 + %23731 = OpCompositeExtract %uint %11595 1 + %7644 = OpCompositeExtract %uint %8442 0 + %7530 = OpCompositeExtract %uint %8442 1 + %18261 = OpCompositeConstruct %v4uint %20098 %23731 %7644 %7530 + %9680 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13334 + OpStore %9680 %18261 + %14840 = OpIAdd %uint %12832 %int_2 + %11787 = OpULessThan %bool %14840 %6594 + OpSelectionMerge %7205 DontFlatten + OpBranchConditional %11787 %22829 %7205 + %22829 = OpLabel + %13335 = OpIAdd %uint %13334 %6977 + %15656 = OpShiftRightLogical %v4uint %16695 %317 + %23836 = OpCompositeExtract %uint %15656 0 + OpSelectionMerge %11723 None + OpBranchConditional %20099 %10652 %21929 + %10652 = OpLabel + %17669 = OpBitwiseAnd %uint %23836 %uint_4793490 + %23960 = OpBitwiseAnd %uint %23836 %uint_9586980 + %21856 = OpShiftRightLogical %uint %23960 %uint_1 + %8145 = OpBitwiseAnd %uint %17669 %21856 + %24621 = OpShiftLeftLogical %uint %8145 %uint_1 + %22968 = OpShiftRightLogical %uint %8145 %uint_1 + %18798 = OpBitwiseOr %uint %24621 %22968 + %16053 = OpBitwiseOr %uint %8145 %18798 + %18313 = OpBitwiseAnd %uint %23836 %uint_2396745 + %14689 = OpBitwiseOr %uint %18313 %uint_14380470 + %20410 = OpBitwiseAnd %uint %14689 %16053 + %20543 = OpShiftRightLogical %uint %17669 %uint_1 + %24926 = OpBitwiseOr %uint %18313 %20543 + %21928 = OpShiftRightLogical %uint %23960 %uint_2 + %22683 = OpBitwiseOr %uint %24926 %21928 + %7729 = OpBitwiseXor %uint %22683 %uint_2396745 + %9548 = OpNot %uint %20543 + %14629 = OpBitwiseAnd %uint %18313 %9548 + %8433 = OpNot %uint %21928 + %11415 = OpBitwiseAnd %uint %14629 %8433 + %6807 = OpBitwiseOr %uint %23836 %7729 + %19517 = OpISub %uint %6807 %uint_2396745 + %14880 = OpBitwiseOr %uint %19517 %11415 + %18232 = OpShiftLeftLogical %uint %11415 %uint_2 + %15366 = OpBitwiseOr %uint %14880 %18232 + %12158 = OpNot %uint %16053 + %18516 = OpBitwiseAnd %uint %15366 %12158 + %6256 = OpBitwiseOr %uint %18516 %20410 + OpBranch %11723 + %21929 = OpLabel + %20083 = OpBitwiseAnd %uint %23836 %uint_2396745 + %23914 = OpBitwiseAnd %uint %23836 %uint_4793490 + %22251 = OpShiftRightLogical %uint %23914 %uint_1 + %24004 = OpBitwiseOr %uint %20083 %22251 + %19603 = OpBitwiseAnd %uint %23836 %uint_9586980 + %20619 = OpShiftRightLogical %uint %19603 %uint_2 + %24291 = OpBitwiseOr %uint %24004 %20619 + %7730 = OpBitwiseXor %uint %24291 %uint_2396745 + %9549 = OpNot %uint %22251 + %14630 = OpBitwiseAnd %uint %20083 %9549 + %8434 = OpNot %uint %20619 + %11416 = OpBitwiseAnd %uint %14630 %8434 + %6808 = OpBitwiseOr %uint %23836 %7730 + %19518 = OpISub %uint %6808 %uint_2396745 + %14881 = OpBitwiseOr %uint %19518 %11416 + %18156 = OpShiftLeftLogical %uint %11416 %uint_1 + %16012 = OpBitwiseOr %uint %14881 %18156 + %8122 = OpShiftLeftLogical %uint %11416 %uint_2 + %7812 = OpBitwiseOr %uint %16012 %8122 + OpBranch %11723 + %11723 = OpLabel + %20517 = OpPhi %uint %6256 %10652 %7812 %21929 + %16620 = OpCompositeExtract %uint %15656 1 + OpSelectionMerge %11724 None + OpBranchConditional %20100 %10653 %21931 + %10653 = OpLabel + %17670 = OpBitwiseAnd %uint %16620 %uint_4793490 + %23961 = OpBitwiseAnd %uint %16620 %uint_9586980 + %21857 = OpShiftRightLogical %uint %23961 %uint_1 + %8146 = OpBitwiseAnd %uint %17670 %21857 + %24622 = OpShiftLeftLogical %uint %8146 %uint_1 + %22969 = OpShiftRightLogical %uint %8146 %uint_1 + %18799 = OpBitwiseOr %uint %24622 %22969 + %16054 = OpBitwiseOr %uint %8146 %18799 + %18314 = OpBitwiseAnd %uint %16620 %uint_2396745 + %14690 = OpBitwiseOr %uint %18314 %uint_14380470 + %20411 = OpBitwiseAnd %uint %14690 %16054 + %20544 = OpShiftRightLogical %uint %17670 %uint_1 + %24927 = OpBitwiseOr %uint %18314 %20544 + %21930 = OpShiftRightLogical %uint %23961 %uint_2 + %22684 = OpBitwiseOr %uint %24927 %21930 + %7731 = OpBitwiseXor %uint %22684 %uint_2396745 + %9550 = OpNot %uint %20544 + %14631 = OpBitwiseAnd %uint %18314 %9550 + %8435 = OpNot %uint %21930 + %11417 = OpBitwiseAnd %uint %14631 %8435 + %6809 = OpBitwiseOr %uint %16620 %7731 + %19519 = OpISub %uint %6809 %uint_2396745 + %14882 = OpBitwiseOr %uint %19519 %11417 + %18233 = OpShiftLeftLogical %uint %11417 %uint_2 + %15367 = OpBitwiseOr %uint %14882 %18233 + %12159 = OpNot %uint %16054 + %18517 = OpBitwiseAnd %uint %15367 %12159 + %6257 = OpBitwiseOr %uint %18517 %20411 + OpBranch %11724 + %21931 = OpLabel + %20084 = OpBitwiseAnd %uint %16620 %uint_2396745 + %23915 = OpBitwiseAnd %uint %16620 %uint_4793490 + %22252 = OpShiftRightLogical %uint %23915 %uint_1 + %24005 = OpBitwiseOr %uint %20084 %22252 + %19604 = OpBitwiseAnd %uint %16620 %uint_9586980 + %20620 = OpShiftRightLogical %uint %19604 %uint_2 + %24292 = OpBitwiseOr %uint %24005 %20620 + %7732 = OpBitwiseXor %uint %24292 %uint_2396745 + %9551 = OpNot %uint %22252 + %14632 = OpBitwiseAnd %uint %20084 %9551 + %8436 = OpNot %uint %20620 + %11418 = OpBitwiseAnd %uint %14632 %8436 + %6810 = OpBitwiseOr %uint %16620 %7732 + %19520 = OpISub %uint %6810 %uint_2396745 + %14883 = OpBitwiseOr %uint %19520 %11418 + %18157 = OpShiftLeftLogical %uint %11418 %uint_1 + %16013 = OpBitwiseOr %uint %14883 %18157 + %8123 = OpShiftLeftLogical %uint %11418 %uint_2 + %7813 = OpBitwiseOr %uint %16013 %8123 + OpBranch %11724 + %11724 = OpLabel + %20518 = OpPhi %uint %6257 %10653 %7813 %21931 + %16621 = OpCompositeExtract %uint %15656 2 + OpSelectionMerge %11725 None + OpBranchConditional %20101 %10654 %21933 + %10654 = OpLabel + %17671 = OpBitwiseAnd %uint %16621 %uint_4793490 + %23962 = OpBitwiseAnd %uint %16621 %uint_9586980 + %21858 = OpShiftRightLogical %uint %23962 %uint_1 + %8147 = OpBitwiseAnd %uint %17671 %21858 + %24623 = OpShiftLeftLogical %uint %8147 %uint_1 + %22970 = OpShiftRightLogical %uint %8147 %uint_1 + %18800 = OpBitwiseOr %uint %24623 %22970 + %16055 = OpBitwiseOr %uint %8147 %18800 + %18315 = OpBitwiseAnd %uint %16621 %uint_2396745 + %14691 = OpBitwiseOr %uint %18315 %uint_14380470 + %20412 = OpBitwiseAnd %uint %14691 %16055 + %20545 = OpShiftRightLogical %uint %17671 %uint_1 + %24928 = OpBitwiseOr %uint %18315 %20545 + %21932 = OpShiftRightLogical %uint %23962 %uint_2 + %22685 = OpBitwiseOr %uint %24928 %21932 + %7733 = OpBitwiseXor %uint %22685 %uint_2396745 + %9552 = OpNot %uint %20545 + %14633 = OpBitwiseAnd %uint %18315 %9552 + %8437 = OpNot %uint %21932 + %11419 = OpBitwiseAnd %uint %14633 %8437 + %6811 = OpBitwiseOr %uint %16621 %7733 + %19521 = OpISub %uint %6811 %uint_2396745 + %14884 = OpBitwiseOr %uint %19521 %11419 + %18234 = OpShiftLeftLogical %uint %11419 %uint_2 + %15368 = OpBitwiseOr %uint %14884 %18234 + %12160 = OpNot %uint %16055 + %18518 = OpBitwiseAnd %uint %15368 %12160 + %6258 = OpBitwiseOr %uint %18518 %20412 + OpBranch %11725 + %21933 = OpLabel + %20085 = OpBitwiseAnd %uint %16621 %uint_2396745 + %23916 = OpBitwiseAnd %uint %16621 %uint_4793490 + %22253 = OpShiftRightLogical %uint %23916 %uint_1 + %24006 = OpBitwiseOr %uint %20085 %22253 + %19605 = OpBitwiseAnd %uint %16621 %uint_9586980 + %20621 = OpShiftRightLogical %uint %19605 %uint_2 + %24293 = OpBitwiseOr %uint %24006 %20621 + %7734 = OpBitwiseXor %uint %24293 %uint_2396745 + %9553 = OpNot %uint %22253 + %14634 = OpBitwiseAnd %uint %20085 %9553 + %8438 = OpNot %uint %20621 + %11420 = OpBitwiseAnd %uint %14634 %8438 + %6812 = OpBitwiseOr %uint %16621 %7734 + %19522 = OpISub %uint %6812 %uint_2396745 + %14885 = OpBitwiseOr %uint %19522 %11420 + %18158 = OpShiftLeftLogical %uint %11420 %uint_1 + %16014 = OpBitwiseOr %uint %14885 %18158 + %8124 = OpShiftLeftLogical %uint %11420 %uint_2 + %7814 = OpBitwiseOr %uint %16014 %8124 + OpBranch %11725 + %11725 = OpLabel + %20519 = OpPhi %uint %6258 %10654 %7814 %21933 + %16622 = OpCompositeExtract %uint %15656 3 + OpSelectionMerge %11702 None + OpBranchConditional %20102 %10655 %21951 + %10655 = OpLabel + %17672 = OpBitwiseAnd %uint %16622 %uint_4793490 + %23963 = OpBitwiseAnd %uint %16622 %uint_9586980 + %21859 = OpShiftRightLogical %uint %23963 %uint_1 + %8148 = OpBitwiseAnd %uint %17672 %21859 + %24624 = OpShiftLeftLogical %uint %8148 %uint_1 + %22971 = OpShiftRightLogical %uint %8148 %uint_1 + %18801 = OpBitwiseOr %uint %24624 %22971 + %16056 = OpBitwiseOr %uint %8148 %18801 + %18316 = OpBitwiseAnd %uint %16622 %uint_2396745 + %14692 = OpBitwiseOr %uint %18316 %uint_14380470 + %20413 = OpBitwiseAnd %uint %14692 %16056 + %20546 = OpShiftRightLogical %uint %17672 %uint_1 + %24929 = OpBitwiseOr %uint %18316 %20546 + %21934 = OpShiftRightLogical %uint %23963 %uint_2 + %22686 = OpBitwiseOr %uint %24929 %21934 + %7735 = OpBitwiseXor %uint %22686 %uint_2396745 + %9554 = OpNot %uint %20546 + %14635 = OpBitwiseAnd %uint %18316 %9554 + %8439 = OpNot %uint %21934 + %11421 = OpBitwiseAnd %uint %14635 %8439 + %6813 = OpBitwiseOr %uint %16622 %7735 + %19523 = OpISub %uint %6813 %uint_2396745 + %14886 = OpBitwiseOr %uint %19523 %11421 + %18235 = OpShiftLeftLogical %uint %11421 %uint_2 + %15369 = OpBitwiseOr %uint %14886 %18235 + %12161 = OpNot %uint %16056 + %18519 = OpBitwiseAnd %uint %15369 %12161 + %6259 = OpBitwiseOr %uint %18519 %20413 + OpBranch %11702 + %21951 = OpLabel + %20086 = OpBitwiseAnd %uint %16622 %uint_2396745 + %23917 = OpBitwiseAnd %uint %16622 %uint_4793490 + %22254 = OpShiftRightLogical %uint %23917 %uint_1 + %24007 = OpBitwiseOr %uint %20086 %22254 + %19606 = OpBitwiseAnd %uint %16622 %uint_9586980 + %20622 = OpShiftRightLogical %uint %19606 %uint_2 + %24294 = OpBitwiseOr %uint %24007 %20622 + %7736 = OpBitwiseXor %uint %24294 %uint_2396745 + %9555 = OpNot %uint %22254 + %14636 = OpBitwiseAnd %uint %20086 %9555 + %8440 = OpNot %uint %20622 + %11422 = OpBitwiseAnd %uint %14636 %8440 + %6814 = OpBitwiseOr %uint %16622 %7736 + %19524 = OpISub %uint %6814 %uint_2396745 + %14887 = OpBitwiseOr %uint %19524 %11422 + %18159 = OpShiftLeftLogical %uint %11422 %uint_1 + %16015 = OpBitwiseOr %uint %14887 %18159 + %8125 = OpShiftLeftLogical %uint %11422 %uint_2 + %7815 = OpBitwiseOr %uint %16015 %8125 + OpBranch %11702 + %11702 = OpLabel + %20688 = OpPhi %uint %6259 %10655 %7815 %21951 + %24812 = OpCompositeConstruct %v4uint %20517 %20518 %20519 %20688 + OpSelectionMerge %20299 None + OpBranchConditional %20099 %10656 %14534 + %10656 = OpLabel + %17673 = OpBitwiseAnd %uint %20517 %uint_1170 + %23964 = OpBitwiseAnd %uint %20517 %uint_2340 + %21860 = OpShiftRightLogical %uint %23964 %uint_1 + %8149 = OpBitwiseAnd %uint %17673 %21860 + %24625 = OpShiftLeftLogical %uint %8149 %uint_1 + %22972 = OpShiftRightLogical %uint %8149 %uint_1 + %18820 = OpBitwiseOr %uint %24625 %22972 + %15922 = OpBitwiseOr %uint %8149 %18820 + %8467 = OpNot %uint %15922 + %10090 = OpBitwiseAnd %uint %20517 %8467 + %16308 = OpISub %uint %uint_2925 %10090 + %17423 = OpBitwiseAnd %uint %16308 %8467 + %16999 = OpBitwiseAnd %uint %17423 %uint_7 + %13685 = OpIMul %uint %6502 %16999 + %21991 = OpBitwiseAnd %uint %10090 %uint_7 + %20414 = OpIMul %uint %13104 %21991 + %19875 = OpIAdd %uint %13685 %20414 + %13032 = OpUDiv %uint %19875 %uint_5 + %23058 = OpShiftRightLogical %uint %17423 %uint_3 + %8785 = OpBitwiseAnd %uint %23058 %uint_7 + %15059 = OpIMul %uint %6502 %8785 + %13332 = OpShiftRightLogical %uint %10090 %uint_3 + %25005 = OpBitwiseAnd %uint %13332 %uint_7 + %25242 = OpIMul %uint %13104 %25005 + %19912 = OpIAdd %uint %15059 %25242 + %12648 = OpUDiv %uint %19912 %uint_5 + %8176 = OpShiftLeftLogical %uint %12648 %uint_16 + %7569 = OpBitwiseOr %uint %13032 %8176 + %21952 = OpShiftRightLogical %uint %17423 %uint_6 + %17610 = OpBitwiseAnd %uint %21952 %uint_7 + %15060 = OpIMul %uint %6502 %17610 + %13333 = OpShiftRightLogical %uint %10090 %uint_6 + %25006 = OpBitwiseAnd %uint %13333 %uint_7 + %25243 = OpIMul %uint %13104 %25006 + %19876 = OpIAdd %uint %15060 %25243 + %13033 = OpUDiv %uint %19876 %uint_5 + %23059 = OpShiftRightLogical %uint %17423 %uint_9 + %8786 = OpBitwiseAnd %uint %23059 %uint_7 + %15061 = OpIMul %uint %6502 %8786 + %13336 = OpShiftRightLogical %uint %10090 %uint_9 + %25007 = OpBitwiseAnd %uint %13336 %uint_7 + %25244 = OpIMul %uint %13104 %25007 + %19913 = OpIAdd %uint %15061 %25244 + %12649 = OpUDiv %uint %19913 %uint_5 + %25081 = OpShiftLeftLogical %uint %12649 %uint_16 + %8212 = OpBitwiseOr %uint %13033 %25081 + %10126 = OpCompositeConstruct %v2uint %7569 %8212 + %24276 = OpBitwiseAnd %uint %20517 %15922 + %16384 = OpBitwiseAnd %uint %24276 %uint_1 + %19567 = OpBitwiseAnd %uint %24276 %uint_8 + %24845 = OpShiftLeftLogical %uint %19567 %uint_13 + %18013 = OpBitwiseOr %uint %16384 %24845 + %23216 = OpShiftRightLogical %uint %24276 %uint_6 + %25118 = OpBitwiseAnd %uint %23216 %uint_1 + %18763 = OpBitwiseAnd %uint %24276 %uint_512 + %22687 = OpShiftLeftLogical %uint %18763 %uint_7 + %17391 = OpBitwiseOr %uint %25118 %22687 + %20367 = OpCompositeConstruct %v2uint %18013 %17391 + %20767 = OpIMul %v2uint %20367 %1140 + %23862 = OpIAdd %v2uint %10126 %20767 + OpBranch %20299 + %14534 = OpLabel + %10716 = OpNot %uint %20517 + %15370 = OpBitwiseAnd %uint %10716 %uint_7 + %17720 = OpIMul %uint %6502 %15370 + %21993 = OpBitwiseAnd %uint %20517 %uint_7 + %20415 = OpIMul %uint %13104 %21993 + %19877 = OpIAdd %uint %17720 %20415 + %13034 = OpUDiv %uint %19877 %uint_7 + %23060 = OpShiftRightLogical %uint %10716 %uint_3 + %8788 = OpBitwiseAnd %uint %23060 %uint_7 + %15062 = OpIMul %uint %6502 %8788 + %13337 = OpShiftRightLogical %uint %20517 %uint_3 + %25008 = OpBitwiseAnd %uint %13337 %uint_7 + %25245 = OpIMul %uint %13104 %25008 + %19914 = OpIAdd %uint %15062 %25245 + %12650 = OpUDiv %uint %19914 %uint_7 + %8177 = OpShiftLeftLogical %uint %12650 %uint_16 + %7570 = OpBitwiseOr %uint %13034 %8177 + %21953 = OpShiftRightLogical %uint %10716 %uint_6 + %17611 = OpBitwiseAnd %uint %21953 %uint_7 + %15063 = OpIMul %uint %6502 %17611 + %13338 = OpShiftRightLogical %uint %20517 %uint_6 + %25009 = OpBitwiseAnd %uint %13338 %uint_7 + %25246 = OpIMul %uint %13104 %25009 + %19878 = OpIAdd %uint %15063 %25246 + %13035 = OpUDiv %uint %19878 %uint_7 + %23061 = OpShiftRightLogical %uint %10716 %uint_9 + %8789 = OpBitwiseAnd %uint %23061 %uint_7 + %15064 = OpIMul %uint %6502 %8789 + %13339 = OpShiftRightLogical %uint %20517 %uint_9 + %25010 = OpBitwiseAnd %uint %13339 %uint_7 + %25247 = OpIMul %uint %13104 %25010 + %19915 = OpIAdd %uint %15064 %25247 + %12651 = OpUDiv %uint %19915 %uint_7 + %25082 = OpShiftLeftLogical %uint %12651 %uint_16 + %9162 = OpBitwiseOr %uint %13035 %25082 + %21477 = OpCompositeConstruct %v2uint %7570 %9162 + OpBranch %20299 + %20299 = OpLabel + %10927 = OpPhi %v2uint %23862 %10656 %21477 %14534 + OpSelectionMerge %19332 None + OpBranchConditional %20100 %10657 %14535 + %10657 = OpLabel + %17674 = OpBitwiseAnd %uint %20518 %uint_1170 + %23965 = OpBitwiseAnd %uint %20518 %uint_2340 + %21861 = OpShiftRightLogical %uint %23965 %uint_1 + %8150 = OpBitwiseAnd %uint %17674 %21861 + %24626 = OpShiftLeftLogical %uint %8150 %uint_1 + %22973 = OpShiftRightLogical %uint %8150 %uint_1 + %18821 = OpBitwiseOr %uint %24626 %22973 + %15923 = OpBitwiseOr %uint %8150 %18821 + %8468 = OpNot %uint %15923 + %10091 = OpBitwiseAnd %uint %20518 %8468 + %16309 = OpISub %uint %uint_2925 %10091 + %17424 = OpBitwiseAnd %uint %16309 %8468 + %17000 = OpBitwiseAnd %uint %17424 %uint_7 + %13686 = OpIMul %uint %12929 %17000 + %21994 = OpBitwiseAnd %uint %10091 %uint_7 + %20416 = OpIMul %uint %13105 %21994 + %19879 = OpIAdd %uint %13686 %20416 + %13036 = OpUDiv %uint %19879 %uint_5 + %23062 = OpShiftRightLogical %uint %17424 %uint_3 + %8790 = OpBitwiseAnd %uint %23062 %uint_7 + %15065 = OpIMul %uint %12929 %8790 + %13340 = OpShiftRightLogical %uint %10091 %uint_3 + %25011 = OpBitwiseAnd %uint %13340 %uint_7 + %25248 = OpIMul %uint %13105 %25011 + %19916 = OpIAdd %uint %15065 %25248 + %12652 = OpUDiv %uint %19916 %uint_5 + %8178 = OpShiftLeftLogical %uint %12652 %uint_16 + %7571 = OpBitwiseOr %uint %13036 %8178 + %21954 = OpShiftRightLogical %uint %17424 %uint_6 + %17612 = OpBitwiseAnd %uint %21954 %uint_7 + %15066 = OpIMul %uint %12929 %17612 + %13341 = OpShiftRightLogical %uint %10091 %uint_6 + %25012 = OpBitwiseAnd %uint %13341 %uint_7 + %25249 = OpIMul %uint %13105 %25012 + %19917 = OpIAdd %uint %15066 %25249 + %13037 = OpUDiv %uint %19917 %uint_5 + %23063 = OpShiftRightLogical %uint %17424 %uint_9 + %8791 = OpBitwiseAnd %uint %23063 %uint_7 + %15067 = OpIMul %uint %12929 %8791 + %13342 = OpShiftRightLogical %uint %10091 %uint_9 + %25013 = OpBitwiseAnd %uint %13342 %uint_7 + %25250 = OpIMul %uint %13105 %25013 + %19918 = OpIAdd %uint %15067 %25250 + %12653 = OpUDiv %uint %19918 %uint_5 + %25083 = OpShiftLeftLogical %uint %12653 %uint_16 + %8213 = OpBitwiseOr %uint %13037 %25083 + %10127 = OpCompositeConstruct %v2uint %7571 %8213 + %24277 = OpBitwiseAnd %uint %20518 %15923 + %16385 = OpBitwiseAnd %uint %24277 %uint_1 + %19568 = OpBitwiseAnd %uint %24277 %uint_8 + %24846 = OpShiftLeftLogical %uint %19568 %uint_13 + %18014 = OpBitwiseOr %uint %16385 %24846 + %23219 = OpShiftRightLogical %uint %24277 %uint_6 + %25119 = OpBitwiseAnd %uint %23219 %uint_1 + %18764 = OpBitwiseAnd %uint %24277 %uint_512 + %22688 = OpShiftLeftLogical %uint %18764 %uint_7 + %17392 = OpBitwiseOr %uint %25119 %22688 + %20368 = OpCompositeConstruct %v2uint %18014 %17392 + %20768 = OpIMul %v2uint %20368 %1140 + %23863 = OpIAdd %v2uint %10127 %20768 + OpBranch %19332 + %14535 = OpLabel + %10717 = OpNot %uint %20518 + %15371 = OpBitwiseAnd %uint %10717 %uint_7 + %17721 = OpIMul %uint %12929 %15371 + %21995 = OpBitwiseAnd %uint %20518 %uint_7 + %20417 = OpIMul %uint %13105 %21995 + %19919 = OpIAdd %uint %17721 %20417 + %13038 = OpUDiv %uint %19919 %uint_7 + %23064 = OpShiftRightLogical %uint %10717 %uint_3 + %8792 = OpBitwiseAnd %uint %23064 %uint_7 + %15068 = OpIMul %uint %12929 %8792 + %13343 = OpShiftRightLogical %uint %20518 %uint_3 + %25014 = OpBitwiseAnd %uint %13343 %uint_7 + %25251 = OpIMul %uint %13105 %25014 + %19920 = OpIAdd %uint %15068 %25251 + %12654 = OpUDiv %uint %19920 %uint_7 + %8179 = OpShiftLeftLogical %uint %12654 %uint_16 + %7572 = OpBitwiseOr %uint %13038 %8179 + %21955 = OpShiftRightLogical %uint %10717 %uint_6 + %17613 = OpBitwiseAnd %uint %21955 %uint_7 + %15069 = OpIMul %uint %12929 %17613 + %13344 = OpShiftRightLogical %uint %20518 %uint_6 + %25015 = OpBitwiseAnd %uint %13344 %uint_7 + %25252 = OpIMul %uint %13105 %25015 + %19921 = OpIAdd %uint %15069 %25252 + %13039 = OpUDiv %uint %19921 %uint_7 + %23065 = OpShiftRightLogical %uint %10717 %uint_9 + %8793 = OpBitwiseAnd %uint %23065 %uint_7 + %15070 = OpIMul %uint %12929 %8793 + %13345 = OpShiftRightLogical %uint %20518 %uint_9 + %25016 = OpBitwiseAnd %uint %13345 %uint_7 + %25253 = OpIMul %uint %13105 %25016 + %19922 = OpIAdd %uint %15070 %25253 + %12655 = OpUDiv %uint %19922 %uint_7 + %25084 = OpShiftLeftLogical %uint %12655 %uint_16 + %9163 = OpBitwiseOr %uint %13039 %25084 + %21478 = OpCompositeConstruct %v2uint %7572 %9163 + OpBranch %19332 + %19332 = OpLabel + %18744 = OpPhi %v2uint %23863 %10657 %21478 %14535 + %11039 = OpShiftLeftLogical %v2uint %18744 %1975 + %21077 = OpBitwiseOr %v2uint %10927 %11039 + OpSelectionMerge %20300 None + OpBranchConditional %20101 %10658 %14536 + %10658 = OpLabel + %17675 = OpBitwiseAnd %uint %20519 %uint_1170 + %23966 = OpBitwiseAnd %uint %20519 %uint_2340 + %21862 = OpShiftRightLogical %uint %23966 %uint_1 + %8151 = OpBitwiseAnd %uint %17675 %21862 + %24627 = OpShiftLeftLogical %uint %8151 %uint_1 + %22974 = OpShiftRightLogical %uint %8151 %uint_1 + %18822 = OpBitwiseOr %uint %24627 %22974 + %15924 = OpBitwiseOr %uint %8151 %18822 + %8469 = OpNot %uint %15924 + %10092 = OpBitwiseAnd %uint %20519 %8469 + %16310 = OpISub %uint %uint_2925 %10092 + %17426 = OpBitwiseAnd %uint %16310 %8469 + %17001 = OpBitwiseAnd %uint %17426 %uint_7 + %13687 = OpIMul %uint %12930 %17001 + %21996 = OpBitwiseAnd %uint %10092 %uint_7 + %20418 = OpIMul %uint %13107 %21996 + %19923 = OpIAdd %uint %13687 %20418 + %13040 = OpUDiv %uint %19923 %uint_5 + %23066 = OpShiftRightLogical %uint %17426 %uint_3 + %8794 = OpBitwiseAnd %uint %23066 %uint_7 + %15071 = OpIMul %uint %12930 %8794 + %13346 = OpShiftRightLogical %uint %10092 %uint_3 + %25017 = OpBitwiseAnd %uint %13346 %uint_7 + %25254 = OpIMul %uint %13107 %25017 + %19924 = OpIAdd %uint %15071 %25254 + %12656 = OpUDiv %uint %19924 %uint_5 + %8180 = OpShiftLeftLogical %uint %12656 %uint_16 + %7573 = OpBitwiseOr %uint %13040 %8180 + %21956 = OpShiftRightLogical %uint %17426 %uint_6 + %17614 = OpBitwiseAnd %uint %21956 %uint_7 + %15072 = OpIMul %uint %12930 %17614 + %13347 = OpShiftRightLogical %uint %10092 %uint_6 + %25018 = OpBitwiseAnd %uint %13347 %uint_7 + %25255 = OpIMul %uint %13107 %25018 + %19925 = OpIAdd %uint %15072 %25255 + %13041 = OpUDiv %uint %19925 %uint_5 + %23067 = OpShiftRightLogical %uint %17426 %uint_9 + %8795 = OpBitwiseAnd %uint %23067 %uint_7 + %15073 = OpIMul %uint %12930 %8795 + %13348 = OpShiftRightLogical %uint %10092 %uint_9 + %25019 = OpBitwiseAnd %uint %13348 %uint_7 + %25256 = OpIMul %uint %13107 %25019 + %19926 = OpIAdd %uint %15073 %25256 + %12657 = OpUDiv %uint %19926 %uint_5 + %25085 = OpShiftLeftLogical %uint %12657 %uint_16 + %8214 = OpBitwiseOr %uint %13041 %25085 + %10128 = OpCompositeConstruct %v2uint %7573 %8214 + %24278 = OpBitwiseAnd %uint %20519 %15924 + %16386 = OpBitwiseAnd %uint %24278 %uint_1 + %19569 = OpBitwiseAnd %uint %24278 %uint_8 + %24847 = OpShiftLeftLogical %uint %19569 %uint_13 + %18015 = OpBitwiseOr %uint %16386 %24847 + %23220 = OpShiftRightLogical %uint %24278 %uint_6 + %25120 = OpBitwiseAnd %uint %23220 %uint_1 + %18765 = OpBitwiseAnd %uint %24278 %uint_512 + %22689 = OpShiftLeftLogical %uint %18765 %uint_7 + %17393 = OpBitwiseOr %uint %25120 %22689 + %20369 = OpCompositeConstruct %v2uint %18015 %17393 + %20769 = OpIMul %v2uint %20369 %1140 + %23864 = OpIAdd %v2uint %10128 %20769 + OpBranch %20300 + %14536 = OpLabel + %10718 = OpNot %uint %20519 + %15372 = OpBitwiseAnd %uint %10718 %uint_7 + %17722 = OpIMul %uint %12930 %15372 + %21997 = OpBitwiseAnd %uint %20519 %uint_7 + %20419 = OpIMul %uint %13107 %21997 + %19927 = OpIAdd %uint %17722 %20419 + %13042 = OpUDiv %uint %19927 %uint_7 + %23068 = OpShiftRightLogical %uint %10718 %uint_3 + %8796 = OpBitwiseAnd %uint %23068 %uint_7 + %15074 = OpIMul %uint %12930 %8796 + %13349 = OpShiftRightLogical %uint %20519 %uint_3 + %25020 = OpBitwiseAnd %uint %13349 %uint_7 + %25257 = OpIMul %uint %13107 %25020 + %19928 = OpIAdd %uint %15074 %25257 + %12658 = OpUDiv %uint %19928 %uint_7 + %8181 = OpShiftLeftLogical %uint %12658 %uint_16 + %7574 = OpBitwiseOr %uint %13042 %8181 + %21957 = OpShiftRightLogical %uint %10718 %uint_6 + %17615 = OpBitwiseAnd %uint %21957 %uint_7 + %15075 = OpIMul %uint %12930 %17615 + %13350 = OpShiftRightLogical %uint %20519 %uint_6 + %25021 = OpBitwiseAnd %uint %13350 %uint_7 + %25258 = OpIMul %uint %13107 %25021 + %19929 = OpIAdd %uint %15075 %25258 + %13043 = OpUDiv %uint %19929 %uint_7 + %23069 = OpShiftRightLogical %uint %10718 %uint_9 + %8798 = OpBitwiseAnd %uint %23069 %uint_7 + %15076 = OpIMul %uint %12930 %8798 + %13351 = OpShiftRightLogical %uint %20519 %uint_9 + %25022 = OpBitwiseAnd %uint %13351 %uint_7 + %25259 = OpIMul %uint %13107 %25022 + %19930 = OpIAdd %uint %15076 %25259 + %12659 = OpUDiv %uint %19930 %uint_7 + %25086 = OpShiftLeftLogical %uint %12659 %uint_16 + %9164 = OpBitwiseOr %uint %13043 %25086 + %21479 = OpCompositeConstruct %v2uint %7574 %9164 + OpBranch %20300 + %20300 = OpLabel + %10928 = OpPhi %v2uint %23864 %10658 %21479 %14536 + OpSelectionMerge %19333 None + OpBranchConditional %20102 %10659 %14537 + %10659 = OpLabel + %17676 = OpBitwiseAnd %uint %20688 %uint_1170 + %23967 = OpBitwiseAnd %uint %20688 %uint_2340 + %21863 = OpShiftRightLogical %uint %23967 %uint_1 + %8152 = OpBitwiseAnd %uint %17676 %21863 + %24628 = OpShiftLeftLogical %uint %8152 %uint_1 + %22975 = OpShiftRightLogical %uint %8152 %uint_1 + %18823 = OpBitwiseOr %uint %24628 %22975 + %15925 = OpBitwiseOr %uint %8152 %18823 + %8470 = OpNot %uint %15925 + %10093 = OpBitwiseAnd %uint %20688 %8470 + %16311 = OpISub %uint %uint_2925 %10093 + %17427 = OpBitwiseAnd %uint %16311 %8470 + %17002 = OpBitwiseAnd %uint %17427 %uint_7 + %13688 = OpIMul %uint %12931 %17002 + %21998 = OpBitwiseAnd %uint %10093 %uint_7 + %20420 = OpIMul %uint %13108 %21998 + %19931 = OpIAdd %uint %13688 %20420 + %13044 = OpUDiv %uint %19931 %uint_5 + %23070 = OpShiftRightLogical %uint %17427 %uint_3 + %8799 = OpBitwiseAnd %uint %23070 %uint_7 + %15077 = OpIMul %uint %12931 %8799 + %13352 = OpShiftRightLogical %uint %10093 %uint_3 + %25023 = OpBitwiseAnd %uint %13352 %uint_7 + %25260 = OpIMul %uint %13108 %25023 + %19932 = OpIAdd %uint %15077 %25260 + %12660 = OpUDiv %uint %19932 %uint_5 + %8182 = OpShiftLeftLogical %uint %12660 %uint_16 + %7575 = OpBitwiseOr %uint %13044 %8182 + %21958 = OpShiftRightLogical %uint %17427 %uint_6 + %17616 = OpBitwiseAnd %uint %21958 %uint_7 + %15078 = OpIMul %uint %12931 %17616 + %13353 = OpShiftRightLogical %uint %10093 %uint_6 + %25024 = OpBitwiseAnd %uint %13353 %uint_7 + %25261 = OpIMul %uint %13108 %25024 + %19933 = OpIAdd %uint %15078 %25261 + %13045 = OpUDiv %uint %19933 %uint_5 + %23071 = OpShiftRightLogical %uint %17427 %uint_9 + %8800 = OpBitwiseAnd %uint %23071 %uint_7 + %15079 = OpIMul %uint %12931 %8800 + %13354 = OpShiftRightLogical %uint %10093 %uint_9 + %25025 = OpBitwiseAnd %uint %13354 %uint_7 + %25262 = OpIMul %uint %13108 %25025 + %19934 = OpIAdd %uint %15079 %25262 + %12661 = OpUDiv %uint %19934 %uint_5 + %25087 = OpShiftLeftLogical %uint %12661 %uint_16 + %8215 = OpBitwiseOr %uint %13045 %25087 + %10129 = OpCompositeConstruct %v2uint %7575 %8215 + %24279 = OpBitwiseAnd %uint %20688 %15925 + %16387 = OpBitwiseAnd %uint %24279 %uint_1 + %19570 = OpBitwiseAnd %uint %24279 %uint_8 + %24848 = OpShiftLeftLogical %uint %19570 %uint_13 + %18016 = OpBitwiseOr %uint %16387 %24848 + %23221 = OpShiftRightLogical %uint %24279 %uint_6 + %25121 = OpBitwiseAnd %uint %23221 %uint_1 + %18766 = OpBitwiseAnd %uint %24279 %uint_512 + %22690 = OpShiftLeftLogical %uint %18766 %uint_7 + %17394 = OpBitwiseOr %uint %25121 %22690 + %20370 = OpCompositeConstruct %v2uint %18016 %17394 + %20770 = OpIMul %v2uint %20370 %1140 + %23865 = OpIAdd %v2uint %10129 %20770 + OpBranch %19333 + %14537 = OpLabel + %10719 = OpNot %uint %20688 + %15373 = OpBitwiseAnd %uint %10719 %uint_7 + %17723 = OpIMul %uint %12931 %15373 + %21999 = OpBitwiseAnd %uint %20688 %uint_7 + %20421 = OpIMul %uint %13108 %21999 + %19935 = OpIAdd %uint %17723 %20421 + %13046 = OpUDiv %uint %19935 %uint_7 + %23072 = OpShiftRightLogical %uint %10719 %uint_3 + %8801 = OpBitwiseAnd %uint %23072 %uint_7 + %15080 = OpIMul %uint %12931 %8801 + %13355 = OpShiftRightLogical %uint %20688 %uint_3 + %25026 = OpBitwiseAnd %uint %13355 %uint_7 + %25263 = OpIMul %uint %13108 %25026 + %19936 = OpIAdd %uint %15080 %25263 + %12662 = OpUDiv %uint %19936 %uint_7 + %8183 = OpShiftLeftLogical %uint %12662 %uint_16 + %7576 = OpBitwiseOr %uint %13046 %8183 + %21959 = OpShiftRightLogical %uint %10719 %uint_6 + %17617 = OpBitwiseAnd %uint %21959 %uint_7 + %15081 = OpIMul %uint %12931 %17617 + %13356 = OpShiftRightLogical %uint %20688 %uint_6 + %25027 = OpBitwiseAnd %uint %13356 %uint_7 + %25264 = OpIMul %uint %13108 %25027 + %19937 = OpIAdd %uint %15081 %25264 + %13047 = OpUDiv %uint %19937 %uint_7 + %23073 = OpShiftRightLogical %uint %10719 %uint_9 + %8802 = OpBitwiseAnd %uint %23073 %uint_7 + %15082 = OpIMul %uint %12931 %8802 + %13357 = OpShiftRightLogical %uint %20688 %uint_9 + %25028 = OpBitwiseAnd %uint %13357 %uint_7 + %25265 = OpIMul %uint %13108 %25028 + %19938 = OpIAdd %uint %15082 %25265 + %12663 = OpUDiv %uint %19938 %uint_7 + %25088 = OpShiftLeftLogical %uint %12663 %uint_16 + %9165 = OpBitwiseOr %uint %13047 %25088 + %21480 = OpCompositeConstruct %v2uint %7576 %9165 + OpBranch %19333 + %19333 = OpLabel + %18745 = OpPhi %v2uint %23865 %10659 %21480 %14537 + %7887 = OpShiftLeftLogical %v2uint %18745 %1975 + %8443 = OpBitwiseOr %v2uint %10928 %7887 + %20103 = OpCompositeExtract %uint %21077 0 + %23732 = OpCompositeExtract %uint %21077 1 + %7645 = OpCompositeExtract %uint %8443 0 + %7531 = OpCompositeExtract %uint %8443 1 + %18262 = OpCompositeConstruct %v4uint %20103 %23732 %7645 %7531 + %9681 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13335 + OpStore %9681 %18262 + %14841 = OpIAdd %uint %12832 %int_3 + %11788 = OpULessThan %bool %14841 %6594 + OpSelectionMerge %18021 DontFlatten + OpBranchConditional %11788 %22830 %18021 + %22830 = OpLabel + %13358 = OpIAdd %uint %13335 %6977 + %15657 = OpShiftRightLogical %v4uint %24812 %533 + %23837 = OpCompositeExtract %uint %15657 0 + OpSelectionMerge %17145 None + OpBranchConditional %20099 %10660 %14538 + %10660 = OpLabel + %17677 = OpBitwiseAnd %uint %23837 %uint_1170 + %23968 = OpBitwiseAnd %uint %23837 %uint_2340 + %21864 = OpShiftRightLogical %uint %23968 %uint_1 + %8153 = OpBitwiseAnd %uint %17677 %21864 + %24629 = OpShiftLeftLogical %uint %8153 %uint_1 + %22976 = OpShiftRightLogical %uint %8153 %uint_1 + %18824 = OpBitwiseOr %uint %24629 %22976 + %15926 = OpBitwiseOr %uint %8153 %18824 + %8471 = OpNot %uint %15926 + %10094 = OpBitwiseAnd %uint %23837 %8471 + %16312 = OpISub %uint %uint_2925 %10094 + %17428 = OpBitwiseAnd %uint %16312 %8471 + %17003 = OpBitwiseAnd %uint %17428 %uint_7 + %13689 = OpIMul %uint %6502 %17003 + %22000 = OpBitwiseAnd %uint %10094 %uint_7 + %20422 = OpIMul %uint %13104 %22000 + %19939 = OpIAdd %uint %13689 %20422 + %13048 = OpUDiv %uint %19939 %uint_5 + %23074 = OpShiftRightLogical %uint %17428 %uint_3 + %8803 = OpBitwiseAnd %uint %23074 %uint_7 + %15083 = OpIMul %uint %6502 %8803 + %13359 = OpShiftRightLogical %uint %10094 %uint_3 + %25029 = OpBitwiseAnd %uint %13359 %uint_7 + %25266 = OpIMul %uint %13104 %25029 + %19940 = OpIAdd %uint %15083 %25266 + %12664 = OpUDiv %uint %19940 %uint_5 + %8184 = OpShiftLeftLogical %uint %12664 %uint_16 + %7577 = OpBitwiseOr %uint %13048 %8184 + %21960 = OpShiftRightLogical %uint %17428 %uint_6 + %17618 = OpBitwiseAnd %uint %21960 %uint_7 + %15084 = OpIMul %uint %6502 %17618 + %13360 = OpShiftRightLogical %uint %10094 %uint_6 + %25030 = OpBitwiseAnd %uint %13360 %uint_7 + %25267 = OpIMul %uint %13104 %25030 + %19941 = OpIAdd %uint %15084 %25267 + %13049 = OpUDiv %uint %19941 %uint_5 + %23075 = OpShiftRightLogical %uint %17428 %uint_9 + %8804 = OpBitwiseAnd %uint %23075 %uint_7 + %15085 = OpIMul %uint %6502 %8804 + %13361 = OpShiftRightLogical %uint %10094 %uint_9 + %25031 = OpBitwiseAnd %uint %13361 %uint_7 + %25268 = OpIMul %uint %13104 %25031 + %19942 = OpIAdd %uint %15085 %25268 + %12665 = OpUDiv %uint %19942 %uint_5 + %25089 = OpShiftLeftLogical %uint %12665 %uint_16 + %8216 = OpBitwiseOr %uint %13049 %25089 + %10130 = OpCompositeConstruct %v2uint %7577 %8216 + %24280 = OpBitwiseAnd %uint %23837 %15926 + %16388 = OpBitwiseAnd %uint %24280 %uint_1 + %19571 = OpBitwiseAnd %uint %24280 %uint_8 + %24849 = OpShiftLeftLogical %uint %19571 %uint_13 + %18017 = OpBitwiseOr %uint %16388 %24849 + %23222 = OpShiftRightLogical %uint %24280 %uint_6 + %25122 = OpBitwiseAnd %uint %23222 %uint_1 + %18767 = OpBitwiseAnd %uint %24280 %uint_512 + %22691 = OpShiftLeftLogical %uint %18767 %uint_7 + %17395 = OpBitwiseOr %uint %25122 %22691 + %20371 = OpCompositeConstruct %v2uint %18017 %17395 + %20771 = OpIMul %v2uint %20371 %1140 + %23866 = OpIAdd %v2uint %10130 %20771 + OpBranch %17145 + %14538 = OpLabel + %10720 = OpNot %uint %23837 + %15374 = OpBitwiseAnd %uint %10720 %uint_7 + %17724 = OpIMul %uint %6502 %15374 + %22001 = OpBitwiseAnd %uint %23837 %uint_7 + %20424 = OpIMul %uint %13104 %22001 + %19943 = OpIAdd %uint %17724 %20424 + %13050 = OpUDiv %uint %19943 %uint_7 + %23076 = OpShiftRightLogical %uint %10720 %uint_3 + %8805 = OpBitwiseAnd %uint %23076 %uint_7 + %15086 = OpIMul %uint %6502 %8805 + %13362 = OpShiftRightLogical %uint %23837 %uint_3 + %25032 = OpBitwiseAnd %uint %13362 %uint_7 + %25269 = OpIMul %uint %13104 %25032 + %19944 = OpIAdd %uint %15086 %25269 + %12666 = OpUDiv %uint %19944 %uint_7 + %8185 = OpShiftLeftLogical %uint %12666 %uint_16 + %7578 = OpBitwiseOr %uint %13050 %8185 + %21961 = OpShiftRightLogical %uint %10720 %uint_6 + %17619 = OpBitwiseAnd %uint %21961 %uint_7 + %15087 = OpIMul %uint %6502 %17619 + %13363 = OpShiftRightLogical %uint %23837 %uint_6 + %25033 = OpBitwiseAnd %uint %13363 %uint_7 + %25270 = OpIMul %uint %13104 %25033 + %19945 = OpIAdd %uint %15087 %25270 + %13051 = OpUDiv %uint %19945 %uint_7 + %23077 = OpShiftRightLogical %uint %10720 %uint_9 + %8806 = OpBitwiseAnd %uint %23077 %uint_7 + %15088 = OpIMul %uint %6502 %8806 + %13364 = OpShiftRightLogical %uint %23837 %uint_9 + %25034 = OpBitwiseAnd %uint %13364 %uint_7 + %25271 = OpIMul %uint %13104 %25034 + %19946 = OpIAdd %uint %15088 %25271 + %12667 = OpUDiv %uint %19946 %uint_7 + %25090 = OpShiftLeftLogical %uint %12667 %uint_16 + %9166 = OpBitwiseOr %uint %13051 %25090 + %21481 = OpCompositeConstruct %v2uint %7578 %9166 + OpBranch %17145 + %17145 = OpLabel + %20520 = OpPhi %v2uint %23866 %10660 %21481 %14538 + %16623 = OpCompositeExtract %uint %15657 1 + OpSelectionMerge %19334 None + OpBranchConditional %20100 %10661 %14539 + %10661 = OpLabel + %17678 = OpBitwiseAnd %uint %16623 %uint_1170 + %23969 = OpBitwiseAnd %uint %16623 %uint_2340 + %21865 = OpShiftRightLogical %uint %23969 %uint_1 + %8154 = OpBitwiseAnd %uint %17678 %21865 + %24630 = OpShiftLeftLogical %uint %8154 %uint_1 + %22977 = OpShiftRightLogical %uint %8154 %uint_1 + %18825 = OpBitwiseOr %uint %24630 %22977 + %15927 = OpBitwiseOr %uint %8154 %18825 + %8472 = OpNot %uint %15927 + %10095 = OpBitwiseAnd %uint %16623 %8472 + %16313 = OpISub %uint %uint_2925 %10095 + %17429 = OpBitwiseAnd %uint %16313 %8472 + %17004 = OpBitwiseAnd %uint %17429 %uint_7 + %13690 = OpIMul %uint %12929 %17004 + %22002 = OpBitwiseAnd %uint %10095 %uint_7 + %20425 = OpIMul %uint %13105 %22002 + %19947 = OpIAdd %uint %13690 %20425 + %13052 = OpUDiv %uint %19947 %uint_5 + %23078 = OpShiftRightLogical %uint %17429 %uint_3 + %8807 = OpBitwiseAnd %uint %23078 %uint_7 + %15089 = OpIMul %uint %12929 %8807 + %13365 = OpShiftRightLogical %uint %10095 %uint_3 + %25035 = OpBitwiseAnd %uint %13365 %uint_7 + %25272 = OpIMul %uint %13105 %25035 + %19948 = OpIAdd %uint %15089 %25272 + %12668 = OpUDiv %uint %19948 %uint_5 + %8186 = OpShiftLeftLogical %uint %12668 %uint_16 + %7579 = OpBitwiseOr %uint %13052 %8186 + %21962 = OpShiftRightLogical %uint %17429 %uint_6 + %17620 = OpBitwiseAnd %uint %21962 %uint_7 + %15090 = OpIMul %uint %12929 %17620 + %13366 = OpShiftRightLogical %uint %10095 %uint_6 + %25036 = OpBitwiseAnd %uint %13366 %uint_7 + %25273 = OpIMul %uint %13105 %25036 + %19949 = OpIAdd %uint %15090 %25273 + %13053 = OpUDiv %uint %19949 %uint_5 + %23079 = OpShiftRightLogical %uint %17429 %uint_9 + %8808 = OpBitwiseAnd %uint %23079 %uint_7 + %15091 = OpIMul %uint %12929 %8808 + %13367 = OpShiftRightLogical %uint %10095 %uint_9 + %25037 = OpBitwiseAnd %uint %13367 %uint_7 + %25274 = OpIMul %uint %13105 %25037 + %19950 = OpIAdd %uint %15091 %25274 + %12669 = OpUDiv %uint %19950 %uint_5 + %25091 = OpShiftLeftLogical %uint %12669 %uint_16 + %8217 = OpBitwiseOr %uint %13053 %25091 + %10131 = OpCompositeConstruct %v2uint %7579 %8217 + %24281 = OpBitwiseAnd %uint %16623 %15927 + %16389 = OpBitwiseAnd %uint %24281 %uint_1 + %19572 = OpBitwiseAnd %uint %24281 %uint_8 + %24850 = OpShiftLeftLogical %uint %19572 %uint_13 + %18018 = OpBitwiseOr %uint %16389 %24850 + %23223 = OpShiftRightLogical %uint %24281 %uint_6 + %25123 = OpBitwiseAnd %uint %23223 %uint_1 + %18768 = OpBitwiseAnd %uint %24281 %uint_512 + %22692 = OpShiftLeftLogical %uint %18768 %uint_7 + %17396 = OpBitwiseOr %uint %25123 %22692 + %20372 = OpCompositeConstruct %v2uint %18018 %17396 + %20772 = OpIMul %v2uint %20372 %1140 + %23867 = OpIAdd %v2uint %10131 %20772 + OpBranch %19334 + %14539 = OpLabel + %10721 = OpNot %uint %16623 + %15376 = OpBitwiseAnd %uint %10721 %uint_7 + %17725 = OpIMul %uint %12929 %15376 + %22003 = OpBitwiseAnd %uint %16623 %uint_7 + %20426 = OpIMul %uint %13105 %22003 + %19951 = OpIAdd %uint %17725 %20426 + %13054 = OpUDiv %uint %19951 %uint_7 + %23080 = OpShiftRightLogical %uint %10721 %uint_3 + %8809 = OpBitwiseAnd %uint %23080 %uint_7 + %15092 = OpIMul %uint %12929 %8809 + %13368 = OpShiftRightLogical %uint %16623 %uint_3 + %25038 = OpBitwiseAnd %uint %13368 %uint_7 + %25275 = OpIMul %uint %13105 %25038 + %19952 = OpIAdd %uint %15092 %25275 + %12670 = OpUDiv %uint %19952 %uint_7 + %8187 = OpShiftLeftLogical %uint %12670 %uint_16 + %7580 = OpBitwiseOr %uint %13054 %8187 + %21963 = OpShiftRightLogical %uint %10721 %uint_6 + %17621 = OpBitwiseAnd %uint %21963 %uint_7 + %15093 = OpIMul %uint %12929 %17621 + %13369 = OpShiftRightLogical %uint %16623 %uint_6 + %25039 = OpBitwiseAnd %uint %13369 %uint_7 + %25276 = OpIMul %uint %13105 %25039 + %19953 = OpIAdd %uint %15093 %25276 + %13055 = OpUDiv %uint %19953 %uint_7 + %23081 = OpShiftRightLogical %uint %10721 %uint_9 + %8810 = OpBitwiseAnd %uint %23081 %uint_7 + %15094 = OpIMul %uint %12929 %8810 + %13370 = OpShiftRightLogical %uint %16623 %uint_9 + %25040 = OpBitwiseAnd %uint %13370 %uint_7 + %25277 = OpIMul %uint %13105 %25040 + %19954 = OpIAdd %uint %15094 %25277 + %12671 = OpUDiv %uint %19954 %uint_7 + %25092 = OpShiftLeftLogical %uint %12671 %uint_16 + %9167 = OpBitwiseOr %uint %13055 %25092 + %21482 = OpCompositeConstruct %v2uint %7580 %9167 + OpBranch %19334 + %19334 = OpLabel + %18746 = OpPhi %v2uint %23867 %10661 %21482 %14539 + %7888 = OpShiftLeftLogical %v2uint %18746 %1975 + %11596 = OpBitwiseOr %v2uint %20520 %7888 + %13661 = OpCompositeExtract %uint %15657 2 + OpSelectionMerge %17146 None + OpBranchConditional %20101 %10662 %14540 + %10662 = OpLabel + %17679 = OpBitwiseAnd %uint %13661 %uint_1170 + %23970 = OpBitwiseAnd %uint %13661 %uint_2340 + %21866 = OpShiftRightLogical %uint %23970 %uint_1 + %8155 = OpBitwiseAnd %uint %17679 %21866 + %24631 = OpShiftLeftLogical %uint %8155 %uint_1 + %22978 = OpShiftRightLogical %uint %8155 %uint_1 + %18826 = OpBitwiseOr %uint %24631 %22978 + %15928 = OpBitwiseOr %uint %8155 %18826 + %8473 = OpNot %uint %15928 + %10096 = OpBitwiseAnd %uint %13661 %8473 + %16314 = OpISub %uint %uint_2925 %10096 + %17430 = OpBitwiseAnd %uint %16314 %8473 + %17005 = OpBitwiseAnd %uint %17430 %uint_7 + %13691 = OpIMul %uint %12930 %17005 + %22004 = OpBitwiseAnd %uint %10096 %uint_7 + %20427 = OpIMul %uint %13107 %22004 + %19955 = OpIAdd %uint %13691 %20427 + %13056 = OpUDiv %uint %19955 %uint_5 + %23082 = OpShiftRightLogical %uint %17430 %uint_3 + %8811 = OpBitwiseAnd %uint %23082 %uint_7 + %15095 = OpIMul %uint %12930 %8811 + %13371 = OpShiftRightLogical %uint %10096 %uint_3 + %25041 = OpBitwiseAnd %uint %13371 %uint_7 + %25278 = OpIMul %uint %13107 %25041 + %19956 = OpIAdd %uint %15095 %25278 + %12672 = OpUDiv %uint %19956 %uint_5 + %8188 = OpShiftLeftLogical %uint %12672 %uint_16 + %7581 = OpBitwiseOr %uint %13056 %8188 + %21964 = OpShiftRightLogical %uint %17430 %uint_6 + %17622 = OpBitwiseAnd %uint %21964 %uint_7 + %15096 = OpIMul %uint %12930 %17622 + %13372 = OpShiftRightLogical %uint %10096 %uint_6 + %25042 = OpBitwiseAnd %uint %13372 %uint_7 + %25279 = OpIMul %uint %13107 %25042 + %19957 = OpIAdd %uint %15096 %25279 + %13057 = OpUDiv %uint %19957 %uint_5 + %23083 = OpShiftRightLogical %uint %17430 %uint_9 + %8812 = OpBitwiseAnd %uint %23083 %uint_7 + %15097 = OpIMul %uint %12930 %8812 + %13373 = OpShiftRightLogical %uint %10096 %uint_9 + %25043 = OpBitwiseAnd %uint %13373 %uint_7 + %25280 = OpIMul %uint %13107 %25043 + %19958 = OpIAdd %uint %15097 %25280 + %12673 = OpUDiv %uint %19958 %uint_5 + %25093 = OpShiftLeftLogical %uint %12673 %uint_16 + %8218 = OpBitwiseOr %uint %13057 %25093 + %10132 = OpCompositeConstruct %v2uint %7581 %8218 + %24282 = OpBitwiseAnd %uint %13661 %15928 + %16390 = OpBitwiseAnd %uint %24282 %uint_1 + %19573 = OpBitwiseAnd %uint %24282 %uint_8 + %24851 = OpShiftLeftLogical %uint %19573 %uint_13 + %18019 = OpBitwiseOr %uint %16390 %24851 + %23224 = OpShiftRightLogical %uint %24282 %uint_6 + %25124 = OpBitwiseAnd %uint %23224 %uint_1 + %18769 = OpBitwiseAnd %uint %24282 %uint_512 + %22693 = OpShiftLeftLogical %uint %18769 %uint_7 + %17397 = OpBitwiseOr %uint %25124 %22693 + %20373 = OpCompositeConstruct %v2uint %18019 %17397 + %20773 = OpIMul %v2uint %20373 %1140 + %23868 = OpIAdd %v2uint %10132 %20773 + OpBranch %17146 + %14540 = OpLabel + %10722 = OpNot %uint %13661 + %15377 = OpBitwiseAnd %uint %10722 %uint_7 + %17726 = OpIMul %uint %12930 %15377 + %22005 = OpBitwiseAnd %uint %13661 %uint_7 + %20428 = OpIMul %uint %13107 %22005 + %19959 = OpIAdd %uint %17726 %20428 + %13058 = OpUDiv %uint %19959 %uint_7 + %23084 = OpShiftRightLogical %uint %10722 %uint_3 + %8813 = OpBitwiseAnd %uint %23084 %uint_7 + %15098 = OpIMul %uint %12930 %8813 + %13374 = OpShiftRightLogical %uint %13661 %uint_3 + %25044 = OpBitwiseAnd %uint %13374 %uint_7 + %25281 = OpIMul %uint %13107 %25044 + %19960 = OpIAdd %uint %15098 %25281 + %12674 = OpUDiv %uint %19960 %uint_7 + %8189 = OpShiftLeftLogical %uint %12674 %uint_16 + %7582 = OpBitwiseOr %uint %13058 %8189 + %21965 = OpShiftRightLogical %uint %10722 %uint_6 + %17623 = OpBitwiseAnd %uint %21965 %uint_7 + %15099 = OpIMul %uint %12930 %17623 + %13375 = OpShiftRightLogical %uint %13661 %uint_6 + %25045 = OpBitwiseAnd %uint %13375 %uint_7 + %25282 = OpIMul %uint %13107 %25045 + %19961 = OpIAdd %uint %15099 %25282 + %13059 = OpUDiv %uint %19961 %uint_7 + %23085 = OpShiftRightLogical %uint %10722 %uint_9 + %8814 = OpBitwiseAnd %uint %23085 %uint_7 + %15100 = OpIMul %uint %12930 %8814 + %13376 = OpShiftRightLogical %uint %13661 %uint_9 + %25046 = OpBitwiseAnd %uint %13376 %uint_7 + %25283 = OpIMul %uint %13107 %25046 + %19962 = OpIAdd %uint %15100 %25283 + %12675 = OpUDiv %uint %19962 %uint_7 + %25094 = OpShiftLeftLogical %uint %12675 %uint_16 + %9168 = OpBitwiseOr %uint %13059 %25094 + %21483 = OpCompositeConstruct %v2uint %7582 %9168 + OpBranch %17146 + %17146 = OpLabel + %20521 = OpPhi %v2uint %23868 %10662 %21483 %14540 + %16624 = OpCompositeExtract %uint %15657 3 + OpSelectionMerge %19335 None + OpBranchConditional %20102 %10663 %14541 + %10663 = OpLabel + %17680 = OpBitwiseAnd %uint %16624 %uint_1170 + %23971 = OpBitwiseAnd %uint %16624 %uint_2340 + %21867 = OpShiftRightLogical %uint %23971 %uint_1 + %8156 = OpBitwiseAnd %uint %17680 %21867 + %24632 = OpShiftLeftLogical %uint %8156 %uint_1 + %22979 = OpShiftRightLogical %uint %8156 %uint_1 + %18827 = OpBitwiseOr %uint %24632 %22979 + %15929 = OpBitwiseOr %uint %8156 %18827 + %8474 = OpNot %uint %15929 + %10097 = OpBitwiseAnd %uint %16624 %8474 + %16315 = OpISub %uint %uint_2925 %10097 + %17431 = OpBitwiseAnd %uint %16315 %8474 + %17006 = OpBitwiseAnd %uint %17431 %uint_7 + %13692 = OpIMul %uint %12931 %17006 + %22006 = OpBitwiseAnd %uint %10097 %uint_7 + %20429 = OpIMul %uint %13108 %22006 + %19963 = OpIAdd %uint %13692 %20429 + %13060 = OpUDiv %uint %19963 %uint_5 + %23086 = OpShiftRightLogical %uint %17431 %uint_3 + %8815 = OpBitwiseAnd %uint %23086 %uint_7 + %15101 = OpIMul %uint %12931 %8815 + %13377 = OpShiftRightLogical %uint %10097 %uint_3 + %25047 = OpBitwiseAnd %uint %13377 %uint_7 + %25284 = OpIMul %uint %13108 %25047 + %19964 = OpIAdd %uint %15101 %25284 + %12676 = OpUDiv %uint %19964 %uint_5 + %8190 = OpShiftLeftLogical %uint %12676 %uint_16 + %7583 = OpBitwiseOr %uint %13060 %8190 + %21966 = OpShiftRightLogical %uint %17431 %uint_6 + %17624 = OpBitwiseAnd %uint %21966 %uint_7 + %15102 = OpIMul %uint %12931 %17624 + %13378 = OpShiftRightLogical %uint %10097 %uint_6 + %25048 = OpBitwiseAnd %uint %13378 %uint_7 + %25285 = OpIMul %uint %13108 %25048 + %19965 = OpIAdd %uint %15102 %25285 + %13061 = OpUDiv %uint %19965 %uint_5 + %23087 = OpShiftRightLogical %uint %17431 %uint_9 + %8816 = OpBitwiseAnd %uint %23087 %uint_7 + %15103 = OpIMul %uint %12931 %8816 + %13379 = OpShiftRightLogical %uint %10097 %uint_9 + %25049 = OpBitwiseAnd %uint %13379 %uint_7 + %25286 = OpIMul %uint %13108 %25049 + %19966 = OpIAdd %uint %15103 %25286 + %12677 = OpUDiv %uint %19966 %uint_5 + %25095 = OpShiftLeftLogical %uint %12677 %uint_16 + %8219 = OpBitwiseOr %uint %13061 %25095 + %10133 = OpCompositeConstruct %v2uint %7583 %8219 + %24283 = OpBitwiseAnd %uint %16624 %15929 + %16391 = OpBitwiseAnd %uint %24283 %uint_1 + %19574 = OpBitwiseAnd %uint %24283 %uint_8 + %24852 = OpShiftLeftLogical %uint %19574 %uint_13 + %18020 = OpBitwiseOr %uint %16391 %24852 + %23225 = OpShiftRightLogical %uint %24283 %uint_6 + %25125 = OpBitwiseAnd %uint %23225 %uint_1 + %18770 = OpBitwiseAnd %uint %24283 %uint_512 + %22694 = OpShiftLeftLogical %uint %18770 %uint_7 + %17398 = OpBitwiseOr %uint %25125 %22694 + %20374 = OpCompositeConstruct %v2uint %18020 %17398 + %20774 = OpIMul %v2uint %20374 %1140 + %23869 = OpIAdd %v2uint %10133 %20774 + OpBranch %19335 + %14541 = OpLabel + %10723 = OpNot %uint %16624 + %15378 = OpBitwiseAnd %uint %10723 %uint_7 + %17727 = OpIMul %uint %12931 %15378 + %22007 = OpBitwiseAnd %uint %16624 %uint_7 + %20430 = OpIMul %uint %13108 %22007 + %19967 = OpIAdd %uint %17727 %20430 + %13062 = OpUDiv %uint %19967 %uint_7 + %23088 = OpShiftRightLogical %uint %10723 %uint_3 + %8817 = OpBitwiseAnd %uint %23088 %uint_7 + %15104 = OpIMul %uint %12931 %8817 + %13380 = OpShiftRightLogical %uint %16624 %uint_3 + %25050 = OpBitwiseAnd %uint %13380 %uint_7 + %25287 = OpIMul %uint %13108 %25050 + %19968 = OpIAdd %uint %15104 %25287 + %12678 = OpUDiv %uint %19968 %uint_7 + %8191 = OpShiftLeftLogical %uint %12678 %uint_16 + %7584 = OpBitwiseOr %uint %13062 %8191 + %21967 = OpShiftRightLogical %uint %10723 %uint_6 + %17625 = OpBitwiseAnd %uint %21967 %uint_7 + %15105 = OpIMul %uint %12931 %17625 + %13381 = OpShiftRightLogical %uint %16624 %uint_6 + %25051 = OpBitwiseAnd %uint %13381 %uint_7 + %25288 = OpIMul %uint %13108 %25051 + %19969 = OpIAdd %uint %15105 %25288 + %13063 = OpUDiv %uint %19969 %uint_7 + %23089 = OpShiftRightLogical %uint %10723 %uint_9 + %8818 = OpBitwiseAnd %uint %23089 %uint_7 + %15106 = OpIMul %uint %12931 %8818 + %13382 = OpShiftRightLogical %uint %16624 %uint_9 + %25052 = OpBitwiseAnd %uint %13382 %uint_7 + %25289 = OpIMul %uint %13108 %25052 + %19970 = OpIAdd %uint %15106 %25289 + %12679 = OpUDiv %uint %19970 %uint_7 + %25096 = OpShiftLeftLogical %uint %12679 %uint_16 + %9169 = OpBitwiseOr %uint %13063 %25096 + %21484 = OpCompositeConstruct %v2uint %7584 %9169 + OpBranch %19335 + %19335 = OpLabel + %18747 = OpPhi %v2uint %23869 %10663 %21484 %14541 + %7889 = OpShiftLeftLogical %v2uint %18747 %1975 + %8444 = OpBitwiseOr %v2uint %20521 %7889 + %20104 = OpCompositeExtract %uint %11596 0 + %23733 = OpCompositeExtract %uint %11596 1 + %7646 = OpCompositeExtract %uint %8444 0 + %7532 = OpCompositeExtract %uint %8444 1 + %18263 = OpCompositeConstruct %v4uint %20104 %23733 %7646 %7532 + %11979 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13358 + OpStore %11979 %18263 + OpBranch %18021 + %18021 = OpLabel + OpBranch %7205 + %7205 = OpLabel + OpBranch %7206 + %7206 = OpLabel + OpBranch %14903 + %14903 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_dxn_rg8_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000062CA, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x000009E9, 0x00249249, 0x0004002B, 0x0000000B, 0x000009C8, 0x00492492, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000986, 0x00924924, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000944, 0x00DB6DB6, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, + 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, + 0x0004002B, 0x0000000B, 0x0000003A, 0x00000492, 0x0004002B, 0x0000000B, 0x0000022D, 0x00000924, + 0x0004002B, 0x0000000B, 0x00000908, 0x00000B6D, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, + 0x0004002B, 0x0000000B, 0x00000447, 0x00000200, 0x0004002B, 0x0000000B, 0x00000144, 0x000000FF, + 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, + 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, + 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, + 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, + 0x00000009, 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, + 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, + 0x00000A1B, 0x00000A0D, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0006002C, 0x00000014, 0x00000A3C, 0x00000A10, 0x00000A10, 0x00000A0A, 0x0003001D, 0x000007DC, + 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, + 0x0004003B, 0x00000A32, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, + 0x0007002C, 0x00000017, 0x0000007D, 0x00000A0A, 0x00000A22, 0x00000A0A, 0x00000A22, 0x0003001D, + 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A33, 0x00000002, + 0x000007B5, 0x0004003B, 0x00000A33, 0x0000140E, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A2E, + 0x0000000C, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0006002C, 0x00000014, 0x00000BC3, + 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, + 0x0000000B, 0x00000A2B, 0x0000000B, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, + 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, + 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, + 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0007002C, + 0x00000017, 0x0000064B, 0x00000144, 0x00000144, 0x00000144, 0x00000144, 0x0005002C, 0x00000011, + 0x00000474, 0x00000144, 0x00000144, 0x0005002C, 0x00000011, 0x000007B7, 0x00000A22, 0x00000A22, + 0x0007002C, 0x00000017, 0x00000215, 0x00000A2E, 0x00000A2E, 0x00000A2E, 0x00000A2E, 0x00050036, + 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00003A37, + 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, + 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, + 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, + 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, + 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, + 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, + 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, + 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, + 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, + 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, + 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, + 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004EBE, 0x00000CE9, 0x00000A1D, 0x0004003D, + 0x0000000B, 0x0000578C, 0x00004EBE, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A20, + 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, + 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A1B, 0x0007004F, 0x00000011, 0x000042F0, + 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, + 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, + 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000036C2, 0x00000002, 0x000400FA, + 0x00006067, 0x000055E8, 0x000036C2, 0x000200F8, 0x000055E8, 0x000200F9, 0x00003A37, 0x000200F8, + 0x000036C2, 0x000500C4, 0x00000014, 0x000043C0, 0x0000538B, 0x00000A3C, 0x0004007C, 0x00000016, + 0x00003C81, 0x000043C0, 0x00050051, 0x0000000C, 0x000047A0, 0x00003C81, 0x00000000, 0x00050084, + 0x0000000C, 0x00002492, 0x000047A0, 0x00000A11, 0x00050051, 0x0000000C, 0x000018DA, 0x00003C81, + 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x000019C2, 0x00050084, 0x0000000C, 0x00002C0F, + 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00003C81, 0x00000001, 0x00050080, + 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x0000578C, + 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, + 0x00002492, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, + 0x00002375, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x00002DCE, 0x00002375, 0x00000A16, + 0x000500C2, 0x0000000B, 0x00001B41, 0x0000578C, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, + 0x000400FA, 0x00004376, 0x00005768, 0x00004E29, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, + 0x00000002, 0x000400FA, 0x00004384, 0x0000537D, 0x000018D9, 0x000200F8, 0x0000537D, 0x0004007C, + 0x00000016, 0x00002970, 0x0000538B, 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, + 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, + 0x00002970, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, + 0x0000000B, 0x00005B4D, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, + 0x00050084, 0x0000000C, 0x00005321, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, + 0x000024FD, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, + 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, + 0x00050051, 0x0000000C, 0x00006242, 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, + 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, + 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A28, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, + 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, + 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, + 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, + 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A28, 0x000500C3, + 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, + 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, + 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, + 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, + 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, + 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A28, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, + 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, + 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, + 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, + 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, + 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, + 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, + 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, + 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, + 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, + 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, + 0x000042C3, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FE, 0x000042C3, 0x00000A1A, + 0x00050051, 0x0000000C, 0x00002748, 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405D, + 0x00002748, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00005788, 0x00000A19, 0x0004007C, + 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005347, 0x0000405D, 0x000018AB, + 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FE, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, + 0x00003F5E, 0x00000A2B, 0x000500C7, 0x0000000C, 0x00002AB6, 0x000042C3, 0x00000A20, 0x000500C7, + 0x0000000C, 0x00003139, 0x00002748, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, + 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, + 0x000018E7, 0x00004397, 0x00000A16, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, + 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, + 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, + 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, + 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, + 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, + 0x00002748, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, + 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, + 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, + 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002748, 0x00000A23, + 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, + 0x000042C3, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, + 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, + 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, + 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, + 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, + 0x0000537D, 0x00002F42, 0x000018D9, 0x000200F9, 0x00005F43, 0x000200F8, 0x00004E29, 0x0004007C, + 0x00000016, 0x00005F7F, 0x0000538B, 0x00050051, 0x0000000C, 0x000022D6, 0x00005F7F, 0x00000000, + 0x00050084, 0x0000000C, 0x00002493, 0x000022D6, 0x00000A3B, 0x00050051, 0x0000000C, 0x000018DB, + 0x00005F7F, 0x00000002, 0x0004007C, 0x0000000C, 0x000038AA, 0x00005789, 0x00050084, 0x0000000C, + 0x00002C10, 0x000018DB, 0x000038AA, 0x00050051, 0x0000000C, 0x000044BF, 0x00005F7F, 0x00000001, + 0x00050080, 0x0000000C, 0x000056D5, 0x00002C10, 0x000044BF, 0x0004007C, 0x0000000C, 0x00005786, + 0x00005788, 0x00050084, 0x0000000C, 0x00001E9F, 0x000056D5, 0x00005786, 0x00050080, 0x0000000C, + 0x00001F30, 0x00002493, 0x00001E9F, 0x000200F9, 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, + 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, 0x00001F30, 0x00004E29, 0x0004007C, 0x0000000C, + 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, + 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, + 0x00060041, 0x00000294, 0x00004315, 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, + 0x00001CAA, 0x00004315, 0x000500AA, 0x00000009, 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, + 0x00000009, 0x00005376, 0x000061E2, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, + 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, + 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, + 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, + 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, + 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, + 0x00000017, 0x00005879, 0x00001CAA, 0x00005F43, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, + 0x00004CB6, 0x000061E2, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, + 0x000300F7, 0x00003450, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x00003450, 0x000200F8, + 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, + 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, + 0x000200F9, 0x00003450, 0x000200F8, 0x00003450, 0x000700F5, 0x00000017, 0x00005654, 0x00005879, + 0x00003463, 0x000029E8, 0x00002B38, 0x000600A9, 0x0000000B, 0x00002E64, 0x00004376, 0x00000A10, + 0x00000A0D, 0x00050080, 0x0000000B, 0x00002C4B, 0x00005665, 0x00002E64, 0x00060041, 0x00000294, + 0x00004766, 0x0000107A, 0x00000A0B, 0x00002C4B, 0x0004003D, 0x00000017, 0x000019B2, 0x00004766, + 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, + 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, + 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, + 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, + 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, + 0x00002AAC, 0x000019B2, 0x00003450, 0x00003FF9, 0x00002958, 0x000300F7, 0x00002DA2, 0x00000000, + 0x000400FA, 0x00003B23, 0x00002B39, 0x00002DA2, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, + 0x00005E18, 0x00002AAC, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, + 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002DA2, 0x000200F8, + 0x00002DA2, 0x000700F5, 0x00000017, 0x00004D8D, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, + 0x0009004F, 0x00000017, 0x00005675, 0x00005654, 0x00005654, 0x00000000, 0x00000000, 0x00000002, + 0x00000002, 0x000500C2, 0x00000017, 0x00003080, 0x00005675, 0x0000007D, 0x000500C7, 0x00000017, + 0x00002376, 0x00003080, 0x0000064B, 0x0009004F, 0x00000017, 0x000042A8, 0x00004D8D, 0x00004D8D, + 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x000500C2, 0x00000017, 0x00001DD8, 0x000042A8, + 0x0000007D, 0x000500C7, 0x00000017, 0x000019B9, 0x00001DD8, 0x0000064B, 0x00050051, 0x0000000B, + 0x00004641, 0x00005654, 0x00000000, 0x00050051, 0x0000000B, 0x00001880, 0x00005654, 0x00000002, + 0x00050051, 0x0000000B, 0x00001DD9, 0x00004D8D, 0x00000000, 0x00050051, 0x0000000B, 0x000026FC, + 0x00004D8D, 0x00000002, 0x00070050, 0x00000017, 0x00003C0F, 0x00004641, 0x00001880, 0x00001DD9, + 0x000026FC, 0x000500C2, 0x00000017, 0x0000278A, 0x00003C0F, 0x000002ED, 0x00050051, 0x0000000B, + 0x00005D24, 0x00005654, 0x00000001, 0x00050051, 0x0000000B, 0x00005FDB, 0x00005654, 0x00000003, + 0x00050051, 0x0000000B, 0x00001DDA, 0x00004D8D, 0x00000001, 0x00050051, 0x0000000B, 0x0000275B, + 0x00004D8D, 0x00000003, 0x00070050, 0x00000017, 0x00004137, 0x00005D24, 0x00005FDB, 0x00001DDA, + 0x0000275B, 0x000500C7, 0x00000017, 0x000021E7, 0x00004137, 0x0000064B, 0x000500C4, 0x00000017, + 0x00004E4B, 0x000021E7, 0x000002ED, 0x000500C5, 0x00000017, 0x00003F71, 0x0000278A, 0x00004E4B, + 0x00050051, 0x0000000B, 0x00004E80, 0x00003F71, 0x00000000, 0x00050051, 0x0000000B, 0x00001966, + 0x00002376, 0x00000000, 0x00050051, 0x0000000B, 0x00003330, 0x00002376, 0x00000001, 0x000500B2, + 0x00000009, 0x00004E83, 0x00001966, 0x00003330, 0x000300F7, 0x00002DC8, 0x00000000, 0x000400FA, + 0x00004E83, 0x00002990, 0x000055A0, 0x000200F8, 0x00002990, 0x000500C7, 0x0000000B, 0x000044F9, + 0x00004E80, 0x000009C8, 0x000500C7, 0x0000000B, 0x00005D8C, 0x00004E80, 0x00000986, 0x000500C2, + 0x0000000B, 0x00005554, 0x00005D8C, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FC5, 0x000044F9, + 0x00005554, 0x000500C4, 0x0000000B, 0x00006021, 0x00001FC5, 0x00000A0D, 0x000500C2, 0x0000000B, + 0x000059AC, 0x00001FC5, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004969, 0x00006021, 0x000059AC, + 0x000500C5, 0x0000000B, 0x00003EB1, 0x00001FC5, 0x00004969, 0x000500C7, 0x0000000B, 0x00004785, + 0x00004E80, 0x000009E9, 0x000500C5, 0x0000000B, 0x0000395D, 0x00004785, 0x00000944, 0x000500C7, + 0x0000000B, 0x00004FB3, 0x0000395D, 0x00003EB1, 0x000500C2, 0x0000000B, 0x0000503B, 0x000044F9, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000615A, 0x00004785, 0x0000503B, 0x000500C2, 0x0000000B, + 0x000055A2, 0x00005D8C, 0x00000A10, 0x000500C5, 0x0000000B, 0x00005892, 0x0000615A, 0x000055A2, + 0x000500C6, 0x0000000B, 0x00001E29, 0x00005892, 0x000009E9, 0x000400C8, 0x0000000B, 0x00002544, + 0x0000503B, 0x000500C7, 0x0000000B, 0x0000391D, 0x00004785, 0x00002544, 0x000400C8, 0x0000000B, + 0x000020E9, 0x000055A2, 0x000500C7, 0x0000000B, 0x00002C8F, 0x0000391D, 0x000020E9, 0x000500C5, + 0x0000000B, 0x00001A8F, 0x00004E80, 0x00001E29, 0x00050082, 0x0000000B, 0x00004C35, 0x00001A8F, + 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A17, 0x00004C35, 0x00002C8F, 0x000500C4, 0x0000000B, + 0x00004734, 0x00002C8F, 0x00000A10, 0x000500C5, 0x0000000B, 0x00003BFA, 0x00003A17, 0x00004734, + 0x000400C8, 0x0000000B, 0x00002F7A, 0x00003EB1, 0x000500C7, 0x0000000B, 0x00004850, 0x00003BFA, + 0x00002F7A, 0x000500C5, 0x0000000B, 0x0000186C, 0x00004850, 0x00004FB3, 0x000200F9, 0x00002DC8, + 0x000200F8, 0x000055A0, 0x000500C7, 0x0000000B, 0x00004E6F, 0x00004E80, 0x000009E9, 0x000500C7, + 0x0000000B, 0x00005D66, 0x00004E80, 0x000009C8, 0x000500C2, 0x0000000B, 0x000056E7, 0x00005D66, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x00005DC0, 0x00004E6F, 0x000056E7, 0x000500C7, 0x0000000B, + 0x00004C8F, 0x00004E80, 0x00000986, 0x000500C2, 0x0000000B, 0x00005087, 0x00004C8F, 0x00000A10, + 0x000500C5, 0x0000000B, 0x00005EDF, 0x00005DC0, 0x00005087, 0x000500C6, 0x0000000B, 0x00001E2A, + 0x00005EDF, 0x000009E9, 0x000400C8, 0x0000000B, 0x00002545, 0x000056E7, 0x000500C7, 0x0000000B, + 0x0000391E, 0x00004E6F, 0x00002545, 0x000400C8, 0x0000000B, 0x000020EA, 0x00005087, 0x000500C7, + 0x0000000B, 0x00002C90, 0x0000391E, 0x000020EA, 0x000500C5, 0x0000000B, 0x00001A90, 0x00004E80, + 0x00001E2A, 0x00050082, 0x0000000B, 0x00004C36, 0x00001A90, 0x000009E9, 0x000500C5, 0x0000000B, + 0x00003A18, 0x00004C36, 0x00002C90, 0x000500C4, 0x0000000B, 0x000046E8, 0x00002C90, 0x00000A0D, + 0x000500C5, 0x0000000B, 0x00003E88, 0x00003A18, 0x000046E8, 0x000500C4, 0x0000000B, 0x00001FB6, + 0x00002C90, 0x00000A10, 0x000500C5, 0x0000000B, 0x00001E80, 0x00003E88, 0x00001FB6, 0x000200F9, + 0x00002DC8, 0x000200F8, 0x00002DC8, 0x000700F5, 0x0000000B, 0x000043D0, 0x0000186C, 0x00002990, + 0x00001E80, 0x000055A0, 0x00050051, 0x0000000B, 0x00005A0E, 0x00003F71, 0x00000001, 0x00050051, + 0x0000000B, 0x00003281, 0x00002376, 0x00000002, 0x00050051, 0x0000000B, 0x00003331, 0x00002376, + 0x00000003, 0x000500B2, 0x00000009, 0x00004E84, 0x00003281, 0x00003331, 0x000300F7, 0x00002DC9, + 0x00000000, 0x000400FA, 0x00004E84, 0x00002991, 0x000055A1, 0x000200F8, 0x00002991, 0x000500C7, + 0x0000000B, 0x000044FA, 0x00005A0E, 0x000009C8, 0x000500C7, 0x0000000B, 0x00005D8D, 0x00005A0E, + 0x00000986, 0x000500C2, 0x0000000B, 0x00005555, 0x00005D8D, 0x00000A0D, 0x000500C7, 0x0000000B, + 0x00001FC6, 0x000044FA, 0x00005555, 0x000500C4, 0x0000000B, 0x00006022, 0x00001FC6, 0x00000A0D, + 0x000500C2, 0x0000000B, 0x000059AD, 0x00001FC6, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000496B, + 0x00006022, 0x000059AD, 0x000500C5, 0x0000000B, 0x00003EB2, 0x00001FC6, 0x0000496B, 0x000500C7, + 0x0000000B, 0x00004786, 0x00005A0E, 0x000009E9, 0x000500C5, 0x0000000B, 0x0000395E, 0x00004786, + 0x00000944, 0x000500C7, 0x0000000B, 0x00004FB4, 0x0000395E, 0x00003EB2, 0x000500C2, 0x0000000B, + 0x0000503C, 0x000044FA, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000615B, 0x00004786, 0x0000503C, + 0x000500C2, 0x0000000B, 0x000055A3, 0x00005D8D, 0x00000A10, 0x000500C5, 0x0000000B, 0x00005893, + 0x0000615B, 0x000055A3, 0x000500C6, 0x0000000B, 0x00001E2B, 0x00005893, 0x000009E9, 0x000400C8, + 0x0000000B, 0x00002546, 0x0000503C, 0x000500C7, 0x0000000B, 0x0000391F, 0x00004786, 0x00002546, + 0x000400C8, 0x0000000B, 0x000020EB, 0x000055A3, 0x000500C7, 0x0000000B, 0x00002C91, 0x0000391F, + 0x000020EB, 0x000500C5, 0x0000000B, 0x00001A91, 0x00005A0E, 0x00001E2B, 0x00050082, 0x0000000B, + 0x00004C37, 0x00001A91, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A19, 0x00004C37, 0x00002C91, + 0x000500C4, 0x0000000B, 0x00004735, 0x00002C91, 0x00000A10, 0x000500C5, 0x0000000B, 0x00003BFB, + 0x00003A19, 0x00004735, 0x000400C8, 0x0000000B, 0x00002F7B, 0x00003EB2, 0x000500C7, 0x0000000B, + 0x00004851, 0x00003BFB, 0x00002F7B, 0x000500C5, 0x0000000B, 0x0000186D, 0x00004851, 0x00004FB4, + 0x000200F9, 0x00002DC9, 0x000200F8, 0x000055A1, 0x000500C7, 0x0000000B, 0x00004E70, 0x00005A0E, + 0x000009E9, 0x000500C7, 0x0000000B, 0x00005D67, 0x00005A0E, 0x000009C8, 0x000500C2, 0x0000000B, + 0x000056E8, 0x00005D67, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00005DC1, 0x00004E70, 0x000056E8, + 0x000500C7, 0x0000000B, 0x00004C90, 0x00005A0E, 0x00000986, 0x000500C2, 0x0000000B, 0x00005088, + 0x00004C90, 0x00000A10, 0x000500C5, 0x0000000B, 0x00005EE0, 0x00005DC1, 0x00005088, 0x000500C6, + 0x0000000B, 0x00001E2C, 0x00005EE0, 0x000009E9, 0x000400C8, 0x0000000B, 0x00002547, 0x000056E8, + 0x000500C7, 0x0000000B, 0x00003920, 0x00004E70, 0x00002547, 0x000400C8, 0x0000000B, 0x000020EC, + 0x00005088, 0x000500C7, 0x0000000B, 0x00002C92, 0x00003920, 0x000020EC, 0x000500C5, 0x0000000B, + 0x00001A92, 0x00005A0E, 0x00001E2C, 0x00050082, 0x0000000B, 0x00004C38, 0x00001A92, 0x000009E9, + 0x000500C5, 0x0000000B, 0x00003A1B, 0x00004C38, 0x00002C92, 0x000500C4, 0x0000000B, 0x000046E9, + 0x00002C92, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00003E89, 0x00003A1B, 0x000046E9, 0x000500C4, + 0x0000000B, 0x00001FB7, 0x00002C92, 0x00000A10, 0x000500C5, 0x0000000B, 0x00001E81, 0x00003E89, + 0x00001FB7, 0x000200F9, 0x00002DC9, 0x000200F8, 0x00002DC9, 0x000700F5, 0x0000000B, 0x000043D1, + 0x0000186D, 0x00002991, 0x00001E81, 0x000055A1, 0x00050051, 0x0000000B, 0x00005A0F, 0x00003F71, + 0x00000002, 0x00050051, 0x0000000B, 0x00003282, 0x000019B9, 0x00000000, 0x00050051, 0x0000000B, + 0x00003333, 0x000019B9, 0x00000001, 0x000500B2, 0x00000009, 0x00004E85, 0x00003282, 0x00003333, + 0x000300F7, 0x00002DCA, 0x00000000, 0x000400FA, 0x00004E85, 0x00002992, 0x000055A5, 0x000200F8, + 0x00002992, 0x000500C7, 0x0000000B, 0x000044FB, 0x00005A0F, 0x000009C8, 0x000500C7, 0x0000000B, + 0x00005D8E, 0x00005A0F, 0x00000986, 0x000500C2, 0x0000000B, 0x00005556, 0x00005D8E, 0x00000A0D, + 0x000500C7, 0x0000000B, 0x00001FC7, 0x000044FB, 0x00005556, 0x000500C4, 0x0000000B, 0x00006023, + 0x00001FC7, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059AE, 0x00001FC7, 0x00000A0D, 0x000500C5, + 0x0000000B, 0x0000496C, 0x00006023, 0x000059AE, 0x000500C5, 0x0000000B, 0x00003EB3, 0x00001FC7, + 0x0000496C, 0x000500C7, 0x0000000B, 0x00004787, 0x00005A0F, 0x000009E9, 0x000500C5, 0x0000000B, + 0x0000395F, 0x00004787, 0x00000944, 0x000500C7, 0x0000000B, 0x00004FB5, 0x0000395F, 0x00003EB3, + 0x000500C2, 0x0000000B, 0x0000503D, 0x000044FB, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000615C, + 0x00004787, 0x0000503D, 0x000500C2, 0x0000000B, 0x000055A4, 0x00005D8E, 0x00000A10, 0x000500C5, + 0x0000000B, 0x00005894, 0x0000615C, 0x000055A4, 0x000500C6, 0x0000000B, 0x00001E2D, 0x00005894, + 0x000009E9, 0x000400C8, 0x0000000B, 0x00002548, 0x0000503D, 0x000500C7, 0x0000000B, 0x00003921, + 0x00004787, 0x00002548, 0x000400C8, 0x0000000B, 0x000020ED, 0x000055A4, 0x000500C7, 0x0000000B, + 0x00002C93, 0x00003921, 0x000020ED, 0x000500C5, 0x0000000B, 0x00001A93, 0x00005A0F, 0x00001E2D, + 0x00050082, 0x0000000B, 0x00004C39, 0x00001A93, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A1C, + 0x00004C39, 0x00002C93, 0x000500C4, 0x0000000B, 0x00004736, 0x00002C93, 0x00000A10, 0x000500C5, + 0x0000000B, 0x00003BFC, 0x00003A1C, 0x00004736, 0x000400C8, 0x0000000B, 0x00002F7C, 0x00003EB3, + 0x000500C7, 0x0000000B, 0x00004852, 0x00003BFC, 0x00002F7C, 0x000500C5, 0x0000000B, 0x0000186E, + 0x00004852, 0x00004FB5, 0x000200F9, 0x00002DCA, 0x000200F8, 0x000055A5, 0x000500C7, 0x0000000B, + 0x00004E71, 0x00005A0F, 0x000009E9, 0x000500C7, 0x0000000B, 0x00005D68, 0x00005A0F, 0x000009C8, + 0x000500C2, 0x0000000B, 0x000056E9, 0x00005D68, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00005DC2, + 0x00004E71, 0x000056E9, 0x000500C7, 0x0000000B, 0x00004C91, 0x00005A0F, 0x00000986, 0x000500C2, + 0x0000000B, 0x00005089, 0x00004C91, 0x00000A10, 0x000500C5, 0x0000000B, 0x00005EE1, 0x00005DC2, + 0x00005089, 0x000500C6, 0x0000000B, 0x00001E2E, 0x00005EE1, 0x000009E9, 0x000400C8, 0x0000000B, + 0x00002549, 0x000056E9, 0x000500C7, 0x0000000B, 0x00003922, 0x00004E71, 0x00002549, 0x000400C8, + 0x0000000B, 0x000020EE, 0x00005089, 0x000500C7, 0x0000000B, 0x00002C94, 0x00003922, 0x000020EE, + 0x000500C5, 0x0000000B, 0x00001A94, 0x00005A0F, 0x00001E2E, 0x00050082, 0x0000000B, 0x00004C3A, + 0x00001A94, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A1D, 0x00004C3A, 0x00002C94, 0x000500C4, + 0x0000000B, 0x000046EA, 0x00002C94, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00003E8A, 0x00003A1D, + 0x000046EA, 0x000500C4, 0x0000000B, 0x00001FB8, 0x00002C94, 0x00000A10, 0x000500C5, 0x0000000B, + 0x00001E82, 0x00003E8A, 0x00001FB8, 0x000200F9, 0x00002DCA, 0x000200F8, 0x00002DCA, 0x000700F5, + 0x0000000B, 0x000043D2, 0x0000186E, 0x00002992, 0x00001E82, 0x000055A5, 0x00050051, 0x0000000B, + 0x00005A10, 0x00003F71, 0x00000003, 0x00050051, 0x0000000B, 0x00003283, 0x000019B9, 0x00000002, + 0x00050051, 0x0000000B, 0x00003334, 0x000019B9, 0x00000003, 0x000500B2, 0x00000009, 0x00004E86, + 0x00003283, 0x00003334, 0x000300F7, 0x00002DB5, 0x00000000, 0x000400FA, 0x00004E86, 0x00002993, + 0x000055A7, 0x000200F8, 0x00002993, 0x000500C7, 0x0000000B, 0x000044FC, 0x00005A10, 0x000009C8, + 0x000500C7, 0x0000000B, 0x00005D8F, 0x00005A10, 0x00000986, 0x000500C2, 0x0000000B, 0x00005557, + 0x00005D8F, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FC8, 0x000044FC, 0x00005557, 0x000500C4, + 0x0000000B, 0x00006024, 0x00001FC8, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059AF, 0x00001FC8, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000496D, 0x00006024, 0x000059AF, 0x000500C5, 0x0000000B, + 0x00003EB4, 0x00001FC8, 0x0000496D, 0x000500C7, 0x0000000B, 0x00004788, 0x00005A10, 0x000009E9, + 0x000500C5, 0x0000000B, 0x00003960, 0x00004788, 0x00000944, 0x000500C7, 0x0000000B, 0x00004FB6, + 0x00003960, 0x00003EB4, 0x000500C2, 0x0000000B, 0x0000503E, 0x000044FC, 0x00000A0D, 0x000500C5, + 0x0000000B, 0x0000615D, 0x00004788, 0x0000503E, 0x000500C2, 0x0000000B, 0x000055A6, 0x00005D8F, + 0x00000A10, 0x000500C5, 0x0000000B, 0x00005895, 0x0000615D, 0x000055A6, 0x000500C6, 0x0000000B, + 0x00001E2F, 0x00005895, 0x000009E9, 0x000400C8, 0x0000000B, 0x0000254A, 0x0000503E, 0x000500C7, + 0x0000000B, 0x00003923, 0x00004788, 0x0000254A, 0x000400C8, 0x0000000B, 0x000020EF, 0x000055A6, + 0x000500C7, 0x0000000B, 0x00002C95, 0x00003923, 0x000020EF, 0x000500C5, 0x0000000B, 0x00001A95, + 0x00005A10, 0x00001E2F, 0x00050082, 0x0000000B, 0x00004C3B, 0x00001A95, 0x000009E9, 0x000500C5, + 0x0000000B, 0x00003A1E, 0x00004C3B, 0x00002C95, 0x000500C4, 0x0000000B, 0x00004737, 0x00002C95, + 0x00000A10, 0x000500C5, 0x0000000B, 0x00003BFD, 0x00003A1E, 0x00004737, 0x000400C8, 0x0000000B, + 0x00002F7D, 0x00003EB4, 0x000500C7, 0x0000000B, 0x00004853, 0x00003BFD, 0x00002F7D, 0x000500C5, + 0x0000000B, 0x0000186F, 0x00004853, 0x00004FB6, 0x000200F9, 0x00002DB5, 0x000200F8, 0x000055A7, + 0x000500C7, 0x0000000B, 0x00004E72, 0x00005A10, 0x000009E9, 0x000500C7, 0x0000000B, 0x00005D69, + 0x00005A10, 0x000009C8, 0x000500C2, 0x0000000B, 0x000056EA, 0x00005D69, 0x00000A0D, 0x000500C5, + 0x0000000B, 0x00005DC3, 0x00004E72, 0x000056EA, 0x000500C7, 0x0000000B, 0x00004C92, 0x00005A10, + 0x00000986, 0x000500C2, 0x0000000B, 0x0000508A, 0x00004C92, 0x00000A10, 0x000500C5, 0x0000000B, + 0x00005EE2, 0x00005DC3, 0x0000508A, 0x000500C6, 0x0000000B, 0x00001E30, 0x00005EE2, 0x000009E9, + 0x000400C8, 0x0000000B, 0x0000254B, 0x000056EA, 0x000500C7, 0x0000000B, 0x00003924, 0x00004E72, + 0x0000254B, 0x000400C8, 0x0000000B, 0x000020F0, 0x0000508A, 0x000500C7, 0x0000000B, 0x00002C96, + 0x00003924, 0x000020F0, 0x000500C5, 0x0000000B, 0x00001A96, 0x00005A10, 0x00001E30, 0x00050082, + 0x0000000B, 0x00004C3C, 0x00001A96, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A1F, 0x00004C3C, + 0x00002C96, 0x000500C4, 0x0000000B, 0x000046EB, 0x00002C96, 0x00000A0D, 0x000500C5, 0x0000000B, + 0x00003E8B, 0x00003A1F, 0x000046EB, 0x000500C4, 0x0000000B, 0x00001FB9, 0x00002C96, 0x00000A10, + 0x000500C5, 0x0000000B, 0x00001E83, 0x00003E8B, 0x00001FB9, 0x000200F9, 0x00002DB5, 0x000200F8, + 0x00002DB5, 0x000700F5, 0x0000000B, 0x000050CF, 0x0000186F, 0x00002993, 0x00001E83, 0x000055A7, + 0x00070050, 0x00000017, 0x000060EB, 0x000043D0, 0x000043D1, 0x000043D2, 0x000050CF, 0x000300F7, + 0x00004F49, 0x00000000, 0x000400FA, 0x00004E83, 0x00002994, 0x000038BE, 0x000200F8, 0x00002994, + 0x000500C7, 0x0000000B, 0x000044FD, 0x000043D0, 0x0000003A, 0x000500C7, 0x0000000B, 0x00005D90, + 0x000043D0, 0x0000022D, 0x000500C2, 0x0000000B, 0x00005558, 0x00005D90, 0x00000A0D, 0x000500C7, + 0x0000000B, 0x00001FC9, 0x000044FD, 0x00005558, 0x000500C4, 0x0000000B, 0x00006025, 0x00001FC9, + 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059B0, 0x00001FC9, 0x00000A0D, 0x000500C5, 0x0000000B, + 0x0000497C, 0x00006025, 0x000059B0, 0x000500C5, 0x0000000B, 0x00003E2A, 0x00001FC9, 0x0000497C, + 0x000400C8, 0x0000000B, 0x0000210B, 0x00003E2A, 0x000500C7, 0x0000000B, 0x00002762, 0x000043D0, + 0x0000210B, 0x00050082, 0x0000000B, 0x00003FAC, 0x00000908, 0x00002762, 0x000500C7, 0x0000000B, + 0x00004407, 0x00003FAC, 0x0000210B, 0x000500C7, 0x0000000B, 0x0000425F, 0x00004407, 0x00000A1F, + 0x00050084, 0x0000000B, 0x0000356D, 0x00001966, 0x0000425F, 0x000500C7, 0x0000000B, 0x000055D7, + 0x00002762, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FA6, 0x00003330, 0x000055D7, 0x00050080, + 0x0000000B, 0x00004D82, 0x0000356D, 0x00004FA6, 0x00050086, 0x0000000B, 0x000032C8, 0x00004D82, + 0x00000A19, 0x000500C2, 0x0000000B, 0x000059EE, 0x00004407, 0x00000A13, 0x000500C7, 0x0000000B, + 0x00002231, 0x000059EE, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AA3, 0x00001966, 0x00002231, + 0x000500C2, 0x0000000B, 0x000033E3, 0x00002762, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000617D, + 0x000033E3, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000626A, 0x00003330, 0x0000617D, 0x00050080, + 0x0000000B, 0x00004DA8, 0x00003AA3, 0x0000626A, 0x00050086, 0x0000000B, 0x00003148, 0x00004DA8, + 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FE0, 0x00003148, 0x00000A3A, 0x000500C5, 0x0000000B, + 0x00001D81, 0x000032C8, 0x00001FE0, 0x000500C2, 0x0000000B, 0x000055AF, 0x00004407, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x000044B8, 0x000055AF, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AA4, + 0x00001966, 0x000044B8, 0x000500C2, 0x0000000B, 0x000033E4, 0x00002762, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x0000617E, 0x000033E4, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000626B, 0x00003330, + 0x0000617E, 0x00050080, 0x0000000B, 0x00004D83, 0x00003AA4, 0x0000626B, 0x00050086, 0x0000000B, + 0x000032C9, 0x00004D83, 0x00000A19, 0x000500C2, 0x0000000B, 0x000059EF, 0x00004407, 0x00000A25, + 0x000500C7, 0x0000000B, 0x00002232, 0x000059EF, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AA5, + 0x00001966, 0x00002232, 0x000500C2, 0x0000000B, 0x000033E5, 0x00002762, 0x00000A25, 0x000500C7, + 0x0000000B, 0x0000617F, 0x000033E5, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000626C, 0x00003330, + 0x0000617F, 0x00050080, 0x0000000B, 0x00004DA9, 0x00003AA5, 0x0000626C, 0x00050086, 0x0000000B, + 0x00003149, 0x00004DA9, 0x00000A19, 0x000500C4, 0x0000000B, 0x000061E9, 0x00003149, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x0000200C, 0x000032C9, 0x000061E9, 0x00050050, 0x00000011, 0x00002785, + 0x00001D81, 0x0000200C, 0x000500C7, 0x0000000B, 0x00005ECC, 0x000043D0, 0x00003E2A, 0x000500C7, + 0x0000000B, 0x00003FF6, 0x00005ECC, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C67, 0x00005ECC, + 0x00000A22, 0x000500C4, 0x0000000B, 0x00006105, 0x00004C67, 0x00000A31, 0x000500C5, 0x0000000B, + 0x00004655, 0x00003FF6, 0x00006105, 0x000500C2, 0x0000000B, 0x00005AA8, 0x00005ECC, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x00006216, 0x00005AA8, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004943, + 0x00005ECC, 0x00000447, 0x000500C4, 0x0000000B, 0x0000588F, 0x00004943, 0x00000A1F, 0x000500C5, + 0x0000000B, 0x000043E7, 0x00006216, 0x0000588F, 0x00050050, 0x00000011, 0x00004F87, 0x00004655, + 0x000043E7, 0x00050084, 0x00000011, 0x00005117, 0x00004F87, 0x00000474, 0x00050080, 0x00000011, + 0x00005D2E, 0x00002785, 0x00005117, 0x000200F9, 0x00004F49, 0x000200F8, 0x000038BE, 0x000400C8, + 0x0000000B, 0x000029D4, 0x000043D0, 0x000500C7, 0x0000000B, 0x00003BFE, 0x000029D4, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00004530, 0x00001966, 0x00003BFE, 0x000500C7, 0x0000000B, 0x000055D8, + 0x000043D0, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FA7, 0x00003330, 0x000055D8, 0x00050080, + 0x0000000B, 0x00004D84, 0x00004530, 0x00004FA7, 0x00050086, 0x0000000B, 0x000032CA, 0x00004D84, + 0x00000A1F, 0x000500C2, 0x0000000B, 0x000059F0, 0x000029D4, 0x00000A13, 0x000500C7, 0x0000000B, + 0x00002233, 0x000059F0, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AA6, 0x00001966, 0x00002233, + 0x000500C2, 0x0000000B, 0x000033E6, 0x000043D0, 0x00000A13, 0x000500C7, 0x0000000B, 0x00006180, + 0x000033E6, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000626D, 0x00003330, 0x00006180, 0x00050080, + 0x0000000B, 0x00004DAA, 0x00003AA6, 0x0000626D, 0x00050086, 0x0000000B, 0x0000314A, 0x00004DAA, + 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FE1, 0x0000314A, 0x00000A3A, 0x000500C5, 0x0000000B, + 0x00001D82, 0x000032CA, 0x00001FE1, 0x000500C2, 0x0000000B, 0x000055B0, 0x000029D4, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x000044B9, 0x000055B0, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AA7, + 0x00001966, 0x000044B9, 0x000500C2, 0x0000000B, 0x000033E7, 0x000043D0, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x00006181, 0x000033E7, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000626E, 0x00003330, + 0x00006181, 0x00050080, 0x0000000B, 0x00004D85, 0x00003AA7, 0x0000626E, 0x00050086, 0x0000000B, + 0x000032CB, 0x00004D85, 0x00000A1F, 0x000500C2, 0x0000000B, 0x000059F1, 0x000029D4, 0x00000A25, + 0x000500C7, 0x0000000B, 0x00002234, 0x000059F1, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AA8, + 0x00001966, 0x00002234, 0x000500C2, 0x0000000B, 0x000033E8, 0x000043D0, 0x00000A25, 0x000500C7, + 0x0000000B, 0x00006182, 0x000033E8, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000626F, 0x00003330, + 0x00006182, 0x00050080, 0x0000000B, 0x00004DAB, 0x00003AA8, 0x0000626F, 0x00050086, 0x0000000B, + 0x0000314B, 0x00004DAB, 0x00000A1F, 0x000500C4, 0x0000000B, 0x000061EA, 0x0000314B, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x000023C2, 0x000032CB, 0x000061EA, 0x00050050, 0x00000011, 0x000053DD, + 0x00001D82, 0x000023C2, 0x000200F9, 0x00004F49, 0x000200F8, 0x00004F49, 0x000700F5, 0x00000011, + 0x00002AAD, 0x00005D2E, 0x00002994, 0x000053DD, 0x000038BE, 0x000300F7, 0x00004B80, 0x00000000, + 0x000400FA, 0x00004E84, 0x00002995, 0x000038BF, 0x000200F8, 0x00002995, 0x000500C7, 0x0000000B, + 0x000044FE, 0x000043D1, 0x0000003A, 0x000500C7, 0x0000000B, 0x00005D91, 0x000043D1, 0x0000022D, + 0x000500C2, 0x0000000B, 0x00005559, 0x00005D91, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FCA, + 0x000044FE, 0x00005559, 0x000500C4, 0x0000000B, 0x00006026, 0x00001FCA, 0x00000A0D, 0x000500C2, + 0x0000000B, 0x000059B1, 0x00001FCA, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000497D, 0x00006026, + 0x000059B1, 0x000500C5, 0x0000000B, 0x00003E2B, 0x00001FCA, 0x0000497D, 0x000400C8, 0x0000000B, + 0x0000210C, 0x00003E2B, 0x000500C7, 0x0000000B, 0x00002763, 0x000043D1, 0x0000210C, 0x00050082, + 0x0000000B, 0x00003FAD, 0x00000908, 0x00002763, 0x000500C7, 0x0000000B, 0x00004408, 0x00003FAD, + 0x0000210C, 0x000500C7, 0x0000000B, 0x00004260, 0x00004408, 0x00000A1F, 0x00050084, 0x0000000B, + 0x0000356E, 0x00003281, 0x00004260, 0x000500C7, 0x0000000B, 0x000055D9, 0x00002763, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00004FA8, 0x00003331, 0x000055D9, 0x00050080, 0x0000000B, 0x00004D86, + 0x0000356E, 0x00004FA8, 0x00050086, 0x0000000B, 0x000032CC, 0x00004D86, 0x00000A19, 0x000500C2, + 0x0000000B, 0x000059F2, 0x00004408, 0x00000A13, 0x000500C7, 0x0000000B, 0x00002235, 0x000059F2, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AA9, 0x00003281, 0x00002235, 0x000500C2, 0x0000000B, + 0x000033E9, 0x00002763, 0x00000A13, 0x000500C7, 0x0000000B, 0x00006183, 0x000033E9, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00006270, 0x00003331, 0x00006183, 0x00050080, 0x0000000B, 0x00004DAC, + 0x00003AA9, 0x00006270, 0x00050086, 0x0000000B, 0x0000314C, 0x00004DAC, 0x00000A19, 0x000500C4, + 0x0000000B, 0x00001FE2, 0x0000314C, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D83, 0x000032CC, + 0x00001FE2, 0x000500C2, 0x0000000B, 0x000055B1, 0x00004408, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x000044BA, 0x000055B1, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AAA, 0x00003281, 0x000044BA, + 0x000500C2, 0x0000000B, 0x000033EA, 0x00002763, 0x00000A1C, 0x000500C7, 0x0000000B, 0x00006184, + 0x000033EA, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006271, 0x00003331, 0x00006184, 0x00050080, + 0x0000000B, 0x00004D87, 0x00003AAA, 0x00006271, 0x00050086, 0x0000000B, 0x000032CD, 0x00004D87, + 0x00000A19, 0x000500C2, 0x0000000B, 0x000059F3, 0x00004408, 0x00000A25, 0x000500C7, 0x0000000B, + 0x00002236, 0x000059F3, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AAB, 0x00003281, 0x00002236, + 0x000500C2, 0x0000000B, 0x000033EB, 0x00002763, 0x00000A25, 0x000500C7, 0x0000000B, 0x00006185, + 0x000033EB, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006272, 0x00003331, 0x00006185, 0x00050080, + 0x0000000B, 0x00004DAD, 0x00003AAB, 0x00006272, 0x00050086, 0x0000000B, 0x0000314D, 0x00004DAD, + 0x00000A19, 0x000500C4, 0x0000000B, 0x000061EB, 0x0000314D, 0x00000A3A, 0x000500C5, 0x0000000B, + 0x0000200D, 0x000032CD, 0x000061EB, 0x00050050, 0x00000011, 0x00002786, 0x00001D83, 0x0000200D, + 0x000500C7, 0x0000000B, 0x00005ECD, 0x000043D1, 0x00003E2B, 0x000500C7, 0x0000000B, 0x00003FF7, + 0x00005ECD, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C68, 0x00005ECD, 0x00000A22, 0x000500C4, + 0x0000000B, 0x00006106, 0x00004C68, 0x00000A31, 0x000500C5, 0x0000000B, 0x00004656, 0x00003FF7, + 0x00006106, 0x000500C2, 0x0000000B, 0x00005AA9, 0x00005ECD, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x00006217, 0x00005AA9, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004944, 0x00005ECD, 0x00000447, + 0x000500C4, 0x0000000B, 0x00005890, 0x00004944, 0x00000A1F, 0x000500C5, 0x0000000B, 0x000043E8, + 0x00006217, 0x00005890, 0x00050050, 0x00000011, 0x00004F88, 0x00004656, 0x000043E8, 0x00050084, + 0x00000011, 0x00005118, 0x00004F88, 0x00000474, 0x00050080, 0x00000011, 0x00005D2F, 0x00002786, + 0x00005118, 0x000200F9, 0x00004B80, 0x000200F8, 0x000038BF, 0x000400C8, 0x0000000B, 0x000029D5, + 0x000043D1, 0x000500C7, 0x0000000B, 0x00003BFF, 0x000029D5, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00004531, 0x00003281, 0x00003BFF, 0x000500C7, 0x0000000B, 0x000055DA, 0x000043D1, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00004FA9, 0x00003331, 0x000055DA, 0x00050080, 0x0000000B, 0x00004D88, + 0x00004531, 0x00004FA9, 0x00050086, 0x0000000B, 0x000032CE, 0x00004D88, 0x00000A1F, 0x000500C2, + 0x0000000B, 0x000059F4, 0x000029D5, 0x00000A13, 0x000500C7, 0x0000000B, 0x00002237, 0x000059F4, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AAC, 0x00003281, 0x00002237, 0x000500C2, 0x0000000B, + 0x000033EC, 0x000043D1, 0x00000A13, 0x000500C7, 0x0000000B, 0x00006186, 0x000033EC, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00006273, 0x00003331, 0x00006186, 0x00050080, 0x0000000B, 0x00004DAE, + 0x00003AAC, 0x00006273, 0x00050086, 0x0000000B, 0x0000314E, 0x00004DAE, 0x00000A1F, 0x000500C4, + 0x0000000B, 0x00001FE3, 0x0000314E, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D84, 0x000032CE, + 0x00001FE3, 0x000500C2, 0x0000000B, 0x000055B2, 0x000029D5, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x000044BB, 0x000055B2, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AAD, 0x00003281, 0x000044BB, + 0x000500C2, 0x0000000B, 0x000033ED, 0x000043D1, 0x00000A1C, 0x000500C7, 0x0000000B, 0x00006187, + 0x000033ED, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006274, 0x00003331, 0x00006187, 0x00050080, + 0x0000000B, 0x00004D89, 0x00003AAD, 0x00006274, 0x00050086, 0x0000000B, 0x000032CF, 0x00004D89, + 0x00000A1F, 0x000500C2, 0x0000000B, 0x000059F5, 0x000029D5, 0x00000A25, 0x000500C7, 0x0000000B, + 0x00002238, 0x000059F5, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AAE, 0x00003281, 0x00002238, + 0x000500C2, 0x0000000B, 0x000033EE, 0x000043D1, 0x00000A25, 0x000500C7, 0x0000000B, 0x00006188, + 0x000033EE, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006275, 0x00003331, 0x00006188, 0x00050080, + 0x0000000B, 0x00004DAF, 0x00003AAE, 0x00006275, 0x00050086, 0x0000000B, 0x0000314F, 0x00004DAF, + 0x00000A1F, 0x000500C4, 0x0000000B, 0x000061EC, 0x0000314F, 0x00000A3A, 0x000500C5, 0x0000000B, + 0x000023C3, 0x000032CF, 0x000061EC, 0x00050050, 0x00000011, 0x000053DE, 0x00001D84, 0x000023C3, + 0x000200F9, 0x00004B80, 0x000200F8, 0x00004B80, 0x000700F5, 0x00000011, 0x00004934, 0x00005D2F, + 0x00002995, 0x000053DE, 0x000038BF, 0x000500C4, 0x00000011, 0x00002B1E, 0x00004934, 0x000007B7, + 0x000500C5, 0x00000011, 0x00005254, 0x00002AAD, 0x00002B1E, 0x000300F7, 0x00004F4A, 0x00000000, + 0x000400FA, 0x00004E85, 0x00002996, 0x000038C0, 0x000200F8, 0x00002996, 0x000500C7, 0x0000000B, + 0x000044FF, 0x000043D2, 0x0000003A, 0x000500C7, 0x0000000B, 0x00005D92, 0x000043D2, 0x0000022D, + 0x000500C2, 0x0000000B, 0x0000555A, 0x00005D92, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FCB, + 0x000044FF, 0x0000555A, 0x000500C4, 0x0000000B, 0x00006027, 0x00001FCB, 0x00000A0D, 0x000500C2, + 0x0000000B, 0x000059B2, 0x00001FCB, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000497E, 0x00006027, + 0x000059B2, 0x000500C5, 0x0000000B, 0x00003E2C, 0x00001FCB, 0x0000497E, 0x000400C8, 0x0000000B, + 0x0000210D, 0x00003E2C, 0x000500C7, 0x0000000B, 0x00002764, 0x000043D2, 0x0000210D, 0x00050082, + 0x0000000B, 0x00003FAE, 0x00000908, 0x00002764, 0x000500C7, 0x0000000B, 0x00004409, 0x00003FAE, + 0x0000210D, 0x000500C7, 0x0000000B, 0x00004261, 0x00004409, 0x00000A1F, 0x00050084, 0x0000000B, + 0x0000356F, 0x00003282, 0x00004261, 0x000500C7, 0x0000000B, 0x000055DB, 0x00002764, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00004FAA, 0x00003333, 0x000055DB, 0x00050080, 0x0000000B, 0x00004D8A, + 0x0000356F, 0x00004FAA, 0x00050086, 0x0000000B, 0x000032D0, 0x00004D8A, 0x00000A19, 0x000500C2, + 0x0000000B, 0x000059F6, 0x00004409, 0x00000A13, 0x000500C7, 0x0000000B, 0x00002239, 0x000059F6, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AAF, 0x00003282, 0x00002239, 0x000500C2, 0x0000000B, + 0x000033EF, 0x00002764, 0x00000A13, 0x000500C7, 0x0000000B, 0x00006189, 0x000033EF, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00006276, 0x00003333, 0x00006189, 0x00050080, 0x0000000B, 0x00004DB0, + 0x00003AAF, 0x00006276, 0x00050086, 0x0000000B, 0x00003150, 0x00004DB0, 0x00000A19, 0x000500C4, + 0x0000000B, 0x00001FE4, 0x00003150, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D85, 0x000032D0, + 0x00001FE4, 0x000500C2, 0x0000000B, 0x000055B3, 0x00004409, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x000044BC, 0x000055B3, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB0, 0x00003282, 0x000044BC, + 0x000500C2, 0x0000000B, 0x000033F0, 0x00002764, 0x00000A1C, 0x000500C7, 0x0000000B, 0x0000618A, + 0x000033F0, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006277, 0x00003333, 0x0000618A, 0x00050080, + 0x0000000B, 0x00004D8B, 0x00003AB0, 0x00006277, 0x00050086, 0x0000000B, 0x000032D1, 0x00004D8B, + 0x00000A19, 0x000500C2, 0x0000000B, 0x000059F7, 0x00004409, 0x00000A25, 0x000500C7, 0x0000000B, + 0x0000223A, 0x000059F7, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB1, 0x00003282, 0x0000223A, + 0x000500C2, 0x0000000B, 0x000033F1, 0x00002764, 0x00000A25, 0x000500C7, 0x0000000B, 0x0000618B, + 0x000033F1, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006278, 0x00003333, 0x0000618B, 0x00050080, + 0x0000000B, 0x00004DB1, 0x00003AB1, 0x00006278, 0x00050086, 0x0000000B, 0x00003151, 0x00004DB1, + 0x00000A19, 0x000500C4, 0x0000000B, 0x000061ED, 0x00003151, 0x00000A3A, 0x000500C5, 0x0000000B, + 0x0000200E, 0x000032D1, 0x000061ED, 0x00050050, 0x00000011, 0x00002787, 0x00001D85, 0x0000200E, + 0x000500C7, 0x0000000B, 0x00005ECE, 0x000043D2, 0x00003E2C, 0x000500C7, 0x0000000B, 0x00003FFA, + 0x00005ECE, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C69, 0x00005ECE, 0x00000A22, 0x000500C4, + 0x0000000B, 0x00006107, 0x00004C69, 0x00000A31, 0x000500C5, 0x0000000B, 0x00004657, 0x00003FFA, + 0x00006107, 0x000500C2, 0x0000000B, 0x00005AAA, 0x00005ECE, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x00006218, 0x00005AAA, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004945, 0x00005ECE, 0x00000447, + 0x000500C4, 0x0000000B, 0x00005891, 0x00004945, 0x00000A1F, 0x000500C5, 0x0000000B, 0x000043E9, + 0x00006218, 0x00005891, 0x00050050, 0x00000011, 0x00004F89, 0x00004657, 0x000043E9, 0x00050084, + 0x00000011, 0x00005119, 0x00004F89, 0x00000474, 0x00050080, 0x00000011, 0x00005D30, 0x00002787, + 0x00005119, 0x000200F9, 0x00004F4A, 0x000200F8, 0x000038C0, 0x000400C8, 0x0000000B, 0x000029D6, + 0x000043D2, 0x000500C7, 0x0000000B, 0x00003C00, 0x000029D6, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00004532, 0x00003282, 0x00003C00, 0x000500C7, 0x0000000B, 0x000055DC, 0x000043D2, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00004FAB, 0x00003333, 0x000055DC, 0x00050080, 0x0000000B, 0x00004D8C, + 0x00004532, 0x00004FAB, 0x00050086, 0x0000000B, 0x000032D2, 0x00004D8C, 0x00000A1F, 0x000500C2, + 0x0000000B, 0x000059F8, 0x000029D6, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000223B, 0x000059F8, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB2, 0x00003282, 0x0000223B, 0x000500C2, 0x0000000B, + 0x000033F2, 0x000043D2, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000618C, 0x000033F2, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00006279, 0x00003333, 0x0000618C, 0x00050080, 0x0000000B, 0x00004DB2, + 0x00003AB2, 0x00006279, 0x00050086, 0x0000000B, 0x00003152, 0x00004DB2, 0x00000A1F, 0x000500C4, + 0x0000000B, 0x00001FE5, 0x00003152, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D86, 0x000032D2, + 0x00001FE5, 0x000500C2, 0x0000000B, 0x000055B4, 0x000029D6, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x000044BD, 0x000055B4, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB3, 0x00003282, 0x000044BD, + 0x000500C2, 0x0000000B, 0x000033F3, 0x000043D2, 0x00000A1C, 0x000500C7, 0x0000000B, 0x0000618D, + 0x000033F3, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000627A, 0x00003333, 0x0000618D, 0x00050080, + 0x0000000B, 0x00004D8E, 0x00003AB3, 0x0000627A, 0x00050086, 0x0000000B, 0x000032D3, 0x00004D8E, + 0x00000A1F, 0x000500C2, 0x0000000B, 0x000059F9, 0x000029D6, 0x00000A25, 0x000500C7, 0x0000000B, + 0x0000223C, 0x000059F9, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB4, 0x00003282, 0x0000223C, + 0x000500C2, 0x0000000B, 0x000033F4, 0x000043D2, 0x00000A25, 0x000500C7, 0x0000000B, 0x0000618E, + 0x000033F4, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000627B, 0x00003333, 0x0000618E, 0x00050080, + 0x0000000B, 0x00004DB3, 0x00003AB4, 0x0000627B, 0x00050086, 0x0000000B, 0x00003153, 0x00004DB3, + 0x00000A1F, 0x000500C4, 0x0000000B, 0x000061EE, 0x00003153, 0x00000A3A, 0x000500C5, 0x0000000B, + 0x000023C4, 0x000032D3, 0x000061EE, 0x00050050, 0x00000011, 0x000053DF, 0x00001D86, 0x000023C4, + 0x000200F9, 0x00004F4A, 0x000200F8, 0x00004F4A, 0x000700F5, 0x00000011, 0x00002AAE, 0x00005D30, + 0x00002996, 0x000053DF, 0x000038C0, 0x000300F7, 0x00004B81, 0x00000000, 0x000400FA, 0x00004E86, + 0x00002997, 0x000038C1, 0x000200F8, 0x00002997, 0x000500C7, 0x0000000B, 0x00004500, 0x000050CF, + 0x0000003A, 0x000500C7, 0x0000000B, 0x00005D93, 0x000050CF, 0x0000022D, 0x000500C2, 0x0000000B, + 0x0000555B, 0x00005D93, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FCC, 0x00004500, 0x0000555B, + 0x000500C4, 0x0000000B, 0x00006028, 0x00001FCC, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059B3, + 0x00001FCC, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000497F, 0x00006028, 0x000059B3, 0x000500C5, + 0x0000000B, 0x00003E2D, 0x00001FCC, 0x0000497F, 0x000400C8, 0x0000000B, 0x0000210E, 0x00003E2D, + 0x000500C7, 0x0000000B, 0x00002765, 0x000050CF, 0x0000210E, 0x00050082, 0x0000000B, 0x00003FAF, + 0x00000908, 0x00002765, 0x000500C7, 0x0000000B, 0x0000440A, 0x00003FAF, 0x0000210E, 0x000500C7, + 0x0000000B, 0x00004262, 0x0000440A, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003570, 0x00003283, + 0x00004262, 0x000500C7, 0x0000000B, 0x000055DD, 0x00002765, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00004FAC, 0x00003334, 0x000055DD, 0x00050080, 0x0000000B, 0x00004D8F, 0x00003570, 0x00004FAC, + 0x00050086, 0x0000000B, 0x000032D4, 0x00004D8F, 0x00000A19, 0x000500C2, 0x0000000B, 0x000059FA, + 0x0000440A, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000223D, 0x000059FA, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AB5, 0x00003283, 0x0000223D, 0x000500C2, 0x0000000B, 0x000033F5, 0x00002765, + 0x00000A13, 0x000500C7, 0x0000000B, 0x0000618F, 0x000033F5, 0x00000A1F, 0x00050084, 0x0000000B, + 0x0000627C, 0x00003334, 0x0000618F, 0x00050080, 0x0000000B, 0x00004DB4, 0x00003AB5, 0x0000627C, + 0x00050086, 0x0000000B, 0x00003154, 0x00004DB4, 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FE6, + 0x00003154, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D87, 0x000032D4, 0x00001FE6, 0x000500C2, + 0x0000000B, 0x000055B5, 0x0000440A, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044C0, 0x000055B5, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB6, 0x00003283, 0x000044C0, 0x000500C2, 0x0000000B, + 0x000033F6, 0x00002765, 0x00000A1C, 0x000500C7, 0x0000000B, 0x00006190, 0x000033F6, 0x00000A1F, + 0x00050084, 0x0000000B, 0x0000627D, 0x00003334, 0x00006190, 0x00050080, 0x0000000B, 0x00004D90, + 0x00003AB6, 0x0000627D, 0x00050086, 0x0000000B, 0x000032D5, 0x00004D90, 0x00000A19, 0x000500C2, + 0x0000000B, 0x000059FB, 0x0000440A, 0x00000A25, 0x000500C7, 0x0000000B, 0x0000223E, 0x000059FB, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB7, 0x00003283, 0x0000223E, 0x000500C2, 0x0000000B, + 0x000033F7, 0x00002765, 0x00000A25, 0x000500C7, 0x0000000B, 0x00006191, 0x000033F7, 0x00000A1F, + 0x00050084, 0x0000000B, 0x0000627E, 0x00003334, 0x00006191, 0x00050080, 0x0000000B, 0x00004DB5, + 0x00003AB7, 0x0000627E, 0x00050086, 0x0000000B, 0x00003155, 0x00004DB5, 0x00000A19, 0x000500C4, + 0x0000000B, 0x000061EF, 0x00003155, 0x00000A3A, 0x000500C5, 0x0000000B, 0x0000200F, 0x000032D5, + 0x000061EF, 0x00050050, 0x00000011, 0x00002788, 0x00001D87, 0x0000200F, 0x000500C7, 0x0000000B, + 0x00005ECF, 0x000050CF, 0x00003E2D, 0x000500C7, 0x0000000B, 0x00003FFB, 0x00005ECF, 0x00000A0D, + 0x000500C7, 0x0000000B, 0x00004C6A, 0x00005ECF, 0x00000A22, 0x000500C4, 0x0000000B, 0x00006108, + 0x00004C6A, 0x00000A31, 0x000500C5, 0x0000000B, 0x00004658, 0x00003FFB, 0x00006108, 0x000500C2, + 0x0000000B, 0x00005AAB, 0x00005ECF, 0x00000A1C, 0x000500C7, 0x0000000B, 0x00006219, 0x00005AAB, + 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004946, 0x00005ECF, 0x00000447, 0x000500C4, 0x0000000B, + 0x00005896, 0x00004946, 0x00000A1F, 0x000500C5, 0x0000000B, 0x000043EA, 0x00006219, 0x00005896, + 0x00050050, 0x00000011, 0x00004F8A, 0x00004658, 0x000043EA, 0x00050084, 0x00000011, 0x0000511A, + 0x00004F8A, 0x00000474, 0x00050080, 0x00000011, 0x00005D31, 0x00002788, 0x0000511A, 0x000200F9, + 0x00004B81, 0x000200F8, 0x000038C1, 0x000400C8, 0x0000000B, 0x000029D7, 0x000050CF, 0x000500C7, + 0x0000000B, 0x00003C01, 0x000029D7, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004533, 0x00003283, + 0x00003C01, 0x000500C7, 0x0000000B, 0x000055DE, 0x000050CF, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00004FAD, 0x00003334, 0x000055DE, 0x00050080, 0x0000000B, 0x00004D91, 0x00004533, 0x00004FAD, + 0x00050086, 0x0000000B, 0x000032D6, 0x00004D91, 0x00000A1F, 0x000500C2, 0x0000000B, 0x000059FC, + 0x000029D7, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000223F, 0x000059FC, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AB8, 0x00003283, 0x0000223F, 0x000500C2, 0x0000000B, 0x000033F8, 0x000050CF, + 0x00000A13, 0x000500C7, 0x0000000B, 0x00006192, 0x000033F8, 0x00000A1F, 0x00050084, 0x0000000B, + 0x0000627F, 0x00003334, 0x00006192, 0x00050080, 0x0000000B, 0x00004DB6, 0x00003AB8, 0x0000627F, + 0x00050086, 0x0000000B, 0x00003156, 0x00004DB6, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FE7, + 0x00003156, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D88, 0x000032D6, 0x00001FE7, 0x000500C2, + 0x0000000B, 0x000055B6, 0x000029D7, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044C1, 0x000055B6, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB9, 0x00003283, 0x000044C1, 0x000500C2, 0x0000000B, + 0x000033F9, 0x000050CF, 0x00000A1C, 0x000500C7, 0x0000000B, 0x00006193, 0x000033F9, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00006280, 0x00003334, 0x00006193, 0x00050080, 0x0000000B, 0x00004D92, + 0x00003AB9, 0x00006280, 0x00050086, 0x0000000B, 0x000032D7, 0x00004D92, 0x00000A1F, 0x000500C2, + 0x0000000B, 0x000059FD, 0x000029D7, 0x00000A25, 0x000500C7, 0x0000000B, 0x00002240, 0x000059FD, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ABA, 0x00003283, 0x00002240, 0x000500C2, 0x0000000B, + 0x000033FA, 0x000050CF, 0x00000A25, 0x000500C7, 0x0000000B, 0x00006194, 0x000033FA, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00006281, 0x00003334, 0x00006194, 0x00050080, 0x0000000B, 0x00004DB7, + 0x00003ABA, 0x00006281, 0x00050086, 0x0000000B, 0x00003157, 0x00004DB7, 0x00000A1F, 0x000500C4, + 0x0000000B, 0x000061F0, 0x00003157, 0x00000A3A, 0x000500C5, 0x0000000B, 0x000023C5, 0x000032D7, + 0x000061F0, 0x00050050, 0x00000011, 0x000053E0, 0x00001D88, 0x000023C5, 0x000200F9, 0x00004B81, + 0x000200F8, 0x00004B81, 0x000700F5, 0x00000011, 0x00004935, 0x00005D31, 0x00002997, 0x000053E0, + 0x000038C1, 0x000500C4, 0x00000011, 0x00001ECC, 0x00004935, 0x000007B7, 0x000500C5, 0x00000011, + 0x000020F9, 0x00002AAE, 0x00001ECC, 0x00050051, 0x0000000B, 0x00004E81, 0x00005254, 0x00000000, + 0x00050051, 0x0000000B, 0x00005CB2, 0x00005254, 0x00000001, 0x00050051, 0x0000000B, 0x00001DDB, + 0x000020F9, 0x00000000, 0x00050051, 0x0000000B, 0x00001D69, 0x000020F9, 0x00000001, 0x00070050, + 0x00000017, 0x00004754, 0x00004E81, 0x00005CB2, 0x00001DDB, 0x00001D69, 0x00060041, 0x00000294, + 0x00002253, 0x0000140E, 0x00000A0B, 0x00002DCE, 0x0003003E, 0x00002253, 0x00004754, 0x00050051, + 0x0000000B, 0x00003220, 0x000043C0, 0x00000001, 0x00050080, 0x0000000B, 0x00005AC0, 0x00003220, + 0x00000A0E, 0x000500B0, 0x00000009, 0x00004411, 0x00005AC0, 0x000019C2, 0x000300F7, 0x00001C26, + 0x00000002, 0x000400FA, 0x00004411, 0x0000592C, 0x00001C26, 0x000200F8, 0x0000592C, 0x00050080, + 0x0000000B, 0x00003416, 0x00002DCE, 0x00001B41, 0x000500C2, 0x00000017, 0x00003D27, 0x000060EB, + 0x00000215, 0x00050051, 0x0000000B, 0x00005D1B, 0x00003D27, 0x00000000, 0x000300F7, 0x000042F7, + 0x00000000, 0x000400FA, 0x00004E83, 0x00002998, 0x000038C2, 0x000200F8, 0x00002998, 0x000500C7, + 0x0000000B, 0x00004501, 0x00005D1B, 0x0000003A, 0x000500C7, 0x0000000B, 0x00005D94, 0x00005D1B, + 0x0000022D, 0x000500C2, 0x0000000B, 0x0000555C, 0x00005D94, 0x00000A0D, 0x000500C7, 0x0000000B, + 0x00001FCD, 0x00004501, 0x0000555C, 0x000500C4, 0x0000000B, 0x00006029, 0x00001FCD, 0x00000A0D, + 0x000500C2, 0x0000000B, 0x000059B4, 0x00001FCD, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004980, + 0x00006029, 0x000059B4, 0x000500C5, 0x0000000B, 0x00003E2E, 0x00001FCD, 0x00004980, 0x000400C8, + 0x0000000B, 0x0000210F, 0x00003E2E, 0x000500C7, 0x0000000B, 0x00002766, 0x00005D1B, 0x0000210F, + 0x00050082, 0x0000000B, 0x00003FB0, 0x00000908, 0x00002766, 0x000500C7, 0x0000000B, 0x0000440B, + 0x00003FB0, 0x0000210F, 0x000500C7, 0x0000000B, 0x00004263, 0x0000440B, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003571, 0x00001966, 0x00004263, 0x000500C7, 0x0000000B, 0x000055DF, 0x00002766, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FAE, 0x00003330, 0x000055DF, 0x00050080, 0x0000000B, + 0x00004D93, 0x00003571, 0x00004FAE, 0x00050086, 0x0000000B, 0x000032D8, 0x00004D93, 0x00000A19, + 0x000500C2, 0x0000000B, 0x000059FE, 0x0000440B, 0x00000A13, 0x000500C7, 0x0000000B, 0x00002241, + 0x000059FE, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ABB, 0x00001966, 0x00002241, 0x000500C2, + 0x0000000B, 0x000033FB, 0x00002766, 0x00000A13, 0x000500C7, 0x0000000B, 0x00006195, 0x000033FB, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00006282, 0x00003330, 0x00006195, 0x00050080, 0x0000000B, + 0x00004DB8, 0x00003ABB, 0x00006282, 0x00050086, 0x0000000B, 0x00003158, 0x00004DB8, 0x00000A19, + 0x000500C4, 0x0000000B, 0x00001FE8, 0x00003158, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D89, + 0x000032D8, 0x00001FE8, 0x000500C2, 0x0000000B, 0x000055B7, 0x0000440B, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x000044C2, 0x000055B7, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ABC, 0x00001966, + 0x000044C2, 0x000500C2, 0x0000000B, 0x000033FC, 0x00002766, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x00006196, 0x000033FC, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006283, 0x00003330, 0x00006196, + 0x00050080, 0x0000000B, 0x00004D94, 0x00003ABC, 0x00006283, 0x00050086, 0x0000000B, 0x000032D9, + 0x00004D94, 0x00000A19, 0x000500C2, 0x0000000B, 0x000059FF, 0x0000440B, 0x00000A25, 0x000500C7, + 0x0000000B, 0x00002242, 0x000059FF, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ABD, 0x00001966, + 0x00002242, 0x000500C2, 0x0000000B, 0x000033FD, 0x00002766, 0x00000A25, 0x000500C7, 0x0000000B, + 0x00006197, 0x000033FD, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006284, 0x00003330, 0x00006197, + 0x00050080, 0x0000000B, 0x00004DB9, 0x00003ABD, 0x00006284, 0x00050086, 0x0000000B, 0x00003159, + 0x00004DB9, 0x00000A19, 0x000500C4, 0x0000000B, 0x000061F1, 0x00003159, 0x00000A3A, 0x000500C5, + 0x0000000B, 0x00002010, 0x000032D9, 0x000061F1, 0x00050050, 0x00000011, 0x00002789, 0x00001D89, + 0x00002010, 0x000500C7, 0x0000000B, 0x00005ED0, 0x00005D1B, 0x00003E2E, 0x000500C7, 0x0000000B, + 0x00003FFC, 0x00005ED0, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C6B, 0x00005ED0, 0x00000A22, + 0x000500C4, 0x0000000B, 0x00006109, 0x00004C6B, 0x00000A31, 0x000500C5, 0x0000000B, 0x00004659, + 0x00003FFC, 0x00006109, 0x000500C2, 0x0000000B, 0x00005AAC, 0x00005ED0, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x0000621A, 0x00005AAC, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004947, 0x00005ED0, + 0x00000447, 0x000500C4, 0x0000000B, 0x00005897, 0x00004947, 0x00000A1F, 0x000500C5, 0x0000000B, + 0x000043EB, 0x0000621A, 0x00005897, 0x00050050, 0x00000011, 0x00004F8B, 0x00004659, 0x000043EB, + 0x00050084, 0x00000011, 0x0000511B, 0x00004F8B, 0x00000474, 0x00050080, 0x00000011, 0x00005D32, + 0x00002789, 0x0000511B, 0x000200F9, 0x000042F7, 0x000200F8, 0x000038C2, 0x000400C8, 0x0000000B, + 0x000029D8, 0x00005D1B, 0x000500C7, 0x0000000B, 0x00003C02, 0x000029D8, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00004534, 0x00001966, 0x00003C02, 0x000500C7, 0x0000000B, 0x000055E0, 0x00005D1B, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FAF, 0x00003330, 0x000055E0, 0x00050080, 0x0000000B, + 0x00004D95, 0x00004534, 0x00004FAF, 0x00050086, 0x0000000B, 0x000032DA, 0x00004D95, 0x00000A1F, + 0x000500C2, 0x0000000B, 0x00005A00, 0x000029D8, 0x00000A13, 0x000500C7, 0x0000000B, 0x00002243, + 0x00005A00, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ABE, 0x00001966, 0x00002243, 0x000500C2, + 0x0000000B, 0x000033FE, 0x00005D1B, 0x00000A13, 0x000500C7, 0x0000000B, 0x00006198, 0x000033FE, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00006285, 0x00003330, 0x00006198, 0x00050080, 0x0000000B, + 0x00004DBA, 0x00003ABE, 0x00006285, 0x00050086, 0x0000000B, 0x0000315A, 0x00004DBA, 0x00000A1F, + 0x000500C4, 0x0000000B, 0x00001FE9, 0x0000315A, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D8A, + 0x000032DA, 0x00001FE9, 0x000500C2, 0x0000000B, 0x000055B8, 0x000029D8, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x000044C3, 0x000055B8, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ABF, 0x00001966, + 0x000044C3, 0x000500C2, 0x0000000B, 0x000033FF, 0x00005D1B, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x00006199, 0x000033FF, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006286, 0x00003330, 0x00006199, + 0x00050080, 0x0000000B, 0x00004D96, 0x00003ABF, 0x00006286, 0x00050086, 0x0000000B, 0x000032DB, + 0x00004D96, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A01, 0x000029D8, 0x00000A25, 0x000500C7, + 0x0000000B, 0x00002244, 0x00005A01, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AC0, 0x00001966, + 0x00002244, 0x000500C2, 0x0000000B, 0x00003400, 0x00005D1B, 0x00000A25, 0x000500C7, 0x0000000B, + 0x0000619A, 0x00003400, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006287, 0x00003330, 0x0000619A, + 0x00050080, 0x0000000B, 0x00004DBB, 0x00003AC0, 0x00006287, 0x00050086, 0x0000000B, 0x0000315B, + 0x00004DBB, 0x00000A1F, 0x000500C4, 0x0000000B, 0x000061F2, 0x0000315B, 0x00000A3A, 0x000500C5, + 0x0000000B, 0x000023C6, 0x000032DB, 0x000061F2, 0x00050050, 0x00000011, 0x000053E1, 0x00001D8A, + 0x000023C6, 0x000200F9, 0x000042F7, 0x000200F8, 0x000042F7, 0x000700F5, 0x00000011, 0x00005023, + 0x00005D32, 0x00002998, 0x000053E1, 0x000038C2, 0x00050051, 0x0000000B, 0x000040EA, 0x00003D27, + 0x00000001, 0x000300F7, 0x00004B82, 0x00000000, 0x000400FA, 0x00004E84, 0x00002999, 0x000038C3, + 0x000200F8, 0x00002999, 0x000500C7, 0x0000000B, 0x00004502, 0x000040EA, 0x0000003A, 0x000500C7, + 0x0000000B, 0x00005D95, 0x000040EA, 0x0000022D, 0x000500C2, 0x0000000B, 0x0000555D, 0x00005D95, + 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FCE, 0x00004502, 0x0000555D, 0x000500C4, 0x0000000B, + 0x0000602A, 0x00001FCE, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059B5, 0x00001FCE, 0x00000A0D, + 0x000500C5, 0x0000000B, 0x00004981, 0x0000602A, 0x000059B5, 0x000500C5, 0x0000000B, 0x00003E2F, + 0x00001FCE, 0x00004981, 0x000400C8, 0x0000000B, 0x00002110, 0x00003E2F, 0x000500C7, 0x0000000B, + 0x00002767, 0x000040EA, 0x00002110, 0x00050082, 0x0000000B, 0x00003FB1, 0x00000908, 0x00002767, + 0x000500C7, 0x0000000B, 0x0000440C, 0x00003FB1, 0x00002110, 0x000500C7, 0x0000000B, 0x00004264, + 0x0000440C, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003572, 0x00003281, 0x00004264, 0x000500C7, + 0x0000000B, 0x000055E1, 0x00002767, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FB0, 0x00003331, + 0x000055E1, 0x00050080, 0x0000000B, 0x00004D97, 0x00003572, 0x00004FB0, 0x00050086, 0x0000000B, + 0x000032DC, 0x00004D97, 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A02, 0x0000440C, 0x00000A13, + 0x000500C7, 0x0000000B, 0x00002245, 0x00005A02, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AC1, + 0x00003281, 0x00002245, 0x000500C2, 0x0000000B, 0x00003401, 0x00002767, 0x00000A13, 0x000500C7, + 0x0000000B, 0x0000619B, 0x00003401, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006288, 0x00003331, + 0x0000619B, 0x00050080, 0x0000000B, 0x00004DBC, 0x00003AC1, 0x00006288, 0x00050086, 0x0000000B, + 0x0000315C, 0x00004DBC, 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FEA, 0x0000315C, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x00001D8B, 0x000032DC, 0x00001FEA, 0x000500C2, 0x0000000B, 0x000055B9, + 0x0000440C, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044C4, 0x000055B9, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AC2, 0x00003281, 0x000044C4, 0x000500C2, 0x0000000B, 0x00003402, 0x00002767, + 0x00000A1C, 0x000500C7, 0x0000000B, 0x0000619C, 0x00003402, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00006289, 0x00003331, 0x0000619C, 0x00050080, 0x0000000B, 0x00004D98, 0x00003AC2, 0x00006289, + 0x00050086, 0x0000000B, 0x000032DD, 0x00004D98, 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A03, + 0x0000440C, 0x00000A25, 0x000500C7, 0x0000000B, 0x00002246, 0x00005A03, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AC3, 0x00003281, 0x00002246, 0x000500C2, 0x0000000B, 0x00003403, 0x00002767, + 0x00000A25, 0x000500C7, 0x0000000B, 0x0000619D, 0x00003403, 0x00000A1F, 0x00050084, 0x0000000B, + 0x0000628A, 0x00003331, 0x0000619D, 0x00050080, 0x0000000B, 0x00004DBD, 0x00003AC3, 0x0000628A, + 0x00050086, 0x0000000B, 0x0000315D, 0x00004DBD, 0x00000A19, 0x000500C4, 0x0000000B, 0x000061F3, + 0x0000315D, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00002011, 0x000032DD, 0x000061F3, 0x00050050, + 0x00000011, 0x0000278B, 0x00001D8B, 0x00002011, 0x000500C7, 0x0000000B, 0x00005ED1, 0x000040EA, + 0x00003E2F, 0x000500C7, 0x0000000B, 0x00003FFD, 0x00005ED1, 0x00000A0D, 0x000500C7, 0x0000000B, + 0x00004C6C, 0x00005ED1, 0x00000A22, 0x000500C4, 0x0000000B, 0x0000610A, 0x00004C6C, 0x00000A31, + 0x000500C5, 0x0000000B, 0x0000465A, 0x00003FFD, 0x0000610A, 0x000500C2, 0x0000000B, 0x00005AAD, + 0x00005ED1, 0x00000A1C, 0x000500C7, 0x0000000B, 0x0000621B, 0x00005AAD, 0x00000A0D, 0x000500C7, + 0x0000000B, 0x00004948, 0x00005ED1, 0x00000447, 0x000500C4, 0x0000000B, 0x00005898, 0x00004948, + 0x00000A1F, 0x000500C5, 0x0000000B, 0x000043EC, 0x0000621B, 0x00005898, 0x00050050, 0x00000011, + 0x00004F8C, 0x0000465A, 0x000043EC, 0x00050084, 0x00000011, 0x0000511C, 0x00004F8C, 0x00000474, + 0x00050080, 0x00000011, 0x00005D33, 0x0000278B, 0x0000511C, 0x000200F9, 0x00004B82, 0x000200F8, + 0x000038C3, 0x000400C8, 0x0000000B, 0x000029D9, 0x000040EA, 0x000500C7, 0x0000000B, 0x00003C03, + 0x000029D9, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004535, 0x00003281, 0x00003C03, 0x000500C7, + 0x0000000B, 0x000055E2, 0x000040EA, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FB1, 0x00003331, + 0x000055E2, 0x00050080, 0x0000000B, 0x00004D99, 0x00004535, 0x00004FB1, 0x00050086, 0x0000000B, + 0x000032DE, 0x00004D99, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A04, 0x000029D9, 0x00000A13, + 0x000500C7, 0x0000000B, 0x00002247, 0x00005A04, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AC4, + 0x00003281, 0x00002247, 0x000500C2, 0x0000000B, 0x00003404, 0x000040EA, 0x00000A13, 0x000500C7, + 0x0000000B, 0x0000619E, 0x00003404, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000628B, 0x00003331, + 0x0000619E, 0x00050080, 0x0000000B, 0x00004DBE, 0x00003AC4, 0x0000628B, 0x00050086, 0x0000000B, + 0x0000315E, 0x00004DBE, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FEB, 0x0000315E, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x00001D8C, 0x000032DE, 0x00001FEB, 0x000500C2, 0x0000000B, 0x000055BA, + 0x000029D9, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044C5, 0x000055BA, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AC5, 0x00003281, 0x000044C5, 0x000500C2, 0x0000000B, 0x00003405, 0x000040EA, + 0x00000A1C, 0x000500C7, 0x0000000B, 0x0000619F, 0x00003405, 0x00000A1F, 0x00050084, 0x0000000B, + 0x0000628C, 0x00003331, 0x0000619F, 0x00050080, 0x0000000B, 0x00004D9A, 0x00003AC5, 0x0000628C, + 0x00050086, 0x0000000B, 0x000032DF, 0x00004D9A, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A05, + 0x000029D9, 0x00000A25, 0x000500C7, 0x0000000B, 0x00002248, 0x00005A05, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AC6, 0x00003281, 0x00002248, 0x000500C2, 0x0000000B, 0x00003406, 0x000040EA, + 0x00000A25, 0x000500C7, 0x0000000B, 0x000061A0, 0x00003406, 0x00000A1F, 0x00050084, 0x0000000B, + 0x0000628D, 0x00003331, 0x000061A0, 0x00050080, 0x0000000B, 0x00004DBF, 0x00003AC6, 0x0000628D, + 0x00050086, 0x0000000B, 0x0000315F, 0x00004DBF, 0x00000A1F, 0x000500C4, 0x0000000B, 0x000061F4, + 0x0000315F, 0x00000A3A, 0x000500C5, 0x0000000B, 0x000023C7, 0x000032DF, 0x000061F4, 0x00050050, + 0x00000011, 0x000053E2, 0x00001D8C, 0x000023C7, 0x000200F9, 0x00004B82, 0x000200F8, 0x00004B82, + 0x000700F5, 0x00000011, 0x00004936, 0x00005D33, 0x00002999, 0x000053E2, 0x000038C3, 0x000500C4, + 0x00000011, 0x00001ECD, 0x00004936, 0x000007B7, 0x000500C5, 0x00000011, 0x00002D4B, 0x00005023, + 0x00001ECD, 0x00050051, 0x0000000B, 0x0000355C, 0x00003D27, 0x00000002, 0x000300F7, 0x000042F8, + 0x00000000, 0x000400FA, 0x00004E85, 0x0000299A, 0x000038C4, 0x000200F8, 0x0000299A, 0x000500C7, + 0x0000000B, 0x00004503, 0x0000355C, 0x0000003A, 0x000500C7, 0x0000000B, 0x00005D96, 0x0000355C, + 0x0000022D, 0x000500C2, 0x0000000B, 0x0000555E, 0x00005D96, 0x00000A0D, 0x000500C7, 0x0000000B, + 0x00001FCF, 0x00004503, 0x0000555E, 0x000500C4, 0x0000000B, 0x0000602B, 0x00001FCF, 0x00000A0D, + 0x000500C2, 0x0000000B, 0x000059B6, 0x00001FCF, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004982, + 0x0000602B, 0x000059B6, 0x000500C5, 0x0000000B, 0x00003E30, 0x00001FCF, 0x00004982, 0x000400C8, + 0x0000000B, 0x00002111, 0x00003E30, 0x000500C7, 0x0000000B, 0x00002768, 0x0000355C, 0x00002111, + 0x00050082, 0x0000000B, 0x00003FB2, 0x00000908, 0x00002768, 0x000500C7, 0x0000000B, 0x0000440D, + 0x00003FB2, 0x00002111, 0x000500C7, 0x0000000B, 0x00004265, 0x0000440D, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003573, 0x00003282, 0x00004265, 0x000500C7, 0x0000000B, 0x000055E3, 0x00002768, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FB2, 0x00003333, 0x000055E3, 0x00050080, 0x0000000B, + 0x00004D9B, 0x00003573, 0x00004FB2, 0x00050086, 0x0000000B, 0x000032E0, 0x00004D9B, 0x00000A19, + 0x000500C2, 0x0000000B, 0x00005A06, 0x0000440D, 0x00000A13, 0x000500C7, 0x0000000B, 0x00002249, + 0x00005A06, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AC7, 0x00003282, 0x00002249, 0x000500C2, + 0x0000000B, 0x00003407, 0x00002768, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061A1, 0x00003407, + 0x00000A1F, 0x00050084, 0x0000000B, 0x0000628E, 0x00003333, 0x000061A1, 0x00050080, 0x0000000B, + 0x00004DC0, 0x00003AC7, 0x0000628E, 0x00050086, 0x0000000B, 0x00003160, 0x00004DC0, 0x00000A19, + 0x000500C4, 0x0000000B, 0x00001FEC, 0x00003160, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D8D, + 0x000032E0, 0x00001FEC, 0x000500C2, 0x0000000B, 0x000055BB, 0x0000440D, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x000044C6, 0x000055BB, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AC8, 0x00003282, + 0x000044C6, 0x000500C2, 0x0000000B, 0x00003408, 0x00002768, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x000061A2, 0x00003408, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000628F, 0x00003333, 0x000061A2, + 0x00050080, 0x0000000B, 0x00004D9C, 0x00003AC8, 0x0000628F, 0x00050086, 0x0000000B, 0x000032E1, + 0x00004D9C, 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A07, 0x0000440D, 0x00000A25, 0x000500C7, + 0x0000000B, 0x0000224A, 0x00005A07, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AC9, 0x00003282, + 0x0000224A, 0x000500C2, 0x0000000B, 0x00003409, 0x00002768, 0x00000A25, 0x000500C7, 0x0000000B, + 0x000061A3, 0x00003409, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006290, 0x00003333, 0x000061A3, + 0x00050080, 0x0000000B, 0x00004DC1, 0x00003AC9, 0x00006290, 0x00050086, 0x0000000B, 0x00003161, + 0x00004DC1, 0x00000A19, 0x000500C4, 0x0000000B, 0x000061F5, 0x00003161, 0x00000A3A, 0x000500C5, + 0x0000000B, 0x00002012, 0x000032E1, 0x000061F5, 0x00050050, 0x00000011, 0x0000278C, 0x00001D8D, + 0x00002012, 0x000500C7, 0x0000000B, 0x00005ED2, 0x0000355C, 0x00003E30, 0x000500C7, 0x0000000B, + 0x00003FFE, 0x00005ED2, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C6D, 0x00005ED2, 0x00000A22, + 0x000500C4, 0x0000000B, 0x0000610B, 0x00004C6D, 0x00000A31, 0x000500C5, 0x0000000B, 0x0000465B, + 0x00003FFE, 0x0000610B, 0x000500C2, 0x0000000B, 0x00005AAE, 0x00005ED2, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x0000621C, 0x00005AAE, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004949, 0x00005ED2, + 0x00000447, 0x000500C4, 0x0000000B, 0x00005899, 0x00004949, 0x00000A1F, 0x000500C5, 0x0000000B, + 0x000043ED, 0x0000621C, 0x00005899, 0x00050050, 0x00000011, 0x00004F8D, 0x0000465B, 0x000043ED, + 0x00050084, 0x00000011, 0x0000511D, 0x00004F8D, 0x00000474, 0x00050080, 0x00000011, 0x00005D34, + 0x0000278C, 0x0000511D, 0x000200F9, 0x000042F8, 0x000200F8, 0x000038C4, 0x000400C8, 0x0000000B, + 0x000029DA, 0x0000355C, 0x000500C7, 0x0000000B, 0x00003C04, 0x000029DA, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00004536, 0x00003282, 0x00003C04, 0x000500C7, 0x0000000B, 0x000055E4, 0x0000355C, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FB7, 0x00003333, 0x000055E4, 0x00050080, 0x0000000B, + 0x00004D9D, 0x00004536, 0x00004FB7, 0x00050086, 0x0000000B, 0x000032E2, 0x00004D9D, 0x00000A1F, + 0x000500C2, 0x0000000B, 0x00005A08, 0x000029DA, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000224B, + 0x00005A08, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ACA, 0x00003282, 0x0000224B, 0x000500C2, + 0x0000000B, 0x0000340A, 0x0000355C, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061A4, 0x0000340A, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00006291, 0x00003333, 0x000061A4, 0x00050080, 0x0000000B, + 0x00004DC2, 0x00003ACA, 0x00006291, 0x00050086, 0x0000000B, 0x00003162, 0x00004DC2, 0x00000A1F, + 0x000500C4, 0x0000000B, 0x00001FED, 0x00003162, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D8E, + 0x000032E2, 0x00001FED, 0x000500C2, 0x0000000B, 0x000055BC, 0x000029DA, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x000044C7, 0x000055BC, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ACB, 0x00003282, + 0x000044C7, 0x000500C2, 0x0000000B, 0x0000340B, 0x0000355C, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x000061A5, 0x0000340B, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006292, 0x00003333, 0x000061A5, + 0x00050080, 0x0000000B, 0x00004D9E, 0x00003ACB, 0x00006292, 0x00050086, 0x0000000B, 0x000032E3, + 0x00004D9E, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A09, 0x000029DA, 0x00000A25, 0x000500C7, + 0x0000000B, 0x0000224C, 0x00005A09, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ACC, 0x00003282, + 0x0000224C, 0x000500C2, 0x0000000B, 0x0000340C, 0x0000355C, 0x00000A25, 0x000500C7, 0x0000000B, + 0x000061A6, 0x0000340C, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006293, 0x00003333, 0x000061A6, + 0x00050080, 0x0000000B, 0x00004DC3, 0x00003ACC, 0x00006293, 0x00050086, 0x0000000B, 0x00003163, + 0x00004DC3, 0x00000A1F, 0x000500C4, 0x0000000B, 0x000061F6, 0x00003163, 0x00000A3A, 0x000500C5, + 0x0000000B, 0x000023C8, 0x000032E3, 0x000061F6, 0x00050050, 0x00000011, 0x000053E3, 0x00001D8E, + 0x000023C8, 0x000200F9, 0x000042F8, 0x000200F8, 0x000042F8, 0x000700F5, 0x00000011, 0x00005024, + 0x00005D34, 0x0000299A, 0x000053E3, 0x000038C4, 0x00050051, 0x0000000B, 0x000040EB, 0x00003D27, + 0x00000003, 0x000300F7, 0x00004B83, 0x00000000, 0x000400FA, 0x00004E86, 0x0000299B, 0x000038C5, + 0x000200F8, 0x0000299B, 0x000500C7, 0x0000000B, 0x00004504, 0x000040EB, 0x0000003A, 0x000500C7, + 0x0000000B, 0x00005D97, 0x000040EB, 0x0000022D, 0x000500C2, 0x0000000B, 0x0000555F, 0x00005D97, + 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FD0, 0x00004504, 0x0000555F, 0x000500C4, 0x0000000B, + 0x0000602C, 0x00001FD0, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059B7, 0x00001FD0, 0x00000A0D, + 0x000500C5, 0x0000000B, 0x00004983, 0x0000602C, 0x000059B7, 0x000500C5, 0x0000000B, 0x00003E31, + 0x00001FD0, 0x00004983, 0x000400C8, 0x0000000B, 0x00002112, 0x00003E31, 0x000500C7, 0x0000000B, + 0x00002769, 0x000040EB, 0x00002112, 0x00050082, 0x0000000B, 0x00003FB3, 0x00000908, 0x00002769, + 0x000500C7, 0x0000000B, 0x0000440E, 0x00003FB3, 0x00002112, 0x000500C7, 0x0000000B, 0x00004266, + 0x0000440E, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003574, 0x00003283, 0x00004266, 0x000500C7, + 0x0000000B, 0x000055E5, 0x00002769, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FB8, 0x00003334, + 0x000055E5, 0x00050080, 0x0000000B, 0x00004D9F, 0x00003574, 0x00004FB8, 0x00050086, 0x0000000B, + 0x000032E4, 0x00004D9F, 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A0A, 0x0000440E, 0x00000A13, + 0x000500C7, 0x0000000B, 0x0000224D, 0x00005A0A, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ACD, + 0x00003283, 0x0000224D, 0x000500C2, 0x0000000B, 0x0000340D, 0x00002769, 0x00000A13, 0x000500C7, + 0x0000000B, 0x000061A7, 0x0000340D, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006294, 0x00003334, + 0x000061A7, 0x00050080, 0x0000000B, 0x00004DC4, 0x00003ACD, 0x00006294, 0x00050086, 0x0000000B, + 0x00003164, 0x00004DC4, 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FEE, 0x00003164, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x00001D8F, 0x000032E4, 0x00001FEE, 0x000500C2, 0x0000000B, 0x000055BD, + 0x0000440E, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044C8, 0x000055BD, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003ACE, 0x00003283, 0x000044C8, 0x000500C2, 0x0000000B, 0x0000340E, 0x00002769, + 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061A8, 0x0000340E, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00006295, 0x00003334, 0x000061A8, 0x00050080, 0x0000000B, 0x00004DA0, 0x00003ACE, 0x00006295, + 0x00050086, 0x0000000B, 0x000032E5, 0x00004DA0, 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A0B, + 0x0000440E, 0x00000A25, 0x000500C7, 0x0000000B, 0x0000224E, 0x00005A0B, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003ACF, 0x00003283, 0x0000224E, 0x000500C2, 0x0000000B, 0x0000340F, 0x00002769, + 0x00000A25, 0x000500C7, 0x0000000B, 0x000061A9, 0x0000340F, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00006296, 0x00003334, 0x000061A9, 0x00050080, 0x0000000B, 0x00004DC5, 0x00003ACF, 0x00006296, + 0x00050086, 0x0000000B, 0x00003165, 0x00004DC5, 0x00000A19, 0x000500C4, 0x0000000B, 0x000061F7, + 0x00003165, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00002013, 0x000032E5, 0x000061F7, 0x00050050, + 0x00000011, 0x0000278D, 0x00001D8F, 0x00002013, 0x000500C7, 0x0000000B, 0x00005ED3, 0x000040EB, + 0x00003E31, 0x000500C7, 0x0000000B, 0x00003FFF, 0x00005ED3, 0x00000A0D, 0x000500C7, 0x0000000B, + 0x00004C6E, 0x00005ED3, 0x00000A22, 0x000500C4, 0x0000000B, 0x0000610C, 0x00004C6E, 0x00000A31, + 0x000500C5, 0x0000000B, 0x0000465C, 0x00003FFF, 0x0000610C, 0x000500C2, 0x0000000B, 0x00005AAF, + 0x00005ED3, 0x00000A1C, 0x000500C7, 0x0000000B, 0x0000621D, 0x00005AAF, 0x00000A0D, 0x000500C7, + 0x0000000B, 0x0000494A, 0x00005ED3, 0x00000447, 0x000500C4, 0x0000000B, 0x0000589A, 0x0000494A, + 0x00000A1F, 0x000500C5, 0x0000000B, 0x000043EE, 0x0000621D, 0x0000589A, 0x00050050, 0x00000011, + 0x00004F8E, 0x0000465C, 0x000043EE, 0x00050084, 0x00000011, 0x0000511E, 0x00004F8E, 0x00000474, + 0x00050080, 0x00000011, 0x00005D35, 0x0000278D, 0x0000511E, 0x000200F9, 0x00004B83, 0x000200F8, + 0x000038C5, 0x000400C8, 0x0000000B, 0x000029DB, 0x000040EB, 0x000500C7, 0x0000000B, 0x00003C05, + 0x000029DB, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004537, 0x00003283, 0x00003C05, 0x000500C7, + 0x0000000B, 0x000055E6, 0x000040EB, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FB9, 0x00003334, + 0x000055E6, 0x00050080, 0x0000000B, 0x00004DA1, 0x00004537, 0x00004FB9, 0x00050086, 0x0000000B, + 0x000032E6, 0x00004DA1, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A0D, 0x000029DB, 0x00000A13, + 0x000500C7, 0x0000000B, 0x0000224F, 0x00005A0D, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AD0, + 0x00003283, 0x0000224F, 0x000500C2, 0x0000000B, 0x00003410, 0x000040EB, 0x00000A13, 0x000500C7, + 0x0000000B, 0x000061AA, 0x00003410, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006297, 0x00003334, + 0x000061AA, 0x00050080, 0x0000000B, 0x00004DC6, 0x00003AD0, 0x00006297, 0x00050086, 0x0000000B, + 0x00003166, 0x00004DC6, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FEF, 0x00003166, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x00001D90, 0x000032E6, 0x00001FEF, 0x000500C2, 0x0000000B, 0x000055BE, + 0x000029DB, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044C9, 0x000055BE, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AD1, 0x00003283, 0x000044C9, 0x000500C2, 0x0000000B, 0x00003411, 0x000040EB, + 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061AB, 0x00003411, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00006298, 0x00003334, 0x000061AB, 0x00050080, 0x0000000B, 0x00004DA2, 0x00003AD1, 0x00006298, + 0x00050086, 0x0000000B, 0x000032E7, 0x00004DA2, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A11, + 0x000029DB, 0x00000A25, 0x000500C7, 0x0000000B, 0x00002250, 0x00005A11, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AD2, 0x00003283, 0x00002250, 0x000500C2, 0x0000000B, 0x00003413, 0x000040EB, + 0x00000A25, 0x000500C7, 0x0000000B, 0x000061AC, 0x00003413, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00006299, 0x00003334, 0x000061AC, 0x00050080, 0x0000000B, 0x00004DC7, 0x00003AD2, 0x00006299, + 0x00050086, 0x0000000B, 0x00003167, 0x00004DC7, 0x00000A1F, 0x000500C4, 0x0000000B, 0x000061F8, + 0x00003167, 0x00000A3A, 0x000500C5, 0x0000000B, 0x000023C9, 0x000032E7, 0x000061F8, 0x00050050, + 0x00000011, 0x000053E4, 0x00001D90, 0x000023C9, 0x000200F9, 0x00004B83, 0x000200F8, 0x00004B83, + 0x000700F5, 0x00000011, 0x00004937, 0x00005D35, 0x0000299B, 0x000053E4, 0x000038C5, 0x000500C4, + 0x00000011, 0x00001ECE, 0x00004937, 0x000007B7, 0x000500C5, 0x00000011, 0x000020FA, 0x00005024, + 0x00001ECE, 0x00050051, 0x0000000B, 0x00004E82, 0x00002D4B, 0x00000000, 0x00050051, 0x0000000B, + 0x00005CB3, 0x00002D4B, 0x00000001, 0x00050051, 0x0000000B, 0x00001DDC, 0x000020FA, 0x00000000, + 0x00050051, 0x0000000B, 0x00001D6A, 0x000020FA, 0x00000001, 0x00070050, 0x00000017, 0x00004755, + 0x00004E82, 0x00005CB3, 0x00001DDC, 0x00001D6A, 0x00060041, 0x00000294, 0x000025D0, 0x0000140E, + 0x00000A0B, 0x00003416, 0x0003003E, 0x000025D0, 0x00004755, 0x00050080, 0x0000000B, 0x000039F8, + 0x00003220, 0x00000A11, 0x000500B0, 0x00000009, 0x00002E0B, 0x000039F8, 0x000019C2, 0x000300F7, + 0x00001C25, 0x00000002, 0x000400FA, 0x00002E0B, 0x0000592D, 0x00001C25, 0x000200F8, 0x0000592D, + 0x00050080, 0x0000000B, 0x00003417, 0x00003416, 0x00001B41, 0x000500C2, 0x00000017, 0x00003D28, + 0x00004137, 0x0000013D, 0x00050051, 0x0000000B, 0x00005D1C, 0x00003D28, 0x00000000, 0x000300F7, + 0x00002DCB, 0x00000000, 0x000400FA, 0x00004E83, 0x0000299C, 0x000055A9, 0x000200F8, 0x0000299C, + 0x000500C7, 0x0000000B, 0x00004505, 0x00005D1C, 0x000009C8, 0x000500C7, 0x0000000B, 0x00005D98, + 0x00005D1C, 0x00000986, 0x000500C2, 0x0000000B, 0x00005560, 0x00005D98, 0x00000A0D, 0x000500C7, + 0x0000000B, 0x00001FD1, 0x00004505, 0x00005560, 0x000500C4, 0x0000000B, 0x0000602D, 0x00001FD1, + 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059B8, 0x00001FD1, 0x00000A0D, 0x000500C5, 0x0000000B, + 0x0000496E, 0x0000602D, 0x000059B8, 0x000500C5, 0x0000000B, 0x00003EB5, 0x00001FD1, 0x0000496E, + 0x000500C7, 0x0000000B, 0x00004789, 0x00005D1C, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003961, + 0x00004789, 0x00000944, 0x000500C7, 0x0000000B, 0x00004FBA, 0x00003961, 0x00003EB5, 0x000500C2, + 0x0000000B, 0x0000503F, 0x00004505, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000615E, 0x00004789, + 0x0000503F, 0x000500C2, 0x0000000B, 0x000055A8, 0x00005D98, 0x00000A10, 0x000500C5, 0x0000000B, + 0x0000589B, 0x0000615E, 0x000055A8, 0x000500C6, 0x0000000B, 0x00001E31, 0x0000589B, 0x000009E9, + 0x000400C8, 0x0000000B, 0x0000254C, 0x0000503F, 0x000500C7, 0x0000000B, 0x00003925, 0x00004789, + 0x0000254C, 0x000400C8, 0x0000000B, 0x000020F1, 0x000055A8, 0x000500C7, 0x0000000B, 0x00002C97, + 0x00003925, 0x000020F1, 0x000500C5, 0x0000000B, 0x00001A97, 0x00005D1C, 0x00001E31, 0x00050082, + 0x0000000B, 0x00004C3D, 0x00001A97, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A20, 0x00004C3D, + 0x00002C97, 0x000500C4, 0x0000000B, 0x00004738, 0x00002C97, 0x00000A10, 0x000500C5, 0x0000000B, + 0x00003C06, 0x00003A20, 0x00004738, 0x000400C8, 0x0000000B, 0x00002F7E, 0x00003EB5, 0x000500C7, + 0x0000000B, 0x00004854, 0x00003C06, 0x00002F7E, 0x000500C5, 0x0000000B, 0x00001870, 0x00004854, + 0x00004FBA, 0x000200F9, 0x00002DCB, 0x000200F8, 0x000055A9, 0x000500C7, 0x0000000B, 0x00004E73, + 0x00005D1C, 0x000009E9, 0x000500C7, 0x0000000B, 0x00005D6A, 0x00005D1C, 0x000009C8, 0x000500C2, + 0x0000000B, 0x000056EB, 0x00005D6A, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00005DC4, 0x00004E73, + 0x000056EB, 0x000500C7, 0x0000000B, 0x00004C93, 0x00005D1C, 0x00000986, 0x000500C2, 0x0000000B, + 0x0000508B, 0x00004C93, 0x00000A10, 0x000500C5, 0x0000000B, 0x00005EE3, 0x00005DC4, 0x0000508B, + 0x000500C6, 0x0000000B, 0x00001E32, 0x00005EE3, 0x000009E9, 0x000400C8, 0x0000000B, 0x0000254D, + 0x000056EB, 0x000500C7, 0x0000000B, 0x00003926, 0x00004E73, 0x0000254D, 0x000400C8, 0x0000000B, + 0x000020F2, 0x0000508B, 0x000500C7, 0x0000000B, 0x00002C98, 0x00003926, 0x000020F2, 0x000500C5, + 0x0000000B, 0x00001A98, 0x00005D1C, 0x00001E32, 0x00050082, 0x0000000B, 0x00004C3E, 0x00001A98, + 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A21, 0x00004C3E, 0x00002C98, 0x000500C4, 0x0000000B, + 0x000046EC, 0x00002C98, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00003E8C, 0x00003A21, 0x000046EC, + 0x000500C4, 0x0000000B, 0x00001FBA, 0x00002C98, 0x00000A10, 0x000500C5, 0x0000000B, 0x00001E84, + 0x00003E8C, 0x00001FBA, 0x000200F9, 0x00002DCB, 0x000200F8, 0x00002DCB, 0x000700F5, 0x0000000B, + 0x00005025, 0x00001870, 0x0000299C, 0x00001E84, 0x000055A9, 0x00050051, 0x0000000B, 0x000040EC, + 0x00003D28, 0x00000001, 0x000300F7, 0x00002DCC, 0x00000000, 0x000400FA, 0x00004E84, 0x0000299D, + 0x000055AB, 0x000200F8, 0x0000299D, 0x000500C7, 0x0000000B, 0x00004506, 0x000040EC, 0x000009C8, + 0x000500C7, 0x0000000B, 0x00005D99, 0x000040EC, 0x00000986, 0x000500C2, 0x0000000B, 0x00005561, + 0x00005D99, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FD2, 0x00004506, 0x00005561, 0x000500C4, + 0x0000000B, 0x0000602E, 0x00001FD2, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059B9, 0x00001FD2, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000496F, 0x0000602E, 0x000059B9, 0x000500C5, 0x0000000B, + 0x00003EB6, 0x00001FD2, 0x0000496F, 0x000500C7, 0x0000000B, 0x0000478A, 0x000040EC, 0x000009E9, + 0x000500C5, 0x0000000B, 0x00003962, 0x0000478A, 0x00000944, 0x000500C7, 0x0000000B, 0x00004FBB, + 0x00003962, 0x00003EB6, 0x000500C2, 0x0000000B, 0x00005040, 0x00004506, 0x00000A0D, 0x000500C5, + 0x0000000B, 0x0000615F, 0x0000478A, 0x00005040, 0x000500C2, 0x0000000B, 0x000055AA, 0x00005D99, + 0x00000A10, 0x000500C5, 0x0000000B, 0x0000589C, 0x0000615F, 0x000055AA, 0x000500C6, 0x0000000B, + 0x00001E33, 0x0000589C, 0x000009E9, 0x000400C8, 0x0000000B, 0x0000254E, 0x00005040, 0x000500C7, + 0x0000000B, 0x00003927, 0x0000478A, 0x0000254E, 0x000400C8, 0x0000000B, 0x000020F3, 0x000055AA, + 0x000500C7, 0x0000000B, 0x00002C99, 0x00003927, 0x000020F3, 0x000500C5, 0x0000000B, 0x00001A99, + 0x000040EC, 0x00001E33, 0x00050082, 0x0000000B, 0x00004C3F, 0x00001A99, 0x000009E9, 0x000500C5, + 0x0000000B, 0x00003A22, 0x00004C3F, 0x00002C99, 0x000500C4, 0x0000000B, 0x00004739, 0x00002C99, + 0x00000A10, 0x000500C5, 0x0000000B, 0x00003C07, 0x00003A22, 0x00004739, 0x000400C8, 0x0000000B, + 0x00002F7F, 0x00003EB6, 0x000500C7, 0x0000000B, 0x00004855, 0x00003C07, 0x00002F7F, 0x000500C5, + 0x0000000B, 0x00001871, 0x00004855, 0x00004FBB, 0x000200F9, 0x00002DCC, 0x000200F8, 0x000055AB, + 0x000500C7, 0x0000000B, 0x00004E74, 0x000040EC, 0x000009E9, 0x000500C7, 0x0000000B, 0x00005D6B, + 0x000040EC, 0x000009C8, 0x000500C2, 0x0000000B, 0x000056EC, 0x00005D6B, 0x00000A0D, 0x000500C5, + 0x0000000B, 0x00005DC5, 0x00004E74, 0x000056EC, 0x000500C7, 0x0000000B, 0x00004C94, 0x000040EC, + 0x00000986, 0x000500C2, 0x0000000B, 0x0000508C, 0x00004C94, 0x00000A10, 0x000500C5, 0x0000000B, + 0x00005EE4, 0x00005DC5, 0x0000508C, 0x000500C6, 0x0000000B, 0x00001E34, 0x00005EE4, 0x000009E9, + 0x000400C8, 0x0000000B, 0x0000254F, 0x000056EC, 0x000500C7, 0x0000000B, 0x00003928, 0x00004E74, + 0x0000254F, 0x000400C8, 0x0000000B, 0x000020F4, 0x0000508C, 0x000500C7, 0x0000000B, 0x00002C9A, + 0x00003928, 0x000020F4, 0x000500C5, 0x0000000B, 0x00001A9A, 0x000040EC, 0x00001E34, 0x00050082, + 0x0000000B, 0x00004C40, 0x00001A9A, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A23, 0x00004C40, + 0x00002C9A, 0x000500C4, 0x0000000B, 0x000046ED, 0x00002C9A, 0x00000A0D, 0x000500C5, 0x0000000B, + 0x00003E8D, 0x00003A23, 0x000046ED, 0x000500C4, 0x0000000B, 0x00001FBB, 0x00002C9A, 0x00000A10, + 0x000500C5, 0x0000000B, 0x00001E85, 0x00003E8D, 0x00001FBB, 0x000200F9, 0x00002DCC, 0x000200F8, + 0x00002DCC, 0x000700F5, 0x0000000B, 0x00005026, 0x00001871, 0x0000299D, 0x00001E85, 0x000055AB, + 0x00050051, 0x0000000B, 0x000040ED, 0x00003D28, 0x00000002, 0x000300F7, 0x00002DCD, 0x00000000, + 0x000400FA, 0x00004E85, 0x0000299E, 0x000055AD, 0x000200F8, 0x0000299E, 0x000500C7, 0x0000000B, + 0x00004507, 0x000040ED, 0x000009C8, 0x000500C7, 0x0000000B, 0x00005D9A, 0x000040ED, 0x00000986, + 0x000500C2, 0x0000000B, 0x00005562, 0x00005D9A, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FD3, + 0x00004507, 0x00005562, 0x000500C4, 0x0000000B, 0x0000602F, 0x00001FD3, 0x00000A0D, 0x000500C2, + 0x0000000B, 0x000059BA, 0x00001FD3, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004970, 0x0000602F, + 0x000059BA, 0x000500C5, 0x0000000B, 0x00003EB7, 0x00001FD3, 0x00004970, 0x000500C7, 0x0000000B, + 0x0000478B, 0x000040ED, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003963, 0x0000478B, 0x00000944, + 0x000500C7, 0x0000000B, 0x00004FBC, 0x00003963, 0x00003EB7, 0x000500C2, 0x0000000B, 0x00005041, + 0x00004507, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00006160, 0x0000478B, 0x00005041, 0x000500C2, + 0x0000000B, 0x000055AC, 0x00005D9A, 0x00000A10, 0x000500C5, 0x0000000B, 0x0000589D, 0x00006160, + 0x000055AC, 0x000500C6, 0x0000000B, 0x00001E35, 0x0000589D, 0x000009E9, 0x000400C8, 0x0000000B, + 0x00002550, 0x00005041, 0x000500C7, 0x0000000B, 0x00003929, 0x0000478B, 0x00002550, 0x000400C8, + 0x0000000B, 0x000020F5, 0x000055AC, 0x000500C7, 0x0000000B, 0x00002C9B, 0x00003929, 0x000020F5, + 0x000500C5, 0x0000000B, 0x00001A9B, 0x000040ED, 0x00001E35, 0x00050082, 0x0000000B, 0x00004C41, + 0x00001A9B, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A24, 0x00004C41, 0x00002C9B, 0x000500C4, + 0x0000000B, 0x0000473A, 0x00002C9B, 0x00000A10, 0x000500C5, 0x0000000B, 0x00003C08, 0x00003A24, + 0x0000473A, 0x000400C8, 0x0000000B, 0x00002F80, 0x00003EB7, 0x000500C7, 0x0000000B, 0x00004856, + 0x00003C08, 0x00002F80, 0x000500C5, 0x0000000B, 0x00001872, 0x00004856, 0x00004FBC, 0x000200F9, + 0x00002DCD, 0x000200F8, 0x000055AD, 0x000500C7, 0x0000000B, 0x00004E75, 0x000040ED, 0x000009E9, + 0x000500C7, 0x0000000B, 0x00005D6C, 0x000040ED, 0x000009C8, 0x000500C2, 0x0000000B, 0x000056ED, + 0x00005D6C, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00005DC6, 0x00004E75, 0x000056ED, 0x000500C7, + 0x0000000B, 0x00004C95, 0x000040ED, 0x00000986, 0x000500C2, 0x0000000B, 0x0000508D, 0x00004C95, + 0x00000A10, 0x000500C5, 0x0000000B, 0x00005EE5, 0x00005DC6, 0x0000508D, 0x000500C6, 0x0000000B, + 0x00001E36, 0x00005EE5, 0x000009E9, 0x000400C8, 0x0000000B, 0x00002551, 0x000056ED, 0x000500C7, + 0x0000000B, 0x0000392A, 0x00004E75, 0x00002551, 0x000400C8, 0x0000000B, 0x000020F6, 0x0000508D, + 0x000500C7, 0x0000000B, 0x00002C9C, 0x0000392A, 0x000020F6, 0x000500C5, 0x0000000B, 0x00001A9C, + 0x000040ED, 0x00001E36, 0x00050082, 0x0000000B, 0x00004C42, 0x00001A9C, 0x000009E9, 0x000500C5, + 0x0000000B, 0x00003A25, 0x00004C42, 0x00002C9C, 0x000500C4, 0x0000000B, 0x000046EE, 0x00002C9C, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x00003E8E, 0x00003A25, 0x000046EE, 0x000500C4, 0x0000000B, + 0x00001FBC, 0x00002C9C, 0x00000A10, 0x000500C5, 0x0000000B, 0x00001E86, 0x00003E8E, 0x00001FBC, + 0x000200F9, 0x00002DCD, 0x000200F8, 0x00002DCD, 0x000700F5, 0x0000000B, 0x00005027, 0x00001872, + 0x0000299E, 0x00001E86, 0x000055AD, 0x00050051, 0x0000000B, 0x000040EE, 0x00003D28, 0x00000003, + 0x000300F7, 0x00002DB6, 0x00000000, 0x000400FA, 0x00004E86, 0x0000299F, 0x000055BF, 0x000200F8, + 0x0000299F, 0x000500C7, 0x0000000B, 0x00004508, 0x000040EE, 0x000009C8, 0x000500C7, 0x0000000B, + 0x00005D9B, 0x000040EE, 0x00000986, 0x000500C2, 0x0000000B, 0x00005563, 0x00005D9B, 0x00000A0D, + 0x000500C7, 0x0000000B, 0x00001FD4, 0x00004508, 0x00005563, 0x000500C4, 0x0000000B, 0x00006030, + 0x00001FD4, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059BB, 0x00001FD4, 0x00000A0D, 0x000500C5, + 0x0000000B, 0x00004971, 0x00006030, 0x000059BB, 0x000500C5, 0x0000000B, 0x00003EB8, 0x00001FD4, + 0x00004971, 0x000500C7, 0x0000000B, 0x0000478C, 0x000040EE, 0x000009E9, 0x000500C5, 0x0000000B, + 0x00003964, 0x0000478C, 0x00000944, 0x000500C7, 0x0000000B, 0x00004FBD, 0x00003964, 0x00003EB8, + 0x000500C2, 0x0000000B, 0x00005042, 0x00004508, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00006161, + 0x0000478C, 0x00005042, 0x000500C2, 0x0000000B, 0x000055AE, 0x00005D9B, 0x00000A10, 0x000500C5, + 0x0000000B, 0x0000589E, 0x00006161, 0x000055AE, 0x000500C6, 0x0000000B, 0x00001E37, 0x0000589E, + 0x000009E9, 0x000400C8, 0x0000000B, 0x00002552, 0x00005042, 0x000500C7, 0x0000000B, 0x0000392B, + 0x0000478C, 0x00002552, 0x000400C8, 0x0000000B, 0x000020F7, 0x000055AE, 0x000500C7, 0x0000000B, + 0x00002C9D, 0x0000392B, 0x000020F7, 0x000500C5, 0x0000000B, 0x00001A9D, 0x000040EE, 0x00001E37, + 0x00050082, 0x0000000B, 0x00004C43, 0x00001A9D, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A26, + 0x00004C43, 0x00002C9D, 0x000500C4, 0x0000000B, 0x0000473B, 0x00002C9D, 0x00000A10, 0x000500C5, + 0x0000000B, 0x00003C09, 0x00003A26, 0x0000473B, 0x000400C8, 0x0000000B, 0x00002F81, 0x00003EB8, + 0x000500C7, 0x0000000B, 0x00004857, 0x00003C09, 0x00002F81, 0x000500C5, 0x0000000B, 0x00001873, + 0x00004857, 0x00004FBD, 0x000200F9, 0x00002DB6, 0x000200F8, 0x000055BF, 0x000500C7, 0x0000000B, + 0x00004E76, 0x000040EE, 0x000009E9, 0x000500C7, 0x0000000B, 0x00005D6D, 0x000040EE, 0x000009C8, + 0x000500C2, 0x0000000B, 0x000056EE, 0x00005D6D, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00005DC7, + 0x00004E76, 0x000056EE, 0x000500C7, 0x0000000B, 0x00004C96, 0x000040EE, 0x00000986, 0x000500C2, + 0x0000000B, 0x0000508E, 0x00004C96, 0x00000A10, 0x000500C5, 0x0000000B, 0x00005EE6, 0x00005DC7, + 0x0000508E, 0x000500C6, 0x0000000B, 0x00001E38, 0x00005EE6, 0x000009E9, 0x000400C8, 0x0000000B, + 0x00002553, 0x000056EE, 0x000500C7, 0x0000000B, 0x0000392C, 0x00004E76, 0x00002553, 0x000400C8, + 0x0000000B, 0x000020F8, 0x0000508E, 0x000500C7, 0x0000000B, 0x00002C9E, 0x0000392C, 0x000020F8, + 0x000500C5, 0x0000000B, 0x00001A9E, 0x000040EE, 0x00001E38, 0x00050082, 0x0000000B, 0x00004C44, + 0x00001A9E, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A27, 0x00004C44, 0x00002C9E, 0x000500C4, + 0x0000000B, 0x000046EF, 0x00002C9E, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00003E8F, 0x00003A27, + 0x000046EF, 0x000500C4, 0x0000000B, 0x00001FBD, 0x00002C9E, 0x00000A10, 0x000500C5, 0x0000000B, + 0x00001E87, 0x00003E8F, 0x00001FBD, 0x000200F9, 0x00002DB6, 0x000200F8, 0x00002DB6, 0x000700F5, + 0x0000000B, 0x000050D0, 0x00001873, 0x0000299F, 0x00001E87, 0x000055BF, 0x00070050, 0x00000017, + 0x000060EC, 0x00005025, 0x00005026, 0x00005027, 0x000050D0, 0x000300F7, 0x00004F4B, 0x00000000, + 0x000400FA, 0x00004E83, 0x000029A0, 0x000038C6, 0x000200F8, 0x000029A0, 0x000500C7, 0x0000000B, + 0x00004509, 0x00005025, 0x0000003A, 0x000500C7, 0x0000000B, 0x00005D9C, 0x00005025, 0x0000022D, + 0x000500C2, 0x0000000B, 0x00005564, 0x00005D9C, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FD5, + 0x00004509, 0x00005564, 0x000500C4, 0x0000000B, 0x00006031, 0x00001FD5, 0x00000A0D, 0x000500C2, + 0x0000000B, 0x000059BC, 0x00001FD5, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004984, 0x00006031, + 0x000059BC, 0x000500C5, 0x0000000B, 0x00003E32, 0x00001FD5, 0x00004984, 0x000400C8, 0x0000000B, + 0x00002113, 0x00003E32, 0x000500C7, 0x0000000B, 0x0000276A, 0x00005025, 0x00002113, 0x00050082, + 0x0000000B, 0x00003FB4, 0x00000908, 0x0000276A, 0x000500C7, 0x0000000B, 0x0000440F, 0x00003FB4, + 0x00002113, 0x000500C7, 0x0000000B, 0x00004267, 0x0000440F, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003575, 0x00001966, 0x00004267, 0x000500C7, 0x0000000B, 0x000055E7, 0x0000276A, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00004FBE, 0x00003330, 0x000055E7, 0x00050080, 0x0000000B, 0x00004DA3, + 0x00003575, 0x00004FBE, 0x00050086, 0x0000000B, 0x000032E8, 0x00004DA3, 0x00000A19, 0x000500C2, + 0x0000000B, 0x00005A12, 0x0000440F, 0x00000A13, 0x000500C7, 0x0000000B, 0x00002251, 0x00005A12, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AD3, 0x00001966, 0x00002251, 0x000500C2, 0x0000000B, + 0x00003414, 0x0000276A, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061AD, 0x00003414, 0x00000A1F, + 0x00050084, 0x0000000B, 0x0000629A, 0x00003330, 0x000061AD, 0x00050080, 0x0000000B, 0x00004DC8, + 0x00003AD3, 0x0000629A, 0x00050086, 0x0000000B, 0x00003168, 0x00004DC8, 0x00000A19, 0x000500C4, + 0x0000000B, 0x00001FF0, 0x00003168, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D91, 0x000032E8, + 0x00001FF0, 0x000500C2, 0x0000000B, 0x000055C0, 0x0000440F, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x000044CA, 0x000055C0, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AD4, 0x00001966, 0x000044CA, + 0x000500C2, 0x0000000B, 0x00003415, 0x0000276A, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061AE, + 0x00003415, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000629B, 0x00003330, 0x000061AE, 0x00050080, + 0x0000000B, 0x00004DA4, 0x00003AD4, 0x0000629B, 0x00050086, 0x0000000B, 0x000032E9, 0x00004DA4, + 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A13, 0x0000440F, 0x00000A25, 0x000500C7, 0x0000000B, + 0x00002252, 0x00005A13, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AD5, 0x00001966, 0x00002252, + 0x000500C2, 0x0000000B, 0x00003418, 0x0000276A, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061AF, + 0x00003418, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000629C, 0x00003330, 0x000061AF, 0x00050080, + 0x0000000B, 0x00004DC9, 0x00003AD5, 0x0000629C, 0x00050086, 0x0000000B, 0x00003169, 0x00004DC9, + 0x00000A19, 0x000500C4, 0x0000000B, 0x000061F9, 0x00003169, 0x00000A3A, 0x000500C5, 0x0000000B, + 0x00002014, 0x000032E9, 0x000061F9, 0x00050050, 0x00000011, 0x0000278E, 0x00001D91, 0x00002014, + 0x000500C7, 0x0000000B, 0x00005ED4, 0x00005025, 0x00003E32, 0x000500C7, 0x0000000B, 0x00004000, + 0x00005ED4, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C6F, 0x00005ED4, 0x00000A22, 0x000500C4, + 0x0000000B, 0x0000610D, 0x00004C6F, 0x00000A31, 0x000500C5, 0x0000000B, 0x0000465D, 0x00004000, + 0x0000610D, 0x000500C2, 0x0000000B, 0x00005AB0, 0x00005ED4, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x0000621E, 0x00005AB0, 0x00000A0D, 0x000500C7, 0x0000000B, 0x0000494B, 0x00005ED4, 0x00000447, + 0x000500C4, 0x0000000B, 0x0000589F, 0x0000494B, 0x00000A1F, 0x000500C5, 0x0000000B, 0x000043EF, + 0x0000621E, 0x0000589F, 0x00050050, 0x00000011, 0x00004F8F, 0x0000465D, 0x000043EF, 0x00050084, + 0x00000011, 0x0000511F, 0x00004F8F, 0x00000474, 0x00050080, 0x00000011, 0x00005D36, 0x0000278E, + 0x0000511F, 0x000200F9, 0x00004F4B, 0x000200F8, 0x000038C6, 0x000400C8, 0x0000000B, 0x000029DC, + 0x00005025, 0x000500C7, 0x0000000B, 0x00003C0A, 0x000029DC, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00004538, 0x00001966, 0x00003C0A, 0x000500C7, 0x0000000B, 0x000055E9, 0x00005025, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00004FBF, 0x00003330, 0x000055E9, 0x00050080, 0x0000000B, 0x00004DA5, + 0x00004538, 0x00004FBF, 0x00050086, 0x0000000B, 0x000032EA, 0x00004DA5, 0x00000A1F, 0x000500C2, + 0x0000000B, 0x00005A14, 0x000029DC, 0x00000A13, 0x000500C7, 0x0000000B, 0x00002254, 0x00005A14, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AD6, 0x00001966, 0x00002254, 0x000500C2, 0x0000000B, + 0x00003419, 0x00005025, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061B0, 0x00003419, 0x00000A1F, + 0x00050084, 0x0000000B, 0x0000629D, 0x00003330, 0x000061B0, 0x00050080, 0x0000000B, 0x00004DCA, + 0x00003AD6, 0x0000629D, 0x00050086, 0x0000000B, 0x0000316A, 0x00004DCA, 0x00000A1F, 0x000500C4, + 0x0000000B, 0x00001FF1, 0x0000316A, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D92, 0x000032EA, + 0x00001FF1, 0x000500C2, 0x0000000B, 0x000055C1, 0x000029DC, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x000044CB, 0x000055C1, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AD7, 0x00001966, 0x000044CB, + 0x000500C2, 0x0000000B, 0x0000341A, 0x00005025, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061B1, + 0x0000341A, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000629E, 0x00003330, 0x000061B1, 0x00050080, + 0x0000000B, 0x00004DA6, 0x00003AD7, 0x0000629E, 0x00050086, 0x0000000B, 0x000032EB, 0x00004DA6, + 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A15, 0x000029DC, 0x00000A25, 0x000500C7, 0x0000000B, + 0x00002255, 0x00005A15, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AD8, 0x00001966, 0x00002255, + 0x000500C2, 0x0000000B, 0x0000341B, 0x00005025, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061B2, + 0x0000341B, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000629F, 0x00003330, 0x000061B2, 0x00050080, + 0x0000000B, 0x00004DCB, 0x00003AD8, 0x0000629F, 0x00050086, 0x0000000B, 0x0000316B, 0x00004DCB, + 0x00000A1F, 0x000500C4, 0x0000000B, 0x000061FA, 0x0000316B, 0x00000A3A, 0x000500C5, 0x0000000B, + 0x000023CA, 0x000032EB, 0x000061FA, 0x00050050, 0x00000011, 0x000053E5, 0x00001D92, 0x000023CA, + 0x000200F9, 0x00004F4B, 0x000200F8, 0x00004F4B, 0x000700F5, 0x00000011, 0x00002AAF, 0x00005D36, + 0x000029A0, 0x000053E5, 0x000038C6, 0x000300F7, 0x00004B84, 0x00000000, 0x000400FA, 0x00004E84, + 0x000029A1, 0x000038C7, 0x000200F8, 0x000029A1, 0x000500C7, 0x0000000B, 0x0000450A, 0x00005026, + 0x0000003A, 0x000500C7, 0x0000000B, 0x00005D9D, 0x00005026, 0x0000022D, 0x000500C2, 0x0000000B, + 0x00005565, 0x00005D9D, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FD6, 0x0000450A, 0x00005565, + 0x000500C4, 0x0000000B, 0x00006032, 0x00001FD6, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059BD, + 0x00001FD6, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004985, 0x00006032, 0x000059BD, 0x000500C5, + 0x0000000B, 0x00003E33, 0x00001FD6, 0x00004985, 0x000400C8, 0x0000000B, 0x00002114, 0x00003E33, + 0x000500C7, 0x0000000B, 0x0000276B, 0x00005026, 0x00002114, 0x00050082, 0x0000000B, 0x00003FB5, + 0x00000908, 0x0000276B, 0x000500C7, 0x0000000B, 0x00004410, 0x00003FB5, 0x00002114, 0x000500C7, + 0x0000000B, 0x00004268, 0x00004410, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003576, 0x00003281, + 0x00004268, 0x000500C7, 0x0000000B, 0x000055EA, 0x0000276B, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00004FC0, 0x00003331, 0x000055EA, 0x00050080, 0x0000000B, 0x00004DA7, 0x00003576, 0x00004FC0, + 0x00050086, 0x0000000B, 0x000032EC, 0x00004DA7, 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A16, + 0x00004410, 0x00000A13, 0x000500C7, 0x0000000B, 0x00002256, 0x00005A16, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AD9, 0x00003281, 0x00002256, 0x000500C2, 0x0000000B, 0x0000341C, 0x0000276B, + 0x00000A13, 0x000500C7, 0x0000000B, 0x000061B3, 0x0000341C, 0x00000A1F, 0x00050084, 0x0000000B, + 0x000062A0, 0x00003331, 0x000061B3, 0x00050080, 0x0000000B, 0x00004DCC, 0x00003AD9, 0x000062A0, + 0x00050086, 0x0000000B, 0x0000316C, 0x00004DCC, 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FF2, + 0x0000316C, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D93, 0x000032EC, 0x00001FF2, 0x000500C2, + 0x0000000B, 0x000055C2, 0x00004410, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044CC, 0x000055C2, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ADA, 0x00003281, 0x000044CC, 0x000500C2, 0x0000000B, + 0x0000341D, 0x0000276B, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061B4, 0x0000341D, 0x00000A1F, + 0x00050084, 0x0000000B, 0x000062A1, 0x00003331, 0x000061B4, 0x00050080, 0x0000000B, 0x00004DCD, + 0x00003ADA, 0x000062A1, 0x00050086, 0x0000000B, 0x000032ED, 0x00004DCD, 0x00000A19, 0x000500C2, + 0x0000000B, 0x00005A17, 0x00004410, 0x00000A25, 0x000500C7, 0x0000000B, 0x00002257, 0x00005A17, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ADB, 0x00003281, 0x00002257, 0x000500C2, 0x0000000B, + 0x0000341E, 0x0000276B, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061B5, 0x0000341E, 0x00000A1F, + 0x00050084, 0x0000000B, 0x000062A2, 0x00003331, 0x000061B5, 0x00050080, 0x0000000B, 0x00004DCE, + 0x00003ADB, 0x000062A2, 0x00050086, 0x0000000B, 0x0000316D, 0x00004DCE, 0x00000A19, 0x000500C4, + 0x0000000B, 0x000061FB, 0x0000316D, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00002015, 0x000032ED, + 0x000061FB, 0x00050050, 0x00000011, 0x0000278F, 0x00001D93, 0x00002015, 0x000500C7, 0x0000000B, + 0x00005ED5, 0x00005026, 0x00003E33, 0x000500C7, 0x0000000B, 0x00004001, 0x00005ED5, 0x00000A0D, + 0x000500C7, 0x0000000B, 0x00004C70, 0x00005ED5, 0x00000A22, 0x000500C4, 0x0000000B, 0x0000610E, + 0x00004C70, 0x00000A31, 0x000500C5, 0x0000000B, 0x0000465E, 0x00004001, 0x0000610E, 0x000500C2, + 0x0000000B, 0x00005AB3, 0x00005ED5, 0x00000A1C, 0x000500C7, 0x0000000B, 0x0000621F, 0x00005AB3, + 0x00000A0D, 0x000500C7, 0x0000000B, 0x0000494C, 0x00005ED5, 0x00000447, 0x000500C4, 0x0000000B, + 0x000058A0, 0x0000494C, 0x00000A1F, 0x000500C5, 0x0000000B, 0x000043F0, 0x0000621F, 0x000058A0, + 0x00050050, 0x00000011, 0x00004F90, 0x0000465E, 0x000043F0, 0x00050084, 0x00000011, 0x00005120, + 0x00004F90, 0x00000474, 0x00050080, 0x00000011, 0x00005D37, 0x0000278F, 0x00005120, 0x000200F9, + 0x00004B84, 0x000200F8, 0x000038C7, 0x000400C8, 0x0000000B, 0x000029DD, 0x00005026, 0x000500C7, + 0x0000000B, 0x00003C0B, 0x000029DD, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004539, 0x00003281, + 0x00003C0B, 0x000500C7, 0x0000000B, 0x000055EB, 0x00005026, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00004FC1, 0x00003331, 0x000055EB, 0x00050080, 0x0000000B, 0x00004DCF, 0x00004539, 0x00004FC1, + 0x00050086, 0x0000000B, 0x000032EE, 0x00004DCF, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A18, + 0x000029DD, 0x00000A13, 0x000500C7, 0x0000000B, 0x00002258, 0x00005A18, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003ADC, 0x00003281, 0x00002258, 0x000500C2, 0x0000000B, 0x0000341F, 0x00005026, + 0x00000A13, 0x000500C7, 0x0000000B, 0x000061B6, 0x0000341F, 0x00000A1F, 0x00050084, 0x0000000B, + 0x000062A3, 0x00003331, 0x000061B6, 0x00050080, 0x0000000B, 0x00004DD0, 0x00003ADC, 0x000062A3, + 0x00050086, 0x0000000B, 0x0000316E, 0x00004DD0, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FF3, + 0x0000316E, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D94, 0x000032EE, 0x00001FF3, 0x000500C2, + 0x0000000B, 0x000055C3, 0x000029DD, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044CD, 0x000055C3, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ADD, 0x00003281, 0x000044CD, 0x000500C2, 0x0000000B, + 0x00003420, 0x00005026, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061B7, 0x00003420, 0x00000A1F, + 0x00050084, 0x0000000B, 0x000062A4, 0x00003331, 0x000061B7, 0x00050080, 0x0000000B, 0x00004DD1, + 0x00003ADD, 0x000062A4, 0x00050086, 0x0000000B, 0x000032EF, 0x00004DD1, 0x00000A1F, 0x000500C2, + 0x0000000B, 0x00005A19, 0x000029DD, 0x00000A25, 0x000500C7, 0x0000000B, 0x00002259, 0x00005A19, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ADE, 0x00003281, 0x00002259, 0x000500C2, 0x0000000B, + 0x00003421, 0x00005026, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061B8, 0x00003421, 0x00000A1F, + 0x00050084, 0x0000000B, 0x000062A5, 0x00003331, 0x000061B8, 0x00050080, 0x0000000B, 0x00004DD2, + 0x00003ADE, 0x000062A5, 0x00050086, 0x0000000B, 0x0000316F, 0x00004DD2, 0x00000A1F, 0x000500C4, + 0x0000000B, 0x000061FC, 0x0000316F, 0x00000A3A, 0x000500C5, 0x0000000B, 0x000023CB, 0x000032EF, + 0x000061FC, 0x00050050, 0x00000011, 0x000053E6, 0x00001D94, 0x000023CB, 0x000200F9, 0x00004B84, + 0x000200F8, 0x00004B84, 0x000700F5, 0x00000011, 0x00004938, 0x00005D37, 0x000029A1, 0x000053E6, + 0x000038C7, 0x000500C4, 0x00000011, 0x00002B1F, 0x00004938, 0x000007B7, 0x000500C5, 0x00000011, + 0x00005255, 0x00002AAF, 0x00002B1F, 0x000300F7, 0x00004F4C, 0x00000000, 0x000400FA, 0x00004E85, + 0x000029A2, 0x000038C8, 0x000200F8, 0x000029A2, 0x000500C7, 0x0000000B, 0x0000450B, 0x00005027, + 0x0000003A, 0x000500C7, 0x0000000B, 0x00005D9E, 0x00005027, 0x0000022D, 0x000500C2, 0x0000000B, + 0x00005566, 0x00005D9E, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FD7, 0x0000450B, 0x00005566, + 0x000500C4, 0x0000000B, 0x00006033, 0x00001FD7, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059BE, + 0x00001FD7, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004986, 0x00006033, 0x000059BE, 0x000500C5, + 0x0000000B, 0x00003E34, 0x00001FD7, 0x00004986, 0x000400C8, 0x0000000B, 0x00002115, 0x00003E34, + 0x000500C7, 0x0000000B, 0x0000276C, 0x00005027, 0x00002115, 0x00050082, 0x0000000B, 0x00003FB6, + 0x00000908, 0x0000276C, 0x000500C7, 0x0000000B, 0x00004412, 0x00003FB6, 0x00002115, 0x000500C7, + 0x0000000B, 0x00004269, 0x00004412, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003577, 0x00003282, + 0x00004269, 0x000500C7, 0x0000000B, 0x000055EC, 0x0000276C, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00004FC2, 0x00003333, 0x000055EC, 0x00050080, 0x0000000B, 0x00004DD3, 0x00003577, 0x00004FC2, + 0x00050086, 0x0000000B, 0x000032F0, 0x00004DD3, 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A1A, + 0x00004412, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000225A, 0x00005A1A, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003ADF, 0x00003282, 0x0000225A, 0x000500C2, 0x0000000B, 0x00003422, 0x0000276C, + 0x00000A13, 0x000500C7, 0x0000000B, 0x000061B9, 0x00003422, 0x00000A1F, 0x00050084, 0x0000000B, + 0x000062A6, 0x00003333, 0x000061B9, 0x00050080, 0x0000000B, 0x00004DD4, 0x00003ADF, 0x000062A6, + 0x00050086, 0x0000000B, 0x00003170, 0x00004DD4, 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FF4, + 0x00003170, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D95, 0x000032F0, 0x00001FF4, 0x000500C2, + 0x0000000B, 0x000055C4, 0x00004412, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044CE, 0x000055C4, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AE0, 0x00003282, 0x000044CE, 0x000500C2, 0x0000000B, + 0x00003423, 0x0000276C, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061BA, 0x00003423, 0x00000A1F, + 0x00050084, 0x0000000B, 0x000062A7, 0x00003333, 0x000061BA, 0x00050080, 0x0000000B, 0x00004DD5, + 0x00003AE0, 0x000062A7, 0x00050086, 0x0000000B, 0x000032F1, 0x00004DD5, 0x00000A19, 0x000500C2, + 0x0000000B, 0x00005A1B, 0x00004412, 0x00000A25, 0x000500C7, 0x0000000B, 0x0000225B, 0x00005A1B, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AE1, 0x00003282, 0x0000225B, 0x000500C2, 0x0000000B, + 0x00003424, 0x0000276C, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061BB, 0x00003424, 0x00000A1F, + 0x00050084, 0x0000000B, 0x000062A8, 0x00003333, 0x000061BB, 0x00050080, 0x0000000B, 0x00004DD6, + 0x00003AE1, 0x000062A8, 0x00050086, 0x0000000B, 0x00003171, 0x00004DD6, 0x00000A19, 0x000500C4, + 0x0000000B, 0x000061FD, 0x00003171, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00002016, 0x000032F1, + 0x000061FD, 0x00050050, 0x00000011, 0x00002790, 0x00001D95, 0x00002016, 0x000500C7, 0x0000000B, + 0x00005ED6, 0x00005027, 0x00003E34, 0x000500C7, 0x0000000B, 0x00004002, 0x00005ED6, 0x00000A0D, + 0x000500C7, 0x0000000B, 0x00004C71, 0x00005ED6, 0x00000A22, 0x000500C4, 0x0000000B, 0x0000610F, + 0x00004C71, 0x00000A31, 0x000500C5, 0x0000000B, 0x0000465F, 0x00004002, 0x0000610F, 0x000500C2, + 0x0000000B, 0x00005AB4, 0x00005ED6, 0x00000A1C, 0x000500C7, 0x0000000B, 0x00006220, 0x00005AB4, + 0x00000A0D, 0x000500C7, 0x0000000B, 0x0000494D, 0x00005ED6, 0x00000447, 0x000500C4, 0x0000000B, + 0x000058A1, 0x0000494D, 0x00000A1F, 0x000500C5, 0x0000000B, 0x000043F1, 0x00006220, 0x000058A1, + 0x00050050, 0x00000011, 0x00004F91, 0x0000465F, 0x000043F1, 0x00050084, 0x00000011, 0x00005121, + 0x00004F91, 0x00000474, 0x00050080, 0x00000011, 0x00005D38, 0x00002790, 0x00005121, 0x000200F9, + 0x00004F4C, 0x000200F8, 0x000038C8, 0x000400C8, 0x0000000B, 0x000029DE, 0x00005027, 0x000500C7, + 0x0000000B, 0x00003C0C, 0x000029DE, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000453A, 0x00003282, + 0x00003C0C, 0x000500C7, 0x0000000B, 0x000055ED, 0x00005027, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00004FC3, 0x00003333, 0x000055ED, 0x00050080, 0x0000000B, 0x00004DD7, 0x0000453A, 0x00004FC3, + 0x00050086, 0x0000000B, 0x000032F2, 0x00004DD7, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A1C, + 0x000029DE, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000225C, 0x00005A1C, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AE2, 0x00003282, 0x0000225C, 0x000500C2, 0x0000000B, 0x00003425, 0x00005027, + 0x00000A13, 0x000500C7, 0x0000000B, 0x000061BC, 0x00003425, 0x00000A1F, 0x00050084, 0x0000000B, + 0x000062A9, 0x00003333, 0x000061BC, 0x00050080, 0x0000000B, 0x00004DD8, 0x00003AE2, 0x000062A9, + 0x00050086, 0x0000000B, 0x00003172, 0x00004DD8, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FF5, + 0x00003172, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D96, 0x000032F2, 0x00001FF5, 0x000500C2, + 0x0000000B, 0x000055C5, 0x000029DE, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044CF, 0x000055C5, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AE3, 0x00003282, 0x000044CF, 0x000500C2, 0x0000000B, + 0x00003426, 0x00005027, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061BD, 0x00003426, 0x00000A1F, + 0x00050084, 0x0000000B, 0x000062AA, 0x00003333, 0x000061BD, 0x00050080, 0x0000000B, 0x00004DD9, + 0x00003AE3, 0x000062AA, 0x00050086, 0x0000000B, 0x000032F3, 0x00004DD9, 0x00000A1F, 0x000500C2, + 0x0000000B, 0x00005A1D, 0x000029DE, 0x00000A25, 0x000500C7, 0x0000000B, 0x0000225E, 0x00005A1D, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AE4, 0x00003282, 0x0000225E, 0x000500C2, 0x0000000B, + 0x00003427, 0x00005027, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061BE, 0x00003427, 0x00000A1F, + 0x00050084, 0x0000000B, 0x000062AB, 0x00003333, 0x000061BE, 0x00050080, 0x0000000B, 0x00004DDA, + 0x00003AE4, 0x000062AB, 0x00050086, 0x0000000B, 0x00003173, 0x00004DDA, 0x00000A1F, 0x000500C4, + 0x0000000B, 0x000061FE, 0x00003173, 0x00000A3A, 0x000500C5, 0x0000000B, 0x000023CC, 0x000032F3, + 0x000061FE, 0x00050050, 0x00000011, 0x000053E7, 0x00001D96, 0x000023CC, 0x000200F9, 0x00004F4C, + 0x000200F8, 0x00004F4C, 0x000700F5, 0x00000011, 0x00002AB0, 0x00005D38, 0x000029A2, 0x000053E7, + 0x000038C8, 0x000300F7, 0x00004B85, 0x00000000, 0x000400FA, 0x00004E86, 0x000029A3, 0x000038C9, + 0x000200F8, 0x000029A3, 0x000500C7, 0x0000000B, 0x0000450C, 0x000050D0, 0x0000003A, 0x000500C7, + 0x0000000B, 0x00005D9F, 0x000050D0, 0x0000022D, 0x000500C2, 0x0000000B, 0x00005567, 0x00005D9F, + 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FD8, 0x0000450C, 0x00005567, 0x000500C4, 0x0000000B, + 0x00006034, 0x00001FD8, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059BF, 0x00001FD8, 0x00000A0D, + 0x000500C5, 0x0000000B, 0x00004987, 0x00006034, 0x000059BF, 0x000500C5, 0x0000000B, 0x00003E35, + 0x00001FD8, 0x00004987, 0x000400C8, 0x0000000B, 0x00002116, 0x00003E35, 0x000500C7, 0x0000000B, + 0x0000276D, 0x000050D0, 0x00002116, 0x00050082, 0x0000000B, 0x00003FB7, 0x00000908, 0x0000276D, + 0x000500C7, 0x0000000B, 0x00004413, 0x00003FB7, 0x00002116, 0x000500C7, 0x0000000B, 0x0000426A, + 0x00004413, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003578, 0x00003283, 0x0000426A, 0x000500C7, + 0x0000000B, 0x000055EE, 0x0000276D, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FC4, 0x00003334, + 0x000055EE, 0x00050080, 0x0000000B, 0x00004DDB, 0x00003578, 0x00004FC4, 0x00050086, 0x0000000B, + 0x000032F4, 0x00004DDB, 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A1E, 0x00004413, 0x00000A13, + 0x000500C7, 0x0000000B, 0x0000225F, 0x00005A1E, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AE5, + 0x00003283, 0x0000225F, 0x000500C2, 0x0000000B, 0x00003428, 0x0000276D, 0x00000A13, 0x000500C7, + 0x0000000B, 0x000061BF, 0x00003428, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062AC, 0x00003334, + 0x000061BF, 0x00050080, 0x0000000B, 0x00004DDC, 0x00003AE5, 0x000062AC, 0x00050086, 0x0000000B, + 0x00003174, 0x00004DDC, 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FF6, 0x00003174, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x00001D97, 0x000032F4, 0x00001FF6, 0x000500C2, 0x0000000B, 0x000055C6, + 0x00004413, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044D0, 0x000055C6, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AE6, 0x00003283, 0x000044D0, 0x000500C2, 0x0000000B, 0x00003429, 0x0000276D, + 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061C0, 0x00003429, 0x00000A1F, 0x00050084, 0x0000000B, + 0x000062AD, 0x00003334, 0x000061C0, 0x00050080, 0x0000000B, 0x00004DDD, 0x00003AE6, 0x000062AD, + 0x00050086, 0x0000000B, 0x000032F5, 0x00004DDD, 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A1F, + 0x00004413, 0x00000A25, 0x000500C7, 0x0000000B, 0x00002260, 0x00005A1F, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AE7, 0x00003283, 0x00002260, 0x000500C2, 0x0000000B, 0x0000342A, 0x0000276D, + 0x00000A25, 0x000500C7, 0x0000000B, 0x000061C1, 0x0000342A, 0x00000A1F, 0x00050084, 0x0000000B, + 0x000062AE, 0x00003334, 0x000061C1, 0x00050080, 0x0000000B, 0x00004DDE, 0x00003AE7, 0x000062AE, + 0x00050086, 0x0000000B, 0x00003175, 0x00004DDE, 0x00000A19, 0x000500C4, 0x0000000B, 0x000061FF, + 0x00003175, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00002017, 0x000032F5, 0x000061FF, 0x00050050, + 0x00000011, 0x00002791, 0x00001D97, 0x00002017, 0x000500C7, 0x0000000B, 0x00005ED7, 0x000050D0, + 0x00003E35, 0x000500C7, 0x0000000B, 0x00004003, 0x00005ED7, 0x00000A0D, 0x000500C7, 0x0000000B, + 0x00004C72, 0x00005ED7, 0x00000A22, 0x000500C4, 0x0000000B, 0x00006110, 0x00004C72, 0x00000A31, + 0x000500C5, 0x0000000B, 0x00004660, 0x00004003, 0x00006110, 0x000500C2, 0x0000000B, 0x00005AB5, + 0x00005ED7, 0x00000A1C, 0x000500C7, 0x0000000B, 0x00006221, 0x00005AB5, 0x00000A0D, 0x000500C7, + 0x0000000B, 0x0000494E, 0x00005ED7, 0x00000447, 0x000500C4, 0x0000000B, 0x000058A2, 0x0000494E, + 0x00000A1F, 0x000500C5, 0x0000000B, 0x000043F2, 0x00006221, 0x000058A2, 0x00050050, 0x00000011, + 0x00004F92, 0x00004660, 0x000043F2, 0x00050084, 0x00000011, 0x00005122, 0x00004F92, 0x00000474, + 0x00050080, 0x00000011, 0x00005D39, 0x00002791, 0x00005122, 0x000200F9, 0x00004B85, 0x000200F8, + 0x000038C9, 0x000400C8, 0x0000000B, 0x000029DF, 0x000050D0, 0x000500C7, 0x0000000B, 0x00003C0D, + 0x000029DF, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000453B, 0x00003283, 0x00003C0D, 0x000500C7, + 0x0000000B, 0x000055EF, 0x000050D0, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FC5, 0x00003334, + 0x000055EF, 0x00050080, 0x0000000B, 0x00004DDF, 0x0000453B, 0x00004FC5, 0x00050086, 0x0000000B, + 0x000032F6, 0x00004DDF, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A20, 0x000029DF, 0x00000A13, + 0x000500C7, 0x0000000B, 0x00002261, 0x00005A20, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AE8, + 0x00003283, 0x00002261, 0x000500C2, 0x0000000B, 0x0000342B, 0x000050D0, 0x00000A13, 0x000500C7, + 0x0000000B, 0x000061C2, 0x0000342B, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062AF, 0x00003334, + 0x000061C2, 0x00050080, 0x0000000B, 0x00004DE0, 0x00003AE8, 0x000062AF, 0x00050086, 0x0000000B, + 0x00003176, 0x00004DE0, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FF7, 0x00003176, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x00001D98, 0x000032F6, 0x00001FF7, 0x000500C2, 0x0000000B, 0x000055C7, + 0x000029DF, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044D1, 0x000055C7, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AE9, 0x00003283, 0x000044D1, 0x000500C2, 0x0000000B, 0x0000342C, 0x000050D0, + 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061C3, 0x0000342C, 0x00000A1F, 0x00050084, 0x0000000B, + 0x000062B0, 0x00003334, 0x000061C3, 0x00050080, 0x0000000B, 0x00004DE1, 0x00003AE9, 0x000062B0, + 0x00050086, 0x0000000B, 0x000032F7, 0x00004DE1, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A21, + 0x000029DF, 0x00000A25, 0x000500C7, 0x0000000B, 0x00002262, 0x00005A21, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AEA, 0x00003283, 0x00002262, 0x000500C2, 0x0000000B, 0x0000342D, 0x000050D0, + 0x00000A25, 0x000500C7, 0x0000000B, 0x000061C4, 0x0000342D, 0x00000A1F, 0x00050084, 0x0000000B, + 0x000062B1, 0x00003334, 0x000061C4, 0x00050080, 0x0000000B, 0x00004DE2, 0x00003AEA, 0x000062B1, + 0x00050086, 0x0000000B, 0x00003177, 0x00004DE2, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00006200, + 0x00003177, 0x00000A3A, 0x000500C5, 0x0000000B, 0x000023CD, 0x000032F7, 0x00006200, 0x00050050, + 0x00000011, 0x000053E8, 0x00001D98, 0x000023CD, 0x000200F9, 0x00004B85, 0x000200F8, 0x00004B85, + 0x000700F5, 0x00000011, 0x00004939, 0x00005D39, 0x000029A3, 0x000053E8, 0x000038C9, 0x000500C4, + 0x00000011, 0x00001ECF, 0x00004939, 0x000007B7, 0x000500C5, 0x00000011, 0x000020FB, 0x00002AB0, + 0x00001ECF, 0x00050051, 0x0000000B, 0x00004E87, 0x00005255, 0x00000000, 0x00050051, 0x0000000B, + 0x00005CB4, 0x00005255, 0x00000001, 0x00050051, 0x0000000B, 0x00001DDD, 0x000020FB, 0x00000000, + 0x00050051, 0x0000000B, 0x00001D6B, 0x000020FB, 0x00000001, 0x00070050, 0x00000017, 0x00004756, + 0x00004E87, 0x00005CB4, 0x00001DDD, 0x00001D6B, 0x00060041, 0x00000294, 0x000025D1, 0x0000140E, + 0x00000A0B, 0x00003417, 0x0003003E, 0x000025D1, 0x00004756, 0x00050080, 0x0000000B, 0x000039F9, + 0x00003220, 0x00000A14, 0x000500B0, 0x00000009, 0x00002E0C, 0x000039F9, 0x000019C2, 0x000300F7, + 0x00004665, 0x00000002, 0x000400FA, 0x00002E0C, 0x0000592E, 0x00004665, 0x000200F8, 0x0000592E, + 0x00050080, 0x0000000B, 0x0000342E, 0x00003417, 0x00001B41, 0x000500C2, 0x00000017, 0x00003D29, + 0x000060EC, 0x00000215, 0x00050051, 0x0000000B, 0x00005D1D, 0x00003D29, 0x00000000, 0x000300F7, + 0x000042F9, 0x00000000, 0x000400FA, 0x00004E83, 0x000029A4, 0x000038CA, 0x000200F8, 0x000029A4, + 0x000500C7, 0x0000000B, 0x0000450D, 0x00005D1D, 0x0000003A, 0x000500C7, 0x0000000B, 0x00005DA0, + 0x00005D1D, 0x0000022D, 0x000500C2, 0x0000000B, 0x00005568, 0x00005DA0, 0x00000A0D, 0x000500C7, + 0x0000000B, 0x00001FD9, 0x0000450D, 0x00005568, 0x000500C4, 0x0000000B, 0x00006035, 0x00001FD9, + 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059C0, 0x00001FD9, 0x00000A0D, 0x000500C5, 0x0000000B, + 0x00004988, 0x00006035, 0x000059C0, 0x000500C5, 0x0000000B, 0x00003E36, 0x00001FD9, 0x00004988, + 0x000400C8, 0x0000000B, 0x00002117, 0x00003E36, 0x000500C7, 0x0000000B, 0x0000276E, 0x00005D1D, + 0x00002117, 0x00050082, 0x0000000B, 0x00003FB8, 0x00000908, 0x0000276E, 0x000500C7, 0x0000000B, + 0x00004414, 0x00003FB8, 0x00002117, 0x000500C7, 0x0000000B, 0x0000426B, 0x00004414, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003579, 0x00001966, 0x0000426B, 0x000500C7, 0x0000000B, 0x000055F0, + 0x0000276E, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FC6, 0x00003330, 0x000055F0, 0x00050080, + 0x0000000B, 0x00004DE3, 0x00003579, 0x00004FC6, 0x00050086, 0x0000000B, 0x000032F8, 0x00004DE3, + 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A22, 0x00004414, 0x00000A13, 0x000500C7, 0x0000000B, + 0x00002263, 0x00005A22, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AEB, 0x00001966, 0x00002263, + 0x000500C2, 0x0000000B, 0x0000342F, 0x0000276E, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061C5, + 0x0000342F, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062B2, 0x00003330, 0x000061C5, 0x00050080, + 0x0000000B, 0x00004DE4, 0x00003AEB, 0x000062B2, 0x00050086, 0x0000000B, 0x00003178, 0x00004DE4, + 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FF8, 0x00003178, 0x00000A3A, 0x000500C5, 0x0000000B, + 0x00001D99, 0x000032F8, 0x00001FF8, 0x000500C2, 0x0000000B, 0x000055C8, 0x00004414, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x000044D2, 0x000055C8, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AEC, + 0x00001966, 0x000044D2, 0x000500C2, 0x0000000B, 0x00003430, 0x0000276E, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x000061C6, 0x00003430, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062B3, 0x00003330, + 0x000061C6, 0x00050080, 0x0000000B, 0x00004DE5, 0x00003AEC, 0x000062B3, 0x00050086, 0x0000000B, + 0x000032F9, 0x00004DE5, 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A23, 0x00004414, 0x00000A25, + 0x000500C7, 0x0000000B, 0x00002264, 0x00005A23, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AED, + 0x00001966, 0x00002264, 0x000500C2, 0x0000000B, 0x00003431, 0x0000276E, 0x00000A25, 0x000500C7, + 0x0000000B, 0x000061C7, 0x00003431, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062B4, 0x00003330, + 0x000061C7, 0x00050080, 0x0000000B, 0x00004DE6, 0x00003AED, 0x000062B4, 0x00050086, 0x0000000B, + 0x00003179, 0x00004DE6, 0x00000A19, 0x000500C4, 0x0000000B, 0x00006201, 0x00003179, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x00002018, 0x000032F9, 0x00006201, 0x00050050, 0x00000011, 0x00002792, + 0x00001D99, 0x00002018, 0x000500C7, 0x0000000B, 0x00005ED8, 0x00005D1D, 0x00003E36, 0x000500C7, + 0x0000000B, 0x00004004, 0x00005ED8, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C73, 0x00005ED8, + 0x00000A22, 0x000500C4, 0x0000000B, 0x00006111, 0x00004C73, 0x00000A31, 0x000500C5, 0x0000000B, + 0x00004661, 0x00004004, 0x00006111, 0x000500C2, 0x0000000B, 0x00005AB6, 0x00005ED8, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x00006222, 0x00005AB6, 0x00000A0D, 0x000500C7, 0x0000000B, 0x0000494F, + 0x00005ED8, 0x00000447, 0x000500C4, 0x0000000B, 0x000058A3, 0x0000494F, 0x00000A1F, 0x000500C5, + 0x0000000B, 0x000043F3, 0x00006222, 0x000058A3, 0x00050050, 0x00000011, 0x00004F93, 0x00004661, + 0x000043F3, 0x00050084, 0x00000011, 0x00005123, 0x00004F93, 0x00000474, 0x00050080, 0x00000011, + 0x00005D3A, 0x00002792, 0x00005123, 0x000200F9, 0x000042F9, 0x000200F8, 0x000038CA, 0x000400C8, + 0x0000000B, 0x000029E0, 0x00005D1D, 0x000500C7, 0x0000000B, 0x00003C0E, 0x000029E0, 0x00000A1F, + 0x00050084, 0x0000000B, 0x0000453C, 0x00001966, 0x00003C0E, 0x000500C7, 0x0000000B, 0x000055F1, + 0x00005D1D, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FC8, 0x00003330, 0x000055F1, 0x00050080, + 0x0000000B, 0x00004DE7, 0x0000453C, 0x00004FC8, 0x00050086, 0x0000000B, 0x000032FA, 0x00004DE7, + 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A24, 0x000029E0, 0x00000A13, 0x000500C7, 0x0000000B, + 0x00002265, 0x00005A24, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AEE, 0x00001966, 0x00002265, + 0x000500C2, 0x0000000B, 0x00003432, 0x00005D1D, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061C8, + 0x00003432, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062B5, 0x00003330, 0x000061C8, 0x00050080, + 0x0000000B, 0x00004DE8, 0x00003AEE, 0x000062B5, 0x00050086, 0x0000000B, 0x0000317A, 0x00004DE8, + 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FF9, 0x0000317A, 0x00000A3A, 0x000500C5, 0x0000000B, + 0x00001D9A, 0x000032FA, 0x00001FF9, 0x000500C2, 0x0000000B, 0x000055C9, 0x000029E0, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x000044D3, 0x000055C9, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AEF, + 0x00001966, 0x000044D3, 0x000500C2, 0x0000000B, 0x00003433, 0x00005D1D, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x000061C9, 0x00003433, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062B6, 0x00003330, + 0x000061C9, 0x00050080, 0x0000000B, 0x00004DE9, 0x00003AEF, 0x000062B6, 0x00050086, 0x0000000B, + 0x000032FB, 0x00004DE9, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A25, 0x000029E0, 0x00000A25, + 0x000500C7, 0x0000000B, 0x00002266, 0x00005A25, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AF0, + 0x00001966, 0x00002266, 0x000500C2, 0x0000000B, 0x00003434, 0x00005D1D, 0x00000A25, 0x000500C7, + 0x0000000B, 0x000061CA, 0x00003434, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062B7, 0x00003330, + 0x000061CA, 0x00050080, 0x0000000B, 0x00004DEA, 0x00003AF0, 0x000062B7, 0x00050086, 0x0000000B, + 0x0000317B, 0x00004DEA, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00006202, 0x0000317B, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x000023CE, 0x000032FB, 0x00006202, 0x00050050, 0x00000011, 0x000053E9, + 0x00001D9A, 0x000023CE, 0x000200F9, 0x000042F9, 0x000200F8, 0x000042F9, 0x000700F5, 0x00000011, + 0x00005028, 0x00005D3A, 0x000029A4, 0x000053E9, 0x000038CA, 0x00050051, 0x0000000B, 0x000040EF, + 0x00003D29, 0x00000001, 0x000300F7, 0x00004B86, 0x00000000, 0x000400FA, 0x00004E84, 0x000029A5, + 0x000038CB, 0x000200F8, 0x000029A5, 0x000500C7, 0x0000000B, 0x0000450E, 0x000040EF, 0x0000003A, + 0x000500C7, 0x0000000B, 0x00005DA1, 0x000040EF, 0x0000022D, 0x000500C2, 0x0000000B, 0x00005569, + 0x00005DA1, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FDA, 0x0000450E, 0x00005569, 0x000500C4, + 0x0000000B, 0x00006036, 0x00001FDA, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059C1, 0x00001FDA, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004989, 0x00006036, 0x000059C1, 0x000500C5, 0x0000000B, + 0x00003E37, 0x00001FDA, 0x00004989, 0x000400C8, 0x0000000B, 0x00002118, 0x00003E37, 0x000500C7, + 0x0000000B, 0x0000276F, 0x000040EF, 0x00002118, 0x00050082, 0x0000000B, 0x00003FB9, 0x00000908, + 0x0000276F, 0x000500C7, 0x0000000B, 0x00004415, 0x00003FB9, 0x00002118, 0x000500C7, 0x0000000B, + 0x0000426C, 0x00004415, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000357A, 0x00003281, 0x0000426C, + 0x000500C7, 0x0000000B, 0x000055F2, 0x0000276F, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FC9, + 0x00003331, 0x000055F2, 0x00050080, 0x0000000B, 0x00004DEB, 0x0000357A, 0x00004FC9, 0x00050086, + 0x0000000B, 0x000032FC, 0x00004DEB, 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A26, 0x00004415, + 0x00000A13, 0x000500C7, 0x0000000B, 0x00002267, 0x00005A26, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003AF1, 0x00003281, 0x00002267, 0x000500C2, 0x0000000B, 0x00003435, 0x0000276F, 0x00000A13, + 0x000500C7, 0x0000000B, 0x000061CB, 0x00003435, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062B8, + 0x00003331, 0x000061CB, 0x00050080, 0x0000000B, 0x00004DEC, 0x00003AF1, 0x000062B8, 0x00050086, + 0x0000000B, 0x0000317C, 0x00004DEC, 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FFA, 0x0000317C, + 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D9B, 0x000032FC, 0x00001FFA, 0x000500C2, 0x0000000B, + 0x000055CA, 0x00004415, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044D4, 0x000055CA, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AF2, 0x00003281, 0x000044D4, 0x000500C2, 0x0000000B, 0x00003436, + 0x0000276F, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061CC, 0x00003436, 0x00000A1F, 0x00050084, + 0x0000000B, 0x000062B9, 0x00003331, 0x000061CC, 0x00050080, 0x0000000B, 0x00004DED, 0x00003AF2, + 0x000062B9, 0x00050086, 0x0000000B, 0x000032FD, 0x00004DED, 0x00000A19, 0x000500C2, 0x0000000B, + 0x00005A27, 0x00004415, 0x00000A25, 0x000500C7, 0x0000000B, 0x00002268, 0x00005A27, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AF3, 0x00003281, 0x00002268, 0x000500C2, 0x0000000B, 0x00003437, + 0x0000276F, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061CD, 0x00003437, 0x00000A1F, 0x00050084, + 0x0000000B, 0x000062BA, 0x00003331, 0x000061CD, 0x00050080, 0x0000000B, 0x00004DEE, 0x00003AF3, + 0x000062BA, 0x00050086, 0x0000000B, 0x0000317D, 0x00004DEE, 0x00000A19, 0x000500C4, 0x0000000B, + 0x00006203, 0x0000317D, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00002019, 0x000032FD, 0x00006203, + 0x00050050, 0x00000011, 0x00002793, 0x00001D9B, 0x00002019, 0x000500C7, 0x0000000B, 0x00005ED9, + 0x000040EF, 0x00003E37, 0x000500C7, 0x0000000B, 0x00004005, 0x00005ED9, 0x00000A0D, 0x000500C7, + 0x0000000B, 0x00004C74, 0x00005ED9, 0x00000A22, 0x000500C4, 0x0000000B, 0x00006112, 0x00004C74, + 0x00000A31, 0x000500C5, 0x0000000B, 0x00004662, 0x00004005, 0x00006112, 0x000500C2, 0x0000000B, + 0x00005AB7, 0x00005ED9, 0x00000A1C, 0x000500C7, 0x0000000B, 0x00006223, 0x00005AB7, 0x00000A0D, + 0x000500C7, 0x0000000B, 0x00004950, 0x00005ED9, 0x00000447, 0x000500C4, 0x0000000B, 0x000058A4, + 0x00004950, 0x00000A1F, 0x000500C5, 0x0000000B, 0x000043F4, 0x00006223, 0x000058A4, 0x00050050, + 0x00000011, 0x00004F94, 0x00004662, 0x000043F4, 0x00050084, 0x00000011, 0x00005124, 0x00004F94, + 0x00000474, 0x00050080, 0x00000011, 0x00005D3B, 0x00002793, 0x00005124, 0x000200F9, 0x00004B86, + 0x000200F8, 0x000038CB, 0x000400C8, 0x0000000B, 0x000029E1, 0x000040EF, 0x000500C7, 0x0000000B, + 0x00003C10, 0x000029E1, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000453D, 0x00003281, 0x00003C10, + 0x000500C7, 0x0000000B, 0x000055F3, 0x000040EF, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FCA, + 0x00003331, 0x000055F3, 0x00050080, 0x0000000B, 0x00004DEF, 0x0000453D, 0x00004FCA, 0x00050086, + 0x0000000B, 0x000032FE, 0x00004DEF, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A28, 0x000029E1, + 0x00000A13, 0x000500C7, 0x0000000B, 0x00002269, 0x00005A28, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003AF4, 0x00003281, 0x00002269, 0x000500C2, 0x0000000B, 0x00003438, 0x000040EF, 0x00000A13, + 0x000500C7, 0x0000000B, 0x000061CE, 0x00003438, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062BB, + 0x00003331, 0x000061CE, 0x00050080, 0x0000000B, 0x00004DF0, 0x00003AF4, 0x000062BB, 0x00050086, + 0x0000000B, 0x0000317E, 0x00004DF0, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FFB, 0x0000317E, + 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D9C, 0x000032FE, 0x00001FFB, 0x000500C2, 0x0000000B, + 0x000055CB, 0x000029E1, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044D5, 0x000055CB, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AF5, 0x00003281, 0x000044D5, 0x000500C2, 0x0000000B, 0x00003439, + 0x000040EF, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061CF, 0x00003439, 0x00000A1F, 0x00050084, + 0x0000000B, 0x000062BC, 0x00003331, 0x000061CF, 0x00050080, 0x0000000B, 0x00004DF1, 0x00003AF5, + 0x000062BC, 0x00050086, 0x0000000B, 0x000032FF, 0x00004DF1, 0x00000A1F, 0x000500C2, 0x0000000B, + 0x00005A29, 0x000029E1, 0x00000A25, 0x000500C7, 0x0000000B, 0x0000226A, 0x00005A29, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AF6, 0x00003281, 0x0000226A, 0x000500C2, 0x0000000B, 0x0000343A, + 0x000040EF, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061D0, 0x0000343A, 0x00000A1F, 0x00050084, + 0x0000000B, 0x000062BD, 0x00003331, 0x000061D0, 0x00050080, 0x0000000B, 0x00004DF2, 0x00003AF6, + 0x000062BD, 0x00050086, 0x0000000B, 0x0000317F, 0x00004DF2, 0x00000A1F, 0x000500C4, 0x0000000B, + 0x00006204, 0x0000317F, 0x00000A3A, 0x000500C5, 0x0000000B, 0x000023CF, 0x000032FF, 0x00006204, + 0x00050050, 0x00000011, 0x000053EA, 0x00001D9C, 0x000023CF, 0x000200F9, 0x00004B86, 0x000200F8, + 0x00004B86, 0x000700F5, 0x00000011, 0x0000493A, 0x00005D3B, 0x000029A5, 0x000053EA, 0x000038CB, + 0x000500C4, 0x00000011, 0x00001ED0, 0x0000493A, 0x000007B7, 0x000500C5, 0x00000011, 0x00002D4C, + 0x00005028, 0x00001ED0, 0x00050051, 0x0000000B, 0x0000355D, 0x00003D29, 0x00000002, 0x000300F7, + 0x000042FA, 0x00000000, 0x000400FA, 0x00004E85, 0x000029A6, 0x000038CC, 0x000200F8, 0x000029A6, + 0x000500C7, 0x0000000B, 0x0000450F, 0x0000355D, 0x0000003A, 0x000500C7, 0x0000000B, 0x00005DA2, + 0x0000355D, 0x0000022D, 0x000500C2, 0x0000000B, 0x0000556A, 0x00005DA2, 0x00000A0D, 0x000500C7, + 0x0000000B, 0x00001FDB, 0x0000450F, 0x0000556A, 0x000500C4, 0x0000000B, 0x00006037, 0x00001FDB, + 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059C2, 0x00001FDB, 0x00000A0D, 0x000500C5, 0x0000000B, + 0x0000498A, 0x00006037, 0x000059C2, 0x000500C5, 0x0000000B, 0x00003E38, 0x00001FDB, 0x0000498A, + 0x000400C8, 0x0000000B, 0x00002119, 0x00003E38, 0x000500C7, 0x0000000B, 0x00002770, 0x0000355D, + 0x00002119, 0x00050082, 0x0000000B, 0x00003FBA, 0x00000908, 0x00002770, 0x000500C7, 0x0000000B, + 0x00004416, 0x00003FBA, 0x00002119, 0x000500C7, 0x0000000B, 0x0000426D, 0x00004416, 0x00000A1F, + 0x00050084, 0x0000000B, 0x0000357B, 0x00003282, 0x0000426D, 0x000500C7, 0x0000000B, 0x000055F4, + 0x00002770, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FCB, 0x00003333, 0x000055F4, 0x00050080, + 0x0000000B, 0x00004DF3, 0x0000357B, 0x00004FCB, 0x00050086, 0x0000000B, 0x00003300, 0x00004DF3, + 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A2A, 0x00004416, 0x00000A13, 0x000500C7, 0x0000000B, + 0x0000226B, 0x00005A2A, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AF7, 0x00003282, 0x0000226B, + 0x000500C2, 0x0000000B, 0x0000343B, 0x00002770, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061D1, + 0x0000343B, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062BE, 0x00003333, 0x000061D1, 0x00050080, + 0x0000000B, 0x00004DF4, 0x00003AF7, 0x000062BE, 0x00050086, 0x0000000B, 0x00003180, 0x00004DF4, + 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FFC, 0x00003180, 0x00000A3A, 0x000500C5, 0x0000000B, + 0x00001D9D, 0x00003300, 0x00001FFC, 0x000500C2, 0x0000000B, 0x000055CC, 0x00004416, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x000044D6, 0x000055CC, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AF8, + 0x00003282, 0x000044D6, 0x000500C2, 0x0000000B, 0x0000343C, 0x00002770, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x000061D2, 0x0000343C, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062BF, 0x00003333, + 0x000061D2, 0x00050080, 0x0000000B, 0x00004DF5, 0x00003AF8, 0x000062BF, 0x00050086, 0x0000000B, + 0x00003301, 0x00004DF5, 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A2B, 0x00004416, 0x00000A25, + 0x000500C7, 0x0000000B, 0x0000226C, 0x00005A2B, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AF9, + 0x00003282, 0x0000226C, 0x000500C2, 0x0000000B, 0x0000343D, 0x00002770, 0x00000A25, 0x000500C7, + 0x0000000B, 0x000061D3, 0x0000343D, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062C0, 0x00003333, + 0x000061D3, 0x00050080, 0x0000000B, 0x00004DF6, 0x00003AF9, 0x000062C0, 0x00050086, 0x0000000B, + 0x00003181, 0x00004DF6, 0x00000A19, 0x000500C4, 0x0000000B, 0x00006205, 0x00003181, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x0000201A, 0x00003301, 0x00006205, 0x00050050, 0x00000011, 0x00002794, + 0x00001D9D, 0x0000201A, 0x000500C7, 0x0000000B, 0x00005EDA, 0x0000355D, 0x00003E38, 0x000500C7, + 0x0000000B, 0x00004006, 0x00005EDA, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C75, 0x00005EDA, + 0x00000A22, 0x000500C4, 0x0000000B, 0x00006113, 0x00004C75, 0x00000A31, 0x000500C5, 0x0000000B, + 0x00004663, 0x00004006, 0x00006113, 0x000500C2, 0x0000000B, 0x00005AB8, 0x00005EDA, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x00006224, 0x00005AB8, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004951, + 0x00005EDA, 0x00000447, 0x000500C4, 0x0000000B, 0x000058A5, 0x00004951, 0x00000A1F, 0x000500C5, + 0x0000000B, 0x000043F5, 0x00006224, 0x000058A5, 0x00050050, 0x00000011, 0x00004F95, 0x00004663, + 0x000043F5, 0x00050084, 0x00000011, 0x00005125, 0x00004F95, 0x00000474, 0x00050080, 0x00000011, + 0x00005D3C, 0x00002794, 0x00005125, 0x000200F9, 0x000042FA, 0x000200F8, 0x000038CC, 0x000400C8, + 0x0000000B, 0x000029E2, 0x0000355D, 0x000500C7, 0x0000000B, 0x00003C11, 0x000029E2, 0x00000A1F, + 0x00050084, 0x0000000B, 0x0000453E, 0x00003282, 0x00003C11, 0x000500C7, 0x0000000B, 0x000055F5, + 0x0000355D, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FCC, 0x00003333, 0x000055F5, 0x00050080, + 0x0000000B, 0x00004DF7, 0x0000453E, 0x00004FCC, 0x00050086, 0x0000000B, 0x00003302, 0x00004DF7, + 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A2C, 0x000029E2, 0x00000A13, 0x000500C7, 0x0000000B, + 0x0000226D, 0x00005A2C, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AFA, 0x00003282, 0x0000226D, + 0x000500C2, 0x0000000B, 0x0000343E, 0x0000355D, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061D4, + 0x0000343E, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062C1, 0x00003333, 0x000061D4, 0x00050080, + 0x0000000B, 0x00004DF8, 0x00003AFA, 0x000062C1, 0x00050086, 0x0000000B, 0x00003182, 0x00004DF8, + 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FFD, 0x00003182, 0x00000A3A, 0x000500C5, 0x0000000B, + 0x00001D9E, 0x00003302, 0x00001FFD, 0x000500C2, 0x0000000B, 0x000055CD, 0x000029E2, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x000044D7, 0x000055CD, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AFB, + 0x00003282, 0x000044D7, 0x000500C2, 0x0000000B, 0x0000343F, 0x0000355D, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x000061D5, 0x0000343F, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062C2, 0x00003333, + 0x000061D5, 0x00050080, 0x0000000B, 0x00004DF9, 0x00003AFB, 0x000062C2, 0x00050086, 0x0000000B, + 0x00003303, 0x00004DF9, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A2D, 0x000029E2, 0x00000A25, + 0x000500C7, 0x0000000B, 0x0000226E, 0x00005A2D, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AFC, + 0x00003282, 0x0000226E, 0x000500C2, 0x0000000B, 0x00003440, 0x0000355D, 0x00000A25, 0x000500C7, + 0x0000000B, 0x000061D6, 0x00003440, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062C3, 0x00003333, + 0x000061D6, 0x00050080, 0x0000000B, 0x00004DFA, 0x00003AFC, 0x000062C3, 0x00050086, 0x0000000B, + 0x00003183, 0x00004DFA, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00006206, 0x00003183, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x000023D0, 0x00003303, 0x00006206, 0x00050050, 0x00000011, 0x000053EB, + 0x00001D9E, 0x000023D0, 0x000200F9, 0x000042FA, 0x000200F8, 0x000042FA, 0x000700F5, 0x00000011, + 0x00005029, 0x00005D3C, 0x000029A6, 0x000053EB, 0x000038CC, 0x00050051, 0x0000000B, 0x000040F0, + 0x00003D29, 0x00000003, 0x000300F7, 0x00004B87, 0x00000000, 0x000400FA, 0x00004E86, 0x000029A7, + 0x000038CD, 0x000200F8, 0x000029A7, 0x000500C7, 0x0000000B, 0x00004510, 0x000040F0, 0x0000003A, + 0x000500C7, 0x0000000B, 0x00005DA3, 0x000040F0, 0x0000022D, 0x000500C2, 0x0000000B, 0x0000556B, + 0x00005DA3, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FDC, 0x00004510, 0x0000556B, 0x000500C4, + 0x0000000B, 0x00006038, 0x00001FDC, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059C3, 0x00001FDC, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000498B, 0x00006038, 0x000059C3, 0x000500C5, 0x0000000B, + 0x00003E39, 0x00001FDC, 0x0000498B, 0x000400C8, 0x0000000B, 0x0000211A, 0x00003E39, 0x000500C7, + 0x0000000B, 0x00002771, 0x000040F0, 0x0000211A, 0x00050082, 0x0000000B, 0x00003FBB, 0x00000908, + 0x00002771, 0x000500C7, 0x0000000B, 0x00004417, 0x00003FBB, 0x0000211A, 0x000500C7, 0x0000000B, + 0x0000426E, 0x00004417, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000357C, 0x00003283, 0x0000426E, + 0x000500C7, 0x0000000B, 0x000055F6, 0x00002771, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FCD, + 0x00003334, 0x000055F6, 0x00050080, 0x0000000B, 0x00004DFB, 0x0000357C, 0x00004FCD, 0x00050086, + 0x0000000B, 0x00003304, 0x00004DFB, 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A2E, 0x00004417, + 0x00000A13, 0x000500C7, 0x0000000B, 0x0000226F, 0x00005A2E, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003AFD, 0x00003283, 0x0000226F, 0x000500C2, 0x0000000B, 0x00003441, 0x00002771, 0x00000A13, + 0x000500C7, 0x0000000B, 0x000061D7, 0x00003441, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062C4, + 0x00003334, 0x000061D7, 0x00050080, 0x0000000B, 0x00004DFC, 0x00003AFD, 0x000062C4, 0x00050086, + 0x0000000B, 0x00003184, 0x00004DFC, 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FFE, 0x00003184, + 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D9F, 0x00003304, 0x00001FFE, 0x000500C2, 0x0000000B, + 0x000055CE, 0x00004417, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044D8, 0x000055CE, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AFE, 0x00003283, 0x000044D8, 0x000500C2, 0x0000000B, 0x00003442, + 0x00002771, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061D8, 0x00003442, 0x00000A1F, 0x00050084, + 0x0000000B, 0x000062C5, 0x00003334, 0x000061D8, 0x00050080, 0x0000000B, 0x00004DFD, 0x00003AFE, + 0x000062C5, 0x00050086, 0x0000000B, 0x00003305, 0x00004DFD, 0x00000A19, 0x000500C2, 0x0000000B, + 0x00005A2F, 0x00004417, 0x00000A25, 0x000500C7, 0x0000000B, 0x00002270, 0x00005A2F, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AFF, 0x00003283, 0x00002270, 0x000500C2, 0x0000000B, 0x00003443, + 0x00002771, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061D9, 0x00003443, 0x00000A1F, 0x00050084, + 0x0000000B, 0x000062C6, 0x00003334, 0x000061D9, 0x00050080, 0x0000000B, 0x00004DFE, 0x00003AFF, + 0x000062C6, 0x00050086, 0x0000000B, 0x00003185, 0x00004DFE, 0x00000A19, 0x000500C4, 0x0000000B, + 0x00006207, 0x00003185, 0x00000A3A, 0x000500C5, 0x0000000B, 0x0000201B, 0x00003305, 0x00006207, + 0x00050050, 0x00000011, 0x00002795, 0x00001D9F, 0x0000201B, 0x000500C7, 0x0000000B, 0x00005EDB, + 0x000040F0, 0x00003E39, 0x000500C7, 0x0000000B, 0x00004007, 0x00005EDB, 0x00000A0D, 0x000500C7, + 0x0000000B, 0x00004C76, 0x00005EDB, 0x00000A22, 0x000500C4, 0x0000000B, 0x00006114, 0x00004C76, + 0x00000A31, 0x000500C5, 0x0000000B, 0x00004664, 0x00004007, 0x00006114, 0x000500C2, 0x0000000B, + 0x00005AB9, 0x00005EDB, 0x00000A1C, 0x000500C7, 0x0000000B, 0x00006225, 0x00005AB9, 0x00000A0D, + 0x000500C7, 0x0000000B, 0x00004952, 0x00005EDB, 0x00000447, 0x000500C4, 0x0000000B, 0x000058A6, + 0x00004952, 0x00000A1F, 0x000500C5, 0x0000000B, 0x000043F6, 0x00006225, 0x000058A6, 0x00050050, + 0x00000011, 0x00004F96, 0x00004664, 0x000043F6, 0x00050084, 0x00000011, 0x00005126, 0x00004F96, + 0x00000474, 0x00050080, 0x00000011, 0x00005D3D, 0x00002795, 0x00005126, 0x000200F9, 0x00004B87, + 0x000200F8, 0x000038CD, 0x000400C8, 0x0000000B, 0x000029E3, 0x000040F0, 0x000500C7, 0x0000000B, + 0x00003C12, 0x000029E3, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000453F, 0x00003283, 0x00003C12, + 0x000500C7, 0x0000000B, 0x000055F7, 0x000040F0, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FCE, + 0x00003334, 0x000055F7, 0x00050080, 0x0000000B, 0x00004DFF, 0x0000453F, 0x00004FCE, 0x00050086, + 0x0000000B, 0x00003306, 0x00004DFF, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A30, 0x000029E3, + 0x00000A13, 0x000500C7, 0x0000000B, 0x00002271, 0x00005A30, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003B00, 0x00003283, 0x00002271, 0x000500C2, 0x0000000B, 0x00003444, 0x000040F0, 0x00000A13, + 0x000500C7, 0x0000000B, 0x000061DA, 0x00003444, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062C7, + 0x00003334, 0x000061DA, 0x00050080, 0x0000000B, 0x00004E00, 0x00003B00, 0x000062C7, 0x00050086, + 0x0000000B, 0x00003186, 0x00004E00, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FFF, 0x00003186, + 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001DA0, 0x00003306, 0x00001FFF, 0x000500C2, 0x0000000B, + 0x000055CF, 0x000029E3, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044D9, 0x000055CF, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003B01, 0x00003283, 0x000044D9, 0x000500C2, 0x0000000B, 0x00003445, + 0x000040F0, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061DB, 0x00003445, 0x00000A1F, 0x00050084, + 0x0000000B, 0x000062C8, 0x00003334, 0x000061DB, 0x00050080, 0x0000000B, 0x00004E01, 0x00003B01, + 0x000062C8, 0x00050086, 0x0000000B, 0x00003307, 0x00004E01, 0x00000A1F, 0x000500C2, 0x0000000B, + 0x00005A31, 0x000029E3, 0x00000A25, 0x000500C7, 0x0000000B, 0x00002272, 0x00005A31, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003B02, 0x00003283, 0x00002272, 0x000500C2, 0x0000000B, 0x00003446, + 0x000040F0, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061DC, 0x00003446, 0x00000A1F, 0x00050084, + 0x0000000B, 0x000062C9, 0x00003334, 0x000061DC, 0x00050080, 0x0000000B, 0x00004E02, 0x00003B02, + 0x000062C9, 0x00050086, 0x0000000B, 0x00003187, 0x00004E02, 0x00000A1F, 0x000500C4, 0x0000000B, + 0x00006208, 0x00003187, 0x00000A3A, 0x000500C5, 0x0000000B, 0x000023D1, 0x00003307, 0x00006208, + 0x00050050, 0x00000011, 0x000053EC, 0x00001DA0, 0x000023D1, 0x000200F9, 0x00004B87, 0x000200F8, + 0x00004B87, 0x000700F5, 0x00000011, 0x0000493B, 0x00005D3D, 0x000029A7, 0x000053EC, 0x000038CD, + 0x000500C4, 0x00000011, 0x00001ED1, 0x0000493B, 0x000007B7, 0x000500C5, 0x00000011, 0x000020FC, + 0x00005029, 0x00001ED1, 0x00050051, 0x0000000B, 0x00004E88, 0x00002D4C, 0x00000000, 0x00050051, + 0x0000000B, 0x00005CB5, 0x00002D4C, 0x00000001, 0x00050051, 0x0000000B, 0x00001DDE, 0x000020FC, + 0x00000000, 0x00050051, 0x0000000B, 0x00001D6C, 0x000020FC, 0x00000001, 0x00070050, 0x00000017, + 0x00004757, 0x00004E88, 0x00005CB5, 0x00001DDE, 0x00001D6C, 0x00060041, 0x00000294, 0x00002ECB, + 0x0000140E, 0x00000A0B, 0x0000342E, 0x0003003E, 0x00002ECB, 0x00004757, 0x000200F9, 0x00004665, + 0x000200F8, 0x00004665, 0x000200F9, 0x00001C25, 0x000200F8, 0x00001C25, 0x000200F9, 0x00001C26, + 0x000200F8, 0x00001C26, 0x000200F9, 0x00003A37, 0x000200F8, 0x00003A37, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_dxt1_rgba8_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_dxt1_rgba8_cs.h new file mode 100644 index 0000000..2294217 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_dxt1_rgba8_cs.h @@ -0,0 +1,1279 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25215 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %v2uint = OpTypeVector %uint 2 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_3 = OpConstant %uint 3 + %uint_13 = OpConstant %uint 13 + %uint_248 = OpConstant %uint 248 + %uint_7 = OpConstant %uint 7 + %uint_9 = OpConstant %uint 9 +%uint_258048 = OpConstant %uint 258048 + %uint_12 = OpConstant %uint 12 + %uint_4 = OpConstant %uint 4 +%uint_260046848 = OpConstant %uint 260046848 + %uint_5 = OpConstant %uint 5 +%uint_7340039 = OpConstant %uint 7340039 + %uint_6 = OpConstant %uint 6 + %uint_3072 = OpConstant %uint 3072 +%uint_1431655765 = OpConstant %uint 1431655765 + %uint_1 = OpConstant %uint 1 +%uint_2863311530 = OpConstant %uint 2863311530 + %uint_0 = OpConstant %uint 0 + %uint_2 = OpConstant %uint 2 + %77 = OpConstantComposite %v4uint %uint_0 %uint_2 %uint_4 %uint_6 + %uint_1023 = OpConstant %uint 1023 + %uint_16 = OpConstant %uint 16 + %uint_10 = OpConstant %uint 10 + %uint_8 = OpConstant %uint 8 + %uint_20 = OpConstant %uint 20 + %131 = OpConstantComposite %v4uint %uint_1 %uint_3 %uint_5 %uint_7 +%uint_4278190080 = OpConstant %uint 4278190080 +%uint_16711935 = OpConstant %uint 16711935 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2596 = OpConstantComposite %v3uint %uint_2 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 + %2620 = OpConstantComposite %v3uint %uint_2 %uint_2 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint + %v4bool = OpTypeVector %bool 4 +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform + %uint_32 = OpConstant %uint 32 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %993 = OpConstantComposite %v2uint %uint_248 %uint_248 + %1015 = OpConstantComposite %v2uint %uint_258048 %uint_258048 + %2547 = OpConstantComposite %v2uint %uint_260046848 %uint_260046848 + %1912 = OpConstantComposite %v2uint %uint_5 %uint_5 + %503 = OpConstantComposite %v2uint %uint_7340039 %uint_7340039 + %1933 = OpConstantComposite %v2uint %uint_6 %uint_6 + %78 = OpConstantComposite %v2uint %uint_3072 %uint_3072 + %2878 = OpConstantComposite %v4uint %uint_1431655765 %uint_1431655765 %uint_1431655765 %uint_1431655765 + %2950 = OpConstantComposite %v4uint %uint_1 %uint_1 %uint_1 %uint_1 + %2860 = OpConstantComposite %v4uint %uint_2863311530 %uint_2863311530 %uint_2863311530 %uint_2863311530 + %929 = OpConstantComposite %v4uint %uint_1023 %uint_1023 %uint_1023 %uint_1023 + %425 = OpConstantComposite %v4uint %uint_10 %uint_10 %uint_10 %uint_10 + %965 = OpConstantComposite %v4uint %uint_20 %uint_20 %uint_20 %uint_20 + %2599 = OpConstantComposite %v4uint %uint_4278190080 %uint_4278190080 %uint_4278190080 %uint_4278190080 + %47 = OpConstantComposite %v4uint %uint_3 %uint_3 %uint_3 %uint_3 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %14903 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20158 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %22412 = OpLoad %uint %20158 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_7 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2596 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %14018 DontFlatten + OpBranchConditional %24679 %21992 %14018 + %21992 = OpLabel + OpBranch %14903 + %14018 = OpLabel + %17344 = OpShiftLeftLogical %v3uint %21387 %2620 + %15489 = OpBitcast %v3int %17344 + %18336 = OpCompositeExtract %int %15489 0 + %9362 = OpIMul %int %18336 %int_4 + %6362 = OpCompositeExtract %int %15489 2 + %14505 = OpBitcast %int %6594 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %15489 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %22412 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %9362 %24535 + %10898 = OpBitcast %uint %8258 + %9077 = OpIAdd %uint %10898 %22411 + %11726 = OpShiftRightLogical %uint %9077 %uint_4 + %6977 = OpShiftRightLogical %uint %22412 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20009 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %21373 %6361 + %21373 = OpLabel + %10608 = OpBitcast %v3int %21387 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_9 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_9 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_9 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17091 = OpCompositeExtract %int %6573 0 + %9470 = OpShiftRightArithmetic %int %17091 %int_5 + %10056 = OpCompositeExtract %int %6573 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_10 + %10934 = OpBitwiseAnd %int %17091 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_3 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17091 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %21373 %12098 %6361 + OpBranch %24387 + %20009 = OpLabel + %24447 = OpBitcast %v3int %21387 + %8918 = OpCompositeExtract %int %24447 0 + %9363 = OpIMul %int %8918 %int_8 + %6363 = OpCompositeExtract %int %24447 2 + %14506 = OpBitcast %int %22409 + %11280 = OpIMul %int %6363 %14506 + %17599 = OpCompositeExtract %int %24447 1 + %22229 = OpIAdd %int %11280 %17599 + %22406 = OpBitcast %int %22408 + %7839 = OpIMul %int %22229 %22406 + %7984 = OpIAdd %int %9363 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20009 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %13392 None + OpBranchConditional %15139 %11064 %13392 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %13392 + %13392 = OpLabel + %22100 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %11876 = OpSelect %uint %17270 %uint_2 %uint_1 + %11339 = OpIAdd %uint %22117 %11876 + %18278 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %11339 + %6578 = OpLoad %v4uint %18278 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %13392 %16377 %10584 + OpSelectionMerge %11720 None + OpBranchConditional %15139 %11065 %11720 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11720 + %11720 = OpLabel + %19545 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %24377 = OpCompositeExtract %uint %22100 0 + %15487 = OpShiftLeftLogical %uint %24377 %uint_3 + %6481 = OpShiftRightLogical %uint %24377 %uint_13 + %17264 = OpCompositeConstruct %v2uint %15487 %6481 + %6430 = OpBitwiseAnd %v2uint %17264 %993 + %20543 = OpShiftLeftLogical %uint %24377 %uint_7 + %24164 = OpShiftRightLogical %uint %24377 %uint_9 + %17283 = OpCompositeConstruct %v2uint %20543 %24164 + %6295 = OpBitwiseAnd %v2uint %17283 %1015 + %14170 = OpBitwiseOr %v2uint %6430 %6295 + %23688 = OpShiftLeftLogical %uint %24377 %uint_12 + %22551 = OpShiftRightLogical %uint %24377 %uint_4 + %17285 = OpCompositeConstruct %v2uint %23688 %22551 + %6257 = OpBitwiseAnd %v2uint %17285 %2547 + %14611 = OpBitwiseOr %v2uint %14170 %6257 + %22361 = OpShiftRightLogical %v2uint %14611 %1912 + %6347 = OpBitwiseAnd %v2uint %22361 %503 + %16454 = OpBitwiseOr %v2uint %14611 %6347 + %22362 = OpShiftRightLogical %v2uint %16454 %1933 + %23271 = OpBitwiseAnd %v2uint %22362 %78 + %16875 = OpBitwiseOr %v2uint %16454 %23271 + %20610 = OpCompositeExtract %uint %22100 2 + %9060 = OpShiftLeftLogical %uint %20610 %uint_3 + %6482 = OpShiftRightLogical %uint %20610 %uint_13 + %17265 = OpCompositeConstruct %v2uint %9060 %6482 + %6431 = OpBitwiseAnd %v2uint %17265 %993 + %20544 = OpShiftLeftLogical %uint %20610 %uint_7 + %24165 = OpShiftRightLogical %uint %20610 %uint_9 + %17286 = OpCompositeConstruct %v2uint %20544 %24165 + %6296 = OpBitwiseAnd %v2uint %17286 %1015 + %14171 = OpBitwiseOr %v2uint %6431 %6296 + %23689 = OpShiftLeftLogical %uint %20610 %uint_12 + %22552 = OpShiftRightLogical %uint %20610 %uint_4 + %17287 = OpCompositeConstruct %v2uint %23689 %22552 + %6258 = OpBitwiseAnd %v2uint %17287 %2547 + %14612 = OpBitwiseOr %v2uint %14171 %6258 + %22363 = OpShiftRightLogical %v2uint %14612 %1912 + %6348 = OpBitwiseAnd %v2uint %22363 %503 + %16455 = OpBitwiseOr %v2uint %14612 %6348 + %22364 = OpShiftRightLogical %v2uint %16455 %1933 + %23272 = OpBitwiseAnd %v2uint %22364 %78 + %14690 = OpBitwiseOr %v2uint %16455 %23272 + %19287 = OpCompositeExtract %uint %16875 0 + %23730 = OpCompositeExtract %uint %16875 1 + %7660 = OpCompositeExtract %uint %14690 0 + %9845 = OpCompositeExtract %uint %14690 1 + %8983 = OpCompositeExtract %uint %19545 0 + %12061 = OpShiftLeftLogical %uint %8983 %uint_3 + %6483 = OpShiftRightLogical %uint %8983 %uint_13 + %17266 = OpCompositeConstruct %v2uint %12061 %6483 + %6432 = OpBitwiseAnd %v2uint %17266 %993 + %20545 = OpShiftLeftLogical %uint %8983 %uint_7 + %24166 = OpShiftRightLogical %uint %8983 %uint_9 + %17288 = OpCompositeConstruct %v2uint %20545 %24166 + %6297 = OpBitwiseAnd %v2uint %17288 %1015 + %14172 = OpBitwiseOr %v2uint %6432 %6297 + %23690 = OpShiftLeftLogical %uint %8983 %uint_12 + %22553 = OpShiftRightLogical %uint %8983 %uint_4 + %17289 = OpCompositeConstruct %v2uint %23690 %22553 + %6259 = OpBitwiseAnd %v2uint %17289 %2547 + %14613 = OpBitwiseOr %v2uint %14172 %6259 + %22365 = OpShiftRightLogical %v2uint %14613 %1912 + %6349 = OpBitwiseAnd %v2uint %22365 %503 + %16456 = OpBitwiseOr %v2uint %14613 %6349 + %22366 = OpShiftRightLogical %v2uint %16456 %1933 + %23273 = OpBitwiseAnd %v2uint %22366 %78 + %16876 = OpBitwiseOr %v2uint %16456 %23273 + %20612 = OpCompositeExtract %uint %19545 2 + %9061 = OpShiftLeftLogical %uint %20612 %uint_3 + %6484 = OpShiftRightLogical %uint %20612 %uint_13 + %17267 = OpCompositeConstruct %v2uint %9061 %6484 + %6433 = OpBitwiseAnd %v2uint %17267 %993 + %20546 = OpShiftLeftLogical %uint %20612 %uint_7 + %24167 = OpShiftRightLogical %uint %20612 %uint_9 + %17290 = OpCompositeConstruct %v2uint %20546 %24167 + %6298 = OpBitwiseAnd %v2uint %17290 %1015 + %14173 = OpBitwiseOr %v2uint %6433 %6298 + %23691 = OpShiftLeftLogical %uint %20612 %uint_12 + %22554 = OpShiftRightLogical %uint %20612 %uint_4 + %17291 = OpCompositeConstruct %v2uint %23691 %22554 + %6260 = OpBitwiseAnd %v2uint %17291 %2547 + %14614 = OpBitwiseOr %v2uint %14173 %6260 + %22367 = OpShiftRightLogical %v2uint %14614 %1912 + %6350 = OpBitwiseAnd %v2uint %22367 %503 + %16457 = OpBitwiseOr %v2uint %14614 %6350 + %22368 = OpShiftRightLogical %v2uint %16457 %1933 + %23275 = OpBitwiseAnd %v2uint %22368 %78 + %14691 = OpBitwiseOr %v2uint %16457 %23275 + %19288 = OpCompositeExtract %uint %16876 0 + %23731 = OpCompositeExtract %uint %16876 1 + %7641 = OpCompositeExtract %uint %14691 0 + %7814 = OpCompositeExtract %uint %14691 1 + %17869 = OpCompositeConstruct %v4uint %19287 %7660 %19288 %7641 + %18392 = OpCompositeConstruct %v4uint %23730 %9845 %23731 %7814 + %10135 = OpULessThanEqual %v4bool %17869 %18392 + %15514 = OpCompositeExtract %uint %22100 1 + %18092 = OpCompositeExtract %uint %22100 3 + %7642 = OpCompositeExtract %uint %19545 1 + %10075 = OpCompositeExtract %uint %19545 3 + %16695 = OpCompositeConstruct %v4uint %15514 %18092 %7642 %10075 + %8717 = OpBitwiseAnd %v4uint %16695 %2878 + %21844 = OpShiftLeftLogical %v4uint %8717 %2950 + %20654 = OpBitwiseAnd %v4uint %16695 %2860 + %16599 = OpShiftRightLogical %v4uint %20654 %2950 + %24000 = OpBitwiseOr %v4uint %21844 %16599 + %19618 = OpBitwiseAnd %v4uint %24000 %2860 + %20480 = OpShiftRightLogical %v4uint %19618 %2950 + %15729 = OpBitwiseXor %v4uint %24000 %20480 + %10273 = OpNot %v4uint %16695 + %15294 = OpBitwiseAnd %v4uint %10273 %2878 + %21767 = OpShiftLeftLogical %v4uint %15294 %2950 + %15087 = OpBitwiseXor %v4uint %10273 %21767 + %10284 = OpSelect %v4uint %10135 %15087 %15729 + OpBranch %11625 + %11625 = OpLabel + %11175 = OpPhi %v4uint %10284 %11720 %8059 %19902 + %13033 = OpPhi %uint %11726 %11720 %11069 %19902 + %8038 = OpPhi %uint %uint_0 %11720 %22028 %19902 + %14719 = OpULessThan %bool %8038 %uint_4 + OpLoopMerge %6980 %19902 Unroll + OpBranchConditional %14719 %18818 %6980 + %18818 = OpLabel + %10969 = OpINotEqual %bool %8038 %uint_0 + OpSelectionMerge %15645 None + OpBranchConditional %10969 %10634 %15645 + %10634 = OpLabel + %11099 = OpCompositeExtract %uint %17344 1 + %12762 = OpIAdd %uint %11099 %8038 + %14740 = OpUGreaterThanEqual %bool %12762 %6594 + OpSelectionMerge %8041 None + OpBranchConditional %14740 %21993 %8041 + %21993 = OpLabel + OpBranch %6980 + %8041 = OpLabel + %12491 = OpIAdd %uint %13033 %6977 + %24752 = OpShiftRightLogical %v4uint %11175 %317 + OpBranch %15645 + %15645 = OpLabel + %8059 = OpPhi %v4uint %11175 %18818 %24752 %8041 + %11069 = OpPhi %uint %13033 %18818 %12491 %8041 + %17427 = OpCompositeExtract %bool %10135 0 + OpSelectionMerge %11416 None + OpBranchConditional %17427 %9722 %16061 + %9722 = OpLabel + %19783 = OpCompositeExtract %uint %8059 0 + %20234 = OpCompositeConstruct %v4uint %19783 %19783 %19783 %19783 + %8760 = OpShiftRightLogical %v4uint %20234 %77 + %24376 = OpBitwiseAnd %v4uint %8760 %2950 + %19502 = OpCompositeConstruct %v4uint %19287 %19287 %19287 %19287 + %22618 = OpIMul %v4uint %24376 %19502 + %16106 = OpShiftRightLogical %v4uint %20234 %131 + %14958 = OpBitwiseAnd %v4uint %16106 %2950 + %18248 = OpCompositeConstruct %v4uint %23730 %23730 %23730 %23730 + %14965 = OpIMul %v4uint %14958 %18248 + %12407 = OpIAdd %v4uint %22618 %14965 + %14443 = OpBitwiseAnd %uint %19783 %uint_2863311530 + %23420 = OpShiftRightLogical %uint %14443 %uint_1 + %9130 = OpBitwiseAnd %uint %19783 %23420 + %8871 = OpCompositeConstruct %v4uint %9130 %9130 %9130 %9130 + %9633 = OpShiftRightLogical %v4uint %8871 %77 + %24095 = OpBitwiseAnd %v4uint %9633 %2950 + %18620 = OpBitwiseAnd %uint %19783 %uint_1431655765 + %16298 = OpBitwiseOr %uint %18620 %23420 + %20384 = OpBitwiseAnd %v4uint %12407 %929 + %20712 = OpShiftRightLogical %v4uint %20384 %24095 + %14082 = OpShiftLeftLogical %v4uint %20712 %749 + %21749 = OpShiftRightLogical %v4uint %12407 %425 + %21940 = OpBitwiseAnd %v4uint %21749 %929 + %20267 = OpShiftRightLogical %v4uint %21940 %24095 + %6334 = OpShiftLeftLogical %v4uint %20267 %317 + %16750 = OpIAdd %v4uint %14082 %6334 + %22334 = OpShiftRightLogical %v4uint %12407 %965 + %11721 = OpShiftRightLogical %v4uint %22334 %24095 + %17899 = OpIAdd %v4uint %16750 %11721 + %8979 = OpCompositeConstruct %v4uint %16298 %16298 %16298 %16298 + %18597 = OpShiftRightLogical %v4uint %8979 %77 + %15304 = OpBitwiseAnd %v4uint %18597 %2950 + %8308 = OpIMul %v4uint %15304 %2599 + %20044 = OpIAdd %v4uint %17899 %8308 + OpBranch %11416 + %16061 = OpLabel + %18350 = OpCompositeExtract %uint %8059 0 + %22865 = OpNot %uint %18350 + %10815 = OpCompositeConstruct %v4uint %22865 %22865 %22865 %22865 + %24021 = OpShiftRightLogical %v4uint %10815 %77 + %24378 = OpBitwiseAnd %v4uint %24021 %47 + %17336 = OpCompositeConstruct %v4uint %19287 %19287 %19287 %19287 + %23174 = OpIMul %v4uint %24378 %17336 + %25211 = OpCompositeConstruct %v4uint %18350 %18350 %18350 %18350 + %14378 = OpShiftRightLogical %v4uint %25211 %77 + %24379 = OpBitwiseAnd %v4uint %14378 %47 + %18249 = OpCompositeConstruct %v4uint %23730 %23730 %23730 %23730 + %14966 = OpIMul %v4uint %24379 %18249 + %11267 = OpIAdd %v4uint %23174 %14966 + %24766 = OpBitwiseAnd %v4uint %11267 %929 + %9225 = OpUDiv %v4uint %24766 %47 + %17608 = OpShiftLeftLogical %v4uint %9225 %749 + %10961 = OpShiftRightLogical %v4uint %11267 %425 + %13249 = OpBitwiseAnd %v4uint %10961 %929 + %17312 = OpUDiv %v4uint %13249 %47 + %16994 = OpShiftLeftLogical %v4uint %17312 %317 + %6318 = OpBitwiseOr %v4uint %17608 %16994 + %15344 = OpShiftRightLogical %v4uint %11267 %965 + %24032 = OpUDiv %v4uint %15344 %47 + %9042 = OpBitwiseOr %v4uint %6318 %24032 + %17791 = OpBitwiseOr %v4uint %9042 %2599 + OpBranch %11416 + %11416 = OpLabel + %19767 = OpPhi %v4uint %20044 %9722 %17791 %16061 + %24825 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11069 + OpStore %24825 %19767 + %12204 = OpIAdd %uint %11069 %uint_1 + %14668 = OpCompositeExtract %bool %10135 1 + OpSelectionMerge %11417 None + OpBranchConditional %14668 %9723 %16062 + %9723 = OpLabel + %19784 = OpCompositeExtract %uint %8059 1 + %20235 = OpCompositeConstruct %v4uint %19784 %19784 %19784 %19784 + %8761 = OpShiftRightLogical %v4uint %20235 %77 + %24380 = OpBitwiseAnd %v4uint %8761 %2950 + %19503 = OpCompositeConstruct %v4uint %7660 %7660 %7660 %7660 + %22619 = OpIMul %v4uint %24380 %19503 + %16107 = OpShiftRightLogical %v4uint %20235 %131 + %14959 = OpBitwiseAnd %v4uint %16107 %2950 + %18250 = OpCompositeConstruct %v4uint %9845 %9845 %9845 %9845 + %14967 = OpIMul %v4uint %14959 %18250 + %12408 = OpIAdd %v4uint %22619 %14967 + %14444 = OpBitwiseAnd %uint %19784 %uint_2863311530 + %23421 = OpShiftRightLogical %uint %14444 %uint_1 + %9131 = OpBitwiseAnd %uint %19784 %23421 + %8872 = OpCompositeConstruct %v4uint %9131 %9131 %9131 %9131 + %9634 = OpShiftRightLogical %v4uint %8872 %77 + %24096 = OpBitwiseAnd %v4uint %9634 %2950 + %18621 = OpBitwiseAnd %uint %19784 %uint_1431655765 + %16299 = OpBitwiseOr %uint %18621 %23421 + %20385 = OpBitwiseAnd %v4uint %12408 %929 + %20713 = OpShiftRightLogical %v4uint %20385 %24096 + %14083 = OpShiftLeftLogical %v4uint %20713 %749 + %21750 = OpShiftRightLogical %v4uint %12408 %425 + %21941 = OpBitwiseAnd %v4uint %21750 %929 + %20268 = OpShiftRightLogical %v4uint %21941 %24096 + %6335 = OpShiftLeftLogical %v4uint %20268 %317 + %16751 = OpIAdd %v4uint %14083 %6335 + %22335 = OpShiftRightLogical %v4uint %12408 %965 + %11722 = OpShiftRightLogical %v4uint %22335 %24096 + %17900 = OpIAdd %v4uint %16751 %11722 + %8980 = OpCompositeConstruct %v4uint %16299 %16299 %16299 %16299 + %18598 = OpShiftRightLogical %v4uint %8980 %77 + %15305 = OpBitwiseAnd %v4uint %18598 %2950 + %8309 = OpIMul %v4uint %15305 %2599 + %20045 = OpIAdd %v4uint %17900 %8309 + OpBranch %11417 + %16062 = OpLabel + %18351 = OpCompositeExtract %uint %8059 1 + %22866 = OpNot %uint %18351 + %10816 = OpCompositeConstruct %v4uint %22866 %22866 %22866 %22866 + %24022 = OpShiftRightLogical %v4uint %10816 %77 + %24381 = OpBitwiseAnd %v4uint %24022 %47 + %17337 = OpCompositeConstruct %v4uint %7660 %7660 %7660 %7660 + %23175 = OpIMul %v4uint %24381 %17337 + %25212 = OpCompositeConstruct %v4uint %18351 %18351 %18351 %18351 + %14379 = OpShiftRightLogical %v4uint %25212 %77 + %24382 = OpBitwiseAnd %v4uint %14379 %47 + %18251 = OpCompositeConstruct %v4uint %9845 %9845 %9845 %9845 + %14968 = OpIMul %v4uint %24382 %18251 + %11268 = OpIAdd %v4uint %23175 %14968 + %24767 = OpBitwiseAnd %v4uint %11268 %929 + %9226 = OpUDiv %v4uint %24767 %47 + %17609 = OpShiftLeftLogical %v4uint %9226 %749 + %10962 = OpShiftRightLogical %v4uint %11268 %425 + %13250 = OpBitwiseAnd %v4uint %10962 %929 + %17313 = OpUDiv %v4uint %13250 %47 + %16995 = OpShiftLeftLogical %v4uint %17313 %317 + %6319 = OpBitwiseOr %v4uint %17609 %16995 + %15345 = OpShiftRightLogical %v4uint %11268 %965 + %24033 = OpUDiv %v4uint %15345 %47 + %9043 = OpBitwiseOr %v4uint %6319 %24033 + %17792 = OpBitwiseOr %v4uint %9043 %2599 + OpBranch %11417 + %11417 = OpLabel + %19769 = OpPhi %v4uint %20045 %9723 %17792 %16062 + %24826 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %12204 + OpStore %24826 %19769 + %12205 = OpIAdd %uint %11069 %uint_2 + %14669 = OpCompositeExtract %bool %10135 2 + OpSelectionMerge %11418 None + OpBranchConditional %14669 %9724 %16063 + %9724 = OpLabel + %19785 = OpCompositeExtract %uint %8059 2 + %20236 = OpCompositeConstruct %v4uint %19785 %19785 %19785 %19785 + %8762 = OpShiftRightLogical %v4uint %20236 %77 + %24383 = OpBitwiseAnd %v4uint %8762 %2950 + %19504 = OpCompositeConstruct %v4uint %19288 %19288 %19288 %19288 + %22620 = OpIMul %v4uint %24383 %19504 + %16108 = OpShiftRightLogical %v4uint %20236 %131 + %14960 = OpBitwiseAnd %v4uint %16108 %2950 + %18252 = OpCompositeConstruct %v4uint %23731 %23731 %23731 %23731 + %14969 = OpIMul %v4uint %14960 %18252 + %12409 = OpIAdd %v4uint %22620 %14969 + %14445 = OpBitwiseAnd %uint %19785 %uint_2863311530 + %23422 = OpShiftRightLogical %uint %14445 %uint_1 + %9132 = OpBitwiseAnd %uint %19785 %23422 + %8873 = OpCompositeConstruct %v4uint %9132 %9132 %9132 %9132 + %9635 = OpShiftRightLogical %v4uint %8873 %77 + %24097 = OpBitwiseAnd %v4uint %9635 %2950 + %18622 = OpBitwiseAnd %uint %19785 %uint_1431655765 + %16300 = OpBitwiseOr %uint %18622 %23422 + %20386 = OpBitwiseAnd %v4uint %12409 %929 + %20714 = OpShiftRightLogical %v4uint %20386 %24097 + %14084 = OpShiftLeftLogical %v4uint %20714 %749 + %21751 = OpShiftRightLogical %v4uint %12409 %425 + %21942 = OpBitwiseAnd %v4uint %21751 %929 + %20269 = OpShiftRightLogical %v4uint %21942 %24097 + %6336 = OpShiftLeftLogical %v4uint %20269 %317 + %16752 = OpIAdd %v4uint %14084 %6336 + %22336 = OpShiftRightLogical %v4uint %12409 %965 + %11723 = OpShiftRightLogical %v4uint %22336 %24097 + %17901 = OpIAdd %v4uint %16752 %11723 + %8981 = OpCompositeConstruct %v4uint %16300 %16300 %16300 %16300 + %18599 = OpShiftRightLogical %v4uint %8981 %77 + %15306 = OpBitwiseAnd %v4uint %18599 %2950 + %8310 = OpIMul %v4uint %15306 %2599 + %20046 = OpIAdd %v4uint %17901 %8310 + OpBranch %11418 + %16063 = OpLabel + %18352 = OpCompositeExtract %uint %8059 2 + %22867 = OpNot %uint %18352 + %10817 = OpCompositeConstruct %v4uint %22867 %22867 %22867 %22867 + %24023 = OpShiftRightLogical %v4uint %10817 %77 + %24384 = OpBitwiseAnd %v4uint %24023 %47 + %17338 = OpCompositeConstruct %v4uint %19288 %19288 %19288 %19288 + %23176 = OpIMul %v4uint %24384 %17338 + %25213 = OpCompositeConstruct %v4uint %18352 %18352 %18352 %18352 + %14380 = OpShiftRightLogical %v4uint %25213 %77 + %24385 = OpBitwiseAnd %v4uint %14380 %47 + %18253 = OpCompositeConstruct %v4uint %23731 %23731 %23731 %23731 + %14970 = OpIMul %v4uint %24385 %18253 + %11269 = OpIAdd %v4uint %23176 %14970 + %24768 = OpBitwiseAnd %v4uint %11269 %929 + %9227 = OpUDiv %v4uint %24768 %47 + %17610 = OpShiftLeftLogical %v4uint %9227 %749 + %10963 = OpShiftRightLogical %v4uint %11269 %425 + %13251 = OpBitwiseAnd %v4uint %10963 %929 + %17314 = OpUDiv %v4uint %13251 %47 + %16996 = OpShiftLeftLogical %v4uint %17314 %317 + %6320 = OpBitwiseOr %v4uint %17610 %16996 + %15346 = OpShiftRightLogical %v4uint %11269 %965 + %24034 = OpUDiv %v4uint %15346 %47 + %9044 = OpBitwiseOr %v4uint %6320 %24034 + %17793 = OpBitwiseOr %v4uint %9044 %2599 + OpBranch %11418 + %11418 = OpLabel + %19770 = OpPhi %v4uint %20046 %9724 %17793 %16063 + %24827 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %12205 + OpStore %24827 %19770 + %12206 = OpIAdd %uint %11069 %uint_3 + %14670 = OpCompositeExtract %bool %10135 3 + OpSelectionMerge %11419 None + OpBranchConditional %14670 %9725 %16064 + %9725 = OpLabel + %19786 = OpCompositeExtract %uint %8059 3 + %20237 = OpCompositeConstruct %v4uint %19786 %19786 %19786 %19786 + %8763 = OpShiftRightLogical %v4uint %20237 %77 + %24386 = OpBitwiseAnd %v4uint %8763 %2950 + %19505 = OpCompositeConstruct %v4uint %7641 %7641 %7641 %7641 + %22621 = OpIMul %v4uint %24386 %19505 + %16109 = OpShiftRightLogical %v4uint %20237 %131 + %14961 = OpBitwiseAnd %v4uint %16109 %2950 + %18254 = OpCompositeConstruct %v4uint %7814 %7814 %7814 %7814 + %14971 = OpIMul %v4uint %14961 %18254 + %12410 = OpIAdd %v4uint %22621 %14971 + %14446 = OpBitwiseAnd %uint %19786 %uint_2863311530 + %23423 = OpShiftRightLogical %uint %14446 %uint_1 + %9133 = OpBitwiseAnd %uint %19786 %23423 + %8874 = OpCompositeConstruct %v4uint %9133 %9133 %9133 %9133 + %9636 = OpShiftRightLogical %v4uint %8874 %77 + %24098 = OpBitwiseAnd %v4uint %9636 %2950 + %18623 = OpBitwiseAnd %uint %19786 %uint_1431655765 + %16301 = OpBitwiseOr %uint %18623 %23423 + %20387 = OpBitwiseAnd %v4uint %12410 %929 + %20715 = OpShiftRightLogical %v4uint %20387 %24098 + %14085 = OpShiftLeftLogical %v4uint %20715 %749 + %21752 = OpShiftRightLogical %v4uint %12410 %425 + %21943 = OpBitwiseAnd %v4uint %21752 %929 + %20270 = OpShiftRightLogical %v4uint %21943 %24098 + %6337 = OpShiftLeftLogical %v4uint %20270 %317 + %16753 = OpIAdd %v4uint %14085 %6337 + %22337 = OpShiftRightLogical %v4uint %12410 %965 + %11724 = OpShiftRightLogical %v4uint %22337 %24098 + %17902 = OpIAdd %v4uint %16753 %11724 + %8982 = OpCompositeConstruct %v4uint %16301 %16301 %16301 %16301 + %18600 = OpShiftRightLogical %v4uint %8982 %77 + %15307 = OpBitwiseAnd %v4uint %18600 %2950 + %8311 = OpIMul %v4uint %15307 %2599 + %20047 = OpIAdd %v4uint %17902 %8311 + OpBranch %11419 + %16064 = OpLabel + %18353 = OpCompositeExtract %uint %8059 3 + %22868 = OpNot %uint %18353 + %10818 = OpCompositeConstruct %v4uint %22868 %22868 %22868 %22868 + %24024 = OpShiftRightLogical %v4uint %10818 %77 + %24388 = OpBitwiseAnd %v4uint %24024 %47 + %17339 = OpCompositeConstruct %v4uint %7641 %7641 %7641 %7641 + %23177 = OpIMul %v4uint %24388 %17339 + %25214 = OpCompositeConstruct %v4uint %18353 %18353 %18353 %18353 + %14381 = OpShiftRightLogical %v4uint %25214 %77 + %24389 = OpBitwiseAnd %v4uint %14381 %47 + %18255 = OpCompositeConstruct %v4uint %7814 %7814 %7814 %7814 + %14972 = OpIMul %v4uint %24389 %18255 + %11270 = OpIAdd %v4uint %23177 %14972 + %24769 = OpBitwiseAnd %v4uint %11270 %929 + %9228 = OpUDiv %v4uint %24769 %47 + %17611 = OpShiftLeftLogical %v4uint %9228 %749 + %10964 = OpShiftRightLogical %v4uint %11270 %425 + %13252 = OpBitwiseAnd %v4uint %10964 %929 + %17315 = OpUDiv %v4uint %13252 %47 + %16997 = OpShiftLeftLogical %v4uint %17315 %317 + %6321 = OpBitwiseOr %v4uint %17611 %16997 + %15347 = OpShiftRightLogical %v4uint %11270 %965 + %24036 = OpUDiv %v4uint %15347 %47 + %9045 = OpBitwiseOr %v4uint %6321 %24036 + %17794 = OpBitwiseOr %v4uint %9045 %2599 + OpBranch %11419 + %11419 = OpLabel + %19771 = OpPhi %v4uint %20047 %9725 %17794 %16064 + %8053 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %12206 + OpStore %8053 %19771 + OpBranch %19902 + %19902 = OpLabel + %22028 = OpIAdd %uint %8038 %int_1 + OpBranch %11625 + %6980 = OpLabel + OpBranch %14903 + %14903 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_dxt1_rgba8_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x0000627F, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, + 0x0004002B, 0x0000000B, 0x0000012F, 0x000000F8, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0004002B, 0x0000000B, 0x00000B47, 0x0003F000, + 0x0004002B, 0x0000000B, 0x00000A2E, 0x0000000C, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000B, 0x000007FF, 0x0F800000, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x000000E9, 0x00700007, 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, + 0x0004002B, 0x0000000B, 0x00000AC1, 0x00000C00, 0x0004002B, 0x0000000B, 0x00000A09, 0x55555555, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A08, 0xAAAAAAAA, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0007002C, 0x00000017, 0x0000004D, 0x00000A0A, 0x00000A10, 0x00000A16, 0x00000A1C, 0x0004002B, + 0x0000000B, 0x00000A44, 0x000003FF, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, + 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, + 0x0000000B, 0x00000A46, 0x00000014, 0x0007002C, 0x00000017, 0x00000083, 0x00000A0D, 0x00000A13, + 0x00000A19, 0x00000A1F, 0x0004002B, 0x0000000B, 0x00000580, 0xFF000000, 0x0004002B, 0x0000000B, + 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000C, + 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, + 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, + 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, + 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, + 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, + 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, + 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, + 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, + 0x00000A05, 0xFFFFFFFE, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, + 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, + 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, + 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, + 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, + 0x0006002C, 0x00000014, 0x00000A24, 0x00000A10, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, + 0x00000009, 0x00000002, 0x0006002C, 0x00000014, 0x00000A3C, 0x00000A10, 0x00000A10, 0x00000A0A, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A32, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, + 0x00000002, 0x00000017, 0x00040017, 0x00000013, 0x00000009, 0x00000004, 0x0003001D, 0x000007DD, + 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A33, 0x00000002, 0x000007B5, + 0x0004003B, 0x00000A33, 0x0000140E, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, + 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0007002C, 0x00000017, + 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, + 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, + 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000011, 0x000003E1, 0x0000012F, 0x0000012F, 0x0005002C, + 0x00000011, 0x000003F7, 0x00000B47, 0x00000B47, 0x0005002C, 0x00000011, 0x000009F3, 0x000007FF, + 0x000007FF, 0x0005002C, 0x00000011, 0x00000778, 0x00000A19, 0x00000A19, 0x0005002C, 0x00000011, + 0x000001F7, 0x000000E9, 0x000000E9, 0x0005002C, 0x00000011, 0x0000078D, 0x00000A1C, 0x00000A1C, + 0x0005002C, 0x00000011, 0x0000004E, 0x00000AC1, 0x00000AC1, 0x0007002C, 0x00000017, 0x00000B3E, + 0x00000A09, 0x00000A09, 0x00000A09, 0x00000A09, 0x0007002C, 0x00000017, 0x00000B86, 0x00000A0D, + 0x00000A0D, 0x00000A0D, 0x00000A0D, 0x0007002C, 0x00000017, 0x00000B2C, 0x00000A08, 0x00000A08, + 0x00000A08, 0x00000A08, 0x0007002C, 0x00000017, 0x000003A1, 0x00000A44, 0x00000A44, 0x00000A44, + 0x00000A44, 0x0007002C, 0x00000017, 0x000001A9, 0x00000A28, 0x00000A28, 0x00000A28, 0x00000A28, + 0x0007002C, 0x00000017, 0x000003C5, 0x00000A46, 0x00000A46, 0x00000A46, 0x00000A46, 0x0007002C, + 0x00000017, 0x00000A27, 0x00000580, 0x00000580, 0x00000580, 0x00000580, 0x0007002C, 0x00000017, + 0x0000002F, 0x00000A13, 0x00000A13, 0x00000A13, 0x00000A13, 0x00050036, 0x00000008, 0x0000161F, + 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00003A37, 0x00000000, 0x000300FB, + 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, + 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, + 0x00003526, 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, + 0x0000000B, 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, + 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, + 0x000061E2, 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, + 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, + 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, + 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, + 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, + 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, + 0x00050041, 0x00000288, 0x00004EBE, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x0000578C, + 0x00004EBE, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A20, 0x0004003D, 0x0000000B, + 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, + 0x0000538B, 0x00002A0E, 0x00000A24, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, + 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, + 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, + 0x00006067, 0x00004288, 0x000300F7, 0x000036C2, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, + 0x000036C2, 0x000200F8, 0x000055E8, 0x000200F9, 0x00003A37, 0x000200F8, 0x000036C2, 0x000500C4, + 0x00000014, 0x000043C0, 0x0000538B, 0x00000A3C, 0x0004007C, 0x00000016, 0x00003C81, 0x000043C0, + 0x00050051, 0x0000000C, 0x000047A0, 0x00003C81, 0x00000000, 0x00050084, 0x0000000C, 0x00002492, + 0x000047A0, 0x00000A17, 0x00050051, 0x0000000C, 0x000018DA, 0x00003C81, 0x00000002, 0x0004007C, + 0x0000000C, 0x000038A9, 0x000019C2, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, + 0x00050051, 0x0000000C, 0x000044BE, 0x00003C81, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, + 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x0000578C, 0x00050084, 0x0000000C, + 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x00002492, 0x00005FD7, + 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00002375, 0x00002A92, + 0x0000578B, 0x000500C2, 0x0000000B, 0x00002DCE, 0x00002375, 0x00000A16, 0x000500C2, 0x0000000B, + 0x00001B41, 0x0000578C, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, + 0x00005768, 0x00004E29, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, + 0x00004384, 0x0000537D, 0x000018D9, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, 0x00002970, + 0x0000538B, 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, + 0x000024FD, 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000002, + 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4D, + 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, + 0x00005321, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, 0x00005321, + 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, + 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, + 0x00006242, 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, + 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, + 0x000049FC, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, + 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, + 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, + 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, + 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A25, 0x000500C3, 0x0000000C, 0x00005DE3, + 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, 0x00050080, + 0x0000000C, 0x000035A3, 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, + 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, + 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, + 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, + 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, + 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, + 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, + 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, + 0x000047B4, 0x00000A25, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, + 0x0000000C, 0x00004ADE, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, + 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, + 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, + 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, + 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, + 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, + 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, + 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, + 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, + 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, + 0x0000000C, 0x000054ED, 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, + 0x0004007C, 0x00000012, 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, 0x000042C3, 0x000019AD, + 0x00000000, 0x000500C3, 0x0000000C, 0x000024FE, 0x000042C3, 0x00000A1A, 0x00050051, 0x0000000C, + 0x00002748, 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, + 0x000500C2, 0x0000000B, 0x00005B4E, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, + 0x00005B4E, 0x00050084, 0x0000000C, 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, + 0x00003F5E, 0x000024FE, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A28, + 0x000500C7, 0x0000000C, 0x00002AB6, 0x000042C3, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, + 0x00002748, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, + 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, + 0x00000A13, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, + 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, + 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, + 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, + 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, + 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, + 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, + 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, + 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, + 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, + 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C3, 0x00000A14, + 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, + 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, + 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, + 0x00000AC8, 0x00050080, 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, + 0x000200F8, 0x00001E0B, 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, 0x0000537D, 0x00002F42, + 0x000018D9, 0x000200F9, 0x00005F43, 0x000200F8, 0x00004E29, 0x0004007C, 0x00000016, 0x00005F7F, + 0x0000538B, 0x00050051, 0x0000000C, 0x000022D6, 0x00005F7F, 0x00000000, 0x00050084, 0x0000000C, + 0x00002493, 0x000022D6, 0x00000A23, 0x00050051, 0x0000000C, 0x000018DB, 0x00005F7F, 0x00000002, + 0x0004007C, 0x0000000C, 0x000038AA, 0x00005789, 0x00050084, 0x0000000C, 0x00002C10, 0x000018DB, + 0x000038AA, 0x00050051, 0x0000000C, 0x000044BF, 0x00005F7F, 0x00000001, 0x00050080, 0x0000000C, + 0x000056D5, 0x00002C10, 0x000044BF, 0x0004007C, 0x0000000C, 0x00005786, 0x00005788, 0x00050084, + 0x0000000C, 0x00001E9F, 0x000056D5, 0x00005786, 0x00050080, 0x0000000C, 0x00001F30, 0x00002493, + 0x00001E9F, 0x000200F9, 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, + 0x0000292C, 0x00001E0B, 0x00001F30, 0x00004E29, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, + 0x00050080, 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, + 0x000056CD, 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, + 0x00004315, 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004315, + 0x000500AA, 0x00000009, 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, + 0x000061E2, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, + 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, + 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, + 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, + 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, + 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, + 0x00001CAA, 0x00005F43, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000061E2, + 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x00003450, + 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x00003450, 0x000200F8, 0x00002B38, 0x000500C4, + 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, + 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x00003450, + 0x000200F8, 0x00003450, 0x000700F5, 0x00000017, 0x00005654, 0x00005879, 0x00003463, 0x000029E8, + 0x00002B38, 0x000600A9, 0x0000000B, 0x00002E64, 0x00004376, 0x00000A10, 0x00000A0D, 0x00050080, + 0x0000000B, 0x00002C4B, 0x00005665, 0x00002E64, 0x00060041, 0x00000294, 0x00004766, 0x0000107A, + 0x00000A0B, 0x00002C4B, 0x0004003D, 0x00000017, 0x000019B2, 0x00004766, 0x000300F7, 0x00003A1A, + 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, + 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, + 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, + 0x00003450, 0x00003FF9, 0x00002958, 0x000300F7, 0x00002DC8, 0x00000000, 0x000400FA, 0x00003B23, + 0x00002B39, 0x00002DC8, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, + 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, + 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002DC8, 0x000200F8, 0x00002DC8, 0x000700F5, + 0x00000017, 0x00004C59, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x00050051, 0x0000000B, + 0x00005F39, 0x00005654, 0x00000000, 0x000500C4, 0x0000000B, 0x00003C7F, 0x00005F39, 0x00000A13, + 0x000500C2, 0x0000000B, 0x00001951, 0x00005F39, 0x00000A31, 0x00050050, 0x00000011, 0x00004370, + 0x00003C7F, 0x00001951, 0x000500C7, 0x00000011, 0x0000191E, 0x00004370, 0x000003E1, 0x000500C4, + 0x0000000B, 0x0000503F, 0x00005F39, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005E64, 0x00005F39, + 0x00000A25, 0x00050050, 0x00000011, 0x00004383, 0x0000503F, 0x00005E64, 0x000500C7, 0x00000011, + 0x00001897, 0x00004383, 0x000003F7, 0x000500C5, 0x00000011, 0x0000375A, 0x0000191E, 0x00001897, + 0x000500C4, 0x0000000B, 0x00005C88, 0x00005F39, 0x00000A2E, 0x000500C2, 0x0000000B, 0x00005817, + 0x00005F39, 0x00000A16, 0x00050050, 0x00000011, 0x00004385, 0x00005C88, 0x00005817, 0x000500C7, + 0x00000011, 0x00001871, 0x00004385, 0x000009F3, 0x000500C5, 0x00000011, 0x00003913, 0x0000375A, + 0x00001871, 0x000500C2, 0x00000011, 0x00005759, 0x00003913, 0x00000778, 0x000500C7, 0x00000011, + 0x000018CB, 0x00005759, 0x000001F7, 0x000500C5, 0x00000011, 0x00004046, 0x00003913, 0x000018CB, + 0x000500C2, 0x00000011, 0x0000575A, 0x00004046, 0x0000078D, 0x000500C7, 0x00000011, 0x00005AE7, + 0x0000575A, 0x0000004E, 0x000500C5, 0x00000011, 0x000041EB, 0x00004046, 0x00005AE7, 0x00050051, + 0x0000000B, 0x00005082, 0x00005654, 0x00000002, 0x000500C4, 0x0000000B, 0x00002364, 0x00005082, + 0x00000A13, 0x000500C2, 0x0000000B, 0x00001952, 0x00005082, 0x00000A31, 0x00050050, 0x00000011, + 0x00004371, 0x00002364, 0x00001952, 0x000500C7, 0x00000011, 0x0000191F, 0x00004371, 0x000003E1, + 0x000500C4, 0x0000000B, 0x00005040, 0x00005082, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005E65, + 0x00005082, 0x00000A25, 0x00050050, 0x00000011, 0x00004386, 0x00005040, 0x00005E65, 0x000500C7, + 0x00000011, 0x00001898, 0x00004386, 0x000003F7, 0x000500C5, 0x00000011, 0x0000375B, 0x0000191F, + 0x00001898, 0x000500C4, 0x0000000B, 0x00005C89, 0x00005082, 0x00000A2E, 0x000500C2, 0x0000000B, + 0x00005818, 0x00005082, 0x00000A16, 0x00050050, 0x00000011, 0x00004387, 0x00005C89, 0x00005818, + 0x000500C7, 0x00000011, 0x00001872, 0x00004387, 0x000009F3, 0x000500C5, 0x00000011, 0x00003914, + 0x0000375B, 0x00001872, 0x000500C2, 0x00000011, 0x0000575B, 0x00003914, 0x00000778, 0x000500C7, + 0x00000011, 0x000018CC, 0x0000575B, 0x000001F7, 0x000500C5, 0x00000011, 0x00004047, 0x00003914, + 0x000018CC, 0x000500C2, 0x00000011, 0x0000575C, 0x00004047, 0x0000078D, 0x000500C7, 0x00000011, + 0x00005AE8, 0x0000575C, 0x0000004E, 0x000500C5, 0x00000011, 0x00003962, 0x00004047, 0x00005AE8, + 0x00050051, 0x0000000B, 0x00004B57, 0x000041EB, 0x00000000, 0x00050051, 0x0000000B, 0x00005CB2, + 0x000041EB, 0x00000001, 0x00050051, 0x0000000B, 0x00001DEC, 0x00003962, 0x00000000, 0x00050051, + 0x0000000B, 0x00002675, 0x00003962, 0x00000001, 0x00050051, 0x0000000B, 0x00002317, 0x00004C59, + 0x00000000, 0x000500C4, 0x0000000B, 0x00002F1D, 0x00002317, 0x00000A13, 0x000500C2, 0x0000000B, + 0x00001953, 0x00002317, 0x00000A31, 0x00050050, 0x00000011, 0x00004372, 0x00002F1D, 0x00001953, + 0x000500C7, 0x00000011, 0x00001920, 0x00004372, 0x000003E1, 0x000500C4, 0x0000000B, 0x00005041, + 0x00002317, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005E66, 0x00002317, 0x00000A25, 0x00050050, + 0x00000011, 0x00004388, 0x00005041, 0x00005E66, 0x000500C7, 0x00000011, 0x00001899, 0x00004388, + 0x000003F7, 0x000500C5, 0x00000011, 0x0000375C, 0x00001920, 0x00001899, 0x000500C4, 0x0000000B, + 0x00005C8A, 0x00002317, 0x00000A2E, 0x000500C2, 0x0000000B, 0x00005819, 0x00002317, 0x00000A16, + 0x00050050, 0x00000011, 0x00004389, 0x00005C8A, 0x00005819, 0x000500C7, 0x00000011, 0x00001873, + 0x00004389, 0x000009F3, 0x000500C5, 0x00000011, 0x00003915, 0x0000375C, 0x00001873, 0x000500C2, + 0x00000011, 0x0000575D, 0x00003915, 0x00000778, 0x000500C7, 0x00000011, 0x000018CD, 0x0000575D, + 0x000001F7, 0x000500C5, 0x00000011, 0x00004048, 0x00003915, 0x000018CD, 0x000500C2, 0x00000011, + 0x0000575E, 0x00004048, 0x0000078D, 0x000500C7, 0x00000011, 0x00005AE9, 0x0000575E, 0x0000004E, + 0x000500C5, 0x00000011, 0x000041EC, 0x00004048, 0x00005AE9, 0x00050051, 0x0000000B, 0x00005084, + 0x00004C59, 0x00000002, 0x000500C4, 0x0000000B, 0x00002365, 0x00005084, 0x00000A13, 0x000500C2, + 0x0000000B, 0x00001954, 0x00005084, 0x00000A31, 0x00050050, 0x00000011, 0x00004373, 0x00002365, + 0x00001954, 0x000500C7, 0x00000011, 0x00001921, 0x00004373, 0x000003E1, 0x000500C4, 0x0000000B, + 0x00005042, 0x00005084, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005E67, 0x00005084, 0x00000A25, + 0x00050050, 0x00000011, 0x0000438A, 0x00005042, 0x00005E67, 0x000500C7, 0x00000011, 0x0000189A, + 0x0000438A, 0x000003F7, 0x000500C5, 0x00000011, 0x0000375D, 0x00001921, 0x0000189A, 0x000500C4, + 0x0000000B, 0x00005C8B, 0x00005084, 0x00000A2E, 0x000500C2, 0x0000000B, 0x0000581A, 0x00005084, + 0x00000A16, 0x00050050, 0x00000011, 0x0000438B, 0x00005C8B, 0x0000581A, 0x000500C7, 0x00000011, + 0x00001874, 0x0000438B, 0x000009F3, 0x000500C5, 0x00000011, 0x00003916, 0x0000375D, 0x00001874, + 0x000500C2, 0x00000011, 0x0000575F, 0x00003916, 0x00000778, 0x000500C7, 0x00000011, 0x000018CE, + 0x0000575F, 0x000001F7, 0x000500C5, 0x00000011, 0x00004049, 0x00003916, 0x000018CE, 0x000500C2, + 0x00000011, 0x00005760, 0x00004049, 0x0000078D, 0x000500C7, 0x00000011, 0x00005AEB, 0x00005760, + 0x0000004E, 0x000500C5, 0x00000011, 0x00003963, 0x00004049, 0x00005AEB, 0x00050051, 0x0000000B, + 0x00004B58, 0x000041EC, 0x00000000, 0x00050051, 0x0000000B, 0x00005CB3, 0x000041EC, 0x00000001, + 0x00050051, 0x0000000B, 0x00001DD9, 0x00003963, 0x00000000, 0x00050051, 0x0000000B, 0x00001E86, + 0x00003963, 0x00000001, 0x00070050, 0x00000017, 0x000045CD, 0x00004B57, 0x00001DEC, 0x00004B58, + 0x00001DD9, 0x00070050, 0x00000017, 0x000047D8, 0x00005CB2, 0x00002675, 0x00005CB3, 0x00001E86, + 0x000500B2, 0x00000013, 0x00002797, 0x000045CD, 0x000047D8, 0x00050051, 0x0000000B, 0x00003C9A, + 0x00005654, 0x00000001, 0x00050051, 0x0000000B, 0x000046AC, 0x00005654, 0x00000003, 0x00050051, + 0x0000000B, 0x00001DDA, 0x00004C59, 0x00000001, 0x00050051, 0x0000000B, 0x0000275B, 0x00004C59, + 0x00000003, 0x00070050, 0x00000017, 0x00004137, 0x00003C9A, 0x000046AC, 0x00001DDA, 0x0000275B, + 0x000500C7, 0x00000017, 0x0000220D, 0x00004137, 0x00000B3E, 0x000500C4, 0x00000017, 0x00005554, + 0x0000220D, 0x00000B86, 0x000500C7, 0x00000017, 0x000050AE, 0x00004137, 0x00000B2C, 0x000500C2, + 0x00000017, 0x000040D7, 0x000050AE, 0x00000B86, 0x000500C5, 0x00000017, 0x00005DC0, 0x00005554, + 0x000040D7, 0x000500C7, 0x00000017, 0x00004CA2, 0x00005DC0, 0x00000B2C, 0x000500C2, 0x00000017, + 0x00005000, 0x00004CA2, 0x00000B86, 0x000500C6, 0x00000017, 0x00003D71, 0x00005DC0, 0x00005000, + 0x000400C8, 0x00000017, 0x00002821, 0x00004137, 0x000500C7, 0x00000017, 0x00003BBE, 0x00002821, + 0x00000B3E, 0x000500C4, 0x00000017, 0x00005507, 0x00003BBE, 0x00000B86, 0x000500C6, 0x00000017, + 0x00003AEF, 0x00002821, 0x00005507, 0x000600A9, 0x00000017, 0x0000282C, 0x00002797, 0x00003AEF, + 0x00003D71, 0x000200F9, 0x00002D69, 0x000200F8, 0x00002D69, 0x000700F5, 0x00000017, 0x00002BA7, + 0x0000282C, 0x00002DC8, 0x00001F7B, 0x00004DBE, 0x000700F5, 0x0000000B, 0x000032E9, 0x00002DCE, + 0x00002DC8, 0x00002B3D, 0x00004DBE, 0x000700F5, 0x0000000B, 0x00001F66, 0x00000A0A, 0x00002DC8, + 0x0000560C, 0x00004DBE, 0x000500B0, 0x00000009, 0x0000397F, 0x00001F66, 0x00000A16, 0x000400F6, + 0x00001B44, 0x00004DBE, 0x00000001, 0x000400FA, 0x0000397F, 0x00004982, 0x00001B44, 0x000200F8, + 0x00004982, 0x000500AB, 0x00000009, 0x00002AD9, 0x00001F66, 0x00000A0A, 0x000300F7, 0x00003D1D, + 0x00000000, 0x000400FA, 0x00002AD9, 0x0000298A, 0x00003D1D, 0x000200F8, 0x0000298A, 0x00050051, + 0x0000000B, 0x00002B5B, 0x000043C0, 0x00000001, 0x00050080, 0x0000000B, 0x000031DA, 0x00002B5B, + 0x00001F66, 0x000500AE, 0x00000009, 0x00003994, 0x000031DA, 0x000019C2, 0x000300F7, 0x00001F69, + 0x00000000, 0x000400FA, 0x00003994, 0x000055E9, 0x00001F69, 0x000200F8, 0x000055E9, 0x000200F9, + 0x00001B44, 0x000200F8, 0x00001F69, 0x00050080, 0x0000000B, 0x000030CB, 0x000032E9, 0x00001B41, + 0x000500C2, 0x00000017, 0x000060B0, 0x00002BA7, 0x0000013D, 0x000200F9, 0x00003D1D, 0x000200F8, + 0x00003D1D, 0x000700F5, 0x00000017, 0x00001F7B, 0x00002BA7, 0x00004982, 0x000060B0, 0x00001F69, + 0x000700F5, 0x0000000B, 0x00002B3D, 0x000032E9, 0x00004982, 0x000030CB, 0x00001F69, 0x00050051, + 0x00000009, 0x00004413, 0x00002797, 0x00000000, 0x000300F7, 0x00002C98, 0x00000000, 0x000400FA, + 0x00004413, 0x000025FA, 0x00003EBD, 0x000200F8, 0x000025FA, 0x00050051, 0x0000000B, 0x00004D47, + 0x00001F7B, 0x00000000, 0x00070050, 0x00000017, 0x00004F0A, 0x00004D47, 0x00004D47, 0x00004D47, + 0x00004D47, 0x000500C2, 0x00000017, 0x00002238, 0x00004F0A, 0x0000004D, 0x000500C7, 0x00000017, + 0x00005F38, 0x00002238, 0x00000B86, 0x00070050, 0x00000017, 0x00004C2E, 0x00004B57, 0x00004B57, + 0x00004B57, 0x00004B57, 0x00050084, 0x00000017, 0x0000585A, 0x00005F38, 0x00004C2E, 0x000500C2, + 0x00000017, 0x00003EEA, 0x00004F0A, 0x00000083, 0x000500C7, 0x00000017, 0x00003A6E, 0x00003EEA, + 0x00000B86, 0x00070050, 0x00000017, 0x00004748, 0x00005CB2, 0x00005CB2, 0x00005CB2, 0x00005CB2, + 0x00050084, 0x00000017, 0x00003A75, 0x00003A6E, 0x00004748, 0x00050080, 0x00000017, 0x00003077, + 0x0000585A, 0x00003A75, 0x000500C7, 0x0000000B, 0x0000386B, 0x00004D47, 0x00000A08, 0x000500C2, + 0x0000000B, 0x00005B7C, 0x0000386B, 0x00000A0D, 0x000500C7, 0x0000000B, 0x000023AA, 0x00004D47, + 0x00005B7C, 0x00070050, 0x00000017, 0x000022A7, 0x000023AA, 0x000023AA, 0x000023AA, 0x000023AA, + 0x000500C2, 0x00000017, 0x000025A1, 0x000022A7, 0x0000004D, 0x000500C7, 0x00000017, 0x00005E1F, + 0x000025A1, 0x00000B86, 0x000500C7, 0x0000000B, 0x000048BC, 0x00004D47, 0x00000A09, 0x000500C5, + 0x0000000B, 0x00003FAA, 0x000048BC, 0x00005B7C, 0x000500C7, 0x00000017, 0x00004FA0, 0x00003077, + 0x000003A1, 0x000500C2, 0x00000017, 0x000050E8, 0x00004FA0, 0x00005E1F, 0x000500C4, 0x00000017, + 0x00003702, 0x000050E8, 0x000002ED, 0x000500C2, 0x00000017, 0x000054F5, 0x00003077, 0x000001A9, + 0x000500C7, 0x00000017, 0x000055B4, 0x000054F5, 0x000003A1, 0x000500C2, 0x00000017, 0x00004F2B, + 0x000055B4, 0x00005E1F, 0x000500C4, 0x00000017, 0x000018BE, 0x00004F2B, 0x0000013D, 0x00050080, + 0x00000017, 0x0000416E, 0x00003702, 0x000018BE, 0x000500C2, 0x00000017, 0x0000573E, 0x00003077, + 0x000003C5, 0x000500C2, 0x00000017, 0x00002DC9, 0x0000573E, 0x00005E1F, 0x00050080, 0x00000017, + 0x000045EB, 0x0000416E, 0x00002DC9, 0x00070050, 0x00000017, 0x00002313, 0x00003FAA, 0x00003FAA, + 0x00003FAA, 0x00003FAA, 0x000500C2, 0x00000017, 0x000048A5, 0x00002313, 0x0000004D, 0x000500C7, + 0x00000017, 0x00003BC8, 0x000048A5, 0x00000B86, 0x00050084, 0x00000017, 0x00002074, 0x00003BC8, + 0x00000A27, 0x00050080, 0x00000017, 0x00004E4C, 0x000045EB, 0x00002074, 0x000200F9, 0x00002C98, + 0x000200F8, 0x00003EBD, 0x00050051, 0x0000000B, 0x000047AE, 0x00001F7B, 0x00000000, 0x000400C8, + 0x0000000B, 0x00005951, 0x000047AE, 0x00070050, 0x00000017, 0x00002A3F, 0x00005951, 0x00005951, + 0x00005951, 0x00005951, 0x000500C2, 0x00000017, 0x00005DD5, 0x00002A3F, 0x0000004D, 0x000500C7, + 0x00000017, 0x00005F3A, 0x00005DD5, 0x0000002F, 0x00070050, 0x00000017, 0x000043B8, 0x00004B57, + 0x00004B57, 0x00004B57, 0x00004B57, 0x00050084, 0x00000017, 0x00005A86, 0x00005F3A, 0x000043B8, + 0x00070050, 0x00000017, 0x0000627B, 0x000047AE, 0x000047AE, 0x000047AE, 0x000047AE, 0x000500C2, + 0x00000017, 0x0000382A, 0x0000627B, 0x0000004D, 0x000500C7, 0x00000017, 0x00005F3B, 0x0000382A, + 0x0000002F, 0x00070050, 0x00000017, 0x00004749, 0x00005CB2, 0x00005CB2, 0x00005CB2, 0x00005CB2, + 0x00050084, 0x00000017, 0x00003A76, 0x00005F3B, 0x00004749, 0x00050080, 0x00000017, 0x00002C03, + 0x00005A86, 0x00003A76, 0x000500C7, 0x00000017, 0x000060BE, 0x00002C03, 0x000003A1, 0x00050086, + 0x00000017, 0x00002409, 0x000060BE, 0x0000002F, 0x000500C4, 0x00000017, 0x000044C8, 0x00002409, + 0x000002ED, 0x000500C2, 0x00000017, 0x00002AD1, 0x00002C03, 0x000001A9, 0x000500C7, 0x00000017, + 0x000033C1, 0x00002AD1, 0x000003A1, 0x00050086, 0x00000017, 0x000043A0, 0x000033C1, 0x0000002F, + 0x000500C4, 0x00000017, 0x00004262, 0x000043A0, 0x0000013D, 0x000500C5, 0x00000017, 0x000018AE, + 0x000044C8, 0x00004262, 0x000500C2, 0x00000017, 0x00003BF0, 0x00002C03, 0x000003C5, 0x00050086, + 0x00000017, 0x00005DE0, 0x00003BF0, 0x0000002F, 0x000500C5, 0x00000017, 0x00002352, 0x000018AE, + 0x00005DE0, 0x000500C5, 0x00000017, 0x0000457F, 0x00002352, 0x00000A27, 0x000200F9, 0x00002C98, + 0x000200F8, 0x00002C98, 0x000700F5, 0x00000017, 0x00004D37, 0x00004E4C, 0x000025FA, 0x0000457F, + 0x00003EBD, 0x00060041, 0x00000294, 0x000060F9, 0x0000140E, 0x00000A0B, 0x00002B3D, 0x0003003E, + 0x000060F9, 0x00004D37, 0x00050080, 0x0000000B, 0x00002FAC, 0x00002B3D, 0x00000A0D, 0x00050051, + 0x00000009, 0x0000394C, 0x00002797, 0x00000001, 0x000300F7, 0x00002C99, 0x00000000, 0x000400FA, + 0x0000394C, 0x000025FB, 0x00003EBE, 0x000200F8, 0x000025FB, 0x00050051, 0x0000000B, 0x00004D48, + 0x00001F7B, 0x00000001, 0x00070050, 0x00000017, 0x00004F0B, 0x00004D48, 0x00004D48, 0x00004D48, + 0x00004D48, 0x000500C2, 0x00000017, 0x00002239, 0x00004F0B, 0x0000004D, 0x000500C7, 0x00000017, + 0x00005F3C, 0x00002239, 0x00000B86, 0x00070050, 0x00000017, 0x00004C2F, 0x00001DEC, 0x00001DEC, + 0x00001DEC, 0x00001DEC, 0x00050084, 0x00000017, 0x0000585B, 0x00005F3C, 0x00004C2F, 0x000500C2, + 0x00000017, 0x00003EEB, 0x00004F0B, 0x00000083, 0x000500C7, 0x00000017, 0x00003A6F, 0x00003EEB, + 0x00000B86, 0x00070050, 0x00000017, 0x0000474A, 0x00002675, 0x00002675, 0x00002675, 0x00002675, + 0x00050084, 0x00000017, 0x00003A77, 0x00003A6F, 0x0000474A, 0x00050080, 0x00000017, 0x00003078, + 0x0000585B, 0x00003A77, 0x000500C7, 0x0000000B, 0x0000386C, 0x00004D48, 0x00000A08, 0x000500C2, + 0x0000000B, 0x00005B7D, 0x0000386C, 0x00000A0D, 0x000500C7, 0x0000000B, 0x000023AB, 0x00004D48, + 0x00005B7D, 0x00070050, 0x00000017, 0x000022A8, 0x000023AB, 0x000023AB, 0x000023AB, 0x000023AB, + 0x000500C2, 0x00000017, 0x000025A2, 0x000022A8, 0x0000004D, 0x000500C7, 0x00000017, 0x00005E20, + 0x000025A2, 0x00000B86, 0x000500C7, 0x0000000B, 0x000048BD, 0x00004D48, 0x00000A09, 0x000500C5, + 0x0000000B, 0x00003FAB, 0x000048BD, 0x00005B7D, 0x000500C7, 0x00000017, 0x00004FA1, 0x00003078, + 0x000003A1, 0x000500C2, 0x00000017, 0x000050E9, 0x00004FA1, 0x00005E20, 0x000500C4, 0x00000017, + 0x00003703, 0x000050E9, 0x000002ED, 0x000500C2, 0x00000017, 0x000054F6, 0x00003078, 0x000001A9, + 0x000500C7, 0x00000017, 0x000055B5, 0x000054F6, 0x000003A1, 0x000500C2, 0x00000017, 0x00004F2C, + 0x000055B5, 0x00005E20, 0x000500C4, 0x00000017, 0x000018BF, 0x00004F2C, 0x0000013D, 0x00050080, + 0x00000017, 0x0000416F, 0x00003703, 0x000018BF, 0x000500C2, 0x00000017, 0x0000573F, 0x00003078, + 0x000003C5, 0x000500C2, 0x00000017, 0x00002DCA, 0x0000573F, 0x00005E20, 0x00050080, 0x00000017, + 0x000045EC, 0x0000416F, 0x00002DCA, 0x00070050, 0x00000017, 0x00002314, 0x00003FAB, 0x00003FAB, + 0x00003FAB, 0x00003FAB, 0x000500C2, 0x00000017, 0x000048A6, 0x00002314, 0x0000004D, 0x000500C7, + 0x00000017, 0x00003BC9, 0x000048A6, 0x00000B86, 0x00050084, 0x00000017, 0x00002075, 0x00003BC9, + 0x00000A27, 0x00050080, 0x00000017, 0x00004E4D, 0x000045EC, 0x00002075, 0x000200F9, 0x00002C99, + 0x000200F8, 0x00003EBE, 0x00050051, 0x0000000B, 0x000047AF, 0x00001F7B, 0x00000001, 0x000400C8, + 0x0000000B, 0x00005952, 0x000047AF, 0x00070050, 0x00000017, 0x00002A40, 0x00005952, 0x00005952, + 0x00005952, 0x00005952, 0x000500C2, 0x00000017, 0x00005DD6, 0x00002A40, 0x0000004D, 0x000500C7, + 0x00000017, 0x00005F3D, 0x00005DD6, 0x0000002F, 0x00070050, 0x00000017, 0x000043B9, 0x00001DEC, + 0x00001DEC, 0x00001DEC, 0x00001DEC, 0x00050084, 0x00000017, 0x00005A87, 0x00005F3D, 0x000043B9, + 0x00070050, 0x00000017, 0x0000627C, 0x000047AF, 0x000047AF, 0x000047AF, 0x000047AF, 0x000500C2, + 0x00000017, 0x0000382B, 0x0000627C, 0x0000004D, 0x000500C7, 0x00000017, 0x00005F3E, 0x0000382B, + 0x0000002F, 0x00070050, 0x00000017, 0x0000474B, 0x00002675, 0x00002675, 0x00002675, 0x00002675, + 0x00050084, 0x00000017, 0x00003A78, 0x00005F3E, 0x0000474B, 0x00050080, 0x00000017, 0x00002C04, + 0x00005A87, 0x00003A78, 0x000500C7, 0x00000017, 0x000060BF, 0x00002C04, 0x000003A1, 0x00050086, + 0x00000017, 0x0000240A, 0x000060BF, 0x0000002F, 0x000500C4, 0x00000017, 0x000044C9, 0x0000240A, + 0x000002ED, 0x000500C2, 0x00000017, 0x00002AD2, 0x00002C04, 0x000001A9, 0x000500C7, 0x00000017, + 0x000033C2, 0x00002AD2, 0x000003A1, 0x00050086, 0x00000017, 0x000043A1, 0x000033C2, 0x0000002F, + 0x000500C4, 0x00000017, 0x00004263, 0x000043A1, 0x0000013D, 0x000500C5, 0x00000017, 0x000018AF, + 0x000044C9, 0x00004263, 0x000500C2, 0x00000017, 0x00003BF1, 0x00002C04, 0x000003C5, 0x00050086, + 0x00000017, 0x00005DE1, 0x00003BF1, 0x0000002F, 0x000500C5, 0x00000017, 0x00002353, 0x000018AF, + 0x00005DE1, 0x000500C5, 0x00000017, 0x00004580, 0x00002353, 0x00000A27, 0x000200F9, 0x00002C99, + 0x000200F8, 0x00002C99, 0x000700F5, 0x00000017, 0x00004D39, 0x00004E4D, 0x000025FB, 0x00004580, + 0x00003EBE, 0x00060041, 0x00000294, 0x000060FA, 0x0000140E, 0x00000A0B, 0x00002FAC, 0x0003003E, + 0x000060FA, 0x00004D39, 0x00050080, 0x0000000B, 0x00002FAD, 0x00002B3D, 0x00000A10, 0x00050051, + 0x00000009, 0x0000394D, 0x00002797, 0x00000002, 0x000300F7, 0x00002C9A, 0x00000000, 0x000400FA, + 0x0000394D, 0x000025FC, 0x00003EBF, 0x000200F8, 0x000025FC, 0x00050051, 0x0000000B, 0x00004D49, + 0x00001F7B, 0x00000002, 0x00070050, 0x00000017, 0x00004F0C, 0x00004D49, 0x00004D49, 0x00004D49, + 0x00004D49, 0x000500C2, 0x00000017, 0x0000223A, 0x00004F0C, 0x0000004D, 0x000500C7, 0x00000017, + 0x00005F3F, 0x0000223A, 0x00000B86, 0x00070050, 0x00000017, 0x00004C30, 0x00004B58, 0x00004B58, + 0x00004B58, 0x00004B58, 0x00050084, 0x00000017, 0x0000585C, 0x00005F3F, 0x00004C30, 0x000500C2, + 0x00000017, 0x00003EEC, 0x00004F0C, 0x00000083, 0x000500C7, 0x00000017, 0x00003A70, 0x00003EEC, + 0x00000B86, 0x00070050, 0x00000017, 0x0000474C, 0x00005CB3, 0x00005CB3, 0x00005CB3, 0x00005CB3, + 0x00050084, 0x00000017, 0x00003A79, 0x00003A70, 0x0000474C, 0x00050080, 0x00000017, 0x00003079, + 0x0000585C, 0x00003A79, 0x000500C7, 0x0000000B, 0x0000386D, 0x00004D49, 0x00000A08, 0x000500C2, + 0x0000000B, 0x00005B7E, 0x0000386D, 0x00000A0D, 0x000500C7, 0x0000000B, 0x000023AC, 0x00004D49, + 0x00005B7E, 0x00070050, 0x00000017, 0x000022A9, 0x000023AC, 0x000023AC, 0x000023AC, 0x000023AC, + 0x000500C2, 0x00000017, 0x000025A3, 0x000022A9, 0x0000004D, 0x000500C7, 0x00000017, 0x00005E21, + 0x000025A3, 0x00000B86, 0x000500C7, 0x0000000B, 0x000048BE, 0x00004D49, 0x00000A09, 0x000500C5, + 0x0000000B, 0x00003FAC, 0x000048BE, 0x00005B7E, 0x000500C7, 0x00000017, 0x00004FA2, 0x00003079, + 0x000003A1, 0x000500C2, 0x00000017, 0x000050EA, 0x00004FA2, 0x00005E21, 0x000500C4, 0x00000017, + 0x00003704, 0x000050EA, 0x000002ED, 0x000500C2, 0x00000017, 0x000054F7, 0x00003079, 0x000001A9, + 0x000500C7, 0x00000017, 0x000055B6, 0x000054F7, 0x000003A1, 0x000500C2, 0x00000017, 0x00004F2D, + 0x000055B6, 0x00005E21, 0x000500C4, 0x00000017, 0x000018C0, 0x00004F2D, 0x0000013D, 0x00050080, + 0x00000017, 0x00004170, 0x00003704, 0x000018C0, 0x000500C2, 0x00000017, 0x00005740, 0x00003079, + 0x000003C5, 0x000500C2, 0x00000017, 0x00002DCB, 0x00005740, 0x00005E21, 0x00050080, 0x00000017, + 0x000045ED, 0x00004170, 0x00002DCB, 0x00070050, 0x00000017, 0x00002315, 0x00003FAC, 0x00003FAC, + 0x00003FAC, 0x00003FAC, 0x000500C2, 0x00000017, 0x000048A7, 0x00002315, 0x0000004D, 0x000500C7, + 0x00000017, 0x00003BCA, 0x000048A7, 0x00000B86, 0x00050084, 0x00000017, 0x00002076, 0x00003BCA, + 0x00000A27, 0x00050080, 0x00000017, 0x00004E4E, 0x000045ED, 0x00002076, 0x000200F9, 0x00002C9A, + 0x000200F8, 0x00003EBF, 0x00050051, 0x0000000B, 0x000047B0, 0x00001F7B, 0x00000002, 0x000400C8, + 0x0000000B, 0x00005953, 0x000047B0, 0x00070050, 0x00000017, 0x00002A41, 0x00005953, 0x00005953, + 0x00005953, 0x00005953, 0x000500C2, 0x00000017, 0x00005DD7, 0x00002A41, 0x0000004D, 0x000500C7, + 0x00000017, 0x00005F40, 0x00005DD7, 0x0000002F, 0x00070050, 0x00000017, 0x000043BA, 0x00004B58, + 0x00004B58, 0x00004B58, 0x00004B58, 0x00050084, 0x00000017, 0x00005A88, 0x00005F40, 0x000043BA, + 0x00070050, 0x00000017, 0x0000627D, 0x000047B0, 0x000047B0, 0x000047B0, 0x000047B0, 0x000500C2, + 0x00000017, 0x0000382C, 0x0000627D, 0x0000004D, 0x000500C7, 0x00000017, 0x00005F41, 0x0000382C, + 0x0000002F, 0x00070050, 0x00000017, 0x0000474D, 0x00005CB3, 0x00005CB3, 0x00005CB3, 0x00005CB3, + 0x00050084, 0x00000017, 0x00003A7A, 0x00005F41, 0x0000474D, 0x00050080, 0x00000017, 0x00002C05, + 0x00005A88, 0x00003A7A, 0x000500C7, 0x00000017, 0x000060C0, 0x00002C05, 0x000003A1, 0x00050086, + 0x00000017, 0x0000240B, 0x000060C0, 0x0000002F, 0x000500C4, 0x00000017, 0x000044CA, 0x0000240B, + 0x000002ED, 0x000500C2, 0x00000017, 0x00002AD3, 0x00002C05, 0x000001A9, 0x000500C7, 0x00000017, + 0x000033C3, 0x00002AD3, 0x000003A1, 0x00050086, 0x00000017, 0x000043A2, 0x000033C3, 0x0000002F, + 0x000500C4, 0x00000017, 0x00004264, 0x000043A2, 0x0000013D, 0x000500C5, 0x00000017, 0x000018B0, + 0x000044CA, 0x00004264, 0x000500C2, 0x00000017, 0x00003BF2, 0x00002C05, 0x000003C5, 0x00050086, + 0x00000017, 0x00005DE2, 0x00003BF2, 0x0000002F, 0x000500C5, 0x00000017, 0x00002354, 0x000018B0, + 0x00005DE2, 0x000500C5, 0x00000017, 0x00004581, 0x00002354, 0x00000A27, 0x000200F9, 0x00002C9A, + 0x000200F8, 0x00002C9A, 0x000700F5, 0x00000017, 0x00004D3A, 0x00004E4E, 0x000025FC, 0x00004581, + 0x00003EBF, 0x00060041, 0x00000294, 0x000060FB, 0x0000140E, 0x00000A0B, 0x00002FAD, 0x0003003E, + 0x000060FB, 0x00004D3A, 0x00050080, 0x0000000B, 0x00002FAE, 0x00002B3D, 0x00000A13, 0x00050051, + 0x00000009, 0x0000394E, 0x00002797, 0x00000003, 0x000300F7, 0x00002C9B, 0x00000000, 0x000400FA, + 0x0000394E, 0x000025FD, 0x00003EC0, 0x000200F8, 0x000025FD, 0x00050051, 0x0000000B, 0x00004D4A, + 0x00001F7B, 0x00000003, 0x00070050, 0x00000017, 0x00004F0D, 0x00004D4A, 0x00004D4A, 0x00004D4A, + 0x00004D4A, 0x000500C2, 0x00000017, 0x0000223B, 0x00004F0D, 0x0000004D, 0x000500C7, 0x00000017, + 0x00005F42, 0x0000223B, 0x00000B86, 0x00070050, 0x00000017, 0x00004C31, 0x00001DD9, 0x00001DD9, + 0x00001DD9, 0x00001DD9, 0x00050084, 0x00000017, 0x0000585D, 0x00005F42, 0x00004C31, 0x000500C2, + 0x00000017, 0x00003EED, 0x00004F0D, 0x00000083, 0x000500C7, 0x00000017, 0x00003A71, 0x00003EED, + 0x00000B86, 0x00070050, 0x00000017, 0x0000474E, 0x00001E86, 0x00001E86, 0x00001E86, 0x00001E86, + 0x00050084, 0x00000017, 0x00003A7B, 0x00003A71, 0x0000474E, 0x00050080, 0x00000017, 0x0000307A, + 0x0000585D, 0x00003A7B, 0x000500C7, 0x0000000B, 0x0000386E, 0x00004D4A, 0x00000A08, 0x000500C2, + 0x0000000B, 0x00005B7F, 0x0000386E, 0x00000A0D, 0x000500C7, 0x0000000B, 0x000023AD, 0x00004D4A, + 0x00005B7F, 0x00070050, 0x00000017, 0x000022AA, 0x000023AD, 0x000023AD, 0x000023AD, 0x000023AD, + 0x000500C2, 0x00000017, 0x000025A4, 0x000022AA, 0x0000004D, 0x000500C7, 0x00000017, 0x00005E22, + 0x000025A4, 0x00000B86, 0x000500C7, 0x0000000B, 0x000048BF, 0x00004D4A, 0x00000A09, 0x000500C5, + 0x0000000B, 0x00003FAD, 0x000048BF, 0x00005B7F, 0x000500C7, 0x00000017, 0x00004FA3, 0x0000307A, + 0x000003A1, 0x000500C2, 0x00000017, 0x000050EB, 0x00004FA3, 0x00005E22, 0x000500C4, 0x00000017, + 0x00003705, 0x000050EB, 0x000002ED, 0x000500C2, 0x00000017, 0x000054F8, 0x0000307A, 0x000001A9, + 0x000500C7, 0x00000017, 0x000055B7, 0x000054F8, 0x000003A1, 0x000500C2, 0x00000017, 0x00004F2E, + 0x000055B7, 0x00005E22, 0x000500C4, 0x00000017, 0x000018C1, 0x00004F2E, 0x0000013D, 0x00050080, + 0x00000017, 0x00004171, 0x00003705, 0x000018C1, 0x000500C2, 0x00000017, 0x00005741, 0x0000307A, + 0x000003C5, 0x000500C2, 0x00000017, 0x00002DCC, 0x00005741, 0x00005E22, 0x00050080, 0x00000017, + 0x000045EE, 0x00004171, 0x00002DCC, 0x00070050, 0x00000017, 0x00002316, 0x00003FAD, 0x00003FAD, + 0x00003FAD, 0x00003FAD, 0x000500C2, 0x00000017, 0x000048A8, 0x00002316, 0x0000004D, 0x000500C7, + 0x00000017, 0x00003BCB, 0x000048A8, 0x00000B86, 0x00050084, 0x00000017, 0x00002077, 0x00003BCB, + 0x00000A27, 0x00050080, 0x00000017, 0x00004E4F, 0x000045EE, 0x00002077, 0x000200F9, 0x00002C9B, + 0x000200F8, 0x00003EC0, 0x00050051, 0x0000000B, 0x000047B1, 0x00001F7B, 0x00000003, 0x000400C8, + 0x0000000B, 0x00005954, 0x000047B1, 0x00070050, 0x00000017, 0x00002A42, 0x00005954, 0x00005954, + 0x00005954, 0x00005954, 0x000500C2, 0x00000017, 0x00005DD8, 0x00002A42, 0x0000004D, 0x000500C7, + 0x00000017, 0x00005F44, 0x00005DD8, 0x0000002F, 0x00070050, 0x00000017, 0x000043BB, 0x00001DD9, + 0x00001DD9, 0x00001DD9, 0x00001DD9, 0x00050084, 0x00000017, 0x00005A89, 0x00005F44, 0x000043BB, + 0x00070050, 0x00000017, 0x0000627E, 0x000047B1, 0x000047B1, 0x000047B1, 0x000047B1, 0x000500C2, + 0x00000017, 0x0000382D, 0x0000627E, 0x0000004D, 0x000500C7, 0x00000017, 0x00005F45, 0x0000382D, + 0x0000002F, 0x00070050, 0x00000017, 0x0000474F, 0x00001E86, 0x00001E86, 0x00001E86, 0x00001E86, + 0x00050084, 0x00000017, 0x00003A7C, 0x00005F45, 0x0000474F, 0x00050080, 0x00000017, 0x00002C06, + 0x00005A89, 0x00003A7C, 0x000500C7, 0x00000017, 0x000060C1, 0x00002C06, 0x000003A1, 0x00050086, + 0x00000017, 0x0000240C, 0x000060C1, 0x0000002F, 0x000500C4, 0x00000017, 0x000044CB, 0x0000240C, + 0x000002ED, 0x000500C2, 0x00000017, 0x00002AD4, 0x00002C06, 0x000001A9, 0x000500C7, 0x00000017, + 0x000033C4, 0x00002AD4, 0x000003A1, 0x00050086, 0x00000017, 0x000043A3, 0x000033C4, 0x0000002F, + 0x000500C4, 0x00000017, 0x00004265, 0x000043A3, 0x0000013D, 0x000500C5, 0x00000017, 0x000018B1, + 0x000044CB, 0x00004265, 0x000500C2, 0x00000017, 0x00003BF3, 0x00002C06, 0x000003C5, 0x00050086, + 0x00000017, 0x00005DE4, 0x00003BF3, 0x0000002F, 0x000500C5, 0x00000017, 0x00002355, 0x000018B1, + 0x00005DE4, 0x000500C5, 0x00000017, 0x00004582, 0x00002355, 0x00000A27, 0x000200F9, 0x00002C9B, + 0x000200F8, 0x00002C9B, 0x000700F5, 0x00000017, 0x00004D3B, 0x00004E4F, 0x000025FD, 0x00004582, + 0x00003EC0, 0x00060041, 0x00000294, 0x00001F75, 0x0000140E, 0x00000A0B, 0x00002FAE, 0x0003003E, + 0x00001F75, 0x00004D3B, 0x000200F9, 0x00004DBE, 0x000200F8, 0x00004DBE, 0x00050080, 0x0000000B, + 0x0000560C, 0x00001F66, 0x00000A0E, 0x000200F9, 0x00002D69, 0x000200F8, 0x00001B44, 0x000200F9, + 0x00003A37, 0x000200F8, 0x00003A37, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_dxt3_rgba8_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_dxt3_rgba8_cs.h new file mode 100644 index 0000000..58bb90f --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_dxt3_rgba8_cs.h @@ -0,0 +1,1158 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25213 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_3 = OpConstant %uint 3 + %uint_13 = OpConstant %uint 13 + %uint_248 = OpConstant %uint 248 + %uint_7 = OpConstant %uint 7 + %uint_9 = OpConstant %uint 9 +%uint_258048 = OpConstant %uint 258048 + %uint_12 = OpConstant %uint 12 + %uint_4 = OpConstant %uint 4 +%uint_260046848 = OpConstant %uint 260046848 + %uint_5 = OpConstant %uint 5 +%uint_7340039 = OpConstant %uint 7340039 + %uint_6 = OpConstant %uint 6 + %uint_3072 = OpConstant %uint 3072 +%uint_1431655765 = OpConstant %uint 1431655765 + %uint_1 = OpConstant %uint 1 +%uint_2863311530 = OpConstant %uint 2863311530 + %uint_0 = OpConstant %uint 0 + %uint_2 = OpConstant %uint 2 + %77 = OpConstantComposite %v4uint %uint_0 %uint_2 %uint_4 %uint_6 + %uint_1023 = OpConstant %uint 1023 + %uint_16 = OpConstant %uint 16 + %uint_10 = OpConstant %uint 10 + %uint_8 = OpConstant %uint 8 + %uint_20 = OpConstant %uint 20 +%uint_16711935 = OpConstant %uint 16711935 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2587 = OpConstantComposite %v3uint %uint_1 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 + %2620 = OpConstantComposite %v3uint %uint_2 %uint_2 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform + %269 = OpConstantComposite %v4uint %uint_0 %uint_4 %uint_8 %uint_12 + %uint_15 = OpConstant %uint 15 +%uint_285212672 = OpConstant %uint 285212672 + %uint_24 = OpConstant %uint 24 + %uint_28 = OpConstant %uint 28 + %1133 = OpConstantComposite %v4uint %uint_16 %uint_20 %uint_24 %uint_28 + %uint_32 = OpConstant %uint 32 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_11 = OpConstant %uint 11 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %993 = OpConstantComposite %v2uint %uint_248 %uint_248 + %1015 = OpConstantComposite %v2uint %uint_258048 %uint_258048 + %2547 = OpConstantComposite %v2uint %uint_260046848 %uint_260046848 + %1912 = OpConstantComposite %v2uint %uint_5 %uint_5 + %503 = OpConstantComposite %v2uint %uint_7340039 %uint_7340039 + %1933 = OpConstantComposite %v2uint %uint_6 %uint_6 + %78 = OpConstantComposite %v2uint %uint_3072 %uint_3072 + %2878 = OpConstantComposite %v4uint %uint_1431655765 %uint_1431655765 %uint_1431655765 %uint_1431655765 + %2950 = OpConstantComposite %v4uint %uint_1 %uint_1 %uint_1 %uint_1 + %2860 = OpConstantComposite %v4uint %uint_2863311530 %uint_2863311530 %uint_2863311530 %uint_2863311530 + %47 = OpConstantComposite %v4uint %uint_3 %uint_3 %uint_3 %uint_3 + %929 = OpConstantComposite %v4uint %uint_1023 %uint_1023 %uint_1023 %uint_1023 + %425 = OpConstantComposite %v4uint %uint_10 %uint_10 %uint_10 %uint_10 + %965 = OpConstantComposite %v4uint %uint_20 %uint_20 %uint_20 %uint_20 + %695 = OpConstantComposite %v4uint %uint_15 %uint_15 %uint_15 %uint_15 + %529 = OpConstantComposite %v4uint %uint_285212672 %uint_285212672 %uint_285212672 %uint_285212672 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %14903 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20158 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %22412 = OpLoad %uint %20158 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_7 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2587 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %14018 DontFlatten + OpBranchConditional %24679 %21992 %14018 + %21992 = OpLabel + OpBranch %14903 + %14018 = OpLabel + %17344 = OpShiftLeftLogical %v3uint %21387 %2620 + %15489 = OpBitcast %v3int %17344 + %18336 = OpCompositeExtract %int %15489 0 + %9362 = OpIMul %int %18336 %int_4 + %6362 = OpCompositeExtract %int %15489 2 + %14505 = OpBitcast %int %6594 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %15489 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %22412 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %9362 %24535 + %10898 = OpBitcast %uint %8258 + %9077 = OpIAdd %uint %10898 %22411 + %11726 = OpShiftRightLogical %uint %9077 %uint_4 + %6977 = OpShiftRightLogical %uint %22412 %uint_4 + OpSelectionMerge %18964 DontFlatten + OpBranchConditional %17270 %7364 %21373 + %21373 = OpLabel + %9411 = OpBitcast %v3int %21387 + %8918 = OpCompositeExtract %int %9411 0 + %9363 = OpIMul %int %8918 %int_16 + %6363 = OpCompositeExtract %int %9411 2 + %14506 = OpBitcast %int %22409 + %11280 = OpIMul %int %6363 %14506 + %17599 = OpCompositeExtract %int %9411 1 + %22229 = OpIAdd %int %11280 %17599 + %22406 = OpBitcast %int %22408 + %7839 = OpIMul %int %22229 %22406 + %7984 = OpIAdd %int %9363 %7839 + OpBranch %18964 + %7364 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %6361 %21374 + %21374 = OpLabel + %10608 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %10608 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %10608 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_11 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17303 = OpIAdd %int %10934 %17741 + %6375 = OpShiftLeftLogical %int %17303 %uint_4 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15435 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18356 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18356 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12151 + %19165 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19165 %int_2 + %16708 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21587 %int_6 + %15436 = OpIAdd %int %16708 %21580 + %14157 = OpBitwiseAnd %int %16727 %int_63 + %12098 = OpIAdd %int %15436 %14157 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v3int %21387 + %17091 = OpCompositeExtract %int %6573 1 + %9470 = OpShiftRightArithmetic %int %17091 %int_4 + %10056 = OpCompositeExtract %int %6573 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %22409 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %6573 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_10 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12601 = OpBitwiseAnd %int %17091 %int_6 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7048 = OpShiftLeftLogical %int %17227 %uint_10 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17091 %int_3 + %13731 = OpIAdd %int %8725 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19166 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19166 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18357 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18357 %uint_10 + %16729 = OpIAdd %int %10332 %21582 + %19167 = OpBitwiseAnd %int %17091 %int_1 + %21583 = OpShiftLeftLogical %int %19167 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16730 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %6361 %12098 %21374 + OpBranch %18964 + %18964 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %21373 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %18964 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %11720 None + OpBranchConditional %15139 %11064 %11720 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11720 + %11720 = OpLabel + %19545 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %24377 = OpCompositeExtract %uint %19545 2 + %15487 = OpShiftLeftLogical %uint %24377 %uint_3 + %6481 = OpShiftRightLogical %uint %24377 %uint_13 + %17264 = OpCompositeConstruct %v2uint %15487 %6481 + %6430 = OpBitwiseAnd %v2uint %17264 %993 + %20543 = OpShiftLeftLogical %uint %24377 %uint_7 + %24164 = OpShiftRightLogical %uint %24377 %uint_9 + %17283 = OpCompositeConstruct %v2uint %20543 %24164 + %6295 = OpBitwiseAnd %v2uint %17283 %1015 + %14170 = OpBitwiseOr %v2uint %6430 %6295 + %23688 = OpShiftLeftLogical %uint %24377 %uint_12 + %22551 = OpShiftRightLogical %uint %24377 %uint_4 + %17285 = OpCompositeConstruct %v2uint %23688 %22551 + %6257 = OpBitwiseAnd %v2uint %17285 %2547 + %14611 = OpBitwiseOr %v2uint %14170 %6257 + %22361 = OpShiftRightLogical %v2uint %14611 %1912 + %6347 = OpBitwiseAnd %v2uint %22361 %503 + %16454 = OpBitwiseOr %v2uint %14611 %6347 + %22362 = OpShiftRightLogical %v2uint %16454 %1933 + %23271 = OpBitwiseAnd %v2uint %22362 %78 + %14671 = OpBitwiseOr %v2uint %16454 %23271 + %19422 = OpCompositeExtract %uint %19545 3 + %15440 = OpCompositeConstruct %v2uint %19422 %19422 + %25137 = OpVectorShuffle %v4uint %15440 %15440 0 1 0 0 + %11388 = OpBitwiseAnd %v4uint %25137 %2878 + %24266 = OpShiftLeftLogical %v4uint %11388 %2950 + %20653 = OpBitwiseAnd %v4uint %25137 %2860 + %16599 = OpShiftRightLogical %v4uint %20653 %2950 + %24000 = OpBitwiseOr %v4uint %24266 %16599 + %19618 = OpBitwiseAnd %v4uint %24000 %2860 + %18219 = OpShiftRightLogical %v4uint %19618 %2950 + %17265 = OpBitwiseXor %v4uint %24000 %18219 + %16699 = OpCompositeExtract %uint %17265 0 + %14825 = OpNot %uint %16699 + %10815 = OpCompositeConstruct %v4uint %14825 %14825 %14825 %14825 + %24040 = OpShiftRightLogical %v4uint %10815 %77 + %23215 = OpBitwiseAnd %v4uint %24040 %47 + %19127 = OpCompositeExtract %uint %14671 0 + %24694 = OpCompositeConstruct %v4uint %19127 %19127 %19127 %19127 + %24562 = OpIMul %v4uint %23215 %24694 + %25211 = OpCompositeConstruct %v4uint %16699 %16699 %16699 %16699 + %14397 = OpShiftRightLogical %v4uint %25211 %77 + %23216 = OpBitwiseAnd %v4uint %14397 %47 + %19128 = OpCompositeExtract %uint %14671 1 + %6535 = OpCompositeConstruct %v4uint %19128 %19128 %19128 %19128 + %16353 = OpIMul %v4uint %23216 %6535 + %11267 = OpIAdd %v4uint %24562 %16353 + %24766 = OpBitwiseAnd %v4uint %11267 %929 + %9225 = OpUDiv %v4uint %24766 %47 + %17608 = OpShiftLeftLogical %v4uint %9225 %749 + %10961 = OpShiftRightLogical %v4uint %11267 %425 + %13249 = OpBitwiseAnd %v4uint %10961 %929 + %17312 = OpUDiv %v4uint %13249 %47 + %16994 = OpShiftLeftLogical %v4uint %17312 %317 + %6318 = OpBitwiseOr %v4uint %17608 %16994 + %15344 = OpShiftRightLogical %v4uint %11267 %965 + %21790 = OpUDiv %v4uint %15344 %47 + %9340 = OpBitwiseOr %v4uint %6318 %21790 + %7914 = OpVectorShuffle %v4uint %19545 %19545 0 0 0 0 + %6996 = OpShiftRightLogical %v4uint %7914 %269 + %17726 = OpBitwiseAnd %v4uint %6996 %695 + %23883 = OpIMul %v4uint %17726 %529 + %10200 = OpIAdd %v4uint %9340 %23883 + %14167 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11726 + OpStore %14167 %10200 + %12832 = OpCompositeExtract %uint %17344 1 + %23232 = OpIAdd %uint %12832 %uint_1 + %17425 = OpULessThan %bool %23232 %6594 + OpSelectionMerge %7566 DontFlatten + OpBranchConditional %17425 %22828 %7566 + %22828 = OpLabel + %15595 = OpIAdd %uint %11726 %6977 + %10966 = OpShiftRightLogical %uint %16699 %uint_8 + %23788 = OpNot %uint %10966 + %21236 = OpCompositeConstruct %v4uint %23788 %23788 %23788 %23788 + %25009 = OpShiftRightLogical %v4uint %21236 %77 + %14392 = OpBitwiseAnd %v4uint %25009 %47 + %15567 = OpIMul %v4uint %14392 %24694 + %21401 = OpCompositeConstruct %v4uint %10966 %10966 %10966 %10966 + %15366 = OpShiftRightLogical %v4uint %21401 %77 + %15304 = OpBitwiseAnd %v4uint %15366 %47 + %7358 = OpIMul %v4uint %15304 %6535 + %7457 = OpIAdd %v4uint %15567 %7358 + %24767 = OpBitwiseAnd %v4uint %7457 %929 + %9226 = OpUDiv %v4uint %24767 %47 + %17609 = OpShiftLeftLogical %v4uint %9226 %749 + %10962 = OpShiftRightLogical %v4uint %7457 %425 + %13250 = OpBitwiseAnd %v4uint %10962 %929 + %17313 = OpUDiv %v4uint %13250 %47 + %16995 = OpShiftLeftLogical %v4uint %17313 %317 + %6319 = OpBitwiseOr %v4uint %17609 %16995 + %15345 = OpShiftRightLogical %v4uint %7457 %965 + %23975 = OpUDiv %v4uint %15345 %47 + %8611 = OpBitwiseOr %v4uint %6319 %23975 + %10674 = OpShiftRightLogical %v4uint %7914 %1133 + %16338 = OpBitwiseAnd %v4uint %10674 %695 + %23884 = OpIMul %v4uint %16338 %529 + %10201 = OpIAdd %v4uint %8611 %23884 + %15060 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15595 + OpStore %15060 %10201 + %14840 = OpIAdd %uint %12832 %uint_2 + %11787 = OpULessThan %bool %14840 %6594 + OpSelectionMerge %7205 DontFlatten + OpBranchConditional %11787 %20882 %7205 + %20882 = OpLabel + %13198 = OpIMul %uint %uint_2 %6977 + %13581 = OpIAdd %uint %11726 %13198 + %13967 = OpShiftRightLogical %uint %16699 %uint_16 + %23789 = OpNot %uint %13967 + %21237 = OpCompositeConstruct %v4uint %23789 %23789 %23789 %23789 + %25010 = OpShiftRightLogical %v4uint %21237 %77 + %14393 = OpBitwiseAnd %v4uint %25010 %47 + %15568 = OpIMul %v4uint %14393 %24694 + %21402 = OpCompositeConstruct %v4uint %13967 %13967 %13967 %13967 + %15367 = OpShiftRightLogical %v4uint %21402 %77 + %15305 = OpBitwiseAnd %v4uint %15367 %47 + %7359 = OpIMul %v4uint %15305 %6535 + %7458 = OpIAdd %v4uint %15568 %7359 + %24768 = OpBitwiseAnd %v4uint %7458 %929 + %9227 = OpUDiv %v4uint %24768 %47 + %17610 = OpShiftLeftLogical %v4uint %9227 %749 + %10963 = OpShiftRightLogical %v4uint %7458 %425 + %13251 = OpBitwiseAnd %v4uint %10963 %929 + %17314 = OpUDiv %v4uint %13251 %47 + %16996 = OpShiftLeftLogical %v4uint %17314 %317 + %6320 = OpBitwiseOr %v4uint %17610 %16996 + %15346 = OpShiftRightLogical %v4uint %7458 %965 + %21791 = OpUDiv %v4uint %15346 %47 + %9341 = OpBitwiseOr %v4uint %6320 %21791 + %7915 = OpVectorShuffle %v4uint %19545 %19545 1 1 1 1 + %6997 = OpShiftRightLogical %v4uint %7915 %269 + %17727 = OpBitwiseAnd %v4uint %6997 %695 + %23885 = OpIMul %v4uint %17727 %529 + %10202 = OpIAdd %v4uint %9341 %23885 + %15061 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13581 + OpStore %15061 %10202 + %14841 = OpIAdd %uint %12832 %uint_3 + %11788 = OpULessThan %bool %14841 %6594 + OpSelectionMerge %18021 DontFlatten + OpBranchConditional %11788 %20883 %18021 + %20883 = OpLabel + %13199 = OpIMul %uint %uint_3 %6977 + %13582 = OpIAdd %uint %11726 %13199 + %13968 = OpShiftRightLogical %uint %16699 %uint_24 + %23790 = OpNot %uint %13968 + %21238 = OpCompositeConstruct %v4uint %23790 %23790 %23790 %23790 + %25011 = OpShiftRightLogical %v4uint %21238 %77 + %14394 = OpBitwiseAnd %v4uint %25011 %47 + %15569 = OpIMul %v4uint %14394 %24694 + %21403 = OpCompositeConstruct %v4uint %13968 %13968 %13968 %13968 + %15368 = OpShiftRightLogical %v4uint %21403 %77 + %15306 = OpBitwiseAnd %v4uint %15368 %47 + %7360 = OpIMul %v4uint %15306 %6535 + %7459 = OpIAdd %v4uint %15569 %7360 + %24769 = OpBitwiseAnd %v4uint %7459 %929 + %9228 = OpUDiv %v4uint %24769 %47 + %17611 = OpShiftLeftLogical %v4uint %9228 %749 + %10964 = OpShiftRightLogical %v4uint %7459 %425 + %13252 = OpBitwiseAnd %v4uint %10964 %929 + %17315 = OpUDiv %v4uint %13252 %47 + %16997 = OpShiftLeftLogical %v4uint %17315 %317 + %6321 = OpBitwiseOr %v4uint %17611 %16997 + %15347 = OpShiftRightLogical %v4uint %7459 %965 + %23976 = OpUDiv %v4uint %15347 %47 + %8612 = OpBitwiseOr %v4uint %6321 %23976 + %10675 = OpShiftRightLogical %v4uint %7915 %1133 + %16339 = OpBitwiseAnd %v4uint %10675 %695 + %23886 = OpIMul %v4uint %16339 %529 + %10203 = OpIAdd %v4uint %8612 %23886 + %17359 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13582 + OpStore %17359 %10203 + OpBranch %18021 + %18021 = OpLabel + OpBranch %7205 + %7205 = OpLabel + OpBranch %7566 + %7566 = OpLabel + %14517 = OpIAdd %uint %11726 %int_1 + %18181 = OpSelect %uint %17270 %uint_2 %uint_1 + %16762 = OpIAdd %uint %22117 %18181 + %18278 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %16762 + %6578 = OpLoad %v4uint %18278 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20654 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20654 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %7566 %16377 %10584 + OpSelectionMerge %11721 None + OpBranchConditional %15139 %11065 %11721 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11721 + %11721 = OpLabel + %19546 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %24378 = OpCompositeExtract %uint %19546 2 + %15488 = OpShiftLeftLogical %uint %24378 %uint_3 + %6482 = OpShiftRightLogical %uint %24378 %uint_13 + %17266 = OpCompositeConstruct %v2uint %15488 %6482 + %6431 = OpBitwiseAnd %v2uint %17266 %993 + %20544 = OpShiftLeftLogical %uint %24378 %uint_7 + %24165 = OpShiftRightLogical %uint %24378 %uint_9 + %17286 = OpCompositeConstruct %v2uint %20544 %24165 + %6296 = OpBitwiseAnd %v2uint %17286 %1015 + %14171 = OpBitwiseOr %v2uint %6431 %6296 + %23689 = OpShiftLeftLogical %uint %24378 %uint_12 + %22552 = OpShiftRightLogical %uint %24378 %uint_4 + %17287 = OpCompositeConstruct %v2uint %23689 %22552 + %6258 = OpBitwiseAnd %v2uint %17287 %2547 + %14612 = OpBitwiseOr %v2uint %14171 %6258 + %22363 = OpShiftRightLogical %v2uint %14612 %1912 + %6348 = OpBitwiseAnd %v2uint %22363 %503 + %16455 = OpBitwiseOr %v2uint %14612 %6348 + %22364 = OpShiftRightLogical %v2uint %16455 %1933 + %23272 = OpBitwiseAnd %v2uint %22364 %78 + %14672 = OpBitwiseOr %v2uint %16455 %23272 + %19423 = OpCompositeExtract %uint %19546 3 + %15441 = OpCompositeConstruct %v2uint %19423 %19423 + %25138 = OpVectorShuffle %v4uint %15441 %15441 0 1 0 0 + %11389 = OpBitwiseAnd %v4uint %25138 %2878 + %24267 = OpShiftLeftLogical %v4uint %11389 %2950 + %20655 = OpBitwiseAnd %v4uint %25138 %2860 + %16600 = OpShiftRightLogical %v4uint %20655 %2950 + %24001 = OpBitwiseOr %v4uint %24267 %16600 + %19619 = OpBitwiseAnd %v4uint %24001 %2860 + %18220 = OpShiftRightLogical %v4uint %19619 %2950 + %17267 = OpBitwiseXor %v4uint %24001 %18220 + %16700 = OpCompositeExtract %uint %17267 0 + %14826 = OpNot %uint %16700 + %10816 = OpCompositeConstruct %v4uint %14826 %14826 %14826 %14826 + %24041 = OpShiftRightLogical %v4uint %10816 %77 + %23219 = OpBitwiseAnd %v4uint %24041 %47 + %19129 = OpCompositeExtract %uint %14672 0 + %24695 = OpCompositeConstruct %v4uint %19129 %19129 %19129 %19129 + %24563 = OpIMul %v4uint %23219 %24695 + %25212 = OpCompositeConstruct %v4uint %16700 %16700 %16700 %16700 + %14398 = OpShiftRightLogical %v4uint %25212 %77 + %23220 = OpBitwiseAnd %v4uint %14398 %47 + %19130 = OpCompositeExtract %uint %14672 1 + %6536 = OpCompositeConstruct %v4uint %19130 %19130 %19130 %19130 + %16354 = OpIMul %v4uint %23220 %6536 + %11268 = OpIAdd %v4uint %24563 %16354 + %24770 = OpBitwiseAnd %v4uint %11268 %929 + %9229 = OpUDiv %v4uint %24770 %47 + %17612 = OpShiftLeftLogical %v4uint %9229 %749 + %10965 = OpShiftRightLogical %v4uint %11268 %425 + %13253 = OpBitwiseAnd %v4uint %10965 %929 + %17316 = OpUDiv %v4uint %13253 %47 + %16998 = OpShiftLeftLogical %v4uint %17316 %317 + %6322 = OpBitwiseOr %v4uint %17612 %16998 + %15348 = OpShiftRightLogical %v4uint %11268 %965 + %21792 = OpUDiv %v4uint %15348 %47 + %9342 = OpBitwiseOr %v4uint %6322 %21792 + %7917 = OpVectorShuffle %v4uint %19546 %19546 0 0 0 0 + %6998 = OpShiftRightLogical %v4uint %7917 %269 + %17728 = OpBitwiseAnd %v4uint %6998 %695 + %23887 = OpIMul %v4uint %17728 %529 + %10204 = OpIAdd %v4uint %9342 %23887 + %17321 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %14517 + OpStore %17321 %10204 + OpSelectionMerge %7207 DontFlatten + OpBranchConditional %17425 %22829 %7207 + %22829 = OpLabel + %15596 = OpIAdd %uint %14517 %6977 + %10967 = OpShiftRightLogical %uint %16700 %uint_8 + %23791 = OpNot %uint %10967 + %21239 = OpCompositeConstruct %v4uint %23791 %23791 %23791 %23791 + %25012 = OpShiftRightLogical %v4uint %21239 %77 + %14395 = OpBitwiseAnd %v4uint %25012 %47 + %15570 = OpIMul %v4uint %14395 %24695 + %21404 = OpCompositeConstruct %v4uint %10967 %10967 %10967 %10967 + %15369 = OpShiftRightLogical %v4uint %21404 %77 + %15307 = OpBitwiseAnd %v4uint %15369 %47 + %7361 = OpIMul %v4uint %15307 %6536 + %7460 = OpIAdd %v4uint %15570 %7361 + %24771 = OpBitwiseAnd %v4uint %7460 %929 + %9230 = OpUDiv %v4uint %24771 %47 + %17613 = OpShiftLeftLogical %v4uint %9230 %749 + %10968 = OpShiftRightLogical %v4uint %7460 %425 + %13254 = OpBitwiseAnd %v4uint %10968 %929 + %17317 = OpUDiv %v4uint %13254 %47 + %16999 = OpShiftLeftLogical %v4uint %17317 %317 + %6323 = OpBitwiseOr %v4uint %17613 %16999 + %15349 = OpShiftRightLogical %v4uint %7460 %965 + %23977 = OpUDiv %v4uint %15349 %47 + %8613 = OpBitwiseOr %v4uint %6323 %23977 + %10676 = OpShiftRightLogical %v4uint %7917 %1133 + %16340 = OpBitwiseAnd %v4uint %10676 %695 + %23888 = OpIMul %v4uint %16340 %529 + %10205 = OpIAdd %v4uint %8613 %23888 + %15062 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15596 + OpStore %15062 %10205 + %14842 = OpIAdd %uint %12832 %uint_2 + %11789 = OpULessThan %bool %14842 %6594 + OpSelectionMerge %7206 DontFlatten + OpBranchConditional %11789 %20884 %7206 + %20884 = OpLabel + %13200 = OpIMul %uint %uint_2 %6977 + %13583 = OpIAdd %uint %14517 %13200 + %13969 = OpShiftRightLogical %uint %16700 %uint_16 + %23792 = OpNot %uint %13969 + %21240 = OpCompositeConstruct %v4uint %23792 %23792 %23792 %23792 + %25013 = OpShiftRightLogical %v4uint %21240 %77 + %14396 = OpBitwiseAnd %v4uint %25013 %47 + %15571 = OpIMul %v4uint %14396 %24695 + %21405 = OpCompositeConstruct %v4uint %13969 %13969 %13969 %13969 + %15370 = OpShiftRightLogical %v4uint %21405 %77 + %15308 = OpBitwiseAnd %v4uint %15370 %47 + %7362 = OpIMul %v4uint %15308 %6536 + %7461 = OpIAdd %v4uint %15571 %7362 + %24772 = OpBitwiseAnd %v4uint %7461 %929 + %9231 = OpUDiv %v4uint %24772 %47 + %17614 = OpShiftLeftLogical %v4uint %9231 %749 + %10969 = OpShiftRightLogical %v4uint %7461 %425 + %13255 = OpBitwiseAnd %v4uint %10969 %929 + %17318 = OpUDiv %v4uint %13255 %47 + %17000 = OpShiftLeftLogical %v4uint %17318 %317 + %6324 = OpBitwiseOr %v4uint %17614 %17000 + %15350 = OpShiftRightLogical %v4uint %7461 %965 + %21793 = OpUDiv %v4uint %15350 %47 + %9343 = OpBitwiseOr %v4uint %6324 %21793 + %7918 = OpVectorShuffle %v4uint %19546 %19546 1 1 1 1 + %6999 = OpShiftRightLogical %v4uint %7918 %269 + %17729 = OpBitwiseAnd %v4uint %6999 %695 + %23889 = OpIMul %v4uint %17729 %529 + %10206 = OpIAdd %v4uint %9343 %23889 + %15063 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13583 + OpStore %15063 %10206 + %14843 = OpIAdd %uint %12832 %uint_3 + %11790 = OpULessThan %bool %14843 %6594 + OpSelectionMerge %18022 DontFlatten + OpBranchConditional %11790 %20885 %18022 + %20885 = OpLabel + %13201 = OpIMul %uint %uint_3 %6977 + %13584 = OpIAdd %uint %14517 %13201 + %13970 = OpShiftRightLogical %uint %16700 %uint_24 + %23793 = OpNot %uint %13970 + %21241 = OpCompositeConstruct %v4uint %23793 %23793 %23793 %23793 + %25014 = OpShiftRightLogical %v4uint %21241 %77 + %14399 = OpBitwiseAnd %v4uint %25014 %47 + %15572 = OpIMul %v4uint %14399 %24695 + %21406 = OpCompositeConstruct %v4uint %13970 %13970 %13970 %13970 + %15371 = OpShiftRightLogical %v4uint %21406 %77 + %15309 = OpBitwiseAnd %v4uint %15371 %47 + %7363 = OpIMul %v4uint %15309 %6536 + %7462 = OpIAdd %v4uint %15572 %7363 + %24773 = OpBitwiseAnd %v4uint %7462 %929 + %9232 = OpUDiv %v4uint %24773 %47 + %17615 = OpShiftLeftLogical %v4uint %9232 %749 + %10970 = OpShiftRightLogical %v4uint %7462 %425 + %13256 = OpBitwiseAnd %v4uint %10970 %929 + %17319 = OpUDiv %v4uint %13256 %47 + %17001 = OpShiftLeftLogical %v4uint %17319 %317 + %6325 = OpBitwiseOr %v4uint %17615 %17001 + %15351 = OpShiftRightLogical %v4uint %7462 %965 + %23978 = OpUDiv %v4uint %15351 %47 + %8614 = OpBitwiseOr %v4uint %6325 %23978 + %10677 = OpShiftRightLogical %v4uint %7918 %1133 + %16341 = OpBitwiseAnd %v4uint %10677 %695 + %23890 = OpIMul %v4uint %16341 %529 + %10207 = OpIAdd %v4uint %8614 %23890 + %17360 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13584 + OpStore %17360 %10207 + OpBranch %18022 + %18022 = OpLabel + OpBranch %7206 + %7206 = OpLabel + OpBranch %7207 + %7207 = OpLabel + OpBranch %14903 + %14903 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_dxt3_rgba8_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x0000627D, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, + 0x0004002B, 0x0000000B, 0x0000012F, 0x000000F8, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0004002B, 0x0000000B, 0x00000B47, 0x0003F000, + 0x0004002B, 0x0000000B, 0x00000A2E, 0x0000000C, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000B, 0x000007FF, 0x0F800000, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x000000E9, 0x00700007, 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, + 0x0004002B, 0x0000000B, 0x00000AC1, 0x00000C00, 0x0004002B, 0x0000000B, 0x00000A09, 0x55555555, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A08, 0xAAAAAAAA, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0007002C, 0x00000017, 0x0000004D, 0x00000A0A, 0x00000A10, 0x00000A16, 0x00000A1C, 0x0004002B, + 0x0000000B, 0x00000A44, 0x000003FF, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, + 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, + 0x0000000B, 0x00000A46, 0x00000014, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, + 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, + 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, + 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, + 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, + 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, + 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, + 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, + 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, + 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x000A001E, + 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, + 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, + 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, + 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A1B, + 0x00000A0D, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0006002C, + 0x00000014, 0x00000A3C, 0x00000A10, 0x00000A10, 0x00000A0A, 0x0003001D, 0x000007DC, 0x00000017, + 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, 0x0004003B, + 0x00000A32, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, + 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A33, 0x00000002, + 0x000007B5, 0x0004003B, 0x00000A33, 0x0000140E, 0x00000002, 0x0007002C, 0x00000017, 0x0000010D, + 0x00000A0A, 0x00000A16, 0x00000A22, 0x00000A2E, 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, + 0x0004002B, 0x0000000B, 0x000006A9, 0x11000000, 0x0004002B, 0x0000000B, 0x00000A52, 0x00000018, + 0x0004002B, 0x0000000B, 0x00000A5E, 0x0000001C, 0x0007002C, 0x00000017, 0x0000046D, 0x00000A3A, + 0x00000A46, 0x00000A52, 0x00000A5E, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0006002C, + 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0004002B, 0x0000000B, 0x00000A2B, + 0x0000000B, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, + 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, + 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, + 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000011, 0x000003E1, + 0x0000012F, 0x0000012F, 0x0005002C, 0x00000011, 0x000003F7, 0x00000B47, 0x00000B47, 0x0005002C, + 0x00000011, 0x000009F3, 0x000007FF, 0x000007FF, 0x0005002C, 0x00000011, 0x00000778, 0x00000A19, + 0x00000A19, 0x0005002C, 0x00000011, 0x000001F7, 0x000000E9, 0x000000E9, 0x0005002C, 0x00000011, + 0x0000078D, 0x00000A1C, 0x00000A1C, 0x0005002C, 0x00000011, 0x0000004E, 0x00000AC1, 0x00000AC1, + 0x0007002C, 0x00000017, 0x00000B3E, 0x00000A09, 0x00000A09, 0x00000A09, 0x00000A09, 0x0007002C, + 0x00000017, 0x00000B86, 0x00000A0D, 0x00000A0D, 0x00000A0D, 0x00000A0D, 0x0007002C, 0x00000017, + 0x00000B2C, 0x00000A08, 0x00000A08, 0x00000A08, 0x00000A08, 0x0007002C, 0x00000017, 0x0000002F, + 0x00000A13, 0x00000A13, 0x00000A13, 0x00000A13, 0x0007002C, 0x00000017, 0x000003A1, 0x00000A44, + 0x00000A44, 0x00000A44, 0x00000A44, 0x0007002C, 0x00000017, 0x000001A9, 0x00000A28, 0x00000A28, + 0x00000A28, 0x00000A28, 0x0007002C, 0x00000017, 0x000003C5, 0x00000A46, 0x00000A46, 0x00000A46, + 0x00000A46, 0x0007002C, 0x00000017, 0x000002B7, 0x00000A37, 0x00000A37, 0x00000A37, 0x00000A37, + 0x0007002C, 0x00000017, 0x00000211, 0x000006A9, 0x000006A9, 0x000006A9, 0x000006A9, 0x00050036, + 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00003A37, + 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, + 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, + 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, + 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, + 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, + 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, + 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, + 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, + 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, + 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, + 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, + 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004EBE, 0x00000CE9, 0x00000A1D, 0x0004003D, + 0x0000000B, 0x0000578C, 0x00004EBE, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A20, + 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, + 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A1B, 0x0007004F, 0x00000011, 0x000042F0, + 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, + 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, + 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000036C2, 0x00000002, 0x000400FA, + 0x00006067, 0x000055E8, 0x000036C2, 0x000200F8, 0x000055E8, 0x000200F9, 0x00003A37, 0x000200F8, + 0x000036C2, 0x000500C4, 0x00000014, 0x000043C0, 0x0000538B, 0x00000A3C, 0x0004007C, 0x00000016, + 0x00003C81, 0x000043C0, 0x00050051, 0x0000000C, 0x000047A0, 0x00003C81, 0x00000000, 0x00050084, + 0x0000000C, 0x00002492, 0x000047A0, 0x00000A17, 0x00050051, 0x0000000C, 0x000018DA, 0x00003C81, + 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x000019C2, 0x00050084, 0x0000000C, 0x00002C0F, + 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00003C81, 0x00000001, 0x00050080, + 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x0000578C, + 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, + 0x00002492, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, + 0x00002375, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x00002DCE, 0x00002375, 0x00000A16, + 0x000500C2, 0x0000000B, 0x00001B41, 0x0000578C, 0x00000A16, 0x000300F7, 0x00004A14, 0x00000002, + 0x000400FA, 0x00004376, 0x00001CC4, 0x0000537D, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, + 0x000024C3, 0x0000538B, 0x00050051, 0x0000000C, 0x000022D6, 0x000024C3, 0x00000000, 0x00050084, + 0x0000000C, 0x00002493, 0x000022D6, 0x00000A3B, 0x00050051, 0x0000000C, 0x000018DB, 0x000024C3, + 0x00000002, 0x0004007C, 0x0000000C, 0x000038AA, 0x00005789, 0x00050084, 0x0000000C, 0x00002C10, + 0x000018DB, 0x000038AA, 0x00050051, 0x0000000C, 0x000044BF, 0x000024C3, 0x00000001, 0x00050080, + 0x0000000C, 0x000056D5, 0x00002C10, 0x000044BF, 0x0004007C, 0x0000000C, 0x00005786, 0x00005788, + 0x00050084, 0x0000000C, 0x00001E9F, 0x000056D5, 0x00005786, 0x00050080, 0x0000000C, 0x00001F30, + 0x00002493, 0x00001E9F, 0x000200F9, 0x00004A14, 0x000200F8, 0x00001CC4, 0x000300F7, 0x00001E0B, + 0x00000002, 0x000400FA, 0x00004384, 0x000018D9, 0x0000537E, 0x000200F8, 0x0000537E, 0x0004007C, + 0x00000012, 0x00002970, 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000000, + 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, + 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, + 0x0000000B, 0x00005B4D, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, + 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003F5E, + 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A2B, 0x000500C7, + 0x0000000C, 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x00002747, + 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, + 0x00004397, 0x00002AB6, 0x0000454D, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A16, + 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, + 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00004A8E, 0x00002F76, 0x000500C7, + 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4B, + 0x00003397, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544A, 0x000047B4, 0x00000A17, 0x00050080, 0x0000000C, 0x00004157, 0x00004D30, 0x0000544A, + 0x000500C7, 0x0000000C, 0x00005022, 0x00004157, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, + 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, + 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x00004158, 0x00002416, + 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADD, 0x00004157, 0x00000388, 0x000500C4, 0x0000000C, + 0x0000544B, 0x00004ADD, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x00004158, 0x0000544B, + 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, + 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, + 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544C, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, + 0x00003C4C, 0x00004144, 0x0000544C, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004157, 0x00000AC8, + 0x00050080, 0x0000000C, 0x00002F42, 0x00003C4C, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, + 0x000018D9, 0x0004007C, 0x00000016, 0x000019AD, 0x0000538B, 0x00050051, 0x0000000C, 0x000042C3, + 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FE, 0x000042C3, 0x00000A17, 0x00050051, + 0x0000000C, 0x00002748, 0x000019AD, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, + 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, + 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005321, 0x0000405D, 0x000018AB, 0x00050080, + 0x0000000C, 0x00003B27, 0x000024FE, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, + 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, + 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, 0x000019AD, 0x00000000, 0x000500C3, + 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, + 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A28, 0x000500C7, 0x0000000C, + 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, + 0x000042C3, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, + 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454E, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, + 0x00000A28, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, + 0x00002215, 0x000042C3, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405D, + 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, + 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, + 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000034BD, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544D, 0x00004ADE, 0x00000A0E, 0x00050080, 0x0000000C, + 0x00003C4D, 0x00005A0C, 0x0000544D, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, + 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, + 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, + 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544E, 0x000047B5, 0x00000A28, 0x00050080, 0x0000000C, + 0x00004159, 0x0000285C, 0x0000544E, 0x000500C7, 0x0000000C, 0x00004ADF, 0x000042C3, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544F, 0x00004ADF, 0x00000A17, 0x00050080, 0x0000000C, 0x0000415A, + 0x00004159, 0x0000544F, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4D, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x0000415A, + 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, + 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4D, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, + 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, + 0x0000000C, 0x00005AB2, 0x0000415A, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, + 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005EA0, 0x0000415A, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, 0x00005EA0, + 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, + 0x000018D9, 0x00002F42, 0x0000537E, 0x000200F9, 0x00004A14, 0x000200F8, 0x00004A14, 0x000700F5, + 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, 0x00001F30, 0x0000537D, 0x0004007C, 0x0000000C, + 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, + 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, + 0x00060041, 0x00000294, 0x00004315, 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, + 0x00001CAA, 0x00004315, 0x000500AA, 0x00000009, 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, + 0x00000009, 0x00005376, 0x000061E2, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, + 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, + 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, + 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, + 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, + 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, + 0x00000017, 0x00005879, 0x00001CAA, 0x00004A14, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, + 0x00004CB6, 0x000061E2, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, + 0x000300F7, 0x00002DC8, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x00002DC8, 0x000200F8, + 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, + 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, + 0x000200F9, 0x00002DC8, 0x000200F8, 0x00002DC8, 0x000700F5, 0x00000017, 0x00004C59, 0x00005879, + 0x00003463, 0x000029E8, 0x00002B38, 0x00050051, 0x0000000B, 0x00005F39, 0x00004C59, 0x00000002, + 0x000500C4, 0x0000000B, 0x00003C7F, 0x00005F39, 0x00000A13, 0x000500C2, 0x0000000B, 0x00001951, + 0x00005F39, 0x00000A31, 0x00050050, 0x00000011, 0x00004370, 0x00003C7F, 0x00001951, 0x000500C7, + 0x00000011, 0x0000191E, 0x00004370, 0x000003E1, 0x000500C4, 0x0000000B, 0x0000503F, 0x00005F39, + 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005E64, 0x00005F39, 0x00000A25, 0x00050050, 0x00000011, + 0x00004383, 0x0000503F, 0x00005E64, 0x000500C7, 0x00000011, 0x00001897, 0x00004383, 0x000003F7, + 0x000500C5, 0x00000011, 0x0000375A, 0x0000191E, 0x00001897, 0x000500C4, 0x0000000B, 0x00005C88, + 0x00005F39, 0x00000A2E, 0x000500C2, 0x0000000B, 0x00005817, 0x00005F39, 0x00000A16, 0x00050050, + 0x00000011, 0x00004385, 0x00005C88, 0x00005817, 0x000500C7, 0x00000011, 0x00001871, 0x00004385, + 0x000009F3, 0x000500C5, 0x00000011, 0x00003913, 0x0000375A, 0x00001871, 0x000500C2, 0x00000011, + 0x00005759, 0x00003913, 0x00000778, 0x000500C7, 0x00000011, 0x000018CB, 0x00005759, 0x000001F7, + 0x000500C5, 0x00000011, 0x00004046, 0x00003913, 0x000018CB, 0x000500C2, 0x00000011, 0x0000575A, + 0x00004046, 0x0000078D, 0x000500C7, 0x00000011, 0x00005AE7, 0x0000575A, 0x0000004E, 0x000500C5, + 0x00000011, 0x0000394F, 0x00004046, 0x00005AE7, 0x00050051, 0x0000000B, 0x00004BDE, 0x00004C59, + 0x00000003, 0x00050050, 0x00000011, 0x00003C50, 0x00004BDE, 0x00004BDE, 0x0009004F, 0x00000017, + 0x00006231, 0x00003C50, 0x00003C50, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x000500C7, + 0x00000017, 0x00002C7C, 0x00006231, 0x00000B3E, 0x000500C4, 0x00000017, 0x00005ECA, 0x00002C7C, + 0x00000B86, 0x000500C7, 0x00000017, 0x000050AD, 0x00006231, 0x00000B2C, 0x000500C2, 0x00000017, + 0x000040D7, 0x000050AD, 0x00000B86, 0x000500C5, 0x00000017, 0x00005DC0, 0x00005ECA, 0x000040D7, + 0x000500C7, 0x00000017, 0x00004CA2, 0x00005DC0, 0x00000B2C, 0x000500C2, 0x00000017, 0x0000472B, + 0x00004CA2, 0x00000B86, 0x000500C6, 0x00000017, 0x00004371, 0x00005DC0, 0x0000472B, 0x00050051, + 0x0000000B, 0x0000413B, 0x00004371, 0x00000000, 0x000400C8, 0x0000000B, 0x000039E9, 0x0000413B, + 0x00070050, 0x00000017, 0x00002A3F, 0x000039E9, 0x000039E9, 0x000039E9, 0x000039E9, 0x000500C2, + 0x00000017, 0x00005DE8, 0x00002A3F, 0x0000004D, 0x000500C7, 0x00000017, 0x00005AAF, 0x00005DE8, + 0x0000002F, 0x00050051, 0x0000000B, 0x00004AB7, 0x0000394F, 0x00000000, 0x00070050, 0x00000017, + 0x00006076, 0x00004AB7, 0x00004AB7, 0x00004AB7, 0x00004AB7, 0x00050084, 0x00000017, 0x00005FF2, + 0x00005AAF, 0x00006076, 0x00070050, 0x00000017, 0x0000627B, 0x0000413B, 0x0000413B, 0x0000413B, + 0x0000413B, 0x000500C2, 0x00000017, 0x0000383D, 0x0000627B, 0x0000004D, 0x000500C7, 0x00000017, + 0x00005AB0, 0x0000383D, 0x0000002F, 0x00050051, 0x0000000B, 0x00004AB8, 0x0000394F, 0x00000001, + 0x00070050, 0x00000017, 0x00001987, 0x00004AB8, 0x00004AB8, 0x00004AB8, 0x00004AB8, 0x00050084, + 0x00000017, 0x00003FE1, 0x00005AB0, 0x00001987, 0x00050080, 0x00000017, 0x00002C03, 0x00005FF2, + 0x00003FE1, 0x000500C7, 0x00000017, 0x000060BE, 0x00002C03, 0x000003A1, 0x00050086, 0x00000017, + 0x00002409, 0x000060BE, 0x0000002F, 0x000500C4, 0x00000017, 0x000044C8, 0x00002409, 0x000002ED, + 0x000500C2, 0x00000017, 0x00002AD1, 0x00002C03, 0x000001A9, 0x000500C7, 0x00000017, 0x000033C1, + 0x00002AD1, 0x000003A1, 0x00050086, 0x00000017, 0x000043A0, 0x000033C1, 0x0000002F, 0x000500C4, + 0x00000017, 0x00004262, 0x000043A0, 0x0000013D, 0x000500C5, 0x00000017, 0x000018AE, 0x000044C8, + 0x00004262, 0x000500C2, 0x00000017, 0x00003BF0, 0x00002C03, 0x000003C5, 0x00050086, 0x00000017, + 0x0000551E, 0x00003BF0, 0x0000002F, 0x000500C5, 0x00000017, 0x0000247C, 0x000018AE, 0x0000551E, + 0x0009004F, 0x00000017, 0x00001EEA, 0x00004C59, 0x00004C59, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x000500C2, 0x00000017, 0x00001B54, 0x00001EEA, 0x0000010D, 0x000500C7, 0x00000017, + 0x0000453E, 0x00001B54, 0x000002B7, 0x00050084, 0x00000017, 0x00005D4B, 0x0000453E, 0x00000211, + 0x00050080, 0x00000017, 0x000027D8, 0x0000247C, 0x00005D4B, 0x00060041, 0x00000294, 0x00003757, + 0x0000140E, 0x00000A0B, 0x00002DCE, 0x0003003E, 0x00003757, 0x000027D8, 0x00050051, 0x0000000B, + 0x00003220, 0x000043C0, 0x00000001, 0x00050080, 0x0000000B, 0x00005AC0, 0x00003220, 0x00000A0D, + 0x000500B0, 0x00000009, 0x00004411, 0x00005AC0, 0x000019C2, 0x000300F7, 0x00001D8E, 0x00000002, + 0x000400FA, 0x00004411, 0x0000592C, 0x00001D8E, 0x000200F8, 0x0000592C, 0x00050080, 0x0000000B, + 0x00003CEB, 0x00002DCE, 0x00001B41, 0x000500C2, 0x0000000B, 0x00002AD6, 0x0000413B, 0x00000A22, + 0x000400C8, 0x0000000B, 0x00005CEC, 0x00002AD6, 0x00070050, 0x00000017, 0x000052F4, 0x00005CEC, + 0x00005CEC, 0x00005CEC, 0x00005CEC, 0x000500C2, 0x00000017, 0x000061B1, 0x000052F4, 0x0000004D, + 0x000500C7, 0x00000017, 0x00003838, 0x000061B1, 0x0000002F, 0x00050084, 0x00000017, 0x00003CCF, + 0x00003838, 0x00006076, 0x00070050, 0x00000017, 0x00005399, 0x00002AD6, 0x00002AD6, 0x00002AD6, + 0x00002AD6, 0x000500C2, 0x00000017, 0x00003C06, 0x00005399, 0x0000004D, 0x000500C7, 0x00000017, + 0x00003BC8, 0x00003C06, 0x0000002F, 0x00050084, 0x00000017, 0x00001CBE, 0x00003BC8, 0x00001987, + 0x00050080, 0x00000017, 0x00001D21, 0x00003CCF, 0x00001CBE, 0x000500C7, 0x00000017, 0x000060BF, + 0x00001D21, 0x000003A1, 0x00050086, 0x00000017, 0x0000240A, 0x000060BF, 0x0000002F, 0x000500C4, + 0x00000017, 0x000044C9, 0x0000240A, 0x000002ED, 0x000500C2, 0x00000017, 0x00002AD2, 0x00001D21, + 0x000001A9, 0x000500C7, 0x00000017, 0x000033C2, 0x00002AD2, 0x000003A1, 0x00050086, 0x00000017, + 0x000043A1, 0x000033C2, 0x0000002F, 0x000500C4, 0x00000017, 0x00004263, 0x000043A1, 0x0000013D, + 0x000500C5, 0x00000017, 0x000018AF, 0x000044C9, 0x00004263, 0x000500C2, 0x00000017, 0x00003BF1, + 0x00001D21, 0x000003C5, 0x00050086, 0x00000017, 0x00005DA7, 0x00003BF1, 0x0000002F, 0x000500C5, + 0x00000017, 0x000021A3, 0x000018AF, 0x00005DA7, 0x000500C2, 0x00000017, 0x000029B2, 0x00001EEA, + 0x0000046D, 0x000500C7, 0x00000017, 0x00003FD2, 0x000029B2, 0x000002B7, 0x00050084, 0x00000017, + 0x00005D4C, 0x00003FD2, 0x00000211, 0x00050080, 0x00000017, 0x000027D9, 0x000021A3, 0x00005D4C, + 0x00060041, 0x00000294, 0x00003AD4, 0x0000140E, 0x00000A0B, 0x00003CEB, 0x0003003E, 0x00003AD4, + 0x000027D9, 0x00050080, 0x0000000B, 0x000039F8, 0x00003220, 0x00000A10, 0x000500B0, 0x00000009, + 0x00002E0B, 0x000039F8, 0x000019C2, 0x000300F7, 0x00001C25, 0x00000002, 0x000400FA, 0x00002E0B, + 0x00005192, 0x00001C25, 0x000200F8, 0x00005192, 0x00050084, 0x0000000B, 0x0000338E, 0x00000A10, + 0x00001B41, 0x00050080, 0x0000000B, 0x0000350D, 0x00002DCE, 0x0000338E, 0x000500C2, 0x0000000B, + 0x0000368F, 0x0000413B, 0x00000A3A, 0x000400C8, 0x0000000B, 0x00005CED, 0x0000368F, 0x00070050, + 0x00000017, 0x000052F5, 0x00005CED, 0x00005CED, 0x00005CED, 0x00005CED, 0x000500C2, 0x00000017, + 0x000061B2, 0x000052F5, 0x0000004D, 0x000500C7, 0x00000017, 0x00003839, 0x000061B2, 0x0000002F, + 0x00050084, 0x00000017, 0x00003CD0, 0x00003839, 0x00006076, 0x00070050, 0x00000017, 0x0000539A, + 0x0000368F, 0x0000368F, 0x0000368F, 0x0000368F, 0x000500C2, 0x00000017, 0x00003C07, 0x0000539A, + 0x0000004D, 0x000500C7, 0x00000017, 0x00003BC9, 0x00003C07, 0x0000002F, 0x00050084, 0x00000017, + 0x00001CBF, 0x00003BC9, 0x00001987, 0x00050080, 0x00000017, 0x00001D22, 0x00003CD0, 0x00001CBF, + 0x000500C7, 0x00000017, 0x000060C0, 0x00001D22, 0x000003A1, 0x00050086, 0x00000017, 0x0000240B, + 0x000060C0, 0x0000002F, 0x000500C4, 0x00000017, 0x000044CA, 0x0000240B, 0x000002ED, 0x000500C2, + 0x00000017, 0x00002AD3, 0x00001D22, 0x000001A9, 0x000500C7, 0x00000017, 0x000033C3, 0x00002AD3, + 0x000003A1, 0x00050086, 0x00000017, 0x000043A2, 0x000033C3, 0x0000002F, 0x000500C4, 0x00000017, + 0x00004264, 0x000043A2, 0x0000013D, 0x000500C5, 0x00000017, 0x000018B0, 0x000044CA, 0x00004264, + 0x000500C2, 0x00000017, 0x00003BF2, 0x00001D22, 0x000003C5, 0x00050086, 0x00000017, 0x0000551F, + 0x00003BF2, 0x0000002F, 0x000500C5, 0x00000017, 0x0000247D, 0x000018B0, 0x0000551F, 0x0009004F, + 0x00000017, 0x00001EEB, 0x00004C59, 0x00004C59, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x000500C2, 0x00000017, 0x00001B55, 0x00001EEB, 0x0000010D, 0x000500C7, 0x00000017, 0x0000453F, + 0x00001B55, 0x000002B7, 0x00050084, 0x00000017, 0x00005D4D, 0x0000453F, 0x00000211, 0x00050080, + 0x00000017, 0x000027DA, 0x0000247D, 0x00005D4D, 0x00060041, 0x00000294, 0x00003AD5, 0x0000140E, + 0x00000A0B, 0x0000350D, 0x0003003E, 0x00003AD5, 0x000027DA, 0x00050080, 0x0000000B, 0x000039F9, + 0x00003220, 0x00000A13, 0x000500B0, 0x00000009, 0x00002E0C, 0x000039F9, 0x000019C2, 0x000300F7, + 0x00004665, 0x00000002, 0x000400FA, 0x00002E0C, 0x00005193, 0x00004665, 0x000200F8, 0x00005193, + 0x00050084, 0x0000000B, 0x0000338F, 0x00000A13, 0x00001B41, 0x00050080, 0x0000000B, 0x0000350E, + 0x00002DCE, 0x0000338F, 0x000500C2, 0x0000000B, 0x00003690, 0x0000413B, 0x00000A52, 0x000400C8, + 0x0000000B, 0x00005CEE, 0x00003690, 0x00070050, 0x00000017, 0x000052F6, 0x00005CEE, 0x00005CEE, + 0x00005CEE, 0x00005CEE, 0x000500C2, 0x00000017, 0x000061B3, 0x000052F6, 0x0000004D, 0x000500C7, + 0x00000017, 0x0000383A, 0x000061B3, 0x0000002F, 0x00050084, 0x00000017, 0x00003CD1, 0x0000383A, + 0x00006076, 0x00070050, 0x00000017, 0x0000539B, 0x00003690, 0x00003690, 0x00003690, 0x00003690, + 0x000500C2, 0x00000017, 0x00003C08, 0x0000539B, 0x0000004D, 0x000500C7, 0x00000017, 0x00003BCA, + 0x00003C08, 0x0000002F, 0x00050084, 0x00000017, 0x00001CC0, 0x00003BCA, 0x00001987, 0x00050080, + 0x00000017, 0x00001D23, 0x00003CD1, 0x00001CC0, 0x000500C7, 0x00000017, 0x000060C1, 0x00001D23, + 0x000003A1, 0x00050086, 0x00000017, 0x0000240C, 0x000060C1, 0x0000002F, 0x000500C4, 0x00000017, + 0x000044CB, 0x0000240C, 0x000002ED, 0x000500C2, 0x00000017, 0x00002AD4, 0x00001D23, 0x000001A9, + 0x000500C7, 0x00000017, 0x000033C4, 0x00002AD4, 0x000003A1, 0x00050086, 0x00000017, 0x000043A3, + 0x000033C4, 0x0000002F, 0x000500C4, 0x00000017, 0x00004265, 0x000043A3, 0x0000013D, 0x000500C5, + 0x00000017, 0x000018B1, 0x000044CB, 0x00004265, 0x000500C2, 0x00000017, 0x00003BF3, 0x00001D23, + 0x000003C5, 0x00050086, 0x00000017, 0x00005DA8, 0x00003BF3, 0x0000002F, 0x000500C5, 0x00000017, + 0x000021A4, 0x000018B1, 0x00005DA8, 0x000500C2, 0x00000017, 0x000029B3, 0x00001EEB, 0x0000046D, + 0x000500C7, 0x00000017, 0x00003FD3, 0x000029B3, 0x000002B7, 0x00050084, 0x00000017, 0x00005D4E, + 0x00003FD3, 0x00000211, 0x00050080, 0x00000017, 0x000027DB, 0x000021A4, 0x00005D4E, 0x00060041, + 0x00000294, 0x000043CF, 0x0000140E, 0x00000A0B, 0x0000350E, 0x0003003E, 0x000043CF, 0x000027DB, + 0x000200F9, 0x00004665, 0x000200F8, 0x00004665, 0x000200F9, 0x00001C25, 0x000200F8, 0x00001C25, + 0x000200F9, 0x00001D8E, 0x000200F8, 0x00001D8E, 0x00050080, 0x0000000B, 0x000038B5, 0x00002DCE, + 0x00000A0E, 0x000600A9, 0x0000000B, 0x00004705, 0x00004376, 0x00000A10, 0x00000A0D, 0x00050080, + 0x0000000B, 0x0000417A, 0x00005665, 0x00004705, 0x00060041, 0x00000294, 0x00004766, 0x0000107A, + 0x00000A0B, 0x0000417A, 0x0004003D, 0x00000017, 0x000019B2, 0x00004766, 0x000300F7, 0x00003A1A, + 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, + 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AE, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448E, 0x000050AE, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, + 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, + 0x00001D8E, 0x00003FF9, 0x00002958, 0x000300F7, 0x00002DC9, 0x00000000, 0x000400FA, 0x00003B23, + 0x00002B39, 0x00002DC9, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, + 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, + 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002DC9, 0x000200F8, 0x00002DC9, 0x000700F5, + 0x00000017, 0x00004C5A, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x00050051, 0x0000000B, + 0x00005F3A, 0x00004C5A, 0x00000002, 0x000500C4, 0x0000000B, 0x00003C80, 0x00005F3A, 0x00000A13, + 0x000500C2, 0x0000000B, 0x00001952, 0x00005F3A, 0x00000A31, 0x00050050, 0x00000011, 0x00004372, + 0x00003C80, 0x00001952, 0x000500C7, 0x00000011, 0x0000191F, 0x00004372, 0x000003E1, 0x000500C4, + 0x0000000B, 0x00005040, 0x00005F3A, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005E65, 0x00005F3A, + 0x00000A25, 0x00050050, 0x00000011, 0x00004386, 0x00005040, 0x00005E65, 0x000500C7, 0x00000011, + 0x00001898, 0x00004386, 0x000003F7, 0x000500C5, 0x00000011, 0x0000375B, 0x0000191F, 0x00001898, + 0x000500C4, 0x0000000B, 0x00005C89, 0x00005F3A, 0x00000A2E, 0x000500C2, 0x0000000B, 0x00005818, + 0x00005F3A, 0x00000A16, 0x00050050, 0x00000011, 0x00004387, 0x00005C89, 0x00005818, 0x000500C7, + 0x00000011, 0x00001872, 0x00004387, 0x000009F3, 0x000500C5, 0x00000011, 0x00003914, 0x0000375B, + 0x00001872, 0x000500C2, 0x00000011, 0x0000575B, 0x00003914, 0x00000778, 0x000500C7, 0x00000011, + 0x000018CC, 0x0000575B, 0x000001F7, 0x000500C5, 0x00000011, 0x00004047, 0x00003914, 0x000018CC, + 0x000500C2, 0x00000011, 0x0000575C, 0x00004047, 0x0000078D, 0x000500C7, 0x00000011, 0x00005AE8, + 0x0000575C, 0x0000004E, 0x000500C5, 0x00000011, 0x00003950, 0x00004047, 0x00005AE8, 0x00050051, + 0x0000000B, 0x00004BDF, 0x00004C5A, 0x00000003, 0x00050050, 0x00000011, 0x00003C51, 0x00004BDF, + 0x00004BDF, 0x0009004F, 0x00000017, 0x00006232, 0x00003C51, 0x00003C51, 0x00000000, 0x00000001, + 0x00000000, 0x00000000, 0x000500C7, 0x00000017, 0x00002C7D, 0x00006232, 0x00000B3E, 0x000500C4, + 0x00000017, 0x00005ECB, 0x00002C7D, 0x00000B86, 0x000500C7, 0x00000017, 0x000050AF, 0x00006232, + 0x00000B2C, 0x000500C2, 0x00000017, 0x000040D8, 0x000050AF, 0x00000B86, 0x000500C5, 0x00000017, + 0x00005DC1, 0x00005ECB, 0x000040D8, 0x000500C7, 0x00000017, 0x00004CA3, 0x00005DC1, 0x00000B2C, + 0x000500C2, 0x00000017, 0x0000472C, 0x00004CA3, 0x00000B86, 0x000500C6, 0x00000017, 0x00004373, + 0x00005DC1, 0x0000472C, 0x00050051, 0x0000000B, 0x0000413C, 0x00004373, 0x00000000, 0x000400C8, + 0x0000000B, 0x000039EA, 0x0000413C, 0x00070050, 0x00000017, 0x00002A40, 0x000039EA, 0x000039EA, + 0x000039EA, 0x000039EA, 0x000500C2, 0x00000017, 0x00005DE9, 0x00002A40, 0x0000004D, 0x000500C7, + 0x00000017, 0x00005AB3, 0x00005DE9, 0x0000002F, 0x00050051, 0x0000000B, 0x00004AB9, 0x00003950, + 0x00000000, 0x00070050, 0x00000017, 0x00006077, 0x00004AB9, 0x00004AB9, 0x00004AB9, 0x00004AB9, + 0x00050084, 0x00000017, 0x00005FF3, 0x00005AB3, 0x00006077, 0x00070050, 0x00000017, 0x0000627C, + 0x0000413C, 0x0000413C, 0x0000413C, 0x0000413C, 0x000500C2, 0x00000017, 0x0000383E, 0x0000627C, + 0x0000004D, 0x000500C7, 0x00000017, 0x00005AB4, 0x0000383E, 0x0000002F, 0x00050051, 0x0000000B, + 0x00004ABA, 0x00003950, 0x00000001, 0x00070050, 0x00000017, 0x00001988, 0x00004ABA, 0x00004ABA, + 0x00004ABA, 0x00004ABA, 0x00050084, 0x00000017, 0x00003FE2, 0x00005AB4, 0x00001988, 0x00050080, + 0x00000017, 0x00002C04, 0x00005FF3, 0x00003FE2, 0x000500C7, 0x00000017, 0x000060C2, 0x00002C04, + 0x000003A1, 0x00050086, 0x00000017, 0x0000240D, 0x000060C2, 0x0000002F, 0x000500C4, 0x00000017, + 0x000044CC, 0x0000240D, 0x000002ED, 0x000500C2, 0x00000017, 0x00002AD5, 0x00002C04, 0x000001A9, + 0x000500C7, 0x00000017, 0x000033C5, 0x00002AD5, 0x000003A1, 0x00050086, 0x00000017, 0x000043A4, + 0x000033C5, 0x0000002F, 0x000500C4, 0x00000017, 0x00004266, 0x000043A4, 0x0000013D, 0x000500C5, + 0x00000017, 0x000018B2, 0x000044CC, 0x00004266, 0x000500C2, 0x00000017, 0x00003BF4, 0x00002C04, + 0x000003C5, 0x00050086, 0x00000017, 0x00005520, 0x00003BF4, 0x0000002F, 0x000500C5, 0x00000017, + 0x0000247E, 0x000018B2, 0x00005520, 0x0009004F, 0x00000017, 0x00001EED, 0x00004C5A, 0x00004C5A, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000500C2, 0x00000017, 0x00001B56, 0x00001EED, + 0x0000010D, 0x000500C7, 0x00000017, 0x00004540, 0x00001B56, 0x000002B7, 0x00050084, 0x00000017, + 0x00005D4F, 0x00004540, 0x00000211, 0x00050080, 0x00000017, 0x000027DC, 0x0000247E, 0x00005D4F, + 0x00060041, 0x00000294, 0x000043A9, 0x0000140E, 0x00000A0B, 0x000038B5, 0x0003003E, 0x000043A9, + 0x000027DC, 0x000300F7, 0x00001C27, 0x00000002, 0x000400FA, 0x00004411, 0x0000592D, 0x00001C27, + 0x000200F8, 0x0000592D, 0x00050080, 0x0000000B, 0x00003CEC, 0x000038B5, 0x00001B41, 0x000500C2, + 0x0000000B, 0x00002AD7, 0x0000413C, 0x00000A22, 0x000400C8, 0x0000000B, 0x00005CEF, 0x00002AD7, + 0x00070050, 0x00000017, 0x000052F7, 0x00005CEF, 0x00005CEF, 0x00005CEF, 0x00005CEF, 0x000500C2, + 0x00000017, 0x000061B4, 0x000052F7, 0x0000004D, 0x000500C7, 0x00000017, 0x0000383B, 0x000061B4, + 0x0000002F, 0x00050084, 0x00000017, 0x00003CD2, 0x0000383B, 0x00006077, 0x00070050, 0x00000017, + 0x0000539C, 0x00002AD7, 0x00002AD7, 0x00002AD7, 0x00002AD7, 0x000500C2, 0x00000017, 0x00003C09, + 0x0000539C, 0x0000004D, 0x000500C7, 0x00000017, 0x00003BCB, 0x00003C09, 0x0000002F, 0x00050084, + 0x00000017, 0x00001CC1, 0x00003BCB, 0x00001988, 0x00050080, 0x00000017, 0x00001D24, 0x00003CD2, + 0x00001CC1, 0x000500C7, 0x00000017, 0x000060C3, 0x00001D24, 0x000003A1, 0x00050086, 0x00000017, + 0x0000240E, 0x000060C3, 0x0000002F, 0x000500C4, 0x00000017, 0x000044CD, 0x0000240E, 0x000002ED, + 0x000500C2, 0x00000017, 0x00002AD8, 0x00001D24, 0x000001A9, 0x000500C7, 0x00000017, 0x000033C6, + 0x00002AD8, 0x000003A1, 0x00050086, 0x00000017, 0x000043A5, 0x000033C6, 0x0000002F, 0x000500C4, + 0x00000017, 0x00004267, 0x000043A5, 0x0000013D, 0x000500C5, 0x00000017, 0x000018B3, 0x000044CD, + 0x00004267, 0x000500C2, 0x00000017, 0x00003BF5, 0x00001D24, 0x000003C5, 0x00050086, 0x00000017, + 0x00005DA9, 0x00003BF5, 0x0000002F, 0x000500C5, 0x00000017, 0x000021A5, 0x000018B3, 0x00005DA9, + 0x000500C2, 0x00000017, 0x000029B4, 0x00001EED, 0x0000046D, 0x000500C7, 0x00000017, 0x00003FD4, + 0x000029B4, 0x000002B7, 0x00050084, 0x00000017, 0x00005D50, 0x00003FD4, 0x00000211, 0x00050080, + 0x00000017, 0x000027DD, 0x000021A5, 0x00005D50, 0x00060041, 0x00000294, 0x00003AD6, 0x0000140E, + 0x00000A0B, 0x00003CEC, 0x0003003E, 0x00003AD6, 0x000027DD, 0x00050080, 0x0000000B, 0x000039FA, + 0x00003220, 0x00000A10, 0x000500B0, 0x00000009, 0x00002E0D, 0x000039FA, 0x000019C2, 0x000300F7, + 0x00001C26, 0x00000002, 0x000400FA, 0x00002E0D, 0x00005194, 0x00001C26, 0x000200F8, 0x00005194, + 0x00050084, 0x0000000B, 0x00003390, 0x00000A10, 0x00001B41, 0x00050080, 0x0000000B, 0x0000350F, + 0x000038B5, 0x00003390, 0x000500C2, 0x0000000B, 0x00003691, 0x0000413C, 0x00000A3A, 0x000400C8, + 0x0000000B, 0x00005CF0, 0x00003691, 0x00070050, 0x00000017, 0x000052F8, 0x00005CF0, 0x00005CF0, + 0x00005CF0, 0x00005CF0, 0x000500C2, 0x00000017, 0x000061B5, 0x000052F8, 0x0000004D, 0x000500C7, + 0x00000017, 0x0000383C, 0x000061B5, 0x0000002F, 0x00050084, 0x00000017, 0x00003CD3, 0x0000383C, + 0x00006077, 0x00070050, 0x00000017, 0x0000539D, 0x00003691, 0x00003691, 0x00003691, 0x00003691, + 0x000500C2, 0x00000017, 0x00003C0A, 0x0000539D, 0x0000004D, 0x000500C7, 0x00000017, 0x00003BCC, + 0x00003C0A, 0x0000002F, 0x00050084, 0x00000017, 0x00001CC2, 0x00003BCC, 0x00001988, 0x00050080, + 0x00000017, 0x00001D25, 0x00003CD3, 0x00001CC2, 0x000500C7, 0x00000017, 0x000060C4, 0x00001D25, + 0x000003A1, 0x00050086, 0x00000017, 0x0000240F, 0x000060C4, 0x0000002F, 0x000500C4, 0x00000017, + 0x000044CE, 0x0000240F, 0x000002ED, 0x000500C2, 0x00000017, 0x00002AD9, 0x00001D25, 0x000001A9, + 0x000500C7, 0x00000017, 0x000033C7, 0x00002AD9, 0x000003A1, 0x00050086, 0x00000017, 0x000043A6, + 0x000033C7, 0x0000002F, 0x000500C4, 0x00000017, 0x00004268, 0x000043A6, 0x0000013D, 0x000500C5, + 0x00000017, 0x000018B4, 0x000044CE, 0x00004268, 0x000500C2, 0x00000017, 0x00003BF6, 0x00001D25, + 0x000003C5, 0x00050086, 0x00000017, 0x00005521, 0x00003BF6, 0x0000002F, 0x000500C5, 0x00000017, + 0x0000247F, 0x000018B4, 0x00005521, 0x0009004F, 0x00000017, 0x00001EEE, 0x00004C5A, 0x00004C5A, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x000500C2, 0x00000017, 0x00001B57, 0x00001EEE, + 0x0000010D, 0x000500C7, 0x00000017, 0x00004541, 0x00001B57, 0x000002B7, 0x00050084, 0x00000017, + 0x00005D51, 0x00004541, 0x00000211, 0x00050080, 0x00000017, 0x000027DE, 0x0000247F, 0x00005D51, + 0x00060041, 0x00000294, 0x00003AD7, 0x0000140E, 0x00000A0B, 0x0000350F, 0x0003003E, 0x00003AD7, + 0x000027DE, 0x00050080, 0x0000000B, 0x000039FB, 0x00003220, 0x00000A13, 0x000500B0, 0x00000009, + 0x00002E0E, 0x000039FB, 0x000019C2, 0x000300F7, 0x00004666, 0x00000002, 0x000400FA, 0x00002E0E, + 0x00005195, 0x00004666, 0x000200F8, 0x00005195, 0x00050084, 0x0000000B, 0x00003391, 0x00000A13, + 0x00001B41, 0x00050080, 0x0000000B, 0x00003510, 0x000038B5, 0x00003391, 0x000500C2, 0x0000000B, + 0x00003692, 0x0000413C, 0x00000A52, 0x000400C8, 0x0000000B, 0x00005CF1, 0x00003692, 0x00070050, + 0x00000017, 0x000052F9, 0x00005CF1, 0x00005CF1, 0x00005CF1, 0x00005CF1, 0x000500C2, 0x00000017, + 0x000061B6, 0x000052F9, 0x0000004D, 0x000500C7, 0x00000017, 0x0000383F, 0x000061B6, 0x0000002F, + 0x00050084, 0x00000017, 0x00003CD4, 0x0000383F, 0x00006077, 0x00070050, 0x00000017, 0x0000539E, + 0x00003692, 0x00003692, 0x00003692, 0x00003692, 0x000500C2, 0x00000017, 0x00003C0B, 0x0000539E, + 0x0000004D, 0x000500C7, 0x00000017, 0x00003BCD, 0x00003C0B, 0x0000002F, 0x00050084, 0x00000017, + 0x00001CC3, 0x00003BCD, 0x00001988, 0x00050080, 0x00000017, 0x00001D26, 0x00003CD4, 0x00001CC3, + 0x000500C7, 0x00000017, 0x000060C5, 0x00001D26, 0x000003A1, 0x00050086, 0x00000017, 0x00002410, + 0x000060C5, 0x0000002F, 0x000500C4, 0x00000017, 0x000044CF, 0x00002410, 0x000002ED, 0x000500C2, + 0x00000017, 0x00002ADA, 0x00001D26, 0x000001A9, 0x000500C7, 0x00000017, 0x000033C8, 0x00002ADA, + 0x000003A1, 0x00050086, 0x00000017, 0x000043A7, 0x000033C8, 0x0000002F, 0x000500C4, 0x00000017, + 0x00004269, 0x000043A7, 0x0000013D, 0x000500C5, 0x00000017, 0x000018B5, 0x000044CF, 0x00004269, + 0x000500C2, 0x00000017, 0x00003BF7, 0x00001D26, 0x000003C5, 0x00050086, 0x00000017, 0x00005DAA, + 0x00003BF7, 0x0000002F, 0x000500C5, 0x00000017, 0x000021A6, 0x000018B5, 0x00005DAA, 0x000500C2, + 0x00000017, 0x000029B5, 0x00001EEE, 0x0000046D, 0x000500C7, 0x00000017, 0x00003FD5, 0x000029B5, + 0x000002B7, 0x00050084, 0x00000017, 0x00005D52, 0x00003FD5, 0x00000211, 0x00050080, 0x00000017, + 0x000027DF, 0x000021A6, 0x00005D52, 0x00060041, 0x00000294, 0x000043D0, 0x0000140E, 0x00000A0B, + 0x00003510, 0x0003003E, 0x000043D0, 0x000027DF, 0x000200F9, 0x00004666, 0x000200F8, 0x00004666, + 0x000200F9, 0x00001C26, 0x000200F8, 0x00001C26, 0x000200F9, 0x00001C27, 0x000200F8, 0x00001C27, + 0x000200F9, 0x00003A37, 0x000200F8, 0x00003A37, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_dxt3a_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_dxt3a_cs.h new file mode 100644 index 0000000..4d7e062 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_dxt3a_cs.h @@ -0,0 +1,702 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %uint_15 = OpConstant %uint 15 + %uint_255 = OpConstant %uint 255 + %uint_4 = OpConstant %uint 4 + %uint_4080 = OpConstant %uint 4080 + %uint_8 = OpConstant %uint 8 + %uint_65280 = OpConstant %uint 65280 + %uint_12 = OpConstant %uint 12 + %uint_61440 = OpConstant %uint 61440 + %uint_16 = OpConstant %uint 16 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2596 = OpConstantComposite %v3uint %uint_2 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 + %2620 = OpConstantComposite %v3uint %uint_2 %uint_2 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform + %uint_32 = OpConstant %uint 32 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_9 = OpConstant %uint 9 + %uint_10 = OpConstant %uint 10 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %695 = OpConstantComposite %v4uint %uint_15 %uint_15 %uint_15 %uint_15 + %1611 = OpConstantComposite %v4uint %uint_255 %uint_255 %uint_255 %uint_255 + %101 = OpConstantComposite %v4uint %uint_4 %uint_4 %uint_4 %uint_4 + %402 = OpConstantComposite %v4uint %uint_4080 %uint_4080 %uint_4080 %uint_4080 + %2135 = OpConstantComposite %v4uint %uint_65280 %uint_65280 %uint_65280 %uint_65280 + %533 = OpConstantComposite %v4uint %uint_12 %uint_12 %uint_12 %uint_12 + %2534 = OpConstantComposite %v4uint %uint_61440 %uint_61440 %uint_61440 %uint_61440 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %14903 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20158 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %22412 = OpLoad %uint %20158 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_7 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2596 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %14018 DontFlatten + OpBranchConditional %24679 %21992 %14018 + %21992 = OpLabel + OpBranch %14903 + %14018 = OpLabel + %17344 = OpShiftLeftLogical %v3uint %21387 %2620 + %14520 = OpBitcast %v3int %17344 + %8905 = OpCompositeExtract %int %14520 0 + %6813 = OpCompositeExtract %int %14520 2 + %21501 = OpBitcast %int %6594 + %11279 = OpIMul %int %6813 %21501 + %17598 = OpCompositeExtract %int %14520 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %22412 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %8905 %24535 + %10898 = OpBitcast %uint %8258 + %9077 = OpIAdd %uint %10898 %22411 + %11726 = OpShiftRightLogical %uint %9077 %uint_4 + %6977 = OpShiftRightLogical %uint %22412 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20009 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %21373 %6361 + %21373 = OpLabel + %10608 = OpBitcast %v3int %21387 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_9 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_9 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_9 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17091 = OpCompositeExtract %int %6573 0 + %9470 = OpShiftRightArithmetic %int %17091 %int_5 + %10056 = OpCompositeExtract %int %6573 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_10 + %10934 = OpBitwiseAnd %int %17091 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_3 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17091 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %21373 %12098 %6361 + OpBranch %24387 + %20009 = OpLabel + %24447 = OpBitcast %v3int %21387 + %8918 = OpCompositeExtract %int %24447 0 + %9362 = OpIMul %int %8918 %int_8 + %6362 = OpCompositeExtract %int %24447 2 + %14505 = OpBitcast %int %22409 + %11280 = OpIMul %int %6362 %14505 + %17599 = OpCompositeExtract %int %24447 1 + %22229 = OpIAdd %int %11280 %17599 + %22406 = OpBitcast %int %22408 + %7839 = OpIMul %int %22229 %22406 + %7984 = OpIAdd %int %9362 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20009 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %13392 None + OpBranchConditional %15139 %11064 %13392 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %13392 + %13392 = OpLabel + %22100 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %11876 = OpSelect %uint %17270 %uint_2 %uint_1 + %11339 = OpIAdd %uint %22117 %11876 + %18278 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %11339 + %6578 = OpLoad %v4uint %18278 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %13392 %16377 %10584 + OpSelectionMerge %11720 None + OpBranchConditional %15139 %11065 %11720 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11720 + %11720 = OpLabel + %17360 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %23054 = OpCompositeExtract %uint %22100 0 + %11086 = OpCompositeExtract %uint %22100 2 + %7641 = OpCompositeExtract %uint %17360 0 + %10075 = OpCompositeExtract %uint %17360 2 + %16752 = OpCompositeConstruct %v4uint %23054 %11086 %7641 %10075 + %8141 = OpBitwiseAnd %v4uint %16752 %695 + %16912 = OpBitwiseAnd %v4uint %16752 %1611 + %24932 = OpShiftLeftLogical %v4uint %16912 %101 + %17083 = OpBitwiseOr %v4uint %8141 %24932 + %20866 = OpBitwiseAnd %v4uint %16752 %402 + %23319 = OpShiftLeftLogical %v4uint %20866 %317 + %17084 = OpBitwiseOr %v4uint %17083 %23319 + %20867 = OpBitwiseAnd %v4uint %16752 %2135 + %23320 = OpShiftLeftLogical %v4uint %20867 %533 + %17085 = OpBitwiseOr %v4uint %17084 %23320 + %20868 = OpBitwiseAnd %v4uint %16752 %2534 + %20773 = OpShiftLeftLogical %v4uint %20868 %749 + %18648 = OpBitwiseOr %v4uint %17085 %20773 + %20974 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11726 + OpStore %20974 %18648 + %12832 = OpCompositeExtract %uint %17344 1 + %23232 = OpIAdd %uint %12832 %int_1 + %17425 = OpULessThan %bool %23232 %6594 + OpSelectionMerge %7206 DontFlatten + OpBranchConditional %17425 %22828 %7206 + %22828 = OpLabel + %15576 = OpIAdd %uint %11726 %6977 + %13400 = OpShiftRightLogical %v4uint %16752 %749 + %11432 = OpBitwiseAnd %v4uint %13400 %695 + %18755 = OpBitwiseAnd %v4uint %13400 %1611 + %24933 = OpShiftLeftLogical %v4uint %18755 %101 + %17086 = OpBitwiseOr %v4uint %11432 %24933 + %20869 = OpBitwiseAnd %v4uint %13400 %402 + %23321 = OpShiftLeftLogical %v4uint %20869 %317 + %17087 = OpBitwiseOr %v4uint %17086 %23321 + %20870 = OpBitwiseAnd %v4uint %13400 %2135 + %23322 = OpShiftLeftLogical %v4uint %20870 %533 + %17088 = OpBitwiseOr %v4uint %17087 %23322 + %20871 = OpBitwiseAnd %v4uint %13400 %2534 + %20774 = OpShiftLeftLogical %v4uint %20871 %749 + %18649 = OpBitwiseOr %v4uint %17088 %20774 + %21867 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15576 + OpStore %21867 %18649 + %14840 = OpIAdd %uint %12832 %int_2 + %11787 = OpULessThan %bool %14840 %6594 + OpSelectionMerge %7205 DontFlatten + OpBranchConditional %11787 %20681 %7205 + %20681 = OpLabel + %13812 = OpIAdd %uint %15576 %6977 + %10288 = OpCompositeExtract %uint %22100 1 + %10052 = OpCompositeExtract %uint %22100 3 + %7642 = OpCompositeExtract %uint %17360 1 + %10076 = OpCompositeExtract %uint %17360 3 + %16753 = OpCompositeConstruct %v4uint %10288 %10052 %7642 %10076 + %8142 = OpBitwiseAnd %v4uint %16753 %695 + %16913 = OpBitwiseAnd %v4uint %16753 %1611 + %24934 = OpShiftLeftLogical %v4uint %16913 %101 + %17089 = OpBitwiseOr %v4uint %8142 %24934 + %20872 = OpBitwiseAnd %v4uint %16753 %402 + %23323 = OpShiftLeftLogical %v4uint %20872 %317 + %17092 = OpBitwiseOr %v4uint %17089 %23323 + %20873 = OpBitwiseAnd %v4uint %16753 %2135 + %23324 = OpShiftLeftLogical %v4uint %20873 %533 + %17093 = OpBitwiseOr %v4uint %17092 %23324 + %20874 = OpBitwiseAnd %v4uint %16753 %2534 + %20775 = OpShiftLeftLogical %v4uint %20874 %749 + %18650 = OpBitwiseOr %v4uint %17093 %20775 + %21868 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13812 + OpStore %21868 %18650 + %14841 = OpIAdd %uint %12832 %int_3 + %11788 = OpULessThan %bool %14841 %6594 + OpSelectionMerge %18021 DontFlatten + OpBranchConditional %11788 %22829 %18021 + %22829 = OpLabel + %15577 = OpIAdd %uint %13812 %6977 + %13401 = OpShiftRightLogical %v4uint %16753 %749 + %11433 = OpBitwiseAnd %v4uint %13401 %695 + %18756 = OpBitwiseAnd %v4uint %13401 %1611 + %24935 = OpShiftLeftLogical %v4uint %18756 %101 + %17094 = OpBitwiseOr %v4uint %11433 %24935 + %20875 = OpBitwiseAnd %v4uint %13401 %402 + %23325 = OpShiftLeftLogical %v4uint %20875 %317 + %17095 = OpBitwiseOr %v4uint %17094 %23325 + %20876 = OpBitwiseAnd %v4uint %13401 %2135 + %23326 = OpShiftLeftLogical %v4uint %20876 %533 + %17096 = OpBitwiseOr %v4uint %17095 %23326 + %20877 = OpBitwiseAnd %v4uint %13401 %2534 + %20776 = OpShiftLeftLogical %v4uint %20877 %749 + %18651 = OpBitwiseOr %v4uint %17096 %20776 + %24166 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15577 + OpStore %24166 %18651 + OpBranch %18021 + %18021 = OpLabel + OpBranch %7205 + %7205 = OpLabel + OpBranch %7206 + %7206 = OpLabel + OpBranch %14903 + %14903 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_dxt3a_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, + 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, 0x0004002B, 0x0000000B, 0x00000144, 0x000000FF, + 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000B, 0x00000ACE, 0x00000FF0, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x00000A87, 0x0000FF00, + 0x0004002B, 0x0000000B, 0x00000A2E, 0x0000000C, 0x0004002B, 0x0000000B, 0x000000D0, 0x0000F000, + 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, + 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, + 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, + 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x00040020, 0x00000291, + 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, + 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A24, 0x00000A10, 0x00000A0A, 0x00000A0A, + 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0006002C, 0x00000014, 0x00000A3C, 0x00000A10, + 0x00000A10, 0x00000A0A, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, + 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, + 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, + 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, + 0x0000140E, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0006002C, 0x00000014, + 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, + 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, + 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, + 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, + 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, + 0x0007002C, 0x00000017, 0x000002B7, 0x00000A37, 0x00000A37, 0x00000A37, 0x00000A37, 0x0007002C, + 0x00000017, 0x0000064B, 0x00000144, 0x00000144, 0x00000144, 0x00000144, 0x0007002C, 0x00000017, + 0x00000065, 0x00000A16, 0x00000A16, 0x00000A16, 0x00000A16, 0x0007002C, 0x00000017, 0x00000192, + 0x00000ACE, 0x00000ACE, 0x00000ACE, 0x00000ACE, 0x0007002C, 0x00000017, 0x00000857, 0x00000A87, + 0x00000A87, 0x00000A87, 0x00000A87, 0x0007002C, 0x00000017, 0x00000215, 0x00000A2E, 0x00000A2E, + 0x00000A2E, 0x00000A2E, 0x0007002C, 0x00000017, 0x000009E6, 0x000000D0, 0x000000D0, 0x000000D0, + 0x000000D0, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, + 0x000300F7, 0x00003A37, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, + 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, + 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, 0x000500AB, 0x00000009, + 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, 0x00003526, 0x00000A10, + 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001EB0, + 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, 0x00000A13, 0x00050041, + 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, + 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, + 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, + 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, + 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, + 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004EBE, 0x00000CE9, + 0x00000A1D, 0x0004003D, 0x0000000B, 0x0000578C, 0x00004EBE, 0x00050041, 0x00000288, 0x00004E6E, + 0x00000CE9, 0x00000A20, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, + 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A24, 0x0007004F, + 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, + 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, + 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000036C2, + 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000036C2, 0x000200F8, 0x000055E8, 0x000200F9, + 0x00003A37, 0x000200F8, 0x000036C2, 0x000500C4, 0x00000014, 0x000043C0, 0x0000538B, 0x00000A3C, + 0x0004007C, 0x00000016, 0x000038B8, 0x000043C0, 0x00050051, 0x0000000C, 0x000022C9, 0x000038B8, + 0x00000000, 0x00050051, 0x0000000C, 0x00001A9D, 0x000038B8, 0x00000002, 0x0004007C, 0x0000000C, + 0x000053FD, 0x000019C2, 0x00050084, 0x0000000C, 0x00002C0F, 0x00001A9D, 0x000053FD, 0x00050051, + 0x0000000C, 0x000044BE, 0x000038B8, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, + 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x0000578C, 0x00050084, 0x0000000C, 0x00005FD7, + 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x000022C9, 0x00005FD7, 0x0004007C, + 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00002375, 0x00002A92, 0x0000578B, + 0x000500C2, 0x0000000B, 0x00002DCE, 0x00002375, 0x00000A16, 0x000500C2, 0x0000000B, 0x00001B41, + 0x0000578C, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, 0x00005768, + 0x00004E29, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, 0x00004384, + 0x0000537D, 0x000018D9, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, 0x00002970, 0x0000538B, + 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FD, + 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000002, 0x000500C3, + 0x0000000C, 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005789, + 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005321, + 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, 0x00005321, 0x000500C2, + 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, + 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, + 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, + 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, + 0x00000A25, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, + 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, + 0x000500C7, 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, + 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, + 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A25, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, + 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, + 0x000035A3, 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, + 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, + 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, + 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, + 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, + 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, + 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, + 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, + 0x0000000C, 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, + 0x00000A25, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, + 0x00004ADE, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, + 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, + 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, + 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, + 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, + 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, + 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, + 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, + 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, + 0x000054ED, 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, + 0x00000012, 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, 0x000042C3, 0x000019AD, 0x00000000, + 0x000500C3, 0x0000000C, 0x000024FE, 0x000042C3, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002748, + 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, 0x000500C2, + 0x0000000B, 0x00005B4E, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, + 0x00050084, 0x0000000C, 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, + 0x000024FE, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A28, 0x000500C7, + 0x0000000C, 0x00002AB6, 0x000042C3, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002748, + 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, + 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A13, + 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, + 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, + 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, + 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, + 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, + 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, 0x000500C4, + 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, + 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, + 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, + 0x000500C7, 0x0000000C, 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, + 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C3, 0x00000A14, 0x00050080, + 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, + 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, + 0x00050080, 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, + 0x00001E0B, 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, 0x0000537D, 0x00002F42, 0x000018D9, + 0x000200F9, 0x00005F43, 0x000200F8, 0x00004E29, 0x0004007C, 0x00000016, 0x00005F7F, 0x0000538B, + 0x00050051, 0x0000000C, 0x000022D6, 0x00005F7F, 0x00000000, 0x00050084, 0x0000000C, 0x00002492, + 0x000022D6, 0x00000A23, 0x00050051, 0x0000000C, 0x000018DA, 0x00005F7F, 0x00000002, 0x0004007C, + 0x0000000C, 0x000038A9, 0x00005789, 0x00050084, 0x0000000C, 0x00002C10, 0x000018DA, 0x000038A9, + 0x00050051, 0x0000000C, 0x000044BF, 0x00005F7F, 0x00000001, 0x00050080, 0x0000000C, 0x000056D5, + 0x00002C10, 0x000044BF, 0x0004007C, 0x0000000C, 0x00005786, 0x00005788, 0x00050084, 0x0000000C, + 0x00001E9F, 0x000056D5, 0x00005786, 0x00050080, 0x0000000C, 0x00001F30, 0x00002492, 0x00001E9F, + 0x000200F9, 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, + 0x00001E0B, 0x00001F30, 0x00004E29, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, + 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, + 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, 0x00004315, + 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004315, 0x000500AA, + 0x00000009, 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x000061E2, + 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, + 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, + 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, + 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, + 0x00005F43, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000061E2, 0x00000A13, + 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x00003450, 0x00000000, + 0x000400FA, 0x00003B23, 0x00002B38, 0x00003450, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, + 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, + 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x00003450, 0x000200F8, + 0x00003450, 0x000700F5, 0x00000017, 0x00005654, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, + 0x000600A9, 0x0000000B, 0x00002E64, 0x00004376, 0x00000A10, 0x00000A0D, 0x00050080, 0x0000000B, + 0x00002C4B, 0x00005665, 0x00002E64, 0x00060041, 0x00000294, 0x00004766, 0x0000107A, 0x00000A0B, + 0x00002C4B, 0x0004003D, 0x00000017, 0x000019B2, 0x00004766, 0x000300F7, 0x00003A1A, 0x00000000, + 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, + 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, + 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, + 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x00003450, + 0x00003FF9, 0x00002958, 0x000300F7, 0x00002DC8, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, + 0x00002DC8, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, + 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, + 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002DC8, 0x000200F8, 0x00002DC8, 0x000700F5, 0x00000017, + 0x000043D0, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x00050051, 0x0000000B, 0x00005A0E, + 0x00005654, 0x00000000, 0x00050051, 0x0000000B, 0x00002B4E, 0x00005654, 0x00000002, 0x00050051, + 0x0000000B, 0x00001DD9, 0x000043D0, 0x00000000, 0x00050051, 0x0000000B, 0x0000275B, 0x000043D0, + 0x00000002, 0x00070050, 0x00000017, 0x00004170, 0x00005A0E, 0x00002B4E, 0x00001DD9, 0x0000275B, + 0x000500C7, 0x00000017, 0x00001FCD, 0x00004170, 0x000002B7, 0x000500C7, 0x00000017, 0x00004210, + 0x00004170, 0x0000064B, 0x000500C4, 0x00000017, 0x00006164, 0x00004210, 0x00000065, 0x000500C5, + 0x00000017, 0x000042BB, 0x00001FCD, 0x00006164, 0x000500C7, 0x00000017, 0x00005182, 0x00004170, + 0x00000192, 0x000500C4, 0x00000017, 0x00005B17, 0x00005182, 0x0000013D, 0x000500C5, 0x00000017, + 0x000042BC, 0x000042BB, 0x00005B17, 0x000500C7, 0x00000017, 0x00005183, 0x00004170, 0x00000857, + 0x000500C4, 0x00000017, 0x00005B18, 0x00005183, 0x00000215, 0x000500C5, 0x00000017, 0x000042BD, + 0x000042BC, 0x00005B18, 0x000500C7, 0x00000017, 0x00005184, 0x00004170, 0x000009E6, 0x000500C4, + 0x00000017, 0x00005125, 0x00005184, 0x000002ED, 0x000500C5, 0x00000017, 0x000048D8, 0x000042BD, + 0x00005125, 0x00060041, 0x00000294, 0x000051EE, 0x0000140E, 0x00000A0B, 0x00002DCE, 0x0003003E, + 0x000051EE, 0x000048D8, 0x00050051, 0x0000000B, 0x00003220, 0x000043C0, 0x00000001, 0x00050080, + 0x0000000B, 0x00005AC0, 0x00003220, 0x00000A0E, 0x000500B0, 0x00000009, 0x00004411, 0x00005AC0, + 0x000019C2, 0x000300F7, 0x00001C26, 0x00000002, 0x000400FA, 0x00004411, 0x0000592C, 0x00001C26, + 0x000200F8, 0x0000592C, 0x00050080, 0x0000000B, 0x00003CD8, 0x00002DCE, 0x00001B41, 0x000500C2, + 0x00000017, 0x00003458, 0x00004170, 0x000002ED, 0x000500C7, 0x00000017, 0x00002CA8, 0x00003458, + 0x000002B7, 0x000500C7, 0x00000017, 0x00004943, 0x00003458, 0x0000064B, 0x000500C4, 0x00000017, + 0x00006165, 0x00004943, 0x00000065, 0x000500C5, 0x00000017, 0x000042BE, 0x00002CA8, 0x00006165, + 0x000500C7, 0x00000017, 0x00005185, 0x00003458, 0x00000192, 0x000500C4, 0x00000017, 0x00005B19, + 0x00005185, 0x0000013D, 0x000500C5, 0x00000017, 0x000042BF, 0x000042BE, 0x00005B19, 0x000500C7, + 0x00000017, 0x00005186, 0x00003458, 0x00000857, 0x000500C4, 0x00000017, 0x00005B1A, 0x00005186, + 0x00000215, 0x000500C5, 0x00000017, 0x000042C0, 0x000042BF, 0x00005B1A, 0x000500C7, 0x00000017, + 0x00005187, 0x00003458, 0x000009E6, 0x000500C4, 0x00000017, 0x00005126, 0x00005187, 0x000002ED, + 0x000500C5, 0x00000017, 0x000048D9, 0x000042C0, 0x00005126, 0x00060041, 0x00000294, 0x0000556B, + 0x0000140E, 0x00000A0B, 0x00003CD8, 0x0003003E, 0x0000556B, 0x000048D9, 0x00050080, 0x0000000B, + 0x000039F8, 0x00003220, 0x00000A11, 0x000500B0, 0x00000009, 0x00002E0B, 0x000039F8, 0x000019C2, + 0x000300F7, 0x00001C25, 0x00000002, 0x000400FA, 0x00002E0B, 0x000050C9, 0x00001C25, 0x000200F8, + 0x000050C9, 0x00050080, 0x0000000B, 0x000035F4, 0x00003CD8, 0x00001B41, 0x00050051, 0x0000000B, + 0x00002830, 0x00005654, 0x00000001, 0x00050051, 0x0000000B, 0x00002744, 0x00005654, 0x00000003, + 0x00050051, 0x0000000B, 0x00001DDA, 0x000043D0, 0x00000001, 0x00050051, 0x0000000B, 0x0000275C, + 0x000043D0, 0x00000003, 0x00070050, 0x00000017, 0x00004171, 0x00002830, 0x00002744, 0x00001DDA, + 0x0000275C, 0x000500C7, 0x00000017, 0x00001FCE, 0x00004171, 0x000002B7, 0x000500C7, 0x00000017, + 0x00004211, 0x00004171, 0x0000064B, 0x000500C4, 0x00000017, 0x00006166, 0x00004211, 0x00000065, + 0x000500C5, 0x00000017, 0x000042C1, 0x00001FCE, 0x00006166, 0x000500C7, 0x00000017, 0x00005188, + 0x00004171, 0x00000192, 0x000500C4, 0x00000017, 0x00005B1B, 0x00005188, 0x0000013D, 0x000500C5, + 0x00000017, 0x000042C4, 0x000042C1, 0x00005B1B, 0x000500C7, 0x00000017, 0x00005189, 0x00004171, + 0x00000857, 0x000500C4, 0x00000017, 0x00005B1C, 0x00005189, 0x00000215, 0x000500C5, 0x00000017, + 0x000042C5, 0x000042C4, 0x00005B1C, 0x000500C7, 0x00000017, 0x0000518A, 0x00004171, 0x000009E6, + 0x000500C4, 0x00000017, 0x00005127, 0x0000518A, 0x000002ED, 0x000500C5, 0x00000017, 0x000048DA, + 0x000042C5, 0x00005127, 0x00060041, 0x00000294, 0x0000556C, 0x0000140E, 0x00000A0B, 0x000035F4, + 0x0003003E, 0x0000556C, 0x000048DA, 0x00050080, 0x0000000B, 0x000039F9, 0x00003220, 0x00000A14, + 0x000500B0, 0x00000009, 0x00002E0C, 0x000039F9, 0x000019C2, 0x000300F7, 0x00004665, 0x00000002, + 0x000400FA, 0x00002E0C, 0x0000592D, 0x00004665, 0x000200F8, 0x0000592D, 0x00050080, 0x0000000B, + 0x00003CD9, 0x000035F4, 0x00001B41, 0x000500C2, 0x00000017, 0x00003459, 0x00004171, 0x000002ED, + 0x000500C7, 0x00000017, 0x00002CA9, 0x00003459, 0x000002B7, 0x000500C7, 0x00000017, 0x00004944, + 0x00003459, 0x0000064B, 0x000500C4, 0x00000017, 0x00006167, 0x00004944, 0x00000065, 0x000500C5, + 0x00000017, 0x000042C6, 0x00002CA9, 0x00006167, 0x000500C7, 0x00000017, 0x0000518B, 0x00003459, + 0x00000192, 0x000500C4, 0x00000017, 0x00005B1D, 0x0000518B, 0x0000013D, 0x000500C5, 0x00000017, + 0x000042C7, 0x000042C6, 0x00005B1D, 0x000500C7, 0x00000017, 0x0000518C, 0x00003459, 0x00000857, + 0x000500C4, 0x00000017, 0x00005B1E, 0x0000518C, 0x00000215, 0x000500C5, 0x00000017, 0x000042C8, + 0x000042C7, 0x00005B1E, 0x000500C7, 0x00000017, 0x0000518D, 0x00003459, 0x000009E6, 0x000500C4, + 0x00000017, 0x00005128, 0x0000518D, 0x000002ED, 0x000500C5, 0x00000017, 0x000048DB, 0x000042C8, + 0x00005128, 0x00060041, 0x00000294, 0x00005E66, 0x0000140E, 0x00000A0B, 0x00003CD9, 0x0003003E, + 0x00005E66, 0x000048DB, 0x000200F9, 0x00004665, 0x000200F8, 0x00004665, 0x000200F9, 0x00001C25, + 0x000200F8, 0x00001C25, 0x000200F9, 0x00001C26, 0x000200F8, 0x00001C26, 0x000200F9, 0x00003A37, + 0x000200F8, 0x00003A37, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_dxt3aas1111_argb4_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_dxt3aas1111_argb4_cs.h new file mode 100644 index 0000000..4cd8af8 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_dxt3aas1111_argb4_cs.h @@ -0,0 +1,1119 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_3 = OpConstant %uint 3 + %uint_11 = OpConstant %uint 11 + %287 = OpConstantComposite %v4uint %uint_3 %uint_11 %uint_3 %uint_11 + %uint_1 = OpConstant %uint 1 + %uint_4 = OpConstant %uint 4 + %uint_7 = OpConstant %uint 7 + %uint_15 = OpConstant %uint 15 + %503 = OpConstantComposite %v4uint %uint_7 %uint_15 %uint_7 %uint_15 + %uint_20 = OpConstant %uint 20 + %uint_2 = OpConstant %uint 2 + %uint_10 = OpConstant %uint 10 + %233 = OpConstantComposite %v4uint %uint_2 %uint_10 %uint_2 %uint_10 + %uint_8 = OpConstant %uint 8 + %uint_6 = OpConstant %uint 6 + %uint_14 = OpConstant %uint 14 + %449 = OpConstantComposite %v4uint %uint_6 %uint_14 %uint_6 %uint_14 + %uint_24 = OpConstant %uint 24 + %uint_9 = OpConstant %uint 9 + %179 = OpConstantComposite %v4uint %uint_1 %uint_9 %uint_1 %uint_9 + %uint_12 = OpConstant %uint 12 + %uint_5 = OpConstant %uint 5 + %uint_13 = OpConstant %uint 13 + %395 = OpConstantComposite %v4uint %uint_5 %uint_13 %uint_5 %uint_13 + %uint_28 = OpConstant %uint 28 + %uint_0 = OpConstant %uint 0 + %125 = OpConstantComposite %v4uint %uint_0 %uint_8 %uint_0 %uint_8 + %341 = OpConstantComposite %v4uint %uint_4 %uint_12 %uint_4 %uint_12 + %uint_16 = OpConstant %uint 16 +%uint_16711935 = OpConstant %uint 16711935 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2596 = OpConstantComposite %v3uint %uint_2 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 + %2620 = OpConstantComposite %v3uint %uint_2 %uint_2 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform + %uint_32 = OpConstant %uint 32 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %2950 = OpConstantComposite %v4uint %uint_1 %uint_1 %uint_1 %uint_1 + %101 = OpConstantComposite %v4uint %uint_4 %uint_4 %uint_4 %uint_4 + %965 = OpConstantComposite %v4uint %uint_20 %uint_20 %uint_20 %uint_20 + %1181 = OpConstantComposite %v4uint %uint_24 %uint_24 %uint_24 %uint_24 + %533 = OpConstantComposite %v4uint %uint_12 %uint_12 %uint_12 %uint_12 + %1397 = OpConstantComposite %v4uint %uint_28 %uint_28 %uint_28 %uint_28 + %3004 = OpConstantComposite %v4uint %uint_2 %uint_2 %uint_2 %uint_2 + %200 = OpConstantNull %v2uint + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %14903 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20158 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %22412 = OpLoad %uint %20158 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_7 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2596 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %14018 DontFlatten + OpBranchConditional %24679 %21992 %14018 + %21992 = OpLabel + OpBranch %14903 + %14018 = OpLabel + %17344 = OpShiftLeftLogical %v3uint %21387 %2620 + %15489 = OpBitcast %v3int %17344 + %18336 = OpCompositeExtract %int %15489 0 + %9362 = OpIMul %int %18336 %int_2 + %6362 = OpCompositeExtract %int %15489 2 + %14505 = OpBitcast %int %6594 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %15489 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %22412 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %9362 %24535 + %10898 = OpBitcast %uint %8258 + %9077 = OpIAdd %uint %10898 %22411 + %11726 = OpShiftRightLogical %uint %9077 %uint_4 + %6977 = OpShiftRightLogical %uint %22412 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20009 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %21373 %6361 + %21373 = OpLabel + %10608 = OpBitcast %v3int %21387 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_9 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_9 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_9 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17091 = OpCompositeExtract %int %6573 0 + %9470 = OpShiftRightArithmetic %int %17091 %int_5 + %10056 = OpCompositeExtract %int %6573 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_10 + %10934 = OpBitwiseAnd %int %17091 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_3 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17091 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %21373 %12098 %6361 + OpBranch %24387 + %20009 = OpLabel + %24447 = OpBitcast %v3int %21387 + %8918 = OpCompositeExtract %int %24447 0 + %9363 = OpIMul %int %8918 %int_8 + %6363 = OpCompositeExtract %int %24447 2 + %14506 = OpBitcast %int %22409 + %11280 = OpIMul %int %6363 %14506 + %17599 = OpCompositeExtract %int %24447 1 + %22229 = OpIAdd %int %11280 %17599 + %22406 = OpBitcast %int %22408 + %7839 = OpIMul %int %22229 %22406 + %7984 = OpIAdd %int %9363 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20009 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %13392 None + OpBranchConditional %15139 %11064 %13392 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %13392 + %13392 = OpLabel + %22100 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %11876 = OpSelect %uint %17270 %uint_2 %uint_1 + %11339 = OpIAdd %uint %22117 %11876 + %18278 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %11339 + %6578 = OpLoad %v4uint %18278 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %13392 %16377 %10584 + OpSelectionMerge %11682 None + OpBranchConditional %15139 %11065 %11682 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11682 + %11682 = OpLabel + %19853 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %22133 = OpVectorShuffle %v4uint %22100 %200 0 0 2 2 + %14639 = OpShiftRightLogical %v4uint %22133 %287 + %7908 = OpBitwiseAnd %v4uint %14639 %2950 + %24647 = OpShiftLeftLogical %v4uint %7908 %101 + %22591 = OpShiftRightLogical %v4uint %22133 %503 + %21613 = OpBitwiseAnd %v4uint %22591 %2950 + %24033 = OpShiftLeftLogical %v4uint %21613 %965 + %18005 = OpBitwiseOr %v4uint %24647 %24033 + %23151 = OpShiftRightLogical %v4uint %22133 %233 + %6577 = OpBitwiseAnd %v4uint %23151 %2950 + %24034 = OpShiftLeftLogical %v4uint %6577 %317 + %18006 = OpBitwiseOr %v4uint %18005 %24034 + %23152 = OpShiftRightLogical %v4uint %22133 %449 + %6579 = OpBitwiseAnd %v4uint %23152 %2950 + %24036 = OpShiftLeftLogical %v4uint %6579 %1181 + %18007 = OpBitwiseOr %v4uint %18006 %24036 + %23153 = OpShiftRightLogical %v4uint %22133 %179 + %6580 = OpBitwiseAnd %v4uint %23153 %2950 + %24037 = OpShiftLeftLogical %v4uint %6580 %533 + %18008 = OpBitwiseOr %v4uint %18007 %24037 + %23154 = OpShiftRightLogical %v4uint %22133 %395 + %6581 = OpBitwiseAnd %v4uint %23154 %2950 + %24038 = OpShiftLeftLogical %v4uint %6581 %1397 + %18009 = OpBitwiseOr %v4uint %18008 %24038 + %23170 = OpShiftRightLogical %v4uint %22133 %125 + %6347 = OpBitwiseAnd %v4uint %23170 %2950 + %16454 = OpBitwiseOr %v4uint %18009 %6347 + %22342 = OpShiftRightLogical %v4uint %22133 %341 + %6582 = OpBitwiseAnd %v4uint %22342 %2950 + %24071 = OpShiftLeftLogical %v4uint %6582 %749 + %17621 = OpBitwiseOr %v4uint %16454 %24071 + %7111 = OpShiftLeftLogical %v4uint %17621 %2950 + %16008 = OpBitwiseOr %v4uint %17621 %7111 + %23693 = OpShiftLeftLogical %v4uint %16008 %3004 + %17035 = OpBitwiseOr %v4uint %16008 %23693 + %21867 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11726 + OpStore %21867 %17035 + %11543 = OpIAdd %uint %11726 %uint_1 + %20183 = OpVectorShuffle %v4uint %19853 %200 0 0 2 2 + %20062 = OpShiftRightLogical %v4uint %20183 %287 + %7909 = OpBitwiseAnd %v4uint %20062 %2950 + %24648 = OpShiftLeftLogical %v4uint %7909 %101 + %22592 = OpShiftRightLogical %v4uint %20183 %503 + %21614 = OpBitwiseAnd %v4uint %22592 %2950 + %24039 = OpShiftLeftLogical %v4uint %21614 %965 + %18010 = OpBitwiseOr %v4uint %24648 %24039 + %23155 = OpShiftRightLogical %v4uint %20183 %233 + %6583 = OpBitwiseAnd %v4uint %23155 %2950 + %24040 = OpShiftLeftLogical %v4uint %6583 %317 + %18011 = OpBitwiseOr %v4uint %18010 %24040 + %23156 = OpShiftRightLogical %v4uint %20183 %449 + %6584 = OpBitwiseAnd %v4uint %23156 %2950 + %24041 = OpShiftLeftLogical %v4uint %6584 %1181 + %18012 = OpBitwiseOr %v4uint %18011 %24041 + %23157 = OpShiftRightLogical %v4uint %20183 %179 + %6585 = OpBitwiseAnd %v4uint %23157 %2950 + %24042 = OpShiftLeftLogical %v4uint %6585 %533 + %18013 = OpBitwiseOr %v4uint %18012 %24042 + %23158 = OpShiftRightLogical %v4uint %20183 %395 + %6586 = OpBitwiseAnd %v4uint %23158 %2950 + %24043 = OpShiftLeftLogical %v4uint %6586 %1397 + %18014 = OpBitwiseOr %v4uint %18013 %24043 + %23171 = OpShiftRightLogical %v4uint %20183 %125 + %6348 = OpBitwiseAnd %v4uint %23171 %2950 + %16455 = OpBitwiseOr %v4uint %18014 %6348 + %22343 = OpShiftRightLogical %v4uint %20183 %341 + %6587 = OpBitwiseAnd %v4uint %22343 %2950 + %24072 = OpShiftLeftLogical %v4uint %6587 %749 + %17622 = OpBitwiseOr %v4uint %16455 %24072 + %7112 = OpShiftLeftLogical %v4uint %17622 %2950 + %16009 = OpBitwiseOr %v4uint %17622 %7112 + %23694 = OpShiftLeftLogical %v4uint %16009 %3004 + %17036 = OpBitwiseOr %v4uint %16009 %23694 + %20974 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11543 + OpStore %20974 %17036 + %12832 = OpCompositeExtract %uint %17344 1 + %23232 = OpIAdd %uint %12832 %int_1 + %17425 = OpULessThan %bool %23232 %6594 + OpSelectionMerge %7206 DontFlatten + OpBranchConditional %17425 %20681 %7206 + %20681 = OpLabel + %13812 = OpIAdd %uint %11726 %6977 + %10288 = OpCompositeExtract %uint %22100 0 + %10052 = OpCompositeExtract %uint %22100 2 + %7641 = OpCompositeExtract %uint %19853 0 + %9980 = OpCompositeExtract %uint %19853 2 + %15337 = OpCompositeConstruct %v4uint %10288 %10052 %7641 %9980 + %12615 = OpShiftRightLogical %v4uint %15337 %749 + %22923 = OpVectorShuffle %v4uint %12615 %200 0 0 1 1 + %9021 = OpShiftRightLogical %v4uint %22923 %287 + %7910 = OpBitwiseAnd %v4uint %9021 %2950 + %24649 = OpShiftLeftLogical %v4uint %7910 %101 + %22593 = OpShiftRightLogical %v4uint %22923 %503 + %21615 = OpBitwiseAnd %v4uint %22593 %2950 + %24044 = OpShiftLeftLogical %v4uint %21615 %965 + %18015 = OpBitwiseOr %v4uint %24649 %24044 + %23159 = OpShiftRightLogical %v4uint %22923 %233 + %6588 = OpBitwiseAnd %v4uint %23159 %2950 + %24045 = OpShiftLeftLogical %v4uint %6588 %317 + %18016 = OpBitwiseOr %v4uint %18015 %24045 + %23160 = OpShiftRightLogical %v4uint %22923 %449 + %6589 = OpBitwiseAnd %v4uint %23160 %2950 + %24046 = OpShiftLeftLogical %v4uint %6589 %1181 + %18017 = OpBitwiseOr %v4uint %18016 %24046 + %23161 = OpShiftRightLogical %v4uint %22923 %179 + %6590 = OpBitwiseAnd %v4uint %23161 %2950 + %24047 = OpShiftLeftLogical %v4uint %6590 %533 + %18018 = OpBitwiseOr %v4uint %18017 %24047 + %23162 = OpShiftRightLogical %v4uint %22923 %395 + %6591 = OpBitwiseAnd %v4uint %23162 %2950 + %24048 = OpShiftLeftLogical %v4uint %6591 %1397 + %18019 = OpBitwiseOr %v4uint %18018 %24048 + %23172 = OpShiftRightLogical %v4uint %22923 %125 + %6349 = OpBitwiseAnd %v4uint %23172 %2950 + %16456 = OpBitwiseOr %v4uint %18019 %6349 + %22344 = OpShiftRightLogical %v4uint %22923 %341 + %6592 = OpBitwiseAnd %v4uint %22344 %2950 + %24073 = OpShiftLeftLogical %v4uint %6592 %749 + %17623 = OpBitwiseOr %v4uint %16456 %24073 + %7113 = OpShiftLeftLogical %v4uint %17623 %2950 + %16010 = OpBitwiseOr %v4uint %17623 %7113 + %23695 = OpShiftLeftLogical %v4uint %16010 %3004 + %17037 = OpBitwiseOr %v4uint %16010 %23695 + %21868 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13812 + OpStore %21868 %17037 + %11544 = OpIAdd %uint %13812 %uint_1 + %20184 = OpVectorShuffle %v4uint %12615 %200 2 2 3 3 + %20063 = OpShiftRightLogical %v4uint %20184 %287 + %7911 = OpBitwiseAnd %v4uint %20063 %2950 + %24650 = OpShiftLeftLogical %v4uint %7911 %101 + %22594 = OpShiftRightLogical %v4uint %20184 %503 + %21616 = OpBitwiseAnd %v4uint %22594 %2950 + %24049 = OpShiftLeftLogical %v4uint %21616 %965 + %18020 = OpBitwiseOr %v4uint %24650 %24049 + %23163 = OpShiftRightLogical %v4uint %20184 %233 + %6593 = OpBitwiseAnd %v4uint %23163 %2950 + %24050 = OpShiftLeftLogical %v4uint %6593 %317 + %18021 = OpBitwiseOr %v4uint %18020 %24050 + %23164 = OpShiftRightLogical %v4uint %20184 %449 + %6595 = OpBitwiseAnd %v4uint %23164 %2950 + %24051 = OpShiftLeftLogical %v4uint %6595 %1181 + %18022 = OpBitwiseOr %v4uint %18021 %24051 + %23165 = OpShiftRightLogical %v4uint %20184 %179 + %6596 = OpBitwiseAnd %v4uint %23165 %2950 + %24052 = OpShiftLeftLogical %v4uint %6596 %533 + %18023 = OpBitwiseOr %v4uint %18022 %24052 + %23166 = OpShiftRightLogical %v4uint %20184 %395 + %6597 = OpBitwiseAnd %v4uint %23166 %2950 + %24053 = OpShiftLeftLogical %v4uint %6597 %1397 + %18024 = OpBitwiseOr %v4uint %18023 %24053 + %23173 = OpShiftRightLogical %v4uint %20184 %125 + %6350 = OpBitwiseAnd %v4uint %23173 %2950 + %16457 = OpBitwiseOr %v4uint %18024 %6350 + %22345 = OpShiftRightLogical %v4uint %20184 %341 + %6598 = OpBitwiseAnd %v4uint %22345 %2950 + %24074 = OpShiftLeftLogical %v4uint %6598 %749 + %17624 = OpBitwiseOr %v4uint %16457 %24074 + %7114 = OpShiftLeftLogical %v4uint %17624 %2950 + %16011 = OpBitwiseOr %v4uint %17624 %7114 + %23696 = OpShiftLeftLogical %v4uint %16011 %3004 + %17038 = OpBitwiseOr %v4uint %16011 %23696 + %21869 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11544 + OpStore %21869 %17038 + %14840 = OpIAdd %uint %12832 %int_2 + %11787 = OpULessThan %bool %14840 %6594 + OpSelectionMerge %7205 DontFlatten + OpBranchConditional %11787 %20643 %7205 + %20643 = OpLabel + %16305 = OpIAdd %uint %13812 %6977 + %9367 = OpVectorShuffle %v4uint %22100 %200 1 1 3 3 + %20064 = OpShiftRightLogical %v4uint %9367 %287 + %7912 = OpBitwiseAnd %v4uint %20064 %2950 + %24651 = OpShiftLeftLogical %v4uint %7912 %101 + %22595 = OpShiftRightLogical %v4uint %9367 %503 + %21617 = OpBitwiseAnd %v4uint %22595 %2950 + %24054 = OpShiftLeftLogical %v4uint %21617 %965 + %18025 = OpBitwiseOr %v4uint %24651 %24054 + %23167 = OpShiftRightLogical %v4uint %9367 %233 + %6599 = OpBitwiseAnd %v4uint %23167 %2950 + %24055 = OpShiftLeftLogical %v4uint %6599 %317 + %18026 = OpBitwiseOr %v4uint %18025 %24055 + %23168 = OpShiftRightLogical %v4uint %9367 %449 + %6600 = OpBitwiseAnd %v4uint %23168 %2950 + %24056 = OpShiftLeftLogical %v4uint %6600 %1181 + %18027 = OpBitwiseOr %v4uint %18026 %24056 + %23169 = OpShiftRightLogical %v4uint %9367 %179 + %6601 = OpBitwiseAnd %v4uint %23169 %2950 + %24057 = OpShiftLeftLogical %v4uint %6601 %533 + %18028 = OpBitwiseOr %v4uint %18027 %24057 + %23174 = OpShiftRightLogical %v4uint %9367 %395 + %6602 = OpBitwiseAnd %v4uint %23174 %2950 + %24058 = OpShiftLeftLogical %v4uint %6602 %1397 + %18029 = OpBitwiseOr %v4uint %18028 %24058 + %23175 = OpShiftRightLogical %v4uint %9367 %125 + %6351 = OpBitwiseAnd %v4uint %23175 %2950 + %16458 = OpBitwiseOr %v4uint %18029 %6351 + %22346 = OpShiftRightLogical %v4uint %9367 %341 + %6603 = OpBitwiseAnd %v4uint %22346 %2950 + %24075 = OpShiftLeftLogical %v4uint %6603 %749 + %17625 = OpBitwiseOr %v4uint %16458 %24075 + %7115 = OpShiftLeftLogical %v4uint %17625 %2950 + %16012 = OpBitwiseOr %v4uint %17625 %7115 + %23697 = OpShiftLeftLogical %v4uint %16012 %3004 + %17039 = OpBitwiseOr %v4uint %16012 %23697 + %21870 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %16305 + OpStore %21870 %17039 + %11545 = OpIAdd %uint %16305 %uint_1 + %20185 = OpVectorShuffle %v4uint %19853 %200 1 1 3 3 + %20065 = OpShiftRightLogical %v4uint %20185 %287 + %7913 = OpBitwiseAnd %v4uint %20065 %2950 + %24652 = OpShiftLeftLogical %v4uint %7913 %101 + %22596 = OpShiftRightLogical %v4uint %20185 %503 + %21618 = OpBitwiseAnd %v4uint %22596 %2950 + %24059 = OpShiftLeftLogical %v4uint %21618 %965 + %18030 = OpBitwiseOr %v4uint %24652 %24059 + %23176 = OpShiftRightLogical %v4uint %20185 %233 + %6604 = OpBitwiseAnd %v4uint %23176 %2950 + %24060 = OpShiftLeftLogical %v4uint %6604 %317 + %18031 = OpBitwiseOr %v4uint %18030 %24060 + %23177 = OpShiftRightLogical %v4uint %20185 %449 + %6605 = OpBitwiseAnd %v4uint %23177 %2950 + %24061 = OpShiftLeftLogical %v4uint %6605 %1181 + %18032 = OpBitwiseOr %v4uint %18031 %24061 + %23178 = OpShiftRightLogical %v4uint %20185 %179 + %6606 = OpBitwiseAnd %v4uint %23178 %2950 + %24062 = OpShiftLeftLogical %v4uint %6606 %533 + %18033 = OpBitwiseOr %v4uint %18032 %24062 + %23179 = OpShiftRightLogical %v4uint %20185 %395 + %6607 = OpBitwiseAnd %v4uint %23179 %2950 + %24063 = OpShiftLeftLogical %v4uint %6607 %1397 + %18034 = OpBitwiseOr %v4uint %18033 %24063 + %23180 = OpShiftRightLogical %v4uint %20185 %125 + %6352 = OpBitwiseAnd %v4uint %23180 %2950 + %16459 = OpBitwiseOr %v4uint %18034 %6352 + %22347 = OpShiftRightLogical %v4uint %20185 %341 + %6608 = OpBitwiseAnd %v4uint %22347 %2950 + %24076 = OpShiftLeftLogical %v4uint %6608 %749 + %17626 = OpBitwiseOr %v4uint %16459 %24076 + %7116 = OpShiftLeftLogical %v4uint %17626 %2950 + %16013 = OpBitwiseOr %v4uint %17626 %7116 + %23698 = OpShiftLeftLogical %v4uint %16013 %3004 + %17040 = OpBitwiseOr %v4uint %16013 %23698 + %21871 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11545 + OpStore %21871 %17040 + %14841 = OpIAdd %uint %12832 %int_3 + %11788 = OpULessThan %bool %14841 %6594 + OpSelectionMerge %18045 DontFlatten + OpBranchConditional %11788 %20682 %18045 + %20682 = OpLabel + %13813 = OpIAdd %uint %16305 %6977 + %10289 = OpCompositeExtract %uint %22100 1 + %10053 = OpCompositeExtract %uint %22100 3 + %7642 = OpCompositeExtract %uint %19853 1 + %9981 = OpCompositeExtract %uint %19853 3 + %15338 = OpCompositeConstruct %v4uint %10289 %10053 %7642 %9981 + %12616 = OpShiftRightLogical %v4uint %15338 %749 + %22924 = OpVectorShuffle %v4uint %12616 %200 0 0 1 1 + %9022 = OpShiftRightLogical %v4uint %22924 %287 + %7914 = OpBitwiseAnd %v4uint %9022 %2950 + %24653 = OpShiftLeftLogical %v4uint %7914 %101 + %22597 = OpShiftRightLogical %v4uint %22924 %503 + %21619 = OpBitwiseAnd %v4uint %22597 %2950 + %24064 = OpShiftLeftLogical %v4uint %21619 %965 + %18035 = OpBitwiseOr %v4uint %24653 %24064 + %23181 = OpShiftRightLogical %v4uint %22924 %233 + %6609 = OpBitwiseAnd %v4uint %23181 %2950 + %24065 = OpShiftLeftLogical %v4uint %6609 %317 + %18036 = OpBitwiseOr %v4uint %18035 %24065 + %23182 = OpShiftRightLogical %v4uint %22924 %449 + %6610 = OpBitwiseAnd %v4uint %23182 %2950 + %24066 = OpShiftLeftLogical %v4uint %6610 %1181 + %18037 = OpBitwiseOr %v4uint %18036 %24066 + %23183 = OpShiftRightLogical %v4uint %22924 %179 + %6611 = OpBitwiseAnd %v4uint %23183 %2950 + %24067 = OpShiftLeftLogical %v4uint %6611 %533 + %18038 = OpBitwiseOr %v4uint %18037 %24067 + %23184 = OpShiftRightLogical %v4uint %22924 %395 + %6612 = OpBitwiseAnd %v4uint %23184 %2950 + %24068 = OpShiftLeftLogical %v4uint %6612 %1397 + %18039 = OpBitwiseOr %v4uint %18038 %24068 + %23185 = OpShiftRightLogical %v4uint %22924 %125 + %6353 = OpBitwiseAnd %v4uint %23185 %2950 + %16460 = OpBitwiseOr %v4uint %18039 %6353 + %22348 = OpShiftRightLogical %v4uint %22924 %341 + %6613 = OpBitwiseAnd %v4uint %22348 %2950 + %24077 = OpShiftLeftLogical %v4uint %6613 %749 + %17627 = OpBitwiseOr %v4uint %16460 %24077 + %7117 = OpShiftLeftLogical %v4uint %17627 %2950 + %16014 = OpBitwiseOr %v4uint %17627 %7117 + %23699 = OpShiftLeftLogical %v4uint %16014 %3004 + %17041 = OpBitwiseOr %v4uint %16014 %23699 + %21872 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13813 + OpStore %21872 %17041 + %11546 = OpIAdd %uint %13813 %uint_1 + %20186 = OpVectorShuffle %v4uint %12616 %200 2 2 3 3 + %20066 = OpShiftRightLogical %v4uint %20186 %287 + %7915 = OpBitwiseAnd %v4uint %20066 %2950 + %24654 = OpShiftLeftLogical %v4uint %7915 %101 + %22598 = OpShiftRightLogical %v4uint %20186 %503 + %21620 = OpBitwiseAnd %v4uint %22598 %2950 + %24069 = OpShiftLeftLogical %v4uint %21620 %965 + %18040 = OpBitwiseOr %v4uint %24654 %24069 + %23186 = OpShiftRightLogical %v4uint %20186 %233 + %6614 = OpBitwiseAnd %v4uint %23186 %2950 + %24070 = OpShiftLeftLogical %v4uint %6614 %317 + %18041 = OpBitwiseOr %v4uint %18040 %24070 + %23187 = OpShiftRightLogical %v4uint %20186 %449 + %6615 = OpBitwiseAnd %v4uint %23187 %2950 + %24078 = OpShiftLeftLogical %v4uint %6615 %1181 + %18042 = OpBitwiseOr %v4uint %18041 %24078 + %23188 = OpShiftRightLogical %v4uint %20186 %179 + %6616 = OpBitwiseAnd %v4uint %23188 %2950 + %24079 = OpShiftLeftLogical %v4uint %6616 %533 + %18043 = OpBitwiseOr %v4uint %18042 %24079 + %23189 = OpShiftRightLogical %v4uint %20186 %395 + %6617 = OpBitwiseAnd %v4uint %23189 %2950 + %24080 = OpShiftLeftLogical %v4uint %6617 %1397 + %18044 = OpBitwiseOr %v4uint %18043 %24080 + %23190 = OpShiftRightLogical %v4uint %20186 %125 + %6354 = OpBitwiseAnd %v4uint %23190 %2950 + %16461 = OpBitwiseOr %v4uint %18044 %6354 + %22349 = OpShiftRightLogical %v4uint %20186 %341 + %6618 = OpBitwiseAnd %v4uint %22349 %2950 + %24081 = OpShiftLeftLogical %v4uint %6618 %749 + %17628 = OpBitwiseOr %v4uint %16461 %24081 + %7118 = OpShiftLeftLogical %v4uint %17628 %2950 + %16015 = OpBitwiseOr %v4uint %17628 %7118 + %23700 = OpShiftLeftLogical %v4uint %16015 %3004 + %17042 = OpBitwiseOr %v4uint %16015 %23700 + %24166 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11546 + OpStore %24166 %17042 + OpBranch %18045 + %18045 = OpLabel + OpBranch %7205 + %7205 = OpLabel + OpBranch %7206 + %7206 = OpLabel + OpBranch %14903 + %14903 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_dxt3aas1111_argb4_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A2B, 0x0000000B, + 0x0007002C, 0x00000017, 0x0000011F, 0x00000A13, 0x00000A2B, 0x00000A13, 0x00000A2B, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, + 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, 0x0007002C, + 0x00000017, 0x000001F7, 0x00000A1F, 0x00000A37, 0x00000A1F, 0x00000A37, 0x0004002B, 0x0000000B, + 0x00000A46, 0x00000014, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, + 0x00000A28, 0x0000000A, 0x0007002C, 0x00000017, 0x000000E9, 0x00000A10, 0x00000A28, 0x00000A10, + 0x00000A28, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x00000A1C, + 0x00000006, 0x0004002B, 0x0000000B, 0x00000A34, 0x0000000E, 0x0007002C, 0x00000017, 0x000001C1, + 0x00000A1C, 0x00000A34, 0x00000A1C, 0x00000A34, 0x0004002B, 0x0000000B, 0x00000A52, 0x00000018, + 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0007002C, 0x00000017, 0x000000B3, 0x00000A0D, + 0x00000A25, 0x00000A0D, 0x00000A25, 0x0004002B, 0x0000000B, 0x00000A2E, 0x0000000C, 0x0004002B, + 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, 0x0007002C, + 0x00000017, 0x0000018B, 0x00000A19, 0x00000A31, 0x00000A19, 0x00000A31, 0x0004002B, 0x0000000B, + 0x00000A5E, 0x0000001C, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0007002C, 0x00000017, + 0x0000007D, 0x00000A0A, 0x00000A22, 0x00000A0A, 0x00000A22, 0x0007002C, 0x00000017, 0x00000155, + 0x00000A16, 0x00000A2E, 0x00000A16, 0x00000A2E, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, + 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, + 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, + 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, + 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x00040020, 0x00000291, + 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, + 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A24, 0x00000A10, 0x00000A0A, 0x00000A0A, + 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0006002C, 0x00000014, 0x00000A3C, 0x00000A10, + 0x00000A10, 0x00000A0A, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A32, 0x0000107A, 0x00000002, + 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, + 0x000007B5, 0x000007DD, 0x00040020, 0x00000A33, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A33, + 0x0000140E, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0006002C, 0x00000014, + 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, + 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, + 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, + 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, + 0x0007002C, 0x00000017, 0x00000B86, 0x00000A0D, 0x00000A0D, 0x00000A0D, 0x00000A0D, 0x0007002C, + 0x00000017, 0x00000065, 0x00000A16, 0x00000A16, 0x00000A16, 0x00000A16, 0x0007002C, 0x00000017, + 0x000003C5, 0x00000A46, 0x00000A46, 0x00000A46, 0x00000A46, 0x0007002C, 0x00000017, 0x0000049D, + 0x00000A52, 0x00000A52, 0x00000A52, 0x00000A52, 0x0007002C, 0x00000017, 0x00000215, 0x00000A2E, + 0x00000A2E, 0x00000A2E, 0x00000A2E, 0x0007002C, 0x00000017, 0x00000575, 0x00000A5E, 0x00000A5E, + 0x00000A5E, 0x00000A5E, 0x0007002C, 0x00000017, 0x00000BBC, 0x00000A10, 0x00000A10, 0x00000A10, + 0x00000A10, 0x0003002E, 0x00000011, 0x000000C8, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, + 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00003A37, 0x00000000, 0x000300FB, 0x00000A0A, + 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, + 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, + 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, + 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, + 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, + 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, + 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, + 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, + 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, + 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, + 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, + 0x00000288, 0x00004EBE, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x0000578C, 0x00004EBE, + 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A20, 0x0004003D, 0x0000000B, 0x000019C2, + 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, + 0x00002A0E, 0x00000A24, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, + 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, + 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, + 0x00004288, 0x000300F7, 0x000036C2, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000036C2, + 0x000200F8, 0x000055E8, 0x000200F9, 0x00003A37, 0x000200F8, 0x000036C2, 0x000500C4, 0x00000014, + 0x000043C0, 0x0000538B, 0x00000A3C, 0x0004007C, 0x00000016, 0x00003C81, 0x000043C0, 0x00050051, + 0x0000000C, 0x000047A0, 0x00003C81, 0x00000000, 0x00050084, 0x0000000C, 0x00002492, 0x000047A0, + 0x00000A11, 0x00050051, 0x0000000C, 0x000018DA, 0x00003C81, 0x00000002, 0x0004007C, 0x0000000C, + 0x000038A9, 0x000019C2, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, + 0x0000000C, 0x000044BE, 0x00003C81, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, + 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x0000578C, 0x00050084, 0x0000000C, 0x00005FD7, + 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x00002492, 0x00005FD7, 0x0004007C, + 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00002375, 0x00002A92, 0x0000578B, + 0x000500C2, 0x0000000B, 0x00002DCE, 0x00002375, 0x00000A16, 0x000500C2, 0x0000000B, 0x00001B41, + 0x0000578C, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, 0x00005768, + 0x00004E29, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, 0x00004384, + 0x0000537D, 0x000018D9, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, 0x00002970, 0x0000538B, + 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FD, + 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000002, 0x000500C3, + 0x0000000C, 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005789, + 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005321, + 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, 0x00005321, 0x000500C2, + 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, + 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, + 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, + 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, + 0x00000A25, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, + 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, + 0x000500C7, 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, + 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, + 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A25, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, + 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, + 0x000035A3, 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, + 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, + 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, + 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, + 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, + 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, + 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, + 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, + 0x0000000C, 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, + 0x00000A25, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, + 0x00004ADE, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, + 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, + 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, + 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, + 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, + 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, + 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, + 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, + 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, + 0x000054ED, 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, + 0x00000012, 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, 0x000042C3, 0x000019AD, 0x00000000, + 0x000500C3, 0x0000000C, 0x000024FE, 0x000042C3, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002748, + 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, 0x000500C2, + 0x0000000B, 0x00005B4E, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, + 0x00050084, 0x0000000C, 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, + 0x000024FE, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A28, 0x000500C7, + 0x0000000C, 0x00002AB6, 0x000042C3, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002748, + 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, + 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A13, + 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, + 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, + 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, + 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, + 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, + 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, 0x000500C4, + 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, + 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, + 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, + 0x000500C7, 0x0000000C, 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, + 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C3, 0x00000A14, 0x00050080, + 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, + 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, + 0x00050080, 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, + 0x00001E0B, 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, 0x0000537D, 0x00002F42, 0x000018D9, + 0x000200F9, 0x00005F43, 0x000200F8, 0x00004E29, 0x0004007C, 0x00000016, 0x00005F7F, 0x0000538B, + 0x00050051, 0x0000000C, 0x000022D6, 0x00005F7F, 0x00000000, 0x00050084, 0x0000000C, 0x00002493, + 0x000022D6, 0x00000A23, 0x00050051, 0x0000000C, 0x000018DB, 0x00005F7F, 0x00000002, 0x0004007C, + 0x0000000C, 0x000038AA, 0x00005789, 0x00050084, 0x0000000C, 0x00002C10, 0x000018DB, 0x000038AA, + 0x00050051, 0x0000000C, 0x000044BF, 0x00005F7F, 0x00000001, 0x00050080, 0x0000000C, 0x000056D5, + 0x00002C10, 0x000044BF, 0x0004007C, 0x0000000C, 0x00005786, 0x00005788, 0x00050084, 0x0000000C, + 0x00001E9F, 0x000056D5, 0x00005786, 0x00050080, 0x0000000C, 0x00001F30, 0x00002493, 0x00001E9F, + 0x000200F9, 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, + 0x00001E0B, 0x00001F30, 0x00004E29, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, + 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, + 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, 0x00004315, + 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004315, 0x000500AA, + 0x00000009, 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x000061E2, + 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, + 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, + 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, + 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, + 0x00005F43, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000061E2, 0x00000A13, + 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x00003450, 0x00000000, + 0x000400FA, 0x00003B23, 0x00002B38, 0x00003450, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, + 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, + 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x00003450, 0x000200F8, + 0x00003450, 0x000700F5, 0x00000017, 0x00005654, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, + 0x000600A9, 0x0000000B, 0x00002E64, 0x00004376, 0x00000A10, 0x00000A0D, 0x00050080, 0x0000000B, + 0x00002C4B, 0x00005665, 0x00002E64, 0x00060041, 0x00000294, 0x00004766, 0x0000107A, 0x00000A0B, + 0x00002C4B, 0x0004003D, 0x00000017, 0x000019B2, 0x00004766, 0x000300F7, 0x00003A1A, 0x00000000, + 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, + 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, + 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, + 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x00003450, + 0x00003FF9, 0x00002958, 0x000300F7, 0x00002DA2, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, + 0x00002DA2, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, + 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, + 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002DA2, 0x000200F8, 0x00002DA2, 0x000700F5, 0x00000017, + 0x00004D8D, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x0009004F, 0x00000017, 0x00005675, + 0x00005654, 0x000000C8, 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x000500C2, 0x00000017, + 0x0000392F, 0x00005675, 0x0000011F, 0x000500C7, 0x00000017, 0x00001EE4, 0x0000392F, 0x00000B86, + 0x000500C4, 0x00000017, 0x00006047, 0x00001EE4, 0x00000065, 0x000500C2, 0x00000017, 0x0000583F, + 0x00005675, 0x000001F7, 0x000500C7, 0x00000017, 0x0000546D, 0x0000583F, 0x00000B86, 0x000500C4, + 0x00000017, 0x00005DE1, 0x0000546D, 0x000003C5, 0x000500C5, 0x00000017, 0x00004655, 0x00006047, + 0x00005DE1, 0x000500C2, 0x00000017, 0x00005A6F, 0x00005675, 0x000000E9, 0x000500C7, 0x00000017, + 0x000019B1, 0x00005A6F, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DE2, 0x000019B1, 0x0000013D, + 0x000500C5, 0x00000017, 0x00004656, 0x00004655, 0x00005DE2, 0x000500C2, 0x00000017, 0x00005A70, + 0x00005675, 0x000001C1, 0x000500C7, 0x00000017, 0x000019B3, 0x00005A70, 0x00000B86, 0x000500C4, + 0x00000017, 0x00005DE4, 0x000019B3, 0x0000049D, 0x000500C5, 0x00000017, 0x00004657, 0x00004656, + 0x00005DE4, 0x000500C2, 0x00000017, 0x00005A71, 0x00005675, 0x000000B3, 0x000500C7, 0x00000017, + 0x000019B4, 0x00005A71, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DE5, 0x000019B4, 0x00000215, + 0x000500C5, 0x00000017, 0x00004658, 0x00004657, 0x00005DE5, 0x000500C2, 0x00000017, 0x00005A72, + 0x00005675, 0x0000018B, 0x000500C7, 0x00000017, 0x000019B5, 0x00005A72, 0x00000B86, 0x000500C4, + 0x00000017, 0x00005DE6, 0x000019B5, 0x00000575, 0x000500C5, 0x00000017, 0x00004659, 0x00004658, + 0x00005DE6, 0x000500C2, 0x00000017, 0x00005A82, 0x00005675, 0x0000007D, 0x000500C7, 0x00000017, + 0x000018CB, 0x00005A82, 0x00000B86, 0x000500C5, 0x00000017, 0x00004046, 0x00004659, 0x000018CB, + 0x000500C2, 0x00000017, 0x00005746, 0x00005675, 0x00000155, 0x000500C7, 0x00000017, 0x000019B6, + 0x00005746, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E07, 0x000019B6, 0x000002ED, 0x000500C5, + 0x00000017, 0x000044D5, 0x00004046, 0x00005E07, 0x000500C4, 0x00000017, 0x00001BC7, 0x000044D5, + 0x00000B86, 0x000500C5, 0x00000017, 0x00003E88, 0x000044D5, 0x00001BC7, 0x000500C4, 0x00000017, + 0x00005C8D, 0x00003E88, 0x00000BBC, 0x000500C5, 0x00000017, 0x0000428B, 0x00003E88, 0x00005C8D, + 0x00060041, 0x00000294, 0x0000556B, 0x0000140E, 0x00000A0B, 0x00002DCE, 0x0003003E, 0x0000556B, + 0x0000428B, 0x00050080, 0x0000000B, 0x00002D17, 0x00002DCE, 0x00000A0D, 0x0009004F, 0x00000017, + 0x00004ED7, 0x00004D8D, 0x000000C8, 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x000500C2, + 0x00000017, 0x00004E5E, 0x00004ED7, 0x0000011F, 0x000500C7, 0x00000017, 0x00001EE5, 0x00004E5E, + 0x00000B86, 0x000500C4, 0x00000017, 0x00006048, 0x00001EE5, 0x00000065, 0x000500C2, 0x00000017, + 0x00005840, 0x00004ED7, 0x000001F7, 0x000500C7, 0x00000017, 0x0000546E, 0x00005840, 0x00000B86, + 0x000500C4, 0x00000017, 0x00005DE7, 0x0000546E, 0x000003C5, 0x000500C5, 0x00000017, 0x0000465A, + 0x00006048, 0x00005DE7, 0x000500C2, 0x00000017, 0x00005A73, 0x00004ED7, 0x000000E9, 0x000500C7, + 0x00000017, 0x000019B7, 0x00005A73, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DE8, 0x000019B7, + 0x0000013D, 0x000500C5, 0x00000017, 0x0000465B, 0x0000465A, 0x00005DE8, 0x000500C2, 0x00000017, + 0x00005A74, 0x00004ED7, 0x000001C1, 0x000500C7, 0x00000017, 0x000019B8, 0x00005A74, 0x00000B86, + 0x000500C4, 0x00000017, 0x00005DE9, 0x000019B8, 0x0000049D, 0x000500C5, 0x00000017, 0x0000465C, + 0x0000465B, 0x00005DE9, 0x000500C2, 0x00000017, 0x00005A75, 0x00004ED7, 0x000000B3, 0x000500C7, + 0x00000017, 0x000019B9, 0x00005A75, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DEA, 0x000019B9, + 0x00000215, 0x000500C5, 0x00000017, 0x0000465D, 0x0000465C, 0x00005DEA, 0x000500C2, 0x00000017, + 0x00005A76, 0x00004ED7, 0x0000018B, 0x000500C7, 0x00000017, 0x000019BA, 0x00005A76, 0x00000B86, + 0x000500C4, 0x00000017, 0x00005DEB, 0x000019BA, 0x00000575, 0x000500C5, 0x00000017, 0x0000465E, + 0x0000465D, 0x00005DEB, 0x000500C2, 0x00000017, 0x00005A83, 0x00004ED7, 0x0000007D, 0x000500C7, + 0x00000017, 0x000018CC, 0x00005A83, 0x00000B86, 0x000500C5, 0x00000017, 0x00004047, 0x0000465E, + 0x000018CC, 0x000500C2, 0x00000017, 0x00005747, 0x00004ED7, 0x00000155, 0x000500C7, 0x00000017, + 0x000019BB, 0x00005747, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E08, 0x000019BB, 0x000002ED, + 0x000500C5, 0x00000017, 0x000044D6, 0x00004047, 0x00005E08, 0x000500C4, 0x00000017, 0x00001BC8, + 0x000044D6, 0x00000B86, 0x000500C5, 0x00000017, 0x00003E89, 0x000044D6, 0x00001BC8, 0x000500C4, + 0x00000017, 0x00005C8E, 0x00003E89, 0x00000BBC, 0x000500C5, 0x00000017, 0x0000428C, 0x00003E89, + 0x00005C8E, 0x00060041, 0x00000294, 0x000051EE, 0x0000140E, 0x00000A0B, 0x00002D17, 0x0003003E, + 0x000051EE, 0x0000428C, 0x00050051, 0x0000000B, 0x00003220, 0x000043C0, 0x00000001, 0x00050080, + 0x0000000B, 0x00005AC0, 0x00003220, 0x00000A0E, 0x000500B0, 0x00000009, 0x00004411, 0x00005AC0, + 0x000019C2, 0x000300F7, 0x00001C26, 0x00000002, 0x000400FA, 0x00004411, 0x000050C9, 0x00001C26, + 0x000200F8, 0x000050C9, 0x00050080, 0x0000000B, 0x000035F4, 0x00002DCE, 0x00001B41, 0x00050051, + 0x0000000B, 0x00002830, 0x00005654, 0x00000000, 0x00050051, 0x0000000B, 0x00002744, 0x00005654, + 0x00000002, 0x00050051, 0x0000000B, 0x00001DD9, 0x00004D8D, 0x00000000, 0x00050051, 0x0000000B, + 0x000026FC, 0x00004D8D, 0x00000002, 0x00070050, 0x00000017, 0x00003BE9, 0x00002830, 0x00002744, + 0x00001DD9, 0x000026FC, 0x000500C2, 0x00000017, 0x00003147, 0x00003BE9, 0x000002ED, 0x0009004F, + 0x00000017, 0x0000598B, 0x00003147, 0x000000C8, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C2, 0x00000017, 0x0000233D, 0x0000598B, 0x0000011F, 0x000500C7, 0x00000017, 0x00001EE6, + 0x0000233D, 0x00000B86, 0x000500C4, 0x00000017, 0x00006049, 0x00001EE6, 0x00000065, 0x000500C2, + 0x00000017, 0x00005841, 0x0000598B, 0x000001F7, 0x000500C7, 0x00000017, 0x0000546F, 0x00005841, + 0x00000B86, 0x000500C4, 0x00000017, 0x00005DEC, 0x0000546F, 0x000003C5, 0x000500C5, 0x00000017, + 0x0000465F, 0x00006049, 0x00005DEC, 0x000500C2, 0x00000017, 0x00005A77, 0x0000598B, 0x000000E9, + 0x000500C7, 0x00000017, 0x000019BC, 0x00005A77, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DED, + 0x000019BC, 0x0000013D, 0x000500C5, 0x00000017, 0x00004660, 0x0000465F, 0x00005DED, 0x000500C2, + 0x00000017, 0x00005A78, 0x0000598B, 0x000001C1, 0x000500C7, 0x00000017, 0x000019BD, 0x00005A78, + 0x00000B86, 0x000500C4, 0x00000017, 0x00005DEE, 0x000019BD, 0x0000049D, 0x000500C5, 0x00000017, + 0x00004661, 0x00004660, 0x00005DEE, 0x000500C2, 0x00000017, 0x00005A79, 0x0000598B, 0x000000B3, + 0x000500C7, 0x00000017, 0x000019BE, 0x00005A79, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DEF, + 0x000019BE, 0x00000215, 0x000500C5, 0x00000017, 0x00004662, 0x00004661, 0x00005DEF, 0x000500C2, + 0x00000017, 0x00005A7A, 0x0000598B, 0x0000018B, 0x000500C7, 0x00000017, 0x000019BF, 0x00005A7A, + 0x00000B86, 0x000500C4, 0x00000017, 0x00005DF0, 0x000019BF, 0x00000575, 0x000500C5, 0x00000017, + 0x00004663, 0x00004662, 0x00005DF0, 0x000500C2, 0x00000017, 0x00005A84, 0x0000598B, 0x0000007D, + 0x000500C7, 0x00000017, 0x000018CD, 0x00005A84, 0x00000B86, 0x000500C5, 0x00000017, 0x00004048, + 0x00004663, 0x000018CD, 0x000500C2, 0x00000017, 0x00005748, 0x0000598B, 0x00000155, 0x000500C7, + 0x00000017, 0x000019C0, 0x00005748, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E09, 0x000019C0, + 0x000002ED, 0x000500C5, 0x00000017, 0x000044D7, 0x00004048, 0x00005E09, 0x000500C4, 0x00000017, + 0x00001BC9, 0x000044D7, 0x00000B86, 0x000500C5, 0x00000017, 0x00003E8A, 0x000044D7, 0x00001BC9, + 0x000500C4, 0x00000017, 0x00005C8F, 0x00003E8A, 0x00000BBC, 0x000500C5, 0x00000017, 0x0000428D, + 0x00003E8A, 0x00005C8F, 0x00060041, 0x00000294, 0x0000556C, 0x0000140E, 0x00000A0B, 0x000035F4, + 0x0003003E, 0x0000556C, 0x0000428D, 0x00050080, 0x0000000B, 0x00002D18, 0x000035F4, 0x00000A0D, + 0x0009004F, 0x00000017, 0x00004ED8, 0x00003147, 0x000000C8, 0x00000002, 0x00000002, 0x00000003, + 0x00000003, 0x000500C2, 0x00000017, 0x00004E5F, 0x00004ED8, 0x0000011F, 0x000500C7, 0x00000017, + 0x00001EE7, 0x00004E5F, 0x00000B86, 0x000500C4, 0x00000017, 0x0000604A, 0x00001EE7, 0x00000065, + 0x000500C2, 0x00000017, 0x00005842, 0x00004ED8, 0x000001F7, 0x000500C7, 0x00000017, 0x00005470, + 0x00005842, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DF1, 0x00005470, 0x000003C5, 0x000500C5, + 0x00000017, 0x00004664, 0x0000604A, 0x00005DF1, 0x000500C2, 0x00000017, 0x00005A7B, 0x00004ED8, + 0x000000E9, 0x000500C7, 0x00000017, 0x000019C1, 0x00005A7B, 0x00000B86, 0x000500C4, 0x00000017, + 0x00005DF2, 0x000019C1, 0x0000013D, 0x000500C5, 0x00000017, 0x00004665, 0x00004664, 0x00005DF2, + 0x000500C2, 0x00000017, 0x00005A7C, 0x00004ED8, 0x000001C1, 0x000500C7, 0x00000017, 0x000019C3, + 0x00005A7C, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DF3, 0x000019C3, 0x0000049D, 0x000500C5, + 0x00000017, 0x00004666, 0x00004665, 0x00005DF3, 0x000500C2, 0x00000017, 0x00005A7D, 0x00004ED8, + 0x000000B3, 0x000500C7, 0x00000017, 0x000019C4, 0x00005A7D, 0x00000B86, 0x000500C4, 0x00000017, + 0x00005DF4, 0x000019C4, 0x00000215, 0x000500C5, 0x00000017, 0x00004667, 0x00004666, 0x00005DF4, + 0x000500C2, 0x00000017, 0x00005A7E, 0x00004ED8, 0x0000018B, 0x000500C7, 0x00000017, 0x000019C5, + 0x00005A7E, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DF5, 0x000019C5, 0x00000575, 0x000500C5, + 0x00000017, 0x00004668, 0x00004667, 0x00005DF5, 0x000500C2, 0x00000017, 0x00005A85, 0x00004ED8, + 0x0000007D, 0x000500C7, 0x00000017, 0x000018CE, 0x00005A85, 0x00000B86, 0x000500C5, 0x00000017, + 0x00004049, 0x00004668, 0x000018CE, 0x000500C2, 0x00000017, 0x00005749, 0x00004ED8, 0x00000155, + 0x000500C7, 0x00000017, 0x000019C6, 0x00005749, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E0A, + 0x000019C6, 0x000002ED, 0x000500C5, 0x00000017, 0x000044D8, 0x00004049, 0x00005E0A, 0x000500C4, + 0x00000017, 0x00001BCA, 0x000044D8, 0x00000B86, 0x000500C5, 0x00000017, 0x00003E8B, 0x000044D8, + 0x00001BCA, 0x000500C4, 0x00000017, 0x00005C90, 0x00003E8B, 0x00000BBC, 0x000500C5, 0x00000017, + 0x0000428E, 0x00003E8B, 0x00005C90, 0x00060041, 0x00000294, 0x0000556D, 0x0000140E, 0x00000A0B, + 0x00002D18, 0x0003003E, 0x0000556D, 0x0000428E, 0x00050080, 0x0000000B, 0x000039F8, 0x00003220, + 0x00000A11, 0x000500B0, 0x00000009, 0x00002E0B, 0x000039F8, 0x000019C2, 0x000300F7, 0x00001C25, + 0x00000002, 0x000400FA, 0x00002E0B, 0x000050A3, 0x00001C25, 0x000200F8, 0x000050A3, 0x00050080, + 0x0000000B, 0x00003FB1, 0x000035F4, 0x00001B41, 0x0009004F, 0x00000017, 0x00002497, 0x00005654, + 0x000000C8, 0x00000001, 0x00000001, 0x00000003, 0x00000003, 0x000500C2, 0x00000017, 0x00004E60, + 0x00002497, 0x0000011F, 0x000500C7, 0x00000017, 0x00001EE8, 0x00004E60, 0x00000B86, 0x000500C4, + 0x00000017, 0x0000604B, 0x00001EE8, 0x00000065, 0x000500C2, 0x00000017, 0x00005843, 0x00002497, + 0x000001F7, 0x000500C7, 0x00000017, 0x00005471, 0x00005843, 0x00000B86, 0x000500C4, 0x00000017, + 0x00005DF6, 0x00005471, 0x000003C5, 0x000500C5, 0x00000017, 0x00004669, 0x0000604B, 0x00005DF6, + 0x000500C2, 0x00000017, 0x00005A7F, 0x00002497, 0x000000E9, 0x000500C7, 0x00000017, 0x000019C7, + 0x00005A7F, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DF7, 0x000019C7, 0x0000013D, 0x000500C5, + 0x00000017, 0x0000466A, 0x00004669, 0x00005DF7, 0x000500C2, 0x00000017, 0x00005A80, 0x00002497, + 0x000001C1, 0x000500C7, 0x00000017, 0x000019C8, 0x00005A80, 0x00000B86, 0x000500C4, 0x00000017, + 0x00005DF8, 0x000019C8, 0x0000049D, 0x000500C5, 0x00000017, 0x0000466B, 0x0000466A, 0x00005DF8, + 0x000500C2, 0x00000017, 0x00005A81, 0x00002497, 0x000000B3, 0x000500C7, 0x00000017, 0x000019C9, + 0x00005A81, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DF9, 0x000019C9, 0x00000215, 0x000500C5, + 0x00000017, 0x0000466C, 0x0000466B, 0x00005DF9, 0x000500C2, 0x00000017, 0x00005A86, 0x00002497, + 0x0000018B, 0x000500C7, 0x00000017, 0x000019CA, 0x00005A86, 0x00000B86, 0x000500C4, 0x00000017, + 0x00005DFA, 0x000019CA, 0x00000575, 0x000500C5, 0x00000017, 0x0000466D, 0x0000466C, 0x00005DFA, + 0x000500C2, 0x00000017, 0x00005A87, 0x00002497, 0x0000007D, 0x000500C7, 0x00000017, 0x000018CF, + 0x00005A87, 0x00000B86, 0x000500C5, 0x00000017, 0x0000404A, 0x0000466D, 0x000018CF, 0x000500C2, + 0x00000017, 0x0000574A, 0x00002497, 0x00000155, 0x000500C7, 0x00000017, 0x000019CB, 0x0000574A, + 0x00000B86, 0x000500C4, 0x00000017, 0x00005E0B, 0x000019CB, 0x000002ED, 0x000500C5, 0x00000017, + 0x000044D9, 0x0000404A, 0x00005E0B, 0x000500C4, 0x00000017, 0x00001BCB, 0x000044D9, 0x00000B86, + 0x000500C5, 0x00000017, 0x00003E8C, 0x000044D9, 0x00001BCB, 0x000500C4, 0x00000017, 0x00005C91, + 0x00003E8C, 0x00000BBC, 0x000500C5, 0x00000017, 0x0000428F, 0x00003E8C, 0x00005C91, 0x00060041, + 0x00000294, 0x0000556E, 0x0000140E, 0x00000A0B, 0x00003FB1, 0x0003003E, 0x0000556E, 0x0000428F, + 0x00050080, 0x0000000B, 0x00002D19, 0x00003FB1, 0x00000A0D, 0x0009004F, 0x00000017, 0x00004ED9, + 0x00004D8D, 0x000000C8, 0x00000001, 0x00000001, 0x00000003, 0x00000003, 0x000500C2, 0x00000017, + 0x00004E61, 0x00004ED9, 0x0000011F, 0x000500C7, 0x00000017, 0x00001EE9, 0x00004E61, 0x00000B86, + 0x000500C4, 0x00000017, 0x0000604C, 0x00001EE9, 0x00000065, 0x000500C2, 0x00000017, 0x00005844, + 0x00004ED9, 0x000001F7, 0x000500C7, 0x00000017, 0x00005472, 0x00005844, 0x00000B86, 0x000500C4, + 0x00000017, 0x00005DFB, 0x00005472, 0x000003C5, 0x000500C5, 0x00000017, 0x0000466E, 0x0000604C, + 0x00005DFB, 0x000500C2, 0x00000017, 0x00005A88, 0x00004ED9, 0x000000E9, 0x000500C7, 0x00000017, + 0x000019CC, 0x00005A88, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DFC, 0x000019CC, 0x0000013D, + 0x000500C5, 0x00000017, 0x0000466F, 0x0000466E, 0x00005DFC, 0x000500C2, 0x00000017, 0x00005A89, + 0x00004ED9, 0x000001C1, 0x000500C7, 0x00000017, 0x000019CD, 0x00005A89, 0x00000B86, 0x000500C4, + 0x00000017, 0x00005DFD, 0x000019CD, 0x0000049D, 0x000500C5, 0x00000017, 0x00004670, 0x0000466F, + 0x00005DFD, 0x000500C2, 0x00000017, 0x00005A8A, 0x00004ED9, 0x000000B3, 0x000500C7, 0x00000017, + 0x000019CE, 0x00005A8A, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DFE, 0x000019CE, 0x00000215, + 0x000500C5, 0x00000017, 0x00004671, 0x00004670, 0x00005DFE, 0x000500C2, 0x00000017, 0x00005A8B, + 0x00004ED9, 0x0000018B, 0x000500C7, 0x00000017, 0x000019CF, 0x00005A8B, 0x00000B86, 0x000500C4, + 0x00000017, 0x00005DFF, 0x000019CF, 0x00000575, 0x000500C5, 0x00000017, 0x00004672, 0x00004671, + 0x00005DFF, 0x000500C2, 0x00000017, 0x00005A8C, 0x00004ED9, 0x0000007D, 0x000500C7, 0x00000017, + 0x000018D0, 0x00005A8C, 0x00000B86, 0x000500C5, 0x00000017, 0x0000404B, 0x00004672, 0x000018D0, + 0x000500C2, 0x00000017, 0x0000574B, 0x00004ED9, 0x00000155, 0x000500C7, 0x00000017, 0x000019D0, + 0x0000574B, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E0C, 0x000019D0, 0x000002ED, 0x000500C5, + 0x00000017, 0x000044DA, 0x0000404B, 0x00005E0C, 0x000500C4, 0x00000017, 0x00001BCC, 0x000044DA, + 0x00000B86, 0x000500C5, 0x00000017, 0x00003E8D, 0x000044DA, 0x00001BCC, 0x000500C4, 0x00000017, + 0x00005C92, 0x00003E8D, 0x00000BBC, 0x000500C5, 0x00000017, 0x00004290, 0x00003E8D, 0x00005C92, + 0x00060041, 0x00000294, 0x0000556F, 0x0000140E, 0x00000A0B, 0x00002D19, 0x0003003E, 0x0000556F, + 0x00004290, 0x00050080, 0x0000000B, 0x000039F9, 0x00003220, 0x00000A14, 0x000500B0, 0x00000009, + 0x00002E0C, 0x000039F9, 0x000019C2, 0x000300F7, 0x0000467D, 0x00000002, 0x000400FA, 0x00002E0C, + 0x000050CA, 0x0000467D, 0x000200F8, 0x000050CA, 0x00050080, 0x0000000B, 0x000035F5, 0x00003FB1, + 0x00001B41, 0x00050051, 0x0000000B, 0x00002831, 0x00005654, 0x00000001, 0x00050051, 0x0000000B, + 0x00002745, 0x00005654, 0x00000003, 0x00050051, 0x0000000B, 0x00001DDA, 0x00004D8D, 0x00000001, + 0x00050051, 0x0000000B, 0x000026FD, 0x00004D8D, 0x00000003, 0x00070050, 0x00000017, 0x00003BEA, + 0x00002831, 0x00002745, 0x00001DDA, 0x000026FD, 0x000500C2, 0x00000017, 0x00003148, 0x00003BEA, + 0x000002ED, 0x0009004F, 0x00000017, 0x0000598C, 0x00003148, 0x000000C8, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C2, 0x00000017, 0x0000233E, 0x0000598C, 0x0000011F, 0x000500C7, + 0x00000017, 0x00001EEA, 0x0000233E, 0x00000B86, 0x000500C4, 0x00000017, 0x0000604D, 0x00001EEA, + 0x00000065, 0x000500C2, 0x00000017, 0x00005845, 0x0000598C, 0x000001F7, 0x000500C7, 0x00000017, + 0x00005473, 0x00005845, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E00, 0x00005473, 0x000003C5, + 0x000500C5, 0x00000017, 0x00004673, 0x0000604D, 0x00005E00, 0x000500C2, 0x00000017, 0x00005A8D, + 0x0000598C, 0x000000E9, 0x000500C7, 0x00000017, 0x000019D1, 0x00005A8D, 0x00000B86, 0x000500C4, + 0x00000017, 0x00005E01, 0x000019D1, 0x0000013D, 0x000500C5, 0x00000017, 0x00004674, 0x00004673, + 0x00005E01, 0x000500C2, 0x00000017, 0x00005A8E, 0x0000598C, 0x000001C1, 0x000500C7, 0x00000017, + 0x000019D2, 0x00005A8E, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E02, 0x000019D2, 0x0000049D, + 0x000500C5, 0x00000017, 0x00004675, 0x00004674, 0x00005E02, 0x000500C2, 0x00000017, 0x00005A8F, + 0x0000598C, 0x000000B3, 0x000500C7, 0x00000017, 0x000019D3, 0x00005A8F, 0x00000B86, 0x000500C4, + 0x00000017, 0x00005E03, 0x000019D3, 0x00000215, 0x000500C5, 0x00000017, 0x00004676, 0x00004675, + 0x00005E03, 0x000500C2, 0x00000017, 0x00005A90, 0x0000598C, 0x0000018B, 0x000500C7, 0x00000017, + 0x000019D4, 0x00005A90, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E04, 0x000019D4, 0x00000575, + 0x000500C5, 0x00000017, 0x00004677, 0x00004676, 0x00005E04, 0x000500C2, 0x00000017, 0x00005A91, + 0x0000598C, 0x0000007D, 0x000500C7, 0x00000017, 0x000018D1, 0x00005A91, 0x00000B86, 0x000500C5, + 0x00000017, 0x0000404C, 0x00004677, 0x000018D1, 0x000500C2, 0x00000017, 0x0000574C, 0x0000598C, + 0x00000155, 0x000500C7, 0x00000017, 0x000019D5, 0x0000574C, 0x00000B86, 0x000500C4, 0x00000017, + 0x00005E0D, 0x000019D5, 0x000002ED, 0x000500C5, 0x00000017, 0x000044DB, 0x0000404C, 0x00005E0D, + 0x000500C4, 0x00000017, 0x00001BCD, 0x000044DB, 0x00000B86, 0x000500C5, 0x00000017, 0x00003E8E, + 0x000044DB, 0x00001BCD, 0x000500C4, 0x00000017, 0x00005C93, 0x00003E8E, 0x00000BBC, 0x000500C5, + 0x00000017, 0x00004291, 0x00003E8E, 0x00005C93, 0x00060041, 0x00000294, 0x00005570, 0x0000140E, + 0x00000A0B, 0x000035F5, 0x0003003E, 0x00005570, 0x00004291, 0x00050080, 0x0000000B, 0x00002D1A, + 0x000035F5, 0x00000A0D, 0x0009004F, 0x00000017, 0x00004EDA, 0x00003148, 0x000000C8, 0x00000002, + 0x00000002, 0x00000003, 0x00000003, 0x000500C2, 0x00000017, 0x00004E62, 0x00004EDA, 0x0000011F, + 0x000500C7, 0x00000017, 0x00001EEB, 0x00004E62, 0x00000B86, 0x000500C4, 0x00000017, 0x0000604E, + 0x00001EEB, 0x00000065, 0x000500C2, 0x00000017, 0x00005846, 0x00004EDA, 0x000001F7, 0x000500C7, + 0x00000017, 0x00005474, 0x00005846, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E05, 0x00005474, + 0x000003C5, 0x000500C5, 0x00000017, 0x00004678, 0x0000604E, 0x00005E05, 0x000500C2, 0x00000017, + 0x00005A92, 0x00004EDA, 0x000000E9, 0x000500C7, 0x00000017, 0x000019D6, 0x00005A92, 0x00000B86, + 0x000500C4, 0x00000017, 0x00005E06, 0x000019D6, 0x0000013D, 0x000500C5, 0x00000017, 0x00004679, + 0x00004678, 0x00005E06, 0x000500C2, 0x00000017, 0x00005A93, 0x00004EDA, 0x000001C1, 0x000500C7, + 0x00000017, 0x000019D7, 0x00005A93, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E0E, 0x000019D7, + 0x0000049D, 0x000500C5, 0x00000017, 0x0000467A, 0x00004679, 0x00005E0E, 0x000500C2, 0x00000017, + 0x00005A94, 0x00004EDA, 0x000000B3, 0x000500C7, 0x00000017, 0x000019D8, 0x00005A94, 0x00000B86, + 0x000500C4, 0x00000017, 0x00005E0F, 0x000019D8, 0x00000215, 0x000500C5, 0x00000017, 0x0000467B, + 0x0000467A, 0x00005E0F, 0x000500C2, 0x00000017, 0x00005A95, 0x00004EDA, 0x0000018B, 0x000500C7, + 0x00000017, 0x000019D9, 0x00005A95, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E10, 0x000019D9, + 0x00000575, 0x000500C5, 0x00000017, 0x0000467C, 0x0000467B, 0x00005E10, 0x000500C2, 0x00000017, + 0x00005A96, 0x00004EDA, 0x0000007D, 0x000500C7, 0x00000017, 0x000018D2, 0x00005A96, 0x00000B86, + 0x000500C5, 0x00000017, 0x0000404D, 0x0000467C, 0x000018D2, 0x000500C2, 0x00000017, 0x0000574D, + 0x00004EDA, 0x00000155, 0x000500C7, 0x00000017, 0x000019DA, 0x0000574D, 0x00000B86, 0x000500C4, + 0x00000017, 0x00005E11, 0x000019DA, 0x000002ED, 0x000500C5, 0x00000017, 0x000044DC, 0x0000404D, + 0x00005E11, 0x000500C4, 0x00000017, 0x00001BCE, 0x000044DC, 0x00000B86, 0x000500C5, 0x00000017, + 0x00003E8F, 0x000044DC, 0x00001BCE, 0x000500C4, 0x00000017, 0x00005C94, 0x00003E8F, 0x00000BBC, + 0x000500C5, 0x00000017, 0x00004292, 0x00003E8F, 0x00005C94, 0x00060041, 0x00000294, 0x00005E66, + 0x0000140E, 0x00000A0B, 0x00002D1A, 0x0003003E, 0x00005E66, 0x00004292, 0x000200F9, 0x0000467D, + 0x000200F8, 0x0000467D, 0x000200F9, 0x00001C25, 0x000200F8, 0x00001C25, 0x000200F9, 0x00001C26, + 0x000200F8, 0x00001C26, 0x000200F9, 0x00003A37, 0x000200F8, 0x00003A37, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_dxt3aas1111_bgra4_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_dxt3aas1111_bgra4_cs.h new file mode 100644 index 0000000..9f55594 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_dxt3aas1111_bgra4_cs.h @@ -0,0 +1,1119 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_3 = OpConstant %uint 3 + %uint_11 = OpConstant %uint 11 + %287 = OpConstantComposite %v4uint %uint_3 %uint_11 %uint_3 %uint_11 + %uint_1 = OpConstant %uint 1 + %uint_8 = OpConstant %uint 8 + %uint_7 = OpConstant %uint 7 + %uint_15 = OpConstant %uint 15 + %503 = OpConstantComposite %v4uint %uint_7 %uint_15 %uint_7 %uint_15 + %uint_24 = OpConstant %uint 24 + %uint_2 = OpConstant %uint 2 + %uint_10 = OpConstant %uint 10 + %233 = OpConstantComposite %v4uint %uint_2 %uint_10 %uint_2 %uint_10 + %uint_4 = OpConstant %uint 4 + %uint_6 = OpConstant %uint 6 + %uint_14 = OpConstant %uint 14 + %449 = OpConstantComposite %v4uint %uint_6 %uint_14 %uint_6 %uint_14 + %uint_20 = OpConstant %uint 20 + %uint_9 = OpConstant %uint 9 + %179 = OpConstantComposite %v4uint %uint_1 %uint_9 %uint_1 %uint_9 + %uint_5 = OpConstant %uint 5 + %uint_13 = OpConstant %uint 13 + %395 = OpConstantComposite %v4uint %uint_5 %uint_13 %uint_5 %uint_13 + %uint_16 = OpConstant %uint 16 + %uint_0 = OpConstant %uint 0 + %125 = OpConstantComposite %v4uint %uint_0 %uint_8 %uint_0 %uint_8 + %uint_12 = OpConstant %uint 12 + %341 = OpConstantComposite %v4uint %uint_4 %uint_12 %uint_4 %uint_12 + %uint_28 = OpConstant %uint 28 +%uint_16711935 = OpConstant %uint 16711935 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2596 = OpConstantComposite %v3uint %uint_2 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 + %2620 = OpConstantComposite %v3uint %uint_2 %uint_2 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform + %uint_32 = OpConstant %uint 32 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %2950 = OpConstantComposite %v4uint %uint_1 %uint_1 %uint_1 %uint_1 + %1181 = OpConstantComposite %v4uint %uint_24 %uint_24 %uint_24 %uint_24 + %101 = OpConstantComposite %v4uint %uint_4 %uint_4 %uint_4 %uint_4 + %965 = OpConstantComposite %v4uint %uint_20 %uint_20 %uint_20 %uint_20 + %533 = OpConstantComposite %v4uint %uint_12 %uint_12 %uint_12 %uint_12 + %1397 = OpConstantComposite %v4uint %uint_28 %uint_28 %uint_28 %uint_28 + %3004 = OpConstantComposite %v4uint %uint_2 %uint_2 %uint_2 %uint_2 + %200 = OpConstantNull %v2uint + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %14903 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20158 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %22412 = OpLoad %uint %20158 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_7 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2596 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %14018 DontFlatten + OpBranchConditional %24679 %21992 %14018 + %21992 = OpLabel + OpBranch %14903 + %14018 = OpLabel + %17344 = OpShiftLeftLogical %v3uint %21387 %2620 + %15489 = OpBitcast %v3int %17344 + %18336 = OpCompositeExtract %int %15489 0 + %9362 = OpIMul %int %18336 %int_2 + %6362 = OpCompositeExtract %int %15489 2 + %14505 = OpBitcast %int %6594 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %15489 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %22412 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %9362 %24535 + %10898 = OpBitcast %uint %8258 + %9077 = OpIAdd %uint %10898 %22411 + %11726 = OpShiftRightLogical %uint %9077 %uint_4 + %6977 = OpShiftRightLogical %uint %22412 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20009 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %21373 %6361 + %21373 = OpLabel + %10608 = OpBitcast %v3int %21387 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_9 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_9 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_9 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17091 = OpCompositeExtract %int %6573 0 + %9470 = OpShiftRightArithmetic %int %17091 %int_5 + %10056 = OpCompositeExtract %int %6573 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_10 + %10934 = OpBitwiseAnd %int %17091 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_3 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17091 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %21373 %12098 %6361 + OpBranch %24387 + %20009 = OpLabel + %24447 = OpBitcast %v3int %21387 + %8918 = OpCompositeExtract %int %24447 0 + %9363 = OpIMul %int %8918 %int_8 + %6363 = OpCompositeExtract %int %24447 2 + %14506 = OpBitcast %int %22409 + %11280 = OpIMul %int %6363 %14506 + %17599 = OpCompositeExtract %int %24447 1 + %22229 = OpIAdd %int %11280 %17599 + %22406 = OpBitcast %int %22408 + %7839 = OpIMul %int %22229 %22406 + %7984 = OpIAdd %int %9363 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20009 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %13392 None + OpBranchConditional %15139 %11064 %13392 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %13392 + %13392 = OpLabel + %22100 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %11876 = OpSelect %uint %17270 %uint_2 %uint_1 + %11339 = OpIAdd %uint %22117 %11876 + %18278 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %11339 + %6578 = OpLoad %v4uint %18278 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %13392 %16377 %10584 + OpSelectionMerge %11682 None + OpBranchConditional %15139 %11065 %11682 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11682 + %11682 = OpLabel + %19853 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %22133 = OpVectorShuffle %v4uint %22100 %200 0 0 2 2 + %14639 = OpShiftRightLogical %v4uint %22133 %287 + %7908 = OpBitwiseAnd %v4uint %14639 %2950 + %24647 = OpShiftLeftLogical %v4uint %7908 %317 + %22591 = OpShiftRightLogical %v4uint %22133 %503 + %21613 = OpBitwiseAnd %v4uint %22591 %2950 + %24033 = OpShiftLeftLogical %v4uint %21613 %1181 + %18005 = OpBitwiseOr %v4uint %24647 %24033 + %23151 = OpShiftRightLogical %v4uint %22133 %233 + %6577 = OpBitwiseAnd %v4uint %23151 %2950 + %24034 = OpShiftLeftLogical %v4uint %6577 %101 + %18006 = OpBitwiseOr %v4uint %18005 %24034 + %23152 = OpShiftRightLogical %v4uint %22133 %449 + %6579 = OpBitwiseAnd %v4uint %23152 %2950 + %24036 = OpShiftLeftLogical %v4uint %6579 %965 + %18007 = OpBitwiseOr %v4uint %18006 %24036 + %23170 = OpShiftRightLogical %v4uint %22133 %179 + %6347 = OpBitwiseAnd %v4uint %23170 %2950 + %16454 = OpBitwiseOr %v4uint %18007 %6347 + %22342 = OpShiftRightLogical %v4uint %22133 %395 + %6580 = OpBitwiseAnd %v4uint %22342 %2950 + %24037 = OpShiftLeftLogical %v4uint %6580 %749 + %18008 = OpBitwiseOr %v4uint %16454 %24037 + %23153 = OpShiftRightLogical %v4uint %22133 %125 + %6581 = OpBitwiseAnd %v4uint %23153 %2950 + %24038 = OpShiftLeftLogical %v4uint %6581 %533 + %18009 = OpBitwiseOr %v4uint %18008 %24038 + %23154 = OpShiftRightLogical %v4uint %22133 %341 + %6582 = OpBitwiseAnd %v4uint %23154 %2950 + %24071 = OpShiftLeftLogical %v4uint %6582 %1397 + %17621 = OpBitwiseOr %v4uint %18009 %24071 + %7111 = OpShiftLeftLogical %v4uint %17621 %2950 + %16008 = OpBitwiseOr %v4uint %17621 %7111 + %23693 = OpShiftLeftLogical %v4uint %16008 %3004 + %17035 = OpBitwiseOr %v4uint %16008 %23693 + %21867 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11726 + OpStore %21867 %17035 + %11543 = OpIAdd %uint %11726 %uint_1 + %20183 = OpVectorShuffle %v4uint %19853 %200 0 0 2 2 + %20062 = OpShiftRightLogical %v4uint %20183 %287 + %7909 = OpBitwiseAnd %v4uint %20062 %2950 + %24648 = OpShiftLeftLogical %v4uint %7909 %317 + %22592 = OpShiftRightLogical %v4uint %20183 %503 + %21614 = OpBitwiseAnd %v4uint %22592 %2950 + %24039 = OpShiftLeftLogical %v4uint %21614 %1181 + %18010 = OpBitwiseOr %v4uint %24648 %24039 + %23155 = OpShiftRightLogical %v4uint %20183 %233 + %6583 = OpBitwiseAnd %v4uint %23155 %2950 + %24040 = OpShiftLeftLogical %v4uint %6583 %101 + %18011 = OpBitwiseOr %v4uint %18010 %24040 + %23156 = OpShiftRightLogical %v4uint %20183 %449 + %6584 = OpBitwiseAnd %v4uint %23156 %2950 + %24041 = OpShiftLeftLogical %v4uint %6584 %965 + %18012 = OpBitwiseOr %v4uint %18011 %24041 + %23171 = OpShiftRightLogical %v4uint %20183 %179 + %6348 = OpBitwiseAnd %v4uint %23171 %2950 + %16455 = OpBitwiseOr %v4uint %18012 %6348 + %22343 = OpShiftRightLogical %v4uint %20183 %395 + %6585 = OpBitwiseAnd %v4uint %22343 %2950 + %24042 = OpShiftLeftLogical %v4uint %6585 %749 + %18013 = OpBitwiseOr %v4uint %16455 %24042 + %23157 = OpShiftRightLogical %v4uint %20183 %125 + %6586 = OpBitwiseAnd %v4uint %23157 %2950 + %24043 = OpShiftLeftLogical %v4uint %6586 %533 + %18014 = OpBitwiseOr %v4uint %18013 %24043 + %23158 = OpShiftRightLogical %v4uint %20183 %341 + %6587 = OpBitwiseAnd %v4uint %23158 %2950 + %24072 = OpShiftLeftLogical %v4uint %6587 %1397 + %17622 = OpBitwiseOr %v4uint %18014 %24072 + %7112 = OpShiftLeftLogical %v4uint %17622 %2950 + %16009 = OpBitwiseOr %v4uint %17622 %7112 + %23694 = OpShiftLeftLogical %v4uint %16009 %3004 + %17036 = OpBitwiseOr %v4uint %16009 %23694 + %20974 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11543 + OpStore %20974 %17036 + %12832 = OpCompositeExtract %uint %17344 1 + %23232 = OpIAdd %uint %12832 %int_1 + %17425 = OpULessThan %bool %23232 %6594 + OpSelectionMerge %7206 DontFlatten + OpBranchConditional %17425 %20681 %7206 + %20681 = OpLabel + %13812 = OpIAdd %uint %11726 %6977 + %10288 = OpCompositeExtract %uint %22100 0 + %10052 = OpCompositeExtract %uint %22100 2 + %7641 = OpCompositeExtract %uint %19853 0 + %9980 = OpCompositeExtract %uint %19853 2 + %15337 = OpCompositeConstruct %v4uint %10288 %10052 %7641 %9980 + %12615 = OpShiftRightLogical %v4uint %15337 %749 + %22923 = OpVectorShuffle %v4uint %12615 %200 0 0 1 1 + %9021 = OpShiftRightLogical %v4uint %22923 %287 + %7910 = OpBitwiseAnd %v4uint %9021 %2950 + %24649 = OpShiftLeftLogical %v4uint %7910 %317 + %22593 = OpShiftRightLogical %v4uint %22923 %503 + %21615 = OpBitwiseAnd %v4uint %22593 %2950 + %24044 = OpShiftLeftLogical %v4uint %21615 %1181 + %18015 = OpBitwiseOr %v4uint %24649 %24044 + %23159 = OpShiftRightLogical %v4uint %22923 %233 + %6588 = OpBitwiseAnd %v4uint %23159 %2950 + %24045 = OpShiftLeftLogical %v4uint %6588 %101 + %18016 = OpBitwiseOr %v4uint %18015 %24045 + %23160 = OpShiftRightLogical %v4uint %22923 %449 + %6589 = OpBitwiseAnd %v4uint %23160 %2950 + %24046 = OpShiftLeftLogical %v4uint %6589 %965 + %18017 = OpBitwiseOr %v4uint %18016 %24046 + %23172 = OpShiftRightLogical %v4uint %22923 %179 + %6349 = OpBitwiseAnd %v4uint %23172 %2950 + %16456 = OpBitwiseOr %v4uint %18017 %6349 + %22344 = OpShiftRightLogical %v4uint %22923 %395 + %6590 = OpBitwiseAnd %v4uint %22344 %2950 + %24047 = OpShiftLeftLogical %v4uint %6590 %749 + %18018 = OpBitwiseOr %v4uint %16456 %24047 + %23161 = OpShiftRightLogical %v4uint %22923 %125 + %6591 = OpBitwiseAnd %v4uint %23161 %2950 + %24048 = OpShiftLeftLogical %v4uint %6591 %533 + %18019 = OpBitwiseOr %v4uint %18018 %24048 + %23162 = OpShiftRightLogical %v4uint %22923 %341 + %6592 = OpBitwiseAnd %v4uint %23162 %2950 + %24073 = OpShiftLeftLogical %v4uint %6592 %1397 + %17623 = OpBitwiseOr %v4uint %18019 %24073 + %7113 = OpShiftLeftLogical %v4uint %17623 %2950 + %16010 = OpBitwiseOr %v4uint %17623 %7113 + %23695 = OpShiftLeftLogical %v4uint %16010 %3004 + %17037 = OpBitwiseOr %v4uint %16010 %23695 + %21868 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13812 + OpStore %21868 %17037 + %11544 = OpIAdd %uint %13812 %uint_1 + %20184 = OpVectorShuffle %v4uint %12615 %200 2 2 3 3 + %20063 = OpShiftRightLogical %v4uint %20184 %287 + %7911 = OpBitwiseAnd %v4uint %20063 %2950 + %24650 = OpShiftLeftLogical %v4uint %7911 %317 + %22594 = OpShiftRightLogical %v4uint %20184 %503 + %21616 = OpBitwiseAnd %v4uint %22594 %2950 + %24049 = OpShiftLeftLogical %v4uint %21616 %1181 + %18020 = OpBitwiseOr %v4uint %24650 %24049 + %23163 = OpShiftRightLogical %v4uint %20184 %233 + %6593 = OpBitwiseAnd %v4uint %23163 %2950 + %24050 = OpShiftLeftLogical %v4uint %6593 %101 + %18021 = OpBitwiseOr %v4uint %18020 %24050 + %23164 = OpShiftRightLogical %v4uint %20184 %449 + %6595 = OpBitwiseAnd %v4uint %23164 %2950 + %24051 = OpShiftLeftLogical %v4uint %6595 %965 + %18022 = OpBitwiseOr %v4uint %18021 %24051 + %23173 = OpShiftRightLogical %v4uint %20184 %179 + %6350 = OpBitwiseAnd %v4uint %23173 %2950 + %16457 = OpBitwiseOr %v4uint %18022 %6350 + %22345 = OpShiftRightLogical %v4uint %20184 %395 + %6596 = OpBitwiseAnd %v4uint %22345 %2950 + %24052 = OpShiftLeftLogical %v4uint %6596 %749 + %18023 = OpBitwiseOr %v4uint %16457 %24052 + %23165 = OpShiftRightLogical %v4uint %20184 %125 + %6597 = OpBitwiseAnd %v4uint %23165 %2950 + %24053 = OpShiftLeftLogical %v4uint %6597 %533 + %18024 = OpBitwiseOr %v4uint %18023 %24053 + %23166 = OpShiftRightLogical %v4uint %20184 %341 + %6598 = OpBitwiseAnd %v4uint %23166 %2950 + %24074 = OpShiftLeftLogical %v4uint %6598 %1397 + %17624 = OpBitwiseOr %v4uint %18024 %24074 + %7114 = OpShiftLeftLogical %v4uint %17624 %2950 + %16011 = OpBitwiseOr %v4uint %17624 %7114 + %23696 = OpShiftLeftLogical %v4uint %16011 %3004 + %17038 = OpBitwiseOr %v4uint %16011 %23696 + %21869 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11544 + OpStore %21869 %17038 + %14840 = OpIAdd %uint %12832 %int_2 + %11787 = OpULessThan %bool %14840 %6594 + OpSelectionMerge %7205 DontFlatten + OpBranchConditional %11787 %20643 %7205 + %20643 = OpLabel + %16305 = OpIAdd %uint %13812 %6977 + %9367 = OpVectorShuffle %v4uint %22100 %200 1 1 3 3 + %20064 = OpShiftRightLogical %v4uint %9367 %287 + %7912 = OpBitwiseAnd %v4uint %20064 %2950 + %24651 = OpShiftLeftLogical %v4uint %7912 %317 + %22595 = OpShiftRightLogical %v4uint %9367 %503 + %21617 = OpBitwiseAnd %v4uint %22595 %2950 + %24054 = OpShiftLeftLogical %v4uint %21617 %1181 + %18025 = OpBitwiseOr %v4uint %24651 %24054 + %23167 = OpShiftRightLogical %v4uint %9367 %233 + %6599 = OpBitwiseAnd %v4uint %23167 %2950 + %24055 = OpShiftLeftLogical %v4uint %6599 %101 + %18026 = OpBitwiseOr %v4uint %18025 %24055 + %23168 = OpShiftRightLogical %v4uint %9367 %449 + %6600 = OpBitwiseAnd %v4uint %23168 %2950 + %24056 = OpShiftLeftLogical %v4uint %6600 %965 + %18027 = OpBitwiseOr %v4uint %18026 %24056 + %23174 = OpShiftRightLogical %v4uint %9367 %179 + %6351 = OpBitwiseAnd %v4uint %23174 %2950 + %16458 = OpBitwiseOr %v4uint %18027 %6351 + %22346 = OpShiftRightLogical %v4uint %9367 %395 + %6601 = OpBitwiseAnd %v4uint %22346 %2950 + %24057 = OpShiftLeftLogical %v4uint %6601 %749 + %18028 = OpBitwiseOr %v4uint %16458 %24057 + %23169 = OpShiftRightLogical %v4uint %9367 %125 + %6602 = OpBitwiseAnd %v4uint %23169 %2950 + %24058 = OpShiftLeftLogical %v4uint %6602 %533 + %18029 = OpBitwiseOr %v4uint %18028 %24058 + %23175 = OpShiftRightLogical %v4uint %9367 %341 + %6603 = OpBitwiseAnd %v4uint %23175 %2950 + %24075 = OpShiftLeftLogical %v4uint %6603 %1397 + %17625 = OpBitwiseOr %v4uint %18029 %24075 + %7115 = OpShiftLeftLogical %v4uint %17625 %2950 + %16012 = OpBitwiseOr %v4uint %17625 %7115 + %23697 = OpShiftLeftLogical %v4uint %16012 %3004 + %17039 = OpBitwiseOr %v4uint %16012 %23697 + %21870 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %16305 + OpStore %21870 %17039 + %11545 = OpIAdd %uint %16305 %uint_1 + %20185 = OpVectorShuffle %v4uint %19853 %200 1 1 3 3 + %20065 = OpShiftRightLogical %v4uint %20185 %287 + %7913 = OpBitwiseAnd %v4uint %20065 %2950 + %24652 = OpShiftLeftLogical %v4uint %7913 %317 + %22596 = OpShiftRightLogical %v4uint %20185 %503 + %21618 = OpBitwiseAnd %v4uint %22596 %2950 + %24059 = OpShiftLeftLogical %v4uint %21618 %1181 + %18030 = OpBitwiseOr %v4uint %24652 %24059 + %23176 = OpShiftRightLogical %v4uint %20185 %233 + %6604 = OpBitwiseAnd %v4uint %23176 %2950 + %24060 = OpShiftLeftLogical %v4uint %6604 %101 + %18031 = OpBitwiseOr %v4uint %18030 %24060 + %23177 = OpShiftRightLogical %v4uint %20185 %449 + %6605 = OpBitwiseAnd %v4uint %23177 %2950 + %24061 = OpShiftLeftLogical %v4uint %6605 %965 + %18032 = OpBitwiseOr %v4uint %18031 %24061 + %23178 = OpShiftRightLogical %v4uint %20185 %179 + %6352 = OpBitwiseAnd %v4uint %23178 %2950 + %16459 = OpBitwiseOr %v4uint %18032 %6352 + %22347 = OpShiftRightLogical %v4uint %20185 %395 + %6606 = OpBitwiseAnd %v4uint %22347 %2950 + %24062 = OpShiftLeftLogical %v4uint %6606 %749 + %18033 = OpBitwiseOr %v4uint %16459 %24062 + %23179 = OpShiftRightLogical %v4uint %20185 %125 + %6607 = OpBitwiseAnd %v4uint %23179 %2950 + %24063 = OpShiftLeftLogical %v4uint %6607 %533 + %18034 = OpBitwiseOr %v4uint %18033 %24063 + %23180 = OpShiftRightLogical %v4uint %20185 %341 + %6608 = OpBitwiseAnd %v4uint %23180 %2950 + %24076 = OpShiftLeftLogical %v4uint %6608 %1397 + %17626 = OpBitwiseOr %v4uint %18034 %24076 + %7116 = OpShiftLeftLogical %v4uint %17626 %2950 + %16013 = OpBitwiseOr %v4uint %17626 %7116 + %23698 = OpShiftLeftLogical %v4uint %16013 %3004 + %17040 = OpBitwiseOr %v4uint %16013 %23698 + %21871 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11545 + OpStore %21871 %17040 + %14841 = OpIAdd %uint %12832 %int_3 + %11788 = OpULessThan %bool %14841 %6594 + OpSelectionMerge %18045 DontFlatten + OpBranchConditional %11788 %20682 %18045 + %20682 = OpLabel + %13813 = OpIAdd %uint %16305 %6977 + %10289 = OpCompositeExtract %uint %22100 1 + %10053 = OpCompositeExtract %uint %22100 3 + %7642 = OpCompositeExtract %uint %19853 1 + %9981 = OpCompositeExtract %uint %19853 3 + %15338 = OpCompositeConstruct %v4uint %10289 %10053 %7642 %9981 + %12616 = OpShiftRightLogical %v4uint %15338 %749 + %22924 = OpVectorShuffle %v4uint %12616 %200 0 0 1 1 + %9022 = OpShiftRightLogical %v4uint %22924 %287 + %7914 = OpBitwiseAnd %v4uint %9022 %2950 + %24653 = OpShiftLeftLogical %v4uint %7914 %317 + %22597 = OpShiftRightLogical %v4uint %22924 %503 + %21619 = OpBitwiseAnd %v4uint %22597 %2950 + %24064 = OpShiftLeftLogical %v4uint %21619 %1181 + %18035 = OpBitwiseOr %v4uint %24653 %24064 + %23181 = OpShiftRightLogical %v4uint %22924 %233 + %6609 = OpBitwiseAnd %v4uint %23181 %2950 + %24065 = OpShiftLeftLogical %v4uint %6609 %101 + %18036 = OpBitwiseOr %v4uint %18035 %24065 + %23182 = OpShiftRightLogical %v4uint %22924 %449 + %6610 = OpBitwiseAnd %v4uint %23182 %2950 + %24066 = OpShiftLeftLogical %v4uint %6610 %965 + %18037 = OpBitwiseOr %v4uint %18036 %24066 + %23183 = OpShiftRightLogical %v4uint %22924 %179 + %6353 = OpBitwiseAnd %v4uint %23183 %2950 + %16460 = OpBitwiseOr %v4uint %18037 %6353 + %22348 = OpShiftRightLogical %v4uint %22924 %395 + %6611 = OpBitwiseAnd %v4uint %22348 %2950 + %24067 = OpShiftLeftLogical %v4uint %6611 %749 + %18038 = OpBitwiseOr %v4uint %16460 %24067 + %23184 = OpShiftRightLogical %v4uint %22924 %125 + %6612 = OpBitwiseAnd %v4uint %23184 %2950 + %24068 = OpShiftLeftLogical %v4uint %6612 %533 + %18039 = OpBitwiseOr %v4uint %18038 %24068 + %23185 = OpShiftRightLogical %v4uint %22924 %341 + %6613 = OpBitwiseAnd %v4uint %23185 %2950 + %24077 = OpShiftLeftLogical %v4uint %6613 %1397 + %17627 = OpBitwiseOr %v4uint %18039 %24077 + %7117 = OpShiftLeftLogical %v4uint %17627 %2950 + %16014 = OpBitwiseOr %v4uint %17627 %7117 + %23699 = OpShiftLeftLogical %v4uint %16014 %3004 + %17041 = OpBitwiseOr %v4uint %16014 %23699 + %21872 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13813 + OpStore %21872 %17041 + %11546 = OpIAdd %uint %13813 %uint_1 + %20186 = OpVectorShuffle %v4uint %12616 %200 2 2 3 3 + %20066 = OpShiftRightLogical %v4uint %20186 %287 + %7915 = OpBitwiseAnd %v4uint %20066 %2950 + %24654 = OpShiftLeftLogical %v4uint %7915 %317 + %22598 = OpShiftRightLogical %v4uint %20186 %503 + %21620 = OpBitwiseAnd %v4uint %22598 %2950 + %24069 = OpShiftLeftLogical %v4uint %21620 %1181 + %18040 = OpBitwiseOr %v4uint %24654 %24069 + %23186 = OpShiftRightLogical %v4uint %20186 %233 + %6614 = OpBitwiseAnd %v4uint %23186 %2950 + %24070 = OpShiftLeftLogical %v4uint %6614 %101 + %18041 = OpBitwiseOr %v4uint %18040 %24070 + %23187 = OpShiftRightLogical %v4uint %20186 %449 + %6615 = OpBitwiseAnd %v4uint %23187 %2950 + %24078 = OpShiftLeftLogical %v4uint %6615 %965 + %18042 = OpBitwiseOr %v4uint %18041 %24078 + %23188 = OpShiftRightLogical %v4uint %20186 %179 + %6354 = OpBitwiseAnd %v4uint %23188 %2950 + %16461 = OpBitwiseOr %v4uint %18042 %6354 + %22349 = OpShiftRightLogical %v4uint %20186 %395 + %6616 = OpBitwiseAnd %v4uint %22349 %2950 + %24079 = OpShiftLeftLogical %v4uint %6616 %749 + %18043 = OpBitwiseOr %v4uint %16461 %24079 + %23189 = OpShiftRightLogical %v4uint %20186 %125 + %6617 = OpBitwiseAnd %v4uint %23189 %2950 + %24080 = OpShiftLeftLogical %v4uint %6617 %533 + %18044 = OpBitwiseOr %v4uint %18043 %24080 + %23190 = OpShiftRightLogical %v4uint %20186 %341 + %6618 = OpBitwiseAnd %v4uint %23190 %2950 + %24081 = OpShiftLeftLogical %v4uint %6618 %1397 + %17628 = OpBitwiseOr %v4uint %18044 %24081 + %7118 = OpShiftLeftLogical %v4uint %17628 %2950 + %16015 = OpBitwiseOr %v4uint %17628 %7118 + %23700 = OpShiftLeftLogical %v4uint %16015 %3004 + %17042 = OpBitwiseOr %v4uint %16015 %23700 + %24166 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11546 + OpStore %24166 %17042 + OpBranch %18045 + %18045 = OpLabel + OpBranch %7205 + %7205 = OpLabel + OpBranch %7206 + %7206 = OpLabel + OpBranch %14903 + %14903 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_dxt3aas1111_bgra4_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A2B, 0x0000000B, + 0x0007002C, 0x00000017, 0x0000011F, 0x00000A13, 0x00000A2B, 0x00000A13, 0x00000A2B, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, + 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, 0x0007002C, + 0x00000017, 0x000001F7, 0x00000A1F, 0x00000A37, 0x00000A1F, 0x00000A37, 0x0004002B, 0x0000000B, + 0x00000A52, 0x00000018, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, + 0x00000A28, 0x0000000A, 0x0007002C, 0x00000017, 0x000000E9, 0x00000A10, 0x00000A28, 0x00000A10, + 0x00000A28, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000B, 0x00000A1C, + 0x00000006, 0x0004002B, 0x0000000B, 0x00000A34, 0x0000000E, 0x0007002C, 0x00000017, 0x000001C1, + 0x00000A1C, 0x00000A34, 0x00000A1C, 0x00000A34, 0x0004002B, 0x0000000B, 0x00000A46, 0x00000014, + 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0007002C, 0x00000017, 0x000000B3, 0x00000A0D, + 0x00000A25, 0x00000A0D, 0x00000A25, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, + 0x0000000B, 0x00000A31, 0x0000000D, 0x0007002C, 0x00000017, 0x0000018B, 0x00000A19, 0x00000A31, + 0x00000A19, 0x00000A31, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, + 0x00000A0A, 0x00000000, 0x0007002C, 0x00000017, 0x0000007D, 0x00000A0A, 0x00000A22, 0x00000A0A, + 0x00000A22, 0x0004002B, 0x0000000B, 0x00000A2E, 0x0000000C, 0x0007002C, 0x00000017, 0x00000155, + 0x00000A16, 0x00000A2E, 0x00000A16, 0x00000A2E, 0x0004002B, 0x0000000B, 0x00000A5E, 0x0000001C, + 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, + 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, + 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, + 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x00040020, 0x00000291, + 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, + 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A24, 0x00000A10, 0x00000A0A, 0x00000A0A, + 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0006002C, 0x00000014, 0x00000A3C, 0x00000A10, + 0x00000A10, 0x00000A0A, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A32, 0x0000107A, 0x00000002, + 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, + 0x000007B5, 0x000007DD, 0x00040020, 0x00000A33, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A33, + 0x0000140E, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0006002C, 0x00000014, + 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, + 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, + 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, + 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, + 0x0007002C, 0x00000017, 0x00000B86, 0x00000A0D, 0x00000A0D, 0x00000A0D, 0x00000A0D, 0x0007002C, + 0x00000017, 0x0000049D, 0x00000A52, 0x00000A52, 0x00000A52, 0x00000A52, 0x0007002C, 0x00000017, + 0x00000065, 0x00000A16, 0x00000A16, 0x00000A16, 0x00000A16, 0x0007002C, 0x00000017, 0x000003C5, + 0x00000A46, 0x00000A46, 0x00000A46, 0x00000A46, 0x0007002C, 0x00000017, 0x00000215, 0x00000A2E, + 0x00000A2E, 0x00000A2E, 0x00000A2E, 0x0007002C, 0x00000017, 0x00000575, 0x00000A5E, 0x00000A5E, + 0x00000A5E, 0x00000A5E, 0x0007002C, 0x00000017, 0x00000BBC, 0x00000A10, 0x00000A10, 0x00000A10, + 0x00000A10, 0x0003002E, 0x00000011, 0x000000C8, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, + 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00003A37, 0x00000000, 0x000300FB, 0x00000A0A, + 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, + 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, + 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, + 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, + 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, + 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, + 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, + 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, + 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, + 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, + 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, + 0x00000288, 0x00004EBE, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x0000578C, 0x00004EBE, + 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A20, 0x0004003D, 0x0000000B, 0x000019C2, + 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, + 0x00002A0E, 0x00000A24, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, + 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, + 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, + 0x00004288, 0x000300F7, 0x000036C2, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000036C2, + 0x000200F8, 0x000055E8, 0x000200F9, 0x00003A37, 0x000200F8, 0x000036C2, 0x000500C4, 0x00000014, + 0x000043C0, 0x0000538B, 0x00000A3C, 0x0004007C, 0x00000016, 0x00003C81, 0x000043C0, 0x00050051, + 0x0000000C, 0x000047A0, 0x00003C81, 0x00000000, 0x00050084, 0x0000000C, 0x00002492, 0x000047A0, + 0x00000A11, 0x00050051, 0x0000000C, 0x000018DA, 0x00003C81, 0x00000002, 0x0004007C, 0x0000000C, + 0x000038A9, 0x000019C2, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, + 0x0000000C, 0x000044BE, 0x00003C81, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, + 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x0000578C, 0x00050084, 0x0000000C, 0x00005FD7, + 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x00002492, 0x00005FD7, 0x0004007C, + 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00002375, 0x00002A92, 0x0000578B, + 0x000500C2, 0x0000000B, 0x00002DCE, 0x00002375, 0x00000A16, 0x000500C2, 0x0000000B, 0x00001B41, + 0x0000578C, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, 0x00005768, + 0x00004E29, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, 0x00004384, + 0x0000537D, 0x000018D9, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, 0x00002970, 0x0000538B, + 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FD, + 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000002, 0x000500C3, + 0x0000000C, 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005789, + 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005321, + 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, 0x00005321, 0x000500C2, + 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, + 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, + 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, + 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, + 0x00000A25, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, + 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, + 0x000500C7, 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, + 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, + 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A25, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, + 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, + 0x000035A3, 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, + 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, + 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, + 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, + 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, + 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, + 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, + 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, + 0x0000000C, 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, + 0x00000A25, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, + 0x00004ADE, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, + 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, + 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, + 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, + 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, + 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, + 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, + 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, + 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, + 0x000054ED, 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, + 0x00000012, 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, 0x000042C3, 0x000019AD, 0x00000000, + 0x000500C3, 0x0000000C, 0x000024FE, 0x000042C3, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002748, + 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, 0x000500C2, + 0x0000000B, 0x00005B4E, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, + 0x00050084, 0x0000000C, 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, + 0x000024FE, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A28, 0x000500C7, + 0x0000000C, 0x00002AB6, 0x000042C3, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002748, + 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, + 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A13, + 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, + 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, + 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, + 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, + 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, + 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, 0x000500C4, + 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, + 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, + 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, + 0x000500C7, 0x0000000C, 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, + 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C3, 0x00000A14, 0x00050080, + 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, + 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, + 0x00050080, 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, + 0x00001E0B, 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, 0x0000537D, 0x00002F42, 0x000018D9, + 0x000200F9, 0x00005F43, 0x000200F8, 0x00004E29, 0x0004007C, 0x00000016, 0x00005F7F, 0x0000538B, + 0x00050051, 0x0000000C, 0x000022D6, 0x00005F7F, 0x00000000, 0x00050084, 0x0000000C, 0x00002493, + 0x000022D6, 0x00000A23, 0x00050051, 0x0000000C, 0x000018DB, 0x00005F7F, 0x00000002, 0x0004007C, + 0x0000000C, 0x000038AA, 0x00005789, 0x00050084, 0x0000000C, 0x00002C10, 0x000018DB, 0x000038AA, + 0x00050051, 0x0000000C, 0x000044BF, 0x00005F7F, 0x00000001, 0x00050080, 0x0000000C, 0x000056D5, + 0x00002C10, 0x000044BF, 0x0004007C, 0x0000000C, 0x00005786, 0x00005788, 0x00050084, 0x0000000C, + 0x00001E9F, 0x000056D5, 0x00005786, 0x00050080, 0x0000000C, 0x00001F30, 0x00002493, 0x00001E9F, + 0x000200F9, 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, + 0x00001E0B, 0x00001F30, 0x00004E29, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, + 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, + 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, 0x00004315, + 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004315, 0x000500AA, + 0x00000009, 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x000061E2, + 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, + 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, + 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, + 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, + 0x00005F43, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000061E2, 0x00000A13, + 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x00003450, 0x00000000, + 0x000400FA, 0x00003B23, 0x00002B38, 0x00003450, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, + 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, + 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x00003450, 0x000200F8, + 0x00003450, 0x000700F5, 0x00000017, 0x00005654, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, + 0x000600A9, 0x0000000B, 0x00002E64, 0x00004376, 0x00000A10, 0x00000A0D, 0x00050080, 0x0000000B, + 0x00002C4B, 0x00005665, 0x00002E64, 0x00060041, 0x00000294, 0x00004766, 0x0000107A, 0x00000A0B, + 0x00002C4B, 0x0004003D, 0x00000017, 0x000019B2, 0x00004766, 0x000300F7, 0x00003A1A, 0x00000000, + 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, + 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, + 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, + 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x00003450, + 0x00003FF9, 0x00002958, 0x000300F7, 0x00002DA2, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, + 0x00002DA2, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, + 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, + 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002DA2, 0x000200F8, 0x00002DA2, 0x000700F5, 0x00000017, + 0x00004D8D, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x0009004F, 0x00000017, 0x00005675, + 0x00005654, 0x000000C8, 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x000500C2, 0x00000017, + 0x0000392F, 0x00005675, 0x0000011F, 0x000500C7, 0x00000017, 0x00001EE4, 0x0000392F, 0x00000B86, + 0x000500C4, 0x00000017, 0x00006047, 0x00001EE4, 0x0000013D, 0x000500C2, 0x00000017, 0x0000583F, + 0x00005675, 0x000001F7, 0x000500C7, 0x00000017, 0x0000546D, 0x0000583F, 0x00000B86, 0x000500C4, + 0x00000017, 0x00005DE1, 0x0000546D, 0x0000049D, 0x000500C5, 0x00000017, 0x00004655, 0x00006047, + 0x00005DE1, 0x000500C2, 0x00000017, 0x00005A6F, 0x00005675, 0x000000E9, 0x000500C7, 0x00000017, + 0x000019B1, 0x00005A6F, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DE2, 0x000019B1, 0x00000065, + 0x000500C5, 0x00000017, 0x00004656, 0x00004655, 0x00005DE2, 0x000500C2, 0x00000017, 0x00005A70, + 0x00005675, 0x000001C1, 0x000500C7, 0x00000017, 0x000019B3, 0x00005A70, 0x00000B86, 0x000500C4, + 0x00000017, 0x00005DE4, 0x000019B3, 0x000003C5, 0x000500C5, 0x00000017, 0x00004657, 0x00004656, + 0x00005DE4, 0x000500C2, 0x00000017, 0x00005A82, 0x00005675, 0x000000B3, 0x000500C7, 0x00000017, + 0x000018CB, 0x00005A82, 0x00000B86, 0x000500C5, 0x00000017, 0x00004046, 0x00004657, 0x000018CB, + 0x000500C2, 0x00000017, 0x00005746, 0x00005675, 0x0000018B, 0x000500C7, 0x00000017, 0x000019B4, + 0x00005746, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DE5, 0x000019B4, 0x000002ED, 0x000500C5, + 0x00000017, 0x00004658, 0x00004046, 0x00005DE5, 0x000500C2, 0x00000017, 0x00005A71, 0x00005675, + 0x0000007D, 0x000500C7, 0x00000017, 0x000019B5, 0x00005A71, 0x00000B86, 0x000500C4, 0x00000017, + 0x00005DE6, 0x000019B5, 0x00000215, 0x000500C5, 0x00000017, 0x00004659, 0x00004658, 0x00005DE6, + 0x000500C2, 0x00000017, 0x00005A72, 0x00005675, 0x00000155, 0x000500C7, 0x00000017, 0x000019B6, + 0x00005A72, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E07, 0x000019B6, 0x00000575, 0x000500C5, + 0x00000017, 0x000044D5, 0x00004659, 0x00005E07, 0x000500C4, 0x00000017, 0x00001BC7, 0x000044D5, + 0x00000B86, 0x000500C5, 0x00000017, 0x00003E88, 0x000044D5, 0x00001BC7, 0x000500C4, 0x00000017, + 0x00005C8D, 0x00003E88, 0x00000BBC, 0x000500C5, 0x00000017, 0x0000428B, 0x00003E88, 0x00005C8D, + 0x00060041, 0x00000294, 0x0000556B, 0x0000140E, 0x00000A0B, 0x00002DCE, 0x0003003E, 0x0000556B, + 0x0000428B, 0x00050080, 0x0000000B, 0x00002D17, 0x00002DCE, 0x00000A0D, 0x0009004F, 0x00000017, + 0x00004ED7, 0x00004D8D, 0x000000C8, 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x000500C2, + 0x00000017, 0x00004E5E, 0x00004ED7, 0x0000011F, 0x000500C7, 0x00000017, 0x00001EE5, 0x00004E5E, + 0x00000B86, 0x000500C4, 0x00000017, 0x00006048, 0x00001EE5, 0x0000013D, 0x000500C2, 0x00000017, + 0x00005840, 0x00004ED7, 0x000001F7, 0x000500C7, 0x00000017, 0x0000546E, 0x00005840, 0x00000B86, + 0x000500C4, 0x00000017, 0x00005DE7, 0x0000546E, 0x0000049D, 0x000500C5, 0x00000017, 0x0000465A, + 0x00006048, 0x00005DE7, 0x000500C2, 0x00000017, 0x00005A73, 0x00004ED7, 0x000000E9, 0x000500C7, + 0x00000017, 0x000019B7, 0x00005A73, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DE8, 0x000019B7, + 0x00000065, 0x000500C5, 0x00000017, 0x0000465B, 0x0000465A, 0x00005DE8, 0x000500C2, 0x00000017, + 0x00005A74, 0x00004ED7, 0x000001C1, 0x000500C7, 0x00000017, 0x000019B8, 0x00005A74, 0x00000B86, + 0x000500C4, 0x00000017, 0x00005DE9, 0x000019B8, 0x000003C5, 0x000500C5, 0x00000017, 0x0000465C, + 0x0000465B, 0x00005DE9, 0x000500C2, 0x00000017, 0x00005A83, 0x00004ED7, 0x000000B3, 0x000500C7, + 0x00000017, 0x000018CC, 0x00005A83, 0x00000B86, 0x000500C5, 0x00000017, 0x00004047, 0x0000465C, + 0x000018CC, 0x000500C2, 0x00000017, 0x00005747, 0x00004ED7, 0x0000018B, 0x000500C7, 0x00000017, + 0x000019B9, 0x00005747, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DEA, 0x000019B9, 0x000002ED, + 0x000500C5, 0x00000017, 0x0000465D, 0x00004047, 0x00005DEA, 0x000500C2, 0x00000017, 0x00005A75, + 0x00004ED7, 0x0000007D, 0x000500C7, 0x00000017, 0x000019BA, 0x00005A75, 0x00000B86, 0x000500C4, + 0x00000017, 0x00005DEB, 0x000019BA, 0x00000215, 0x000500C5, 0x00000017, 0x0000465E, 0x0000465D, + 0x00005DEB, 0x000500C2, 0x00000017, 0x00005A76, 0x00004ED7, 0x00000155, 0x000500C7, 0x00000017, + 0x000019BB, 0x00005A76, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E08, 0x000019BB, 0x00000575, + 0x000500C5, 0x00000017, 0x000044D6, 0x0000465E, 0x00005E08, 0x000500C4, 0x00000017, 0x00001BC8, + 0x000044D6, 0x00000B86, 0x000500C5, 0x00000017, 0x00003E89, 0x000044D6, 0x00001BC8, 0x000500C4, + 0x00000017, 0x00005C8E, 0x00003E89, 0x00000BBC, 0x000500C5, 0x00000017, 0x0000428C, 0x00003E89, + 0x00005C8E, 0x00060041, 0x00000294, 0x000051EE, 0x0000140E, 0x00000A0B, 0x00002D17, 0x0003003E, + 0x000051EE, 0x0000428C, 0x00050051, 0x0000000B, 0x00003220, 0x000043C0, 0x00000001, 0x00050080, + 0x0000000B, 0x00005AC0, 0x00003220, 0x00000A0E, 0x000500B0, 0x00000009, 0x00004411, 0x00005AC0, + 0x000019C2, 0x000300F7, 0x00001C26, 0x00000002, 0x000400FA, 0x00004411, 0x000050C9, 0x00001C26, + 0x000200F8, 0x000050C9, 0x00050080, 0x0000000B, 0x000035F4, 0x00002DCE, 0x00001B41, 0x00050051, + 0x0000000B, 0x00002830, 0x00005654, 0x00000000, 0x00050051, 0x0000000B, 0x00002744, 0x00005654, + 0x00000002, 0x00050051, 0x0000000B, 0x00001DD9, 0x00004D8D, 0x00000000, 0x00050051, 0x0000000B, + 0x000026FC, 0x00004D8D, 0x00000002, 0x00070050, 0x00000017, 0x00003BE9, 0x00002830, 0x00002744, + 0x00001DD9, 0x000026FC, 0x000500C2, 0x00000017, 0x00003147, 0x00003BE9, 0x000002ED, 0x0009004F, + 0x00000017, 0x0000598B, 0x00003147, 0x000000C8, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C2, 0x00000017, 0x0000233D, 0x0000598B, 0x0000011F, 0x000500C7, 0x00000017, 0x00001EE6, + 0x0000233D, 0x00000B86, 0x000500C4, 0x00000017, 0x00006049, 0x00001EE6, 0x0000013D, 0x000500C2, + 0x00000017, 0x00005841, 0x0000598B, 0x000001F7, 0x000500C7, 0x00000017, 0x0000546F, 0x00005841, + 0x00000B86, 0x000500C4, 0x00000017, 0x00005DEC, 0x0000546F, 0x0000049D, 0x000500C5, 0x00000017, + 0x0000465F, 0x00006049, 0x00005DEC, 0x000500C2, 0x00000017, 0x00005A77, 0x0000598B, 0x000000E9, + 0x000500C7, 0x00000017, 0x000019BC, 0x00005A77, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DED, + 0x000019BC, 0x00000065, 0x000500C5, 0x00000017, 0x00004660, 0x0000465F, 0x00005DED, 0x000500C2, + 0x00000017, 0x00005A78, 0x0000598B, 0x000001C1, 0x000500C7, 0x00000017, 0x000019BD, 0x00005A78, + 0x00000B86, 0x000500C4, 0x00000017, 0x00005DEE, 0x000019BD, 0x000003C5, 0x000500C5, 0x00000017, + 0x00004661, 0x00004660, 0x00005DEE, 0x000500C2, 0x00000017, 0x00005A84, 0x0000598B, 0x000000B3, + 0x000500C7, 0x00000017, 0x000018CD, 0x00005A84, 0x00000B86, 0x000500C5, 0x00000017, 0x00004048, + 0x00004661, 0x000018CD, 0x000500C2, 0x00000017, 0x00005748, 0x0000598B, 0x0000018B, 0x000500C7, + 0x00000017, 0x000019BE, 0x00005748, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DEF, 0x000019BE, + 0x000002ED, 0x000500C5, 0x00000017, 0x00004662, 0x00004048, 0x00005DEF, 0x000500C2, 0x00000017, + 0x00005A79, 0x0000598B, 0x0000007D, 0x000500C7, 0x00000017, 0x000019BF, 0x00005A79, 0x00000B86, + 0x000500C4, 0x00000017, 0x00005DF0, 0x000019BF, 0x00000215, 0x000500C5, 0x00000017, 0x00004663, + 0x00004662, 0x00005DF0, 0x000500C2, 0x00000017, 0x00005A7A, 0x0000598B, 0x00000155, 0x000500C7, + 0x00000017, 0x000019C0, 0x00005A7A, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E09, 0x000019C0, + 0x00000575, 0x000500C5, 0x00000017, 0x000044D7, 0x00004663, 0x00005E09, 0x000500C4, 0x00000017, + 0x00001BC9, 0x000044D7, 0x00000B86, 0x000500C5, 0x00000017, 0x00003E8A, 0x000044D7, 0x00001BC9, + 0x000500C4, 0x00000017, 0x00005C8F, 0x00003E8A, 0x00000BBC, 0x000500C5, 0x00000017, 0x0000428D, + 0x00003E8A, 0x00005C8F, 0x00060041, 0x00000294, 0x0000556C, 0x0000140E, 0x00000A0B, 0x000035F4, + 0x0003003E, 0x0000556C, 0x0000428D, 0x00050080, 0x0000000B, 0x00002D18, 0x000035F4, 0x00000A0D, + 0x0009004F, 0x00000017, 0x00004ED8, 0x00003147, 0x000000C8, 0x00000002, 0x00000002, 0x00000003, + 0x00000003, 0x000500C2, 0x00000017, 0x00004E5F, 0x00004ED8, 0x0000011F, 0x000500C7, 0x00000017, + 0x00001EE7, 0x00004E5F, 0x00000B86, 0x000500C4, 0x00000017, 0x0000604A, 0x00001EE7, 0x0000013D, + 0x000500C2, 0x00000017, 0x00005842, 0x00004ED8, 0x000001F7, 0x000500C7, 0x00000017, 0x00005470, + 0x00005842, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DF1, 0x00005470, 0x0000049D, 0x000500C5, + 0x00000017, 0x00004664, 0x0000604A, 0x00005DF1, 0x000500C2, 0x00000017, 0x00005A7B, 0x00004ED8, + 0x000000E9, 0x000500C7, 0x00000017, 0x000019C1, 0x00005A7B, 0x00000B86, 0x000500C4, 0x00000017, + 0x00005DF2, 0x000019C1, 0x00000065, 0x000500C5, 0x00000017, 0x00004665, 0x00004664, 0x00005DF2, + 0x000500C2, 0x00000017, 0x00005A7C, 0x00004ED8, 0x000001C1, 0x000500C7, 0x00000017, 0x000019C3, + 0x00005A7C, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DF3, 0x000019C3, 0x000003C5, 0x000500C5, + 0x00000017, 0x00004666, 0x00004665, 0x00005DF3, 0x000500C2, 0x00000017, 0x00005A85, 0x00004ED8, + 0x000000B3, 0x000500C7, 0x00000017, 0x000018CE, 0x00005A85, 0x00000B86, 0x000500C5, 0x00000017, + 0x00004049, 0x00004666, 0x000018CE, 0x000500C2, 0x00000017, 0x00005749, 0x00004ED8, 0x0000018B, + 0x000500C7, 0x00000017, 0x000019C4, 0x00005749, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DF4, + 0x000019C4, 0x000002ED, 0x000500C5, 0x00000017, 0x00004667, 0x00004049, 0x00005DF4, 0x000500C2, + 0x00000017, 0x00005A7D, 0x00004ED8, 0x0000007D, 0x000500C7, 0x00000017, 0x000019C5, 0x00005A7D, + 0x00000B86, 0x000500C4, 0x00000017, 0x00005DF5, 0x000019C5, 0x00000215, 0x000500C5, 0x00000017, + 0x00004668, 0x00004667, 0x00005DF5, 0x000500C2, 0x00000017, 0x00005A7E, 0x00004ED8, 0x00000155, + 0x000500C7, 0x00000017, 0x000019C6, 0x00005A7E, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E0A, + 0x000019C6, 0x00000575, 0x000500C5, 0x00000017, 0x000044D8, 0x00004668, 0x00005E0A, 0x000500C4, + 0x00000017, 0x00001BCA, 0x000044D8, 0x00000B86, 0x000500C5, 0x00000017, 0x00003E8B, 0x000044D8, + 0x00001BCA, 0x000500C4, 0x00000017, 0x00005C90, 0x00003E8B, 0x00000BBC, 0x000500C5, 0x00000017, + 0x0000428E, 0x00003E8B, 0x00005C90, 0x00060041, 0x00000294, 0x0000556D, 0x0000140E, 0x00000A0B, + 0x00002D18, 0x0003003E, 0x0000556D, 0x0000428E, 0x00050080, 0x0000000B, 0x000039F8, 0x00003220, + 0x00000A11, 0x000500B0, 0x00000009, 0x00002E0B, 0x000039F8, 0x000019C2, 0x000300F7, 0x00001C25, + 0x00000002, 0x000400FA, 0x00002E0B, 0x000050A3, 0x00001C25, 0x000200F8, 0x000050A3, 0x00050080, + 0x0000000B, 0x00003FB1, 0x000035F4, 0x00001B41, 0x0009004F, 0x00000017, 0x00002497, 0x00005654, + 0x000000C8, 0x00000001, 0x00000001, 0x00000003, 0x00000003, 0x000500C2, 0x00000017, 0x00004E60, + 0x00002497, 0x0000011F, 0x000500C7, 0x00000017, 0x00001EE8, 0x00004E60, 0x00000B86, 0x000500C4, + 0x00000017, 0x0000604B, 0x00001EE8, 0x0000013D, 0x000500C2, 0x00000017, 0x00005843, 0x00002497, + 0x000001F7, 0x000500C7, 0x00000017, 0x00005471, 0x00005843, 0x00000B86, 0x000500C4, 0x00000017, + 0x00005DF6, 0x00005471, 0x0000049D, 0x000500C5, 0x00000017, 0x00004669, 0x0000604B, 0x00005DF6, + 0x000500C2, 0x00000017, 0x00005A7F, 0x00002497, 0x000000E9, 0x000500C7, 0x00000017, 0x000019C7, + 0x00005A7F, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DF7, 0x000019C7, 0x00000065, 0x000500C5, + 0x00000017, 0x0000466A, 0x00004669, 0x00005DF7, 0x000500C2, 0x00000017, 0x00005A80, 0x00002497, + 0x000001C1, 0x000500C7, 0x00000017, 0x000019C8, 0x00005A80, 0x00000B86, 0x000500C4, 0x00000017, + 0x00005DF8, 0x000019C8, 0x000003C5, 0x000500C5, 0x00000017, 0x0000466B, 0x0000466A, 0x00005DF8, + 0x000500C2, 0x00000017, 0x00005A86, 0x00002497, 0x000000B3, 0x000500C7, 0x00000017, 0x000018CF, + 0x00005A86, 0x00000B86, 0x000500C5, 0x00000017, 0x0000404A, 0x0000466B, 0x000018CF, 0x000500C2, + 0x00000017, 0x0000574A, 0x00002497, 0x0000018B, 0x000500C7, 0x00000017, 0x000019C9, 0x0000574A, + 0x00000B86, 0x000500C4, 0x00000017, 0x00005DF9, 0x000019C9, 0x000002ED, 0x000500C5, 0x00000017, + 0x0000466C, 0x0000404A, 0x00005DF9, 0x000500C2, 0x00000017, 0x00005A81, 0x00002497, 0x0000007D, + 0x000500C7, 0x00000017, 0x000019CA, 0x00005A81, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DFA, + 0x000019CA, 0x00000215, 0x000500C5, 0x00000017, 0x0000466D, 0x0000466C, 0x00005DFA, 0x000500C2, + 0x00000017, 0x00005A87, 0x00002497, 0x00000155, 0x000500C7, 0x00000017, 0x000019CB, 0x00005A87, + 0x00000B86, 0x000500C4, 0x00000017, 0x00005E0B, 0x000019CB, 0x00000575, 0x000500C5, 0x00000017, + 0x000044D9, 0x0000466D, 0x00005E0B, 0x000500C4, 0x00000017, 0x00001BCB, 0x000044D9, 0x00000B86, + 0x000500C5, 0x00000017, 0x00003E8C, 0x000044D9, 0x00001BCB, 0x000500C4, 0x00000017, 0x00005C91, + 0x00003E8C, 0x00000BBC, 0x000500C5, 0x00000017, 0x0000428F, 0x00003E8C, 0x00005C91, 0x00060041, + 0x00000294, 0x0000556E, 0x0000140E, 0x00000A0B, 0x00003FB1, 0x0003003E, 0x0000556E, 0x0000428F, + 0x00050080, 0x0000000B, 0x00002D19, 0x00003FB1, 0x00000A0D, 0x0009004F, 0x00000017, 0x00004ED9, + 0x00004D8D, 0x000000C8, 0x00000001, 0x00000001, 0x00000003, 0x00000003, 0x000500C2, 0x00000017, + 0x00004E61, 0x00004ED9, 0x0000011F, 0x000500C7, 0x00000017, 0x00001EE9, 0x00004E61, 0x00000B86, + 0x000500C4, 0x00000017, 0x0000604C, 0x00001EE9, 0x0000013D, 0x000500C2, 0x00000017, 0x00005844, + 0x00004ED9, 0x000001F7, 0x000500C7, 0x00000017, 0x00005472, 0x00005844, 0x00000B86, 0x000500C4, + 0x00000017, 0x00005DFB, 0x00005472, 0x0000049D, 0x000500C5, 0x00000017, 0x0000466E, 0x0000604C, + 0x00005DFB, 0x000500C2, 0x00000017, 0x00005A88, 0x00004ED9, 0x000000E9, 0x000500C7, 0x00000017, + 0x000019CC, 0x00005A88, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DFC, 0x000019CC, 0x00000065, + 0x000500C5, 0x00000017, 0x0000466F, 0x0000466E, 0x00005DFC, 0x000500C2, 0x00000017, 0x00005A89, + 0x00004ED9, 0x000001C1, 0x000500C7, 0x00000017, 0x000019CD, 0x00005A89, 0x00000B86, 0x000500C4, + 0x00000017, 0x00005DFD, 0x000019CD, 0x000003C5, 0x000500C5, 0x00000017, 0x00004670, 0x0000466F, + 0x00005DFD, 0x000500C2, 0x00000017, 0x00005A8A, 0x00004ED9, 0x000000B3, 0x000500C7, 0x00000017, + 0x000018D0, 0x00005A8A, 0x00000B86, 0x000500C5, 0x00000017, 0x0000404B, 0x00004670, 0x000018D0, + 0x000500C2, 0x00000017, 0x0000574B, 0x00004ED9, 0x0000018B, 0x000500C7, 0x00000017, 0x000019CE, + 0x0000574B, 0x00000B86, 0x000500C4, 0x00000017, 0x00005DFE, 0x000019CE, 0x000002ED, 0x000500C5, + 0x00000017, 0x00004671, 0x0000404B, 0x00005DFE, 0x000500C2, 0x00000017, 0x00005A8B, 0x00004ED9, + 0x0000007D, 0x000500C7, 0x00000017, 0x000019CF, 0x00005A8B, 0x00000B86, 0x000500C4, 0x00000017, + 0x00005DFF, 0x000019CF, 0x00000215, 0x000500C5, 0x00000017, 0x00004672, 0x00004671, 0x00005DFF, + 0x000500C2, 0x00000017, 0x00005A8C, 0x00004ED9, 0x00000155, 0x000500C7, 0x00000017, 0x000019D0, + 0x00005A8C, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E0C, 0x000019D0, 0x00000575, 0x000500C5, + 0x00000017, 0x000044DA, 0x00004672, 0x00005E0C, 0x000500C4, 0x00000017, 0x00001BCC, 0x000044DA, + 0x00000B86, 0x000500C5, 0x00000017, 0x00003E8D, 0x000044DA, 0x00001BCC, 0x000500C4, 0x00000017, + 0x00005C92, 0x00003E8D, 0x00000BBC, 0x000500C5, 0x00000017, 0x00004290, 0x00003E8D, 0x00005C92, + 0x00060041, 0x00000294, 0x0000556F, 0x0000140E, 0x00000A0B, 0x00002D19, 0x0003003E, 0x0000556F, + 0x00004290, 0x00050080, 0x0000000B, 0x000039F9, 0x00003220, 0x00000A14, 0x000500B0, 0x00000009, + 0x00002E0C, 0x000039F9, 0x000019C2, 0x000300F7, 0x0000467D, 0x00000002, 0x000400FA, 0x00002E0C, + 0x000050CA, 0x0000467D, 0x000200F8, 0x000050CA, 0x00050080, 0x0000000B, 0x000035F5, 0x00003FB1, + 0x00001B41, 0x00050051, 0x0000000B, 0x00002831, 0x00005654, 0x00000001, 0x00050051, 0x0000000B, + 0x00002745, 0x00005654, 0x00000003, 0x00050051, 0x0000000B, 0x00001DDA, 0x00004D8D, 0x00000001, + 0x00050051, 0x0000000B, 0x000026FD, 0x00004D8D, 0x00000003, 0x00070050, 0x00000017, 0x00003BEA, + 0x00002831, 0x00002745, 0x00001DDA, 0x000026FD, 0x000500C2, 0x00000017, 0x00003148, 0x00003BEA, + 0x000002ED, 0x0009004F, 0x00000017, 0x0000598C, 0x00003148, 0x000000C8, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x000500C2, 0x00000017, 0x0000233E, 0x0000598C, 0x0000011F, 0x000500C7, + 0x00000017, 0x00001EEA, 0x0000233E, 0x00000B86, 0x000500C4, 0x00000017, 0x0000604D, 0x00001EEA, + 0x0000013D, 0x000500C2, 0x00000017, 0x00005845, 0x0000598C, 0x000001F7, 0x000500C7, 0x00000017, + 0x00005473, 0x00005845, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E00, 0x00005473, 0x0000049D, + 0x000500C5, 0x00000017, 0x00004673, 0x0000604D, 0x00005E00, 0x000500C2, 0x00000017, 0x00005A8D, + 0x0000598C, 0x000000E9, 0x000500C7, 0x00000017, 0x000019D1, 0x00005A8D, 0x00000B86, 0x000500C4, + 0x00000017, 0x00005E01, 0x000019D1, 0x00000065, 0x000500C5, 0x00000017, 0x00004674, 0x00004673, + 0x00005E01, 0x000500C2, 0x00000017, 0x00005A8E, 0x0000598C, 0x000001C1, 0x000500C7, 0x00000017, + 0x000019D2, 0x00005A8E, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E02, 0x000019D2, 0x000003C5, + 0x000500C5, 0x00000017, 0x00004675, 0x00004674, 0x00005E02, 0x000500C2, 0x00000017, 0x00005A8F, + 0x0000598C, 0x000000B3, 0x000500C7, 0x00000017, 0x000018D1, 0x00005A8F, 0x00000B86, 0x000500C5, + 0x00000017, 0x0000404C, 0x00004675, 0x000018D1, 0x000500C2, 0x00000017, 0x0000574C, 0x0000598C, + 0x0000018B, 0x000500C7, 0x00000017, 0x000019D3, 0x0000574C, 0x00000B86, 0x000500C4, 0x00000017, + 0x00005E03, 0x000019D3, 0x000002ED, 0x000500C5, 0x00000017, 0x00004676, 0x0000404C, 0x00005E03, + 0x000500C2, 0x00000017, 0x00005A90, 0x0000598C, 0x0000007D, 0x000500C7, 0x00000017, 0x000019D4, + 0x00005A90, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E04, 0x000019D4, 0x00000215, 0x000500C5, + 0x00000017, 0x00004677, 0x00004676, 0x00005E04, 0x000500C2, 0x00000017, 0x00005A91, 0x0000598C, + 0x00000155, 0x000500C7, 0x00000017, 0x000019D5, 0x00005A91, 0x00000B86, 0x000500C4, 0x00000017, + 0x00005E0D, 0x000019D5, 0x00000575, 0x000500C5, 0x00000017, 0x000044DB, 0x00004677, 0x00005E0D, + 0x000500C4, 0x00000017, 0x00001BCD, 0x000044DB, 0x00000B86, 0x000500C5, 0x00000017, 0x00003E8E, + 0x000044DB, 0x00001BCD, 0x000500C4, 0x00000017, 0x00005C93, 0x00003E8E, 0x00000BBC, 0x000500C5, + 0x00000017, 0x00004291, 0x00003E8E, 0x00005C93, 0x00060041, 0x00000294, 0x00005570, 0x0000140E, + 0x00000A0B, 0x000035F5, 0x0003003E, 0x00005570, 0x00004291, 0x00050080, 0x0000000B, 0x00002D1A, + 0x000035F5, 0x00000A0D, 0x0009004F, 0x00000017, 0x00004EDA, 0x00003148, 0x000000C8, 0x00000002, + 0x00000002, 0x00000003, 0x00000003, 0x000500C2, 0x00000017, 0x00004E62, 0x00004EDA, 0x0000011F, + 0x000500C7, 0x00000017, 0x00001EEB, 0x00004E62, 0x00000B86, 0x000500C4, 0x00000017, 0x0000604E, + 0x00001EEB, 0x0000013D, 0x000500C2, 0x00000017, 0x00005846, 0x00004EDA, 0x000001F7, 0x000500C7, + 0x00000017, 0x00005474, 0x00005846, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E05, 0x00005474, + 0x0000049D, 0x000500C5, 0x00000017, 0x00004678, 0x0000604E, 0x00005E05, 0x000500C2, 0x00000017, + 0x00005A92, 0x00004EDA, 0x000000E9, 0x000500C7, 0x00000017, 0x000019D6, 0x00005A92, 0x00000B86, + 0x000500C4, 0x00000017, 0x00005E06, 0x000019D6, 0x00000065, 0x000500C5, 0x00000017, 0x00004679, + 0x00004678, 0x00005E06, 0x000500C2, 0x00000017, 0x00005A93, 0x00004EDA, 0x000001C1, 0x000500C7, + 0x00000017, 0x000019D7, 0x00005A93, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E0E, 0x000019D7, + 0x000003C5, 0x000500C5, 0x00000017, 0x0000467A, 0x00004679, 0x00005E0E, 0x000500C2, 0x00000017, + 0x00005A94, 0x00004EDA, 0x000000B3, 0x000500C7, 0x00000017, 0x000018D2, 0x00005A94, 0x00000B86, + 0x000500C5, 0x00000017, 0x0000404D, 0x0000467A, 0x000018D2, 0x000500C2, 0x00000017, 0x0000574D, + 0x00004EDA, 0x0000018B, 0x000500C7, 0x00000017, 0x000019D8, 0x0000574D, 0x00000B86, 0x000500C4, + 0x00000017, 0x00005E0F, 0x000019D8, 0x000002ED, 0x000500C5, 0x00000017, 0x0000467B, 0x0000404D, + 0x00005E0F, 0x000500C2, 0x00000017, 0x00005A95, 0x00004EDA, 0x0000007D, 0x000500C7, 0x00000017, + 0x000019D9, 0x00005A95, 0x00000B86, 0x000500C4, 0x00000017, 0x00005E10, 0x000019D9, 0x00000215, + 0x000500C5, 0x00000017, 0x0000467C, 0x0000467B, 0x00005E10, 0x000500C2, 0x00000017, 0x00005A96, + 0x00004EDA, 0x00000155, 0x000500C7, 0x00000017, 0x000019DA, 0x00005A96, 0x00000B86, 0x000500C4, + 0x00000017, 0x00005E11, 0x000019DA, 0x00000575, 0x000500C5, 0x00000017, 0x000044DC, 0x0000467C, + 0x00005E11, 0x000500C4, 0x00000017, 0x00001BCE, 0x000044DC, 0x00000B86, 0x000500C5, 0x00000017, + 0x00003E8F, 0x000044DC, 0x00001BCE, 0x000500C4, 0x00000017, 0x00005C94, 0x00003E8F, 0x00000BBC, + 0x000500C5, 0x00000017, 0x00004292, 0x00003E8F, 0x00005C94, 0x00060041, 0x00000294, 0x00005E66, + 0x0000140E, 0x00000A0B, 0x00002D1A, 0x0003003E, 0x00005E66, 0x00004292, 0x000200F9, 0x0000467D, + 0x000200F8, 0x0000467D, 0x000200F9, 0x00001C25, 0x000200F8, 0x00001C25, 0x000200F9, 0x00001C26, + 0x000200F8, 0x00001C26, 0x000200F9, 0x00003A37, 0x000200F8, 0x00003A37, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_dxt5_rgba8_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_dxt5_rgba8_cs.h new file mode 100644 index 0000000..2986f13 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_dxt5_rgba8_cs.h @@ -0,0 +1,2921 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25244 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_3 = OpConstant %uint 3 + %uint_13 = OpConstant %uint 13 + %uint_248 = OpConstant %uint 248 + %uint_7 = OpConstant %uint 7 + %uint_9 = OpConstant %uint 9 +%uint_258048 = OpConstant %uint 258048 + %uint_12 = OpConstant %uint 12 + %uint_4 = OpConstant %uint 4 +%uint_260046848 = OpConstant %uint 260046848 + %uint_5 = OpConstant %uint 5 +%uint_7340039 = OpConstant %uint 7340039 + %uint_6 = OpConstant %uint 6 + %uint_3072 = OpConstant %uint 3072 +%uint_1431655765 = OpConstant %uint 1431655765 + %uint_1 = OpConstant %uint 1 +%uint_2863311530 = OpConstant %uint 2863311530 + %uint_0 = OpConstant %uint 0 + %uint_2 = OpConstant %uint 2 + %77 = OpConstantComposite %v4uint %uint_0 %uint_2 %uint_4 %uint_6 + %uint_1023 = OpConstant %uint 1023 + %uint_16 = OpConstant %uint 16 + %uint_10 = OpConstant %uint 10 + %uint_8 = OpConstant %uint 8 + %uint_20 = OpConstant %uint 20 +%uint_2396745 = OpConstant %uint 2396745 +%uint_4793490 = OpConstant %uint 4793490 +%uint_9586980 = OpConstant %uint 9586980 +%uint_14380470 = OpConstant %uint 14380470 + %uint_24 = OpConstant %uint 24 + %uint_1170 = OpConstant %uint 1170 + %uint_2340 = OpConstant %uint 2340 + %uint_2925 = OpConstant %uint 2925 + %uint_64 = OpConstant %uint 64 + %uint_512 = OpConstant %uint 512 + %uint_15 = OpConstant %uint 15 + %uint_255 = OpConstant %uint 255 +%uint_16711935 = OpConstant %uint 16711935 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2587 = OpConstantComposite %v3uint %uint_1 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 + %2620 = OpConstantComposite %v3uint %uint_2 %uint_2 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint + %1903 = OpConstantComposite %v2uint %uint_0 %uint_8 +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform + %413 = OpConstantComposite %v4uint %uint_24 %uint_16 %uint_8 %uint_0 +%uint_4278190080 = OpConstant %uint 4278190080 + %uint_32 = OpConstant %uint 32 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_11 = OpConstant %uint 11 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %993 = OpConstantComposite %v2uint %uint_248 %uint_248 + %1015 = OpConstantComposite %v2uint %uint_258048 %uint_258048 + %2547 = OpConstantComposite %v2uint %uint_260046848 %uint_260046848 + %1912 = OpConstantComposite %v2uint %uint_5 %uint_5 + %503 = OpConstantComposite %v2uint %uint_7340039 %uint_7340039 + %1933 = OpConstantComposite %v2uint %uint_6 %uint_6 + %78 = OpConstantComposite %v2uint %uint_3072 %uint_3072 + %2878 = OpConstantComposite %v4uint %uint_1431655765 %uint_1431655765 %uint_1431655765 %uint_1431655765 + %2950 = OpConstantComposite %v4uint %uint_1 %uint_1 %uint_1 %uint_1 + %2860 = OpConstantComposite %v4uint %uint_2863311530 %uint_2863311530 %uint_2863311530 %uint_2863311530 + %1140 = OpConstantComposite %v2uint %uint_255 %uint_255 + %47 = OpConstantComposite %v4uint %uint_3 %uint_3 %uint_3 %uint_3 + %929 = OpConstantComposite %v4uint %uint_1023 %uint_1023 %uint_1023 %uint_1023 + %425 = OpConstantComposite %v4uint %uint_10 %uint_10 %uint_10 %uint_10 + %965 = OpConstantComposite %v4uint %uint_20 %uint_20 %uint_20 %uint_20 + %2599 = OpConstantComposite %v4uint %uint_4278190080 %uint_4278190080 %uint_4278190080 %uint_4278190080 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %14903 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20158 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %22412 = OpLoad %uint %20158 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_7 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2587 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %14018 DontFlatten + OpBranchConditional %24679 %21992 %14018 + %21992 = OpLabel + OpBranch %14903 + %14018 = OpLabel + %17344 = OpShiftLeftLogical %v3uint %21387 %2620 + %15489 = OpBitcast %v3int %17344 + %18336 = OpCompositeExtract %int %15489 0 + %9362 = OpIMul %int %18336 %int_4 + %6362 = OpCompositeExtract %int %15489 2 + %14505 = OpBitcast %int %6594 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %15489 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %22412 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %9362 %24535 + %10898 = OpBitcast %uint %8258 + %9077 = OpIAdd %uint %10898 %22411 + %11726 = OpShiftRightLogical %uint %9077 %uint_4 + %6977 = OpShiftRightLogical %uint %22412 %uint_4 + OpSelectionMerge %18964 DontFlatten + OpBranchConditional %17270 %7364 %21373 + %21373 = OpLabel + %9411 = OpBitcast %v3int %21387 + %8918 = OpCompositeExtract %int %9411 0 + %9363 = OpIMul %int %8918 %int_16 + %6363 = OpCompositeExtract %int %9411 2 + %14506 = OpBitcast %int %22409 + %11280 = OpIMul %int %6363 %14506 + %17599 = OpCompositeExtract %int %9411 1 + %22229 = OpIAdd %int %11280 %17599 + %22406 = OpBitcast %int %22408 + %7839 = OpIMul %int %22229 %22406 + %7984 = OpIAdd %int %9363 %7839 + OpBranch %18964 + %7364 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %6361 %21374 + %21374 = OpLabel + %10608 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %10608 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %10608 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6314 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6314 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_11 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12600 = OpBitwiseAnd %int %10055 %int_14 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17303 = OpIAdd %int %10934 %17741 + %6375 = OpShiftLeftLogical %int %17303 %uint_4 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15435 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15435 %13207 + %18356 = OpBitwiseAnd %int %10055 %int_1 + %21578 = OpShiftLeftLogical %int %18356 %int_4 + %16727 = OpIAdd %int %19760 %21578 + %20514 = OpBitwiseAnd %int %16727 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16728 = OpIAdd %int %9238 %12151 + %19165 = OpBitwiseAnd %int %16727 %int_448 + %21579 = OpShiftLeftLogical %int %19165 %int_2 + %16708 = OpIAdd %int %16728 %21579 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21580 = OpShiftLeftLogical %int %21587 %int_6 + %15436 = OpIAdd %int %16708 %21580 + %14157 = OpBitwiseAnd %int %16727 %int_63 + %12098 = OpIAdd %int %15436 %14157 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v3int %21387 + %17091 = OpCompositeExtract %int %6573 1 + %9470 = OpShiftRightArithmetic %int %17091 %int_4 + %10056 = OpCompositeExtract %int %6573 2 + %16477 = OpShiftRightArithmetic %int %10056 %int_2 + %23374 = OpShiftRightLogical %uint %22409 %uint_4 + %6315 = OpBitcast %int %23374 + %21281 = OpIMul %int %16477 %6315 + %15143 = OpIAdd %int %9470 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %6573 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_10 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12601 = OpBitwiseAnd %int %17091 %int_6 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17227 = OpIAdd %int %19768 %17742 + %7048 = OpShiftLeftLogical %int %17227 %uint_10 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17091 %int_3 + %13731 = OpIAdd %int %8725 %16477 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19166 = OpBitwiseAnd %int %13501 %int_3 + %21581 = OpShiftLeftLogical %int %19166 %int_1 + %15437 = OpIAdd %int %23052 %21581 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18357 = OpBitwiseAnd %int %10056 %int_3 + %21582 = OpShiftLeftLogical %int %18357 %uint_10 + %16729 = OpIAdd %int %10332 %21582 + %19167 = OpBitwiseAnd %int %17091 %int_1 + %21583 = OpShiftLeftLogical %int %19167 %int_4 + %16730 = OpIAdd %int %16729 %21583 + %20438 = OpBitwiseAnd %int %15437 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16730 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15437 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16730 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16730 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %6361 %12098 %21374 + OpBranch %18964 + %18964 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %21373 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %18964 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %11720 None + OpBranchConditional %15139 %11064 %11720 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11720 + %11720 = OpLabel + %19545 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %24377 = OpCompositeExtract %uint %19545 2 + %15487 = OpShiftLeftLogical %uint %24377 %uint_3 + %6481 = OpShiftRightLogical %uint %24377 %uint_13 + %17264 = OpCompositeConstruct %v2uint %15487 %6481 + %6430 = OpBitwiseAnd %v2uint %17264 %993 + %20543 = OpShiftLeftLogical %uint %24377 %uint_7 + %24164 = OpShiftRightLogical %uint %24377 %uint_9 + %17283 = OpCompositeConstruct %v2uint %20543 %24164 + %6295 = OpBitwiseAnd %v2uint %17283 %1015 + %14170 = OpBitwiseOr %v2uint %6430 %6295 + %23688 = OpShiftLeftLogical %uint %24377 %uint_12 + %22551 = OpShiftRightLogical %uint %24377 %uint_4 + %17285 = OpCompositeConstruct %v2uint %23688 %22551 + %6257 = OpBitwiseAnd %v2uint %17285 %2547 + %14611 = OpBitwiseOr %v2uint %14170 %6257 + %22361 = OpShiftRightLogical %v2uint %14611 %1912 + %6347 = OpBitwiseAnd %v2uint %22361 %503 + %16454 = OpBitwiseOr %v2uint %14611 %6347 + %22362 = OpShiftRightLogical %v2uint %16454 %1933 + %23271 = OpBitwiseAnd %v2uint %22362 %78 + %14671 = OpBitwiseOr %v2uint %16454 %23271 + %19422 = OpCompositeExtract %uint %19545 3 + %15440 = OpCompositeConstruct %v2uint %19422 %19422 + %25137 = OpVectorShuffle %v4uint %15440 %15440 0 1 0 0 + %11388 = OpBitwiseAnd %v4uint %25137 %2878 + %24266 = OpShiftLeftLogical %v4uint %11388 %2950 + %20653 = OpBitwiseAnd %v4uint %25137 %2860 + %16599 = OpShiftRightLogical %v4uint %20653 %2950 + %24000 = OpBitwiseOr %v4uint %24266 %16599 + %19618 = OpBitwiseAnd %v4uint %24000 %2860 + %18219 = OpShiftRightLogical %v4uint %19618 %2950 + %14965 = OpBitwiseXor %v4uint %24000 %18219 + %20727 = OpCompositeExtract %uint %14965 0 + %20387 = OpVectorShuffle %v2uint %19545 %19545 0 0 + %9028 = OpShiftRightLogical %v2uint %20387 %1903 + %8732 = OpBitwiseAnd %v2uint %9028 %1140 + %17507 = OpCompositeExtract %uint %19545 0 + %10727 = OpShiftRightLogical %uint %17507 %uint_16 + %9650 = OpCompositeExtract %uint %19545 1 + %6238 = OpBitwiseAnd %uint %9650 %uint_255 + %24078 = OpShiftLeftLogical %uint %6238 %uint_16 + %16241 = OpBitwiseOr %uint %10727 %24078 + %21939 = OpCompositeExtract %uint %8732 0 + %10103 = OpCompositeExtract %uint %8732 1 + %20099 = OpULessThanEqual %bool %21939 %10103 + OpSelectionMerge %13981 None + OpBranchConditional %20099 %21920 %10640 + %10640 = OpLabel + %17657 = OpBitwiseAnd %uint %16241 %uint_2396745 + %23910 = OpBitwiseAnd %uint %16241 %uint_4793490 + %22247 = OpShiftRightLogical %uint %23910 %uint_1 + %24001 = OpBitwiseOr %uint %17657 %22247 + %19599 = OpBitwiseAnd %uint %16241 %uint_9586980 + %20615 = OpShiftRightLogical %uint %19599 %uint_2 + %24287 = OpBitwiseOr %uint %24001 %20615 + %7721 = OpBitwiseXor %uint %24287 %uint_2396745 + %9540 = OpNot %uint %22247 + %14621 = OpBitwiseAnd %uint %17657 %9540 + %8425 = OpNot %uint %20615 + %11407 = OpBitwiseAnd %uint %14621 %8425 + %6799 = OpBitwiseOr %uint %16241 %7721 + %19509 = OpISub %uint %6799 %uint_2396745 + %14871 = OpBitwiseOr %uint %19509 %11407 + %18152 = OpShiftLeftLogical %uint %11407 %uint_1 + %16008 = OpBitwiseOr %uint %14871 %18152 + %8118 = OpShiftLeftLogical %uint %11407 %uint_2 + %7808 = OpBitwiseOr %uint %16008 %8118 + OpBranch %13981 + %21920 = OpLabel + %20079 = OpBitwiseAnd %uint %16241 %uint_4793490 + %23948 = OpBitwiseAnd %uint %16241 %uint_9586980 + %21844 = OpShiftRightLogical %uint %23948 %uint_1 + %8133 = OpBitwiseAnd %uint %20079 %21844 + %24609 = OpShiftLeftLogical %uint %8133 %uint_1 + %22956 = OpShiftRightLogical %uint %8133 %uint_1 + %18793 = OpBitwiseOr %uint %24609 %22956 + %16049 = OpBitwiseOr %uint %8133 %18793 + %18309 = OpBitwiseAnd %uint %16241 %uint_2396745 + %14685 = OpBitwiseOr %uint %18309 %uint_14380470 + %20403 = OpBitwiseAnd %uint %14685 %16049 + %20539 = OpShiftRightLogical %uint %20079 %uint_1 + %24922 = OpBitwiseOr %uint %18309 %20539 + %21922 = OpShiftRightLogical %uint %23948 %uint_2 + %22674 = OpBitwiseOr %uint %24922 %21922 + %7722 = OpBitwiseXor %uint %22674 %uint_2396745 + %9541 = OpNot %uint %20539 + %14622 = OpBitwiseAnd %uint %18309 %9541 + %8426 = OpNot %uint %21922 + %11408 = OpBitwiseAnd %uint %14622 %8426 + %6800 = OpBitwiseOr %uint %16241 %7722 + %19510 = OpISub %uint %6800 %uint_2396745 + %14872 = OpBitwiseOr %uint %19510 %11408 + %18228 = OpShiftLeftLogical %uint %11408 %uint_2 + %15354 = OpBitwiseOr %uint %14872 %18228 + %12154 = OpNot %uint %16049 + %18512 = OpBitwiseAnd %uint %15354 %12154 + %6252 = OpBitwiseOr %uint %18512 %20403 + OpBranch %13981 + %13981 = OpLabel + %15825 = OpPhi %uint %6252 %21920 %7808 %10640 + %16571 = OpNot %uint %20727 + %14240 = OpCompositeConstruct %v4uint %16571 %16571 %16571 %16571 + %24040 = OpShiftRightLogical %v4uint %14240 %77 + %23215 = OpBitwiseAnd %v4uint %24040 %47 + %19127 = OpCompositeExtract %uint %14671 0 + %24694 = OpCompositeConstruct %v4uint %19127 %19127 %19127 %19127 + %24562 = OpIMul %v4uint %23215 %24694 + %25211 = OpCompositeConstruct %v4uint %20727 %20727 %20727 %20727 + %14397 = OpShiftRightLogical %v4uint %25211 %77 + %23216 = OpBitwiseAnd %v4uint %14397 %47 + %19128 = OpCompositeExtract %uint %14671 1 + %6535 = OpCompositeConstruct %v4uint %19128 %19128 %19128 %19128 + %16353 = OpIMul %v4uint %23216 %6535 + %11267 = OpIAdd %v4uint %24562 %16353 + %24766 = OpBitwiseAnd %v4uint %11267 %929 + %9225 = OpUDiv %v4uint %24766 %47 + %17608 = OpShiftLeftLogical %v4uint %9225 %749 + %10961 = OpShiftRightLogical %v4uint %11267 %425 + %13249 = OpBitwiseAnd %v4uint %10961 %929 + %17312 = OpUDiv %v4uint %13249 %47 + %16994 = OpShiftLeftLogical %v4uint %17312 %317 + %6318 = OpBitwiseOr %v4uint %17608 %16994 + %15344 = OpShiftRightLogical %v4uint %11267 %965 + %24982 = OpUDiv %v4uint %15344 %47 + %19482 = OpBitwiseOr %v4uint %6318 %24982 + OpSelectionMerge %23551 None + OpBranchConditional %20099 %21921 %10467 + %10467 = OpLabel + %8286 = OpNot %uint %15825 + %15355 = OpBitwiseAnd %uint %8286 %uint_7 + %17712 = OpIMul %uint %21939 %15355 + %21975 = OpBitwiseAnd %uint %15825 %uint_7 + %20390 = OpIMul %uint %10103 %21975 + %19842 = OpIAdd %uint %17712 %20390 + %13000 = OpUDiv %uint %19842 %uint_7 + %23022 = OpShiftRightLogical %uint %8286 %uint_3 + %8753 = OpBitwiseAnd %uint %23022 %uint_7 + %15011 = OpIMul %uint %21939 %8753 + %13283 = OpShiftRightLogical %uint %15825 %uint_3 + %24957 = OpBitwiseAnd %uint %13283 %uint_7 + %25194 = OpIMul %uint %10103 %24957 + %19880 = OpIAdd %uint %15011 %25194 + %12616 = OpUDiv %uint %19880 %uint_7 + %8160 = OpShiftLeftLogical %uint %12616 %uint_8 + %7553 = OpBitwiseOr %uint %13000 %8160 + %21935 = OpShiftRightLogical %uint %8286 %uint_6 + %17592 = OpBitwiseAnd %uint %21935 %uint_7 + %15012 = OpIMul %uint %21939 %17592 + %13284 = OpShiftRightLogical %uint %15825 %uint_6 + %24958 = OpBitwiseAnd %uint %13284 %uint_7 + %25195 = OpIMul %uint %10103 %24958 + %19881 = OpIAdd %uint %15012 %25195 + %12617 = OpUDiv %uint %19881 %uint_7 + %8161 = OpShiftLeftLogical %uint %12617 %uint_16 + %7554 = OpBitwiseOr %uint %7553 %8161 + %21936 = OpShiftRightLogical %uint %8286 %uint_9 + %17593 = OpBitwiseAnd %uint %21936 %uint_7 + %15013 = OpIMul %uint %21939 %17593 + %13285 = OpShiftRightLogical %uint %15825 %uint_9 + %24959 = OpBitwiseAnd %uint %13285 %uint_7 + %25196 = OpIMul %uint %10103 %24959 + %19882 = OpIAdd %uint %15013 %25196 + %12618 = OpUDiv %uint %19882 %uint_7 + %9205 = OpShiftLeftLogical %uint %12618 %uint_24 + %18040 = OpBitwiseOr %uint %7554 %9205 + OpBranch %23551 + %21921 = OpLabel + %20080 = OpBitwiseAnd %uint %15825 %uint_1170 + %23949 = OpBitwiseAnd %uint %15825 %uint_2340 + %21845 = OpShiftRightLogical %uint %23949 %uint_1 + %8134 = OpBitwiseAnd %uint %20080 %21845 + %24610 = OpShiftLeftLogical %uint %8134 %uint_1 + %22957 = OpShiftRightLogical %uint %8134 %uint_1 + %18812 = OpBitwiseOr %uint %24610 %22957 + %15914 = OpBitwiseOr %uint %8134 %18812 + %8459 = OpNot %uint %15914 + %10082 = OpBitwiseAnd %uint %15825 %8459 + %16300 = OpISub %uint %uint_2925 %10082 + %17415 = OpBitwiseAnd %uint %16300 %8459 + %16991 = OpBitwiseAnd %uint %17415 %uint_7 + %13677 = OpIMul %uint %21939 %16991 + %21976 = OpBitwiseAnd %uint %10082 %uint_7 + %20391 = OpIMul %uint %10103 %21976 + %19843 = OpIAdd %uint %13677 %20391 + %13001 = OpUDiv %uint %19843 %uint_5 + %23023 = OpShiftRightLogical %uint %17415 %uint_3 + %8754 = OpBitwiseAnd %uint %23023 %uint_7 + %15014 = OpIMul %uint %21939 %8754 + %13286 = OpShiftRightLogical %uint %10082 %uint_3 + %24960 = OpBitwiseAnd %uint %13286 %uint_7 + %25197 = OpIMul %uint %10103 %24960 + %19883 = OpIAdd %uint %15014 %25197 + %12619 = OpUDiv %uint %19883 %uint_5 + %8162 = OpShiftLeftLogical %uint %12619 %uint_8 + %7555 = OpBitwiseOr %uint %13001 %8162 + %21937 = OpShiftRightLogical %uint %17415 %uint_6 + %17594 = OpBitwiseAnd %uint %21937 %uint_7 + %15015 = OpIMul %uint %21939 %17594 + %13287 = OpShiftRightLogical %uint %10082 %uint_6 + %24961 = OpBitwiseAnd %uint %13287 %uint_7 + %25198 = OpIMul %uint %10103 %24961 + %19884 = OpIAdd %uint %15015 %25198 + %12620 = OpUDiv %uint %19884 %uint_5 + %8163 = OpShiftLeftLogical %uint %12620 %uint_16 + %7556 = OpBitwiseOr %uint %7555 %8163 + %21938 = OpShiftRightLogical %uint %17415 %uint_9 + %17595 = OpBitwiseAnd %uint %21938 %uint_7 + %15016 = OpIMul %uint %21939 %17595 + %13288 = OpShiftRightLogical %uint %10082 %uint_9 + %24962 = OpBitwiseAnd %uint %13288 %uint_7 + %25199 = OpIMul %uint %10103 %24962 + %19885 = OpIAdd %uint %15016 %25199 + %12621 = OpUDiv %uint %19885 %uint_5 + %8255 = OpShiftLeftLogical %uint %12621 %uint_24 + %6688 = OpBitwiseOr %uint %7556 %8255 + %20385 = OpBitwiseAnd %uint %15825 %15914 + %17408 = OpBitwiseAnd %uint %20385 %uint_1 + %19559 = OpBitwiseAnd %uint %20385 %uint_8 + %24932 = OpShiftLeftLogical %uint %19559 %uint_5 + %17083 = OpBitwiseOr %uint %17408 %24932 + %20866 = OpBitwiseAnd %uint %20385 %uint_64 + %23319 = OpShiftLeftLogical %uint %20866 %uint_10 + %17084 = OpBitwiseOr %uint %17083 %23319 + %20867 = OpBitwiseAnd %uint %20385 %uint_512 + %22046 = OpShiftLeftLogical %uint %20867 %uint_15 + %8311 = OpBitwiseOr %uint %17084 %22046 + %10419 = OpIMul %uint %8311 %uint_255 + %18431 = OpIAdd %uint %6688 %10419 + OpBranch %23551 + %23551 = OpLabel + %19718 = OpPhi %uint %18431 %21921 %18040 %10467 + %13594 = OpCompositeConstruct %v4uint %19718 %19718 %19718 %19718 + %17094 = OpShiftLeftLogical %v4uint %13594 %413 + %21435 = OpBitwiseAnd %v4uint %17094 %2599 + %12253 = OpBitwiseOr %v4uint %19482 %21435 + %20165 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11726 + OpStore %20165 %12253 + %12832 = OpCompositeExtract %uint %17344 1 + %23232 = OpIAdd %uint %12832 %uint_1 + %17425 = OpULessThan %bool %23232 %6594 + OpSelectionMerge %7569 DontFlatten + OpBranchConditional %17425 %22828 %7569 + %22828 = OpLabel + %15595 = OpIAdd %uint %11726 %6977 + %10966 = OpShiftRightLogical %uint %20727 %uint_8 + %23788 = OpNot %uint %10966 + %21236 = OpCompositeConstruct %v4uint %23788 %23788 %23788 %23788 + %25009 = OpShiftRightLogical %v4uint %21236 %77 + %14392 = OpBitwiseAnd %v4uint %25009 %47 + %15567 = OpIMul %v4uint %14392 %24694 + %21401 = OpCompositeConstruct %v4uint %10966 %10966 %10966 %10966 + %15366 = OpShiftRightLogical %v4uint %21401 %77 + %15304 = OpBitwiseAnd %v4uint %15366 %47 + %7358 = OpIMul %v4uint %15304 %6535 + %7457 = OpIAdd %v4uint %15567 %7358 + %24767 = OpBitwiseAnd %v4uint %7457 %929 + %9226 = OpUDiv %v4uint %24767 %47 + %17609 = OpShiftLeftLogical %v4uint %9226 %749 + %10962 = OpShiftRightLogical %v4uint %7457 %425 + %13250 = OpBitwiseAnd %v4uint %10962 %929 + %17313 = OpUDiv %v4uint %13250 %47 + %16995 = OpShiftLeftLogical %v4uint %17313 %317 + %6319 = OpBitwiseOr %v4uint %17609 %16995 + %15345 = OpShiftRightLogical %v4uint %7457 %965 + %23975 = OpUDiv %v4uint %15345 %47 + %9523 = OpBitwiseOr %v4uint %6319 %23975 + %23683 = OpShiftRightLogical %uint %15825 %uint_12 + OpSelectionMerge %23552 None + OpBranchConditional %20099 %21923 %10468 + %10468 = OpLabel + %8287 = OpNot %uint %23683 + %15356 = OpBitwiseAnd %uint %8287 %uint_7 + %17713 = OpIMul %uint %21939 %15356 + %21977 = OpBitwiseAnd %uint %23683 %uint_7 + %20392 = OpIMul %uint %10103 %21977 + %19844 = OpIAdd %uint %17713 %20392 + %13002 = OpUDiv %uint %19844 %uint_7 + %23024 = OpShiftRightLogical %uint %8287 %uint_3 + %8755 = OpBitwiseAnd %uint %23024 %uint_7 + %15017 = OpIMul %uint %21939 %8755 + %13289 = OpShiftRightLogical %uint %23683 %uint_3 + %24963 = OpBitwiseAnd %uint %13289 %uint_7 + %25200 = OpIMul %uint %10103 %24963 + %19886 = OpIAdd %uint %15017 %25200 + %12622 = OpUDiv %uint %19886 %uint_7 + %8164 = OpShiftLeftLogical %uint %12622 %uint_8 + %7557 = OpBitwiseOr %uint %13002 %8164 + %21940 = OpShiftRightLogical %uint %8287 %uint_6 + %17596 = OpBitwiseAnd %uint %21940 %uint_7 + %15018 = OpIMul %uint %21939 %17596 + %13290 = OpShiftRightLogical %uint %23683 %uint_6 + %24964 = OpBitwiseAnd %uint %13290 %uint_7 + %25201 = OpIMul %uint %10103 %24964 + %19887 = OpIAdd %uint %15018 %25201 + %12623 = OpUDiv %uint %19887 %uint_7 + %8165 = OpShiftLeftLogical %uint %12623 %uint_16 + %7558 = OpBitwiseOr %uint %7557 %8165 + %21941 = OpShiftRightLogical %uint %8287 %uint_9 + %17597 = OpBitwiseAnd %uint %21941 %uint_7 + %15019 = OpIMul %uint %21939 %17597 + %13291 = OpShiftRightLogical %uint %23683 %uint_9 + %24965 = OpBitwiseAnd %uint %13291 %uint_7 + %25202 = OpIMul %uint %10103 %24965 + %19888 = OpIAdd %uint %15019 %25202 + %12624 = OpUDiv %uint %19888 %uint_7 + %9206 = OpShiftLeftLogical %uint %12624 %uint_24 + %18041 = OpBitwiseOr %uint %7558 %9206 + OpBranch %23552 + %21923 = OpLabel + %20081 = OpBitwiseAnd %uint %23683 %uint_1170 + %23950 = OpBitwiseAnd %uint %23683 %uint_2340 + %21846 = OpShiftRightLogical %uint %23950 %uint_1 + %8135 = OpBitwiseAnd %uint %20081 %21846 + %24611 = OpShiftLeftLogical %uint %8135 %uint_1 + %22958 = OpShiftRightLogical %uint %8135 %uint_1 + %18813 = OpBitwiseOr %uint %24611 %22958 + %15915 = OpBitwiseOr %uint %8135 %18813 + %8460 = OpNot %uint %15915 + %10083 = OpBitwiseAnd %uint %23683 %8460 + %16301 = OpISub %uint %uint_2925 %10083 + %17416 = OpBitwiseAnd %uint %16301 %8460 + %16992 = OpBitwiseAnd %uint %17416 %uint_7 + %13678 = OpIMul %uint %21939 %16992 + %21978 = OpBitwiseAnd %uint %10083 %uint_7 + %20393 = OpIMul %uint %10103 %21978 + %19845 = OpIAdd %uint %13678 %20393 + %13003 = OpUDiv %uint %19845 %uint_5 + %23025 = OpShiftRightLogical %uint %17416 %uint_3 + %8756 = OpBitwiseAnd %uint %23025 %uint_7 + %15020 = OpIMul %uint %21939 %8756 + %13292 = OpShiftRightLogical %uint %10083 %uint_3 + %24966 = OpBitwiseAnd %uint %13292 %uint_7 + %25203 = OpIMul %uint %10103 %24966 + %19889 = OpIAdd %uint %15020 %25203 + %12625 = OpUDiv %uint %19889 %uint_5 + %8166 = OpShiftLeftLogical %uint %12625 %uint_8 + %7559 = OpBitwiseOr %uint %13003 %8166 + %21942 = OpShiftRightLogical %uint %17416 %uint_6 + %17600 = OpBitwiseAnd %uint %21942 %uint_7 + %15021 = OpIMul %uint %21939 %17600 + %13293 = OpShiftRightLogical %uint %10083 %uint_6 + %24967 = OpBitwiseAnd %uint %13293 %uint_7 + %25204 = OpIMul %uint %10103 %24967 + %19890 = OpIAdd %uint %15021 %25204 + %12626 = OpUDiv %uint %19890 %uint_5 + %8167 = OpShiftLeftLogical %uint %12626 %uint_16 + %7560 = OpBitwiseOr %uint %7559 %8167 + %21943 = OpShiftRightLogical %uint %17416 %uint_9 + %17601 = OpBitwiseAnd %uint %21943 %uint_7 + %15022 = OpIMul %uint %21939 %17601 + %13294 = OpShiftRightLogical %uint %10083 %uint_9 + %24968 = OpBitwiseAnd %uint %13294 %uint_7 + %25205 = OpIMul %uint %10103 %24968 + %19891 = OpIAdd %uint %15022 %25205 + %12627 = OpUDiv %uint %19891 %uint_5 + %8256 = OpShiftLeftLogical %uint %12627 %uint_24 + %6689 = OpBitwiseOr %uint %7560 %8256 + %20386 = OpBitwiseAnd %uint %23683 %15915 + %17409 = OpBitwiseAnd %uint %20386 %uint_1 + %19560 = OpBitwiseAnd %uint %20386 %uint_8 + %24933 = OpShiftLeftLogical %uint %19560 %uint_5 + %17085 = OpBitwiseOr %uint %17409 %24933 + %20868 = OpBitwiseAnd %uint %20386 %uint_64 + %23320 = OpShiftLeftLogical %uint %20868 %uint_10 + %17086 = OpBitwiseOr %uint %17085 %23320 + %20869 = OpBitwiseAnd %uint %20386 %uint_512 + %22047 = OpShiftLeftLogical %uint %20869 %uint_15 + %8312 = OpBitwiseOr %uint %17086 %22047 + %10420 = OpIMul %uint %8312 %uint_255 + %18432 = OpIAdd %uint %6689 %10420 + OpBranch %23552 + %23552 = OpLabel + %19719 = OpPhi %uint %18432 %21923 %18041 %10468 + %13595 = OpCompositeConstruct %v4uint %19719 %19719 %19719 %19719 + %17095 = OpShiftLeftLogical %v4uint %13595 %413 + %21436 = OpBitwiseAnd %v4uint %17095 %2599 + %12254 = OpBitwiseOr %v4uint %9523 %21436 + %21058 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15595 + OpStore %21058 %12254 + %14840 = OpIAdd %uint %12832 %uint_2 + %11787 = OpULessThan %bool %14840 %6594 + OpSelectionMerge %7205 DontFlatten + OpBranchConditional %11787 %12417 %7205 + %12417 = OpLabel + %13240 = OpShiftRightLogical %uint %9650 %uint_8 + OpSelectionMerge %12689 None + OpBranchConditional %20099 %21924 %10641 + %10641 = OpLabel + %17658 = OpBitwiseAnd %uint %13240 %uint_2396745 + %23911 = OpBitwiseAnd %uint %13240 %uint_4793490 + %22248 = OpShiftRightLogical %uint %23911 %uint_1 + %24002 = OpBitwiseOr %uint %17658 %22248 + %19600 = OpBitwiseAnd %uint %13240 %uint_9586980 + %20616 = OpShiftRightLogical %uint %19600 %uint_2 + %24288 = OpBitwiseOr %uint %24002 %20616 + %7723 = OpBitwiseXor %uint %24288 %uint_2396745 + %9542 = OpNot %uint %22248 + %14623 = OpBitwiseAnd %uint %17658 %9542 + %8427 = OpNot %uint %20616 + %11409 = OpBitwiseAnd %uint %14623 %8427 + %6801 = OpBitwiseOr %uint %13240 %7723 + %19511 = OpISub %uint %6801 %uint_2396745 + %14873 = OpBitwiseOr %uint %19511 %11409 + %18153 = OpShiftLeftLogical %uint %11409 %uint_1 + %16009 = OpBitwiseOr %uint %14873 %18153 + %8119 = OpShiftLeftLogical %uint %11409 %uint_2 + %7809 = OpBitwiseOr %uint %16009 %8119 + OpBranch %12689 + %21924 = OpLabel + %20082 = OpBitwiseAnd %uint %13240 %uint_4793490 + %23951 = OpBitwiseAnd %uint %13240 %uint_9586980 + %21847 = OpShiftRightLogical %uint %23951 %uint_1 + %8136 = OpBitwiseAnd %uint %20082 %21847 + %24612 = OpShiftLeftLogical %uint %8136 %uint_1 + %22959 = OpShiftRightLogical %uint %8136 %uint_1 + %18795 = OpBitwiseOr %uint %24612 %22959 + %16050 = OpBitwiseOr %uint %8136 %18795 + %18310 = OpBitwiseAnd %uint %13240 %uint_2396745 + %14686 = OpBitwiseOr %uint %18310 %uint_14380470 + %20404 = OpBitwiseAnd %uint %14686 %16050 + %20540 = OpShiftRightLogical %uint %20082 %uint_1 + %24923 = OpBitwiseOr %uint %18310 %20540 + %21925 = OpShiftRightLogical %uint %23951 %uint_2 + %22675 = OpBitwiseOr %uint %24923 %21925 + %7724 = OpBitwiseXor %uint %22675 %uint_2396745 + %9543 = OpNot %uint %20540 + %14624 = OpBitwiseAnd %uint %18310 %9543 + %8428 = OpNot %uint %21925 + %11410 = OpBitwiseAnd %uint %14624 %8428 + %6802 = OpBitwiseOr %uint %13240 %7724 + %19512 = OpISub %uint %6802 %uint_2396745 + %14874 = OpBitwiseOr %uint %19512 %11410 + %18229 = OpShiftLeftLogical %uint %11410 %uint_2 + %15357 = OpBitwiseOr %uint %14874 %18229 + %12155 = OpNot %uint %16050 + %18513 = OpBitwiseAnd %uint %15357 %12155 + %6253 = OpBitwiseOr %uint %18513 %20404 + OpBranch %12689 + %12689 = OpLabel + %9430 = OpPhi %uint %6253 %21924 %7809 %10641 + %18789 = OpIMul %uint %uint_2 %6977 + %14390 = OpIAdd %uint %11726 %18789 + %13967 = OpShiftRightLogical %uint %20727 %uint_16 + %23789 = OpNot %uint %13967 + %21237 = OpCompositeConstruct %v4uint %23789 %23789 %23789 %23789 + %25010 = OpShiftRightLogical %v4uint %21237 %77 + %14393 = OpBitwiseAnd %v4uint %25010 %47 + %15568 = OpIMul %v4uint %14393 %24694 + %21402 = OpCompositeConstruct %v4uint %13967 %13967 %13967 %13967 + %15367 = OpShiftRightLogical %v4uint %21402 %77 + %15305 = OpBitwiseAnd %v4uint %15367 %47 + %7359 = OpIMul %v4uint %15305 %6535 + %7458 = OpIAdd %v4uint %15568 %7359 + %24768 = OpBitwiseAnd %v4uint %7458 %929 + %9227 = OpUDiv %v4uint %24768 %47 + %17610 = OpShiftLeftLogical %v4uint %9227 %749 + %10963 = OpShiftRightLogical %v4uint %7458 %425 + %13251 = OpBitwiseAnd %v4uint %10963 %929 + %17314 = OpUDiv %v4uint %13251 %47 + %16996 = OpShiftLeftLogical %v4uint %17314 %317 + %6320 = OpBitwiseOr %v4uint %17610 %16996 + %15346 = OpShiftRightLogical %v4uint %7458 %965 + %24983 = OpUDiv %v4uint %15346 %47 + %19483 = OpBitwiseOr %v4uint %6320 %24983 + OpSelectionMerge %23553 None + OpBranchConditional %20099 %21926 %10469 + %10469 = OpLabel + %8288 = OpNot %uint %9430 + %15358 = OpBitwiseAnd %uint %8288 %uint_7 + %17714 = OpIMul %uint %21939 %15358 + %21979 = OpBitwiseAnd %uint %9430 %uint_7 + %20394 = OpIMul %uint %10103 %21979 + %19846 = OpIAdd %uint %17714 %20394 + %13004 = OpUDiv %uint %19846 %uint_7 + %23026 = OpShiftRightLogical %uint %8288 %uint_3 + %8757 = OpBitwiseAnd %uint %23026 %uint_7 + %15023 = OpIMul %uint %21939 %8757 + %13295 = OpShiftRightLogical %uint %9430 %uint_3 + %24969 = OpBitwiseAnd %uint %13295 %uint_7 + %25206 = OpIMul %uint %10103 %24969 + %19892 = OpIAdd %uint %15023 %25206 + %12628 = OpUDiv %uint %19892 %uint_7 + %8168 = OpShiftLeftLogical %uint %12628 %uint_8 + %7561 = OpBitwiseOr %uint %13004 %8168 + %21944 = OpShiftRightLogical %uint %8288 %uint_6 + %17602 = OpBitwiseAnd %uint %21944 %uint_7 + %15024 = OpIMul %uint %21939 %17602 + %13296 = OpShiftRightLogical %uint %9430 %uint_6 + %24970 = OpBitwiseAnd %uint %13296 %uint_7 + %25207 = OpIMul %uint %10103 %24970 + %19893 = OpIAdd %uint %15024 %25207 + %12629 = OpUDiv %uint %19893 %uint_7 + %8169 = OpShiftLeftLogical %uint %12629 %uint_16 + %7562 = OpBitwiseOr %uint %7561 %8169 + %21945 = OpShiftRightLogical %uint %8288 %uint_9 + %17603 = OpBitwiseAnd %uint %21945 %uint_7 + %15025 = OpIMul %uint %21939 %17603 + %13297 = OpShiftRightLogical %uint %9430 %uint_9 + %24971 = OpBitwiseAnd %uint %13297 %uint_7 + %25208 = OpIMul %uint %10103 %24971 + %19894 = OpIAdd %uint %15025 %25208 + %12630 = OpUDiv %uint %19894 %uint_7 + %9207 = OpShiftLeftLogical %uint %12630 %uint_24 + %18042 = OpBitwiseOr %uint %7562 %9207 + OpBranch %23553 + %21926 = OpLabel + %20083 = OpBitwiseAnd %uint %9430 %uint_1170 + %23952 = OpBitwiseAnd %uint %9430 %uint_2340 + %21848 = OpShiftRightLogical %uint %23952 %uint_1 + %8137 = OpBitwiseAnd %uint %20083 %21848 + %24613 = OpShiftLeftLogical %uint %8137 %uint_1 + %22960 = OpShiftRightLogical %uint %8137 %uint_1 + %18814 = OpBitwiseOr %uint %24613 %22960 + %15916 = OpBitwiseOr %uint %8137 %18814 + %8461 = OpNot %uint %15916 + %10084 = OpBitwiseAnd %uint %9430 %8461 + %16302 = OpISub %uint %uint_2925 %10084 + %17417 = OpBitwiseAnd %uint %16302 %8461 + %16993 = OpBitwiseAnd %uint %17417 %uint_7 + %13679 = OpIMul %uint %21939 %16993 + %21980 = OpBitwiseAnd %uint %10084 %uint_7 + %20395 = OpIMul %uint %10103 %21980 + %19847 = OpIAdd %uint %13679 %20395 + %13005 = OpUDiv %uint %19847 %uint_5 + %23027 = OpShiftRightLogical %uint %17417 %uint_3 + %8758 = OpBitwiseAnd %uint %23027 %uint_7 + %15026 = OpIMul %uint %21939 %8758 + %13298 = OpShiftRightLogical %uint %10084 %uint_3 + %24972 = OpBitwiseAnd %uint %13298 %uint_7 + %25209 = OpIMul %uint %10103 %24972 + %19895 = OpIAdd %uint %15026 %25209 + %12631 = OpUDiv %uint %19895 %uint_5 + %8170 = OpShiftLeftLogical %uint %12631 %uint_8 + %7563 = OpBitwiseOr %uint %13005 %8170 + %21946 = OpShiftRightLogical %uint %17417 %uint_6 + %17604 = OpBitwiseAnd %uint %21946 %uint_7 + %15027 = OpIMul %uint %21939 %17604 + %13299 = OpShiftRightLogical %uint %10084 %uint_6 + %24973 = OpBitwiseAnd %uint %13299 %uint_7 + %25210 = OpIMul %uint %10103 %24973 + %19896 = OpIAdd %uint %15027 %25210 + %12632 = OpUDiv %uint %19896 %uint_5 + %8171 = OpShiftLeftLogical %uint %12632 %uint_16 + %7564 = OpBitwiseOr %uint %7563 %8171 + %21947 = OpShiftRightLogical %uint %17417 %uint_9 + %17605 = OpBitwiseAnd %uint %21947 %uint_7 + %15028 = OpIMul %uint %21939 %17605 + %13300 = OpShiftRightLogical %uint %10084 %uint_9 + %24974 = OpBitwiseAnd %uint %13300 %uint_7 + %25212 = OpIMul %uint %10103 %24974 + %19897 = OpIAdd %uint %15028 %25212 + %12633 = OpUDiv %uint %19897 %uint_5 + %8257 = OpShiftLeftLogical %uint %12633 %uint_24 + %6690 = OpBitwiseOr %uint %7564 %8257 + %20388 = OpBitwiseAnd %uint %9430 %15916 + %17410 = OpBitwiseAnd %uint %20388 %uint_1 + %19561 = OpBitwiseAnd %uint %20388 %uint_8 + %24934 = OpShiftLeftLogical %uint %19561 %uint_5 + %17087 = OpBitwiseOr %uint %17410 %24934 + %20870 = OpBitwiseAnd %uint %20388 %uint_64 + %23321 = OpShiftLeftLogical %uint %20870 %uint_10 + %17088 = OpBitwiseOr %uint %17087 %23321 + %20871 = OpBitwiseAnd %uint %20388 %uint_512 + %22048 = OpShiftLeftLogical %uint %20871 %uint_15 + %8313 = OpBitwiseOr %uint %17088 %22048 + %10421 = OpIMul %uint %8313 %uint_255 + %18433 = OpIAdd %uint %6690 %10421 + OpBranch %23553 + %23553 = OpLabel + %19720 = OpPhi %uint %18433 %21926 %18042 %10469 + %13596 = OpCompositeConstruct %v4uint %19720 %19720 %19720 %19720 + %17096 = OpShiftLeftLogical %v4uint %13596 %413 + %21437 = OpBitwiseAnd %v4uint %17096 %2599 + %12255 = OpBitwiseOr %v4uint %19483 %21437 + %21059 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %14390 + OpStore %21059 %12255 + %14841 = OpIAdd %uint %12832 %uint_3 + %11788 = OpULessThan %bool %14841 %6594 + OpSelectionMerge %18021 DontFlatten + OpBranchConditional %11788 %20882 %18021 + %20882 = OpLabel + %13198 = OpIMul %uint %uint_3 %6977 + %13581 = OpIAdd %uint %11726 %13198 + %13968 = OpShiftRightLogical %uint %20727 %uint_24 + %23790 = OpNot %uint %13968 + %21238 = OpCompositeConstruct %v4uint %23790 %23790 %23790 %23790 + %25011 = OpShiftRightLogical %v4uint %21238 %77 + %14394 = OpBitwiseAnd %v4uint %25011 %47 + %15569 = OpIMul %v4uint %14394 %24694 + %21403 = OpCompositeConstruct %v4uint %13968 %13968 %13968 %13968 + %15368 = OpShiftRightLogical %v4uint %21403 %77 + %15306 = OpBitwiseAnd %v4uint %15368 %47 + %7360 = OpIMul %v4uint %15306 %6535 + %7459 = OpIAdd %v4uint %15569 %7360 + %24769 = OpBitwiseAnd %v4uint %7459 %929 + %9228 = OpUDiv %v4uint %24769 %47 + %17611 = OpShiftLeftLogical %v4uint %9228 %749 + %10964 = OpShiftRightLogical %v4uint %7459 %425 + %13252 = OpBitwiseAnd %v4uint %10964 %929 + %17315 = OpUDiv %v4uint %13252 %47 + %16997 = OpShiftLeftLogical %v4uint %17315 %317 + %6321 = OpBitwiseOr %v4uint %17611 %16997 + %15347 = OpShiftRightLogical %v4uint %7459 %965 + %23976 = OpUDiv %v4uint %15347 %47 + %9524 = OpBitwiseOr %v4uint %6321 %23976 + %23684 = OpShiftRightLogical %uint %9430 %uint_12 + OpSelectionMerge %23554 None + OpBranchConditional %20099 %21927 %10470 + %10470 = OpLabel + %8289 = OpNot %uint %23684 + %15359 = OpBitwiseAnd %uint %8289 %uint_7 + %17715 = OpIMul %uint %21939 %15359 + %21981 = OpBitwiseAnd %uint %23684 %uint_7 + %20396 = OpIMul %uint %10103 %21981 + %19848 = OpIAdd %uint %17715 %20396 + %13006 = OpUDiv %uint %19848 %uint_7 + %23028 = OpShiftRightLogical %uint %8289 %uint_3 + %8759 = OpBitwiseAnd %uint %23028 %uint_7 + %15029 = OpIMul %uint %21939 %8759 + %13301 = OpShiftRightLogical %uint %23684 %uint_3 + %24975 = OpBitwiseAnd %uint %13301 %uint_7 + %25213 = OpIMul %uint %10103 %24975 + %19898 = OpIAdd %uint %15029 %25213 + %12634 = OpUDiv %uint %19898 %uint_7 + %8172 = OpShiftLeftLogical %uint %12634 %uint_8 + %7565 = OpBitwiseOr %uint %13006 %8172 + %21948 = OpShiftRightLogical %uint %8289 %uint_6 + %17606 = OpBitwiseAnd %uint %21948 %uint_7 + %15030 = OpIMul %uint %21939 %17606 + %13302 = OpShiftRightLogical %uint %23684 %uint_6 + %24976 = OpBitwiseAnd %uint %13302 %uint_7 + %25214 = OpIMul %uint %10103 %24976 + %19899 = OpIAdd %uint %15030 %25214 + %12635 = OpUDiv %uint %19899 %uint_7 + %8173 = OpShiftLeftLogical %uint %12635 %uint_16 + %7566 = OpBitwiseOr %uint %7565 %8173 + %21949 = OpShiftRightLogical %uint %8289 %uint_9 + %17607 = OpBitwiseAnd %uint %21949 %uint_7 + %15031 = OpIMul %uint %21939 %17607 + %13303 = OpShiftRightLogical %uint %23684 %uint_9 + %24977 = OpBitwiseAnd %uint %13303 %uint_7 + %25215 = OpIMul %uint %10103 %24977 + %19900 = OpIAdd %uint %15031 %25215 + %12636 = OpUDiv %uint %19900 %uint_7 + %9208 = OpShiftLeftLogical %uint %12636 %uint_24 + %18043 = OpBitwiseOr %uint %7566 %9208 + OpBranch %23554 + %21927 = OpLabel + %20084 = OpBitwiseAnd %uint %23684 %uint_1170 + %23953 = OpBitwiseAnd %uint %23684 %uint_2340 + %21849 = OpShiftRightLogical %uint %23953 %uint_1 + %8138 = OpBitwiseAnd %uint %20084 %21849 + %24614 = OpShiftLeftLogical %uint %8138 %uint_1 + %22961 = OpShiftRightLogical %uint %8138 %uint_1 + %18815 = OpBitwiseOr %uint %24614 %22961 + %15917 = OpBitwiseOr %uint %8138 %18815 + %8462 = OpNot %uint %15917 + %10085 = OpBitwiseAnd %uint %23684 %8462 + %16303 = OpISub %uint %uint_2925 %10085 + %17418 = OpBitwiseAnd %uint %16303 %8462 + %16998 = OpBitwiseAnd %uint %17418 %uint_7 + %13680 = OpIMul %uint %21939 %16998 + %21982 = OpBitwiseAnd %uint %10085 %uint_7 + %20397 = OpIMul %uint %10103 %21982 + %19849 = OpIAdd %uint %13680 %20397 + %13007 = OpUDiv %uint %19849 %uint_5 + %23029 = OpShiftRightLogical %uint %17418 %uint_3 + %8760 = OpBitwiseAnd %uint %23029 %uint_7 + %15032 = OpIMul %uint %21939 %8760 + %13304 = OpShiftRightLogical %uint %10085 %uint_3 + %24978 = OpBitwiseAnd %uint %13304 %uint_7 + %25216 = OpIMul %uint %10103 %24978 + %19901 = OpIAdd %uint %15032 %25216 + %12637 = OpUDiv %uint %19901 %uint_5 + %8174 = OpShiftLeftLogical %uint %12637 %uint_8 + %7567 = OpBitwiseOr %uint %13007 %8174 + %21950 = OpShiftRightLogical %uint %17418 %uint_6 + %17612 = OpBitwiseAnd %uint %21950 %uint_7 + %15033 = OpIMul %uint %21939 %17612 + %13305 = OpShiftRightLogical %uint %10085 %uint_6 + %24979 = OpBitwiseAnd %uint %13305 %uint_7 + %25217 = OpIMul %uint %10103 %24979 + %19902 = OpIAdd %uint %15033 %25217 + %12638 = OpUDiv %uint %19902 %uint_5 + %8175 = OpShiftLeftLogical %uint %12638 %uint_16 + %7568 = OpBitwiseOr %uint %7567 %8175 + %21951 = OpShiftRightLogical %uint %17418 %uint_9 + %17613 = OpBitwiseAnd %uint %21951 %uint_7 + %15034 = OpIMul %uint %21939 %17613 + %13306 = OpShiftRightLogical %uint %10085 %uint_9 + %24980 = OpBitwiseAnd %uint %13306 %uint_7 + %25218 = OpIMul %uint %10103 %24980 + %19903 = OpIAdd %uint %15034 %25218 + %12639 = OpUDiv %uint %19903 %uint_5 + %8259 = OpShiftLeftLogical %uint %12639 %uint_24 + %6691 = OpBitwiseOr %uint %7568 %8259 + %20389 = OpBitwiseAnd %uint %23684 %15917 + %17411 = OpBitwiseAnd %uint %20389 %uint_1 + %19562 = OpBitwiseAnd %uint %20389 %uint_8 + %24935 = OpShiftLeftLogical %uint %19562 %uint_5 + %17089 = OpBitwiseOr %uint %17411 %24935 + %20872 = OpBitwiseAnd %uint %20389 %uint_64 + %23322 = OpShiftLeftLogical %uint %20872 %uint_10 + %17092 = OpBitwiseOr %uint %17089 %23322 + %20873 = OpBitwiseAnd %uint %20389 %uint_512 + %22049 = OpShiftLeftLogical %uint %20873 %uint_15 + %8314 = OpBitwiseOr %uint %17092 %22049 + %10422 = OpIMul %uint %8314 %uint_255 + %18434 = OpIAdd %uint %6691 %10422 + OpBranch %23554 + %23554 = OpLabel + %19721 = OpPhi %uint %18434 %21927 %18043 %10470 + %13597 = OpCompositeConstruct %v4uint %19721 %19721 %19721 %19721 + %17097 = OpShiftLeftLogical %v4uint %13597 %413 + %21438 = OpBitwiseAnd %v4uint %17097 %2599 + %12256 = OpBitwiseOr %v4uint %9524 %21438 + %23357 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13581 + OpStore %23357 %12256 + OpBranch %18021 + %18021 = OpLabel + OpBranch %7205 + %7205 = OpLabel + OpBranch %7569 + %7569 = OpLabel + %14517 = OpIAdd %uint %11726 %int_1 + %18181 = OpSelect %uint %17270 %uint_2 %uint_1 + %16762 = OpIAdd %uint %22117 %18181 + %18278 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %16762 + %6578 = OpLoad %v4uint %18278 + OpSelectionMerge %14875 None + OpBranchConditional %22150 %10584 %14875 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20654 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20654 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14875 + %14875 = OpLabel + %10924 = OpPhi %v4uint %6578 %7569 %16377 %10584 + OpSelectionMerge %11721 None + OpBranchConditional %15139 %11065 %11721 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11721 + %11721 = OpLabel + %19546 = OpPhi %v4uint %10924 %14875 %10729 %11065 + %24378 = OpCompositeExtract %uint %19546 2 + %15488 = OpShiftLeftLogical %uint %24378 %uint_3 + %6482 = OpShiftRightLogical %uint %24378 %uint_13 + %17265 = OpCompositeConstruct %v2uint %15488 %6482 + %6431 = OpBitwiseAnd %v2uint %17265 %993 + %20544 = OpShiftLeftLogical %uint %24378 %uint_7 + %24165 = OpShiftRightLogical %uint %24378 %uint_9 + %17286 = OpCompositeConstruct %v2uint %20544 %24165 + %6296 = OpBitwiseAnd %v2uint %17286 %1015 + %14171 = OpBitwiseOr %v2uint %6431 %6296 + %23689 = OpShiftLeftLogical %uint %24378 %uint_12 + %22552 = OpShiftRightLogical %uint %24378 %uint_4 + %17287 = OpCompositeConstruct %v2uint %23689 %22552 + %6258 = OpBitwiseAnd %v2uint %17287 %2547 + %14612 = OpBitwiseOr %v2uint %14171 %6258 + %22363 = OpShiftRightLogical %v2uint %14612 %1912 + %6348 = OpBitwiseAnd %v2uint %22363 %503 + %16455 = OpBitwiseOr %v2uint %14612 %6348 + %22364 = OpShiftRightLogical %v2uint %16455 %1933 + %23272 = OpBitwiseAnd %v2uint %22364 %78 + %14672 = OpBitwiseOr %v2uint %16455 %23272 + %19423 = OpCompositeExtract %uint %19546 3 + %15441 = OpCompositeConstruct %v2uint %19423 %19423 + %25138 = OpVectorShuffle %v4uint %15441 %15441 0 1 0 0 + %11389 = OpBitwiseAnd %v4uint %25138 %2878 + %24267 = OpShiftLeftLogical %v4uint %11389 %2950 + %20655 = OpBitwiseAnd %v4uint %25138 %2860 + %16600 = OpShiftRightLogical %v4uint %20655 %2950 + %24003 = OpBitwiseOr %v4uint %24267 %16600 + %19619 = OpBitwiseAnd %v4uint %24003 %2860 + %18220 = OpShiftRightLogical %v4uint %19619 %2950 + %14966 = OpBitwiseXor %v4uint %24003 %18220 + %20728 = OpCompositeExtract %uint %14966 0 + %20398 = OpVectorShuffle %v2uint %19546 %19546 0 0 + %9029 = OpShiftRightLogical %v2uint %20398 %1903 + %8733 = OpBitwiseAnd %v2uint %9029 %1140 + %17508 = OpCompositeExtract %uint %19546 0 + %10730 = OpShiftRightLogical %uint %17508 %uint_16 + %9651 = OpCompositeExtract %uint %19546 1 + %6239 = OpBitwiseAnd %uint %9651 %uint_255 + %24079 = OpShiftLeftLogical %uint %6239 %uint_16 + %16242 = OpBitwiseOr %uint %10730 %24079 + %21952 = OpCompositeExtract %uint %8733 0 + %10104 = OpCompositeExtract %uint %8733 1 + %20100 = OpULessThanEqual %bool %21952 %10104 + OpSelectionMerge %13982 None + OpBranchConditional %20100 %21928 %10642 + %10642 = OpLabel + %17659 = OpBitwiseAnd %uint %16242 %uint_2396745 + %23912 = OpBitwiseAnd %uint %16242 %uint_4793490 + %22249 = OpShiftRightLogical %uint %23912 %uint_1 + %24004 = OpBitwiseOr %uint %17659 %22249 + %19601 = OpBitwiseAnd %uint %16242 %uint_9586980 + %20617 = OpShiftRightLogical %uint %19601 %uint_2 + %24289 = OpBitwiseOr %uint %24004 %20617 + %7725 = OpBitwiseXor %uint %24289 %uint_2396745 + %9544 = OpNot %uint %22249 + %14625 = OpBitwiseAnd %uint %17659 %9544 + %8429 = OpNot %uint %20617 + %11411 = OpBitwiseAnd %uint %14625 %8429 + %6803 = OpBitwiseOr %uint %16242 %7725 + %19513 = OpISub %uint %6803 %uint_2396745 + %14876 = OpBitwiseOr %uint %19513 %11411 + %18154 = OpShiftLeftLogical %uint %11411 %uint_1 + %16010 = OpBitwiseOr %uint %14876 %18154 + %8120 = OpShiftLeftLogical %uint %11411 %uint_2 + %7810 = OpBitwiseOr %uint %16010 %8120 + OpBranch %13982 + %21928 = OpLabel + %20085 = OpBitwiseAnd %uint %16242 %uint_4793490 + %23954 = OpBitwiseAnd %uint %16242 %uint_9586980 + %21850 = OpShiftRightLogical %uint %23954 %uint_1 + %8139 = OpBitwiseAnd %uint %20085 %21850 + %24615 = OpShiftLeftLogical %uint %8139 %uint_1 + %22962 = OpShiftRightLogical %uint %8139 %uint_1 + %18796 = OpBitwiseOr %uint %24615 %22962 + %16051 = OpBitwiseOr %uint %8139 %18796 + %18311 = OpBitwiseAnd %uint %16242 %uint_2396745 + %14687 = OpBitwiseOr %uint %18311 %uint_14380470 + %20405 = OpBitwiseAnd %uint %14687 %16051 + %20541 = OpShiftRightLogical %uint %20085 %uint_1 + %24924 = OpBitwiseOr %uint %18311 %20541 + %21929 = OpShiftRightLogical %uint %23954 %uint_2 + %22676 = OpBitwiseOr %uint %24924 %21929 + %7726 = OpBitwiseXor %uint %22676 %uint_2396745 + %9545 = OpNot %uint %20541 + %14626 = OpBitwiseAnd %uint %18311 %9545 + %8430 = OpNot %uint %21929 + %11412 = OpBitwiseAnd %uint %14626 %8430 + %6804 = OpBitwiseOr %uint %16242 %7726 + %19514 = OpISub %uint %6804 %uint_2396745 + %14877 = OpBitwiseOr %uint %19514 %11412 + %18230 = OpShiftLeftLogical %uint %11412 %uint_2 + %15360 = OpBitwiseOr %uint %14877 %18230 + %12156 = OpNot %uint %16051 + %18514 = OpBitwiseAnd %uint %15360 %12156 + %6254 = OpBitwiseOr %uint %18514 %20405 + OpBranch %13982 + %13982 = OpLabel + %15826 = OpPhi %uint %6254 %21928 %7810 %10642 + %16572 = OpNot %uint %20728 + %14241 = OpCompositeConstruct %v4uint %16572 %16572 %16572 %16572 + %24041 = OpShiftRightLogical %v4uint %14241 %77 + %23219 = OpBitwiseAnd %v4uint %24041 %47 + %19129 = OpCompositeExtract %uint %14672 0 + %24695 = OpCompositeConstruct %v4uint %19129 %19129 %19129 %19129 + %24563 = OpIMul %v4uint %23219 %24695 + %25219 = OpCompositeConstruct %v4uint %20728 %20728 %20728 %20728 + %14398 = OpShiftRightLogical %v4uint %25219 %77 + %23220 = OpBitwiseAnd %v4uint %14398 %47 + %19130 = OpCompositeExtract %uint %14672 1 + %6536 = OpCompositeConstruct %v4uint %19130 %19130 %19130 %19130 + %16354 = OpIMul %v4uint %23220 %6536 + %11268 = OpIAdd %v4uint %24563 %16354 + %24770 = OpBitwiseAnd %v4uint %11268 %929 + %9229 = OpUDiv %v4uint %24770 %47 + %17614 = OpShiftLeftLogical %v4uint %9229 %749 + %10965 = OpShiftRightLogical %v4uint %11268 %425 + %13253 = OpBitwiseAnd %v4uint %10965 %929 + %17316 = OpUDiv %v4uint %13253 %47 + %16999 = OpShiftLeftLogical %v4uint %17316 %317 + %6322 = OpBitwiseOr %v4uint %17614 %16999 + %15348 = OpShiftRightLogical %v4uint %11268 %965 + %24984 = OpUDiv %v4uint %15348 %47 + %19484 = OpBitwiseOr %v4uint %6322 %24984 + OpSelectionMerge %23555 None + OpBranchConditional %20100 %21930 %10471 + %10471 = OpLabel + %8290 = OpNot %uint %15826 + %15361 = OpBitwiseAnd %uint %8290 %uint_7 + %17716 = OpIMul %uint %21952 %15361 + %21983 = OpBitwiseAnd %uint %15826 %uint_7 + %20399 = OpIMul %uint %10104 %21983 + %19850 = OpIAdd %uint %17716 %20399 + %13008 = OpUDiv %uint %19850 %uint_7 + %23030 = OpShiftRightLogical %uint %8290 %uint_3 + %8761 = OpBitwiseAnd %uint %23030 %uint_7 + %15035 = OpIMul %uint %21952 %8761 + %13307 = OpShiftRightLogical %uint %15826 %uint_3 + %24981 = OpBitwiseAnd %uint %13307 %uint_7 + %25220 = OpIMul %uint %10104 %24981 + %19904 = OpIAdd %uint %15035 %25220 + %12640 = OpUDiv %uint %19904 %uint_7 + %8176 = OpShiftLeftLogical %uint %12640 %uint_8 + %7570 = OpBitwiseOr %uint %13008 %8176 + %21953 = OpShiftRightLogical %uint %8290 %uint_6 + %17615 = OpBitwiseAnd %uint %21953 %uint_7 + %15036 = OpIMul %uint %21952 %17615 + %13308 = OpShiftRightLogical %uint %15826 %uint_6 + %24985 = OpBitwiseAnd %uint %13308 %uint_7 + %25221 = OpIMul %uint %10104 %24985 + %19905 = OpIAdd %uint %15036 %25221 + %12641 = OpUDiv %uint %19905 %uint_7 + %8177 = OpShiftLeftLogical %uint %12641 %uint_16 + %7571 = OpBitwiseOr %uint %7570 %8177 + %21954 = OpShiftRightLogical %uint %8290 %uint_9 + %17616 = OpBitwiseAnd %uint %21954 %uint_7 + %15037 = OpIMul %uint %21952 %17616 + %13309 = OpShiftRightLogical %uint %15826 %uint_9 + %24986 = OpBitwiseAnd %uint %13309 %uint_7 + %25222 = OpIMul %uint %10104 %24986 + %19906 = OpIAdd %uint %15037 %25222 + %12642 = OpUDiv %uint %19906 %uint_7 + %9209 = OpShiftLeftLogical %uint %12642 %uint_24 + %18044 = OpBitwiseOr %uint %7571 %9209 + OpBranch %23555 + %21930 = OpLabel + %20086 = OpBitwiseAnd %uint %15826 %uint_1170 + %23955 = OpBitwiseAnd %uint %15826 %uint_2340 + %21851 = OpShiftRightLogical %uint %23955 %uint_1 + %8140 = OpBitwiseAnd %uint %20086 %21851 + %24616 = OpShiftLeftLogical %uint %8140 %uint_1 + %22963 = OpShiftRightLogical %uint %8140 %uint_1 + %18816 = OpBitwiseOr %uint %24616 %22963 + %15918 = OpBitwiseOr %uint %8140 %18816 + %8463 = OpNot %uint %15918 + %10086 = OpBitwiseAnd %uint %15826 %8463 + %16304 = OpISub %uint %uint_2925 %10086 + %17419 = OpBitwiseAnd %uint %16304 %8463 + %17000 = OpBitwiseAnd %uint %17419 %uint_7 + %13681 = OpIMul %uint %21952 %17000 + %21984 = OpBitwiseAnd %uint %10086 %uint_7 + %20400 = OpIMul %uint %10104 %21984 + %19851 = OpIAdd %uint %13681 %20400 + %13009 = OpUDiv %uint %19851 %uint_5 + %23031 = OpShiftRightLogical %uint %17419 %uint_3 + %8762 = OpBitwiseAnd %uint %23031 %uint_7 + %15038 = OpIMul %uint %21952 %8762 + %13310 = OpShiftRightLogical %uint %10086 %uint_3 + %24987 = OpBitwiseAnd %uint %13310 %uint_7 + %25223 = OpIMul %uint %10104 %24987 + %19907 = OpIAdd %uint %15038 %25223 + %12643 = OpUDiv %uint %19907 %uint_5 + %8178 = OpShiftLeftLogical %uint %12643 %uint_8 + %7572 = OpBitwiseOr %uint %13009 %8178 + %21955 = OpShiftRightLogical %uint %17419 %uint_6 + %17617 = OpBitwiseAnd %uint %21955 %uint_7 + %15039 = OpIMul %uint %21952 %17617 + %13311 = OpShiftRightLogical %uint %10086 %uint_6 + %24988 = OpBitwiseAnd %uint %13311 %uint_7 + %25224 = OpIMul %uint %10104 %24988 + %19908 = OpIAdd %uint %15039 %25224 + %12644 = OpUDiv %uint %19908 %uint_5 + %8179 = OpShiftLeftLogical %uint %12644 %uint_16 + %7573 = OpBitwiseOr %uint %7572 %8179 + %21956 = OpShiftRightLogical %uint %17419 %uint_9 + %17618 = OpBitwiseAnd %uint %21956 %uint_7 + %15040 = OpIMul %uint %21952 %17618 + %13312 = OpShiftRightLogical %uint %10086 %uint_9 + %24989 = OpBitwiseAnd %uint %13312 %uint_7 + %25225 = OpIMul %uint %10104 %24989 + %19909 = OpIAdd %uint %15040 %25225 + %12645 = OpUDiv %uint %19909 %uint_5 + %8260 = OpShiftLeftLogical %uint %12645 %uint_24 + %6692 = OpBitwiseOr %uint %7573 %8260 + %20401 = OpBitwiseAnd %uint %15826 %15918 + %17412 = OpBitwiseAnd %uint %20401 %uint_1 + %19563 = OpBitwiseAnd %uint %20401 %uint_8 + %24936 = OpShiftLeftLogical %uint %19563 %uint_5 + %17093 = OpBitwiseOr %uint %17412 %24936 + %20874 = OpBitwiseAnd %uint %20401 %uint_64 + %23323 = OpShiftLeftLogical %uint %20874 %uint_10 + %17098 = OpBitwiseOr %uint %17093 %23323 + %20875 = OpBitwiseAnd %uint %20401 %uint_512 + %22050 = OpShiftLeftLogical %uint %20875 %uint_15 + %8315 = OpBitwiseOr %uint %17098 %22050 + %10423 = OpIMul %uint %8315 %uint_255 + %18435 = OpIAdd %uint %6692 %10423 + OpBranch %23555 + %23555 = OpLabel + %19722 = OpPhi %uint %18435 %21930 %18044 %10471 + %13598 = OpCompositeConstruct %v4uint %19722 %19722 %19722 %19722 + %17099 = OpShiftLeftLogical %v4uint %13598 %413 + %21439 = OpBitwiseAnd %v4uint %17099 %2599 + %12257 = OpBitwiseOr %v4uint %19484 %21439 + %23324 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %14517 + OpStore %23324 %12257 + OpSelectionMerge %7207 DontFlatten + OpBranchConditional %17425 %22829 %7207 + %22829 = OpLabel + %15596 = OpIAdd %uint %14517 %6977 + %10967 = OpShiftRightLogical %uint %20728 %uint_8 + %23791 = OpNot %uint %10967 + %21239 = OpCompositeConstruct %v4uint %23791 %23791 %23791 %23791 + %25012 = OpShiftRightLogical %v4uint %21239 %77 + %14395 = OpBitwiseAnd %v4uint %25012 %47 + %15570 = OpIMul %v4uint %14395 %24695 + %21404 = OpCompositeConstruct %v4uint %10967 %10967 %10967 %10967 + %15369 = OpShiftRightLogical %v4uint %21404 %77 + %15307 = OpBitwiseAnd %v4uint %15369 %47 + %7361 = OpIMul %v4uint %15307 %6536 + %7460 = OpIAdd %v4uint %15570 %7361 + %24771 = OpBitwiseAnd %v4uint %7460 %929 + %9230 = OpUDiv %v4uint %24771 %47 + %17619 = OpShiftLeftLogical %v4uint %9230 %749 + %10968 = OpShiftRightLogical %v4uint %7460 %425 + %13254 = OpBitwiseAnd %v4uint %10968 %929 + %17317 = OpUDiv %v4uint %13254 %47 + %17001 = OpShiftLeftLogical %v4uint %17317 %317 + %6323 = OpBitwiseOr %v4uint %17619 %17001 + %15349 = OpShiftRightLogical %v4uint %7460 %965 + %23977 = OpUDiv %v4uint %15349 %47 + %9525 = OpBitwiseOr %v4uint %6323 %23977 + %23685 = OpShiftRightLogical %uint %15826 %uint_12 + OpSelectionMerge %23556 None + OpBranchConditional %20100 %21931 %10472 + %10472 = OpLabel + %8291 = OpNot %uint %23685 + %15362 = OpBitwiseAnd %uint %8291 %uint_7 + %17717 = OpIMul %uint %21952 %15362 + %21985 = OpBitwiseAnd %uint %23685 %uint_7 + %20402 = OpIMul %uint %10104 %21985 + %19852 = OpIAdd %uint %17717 %20402 + %13010 = OpUDiv %uint %19852 %uint_7 + %23032 = OpShiftRightLogical %uint %8291 %uint_3 + %8763 = OpBitwiseAnd %uint %23032 %uint_7 + %15041 = OpIMul %uint %21952 %8763 + %13313 = OpShiftRightLogical %uint %23685 %uint_3 + %24990 = OpBitwiseAnd %uint %13313 %uint_7 + %25226 = OpIMul %uint %10104 %24990 + %19910 = OpIAdd %uint %15041 %25226 + %12646 = OpUDiv %uint %19910 %uint_7 + %8180 = OpShiftLeftLogical %uint %12646 %uint_8 + %7574 = OpBitwiseOr %uint %13010 %8180 + %21957 = OpShiftRightLogical %uint %8291 %uint_6 + %17620 = OpBitwiseAnd %uint %21957 %uint_7 + %15042 = OpIMul %uint %21952 %17620 + %13314 = OpShiftRightLogical %uint %23685 %uint_6 + %24991 = OpBitwiseAnd %uint %13314 %uint_7 + %25227 = OpIMul %uint %10104 %24991 + %19911 = OpIAdd %uint %15042 %25227 + %12647 = OpUDiv %uint %19911 %uint_7 + %8181 = OpShiftLeftLogical %uint %12647 %uint_16 + %7575 = OpBitwiseOr %uint %7574 %8181 + %21958 = OpShiftRightLogical %uint %8291 %uint_9 + %17621 = OpBitwiseAnd %uint %21958 %uint_7 + %15043 = OpIMul %uint %21952 %17621 + %13315 = OpShiftRightLogical %uint %23685 %uint_9 + %24992 = OpBitwiseAnd %uint %13315 %uint_7 + %25228 = OpIMul %uint %10104 %24992 + %19912 = OpIAdd %uint %15043 %25228 + %12648 = OpUDiv %uint %19912 %uint_7 + %9210 = OpShiftLeftLogical %uint %12648 %uint_24 + %18045 = OpBitwiseOr %uint %7575 %9210 + OpBranch %23556 + %21931 = OpLabel + %20087 = OpBitwiseAnd %uint %23685 %uint_1170 + %23956 = OpBitwiseAnd %uint %23685 %uint_2340 + %21852 = OpShiftRightLogical %uint %23956 %uint_1 + %8141 = OpBitwiseAnd %uint %20087 %21852 + %24617 = OpShiftLeftLogical %uint %8141 %uint_1 + %22964 = OpShiftRightLogical %uint %8141 %uint_1 + %18817 = OpBitwiseOr %uint %24617 %22964 + %15919 = OpBitwiseOr %uint %8141 %18817 + %8464 = OpNot %uint %15919 + %10087 = OpBitwiseAnd %uint %23685 %8464 + %16305 = OpISub %uint %uint_2925 %10087 + %17420 = OpBitwiseAnd %uint %16305 %8464 + %17002 = OpBitwiseAnd %uint %17420 %uint_7 + %13682 = OpIMul %uint %21952 %17002 + %21986 = OpBitwiseAnd %uint %10087 %uint_7 + %20406 = OpIMul %uint %10104 %21986 + %19853 = OpIAdd %uint %13682 %20406 + %13011 = OpUDiv %uint %19853 %uint_5 + %23033 = OpShiftRightLogical %uint %17420 %uint_3 + %8764 = OpBitwiseAnd %uint %23033 %uint_7 + %15044 = OpIMul %uint %21952 %8764 + %13316 = OpShiftRightLogical %uint %10087 %uint_3 + %24993 = OpBitwiseAnd %uint %13316 %uint_7 + %25229 = OpIMul %uint %10104 %24993 + %19913 = OpIAdd %uint %15044 %25229 + %12649 = OpUDiv %uint %19913 %uint_5 + %8182 = OpShiftLeftLogical %uint %12649 %uint_8 + %7576 = OpBitwiseOr %uint %13011 %8182 + %21959 = OpShiftRightLogical %uint %17420 %uint_6 + %17622 = OpBitwiseAnd %uint %21959 %uint_7 + %15045 = OpIMul %uint %21952 %17622 + %13317 = OpShiftRightLogical %uint %10087 %uint_6 + %24994 = OpBitwiseAnd %uint %13317 %uint_7 + %25230 = OpIMul %uint %10104 %24994 + %19914 = OpIAdd %uint %15045 %25230 + %12650 = OpUDiv %uint %19914 %uint_5 + %8183 = OpShiftLeftLogical %uint %12650 %uint_16 + %7577 = OpBitwiseOr %uint %7576 %8183 + %21960 = OpShiftRightLogical %uint %17420 %uint_9 + %17623 = OpBitwiseAnd %uint %21960 %uint_7 + %15046 = OpIMul %uint %21952 %17623 + %13318 = OpShiftRightLogical %uint %10087 %uint_9 + %24995 = OpBitwiseAnd %uint %13318 %uint_7 + %25231 = OpIMul %uint %10104 %24995 + %19915 = OpIAdd %uint %15046 %25231 + %12651 = OpUDiv %uint %19915 %uint_5 + %8261 = OpShiftLeftLogical %uint %12651 %uint_24 + %6693 = OpBitwiseOr %uint %7577 %8261 + %20407 = OpBitwiseAnd %uint %23685 %15919 + %17413 = OpBitwiseAnd %uint %20407 %uint_1 + %19564 = OpBitwiseAnd %uint %20407 %uint_8 + %24937 = OpShiftLeftLogical %uint %19564 %uint_5 + %17100 = OpBitwiseOr %uint %17413 %24937 + %20876 = OpBitwiseAnd %uint %20407 %uint_64 + %23325 = OpShiftLeftLogical %uint %20876 %uint_10 + %17101 = OpBitwiseOr %uint %17100 %23325 + %20877 = OpBitwiseAnd %uint %20407 %uint_512 + %22051 = OpShiftLeftLogical %uint %20877 %uint_15 + %8316 = OpBitwiseOr %uint %17101 %22051 + %10424 = OpIMul %uint %8316 %uint_255 + %18436 = OpIAdd %uint %6693 %10424 + OpBranch %23556 + %23556 = OpLabel + %19723 = OpPhi %uint %18436 %21931 %18045 %10472 + %13599 = OpCompositeConstruct %v4uint %19723 %19723 %19723 %19723 + %17102 = OpShiftLeftLogical %v4uint %13599 %413 + %21440 = OpBitwiseAnd %v4uint %17102 %2599 + %12258 = OpBitwiseOr %v4uint %9525 %21440 + %21060 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15596 + OpStore %21060 %12258 + %14842 = OpIAdd %uint %12832 %uint_2 + %11789 = OpULessThan %bool %14842 %6594 + OpSelectionMerge %7206 DontFlatten + OpBranchConditional %11789 %12418 %7206 + %12418 = OpLabel + %13241 = OpShiftRightLogical %uint %9651 %uint_8 + OpSelectionMerge %12690 None + OpBranchConditional %20100 %21932 %10643 + %10643 = OpLabel + %17660 = OpBitwiseAnd %uint %13241 %uint_2396745 + %23913 = OpBitwiseAnd %uint %13241 %uint_4793490 + %22250 = OpShiftRightLogical %uint %23913 %uint_1 + %24005 = OpBitwiseOr %uint %17660 %22250 + %19602 = OpBitwiseAnd %uint %13241 %uint_9586980 + %20618 = OpShiftRightLogical %uint %19602 %uint_2 + %24290 = OpBitwiseOr %uint %24005 %20618 + %7727 = OpBitwiseXor %uint %24290 %uint_2396745 + %9546 = OpNot %uint %22250 + %14627 = OpBitwiseAnd %uint %17660 %9546 + %8431 = OpNot %uint %20618 + %11413 = OpBitwiseAnd %uint %14627 %8431 + %6805 = OpBitwiseOr %uint %13241 %7727 + %19515 = OpISub %uint %6805 %uint_2396745 + %14878 = OpBitwiseOr %uint %19515 %11413 + %18155 = OpShiftLeftLogical %uint %11413 %uint_1 + %16011 = OpBitwiseOr %uint %14878 %18155 + %8121 = OpShiftLeftLogical %uint %11413 %uint_2 + %7811 = OpBitwiseOr %uint %16011 %8121 + OpBranch %12690 + %21932 = OpLabel + %20088 = OpBitwiseAnd %uint %13241 %uint_4793490 + %23957 = OpBitwiseAnd %uint %13241 %uint_9586980 + %21853 = OpShiftRightLogical %uint %23957 %uint_1 + %8142 = OpBitwiseAnd %uint %20088 %21853 + %24618 = OpShiftLeftLogical %uint %8142 %uint_1 + %22965 = OpShiftRightLogical %uint %8142 %uint_1 + %18797 = OpBitwiseOr %uint %24618 %22965 + %16052 = OpBitwiseOr %uint %8142 %18797 + %18312 = OpBitwiseAnd %uint %13241 %uint_2396745 + %14688 = OpBitwiseOr %uint %18312 %uint_14380470 + %20408 = OpBitwiseAnd %uint %14688 %16052 + %20542 = OpShiftRightLogical %uint %20088 %uint_1 + %24925 = OpBitwiseOr %uint %18312 %20542 + %21933 = OpShiftRightLogical %uint %23957 %uint_2 + %22677 = OpBitwiseOr %uint %24925 %21933 + %7728 = OpBitwiseXor %uint %22677 %uint_2396745 + %9547 = OpNot %uint %20542 + %14628 = OpBitwiseAnd %uint %18312 %9547 + %8432 = OpNot %uint %21933 + %11414 = OpBitwiseAnd %uint %14628 %8432 + %6806 = OpBitwiseOr %uint %13241 %7728 + %19516 = OpISub %uint %6806 %uint_2396745 + %14879 = OpBitwiseOr %uint %19516 %11414 + %18231 = OpShiftLeftLogical %uint %11414 %uint_2 + %15363 = OpBitwiseOr %uint %14879 %18231 + %12157 = OpNot %uint %16052 + %18515 = OpBitwiseAnd %uint %15363 %12157 + %6255 = OpBitwiseOr %uint %18515 %20408 + OpBranch %12690 + %12690 = OpLabel + %9431 = OpPhi %uint %6255 %21932 %7811 %10643 + %18790 = OpIMul %uint %uint_2 %6977 + %14391 = OpIAdd %uint %14517 %18790 + %13969 = OpShiftRightLogical %uint %20728 %uint_16 + %23792 = OpNot %uint %13969 + %21240 = OpCompositeConstruct %v4uint %23792 %23792 %23792 %23792 + %25013 = OpShiftRightLogical %v4uint %21240 %77 + %14396 = OpBitwiseAnd %v4uint %25013 %47 + %15571 = OpIMul %v4uint %14396 %24695 + %21405 = OpCompositeConstruct %v4uint %13969 %13969 %13969 %13969 + %15370 = OpShiftRightLogical %v4uint %21405 %77 + %15308 = OpBitwiseAnd %v4uint %15370 %47 + %7362 = OpIMul %v4uint %15308 %6536 + %7461 = OpIAdd %v4uint %15571 %7362 + %24772 = OpBitwiseAnd %v4uint %7461 %929 + %9231 = OpUDiv %v4uint %24772 %47 + %17624 = OpShiftLeftLogical %v4uint %9231 %749 + %10969 = OpShiftRightLogical %v4uint %7461 %425 + %13255 = OpBitwiseAnd %v4uint %10969 %929 + %17318 = OpUDiv %v4uint %13255 %47 + %17003 = OpShiftLeftLogical %v4uint %17318 %317 + %6324 = OpBitwiseOr %v4uint %17624 %17003 + %15350 = OpShiftRightLogical %v4uint %7461 %965 + %24996 = OpUDiv %v4uint %15350 %47 + %19485 = OpBitwiseOr %v4uint %6324 %24996 + OpSelectionMerge %23557 None + OpBranchConditional %20100 %21934 %10473 + %10473 = OpLabel + %8292 = OpNot %uint %9431 + %15364 = OpBitwiseAnd %uint %8292 %uint_7 + %17718 = OpIMul %uint %21952 %15364 + %21987 = OpBitwiseAnd %uint %9431 %uint_7 + %20409 = OpIMul %uint %10104 %21987 + %19854 = OpIAdd %uint %17718 %20409 + %13012 = OpUDiv %uint %19854 %uint_7 + %23034 = OpShiftRightLogical %uint %8292 %uint_3 + %8765 = OpBitwiseAnd %uint %23034 %uint_7 + %15047 = OpIMul %uint %21952 %8765 + %13319 = OpShiftRightLogical %uint %9431 %uint_3 + %24997 = OpBitwiseAnd %uint %13319 %uint_7 + %25232 = OpIMul %uint %10104 %24997 + %19916 = OpIAdd %uint %15047 %25232 + %12652 = OpUDiv %uint %19916 %uint_7 + %8184 = OpShiftLeftLogical %uint %12652 %uint_8 + %7578 = OpBitwiseOr %uint %13012 %8184 + %21961 = OpShiftRightLogical %uint %8292 %uint_6 + %17625 = OpBitwiseAnd %uint %21961 %uint_7 + %15048 = OpIMul %uint %21952 %17625 + %13320 = OpShiftRightLogical %uint %9431 %uint_6 + %24998 = OpBitwiseAnd %uint %13320 %uint_7 + %25233 = OpIMul %uint %10104 %24998 + %19917 = OpIAdd %uint %15048 %25233 + %12653 = OpUDiv %uint %19917 %uint_7 + %8185 = OpShiftLeftLogical %uint %12653 %uint_16 + %7579 = OpBitwiseOr %uint %7578 %8185 + %21962 = OpShiftRightLogical %uint %8292 %uint_9 + %17626 = OpBitwiseAnd %uint %21962 %uint_7 + %15049 = OpIMul %uint %21952 %17626 + %13321 = OpShiftRightLogical %uint %9431 %uint_9 + %24999 = OpBitwiseAnd %uint %13321 %uint_7 + %25234 = OpIMul %uint %10104 %24999 + %19918 = OpIAdd %uint %15049 %25234 + %12654 = OpUDiv %uint %19918 %uint_7 + %9211 = OpShiftLeftLogical %uint %12654 %uint_24 + %18046 = OpBitwiseOr %uint %7579 %9211 + OpBranch %23557 + %21934 = OpLabel + %20089 = OpBitwiseAnd %uint %9431 %uint_1170 + %23958 = OpBitwiseAnd %uint %9431 %uint_2340 + %21854 = OpShiftRightLogical %uint %23958 %uint_1 + %8143 = OpBitwiseAnd %uint %20089 %21854 + %24619 = OpShiftLeftLogical %uint %8143 %uint_1 + %22966 = OpShiftRightLogical %uint %8143 %uint_1 + %18818 = OpBitwiseOr %uint %24619 %22966 + %15920 = OpBitwiseOr %uint %8143 %18818 + %8465 = OpNot %uint %15920 + %10088 = OpBitwiseAnd %uint %9431 %8465 + %16306 = OpISub %uint %uint_2925 %10088 + %17421 = OpBitwiseAnd %uint %16306 %8465 + %17004 = OpBitwiseAnd %uint %17421 %uint_7 + %13683 = OpIMul %uint %21952 %17004 + %21988 = OpBitwiseAnd %uint %10088 %uint_7 + %20410 = OpIMul %uint %10104 %21988 + %19855 = OpIAdd %uint %13683 %20410 + %13013 = OpUDiv %uint %19855 %uint_5 + %23035 = OpShiftRightLogical %uint %17421 %uint_3 + %8766 = OpBitwiseAnd %uint %23035 %uint_7 + %15050 = OpIMul %uint %21952 %8766 + %13322 = OpShiftRightLogical %uint %10088 %uint_3 + %25000 = OpBitwiseAnd %uint %13322 %uint_7 + %25235 = OpIMul %uint %10104 %25000 + %19919 = OpIAdd %uint %15050 %25235 + %12655 = OpUDiv %uint %19919 %uint_5 + %8186 = OpShiftLeftLogical %uint %12655 %uint_8 + %7580 = OpBitwiseOr %uint %13013 %8186 + %21963 = OpShiftRightLogical %uint %17421 %uint_6 + %17627 = OpBitwiseAnd %uint %21963 %uint_7 + %15051 = OpIMul %uint %21952 %17627 + %13323 = OpShiftRightLogical %uint %10088 %uint_6 + %25001 = OpBitwiseAnd %uint %13323 %uint_7 + %25236 = OpIMul %uint %10104 %25001 + %19920 = OpIAdd %uint %15051 %25236 + %12656 = OpUDiv %uint %19920 %uint_5 + %8187 = OpShiftLeftLogical %uint %12656 %uint_16 + %7581 = OpBitwiseOr %uint %7580 %8187 + %21964 = OpShiftRightLogical %uint %17421 %uint_9 + %17628 = OpBitwiseAnd %uint %21964 %uint_7 + %15052 = OpIMul %uint %21952 %17628 + %13324 = OpShiftRightLogical %uint %10088 %uint_9 + %25002 = OpBitwiseAnd %uint %13324 %uint_7 + %25237 = OpIMul %uint %10104 %25002 + %19921 = OpIAdd %uint %15052 %25237 + %12657 = OpUDiv %uint %19921 %uint_5 + %8262 = OpShiftLeftLogical %uint %12657 %uint_24 + %6694 = OpBitwiseOr %uint %7581 %8262 + %20411 = OpBitwiseAnd %uint %9431 %15920 + %17414 = OpBitwiseAnd %uint %20411 %uint_1 + %19565 = OpBitwiseAnd %uint %20411 %uint_8 + %24938 = OpShiftLeftLogical %uint %19565 %uint_5 + %17103 = OpBitwiseOr %uint %17414 %24938 + %20878 = OpBitwiseAnd %uint %20411 %uint_64 + %23326 = OpShiftLeftLogical %uint %20878 %uint_10 + %17104 = OpBitwiseOr %uint %17103 %23326 + %20879 = OpBitwiseAnd %uint %20411 %uint_512 + %22052 = OpShiftLeftLogical %uint %20879 %uint_15 + %8317 = OpBitwiseOr %uint %17104 %22052 + %10425 = OpIMul %uint %8317 %uint_255 + %18437 = OpIAdd %uint %6694 %10425 + OpBranch %23557 + %23557 = OpLabel + %19724 = OpPhi %uint %18437 %21934 %18046 %10473 + %13600 = OpCompositeConstruct %v4uint %19724 %19724 %19724 %19724 + %17105 = OpShiftLeftLogical %v4uint %13600 %413 + %21441 = OpBitwiseAnd %v4uint %17105 %2599 + %12259 = OpBitwiseOr %v4uint %19485 %21441 + %21061 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %14391 + OpStore %21061 %12259 + %14843 = OpIAdd %uint %12832 %uint_3 + %11790 = OpULessThan %bool %14843 %6594 + OpSelectionMerge %18022 DontFlatten + OpBranchConditional %11790 %20883 %18022 + %20883 = OpLabel + %13199 = OpIMul %uint %uint_3 %6977 + %13582 = OpIAdd %uint %14517 %13199 + %13970 = OpShiftRightLogical %uint %20728 %uint_24 + %23793 = OpNot %uint %13970 + %21241 = OpCompositeConstruct %v4uint %23793 %23793 %23793 %23793 + %25014 = OpShiftRightLogical %v4uint %21241 %77 + %14399 = OpBitwiseAnd %v4uint %25014 %47 + %15572 = OpIMul %v4uint %14399 %24695 + %21406 = OpCompositeConstruct %v4uint %13970 %13970 %13970 %13970 + %15371 = OpShiftRightLogical %v4uint %21406 %77 + %15309 = OpBitwiseAnd %v4uint %15371 %47 + %7363 = OpIMul %v4uint %15309 %6536 + %7462 = OpIAdd %v4uint %15572 %7363 + %24773 = OpBitwiseAnd %v4uint %7462 %929 + %9232 = OpUDiv %v4uint %24773 %47 + %17629 = OpShiftLeftLogical %v4uint %9232 %749 + %10970 = OpShiftRightLogical %v4uint %7462 %425 + %13256 = OpBitwiseAnd %v4uint %10970 %929 + %17319 = OpUDiv %v4uint %13256 %47 + %17005 = OpShiftLeftLogical %v4uint %17319 %317 + %6325 = OpBitwiseOr %v4uint %17629 %17005 + %15351 = OpShiftRightLogical %v4uint %7462 %965 + %23978 = OpUDiv %v4uint %15351 %47 + %9526 = OpBitwiseOr %v4uint %6325 %23978 + %23686 = OpShiftRightLogical %uint %9431 %uint_12 + OpSelectionMerge %23558 None + OpBranchConditional %20100 %21967 %10474 + %10474 = OpLabel + %8293 = OpNot %uint %23686 + %15365 = OpBitwiseAnd %uint %8293 %uint_7 + %17719 = OpIMul %uint %21952 %15365 + %21989 = OpBitwiseAnd %uint %23686 %uint_7 + %20412 = OpIMul %uint %10104 %21989 + %19856 = OpIAdd %uint %17719 %20412 + %13014 = OpUDiv %uint %19856 %uint_7 + %23036 = OpShiftRightLogical %uint %8293 %uint_3 + %8767 = OpBitwiseAnd %uint %23036 %uint_7 + %15053 = OpIMul %uint %21952 %8767 + %13325 = OpShiftRightLogical %uint %23686 %uint_3 + %25003 = OpBitwiseAnd %uint %13325 %uint_7 + %25238 = OpIMul %uint %10104 %25003 + %19922 = OpIAdd %uint %15053 %25238 + %12658 = OpUDiv %uint %19922 %uint_7 + %8188 = OpShiftLeftLogical %uint %12658 %uint_8 + %7582 = OpBitwiseOr %uint %13014 %8188 + %21965 = OpShiftRightLogical %uint %8293 %uint_6 + %17630 = OpBitwiseAnd %uint %21965 %uint_7 + %15054 = OpIMul %uint %21952 %17630 + %13326 = OpShiftRightLogical %uint %23686 %uint_6 + %25004 = OpBitwiseAnd %uint %13326 %uint_7 + %25239 = OpIMul %uint %10104 %25004 + %19923 = OpIAdd %uint %15054 %25239 + %12659 = OpUDiv %uint %19923 %uint_7 + %8189 = OpShiftLeftLogical %uint %12659 %uint_16 + %7583 = OpBitwiseOr %uint %7582 %8189 + %21966 = OpShiftRightLogical %uint %8293 %uint_9 + %17631 = OpBitwiseAnd %uint %21966 %uint_7 + %15055 = OpIMul %uint %21952 %17631 + %13327 = OpShiftRightLogical %uint %23686 %uint_9 + %25005 = OpBitwiseAnd %uint %13327 %uint_7 + %25240 = OpIMul %uint %10104 %25005 + %19924 = OpIAdd %uint %15055 %25240 + %12660 = OpUDiv %uint %19924 %uint_7 + %9212 = OpShiftLeftLogical %uint %12660 %uint_24 + %18047 = OpBitwiseOr %uint %7583 %9212 + OpBranch %23558 + %21967 = OpLabel + %20090 = OpBitwiseAnd %uint %23686 %uint_1170 + %23959 = OpBitwiseAnd %uint %23686 %uint_2340 + %21855 = OpShiftRightLogical %uint %23959 %uint_1 + %8144 = OpBitwiseAnd %uint %20090 %21855 + %24620 = OpShiftLeftLogical %uint %8144 %uint_1 + %22967 = OpShiftRightLogical %uint %8144 %uint_1 + %18819 = OpBitwiseOr %uint %24620 %22967 + %15921 = OpBitwiseOr %uint %8144 %18819 + %8466 = OpNot %uint %15921 + %10089 = OpBitwiseAnd %uint %23686 %8466 + %16307 = OpISub %uint %uint_2925 %10089 + %17422 = OpBitwiseAnd %uint %16307 %8466 + %17006 = OpBitwiseAnd %uint %17422 %uint_7 + %13684 = OpIMul %uint %21952 %17006 + %21990 = OpBitwiseAnd %uint %10089 %uint_7 + %20413 = OpIMul %uint %10104 %21990 + %19857 = OpIAdd %uint %13684 %20413 + %13015 = OpUDiv %uint %19857 %uint_5 + %23037 = OpShiftRightLogical %uint %17422 %uint_3 + %8768 = OpBitwiseAnd %uint %23037 %uint_7 + %15056 = OpIMul %uint %21952 %8768 + %13328 = OpShiftRightLogical %uint %10089 %uint_3 + %25006 = OpBitwiseAnd %uint %13328 %uint_7 + %25241 = OpIMul %uint %10104 %25006 + %19925 = OpIAdd %uint %15056 %25241 + %12661 = OpUDiv %uint %19925 %uint_5 + %8190 = OpShiftLeftLogical %uint %12661 %uint_8 + %7584 = OpBitwiseOr %uint %13015 %8190 + %21968 = OpShiftRightLogical %uint %17422 %uint_6 + %17632 = OpBitwiseAnd %uint %21968 %uint_7 + %15057 = OpIMul %uint %21952 %17632 + %13329 = OpShiftRightLogical %uint %10089 %uint_6 + %25007 = OpBitwiseAnd %uint %13329 %uint_7 + %25242 = OpIMul %uint %10104 %25007 + %19926 = OpIAdd %uint %15057 %25242 + %12662 = OpUDiv %uint %19926 %uint_5 + %8191 = OpShiftLeftLogical %uint %12662 %uint_16 + %7585 = OpBitwiseOr %uint %7584 %8191 + %21969 = OpShiftRightLogical %uint %17422 %uint_9 + %17633 = OpBitwiseAnd %uint %21969 %uint_7 + %15058 = OpIMul %uint %21952 %17633 + %13331 = OpShiftRightLogical %uint %10089 %uint_9 + %25008 = OpBitwiseAnd %uint %13331 %uint_7 + %25243 = OpIMul %uint %10104 %25008 + %19927 = OpIAdd %uint %15058 %25243 + %12663 = OpUDiv %uint %19927 %uint_5 + %8263 = OpShiftLeftLogical %uint %12663 %uint_24 + %6695 = OpBitwiseOr %uint %7585 %8263 + %20414 = OpBitwiseAnd %uint %23686 %15921 + %17423 = OpBitwiseAnd %uint %20414 %uint_1 + %19566 = OpBitwiseAnd %uint %20414 %uint_8 + %24939 = OpShiftLeftLogical %uint %19566 %uint_5 + %17106 = OpBitwiseOr %uint %17423 %24939 + %20880 = OpBitwiseAnd %uint %20414 %uint_64 + %23327 = OpShiftLeftLogical %uint %20880 %uint_10 + %17107 = OpBitwiseOr %uint %17106 %23327 + %20881 = OpBitwiseAnd %uint %20414 %uint_512 + %22053 = OpShiftLeftLogical %uint %20881 %uint_15 + %8318 = OpBitwiseOr %uint %17107 %22053 + %10426 = OpIMul %uint %8318 %uint_255 + %18438 = OpIAdd %uint %6695 %10426 + OpBranch %23558 + %23558 = OpLabel + %19725 = OpPhi %uint %18438 %21967 %18047 %10474 + %13601 = OpCompositeConstruct %v4uint %19725 %19725 %19725 %19725 + %17108 = OpShiftLeftLogical %v4uint %13601 %413 + %21442 = OpBitwiseAnd %v4uint %17108 %2599 + %12260 = OpBitwiseOr %v4uint %9526 %21442 + %23358 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13582 + OpStore %23358 %12260 + OpBranch %18022 + %18022 = OpLabel + OpBranch %7206 + %7206 = OpLabel + OpBranch %7207 + %7207 = OpLabel + OpBranch %14903 + %14903 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_dxt5_rgba8_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x0000629C, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A31, 0x0000000D, + 0x0004002B, 0x0000000B, 0x0000012F, 0x000000F8, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0004002B, 0x0000000B, 0x00000B47, 0x0003F000, + 0x0004002B, 0x0000000B, 0x00000A2E, 0x0000000C, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000B, 0x000007FF, 0x0F800000, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x000000E9, 0x00700007, 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, + 0x0004002B, 0x0000000B, 0x00000AC1, 0x00000C00, 0x0004002B, 0x0000000B, 0x00000A09, 0x55555555, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A08, 0xAAAAAAAA, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0007002C, 0x00000017, 0x0000004D, 0x00000A0A, 0x00000A10, 0x00000A16, 0x00000A1C, 0x0004002B, + 0x0000000B, 0x00000A44, 0x000003FF, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, + 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, + 0x0000000B, 0x00000A46, 0x00000014, 0x0004002B, 0x0000000B, 0x000009E9, 0x00249249, 0x0004002B, + 0x0000000B, 0x000009C8, 0x00492492, 0x0004002B, 0x0000000B, 0x00000986, 0x00924924, 0x0004002B, + 0x0000000B, 0x00000944, 0x00DB6DB6, 0x0004002B, 0x0000000B, 0x00000A52, 0x00000018, 0x0004002B, + 0x0000000B, 0x0000003A, 0x00000492, 0x0004002B, 0x0000000B, 0x0000022D, 0x00000924, 0x0004002B, + 0x0000000B, 0x00000908, 0x00000B6D, 0x0004002B, 0x0000000B, 0x00000ACA, 0x00000040, 0x0004002B, + 0x0000000B, 0x00000447, 0x00000200, 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, 0x0004002B, + 0x0000000B, 0x00000144, 0x000000FF, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, + 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, + 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, + 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, + 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, + 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, + 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, + 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, + 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, + 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x000A001E, + 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, + 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, + 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, + 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A1B, + 0x00000A0D, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0006002C, + 0x00000014, 0x00000A3C, 0x00000A10, 0x00000A10, 0x00000A0A, 0x0003001D, 0x000007DC, 0x00000017, + 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A32, 0x00000002, 0x000007B4, 0x0004003B, + 0x00000A32, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0005002C, + 0x00000011, 0x0000076F, 0x00000A0A, 0x00000A22, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, + 0x000007B5, 0x000007DD, 0x00040020, 0x00000A33, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A33, + 0x0000140E, 0x00000002, 0x0007002C, 0x00000017, 0x0000019D, 0x00000A52, 0x00000A3A, 0x00000A22, + 0x00000A0A, 0x0004002B, 0x0000000B, 0x00000580, 0xFF000000, 0x0004002B, 0x0000000B, 0x00000A6A, + 0x00000020, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0004002B, + 0x0000000B, 0x00000A2B, 0x0000000B, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, + 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, + 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, + 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0005002C, + 0x00000011, 0x000003E1, 0x0000012F, 0x0000012F, 0x0005002C, 0x00000011, 0x000003F7, 0x00000B47, + 0x00000B47, 0x0005002C, 0x00000011, 0x000009F3, 0x000007FF, 0x000007FF, 0x0005002C, 0x00000011, + 0x00000778, 0x00000A19, 0x00000A19, 0x0005002C, 0x00000011, 0x000001F7, 0x000000E9, 0x000000E9, + 0x0005002C, 0x00000011, 0x0000078D, 0x00000A1C, 0x00000A1C, 0x0005002C, 0x00000011, 0x0000004E, + 0x00000AC1, 0x00000AC1, 0x0007002C, 0x00000017, 0x00000B3E, 0x00000A09, 0x00000A09, 0x00000A09, + 0x00000A09, 0x0007002C, 0x00000017, 0x00000B86, 0x00000A0D, 0x00000A0D, 0x00000A0D, 0x00000A0D, + 0x0007002C, 0x00000017, 0x00000B2C, 0x00000A08, 0x00000A08, 0x00000A08, 0x00000A08, 0x0005002C, + 0x00000011, 0x00000474, 0x00000144, 0x00000144, 0x0007002C, 0x00000017, 0x0000002F, 0x00000A13, + 0x00000A13, 0x00000A13, 0x00000A13, 0x0007002C, 0x00000017, 0x000003A1, 0x00000A44, 0x00000A44, + 0x00000A44, 0x00000A44, 0x0007002C, 0x00000017, 0x000001A9, 0x00000A28, 0x00000A28, 0x00000A28, + 0x00000A28, 0x0007002C, 0x00000017, 0x000003C5, 0x00000A46, 0x00000A46, 0x00000A46, 0x00000A46, + 0x0007002C, 0x00000017, 0x00000A27, 0x00000580, 0x00000580, 0x00000580, 0x00000580, 0x00050036, + 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00003A37, + 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, + 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, + 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, + 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, + 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, + 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, + 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, + 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, + 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, + 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, + 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, + 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004EBE, 0x00000CE9, 0x00000A1D, 0x0004003D, + 0x0000000B, 0x0000578C, 0x00004EBE, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A20, + 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, + 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A1B, 0x0007004F, 0x00000011, 0x000042F0, + 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, + 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, + 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000036C2, 0x00000002, 0x000400FA, + 0x00006067, 0x000055E8, 0x000036C2, 0x000200F8, 0x000055E8, 0x000200F9, 0x00003A37, 0x000200F8, + 0x000036C2, 0x000500C4, 0x00000014, 0x000043C0, 0x0000538B, 0x00000A3C, 0x0004007C, 0x00000016, + 0x00003C81, 0x000043C0, 0x00050051, 0x0000000C, 0x000047A0, 0x00003C81, 0x00000000, 0x00050084, + 0x0000000C, 0x00002492, 0x000047A0, 0x00000A17, 0x00050051, 0x0000000C, 0x000018DA, 0x00003C81, + 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x000019C2, 0x00050084, 0x0000000C, 0x00002C0F, + 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00003C81, 0x00000001, 0x00050080, + 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x0000578C, + 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, + 0x00002492, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, + 0x00002375, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x00002DCE, 0x00002375, 0x00000A16, + 0x000500C2, 0x0000000B, 0x00001B41, 0x0000578C, 0x00000A16, 0x000300F7, 0x00004A14, 0x00000002, + 0x000400FA, 0x00004376, 0x00001CC4, 0x0000537D, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, + 0x000024C3, 0x0000538B, 0x00050051, 0x0000000C, 0x000022D6, 0x000024C3, 0x00000000, 0x00050084, + 0x0000000C, 0x00002493, 0x000022D6, 0x00000A3B, 0x00050051, 0x0000000C, 0x000018DB, 0x000024C3, + 0x00000002, 0x0004007C, 0x0000000C, 0x000038AA, 0x00005789, 0x00050084, 0x0000000C, 0x00002C10, + 0x000018DB, 0x000038AA, 0x00050051, 0x0000000C, 0x000044BF, 0x000024C3, 0x00000001, 0x00050080, + 0x0000000C, 0x000056D5, 0x00002C10, 0x000044BF, 0x0004007C, 0x0000000C, 0x00005786, 0x00005788, + 0x00050084, 0x0000000C, 0x00001E9F, 0x000056D5, 0x00005786, 0x00050080, 0x0000000C, 0x00001F30, + 0x00002493, 0x00001E9F, 0x000200F9, 0x00004A14, 0x000200F8, 0x00001CC4, 0x000300F7, 0x00001E0B, + 0x00000002, 0x000400FA, 0x00004384, 0x000018D9, 0x0000537E, 0x000200F8, 0x0000537E, 0x0004007C, + 0x00000012, 0x00002970, 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000000, + 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, + 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, + 0x0000000B, 0x00005B4D, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, + 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003F5E, + 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A2B, 0x000500C7, + 0x0000000C, 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x00002747, + 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, + 0x00004397, 0x00002AB6, 0x0000454D, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A16, + 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, + 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00004A8E, 0x00002F76, 0x000500C7, + 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4B, + 0x00003397, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544A, 0x000047B4, 0x00000A17, 0x00050080, 0x0000000C, 0x00004157, 0x00004D30, 0x0000544A, + 0x000500C7, 0x0000000C, 0x00005022, 0x00004157, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, + 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, + 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x00004158, 0x00002416, + 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADD, 0x00004157, 0x00000388, 0x000500C4, 0x0000000C, + 0x0000544B, 0x00004ADD, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x00004158, 0x0000544B, + 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, + 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, + 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544C, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, + 0x00003C4C, 0x00004144, 0x0000544C, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004157, 0x00000AC8, + 0x00050080, 0x0000000C, 0x00002F42, 0x00003C4C, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, + 0x000018D9, 0x0004007C, 0x00000016, 0x000019AD, 0x0000538B, 0x00050051, 0x0000000C, 0x000042C3, + 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FE, 0x000042C3, 0x00000A17, 0x00050051, + 0x0000000C, 0x00002748, 0x000019AD, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, + 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, + 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005321, 0x0000405D, 0x000018AB, 0x00050080, + 0x0000000C, 0x00003B27, 0x000024FE, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, + 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, + 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, 0x000019AD, 0x00000000, 0x000500C3, + 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, + 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A28, 0x000500C7, 0x0000000C, + 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, + 0x000042C3, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, + 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454E, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, + 0x00000A28, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, + 0x00002215, 0x000042C3, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405D, + 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, + 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, + 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000034BD, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544D, 0x00004ADE, 0x00000A0E, 0x00050080, 0x0000000C, + 0x00003C4D, 0x00005A0C, 0x0000544D, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, + 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, + 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, + 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544E, 0x000047B5, 0x00000A28, 0x00050080, 0x0000000C, + 0x00004159, 0x0000285C, 0x0000544E, 0x000500C7, 0x0000000C, 0x00004ADF, 0x000042C3, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544F, 0x00004ADF, 0x00000A17, 0x00050080, 0x0000000C, 0x0000415A, + 0x00004159, 0x0000544F, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4D, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x0000415A, + 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, + 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4D, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, + 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, + 0x0000000C, 0x00005AB2, 0x0000415A, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, + 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005EA0, 0x0000415A, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, 0x00005EA0, + 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, + 0x000018D9, 0x00002F42, 0x0000537E, 0x000200F9, 0x00004A14, 0x000200F8, 0x00004A14, 0x000700F5, + 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, 0x00001F30, 0x0000537D, 0x0004007C, 0x0000000C, + 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, + 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, + 0x00060041, 0x00000294, 0x00004315, 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, + 0x00001CAA, 0x00004315, 0x000500AA, 0x00000009, 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, + 0x00000009, 0x00005376, 0x000061E2, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, + 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, + 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, + 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, + 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, + 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, + 0x00000017, 0x00005879, 0x00001CAA, 0x00004A14, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, + 0x00004CB6, 0x000061E2, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, + 0x000300F7, 0x00002DC8, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x00002DC8, 0x000200F8, + 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, + 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, + 0x000200F9, 0x00002DC8, 0x000200F8, 0x00002DC8, 0x000700F5, 0x00000017, 0x00004C59, 0x00005879, + 0x00003463, 0x000029E8, 0x00002B38, 0x00050051, 0x0000000B, 0x00005F39, 0x00004C59, 0x00000002, + 0x000500C4, 0x0000000B, 0x00003C7F, 0x00005F39, 0x00000A13, 0x000500C2, 0x0000000B, 0x00001951, + 0x00005F39, 0x00000A31, 0x00050050, 0x00000011, 0x00004370, 0x00003C7F, 0x00001951, 0x000500C7, + 0x00000011, 0x0000191E, 0x00004370, 0x000003E1, 0x000500C4, 0x0000000B, 0x0000503F, 0x00005F39, + 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005E64, 0x00005F39, 0x00000A25, 0x00050050, 0x00000011, + 0x00004383, 0x0000503F, 0x00005E64, 0x000500C7, 0x00000011, 0x00001897, 0x00004383, 0x000003F7, + 0x000500C5, 0x00000011, 0x0000375A, 0x0000191E, 0x00001897, 0x000500C4, 0x0000000B, 0x00005C88, + 0x00005F39, 0x00000A2E, 0x000500C2, 0x0000000B, 0x00005817, 0x00005F39, 0x00000A16, 0x00050050, + 0x00000011, 0x00004385, 0x00005C88, 0x00005817, 0x000500C7, 0x00000011, 0x00001871, 0x00004385, + 0x000009F3, 0x000500C5, 0x00000011, 0x00003913, 0x0000375A, 0x00001871, 0x000500C2, 0x00000011, + 0x00005759, 0x00003913, 0x00000778, 0x000500C7, 0x00000011, 0x000018CB, 0x00005759, 0x000001F7, + 0x000500C5, 0x00000011, 0x00004046, 0x00003913, 0x000018CB, 0x000500C2, 0x00000011, 0x0000575A, + 0x00004046, 0x0000078D, 0x000500C7, 0x00000011, 0x00005AE7, 0x0000575A, 0x0000004E, 0x000500C5, + 0x00000011, 0x0000394F, 0x00004046, 0x00005AE7, 0x00050051, 0x0000000B, 0x00004BDE, 0x00004C59, + 0x00000003, 0x00050050, 0x00000011, 0x00003C50, 0x00004BDE, 0x00004BDE, 0x0009004F, 0x00000017, + 0x00006231, 0x00003C50, 0x00003C50, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x000500C7, + 0x00000017, 0x00002C7C, 0x00006231, 0x00000B3E, 0x000500C4, 0x00000017, 0x00005ECA, 0x00002C7C, + 0x00000B86, 0x000500C7, 0x00000017, 0x000050AD, 0x00006231, 0x00000B2C, 0x000500C2, 0x00000017, + 0x000040D7, 0x000050AD, 0x00000B86, 0x000500C5, 0x00000017, 0x00005DC0, 0x00005ECA, 0x000040D7, + 0x000500C7, 0x00000017, 0x00004CA2, 0x00005DC0, 0x00000B2C, 0x000500C2, 0x00000017, 0x0000472B, + 0x00004CA2, 0x00000B86, 0x000500C6, 0x00000017, 0x00003A75, 0x00005DC0, 0x0000472B, 0x00050051, + 0x0000000B, 0x000050F7, 0x00003A75, 0x00000000, 0x0007004F, 0x00000011, 0x00004FA3, 0x00004C59, + 0x00004C59, 0x00000000, 0x00000000, 0x000500C2, 0x00000011, 0x00002344, 0x00004FA3, 0x0000076F, + 0x000500C7, 0x00000011, 0x0000221C, 0x00002344, 0x00000474, 0x00050051, 0x0000000B, 0x00004463, + 0x00004C59, 0x00000000, 0x000500C2, 0x0000000B, 0x000029E7, 0x00004463, 0x00000A3A, 0x00050051, + 0x0000000B, 0x000025B2, 0x00004C59, 0x00000001, 0x000500C7, 0x0000000B, 0x0000185E, 0x000025B2, + 0x00000144, 0x000500C4, 0x0000000B, 0x00005E0E, 0x0000185E, 0x00000A3A, 0x000500C5, 0x0000000B, + 0x00003F71, 0x000029E7, 0x00005E0E, 0x00050051, 0x0000000B, 0x000055B3, 0x0000221C, 0x00000000, + 0x00050051, 0x0000000B, 0x00002777, 0x0000221C, 0x00000001, 0x000500B2, 0x00000009, 0x00004E83, + 0x000055B3, 0x00002777, 0x000300F7, 0x0000369D, 0x00000000, 0x000400FA, 0x00004E83, 0x000055A0, + 0x00002990, 0x000200F8, 0x00002990, 0x000500C7, 0x0000000B, 0x000044F9, 0x00003F71, 0x000009E9, + 0x000500C7, 0x0000000B, 0x00005D66, 0x00003F71, 0x000009C8, 0x000500C2, 0x0000000B, 0x000056E7, + 0x00005D66, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00005DC1, 0x000044F9, 0x000056E7, 0x000500C7, + 0x0000000B, 0x00004C8F, 0x00003F71, 0x00000986, 0x000500C2, 0x0000000B, 0x00005087, 0x00004C8F, + 0x00000A10, 0x000500C5, 0x0000000B, 0x00005EDF, 0x00005DC1, 0x00005087, 0x000500C6, 0x0000000B, + 0x00001E29, 0x00005EDF, 0x000009E9, 0x000400C8, 0x0000000B, 0x00002544, 0x000056E7, 0x000500C7, + 0x0000000B, 0x0000391D, 0x000044F9, 0x00002544, 0x000400C8, 0x0000000B, 0x000020E9, 0x00005087, + 0x000500C7, 0x0000000B, 0x00002C8F, 0x0000391D, 0x000020E9, 0x000500C5, 0x0000000B, 0x00001A8F, + 0x00003F71, 0x00001E29, 0x00050082, 0x0000000B, 0x00004C35, 0x00001A8F, 0x000009E9, 0x000500C5, + 0x0000000B, 0x00003A17, 0x00004C35, 0x00002C8F, 0x000500C4, 0x0000000B, 0x000046E8, 0x00002C8F, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x00003E88, 0x00003A17, 0x000046E8, 0x000500C4, 0x0000000B, + 0x00001FB6, 0x00002C8F, 0x00000A10, 0x000500C5, 0x0000000B, 0x00001E80, 0x00003E88, 0x00001FB6, + 0x000200F9, 0x0000369D, 0x000200F8, 0x000055A0, 0x000500C7, 0x0000000B, 0x00004E6F, 0x00003F71, + 0x000009C8, 0x000500C7, 0x0000000B, 0x00005D8C, 0x00003F71, 0x00000986, 0x000500C2, 0x0000000B, + 0x00005554, 0x00005D8C, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FC5, 0x00004E6F, 0x00005554, + 0x000500C4, 0x0000000B, 0x00006021, 0x00001FC5, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059AC, + 0x00001FC5, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004969, 0x00006021, 0x000059AC, 0x000500C5, + 0x0000000B, 0x00003EB1, 0x00001FC5, 0x00004969, 0x000500C7, 0x0000000B, 0x00004785, 0x00003F71, + 0x000009E9, 0x000500C5, 0x0000000B, 0x0000395D, 0x00004785, 0x00000944, 0x000500C7, 0x0000000B, + 0x00004FB3, 0x0000395D, 0x00003EB1, 0x000500C2, 0x0000000B, 0x0000503B, 0x00004E6F, 0x00000A0D, + 0x000500C5, 0x0000000B, 0x0000615A, 0x00004785, 0x0000503B, 0x000500C2, 0x0000000B, 0x000055A2, + 0x00005D8C, 0x00000A10, 0x000500C5, 0x0000000B, 0x00005892, 0x0000615A, 0x000055A2, 0x000500C6, + 0x0000000B, 0x00001E2A, 0x00005892, 0x000009E9, 0x000400C8, 0x0000000B, 0x00002545, 0x0000503B, + 0x000500C7, 0x0000000B, 0x0000391E, 0x00004785, 0x00002545, 0x000400C8, 0x0000000B, 0x000020EA, + 0x000055A2, 0x000500C7, 0x0000000B, 0x00002C90, 0x0000391E, 0x000020EA, 0x000500C5, 0x0000000B, + 0x00001A90, 0x00003F71, 0x00001E2A, 0x00050082, 0x0000000B, 0x00004C36, 0x00001A90, 0x000009E9, + 0x000500C5, 0x0000000B, 0x00003A18, 0x00004C36, 0x00002C90, 0x000500C4, 0x0000000B, 0x00004734, + 0x00002C90, 0x00000A10, 0x000500C5, 0x0000000B, 0x00003BFA, 0x00003A18, 0x00004734, 0x000400C8, + 0x0000000B, 0x00002F7A, 0x00003EB1, 0x000500C7, 0x0000000B, 0x00004850, 0x00003BFA, 0x00002F7A, + 0x000500C5, 0x0000000B, 0x0000186C, 0x00004850, 0x00004FB3, 0x000200F9, 0x0000369D, 0x000200F8, + 0x0000369D, 0x000700F5, 0x0000000B, 0x00003DD1, 0x0000186C, 0x000055A0, 0x00001E80, 0x00002990, + 0x000400C8, 0x0000000B, 0x000040BB, 0x000050F7, 0x00070050, 0x00000017, 0x000037A0, 0x000040BB, + 0x000040BB, 0x000040BB, 0x000040BB, 0x000500C2, 0x00000017, 0x00005DE8, 0x000037A0, 0x0000004D, + 0x000500C7, 0x00000017, 0x00005AAF, 0x00005DE8, 0x0000002F, 0x00050051, 0x0000000B, 0x00004AB7, + 0x0000394F, 0x00000000, 0x00070050, 0x00000017, 0x00006076, 0x00004AB7, 0x00004AB7, 0x00004AB7, + 0x00004AB7, 0x00050084, 0x00000017, 0x00005FF2, 0x00005AAF, 0x00006076, 0x00070050, 0x00000017, + 0x0000627B, 0x000050F7, 0x000050F7, 0x000050F7, 0x000050F7, 0x000500C2, 0x00000017, 0x0000383D, + 0x0000627B, 0x0000004D, 0x000500C7, 0x00000017, 0x00005AB0, 0x0000383D, 0x0000002F, 0x00050051, + 0x0000000B, 0x00004AB8, 0x0000394F, 0x00000001, 0x00070050, 0x00000017, 0x00001987, 0x00004AB8, + 0x00004AB8, 0x00004AB8, 0x00004AB8, 0x00050084, 0x00000017, 0x00003FE1, 0x00005AB0, 0x00001987, + 0x00050080, 0x00000017, 0x00002C03, 0x00005FF2, 0x00003FE1, 0x000500C7, 0x00000017, 0x000060BE, + 0x00002C03, 0x000003A1, 0x00050086, 0x00000017, 0x00002409, 0x000060BE, 0x0000002F, 0x000500C4, + 0x00000017, 0x000044C8, 0x00002409, 0x000002ED, 0x000500C2, 0x00000017, 0x00002AD1, 0x00002C03, + 0x000001A9, 0x000500C7, 0x00000017, 0x000033C1, 0x00002AD1, 0x000003A1, 0x00050086, 0x00000017, + 0x000043A0, 0x000033C1, 0x0000002F, 0x000500C4, 0x00000017, 0x00004262, 0x000043A0, 0x0000013D, + 0x000500C5, 0x00000017, 0x000018AE, 0x000044C8, 0x00004262, 0x000500C2, 0x00000017, 0x00003BF0, + 0x00002C03, 0x000003C5, 0x00050086, 0x00000017, 0x00006196, 0x00003BF0, 0x0000002F, 0x000500C5, + 0x00000017, 0x00004C1A, 0x000018AE, 0x00006196, 0x000300F7, 0x00005BFF, 0x00000000, 0x000400FA, + 0x00004E83, 0x000055A1, 0x000028E3, 0x000200F8, 0x000028E3, 0x000400C8, 0x0000000B, 0x0000205E, + 0x00003DD1, 0x000500C7, 0x0000000B, 0x00003BFB, 0x0000205E, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00004530, 0x000055B3, 0x00003BFB, 0x000500C7, 0x0000000B, 0x000055D7, 0x00003DD1, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00004FA6, 0x00002777, 0x000055D7, 0x00050080, 0x0000000B, 0x00004D82, + 0x00004530, 0x00004FA6, 0x00050086, 0x0000000B, 0x000032C8, 0x00004D82, 0x00000A1F, 0x000500C2, + 0x0000000B, 0x000059EE, 0x0000205E, 0x00000A13, 0x000500C7, 0x0000000B, 0x00002231, 0x000059EE, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AA3, 0x000055B3, 0x00002231, 0x000500C2, 0x0000000B, + 0x000033E3, 0x00003DD1, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000617D, 0x000033E3, 0x00000A1F, + 0x00050084, 0x0000000B, 0x0000626A, 0x00002777, 0x0000617D, 0x00050080, 0x0000000B, 0x00004DA8, + 0x00003AA3, 0x0000626A, 0x00050086, 0x0000000B, 0x00003148, 0x00004DA8, 0x00000A1F, 0x000500C4, + 0x0000000B, 0x00001FE0, 0x00003148, 0x00000A22, 0x000500C5, 0x0000000B, 0x00001D81, 0x000032C8, + 0x00001FE0, 0x000500C2, 0x0000000B, 0x000055AF, 0x0000205E, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x000044B8, 0x000055AF, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AA4, 0x000055B3, 0x000044B8, + 0x000500C2, 0x0000000B, 0x000033E4, 0x00003DD1, 0x00000A1C, 0x000500C7, 0x0000000B, 0x0000617E, + 0x000033E4, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000626B, 0x00002777, 0x0000617E, 0x00050080, + 0x0000000B, 0x00004DA9, 0x00003AA4, 0x0000626B, 0x00050086, 0x0000000B, 0x00003149, 0x00004DA9, + 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FE1, 0x00003149, 0x00000A3A, 0x000500C5, 0x0000000B, + 0x00001D82, 0x00001D81, 0x00001FE1, 0x000500C2, 0x0000000B, 0x000055B0, 0x0000205E, 0x00000A25, + 0x000500C7, 0x0000000B, 0x000044B9, 0x000055B0, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AA5, + 0x000055B3, 0x000044B9, 0x000500C2, 0x0000000B, 0x000033E5, 0x00003DD1, 0x00000A25, 0x000500C7, + 0x0000000B, 0x0000617F, 0x000033E5, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000626C, 0x00002777, + 0x0000617F, 0x00050080, 0x0000000B, 0x00004DAA, 0x00003AA5, 0x0000626C, 0x00050086, 0x0000000B, + 0x0000314A, 0x00004DAA, 0x00000A1F, 0x000500C4, 0x0000000B, 0x000023F5, 0x0000314A, 0x00000A52, + 0x000500C5, 0x0000000B, 0x00004678, 0x00001D82, 0x000023F5, 0x000200F9, 0x00005BFF, 0x000200F8, + 0x000055A1, 0x000500C7, 0x0000000B, 0x00004E70, 0x00003DD1, 0x0000003A, 0x000500C7, 0x0000000B, + 0x00005D8D, 0x00003DD1, 0x0000022D, 0x000500C2, 0x0000000B, 0x00005555, 0x00005D8D, 0x00000A0D, + 0x000500C7, 0x0000000B, 0x00001FC6, 0x00004E70, 0x00005555, 0x000500C4, 0x0000000B, 0x00006022, + 0x00001FC6, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059AD, 0x00001FC6, 0x00000A0D, 0x000500C5, + 0x0000000B, 0x0000497C, 0x00006022, 0x000059AD, 0x000500C5, 0x0000000B, 0x00003E2A, 0x00001FC6, + 0x0000497C, 0x000400C8, 0x0000000B, 0x0000210B, 0x00003E2A, 0x000500C7, 0x0000000B, 0x00002762, + 0x00003DD1, 0x0000210B, 0x00050082, 0x0000000B, 0x00003FAC, 0x00000908, 0x00002762, 0x000500C7, + 0x0000000B, 0x00004407, 0x00003FAC, 0x0000210B, 0x000500C7, 0x0000000B, 0x0000425F, 0x00004407, + 0x00000A1F, 0x00050084, 0x0000000B, 0x0000356D, 0x000055B3, 0x0000425F, 0x000500C7, 0x0000000B, + 0x000055D8, 0x00002762, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FA7, 0x00002777, 0x000055D8, + 0x00050080, 0x0000000B, 0x00004D83, 0x0000356D, 0x00004FA7, 0x00050086, 0x0000000B, 0x000032C9, + 0x00004D83, 0x00000A19, 0x000500C2, 0x0000000B, 0x000059EF, 0x00004407, 0x00000A13, 0x000500C7, + 0x0000000B, 0x00002232, 0x000059EF, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AA6, 0x000055B3, + 0x00002232, 0x000500C2, 0x0000000B, 0x000033E6, 0x00002762, 0x00000A13, 0x000500C7, 0x0000000B, + 0x00006180, 0x000033E6, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000626D, 0x00002777, 0x00006180, + 0x00050080, 0x0000000B, 0x00004DAB, 0x00003AA6, 0x0000626D, 0x00050086, 0x0000000B, 0x0000314B, + 0x00004DAB, 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FE2, 0x0000314B, 0x00000A22, 0x000500C5, + 0x0000000B, 0x00001D83, 0x000032C9, 0x00001FE2, 0x000500C2, 0x0000000B, 0x000055B1, 0x00004407, + 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044BA, 0x000055B1, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003AA7, 0x000055B3, 0x000044BA, 0x000500C2, 0x0000000B, 0x000033E7, 0x00002762, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x00006181, 0x000033E7, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000626E, + 0x00002777, 0x00006181, 0x00050080, 0x0000000B, 0x00004DAC, 0x00003AA7, 0x0000626E, 0x00050086, + 0x0000000B, 0x0000314C, 0x00004DAC, 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FE3, 0x0000314C, + 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D84, 0x00001D83, 0x00001FE3, 0x000500C2, 0x0000000B, + 0x000055B2, 0x00004407, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044BB, 0x000055B2, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AA8, 0x000055B3, 0x000044BB, 0x000500C2, 0x0000000B, 0x000033E8, + 0x00002762, 0x00000A25, 0x000500C7, 0x0000000B, 0x00006182, 0x000033E8, 0x00000A1F, 0x00050084, + 0x0000000B, 0x0000626F, 0x00002777, 0x00006182, 0x00050080, 0x0000000B, 0x00004DAD, 0x00003AA8, + 0x0000626F, 0x00050086, 0x0000000B, 0x0000314D, 0x00004DAD, 0x00000A19, 0x000500C4, 0x0000000B, + 0x0000203F, 0x0000314D, 0x00000A52, 0x000500C5, 0x0000000B, 0x00001A20, 0x00001D84, 0x0000203F, + 0x000500C7, 0x0000000B, 0x00004FA1, 0x00003DD1, 0x00003E2A, 0x000500C7, 0x0000000B, 0x00004400, + 0x00004FA1, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C67, 0x00004FA1, 0x00000A22, 0x000500C4, + 0x0000000B, 0x00006164, 0x00004C67, 0x00000A19, 0x000500C5, 0x0000000B, 0x000042BB, 0x00004400, + 0x00006164, 0x000500C7, 0x0000000B, 0x00005182, 0x00004FA1, 0x00000ACA, 0x000500C4, 0x0000000B, + 0x00005B17, 0x00005182, 0x00000A28, 0x000500C5, 0x0000000B, 0x000042BC, 0x000042BB, 0x00005B17, + 0x000500C7, 0x0000000B, 0x00005183, 0x00004FA1, 0x00000447, 0x000500C4, 0x0000000B, 0x0000561E, + 0x00005183, 0x00000A37, 0x000500C5, 0x0000000B, 0x00002077, 0x000042BC, 0x0000561E, 0x00050084, + 0x0000000B, 0x000028B3, 0x00002077, 0x00000144, 0x00050080, 0x0000000B, 0x000047FF, 0x00001A20, + 0x000028B3, 0x000200F9, 0x00005BFF, 0x000200F8, 0x00005BFF, 0x000700F5, 0x0000000B, 0x00004D06, + 0x000047FF, 0x000055A1, 0x00004678, 0x000028E3, 0x00070050, 0x00000017, 0x0000351A, 0x00004D06, + 0x00004D06, 0x00004D06, 0x00004D06, 0x000500C4, 0x00000017, 0x000042C6, 0x0000351A, 0x0000019D, + 0x000500C7, 0x00000017, 0x000053BB, 0x000042C6, 0x00000A27, 0x000500C5, 0x00000017, 0x00002FDD, + 0x00004C1A, 0x000053BB, 0x00060041, 0x00000294, 0x00004EC5, 0x0000140E, 0x00000A0B, 0x00002DCE, + 0x0003003E, 0x00004EC5, 0x00002FDD, 0x00050051, 0x0000000B, 0x00003220, 0x000043C0, 0x00000001, + 0x00050080, 0x0000000B, 0x00005AC0, 0x00003220, 0x00000A0D, 0x000500B0, 0x00000009, 0x00004411, + 0x00005AC0, 0x000019C2, 0x000300F7, 0x00001D91, 0x00000002, 0x000400FA, 0x00004411, 0x0000592C, + 0x00001D91, 0x000200F8, 0x0000592C, 0x00050080, 0x0000000B, 0x00003CEB, 0x00002DCE, 0x00001B41, + 0x000500C2, 0x0000000B, 0x00002AD6, 0x000050F7, 0x00000A22, 0x000400C8, 0x0000000B, 0x00005CEC, + 0x00002AD6, 0x00070050, 0x00000017, 0x000052F4, 0x00005CEC, 0x00005CEC, 0x00005CEC, 0x00005CEC, + 0x000500C2, 0x00000017, 0x000061B1, 0x000052F4, 0x0000004D, 0x000500C7, 0x00000017, 0x00003838, + 0x000061B1, 0x0000002F, 0x00050084, 0x00000017, 0x00003CCF, 0x00003838, 0x00006076, 0x00070050, + 0x00000017, 0x00005399, 0x00002AD6, 0x00002AD6, 0x00002AD6, 0x00002AD6, 0x000500C2, 0x00000017, + 0x00003C06, 0x00005399, 0x0000004D, 0x000500C7, 0x00000017, 0x00003BC8, 0x00003C06, 0x0000002F, + 0x00050084, 0x00000017, 0x00001CBE, 0x00003BC8, 0x00001987, 0x00050080, 0x00000017, 0x00001D21, + 0x00003CCF, 0x00001CBE, 0x000500C7, 0x00000017, 0x000060BF, 0x00001D21, 0x000003A1, 0x00050086, + 0x00000017, 0x0000240A, 0x000060BF, 0x0000002F, 0x000500C4, 0x00000017, 0x000044C9, 0x0000240A, + 0x000002ED, 0x000500C2, 0x00000017, 0x00002AD2, 0x00001D21, 0x000001A9, 0x000500C7, 0x00000017, + 0x000033C2, 0x00002AD2, 0x000003A1, 0x00050086, 0x00000017, 0x000043A1, 0x000033C2, 0x0000002F, + 0x000500C4, 0x00000017, 0x00004263, 0x000043A1, 0x0000013D, 0x000500C5, 0x00000017, 0x000018AF, + 0x000044C9, 0x00004263, 0x000500C2, 0x00000017, 0x00003BF1, 0x00001D21, 0x000003C5, 0x00050086, + 0x00000017, 0x00005DA7, 0x00003BF1, 0x0000002F, 0x000500C5, 0x00000017, 0x00002533, 0x000018AF, + 0x00005DA7, 0x000500C2, 0x0000000B, 0x00005C83, 0x00003DD1, 0x00000A2E, 0x000300F7, 0x00005C00, + 0x00000000, 0x000400FA, 0x00004E83, 0x000055A3, 0x000028E4, 0x000200F8, 0x000028E4, 0x000400C8, + 0x0000000B, 0x0000205F, 0x00005C83, 0x000500C7, 0x0000000B, 0x00003BFC, 0x0000205F, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00004531, 0x000055B3, 0x00003BFC, 0x000500C7, 0x0000000B, 0x000055D9, + 0x00005C83, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FA8, 0x00002777, 0x000055D9, 0x00050080, + 0x0000000B, 0x00004D84, 0x00004531, 0x00004FA8, 0x00050086, 0x0000000B, 0x000032CA, 0x00004D84, + 0x00000A1F, 0x000500C2, 0x0000000B, 0x000059F0, 0x0000205F, 0x00000A13, 0x000500C7, 0x0000000B, + 0x00002233, 0x000059F0, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AA9, 0x000055B3, 0x00002233, + 0x000500C2, 0x0000000B, 0x000033E9, 0x00005C83, 0x00000A13, 0x000500C7, 0x0000000B, 0x00006183, + 0x000033E9, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006270, 0x00002777, 0x00006183, 0x00050080, + 0x0000000B, 0x00004DAE, 0x00003AA9, 0x00006270, 0x00050086, 0x0000000B, 0x0000314E, 0x00004DAE, + 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FE4, 0x0000314E, 0x00000A22, 0x000500C5, 0x0000000B, + 0x00001D85, 0x000032CA, 0x00001FE4, 0x000500C2, 0x0000000B, 0x000055B4, 0x0000205F, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x000044BC, 0x000055B4, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AAA, + 0x000055B3, 0x000044BC, 0x000500C2, 0x0000000B, 0x000033EA, 0x00005C83, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x00006184, 0x000033EA, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006271, 0x00002777, + 0x00006184, 0x00050080, 0x0000000B, 0x00004DAF, 0x00003AAA, 0x00006271, 0x00050086, 0x0000000B, + 0x0000314F, 0x00004DAF, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FE5, 0x0000314F, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x00001D86, 0x00001D85, 0x00001FE5, 0x000500C2, 0x0000000B, 0x000055B5, + 0x0000205F, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044BD, 0x000055B5, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AAB, 0x000055B3, 0x000044BD, 0x000500C2, 0x0000000B, 0x000033EB, 0x00005C83, + 0x00000A25, 0x000500C7, 0x0000000B, 0x00006185, 0x000033EB, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00006272, 0x00002777, 0x00006185, 0x00050080, 0x0000000B, 0x00004DB0, 0x00003AAB, 0x00006272, + 0x00050086, 0x0000000B, 0x00003150, 0x00004DB0, 0x00000A1F, 0x000500C4, 0x0000000B, 0x000023F6, + 0x00003150, 0x00000A52, 0x000500C5, 0x0000000B, 0x00004679, 0x00001D86, 0x000023F6, 0x000200F9, + 0x00005C00, 0x000200F8, 0x000055A3, 0x000500C7, 0x0000000B, 0x00004E71, 0x00005C83, 0x0000003A, + 0x000500C7, 0x0000000B, 0x00005D8E, 0x00005C83, 0x0000022D, 0x000500C2, 0x0000000B, 0x00005556, + 0x00005D8E, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FC7, 0x00004E71, 0x00005556, 0x000500C4, + 0x0000000B, 0x00006023, 0x00001FC7, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059AE, 0x00001FC7, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000497D, 0x00006023, 0x000059AE, 0x000500C5, 0x0000000B, + 0x00003E2B, 0x00001FC7, 0x0000497D, 0x000400C8, 0x0000000B, 0x0000210C, 0x00003E2B, 0x000500C7, + 0x0000000B, 0x00002763, 0x00005C83, 0x0000210C, 0x00050082, 0x0000000B, 0x00003FAD, 0x00000908, + 0x00002763, 0x000500C7, 0x0000000B, 0x00004408, 0x00003FAD, 0x0000210C, 0x000500C7, 0x0000000B, + 0x00004260, 0x00004408, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000356E, 0x000055B3, 0x00004260, + 0x000500C7, 0x0000000B, 0x000055DA, 0x00002763, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FA9, + 0x00002777, 0x000055DA, 0x00050080, 0x0000000B, 0x00004D85, 0x0000356E, 0x00004FA9, 0x00050086, + 0x0000000B, 0x000032CB, 0x00004D85, 0x00000A19, 0x000500C2, 0x0000000B, 0x000059F1, 0x00004408, + 0x00000A13, 0x000500C7, 0x0000000B, 0x00002234, 0x000059F1, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003AAC, 0x000055B3, 0x00002234, 0x000500C2, 0x0000000B, 0x000033EC, 0x00002763, 0x00000A13, + 0x000500C7, 0x0000000B, 0x00006186, 0x000033EC, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006273, + 0x00002777, 0x00006186, 0x00050080, 0x0000000B, 0x00004DB1, 0x00003AAC, 0x00006273, 0x00050086, + 0x0000000B, 0x00003151, 0x00004DB1, 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FE6, 0x00003151, + 0x00000A22, 0x000500C5, 0x0000000B, 0x00001D87, 0x000032CB, 0x00001FE6, 0x000500C2, 0x0000000B, + 0x000055B6, 0x00004408, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044C0, 0x000055B6, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AAD, 0x000055B3, 0x000044C0, 0x000500C2, 0x0000000B, 0x000033ED, + 0x00002763, 0x00000A1C, 0x000500C7, 0x0000000B, 0x00006187, 0x000033ED, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00006274, 0x00002777, 0x00006187, 0x00050080, 0x0000000B, 0x00004DB2, 0x00003AAD, + 0x00006274, 0x00050086, 0x0000000B, 0x00003152, 0x00004DB2, 0x00000A19, 0x000500C4, 0x0000000B, + 0x00001FE7, 0x00003152, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D88, 0x00001D87, 0x00001FE7, + 0x000500C2, 0x0000000B, 0x000055B7, 0x00004408, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044C1, + 0x000055B7, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AAE, 0x000055B3, 0x000044C1, 0x000500C2, + 0x0000000B, 0x000033EE, 0x00002763, 0x00000A25, 0x000500C7, 0x0000000B, 0x00006188, 0x000033EE, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00006275, 0x00002777, 0x00006188, 0x00050080, 0x0000000B, + 0x00004DB3, 0x00003AAE, 0x00006275, 0x00050086, 0x0000000B, 0x00003153, 0x00004DB3, 0x00000A19, + 0x000500C4, 0x0000000B, 0x00002040, 0x00003153, 0x00000A52, 0x000500C5, 0x0000000B, 0x00001A21, + 0x00001D88, 0x00002040, 0x000500C7, 0x0000000B, 0x00004FA2, 0x00005C83, 0x00003E2B, 0x000500C7, + 0x0000000B, 0x00004401, 0x00004FA2, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C68, 0x00004FA2, + 0x00000A22, 0x000500C4, 0x0000000B, 0x00006165, 0x00004C68, 0x00000A19, 0x000500C5, 0x0000000B, + 0x000042BD, 0x00004401, 0x00006165, 0x000500C7, 0x0000000B, 0x00005184, 0x00004FA2, 0x00000ACA, + 0x000500C4, 0x0000000B, 0x00005B18, 0x00005184, 0x00000A28, 0x000500C5, 0x0000000B, 0x000042BE, + 0x000042BD, 0x00005B18, 0x000500C7, 0x0000000B, 0x00005185, 0x00004FA2, 0x00000447, 0x000500C4, + 0x0000000B, 0x0000561F, 0x00005185, 0x00000A37, 0x000500C5, 0x0000000B, 0x00002078, 0x000042BE, + 0x0000561F, 0x00050084, 0x0000000B, 0x000028B4, 0x00002078, 0x00000144, 0x00050080, 0x0000000B, + 0x00004800, 0x00001A21, 0x000028B4, 0x000200F9, 0x00005C00, 0x000200F8, 0x00005C00, 0x000700F5, + 0x0000000B, 0x00004D07, 0x00004800, 0x000055A3, 0x00004679, 0x000028E4, 0x00070050, 0x00000017, + 0x0000351B, 0x00004D07, 0x00004D07, 0x00004D07, 0x00004D07, 0x000500C4, 0x00000017, 0x000042C7, + 0x0000351B, 0x0000019D, 0x000500C7, 0x00000017, 0x000053BC, 0x000042C7, 0x00000A27, 0x000500C5, + 0x00000017, 0x00002FDE, 0x00002533, 0x000053BC, 0x00060041, 0x00000294, 0x00005242, 0x0000140E, + 0x00000A0B, 0x00003CEB, 0x0003003E, 0x00005242, 0x00002FDE, 0x00050080, 0x0000000B, 0x000039F8, + 0x00003220, 0x00000A10, 0x000500B0, 0x00000009, 0x00002E0B, 0x000039F8, 0x000019C2, 0x000300F7, + 0x00001C25, 0x00000002, 0x000400FA, 0x00002E0B, 0x00003081, 0x00001C25, 0x000200F8, 0x00003081, + 0x000500C2, 0x0000000B, 0x000033B8, 0x000025B2, 0x00000A22, 0x000300F7, 0x00003191, 0x00000000, + 0x000400FA, 0x00004E83, 0x000055A4, 0x00002991, 0x000200F8, 0x00002991, 0x000500C7, 0x0000000B, + 0x000044FA, 0x000033B8, 0x000009E9, 0x000500C7, 0x0000000B, 0x00005D67, 0x000033B8, 0x000009C8, + 0x000500C2, 0x0000000B, 0x000056E8, 0x00005D67, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00005DC2, + 0x000044FA, 0x000056E8, 0x000500C7, 0x0000000B, 0x00004C90, 0x000033B8, 0x00000986, 0x000500C2, + 0x0000000B, 0x00005088, 0x00004C90, 0x00000A10, 0x000500C5, 0x0000000B, 0x00005EE0, 0x00005DC2, + 0x00005088, 0x000500C6, 0x0000000B, 0x00001E2B, 0x00005EE0, 0x000009E9, 0x000400C8, 0x0000000B, + 0x00002546, 0x000056E8, 0x000500C7, 0x0000000B, 0x0000391F, 0x000044FA, 0x00002546, 0x000400C8, + 0x0000000B, 0x000020EB, 0x00005088, 0x000500C7, 0x0000000B, 0x00002C91, 0x0000391F, 0x000020EB, + 0x000500C5, 0x0000000B, 0x00001A91, 0x000033B8, 0x00001E2B, 0x00050082, 0x0000000B, 0x00004C37, + 0x00001A91, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A19, 0x00004C37, 0x00002C91, 0x000500C4, + 0x0000000B, 0x000046E9, 0x00002C91, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00003E89, 0x00003A19, + 0x000046E9, 0x000500C4, 0x0000000B, 0x00001FB7, 0x00002C91, 0x00000A10, 0x000500C5, 0x0000000B, + 0x00001E81, 0x00003E89, 0x00001FB7, 0x000200F9, 0x00003191, 0x000200F8, 0x000055A4, 0x000500C7, + 0x0000000B, 0x00004E72, 0x000033B8, 0x000009C8, 0x000500C7, 0x0000000B, 0x00005D8F, 0x000033B8, + 0x00000986, 0x000500C2, 0x0000000B, 0x00005557, 0x00005D8F, 0x00000A0D, 0x000500C7, 0x0000000B, + 0x00001FC8, 0x00004E72, 0x00005557, 0x000500C4, 0x0000000B, 0x00006024, 0x00001FC8, 0x00000A0D, + 0x000500C2, 0x0000000B, 0x000059AF, 0x00001FC8, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000496B, + 0x00006024, 0x000059AF, 0x000500C5, 0x0000000B, 0x00003EB2, 0x00001FC8, 0x0000496B, 0x000500C7, + 0x0000000B, 0x00004786, 0x000033B8, 0x000009E9, 0x000500C5, 0x0000000B, 0x0000395E, 0x00004786, + 0x00000944, 0x000500C7, 0x0000000B, 0x00004FB4, 0x0000395E, 0x00003EB2, 0x000500C2, 0x0000000B, + 0x0000503C, 0x00004E72, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000615B, 0x00004786, 0x0000503C, + 0x000500C2, 0x0000000B, 0x000055A5, 0x00005D8F, 0x00000A10, 0x000500C5, 0x0000000B, 0x00005893, + 0x0000615B, 0x000055A5, 0x000500C6, 0x0000000B, 0x00001E2C, 0x00005893, 0x000009E9, 0x000400C8, + 0x0000000B, 0x00002547, 0x0000503C, 0x000500C7, 0x0000000B, 0x00003920, 0x00004786, 0x00002547, + 0x000400C8, 0x0000000B, 0x000020EC, 0x000055A5, 0x000500C7, 0x0000000B, 0x00002C92, 0x00003920, + 0x000020EC, 0x000500C5, 0x0000000B, 0x00001A92, 0x000033B8, 0x00001E2C, 0x00050082, 0x0000000B, + 0x00004C38, 0x00001A92, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A1A, 0x00004C38, 0x00002C92, + 0x000500C4, 0x0000000B, 0x00004735, 0x00002C92, 0x00000A10, 0x000500C5, 0x0000000B, 0x00003BFD, + 0x00003A1A, 0x00004735, 0x000400C8, 0x0000000B, 0x00002F7B, 0x00003EB2, 0x000500C7, 0x0000000B, + 0x00004851, 0x00003BFD, 0x00002F7B, 0x000500C5, 0x0000000B, 0x0000186D, 0x00004851, 0x00004FB4, + 0x000200F9, 0x00003191, 0x000200F8, 0x00003191, 0x000700F5, 0x0000000B, 0x000024D6, 0x0000186D, + 0x000055A4, 0x00001E81, 0x00002991, 0x00050084, 0x0000000B, 0x00004965, 0x00000A10, 0x00001B41, + 0x00050080, 0x0000000B, 0x00003836, 0x00002DCE, 0x00004965, 0x000500C2, 0x0000000B, 0x0000368F, + 0x000050F7, 0x00000A3A, 0x000400C8, 0x0000000B, 0x00005CED, 0x0000368F, 0x00070050, 0x00000017, + 0x000052F5, 0x00005CED, 0x00005CED, 0x00005CED, 0x00005CED, 0x000500C2, 0x00000017, 0x000061B2, + 0x000052F5, 0x0000004D, 0x000500C7, 0x00000017, 0x00003839, 0x000061B2, 0x0000002F, 0x00050084, + 0x00000017, 0x00003CD0, 0x00003839, 0x00006076, 0x00070050, 0x00000017, 0x0000539A, 0x0000368F, + 0x0000368F, 0x0000368F, 0x0000368F, 0x000500C2, 0x00000017, 0x00003C07, 0x0000539A, 0x0000004D, + 0x000500C7, 0x00000017, 0x00003BC9, 0x00003C07, 0x0000002F, 0x00050084, 0x00000017, 0x00001CBF, + 0x00003BC9, 0x00001987, 0x00050080, 0x00000017, 0x00001D22, 0x00003CD0, 0x00001CBF, 0x000500C7, + 0x00000017, 0x000060C0, 0x00001D22, 0x000003A1, 0x00050086, 0x00000017, 0x0000240B, 0x000060C0, + 0x0000002F, 0x000500C4, 0x00000017, 0x000044CA, 0x0000240B, 0x000002ED, 0x000500C2, 0x00000017, + 0x00002AD3, 0x00001D22, 0x000001A9, 0x000500C7, 0x00000017, 0x000033C3, 0x00002AD3, 0x000003A1, + 0x00050086, 0x00000017, 0x000043A2, 0x000033C3, 0x0000002F, 0x000500C4, 0x00000017, 0x00004264, + 0x000043A2, 0x0000013D, 0x000500C5, 0x00000017, 0x000018B0, 0x000044CA, 0x00004264, 0x000500C2, + 0x00000017, 0x00003BF2, 0x00001D22, 0x000003C5, 0x00050086, 0x00000017, 0x00006197, 0x00003BF2, + 0x0000002F, 0x000500C5, 0x00000017, 0x00004C1B, 0x000018B0, 0x00006197, 0x000300F7, 0x00005C01, + 0x00000000, 0x000400FA, 0x00004E83, 0x000055A6, 0x000028E5, 0x000200F8, 0x000028E5, 0x000400C8, + 0x0000000B, 0x00002060, 0x000024D6, 0x000500C7, 0x0000000B, 0x00003BFE, 0x00002060, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00004532, 0x000055B3, 0x00003BFE, 0x000500C7, 0x0000000B, 0x000055DB, + 0x000024D6, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FAA, 0x00002777, 0x000055DB, 0x00050080, + 0x0000000B, 0x00004D86, 0x00004532, 0x00004FAA, 0x00050086, 0x0000000B, 0x000032CC, 0x00004D86, + 0x00000A1F, 0x000500C2, 0x0000000B, 0x000059F2, 0x00002060, 0x00000A13, 0x000500C7, 0x0000000B, + 0x00002235, 0x000059F2, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AAF, 0x000055B3, 0x00002235, + 0x000500C2, 0x0000000B, 0x000033EF, 0x000024D6, 0x00000A13, 0x000500C7, 0x0000000B, 0x00006189, + 0x000033EF, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006276, 0x00002777, 0x00006189, 0x00050080, + 0x0000000B, 0x00004DB4, 0x00003AAF, 0x00006276, 0x00050086, 0x0000000B, 0x00003154, 0x00004DB4, + 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FE8, 0x00003154, 0x00000A22, 0x000500C5, 0x0000000B, + 0x00001D89, 0x000032CC, 0x00001FE8, 0x000500C2, 0x0000000B, 0x000055B8, 0x00002060, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x000044C2, 0x000055B8, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB0, + 0x000055B3, 0x000044C2, 0x000500C2, 0x0000000B, 0x000033F0, 0x000024D6, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x0000618A, 0x000033F0, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006277, 0x00002777, + 0x0000618A, 0x00050080, 0x0000000B, 0x00004DB5, 0x00003AB0, 0x00006277, 0x00050086, 0x0000000B, + 0x00003155, 0x00004DB5, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FE9, 0x00003155, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x00001D8A, 0x00001D89, 0x00001FE9, 0x000500C2, 0x0000000B, 0x000055B9, + 0x00002060, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044C3, 0x000055B9, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AB1, 0x000055B3, 0x000044C3, 0x000500C2, 0x0000000B, 0x000033F1, 0x000024D6, + 0x00000A25, 0x000500C7, 0x0000000B, 0x0000618B, 0x000033F1, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00006278, 0x00002777, 0x0000618B, 0x00050080, 0x0000000B, 0x00004DB6, 0x00003AB1, 0x00006278, + 0x00050086, 0x0000000B, 0x00003156, 0x00004DB6, 0x00000A1F, 0x000500C4, 0x0000000B, 0x000023F7, + 0x00003156, 0x00000A52, 0x000500C5, 0x0000000B, 0x0000467A, 0x00001D8A, 0x000023F7, 0x000200F9, + 0x00005C01, 0x000200F8, 0x000055A6, 0x000500C7, 0x0000000B, 0x00004E73, 0x000024D6, 0x0000003A, + 0x000500C7, 0x0000000B, 0x00005D90, 0x000024D6, 0x0000022D, 0x000500C2, 0x0000000B, 0x00005558, + 0x00005D90, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FC9, 0x00004E73, 0x00005558, 0x000500C4, + 0x0000000B, 0x00006025, 0x00001FC9, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059B0, 0x00001FC9, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000497E, 0x00006025, 0x000059B0, 0x000500C5, 0x0000000B, + 0x00003E2C, 0x00001FC9, 0x0000497E, 0x000400C8, 0x0000000B, 0x0000210D, 0x00003E2C, 0x000500C7, + 0x0000000B, 0x00002764, 0x000024D6, 0x0000210D, 0x00050082, 0x0000000B, 0x00003FAE, 0x00000908, + 0x00002764, 0x000500C7, 0x0000000B, 0x00004409, 0x00003FAE, 0x0000210D, 0x000500C7, 0x0000000B, + 0x00004261, 0x00004409, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000356F, 0x000055B3, 0x00004261, + 0x000500C7, 0x0000000B, 0x000055DC, 0x00002764, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FAB, + 0x00002777, 0x000055DC, 0x00050080, 0x0000000B, 0x00004D87, 0x0000356F, 0x00004FAB, 0x00050086, + 0x0000000B, 0x000032CD, 0x00004D87, 0x00000A19, 0x000500C2, 0x0000000B, 0x000059F3, 0x00004409, + 0x00000A13, 0x000500C7, 0x0000000B, 0x00002236, 0x000059F3, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003AB2, 0x000055B3, 0x00002236, 0x000500C2, 0x0000000B, 0x000033F2, 0x00002764, 0x00000A13, + 0x000500C7, 0x0000000B, 0x0000618C, 0x000033F2, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006279, + 0x00002777, 0x0000618C, 0x00050080, 0x0000000B, 0x00004DB7, 0x00003AB2, 0x00006279, 0x00050086, + 0x0000000B, 0x00003157, 0x00004DB7, 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FEA, 0x00003157, + 0x00000A22, 0x000500C5, 0x0000000B, 0x00001D8B, 0x000032CD, 0x00001FEA, 0x000500C2, 0x0000000B, + 0x000055BA, 0x00004409, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044C4, 0x000055BA, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AB3, 0x000055B3, 0x000044C4, 0x000500C2, 0x0000000B, 0x000033F3, + 0x00002764, 0x00000A1C, 0x000500C7, 0x0000000B, 0x0000618D, 0x000033F3, 0x00000A1F, 0x00050084, + 0x0000000B, 0x0000627A, 0x00002777, 0x0000618D, 0x00050080, 0x0000000B, 0x00004DB8, 0x00003AB3, + 0x0000627A, 0x00050086, 0x0000000B, 0x00003158, 0x00004DB8, 0x00000A19, 0x000500C4, 0x0000000B, + 0x00001FEB, 0x00003158, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D8C, 0x00001D8B, 0x00001FEB, + 0x000500C2, 0x0000000B, 0x000055BB, 0x00004409, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044C5, + 0x000055BB, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB4, 0x000055B3, 0x000044C5, 0x000500C2, + 0x0000000B, 0x000033F4, 0x00002764, 0x00000A25, 0x000500C7, 0x0000000B, 0x0000618E, 0x000033F4, + 0x00000A1F, 0x00050084, 0x0000000B, 0x0000627C, 0x00002777, 0x0000618E, 0x00050080, 0x0000000B, + 0x00004DB9, 0x00003AB4, 0x0000627C, 0x00050086, 0x0000000B, 0x00003159, 0x00004DB9, 0x00000A19, + 0x000500C4, 0x0000000B, 0x00002041, 0x00003159, 0x00000A52, 0x000500C5, 0x0000000B, 0x00001A22, + 0x00001D8C, 0x00002041, 0x000500C7, 0x0000000B, 0x00004FA4, 0x000024D6, 0x00003E2C, 0x000500C7, + 0x0000000B, 0x00004402, 0x00004FA4, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C69, 0x00004FA4, + 0x00000A22, 0x000500C4, 0x0000000B, 0x00006166, 0x00004C69, 0x00000A19, 0x000500C5, 0x0000000B, + 0x000042BF, 0x00004402, 0x00006166, 0x000500C7, 0x0000000B, 0x00005186, 0x00004FA4, 0x00000ACA, + 0x000500C4, 0x0000000B, 0x00005B19, 0x00005186, 0x00000A28, 0x000500C5, 0x0000000B, 0x000042C0, + 0x000042BF, 0x00005B19, 0x000500C7, 0x0000000B, 0x00005187, 0x00004FA4, 0x00000447, 0x000500C4, + 0x0000000B, 0x00005620, 0x00005187, 0x00000A37, 0x000500C5, 0x0000000B, 0x00002079, 0x000042C0, + 0x00005620, 0x00050084, 0x0000000B, 0x000028B5, 0x00002079, 0x00000144, 0x00050080, 0x0000000B, + 0x00004801, 0x00001A22, 0x000028B5, 0x000200F9, 0x00005C01, 0x000200F8, 0x00005C01, 0x000700F5, + 0x0000000B, 0x00004D08, 0x00004801, 0x000055A6, 0x0000467A, 0x000028E5, 0x00070050, 0x00000017, + 0x0000351C, 0x00004D08, 0x00004D08, 0x00004D08, 0x00004D08, 0x000500C4, 0x00000017, 0x000042C8, + 0x0000351C, 0x0000019D, 0x000500C7, 0x00000017, 0x000053BD, 0x000042C8, 0x00000A27, 0x000500C5, + 0x00000017, 0x00002FDF, 0x00004C1B, 0x000053BD, 0x00060041, 0x00000294, 0x00005243, 0x0000140E, + 0x00000A0B, 0x00003836, 0x0003003E, 0x00005243, 0x00002FDF, 0x00050080, 0x0000000B, 0x000039F9, + 0x00003220, 0x00000A13, 0x000500B0, 0x00000009, 0x00002E0C, 0x000039F9, 0x000019C2, 0x000300F7, + 0x00004665, 0x00000002, 0x000400FA, 0x00002E0C, 0x00005192, 0x00004665, 0x000200F8, 0x00005192, + 0x00050084, 0x0000000B, 0x0000338E, 0x00000A13, 0x00001B41, 0x00050080, 0x0000000B, 0x0000350D, + 0x00002DCE, 0x0000338E, 0x000500C2, 0x0000000B, 0x00003690, 0x000050F7, 0x00000A52, 0x000400C8, + 0x0000000B, 0x00005CEE, 0x00003690, 0x00070050, 0x00000017, 0x000052F6, 0x00005CEE, 0x00005CEE, + 0x00005CEE, 0x00005CEE, 0x000500C2, 0x00000017, 0x000061B3, 0x000052F6, 0x0000004D, 0x000500C7, + 0x00000017, 0x0000383A, 0x000061B3, 0x0000002F, 0x00050084, 0x00000017, 0x00003CD1, 0x0000383A, + 0x00006076, 0x00070050, 0x00000017, 0x0000539B, 0x00003690, 0x00003690, 0x00003690, 0x00003690, + 0x000500C2, 0x00000017, 0x00003C08, 0x0000539B, 0x0000004D, 0x000500C7, 0x00000017, 0x00003BCA, + 0x00003C08, 0x0000002F, 0x00050084, 0x00000017, 0x00001CC0, 0x00003BCA, 0x00001987, 0x00050080, + 0x00000017, 0x00001D23, 0x00003CD1, 0x00001CC0, 0x000500C7, 0x00000017, 0x000060C1, 0x00001D23, + 0x000003A1, 0x00050086, 0x00000017, 0x0000240C, 0x000060C1, 0x0000002F, 0x000500C4, 0x00000017, + 0x000044CB, 0x0000240C, 0x000002ED, 0x000500C2, 0x00000017, 0x00002AD4, 0x00001D23, 0x000001A9, + 0x000500C7, 0x00000017, 0x000033C4, 0x00002AD4, 0x000003A1, 0x00050086, 0x00000017, 0x000043A3, + 0x000033C4, 0x0000002F, 0x000500C4, 0x00000017, 0x00004265, 0x000043A3, 0x0000013D, 0x000500C5, + 0x00000017, 0x000018B1, 0x000044CB, 0x00004265, 0x000500C2, 0x00000017, 0x00003BF3, 0x00001D23, + 0x000003C5, 0x00050086, 0x00000017, 0x00005DA8, 0x00003BF3, 0x0000002F, 0x000500C5, 0x00000017, + 0x00002534, 0x000018B1, 0x00005DA8, 0x000500C2, 0x0000000B, 0x00005C84, 0x000024D6, 0x00000A2E, + 0x000300F7, 0x00005C02, 0x00000000, 0x000400FA, 0x00004E83, 0x000055A7, 0x000028E6, 0x000200F8, + 0x000028E6, 0x000400C8, 0x0000000B, 0x00002061, 0x00005C84, 0x000500C7, 0x0000000B, 0x00003BFF, + 0x00002061, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004533, 0x000055B3, 0x00003BFF, 0x000500C7, + 0x0000000B, 0x000055DD, 0x00005C84, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FAC, 0x00002777, + 0x000055DD, 0x00050080, 0x0000000B, 0x00004D88, 0x00004533, 0x00004FAC, 0x00050086, 0x0000000B, + 0x000032CE, 0x00004D88, 0x00000A1F, 0x000500C2, 0x0000000B, 0x000059F4, 0x00002061, 0x00000A13, + 0x000500C7, 0x0000000B, 0x00002237, 0x000059F4, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB5, + 0x000055B3, 0x00002237, 0x000500C2, 0x0000000B, 0x000033F5, 0x00005C84, 0x00000A13, 0x000500C7, + 0x0000000B, 0x0000618F, 0x000033F5, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000627D, 0x00002777, + 0x0000618F, 0x00050080, 0x0000000B, 0x00004DBA, 0x00003AB5, 0x0000627D, 0x00050086, 0x0000000B, + 0x0000315A, 0x00004DBA, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FEC, 0x0000315A, 0x00000A22, + 0x000500C5, 0x0000000B, 0x00001D8D, 0x000032CE, 0x00001FEC, 0x000500C2, 0x0000000B, 0x000055BC, + 0x00002061, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044C6, 0x000055BC, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AB6, 0x000055B3, 0x000044C6, 0x000500C2, 0x0000000B, 0x000033F6, 0x00005C84, + 0x00000A1C, 0x000500C7, 0x0000000B, 0x00006190, 0x000033F6, 0x00000A1F, 0x00050084, 0x0000000B, + 0x0000627E, 0x00002777, 0x00006190, 0x00050080, 0x0000000B, 0x00004DBB, 0x00003AB6, 0x0000627E, + 0x00050086, 0x0000000B, 0x0000315B, 0x00004DBB, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FED, + 0x0000315B, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D8E, 0x00001D8D, 0x00001FED, 0x000500C2, + 0x0000000B, 0x000055BD, 0x00002061, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044C7, 0x000055BD, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB7, 0x000055B3, 0x000044C7, 0x000500C2, 0x0000000B, + 0x000033F7, 0x00005C84, 0x00000A25, 0x000500C7, 0x0000000B, 0x00006191, 0x000033F7, 0x00000A1F, + 0x00050084, 0x0000000B, 0x0000627F, 0x00002777, 0x00006191, 0x00050080, 0x0000000B, 0x00004DBC, + 0x00003AB7, 0x0000627F, 0x00050086, 0x0000000B, 0x0000315C, 0x00004DBC, 0x00000A1F, 0x000500C4, + 0x0000000B, 0x000023F8, 0x0000315C, 0x00000A52, 0x000500C5, 0x0000000B, 0x0000467B, 0x00001D8E, + 0x000023F8, 0x000200F9, 0x00005C02, 0x000200F8, 0x000055A7, 0x000500C7, 0x0000000B, 0x00004E74, + 0x00005C84, 0x0000003A, 0x000500C7, 0x0000000B, 0x00005D91, 0x00005C84, 0x0000022D, 0x000500C2, + 0x0000000B, 0x00005559, 0x00005D91, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FCA, 0x00004E74, + 0x00005559, 0x000500C4, 0x0000000B, 0x00006026, 0x00001FCA, 0x00000A0D, 0x000500C2, 0x0000000B, + 0x000059B1, 0x00001FCA, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000497F, 0x00006026, 0x000059B1, + 0x000500C5, 0x0000000B, 0x00003E2D, 0x00001FCA, 0x0000497F, 0x000400C8, 0x0000000B, 0x0000210E, + 0x00003E2D, 0x000500C7, 0x0000000B, 0x00002765, 0x00005C84, 0x0000210E, 0x00050082, 0x0000000B, + 0x00003FAF, 0x00000908, 0x00002765, 0x000500C7, 0x0000000B, 0x0000440A, 0x00003FAF, 0x0000210E, + 0x000500C7, 0x0000000B, 0x00004266, 0x0000440A, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003570, + 0x000055B3, 0x00004266, 0x000500C7, 0x0000000B, 0x000055DE, 0x00002765, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00004FAD, 0x00002777, 0x000055DE, 0x00050080, 0x0000000B, 0x00004D89, 0x00003570, + 0x00004FAD, 0x00050086, 0x0000000B, 0x000032CF, 0x00004D89, 0x00000A19, 0x000500C2, 0x0000000B, + 0x000059F5, 0x0000440A, 0x00000A13, 0x000500C7, 0x0000000B, 0x00002238, 0x000059F5, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AB8, 0x000055B3, 0x00002238, 0x000500C2, 0x0000000B, 0x000033F8, + 0x00002765, 0x00000A13, 0x000500C7, 0x0000000B, 0x00006192, 0x000033F8, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00006280, 0x00002777, 0x00006192, 0x00050080, 0x0000000B, 0x00004DBD, 0x00003AB8, + 0x00006280, 0x00050086, 0x0000000B, 0x0000315D, 0x00004DBD, 0x00000A19, 0x000500C4, 0x0000000B, + 0x00001FEE, 0x0000315D, 0x00000A22, 0x000500C5, 0x0000000B, 0x00001D8F, 0x000032CF, 0x00001FEE, + 0x000500C2, 0x0000000B, 0x000055BE, 0x0000440A, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044CC, + 0x000055BE, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB9, 0x000055B3, 0x000044CC, 0x000500C2, + 0x0000000B, 0x000033F9, 0x00002765, 0x00000A1C, 0x000500C7, 0x0000000B, 0x00006193, 0x000033F9, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00006281, 0x00002777, 0x00006193, 0x00050080, 0x0000000B, + 0x00004DBE, 0x00003AB9, 0x00006281, 0x00050086, 0x0000000B, 0x0000315E, 0x00004DBE, 0x00000A19, + 0x000500C4, 0x0000000B, 0x00001FEF, 0x0000315E, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D90, + 0x00001D8F, 0x00001FEF, 0x000500C2, 0x0000000B, 0x000055BF, 0x0000440A, 0x00000A25, 0x000500C7, + 0x0000000B, 0x000044CD, 0x000055BF, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ABA, 0x000055B3, + 0x000044CD, 0x000500C2, 0x0000000B, 0x000033FA, 0x00002765, 0x00000A25, 0x000500C7, 0x0000000B, + 0x00006194, 0x000033FA, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006282, 0x00002777, 0x00006194, + 0x00050080, 0x0000000B, 0x00004DBF, 0x00003ABA, 0x00006282, 0x00050086, 0x0000000B, 0x0000315F, + 0x00004DBF, 0x00000A19, 0x000500C4, 0x0000000B, 0x00002043, 0x0000315F, 0x00000A52, 0x000500C5, + 0x0000000B, 0x00001A23, 0x00001D90, 0x00002043, 0x000500C7, 0x0000000B, 0x00004FA5, 0x00005C84, + 0x00003E2D, 0x000500C7, 0x0000000B, 0x00004403, 0x00004FA5, 0x00000A0D, 0x000500C7, 0x0000000B, + 0x00004C6A, 0x00004FA5, 0x00000A22, 0x000500C4, 0x0000000B, 0x00006167, 0x00004C6A, 0x00000A19, + 0x000500C5, 0x0000000B, 0x000042C1, 0x00004403, 0x00006167, 0x000500C7, 0x0000000B, 0x00005188, + 0x00004FA5, 0x00000ACA, 0x000500C4, 0x0000000B, 0x00005B1A, 0x00005188, 0x00000A28, 0x000500C5, + 0x0000000B, 0x000042C4, 0x000042C1, 0x00005B1A, 0x000500C7, 0x0000000B, 0x00005189, 0x00004FA5, + 0x00000447, 0x000500C4, 0x0000000B, 0x00005621, 0x00005189, 0x00000A37, 0x000500C5, 0x0000000B, + 0x0000207A, 0x000042C4, 0x00005621, 0x00050084, 0x0000000B, 0x000028B6, 0x0000207A, 0x00000144, + 0x00050080, 0x0000000B, 0x00004802, 0x00001A23, 0x000028B6, 0x000200F9, 0x00005C02, 0x000200F8, + 0x00005C02, 0x000700F5, 0x0000000B, 0x00004D09, 0x00004802, 0x000055A7, 0x0000467B, 0x000028E6, + 0x00070050, 0x00000017, 0x0000351D, 0x00004D09, 0x00004D09, 0x00004D09, 0x00004D09, 0x000500C4, + 0x00000017, 0x000042C9, 0x0000351D, 0x0000019D, 0x000500C7, 0x00000017, 0x000053BE, 0x000042C9, + 0x00000A27, 0x000500C5, 0x00000017, 0x00002FE0, 0x00002534, 0x000053BE, 0x00060041, 0x00000294, + 0x00005B3D, 0x0000140E, 0x00000A0B, 0x0000350D, 0x0003003E, 0x00005B3D, 0x00002FE0, 0x000200F9, + 0x00004665, 0x000200F8, 0x00004665, 0x000200F9, 0x00001C25, 0x000200F8, 0x00001C25, 0x000200F9, + 0x00001D91, 0x000200F8, 0x00001D91, 0x00050080, 0x0000000B, 0x000038B5, 0x00002DCE, 0x00000A0E, + 0x000600A9, 0x0000000B, 0x00004705, 0x00004376, 0x00000A10, 0x00000A0D, 0x00050080, 0x0000000B, + 0x0000417A, 0x00005665, 0x00004705, 0x00060041, 0x00000294, 0x00004766, 0x0000107A, 0x00000A0B, + 0x0000417A, 0x0004003D, 0x00000017, 0x000019B2, 0x00004766, 0x000300F7, 0x00003A1B, 0x00000000, + 0x000400FA, 0x00005686, 0x00002958, 0x00003A1B, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, + 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AE, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, + 0x000050AE, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, + 0x00003A1B, 0x000200F8, 0x00003A1B, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x00001D91, + 0x00003FF9, 0x00002958, 0x000300F7, 0x00002DC9, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, + 0x00002DC9, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, + 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, + 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002DC9, 0x000200F8, 0x00002DC9, 0x000700F5, 0x00000017, + 0x00004C5A, 0x00002AAC, 0x00003A1B, 0x000029E9, 0x00002B39, 0x00050051, 0x0000000B, 0x00005F3A, + 0x00004C5A, 0x00000002, 0x000500C4, 0x0000000B, 0x00003C80, 0x00005F3A, 0x00000A13, 0x000500C2, + 0x0000000B, 0x00001952, 0x00005F3A, 0x00000A31, 0x00050050, 0x00000011, 0x00004371, 0x00003C80, + 0x00001952, 0x000500C7, 0x00000011, 0x0000191F, 0x00004371, 0x000003E1, 0x000500C4, 0x0000000B, + 0x00005040, 0x00005F3A, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005E65, 0x00005F3A, 0x00000A25, + 0x00050050, 0x00000011, 0x00004386, 0x00005040, 0x00005E65, 0x000500C7, 0x00000011, 0x00001898, + 0x00004386, 0x000003F7, 0x000500C5, 0x00000011, 0x0000375B, 0x0000191F, 0x00001898, 0x000500C4, + 0x0000000B, 0x00005C89, 0x00005F3A, 0x00000A2E, 0x000500C2, 0x0000000B, 0x00005818, 0x00005F3A, + 0x00000A16, 0x00050050, 0x00000011, 0x00004387, 0x00005C89, 0x00005818, 0x000500C7, 0x00000011, + 0x00001872, 0x00004387, 0x000009F3, 0x000500C5, 0x00000011, 0x00003914, 0x0000375B, 0x00001872, + 0x000500C2, 0x00000011, 0x0000575B, 0x00003914, 0x00000778, 0x000500C7, 0x00000011, 0x000018CC, + 0x0000575B, 0x000001F7, 0x000500C5, 0x00000011, 0x00004047, 0x00003914, 0x000018CC, 0x000500C2, + 0x00000011, 0x0000575C, 0x00004047, 0x0000078D, 0x000500C7, 0x00000011, 0x00005AE8, 0x0000575C, + 0x0000004E, 0x000500C5, 0x00000011, 0x00003950, 0x00004047, 0x00005AE8, 0x00050051, 0x0000000B, + 0x00004BDF, 0x00004C5A, 0x00000003, 0x00050050, 0x00000011, 0x00003C51, 0x00004BDF, 0x00004BDF, + 0x0009004F, 0x00000017, 0x00006232, 0x00003C51, 0x00003C51, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x000500C7, 0x00000017, 0x00002C7D, 0x00006232, 0x00000B3E, 0x000500C4, 0x00000017, + 0x00005ECB, 0x00002C7D, 0x00000B86, 0x000500C7, 0x00000017, 0x000050AF, 0x00006232, 0x00000B2C, + 0x000500C2, 0x00000017, 0x000040D8, 0x000050AF, 0x00000B86, 0x000500C5, 0x00000017, 0x00005DC3, + 0x00005ECB, 0x000040D8, 0x000500C7, 0x00000017, 0x00004CA3, 0x00005DC3, 0x00000B2C, 0x000500C2, + 0x00000017, 0x0000472C, 0x00004CA3, 0x00000B86, 0x000500C6, 0x00000017, 0x00003A76, 0x00005DC3, + 0x0000472C, 0x00050051, 0x0000000B, 0x000050F8, 0x00003A76, 0x00000000, 0x0007004F, 0x00000011, + 0x00004FAE, 0x00004C5A, 0x00004C5A, 0x00000000, 0x00000000, 0x000500C2, 0x00000011, 0x00002345, + 0x00004FAE, 0x0000076F, 0x000500C7, 0x00000011, 0x0000221D, 0x00002345, 0x00000474, 0x00050051, + 0x0000000B, 0x00004464, 0x00004C5A, 0x00000000, 0x000500C2, 0x0000000B, 0x000029EA, 0x00004464, + 0x00000A3A, 0x00050051, 0x0000000B, 0x000025B3, 0x00004C5A, 0x00000001, 0x000500C7, 0x0000000B, + 0x0000185F, 0x000025B3, 0x00000144, 0x000500C4, 0x0000000B, 0x00005E0F, 0x0000185F, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x00003F72, 0x000029EA, 0x00005E0F, 0x00050051, 0x0000000B, 0x000055C0, + 0x0000221D, 0x00000000, 0x00050051, 0x0000000B, 0x00002778, 0x0000221D, 0x00000001, 0x000500B2, + 0x00000009, 0x00004E84, 0x000055C0, 0x00002778, 0x000300F7, 0x0000369E, 0x00000000, 0x000400FA, + 0x00004E84, 0x000055A8, 0x00002992, 0x000200F8, 0x00002992, 0x000500C7, 0x0000000B, 0x000044FB, + 0x00003F72, 0x000009E9, 0x000500C7, 0x0000000B, 0x00005D68, 0x00003F72, 0x000009C8, 0x000500C2, + 0x0000000B, 0x000056E9, 0x00005D68, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00005DC4, 0x000044FB, + 0x000056E9, 0x000500C7, 0x0000000B, 0x00004C91, 0x00003F72, 0x00000986, 0x000500C2, 0x0000000B, + 0x00005089, 0x00004C91, 0x00000A10, 0x000500C5, 0x0000000B, 0x00005EE1, 0x00005DC4, 0x00005089, + 0x000500C6, 0x0000000B, 0x00001E2D, 0x00005EE1, 0x000009E9, 0x000400C8, 0x0000000B, 0x00002548, + 0x000056E9, 0x000500C7, 0x0000000B, 0x00003921, 0x000044FB, 0x00002548, 0x000400C8, 0x0000000B, + 0x000020ED, 0x00005089, 0x000500C7, 0x0000000B, 0x00002C93, 0x00003921, 0x000020ED, 0x000500C5, + 0x0000000B, 0x00001A93, 0x00003F72, 0x00001E2D, 0x00050082, 0x0000000B, 0x00004C39, 0x00001A93, + 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A1C, 0x00004C39, 0x00002C93, 0x000500C4, 0x0000000B, + 0x000046EA, 0x00002C93, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00003E8A, 0x00003A1C, 0x000046EA, + 0x000500C4, 0x0000000B, 0x00001FB8, 0x00002C93, 0x00000A10, 0x000500C5, 0x0000000B, 0x00001E82, + 0x00003E8A, 0x00001FB8, 0x000200F9, 0x0000369E, 0x000200F8, 0x000055A8, 0x000500C7, 0x0000000B, + 0x00004E75, 0x00003F72, 0x000009C8, 0x000500C7, 0x0000000B, 0x00005D92, 0x00003F72, 0x00000986, + 0x000500C2, 0x0000000B, 0x0000555A, 0x00005D92, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FCB, + 0x00004E75, 0x0000555A, 0x000500C4, 0x0000000B, 0x00006027, 0x00001FCB, 0x00000A0D, 0x000500C2, + 0x0000000B, 0x000059B2, 0x00001FCB, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000496C, 0x00006027, + 0x000059B2, 0x000500C5, 0x0000000B, 0x00003EB3, 0x00001FCB, 0x0000496C, 0x000500C7, 0x0000000B, + 0x00004787, 0x00003F72, 0x000009E9, 0x000500C5, 0x0000000B, 0x0000395F, 0x00004787, 0x00000944, + 0x000500C7, 0x0000000B, 0x00004FB5, 0x0000395F, 0x00003EB3, 0x000500C2, 0x0000000B, 0x0000503D, + 0x00004E75, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000615C, 0x00004787, 0x0000503D, 0x000500C2, + 0x0000000B, 0x000055A9, 0x00005D92, 0x00000A10, 0x000500C5, 0x0000000B, 0x00005894, 0x0000615C, + 0x000055A9, 0x000500C6, 0x0000000B, 0x00001E2E, 0x00005894, 0x000009E9, 0x000400C8, 0x0000000B, + 0x00002549, 0x0000503D, 0x000500C7, 0x0000000B, 0x00003922, 0x00004787, 0x00002549, 0x000400C8, + 0x0000000B, 0x000020EE, 0x000055A9, 0x000500C7, 0x0000000B, 0x00002C94, 0x00003922, 0x000020EE, + 0x000500C5, 0x0000000B, 0x00001A94, 0x00003F72, 0x00001E2E, 0x00050082, 0x0000000B, 0x00004C3A, + 0x00001A94, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A1D, 0x00004C3A, 0x00002C94, 0x000500C4, + 0x0000000B, 0x00004736, 0x00002C94, 0x00000A10, 0x000500C5, 0x0000000B, 0x00003C00, 0x00003A1D, + 0x00004736, 0x000400C8, 0x0000000B, 0x00002F7C, 0x00003EB3, 0x000500C7, 0x0000000B, 0x00004852, + 0x00003C00, 0x00002F7C, 0x000500C5, 0x0000000B, 0x0000186E, 0x00004852, 0x00004FB5, 0x000200F9, + 0x0000369E, 0x000200F8, 0x0000369E, 0x000700F5, 0x0000000B, 0x00003DD2, 0x0000186E, 0x000055A8, + 0x00001E82, 0x00002992, 0x000400C8, 0x0000000B, 0x000040BC, 0x000050F8, 0x00070050, 0x00000017, + 0x000037A1, 0x000040BC, 0x000040BC, 0x000040BC, 0x000040BC, 0x000500C2, 0x00000017, 0x00005DE9, + 0x000037A1, 0x0000004D, 0x000500C7, 0x00000017, 0x00005AB3, 0x00005DE9, 0x0000002F, 0x00050051, + 0x0000000B, 0x00004AB9, 0x00003950, 0x00000000, 0x00070050, 0x00000017, 0x00006077, 0x00004AB9, + 0x00004AB9, 0x00004AB9, 0x00004AB9, 0x00050084, 0x00000017, 0x00005FF3, 0x00005AB3, 0x00006077, + 0x00070050, 0x00000017, 0x00006283, 0x000050F8, 0x000050F8, 0x000050F8, 0x000050F8, 0x000500C2, + 0x00000017, 0x0000383E, 0x00006283, 0x0000004D, 0x000500C7, 0x00000017, 0x00005AB4, 0x0000383E, + 0x0000002F, 0x00050051, 0x0000000B, 0x00004ABA, 0x00003950, 0x00000001, 0x00070050, 0x00000017, + 0x00001988, 0x00004ABA, 0x00004ABA, 0x00004ABA, 0x00004ABA, 0x00050084, 0x00000017, 0x00003FE2, + 0x00005AB4, 0x00001988, 0x00050080, 0x00000017, 0x00002C04, 0x00005FF3, 0x00003FE2, 0x000500C7, + 0x00000017, 0x000060C2, 0x00002C04, 0x000003A1, 0x00050086, 0x00000017, 0x0000240D, 0x000060C2, + 0x0000002F, 0x000500C4, 0x00000017, 0x000044CE, 0x0000240D, 0x000002ED, 0x000500C2, 0x00000017, + 0x00002AD5, 0x00002C04, 0x000001A9, 0x000500C7, 0x00000017, 0x000033C5, 0x00002AD5, 0x000003A1, + 0x00050086, 0x00000017, 0x000043A4, 0x000033C5, 0x0000002F, 0x000500C4, 0x00000017, 0x00004267, + 0x000043A4, 0x0000013D, 0x000500C5, 0x00000017, 0x000018B2, 0x000044CE, 0x00004267, 0x000500C2, + 0x00000017, 0x00003BF4, 0x00002C04, 0x000003C5, 0x00050086, 0x00000017, 0x00006198, 0x00003BF4, + 0x0000002F, 0x000500C5, 0x00000017, 0x00004C1C, 0x000018B2, 0x00006198, 0x000300F7, 0x00005C03, + 0x00000000, 0x000400FA, 0x00004E84, 0x000055AA, 0x000028E7, 0x000200F8, 0x000028E7, 0x000400C8, + 0x0000000B, 0x00002062, 0x00003DD2, 0x000500C7, 0x0000000B, 0x00003C01, 0x00002062, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00004534, 0x000055C0, 0x00003C01, 0x000500C7, 0x0000000B, 0x000055DF, + 0x00003DD2, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FAF, 0x00002778, 0x000055DF, 0x00050080, + 0x0000000B, 0x00004D8A, 0x00004534, 0x00004FAF, 0x00050086, 0x0000000B, 0x000032D0, 0x00004D8A, + 0x00000A1F, 0x000500C2, 0x0000000B, 0x000059F6, 0x00002062, 0x00000A13, 0x000500C7, 0x0000000B, + 0x00002239, 0x000059F6, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ABB, 0x000055C0, 0x00002239, + 0x000500C2, 0x0000000B, 0x000033FB, 0x00003DD2, 0x00000A13, 0x000500C7, 0x0000000B, 0x00006195, + 0x000033FB, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006284, 0x00002778, 0x00006195, 0x00050080, + 0x0000000B, 0x00004DC0, 0x00003ABB, 0x00006284, 0x00050086, 0x0000000B, 0x00003160, 0x00004DC0, + 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FF0, 0x00003160, 0x00000A22, 0x000500C5, 0x0000000B, + 0x00001D92, 0x000032D0, 0x00001FF0, 0x000500C2, 0x0000000B, 0x000055C1, 0x00002062, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x000044CF, 0x000055C1, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ABC, + 0x000055C0, 0x000044CF, 0x000500C2, 0x0000000B, 0x000033FC, 0x00003DD2, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x00006199, 0x000033FC, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006285, 0x00002778, + 0x00006199, 0x00050080, 0x0000000B, 0x00004DC1, 0x00003ABC, 0x00006285, 0x00050086, 0x0000000B, + 0x00003161, 0x00004DC1, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FF1, 0x00003161, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x00001D93, 0x00001D92, 0x00001FF1, 0x000500C2, 0x0000000B, 0x000055C2, + 0x00002062, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044D0, 0x000055C2, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003ABD, 0x000055C0, 0x000044D0, 0x000500C2, 0x0000000B, 0x000033FD, 0x00003DD2, + 0x00000A25, 0x000500C7, 0x0000000B, 0x0000619A, 0x000033FD, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00006286, 0x00002778, 0x0000619A, 0x00050080, 0x0000000B, 0x00004DC2, 0x00003ABD, 0x00006286, + 0x00050086, 0x0000000B, 0x00003162, 0x00004DC2, 0x00000A1F, 0x000500C4, 0x0000000B, 0x000023F9, + 0x00003162, 0x00000A52, 0x000500C5, 0x0000000B, 0x0000467C, 0x00001D93, 0x000023F9, 0x000200F9, + 0x00005C03, 0x000200F8, 0x000055AA, 0x000500C7, 0x0000000B, 0x00004E76, 0x00003DD2, 0x0000003A, + 0x000500C7, 0x0000000B, 0x00005D93, 0x00003DD2, 0x0000022D, 0x000500C2, 0x0000000B, 0x0000555B, + 0x00005D93, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FCC, 0x00004E76, 0x0000555B, 0x000500C4, + 0x0000000B, 0x00006028, 0x00001FCC, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059B3, 0x00001FCC, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004980, 0x00006028, 0x000059B3, 0x000500C5, 0x0000000B, + 0x00003E2E, 0x00001FCC, 0x00004980, 0x000400C8, 0x0000000B, 0x0000210F, 0x00003E2E, 0x000500C7, + 0x0000000B, 0x00002766, 0x00003DD2, 0x0000210F, 0x00050082, 0x0000000B, 0x00003FB0, 0x00000908, + 0x00002766, 0x000500C7, 0x0000000B, 0x0000440B, 0x00003FB0, 0x0000210F, 0x000500C7, 0x0000000B, + 0x00004268, 0x0000440B, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003571, 0x000055C0, 0x00004268, + 0x000500C7, 0x0000000B, 0x000055E0, 0x00002766, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FB0, + 0x00002778, 0x000055E0, 0x00050080, 0x0000000B, 0x00004D8B, 0x00003571, 0x00004FB0, 0x00050086, + 0x0000000B, 0x000032D1, 0x00004D8B, 0x00000A19, 0x000500C2, 0x0000000B, 0x000059F7, 0x0000440B, + 0x00000A13, 0x000500C7, 0x0000000B, 0x0000223A, 0x000059F7, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003ABE, 0x000055C0, 0x0000223A, 0x000500C2, 0x0000000B, 0x000033FE, 0x00002766, 0x00000A13, + 0x000500C7, 0x0000000B, 0x0000619B, 0x000033FE, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006287, + 0x00002778, 0x0000619B, 0x00050080, 0x0000000B, 0x00004DC3, 0x00003ABE, 0x00006287, 0x00050086, + 0x0000000B, 0x00003163, 0x00004DC3, 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FF2, 0x00003163, + 0x00000A22, 0x000500C5, 0x0000000B, 0x00001D94, 0x000032D1, 0x00001FF2, 0x000500C2, 0x0000000B, + 0x000055C3, 0x0000440B, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044D1, 0x000055C3, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003ABF, 0x000055C0, 0x000044D1, 0x000500C2, 0x0000000B, 0x000033FF, + 0x00002766, 0x00000A1C, 0x000500C7, 0x0000000B, 0x0000619C, 0x000033FF, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00006288, 0x00002778, 0x0000619C, 0x00050080, 0x0000000B, 0x00004DC4, 0x00003ABF, + 0x00006288, 0x00050086, 0x0000000B, 0x00003164, 0x00004DC4, 0x00000A19, 0x000500C4, 0x0000000B, + 0x00001FF3, 0x00003164, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D95, 0x00001D94, 0x00001FF3, + 0x000500C2, 0x0000000B, 0x000055C4, 0x0000440B, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044D2, + 0x000055C4, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AC0, 0x000055C0, 0x000044D2, 0x000500C2, + 0x0000000B, 0x00003400, 0x00002766, 0x00000A25, 0x000500C7, 0x0000000B, 0x0000619D, 0x00003400, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00006289, 0x00002778, 0x0000619D, 0x00050080, 0x0000000B, + 0x00004DC5, 0x00003AC0, 0x00006289, 0x00050086, 0x0000000B, 0x00003165, 0x00004DC5, 0x00000A19, + 0x000500C4, 0x0000000B, 0x00002044, 0x00003165, 0x00000A52, 0x000500C5, 0x0000000B, 0x00001A24, + 0x00001D95, 0x00002044, 0x000500C7, 0x0000000B, 0x00004FB1, 0x00003DD2, 0x00003E2E, 0x000500C7, + 0x0000000B, 0x00004404, 0x00004FB1, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C6B, 0x00004FB1, + 0x00000A22, 0x000500C4, 0x0000000B, 0x00006168, 0x00004C6B, 0x00000A19, 0x000500C5, 0x0000000B, + 0x000042C5, 0x00004404, 0x00006168, 0x000500C7, 0x0000000B, 0x0000518A, 0x00004FB1, 0x00000ACA, + 0x000500C4, 0x0000000B, 0x00005B1B, 0x0000518A, 0x00000A28, 0x000500C5, 0x0000000B, 0x000042CA, + 0x000042C5, 0x00005B1B, 0x000500C7, 0x0000000B, 0x0000518B, 0x00004FB1, 0x00000447, 0x000500C4, + 0x0000000B, 0x00005622, 0x0000518B, 0x00000A37, 0x000500C5, 0x0000000B, 0x0000207B, 0x000042CA, + 0x00005622, 0x00050084, 0x0000000B, 0x000028B7, 0x0000207B, 0x00000144, 0x00050080, 0x0000000B, + 0x00004803, 0x00001A24, 0x000028B7, 0x000200F9, 0x00005C03, 0x000200F8, 0x00005C03, 0x000700F5, + 0x0000000B, 0x00004D0A, 0x00004803, 0x000055AA, 0x0000467C, 0x000028E7, 0x00070050, 0x00000017, + 0x0000351E, 0x00004D0A, 0x00004D0A, 0x00004D0A, 0x00004D0A, 0x000500C4, 0x00000017, 0x000042CB, + 0x0000351E, 0x0000019D, 0x000500C7, 0x00000017, 0x000053BF, 0x000042CB, 0x00000A27, 0x000500C5, + 0x00000017, 0x00002FE1, 0x00004C1C, 0x000053BF, 0x00060041, 0x00000294, 0x00005B1C, 0x0000140E, + 0x00000A0B, 0x000038B5, 0x0003003E, 0x00005B1C, 0x00002FE1, 0x000300F7, 0x00001C27, 0x00000002, + 0x000400FA, 0x00004411, 0x0000592D, 0x00001C27, 0x000200F8, 0x0000592D, 0x00050080, 0x0000000B, + 0x00003CEC, 0x000038B5, 0x00001B41, 0x000500C2, 0x0000000B, 0x00002AD7, 0x000050F8, 0x00000A22, + 0x000400C8, 0x0000000B, 0x00005CEF, 0x00002AD7, 0x00070050, 0x00000017, 0x000052F7, 0x00005CEF, + 0x00005CEF, 0x00005CEF, 0x00005CEF, 0x000500C2, 0x00000017, 0x000061B4, 0x000052F7, 0x0000004D, + 0x000500C7, 0x00000017, 0x0000383B, 0x000061B4, 0x0000002F, 0x00050084, 0x00000017, 0x00003CD2, + 0x0000383B, 0x00006077, 0x00070050, 0x00000017, 0x0000539C, 0x00002AD7, 0x00002AD7, 0x00002AD7, + 0x00002AD7, 0x000500C2, 0x00000017, 0x00003C09, 0x0000539C, 0x0000004D, 0x000500C7, 0x00000017, + 0x00003BCB, 0x00003C09, 0x0000002F, 0x00050084, 0x00000017, 0x00001CC1, 0x00003BCB, 0x00001988, + 0x00050080, 0x00000017, 0x00001D24, 0x00003CD2, 0x00001CC1, 0x000500C7, 0x00000017, 0x000060C3, + 0x00001D24, 0x000003A1, 0x00050086, 0x00000017, 0x0000240E, 0x000060C3, 0x0000002F, 0x000500C4, + 0x00000017, 0x000044D3, 0x0000240E, 0x000002ED, 0x000500C2, 0x00000017, 0x00002AD8, 0x00001D24, + 0x000001A9, 0x000500C7, 0x00000017, 0x000033C6, 0x00002AD8, 0x000003A1, 0x00050086, 0x00000017, + 0x000043A5, 0x000033C6, 0x0000002F, 0x000500C4, 0x00000017, 0x00004269, 0x000043A5, 0x0000013D, + 0x000500C5, 0x00000017, 0x000018B3, 0x000044D3, 0x00004269, 0x000500C2, 0x00000017, 0x00003BF5, + 0x00001D24, 0x000003C5, 0x00050086, 0x00000017, 0x00005DA9, 0x00003BF5, 0x0000002F, 0x000500C5, + 0x00000017, 0x00002535, 0x000018B3, 0x00005DA9, 0x000500C2, 0x0000000B, 0x00005C85, 0x00003DD2, + 0x00000A2E, 0x000300F7, 0x00005C04, 0x00000000, 0x000400FA, 0x00004E84, 0x000055AB, 0x000028E8, + 0x000200F8, 0x000028E8, 0x000400C8, 0x0000000B, 0x00002063, 0x00005C85, 0x000500C7, 0x0000000B, + 0x00003C02, 0x00002063, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004535, 0x000055C0, 0x00003C02, + 0x000500C7, 0x0000000B, 0x000055E1, 0x00005C85, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FB2, + 0x00002778, 0x000055E1, 0x00050080, 0x0000000B, 0x00004D8C, 0x00004535, 0x00004FB2, 0x00050086, + 0x0000000B, 0x000032D2, 0x00004D8C, 0x00000A1F, 0x000500C2, 0x0000000B, 0x000059F8, 0x00002063, + 0x00000A13, 0x000500C7, 0x0000000B, 0x0000223B, 0x000059F8, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003AC1, 0x000055C0, 0x0000223B, 0x000500C2, 0x0000000B, 0x00003401, 0x00005C85, 0x00000A13, + 0x000500C7, 0x0000000B, 0x0000619E, 0x00003401, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000628A, + 0x00002778, 0x0000619E, 0x00050080, 0x0000000B, 0x00004DC6, 0x00003AC1, 0x0000628A, 0x00050086, + 0x0000000B, 0x00003166, 0x00004DC6, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FF4, 0x00003166, + 0x00000A22, 0x000500C5, 0x0000000B, 0x00001D96, 0x000032D2, 0x00001FF4, 0x000500C2, 0x0000000B, + 0x000055C5, 0x00002063, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044D4, 0x000055C5, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AC2, 0x000055C0, 0x000044D4, 0x000500C2, 0x0000000B, 0x00003402, + 0x00005C85, 0x00000A1C, 0x000500C7, 0x0000000B, 0x0000619F, 0x00003402, 0x00000A1F, 0x00050084, + 0x0000000B, 0x0000628B, 0x00002778, 0x0000619F, 0x00050080, 0x0000000B, 0x00004DC7, 0x00003AC2, + 0x0000628B, 0x00050086, 0x0000000B, 0x00003167, 0x00004DC7, 0x00000A1F, 0x000500C4, 0x0000000B, + 0x00001FF5, 0x00003167, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D97, 0x00001D96, 0x00001FF5, + 0x000500C2, 0x0000000B, 0x000055C6, 0x00002063, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044D5, + 0x000055C6, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AC3, 0x000055C0, 0x000044D5, 0x000500C2, + 0x0000000B, 0x00003403, 0x00005C85, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061A0, 0x00003403, + 0x00000A1F, 0x00050084, 0x0000000B, 0x0000628C, 0x00002778, 0x000061A0, 0x00050080, 0x0000000B, + 0x00004DC8, 0x00003AC3, 0x0000628C, 0x00050086, 0x0000000B, 0x00003168, 0x00004DC8, 0x00000A1F, + 0x000500C4, 0x0000000B, 0x000023FA, 0x00003168, 0x00000A52, 0x000500C5, 0x0000000B, 0x0000467D, + 0x00001D97, 0x000023FA, 0x000200F9, 0x00005C04, 0x000200F8, 0x000055AB, 0x000500C7, 0x0000000B, + 0x00004E77, 0x00005C85, 0x0000003A, 0x000500C7, 0x0000000B, 0x00005D94, 0x00005C85, 0x0000022D, + 0x000500C2, 0x0000000B, 0x0000555C, 0x00005D94, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FCD, + 0x00004E77, 0x0000555C, 0x000500C4, 0x0000000B, 0x00006029, 0x00001FCD, 0x00000A0D, 0x000500C2, + 0x0000000B, 0x000059B4, 0x00001FCD, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004981, 0x00006029, + 0x000059B4, 0x000500C5, 0x0000000B, 0x00003E2F, 0x00001FCD, 0x00004981, 0x000400C8, 0x0000000B, + 0x00002110, 0x00003E2F, 0x000500C7, 0x0000000B, 0x00002767, 0x00005C85, 0x00002110, 0x00050082, + 0x0000000B, 0x00003FB1, 0x00000908, 0x00002767, 0x000500C7, 0x0000000B, 0x0000440C, 0x00003FB1, + 0x00002110, 0x000500C7, 0x0000000B, 0x0000426A, 0x0000440C, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003572, 0x000055C0, 0x0000426A, 0x000500C7, 0x0000000B, 0x000055E2, 0x00002767, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00004FB6, 0x00002778, 0x000055E2, 0x00050080, 0x0000000B, 0x00004D8D, + 0x00003572, 0x00004FB6, 0x00050086, 0x0000000B, 0x000032D3, 0x00004D8D, 0x00000A19, 0x000500C2, + 0x0000000B, 0x000059F9, 0x0000440C, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000223C, 0x000059F9, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AC4, 0x000055C0, 0x0000223C, 0x000500C2, 0x0000000B, + 0x00003404, 0x00002767, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061A1, 0x00003404, 0x00000A1F, + 0x00050084, 0x0000000B, 0x0000628D, 0x00002778, 0x000061A1, 0x00050080, 0x0000000B, 0x00004DC9, + 0x00003AC4, 0x0000628D, 0x00050086, 0x0000000B, 0x00003169, 0x00004DC9, 0x00000A19, 0x000500C4, + 0x0000000B, 0x00001FF6, 0x00003169, 0x00000A22, 0x000500C5, 0x0000000B, 0x00001D98, 0x000032D3, + 0x00001FF6, 0x000500C2, 0x0000000B, 0x000055C7, 0x0000440C, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x000044D6, 0x000055C7, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AC5, 0x000055C0, 0x000044D6, + 0x000500C2, 0x0000000B, 0x00003405, 0x00002767, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061A2, + 0x00003405, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000628E, 0x00002778, 0x000061A2, 0x00050080, + 0x0000000B, 0x00004DCA, 0x00003AC5, 0x0000628E, 0x00050086, 0x0000000B, 0x0000316A, 0x00004DCA, + 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FF7, 0x0000316A, 0x00000A3A, 0x000500C5, 0x0000000B, + 0x00001D99, 0x00001D98, 0x00001FF7, 0x000500C2, 0x0000000B, 0x000055C8, 0x0000440C, 0x00000A25, + 0x000500C7, 0x0000000B, 0x000044D7, 0x000055C8, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AC6, + 0x000055C0, 0x000044D7, 0x000500C2, 0x0000000B, 0x00003406, 0x00002767, 0x00000A25, 0x000500C7, + 0x0000000B, 0x000061A3, 0x00003406, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000628F, 0x00002778, + 0x000061A3, 0x00050080, 0x0000000B, 0x00004DCB, 0x00003AC6, 0x0000628F, 0x00050086, 0x0000000B, + 0x0000316B, 0x00004DCB, 0x00000A19, 0x000500C4, 0x0000000B, 0x00002045, 0x0000316B, 0x00000A52, + 0x000500C5, 0x0000000B, 0x00001A25, 0x00001D99, 0x00002045, 0x000500C7, 0x0000000B, 0x00004FB7, + 0x00005C85, 0x00003E2F, 0x000500C7, 0x0000000B, 0x00004405, 0x00004FB7, 0x00000A0D, 0x000500C7, + 0x0000000B, 0x00004C6C, 0x00004FB7, 0x00000A22, 0x000500C4, 0x0000000B, 0x00006169, 0x00004C6C, + 0x00000A19, 0x000500C5, 0x0000000B, 0x000042CC, 0x00004405, 0x00006169, 0x000500C7, 0x0000000B, + 0x0000518C, 0x00004FB7, 0x00000ACA, 0x000500C4, 0x0000000B, 0x00005B1D, 0x0000518C, 0x00000A28, + 0x000500C5, 0x0000000B, 0x000042CD, 0x000042CC, 0x00005B1D, 0x000500C7, 0x0000000B, 0x0000518D, + 0x00004FB7, 0x00000447, 0x000500C4, 0x0000000B, 0x00005623, 0x0000518D, 0x00000A37, 0x000500C5, + 0x0000000B, 0x0000207C, 0x000042CD, 0x00005623, 0x00050084, 0x0000000B, 0x000028B8, 0x0000207C, + 0x00000144, 0x00050080, 0x0000000B, 0x00004804, 0x00001A25, 0x000028B8, 0x000200F9, 0x00005C04, + 0x000200F8, 0x00005C04, 0x000700F5, 0x0000000B, 0x00004D0B, 0x00004804, 0x000055AB, 0x0000467D, + 0x000028E8, 0x00070050, 0x00000017, 0x0000351F, 0x00004D0B, 0x00004D0B, 0x00004D0B, 0x00004D0B, + 0x000500C4, 0x00000017, 0x000042CE, 0x0000351F, 0x0000019D, 0x000500C7, 0x00000017, 0x000053C0, + 0x000042CE, 0x00000A27, 0x000500C5, 0x00000017, 0x00002FE2, 0x00002535, 0x000053C0, 0x00060041, + 0x00000294, 0x00005244, 0x0000140E, 0x00000A0B, 0x00003CEC, 0x0003003E, 0x00005244, 0x00002FE2, + 0x00050080, 0x0000000B, 0x000039FA, 0x00003220, 0x00000A10, 0x000500B0, 0x00000009, 0x00002E0D, + 0x000039FA, 0x000019C2, 0x000300F7, 0x00001C26, 0x00000002, 0x000400FA, 0x00002E0D, 0x00003082, + 0x00001C26, 0x000200F8, 0x00003082, 0x000500C2, 0x0000000B, 0x000033B9, 0x000025B3, 0x00000A22, + 0x000300F7, 0x00003192, 0x00000000, 0x000400FA, 0x00004E84, 0x000055AC, 0x00002993, 0x000200F8, + 0x00002993, 0x000500C7, 0x0000000B, 0x000044FC, 0x000033B9, 0x000009E9, 0x000500C7, 0x0000000B, + 0x00005D69, 0x000033B9, 0x000009C8, 0x000500C2, 0x0000000B, 0x000056EA, 0x00005D69, 0x00000A0D, + 0x000500C5, 0x0000000B, 0x00005DC5, 0x000044FC, 0x000056EA, 0x000500C7, 0x0000000B, 0x00004C92, + 0x000033B9, 0x00000986, 0x000500C2, 0x0000000B, 0x0000508A, 0x00004C92, 0x00000A10, 0x000500C5, + 0x0000000B, 0x00005EE2, 0x00005DC5, 0x0000508A, 0x000500C6, 0x0000000B, 0x00001E2F, 0x00005EE2, + 0x000009E9, 0x000400C8, 0x0000000B, 0x0000254A, 0x000056EA, 0x000500C7, 0x0000000B, 0x00003923, + 0x000044FC, 0x0000254A, 0x000400C8, 0x0000000B, 0x000020EF, 0x0000508A, 0x000500C7, 0x0000000B, + 0x00002C95, 0x00003923, 0x000020EF, 0x000500C5, 0x0000000B, 0x00001A95, 0x000033B9, 0x00001E2F, + 0x00050082, 0x0000000B, 0x00004C3B, 0x00001A95, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A1E, + 0x00004C3B, 0x00002C95, 0x000500C4, 0x0000000B, 0x000046EB, 0x00002C95, 0x00000A0D, 0x000500C5, + 0x0000000B, 0x00003E8B, 0x00003A1E, 0x000046EB, 0x000500C4, 0x0000000B, 0x00001FB9, 0x00002C95, + 0x00000A10, 0x000500C5, 0x0000000B, 0x00001E83, 0x00003E8B, 0x00001FB9, 0x000200F9, 0x00003192, + 0x000200F8, 0x000055AC, 0x000500C7, 0x0000000B, 0x00004E78, 0x000033B9, 0x000009C8, 0x000500C7, + 0x0000000B, 0x00005D95, 0x000033B9, 0x00000986, 0x000500C2, 0x0000000B, 0x0000555D, 0x00005D95, + 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FCE, 0x00004E78, 0x0000555D, 0x000500C4, 0x0000000B, + 0x0000602A, 0x00001FCE, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059B5, 0x00001FCE, 0x00000A0D, + 0x000500C5, 0x0000000B, 0x0000496D, 0x0000602A, 0x000059B5, 0x000500C5, 0x0000000B, 0x00003EB4, + 0x00001FCE, 0x0000496D, 0x000500C7, 0x0000000B, 0x00004788, 0x000033B9, 0x000009E9, 0x000500C5, + 0x0000000B, 0x00003960, 0x00004788, 0x00000944, 0x000500C7, 0x0000000B, 0x00004FB8, 0x00003960, + 0x00003EB4, 0x000500C2, 0x0000000B, 0x0000503E, 0x00004E78, 0x00000A0D, 0x000500C5, 0x0000000B, + 0x0000615D, 0x00004788, 0x0000503E, 0x000500C2, 0x0000000B, 0x000055AD, 0x00005D95, 0x00000A10, + 0x000500C5, 0x0000000B, 0x00005895, 0x0000615D, 0x000055AD, 0x000500C6, 0x0000000B, 0x00001E30, + 0x00005895, 0x000009E9, 0x000400C8, 0x0000000B, 0x0000254B, 0x0000503E, 0x000500C7, 0x0000000B, + 0x00003924, 0x00004788, 0x0000254B, 0x000400C8, 0x0000000B, 0x000020F0, 0x000055AD, 0x000500C7, + 0x0000000B, 0x00002C96, 0x00003924, 0x000020F0, 0x000500C5, 0x0000000B, 0x00001A96, 0x000033B9, + 0x00001E30, 0x00050082, 0x0000000B, 0x00004C3C, 0x00001A96, 0x000009E9, 0x000500C5, 0x0000000B, + 0x00003A1F, 0x00004C3C, 0x00002C96, 0x000500C4, 0x0000000B, 0x00004737, 0x00002C96, 0x00000A10, + 0x000500C5, 0x0000000B, 0x00003C03, 0x00003A1F, 0x00004737, 0x000400C8, 0x0000000B, 0x00002F7D, + 0x00003EB4, 0x000500C7, 0x0000000B, 0x00004853, 0x00003C03, 0x00002F7D, 0x000500C5, 0x0000000B, + 0x0000186F, 0x00004853, 0x00004FB8, 0x000200F9, 0x00003192, 0x000200F8, 0x00003192, 0x000700F5, + 0x0000000B, 0x000024D7, 0x0000186F, 0x000055AC, 0x00001E83, 0x00002993, 0x00050084, 0x0000000B, + 0x00004966, 0x00000A10, 0x00001B41, 0x00050080, 0x0000000B, 0x00003837, 0x000038B5, 0x00004966, + 0x000500C2, 0x0000000B, 0x00003691, 0x000050F8, 0x00000A3A, 0x000400C8, 0x0000000B, 0x00005CF0, + 0x00003691, 0x00070050, 0x00000017, 0x000052F8, 0x00005CF0, 0x00005CF0, 0x00005CF0, 0x00005CF0, + 0x000500C2, 0x00000017, 0x000061B5, 0x000052F8, 0x0000004D, 0x000500C7, 0x00000017, 0x0000383C, + 0x000061B5, 0x0000002F, 0x00050084, 0x00000017, 0x00003CD3, 0x0000383C, 0x00006077, 0x00070050, + 0x00000017, 0x0000539D, 0x00003691, 0x00003691, 0x00003691, 0x00003691, 0x000500C2, 0x00000017, + 0x00003C0A, 0x0000539D, 0x0000004D, 0x000500C7, 0x00000017, 0x00003BCC, 0x00003C0A, 0x0000002F, + 0x00050084, 0x00000017, 0x00001CC2, 0x00003BCC, 0x00001988, 0x00050080, 0x00000017, 0x00001D25, + 0x00003CD3, 0x00001CC2, 0x000500C7, 0x00000017, 0x000060C4, 0x00001D25, 0x000003A1, 0x00050086, + 0x00000017, 0x0000240F, 0x000060C4, 0x0000002F, 0x000500C4, 0x00000017, 0x000044D8, 0x0000240F, + 0x000002ED, 0x000500C2, 0x00000017, 0x00002AD9, 0x00001D25, 0x000001A9, 0x000500C7, 0x00000017, + 0x000033C7, 0x00002AD9, 0x000003A1, 0x00050086, 0x00000017, 0x000043A6, 0x000033C7, 0x0000002F, + 0x000500C4, 0x00000017, 0x0000426B, 0x000043A6, 0x0000013D, 0x000500C5, 0x00000017, 0x000018B4, + 0x000044D8, 0x0000426B, 0x000500C2, 0x00000017, 0x00003BF6, 0x00001D25, 0x000003C5, 0x00050086, + 0x00000017, 0x000061A4, 0x00003BF6, 0x0000002F, 0x000500C5, 0x00000017, 0x00004C1D, 0x000018B4, + 0x000061A4, 0x000300F7, 0x00005C05, 0x00000000, 0x000400FA, 0x00004E84, 0x000055AE, 0x000028E9, + 0x000200F8, 0x000028E9, 0x000400C8, 0x0000000B, 0x00002064, 0x000024D7, 0x000500C7, 0x0000000B, + 0x00003C04, 0x00002064, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004536, 0x000055C0, 0x00003C04, + 0x000500C7, 0x0000000B, 0x000055E3, 0x000024D7, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FB9, + 0x00002778, 0x000055E3, 0x00050080, 0x0000000B, 0x00004D8E, 0x00004536, 0x00004FB9, 0x00050086, + 0x0000000B, 0x000032D4, 0x00004D8E, 0x00000A1F, 0x000500C2, 0x0000000B, 0x000059FA, 0x00002064, + 0x00000A13, 0x000500C7, 0x0000000B, 0x0000223D, 0x000059FA, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003AC7, 0x000055C0, 0x0000223D, 0x000500C2, 0x0000000B, 0x00003407, 0x000024D7, 0x00000A13, + 0x000500C7, 0x0000000B, 0x000061A5, 0x00003407, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006290, + 0x00002778, 0x000061A5, 0x00050080, 0x0000000B, 0x00004DCC, 0x00003AC7, 0x00006290, 0x00050086, + 0x0000000B, 0x0000316C, 0x00004DCC, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FF8, 0x0000316C, + 0x00000A22, 0x000500C5, 0x0000000B, 0x00001D9A, 0x000032D4, 0x00001FF8, 0x000500C2, 0x0000000B, + 0x000055C9, 0x00002064, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044D9, 0x000055C9, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AC8, 0x000055C0, 0x000044D9, 0x000500C2, 0x0000000B, 0x00003408, + 0x000024D7, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061A6, 0x00003408, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00006291, 0x00002778, 0x000061A6, 0x00050080, 0x0000000B, 0x00004DCD, 0x00003AC8, + 0x00006291, 0x00050086, 0x0000000B, 0x0000316D, 0x00004DCD, 0x00000A1F, 0x000500C4, 0x0000000B, + 0x00001FF9, 0x0000316D, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D9B, 0x00001D9A, 0x00001FF9, + 0x000500C2, 0x0000000B, 0x000055CA, 0x00002064, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044DA, + 0x000055CA, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AC9, 0x000055C0, 0x000044DA, 0x000500C2, + 0x0000000B, 0x00003409, 0x000024D7, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061A7, 0x00003409, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00006292, 0x00002778, 0x000061A7, 0x00050080, 0x0000000B, + 0x00004DCE, 0x00003AC9, 0x00006292, 0x00050086, 0x0000000B, 0x0000316E, 0x00004DCE, 0x00000A1F, + 0x000500C4, 0x0000000B, 0x000023FB, 0x0000316E, 0x00000A52, 0x000500C5, 0x0000000B, 0x0000467E, + 0x00001D9B, 0x000023FB, 0x000200F9, 0x00005C05, 0x000200F8, 0x000055AE, 0x000500C7, 0x0000000B, + 0x00004E79, 0x000024D7, 0x0000003A, 0x000500C7, 0x0000000B, 0x00005D96, 0x000024D7, 0x0000022D, + 0x000500C2, 0x0000000B, 0x0000555E, 0x00005D96, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FCF, + 0x00004E79, 0x0000555E, 0x000500C4, 0x0000000B, 0x0000602B, 0x00001FCF, 0x00000A0D, 0x000500C2, + 0x0000000B, 0x000059B6, 0x00001FCF, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004982, 0x0000602B, + 0x000059B6, 0x000500C5, 0x0000000B, 0x00003E30, 0x00001FCF, 0x00004982, 0x000400C8, 0x0000000B, + 0x00002111, 0x00003E30, 0x000500C7, 0x0000000B, 0x00002768, 0x000024D7, 0x00002111, 0x00050082, + 0x0000000B, 0x00003FB2, 0x00000908, 0x00002768, 0x000500C7, 0x0000000B, 0x0000440D, 0x00003FB2, + 0x00002111, 0x000500C7, 0x0000000B, 0x0000426C, 0x0000440D, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003573, 0x000055C0, 0x0000426C, 0x000500C7, 0x0000000B, 0x000055E4, 0x00002768, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00004FBA, 0x00002778, 0x000055E4, 0x00050080, 0x0000000B, 0x00004D8F, + 0x00003573, 0x00004FBA, 0x00050086, 0x0000000B, 0x000032D5, 0x00004D8F, 0x00000A19, 0x000500C2, + 0x0000000B, 0x000059FB, 0x0000440D, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000223E, 0x000059FB, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ACA, 0x000055C0, 0x0000223E, 0x000500C2, 0x0000000B, + 0x0000340A, 0x00002768, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061A8, 0x0000340A, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00006293, 0x00002778, 0x000061A8, 0x00050080, 0x0000000B, 0x00004DCF, + 0x00003ACA, 0x00006293, 0x00050086, 0x0000000B, 0x0000316F, 0x00004DCF, 0x00000A19, 0x000500C4, + 0x0000000B, 0x00001FFA, 0x0000316F, 0x00000A22, 0x000500C5, 0x0000000B, 0x00001D9C, 0x000032D5, + 0x00001FFA, 0x000500C2, 0x0000000B, 0x000055CB, 0x0000440D, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x000044DB, 0x000055CB, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ACB, 0x000055C0, 0x000044DB, + 0x000500C2, 0x0000000B, 0x0000340B, 0x00002768, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061A9, + 0x0000340B, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006294, 0x00002778, 0x000061A9, 0x00050080, + 0x0000000B, 0x00004DD0, 0x00003ACB, 0x00006294, 0x00050086, 0x0000000B, 0x00003170, 0x00004DD0, + 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FFB, 0x00003170, 0x00000A3A, 0x000500C5, 0x0000000B, + 0x00001D9D, 0x00001D9C, 0x00001FFB, 0x000500C2, 0x0000000B, 0x000055CC, 0x0000440D, 0x00000A25, + 0x000500C7, 0x0000000B, 0x000044DC, 0x000055CC, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ACC, + 0x000055C0, 0x000044DC, 0x000500C2, 0x0000000B, 0x0000340C, 0x00002768, 0x00000A25, 0x000500C7, + 0x0000000B, 0x000061AA, 0x0000340C, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006295, 0x00002778, + 0x000061AA, 0x00050080, 0x0000000B, 0x00004DD1, 0x00003ACC, 0x00006295, 0x00050086, 0x0000000B, + 0x00003171, 0x00004DD1, 0x00000A19, 0x000500C4, 0x0000000B, 0x00002046, 0x00003171, 0x00000A52, + 0x000500C5, 0x0000000B, 0x00001A26, 0x00001D9D, 0x00002046, 0x000500C7, 0x0000000B, 0x00004FBB, + 0x000024D7, 0x00003E30, 0x000500C7, 0x0000000B, 0x00004406, 0x00004FBB, 0x00000A0D, 0x000500C7, + 0x0000000B, 0x00004C6D, 0x00004FBB, 0x00000A22, 0x000500C4, 0x0000000B, 0x0000616A, 0x00004C6D, + 0x00000A19, 0x000500C5, 0x0000000B, 0x000042CF, 0x00004406, 0x0000616A, 0x000500C7, 0x0000000B, + 0x0000518E, 0x00004FBB, 0x00000ACA, 0x000500C4, 0x0000000B, 0x00005B1E, 0x0000518E, 0x00000A28, + 0x000500C5, 0x0000000B, 0x000042D0, 0x000042CF, 0x00005B1E, 0x000500C7, 0x0000000B, 0x0000518F, + 0x00004FBB, 0x00000447, 0x000500C4, 0x0000000B, 0x00005624, 0x0000518F, 0x00000A37, 0x000500C5, + 0x0000000B, 0x0000207D, 0x000042D0, 0x00005624, 0x00050084, 0x0000000B, 0x000028B9, 0x0000207D, + 0x00000144, 0x00050080, 0x0000000B, 0x00004805, 0x00001A26, 0x000028B9, 0x000200F9, 0x00005C05, + 0x000200F8, 0x00005C05, 0x000700F5, 0x0000000B, 0x00004D0C, 0x00004805, 0x000055AE, 0x0000467E, + 0x000028E9, 0x00070050, 0x00000017, 0x00003520, 0x00004D0C, 0x00004D0C, 0x00004D0C, 0x00004D0C, + 0x000500C4, 0x00000017, 0x000042D1, 0x00003520, 0x0000019D, 0x000500C7, 0x00000017, 0x000053C1, + 0x000042D1, 0x00000A27, 0x000500C5, 0x00000017, 0x00002FE3, 0x00004C1D, 0x000053C1, 0x00060041, + 0x00000294, 0x00005245, 0x0000140E, 0x00000A0B, 0x00003837, 0x0003003E, 0x00005245, 0x00002FE3, + 0x00050080, 0x0000000B, 0x000039FB, 0x00003220, 0x00000A13, 0x000500B0, 0x00000009, 0x00002E0E, + 0x000039FB, 0x000019C2, 0x000300F7, 0x00004666, 0x00000002, 0x000400FA, 0x00002E0E, 0x00005193, + 0x00004666, 0x000200F8, 0x00005193, 0x00050084, 0x0000000B, 0x0000338F, 0x00000A13, 0x00001B41, + 0x00050080, 0x0000000B, 0x0000350E, 0x000038B5, 0x0000338F, 0x000500C2, 0x0000000B, 0x00003692, + 0x000050F8, 0x00000A52, 0x000400C8, 0x0000000B, 0x00005CF1, 0x00003692, 0x00070050, 0x00000017, + 0x000052F9, 0x00005CF1, 0x00005CF1, 0x00005CF1, 0x00005CF1, 0x000500C2, 0x00000017, 0x000061B6, + 0x000052F9, 0x0000004D, 0x000500C7, 0x00000017, 0x0000383F, 0x000061B6, 0x0000002F, 0x00050084, + 0x00000017, 0x00003CD4, 0x0000383F, 0x00006077, 0x00070050, 0x00000017, 0x0000539E, 0x00003692, + 0x00003692, 0x00003692, 0x00003692, 0x000500C2, 0x00000017, 0x00003C0B, 0x0000539E, 0x0000004D, + 0x000500C7, 0x00000017, 0x00003BCD, 0x00003C0B, 0x0000002F, 0x00050084, 0x00000017, 0x00001CC3, + 0x00003BCD, 0x00001988, 0x00050080, 0x00000017, 0x00001D26, 0x00003CD4, 0x00001CC3, 0x000500C7, + 0x00000017, 0x000060C5, 0x00001D26, 0x000003A1, 0x00050086, 0x00000017, 0x00002410, 0x000060C5, + 0x0000002F, 0x000500C4, 0x00000017, 0x000044DD, 0x00002410, 0x000002ED, 0x000500C2, 0x00000017, + 0x00002ADA, 0x00001D26, 0x000001A9, 0x000500C7, 0x00000017, 0x000033C8, 0x00002ADA, 0x000003A1, + 0x00050086, 0x00000017, 0x000043A7, 0x000033C8, 0x0000002F, 0x000500C4, 0x00000017, 0x0000426D, + 0x000043A7, 0x0000013D, 0x000500C5, 0x00000017, 0x000018B5, 0x000044DD, 0x0000426D, 0x000500C2, + 0x00000017, 0x00003BF7, 0x00001D26, 0x000003C5, 0x00050086, 0x00000017, 0x00005DAA, 0x00003BF7, + 0x0000002F, 0x000500C5, 0x00000017, 0x00002536, 0x000018B5, 0x00005DAA, 0x000500C2, 0x0000000B, + 0x00005C86, 0x000024D7, 0x00000A2E, 0x000300F7, 0x00005C06, 0x00000000, 0x000400FA, 0x00004E84, + 0x000055CF, 0x000028EA, 0x000200F8, 0x000028EA, 0x000400C8, 0x0000000B, 0x00002065, 0x00005C86, + 0x000500C7, 0x0000000B, 0x00003C05, 0x00002065, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004537, + 0x000055C0, 0x00003C05, 0x000500C7, 0x0000000B, 0x000055E5, 0x00005C86, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00004FBC, 0x00002778, 0x000055E5, 0x00050080, 0x0000000B, 0x00004D90, 0x00004537, + 0x00004FBC, 0x00050086, 0x0000000B, 0x000032D6, 0x00004D90, 0x00000A1F, 0x000500C2, 0x0000000B, + 0x000059FC, 0x00002065, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000223F, 0x000059FC, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003ACD, 0x000055C0, 0x0000223F, 0x000500C2, 0x0000000B, 0x0000340D, + 0x00005C86, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061AB, 0x0000340D, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00006296, 0x00002778, 0x000061AB, 0x00050080, 0x0000000B, 0x00004DD2, 0x00003ACD, + 0x00006296, 0x00050086, 0x0000000B, 0x00003172, 0x00004DD2, 0x00000A1F, 0x000500C4, 0x0000000B, + 0x00001FFC, 0x00003172, 0x00000A22, 0x000500C5, 0x0000000B, 0x00001D9E, 0x000032D6, 0x00001FFC, + 0x000500C2, 0x0000000B, 0x000055CD, 0x00002065, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044DE, + 0x000055CD, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ACE, 0x000055C0, 0x000044DE, 0x000500C2, + 0x0000000B, 0x0000340E, 0x00005C86, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061AC, 0x0000340E, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00006297, 0x00002778, 0x000061AC, 0x00050080, 0x0000000B, + 0x00004DD3, 0x00003ACE, 0x00006297, 0x00050086, 0x0000000B, 0x00003173, 0x00004DD3, 0x00000A1F, + 0x000500C4, 0x0000000B, 0x00001FFD, 0x00003173, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D9F, + 0x00001D9E, 0x00001FFD, 0x000500C2, 0x0000000B, 0x000055CE, 0x00002065, 0x00000A25, 0x000500C7, + 0x0000000B, 0x000044DF, 0x000055CE, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ACF, 0x000055C0, + 0x000044DF, 0x000500C2, 0x0000000B, 0x0000340F, 0x00005C86, 0x00000A25, 0x000500C7, 0x0000000B, + 0x000061AD, 0x0000340F, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006298, 0x00002778, 0x000061AD, + 0x00050080, 0x0000000B, 0x00004DD4, 0x00003ACF, 0x00006298, 0x00050086, 0x0000000B, 0x00003174, + 0x00004DD4, 0x00000A1F, 0x000500C4, 0x0000000B, 0x000023FC, 0x00003174, 0x00000A52, 0x000500C5, + 0x0000000B, 0x0000467F, 0x00001D9F, 0x000023FC, 0x000200F9, 0x00005C06, 0x000200F8, 0x000055CF, + 0x000500C7, 0x0000000B, 0x00004E7A, 0x00005C86, 0x0000003A, 0x000500C7, 0x0000000B, 0x00005D97, + 0x00005C86, 0x0000022D, 0x000500C2, 0x0000000B, 0x0000555F, 0x00005D97, 0x00000A0D, 0x000500C7, + 0x0000000B, 0x00001FD0, 0x00004E7A, 0x0000555F, 0x000500C4, 0x0000000B, 0x0000602C, 0x00001FD0, + 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059B7, 0x00001FD0, 0x00000A0D, 0x000500C5, 0x0000000B, + 0x00004983, 0x0000602C, 0x000059B7, 0x000500C5, 0x0000000B, 0x00003E31, 0x00001FD0, 0x00004983, + 0x000400C8, 0x0000000B, 0x00002112, 0x00003E31, 0x000500C7, 0x0000000B, 0x00002769, 0x00005C86, + 0x00002112, 0x00050082, 0x0000000B, 0x00003FB3, 0x00000908, 0x00002769, 0x000500C7, 0x0000000B, + 0x0000440E, 0x00003FB3, 0x00002112, 0x000500C7, 0x0000000B, 0x0000426E, 0x0000440E, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003574, 0x000055C0, 0x0000426E, 0x000500C7, 0x0000000B, 0x000055E6, + 0x00002769, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FBD, 0x00002778, 0x000055E6, 0x00050080, + 0x0000000B, 0x00004D91, 0x00003574, 0x00004FBD, 0x00050086, 0x0000000B, 0x000032D7, 0x00004D91, + 0x00000A19, 0x000500C2, 0x0000000B, 0x000059FD, 0x0000440E, 0x00000A13, 0x000500C7, 0x0000000B, + 0x00002240, 0x000059FD, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AD0, 0x000055C0, 0x00002240, + 0x000500C2, 0x0000000B, 0x00003410, 0x00002769, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061AE, + 0x00003410, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006299, 0x00002778, 0x000061AE, 0x00050080, + 0x0000000B, 0x00004DD5, 0x00003AD0, 0x00006299, 0x00050086, 0x0000000B, 0x00003175, 0x00004DD5, + 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FFE, 0x00003175, 0x00000A22, 0x000500C5, 0x0000000B, + 0x00001DA0, 0x000032D7, 0x00001FFE, 0x000500C2, 0x0000000B, 0x000055D0, 0x0000440E, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x000044E0, 0x000055D0, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AD1, + 0x000055C0, 0x000044E0, 0x000500C2, 0x0000000B, 0x00003411, 0x00002769, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x000061AF, 0x00003411, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000629A, 0x00002778, + 0x000061AF, 0x00050080, 0x0000000B, 0x00004DD6, 0x00003AD1, 0x0000629A, 0x00050086, 0x0000000B, + 0x00003176, 0x00004DD6, 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FFF, 0x00003176, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x00001DA1, 0x00001DA0, 0x00001FFF, 0x000500C2, 0x0000000B, 0x000055D1, + 0x0000440E, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044E1, 0x000055D1, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AD2, 0x000055C0, 0x000044E1, 0x000500C2, 0x0000000B, 0x00003413, 0x00002769, + 0x00000A25, 0x000500C7, 0x0000000B, 0x000061B0, 0x00003413, 0x00000A1F, 0x00050084, 0x0000000B, + 0x0000629B, 0x00002778, 0x000061B0, 0x00050080, 0x0000000B, 0x00004DD7, 0x00003AD2, 0x0000629B, + 0x00050086, 0x0000000B, 0x00003177, 0x00004DD7, 0x00000A19, 0x000500C4, 0x0000000B, 0x00002047, + 0x00003177, 0x00000A52, 0x000500C5, 0x0000000B, 0x00001A27, 0x00001DA1, 0x00002047, 0x000500C7, + 0x0000000B, 0x00004FBE, 0x00005C86, 0x00003E31, 0x000500C7, 0x0000000B, 0x0000440F, 0x00004FBE, + 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C6E, 0x00004FBE, 0x00000A22, 0x000500C4, 0x0000000B, + 0x0000616B, 0x00004C6E, 0x00000A19, 0x000500C5, 0x0000000B, 0x000042D2, 0x0000440F, 0x0000616B, + 0x000500C7, 0x0000000B, 0x00005190, 0x00004FBE, 0x00000ACA, 0x000500C4, 0x0000000B, 0x00005B1F, + 0x00005190, 0x00000A28, 0x000500C5, 0x0000000B, 0x000042D3, 0x000042D2, 0x00005B1F, 0x000500C7, + 0x0000000B, 0x00005191, 0x00004FBE, 0x00000447, 0x000500C4, 0x0000000B, 0x00005625, 0x00005191, + 0x00000A37, 0x000500C5, 0x0000000B, 0x0000207E, 0x000042D3, 0x00005625, 0x00050084, 0x0000000B, + 0x000028BA, 0x0000207E, 0x00000144, 0x00050080, 0x0000000B, 0x00004806, 0x00001A27, 0x000028BA, + 0x000200F9, 0x00005C06, 0x000200F8, 0x00005C06, 0x000700F5, 0x0000000B, 0x00004D0D, 0x00004806, + 0x000055CF, 0x0000467F, 0x000028EA, 0x00070050, 0x00000017, 0x00003521, 0x00004D0D, 0x00004D0D, + 0x00004D0D, 0x00004D0D, 0x000500C4, 0x00000017, 0x000042D4, 0x00003521, 0x0000019D, 0x000500C7, + 0x00000017, 0x000053C2, 0x000042D4, 0x00000A27, 0x000500C5, 0x00000017, 0x00002FE4, 0x00002536, + 0x000053C2, 0x00060041, 0x00000294, 0x00005B3E, 0x0000140E, 0x00000A0B, 0x0000350E, 0x0003003E, + 0x00005B3E, 0x00002FE4, 0x000200F9, 0x00004666, 0x000200F8, 0x00004666, 0x000200F9, 0x00001C26, + 0x000200F8, 0x00001C26, 0x000200F9, 0x00001C27, 0x000200F8, 0x00001C27, 0x000200F9, 0x00003A37, + 0x000200F8, 0x00003A37, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_dxt5a_r8_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_dxt5a_r8_cs.h new file mode 100644 index 0000000..00ca1c8 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_dxt5a_r8_cs.h @@ -0,0 +1,4113 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25290 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 +%uint_2396745 = OpConstant %uint 2396745 +%uint_4793490 = OpConstant %uint 4793490 + %uint_1 = OpConstant %uint 1 +%uint_9586980 = OpConstant %uint 9586980 + %uint_2 = OpConstant %uint 2 +%uint_14380470 = OpConstant %uint 14380470 + %uint_0 = OpConstant %uint 0 + %uint_7 = OpConstant %uint 7 + %uint_3 = OpConstant %uint 3 + %uint_8 = OpConstant %uint 8 + %uint_6 = OpConstant %uint 6 + %uint_16 = OpConstant %uint 16 + %uint_9 = OpConstant %uint 9 + %uint_24 = OpConstant %uint 24 + %uint_1170 = OpConstant %uint 1170 + %uint_2340 = OpConstant %uint 2340 + %uint_2925 = OpConstant %uint 2925 + %uint_5 = OpConstant %uint 5 + %uint_64 = OpConstant %uint 64 + %uint_10 = OpConstant %uint 10 + %uint_512 = OpConstant %uint 512 + %uint_15 = OpConstant %uint 15 + %uint_255 = OpConstant %uint 255 +%uint_16711935 = OpConstant %uint 16711935 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2596 = OpConstantComposite %v3uint %uint_2 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 + %2620 = OpConstantComposite %v3uint %uint_2 %uint_2 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint + %125 = OpConstantComposite %v4uint %uint_0 %uint_8 %uint_0 %uint_8 +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform + %uint_12 = OpConstant %uint 12 + %uint_32 = OpConstant %uint 32 +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %1611 = OpConstantComposite %v4uint %uint_255 %uint_255 %uint_255 %uint_255 + %533 = OpConstantComposite %v4uint %uint_12 %uint_12 %uint_12 %uint_12 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %14903 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20158 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %22412 = OpLoad %uint %20158 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_7 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2596 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %14018 DontFlatten + OpBranchConditional %24679 %21992 %14018 + %21992 = OpLabel + OpBranch %14903 + %14018 = OpLabel + %17344 = OpShiftLeftLogical %v3uint %21387 %2620 + %14520 = OpBitcast %v3int %17344 + %8905 = OpCompositeExtract %int %14520 0 + %6813 = OpCompositeExtract %int %14520 2 + %21501 = OpBitcast %int %6594 + %11279 = OpIMul %int %6813 %21501 + %17598 = OpCompositeExtract %int %14520 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %22412 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %8905 %24535 + %10898 = OpBitcast %uint %8258 + %9077 = OpIAdd %uint %10898 %22411 + %11726 = OpShiftRightLogical %uint %9077 %uint_4 + %6977 = OpShiftRightLogical %uint %22412 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20009 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %21373 %6361 + %21373 = OpLabel + %10608 = OpBitcast %v3int %21387 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_9 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_9 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_9 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17091 = OpCompositeExtract %int %6573 0 + %9470 = OpShiftRightArithmetic %int %17091 %int_5 + %10056 = OpCompositeExtract %int %6573 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_10 + %10934 = OpBitwiseAnd %int %17091 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_3 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17091 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %21373 %12098 %6361 + OpBranch %24387 + %20009 = OpLabel + %24447 = OpBitcast %v3int %21387 + %8918 = OpCompositeExtract %int %24447 0 + %9362 = OpIMul %int %8918 %int_8 + %6362 = OpCompositeExtract %int %24447 2 + %14505 = OpBitcast %int %22409 + %11280 = OpIMul %int %6362 %14505 + %17599 = OpCompositeExtract %int %24447 1 + %22229 = OpIAdd %int %11280 %17599 + %22406 = OpBitcast %int %22408 + %7839 = OpIMul %int %22229 %22406 + %7984 = OpIAdd %int %9362 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20009 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %13392 None + OpBranchConditional %15139 %11064 %13392 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %13392 + %13392 = OpLabel + %22100 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %11876 = OpSelect %uint %17270 %uint_2 %uint_1 + %11339 = OpIAdd %uint %22117 %11876 + %18278 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %11339 + %6578 = OpLoad %v4uint %18278 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %13392 %16377 %10584 + OpSelectionMerge %11682 None + OpBranchConditional %15139 %11065 %11682 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11682 + %11682 = OpLabel + %19853 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %22133 = OpVectorShuffle %v4uint %22100 %22100 0 0 2 2 + %12416 = OpShiftRightLogical %v4uint %22133 %125 + %9078 = OpBitwiseAnd %v4uint %12416 %1611 + %17064 = OpVectorShuffle %v4uint %19853 %19853 0 0 2 2 + %7640 = OpShiftRightLogical %v4uint %17064 %125 + %6585 = OpBitwiseAnd %v4uint %7640 %1611 + %17985 = OpCompositeExtract %uint %22100 0 + %6272 = OpCompositeExtract %uint %22100 2 + %7641 = OpCompositeExtract %uint %19853 0 + %9980 = OpCompositeExtract %uint %19853 2 + %15375 = OpCompositeConstruct %v4uint %17985 %6272 %7641 %9980 + %10122 = OpShiftRightLogical %v4uint %15375 %749 + %23844 = OpCompositeExtract %uint %22100 1 + %24539 = OpCompositeExtract %uint %22100 3 + %7642 = OpCompositeExtract %uint %19853 1 + %10075 = OpCompositeExtract %uint %19853 3 + %16695 = OpCompositeConstruct %v4uint %23844 %24539 %7642 %10075 + %8679 = OpBitwiseAnd %v4uint %16695 %1611 + %20043 = OpShiftLeftLogical %v4uint %8679 %749 + %16241 = OpBitwiseOr %v4uint %10122 %20043 + %20096 = OpCompositeExtract %uint %16241 0 + %6502 = OpCompositeExtract %uint %9078 0 + %13104 = OpCompositeExtract %uint %9078 1 + %20099 = OpULessThanEqual %bool %6502 %13104 + OpSelectionMerge %11720 None + OpBranchConditional %20099 %10640 %21920 + %10640 = OpLabel + %17657 = OpBitwiseAnd %uint %20096 %uint_4793490 + %23948 = OpBitwiseAnd %uint %20096 %uint_9586980 + %21844 = OpShiftRightLogical %uint %23948 %uint_1 + %8133 = OpBitwiseAnd %uint %17657 %21844 + %24609 = OpShiftLeftLogical %uint %8133 %uint_1 + %22956 = OpShiftRightLogical %uint %8133 %uint_1 + %18793 = OpBitwiseOr %uint %24609 %22956 + %16049 = OpBitwiseOr %uint %8133 %18793 + %18309 = OpBitwiseAnd %uint %20096 %uint_2396745 + %14685 = OpBitwiseOr %uint %18309 %uint_14380470 + %20403 = OpBitwiseAnd %uint %14685 %16049 + %20539 = OpShiftRightLogical %uint %17657 %uint_1 + %24922 = OpBitwiseOr %uint %18309 %20539 + %21922 = OpShiftRightLogical %uint %23948 %uint_2 + %22674 = OpBitwiseOr %uint %24922 %21922 + %7721 = OpBitwiseXor %uint %22674 %uint_2396745 + %9540 = OpNot %uint %20539 + %14621 = OpBitwiseAnd %uint %18309 %9540 + %8425 = OpNot %uint %21922 + %11407 = OpBitwiseAnd %uint %14621 %8425 + %6799 = OpBitwiseOr %uint %20096 %7721 + %19509 = OpISub %uint %6799 %uint_2396745 + %14871 = OpBitwiseOr %uint %19509 %11407 + %18228 = OpShiftLeftLogical %uint %11407 %uint_2 + %15354 = OpBitwiseOr %uint %14871 %18228 + %12154 = OpNot %uint %16049 + %18512 = OpBitwiseAnd %uint %15354 %12154 + %6252 = OpBitwiseOr %uint %18512 %20403 + OpBranch %11720 + %21920 = OpLabel + %20079 = OpBitwiseAnd %uint %20096 %uint_2396745 + %23910 = OpBitwiseAnd %uint %20096 %uint_4793490 + %22247 = OpShiftRightLogical %uint %23910 %uint_1 + %24000 = OpBitwiseOr %uint %20079 %22247 + %19599 = OpBitwiseAnd %uint %20096 %uint_9586980 + %20615 = OpShiftRightLogical %uint %19599 %uint_2 + %24287 = OpBitwiseOr %uint %24000 %20615 + %7722 = OpBitwiseXor %uint %24287 %uint_2396745 + %9541 = OpNot %uint %22247 + %14622 = OpBitwiseAnd %uint %20079 %9541 + %8426 = OpNot %uint %20615 + %11408 = OpBitwiseAnd %uint %14622 %8426 + %6800 = OpBitwiseOr %uint %20096 %7722 + %19510 = OpISub %uint %6800 %uint_2396745 + %14872 = OpBitwiseOr %uint %19510 %11408 + %18152 = OpShiftLeftLogical %uint %11408 %uint_1 + %16008 = OpBitwiseOr %uint %14872 %18152 + %8118 = OpShiftLeftLogical %uint %11408 %uint_2 + %7808 = OpBitwiseOr %uint %16008 %8118 + OpBranch %11720 + %11720 = OpLabel + %17360 = OpPhi %uint %6252 %10640 %7808 %21920 + %23054 = OpCompositeExtract %uint %16241 1 + %12929 = OpCompositeExtract %uint %9078 2 + %13105 = OpCompositeExtract %uint %9078 3 + %20100 = OpULessThanEqual %bool %12929 %13105 + OpSelectionMerge %11721 None + OpBranchConditional %20100 %10641 %21921 + %10641 = OpLabel + %17658 = OpBitwiseAnd %uint %23054 %uint_4793490 + %23949 = OpBitwiseAnd %uint %23054 %uint_9586980 + %21845 = OpShiftRightLogical %uint %23949 %uint_1 + %8134 = OpBitwiseAnd %uint %17658 %21845 + %24610 = OpShiftLeftLogical %uint %8134 %uint_1 + %22957 = OpShiftRightLogical %uint %8134 %uint_1 + %18795 = OpBitwiseOr %uint %24610 %22957 + %16050 = OpBitwiseOr %uint %8134 %18795 + %18310 = OpBitwiseAnd %uint %23054 %uint_2396745 + %14686 = OpBitwiseOr %uint %18310 %uint_14380470 + %20404 = OpBitwiseAnd %uint %14686 %16050 + %20540 = OpShiftRightLogical %uint %17658 %uint_1 + %24923 = OpBitwiseOr %uint %18310 %20540 + %21923 = OpShiftRightLogical %uint %23949 %uint_2 + %22675 = OpBitwiseOr %uint %24923 %21923 + %7723 = OpBitwiseXor %uint %22675 %uint_2396745 + %9542 = OpNot %uint %20540 + %14623 = OpBitwiseAnd %uint %18310 %9542 + %8427 = OpNot %uint %21923 + %11409 = OpBitwiseAnd %uint %14623 %8427 + %6801 = OpBitwiseOr %uint %23054 %7723 + %19511 = OpISub %uint %6801 %uint_2396745 + %14873 = OpBitwiseOr %uint %19511 %11409 + %18229 = OpShiftLeftLogical %uint %11409 %uint_2 + %15355 = OpBitwiseOr %uint %14873 %18229 + %12155 = OpNot %uint %16050 + %18513 = OpBitwiseAnd %uint %15355 %12155 + %6253 = OpBitwiseOr %uint %18513 %20404 + OpBranch %11721 + %21921 = OpLabel + %20080 = OpBitwiseAnd %uint %23054 %uint_2396745 + %23911 = OpBitwiseAnd %uint %23054 %uint_4793490 + %22248 = OpShiftRightLogical %uint %23911 %uint_1 + %24001 = OpBitwiseOr %uint %20080 %22248 + %19600 = OpBitwiseAnd %uint %23054 %uint_9586980 + %20616 = OpShiftRightLogical %uint %19600 %uint_2 + %24288 = OpBitwiseOr %uint %24001 %20616 + %7724 = OpBitwiseXor %uint %24288 %uint_2396745 + %9543 = OpNot %uint %22248 + %14624 = OpBitwiseAnd %uint %20080 %9543 + %8428 = OpNot %uint %20616 + %11410 = OpBitwiseAnd %uint %14624 %8428 + %6802 = OpBitwiseOr %uint %23054 %7724 + %19512 = OpISub %uint %6802 %uint_2396745 + %14875 = OpBitwiseOr %uint %19512 %11410 + %18153 = OpShiftLeftLogical %uint %11410 %uint_1 + %16009 = OpBitwiseOr %uint %14875 %18153 + %8119 = OpShiftLeftLogical %uint %11410 %uint_2 + %7809 = OpBitwiseOr %uint %16009 %8119 + OpBranch %11721 + %11721 = OpLabel + %17361 = OpPhi %uint %6253 %10641 %7809 %21921 + %23055 = OpCompositeExtract %uint %16241 2 + %12930 = OpCompositeExtract %uint %6585 0 + %13107 = OpCompositeExtract %uint %6585 1 + %20101 = OpULessThanEqual %bool %12930 %13107 + OpSelectionMerge %11722 None + OpBranchConditional %20101 %10642 %21925 + %10642 = OpLabel + %17659 = OpBitwiseAnd %uint %23055 %uint_4793490 + %23950 = OpBitwiseAnd %uint %23055 %uint_9586980 + %21846 = OpShiftRightLogical %uint %23950 %uint_1 + %8135 = OpBitwiseAnd %uint %17659 %21846 + %24611 = OpShiftLeftLogical %uint %8135 %uint_1 + %22958 = OpShiftRightLogical %uint %8135 %uint_1 + %18796 = OpBitwiseOr %uint %24611 %22958 + %16051 = OpBitwiseOr %uint %8135 %18796 + %18311 = OpBitwiseAnd %uint %23055 %uint_2396745 + %14687 = OpBitwiseOr %uint %18311 %uint_14380470 + %20405 = OpBitwiseAnd %uint %14687 %16051 + %20541 = OpShiftRightLogical %uint %17659 %uint_1 + %24924 = OpBitwiseOr %uint %18311 %20541 + %21924 = OpShiftRightLogical %uint %23950 %uint_2 + %22676 = OpBitwiseOr %uint %24924 %21924 + %7725 = OpBitwiseXor %uint %22676 %uint_2396745 + %9544 = OpNot %uint %20541 + %14625 = OpBitwiseAnd %uint %18311 %9544 + %8429 = OpNot %uint %21924 + %11411 = OpBitwiseAnd %uint %14625 %8429 + %6803 = OpBitwiseOr %uint %23055 %7725 + %19513 = OpISub %uint %6803 %uint_2396745 + %14876 = OpBitwiseOr %uint %19513 %11411 + %18230 = OpShiftLeftLogical %uint %11411 %uint_2 + %15356 = OpBitwiseOr %uint %14876 %18230 + %12156 = OpNot %uint %16051 + %18514 = OpBitwiseAnd %uint %15356 %12156 + %6254 = OpBitwiseOr %uint %18514 %20405 + OpBranch %11722 + %21925 = OpLabel + %20081 = OpBitwiseAnd %uint %23055 %uint_2396745 + %23912 = OpBitwiseAnd %uint %23055 %uint_4793490 + %22249 = OpShiftRightLogical %uint %23912 %uint_1 + %24002 = OpBitwiseOr %uint %20081 %22249 + %19601 = OpBitwiseAnd %uint %23055 %uint_9586980 + %20617 = OpShiftRightLogical %uint %19601 %uint_2 + %24289 = OpBitwiseOr %uint %24002 %20617 + %7726 = OpBitwiseXor %uint %24289 %uint_2396745 + %9545 = OpNot %uint %22249 + %14626 = OpBitwiseAnd %uint %20081 %9545 + %8430 = OpNot %uint %20617 + %11412 = OpBitwiseAnd %uint %14626 %8430 + %6804 = OpBitwiseOr %uint %23055 %7726 + %19514 = OpISub %uint %6804 %uint_2396745 + %14877 = OpBitwiseOr %uint %19514 %11412 + %18154 = OpShiftLeftLogical %uint %11412 %uint_1 + %16010 = OpBitwiseOr %uint %14877 %18154 + %8120 = OpShiftLeftLogical %uint %11412 %uint_2 + %7810 = OpBitwiseOr %uint %16010 %8120 + OpBranch %11722 + %11722 = OpLabel + %17362 = OpPhi %uint %6254 %10642 %7810 %21925 + %23056 = OpCompositeExtract %uint %16241 3 + %12931 = OpCompositeExtract %uint %6585 2 + %13108 = OpCompositeExtract %uint %6585 3 + %20102 = OpULessThanEqual %bool %12931 %13108 + OpSelectionMerge %11701 None + OpBranchConditional %20102 %10643 %21927 + %10643 = OpLabel + %17660 = OpBitwiseAnd %uint %23056 %uint_4793490 + %23951 = OpBitwiseAnd %uint %23056 %uint_9586980 + %21847 = OpShiftRightLogical %uint %23951 %uint_1 + %8136 = OpBitwiseAnd %uint %17660 %21847 + %24612 = OpShiftLeftLogical %uint %8136 %uint_1 + %22959 = OpShiftRightLogical %uint %8136 %uint_1 + %18797 = OpBitwiseOr %uint %24612 %22959 + %16052 = OpBitwiseOr %uint %8136 %18797 + %18312 = OpBitwiseAnd %uint %23056 %uint_2396745 + %14688 = OpBitwiseOr %uint %18312 %uint_14380470 + %20406 = OpBitwiseAnd %uint %14688 %16052 + %20542 = OpShiftRightLogical %uint %17660 %uint_1 + %24925 = OpBitwiseOr %uint %18312 %20542 + %21926 = OpShiftRightLogical %uint %23951 %uint_2 + %22677 = OpBitwiseOr %uint %24925 %21926 + %7727 = OpBitwiseXor %uint %22677 %uint_2396745 + %9546 = OpNot %uint %20542 + %14627 = OpBitwiseAnd %uint %18312 %9546 + %8431 = OpNot %uint %21926 + %11413 = OpBitwiseAnd %uint %14627 %8431 + %6805 = OpBitwiseOr %uint %23056 %7727 + %19515 = OpISub %uint %6805 %uint_2396745 + %14878 = OpBitwiseOr %uint %19515 %11413 + %18231 = OpShiftLeftLogical %uint %11413 %uint_2 + %15357 = OpBitwiseOr %uint %14878 %18231 + %12157 = OpNot %uint %16052 + %18515 = OpBitwiseAnd %uint %15357 %12157 + %6255 = OpBitwiseOr %uint %18515 %20406 + OpBranch %11701 + %21927 = OpLabel + %20082 = OpBitwiseAnd %uint %23056 %uint_2396745 + %23913 = OpBitwiseAnd %uint %23056 %uint_4793490 + %22250 = OpShiftRightLogical %uint %23913 %uint_1 + %24003 = OpBitwiseOr %uint %20082 %22250 + %19602 = OpBitwiseAnd %uint %23056 %uint_9586980 + %20618 = OpShiftRightLogical %uint %19602 %uint_2 + %24290 = OpBitwiseOr %uint %24003 %20618 + %7728 = OpBitwiseXor %uint %24290 %uint_2396745 + %9547 = OpNot %uint %22250 + %14628 = OpBitwiseAnd %uint %20082 %9547 + %8432 = OpNot %uint %20618 + %11414 = OpBitwiseAnd %uint %14628 %8432 + %6806 = OpBitwiseOr %uint %23056 %7728 + %19516 = OpISub %uint %6806 %uint_2396745 + %14879 = OpBitwiseOr %uint %19516 %11414 + %18155 = OpShiftLeftLogical %uint %11414 %uint_1 + %16011 = OpBitwiseOr %uint %14879 %18155 + %8121 = OpShiftLeftLogical %uint %11414 %uint_2 + %7811 = OpBitwiseOr %uint %16011 %8121 + OpBranch %11701 + %11701 = OpLabel + %20687 = OpPhi %uint %6255 %10643 %7811 %21927 + %24811 = OpCompositeConstruct %v4uint %17360 %17361 %17362 %20687 + OpSelectionMerge %14880 None + OpBranchConditional %20099 %10644 %14526 + %10644 = OpLabel + %17661 = OpBitwiseAnd %uint %17360 %uint_1170 + %23952 = OpBitwiseAnd %uint %17360 %uint_2340 + %21848 = OpShiftRightLogical %uint %23952 %uint_1 + %8137 = OpBitwiseAnd %uint %17661 %21848 + %24613 = OpShiftLeftLogical %uint %8137 %uint_1 + %22960 = OpShiftRightLogical %uint %8137 %uint_1 + %18812 = OpBitwiseOr %uint %24613 %22960 + %15914 = OpBitwiseOr %uint %8137 %18812 + %8459 = OpNot %uint %15914 + %10082 = OpBitwiseAnd %uint %17360 %8459 + %16300 = OpISub %uint %uint_2925 %10082 + %17415 = OpBitwiseAnd %uint %16300 %8459 + %16991 = OpBitwiseAnd %uint %17415 %uint_7 + %13677 = OpIMul %uint %6502 %16991 + %21975 = OpBitwiseAnd %uint %10082 %uint_7 + %20390 = OpIMul %uint %13104 %21975 + %19842 = OpIAdd %uint %13677 %20390 + %13000 = OpUDiv %uint %19842 %uint_5 + %23022 = OpShiftRightLogical %uint %17415 %uint_3 + %8753 = OpBitwiseAnd %uint %23022 %uint_7 + %15011 = OpIMul %uint %6502 %8753 + %13283 = OpShiftRightLogical %uint %10082 %uint_3 + %24957 = OpBitwiseAnd %uint %13283 %uint_7 + %25194 = OpIMul %uint %13104 %24957 + %19880 = OpIAdd %uint %15011 %25194 + %12616 = OpUDiv %uint %19880 %uint_5 + %8160 = OpShiftLeftLogical %uint %12616 %uint_8 + %7553 = OpBitwiseOr %uint %13000 %8160 + %21935 = OpShiftRightLogical %uint %17415 %uint_6 + %17592 = OpBitwiseAnd %uint %21935 %uint_7 + %15012 = OpIMul %uint %6502 %17592 + %13284 = OpShiftRightLogical %uint %10082 %uint_6 + %24958 = OpBitwiseAnd %uint %13284 %uint_7 + %25195 = OpIMul %uint %13104 %24958 + %19881 = OpIAdd %uint %15012 %25195 + %12617 = OpUDiv %uint %19881 %uint_5 + %8161 = OpShiftLeftLogical %uint %12617 %uint_16 + %7554 = OpBitwiseOr %uint %7553 %8161 + %21936 = OpShiftRightLogical %uint %17415 %uint_9 + %17593 = OpBitwiseAnd %uint %21936 %uint_7 + %15013 = OpIMul %uint %6502 %17593 + %13285 = OpShiftRightLogical %uint %10082 %uint_9 + %24959 = OpBitwiseAnd %uint %13285 %uint_7 + %25196 = OpIMul %uint %13104 %24959 + %19882 = OpIAdd %uint %15013 %25196 + %12618 = OpUDiv %uint %19882 %uint_5 + %8255 = OpShiftLeftLogical %uint %12618 %uint_24 + %6688 = OpBitwiseOr %uint %7554 %8255 + %20385 = OpBitwiseAnd %uint %17360 %15914 + %17408 = OpBitwiseAnd %uint %20385 %uint_1 + %19559 = OpBitwiseAnd %uint %20385 %uint_8 + %24932 = OpShiftLeftLogical %uint %19559 %uint_5 + %17083 = OpBitwiseOr %uint %17408 %24932 + %20866 = OpBitwiseAnd %uint %20385 %uint_64 + %23319 = OpShiftLeftLogical %uint %20866 %uint_10 + %17084 = OpBitwiseOr %uint %17083 %23319 + %20867 = OpBitwiseAnd %uint %20385 %uint_512 + %22046 = OpShiftLeftLogical %uint %20867 %uint_15 + %8311 = OpBitwiseOr %uint %17084 %22046 + %10419 = OpIMul %uint %8311 %uint_255 + %18431 = OpIAdd %uint %6688 %10419 + OpBranch %14880 + %14526 = OpLabel + %10708 = OpNot %uint %17360 + %15358 = OpBitwiseAnd %uint %10708 %uint_7 + %17712 = OpIMul %uint %6502 %15358 + %21976 = OpBitwiseAnd %uint %17360 %uint_7 + %20391 = OpIMul %uint %13104 %21976 + %19843 = OpIAdd %uint %17712 %20391 + %13001 = OpUDiv %uint %19843 %uint_7 + %23023 = OpShiftRightLogical %uint %10708 %uint_3 + %8754 = OpBitwiseAnd %uint %23023 %uint_7 + %15014 = OpIMul %uint %6502 %8754 + %13286 = OpShiftRightLogical %uint %17360 %uint_3 + %24960 = OpBitwiseAnd %uint %13286 %uint_7 + %25197 = OpIMul %uint %13104 %24960 + %19883 = OpIAdd %uint %15014 %25197 + %12619 = OpUDiv %uint %19883 %uint_7 + %8162 = OpShiftLeftLogical %uint %12619 %uint_8 + %7555 = OpBitwiseOr %uint %13001 %8162 + %21937 = OpShiftRightLogical %uint %10708 %uint_6 + %17594 = OpBitwiseAnd %uint %21937 %uint_7 + %15015 = OpIMul %uint %6502 %17594 + %13287 = OpShiftRightLogical %uint %17360 %uint_6 + %24961 = OpBitwiseAnd %uint %13287 %uint_7 + %25198 = OpIMul %uint %13104 %24961 + %19884 = OpIAdd %uint %15015 %25198 + %12620 = OpUDiv %uint %19884 %uint_7 + %8163 = OpShiftLeftLogical %uint %12620 %uint_16 + %7556 = OpBitwiseOr %uint %7555 %8163 + %21938 = OpShiftRightLogical %uint %10708 %uint_9 + %17595 = OpBitwiseAnd %uint %21938 %uint_7 + %15016 = OpIMul %uint %6502 %17595 + %13288 = OpShiftRightLogical %uint %17360 %uint_9 + %24962 = OpBitwiseAnd %uint %13288 %uint_7 + %25199 = OpIMul %uint %13104 %24962 + %19885 = OpIAdd %uint %15016 %25199 + %12621 = OpUDiv %uint %19885 %uint_7 + %9205 = OpShiftLeftLogical %uint %12621 %uint_24 + %18040 = OpBitwiseOr %uint %7556 %9205 + OpBranch %14880 + %14880 = OpLabel + %10925 = OpPhi %uint %18431 %10644 %18040 %14526 + OpSelectionMerge %14881 None + OpBranchConditional %20100 %10645 %14527 + %10645 = OpLabel + %17662 = OpBitwiseAnd %uint %17361 %uint_1170 + %23953 = OpBitwiseAnd %uint %17361 %uint_2340 + %21849 = OpShiftRightLogical %uint %23953 %uint_1 + %8138 = OpBitwiseAnd %uint %17662 %21849 + %24614 = OpShiftLeftLogical %uint %8138 %uint_1 + %22961 = OpShiftRightLogical %uint %8138 %uint_1 + %18813 = OpBitwiseOr %uint %24614 %22961 + %15915 = OpBitwiseOr %uint %8138 %18813 + %8460 = OpNot %uint %15915 + %10083 = OpBitwiseAnd %uint %17361 %8460 + %16301 = OpISub %uint %uint_2925 %10083 + %17416 = OpBitwiseAnd %uint %16301 %8460 + %16992 = OpBitwiseAnd %uint %17416 %uint_7 + %13678 = OpIMul %uint %12929 %16992 + %21977 = OpBitwiseAnd %uint %10083 %uint_7 + %20392 = OpIMul %uint %13105 %21977 + %19844 = OpIAdd %uint %13678 %20392 + %13002 = OpUDiv %uint %19844 %uint_5 + %23024 = OpShiftRightLogical %uint %17416 %uint_3 + %8755 = OpBitwiseAnd %uint %23024 %uint_7 + %15017 = OpIMul %uint %12929 %8755 + %13289 = OpShiftRightLogical %uint %10083 %uint_3 + %24963 = OpBitwiseAnd %uint %13289 %uint_7 + %25200 = OpIMul %uint %13105 %24963 + %19886 = OpIAdd %uint %15017 %25200 + %12622 = OpUDiv %uint %19886 %uint_5 + %8164 = OpShiftLeftLogical %uint %12622 %uint_8 + %7557 = OpBitwiseOr %uint %13002 %8164 + %21939 = OpShiftRightLogical %uint %17416 %uint_6 + %17596 = OpBitwiseAnd %uint %21939 %uint_7 + %15018 = OpIMul %uint %12929 %17596 + %13290 = OpShiftRightLogical %uint %10083 %uint_6 + %24964 = OpBitwiseAnd %uint %13290 %uint_7 + %25201 = OpIMul %uint %13105 %24964 + %19887 = OpIAdd %uint %15018 %25201 + %12623 = OpUDiv %uint %19887 %uint_5 + %8165 = OpShiftLeftLogical %uint %12623 %uint_16 + %7558 = OpBitwiseOr %uint %7557 %8165 + %21940 = OpShiftRightLogical %uint %17416 %uint_9 + %17597 = OpBitwiseAnd %uint %21940 %uint_7 + %15019 = OpIMul %uint %12929 %17597 + %13291 = OpShiftRightLogical %uint %10083 %uint_9 + %24965 = OpBitwiseAnd %uint %13291 %uint_7 + %25202 = OpIMul %uint %13105 %24965 + %19888 = OpIAdd %uint %15019 %25202 + %12624 = OpUDiv %uint %19888 %uint_5 + %8256 = OpShiftLeftLogical %uint %12624 %uint_24 + %6689 = OpBitwiseOr %uint %7558 %8256 + %20386 = OpBitwiseAnd %uint %17361 %15915 + %17409 = OpBitwiseAnd %uint %20386 %uint_1 + %19560 = OpBitwiseAnd %uint %20386 %uint_8 + %24933 = OpShiftLeftLogical %uint %19560 %uint_5 + %17085 = OpBitwiseOr %uint %17409 %24933 + %20868 = OpBitwiseAnd %uint %20386 %uint_64 + %23320 = OpShiftLeftLogical %uint %20868 %uint_10 + %17086 = OpBitwiseOr %uint %17085 %23320 + %20869 = OpBitwiseAnd %uint %20386 %uint_512 + %22047 = OpShiftLeftLogical %uint %20869 %uint_15 + %8312 = OpBitwiseOr %uint %17086 %22047 + %10420 = OpIMul %uint %8312 %uint_255 + %18432 = OpIAdd %uint %6689 %10420 + OpBranch %14881 + %14527 = OpLabel + %10709 = OpNot %uint %17361 + %15359 = OpBitwiseAnd %uint %10709 %uint_7 + %17713 = OpIMul %uint %12929 %15359 + %21978 = OpBitwiseAnd %uint %17361 %uint_7 + %20393 = OpIMul %uint %13105 %21978 + %19845 = OpIAdd %uint %17713 %20393 + %13003 = OpUDiv %uint %19845 %uint_7 + %23025 = OpShiftRightLogical %uint %10709 %uint_3 + %8756 = OpBitwiseAnd %uint %23025 %uint_7 + %15020 = OpIMul %uint %12929 %8756 + %13292 = OpShiftRightLogical %uint %17361 %uint_3 + %24966 = OpBitwiseAnd %uint %13292 %uint_7 + %25203 = OpIMul %uint %13105 %24966 + %19889 = OpIAdd %uint %15020 %25203 + %12625 = OpUDiv %uint %19889 %uint_7 + %8166 = OpShiftLeftLogical %uint %12625 %uint_8 + %7559 = OpBitwiseOr %uint %13003 %8166 + %21941 = OpShiftRightLogical %uint %10709 %uint_6 + %17600 = OpBitwiseAnd %uint %21941 %uint_7 + %15021 = OpIMul %uint %12929 %17600 + %13293 = OpShiftRightLogical %uint %17361 %uint_6 + %24967 = OpBitwiseAnd %uint %13293 %uint_7 + %25204 = OpIMul %uint %13105 %24967 + %19890 = OpIAdd %uint %15021 %25204 + %12626 = OpUDiv %uint %19890 %uint_7 + %8167 = OpShiftLeftLogical %uint %12626 %uint_16 + %7560 = OpBitwiseOr %uint %7559 %8167 + %21942 = OpShiftRightLogical %uint %10709 %uint_9 + %17601 = OpBitwiseAnd %uint %21942 %uint_7 + %15022 = OpIMul %uint %12929 %17601 + %13294 = OpShiftRightLogical %uint %17361 %uint_9 + %24968 = OpBitwiseAnd %uint %13294 %uint_7 + %25205 = OpIMul %uint %13105 %24968 + %19891 = OpIAdd %uint %15022 %25205 + %12627 = OpUDiv %uint %19891 %uint_7 + %9206 = OpShiftLeftLogical %uint %12627 %uint_24 + %18041 = OpBitwiseOr %uint %7560 %9206 + OpBranch %14881 + %14881 = OpLabel + %10926 = OpPhi %uint %18432 %10645 %18041 %14527 + OpSelectionMerge %14882 None + OpBranchConditional %20101 %10646 %14528 + %10646 = OpLabel + %17663 = OpBitwiseAnd %uint %17362 %uint_1170 + %23954 = OpBitwiseAnd %uint %17362 %uint_2340 + %21850 = OpShiftRightLogical %uint %23954 %uint_1 + %8139 = OpBitwiseAnd %uint %17663 %21850 + %24615 = OpShiftLeftLogical %uint %8139 %uint_1 + %22962 = OpShiftRightLogical %uint %8139 %uint_1 + %18814 = OpBitwiseOr %uint %24615 %22962 + %15916 = OpBitwiseOr %uint %8139 %18814 + %8461 = OpNot %uint %15916 + %10084 = OpBitwiseAnd %uint %17362 %8461 + %16302 = OpISub %uint %uint_2925 %10084 + %17417 = OpBitwiseAnd %uint %16302 %8461 + %16993 = OpBitwiseAnd %uint %17417 %uint_7 + %13679 = OpIMul %uint %12930 %16993 + %21979 = OpBitwiseAnd %uint %10084 %uint_7 + %20394 = OpIMul %uint %13107 %21979 + %19846 = OpIAdd %uint %13679 %20394 + %13004 = OpUDiv %uint %19846 %uint_5 + %23026 = OpShiftRightLogical %uint %17417 %uint_3 + %8757 = OpBitwiseAnd %uint %23026 %uint_7 + %15023 = OpIMul %uint %12930 %8757 + %13295 = OpShiftRightLogical %uint %10084 %uint_3 + %24969 = OpBitwiseAnd %uint %13295 %uint_7 + %25206 = OpIMul %uint %13107 %24969 + %19892 = OpIAdd %uint %15023 %25206 + %12628 = OpUDiv %uint %19892 %uint_5 + %8168 = OpShiftLeftLogical %uint %12628 %uint_8 + %7561 = OpBitwiseOr %uint %13004 %8168 + %21943 = OpShiftRightLogical %uint %17417 %uint_6 + %17602 = OpBitwiseAnd %uint %21943 %uint_7 + %15024 = OpIMul %uint %12930 %17602 + %13296 = OpShiftRightLogical %uint %10084 %uint_6 + %24970 = OpBitwiseAnd %uint %13296 %uint_7 + %25207 = OpIMul %uint %13107 %24970 + %19893 = OpIAdd %uint %15024 %25207 + %12629 = OpUDiv %uint %19893 %uint_5 + %8169 = OpShiftLeftLogical %uint %12629 %uint_16 + %7562 = OpBitwiseOr %uint %7561 %8169 + %21944 = OpShiftRightLogical %uint %17417 %uint_9 + %17603 = OpBitwiseAnd %uint %21944 %uint_7 + %15025 = OpIMul %uint %12930 %17603 + %13297 = OpShiftRightLogical %uint %10084 %uint_9 + %24971 = OpBitwiseAnd %uint %13297 %uint_7 + %25208 = OpIMul %uint %13107 %24971 + %19894 = OpIAdd %uint %15025 %25208 + %12630 = OpUDiv %uint %19894 %uint_5 + %8257 = OpShiftLeftLogical %uint %12630 %uint_24 + %6690 = OpBitwiseOr %uint %7562 %8257 + %20387 = OpBitwiseAnd %uint %17362 %15916 + %17410 = OpBitwiseAnd %uint %20387 %uint_1 + %19561 = OpBitwiseAnd %uint %20387 %uint_8 + %24934 = OpShiftLeftLogical %uint %19561 %uint_5 + %17087 = OpBitwiseOr %uint %17410 %24934 + %20870 = OpBitwiseAnd %uint %20387 %uint_64 + %23321 = OpShiftLeftLogical %uint %20870 %uint_10 + %17088 = OpBitwiseOr %uint %17087 %23321 + %20871 = OpBitwiseAnd %uint %20387 %uint_512 + %22048 = OpShiftLeftLogical %uint %20871 %uint_15 + %8313 = OpBitwiseOr %uint %17088 %22048 + %10421 = OpIMul %uint %8313 %uint_255 + %18433 = OpIAdd %uint %6690 %10421 + OpBranch %14882 + %14528 = OpLabel + %10710 = OpNot %uint %17362 + %15360 = OpBitwiseAnd %uint %10710 %uint_7 + %17714 = OpIMul %uint %12930 %15360 + %21980 = OpBitwiseAnd %uint %17362 %uint_7 + %20395 = OpIMul %uint %13107 %21980 + %19847 = OpIAdd %uint %17714 %20395 + %13005 = OpUDiv %uint %19847 %uint_7 + %23027 = OpShiftRightLogical %uint %10710 %uint_3 + %8758 = OpBitwiseAnd %uint %23027 %uint_7 + %15026 = OpIMul %uint %12930 %8758 + %13298 = OpShiftRightLogical %uint %17362 %uint_3 + %24972 = OpBitwiseAnd %uint %13298 %uint_7 + %25209 = OpIMul %uint %13107 %24972 + %19895 = OpIAdd %uint %15026 %25209 + %12631 = OpUDiv %uint %19895 %uint_7 + %8170 = OpShiftLeftLogical %uint %12631 %uint_8 + %7563 = OpBitwiseOr %uint %13005 %8170 + %21945 = OpShiftRightLogical %uint %10710 %uint_6 + %17604 = OpBitwiseAnd %uint %21945 %uint_7 + %15027 = OpIMul %uint %12930 %17604 + %13299 = OpShiftRightLogical %uint %17362 %uint_6 + %24973 = OpBitwiseAnd %uint %13299 %uint_7 + %25210 = OpIMul %uint %13107 %24973 + %19896 = OpIAdd %uint %15027 %25210 + %12632 = OpUDiv %uint %19896 %uint_7 + %8171 = OpShiftLeftLogical %uint %12632 %uint_16 + %7564 = OpBitwiseOr %uint %7563 %8171 + %21946 = OpShiftRightLogical %uint %10710 %uint_9 + %17605 = OpBitwiseAnd %uint %21946 %uint_7 + %15028 = OpIMul %uint %12930 %17605 + %13300 = OpShiftRightLogical %uint %17362 %uint_9 + %24974 = OpBitwiseAnd %uint %13300 %uint_7 + %25211 = OpIMul %uint %13107 %24974 + %19897 = OpIAdd %uint %15028 %25211 + %12633 = OpUDiv %uint %19897 %uint_7 + %9207 = OpShiftLeftLogical %uint %12633 %uint_24 + %18042 = OpBitwiseOr %uint %7564 %9207 + OpBranch %14882 + %14882 = OpLabel + %10927 = OpPhi %uint %18433 %10646 %18042 %14528 + OpSelectionMerge %11702 None + OpBranchConditional %20102 %10647 %14529 + %10647 = OpLabel + %17664 = OpBitwiseAnd %uint %20687 %uint_1170 + %23955 = OpBitwiseAnd %uint %20687 %uint_2340 + %21851 = OpShiftRightLogical %uint %23955 %uint_1 + %8140 = OpBitwiseAnd %uint %17664 %21851 + %24616 = OpShiftLeftLogical %uint %8140 %uint_1 + %22963 = OpShiftRightLogical %uint %8140 %uint_1 + %18815 = OpBitwiseOr %uint %24616 %22963 + %15917 = OpBitwiseOr %uint %8140 %18815 + %8462 = OpNot %uint %15917 + %10085 = OpBitwiseAnd %uint %20687 %8462 + %16303 = OpISub %uint %uint_2925 %10085 + %17418 = OpBitwiseAnd %uint %16303 %8462 + %16994 = OpBitwiseAnd %uint %17418 %uint_7 + %13680 = OpIMul %uint %12931 %16994 + %21981 = OpBitwiseAnd %uint %10085 %uint_7 + %20396 = OpIMul %uint %13108 %21981 + %19848 = OpIAdd %uint %13680 %20396 + %13006 = OpUDiv %uint %19848 %uint_5 + %23028 = OpShiftRightLogical %uint %17418 %uint_3 + %8759 = OpBitwiseAnd %uint %23028 %uint_7 + %15029 = OpIMul %uint %12931 %8759 + %13301 = OpShiftRightLogical %uint %10085 %uint_3 + %24975 = OpBitwiseAnd %uint %13301 %uint_7 + %25212 = OpIMul %uint %13108 %24975 + %19898 = OpIAdd %uint %15029 %25212 + %12634 = OpUDiv %uint %19898 %uint_5 + %8172 = OpShiftLeftLogical %uint %12634 %uint_8 + %7565 = OpBitwiseOr %uint %13006 %8172 + %21947 = OpShiftRightLogical %uint %17418 %uint_6 + %17606 = OpBitwiseAnd %uint %21947 %uint_7 + %15030 = OpIMul %uint %12931 %17606 + %13302 = OpShiftRightLogical %uint %10085 %uint_6 + %24976 = OpBitwiseAnd %uint %13302 %uint_7 + %25213 = OpIMul %uint %13108 %24976 + %19899 = OpIAdd %uint %15030 %25213 + %12635 = OpUDiv %uint %19899 %uint_5 + %8173 = OpShiftLeftLogical %uint %12635 %uint_16 + %7566 = OpBitwiseOr %uint %7565 %8173 + %21948 = OpShiftRightLogical %uint %17418 %uint_9 + %17607 = OpBitwiseAnd %uint %21948 %uint_7 + %15031 = OpIMul %uint %12931 %17607 + %13303 = OpShiftRightLogical %uint %10085 %uint_9 + %24977 = OpBitwiseAnd %uint %13303 %uint_7 + %25214 = OpIMul %uint %13108 %24977 + %19900 = OpIAdd %uint %15031 %25214 + %12636 = OpUDiv %uint %19900 %uint_5 + %8259 = OpShiftLeftLogical %uint %12636 %uint_24 + %6691 = OpBitwiseOr %uint %7566 %8259 + %20388 = OpBitwiseAnd %uint %20687 %15917 + %17411 = OpBitwiseAnd %uint %20388 %uint_1 + %19562 = OpBitwiseAnd %uint %20388 %uint_8 + %24935 = OpShiftLeftLogical %uint %19562 %uint_5 + %17089 = OpBitwiseOr %uint %17411 %24935 + %20872 = OpBitwiseAnd %uint %20388 %uint_64 + %23322 = OpShiftLeftLogical %uint %20872 %uint_10 + %17092 = OpBitwiseOr %uint %17089 %23322 + %20873 = OpBitwiseAnd %uint %20388 %uint_512 + %22049 = OpShiftLeftLogical %uint %20873 %uint_15 + %8314 = OpBitwiseOr %uint %17092 %22049 + %10422 = OpIMul %uint %8314 %uint_255 + %18434 = OpIAdd %uint %6691 %10422 + OpBranch %11702 + %14529 = OpLabel + %10711 = OpNot %uint %20687 + %15361 = OpBitwiseAnd %uint %10711 %uint_7 + %17715 = OpIMul %uint %12931 %15361 + %21982 = OpBitwiseAnd %uint %20687 %uint_7 + %20397 = OpIMul %uint %13108 %21982 + %19849 = OpIAdd %uint %17715 %20397 + %13007 = OpUDiv %uint %19849 %uint_7 + %23029 = OpShiftRightLogical %uint %10711 %uint_3 + %8760 = OpBitwiseAnd %uint %23029 %uint_7 + %15032 = OpIMul %uint %12931 %8760 + %13304 = OpShiftRightLogical %uint %20687 %uint_3 + %24978 = OpBitwiseAnd %uint %13304 %uint_7 + %25215 = OpIMul %uint %13108 %24978 + %19901 = OpIAdd %uint %15032 %25215 + %12637 = OpUDiv %uint %19901 %uint_7 + %8174 = OpShiftLeftLogical %uint %12637 %uint_8 + %7567 = OpBitwiseOr %uint %13007 %8174 + %21949 = OpShiftRightLogical %uint %10711 %uint_6 + %17608 = OpBitwiseAnd %uint %21949 %uint_7 + %15033 = OpIMul %uint %12931 %17608 + %13305 = OpShiftRightLogical %uint %20687 %uint_6 + %24979 = OpBitwiseAnd %uint %13305 %uint_7 + %25216 = OpIMul %uint %13108 %24979 + %19902 = OpIAdd %uint %15033 %25216 + %12638 = OpUDiv %uint %19902 %uint_7 + %8175 = OpShiftLeftLogical %uint %12638 %uint_16 + %7568 = OpBitwiseOr %uint %7567 %8175 + %21950 = OpShiftRightLogical %uint %10711 %uint_9 + %17609 = OpBitwiseAnd %uint %21950 %uint_7 + %15034 = OpIMul %uint %12931 %17609 + %13306 = OpShiftRightLogical %uint %20687 %uint_9 + %24980 = OpBitwiseAnd %uint %13306 %uint_7 + %25217 = OpIMul %uint %13108 %24980 + %19903 = OpIAdd %uint %15034 %25217 + %12639 = OpUDiv %uint %19903 %uint_7 + %9208 = OpShiftLeftLogical %uint %12639 %uint_24 + %18043 = OpBitwiseOr %uint %7568 %9208 + OpBranch %11702 + %11702 = OpLabel + %17229 = OpPhi %uint %18434 %10647 %18043 %14529 + %14583 = OpCompositeConstruct %v4uint %10925 %10926 %10927 %17229 + %12213 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11726 + OpStore %12213 %14583 + %12832 = OpCompositeExtract %uint %17344 1 + %23232 = OpIAdd %uint %12832 %int_1 + %17425 = OpULessThan %bool %23232 %6594 + OpSelectionMerge %7206 DontFlatten + OpBranchConditional %17425 %22828 %7206 + %22828 = OpLabel + %13334 = OpIAdd %uint %11726 %6977 + %15655 = OpShiftRightLogical %v4uint %24811 %533 + %23835 = OpCompositeExtract %uint %15655 0 + OpSelectionMerge %11723 None + OpBranchConditional %20099 %10648 %14530 + %10648 = OpLabel + %17665 = OpBitwiseAnd %uint %23835 %uint_1170 + %23956 = OpBitwiseAnd %uint %23835 %uint_2340 + %21852 = OpShiftRightLogical %uint %23956 %uint_1 + %8141 = OpBitwiseAnd %uint %17665 %21852 + %24617 = OpShiftLeftLogical %uint %8141 %uint_1 + %22964 = OpShiftRightLogical %uint %8141 %uint_1 + %18816 = OpBitwiseOr %uint %24617 %22964 + %15918 = OpBitwiseOr %uint %8141 %18816 + %8463 = OpNot %uint %15918 + %10086 = OpBitwiseAnd %uint %23835 %8463 + %16304 = OpISub %uint %uint_2925 %10086 + %17419 = OpBitwiseAnd %uint %16304 %8463 + %16995 = OpBitwiseAnd %uint %17419 %uint_7 + %13681 = OpIMul %uint %6502 %16995 + %21983 = OpBitwiseAnd %uint %10086 %uint_7 + %20398 = OpIMul %uint %13104 %21983 + %19850 = OpIAdd %uint %13681 %20398 + %13008 = OpUDiv %uint %19850 %uint_5 + %23030 = OpShiftRightLogical %uint %17419 %uint_3 + %8761 = OpBitwiseAnd %uint %23030 %uint_7 + %15035 = OpIMul %uint %6502 %8761 + %13307 = OpShiftRightLogical %uint %10086 %uint_3 + %24981 = OpBitwiseAnd %uint %13307 %uint_7 + %25218 = OpIMul %uint %13104 %24981 + %19904 = OpIAdd %uint %15035 %25218 + %12640 = OpUDiv %uint %19904 %uint_5 + %8176 = OpShiftLeftLogical %uint %12640 %uint_8 + %7569 = OpBitwiseOr %uint %13008 %8176 + %21951 = OpShiftRightLogical %uint %17419 %uint_6 + %17610 = OpBitwiseAnd %uint %21951 %uint_7 + %15036 = OpIMul %uint %6502 %17610 + %13308 = OpShiftRightLogical %uint %10086 %uint_6 + %24982 = OpBitwiseAnd %uint %13308 %uint_7 + %25219 = OpIMul %uint %13104 %24982 + %19905 = OpIAdd %uint %15036 %25219 + %12641 = OpUDiv %uint %19905 %uint_5 + %8177 = OpShiftLeftLogical %uint %12641 %uint_16 + %7570 = OpBitwiseOr %uint %7569 %8177 + %21952 = OpShiftRightLogical %uint %17419 %uint_9 + %17611 = OpBitwiseAnd %uint %21952 %uint_7 + %15037 = OpIMul %uint %6502 %17611 + %13309 = OpShiftRightLogical %uint %10086 %uint_9 + %24983 = OpBitwiseAnd %uint %13309 %uint_7 + %25220 = OpIMul %uint %13104 %24983 + %19906 = OpIAdd %uint %15037 %25220 + %12642 = OpUDiv %uint %19906 %uint_5 + %8260 = OpShiftLeftLogical %uint %12642 %uint_24 + %6692 = OpBitwiseOr %uint %7570 %8260 + %20389 = OpBitwiseAnd %uint %23835 %15918 + %17412 = OpBitwiseAnd %uint %20389 %uint_1 + %19563 = OpBitwiseAnd %uint %20389 %uint_8 + %24936 = OpShiftLeftLogical %uint %19563 %uint_5 + %17093 = OpBitwiseOr %uint %17412 %24936 + %20874 = OpBitwiseAnd %uint %20389 %uint_64 + %23323 = OpShiftLeftLogical %uint %20874 %uint_10 + %17094 = OpBitwiseOr %uint %17093 %23323 + %20875 = OpBitwiseAnd %uint %20389 %uint_512 + %22050 = OpShiftLeftLogical %uint %20875 %uint_15 + %8315 = OpBitwiseOr %uint %17094 %22050 + %10423 = OpIMul %uint %8315 %uint_255 + %18435 = OpIAdd %uint %6692 %10423 + OpBranch %11723 + %14530 = OpLabel + %10712 = OpNot %uint %23835 + %15362 = OpBitwiseAnd %uint %10712 %uint_7 + %17716 = OpIMul %uint %6502 %15362 + %21984 = OpBitwiseAnd %uint %23835 %uint_7 + %20399 = OpIMul %uint %13104 %21984 + %19851 = OpIAdd %uint %17716 %20399 + %13009 = OpUDiv %uint %19851 %uint_7 + %23031 = OpShiftRightLogical %uint %10712 %uint_3 + %8762 = OpBitwiseAnd %uint %23031 %uint_7 + %15038 = OpIMul %uint %6502 %8762 + %13310 = OpShiftRightLogical %uint %23835 %uint_3 + %24984 = OpBitwiseAnd %uint %13310 %uint_7 + %25221 = OpIMul %uint %13104 %24984 + %19907 = OpIAdd %uint %15038 %25221 + %12643 = OpUDiv %uint %19907 %uint_7 + %8178 = OpShiftLeftLogical %uint %12643 %uint_8 + %7571 = OpBitwiseOr %uint %13009 %8178 + %21953 = OpShiftRightLogical %uint %10712 %uint_6 + %17612 = OpBitwiseAnd %uint %21953 %uint_7 + %15039 = OpIMul %uint %6502 %17612 + %13311 = OpShiftRightLogical %uint %23835 %uint_6 + %24985 = OpBitwiseAnd %uint %13311 %uint_7 + %25222 = OpIMul %uint %13104 %24985 + %19908 = OpIAdd %uint %15039 %25222 + %12644 = OpUDiv %uint %19908 %uint_7 + %8179 = OpShiftLeftLogical %uint %12644 %uint_16 + %7572 = OpBitwiseOr %uint %7571 %8179 + %21954 = OpShiftRightLogical %uint %10712 %uint_9 + %17613 = OpBitwiseAnd %uint %21954 %uint_7 + %15040 = OpIMul %uint %6502 %17613 + %13312 = OpShiftRightLogical %uint %23835 %uint_9 + %24986 = OpBitwiseAnd %uint %13312 %uint_7 + %25223 = OpIMul %uint %13104 %24986 + %19909 = OpIAdd %uint %15040 %25223 + %12645 = OpUDiv %uint %19909 %uint_7 + %9209 = OpShiftLeftLogical %uint %12645 %uint_24 + %18044 = OpBitwiseOr %uint %7572 %9209 + OpBranch %11723 + %11723 = OpLabel + %20515 = OpPhi %uint %18435 %10648 %18044 %14530 + %16618 = OpCompositeExtract %uint %15655 1 + OpSelectionMerge %11724 None + OpBranchConditional %20100 %10649 %14531 + %10649 = OpLabel + %17666 = OpBitwiseAnd %uint %16618 %uint_1170 + %23957 = OpBitwiseAnd %uint %16618 %uint_2340 + %21853 = OpShiftRightLogical %uint %23957 %uint_1 + %8142 = OpBitwiseAnd %uint %17666 %21853 + %24618 = OpShiftLeftLogical %uint %8142 %uint_1 + %22965 = OpShiftRightLogical %uint %8142 %uint_1 + %18817 = OpBitwiseOr %uint %24618 %22965 + %15919 = OpBitwiseOr %uint %8142 %18817 + %8464 = OpNot %uint %15919 + %10087 = OpBitwiseAnd %uint %16618 %8464 + %16305 = OpISub %uint %uint_2925 %10087 + %17420 = OpBitwiseAnd %uint %16305 %8464 + %16996 = OpBitwiseAnd %uint %17420 %uint_7 + %13682 = OpIMul %uint %12929 %16996 + %21985 = OpBitwiseAnd %uint %10087 %uint_7 + %20400 = OpIMul %uint %13105 %21985 + %19852 = OpIAdd %uint %13682 %20400 + %13010 = OpUDiv %uint %19852 %uint_5 + %23032 = OpShiftRightLogical %uint %17420 %uint_3 + %8763 = OpBitwiseAnd %uint %23032 %uint_7 + %15041 = OpIMul %uint %12929 %8763 + %13313 = OpShiftRightLogical %uint %10087 %uint_3 + %24987 = OpBitwiseAnd %uint %13313 %uint_7 + %25224 = OpIMul %uint %13105 %24987 + %19910 = OpIAdd %uint %15041 %25224 + %12646 = OpUDiv %uint %19910 %uint_5 + %8180 = OpShiftLeftLogical %uint %12646 %uint_8 + %7573 = OpBitwiseOr %uint %13010 %8180 + %21955 = OpShiftRightLogical %uint %17420 %uint_6 + %17614 = OpBitwiseAnd %uint %21955 %uint_7 + %15042 = OpIMul %uint %12929 %17614 + %13314 = OpShiftRightLogical %uint %10087 %uint_6 + %24988 = OpBitwiseAnd %uint %13314 %uint_7 + %25225 = OpIMul %uint %13105 %24988 + %19911 = OpIAdd %uint %15042 %25225 + %12647 = OpUDiv %uint %19911 %uint_5 + %8181 = OpShiftLeftLogical %uint %12647 %uint_16 + %7574 = OpBitwiseOr %uint %7573 %8181 + %21956 = OpShiftRightLogical %uint %17420 %uint_9 + %17615 = OpBitwiseAnd %uint %21956 %uint_7 + %15043 = OpIMul %uint %12929 %17615 + %13315 = OpShiftRightLogical %uint %10087 %uint_9 + %24989 = OpBitwiseAnd %uint %13315 %uint_7 + %25226 = OpIMul %uint %13105 %24989 + %19912 = OpIAdd %uint %15043 %25226 + %12648 = OpUDiv %uint %19912 %uint_5 + %8261 = OpShiftLeftLogical %uint %12648 %uint_24 + %6693 = OpBitwiseOr %uint %7574 %8261 + %20401 = OpBitwiseAnd %uint %16618 %15919 + %17413 = OpBitwiseAnd %uint %20401 %uint_1 + %19564 = OpBitwiseAnd %uint %20401 %uint_8 + %24937 = OpShiftLeftLogical %uint %19564 %uint_5 + %17095 = OpBitwiseOr %uint %17413 %24937 + %20876 = OpBitwiseAnd %uint %20401 %uint_64 + %23324 = OpShiftLeftLogical %uint %20876 %uint_10 + %17096 = OpBitwiseOr %uint %17095 %23324 + %20877 = OpBitwiseAnd %uint %20401 %uint_512 + %22051 = OpShiftLeftLogical %uint %20877 %uint_15 + %8316 = OpBitwiseOr %uint %17096 %22051 + %10424 = OpIMul %uint %8316 %uint_255 + %18436 = OpIAdd %uint %6693 %10424 + OpBranch %11724 + %14531 = OpLabel + %10713 = OpNot %uint %16618 + %15363 = OpBitwiseAnd %uint %10713 %uint_7 + %17717 = OpIMul %uint %12929 %15363 + %21986 = OpBitwiseAnd %uint %16618 %uint_7 + %20402 = OpIMul %uint %13105 %21986 + %19854 = OpIAdd %uint %17717 %20402 + %13011 = OpUDiv %uint %19854 %uint_7 + %23033 = OpShiftRightLogical %uint %10713 %uint_3 + %8764 = OpBitwiseAnd %uint %23033 %uint_7 + %15044 = OpIMul %uint %12929 %8764 + %13316 = OpShiftRightLogical %uint %16618 %uint_3 + %24990 = OpBitwiseAnd %uint %13316 %uint_7 + %25227 = OpIMul %uint %13105 %24990 + %19913 = OpIAdd %uint %15044 %25227 + %12649 = OpUDiv %uint %19913 %uint_7 + %8182 = OpShiftLeftLogical %uint %12649 %uint_8 + %7575 = OpBitwiseOr %uint %13011 %8182 + %21957 = OpShiftRightLogical %uint %10713 %uint_6 + %17616 = OpBitwiseAnd %uint %21957 %uint_7 + %15045 = OpIMul %uint %12929 %17616 + %13317 = OpShiftRightLogical %uint %16618 %uint_6 + %24991 = OpBitwiseAnd %uint %13317 %uint_7 + %25228 = OpIMul %uint %13105 %24991 + %19914 = OpIAdd %uint %15045 %25228 + %12650 = OpUDiv %uint %19914 %uint_7 + %8183 = OpShiftLeftLogical %uint %12650 %uint_16 + %7576 = OpBitwiseOr %uint %7575 %8183 + %21958 = OpShiftRightLogical %uint %10713 %uint_9 + %17617 = OpBitwiseAnd %uint %21958 %uint_7 + %15046 = OpIMul %uint %12929 %17617 + %13318 = OpShiftRightLogical %uint %16618 %uint_9 + %24992 = OpBitwiseAnd %uint %13318 %uint_7 + %25229 = OpIMul %uint %13105 %24992 + %19915 = OpIAdd %uint %15046 %25229 + %12651 = OpUDiv %uint %19915 %uint_7 + %9210 = OpShiftLeftLogical %uint %12651 %uint_24 + %18045 = OpBitwiseOr %uint %7576 %9210 + OpBranch %11724 + %11724 = OpLabel + %20516 = OpPhi %uint %18436 %10649 %18045 %14531 + %16619 = OpCompositeExtract %uint %15655 2 + OpSelectionMerge %11725 None + OpBranchConditional %20101 %10650 %14532 + %10650 = OpLabel + %17667 = OpBitwiseAnd %uint %16619 %uint_1170 + %23958 = OpBitwiseAnd %uint %16619 %uint_2340 + %21854 = OpShiftRightLogical %uint %23958 %uint_1 + %8143 = OpBitwiseAnd %uint %17667 %21854 + %24619 = OpShiftLeftLogical %uint %8143 %uint_1 + %22966 = OpShiftRightLogical %uint %8143 %uint_1 + %18818 = OpBitwiseOr %uint %24619 %22966 + %15920 = OpBitwiseOr %uint %8143 %18818 + %8465 = OpNot %uint %15920 + %10088 = OpBitwiseAnd %uint %16619 %8465 + %16306 = OpISub %uint %uint_2925 %10088 + %17421 = OpBitwiseAnd %uint %16306 %8465 + %16997 = OpBitwiseAnd %uint %17421 %uint_7 + %13683 = OpIMul %uint %12930 %16997 + %21987 = OpBitwiseAnd %uint %10088 %uint_7 + %20407 = OpIMul %uint %13107 %21987 + %19855 = OpIAdd %uint %13683 %20407 + %13012 = OpUDiv %uint %19855 %uint_5 + %23034 = OpShiftRightLogical %uint %17421 %uint_3 + %8765 = OpBitwiseAnd %uint %23034 %uint_7 + %15047 = OpIMul %uint %12930 %8765 + %13319 = OpShiftRightLogical %uint %10088 %uint_3 + %24993 = OpBitwiseAnd %uint %13319 %uint_7 + %25230 = OpIMul %uint %13107 %24993 + %19916 = OpIAdd %uint %15047 %25230 + %12652 = OpUDiv %uint %19916 %uint_5 + %8184 = OpShiftLeftLogical %uint %12652 %uint_8 + %7577 = OpBitwiseOr %uint %13012 %8184 + %21959 = OpShiftRightLogical %uint %17421 %uint_6 + %17618 = OpBitwiseAnd %uint %21959 %uint_7 + %15048 = OpIMul %uint %12930 %17618 + %13320 = OpShiftRightLogical %uint %10088 %uint_6 + %24994 = OpBitwiseAnd %uint %13320 %uint_7 + %25231 = OpIMul %uint %13107 %24994 + %19917 = OpIAdd %uint %15048 %25231 + %12653 = OpUDiv %uint %19917 %uint_5 + %8185 = OpShiftLeftLogical %uint %12653 %uint_16 + %7578 = OpBitwiseOr %uint %7577 %8185 + %21960 = OpShiftRightLogical %uint %17421 %uint_9 + %17619 = OpBitwiseAnd %uint %21960 %uint_7 + %15049 = OpIMul %uint %12930 %17619 + %13321 = OpShiftRightLogical %uint %10088 %uint_9 + %24995 = OpBitwiseAnd %uint %13321 %uint_7 + %25232 = OpIMul %uint %13107 %24995 + %19918 = OpIAdd %uint %15049 %25232 + %12654 = OpUDiv %uint %19918 %uint_5 + %8262 = OpShiftLeftLogical %uint %12654 %uint_24 + %6694 = OpBitwiseOr %uint %7578 %8262 + %20408 = OpBitwiseAnd %uint %16619 %15920 + %17414 = OpBitwiseAnd %uint %20408 %uint_1 + %19565 = OpBitwiseAnd %uint %20408 %uint_8 + %24938 = OpShiftLeftLogical %uint %19565 %uint_5 + %17097 = OpBitwiseOr %uint %17414 %24938 + %20878 = OpBitwiseAnd %uint %20408 %uint_64 + %23325 = OpShiftLeftLogical %uint %20878 %uint_10 + %17098 = OpBitwiseOr %uint %17097 %23325 + %20879 = OpBitwiseAnd %uint %20408 %uint_512 + %22052 = OpShiftLeftLogical %uint %20879 %uint_15 + %8317 = OpBitwiseOr %uint %17098 %22052 + %10425 = OpIMul %uint %8317 %uint_255 + %18437 = OpIAdd %uint %6694 %10425 + OpBranch %11725 + %14532 = OpLabel + %10714 = OpNot %uint %16619 + %15364 = OpBitwiseAnd %uint %10714 %uint_7 + %17718 = OpIMul %uint %12930 %15364 + %21988 = OpBitwiseAnd %uint %16619 %uint_7 + %20409 = OpIMul %uint %13107 %21988 + %19856 = OpIAdd %uint %17718 %20409 + %13013 = OpUDiv %uint %19856 %uint_7 + %23035 = OpShiftRightLogical %uint %10714 %uint_3 + %8766 = OpBitwiseAnd %uint %23035 %uint_7 + %15050 = OpIMul %uint %12930 %8766 + %13322 = OpShiftRightLogical %uint %16619 %uint_3 + %24996 = OpBitwiseAnd %uint %13322 %uint_7 + %25233 = OpIMul %uint %13107 %24996 + %19919 = OpIAdd %uint %15050 %25233 + %12655 = OpUDiv %uint %19919 %uint_7 + %8186 = OpShiftLeftLogical %uint %12655 %uint_8 + %7579 = OpBitwiseOr %uint %13013 %8186 + %21961 = OpShiftRightLogical %uint %10714 %uint_6 + %17620 = OpBitwiseAnd %uint %21961 %uint_7 + %15051 = OpIMul %uint %12930 %17620 + %13323 = OpShiftRightLogical %uint %16619 %uint_6 + %24997 = OpBitwiseAnd %uint %13323 %uint_7 + %25234 = OpIMul %uint %13107 %24997 + %19920 = OpIAdd %uint %15051 %25234 + %12656 = OpUDiv %uint %19920 %uint_7 + %8187 = OpShiftLeftLogical %uint %12656 %uint_16 + %7580 = OpBitwiseOr %uint %7579 %8187 + %21962 = OpShiftRightLogical %uint %10714 %uint_9 + %17621 = OpBitwiseAnd %uint %21962 %uint_7 + %15052 = OpIMul %uint %12930 %17621 + %13324 = OpShiftRightLogical %uint %16619 %uint_9 + %24998 = OpBitwiseAnd %uint %13324 %uint_7 + %25235 = OpIMul %uint %13107 %24998 + %19921 = OpIAdd %uint %15052 %25235 + %12657 = OpUDiv %uint %19921 %uint_7 + %9211 = OpShiftLeftLogical %uint %12657 %uint_24 + %18046 = OpBitwiseOr %uint %7580 %9211 + OpBranch %11725 + %11725 = OpLabel + %20517 = OpPhi %uint %18437 %10650 %18046 %14532 + %16620 = OpCompositeExtract %uint %15655 3 + OpSelectionMerge %11703 None + OpBranchConditional %20102 %10651 %14533 + %10651 = OpLabel + %17668 = OpBitwiseAnd %uint %16620 %uint_1170 + %23959 = OpBitwiseAnd %uint %16620 %uint_2340 + %21855 = OpShiftRightLogical %uint %23959 %uint_1 + %8144 = OpBitwiseAnd %uint %17668 %21855 + %24620 = OpShiftLeftLogical %uint %8144 %uint_1 + %22967 = OpShiftRightLogical %uint %8144 %uint_1 + %18819 = OpBitwiseOr %uint %24620 %22967 + %15921 = OpBitwiseOr %uint %8144 %18819 + %8466 = OpNot %uint %15921 + %10089 = OpBitwiseAnd %uint %16620 %8466 + %16307 = OpISub %uint %uint_2925 %10089 + %17422 = OpBitwiseAnd %uint %16307 %8466 + %16998 = OpBitwiseAnd %uint %17422 %uint_7 + %13684 = OpIMul %uint %12931 %16998 + %21989 = OpBitwiseAnd %uint %10089 %uint_7 + %20410 = OpIMul %uint %13108 %21989 + %19857 = OpIAdd %uint %13684 %20410 + %13014 = OpUDiv %uint %19857 %uint_5 + %23036 = OpShiftRightLogical %uint %17422 %uint_3 + %8767 = OpBitwiseAnd %uint %23036 %uint_7 + %15053 = OpIMul %uint %12931 %8767 + %13325 = OpShiftRightLogical %uint %10089 %uint_3 + %24999 = OpBitwiseAnd %uint %13325 %uint_7 + %25236 = OpIMul %uint %13108 %24999 + %19922 = OpIAdd %uint %15053 %25236 + %12658 = OpUDiv %uint %19922 %uint_5 + %8188 = OpShiftLeftLogical %uint %12658 %uint_8 + %7581 = OpBitwiseOr %uint %13014 %8188 + %21963 = OpShiftRightLogical %uint %17422 %uint_6 + %17622 = OpBitwiseAnd %uint %21963 %uint_7 + %15054 = OpIMul %uint %12931 %17622 + %13326 = OpShiftRightLogical %uint %10089 %uint_6 + %25000 = OpBitwiseAnd %uint %13326 %uint_7 + %25237 = OpIMul %uint %13108 %25000 + %19923 = OpIAdd %uint %15054 %25237 + %12659 = OpUDiv %uint %19923 %uint_5 + %8189 = OpShiftLeftLogical %uint %12659 %uint_16 + %7582 = OpBitwiseOr %uint %7581 %8189 + %21964 = OpShiftRightLogical %uint %17422 %uint_9 + %17623 = OpBitwiseAnd %uint %21964 %uint_7 + %15055 = OpIMul %uint %12931 %17623 + %13327 = OpShiftRightLogical %uint %10089 %uint_9 + %25001 = OpBitwiseAnd %uint %13327 %uint_7 + %25238 = OpIMul %uint %13108 %25001 + %19924 = OpIAdd %uint %15055 %25238 + %12660 = OpUDiv %uint %19924 %uint_5 + %8263 = OpShiftLeftLogical %uint %12660 %uint_24 + %6695 = OpBitwiseOr %uint %7582 %8263 + %20411 = OpBitwiseAnd %uint %16620 %15921 + %17423 = OpBitwiseAnd %uint %20411 %uint_1 + %19566 = OpBitwiseAnd %uint %20411 %uint_8 + %24939 = OpShiftLeftLogical %uint %19566 %uint_5 + %17099 = OpBitwiseOr %uint %17423 %24939 + %20880 = OpBitwiseAnd %uint %20411 %uint_64 + %23326 = OpShiftLeftLogical %uint %20880 %uint_10 + %17100 = OpBitwiseOr %uint %17099 %23326 + %20881 = OpBitwiseAnd %uint %20411 %uint_512 + %22053 = OpShiftLeftLogical %uint %20881 %uint_15 + %8318 = OpBitwiseOr %uint %17100 %22053 + %10426 = OpIMul %uint %8318 %uint_255 + %18438 = OpIAdd %uint %6695 %10426 + OpBranch %11703 + %14533 = OpLabel + %10715 = OpNot %uint %16620 + %15365 = OpBitwiseAnd %uint %10715 %uint_7 + %17719 = OpIMul %uint %12931 %15365 + %21990 = OpBitwiseAnd %uint %16620 %uint_7 + %20412 = OpIMul %uint %13108 %21990 + %19858 = OpIAdd %uint %17719 %20412 + %13015 = OpUDiv %uint %19858 %uint_7 + %23037 = OpShiftRightLogical %uint %10715 %uint_3 + %8768 = OpBitwiseAnd %uint %23037 %uint_7 + %15056 = OpIMul %uint %12931 %8768 + %13328 = OpShiftRightLogical %uint %16620 %uint_3 + %25002 = OpBitwiseAnd %uint %13328 %uint_7 + %25239 = OpIMul %uint %13108 %25002 + %19925 = OpIAdd %uint %15056 %25239 + %12661 = OpUDiv %uint %19925 %uint_7 + %8190 = OpShiftLeftLogical %uint %12661 %uint_8 + %7583 = OpBitwiseOr %uint %13015 %8190 + %21965 = OpShiftRightLogical %uint %10715 %uint_6 + %17624 = OpBitwiseAnd %uint %21965 %uint_7 + %15057 = OpIMul %uint %12931 %17624 + %13329 = OpShiftRightLogical %uint %16620 %uint_6 + %25003 = OpBitwiseAnd %uint %13329 %uint_7 + %25240 = OpIMul %uint %13108 %25003 + %19926 = OpIAdd %uint %15057 %25240 + %12662 = OpUDiv %uint %19926 %uint_7 + %8191 = OpShiftLeftLogical %uint %12662 %uint_16 + %7584 = OpBitwiseOr %uint %7583 %8191 + %21966 = OpShiftRightLogical %uint %10715 %uint_9 + %17625 = OpBitwiseAnd %uint %21966 %uint_7 + %15058 = OpIMul %uint %12931 %17625 + %13331 = OpShiftRightLogical %uint %16620 %uint_9 + %25004 = OpBitwiseAnd %uint %13331 %uint_7 + %25241 = OpIMul %uint %13108 %25004 + %19927 = OpIAdd %uint %15058 %25241 + %12663 = OpUDiv %uint %19927 %uint_7 + %9212 = OpShiftLeftLogical %uint %12663 %uint_24 + %18047 = OpBitwiseOr %uint %7584 %9212 + OpBranch %11703 + %11703 = OpLabel + %17230 = OpPhi %uint %18438 %10651 %18047 %14533 + %14584 = OpCompositeConstruct %v4uint %20515 %20516 %20517 %17230 + %13109 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13334 + OpStore %13109 %14584 + %14840 = OpIAdd %uint %12832 %int_2 + %11787 = OpULessThan %bool %14840 %6594 + OpSelectionMerge %7205 DontFlatten + OpBranchConditional %11787 %22829 %7205 + %22829 = OpLabel + %13335 = OpIAdd %uint %13334 %6977 + %15656 = OpShiftRightLogical %v4uint %16695 %317 + %23836 = OpCompositeExtract %uint %15656 0 + OpSelectionMerge %11727 None + OpBranchConditional %20099 %10652 %21929 + %10652 = OpLabel + %17669 = OpBitwiseAnd %uint %23836 %uint_4793490 + %23960 = OpBitwiseAnd %uint %23836 %uint_9586980 + %21856 = OpShiftRightLogical %uint %23960 %uint_1 + %8145 = OpBitwiseAnd %uint %17669 %21856 + %24621 = OpShiftLeftLogical %uint %8145 %uint_1 + %22968 = OpShiftRightLogical %uint %8145 %uint_1 + %18798 = OpBitwiseOr %uint %24621 %22968 + %16053 = OpBitwiseOr %uint %8145 %18798 + %18313 = OpBitwiseAnd %uint %23836 %uint_2396745 + %14689 = OpBitwiseOr %uint %18313 %uint_14380470 + %20413 = OpBitwiseAnd %uint %14689 %16053 + %20543 = OpShiftRightLogical %uint %17669 %uint_1 + %24926 = OpBitwiseOr %uint %18313 %20543 + %21928 = OpShiftRightLogical %uint %23960 %uint_2 + %22678 = OpBitwiseOr %uint %24926 %21928 + %7729 = OpBitwiseXor %uint %22678 %uint_2396745 + %9548 = OpNot %uint %20543 + %14629 = OpBitwiseAnd %uint %18313 %9548 + %8433 = OpNot %uint %21928 + %11415 = OpBitwiseAnd %uint %14629 %8433 + %6807 = OpBitwiseOr %uint %23836 %7729 + %19517 = OpISub %uint %6807 %uint_2396745 + %14883 = OpBitwiseOr %uint %19517 %11415 + %18232 = OpShiftLeftLogical %uint %11415 %uint_2 + %15366 = OpBitwiseOr %uint %14883 %18232 + %12158 = OpNot %uint %16053 + %18516 = OpBitwiseAnd %uint %15366 %12158 + %6256 = OpBitwiseOr %uint %18516 %20413 + OpBranch %11727 + %21929 = OpLabel + %20083 = OpBitwiseAnd %uint %23836 %uint_2396745 + %23914 = OpBitwiseAnd %uint %23836 %uint_4793490 + %22251 = OpShiftRightLogical %uint %23914 %uint_1 + %24004 = OpBitwiseOr %uint %20083 %22251 + %19603 = OpBitwiseAnd %uint %23836 %uint_9586980 + %20619 = OpShiftRightLogical %uint %19603 %uint_2 + %24291 = OpBitwiseOr %uint %24004 %20619 + %7730 = OpBitwiseXor %uint %24291 %uint_2396745 + %9549 = OpNot %uint %22251 + %14630 = OpBitwiseAnd %uint %20083 %9549 + %8434 = OpNot %uint %20619 + %11416 = OpBitwiseAnd %uint %14630 %8434 + %6808 = OpBitwiseOr %uint %23836 %7730 + %19518 = OpISub %uint %6808 %uint_2396745 + %14884 = OpBitwiseOr %uint %19518 %11416 + %18156 = OpShiftLeftLogical %uint %11416 %uint_1 + %16012 = OpBitwiseOr %uint %14884 %18156 + %8122 = OpShiftLeftLogical %uint %11416 %uint_2 + %7812 = OpBitwiseOr %uint %16012 %8122 + OpBranch %11727 + %11727 = OpLabel + %20518 = OpPhi %uint %6256 %10652 %7812 %21929 + %16621 = OpCompositeExtract %uint %15656 1 + OpSelectionMerge %11728 None + OpBranchConditional %20100 %10653 %21931 + %10653 = OpLabel + %17670 = OpBitwiseAnd %uint %16621 %uint_4793490 + %23961 = OpBitwiseAnd %uint %16621 %uint_9586980 + %21857 = OpShiftRightLogical %uint %23961 %uint_1 + %8146 = OpBitwiseAnd %uint %17670 %21857 + %24622 = OpShiftLeftLogical %uint %8146 %uint_1 + %22969 = OpShiftRightLogical %uint %8146 %uint_1 + %18799 = OpBitwiseOr %uint %24622 %22969 + %16054 = OpBitwiseOr %uint %8146 %18799 + %18314 = OpBitwiseAnd %uint %16621 %uint_2396745 + %14690 = OpBitwiseOr %uint %18314 %uint_14380470 + %20414 = OpBitwiseAnd %uint %14690 %16054 + %20544 = OpShiftRightLogical %uint %17670 %uint_1 + %24927 = OpBitwiseOr %uint %18314 %20544 + %21930 = OpShiftRightLogical %uint %23961 %uint_2 + %22679 = OpBitwiseOr %uint %24927 %21930 + %7731 = OpBitwiseXor %uint %22679 %uint_2396745 + %9550 = OpNot %uint %20544 + %14631 = OpBitwiseAnd %uint %18314 %9550 + %8435 = OpNot %uint %21930 + %11417 = OpBitwiseAnd %uint %14631 %8435 + %6809 = OpBitwiseOr %uint %16621 %7731 + %19519 = OpISub %uint %6809 %uint_2396745 + %14885 = OpBitwiseOr %uint %19519 %11417 + %18233 = OpShiftLeftLogical %uint %11417 %uint_2 + %15367 = OpBitwiseOr %uint %14885 %18233 + %12159 = OpNot %uint %16054 + %18517 = OpBitwiseAnd %uint %15367 %12159 + %6257 = OpBitwiseOr %uint %18517 %20414 + OpBranch %11728 + %21931 = OpLabel + %20084 = OpBitwiseAnd %uint %16621 %uint_2396745 + %23915 = OpBitwiseAnd %uint %16621 %uint_4793490 + %22252 = OpShiftRightLogical %uint %23915 %uint_1 + %24005 = OpBitwiseOr %uint %20084 %22252 + %19604 = OpBitwiseAnd %uint %16621 %uint_9586980 + %20620 = OpShiftRightLogical %uint %19604 %uint_2 + %24292 = OpBitwiseOr %uint %24005 %20620 + %7732 = OpBitwiseXor %uint %24292 %uint_2396745 + %9551 = OpNot %uint %22252 + %14632 = OpBitwiseAnd %uint %20084 %9551 + %8436 = OpNot %uint %20620 + %11418 = OpBitwiseAnd %uint %14632 %8436 + %6810 = OpBitwiseOr %uint %16621 %7732 + %19520 = OpISub %uint %6810 %uint_2396745 + %14886 = OpBitwiseOr %uint %19520 %11418 + %18157 = OpShiftLeftLogical %uint %11418 %uint_1 + %16013 = OpBitwiseOr %uint %14886 %18157 + %8123 = OpShiftLeftLogical %uint %11418 %uint_2 + %7813 = OpBitwiseOr %uint %16013 %8123 + OpBranch %11728 + %11728 = OpLabel + %20519 = OpPhi %uint %6257 %10653 %7813 %21931 + %16622 = OpCompositeExtract %uint %15656 2 + OpSelectionMerge %11729 None + OpBranchConditional %20101 %10654 %21933 + %10654 = OpLabel + %17671 = OpBitwiseAnd %uint %16622 %uint_4793490 + %23962 = OpBitwiseAnd %uint %16622 %uint_9586980 + %21858 = OpShiftRightLogical %uint %23962 %uint_1 + %8147 = OpBitwiseAnd %uint %17671 %21858 + %24623 = OpShiftLeftLogical %uint %8147 %uint_1 + %22970 = OpShiftRightLogical %uint %8147 %uint_1 + %18800 = OpBitwiseOr %uint %24623 %22970 + %16055 = OpBitwiseOr %uint %8147 %18800 + %18315 = OpBitwiseAnd %uint %16622 %uint_2396745 + %14691 = OpBitwiseOr %uint %18315 %uint_14380470 + %20415 = OpBitwiseAnd %uint %14691 %16055 + %20545 = OpShiftRightLogical %uint %17671 %uint_1 + %24928 = OpBitwiseOr %uint %18315 %20545 + %21932 = OpShiftRightLogical %uint %23962 %uint_2 + %22680 = OpBitwiseOr %uint %24928 %21932 + %7733 = OpBitwiseXor %uint %22680 %uint_2396745 + %9552 = OpNot %uint %20545 + %14633 = OpBitwiseAnd %uint %18315 %9552 + %8437 = OpNot %uint %21932 + %11419 = OpBitwiseAnd %uint %14633 %8437 + %6811 = OpBitwiseOr %uint %16622 %7733 + %19521 = OpISub %uint %6811 %uint_2396745 + %14887 = OpBitwiseOr %uint %19521 %11419 + %18234 = OpShiftLeftLogical %uint %11419 %uint_2 + %15368 = OpBitwiseOr %uint %14887 %18234 + %12160 = OpNot %uint %16055 + %18518 = OpBitwiseAnd %uint %15368 %12160 + %6258 = OpBitwiseOr %uint %18518 %20415 + OpBranch %11729 + %21933 = OpLabel + %20085 = OpBitwiseAnd %uint %16622 %uint_2396745 + %23916 = OpBitwiseAnd %uint %16622 %uint_4793490 + %22253 = OpShiftRightLogical %uint %23916 %uint_1 + %24006 = OpBitwiseOr %uint %20085 %22253 + %19605 = OpBitwiseAnd %uint %16622 %uint_9586980 + %20621 = OpShiftRightLogical %uint %19605 %uint_2 + %24293 = OpBitwiseOr %uint %24006 %20621 + %7734 = OpBitwiseXor %uint %24293 %uint_2396745 + %9553 = OpNot %uint %22253 + %14634 = OpBitwiseAnd %uint %20085 %9553 + %8438 = OpNot %uint %20621 + %11420 = OpBitwiseAnd %uint %14634 %8438 + %6812 = OpBitwiseOr %uint %16622 %7734 + %19522 = OpISub %uint %6812 %uint_2396745 + %14888 = OpBitwiseOr %uint %19522 %11420 + %18158 = OpShiftLeftLogical %uint %11420 %uint_1 + %16014 = OpBitwiseOr %uint %14888 %18158 + %8124 = OpShiftLeftLogical %uint %11420 %uint_2 + %7814 = OpBitwiseOr %uint %16014 %8124 + OpBranch %11729 + %11729 = OpLabel + %20520 = OpPhi %uint %6258 %10654 %7814 %21933 + %16623 = OpCompositeExtract %uint %15656 3 + OpSelectionMerge %11704 None + OpBranchConditional %20102 %10655 %21967 + %10655 = OpLabel + %17672 = OpBitwiseAnd %uint %16623 %uint_4793490 + %23963 = OpBitwiseAnd %uint %16623 %uint_9586980 + %21859 = OpShiftRightLogical %uint %23963 %uint_1 + %8148 = OpBitwiseAnd %uint %17672 %21859 + %24624 = OpShiftLeftLogical %uint %8148 %uint_1 + %22971 = OpShiftRightLogical %uint %8148 %uint_1 + %18801 = OpBitwiseOr %uint %24624 %22971 + %16056 = OpBitwiseOr %uint %8148 %18801 + %18316 = OpBitwiseAnd %uint %16623 %uint_2396745 + %14692 = OpBitwiseOr %uint %18316 %uint_14380470 + %20416 = OpBitwiseAnd %uint %14692 %16056 + %20546 = OpShiftRightLogical %uint %17672 %uint_1 + %24929 = OpBitwiseOr %uint %18316 %20546 + %21934 = OpShiftRightLogical %uint %23963 %uint_2 + %22681 = OpBitwiseOr %uint %24929 %21934 + %7735 = OpBitwiseXor %uint %22681 %uint_2396745 + %9554 = OpNot %uint %20546 + %14635 = OpBitwiseAnd %uint %18316 %9554 + %8439 = OpNot %uint %21934 + %11421 = OpBitwiseAnd %uint %14635 %8439 + %6814 = OpBitwiseOr %uint %16623 %7735 + %19523 = OpISub %uint %6814 %uint_2396745 + %14889 = OpBitwiseOr %uint %19523 %11421 + %18235 = OpShiftLeftLogical %uint %11421 %uint_2 + %15369 = OpBitwiseOr %uint %14889 %18235 + %12161 = OpNot %uint %16056 + %18519 = OpBitwiseAnd %uint %15369 %12161 + %6259 = OpBitwiseOr %uint %18519 %20416 + OpBranch %11704 + %21967 = OpLabel + %20086 = OpBitwiseAnd %uint %16623 %uint_2396745 + %23917 = OpBitwiseAnd %uint %16623 %uint_4793490 + %22254 = OpShiftRightLogical %uint %23917 %uint_1 + %24007 = OpBitwiseOr %uint %20086 %22254 + %19606 = OpBitwiseAnd %uint %16623 %uint_9586980 + %20622 = OpShiftRightLogical %uint %19606 %uint_2 + %24294 = OpBitwiseOr %uint %24007 %20622 + %7736 = OpBitwiseXor %uint %24294 %uint_2396745 + %9555 = OpNot %uint %22254 + %14636 = OpBitwiseAnd %uint %20086 %9555 + %8440 = OpNot %uint %20622 + %11422 = OpBitwiseAnd %uint %14636 %8440 + %6815 = OpBitwiseOr %uint %16623 %7736 + %19524 = OpISub %uint %6815 %uint_2396745 + %14890 = OpBitwiseOr %uint %19524 %11422 + %18159 = OpShiftLeftLogical %uint %11422 %uint_1 + %16015 = OpBitwiseOr %uint %14890 %18159 + %8125 = OpShiftLeftLogical %uint %11422 %uint_2 + %7815 = OpBitwiseOr %uint %16015 %8125 + OpBranch %11704 + %11704 = OpLabel + %20688 = OpPhi %uint %6259 %10655 %7815 %21967 + %24812 = OpCompositeConstruct %v4uint %20518 %20519 %20520 %20688 + OpSelectionMerge %14891 None + OpBranchConditional %20099 %10656 %14534 + %10656 = OpLabel + %17673 = OpBitwiseAnd %uint %20518 %uint_1170 + %23964 = OpBitwiseAnd %uint %20518 %uint_2340 + %21860 = OpShiftRightLogical %uint %23964 %uint_1 + %8149 = OpBitwiseAnd %uint %17673 %21860 + %24625 = OpShiftLeftLogical %uint %8149 %uint_1 + %22972 = OpShiftRightLogical %uint %8149 %uint_1 + %18820 = OpBitwiseOr %uint %24625 %22972 + %15922 = OpBitwiseOr %uint %8149 %18820 + %8467 = OpNot %uint %15922 + %10090 = OpBitwiseAnd %uint %20518 %8467 + %16308 = OpISub %uint %uint_2925 %10090 + %17424 = OpBitwiseAnd %uint %16308 %8467 + %16999 = OpBitwiseAnd %uint %17424 %uint_7 + %13685 = OpIMul %uint %6502 %16999 + %21991 = OpBitwiseAnd %uint %10090 %uint_7 + %20417 = OpIMul %uint %13104 %21991 + %19859 = OpIAdd %uint %13685 %20417 + %13016 = OpUDiv %uint %19859 %uint_5 + %23038 = OpShiftRightLogical %uint %17424 %uint_3 + %8769 = OpBitwiseAnd %uint %23038 %uint_7 + %15059 = OpIMul %uint %6502 %8769 + %13332 = OpShiftRightLogical %uint %10090 %uint_3 + %25005 = OpBitwiseAnd %uint %13332 %uint_7 + %25242 = OpIMul %uint %13104 %25005 + %19928 = OpIAdd %uint %15059 %25242 + %12664 = OpUDiv %uint %19928 %uint_5 + %8192 = OpShiftLeftLogical %uint %12664 %uint_8 + %7585 = OpBitwiseOr %uint %13016 %8192 + %21968 = OpShiftRightLogical %uint %17424 %uint_6 + %17626 = OpBitwiseAnd %uint %21968 %uint_7 + %15060 = OpIMul %uint %6502 %17626 + %13333 = OpShiftRightLogical %uint %10090 %uint_6 + %25006 = OpBitwiseAnd %uint %13333 %uint_7 + %25243 = OpIMul %uint %13104 %25006 + %19929 = OpIAdd %uint %15060 %25243 + %12665 = OpUDiv %uint %19929 %uint_5 + %8193 = OpShiftLeftLogical %uint %12665 %uint_16 + %7586 = OpBitwiseOr %uint %7585 %8193 + %21969 = OpShiftRightLogical %uint %17424 %uint_9 + %17627 = OpBitwiseAnd %uint %21969 %uint_7 + %15061 = OpIMul %uint %6502 %17627 + %13336 = OpShiftRightLogical %uint %10090 %uint_9 + %25007 = OpBitwiseAnd %uint %13336 %uint_7 + %25244 = OpIMul %uint %13104 %25007 + %19930 = OpIAdd %uint %15061 %25244 + %12666 = OpUDiv %uint %19930 %uint_5 + %8264 = OpShiftLeftLogical %uint %12666 %uint_24 + %6696 = OpBitwiseOr %uint %7586 %8264 + %20418 = OpBitwiseAnd %uint %20518 %15922 + %17426 = OpBitwiseAnd %uint %20418 %uint_1 + %19567 = OpBitwiseAnd %uint %20418 %uint_8 + %24940 = OpShiftLeftLogical %uint %19567 %uint_5 + %17101 = OpBitwiseOr %uint %17426 %24940 + %20882 = OpBitwiseAnd %uint %20418 %uint_64 + %23327 = OpShiftLeftLogical %uint %20882 %uint_10 + %17102 = OpBitwiseOr %uint %17101 %23327 + %20883 = OpBitwiseAnd %uint %20418 %uint_512 + %22054 = OpShiftLeftLogical %uint %20883 %uint_15 + %8319 = OpBitwiseOr %uint %17102 %22054 + %10427 = OpIMul %uint %8319 %uint_255 + %18439 = OpIAdd %uint %6696 %10427 + OpBranch %14891 + %14534 = OpLabel + %10716 = OpNot %uint %20518 + %15370 = OpBitwiseAnd %uint %10716 %uint_7 + %17720 = OpIMul %uint %6502 %15370 + %21993 = OpBitwiseAnd %uint %20518 %uint_7 + %20419 = OpIMul %uint %13104 %21993 + %19860 = OpIAdd %uint %17720 %20419 + %13017 = OpUDiv %uint %19860 %uint_7 + %23039 = OpShiftRightLogical %uint %10716 %uint_3 + %8770 = OpBitwiseAnd %uint %23039 %uint_7 + %15062 = OpIMul %uint %6502 %8770 + %13337 = OpShiftRightLogical %uint %20518 %uint_3 + %25008 = OpBitwiseAnd %uint %13337 %uint_7 + %25245 = OpIMul %uint %13104 %25008 + %19931 = OpIAdd %uint %15062 %25245 + %12667 = OpUDiv %uint %19931 %uint_7 + %8194 = OpShiftLeftLogical %uint %12667 %uint_8 + %7587 = OpBitwiseOr %uint %13017 %8194 + %21970 = OpShiftRightLogical %uint %10716 %uint_6 + %17628 = OpBitwiseAnd %uint %21970 %uint_7 + %15063 = OpIMul %uint %6502 %17628 + %13338 = OpShiftRightLogical %uint %20518 %uint_6 + %25009 = OpBitwiseAnd %uint %13338 %uint_7 + %25246 = OpIMul %uint %13104 %25009 + %19932 = OpIAdd %uint %15063 %25246 + %12668 = OpUDiv %uint %19932 %uint_7 + %8195 = OpShiftLeftLogical %uint %12668 %uint_16 + %7588 = OpBitwiseOr %uint %7587 %8195 + %21971 = OpShiftRightLogical %uint %10716 %uint_9 + %17629 = OpBitwiseAnd %uint %21971 %uint_7 + %15064 = OpIMul %uint %6502 %17629 + %13339 = OpShiftRightLogical %uint %20518 %uint_9 + %25010 = OpBitwiseAnd %uint %13339 %uint_7 + %25247 = OpIMul %uint %13104 %25010 + %19933 = OpIAdd %uint %15064 %25247 + %12669 = OpUDiv %uint %19933 %uint_7 + %9213 = OpShiftLeftLogical %uint %12669 %uint_24 + %18048 = OpBitwiseOr %uint %7588 %9213 + OpBranch %14891 + %14891 = OpLabel + %10928 = OpPhi %uint %18439 %10656 %18048 %14534 + OpSelectionMerge %14892 None + OpBranchConditional %20100 %10657 %14535 + %10657 = OpLabel + %17674 = OpBitwiseAnd %uint %20519 %uint_1170 + %23965 = OpBitwiseAnd %uint %20519 %uint_2340 + %21861 = OpShiftRightLogical %uint %23965 %uint_1 + %8150 = OpBitwiseAnd %uint %17674 %21861 + %24626 = OpShiftLeftLogical %uint %8150 %uint_1 + %22973 = OpShiftRightLogical %uint %8150 %uint_1 + %18821 = OpBitwiseOr %uint %24626 %22973 + %15923 = OpBitwiseOr %uint %8150 %18821 + %8468 = OpNot %uint %15923 + %10091 = OpBitwiseAnd %uint %20519 %8468 + %16309 = OpISub %uint %uint_2925 %10091 + %17427 = OpBitwiseAnd %uint %16309 %8468 + %17000 = OpBitwiseAnd %uint %17427 %uint_7 + %13686 = OpIMul %uint %12929 %17000 + %21994 = OpBitwiseAnd %uint %10091 %uint_7 + %20420 = OpIMul %uint %13105 %21994 + %19861 = OpIAdd %uint %13686 %20420 + %13018 = OpUDiv %uint %19861 %uint_5 + %23040 = OpShiftRightLogical %uint %17427 %uint_3 + %8771 = OpBitwiseAnd %uint %23040 %uint_7 + %15065 = OpIMul %uint %12929 %8771 + %13340 = OpShiftRightLogical %uint %10091 %uint_3 + %25011 = OpBitwiseAnd %uint %13340 %uint_7 + %25248 = OpIMul %uint %13105 %25011 + %19934 = OpIAdd %uint %15065 %25248 + %12670 = OpUDiv %uint %19934 %uint_5 + %8196 = OpShiftLeftLogical %uint %12670 %uint_8 + %7589 = OpBitwiseOr %uint %13018 %8196 + %21972 = OpShiftRightLogical %uint %17427 %uint_6 + %17630 = OpBitwiseAnd %uint %21972 %uint_7 + %15066 = OpIMul %uint %12929 %17630 + %13341 = OpShiftRightLogical %uint %10091 %uint_6 + %25012 = OpBitwiseAnd %uint %13341 %uint_7 + %25249 = OpIMul %uint %13105 %25012 + %19935 = OpIAdd %uint %15066 %25249 + %12671 = OpUDiv %uint %19935 %uint_5 + %8197 = OpShiftLeftLogical %uint %12671 %uint_16 + %7590 = OpBitwiseOr %uint %7589 %8197 + %21973 = OpShiftRightLogical %uint %17427 %uint_9 + %17631 = OpBitwiseAnd %uint %21973 %uint_7 + %15067 = OpIMul %uint %12929 %17631 + %13342 = OpShiftRightLogical %uint %10091 %uint_9 + %25013 = OpBitwiseAnd %uint %13342 %uint_7 + %25250 = OpIMul %uint %13105 %25013 + %19936 = OpIAdd %uint %15067 %25250 + %12672 = OpUDiv %uint %19936 %uint_5 + %8265 = OpShiftLeftLogical %uint %12672 %uint_24 + %6697 = OpBitwiseOr %uint %7590 %8265 + %20421 = OpBitwiseAnd %uint %20519 %15923 + %17428 = OpBitwiseAnd %uint %20421 %uint_1 + %19568 = OpBitwiseAnd %uint %20421 %uint_8 + %24941 = OpShiftLeftLogical %uint %19568 %uint_5 + %17103 = OpBitwiseOr %uint %17428 %24941 + %20884 = OpBitwiseAnd %uint %20421 %uint_64 + %23328 = OpShiftLeftLogical %uint %20884 %uint_10 + %17104 = OpBitwiseOr %uint %17103 %23328 + %20885 = OpBitwiseAnd %uint %20421 %uint_512 + %22055 = OpShiftLeftLogical %uint %20885 %uint_15 + %8320 = OpBitwiseOr %uint %17104 %22055 + %10428 = OpIMul %uint %8320 %uint_255 + %18440 = OpIAdd %uint %6697 %10428 + OpBranch %14892 + %14535 = OpLabel + %10717 = OpNot %uint %20519 + %15371 = OpBitwiseAnd %uint %10717 %uint_7 + %17721 = OpIMul %uint %12929 %15371 + %21995 = OpBitwiseAnd %uint %20519 %uint_7 + %20422 = OpIMul %uint %13105 %21995 + %19862 = OpIAdd %uint %17721 %20422 + %13019 = OpUDiv %uint %19862 %uint_7 + %23041 = OpShiftRightLogical %uint %10717 %uint_3 + %8772 = OpBitwiseAnd %uint %23041 %uint_7 + %15068 = OpIMul %uint %12929 %8772 + %13343 = OpShiftRightLogical %uint %20519 %uint_3 + %25014 = OpBitwiseAnd %uint %13343 %uint_7 + %25251 = OpIMul %uint %13105 %25014 + %19937 = OpIAdd %uint %15068 %25251 + %12673 = OpUDiv %uint %19937 %uint_7 + %8198 = OpShiftLeftLogical %uint %12673 %uint_8 + %7591 = OpBitwiseOr %uint %13019 %8198 + %21974 = OpShiftRightLogical %uint %10717 %uint_6 + %17632 = OpBitwiseAnd %uint %21974 %uint_7 + %15069 = OpIMul %uint %12929 %17632 + %13344 = OpShiftRightLogical %uint %20519 %uint_6 + %25015 = OpBitwiseAnd %uint %13344 %uint_7 + %25252 = OpIMul %uint %13105 %25015 + %19938 = OpIAdd %uint %15069 %25252 + %12674 = OpUDiv %uint %19938 %uint_7 + %8199 = OpShiftLeftLogical %uint %12674 %uint_16 + %7592 = OpBitwiseOr %uint %7591 %8199 + %21996 = OpShiftRightLogical %uint %10717 %uint_9 + %17633 = OpBitwiseAnd %uint %21996 %uint_7 + %15070 = OpIMul %uint %12929 %17633 + %13345 = OpShiftRightLogical %uint %20519 %uint_9 + %25016 = OpBitwiseAnd %uint %13345 %uint_7 + %25253 = OpIMul %uint %13105 %25016 + %19939 = OpIAdd %uint %15070 %25253 + %12675 = OpUDiv %uint %19939 %uint_7 + %9214 = OpShiftLeftLogical %uint %12675 %uint_24 + %18049 = OpBitwiseOr %uint %7592 %9214 + OpBranch %14892 + %14892 = OpLabel + %10929 = OpPhi %uint %18440 %10657 %18049 %14535 + OpSelectionMerge %14893 None + OpBranchConditional %20101 %10658 %14536 + %10658 = OpLabel + %17675 = OpBitwiseAnd %uint %20520 %uint_1170 + %23966 = OpBitwiseAnd %uint %20520 %uint_2340 + %21862 = OpShiftRightLogical %uint %23966 %uint_1 + %8151 = OpBitwiseAnd %uint %17675 %21862 + %24627 = OpShiftLeftLogical %uint %8151 %uint_1 + %22974 = OpShiftRightLogical %uint %8151 %uint_1 + %18822 = OpBitwiseOr %uint %24627 %22974 + %15924 = OpBitwiseOr %uint %8151 %18822 + %8469 = OpNot %uint %15924 + %10092 = OpBitwiseAnd %uint %20520 %8469 + %16310 = OpISub %uint %uint_2925 %10092 + %17429 = OpBitwiseAnd %uint %16310 %8469 + %17001 = OpBitwiseAnd %uint %17429 %uint_7 + %13687 = OpIMul %uint %12930 %17001 + %21997 = OpBitwiseAnd %uint %10092 %uint_7 + %20424 = OpIMul %uint %13107 %21997 + %19863 = OpIAdd %uint %13687 %20424 + %13020 = OpUDiv %uint %19863 %uint_5 + %23042 = OpShiftRightLogical %uint %17429 %uint_3 + %8773 = OpBitwiseAnd %uint %23042 %uint_7 + %15071 = OpIMul %uint %12930 %8773 + %13346 = OpShiftRightLogical %uint %10092 %uint_3 + %25017 = OpBitwiseAnd %uint %13346 %uint_7 + %25254 = OpIMul %uint %13107 %25017 + %19940 = OpIAdd %uint %15071 %25254 + %12676 = OpUDiv %uint %19940 %uint_5 + %8200 = OpShiftLeftLogical %uint %12676 %uint_8 + %7593 = OpBitwiseOr %uint %13020 %8200 + %21998 = OpShiftRightLogical %uint %17429 %uint_6 + %17634 = OpBitwiseAnd %uint %21998 %uint_7 + %15072 = OpIMul %uint %12930 %17634 + %13347 = OpShiftRightLogical %uint %10092 %uint_6 + %25018 = OpBitwiseAnd %uint %13347 %uint_7 + %25255 = OpIMul %uint %13107 %25018 + %19941 = OpIAdd %uint %15072 %25255 + %12677 = OpUDiv %uint %19941 %uint_5 + %8201 = OpShiftLeftLogical %uint %12677 %uint_16 + %7594 = OpBitwiseOr %uint %7593 %8201 + %21999 = OpShiftRightLogical %uint %17429 %uint_9 + %17635 = OpBitwiseAnd %uint %21999 %uint_7 + %15073 = OpIMul %uint %12930 %17635 + %13348 = OpShiftRightLogical %uint %10092 %uint_9 + %25019 = OpBitwiseAnd %uint %13348 %uint_7 + %25256 = OpIMul %uint %13107 %25019 + %19942 = OpIAdd %uint %15073 %25256 + %12678 = OpUDiv %uint %19942 %uint_5 + %8266 = OpShiftLeftLogical %uint %12678 %uint_24 + %6698 = OpBitwiseOr %uint %7594 %8266 + %20425 = OpBitwiseAnd %uint %20520 %15924 + %17430 = OpBitwiseAnd %uint %20425 %uint_1 + %19569 = OpBitwiseAnd %uint %20425 %uint_8 + %24942 = OpShiftLeftLogical %uint %19569 %uint_5 + %17105 = OpBitwiseOr %uint %17430 %24942 + %20886 = OpBitwiseAnd %uint %20425 %uint_64 + %23329 = OpShiftLeftLogical %uint %20886 %uint_10 + %17106 = OpBitwiseOr %uint %17105 %23329 + %20887 = OpBitwiseAnd %uint %20425 %uint_512 + %22056 = OpShiftLeftLogical %uint %20887 %uint_15 + %8321 = OpBitwiseOr %uint %17106 %22056 + %10429 = OpIMul %uint %8321 %uint_255 + %18441 = OpIAdd %uint %6698 %10429 + OpBranch %14893 + %14536 = OpLabel + %10718 = OpNot %uint %20520 + %15372 = OpBitwiseAnd %uint %10718 %uint_7 + %17722 = OpIMul %uint %12930 %15372 + %22000 = OpBitwiseAnd %uint %20520 %uint_7 + %20426 = OpIMul %uint %13107 %22000 + %19864 = OpIAdd %uint %17722 %20426 + %13021 = OpUDiv %uint %19864 %uint_7 + %23043 = OpShiftRightLogical %uint %10718 %uint_3 + %8774 = OpBitwiseAnd %uint %23043 %uint_7 + %15074 = OpIMul %uint %12930 %8774 + %13349 = OpShiftRightLogical %uint %20520 %uint_3 + %25020 = OpBitwiseAnd %uint %13349 %uint_7 + %25257 = OpIMul %uint %13107 %25020 + %19943 = OpIAdd %uint %15074 %25257 + %12679 = OpUDiv %uint %19943 %uint_7 + %8202 = OpShiftLeftLogical %uint %12679 %uint_8 + %7595 = OpBitwiseOr %uint %13021 %8202 + %22001 = OpShiftRightLogical %uint %10718 %uint_6 + %17636 = OpBitwiseAnd %uint %22001 %uint_7 + %15075 = OpIMul %uint %12930 %17636 + %13350 = OpShiftRightLogical %uint %20520 %uint_6 + %25021 = OpBitwiseAnd %uint %13350 %uint_7 + %25258 = OpIMul %uint %13107 %25021 + %19944 = OpIAdd %uint %15075 %25258 + %12680 = OpUDiv %uint %19944 %uint_7 + %8203 = OpShiftLeftLogical %uint %12680 %uint_16 + %7596 = OpBitwiseOr %uint %7595 %8203 + %22002 = OpShiftRightLogical %uint %10718 %uint_9 + %17637 = OpBitwiseAnd %uint %22002 %uint_7 + %15076 = OpIMul %uint %12930 %17637 + %13351 = OpShiftRightLogical %uint %20520 %uint_9 + %25022 = OpBitwiseAnd %uint %13351 %uint_7 + %25259 = OpIMul %uint %13107 %25022 + %19945 = OpIAdd %uint %15076 %25259 + %12681 = OpUDiv %uint %19945 %uint_7 + %9215 = OpShiftLeftLogical %uint %12681 %uint_24 + %18050 = OpBitwiseOr %uint %7596 %9215 + OpBranch %14893 + %14893 = OpLabel + %10930 = OpPhi %uint %18441 %10658 %18050 %14536 + OpSelectionMerge %11705 None + OpBranchConditional %20102 %10659 %14537 + %10659 = OpLabel + %17676 = OpBitwiseAnd %uint %20688 %uint_1170 + %23967 = OpBitwiseAnd %uint %20688 %uint_2340 + %21863 = OpShiftRightLogical %uint %23967 %uint_1 + %8152 = OpBitwiseAnd %uint %17676 %21863 + %24628 = OpShiftLeftLogical %uint %8152 %uint_1 + %22975 = OpShiftRightLogical %uint %8152 %uint_1 + %18823 = OpBitwiseOr %uint %24628 %22975 + %15925 = OpBitwiseOr %uint %8152 %18823 + %8470 = OpNot %uint %15925 + %10093 = OpBitwiseAnd %uint %20688 %8470 + %16311 = OpISub %uint %uint_2925 %10093 + %17431 = OpBitwiseAnd %uint %16311 %8470 + %17002 = OpBitwiseAnd %uint %17431 %uint_7 + %13688 = OpIMul %uint %12931 %17002 + %22003 = OpBitwiseAnd %uint %10093 %uint_7 + %20427 = OpIMul %uint %13108 %22003 + %19865 = OpIAdd %uint %13688 %20427 + %13022 = OpUDiv %uint %19865 %uint_5 + %23044 = OpShiftRightLogical %uint %17431 %uint_3 + %8775 = OpBitwiseAnd %uint %23044 %uint_7 + %15077 = OpIMul %uint %12931 %8775 + %13352 = OpShiftRightLogical %uint %10093 %uint_3 + %25023 = OpBitwiseAnd %uint %13352 %uint_7 + %25260 = OpIMul %uint %13108 %25023 + %19946 = OpIAdd %uint %15077 %25260 + %12682 = OpUDiv %uint %19946 %uint_5 + %8204 = OpShiftLeftLogical %uint %12682 %uint_8 + %7597 = OpBitwiseOr %uint %13022 %8204 + %22004 = OpShiftRightLogical %uint %17431 %uint_6 + %17638 = OpBitwiseAnd %uint %22004 %uint_7 + %15078 = OpIMul %uint %12931 %17638 + %13353 = OpShiftRightLogical %uint %10093 %uint_6 + %25024 = OpBitwiseAnd %uint %13353 %uint_7 + %25261 = OpIMul %uint %13108 %25024 + %19947 = OpIAdd %uint %15078 %25261 + %12683 = OpUDiv %uint %19947 %uint_5 + %8205 = OpShiftLeftLogical %uint %12683 %uint_16 + %7598 = OpBitwiseOr %uint %7597 %8205 + %22005 = OpShiftRightLogical %uint %17431 %uint_9 + %17639 = OpBitwiseAnd %uint %22005 %uint_7 + %15079 = OpIMul %uint %12931 %17639 + %13354 = OpShiftRightLogical %uint %10093 %uint_9 + %25025 = OpBitwiseAnd %uint %13354 %uint_7 + %25262 = OpIMul %uint %13108 %25025 + %19948 = OpIAdd %uint %15079 %25262 + %12684 = OpUDiv %uint %19948 %uint_5 + %8267 = OpShiftLeftLogical %uint %12684 %uint_24 + %6699 = OpBitwiseOr %uint %7598 %8267 + %20428 = OpBitwiseAnd %uint %20688 %15925 + %17432 = OpBitwiseAnd %uint %20428 %uint_1 + %19570 = OpBitwiseAnd %uint %20428 %uint_8 + %24943 = OpShiftLeftLogical %uint %19570 %uint_5 + %17107 = OpBitwiseOr %uint %17432 %24943 + %20888 = OpBitwiseAnd %uint %20428 %uint_64 + %23330 = OpShiftLeftLogical %uint %20888 %uint_10 + %17108 = OpBitwiseOr %uint %17107 %23330 + %20889 = OpBitwiseAnd %uint %20428 %uint_512 + %22057 = OpShiftLeftLogical %uint %20889 %uint_15 + %8322 = OpBitwiseOr %uint %17108 %22057 + %10430 = OpIMul %uint %8322 %uint_255 + %18442 = OpIAdd %uint %6699 %10430 + OpBranch %11705 + %14537 = OpLabel + %10719 = OpNot %uint %20688 + %15373 = OpBitwiseAnd %uint %10719 %uint_7 + %17723 = OpIMul %uint %12931 %15373 + %22006 = OpBitwiseAnd %uint %20688 %uint_7 + %20429 = OpIMul %uint %13108 %22006 + %19866 = OpIAdd %uint %17723 %20429 + %13023 = OpUDiv %uint %19866 %uint_7 + %23045 = OpShiftRightLogical %uint %10719 %uint_3 + %8776 = OpBitwiseAnd %uint %23045 %uint_7 + %15080 = OpIMul %uint %12931 %8776 + %13355 = OpShiftRightLogical %uint %20688 %uint_3 + %25026 = OpBitwiseAnd %uint %13355 %uint_7 + %25263 = OpIMul %uint %13108 %25026 + %19949 = OpIAdd %uint %15080 %25263 + %12685 = OpUDiv %uint %19949 %uint_7 + %8206 = OpShiftLeftLogical %uint %12685 %uint_8 + %7599 = OpBitwiseOr %uint %13023 %8206 + %22007 = OpShiftRightLogical %uint %10719 %uint_6 + %17640 = OpBitwiseAnd %uint %22007 %uint_7 + %15081 = OpIMul %uint %12931 %17640 + %13356 = OpShiftRightLogical %uint %20688 %uint_6 + %25027 = OpBitwiseAnd %uint %13356 %uint_7 + %25264 = OpIMul %uint %13108 %25027 + %19950 = OpIAdd %uint %15081 %25264 + %12686 = OpUDiv %uint %19950 %uint_7 + %8207 = OpShiftLeftLogical %uint %12686 %uint_16 + %7600 = OpBitwiseOr %uint %7599 %8207 + %22008 = OpShiftRightLogical %uint %10719 %uint_9 + %17641 = OpBitwiseAnd %uint %22008 %uint_7 + %15082 = OpIMul %uint %12931 %17641 + %13357 = OpShiftRightLogical %uint %20688 %uint_9 + %25028 = OpBitwiseAnd %uint %13357 %uint_7 + %25265 = OpIMul %uint %13108 %25028 + %19951 = OpIAdd %uint %15082 %25265 + %12687 = OpUDiv %uint %19951 %uint_7 + %9216 = OpShiftLeftLogical %uint %12687 %uint_24 + %18051 = OpBitwiseOr %uint %7600 %9216 + OpBranch %11705 + %11705 = OpLabel + %17231 = OpPhi %uint %18442 %10659 %18051 %14537 + %14585 = OpCompositeConstruct %v4uint %10928 %10929 %10930 %17231 + %13110 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13335 + OpStore %13110 %14585 + %14841 = OpIAdd %uint %12832 %int_3 + %11788 = OpULessThan %bool %14841 %6594 + OpSelectionMerge %18021 DontFlatten + OpBranchConditional %11788 %22830 %18021 + %22830 = OpLabel + %13358 = OpIAdd %uint %13335 %6977 + %15657 = OpShiftRightLogical %v4uint %24812 %533 + %23837 = OpCompositeExtract %uint %15657 0 + OpSelectionMerge %11730 None + OpBranchConditional %20099 %10660 %14538 + %10660 = OpLabel + %17677 = OpBitwiseAnd %uint %23837 %uint_1170 + %23968 = OpBitwiseAnd %uint %23837 %uint_2340 + %21864 = OpShiftRightLogical %uint %23968 %uint_1 + %8153 = OpBitwiseAnd %uint %17677 %21864 + %24629 = OpShiftLeftLogical %uint %8153 %uint_1 + %22976 = OpShiftRightLogical %uint %8153 %uint_1 + %18824 = OpBitwiseOr %uint %24629 %22976 + %15926 = OpBitwiseOr %uint %8153 %18824 + %8471 = OpNot %uint %15926 + %10094 = OpBitwiseAnd %uint %23837 %8471 + %16312 = OpISub %uint %uint_2925 %10094 + %17433 = OpBitwiseAnd %uint %16312 %8471 + %17003 = OpBitwiseAnd %uint %17433 %uint_7 + %13689 = OpIMul %uint %6502 %17003 + %22009 = OpBitwiseAnd %uint %10094 %uint_7 + %20430 = OpIMul %uint %13104 %22009 + %19867 = OpIAdd %uint %13689 %20430 + %13024 = OpUDiv %uint %19867 %uint_5 + %23046 = OpShiftRightLogical %uint %17433 %uint_3 + %8777 = OpBitwiseAnd %uint %23046 %uint_7 + %15083 = OpIMul %uint %6502 %8777 + %13359 = OpShiftRightLogical %uint %10094 %uint_3 + %25029 = OpBitwiseAnd %uint %13359 %uint_7 + %25266 = OpIMul %uint %13104 %25029 + %19952 = OpIAdd %uint %15083 %25266 + %12688 = OpUDiv %uint %19952 %uint_5 + %8208 = OpShiftLeftLogical %uint %12688 %uint_8 + %7601 = OpBitwiseOr %uint %13024 %8208 + %22010 = OpShiftRightLogical %uint %17433 %uint_6 + %17642 = OpBitwiseAnd %uint %22010 %uint_7 + %15084 = OpIMul %uint %6502 %17642 + %13360 = OpShiftRightLogical %uint %10094 %uint_6 + %25030 = OpBitwiseAnd %uint %13360 %uint_7 + %25267 = OpIMul %uint %13104 %25030 + %19953 = OpIAdd %uint %15084 %25267 + %12689 = OpUDiv %uint %19953 %uint_5 + %8209 = OpShiftLeftLogical %uint %12689 %uint_16 + %7602 = OpBitwiseOr %uint %7601 %8209 + %22011 = OpShiftRightLogical %uint %17433 %uint_9 + %17643 = OpBitwiseAnd %uint %22011 %uint_7 + %15085 = OpIMul %uint %6502 %17643 + %13361 = OpShiftRightLogical %uint %10094 %uint_9 + %25031 = OpBitwiseAnd %uint %13361 %uint_7 + %25268 = OpIMul %uint %13104 %25031 + %19954 = OpIAdd %uint %15085 %25268 + %12690 = OpUDiv %uint %19954 %uint_5 + %8268 = OpShiftLeftLogical %uint %12690 %uint_24 + %6700 = OpBitwiseOr %uint %7602 %8268 + %20431 = OpBitwiseAnd %uint %23837 %15926 + %17434 = OpBitwiseAnd %uint %20431 %uint_1 + %19571 = OpBitwiseAnd %uint %20431 %uint_8 + %24944 = OpShiftLeftLogical %uint %19571 %uint_5 + %17109 = OpBitwiseOr %uint %17434 %24944 + %20890 = OpBitwiseAnd %uint %20431 %uint_64 + %23331 = OpShiftLeftLogical %uint %20890 %uint_10 + %17110 = OpBitwiseOr %uint %17109 %23331 + %20891 = OpBitwiseAnd %uint %20431 %uint_512 + %22058 = OpShiftLeftLogical %uint %20891 %uint_15 + %8323 = OpBitwiseOr %uint %17110 %22058 + %10431 = OpIMul %uint %8323 %uint_255 + %18443 = OpIAdd %uint %6700 %10431 + OpBranch %11730 + %14538 = OpLabel + %10720 = OpNot %uint %23837 + %15374 = OpBitwiseAnd %uint %10720 %uint_7 + %17724 = OpIMul %uint %6502 %15374 + %22012 = OpBitwiseAnd %uint %23837 %uint_7 + %20432 = OpIMul %uint %13104 %22012 + %19868 = OpIAdd %uint %17724 %20432 + %13025 = OpUDiv %uint %19868 %uint_7 + %23047 = OpShiftRightLogical %uint %10720 %uint_3 + %8778 = OpBitwiseAnd %uint %23047 %uint_7 + %15086 = OpIMul %uint %6502 %8778 + %13362 = OpShiftRightLogical %uint %23837 %uint_3 + %25032 = OpBitwiseAnd %uint %13362 %uint_7 + %25269 = OpIMul %uint %13104 %25032 + %19955 = OpIAdd %uint %15086 %25269 + %12691 = OpUDiv %uint %19955 %uint_7 + %8210 = OpShiftLeftLogical %uint %12691 %uint_8 + %7603 = OpBitwiseOr %uint %13025 %8210 + %22013 = OpShiftRightLogical %uint %10720 %uint_6 + %17644 = OpBitwiseAnd %uint %22013 %uint_7 + %15087 = OpIMul %uint %6502 %17644 + %13363 = OpShiftRightLogical %uint %23837 %uint_6 + %25033 = OpBitwiseAnd %uint %13363 %uint_7 + %25270 = OpIMul %uint %13104 %25033 + %19956 = OpIAdd %uint %15087 %25270 + %12692 = OpUDiv %uint %19956 %uint_7 + %8211 = OpShiftLeftLogical %uint %12692 %uint_16 + %7604 = OpBitwiseOr %uint %7603 %8211 + %22014 = OpShiftRightLogical %uint %10720 %uint_9 + %17645 = OpBitwiseAnd %uint %22014 %uint_7 + %15088 = OpIMul %uint %6502 %17645 + %13364 = OpShiftRightLogical %uint %23837 %uint_9 + %25034 = OpBitwiseAnd %uint %13364 %uint_7 + %25271 = OpIMul %uint %13104 %25034 + %19957 = OpIAdd %uint %15088 %25271 + %12693 = OpUDiv %uint %19957 %uint_7 + %9217 = OpShiftLeftLogical %uint %12693 %uint_24 + %18052 = OpBitwiseOr %uint %7604 %9217 + OpBranch %11730 + %11730 = OpLabel + %20521 = OpPhi %uint %18443 %10660 %18052 %14538 + %16624 = OpCompositeExtract %uint %15657 1 + OpSelectionMerge %11731 None + OpBranchConditional %20100 %10661 %14539 + %10661 = OpLabel + %17678 = OpBitwiseAnd %uint %16624 %uint_1170 + %23969 = OpBitwiseAnd %uint %16624 %uint_2340 + %21865 = OpShiftRightLogical %uint %23969 %uint_1 + %8154 = OpBitwiseAnd %uint %17678 %21865 + %24630 = OpShiftLeftLogical %uint %8154 %uint_1 + %22977 = OpShiftRightLogical %uint %8154 %uint_1 + %18825 = OpBitwiseOr %uint %24630 %22977 + %15927 = OpBitwiseOr %uint %8154 %18825 + %8472 = OpNot %uint %15927 + %10095 = OpBitwiseAnd %uint %16624 %8472 + %16313 = OpISub %uint %uint_2925 %10095 + %17435 = OpBitwiseAnd %uint %16313 %8472 + %17004 = OpBitwiseAnd %uint %17435 %uint_7 + %13690 = OpIMul %uint %12929 %17004 + %22015 = OpBitwiseAnd %uint %10095 %uint_7 + %20433 = OpIMul %uint %13105 %22015 + %19869 = OpIAdd %uint %13690 %20433 + %13026 = OpUDiv %uint %19869 %uint_5 + %23048 = OpShiftRightLogical %uint %17435 %uint_3 + %8779 = OpBitwiseAnd %uint %23048 %uint_7 + %15089 = OpIMul %uint %12929 %8779 + %13365 = OpShiftRightLogical %uint %10095 %uint_3 + %25035 = OpBitwiseAnd %uint %13365 %uint_7 + %25272 = OpIMul %uint %13105 %25035 + %19958 = OpIAdd %uint %15089 %25272 + %12694 = OpUDiv %uint %19958 %uint_5 + %8212 = OpShiftLeftLogical %uint %12694 %uint_8 + %7605 = OpBitwiseOr %uint %13026 %8212 + %22016 = OpShiftRightLogical %uint %17435 %uint_6 + %17646 = OpBitwiseAnd %uint %22016 %uint_7 + %15090 = OpIMul %uint %12929 %17646 + %13366 = OpShiftRightLogical %uint %10095 %uint_6 + %25036 = OpBitwiseAnd %uint %13366 %uint_7 + %25273 = OpIMul %uint %13105 %25036 + %19959 = OpIAdd %uint %15090 %25273 + %12695 = OpUDiv %uint %19959 %uint_5 + %8213 = OpShiftLeftLogical %uint %12695 %uint_16 + %7606 = OpBitwiseOr %uint %7605 %8213 + %22017 = OpShiftRightLogical %uint %17435 %uint_9 + %17647 = OpBitwiseAnd %uint %22017 %uint_7 + %15091 = OpIMul %uint %12929 %17647 + %13367 = OpShiftRightLogical %uint %10095 %uint_9 + %25037 = OpBitwiseAnd %uint %13367 %uint_7 + %25274 = OpIMul %uint %13105 %25037 + %19960 = OpIAdd %uint %15091 %25274 + %12696 = OpUDiv %uint %19960 %uint_5 + %8269 = OpShiftLeftLogical %uint %12696 %uint_24 + %6701 = OpBitwiseOr %uint %7606 %8269 + %20434 = OpBitwiseAnd %uint %16624 %15927 + %17436 = OpBitwiseAnd %uint %20434 %uint_1 + %19572 = OpBitwiseAnd %uint %20434 %uint_8 + %24945 = OpShiftLeftLogical %uint %19572 %uint_5 + %17111 = OpBitwiseOr %uint %17436 %24945 + %20892 = OpBitwiseAnd %uint %20434 %uint_64 + %23332 = OpShiftLeftLogical %uint %20892 %uint_10 + %17112 = OpBitwiseOr %uint %17111 %23332 + %20893 = OpBitwiseAnd %uint %20434 %uint_512 + %22059 = OpShiftLeftLogical %uint %20893 %uint_15 + %8324 = OpBitwiseOr %uint %17112 %22059 + %10432 = OpIMul %uint %8324 %uint_255 + %18444 = OpIAdd %uint %6701 %10432 + OpBranch %11731 + %14539 = OpLabel + %10721 = OpNot %uint %16624 + %15376 = OpBitwiseAnd %uint %10721 %uint_7 + %17725 = OpIMul %uint %12929 %15376 + %22018 = OpBitwiseAnd %uint %16624 %uint_7 + %20435 = OpIMul %uint %13105 %22018 + %19870 = OpIAdd %uint %17725 %20435 + %13027 = OpUDiv %uint %19870 %uint_7 + %23049 = OpShiftRightLogical %uint %10721 %uint_3 + %8780 = OpBitwiseAnd %uint %23049 %uint_7 + %15092 = OpIMul %uint %12929 %8780 + %13368 = OpShiftRightLogical %uint %16624 %uint_3 + %25038 = OpBitwiseAnd %uint %13368 %uint_7 + %25275 = OpIMul %uint %13105 %25038 + %19961 = OpIAdd %uint %15092 %25275 + %12697 = OpUDiv %uint %19961 %uint_7 + %8214 = OpShiftLeftLogical %uint %12697 %uint_8 + %7607 = OpBitwiseOr %uint %13027 %8214 + %22019 = OpShiftRightLogical %uint %10721 %uint_6 + %17648 = OpBitwiseAnd %uint %22019 %uint_7 + %15093 = OpIMul %uint %12929 %17648 + %13369 = OpShiftRightLogical %uint %16624 %uint_6 + %25039 = OpBitwiseAnd %uint %13369 %uint_7 + %25276 = OpIMul %uint %13105 %25039 + %19962 = OpIAdd %uint %15093 %25276 + %12698 = OpUDiv %uint %19962 %uint_7 + %8215 = OpShiftLeftLogical %uint %12698 %uint_16 + %7608 = OpBitwiseOr %uint %7607 %8215 + %22020 = OpShiftRightLogical %uint %10721 %uint_9 + %17649 = OpBitwiseAnd %uint %22020 %uint_7 + %15094 = OpIMul %uint %12929 %17649 + %13370 = OpShiftRightLogical %uint %16624 %uint_9 + %25040 = OpBitwiseAnd %uint %13370 %uint_7 + %25277 = OpIMul %uint %13105 %25040 + %19963 = OpIAdd %uint %15094 %25277 + %12699 = OpUDiv %uint %19963 %uint_7 + %9218 = OpShiftLeftLogical %uint %12699 %uint_24 + %18053 = OpBitwiseOr %uint %7608 %9218 + OpBranch %11731 + %11731 = OpLabel + %20522 = OpPhi %uint %18444 %10661 %18053 %14539 + %16625 = OpCompositeExtract %uint %15657 2 + OpSelectionMerge %11732 None + OpBranchConditional %20101 %10662 %14540 + %10662 = OpLabel + %17679 = OpBitwiseAnd %uint %16625 %uint_1170 + %23970 = OpBitwiseAnd %uint %16625 %uint_2340 + %21866 = OpShiftRightLogical %uint %23970 %uint_1 + %8155 = OpBitwiseAnd %uint %17679 %21866 + %24631 = OpShiftLeftLogical %uint %8155 %uint_1 + %22978 = OpShiftRightLogical %uint %8155 %uint_1 + %18826 = OpBitwiseOr %uint %24631 %22978 + %15928 = OpBitwiseOr %uint %8155 %18826 + %8473 = OpNot %uint %15928 + %10096 = OpBitwiseAnd %uint %16625 %8473 + %16314 = OpISub %uint %uint_2925 %10096 + %17437 = OpBitwiseAnd %uint %16314 %8473 + %17005 = OpBitwiseAnd %uint %17437 %uint_7 + %13691 = OpIMul %uint %12930 %17005 + %22021 = OpBitwiseAnd %uint %10096 %uint_7 + %20436 = OpIMul %uint %13107 %22021 + %19871 = OpIAdd %uint %13691 %20436 + %13028 = OpUDiv %uint %19871 %uint_5 + %23050 = OpShiftRightLogical %uint %17437 %uint_3 + %8781 = OpBitwiseAnd %uint %23050 %uint_7 + %15095 = OpIMul %uint %12930 %8781 + %13371 = OpShiftRightLogical %uint %10096 %uint_3 + %25041 = OpBitwiseAnd %uint %13371 %uint_7 + %25278 = OpIMul %uint %13107 %25041 + %19964 = OpIAdd %uint %15095 %25278 + %12700 = OpUDiv %uint %19964 %uint_5 + %8216 = OpShiftLeftLogical %uint %12700 %uint_8 + %7609 = OpBitwiseOr %uint %13028 %8216 + %22022 = OpShiftRightLogical %uint %17437 %uint_6 + %17650 = OpBitwiseAnd %uint %22022 %uint_7 + %15096 = OpIMul %uint %12930 %17650 + %13372 = OpShiftRightLogical %uint %10096 %uint_6 + %25042 = OpBitwiseAnd %uint %13372 %uint_7 + %25279 = OpIMul %uint %13107 %25042 + %19965 = OpIAdd %uint %15096 %25279 + %12701 = OpUDiv %uint %19965 %uint_5 + %8217 = OpShiftLeftLogical %uint %12701 %uint_16 + %7610 = OpBitwiseOr %uint %7609 %8217 + %22023 = OpShiftRightLogical %uint %17437 %uint_9 + %17651 = OpBitwiseAnd %uint %22023 %uint_7 + %15097 = OpIMul %uint %12930 %17651 + %13373 = OpShiftRightLogical %uint %10096 %uint_9 + %25043 = OpBitwiseAnd %uint %13373 %uint_7 + %25280 = OpIMul %uint %13107 %25043 + %19966 = OpIAdd %uint %15097 %25280 + %12702 = OpUDiv %uint %19966 %uint_5 + %8270 = OpShiftLeftLogical %uint %12702 %uint_24 + %6702 = OpBitwiseOr %uint %7610 %8270 + %20437 = OpBitwiseAnd %uint %16625 %15928 + %17438 = OpBitwiseAnd %uint %20437 %uint_1 + %19573 = OpBitwiseAnd %uint %20437 %uint_8 + %24946 = OpShiftLeftLogical %uint %19573 %uint_5 + %17113 = OpBitwiseOr %uint %17438 %24946 + %20894 = OpBitwiseAnd %uint %20437 %uint_64 + %23333 = OpShiftLeftLogical %uint %20894 %uint_10 + %17114 = OpBitwiseOr %uint %17113 %23333 + %20895 = OpBitwiseAnd %uint %20437 %uint_512 + %22060 = OpShiftLeftLogical %uint %20895 %uint_15 + %8325 = OpBitwiseOr %uint %17114 %22060 + %10433 = OpIMul %uint %8325 %uint_255 + %18445 = OpIAdd %uint %6702 %10433 + OpBranch %11732 + %14540 = OpLabel + %10722 = OpNot %uint %16625 + %15377 = OpBitwiseAnd %uint %10722 %uint_7 + %17726 = OpIMul %uint %12930 %15377 + %22024 = OpBitwiseAnd %uint %16625 %uint_7 + %20439 = OpIMul %uint %13107 %22024 + %19872 = OpIAdd %uint %17726 %20439 + %13029 = OpUDiv %uint %19872 %uint_7 + %23051 = OpShiftRightLogical %uint %10722 %uint_3 + %8782 = OpBitwiseAnd %uint %23051 %uint_7 + %15098 = OpIMul %uint %12930 %8782 + %13374 = OpShiftRightLogical %uint %16625 %uint_3 + %25044 = OpBitwiseAnd %uint %13374 %uint_7 + %25281 = OpIMul %uint %13107 %25044 + %19967 = OpIAdd %uint %15098 %25281 + %12703 = OpUDiv %uint %19967 %uint_7 + %8218 = OpShiftLeftLogical %uint %12703 %uint_8 + %7611 = OpBitwiseOr %uint %13029 %8218 + %22025 = OpShiftRightLogical %uint %10722 %uint_6 + %17652 = OpBitwiseAnd %uint %22025 %uint_7 + %15099 = OpIMul %uint %12930 %17652 + %13375 = OpShiftRightLogical %uint %16625 %uint_6 + %25045 = OpBitwiseAnd %uint %13375 %uint_7 + %25282 = OpIMul %uint %13107 %25045 + %19968 = OpIAdd %uint %15099 %25282 + %12704 = OpUDiv %uint %19968 %uint_7 + %8219 = OpShiftLeftLogical %uint %12704 %uint_16 + %7612 = OpBitwiseOr %uint %7611 %8219 + %22026 = OpShiftRightLogical %uint %10722 %uint_9 + %17653 = OpBitwiseAnd %uint %22026 %uint_7 + %15100 = OpIMul %uint %12930 %17653 + %13376 = OpShiftRightLogical %uint %16625 %uint_9 + %25046 = OpBitwiseAnd %uint %13376 %uint_7 + %25283 = OpIMul %uint %13107 %25046 + %19969 = OpIAdd %uint %15100 %25283 + %12705 = OpUDiv %uint %19969 %uint_7 + %9219 = OpShiftLeftLogical %uint %12705 %uint_24 + %18054 = OpBitwiseOr %uint %7612 %9219 + OpBranch %11732 + %11732 = OpLabel + %20523 = OpPhi %uint %18445 %10662 %18054 %14540 + %16626 = OpCompositeExtract %uint %15657 3 + OpSelectionMerge %11706 None + OpBranchConditional %20102 %10663 %14541 + %10663 = OpLabel + %17680 = OpBitwiseAnd %uint %16626 %uint_1170 + %23971 = OpBitwiseAnd %uint %16626 %uint_2340 + %21867 = OpShiftRightLogical %uint %23971 %uint_1 + %8156 = OpBitwiseAnd %uint %17680 %21867 + %24632 = OpShiftLeftLogical %uint %8156 %uint_1 + %22979 = OpShiftRightLogical %uint %8156 %uint_1 + %18827 = OpBitwiseOr %uint %24632 %22979 + %15929 = OpBitwiseOr %uint %8156 %18827 + %8474 = OpNot %uint %15929 + %10097 = OpBitwiseAnd %uint %16626 %8474 + %16315 = OpISub %uint %uint_2925 %10097 + %17439 = OpBitwiseAnd %uint %16315 %8474 + %17006 = OpBitwiseAnd %uint %17439 %uint_7 + %13692 = OpIMul %uint %12931 %17006 + %22027 = OpBitwiseAnd %uint %10097 %uint_7 + %20440 = OpIMul %uint %13108 %22027 + %19873 = OpIAdd %uint %13692 %20440 + %13030 = OpUDiv %uint %19873 %uint_5 + %23053 = OpShiftRightLogical %uint %17439 %uint_3 + %8783 = OpBitwiseAnd %uint %23053 %uint_7 + %15101 = OpIMul %uint %12931 %8783 + %13377 = OpShiftRightLogical %uint %10097 %uint_3 + %25047 = OpBitwiseAnd %uint %13377 %uint_7 + %25284 = OpIMul %uint %13108 %25047 + %19970 = OpIAdd %uint %15101 %25284 + %12706 = OpUDiv %uint %19970 %uint_5 + %8220 = OpShiftLeftLogical %uint %12706 %uint_8 + %7613 = OpBitwiseOr %uint %13030 %8220 + %22028 = OpShiftRightLogical %uint %17439 %uint_6 + %17654 = OpBitwiseAnd %uint %22028 %uint_7 + %15102 = OpIMul %uint %12931 %17654 + %13378 = OpShiftRightLogical %uint %10097 %uint_6 + %25048 = OpBitwiseAnd %uint %13378 %uint_7 + %25285 = OpIMul %uint %13108 %25048 + %19971 = OpIAdd %uint %15102 %25285 + %12707 = OpUDiv %uint %19971 %uint_5 + %8221 = OpShiftLeftLogical %uint %12707 %uint_16 + %7614 = OpBitwiseOr %uint %7613 %8221 + %22029 = OpShiftRightLogical %uint %17439 %uint_9 + %17655 = OpBitwiseAnd %uint %22029 %uint_7 + %15103 = OpIMul %uint %12931 %17655 + %13379 = OpShiftRightLogical %uint %10097 %uint_9 + %25049 = OpBitwiseAnd %uint %13379 %uint_7 + %25286 = OpIMul %uint %13108 %25049 + %19972 = OpIAdd %uint %15103 %25286 + %12708 = OpUDiv %uint %19972 %uint_5 + %8271 = OpShiftLeftLogical %uint %12708 %uint_24 + %6703 = OpBitwiseOr %uint %7614 %8271 + %20441 = OpBitwiseAnd %uint %16626 %15929 + %17440 = OpBitwiseAnd %uint %20441 %uint_1 + %19574 = OpBitwiseAnd %uint %20441 %uint_8 + %24947 = OpShiftLeftLogical %uint %19574 %uint_5 + %17115 = OpBitwiseOr %uint %17440 %24947 + %20896 = OpBitwiseAnd %uint %20441 %uint_64 + %23334 = OpShiftLeftLogical %uint %20896 %uint_10 + %17116 = OpBitwiseOr %uint %17115 %23334 + %20897 = OpBitwiseAnd %uint %20441 %uint_512 + %22061 = OpShiftLeftLogical %uint %20897 %uint_15 + %8326 = OpBitwiseOr %uint %17116 %22061 + %10434 = OpIMul %uint %8326 %uint_255 + %18446 = OpIAdd %uint %6703 %10434 + OpBranch %11706 + %14541 = OpLabel + %10723 = OpNot %uint %16626 + %15378 = OpBitwiseAnd %uint %10723 %uint_7 + %17727 = OpIMul %uint %12931 %15378 + %22030 = OpBitwiseAnd %uint %16626 %uint_7 + %20442 = OpIMul %uint %13108 %22030 + %19874 = OpIAdd %uint %17727 %20442 + %13031 = OpUDiv %uint %19874 %uint_7 + %23057 = OpShiftRightLogical %uint %10723 %uint_3 + %8784 = OpBitwiseAnd %uint %23057 %uint_7 + %15104 = OpIMul %uint %12931 %8784 + %13380 = OpShiftRightLogical %uint %16626 %uint_3 + %25050 = OpBitwiseAnd %uint %13380 %uint_7 + %25287 = OpIMul %uint %13108 %25050 + %19973 = OpIAdd %uint %15104 %25287 + %12709 = OpUDiv %uint %19973 %uint_7 + %8222 = OpShiftLeftLogical %uint %12709 %uint_8 + %7615 = OpBitwiseOr %uint %13031 %8222 + %22031 = OpShiftRightLogical %uint %10723 %uint_6 + %17656 = OpBitwiseAnd %uint %22031 %uint_7 + %15105 = OpIMul %uint %12931 %17656 + %13381 = OpShiftRightLogical %uint %16626 %uint_6 + %25051 = OpBitwiseAnd %uint %13381 %uint_7 + %25288 = OpIMul %uint %13108 %25051 + %19974 = OpIAdd %uint %15105 %25288 + %12710 = OpUDiv %uint %19974 %uint_7 + %8223 = OpShiftLeftLogical %uint %12710 %uint_16 + %7616 = OpBitwiseOr %uint %7615 %8223 + %22032 = OpShiftRightLogical %uint %10723 %uint_9 + %17681 = OpBitwiseAnd %uint %22032 %uint_7 + %15106 = OpIMul %uint %12931 %17681 + %13382 = OpShiftRightLogical %uint %16626 %uint_9 + %25052 = OpBitwiseAnd %uint %13382 %uint_7 + %25289 = OpIMul %uint %13108 %25052 + %19975 = OpIAdd %uint %15106 %25289 + %12711 = OpUDiv %uint %19975 %uint_7 + %9220 = OpShiftLeftLogical %uint %12711 %uint_24 + %18055 = OpBitwiseOr %uint %7616 %9220 + OpBranch %11706 + %11706 = OpLabel + %17232 = OpPhi %uint %18446 %10663 %18055 %14541 + %14586 = OpCompositeConstruct %v4uint %20521 %20522 %20523 %17232 + %15405 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %13358 + OpStore %15405 %14586 + OpBranch %18021 + %18021 = OpLabel + OpBranch %7205 + %7205 = OpLabel + OpBranch %7206 + %7206 = OpLabel + OpBranch %14903 + %14903 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_dxt5a_r8_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000062CA, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x000009E9, 0x00249249, 0x0004002B, 0x0000000B, 0x000009C8, 0x00492492, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000986, 0x00924924, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000944, 0x00DB6DB6, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, + 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, + 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0004002B, 0x0000000B, 0x00000A52, 0x00000018, + 0x0004002B, 0x0000000B, 0x0000003A, 0x00000492, 0x0004002B, 0x0000000B, 0x0000022D, 0x00000924, + 0x0004002B, 0x0000000B, 0x00000908, 0x00000B6D, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000ACA, 0x00000040, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, + 0x0004002B, 0x0000000B, 0x00000447, 0x00000200, 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, + 0x0004002B, 0x0000000B, 0x00000144, 0x000000FF, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, + 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x00040020, 0x00000291, + 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, + 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A24, 0x00000A10, 0x00000A0A, 0x00000A0A, + 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0006002C, 0x00000014, 0x00000A3C, 0x00000A10, + 0x00000A10, 0x00000A0A, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, + 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, + 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0007002C, 0x00000017, 0x0000007D, 0x00000A0A, + 0x00000A22, 0x00000A0A, 0x00000A22, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, + 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, + 0x00000002, 0x0004002B, 0x0000000B, 0x00000A2E, 0x0000000C, 0x0004002B, 0x0000000B, 0x00000A6A, + 0x00000020, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0007002C, + 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, + 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, + 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0007002C, 0x00000017, 0x0000064B, 0x00000144, 0x00000144, + 0x00000144, 0x00000144, 0x0007002C, 0x00000017, 0x00000215, 0x00000A2E, 0x00000A2E, 0x00000A2E, + 0x00000A2E, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, + 0x000300F7, 0x00003A37, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, + 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, + 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, 0x000500AB, 0x00000009, + 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, 0x00003526, 0x00000A10, + 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001EB0, + 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, 0x00000A13, 0x00050041, + 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, + 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, + 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, + 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, + 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, + 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004EBE, 0x00000CE9, + 0x00000A1D, 0x0004003D, 0x0000000B, 0x0000578C, 0x00004EBE, 0x00050041, 0x00000288, 0x00004E6E, + 0x00000CE9, 0x00000A20, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, + 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A24, 0x0007004F, + 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, + 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, + 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000036C2, + 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000036C2, 0x000200F8, 0x000055E8, 0x000200F9, + 0x00003A37, 0x000200F8, 0x000036C2, 0x000500C4, 0x00000014, 0x000043C0, 0x0000538B, 0x00000A3C, + 0x0004007C, 0x00000016, 0x000038B8, 0x000043C0, 0x00050051, 0x0000000C, 0x000022C9, 0x000038B8, + 0x00000000, 0x00050051, 0x0000000C, 0x00001A9D, 0x000038B8, 0x00000002, 0x0004007C, 0x0000000C, + 0x000053FD, 0x000019C2, 0x00050084, 0x0000000C, 0x00002C0F, 0x00001A9D, 0x000053FD, 0x00050051, + 0x0000000C, 0x000044BE, 0x000038B8, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, + 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x0000578C, 0x00050084, 0x0000000C, 0x00005FD7, + 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x000022C9, 0x00005FD7, 0x0004007C, + 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00002375, 0x00002A92, 0x0000578B, + 0x000500C2, 0x0000000B, 0x00002DCE, 0x00002375, 0x00000A16, 0x000500C2, 0x0000000B, 0x00001B41, + 0x0000578C, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, 0x00005768, + 0x00004E29, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, 0x00004384, + 0x0000537D, 0x000018D9, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, 0x00002970, 0x0000538B, + 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FD, + 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000002, 0x000500C3, + 0x0000000C, 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005789, + 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005321, + 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, 0x00005321, 0x000500C2, + 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, + 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, + 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, + 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, + 0x00000A25, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, + 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, + 0x000500C7, 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, + 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, + 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A25, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, + 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, + 0x000035A3, 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, + 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, + 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, + 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, + 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, + 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, + 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, + 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, + 0x0000000C, 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, + 0x00000A25, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, + 0x00004ADE, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, + 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, + 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, + 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, + 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, + 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, + 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, + 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, + 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, + 0x000054ED, 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, + 0x00000012, 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, 0x000042C3, 0x000019AD, 0x00000000, + 0x000500C3, 0x0000000C, 0x000024FE, 0x000042C3, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002748, + 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, 0x000500C2, + 0x0000000B, 0x00005B4E, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, + 0x00050084, 0x0000000C, 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, + 0x000024FE, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A28, 0x000500C7, + 0x0000000C, 0x00002AB6, 0x000042C3, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002748, + 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, + 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A13, + 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, + 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, + 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, + 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, + 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, + 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, 0x000500C4, + 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, + 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, + 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, + 0x000500C7, 0x0000000C, 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, + 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C3, 0x00000A14, 0x00050080, + 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, + 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, + 0x00050080, 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, + 0x00001E0B, 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, 0x0000537D, 0x00002F42, 0x000018D9, + 0x000200F9, 0x00005F43, 0x000200F8, 0x00004E29, 0x0004007C, 0x00000016, 0x00005F7F, 0x0000538B, + 0x00050051, 0x0000000C, 0x000022D6, 0x00005F7F, 0x00000000, 0x00050084, 0x0000000C, 0x00002492, + 0x000022D6, 0x00000A23, 0x00050051, 0x0000000C, 0x000018DA, 0x00005F7F, 0x00000002, 0x0004007C, + 0x0000000C, 0x000038A9, 0x00005789, 0x00050084, 0x0000000C, 0x00002C10, 0x000018DA, 0x000038A9, + 0x00050051, 0x0000000C, 0x000044BF, 0x00005F7F, 0x00000001, 0x00050080, 0x0000000C, 0x000056D5, + 0x00002C10, 0x000044BF, 0x0004007C, 0x0000000C, 0x00005786, 0x00005788, 0x00050084, 0x0000000C, + 0x00001E9F, 0x000056D5, 0x00005786, 0x00050080, 0x0000000C, 0x00001F30, 0x00002492, 0x00001E9F, + 0x000200F9, 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, + 0x00001E0B, 0x00001F30, 0x00004E29, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, + 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, + 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, 0x00004315, + 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004315, 0x000500AA, + 0x00000009, 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x000061E2, + 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, + 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, + 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, + 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, + 0x00005F43, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000061E2, 0x00000A13, + 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x00003450, 0x00000000, + 0x000400FA, 0x00003B23, 0x00002B38, 0x00003450, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, + 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, + 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x00003450, 0x000200F8, + 0x00003450, 0x000700F5, 0x00000017, 0x00005654, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, + 0x000600A9, 0x0000000B, 0x00002E64, 0x00004376, 0x00000A10, 0x00000A0D, 0x00050080, 0x0000000B, + 0x00002C4B, 0x00005665, 0x00002E64, 0x00060041, 0x00000294, 0x00004766, 0x0000107A, 0x00000A0B, + 0x00002C4B, 0x0004003D, 0x00000017, 0x000019B2, 0x00004766, 0x000300F7, 0x00003A1A, 0x00000000, + 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, + 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, + 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, + 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x00003450, + 0x00003FF9, 0x00002958, 0x000300F7, 0x00002DA2, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, + 0x00002DA2, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, + 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, + 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002DA2, 0x000200F8, 0x00002DA2, 0x000700F5, 0x00000017, + 0x00004D8D, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x0009004F, 0x00000017, 0x00005675, + 0x00005654, 0x00005654, 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x000500C2, 0x00000017, + 0x00003080, 0x00005675, 0x0000007D, 0x000500C7, 0x00000017, 0x00002376, 0x00003080, 0x0000064B, + 0x0009004F, 0x00000017, 0x000042A8, 0x00004D8D, 0x00004D8D, 0x00000000, 0x00000000, 0x00000002, + 0x00000002, 0x000500C2, 0x00000017, 0x00001DD8, 0x000042A8, 0x0000007D, 0x000500C7, 0x00000017, + 0x000019B9, 0x00001DD8, 0x0000064B, 0x00050051, 0x0000000B, 0x00004641, 0x00005654, 0x00000000, + 0x00050051, 0x0000000B, 0x00001880, 0x00005654, 0x00000002, 0x00050051, 0x0000000B, 0x00001DD9, + 0x00004D8D, 0x00000000, 0x00050051, 0x0000000B, 0x000026FC, 0x00004D8D, 0x00000002, 0x00070050, + 0x00000017, 0x00003C0F, 0x00004641, 0x00001880, 0x00001DD9, 0x000026FC, 0x000500C2, 0x00000017, + 0x0000278A, 0x00003C0F, 0x000002ED, 0x00050051, 0x0000000B, 0x00005D24, 0x00005654, 0x00000001, + 0x00050051, 0x0000000B, 0x00005FDB, 0x00005654, 0x00000003, 0x00050051, 0x0000000B, 0x00001DDA, + 0x00004D8D, 0x00000001, 0x00050051, 0x0000000B, 0x0000275B, 0x00004D8D, 0x00000003, 0x00070050, + 0x00000017, 0x00004137, 0x00005D24, 0x00005FDB, 0x00001DDA, 0x0000275B, 0x000500C7, 0x00000017, + 0x000021E7, 0x00004137, 0x0000064B, 0x000500C4, 0x00000017, 0x00004E4B, 0x000021E7, 0x000002ED, + 0x000500C5, 0x00000017, 0x00003F71, 0x0000278A, 0x00004E4B, 0x00050051, 0x0000000B, 0x00004E80, + 0x00003F71, 0x00000000, 0x00050051, 0x0000000B, 0x00001966, 0x00002376, 0x00000000, 0x00050051, + 0x0000000B, 0x00003330, 0x00002376, 0x00000001, 0x000500B2, 0x00000009, 0x00004E83, 0x00001966, + 0x00003330, 0x000300F7, 0x00002DC8, 0x00000000, 0x000400FA, 0x00004E83, 0x00002990, 0x000055A0, + 0x000200F8, 0x00002990, 0x000500C7, 0x0000000B, 0x000044F9, 0x00004E80, 0x000009C8, 0x000500C7, + 0x0000000B, 0x00005D8C, 0x00004E80, 0x00000986, 0x000500C2, 0x0000000B, 0x00005554, 0x00005D8C, + 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FC5, 0x000044F9, 0x00005554, 0x000500C4, 0x0000000B, + 0x00006021, 0x00001FC5, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059AC, 0x00001FC5, 0x00000A0D, + 0x000500C5, 0x0000000B, 0x00004969, 0x00006021, 0x000059AC, 0x000500C5, 0x0000000B, 0x00003EB1, + 0x00001FC5, 0x00004969, 0x000500C7, 0x0000000B, 0x00004785, 0x00004E80, 0x000009E9, 0x000500C5, + 0x0000000B, 0x0000395D, 0x00004785, 0x00000944, 0x000500C7, 0x0000000B, 0x00004FB3, 0x0000395D, + 0x00003EB1, 0x000500C2, 0x0000000B, 0x0000503B, 0x000044F9, 0x00000A0D, 0x000500C5, 0x0000000B, + 0x0000615A, 0x00004785, 0x0000503B, 0x000500C2, 0x0000000B, 0x000055A2, 0x00005D8C, 0x00000A10, + 0x000500C5, 0x0000000B, 0x00005892, 0x0000615A, 0x000055A2, 0x000500C6, 0x0000000B, 0x00001E29, + 0x00005892, 0x000009E9, 0x000400C8, 0x0000000B, 0x00002544, 0x0000503B, 0x000500C7, 0x0000000B, + 0x0000391D, 0x00004785, 0x00002544, 0x000400C8, 0x0000000B, 0x000020E9, 0x000055A2, 0x000500C7, + 0x0000000B, 0x00002C8F, 0x0000391D, 0x000020E9, 0x000500C5, 0x0000000B, 0x00001A8F, 0x00004E80, + 0x00001E29, 0x00050082, 0x0000000B, 0x00004C35, 0x00001A8F, 0x000009E9, 0x000500C5, 0x0000000B, + 0x00003A17, 0x00004C35, 0x00002C8F, 0x000500C4, 0x0000000B, 0x00004734, 0x00002C8F, 0x00000A10, + 0x000500C5, 0x0000000B, 0x00003BFA, 0x00003A17, 0x00004734, 0x000400C8, 0x0000000B, 0x00002F7A, + 0x00003EB1, 0x000500C7, 0x0000000B, 0x00004850, 0x00003BFA, 0x00002F7A, 0x000500C5, 0x0000000B, + 0x0000186C, 0x00004850, 0x00004FB3, 0x000200F9, 0x00002DC8, 0x000200F8, 0x000055A0, 0x000500C7, + 0x0000000B, 0x00004E6F, 0x00004E80, 0x000009E9, 0x000500C7, 0x0000000B, 0x00005D66, 0x00004E80, + 0x000009C8, 0x000500C2, 0x0000000B, 0x000056E7, 0x00005D66, 0x00000A0D, 0x000500C5, 0x0000000B, + 0x00005DC0, 0x00004E6F, 0x000056E7, 0x000500C7, 0x0000000B, 0x00004C8F, 0x00004E80, 0x00000986, + 0x000500C2, 0x0000000B, 0x00005087, 0x00004C8F, 0x00000A10, 0x000500C5, 0x0000000B, 0x00005EDF, + 0x00005DC0, 0x00005087, 0x000500C6, 0x0000000B, 0x00001E2A, 0x00005EDF, 0x000009E9, 0x000400C8, + 0x0000000B, 0x00002545, 0x000056E7, 0x000500C7, 0x0000000B, 0x0000391E, 0x00004E6F, 0x00002545, + 0x000400C8, 0x0000000B, 0x000020EA, 0x00005087, 0x000500C7, 0x0000000B, 0x00002C90, 0x0000391E, + 0x000020EA, 0x000500C5, 0x0000000B, 0x00001A90, 0x00004E80, 0x00001E2A, 0x00050082, 0x0000000B, + 0x00004C36, 0x00001A90, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A18, 0x00004C36, 0x00002C90, + 0x000500C4, 0x0000000B, 0x000046E8, 0x00002C90, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00003E88, + 0x00003A18, 0x000046E8, 0x000500C4, 0x0000000B, 0x00001FB6, 0x00002C90, 0x00000A10, 0x000500C5, + 0x0000000B, 0x00001E80, 0x00003E88, 0x00001FB6, 0x000200F9, 0x00002DC8, 0x000200F8, 0x00002DC8, + 0x000700F5, 0x0000000B, 0x000043D0, 0x0000186C, 0x00002990, 0x00001E80, 0x000055A0, 0x00050051, + 0x0000000B, 0x00005A0E, 0x00003F71, 0x00000001, 0x00050051, 0x0000000B, 0x00003281, 0x00002376, + 0x00000002, 0x00050051, 0x0000000B, 0x00003331, 0x00002376, 0x00000003, 0x000500B2, 0x00000009, + 0x00004E84, 0x00003281, 0x00003331, 0x000300F7, 0x00002DC9, 0x00000000, 0x000400FA, 0x00004E84, + 0x00002991, 0x000055A1, 0x000200F8, 0x00002991, 0x000500C7, 0x0000000B, 0x000044FA, 0x00005A0E, + 0x000009C8, 0x000500C7, 0x0000000B, 0x00005D8D, 0x00005A0E, 0x00000986, 0x000500C2, 0x0000000B, + 0x00005555, 0x00005D8D, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FC6, 0x000044FA, 0x00005555, + 0x000500C4, 0x0000000B, 0x00006022, 0x00001FC6, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059AD, + 0x00001FC6, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000496B, 0x00006022, 0x000059AD, 0x000500C5, + 0x0000000B, 0x00003EB2, 0x00001FC6, 0x0000496B, 0x000500C7, 0x0000000B, 0x00004786, 0x00005A0E, + 0x000009E9, 0x000500C5, 0x0000000B, 0x0000395E, 0x00004786, 0x00000944, 0x000500C7, 0x0000000B, + 0x00004FB4, 0x0000395E, 0x00003EB2, 0x000500C2, 0x0000000B, 0x0000503C, 0x000044FA, 0x00000A0D, + 0x000500C5, 0x0000000B, 0x0000615B, 0x00004786, 0x0000503C, 0x000500C2, 0x0000000B, 0x000055A3, + 0x00005D8D, 0x00000A10, 0x000500C5, 0x0000000B, 0x00005893, 0x0000615B, 0x000055A3, 0x000500C6, + 0x0000000B, 0x00001E2B, 0x00005893, 0x000009E9, 0x000400C8, 0x0000000B, 0x00002546, 0x0000503C, + 0x000500C7, 0x0000000B, 0x0000391F, 0x00004786, 0x00002546, 0x000400C8, 0x0000000B, 0x000020EB, + 0x000055A3, 0x000500C7, 0x0000000B, 0x00002C91, 0x0000391F, 0x000020EB, 0x000500C5, 0x0000000B, + 0x00001A91, 0x00005A0E, 0x00001E2B, 0x00050082, 0x0000000B, 0x00004C37, 0x00001A91, 0x000009E9, + 0x000500C5, 0x0000000B, 0x00003A19, 0x00004C37, 0x00002C91, 0x000500C4, 0x0000000B, 0x00004735, + 0x00002C91, 0x00000A10, 0x000500C5, 0x0000000B, 0x00003BFB, 0x00003A19, 0x00004735, 0x000400C8, + 0x0000000B, 0x00002F7B, 0x00003EB2, 0x000500C7, 0x0000000B, 0x00004851, 0x00003BFB, 0x00002F7B, + 0x000500C5, 0x0000000B, 0x0000186D, 0x00004851, 0x00004FB4, 0x000200F9, 0x00002DC9, 0x000200F8, + 0x000055A1, 0x000500C7, 0x0000000B, 0x00004E70, 0x00005A0E, 0x000009E9, 0x000500C7, 0x0000000B, + 0x00005D67, 0x00005A0E, 0x000009C8, 0x000500C2, 0x0000000B, 0x000056E8, 0x00005D67, 0x00000A0D, + 0x000500C5, 0x0000000B, 0x00005DC1, 0x00004E70, 0x000056E8, 0x000500C7, 0x0000000B, 0x00004C90, + 0x00005A0E, 0x00000986, 0x000500C2, 0x0000000B, 0x00005088, 0x00004C90, 0x00000A10, 0x000500C5, + 0x0000000B, 0x00005EE0, 0x00005DC1, 0x00005088, 0x000500C6, 0x0000000B, 0x00001E2C, 0x00005EE0, + 0x000009E9, 0x000400C8, 0x0000000B, 0x00002547, 0x000056E8, 0x000500C7, 0x0000000B, 0x00003920, + 0x00004E70, 0x00002547, 0x000400C8, 0x0000000B, 0x000020EC, 0x00005088, 0x000500C7, 0x0000000B, + 0x00002C92, 0x00003920, 0x000020EC, 0x000500C5, 0x0000000B, 0x00001A92, 0x00005A0E, 0x00001E2C, + 0x00050082, 0x0000000B, 0x00004C38, 0x00001A92, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A1B, + 0x00004C38, 0x00002C92, 0x000500C4, 0x0000000B, 0x000046E9, 0x00002C92, 0x00000A0D, 0x000500C5, + 0x0000000B, 0x00003E89, 0x00003A1B, 0x000046E9, 0x000500C4, 0x0000000B, 0x00001FB7, 0x00002C92, + 0x00000A10, 0x000500C5, 0x0000000B, 0x00001E81, 0x00003E89, 0x00001FB7, 0x000200F9, 0x00002DC9, + 0x000200F8, 0x00002DC9, 0x000700F5, 0x0000000B, 0x000043D1, 0x0000186D, 0x00002991, 0x00001E81, + 0x000055A1, 0x00050051, 0x0000000B, 0x00005A0F, 0x00003F71, 0x00000002, 0x00050051, 0x0000000B, + 0x00003282, 0x000019B9, 0x00000000, 0x00050051, 0x0000000B, 0x00003333, 0x000019B9, 0x00000001, + 0x000500B2, 0x00000009, 0x00004E85, 0x00003282, 0x00003333, 0x000300F7, 0x00002DCA, 0x00000000, + 0x000400FA, 0x00004E85, 0x00002992, 0x000055A5, 0x000200F8, 0x00002992, 0x000500C7, 0x0000000B, + 0x000044FB, 0x00005A0F, 0x000009C8, 0x000500C7, 0x0000000B, 0x00005D8E, 0x00005A0F, 0x00000986, + 0x000500C2, 0x0000000B, 0x00005556, 0x00005D8E, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FC7, + 0x000044FB, 0x00005556, 0x000500C4, 0x0000000B, 0x00006023, 0x00001FC7, 0x00000A0D, 0x000500C2, + 0x0000000B, 0x000059AE, 0x00001FC7, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000496C, 0x00006023, + 0x000059AE, 0x000500C5, 0x0000000B, 0x00003EB3, 0x00001FC7, 0x0000496C, 0x000500C7, 0x0000000B, + 0x00004787, 0x00005A0F, 0x000009E9, 0x000500C5, 0x0000000B, 0x0000395F, 0x00004787, 0x00000944, + 0x000500C7, 0x0000000B, 0x00004FB5, 0x0000395F, 0x00003EB3, 0x000500C2, 0x0000000B, 0x0000503D, + 0x000044FB, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000615C, 0x00004787, 0x0000503D, 0x000500C2, + 0x0000000B, 0x000055A4, 0x00005D8E, 0x00000A10, 0x000500C5, 0x0000000B, 0x00005894, 0x0000615C, + 0x000055A4, 0x000500C6, 0x0000000B, 0x00001E2D, 0x00005894, 0x000009E9, 0x000400C8, 0x0000000B, + 0x00002548, 0x0000503D, 0x000500C7, 0x0000000B, 0x00003921, 0x00004787, 0x00002548, 0x000400C8, + 0x0000000B, 0x000020ED, 0x000055A4, 0x000500C7, 0x0000000B, 0x00002C93, 0x00003921, 0x000020ED, + 0x000500C5, 0x0000000B, 0x00001A93, 0x00005A0F, 0x00001E2D, 0x00050082, 0x0000000B, 0x00004C39, + 0x00001A93, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A1C, 0x00004C39, 0x00002C93, 0x000500C4, + 0x0000000B, 0x00004736, 0x00002C93, 0x00000A10, 0x000500C5, 0x0000000B, 0x00003BFC, 0x00003A1C, + 0x00004736, 0x000400C8, 0x0000000B, 0x00002F7C, 0x00003EB3, 0x000500C7, 0x0000000B, 0x00004852, + 0x00003BFC, 0x00002F7C, 0x000500C5, 0x0000000B, 0x0000186E, 0x00004852, 0x00004FB5, 0x000200F9, + 0x00002DCA, 0x000200F8, 0x000055A5, 0x000500C7, 0x0000000B, 0x00004E71, 0x00005A0F, 0x000009E9, + 0x000500C7, 0x0000000B, 0x00005D68, 0x00005A0F, 0x000009C8, 0x000500C2, 0x0000000B, 0x000056E9, + 0x00005D68, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00005DC2, 0x00004E71, 0x000056E9, 0x000500C7, + 0x0000000B, 0x00004C91, 0x00005A0F, 0x00000986, 0x000500C2, 0x0000000B, 0x00005089, 0x00004C91, + 0x00000A10, 0x000500C5, 0x0000000B, 0x00005EE1, 0x00005DC2, 0x00005089, 0x000500C6, 0x0000000B, + 0x00001E2E, 0x00005EE1, 0x000009E9, 0x000400C8, 0x0000000B, 0x00002549, 0x000056E9, 0x000500C7, + 0x0000000B, 0x00003922, 0x00004E71, 0x00002549, 0x000400C8, 0x0000000B, 0x000020EE, 0x00005089, + 0x000500C7, 0x0000000B, 0x00002C94, 0x00003922, 0x000020EE, 0x000500C5, 0x0000000B, 0x00001A94, + 0x00005A0F, 0x00001E2E, 0x00050082, 0x0000000B, 0x00004C3A, 0x00001A94, 0x000009E9, 0x000500C5, + 0x0000000B, 0x00003A1D, 0x00004C3A, 0x00002C94, 0x000500C4, 0x0000000B, 0x000046EA, 0x00002C94, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x00003E8A, 0x00003A1D, 0x000046EA, 0x000500C4, 0x0000000B, + 0x00001FB8, 0x00002C94, 0x00000A10, 0x000500C5, 0x0000000B, 0x00001E82, 0x00003E8A, 0x00001FB8, + 0x000200F9, 0x00002DCA, 0x000200F8, 0x00002DCA, 0x000700F5, 0x0000000B, 0x000043D2, 0x0000186E, + 0x00002992, 0x00001E82, 0x000055A5, 0x00050051, 0x0000000B, 0x00005A10, 0x00003F71, 0x00000003, + 0x00050051, 0x0000000B, 0x00003283, 0x000019B9, 0x00000002, 0x00050051, 0x0000000B, 0x00003334, + 0x000019B9, 0x00000003, 0x000500B2, 0x00000009, 0x00004E86, 0x00003283, 0x00003334, 0x000300F7, + 0x00002DB5, 0x00000000, 0x000400FA, 0x00004E86, 0x00002993, 0x000055A7, 0x000200F8, 0x00002993, + 0x000500C7, 0x0000000B, 0x000044FC, 0x00005A10, 0x000009C8, 0x000500C7, 0x0000000B, 0x00005D8F, + 0x00005A10, 0x00000986, 0x000500C2, 0x0000000B, 0x00005557, 0x00005D8F, 0x00000A0D, 0x000500C7, + 0x0000000B, 0x00001FC8, 0x000044FC, 0x00005557, 0x000500C4, 0x0000000B, 0x00006024, 0x00001FC8, + 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059AF, 0x00001FC8, 0x00000A0D, 0x000500C5, 0x0000000B, + 0x0000496D, 0x00006024, 0x000059AF, 0x000500C5, 0x0000000B, 0x00003EB4, 0x00001FC8, 0x0000496D, + 0x000500C7, 0x0000000B, 0x00004788, 0x00005A10, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003960, + 0x00004788, 0x00000944, 0x000500C7, 0x0000000B, 0x00004FB6, 0x00003960, 0x00003EB4, 0x000500C2, + 0x0000000B, 0x0000503E, 0x000044FC, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000615D, 0x00004788, + 0x0000503E, 0x000500C2, 0x0000000B, 0x000055A6, 0x00005D8F, 0x00000A10, 0x000500C5, 0x0000000B, + 0x00005895, 0x0000615D, 0x000055A6, 0x000500C6, 0x0000000B, 0x00001E2F, 0x00005895, 0x000009E9, + 0x000400C8, 0x0000000B, 0x0000254A, 0x0000503E, 0x000500C7, 0x0000000B, 0x00003923, 0x00004788, + 0x0000254A, 0x000400C8, 0x0000000B, 0x000020EF, 0x000055A6, 0x000500C7, 0x0000000B, 0x00002C95, + 0x00003923, 0x000020EF, 0x000500C5, 0x0000000B, 0x00001A95, 0x00005A10, 0x00001E2F, 0x00050082, + 0x0000000B, 0x00004C3B, 0x00001A95, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A1E, 0x00004C3B, + 0x00002C95, 0x000500C4, 0x0000000B, 0x00004737, 0x00002C95, 0x00000A10, 0x000500C5, 0x0000000B, + 0x00003BFD, 0x00003A1E, 0x00004737, 0x000400C8, 0x0000000B, 0x00002F7D, 0x00003EB4, 0x000500C7, + 0x0000000B, 0x00004853, 0x00003BFD, 0x00002F7D, 0x000500C5, 0x0000000B, 0x0000186F, 0x00004853, + 0x00004FB6, 0x000200F9, 0x00002DB5, 0x000200F8, 0x000055A7, 0x000500C7, 0x0000000B, 0x00004E72, + 0x00005A10, 0x000009E9, 0x000500C7, 0x0000000B, 0x00005D69, 0x00005A10, 0x000009C8, 0x000500C2, + 0x0000000B, 0x000056EA, 0x00005D69, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00005DC3, 0x00004E72, + 0x000056EA, 0x000500C7, 0x0000000B, 0x00004C92, 0x00005A10, 0x00000986, 0x000500C2, 0x0000000B, + 0x0000508A, 0x00004C92, 0x00000A10, 0x000500C5, 0x0000000B, 0x00005EE2, 0x00005DC3, 0x0000508A, + 0x000500C6, 0x0000000B, 0x00001E30, 0x00005EE2, 0x000009E9, 0x000400C8, 0x0000000B, 0x0000254B, + 0x000056EA, 0x000500C7, 0x0000000B, 0x00003924, 0x00004E72, 0x0000254B, 0x000400C8, 0x0000000B, + 0x000020F0, 0x0000508A, 0x000500C7, 0x0000000B, 0x00002C96, 0x00003924, 0x000020F0, 0x000500C5, + 0x0000000B, 0x00001A96, 0x00005A10, 0x00001E30, 0x00050082, 0x0000000B, 0x00004C3C, 0x00001A96, + 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A1F, 0x00004C3C, 0x00002C96, 0x000500C4, 0x0000000B, + 0x000046EB, 0x00002C96, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00003E8B, 0x00003A1F, 0x000046EB, + 0x000500C4, 0x0000000B, 0x00001FB9, 0x00002C96, 0x00000A10, 0x000500C5, 0x0000000B, 0x00001E83, + 0x00003E8B, 0x00001FB9, 0x000200F9, 0x00002DB5, 0x000200F8, 0x00002DB5, 0x000700F5, 0x0000000B, + 0x000050CF, 0x0000186F, 0x00002993, 0x00001E83, 0x000055A7, 0x00070050, 0x00000017, 0x000060EB, + 0x000043D0, 0x000043D1, 0x000043D2, 0x000050CF, 0x000300F7, 0x00003A20, 0x00000000, 0x000400FA, + 0x00004E83, 0x00002994, 0x000038BE, 0x000200F8, 0x00002994, 0x000500C7, 0x0000000B, 0x000044FD, + 0x000043D0, 0x0000003A, 0x000500C7, 0x0000000B, 0x00005D90, 0x000043D0, 0x0000022D, 0x000500C2, + 0x0000000B, 0x00005558, 0x00005D90, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FC9, 0x000044FD, + 0x00005558, 0x000500C4, 0x0000000B, 0x00006025, 0x00001FC9, 0x00000A0D, 0x000500C2, 0x0000000B, + 0x000059B0, 0x00001FC9, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000497C, 0x00006025, 0x000059B0, + 0x000500C5, 0x0000000B, 0x00003E2A, 0x00001FC9, 0x0000497C, 0x000400C8, 0x0000000B, 0x0000210B, + 0x00003E2A, 0x000500C7, 0x0000000B, 0x00002762, 0x000043D0, 0x0000210B, 0x00050082, 0x0000000B, + 0x00003FAC, 0x00000908, 0x00002762, 0x000500C7, 0x0000000B, 0x00004407, 0x00003FAC, 0x0000210B, + 0x000500C7, 0x0000000B, 0x0000425F, 0x00004407, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000356D, + 0x00001966, 0x0000425F, 0x000500C7, 0x0000000B, 0x000055D7, 0x00002762, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00004FA6, 0x00003330, 0x000055D7, 0x00050080, 0x0000000B, 0x00004D82, 0x0000356D, + 0x00004FA6, 0x00050086, 0x0000000B, 0x000032C8, 0x00004D82, 0x00000A19, 0x000500C2, 0x0000000B, + 0x000059EE, 0x00004407, 0x00000A13, 0x000500C7, 0x0000000B, 0x00002231, 0x000059EE, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AA3, 0x00001966, 0x00002231, 0x000500C2, 0x0000000B, 0x000033E3, + 0x00002762, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000617D, 0x000033E3, 0x00000A1F, 0x00050084, + 0x0000000B, 0x0000626A, 0x00003330, 0x0000617D, 0x00050080, 0x0000000B, 0x00004DA8, 0x00003AA3, + 0x0000626A, 0x00050086, 0x0000000B, 0x00003148, 0x00004DA8, 0x00000A19, 0x000500C4, 0x0000000B, + 0x00001FE0, 0x00003148, 0x00000A22, 0x000500C5, 0x0000000B, 0x00001D81, 0x000032C8, 0x00001FE0, + 0x000500C2, 0x0000000B, 0x000055AF, 0x00004407, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044B8, + 0x000055AF, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AA4, 0x00001966, 0x000044B8, 0x000500C2, + 0x0000000B, 0x000033E4, 0x00002762, 0x00000A1C, 0x000500C7, 0x0000000B, 0x0000617E, 0x000033E4, + 0x00000A1F, 0x00050084, 0x0000000B, 0x0000626B, 0x00003330, 0x0000617E, 0x00050080, 0x0000000B, + 0x00004DA9, 0x00003AA4, 0x0000626B, 0x00050086, 0x0000000B, 0x00003149, 0x00004DA9, 0x00000A19, + 0x000500C4, 0x0000000B, 0x00001FE1, 0x00003149, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D82, + 0x00001D81, 0x00001FE1, 0x000500C2, 0x0000000B, 0x000055B0, 0x00004407, 0x00000A25, 0x000500C7, + 0x0000000B, 0x000044B9, 0x000055B0, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AA5, 0x00001966, + 0x000044B9, 0x000500C2, 0x0000000B, 0x000033E5, 0x00002762, 0x00000A25, 0x000500C7, 0x0000000B, + 0x0000617F, 0x000033E5, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000626C, 0x00003330, 0x0000617F, + 0x00050080, 0x0000000B, 0x00004DAA, 0x00003AA5, 0x0000626C, 0x00050086, 0x0000000B, 0x0000314A, + 0x00004DAA, 0x00000A19, 0x000500C4, 0x0000000B, 0x0000203F, 0x0000314A, 0x00000A52, 0x000500C5, + 0x0000000B, 0x00001A20, 0x00001D82, 0x0000203F, 0x000500C7, 0x0000000B, 0x00004FA1, 0x000043D0, + 0x00003E2A, 0x000500C7, 0x0000000B, 0x00004400, 0x00004FA1, 0x00000A0D, 0x000500C7, 0x0000000B, + 0x00004C67, 0x00004FA1, 0x00000A22, 0x000500C4, 0x0000000B, 0x00006164, 0x00004C67, 0x00000A19, + 0x000500C5, 0x0000000B, 0x000042BB, 0x00004400, 0x00006164, 0x000500C7, 0x0000000B, 0x00005182, + 0x00004FA1, 0x00000ACA, 0x000500C4, 0x0000000B, 0x00005B17, 0x00005182, 0x00000A28, 0x000500C5, + 0x0000000B, 0x000042BC, 0x000042BB, 0x00005B17, 0x000500C7, 0x0000000B, 0x00005183, 0x00004FA1, + 0x00000447, 0x000500C4, 0x0000000B, 0x0000561E, 0x00005183, 0x00000A37, 0x000500C5, 0x0000000B, + 0x00002077, 0x000042BC, 0x0000561E, 0x00050084, 0x0000000B, 0x000028B3, 0x00002077, 0x00000144, + 0x00050080, 0x0000000B, 0x000047FF, 0x00001A20, 0x000028B3, 0x000200F9, 0x00003A20, 0x000200F8, + 0x000038BE, 0x000400C8, 0x0000000B, 0x000029D4, 0x000043D0, 0x000500C7, 0x0000000B, 0x00003BFE, + 0x000029D4, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004530, 0x00001966, 0x00003BFE, 0x000500C7, + 0x0000000B, 0x000055D8, 0x000043D0, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FA7, 0x00003330, + 0x000055D8, 0x00050080, 0x0000000B, 0x00004D83, 0x00004530, 0x00004FA7, 0x00050086, 0x0000000B, + 0x000032C9, 0x00004D83, 0x00000A1F, 0x000500C2, 0x0000000B, 0x000059EF, 0x000029D4, 0x00000A13, + 0x000500C7, 0x0000000B, 0x00002232, 0x000059EF, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AA6, + 0x00001966, 0x00002232, 0x000500C2, 0x0000000B, 0x000033E6, 0x000043D0, 0x00000A13, 0x000500C7, + 0x0000000B, 0x00006180, 0x000033E6, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000626D, 0x00003330, + 0x00006180, 0x00050080, 0x0000000B, 0x00004DAB, 0x00003AA6, 0x0000626D, 0x00050086, 0x0000000B, + 0x0000314B, 0x00004DAB, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FE2, 0x0000314B, 0x00000A22, + 0x000500C5, 0x0000000B, 0x00001D83, 0x000032C9, 0x00001FE2, 0x000500C2, 0x0000000B, 0x000055B1, + 0x000029D4, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044BA, 0x000055B1, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AA7, 0x00001966, 0x000044BA, 0x000500C2, 0x0000000B, 0x000033E7, 0x000043D0, + 0x00000A1C, 0x000500C7, 0x0000000B, 0x00006181, 0x000033E7, 0x00000A1F, 0x00050084, 0x0000000B, + 0x0000626E, 0x00003330, 0x00006181, 0x00050080, 0x0000000B, 0x00004DAC, 0x00003AA7, 0x0000626E, + 0x00050086, 0x0000000B, 0x0000314C, 0x00004DAC, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FE3, + 0x0000314C, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D84, 0x00001D83, 0x00001FE3, 0x000500C2, + 0x0000000B, 0x000055B2, 0x000029D4, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044BB, 0x000055B2, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AA8, 0x00001966, 0x000044BB, 0x000500C2, 0x0000000B, + 0x000033E8, 0x000043D0, 0x00000A25, 0x000500C7, 0x0000000B, 0x00006182, 0x000033E8, 0x00000A1F, + 0x00050084, 0x0000000B, 0x0000626F, 0x00003330, 0x00006182, 0x00050080, 0x0000000B, 0x00004DAD, + 0x00003AA8, 0x0000626F, 0x00050086, 0x0000000B, 0x0000314D, 0x00004DAD, 0x00000A1F, 0x000500C4, + 0x0000000B, 0x000023F5, 0x0000314D, 0x00000A52, 0x000500C5, 0x0000000B, 0x00004678, 0x00001D84, + 0x000023F5, 0x000200F9, 0x00003A20, 0x000200F8, 0x00003A20, 0x000700F5, 0x0000000B, 0x00002AAD, + 0x000047FF, 0x00002994, 0x00004678, 0x000038BE, 0x000300F7, 0x00003A21, 0x00000000, 0x000400FA, + 0x00004E84, 0x00002995, 0x000038BF, 0x000200F8, 0x00002995, 0x000500C7, 0x0000000B, 0x000044FE, + 0x000043D1, 0x0000003A, 0x000500C7, 0x0000000B, 0x00005D91, 0x000043D1, 0x0000022D, 0x000500C2, + 0x0000000B, 0x00005559, 0x00005D91, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FCA, 0x000044FE, + 0x00005559, 0x000500C4, 0x0000000B, 0x00006026, 0x00001FCA, 0x00000A0D, 0x000500C2, 0x0000000B, + 0x000059B1, 0x00001FCA, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000497D, 0x00006026, 0x000059B1, + 0x000500C5, 0x0000000B, 0x00003E2B, 0x00001FCA, 0x0000497D, 0x000400C8, 0x0000000B, 0x0000210C, + 0x00003E2B, 0x000500C7, 0x0000000B, 0x00002763, 0x000043D1, 0x0000210C, 0x00050082, 0x0000000B, + 0x00003FAD, 0x00000908, 0x00002763, 0x000500C7, 0x0000000B, 0x00004408, 0x00003FAD, 0x0000210C, + 0x000500C7, 0x0000000B, 0x00004260, 0x00004408, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000356E, + 0x00003281, 0x00004260, 0x000500C7, 0x0000000B, 0x000055D9, 0x00002763, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00004FA8, 0x00003331, 0x000055D9, 0x00050080, 0x0000000B, 0x00004D84, 0x0000356E, + 0x00004FA8, 0x00050086, 0x0000000B, 0x000032CA, 0x00004D84, 0x00000A19, 0x000500C2, 0x0000000B, + 0x000059F0, 0x00004408, 0x00000A13, 0x000500C7, 0x0000000B, 0x00002233, 0x000059F0, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AA9, 0x00003281, 0x00002233, 0x000500C2, 0x0000000B, 0x000033E9, + 0x00002763, 0x00000A13, 0x000500C7, 0x0000000B, 0x00006183, 0x000033E9, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00006270, 0x00003331, 0x00006183, 0x00050080, 0x0000000B, 0x00004DAE, 0x00003AA9, + 0x00006270, 0x00050086, 0x0000000B, 0x0000314E, 0x00004DAE, 0x00000A19, 0x000500C4, 0x0000000B, + 0x00001FE4, 0x0000314E, 0x00000A22, 0x000500C5, 0x0000000B, 0x00001D85, 0x000032CA, 0x00001FE4, + 0x000500C2, 0x0000000B, 0x000055B3, 0x00004408, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044BC, + 0x000055B3, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AAA, 0x00003281, 0x000044BC, 0x000500C2, + 0x0000000B, 0x000033EA, 0x00002763, 0x00000A1C, 0x000500C7, 0x0000000B, 0x00006184, 0x000033EA, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00006271, 0x00003331, 0x00006184, 0x00050080, 0x0000000B, + 0x00004DAF, 0x00003AAA, 0x00006271, 0x00050086, 0x0000000B, 0x0000314F, 0x00004DAF, 0x00000A19, + 0x000500C4, 0x0000000B, 0x00001FE5, 0x0000314F, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D86, + 0x00001D85, 0x00001FE5, 0x000500C2, 0x0000000B, 0x000055B4, 0x00004408, 0x00000A25, 0x000500C7, + 0x0000000B, 0x000044BD, 0x000055B4, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AAB, 0x00003281, + 0x000044BD, 0x000500C2, 0x0000000B, 0x000033EB, 0x00002763, 0x00000A25, 0x000500C7, 0x0000000B, + 0x00006185, 0x000033EB, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006272, 0x00003331, 0x00006185, + 0x00050080, 0x0000000B, 0x00004DB0, 0x00003AAB, 0x00006272, 0x00050086, 0x0000000B, 0x00003150, + 0x00004DB0, 0x00000A19, 0x000500C4, 0x0000000B, 0x00002040, 0x00003150, 0x00000A52, 0x000500C5, + 0x0000000B, 0x00001A21, 0x00001D86, 0x00002040, 0x000500C7, 0x0000000B, 0x00004FA2, 0x000043D1, + 0x00003E2B, 0x000500C7, 0x0000000B, 0x00004401, 0x00004FA2, 0x00000A0D, 0x000500C7, 0x0000000B, + 0x00004C68, 0x00004FA2, 0x00000A22, 0x000500C4, 0x0000000B, 0x00006165, 0x00004C68, 0x00000A19, + 0x000500C5, 0x0000000B, 0x000042BD, 0x00004401, 0x00006165, 0x000500C7, 0x0000000B, 0x00005184, + 0x00004FA2, 0x00000ACA, 0x000500C4, 0x0000000B, 0x00005B18, 0x00005184, 0x00000A28, 0x000500C5, + 0x0000000B, 0x000042BE, 0x000042BD, 0x00005B18, 0x000500C7, 0x0000000B, 0x00005185, 0x00004FA2, + 0x00000447, 0x000500C4, 0x0000000B, 0x0000561F, 0x00005185, 0x00000A37, 0x000500C5, 0x0000000B, + 0x00002078, 0x000042BE, 0x0000561F, 0x00050084, 0x0000000B, 0x000028B4, 0x00002078, 0x00000144, + 0x00050080, 0x0000000B, 0x00004800, 0x00001A21, 0x000028B4, 0x000200F9, 0x00003A21, 0x000200F8, + 0x000038BF, 0x000400C8, 0x0000000B, 0x000029D5, 0x000043D1, 0x000500C7, 0x0000000B, 0x00003BFF, + 0x000029D5, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004531, 0x00003281, 0x00003BFF, 0x000500C7, + 0x0000000B, 0x000055DA, 0x000043D1, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FA9, 0x00003331, + 0x000055DA, 0x00050080, 0x0000000B, 0x00004D85, 0x00004531, 0x00004FA9, 0x00050086, 0x0000000B, + 0x000032CB, 0x00004D85, 0x00000A1F, 0x000500C2, 0x0000000B, 0x000059F1, 0x000029D5, 0x00000A13, + 0x000500C7, 0x0000000B, 0x00002234, 0x000059F1, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AAC, + 0x00003281, 0x00002234, 0x000500C2, 0x0000000B, 0x000033EC, 0x000043D1, 0x00000A13, 0x000500C7, + 0x0000000B, 0x00006186, 0x000033EC, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006273, 0x00003331, + 0x00006186, 0x00050080, 0x0000000B, 0x00004DB1, 0x00003AAC, 0x00006273, 0x00050086, 0x0000000B, + 0x00003151, 0x00004DB1, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FE6, 0x00003151, 0x00000A22, + 0x000500C5, 0x0000000B, 0x00001D87, 0x000032CB, 0x00001FE6, 0x000500C2, 0x0000000B, 0x000055B5, + 0x000029D5, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044C0, 0x000055B5, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AAD, 0x00003281, 0x000044C0, 0x000500C2, 0x0000000B, 0x000033ED, 0x000043D1, + 0x00000A1C, 0x000500C7, 0x0000000B, 0x00006187, 0x000033ED, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00006274, 0x00003331, 0x00006187, 0x00050080, 0x0000000B, 0x00004DB2, 0x00003AAD, 0x00006274, + 0x00050086, 0x0000000B, 0x00003152, 0x00004DB2, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FE7, + 0x00003152, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D88, 0x00001D87, 0x00001FE7, 0x000500C2, + 0x0000000B, 0x000055B6, 0x000029D5, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044C1, 0x000055B6, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AAE, 0x00003281, 0x000044C1, 0x000500C2, 0x0000000B, + 0x000033EE, 0x000043D1, 0x00000A25, 0x000500C7, 0x0000000B, 0x00006188, 0x000033EE, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00006275, 0x00003331, 0x00006188, 0x00050080, 0x0000000B, 0x00004DB3, + 0x00003AAE, 0x00006275, 0x00050086, 0x0000000B, 0x00003153, 0x00004DB3, 0x00000A1F, 0x000500C4, + 0x0000000B, 0x000023F6, 0x00003153, 0x00000A52, 0x000500C5, 0x0000000B, 0x00004679, 0x00001D88, + 0x000023F6, 0x000200F9, 0x00003A21, 0x000200F8, 0x00003A21, 0x000700F5, 0x0000000B, 0x00002AAE, + 0x00004800, 0x00002995, 0x00004679, 0x000038BF, 0x000300F7, 0x00003A22, 0x00000000, 0x000400FA, + 0x00004E85, 0x00002996, 0x000038C0, 0x000200F8, 0x00002996, 0x000500C7, 0x0000000B, 0x000044FF, + 0x000043D2, 0x0000003A, 0x000500C7, 0x0000000B, 0x00005D92, 0x000043D2, 0x0000022D, 0x000500C2, + 0x0000000B, 0x0000555A, 0x00005D92, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FCB, 0x000044FF, + 0x0000555A, 0x000500C4, 0x0000000B, 0x00006027, 0x00001FCB, 0x00000A0D, 0x000500C2, 0x0000000B, + 0x000059B2, 0x00001FCB, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000497E, 0x00006027, 0x000059B2, + 0x000500C5, 0x0000000B, 0x00003E2C, 0x00001FCB, 0x0000497E, 0x000400C8, 0x0000000B, 0x0000210D, + 0x00003E2C, 0x000500C7, 0x0000000B, 0x00002764, 0x000043D2, 0x0000210D, 0x00050082, 0x0000000B, + 0x00003FAE, 0x00000908, 0x00002764, 0x000500C7, 0x0000000B, 0x00004409, 0x00003FAE, 0x0000210D, + 0x000500C7, 0x0000000B, 0x00004261, 0x00004409, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000356F, + 0x00003282, 0x00004261, 0x000500C7, 0x0000000B, 0x000055DB, 0x00002764, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00004FAA, 0x00003333, 0x000055DB, 0x00050080, 0x0000000B, 0x00004D86, 0x0000356F, + 0x00004FAA, 0x00050086, 0x0000000B, 0x000032CC, 0x00004D86, 0x00000A19, 0x000500C2, 0x0000000B, + 0x000059F2, 0x00004409, 0x00000A13, 0x000500C7, 0x0000000B, 0x00002235, 0x000059F2, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AAF, 0x00003282, 0x00002235, 0x000500C2, 0x0000000B, 0x000033EF, + 0x00002764, 0x00000A13, 0x000500C7, 0x0000000B, 0x00006189, 0x000033EF, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00006276, 0x00003333, 0x00006189, 0x00050080, 0x0000000B, 0x00004DB4, 0x00003AAF, + 0x00006276, 0x00050086, 0x0000000B, 0x00003154, 0x00004DB4, 0x00000A19, 0x000500C4, 0x0000000B, + 0x00001FE8, 0x00003154, 0x00000A22, 0x000500C5, 0x0000000B, 0x00001D89, 0x000032CC, 0x00001FE8, + 0x000500C2, 0x0000000B, 0x000055B7, 0x00004409, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044C2, + 0x000055B7, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB0, 0x00003282, 0x000044C2, 0x000500C2, + 0x0000000B, 0x000033F0, 0x00002764, 0x00000A1C, 0x000500C7, 0x0000000B, 0x0000618A, 0x000033F0, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00006277, 0x00003333, 0x0000618A, 0x00050080, 0x0000000B, + 0x00004DB5, 0x00003AB0, 0x00006277, 0x00050086, 0x0000000B, 0x00003155, 0x00004DB5, 0x00000A19, + 0x000500C4, 0x0000000B, 0x00001FE9, 0x00003155, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D8A, + 0x00001D89, 0x00001FE9, 0x000500C2, 0x0000000B, 0x000055B8, 0x00004409, 0x00000A25, 0x000500C7, + 0x0000000B, 0x000044C3, 0x000055B8, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB1, 0x00003282, + 0x000044C3, 0x000500C2, 0x0000000B, 0x000033F1, 0x00002764, 0x00000A25, 0x000500C7, 0x0000000B, + 0x0000618B, 0x000033F1, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006278, 0x00003333, 0x0000618B, + 0x00050080, 0x0000000B, 0x00004DB6, 0x00003AB1, 0x00006278, 0x00050086, 0x0000000B, 0x00003156, + 0x00004DB6, 0x00000A19, 0x000500C4, 0x0000000B, 0x00002041, 0x00003156, 0x00000A52, 0x000500C5, + 0x0000000B, 0x00001A22, 0x00001D8A, 0x00002041, 0x000500C7, 0x0000000B, 0x00004FA3, 0x000043D2, + 0x00003E2C, 0x000500C7, 0x0000000B, 0x00004402, 0x00004FA3, 0x00000A0D, 0x000500C7, 0x0000000B, + 0x00004C69, 0x00004FA3, 0x00000A22, 0x000500C4, 0x0000000B, 0x00006166, 0x00004C69, 0x00000A19, + 0x000500C5, 0x0000000B, 0x000042BF, 0x00004402, 0x00006166, 0x000500C7, 0x0000000B, 0x00005186, + 0x00004FA3, 0x00000ACA, 0x000500C4, 0x0000000B, 0x00005B19, 0x00005186, 0x00000A28, 0x000500C5, + 0x0000000B, 0x000042C0, 0x000042BF, 0x00005B19, 0x000500C7, 0x0000000B, 0x00005187, 0x00004FA3, + 0x00000447, 0x000500C4, 0x0000000B, 0x00005620, 0x00005187, 0x00000A37, 0x000500C5, 0x0000000B, + 0x00002079, 0x000042C0, 0x00005620, 0x00050084, 0x0000000B, 0x000028B5, 0x00002079, 0x00000144, + 0x00050080, 0x0000000B, 0x00004801, 0x00001A22, 0x000028B5, 0x000200F9, 0x00003A22, 0x000200F8, + 0x000038C0, 0x000400C8, 0x0000000B, 0x000029D6, 0x000043D2, 0x000500C7, 0x0000000B, 0x00003C00, + 0x000029D6, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004532, 0x00003282, 0x00003C00, 0x000500C7, + 0x0000000B, 0x000055DC, 0x000043D2, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FAB, 0x00003333, + 0x000055DC, 0x00050080, 0x0000000B, 0x00004D87, 0x00004532, 0x00004FAB, 0x00050086, 0x0000000B, + 0x000032CD, 0x00004D87, 0x00000A1F, 0x000500C2, 0x0000000B, 0x000059F3, 0x000029D6, 0x00000A13, + 0x000500C7, 0x0000000B, 0x00002236, 0x000059F3, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB2, + 0x00003282, 0x00002236, 0x000500C2, 0x0000000B, 0x000033F2, 0x000043D2, 0x00000A13, 0x000500C7, + 0x0000000B, 0x0000618C, 0x000033F2, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006279, 0x00003333, + 0x0000618C, 0x00050080, 0x0000000B, 0x00004DB7, 0x00003AB2, 0x00006279, 0x00050086, 0x0000000B, + 0x00003157, 0x00004DB7, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FEA, 0x00003157, 0x00000A22, + 0x000500C5, 0x0000000B, 0x00001D8B, 0x000032CD, 0x00001FEA, 0x000500C2, 0x0000000B, 0x000055B9, + 0x000029D6, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044C4, 0x000055B9, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AB3, 0x00003282, 0x000044C4, 0x000500C2, 0x0000000B, 0x000033F3, 0x000043D2, + 0x00000A1C, 0x000500C7, 0x0000000B, 0x0000618D, 0x000033F3, 0x00000A1F, 0x00050084, 0x0000000B, + 0x0000627A, 0x00003333, 0x0000618D, 0x00050080, 0x0000000B, 0x00004DB8, 0x00003AB3, 0x0000627A, + 0x00050086, 0x0000000B, 0x00003158, 0x00004DB8, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FEB, + 0x00003158, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D8C, 0x00001D8B, 0x00001FEB, 0x000500C2, + 0x0000000B, 0x000055BA, 0x000029D6, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044C5, 0x000055BA, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB4, 0x00003282, 0x000044C5, 0x000500C2, 0x0000000B, + 0x000033F4, 0x000043D2, 0x00000A25, 0x000500C7, 0x0000000B, 0x0000618E, 0x000033F4, 0x00000A1F, + 0x00050084, 0x0000000B, 0x0000627B, 0x00003333, 0x0000618E, 0x00050080, 0x0000000B, 0x00004DB9, + 0x00003AB4, 0x0000627B, 0x00050086, 0x0000000B, 0x00003159, 0x00004DB9, 0x00000A1F, 0x000500C4, + 0x0000000B, 0x000023F7, 0x00003159, 0x00000A52, 0x000500C5, 0x0000000B, 0x0000467A, 0x00001D8C, + 0x000023F7, 0x000200F9, 0x00003A22, 0x000200F8, 0x00003A22, 0x000700F5, 0x0000000B, 0x00002AAF, + 0x00004801, 0x00002996, 0x0000467A, 0x000038C0, 0x000300F7, 0x00002DB6, 0x00000000, 0x000400FA, + 0x00004E86, 0x00002997, 0x000038C1, 0x000200F8, 0x00002997, 0x000500C7, 0x0000000B, 0x00004500, + 0x000050CF, 0x0000003A, 0x000500C7, 0x0000000B, 0x00005D93, 0x000050CF, 0x0000022D, 0x000500C2, + 0x0000000B, 0x0000555B, 0x00005D93, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FCC, 0x00004500, + 0x0000555B, 0x000500C4, 0x0000000B, 0x00006028, 0x00001FCC, 0x00000A0D, 0x000500C2, 0x0000000B, + 0x000059B3, 0x00001FCC, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000497F, 0x00006028, 0x000059B3, + 0x000500C5, 0x0000000B, 0x00003E2D, 0x00001FCC, 0x0000497F, 0x000400C8, 0x0000000B, 0x0000210E, + 0x00003E2D, 0x000500C7, 0x0000000B, 0x00002765, 0x000050CF, 0x0000210E, 0x00050082, 0x0000000B, + 0x00003FAF, 0x00000908, 0x00002765, 0x000500C7, 0x0000000B, 0x0000440A, 0x00003FAF, 0x0000210E, + 0x000500C7, 0x0000000B, 0x00004262, 0x0000440A, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003570, + 0x00003283, 0x00004262, 0x000500C7, 0x0000000B, 0x000055DD, 0x00002765, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00004FAC, 0x00003334, 0x000055DD, 0x00050080, 0x0000000B, 0x00004D88, 0x00003570, + 0x00004FAC, 0x00050086, 0x0000000B, 0x000032CE, 0x00004D88, 0x00000A19, 0x000500C2, 0x0000000B, + 0x000059F4, 0x0000440A, 0x00000A13, 0x000500C7, 0x0000000B, 0x00002237, 0x000059F4, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AB5, 0x00003283, 0x00002237, 0x000500C2, 0x0000000B, 0x000033F5, + 0x00002765, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000618F, 0x000033F5, 0x00000A1F, 0x00050084, + 0x0000000B, 0x0000627C, 0x00003334, 0x0000618F, 0x00050080, 0x0000000B, 0x00004DBA, 0x00003AB5, + 0x0000627C, 0x00050086, 0x0000000B, 0x0000315A, 0x00004DBA, 0x00000A19, 0x000500C4, 0x0000000B, + 0x00001FEC, 0x0000315A, 0x00000A22, 0x000500C5, 0x0000000B, 0x00001D8D, 0x000032CE, 0x00001FEC, + 0x000500C2, 0x0000000B, 0x000055BB, 0x0000440A, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044C6, + 0x000055BB, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB6, 0x00003283, 0x000044C6, 0x000500C2, + 0x0000000B, 0x000033F6, 0x00002765, 0x00000A1C, 0x000500C7, 0x0000000B, 0x00006190, 0x000033F6, + 0x00000A1F, 0x00050084, 0x0000000B, 0x0000627D, 0x00003334, 0x00006190, 0x00050080, 0x0000000B, + 0x00004DBB, 0x00003AB6, 0x0000627D, 0x00050086, 0x0000000B, 0x0000315B, 0x00004DBB, 0x00000A19, + 0x000500C4, 0x0000000B, 0x00001FED, 0x0000315B, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D8E, + 0x00001D8D, 0x00001FED, 0x000500C2, 0x0000000B, 0x000055BC, 0x0000440A, 0x00000A25, 0x000500C7, + 0x0000000B, 0x000044C7, 0x000055BC, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB7, 0x00003283, + 0x000044C7, 0x000500C2, 0x0000000B, 0x000033F7, 0x00002765, 0x00000A25, 0x000500C7, 0x0000000B, + 0x00006191, 0x000033F7, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000627E, 0x00003334, 0x00006191, + 0x00050080, 0x0000000B, 0x00004DBC, 0x00003AB7, 0x0000627E, 0x00050086, 0x0000000B, 0x0000315C, + 0x00004DBC, 0x00000A19, 0x000500C4, 0x0000000B, 0x00002043, 0x0000315C, 0x00000A52, 0x000500C5, + 0x0000000B, 0x00001A23, 0x00001D8E, 0x00002043, 0x000500C7, 0x0000000B, 0x00004FA4, 0x000050CF, + 0x00003E2D, 0x000500C7, 0x0000000B, 0x00004403, 0x00004FA4, 0x00000A0D, 0x000500C7, 0x0000000B, + 0x00004C6A, 0x00004FA4, 0x00000A22, 0x000500C4, 0x0000000B, 0x00006167, 0x00004C6A, 0x00000A19, + 0x000500C5, 0x0000000B, 0x000042C1, 0x00004403, 0x00006167, 0x000500C7, 0x0000000B, 0x00005188, + 0x00004FA4, 0x00000ACA, 0x000500C4, 0x0000000B, 0x00005B1A, 0x00005188, 0x00000A28, 0x000500C5, + 0x0000000B, 0x000042C4, 0x000042C1, 0x00005B1A, 0x000500C7, 0x0000000B, 0x00005189, 0x00004FA4, + 0x00000447, 0x000500C4, 0x0000000B, 0x00005621, 0x00005189, 0x00000A37, 0x000500C5, 0x0000000B, + 0x0000207A, 0x000042C4, 0x00005621, 0x00050084, 0x0000000B, 0x000028B6, 0x0000207A, 0x00000144, + 0x00050080, 0x0000000B, 0x00004802, 0x00001A23, 0x000028B6, 0x000200F9, 0x00002DB6, 0x000200F8, + 0x000038C1, 0x000400C8, 0x0000000B, 0x000029D7, 0x000050CF, 0x000500C7, 0x0000000B, 0x00003C01, + 0x000029D7, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004533, 0x00003283, 0x00003C01, 0x000500C7, + 0x0000000B, 0x000055DE, 0x000050CF, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FAD, 0x00003334, + 0x000055DE, 0x00050080, 0x0000000B, 0x00004D89, 0x00004533, 0x00004FAD, 0x00050086, 0x0000000B, + 0x000032CF, 0x00004D89, 0x00000A1F, 0x000500C2, 0x0000000B, 0x000059F5, 0x000029D7, 0x00000A13, + 0x000500C7, 0x0000000B, 0x00002238, 0x000059F5, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AB8, + 0x00003283, 0x00002238, 0x000500C2, 0x0000000B, 0x000033F8, 0x000050CF, 0x00000A13, 0x000500C7, + 0x0000000B, 0x00006192, 0x000033F8, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000627F, 0x00003334, + 0x00006192, 0x00050080, 0x0000000B, 0x00004DBD, 0x00003AB8, 0x0000627F, 0x00050086, 0x0000000B, + 0x0000315D, 0x00004DBD, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FEE, 0x0000315D, 0x00000A22, + 0x000500C5, 0x0000000B, 0x00001D8F, 0x000032CF, 0x00001FEE, 0x000500C2, 0x0000000B, 0x000055BD, + 0x000029D7, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044C8, 0x000055BD, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AB9, 0x00003283, 0x000044C8, 0x000500C2, 0x0000000B, 0x000033F9, 0x000050CF, + 0x00000A1C, 0x000500C7, 0x0000000B, 0x00006193, 0x000033F9, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00006280, 0x00003334, 0x00006193, 0x00050080, 0x0000000B, 0x00004DBE, 0x00003AB9, 0x00006280, + 0x00050086, 0x0000000B, 0x0000315E, 0x00004DBE, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FEF, + 0x0000315E, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D90, 0x00001D8F, 0x00001FEF, 0x000500C2, + 0x0000000B, 0x000055BE, 0x000029D7, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044C9, 0x000055BE, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ABA, 0x00003283, 0x000044C9, 0x000500C2, 0x0000000B, + 0x000033FA, 0x000050CF, 0x00000A25, 0x000500C7, 0x0000000B, 0x00006194, 0x000033FA, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00006281, 0x00003334, 0x00006194, 0x00050080, 0x0000000B, 0x00004DBF, + 0x00003ABA, 0x00006281, 0x00050086, 0x0000000B, 0x0000315F, 0x00004DBF, 0x00000A1F, 0x000500C4, + 0x0000000B, 0x000023F8, 0x0000315F, 0x00000A52, 0x000500C5, 0x0000000B, 0x0000467B, 0x00001D90, + 0x000023F8, 0x000200F9, 0x00002DB6, 0x000200F8, 0x00002DB6, 0x000700F5, 0x0000000B, 0x0000434D, + 0x00004802, 0x00002997, 0x0000467B, 0x000038C1, 0x00070050, 0x00000017, 0x000038F7, 0x00002AAD, + 0x00002AAE, 0x00002AAF, 0x0000434D, 0x00060041, 0x00000294, 0x00002FB5, 0x0000140E, 0x00000A0B, + 0x00002DCE, 0x0003003E, 0x00002FB5, 0x000038F7, 0x00050051, 0x0000000B, 0x00003220, 0x000043C0, + 0x00000001, 0x00050080, 0x0000000B, 0x00005AC0, 0x00003220, 0x00000A0E, 0x000500B0, 0x00000009, + 0x00004411, 0x00005AC0, 0x000019C2, 0x000300F7, 0x00001C26, 0x00000002, 0x000400FA, 0x00004411, + 0x0000592C, 0x00001C26, 0x000200F8, 0x0000592C, 0x00050080, 0x0000000B, 0x00003416, 0x00002DCE, + 0x00001B41, 0x000500C2, 0x00000017, 0x00003D27, 0x000060EB, 0x00000215, 0x00050051, 0x0000000B, + 0x00005D1B, 0x00003D27, 0x00000000, 0x000300F7, 0x00002DCB, 0x00000000, 0x000400FA, 0x00004E83, + 0x00002998, 0x000038C2, 0x000200F8, 0x00002998, 0x000500C7, 0x0000000B, 0x00004501, 0x00005D1B, + 0x0000003A, 0x000500C7, 0x0000000B, 0x00005D94, 0x00005D1B, 0x0000022D, 0x000500C2, 0x0000000B, + 0x0000555C, 0x00005D94, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FCD, 0x00004501, 0x0000555C, + 0x000500C4, 0x0000000B, 0x00006029, 0x00001FCD, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059B4, + 0x00001FCD, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004980, 0x00006029, 0x000059B4, 0x000500C5, + 0x0000000B, 0x00003E2E, 0x00001FCD, 0x00004980, 0x000400C8, 0x0000000B, 0x0000210F, 0x00003E2E, + 0x000500C7, 0x0000000B, 0x00002766, 0x00005D1B, 0x0000210F, 0x00050082, 0x0000000B, 0x00003FB0, + 0x00000908, 0x00002766, 0x000500C7, 0x0000000B, 0x0000440B, 0x00003FB0, 0x0000210F, 0x000500C7, + 0x0000000B, 0x00004263, 0x0000440B, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003571, 0x00001966, + 0x00004263, 0x000500C7, 0x0000000B, 0x000055DF, 0x00002766, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00004FAE, 0x00003330, 0x000055DF, 0x00050080, 0x0000000B, 0x00004D8A, 0x00003571, 0x00004FAE, + 0x00050086, 0x0000000B, 0x000032D0, 0x00004D8A, 0x00000A19, 0x000500C2, 0x0000000B, 0x000059F6, + 0x0000440B, 0x00000A13, 0x000500C7, 0x0000000B, 0x00002239, 0x000059F6, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003ABB, 0x00001966, 0x00002239, 0x000500C2, 0x0000000B, 0x000033FB, 0x00002766, + 0x00000A13, 0x000500C7, 0x0000000B, 0x00006195, 0x000033FB, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00006282, 0x00003330, 0x00006195, 0x00050080, 0x0000000B, 0x00004DC0, 0x00003ABB, 0x00006282, + 0x00050086, 0x0000000B, 0x00003160, 0x00004DC0, 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FF0, + 0x00003160, 0x00000A22, 0x000500C5, 0x0000000B, 0x00001D91, 0x000032D0, 0x00001FF0, 0x000500C2, + 0x0000000B, 0x000055BF, 0x0000440B, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044CA, 0x000055BF, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ABC, 0x00001966, 0x000044CA, 0x000500C2, 0x0000000B, + 0x000033FC, 0x00002766, 0x00000A1C, 0x000500C7, 0x0000000B, 0x00006196, 0x000033FC, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00006283, 0x00003330, 0x00006196, 0x00050080, 0x0000000B, 0x00004DC1, + 0x00003ABC, 0x00006283, 0x00050086, 0x0000000B, 0x00003161, 0x00004DC1, 0x00000A19, 0x000500C4, + 0x0000000B, 0x00001FF1, 0x00003161, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D92, 0x00001D91, + 0x00001FF1, 0x000500C2, 0x0000000B, 0x000055C0, 0x0000440B, 0x00000A25, 0x000500C7, 0x0000000B, + 0x000044CB, 0x000055C0, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ABD, 0x00001966, 0x000044CB, + 0x000500C2, 0x0000000B, 0x000033FD, 0x00002766, 0x00000A25, 0x000500C7, 0x0000000B, 0x00006197, + 0x000033FD, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006284, 0x00003330, 0x00006197, 0x00050080, + 0x0000000B, 0x00004DC2, 0x00003ABD, 0x00006284, 0x00050086, 0x0000000B, 0x00003162, 0x00004DC2, + 0x00000A19, 0x000500C4, 0x0000000B, 0x00002044, 0x00003162, 0x00000A52, 0x000500C5, 0x0000000B, + 0x00001A24, 0x00001D92, 0x00002044, 0x000500C7, 0x0000000B, 0x00004FA5, 0x00005D1B, 0x00003E2E, + 0x000500C7, 0x0000000B, 0x00004404, 0x00004FA5, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C6B, + 0x00004FA5, 0x00000A22, 0x000500C4, 0x0000000B, 0x00006168, 0x00004C6B, 0x00000A19, 0x000500C5, + 0x0000000B, 0x000042C5, 0x00004404, 0x00006168, 0x000500C7, 0x0000000B, 0x0000518A, 0x00004FA5, + 0x00000ACA, 0x000500C4, 0x0000000B, 0x00005B1B, 0x0000518A, 0x00000A28, 0x000500C5, 0x0000000B, + 0x000042C6, 0x000042C5, 0x00005B1B, 0x000500C7, 0x0000000B, 0x0000518B, 0x00004FA5, 0x00000447, + 0x000500C4, 0x0000000B, 0x00005622, 0x0000518B, 0x00000A37, 0x000500C5, 0x0000000B, 0x0000207B, + 0x000042C6, 0x00005622, 0x00050084, 0x0000000B, 0x000028B7, 0x0000207B, 0x00000144, 0x00050080, + 0x0000000B, 0x00004803, 0x00001A24, 0x000028B7, 0x000200F9, 0x00002DCB, 0x000200F8, 0x000038C2, + 0x000400C8, 0x0000000B, 0x000029D8, 0x00005D1B, 0x000500C7, 0x0000000B, 0x00003C02, 0x000029D8, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00004534, 0x00001966, 0x00003C02, 0x000500C7, 0x0000000B, + 0x000055E0, 0x00005D1B, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FAF, 0x00003330, 0x000055E0, + 0x00050080, 0x0000000B, 0x00004D8B, 0x00004534, 0x00004FAF, 0x00050086, 0x0000000B, 0x000032D1, + 0x00004D8B, 0x00000A1F, 0x000500C2, 0x0000000B, 0x000059F7, 0x000029D8, 0x00000A13, 0x000500C7, + 0x0000000B, 0x0000223A, 0x000059F7, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ABE, 0x00001966, + 0x0000223A, 0x000500C2, 0x0000000B, 0x000033FE, 0x00005D1B, 0x00000A13, 0x000500C7, 0x0000000B, + 0x00006198, 0x000033FE, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006285, 0x00003330, 0x00006198, + 0x00050080, 0x0000000B, 0x00004DC3, 0x00003ABE, 0x00006285, 0x00050086, 0x0000000B, 0x00003163, + 0x00004DC3, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FF2, 0x00003163, 0x00000A22, 0x000500C5, + 0x0000000B, 0x00001D93, 0x000032D1, 0x00001FF2, 0x000500C2, 0x0000000B, 0x000055C1, 0x000029D8, + 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044CC, 0x000055C1, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003ABF, 0x00001966, 0x000044CC, 0x000500C2, 0x0000000B, 0x000033FF, 0x00005D1B, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x00006199, 0x000033FF, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006286, + 0x00003330, 0x00006199, 0x00050080, 0x0000000B, 0x00004DC4, 0x00003ABF, 0x00006286, 0x00050086, + 0x0000000B, 0x00003164, 0x00004DC4, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FF3, 0x00003164, + 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D94, 0x00001D93, 0x00001FF3, 0x000500C2, 0x0000000B, + 0x000055C2, 0x000029D8, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044CD, 0x000055C2, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AC0, 0x00001966, 0x000044CD, 0x000500C2, 0x0000000B, 0x00003400, + 0x00005D1B, 0x00000A25, 0x000500C7, 0x0000000B, 0x0000619A, 0x00003400, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00006287, 0x00003330, 0x0000619A, 0x00050080, 0x0000000B, 0x00004DC5, 0x00003AC0, + 0x00006287, 0x00050086, 0x0000000B, 0x00003165, 0x00004DC5, 0x00000A1F, 0x000500C4, 0x0000000B, + 0x000023F9, 0x00003165, 0x00000A52, 0x000500C5, 0x0000000B, 0x0000467C, 0x00001D94, 0x000023F9, + 0x000200F9, 0x00002DCB, 0x000200F8, 0x00002DCB, 0x000700F5, 0x0000000B, 0x00005023, 0x00004803, + 0x00002998, 0x0000467C, 0x000038C2, 0x00050051, 0x0000000B, 0x000040EA, 0x00003D27, 0x00000001, + 0x000300F7, 0x00002DCC, 0x00000000, 0x000400FA, 0x00004E84, 0x00002999, 0x000038C3, 0x000200F8, + 0x00002999, 0x000500C7, 0x0000000B, 0x00004502, 0x000040EA, 0x0000003A, 0x000500C7, 0x0000000B, + 0x00005D95, 0x000040EA, 0x0000022D, 0x000500C2, 0x0000000B, 0x0000555D, 0x00005D95, 0x00000A0D, + 0x000500C7, 0x0000000B, 0x00001FCE, 0x00004502, 0x0000555D, 0x000500C4, 0x0000000B, 0x0000602A, + 0x00001FCE, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059B5, 0x00001FCE, 0x00000A0D, 0x000500C5, + 0x0000000B, 0x00004981, 0x0000602A, 0x000059B5, 0x000500C5, 0x0000000B, 0x00003E2F, 0x00001FCE, + 0x00004981, 0x000400C8, 0x0000000B, 0x00002110, 0x00003E2F, 0x000500C7, 0x0000000B, 0x00002767, + 0x000040EA, 0x00002110, 0x00050082, 0x0000000B, 0x00003FB1, 0x00000908, 0x00002767, 0x000500C7, + 0x0000000B, 0x0000440C, 0x00003FB1, 0x00002110, 0x000500C7, 0x0000000B, 0x00004264, 0x0000440C, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003572, 0x00003281, 0x00004264, 0x000500C7, 0x0000000B, + 0x000055E1, 0x00002767, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FB0, 0x00003331, 0x000055E1, + 0x00050080, 0x0000000B, 0x00004D8C, 0x00003572, 0x00004FB0, 0x00050086, 0x0000000B, 0x000032D2, + 0x00004D8C, 0x00000A19, 0x000500C2, 0x0000000B, 0x000059F8, 0x0000440C, 0x00000A13, 0x000500C7, + 0x0000000B, 0x0000223B, 0x000059F8, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AC1, 0x00003281, + 0x0000223B, 0x000500C2, 0x0000000B, 0x00003401, 0x00002767, 0x00000A13, 0x000500C7, 0x0000000B, + 0x0000619B, 0x00003401, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006288, 0x00003331, 0x0000619B, + 0x00050080, 0x0000000B, 0x00004DC6, 0x00003AC1, 0x00006288, 0x00050086, 0x0000000B, 0x00003166, + 0x00004DC6, 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FF4, 0x00003166, 0x00000A22, 0x000500C5, + 0x0000000B, 0x00001D95, 0x000032D2, 0x00001FF4, 0x000500C2, 0x0000000B, 0x000055C3, 0x0000440C, + 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044CE, 0x000055C3, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003AC2, 0x00003281, 0x000044CE, 0x000500C2, 0x0000000B, 0x00003402, 0x00002767, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x0000619C, 0x00003402, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006289, + 0x00003331, 0x0000619C, 0x00050080, 0x0000000B, 0x00004DC7, 0x00003AC2, 0x00006289, 0x00050086, + 0x0000000B, 0x00003167, 0x00004DC7, 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FF5, 0x00003167, + 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D96, 0x00001D95, 0x00001FF5, 0x000500C2, 0x0000000B, + 0x000055C4, 0x0000440C, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044CF, 0x000055C4, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AC3, 0x00003281, 0x000044CF, 0x000500C2, 0x0000000B, 0x00003403, + 0x00002767, 0x00000A25, 0x000500C7, 0x0000000B, 0x0000619D, 0x00003403, 0x00000A1F, 0x00050084, + 0x0000000B, 0x0000628A, 0x00003331, 0x0000619D, 0x00050080, 0x0000000B, 0x00004DC8, 0x00003AC3, + 0x0000628A, 0x00050086, 0x0000000B, 0x00003168, 0x00004DC8, 0x00000A19, 0x000500C4, 0x0000000B, + 0x00002045, 0x00003168, 0x00000A52, 0x000500C5, 0x0000000B, 0x00001A25, 0x00001D96, 0x00002045, + 0x000500C7, 0x0000000B, 0x00004FB1, 0x000040EA, 0x00003E2F, 0x000500C7, 0x0000000B, 0x00004405, + 0x00004FB1, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C6C, 0x00004FB1, 0x00000A22, 0x000500C4, + 0x0000000B, 0x00006169, 0x00004C6C, 0x00000A19, 0x000500C5, 0x0000000B, 0x000042C7, 0x00004405, + 0x00006169, 0x000500C7, 0x0000000B, 0x0000518C, 0x00004FB1, 0x00000ACA, 0x000500C4, 0x0000000B, + 0x00005B1C, 0x0000518C, 0x00000A28, 0x000500C5, 0x0000000B, 0x000042C8, 0x000042C7, 0x00005B1C, + 0x000500C7, 0x0000000B, 0x0000518D, 0x00004FB1, 0x00000447, 0x000500C4, 0x0000000B, 0x00005623, + 0x0000518D, 0x00000A37, 0x000500C5, 0x0000000B, 0x0000207C, 0x000042C8, 0x00005623, 0x00050084, + 0x0000000B, 0x000028B8, 0x0000207C, 0x00000144, 0x00050080, 0x0000000B, 0x00004804, 0x00001A25, + 0x000028B8, 0x000200F9, 0x00002DCC, 0x000200F8, 0x000038C3, 0x000400C8, 0x0000000B, 0x000029D9, + 0x000040EA, 0x000500C7, 0x0000000B, 0x00003C03, 0x000029D9, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00004535, 0x00003281, 0x00003C03, 0x000500C7, 0x0000000B, 0x000055E2, 0x000040EA, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00004FB2, 0x00003331, 0x000055E2, 0x00050080, 0x0000000B, 0x00004D8E, + 0x00004535, 0x00004FB2, 0x00050086, 0x0000000B, 0x000032D3, 0x00004D8E, 0x00000A1F, 0x000500C2, + 0x0000000B, 0x000059F9, 0x000029D9, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000223C, 0x000059F9, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AC4, 0x00003281, 0x0000223C, 0x000500C2, 0x0000000B, + 0x00003404, 0x000040EA, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000619E, 0x00003404, 0x00000A1F, + 0x00050084, 0x0000000B, 0x0000628B, 0x00003331, 0x0000619E, 0x00050080, 0x0000000B, 0x00004DC9, + 0x00003AC4, 0x0000628B, 0x00050086, 0x0000000B, 0x00003169, 0x00004DC9, 0x00000A1F, 0x000500C4, + 0x0000000B, 0x00001FF6, 0x00003169, 0x00000A22, 0x000500C5, 0x0000000B, 0x00001D97, 0x000032D3, + 0x00001FF6, 0x000500C2, 0x0000000B, 0x000055C5, 0x000029D9, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x000044D0, 0x000055C5, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AC5, 0x00003281, 0x000044D0, + 0x000500C2, 0x0000000B, 0x00003405, 0x000040EA, 0x00000A1C, 0x000500C7, 0x0000000B, 0x0000619F, + 0x00003405, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000628C, 0x00003331, 0x0000619F, 0x00050080, + 0x0000000B, 0x00004DCA, 0x00003AC5, 0x0000628C, 0x00050086, 0x0000000B, 0x0000316A, 0x00004DCA, + 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FF7, 0x0000316A, 0x00000A3A, 0x000500C5, 0x0000000B, + 0x00001D98, 0x00001D97, 0x00001FF7, 0x000500C2, 0x0000000B, 0x000055C6, 0x000029D9, 0x00000A25, + 0x000500C7, 0x0000000B, 0x000044D1, 0x000055C6, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AC6, + 0x00003281, 0x000044D1, 0x000500C2, 0x0000000B, 0x00003406, 0x000040EA, 0x00000A25, 0x000500C7, + 0x0000000B, 0x000061A0, 0x00003406, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000628D, 0x00003331, + 0x000061A0, 0x00050080, 0x0000000B, 0x00004DCB, 0x00003AC6, 0x0000628D, 0x00050086, 0x0000000B, + 0x0000316B, 0x00004DCB, 0x00000A1F, 0x000500C4, 0x0000000B, 0x000023FA, 0x0000316B, 0x00000A52, + 0x000500C5, 0x0000000B, 0x0000467D, 0x00001D98, 0x000023FA, 0x000200F9, 0x00002DCC, 0x000200F8, + 0x00002DCC, 0x000700F5, 0x0000000B, 0x00005024, 0x00004804, 0x00002999, 0x0000467D, 0x000038C3, + 0x00050051, 0x0000000B, 0x000040EB, 0x00003D27, 0x00000002, 0x000300F7, 0x00002DCD, 0x00000000, + 0x000400FA, 0x00004E85, 0x0000299A, 0x000038C4, 0x000200F8, 0x0000299A, 0x000500C7, 0x0000000B, + 0x00004503, 0x000040EB, 0x0000003A, 0x000500C7, 0x0000000B, 0x00005D96, 0x000040EB, 0x0000022D, + 0x000500C2, 0x0000000B, 0x0000555E, 0x00005D96, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FCF, + 0x00004503, 0x0000555E, 0x000500C4, 0x0000000B, 0x0000602B, 0x00001FCF, 0x00000A0D, 0x000500C2, + 0x0000000B, 0x000059B6, 0x00001FCF, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004982, 0x0000602B, + 0x000059B6, 0x000500C5, 0x0000000B, 0x00003E30, 0x00001FCF, 0x00004982, 0x000400C8, 0x0000000B, + 0x00002111, 0x00003E30, 0x000500C7, 0x0000000B, 0x00002768, 0x000040EB, 0x00002111, 0x00050082, + 0x0000000B, 0x00003FB2, 0x00000908, 0x00002768, 0x000500C7, 0x0000000B, 0x0000440D, 0x00003FB2, + 0x00002111, 0x000500C7, 0x0000000B, 0x00004265, 0x0000440D, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003573, 0x00003282, 0x00004265, 0x000500C7, 0x0000000B, 0x000055E3, 0x00002768, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00004FB7, 0x00003333, 0x000055E3, 0x00050080, 0x0000000B, 0x00004D8F, + 0x00003573, 0x00004FB7, 0x00050086, 0x0000000B, 0x000032D4, 0x00004D8F, 0x00000A19, 0x000500C2, + 0x0000000B, 0x000059FA, 0x0000440D, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000223D, 0x000059FA, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AC7, 0x00003282, 0x0000223D, 0x000500C2, 0x0000000B, + 0x00003407, 0x00002768, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061A1, 0x00003407, 0x00000A1F, + 0x00050084, 0x0000000B, 0x0000628E, 0x00003333, 0x000061A1, 0x00050080, 0x0000000B, 0x00004DCC, + 0x00003AC7, 0x0000628E, 0x00050086, 0x0000000B, 0x0000316C, 0x00004DCC, 0x00000A19, 0x000500C4, + 0x0000000B, 0x00001FF8, 0x0000316C, 0x00000A22, 0x000500C5, 0x0000000B, 0x00001D99, 0x000032D4, + 0x00001FF8, 0x000500C2, 0x0000000B, 0x000055C7, 0x0000440D, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x000044D2, 0x000055C7, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AC8, 0x00003282, 0x000044D2, + 0x000500C2, 0x0000000B, 0x00003408, 0x00002768, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061A2, + 0x00003408, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000628F, 0x00003333, 0x000061A2, 0x00050080, + 0x0000000B, 0x00004DCD, 0x00003AC8, 0x0000628F, 0x00050086, 0x0000000B, 0x0000316D, 0x00004DCD, + 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FF9, 0x0000316D, 0x00000A3A, 0x000500C5, 0x0000000B, + 0x00001D9A, 0x00001D99, 0x00001FF9, 0x000500C2, 0x0000000B, 0x000055C8, 0x0000440D, 0x00000A25, + 0x000500C7, 0x0000000B, 0x000044D3, 0x000055C8, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AC9, + 0x00003282, 0x000044D3, 0x000500C2, 0x0000000B, 0x00003409, 0x00002768, 0x00000A25, 0x000500C7, + 0x0000000B, 0x000061A3, 0x00003409, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006290, 0x00003333, + 0x000061A3, 0x00050080, 0x0000000B, 0x00004DCE, 0x00003AC9, 0x00006290, 0x00050086, 0x0000000B, + 0x0000316E, 0x00004DCE, 0x00000A19, 0x000500C4, 0x0000000B, 0x00002046, 0x0000316E, 0x00000A52, + 0x000500C5, 0x0000000B, 0x00001A26, 0x00001D9A, 0x00002046, 0x000500C7, 0x0000000B, 0x00004FB8, + 0x000040EB, 0x00003E30, 0x000500C7, 0x0000000B, 0x00004406, 0x00004FB8, 0x00000A0D, 0x000500C7, + 0x0000000B, 0x00004C6D, 0x00004FB8, 0x00000A22, 0x000500C4, 0x0000000B, 0x0000616A, 0x00004C6D, + 0x00000A19, 0x000500C5, 0x0000000B, 0x000042C9, 0x00004406, 0x0000616A, 0x000500C7, 0x0000000B, + 0x0000518E, 0x00004FB8, 0x00000ACA, 0x000500C4, 0x0000000B, 0x00005B1D, 0x0000518E, 0x00000A28, + 0x000500C5, 0x0000000B, 0x000042CA, 0x000042C9, 0x00005B1D, 0x000500C7, 0x0000000B, 0x0000518F, + 0x00004FB8, 0x00000447, 0x000500C4, 0x0000000B, 0x00005624, 0x0000518F, 0x00000A37, 0x000500C5, + 0x0000000B, 0x0000207D, 0x000042CA, 0x00005624, 0x00050084, 0x0000000B, 0x000028B9, 0x0000207D, + 0x00000144, 0x00050080, 0x0000000B, 0x00004805, 0x00001A26, 0x000028B9, 0x000200F9, 0x00002DCD, + 0x000200F8, 0x000038C4, 0x000400C8, 0x0000000B, 0x000029DA, 0x000040EB, 0x000500C7, 0x0000000B, + 0x00003C04, 0x000029DA, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004536, 0x00003282, 0x00003C04, + 0x000500C7, 0x0000000B, 0x000055E4, 0x000040EB, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FB9, + 0x00003333, 0x000055E4, 0x00050080, 0x0000000B, 0x00004D90, 0x00004536, 0x00004FB9, 0x00050086, + 0x0000000B, 0x000032D5, 0x00004D90, 0x00000A1F, 0x000500C2, 0x0000000B, 0x000059FB, 0x000029DA, + 0x00000A13, 0x000500C7, 0x0000000B, 0x0000223E, 0x000059FB, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003ACA, 0x00003282, 0x0000223E, 0x000500C2, 0x0000000B, 0x0000340A, 0x000040EB, 0x00000A13, + 0x000500C7, 0x0000000B, 0x000061A4, 0x0000340A, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006291, + 0x00003333, 0x000061A4, 0x00050080, 0x0000000B, 0x00004DCF, 0x00003ACA, 0x00006291, 0x00050086, + 0x0000000B, 0x0000316F, 0x00004DCF, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FFA, 0x0000316F, + 0x00000A22, 0x000500C5, 0x0000000B, 0x00001D9B, 0x000032D5, 0x00001FFA, 0x000500C2, 0x0000000B, + 0x000055C9, 0x000029DA, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044D4, 0x000055C9, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003ACB, 0x00003282, 0x000044D4, 0x000500C2, 0x0000000B, 0x0000340B, + 0x000040EB, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061A5, 0x0000340B, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00006292, 0x00003333, 0x000061A5, 0x00050080, 0x0000000B, 0x00004DD0, 0x00003ACB, + 0x00006292, 0x00050086, 0x0000000B, 0x00003170, 0x00004DD0, 0x00000A1F, 0x000500C4, 0x0000000B, + 0x00001FFB, 0x00003170, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D9C, 0x00001D9B, 0x00001FFB, + 0x000500C2, 0x0000000B, 0x000055CA, 0x000029DA, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044D5, + 0x000055CA, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ACC, 0x00003282, 0x000044D5, 0x000500C2, + 0x0000000B, 0x0000340C, 0x000040EB, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061A6, 0x0000340C, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00006293, 0x00003333, 0x000061A6, 0x00050080, 0x0000000B, + 0x00004DD1, 0x00003ACC, 0x00006293, 0x00050086, 0x0000000B, 0x00003171, 0x00004DD1, 0x00000A1F, + 0x000500C4, 0x0000000B, 0x000023FB, 0x00003171, 0x00000A52, 0x000500C5, 0x0000000B, 0x0000467E, + 0x00001D9C, 0x000023FB, 0x000200F9, 0x00002DCD, 0x000200F8, 0x00002DCD, 0x000700F5, 0x0000000B, + 0x00005025, 0x00004805, 0x0000299A, 0x0000467E, 0x000038C4, 0x00050051, 0x0000000B, 0x000040EC, + 0x00003D27, 0x00000003, 0x000300F7, 0x00002DB7, 0x00000000, 0x000400FA, 0x00004E86, 0x0000299B, + 0x000038C5, 0x000200F8, 0x0000299B, 0x000500C7, 0x0000000B, 0x00004504, 0x000040EC, 0x0000003A, + 0x000500C7, 0x0000000B, 0x00005D97, 0x000040EC, 0x0000022D, 0x000500C2, 0x0000000B, 0x0000555F, + 0x00005D97, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FD0, 0x00004504, 0x0000555F, 0x000500C4, + 0x0000000B, 0x0000602C, 0x00001FD0, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059B7, 0x00001FD0, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004983, 0x0000602C, 0x000059B7, 0x000500C5, 0x0000000B, + 0x00003E31, 0x00001FD0, 0x00004983, 0x000400C8, 0x0000000B, 0x00002112, 0x00003E31, 0x000500C7, + 0x0000000B, 0x00002769, 0x000040EC, 0x00002112, 0x00050082, 0x0000000B, 0x00003FB3, 0x00000908, + 0x00002769, 0x000500C7, 0x0000000B, 0x0000440E, 0x00003FB3, 0x00002112, 0x000500C7, 0x0000000B, + 0x00004266, 0x0000440E, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003574, 0x00003283, 0x00004266, + 0x000500C7, 0x0000000B, 0x000055E5, 0x00002769, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FBA, + 0x00003334, 0x000055E5, 0x00050080, 0x0000000B, 0x00004D91, 0x00003574, 0x00004FBA, 0x00050086, + 0x0000000B, 0x000032D6, 0x00004D91, 0x00000A19, 0x000500C2, 0x0000000B, 0x000059FC, 0x0000440E, + 0x00000A13, 0x000500C7, 0x0000000B, 0x0000223F, 0x000059FC, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003ACD, 0x00003283, 0x0000223F, 0x000500C2, 0x0000000B, 0x0000340D, 0x00002769, 0x00000A13, + 0x000500C7, 0x0000000B, 0x000061A7, 0x0000340D, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006294, + 0x00003334, 0x000061A7, 0x00050080, 0x0000000B, 0x00004DD2, 0x00003ACD, 0x00006294, 0x00050086, + 0x0000000B, 0x00003172, 0x00004DD2, 0x00000A19, 0x000500C4, 0x0000000B, 0x00001FFC, 0x00003172, + 0x00000A22, 0x000500C5, 0x0000000B, 0x00001D9D, 0x000032D6, 0x00001FFC, 0x000500C2, 0x0000000B, + 0x000055CB, 0x0000440E, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044D6, 0x000055CB, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003ACE, 0x00003283, 0x000044D6, 0x000500C2, 0x0000000B, 0x0000340E, + 0x00002769, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061A8, 0x0000340E, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00006295, 0x00003334, 0x000061A8, 0x00050080, 0x0000000B, 0x00004DD3, 0x00003ACE, + 0x00006295, 0x00050086, 0x0000000B, 0x00003173, 0x00004DD3, 0x00000A19, 0x000500C4, 0x0000000B, + 0x00001FFD, 0x00003173, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001D9E, 0x00001D9D, 0x00001FFD, + 0x000500C2, 0x0000000B, 0x000055CC, 0x0000440E, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044D7, + 0x000055CC, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ACF, 0x00003283, 0x000044D7, 0x000500C2, + 0x0000000B, 0x0000340F, 0x00002769, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061A9, 0x0000340F, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00006296, 0x00003334, 0x000061A9, 0x00050080, 0x0000000B, + 0x00004DD4, 0x00003ACF, 0x00006296, 0x00050086, 0x0000000B, 0x00003174, 0x00004DD4, 0x00000A19, + 0x000500C4, 0x0000000B, 0x00002047, 0x00003174, 0x00000A52, 0x000500C5, 0x0000000B, 0x00001A27, + 0x00001D9E, 0x00002047, 0x000500C7, 0x0000000B, 0x00004FBB, 0x000040EC, 0x00003E31, 0x000500C7, + 0x0000000B, 0x0000440F, 0x00004FBB, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C6E, 0x00004FBB, + 0x00000A22, 0x000500C4, 0x0000000B, 0x0000616B, 0x00004C6E, 0x00000A19, 0x000500C5, 0x0000000B, + 0x000042CB, 0x0000440F, 0x0000616B, 0x000500C7, 0x0000000B, 0x00005190, 0x00004FBB, 0x00000ACA, + 0x000500C4, 0x0000000B, 0x00005B1E, 0x00005190, 0x00000A28, 0x000500C5, 0x0000000B, 0x000042CC, + 0x000042CB, 0x00005B1E, 0x000500C7, 0x0000000B, 0x00005191, 0x00004FBB, 0x00000447, 0x000500C4, + 0x0000000B, 0x00005625, 0x00005191, 0x00000A37, 0x000500C5, 0x0000000B, 0x0000207E, 0x000042CC, + 0x00005625, 0x00050084, 0x0000000B, 0x000028BA, 0x0000207E, 0x00000144, 0x00050080, 0x0000000B, + 0x00004806, 0x00001A27, 0x000028BA, 0x000200F9, 0x00002DB7, 0x000200F8, 0x000038C5, 0x000400C8, + 0x0000000B, 0x000029DB, 0x000040EC, 0x000500C7, 0x0000000B, 0x00003C05, 0x000029DB, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00004537, 0x00003283, 0x00003C05, 0x000500C7, 0x0000000B, 0x000055E6, + 0x000040EC, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FBC, 0x00003334, 0x000055E6, 0x00050080, + 0x0000000B, 0x00004D92, 0x00004537, 0x00004FBC, 0x00050086, 0x0000000B, 0x000032D7, 0x00004D92, + 0x00000A1F, 0x000500C2, 0x0000000B, 0x000059FD, 0x000029DB, 0x00000A13, 0x000500C7, 0x0000000B, + 0x00002240, 0x000059FD, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AD0, 0x00003283, 0x00002240, + 0x000500C2, 0x0000000B, 0x00003410, 0x000040EC, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061AA, + 0x00003410, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006297, 0x00003334, 0x000061AA, 0x00050080, + 0x0000000B, 0x00004DD5, 0x00003AD0, 0x00006297, 0x00050086, 0x0000000B, 0x00003175, 0x00004DD5, + 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FFE, 0x00003175, 0x00000A22, 0x000500C5, 0x0000000B, + 0x00001D9F, 0x000032D7, 0x00001FFE, 0x000500C2, 0x0000000B, 0x000055CD, 0x000029DB, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x000044D8, 0x000055CD, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AD1, + 0x00003283, 0x000044D8, 0x000500C2, 0x0000000B, 0x00003411, 0x000040EC, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x000061AB, 0x00003411, 0x00000A1F, 0x00050084, 0x0000000B, 0x00006298, 0x00003334, + 0x000061AB, 0x00050080, 0x0000000B, 0x00004DD6, 0x00003AD1, 0x00006298, 0x00050086, 0x0000000B, + 0x00003176, 0x00004DD6, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00001FFF, 0x00003176, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x00001DA0, 0x00001D9F, 0x00001FFF, 0x000500C2, 0x0000000B, 0x000055CE, + 0x000029DB, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044D9, 0x000055CE, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AD2, 0x00003283, 0x000044D9, 0x000500C2, 0x0000000B, 0x00003413, 0x000040EC, + 0x00000A25, 0x000500C7, 0x0000000B, 0x000061AC, 0x00003413, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00006299, 0x00003334, 0x000061AC, 0x00050080, 0x0000000B, 0x00004DD7, 0x00003AD2, 0x00006299, + 0x00050086, 0x0000000B, 0x00003177, 0x00004DD7, 0x00000A1F, 0x000500C4, 0x0000000B, 0x000023FC, + 0x00003177, 0x00000A52, 0x000500C5, 0x0000000B, 0x0000467F, 0x00001DA0, 0x000023FC, 0x000200F9, + 0x00002DB7, 0x000200F8, 0x00002DB7, 0x000700F5, 0x0000000B, 0x0000434E, 0x00004806, 0x0000299B, + 0x0000467F, 0x000038C5, 0x00070050, 0x00000017, 0x000038F8, 0x00005023, 0x00005024, 0x00005025, + 0x0000434E, 0x00060041, 0x00000294, 0x00003335, 0x0000140E, 0x00000A0B, 0x00003416, 0x0003003E, + 0x00003335, 0x000038F8, 0x00050080, 0x0000000B, 0x000039F8, 0x00003220, 0x00000A11, 0x000500B0, + 0x00000009, 0x00002E0B, 0x000039F8, 0x000019C2, 0x000300F7, 0x00001C25, 0x00000002, 0x000400FA, + 0x00002E0B, 0x0000592D, 0x00001C25, 0x000200F8, 0x0000592D, 0x00050080, 0x0000000B, 0x00003417, + 0x00003416, 0x00001B41, 0x000500C2, 0x00000017, 0x00003D28, 0x00004137, 0x0000013D, 0x00050051, + 0x0000000B, 0x00005D1C, 0x00003D28, 0x00000000, 0x000300F7, 0x00002DCF, 0x00000000, 0x000400FA, + 0x00004E83, 0x0000299C, 0x000055A9, 0x000200F8, 0x0000299C, 0x000500C7, 0x0000000B, 0x00004505, + 0x00005D1C, 0x000009C8, 0x000500C7, 0x0000000B, 0x00005D98, 0x00005D1C, 0x00000986, 0x000500C2, + 0x0000000B, 0x00005560, 0x00005D98, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FD1, 0x00004505, + 0x00005560, 0x000500C4, 0x0000000B, 0x0000602D, 0x00001FD1, 0x00000A0D, 0x000500C2, 0x0000000B, + 0x000059B8, 0x00001FD1, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000496E, 0x0000602D, 0x000059B8, + 0x000500C5, 0x0000000B, 0x00003EB5, 0x00001FD1, 0x0000496E, 0x000500C7, 0x0000000B, 0x00004789, + 0x00005D1C, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003961, 0x00004789, 0x00000944, 0x000500C7, + 0x0000000B, 0x00004FBD, 0x00003961, 0x00003EB5, 0x000500C2, 0x0000000B, 0x0000503F, 0x00004505, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000615E, 0x00004789, 0x0000503F, 0x000500C2, 0x0000000B, + 0x000055A8, 0x00005D98, 0x00000A10, 0x000500C5, 0x0000000B, 0x00005896, 0x0000615E, 0x000055A8, + 0x000500C6, 0x0000000B, 0x00001E31, 0x00005896, 0x000009E9, 0x000400C8, 0x0000000B, 0x0000254C, + 0x0000503F, 0x000500C7, 0x0000000B, 0x00003925, 0x00004789, 0x0000254C, 0x000400C8, 0x0000000B, + 0x000020F1, 0x000055A8, 0x000500C7, 0x0000000B, 0x00002C97, 0x00003925, 0x000020F1, 0x000500C5, + 0x0000000B, 0x00001A97, 0x00005D1C, 0x00001E31, 0x00050082, 0x0000000B, 0x00004C3D, 0x00001A97, + 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A23, 0x00004C3D, 0x00002C97, 0x000500C4, 0x0000000B, + 0x00004738, 0x00002C97, 0x00000A10, 0x000500C5, 0x0000000B, 0x00003C06, 0x00003A23, 0x00004738, + 0x000400C8, 0x0000000B, 0x00002F7E, 0x00003EB5, 0x000500C7, 0x0000000B, 0x00004854, 0x00003C06, + 0x00002F7E, 0x000500C5, 0x0000000B, 0x00001870, 0x00004854, 0x00004FBD, 0x000200F9, 0x00002DCF, + 0x000200F8, 0x000055A9, 0x000500C7, 0x0000000B, 0x00004E73, 0x00005D1C, 0x000009E9, 0x000500C7, + 0x0000000B, 0x00005D6A, 0x00005D1C, 0x000009C8, 0x000500C2, 0x0000000B, 0x000056EB, 0x00005D6A, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x00005DC4, 0x00004E73, 0x000056EB, 0x000500C7, 0x0000000B, + 0x00004C93, 0x00005D1C, 0x00000986, 0x000500C2, 0x0000000B, 0x0000508B, 0x00004C93, 0x00000A10, + 0x000500C5, 0x0000000B, 0x00005EE3, 0x00005DC4, 0x0000508B, 0x000500C6, 0x0000000B, 0x00001E32, + 0x00005EE3, 0x000009E9, 0x000400C8, 0x0000000B, 0x0000254D, 0x000056EB, 0x000500C7, 0x0000000B, + 0x00003926, 0x00004E73, 0x0000254D, 0x000400C8, 0x0000000B, 0x000020F2, 0x0000508B, 0x000500C7, + 0x0000000B, 0x00002C98, 0x00003926, 0x000020F2, 0x000500C5, 0x0000000B, 0x00001A98, 0x00005D1C, + 0x00001E32, 0x00050082, 0x0000000B, 0x00004C3E, 0x00001A98, 0x000009E9, 0x000500C5, 0x0000000B, + 0x00003A24, 0x00004C3E, 0x00002C98, 0x000500C4, 0x0000000B, 0x000046EC, 0x00002C98, 0x00000A0D, + 0x000500C5, 0x0000000B, 0x00003E8C, 0x00003A24, 0x000046EC, 0x000500C4, 0x0000000B, 0x00001FBA, + 0x00002C98, 0x00000A10, 0x000500C5, 0x0000000B, 0x00001E84, 0x00003E8C, 0x00001FBA, 0x000200F9, + 0x00002DCF, 0x000200F8, 0x00002DCF, 0x000700F5, 0x0000000B, 0x00005026, 0x00001870, 0x0000299C, + 0x00001E84, 0x000055A9, 0x00050051, 0x0000000B, 0x000040ED, 0x00003D28, 0x00000001, 0x000300F7, + 0x00002DD0, 0x00000000, 0x000400FA, 0x00004E84, 0x0000299D, 0x000055AB, 0x000200F8, 0x0000299D, + 0x000500C7, 0x0000000B, 0x00004506, 0x000040ED, 0x000009C8, 0x000500C7, 0x0000000B, 0x00005D99, + 0x000040ED, 0x00000986, 0x000500C2, 0x0000000B, 0x00005561, 0x00005D99, 0x00000A0D, 0x000500C7, + 0x0000000B, 0x00001FD2, 0x00004506, 0x00005561, 0x000500C4, 0x0000000B, 0x0000602E, 0x00001FD2, + 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059B9, 0x00001FD2, 0x00000A0D, 0x000500C5, 0x0000000B, + 0x0000496F, 0x0000602E, 0x000059B9, 0x000500C5, 0x0000000B, 0x00003EB6, 0x00001FD2, 0x0000496F, + 0x000500C7, 0x0000000B, 0x0000478A, 0x000040ED, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003962, + 0x0000478A, 0x00000944, 0x000500C7, 0x0000000B, 0x00004FBE, 0x00003962, 0x00003EB6, 0x000500C2, + 0x0000000B, 0x00005040, 0x00004506, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000615F, 0x0000478A, + 0x00005040, 0x000500C2, 0x0000000B, 0x000055AA, 0x00005D99, 0x00000A10, 0x000500C5, 0x0000000B, + 0x00005897, 0x0000615F, 0x000055AA, 0x000500C6, 0x0000000B, 0x00001E33, 0x00005897, 0x000009E9, + 0x000400C8, 0x0000000B, 0x0000254E, 0x00005040, 0x000500C7, 0x0000000B, 0x00003927, 0x0000478A, + 0x0000254E, 0x000400C8, 0x0000000B, 0x000020F3, 0x000055AA, 0x000500C7, 0x0000000B, 0x00002C99, + 0x00003927, 0x000020F3, 0x000500C5, 0x0000000B, 0x00001A99, 0x000040ED, 0x00001E33, 0x00050082, + 0x0000000B, 0x00004C3F, 0x00001A99, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A25, 0x00004C3F, + 0x00002C99, 0x000500C4, 0x0000000B, 0x00004739, 0x00002C99, 0x00000A10, 0x000500C5, 0x0000000B, + 0x00003C07, 0x00003A25, 0x00004739, 0x000400C8, 0x0000000B, 0x00002F7F, 0x00003EB6, 0x000500C7, + 0x0000000B, 0x00004855, 0x00003C07, 0x00002F7F, 0x000500C5, 0x0000000B, 0x00001871, 0x00004855, + 0x00004FBE, 0x000200F9, 0x00002DD0, 0x000200F8, 0x000055AB, 0x000500C7, 0x0000000B, 0x00004E74, + 0x000040ED, 0x000009E9, 0x000500C7, 0x0000000B, 0x00005D6B, 0x000040ED, 0x000009C8, 0x000500C2, + 0x0000000B, 0x000056EC, 0x00005D6B, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00005DC5, 0x00004E74, + 0x000056EC, 0x000500C7, 0x0000000B, 0x00004C94, 0x000040ED, 0x00000986, 0x000500C2, 0x0000000B, + 0x0000508C, 0x00004C94, 0x00000A10, 0x000500C5, 0x0000000B, 0x00005EE4, 0x00005DC5, 0x0000508C, + 0x000500C6, 0x0000000B, 0x00001E34, 0x00005EE4, 0x000009E9, 0x000400C8, 0x0000000B, 0x0000254F, + 0x000056EC, 0x000500C7, 0x0000000B, 0x00003928, 0x00004E74, 0x0000254F, 0x000400C8, 0x0000000B, + 0x000020F4, 0x0000508C, 0x000500C7, 0x0000000B, 0x00002C9A, 0x00003928, 0x000020F4, 0x000500C5, + 0x0000000B, 0x00001A9A, 0x000040ED, 0x00001E34, 0x00050082, 0x0000000B, 0x00004C40, 0x00001A9A, + 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A26, 0x00004C40, 0x00002C9A, 0x000500C4, 0x0000000B, + 0x000046ED, 0x00002C9A, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00003E8D, 0x00003A26, 0x000046ED, + 0x000500C4, 0x0000000B, 0x00001FBB, 0x00002C9A, 0x00000A10, 0x000500C5, 0x0000000B, 0x00001E85, + 0x00003E8D, 0x00001FBB, 0x000200F9, 0x00002DD0, 0x000200F8, 0x00002DD0, 0x000700F5, 0x0000000B, + 0x00005027, 0x00001871, 0x0000299D, 0x00001E85, 0x000055AB, 0x00050051, 0x0000000B, 0x000040EE, + 0x00003D28, 0x00000002, 0x000300F7, 0x00002DD1, 0x00000000, 0x000400FA, 0x00004E85, 0x0000299E, + 0x000055AD, 0x000200F8, 0x0000299E, 0x000500C7, 0x0000000B, 0x00004507, 0x000040EE, 0x000009C8, + 0x000500C7, 0x0000000B, 0x00005D9A, 0x000040EE, 0x00000986, 0x000500C2, 0x0000000B, 0x00005562, + 0x00005D9A, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FD3, 0x00004507, 0x00005562, 0x000500C4, + 0x0000000B, 0x0000602F, 0x00001FD3, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059BA, 0x00001FD3, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004970, 0x0000602F, 0x000059BA, 0x000500C5, 0x0000000B, + 0x00003EB7, 0x00001FD3, 0x00004970, 0x000500C7, 0x0000000B, 0x0000478B, 0x000040EE, 0x000009E9, + 0x000500C5, 0x0000000B, 0x00003963, 0x0000478B, 0x00000944, 0x000500C7, 0x0000000B, 0x00004FBF, + 0x00003963, 0x00003EB7, 0x000500C2, 0x0000000B, 0x00005041, 0x00004507, 0x00000A0D, 0x000500C5, + 0x0000000B, 0x00006160, 0x0000478B, 0x00005041, 0x000500C2, 0x0000000B, 0x000055AC, 0x00005D9A, + 0x00000A10, 0x000500C5, 0x0000000B, 0x00005898, 0x00006160, 0x000055AC, 0x000500C6, 0x0000000B, + 0x00001E35, 0x00005898, 0x000009E9, 0x000400C8, 0x0000000B, 0x00002550, 0x00005041, 0x000500C7, + 0x0000000B, 0x00003929, 0x0000478B, 0x00002550, 0x000400C8, 0x0000000B, 0x000020F5, 0x000055AC, + 0x000500C7, 0x0000000B, 0x00002C9B, 0x00003929, 0x000020F5, 0x000500C5, 0x0000000B, 0x00001A9B, + 0x000040EE, 0x00001E35, 0x00050082, 0x0000000B, 0x00004C41, 0x00001A9B, 0x000009E9, 0x000500C5, + 0x0000000B, 0x00003A27, 0x00004C41, 0x00002C9B, 0x000500C4, 0x0000000B, 0x0000473A, 0x00002C9B, + 0x00000A10, 0x000500C5, 0x0000000B, 0x00003C08, 0x00003A27, 0x0000473A, 0x000400C8, 0x0000000B, + 0x00002F80, 0x00003EB7, 0x000500C7, 0x0000000B, 0x00004856, 0x00003C08, 0x00002F80, 0x000500C5, + 0x0000000B, 0x00001872, 0x00004856, 0x00004FBF, 0x000200F9, 0x00002DD1, 0x000200F8, 0x000055AD, + 0x000500C7, 0x0000000B, 0x00004E75, 0x000040EE, 0x000009E9, 0x000500C7, 0x0000000B, 0x00005D6C, + 0x000040EE, 0x000009C8, 0x000500C2, 0x0000000B, 0x000056ED, 0x00005D6C, 0x00000A0D, 0x000500C5, + 0x0000000B, 0x00005DC6, 0x00004E75, 0x000056ED, 0x000500C7, 0x0000000B, 0x00004C95, 0x000040EE, + 0x00000986, 0x000500C2, 0x0000000B, 0x0000508D, 0x00004C95, 0x00000A10, 0x000500C5, 0x0000000B, + 0x00005EE5, 0x00005DC6, 0x0000508D, 0x000500C6, 0x0000000B, 0x00001E36, 0x00005EE5, 0x000009E9, + 0x000400C8, 0x0000000B, 0x00002551, 0x000056ED, 0x000500C7, 0x0000000B, 0x0000392A, 0x00004E75, + 0x00002551, 0x000400C8, 0x0000000B, 0x000020F6, 0x0000508D, 0x000500C7, 0x0000000B, 0x00002C9C, + 0x0000392A, 0x000020F6, 0x000500C5, 0x0000000B, 0x00001A9C, 0x000040EE, 0x00001E36, 0x00050082, + 0x0000000B, 0x00004C42, 0x00001A9C, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A28, 0x00004C42, + 0x00002C9C, 0x000500C4, 0x0000000B, 0x000046EE, 0x00002C9C, 0x00000A0D, 0x000500C5, 0x0000000B, + 0x00003E8E, 0x00003A28, 0x000046EE, 0x000500C4, 0x0000000B, 0x00001FBC, 0x00002C9C, 0x00000A10, + 0x000500C5, 0x0000000B, 0x00001E86, 0x00003E8E, 0x00001FBC, 0x000200F9, 0x00002DD1, 0x000200F8, + 0x00002DD1, 0x000700F5, 0x0000000B, 0x00005028, 0x00001872, 0x0000299E, 0x00001E86, 0x000055AD, + 0x00050051, 0x0000000B, 0x000040EF, 0x00003D28, 0x00000003, 0x000300F7, 0x00002DB8, 0x00000000, + 0x000400FA, 0x00004E86, 0x0000299F, 0x000055CF, 0x000200F8, 0x0000299F, 0x000500C7, 0x0000000B, + 0x00004508, 0x000040EF, 0x000009C8, 0x000500C7, 0x0000000B, 0x00005D9B, 0x000040EF, 0x00000986, + 0x000500C2, 0x0000000B, 0x00005563, 0x00005D9B, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FD4, + 0x00004508, 0x00005563, 0x000500C4, 0x0000000B, 0x00006030, 0x00001FD4, 0x00000A0D, 0x000500C2, + 0x0000000B, 0x000059BB, 0x00001FD4, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004971, 0x00006030, + 0x000059BB, 0x000500C5, 0x0000000B, 0x00003EB8, 0x00001FD4, 0x00004971, 0x000500C7, 0x0000000B, + 0x0000478C, 0x000040EF, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003964, 0x0000478C, 0x00000944, + 0x000500C7, 0x0000000B, 0x00004FC0, 0x00003964, 0x00003EB8, 0x000500C2, 0x0000000B, 0x00005042, + 0x00004508, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00006161, 0x0000478C, 0x00005042, 0x000500C2, + 0x0000000B, 0x000055AE, 0x00005D9B, 0x00000A10, 0x000500C5, 0x0000000B, 0x00005899, 0x00006161, + 0x000055AE, 0x000500C6, 0x0000000B, 0x00001E37, 0x00005899, 0x000009E9, 0x000400C8, 0x0000000B, + 0x00002552, 0x00005042, 0x000500C7, 0x0000000B, 0x0000392B, 0x0000478C, 0x00002552, 0x000400C8, + 0x0000000B, 0x000020F7, 0x000055AE, 0x000500C7, 0x0000000B, 0x00002C9D, 0x0000392B, 0x000020F7, + 0x000500C5, 0x0000000B, 0x00001A9E, 0x000040EF, 0x00001E37, 0x00050082, 0x0000000B, 0x00004C43, + 0x00001A9E, 0x000009E9, 0x000500C5, 0x0000000B, 0x00003A29, 0x00004C43, 0x00002C9D, 0x000500C4, + 0x0000000B, 0x0000473B, 0x00002C9D, 0x00000A10, 0x000500C5, 0x0000000B, 0x00003C09, 0x00003A29, + 0x0000473B, 0x000400C8, 0x0000000B, 0x00002F81, 0x00003EB8, 0x000500C7, 0x0000000B, 0x00004857, + 0x00003C09, 0x00002F81, 0x000500C5, 0x0000000B, 0x00001873, 0x00004857, 0x00004FC0, 0x000200F9, + 0x00002DB8, 0x000200F8, 0x000055CF, 0x000500C7, 0x0000000B, 0x00004E76, 0x000040EF, 0x000009E9, + 0x000500C7, 0x0000000B, 0x00005D6D, 0x000040EF, 0x000009C8, 0x000500C2, 0x0000000B, 0x000056EE, + 0x00005D6D, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00005DC7, 0x00004E76, 0x000056EE, 0x000500C7, + 0x0000000B, 0x00004C96, 0x000040EF, 0x00000986, 0x000500C2, 0x0000000B, 0x0000508E, 0x00004C96, + 0x00000A10, 0x000500C5, 0x0000000B, 0x00005EE6, 0x00005DC7, 0x0000508E, 0x000500C6, 0x0000000B, + 0x00001E38, 0x00005EE6, 0x000009E9, 0x000400C8, 0x0000000B, 0x00002553, 0x000056EE, 0x000500C7, + 0x0000000B, 0x0000392C, 0x00004E76, 0x00002553, 0x000400C8, 0x0000000B, 0x000020F8, 0x0000508E, + 0x000500C7, 0x0000000B, 0x00002C9E, 0x0000392C, 0x000020F8, 0x000500C5, 0x0000000B, 0x00001A9F, + 0x000040EF, 0x00001E38, 0x00050082, 0x0000000B, 0x00004C44, 0x00001A9F, 0x000009E9, 0x000500C5, + 0x0000000B, 0x00003A2A, 0x00004C44, 0x00002C9E, 0x000500C4, 0x0000000B, 0x000046EF, 0x00002C9E, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x00003E8F, 0x00003A2A, 0x000046EF, 0x000500C4, 0x0000000B, + 0x00001FBD, 0x00002C9E, 0x00000A10, 0x000500C5, 0x0000000B, 0x00001E87, 0x00003E8F, 0x00001FBD, + 0x000200F9, 0x00002DB8, 0x000200F8, 0x00002DB8, 0x000700F5, 0x0000000B, 0x000050D0, 0x00001873, + 0x0000299F, 0x00001E87, 0x000055CF, 0x00070050, 0x00000017, 0x000060EC, 0x00005026, 0x00005027, + 0x00005028, 0x000050D0, 0x000300F7, 0x00003A2B, 0x00000000, 0x000400FA, 0x00004E83, 0x000029A0, + 0x000038C6, 0x000200F8, 0x000029A0, 0x000500C7, 0x0000000B, 0x00004509, 0x00005026, 0x0000003A, + 0x000500C7, 0x0000000B, 0x00005D9C, 0x00005026, 0x0000022D, 0x000500C2, 0x0000000B, 0x00005564, + 0x00005D9C, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FD5, 0x00004509, 0x00005564, 0x000500C4, + 0x0000000B, 0x00006031, 0x00001FD5, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059BC, 0x00001FD5, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004984, 0x00006031, 0x000059BC, 0x000500C5, 0x0000000B, + 0x00003E32, 0x00001FD5, 0x00004984, 0x000400C8, 0x0000000B, 0x00002113, 0x00003E32, 0x000500C7, + 0x0000000B, 0x0000276A, 0x00005026, 0x00002113, 0x00050082, 0x0000000B, 0x00003FB4, 0x00000908, + 0x0000276A, 0x000500C7, 0x0000000B, 0x00004410, 0x00003FB4, 0x00002113, 0x000500C7, 0x0000000B, + 0x00004267, 0x00004410, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003575, 0x00001966, 0x00004267, + 0x000500C7, 0x0000000B, 0x000055E7, 0x0000276A, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FC1, + 0x00003330, 0x000055E7, 0x00050080, 0x0000000B, 0x00004D93, 0x00003575, 0x00004FC1, 0x00050086, + 0x0000000B, 0x000032D8, 0x00004D93, 0x00000A19, 0x000500C2, 0x0000000B, 0x000059FE, 0x00004410, + 0x00000A13, 0x000500C7, 0x0000000B, 0x00002241, 0x000059FE, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003AD3, 0x00001966, 0x00002241, 0x000500C2, 0x0000000B, 0x00003414, 0x0000276A, 0x00000A13, + 0x000500C7, 0x0000000B, 0x000061AD, 0x00003414, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000629A, + 0x00003330, 0x000061AD, 0x00050080, 0x0000000B, 0x00004DD8, 0x00003AD3, 0x0000629A, 0x00050086, + 0x0000000B, 0x00003178, 0x00004DD8, 0x00000A19, 0x000500C4, 0x0000000B, 0x00002000, 0x00003178, + 0x00000A22, 0x000500C5, 0x0000000B, 0x00001DA1, 0x000032D8, 0x00002000, 0x000500C2, 0x0000000B, + 0x000055D0, 0x00004410, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044DA, 0x000055D0, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AD4, 0x00001966, 0x000044DA, 0x000500C2, 0x0000000B, 0x00003415, + 0x0000276A, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061AE, 0x00003415, 0x00000A1F, 0x00050084, + 0x0000000B, 0x0000629B, 0x00003330, 0x000061AE, 0x00050080, 0x0000000B, 0x00004DD9, 0x00003AD4, + 0x0000629B, 0x00050086, 0x0000000B, 0x00003179, 0x00004DD9, 0x00000A19, 0x000500C4, 0x0000000B, + 0x00002001, 0x00003179, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001DA2, 0x00001DA1, 0x00002001, + 0x000500C2, 0x0000000B, 0x000055D1, 0x00004410, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044DB, + 0x000055D1, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AD5, 0x00001966, 0x000044DB, 0x000500C2, + 0x0000000B, 0x00003418, 0x0000276A, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061AF, 0x00003418, + 0x00000A1F, 0x00050084, 0x0000000B, 0x0000629C, 0x00003330, 0x000061AF, 0x00050080, 0x0000000B, + 0x00004DDA, 0x00003AD5, 0x0000629C, 0x00050086, 0x0000000B, 0x0000317A, 0x00004DDA, 0x00000A19, + 0x000500C4, 0x0000000B, 0x00002048, 0x0000317A, 0x00000A52, 0x000500C5, 0x0000000B, 0x00001A28, + 0x00001DA2, 0x00002048, 0x000500C7, 0x0000000B, 0x00004FC2, 0x00005026, 0x00003E32, 0x000500C7, + 0x0000000B, 0x00004412, 0x00004FC2, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C6F, 0x00004FC2, + 0x00000A22, 0x000500C4, 0x0000000B, 0x0000616C, 0x00004C6F, 0x00000A19, 0x000500C5, 0x0000000B, + 0x000042CD, 0x00004412, 0x0000616C, 0x000500C7, 0x0000000B, 0x00005192, 0x00004FC2, 0x00000ACA, + 0x000500C4, 0x0000000B, 0x00005B1F, 0x00005192, 0x00000A28, 0x000500C5, 0x0000000B, 0x000042CE, + 0x000042CD, 0x00005B1F, 0x000500C7, 0x0000000B, 0x00005193, 0x00004FC2, 0x00000447, 0x000500C4, + 0x0000000B, 0x00005626, 0x00005193, 0x00000A37, 0x000500C5, 0x0000000B, 0x0000207F, 0x000042CE, + 0x00005626, 0x00050084, 0x0000000B, 0x000028BB, 0x0000207F, 0x00000144, 0x00050080, 0x0000000B, + 0x00004807, 0x00001A28, 0x000028BB, 0x000200F9, 0x00003A2B, 0x000200F8, 0x000038C6, 0x000400C8, + 0x0000000B, 0x000029DC, 0x00005026, 0x000500C7, 0x0000000B, 0x00003C0A, 0x000029DC, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00004538, 0x00001966, 0x00003C0A, 0x000500C7, 0x0000000B, 0x000055E9, + 0x00005026, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FC3, 0x00003330, 0x000055E9, 0x00050080, + 0x0000000B, 0x00004D94, 0x00004538, 0x00004FC3, 0x00050086, 0x0000000B, 0x000032D9, 0x00004D94, + 0x00000A1F, 0x000500C2, 0x0000000B, 0x000059FF, 0x000029DC, 0x00000A13, 0x000500C7, 0x0000000B, + 0x00002242, 0x000059FF, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AD6, 0x00001966, 0x00002242, + 0x000500C2, 0x0000000B, 0x00003419, 0x00005026, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061B0, + 0x00003419, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000629D, 0x00003330, 0x000061B0, 0x00050080, + 0x0000000B, 0x00004DDB, 0x00003AD6, 0x0000629D, 0x00050086, 0x0000000B, 0x0000317B, 0x00004DDB, + 0x00000A1F, 0x000500C4, 0x0000000B, 0x00002002, 0x0000317B, 0x00000A22, 0x000500C5, 0x0000000B, + 0x00001DA3, 0x000032D9, 0x00002002, 0x000500C2, 0x0000000B, 0x000055D2, 0x000029DC, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x000044DC, 0x000055D2, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AD7, + 0x00001966, 0x000044DC, 0x000500C2, 0x0000000B, 0x0000341A, 0x00005026, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x000061B1, 0x0000341A, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000629E, 0x00003330, + 0x000061B1, 0x00050080, 0x0000000B, 0x00004DDC, 0x00003AD7, 0x0000629E, 0x00050086, 0x0000000B, + 0x0000317C, 0x00004DDC, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00002003, 0x0000317C, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x00001DA4, 0x00001DA3, 0x00002003, 0x000500C2, 0x0000000B, 0x000055D3, + 0x000029DC, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044DD, 0x000055D3, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AD8, 0x00001966, 0x000044DD, 0x000500C2, 0x0000000B, 0x0000341B, 0x00005026, + 0x00000A25, 0x000500C7, 0x0000000B, 0x000061B2, 0x0000341B, 0x00000A1F, 0x00050084, 0x0000000B, + 0x0000629F, 0x00003330, 0x000061B2, 0x00050080, 0x0000000B, 0x00004DDD, 0x00003AD8, 0x0000629F, + 0x00050086, 0x0000000B, 0x0000317D, 0x00004DDD, 0x00000A1F, 0x000500C4, 0x0000000B, 0x000023FD, + 0x0000317D, 0x00000A52, 0x000500C5, 0x0000000B, 0x00004680, 0x00001DA4, 0x000023FD, 0x000200F9, + 0x00003A2B, 0x000200F8, 0x00003A2B, 0x000700F5, 0x0000000B, 0x00002AB0, 0x00004807, 0x000029A0, + 0x00004680, 0x000038C6, 0x000300F7, 0x00003A2C, 0x00000000, 0x000400FA, 0x00004E84, 0x000029A1, + 0x000038C7, 0x000200F8, 0x000029A1, 0x000500C7, 0x0000000B, 0x0000450A, 0x00005027, 0x0000003A, + 0x000500C7, 0x0000000B, 0x00005D9D, 0x00005027, 0x0000022D, 0x000500C2, 0x0000000B, 0x00005565, + 0x00005D9D, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FD6, 0x0000450A, 0x00005565, 0x000500C4, + 0x0000000B, 0x00006032, 0x00001FD6, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059BD, 0x00001FD6, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004985, 0x00006032, 0x000059BD, 0x000500C5, 0x0000000B, + 0x00003E33, 0x00001FD6, 0x00004985, 0x000400C8, 0x0000000B, 0x00002114, 0x00003E33, 0x000500C7, + 0x0000000B, 0x0000276B, 0x00005027, 0x00002114, 0x00050082, 0x0000000B, 0x00003FB5, 0x00000908, + 0x0000276B, 0x000500C7, 0x0000000B, 0x00004413, 0x00003FB5, 0x00002114, 0x000500C7, 0x0000000B, + 0x00004268, 0x00004413, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003576, 0x00003281, 0x00004268, + 0x000500C7, 0x0000000B, 0x000055EA, 0x0000276B, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FC4, + 0x00003331, 0x000055EA, 0x00050080, 0x0000000B, 0x00004D95, 0x00003576, 0x00004FC4, 0x00050086, + 0x0000000B, 0x000032DA, 0x00004D95, 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A00, 0x00004413, + 0x00000A13, 0x000500C7, 0x0000000B, 0x00002243, 0x00005A00, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003AD9, 0x00003281, 0x00002243, 0x000500C2, 0x0000000B, 0x0000341C, 0x0000276B, 0x00000A13, + 0x000500C7, 0x0000000B, 0x000061B3, 0x0000341C, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062A0, + 0x00003331, 0x000061B3, 0x00050080, 0x0000000B, 0x00004DDE, 0x00003AD9, 0x000062A0, 0x00050086, + 0x0000000B, 0x0000317E, 0x00004DDE, 0x00000A19, 0x000500C4, 0x0000000B, 0x00002004, 0x0000317E, + 0x00000A22, 0x000500C5, 0x0000000B, 0x00001DA5, 0x000032DA, 0x00002004, 0x000500C2, 0x0000000B, + 0x000055D4, 0x00004413, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044DE, 0x000055D4, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003ADA, 0x00003281, 0x000044DE, 0x000500C2, 0x0000000B, 0x0000341D, + 0x0000276B, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061B4, 0x0000341D, 0x00000A1F, 0x00050084, + 0x0000000B, 0x000062A1, 0x00003331, 0x000061B4, 0x00050080, 0x0000000B, 0x00004DDF, 0x00003ADA, + 0x000062A1, 0x00050086, 0x0000000B, 0x0000317F, 0x00004DDF, 0x00000A19, 0x000500C4, 0x0000000B, + 0x00002005, 0x0000317F, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001DA6, 0x00001DA5, 0x00002005, + 0x000500C2, 0x0000000B, 0x000055D5, 0x00004413, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044DF, + 0x000055D5, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ADB, 0x00003281, 0x000044DF, 0x000500C2, + 0x0000000B, 0x0000341E, 0x0000276B, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061B5, 0x0000341E, + 0x00000A1F, 0x00050084, 0x0000000B, 0x000062A2, 0x00003331, 0x000061B5, 0x00050080, 0x0000000B, + 0x00004DE0, 0x00003ADB, 0x000062A2, 0x00050086, 0x0000000B, 0x00003180, 0x00004DE0, 0x00000A19, + 0x000500C4, 0x0000000B, 0x00002049, 0x00003180, 0x00000A52, 0x000500C5, 0x0000000B, 0x00001A29, + 0x00001DA6, 0x00002049, 0x000500C7, 0x0000000B, 0x00004FC5, 0x00005027, 0x00003E33, 0x000500C7, + 0x0000000B, 0x00004414, 0x00004FC5, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C70, 0x00004FC5, + 0x00000A22, 0x000500C4, 0x0000000B, 0x0000616D, 0x00004C70, 0x00000A19, 0x000500C5, 0x0000000B, + 0x000042CF, 0x00004414, 0x0000616D, 0x000500C7, 0x0000000B, 0x00005194, 0x00004FC5, 0x00000ACA, + 0x000500C4, 0x0000000B, 0x00005B20, 0x00005194, 0x00000A28, 0x000500C5, 0x0000000B, 0x000042D0, + 0x000042CF, 0x00005B20, 0x000500C7, 0x0000000B, 0x00005195, 0x00004FC5, 0x00000447, 0x000500C4, + 0x0000000B, 0x00005627, 0x00005195, 0x00000A37, 0x000500C5, 0x0000000B, 0x00002080, 0x000042D0, + 0x00005627, 0x00050084, 0x0000000B, 0x000028BC, 0x00002080, 0x00000144, 0x00050080, 0x0000000B, + 0x00004808, 0x00001A29, 0x000028BC, 0x000200F9, 0x00003A2C, 0x000200F8, 0x000038C7, 0x000400C8, + 0x0000000B, 0x000029DD, 0x00005027, 0x000500C7, 0x0000000B, 0x00003C0B, 0x000029DD, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00004539, 0x00003281, 0x00003C0B, 0x000500C7, 0x0000000B, 0x000055EB, + 0x00005027, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FC6, 0x00003331, 0x000055EB, 0x00050080, + 0x0000000B, 0x00004D96, 0x00004539, 0x00004FC6, 0x00050086, 0x0000000B, 0x000032DB, 0x00004D96, + 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A01, 0x000029DD, 0x00000A13, 0x000500C7, 0x0000000B, + 0x00002244, 0x00005A01, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ADC, 0x00003281, 0x00002244, + 0x000500C2, 0x0000000B, 0x0000341F, 0x00005027, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061B6, + 0x0000341F, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062A3, 0x00003331, 0x000061B6, 0x00050080, + 0x0000000B, 0x00004DE1, 0x00003ADC, 0x000062A3, 0x00050086, 0x0000000B, 0x00003181, 0x00004DE1, + 0x00000A1F, 0x000500C4, 0x0000000B, 0x00002006, 0x00003181, 0x00000A22, 0x000500C5, 0x0000000B, + 0x00001DA7, 0x000032DB, 0x00002006, 0x000500C2, 0x0000000B, 0x000055D6, 0x000029DD, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x000044E0, 0x000055D6, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003ADD, + 0x00003281, 0x000044E0, 0x000500C2, 0x0000000B, 0x00003420, 0x00005027, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x000061B7, 0x00003420, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062A4, 0x00003331, + 0x000061B7, 0x00050080, 0x0000000B, 0x00004DE2, 0x00003ADD, 0x000062A4, 0x00050086, 0x0000000B, + 0x00003182, 0x00004DE2, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00002007, 0x00003182, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x00001DA8, 0x00001DA7, 0x00002007, 0x000500C2, 0x0000000B, 0x000055EC, + 0x000029DD, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044E1, 0x000055EC, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003ADE, 0x00003281, 0x000044E1, 0x000500C2, 0x0000000B, 0x00003421, 0x00005027, + 0x00000A25, 0x000500C7, 0x0000000B, 0x000061B8, 0x00003421, 0x00000A1F, 0x00050084, 0x0000000B, + 0x000062A5, 0x00003331, 0x000061B8, 0x00050080, 0x0000000B, 0x00004DE3, 0x00003ADE, 0x000062A5, + 0x00050086, 0x0000000B, 0x00003183, 0x00004DE3, 0x00000A1F, 0x000500C4, 0x0000000B, 0x000023FE, + 0x00003183, 0x00000A52, 0x000500C5, 0x0000000B, 0x00004681, 0x00001DA8, 0x000023FE, 0x000200F9, + 0x00003A2C, 0x000200F8, 0x00003A2C, 0x000700F5, 0x0000000B, 0x00002AB1, 0x00004808, 0x000029A1, + 0x00004681, 0x000038C7, 0x000300F7, 0x00003A2D, 0x00000000, 0x000400FA, 0x00004E85, 0x000029A2, + 0x000038C8, 0x000200F8, 0x000029A2, 0x000500C7, 0x0000000B, 0x0000450B, 0x00005028, 0x0000003A, + 0x000500C7, 0x0000000B, 0x00005D9E, 0x00005028, 0x0000022D, 0x000500C2, 0x0000000B, 0x00005566, + 0x00005D9E, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FD7, 0x0000450B, 0x00005566, 0x000500C4, + 0x0000000B, 0x00006033, 0x00001FD7, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059BE, 0x00001FD7, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004986, 0x00006033, 0x000059BE, 0x000500C5, 0x0000000B, + 0x00003E34, 0x00001FD7, 0x00004986, 0x000400C8, 0x0000000B, 0x00002115, 0x00003E34, 0x000500C7, + 0x0000000B, 0x0000276C, 0x00005028, 0x00002115, 0x00050082, 0x0000000B, 0x00003FB6, 0x00000908, + 0x0000276C, 0x000500C7, 0x0000000B, 0x00004415, 0x00003FB6, 0x00002115, 0x000500C7, 0x0000000B, + 0x00004269, 0x00004415, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003577, 0x00003282, 0x00004269, + 0x000500C7, 0x0000000B, 0x000055ED, 0x0000276C, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FC8, + 0x00003333, 0x000055ED, 0x00050080, 0x0000000B, 0x00004D97, 0x00003577, 0x00004FC8, 0x00050086, + 0x0000000B, 0x000032DC, 0x00004D97, 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A02, 0x00004415, + 0x00000A13, 0x000500C7, 0x0000000B, 0x00002245, 0x00005A02, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003ADF, 0x00003282, 0x00002245, 0x000500C2, 0x0000000B, 0x00003422, 0x0000276C, 0x00000A13, + 0x000500C7, 0x0000000B, 0x000061B9, 0x00003422, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062A6, + 0x00003333, 0x000061B9, 0x00050080, 0x0000000B, 0x00004DE4, 0x00003ADF, 0x000062A6, 0x00050086, + 0x0000000B, 0x00003184, 0x00004DE4, 0x00000A19, 0x000500C4, 0x0000000B, 0x00002008, 0x00003184, + 0x00000A22, 0x000500C5, 0x0000000B, 0x00001DA9, 0x000032DC, 0x00002008, 0x000500C2, 0x0000000B, + 0x000055EE, 0x00004415, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044E2, 0x000055EE, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AE0, 0x00003282, 0x000044E2, 0x000500C2, 0x0000000B, 0x00003423, + 0x0000276C, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061BA, 0x00003423, 0x00000A1F, 0x00050084, + 0x0000000B, 0x000062A7, 0x00003333, 0x000061BA, 0x00050080, 0x0000000B, 0x00004DE5, 0x00003AE0, + 0x000062A7, 0x00050086, 0x0000000B, 0x00003185, 0x00004DE5, 0x00000A19, 0x000500C4, 0x0000000B, + 0x00002009, 0x00003185, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001DAA, 0x00001DA9, 0x00002009, + 0x000500C2, 0x0000000B, 0x000055EF, 0x00004415, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044E3, + 0x000055EF, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AE1, 0x00003282, 0x000044E3, 0x000500C2, + 0x0000000B, 0x00003424, 0x0000276C, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061BB, 0x00003424, + 0x00000A1F, 0x00050084, 0x0000000B, 0x000062A8, 0x00003333, 0x000061BB, 0x00050080, 0x0000000B, + 0x00004DE6, 0x00003AE1, 0x000062A8, 0x00050086, 0x0000000B, 0x00003186, 0x00004DE6, 0x00000A19, + 0x000500C4, 0x0000000B, 0x0000204A, 0x00003186, 0x00000A52, 0x000500C5, 0x0000000B, 0x00001A2A, + 0x00001DAA, 0x0000204A, 0x000500C7, 0x0000000B, 0x00004FC9, 0x00005028, 0x00003E34, 0x000500C7, + 0x0000000B, 0x00004416, 0x00004FC9, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C71, 0x00004FC9, + 0x00000A22, 0x000500C4, 0x0000000B, 0x0000616E, 0x00004C71, 0x00000A19, 0x000500C5, 0x0000000B, + 0x000042D1, 0x00004416, 0x0000616E, 0x000500C7, 0x0000000B, 0x00005196, 0x00004FC9, 0x00000ACA, + 0x000500C4, 0x0000000B, 0x00005B21, 0x00005196, 0x00000A28, 0x000500C5, 0x0000000B, 0x000042D2, + 0x000042D1, 0x00005B21, 0x000500C7, 0x0000000B, 0x00005197, 0x00004FC9, 0x00000447, 0x000500C4, + 0x0000000B, 0x00005628, 0x00005197, 0x00000A37, 0x000500C5, 0x0000000B, 0x00002081, 0x000042D2, + 0x00005628, 0x00050084, 0x0000000B, 0x000028BD, 0x00002081, 0x00000144, 0x00050080, 0x0000000B, + 0x00004809, 0x00001A2A, 0x000028BD, 0x000200F9, 0x00003A2D, 0x000200F8, 0x000038C8, 0x000400C8, + 0x0000000B, 0x000029DE, 0x00005028, 0x000500C7, 0x0000000B, 0x00003C0C, 0x000029DE, 0x00000A1F, + 0x00050084, 0x0000000B, 0x0000453A, 0x00003282, 0x00003C0C, 0x000500C7, 0x0000000B, 0x000055F0, + 0x00005028, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FCA, 0x00003333, 0x000055F0, 0x00050080, + 0x0000000B, 0x00004D98, 0x0000453A, 0x00004FCA, 0x00050086, 0x0000000B, 0x000032DD, 0x00004D98, + 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A03, 0x000029DE, 0x00000A13, 0x000500C7, 0x0000000B, + 0x00002246, 0x00005A03, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AE2, 0x00003282, 0x00002246, + 0x000500C2, 0x0000000B, 0x00003425, 0x00005028, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061BC, + 0x00003425, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062A9, 0x00003333, 0x000061BC, 0x00050080, + 0x0000000B, 0x00004DE7, 0x00003AE2, 0x000062A9, 0x00050086, 0x0000000B, 0x00003187, 0x00004DE7, + 0x00000A1F, 0x000500C4, 0x0000000B, 0x0000200A, 0x00003187, 0x00000A22, 0x000500C5, 0x0000000B, + 0x00001DAB, 0x000032DD, 0x0000200A, 0x000500C2, 0x0000000B, 0x000055F1, 0x000029DE, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x000044E4, 0x000055F1, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AE3, + 0x00003282, 0x000044E4, 0x000500C2, 0x0000000B, 0x00003426, 0x00005028, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x000061BD, 0x00003426, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062AA, 0x00003333, + 0x000061BD, 0x00050080, 0x0000000B, 0x00004DE8, 0x00003AE3, 0x000062AA, 0x00050086, 0x0000000B, + 0x00003188, 0x00004DE8, 0x00000A1F, 0x000500C4, 0x0000000B, 0x0000200B, 0x00003188, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x00001DAC, 0x00001DAB, 0x0000200B, 0x000500C2, 0x0000000B, 0x000055F2, + 0x000029DE, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044E5, 0x000055F2, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AE4, 0x00003282, 0x000044E5, 0x000500C2, 0x0000000B, 0x00003427, 0x00005028, + 0x00000A25, 0x000500C7, 0x0000000B, 0x000061BE, 0x00003427, 0x00000A1F, 0x00050084, 0x0000000B, + 0x000062AB, 0x00003333, 0x000061BE, 0x00050080, 0x0000000B, 0x00004DE9, 0x00003AE4, 0x000062AB, + 0x00050086, 0x0000000B, 0x00003189, 0x00004DE9, 0x00000A1F, 0x000500C4, 0x0000000B, 0x000023FF, + 0x00003189, 0x00000A52, 0x000500C5, 0x0000000B, 0x00004682, 0x00001DAC, 0x000023FF, 0x000200F9, + 0x00003A2D, 0x000200F8, 0x00003A2D, 0x000700F5, 0x0000000B, 0x00002AB2, 0x00004809, 0x000029A2, + 0x00004682, 0x000038C8, 0x000300F7, 0x00002DB9, 0x00000000, 0x000400FA, 0x00004E86, 0x000029A3, + 0x000038C9, 0x000200F8, 0x000029A3, 0x000500C7, 0x0000000B, 0x0000450C, 0x000050D0, 0x0000003A, + 0x000500C7, 0x0000000B, 0x00005D9F, 0x000050D0, 0x0000022D, 0x000500C2, 0x0000000B, 0x00005567, + 0x00005D9F, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FD8, 0x0000450C, 0x00005567, 0x000500C4, + 0x0000000B, 0x00006034, 0x00001FD8, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059BF, 0x00001FD8, + 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004987, 0x00006034, 0x000059BF, 0x000500C5, 0x0000000B, + 0x00003E35, 0x00001FD8, 0x00004987, 0x000400C8, 0x0000000B, 0x00002116, 0x00003E35, 0x000500C7, + 0x0000000B, 0x0000276D, 0x000050D0, 0x00002116, 0x00050082, 0x0000000B, 0x00003FB7, 0x00000908, + 0x0000276D, 0x000500C7, 0x0000000B, 0x00004417, 0x00003FB7, 0x00002116, 0x000500C7, 0x0000000B, + 0x0000426A, 0x00004417, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003578, 0x00003283, 0x0000426A, + 0x000500C7, 0x0000000B, 0x000055F3, 0x0000276D, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FCB, + 0x00003334, 0x000055F3, 0x00050080, 0x0000000B, 0x00004D99, 0x00003578, 0x00004FCB, 0x00050086, + 0x0000000B, 0x000032DE, 0x00004D99, 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A04, 0x00004417, + 0x00000A13, 0x000500C7, 0x0000000B, 0x00002247, 0x00005A04, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003AE5, 0x00003283, 0x00002247, 0x000500C2, 0x0000000B, 0x00003428, 0x0000276D, 0x00000A13, + 0x000500C7, 0x0000000B, 0x000061BF, 0x00003428, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062AC, + 0x00003334, 0x000061BF, 0x00050080, 0x0000000B, 0x00004DEA, 0x00003AE5, 0x000062AC, 0x00050086, + 0x0000000B, 0x0000318A, 0x00004DEA, 0x00000A19, 0x000500C4, 0x0000000B, 0x0000200C, 0x0000318A, + 0x00000A22, 0x000500C5, 0x0000000B, 0x00001DAD, 0x000032DE, 0x0000200C, 0x000500C2, 0x0000000B, + 0x000055F4, 0x00004417, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044E6, 0x000055F4, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AE6, 0x00003283, 0x000044E6, 0x000500C2, 0x0000000B, 0x00003429, + 0x0000276D, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061C0, 0x00003429, 0x00000A1F, 0x00050084, + 0x0000000B, 0x000062AD, 0x00003334, 0x000061C0, 0x00050080, 0x0000000B, 0x00004DEB, 0x00003AE6, + 0x000062AD, 0x00050086, 0x0000000B, 0x0000318B, 0x00004DEB, 0x00000A19, 0x000500C4, 0x0000000B, + 0x0000200D, 0x0000318B, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001DAE, 0x00001DAD, 0x0000200D, + 0x000500C2, 0x0000000B, 0x000055F5, 0x00004417, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044E7, + 0x000055F5, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AE7, 0x00003283, 0x000044E7, 0x000500C2, + 0x0000000B, 0x0000342A, 0x0000276D, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061C1, 0x0000342A, + 0x00000A1F, 0x00050084, 0x0000000B, 0x000062AE, 0x00003334, 0x000061C1, 0x00050080, 0x0000000B, + 0x00004DEC, 0x00003AE7, 0x000062AE, 0x00050086, 0x0000000B, 0x0000318C, 0x00004DEC, 0x00000A19, + 0x000500C4, 0x0000000B, 0x0000204B, 0x0000318C, 0x00000A52, 0x000500C5, 0x0000000B, 0x00001A2B, + 0x00001DAE, 0x0000204B, 0x000500C7, 0x0000000B, 0x00004FCC, 0x000050D0, 0x00003E35, 0x000500C7, + 0x0000000B, 0x00004418, 0x00004FCC, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C72, 0x00004FCC, + 0x00000A22, 0x000500C4, 0x0000000B, 0x0000616F, 0x00004C72, 0x00000A19, 0x000500C5, 0x0000000B, + 0x000042D3, 0x00004418, 0x0000616F, 0x000500C7, 0x0000000B, 0x00005198, 0x00004FCC, 0x00000ACA, + 0x000500C4, 0x0000000B, 0x00005B22, 0x00005198, 0x00000A28, 0x000500C5, 0x0000000B, 0x000042D4, + 0x000042D3, 0x00005B22, 0x000500C7, 0x0000000B, 0x00005199, 0x00004FCC, 0x00000447, 0x000500C4, + 0x0000000B, 0x00005629, 0x00005199, 0x00000A37, 0x000500C5, 0x0000000B, 0x00002082, 0x000042D4, + 0x00005629, 0x00050084, 0x0000000B, 0x000028BE, 0x00002082, 0x00000144, 0x00050080, 0x0000000B, + 0x0000480A, 0x00001A2B, 0x000028BE, 0x000200F9, 0x00002DB9, 0x000200F8, 0x000038C9, 0x000400C8, + 0x0000000B, 0x000029DF, 0x000050D0, 0x000500C7, 0x0000000B, 0x00003C0D, 0x000029DF, 0x00000A1F, + 0x00050084, 0x0000000B, 0x0000453B, 0x00003283, 0x00003C0D, 0x000500C7, 0x0000000B, 0x000055F6, + 0x000050D0, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FCD, 0x00003334, 0x000055F6, 0x00050080, + 0x0000000B, 0x00004D9A, 0x0000453B, 0x00004FCD, 0x00050086, 0x0000000B, 0x000032DF, 0x00004D9A, + 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A05, 0x000029DF, 0x00000A13, 0x000500C7, 0x0000000B, + 0x00002248, 0x00005A05, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AE8, 0x00003283, 0x00002248, + 0x000500C2, 0x0000000B, 0x0000342B, 0x000050D0, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061C2, + 0x0000342B, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062AF, 0x00003334, 0x000061C2, 0x00050080, + 0x0000000B, 0x00004DED, 0x00003AE8, 0x000062AF, 0x00050086, 0x0000000B, 0x0000318D, 0x00004DED, + 0x00000A1F, 0x000500C4, 0x0000000B, 0x0000200E, 0x0000318D, 0x00000A22, 0x000500C5, 0x0000000B, + 0x00001DAF, 0x000032DF, 0x0000200E, 0x000500C2, 0x0000000B, 0x000055F7, 0x000029DF, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x000044E8, 0x000055F7, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AE9, + 0x00003283, 0x000044E8, 0x000500C2, 0x0000000B, 0x0000342C, 0x000050D0, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x000061C3, 0x0000342C, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062B0, 0x00003334, + 0x000061C3, 0x00050080, 0x0000000B, 0x00004DEE, 0x00003AE9, 0x000062B0, 0x00050086, 0x0000000B, + 0x0000318E, 0x00004DEE, 0x00000A1F, 0x000500C4, 0x0000000B, 0x0000200F, 0x0000318E, 0x00000A3A, + 0x000500C5, 0x0000000B, 0x00001DB0, 0x00001DAF, 0x0000200F, 0x000500C2, 0x0000000B, 0x000055F8, + 0x000029DF, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044E9, 0x000055F8, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AEA, 0x00003283, 0x000044E9, 0x000500C2, 0x0000000B, 0x0000342D, 0x000050D0, + 0x00000A25, 0x000500C7, 0x0000000B, 0x000061C4, 0x0000342D, 0x00000A1F, 0x00050084, 0x0000000B, + 0x000062B1, 0x00003334, 0x000061C4, 0x00050080, 0x0000000B, 0x00004DEF, 0x00003AEA, 0x000062B1, + 0x00050086, 0x0000000B, 0x0000318F, 0x00004DEF, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00002400, + 0x0000318F, 0x00000A52, 0x000500C5, 0x0000000B, 0x00004683, 0x00001DB0, 0x00002400, 0x000200F9, + 0x00002DB9, 0x000200F8, 0x00002DB9, 0x000700F5, 0x0000000B, 0x0000434F, 0x0000480A, 0x000029A3, + 0x00004683, 0x000038C9, 0x00070050, 0x00000017, 0x000038F9, 0x00002AB0, 0x00002AB1, 0x00002AB2, + 0x0000434F, 0x00060041, 0x00000294, 0x00003336, 0x0000140E, 0x00000A0B, 0x00003417, 0x0003003E, + 0x00003336, 0x000038F9, 0x00050080, 0x0000000B, 0x000039F9, 0x00003220, 0x00000A14, 0x000500B0, + 0x00000009, 0x00002E0C, 0x000039F9, 0x000019C2, 0x000300F7, 0x00004665, 0x00000002, 0x000400FA, + 0x00002E0C, 0x0000592E, 0x00004665, 0x000200F8, 0x0000592E, 0x00050080, 0x0000000B, 0x0000342E, + 0x00003417, 0x00001B41, 0x000500C2, 0x00000017, 0x00003D29, 0x000060EC, 0x00000215, 0x00050051, + 0x0000000B, 0x00005D1D, 0x00003D29, 0x00000000, 0x000300F7, 0x00002DD2, 0x00000000, 0x000400FA, + 0x00004E83, 0x000029A4, 0x000038CA, 0x000200F8, 0x000029A4, 0x000500C7, 0x0000000B, 0x0000450D, + 0x00005D1D, 0x0000003A, 0x000500C7, 0x0000000B, 0x00005DA0, 0x00005D1D, 0x0000022D, 0x000500C2, + 0x0000000B, 0x00005568, 0x00005DA0, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FD9, 0x0000450D, + 0x00005568, 0x000500C4, 0x0000000B, 0x00006035, 0x00001FD9, 0x00000A0D, 0x000500C2, 0x0000000B, + 0x000059C0, 0x00001FD9, 0x00000A0D, 0x000500C5, 0x0000000B, 0x00004988, 0x00006035, 0x000059C0, + 0x000500C5, 0x0000000B, 0x00003E36, 0x00001FD9, 0x00004988, 0x000400C8, 0x0000000B, 0x00002117, + 0x00003E36, 0x000500C7, 0x0000000B, 0x0000276E, 0x00005D1D, 0x00002117, 0x00050082, 0x0000000B, + 0x00003FB8, 0x00000908, 0x0000276E, 0x000500C7, 0x0000000B, 0x00004419, 0x00003FB8, 0x00002117, + 0x000500C7, 0x0000000B, 0x0000426B, 0x00004419, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003579, + 0x00001966, 0x0000426B, 0x000500C7, 0x0000000B, 0x000055F9, 0x0000276E, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00004FCE, 0x00003330, 0x000055F9, 0x00050080, 0x0000000B, 0x00004D9B, 0x00003579, + 0x00004FCE, 0x00050086, 0x0000000B, 0x000032E0, 0x00004D9B, 0x00000A19, 0x000500C2, 0x0000000B, + 0x00005A06, 0x00004419, 0x00000A13, 0x000500C7, 0x0000000B, 0x00002249, 0x00005A06, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003AEB, 0x00001966, 0x00002249, 0x000500C2, 0x0000000B, 0x0000342F, + 0x0000276E, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061C5, 0x0000342F, 0x00000A1F, 0x00050084, + 0x0000000B, 0x000062B2, 0x00003330, 0x000061C5, 0x00050080, 0x0000000B, 0x00004DF0, 0x00003AEB, + 0x000062B2, 0x00050086, 0x0000000B, 0x00003190, 0x00004DF0, 0x00000A19, 0x000500C4, 0x0000000B, + 0x00002010, 0x00003190, 0x00000A22, 0x000500C5, 0x0000000B, 0x00001DB1, 0x000032E0, 0x00002010, + 0x000500C2, 0x0000000B, 0x000055FA, 0x00004419, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044EA, + 0x000055FA, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AEC, 0x00001966, 0x000044EA, 0x000500C2, + 0x0000000B, 0x00003430, 0x0000276E, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061C6, 0x00003430, + 0x00000A1F, 0x00050084, 0x0000000B, 0x000062B3, 0x00003330, 0x000061C6, 0x00050080, 0x0000000B, + 0x00004DF1, 0x00003AEC, 0x000062B3, 0x00050086, 0x0000000B, 0x00003191, 0x00004DF1, 0x00000A19, + 0x000500C4, 0x0000000B, 0x00002011, 0x00003191, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001DB2, + 0x00001DB1, 0x00002011, 0x000500C2, 0x0000000B, 0x000055FB, 0x00004419, 0x00000A25, 0x000500C7, + 0x0000000B, 0x000044EB, 0x000055FB, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AED, 0x00001966, + 0x000044EB, 0x000500C2, 0x0000000B, 0x00003431, 0x0000276E, 0x00000A25, 0x000500C7, 0x0000000B, + 0x000061C7, 0x00003431, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062B4, 0x00003330, 0x000061C7, + 0x00050080, 0x0000000B, 0x00004DF2, 0x00003AED, 0x000062B4, 0x00050086, 0x0000000B, 0x00003192, + 0x00004DF2, 0x00000A19, 0x000500C4, 0x0000000B, 0x0000204C, 0x00003192, 0x00000A52, 0x000500C5, + 0x0000000B, 0x00001A2C, 0x00001DB2, 0x0000204C, 0x000500C7, 0x0000000B, 0x00004FCF, 0x00005D1D, + 0x00003E36, 0x000500C7, 0x0000000B, 0x0000441A, 0x00004FCF, 0x00000A0D, 0x000500C7, 0x0000000B, + 0x00004C73, 0x00004FCF, 0x00000A22, 0x000500C4, 0x0000000B, 0x00006170, 0x00004C73, 0x00000A19, + 0x000500C5, 0x0000000B, 0x000042D5, 0x0000441A, 0x00006170, 0x000500C7, 0x0000000B, 0x0000519A, + 0x00004FCF, 0x00000ACA, 0x000500C4, 0x0000000B, 0x00005B23, 0x0000519A, 0x00000A28, 0x000500C5, + 0x0000000B, 0x000042D6, 0x000042D5, 0x00005B23, 0x000500C7, 0x0000000B, 0x0000519B, 0x00004FCF, + 0x00000447, 0x000500C4, 0x0000000B, 0x0000562A, 0x0000519B, 0x00000A37, 0x000500C5, 0x0000000B, + 0x00002083, 0x000042D6, 0x0000562A, 0x00050084, 0x0000000B, 0x000028BF, 0x00002083, 0x00000144, + 0x00050080, 0x0000000B, 0x0000480B, 0x00001A2C, 0x000028BF, 0x000200F9, 0x00002DD2, 0x000200F8, + 0x000038CA, 0x000400C8, 0x0000000B, 0x000029E0, 0x00005D1D, 0x000500C7, 0x0000000B, 0x00003C0E, + 0x000029E0, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000453C, 0x00001966, 0x00003C0E, 0x000500C7, + 0x0000000B, 0x000055FC, 0x00005D1D, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FD0, 0x00003330, + 0x000055FC, 0x00050080, 0x0000000B, 0x00004D9C, 0x0000453C, 0x00004FD0, 0x00050086, 0x0000000B, + 0x000032E1, 0x00004D9C, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A07, 0x000029E0, 0x00000A13, + 0x000500C7, 0x0000000B, 0x0000224A, 0x00005A07, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AEE, + 0x00001966, 0x0000224A, 0x000500C2, 0x0000000B, 0x00003432, 0x00005D1D, 0x00000A13, 0x000500C7, + 0x0000000B, 0x000061C8, 0x00003432, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062B5, 0x00003330, + 0x000061C8, 0x00050080, 0x0000000B, 0x00004DF3, 0x00003AEE, 0x000062B5, 0x00050086, 0x0000000B, + 0x00003193, 0x00004DF3, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00002012, 0x00003193, 0x00000A22, + 0x000500C5, 0x0000000B, 0x00001DB3, 0x000032E1, 0x00002012, 0x000500C2, 0x0000000B, 0x000055FD, + 0x000029E0, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044EC, 0x000055FD, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AEF, 0x00001966, 0x000044EC, 0x000500C2, 0x0000000B, 0x00003433, 0x00005D1D, + 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061C9, 0x00003433, 0x00000A1F, 0x00050084, 0x0000000B, + 0x000062B6, 0x00003330, 0x000061C9, 0x00050080, 0x0000000B, 0x00004DF4, 0x00003AEF, 0x000062B6, + 0x00050086, 0x0000000B, 0x00003194, 0x00004DF4, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00002013, + 0x00003194, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001DB4, 0x00001DB3, 0x00002013, 0x000500C2, + 0x0000000B, 0x000055FE, 0x000029E0, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044ED, 0x000055FE, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AF0, 0x00001966, 0x000044ED, 0x000500C2, 0x0000000B, + 0x00003434, 0x00005D1D, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061CA, 0x00003434, 0x00000A1F, + 0x00050084, 0x0000000B, 0x000062B7, 0x00003330, 0x000061CA, 0x00050080, 0x0000000B, 0x00004DF5, + 0x00003AF0, 0x000062B7, 0x00050086, 0x0000000B, 0x00003195, 0x00004DF5, 0x00000A1F, 0x000500C4, + 0x0000000B, 0x00002401, 0x00003195, 0x00000A52, 0x000500C5, 0x0000000B, 0x00004684, 0x00001DB4, + 0x00002401, 0x000200F9, 0x00002DD2, 0x000200F8, 0x00002DD2, 0x000700F5, 0x0000000B, 0x00005029, + 0x0000480B, 0x000029A4, 0x00004684, 0x000038CA, 0x00050051, 0x0000000B, 0x000040F0, 0x00003D29, + 0x00000001, 0x000300F7, 0x00002DD3, 0x00000000, 0x000400FA, 0x00004E84, 0x000029A5, 0x000038CB, + 0x000200F8, 0x000029A5, 0x000500C7, 0x0000000B, 0x0000450E, 0x000040F0, 0x0000003A, 0x000500C7, + 0x0000000B, 0x00005DA1, 0x000040F0, 0x0000022D, 0x000500C2, 0x0000000B, 0x00005569, 0x00005DA1, + 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FDA, 0x0000450E, 0x00005569, 0x000500C4, 0x0000000B, + 0x00006036, 0x00001FDA, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059C1, 0x00001FDA, 0x00000A0D, + 0x000500C5, 0x0000000B, 0x00004989, 0x00006036, 0x000059C1, 0x000500C5, 0x0000000B, 0x00003E37, + 0x00001FDA, 0x00004989, 0x000400C8, 0x0000000B, 0x00002118, 0x00003E37, 0x000500C7, 0x0000000B, + 0x0000276F, 0x000040F0, 0x00002118, 0x00050082, 0x0000000B, 0x00003FB9, 0x00000908, 0x0000276F, + 0x000500C7, 0x0000000B, 0x0000441B, 0x00003FB9, 0x00002118, 0x000500C7, 0x0000000B, 0x0000426C, + 0x0000441B, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000357A, 0x00003281, 0x0000426C, 0x000500C7, + 0x0000000B, 0x000055FF, 0x0000276F, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FD1, 0x00003331, + 0x000055FF, 0x00050080, 0x0000000B, 0x00004D9D, 0x0000357A, 0x00004FD1, 0x00050086, 0x0000000B, + 0x000032E2, 0x00004D9D, 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A08, 0x0000441B, 0x00000A13, + 0x000500C7, 0x0000000B, 0x0000224B, 0x00005A08, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AF1, + 0x00003281, 0x0000224B, 0x000500C2, 0x0000000B, 0x00003435, 0x0000276F, 0x00000A13, 0x000500C7, + 0x0000000B, 0x000061CB, 0x00003435, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062B8, 0x00003331, + 0x000061CB, 0x00050080, 0x0000000B, 0x00004DF6, 0x00003AF1, 0x000062B8, 0x00050086, 0x0000000B, + 0x00003196, 0x00004DF6, 0x00000A19, 0x000500C4, 0x0000000B, 0x00002014, 0x00003196, 0x00000A22, + 0x000500C5, 0x0000000B, 0x00001DB5, 0x000032E2, 0x00002014, 0x000500C2, 0x0000000B, 0x00005600, + 0x0000441B, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044EE, 0x00005600, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AF2, 0x00003281, 0x000044EE, 0x000500C2, 0x0000000B, 0x00003436, 0x0000276F, + 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061CC, 0x00003436, 0x00000A1F, 0x00050084, 0x0000000B, + 0x000062B9, 0x00003331, 0x000061CC, 0x00050080, 0x0000000B, 0x00004DF7, 0x00003AF2, 0x000062B9, + 0x00050086, 0x0000000B, 0x00003197, 0x00004DF7, 0x00000A19, 0x000500C4, 0x0000000B, 0x00002015, + 0x00003197, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001DB6, 0x00001DB5, 0x00002015, 0x000500C2, + 0x0000000B, 0x00005601, 0x0000441B, 0x00000A25, 0x000500C7, 0x0000000B, 0x000044EF, 0x00005601, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AF3, 0x00003281, 0x000044EF, 0x000500C2, 0x0000000B, + 0x00003437, 0x0000276F, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061CD, 0x00003437, 0x00000A1F, + 0x00050084, 0x0000000B, 0x000062BA, 0x00003331, 0x000061CD, 0x00050080, 0x0000000B, 0x00004DF8, + 0x00003AF3, 0x000062BA, 0x00050086, 0x0000000B, 0x00003198, 0x00004DF8, 0x00000A19, 0x000500C4, + 0x0000000B, 0x0000204D, 0x00003198, 0x00000A52, 0x000500C5, 0x0000000B, 0x00001A2D, 0x00001DB6, + 0x0000204D, 0x000500C7, 0x0000000B, 0x00004FD2, 0x000040F0, 0x00003E37, 0x000500C7, 0x0000000B, + 0x0000441C, 0x00004FD2, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C74, 0x00004FD2, 0x00000A22, + 0x000500C4, 0x0000000B, 0x00006171, 0x00004C74, 0x00000A19, 0x000500C5, 0x0000000B, 0x000042D7, + 0x0000441C, 0x00006171, 0x000500C7, 0x0000000B, 0x0000519C, 0x00004FD2, 0x00000ACA, 0x000500C4, + 0x0000000B, 0x00005B24, 0x0000519C, 0x00000A28, 0x000500C5, 0x0000000B, 0x000042D8, 0x000042D7, + 0x00005B24, 0x000500C7, 0x0000000B, 0x0000519D, 0x00004FD2, 0x00000447, 0x000500C4, 0x0000000B, + 0x0000562B, 0x0000519D, 0x00000A37, 0x000500C5, 0x0000000B, 0x00002084, 0x000042D8, 0x0000562B, + 0x00050084, 0x0000000B, 0x000028C0, 0x00002084, 0x00000144, 0x00050080, 0x0000000B, 0x0000480C, + 0x00001A2D, 0x000028C0, 0x000200F9, 0x00002DD3, 0x000200F8, 0x000038CB, 0x000400C8, 0x0000000B, + 0x000029E1, 0x000040F0, 0x000500C7, 0x0000000B, 0x00003C10, 0x000029E1, 0x00000A1F, 0x00050084, + 0x0000000B, 0x0000453D, 0x00003281, 0x00003C10, 0x000500C7, 0x0000000B, 0x00005602, 0x000040F0, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FD3, 0x00003331, 0x00005602, 0x00050080, 0x0000000B, + 0x00004D9E, 0x0000453D, 0x00004FD3, 0x00050086, 0x0000000B, 0x000032E3, 0x00004D9E, 0x00000A1F, + 0x000500C2, 0x0000000B, 0x00005A09, 0x000029E1, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000224C, + 0x00005A09, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AF4, 0x00003281, 0x0000224C, 0x000500C2, + 0x0000000B, 0x00003438, 0x000040F0, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061CE, 0x00003438, + 0x00000A1F, 0x00050084, 0x0000000B, 0x000062BB, 0x00003331, 0x000061CE, 0x00050080, 0x0000000B, + 0x00004DF9, 0x00003AF4, 0x000062BB, 0x00050086, 0x0000000B, 0x00003199, 0x00004DF9, 0x00000A1F, + 0x000500C4, 0x0000000B, 0x00002016, 0x00003199, 0x00000A22, 0x000500C5, 0x0000000B, 0x00001DB7, + 0x000032E3, 0x00002016, 0x000500C2, 0x0000000B, 0x00005603, 0x000029E1, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x000044F0, 0x00005603, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AF5, 0x00003281, + 0x000044F0, 0x000500C2, 0x0000000B, 0x00003439, 0x000040F0, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x000061CF, 0x00003439, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062BC, 0x00003331, 0x000061CF, + 0x00050080, 0x0000000B, 0x00004DFA, 0x00003AF5, 0x000062BC, 0x00050086, 0x0000000B, 0x0000319A, + 0x00004DFA, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00002017, 0x0000319A, 0x00000A3A, 0x000500C5, + 0x0000000B, 0x00001DB8, 0x00001DB7, 0x00002017, 0x000500C2, 0x0000000B, 0x00005604, 0x000029E1, + 0x00000A25, 0x000500C7, 0x0000000B, 0x000044F1, 0x00005604, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003AF6, 0x00003281, 0x000044F1, 0x000500C2, 0x0000000B, 0x0000343A, 0x000040F0, 0x00000A25, + 0x000500C7, 0x0000000B, 0x000061D0, 0x0000343A, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062BD, + 0x00003331, 0x000061D0, 0x00050080, 0x0000000B, 0x00004DFB, 0x00003AF6, 0x000062BD, 0x00050086, + 0x0000000B, 0x0000319B, 0x00004DFB, 0x00000A1F, 0x000500C4, 0x0000000B, 0x00002402, 0x0000319B, + 0x00000A52, 0x000500C5, 0x0000000B, 0x00004685, 0x00001DB8, 0x00002402, 0x000200F9, 0x00002DD3, + 0x000200F8, 0x00002DD3, 0x000700F5, 0x0000000B, 0x0000502A, 0x0000480C, 0x000029A5, 0x00004685, + 0x000038CB, 0x00050051, 0x0000000B, 0x000040F1, 0x00003D29, 0x00000002, 0x000300F7, 0x00002DD4, + 0x00000000, 0x000400FA, 0x00004E85, 0x000029A6, 0x000038CC, 0x000200F8, 0x000029A6, 0x000500C7, + 0x0000000B, 0x0000450F, 0x000040F1, 0x0000003A, 0x000500C7, 0x0000000B, 0x00005DA2, 0x000040F1, + 0x0000022D, 0x000500C2, 0x0000000B, 0x0000556A, 0x00005DA2, 0x00000A0D, 0x000500C7, 0x0000000B, + 0x00001FDB, 0x0000450F, 0x0000556A, 0x000500C4, 0x0000000B, 0x00006037, 0x00001FDB, 0x00000A0D, + 0x000500C2, 0x0000000B, 0x000059C2, 0x00001FDB, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000498A, + 0x00006037, 0x000059C2, 0x000500C5, 0x0000000B, 0x00003E38, 0x00001FDB, 0x0000498A, 0x000400C8, + 0x0000000B, 0x00002119, 0x00003E38, 0x000500C7, 0x0000000B, 0x00002770, 0x000040F1, 0x00002119, + 0x00050082, 0x0000000B, 0x00003FBA, 0x00000908, 0x00002770, 0x000500C7, 0x0000000B, 0x0000441D, + 0x00003FBA, 0x00002119, 0x000500C7, 0x0000000B, 0x0000426D, 0x0000441D, 0x00000A1F, 0x00050084, + 0x0000000B, 0x0000357B, 0x00003282, 0x0000426D, 0x000500C7, 0x0000000B, 0x00005605, 0x00002770, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FD4, 0x00003333, 0x00005605, 0x00050080, 0x0000000B, + 0x00004D9F, 0x0000357B, 0x00004FD4, 0x00050086, 0x0000000B, 0x000032E4, 0x00004D9F, 0x00000A19, + 0x000500C2, 0x0000000B, 0x00005A0A, 0x0000441D, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000224D, + 0x00005A0A, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AF7, 0x00003282, 0x0000224D, 0x000500C2, + 0x0000000B, 0x0000343B, 0x00002770, 0x00000A13, 0x000500C7, 0x0000000B, 0x000061D1, 0x0000343B, + 0x00000A1F, 0x00050084, 0x0000000B, 0x000062BE, 0x00003333, 0x000061D1, 0x00050080, 0x0000000B, + 0x00004DFC, 0x00003AF7, 0x000062BE, 0x00050086, 0x0000000B, 0x0000319C, 0x00004DFC, 0x00000A19, + 0x000500C4, 0x0000000B, 0x00002018, 0x0000319C, 0x00000A22, 0x000500C5, 0x0000000B, 0x00001DB9, + 0x000032E4, 0x00002018, 0x000500C2, 0x0000000B, 0x00005606, 0x0000441D, 0x00000A1C, 0x000500C7, + 0x0000000B, 0x000044F2, 0x00005606, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AF8, 0x00003282, + 0x000044F2, 0x000500C2, 0x0000000B, 0x0000343C, 0x00002770, 0x00000A1C, 0x000500C7, 0x0000000B, + 0x000061D2, 0x0000343C, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062BF, 0x00003333, 0x000061D2, + 0x00050080, 0x0000000B, 0x00004DFD, 0x00003AF8, 0x000062BF, 0x00050086, 0x0000000B, 0x0000319D, + 0x00004DFD, 0x00000A19, 0x000500C4, 0x0000000B, 0x00002019, 0x0000319D, 0x00000A3A, 0x000500C5, + 0x0000000B, 0x00001DBA, 0x00001DB9, 0x00002019, 0x000500C2, 0x0000000B, 0x00005607, 0x0000441D, + 0x00000A25, 0x000500C7, 0x0000000B, 0x000044F3, 0x00005607, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003AF9, 0x00003282, 0x000044F3, 0x000500C2, 0x0000000B, 0x0000343D, 0x00002770, 0x00000A25, + 0x000500C7, 0x0000000B, 0x000061D3, 0x0000343D, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062C0, + 0x00003333, 0x000061D3, 0x00050080, 0x0000000B, 0x00004DFE, 0x00003AF9, 0x000062C0, 0x00050086, + 0x0000000B, 0x0000319E, 0x00004DFE, 0x00000A19, 0x000500C4, 0x0000000B, 0x0000204E, 0x0000319E, + 0x00000A52, 0x000500C5, 0x0000000B, 0x00001A2E, 0x00001DBA, 0x0000204E, 0x000500C7, 0x0000000B, + 0x00004FD5, 0x000040F1, 0x00003E38, 0x000500C7, 0x0000000B, 0x0000441E, 0x00004FD5, 0x00000A0D, + 0x000500C7, 0x0000000B, 0x00004C75, 0x00004FD5, 0x00000A22, 0x000500C4, 0x0000000B, 0x00006172, + 0x00004C75, 0x00000A19, 0x000500C5, 0x0000000B, 0x000042D9, 0x0000441E, 0x00006172, 0x000500C7, + 0x0000000B, 0x0000519E, 0x00004FD5, 0x00000ACA, 0x000500C4, 0x0000000B, 0x00005B25, 0x0000519E, + 0x00000A28, 0x000500C5, 0x0000000B, 0x000042DA, 0x000042D9, 0x00005B25, 0x000500C7, 0x0000000B, + 0x0000519F, 0x00004FD5, 0x00000447, 0x000500C4, 0x0000000B, 0x0000562C, 0x0000519F, 0x00000A37, + 0x000500C5, 0x0000000B, 0x00002085, 0x000042DA, 0x0000562C, 0x00050084, 0x0000000B, 0x000028C1, + 0x00002085, 0x00000144, 0x00050080, 0x0000000B, 0x0000480D, 0x00001A2E, 0x000028C1, 0x000200F9, + 0x00002DD4, 0x000200F8, 0x000038CC, 0x000400C8, 0x0000000B, 0x000029E2, 0x000040F1, 0x000500C7, + 0x0000000B, 0x00003C11, 0x000029E2, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000453E, 0x00003282, + 0x00003C11, 0x000500C7, 0x0000000B, 0x00005608, 0x000040F1, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00004FD7, 0x00003333, 0x00005608, 0x00050080, 0x0000000B, 0x00004DA0, 0x0000453E, 0x00004FD7, + 0x00050086, 0x0000000B, 0x000032E5, 0x00004DA0, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A0B, + 0x000029E2, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000224E, 0x00005A0B, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AFA, 0x00003282, 0x0000224E, 0x000500C2, 0x0000000B, 0x0000343E, 0x000040F1, + 0x00000A13, 0x000500C7, 0x0000000B, 0x000061D4, 0x0000343E, 0x00000A1F, 0x00050084, 0x0000000B, + 0x000062C1, 0x00003333, 0x000061D4, 0x00050080, 0x0000000B, 0x00004DFF, 0x00003AFA, 0x000062C1, + 0x00050086, 0x0000000B, 0x0000319F, 0x00004DFF, 0x00000A1F, 0x000500C4, 0x0000000B, 0x0000201A, + 0x0000319F, 0x00000A22, 0x000500C5, 0x0000000B, 0x00001DBB, 0x000032E5, 0x0000201A, 0x000500C2, + 0x0000000B, 0x00005609, 0x000029E2, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044F4, 0x00005609, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AFB, 0x00003282, 0x000044F4, 0x000500C2, 0x0000000B, + 0x0000343F, 0x000040F1, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061D5, 0x0000343F, 0x00000A1F, + 0x00050084, 0x0000000B, 0x000062C2, 0x00003333, 0x000061D5, 0x00050080, 0x0000000B, 0x00004E00, + 0x00003AFB, 0x000062C2, 0x00050086, 0x0000000B, 0x000031A0, 0x00004E00, 0x00000A1F, 0x000500C4, + 0x0000000B, 0x0000201B, 0x000031A0, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001DBC, 0x00001DBB, + 0x0000201B, 0x000500C2, 0x0000000B, 0x0000560A, 0x000029E2, 0x00000A25, 0x000500C7, 0x0000000B, + 0x000044F5, 0x0000560A, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AFC, 0x00003282, 0x000044F5, + 0x000500C2, 0x0000000B, 0x00003440, 0x000040F1, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061D6, + 0x00003440, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062C3, 0x00003333, 0x000061D6, 0x00050080, + 0x0000000B, 0x00004E01, 0x00003AFC, 0x000062C3, 0x00050086, 0x0000000B, 0x000031A1, 0x00004E01, + 0x00000A1F, 0x000500C4, 0x0000000B, 0x00002403, 0x000031A1, 0x00000A52, 0x000500C5, 0x0000000B, + 0x00004686, 0x00001DBC, 0x00002403, 0x000200F9, 0x00002DD4, 0x000200F8, 0x00002DD4, 0x000700F5, + 0x0000000B, 0x0000502B, 0x0000480D, 0x000029A6, 0x00004686, 0x000038CC, 0x00050051, 0x0000000B, + 0x000040F2, 0x00003D29, 0x00000003, 0x000300F7, 0x00002DBA, 0x00000000, 0x000400FA, 0x00004E86, + 0x000029A7, 0x000038CD, 0x000200F8, 0x000029A7, 0x000500C7, 0x0000000B, 0x00004510, 0x000040F2, + 0x0000003A, 0x000500C7, 0x0000000B, 0x00005DA3, 0x000040F2, 0x0000022D, 0x000500C2, 0x0000000B, + 0x0000556B, 0x00005DA3, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00001FDC, 0x00004510, 0x0000556B, + 0x000500C4, 0x0000000B, 0x00006038, 0x00001FDC, 0x00000A0D, 0x000500C2, 0x0000000B, 0x000059C3, + 0x00001FDC, 0x00000A0D, 0x000500C5, 0x0000000B, 0x0000498B, 0x00006038, 0x000059C3, 0x000500C5, + 0x0000000B, 0x00003E39, 0x00001FDC, 0x0000498B, 0x000400C8, 0x0000000B, 0x0000211A, 0x00003E39, + 0x000500C7, 0x0000000B, 0x00002771, 0x000040F2, 0x0000211A, 0x00050082, 0x0000000B, 0x00003FBB, + 0x00000908, 0x00002771, 0x000500C7, 0x0000000B, 0x0000441F, 0x00003FBB, 0x0000211A, 0x000500C7, + 0x0000000B, 0x0000426E, 0x0000441F, 0x00000A1F, 0x00050084, 0x0000000B, 0x0000357C, 0x00003283, + 0x0000426E, 0x000500C7, 0x0000000B, 0x0000560B, 0x00002771, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00004FD8, 0x00003334, 0x0000560B, 0x00050080, 0x0000000B, 0x00004DA1, 0x0000357C, 0x00004FD8, + 0x00050086, 0x0000000B, 0x000032E6, 0x00004DA1, 0x00000A19, 0x000500C2, 0x0000000B, 0x00005A0D, + 0x0000441F, 0x00000A13, 0x000500C7, 0x0000000B, 0x0000224F, 0x00005A0D, 0x00000A1F, 0x00050084, + 0x0000000B, 0x00003AFD, 0x00003283, 0x0000224F, 0x000500C2, 0x0000000B, 0x00003441, 0x00002771, + 0x00000A13, 0x000500C7, 0x0000000B, 0x000061D7, 0x00003441, 0x00000A1F, 0x00050084, 0x0000000B, + 0x000062C4, 0x00003334, 0x000061D7, 0x00050080, 0x0000000B, 0x00004E02, 0x00003AFD, 0x000062C4, + 0x00050086, 0x0000000B, 0x000031A2, 0x00004E02, 0x00000A19, 0x000500C4, 0x0000000B, 0x0000201C, + 0x000031A2, 0x00000A22, 0x000500C5, 0x0000000B, 0x00001DBD, 0x000032E6, 0x0000201C, 0x000500C2, + 0x0000000B, 0x0000560C, 0x0000441F, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044F6, 0x0000560C, + 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AFE, 0x00003283, 0x000044F6, 0x000500C2, 0x0000000B, + 0x00003442, 0x00002771, 0x00000A1C, 0x000500C7, 0x0000000B, 0x000061D8, 0x00003442, 0x00000A1F, + 0x00050084, 0x0000000B, 0x000062C5, 0x00003334, 0x000061D8, 0x00050080, 0x0000000B, 0x00004E03, + 0x00003AFE, 0x000062C5, 0x00050086, 0x0000000B, 0x000031A3, 0x00004E03, 0x00000A19, 0x000500C4, + 0x0000000B, 0x0000201D, 0x000031A3, 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001DBE, 0x00001DBD, + 0x0000201D, 0x000500C2, 0x0000000B, 0x0000560D, 0x0000441F, 0x00000A25, 0x000500C7, 0x0000000B, + 0x000044F7, 0x0000560D, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003AFF, 0x00003283, 0x000044F7, + 0x000500C2, 0x0000000B, 0x00003443, 0x00002771, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061D9, + 0x00003443, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062C6, 0x00003334, 0x000061D9, 0x00050080, + 0x0000000B, 0x00004E04, 0x00003AFF, 0x000062C6, 0x00050086, 0x0000000B, 0x000031A4, 0x00004E04, + 0x00000A19, 0x000500C4, 0x0000000B, 0x0000204F, 0x000031A4, 0x00000A52, 0x000500C5, 0x0000000B, + 0x00001A2F, 0x00001DBE, 0x0000204F, 0x000500C7, 0x0000000B, 0x00004FD9, 0x000040F2, 0x00003E39, + 0x000500C7, 0x0000000B, 0x00004420, 0x00004FD9, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00004C76, + 0x00004FD9, 0x00000A22, 0x000500C4, 0x0000000B, 0x00006173, 0x00004C76, 0x00000A19, 0x000500C5, + 0x0000000B, 0x000042DB, 0x00004420, 0x00006173, 0x000500C7, 0x0000000B, 0x000051A0, 0x00004FD9, + 0x00000ACA, 0x000500C4, 0x0000000B, 0x00005B26, 0x000051A0, 0x00000A28, 0x000500C5, 0x0000000B, + 0x000042DC, 0x000042DB, 0x00005B26, 0x000500C7, 0x0000000B, 0x000051A1, 0x00004FD9, 0x00000447, + 0x000500C4, 0x0000000B, 0x0000562D, 0x000051A1, 0x00000A37, 0x000500C5, 0x0000000B, 0x00002086, + 0x000042DC, 0x0000562D, 0x00050084, 0x0000000B, 0x000028C2, 0x00002086, 0x00000144, 0x00050080, + 0x0000000B, 0x0000480E, 0x00001A2F, 0x000028C2, 0x000200F9, 0x00002DBA, 0x000200F8, 0x000038CD, + 0x000400C8, 0x0000000B, 0x000029E3, 0x000040F2, 0x000500C7, 0x0000000B, 0x00003C12, 0x000029E3, + 0x00000A1F, 0x00050084, 0x0000000B, 0x0000453F, 0x00003283, 0x00003C12, 0x000500C7, 0x0000000B, + 0x0000560E, 0x000040F2, 0x00000A1F, 0x00050084, 0x0000000B, 0x00004FDA, 0x00003334, 0x0000560E, + 0x00050080, 0x0000000B, 0x00004DA2, 0x0000453F, 0x00004FDA, 0x00050086, 0x0000000B, 0x000032E7, + 0x00004DA2, 0x00000A1F, 0x000500C2, 0x0000000B, 0x00005A11, 0x000029E3, 0x00000A13, 0x000500C7, + 0x0000000B, 0x00002250, 0x00005A11, 0x00000A1F, 0x00050084, 0x0000000B, 0x00003B00, 0x00003283, + 0x00002250, 0x000500C2, 0x0000000B, 0x00003444, 0x000040F2, 0x00000A13, 0x000500C7, 0x0000000B, + 0x000061DA, 0x00003444, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062C7, 0x00003334, 0x000061DA, + 0x00050080, 0x0000000B, 0x00004E05, 0x00003B00, 0x000062C7, 0x00050086, 0x0000000B, 0x000031A5, + 0x00004E05, 0x00000A1F, 0x000500C4, 0x0000000B, 0x0000201E, 0x000031A5, 0x00000A22, 0x000500C5, + 0x0000000B, 0x00001DBF, 0x000032E7, 0x0000201E, 0x000500C2, 0x0000000B, 0x0000560F, 0x000029E3, + 0x00000A1C, 0x000500C7, 0x0000000B, 0x000044F8, 0x0000560F, 0x00000A1F, 0x00050084, 0x0000000B, + 0x00003B01, 0x00003283, 0x000044F8, 0x000500C2, 0x0000000B, 0x00003445, 0x000040F2, 0x00000A1C, + 0x000500C7, 0x0000000B, 0x000061DB, 0x00003445, 0x00000A1F, 0x00050084, 0x0000000B, 0x000062C8, + 0x00003334, 0x000061DB, 0x00050080, 0x0000000B, 0x00004E06, 0x00003B01, 0x000062C8, 0x00050086, + 0x0000000B, 0x000031A6, 0x00004E06, 0x00000A1F, 0x000500C4, 0x0000000B, 0x0000201F, 0x000031A6, + 0x00000A3A, 0x000500C5, 0x0000000B, 0x00001DC0, 0x00001DBF, 0x0000201F, 0x000500C2, 0x0000000B, + 0x00005610, 0x000029E3, 0x00000A25, 0x000500C7, 0x0000000B, 0x00004511, 0x00005610, 0x00000A1F, + 0x00050084, 0x0000000B, 0x00003B02, 0x00003283, 0x00004511, 0x000500C2, 0x0000000B, 0x00003446, + 0x000040F2, 0x00000A25, 0x000500C7, 0x0000000B, 0x000061DC, 0x00003446, 0x00000A1F, 0x00050084, + 0x0000000B, 0x000062C9, 0x00003334, 0x000061DC, 0x00050080, 0x0000000B, 0x00004E07, 0x00003B02, + 0x000062C9, 0x00050086, 0x0000000B, 0x000031A7, 0x00004E07, 0x00000A1F, 0x000500C4, 0x0000000B, + 0x00002404, 0x000031A7, 0x00000A52, 0x000500C5, 0x0000000B, 0x00004687, 0x00001DC0, 0x00002404, + 0x000200F9, 0x00002DBA, 0x000200F8, 0x00002DBA, 0x000700F5, 0x0000000B, 0x00004350, 0x0000480E, + 0x000029A7, 0x00004687, 0x000038CD, 0x00070050, 0x00000017, 0x000038FA, 0x00005029, 0x0000502A, + 0x0000502B, 0x00004350, 0x00060041, 0x00000294, 0x00003C2D, 0x0000140E, 0x00000A0B, 0x0000342E, + 0x0003003E, 0x00003C2D, 0x000038FA, 0x000200F9, 0x00004665, 0x000200F8, 0x00004665, 0x000200F9, + 0x00001C25, 0x000200F8, 0x00001C25, 0x000200F9, 0x00001C26, 0x000200F8, 0x00001C26, 0x000200F9, + 0x00003A37, 0x000200F8, 0x00003A37, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_gbgr8_grgb8_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_gbgr8_grgb8_cs.h new file mode 100644 index 0000000..7770a30 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_gbgr8_grgb8_cs.h @@ -0,0 +1,554 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25059 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 +%uint_16711935 = OpConstant %uint 16711935 + %uint_65280 = OpConstant %uint 65280 + %uint_16 = OpConstant %uint 16 +%uint_4278190080 = OpConstant %uint 4278190080 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2603 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %2135 = OpConstantComposite %v4uint %uint_65280 %uint_65280 %uint_65280 %uint_65280 + %2599 = OpConstantComposite %v4uint %uint_4278190080 %uint_4278190080 %uint_4278190080 %uint_4278190080 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2603 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_4 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %6362 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %22810 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %13962 None + OpBranchConditional %15139 %11064 %13962 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %13962 + %13962 = OpLabel + %18259 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %23286 = OpBitwiseAnd %v4uint %18259 %2510 + %24373 = OpBitwiseAnd %v4uint %18259 %2135 + %24932 = OpShiftLeftLogical %v4uint %24373 %749 + %17045 = OpBitwiseOr %v4uint %23286 %24932 + %21212 = OpBitwiseAnd %v4uint %18259 %2599 + %18088 = OpShiftRightLogical %v4uint %21212 %749 + %6532 = OpBitwiseOr %v4uint %17045 %18088 + %20254 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %20254 %6532 + %21686 = OpIAdd %uint %21685 %int_1 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_32 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %6871 %16377 %10584 + OpSelectionMerge %13963 None + OpBranchConditional %15139 %11065 %13963 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %13963 + %13963 = OpLabel + %18260 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %23287 = OpBitwiseAnd %v4uint %18260 %2510 + %24374 = OpBitwiseAnd %v4uint %18260 %2135 + %24933 = OpShiftLeftLogical %v4uint %24374 %749 + %17046 = OpBitwiseOr %v4uint %23287 %24933 + %21213 = OpBitwiseAnd %v4uint %18260 %2599 + %18089 = OpShiftRightLogical %v4uint %21213 %749 + %6533 = OpBitwiseOr %v4uint %17046 %18089 + %22553 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21686 + OpStore %22553 %6533 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_gbgr8_grgb8_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000061E3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, + 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A87, 0x0000FF00, + 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000580, 0xFF000000, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, + 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, + 0x00000009, 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, + 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, + 0x00000A2B, 0x00000A13, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, + 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, + 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0004002B, 0x0000000B, + 0x00000A25, 0x00000009, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, + 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, + 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, + 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0007002C, 0x00000017, + 0x00000857, 0x00000A87, 0x00000A87, 0x00000A87, 0x00000A87, 0x0007002C, 0x00000017, 0x00000A27, + 0x00000580, 0x00000580, 0x00000580, 0x00000580, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, + 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, + 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, + 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, + 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, + 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, + 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, + 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, + 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, + 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, + 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, + 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, + 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, + 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, + 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, + 0x00000A2B, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, + 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, + 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, + 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, + 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, + 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, + 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A17, + 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, + 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, + 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, + 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, + 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, + 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, + 0x0000000B, 0x000054B5, 0x00002764, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, + 0x00004376, 0x00005768, 0x000051F2, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, + 0x000400FA, 0x00004384, 0x00002BF8, 0x000018D9, 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, + 0x000032B3, 0x000044BE, 0x00000A17, 0x000500C3, 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, + 0x000500C2, 0x0000000B, 0x00004947, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, + 0x00004947, 0x00050084, 0x0000000C, 0x00005321, 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, + 0x00003B27, 0x000032B3, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, + 0x0004007C, 0x0000000C, 0x00003901, 0x00002348, 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, + 0x00003901, 0x000500C3, 0x0000000C, 0x000032BA, 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, + 0x00005FEE, 0x000032BA, 0x000020F4, 0x000500C4, 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A22, + 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, + 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, + 0x0000000C, 0x00003138, 0x000044BE, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, + 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, + 0x00001B88, 0x0000434B, 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, + 0x000500C3, 0x0000000C, 0x00002215, 0x000044BE, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, + 0x00002215, 0x0000601E, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, + 0x0000000C, 0x00004112, 0x00005BEB, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, + 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, + 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, + 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, + 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, + 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, + 0x000047B4, 0x000018DA, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, + 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, + 0x000044BE, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, + 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, + 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, + 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, + 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, + 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, + 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, + 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, + 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, + 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, + 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, + 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, + 0x00005B4D, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, + 0x0000000C, 0x00005347, 0x0000405C, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, + 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, + 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, + 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, + 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, + 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, + 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, + 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, + 0x000500C7, 0x0000000C, 0x000047B5, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, + 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, + 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, + 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, + 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, + 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, + 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, + 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, + 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, + 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, + 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, + 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, + 0x00005F43, 0x000200F8, 0x000051F2, 0x0004007C, 0x0000000C, 0x00003CBC, 0x00005789, 0x00050084, + 0x0000000C, 0x000060B8, 0x000018DA, 0x00003CBC, 0x00050080, 0x0000000C, 0x0000208E, 0x000060B8, + 0x000044BE, 0x0004007C, 0x0000000C, 0x000022F8, 0x00005788, 0x00050084, 0x0000000C, 0x00001E9F, + 0x0000208E, 0x000022F8, 0x00050080, 0x0000000C, 0x00001F30, 0x0000591A, 0x00001E9F, 0x000200F9, + 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, + 0x00001F30, 0x000051F2, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, + 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, + 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, 0x00004315, 0x0000107A, + 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004315, 0x000500AA, 0x00000009, + 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x000061E2, 0x00000A10, + 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, 0x00000000, + 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, + 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, + 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, + 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, 0x00005F43, + 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000061E2, 0x00000A13, 0x000500A6, + 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x0000368A, 0x00000000, 0x000400FA, + 0x00003B23, 0x00002B38, 0x0000368A, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, + 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, + 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x0000368A, 0x000200F8, 0x0000368A, + 0x000700F5, 0x00000017, 0x00004753, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x000500C7, + 0x00000017, 0x00005AF6, 0x00004753, 0x000009CE, 0x000500C7, 0x00000017, 0x00005F35, 0x00004753, + 0x00000857, 0x000500C4, 0x00000017, 0x00006164, 0x00005F35, 0x000002ED, 0x000500C5, 0x00000017, + 0x00004295, 0x00005AF6, 0x00006164, 0x000500C7, 0x00000017, 0x000052DC, 0x00004753, 0x00000A27, + 0x000500C2, 0x00000017, 0x000046A8, 0x000052DC, 0x000002ED, 0x000500C5, 0x00000017, 0x00001984, + 0x00004295, 0x000046A8, 0x00060041, 0x00000294, 0x00004F1E, 0x0000140E, 0x00000A0B, 0x000054B5, + 0x0003003E, 0x00004F1E, 0x00001984, 0x00050080, 0x0000000B, 0x000054B6, 0x000054B5, 0x00000A0E, + 0x000300F7, 0x00001AD7, 0x00000002, 0x000400FA, 0x00004376, 0x000055E9, 0x00001C25, 0x000200F8, + 0x000055E9, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001C25, 0x000200F9, 0x00001AD7, 0x000200F8, + 0x00001AD7, 0x000700F5, 0x0000000B, 0x0000456F, 0x00000A6A, 0x000055E9, 0x00000A3A, 0x00001C25, + 0x000500C2, 0x0000000B, 0x000041C0, 0x0000456F, 0x00000A16, 0x00050080, 0x0000000B, 0x00002ADB, + 0x00005665, 0x000041C0, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, 0x00002ADB, + 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, + 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, + 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, + 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, + 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, + 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x00001AD7, 0x00003FF9, + 0x00002958, 0x000300F7, 0x0000368B, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, 0x0000368B, + 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, 0x000500C2, + 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, + 0x00003BE8, 0x000200F9, 0x0000368B, 0x000200F8, 0x0000368B, 0x000700F5, 0x00000017, 0x00004754, + 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x000500C7, 0x00000017, 0x00005AF7, 0x00004754, + 0x000009CE, 0x000500C7, 0x00000017, 0x00005F36, 0x00004754, 0x00000857, 0x000500C4, 0x00000017, + 0x00006165, 0x00005F36, 0x000002ED, 0x000500C5, 0x00000017, 0x00004296, 0x00005AF7, 0x00006165, + 0x000500C7, 0x00000017, 0x000052DD, 0x00004754, 0x00000A27, 0x000500C2, 0x00000017, 0x000046A9, + 0x000052DD, 0x000002ED, 0x000500C5, 0x00000017, 0x00001985, 0x00004296, 0x000046A9, 0x00060041, + 0x00000294, 0x00005819, 0x0000140E, 0x00000A0B, 0x000054B6, 0x0003003E, 0x00005819, 0x00001985, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_gbgr8_rgb8_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_gbgr8_rgb8_cs.h new file mode 100644 index 0000000..6acd641 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_gbgr8_rgb8_cs.h @@ -0,0 +1,676 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25175 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_24 = OpConstant %uint 24 + %uint_65280 = OpConstant %uint 65280 + %uint_8 = OpConstant %uint 8 + %uint_257 = OpConstant %uint 257 + %uint_255 = OpConstant %uint 255 +%uint_16711680 = OpConstant %uint 16711680 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_3 = OpConstant %uint 3 + %uint_16 = OpConstant %uint 16 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2603 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %2311 = OpConstantComposite %v2uint %uint_24 %uint_24 + %2682 = OpConstantComposite %v2uint %uint_65280 %uint_65280 + %1975 = OpConstantComposite %v2uint %uint_8 %uint_8 + %1182 = OpConstantComposite %v2uint %uint_257 %uint_257 + %1140 = OpConstantComposite %v2uint %uint_255 %uint_255 + %2993 = OpConstantComposite %v2uint %uint_16711680 %uint_16711680 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2603 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_8 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %19442 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %19442 = OpLabel + %8677 = OpIMul %int %23531 %int_4 + %17569 = OpBitcast %int %22409 + %8690 = OpIMul %int %6362 %17569 + %8334 = OpIAdd %int %8690 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %8677 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %19442 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %11682 None + OpBranchConditional %15139 %11064 %11682 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11682 + %11682 = OpLabel + %19853 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %22133 = OpVectorShuffle %v2uint %19853 %19853 0 1 + %14639 = OpShiftRightLogical %v2uint %22133 %2311 + %6730 = OpBitwiseAnd %v2uint %22133 %2682 + %16264 = OpShiftLeftLogical %v2uint %6730 %1975 + %22500 = OpIMul %v2uint %16264 %1182 + %9800 = OpBitwiseOr %v2uint %14639 %22500 + %8030 = OpBitwiseAnd %v2uint %22133 %1140 + %22878 = OpShiftLeftLogical %v2uint %8030 %1975 + %18448 = OpBitwiseAnd %v2uint %22133 %2993 + %15354 = OpShiftRightLogical %v2uint %18448 %1975 + %7420 = OpCompositeExtract %uint %22878 0 + %24539 = OpCompositeExtract %uint %22878 1 + %7641 = OpCompositeExtract %uint %15354 0 + %7795 = OpCompositeExtract %uint %15354 1 + %16161 = OpCompositeConstruct %v4uint %7420 %24539 %7641 %7795 + %7774 = OpVectorShuffle %v4uint %16161 %16161 0 2 1 3 + %6860 = OpVectorShuffle %v4uint %9800 %9800 0 0 1 1 + %24814 = OpBitwiseOr %v4uint %6860 %7774 + %18141 = OpVectorShuffle %v2uint %19853 %19853 2 3 + %8212 = OpShiftRightLogical %v2uint %18141 %2311 + %6731 = OpBitwiseAnd %v2uint %18141 %2682 + %16265 = OpShiftLeftLogical %v2uint %6731 %1975 + %22501 = OpIMul %v2uint %16265 %1182 + %9801 = OpBitwiseOr %v2uint %8212 %22501 + %8031 = OpBitwiseAnd %v2uint %18141 %1140 + %22879 = OpShiftLeftLogical %v2uint %8031 %1975 + %18449 = OpBitwiseAnd %v2uint %18141 %2993 + %15355 = OpShiftRightLogical %v2uint %18449 %1975 + %7421 = OpCompositeExtract %uint %22879 0 + %24541 = OpCompositeExtract %uint %22879 1 + %7642 = OpCompositeExtract %uint %15355 0 + %7796 = OpCompositeExtract %uint %15355 1 + %16162 = OpCompositeConstruct %v4uint %7421 %24541 %7642 %7796 + %7775 = OpVectorShuffle %v4uint %16162 %16162 0 2 1 3 + %6595 = OpVectorShuffle %v4uint %9801 %9801 0 0 1 1 + %24728 = OpBitwiseOr %v4uint %6595 %7775 + %8219 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %8219 %24814 + %11457 = OpIAdd %uint %21685 %uint_1 + %25136 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11457 + OpStore %25136 %24728 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_32 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %6871 %16377 %10584 + OpSelectionMerge %11683 None + OpBranchConditional %15139 %11065 %11683 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11683 + %11683 = OpLabel + %19854 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %22134 = OpVectorShuffle %v2uint %19854 %19854 0 1 + %14640 = OpShiftRightLogical %v2uint %22134 %2311 + %6732 = OpBitwiseAnd %v2uint %22134 %2682 + %16266 = OpShiftLeftLogical %v2uint %6732 %1975 + %22502 = OpIMul %v2uint %16266 %1182 + %9802 = OpBitwiseOr %v2uint %14640 %22502 + %8032 = OpBitwiseAnd %v2uint %22134 %1140 + %22880 = OpShiftLeftLogical %v2uint %8032 %1975 + %18450 = OpBitwiseAnd %v2uint %22134 %2993 + %15356 = OpShiftRightLogical %v2uint %18450 %1975 + %7422 = OpCompositeExtract %uint %22880 0 + %24542 = OpCompositeExtract %uint %22880 1 + %7643 = OpCompositeExtract %uint %15356 0 + %7797 = OpCompositeExtract %uint %15356 1 + %16163 = OpCompositeConstruct %v4uint %7422 %24542 %7643 %7797 + %7776 = OpVectorShuffle %v4uint %16163 %16163 0 2 1 3 + %6861 = OpVectorShuffle %v4uint %9802 %9802 0 0 1 1 + %24815 = OpBitwiseOr %v4uint %6861 %7776 + %18142 = OpVectorShuffle %v2uint %19854 %19854 2 3 + %8213 = OpShiftRightLogical %v2uint %18142 %2311 + %6733 = OpBitwiseAnd %v2uint %18142 %2682 + %16267 = OpShiftLeftLogical %v2uint %6733 %1975 + %22503 = OpIMul %v2uint %16267 %1182 + %9803 = OpBitwiseOr %v2uint %8213 %22503 + %8033 = OpBitwiseAnd %v2uint %18142 %1140 + %22881 = OpShiftLeftLogical %v2uint %8033 %1975 + %18451 = OpBitwiseAnd %v2uint %18142 %2993 + %15357 = OpShiftRightLogical %v2uint %18451 %1975 + %7423 = OpCompositeExtract %uint %22881 0 + %24543 = OpCompositeExtract %uint %22881 1 + %7644 = OpCompositeExtract %uint %15357 0 + %7798 = OpCompositeExtract %uint %15357 1 + %16164 = OpCompositeConstruct %v4uint %7423 %24543 %7644 %7798 + %7777 = OpVectorShuffle %v4uint %16164 %16164 0 2 1 3 + %7791 = OpVectorShuffle %v4uint %9803 %9803 0 0 1 1 + %13886 = OpBitwiseOr %v4uint %7791 %7777 + %17818 = OpIAdd %uint %21685 %uint_2 + %6441 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %17818 + OpStore %6441 %24815 + %11458 = OpIAdd %uint %21685 %uint_3 + %25174 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11458 + OpStore %25174 %13886 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_gbgr8_rgb8_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006257, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A52, 0x00000018, 0x0004002B, 0x0000000B, 0x00000A87, 0x0000FF00, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x0000014A, 0x00000101, + 0x0004002B, 0x0000000B, 0x00000144, 0x000000FF, 0x0004002B, 0x0000000B, 0x000005A9, 0x00FF0000, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, + 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, + 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, + 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, + 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x00040020, 0x00000291, + 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, + 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A2B, 0x00000A13, 0x00000A0A, 0x00000A0A, + 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, + 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, + 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, + 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, + 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, + 0x00000A6A, 0x00000A0D, 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0007002C, 0x00000017, + 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, + 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, + 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000011, 0x00000907, 0x00000A52, 0x00000A52, 0x0005002C, + 0x00000011, 0x00000A7A, 0x00000A87, 0x00000A87, 0x0005002C, 0x00000011, 0x000007B7, 0x00000A22, + 0x00000A22, 0x0005002C, 0x00000011, 0x0000049E, 0x0000014A, 0x0000014A, 0x0005002C, 0x00000011, + 0x00000474, 0x00000144, 0x00000144, 0x0005002C, 0x00000011, 0x00000BB1, 0x000005A9, 0x000005A9, + 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, + 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, + 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, + 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, + 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, + 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, + 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, + 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, + 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, + 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, + 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, + 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, + 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, + 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, + 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A2B, 0x0007004F, 0x00000011, 0x000042F0, + 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, + 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, + 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, + 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, + 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, + 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, + 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A23, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, + 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, + 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, + 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, + 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, + 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, + 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x000054B5, 0x00002764, 0x00000A16, + 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, 0x00005768, 0x00004BF2, 0x000200F8, + 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, 0x00004384, 0x00002BF8, 0x000018D9, + 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, 0x000032B3, 0x000044BE, 0x00000A17, 0x000500C3, + 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, 0x000500C2, 0x0000000B, 0x00004947, 0x00005789, + 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00004947, 0x00050084, 0x0000000C, 0x00005321, + 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000032B3, 0x00005321, 0x000500C2, + 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x00003901, 0x00002348, + 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, 0x00003901, 0x000500C3, 0x0000000C, 0x000032BA, + 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, 0x00005FEE, 0x000032BA, 0x000020F4, 0x000500C4, + 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, + 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, + 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000044BE, 0x00000A1D, + 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, + 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A22, 0x000500C3, + 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000044BE, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000601E, 0x000500C7, 0x0000000C, + 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00005BEB, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, + 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, + 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, + 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, + 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x000018DA, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, + 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000044BE, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, + 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, + 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, + 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, + 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, + 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, + 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, + 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, + 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, + 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, + 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, + 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, + 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005788, 0x00000A19, 0x0004007C, + 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AB, + 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, + 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, + 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, + 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, + 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, + 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, + 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, + 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002747, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, + 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, + 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, + 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, + 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, + 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, + 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, + 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, + 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, + 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, + 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, + 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, + 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, + 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, 0x00005F43, 0x000200F8, 0x00004BF2, 0x00050084, + 0x0000000C, 0x000021E5, 0x00005BEB, 0x00000A17, 0x0004007C, 0x0000000C, 0x000044A1, 0x00005789, + 0x00050084, 0x0000000C, 0x000021F2, 0x000018DA, 0x000044A1, 0x00050080, 0x0000000C, 0x0000208E, + 0x000021F2, 0x000044BE, 0x0004007C, 0x0000000C, 0x000022F8, 0x00005788, 0x00050084, 0x0000000C, + 0x00001E9F, 0x0000208E, 0x000022F8, 0x00050080, 0x0000000C, 0x00001F30, 0x000021E5, 0x00001E9F, + 0x000200F9, 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, + 0x00001E0B, 0x00001F30, 0x00004BF2, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, + 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, + 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, 0x00004315, + 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004315, 0x000500AA, + 0x00000009, 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x000061E2, + 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, + 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, + 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, + 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, + 0x00005F43, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000061E2, 0x00000A13, + 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x00002DA2, 0x00000000, + 0x000400FA, 0x00003B23, 0x00002B38, 0x00002DA2, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, + 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, + 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x00002DA2, 0x000200F8, + 0x00002DA2, 0x000700F5, 0x00000017, 0x00004D8D, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, + 0x0007004F, 0x00000011, 0x00005675, 0x00004D8D, 0x00004D8D, 0x00000000, 0x00000001, 0x000500C2, + 0x00000011, 0x0000392F, 0x00005675, 0x00000907, 0x000500C7, 0x00000011, 0x00001A4A, 0x00005675, + 0x00000A7A, 0x000500C4, 0x00000011, 0x00003F88, 0x00001A4A, 0x000007B7, 0x00050084, 0x00000011, + 0x000057E4, 0x00003F88, 0x0000049E, 0x000500C5, 0x00000011, 0x00002648, 0x0000392F, 0x000057E4, + 0x000500C7, 0x00000011, 0x00001F5E, 0x00005675, 0x00000474, 0x000500C4, 0x00000011, 0x0000595E, + 0x00001F5E, 0x000007B7, 0x000500C7, 0x00000011, 0x00004810, 0x00005675, 0x00000BB1, 0x000500C2, + 0x00000011, 0x00003BFA, 0x00004810, 0x000007B7, 0x00050051, 0x0000000B, 0x00001CFC, 0x0000595E, + 0x00000000, 0x00050051, 0x0000000B, 0x00005FDB, 0x0000595E, 0x00000001, 0x00050051, 0x0000000B, + 0x00001DD9, 0x00003BFA, 0x00000000, 0x00050051, 0x0000000B, 0x00001E73, 0x00003BFA, 0x00000001, + 0x00070050, 0x00000017, 0x00003F21, 0x00001CFC, 0x00005FDB, 0x00001DD9, 0x00001E73, 0x0009004F, + 0x00000017, 0x00001E5E, 0x00003F21, 0x00003F21, 0x00000000, 0x00000002, 0x00000001, 0x00000003, + 0x0009004F, 0x00000017, 0x00001ACC, 0x00002648, 0x00002648, 0x00000000, 0x00000000, 0x00000001, + 0x00000001, 0x000500C5, 0x00000017, 0x000060EE, 0x00001ACC, 0x00001E5E, 0x0007004F, 0x00000011, + 0x000046DD, 0x00004D8D, 0x00004D8D, 0x00000002, 0x00000003, 0x000500C2, 0x00000011, 0x00002014, + 0x000046DD, 0x00000907, 0x000500C7, 0x00000011, 0x00001A4B, 0x000046DD, 0x00000A7A, 0x000500C4, + 0x00000011, 0x00003F89, 0x00001A4B, 0x000007B7, 0x00050084, 0x00000011, 0x000057E5, 0x00003F89, + 0x0000049E, 0x000500C5, 0x00000011, 0x00002649, 0x00002014, 0x000057E5, 0x000500C7, 0x00000011, + 0x00001F5F, 0x000046DD, 0x00000474, 0x000500C4, 0x00000011, 0x0000595F, 0x00001F5F, 0x000007B7, + 0x000500C7, 0x00000011, 0x00004811, 0x000046DD, 0x00000BB1, 0x000500C2, 0x00000011, 0x00003BFB, + 0x00004811, 0x000007B7, 0x00050051, 0x0000000B, 0x00001CFD, 0x0000595F, 0x00000000, 0x00050051, + 0x0000000B, 0x00005FDD, 0x0000595F, 0x00000001, 0x00050051, 0x0000000B, 0x00001DDA, 0x00003BFB, + 0x00000000, 0x00050051, 0x0000000B, 0x00001E74, 0x00003BFB, 0x00000001, 0x00070050, 0x00000017, + 0x00003F22, 0x00001CFD, 0x00005FDD, 0x00001DDA, 0x00001E74, 0x0009004F, 0x00000017, 0x00001E5F, + 0x00003F22, 0x00003F22, 0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x0009004F, 0x00000017, + 0x000019C3, 0x00002649, 0x00002649, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C5, + 0x00000017, 0x00006098, 0x000019C3, 0x00001E5F, 0x00060041, 0x00000294, 0x0000201B, 0x0000140E, + 0x00000A0B, 0x000054B5, 0x0003003E, 0x0000201B, 0x000060EE, 0x00050080, 0x0000000B, 0x00002CC1, + 0x000054B5, 0x00000A0D, 0x00060041, 0x00000294, 0x00006230, 0x0000140E, 0x00000A0B, 0x00002CC1, + 0x0003003E, 0x00006230, 0x00006098, 0x000300F7, 0x00001AD7, 0x00000002, 0x000400FA, 0x00004376, + 0x000055E9, 0x00001C25, 0x000200F8, 0x000055E9, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001C25, + 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001AD7, 0x000700F5, 0x0000000B, 0x0000456F, 0x00000A6A, + 0x000055E9, 0x00000A3A, 0x00001C25, 0x000500C2, 0x0000000B, 0x000041C0, 0x0000456F, 0x00000A16, + 0x00050080, 0x0000000B, 0x00002ADB, 0x00005665, 0x000041C0, 0x00060041, 0x00000294, 0x0000571A, + 0x0000107A, 0x00000A0B, 0x00002ADB, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, + 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, + 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, + 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, + 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, + 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, + 0x000019B2, 0x00001AD7, 0x00003FF9, 0x00002958, 0x000300F7, 0x00002DA3, 0x00000000, 0x000400FA, + 0x00003B23, 0x00002B39, 0x00002DA3, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, + 0x00002AAC, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, + 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002DA3, 0x000200F8, 0x00002DA3, + 0x000700F5, 0x00000017, 0x00004D8E, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x0007004F, + 0x00000011, 0x00005676, 0x00004D8E, 0x00004D8E, 0x00000000, 0x00000001, 0x000500C2, 0x00000011, + 0x00003930, 0x00005676, 0x00000907, 0x000500C7, 0x00000011, 0x00001A4C, 0x00005676, 0x00000A7A, + 0x000500C4, 0x00000011, 0x00003F8A, 0x00001A4C, 0x000007B7, 0x00050084, 0x00000011, 0x000057E6, + 0x00003F8A, 0x0000049E, 0x000500C5, 0x00000011, 0x0000264A, 0x00003930, 0x000057E6, 0x000500C7, + 0x00000011, 0x00001F60, 0x00005676, 0x00000474, 0x000500C4, 0x00000011, 0x00005960, 0x00001F60, + 0x000007B7, 0x000500C7, 0x00000011, 0x00004812, 0x00005676, 0x00000BB1, 0x000500C2, 0x00000011, + 0x00003BFC, 0x00004812, 0x000007B7, 0x00050051, 0x0000000B, 0x00001CFE, 0x00005960, 0x00000000, + 0x00050051, 0x0000000B, 0x00005FDE, 0x00005960, 0x00000001, 0x00050051, 0x0000000B, 0x00001DDB, + 0x00003BFC, 0x00000000, 0x00050051, 0x0000000B, 0x00001E75, 0x00003BFC, 0x00000001, 0x00070050, + 0x00000017, 0x00003F23, 0x00001CFE, 0x00005FDE, 0x00001DDB, 0x00001E75, 0x0009004F, 0x00000017, + 0x00001E60, 0x00003F23, 0x00003F23, 0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x0009004F, + 0x00000017, 0x00001ACD, 0x0000264A, 0x0000264A, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C5, 0x00000017, 0x000060EF, 0x00001ACD, 0x00001E60, 0x0007004F, 0x00000011, 0x000046DE, + 0x00004D8E, 0x00004D8E, 0x00000002, 0x00000003, 0x000500C2, 0x00000011, 0x00002015, 0x000046DE, + 0x00000907, 0x000500C7, 0x00000011, 0x00001A4D, 0x000046DE, 0x00000A7A, 0x000500C4, 0x00000011, + 0x00003F8B, 0x00001A4D, 0x000007B7, 0x00050084, 0x00000011, 0x000057E7, 0x00003F8B, 0x0000049E, + 0x000500C5, 0x00000011, 0x0000264B, 0x00002015, 0x000057E7, 0x000500C7, 0x00000011, 0x00001F61, + 0x000046DE, 0x00000474, 0x000500C4, 0x00000011, 0x00005961, 0x00001F61, 0x000007B7, 0x000500C7, + 0x00000011, 0x00004813, 0x000046DE, 0x00000BB1, 0x000500C2, 0x00000011, 0x00003BFD, 0x00004813, + 0x000007B7, 0x00050051, 0x0000000B, 0x00001CFF, 0x00005961, 0x00000000, 0x00050051, 0x0000000B, + 0x00005FDF, 0x00005961, 0x00000001, 0x00050051, 0x0000000B, 0x00001DDC, 0x00003BFD, 0x00000000, + 0x00050051, 0x0000000B, 0x00001E76, 0x00003BFD, 0x00000001, 0x00070050, 0x00000017, 0x00003F24, + 0x00001CFF, 0x00005FDF, 0x00001DDC, 0x00001E76, 0x0009004F, 0x00000017, 0x00001E61, 0x00003F24, + 0x00003F24, 0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x0009004F, 0x00000017, 0x00001E6F, + 0x0000264B, 0x0000264B, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C5, 0x00000017, + 0x0000363E, 0x00001E6F, 0x00001E61, 0x00050080, 0x0000000B, 0x0000459A, 0x000054B5, 0x00000A10, + 0x00060041, 0x00000294, 0x00001929, 0x0000140E, 0x00000A0B, 0x0000459A, 0x0003003E, 0x00001929, + 0x000060EF, 0x00050080, 0x0000000B, 0x00002CC2, 0x000054B5, 0x00000A13, 0x00060041, 0x00000294, + 0x00006256, 0x0000140E, 0x00000A0B, 0x00002CC2, 0x0003003E, 0x00006256, 0x0000363E, 0x000200F9, + 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r10g11b11_rgba16_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r10g11b11_rgba16_cs.h new file mode 100644 index 0000000..9896255 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r10g11b11_rgba16_cs.h @@ -0,0 +1,712 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25175 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_0 = OpConstant %uint 0 + %uint_21 = OpConstant %uint 21 + %515 = OpConstantComposite %v4uint %uint_0 %uint_21 %uint_0 %uint_21 + %uint_1023 = OpConstant %uint 1023 + %uint_2047 = OpConstant %uint 2047 + %1539 = OpConstantComposite %v4uint %uint_1023 %uint_2047 %uint_1023 %uint_2047 + %uint_6 = OpConstant %uint 6 + %uint_5 = OpConstant %uint 5 + %179 = OpConstantComposite %v4uint %uint_6 %uint_5 %uint_6 %uint_5 + %uint_4 = OpConstant %uint 4 + %uint_27 = OpConstant %uint 27 + %791 = OpConstantComposite %v4uint %uint_4 %uint_27 %uint_4 %uint_27 + %uint_63 = OpConstant %uint 63 + %uint_31 = OpConstant %uint 31 + %2327 = OpConstantComposite %v4uint %uint_63 %uint_31 %uint_63 %uint_31 +%uint_2096128 = OpConstant %uint 2096128 + %uint_11 = OpConstant %uint 11 +%uint_2031616 = OpConstant %uint 2031616 + %uint_2 = OpConstant %uint 2 +%uint_4294901760 = OpConstant %uint 4294901760 + %uint_1 = OpConstant %uint 1 + %uint_3 = OpConstant %uint 3 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_16 = OpConstant %uint 16 + %int_5 = OpConstant %int 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2604 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %2686 = OpConstantComposite %v2uint %uint_2096128 %uint_2096128 + %2038 = OpConstantComposite %v2uint %uint_11 %uint_11 + %2884 = OpConstantComposite %v2uint %uint_2031616 %uint_2031616 + %1578 = OpConstantComposite %v2uint %uint_4294901760 %uint_4294901760 + %200 = OpConstantNull %v2uint + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2604 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_8 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %19442 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %19442 = OpLabel + %8677 = OpIMul %int %23531 %int_4 + %17569 = OpBitcast %int %22409 + %8690 = OpIMul %int %6362 %17569 + %8334 = OpIAdd %int %8690 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %8677 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %19442 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %11682 None + OpBranchConditional %15139 %11064 %11682 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11682 + %11682 = OpLabel + %17668 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %22862 = OpVectorShuffle %v2uint %17668 %17668 0 1 + %10663 = OpVectorShuffle %v4uint %17668 %200 0 0 1 1 + %9600 = OpShiftRightLogical %v4uint %10663 %515 + %7908 = OpBitwiseAnd %v4uint %9600 %1539 + %24647 = OpShiftLeftLogical %v4uint %7908 %179 + %22610 = OpShiftRightLogical %v4uint %10663 %791 + %21478 = OpBitwiseAnd %v4uint %22610 %2327 + %15532 = OpBitwiseOr %v4uint %24647 %21478 + %20095 = OpBitwiseAnd %v2uint %22862 %2686 + %22935 = OpShiftLeftLogical %v2uint %20095 %2038 + %17891 = OpBitwiseAnd %v2uint %22862 %2884 + %12396 = OpBitwiseOr %v2uint %22935 %17891 + %15605 = OpVectorShuffle %v2uint %15532 %15532 0 2 + %20933 = OpBitwiseOr %v2uint %15605 %12396 + %19024 = OpCompositeExtract %uint %20933 0 + %7209 = OpCompositeExtract %uint %20933 1 + %23049 = OpVectorShuffle %v2uint %15532 %15532 1 3 + %23934 = OpBitwiseOr %v2uint %23049 %1578 + %19043 = OpCompositeExtract %uint %23934 0 + %23865 = OpCompositeExtract %uint %23934 1 + %16161 = OpCompositeConstruct %v4uint %19024 %19043 %7209 %23865 + %7717 = OpVectorShuffle %v2uint %17668 %17668 2 3 + %9659 = OpVectorShuffle %v4uint %17668 %200 2 2 3 3 + %9601 = OpShiftRightLogical %v4uint %9659 %515 + %7909 = OpBitwiseAnd %v4uint %9601 %1539 + %24648 = OpShiftLeftLogical %v4uint %7909 %179 + %22611 = OpShiftRightLogical %v4uint %9659 %791 + %21479 = OpBitwiseAnd %v4uint %22611 %2327 + %15533 = OpBitwiseOr %v4uint %24648 %21479 + %20096 = OpBitwiseAnd %v2uint %7717 %2686 + %22936 = OpShiftLeftLogical %v2uint %20096 %2038 + %17892 = OpBitwiseAnd %v2uint %7717 %2884 + %12397 = OpBitwiseOr %v2uint %22936 %17892 + %15606 = OpVectorShuffle %v2uint %15533 %15533 0 2 + %20934 = OpBitwiseOr %v2uint %15606 %12397 + %19025 = OpCompositeExtract %uint %20934 0 + %7210 = OpCompositeExtract %uint %20934 1 + %23050 = OpVectorShuffle %v2uint %15533 %15533 1 3 + %23935 = OpBitwiseOr %v2uint %23050 %1578 + %19044 = OpCompositeExtract %uint %23935 0 + %23599 = OpCompositeExtract %uint %23935 1 + %18260 = OpCompositeConstruct %v4uint %19025 %19044 %7210 %23599 + %9680 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %9680 %16161 + %11457 = OpIAdd %uint %21685 %uint_1 + %25136 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11457 + OpStore %25136 %18260 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_32 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %6871 %16377 %10584 + OpSelectionMerge %11683 None + OpBranchConditional %15139 %11065 %11683 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11683 + %11683 = OpLabel + %17669 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %22863 = OpVectorShuffle %v2uint %17669 %17669 0 1 + %10664 = OpVectorShuffle %v4uint %17669 %200 0 0 1 1 + %9602 = OpShiftRightLogical %v4uint %10664 %515 + %7910 = OpBitwiseAnd %v4uint %9602 %1539 + %24649 = OpShiftLeftLogical %v4uint %7910 %179 + %22612 = OpShiftRightLogical %v4uint %10664 %791 + %21480 = OpBitwiseAnd %v4uint %22612 %2327 + %15534 = OpBitwiseOr %v4uint %24649 %21480 + %20097 = OpBitwiseAnd %v2uint %22863 %2686 + %22937 = OpShiftLeftLogical %v2uint %20097 %2038 + %17893 = OpBitwiseAnd %v2uint %22863 %2884 + %12398 = OpBitwiseOr %v2uint %22937 %17893 + %15607 = OpVectorShuffle %v2uint %15534 %15534 0 2 + %20935 = OpBitwiseOr %v2uint %15607 %12398 + %19026 = OpCompositeExtract %uint %20935 0 + %7211 = OpCompositeExtract %uint %20935 1 + %23051 = OpVectorShuffle %v2uint %15534 %15534 1 3 + %23936 = OpBitwiseOr %v2uint %23051 %1578 + %19045 = OpCompositeExtract %uint %23936 0 + %23866 = OpCompositeExtract %uint %23936 1 + %16162 = OpCompositeConstruct %v4uint %19026 %19045 %7211 %23866 + %7718 = OpVectorShuffle %v2uint %17669 %17669 2 3 + %9660 = OpVectorShuffle %v4uint %17669 %200 2 2 3 3 + %9603 = OpShiftRightLogical %v4uint %9660 %515 + %7911 = OpBitwiseAnd %v4uint %9603 %1539 + %24650 = OpShiftLeftLogical %v4uint %7911 %179 + %22613 = OpShiftRightLogical %v4uint %9660 %791 + %21481 = OpBitwiseAnd %v4uint %22613 %2327 + %15535 = OpBitwiseOr %v4uint %24650 %21481 + %20098 = OpBitwiseAnd %v2uint %7718 %2686 + %22938 = OpShiftLeftLogical %v2uint %20098 %2038 + %17894 = OpBitwiseAnd %v2uint %7718 %2884 + %12399 = OpBitwiseOr %v2uint %22938 %17894 + %15608 = OpVectorShuffle %v2uint %15535 %15535 0 2 + %20936 = OpBitwiseOr %v2uint %15608 %12399 + %19027 = OpCompositeExtract %uint %20936 0 + %7212 = OpCompositeExtract %uint %20936 1 + %23053 = OpVectorShuffle %v2uint %15535 %15535 1 3 + %23937 = OpBitwiseOr %v2uint %23053 %1578 + %19046 = OpCompositeExtract %uint %23937 0 + %24796 = OpCompositeExtract %uint %23937 1 + %7418 = OpCompositeConstruct %v4uint %19027 %19046 %7212 %24796 + %6665 = OpIAdd %uint %21685 %uint_2 + %24478 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %6665 + OpStore %24478 %16162 + %11458 = OpIAdd %uint %21685 %uint_3 + %25174 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11458 + OpStore %25174 %7418 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r10g11b11_rgba16_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006257, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A49, 0x00000015, + 0x0007002C, 0x00000017, 0x00000203, 0x00000A0A, 0x00000A49, 0x00000A0A, 0x00000A49, 0x0004002B, + 0x0000000B, 0x00000A44, 0x000003FF, 0x0004002B, 0x0000000B, 0x00000A81, 0x000007FF, 0x0007002C, + 0x00000017, 0x00000603, 0x00000A44, 0x00000A81, 0x00000A44, 0x00000A81, 0x0004002B, 0x0000000B, + 0x00000A1C, 0x00000006, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0007002C, 0x00000017, + 0x000000B3, 0x00000A1C, 0x00000A19, 0x00000A1C, 0x00000A19, 0x0004002B, 0x0000000B, 0x00000A16, + 0x00000004, 0x0004002B, 0x0000000B, 0x00000A5B, 0x0000001B, 0x0007002C, 0x00000017, 0x00000317, + 0x00000A16, 0x00000A5B, 0x00000A16, 0x00000A5B, 0x0004002B, 0x0000000B, 0x00000AC7, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A67, 0x0000001F, 0x0007002C, 0x00000017, 0x00000917, 0x00000AC7, + 0x00000A67, 0x00000AC7, 0x00000A67, 0x0004002B, 0x0000000B, 0x000003CF, 0x001FFC00, 0x0004002B, + 0x0000000B, 0x00000A2B, 0x0000000B, 0x0004002B, 0x0000000B, 0x0000008F, 0x001F0000, 0x0004002B, + 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x0000068D, 0xFFFF0000, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, + 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, + 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, + 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, + 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, + 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, + 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, + 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, + 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, + 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, + 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, + 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, + 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, + 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, + 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, + 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A2C, + 0x00000A13, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0003001D, + 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, + 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, + 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, + 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, + 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0004002B, 0x0000000B, 0x00000A25, + 0x00000009, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, + 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, + 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, + 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000011, 0x00000A7E, + 0x000003CF, 0x000003CF, 0x0005002C, 0x00000011, 0x000007F6, 0x00000A2B, 0x00000A2B, 0x0005002C, + 0x00000011, 0x00000B44, 0x0000008F, 0x0000008F, 0x0005002C, 0x00000011, 0x0000062A, 0x0000068D, + 0x0000068D, 0x0003002E, 0x00000011, 0x000000C8, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, + 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, + 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, + 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, + 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, + 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, + 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, + 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, + 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, + 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, + 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, + 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, + 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, + 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, + 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, + 0x00000A2C, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, + 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, + 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, + 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, + 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, + 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, + 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A23, + 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, + 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, + 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, + 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, + 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, + 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, + 0x0000000B, 0x000054B5, 0x00002764, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, + 0x00004376, 0x00005768, 0x00004BF2, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, + 0x000400FA, 0x00004384, 0x00002BF8, 0x000018D9, 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, + 0x000032B3, 0x000044BE, 0x00000A17, 0x000500C3, 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, + 0x000500C2, 0x0000000B, 0x00004947, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, + 0x00004947, 0x00050084, 0x0000000C, 0x00005321, 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, + 0x00003B27, 0x000032B3, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, + 0x0004007C, 0x0000000C, 0x00003901, 0x00002348, 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, + 0x00003901, 0x000500C3, 0x0000000C, 0x000032BA, 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, + 0x00005FEE, 0x000032BA, 0x000020F4, 0x000500C4, 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A22, + 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, + 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, + 0x0000000C, 0x00003138, 0x000044BE, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, + 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, + 0x00001B88, 0x0000434B, 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, + 0x000500C3, 0x0000000C, 0x00002215, 0x000044BE, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, + 0x00002215, 0x0000601E, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, + 0x0000000C, 0x00004112, 0x00005BEB, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, + 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, + 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, + 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, + 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, + 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, + 0x000047B4, 0x000018DA, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, + 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, + 0x000044BE, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, + 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, + 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, + 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, + 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, + 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, + 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, + 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, + 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, + 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, + 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, + 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, + 0x00005B4D, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, + 0x0000000C, 0x00005347, 0x0000405C, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, + 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, + 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, + 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, + 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, + 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, + 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, + 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, + 0x000500C7, 0x0000000C, 0x000047B5, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, + 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, + 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, + 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, + 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, + 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, + 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, + 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, + 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, + 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, + 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, + 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, + 0x00005F43, 0x000200F8, 0x00004BF2, 0x00050084, 0x0000000C, 0x000021E5, 0x00005BEB, 0x00000A17, + 0x0004007C, 0x0000000C, 0x000044A1, 0x00005789, 0x00050084, 0x0000000C, 0x000021F2, 0x000018DA, + 0x000044A1, 0x00050080, 0x0000000C, 0x0000208E, 0x000021F2, 0x000044BE, 0x0004007C, 0x0000000C, + 0x000022F8, 0x00005788, 0x00050084, 0x0000000C, 0x00001E9F, 0x0000208E, 0x000022F8, 0x00050080, + 0x0000000C, 0x00001F30, 0x000021E5, 0x00001E9F, 0x000200F9, 0x00005F43, 0x000200F8, 0x00005F43, + 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, 0x00001F30, 0x00004BF2, 0x0004007C, + 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, + 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, + 0x00000A16, 0x00060041, 0x00000294, 0x00004315, 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, + 0x00000017, 0x00001CAA, 0x00004315, 0x000500AA, 0x00000009, 0x000035C0, 0x000061E2, 0x00000A0D, + 0x000500AA, 0x00000009, 0x00005376, 0x000061E2, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, + 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, + 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, + 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, + 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, + 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, + 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, 0x00005F43, 0x00003FF8, 0x00002957, 0x000500AA, + 0x00000009, 0x00004CB6, 0x000061E2, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, + 0x00004CB6, 0x000300F7, 0x00002DA2, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x00002DA2, + 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, + 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, + 0x00003BE7, 0x000200F9, 0x00002DA2, 0x000200F8, 0x00002DA2, 0x000700F5, 0x00000017, 0x00004504, + 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x0007004F, 0x00000011, 0x0000594E, 0x00004504, + 0x00004504, 0x00000000, 0x00000001, 0x0009004F, 0x00000017, 0x000029A7, 0x00004504, 0x000000C8, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C2, 0x00000017, 0x00002580, 0x000029A7, + 0x00000203, 0x000500C7, 0x00000017, 0x00001EE4, 0x00002580, 0x00000603, 0x000500C4, 0x00000017, + 0x00006047, 0x00001EE4, 0x000000B3, 0x000500C2, 0x00000017, 0x00005852, 0x000029A7, 0x00000317, + 0x000500C7, 0x00000017, 0x000053E6, 0x00005852, 0x00000917, 0x000500C5, 0x00000017, 0x00003CAC, + 0x00006047, 0x000053E6, 0x000500C7, 0x00000011, 0x00004E7F, 0x0000594E, 0x00000A7E, 0x000500C4, + 0x00000011, 0x00005997, 0x00004E7F, 0x000007F6, 0x000500C7, 0x00000011, 0x000045E3, 0x0000594E, + 0x00000B44, 0x000500C5, 0x00000011, 0x0000306C, 0x00005997, 0x000045E3, 0x0007004F, 0x00000011, + 0x00003CF5, 0x00003CAC, 0x00003CAC, 0x00000000, 0x00000002, 0x000500C5, 0x00000011, 0x000051C5, + 0x00003CF5, 0x0000306C, 0x00050051, 0x0000000B, 0x00004A50, 0x000051C5, 0x00000000, 0x00050051, + 0x0000000B, 0x00001C29, 0x000051C5, 0x00000001, 0x0007004F, 0x00000011, 0x00005A09, 0x00003CAC, + 0x00003CAC, 0x00000001, 0x00000003, 0x000500C5, 0x00000011, 0x00005D7E, 0x00005A09, 0x0000062A, + 0x00050051, 0x0000000B, 0x00004A63, 0x00005D7E, 0x00000000, 0x00050051, 0x0000000B, 0x00005D39, + 0x00005D7E, 0x00000001, 0x00070050, 0x00000017, 0x00003F21, 0x00004A50, 0x00004A63, 0x00001C29, + 0x00005D39, 0x0007004F, 0x00000011, 0x00001E25, 0x00004504, 0x00004504, 0x00000002, 0x00000003, + 0x0009004F, 0x00000017, 0x000025BB, 0x00004504, 0x000000C8, 0x00000002, 0x00000002, 0x00000003, + 0x00000003, 0x000500C2, 0x00000017, 0x00002581, 0x000025BB, 0x00000203, 0x000500C7, 0x00000017, + 0x00001EE5, 0x00002581, 0x00000603, 0x000500C4, 0x00000017, 0x00006048, 0x00001EE5, 0x000000B3, + 0x000500C2, 0x00000017, 0x00005853, 0x000025BB, 0x00000317, 0x000500C7, 0x00000017, 0x000053E7, + 0x00005853, 0x00000917, 0x000500C5, 0x00000017, 0x00003CAD, 0x00006048, 0x000053E7, 0x000500C7, + 0x00000011, 0x00004E80, 0x00001E25, 0x00000A7E, 0x000500C4, 0x00000011, 0x00005998, 0x00004E80, + 0x000007F6, 0x000500C7, 0x00000011, 0x000045E4, 0x00001E25, 0x00000B44, 0x000500C5, 0x00000011, + 0x0000306D, 0x00005998, 0x000045E4, 0x0007004F, 0x00000011, 0x00003CF6, 0x00003CAD, 0x00003CAD, + 0x00000000, 0x00000002, 0x000500C5, 0x00000011, 0x000051C6, 0x00003CF6, 0x0000306D, 0x00050051, + 0x0000000B, 0x00004A51, 0x000051C6, 0x00000000, 0x00050051, 0x0000000B, 0x00001C2A, 0x000051C6, + 0x00000001, 0x0007004F, 0x00000011, 0x00005A0A, 0x00003CAD, 0x00003CAD, 0x00000001, 0x00000003, + 0x000500C5, 0x00000011, 0x00005D7F, 0x00005A0A, 0x0000062A, 0x00050051, 0x0000000B, 0x00004A64, + 0x00005D7F, 0x00000000, 0x00050051, 0x0000000B, 0x00005C2F, 0x00005D7F, 0x00000001, 0x00070050, + 0x00000017, 0x00004754, 0x00004A51, 0x00004A64, 0x00001C2A, 0x00005C2F, 0x00060041, 0x00000294, + 0x000025D0, 0x0000140E, 0x00000A0B, 0x000054B5, 0x0003003E, 0x000025D0, 0x00003F21, 0x00050080, + 0x0000000B, 0x00002CC1, 0x000054B5, 0x00000A0D, 0x00060041, 0x00000294, 0x00006230, 0x0000140E, + 0x00000A0B, 0x00002CC1, 0x0003003E, 0x00006230, 0x00004754, 0x000300F7, 0x00001AD7, 0x00000002, + 0x000400FA, 0x00004376, 0x000055E9, 0x00001C25, 0x000200F8, 0x000055E9, 0x000200F9, 0x00001AD7, + 0x000200F8, 0x00001C25, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001AD7, 0x000700F5, 0x0000000B, + 0x0000456F, 0x00000A6A, 0x000055E9, 0x00000A3A, 0x00001C25, 0x000500C2, 0x0000000B, 0x000041C0, + 0x0000456F, 0x00000A16, 0x00050080, 0x0000000B, 0x00002ADB, 0x00005665, 0x000041C0, 0x00060041, + 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, 0x00002ADB, 0x0004003D, 0x00000017, 0x000019B2, + 0x0000571A, 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, + 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, + 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, + 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, + 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, + 0x00000017, 0x00002AAC, 0x000019B2, 0x00001AD7, 0x00003FF9, 0x00002958, 0x000300F7, 0x00002DA3, + 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, 0x00002DA3, 0x000200F8, 0x00002B39, 0x000500C4, + 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, + 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002DA3, + 0x000200F8, 0x00002DA3, 0x000700F5, 0x00000017, 0x00004505, 0x00002AAC, 0x00003A1A, 0x000029E9, + 0x00002B39, 0x0007004F, 0x00000011, 0x0000594F, 0x00004505, 0x00004505, 0x00000000, 0x00000001, + 0x0009004F, 0x00000017, 0x000029A8, 0x00004505, 0x000000C8, 0x00000000, 0x00000000, 0x00000001, + 0x00000001, 0x000500C2, 0x00000017, 0x00002582, 0x000029A8, 0x00000203, 0x000500C7, 0x00000017, + 0x00001EE6, 0x00002582, 0x00000603, 0x000500C4, 0x00000017, 0x00006049, 0x00001EE6, 0x000000B3, + 0x000500C2, 0x00000017, 0x00005854, 0x000029A8, 0x00000317, 0x000500C7, 0x00000017, 0x000053E8, + 0x00005854, 0x00000917, 0x000500C5, 0x00000017, 0x00003CAE, 0x00006049, 0x000053E8, 0x000500C7, + 0x00000011, 0x00004E81, 0x0000594F, 0x00000A7E, 0x000500C4, 0x00000011, 0x00005999, 0x00004E81, + 0x000007F6, 0x000500C7, 0x00000011, 0x000045E5, 0x0000594F, 0x00000B44, 0x000500C5, 0x00000011, + 0x0000306E, 0x00005999, 0x000045E5, 0x0007004F, 0x00000011, 0x00003CF7, 0x00003CAE, 0x00003CAE, + 0x00000000, 0x00000002, 0x000500C5, 0x00000011, 0x000051C7, 0x00003CF7, 0x0000306E, 0x00050051, + 0x0000000B, 0x00004A52, 0x000051C7, 0x00000000, 0x00050051, 0x0000000B, 0x00001C2B, 0x000051C7, + 0x00000001, 0x0007004F, 0x00000011, 0x00005A0B, 0x00003CAE, 0x00003CAE, 0x00000001, 0x00000003, + 0x000500C5, 0x00000011, 0x00005D80, 0x00005A0B, 0x0000062A, 0x00050051, 0x0000000B, 0x00004A65, + 0x00005D80, 0x00000000, 0x00050051, 0x0000000B, 0x00005D3A, 0x00005D80, 0x00000001, 0x00070050, + 0x00000017, 0x00003F22, 0x00004A52, 0x00004A65, 0x00001C2B, 0x00005D3A, 0x0007004F, 0x00000011, + 0x00001E26, 0x00004505, 0x00004505, 0x00000002, 0x00000003, 0x0009004F, 0x00000017, 0x000025BC, + 0x00004505, 0x000000C8, 0x00000002, 0x00000002, 0x00000003, 0x00000003, 0x000500C2, 0x00000017, + 0x00002583, 0x000025BC, 0x00000203, 0x000500C7, 0x00000017, 0x00001EE7, 0x00002583, 0x00000603, + 0x000500C4, 0x00000017, 0x0000604A, 0x00001EE7, 0x000000B3, 0x000500C2, 0x00000017, 0x00005855, + 0x000025BC, 0x00000317, 0x000500C7, 0x00000017, 0x000053E9, 0x00005855, 0x00000917, 0x000500C5, + 0x00000017, 0x00003CAF, 0x0000604A, 0x000053E9, 0x000500C7, 0x00000011, 0x00004E82, 0x00001E26, + 0x00000A7E, 0x000500C4, 0x00000011, 0x0000599A, 0x00004E82, 0x000007F6, 0x000500C7, 0x00000011, + 0x000045E6, 0x00001E26, 0x00000B44, 0x000500C5, 0x00000011, 0x0000306F, 0x0000599A, 0x000045E6, + 0x0007004F, 0x00000011, 0x00003CF8, 0x00003CAF, 0x00003CAF, 0x00000000, 0x00000002, 0x000500C5, + 0x00000011, 0x000051C8, 0x00003CF8, 0x0000306F, 0x00050051, 0x0000000B, 0x00004A53, 0x000051C8, + 0x00000000, 0x00050051, 0x0000000B, 0x00001C2C, 0x000051C8, 0x00000001, 0x0007004F, 0x00000011, + 0x00005A0D, 0x00003CAF, 0x00003CAF, 0x00000001, 0x00000003, 0x000500C5, 0x00000011, 0x00005D81, + 0x00005A0D, 0x0000062A, 0x00050051, 0x0000000B, 0x00004A66, 0x00005D81, 0x00000000, 0x00050051, + 0x0000000B, 0x000060DC, 0x00005D81, 0x00000001, 0x00070050, 0x00000017, 0x00001CFA, 0x00004A53, + 0x00004A66, 0x00001C2C, 0x000060DC, 0x00050080, 0x0000000B, 0x00001A09, 0x000054B5, 0x00000A10, + 0x00060041, 0x00000294, 0x00005F9E, 0x0000140E, 0x00000A0B, 0x00001A09, 0x0003003E, 0x00005F9E, + 0x00003F22, 0x00050080, 0x0000000B, 0x00002CC2, 0x000054B5, 0x00000A13, 0x00060041, 0x00000294, + 0x00006256, 0x0000140E, 0x00000A0B, 0x00002CC2, 0x0003003E, 0x00006256, 0x00001CFA, 0x000200F9, + 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r10g11b11_rgba16_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r10g11b11_rgba16_scaled_cs.h new file mode 100644 index 0000000..b429010 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r10g11b11_rgba16_scaled_cs.h @@ -0,0 +1,773 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25175 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_0 = OpConstant %uint 0 + %uint_21 = OpConstant %uint 21 + %515 = OpConstantComposite %v4uint %uint_0 %uint_21 %uint_0 %uint_21 + %uint_1023 = OpConstant %uint 1023 + %uint_2047 = OpConstant %uint 2047 + %1539 = OpConstantComposite %v4uint %uint_1023 %uint_2047 %uint_1023 %uint_2047 + %uint_6 = OpConstant %uint 6 + %uint_5 = OpConstant %uint 5 + %179 = OpConstantComposite %v4uint %uint_6 %uint_5 %uint_6 %uint_5 + %uint_4 = OpConstant %uint 4 + %uint_27 = OpConstant %uint 27 + %791 = OpConstantComposite %v4uint %uint_4 %uint_27 %uint_4 %uint_27 + %uint_63 = OpConstant %uint 63 + %uint_31 = OpConstant %uint 31 + %2327 = OpConstantComposite %v4uint %uint_63 %uint_31 %uint_63 %uint_31 +%uint_2096128 = OpConstant %uint 2096128 + %uint_11 = OpConstant %uint 11 +%uint_2031616 = OpConstant %uint 2031616 + %uint_2 = OpConstant %uint 2 +%uint_4294901760 = OpConstant %uint 4294901760 + %uint_1 = OpConstant %uint 1 + %uint_3 = OpConstant %uint 3 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_16 = OpConstant %uint 16 + %int_5 = OpConstant %int 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2604 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %2686 = OpConstantComposite %v2uint %uint_2096128 %uint_2096128 + %2038 = OpConstantComposite %v2uint %uint_11 %uint_11 + %2884 = OpConstantComposite %v2uint %uint_2031616 %uint_2031616 + %1578 = OpConstantComposite %v2uint %uint_4294901760 %uint_4294901760 + %200 = OpConstantNull %v2uint + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2604 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_8 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_2 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_2 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_2 + %23219 = OpBitwiseAnd %uint %10722 %uint_3 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_2 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %7338 = OpLoad %v4uint %20399 + %13760 = OpIEqual %bool %24990 %uint_1 + %21366 = OpIEqual %bool %24990 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %21313 %16376 %10583 + %19638 = OpIEqual %bool %24990 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %11682 None + OpBranchConditional %15139 %11064 %11682 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11682 + %11682 = OpLabel + %17668 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %22862 = OpVectorShuffle %v2uint %17668 %17668 0 1 + %10663 = OpVectorShuffle %v4uint %17668 %200 0 0 1 1 + %9600 = OpShiftRightLogical %v4uint %10663 %515 + %7908 = OpBitwiseAnd %v4uint %9600 %1539 + %24647 = OpShiftLeftLogical %v4uint %7908 %179 + %22610 = OpShiftRightLogical %v4uint %10663 %791 + %21478 = OpBitwiseAnd %v4uint %22610 %2327 + %15532 = OpBitwiseOr %v4uint %24647 %21478 + %20095 = OpBitwiseAnd %v2uint %22862 %2686 + %22935 = OpShiftLeftLogical %v2uint %20095 %2038 + %17891 = OpBitwiseAnd %v2uint %22862 %2884 + %12396 = OpBitwiseOr %v2uint %22935 %17891 + %15605 = OpVectorShuffle %v2uint %15532 %15532 0 2 + %20933 = OpBitwiseOr %v2uint %15605 %12396 + %19024 = OpCompositeExtract %uint %20933 0 + %7209 = OpCompositeExtract %uint %20933 1 + %23049 = OpVectorShuffle %v2uint %15532 %15532 1 3 + %23934 = OpBitwiseOr %v2uint %23049 %1578 + %19043 = OpCompositeExtract %uint %23934 0 + %23865 = OpCompositeExtract %uint %23934 1 + %16161 = OpCompositeConstruct %v4uint %19024 %19043 %7209 %23865 + %7717 = OpVectorShuffle %v2uint %17668 %17668 2 3 + %9659 = OpVectorShuffle %v4uint %17668 %200 2 2 3 3 + %9601 = OpShiftRightLogical %v4uint %9659 %515 + %7909 = OpBitwiseAnd %v4uint %9601 %1539 + %24648 = OpShiftLeftLogical %v4uint %7909 %179 + %22611 = OpShiftRightLogical %v4uint %9659 %791 + %21479 = OpBitwiseAnd %v4uint %22611 %2327 + %15533 = OpBitwiseOr %v4uint %24648 %21479 + %20096 = OpBitwiseAnd %v2uint %7717 %2686 + %22936 = OpShiftLeftLogical %v2uint %20096 %2038 + %17892 = OpBitwiseAnd %v2uint %7717 %2884 + %12397 = OpBitwiseOr %v2uint %22936 %17892 + %15606 = OpVectorShuffle %v2uint %15533 %15533 0 2 + %20934 = OpBitwiseOr %v2uint %15606 %12397 + %19025 = OpCompositeExtract %uint %20934 0 + %7210 = OpCompositeExtract %uint %20934 1 + %23050 = OpVectorShuffle %v2uint %15533 %15533 1 3 + %23935 = OpBitwiseOr %v2uint %23050 %1578 + %19044 = OpCompositeExtract %uint %23935 0 + %23599 = OpCompositeExtract %uint %23935 1 + %18260 = OpCompositeConstruct %v4uint %19025 %19044 %7210 %23599 + %9680 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %9680 %16161 + %11457 = OpIAdd %uint %11197 %uint_1 + %23711 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11457 + OpStore %23711 %18260 + %23542 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %23542 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_32 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_32 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %24764 %16377 %10584 + OpSelectionMerge %11683 None + OpBranchConditional %15139 %11065 %11683 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11683 + %11683 = OpLabel + %17669 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %22863 = OpVectorShuffle %v2uint %17669 %17669 0 1 + %10664 = OpVectorShuffle %v4uint %17669 %200 0 0 1 1 + %9602 = OpShiftRightLogical %v4uint %10664 %515 + %7910 = OpBitwiseAnd %v4uint %9602 %1539 + %24649 = OpShiftLeftLogical %v4uint %7910 %179 + %22612 = OpShiftRightLogical %v4uint %10664 %791 + %21480 = OpBitwiseAnd %v4uint %22612 %2327 + %15534 = OpBitwiseOr %v4uint %24649 %21480 + %20097 = OpBitwiseAnd %v2uint %22863 %2686 + %22937 = OpShiftLeftLogical %v2uint %20097 %2038 + %17893 = OpBitwiseAnd %v2uint %22863 %2884 + %12398 = OpBitwiseOr %v2uint %22937 %17893 + %15607 = OpVectorShuffle %v2uint %15534 %15534 0 2 + %20935 = OpBitwiseOr %v2uint %15607 %12398 + %19026 = OpCompositeExtract %uint %20935 0 + %7211 = OpCompositeExtract %uint %20935 1 + %23051 = OpVectorShuffle %v2uint %15534 %15534 1 3 + %23936 = OpBitwiseOr %v2uint %23051 %1578 + %19045 = OpCompositeExtract %uint %23936 0 + %23866 = OpCompositeExtract %uint %23936 1 + %16162 = OpCompositeConstruct %v4uint %19026 %19045 %7211 %23866 + %7718 = OpVectorShuffle %v2uint %17669 %17669 2 3 + %9660 = OpVectorShuffle %v4uint %17669 %200 2 2 3 3 + %9603 = OpShiftRightLogical %v4uint %9660 %515 + %7911 = OpBitwiseAnd %v4uint %9603 %1539 + %24650 = OpShiftLeftLogical %v4uint %7911 %179 + %22613 = OpShiftRightLogical %v4uint %9660 %791 + %21481 = OpBitwiseAnd %v4uint %22613 %2327 + %15535 = OpBitwiseOr %v4uint %24650 %21481 + %20098 = OpBitwiseAnd %v2uint %7718 %2686 + %22938 = OpShiftLeftLogical %v2uint %20098 %2038 + %17894 = OpBitwiseAnd %v2uint %7718 %2884 + %12399 = OpBitwiseOr %v2uint %22938 %17894 + %15608 = OpVectorShuffle %v2uint %15535 %15535 0 2 + %20936 = OpBitwiseOr %v2uint %15608 %12399 + %19027 = OpCompositeExtract %uint %20936 0 + %7212 = OpCompositeExtract %uint %20936 1 + %23053 = OpVectorShuffle %v2uint %15535 %15535 1 3 + %23937 = OpBitwiseOr %v2uint %23053 %1578 + %19046 = OpCompositeExtract %uint %23937 0 + %24796 = OpCompositeExtract %uint %23937 1 + %7418 = OpCompositeConstruct %v4uint %19027 %19046 %7212 %24796 + %6665 = OpIAdd %uint %11197 %uint_2 + %24478 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %6665 + OpStore %24478 %16162 + %11458 = OpIAdd %uint %11197 %uint_3 + %25174 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11458 + OpStore %25174 %7418 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r10g11b11_rgba16_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006257, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A49, 0x00000015, + 0x0007002C, 0x00000017, 0x00000203, 0x00000A0A, 0x00000A49, 0x00000A0A, 0x00000A49, 0x0004002B, + 0x0000000B, 0x00000A44, 0x000003FF, 0x0004002B, 0x0000000B, 0x00000A81, 0x000007FF, 0x0007002C, + 0x00000017, 0x00000603, 0x00000A44, 0x00000A81, 0x00000A44, 0x00000A81, 0x0004002B, 0x0000000B, + 0x00000A1C, 0x00000006, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0007002C, 0x00000017, + 0x000000B3, 0x00000A1C, 0x00000A19, 0x00000A1C, 0x00000A19, 0x0004002B, 0x0000000B, 0x00000A16, + 0x00000004, 0x0004002B, 0x0000000B, 0x00000A5B, 0x0000001B, 0x0007002C, 0x00000017, 0x00000317, + 0x00000A16, 0x00000A5B, 0x00000A16, 0x00000A5B, 0x0004002B, 0x0000000B, 0x00000AC7, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A67, 0x0000001F, 0x0007002C, 0x00000017, 0x00000917, 0x00000AC7, + 0x00000A67, 0x00000AC7, 0x00000A67, 0x0004002B, 0x0000000B, 0x000003CF, 0x001FFC00, 0x0004002B, + 0x0000000B, 0x00000A2B, 0x0000000B, 0x0004002B, 0x0000000B, 0x0000008F, 0x001F0000, 0x0004002B, + 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x0000068D, 0xFFFF0000, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, + 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, + 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, + 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, + 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, + 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, + 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, + 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, + 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, + 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, + 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, + 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, + 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, + 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, + 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, 0x00000787, + 0x00000A16, 0x00000A1F, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, + 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, + 0x00000A2C, 0x00000A13, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, + 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, + 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, 0x00000011, + 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0007002C, + 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, + 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, + 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000011, 0x00000A7E, 0x000003CF, 0x000003CF, + 0x0005002C, 0x00000011, 0x000007F6, 0x00000A2B, 0x00000A2B, 0x0005002C, 0x00000011, 0x00000B44, + 0x0000008F, 0x0000008F, 0x0005002C, 0x00000011, 0x0000062A, 0x0000068D, 0x0000068D, 0x0003002E, + 0x00000011, 0x000000C8, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, + 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, + 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, + 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005F7D, 0x00003526, 0x00000A10, 0x000500AB, + 0x00000009, 0x000048EB, 0x00005F7D, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001FCD, 0x00003526, + 0x00000A10, 0x000500C7, 0x0000000B, 0x0000619E, 0x00001FCD, 0x00000A13, 0x00050050, 0x00000011, + 0x000022A7, 0x00003526, 0x00003526, 0x000500C2, 0x00000011, 0x00001BAF, 0x000022A7, 0x00000787, + 0x000500C7, 0x00000011, 0x00001997, 0x00001BAF, 0x000007A2, 0x00050041, 0x00000288, 0x0000492C, + 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, + 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, + 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, + 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, + 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, + 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, + 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, + 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A2C, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, + 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, + 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, + 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, + 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, + 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, + 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, + 0x0000591A, 0x00005BEB, 0x00000A23, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, + 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, + 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, + 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, + 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, + 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00001B12, + 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x00002BBD, 0x00001B12, 0x00000A16, 0x00050051, + 0x0000000B, 0x000029E2, 0x0000538B, 0x00000000, 0x000500C2, 0x0000000B, 0x00001DEE, 0x000029E2, + 0x00000A10, 0x00050051, 0x0000000B, 0x00002704, 0x0000538B, 0x00000001, 0x00050050, 0x00000011, + 0x00005C0B, 0x00001DEE, 0x00002704, 0x00050086, 0x00000011, 0x00001F69, 0x00005C0B, 0x00001997, + 0x00050051, 0x0000000B, 0x0000366C, 0x00001F69, 0x00000000, 0x000500C4, 0x0000000B, 0x00004D4D, + 0x0000366C, 0x00000A10, 0x00050051, 0x0000000B, 0x000051A9, 0x00001F69, 0x00000001, 0x00050051, + 0x0000000B, 0x000059EE, 0x0000538B, 0x00000002, 0x00060050, 0x00000014, 0x000024C9, 0x00004D4D, + 0x000051A9, 0x000059EE, 0x000300F7, 0x00005341, 0x00000002, 0x000400FA, 0x000048EB, 0x0000537D, + 0x00002DD9, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, 0x00002970, 0x000024C9, 0x00050051, + 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, + 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000002, 0x000500C3, 0x0000000C, + 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005789, 0x00000A16, + 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005321, 0x0000405C, + 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, 0x00005321, 0x000500C2, 0x0000000B, + 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, + 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, 0x00002970, + 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, + 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A22, + 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, + 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, + 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, + 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, + 0x00001B88, 0x0000434B, 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, + 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, + 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, + 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, + 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, + 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, + 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, + 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, + 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, + 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, + 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, + 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, + 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, + 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, + 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, + 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, + 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, + 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, + 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005559, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, + 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, 0x0000566F, 0x00005EFA, 0x000200F9, 0x00005341, + 0x000200F8, 0x00002DD9, 0x0007004F, 0x00000011, 0x00002621, 0x000024C9, 0x000024C9, 0x00000000, + 0x00000001, 0x0004007C, 0x00000012, 0x000059CF, 0x00002621, 0x00050051, 0x0000000C, 0x00001903, + 0x000059CF, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FE, 0x00001903, 0x00000A1A, 0x00050051, + 0x0000000C, 0x00002748, 0x000059CF, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, + 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, + 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, + 0x0000000C, 0x00003F5E, 0x000024FE, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, + 0x00000A25, 0x000500C7, 0x0000000C, 0x00002AB6, 0x00001903, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003139, 0x00002748, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, + 0x00004397, 0x00000A10, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, + 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, + 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, + 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, + 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, + 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, + 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, + 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, + 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, + 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, + 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x00001903, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, + 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, + 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x00002E06, + 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4D, 0x00002E06, 0x0004007C, + 0x0000000B, 0x00005670, 0x0000394F, 0x000200F9, 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, + 0x0000000B, 0x000024FC, 0x0000566F, 0x0000537D, 0x00005670, 0x00002DD9, 0x00050084, 0x00000011, + 0x00003FA8, 0x00001F69, 0x00001997, 0x00050082, 0x00000011, 0x00003BBC, 0x00005C0B, 0x00003FA8, + 0x00050051, 0x0000000B, 0x00001C87, 0x00001997, 0x00000000, 0x00050051, 0x0000000B, 0x00005962, + 0x00001997, 0x00000001, 0x00050084, 0x0000000B, 0x00003372, 0x00001C87, 0x00005962, 0x00050084, + 0x0000000B, 0x00003CA0, 0x000024FC, 0x00003372, 0x00050051, 0x0000000B, 0x00003ED4, 0x00003BBC, + 0x00000000, 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, 0x00005962, 0x00050051, 0x0000000B, + 0x00001AE6, 0x00003BBC, 0x00000001, 0x00050080, 0x0000000B, 0x00002B25, 0x00003E12, 0x00001AE6, + 0x000500C4, 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A10, 0x000500C7, 0x0000000B, 0x00005AB3, + 0x000029E2, 0x00000A13, 0x00050080, 0x0000000B, 0x00002557, 0x0000609D, 0x00005AB3, 0x000500C4, + 0x0000000B, 0x000040AD, 0x00002557, 0x00000A10, 0x00050080, 0x0000000B, 0x00004EAA, 0x00003CA0, + 0x000040AD, 0x00050080, 0x0000000B, 0x00003BA9, 0x00005EAC, 0x00004EAA, 0x000500C2, 0x0000000B, + 0x00003948, 0x00003BA9, 0x00000A16, 0x00060041, 0x00000294, 0x00004FAF, 0x0000107A, 0x00000A0B, + 0x00003948, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004FAF, 0x000500AA, 0x00000009, 0x000035C0, + 0x0000619E, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x0000619E, 0x00000A10, 0x000500A6, + 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, + 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, + 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, + 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, + 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, + 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, 0x00005341, 0x00003FF8, + 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x0000619E, 0x00000A13, 0x000500A6, 0x00000009, + 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x00002DA2, 0x00000000, 0x000400FA, 0x00003B23, + 0x00002B38, 0x00002DA2, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, + 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, + 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x00002DA2, 0x000200F8, 0x00002DA2, 0x000700F5, + 0x00000017, 0x00004504, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x0007004F, 0x00000011, + 0x0000594E, 0x00004504, 0x00004504, 0x00000000, 0x00000001, 0x0009004F, 0x00000017, 0x000029A7, + 0x00004504, 0x000000C8, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C2, 0x00000017, + 0x00002580, 0x000029A7, 0x00000203, 0x000500C7, 0x00000017, 0x00001EE4, 0x00002580, 0x00000603, + 0x000500C4, 0x00000017, 0x00006047, 0x00001EE4, 0x000000B3, 0x000500C2, 0x00000017, 0x00005852, + 0x000029A7, 0x00000317, 0x000500C7, 0x00000017, 0x000053E6, 0x00005852, 0x00000917, 0x000500C5, + 0x00000017, 0x00003CAC, 0x00006047, 0x000053E6, 0x000500C7, 0x00000011, 0x00004E7F, 0x0000594E, + 0x00000A7E, 0x000500C4, 0x00000011, 0x00005997, 0x00004E7F, 0x000007F6, 0x000500C7, 0x00000011, + 0x000045E3, 0x0000594E, 0x00000B44, 0x000500C5, 0x00000011, 0x0000306C, 0x00005997, 0x000045E3, + 0x0007004F, 0x00000011, 0x00003CF5, 0x00003CAC, 0x00003CAC, 0x00000000, 0x00000002, 0x000500C5, + 0x00000011, 0x000051C5, 0x00003CF5, 0x0000306C, 0x00050051, 0x0000000B, 0x00004A50, 0x000051C5, + 0x00000000, 0x00050051, 0x0000000B, 0x00001C29, 0x000051C5, 0x00000001, 0x0007004F, 0x00000011, + 0x00005A09, 0x00003CAC, 0x00003CAC, 0x00000001, 0x00000003, 0x000500C5, 0x00000011, 0x00005D7E, + 0x00005A09, 0x0000062A, 0x00050051, 0x0000000B, 0x00004A63, 0x00005D7E, 0x00000000, 0x00050051, + 0x0000000B, 0x00005D39, 0x00005D7E, 0x00000001, 0x00070050, 0x00000017, 0x00003F21, 0x00004A50, + 0x00004A63, 0x00001C29, 0x00005D39, 0x0007004F, 0x00000011, 0x00001E25, 0x00004504, 0x00004504, + 0x00000002, 0x00000003, 0x0009004F, 0x00000017, 0x000025BB, 0x00004504, 0x000000C8, 0x00000002, + 0x00000002, 0x00000003, 0x00000003, 0x000500C2, 0x00000017, 0x00002581, 0x000025BB, 0x00000203, + 0x000500C7, 0x00000017, 0x00001EE5, 0x00002581, 0x00000603, 0x000500C4, 0x00000017, 0x00006048, + 0x00001EE5, 0x000000B3, 0x000500C2, 0x00000017, 0x00005853, 0x000025BB, 0x00000317, 0x000500C7, + 0x00000017, 0x000053E7, 0x00005853, 0x00000917, 0x000500C5, 0x00000017, 0x00003CAD, 0x00006048, + 0x000053E7, 0x000500C7, 0x00000011, 0x00004E80, 0x00001E25, 0x00000A7E, 0x000500C4, 0x00000011, + 0x00005998, 0x00004E80, 0x000007F6, 0x000500C7, 0x00000011, 0x000045E4, 0x00001E25, 0x00000B44, + 0x000500C5, 0x00000011, 0x0000306D, 0x00005998, 0x000045E4, 0x0007004F, 0x00000011, 0x00003CF6, + 0x00003CAD, 0x00003CAD, 0x00000000, 0x00000002, 0x000500C5, 0x00000011, 0x000051C6, 0x00003CF6, + 0x0000306D, 0x00050051, 0x0000000B, 0x00004A51, 0x000051C6, 0x00000000, 0x00050051, 0x0000000B, + 0x00001C2A, 0x000051C6, 0x00000001, 0x0007004F, 0x00000011, 0x00005A0A, 0x00003CAD, 0x00003CAD, + 0x00000001, 0x00000003, 0x000500C5, 0x00000011, 0x00005D7F, 0x00005A0A, 0x0000062A, 0x00050051, + 0x0000000B, 0x00004A64, 0x00005D7F, 0x00000000, 0x00050051, 0x0000000B, 0x00005C2F, 0x00005D7F, + 0x00000001, 0x00070050, 0x00000017, 0x00004754, 0x00004A51, 0x00004A64, 0x00001C2A, 0x00005C2F, + 0x00060041, 0x00000294, 0x000025D0, 0x0000140E, 0x00000A0B, 0x00002BBD, 0x0003003E, 0x000025D0, + 0x00003F21, 0x00050080, 0x0000000B, 0x00002CC1, 0x00002BBD, 0x00000A0D, 0x00060041, 0x00000294, + 0x00005C9F, 0x0000140E, 0x00000A0B, 0x00002CC1, 0x0003003E, 0x00005C9F, 0x00004754, 0x000500AC, + 0x00000009, 0x00005BF6, 0x00001C87, 0x00000A0D, 0x000300F7, 0x000060BC, 0x00000002, 0x000400FA, + 0x00005BF6, 0x00005084, 0x00005094, 0x000200F8, 0x00005084, 0x00050086, 0x0000000B, 0x00003697, + 0x00001DEE, 0x00001C87, 0x00050084, 0x0000000B, 0x0000237E, 0x00003697, 0x00001C87, 0x00050082, + 0x0000000B, 0x00003171, 0x00001DEE, 0x0000237E, 0x00050080, 0x0000000B, 0x00002527, 0x00003171, + 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, 0x00001C87, 0x000300F7, 0x00001EED, + 0x00000000, 0x000400FA, 0x0000343F, 0x0000569E, 0x00002191, 0x000200F8, 0x0000569E, 0x00050084, + 0x0000000B, 0x00004B59, 0x00000A6A, 0x00001C87, 0x000500C4, 0x0000000B, 0x0000540F, 0x00003171, + 0x00000A16, 0x00050082, 0x0000000B, 0x00004944, 0x00004B59, 0x0000540F, 0x000200F9, 0x00001EED, + 0x000200F8, 0x00002191, 0x000200F9, 0x00001EED, 0x000200F8, 0x00001EED, 0x000700F5, 0x0000000B, + 0x0000292C, 0x00004944, 0x0000569E, 0x00000A3A, 0x00002191, 0x000200F9, 0x000060BC, 0x000200F8, + 0x00005094, 0x000200F9, 0x000060BC, 0x000200F8, 0x000060BC, 0x000700F5, 0x0000000B, 0x000029BC, + 0x0000292C, 0x00001EED, 0x00000A6A, 0x00005094, 0x00050084, 0x0000000B, 0x0000492B, 0x000029BC, + 0x00005962, 0x000500C2, 0x0000000B, 0x0000406D, 0x0000492B, 0x00000A16, 0x00050080, 0x0000000B, + 0x0000336B, 0x00003948, 0x0000406D, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, + 0x0000336B, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x00003A1A, 0x00000000, + 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, + 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, + 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, + 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x000060BC, + 0x00003FF9, 0x00002958, 0x000300F7, 0x00002DA3, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, + 0x00002DA3, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, + 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, + 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002DA3, 0x000200F8, 0x00002DA3, 0x000700F5, 0x00000017, + 0x00004505, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x0007004F, 0x00000011, 0x0000594F, + 0x00004505, 0x00004505, 0x00000000, 0x00000001, 0x0009004F, 0x00000017, 0x000029A8, 0x00004505, + 0x000000C8, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C2, 0x00000017, 0x00002582, + 0x000029A8, 0x00000203, 0x000500C7, 0x00000017, 0x00001EE6, 0x00002582, 0x00000603, 0x000500C4, + 0x00000017, 0x00006049, 0x00001EE6, 0x000000B3, 0x000500C2, 0x00000017, 0x00005854, 0x000029A8, + 0x00000317, 0x000500C7, 0x00000017, 0x000053E8, 0x00005854, 0x00000917, 0x000500C5, 0x00000017, + 0x00003CAE, 0x00006049, 0x000053E8, 0x000500C7, 0x00000011, 0x00004E81, 0x0000594F, 0x00000A7E, + 0x000500C4, 0x00000011, 0x00005999, 0x00004E81, 0x000007F6, 0x000500C7, 0x00000011, 0x000045E5, + 0x0000594F, 0x00000B44, 0x000500C5, 0x00000011, 0x0000306E, 0x00005999, 0x000045E5, 0x0007004F, + 0x00000011, 0x00003CF7, 0x00003CAE, 0x00003CAE, 0x00000000, 0x00000002, 0x000500C5, 0x00000011, + 0x000051C7, 0x00003CF7, 0x0000306E, 0x00050051, 0x0000000B, 0x00004A52, 0x000051C7, 0x00000000, + 0x00050051, 0x0000000B, 0x00001C2B, 0x000051C7, 0x00000001, 0x0007004F, 0x00000011, 0x00005A0B, + 0x00003CAE, 0x00003CAE, 0x00000001, 0x00000003, 0x000500C5, 0x00000011, 0x00005D80, 0x00005A0B, + 0x0000062A, 0x00050051, 0x0000000B, 0x00004A65, 0x00005D80, 0x00000000, 0x00050051, 0x0000000B, + 0x00005D3A, 0x00005D80, 0x00000001, 0x00070050, 0x00000017, 0x00003F22, 0x00004A52, 0x00004A65, + 0x00001C2B, 0x00005D3A, 0x0007004F, 0x00000011, 0x00001E26, 0x00004505, 0x00004505, 0x00000002, + 0x00000003, 0x0009004F, 0x00000017, 0x000025BC, 0x00004505, 0x000000C8, 0x00000002, 0x00000002, + 0x00000003, 0x00000003, 0x000500C2, 0x00000017, 0x00002583, 0x000025BC, 0x00000203, 0x000500C7, + 0x00000017, 0x00001EE7, 0x00002583, 0x00000603, 0x000500C4, 0x00000017, 0x0000604A, 0x00001EE7, + 0x000000B3, 0x000500C2, 0x00000017, 0x00005855, 0x000025BC, 0x00000317, 0x000500C7, 0x00000017, + 0x000053E9, 0x00005855, 0x00000917, 0x000500C5, 0x00000017, 0x00003CAF, 0x0000604A, 0x000053E9, + 0x000500C7, 0x00000011, 0x00004E82, 0x00001E26, 0x00000A7E, 0x000500C4, 0x00000011, 0x0000599A, + 0x00004E82, 0x000007F6, 0x000500C7, 0x00000011, 0x000045E6, 0x00001E26, 0x00000B44, 0x000500C5, + 0x00000011, 0x0000306F, 0x0000599A, 0x000045E6, 0x0007004F, 0x00000011, 0x00003CF8, 0x00003CAF, + 0x00003CAF, 0x00000000, 0x00000002, 0x000500C5, 0x00000011, 0x000051C8, 0x00003CF8, 0x0000306F, + 0x00050051, 0x0000000B, 0x00004A53, 0x000051C8, 0x00000000, 0x00050051, 0x0000000B, 0x00001C2C, + 0x000051C8, 0x00000001, 0x0007004F, 0x00000011, 0x00005A0D, 0x00003CAF, 0x00003CAF, 0x00000001, + 0x00000003, 0x000500C5, 0x00000011, 0x00005D81, 0x00005A0D, 0x0000062A, 0x00050051, 0x0000000B, + 0x00004A66, 0x00005D81, 0x00000000, 0x00050051, 0x0000000B, 0x000060DC, 0x00005D81, 0x00000001, + 0x00070050, 0x00000017, 0x00001CFA, 0x00004A53, 0x00004A66, 0x00001C2C, 0x000060DC, 0x00050080, + 0x0000000B, 0x00001A09, 0x00002BBD, 0x00000A10, 0x00060041, 0x00000294, 0x00005F9E, 0x0000140E, + 0x00000A0B, 0x00001A09, 0x0003003E, 0x00005F9E, 0x00003F22, 0x00050080, 0x0000000B, 0x00002CC2, + 0x00002BBD, 0x00000A13, 0x00060041, 0x00000294, 0x00006256, 0x0000140E, 0x00000A0B, 0x00002CC2, + 0x0003003E, 0x00006256, 0x00001CFA, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, + 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r10g11b11_rgba16_snorm_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r10g11b11_rgba16_snorm_cs.h new file mode 100644 index 0000000..636ad69 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r10g11b11_rgba16_snorm_cs.h @@ -0,0 +1,931 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25175 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_9 = OpConstant %uint 9 + %v2bool = OpTypeVector %bool 2 + %uint_0 = OpConstant %uint 0 + %uint_513 = OpConstant %uint 513 + %uint_512 = OpConstant %uint 512 + %uint_1023 = OpConstant %uint 1023 + %uint_6 = OpConstant %uint 6 + %uint_3 = OpConstant %uint 3 + %uint_65535 = OpConstant %uint 65535 + %uint_10 = OpConstant %uint 10 + %uint_1025 = OpConstant %uint 1025 + %uint_1024 = OpConstant %uint 1024 + %uint_2047 = OpConstant %uint 2047 + %uint_5 = OpConstant %uint 5 + %uint_16 = OpConstant %uint 16 + %uint_21 = OpConstant %uint 21 +%uint_2147418112 = OpConstant %uint 2147418112 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2603 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %2213 = OpConstantComposite %v2uint %uint_1023 %uint_1023 + %1996 = OpConstantComposite %v2uint %uint_9 %uint_9 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %536 = OpConstantComposite %v2uint %uint_513 %uint_513 + %515 = OpConstantComposite %v2uint %uint_512 %uint_512 + %1933 = OpConstantComposite %v2uint %uint_6 %uint_6 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2015 = OpConstantComposite %v2uint %uint_65535 %uint_65535 + %2017 = OpConstantComposite %v2uint %uint_10 %uint_10 + %2640 = OpConstantComposite %v2uint %uint_2047 %uint_2047 + %2255 = OpConstantComposite %v2uint %uint_1025 %uint_1025 + %2234 = OpConstantComposite %v2uint %uint_1024 %uint_1024 + %1912 = OpConstantComposite %v2uint %uint_5 %uint_5 + %2143 = OpConstantComposite %v2uint %uint_16 %uint_16 + %2248 = OpConstantComposite %v2uint %uint_21 %uint_21 + %883 = OpConstantComposite %v2uint %uint_2147418112 %uint_2147418112 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2603 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_8 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %19442 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %19442 = OpLabel + %8677 = OpIMul %int %23531 %int_4 + %17569 = OpBitcast %int %22409 + %8690 = OpIMul %int %6362 %17569 + %8334 = OpIAdd %int %8690 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %8677 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %19442 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %11682 None + OpBranchConditional %15139 %11064 %11682 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11682 + %11682 = OpLabel + %19948 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %21173 = OpVectorShuffle %v2uint %19948 %19948 0 1 + %12206 = OpBitwiseAnd %v2uint %21173 %2213 + %6898 = OpShiftRightLogical %v2uint %12206 %1996 + %12708 = OpINotEqual %v2bool %6898 %1807 + %20140 = OpIEqual %v2bool %12206 %515 + %7655 = OpSelect %v2uint %20140 %536 %12206 + %23050 = OpSelect %v2uint %12708 %2213 %1807 + %23672 = OpBitwiseXor %v2uint %7655 %23050 + %24500 = OpIAdd %v2uint %23672 %6898 + %8872 = OpShiftLeftLogical %v2uint %24500 %1933 + %13590 = OpShiftRightLogical %v2uint %24500 %1870 + %23618 = OpBitwiseOr %v2uint %8872 %13590 + %15463 = OpSelect %v2uint %12708 %2015 %1807 + %7774 = OpBitwiseXor %v2uint %23618 %15463 + %24941 = OpIAdd %v2uint %7774 %6898 + %24336 = OpShiftRightLogical %v2uint %21173 %2017 + %11822 = OpBitwiseAnd %v2uint %24336 %2640 + %6319 = OpShiftRightLogical %v2uint %11822 %2017 + %12709 = OpINotEqual %v2bool %6319 %1807 + %20141 = OpIEqual %v2bool %11822 %2234 + %7656 = OpSelect %v2uint %20141 %2255 %11822 + %23051 = OpSelect %v2uint %12709 %2640 %1807 + %23673 = OpBitwiseXor %v2uint %7656 %23051 + %24501 = OpIAdd %v2uint %23673 %6319 + %8873 = OpShiftLeftLogical %v2uint %24501 %1912 + %13591 = OpShiftRightLogical %v2uint %24501 %1912 + %23619 = OpBitwiseOr %v2uint %8873 %13591 + %15464 = OpSelect %v2uint %12709 %2015 %1807 + %7812 = OpBitwiseXor %v2uint %23619 %15464 + %24557 = OpIAdd %v2uint %7812 %6319 + %8296 = OpShiftLeftLogical %v2uint %24557 %2143 + %9076 = OpBitwiseOr %v2uint %24941 %8296 + %23541 = OpShiftRightLogical %v2uint %21173 %2248 + %13212 = OpShiftRightLogical %v2uint %23541 %2017 + %11904 = OpINotEqual %v2bool %13212 %1807 + %20142 = OpIEqual %v2bool %23541 %2234 + %7657 = OpSelect %v2uint %20142 %2255 %23541 + %23053 = OpSelect %v2uint %11904 %2640 %1807 + %23674 = OpBitwiseXor %v2uint %7657 %23053 + %24502 = OpIAdd %v2uint %23674 %13212 + %8874 = OpShiftLeftLogical %v2uint %24502 %1912 + %13592 = OpShiftRightLogical %v2uint %24502 %1912 + %23620 = OpBitwiseOr %v2uint %8874 %13592 + %15465 = OpSelect %v2uint %11904 %2015 %1807 + %7831 = OpBitwiseXor %v2uint %23620 %15465 + %22180 = OpIAdd %v2uint %7831 %13212 + %18024 = OpBitwiseOr %v2uint %22180 %883 + %10453 = OpCompositeExtract %uint %9076 0 + %23730 = OpCompositeExtract %uint %9076 1 + %7641 = OpCompositeExtract %uint %18024 0 + %7795 = OpCompositeExtract %uint %18024 1 + %16161 = OpCompositeConstruct %v4uint %10453 %23730 %7641 %7795 + %7813 = OpVectorShuffle %v4uint %16161 %16161 0 2 1 3 + %8699 = OpVectorShuffle %v2uint %19948 %19948 2 3 + %7167 = OpBitwiseAnd %v2uint %8699 %2213 + %6899 = OpShiftRightLogical %v2uint %7167 %1996 + %12710 = OpINotEqual %v2bool %6899 %1807 + %20143 = OpIEqual %v2bool %7167 %515 + %7658 = OpSelect %v2uint %20143 %536 %7167 + %23054 = OpSelect %v2uint %12710 %2213 %1807 + %23675 = OpBitwiseXor %v2uint %7658 %23054 + %24503 = OpIAdd %v2uint %23675 %6899 + %8875 = OpShiftLeftLogical %v2uint %24503 %1933 + %13593 = OpShiftRightLogical %v2uint %24503 %1870 + %23621 = OpBitwiseOr %v2uint %8875 %13593 + %15466 = OpSelect %v2uint %12710 %2015 %1807 + %7775 = OpBitwiseXor %v2uint %23621 %15466 + %24942 = OpIAdd %v2uint %7775 %6899 + %24337 = OpShiftRightLogical %v2uint %8699 %2017 + %11823 = OpBitwiseAnd %v2uint %24337 %2640 + %6320 = OpShiftRightLogical %v2uint %11823 %2017 + %12711 = OpINotEqual %v2bool %6320 %1807 + %20144 = OpIEqual %v2bool %11823 %2234 + %7659 = OpSelect %v2uint %20144 %2255 %11823 + %23055 = OpSelect %v2uint %12711 %2640 %1807 + %23676 = OpBitwiseXor %v2uint %7659 %23055 + %24504 = OpIAdd %v2uint %23676 %6320 + %8876 = OpShiftLeftLogical %v2uint %24504 %1912 + %13594 = OpShiftRightLogical %v2uint %24504 %1912 + %23622 = OpBitwiseOr %v2uint %8876 %13594 + %15467 = OpSelect %v2uint %12711 %2015 %1807 + %7814 = OpBitwiseXor %v2uint %23622 %15467 + %24559 = OpIAdd %v2uint %7814 %6320 + %8297 = OpShiftLeftLogical %v2uint %24559 %2143 + %9077 = OpBitwiseOr %v2uint %24942 %8297 + %23542 = OpShiftRightLogical %v2uint %8699 %2248 + %13213 = OpShiftRightLogical %v2uint %23542 %2017 + %11905 = OpINotEqual %v2bool %13213 %1807 + %20145 = OpIEqual %v2bool %23542 %2234 + %7660 = OpSelect %v2uint %20145 %2255 %23542 + %23056 = OpSelect %v2uint %11905 %2640 %1807 + %23677 = OpBitwiseXor %v2uint %7660 %23056 + %24505 = OpIAdd %v2uint %23677 %13213 + %8877 = OpShiftLeftLogical %v2uint %24505 %1912 + %13595 = OpShiftRightLogical %v2uint %24505 %1912 + %23623 = OpBitwiseOr %v2uint %8877 %13595 + %15468 = OpSelect %v2uint %11905 %2015 %1807 + %7832 = OpBitwiseXor %v2uint %23623 %15468 + %22181 = OpIAdd %v2uint %7832 %13213 + %18025 = OpBitwiseOr %v2uint %22181 %883 + %10454 = OpCompositeExtract %uint %9077 0 + %23731 = OpCompositeExtract %uint %9077 1 + %7642 = OpCompositeExtract %uint %18025 0 + %7796 = OpCompositeExtract %uint %18025 1 + %15895 = OpCompositeConstruct %v4uint %10454 %23731 %7642 %7796 + %7631 = OpVectorShuffle %v4uint %15895 %15895 0 2 1 3 + %12351 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %12351 %7813 + %11457 = OpIAdd %uint %21685 %uint_1 + %25136 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11457 + OpStore %25136 %7631 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_32 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %6871 %16377 %10584 + OpSelectionMerge %11683 None + OpBranchConditional %15139 %11065 %11683 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11683 + %11683 = OpLabel + %19949 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %21174 = OpVectorShuffle %v2uint %19949 %19949 0 1 + %12207 = OpBitwiseAnd %v2uint %21174 %2213 + %6900 = OpShiftRightLogical %v2uint %12207 %1996 + %12712 = OpINotEqual %v2bool %6900 %1807 + %20146 = OpIEqual %v2bool %12207 %515 + %7661 = OpSelect %v2uint %20146 %536 %12207 + %23057 = OpSelect %v2uint %12712 %2213 %1807 + %23678 = OpBitwiseXor %v2uint %7661 %23057 + %24506 = OpIAdd %v2uint %23678 %6900 + %8878 = OpShiftLeftLogical %v2uint %24506 %1933 + %13596 = OpShiftRightLogical %v2uint %24506 %1870 + %23624 = OpBitwiseOr %v2uint %8878 %13596 + %15469 = OpSelect %v2uint %12712 %2015 %1807 + %7776 = OpBitwiseXor %v2uint %23624 %15469 + %24943 = OpIAdd %v2uint %7776 %6900 + %24338 = OpShiftRightLogical %v2uint %21174 %2017 + %11824 = OpBitwiseAnd %v2uint %24338 %2640 + %6321 = OpShiftRightLogical %v2uint %11824 %2017 + %12713 = OpINotEqual %v2bool %6321 %1807 + %20147 = OpIEqual %v2bool %11824 %2234 + %7662 = OpSelect %v2uint %20147 %2255 %11824 + %23058 = OpSelect %v2uint %12713 %2640 %1807 + %23679 = OpBitwiseXor %v2uint %7662 %23058 + %24507 = OpIAdd %v2uint %23679 %6321 + %8879 = OpShiftLeftLogical %v2uint %24507 %1912 + %13597 = OpShiftRightLogical %v2uint %24507 %1912 + %23625 = OpBitwiseOr %v2uint %8879 %13597 + %15470 = OpSelect %v2uint %12713 %2015 %1807 + %7815 = OpBitwiseXor %v2uint %23625 %15470 + %24560 = OpIAdd %v2uint %7815 %6321 + %8298 = OpShiftLeftLogical %v2uint %24560 %2143 + %9078 = OpBitwiseOr %v2uint %24943 %8298 + %23543 = OpShiftRightLogical %v2uint %21174 %2248 + %13214 = OpShiftRightLogical %v2uint %23543 %2017 + %11906 = OpINotEqual %v2bool %13214 %1807 + %20148 = OpIEqual %v2bool %23543 %2234 + %7663 = OpSelect %v2uint %20148 %2255 %23543 + %23059 = OpSelect %v2uint %11906 %2640 %1807 + %23680 = OpBitwiseXor %v2uint %7663 %23059 + %24508 = OpIAdd %v2uint %23680 %13214 + %8880 = OpShiftLeftLogical %v2uint %24508 %1912 + %13598 = OpShiftRightLogical %v2uint %24508 %1912 + %23626 = OpBitwiseOr %v2uint %8880 %13598 + %15471 = OpSelect %v2uint %11906 %2015 %1807 + %7833 = OpBitwiseXor %v2uint %23626 %15471 + %22182 = OpIAdd %v2uint %7833 %13214 + %18026 = OpBitwiseOr %v2uint %22182 %883 + %10455 = OpCompositeExtract %uint %9078 0 + %23732 = OpCompositeExtract %uint %9078 1 + %7643 = OpCompositeExtract %uint %18026 0 + %7797 = OpCompositeExtract %uint %18026 1 + %16162 = OpCompositeConstruct %v4uint %10455 %23732 %7643 %7797 + %7816 = OpVectorShuffle %v4uint %16162 %16162 0 2 1 3 + %8700 = OpVectorShuffle %v2uint %19949 %19949 2 3 + %7168 = OpBitwiseAnd %v2uint %8700 %2213 + %6901 = OpShiftRightLogical %v2uint %7168 %1996 + %12714 = OpINotEqual %v2bool %6901 %1807 + %20149 = OpIEqual %v2bool %7168 %515 + %7664 = OpSelect %v2uint %20149 %536 %7168 + %23060 = OpSelect %v2uint %12714 %2213 %1807 + %23681 = OpBitwiseXor %v2uint %7664 %23060 + %24509 = OpIAdd %v2uint %23681 %6901 + %8881 = OpShiftLeftLogical %v2uint %24509 %1933 + %13599 = OpShiftRightLogical %v2uint %24509 %1870 + %23627 = OpBitwiseOr %v2uint %8881 %13599 + %15472 = OpSelect %v2uint %12714 %2015 %1807 + %7777 = OpBitwiseXor %v2uint %23627 %15472 + %24944 = OpIAdd %v2uint %7777 %6901 + %24339 = OpShiftRightLogical %v2uint %8700 %2017 + %11825 = OpBitwiseAnd %v2uint %24339 %2640 + %6322 = OpShiftRightLogical %v2uint %11825 %2017 + %12715 = OpINotEqual %v2bool %6322 %1807 + %20150 = OpIEqual %v2bool %11825 %2234 + %7665 = OpSelect %v2uint %20150 %2255 %11825 + %23061 = OpSelect %v2uint %12715 %2640 %1807 + %23682 = OpBitwiseXor %v2uint %7665 %23061 + %24510 = OpIAdd %v2uint %23682 %6322 + %8882 = OpShiftLeftLogical %v2uint %24510 %1912 + %13600 = OpShiftRightLogical %v2uint %24510 %1912 + %23628 = OpBitwiseOr %v2uint %8882 %13600 + %15473 = OpSelect %v2uint %12715 %2015 %1807 + %7817 = OpBitwiseXor %v2uint %23628 %15473 + %24561 = OpIAdd %v2uint %7817 %6322 + %8299 = OpShiftLeftLogical %v2uint %24561 %2143 + %9079 = OpBitwiseOr %v2uint %24944 %8299 + %23544 = OpShiftRightLogical %v2uint %8700 %2248 + %13215 = OpShiftRightLogical %v2uint %23544 %2017 + %11907 = OpINotEqual %v2bool %13215 %1807 + %20151 = OpIEqual %v2bool %23544 %2234 + %7666 = OpSelect %v2uint %20151 %2255 %23544 + %23062 = OpSelect %v2uint %11907 %2640 %1807 + %23683 = OpBitwiseXor %v2uint %7666 %23062 + %24511 = OpIAdd %v2uint %23683 %13215 + %8883 = OpShiftLeftLogical %v2uint %24511 %1912 + %13601 = OpShiftRightLogical %v2uint %24511 %1912 + %23629 = OpBitwiseOr %v2uint %8883 %13601 + %15474 = OpSelect %v2uint %11907 %2015 %1807 + %7834 = OpBitwiseXor %v2uint %23629 %15474 + %22183 = OpIAdd %v2uint %7834 %13215 + %18027 = OpBitwiseOr %v2uint %22183 %883 + %10456 = OpCompositeExtract %uint %9079 0 + %23733 = OpCompositeExtract %uint %9079 1 + %7644 = OpCompositeExtract %uint %18027 0 + %7798 = OpCompositeExtract %uint %18027 1 + %17092 = OpCompositeConstruct %v4uint %10456 %23733 %7644 %7798 + %15860 = OpVectorShuffle %v4uint %17092 %17092 0 2 1 3 + %21950 = OpIAdd %uint %21685 %uint_2 + %7829 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21950 + OpStore %7829 %7816 + %11458 = OpIAdd %uint %21685 %uint_3 + %25174 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11458 + OpStore %25174 %15860 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r10g11b11_rgba16_snorm_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006257, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x0000044A, 0x00000201, + 0x0004002B, 0x0000000B, 0x00000447, 0x00000200, 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, + 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x000001C1, 0x0000FFFF, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, + 0x0004002B, 0x0000000B, 0x00000A4A, 0x00000401, 0x0004002B, 0x0000000B, 0x00000A47, 0x00000400, + 0x0004002B, 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A49, 0x00000015, + 0x0004002B, 0x0000000B, 0x000003D6, 0x7FFF0000, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, + 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, + 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, + 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, + 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x00040020, 0x00000291, + 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, + 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A2B, 0x00000A13, 0x00000A0A, 0x00000A0A, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, + 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, + 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0007002C, 0x00000017, + 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, + 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, + 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000011, 0x000008A5, 0x00000A44, 0x00000A44, 0x0005002C, + 0x00000011, 0x000007CC, 0x00000A25, 0x00000A25, 0x0005002C, 0x00000011, 0x0000070F, 0x00000A0A, + 0x00000A0A, 0x0005002C, 0x00000011, 0x00000218, 0x0000044A, 0x0000044A, 0x0005002C, 0x00000011, + 0x00000203, 0x00000447, 0x00000447, 0x0005002C, 0x00000011, 0x0000078D, 0x00000A1C, 0x00000A1C, + 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, 0x0005002C, 0x00000011, 0x000007DF, + 0x000001C1, 0x000001C1, 0x0005002C, 0x00000011, 0x000007E1, 0x00000A28, 0x00000A28, 0x0005002C, + 0x00000011, 0x00000A50, 0x00000A81, 0x00000A81, 0x0005002C, 0x00000011, 0x000008CF, 0x00000A4A, + 0x00000A4A, 0x0005002C, 0x00000011, 0x000008BA, 0x00000A47, 0x00000A47, 0x0005002C, 0x00000011, + 0x00000778, 0x00000A19, 0x00000A19, 0x0005002C, 0x00000011, 0x0000085F, 0x00000A3A, 0x00000A3A, + 0x0005002C, 0x00000011, 0x000008C8, 0x00000A49, 0x00000A49, 0x0005002C, 0x00000011, 0x00000373, + 0x000003D6, 0x000003D6, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, + 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, + 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, + 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, 0x000500AB, + 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, 0x00003526, + 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, 0x0000000B, + 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, 0x00000A13, + 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, + 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, + 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, + 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, + 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, + 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, + 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, + 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A2B, 0x0007004F, + 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, + 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, + 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, + 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, + 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, + 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, + 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A23, 0x00050051, 0x0000000C, + 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, + 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, + 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, + 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, + 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, + 0x00050080, 0x0000000B, 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x000054B5, + 0x00002764, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, 0x00005768, + 0x00004BF2, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, 0x00004384, + 0x00002BF8, 0x000018D9, 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, 0x000032B3, 0x000044BE, + 0x00000A17, 0x000500C3, 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, 0x000500C2, 0x0000000B, + 0x00004947, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00004947, 0x00050084, + 0x0000000C, 0x00005321, 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000032B3, + 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, + 0x00003901, 0x00002348, 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, 0x00003901, 0x000500C3, + 0x0000000C, 0x000032BA, 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, 0x00005FEE, 0x000032BA, + 0x000020F4, 0x000500C4, 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A22, 0x000500C7, 0x0000000C, + 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, + 0x000044BE, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, + 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, + 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, + 0x00002215, 0x000044BE, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000601E, + 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, + 0x00005BEB, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, + 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, + 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, + 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, + 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, + 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x000018DA, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, 0x00050080, 0x0000000C, + 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000044BE, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, + 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, + 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, + 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, + 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, + 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, + 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, 0x00005EA0, + 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, 0x000019AD, 0x000042F0, + 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, + 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, 0x00000001, 0x000500C3, + 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005788, + 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, + 0x0000405C, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, + 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002AB6, 0x000042C2, + 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, + 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, + 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, 0x0000000C, 0x000027B1, + 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, + 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, + 0x000047B5, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, + 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, + 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, + 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, + 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, + 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, + 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, + 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, + 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x00002F42, + 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, 0x0000000C, + 0x0000292C, 0x000054ED, 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, 0x00005F43, 0x000200F8, + 0x00004BF2, 0x00050084, 0x0000000C, 0x000021E5, 0x00005BEB, 0x00000A17, 0x0004007C, 0x0000000C, + 0x000044A1, 0x00005789, 0x00050084, 0x0000000C, 0x000021F2, 0x000018DA, 0x000044A1, 0x00050080, + 0x0000000C, 0x0000208E, 0x000021F2, 0x000044BE, 0x0004007C, 0x0000000C, 0x000022F8, 0x00005788, + 0x00050084, 0x0000000C, 0x00001E9F, 0x0000208E, 0x000022F8, 0x00050080, 0x0000000C, 0x00001F30, + 0x000021E5, 0x00001E9F, 0x000200F9, 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, + 0x00002A3E, 0x0000292C, 0x00001E0B, 0x00001F30, 0x00004BF2, 0x0004007C, 0x0000000C, 0x00001A3F, + 0x00005EAC, 0x00050080, 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, + 0x00003EE9, 0x000056CD, 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, + 0x00000294, 0x00004315, 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00001CAA, + 0x00004315, 0x000500AA, 0x00000009, 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, 0x00000009, + 0x00005376, 0x000061E2, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, 0x00005376, + 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, + 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, + 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, + 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, + 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, + 0x00005879, 0x00001CAA, 0x00005F43, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, + 0x000061E2, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, + 0x00002DA2, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x00002DA2, 0x000200F8, 0x00002B38, + 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, + 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, + 0x00002DA2, 0x000200F8, 0x00002DA2, 0x000700F5, 0x00000017, 0x00004DEC, 0x00005879, 0x00003463, + 0x000029E8, 0x00002B38, 0x0007004F, 0x00000011, 0x000052B5, 0x00004DEC, 0x00004DEC, 0x00000000, + 0x00000001, 0x000500C7, 0x00000011, 0x00002FAE, 0x000052B5, 0x000008A5, 0x000500C2, 0x00000011, + 0x00001AF2, 0x00002FAE, 0x000007CC, 0x000500AB, 0x0000000F, 0x000031A4, 0x00001AF2, 0x0000070F, + 0x000500AA, 0x0000000F, 0x00004EAC, 0x00002FAE, 0x00000203, 0x000600A9, 0x00000011, 0x00001DE7, + 0x00004EAC, 0x00000218, 0x00002FAE, 0x000600A9, 0x00000011, 0x00005A0A, 0x000031A4, 0x000008A5, + 0x0000070F, 0x000500C6, 0x00000011, 0x00005C78, 0x00001DE7, 0x00005A0A, 0x00050080, 0x00000011, + 0x00005FB4, 0x00005C78, 0x00001AF2, 0x000500C4, 0x00000011, 0x000022A8, 0x00005FB4, 0x0000078D, + 0x000500C2, 0x00000011, 0x00003516, 0x00005FB4, 0x0000074E, 0x000500C5, 0x00000011, 0x00005C42, + 0x000022A8, 0x00003516, 0x000600A9, 0x00000011, 0x00003C67, 0x000031A4, 0x000007DF, 0x0000070F, + 0x000500C6, 0x00000011, 0x00001E5E, 0x00005C42, 0x00003C67, 0x00050080, 0x00000011, 0x0000616D, + 0x00001E5E, 0x00001AF2, 0x000500C2, 0x00000011, 0x00005F10, 0x000052B5, 0x000007E1, 0x000500C7, + 0x00000011, 0x00002E2E, 0x00005F10, 0x00000A50, 0x000500C2, 0x00000011, 0x000018AF, 0x00002E2E, + 0x000007E1, 0x000500AB, 0x0000000F, 0x000031A5, 0x000018AF, 0x0000070F, 0x000500AA, 0x0000000F, + 0x00004EAD, 0x00002E2E, 0x000008BA, 0x000600A9, 0x00000011, 0x00001DE8, 0x00004EAD, 0x000008CF, + 0x00002E2E, 0x000600A9, 0x00000011, 0x00005A0B, 0x000031A5, 0x00000A50, 0x0000070F, 0x000500C6, + 0x00000011, 0x00005C79, 0x00001DE8, 0x00005A0B, 0x00050080, 0x00000011, 0x00005FB5, 0x00005C79, + 0x000018AF, 0x000500C4, 0x00000011, 0x000022A9, 0x00005FB5, 0x00000778, 0x000500C2, 0x00000011, + 0x00003517, 0x00005FB5, 0x00000778, 0x000500C5, 0x00000011, 0x00005C43, 0x000022A9, 0x00003517, + 0x000600A9, 0x00000011, 0x00003C68, 0x000031A5, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, + 0x00001E84, 0x00005C43, 0x00003C68, 0x00050080, 0x00000011, 0x00005FED, 0x00001E84, 0x000018AF, + 0x000500C4, 0x00000011, 0x00002068, 0x00005FED, 0x0000085F, 0x000500C5, 0x00000011, 0x00002374, + 0x0000616D, 0x00002068, 0x000500C2, 0x00000011, 0x00005BF5, 0x000052B5, 0x000008C8, 0x000500C2, + 0x00000011, 0x0000339C, 0x00005BF5, 0x000007E1, 0x000500AB, 0x0000000F, 0x00002E80, 0x0000339C, + 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EAE, 0x00005BF5, 0x000008BA, 0x000600A9, 0x00000011, + 0x00001DE9, 0x00004EAE, 0x000008CF, 0x00005BF5, 0x000600A9, 0x00000011, 0x00005A0D, 0x00002E80, + 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C7A, 0x00001DE9, 0x00005A0D, 0x00050080, + 0x00000011, 0x00005FB6, 0x00005C7A, 0x0000339C, 0x000500C4, 0x00000011, 0x000022AA, 0x00005FB6, + 0x00000778, 0x000500C2, 0x00000011, 0x00003518, 0x00005FB6, 0x00000778, 0x000500C5, 0x00000011, + 0x00005C44, 0x000022AA, 0x00003518, 0x000600A9, 0x00000011, 0x00003C69, 0x00002E80, 0x000007DF, + 0x0000070F, 0x000500C6, 0x00000011, 0x00001E97, 0x00005C44, 0x00003C69, 0x00050080, 0x00000011, + 0x000056A4, 0x00001E97, 0x0000339C, 0x000500C5, 0x00000011, 0x00004668, 0x000056A4, 0x00000373, + 0x00050051, 0x0000000B, 0x000028D5, 0x00002374, 0x00000000, 0x00050051, 0x0000000B, 0x00005CB2, + 0x00002374, 0x00000001, 0x00050051, 0x0000000B, 0x00001DD9, 0x00004668, 0x00000000, 0x00050051, + 0x0000000B, 0x00001E73, 0x00004668, 0x00000001, 0x00070050, 0x00000017, 0x00003F21, 0x000028D5, + 0x00005CB2, 0x00001DD9, 0x00001E73, 0x0009004F, 0x00000017, 0x00001E85, 0x00003F21, 0x00003F21, + 0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x0007004F, 0x00000011, 0x000021FB, 0x00004DEC, + 0x00004DEC, 0x00000002, 0x00000003, 0x000500C7, 0x00000011, 0x00001BFF, 0x000021FB, 0x000008A5, + 0x000500C2, 0x00000011, 0x00001AF3, 0x00001BFF, 0x000007CC, 0x000500AB, 0x0000000F, 0x000031A6, + 0x00001AF3, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EAF, 0x00001BFF, 0x00000203, 0x000600A9, + 0x00000011, 0x00001DEA, 0x00004EAF, 0x00000218, 0x00001BFF, 0x000600A9, 0x00000011, 0x00005A0E, + 0x000031A6, 0x000008A5, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C7B, 0x00001DEA, 0x00005A0E, + 0x00050080, 0x00000011, 0x00005FB7, 0x00005C7B, 0x00001AF3, 0x000500C4, 0x00000011, 0x000022AB, + 0x00005FB7, 0x0000078D, 0x000500C2, 0x00000011, 0x00003519, 0x00005FB7, 0x0000074E, 0x000500C5, + 0x00000011, 0x00005C45, 0x000022AB, 0x00003519, 0x000600A9, 0x00000011, 0x00003C6A, 0x000031A6, + 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E5F, 0x00005C45, 0x00003C6A, 0x00050080, + 0x00000011, 0x0000616E, 0x00001E5F, 0x00001AF3, 0x000500C2, 0x00000011, 0x00005F11, 0x000021FB, + 0x000007E1, 0x000500C7, 0x00000011, 0x00002E2F, 0x00005F11, 0x00000A50, 0x000500C2, 0x00000011, + 0x000018B0, 0x00002E2F, 0x000007E1, 0x000500AB, 0x0000000F, 0x000031A7, 0x000018B0, 0x0000070F, + 0x000500AA, 0x0000000F, 0x00004EB0, 0x00002E2F, 0x000008BA, 0x000600A9, 0x00000011, 0x00001DEB, + 0x00004EB0, 0x000008CF, 0x00002E2F, 0x000600A9, 0x00000011, 0x00005A0F, 0x000031A7, 0x00000A50, + 0x0000070F, 0x000500C6, 0x00000011, 0x00005C7C, 0x00001DEB, 0x00005A0F, 0x00050080, 0x00000011, + 0x00005FB8, 0x00005C7C, 0x000018B0, 0x000500C4, 0x00000011, 0x000022AC, 0x00005FB8, 0x00000778, + 0x000500C2, 0x00000011, 0x0000351A, 0x00005FB8, 0x00000778, 0x000500C5, 0x00000011, 0x00005C46, + 0x000022AC, 0x0000351A, 0x000600A9, 0x00000011, 0x00003C6B, 0x000031A7, 0x000007DF, 0x0000070F, + 0x000500C6, 0x00000011, 0x00001E86, 0x00005C46, 0x00003C6B, 0x00050080, 0x00000011, 0x00005FEF, + 0x00001E86, 0x000018B0, 0x000500C4, 0x00000011, 0x00002069, 0x00005FEF, 0x0000085F, 0x000500C5, + 0x00000011, 0x00002375, 0x0000616E, 0x00002069, 0x000500C2, 0x00000011, 0x00005BF6, 0x000021FB, + 0x000008C8, 0x000500C2, 0x00000011, 0x0000339D, 0x00005BF6, 0x000007E1, 0x000500AB, 0x0000000F, + 0x00002E81, 0x0000339D, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB1, 0x00005BF6, 0x000008BA, + 0x000600A9, 0x00000011, 0x00001DEC, 0x00004EB1, 0x000008CF, 0x00005BF6, 0x000600A9, 0x00000011, + 0x00005A10, 0x00002E81, 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C7D, 0x00001DEC, + 0x00005A10, 0x00050080, 0x00000011, 0x00005FB9, 0x00005C7D, 0x0000339D, 0x000500C4, 0x00000011, + 0x000022AD, 0x00005FB9, 0x00000778, 0x000500C2, 0x00000011, 0x0000351B, 0x00005FB9, 0x00000778, + 0x000500C5, 0x00000011, 0x00005C47, 0x000022AD, 0x0000351B, 0x000600A9, 0x00000011, 0x00003C6C, + 0x00002E81, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E98, 0x00005C47, 0x00003C6C, + 0x00050080, 0x00000011, 0x000056A5, 0x00001E98, 0x0000339D, 0x000500C5, 0x00000011, 0x00004669, + 0x000056A5, 0x00000373, 0x00050051, 0x0000000B, 0x000028D6, 0x00002375, 0x00000000, 0x00050051, + 0x0000000B, 0x00005CB3, 0x00002375, 0x00000001, 0x00050051, 0x0000000B, 0x00001DDA, 0x00004669, + 0x00000000, 0x00050051, 0x0000000B, 0x00001E74, 0x00004669, 0x00000001, 0x00070050, 0x00000017, + 0x00003E17, 0x000028D6, 0x00005CB3, 0x00001DDA, 0x00001E74, 0x0009004F, 0x00000017, 0x00001DCF, + 0x00003E17, 0x00003E17, 0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x00060041, 0x00000294, + 0x0000303F, 0x0000140E, 0x00000A0B, 0x000054B5, 0x0003003E, 0x0000303F, 0x00001E85, 0x00050080, + 0x0000000B, 0x00002CC1, 0x000054B5, 0x00000A0D, 0x00060041, 0x00000294, 0x00006230, 0x0000140E, + 0x00000A0B, 0x00002CC1, 0x0003003E, 0x00006230, 0x00001DCF, 0x000300F7, 0x00001AD7, 0x00000002, + 0x000400FA, 0x00004376, 0x000055E9, 0x00001C25, 0x000200F8, 0x000055E9, 0x000200F9, 0x00001AD7, + 0x000200F8, 0x00001C25, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001AD7, 0x000700F5, 0x0000000B, + 0x0000456F, 0x00000A6A, 0x000055E9, 0x00000A3A, 0x00001C25, 0x000500C2, 0x0000000B, 0x000041C0, + 0x0000456F, 0x00000A16, 0x00050080, 0x0000000B, 0x00002ADB, 0x00005665, 0x000041C0, 0x00060041, + 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, 0x00002ADB, 0x0004003D, 0x00000017, 0x000019B2, + 0x0000571A, 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, + 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, + 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, + 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, + 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, + 0x00000017, 0x00002AAC, 0x000019B2, 0x00001AD7, 0x00003FF9, 0x00002958, 0x000300F7, 0x00002DA3, + 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, 0x00002DA3, 0x000200F8, 0x00002B39, 0x000500C4, + 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, + 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002DA3, + 0x000200F8, 0x00002DA3, 0x000700F5, 0x00000017, 0x00004DED, 0x00002AAC, 0x00003A1A, 0x000029E9, + 0x00002B39, 0x0007004F, 0x00000011, 0x000052B6, 0x00004DED, 0x00004DED, 0x00000000, 0x00000001, + 0x000500C7, 0x00000011, 0x00002FAF, 0x000052B6, 0x000008A5, 0x000500C2, 0x00000011, 0x00001AF4, + 0x00002FAF, 0x000007CC, 0x000500AB, 0x0000000F, 0x000031A8, 0x00001AF4, 0x0000070F, 0x000500AA, + 0x0000000F, 0x00004EB2, 0x00002FAF, 0x00000203, 0x000600A9, 0x00000011, 0x00001DED, 0x00004EB2, + 0x00000218, 0x00002FAF, 0x000600A9, 0x00000011, 0x00005A11, 0x000031A8, 0x000008A5, 0x0000070F, + 0x000500C6, 0x00000011, 0x00005C7E, 0x00001DED, 0x00005A11, 0x00050080, 0x00000011, 0x00005FBA, + 0x00005C7E, 0x00001AF4, 0x000500C4, 0x00000011, 0x000022AE, 0x00005FBA, 0x0000078D, 0x000500C2, + 0x00000011, 0x0000351C, 0x00005FBA, 0x0000074E, 0x000500C5, 0x00000011, 0x00005C48, 0x000022AE, + 0x0000351C, 0x000600A9, 0x00000011, 0x00003C6D, 0x000031A8, 0x000007DF, 0x0000070F, 0x000500C6, + 0x00000011, 0x00001E60, 0x00005C48, 0x00003C6D, 0x00050080, 0x00000011, 0x0000616F, 0x00001E60, + 0x00001AF4, 0x000500C2, 0x00000011, 0x00005F12, 0x000052B6, 0x000007E1, 0x000500C7, 0x00000011, + 0x00002E30, 0x00005F12, 0x00000A50, 0x000500C2, 0x00000011, 0x000018B1, 0x00002E30, 0x000007E1, + 0x000500AB, 0x0000000F, 0x000031A9, 0x000018B1, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB3, + 0x00002E30, 0x000008BA, 0x000600A9, 0x00000011, 0x00001DEE, 0x00004EB3, 0x000008CF, 0x00002E30, + 0x000600A9, 0x00000011, 0x00005A12, 0x000031A9, 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, + 0x00005C7F, 0x00001DEE, 0x00005A12, 0x00050080, 0x00000011, 0x00005FBB, 0x00005C7F, 0x000018B1, + 0x000500C4, 0x00000011, 0x000022AF, 0x00005FBB, 0x00000778, 0x000500C2, 0x00000011, 0x0000351D, + 0x00005FBB, 0x00000778, 0x000500C5, 0x00000011, 0x00005C49, 0x000022AF, 0x0000351D, 0x000600A9, + 0x00000011, 0x00003C6E, 0x000031A9, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E87, + 0x00005C49, 0x00003C6E, 0x00050080, 0x00000011, 0x00005FF0, 0x00001E87, 0x000018B1, 0x000500C4, + 0x00000011, 0x0000206A, 0x00005FF0, 0x0000085F, 0x000500C5, 0x00000011, 0x00002376, 0x0000616F, + 0x0000206A, 0x000500C2, 0x00000011, 0x00005BF7, 0x000052B6, 0x000008C8, 0x000500C2, 0x00000011, + 0x0000339E, 0x00005BF7, 0x000007E1, 0x000500AB, 0x0000000F, 0x00002E82, 0x0000339E, 0x0000070F, + 0x000500AA, 0x0000000F, 0x00004EB4, 0x00005BF7, 0x000008BA, 0x000600A9, 0x00000011, 0x00001DEF, + 0x00004EB4, 0x000008CF, 0x00005BF7, 0x000600A9, 0x00000011, 0x00005A13, 0x00002E82, 0x00000A50, + 0x0000070F, 0x000500C6, 0x00000011, 0x00005C80, 0x00001DEF, 0x00005A13, 0x00050080, 0x00000011, + 0x00005FBC, 0x00005C80, 0x0000339E, 0x000500C4, 0x00000011, 0x000022B0, 0x00005FBC, 0x00000778, + 0x000500C2, 0x00000011, 0x0000351E, 0x00005FBC, 0x00000778, 0x000500C5, 0x00000011, 0x00005C4A, + 0x000022B0, 0x0000351E, 0x000600A9, 0x00000011, 0x00003C6F, 0x00002E82, 0x000007DF, 0x0000070F, + 0x000500C6, 0x00000011, 0x00001E99, 0x00005C4A, 0x00003C6F, 0x00050080, 0x00000011, 0x000056A6, + 0x00001E99, 0x0000339E, 0x000500C5, 0x00000011, 0x0000466A, 0x000056A6, 0x00000373, 0x00050051, + 0x0000000B, 0x000028D7, 0x00002376, 0x00000000, 0x00050051, 0x0000000B, 0x00005CB4, 0x00002376, + 0x00000001, 0x00050051, 0x0000000B, 0x00001DDB, 0x0000466A, 0x00000000, 0x00050051, 0x0000000B, + 0x00001E75, 0x0000466A, 0x00000001, 0x00070050, 0x00000017, 0x00003F22, 0x000028D7, 0x00005CB4, + 0x00001DDB, 0x00001E75, 0x0009004F, 0x00000017, 0x00001E88, 0x00003F22, 0x00003F22, 0x00000000, + 0x00000002, 0x00000001, 0x00000003, 0x0007004F, 0x00000011, 0x000021FC, 0x00004DED, 0x00004DED, + 0x00000002, 0x00000003, 0x000500C7, 0x00000011, 0x00001C00, 0x000021FC, 0x000008A5, 0x000500C2, + 0x00000011, 0x00001AF5, 0x00001C00, 0x000007CC, 0x000500AB, 0x0000000F, 0x000031AA, 0x00001AF5, + 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB5, 0x00001C00, 0x00000203, 0x000600A9, 0x00000011, + 0x00001DF0, 0x00004EB5, 0x00000218, 0x00001C00, 0x000600A9, 0x00000011, 0x00005A14, 0x000031AA, + 0x000008A5, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C81, 0x00001DF0, 0x00005A14, 0x00050080, + 0x00000011, 0x00005FBD, 0x00005C81, 0x00001AF5, 0x000500C4, 0x00000011, 0x000022B1, 0x00005FBD, + 0x0000078D, 0x000500C2, 0x00000011, 0x0000351F, 0x00005FBD, 0x0000074E, 0x000500C5, 0x00000011, + 0x00005C4B, 0x000022B1, 0x0000351F, 0x000600A9, 0x00000011, 0x00003C70, 0x000031AA, 0x000007DF, + 0x0000070F, 0x000500C6, 0x00000011, 0x00001E61, 0x00005C4B, 0x00003C70, 0x00050080, 0x00000011, + 0x00006170, 0x00001E61, 0x00001AF5, 0x000500C2, 0x00000011, 0x00005F13, 0x000021FC, 0x000007E1, + 0x000500C7, 0x00000011, 0x00002E31, 0x00005F13, 0x00000A50, 0x000500C2, 0x00000011, 0x000018B2, + 0x00002E31, 0x000007E1, 0x000500AB, 0x0000000F, 0x000031AB, 0x000018B2, 0x0000070F, 0x000500AA, + 0x0000000F, 0x00004EB6, 0x00002E31, 0x000008BA, 0x000600A9, 0x00000011, 0x00001DF1, 0x00004EB6, + 0x000008CF, 0x00002E31, 0x000600A9, 0x00000011, 0x00005A15, 0x000031AB, 0x00000A50, 0x0000070F, + 0x000500C6, 0x00000011, 0x00005C82, 0x00001DF1, 0x00005A15, 0x00050080, 0x00000011, 0x00005FBE, + 0x00005C82, 0x000018B2, 0x000500C4, 0x00000011, 0x000022B2, 0x00005FBE, 0x00000778, 0x000500C2, + 0x00000011, 0x00003520, 0x00005FBE, 0x00000778, 0x000500C5, 0x00000011, 0x00005C4C, 0x000022B2, + 0x00003520, 0x000600A9, 0x00000011, 0x00003C71, 0x000031AB, 0x000007DF, 0x0000070F, 0x000500C6, + 0x00000011, 0x00001E89, 0x00005C4C, 0x00003C71, 0x00050080, 0x00000011, 0x00005FF1, 0x00001E89, + 0x000018B2, 0x000500C4, 0x00000011, 0x0000206B, 0x00005FF1, 0x0000085F, 0x000500C5, 0x00000011, + 0x00002377, 0x00006170, 0x0000206B, 0x000500C2, 0x00000011, 0x00005BF8, 0x000021FC, 0x000008C8, + 0x000500C2, 0x00000011, 0x0000339F, 0x00005BF8, 0x000007E1, 0x000500AB, 0x0000000F, 0x00002E83, + 0x0000339F, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB7, 0x00005BF8, 0x000008BA, 0x000600A9, + 0x00000011, 0x00001DF2, 0x00004EB7, 0x000008CF, 0x00005BF8, 0x000600A9, 0x00000011, 0x00005A16, + 0x00002E83, 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C83, 0x00001DF2, 0x00005A16, + 0x00050080, 0x00000011, 0x00005FBF, 0x00005C83, 0x0000339F, 0x000500C4, 0x00000011, 0x000022B3, + 0x00005FBF, 0x00000778, 0x000500C2, 0x00000011, 0x00003521, 0x00005FBF, 0x00000778, 0x000500C5, + 0x00000011, 0x00005C4D, 0x000022B3, 0x00003521, 0x000600A9, 0x00000011, 0x00003C72, 0x00002E83, + 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E9A, 0x00005C4D, 0x00003C72, 0x00050080, + 0x00000011, 0x000056A7, 0x00001E9A, 0x0000339F, 0x000500C5, 0x00000011, 0x0000466B, 0x000056A7, + 0x00000373, 0x00050051, 0x0000000B, 0x000028D8, 0x00002377, 0x00000000, 0x00050051, 0x0000000B, + 0x00005CB5, 0x00002377, 0x00000001, 0x00050051, 0x0000000B, 0x00001DDC, 0x0000466B, 0x00000000, + 0x00050051, 0x0000000B, 0x00001E76, 0x0000466B, 0x00000001, 0x00070050, 0x00000017, 0x000042C4, + 0x000028D8, 0x00005CB5, 0x00001DDC, 0x00001E76, 0x0009004F, 0x00000017, 0x00003DF4, 0x000042C4, + 0x000042C4, 0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x00050080, 0x0000000B, 0x000055BE, + 0x000054B5, 0x00000A10, 0x00060041, 0x00000294, 0x00001E95, 0x0000140E, 0x00000A0B, 0x000055BE, + 0x0003003E, 0x00001E95, 0x00001E88, 0x00050080, 0x0000000B, 0x00002CC2, 0x000054B5, 0x00000A13, + 0x00060041, 0x00000294, 0x00006256, 0x0000140E, 0x00000A0B, 0x00002CC2, 0x0003003E, 0x00006256, + 0x00003DF4, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r10g11b11_rgba16_snorm_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r10g11b11_rgba16_snorm_scaled_cs.h new file mode 100644 index 0000000..c1bf66a --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r10g11b11_rgba16_snorm_scaled_cs.h @@ -0,0 +1,992 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25175 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_9 = OpConstant %uint 9 + %v2bool = OpTypeVector %bool 2 + %uint_0 = OpConstant %uint 0 + %uint_513 = OpConstant %uint 513 + %uint_512 = OpConstant %uint 512 + %uint_1023 = OpConstant %uint 1023 + %uint_6 = OpConstant %uint 6 + %uint_3 = OpConstant %uint 3 + %uint_65535 = OpConstant %uint 65535 + %uint_10 = OpConstant %uint 10 + %uint_1025 = OpConstant %uint 1025 + %uint_1024 = OpConstant %uint 1024 + %uint_2047 = OpConstant %uint 2047 + %uint_5 = OpConstant %uint 5 + %uint_16 = OpConstant %uint 16 + %uint_21 = OpConstant %uint 21 +%uint_2147418112 = OpConstant %uint 2147418112 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2603 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %2213 = OpConstantComposite %v2uint %uint_1023 %uint_1023 + %1996 = OpConstantComposite %v2uint %uint_9 %uint_9 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %536 = OpConstantComposite %v2uint %uint_513 %uint_513 + %515 = OpConstantComposite %v2uint %uint_512 %uint_512 + %1933 = OpConstantComposite %v2uint %uint_6 %uint_6 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %2015 = OpConstantComposite %v2uint %uint_65535 %uint_65535 + %2017 = OpConstantComposite %v2uint %uint_10 %uint_10 + %2640 = OpConstantComposite %v2uint %uint_2047 %uint_2047 + %2255 = OpConstantComposite %v2uint %uint_1025 %uint_1025 + %2234 = OpConstantComposite %v2uint %uint_1024 %uint_1024 + %1912 = OpConstantComposite %v2uint %uint_5 %uint_5 + %2143 = OpConstantComposite %v2uint %uint_16 %uint_16 + %2248 = OpConstantComposite %v2uint %uint_21 %uint_21 + %883 = OpConstantComposite %v2uint %uint_2147418112 %uint_2147418112 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2603 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_8 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_2 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_2 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_2 + %23219 = OpBitwiseAnd %uint %10722 %uint_3 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_2 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %7338 = OpLoad %v4uint %20399 + %13760 = OpIEqual %bool %24990 %uint_1 + %21366 = OpIEqual %bool %24990 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %21313 %16376 %10583 + %19638 = OpIEqual %bool %24990 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %11682 None + OpBranchConditional %15139 %11064 %11682 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11682 + %11682 = OpLabel + %19948 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %21173 = OpVectorShuffle %v2uint %19948 %19948 0 1 + %12206 = OpBitwiseAnd %v2uint %21173 %2213 + %6898 = OpShiftRightLogical %v2uint %12206 %1996 + %12708 = OpINotEqual %v2bool %6898 %1807 + %20140 = OpIEqual %v2bool %12206 %515 + %7655 = OpSelect %v2uint %20140 %536 %12206 + %23050 = OpSelect %v2uint %12708 %2213 %1807 + %23672 = OpBitwiseXor %v2uint %7655 %23050 + %24500 = OpIAdd %v2uint %23672 %6898 + %8872 = OpShiftLeftLogical %v2uint %24500 %1933 + %13590 = OpShiftRightLogical %v2uint %24500 %1870 + %23618 = OpBitwiseOr %v2uint %8872 %13590 + %15463 = OpSelect %v2uint %12708 %2015 %1807 + %7774 = OpBitwiseXor %v2uint %23618 %15463 + %24941 = OpIAdd %v2uint %7774 %6898 + %24336 = OpShiftRightLogical %v2uint %21173 %2017 + %11822 = OpBitwiseAnd %v2uint %24336 %2640 + %6319 = OpShiftRightLogical %v2uint %11822 %2017 + %12709 = OpINotEqual %v2bool %6319 %1807 + %20141 = OpIEqual %v2bool %11822 %2234 + %7656 = OpSelect %v2uint %20141 %2255 %11822 + %23051 = OpSelect %v2uint %12709 %2640 %1807 + %23673 = OpBitwiseXor %v2uint %7656 %23051 + %24501 = OpIAdd %v2uint %23673 %6319 + %8873 = OpShiftLeftLogical %v2uint %24501 %1912 + %13591 = OpShiftRightLogical %v2uint %24501 %1912 + %23619 = OpBitwiseOr %v2uint %8873 %13591 + %15464 = OpSelect %v2uint %12709 %2015 %1807 + %7812 = OpBitwiseXor %v2uint %23619 %15464 + %24557 = OpIAdd %v2uint %7812 %6319 + %8296 = OpShiftLeftLogical %v2uint %24557 %2143 + %9076 = OpBitwiseOr %v2uint %24941 %8296 + %23541 = OpShiftRightLogical %v2uint %21173 %2248 + %13212 = OpShiftRightLogical %v2uint %23541 %2017 + %11904 = OpINotEqual %v2bool %13212 %1807 + %20142 = OpIEqual %v2bool %23541 %2234 + %7657 = OpSelect %v2uint %20142 %2255 %23541 + %23053 = OpSelect %v2uint %11904 %2640 %1807 + %23674 = OpBitwiseXor %v2uint %7657 %23053 + %24502 = OpIAdd %v2uint %23674 %13212 + %8874 = OpShiftLeftLogical %v2uint %24502 %1912 + %13592 = OpShiftRightLogical %v2uint %24502 %1912 + %23620 = OpBitwiseOr %v2uint %8874 %13592 + %15465 = OpSelect %v2uint %11904 %2015 %1807 + %7831 = OpBitwiseXor %v2uint %23620 %15465 + %22180 = OpIAdd %v2uint %7831 %13212 + %18024 = OpBitwiseOr %v2uint %22180 %883 + %10453 = OpCompositeExtract %uint %9076 0 + %23730 = OpCompositeExtract %uint %9076 1 + %7641 = OpCompositeExtract %uint %18024 0 + %7795 = OpCompositeExtract %uint %18024 1 + %16161 = OpCompositeConstruct %v4uint %10453 %23730 %7641 %7795 + %7813 = OpVectorShuffle %v4uint %16161 %16161 0 2 1 3 + %8699 = OpVectorShuffle %v2uint %19948 %19948 2 3 + %7167 = OpBitwiseAnd %v2uint %8699 %2213 + %6899 = OpShiftRightLogical %v2uint %7167 %1996 + %12710 = OpINotEqual %v2bool %6899 %1807 + %20143 = OpIEqual %v2bool %7167 %515 + %7658 = OpSelect %v2uint %20143 %536 %7167 + %23054 = OpSelect %v2uint %12710 %2213 %1807 + %23675 = OpBitwiseXor %v2uint %7658 %23054 + %24503 = OpIAdd %v2uint %23675 %6899 + %8875 = OpShiftLeftLogical %v2uint %24503 %1933 + %13593 = OpShiftRightLogical %v2uint %24503 %1870 + %23621 = OpBitwiseOr %v2uint %8875 %13593 + %15466 = OpSelect %v2uint %12710 %2015 %1807 + %7775 = OpBitwiseXor %v2uint %23621 %15466 + %24942 = OpIAdd %v2uint %7775 %6899 + %24337 = OpShiftRightLogical %v2uint %8699 %2017 + %11823 = OpBitwiseAnd %v2uint %24337 %2640 + %6320 = OpShiftRightLogical %v2uint %11823 %2017 + %12711 = OpINotEqual %v2bool %6320 %1807 + %20144 = OpIEqual %v2bool %11823 %2234 + %7659 = OpSelect %v2uint %20144 %2255 %11823 + %23055 = OpSelect %v2uint %12711 %2640 %1807 + %23676 = OpBitwiseXor %v2uint %7659 %23055 + %24504 = OpIAdd %v2uint %23676 %6320 + %8876 = OpShiftLeftLogical %v2uint %24504 %1912 + %13594 = OpShiftRightLogical %v2uint %24504 %1912 + %23622 = OpBitwiseOr %v2uint %8876 %13594 + %15467 = OpSelect %v2uint %12711 %2015 %1807 + %7814 = OpBitwiseXor %v2uint %23622 %15467 + %24558 = OpIAdd %v2uint %7814 %6320 + %8297 = OpShiftLeftLogical %v2uint %24558 %2143 + %9077 = OpBitwiseOr %v2uint %24942 %8297 + %23542 = OpShiftRightLogical %v2uint %8699 %2248 + %13213 = OpShiftRightLogical %v2uint %23542 %2017 + %11905 = OpINotEqual %v2bool %13213 %1807 + %20145 = OpIEqual %v2bool %23542 %2234 + %7660 = OpSelect %v2uint %20145 %2255 %23542 + %23056 = OpSelect %v2uint %11905 %2640 %1807 + %23677 = OpBitwiseXor %v2uint %7660 %23056 + %24505 = OpIAdd %v2uint %23677 %13213 + %8877 = OpShiftLeftLogical %v2uint %24505 %1912 + %13595 = OpShiftRightLogical %v2uint %24505 %1912 + %23623 = OpBitwiseOr %v2uint %8877 %13595 + %15468 = OpSelect %v2uint %11905 %2015 %1807 + %7832 = OpBitwiseXor %v2uint %23623 %15468 + %22181 = OpIAdd %v2uint %7832 %13213 + %18025 = OpBitwiseOr %v2uint %22181 %883 + %10454 = OpCompositeExtract %uint %9077 0 + %23731 = OpCompositeExtract %uint %9077 1 + %7642 = OpCompositeExtract %uint %18025 0 + %7796 = OpCompositeExtract %uint %18025 1 + %15895 = OpCompositeConstruct %v4uint %10454 %23731 %7642 %7796 + %7631 = OpVectorShuffle %v4uint %15895 %15895 0 2 1 3 + %12351 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %12351 %7813 + %11457 = OpIAdd %uint %11197 %uint_1 + %23711 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11457 + OpStore %23711 %7631 + %23543 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %23543 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_32 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_32 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %24764 %16377 %10584 + OpSelectionMerge %11683 None + OpBranchConditional %15139 %11065 %11683 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11683 + %11683 = OpLabel + %19949 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %21174 = OpVectorShuffle %v2uint %19949 %19949 0 1 + %12207 = OpBitwiseAnd %v2uint %21174 %2213 + %6900 = OpShiftRightLogical %v2uint %12207 %1996 + %12712 = OpINotEqual %v2bool %6900 %1807 + %20146 = OpIEqual %v2bool %12207 %515 + %7661 = OpSelect %v2uint %20146 %536 %12207 + %23057 = OpSelect %v2uint %12712 %2213 %1807 + %23678 = OpBitwiseXor %v2uint %7661 %23057 + %24506 = OpIAdd %v2uint %23678 %6900 + %8878 = OpShiftLeftLogical %v2uint %24506 %1933 + %13596 = OpShiftRightLogical %v2uint %24506 %1870 + %23624 = OpBitwiseOr %v2uint %8878 %13596 + %15469 = OpSelect %v2uint %12712 %2015 %1807 + %7776 = OpBitwiseXor %v2uint %23624 %15469 + %24943 = OpIAdd %v2uint %7776 %6900 + %24338 = OpShiftRightLogical %v2uint %21174 %2017 + %11824 = OpBitwiseAnd %v2uint %24338 %2640 + %6321 = OpShiftRightLogical %v2uint %11824 %2017 + %12713 = OpINotEqual %v2bool %6321 %1807 + %20147 = OpIEqual %v2bool %11824 %2234 + %7663 = OpSelect %v2uint %20147 %2255 %11824 + %23058 = OpSelect %v2uint %12713 %2640 %1807 + %23679 = OpBitwiseXor %v2uint %7663 %23058 + %24507 = OpIAdd %v2uint %23679 %6321 + %8879 = OpShiftLeftLogical %v2uint %24507 %1912 + %13597 = OpShiftRightLogical %v2uint %24507 %1912 + %23625 = OpBitwiseOr %v2uint %8879 %13597 + %15470 = OpSelect %v2uint %12713 %2015 %1807 + %7815 = OpBitwiseXor %v2uint %23625 %15470 + %24559 = OpIAdd %v2uint %7815 %6321 + %8298 = OpShiftLeftLogical %v2uint %24559 %2143 + %9078 = OpBitwiseOr %v2uint %24943 %8298 + %23544 = OpShiftRightLogical %v2uint %21174 %2248 + %13214 = OpShiftRightLogical %v2uint %23544 %2017 + %11906 = OpINotEqual %v2bool %13214 %1807 + %20148 = OpIEqual %v2bool %23544 %2234 + %7664 = OpSelect %v2uint %20148 %2255 %23544 + %23059 = OpSelect %v2uint %11906 %2640 %1807 + %23680 = OpBitwiseXor %v2uint %7664 %23059 + %24508 = OpIAdd %v2uint %23680 %13214 + %8880 = OpShiftLeftLogical %v2uint %24508 %1912 + %13598 = OpShiftRightLogical %v2uint %24508 %1912 + %23626 = OpBitwiseOr %v2uint %8880 %13598 + %15471 = OpSelect %v2uint %11906 %2015 %1807 + %7833 = OpBitwiseXor %v2uint %23626 %15471 + %22182 = OpIAdd %v2uint %7833 %13214 + %18026 = OpBitwiseOr %v2uint %22182 %883 + %10455 = OpCompositeExtract %uint %9078 0 + %23732 = OpCompositeExtract %uint %9078 1 + %7643 = OpCompositeExtract %uint %18026 0 + %7797 = OpCompositeExtract %uint %18026 1 + %16162 = OpCompositeConstruct %v4uint %10455 %23732 %7643 %7797 + %7816 = OpVectorShuffle %v4uint %16162 %16162 0 2 1 3 + %8700 = OpVectorShuffle %v2uint %19949 %19949 2 3 + %7168 = OpBitwiseAnd %v2uint %8700 %2213 + %6901 = OpShiftRightLogical %v2uint %7168 %1996 + %12714 = OpINotEqual %v2bool %6901 %1807 + %20149 = OpIEqual %v2bool %7168 %515 + %7665 = OpSelect %v2uint %20149 %536 %7168 + %23060 = OpSelect %v2uint %12714 %2213 %1807 + %23681 = OpBitwiseXor %v2uint %7665 %23060 + %24509 = OpIAdd %v2uint %23681 %6901 + %8881 = OpShiftLeftLogical %v2uint %24509 %1933 + %13599 = OpShiftRightLogical %v2uint %24509 %1870 + %23627 = OpBitwiseOr %v2uint %8881 %13599 + %15472 = OpSelect %v2uint %12714 %2015 %1807 + %7777 = OpBitwiseXor %v2uint %23627 %15472 + %24944 = OpIAdd %v2uint %7777 %6901 + %24339 = OpShiftRightLogical %v2uint %8700 %2017 + %11825 = OpBitwiseAnd %v2uint %24339 %2640 + %6322 = OpShiftRightLogical %v2uint %11825 %2017 + %12715 = OpINotEqual %v2bool %6322 %1807 + %20150 = OpIEqual %v2bool %11825 %2234 + %7666 = OpSelect %v2uint %20150 %2255 %11825 + %23061 = OpSelect %v2uint %12715 %2640 %1807 + %23682 = OpBitwiseXor %v2uint %7666 %23061 + %24510 = OpIAdd %v2uint %23682 %6322 + %8882 = OpShiftLeftLogical %v2uint %24510 %1912 + %13600 = OpShiftRightLogical %v2uint %24510 %1912 + %23628 = OpBitwiseOr %v2uint %8882 %13600 + %15473 = OpSelect %v2uint %12715 %2015 %1807 + %7817 = OpBitwiseXor %v2uint %23628 %15473 + %24560 = OpIAdd %v2uint %7817 %6322 + %8299 = OpShiftLeftLogical %v2uint %24560 %2143 + %9079 = OpBitwiseOr %v2uint %24944 %8299 + %23545 = OpShiftRightLogical %v2uint %8700 %2248 + %13215 = OpShiftRightLogical %v2uint %23545 %2017 + %11907 = OpINotEqual %v2bool %13215 %1807 + %20151 = OpIEqual %v2bool %23545 %2234 + %7667 = OpSelect %v2uint %20151 %2255 %23545 + %23062 = OpSelect %v2uint %11907 %2640 %1807 + %23683 = OpBitwiseXor %v2uint %7667 %23062 + %24511 = OpIAdd %v2uint %23683 %13215 + %8883 = OpShiftLeftLogical %v2uint %24511 %1912 + %13601 = OpShiftRightLogical %v2uint %24511 %1912 + %23629 = OpBitwiseOr %v2uint %8883 %13601 + %15474 = OpSelect %v2uint %11907 %2015 %1807 + %7834 = OpBitwiseXor %v2uint %23629 %15474 + %22183 = OpIAdd %v2uint %7834 %13215 + %18027 = OpBitwiseOr %v2uint %22183 %883 + %10456 = OpCompositeExtract %uint %9079 0 + %23733 = OpCompositeExtract %uint %9079 1 + %7644 = OpCompositeExtract %uint %18027 0 + %7798 = OpCompositeExtract %uint %18027 1 + %17092 = OpCompositeConstruct %v4uint %10456 %23733 %7644 %7798 + %15860 = OpVectorShuffle %v4uint %17092 %17092 0 2 1 3 + %21950 = OpIAdd %uint %11197 %uint_2 + %7829 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21950 + OpStore %7829 %7816 + %11458 = OpIAdd %uint %11197 %uint_3 + %25174 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11458 + OpStore %25174 %15860 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r10g11b11_rgba16_snorm_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006257, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x0000044A, 0x00000201, + 0x0004002B, 0x0000000B, 0x00000447, 0x00000200, 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, + 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x000001C1, 0x0000FFFF, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, + 0x0004002B, 0x0000000B, 0x00000A4A, 0x00000401, 0x0004002B, 0x0000000B, 0x00000A47, 0x00000400, + 0x0004002B, 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A49, 0x00000015, + 0x0004002B, 0x0000000B, 0x000003D6, 0x7FFF0000, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, + 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, + 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, 0x00000787, 0x00000A16, 0x00000A1F, 0x00040020, + 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, + 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A2B, 0x00000A13, 0x00000A0A, + 0x00000A0A, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, + 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, + 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, + 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, + 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, + 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, + 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, + 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, + 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, + 0x0005002C, 0x00000011, 0x000008A5, 0x00000A44, 0x00000A44, 0x0005002C, 0x00000011, 0x000007CC, + 0x00000A25, 0x00000A25, 0x0005002C, 0x00000011, 0x0000070F, 0x00000A0A, 0x00000A0A, 0x0005002C, + 0x00000011, 0x00000218, 0x0000044A, 0x0000044A, 0x0005002C, 0x00000011, 0x00000203, 0x00000447, + 0x00000447, 0x0005002C, 0x00000011, 0x0000078D, 0x00000A1C, 0x00000A1C, 0x0005002C, 0x00000011, + 0x0000074E, 0x00000A13, 0x00000A13, 0x0005002C, 0x00000011, 0x000007DF, 0x000001C1, 0x000001C1, + 0x0005002C, 0x00000011, 0x000007E1, 0x00000A28, 0x00000A28, 0x0005002C, 0x00000011, 0x00000A50, + 0x00000A81, 0x00000A81, 0x0005002C, 0x00000011, 0x000008CF, 0x00000A4A, 0x00000A4A, 0x0005002C, + 0x00000011, 0x000008BA, 0x00000A47, 0x00000A47, 0x0005002C, 0x00000011, 0x00000778, 0x00000A19, + 0x00000A19, 0x0005002C, 0x00000011, 0x0000085F, 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000011, + 0x000008C8, 0x00000A49, 0x00000A49, 0x0005002C, 0x00000011, 0x00000373, 0x000003D6, 0x000003D6, + 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, + 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, + 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, + 0x000500C7, 0x0000000B, 0x00005F7D, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x000048EB, + 0x00005F7D, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001FCD, 0x00003526, 0x00000A10, 0x000500C7, + 0x0000000B, 0x0000619E, 0x00001FCD, 0x00000A13, 0x00050050, 0x00000011, 0x000022A7, 0x00003526, + 0x00003526, 0x000500C2, 0x00000011, 0x00001BAF, 0x000022A7, 0x00000787, 0x000500C7, 0x00000011, + 0x00001997, 0x00001BAF, 0x000007A2, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, + 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, + 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, + 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, + 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, + 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, + 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, + 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, + 0x00002A0E, 0x00000A2B, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, + 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, + 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, + 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, + 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, + 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, + 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, + 0x00000A23, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, + 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, + 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, + 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, + 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, + 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00001B12, 0x00002A92, 0x0000578B, + 0x000500C2, 0x0000000B, 0x00002BBD, 0x00001B12, 0x00000A16, 0x00050051, 0x0000000B, 0x000029E2, + 0x0000538B, 0x00000000, 0x000500C2, 0x0000000B, 0x00001DEE, 0x000029E2, 0x00000A10, 0x00050051, + 0x0000000B, 0x00002704, 0x0000538B, 0x00000001, 0x00050050, 0x00000011, 0x00005C0B, 0x00001DEE, + 0x00002704, 0x00050086, 0x00000011, 0x00001F69, 0x00005C0B, 0x00001997, 0x00050051, 0x0000000B, + 0x0000366C, 0x00001F69, 0x00000000, 0x000500C4, 0x0000000B, 0x00004D4D, 0x0000366C, 0x00000A10, + 0x00050051, 0x0000000B, 0x000051A9, 0x00001F69, 0x00000001, 0x00050051, 0x0000000B, 0x000059EE, + 0x0000538B, 0x00000002, 0x00060050, 0x00000014, 0x000024C9, 0x00004D4D, 0x000051A9, 0x000059EE, + 0x000300F7, 0x00005341, 0x00000002, 0x000400FA, 0x000048EB, 0x0000537D, 0x00002DD9, 0x000200F8, + 0x0000537D, 0x0004007C, 0x00000016, 0x00002970, 0x000024C9, 0x00050051, 0x0000000C, 0x000042C2, + 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A17, 0x00050051, + 0x0000000C, 0x00002747, 0x00002970, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, + 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, + 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005321, 0x0000405C, 0x000018AA, 0x00050080, + 0x0000000C, 0x00003B27, 0x000024FD, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, + 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, + 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, 0x00002970, 0x00000000, 0x000500C3, + 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, + 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A22, 0x000500C7, 0x0000000C, + 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, + 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, + 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, + 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, + 0x00002215, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405C, + 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, + 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, + 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, + 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, + 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, + 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, + 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, 0x00050080, 0x0000000C, + 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000042C2, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, + 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, + 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, + 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, + 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, + 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, + 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005559, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, + 0x0004007C, 0x0000000B, 0x0000566F, 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, 0x00002DD9, + 0x0007004F, 0x00000011, 0x00002621, 0x000024C9, 0x000024C9, 0x00000000, 0x00000001, 0x0004007C, + 0x00000012, 0x000059CF, 0x00002621, 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, 0x00000000, + 0x000500C3, 0x0000000C, 0x000024FE, 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002748, + 0x000059CF, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, 0x000500C2, + 0x0000000B, 0x00005B4E, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, + 0x00050084, 0x0000000C, 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, + 0x000024FE, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A25, 0x000500C7, + 0x0000000C, 0x00002AB6, 0x00001903, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002748, + 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, + 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A10, + 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, + 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, + 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, + 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, + 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, + 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, 0x000500C4, + 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, + 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, + 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, + 0x000500C7, 0x0000000C, 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, + 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x00001903, 0x00000A14, 0x00050080, + 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, + 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x00002E06, 0x00004159, 0x00000AC8, + 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4D, 0x00002E06, 0x0004007C, 0x0000000B, 0x00005670, + 0x0000394F, 0x000200F9, 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, 0x000024FC, + 0x0000566F, 0x0000537D, 0x00005670, 0x00002DD9, 0x00050084, 0x00000011, 0x00003FA8, 0x00001F69, + 0x00001997, 0x00050082, 0x00000011, 0x00003BBC, 0x00005C0B, 0x00003FA8, 0x00050051, 0x0000000B, + 0x00001C87, 0x00001997, 0x00000000, 0x00050051, 0x0000000B, 0x00005962, 0x00001997, 0x00000001, + 0x00050084, 0x0000000B, 0x00003372, 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, 0x00003CA0, + 0x000024FC, 0x00003372, 0x00050051, 0x0000000B, 0x00003ED4, 0x00003BBC, 0x00000000, 0x00050084, + 0x0000000B, 0x00003E12, 0x00003ED4, 0x00005962, 0x00050051, 0x0000000B, 0x00001AE6, 0x00003BBC, + 0x00000001, 0x00050080, 0x0000000B, 0x00002B25, 0x00003E12, 0x00001AE6, 0x000500C4, 0x0000000B, + 0x0000609D, 0x00002B25, 0x00000A10, 0x000500C7, 0x0000000B, 0x00005AB3, 0x000029E2, 0x00000A13, + 0x00050080, 0x0000000B, 0x00002557, 0x0000609D, 0x00005AB3, 0x000500C4, 0x0000000B, 0x000040AD, + 0x00002557, 0x00000A10, 0x00050080, 0x0000000B, 0x00004EAA, 0x00003CA0, 0x000040AD, 0x00050080, + 0x0000000B, 0x00003BA9, 0x00005EAC, 0x00004EAA, 0x000500C2, 0x0000000B, 0x00003948, 0x00003BA9, + 0x00000A16, 0x00060041, 0x00000294, 0x00004FAF, 0x0000107A, 0x00000A0B, 0x00003948, 0x0004003D, + 0x00000017, 0x00001CAA, 0x00004FAF, 0x000500AA, 0x00000009, 0x000035C0, 0x0000619E, 0x00000A0D, + 0x000500AA, 0x00000009, 0x00005376, 0x0000619E, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, + 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, + 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, + 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, + 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, + 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, + 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, 0x00005341, 0x00003FF8, 0x00002957, 0x000500AA, + 0x00000009, 0x00004CB6, 0x0000619E, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, + 0x00004CB6, 0x000300F7, 0x00002DA2, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x00002DA2, + 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, + 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, + 0x00003BE7, 0x000200F9, 0x00002DA2, 0x000200F8, 0x00002DA2, 0x000700F5, 0x00000017, 0x00004DEC, + 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x0007004F, 0x00000011, 0x000052B5, 0x00004DEC, + 0x00004DEC, 0x00000000, 0x00000001, 0x000500C7, 0x00000011, 0x00002FAE, 0x000052B5, 0x000008A5, + 0x000500C2, 0x00000011, 0x00001AF2, 0x00002FAE, 0x000007CC, 0x000500AB, 0x0000000F, 0x000031A4, + 0x00001AF2, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EAC, 0x00002FAE, 0x00000203, 0x000600A9, + 0x00000011, 0x00001DE7, 0x00004EAC, 0x00000218, 0x00002FAE, 0x000600A9, 0x00000011, 0x00005A0A, + 0x000031A4, 0x000008A5, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C78, 0x00001DE7, 0x00005A0A, + 0x00050080, 0x00000011, 0x00005FB4, 0x00005C78, 0x00001AF2, 0x000500C4, 0x00000011, 0x000022A8, + 0x00005FB4, 0x0000078D, 0x000500C2, 0x00000011, 0x00003516, 0x00005FB4, 0x0000074E, 0x000500C5, + 0x00000011, 0x00005C42, 0x000022A8, 0x00003516, 0x000600A9, 0x00000011, 0x00003C67, 0x000031A4, + 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E5E, 0x00005C42, 0x00003C67, 0x00050080, + 0x00000011, 0x0000616D, 0x00001E5E, 0x00001AF2, 0x000500C2, 0x00000011, 0x00005F10, 0x000052B5, + 0x000007E1, 0x000500C7, 0x00000011, 0x00002E2E, 0x00005F10, 0x00000A50, 0x000500C2, 0x00000011, + 0x000018AF, 0x00002E2E, 0x000007E1, 0x000500AB, 0x0000000F, 0x000031A5, 0x000018AF, 0x0000070F, + 0x000500AA, 0x0000000F, 0x00004EAD, 0x00002E2E, 0x000008BA, 0x000600A9, 0x00000011, 0x00001DE8, + 0x00004EAD, 0x000008CF, 0x00002E2E, 0x000600A9, 0x00000011, 0x00005A0B, 0x000031A5, 0x00000A50, + 0x0000070F, 0x000500C6, 0x00000011, 0x00005C79, 0x00001DE8, 0x00005A0B, 0x00050080, 0x00000011, + 0x00005FB5, 0x00005C79, 0x000018AF, 0x000500C4, 0x00000011, 0x000022A9, 0x00005FB5, 0x00000778, + 0x000500C2, 0x00000011, 0x00003517, 0x00005FB5, 0x00000778, 0x000500C5, 0x00000011, 0x00005C43, + 0x000022A9, 0x00003517, 0x000600A9, 0x00000011, 0x00003C68, 0x000031A5, 0x000007DF, 0x0000070F, + 0x000500C6, 0x00000011, 0x00001E84, 0x00005C43, 0x00003C68, 0x00050080, 0x00000011, 0x00005FED, + 0x00001E84, 0x000018AF, 0x000500C4, 0x00000011, 0x00002068, 0x00005FED, 0x0000085F, 0x000500C5, + 0x00000011, 0x00002374, 0x0000616D, 0x00002068, 0x000500C2, 0x00000011, 0x00005BF5, 0x000052B5, + 0x000008C8, 0x000500C2, 0x00000011, 0x0000339C, 0x00005BF5, 0x000007E1, 0x000500AB, 0x0000000F, + 0x00002E80, 0x0000339C, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EAE, 0x00005BF5, 0x000008BA, + 0x000600A9, 0x00000011, 0x00001DE9, 0x00004EAE, 0x000008CF, 0x00005BF5, 0x000600A9, 0x00000011, + 0x00005A0D, 0x00002E80, 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C7A, 0x00001DE9, + 0x00005A0D, 0x00050080, 0x00000011, 0x00005FB6, 0x00005C7A, 0x0000339C, 0x000500C4, 0x00000011, + 0x000022AA, 0x00005FB6, 0x00000778, 0x000500C2, 0x00000011, 0x00003518, 0x00005FB6, 0x00000778, + 0x000500C5, 0x00000011, 0x00005C44, 0x000022AA, 0x00003518, 0x000600A9, 0x00000011, 0x00003C69, + 0x00002E80, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E97, 0x00005C44, 0x00003C69, + 0x00050080, 0x00000011, 0x000056A4, 0x00001E97, 0x0000339C, 0x000500C5, 0x00000011, 0x00004668, + 0x000056A4, 0x00000373, 0x00050051, 0x0000000B, 0x000028D5, 0x00002374, 0x00000000, 0x00050051, + 0x0000000B, 0x00005CB2, 0x00002374, 0x00000001, 0x00050051, 0x0000000B, 0x00001DD9, 0x00004668, + 0x00000000, 0x00050051, 0x0000000B, 0x00001E73, 0x00004668, 0x00000001, 0x00070050, 0x00000017, + 0x00003F21, 0x000028D5, 0x00005CB2, 0x00001DD9, 0x00001E73, 0x0009004F, 0x00000017, 0x00001E85, + 0x00003F21, 0x00003F21, 0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x0007004F, 0x00000011, + 0x000021FB, 0x00004DEC, 0x00004DEC, 0x00000002, 0x00000003, 0x000500C7, 0x00000011, 0x00001BFF, + 0x000021FB, 0x000008A5, 0x000500C2, 0x00000011, 0x00001AF3, 0x00001BFF, 0x000007CC, 0x000500AB, + 0x0000000F, 0x000031A6, 0x00001AF3, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EAF, 0x00001BFF, + 0x00000203, 0x000600A9, 0x00000011, 0x00001DEA, 0x00004EAF, 0x00000218, 0x00001BFF, 0x000600A9, + 0x00000011, 0x00005A0E, 0x000031A6, 0x000008A5, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C7B, + 0x00001DEA, 0x00005A0E, 0x00050080, 0x00000011, 0x00005FB7, 0x00005C7B, 0x00001AF3, 0x000500C4, + 0x00000011, 0x000022AB, 0x00005FB7, 0x0000078D, 0x000500C2, 0x00000011, 0x00003519, 0x00005FB7, + 0x0000074E, 0x000500C5, 0x00000011, 0x00005C45, 0x000022AB, 0x00003519, 0x000600A9, 0x00000011, + 0x00003C6A, 0x000031A6, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E5F, 0x00005C45, + 0x00003C6A, 0x00050080, 0x00000011, 0x0000616E, 0x00001E5F, 0x00001AF3, 0x000500C2, 0x00000011, + 0x00005F11, 0x000021FB, 0x000007E1, 0x000500C7, 0x00000011, 0x00002E2F, 0x00005F11, 0x00000A50, + 0x000500C2, 0x00000011, 0x000018B0, 0x00002E2F, 0x000007E1, 0x000500AB, 0x0000000F, 0x000031A7, + 0x000018B0, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB0, 0x00002E2F, 0x000008BA, 0x000600A9, + 0x00000011, 0x00001DEB, 0x00004EB0, 0x000008CF, 0x00002E2F, 0x000600A9, 0x00000011, 0x00005A0F, + 0x000031A7, 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C7C, 0x00001DEB, 0x00005A0F, + 0x00050080, 0x00000011, 0x00005FB8, 0x00005C7C, 0x000018B0, 0x000500C4, 0x00000011, 0x000022AC, + 0x00005FB8, 0x00000778, 0x000500C2, 0x00000011, 0x0000351A, 0x00005FB8, 0x00000778, 0x000500C5, + 0x00000011, 0x00005C46, 0x000022AC, 0x0000351A, 0x000600A9, 0x00000011, 0x00003C6B, 0x000031A7, + 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E86, 0x00005C46, 0x00003C6B, 0x00050080, + 0x00000011, 0x00005FEE, 0x00001E86, 0x000018B0, 0x000500C4, 0x00000011, 0x00002069, 0x00005FEE, + 0x0000085F, 0x000500C5, 0x00000011, 0x00002375, 0x0000616E, 0x00002069, 0x000500C2, 0x00000011, + 0x00005BF6, 0x000021FB, 0x000008C8, 0x000500C2, 0x00000011, 0x0000339D, 0x00005BF6, 0x000007E1, + 0x000500AB, 0x0000000F, 0x00002E81, 0x0000339D, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB1, + 0x00005BF6, 0x000008BA, 0x000600A9, 0x00000011, 0x00001DEC, 0x00004EB1, 0x000008CF, 0x00005BF6, + 0x000600A9, 0x00000011, 0x00005A10, 0x00002E81, 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, + 0x00005C7D, 0x00001DEC, 0x00005A10, 0x00050080, 0x00000011, 0x00005FB9, 0x00005C7D, 0x0000339D, + 0x000500C4, 0x00000011, 0x000022AD, 0x00005FB9, 0x00000778, 0x000500C2, 0x00000011, 0x0000351B, + 0x00005FB9, 0x00000778, 0x000500C5, 0x00000011, 0x00005C47, 0x000022AD, 0x0000351B, 0x000600A9, + 0x00000011, 0x00003C6C, 0x00002E81, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E98, + 0x00005C47, 0x00003C6C, 0x00050080, 0x00000011, 0x000056A5, 0x00001E98, 0x0000339D, 0x000500C5, + 0x00000011, 0x00004669, 0x000056A5, 0x00000373, 0x00050051, 0x0000000B, 0x000028D6, 0x00002375, + 0x00000000, 0x00050051, 0x0000000B, 0x00005CB3, 0x00002375, 0x00000001, 0x00050051, 0x0000000B, + 0x00001DDA, 0x00004669, 0x00000000, 0x00050051, 0x0000000B, 0x00001E74, 0x00004669, 0x00000001, + 0x00070050, 0x00000017, 0x00003E17, 0x000028D6, 0x00005CB3, 0x00001DDA, 0x00001E74, 0x0009004F, + 0x00000017, 0x00001DCF, 0x00003E17, 0x00003E17, 0x00000000, 0x00000002, 0x00000001, 0x00000003, + 0x00060041, 0x00000294, 0x0000303F, 0x0000140E, 0x00000A0B, 0x00002BBD, 0x0003003E, 0x0000303F, + 0x00001E85, 0x00050080, 0x0000000B, 0x00002CC1, 0x00002BBD, 0x00000A0D, 0x00060041, 0x00000294, + 0x00005C9F, 0x0000140E, 0x00000A0B, 0x00002CC1, 0x0003003E, 0x00005C9F, 0x00001DCF, 0x000500AC, + 0x00000009, 0x00005BF7, 0x00001C87, 0x00000A0D, 0x000300F7, 0x000060BC, 0x00000002, 0x000400FA, + 0x00005BF7, 0x00005084, 0x00005094, 0x000200F8, 0x00005084, 0x00050086, 0x0000000B, 0x00003697, + 0x00001DEE, 0x00001C87, 0x00050084, 0x0000000B, 0x0000237E, 0x00003697, 0x00001C87, 0x00050082, + 0x0000000B, 0x00003171, 0x00001DEE, 0x0000237E, 0x00050080, 0x0000000B, 0x00002527, 0x00003171, + 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, 0x00001C87, 0x000300F7, 0x00001EED, + 0x00000000, 0x000400FA, 0x0000343F, 0x0000569E, 0x00002191, 0x000200F8, 0x0000569E, 0x00050084, + 0x0000000B, 0x00004B59, 0x00000A6A, 0x00001C87, 0x000500C4, 0x0000000B, 0x0000540F, 0x00003171, + 0x00000A16, 0x00050082, 0x0000000B, 0x00004944, 0x00004B59, 0x0000540F, 0x000200F9, 0x00001EED, + 0x000200F8, 0x00002191, 0x000200F9, 0x00001EED, 0x000200F8, 0x00001EED, 0x000700F5, 0x0000000B, + 0x0000292C, 0x00004944, 0x0000569E, 0x00000A3A, 0x00002191, 0x000200F9, 0x000060BC, 0x000200F8, + 0x00005094, 0x000200F9, 0x000060BC, 0x000200F8, 0x000060BC, 0x000700F5, 0x0000000B, 0x000029BC, + 0x0000292C, 0x00001EED, 0x00000A6A, 0x00005094, 0x00050084, 0x0000000B, 0x0000492B, 0x000029BC, + 0x00005962, 0x000500C2, 0x0000000B, 0x0000406D, 0x0000492B, 0x00000A16, 0x00050080, 0x0000000B, + 0x0000336B, 0x00003948, 0x0000406D, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, + 0x0000336B, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x00003A1A, 0x00000000, + 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, + 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, + 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, + 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x000060BC, + 0x00003FF9, 0x00002958, 0x000300F7, 0x00002DA3, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, + 0x00002DA3, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, + 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, + 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002DA3, 0x000200F8, 0x00002DA3, 0x000700F5, 0x00000017, + 0x00004DED, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x0007004F, 0x00000011, 0x000052B6, + 0x00004DED, 0x00004DED, 0x00000000, 0x00000001, 0x000500C7, 0x00000011, 0x00002FAF, 0x000052B6, + 0x000008A5, 0x000500C2, 0x00000011, 0x00001AF4, 0x00002FAF, 0x000007CC, 0x000500AB, 0x0000000F, + 0x000031A8, 0x00001AF4, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB2, 0x00002FAF, 0x00000203, + 0x000600A9, 0x00000011, 0x00001DED, 0x00004EB2, 0x00000218, 0x00002FAF, 0x000600A9, 0x00000011, + 0x00005A11, 0x000031A8, 0x000008A5, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C7E, 0x00001DED, + 0x00005A11, 0x00050080, 0x00000011, 0x00005FBA, 0x00005C7E, 0x00001AF4, 0x000500C4, 0x00000011, + 0x000022AE, 0x00005FBA, 0x0000078D, 0x000500C2, 0x00000011, 0x0000351C, 0x00005FBA, 0x0000074E, + 0x000500C5, 0x00000011, 0x00005C48, 0x000022AE, 0x0000351C, 0x000600A9, 0x00000011, 0x00003C6D, + 0x000031A8, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E60, 0x00005C48, 0x00003C6D, + 0x00050080, 0x00000011, 0x0000616F, 0x00001E60, 0x00001AF4, 0x000500C2, 0x00000011, 0x00005F12, + 0x000052B6, 0x000007E1, 0x000500C7, 0x00000011, 0x00002E30, 0x00005F12, 0x00000A50, 0x000500C2, + 0x00000011, 0x000018B1, 0x00002E30, 0x000007E1, 0x000500AB, 0x0000000F, 0x000031A9, 0x000018B1, + 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB3, 0x00002E30, 0x000008BA, 0x000600A9, 0x00000011, + 0x00001DEF, 0x00004EB3, 0x000008CF, 0x00002E30, 0x000600A9, 0x00000011, 0x00005A12, 0x000031A9, + 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C7F, 0x00001DEF, 0x00005A12, 0x00050080, + 0x00000011, 0x00005FBB, 0x00005C7F, 0x000018B1, 0x000500C4, 0x00000011, 0x000022AF, 0x00005FBB, + 0x00000778, 0x000500C2, 0x00000011, 0x0000351D, 0x00005FBB, 0x00000778, 0x000500C5, 0x00000011, + 0x00005C49, 0x000022AF, 0x0000351D, 0x000600A9, 0x00000011, 0x00003C6E, 0x000031A9, 0x000007DF, + 0x0000070F, 0x000500C6, 0x00000011, 0x00001E87, 0x00005C49, 0x00003C6E, 0x00050080, 0x00000011, + 0x00005FEF, 0x00001E87, 0x000018B1, 0x000500C4, 0x00000011, 0x0000206A, 0x00005FEF, 0x0000085F, + 0x000500C5, 0x00000011, 0x00002376, 0x0000616F, 0x0000206A, 0x000500C2, 0x00000011, 0x00005BF8, + 0x000052B6, 0x000008C8, 0x000500C2, 0x00000011, 0x0000339E, 0x00005BF8, 0x000007E1, 0x000500AB, + 0x0000000F, 0x00002E82, 0x0000339E, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB4, 0x00005BF8, + 0x000008BA, 0x000600A9, 0x00000011, 0x00001DF0, 0x00004EB4, 0x000008CF, 0x00005BF8, 0x000600A9, + 0x00000011, 0x00005A13, 0x00002E82, 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C80, + 0x00001DF0, 0x00005A13, 0x00050080, 0x00000011, 0x00005FBC, 0x00005C80, 0x0000339E, 0x000500C4, + 0x00000011, 0x000022B0, 0x00005FBC, 0x00000778, 0x000500C2, 0x00000011, 0x0000351E, 0x00005FBC, + 0x00000778, 0x000500C5, 0x00000011, 0x00005C4A, 0x000022B0, 0x0000351E, 0x000600A9, 0x00000011, + 0x00003C6F, 0x00002E82, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E99, 0x00005C4A, + 0x00003C6F, 0x00050080, 0x00000011, 0x000056A6, 0x00001E99, 0x0000339E, 0x000500C5, 0x00000011, + 0x0000466A, 0x000056A6, 0x00000373, 0x00050051, 0x0000000B, 0x000028D7, 0x00002376, 0x00000000, + 0x00050051, 0x0000000B, 0x00005CB4, 0x00002376, 0x00000001, 0x00050051, 0x0000000B, 0x00001DDB, + 0x0000466A, 0x00000000, 0x00050051, 0x0000000B, 0x00001E75, 0x0000466A, 0x00000001, 0x00070050, + 0x00000017, 0x00003F22, 0x000028D7, 0x00005CB4, 0x00001DDB, 0x00001E75, 0x0009004F, 0x00000017, + 0x00001E88, 0x00003F22, 0x00003F22, 0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x0007004F, + 0x00000011, 0x000021FC, 0x00004DED, 0x00004DED, 0x00000002, 0x00000003, 0x000500C7, 0x00000011, + 0x00001C00, 0x000021FC, 0x000008A5, 0x000500C2, 0x00000011, 0x00001AF5, 0x00001C00, 0x000007CC, + 0x000500AB, 0x0000000F, 0x000031AA, 0x00001AF5, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB5, + 0x00001C00, 0x00000203, 0x000600A9, 0x00000011, 0x00001DF1, 0x00004EB5, 0x00000218, 0x00001C00, + 0x000600A9, 0x00000011, 0x00005A14, 0x000031AA, 0x000008A5, 0x0000070F, 0x000500C6, 0x00000011, + 0x00005C81, 0x00001DF1, 0x00005A14, 0x00050080, 0x00000011, 0x00005FBD, 0x00005C81, 0x00001AF5, + 0x000500C4, 0x00000011, 0x000022B1, 0x00005FBD, 0x0000078D, 0x000500C2, 0x00000011, 0x0000351F, + 0x00005FBD, 0x0000074E, 0x000500C5, 0x00000011, 0x00005C4B, 0x000022B1, 0x0000351F, 0x000600A9, + 0x00000011, 0x00003C70, 0x000031AA, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E61, + 0x00005C4B, 0x00003C70, 0x00050080, 0x00000011, 0x00006170, 0x00001E61, 0x00001AF5, 0x000500C2, + 0x00000011, 0x00005F13, 0x000021FC, 0x000007E1, 0x000500C7, 0x00000011, 0x00002E31, 0x00005F13, + 0x00000A50, 0x000500C2, 0x00000011, 0x000018B2, 0x00002E31, 0x000007E1, 0x000500AB, 0x0000000F, + 0x000031AB, 0x000018B2, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB6, 0x00002E31, 0x000008BA, + 0x000600A9, 0x00000011, 0x00001DF2, 0x00004EB6, 0x000008CF, 0x00002E31, 0x000600A9, 0x00000011, + 0x00005A15, 0x000031AB, 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C82, 0x00001DF2, + 0x00005A15, 0x00050080, 0x00000011, 0x00005FBE, 0x00005C82, 0x000018B2, 0x000500C4, 0x00000011, + 0x000022B2, 0x00005FBE, 0x00000778, 0x000500C2, 0x00000011, 0x00003520, 0x00005FBE, 0x00000778, + 0x000500C5, 0x00000011, 0x00005C4C, 0x000022B2, 0x00003520, 0x000600A9, 0x00000011, 0x00003C71, + 0x000031AB, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E89, 0x00005C4C, 0x00003C71, + 0x00050080, 0x00000011, 0x00005FF0, 0x00001E89, 0x000018B2, 0x000500C4, 0x00000011, 0x0000206B, + 0x00005FF0, 0x0000085F, 0x000500C5, 0x00000011, 0x00002377, 0x00006170, 0x0000206B, 0x000500C2, + 0x00000011, 0x00005BF9, 0x000021FC, 0x000008C8, 0x000500C2, 0x00000011, 0x0000339F, 0x00005BF9, + 0x000007E1, 0x000500AB, 0x0000000F, 0x00002E83, 0x0000339F, 0x0000070F, 0x000500AA, 0x0000000F, + 0x00004EB7, 0x00005BF9, 0x000008BA, 0x000600A9, 0x00000011, 0x00001DF3, 0x00004EB7, 0x000008CF, + 0x00005BF9, 0x000600A9, 0x00000011, 0x00005A16, 0x00002E83, 0x00000A50, 0x0000070F, 0x000500C6, + 0x00000011, 0x00005C83, 0x00001DF3, 0x00005A16, 0x00050080, 0x00000011, 0x00005FBF, 0x00005C83, + 0x0000339F, 0x000500C4, 0x00000011, 0x000022B3, 0x00005FBF, 0x00000778, 0x000500C2, 0x00000011, + 0x00003521, 0x00005FBF, 0x00000778, 0x000500C5, 0x00000011, 0x00005C4D, 0x000022B3, 0x00003521, + 0x000600A9, 0x00000011, 0x00003C72, 0x00002E83, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, + 0x00001E9A, 0x00005C4D, 0x00003C72, 0x00050080, 0x00000011, 0x000056A7, 0x00001E9A, 0x0000339F, + 0x000500C5, 0x00000011, 0x0000466B, 0x000056A7, 0x00000373, 0x00050051, 0x0000000B, 0x000028D8, + 0x00002377, 0x00000000, 0x00050051, 0x0000000B, 0x00005CB5, 0x00002377, 0x00000001, 0x00050051, + 0x0000000B, 0x00001DDC, 0x0000466B, 0x00000000, 0x00050051, 0x0000000B, 0x00001E76, 0x0000466B, + 0x00000001, 0x00070050, 0x00000017, 0x000042C4, 0x000028D8, 0x00005CB5, 0x00001DDC, 0x00001E76, + 0x0009004F, 0x00000017, 0x00003DF4, 0x000042C4, 0x000042C4, 0x00000000, 0x00000002, 0x00000001, + 0x00000003, 0x00050080, 0x0000000B, 0x000055BE, 0x00002BBD, 0x00000A10, 0x00060041, 0x00000294, + 0x00001E95, 0x0000140E, 0x00000A0B, 0x000055BE, 0x0003003E, 0x00001E95, 0x00001E88, 0x00050080, + 0x0000000B, 0x00002CC2, 0x00002BBD, 0x00000A13, 0x00060041, 0x00000294, 0x00006256, 0x0000140E, + 0x00000A0B, 0x00002CC2, 0x0003003E, 0x00006256, 0x00003DF4, 0x000200F9, 0x00004C7A, 0x000200F8, + 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r11g11b10_rgba16_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r11g11b10_rgba16_cs.h new file mode 100644 index 0000000..8f411db --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r11g11b10_rgba16_cs.h @@ -0,0 +1,720 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25175 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_0 = OpConstant %uint 0 + %uint_22 = OpConstant %uint 22 + %545 = OpConstantComposite %v4uint %uint_0 %uint_22 %uint_0 %uint_22 + %uint_2047 = OpConstant %uint 2047 + %uint_1023 = OpConstant %uint 1023 + %1417 = OpConstantComposite %v4uint %uint_2047 %uint_1023 %uint_2047 %uint_1023 + %uint_5 = OpConstant %uint 5 + %uint_6 = OpConstant %uint 6 + %185 = OpConstantComposite %v4uint %uint_5 %uint_6 %uint_5 %uint_6 + %uint_26 = OpConstant %uint 26 + %809 = OpConstantComposite %v4uint %uint_6 %uint_26 %uint_6 %uint_26 + %uint_31 = OpConstant %uint 31 + %uint_63 = OpConstant %uint 63 + %2519 = OpConstantComposite %v4uint %uint_31 %uint_63 %uint_31 %uint_63 +%uint_4192256 = OpConstant %uint 4192256 + %uint_10 = OpConstant %uint 10 +%uint_4063232 = OpConstant %uint 4063232 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_4294901760 = OpConstant %uint 4294901760 + %uint_3 = OpConstant %uint 3 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_16 = OpConstant %uint 16 + %int_5 = OpConstant %int 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2603 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %554 = OpConstantComposite %v2uint %uint_4192256 %uint_4192256 + %2017 = OpConstantComposite %v2uint %uint_10 %uint_10 + %950 = OpConstantComposite %v2uint %uint_4063232 %uint_4063232 + %1578 = OpConstantComposite %v2uint %uint_4294901760 %uint_4294901760 + %200 = OpConstantNull %v2uint + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2603 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_8 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %19442 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %19442 = OpLabel + %8677 = OpIMul %int %23531 %int_4 + %17569 = OpBitcast %int %22409 + %8690 = OpIMul %int %6362 %17569 + %8334 = OpIAdd %int %8690 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %8677 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %19442 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %11682 None + OpBranchConditional %15139 %11064 %11682 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11682 + %11682 = OpLabel + %17668 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %22862 = OpVectorShuffle %v2uint %17668 %17668 0 1 + %10663 = OpVectorShuffle %v4uint %17668 %200 0 0 1 1 + %9600 = OpShiftRightLogical %v4uint %10663 %545 + %7908 = OpBitwiseAnd %v4uint %9600 %1417 + %24647 = OpShiftLeftLogical %v4uint %7908 %185 + %22610 = OpShiftRightLogical %v4uint %10663 %809 + %21478 = OpBitwiseAnd %v4uint %22610 %2519 + %15532 = OpBitwiseOr %v4uint %24647 %21478 + %20095 = OpBitwiseAnd %v2uint %22862 %554 + %22878 = OpShiftLeftLogical %v2uint %20095 %2017 + %20653 = OpBitwiseAnd %v2uint %22862 %950 + %14319 = OpShiftRightLogical %v2uint %20653 %1828 + %6675 = OpBitwiseOr %v2uint %22878 %14319 + %14801 = OpVectorShuffle %v2uint %15532 %15532 0 2 + %20933 = OpBitwiseOr %v2uint %14801 %6675 + %19024 = OpCompositeExtract %uint %20933 0 + %7209 = OpCompositeExtract %uint %20933 1 + %23049 = OpVectorShuffle %v2uint %15532 %15532 1 3 + %23934 = OpBitwiseOr %v2uint %23049 %1578 + %19043 = OpCompositeExtract %uint %23934 0 + %23865 = OpCompositeExtract %uint %23934 1 + %16161 = OpCompositeConstruct %v4uint %19024 %19043 %7209 %23865 + %7717 = OpVectorShuffle %v2uint %17668 %17668 2 3 + %9659 = OpVectorShuffle %v4uint %17668 %200 2 2 3 3 + %9601 = OpShiftRightLogical %v4uint %9659 %545 + %7909 = OpBitwiseAnd %v4uint %9601 %1417 + %24648 = OpShiftLeftLogical %v4uint %7909 %185 + %22611 = OpShiftRightLogical %v4uint %9659 %809 + %21479 = OpBitwiseAnd %v4uint %22611 %2519 + %15533 = OpBitwiseOr %v4uint %24648 %21479 + %20096 = OpBitwiseAnd %v2uint %7717 %554 + %22879 = OpShiftLeftLogical %v2uint %20096 %2017 + %20654 = OpBitwiseAnd %v2uint %7717 %950 + %14320 = OpShiftRightLogical %v2uint %20654 %1828 + %6676 = OpBitwiseOr %v2uint %22879 %14320 + %14802 = OpVectorShuffle %v2uint %15533 %15533 0 2 + %20934 = OpBitwiseOr %v2uint %14802 %6676 + %19025 = OpCompositeExtract %uint %20934 0 + %7210 = OpCompositeExtract %uint %20934 1 + %23050 = OpVectorShuffle %v2uint %15533 %15533 1 3 + %23935 = OpBitwiseOr %v2uint %23050 %1578 + %19044 = OpCompositeExtract %uint %23935 0 + %23599 = OpCompositeExtract %uint %23935 1 + %18260 = OpCompositeConstruct %v4uint %19025 %19044 %7210 %23599 + %9680 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %9680 %16161 + %11457 = OpIAdd %uint %21685 %uint_1 + %25136 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11457 + OpStore %25136 %18260 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_32 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20655 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20655 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %6871 %16377 %10584 + OpSelectionMerge %11683 None + OpBranchConditional %15139 %11065 %11683 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11683 + %11683 = OpLabel + %17669 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %22863 = OpVectorShuffle %v2uint %17669 %17669 0 1 + %10664 = OpVectorShuffle %v4uint %17669 %200 0 0 1 1 + %9602 = OpShiftRightLogical %v4uint %10664 %545 + %7910 = OpBitwiseAnd %v4uint %9602 %1417 + %24649 = OpShiftLeftLogical %v4uint %7910 %185 + %22612 = OpShiftRightLogical %v4uint %10664 %809 + %21480 = OpBitwiseAnd %v4uint %22612 %2519 + %15534 = OpBitwiseOr %v4uint %24649 %21480 + %20097 = OpBitwiseAnd %v2uint %22863 %554 + %22880 = OpShiftLeftLogical %v2uint %20097 %2017 + %20656 = OpBitwiseAnd %v2uint %22863 %950 + %14321 = OpShiftRightLogical %v2uint %20656 %1828 + %6677 = OpBitwiseOr %v2uint %22880 %14321 + %14803 = OpVectorShuffle %v2uint %15534 %15534 0 2 + %20935 = OpBitwiseOr %v2uint %14803 %6677 + %19026 = OpCompositeExtract %uint %20935 0 + %7211 = OpCompositeExtract %uint %20935 1 + %23051 = OpVectorShuffle %v2uint %15534 %15534 1 3 + %23936 = OpBitwiseOr %v2uint %23051 %1578 + %19045 = OpCompositeExtract %uint %23936 0 + %23866 = OpCompositeExtract %uint %23936 1 + %16162 = OpCompositeConstruct %v4uint %19026 %19045 %7211 %23866 + %7718 = OpVectorShuffle %v2uint %17669 %17669 2 3 + %9660 = OpVectorShuffle %v4uint %17669 %200 2 2 3 3 + %9603 = OpShiftRightLogical %v4uint %9660 %545 + %7911 = OpBitwiseAnd %v4uint %9603 %1417 + %24650 = OpShiftLeftLogical %v4uint %7911 %185 + %22613 = OpShiftRightLogical %v4uint %9660 %809 + %21481 = OpBitwiseAnd %v4uint %22613 %2519 + %15535 = OpBitwiseOr %v4uint %24650 %21481 + %20098 = OpBitwiseAnd %v2uint %7718 %554 + %22881 = OpShiftLeftLogical %v2uint %20098 %2017 + %20657 = OpBitwiseAnd %v2uint %7718 %950 + %14322 = OpShiftRightLogical %v2uint %20657 %1828 + %6678 = OpBitwiseOr %v2uint %22881 %14322 + %14804 = OpVectorShuffle %v2uint %15535 %15535 0 2 + %20936 = OpBitwiseOr %v2uint %14804 %6678 + %19027 = OpCompositeExtract %uint %20936 0 + %7212 = OpCompositeExtract %uint %20936 1 + %23053 = OpVectorShuffle %v2uint %15535 %15535 1 3 + %23937 = OpBitwiseOr %v2uint %23053 %1578 + %19046 = OpCompositeExtract %uint %23937 0 + %24796 = OpCompositeExtract %uint %23937 1 + %7418 = OpCompositeConstruct %v4uint %19027 %19046 %7212 %24796 + %6665 = OpIAdd %uint %21685 %uint_2 + %24478 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %6665 + OpStore %24478 %16162 + %11458 = OpIAdd %uint %21685 %uint_3 + %25174 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11458 + OpStore %25174 %7418 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r11g11b10_rgba16_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006257, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A4C, 0x00000016, + 0x0007002C, 0x00000017, 0x00000221, 0x00000A0A, 0x00000A4C, 0x00000A0A, 0x00000A4C, 0x0004002B, + 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, 0x0007002C, + 0x00000017, 0x00000589, 0x00000A81, 0x00000A44, 0x00000A81, 0x00000A44, 0x0004002B, 0x0000000B, + 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, 0x0007002C, 0x00000017, + 0x000000B9, 0x00000A19, 0x00000A1C, 0x00000A19, 0x00000A1C, 0x0004002B, 0x0000000B, 0x00000A58, + 0x0000001A, 0x0007002C, 0x00000017, 0x00000329, 0x00000A1C, 0x00000A58, 0x00000A1C, 0x00000A58, + 0x0004002B, 0x0000000B, 0x00000A67, 0x0000001F, 0x0004002B, 0x0000000B, 0x00000AC7, 0x0000003F, + 0x0007002C, 0x00000017, 0x000009D7, 0x00000A67, 0x00000AC7, 0x00000A67, 0x00000AC7, 0x0004002B, + 0x0000000B, 0x00000957, 0x003FF800, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, + 0x0000000B, 0x000002D7, 0x003E0000, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, + 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x0000068D, 0xFFFF0000, 0x0004002B, + 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, + 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, + 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, + 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, + 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, + 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, + 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, + 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, + 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, + 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, + 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, + 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, + 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, + 0x0000000B, 0x0005002C, 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, 0x00040020, 0x00000291, + 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, + 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A2B, 0x00000A13, 0x00000A0A, 0x00000A0A, + 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, + 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, + 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, + 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, + 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, + 0x00000A6A, 0x00000A0D, 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0007002C, 0x00000017, + 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, + 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, + 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000011, 0x0000022A, 0x00000957, 0x00000957, 0x0005002C, + 0x00000011, 0x000007E1, 0x00000A28, 0x00000A28, 0x0005002C, 0x00000011, 0x000003B6, 0x000002D7, + 0x000002D7, 0x0005002C, 0x00000011, 0x0000062A, 0x0000068D, 0x0000068D, 0x0003002E, 0x00000011, + 0x000000C8, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, + 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, + 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, + 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, 0x000500AB, 0x00000009, + 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, 0x00003526, 0x00000A10, + 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001EB0, + 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, 0x00000A13, 0x00050041, + 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, + 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, + 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, + 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, + 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, + 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, + 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, + 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A2B, 0x0007004F, 0x00000011, + 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, + 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, + 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, + 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, + 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, + 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, + 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A23, 0x00050051, 0x0000000C, 0x000018DA, + 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, + 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, + 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, + 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, + 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, + 0x0000000B, 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x000054B5, 0x00002764, + 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, 0x00005768, 0x00004BF2, + 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, 0x00004384, 0x00002BF8, + 0x000018D9, 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, 0x000032B3, 0x000044BE, 0x00000A17, + 0x000500C3, 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, 0x000500C2, 0x0000000B, 0x00004947, + 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00004947, 0x00050084, 0x0000000C, + 0x00005321, 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000032B3, 0x00005321, + 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x00003901, + 0x00002348, 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, 0x00003901, 0x000500C3, 0x0000000C, + 0x000032BA, 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, 0x00005FEE, 0x000032BA, 0x000020F4, + 0x000500C4, 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002CF6, + 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, + 0x0000000C, 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000044BE, + 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, + 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A22, + 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, + 0x000044BE, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000601E, 0x000500C7, + 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00005BEB, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, + 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, + 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, + 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, + 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, + 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x000018DA, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, 0x00050080, 0x0000000C, 0x00004157, + 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000044BE, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, + 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, + 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, + 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, + 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, + 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, + 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005EA0, + 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, 0x00005EA0, 0x000200F9, + 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, 0x000019AD, 0x000042F0, 0x00050051, + 0x0000000C, 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, + 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, + 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005788, 0x00000A19, + 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, + 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, + 0x00004A8E, 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002AB6, 0x000042C2, 0x00000A20, + 0x000500C7, 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, + 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, + 0x0000000C, 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, + 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, + 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, + 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, + 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, + 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, + 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, + 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, + 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, + 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, + 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, + 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, + 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, + 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, + 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x00002F42, 0x00003C4D, + 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, 0x0000000C, 0x0000292C, + 0x000054ED, 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, 0x00005F43, 0x000200F8, 0x00004BF2, + 0x00050084, 0x0000000C, 0x000021E5, 0x00005BEB, 0x00000A17, 0x0004007C, 0x0000000C, 0x000044A1, + 0x00005789, 0x00050084, 0x0000000C, 0x000021F2, 0x000018DA, 0x000044A1, 0x00050080, 0x0000000C, + 0x0000208E, 0x000021F2, 0x000044BE, 0x0004007C, 0x0000000C, 0x000022F8, 0x00005788, 0x00050084, + 0x0000000C, 0x00001E9F, 0x0000208E, 0x000022F8, 0x00050080, 0x0000000C, 0x00001F30, 0x000021E5, + 0x00001E9F, 0x000200F9, 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, + 0x0000292C, 0x00001E0B, 0x00001F30, 0x00004BF2, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, + 0x00050080, 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, + 0x000056CD, 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, + 0x00004315, 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004315, + 0x000500AA, 0x00000009, 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, + 0x000061E2, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, + 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, + 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, + 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, + 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, + 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, + 0x00001CAA, 0x00005F43, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000061E2, + 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x00002DA2, + 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x00002DA2, 0x000200F8, 0x00002B38, 0x000500C4, + 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, + 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x00002DA2, + 0x000200F8, 0x00002DA2, 0x000700F5, 0x00000017, 0x00004504, 0x00005879, 0x00003463, 0x000029E8, + 0x00002B38, 0x0007004F, 0x00000011, 0x0000594E, 0x00004504, 0x00004504, 0x00000000, 0x00000001, + 0x0009004F, 0x00000017, 0x000029A7, 0x00004504, 0x000000C8, 0x00000000, 0x00000000, 0x00000001, + 0x00000001, 0x000500C2, 0x00000017, 0x00002580, 0x000029A7, 0x00000221, 0x000500C7, 0x00000017, + 0x00001EE4, 0x00002580, 0x00000589, 0x000500C4, 0x00000017, 0x00006047, 0x00001EE4, 0x000000B9, + 0x000500C2, 0x00000017, 0x00005852, 0x000029A7, 0x00000329, 0x000500C7, 0x00000017, 0x000053E6, + 0x00005852, 0x000009D7, 0x000500C5, 0x00000017, 0x00003CAC, 0x00006047, 0x000053E6, 0x000500C7, + 0x00000011, 0x00004E7F, 0x0000594E, 0x0000022A, 0x000500C4, 0x00000011, 0x0000595E, 0x00004E7F, + 0x000007E1, 0x000500C7, 0x00000011, 0x000050AD, 0x0000594E, 0x000003B6, 0x000500C2, 0x00000011, + 0x000037EF, 0x000050AD, 0x00000724, 0x000500C5, 0x00000011, 0x00001A13, 0x0000595E, 0x000037EF, + 0x0007004F, 0x00000011, 0x000039D1, 0x00003CAC, 0x00003CAC, 0x00000000, 0x00000002, 0x000500C5, + 0x00000011, 0x000051C5, 0x000039D1, 0x00001A13, 0x00050051, 0x0000000B, 0x00004A50, 0x000051C5, + 0x00000000, 0x00050051, 0x0000000B, 0x00001C29, 0x000051C5, 0x00000001, 0x0007004F, 0x00000011, + 0x00005A09, 0x00003CAC, 0x00003CAC, 0x00000001, 0x00000003, 0x000500C5, 0x00000011, 0x00005D7E, + 0x00005A09, 0x0000062A, 0x00050051, 0x0000000B, 0x00004A63, 0x00005D7E, 0x00000000, 0x00050051, + 0x0000000B, 0x00005D39, 0x00005D7E, 0x00000001, 0x00070050, 0x00000017, 0x00003F21, 0x00004A50, + 0x00004A63, 0x00001C29, 0x00005D39, 0x0007004F, 0x00000011, 0x00001E25, 0x00004504, 0x00004504, + 0x00000002, 0x00000003, 0x0009004F, 0x00000017, 0x000025BB, 0x00004504, 0x000000C8, 0x00000002, + 0x00000002, 0x00000003, 0x00000003, 0x000500C2, 0x00000017, 0x00002581, 0x000025BB, 0x00000221, + 0x000500C7, 0x00000017, 0x00001EE5, 0x00002581, 0x00000589, 0x000500C4, 0x00000017, 0x00006048, + 0x00001EE5, 0x000000B9, 0x000500C2, 0x00000017, 0x00005853, 0x000025BB, 0x00000329, 0x000500C7, + 0x00000017, 0x000053E7, 0x00005853, 0x000009D7, 0x000500C5, 0x00000017, 0x00003CAD, 0x00006048, + 0x000053E7, 0x000500C7, 0x00000011, 0x00004E80, 0x00001E25, 0x0000022A, 0x000500C4, 0x00000011, + 0x0000595F, 0x00004E80, 0x000007E1, 0x000500C7, 0x00000011, 0x000050AE, 0x00001E25, 0x000003B6, + 0x000500C2, 0x00000011, 0x000037F0, 0x000050AE, 0x00000724, 0x000500C5, 0x00000011, 0x00001A14, + 0x0000595F, 0x000037F0, 0x0007004F, 0x00000011, 0x000039D2, 0x00003CAD, 0x00003CAD, 0x00000000, + 0x00000002, 0x000500C5, 0x00000011, 0x000051C6, 0x000039D2, 0x00001A14, 0x00050051, 0x0000000B, + 0x00004A51, 0x000051C6, 0x00000000, 0x00050051, 0x0000000B, 0x00001C2A, 0x000051C6, 0x00000001, + 0x0007004F, 0x00000011, 0x00005A0A, 0x00003CAD, 0x00003CAD, 0x00000001, 0x00000003, 0x000500C5, + 0x00000011, 0x00005D7F, 0x00005A0A, 0x0000062A, 0x00050051, 0x0000000B, 0x00004A64, 0x00005D7F, + 0x00000000, 0x00050051, 0x0000000B, 0x00005C2F, 0x00005D7F, 0x00000001, 0x00070050, 0x00000017, + 0x00004754, 0x00004A51, 0x00004A64, 0x00001C2A, 0x00005C2F, 0x00060041, 0x00000294, 0x000025D0, + 0x0000140E, 0x00000A0B, 0x000054B5, 0x0003003E, 0x000025D0, 0x00003F21, 0x00050080, 0x0000000B, + 0x00002CC1, 0x000054B5, 0x00000A0D, 0x00060041, 0x00000294, 0x00006230, 0x0000140E, 0x00000A0B, + 0x00002CC1, 0x0003003E, 0x00006230, 0x00004754, 0x000300F7, 0x00001AD7, 0x00000002, 0x000400FA, + 0x00004376, 0x000055E9, 0x00001C25, 0x000200F8, 0x000055E9, 0x000200F9, 0x00001AD7, 0x000200F8, + 0x00001C25, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001AD7, 0x000700F5, 0x0000000B, 0x0000456F, + 0x00000A6A, 0x000055E9, 0x00000A3A, 0x00001C25, 0x000500C2, 0x0000000B, 0x000041C0, 0x0000456F, + 0x00000A16, 0x00050080, 0x0000000B, 0x00002ADB, 0x00005665, 0x000041C0, 0x00060041, 0x00000294, + 0x0000571A, 0x0000107A, 0x00000A0B, 0x00002ADB, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, + 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, + 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, + 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AF, 0x000019B2, 0x0000072E, + 0x000500C2, 0x00000017, 0x0000448E, 0x000050AF, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, + 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, + 0x00002AAC, 0x000019B2, 0x00001AD7, 0x00003FF9, 0x00002958, 0x000300F7, 0x00002DA3, 0x00000000, + 0x000400FA, 0x00003B23, 0x00002B39, 0x00002DA3, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, + 0x00005E18, 0x00002AAC, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, + 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002DA3, 0x000200F8, + 0x00002DA3, 0x000700F5, 0x00000017, 0x00004505, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, + 0x0007004F, 0x00000011, 0x0000594F, 0x00004505, 0x00004505, 0x00000000, 0x00000001, 0x0009004F, + 0x00000017, 0x000029A8, 0x00004505, 0x000000C8, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x000500C2, 0x00000017, 0x00002582, 0x000029A8, 0x00000221, 0x000500C7, 0x00000017, 0x00001EE6, + 0x00002582, 0x00000589, 0x000500C4, 0x00000017, 0x00006049, 0x00001EE6, 0x000000B9, 0x000500C2, + 0x00000017, 0x00005854, 0x000029A8, 0x00000329, 0x000500C7, 0x00000017, 0x000053E8, 0x00005854, + 0x000009D7, 0x000500C5, 0x00000017, 0x00003CAE, 0x00006049, 0x000053E8, 0x000500C7, 0x00000011, + 0x00004E81, 0x0000594F, 0x0000022A, 0x000500C4, 0x00000011, 0x00005960, 0x00004E81, 0x000007E1, + 0x000500C7, 0x00000011, 0x000050B0, 0x0000594F, 0x000003B6, 0x000500C2, 0x00000011, 0x000037F1, + 0x000050B0, 0x00000724, 0x000500C5, 0x00000011, 0x00001A15, 0x00005960, 0x000037F1, 0x0007004F, + 0x00000011, 0x000039D3, 0x00003CAE, 0x00003CAE, 0x00000000, 0x00000002, 0x000500C5, 0x00000011, + 0x000051C7, 0x000039D3, 0x00001A15, 0x00050051, 0x0000000B, 0x00004A52, 0x000051C7, 0x00000000, + 0x00050051, 0x0000000B, 0x00001C2B, 0x000051C7, 0x00000001, 0x0007004F, 0x00000011, 0x00005A0B, + 0x00003CAE, 0x00003CAE, 0x00000001, 0x00000003, 0x000500C5, 0x00000011, 0x00005D80, 0x00005A0B, + 0x0000062A, 0x00050051, 0x0000000B, 0x00004A65, 0x00005D80, 0x00000000, 0x00050051, 0x0000000B, + 0x00005D3A, 0x00005D80, 0x00000001, 0x00070050, 0x00000017, 0x00003F22, 0x00004A52, 0x00004A65, + 0x00001C2B, 0x00005D3A, 0x0007004F, 0x00000011, 0x00001E26, 0x00004505, 0x00004505, 0x00000002, + 0x00000003, 0x0009004F, 0x00000017, 0x000025BC, 0x00004505, 0x000000C8, 0x00000002, 0x00000002, + 0x00000003, 0x00000003, 0x000500C2, 0x00000017, 0x00002583, 0x000025BC, 0x00000221, 0x000500C7, + 0x00000017, 0x00001EE7, 0x00002583, 0x00000589, 0x000500C4, 0x00000017, 0x0000604A, 0x00001EE7, + 0x000000B9, 0x000500C2, 0x00000017, 0x00005855, 0x000025BC, 0x00000329, 0x000500C7, 0x00000017, + 0x000053E9, 0x00005855, 0x000009D7, 0x000500C5, 0x00000017, 0x00003CAF, 0x0000604A, 0x000053E9, + 0x000500C7, 0x00000011, 0x00004E82, 0x00001E26, 0x0000022A, 0x000500C4, 0x00000011, 0x00005961, + 0x00004E82, 0x000007E1, 0x000500C7, 0x00000011, 0x000050B1, 0x00001E26, 0x000003B6, 0x000500C2, + 0x00000011, 0x000037F2, 0x000050B1, 0x00000724, 0x000500C5, 0x00000011, 0x00001A16, 0x00005961, + 0x000037F2, 0x0007004F, 0x00000011, 0x000039D4, 0x00003CAF, 0x00003CAF, 0x00000000, 0x00000002, + 0x000500C5, 0x00000011, 0x000051C8, 0x000039D4, 0x00001A16, 0x00050051, 0x0000000B, 0x00004A53, + 0x000051C8, 0x00000000, 0x00050051, 0x0000000B, 0x00001C2C, 0x000051C8, 0x00000001, 0x0007004F, + 0x00000011, 0x00005A0D, 0x00003CAF, 0x00003CAF, 0x00000001, 0x00000003, 0x000500C5, 0x00000011, + 0x00005D81, 0x00005A0D, 0x0000062A, 0x00050051, 0x0000000B, 0x00004A66, 0x00005D81, 0x00000000, + 0x00050051, 0x0000000B, 0x000060DC, 0x00005D81, 0x00000001, 0x00070050, 0x00000017, 0x00001CFA, + 0x00004A53, 0x00004A66, 0x00001C2C, 0x000060DC, 0x00050080, 0x0000000B, 0x00001A09, 0x000054B5, + 0x00000A10, 0x00060041, 0x00000294, 0x00005F9E, 0x0000140E, 0x00000A0B, 0x00001A09, 0x0003003E, + 0x00005F9E, 0x00003F22, 0x00050080, 0x0000000B, 0x00002CC2, 0x000054B5, 0x00000A13, 0x00060041, + 0x00000294, 0x00006256, 0x0000140E, 0x00000A0B, 0x00002CC2, 0x0003003E, 0x00006256, 0x00001CFA, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r11g11b10_rgba16_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r11g11b10_rgba16_scaled_cs.h new file mode 100644 index 0000000..8a805fb --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r11g11b10_rgba16_scaled_cs.h @@ -0,0 +1,781 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25175 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_0 = OpConstant %uint 0 + %uint_22 = OpConstant %uint 22 + %545 = OpConstantComposite %v4uint %uint_0 %uint_22 %uint_0 %uint_22 + %uint_2047 = OpConstant %uint 2047 + %uint_1023 = OpConstant %uint 1023 + %1417 = OpConstantComposite %v4uint %uint_2047 %uint_1023 %uint_2047 %uint_1023 + %uint_5 = OpConstant %uint 5 + %uint_6 = OpConstant %uint 6 + %185 = OpConstantComposite %v4uint %uint_5 %uint_6 %uint_5 %uint_6 + %uint_26 = OpConstant %uint 26 + %809 = OpConstantComposite %v4uint %uint_6 %uint_26 %uint_6 %uint_26 + %uint_31 = OpConstant %uint 31 + %uint_63 = OpConstant %uint 63 + %2519 = OpConstantComposite %v4uint %uint_31 %uint_63 %uint_31 %uint_63 +%uint_4192256 = OpConstant %uint 4192256 + %uint_10 = OpConstant %uint 10 +%uint_4063232 = OpConstant %uint 4063232 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_4294901760 = OpConstant %uint 4294901760 + %uint_3 = OpConstant %uint 3 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_16 = OpConstant %uint 16 + %int_5 = OpConstant %int 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2603 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %554 = OpConstantComposite %v2uint %uint_4192256 %uint_4192256 + %2017 = OpConstantComposite %v2uint %uint_10 %uint_10 + %950 = OpConstantComposite %v2uint %uint_4063232 %uint_4063232 + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %1578 = OpConstantComposite %v2uint %uint_4294901760 %uint_4294901760 + %200 = OpConstantNull %v2uint + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2603 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_8 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_2 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_2 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_2 + %23219 = OpBitwiseAnd %uint %10722 %uint_3 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_2 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %7338 = OpLoad %v4uint %20399 + %13760 = OpIEqual %bool %24990 %uint_1 + %21366 = OpIEqual %bool %24990 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %21313 %16376 %10583 + %19638 = OpIEqual %bool %24990 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %11682 None + OpBranchConditional %15139 %11064 %11682 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11682 + %11682 = OpLabel + %17668 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %22862 = OpVectorShuffle %v2uint %17668 %17668 0 1 + %10663 = OpVectorShuffle %v4uint %17668 %200 0 0 1 1 + %9600 = OpShiftRightLogical %v4uint %10663 %545 + %7908 = OpBitwiseAnd %v4uint %9600 %1417 + %24647 = OpShiftLeftLogical %v4uint %7908 %185 + %22610 = OpShiftRightLogical %v4uint %10663 %809 + %21478 = OpBitwiseAnd %v4uint %22610 %2519 + %15532 = OpBitwiseOr %v4uint %24647 %21478 + %20095 = OpBitwiseAnd %v2uint %22862 %554 + %22878 = OpShiftLeftLogical %v2uint %20095 %2017 + %20653 = OpBitwiseAnd %v2uint %22862 %950 + %14319 = OpShiftRightLogical %v2uint %20653 %1828 + %6675 = OpBitwiseOr %v2uint %22878 %14319 + %14801 = OpVectorShuffle %v2uint %15532 %15532 0 2 + %20933 = OpBitwiseOr %v2uint %14801 %6675 + %19024 = OpCompositeExtract %uint %20933 0 + %7209 = OpCompositeExtract %uint %20933 1 + %23049 = OpVectorShuffle %v2uint %15532 %15532 1 3 + %23934 = OpBitwiseOr %v2uint %23049 %1578 + %19043 = OpCompositeExtract %uint %23934 0 + %23865 = OpCompositeExtract %uint %23934 1 + %16161 = OpCompositeConstruct %v4uint %19024 %19043 %7209 %23865 + %7717 = OpVectorShuffle %v2uint %17668 %17668 2 3 + %9659 = OpVectorShuffle %v4uint %17668 %200 2 2 3 3 + %9601 = OpShiftRightLogical %v4uint %9659 %545 + %7909 = OpBitwiseAnd %v4uint %9601 %1417 + %24648 = OpShiftLeftLogical %v4uint %7909 %185 + %22611 = OpShiftRightLogical %v4uint %9659 %809 + %21479 = OpBitwiseAnd %v4uint %22611 %2519 + %15533 = OpBitwiseOr %v4uint %24648 %21479 + %20096 = OpBitwiseAnd %v2uint %7717 %554 + %22879 = OpShiftLeftLogical %v2uint %20096 %2017 + %20654 = OpBitwiseAnd %v2uint %7717 %950 + %14320 = OpShiftRightLogical %v2uint %20654 %1828 + %6676 = OpBitwiseOr %v2uint %22879 %14320 + %14802 = OpVectorShuffle %v2uint %15533 %15533 0 2 + %20934 = OpBitwiseOr %v2uint %14802 %6676 + %19025 = OpCompositeExtract %uint %20934 0 + %7210 = OpCompositeExtract %uint %20934 1 + %23050 = OpVectorShuffle %v2uint %15533 %15533 1 3 + %23935 = OpBitwiseOr %v2uint %23050 %1578 + %19044 = OpCompositeExtract %uint %23935 0 + %23599 = OpCompositeExtract %uint %23935 1 + %18260 = OpCompositeConstruct %v4uint %19025 %19044 %7210 %23599 + %9680 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %9680 %16161 + %11457 = OpIAdd %uint %11197 %uint_1 + %23711 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11457 + OpStore %23711 %18260 + %23542 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %23542 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_32 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_32 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20655 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20655 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %24764 %16377 %10584 + OpSelectionMerge %11683 None + OpBranchConditional %15139 %11065 %11683 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11683 + %11683 = OpLabel + %17669 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %22863 = OpVectorShuffle %v2uint %17669 %17669 0 1 + %10664 = OpVectorShuffle %v4uint %17669 %200 0 0 1 1 + %9602 = OpShiftRightLogical %v4uint %10664 %545 + %7910 = OpBitwiseAnd %v4uint %9602 %1417 + %24649 = OpShiftLeftLogical %v4uint %7910 %185 + %22612 = OpShiftRightLogical %v4uint %10664 %809 + %21480 = OpBitwiseAnd %v4uint %22612 %2519 + %15534 = OpBitwiseOr %v4uint %24649 %21480 + %20097 = OpBitwiseAnd %v2uint %22863 %554 + %22880 = OpShiftLeftLogical %v2uint %20097 %2017 + %20656 = OpBitwiseAnd %v2uint %22863 %950 + %14321 = OpShiftRightLogical %v2uint %20656 %1828 + %6677 = OpBitwiseOr %v2uint %22880 %14321 + %14803 = OpVectorShuffle %v2uint %15534 %15534 0 2 + %20935 = OpBitwiseOr %v2uint %14803 %6677 + %19026 = OpCompositeExtract %uint %20935 0 + %7211 = OpCompositeExtract %uint %20935 1 + %23051 = OpVectorShuffle %v2uint %15534 %15534 1 3 + %23936 = OpBitwiseOr %v2uint %23051 %1578 + %19045 = OpCompositeExtract %uint %23936 0 + %23866 = OpCompositeExtract %uint %23936 1 + %16162 = OpCompositeConstruct %v4uint %19026 %19045 %7211 %23866 + %7718 = OpVectorShuffle %v2uint %17669 %17669 2 3 + %9660 = OpVectorShuffle %v4uint %17669 %200 2 2 3 3 + %9603 = OpShiftRightLogical %v4uint %9660 %545 + %7911 = OpBitwiseAnd %v4uint %9603 %1417 + %24650 = OpShiftLeftLogical %v4uint %7911 %185 + %22613 = OpShiftRightLogical %v4uint %9660 %809 + %21481 = OpBitwiseAnd %v4uint %22613 %2519 + %15535 = OpBitwiseOr %v4uint %24650 %21481 + %20098 = OpBitwiseAnd %v2uint %7718 %554 + %22881 = OpShiftLeftLogical %v2uint %20098 %2017 + %20657 = OpBitwiseAnd %v2uint %7718 %950 + %14322 = OpShiftRightLogical %v2uint %20657 %1828 + %6678 = OpBitwiseOr %v2uint %22881 %14322 + %14804 = OpVectorShuffle %v2uint %15535 %15535 0 2 + %20936 = OpBitwiseOr %v2uint %14804 %6678 + %19027 = OpCompositeExtract %uint %20936 0 + %7212 = OpCompositeExtract %uint %20936 1 + %23053 = OpVectorShuffle %v2uint %15535 %15535 1 3 + %23937 = OpBitwiseOr %v2uint %23053 %1578 + %19046 = OpCompositeExtract %uint %23937 0 + %24796 = OpCompositeExtract %uint %23937 1 + %7418 = OpCompositeConstruct %v4uint %19027 %19046 %7212 %24796 + %6665 = OpIAdd %uint %11197 %uint_2 + %24478 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %6665 + OpStore %24478 %16162 + %11458 = OpIAdd %uint %11197 %uint_3 + %25174 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11458 + OpStore %25174 %7418 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r11g11b10_rgba16_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006257, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A4C, 0x00000016, + 0x0007002C, 0x00000017, 0x00000221, 0x00000A0A, 0x00000A4C, 0x00000A0A, 0x00000A4C, 0x0004002B, + 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, 0x0007002C, + 0x00000017, 0x00000589, 0x00000A81, 0x00000A44, 0x00000A81, 0x00000A44, 0x0004002B, 0x0000000B, + 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, 0x0007002C, 0x00000017, + 0x000000B9, 0x00000A19, 0x00000A1C, 0x00000A19, 0x00000A1C, 0x0004002B, 0x0000000B, 0x00000A58, + 0x0000001A, 0x0007002C, 0x00000017, 0x00000329, 0x00000A1C, 0x00000A58, 0x00000A1C, 0x00000A58, + 0x0004002B, 0x0000000B, 0x00000A67, 0x0000001F, 0x0004002B, 0x0000000B, 0x00000AC7, 0x0000003F, + 0x0007002C, 0x00000017, 0x000009D7, 0x00000A67, 0x00000AC7, 0x00000A67, 0x00000AC7, 0x0004002B, + 0x0000000B, 0x00000957, 0x003FF800, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, + 0x0000000B, 0x000002D7, 0x003E0000, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, + 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x0000068D, 0xFFFF0000, 0x0004002B, + 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, + 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, + 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, + 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, + 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, + 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, + 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, + 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, + 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, + 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, + 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, + 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, + 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, + 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, 0x00000787, + 0x00000A16, 0x00000A1F, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, + 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, + 0x00000A2B, 0x00000A13, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, + 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, + 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, 0x00000011, + 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0007002C, + 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, + 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, + 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000011, 0x0000022A, 0x00000957, 0x00000957, + 0x0005002C, 0x00000011, 0x000007E1, 0x00000A28, 0x00000A28, 0x0005002C, 0x00000011, 0x000003B6, + 0x000002D7, 0x000002D7, 0x0005002C, 0x00000011, 0x00000724, 0x00000A0D, 0x00000A0D, 0x0005002C, + 0x00000011, 0x0000062A, 0x0000068D, 0x0000068D, 0x0003002E, 0x00000011, 0x000000C8, 0x00050036, + 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, + 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, + 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, + 0x0000000B, 0x00005F7D, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x000048EB, 0x00005F7D, + 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001FCD, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, + 0x0000619E, 0x00001FCD, 0x00000A13, 0x00050050, 0x00000011, 0x000022A7, 0x00003526, 0x00003526, + 0x000500C2, 0x00000011, 0x00001BAF, 0x000022A7, 0x00000787, 0x000500C7, 0x00000011, 0x00001997, + 0x00001BAF, 0x000007A2, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, + 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, + 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, + 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, + 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, + 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, + 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, + 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, + 0x00000A2B, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, + 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, + 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, + 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, + 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, + 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, + 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A23, + 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, + 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, + 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, + 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, + 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, + 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00001B12, 0x00002A92, 0x0000578B, 0x000500C2, + 0x0000000B, 0x00002BBD, 0x00001B12, 0x00000A16, 0x00050051, 0x0000000B, 0x000029E2, 0x0000538B, + 0x00000000, 0x000500C2, 0x0000000B, 0x00001DEE, 0x000029E2, 0x00000A10, 0x00050051, 0x0000000B, + 0x00002704, 0x0000538B, 0x00000001, 0x00050050, 0x00000011, 0x00005C0B, 0x00001DEE, 0x00002704, + 0x00050086, 0x00000011, 0x00001F69, 0x00005C0B, 0x00001997, 0x00050051, 0x0000000B, 0x0000366C, + 0x00001F69, 0x00000000, 0x000500C4, 0x0000000B, 0x00004D4D, 0x0000366C, 0x00000A10, 0x00050051, + 0x0000000B, 0x000051A9, 0x00001F69, 0x00000001, 0x00050051, 0x0000000B, 0x000059EE, 0x0000538B, + 0x00000002, 0x00060050, 0x00000014, 0x000024C9, 0x00004D4D, 0x000051A9, 0x000059EE, 0x000300F7, + 0x00005341, 0x00000002, 0x000400FA, 0x000048EB, 0x0000537D, 0x00002DD9, 0x000200F8, 0x0000537D, + 0x0004007C, 0x00000016, 0x00002970, 0x000024C9, 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, + 0x00000001, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, + 0x00002747, 0x00002970, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A11, + 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, + 0x00005B4D, 0x00050084, 0x0000000C, 0x00005321, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, + 0x00003B27, 0x000024FD, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, + 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, + 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, + 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, + 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002CF6, + 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, + 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000042C2, + 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, + 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A22, + 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, + 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405C, 0x000500C7, + 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, + 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, + 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, + 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, + 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, + 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, + 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, 0x00050080, 0x0000000C, 0x00004157, + 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000042C2, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, + 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, + 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, + 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, + 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, + 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, + 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, + 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, 0x0004007C, + 0x0000000B, 0x0000566F, 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, 0x00002DD9, 0x0007004F, + 0x00000011, 0x00002621, 0x000024C9, 0x000024C9, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, + 0x000059CF, 0x00002621, 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, 0x00000000, 0x000500C3, + 0x0000000C, 0x000024FE, 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002748, 0x000059CF, + 0x00000001, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, 0x000500C2, 0x0000000B, + 0x00005B4E, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, + 0x0000000C, 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FE, + 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, + 0x00002AB6, 0x00001903, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002748, 0x00000A35, + 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, + 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, + 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, + 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, + 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, + 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, + 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, + 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, 0x000500C4, 0x0000000C, + 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, + 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, + 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, + 0x0000000C, 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, + 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x00001903, 0x00000A14, 0x00050080, 0x0000000C, + 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, + 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x00002E06, 0x00004159, 0x00000AC8, 0x00050080, + 0x0000000C, 0x0000394F, 0x00003C4D, 0x00002E06, 0x0004007C, 0x0000000B, 0x00005670, 0x0000394F, + 0x000200F9, 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, 0x000024FC, 0x0000566F, + 0x0000537D, 0x00005670, 0x00002DD9, 0x00050084, 0x00000011, 0x00003FA8, 0x00001F69, 0x00001997, + 0x00050082, 0x00000011, 0x00003BBC, 0x00005C0B, 0x00003FA8, 0x00050051, 0x0000000B, 0x00001C87, + 0x00001997, 0x00000000, 0x00050051, 0x0000000B, 0x00005962, 0x00001997, 0x00000001, 0x00050084, + 0x0000000B, 0x00003372, 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, 0x00003CA0, 0x000024FC, + 0x00003372, 0x00050051, 0x0000000B, 0x00003ED4, 0x00003BBC, 0x00000000, 0x00050084, 0x0000000B, + 0x00003E12, 0x00003ED4, 0x00005962, 0x00050051, 0x0000000B, 0x00001AE6, 0x00003BBC, 0x00000001, + 0x00050080, 0x0000000B, 0x00002B25, 0x00003E12, 0x00001AE6, 0x000500C4, 0x0000000B, 0x0000609D, + 0x00002B25, 0x00000A10, 0x000500C7, 0x0000000B, 0x00005AB3, 0x000029E2, 0x00000A13, 0x00050080, + 0x0000000B, 0x00002557, 0x0000609D, 0x00005AB3, 0x000500C4, 0x0000000B, 0x000040AD, 0x00002557, + 0x00000A10, 0x00050080, 0x0000000B, 0x00004EAA, 0x00003CA0, 0x000040AD, 0x00050080, 0x0000000B, + 0x00003BA9, 0x00005EAC, 0x00004EAA, 0x000500C2, 0x0000000B, 0x00003948, 0x00003BA9, 0x00000A16, + 0x00060041, 0x00000294, 0x00004FAF, 0x0000107A, 0x00000A0B, 0x00003948, 0x0004003D, 0x00000017, + 0x00001CAA, 0x00004FAF, 0x000500AA, 0x00000009, 0x000035C0, 0x0000619E, 0x00000A0D, 0x000500AA, + 0x00000009, 0x00005376, 0x0000619E, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, + 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, + 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, + 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, + 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, + 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, + 0x00000017, 0x00005879, 0x00001CAA, 0x00005341, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, + 0x00004CB6, 0x0000619E, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, + 0x000300F7, 0x00002DA2, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x00002DA2, 0x000200F8, + 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, + 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, + 0x000200F9, 0x00002DA2, 0x000200F8, 0x00002DA2, 0x000700F5, 0x00000017, 0x00004504, 0x00005879, + 0x00003463, 0x000029E8, 0x00002B38, 0x0007004F, 0x00000011, 0x0000594E, 0x00004504, 0x00004504, + 0x00000000, 0x00000001, 0x0009004F, 0x00000017, 0x000029A7, 0x00004504, 0x000000C8, 0x00000000, + 0x00000000, 0x00000001, 0x00000001, 0x000500C2, 0x00000017, 0x00002580, 0x000029A7, 0x00000221, + 0x000500C7, 0x00000017, 0x00001EE4, 0x00002580, 0x00000589, 0x000500C4, 0x00000017, 0x00006047, + 0x00001EE4, 0x000000B9, 0x000500C2, 0x00000017, 0x00005852, 0x000029A7, 0x00000329, 0x000500C7, + 0x00000017, 0x000053E6, 0x00005852, 0x000009D7, 0x000500C5, 0x00000017, 0x00003CAC, 0x00006047, + 0x000053E6, 0x000500C7, 0x00000011, 0x00004E7F, 0x0000594E, 0x0000022A, 0x000500C4, 0x00000011, + 0x0000595E, 0x00004E7F, 0x000007E1, 0x000500C7, 0x00000011, 0x000050AD, 0x0000594E, 0x000003B6, + 0x000500C2, 0x00000011, 0x000037EF, 0x000050AD, 0x00000724, 0x000500C5, 0x00000011, 0x00001A13, + 0x0000595E, 0x000037EF, 0x0007004F, 0x00000011, 0x000039D1, 0x00003CAC, 0x00003CAC, 0x00000000, + 0x00000002, 0x000500C5, 0x00000011, 0x000051C5, 0x000039D1, 0x00001A13, 0x00050051, 0x0000000B, + 0x00004A50, 0x000051C5, 0x00000000, 0x00050051, 0x0000000B, 0x00001C29, 0x000051C5, 0x00000001, + 0x0007004F, 0x00000011, 0x00005A09, 0x00003CAC, 0x00003CAC, 0x00000001, 0x00000003, 0x000500C5, + 0x00000011, 0x00005D7E, 0x00005A09, 0x0000062A, 0x00050051, 0x0000000B, 0x00004A63, 0x00005D7E, + 0x00000000, 0x00050051, 0x0000000B, 0x00005D39, 0x00005D7E, 0x00000001, 0x00070050, 0x00000017, + 0x00003F21, 0x00004A50, 0x00004A63, 0x00001C29, 0x00005D39, 0x0007004F, 0x00000011, 0x00001E25, + 0x00004504, 0x00004504, 0x00000002, 0x00000003, 0x0009004F, 0x00000017, 0x000025BB, 0x00004504, + 0x000000C8, 0x00000002, 0x00000002, 0x00000003, 0x00000003, 0x000500C2, 0x00000017, 0x00002581, + 0x000025BB, 0x00000221, 0x000500C7, 0x00000017, 0x00001EE5, 0x00002581, 0x00000589, 0x000500C4, + 0x00000017, 0x00006048, 0x00001EE5, 0x000000B9, 0x000500C2, 0x00000017, 0x00005853, 0x000025BB, + 0x00000329, 0x000500C7, 0x00000017, 0x000053E7, 0x00005853, 0x000009D7, 0x000500C5, 0x00000017, + 0x00003CAD, 0x00006048, 0x000053E7, 0x000500C7, 0x00000011, 0x00004E80, 0x00001E25, 0x0000022A, + 0x000500C4, 0x00000011, 0x0000595F, 0x00004E80, 0x000007E1, 0x000500C7, 0x00000011, 0x000050AE, + 0x00001E25, 0x000003B6, 0x000500C2, 0x00000011, 0x000037F0, 0x000050AE, 0x00000724, 0x000500C5, + 0x00000011, 0x00001A14, 0x0000595F, 0x000037F0, 0x0007004F, 0x00000011, 0x000039D2, 0x00003CAD, + 0x00003CAD, 0x00000000, 0x00000002, 0x000500C5, 0x00000011, 0x000051C6, 0x000039D2, 0x00001A14, + 0x00050051, 0x0000000B, 0x00004A51, 0x000051C6, 0x00000000, 0x00050051, 0x0000000B, 0x00001C2A, + 0x000051C6, 0x00000001, 0x0007004F, 0x00000011, 0x00005A0A, 0x00003CAD, 0x00003CAD, 0x00000001, + 0x00000003, 0x000500C5, 0x00000011, 0x00005D7F, 0x00005A0A, 0x0000062A, 0x00050051, 0x0000000B, + 0x00004A64, 0x00005D7F, 0x00000000, 0x00050051, 0x0000000B, 0x00005C2F, 0x00005D7F, 0x00000001, + 0x00070050, 0x00000017, 0x00004754, 0x00004A51, 0x00004A64, 0x00001C2A, 0x00005C2F, 0x00060041, + 0x00000294, 0x000025D0, 0x0000140E, 0x00000A0B, 0x00002BBD, 0x0003003E, 0x000025D0, 0x00003F21, + 0x00050080, 0x0000000B, 0x00002CC1, 0x00002BBD, 0x00000A0D, 0x00060041, 0x00000294, 0x00005C9F, + 0x0000140E, 0x00000A0B, 0x00002CC1, 0x0003003E, 0x00005C9F, 0x00004754, 0x000500AC, 0x00000009, + 0x00005BF6, 0x00001C87, 0x00000A0D, 0x000300F7, 0x000060BC, 0x00000002, 0x000400FA, 0x00005BF6, + 0x00005084, 0x00005094, 0x000200F8, 0x00005084, 0x00050086, 0x0000000B, 0x00003697, 0x00001DEE, + 0x00001C87, 0x00050084, 0x0000000B, 0x0000237E, 0x00003697, 0x00001C87, 0x00050082, 0x0000000B, + 0x00003171, 0x00001DEE, 0x0000237E, 0x00050080, 0x0000000B, 0x00002527, 0x00003171, 0x00000A0D, + 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, 0x00001C87, 0x000300F7, 0x00001EED, 0x00000000, + 0x000400FA, 0x0000343F, 0x0000569E, 0x00002191, 0x000200F8, 0x0000569E, 0x00050084, 0x0000000B, + 0x00004B59, 0x00000A6A, 0x00001C87, 0x000500C4, 0x0000000B, 0x0000540F, 0x00003171, 0x00000A16, + 0x00050082, 0x0000000B, 0x00004944, 0x00004B59, 0x0000540F, 0x000200F9, 0x00001EED, 0x000200F8, + 0x00002191, 0x000200F9, 0x00001EED, 0x000200F8, 0x00001EED, 0x000700F5, 0x0000000B, 0x0000292C, + 0x00004944, 0x0000569E, 0x00000A3A, 0x00002191, 0x000200F9, 0x000060BC, 0x000200F8, 0x00005094, + 0x000200F9, 0x000060BC, 0x000200F8, 0x000060BC, 0x000700F5, 0x0000000B, 0x000029BC, 0x0000292C, + 0x00001EED, 0x00000A6A, 0x00005094, 0x00050084, 0x0000000B, 0x0000492B, 0x000029BC, 0x00005962, + 0x000500C2, 0x0000000B, 0x0000406D, 0x0000492B, 0x00000A16, 0x00050080, 0x0000000B, 0x0000336B, + 0x00003948, 0x0000406D, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, 0x0000336B, + 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, + 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, + 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, + 0x00000017, 0x000050AF, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AF, + 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, + 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x000060BC, 0x00003FF9, + 0x00002958, 0x000300F7, 0x00002DA3, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, 0x00002DA3, + 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, 0x000500C2, + 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, + 0x00003BE8, 0x000200F9, 0x00002DA3, 0x000200F8, 0x00002DA3, 0x000700F5, 0x00000017, 0x00004505, + 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x0007004F, 0x00000011, 0x0000594F, 0x00004505, + 0x00004505, 0x00000000, 0x00000001, 0x0009004F, 0x00000017, 0x000029A8, 0x00004505, 0x000000C8, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000500C2, 0x00000017, 0x00002582, 0x000029A8, + 0x00000221, 0x000500C7, 0x00000017, 0x00001EE6, 0x00002582, 0x00000589, 0x000500C4, 0x00000017, + 0x00006049, 0x00001EE6, 0x000000B9, 0x000500C2, 0x00000017, 0x00005854, 0x000029A8, 0x00000329, + 0x000500C7, 0x00000017, 0x000053E8, 0x00005854, 0x000009D7, 0x000500C5, 0x00000017, 0x00003CAE, + 0x00006049, 0x000053E8, 0x000500C7, 0x00000011, 0x00004E81, 0x0000594F, 0x0000022A, 0x000500C4, + 0x00000011, 0x00005960, 0x00004E81, 0x000007E1, 0x000500C7, 0x00000011, 0x000050B0, 0x0000594F, + 0x000003B6, 0x000500C2, 0x00000011, 0x000037F1, 0x000050B0, 0x00000724, 0x000500C5, 0x00000011, + 0x00001A15, 0x00005960, 0x000037F1, 0x0007004F, 0x00000011, 0x000039D3, 0x00003CAE, 0x00003CAE, + 0x00000000, 0x00000002, 0x000500C5, 0x00000011, 0x000051C7, 0x000039D3, 0x00001A15, 0x00050051, + 0x0000000B, 0x00004A52, 0x000051C7, 0x00000000, 0x00050051, 0x0000000B, 0x00001C2B, 0x000051C7, + 0x00000001, 0x0007004F, 0x00000011, 0x00005A0B, 0x00003CAE, 0x00003CAE, 0x00000001, 0x00000003, + 0x000500C5, 0x00000011, 0x00005D80, 0x00005A0B, 0x0000062A, 0x00050051, 0x0000000B, 0x00004A65, + 0x00005D80, 0x00000000, 0x00050051, 0x0000000B, 0x00005D3A, 0x00005D80, 0x00000001, 0x00070050, + 0x00000017, 0x00003F22, 0x00004A52, 0x00004A65, 0x00001C2B, 0x00005D3A, 0x0007004F, 0x00000011, + 0x00001E26, 0x00004505, 0x00004505, 0x00000002, 0x00000003, 0x0009004F, 0x00000017, 0x000025BC, + 0x00004505, 0x000000C8, 0x00000002, 0x00000002, 0x00000003, 0x00000003, 0x000500C2, 0x00000017, + 0x00002583, 0x000025BC, 0x00000221, 0x000500C7, 0x00000017, 0x00001EE7, 0x00002583, 0x00000589, + 0x000500C4, 0x00000017, 0x0000604A, 0x00001EE7, 0x000000B9, 0x000500C2, 0x00000017, 0x00005855, + 0x000025BC, 0x00000329, 0x000500C7, 0x00000017, 0x000053E9, 0x00005855, 0x000009D7, 0x000500C5, + 0x00000017, 0x00003CAF, 0x0000604A, 0x000053E9, 0x000500C7, 0x00000011, 0x00004E82, 0x00001E26, + 0x0000022A, 0x000500C4, 0x00000011, 0x00005961, 0x00004E82, 0x000007E1, 0x000500C7, 0x00000011, + 0x000050B1, 0x00001E26, 0x000003B6, 0x000500C2, 0x00000011, 0x000037F2, 0x000050B1, 0x00000724, + 0x000500C5, 0x00000011, 0x00001A16, 0x00005961, 0x000037F2, 0x0007004F, 0x00000011, 0x000039D4, + 0x00003CAF, 0x00003CAF, 0x00000000, 0x00000002, 0x000500C5, 0x00000011, 0x000051C8, 0x000039D4, + 0x00001A16, 0x00050051, 0x0000000B, 0x00004A53, 0x000051C8, 0x00000000, 0x00050051, 0x0000000B, + 0x00001C2C, 0x000051C8, 0x00000001, 0x0007004F, 0x00000011, 0x00005A0D, 0x00003CAF, 0x00003CAF, + 0x00000001, 0x00000003, 0x000500C5, 0x00000011, 0x00005D81, 0x00005A0D, 0x0000062A, 0x00050051, + 0x0000000B, 0x00004A66, 0x00005D81, 0x00000000, 0x00050051, 0x0000000B, 0x000060DC, 0x00005D81, + 0x00000001, 0x00070050, 0x00000017, 0x00001CFA, 0x00004A53, 0x00004A66, 0x00001C2C, 0x000060DC, + 0x00050080, 0x0000000B, 0x00001A09, 0x00002BBD, 0x00000A10, 0x00060041, 0x00000294, 0x00005F9E, + 0x0000140E, 0x00000A0B, 0x00001A09, 0x0003003E, 0x00005F9E, 0x00003F22, 0x00050080, 0x0000000B, + 0x00002CC2, 0x00002BBD, 0x00000A13, 0x00060041, 0x00000294, 0x00006256, 0x0000140E, 0x00000A0B, + 0x00002CC2, 0x0003003E, 0x00006256, 0x00001CFA, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, + 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r11g11b10_rgba16_snorm_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r11g11b10_rgba16_snorm_cs.h new file mode 100644 index 0000000..6afcd5f --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r11g11b10_rgba16_snorm_cs.h @@ -0,0 +1,934 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25175 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_9 = OpConstant %uint 9 + %v2bool = OpTypeVector %bool 2 + %uint_0 = OpConstant %uint 0 + %uint_513 = OpConstant %uint 513 + %uint_512 = OpConstant %uint 512 + %uint_1023 = OpConstant %uint 1023 + %uint_6 = OpConstant %uint 6 + %uint_3 = OpConstant %uint 3 + %uint_65535 = OpConstant %uint 65535 + %uint_10 = OpConstant %uint 10 + %uint_1025 = OpConstant %uint 1025 + %uint_1024 = OpConstant %uint 1024 + %uint_2047 = OpConstant %uint 2047 + %uint_5 = OpConstant %uint 5 + %uint_11 = OpConstant %uint 11 + %uint_16 = OpConstant %uint 16 + %uint_22 = OpConstant %uint 22 +%uint_2147418112 = OpConstant %uint 2147418112 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2604 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %2640 = OpConstantComposite %v2uint %uint_2047 %uint_2047 + %2017 = OpConstantComposite %v2uint %uint_10 %uint_10 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %2255 = OpConstantComposite %v2uint %uint_1025 %uint_1025 + %2234 = OpConstantComposite %v2uint %uint_1024 %uint_1024 + %1912 = OpConstantComposite %v2uint %uint_5 %uint_5 + %2015 = OpConstantComposite %v2uint %uint_65535 %uint_65535 + %2038 = OpConstantComposite %v2uint %uint_11 %uint_11 + %2143 = OpConstantComposite %v2uint %uint_16 %uint_16 + %2269 = OpConstantComposite %v2uint %uint_22 %uint_22 + %1996 = OpConstantComposite %v2uint %uint_9 %uint_9 + %536 = OpConstantComposite %v2uint %uint_513 %uint_513 + %515 = OpConstantComposite %v2uint %uint_512 %uint_512 + %2213 = OpConstantComposite %v2uint %uint_1023 %uint_1023 + %1933 = OpConstantComposite %v2uint %uint_6 %uint_6 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %883 = OpConstantComposite %v2uint %uint_2147418112 %uint_2147418112 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2604 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_8 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %19442 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %19442 = OpLabel + %8677 = OpIMul %int %23531 %int_4 + %17569 = OpBitcast %int %22409 + %8690 = OpIMul %int %6362 %17569 + %8334 = OpIAdd %int %8690 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %8677 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %19442 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %11682 None + OpBranchConditional %15139 %11064 %11682 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11682 + %11682 = OpLabel + %19948 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %21173 = OpVectorShuffle %v2uint %19948 %19948 0 1 + %12206 = OpBitwiseAnd %v2uint %21173 %2640 + %6898 = OpShiftRightLogical %v2uint %12206 %2017 + %12708 = OpINotEqual %v2bool %6898 %1807 + %20140 = OpIEqual %v2bool %12206 %2234 + %7655 = OpSelect %v2uint %20140 %2255 %12206 + %23050 = OpSelect %v2uint %12708 %2640 %1807 + %23672 = OpBitwiseXor %v2uint %7655 %23050 + %24500 = OpIAdd %v2uint %23672 %6898 + %8872 = OpShiftLeftLogical %v2uint %24500 %1912 + %13590 = OpShiftRightLogical %v2uint %24500 %1912 + %23618 = OpBitwiseOr %v2uint %8872 %13590 + %15463 = OpSelect %v2uint %12708 %2015 %1807 + %7774 = OpBitwiseXor %v2uint %23618 %15463 + %24941 = OpIAdd %v2uint %7774 %6898 + %24336 = OpShiftRightLogical %v2uint %21173 %2038 + %11822 = OpBitwiseAnd %v2uint %24336 %2640 + %6319 = OpShiftRightLogical %v2uint %11822 %2017 + %12709 = OpINotEqual %v2bool %6319 %1807 + %20141 = OpIEqual %v2bool %11822 %2234 + %7656 = OpSelect %v2uint %20141 %2255 %11822 + %23051 = OpSelect %v2uint %12709 %2640 %1807 + %23673 = OpBitwiseXor %v2uint %7656 %23051 + %24501 = OpIAdd %v2uint %23673 %6319 + %8873 = OpShiftLeftLogical %v2uint %24501 %1912 + %13591 = OpShiftRightLogical %v2uint %24501 %1912 + %23619 = OpBitwiseOr %v2uint %8873 %13591 + %15464 = OpSelect %v2uint %12709 %2015 %1807 + %7812 = OpBitwiseXor %v2uint %23619 %15464 + %24557 = OpIAdd %v2uint %7812 %6319 + %8296 = OpShiftLeftLogical %v2uint %24557 %2143 + %9076 = OpBitwiseOr %v2uint %24941 %8296 + %23541 = OpShiftRightLogical %v2uint %21173 %2269 + %13212 = OpShiftRightLogical %v2uint %23541 %1996 + %11904 = OpINotEqual %v2bool %13212 %1807 + %20142 = OpIEqual %v2bool %23541 %515 + %7657 = OpSelect %v2uint %20142 %536 %23541 + %23053 = OpSelect %v2uint %11904 %2213 %1807 + %23674 = OpBitwiseXor %v2uint %7657 %23053 + %24502 = OpIAdd %v2uint %23674 %13212 + %8874 = OpShiftLeftLogical %v2uint %24502 %1933 + %13592 = OpShiftRightLogical %v2uint %24502 %1870 + %23620 = OpBitwiseOr %v2uint %8874 %13592 + %15465 = OpSelect %v2uint %11904 %2015 %1807 + %7831 = OpBitwiseXor %v2uint %23620 %15465 + %22180 = OpIAdd %v2uint %7831 %13212 + %18024 = OpBitwiseOr %v2uint %22180 %883 + %10453 = OpCompositeExtract %uint %9076 0 + %23730 = OpCompositeExtract %uint %9076 1 + %7641 = OpCompositeExtract %uint %18024 0 + %7795 = OpCompositeExtract %uint %18024 1 + %16161 = OpCompositeConstruct %v4uint %10453 %23730 %7641 %7795 + %7813 = OpVectorShuffle %v4uint %16161 %16161 0 2 1 3 + %8699 = OpVectorShuffle %v2uint %19948 %19948 2 3 + %7167 = OpBitwiseAnd %v2uint %8699 %2640 + %6899 = OpShiftRightLogical %v2uint %7167 %2017 + %12710 = OpINotEqual %v2bool %6899 %1807 + %20143 = OpIEqual %v2bool %7167 %2234 + %7658 = OpSelect %v2uint %20143 %2255 %7167 + %23054 = OpSelect %v2uint %12710 %2640 %1807 + %23675 = OpBitwiseXor %v2uint %7658 %23054 + %24503 = OpIAdd %v2uint %23675 %6899 + %8875 = OpShiftLeftLogical %v2uint %24503 %1912 + %13593 = OpShiftRightLogical %v2uint %24503 %1912 + %23621 = OpBitwiseOr %v2uint %8875 %13593 + %15466 = OpSelect %v2uint %12710 %2015 %1807 + %7775 = OpBitwiseXor %v2uint %23621 %15466 + %24942 = OpIAdd %v2uint %7775 %6899 + %24337 = OpShiftRightLogical %v2uint %8699 %2038 + %11823 = OpBitwiseAnd %v2uint %24337 %2640 + %6320 = OpShiftRightLogical %v2uint %11823 %2017 + %12711 = OpINotEqual %v2bool %6320 %1807 + %20144 = OpIEqual %v2bool %11823 %2234 + %7659 = OpSelect %v2uint %20144 %2255 %11823 + %23055 = OpSelect %v2uint %12711 %2640 %1807 + %23676 = OpBitwiseXor %v2uint %7659 %23055 + %24504 = OpIAdd %v2uint %23676 %6320 + %8876 = OpShiftLeftLogical %v2uint %24504 %1912 + %13594 = OpShiftRightLogical %v2uint %24504 %1912 + %23622 = OpBitwiseOr %v2uint %8876 %13594 + %15467 = OpSelect %v2uint %12711 %2015 %1807 + %7814 = OpBitwiseXor %v2uint %23622 %15467 + %24559 = OpIAdd %v2uint %7814 %6320 + %8297 = OpShiftLeftLogical %v2uint %24559 %2143 + %9077 = OpBitwiseOr %v2uint %24942 %8297 + %23542 = OpShiftRightLogical %v2uint %8699 %2269 + %13213 = OpShiftRightLogical %v2uint %23542 %1996 + %11905 = OpINotEqual %v2bool %13213 %1807 + %20145 = OpIEqual %v2bool %23542 %515 + %7660 = OpSelect %v2uint %20145 %536 %23542 + %23056 = OpSelect %v2uint %11905 %2213 %1807 + %23677 = OpBitwiseXor %v2uint %7660 %23056 + %24505 = OpIAdd %v2uint %23677 %13213 + %8877 = OpShiftLeftLogical %v2uint %24505 %1933 + %13595 = OpShiftRightLogical %v2uint %24505 %1870 + %23623 = OpBitwiseOr %v2uint %8877 %13595 + %15468 = OpSelect %v2uint %11905 %2015 %1807 + %7832 = OpBitwiseXor %v2uint %23623 %15468 + %22181 = OpIAdd %v2uint %7832 %13213 + %18025 = OpBitwiseOr %v2uint %22181 %883 + %10454 = OpCompositeExtract %uint %9077 0 + %23731 = OpCompositeExtract %uint %9077 1 + %7642 = OpCompositeExtract %uint %18025 0 + %7796 = OpCompositeExtract %uint %18025 1 + %15895 = OpCompositeConstruct %v4uint %10454 %23731 %7642 %7796 + %7631 = OpVectorShuffle %v4uint %15895 %15895 0 2 1 3 + %12351 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %12351 %7813 + %11457 = OpIAdd %uint %21685 %uint_1 + %25136 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11457 + OpStore %25136 %7631 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_32 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %6871 %16377 %10584 + OpSelectionMerge %11683 None + OpBranchConditional %15139 %11065 %11683 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11683 + %11683 = OpLabel + %19949 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %21174 = OpVectorShuffle %v2uint %19949 %19949 0 1 + %12207 = OpBitwiseAnd %v2uint %21174 %2640 + %6900 = OpShiftRightLogical %v2uint %12207 %2017 + %12712 = OpINotEqual %v2bool %6900 %1807 + %20146 = OpIEqual %v2bool %12207 %2234 + %7661 = OpSelect %v2uint %20146 %2255 %12207 + %23057 = OpSelect %v2uint %12712 %2640 %1807 + %23678 = OpBitwiseXor %v2uint %7661 %23057 + %24506 = OpIAdd %v2uint %23678 %6900 + %8878 = OpShiftLeftLogical %v2uint %24506 %1912 + %13596 = OpShiftRightLogical %v2uint %24506 %1912 + %23624 = OpBitwiseOr %v2uint %8878 %13596 + %15469 = OpSelect %v2uint %12712 %2015 %1807 + %7776 = OpBitwiseXor %v2uint %23624 %15469 + %24943 = OpIAdd %v2uint %7776 %6900 + %24338 = OpShiftRightLogical %v2uint %21174 %2038 + %11824 = OpBitwiseAnd %v2uint %24338 %2640 + %6321 = OpShiftRightLogical %v2uint %11824 %2017 + %12713 = OpINotEqual %v2bool %6321 %1807 + %20147 = OpIEqual %v2bool %11824 %2234 + %7662 = OpSelect %v2uint %20147 %2255 %11824 + %23058 = OpSelect %v2uint %12713 %2640 %1807 + %23679 = OpBitwiseXor %v2uint %7662 %23058 + %24507 = OpIAdd %v2uint %23679 %6321 + %8879 = OpShiftLeftLogical %v2uint %24507 %1912 + %13597 = OpShiftRightLogical %v2uint %24507 %1912 + %23625 = OpBitwiseOr %v2uint %8879 %13597 + %15470 = OpSelect %v2uint %12713 %2015 %1807 + %7815 = OpBitwiseXor %v2uint %23625 %15470 + %24560 = OpIAdd %v2uint %7815 %6321 + %8298 = OpShiftLeftLogical %v2uint %24560 %2143 + %9078 = OpBitwiseOr %v2uint %24943 %8298 + %23543 = OpShiftRightLogical %v2uint %21174 %2269 + %13214 = OpShiftRightLogical %v2uint %23543 %1996 + %11906 = OpINotEqual %v2bool %13214 %1807 + %20148 = OpIEqual %v2bool %23543 %515 + %7663 = OpSelect %v2uint %20148 %536 %23543 + %23059 = OpSelect %v2uint %11906 %2213 %1807 + %23680 = OpBitwiseXor %v2uint %7663 %23059 + %24508 = OpIAdd %v2uint %23680 %13214 + %8880 = OpShiftLeftLogical %v2uint %24508 %1933 + %13598 = OpShiftRightLogical %v2uint %24508 %1870 + %23626 = OpBitwiseOr %v2uint %8880 %13598 + %15471 = OpSelect %v2uint %11906 %2015 %1807 + %7833 = OpBitwiseXor %v2uint %23626 %15471 + %22182 = OpIAdd %v2uint %7833 %13214 + %18026 = OpBitwiseOr %v2uint %22182 %883 + %10455 = OpCompositeExtract %uint %9078 0 + %23732 = OpCompositeExtract %uint %9078 1 + %7643 = OpCompositeExtract %uint %18026 0 + %7797 = OpCompositeExtract %uint %18026 1 + %16162 = OpCompositeConstruct %v4uint %10455 %23732 %7643 %7797 + %7816 = OpVectorShuffle %v4uint %16162 %16162 0 2 1 3 + %8700 = OpVectorShuffle %v2uint %19949 %19949 2 3 + %7168 = OpBitwiseAnd %v2uint %8700 %2640 + %6901 = OpShiftRightLogical %v2uint %7168 %2017 + %12714 = OpINotEqual %v2bool %6901 %1807 + %20149 = OpIEqual %v2bool %7168 %2234 + %7664 = OpSelect %v2uint %20149 %2255 %7168 + %23060 = OpSelect %v2uint %12714 %2640 %1807 + %23681 = OpBitwiseXor %v2uint %7664 %23060 + %24509 = OpIAdd %v2uint %23681 %6901 + %8881 = OpShiftLeftLogical %v2uint %24509 %1912 + %13599 = OpShiftRightLogical %v2uint %24509 %1912 + %23627 = OpBitwiseOr %v2uint %8881 %13599 + %15472 = OpSelect %v2uint %12714 %2015 %1807 + %7777 = OpBitwiseXor %v2uint %23627 %15472 + %24944 = OpIAdd %v2uint %7777 %6901 + %24339 = OpShiftRightLogical %v2uint %8700 %2038 + %11825 = OpBitwiseAnd %v2uint %24339 %2640 + %6322 = OpShiftRightLogical %v2uint %11825 %2017 + %12715 = OpINotEqual %v2bool %6322 %1807 + %20150 = OpIEqual %v2bool %11825 %2234 + %7665 = OpSelect %v2uint %20150 %2255 %11825 + %23061 = OpSelect %v2uint %12715 %2640 %1807 + %23682 = OpBitwiseXor %v2uint %7665 %23061 + %24510 = OpIAdd %v2uint %23682 %6322 + %8882 = OpShiftLeftLogical %v2uint %24510 %1912 + %13600 = OpShiftRightLogical %v2uint %24510 %1912 + %23628 = OpBitwiseOr %v2uint %8882 %13600 + %15473 = OpSelect %v2uint %12715 %2015 %1807 + %7817 = OpBitwiseXor %v2uint %23628 %15473 + %24561 = OpIAdd %v2uint %7817 %6322 + %8299 = OpShiftLeftLogical %v2uint %24561 %2143 + %9079 = OpBitwiseOr %v2uint %24944 %8299 + %23544 = OpShiftRightLogical %v2uint %8700 %2269 + %13215 = OpShiftRightLogical %v2uint %23544 %1996 + %11907 = OpINotEqual %v2bool %13215 %1807 + %20151 = OpIEqual %v2bool %23544 %515 + %7666 = OpSelect %v2uint %20151 %536 %23544 + %23062 = OpSelect %v2uint %11907 %2213 %1807 + %23683 = OpBitwiseXor %v2uint %7666 %23062 + %24511 = OpIAdd %v2uint %23683 %13215 + %8883 = OpShiftLeftLogical %v2uint %24511 %1933 + %13601 = OpShiftRightLogical %v2uint %24511 %1870 + %23629 = OpBitwiseOr %v2uint %8883 %13601 + %15474 = OpSelect %v2uint %11907 %2015 %1807 + %7834 = OpBitwiseXor %v2uint %23629 %15474 + %22183 = OpIAdd %v2uint %7834 %13215 + %18027 = OpBitwiseOr %v2uint %22183 %883 + %10456 = OpCompositeExtract %uint %9079 0 + %23733 = OpCompositeExtract %uint %9079 1 + %7644 = OpCompositeExtract %uint %18027 0 + %7798 = OpCompositeExtract %uint %18027 1 + %17092 = OpCompositeConstruct %v4uint %10456 %23733 %7644 %7798 + %15860 = OpVectorShuffle %v4uint %17092 %17092 0 2 1 3 + %21950 = OpIAdd %uint %21685 %uint_2 + %7829 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21950 + OpStore %7829 %7816 + %11458 = OpIAdd %uint %21685 %uint_3 + %25174 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11458 + OpStore %25174 %15860 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r11g11b10_rgba16_snorm_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006257, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x0000044A, 0x00000201, + 0x0004002B, 0x0000000B, 0x00000447, 0x00000200, 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, + 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x000001C1, 0x0000FFFF, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, + 0x0004002B, 0x0000000B, 0x00000A4A, 0x00000401, 0x0004002B, 0x0000000B, 0x00000A47, 0x00000400, + 0x0004002B, 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A2B, 0x0000000B, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, + 0x0004002B, 0x0000000B, 0x00000A4C, 0x00000016, 0x0004002B, 0x0000000B, 0x000003D6, 0x7FFF0000, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, + 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, + 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, + 0x00000009, 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, + 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, + 0x00000A2C, 0x00000A13, 0x00000A0A, 0x00000A0A, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, + 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, + 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, + 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, + 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, + 0x00000A6A, 0x00000A0D, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, + 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, + 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, + 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000011, + 0x00000A50, 0x00000A81, 0x00000A81, 0x0005002C, 0x00000011, 0x000007E1, 0x00000A28, 0x00000A28, + 0x0005002C, 0x00000011, 0x0000070F, 0x00000A0A, 0x00000A0A, 0x0005002C, 0x00000011, 0x000008CF, + 0x00000A4A, 0x00000A4A, 0x0005002C, 0x00000011, 0x000008BA, 0x00000A47, 0x00000A47, 0x0005002C, + 0x00000011, 0x00000778, 0x00000A19, 0x00000A19, 0x0005002C, 0x00000011, 0x000007DF, 0x000001C1, + 0x000001C1, 0x0005002C, 0x00000011, 0x000007F6, 0x00000A2B, 0x00000A2B, 0x0005002C, 0x00000011, + 0x0000085F, 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000011, 0x000008DD, 0x00000A4C, 0x00000A4C, + 0x0005002C, 0x00000011, 0x000007CC, 0x00000A25, 0x00000A25, 0x0005002C, 0x00000011, 0x00000218, + 0x0000044A, 0x0000044A, 0x0005002C, 0x00000011, 0x00000203, 0x00000447, 0x00000447, 0x0005002C, + 0x00000011, 0x000008A5, 0x00000A44, 0x00000A44, 0x0005002C, 0x00000011, 0x0000078D, 0x00000A1C, + 0x00000A1C, 0x0005002C, 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, 0x0005002C, 0x00000011, + 0x00000373, 0x000003D6, 0x000003D6, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, + 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, + 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, + 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, + 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, + 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, + 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, + 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, + 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, + 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, + 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, + 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, + 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, + 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, + 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A2C, + 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, + 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, + 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, + 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, + 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, + 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A23, 0x00050051, + 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, + 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, + 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, + 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, + 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, + 0x00002042, 0x00050080, 0x0000000B, 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, + 0x000054B5, 0x00002764, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, + 0x00005768, 0x00004BF2, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, + 0x00004384, 0x00002BF8, 0x000018D9, 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, 0x000032B3, + 0x000044BE, 0x00000A17, 0x000500C3, 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, 0x000500C2, + 0x0000000B, 0x00004947, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00004947, + 0x00050084, 0x0000000C, 0x00005321, 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, + 0x000032B3, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, + 0x0000000C, 0x00003901, 0x00002348, 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, 0x00003901, + 0x000500C3, 0x0000000C, 0x000032BA, 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, 0x00005FEE, + 0x000032BA, 0x000020F4, 0x000500C4, 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A22, 0x000500C7, + 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, + 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003138, 0x000044BE, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, + 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, + 0x0000434B, 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, + 0x0000000C, 0x00002215, 0x000044BE, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, + 0x0000601E, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, + 0x00004112, 0x00005BEB, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, + 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, + 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, + 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, + 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, + 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, + 0x000018DA, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, 0x00050080, + 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000044BE, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, + 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, + 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, + 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, + 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, + 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, + 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, + 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, 0x000019AD, + 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, + 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, 0x00000001, + 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, + 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, 0x0000000C, + 0x00005347, 0x0000405C, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, + 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002AB6, + 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, 0x000500C4, + 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, + 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, 0x0000000C, + 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, + 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, + 0x0000000C, 0x000047B5, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, + 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, + 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, + 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, + 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, + 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, + 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, + 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, + 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, + 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, + 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, + 0x0000000C, 0x0000292C, 0x000054ED, 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, 0x00005F43, + 0x000200F8, 0x00004BF2, 0x00050084, 0x0000000C, 0x000021E5, 0x00005BEB, 0x00000A17, 0x0004007C, + 0x0000000C, 0x000044A1, 0x00005789, 0x00050084, 0x0000000C, 0x000021F2, 0x000018DA, 0x000044A1, + 0x00050080, 0x0000000C, 0x0000208E, 0x000021F2, 0x000044BE, 0x0004007C, 0x0000000C, 0x000022F8, + 0x00005788, 0x00050084, 0x0000000C, 0x00001E9F, 0x0000208E, 0x000022F8, 0x00050080, 0x0000000C, + 0x00001F30, 0x000021E5, 0x00001E9F, 0x000200F9, 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, + 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, 0x00001F30, 0x00004BF2, 0x0004007C, 0x0000000C, + 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, + 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, + 0x00060041, 0x00000294, 0x00004315, 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, + 0x00001CAA, 0x00004315, 0x000500AA, 0x00000009, 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, + 0x00000009, 0x00005376, 0x000061E2, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, + 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, + 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, + 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, + 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, + 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, + 0x00000017, 0x00005879, 0x00001CAA, 0x00005F43, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, + 0x00004CB6, 0x000061E2, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, + 0x000300F7, 0x00002DA2, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x00002DA2, 0x000200F8, + 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, + 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, + 0x000200F9, 0x00002DA2, 0x000200F8, 0x00002DA2, 0x000700F5, 0x00000017, 0x00004DEC, 0x00005879, + 0x00003463, 0x000029E8, 0x00002B38, 0x0007004F, 0x00000011, 0x000052B5, 0x00004DEC, 0x00004DEC, + 0x00000000, 0x00000001, 0x000500C7, 0x00000011, 0x00002FAE, 0x000052B5, 0x00000A50, 0x000500C2, + 0x00000011, 0x00001AF2, 0x00002FAE, 0x000007E1, 0x000500AB, 0x0000000F, 0x000031A4, 0x00001AF2, + 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EAC, 0x00002FAE, 0x000008BA, 0x000600A9, 0x00000011, + 0x00001DE7, 0x00004EAC, 0x000008CF, 0x00002FAE, 0x000600A9, 0x00000011, 0x00005A0A, 0x000031A4, + 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C78, 0x00001DE7, 0x00005A0A, 0x00050080, + 0x00000011, 0x00005FB4, 0x00005C78, 0x00001AF2, 0x000500C4, 0x00000011, 0x000022A8, 0x00005FB4, + 0x00000778, 0x000500C2, 0x00000011, 0x00003516, 0x00005FB4, 0x00000778, 0x000500C5, 0x00000011, + 0x00005C42, 0x000022A8, 0x00003516, 0x000600A9, 0x00000011, 0x00003C67, 0x000031A4, 0x000007DF, + 0x0000070F, 0x000500C6, 0x00000011, 0x00001E5E, 0x00005C42, 0x00003C67, 0x00050080, 0x00000011, + 0x0000616D, 0x00001E5E, 0x00001AF2, 0x000500C2, 0x00000011, 0x00005F10, 0x000052B5, 0x000007F6, + 0x000500C7, 0x00000011, 0x00002E2E, 0x00005F10, 0x00000A50, 0x000500C2, 0x00000011, 0x000018AF, + 0x00002E2E, 0x000007E1, 0x000500AB, 0x0000000F, 0x000031A5, 0x000018AF, 0x0000070F, 0x000500AA, + 0x0000000F, 0x00004EAD, 0x00002E2E, 0x000008BA, 0x000600A9, 0x00000011, 0x00001DE8, 0x00004EAD, + 0x000008CF, 0x00002E2E, 0x000600A9, 0x00000011, 0x00005A0B, 0x000031A5, 0x00000A50, 0x0000070F, + 0x000500C6, 0x00000011, 0x00005C79, 0x00001DE8, 0x00005A0B, 0x00050080, 0x00000011, 0x00005FB5, + 0x00005C79, 0x000018AF, 0x000500C4, 0x00000011, 0x000022A9, 0x00005FB5, 0x00000778, 0x000500C2, + 0x00000011, 0x00003517, 0x00005FB5, 0x00000778, 0x000500C5, 0x00000011, 0x00005C43, 0x000022A9, + 0x00003517, 0x000600A9, 0x00000011, 0x00003C68, 0x000031A5, 0x000007DF, 0x0000070F, 0x000500C6, + 0x00000011, 0x00001E84, 0x00005C43, 0x00003C68, 0x00050080, 0x00000011, 0x00005FED, 0x00001E84, + 0x000018AF, 0x000500C4, 0x00000011, 0x00002068, 0x00005FED, 0x0000085F, 0x000500C5, 0x00000011, + 0x00002374, 0x0000616D, 0x00002068, 0x000500C2, 0x00000011, 0x00005BF5, 0x000052B5, 0x000008DD, + 0x000500C2, 0x00000011, 0x0000339C, 0x00005BF5, 0x000007CC, 0x000500AB, 0x0000000F, 0x00002E80, + 0x0000339C, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EAE, 0x00005BF5, 0x00000203, 0x000600A9, + 0x00000011, 0x00001DE9, 0x00004EAE, 0x00000218, 0x00005BF5, 0x000600A9, 0x00000011, 0x00005A0D, + 0x00002E80, 0x000008A5, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C7A, 0x00001DE9, 0x00005A0D, + 0x00050080, 0x00000011, 0x00005FB6, 0x00005C7A, 0x0000339C, 0x000500C4, 0x00000011, 0x000022AA, + 0x00005FB6, 0x0000078D, 0x000500C2, 0x00000011, 0x00003518, 0x00005FB6, 0x0000074E, 0x000500C5, + 0x00000011, 0x00005C44, 0x000022AA, 0x00003518, 0x000600A9, 0x00000011, 0x00003C69, 0x00002E80, + 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E97, 0x00005C44, 0x00003C69, 0x00050080, + 0x00000011, 0x000056A4, 0x00001E97, 0x0000339C, 0x000500C5, 0x00000011, 0x00004668, 0x000056A4, + 0x00000373, 0x00050051, 0x0000000B, 0x000028D5, 0x00002374, 0x00000000, 0x00050051, 0x0000000B, + 0x00005CB2, 0x00002374, 0x00000001, 0x00050051, 0x0000000B, 0x00001DD9, 0x00004668, 0x00000000, + 0x00050051, 0x0000000B, 0x00001E73, 0x00004668, 0x00000001, 0x00070050, 0x00000017, 0x00003F21, + 0x000028D5, 0x00005CB2, 0x00001DD9, 0x00001E73, 0x0009004F, 0x00000017, 0x00001E85, 0x00003F21, + 0x00003F21, 0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x0007004F, 0x00000011, 0x000021FB, + 0x00004DEC, 0x00004DEC, 0x00000002, 0x00000003, 0x000500C7, 0x00000011, 0x00001BFF, 0x000021FB, + 0x00000A50, 0x000500C2, 0x00000011, 0x00001AF3, 0x00001BFF, 0x000007E1, 0x000500AB, 0x0000000F, + 0x000031A6, 0x00001AF3, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EAF, 0x00001BFF, 0x000008BA, + 0x000600A9, 0x00000011, 0x00001DEA, 0x00004EAF, 0x000008CF, 0x00001BFF, 0x000600A9, 0x00000011, + 0x00005A0E, 0x000031A6, 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C7B, 0x00001DEA, + 0x00005A0E, 0x00050080, 0x00000011, 0x00005FB7, 0x00005C7B, 0x00001AF3, 0x000500C4, 0x00000011, + 0x000022AB, 0x00005FB7, 0x00000778, 0x000500C2, 0x00000011, 0x00003519, 0x00005FB7, 0x00000778, + 0x000500C5, 0x00000011, 0x00005C45, 0x000022AB, 0x00003519, 0x000600A9, 0x00000011, 0x00003C6A, + 0x000031A6, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E5F, 0x00005C45, 0x00003C6A, + 0x00050080, 0x00000011, 0x0000616E, 0x00001E5F, 0x00001AF3, 0x000500C2, 0x00000011, 0x00005F11, + 0x000021FB, 0x000007F6, 0x000500C7, 0x00000011, 0x00002E2F, 0x00005F11, 0x00000A50, 0x000500C2, + 0x00000011, 0x000018B0, 0x00002E2F, 0x000007E1, 0x000500AB, 0x0000000F, 0x000031A7, 0x000018B0, + 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB0, 0x00002E2F, 0x000008BA, 0x000600A9, 0x00000011, + 0x00001DEB, 0x00004EB0, 0x000008CF, 0x00002E2F, 0x000600A9, 0x00000011, 0x00005A0F, 0x000031A7, + 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C7C, 0x00001DEB, 0x00005A0F, 0x00050080, + 0x00000011, 0x00005FB8, 0x00005C7C, 0x000018B0, 0x000500C4, 0x00000011, 0x000022AC, 0x00005FB8, + 0x00000778, 0x000500C2, 0x00000011, 0x0000351A, 0x00005FB8, 0x00000778, 0x000500C5, 0x00000011, + 0x00005C46, 0x000022AC, 0x0000351A, 0x000600A9, 0x00000011, 0x00003C6B, 0x000031A7, 0x000007DF, + 0x0000070F, 0x000500C6, 0x00000011, 0x00001E86, 0x00005C46, 0x00003C6B, 0x00050080, 0x00000011, + 0x00005FEF, 0x00001E86, 0x000018B0, 0x000500C4, 0x00000011, 0x00002069, 0x00005FEF, 0x0000085F, + 0x000500C5, 0x00000011, 0x00002375, 0x0000616E, 0x00002069, 0x000500C2, 0x00000011, 0x00005BF6, + 0x000021FB, 0x000008DD, 0x000500C2, 0x00000011, 0x0000339D, 0x00005BF6, 0x000007CC, 0x000500AB, + 0x0000000F, 0x00002E81, 0x0000339D, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB1, 0x00005BF6, + 0x00000203, 0x000600A9, 0x00000011, 0x00001DEC, 0x00004EB1, 0x00000218, 0x00005BF6, 0x000600A9, + 0x00000011, 0x00005A10, 0x00002E81, 0x000008A5, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C7D, + 0x00001DEC, 0x00005A10, 0x00050080, 0x00000011, 0x00005FB9, 0x00005C7D, 0x0000339D, 0x000500C4, + 0x00000011, 0x000022AD, 0x00005FB9, 0x0000078D, 0x000500C2, 0x00000011, 0x0000351B, 0x00005FB9, + 0x0000074E, 0x000500C5, 0x00000011, 0x00005C47, 0x000022AD, 0x0000351B, 0x000600A9, 0x00000011, + 0x00003C6C, 0x00002E81, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E98, 0x00005C47, + 0x00003C6C, 0x00050080, 0x00000011, 0x000056A5, 0x00001E98, 0x0000339D, 0x000500C5, 0x00000011, + 0x00004669, 0x000056A5, 0x00000373, 0x00050051, 0x0000000B, 0x000028D6, 0x00002375, 0x00000000, + 0x00050051, 0x0000000B, 0x00005CB3, 0x00002375, 0x00000001, 0x00050051, 0x0000000B, 0x00001DDA, + 0x00004669, 0x00000000, 0x00050051, 0x0000000B, 0x00001E74, 0x00004669, 0x00000001, 0x00070050, + 0x00000017, 0x00003E17, 0x000028D6, 0x00005CB3, 0x00001DDA, 0x00001E74, 0x0009004F, 0x00000017, + 0x00001DCF, 0x00003E17, 0x00003E17, 0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x00060041, + 0x00000294, 0x0000303F, 0x0000140E, 0x00000A0B, 0x000054B5, 0x0003003E, 0x0000303F, 0x00001E85, + 0x00050080, 0x0000000B, 0x00002CC1, 0x000054B5, 0x00000A0D, 0x00060041, 0x00000294, 0x00006230, + 0x0000140E, 0x00000A0B, 0x00002CC1, 0x0003003E, 0x00006230, 0x00001DCF, 0x000300F7, 0x00001AD7, + 0x00000002, 0x000400FA, 0x00004376, 0x000055E9, 0x00001C25, 0x000200F8, 0x000055E9, 0x000200F9, + 0x00001AD7, 0x000200F8, 0x00001C25, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001AD7, 0x000700F5, + 0x0000000B, 0x0000456F, 0x00000A6A, 0x000055E9, 0x00000A3A, 0x00001C25, 0x000500C2, 0x0000000B, + 0x000041C0, 0x0000456F, 0x00000A16, 0x00050080, 0x0000000B, 0x00002ADB, 0x00005665, 0x000041C0, + 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, 0x00002ADB, 0x0004003D, 0x00000017, + 0x000019B2, 0x0000571A, 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, + 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, + 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, + 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, + 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, + 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x00001AD7, 0x00003FF9, 0x00002958, 0x000300F7, + 0x00002DA3, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, 0x00002DA3, 0x000200F8, 0x00002B39, + 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, + 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, + 0x00002DA3, 0x000200F8, 0x00002DA3, 0x000700F5, 0x00000017, 0x00004DED, 0x00002AAC, 0x00003A1A, + 0x000029E9, 0x00002B39, 0x0007004F, 0x00000011, 0x000052B6, 0x00004DED, 0x00004DED, 0x00000000, + 0x00000001, 0x000500C7, 0x00000011, 0x00002FAF, 0x000052B6, 0x00000A50, 0x000500C2, 0x00000011, + 0x00001AF4, 0x00002FAF, 0x000007E1, 0x000500AB, 0x0000000F, 0x000031A8, 0x00001AF4, 0x0000070F, + 0x000500AA, 0x0000000F, 0x00004EB2, 0x00002FAF, 0x000008BA, 0x000600A9, 0x00000011, 0x00001DED, + 0x00004EB2, 0x000008CF, 0x00002FAF, 0x000600A9, 0x00000011, 0x00005A11, 0x000031A8, 0x00000A50, + 0x0000070F, 0x000500C6, 0x00000011, 0x00005C7E, 0x00001DED, 0x00005A11, 0x00050080, 0x00000011, + 0x00005FBA, 0x00005C7E, 0x00001AF4, 0x000500C4, 0x00000011, 0x000022AE, 0x00005FBA, 0x00000778, + 0x000500C2, 0x00000011, 0x0000351C, 0x00005FBA, 0x00000778, 0x000500C5, 0x00000011, 0x00005C48, + 0x000022AE, 0x0000351C, 0x000600A9, 0x00000011, 0x00003C6D, 0x000031A8, 0x000007DF, 0x0000070F, + 0x000500C6, 0x00000011, 0x00001E60, 0x00005C48, 0x00003C6D, 0x00050080, 0x00000011, 0x0000616F, + 0x00001E60, 0x00001AF4, 0x000500C2, 0x00000011, 0x00005F12, 0x000052B6, 0x000007F6, 0x000500C7, + 0x00000011, 0x00002E30, 0x00005F12, 0x00000A50, 0x000500C2, 0x00000011, 0x000018B1, 0x00002E30, + 0x000007E1, 0x000500AB, 0x0000000F, 0x000031A9, 0x000018B1, 0x0000070F, 0x000500AA, 0x0000000F, + 0x00004EB3, 0x00002E30, 0x000008BA, 0x000600A9, 0x00000011, 0x00001DEE, 0x00004EB3, 0x000008CF, + 0x00002E30, 0x000600A9, 0x00000011, 0x00005A12, 0x000031A9, 0x00000A50, 0x0000070F, 0x000500C6, + 0x00000011, 0x00005C7F, 0x00001DEE, 0x00005A12, 0x00050080, 0x00000011, 0x00005FBB, 0x00005C7F, + 0x000018B1, 0x000500C4, 0x00000011, 0x000022AF, 0x00005FBB, 0x00000778, 0x000500C2, 0x00000011, + 0x0000351D, 0x00005FBB, 0x00000778, 0x000500C5, 0x00000011, 0x00005C49, 0x000022AF, 0x0000351D, + 0x000600A9, 0x00000011, 0x00003C6E, 0x000031A9, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, + 0x00001E87, 0x00005C49, 0x00003C6E, 0x00050080, 0x00000011, 0x00005FF0, 0x00001E87, 0x000018B1, + 0x000500C4, 0x00000011, 0x0000206A, 0x00005FF0, 0x0000085F, 0x000500C5, 0x00000011, 0x00002376, + 0x0000616F, 0x0000206A, 0x000500C2, 0x00000011, 0x00005BF7, 0x000052B6, 0x000008DD, 0x000500C2, + 0x00000011, 0x0000339E, 0x00005BF7, 0x000007CC, 0x000500AB, 0x0000000F, 0x00002E82, 0x0000339E, + 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB4, 0x00005BF7, 0x00000203, 0x000600A9, 0x00000011, + 0x00001DEF, 0x00004EB4, 0x00000218, 0x00005BF7, 0x000600A9, 0x00000011, 0x00005A13, 0x00002E82, + 0x000008A5, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C80, 0x00001DEF, 0x00005A13, 0x00050080, + 0x00000011, 0x00005FBC, 0x00005C80, 0x0000339E, 0x000500C4, 0x00000011, 0x000022B0, 0x00005FBC, + 0x0000078D, 0x000500C2, 0x00000011, 0x0000351E, 0x00005FBC, 0x0000074E, 0x000500C5, 0x00000011, + 0x00005C4A, 0x000022B0, 0x0000351E, 0x000600A9, 0x00000011, 0x00003C6F, 0x00002E82, 0x000007DF, + 0x0000070F, 0x000500C6, 0x00000011, 0x00001E99, 0x00005C4A, 0x00003C6F, 0x00050080, 0x00000011, + 0x000056A6, 0x00001E99, 0x0000339E, 0x000500C5, 0x00000011, 0x0000466A, 0x000056A6, 0x00000373, + 0x00050051, 0x0000000B, 0x000028D7, 0x00002376, 0x00000000, 0x00050051, 0x0000000B, 0x00005CB4, + 0x00002376, 0x00000001, 0x00050051, 0x0000000B, 0x00001DDB, 0x0000466A, 0x00000000, 0x00050051, + 0x0000000B, 0x00001E75, 0x0000466A, 0x00000001, 0x00070050, 0x00000017, 0x00003F22, 0x000028D7, + 0x00005CB4, 0x00001DDB, 0x00001E75, 0x0009004F, 0x00000017, 0x00001E88, 0x00003F22, 0x00003F22, + 0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x0007004F, 0x00000011, 0x000021FC, 0x00004DED, + 0x00004DED, 0x00000002, 0x00000003, 0x000500C7, 0x00000011, 0x00001C00, 0x000021FC, 0x00000A50, + 0x000500C2, 0x00000011, 0x00001AF5, 0x00001C00, 0x000007E1, 0x000500AB, 0x0000000F, 0x000031AA, + 0x00001AF5, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB5, 0x00001C00, 0x000008BA, 0x000600A9, + 0x00000011, 0x00001DF0, 0x00004EB5, 0x000008CF, 0x00001C00, 0x000600A9, 0x00000011, 0x00005A14, + 0x000031AA, 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C81, 0x00001DF0, 0x00005A14, + 0x00050080, 0x00000011, 0x00005FBD, 0x00005C81, 0x00001AF5, 0x000500C4, 0x00000011, 0x000022B1, + 0x00005FBD, 0x00000778, 0x000500C2, 0x00000011, 0x0000351F, 0x00005FBD, 0x00000778, 0x000500C5, + 0x00000011, 0x00005C4B, 0x000022B1, 0x0000351F, 0x000600A9, 0x00000011, 0x00003C70, 0x000031AA, + 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E61, 0x00005C4B, 0x00003C70, 0x00050080, + 0x00000011, 0x00006170, 0x00001E61, 0x00001AF5, 0x000500C2, 0x00000011, 0x00005F13, 0x000021FC, + 0x000007F6, 0x000500C7, 0x00000011, 0x00002E31, 0x00005F13, 0x00000A50, 0x000500C2, 0x00000011, + 0x000018B2, 0x00002E31, 0x000007E1, 0x000500AB, 0x0000000F, 0x000031AB, 0x000018B2, 0x0000070F, + 0x000500AA, 0x0000000F, 0x00004EB6, 0x00002E31, 0x000008BA, 0x000600A9, 0x00000011, 0x00001DF1, + 0x00004EB6, 0x000008CF, 0x00002E31, 0x000600A9, 0x00000011, 0x00005A15, 0x000031AB, 0x00000A50, + 0x0000070F, 0x000500C6, 0x00000011, 0x00005C82, 0x00001DF1, 0x00005A15, 0x00050080, 0x00000011, + 0x00005FBE, 0x00005C82, 0x000018B2, 0x000500C4, 0x00000011, 0x000022B2, 0x00005FBE, 0x00000778, + 0x000500C2, 0x00000011, 0x00003520, 0x00005FBE, 0x00000778, 0x000500C5, 0x00000011, 0x00005C4C, + 0x000022B2, 0x00003520, 0x000600A9, 0x00000011, 0x00003C71, 0x000031AB, 0x000007DF, 0x0000070F, + 0x000500C6, 0x00000011, 0x00001E89, 0x00005C4C, 0x00003C71, 0x00050080, 0x00000011, 0x00005FF1, + 0x00001E89, 0x000018B2, 0x000500C4, 0x00000011, 0x0000206B, 0x00005FF1, 0x0000085F, 0x000500C5, + 0x00000011, 0x00002377, 0x00006170, 0x0000206B, 0x000500C2, 0x00000011, 0x00005BF8, 0x000021FC, + 0x000008DD, 0x000500C2, 0x00000011, 0x0000339F, 0x00005BF8, 0x000007CC, 0x000500AB, 0x0000000F, + 0x00002E83, 0x0000339F, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB7, 0x00005BF8, 0x00000203, + 0x000600A9, 0x00000011, 0x00001DF2, 0x00004EB7, 0x00000218, 0x00005BF8, 0x000600A9, 0x00000011, + 0x00005A16, 0x00002E83, 0x000008A5, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C83, 0x00001DF2, + 0x00005A16, 0x00050080, 0x00000011, 0x00005FBF, 0x00005C83, 0x0000339F, 0x000500C4, 0x00000011, + 0x000022B3, 0x00005FBF, 0x0000078D, 0x000500C2, 0x00000011, 0x00003521, 0x00005FBF, 0x0000074E, + 0x000500C5, 0x00000011, 0x00005C4D, 0x000022B3, 0x00003521, 0x000600A9, 0x00000011, 0x00003C72, + 0x00002E83, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E9A, 0x00005C4D, 0x00003C72, + 0x00050080, 0x00000011, 0x000056A7, 0x00001E9A, 0x0000339F, 0x000500C5, 0x00000011, 0x0000466B, + 0x000056A7, 0x00000373, 0x00050051, 0x0000000B, 0x000028D8, 0x00002377, 0x00000000, 0x00050051, + 0x0000000B, 0x00005CB5, 0x00002377, 0x00000001, 0x00050051, 0x0000000B, 0x00001DDC, 0x0000466B, + 0x00000000, 0x00050051, 0x0000000B, 0x00001E76, 0x0000466B, 0x00000001, 0x00070050, 0x00000017, + 0x000042C4, 0x000028D8, 0x00005CB5, 0x00001DDC, 0x00001E76, 0x0009004F, 0x00000017, 0x00003DF4, + 0x000042C4, 0x000042C4, 0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x00050080, 0x0000000B, + 0x000055BE, 0x000054B5, 0x00000A10, 0x00060041, 0x00000294, 0x00001E95, 0x0000140E, 0x00000A0B, + 0x000055BE, 0x0003003E, 0x00001E95, 0x00001E88, 0x00050080, 0x0000000B, 0x00002CC2, 0x000054B5, + 0x00000A13, 0x00060041, 0x00000294, 0x00006256, 0x0000140E, 0x00000A0B, 0x00002CC2, 0x0003003E, + 0x00006256, 0x00003DF4, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r11g11b10_rgba16_snorm_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r11g11b10_rgba16_snorm_scaled_cs.h new file mode 100644 index 0000000..5542d58 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r11g11b10_rgba16_snorm_scaled_cs.h @@ -0,0 +1,995 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25175 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %uint_9 = OpConstant %uint 9 + %v2bool = OpTypeVector %bool 2 + %uint_0 = OpConstant %uint 0 + %uint_513 = OpConstant %uint 513 + %uint_512 = OpConstant %uint 512 + %uint_1023 = OpConstant %uint 1023 + %uint_6 = OpConstant %uint 6 + %uint_3 = OpConstant %uint 3 + %uint_65535 = OpConstant %uint 65535 + %uint_10 = OpConstant %uint 10 + %uint_1025 = OpConstant %uint 1025 + %uint_1024 = OpConstant %uint 1024 + %uint_2047 = OpConstant %uint 2047 + %uint_5 = OpConstant %uint 5 + %uint_11 = OpConstant %uint 11 + %uint_16 = OpConstant %uint 16 + %uint_22 = OpConstant %uint 22 +%uint_2147418112 = OpConstant %uint 2147418112 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2604 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %2640 = OpConstantComposite %v2uint %uint_2047 %uint_2047 + %2017 = OpConstantComposite %v2uint %uint_10 %uint_10 + %1807 = OpConstantComposite %v2uint %uint_0 %uint_0 + %2255 = OpConstantComposite %v2uint %uint_1025 %uint_1025 + %2234 = OpConstantComposite %v2uint %uint_1024 %uint_1024 + %1912 = OpConstantComposite %v2uint %uint_5 %uint_5 + %2015 = OpConstantComposite %v2uint %uint_65535 %uint_65535 + %2038 = OpConstantComposite %v2uint %uint_11 %uint_11 + %2143 = OpConstantComposite %v2uint %uint_16 %uint_16 + %2269 = OpConstantComposite %v2uint %uint_22 %uint_22 + %1996 = OpConstantComposite %v2uint %uint_9 %uint_9 + %536 = OpConstantComposite %v2uint %uint_513 %uint_513 + %515 = OpConstantComposite %v2uint %uint_512 %uint_512 + %2213 = OpConstantComposite %v2uint %uint_1023 %uint_1023 + %1933 = OpConstantComposite %v2uint %uint_6 %uint_6 + %1870 = OpConstantComposite %v2uint %uint_3 %uint_3 + %883 = OpConstantComposite %v2uint %uint_2147418112 %uint_2147418112 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2604 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_8 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_2 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_2 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_2 + %23219 = OpBitwiseAnd %uint %10722 %uint_3 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_2 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %7338 = OpLoad %v4uint %20399 + %13760 = OpIEqual %bool %24990 %uint_1 + %21366 = OpIEqual %bool %24990 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %21313 %16376 %10583 + %19638 = OpIEqual %bool %24990 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %11682 None + OpBranchConditional %15139 %11064 %11682 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %11682 + %11682 = OpLabel + %19948 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %21173 = OpVectorShuffle %v2uint %19948 %19948 0 1 + %12206 = OpBitwiseAnd %v2uint %21173 %2640 + %6898 = OpShiftRightLogical %v2uint %12206 %2017 + %12708 = OpINotEqual %v2bool %6898 %1807 + %20140 = OpIEqual %v2bool %12206 %2234 + %7655 = OpSelect %v2uint %20140 %2255 %12206 + %23050 = OpSelect %v2uint %12708 %2640 %1807 + %23672 = OpBitwiseXor %v2uint %7655 %23050 + %24500 = OpIAdd %v2uint %23672 %6898 + %8872 = OpShiftLeftLogical %v2uint %24500 %1912 + %13590 = OpShiftRightLogical %v2uint %24500 %1912 + %23618 = OpBitwiseOr %v2uint %8872 %13590 + %15463 = OpSelect %v2uint %12708 %2015 %1807 + %7774 = OpBitwiseXor %v2uint %23618 %15463 + %24941 = OpIAdd %v2uint %7774 %6898 + %24336 = OpShiftRightLogical %v2uint %21173 %2038 + %11822 = OpBitwiseAnd %v2uint %24336 %2640 + %6319 = OpShiftRightLogical %v2uint %11822 %2017 + %12709 = OpINotEqual %v2bool %6319 %1807 + %20141 = OpIEqual %v2bool %11822 %2234 + %7656 = OpSelect %v2uint %20141 %2255 %11822 + %23051 = OpSelect %v2uint %12709 %2640 %1807 + %23673 = OpBitwiseXor %v2uint %7656 %23051 + %24501 = OpIAdd %v2uint %23673 %6319 + %8873 = OpShiftLeftLogical %v2uint %24501 %1912 + %13591 = OpShiftRightLogical %v2uint %24501 %1912 + %23619 = OpBitwiseOr %v2uint %8873 %13591 + %15464 = OpSelect %v2uint %12709 %2015 %1807 + %7812 = OpBitwiseXor %v2uint %23619 %15464 + %24557 = OpIAdd %v2uint %7812 %6319 + %8296 = OpShiftLeftLogical %v2uint %24557 %2143 + %9076 = OpBitwiseOr %v2uint %24941 %8296 + %23541 = OpShiftRightLogical %v2uint %21173 %2269 + %13212 = OpShiftRightLogical %v2uint %23541 %1996 + %11904 = OpINotEqual %v2bool %13212 %1807 + %20142 = OpIEqual %v2bool %23541 %515 + %7657 = OpSelect %v2uint %20142 %536 %23541 + %23053 = OpSelect %v2uint %11904 %2213 %1807 + %23674 = OpBitwiseXor %v2uint %7657 %23053 + %24502 = OpIAdd %v2uint %23674 %13212 + %8874 = OpShiftLeftLogical %v2uint %24502 %1933 + %13592 = OpShiftRightLogical %v2uint %24502 %1870 + %23620 = OpBitwiseOr %v2uint %8874 %13592 + %15465 = OpSelect %v2uint %11904 %2015 %1807 + %7831 = OpBitwiseXor %v2uint %23620 %15465 + %22180 = OpIAdd %v2uint %7831 %13212 + %18024 = OpBitwiseOr %v2uint %22180 %883 + %10453 = OpCompositeExtract %uint %9076 0 + %23730 = OpCompositeExtract %uint %9076 1 + %7641 = OpCompositeExtract %uint %18024 0 + %7795 = OpCompositeExtract %uint %18024 1 + %16161 = OpCompositeConstruct %v4uint %10453 %23730 %7641 %7795 + %7813 = OpVectorShuffle %v4uint %16161 %16161 0 2 1 3 + %8699 = OpVectorShuffle %v2uint %19948 %19948 2 3 + %7167 = OpBitwiseAnd %v2uint %8699 %2640 + %6899 = OpShiftRightLogical %v2uint %7167 %2017 + %12710 = OpINotEqual %v2bool %6899 %1807 + %20143 = OpIEqual %v2bool %7167 %2234 + %7658 = OpSelect %v2uint %20143 %2255 %7167 + %23054 = OpSelect %v2uint %12710 %2640 %1807 + %23675 = OpBitwiseXor %v2uint %7658 %23054 + %24503 = OpIAdd %v2uint %23675 %6899 + %8875 = OpShiftLeftLogical %v2uint %24503 %1912 + %13593 = OpShiftRightLogical %v2uint %24503 %1912 + %23621 = OpBitwiseOr %v2uint %8875 %13593 + %15466 = OpSelect %v2uint %12710 %2015 %1807 + %7775 = OpBitwiseXor %v2uint %23621 %15466 + %24942 = OpIAdd %v2uint %7775 %6899 + %24337 = OpShiftRightLogical %v2uint %8699 %2038 + %11823 = OpBitwiseAnd %v2uint %24337 %2640 + %6320 = OpShiftRightLogical %v2uint %11823 %2017 + %12711 = OpINotEqual %v2bool %6320 %1807 + %20144 = OpIEqual %v2bool %11823 %2234 + %7659 = OpSelect %v2uint %20144 %2255 %11823 + %23055 = OpSelect %v2uint %12711 %2640 %1807 + %23676 = OpBitwiseXor %v2uint %7659 %23055 + %24504 = OpIAdd %v2uint %23676 %6320 + %8876 = OpShiftLeftLogical %v2uint %24504 %1912 + %13594 = OpShiftRightLogical %v2uint %24504 %1912 + %23622 = OpBitwiseOr %v2uint %8876 %13594 + %15467 = OpSelect %v2uint %12711 %2015 %1807 + %7814 = OpBitwiseXor %v2uint %23622 %15467 + %24558 = OpIAdd %v2uint %7814 %6320 + %8297 = OpShiftLeftLogical %v2uint %24558 %2143 + %9077 = OpBitwiseOr %v2uint %24942 %8297 + %23542 = OpShiftRightLogical %v2uint %8699 %2269 + %13213 = OpShiftRightLogical %v2uint %23542 %1996 + %11905 = OpINotEqual %v2bool %13213 %1807 + %20145 = OpIEqual %v2bool %23542 %515 + %7660 = OpSelect %v2uint %20145 %536 %23542 + %23056 = OpSelect %v2uint %11905 %2213 %1807 + %23677 = OpBitwiseXor %v2uint %7660 %23056 + %24505 = OpIAdd %v2uint %23677 %13213 + %8877 = OpShiftLeftLogical %v2uint %24505 %1933 + %13595 = OpShiftRightLogical %v2uint %24505 %1870 + %23623 = OpBitwiseOr %v2uint %8877 %13595 + %15468 = OpSelect %v2uint %11905 %2015 %1807 + %7832 = OpBitwiseXor %v2uint %23623 %15468 + %22181 = OpIAdd %v2uint %7832 %13213 + %18025 = OpBitwiseOr %v2uint %22181 %883 + %10454 = OpCompositeExtract %uint %9077 0 + %23731 = OpCompositeExtract %uint %9077 1 + %7642 = OpCompositeExtract %uint %18025 0 + %7796 = OpCompositeExtract %uint %18025 1 + %15895 = OpCompositeConstruct %v4uint %10454 %23731 %7642 %7796 + %7631 = OpVectorShuffle %v4uint %15895 %15895 0 2 1 3 + %12351 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %12351 %7813 + %11457 = OpIAdd %uint %11197 %uint_1 + %23711 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11457 + OpStore %23711 %7631 + %23543 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %23543 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_32 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_32 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %24764 %16377 %10584 + OpSelectionMerge %11683 None + OpBranchConditional %15139 %11065 %11683 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %11683 + %11683 = OpLabel + %19949 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %21174 = OpVectorShuffle %v2uint %19949 %19949 0 1 + %12207 = OpBitwiseAnd %v2uint %21174 %2640 + %6900 = OpShiftRightLogical %v2uint %12207 %2017 + %12712 = OpINotEqual %v2bool %6900 %1807 + %20146 = OpIEqual %v2bool %12207 %2234 + %7661 = OpSelect %v2uint %20146 %2255 %12207 + %23057 = OpSelect %v2uint %12712 %2640 %1807 + %23678 = OpBitwiseXor %v2uint %7661 %23057 + %24506 = OpIAdd %v2uint %23678 %6900 + %8878 = OpShiftLeftLogical %v2uint %24506 %1912 + %13596 = OpShiftRightLogical %v2uint %24506 %1912 + %23624 = OpBitwiseOr %v2uint %8878 %13596 + %15469 = OpSelect %v2uint %12712 %2015 %1807 + %7776 = OpBitwiseXor %v2uint %23624 %15469 + %24943 = OpIAdd %v2uint %7776 %6900 + %24338 = OpShiftRightLogical %v2uint %21174 %2038 + %11824 = OpBitwiseAnd %v2uint %24338 %2640 + %6321 = OpShiftRightLogical %v2uint %11824 %2017 + %12713 = OpINotEqual %v2bool %6321 %1807 + %20147 = OpIEqual %v2bool %11824 %2234 + %7663 = OpSelect %v2uint %20147 %2255 %11824 + %23058 = OpSelect %v2uint %12713 %2640 %1807 + %23679 = OpBitwiseXor %v2uint %7663 %23058 + %24507 = OpIAdd %v2uint %23679 %6321 + %8879 = OpShiftLeftLogical %v2uint %24507 %1912 + %13597 = OpShiftRightLogical %v2uint %24507 %1912 + %23625 = OpBitwiseOr %v2uint %8879 %13597 + %15470 = OpSelect %v2uint %12713 %2015 %1807 + %7815 = OpBitwiseXor %v2uint %23625 %15470 + %24559 = OpIAdd %v2uint %7815 %6321 + %8298 = OpShiftLeftLogical %v2uint %24559 %2143 + %9078 = OpBitwiseOr %v2uint %24943 %8298 + %23544 = OpShiftRightLogical %v2uint %21174 %2269 + %13214 = OpShiftRightLogical %v2uint %23544 %1996 + %11906 = OpINotEqual %v2bool %13214 %1807 + %20148 = OpIEqual %v2bool %23544 %515 + %7664 = OpSelect %v2uint %20148 %536 %23544 + %23059 = OpSelect %v2uint %11906 %2213 %1807 + %23680 = OpBitwiseXor %v2uint %7664 %23059 + %24508 = OpIAdd %v2uint %23680 %13214 + %8880 = OpShiftLeftLogical %v2uint %24508 %1933 + %13598 = OpShiftRightLogical %v2uint %24508 %1870 + %23626 = OpBitwiseOr %v2uint %8880 %13598 + %15471 = OpSelect %v2uint %11906 %2015 %1807 + %7833 = OpBitwiseXor %v2uint %23626 %15471 + %22182 = OpIAdd %v2uint %7833 %13214 + %18026 = OpBitwiseOr %v2uint %22182 %883 + %10455 = OpCompositeExtract %uint %9078 0 + %23732 = OpCompositeExtract %uint %9078 1 + %7643 = OpCompositeExtract %uint %18026 0 + %7797 = OpCompositeExtract %uint %18026 1 + %16162 = OpCompositeConstruct %v4uint %10455 %23732 %7643 %7797 + %7816 = OpVectorShuffle %v4uint %16162 %16162 0 2 1 3 + %8700 = OpVectorShuffle %v2uint %19949 %19949 2 3 + %7168 = OpBitwiseAnd %v2uint %8700 %2640 + %6901 = OpShiftRightLogical %v2uint %7168 %2017 + %12714 = OpINotEqual %v2bool %6901 %1807 + %20149 = OpIEqual %v2bool %7168 %2234 + %7665 = OpSelect %v2uint %20149 %2255 %7168 + %23060 = OpSelect %v2uint %12714 %2640 %1807 + %23681 = OpBitwiseXor %v2uint %7665 %23060 + %24509 = OpIAdd %v2uint %23681 %6901 + %8881 = OpShiftLeftLogical %v2uint %24509 %1912 + %13599 = OpShiftRightLogical %v2uint %24509 %1912 + %23627 = OpBitwiseOr %v2uint %8881 %13599 + %15472 = OpSelect %v2uint %12714 %2015 %1807 + %7777 = OpBitwiseXor %v2uint %23627 %15472 + %24944 = OpIAdd %v2uint %7777 %6901 + %24339 = OpShiftRightLogical %v2uint %8700 %2038 + %11825 = OpBitwiseAnd %v2uint %24339 %2640 + %6322 = OpShiftRightLogical %v2uint %11825 %2017 + %12715 = OpINotEqual %v2bool %6322 %1807 + %20150 = OpIEqual %v2bool %11825 %2234 + %7666 = OpSelect %v2uint %20150 %2255 %11825 + %23061 = OpSelect %v2uint %12715 %2640 %1807 + %23682 = OpBitwiseXor %v2uint %7666 %23061 + %24510 = OpIAdd %v2uint %23682 %6322 + %8882 = OpShiftLeftLogical %v2uint %24510 %1912 + %13600 = OpShiftRightLogical %v2uint %24510 %1912 + %23628 = OpBitwiseOr %v2uint %8882 %13600 + %15473 = OpSelect %v2uint %12715 %2015 %1807 + %7817 = OpBitwiseXor %v2uint %23628 %15473 + %24560 = OpIAdd %v2uint %7817 %6322 + %8299 = OpShiftLeftLogical %v2uint %24560 %2143 + %9079 = OpBitwiseOr %v2uint %24944 %8299 + %23545 = OpShiftRightLogical %v2uint %8700 %2269 + %13215 = OpShiftRightLogical %v2uint %23545 %1996 + %11907 = OpINotEqual %v2bool %13215 %1807 + %20151 = OpIEqual %v2bool %23545 %515 + %7667 = OpSelect %v2uint %20151 %536 %23545 + %23062 = OpSelect %v2uint %11907 %2213 %1807 + %23683 = OpBitwiseXor %v2uint %7667 %23062 + %24511 = OpIAdd %v2uint %23683 %13215 + %8883 = OpShiftLeftLogical %v2uint %24511 %1933 + %13601 = OpShiftRightLogical %v2uint %24511 %1870 + %23629 = OpBitwiseOr %v2uint %8883 %13601 + %15474 = OpSelect %v2uint %11907 %2015 %1807 + %7834 = OpBitwiseXor %v2uint %23629 %15474 + %22183 = OpIAdd %v2uint %7834 %13215 + %18027 = OpBitwiseOr %v2uint %22183 %883 + %10456 = OpCompositeExtract %uint %9079 0 + %23733 = OpCompositeExtract %uint %9079 1 + %7644 = OpCompositeExtract %uint %18027 0 + %7798 = OpCompositeExtract %uint %18027 1 + %17092 = OpCompositeConstruct %v4uint %10456 %23733 %7644 %7798 + %15860 = OpVectorShuffle %v4uint %17092 %17092 0 2 1 3 + %21950 = OpIAdd %uint %11197 %uint_2 + %7829 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21950 + OpStore %7829 %7816 + %11458 = OpIAdd %uint %11197 %uint_3 + %25174 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11458 + OpStore %25174 %15860 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r11g11b10_rgba16_snorm_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006257, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000B, 0x0000044A, 0x00000201, + 0x0004002B, 0x0000000B, 0x00000447, 0x00000200, 0x0004002B, 0x0000000B, 0x00000A44, 0x000003FF, + 0x0004002B, 0x0000000B, 0x00000A1C, 0x00000006, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x000001C1, 0x0000FFFF, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, + 0x0004002B, 0x0000000B, 0x00000A4A, 0x00000401, 0x0004002B, 0x0000000B, 0x00000A47, 0x00000400, + 0x0004002B, 0x0000000B, 0x00000A81, 0x000007FF, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A2B, 0x0000000B, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, + 0x0004002B, 0x0000000B, 0x00000A4C, 0x00000016, 0x0004002B, 0x0000000B, 0x000003D6, 0x7FFF0000, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, + 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, + 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, + 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, + 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, + 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, + 0x00000787, 0x00000A16, 0x00000A1F, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, + 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, + 0x00000014, 0x00000A2C, 0x00000A13, 0x00000A0A, 0x00000A0A, 0x0003001D, 0x000007DC, 0x00000017, + 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, + 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, + 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, + 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, + 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, + 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, + 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, + 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, + 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0005002C, 0x00000011, 0x00000A50, 0x00000A81, + 0x00000A81, 0x0005002C, 0x00000011, 0x000007E1, 0x00000A28, 0x00000A28, 0x0005002C, 0x00000011, + 0x0000070F, 0x00000A0A, 0x00000A0A, 0x0005002C, 0x00000011, 0x000008CF, 0x00000A4A, 0x00000A4A, + 0x0005002C, 0x00000011, 0x000008BA, 0x00000A47, 0x00000A47, 0x0005002C, 0x00000011, 0x00000778, + 0x00000A19, 0x00000A19, 0x0005002C, 0x00000011, 0x000007DF, 0x000001C1, 0x000001C1, 0x0005002C, + 0x00000011, 0x000007F6, 0x00000A2B, 0x00000A2B, 0x0005002C, 0x00000011, 0x0000085F, 0x00000A3A, + 0x00000A3A, 0x0005002C, 0x00000011, 0x000008DD, 0x00000A4C, 0x00000A4C, 0x0005002C, 0x00000011, + 0x000007CC, 0x00000A25, 0x00000A25, 0x0005002C, 0x00000011, 0x00000218, 0x0000044A, 0x0000044A, + 0x0005002C, 0x00000011, 0x00000203, 0x00000447, 0x00000447, 0x0005002C, 0x00000011, 0x000008A5, + 0x00000A44, 0x00000A44, 0x0005002C, 0x00000011, 0x0000078D, 0x00000A1C, 0x00000A1C, 0x0005002C, + 0x00000011, 0x0000074E, 0x00000A13, 0x00000A13, 0x0005002C, 0x00000011, 0x00000373, 0x000003D6, + 0x000003D6, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, + 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, + 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, + 0x000060D7, 0x000500C7, 0x0000000B, 0x00005F7D, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, + 0x000048EB, 0x00005F7D, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001FCD, 0x00003526, 0x00000A10, + 0x000500C7, 0x0000000B, 0x0000619E, 0x00001FCD, 0x00000A13, 0x00050050, 0x00000011, 0x000022A7, + 0x00003526, 0x00003526, 0x000500C2, 0x00000011, 0x00001BAF, 0x000022A7, 0x00000787, 0x000500C7, + 0x00000011, 0x00001997, 0x00001BAF, 0x000007A2, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, + 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, + 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, + 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, + 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, + 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, + 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, + 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, + 0x0000538B, 0x00002A0E, 0x00000A2C, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, + 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, + 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, + 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, + 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, + 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, + 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, + 0x00005BEB, 0x00000A23, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, + 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, + 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, + 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, + 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, + 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00001B12, 0x00002A92, + 0x0000578B, 0x000500C2, 0x0000000B, 0x00002BBD, 0x00001B12, 0x00000A16, 0x00050051, 0x0000000B, + 0x000029E2, 0x0000538B, 0x00000000, 0x000500C2, 0x0000000B, 0x00001DEE, 0x000029E2, 0x00000A10, + 0x00050051, 0x0000000B, 0x00002704, 0x0000538B, 0x00000001, 0x00050050, 0x00000011, 0x00005C0B, + 0x00001DEE, 0x00002704, 0x00050086, 0x00000011, 0x00001F69, 0x00005C0B, 0x00001997, 0x00050051, + 0x0000000B, 0x0000366C, 0x00001F69, 0x00000000, 0x000500C4, 0x0000000B, 0x00004D4D, 0x0000366C, + 0x00000A10, 0x00050051, 0x0000000B, 0x000051A9, 0x00001F69, 0x00000001, 0x00050051, 0x0000000B, + 0x000059EE, 0x0000538B, 0x00000002, 0x00060050, 0x00000014, 0x000024C9, 0x00004D4D, 0x000051A9, + 0x000059EE, 0x000300F7, 0x00005341, 0x00000002, 0x000400FA, 0x000048EB, 0x0000537D, 0x00002DD9, + 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, 0x00002970, 0x000024C9, 0x00050051, 0x0000000C, + 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A17, + 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405C, + 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005789, 0x00000A16, 0x0004007C, + 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005321, 0x0000405C, 0x000018AA, + 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, + 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, + 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, 0x00002970, 0x00000000, + 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, + 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A22, 0x000500C7, + 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, + 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, + 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, + 0x0000434B, 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, + 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, + 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, + 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, + 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, + 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, + 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, + 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, + 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, + 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, 0x00050080, + 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000042C2, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, + 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, + 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, + 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, + 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, + 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, + 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00005559, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, + 0x00005559, 0x0004007C, 0x0000000B, 0x0000566F, 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, + 0x00002DD9, 0x0007004F, 0x00000011, 0x00002621, 0x000024C9, 0x000024C9, 0x00000000, 0x00000001, + 0x0004007C, 0x00000012, 0x000059CF, 0x00002621, 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, + 0x00000000, 0x000500C3, 0x0000000C, 0x000024FE, 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, + 0x00002748, 0x000059CF, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, + 0x000500C2, 0x0000000B, 0x00005B4E, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, + 0x00005B4E, 0x00050084, 0x0000000C, 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, + 0x00003F5E, 0x000024FE, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A25, + 0x000500C7, 0x0000000C, 0x00002AB6, 0x00001903, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, + 0x00002748, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, + 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, + 0x00000A10, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, + 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, + 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, + 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, + 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, + 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, + 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, + 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, + 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, + 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, + 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x00001903, 0x00000A14, + 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, + 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, + 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x00002E06, 0x00004159, + 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4D, 0x00002E06, 0x0004007C, 0x0000000B, + 0x00005670, 0x0000394F, 0x000200F9, 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, + 0x000024FC, 0x0000566F, 0x0000537D, 0x00005670, 0x00002DD9, 0x00050084, 0x00000011, 0x00003FA8, + 0x00001F69, 0x00001997, 0x00050082, 0x00000011, 0x00003BBC, 0x00005C0B, 0x00003FA8, 0x00050051, + 0x0000000B, 0x00001C87, 0x00001997, 0x00000000, 0x00050051, 0x0000000B, 0x00005962, 0x00001997, + 0x00000001, 0x00050084, 0x0000000B, 0x00003372, 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, + 0x00003CA0, 0x000024FC, 0x00003372, 0x00050051, 0x0000000B, 0x00003ED4, 0x00003BBC, 0x00000000, + 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, 0x00005962, 0x00050051, 0x0000000B, 0x00001AE6, + 0x00003BBC, 0x00000001, 0x00050080, 0x0000000B, 0x00002B25, 0x00003E12, 0x00001AE6, 0x000500C4, + 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A10, 0x000500C7, 0x0000000B, 0x00005AB3, 0x000029E2, + 0x00000A13, 0x00050080, 0x0000000B, 0x00002557, 0x0000609D, 0x00005AB3, 0x000500C4, 0x0000000B, + 0x000040AD, 0x00002557, 0x00000A10, 0x00050080, 0x0000000B, 0x00004EAA, 0x00003CA0, 0x000040AD, + 0x00050080, 0x0000000B, 0x00003BA9, 0x00005EAC, 0x00004EAA, 0x000500C2, 0x0000000B, 0x00003948, + 0x00003BA9, 0x00000A16, 0x00060041, 0x00000294, 0x00004FAF, 0x0000107A, 0x00000A0B, 0x00003948, + 0x0004003D, 0x00000017, 0x00001CAA, 0x00004FAF, 0x000500AA, 0x00000009, 0x000035C0, 0x0000619E, + 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x0000619E, 0x00000A10, 0x000500A6, 0x00000009, + 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, + 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, + 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, + 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, + 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, + 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, 0x00005341, 0x00003FF8, 0x00002957, + 0x000500AA, 0x00000009, 0x00004CB6, 0x0000619E, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, + 0x00005376, 0x00004CB6, 0x000300F7, 0x00002DA2, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, + 0x00002DA2, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, + 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, + 0x00005E17, 0x00003BE7, 0x000200F9, 0x00002DA2, 0x000200F8, 0x00002DA2, 0x000700F5, 0x00000017, + 0x00004DEC, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x0007004F, 0x00000011, 0x000052B5, + 0x00004DEC, 0x00004DEC, 0x00000000, 0x00000001, 0x000500C7, 0x00000011, 0x00002FAE, 0x000052B5, + 0x00000A50, 0x000500C2, 0x00000011, 0x00001AF2, 0x00002FAE, 0x000007E1, 0x000500AB, 0x0000000F, + 0x000031A4, 0x00001AF2, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EAC, 0x00002FAE, 0x000008BA, + 0x000600A9, 0x00000011, 0x00001DE7, 0x00004EAC, 0x000008CF, 0x00002FAE, 0x000600A9, 0x00000011, + 0x00005A0A, 0x000031A4, 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C78, 0x00001DE7, + 0x00005A0A, 0x00050080, 0x00000011, 0x00005FB4, 0x00005C78, 0x00001AF2, 0x000500C4, 0x00000011, + 0x000022A8, 0x00005FB4, 0x00000778, 0x000500C2, 0x00000011, 0x00003516, 0x00005FB4, 0x00000778, + 0x000500C5, 0x00000011, 0x00005C42, 0x000022A8, 0x00003516, 0x000600A9, 0x00000011, 0x00003C67, + 0x000031A4, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E5E, 0x00005C42, 0x00003C67, + 0x00050080, 0x00000011, 0x0000616D, 0x00001E5E, 0x00001AF2, 0x000500C2, 0x00000011, 0x00005F10, + 0x000052B5, 0x000007F6, 0x000500C7, 0x00000011, 0x00002E2E, 0x00005F10, 0x00000A50, 0x000500C2, + 0x00000011, 0x000018AF, 0x00002E2E, 0x000007E1, 0x000500AB, 0x0000000F, 0x000031A5, 0x000018AF, + 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EAD, 0x00002E2E, 0x000008BA, 0x000600A9, 0x00000011, + 0x00001DE8, 0x00004EAD, 0x000008CF, 0x00002E2E, 0x000600A9, 0x00000011, 0x00005A0B, 0x000031A5, + 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C79, 0x00001DE8, 0x00005A0B, 0x00050080, + 0x00000011, 0x00005FB5, 0x00005C79, 0x000018AF, 0x000500C4, 0x00000011, 0x000022A9, 0x00005FB5, + 0x00000778, 0x000500C2, 0x00000011, 0x00003517, 0x00005FB5, 0x00000778, 0x000500C5, 0x00000011, + 0x00005C43, 0x000022A9, 0x00003517, 0x000600A9, 0x00000011, 0x00003C68, 0x000031A5, 0x000007DF, + 0x0000070F, 0x000500C6, 0x00000011, 0x00001E84, 0x00005C43, 0x00003C68, 0x00050080, 0x00000011, + 0x00005FED, 0x00001E84, 0x000018AF, 0x000500C4, 0x00000011, 0x00002068, 0x00005FED, 0x0000085F, + 0x000500C5, 0x00000011, 0x00002374, 0x0000616D, 0x00002068, 0x000500C2, 0x00000011, 0x00005BF5, + 0x000052B5, 0x000008DD, 0x000500C2, 0x00000011, 0x0000339C, 0x00005BF5, 0x000007CC, 0x000500AB, + 0x0000000F, 0x00002E80, 0x0000339C, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EAE, 0x00005BF5, + 0x00000203, 0x000600A9, 0x00000011, 0x00001DE9, 0x00004EAE, 0x00000218, 0x00005BF5, 0x000600A9, + 0x00000011, 0x00005A0D, 0x00002E80, 0x000008A5, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C7A, + 0x00001DE9, 0x00005A0D, 0x00050080, 0x00000011, 0x00005FB6, 0x00005C7A, 0x0000339C, 0x000500C4, + 0x00000011, 0x000022AA, 0x00005FB6, 0x0000078D, 0x000500C2, 0x00000011, 0x00003518, 0x00005FB6, + 0x0000074E, 0x000500C5, 0x00000011, 0x00005C44, 0x000022AA, 0x00003518, 0x000600A9, 0x00000011, + 0x00003C69, 0x00002E80, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E97, 0x00005C44, + 0x00003C69, 0x00050080, 0x00000011, 0x000056A4, 0x00001E97, 0x0000339C, 0x000500C5, 0x00000011, + 0x00004668, 0x000056A4, 0x00000373, 0x00050051, 0x0000000B, 0x000028D5, 0x00002374, 0x00000000, + 0x00050051, 0x0000000B, 0x00005CB2, 0x00002374, 0x00000001, 0x00050051, 0x0000000B, 0x00001DD9, + 0x00004668, 0x00000000, 0x00050051, 0x0000000B, 0x00001E73, 0x00004668, 0x00000001, 0x00070050, + 0x00000017, 0x00003F21, 0x000028D5, 0x00005CB2, 0x00001DD9, 0x00001E73, 0x0009004F, 0x00000017, + 0x00001E85, 0x00003F21, 0x00003F21, 0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x0007004F, + 0x00000011, 0x000021FB, 0x00004DEC, 0x00004DEC, 0x00000002, 0x00000003, 0x000500C7, 0x00000011, + 0x00001BFF, 0x000021FB, 0x00000A50, 0x000500C2, 0x00000011, 0x00001AF3, 0x00001BFF, 0x000007E1, + 0x000500AB, 0x0000000F, 0x000031A6, 0x00001AF3, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EAF, + 0x00001BFF, 0x000008BA, 0x000600A9, 0x00000011, 0x00001DEA, 0x00004EAF, 0x000008CF, 0x00001BFF, + 0x000600A9, 0x00000011, 0x00005A0E, 0x000031A6, 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, + 0x00005C7B, 0x00001DEA, 0x00005A0E, 0x00050080, 0x00000011, 0x00005FB7, 0x00005C7B, 0x00001AF3, + 0x000500C4, 0x00000011, 0x000022AB, 0x00005FB7, 0x00000778, 0x000500C2, 0x00000011, 0x00003519, + 0x00005FB7, 0x00000778, 0x000500C5, 0x00000011, 0x00005C45, 0x000022AB, 0x00003519, 0x000600A9, + 0x00000011, 0x00003C6A, 0x000031A6, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E5F, + 0x00005C45, 0x00003C6A, 0x00050080, 0x00000011, 0x0000616E, 0x00001E5F, 0x00001AF3, 0x000500C2, + 0x00000011, 0x00005F11, 0x000021FB, 0x000007F6, 0x000500C7, 0x00000011, 0x00002E2F, 0x00005F11, + 0x00000A50, 0x000500C2, 0x00000011, 0x000018B0, 0x00002E2F, 0x000007E1, 0x000500AB, 0x0000000F, + 0x000031A7, 0x000018B0, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB0, 0x00002E2F, 0x000008BA, + 0x000600A9, 0x00000011, 0x00001DEB, 0x00004EB0, 0x000008CF, 0x00002E2F, 0x000600A9, 0x00000011, + 0x00005A0F, 0x000031A7, 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C7C, 0x00001DEB, + 0x00005A0F, 0x00050080, 0x00000011, 0x00005FB8, 0x00005C7C, 0x000018B0, 0x000500C4, 0x00000011, + 0x000022AC, 0x00005FB8, 0x00000778, 0x000500C2, 0x00000011, 0x0000351A, 0x00005FB8, 0x00000778, + 0x000500C5, 0x00000011, 0x00005C46, 0x000022AC, 0x0000351A, 0x000600A9, 0x00000011, 0x00003C6B, + 0x000031A7, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E86, 0x00005C46, 0x00003C6B, + 0x00050080, 0x00000011, 0x00005FEE, 0x00001E86, 0x000018B0, 0x000500C4, 0x00000011, 0x00002069, + 0x00005FEE, 0x0000085F, 0x000500C5, 0x00000011, 0x00002375, 0x0000616E, 0x00002069, 0x000500C2, + 0x00000011, 0x00005BF6, 0x000021FB, 0x000008DD, 0x000500C2, 0x00000011, 0x0000339D, 0x00005BF6, + 0x000007CC, 0x000500AB, 0x0000000F, 0x00002E81, 0x0000339D, 0x0000070F, 0x000500AA, 0x0000000F, + 0x00004EB1, 0x00005BF6, 0x00000203, 0x000600A9, 0x00000011, 0x00001DEC, 0x00004EB1, 0x00000218, + 0x00005BF6, 0x000600A9, 0x00000011, 0x00005A10, 0x00002E81, 0x000008A5, 0x0000070F, 0x000500C6, + 0x00000011, 0x00005C7D, 0x00001DEC, 0x00005A10, 0x00050080, 0x00000011, 0x00005FB9, 0x00005C7D, + 0x0000339D, 0x000500C4, 0x00000011, 0x000022AD, 0x00005FB9, 0x0000078D, 0x000500C2, 0x00000011, + 0x0000351B, 0x00005FB9, 0x0000074E, 0x000500C5, 0x00000011, 0x00005C47, 0x000022AD, 0x0000351B, + 0x000600A9, 0x00000011, 0x00003C6C, 0x00002E81, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, + 0x00001E98, 0x00005C47, 0x00003C6C, 0x00050080, 0x00000011, 0x000056A5, 0x00001E98, 0x0000339D, + 0x000500C5, 0x00000011, 0x00004669, 0x000056A5, 0x00000373, 0x00050051, 0x0000000B, 0x000028D6, + 0x00002375, 0x00000000, 0x00050051, 0x0000000B, 0x00005CB3, 0x00002375, 0x00000001, 0x00050051, + 0x0000000B, 0x00001DDA, 0x00004669, 0x00000000, 0x00050051, 0x0000000B, 0x00001E74, 0x00004669, + 0x00000001, 0x00070050, 0x00000017, 0x00003E17, 0x000028D6, 0x00005CB3, 0x00001DDA, 0x00001E74, + 0x0009004F, 0x00000017, 0x00001DCF, 0x00003E17, 0x00003E17, 0x00000000, 0x00000002, 0x00000001, + 0x00000003, 0x00060041, 0x00000294, 0x0000303F, 0x0000140E, 0x00000A0B, 0x00002BBD, 0x0003003E, + 0x0000303F, 0x00001E85, 0x00050080, 0x0000000B, 0x00002CC1, 0x00002BBD, 0x00000A0D, 0x00060041, + 0x00000294, 0x00005C9F, 0x0000140E, 0x00000A0B, 0x00002CC1, 0x0003003E, 0x00005C9F, 0x00001DCF, + 0x000500AC, 0x00000009, 0x00005BF7, 0x00001C87, 0x00000A0D, 0x000300F7, 0x000060BC, 0x00000002, + 0x000400FA, 0x00005BF7, 0x00005084, 0x00005094, 0x000200F8, 0x00005084, 0x00050086, 0x0000000B, + 0x00003697, 0x00001DEE, 0x00001C87, 0x00050084, 0x0000000B, 0x0000237E, 0x00003697, 0x00001C87, + 0x00050082, 0x0000000B, 0x00003171, 0x00001DEE, 0x0000237E, 0x00050080, 0x0000000B, 0x00002527, + 0x00003171, 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, 0x00001C87, 0x000300F7, + 0x00001EED, 0x00000000, 0x000400FA, 0x0000343F, 0x0000569E, 0x00002191, 0x000200F8, 0x0000569E, + 0x00050084, 0x0000000B, 0x00004B59, 0x00000A6A, 0x00001C87, 0x000500C4, 0x0000000B, 0x0000540F, + 0x00003171, 0x00000A16, 0x00050082, 0x0000000B, 0x00004944, 0x00004B59, 0x0000540F, 0x000200F9, + 0x00001EED, 0x000200F8, 0x00002191, 0x000200F9, 0x00001EED, 0x000200F8, 0x00001EED, 0x000700F5, + 0x0000000B, 0x0000292C, 0x00004944, 0x0000569E, 0x00000A3A, 0x00002191, 0x000200F9, 0x000060BC, + 0x000200F8, 0x00005094, 0x000200F9, 0x000060BC, 0x000200F8, 0x000060BC, 0x000700F5, 0x0000000B, + 0x000029BC, 0x0000292C, 0x00001EED, 0x00000A6A, 0x00005094, 0x00050084, 0x0000000B, 0x0000492B, + 0x000029BC, 0x00005962, 0x000500C2, 0x0000000B, 0x0000406D, 0x0000492B, 0x00000A16, 0x00050080, + 0x0000000B, 0x0000336B, 0x00003948, 0x0000406D, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, + 0x00000A0B, 0x0000336B, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x00003A1A, + 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, + 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, + 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, + 0x000060BC, 0x00003FF9, 0x00002958, 0x000300F7, 0x00002DA3, 0x00000000, 0x000400FA, 0x00003B23, + 0x00002B39, 0x00002DA3, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, + 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, + 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x00002DA3, 0x000200F8, 0x00002DA3, 0x000700F5, + 0x00000017, 0x00004DED, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x0007004F, 0x00000011, + 0x000052B6, 0x00004DED, 0x00004DED, 0x00000000, 0x00000001, 0x000500C7, 0x00000011, 0x00002FAF, + 0x000052B6, 0x00000A50, 0x000500C2, 0x00000011, 0x00001AF4, 0x00002FAF, 0x000007E1, 0x000500AB, + 0x0000000F, 0x000031A8, 0x00001AF4, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB2, 0x00002FAF, + 0x000008BA, 0x000600A9, 0x00000011, 0x00001DED, 0x00004EB2, 0x000008CF, 0x00002FAF, 0x000600A9, + 0x00000011, 0x00005A11, 0x000031A8, 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C7E, + 0x00001DED, 0x00005A11, 0x00050080, 0x00000011, 0x00005FBA, 0x00005C7E, 0x00001AF4, 0x000500C4, + 0x00000011, 0x000022AE, 0x00005FBA, 0x00000778, 0x000500C2, 0x00000011, 0x0000351C, 0x00005FBA, + 0x00000778, 0x000500C5, 0x00000011, 0x00005C48, 0x000022AE, 0x0000351C, 0x000600A9, 0x00000011, + 0x00003C6D, 0x000031A8, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E60, 0x00005C48, + 0x00003C6D, 0x00050080, 0x00000011, 0x0000616F, 0x00001E60, 0x00001AF4, 0x000500C2, 0x00000011, + 0x00005F12, 0x000052B6, 0x000007F6, 0x000500C7, 0x00000011, 0x00002E30, 0x00005F12, 0x00000A50, + 0x000500C2, 0x00000011, 0x000018B1, 0x00002E30, 0x000007E1, 0x000500AB, 0x0000000F, 0x000031A9, + 0x000018B1, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB3, 0x00002E30, 0x000008BA, 0x000600A9, + 0x00000011, 0x00001DEF, 0x00004EB3, 0x000008CF, 0x00002E30, 0x000600A9, 0x00000011, 0x00005A12, + 0x000031A9, 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C7F, 0x00001DEF, 0x00005A12, + 0x00050080, 0x00000011, 0x00005FBB, 0x00005C7F, 0x000018B1, 0x000500C4, 0x00000011, 0x000022AF, + 0x00005FBB, 0x00000778, 0x000500C2, 0x00000011, 0x0000351D, 0x00005FBB, 0x00000778, 0x000500C5, + 0x00000011, 0x00005C49, 0x000022AF, 0x0000351D, 0x000600A9, 0x00000011, 0x00003C6E, 0x000031A9, + 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E87, 0x00005C49, 0x00003C6E, 0x00050080, + 0x00000011, 0x00005FEF, 0x00001E87, 0x000018B1, 0x000500C4, 0x00000011, 0x0000206A, 0x00005FEF, + 0x0000085F, 0x000500C5, 0x00000011, 0x00002376, 0x0000616F, 0x0000206A, 0x000500C2, 0x00000011, + 0x00005BF8, 0x000052B6, 0x000008DD, 0x000500C2, 0x00000011, 0x0000339E, 0x00005BF8, 0x000007CC, + 0x000500AB, 0x0000000F, 0x00002E82, 0x0000339E, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB4, + 0x00005BF8, 0x00000203, 0x000600A9, 0x00000011, 0x00001DF0, 0x00004EB4, 0x00000218, 0x00005BF8, + 0x000600A9, 0x00000011, 0x00005A13, 0x00002E82, 0x000008A5, 0x0000070F, 0x000500C6, 0x00000011, + 0x00005C80, 0x00001DF0, 0x00005A13, 0x00050080, 0x00000011, 0x00005FBC, 0x00005C80, 0x0000339E, + 0x000500C4, 0x00000011, 0x000022B0, 0x00005FBC, 0x0000078D, 0x000500C2, 0x00000011, 0x0000351E, + 0x00005FBC, 0x0000074E, 0x000500C5, 0x00000011, 0x00005C4A, 0x000022B0, 0x0000351E, 0x000600A9, + 0x00000011, 0x00003C6F, 0x00002E82, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E99, + 0x00005C4A, 0x00003C6F, 0x00050080, 0x00000011, 0x000056A6, 0x00001E99, 0x0000339E, 0x000500C5, + 0x00000011, 0x0000466A, 0x000056A6, 0x00000373, 0x00050051, 0x0000000B, 0x000028D7, 0x00002376, + 0x00000000, 0x00050051, 0x0000000B, 0x00005CB4, 0x00002376, 0x00000001, 0x00050051, 0x0000000B, + 0x00001DDB, 0x0000466A, 0x00000000, 0x00050051, 0x0000000B, 0x00001E75, 0x0000466A, 0x00000001, + 0x00070050, 0x00000017, 0x00003F22, 0x000028D7, 0x00005CB4, 0x00001DDB, 0x00001E75, 0x0009004F, + 0x00000017, 0x00001E88, 0x00003F22, 0x00003F22, 0x00000000, 0x00000002, 0x00000001, 0x00000003, + 0x0007004F, 0x00000011, 0x000021FC, 0x00004DED, 0x00004DED, 0x00000002, 0x00000003, 0x000500C7, + 0x00000011, 0x00001C00, 0x000021FC, 0x00000A50, 0x000500C2, 0x00000011, 0x00001AF5, 0x00001C00, + 0x000007E1, 0x000500AB, 0x0000000F, 0x000031AA, 0x00001AF5, 0x0000070F, 0x000500AA, 0x0000000F, + 0x00004EB5, 0x00001C00, 0x000008BA, 0x000600A9, 0x00000011, 0x00001DF1, 0x00004EB5, 0x000008CF, + 0x00001C00, 0x000600A9, 0x00000011, 0x00005A14, 0x000031AA, 0x00000A50, 0x0000070F, 0x000500C6, + 0x00000011, 0x00005C81, 0x00001DF1, 0x00005A14, 0x00050080, 0x00000011, 0x00005FBD, 0x00005C81, + 0x00001AF5, 0x000500C4, 0x00000011, 0x000022B1, 0x00005FBD, 0x00000778, 0x000500C2, 0x00000011, + 0x0000351F, 0x00005FBD, 0x00000778, 0x000500C5, 0x00000011, 0x00005C4B, 0x000022B1, 0x0000351F, + 0x000600A9, 0x00000011, 0x00003C70, 0x000031AA, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, + 0x00001E61, 0x00005C4B, 0x00003C70, 0x00050080, 0x00000011, 0x00006170, 0x00001E61, 0x00001AF5, + 0x000500C2, 0x00000011, 0x00005F13, 0x000021FC, 0x000007F6, 0x000500C7, 0x00000011, 0x00002E31, + 0x00005F13, 0x00000A50, 0x000500C2, 0x00000011, 0x000018B2, 0x00002E31, 0x000007E1, 0x000500AB, + 0x0000000F, 0x000031AB, 0x000018B2, 0x0000070F, 0x000500AA, 0x0000000F, 0x00004EB6, 0x00002E31, + 0x000008BA, 0x000600A9, 0x00000011, 0x00001DF2, 0x00004EB6, 0x000008CF, 0x00002E31, 0x000600A9, + 0x00000011, 0x00005A15, 0x000031AB, 0x00000A50, 0x0000070F, 0x000500C6, 0x00000011, 0x00005C82, + 0x00001DF2, 0x00005A15, 0x00050080, 0x00000011, 0x00005FBE, 0x00005C82, 0x000018B2, 0x000500C4, + 0x00000011, 0x000022B2, 0x00005FBE, 0x00000778, 0x000500C2, 0x00000011, 0x00003520, 0x00005FBE, + 0x00000778, 0x000500C5, 0x00000011, 0x00005C4C, 0x000022B2, 0x00003520, 0x000600A9, 0x00000011, + 0x00003C71, 0x000031AB, 0x000007DF, 0x0000070F, 0x000500C6, 0x00000011, 0x00001E89, 0x00005C4C, + 0x00003C71, 0x00050080, 0x00000011, 0x00005FF0, 0x00001E89, 0x000018B2, 0x000500C4, 0x00000011, + 0x0000206B, 0x00005FF0, 0x0000085F, 0x000500C5, 0x00000011, 0x00002377, 0x00006170, 0x0000206B, + 0x000500C2, 0x00000011, 0x00005BF9, 0x000021FC, 0x000008DD, 0x000500C2, 0x00000011, 0x0000339F, + 0x00005BF9, 0x000007CC, 0x000500AB, 0x0000000F, 0x00002E83, 0x0000339F, 0x0000070F, 0x000500AA, + 0x0000000F, 0x00004EB7, 0x00005BF9, 0x00000203, 0x000600A9, 0x00000011, 0x00001DF3, 0x00004EB7, + 0x00000218, 0x00005BF9, 0x000600A9, 0x00000011, 0x00005A16, 0x00002E83, 0x000008A5, 0x0000070F, + 0x000500C6, 0x00000011, 0x00005C83, 0x00001DF3, 0x00005A16, 0x00050080, 0x00000011, 0x00005FBF, + 0x00005C83, 0x0000339F, 0x000500C4, 0x00000011, 0x000022B3, 0x00005FBF, 0x0000078D, 0x000500C2, + 0x00000011, 0x00003521, 0x00005FBF, 0x0000074E, 0x000500C5, 0x00000011, 0x00005C4D, 0x000022B3, + 0x00003521, 0x000600A9, 0x00000011, 0x00003C72, 0x00002E83, 0x000007DF, 0x0000070F, 0x000500C6, + 0x00000011, 0x00001E9A, 0x00005C4D, 0x00003C72, 0x00050080, 0x00000011, 0x000056A7, 0x00001E9A, + 0x0000339F, 0x000500C5, 0x00000011, 0x0000466B, 0x000056A7, 0x00000373, 0x00050051, 0x0000000B, + 0x000028D8, 0x00002377, 0x00000000, 0x00050051, 0x0000000B, 0x00005CB5, 0x00002377, 0x00000001, + 0x00050051, 0x0000000B, 0x00001DDC, 0x0000466B, 0x00000000, 0x00050051, 0x0000000B, 0x00001E76, + 0x0000466B, 0x00000001, 0x00070050, 0x00000017, 0x000042C4, 0x000028D8, 0x00005CB5, 0x00001DDC, + 0x00001E76, 0x0009004F, 0x00000017, 0x00003DF4, 0x000042C4, 0x000042C4, 0x00000000, 0x00000002, + 0x00000001, 0x00000003, 0x00050080, 0x0000000B, 0x000055BE, 0x00002BBD, 0x00000A10, 0x00060041, + 0x00000294, 0x00001E95, 0x0000140E, 0x00000A0B, 0x000055BE, 0x0003003E, 0x00001E95, 0x00001E88, + 0x00050080, 0x0000000B, 0x00002CC2, 0x00002BBD, 0x00000A13, 0x00060041, 0x00000294, 0x00006256, + 0x0000140E, 0x00000A0B, 0x00002CC2, 0x0003003E, 0x00006256, 0x00003DF4, 0x000200F9, 0x00004C7A, + 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r16_snorm_float_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r16_snorm_float_cs.h new file mode 100644 index 0000000..f3cabf6 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r16_snorm_float_cs.h @@ -0,0 +1,593 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25059 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %float_n1 = OpConstant %float -1 + %v4int = OpTypeVector %int 4 + %int_16 = OpConstant %int 16 +%float_3_05185094en05 = OpConstant %float 3.05185094e-05 + %uint_0 = OpConstant %uint 0 + %v2float = OpTypeVector %float 2 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %uint_3 = OpConstant %uint 3 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 + %uint_64 = OpConstant %uint 64 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2612 = OpConstantComposite %v3uint %uint_4 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %1284 = OpConstantComposite %v4float %float_n1 %float_n1 %float_n1 %float_n1 + %770 = OpConstantComposite %v4int %int_16 %int_16 %int_16 %int_16 + %uint_16 = OpConstant %uint 16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2612 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_2 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_7 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_7 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_7 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_8 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_1 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %6362 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %22810 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %8801 = OpLoad %v4uint %17173 + %21106 = OpIEqual %bool %25058 %uint_1 + OpSelectionMerge %12537 None + OpBranchConditional %21106 %10583 %12537 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %8801 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %8801 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %12537 + %12537 = OpLabel + %12106 = OpPhi %v4uint %8801 %24387 %16376 %10583 + %15375 = OpBitcast %v4int %12106 + %16910 = OpShiftLeftLogical %v4int %15375 %770 + %16536 = OpShiftRightArithmetic %v4int %16910 %770 + %10903 = OpConvertSToF %v4float %16536 + %20413 = OpVectorTimesScalar %v4float %10903 %float_3_05185094en05 + %23989 = OpExtInst %v4float %1 FMax %1284 %20413 + %14338 = OpShiftRightArithmetic %v4int %15375 %770 + %6607 = OpConvertSToF %v4float %14338 + %18247 = OpVectorTimesScalar %v4float %6607 %float_3_05185094en05 + %24070 = OpExtInst %v4float %1 FMax %1284 %18247 + %24330 = OpCompositeExtract %float %23989 0 + %14319 = OpCompositeExtract %float %24070 0 + %19232 = OpCompositeConstruct %v2float %24330 %14319 + %8561 = OpExtInst %uint %1 PackHalf2x16 %19232 + %23487 = OpCompositeExtract %float %23989 1 + %14759 = OpCompositeExtract %float %24070 1 + %19233 = OpCompositeConstruct %v2float %23487 %14759 + %8562 = OpExtInst %uint %1 PackHalf2x16 %19233 + %23488 = OpCompositeExtract %float %23989 2 + %14760 = OpCompositeExtract %float %24070 2 + %19234 = OpCompositeConstruct %v2float %23488 %14760 + %8563 = OpExtInst %uint %1 PackHalf2x16 %19234 + %23489 = OpCompositeExtract %float %23989 3 + %14761 = OpCompositeExtract %float %24070 3 + %19213 = OpCompositeConstruct %v2float %23489 %14761 + %8430 = OpExtInst %uint %1 PackHalf2x16 %19213 + %15035 = OpCompositeConstruct %v4uint %8561 %8562 %8563 %8430 + %17859 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %17859 %15035 + %21686 = OpIAdd %uint %21685 %int_1 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_64 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %12538 None + OpBranchConditional %21106 %10584 %12538 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %12538 + %12538 = OpLabel + %12107 = OpPhi %v4uint %6578 %6871 %16377 %10584 + %15376 = OpBitcast %v4int %12107 + %16911 = OpShiftLeftLogical %v4int %15376 %770 + %16537 = OpShiftRightArithmetic %v4int %16911 %770 + %10904 = OpConvertSToF %v4float %16537 + %20414 = OpVectorTimesScalar %v4float %10904 %float_3_05185094en05 + %23990 = OpExtInst %v4float %1 FMax %1284 %20414 + %14339 = OpShiftRightArithmetic %v4int %15376 %770 + %6608 = OpConvertSToF %v4float %14339 + %18248 = OpVectorTimesScalar %v4float %6608 %float_3_05185094en05 + %24071 = OpExtInst %v4float %1 FMax %1284 %18248 + %24331 = OpCompositeExtract %float %23990 0 + %14320 = OpCompositeExtract %float %24071 0 + %19235 = OpCompositeConstruct %v2float %24331 %14320 + %8564 = OpExtInst %uint %1 PackHalf2x16 %19235 + %23490 = OpCompositeExtract %float %23990 1 + %14762 = OpCompositeExtract %float %24071 1 + %19236 = OpCompositeConstruct %v2float %23490 %14762 + %8565 = OpExtInst %uint %1 PackHalf2x16 %19236 + %23491 = OpCompositeExtract %float %23990 2 + %14763 = OpCompositeExtract %float %24071 2 + %19237 = OpCompositeConstruct %v2float %23491 %14763 + %8566 = OpExtInst %uint %1 PackHalf2x16 %19237 + %23492 = OpCompositeExtract %float %23990 3 + %14764 = OpCompositeExtract %float %24071 3 + %19214 = OpCompositeConstruct %v2float %23492 %14764 + %8431 = OpExtInst %uint %1 PackHalf2x16 %19214 + %15036 = OpCompositeConstruct %v4uint %8564 %8565 %8566 %8431 + %20158 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21686 + OpStore %20158 %15036 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r16_snorm_float_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000061E3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, + 0x00000004, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, 0x0000000B, + 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, + 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, + 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x0004002B, + 0x0000000D, 0x00000341, 0xBF800000, 0x00040017, 0x0000001A, 0x0000000C, 0x00000004, 0x0004002B, + 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000D, 0x00000A38, 0x38000100, 0x0004002B, + 0x0000000B, 0x00000A0A, 0x00000000, 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, + 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, + 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, + 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, + 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, + 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, + 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, + 0x0000000C, 0x00000A39, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, + 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, + 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, + 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, + 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, + 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0004002B, + 0x0000000B, 0x00000ACA, 0x00000040, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, + 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, + 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x00040020, 0x00000291, 0x00000009, + 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, + 0x00000001, 0x0006002C, 0x00000014, 0x00000A34, 0x00000A16, 0x00000A0A, 0x00000A0A, 0x00040017, + 0x0000000F, 0x00000009, 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, + 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, + 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, + 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, + 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, + 0x00000A0D, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, + 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, + 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x0000001D, + 0x00000504, 0x00000341, 0x00000341, 0x00000341, 0x00000341, 0x0007002C, 0x0000001A, 0x00000302, + 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, + 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, + 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, + 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, + 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, + 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, + 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, + 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, + 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, + 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, + 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, + 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, + 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, + 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, + 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, + 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A34, 0x0007004F, 0x00000011, 0x000042F0, + 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, + 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, + 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, + 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, + 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, + 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, + 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A11, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, + 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, + 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, + 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, + 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, + 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, + 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x000054B5, 0x00002764, 0x00000A16, + 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, 0x00005768, 0x000051F2, 0x000200F8, + 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, 0x00004384, 0x00002BF8, 0x000018D9, + 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, 0x000032B3, 0x000044BE, 0x00000A17, 0x000500C3, + 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, 0x000500C2, 0x0000000B, 0x00004947, 0x00005789, + 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00004947, 0x00050084, 0x0000000C, 0x00005321, + 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000032B3, 0x00005321, 0x000500C2, + 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x00003901, 0x00002348, + 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, 0x00003901, 0x000500C3, 0x0000000C, 0x000032BA, + 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, 0x00005FEE, 0x000032BA, 0x000020F4, 0x000500C4, + 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A1F, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, + 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, + 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000044BE, 0x00000A1D, + 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, + 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A1F, 0x000500C3, + 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000044BE, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000601E, 0x000500C7, 0x0000000C, + 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00005BEB, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, + 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, + 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, + 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A39, 0x00050080, 0x0000000C, 0x0000285C, + 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x000018DA, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A1F, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, + 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000044BE, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, + 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, + 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, + 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, + 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, + 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, + 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, + 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, + 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, + 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, + 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, + 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, + 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005788, 0x00000A19, 0x0004007C, + 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AB, + 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, + 0x00003F5E, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, + 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, + 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, + 0x000018E7, 0x00004397, 0x00000A0D, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, + 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, + 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A39, 0x00050080, + 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002747, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, + 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, + 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, + 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, + 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, + 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, + 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, + 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, + 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, + 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, + 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, + 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, + 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, + 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, 0x00005F43, 0x000200F8, 0x000051F2, 0x0004007C, + 0x0000000C, 0x00003CBC, 0x00005789, 0x00050084, 0x0000000C, 0x000060B8, 0x000018DA, 0x00003CBC, + 0x00050080, 0x0000000C, 0x0000208E, 0x000060B8, 0x000044BE, 0x0004007C, 0x0000000C, 0x000022F8, + 0x00005788, 0x00050084, 0x0000000C, 0x00001E9F, 0x0000208E, 0x000022F8, 0x00050080, 0x0000000C, + 0x00001F30, 0x0000591A, 0x00001E9F, 0x000200F9, 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, + 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, 0x00001F30, 0x000051F2, 0x0004007C, 0x0000000C, + 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, + 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, + 0x00060041, 0x00000294, 0x00004315, 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, + 0x00002261, 0x00004315, 0x000500AA, 0x00000009, 0x00005272, 0x000061E2, 0x00000A0D, 0x000300F7, + 0x000030F9, 0x00000000, 0x000400FA, 0x00005272, 0x00002957, 0x000030F9, 0x000200F8, 0x00002957, + 0x000500C7, 0x00000017, 0x0000475F, 0x00002261, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, + 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00002261, 0x0000072E, 0x000500C2, + 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, + 0x0000448D, 0x000200F9, 0x000030F9, 0x000200F8, 0x000030F9, 0x000700F5, 0x00000017, 0x00002F4A, + 0x00002261, 0x00005F43, 0x00003FF8, 0x00002957, 0x0004007C, 0x0000001A, 0x00003C0F, 0x00002F4A, + 0x000500C4, 0x0000001A, 0x0000420E, 0x00003C0F, 0x00000302, 0x000500C3, 0x0000001A, 0x00004098, + 0x0000420E, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A97, 0x00004098, 0x0005008E, 0x0000001D, + 0x00004FBD, 0x00002A97, 0x00000A38, 0x0007000C, 0x0000001D, 0x00005DB5, 0x00000001, 0x00000028, + 0x00000504, 0x00004FBD, 0x000500C3, 0x0000001A, 0x00003802, 0x00003C0F, 0x00000302, 0x0004006F, + 0x0000001D, 0x000019CF, 0x00003802, 0x0005008E, 0x0000001D, 0x00004747, 0x000019CF, 0x00000A38, + 0x0007000C, 0x0000001D, 0x00005E06, 0x00000001, 0x00000028, 0x00000504, 0x00004747, 0x00050051, + 0x0000000D, 0x00005F0A, 0x00005DB5, 0x00000000, 0x00050051, 0x0000000D, 0x000037EF, 0x00005E06, + 0x00000000, 0x00050050, 0x00000013, 0x00004B20, 0x00005F0A, 0x000037EF, 0x0006000C, 0x0000000B, + 0x00002171, 0x00000001, 0x0000003A, 0x00004B20, 0x00050051, 0x0000000D, 0x00005BBF, 0x00005DB5, + 0x00000001, 0x00050051, 0x0000000D, 0x000039A7, 0x00005E06, 0x00000001, 0x00050050, 0x00000013, + 0x00004B21, 0x00005BBF, 0x000039A7, 0x0006000C, 0x0000000B, 0x00002172, 0x00000001, 0x0000003A, + 0x00004B21, 0x00050051, 0x0000000D, 0x00005BC0, 0x00005DB5, 0x00000002, 0x00050051, 0x0000000D, + 0x000039A8, 0x00005E06, 0x00000002, 0x00050050, 0x00000013, 0x00004B22, 0x00005BC0, 0x000039A8, + 0x0006000C, 0x0000000B, 0x00002173, 0x00000001, 0x0000003A, 0x00004B22, 0x00050051, 0x0000000D, + 0x00005BC1, 0x00005DB5, 0x00000003, 0x00050051, 0x0000000D, 0x000039A9, 0x00005E06, 0x00000003, + 0x00050050, 0x00000013, 0x00004B0D, 0x00005BC1, 0x000039A9, 0x0006000C, 0x0000000B, 0x000020EE, + 0x00000001, 0x0000003A, 0x00004B0D, 0x00070050, 0x00000017, 0x00003ABB, 0x00002171, 0x00002172, + 0x00002173, 0x000020EE, 0x00060041, 0x00000294, 0x000045C3, 0x0000140E, 0x00000A0B, 0x000054B5, + 0x0003003E, 0x000045C3, 0x00003ABB, 0x00050080, 0x0000000B, 0x000054B6, 0x000054B5, 0x00000A0E, + 0x000300F7, 0x00001AD7, 0x00000002, 0x000400FA, 0x00004376, 0x000055E9, 0x00001C25, 0x000200F8, + 0x000055E9, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001C25, 0x000200F9, 0x00001AD7, 0x000200F8, + 0x00001AD7, 0x000700F5, 0x0000000B, 0x0000456F, 0x00000ACA, 0x000055E9, 0x00000A3A, 0x00001C25, + 0x000500C2, 0x0000000B, 0x000041C0, 0x0000456F, 0x00000A16, 0x00050080, 0x0000000B, 0x00002ADB, + 0x00005665, 0x000041C0, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, 0x00002ADB, + 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x000030FA, 0x00000000, 0x000400FA, + 0x00005272, 0x00002958, 0x000030FA, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, + 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, + 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, + 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x000030FA, + 0x000200F8, 0x000030FA, 0x000700F5, 0x00000017, 0x00002F4B, 0x000019B2, 0x00001AD7, 0x00003FF9, + 0x00002958, 0x0004007C, 0x0000001A, 0x00003C10, 0x00002F4B, 0x000500C4, 0x0000001A, 0x0000420F, + 0x00003C10, 0x00000302, 0x000500C3, 0x0000001A, 0x00004099, 0x0000420F, 0x00000302, 0x0004006F, + 0x0000001D, 0x00002A98, 0x00004099, 0x0005008E, 0x0000001D, 0x00004FBE, 0x00002A98, 0x00000A38, + 0x0007000C, 0x0000001D, 0x00005DB6, 0x00000001, 0x00000028, 0x00000504, 0x00004FBE, 0x000500C3, + 0x0000001A, 0x00003803, 0x00003C10, 0x00000302, 0x0004006F, 0x0000001D, 0x000019D0, 0x00003803, + 0x0005008E, 0x0000001D, 0x00004748, 0x000019D0, 0x00000A38, 0x0007000C, 0x0000001D, 0x00005E07, + 0x00000001, 0x00000028, 0x00000504, 0x00004748, 0x00050051, 0x0000000D, 0x00005F0B, 0x00005DB6, + 0x00000000, 0x00050051, 0x0000000D, 0x000037F0, 0x00005E07, 0x00000000, 0x00050050, 0x00000013, + 0x00004B23, 0x00005F0B, 0x000037F0, 0x0006000C, 0x0000000B, 0x00002174, 0x00000001, 0x0000003A, + 0x00004B23, 0x00050051, 0x0000000D, 0x00005BC2, 0x00005DB6, 0x00000001, 0x00050051, 0x0000000D, + 0x000039AA, 0x00005E07, 0x00000001, 0x00050050, 0x00000013, 0x00004B24, 0x00005BC2, 0x000039AA, + 0x0006000C, 0x0000000B, 0x00002175, 0x00000001, 0x0000003A, 0x00004B24, 0x00050051, 0x0000000D, + 0x00005BC3, 0x00005DB6, 0x00000002, 0x00050051, 0x0000000D, 0x000039AB, 0x00005E07, 0x00000002, + 0x00050050, 0x00000013, 0x00004B25, 0x00005BC3, 0x000039AB, 0x0006000C, 0x0000000B, 0x00002176, + 0x00000001, 0x0000003A, 0x00004B25, 0x00050051, 0x0000000D, 0x00005BC4, 0x00005DB6, 0x00000003, + 0x00050051, 0x0000000D, 0x000039AC, 0x00005E07, 0x00000003, 0x00050050, 0x00000013, 0x00004B0E, + 0x00005BC4, 0x000039AC, 0x0006000C, 0x0000000B, 0x000020EF, 0x00000001, 0x0000003A, 0x00004B0E, + 0x00070050, 0x00000017, 0x00003ABC, 0x00002174, 0x00002175, 0x00002176, 0x000020EF, 0x00060041, + 0x00000294, 0x00004EBE, 0x0000140E, 0x00000A0B, 0x000054B6, 0x0003003E, 0x00004EBE, 0x00003ABC, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r16_snorm_float_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r16_snorm_float_scaled_cs.h new file mode 100644 index 0000000..2064893 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r16_snorm_float_scaled_cs.h @@ -0,0 +1,654 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %float_n1 = OpConstant %float -1 + %v4int = OpTypeVector %int 4 + %int_16 = OpConstant %int 16 +%float_3_05185094en05 = OpConstant %float 3.05185094e-05 + %uint_0 = OpConstant %uint 0 + %v2float = OpTypeVector %float 2 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %uint_3 = OpConstant %uint 3 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 + %uint_64 = OpConstant %uint 64 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2612 = OpConstantComposite %v3uint %uint_4 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %1284 = OpConstantComposite %v4float %float_n1 %float_n1 %float_n1 %float_n1 + %770 = OpConstantComposite %v4int %int_16 %int_16 %int_16 %int_16 + %uint_16 = OpConstant %uint 16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2612 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_2 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_3 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_3 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_7 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_7 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_7 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_8 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_1 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_3 + %23219 = OpBitwiseAnd %uint %10722 %uint_7 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_1 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %8801 = OpLoad %v4uint %20399 + %21106 = OpIEqual %bool %24990 %uint_1 + OpSelectionMerge %12537 None + OpBranchConditional %21106 %10583 %12537 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %8801 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %8801 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %12537 + %12537 = OpLabel + %12106 = OpPhi %v4uint %8801 %21313 %16376 %10583 + %15375 = OpBitcast %v4int %12106 + %16910 = OpShiftLeftLogical %v4int %15375 %770 + %16536 = OpShiftRightArithmetic %v4int %16910 %770 + %10903 = OpConvertSToF %v4float %16536 + %20413 = OpVectorTimesScalar %v4float %10903 %float_3_05185094en05 + %23989 = OpExtInst %v4float %1 FMax %1284 %20413 + %14338 = OpShiftRightArithmetic %v4int %15375 %770 + %6607 = OpConvertSToF %v4float %14338 + %18247 = OpVectorTimesScalar %v4float %6607 %float_3_05185094en05 + %24070 = OpExtInst %v4float %1 FMax %1284 %18247 + %24330 = OpCompositeExtract %float %23989 0 + %14319 = OpCompositeExtract %float %24070 0 + %19232 = OpCompositeConstruct %v2float %24330 %14319 + %8561 = OpExtInst %uint %1 PackHalf2x16 %19232 + %23487 = OpCompositeExtract %float %23989 1 + %14759 = OpCompositeExtract %float %24070 1 + %19233 = OpCompositeConstruct %v2float %23487 %14759 + %8562 = OpExtInst %uint %1 PackHalf2x16 %19233 + %23488 = OpCompositeExtract %float %23989 2 + %14760 = OpCompositeExtract %float %24070 2 + %19234 = OpCompositeConstruct %v2float %23488 %14760 + %8563 = OpExtInst %uint %1 PackHalf2x16 %19234 + %23489 = OpCompositeExtract %float %23989 3 + %14761 = OpCompositeExtract %float %24070 3 + %19213 = OpCompositeConstruct %v2float %23489 %14761 + %8430 = OpExtInst %uint %1 PackHalf2x16 %19213 + %15035 = OpCompositeConstruct %v4uint %8561 %8562 %8563 %8430 + %17859 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %17859 %15035 + %15532 = OpIAdd %uint %11197 %int_1 + %6417 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %6417 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_64 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_64 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %12538 None + OpBranchConditional %21106 %10584 %12538 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %12538 + %12538 = OpLabel + %12107 = OpPhi %v4uint %6578 %24764 %16377 %10584 + %15376 = OpBitcast %v4int %12107 + %16911 = OpShiftLeftLogical %v4int %15376 %770 + %16537 = OpShiftRightArithmetic %v4int %16911 %770 + %10904 = OpConvertSToF %v4float %16537 + %20414 = OpVectorTimesScalar %v4float %10904 %float_3_05185094en05 + %23990 = OpExtInst %v4float %1 FMax %1284 %20414 + %14339 = OpShiftRightArithmetic %v4int %15376 %770 + %6608 = OpConvertSToF %v4float %14339 + %18248 = OpVectorTimesScalar %v4float %6608 %float_3_05185094en05 + %24071 = OpExtInst %v4float %1 FMax %1284 %18248 + %24331 = OpCompositeExtract %float %23990 0 + %14320 = OpCompositeExtract %float %24071 0 + %19235 = OpCompositeConstruct %v2float %24331 %14320 + %8564 = OpExtInst %uint %1 PackHalf2x16 %19235 + %23490 = OpCompositeExtract %float %23990 1 + %14762 = OpCompositeExtract %float %24071 1 + %19236 = OpCompositeConstruct %v2float %23490 %14762 + %8565 = OpExtInst %uint %1 PackHalf2x16 %19236 + %23491 = OpCompositeExtract %float %23990 2 + %14763 = OpCompositeExtract %float %24071 2 + %19237 = OpCompositeConstruct %v2float %23491 %14763 + %8566 = OpExtInst %uint %1 PackHalf2x16 %19237 + %23492 = OpCompositeExtract %float %23990 3 + %14764 = OpCompositeExtract %float %24071 3 + %19214 = OpCompositeConstruct %v2float %23492 %14764 + %8431 = OpExtInst %uint %1 PackHalf2x16 %19214 + %15036 = OpCompositeConstruct %v4uint %8564 %8565 %8566 %8431 + %20158 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15532 + OpStore %20158 %15036 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r16_snorm_float_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, + 0x00000004, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, + 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, + 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x0004002B, + 0x0000000D, 0x00000341, 0xBF800000, 0x00040017, 0x0000001A, 0x0000000C, 0x00000004, 0x0004002B, + 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000D, 0x00000A38, 0x38000100, 0x0004002B, + 0x0000000B, 0x00000A0A, 0x00000000, 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, + 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, + 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, + 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, + 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, + 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, + 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, + 0x0000000C, 0x00000A39, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, + 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, + 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, + 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, + 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, + 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0004002B, + 0x0000000B, 0x00000ACA, 0x00000040, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, + 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, + 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, 0x00000787, + 0x00000A16, 0x00000A1F, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, + 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, + 0x00000A34, 0x00000A16, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, + 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, + 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, 0x00000011, + 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, + 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, + 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, + 0x0007002C, 0x0000001D, 0x00000504, 0x00000341, 0x00000341, 0x00000341, 0x00000341, 0x0007002C, + 0x0000001A, 0x00000302, 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x0004002B, 0x0000000B, + 0x00000A3A, 0x00000010, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, + 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, + 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, + 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005F7D, 0x00003526, 0x00000A10, 0x000500AB, + 0x00000009, 0x000048EB, 0x00005F7D, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001FCD, 0x00003526, + 0x00000A10, 0x000500C7, 0x0000000B, 0x0000619E, 0x00001FCD, 0x00000A13, 0x00050050, 0x00000011, + 0x000022A7, 0x00003526, 0x00003526, 0x000500C2, 0x00000011, 0x00001BAF, 0x000022A7, 0x00000787, + 0x000500C7, 0x00000011, 0x00001997, 0x00001BAF, 0x000007A2, 0x00050041, 0x00000288, 0x0000492C, + 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, + 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, + 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, + 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, + 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, + 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, + 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, + 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A34, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, + 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, + 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, + 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, + 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, + 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, + 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, + 0x0000591A, 0x00005BEB, 0x00000A11, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, + 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, + 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, + 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, + 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, + 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00001B12, + 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x00002BBD, 0x00001B12, 0x00000A16, 0x00050051, + 0x0000000B, 0x000029E2, 0x0000538B, 0x00000000, 0x000500C2, 0x0000000B, 0x00001DEE, 0x000029E2, + 0x00000A13, 0x00050051, 0x0000000B, 0x00002704, 0x0000538B, 0x00000001, 0x00050050, 0x00000011, + 0x00005C0B, 0x00001DEE, 0x00002704, 0x00050086, 0x00000011, 0x00001F69, 0x00005C0B, 0x00001997, + 0x00050051, 0x0000000B, 0x0000366C, 0x00001F69, 0x00000000, 0x000500C4, 0x0000000B, 0x00004D4D, + 0x0000366C, 0x00000A13, 0x00050051, 0x0000000B, 0x000051A9, 0x00001F69, 0x00000001, 0x00050051, + 0x0000000B, 0x000059EE, 0x0000538B, 0x00000002, 0x00060050, 0x00000014, 0x000024C9, 0x00004D4D, + 0x000051A9, 0x000059EE, 0x000300F7, 0x00005341, 0x00000002, 0x000400FA, 0x000048EB, 0x0000537D, + 0x00002DD9, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, 0x00002970, 0x000024C9, 0x00050051, + 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, + 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000002, 0x000500C3, 0x0000000C, + 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005789, 0x00000A16, + 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005321, 0x0000405C, + 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, 0x00005321, 0x000500C2, 0x0000000B, + 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, + 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, 0x00002970, + 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, + 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A1F, + 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, + 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, + 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, + 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, + 0x00001B88, 0x0000434B, 0x00000A1F, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, + 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, + 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, + 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, + 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, + 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, + 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, + 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, + 0x00000A39, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, + 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A1F, + 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, + 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, + 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, + 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, + 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, + 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, + 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, + 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, + 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005559, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, + 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, 0x0000566F, 0x00005EFA, 0x000200F9, 0x00005341, + 0x000200F8, 0x00002DD9, 0x0007004F, 0x00000011, 0x00002621, 0x000024C9, 0x000024C9, 0x00000000, + 0x00000001, 0x0004007C, 0x00000012, 0x000059CF, 0x00002621, 0x00050051, 0x0000000C, 0x00001903, + 0x000059CF, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FE, 0x00001903, 0x00000A1A, 0x00050051, + 0x0000000C, 0x00002748, 0x000059CF, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, + 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, + 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, + 0x0000000C, 0x00003F5E, 0x000024FE, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, + 0x00000A22, 0x000500C7, 0x0000000C, 0x00002AB6, 0x00001903, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003139, 0x00002748, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, + 0x00004397, 0x00000A0D, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, + 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, + 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A39, 0x00050080, 0x0000000C, + 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, + 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, + 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, + 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, + 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, + 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, + 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, + 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x00001903, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, + 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, + 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x00002E06, + 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4D, 0x00002E06, 0x0004007C, + 0x0000000B, 0x00005670, 0x0000394F, 0x000200F9, 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, + 0x0000000B, 0x000024FC, 0x0000566F, 0x0000537D, 0x00005670, 0x00002DD9, 0x00050084, 0x00000011, + 0x00003FA8, 0x00001F69, 0x00001997, 0x00050082, 0x00000011, 0x00003BBC, 0x00005C0B, 0x00003FA8, + 0x00050051, 0x0000000B, 0x00001C87, 0x00001997, 0x00000000, 0x00050051, 0x0000000B, 0x00005962, + 0x00001997, 0x00000001, 0x00050084, 0x0000000B, 0x00003372, 0x00001C87, 0x00005962, 0x00050084, + 0x0000000B, 0x00003CA0, 0x000024FC, 0x00003372, 0x00050051, 0x0000000B, 0x00003ED4, 0x00003BBC, + 0x00000000, 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, 0x00005962, 0x00050051, 0x0000000B, + 0x00001AE6, 0x00003BBC, 0x00000001, 0x00050080, 0x0000000B, 0x00002B25, 0x00003E12, 0x00001AE6, + 0x000500C4, 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A13, 0x000500C7, 0x0000000B, 0x00005AB3, + 0x000029E2, 0x00000A1F, 0x00050080, 0x0000000B, 0x00002557, 0x0000609D, 0x00005AB3, 0x000500C4, + 0x0000000B, 0x000040AD, 0x00002557, 0x00000A0D, 0x00050080, 0x0000000B, 0x00004EAA, 0x00003CA0, + 0x000040AD, 0x00050080, 0x0000000B, 0x00003BA9, 0x00005EAC, 0x00004EAA, 0x000500C2, 0x0000000B, + 0x00003948, 0x00003BA9, 0x00000A16, 0x00060041, 0x00000294, 0x00004FAF, 0x0000107A, 0x00000A0B, + 0x00003948, 0x0004003D, 0x00000017, 0x00002261, 0x00004FAF, 0x000500AA, 0x00000009, 0x00005272, + 0x0000619E, 0x00000A0D, 0x000300F7, 0x000030F9, 0x00000000, 0x000400FA, 0x00005272, 0x00002957, + 0x000030F9, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00002261, 0x000009CE, + 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, + 0x00002261, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, + 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x000030F9, 0x000200F8, 0x000030F9, + 0x000700F5, 0x00000017, 0x00002F4A, 0x00002261, 0x00005341, 0x00003FF8, 0x00002957, 0x0004007C, + 0x0000001A, 0x00003C0F, 0x00002F4A, 0x000500C4, 0x0000001A, 0x0000420E, 0x00003C0F, 0x00000302, + 0x000500C3, 0x0000001A, 0x00004098, 0x0000420E, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A97, + 0x00004098, 0x0005008E, 0x0000001D, 0x00004FBD, 0x00002A97, 0x00000A38, 0x0007000C, 0x0000001D, + 0x00005DB5, 0x00000001, 0x00000028, 0x00000504, 0x00004FBD, 0x000500C3, 0x0000001A, 0x00003802, + 0x00003C0F, 0x00000302, 0x0004006F, 0x0000001D, 0x000019CF, 0x00003802, 0x0005008E, 0x0000001D, + 0x00004747, 0x000019CF, 0x00000A38, 0x0007000C, 0x0000001D, 0x00005E06, 0x00000001, 0x00000028, + 0x00000504, 0x00004747, 0x00050051, 0x0000000D, 0x00005F0A, 0x00005DB5, 0x00000000, 0x00050051, + 0x0000000D, 0x000037EF, 0x00005E06, 0x00000000, 0x00050050, 0x00000013, 0x00004B20, 0x00005F0A, + 0x000037EF, 0x0006000C, 0x0000000B, 0x00002171, 0x00000001, 0x0000003A, 0x00004B20, 0x00050051, + 0x0000000D, 0x00005BBF, 0x00005DB5, 0x00000001, 0x00050051, 0x0000000D, 0x000039A7, 0x00005E06, + 0x00000001, 0x00050050, 0x00000013, 0x00004B21, 0x00005BBF, 0x000039A7, 0x0006000C, 0x0000000B, + 0x00002172, 0x00000001, 0x0000003A, 0x00004B21, 0x00050051, 0x0000000D, 0x00005BC0, 0x00005DB5, + 0x00000002, 0x00050051, 0x0000000D, 0x000039A8, 0x00005E06, 0x00000002, 0x00050050, 0x00000013, + 0x00004B22, 0x00005BC0, 0x000039A8, 0x0006000C, 0x0000000B, 0x00002173, 0x00000001, 0x0000003A, + 0x00004B22, 0x00050051, 0x0000000D, 0x00005BC1, 0x00005DB5, 0x00000003, 0x00050051, 0x0000000D, + 0x000039A9, 0x00005E06, 0x00000003, 0x00050050, 0x00000013, 0x00004B0D, 0x00005BC1, 0x000039A9, + 0x0006000C, 0x0000000B, 0x000020EE, 0x00000001, 0x0000003A, 0x00004B0D, 0x00070050, 0x00000017, + 0x00003ABB, 0x00002171, 0x00002172, 0x00002173, 0x000020EE, 0x00060041, 0x00000294, 0x000045C3, + 0x0000140E, 0x00000A0B, 0x00002BBD, 0x0003003E, 0x000045C3, 0x00003ABB, 0x00050080, 0x0000000B, + 0x00003CAC, 0x00002BBD, 0x00000A0E, 0x000500AC, 0x00000009, 0x00001911, 0x00001C87, 0x00000A0D, + 0x000300F7, 0x000060BC, 0x00000002, 0x000400FA, 0x00001911, 0x00005084, 0x00005094, 0x000200F8, + 0x00005084, 0x00050086, 0x0000000B, 0x00003697, 0x00001DEE, 0x00001C87, 0x00050084, 0x0000000B, + 0x0000237E, 0x00003697, 0x00001C87, 0x00050082, 0x0000000B, 0x00003171, 0x00001DEE, 0x0000237E, + 0x00050080, 0x0000000B, 0x00002527, 0x00003171, 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, + 0x00002527, 0x00001C87, 0x000300F7, 0x00001EED, 0x00000000, 0x000400FA, 0x0000343F, 0x0000569E, + 0x00002191, 0x000200F8, 0x0000569E, 0x00050084, 0x0000000B, 0x00004B59, 0x00000ACA, 0x00001C87, + 0x000500C4, 0x0000000B, 0x0000540F, 0x00003171, 0x00000A16, 0x00050082, 0x0000000B, 0x00004944, + 0x00004B59, 0x0000540F, 0x000200F9, 0x00001EED, 0x000200F8, 0x00002191, 0x000200F9, 0x00001EED, + 0x000200F8, 0x00001EED, 0x000700F5, 0x0000000B, 0x0000292C, 0x00004944, 0x0000569E, 0x00000A3A, + 0x00002191, 0x000200F9, 0x000060BC, 0x000200F8, 0x00005094, 0x000200F9, 0x000060BC, 0x000200F8, + 0x000060BC, 0x000700F5, 0x0000000B, 0x000029BC, 0x0000292C, 0x00001EED, 0x00000ACA, 0x00005094, + 0x00050084, 0x0000000B, 0x0000492B, 0x000029BC, 0x00005962, 0x000500C2, 0x0000000B, 0x0000406D, + 0x0000492B, 0x00000A16, 0x00050080, 0x0000000B, 0x0000336B, 0x00003948, 0x0000406D, 0x00060041, + 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, 0x0000336B, 0x0004003D, 0x00000017, 0x000019B2, + 0x0000571A, 0x000300F7, 0x000030FA, 0x00000000, 0x000400FA, 0x00005272, 0x00002958, 0x000030FA, + 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, + 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, + 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, + 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x000030FA, 0x000200F8, 0x000030FA, 0x000700F5, + 0x00000017, 0x00002F4B, 0x000019B2, 0x000060BC, 0x00003FF9, 0x00002958, 0x0004007C, 0x0000001A, + 0x00003C10, 0x00002F4B, 0x000500C4, 0x0000001A, 0x0000420F, 0x00003C10, 0x00000302, 0x000500C3, + 0x0000001A, 0x00004099, 0x0000420F, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A98, 0x00004099, + 0x0005008E, 0x0000001D, 0x00004FBE, 0x00002A98, 0x00000A38, 0x0007000C, 0x0000001D, 0x00005DB6, + 0x00000001, 0x00000028, 0x00000504, 0x00004FBE, 0x000500C3, 0x0000001A, 0x00003803, 0x00003C10, + 0x00000302, 0x0004006F, 0x0000001D, 0x000019D0, 0x00003803, 0x0005008E, 0x0000001D, 0x00004748, + 0x000019D0, 0x00000A38, 0x0007000C, 0x0000001D, 0x00005E07, 0x00000001, 0x00000028, 0x00000504, + 0x00004748, 0x00050051, 0x0000000D, 0x00005F0B, 0x00005DB6, 0x00000000, 0x00050051, 0x0000000D, + 0x000037F0, 0x00005E07, 0x00000000, 0x00050050, 0x00000013, 0x00004B23, 0x00005F0B, 0x000037F0, + 0x0006000C, 0x0000000B, 0x00002174, 0x00000001, 0x0000003A, 0x00004B23, 0x00050051, 0x0000000D, + 0x00005BC2, 0x00005DB6, 0x00000001, 0x00050051, 0x0000000D, 0x000039AA, 0x00005E07, 0x00000001, + 0x00050050, 0x00000013, 0x00004B24, 0x00005BC2, 0x000039AA, 0x0006000C, 0x0000000B, 0x00002175, + 0x00000001, 0x0000003A, 0x00004B24, 0x00050051, 0x0000000D, 0x00005BC3, 0x00005DB6, 0x00000002, + 0x00050051, 0x0000000D, 0x000039AB, 0x00005E07, 0x00000002, 0x00050050, 0x00000013, 0x00004B25, + 0x00005BC3, 0x000039AB, 0x0006000C, 0x0000000B, 0x00002176, 0x00000001, 0x0000003A, 0x00004B25, + 0x00050051, 0x0000000D, 0x00005BC4, 0x00005DB6, 0x00000003, 0x00050051, 0x0000000D, 0x000039AC, + 0x00005E07, 0x00000003, 0x00050050, 0x00000013, 0x00004B0E, 0x00005BC4, 0x000039AC, 0x0006000C, + 0x0000000B, 0x000020EF, 0x00000001, 0x0000003A, 0x00004B0E, 0x00070050, 0x00000017, 0x00003ABC, + 0x00002174, 0x00002175, 0x00002176, 0x000020EF, 0x00060041, 0x00000294, 0x00004EBE, 0x0000140E, + 0x00000A0B, 0x00003CAC, 0x0003003E, 0x00004EBE, 0x00003ABC, 0x000200F9, 0x00004C7A, 0x000200F8, + 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r16_unorm_float_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r16_unorm_float_cs.h new file mode 100644 index 0000000..bb964b7 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r16_unorm_float_cs.h @@ -0,0 +1,578 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25059 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %uint_65535 = OpConstant %uint 65535 +%float_1_52590219en05 = OpConstant %float 1.52590219e-05 + %uint_16 = OpConstant %uint 16 + %uint_0 = OpConstant %uint 0 + %v2float = OpTypeVector %float 2 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %uint_3 = OpConstant %uint 3 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 + %uint_64 = OpConstant %uint 64 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2612 = OpConstantComposite %v3uint %uint_4 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %850 = OpConstantComposite %v4uint %uint_65535 %uint_65535 %uint_65535 %uint_65535 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2612 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_2 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_7 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_7 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_7 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_8 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_1 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %6362 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %22810 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %8801 = OpLoad %v4uint %17173 + %21106 = OpIEqual %bool %25058 %uint_1 + OpSelectionMerge %13962 None + OpBranchConditional %21106 %10583 %13962 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %8801 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %8801 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13962 + %13962 = OpLabel + %16606 = OpPhi %v4uint %8801 %24387 %16376 %10583 + %18240 = OpBitwiseAnd %v4uint %16606 %850 + %9137 = OpConvertUToF %v4float %18240 + %19365 = OpVectorTimesScalar %v4float %9137 %float_1_52590219en05 + %23367 = OpShiftRightLogical %v4uint %16606 %749 + %18492 = OpConvertUToF %v4float %23367 + %18450 = OpVectorTimesScalar %v4float %18492 %float_1_52590219en05 + %6268 = OpCompositeExtract %float %19365 0 + %13806 = OpCompositeExtract %float %18450 0 + %19232 = OpCompositeConstruct %v2float %6268 %13806 + %8561 = OpExtInst %uint %1 PackHalf2x16 %19232 + %23487 = OpCompositeExtract %float %19365 1 + %14759 = OpCompositeExtract %float %18450 1 + %19233 = OpCompositeConstruct %v2float %23487 %14759 + %8562 = OpExtInst %uint %1 PackHalf2x16 %19233 + %23488 = OpCompositeExtract %float %19365 2 + %14760 = OpCompositeExtract %float %18450 2 + %19234 = OpCompositeConstruct %v2float %23488 %14760 + %8563 = OpExtInst %uint %1 PackHalf2x16 %19234 + %23489 = OpCompositeExtract %float %19365 3 + %14761 = OpCompositeExtract %float %18450 3 + %19213 = OpCompositeConstruct %v2float %23489 %14761 + %8430 = OpExtInst %uint %1 PackHalf2x16 %19213 + %15035 = OpCompositeConstruct %v4uint %8561 %8562 %8563 %8430 + %17859 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %17859 %15035 + %21686 = OpIAdd %uint %21685 %int_1 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_64 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %13963 None + OpBranchConditional %21106 %10584 %13963 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %13963 + %13963 = OpLabel + %16607 = OpPhi %v4uint %6578 %6871 %16377 %10584 + %18241 = OpBitwiseAnd %v4uint %16607 %850 + %9138 = OpConvertUToF %v4float %18241 + %19366 = OpVectorTimesScalar %v4float %9138 %float_1_52590219en05 + %23368 = OpShiftRightLogical %v4uint %16607 %749 + %18493 = OpConvertUToF %v4float %23368 + %18451 = OpVectorTimesScalar %v4float %18493 %float_1_52590219en05 + %6269 = OpCompositeExtract %float %19366 0 + %13807 = OpCompositeExtract %float %18451 0 + %19235 = OpCompositeConstruct %v2float %6269 %13807 + %8564 = OpExtInst %uint %1 PackHalf2x16 %19235 + %23490 = OpCompositeExtract %float %19366 1 + %14762 = OpCompositeExtract %float %18451 1 + %19236 = OpCompositeConstruct %v2float %23490 %14762 + %8565 = OpExtInst %uint %1 PackHalf2x16 %19236 + %23491 = OpCompositeExtract %float %19366 2 + %14763 = OpCompositeExtract %float %18451 2 + %19237 = OpCompositeConstruct %v2float %23491 %14763 + %8566 = OpExtInst %uint %1 PackHalf2x16 %19237 + %23492 = OpCompositeExtract %float %19366 3 + %14764 = OpCompositeExtract %float %18451 3 + %19214 = OpCompositeConstruct %v2float %23492 %14764 + %8431 = OpExtInst %uint %1 PackHalf2x16 %19214 + %15036 = OpCompositeConstruct %v4uint %8564 %8565 %8566 %8431 + %20158 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21686 + OpStore %20158 %15036 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r16_unorm_float_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000061E3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, + 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x0004002B, + 0x0000000B, 0x000001C1, 0x0000FFFF, 0x0004002B, 0x0000000D, 0x0000092A, 0x37800080, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x00040017, + 0x00000013, 0x0000000D, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, + 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, + 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, + 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, + 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, + 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, + 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, + 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, + 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, + 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, + 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, + 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, + 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, + 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0004002B, + 0x0000000B, 0x00000ACA, 0x00000040, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, + 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, + 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x00040020, 0x00000291, 0x00000009, + 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, + 0x00000001, 0x0006002C, 0x00000014, 0x00000A34, 0x00000A16, 0x00000A0A, 0x00000A0A, 0x00040017, + 0x0000000F, 0x00000009, 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, + 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, + 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, + 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, + 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, + 0x00000A0D, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, + 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, + 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, + 0x00000352, 0x000001C1, 0x000001C1, 0x000001C1, 0x000001C1, 0x0007002C, 0x00000017, 0x000002ED, + 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, + 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, + 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, + 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, + 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, + 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, + 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, + 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, + 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, + 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, + 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, + 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, + 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, + 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, + 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, + 0x00000A34, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, + 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, + 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, + 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, + 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, + 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, + 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A11, + 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, + 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, + 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, + 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, + 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, + 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, + 0x0000000B, 0x000054B5, 0x00002764, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, + 0x00004376, 0x00005768, 0x000051F2, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, + 0x000400FA, 0x00004384, 0x00002BF8, 0x000018D9, 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, + 0x000032B3, 0x000044BE, 0x00000A17, 0x000500C3, 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, + 0x000500C2, 0x0000000B, 0x00004947, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, + 0x00004947, 0x00050084, 0x0000000C, 0x00005321, 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, + 0x00003B27, 0x000032B3, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, + 0x0004007C, 0x0000000C, 0x00003901, 0x00002348, 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, + 0x00003901, 0x000500C3, 0x0000000C, 0x000032BA, 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, + 0x00005FEE, 0x000032BA, 0x000020F4, 0x000500C4, 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A1F, + 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, + 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, + 0x0000000C, 0x00003138, 0x000044BE, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, + 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, + 0x00001B88, 0x0000434B, 0x00000A1F, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, + 0x000500C3, 0x0000000C, 0x00002215, 0x000044BE, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, + 0x00002215, 0x0000601E, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, + 0x0000000C, 0x00004112, 0x00005BEB, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, + 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, + 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, + 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, + 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, + 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, + 0x000047B4, 0x000018DA, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A1F, + 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, + 0x000044BE, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, + 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, + 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, + 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, + 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, + 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, + 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, + 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, + 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, + 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, + 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, + 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, + 0x00005B4D, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, + 0x0000000C, 0x00005347, 0x0000405C, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, + 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A22, 0x000500C7, 0x0000000C, + 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, + 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, + 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A0D, 0x000500C7, + 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, + 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, + 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, + 0x000500C7, 0x0000000C, 0x000047B5, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, + 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, + 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, + 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, + 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, + 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, + 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, + 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, + 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, + 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, + 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, + 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, + 0x00005F43, 0x000200F8, 0x000051F2, 0x0004007C, 0x0000000C, 0x00003CBC, 0x00005789, 0x00050084, + 0x0000000C, 0x000060B8, 0x000018DA, 0x00003CBC, 0x00050080, 0x0000000C, 0x0000208E, 0x000060B8, + 0x000044BE, 0x0004007C, 0x0000000C, 0x000022F8, 0x00005788, 0x00050084, 0x0000000C, 0x00001E9F, + 0x0000208E, 0x000022F8, 0x00050080, 0x0000000C, 0x00001F30, 0x0000591A, 0x00001E9F, 0x000200F9, + 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, + 0x00001F30, 0x000051F2, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, + 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, + 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, 0x00004315, 0x0000107A, + 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00002261, 0x00004315, 0x000500AA, 0x00000009, + 0x00005272, 0x000061E2, 0x00000A0D, 0x000300F7, 0x0000368A, 0x00000000, 0x000400FA, 0x00005272, + 0x00002957, 0x0000368A, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00002261, + 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, + 0x000050AC, 0x00002261, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, + 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x0000368A, 0x000200F8, + 0x0000368A, 0x000700F5, 0x00000017, 0x000040DE, 0x00002261, 0x00005F43, 0x00003FF8, 0x00002957, + 0x000500C7, 0x00000017, 0x00004740, 0x000040DE, 0x00000352, 0x00040070, 0x0000001D, 0x000023B1, + 0x00004740, 0x0005008E, 0x0000001D, 0x00004BA5, 0x000023B1, 0x0000092A, 0x000500C2, 0x00000017, + 0x00005B47, 0x000040DE, 0x000002ED, 0x00040070, 0x0000001D, 0x0000483C, 0x00005B47, 0x0005008E, + 0x0000001D, 0x00004812, 0x0000483C, 0x0000092A, 0x00050051, 0x0000000D, 0x0000187C, 0x00004BA5, + 0x00000000, 0x00050051, 0x0000000D, 0x000035EE, 0x00004812, 0x00000000, 0x00050050, 0x00000013, + 0x00004B20, 0x0000187C, 0x000035EE, 0x0006000C, 0x0000000B, 0x00002171, 0x00000001, 0x0000003A, + 0x00004B20, 0x00050051, 0x0000000D, 0x00005BBF, 0x00004BA5, 0x00000001, 0x00050051, 0x0000000D, + 0x000039A7, 0x00004812, 0x00000001, 0x00050050, 0x00000013, 0x00004B21, 0x00005BBF, 0x000039A7, + 0x0006000C, 0x0000000B, 0x00002172, 0x00000001, 0x0000003A, 0x00004B21, 0x00050051, 0x0000000D, + 0x00005BC0, 0x00004BA5, 0x00000002, 0x00050051, 0x0000000D, 0x000039A8, 0x00004812, 0x00000002, + 0x00050050, 0x00000013, 0x00004B22, 0x00005BC0, 0x000039A8, 0x0006000C, 0x0000000B, 0x00002173, + 0x00000001, 0x0000003A, 0x00004B22, 0x00050051, 0x0000000D, 0x00005BC1, 0x00004BA5, 0x00000003, + 0x00050051, 0x0000000D, 0x000039A9, 0x00004812, 0x00000003, 0x00050050, 0x00000013, 0x00004B0D, + 0x00005BC1, 0x000039A9, 0x0006000C, 0x0000000B, 0x000020EE, 0x00000001, 0x0000003A, 0x00004B0D, + 0x00070050, 0x00000017, 0x00003ABB, 0x00002171, 0x00002172, 0x00002173, 0x000020EE, 0x00060041, + 0x00000294, 0x000045C3, 0x0000140E, 0x00000A0B, 0x000054B5, 0x0003003E, 0x000045C3, 0x00003ABB, + 0x00050080, 0x0000000B, 0x000054B6, 0x000054B5, 0x00000A0E, 0x000300F7, 0x00001AD7, 0x00000002, + 0x000400FA, 0x00004376, 0x000055E9, 0x00001C25, 0x000200F8, 0x000055E9, 0x000200F9, 0x00001AD7, + 0x000200F8, 0x00001C25, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001AD7, 0x000700F5, 0x0000000B, + 0x0000456F, 0x00000ACA, 0x000055E9, 0x00000A3A, 0x00001C25, 0x000500C2, 0x0000000B, 0x000041C0, + 0x0000456F, 0x00000A16, 0x00050080, 0x0000000B, 0x00002ADB, 0x00005665, 0x000041C0, 0x00060041, + 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, 0x00002ADB, 0x0004003D, 0x00000017, 0x000019B2, + 0x0000571A, 0x000300F7, 0x0000368B, 0x00000000, 0x000400FA, 0x00005272, 0x00002958, 0x0000368B, + 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, + 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, + 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, + 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x0000368B, 0x000200F8, 0x0000368B, 0x000700F5, + 0x00000017, 0x000040DF, 0x000019B2, 0x00001AD7, 0x00003FF9, 0x00002958, 0x000500C7, 0x00000017, + 0x00004741, 0x000040DF, 0x00000352, 0x00040070, 0x0000001D, 0x000023B2, 0x00004741, 0x0005008E, + 0x0000001D, 0x00004BA6, 0x000023B2, 0x0000092A, 0x000500C2, 0x00000017, 0x00005B48, 0x000040DF, + 0x000002ED, 0x00040070, 0x0000001D, 0x0000483D, 0x00005B48, 0x0005008E, 0x0000001D, 0x00004813, + 0x0000483D, 0x0000092A, 0x00050051, 0x0000000D, 0x0000187D, 0x00004BA6, 0x00000000, 0x00050051, + 0x0000000D, 0x000035EF, 0x00004813, 0x00000000, 0x00050050, 0x00000013, 0x00004B23, 0x0000187D, + 0x000035EF, 0x0006000C, 0x0000000B, 0x00002174, 0x00000001, 0x0000003A, 0x00004B23, 0x00050051, + 0x0000000D, 0x00005BC2, 0x00004BA6, 0x00000001, 0x00050051, 0x0000000D, 0x000039AA, 0x00004813, + 0x00000001, 0x00050050, 0x00000013, 0x00004B24, 0x00005BC2, 0x000039AA, 0x0006000C, 0x0000000B, + 0x00002175, 0x00000001, 0x0000003A, 0x00004B24, 0x00050051, 0x0000000D, 0x00005BC3, 0x00004BA6, + 0x00000002, 0x00050051, 0x0000000D, 0x000039AB, 0x00004813, 0x00000002, 0x00050050, 0x00000013, + 0x00004B25, 0x00005BC3, 0x000039AB, 0x0006000C, 0x0000000B, 0x00002176, 0x00000001, 0x0000003A, + 0x00004B25, 0x00050051, 0x0000000D, 0x00005BC4, 0x00004BA6, 0x00000003, 0x00050051, 0x0000000D, + 0x000039AC, 0x00004813, 0x00000003, 0x00050050, 0x00000013, 0x00004B0E, 0x00005BC4, 0x000039AC, + 0x0006000C, 0x0000000B, 0x000020EF, 0x00000001, 0x0000003A, 0x00004B0E, 0x00070050, 0x00000017, + 0x00003ABC, 0x00002174, 0x00002175, 0x00002176, 0x000020EF, 0x00060041, 0x00000294, 0x00004EBE, + 0x0000140E, 0x00000A0B, 0x000054B6, 0x0003003E, 0x00004EBE, 0x00003ABC, 0x000200F9, 0x00004C7A, + 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r16_unorm_float_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r16_unorm_float_scaled_cs.h new file mode 100644 index 0000000..d3f7bb7 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r16_unorm_float_scaled_cs.h @@ -0,0 +1,639 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %uint_65535 = OpConstant %uint 65535 +%float_1_52590219en05 = OpConstant %float 1.52590219e-05 + %uint_16 = OpConstant %uint 16 + %uint_0 = OpConstant %uint 0 + %v2float = OpTypeVector %float 2 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %uint_3 = OpConstant %uint 3 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 + %uint_64 = OpConstant %uint 64 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2612 = OpConstantComposite %v3uint %uint_4 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %850 = OpConstantComposite %v4uint %uint_65535 %uint_65535 %uint_65535 %uint_65535 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2612 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_2 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_3 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_3 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_7 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_7 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_7 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_8 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_1 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_3 + %23219 = OpBitwiseAnd %uint %10722 %uint_7 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_1 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %8801 = OpLoad %v4uint %20399 + %21106 = OpIEqual %bool %24990 %uint_1 + OpSelectionMerge %13962 None + OpBranchConditional %21106 %10583 %13962 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %8801 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %8801 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13962 + %13962 = OpLabel + %16606 = OpPhi %v4uint %8801 %21313 %16376 %10583 + %18240 = OpBitwiseAnd %v4uint %16606 %850 + %9137 = OpConvertUToF %v4float %18240 + %19365 = OpVectorTimesScalar %v4float %9137 %float_1_52590219en05 + %23367 = OpShiftRightLogical %v4uint %16606 %749 + %18492 = OpConvertUToF %v4float %23367 + %18450 = OpVectorTimesScalar %v4float %18492 %float_1_52590219en05 + %6268 = OpCompositeExtract %float %19365 0 + %13806 = OpCompositeExtract %float %18450 0 + %19232 = OpCompositeConstruct %v2float %6268 %13806 + %8561 = OpExtInst %uint %1 PackHalf2x16 %19232 + %23487 = OpCompositeExtract %float %19365 1 + %14759 = OpCompositeExtract %float %18450 1 + %19233 = OpCompositeConstruct %v2float %23487 %14759 + %8562 = OpExtInst %uint %1 PackHalf2x16 %19233 + %23488 = OpCompositeExtract %float %19365 2 + %14760 = OpCompositeExtract %float %18450 2 + %19234 = OpCompositeConstruct %v2float %23488 %14760 + %8563 = OpExtInst %uint %1 PackHalf2x16 %19234 + %23489 = OpCompositeExtract %float %19365 3 + %14761 = OpCompositeExtract %float %18450 3 + %19213 = OpCompositeConstruct %v2float %23489 %14761 + %8430 = OpExtInst %uint %1 PackHalf2x16 %19213 + %15035 = OpCompositeConstruct %v4uint %8561 %8562 %8563 %8430 + %17859 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %17859 %15035 + %15532 = OpIAdd %uint %11197 %int_1 + %6417 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %6417 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_64 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_64 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %13963 None + OpBranchConditional %21106 %10584 %13963 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %13963 + %13963 = OpLabel + %16607 = OpPhi %v4uint %6578 %24764 %16377 %10584 + %18241 = OpBitwiseAnd %v4uint %16607 %850 + %9138 = OpConvertUToF %v4float %18241 + %19366 = OpVectorTimesScalar %v4float %9138 %float_1_52590219en05 + %23368 = OpShiftRightLogical %v4uint %16607 %749 + %18493 = OpConvertUToF %v4float %23368 + %18451 = OpVectorTimesScalar %v4float %18493 %float_1_52590219en05 + %6269 = OpCompositeExtract %float %19366 0 + %13807 = OpCompositeExtract %float %18451 0 + %19235 = OpCompositeConstruct %v2float %6269 %13807 + %8564 = OpExtInst %uint %1 PackHalf2x16 %19235 + %23490 = OpCompositeExtract %float %19366 1 + %14762 = OpCompositeExtract %float %18451 1 + %19236 = OpCompositeConstruct %v2float %23490 %14762 + %8565 = OpExtInst %uint %1 PackHalf2x16 %19236 + %23491 = OpCompositeExtract %float %19366 2 + %14763 = OpCompositeExtract %float %18451 2 + %19237 = OpCompositeConstruct %v2float %23491 %14763 + %8566 = OpExtInst %uint %1 PackHalf2x16 %19237 + %23492 = OpCompositeExtract %float %19366 3 + %14764 = OpCompositeExtract %float %18451 3 + %19214 = OpCompositeConstruct %v2float %23492 %14764 + %8431 = OpExtInst %uint %1 PackHalf2x16 %19214 + %15036 = OpCompositeConstruct %v4uint %8564 %8565 %8566 %8431 + %20158 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15532 + OpStore %20158 %15036 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r16_unorm_float_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x0004002B, + 0x0000000B, 0x000001C1, 0x0000FFFF, 0x0004002B, 0x0000000D, 0x0000092A, 0x37800080, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x00040017, + 0x00000013, 0x0000000D, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, + 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, + 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, + 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, + 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, + 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, + 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, + 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, + 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, + 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, + 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, + 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, + 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, + 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0004002B, + 0x0000000B, 0x00000ACA, 0x00000040, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, + 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, + 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, 0x00000787, + 0x00000A16, 0x00000A1F, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, + 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, + 0x00000A34, 0x00000A16, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, + 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, + 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, 0x00000011, + 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, + 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, + 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, + 0x0007002C, 0x00000017, 0x00000352, 0x000001C1, 0x000001C1, 0x000001C1, 0x000001C1, 0x0007002C, + 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00050036, 0x00000008, + 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, + 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, + 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, + 0x00005F7D, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x000048EB, 0x00005F7D, 0x00000A0A, + 0x000500C2, 0x0000000B, 0x00001FCD, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x0000619E, + 0x00001FCD, 0x00000A13, 0x00050050, 0x00000011, 0x000022A7, 0x00003526, 0x00003526, 0x000500C2, + 0x00000011, 0x00001BAF, 0x000022A7, 0x00000787, 0x000500C7, 0x00000011, 0x00001997, 0x00001BAF, + 0x000007A2, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, + 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, + 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, + 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, + 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, + 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, + 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, + 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A34, + 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, + 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, + 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, + 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, + 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, + 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A11, 0x00050051, + 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, + 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, + 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, + 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, + 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, + 0x00002042, 0x00050080, 0x0000000B, 0x00001B12, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, + 0x00002BBD, 0x00001B12, 0x00000A16, 0x00050051, 0x0000000B, 0x000029E2, 0x0000538B, 0x00000000, + 0x000500C2, 0x0000000B, 0x00001DEE, 0x000029E2, 0x00000A13, 0x00050051, 0x0000000B, 0x00002704, + 0x0000538B, 0x00000001, 0x00050050, 0x00000011, 0x00005C0B, 0x00001DEE, 0x00002704, 0x00050086, + 0x00000011, 0x00001F69, 0x00005C0B, 0x00001997, 0x00050051, 0x0000000B, 0x0000366C, 0x00001F69, + 0x00000000, 0x000500C4, 0x0000000B, 0x00004D4D, 0x0000366C, 0x00000A13, 0x00050051, 0x0000000B, + 0x000051A9, 0x00001F69, 0x00000001, 0x00050051, 0x0000000B, 0x000059EE, 0x0000538B, 0x00000002, + 0x00060050, 0x00000014, 0x000024C9, 0x00004D4D, 0x000051A9, 0x000059EE, 0x000300F7, 0x00005341, + 0x00000002, 0x000400FA, 0x000048EB, 0x0000537D, 0x00002DD9, 0x000200F8, 0x0000537D, 0x0004007C, + 0x00000016, 0x00002970, 0x000024C9, 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, + 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, + 0x00002970, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, + 0x0000000B, 0x00005B4D, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, + 0x00050084, 0x0000000C, 0x00005321, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, + 0x000024FD, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, + 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, + 0x00050051, 0x0000000C, 0x00006242, 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, + 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, + 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A1F, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, + 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, + 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, + 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, + 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A1F, 0x000500C3, + 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, + 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, + 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, + 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, + 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, + 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A1F, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, + 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, + 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, + 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, + 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, + 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, + 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, + 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, + 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x00004158, + 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, + 0x0000566F, 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, 0x00002DD9, 0x0007004F, 0x00000011, + 0x00002621, 0x000024C9, 0x000024C9, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000059CF, + 0x00002621, 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, 0x00000000, 0x000500C3, 0x0000000C, + 0x000024FE, 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002748, 0x000059CF, 0x00000001, + 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4E, + 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, + 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FE, 0x00005347, + 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002AB6, + 0x00001903, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002748, 0x00000A35, 0x000500C4, + 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, + 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A0D, 0x000500C7, 0x0000000C, + 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, + 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, + 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, + 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, + 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, + 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, + 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, + 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, + 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, + 0x000500C3, 0x0000000C, 0x00001EEC, 0x00001903, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, + 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, + 0x0000544F, 0x000500C7, 0x0000000C, 0x00002E06, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, + 0x0000394F, 0x00003C4D, 0x00002E06, 0x0004007C, 0x0000000B, 0x00005670, 0x0000394F, 0x000200F9, + 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, 0x000024FC, 0x0000566F, 0x0000537D, + 0x00005670, 0x00002DD9, 0x00050084, 0x00000011, 0x00003FA8, 0x00001F69, 0x00001997, 0x00050082, + 0x00000011, 0x00003BBC, 0x00005C0B, 0x00003FA8, 0x00050051, 0x0000000B, 0x00001C87, 0x00001997, + 0x00000000, 0x00050051, 0x0000000B, 0x00005962, 0x00001997, 0x00000001, 0x00050084, 0x0000000B, + 0x00003372, 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, 0x00003CA0, 0x000024FC, 0x00003372, + 0x00050051, 0x0000000B, 0x00003ED4, 0x00003BBC, 0x00000000, 0x00050084, 0x0000000B, 0x00003E12, + 0x00003ED4, 0x00005962, 0x00050051, 0x0000000B, 0x00001AE6, 0x00003BBC, 0x00000001, 0x00050080, + 0x0000000B, 0x00002B25, 0x00003E12, 0x00001AE6, 0x000500C4, 0x0000000B, 0x0000609D, 0x00002B25, + 0x00000A13, 0x000500C7, 0x0000000B, 0x00005AB3, 0x000029E2, 0x00000A1F, 0x00050080, 0x0000000B, + 0x00002557, 0x0000609D, 0x00005AB3, 0x000500C4, 0x0000000B, 0x000040AD, 0x00002557, 0x00000A0D, + 0x00050080, 0x0000000B, 0x00004EAA, 0x00003CA0, 0x000040AD, 0x00050080, 0x0000000B, 0x00003BA9, + 0x00005EAC, 0x00004EAA, 0x000500C2, 0x0000000B, 0x00003948, 0x00003BA9, 0x00000A16, 0x00060041, + 0x00000294, 0x00004FAF, 0x0000107A, 0x00000A0B, 0x00003948, 0x0004003D, 0x00000017, 0x00002261, + 0x00004FAF, 0x000500AA, 0x00000009, 0x00005272, 0x0000619E, 0x00000A0D, 0x000300F7, 0x0000368A, + 0x00000000, 0x000400FA, 0x00005272, 0x00002957, 0x0000368A, 0x000200F8, 0x00002957, 0x000500C7, + 0x00000017, 0x0000475F, 0x00002261, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00002261, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, + 0x000200F9, 0x0000368A, 0x000200F8, 0x0000368A, 0x000700F5, 0x00000017, 0x000040DE, 0x00002261, + 0x00005341, 0x00003FF8, 0x00002957, 0x000500C7, 0x00000017, 0x00004740, 0x000040DE, 0x00000352, + 0x00040070, 0x0000001D, 0x000023B1, 0x00004740, 0x0005008E, 0x0000001D, 0x00004BA5, 0x000023B1, + 0x0000092A, 0x000500C2, 0x00000017, 0x00005B47, 0x000040DE, 0x000002ED, 0x00040070, 0x0000001D, + 0x0000483C, 0x00005B47, 0x0005008E, 0x0000001D, 0x00004812, 0x0000483C, 0x0000092A, 0x00050051, + 0x0000000D, 0x0000187C, 0x00004BA5, 0x00000000, 0x00050051, 0x0000000D, 0x000035EE, 0x00004812, + 0x00000000, 0x00050050, 0x00000013, 0x00004B20, 0x0000187C, 0x000035EE, 0x0006000C, 0x0000000B, + 0x00002171, 0x00000001, 0x0000003A, 0x00004B20, 0x00050051, 0x0000000D, 0x00005BBF, 0x00004BA5, + 0x00000001, 0x00050051, 0x0000000D, 0x000039A7, 0x00004812, 0x00000001, 0x00050050, 0x00000013, + 0x00004B21, 0x00005BBF, 0x000039A7, 0x0006000C, 0x0000000B, 0x00002172, 0x00000001, 0x0000003A, + 0x00004B21, 0x00050051, 0x0000000D, 0x00005BC0, 0x00004BA5, 0x00000002, 0x00050051, 0x0000000D, + 0x000039A8, 0x00004812, 0x00000002, 0x00050050, 0x00000013, 0x00004B22, 0x00005BC0, 0x000039A8, + 0x0006000C, 0x0000000B, 0x00002173, 0x00000001, 0x0000003A, 0x00004B22, 0x00050051, 0x0000000D, + 0x00005BC1, 0x00004BA5, 0x00000003, 0x00050051, 0x0000000D, 0x000039A9, 0x00004812, 0x00000003, + 0x00050050, 0x00000013, 0x00004B0D, 0x00005BC1, 0x000039A9, 0x0006000C, 0x0000000B, 0x000020EE, + 0x00000001, 0x0000003A, 0x00004B0D, 0x00070050, 0x00000017, 0x00003ABB, 0x00002171, 0x00002172, + 0x00002173, 0x000020EE, 0x00060041, 0x00000294, 0x000045C3, 0x0000140E, 0x00000A0B, 0x00002BBD, + 0x0003003E, 0x000045C3, 0x00003ABB, 0x00050080, 0x0000000B, 0x00003CAC, 0x00002BBD, 0x00000A0E, + 0x000500AC, 0x00000009, 0x00001911, 0x00001C87, 0x00000A0D, 0x000300F7, 0x000060BC, 0x00000002, + 0x000400FA, 0x00001911, 0x00005084, 0x00005094, 0x000200F8, 0x00005084, 0x00050086, 0x0000000B, + 0x00003697, 0x00001DEE, 0x00001C87, 0x00050084, 0x0000000B, 0x0000237E, 0x00003697, 0x00001C87, + 0x00050082, 0x0000000B, 0x00003171, 0x00001DEE, 0x0000237E, 0x00050080, 0x0000000B, 0x00002527, + 0x00003171, 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, 0x00001C87, 0x000300F7, + 0x00001EED, 0x00000000, 0x000400FA, 0x0000343F, 0x0000569E, 0x00002191, 0x000200F8, 0x0000569E, + 0x00050084, 0x0000000B, 0x00004B59, 0x00000ACA, 0x00001C87, 0x000500C4, 0x0000000B, 0x0000540F, + 0x00003171, 0x00000A16, 0x00050082, 0x0000000B, 0x00004944, 0x00004B59, 0x0000540F, 0x000200F9, + 0x00001EED, 0x000200F8, 0x00002191, 0x000200F9, 0x00001EED, 0x000200F8, 0x00001EED, 0x000700F5, + 0x0000000B, 0x0000292C, 0x00004944, 0x0000569E, 0x00000A3A, 0x00002191, 0x000200F9, 0x000060BC, + 0x000200F8, 0x00005094, 0x000200F9, 0x000060BC, 0x000200F8, 0x000060BC, 0x000700F5, 0x0000000B, + 0x000029BC, 0x0000292C, 0x00001EED, 0x00000ACA, 0x00005094, 0x00050084, 0x0000000B, 0x0000492B, + 0x000029BC, 0x00005962, 0x000500C2, 0x0000000B, 0x0000406D, 0x0000492B, 0x00000A16, 0x00050080, + 0x0000000B, 0x0000336B, 0x00003948, 0x0000406D, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, + 0x00000A0B, 0x0000336B, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x0000368B, + 0x00000000, 0x000400FA, 0x00005272, 0x00002958, 0x0000368B, 0x000200F8, 0x00002958, 0x000500C7, + 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, + 0x000200F9, 0x0000368B, 0x000200F8, 0x0000368B, 0x000700F5, 0x00000017, 0x000040DF, 0x000019B2, + 0x000060BC, 0x00003FF9, 0x00002958, 0x000500C7, 0x00000017, 0x00004741, 0x000040DF, 0x00000352, + 0x00040070, 0x0000001D, 0x000023B2, 0x00004741, 0x0005008E, 0x0000001D, 0x00004BA6, 0x000023B2, + 0x0000092A, 0x000500C2, 0x00000017, 0x00005B48, 0x000040DF, 0x000002ED, 0x00040070, 0x0000001D, + 0x0000483D, 0x00005B48, 0x0005008E, 0x0000001D, 0x00004813, 0x0000483D, 0x0000092A, 0x00050051, + 0x0000000D, 0x0000187D, 0x00004BA6, 0x00000000, 0x00050051, 0x0000000D, 0x000035EF, 0x00004813, + 0x00000000, 0x00050050, 0x00000013, 0x00004B23, 0x0000187D, 0x000035EF, 0x0006000C, 0x0000000B, + 0x00002174, 0x00000001, 0x0000003A, 0x00004B23, 0x00050051, 0x0000000D, 0x00005BC2, 0x00004BA6, + 0x00000001, 0x00050051, 0x0000000D, 0x000039AA, 0x00004813, 0x00000001, 0x00050050, 0x00000013, + 0x00004B24, 0x00005BC2, 0x000039AA, 0x0006000C, 0x0000000B, 0x00002175, 0x00000001, 0x0000003A, + 0x00004B24, 0x00050051, 0x0000000D, 0x00005BC3, 0x00004BA6, 0x00000002, 0x00050051, 0x0000000D, + 0x000039AB, 0x00004813, 0x00000002, 0x00050050, 0x00000013, 0x00004B25, 0x00005BC3, 0x000039AB, + 0x0006000C, 0x0000000B, 0x00002176, 0x00000001, 0x0000003A, 0x00004B25, 0x00050051, 0x0000000D, + 0x00005BC4, 0x00004BA6, 0x00000003, 0x00050051, 0x0000000D, 0x000039AC, 0x00004813, 0x00000003, + 0x00050050, 0x00000013, 0x00004B0E, 0x00005BC4, 0x000039AC, 0x0006000C, 0x0000000B, 0x000020EF, + 0x00000001, 0x0000003A, 0x00004B0E, 0x00070050, 0x00000017, 0x00003ABC, 0x00002174, 0x00002175, + 0x00002176, 0x000020EF, 0x00060041, 0x00000294, 0x00004EBE, 0x0000140E, 0x00000A0B, 0x00003CAC, + 0x0003003E, 0x00004EBE, 0x00003ABC, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, + 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r4g4b4a4_a4r4g4b4_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r4g4b4a4_a4r4g4b4_cs.h new file mode 100644 index 0000000..466ec04 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r4g4b4a4_a4r4g4b4_cs.h @@ -0,0 +1,519 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25059 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 +%uint_268374015 = OpConstant %uint 268374015 + %uint_4 = OpConstant %uint 4 +%uint_4026593280 = OpConstant %uint 4026593280 + %uint_12 = OpConstant %uint 12 + %uint_1 = OpConstant %uint 1 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_2 = OpConstant %uint 2 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_3 = OpConstant %uint 3 + %uint_32 = OpConstant %uint 32 + %uint_64 = OpConstant %uint 64 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2612 = OpConstantComposite %v3uint %uint_4 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %1930 = OpConstantComposite %v4uint %uint_268374015 %uint_268374015 %uint_268374015 %uint_268374015 + %101 = OpConstantComposite %v4uint %uint_4 %uint_4 %uint_4 %uint_4 + %2418 = OpConstantComposite %v4uint %uint_4026593280 %uint_4026593280 %uint_4026593280 %uint_4026593280 + %533 = OpConstantComposite %v4uint %uint_12 %uint_12 %uint_12 %uint_12 + %uint_16 = OpConstant %uint 16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2612 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_2 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_7 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_7 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_7 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_8 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_1 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %6362 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %22810 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %8801 = OpLoad %v4uint %17173 + %21106 = OpIEqual %bool %25058 %uint_1 + OpSelectionMerge %13962 None + OpBranchConditional %21106 %10583 %13962 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %8801 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %8801 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13962 + %13962 = OpLabel + %18202 = OpPhi %v4uint %8801 %24387 %16376 %10583 + %23862 = OpBitwiseAnd %v4uint %18202 %1930 + %10234 = OpShiftLeftLogical %v4uint %23862 %101 + %20653 = OpBitwiseAnd %v4uint %18202 %2418 + %14053 = OpShiftRightLogical %v4uint %20653 %533 + %6532 = OpBitwiseOr %v4uint %10234 %14053 + %20254 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %20254 %6532 + %21686 = OpIAdd %uint %21685 %int_1 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_64 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %13963 None + OpBranchConditional %21106 %10584 %13963 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20654 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20654 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %13963 + %13963 = OpLabel + %18203 = OpPhi %v4uint %6578 %6871 %16377 %10584 + %23863 = OpBitwiseAnd %v4uint %18203 %1930 + %10235 = OpShiftLeftLogical %v4uint %23863 %101 + %20655 = OpBitwiseAnd %v4uint %18203 %2418 + %14054 = OpShiftRightLogical %v4uint %20655 %533 + %6533 = OpBitwiseOr %v4uint %10235 %14054 + %22553 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21686 + OpStore %22553 %6533 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r4g4b4a4_a4r4g4b4_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000061E3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, + 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000501, 0x0FFF0FFF, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000B, 0x000009A2, 0xF000F000, 0x0004002B, 0x0000000B, 0x00000A2E, 0x0000000C, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0004002B, 0x0000000B, 0x00000ACA, 0x00000040, + 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, + 0x00000009, 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, + 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, + 0x00000A34, 0x00000A16, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, + 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, + 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0007002C, 0x00000017, + 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, + 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, + 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x0000078A, 0x00000501, 0x00000501, + 0x00000501, 0x00000501, 0x0007002C, 0x00000017, 0x00000065, 0x00000A16, 0x00000A16, 0x00000A16, + 0x00000A16, 0x0007002C, 0x00000017, 0x00000972, 0x000009A2, 0x000009A2, 0x000009A2, 0x000009A2, + 0x0007002C, 0x00000017, 0x00000215, 0x00000A2E, 0x00000A2E, 0x00000A2E, 0x00000A2E, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, + 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, + 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, + 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, + 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, + 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, + 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, + 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, + 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, + 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, + 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, + 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, + 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, + 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, + 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A34, + 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, + 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, + 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, + 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, + 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, + 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A11, 0x00050051, + 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, + 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, + 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, + 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, + 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, + 0x00002042, 0x00050080, 0x0000000B, 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, + 0x000054B5, 0x00002764, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, + 0x00005768, 0x000051F2, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, + 0x00004384, 0x00002BF8, 0x000018D9, 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, 0x000032B3, + 0x000044BE, 0x00000A17, 0x000500C3, 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, 0x000500C2, + 0x0000000B, 0x00004947, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00004947, + 0x00050084, 0x0000000C, 0x00005321, 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, + 0x000032B3, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, + 0x0000000C, 0x00003901, 0x00002348, 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, 0x00003901, + 0x000500C3, 0x0000000C, 0x000032BA, 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, 0x00005FEE, + 0x000032BA, 0x000020F4, 0x000500C4, 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A1F, 0x000500C7, + 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, + 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003138, 0x000044BE, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, + 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, + 0x0000434B, 0x00000A1F, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, + 0x0000000C, 0x00002215, 0x000044BE, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, + 0x0000601E, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, + 0x00004112, 0x00005BEB, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, + 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, + 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, + 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, + 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, + 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, + 0x000018DA, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A1F, 0x00050080, + 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000044BE, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, + 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, + 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, + 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, + 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, + 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, + 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, + 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, 0x000019AD, + 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, + 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, 0x00000001, + 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, + 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, 0x0000000C, + 0x00005347, 0x0000405C, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, + 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002AB6, + 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, 0x000500C4, + 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, + 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A0D, 0x000500C7, 0x0000000C, + 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, + 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, + 0x0000000C, 0x000047B5, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, + 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, + 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, + 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, + 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, + 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, + 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, + 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, + 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, + 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, + 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, + 0x0000000C, 0x0000292C, 0x000054ED, 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, 0x00005F43, + 0x000200F8, 0x000051F2, 0x0004007C, 0x0000000C, 0x00003CBC, 0x00005789, 0x00050084, 0x0000000C, + 0x000060B8, 0x000018DA, 0x00003CBC, 0x00050080, 0x0000000C, 0x0000208E, 0x000060B8, 0x000044BE, + 0x0004007C, 0x0000000C, 0x000022F8, 0x00005788, 0x00050084, 0x0000000C, 0x00001E9F, 0x0000208E, + 0x000022F8, 0x00050080, 0x0000000C, 0x00001F30, 0x0000591A, 0x00001E9F, 0x000200F9, 0x00005F43, + 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, 0x00001F30, + 0x000051F2, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, 0x000056CD, + 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, 0x0000000B, + 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, 0x00004315, 0x0000107A, 0x00000A0B, + 0x00005665, 0x0004003D, 0x00000017, 0x00002261, 0x00004315, 0x000500AA, 0x00000009, 0x00005272, + 0x000061E2, 0x00000A0D, 0x000300F7, 0x0000368A, 0x00000000, 0x000400FA, 0x00005272, 0x00002957, + 0x0000368A, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00002261, 0x000009CE, + 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, + 0x00002261, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, + 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x0000368A, 0x000200F8, 0x0000368A, + 0x000700F5, 0x00000017, 0x0000471A, 0x00002261, 0x00005F43, 0x00003FF8, 0x00002957, 0x000500C7, + 0x00000017, 0x00005D36, 0x0000471A, 0x0000078A, 0x000500C4, 0x00000017, 0x000027FA, 0x00005D36, + 0x00000065, 0x000500C7, 0x00000017, 0x000050AD, 0x0000471A, 0x00000972, 0x000500C2, 0x00000017, + 0x000036E5, 0x000050AD, 0x00000215, 0x000500C5, 0x00000017, 0x00001984, 0x000027FA, 0x000036E5, + 0x00060041, 0x00000294, 0x00004F1E, 0x0000140E, 0x00000A0B, 0x000054B5, 0x0003003E, 0x00004F1E, + 0x00001984, 0x00050080, 0x0000000B, 0x000054B6, 0x000054B5, 0x00000A0E, 0x000300F7, 0x00001AD7, + 0x00000002, 0x000400FA, 0x00004376, 0x000055E9, 0x00001C25, 0x000200F8, 0x000055E9, 0x000200F9, + 0x00001AD7, 0x000200F8, 0x00001C25, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001AD7, 0x000700F5, + 0x0000000B, 0x0000456F, 0x00000ACA, 0x000055E9, 0x00000A3A, 0x00001C25, 0x000500C2, 0x0000000B, + 0x000041C0, 0x0000456F, 0x00000A16, 0x00050080, 0x0000000B, 0x00002ADB, 0x00005665, 0x000041C0, + 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, 0x00002ADB, 0x0004003D, 0x00000017, + 0x000019B2, 0x0000571A, 0x000300F7, 0x0000368B, 0x00000000, 0x000400FA, 0x00005272, 0x00002958, + 0x0000368B, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, + 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AE, + 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AE, 0x0000013D, 0x000500C5, + 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x0000368B, 0x000200F8, 0x0000368B, + 0x000700F5, 0x00000017, 0x0000471B, 0x000019B2, 0x00001AD7, 0x00003FF9, 0x00002958, 0x000500C7, + 0x00000017, 0x00005D37, 0x0000471B, 0x0000078A, 0x000500C4, 0x00000017, 0x000027FB, 0x00005D37, + 0x00000065, 0x000500C7, 0x00000017, 0x000050AF, 0x0000471B, 0x00000972, 0x000500C2, 0x00000017, + 0x000036E6, 0x000050AF, 0x00000215, 0x000500C5, 0x00000017, 0x00001985, 0x000027FB, 0x000036E6, + 0x00060041, 0x00000294, 0x00005819, 0x0000140E, 0x00000A0B, 0x000054B6, 0x0003003E, 0x00005819, + 0x00001985, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r4g4b4a4_a4r4g4b4_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r4g4b4a4_a4r4g4b4_scaled_cs.h new file mode 100644 index 0000000..b86d0ff --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r4g4b4a4_a4r4g4b4_scaled_cs.h @@ -0,0 +1,580 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 +%uint_268374015 = OpConstant %uint 268374015 + %uint_4 = OpConstant %uint 4 +%uint_4026593280 = OpConstant %uint 4026593280 + %uint_12 = OpConstant %uint 12 + %uint_1 = OpConstant %uint 1 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_2 = OpConstant %uint 2 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_3 = OpConstant %uint 3 + %uint_32 = OpConstant %uint 32 + %uint_64 = OpConstant %uint 64 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2612 = OpConstantComposite %v3uint %uint_4 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %1930 = OpConstantComposite %v4uint %uint_268374015 %uint_268374015 %uint_268374015 %uint_268374015 + %101 = OpConstantComposite %v4uint %uint_4 %uint_4 %uint_4 %uint_4 + %2418 = OpConstantComposite %v4uint %uint_4026593280 %uint_4026593280 %uint_4026593280 %uint_4026593280 + %533 = OpConstantComposite %v4uint %uint_12 %uint_12 %uint_12 %uint_12 + %uint_16 = OpConstant %uint 16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2612 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_2 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_3 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_3 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_7 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_7 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_7 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_8 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_1 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_3 + %23219 = OpBitwiseAnd %uint %10722 %uint_7 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_1 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %8801 = OpLoad %v4uint %20399 + %21106 = OpIEqual %bool %24990 %uint_1 + OpSelectionMerge %13962 None + OpBranchConditional %21106 %10583 %13962 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %8801 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %8801 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13962 + %13962 = OpLabel + %18202 = OpPhi %v4uint %8801 %21313 %16376 %10583 + %23862 = OpBitwiseAnd %v4uint %18202 %1930 + %10234 = OpShiftLeftLogical %v4uint %23862 %101 + %20653 = OpBitwiseAnd %v4uint %18202 %2418 + %14053 = OpShiftRightLogical %v4uint %20653 %533 + %6532 = OpBitwiseOr %v4uint %10234 %14053 + %20254 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %20254 %6532 + %15532 = OpIAdd %uint %11197 %int_1 + %6417 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %6417 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_64 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_64 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %13963 None + OpBranchConditional %21106 %10584 %13963 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20654 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20654 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %13963 + %13963 = OpLabel + %18203 = OpPhi %v4uint %6578 %24764 %16377 %10584 + %23863 = OpBitwiseAnd %v4uint %18203 %1930 + %10235 = OpShiftLeftLogical %v4uint %23863 %101 + %20655 = OpBitwiseAnd %v4uint %18203 %2418 + %14054 = OpShiftRightLogical %v4uint %20655 %533 + %6533 = OpBitwiseOr %v4uint %10235 %14054 + %22553 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15532 + OpStore %22553 %6533 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r4g4b4a4_a4r4g4b4_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000501, 0x0FFF0FFF, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000B, 0x000009A2, 0xF000F000, 0x0004002B, 0x0000000B, 0x00000A2E, 0x0000000C, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0004002B, 0x0000000B, 0x00000ACA, 0x00000040, + 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, + 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, 0x00000787, 0x00000A16, 0x00000A1F, 0x00040020, + 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, + 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A34, 0x00000A16, 0x00000A0A, + 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, + 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, + 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, + 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, + 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, + 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, + 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, + 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, + 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x0000078A, + 0x00000501, 0x00000501, 0x00000501, 0x00000501, 0x0007002C, 0x00000017, 0x00000065, 0x00000A16, + 0x00000A16, 0x00000A16, 0x00000A16, 0x0007002C, 0x00000017, 0x00000972, 0x000009A2, 0x000009A2, + 0x000009A2, 0x000009A2, 0x0007002C, 0x00000017, 0x00000215, 0x00000A2E, 0x00000A2E, 0x00000A2E, + 0x00000A2E, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x00050036, 0x00000008, 0x0000161F, + 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, + 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, + 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005F7D, + 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x000048EB, 0x00005F7D, 0x00000A0A, 0x000500C2, + 0x0000000B, 0x00001FCD, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x0000619E, 0x00001FCD, + 0x00000A13, 0x00050050, 0x00000011, 0x000022A7, 0x00003526, 0x00003526, 0x000500C2, 0x00000011, + 0x00001BAF, 0x000022A7, 0x00000787, 0x000500C7, 0x00000011, 0x00001997, 0x00001BAF, 0x000007A2, + 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, + 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, + 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, + 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, + 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, + 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, + 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, + 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A34, 0x0007004F, + 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, + 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, + 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, + 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, + 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, + 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, + 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A11, 0x00050051, 0x0000000C, + 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, + 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, + 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, + 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, + 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, + 0x00050080, 0x0000000B, 0x00001B12, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x00002BBD, + 0x00001B12, 0x00000A16, 0x00050051, 0x0000000B, 0x000029E2, 0x0000538B, 0x00000000, 0x000500C2, + 0x0000000B, 0x00001DEE, 0x000029E2, 0x00000A13, 0x00050051, 0x0000000B, 0x00002704, 0x0000538B, + 0x00000001, 0x00050050, 0x00000011, 0x00005C0B, 0x00001DEE, 0x00002704, 0x00050086, 0x00000011, + 0x00001F69, 0x00005C0B, 0x00001997, 0x00050051, 0x0000000B, 0x0000366C, 0x00001F69, 0x00000000, + 0x000500C4, 0x0000000B, 0x00004D4D, 0x0000366C, 0x00000A13, 0x00050051, 0x0000000B, 0x000051A9, + 0x00001F69, 0x00000001, 0x00050051, 0x0000000B, 0x000059EE, 0x0000538B, 0x00000002, 0x00060050, + 0x00000014, 0x000024C9, 0x00004D4D, 0x000051A9, 0x000059EE, 0x000300F7, 0x00005341, 0x00000002, + 0x000400FA, 0x000048EB, 0x0000537D, 0x00002DD9, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, + 0x00002970, 0x000024C9, 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, + 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, + 0x00000002, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, + 0x00005B4D, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, + 0x0000000C, 0x00005321, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, + 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, + 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, + 0x0000000C, 0x00006242, 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, + 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, + 0x0000225D, 0x000049FC, 0x00000A1F, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, + 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, + 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, + 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, + 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A1F, 0x000500C3, 0x0000000C, + 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, + 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, + 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, + 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, + 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, + 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, + 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, + 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544B, 0x000047B4, 0x00000A1F, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, + 0x000500C7, 0x0000000C, 0x00004ADE, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, + 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, + 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, + 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, + 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, + 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, + 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, + 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, + 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, + 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x00004158, 0x00000AC8, + 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, 0x0000566F, + 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, 0x00002DD9, 0x0007004F, 0x00000011, 0x00002621, + 0x000024C9, 0x000024C9, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000059CF, 0x00002621, + 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FE, + 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002748, 0x000059CF, 0x00000001, 0x000500C3, + 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00005788, + 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005347, + 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FE, 0x00005347, 0x000500C4, + 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002AB6, 0x00001903, + 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002748, 0x00000A35, 0x000500C4, 0x0000000C, + 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, + 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A0D, 0x000500C7, 0x0000000C, 0x000027B1, + 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, + 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, + 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, + 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, + 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, + 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, + 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, + 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, + 0x0000000C, 0x00001EEC, 0x00001903, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, + 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, + 0x000500C7, 0x0000000C, 0x00002E06, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, + 0x00003C4D, 0x00002E06, 0x0004007C, 0x0000000B, 0x00005670, 0x0000394F, 0x000200F9, 0x00005341, + 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, 0x000024FC, 0x0000566F, 0x0000537D, 0x00005670, + 0x00002DD9, 0x00050084, 0x00000011, 0x00003FA8, 0x00001F69, 0x00001997, 0x00050082, 0x00000011, + 0x00003BBC, 0x00005C0B, 0x00003FA8, 0x00050051, 0x0000000B, 0x00001C87, 0x00001997, 0x00000000, + 0x00050051, 0x0000000B, 0x00005962, 0x00001997, 0x00000001, 0x00050084, 0x0000000B, 0x00003372, + 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, 0x00003CA0, 0x000024FC, 0x00003372, 0x00050051, + 0x0000000B, 0x00003ED4, 0x00003BBC, 0x00000000, 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, + 0x00005962, 0x00050051, 0x0000000B, 0x00001AE6, 0x00003BBC, 0x00000001, 0x00050080, 0x0000000B, + 0x00002B25, 0x00003E12, 0x00001AE6, 0x000500C4, 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A13, + 0x000500C7, 0x0000000B, 0x00005AB3, 0x000029E2, 0x00000A1F, 0x00050080, 0x0000000B, 0x00002557, + 0x0000609D, 0x00005AB3, 0x000500C4, 0x0000000B, 0x000040AD, 0x00002557, 0x00000A0D, 0x00050080, + 0x0000000B, 0x00004EAA, 0x00003CA0, 0x000040AD, 0x00050080, 0x0000000B, 0x00003BA9, 0x00005EAC, + 0x00004EAA, 0x000500C2, 0x0000000B, 0x00003948, 0x00003BA9, 0x00000A16, 0x00060041, 0x00000294, + 0x00004FAF, 0x0000107A, 0x00000A0B, 0x00003948, 0x0004003D, 0x00000017, 0x00002261, 0x00004FAF, + 0x000500AA, 0x00000009, 0x00005272, 0x0000619E, 0x00000A0D, 0x000300F7, 0x0000368A, 0x00000000, + 0x000400FA, 0x00005272, 0x00002957, 0x0000368A, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, + 0x0000475F, 0x00002261, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AC, 0x00002261, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, + 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, + 0x0000368A, 0x000200F8, 0x0000368A, 0x000700F5, 0x00000017, 0x0000471A, 0x00002261, 0x00005341, + 0x00003FF8, 0x00002957, 0x000500C7, 0x00000017, 0x00005D36, 0x0000471A, 0x0000078A, 0x000500C4, + 0x00000017, 0x000027FA, 0x00005D36, 0x00000065, 0x000500C7, 0x00000017, 0x000050AD, 0x0000471A, + 0x00000972, 0x000500C2, 0x00000017, 0x000036E5, 0x000050AD, 0x00000215, 0x000500C5, 0x00000017, + 0x00001984, 0x000027FA, 0x000036E5, 0x00060041, 0x00000294, 0x00004F1E, 0x0000140E, 0x00000A0B, + 0x00002BBD, 0x0003003E, 0x00004F1E, 0x00001984, 0x00050080, 0x0000000B, 0x00003CAC, 0x00002BBD, + 0x00000A0E, 0x000500AC, 0x00000009, 0x00001911, 0x00001C87, 0x00000A0D, 0x000300F7, 0x000060BC, + 0x00000002, 0x000400FA, 0x00001911, 0x00005084, 0x00005094, 0x000200F8, 0x00005084, 0x00050086, + 0x0000000B, 0x00003697, 0x00001DEE, 0x00001C87, 0x00050084, 0x0000000B, 0x0000237E, 0x00003697, + 0x00001C87, 0x00050082, 0x0000000B, 0x00003171, 0x00001DEE, 0x0000237E, 0x00050080, 0x0000000B, + 0x00002527, 0x00003171, 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, 0x00001C87, + 0x000300F7, 0x00001EED, 0x00000000, 0x000400FA, 0x0000343F, 0x0000569E, 0x00002191, 0x000200F8, + 0x0000569E, 0x00050084, 0x0000000B, 0x00004B59, 0x00000ACA, 0x00001C87, 0x000500C4, 0x0000000B, + 0x0000540F, 0x00003171, 0x00000A16, 0x00050082, 0x0000000B, 0x00004944, 0x00004B59, 0x0000540F, + 0x000200F9, 0x00001EED, 0x000200F8, 0x00002191, 0x000200F9, 0x00001EED, 0x000200F8, 0x00001EED, + 0x000700F5, 0x0000000B, 0x0000292C, 0x00004944, 0x0000569E, 0x00000A3A, 0x00002191, 0x000200F9, + 0x000060BC, 0x000200F8, 0x00005094, 0x000200F9, 0x000060BC, 0x000200F8, 0x000060BC, 0x000700F5, + 0x0000000B, 0x000029BC, 0x0000292C, 0x00001EED, 0x00000ACA, 0x00005094, 0x00050084, 0x0000000B, + 0x0000492B, 0x000029BC, 0x00005962, 0x000500C2, 0x0000000B, 0x0000406D, 0x0000492B, 0x00000A16, + 0x00050080, 0x0000000B, 0x0000336B, 0x00003948, 0x0000406D, 0x00060041, 0x00000294, 0x0000571A, + 0x0000107A, 0x00000A0B, 0x0000336B, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, + 0x0000368B, 0x00000000, 0x000400FA, 0x00005272, 0x00002958, 0x0000368B, 0x000200F8, 0x00002958, + 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, + 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AE, 0x000019B2, 0x0000072E, 0x000500C2, + 0x00000017, 0x0000448E, 0x000050AE, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, + 0x0000448E, 0x000200F9, 0x0000368B, 0x000200F8, 0x0000368B, 0x000700F5, 0x00000017, 0x0000471B, + 0x000019B2, 0x000060BC, 0x00003FF9, 0x00002958, 0x000500C7, 0x00000017, 0x00005D37, 0x0000471B, + 0x0000078A, 0x000500C4, 0x00000017, 0x000027FB, 0x00005D37, 0x00000065, 0x000500C7, 0x00000017, + 0x000050AF, 0x0000471B, 0x00000972, 0x000500C2, 0x00000017, 0x000036E6, 0x000050AF, 0x00000215, + 0x000500C5, 0x00000017, 0x00001985, 0x000027FB, 0x000036E6, 0x00060041, 0x00000294, 0x00005819, + 0x0000140E, 0x00000A0B, 0x00003CAC, 0x0003003E, 0x00005819, 0x00001985, 0x000200F9, 0x00004C7A, + 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r4g4b4a4_b4g4r4a4_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r4g4b4a4_b4g4r4a4_cs.h new file mode 100644 index 0000000..026685a --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r4g4b4a4_b4g4r4a4_cs.h @@ -0,0 +1,524 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25059 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 +%uint_4042322160 = OpConstant %uint 4042322160 +%uint_983055 = OpConstant %uint 983055 + %uint_8 = OpConstant %uint 8 +%uint_251662080 = OpConstant %uint 251662080 + %uint_1 = OpConstant %uint 1 +%uint_16711935 = OpConstant %uint 16711935 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_2 = OpConstant %uint 2 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_3 = OpConstant %uint 3 + %uint_32 = OpConstant %uint 32 + %uint_64 = OpConstant %uint 64 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2612 = OpConstantComposite %v3uint %uint_4 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %992 = OpConstantComposite %v4uint %uint_4042322160 %uint_4042322160 %uint_4042322160 %uint_4042322160 + %925 = OpConstantComposite %v4uint %uint_983055 %uint_983055 %uint_983055 %uint_983055 + %2316 = OpConstantComposite %v4uint %uint_251662080 %uint_251662080 %uint_251662080 %uint_251662080 + %uint_16 = OpConstant %uint 16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2612 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_2 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_7 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_7 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_7 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_8 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_1 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %6362 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %22810 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %8801 = OpLoad %v4uint %17173 + %21106 = OpIEqual %bool %25058 %uint_1 + OpSelectionMerge %13962 None + OpBranchConditional %21106 %10583 %13962 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %8801 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %8801 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13962 + %13962 = OpLabel + %18259 = OpPhi %v4uint %8801 %24387 %16376 %10583 + %23286 = OpBitwiseAnd %v4uint %18259 %992 + %24373 = OpBitwiseAnd %v4uint %18259 %925 + %24932 = OpShiftLeftLogical %v4uint %24373 %317 + %17045 = OpBitwiseOr %v4uint %23286 %24932 + %21212 = OpBitwiseAnd %v4uint %18259 %2316 + %18088 = OpShiftRightLogical %v4uint %21212 %317 + %6532 = OpBitwiseOr %v4uint %17045 %18088 + %20254 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %20254 %6532 + %21686 = OpIAdd %uint %21685 %int_1 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_64 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %13963 None + OpBranchConditional %21106 %10584 %13963 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %13963 + %13963 = OpLabel + %18260 = OpPhi %v4uint %6578 %6871 %16377 %10584 + %23287 = OpBitwiseAnd %v4uint %18260 %992 + %24374 = OpBitwiseAnd %v4uint %18260 %925 + %24933 = OpShiftLeftLogical %v4uint %24374 %317 + %17046 = OpBitwiseOr %v4uint %23287 %24933 + %21213 = OpBitwiseAnd %v4uint %18260 %2316 + %18089 = OpShiftRightLogical %v4uint %21213 %317 + %6533 = OpBitwiseOr %v4uint %17046 %18089 + %22553 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21686 + OpStore %22553 %6533 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r4g4b4a4_b4g4r4a4_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000061E3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, + 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x000002CA, 0xF0F0F0F0, 0x0004002B, 0x0000000B, 0x000003BB, 0x000F000F, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x00000665, 0x0F000F00, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, + 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, + 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0004002B, 0x0000000B, 0x00000ACA, 0x00000040, + 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, + 0x00000009, 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, + 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, + 0x00000A34, 0x00000A16, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, + 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, + 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0007002C, 0x00000017, + 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, + 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, + 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000003E0, 0x000002CA, 0x000002CA, + 0x000002CA, 0x000002CA, 0x0007002C, 0x00000017, 0x0000039D, 0x000003BB, 0x000003BB, 0x000003BB, + 0x000003BB, 0x0007002C, 0x00000017, 0x0000090C, 0x00000665, 0x00000665, 0x00000665, 0x00000665, + 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, + 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, + 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, + 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, + 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, + 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, + 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, + 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, + 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, + 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, + 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, + 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, + 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, + 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, + 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, + 0x00000A34, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, + 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, + 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, + 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, + 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, + 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, + 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A11, + 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, + 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, + 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, + 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, + 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, + 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, + 0x0000000B, 0x000054B5, 0x00002764, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, + 0x00004376, 0x00005768, 0x000051F2, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, + 0x000400FA, 0x00004384, 0x00002BF8, 0x000018D9, 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, + 0x000032B3, 0x000044BE, 0x00000A17, 0x000500C3, 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, + 0x000500C2, 0x0000000B, 0x00004947, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, + 0x00004947, 0x00050084, 0x0000000C, 0x00005321, 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, + 0x00003B27, 0x000032B3, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, + 0x0004007C, 0x0000000C, 0x00003901, 0x00002348, 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, + 0x00003901, 0x000500C3, 0x0000000C, 0x000032BA, 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, + 0x00005FEE, 0x000032BA, 0x000020F4, 0x000500C4, 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A1F, + 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, + 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, + 0x0000000C, 0x00003138, 0x000044BE, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, + 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, + 0x00001B88, 0x0000434B, 0x00000A1F, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, + 0x000500C3, 0x0000000C, 0x00002215, 0x000044BE, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, + 0x00002215, 0x0000601E, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, + 0x0000000C, 0x00004112, 0x00005BEB, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, + 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, + 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, + 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, + 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, + 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, + 0x000047B4, 0x000018DA, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A1F, + 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, + 0x000044BE, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, + 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, + 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, + 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, + 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, + 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, + 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, + 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, + 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, + 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, + 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, + 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, + 0x00005B4D, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, + 0x0000000C, 0x00005347, 0x0000405C, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, + 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A22, 0x000500C7, 0x0000000C, + 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, + 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, + 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A0D, 0x000500C7, + 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, + 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, + 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, + 0x000500C7, 0x0000000C, 0x000047B5, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, + 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, + 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, + 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, + 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, + 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, + 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, + 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, + 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, + 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, + 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, + 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, + 0x00005F43, 0x000200F8, 0x000051F2, 0x0004007C, 0x0000000C, 0x00003CBC, 0x00005789, 0x00050084, + 0x0000000C, 0x000060B8, 0x000018DA, 0x00003CBC, 0x00050080, 0x0000000C, 0x0000208E, 0x000060B8, + 0x000044BE, 0x0004007C, 0x0000000C, 0x000022F8, 0x00005788, 0x00050084, 0x0000000C, 0x00001E9F, + 0x0000208E, 0x000022F8, 0x00050080, 0x0000000C, 0x00001F30, 0x0000591A, 0x00001E9F, 0x000200F9, + 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, + 0x00001F30, 0x000051F2, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, + 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, + 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, 0x00004315, 0x0000107A, + 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00002261, 0x00004315, 0x000500AA, 0x00000009, + 0x00005272, 0x000061E2, 0x00000A0D, 0x000300F7, 0x0000368A, 0x00000000, 0x000400FA, 0x00005272, + 0x00002957, 0x0000368A, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00002261, + 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, + 0x000050AC, 0x00002261, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, + 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x0000368A, 0x000200F8, + 0x0000368A, 0x000700F5, 0x00000017, 0x00004753, 0x00002261, 0x00005F43, 0x00003FF8, 0x00002957, + 0x000500C7, 0x00000017, 0x00005AF6, 0x00004753, 0x000003E0, 0x000500C7, 0x00000017, 0x00005F35, + 0x00004753, 0x0000039D, 0x000500C4, 0x00000017, 0x00006164, 0x00005F35, 0x0000013D, 0x000500C5, + 0x00000017, 0x00004295, 0x00005AF6, 0x00006164, 0x000500C7, 0x00000017, 0x000052DC, 0x00004753, + 0x0000090C, 0x000500C2, 0x00000017, 0x000046A8, 0x000052DC, 0x0000013D, 0x000500C5, 0x00000017, + 0x00001984, 0x00004295, 0x000046A8, 0x00060041, 0x00000294, 0x00004F1E, 0x0000140E, 0x00000A0B, + 0x000054B5, 0x0003003E, 0x00004F1E, 0x00001984, 0x00050080, 0x0000000B, 0x000054B6, 0x000054B5, + 0x00000A0E, 0x000300F7, 0x00001AD7, 0x00000002, 0x000400FA, 0x00004376, 0x000055E9, 0x00001C25, + 0x000200F8, 0x000055E9, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001C25, 0x000200F9, 0x00001AD7, + 0x000200F8, 0x00001AD7, 0x000700F5, 0x0000000B, 0x0000456F, 0x00000ACA, 0x000055E9, 0x00000A3A, + 0x00001C25, 0x000500C2, 0x0000000B, 0x000041C0, 0x0000456F, 0x00000A16, 0x00050080, 0x0000000B, + 0x00002ADB, 0x00005665, 0x000041C0, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, + 0x00002ADB, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x0000368B, 0x00000000, + 0x000400FA, 0x00005272, 0x00002958, 0x0000368B, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, + 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, + 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, + 0x0000368B, 0x000200F8, 0x0000368B, 0x000700F5, 0x00000017, 0x00004754, 0x000019B2, 0x00001AD7, + 0x00003FF9, 0x00002958, 0x000500C7, 0x00000017, 0x00005AF7, 0x00004754, 0x000003E0, 0x000500C7, + 0x00000017, 0x00005F36, 0x00004754, 0x0000039D, 0x000500C4, 0x00000017, 0x00006165, 0x00005F36, + 0x0000013D, 0x000500C5, 0x00000017, 0x00004296, 0x00005AF7, 0x00006165, 0x000500C7, 0x00000017, + 0x000052DD, 0x00004754, 0x0000090C, 0x000500C2, 0x00000017, 0x000046A9, 0x000052DD, 0x0000013D, + 0x000500C5, 0x00000017, 0x00001985, 0x00004296, 0x000046A9, 0x00060041, 0x00000294, 0x00005819, + 0x0000140E, 0x00000A0B, 0x000054B6, 0x0003003E, 0x00005819, 0x00001985, 0x000200F9, 0x00004C7A, + 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r4g4b4a4_b4g4r4a4_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r4g4b4a4_b4g4r4a4_scaled_cs.h new file mode 100644 index 0000000..2dd5a1a --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r4g4b4a4_b4g4r4a4_scaled_cs.h @@ -0,0 +1,585 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 +%uint_4042322160 = OpConstant %uint 4042322160 +%uint_983055 = OpConstant %uint 983055 + %uint_8 = OpConstant %uint 8 +%uint_251662080 = OpConstant %uint 251662080 + %uint_1 = OpConstant %uint 1 +%uint_16711935 = OpConstant %uint 16711935 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_2 = OpConstant %uint 2 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_3 = OpConstant %uint 3 + %uint_32 = OpConstant %uint 32 + %uint_64 = OpConstant %uint 64 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2612 = OpConstantComposite %v3uint %uint_4 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %992 = OpConstantComposite %v4uint %uint_4042322160 %uint_4042322160 %uint_4042322160 %uint_4042322160 + %925 = OpConstantComposite %v4uint %uint_983055 %uint_983055 %uint_983055 %uint_983055 + %2316 = OpConstantComposite %v4uint %uint_251662080 %uint_251662080 %uint_251662080 %uint_251662080 + %uint_16 = OpConstant %uint 16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2612 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_2 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_3 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_3 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_7 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_7 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_7 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_8 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_1 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_3 + %23219 = OpBitwiseAnd %uint %10722 %uint_7 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_1 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %8801 = OpLoad %v4uint %20399 + %21106 = OpIEqual %bool %24990 %uint_1 + OpSelectionMerge %13962 None + OpBranchConditional %21106 %10583 %13962 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %8801 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %8801 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13962 + %13962 = OpLabel + %18259 = OpPhi %v4uint %8801 %21313 %16376 %10583 + %23286 = OpBitwiseAnd %v4uint %18259 %992 + %24373 = OpBitwiseAnd %v4uint %18259 %925 + %24932 = OpShiftLeftLogical %v4uint %24373 %317 + %17045 = OpBitwiseOr %v4uint %23286 %24932 + %21212 = OpBitwiseAnd %v4uint %18259 %2316 + %18088 = OpShiftRightLogical %v4uint %21212 %317 + %6532 = OpBitwiseOr %v4uint %17045 %18088 + %20254 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %20254 %6532 + %15532 = OpIAdd %uint %11197 %int_1 + %6417 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %6417 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_64 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_64 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %13963 None + OpBranchConditional %21106 %10584 %13963 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %13963 + %13963 = OpLabel + %18260 = OpPhi %v4uint %6578 %24764 %16377 %10584 + %23287 = OpBitwiseAnd %v4uint %18260 %992 + %24374 = OpBitwiseAnd %v4uint %18260 %925 + %24933 = OpShiftLeftLogical %v4uint %24374 %317 + %17046 = OpBitwiseOr %v4uint %23287 %24933 + %21213 = OpBitwiseAnd %v4uint %18260 %2316 + %18089 = OpShiftRightLogical %v4uint %21213 %317 + %6533 = OpBitwiseOr %v4uint %17046 %18089 + %22553 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15532 + OpStore %22553 %6533 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r4g4b4a4_b4g4r4a4_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x000002CA, 0xF0F0F0F0, 0x0004002B, 0x0000000B, 0x000003BB, 0x000F000F, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x00000665, 0x0F000F00, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, + 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, + 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, + 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0004002B, 0x0000000B, 0x00000ACA, 0x00000040, + 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, + 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, 0x00000787, 0x00000A16, 0x00000A1F, 0x00040020, + 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, + 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A34, 0x00000A16, 0x00000A0A, + 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, + 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, + 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, + 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, + 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, + 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, + 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, + 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, + 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000003E0, + 0x000002CA, 0x000002CA, 0x000002CA, 0x000002CA, 0x0007002C, 0x00000017, 0x0000039D, 0x000003BB, + 0x000003BB, 0x000003BB, 0x000003BB, 0x0007002C, 0x00000017, 0x0000090C, 0x00000665, 0x00000665, + 0x00000665, 0x00000665, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x00050036, 0x00000008, + 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, + 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, + 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, + 0x00005F7D, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x000048EB, 0x00005F7D, 0x00000A0A, + 0x000500C2, 0x0000000B, 0x00001FCD, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x0000619E, + 0x00001FCD, 0x00000A13, 0x00050050, 0x00000011, 0x000022A7, 0x00003526, 0x00003526, 0x000500C2, + 0x00000011, 0x00001BAF, 0x000022A7, 0x00000787, 0x000500C7, 0x00000011, 0x00001997, 0x00001BAF, + 0x000007A2, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, + 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, + 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, + 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, + 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, + 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, + 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, + 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A34, + 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, + 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, + 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, + 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, + 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, + 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A11, 0x00050051, + 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, + 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, + 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, + 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, + 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, + 0x00002042, 0x00050080, 0x0000000B, 0x00001B12, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, + 0x00002BBD, 0x00001B12, 0x00000A16, 0x00050051, 0x0000000B, 0x000029E2, 0x0000538B, 0x00000000, + 0x000500C2, 0x0000000B, 0x00001DEE, 0x000029E2, 0x00000A13, 0x00050051, 0x0000000B, 0x00002704, + 0x0000538B, 0x00000001, 0x00050050, 0x00000011, 0x00005C0B, 0x00001DEE, 0x00002704, 0x00050086, + 0x00000011, 0x00001F69, 0x00005C0B, 0x00001997, 0x00050051, 0x0000000B, 0x0000366C, 0x00001F69, + 0x00000000, 0x000500C4, 0x0000000B, 0x00004D4D, 0x0000366C, 0x00000A13, 0x00050051, 0x0000000B, + 0x000051A9, 0x00001F69, 0x00000001, 0x00050051, 0x0000000B, 0x000059EE, 0x0000538B, 0x00000002, + 0x00060050, 0x00000014, 0x000024C9, 0x00004D4D, 0x000051A9, 0x000059EE, 0x000300F7, 0x00005341, + 0x00000002, 0x000400FA, 0x000048EB, 0x0000537D, 0x00002DD9, 0x000200F8, 0x0000537D, 0x0004007C, + 0x00000016, 0x00002970, 0x000024C9, 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, + 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, + 0x00002970, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, + 0x0000000B, 0x00005B4D, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, + 0x00050084, 0x0000000C, 0x00005321, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, + 0x000024FD, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, + 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, + 0x00050051, 0x0000000C, 0x00006242, 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, + 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, + 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A1F, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, + 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, + 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, + 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, + 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A1F, 0x000500C3, + 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, + 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, + 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, + 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, + 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, + 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A1F, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, + 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, + 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, + 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, + 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, + 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, + 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, + 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, + 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x00004158, + 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, + 0x0000566F, 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, 0x00002DD9, 0x0007004F, 0x00000011, + 0x00002621, 0x000024C9, 0x000024C9, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000059CF, + 0x00002621, 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, 0x00000000, 0x000500C3, 0x0000000C, + 0x000024FE, 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002748, 0x000059CF, 0x00000001, + 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4E, + 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, + 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FE, 0x00005347, + 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002AB6, + 0x00001903, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002748, 0x00000A35, 0x000500C4, + 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, + 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A0D, 0x000500C7, 0x0000000C, + 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, + 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, + 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, + 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, + 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, + 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, + 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, + 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, + 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, + 0x000500C3, 0x0000000C, 0x00001EEC, 0x00001903, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, + 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, + 0x0000544F, 0x000500C7, 0x0000000C, 0x00002E06, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, + 0x0000394F, 0x00003C4D, 0x00002E06, 0x0004007C, 0x0000000B, 0x00005670, 0x0000394F, 0x000200F9, + 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, 0x000024FC, 0x0000566F, 0x0000537D, + 0x00005670, 0x00002DD9, 0x00050084, 0x00000011, 0x00003FA8, 0x00001F69, 0x00001997, 0x00050082, + 0x00000011, 0x00003BBC, 0x00005C0B, 0x00003FA8, 0x00050051, 0x0000000B, 0x00001C87, 0x00001997, + 0x00000000, 0x00050051, 0x0000000B, 0x00005962, 0x00001997, 0x00000001, 0x00050084, 0x0000000B, + 0x00003372, 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, 0x00003CA0, 0x000024FC, 0x00003372, + 0x00050051, 0x0000000B, 0x00003ED4, 0x00003BBC, 0x00000000, 0x00050084, 0x0000000B, 0x00003E12, + 0x00003ED4, 0x00005962, 0x00050051, 0x0000000B, 0x00001AE6, 0x00003BBC, 0x00000001, 0x00050080, + 0x0000000B, 0x00002B25, 0x00003E12, 0x00001AE6, 0x000500C4, 0x0000000B, 0x0000609D, 0x00002B25, + 0x00000A13, 0x000500C7, 0x0000000B, 0x00005AB3, 0x000029E2, 0x00000A1F, 0x00050080, 0x0000000B, + 0x00002557, 0x0000609D, 0x00005AB3, 0x000500C4, 0x0000000B, 0x000040AD, 0x00002557, 0x00000A0D, + 0x00050080, 0x0000000B, 0x00004EAA, 0x00003CA0, 0x000040AD, 0x00050080, 0x0000000B, 0x00003BA9, + 0x00005EAC, 0x00004EAA, 0x000500C2, 0x0000000B, 0x00003948, 0x00003BA9, 0x00000A16, 0x00060041, + 0x00000294, 0x00004FAF, 0x0000107A, 0x00000A0B, 0x00003948, 0x0004003D, 0x00000017, 0x00002261, + 0x00004FAF, 0x000500AA, 0x00000009, 0x00005272, 0x0000619E, 0x00000A0D, 0x000300F7, 0x0000368A, + 0x00000000, 0x000400FA, 0x00005272, 0x00002957, 0x0000368A, 0x000200F8, 0x00002957, 0x000500C7, + 0x00000017, 0x0000475F, 0x00002261, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00002261, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, + 0x000200F9, 0x0000368A, 0x000200F8, 0x0000368A, 0x000700F5, 0x00000017, 0x00004753, 0x00002261, + 0x00005341, 0x00003FF8, 0x00002957, 0x000500C7, 0x00000017, 0x00005AF6, 0x00004753, 0x000003E0, + 0x000500C7, 0x00000017, 0x00005F35, 0x00004753, 0x0000039D, 0x000500C4, 0x00000017, 0x00006164, + 0x00005F35, 0x0000013D, 0x000500C5, 0x00000017, 0x00004295, 0x00005AF6, 0x00006164, 0x000500C7, + 0x00000017, 0x000052DC, 0x00004753, 0x0000090C, 0x000500C2, 0x00000017, 0x000046A8, 0x000052DC, + 0x0000013D, 0x000500C5, 0x00000017, 0x00001984, 0x00004295, 0x000046A8, 0x00060041, 0x00000294, + 0x00004F1E, 0x0000140E, 0x00000A0B, 0x00002BBD, 0x0003003E, 0x00004F1E, 0x00001984, 0x00050080, + 0x0000000B, 0x00003CAC, 0x00002BBD, 0x00000A0E, 0x000500AC, 0x00000009, 0x00001911, 0x00001C87, + 0x00000A0D, 0x000300F7, 0x000060BC, 0x00000002, 0x000400FA, 0x00001911, 0x00005084, 0x00005094, + 0x000200F8, 0x00005084, 0x00050086, 0x0000000B, 0x00003697, 0x00001DEE, 0x00001C87, 0x00050084, + 0x0000000B, 0x0000237E, 0x00003697, 0x00001C87, 0x00050082, 0x0000000B, 0x00003171, 0x00001DEE, + 0x0000237E, 0x00050080, 0x0000000B, 0x00002527, 0x00003171, 0x00000A0D, 0x000500AA, 0x00000009, + 0x0000343F, 0x00002527, 0x00001C87, 0x000300F7, 0x00001EED, 0x00000000, 0x000400FA, 0x0000343F, + 0x0000569E, 0x00002191, 0x000200F8, 0x0000569E, 0x00050084, 0x0000000B, 0x00004B59, 0x00000ACA, + 0x00001C87, 0x000500C4, 0x0000000B, 0x0000540F, 0x00003171, 0x00000A16, 0x00050082, 0x0000000B, + 0x00004944, 0x00004B59, 0x0000540F, 0x000200F9, 0x00001EED, 0x000200F8, 0x00002191, 0x000200F9, + 0x00001EED, 0x000200F8, 0x00001EED, 0x000700F5, 0x0000000B, 0x0000292C, 0x00004944, 0x0000569E, + 0x00000A3A, 0x00002191, 0x000200F9, 0x000060BC, 0x000200F8, 0x00005094, 0x000200F9, 0x000060BC, + 0x000200F8, 0x000060BC, 0x000700F5, 0x0000000B, 0x000029BC, 0x0000292C, 0x00001EED, 0x00000ACA, + 0x00005094, 0x00050084, 0x0000000B, 0x0000492B, 0x000029BC, 0x00005962, 0x000500C2, 0x0000000B, + 0x0000406D, 0x0000492B, 0x00000A16, 0x00050080, 0x0000000B, 0x0000336B, 0x00003948, 0x0000406D, + 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, 0x0000336B, 0x0004003D, 0x00000017, + 0x000019B2, 0x0000571A, 0x000300F7, 0x0000368B, 0x00000000, 0x000400FA, 0x00005272, 0x00002958, + 0x0000368B, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, + 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, + 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, + 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x0000368B, 0x000200F8, 0x0000368B, + 0x000700F5, 0x00000017, 0x00004754, 0x000019B2, 0x000060BC, 0x00003FF9, 0x00002958, 0x000500C7, + 0x00000017, 0x00005AF7, 0x00004754, 0x000003E0, 0x000500C7, 0x00000017, 0x00005F36, 0x00004754, + 0x0000039D, 0x000500C4, 0x00000017, 0x00006165, 0x00005F36, 0x0000013D, 0x000500C5, 0x00000017, + 0x00004296, 0x00005AF7, 0x00006165, 0x000500C7, 0x00000017, 0x000052DD, 0x00004754, 0x0000090C, + 0x000500C2, 0x00000017, 0x000046A9, 0x000052DD, 0x0000013D, 0x000500C5, 0x00000017, 0x00001985, + 0x00004296, 0x000046A9, 0x00060041, 0x00000294, 0x00005819, 0x0000140E, 0x00000A0B, 0x00003CAC, + 0x0003003E, 0x00005819, 0x00001985, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, + 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r5g5b5a1_b5g5r5a1_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r5g5b5a1_b5g5r5a1_cs.h new file mode 100644 index 0000000..0ffb60b --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r5g5b5a1_b5g5r5a1_cs.h @@ -0,0 +1,527 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25059 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 +%uint_2212529120 = OpConstant %uint 2212529120 +%uint_2031647 = OpConstant %uint 2031647 + %uint_10 = OpConstant %uint 10 +%uint_2080406528 = OpConstant %uint 2080406528 + %uint_1 = OpConstant %uint 1 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_2 = OpConstant %uint 2 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_3 = OpConstant %uint 3 + %uint_32 = OpConstant %uint 32 + %uint_64 = OpConstant %uint 64 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2612 = OpConstantComposite %v3uint %uint_4 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %422 = OpConstantComposite %v4uint %uint_2212529120 %uint_2212529120 %uint_2212529120 %uint_2212529120 + %27 = OpConstantComposite %v4uint %uint_2031647 %uint_2031647 %uint_2031647 %uint_2031647 + %425 = OpConstantComposite %v4uint %uint_10 %uint_10 %uint_10 %uint_10 + %773 = OpConstantComposite %v4uint %uint_2080406528 %uint_2080406528 %uint_2080406528 %uint_2080406528 + %uint_16 = OpConstant %uint 16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2612 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_2 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_7 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_7 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_7 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_8 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_1 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %6362 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %22810 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %8801 = OpLoad %v4uint %17173 + %21106 = OpIEqual %bool %25058 %uint_1 + OpSelectionMerge %13962 None + OpBranchConditional %21106 %10583 %13962 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %8801 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %8801 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13962 + %13962 = OpLabel + %18259 = OpPhi %v4uint %8801 %24387 %16376 %10583 + %23286 = OpBitwiseAnd %v4uint %18259 %422 + %24373 = OpBitwiseAnd %v4uint %18259 %27 + %24932 = OpShiftLeftLogical %v4uint %24373 %425 + %17045 = OpBitwiseOr %v4uint %23286 %24932 + %21212 = OpBitwiseAnd %v4uint %18259 %773 + %18088 = OpShiftRightLogical %v4uint %21212 %425 + %6532 = OpBitwiseOr %v4uint %17045 %18088 + %20254 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %20254 %6532 + %21686 = OpIAdd %uint %21685 %int_1 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_64 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %13963 None + OpBranchConditional %21106 %10584 %13963 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %13963 + %13963 = OpLabel + %18260 = OpPhi %v4uint %6578 %6871 %16377 %10584 + %23287 = OpBitwiseAnd %v4uint %18260 %422 + %24374 = OpBitwiseAnd %v4uint %18260 %27 + %24933 = OpShiftLeftLogical %v4uint %24374 %425 + %17046 = OpBitwiseOr %v4uint %23287 %24933 + %21213 = OpBitwiseAnd %v4uint %18260 %773 + %18089 = OpShiftRightLogical %v4uint %21213 %425 + %6533 = OpBitwiseOr %v4uint %17046 %18089 + %22553 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21686 + OpStore %22553 %6533 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r5g5b5a1_b5g5r5a1_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000061E3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, + 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x0000057B, 0x83E083E0, 0x0004002B, 0x0000000B, 0x000000EC, 0x001F001F, + 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000683, 0x7C007C00, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, + 0x0004002B, 0x0000000B, 0x00000ACA, 0x00000040, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, + 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x00040020, 0x00000291, + 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, + 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A34, 0x00000A16, 0x00000A0A, 0x00000A0A, + 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, + 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, + 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, + 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, + 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, + 0x00000A6A, 0x00000A0D, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, + 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, + 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, + 0x00000017, 0x000001A6, 0x0000057B, 0x0000057B, 0x0000057B, 0x0000057B, 0x0007002C, 0x00000017, + 0x0000001B, 0x000000EC, 0x000000EC, 0x000000EC, 0x000000EC, 0x0007002C, 0x00000017, 0x000001A9, + 0x00000A28, 0x00000A28, 0x00000A28, 0x00000A28, 0x0007002C, 0x00000017, 0x00000305, 0x00000683, + 0x00000683, 0x00000683, 0x00000683, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x00050036, + 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, + 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, + 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, + 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, + 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, + 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, + 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, + 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, + 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, + 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, + 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, + 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, + 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, + 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, + 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A34, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, + 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, + 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, + 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, + 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, + 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, + 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, + 0x0000591A, 0x00005BEB, 0x00000A11, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, + 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, + 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, + 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, + 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, + 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00002764, + 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x000054B5, 0x00002764, 0x00000A16, 0x000300F7, + 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, 0x00005768, 0x000051F2, 0x000200F8, 0x00005768, + 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, 0x00004384, 0x00002BF8, 0x000018D9, 0x000200F8, + 0x00002BF8, 0x000500C3, 0x0000000C, 0x000032B3, 0x000044BE, 0x00000A17, 0x000500C3, 0x0000000C, + 0x0000601E, 0x000018DA, 0x00000A11, 0x000500C2, 0x0000000B, 0x00004947, 0x00005789, 0x00000A16, + 0x0004007C, 0x0000000C, 0x000018AA, 0x00004947, 0x00050084, 0x0000000C, 0x00005321, 0x0000601E, + 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000032B3, 0x00005321, 0x000500C2, 0x0000000B, + 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x00003901, 0x00002348, 0x00050084, + 0x0000000C, 0x000020F4, 0x00003B27, 0x00003901, 0x000500C3, 0x0000000C, 0x000032BA, 0x00005BEB, + 0x00000A1A, 0x00050080, 0x0000000C, 0x00005FEE, 0x000032BA, 0x000020F4, 0x000500C4, 0x0000000C, + 0x0000225D, 0x00005FEE, 0x00000A1F, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, + 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, + 0x00005BEB, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000044BE, 0x00000A1D, 0x000500C4, + 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, + 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A1F, 0x000500C3, 0x0000000C, + 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000044BE, 0x00000A14, + 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000601E, 0x000500C7, 0x0000000C, 0x00005A0C, + 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00005BEB, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, + 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, + 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, + 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, + 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, + 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x000018DA, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544B, 0x000047B4, 0x00000A1F, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, + 0x000500C7, 0x0000000C, 0x00004ADE, 0x000044BE, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, + 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, + 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, + 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, + 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, + 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, + 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, + 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, + 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, + 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, + 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, + 0x000018D9, 0x0004007C, 0x00000012, 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, + 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, + 0x0000000C, 0x00002747, 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, + 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, + 0x000018AB, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AB, 0x00050080, + 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, + 0x00000A22, 0x000500C7, 0x0000000C, 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003139, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, + 0x00004397, 0x00000A0D, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, + 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, + 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, + 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002747, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, + 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, + 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, + 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, + 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, + 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, + 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, + 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, + 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, + 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, + 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, + 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, 0x00002BF8, + 0x00002F42, 0x000018D9, 0x000200F9, 0x00005F43, 0x000200F8, 0x000051F2, 0x0004007C, 0x0000000C, + 0x00003CBC, 0x00005789, 0x00050084, 0x0000000C, 0x000060B8, 0x000018DA, 0x00003CBC, 0x00050080, + 0x0000000C, 0x0000208E, 0x000060B8, 0x000044BE, 0x0004007C, 0x0000000C, 0x000022F8, 0x00005788, + 0x00050084, 0x0000000C, 0x00001E9F, 0x0000208E, 0x000022F8, 0x00050080, 0x0000000C, 0x00001F30, + 0x0000591A, 0x00001E9F, 0x000200F9, 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, + 0x00002A3E, 0x0000292C, 0x00001E0B, 0x00001F30, 0x000051F2, 0x0004007C, 0x0000000C, 0x00001A3F, + 0x00005EAC, 0x00050080, 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, + 0x00003EE9, 0x000056CD, 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, + 0x00000294, 0x00004315, 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00002261, + 0x00004315, 0x000500AA, 0x00000009, 0x00005272, 0x000061E2, 0x00000A0D, 0x000300F7, 0x0000368A, + 0x00000000, 0x000400FA, 0x00005272, 0x00002957, 0x0000368A, 0x000200F8, 0x00002957, 0x000500C7, + 0x00000017, 0x0000475F, 0x00002261, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00002261, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, + 0x000200F9, 0x0000368A, 0x000200F8, 0x0000368A, 0x000700F5, 0x00000017, 0x00004753, 0x00002261, + 0x00005F43, 0x00003FF8, 0x00002957, 0x000500C7, 0x00000017, 0x00005AF6, 0x00004753, 0x000001A6, + 0x000500C7, 0x00000017, 0x00005F35, 0x00004753, 0x0000001B, 0x000500C4, 0x00000017, 0x00006164, + 0x00005F35, 0x000001A9, 0x000500C5, 0x00000017, 0x00004295, 0x00005AF6, 0x00006164, 0x000500C7, + 0x00000017, 0x000052DC, 0x00004753, 0x00000305, 0x000500C2, 0x00000017, 0x000046A8, 0x000052DC, + 0x000001A9, 0x000500C5, 0x00000017, 0x00001984, 0x00004295, 0x000046A8, 0x00060041, 0x00000294, + 0x00004F1E, 0x0000140E, 0x00000A0B, 0x000054B5, 0x0003003E, 0x00004F1E, 0x00001984, 0x00050080, + 0x0000000B, 0x000054B6, 0x000054B5, 0x00000A0E, 0x000300F7, 0x00001AD7, 0x00000002, 0x000400FA, + 0x00004376, 0x000055E9, 0x00001C25, 0x000200F8, 0x000055E9, 0x000200F9, 0x00001AD7, 0x000200F8, + 0x00001C25, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001AD7, 0x000700F5, 0x0000000B, 0x0000456F, + 0x00000ACA, 0x000055E9, 0x00000A3A, 0x00001C25, 0x000500C2, 0x0000000B, 0x000041C0, 0x0000456F, + 0x00000A16, 0x00050080, 0x0000000B, 0x00002ADB, 0x00005665, 0x000041C0, 0x00060041, 0x00000294, + 0x0000571A, 0x0000107A, 0x00000A0B, 0x00002ADB, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, + 0x000300F7, 0x0000368B, 0x00000000, 0x000400FA, 0x00005272, 0x00002958, 0x0000368B, 0x000200F8, + 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, + 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, + 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, + 0x000024D2, 0x0000448E, 0x000200F9, 0x0000368B, 0x000200F8, 0x0000368B, 0x000700F5, 0x00000017, + 0x00004754, 0x000019B2, 0x00001AD7, 0x00003FF9, 0x00002958, 0x000500C7, 0x00000017, 0x00005AF7, + 0x00004754, 0x000001A6, 0x000500C7, 0x00000017, 0x00005F36, 0x00004754, 0x0000001B, 0x000500C4, + 0x00000017, 0x00006165, 0x00005F36, 0x000001A9, 0x000500C5, 0x00000017, 0x00004296, 0x00005AF7, + 0x00006165, 0x000500C7, 0x00000017, 0x000052DD, 0x00004754, 0x00000305, 0x000500C2, 0x00000017, + 0x000046A9, 0x000052DD, 0x000001A9, 0x000500C5, 0x00000017, 0x00001985, 0x00004296, 0x000046A9, + 0x00060041, 0x00000294, 0x00005819, 0x0000140E, 0x00000A0B, 0x000054B6, 0x0003003E, 0x00005819, + 0x00001985, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r5g5b5a1_b5g5r5a1_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r5g5b5a1_b5g5r5a1_scaled_cs.h new file mode 100644 index 0000000..056c37f --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r5g5b5a1_b5g5r5a1_scaled_cs.h @@ -0,0 +1,588 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 +%uint_2212529120 = OpConstant %uint 2212529120 +%uint_2031647 = OpConstant %uint 2031647 + %uint_10 = OpConstant %uint 10 +%uint_2080406528 = OpConstant %uint 2080406528 + %uint_1 = OpConstant %uint 1 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_2 = OpConstant %uint 2 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_3 = OpConstant %uint 3 + %uint_32 = OpConstant %uint 32 + %uint_64 = OpConstant %uint 64 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2612 = OpConstantComposite %v3uint %uint_4 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %422 = OpConstantComposite %v4uint %uint_2212529120 %uint_2212529120 %uint_2212529120 %uint_2212529120 + %27 = OpConstantComposite %v4uint %uint_2031647 %uint_2031647 %uint_2031647 %uint_2031647 + %425 = OpConstantComposite %v4uint %uint_10 %uint_10 %uint_10 %uint_10 + %773 = OpConstantComposite %v4uint %uint_2080406528 %uint_2080406528 %uint_2080406528 %uint_2080406528 + %uint_16 = OpConstant %uint 16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2612 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_2 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_3 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_3 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_7 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_7 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_7 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_8 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_1 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_3 + %23219 = OpBitwiseAnd %uint %10722 %uint_7 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_1 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %8801 = OpLoad %v4uint %20399 + %21106 = OpIEqual %bool %24990 %uint_1 + OpSelectionMerge %13962 None + OpBranchConditional %21106 %10583 %13962 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %8801 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %8801 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13962 + %13962 = OpLabel + %18259 = OpPhi %v4uint %8801 %21313 %16376 %10583 + %23286 = OpBitwiseAnd %v4uint %18259 %422 + %24373 = OpBitwiseAnd %v4uint %18259 %27 + %24932 = OpShiftLeftLogical %v4uint %24373 %425 + %17045 = OpBitwiseOr %v4uint %23286 %24932 + %21212 = OpBitwiseAnd %v4uint %18259 %773 + %18088 = OpShiftRightLogical %v4uint %21212 %425 + %6532 = OpBitwiseOr %v4uint %17045 %18088 + %20254 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %20254 %6532 + %15532 = OpIAdd %uint %11197 %int_1 + %6417 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %6417 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_64 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_64 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %13963 None + OpBranchConditional %21106 %10584 %13963 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %13963 + %13963 = OpLabel + %18260 = OpPhi %v4uint %6578 %24764 %16377 %10584 + %23287 = OpBitwiseAnd %v4uint %18260 %422 + %24374 = OpBitwiseAnd %v4uint %18260 %27 + %24933 = OpShiftLeftLogical %v4uint %24374 %425 + %17046 = OpBitwiseOr %v4uint %23287 %24933 + %21213 = OpBitwiseAnd %v4uint %18260 %773 + %18089 = OpShiftRightLogical %v4uint %21213 %425 + %6533 = OpBitwiseOr %v4uint %17046 %18089 + %22553 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15532 + OpStore %22553 %6533 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r5g5b5a1_b5g5r5a1_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x0000057B, 0x83E083E0, 0x0004002B, 0x0000000B, 0x000000EC, 0x001F001F, + 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0004002B, 0x0000000B, 0x00000683, 0x7C007C00, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, + 0x0004002B, 0x0000000B, 0x00000ACA, 0x00000040, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, + 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, + 0x00000787, 0x00000A16, 0x00000A1F, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, + 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, + 0x00000014, 0x00000A34, 0x00000A16, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, + 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, + 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, + 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, + 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, + 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, + 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, + 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, + 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, + 0x000005FD, 0x0007002C, 0x00000017, 0x000001A6, 0x0000057B, 0x0000057B, 0x0000057B, 0x0000057B, + 0x0007002C, 0x00000017, 0x0000001B, 0x000000EC, 0x000000EC, 0x000000EC, 0x000000EC, 0x0007002C, + 0x00000017, 0x000001A9, 0x00000A28, 0x00000A28, 0x00000A28, 0x00000A28, 0x0007002C, 0x00000017, + 0x00000305, 0x00000683, 0x00000683, 0x00000683, 0x00000683, 0x0004002B, 0x0000000B, 0x00000A3A, + 0x00000010, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, + 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, + 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, + 0x000060D7, 0x000500C7, 0x0000000B, 0x00005F7D, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, + 0x000048EB, 0x00005F7D, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001FCD, 0x00003526, 0x00000A10, + 0x000500C7, 0x0000000B, 0x0000619E, 0x00001FCD, 0x00000A13, 0x00050050, 0x00000011, 0x000022A7, + 0x00003526, 0x00003526, 0x000500C2, 0x00000011, 0x00001BAF, 0x000022A7, 0x00000787, 0x000500C7, + 0x00000011, 0x00001997, 0x00001BAF, 0x000007A2, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, + 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, + 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, + 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, + 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, + 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, + 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, + 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, + 0x0000538B, 0x00002A0E, 0x00000A34, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, + 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, + 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, + 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, + 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, + 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, + 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, + 0x00005BEB, 0x00000A11, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, + 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, + 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, + 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, + 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, + 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00001B12, 0x00002A92, + 0x0000578B, 0x000500C2, 0x0000000B, 0x00002BBD, 0x00001B12, 0x00000A16, 0x00050051, 0x0000000B, + 0x000029E2, 0x0000538B, 0x00000000, 0x000500C2, 0x0000000B, 0x00001DEE, 0x000029E2, 0x00000A13, + 0x00050051, 0x0000000B, 0x00002704, 0x0000538B, 0x00000001, 0x00050050, 0x00000011, 0x00005C0B, + 0x00001DEE, 0x00002704, 0x00050086, 0x00000011, 0x00001F69, 0x00005C0B, 0x00001997, 0x00050051, + 0x0000000B, 0x0000366C, 0x00001F69, 0x00000000, 0x000500C4, 0x0000000B, 0x00004D4D, 0x0000366C, + 0x00000A13, 0x00050051, 0x0000000B, 0x000051A9, 0x00001F69, 0x00000001, 0x00050051, 0x0000000B, + 0x000059EE, 0x0000538B, 0x00000002, 0x00060050, 0x00000014, 0x000024C9, 0x00004D4D, 0x000051A9, + 0x000059EE, 0x000300F7, 0x00005341, 0x00000002, 0x000400FA, 0x000048EB, 0x0000537D, 0x00002DD9, + 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, 0x00002970, 0x000024C9, 0x00050051, 0x0000000C, + 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A17, + 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405C, + 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005789, 0x00000A16, 0x0004007C, + 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005321, 0x0000405C, 0x000018AA, + 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, + 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, + 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, 0x00002970, 0x00000000, + 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, + 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A1F, 0x000500C7, + 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, + 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, + 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, + 0x0000434B, 0x00000A1F, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, + 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, + 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, + 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, + 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, + 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, + 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, + 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, + 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, + 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A1F, 0x00050080, + 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000042C2, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, + 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, + 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, + 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, + 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, + 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, + 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00005559, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, + 0x00005559, 0x0004007C, 0x0000000B, 0x0000566F, 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, + 0x00002DD9, 0x0007004F, 0x00000011, 0x00002621, 0x000024C9, 0x000024C9, 0x00000000, 0x00000001, + 0x0004007C, 0x00000012, 0x000059CF, 0x00002621, 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, + 0x00000000, 0x000500C3, 0x0000000C, 0x000024FE, 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, + 0x00002748, 0x000059CF, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, + 0x000500C2, 0x0000000B, 0x00005B4E, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, + 0x00005B4E, 0x00050084, 0x0000000C, 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, + 0x00003F5E, 0x000024FE, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A22, + 0x000500C7, 0x0000000C, 0x00002AB6, 0x00001903, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, + 0x00002748, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, + 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, + 0x00000A0D, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, + 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, + 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, + 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, + 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, + 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, + 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, + 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, + 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, + 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, + 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x00001903, 0x00000A14, + 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, + 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, + 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x00002E06, 0x00004159, + 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4D, 0x00002E06, 0x0004007C, 0x0000000B, + 0x00005670, 0x0000394F, 0x000200F9, 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, + 0x000024FC, 0x0000566F, 0x0000537D, 0x00005670, 0x00002DD9, 0x00050084, 0x00000011, 0x00003FA8, + 0x00001F69, 0x00001997, 0x00050082, 0x00000011, 0x00003BBC, 0x00005C0B, 0x00003FA8, 0x00050051, + 0x0000000B, 0x00001C87, 0x00001997, 0x00000000, 0x00050051, 0x0000000B, 0x00005962, 0x00001997, + 0x00000001, 0x00050084, 0x0000000B, 0x00003372, 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, + 0x00003CA0, 0x000024FC, 0x00003372, 0x00050051, 0x0000000B, 0x00003ED4, 0x00003BBC, 0x00000000, + 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, 0x00005962, 0x00050051, 0x0000000B, 0x00001AE6, + 0x00003BBC, 0x00000001, 0x00050080, 0x0000000B, 0x00002B25, 0x00003E12, 0x00001AE6, 0x000500C4, + 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A13, 0x000500C7, 0x0000000B, 0x00005AB3, 0x000029E2, + 0x00000A1F, 0x00050080, 0x0000000B, 0x00002557, 0x0000609D, 0x00005AB3, 0x000500C4, 0x0000000B, + 0x000040AD, 0x00002557, 0x00000A0D, 0x00050080, 0x0000000B, 0x00004EAA, 0x00003CA0, 0x000040AD, + 0x00050080, 0x0000000B, 0x00003BA9, 0x00005EAC, 0x00004EAA, 0x000500C2, 0x0000000B, 0x00003948, + 0x00003BA9, 0x00000A16, 0x00060041, 0x00000294, 0x00004FAF, 0x0000107A, 0x00000A0B, 0x00003948, + 0x0004003D, 0x00000017, 0x00002261, 0x00004FAF, 0x000500AA, 0x00000009, 0x00005272, 0x0000619E, + 0x00000A0D, 0x000300F7, 0x0000368A, 0x00000000, 0x000400FA, 0x00005272, 0x00002957, 0x0000368A, + 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00002261, 0x000009CE, 0x000500C4, + 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00002261, + 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, + 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x0000368A, 0x000200F8, 0x0000368A, 0x000700F5, + 0x00000017, 0x00004753, 0x00002261, 0x00005341, 0x00003FF8, 0x00002957, 0x000500C7, 0x00000017, + 0x00005AF6, 0x00004753, 0x000001A6, 0x000500C7, 0x00000017, 0x00005F35, 0x00004753, 0x0000001B, + 0x000500C4, 0x00000017, 0x00006164, 0x00005F35, 0x000001A9, 0x000500C5, 0x00000017, 0x00004295, + 0x00005AF6, 0x00006164, 0x000500C7, 0x00000017, 0x000052DC, 0x00004753, 0x00000305, 0x000500C2, + 0x00000017, 0x000046A8, 0x000052DC, 0x000001A9, 0x000500C5, 0x00000017, 0x00001984, 0x00004295, + 0x000046A8, 0x00060041, 0x00000294, 0x00004F1E, 0x0000140E, 0x00000A0B, 0x00002BBD, 0x0003003E, + 0x00004F1E, 0x00001984, 0x00050080, 0x0000000B, 0x00003CAC, 0x00002BBD, 0x00000A0E, 0x000500AC, + 0x00000009, 0x00001911, 0x00001C87, 0x00000A0D, 0x000300F7, 0x000060BC, 0x00000002, 0x000400FA, + 0x00001911, 0x00005084, 0x00005094, 0x000200F8, 0x00005084, 0x00050086, 0x0000000B, 0x00003697, + 0x00001DEE, 0x00001C87, 0x00050084, 0x0000000B, 0x0000237E, 0x00003697, 0x00001C87, 0x00050082, + 0x0000000B, 0x00003171, 0x00001DEE, 0x0000237E, 0x00050080, 0x0000000B, 0x00002527, 0x00003171, + 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, 0x00001C87, 0x000300F7, 0x00001EED, + 0x00000000, 0x000400FA, 0x0000343F, 0x0000569E, 0x00002191, 0x000200F8, 0x0000569E, 0x00050084, + 0x0000000B, 0x00004B59, 0x00000ACA, 0x00001C87, 0x000500C4, 0x0000000B, 0x0000540F, 0x00003171, + 0x00000A16, 0x00050082, 0x0000000B, 0x00004944, 0x00004B59, 0x0000540F, 0x000200F9, 0x00001EED, + 0x000200F8, 0x00002191, 0x000200F9, 0x00001EED, 0x000200F8, 0x00001EED, 0x000700F5, 0x0000000B, + 0x0000292C, 0x00004944, 0x0000569E, 0x00000A3A, 0x00002191, 0x000200F9, 0x000060BC, 0x000200F8, + 0x00005094, 0x000200F9, 0x000060BC, 0x000200F8, 0x000060BC, 0x000700F5, 0x0000000B, 0x000029BC, + 0x0000292C, 0x00001EED, 0x00000ACA, 0x00005094, 0x00050084, 0x0000000B, 0x0000492B, 0x000029BC, + 0x00005962, 0x000500C2, 0x0000000B, 0x0000406D, 0x0000492B, 0x00000A16, 0x00050080, 0x0000000B, + 0x0000336B, 0x00003948, 0x0000406D, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, + 0x0000336B, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x0000368B, 0x00000000, + 0x000400FA, 0x00005272, 0x00002958, 0x0000368B, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, + 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, + 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, + 0x0000368B, 0x000200F8, 0x0000368B, 0x000700F5, 0x00000017, 0x00004754, 0x000019B2, 0x000060BC, + 0x00003FF9, 0x00002958, 0x000500C7, 0x00000017, 0x00005AF7, 0x00004754, 0x000001A6, 0x000500C7, + 0x00000017, 0x00005F36, 0x00004754, 0x0000001B, 0x000500C4, 0x00000017, 0x00006165, 0x00005F36, + 0x000001A9, 0x000500C5, 0x00000017, 0x00004296, 0x00005AF7, 0x00006165, 0x000500C7, 0x00000017, + 0x000052DD, 0x00004754, 0x00000305, 0x000500C2, 0x00000017, 0x000046A9, 0x000052DD, 0x000001A9, + 0x000500C5, 0x00000017, 0x00001985, 0x00004296, 0x000046A9, 0x00060041, 0x00000294, 0x00005819, + 0x0000140E, 0x00000A0B, 0x00003CAC, 0x0003003E, 0x00005819, 0x00001985, 0x000200F9, 0x00004C7A, + 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r5g5b6_b5g6r5_swizzle_rbga_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r5g5b6_b5g6r5_swizzle_rbga_cs.h new file mode 100644 index 0000000..dfa5686 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r5g5b6_b5g6r5_swizzle_rbga_cs.h @@ -0,0 +1,519 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25059 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 +%uint_2031647 = OpConstant %uint 2031647 + %uint_11 = OpConstant %uint 11 +%uint_4292935648 = OpConstant %uint 4292935648 + %uint_5 = OpConstant %uint 5 + %uint_1 = OpConstant %uint 1 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_2 = OpConstant %uint 2 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_3 = OpConstant %uint 3 + %uint_32 = OpConstant %uint 32 + %uint_64 = OpConstant %uint 64 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2612 = OpConstantComposite %v3uint %uint_4 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %27 = OpConstantComposite %v4uint %uint_2031647 %uint_2031647 %uint_2031647 %uint_2031647 + %479 = OpConstantComposite %v4uint %uint_11 %uint_11 %uint_11 %uint_11 + %1310 = OpConstantComposite %v4uint %uint_4292935648 %uint_4292935648 %uint_4292935648 %uint_4292935648 + %155 = OpConstantComposite %v4uint %uint_5 %uint_5 %uint_5 %uint_5 + %uint_16 = OpConstant %uint 16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2612 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_2 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_7 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_7 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_7 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_8 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_1 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %6362 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %22810 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %8801 = OpLoad %v4uint %17173 + %21106 = OpIEqual %bool %25058 %uint_1 + OpSelectionMerge %13962 None + OpBranchConditional %21106 %10583 %13962 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %8801 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %8801 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13962 + %13962 = OpLabel + %18202 = OpPhi %v4uint %8801 %24387 %16376 %10583 + %23862 = OpBitwiseAnd %v4uint %18202 %27 + %10234 = OpShiftLeftLogical %v4uint %23862 %479 + %20653 = OpBitwiseAnd %v4uint %18202 %1310 + %14053 = OpShiftRightLogical %v4uint %20653 %155 + %6532 = OpBitwiseOr %v4uint %10234 %14053 + %20254 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %20254 %6532 + %21686 = OpIAdd %uint %21685 %int_1 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_64 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %13963 None + OpBranchConditional %21106 %10584 %13963 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20654 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20654 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %13963 + %13963 = OpLabel + %18203 = OpPhi %v4uint %6578 %6871 %16377 %10584 + %23863 = OpBitwiseAnd %v4uint %18203 %27 + %10235 = OpShiftLeftLogical %v4uint %23863 %479 + %20655 = OpBitwiseAnd %v4uint %18203 %1310 + %14054 = OpShiftRightLogical %v4uint %20655 %155 + %6533 = OpBitwiseOr %v4uint %10235 %14054 + %22553 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21686 + OpStore %22553 %6533 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r5g5b6_b5g6r5_swizzle_rbga_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000061E3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, + 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x000000EC, 0x001F001F, 0x0004002B, 0x0000000B, 0x00000A2B, 0x0000000B, + 0x0004002B, 0x0000000B, 0x000001F4, 0xFFE0FFE0, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, + 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, + 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0004002B, 0x0000000B, 0x00000ACA, 0x00000040, + 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, + 0x00000009, 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, + 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, + 0x00000A34, 0x00000A16, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, + 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, + 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0007002C, 0x00000017, + 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, + 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, + 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x0000001B, 0x000000EC, 0x000000EC, + 0x000000EC, 0x000000EC, 0x0007002C, 0x00000017, 0x000001DF, 0x00000A2B, 0x00000A2B, 0x00000A2B, + 0x00000A2B, 0x0007002C, 0x00000017, 0x0000051E, 0x000001F4, 0x000001F4, 0x000001F4, 0x000001F4, + 0x0007002C, 0x00000017, 0x0000009B, 0x00000A19, 0x00000A19, 0x00000A19, 0x00000A19, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, + 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, + 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, + 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, + 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, + 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, + 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, + 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, + 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, + 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, + 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, + 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, + 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, + 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, + 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A34, + 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, + 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, + 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, + 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, + 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, + 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A11, 0x00050051, + 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, + 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, + 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, + 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, + 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, + 0x00002042, 0x00050080, 0x0000000B, 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, + 0x000054B5, 0x00002764, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, + 0x00005768, 0x000051F2, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, + 0x00004384, 0x00002BF8, 0x000018D9, 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, 0x000032B3, + 0x000044BE, 0x00000A17, 0x000500C3, 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, 0x000500C2, + 0x0000000B, 0x00004947, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00004947, + 0x00050084, 0x0000000C, 0x00005321, 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, + 0x000032B3, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, + 0x0000000C, 0x00003901, 0x00002348, 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, 0x00003901, + 0x000500C3, 0x0000000C, 0x000032BA, 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, 0x00005FEE, + 0x000032BA, 0x000020F4, 0x000500C4, 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A1F, 0x000500C7, + 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, + 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003138, 0x000044BE, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, + 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, + 0x0000434B, 0x00000A1F, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, + 0x0000000C, 0x00002215, 0x000044BE, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, + 0x0000601E, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, + 0x00004112, 0x00005BEB, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, + 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, + 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, + 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, + 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, + 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, + 0x000018DA, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A1F, 0x00050080, + 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000044BE, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, + 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, + 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, + 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, + 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, + 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, + 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, + 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, 0x000019AD, + 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, + 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, 0x00000001, + 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, + 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, 0x0000000C, + 0x00005347, 0x0000405C, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, + 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002AB6, + 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, 0x000500C4, + 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, + 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A0D, 0x000500C7, 0x0000000C, + 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, + 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, + 0x0000000C, 0x000047B5, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, + 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, + 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, + 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, + 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, + 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, + 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, + 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, + 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, + 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, + 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, + 0x0000000C, 0x0000292C, 0x000054ED, 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, 0x00005F43, + 0x000200F8, 0x000051F2, 0x0004007C, 0x0000000C, 0x00003CBC, 0x00005789, 0x00050084, 0x0000000C, + 0x000060B8, 0x000018DA, 0x00003CBC, 0x00050080, 0x0000000C, 0x0000208E, 0x000060B8, 0x000044BE, + 0x0004007C, 0x0000000C, 0x000022F8, 0x00005788, 0x00050084, 0x0000000C, 0x00001E9F, 0x0000208E, + 0x000022F8, 0x00050080, 0x0000000C, 0x00001F30, 0x0000591A, 0x00001E9F, 0x000200F9, 0x00005F43, + 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, 0x00001F30, + 0x000051F2, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, 0x000056CD, + 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, 0x0000000B, + 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, 0x00004315, 0x0000107A, 0x00000A0B, + 0x00005665, 0x0004003D, 0x00000017, 0x00002261, 0x00004315, 0x000500AA, 0x00000009, 0x00005272, + 0x000061E2, 0x00000A0D, 0x000300F7, 0x0000368A, 0x00000000, 0x000400FA, 0x00005272, 0x00002957, + 0x0000368A, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00002261, 0x000009CE, + 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, + 0x00002261, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, + 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x0000368A, 0x000200F8, 0x0000368A, + 0x000700F5, 0x00000017, 0x0000471A, 0x00002261, 0x00005F43, 0x00003FF8, 0x00002957, 0x000500C7, + 0x00000017, 0x00005D36, 0x0000471A, 0x0000001B, 0x000500C4, 0x00000017, 0x000027FA, 0x00005D36, + 0x000001DF, 0x000500C7, 0x00000017, 0x000050AD, 0x0000471A, 0x0000051E, 0x000500C2, 0x00000017, + 0x000036E5, 0x000050AD, 0x0000009B, 0x000500C5, 0x00000017, 0x00001984, 0x000027FA, 0x000036E5, + 0x00060041, 0x00000294, 0x00004F1E, 0x0000140E, 0x00000A0B, 0x000054B5, 0x0003003E, 0x00004F1E, + 0x00001984, 0x00050080, 0x0000000B, 0x000054B6, 0x000054B5, 0x00000A0E, 0x000300F7, 0x00001AD7, + 0x00000002, 0x000400FA, 0x00004376, 0x000055E9, 0x00001C25, 0x000200F8, 0x000055E9, 0x000200F9, + 0x00001AD7, 0x000200F8, 0x00001C25, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001AD7, 0x000700F5, + 0x0000000B, 0x0000456F, 0x00000ACA, 0x000055E9, 0x00000A3A, 0x00001C25, 0x000500C2, 0x0000000B, + 0x000041C0, 0x0000456F, 0x00000A16, 0x00050080, 0x0000000B, 0x00002ADB, 0x00005665, 0x000041C0, + 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, 0x00002ADB, 0x0004003D, 0x00000017, + 0x000019B2, 0x0000571A, 0x000300F7, 0x0000368B, 0x00000000, 0x000400FA, 0x00005272, 0x00002958, + 0x0000368B, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, + 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AE, + 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AE, 0x0000013D, 0x000500C5, + 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x0000368B, 0x000200F8, 0x0000368B, + 0x000700F5, 0x00000017, 0x0000471B, 0x000019B2, 0x00001AD7, 0x00003FF9, 0x00002958, 0x000500C7, + 0x00000017, 0x00005D37, 0x0000471B, 0x0000001B, 0x000500C4, 0x00000017, 0x000027FB, 0x00005D37, + 0x000001DF, 0x000500C7, 0x00000017, 0x000050AF, 0x0000471B, 0x0000051E, 0x000500C2, 0x00000017, + 0x000036E6, 0x000050AF, 0x0000009B, 0x000500C5, 0x00000017, 0x00001985, 0x000027FB, 0x000036E6, + 0x00060041, 0x00000294, 0x00005819, 0x0000140E, 0x00000A0B, 0x000054B6, 0x0003003E, 0x00005819, + 0x00001985, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r5g5b6_b5g6r5_swizzle_rbga_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r5g5b6_b5g6r5_swizzle_rbga_scaled_cs.h new file mode 100644 index 0000000..98278c7 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r5g5b6_b5g6r5_swizzle_rbga_scaled_cs.h @@ -0,0 +1,580 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 +%uint_2031647 = OpConstant %uint 2031647 + %uint_11 = OpConstant %uint 11 +%uint_4292935648 = OpConstant %uint 4292935648 + %uint_5 = OpConstant %uint 5 + %uint_1 = OpConstant %uint 1 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_2 = OpConstant %uint 2 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_3 = OpConstant %uint 3 + %uint_32 = OpConstant %uint 32 + %uint_64 = OpConstant %uint 64 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2612 = OpConstantComposite %v3uint %uint_4 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %27 = OpConstantComposite %v4uint %uint_2031647 %uint_2031647 %uint_2031647 %uint_2031647 + %479 = OpConstantComposite %v4uint %uint_11 %uint_11 %uint_11 %uint_11 + %1310 = OpConstantComposite %v4uint %uint_4292935648 %uint_4292935648 %uint_4292935648 %uint_4292935648 + %155 = OpConstantComposite %v4uint %uint_5 %uint_5 %uint_5 %uint_5 + %uint_16 = OpConstant %uint 16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2612 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_2 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_3 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_3 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_7 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_7 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_7 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_8 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_1 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_3 + %23219 = OpBitwiseAnd %uint %10722 %uint_7 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_1 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %8801 = OpLoad %v4uint %20399 + %21106 = OpIEqual %bool %24990 %uint_1 + OpSelectionMerge %13962 None + OpBranchConditional %21106 %10583 %13962 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %8801 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %8801 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13962 + %13962 = OpLabel + %18202 = OpPhi %v4uint %8801 %21313 %16376 %10583 + %23862 = OpBitwiseAnd %v4uint %18202 %27 + %10234 = OpShiftLeftLogical %v4uint %23862 %479 + %20653 = OpBitwiseAnd %v4uint %18202 %1310 + %14053 = OpShiftRightLogical %v4uint %20653 %155 + %6532 = OpBitwiseOr %v4uint %10234 %14053 + %20254 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %20254 %6532 + %15532 = OpIAdd %uint %11197 %int_1 + %6417 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %6417 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_64 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_64 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %13963 None + OpBranchConditional %21106 %10584 %13963 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20654 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20654 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %13963 + %13963 = OpLabel + %18203 = OpPhi %v4uint %6578 %24764 %16377 %10584 + %23863 = OpBitwiseAnd %v4uint %18203 %27 + %10235 = OpShiftLeftLogical %v4uint %23863 %479 + %20655 = OpBitwiseAnd %v4uint %18203 %1310 + %14054 = OpShiftRightLogical %v4uint %20655 %155 + %6533 = OpBitwiseOr %v4uint %10235 %14054 + %22553 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15532 + OpStore %22553 %6533 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r5g5b6_b5g6r5_swizzle_rbga_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x000000EC, 0x001F001F, 0x0004002B, 0x0000000B, 0x00000A2B, 0x0000000B, + 0x0004002B, 0x0000000B, 0x000001F4, 0xFFE0FFE0, 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, + 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, + 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, + 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, + 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, + 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x0004002B, 0x0000000B, 0x00000ACA, 0x00000040, + 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, + 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, 0x00000787, 0x00000A16, 0x00000A1F, 0x00040020, + 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, + 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A34, 0x00000A16, 0x00000A0A, + 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, + 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, + 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, + 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, + 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, + 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, + 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, + 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, + 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x0000001B, + 0x000000EC, 0x000000EC, 0x000000EC, 0x000000EC, 0x0007002C, 0x00000017, 0x000001DF, 0x00000A2B, + 0x00000A2B, 0x00000A2B, 0x00000A2B, 0x0007002C, 0x00000017, 0x0000051E, 0x000001F4, 0x000001F4, + 0x000001F4, 0x000001F4, 0x0007002C, 0x00000017, 0x0000009B, 0x00000A19, 0x00000A19, 0x00000A19, + 0x00000A19, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x00050036, 0x00000008, 0x0000161F, + 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, + 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, + 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005F7D, + 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x000048EB, 0x00005F7D, 0x00000A0A, 0x000500C2, + 0x0000000B, 0x00001FCD, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x0000619E, 0x00001FCD, + 0x00000A13, 0x00050050, 0x00000011, 0x000022A7, 0x00003526, 0x00003526, 0x000500C2, 0x00000011, + 0x00001BAF, 0x000022A7, 0x00000787, 0x000500C7, 0x00000011, 0x00001997, 0x00001BAF, 0x000007A2, + 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, + 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, + 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, + 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, + 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, + 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, + 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, + 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A34, 0x0007004F, + 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, + 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, + 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, + 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, + 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, + 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, + 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A11, 0x00050051, 0x0000000C, + 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, + 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, + 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, + 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, + 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, + 0x00050080, 0x0000000B, 0x00001B12, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x00002BBD, + 0x00001B12, 0x00000A16, 0x00050051, 0x0000000B, 0x000029E2, 0x0000538B, 0x00000000, 0x000500C2, + 0x0000000B, 0x00001DEE, 0x000029E2, 0x00000A13, 0x00050051, 0x0000000B, 0x00002704, 0x0000538B, + 0x00000001, 0x00050050, 0x00000011, 0x00005C0B, 0x00001DEE, 0x00002704, 0x00050086, 0x00000011, + 0x00001F69, 0x00005C0B, 0x00001997, 0x00050051, 0x0000000B, 0x0000366C, 0x00001F69, 0x00000000, + 0x000500C4, 0x0000000B, 0x00004D4D, 0x0000366C, 0x00000A13, 0x00050051, 0x0000000B, 0x000051A9, + 0x00001F69, 0x00000001, 0x00050051, 0x0000000B, 0x000059EE, 0x0000538B, 0x00000002, 0x00060050, + 0x00000014, 0x000024C9, 0x00004D4D, 0x000051A9, 0x000059EE, 0x000300F7, 0x00005341, 0x00000002, + 0x000400FA, 0x000048EB, 0x0000537D, 0x00002DD9, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, + 0x00002970, 0x000024C9, 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, + 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, + 0x00000002, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, + 0x00005B4D, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, + 0x0000000C, 0x00005321, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, + 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, + 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, + 0x0000000C, 0x00006242, 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, + 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, + 0x0000225D, 0x000049FC, 0x00000A1F, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, + 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, + 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, + 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, + 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A1F, 0x000500C3, 0x0000000C, + 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, + 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, + 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, + 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, + 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, + 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, + 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, + 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544B, 0x000047B4, 0x00000A1F, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, + 0x000500C7, 0x0000000C, 0x00004ADE, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, + 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, + 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, + 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, + 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, + 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, + 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, + 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, + 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, + 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x00004158, 0x00000AC8, + 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, 0x0000566F, + 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, 0x00002DD9, 0x0007004F, 0x00000011, 0x00002621, + 0x000024C9, 0x000024C9, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000059CF, 0x00002621, + 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FE, + 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002748, 0x000059CF, 0x00000001, 0x000500C3, + 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00005788, + 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005347, + 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FE, 0x00005347, 0x000500C4, + 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002AB6, 0x00001903, + 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002748, 0x00000A35, 0x000500C4, 0x0000000C, + 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, + 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A0D, 0x000500C7, 0x0000000C, 0x000027B1, + 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, + 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, + 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, + 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, + 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, + 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, + 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, + 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, + 0x0000000C, 0x00001EEC, 0x00001903, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, + 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, + 0x000500C7, 0x0000000C, 0x00002E06, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, + 0x00003C4D, 0x00002E06, 0x0004007C, 0x0000000B, 0x00005670, 0x0000394F, 0x000200F9, 0x00005341, + 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, 0x000024FC, 0x0000566F, 0x0000537D, 0x00005670, + 0x00002DD9, 0x00050084, 0x00000011, 0x00003FA8, 0x00001F69, 0x00001997, 0x00050082, 0x00000011, + 0x00003BBC, 0x00005C0B, 0x00003FA8, 0x00050051, 0x0000000B, 0x00001C87, 0x00001997, 0x00000000, + 0x00050051, 0x0000000B, 0x00005962, 0x00001997, 0x00000001, 0x00050084, 0x0000000B, 0x00003372, + 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, 0x00003CA0, 0x000024FC, 0x00003372, 0x00050051, + 0x0000000B, 0x00003ED4, 0x00003BBC, 0x00000000, 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, + 0x00005962, 0x00050051, 0x0000000B, 0x00001AE6, 0x00003BBC, 0x00000001, 0x00050080, 0x0000000B, + 0x00002B25, 0x00003E12, 0x00001AE6, 0x000500C4, 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A13, + 0x000500C7, 0x0000000B, 0x00005AB3, 0x000029E2, 0x00000A1F, 0x00050080, 0x0000000B, 0x00002557, + 0x0000609D, 0x00005AB3, 0x000500C4, 0x0000000B, 0x000040AD, 0x00002557, 0x00000A0D, 0x00050080, + 0x0000000B, 0x00004EAA, 0x00003CA0, 0x000040AD, 0x00050080, 0x0000000B, 0x00003BA9, 0x00005EAC, + 0x00004EAA, 0x000500C2, 0x0000000B, 0x00003948, 0x00003BA9, 0x00000A16, 0x00060041, 0x00000294, + 0x00004FAF, 0x0000107A, 0x00000A0B, 0x00003948, 0x0004003D, 0x00000017, 0x00002261, 0x00004FAF, + 0x000500AA, 0x00000009, 0x00005272, 0x0000619E, 0x00000A0D, 0x000300F7, 0x0000368A, 0x00000000, + 0x000400FA, 0x00005272, 0x00002957, 0x0000368A, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, + 0x0000475F, 0x00002261, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AC, 0x00002261, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, + 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, + 0x0000368A, 0x000200F8, 0x0000368A, 0x000700F5, 0x00000017, 0x0000471A, 0x00002261, 0x00005341, + 0x00003FF8, 0x00002957, 0x000500C7, 0x00000017, 0x00005D36, 0x0000471A, 0x0000001B, 0x000500C4, + 0x00000017, 0x000027FA, 0x00005D36, 0x000001DF, 0x000500C7, 0x00000017, 0x000050AD, 0x0000471A, + 0x0000051E, 0x000500C2, 0x00000017, 0x000036E5, 0x000050AD, 0x0000009B, 0x000500C5, 0x00000017, + 0x00001984, 0x000027FA, 0x000036E5, 0x00060041, 0x00000294, 0x00004F1E, 0x0000140E, 0x00000A0B, + 0x00002BBD, 0x0003003E, 0x00004F1E, 0x00001984, 0x00050080, 0x0000000B, 0x00003CAC, 0x00002BBD, + 0x00000A0E, 0x000500AC, 0x00000009, 0x00001911, 0x00001C87, 0x00000A0D, 0x000300F7, 0x000060BC, + 0x00000002, 0x000400FA, 0x00001911, 0x00005084, 0x00005094, 0x000200F8, 0x00005084, 0x00050086, + 0x0000000B, 0x00003697, 0x00001DEE, 0x00001C87, 0x00050084, 0x0000000B, 0x0000237E, 0x00003697, + 0x00001C87, 0x00050082, 0x0000000B, 0x00003171, 0x00001DEE, 0x0000237E, 0x00050080, 0x0000000B, + 0x00002527, 0x00003171, 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, 0x00001C87, + 0x000300F7, 0x00001EED, 0x00000000, 0x000400FA, 0x0000343F, 0x0000569E, 0x00002191, 0x000200F8, + 0x0000569E, 0x00050084, 0x0000000B, 0x00004B59, 0x00000ACA, 0x00001C87, 0x000500C4, 0x0000000B, + 0x0000540F, 0x00003171, 0x00000A16, 0x00050082, 0x0000000B, 0x00004944, 0x00004B59, 0x0000540F, + 0x000200F9, 0x00001EED, 0x000200F8, 0x00002191, 0x000200F9, 0x00001EED, 0x000200F8, 0x00001EED, + 0x000700F5, 0x0000000B, 0x0000292C, 0x00004944, 0x0000569E, 0x00000A3A, 0x00002191, 0x000200F9, + 0x000060BC, 0x000200F8, 0x00005094, 0x000200F9, 0x000060BC, 0x000200F8, 0x000060BC, 0x000700F5, + 0x0000000B, 0x000029BC, 0x0000292C, 0x00001EED, 0x00000ACA, 0x00005094, 0x00050084, 0x0000000B, + 0x0000492B, 0x000029BC, 0x00005962, 0x000500C2, 0x0000000B, 0x0000406D, 0x0000492B, 0x00000A16, + 0x00050080, 0x0000000B, 0x0000336B, 0x00003948, 0x0000406D, 0x00060041, 0x00000294, 0x0000571A, + 0x0000107A, 0x00000A0B, 0x0000336B, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, + 0x0000368B, 0x00000000, 0x000400FA, 0x00005272, 0x00002958, 0x0000368B, 0x000200F8, 0x00002958, + 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, + 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AE, 0x000019B2, 0x0000072E, 0x000500C2, + 0x00000017, 0x0000448E, 0x000050AE, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, + 0x0000448E, 0x000200F9, 0x0000368B, 0x000200F8, 0x0000368B, 0x000700F5, 0x00000017, 0x0000471B, + 0x000019B2, 0x000060BC, 0x00003FF9, 0x00002958, 0x000500C7, 0x00000017, 0x00005D37, 0x0000471B, + 0x0000001B, 0x000500C4, 0x00000017, 0x000027FB, 0x00005D37, 0x000001DF, 0x000500C7, 0x00000017, + 0x000050AF, 0x0000471B, 0x0000051E, 0x000500C2, 0x00000017, 0x000036E6, 0x000050AF, 0x0000009B, + 0x000500C5, 0x00000017, 0x00001985, 0x000027FB, 0x000036E6, 0x00060041, 0x00000294, 0x00005819, + 0x0000140E, 0x00000A0B, 0x00003CAC, 0x0003003E, 0x00005819, 0x00001985, 0x000200F9, 0x00004C7A, + 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r5g6b5_b5g6r5_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r5g6b5_b5g6r5_cs.h new file mode 100644 index 0000000..6ea923b --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r5g6b5_b5g6r5_cs.h @@ -0,0 +1,527 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25059 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 +%uint_132122592 = OpConstant %uint 132122592 +%uint_2031647 = OpConstant %uint 2031647 + %uint_11 = OpConstant %uint 11 +%uint_4160813056 = OpConstant %uint 4160813056 + %uint_1 = OpConstant %uint 1 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_2 = OpConstant %uint 2 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_3 = OpConstant %uint 3 + %uint_32 = OpConstant %uint 32 + %uint_64 = OpConstant %uint 64 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2612 = OpConstantComposite %v3uint %uint_4 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %2545 = OpConstantComposite %v4uint %uint_132122592 %uint_132122592 %uint_132122592 %uint_132122592 + %27 = OpConstantComposite %v4uint %uint_2031647 %uint_2031647 %uint_2031647 %uint_2031647 + %479 = OpConstantComposite %v4uint %uint_11 %uint_11 %uint_11 %uint_11 + %1661 = OpConstantComposite %v4uint %uint_4160813056 %uint_4160813056 %uint_4160813056 %uint_4160813056 + %uint_16 = OpConstant %uint 16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2612 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_2 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_7 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_7 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_7 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_8 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_1 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %6362 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %22810 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %8801 = OpLoad %v4uint %17173 + %21106 = OpIEqual %bool %25058 %uint_1 + OpSelectionMerge %13962 None + OpBranchConditional %21106 %10583 %13962 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %8801 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %8801 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13962 + %13962 = OpLabel + %18259 = OpPhi %v4uint %8801 %24387 %16376 %10583 + %23286 = OpBitwiseAnd %v4uint %18259 %2545 + %24373 = OpBitwiseAnd %v4uint %18259 %27 + %24932 = OpShiftLeftLogical %v4uint %24373 %479 + %17045 = OpBitwiseOr %v4uint %23286 %24932 + %21212 = OpBitwiseAnd %v4uint %18259 %1661 + %18088 = OpShiftRightLogical %v4uint %21212 %479 + %6532 = OpBitwiseOr %v4uint %17045 %18088 + %20254 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %20254 %6532 + %21686 = OpIAdd %uint %21685 %int_1 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_64 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %13963 None + OpBranchConditional %21106 %10584 %13963 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %13963 + %13963 = OpLabel + %18260 = OpPhi %v4uint %6578 %6871 %16377 %10584 + %23287 = OpBitwiseAnd %v4uint %18260 %2545 + %24374 = OpBitwiseAnd %v4uint %18260 %27 + %24933 = OpShiftLeftLogical %v4uint %24374 %479 + %17046 = OpBitwiseOr %v4uint %23287 %24933 + %21213 = OpBitwiseAnd %v4uint %18260 %1661 + %18089 = OpShiftRightLogical %v4uint %21213 %479 + %6533 = OpBitwiseOr %v4uint %17046 %18089 + %22553 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21686 + OpStore %22553 %6533 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r5g6b5_b5g6r5_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000061E3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, + 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000902, 0x07E007E0, 0x0004002B, 0x0000000B, 0x000000EC, 0x001F001F, + 0x0004002B, 0x0000000B, 0x00000A2B, 0x0000000B, 0x0004002B, 0x0000000B, 0x000002FC, 0xF800F800, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, + 0x0004002B, 0x0000000B, 0x00000ACA, 0x00000040, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, + 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x00040020, 0x00000291, + 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, + 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A34, 0x00000A16, 0x00000A0A, 0x00000A0A, + 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, + 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, + 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, + 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, + 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, + 0x00000A6A, 0x00000A0D, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, + 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, + 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, + 0x00000017, 0x000009F1, 0x00000902, 0x00000902, 0x00000902, 0x00000902, 0x0007002C, 0x00000017, + 0x0000001B, 0x000000EC, 0x000000EC, 0x000000EC, 0x000000EC, 0x0007002C, 0x00000017, 0x000001DF, + 0x00000A2B, 0x00000A2B, 0x00000A2B, 0x00000A2B, 0x0007002C, 0x00000017, 0x0000067D, 0x000002FC, + 0x000002FC, 0x000002FC, 0x000002FC, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x00050036, + 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, + 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, + 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, + 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, + 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, + 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, + 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, + 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, + 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, + 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, + 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, + 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, + 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, + 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, + 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A34, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, + 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, + 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, + 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, + 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, + 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, + 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, + 0x0000591A, 0x00005BEB, 0x00000A11, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, + 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, + 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, + 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, + 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, + 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00002764, + 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x000054B5, 0x00002764, 0x00000A16, 0x000300F7, + 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, 0x00005768, 0x000051F2, 0x000200F8, 0x00005768, + 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, 0x00004384, 0x00002BF8, 0x000018D9, 0x000200F8, + 0x00002BF8, 0x000500C3, 0x0000000C, 0x000032B3, 0x000044BE, 0x00000A17, 0x000500C3, 0x0000000C, + 0x0000601E, 0x000018DA, 0x00000A11, 0x000500C2, 0x0000000B, 0x00004947, 0x00005789, 0x00000A16, + 0x0004007C, 0x0000000C, 0x000018AA, 0x00004947, 0x00050084, 0x0000000C, 0x00005321, 0x0000601E, + 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000032B3, 0x00005321, 0x000500C2, 0x0000000B, + 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x00003901, 0x00002348, 0x00050084, + 0x0000000C, 0x000020F4, 0x00003B27, 0x00003901, 0x000500C3, 0x0000000C, 0x000032BA, 0x00005BEB, + 0x00000A1A, 0x00050080, 0x0000000C, 0x00005FEE, 0x000032BA, 0x000020F4, 0x000500C4, 0x0000000C, + 0x0000225D, 0x00005FEE, 0x00000A1F, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, + 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, + 0x00005BEB, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000044BE, 0x00000A1D, 0x000500C4, + 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, + 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A1F, 0x000500C3, 0x0000000C, + 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000044BE, 0x00000A14, + 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000601E, 0x000500C7, 0x0000000C, 0x00005A0C, + 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00005BEB, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, + 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, + 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, + 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, + 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, + 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x000018DA, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544B, 0x000047B4, 0x00000A1F, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, + 0x000500C7, 0x0000000C, 0x00004ADE, 0x000044BE, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, + 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, + 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, + 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, + 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, + 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, + 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, + 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, + 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, + 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, + 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, + 0x000018D9, 0x0004007C, 0x00000012, 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, + 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, + 0x0000000C, 0x00002747, 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, + 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, + 0x000018AB, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AB, 0x00050080, + 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, + 0x00000A22, 0x000500C7, 0x0000000C, 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003139, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, + 0x00004397, 0x00000A0D, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, + 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, + 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, + 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002747, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, + 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, + 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, + 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, + 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, + 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, + 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, + 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, + 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, + 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, + 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, + 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, 0x00002BF8, + 0x00002F42, 0x000018D9, 0x000200F9, 0x00005F43, 0x000200F8, 0x000051F2, 0x0004007C, 0x0000000C, + 0x00003CBC, 0x00005789, 0x00050084, 0x0000000C, 0x000060B8, 0x000018DA, 0x00003CBC, 0x00050080, + 0x0000000C, 0x0000208E, 0x000060B8, 0x000044BE, 0x0004007C, 0x0000000C, 0x000022F8, 0x00005788, + 0x00050084, 0x0000000C, 0x00001E9F, 0x0000208E, 0x000022F8, 0x00050080, 0x0000000C, 0x00001F30, + 0x0000591A, 0x00001E9F, 0x000200F9, 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, + 0x00002A3E, 0x0000292C, 0x00001E0B, 0x00001F30, 0x000051F2, 0x0004007C, 0x0000000C, 0x00001A3F, + 0x00005EAC, 0x00050080, 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, + 0x00003EE9, 0x000056CD, 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, + 0x00000294, 0x00004315, 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00002261, + 0x00004315, 0x000500AA, 0x00000009, 0x00005272, 0x000061E2, 0x00000A0D, 0x000300F7, 0x0000368A, + 0x00000000, 0x000400FA, 0x00005272, 0x00002957, 0x0000368A, 0x000200F8, 0x00002957, 0x000500C7, + 0x00000017, 0x0000475F, 0x00002261, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00002261, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, + 0x000200F9, 0x0000368A, 0x000200F8, 0x0000368A, 0x000700F5, 0x00000017, 0x00004753, 0x00002261, + 0x00005F43, 0x00003FF8, 0x00002957, 0x000500C7, 0x00000017, 0x00005AF6, 0x00004753, 0x000009F1, + 0x000500C7, 0x00000017, 0x00005F35, 0x00004753, 0x0000001B, 0x000500C4, 0x00000017, 0x00006164, + 0x00005F35, 0x000001DF, 0x000500C5, 0x00000017, 0x00004295, 0x00005AF6, 0x00006164, 0x000500C7, + 0x00000017, 0x000052DC, 0x00004753, 0x0000067D, 0x000500C2, 0x00000017, 0x000046A8, 0x000052DC, + 0x000001DF, 0x000500C5, 0x00000017, 0x00001984, 0x00004295, 0x000046A8, 0x00060041, 0x00000294, + 0x00004F1E, 0x0000140E, 0x00000A0B, 0x000054B5, 0x0003003E, 0x00004F1E, 0x00001984, 0x00050080, + 0x0000000B, 0x000054B6, 0x000054B5, 0x00000A0E, 0x000300F7, 0x00001AD7, 0x00000002, 0x000400FA, + 0x00004376, 0x000055E9, 0x00001C25, 0x000200F8, 0x000055E9, 0x000200F9, 0x00001AD7, 0x000200F8, + 0x00001C25, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001AD7, 0x000700F5, 0x0000000B, 0x0000456F, + 0x00000ACA, 0x000055E9, 0x00000A3A, 0x00001C25, 0x000500C2, 0x0000000B, 0x000041C0, 0x0000456F, + 0x00000A16, 0x00050080, 0x0000000B, 0x00002ADB, 0x00005665, 0x000041C0, 0x00060041, 0x00000294, + 0x0000571A, 0x0000107A, 0x00000A0B, 0x00002ADB, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, + 0x000300F7, 0x0000368B, 0x00000000, 0x000400FA, 0x00005272, 0x00002958, 0x0000368B, 0x000200F8, + 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, + 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, + 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, + 0x000024D2, 0x0000448E, 0x000200F9, 0x0000368B, 0x000200F8, 0x0000368B, 0x000700F5, 0x00000017, + 0x00004754, 0x000019B2, 0x00001AD7, 0x00003FF9, 0x00002958, 0x000500C7, 0x00000017, 0x00005AF7, + 0x00004754, 0x000009F1, 0x000500C7, 0x00000017, 0x00005F36, 0x00004754, 0x0000001B, 0x000500C4, + 0x00000017, 0x00006165, 0x00005F36, 0x000001DF, 0x000500C5, 0x00000017, 0x00004296, 0x00005AF7, + 0x00006165, 0x000500C7, 0x00000017, 0x000052DD, 0x00004754, 0x0000067D, 0x000500C2, 0x00000017, + 0x000046A9, 0x000052DD, 0x000001DF, 0x000500C5, 0x00000017, 0x00001985, 0x00004296, 0x000046A9, + 0x00060041, 0x00000294, 0x00005819, 0x0000140E, 0x00000A0B, 0x000054B6, 0x0003003E, 0x00005819, + 0x00001985, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_r5g6b5_b5g6r5_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_r5g6b5_b5g6r5_scaled_cs.h new file mode 100644 index 0000000..1ecd973 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_r5g6b5_b5g6r5_scaled_cs.h @@ -0,0 +1,588 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 +%uint_132122592 = OpConstant %uint 132122592 +%uint_2031647 = OpConstant %uint 2031647 + %uint_11 = OpConstant %uint 11 +%uint_4160813056 = OpConstant %uint 4160813056 + %uint_1 = OpConstant %uint 1 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_0 = OpConstant %uint 0 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_2 = OpConstant %uint 2 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_3 = OpConstant %uint 3 + %uint_32 = OpConstant %uint 32 + %uint_64 = OpConstant %uint 64 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2612 = OpConstantComposite %v3uint %uint_4 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %2545 = OpConstantComposite %v4uint %uint_132122592 %uint_132122592 %uint_132122592 %uint_132122592 + %27 = OpConstantComposite %v4uint %uint_2031647 %uint_2031647 %uint_2031647 %uint_2031647 + %479 = OpConstantComposite %v4uint %uint_11 %uint_11 %uint_11 %uint_11 + %1661 = OpConstantComposite %v4uint %uint_4160813056 %uint_4160813056 %uint_4160813056 %uint_4160813056 + %uint_16 = OpConstant %uint 16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2612 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_2 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_3 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_3 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_7 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_7 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_7 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_8 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_1 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_3 + %23219 = OpBitwiseAnd %uint %10722 %uint_7 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_1 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %8801 = OpLoad %v4uint %20399 + %21106 = OpIEqual %bool %24990 %uint_1 + OpSelectionMerge %13962 None + OpBranchConditional %21106 %10583 %13962 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %8801 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %8801 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13962 + %13962 = OpLabel + %18259 = OpPhi %v4uint %8801 %21313 %16376 %10583 + %23286 = OpBitwiseAnd %v4uint %18259 %2545 + %24373 = OpBitwiseAnd %v4uint %18259 %27 + %24932 = OpShiftLeftLogical %v4uint %24373 %479 + %17045 = OpBitwiseOr %v4uint %23286 %24932 + %21212 = OpBitwiseAnd %v4uint %18259 %1661 + %18088 = OpShiftRightLogical %v4uint %21212 %479 + %6532 = OpBitwiseOr %v4uint %17045 %18088 + %20254 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %20254 %6532 + %15532 = OpIAdd %uint %11197 %int_1 + %6417 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %6417 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_64 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_64 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %13963 None + OpBranchConditional %21106 %10584 %13963 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %13963 + %13963 = OpLabel + %18260 = OpPhi %v4uint %6578 %24764 %16377 %10584 + %23287 = OpBitwiseAnd %v4uint %18260 %2545 + %24374 = OpBitwiseAnd %v4uint %18260 %27 + %24933 = OpShiftLeftLogical %v4uint %24374 %479 + %17046 = OpBitwiseOr %v4uint %23287 %24933 + %21213 = OpBitwiseAnd %v4uint %18260 %1661 + %18089 = OpShiftRightLogical %v4uint %21213 %479 + %6533 = OpBitwiseOr %v4uint %17046 %18089 + %22553 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15532 + OpStore %22553 %6533 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_r5g6b5_b5g6r5_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x0004002B, 0x0000000B, 0x00000902, 0x07E007E0, 0x0004002B, 0x0000000B, 0x000000EC, 0x001F001F, + 0x0004002B, 0x0000000B, 0x00000A2B, 0x0000000B, 0x0004002B, 0x0000000B, 0x000002FC, 0xF800F800, + 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, + 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, + 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, + 0x0004002B, 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, + 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, + 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, + 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, + 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, + 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, + 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, + 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, + 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, + 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, + 0x0004002B, 0x0000000B, 0x00000ACA, 0x00000040, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, + 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, + 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, + 0x00000787, 0x00000A16, 0x00000A1F, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, + 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, + 0x00000014, 0x00000A34, 0x00000A16, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, + 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, + 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, + 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, + 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, + 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, + 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, + 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, + 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, + 0x000005FD, 0x0007002C, 0x00000017, 0x000009F1, 0x00000902, 0x00000902, 0x00000902, 0x00000902, + 0x0007002C, 0x00000017, 0x0000001B, 0x000000EC, 0x000000EC, 0x000000EC, 0x000000EC, 0x0007002C, + 0x00000017, 0x000001DF, 0x00000A2B, 0x00000A2B, 0x00000A2B, 0x00000A2B, 0x0007002C, 0x00000017, + 0x0000067D, 0x000002FC, 0x000002FC, 0x000002FC, 0x000002FC, 0x0004002B, 0x0000000B, 0x00000A3A, + 0x00000010, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, + 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, + 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, + 0x000060D7, 0x000500C7, 0x0000000B, 0x00005F7D, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, + 0x000048EB, 0x00005F7D, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001FCD, 0x00003526, 0x00000A10, + 0x000500C7, 0x0000000B, 0x0000619E, 0x00001FCD, 0x00000A13, 0x00050050, 0x00000011, 0x000022A7, + 0x00003526, 0x00003526, 0x000500C2, 0x00000011, 0x00001BAF, 0x000022A7, 0x00000787, 0x000500C7, + 0x00000011, 0x00001997, 0x00001BAF, 0x000007A2, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, + 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, + 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, + 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, + 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, + 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, + 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, + 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, + 0x0000538B, 0x00002A0E, 0x00000A34, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, + 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, + 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, + 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, + 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, + 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, + 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, + 0x00005BEB, 0x00000A11, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, + 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, + 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, + 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, + 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, + 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00001B12, 0x00002A92, + 0x0000578B, 0x000500C2, 0x0000000B, 0x00002BBD, 0x00001B12, 0x00000A16, 0x00050051, 0x0000000B, + 0x000029E2, 0x0000538B, 0x00000000, 0x000500C2, 0x0000000B, 0x00001DEE, 0x000029E2, 0x00000A13, + 0x00050051, 0x0000000B, 0x00002704, 0x0000538B, 0x00000001, 0x00050050, 0x00000011, 0x00005C0B, + 0x00001DEE, 0x00002704, 0x00050086, 0x00000011, 0x00001F69, 0x00005C0B, 0x00001997, 0x00050051, + 0x0000000B, 0x0000366C, 0x00001F69, 0x00000000, 0x000500C4, 0x0000000B, 0x00004D4D, 0x0000366C, + 0x00000A13, 0x00050051, 0x0000000B, 0x000051A9, 0x00001F69, 0x00000001, 0x00050051, 0x0000000B, + 0x000059EE, 0x0000538B, 0x00000002, 0x00060050, 0x00000014, 0x000024C9, 0x00004D4D, 0x000051A9, + 0x000059EE, 0x000300F7, 0x00005341, 0x00000002, 0x000400FA, 0x000048EB, 0x0000537D, 0x00002DD9, + 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, 0x00002970, 0x000024C9, 0x00050051, 0x0000000C, + 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A17, + 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405C, + 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005789, 0x00000A16, 0x0004007C, + 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005321, 0x0000405C, 0x000018AA, + 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, + 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, + 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, 0x00002970, 0x00000000, + 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, + 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A1F, 0x000500C7, + 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, + 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, + 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, + 0x0000434B, 0x00000A1F, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, + 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, + 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, + 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, + 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, + 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, + 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, + 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, + 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, + 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A1F, 0x00050080, + 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000042C2, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, + 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, + 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, + 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, + 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, + 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, + 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00005559, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, + 0x00005559, 0x0004007C, 0x0000000B, 0x0000566F, 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, + 0x00002DD9, 0x0007004F, 0x00000011, 0x00002621, 0x000024C9, 0x000024C9, 0x00000000, 0x00000001, + 0x0004007C, 0x00000012, 0x000059CF, 0x00002621, 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, + 0x00000000, 0x000500C3, 0x0000000C, 0x000024FE, 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, + 0x00002748, 0x000059CF, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, + 0x000500C2, 0x0000000B, 0x00005B4E, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, + 0x00005B4E, 0x00050084, 0x0000000C, 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, + 0x00003F5E, 0x000024FE, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A22, + 0x000500C7, 0x0000000C, 0x00002AB6, 0x00001903, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, + 0x00002748, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, + 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, + 0x00000A0D, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, + 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, + 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, + 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, + 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, + 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, + 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, + 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, + 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, + 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, + 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x00001903, 0x00000A14, + 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, + 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, + 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x00002E06, 0x00004159, + 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4D, 0x00002E06, 0x0004007C, 0x0000000B, + 0x00005670, 0x0000394F, 0x000200F9, 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, + 0x000024FC, 0x0000566F, 0x0000537D, 0x00005670, 0x00002DD9, 0x00050084, 0x00000011, 0x00003FA8, + 0x00001F69, 0x00001997, 0x00050082, 0x00000011, 0x00003BBC, 0x00005C0B, 0x00003FA8, 0x00050051, + 0x0000000B, 0x00001C87, 0x00001997, 0x00000000, 0x00050051, 0x0000000B, 0x00005962, 0x00001997, + 0x00000001, 0x00050084, 0x0000000B, 0x00003372, 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, + 0x00003CA0, 0x000024FC, 0x00003372, 0x00050051, 0x0000000B, 0x00003ED4, 0x00003BBC, 0x00000000, + 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, 0x00005962, 0x00050051, 0x0000000B, 0x00001AE6, + 0x00003BBC, 0x00000001, 0x00050080, 0x0000000B, 0x00002B25, 0x00003E12, 0x00001AE6, 0x000500C4, + 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A13, 0x000500C7, 0x0000000B, 0x00005AB3, 0x000029E2, + 0x00000A1F, 0x00050080, 0x0000000B, 0x00002557, 0x0000609D, 0x00005AB3, 0x000500C4, 0x0000000B, + 0x000040AD, 0x00002557, 0x00000A0D, 0x00050080, 0x0000000B, 0x00004EAA, 0x00003CA0, 0x000040AD, + 0x00050080, 0x0000000B, 0x00003BA9, 0x00005EAC, 0x00004EAA, 0x000500C2, 0x0000000B, 0x00003948, + 0x00003BA9, 0x00000A16, 0x00060041, 0x00000294, 0x00004FAF, 0x0000107A, 0x00000A0B, 0x00003948, + 0x0004003D, 0x00000017, 0x00002261, 0x00004FAF, 0x000500AA, 0x00000009, 0x00005272, 0x0000619E, + 0x00000A0D, 0x000300F7, 0x0000368A, 0x00000000, 0x000400FA, 0x00005272, 0x00002957, 0x0000368A, + 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00002261, 0x000009CE, 0x000500C4, + 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00002261, + 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, + 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x0000368A, 0x000200F8, 0x0000368A, 0x000700F5, + 0x00000017, 0x00004753, 0x00002261, 0x00005341, 0x00003FF8, 0x00002957, 0x000500C7, 0x00000017, + 0x00005AF6, 0x00004753, 0x000009F1, 0x000500C7, 0x00000017, 0x00005F35, 0x00004753, 0x0000001B, + 0x000500C4, 0x00000017, 0x00006164, 0x00005F35, 0x000001DF, 0x000500C5, 0x00000017, 0x00004295, + 0x00005AF6, 0x00006164, 0x000500C7, 0x00000017, 0x000052DC, 0x00004753, 0x0000067D, 0x000500C2, + 0x00000017, 0x000046A8, 0x000052DC, 0x000001DF, 0x000500C5, 0x00000017, 0x00001984, 0x00004295, + 0x000046A8, 0x00060041, 0x00000294, 0x00004F1E, 0x0000140E, 0x00000A0B, 0x00002BBD, 0x0003003E, + 0x00004F1E, 0x00001984, 0x00050080, 0x0000000B, 0x00003CAC, 0x00002BBD, 0x00000A0E, 0x000500AC, + 0x00000009, 0x00001911, 0x00001C87, 0x00000A0D, 0x000300F7, 0x000060BC, 0x00000002, 0x000400FA, + 0x00001911, 0x00005084, 0x00005094, 0x000200F8, 0x00005084, 0x00050086, 0x0000000B, 0x00003697, + 0x00001DEE, 0x00001C87, 0x00050084, 0x0000000B, 0x0000237E, 0x00003697, 0x00001C87, 0x00050082, + 0x0000000B, 0x00003171, 0x00001DEE, 0x0000237E, 0x00050080, 0x0000000B, 0x00002527, 0x00003171, + 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, 0x00001C87, 0x000300F7, 0x00001EED, + 0x00000000, 0x000400FA, 0x0000343F, 0x0000569E, 0x00002191, 0x000200F8, 0x0000569E, 0x00050084, + 0x0000000B, 0x00004B59, 0x00000ACA, 0x00001C87, 0x000500C4, 0x0000000B, 0x0000540F, 0x00003171, + 0x00000A16, 0x00050082, 0x0000000B, 0x00004944, 0x00004B59, 0x0000540F, 0x000200F9, 0x00001EED, + 0x000200F8, 0x00002191, 0x000200F9, 0x00001EED, 0x000200F8, 0x00001EED, 0x000700F5, 0x0000000B, + 0x0000292C, 0x00004944, 0x0000569E, 0x00000A3A, 0x00002191, 0x000200F9, 0x000060BC, 0x000200F8, + 0x00005094, 0x000200F9, 0x000060BC, 0x000200F8, 0x000060BC, 0x000700F5, 0x0000000B, 0x000029BC, + 0x0000292C, 0x00001EED, 0x00000ACA, 0x00005094, 0x00050084, 0x0000000B, 0x0000492B, 0x000029BC, + 0x00005962, 0x000500C2, 0x0000000B, 0x0000406D, 0x0000492B, 0x00000A16, 0x00050080, 0x0000000B, + 0x0000336B, 0x00003948, 0x0000406D, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, + 0x0000336B, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x0000368B, 0x00000000, + 0x000400FA, 0x00005272, 0x00002958, 0x0000368B, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, + 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, + 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, + 0x0000368B, 0x000200F8, 0x0000368B, 0x000700F5, 0x00000017, 0x00004754, 0x000019B2, 0x000060BC, + 0x00003FF9, 0x00002958, 0x000500C7, 0x00000017, 0x00005AF7, 0x00004754, 0x000009F1, 0x000500C7, + 0x00000017, 0x00005F36, 0x00004754, 0x0000001B, 0x000500C4, 0x00000017, 0x00006165, 0x00005F36, + 0x000001DF, 0x000500C5, 0x00000017, 0x00004296, 0x00005AF7, 0x00006165, 0x000500C7, 0x00000017, + 0x000052DD, 0x00004754, 0x0000067D, 0x000500C2, 0x00000017, 0x000046A9, 0x000052DD, 0x000001DF, + 0x000500C5, 0x00000017, 0x00001985, 0x00004296, 0x000046A9, 0x00060041, 0x00000294, 0x00005819, + 0x0000140E, 0x00000A0B, 0x00003CAC, 0x0003003E, 0x00005819, 0x00001985, 0x000200F9, 0x00004C7A, + 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_rg16_snorm_float_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_rg16_snorm_float_cs.h new file mode 100644 index 0000000..c053c01 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_rg16_snorm_float_cs.h @@ -0,0 +1,627 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25059 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %float_n1 = OpConstant %float -1 + %v4int = OpTypeVector %int 4 + %int_16 = OpConstant %int 16 +%float_3_05185094en05 = OpConstant %float 3.05185094e-05 + %uint_0 = OpConstant %uint 0 + %v2float = OpTypeVector %float 2 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %uint_3 = OpConstant %uint 3 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_16 = OpConstant %uint 16 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2603 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %1284 = OpConstantComposite %v4float %float_n1 %float_n1 %float_n1 %float_n1 + %770 = OpConstantComposite %v4int %int_16 %int_16 %int_16 %int_16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2603 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_4 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %6362 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %22810 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %12537 None + OpBranchConditional %15139 %11064 %12537 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %12537 + %12537 = OpLabel + %12106 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %15375 = OpBitcast %v4int %12106 + %16910 = OpShiftLeftLogical %v4int %15375 %770 + %16536 = OpShiftRightArithmetic %v4int %16910 %770 + %10903 = OpConvertSToF %v4float %16536 + %20413 = OpVectorTimesScalar %v4float %10903 %float_3_05185094en05 + %23989 = OpExtInst %v4float %1 FMax %1284 %20413 + %14338 = OpShiftRightArithmetic %v4int %15375 %770 + %6607 = OpConvertSToF %v4float %14338 + %18247 = OpVectorTimesScalar %v4float %6607 %float_3_05185094en05 + %24070 = OpExtInst %v4float %1 FMax %1284 %18247 + %24330 = OpCompositeExtract %float %23989 0 + %14319 = OpCompositeExtract %float %24070 0 + %19232 = OpCompositeConstruct %v2float %24330 %14319 + %8561 = OpExtInst %uint %1 PackHalf2x16 %19232 + %23487 = OpCompositeExtract %float %23989 1 + %14759 = OpCompositeExtract %float %24070 1 + %19233 = OpCompositeConstruct %v2float %23487 %14759 + %8562 = OpExtInst %uint %1 PackHalf2x16 %19233 + %23488 = OpCompositeExtract %float %23989 2 + %14760 = OpCompositeExtract %float %24070 2 + %19234 = OpCompositeConstruct %v2float %23488 %14760 + %8563 = OpExtInst %uint %1 PackHalf2x16 %19234 + %23489 = OpCompositeExtract %float %23989 3 + %14761 = OpCompositeExtract %float %24070 3 + %19213 = OpCompositeConstruct %v2float %23489 %14761 + %8430 = OpExtInst %uint %1 PackHalf2x16 %19213 + %15035 = OpCompositeConstruct %v4uint %8561 %8562 %8563 %8430 + %17859 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %17859 %15035 + %21686 = OpIAdd %uint %21685 %int_1 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_32 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %6871 %16377 %10584 + OpSelectionMerge %12538 None + OpBranchConditional %15139 %11065 %12538 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %12538 + %12538 = OpLabel + %12107 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %15376 = OpBitcast %v4int %12107 + %16911 = OpShiftLeftLogical %v4int %15376 %770 + %16537 = OpShiftRightArithmetic %v4int %16911 %770 + %10904 = OpConvertSToF %v4float %16537 + %20414 = OpVectorTimesScalar %v4float %10904 %float_3_05185094en05 + %23990 = OpExtInst %v4float %1 FMax %1284 %20414 + %14339 = OpShiftRightArithmetic %v4int %15376 %770 + %6608 = OpConvertSToF %v4float %14339 + %18248 = OpVectorTimesScalar %v4float %6608 %float_3_05185094en05 + %24071 = OpExtInst %v4float %1 FMax %1284 %18248 + %24331 = OpCompositeExtract %float %23990 0 + %14320 = OpCompositeExtract %float %24071 0 + %19235 = OpCompositeConstruct %v2float %24331 %14320 + %8564 = OpExtInst %uint %1 PackHalf2x16 %19235 + %23490 = OpCompositeExtract %float %23990 1 + %14762 = OpCompositeExtract %float %24071 1 + %19236 = OpCompositeConstruct %v2float %23490 %14762 + %8565 = OpExtInst %uint %1 PackHalf2x16 %19236 + %23491 = OpCompositeExtract %float %23990 2 + %14763 = OpCompositeExtract %float %24071 2 + %19237 = OpCompositeConstruct %v2float %23491 %14763 + %8566 = OpExtInst %uint %1 PackHalf2x16 %19237 + %23492 = OpCompositeExtract %float %23990 3 + %14764 = OpCompositeExtract %float %24071 3 + %19214 = OpCompositeConstruct %v2float %23492 %14764 + %8431 = OpExtInst %uint %1 PackHalf2x16 %19214 + %15036 = OpCompositeConstruct %v4uint %8564 %8565 %8566 %8431 + %20158 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21686 + OpStore %20158 %15036 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_rg16_snorm_float_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000061E3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, + 0x00000004, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, 0x0000000B, + 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, + 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, + 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x0004002B, + 0x0000000D, 0x00000341, 0xBF800000, 0x00040017, 0x0000001A, 0x0000000C, 0x00000004, 0x0004002B, + 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000D, 0x00000A38, 0x38000100, 0x0004002B, + 0x0000000B, 0x00000A0A, 0x00000000, 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, + 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, + 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, + 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, + 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, + 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, + 0x0000000C, 0x00000A39, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, + 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, + 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, + 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, + 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, + 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, + 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, + 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, + 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, + 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A2B, + 0x00000A13, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0003001D, + 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, + 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, + 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, + 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, + 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0004002B, 0x0000000B, 0x00000A25, + 0x00000009, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, + 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, + 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, + 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0007002C, 0x0000001D, 0x00000504, + 0x00000341, 0x00000341, 0x00000341, 0x00000341, 0x0007002C, 0x0000001A, 0x00000302, 0x00000A3B, + 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, + 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, + 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, + 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, + 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, + 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, + 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, + 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, + 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, + 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, + 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, + 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, + 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, + 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, + 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A2B, + 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, + 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, + 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, + 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, + 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, + 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A17, 0x00050051, + 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, + 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, + 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, + 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, + 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, + 0x00002042, 0x00050080, 0x0000000B, 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, + 0x000054B5, 0x00002764, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, + 0x00005768, 0x000051F2, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, + 0x00004384, 0x00002BF8, 0x000018D9, 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, 0x000032B3, + 0x000044BE, 0x00000A17, 0x000500C3, 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, 0x000500C2, + 0x0000000B, 0x00004947, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00004947, + 0x00050084, 0x0000000C, 0x00005321, 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, + 0x000032B3, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, + 0x0000000C, 0x00003901, 0x00002348, 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, 0x00003901, + 0x000500C3, 0x0000000C, 0x000032BA, 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, 0x00005FEE, + 0x000032BA, 0x000020F4, 0x000500C4, 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A22, 0x000500C7, + 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, + 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003138, 0x000044BE, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, + 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, + 0x0000434B, 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, + 0x0000000C, 0x00002215, 0x000044BE, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, + 0x0000601E, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, + 0x00004112, 0x00005BEB, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, + 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, + 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, + 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, + 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A39, + 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, + 0x000018DA, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, 0x00050080, + 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000044BE, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, + 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, + 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, + 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, + 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, + 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, + 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, + 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, 0x000019AD, + 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, + 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, 0x00000001, + 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, + 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, 0x0000000C, + 0x00005347, 0x0000405C, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, + 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002AB6, + 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, 0x000500C4, + 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, + 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, 0x0000000C, + 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, + 0x000018E7, 0x00000A39, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, + 0x0000000C, 0x000047B5, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, + 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, + 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, + 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, + 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, + 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, + 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, + 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, + 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, + 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, + 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, + 0x0000000C, 0x0000292C, 0x000054ED, 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, 0x00005F43, + 0x000200F8, 0x000051F2, 0x0004007C, 0x0000000C, 0x00003CBC, 0x00005789, 0x00050084, 0x0000000C, + 0x000060B8, 0x000018DA, 0x00003CBC, 0x00050080, 0x0000000C, 0x0000208E, 0x000060B8, 0x000044BE, + 0x0004007C, 0x0000000C, 0x000022F8, 0x00005788, 0x00050084, 0x0000000C, 0x00001E9F, 0x0000208E, + 0x000022F8, 0x00050080, 0x0000000C, 0x00001F30, 0x0000591A, 0x00001E9F, 0x000200F9, 0x00005F43, + 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, 0x00001F30, + 0x000051F2, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, 0x000056CD, + 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, 0x0000000B, + 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, 0x00004315, 0x0000107A, 0x00000A0B, + 0x00005665, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004315, 0x000500AA, 0x00000009, 0x000035C0, + 0x000061E2, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x000061E2, 0x00000A10, 0x000500A6, + 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, + 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, + 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, + 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, + 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, + 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, 0x00005F43, 0x00003FF8, + 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000061E2, 0x00000A13, 0x000500A6, 0x00000009, + 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x000030F9, 0x00000000, 0x000400FA, 0x00003B23, + 0x00002B38, 0x000030F9, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, + 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, + 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x000030F9, 0x000200F8, 0x000030F9, 0x000700F5, + 0x00000017, 0x00002F4A, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x0004007C, 0x0000001A, + 0x00003C0F, 0x00002F4A, 0x000500C4, 0x0000001A, 0x0000420E, 0x00003C0F, 0x00000302, 0x000500C3, + 0x0000001A, 0x00004098, 0x0000420E, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A97, 0x00004098, + 0x0005008E, 0x0000001D, 0x00004FBD, 0x00002A97, 0x00000A38, 0x0007000C, 0x0000001D, 0x00005DB5, + 0x00000001, 0x00000028, 0x00000504, 0x00004FBD, 0x000500C3, 0x0000001A, 0x00003802, 0x00003C0F, + 0x00000302, 0x0004006F, 0x0000001D, 0x000019CF, 0x00003802, 0x0005008E, 0x0000001D, 0x00004747, + 0x000019CF, 0x00000A38, 0x0007000C, 0x0000001D, 0x00005E06, 0x00000001, 0x00000028, 0x00000504, + 0x00004747, 0x00050051, 0x0000000D, 0x00005F0A, 0x00005DB5, 0x00000000, 0x00050051, 0x0000000D, + 0x000037EF, 0x00005E06, 0x00000000, 0x00050050, 0x00000013, 0x00004B20, 0x00005F0A, 0x000037EF, + 0x0006000C, 0x0000000B, 0x00002171, 0x00000001, 0x0000003A, 0x00004B20, 0x00050051, 0x0000000D, + 0x00005BBF, 0x00005DB5, 0x00000001, 0x00050051, 0x0000000D, 0x000039A7, 0x00005E06, 0x00000001, + 0x00050050, 0x00000013, 0x00004B21, 0x00005BBF, 0x000039A7, 0x0006000C, 0x0000000B, 0x00002172, + 0x00000001, 0x0000003A, 0x00004B21, 0x00050051, 0x0000000D, 0x00005BC0, 0x00005DB5, 0x00000002, + 0x00050051, 0x0000000D, 0x000039A8, 0x00005E06, 0x00000002, 0x00050050, 0x00000013, 0x00004B22, + 0x00005BC0, 0x000039A8, 0x0006000C, 0x0000000B, 0x00002173, 0x00000001, 0x0000003A, 0x00004B22, + 0x00050051, 0x0000000D, 0x00005BC1, 0x00005DB5, 0x00000003, 0x00050051, 0x0000000D, 0x000039A9, + 0x00005E06, 0x00000003, 0x00050050, 0x00000013, 0x00004B0D, 0x00005BC1, 0x000039A9, 0x0006000C, + 0x0000000B, 0x000020EE, 0x00000001, 0x0000003A, 0x00004B0D, 0x00070050, 0x00000017, 0x00003ABB, + 0x00002171, 0x00002172, 0x00002173, 0x000020EE, 0x00060041, 0x00000294, 0x000045C3, 0x0000140E, + 0x00000A0B, 0x000054B5, 0x0003003E, 0x000045C3, 0x00003ABB, 0x00050080, 0x0000000B, 0x000054B6, + 0x000054B5, 0x00000A0E, 0x000300F7, 0x00001AD7, 0x00000002, 0x000400FA, 0x00004376, 0x000055E9, + 0x00001C25, 0x000200F8, 0x000055E9, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001C25, 0x000200F9, + 0x00001AD7, 0x000200F8, 0x00001AD7, 0x000700F5, 0x0000000B, 0x0000456F, 0x00000A6A, 0x000055E9, + 0x00000A3A, 0x00001C25, 0x000500C2, 0x0000000B, 0x000041C0, 0x0000456F, 0x00000A16, 0x00050080, + 0x0000000B, 0x00002ADB, 0x00005665, 0x000041C0, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, + 0x00000A0B, 0x00002ADB, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x00003A1A, + 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, + 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, + 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, + 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, + 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, + 0x00001AD7, 0x00003FF9, 0x00002958, 0x000300F7, 0x000030FA, 0x00000000, 0x000400FA, 0x00003B23, + 0x00002B39, 0x000030FA, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, + 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, + 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x000030FA, 0x000200F8, 0x000030FA, 0x000700F5, + 0x00000017, 0x00002F4B, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x0004007C, 0x0000001A, + 0x00003C10, 0x00002F4B, 0x000500C4, 0x0000001A, 0x0000420F, 0x00003C10, 0x00000302, 0x000500C3, + 0x0000001A, 0x00004099, 0x0000420F, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A98, 0x00004099, + 0x0005008E, 0x0000001D, 0x00004FBE, 0x00002A98, 0x00000A38, 0x0007000C, 0x0000001D, 0x00005DB6, + 0x00000001, 0x00000028, 0x00000504, 0x00004FBE, 0x000500C3, 0x0000001A, 0x00003803, 0x00003C10, + 0x00000302, 0x0004006F, 0x0000001D, 0x000019D0, 0x00003803, 0x0005008E, 0x0000001D, 0x00004748, + 0x000019D0, 0x00000A38, 0x0007000C, 0x0000001D, 0x00005E07, 0x00000001, 0x00000028, 0x00000504, + 0x00004748, 0x00050051, 0x0000000D, 0x00005F0B, 0x00005DB6, 0x00000000, 0x00050051, 0x0000000D, + 0x000037F0, 0x00005E07, 0x00000000, 0x00050050, 0x00000013, 0x00004B23, 0x00005F0B, 0x000037F0, + 0x0006000C, 0x0000000B, 0x00002174, 0x00000001, 0x0000003A, 0x00004B23, 0x00050051, 0x0000000D, + 0x00005BC2, 0x00005DB6, 0x00000001, 0x00050051, 0x0000000D, 0x000039AA, 0x00005E07, 0x00000001, + 0x00050050, 0x00000013, 0x00004B24, 0x00005BC2, 0x000039AA, 0x0006000C, 0x0000000B, 0x00002175, + 0x00000001, 0x0000003A, 0x00004B24, 0x00050051, 0x0000000D, 0x00005BC3, 0x00005DB6, 0x00000002, + 0x00050051, 0x0000000D, 0x000039AB, 0x00005E07, 0x00000002, 0x00050050, 0x00000013, 0x00004B25, + 0x00005BC3, 0x000039AB, 0x0006000C, 0x0000000B, 0x00002176, 0x00000001, 0x0000003A, 0x00004B25, + 0x00050051, 0x0000000D, 0x00005BC4, 0x00005DB6, 0x00000003, 0x00050051, 0x0000000D, 0x000039AC, + 0x00005E07, 0x00000003, 0x00050050, 0x00000013, 0x00004B0E, 0x00005BC4, 0x000039AC, 0x0006000C, + 0x0000000B, 0x000020EF, 0x00000001, 0x0000003A, 0x00004B0E, 0x00070050, 0x00000017, 0x00003ABC, + 0x00002174, 0x00002175, 0x00002176, 0x000020EF, 0x00060041, 0x00000294, 0x00004EBE, 0x0000140E, + 0x00000A0B, 0x000054B6, 0x0003003E, 0x00004EBE, 0x00003ABC, 0x000200F9, 0x00004C7A, 0x000200F8, + 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_rg16_snorm_float_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_rg16_snorm_float_scaled_cs.h new file mode 100644 index 0000000..a4a6cff --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_rg16_snorm_float_scaled_cs.h @@ -0,0 +1,689 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %float_n1 = OpConstant %float -1 + %v4int = OpTypeVector %int 4 + %int_16 = OpConstant %int 16 +%float_3_05185094en05 = OpConstant %float 3.05185094e-05 + %uint_0 = OpConstant %uint 0 + %v2float = OpTypeVector %float 2 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %uint_3 = OpConstant %uint 3 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_16 = OpConstant %uint 16 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2603 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %1284 = OpConstantComposite %v4float %float_n1 %float_n1 %float_n1 %float_n1 + %770 = OpConstantComposite %v4int %int_16 %int_16 %int_16 %int_16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2603 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_4 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_2 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_2 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_2 + %23219 = OpBitwiseAnd %uint %10722 %uint_3 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_2 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %7338 = OpLoad %v4uint %20399 + %13760 = OpIEqual %bool %24990 %uint_1 + %21366 = OpIEqual %bool %24990 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %21313 %16376 %10583 + %19638 = OpIEqual %bool %24990 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %12537 None + OpBranchConditional %15139 %11064 %12537 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %12537 + %12537 = OpLabel + %12106 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %15375 = OpBitcast %v4int %12106 + %16910 = OpShiftLeftLogical %v4int %15375 %770 + %16536 = OpShiftRightArithmetic %v4int %16910 %770 + %10903 = OpConvertSToF %v4float %16536 + %20413 = OpVectorTimesScalar %v4float %10903 %float_3_05185094en05 + %23989 = OpExtInst %v4float %1 FMax %1284 %20413 + %14338 = OpShiftRightArithmetic %v4int %15375 %770 + %6607 = OpConvertSToF %v4float %14338 + %18247 = OpVectorTimesScalar %v4float %6607 %float_3_05185094en05 + %24070 = OpExtInst %v4float %1 FMax %1284 %18247 + %24330 = OpCompositeExtract %float %23989 0 + %14319 = OpCompositeExtract %float %24070 0 + %19232 = OpCompositeConstruct %v2float %24330 %14319 + %8561 = OpExtInst %uint %1 PackHalf2x16 %19232 + %23487 = OpCompositeExtract %float %23989 1 + %14759 = OpCompositeExtract %float %24070 1 + %19233 = OpCompositeConstruct %v2float %23487 %14759 + %8562 = OpExtInst %uint %1 PackHalf2x16 %19233 + %23488 = OpCompositeExtract %float %23989 2 + %14760 = OpCompositeExtract %float %24070 2 + %19234 = OpCompositeConstruct %v2float %23488 %14760 + %8563 = OpExtInst %uint %1 PackHalf2x16 %19234 + %23489 = OpCompositeExtract %float %23989 3 + %14761 = OpCompositeExtract %float %24070 3 + %19213 = OpCompositeConstruct %v2float %23489 %14761 + %8430 = OpExtInst %uint %1 PackHalf2x16 %19213 + %15035 = OpCompositeConstruct %v4uint %8561 %8562 %8563 %8430 + %17859 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %17859 %15035 + %15532 = OpIAdd %uint %11197 %int_1 + %6417 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %6417 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_32 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_32 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %24764 %16377 %10584 + OpSelectionMerge %12538 None + OpBranchConditional %15139 %11065 %12538 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %12538 + %12538 = OpLabel + %12107 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %15376 = OpBitcast %v4int %12107 + %16911 = OpShiftLeftLogical %v4int %15376 %770 + %16537 = OpShiftRightArithmetic %v4int %16911 %770 + %10904 = OpConvertSToF %v4float %16537 + %20414 = OpVectorTimesScalar %v4float %10904 %float_3_05185094en05 + %23990 = OpExtInst %v4float %1 FMax %1284 %20414 + %14339 = OpShiftRightArithmetic %v4int %15376 %770 + %6608 = OpConvertSToF %v4float %14339 + %18248 = OpVectorTimesScalar %v4float %6608 %float_3_05185094en05 + %24071 = OpExtInst %v4float %1 FMax %1284 %18248 + %24331 = OpCompositeExtract %float %23990 0 + %14320 = OpCompositeExtract %float %24071 0 + %19235 = OpCompositeConstruct %v2float %24331 %14320 + %8564 = OpExtInst %uint %1 PackHalf2x16 %19235 + %23490 = OpCompositeExtract %float %23990 1 + %14762 = OpCompositeExtract %float %24071 1 + %19236 = OpCompositeConstruct %v2float %23490 %14762 + %8565 = OpExtInst %uint %1 PackHalf2x16 %19236 + %23491 = OpCompositeExtract %float %23990 2 + %14763 = OpCompositeExtract %float %24071 2 + %19237 = OpCompositeConstruct %v2float %23491 %14763 + %8566 = OpExtInst %uint %1 PackHalf2x16 %19237 + %23492 = OpCompositeExtract %float %23990 3 + %14764 = OpCompositeExtract %float %24071 3 + %19214 = OpCompositeConstruct %v2float %23492 %14764 + %8431 = OpExtInst %uint %1 PackHalf2x16 %19214 + %15036 = OpCompositeConstruct %v4uint %8564 %8565 %8566 %8431 + %20158 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15532 + OpStore %20158 %15036 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_rg16_snorm_float_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, + 0x00000004, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, + 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, + 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x0004002B, + 0x0000000D, 0x00000341, 0xBF800000, 0x00040017, 0x0000001A, 0x0000000C, 0x00000004, 0x0004002B, + 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000D, 0x00000A38, 0x38000100, 0x0004002B, + 0x0000000B, 0x00000A0A, 0x00000000, 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, + 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, + 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, + 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, + 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, + 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, + 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A39, 0x0000000F, 0x0004002B, + 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, + 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, + 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, + 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, + 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, + 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, + 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, + 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, 0x00000787, + 0x00000A16, 0x00000A1F, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, + 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, + 0x00000A2B, 0x00000A13, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, + 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, + 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, 0x00000011, + 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0007002C, + 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, + 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, + 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0007002C, 0x0000001D, 0x00000504, 0x00000341, 0x00000341, + 0x00000341, 0x00000341, 0x0007002C, 0x0000001A, 0x00000302, 0x00000A3B, 0x00000A3B, 0x00000A3B, + 0x00000A3B, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, + 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, + 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, + 0x000060D7, 0x000500C7, 0x0000000B, 0x00005F7D, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, + 0x000048EB, 0x00005F7D, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001FCD, 0x00003526, 0x00000A10, + 0x000500C7, 0x0000000B, 0x0000619E, 0x00001FCD, 0x00000A13, 0x00050050, 0x00000011, 0x000022A7, + 0x00003526, 0x00003526, 0x000500C2, 0x00000011, 0x00001BAF, 0x000022A7, 0x00000787, 0x000500C7, + 0x00000011, 0x00001997, 0x00001BAF, 0x000007A2, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, + 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, + 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, + 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, + 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, + 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, + 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, + 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, + 0x0000538B, 0x00002A0E, 0x00000A2B, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, + 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, + 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, + 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, + 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, + 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, + 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, + 0x00005BEB, 0x00000A17, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, + 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, + 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, + 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, + 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, + 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00001B12, 0x00002A92, + 0x0000578B, 0x000500C2, 0x0000000B, 0x00002BBD, 0x00001B12, 0x00000A16, 0x00050051, 0x0000000B, + 0x000029E2, 0x0000538B, 0x00000000, 0x000500C2, 0x0000000B, 0x00001DEE, 0x000029E2, 0x00000A10, + 0x00050051, 0x0000000B, 0x00002704, 0x0000538B, 0x00000001, 0x00050050, 0x00000011, 0x00005C0B, + 0x00001DEE, 0x00002704, 0x00050086, 0x00000011, 0x00001F69, 0x00005C0B, 0x00001997, 0x00050051, + 0x0000000B, 0x0000366C, 0x00001F69, 0x00000000, 0x000500C4, 0x0000000B, 0x00004D4D, 0x0000366C, + 0x00000A10, 0x00050051, 0x0000000B, 0x000051A9, 0x00001F69, 0x00000001, 0x00050051, 0x0000000B, + 0x000059EE, 0x0000538B, 0x00000002, 0x00060050, 0x00000014, 0x000024C9, 0x00004D4D, 0x000051A9, + 0x000059EE, 0x000300F7, 0x00005341, 0x00000002, 0x000400FA, 0x000048EB, 0x0000537D, 0x00002DD9, + 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, 0x00002970, 0x000024C9, 0x00050051, 0x0000000C, + 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A17, + 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405C, + 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005789, 0x00000A16, 0x0004007C, + 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005321, 0x0000405C, 0x000018AA, + 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, + 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, + 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, 0x00002970, 0x00000000, + 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, + 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A22, 0x000500C7, + 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, + 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, + 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, + 0x0000434B, 0x00000A22, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, + 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, + 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, + 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, + 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, + 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, + 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, + 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A39, + 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, + 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, 0x00050080, + 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000042C2, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, + 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, + 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, + 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, + 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, + 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, + 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00005559, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, + 0x00005559, 0x0004007C, 0x0000000B, 0x0000566F, 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, + 0x00002DD9, 0x0007004F, 0x00000011, 0x00002621, 0x000024C9, 0x000024C9, 0x00000000, 0x00000001, + 0x0004007C, 0x00000012, 0x000059CF, 0x00002621, 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, + 0x00000000, 0x000500C3, 0x0000000C, 0x000024FE, 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, + 0x00002748, 0x000059CF, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, + 0x000500C2, 0x0000000B, 0x00005B4E, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, + 0x00005B4E, 0x00050084, 0x0000000C, 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, + 0x00003F5E, 0x000024FE, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A25, + 0x000500C7, 0x0000000C, 0x00002AB6, 0x00001903, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, + 0x00002748, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, + 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, + 0x00000A10, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, + 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, + 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A39, 0x00050080, 0x0000000C, 0x00004D30, + 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, + 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, + 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, + 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, + 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, + 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, + 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, + 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, + 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x00001903, 0x00000A14, + 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, + 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, + 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x00002E06, 0x00004159, + 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4D, 0x00002E06, 0x0004007C, 0x0000000B, + 0x00005670, 0x0000394F, 0x000200F9, 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, + 0x000024FC, 0x0000566F, 0x0000537D, 0x00005670, 0x00002DD9, 0x00050084, 0x00000011, 0x00003FA8, + 0x00001F69, 0x00001997, 0x00050082, 0x00000011, 0x00003BBC, 0x00005C0B, 0x00003FA8, 0x00050051, + 0x0000000B, 0x00001C87, 0x00001997, 0x00000000, 0x00050051, 0x0000000B, 0x00005962, 0x00001997, + 0x00000001, 0x00050084, 0x0000000B, 0x00003372, 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, + 0x00003CA0, 0x000024FC, 0x00003372, 0x00050051, 0x0000000B, 0x00003ED4, 0x00003BBC, 0x00000000, + 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, 0x00005962, 0x00050051, 0x0000000B, 0x00001AE6, + 0x00003BBC, 0x00000001, 0x00050080, 0x0000000B, 0x00002B25, 0x00003E12, 0x00001AE6, 0x000500C4, + 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A10, 0x000500C7, 0x0000000B, 0x00005AB3, 0x000029E2, + 0x00000A13, 0x00050080, 0x0000000B, 0x00002557, 0x0000609D, 0x00005AB3, 0x000500C4, 0x0000000B, + 0x000040AD, 0x00002557, 0x00000A10, 0x00050080, 0x0000000B, 0x00004EAA, 0x00003CA0, 0x000040AD, + 0x00050080, 0x0000000B, 0x00003BA9, 0x00005EAC, 0x00004EAA, 0x000500C2, 0x0000000B, 0x00003948, + 0x00003BA9, 0x00000A16, 0x00060041, 0x00000294, 0x00004FAF, 0x0000107A, 0x00000A0B, 0x00003948, + 0x0004003D, 0x00000017, 0x00001CAA, 0x00004FAF, 0x000500AA, 0x00000009, 0x000035C0, 0x0000619E, + 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x0000619E, 0x00000A10, 0x000500A6, 0x00000009, + 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, + 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, + 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, + 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, + 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, + 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, 0x00005341, 0x00003FF8, 0x00002957, + 0x000500AA, 0x00000009, 0x00004CB6, 0x0000619E, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, + 0x00005376, 0x00004CB6, 0x000300F7, 0x000030F9, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, + 0x000030F9, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, + 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, + 0x00005E17, 0x00003BE7, 0x000200F9, 0x000030F9, 0x000200F8, 0x000030F9, 0x000700F5, 0x00000017, + 0x00002F4A, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x0004007C, 0x0000001A, 0x00003C0F, + 0x00002F4A, 0x000500C4, 0x0000001A, 0x0000420E, 0x00003C0F, 0x00000302, 0x000500C3, 0x0000001A, + 0x00004098, 0x0000420E, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A97, 0x00004098, 0x0005008E, + 0x0000001D, 0x00004FBD, 0x00002A97, 0x00000A38, 0x0007000C, 0x0000001D, 0x00005DB5, 0x00000001, + 0x00000028, 0x00000504, 0x00004FBD, 0x000500C3, 0x0000001A, 0x00003802, 0x00003C0F, 0x00000302, + 0x0004006F, 0x0000001D, 0x000019CF, 0x00003802, 0x0005008E, 0x0000001D, 0x00004747, 0x000019CF, + 0x00000A38, 0x0007000C, 0x0000001D, 0x00005E06, 0x00000001, 0x00000028, 0x00000504, 0x00004747, + 0x00050051, 0x0000000D, 0x00005F0A, 0x00005DB5, 0x00000000, 0x00050051, 0x0000000D, 0x000037EF, + 0x00005E06, 0x00000000, 0x00050050, 0x00000013, 0x00004B20, 0x00005F0A, 0x000037EF, 0x0006000C, + 0x0000000B, 0x00002171, 0x00000001, 0x0000003A, 0x00004B20, 0x00050051, 0x0000000D, 0x00005BBF, + 0x00005DB5, 0x00000001, 0x00050051, 0x0000000D, 0x000039A7, 0x00005E06, 0x00000001, 0x00050050, + 0x00000013, 0x00004B21, 0x00005BBF, 0x000039A7, 0x0006000C, 0x0000000B, 0x00002172, 0x00000001, + 0x0000003A, 0x00004B21, 0x00050051, 0x0000000D, 0x00005BC0, 0x00005DB5, 0x00000002, 0x00050051, + 0x0000000D, 0x000039A8, 0x00005E06, 0x00000002, 0x00050050, 0x00000013, 0x00004B22, 0x00005BC0, + 0x000039A8, 0x0006000C, 0x0000000B, 0x00002173, 0x00000001, 0x0000003A, 0x00004B22, 0x00050051, + 0x0000000D, 0x00005BC1, 0x00005DB5, 0x00000003, 0x00050051, 0x0000000D, 0x000039A9, 0x00005E06, + 0x00000003, 0x00050050, 0x00000013, 0x00004B0D, 0x00005BC1, 0x000039A9, 0x0006000C, 0x0000000B, + 0x000020EE, 0x00000001, 0x0000003A, 0x00004B0D, 0x00070050, 0x00000017, 0x00003ABB, 0x00002171, + 0x00002172, 0x00002173, 0x000020EE, 0x00060041, 0x00000294, 0x000045C3, 0x0000140E, 0x00000A0B, + 0x00002BBD, 0x0003003E, 0x000045C3, 0x00003ABB, 0x00050080, 0x0000000B, 0x00003CAC, 0x00002BBD, + 0x00000A0E, 0x000500AC, 0x00000009, 0x00001911, 0x00001C87, 0x00000A0D, 0x000300F7, 0x000060BC, + 0x00000002, 0x000400FA, 0x00001911, 0x00005084, 0x00005094, 0x000200F8, 0x00005084, 0x00050086, + 0x0000000B, 0x00003697, 0x00001DEE, 0x00001C87, 0x00050084, 0x0000000B, 0x0000237E, 0x00003697, + 0x00001C87, 0x00050082, 0x0000000B, 0x00003171, 0x00001DEE, 0x0000237E, 0x00050080, 0x0000000B, + 0x00002527, 0x00003171, 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, 0x00001C87, + 0x000300F7, 0x00001EED, 0x00000000, 0x000400FA, 0x0000343F, 0x0000569E, 0x00002191, 0x000200F8, + 0x0000569E, 0x00050084, 0x0000000B, 0x00004B59, 0x00000A6A, 0x00001C87, 0x000500C4, 0x0000000B, + 0x0000540F, 0x00003171, 0x00000A16, 0x00050082, 0x0000000B, 0x00004944, 0x00004B59, 0x0000540F, + 0x000200F9, 0x00001EED, 0x000200F8, 0x00002191, 0x000200F9, 0x00001EED, 0x000200F8, 0x00001EED, + 0x000700F5, 0x0000000B, 0x0000292C, 0x00004944, 0x0000569E, 0x00000A3A, 0x00002191, 0x000200F9, + 0x000060BC, 0x000200F8, 0x00005094, 0x000200F9, 0x000060BC, 0x000200F8, 0x000060BC, 0x000700F5, + 0x0000000B, 0x000029BC, 0x0000292C, 0x00001EED, 0x00000A6A, 0x00005094, 0x00050084, 0x0000000B, + 0x0000492B, 0x000029BC, 0x00005962, 0x000500C2, 0x0000000B, 0x0000406D, 0x0000492B, 0x00000A16, + 0x00050080, 0x0000000B, 0x0000336B, 0x00003948, 0x0000406D, 0x00060041, 0x00000294, 0x0000571A, + 0x0000107A, 0x00000A0B, 0x0000336B, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, + 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, + 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, + 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, + 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, + 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, + 0x000019B2, 0x000060BC, 0x00003FF9, 0x00002958, 0x000300F7, 0x000030FA, 0x00000000, 0x000400FA, + 0x00003B23, 0x00002B39, 0x000030FA, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, + 0x00002AAC, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, + 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x000030FA, 0x000200F8, 0x000030FA, + 0x000700F5, 0x00000017, 0x00002F4B, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x0004007C, + 0x0000001A, 0x00003C10, 0x00002F4B, 0x000500C4, 0x0000001A, 0x0000420F, 0x00003C10, 0x00000302, + 0x000500C3, 0x0000001A, 0x00004099, 0x0000420F, 0x00000302, 0x0004006F, 0x0000001D, 0x00002A98, + 0x00004099, 0x0005008E, 0x0000001D, 0x00004FBE, 0x00002A98, 0x00000A38, 0x0007000C, 0x0000001D, + 0x00005DB6, 0x00000001, 0x00000028, 0x00000504, 0x00004FBE, 0x000500C3, 0x0000001A, 0x00003803, + 0x00003C10, 0x00000302, 0x0004006F, 0x0000001D, 0x000019D0, 0x00003803, 0x0005008E, 0x0000001D, + 0x00004748, 0x000019D0, 0x00000A38, 0x0007000C, 0x0000001D, 0x00005E07, 0x00000001, 0x00000028, + 0x00000504, 0x00004748, 0x00050051, 0x0000000D, 0x00005F0B, 0x00005DB6, 0x00000000, 0x00050051, + 0x0000000D, 0x000037F0, 0x00005E07, 0x00000000, 0x00050050, 0x00000013, 0x00004B23, 0x00005F0B, + 0x000037F0, 0x0006000C, 0x0000000B, 0x00002174, 0x00000001, 0x0000003A, 0x00004B23, 0x00050051, + 0x0000000D, 0x00005BC2, 0x00005DB6, 0x00000001, 0x00050051, 0x0000000D, 0x000039AA, 0x00005E07, + 0x00000001, 0x00050050, 0x00000013, 0x00004B24, 0x00005BC2, 0x000039AA, 0x0006000C, 0x0000000B, + 0x00002175, 0x00000001, 0x0000003A, 0x00004B24, 0x00050051, 0x0000000D, 0x00005BC3, 0x00005DB6, + 0x00000002, 0x00050051, 0x0000000D, 0x000039AB, 0x00005E07, 0x00000002, 0x00050050, 0x00000013, + 0x00004B25, 0x00005BC3, 0x000039AB, 0x0006000C, 0x0000000B, 0x00002176, 0x00000001, 0x0000003A, + 0x00004B25, 0x00050051, 0x0000000D, 0x00005BC4, 0x00005DB6, 0x00000003, 0x00050051, 0x0000000D, + 0x000039AC, 0x00005E07, 0x00000003, 0x00050050, 0x00000013, 0x00004B0E, 0x00005BC4, 0x000039AC, + 0x0006000C, 0x0000000B, 0x000020EF, 0x00000001, 0x0000003A, 0x00004B0E, 0x00070050, 0x00000017, + 0x00003ABC, 0x00002174, 0x00002175, 0x00002176, 0x000020EF, 0x00060041, 0x00000294, 0x00004EBE, + 0x0000140E, 0x00000A0B, 0x00003CAC, 0x0003003E, 0x00004EBE, 0x00003ABC, 0x000200F9, 0x00004C7A, + 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_rg16_unorm_float_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_rg16_unorm_float_cs.h new file mode 100644 index 0000000..18d328f --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_rg16_unorm_float_cs.h @@ -0,0 +1,610 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25059 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %uint_65535 = OpConstant %uint 65535 +%float_1_52590219en05 = OpConstant %float 1.52590219e-05 + %uint_16 = OpConstant %uint 16 + %uint_0 = OpConstant %uint 0 + %v2float = OpTypeVector %float 2 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %uint_3 = OpConstant %uint 3 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2603 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %850 = OpConstantComposite %v4uint %uint_65535 %uint_65535 %uint_65535 %uint_65535 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2603 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_4 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %6362 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %22810 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %13962 None + OpBranchConditional %15139 %11064 %13962 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %13962 + %13962 = OpLabel + %16606 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %18240 = OpBitwiseAnd %v4uint %16606 %850 + %9137 = OpConvertUToF %v4float %18240 + %19365 = OpVectorTimesScalar %v4float %9137 %float_1_52590219en05 + %23367 = OpShiftRightLogical %v4uint %16606 %749 + %18492 = OpConvertUToF %v4float %23367 + %18450 = OpVectorTimesScalar %v4float %18492 %float_1_52590219en05 + %6268 = OpCompositeExtract %float %19365 0 + %13806 = OpCompositeExtract %float %18450 0 + %19232 = OpCompositeConstruct %v2float %6268 %13806 + %8561 = OpExtInst %uint %1 PackHalf2x16 %19232 + %23487 = OpCompositeExtract %float %19365 1 + %14759 = OpCompositeExtract %float %18450 1 + %19233 = OpCompositeConstruct %v2float %23487 %14759 + %8562 = OpExtInst %uint %1 PackHalf2x16 %19233 + %23488 = OpCompositeExtract %float %19365 2 + %14760 = OpCompositeExtract %float %18450 2 + %19234 = OpCompositeConstruct %v2float %23488 %14760 + %8563 = OpExtInst %uint %1 PackHalf2x16 %19234 + %23489 = OpCompositeExtract %float %19365 3 + %14761 = OpCompositeExtract %float %18450 3 + %19213 = OpCompositeConstruct %v2float %23489 %14761 + %8430 = OpExtInst %uint %1 PackHalf2x16 %19213 + %15035 = OpCompositeConstruct %v4uint %8561 %8562 %8563 %8430 + %17859 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %17859 %15035 + %21686 = OpIAdd %uint %21685 %int_1 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_32 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %6871 %16377 %10584 + OpSelectionMerge %13963 None + OpBranchConditional %15139 %11065 %13963 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %13963 + %13963 = OpLabel + %16607 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %18241 = OpBitwiseAnd %v4uint %16607 %850 + %9138 = OpConvertUToF %v4float %18241 + %19366 = OpVectorTimesScalar %v4float %9138 %float_1_52590219en05 + %23368 = OpShiftRightLogical %v4uint %16607 %749 + %18493 = OpConvertUToF %v4float %23368 + %18451 = OpVectorTimesScalar %v4float %18493 %float_1_52590219en05 + %6269 = OpCompositeExtract %float %19366 0 + %13807 = OpCompositeExtract %float %18451 0 + %19235 = OpCompositeConstruct %v2float %6269 %13807 + %8564 = OpExtInst %uint %1 PackHalf2x16 %19235 + %23490 = OpCompositeExtract %float %19366 1 + %14762 = OpCompositeExtract %float %18451 1 + %19236 = OpCompositeConstruct %v2float %23490 %14762 + %8565 = OpExtInst %uint %1 PackHalf2x16 %19236 + %23491 = OpCompositeExtract %float %19366 2 + %14763 = OpCompositeExtract %float %18451 2 + %19237 = OpCompositeConstruct %v2float %23491 %14763 + %8566 = OpExtInst %uint %1 PackHalf2x16 %19237 + %23492 = OpCompositeExtract %float %19366 3 + %14764 = OpCompositeExtract %float %18451 3 + %19214 = OpCompositeConstruct %v2float %23492 %14764 + %8431 = OpExtInst %uint %1 PackHalf2x16 %19214 + %15036 = OpCompositeConstruct %v4uint %8564 %8565 %8566 %8431 + %20158 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21686 + OpStore %20158 %15036 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_rg16_unorm_float_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000061E3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, + 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x0004002B, + 0x0000000B, 0x000001C1, 0x0000FFFF, 0x0004002B, 0x0000000D, 0x0000092A, 0x37800080, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x00040017, + 0x00000013, 0x0000000D, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, + 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, + 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, + 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, + 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, + 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, + 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, + 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, + 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, + 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, + 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, + 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, + 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, + 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, + 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, + 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x00040020, 0x00000291, 0x00000009, + 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, + 0x00000001, 0x0006002C, 0x00000014, 0x00000A2B, 0x00000A13, 0x00000A0A, 0x00000A0A, 0x00040017, + 0x0000000F, 0x00000009, 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, + 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, + 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, + 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, + 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, + 0x00000A0D, 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0007002C, 0x00000017, 0x000009CE, + 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, + 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, + 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, + 0x00000A3A, 0x0007002C, 0x00000017, 0x00000352, 0x000001C1, 0x000001C1, 0x000001C1, 0x000001C1, + 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, + 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, + 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, + 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, + 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, + 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, + 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, + 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, + 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, + 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, + 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, + 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, + 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, + 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, + 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A2B, 0x0007004F, 0x00000011, 0x000042F0, + 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, + 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, + 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, + 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, + 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, + 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, + 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A17, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, + 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, + 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, + 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, + 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, + 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, + 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x000054B5, 0x00002764, 0x00000A16, + 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, 0x00005768, 0x000051F2, 0x000200F8, + 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, 0x00004384, 0x00002BF8, 0x000018D9, + 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, 0x000032B3, 0x000044BE, 0x00000A17, 0x000500C3, + 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, 0x000500C2, 0x0000000B, 0x00004947, 0x00005789, + 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00004947, 0x00050084, 0x0000000C, 0x00005321, + 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000032B3, 0x00005321, 0x000500C2, + 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x00003901, 0x00002348, + 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, 0x00003901, 0x000500C3, 0x0000000C, 0x000032BA, + 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, 0x00005FEE, 0x000032BA, 0x000020F4, 0x000500C4, + 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, + 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, + 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000044BE, 0x00000A1D, + 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, + 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A22, 0x000500C3, + 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000044BE, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000601E, 0x000500C7, 0x0000000C, + 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00005BEB, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, + 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, + 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, + 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, + 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x000018DA, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, + 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000044BE, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, + 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, + 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, + 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, + 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, + 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, + 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, + 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, + 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, + 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, + 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, + 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, + 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005788, 0x00000A19, 0x0004007C, + 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AB, + 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, + 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, + 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, + 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, + 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, + 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, + 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, + 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002747, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, + 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, + 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, + 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, + 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, + 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, + 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, + 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, + 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, + 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, + 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, + 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, + 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, + 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, 0x00005F43, 0x000200F8, 0x000051F2, 0x0004007C, + 0x0000000C, 0x00003CBC, 0x00005789, 0x00050084, 0x0000000C, 0x000060B8, 0x000018DA, 0x00003CBC, + 0x00050080, 0x0000000C, 0x0000208E, 0x000060B8, 0x000044BE, 0x0004007C, 0x0000000C, 0x000022F8, + 0x00005788, 0x00050084, 0x0000000C, 0x00001E9F, 0x0000208E, 0x000022F8, 0x00050080, 0x0000000C, + 0x00001F30, 0x0000591A, 0x00001E9F, 0x000200F9, 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, + 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, 0x00001F30, 0x000051F2, 0x0004007C, 0x0000000C, + 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, + 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, + 0x00060041, 0x00000294, 0x00004315, 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, + 0x00001CAA, 0x00004315, 0x000500AA, 0x00000009, 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, + 0x00000009, 0x00005376, 0x000061E2, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, + 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, + 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, + 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, + 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, + 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, + 0x00000017, 0x00005879, 0x00001CAA, 0x00005F43, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, + 0x00004CB6, 0x000061E2, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, + 0x000300F7, 0x0000368A, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x0000368A, 0x000200F8, + 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, + 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, + 0x000200F9, 0x0000368A, 0x000200F8, 0x0000368A, 0x000700F5, 0x00000017, 0x000040DE, 0x00005879, + 0x00003463, 0x000029E8, 0x00002B38, 0x000500C7, 0x00000017, 0x00004740, 0x000040DE, 0x00000352, + 0x00040070, 0x0000001D, 0x000023B1, 0x00004740, 0x0005008E, 0x0000001D, 0x00004BA5, 0x000023B1, + 0x0000092A, 0x000500C2, 0x00000017, 0x00005B47, 0x000040DE, 0x000002ED, 0x00040070, 0x0000001D, + 0x0000483C, 0x00005B47, 0x0005008E, 0x0000001D, 0x00004812, 0x0000483C, 0x0000092A, 0x00050051, + 0x0000000D, 0x0000187C, 0x00004BA5, 0x00000000, 0x00050051, 0x0000000D, 0x000035EE, 0x00004812, + 0x00000000, 0x00050050, 0x00000013, 0x00004B20, 0x0000187C, 0x000035EE, 0x0006000C, 0x0000000B, + 0x00002171, 0x00000001, 0x0000003A, 0x00004B20, 0x00050051, 0x0000000D, 0x00005BBF, 0x00004BA5, + 0x00000001, 0x00050051, 0x0000000D, 0x000039A7, 0x00004812, 0x00000001, 0x00050050, 0x00000013, + 0x00004B21, 0x00005BBF, 0x000039A7, 0x0006000C, 0x0000000B, 0x00002172, 0x00000001, 0x0000003A, + 0x00004B21, 0x00050051, 0x0000000D, 0x00005BC0, 0x00004BA5, 0x00000002, 0x00050051, 0x0000000D, + 0x000039A8, 0x00004812, 0x00000002, 0x00050050, 0x00000013, 0x00004B22, 0x00005BC0, 0x000039A8, + 0x0006000C, 0x0000000B, 0x00002173, 0x00000001, 0x0000003A, 0x00004B22, 0x00050051, 0x0000000D, + 0x00005BC1, 0x00004BA5, 0x00000003, 0x00050051, 0x0000000D, 0x000039A9, 0x00004812, 0x00000003, + 0x00050050, 0x00000013, 0x00004B0D, 0x00005BC1, 0x000039A9, 0x0006000C, 0x0000000B, 0x000020EE, + 0x00000001, 0x0000003A, 0x00004B0D, 0x00070050, 0x00000017, 0x00003ABB, 0x00002171, 0x00002172, + 0x00002173, 0x000020EE, 0x00060041, 0x00000294, 0x000045C3, 0x0000140E, 0x00000A0B, 0x000054B5, + 0x0003003E, 0x000045C3, 0x00003ABB, 0x00050080, 0x0000000B, 0x000054B6, 0x000054B5, 0x00000A0E, + 0x000300F7, 0x00001AD7, 0x00000002, 0x000400FA, 0x00004376, 0x000055E9, 0x00001C25, 0x000200F8, + 0x000055E9, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001C25, 0x000200F9, 0x00001AD7, 0x000200F8, + 0x00001AD7, 0x000700F5, 0x0000000B, 0x0000456F, 0x00000A6A, 0x000055E9, 0x00000A3A, 0x00001C25, + 0x000500C2, 0x0000000B, 0x000041C0, 0x0000456F, 0x00000A16, 0x00050080, 0x0000000B, 0x00002ADB, + 0x00005665, 0x000041C0, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, 0x00002ADB, + 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, + 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, + 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, + 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, + 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, + 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x00001AD7, 0x00003FF9, + 0x00002958, 0x000300F7, 0x0000368B, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, 0x0000368B, + 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, 0x000500C2, + 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, + 0x00003BE8, 0x000200F9, 0x0000368B, 0x000200F8, 0x0000368B, 0x000700F5, 0x00000017, 0x000040DF, + 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x000500C7, 0x00000017, 0x00004741, 0x000040DF, + 0x00000352, 0x00040070, 0x0000001D, 0x000023B2, 0x00004741, 0x0005008E, 0x0000001D, 0x00004BA6, + 0x000023B2, 0x0000092A, 0x000500C2, 0x00000017, 0x00005B48, 0x000040DF, 0x000002ED, 0x00040070, + 0x0000001D, 0x0000483D, 0x00005B48, 0x0005008E, 0x0000001D, 0x00004813, 0x0000483D, 0x0000092A, + 0x00050051, 0x0000000D, 0x0000187D, 0x00004BA6, 0x00000000, 0x00050051, 0x0000000D, 0x000035EF, + 0x00004813, 0x00000000, 0x00050050, 0x00000013, 0x00004B23, 0x0000187D, 0x000035EF, 0x0006000C, + 0x0000000B, 0x00002174, 0x00000001, 0x0000003A, 0x00004B23, 0x00050051, 0x0000000D, 0x00005BC2, + 0x00004BA6, 0x00000001, 0x00050051, 0x0000000D, 0x000039AA, 0x00004813, 0x00000001, 0x00050050, + 0x00000013, 0x00004B24, 0x00005BC2, 0x000039AA, 0x0006000C, 0x0000000B, 0x00002175, 0x00000001, + 0x0000003A, 0x00004B24, 0x00050051, 0x0000000D, 0x00005BC3, 0x00004BA6, 0x00000002, 0x00050051, + 0x0000000D, 0x000039AB, 0x00004813, 0x00000002, 0x00050050, 0x00000013, 0x00004B25, 0x00005BC3, + 0x000039AB, 0x0006000C, 0x0000000B, 0x00002176, 0x00000001, 0x0000003A, 0x00004B25, 0x00050051, + 0x0000000D, 0x00005BC4, 0x00004BA6, 0x00000003, 0x00050051, 0x0000000D, 0x000039AC, 0x00004813, + 0x00000003, 0x00050050, 0x00000013, 0x00004B0E, 0x00005BC4, 0x000039AC, 0x0006000C, 0x0000000B, + 0x000020EF, 0x00000001, 0x0000003A, 0x00004B0E, 0x00070050, 0x00000017, 0x00003ABC, 0x00002174, + 0x00002175, 0x00002176, 0x000020EF, 0x00060041, 0x00000294, 0x00004EBE, 0x0000140E, 0x00000A0B, + 0x000054B6, 0x0003003E, 0x00004EBE, 0x00003ABC, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, + 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_rg16_unorm_float_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_rg16_unorm_float_scaled_cs.h new file mode 100644 index 0000000..83dca56 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_rg16_unorm_float_scaled_cs.h @@ -0,0 +1,672 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %uint_65535 = OpConstant %uint 65535 +%float_1_52590219en05 = OpConstant %float 1.52590219e-05 + %uint_16 = OpConstant %uint 16 + %uint_0 = OpConstant %uint 0 + %v2float = OpTypeVector %float 2 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %uint_3 = OpConstant %uint 3 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2603 = OpConstantComposite %v3uint %uint_3 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %uint_9 = OpConstant %uint 9 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %850 = OpConstantComposite %v4uint %uint_65535 %uint_65535 %uint_65535 %uint_65535 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2603 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_4 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_2 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_2 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_8 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_8 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_8 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_9 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_2 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_2 + %23219 = OpBitwiseAnd %uint %10722 %uint_3 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_2 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %7338 = OpLoad %v4uint %20399 + %13760 = OpIEqual %bool %24990 %uint_1 + %21366 = OpIEqual %bool %24990 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %21313 %16376 %10583 + %19638 = OpIEqual %bool %24990 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %13962 None + OpBranchConditional %15139 %11064 %13962 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %13962 + %13962 = OpLabel + %16606 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %18240 = OpBitwiseAnd %v4uint %16606 %850 + %9137 = OpConvertUToF %v4float %18240 + %19365 = OpVectorTimesScalar %v4float %9137 %float_1_52590219en05 + %23367 = OpShiftRightLogical %v4uint %16606 %749 + %18492 = OpConvertUToF %v4float %23367 + %18450 = OpVectorTimesScalar %v4float %18492 %float_1_52590219en05 + %6268 = OpCompositeExtract %float %19365 0 + %13806 = OpCompositeExtract %float %18450 0 + %19232 = OpCompositeConstruct %v2float %6268 %13806 + %8561 = OpExtInst %uint %1 PackHalf2x16 %19232 + %23487 = OpCompositeExtract %float %19365 1 + %14759 = OpCompositeExtract %float %18450 1 + %19233 = OpCompositeConstruct %v2float %23487 %14759 + %8562 = OpExtInst %uint %1 PackHalf2x16 %19233 + %23488 = OpCompositeExtract %float %19365 2 + %14760 = OpCompositeExtract %float %18450 2 + %19234 = OpCompositeConstruct %v2float %23488 %14760 + %8563 = OpExtInst %uint %1 PackHalf2x16 %19234 + %23489 = OpCompositeExtract %float %19365 3 + %14761 = OpCompositeExtract %float %18450 3 + %19213 = OpCompositeConstruct %v2float %23489 %14761 + %8430 = OpExtInst %uint %1 PackHalf2x16 %19213 + %15035 = OpCompositeConstruct %v4uint %8561 %8562 %8563 %8430 + %17859 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %17859 %15035 + %15532 = OpIAdd %uint %11197 %int_1 + %6417 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %6417 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_32 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_32 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %24764 %16377 %10584 + OpSelectionMerge %13963 None + OpBranchConditional %15139 %11065 %13963 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %13963 + %13963 = OpLabel + %16607 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %18241 = OpBitwiseAnd %v4uint %16607 %850 + %9138 = OpConvertUToF %v4float %18241 + %19366 = OpVectorTimesScalar %v4float %9138 %float_1_52590219en05 + %23368 = OpShiftRightLogical %v4uint %16607 %749 + %18493 = OpConvertUToF %v4float %23368 + %18451 = OpVectorTimesScalar %v4float %18493 %float_1_52590219en05 + %6269 = OpCompositeExtract %float %19366 0 + %13807 = OpCompositeExtract %float %18451 0 + %19235 = OpCompositeConstruct %v2float %6269 %13807 + %8564 = OpExtInst %uint %1 PackHalf2x16 %19235 + %23490 = OpCompositeExtract %float %19366 1 + %14762 = OpCompositeExtract %float %18451 1 + %19236 = OpCompositeConstruct %v2float %23490 %14762 + %8565 = OpExtInst %uint %1 PackHalf2x16 %19236 + %23491 = OpCompositeExtract %float %19366 2 + %14763 = OpCompositeExtract %float %18451 2 + %19237 = OpCompositeConstruct %v2float %23491 %14763 + %8566 = OpExtInst %uint %1 PackHalf2x16 %19237 + %23492 = OpCompositeExtract %float %19366 3 + %14764 = OpCompositeExtract %float %18451 3 + %19214 = OpCompositeConstruct %v2float %23492 %14764 + %8431 = OpExtInst %uint %1 PackHalf2x16 %19214 + %15036 = OpCompositeConstruct %v4uint %8564 %8565 %8566 %8431 + %20158 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15532 + OpStore %20158 %15036 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_rg16_unorm_float_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x0004002B, + 0x0000000B, 0x000001C1, 0x0000FFFF, 0x0004002B, 0x0000000D, 0x0000092A, 0x37800080, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x00040017, + 0x00000013, 0x0000000D, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, + 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, + 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, + 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, + 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, + 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, + 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, + 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, + 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, + 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, + 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, + 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, + 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, + 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, + 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, + 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, + 0x0000000B, 0x0005002C, 0x00000011, 0x00000787, 0x00000A16, 0x00000A1F, 0x00040020, 0x00000291, + 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, + 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A2B, 0x00000A13, 0x00000A0A, 0x00000A0A, + 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, + 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, + 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, + 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, + 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, + 0x00000A6A, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0004002B, + 0x0000000B, 0x00000A25, 0x00000009, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, + 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, + 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, + 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0007002C, + 0x00000017, 0x00000352, 0x000001C1, 0x000001C1, 0x000001C1, 0x000001C1, 0x00050036, 0x00000008, + 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, + 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, + 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, + 0x00005F7D, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x000048EB, 0x00005F7D, 0x00000A0A, + 0x000500C2, 0x0000000B, 0x00001FCD, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x0000619E, + 0x00001FCD, 0x00000A13, 0x00050050, 0x00000011, 0x000022A7, 0x00003526, 0x00003526, 0x000500C2, + 0x00000011, 0x00001BAF, 0x000022A7, 0x00000787, 0x000500C7, 0x00000011, 0x00001997, 0x00001BAF, + 0x000007A2, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, + 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, + 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, + 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, + 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, + 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, + 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, + 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A2B, + 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, + 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, + 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, + 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, + 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, + 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A17, 0x00050051, + 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, + 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, + 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, + 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, + 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, + 0x00002042, 0x00050080, 0x0000000B, 0x00001B12, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, + 0x00002BBD, 0x00001B12, 0x00000A16, 0x00050051, 0x0000000B, 0x000029E2, 0x0000538B, 0x00000000, + 0x000500C2, 0x0000000B, 0x00001DEE, 0x000029E2, 0x00000A10, 0x00050051, 0x0000000B, 0x00002704, + 0x0000538B, 0x00000001, 0x00050050, 0x00000011, 0x00005C0B, 0x00001DEE, 0x00002704, 0x00050086, + 0x00000011, 0x00001F69, 0x00005C0B, 0x00001997, 0x00050051, 0x0000000B, 0x0000366C, 0x00001F69, + 0x00000000, 0x000500C4, 0x0000000B, 0x00004D4D, 0x0000366C, 0x00000A10, 0x00050051, 0x0000000B, + 0x000051A9, 0x00001F69, 0x00000001, 0x00050051, 0x0000000B, 0x000059EE, 0x0000538B, 0x00000002, + 0x00060050, 0x00000014, 0x000024C9, 0x00004D4D, 0x000051A9, 0x000059EE, 0x000300F7, 0x00005341, + 0x00000002, 0x000400FA, 0x000048EB, 0x0000537D, 0x00002DD9, 0x000200F8, 0x0000537D, 0x0004007C, + 0x00000016, 0x00002970, 0x000024C9, 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, + 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, + 0x00002970, 0x00000002, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, + 0x0000000B, 0x00005B4D, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, + 0x00050084, 0x0000000C, 0x00005321, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, + 0x000024FD, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, + 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, + 0x00050051, 0x0000000C, 0x00006242, 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, + 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, + 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A22, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, + 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, + 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, + 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, + 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A22, 0x000500C3, + 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, + 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, + 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, + 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, + 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, + 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, + 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A22, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, + 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, + 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, + 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, + 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, + 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, + 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, + 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, + 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, + 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, + 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x00004158, + 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, + 0x0000566F, 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, 0x00002DD9, 0x0007004F, 0x00000011, + 0x00002621, 0x000024C9, 0x000024C9, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000059CF, + 0x00002621, 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, 0x00000000, 0x000500C3, 0x0000000C, + 0x000024FE, 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002748, 0x000059CF, 0x00000001, + 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4E, + 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, + 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FE, 0x00005347, + 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002AB6, + 0x00001903, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002748, 0x00000A35, 0x000500C4, + 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, + 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A10, 0x000500C7, 0x0000000C, + 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, + 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, + 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, + 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, + 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, + 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, + 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, + 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, + 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, + 0x000500C3, 0x0000000C, 0x00001EEC, 0x00001903, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, + 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, + 0x0000544F, 0x000500C7, 0x0000000C, 0x00002E06, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, + 0x0000394F, 0x00003C4D, 0x00002E06, 0x0004007C, 0x0000000B, 0x00005670, 0x0000394F, 0x000200F9, + 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, 0x000024FC, 0x0000566F, 0x0000537D, + 0x00005670, 0x00002DD9, 0x00050084, 0x00000011, 0x00003FA8, 0x00001F69, 0x00001997, 0x00050082, + 0x00000011, 0x00003BBC, 0x00005C0B, 0x00003FA8, 0x00050051, 0x0000000B, 0x00001C87, 0x00001997, + 0x00000000, 0x00050051, 0x0000000B, 0x00005962, 0x00001997, 0x00000001, 0x00050084, 0x0000000B, + 0x00003372, 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, 0x00003CA0, 0x000024FC, 0x00003372, + 0x00050051, 0x0000000B, 0x00003ED4, 0x00003BBC, 0x00000000, 0x00050084, 0x0000000B, 0x00003E12, + 0x00003ED4, 0x00005962, 0x00050051, 0x0000000B, 0x00001AE6, 0x00003BBC, 0x00000001, 0x00050080, + 0x0000000B, 0x00002B25, 0x00003E12, 0x00001AE6, 0x000500C4, 0x0000000B, 0x0000609D, 0x00002B25, + 0x00000A10, 0x000500C7, 0x0000000B, 0x00005AB3, 0x000029E2, 0x00000A13, 0x00050080, 0x0000000B, + 0x00002557, 0x0000609D, 0x00005AB3, 0x000500C4, 0x0000000B, 0x000040AD, 0x00002557, 0x00000A10, + 0x00050080, 0x0000000B, 0x00004EAA, 0x00003CA0, 0x000040AD, 0x00050080, 0x0000000B, 0x00003BA9, + 0x00005EAC, 0x00004EAA, 0x000500C2, 0x0000000B, 0x00003948, 0x00003BA9, 0x00000A16, 0x00060041, + 0x00000294, 0x00004FAF, 0x0000107A, 0x00000A0B, 0x00003948, 0x0004003D, 0x00000017, 0x00001CAA, + 0x00004FAF, 0x000500AA, 0x00000009, 0x000035C0, 0x0000619E, 0x00000A0D, 0x000500AA, 0x00000009, + 0x00005376, 0x0000619E, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, 0x00005376, + 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, + 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, + 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, + 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, + 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, + 0x00005879, 0x00001CAA, 0x00005341, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, + 0x0000619E, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, + 0x0000368A, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x0000368A, 0x000200F8, 0x00002B38, + 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, + 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, + 0x0000368A, 0x000200F8, 0x0000368A, 0x000700F5, 0x00000017, 0x000040DE, 0x00005879, 0x00003463, + 0x000029E8, 0x00002B38, 0x000500C7, 0x00000017, 0x00004740, 0x000040DE, 0x00000352, 0x00040070, + 0x0000001D, 0x000023B1, 0x00004740, 0x0005008E, 0x0000001D, 0x00004BA5, 0x000023B1, 0x0000092A, + 0x000500C2, 0x00000017, 0x00005B47, 0x000040DE, 0x000002ED, 0x00040070, 0x0000001D, 0x0000483C, + 0x00005B47, 0x0005008E, 0x0000001D, 0x00004812, 0x0000483C, 0x0000092A, 0x00050051, 0x0000000D, + 0x0000187C, 0x00004BA5, 0x00000000, 0x00050051, 0x0000000D, 0x000035EE, 0x00004812, 0x00000000, + 0x00050050, 0x00000013, 0x00004B20, 0x0000187C, 0x000035EE, 0x0006000C, 0x0000000B, 0x00002171, + 0x00000001, 0x0000003A, 0x00004B20, 0x00050051, 0x0000000D, 0x00005BBF, 0x00004BA5, 0x00000001, + 0x00050051, 0x0000000D, 0x000039A7, 0x00004812, 0x00000001, 0x00050050, 0x00000013, 0x00004B21, + 0x00005BBF, 0x000039A7, 0x0006000C, 0x0000000B, 0x00002172, 0x00000001, 0x0000003A, 0x00004B21, + 0x00050051, 0x0000000D, 0x00005BC0, 0x00004BA5, 0x00000002, 0x00050051, 0x0000000D, 0x000039A8, + 0x00004812, 0x00000002, 0x00050050, 0x00000013, 0x00004B22, 0x00005BC0, 0x000039A8, 0x0006000C, + 0x0000000B, 0x00002173, 0x00000001, 0x0000003A, 0x00004B22, 0x00050051, 0x0000000D, 0x00005BC1, + 0x00004BA5, 0x00000003, 0x00050051, 0x0000000D, 0x000039A9, 0x00004812, 0x00000003, 0x00050050, + 0x00000013, 0x00004B0D, 0x00005BC1, 0x000039A9, 0x0006000C, 0x0000000B, 0x000020EE, 0x00000001, + 0x0000003A, 0x00004B0D, 0x00070050, 0x00000017, 0x00003ABB, 0x00002171, 0x00002172, 0x00002173, + 0x000020EE, 0x00060041, 0x00000294, 0x000045C3, 0x0000140E, 0x00000A0B, 0x00002BBD, 0x0003003E, + 0x000045C3, 0x00003ABB, 0x00050080, 0x0000000B, 0x00003CAC, 0x00002BBD, 0x00000A0E, 0x000500AC, + 0x00000009, 0x00001911, 0x00001C87, 0x00000A0D, 0x000300F7, 0x000060BC, 0x00000002, 0x000400FA, + 0x00001911, 0x00005084, 0x00005094, 0x000200F8, 0x00005084, 0x00050086, 0x0000000B, 0x00003697, + 0x00001DEE, 0x00001C87, 0x00050084, 0x0000000B, 0x0000237E, 0x00003697, 0x00001C87, 0x00050082, + 0x0000000B, 0x00003171, 0x00001DEE, 0x0000237E, 0x00050080, 0x0000000B, 0x00002527, 0x00003171, + 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, 0x00002527, 0x00001C87, 0x000300F7, 0x00001EED, + 0x00000000, 0x000400FA, 0x0000343F, 0x0000569E, 0x00002191, 0x000200F8, 0x0000569E, 0x00050084, + 0x0000000B, 0x00004B59, 0x00000A6A, 0x00001C87, 0x000500C4, 0x0000000B, 0x0000540F, 0x00003171, + 0x00000A16, 0x00050082, 0x0000000B, 0x00004944, 0x00004B59, 0x0000540F, 0x000200F9, 0x00001EED, + 0x000200F8, 0x00002191, 0x000200F9, 0x00001EED, 0x000200F8, 0x00001EED, 0x000700F5, 0x0000000B, + 0x0000292C, 0x00004944, 0x0000569E, 0x00000A3A, 0x00002191, 0x000200F9, 0x000060BC, 0x000200F8, + 0x00005094, 0x000200F9, 0x000060BC, 0x000200F8, 0x000060BC, 0x000700F5, 0x0000000B, 0x000029BC, + 0x0000292C, 0x00001EED, 0x00000A6A, 0x00005094, 0x00050084, 0x0000000B, 0x0000492B, 0x000029BC, + 0x00005962, 0x000500C2, 0x0000000B, 0x0000406D, 0x0000492B, 0x00000A16, 0x00050080, 0x0000000B, + 0x0000336B, 0x00003948, 0x0000406D, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, + 0x0000336B, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x00003A1A, 0x00000000, + 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, + 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, + 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, + 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x000060BC, + 0x00003FF9, 0x00002958, 0x000300F7, 0x0000368B, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, + 0x0000368B, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, + 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, + 0x00005E18, 0x00003BE8, 0x000200F9, 0x0000368B, 0x000200F8, 0x0000368B, 0x000700F5, 0x00000017, + 0x000040DF, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, 0x000500C7, 0x00000017, 0x00004741, + 0x000040DF, 0x00000352, 0x00040070, 0x0000001D, 0x000023B2, 0x00004741, 0x0005008E, 0x0000001D, + 0x00004BA6, 0x000023B2, 0x0000092A, 0x000500C2, 0x00000017, 0x00005B48, 0x000040DF, 0x000002ED, + 0x00040070, 0x0000001D, 0x0000483D, 0x00005B48, 0x0005008E, 0x0000001D, 0x00004813, 0x0000483D, + 0x0000092A, 0x00050051, 0x0000000D, 0x0000187D, 0x00004BA6, 0x00000000, 0x00050051, 0x0000000D, + 0x000035EF, 0x00004813, 0x00000000, 0x00050050, 0x00000013, 0x00004B23, 0x0000187D, 0x000035EF, + 0x0006000C, 0x0000000B, 0x00002174, 0x00000001, 0x0000003A, 0x00004B23, 0x00050051, 0x0000000D, + 0x00005BC2, 0x00004BA6, 0x00000001, 0x00050051, 0x0000000D, 0x000039AA, 0x00004813, 0x00000001, + 0x00050050, 0x00000013, 0x00004B24, 0x00005BC2, 0x000039AA, 0x0006000C, 0x0000000B, 0x00002175, + 0x00000001, 0x0000003A, 0x00004B24, 0x00050051, 0x0000000D, 0x00005BC3, 0x00004BA6, 0x00000002, + 0x00050051, 0x0000000D, 0x000039AB, 0x00004813, 0x00000002, 0x00050050, 0x00000013, 0x00004B25, + 0x00005BC3, 0x000039AB, 0x0006000C, 0x0000000B, 0x00002176, 0x00000001, 0x0000003A, 0x00004B25, + 0x00050051, 0x0000000D, 0x00005BC4, 0x00004BA6, 0x00000003, 0x00050051, 0x0000000D, 0x000039AC, + 0x00004813, 0x00000003, 0x00050050, 0x00000013, 0x00004B0E, 0x00005BC4, 0x000039AC, 0x0006000C, + 0x0000000B, 0x000020EF, 0x00000001, 0x0000003A, 0x00004B0E, 0x00070050, 0x00000017, 0x00003ABC, + 0x00002174, 0x00002175, 0x00002176, 0x000020EF, 0x00060041, 0x00000294, 0x00004EBE, 0x0000140E, + 0x00000A0B, 0x00003CAC, 0x0003003E, 0x00004EBE, 0x00003ABC, 0x000200F9, 0x00004C7A, 0x000200F8, + 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_rgba16_snorm_float_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_rgba16_snorm_float_cs.h new file mode 100644 index 0000000..7f99b0d --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_rgba16_snorm_float_cs.h @@ -0,0 +1,628 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25059 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %float_n1 = OpConstant %float -1 + %v4int = OpTypeVector %int 4 + %int_16 = OpConstant %int 16 +%float_3_05185094en05 = OpConstant %float 3.05185094e-05 + %uint_0 = OpConstant %uint 0 + %v2float = OpTypeVector %float 2 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %uint_3 = OpConstant %uint 3 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_16 = OpConstant %uint 16 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2596 = OpConstantComposite %v3uint %uint_2 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_9 = OpConstant %uint 9 + %uint_10 = OpConstant %uint 10 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %1284 = OpConstantComposite %v4float %float_n1 %float_n1 %float_n1 %float_n1 + %770 = OpConstantComposite %v4int %int_16 %int_16 %int_16 %int_16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2596 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_8 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_9 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_9 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_9 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_10 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_3 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %6362 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %22810 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %12537 None + OpBranchConditional %15139 %11064 %12537 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %12537 + %12537 = OpLabel + %12106 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %15375 = OpBitcast %v4int %12106 + %16910 = OpShiftLeftLogical %v4int %15375 %770 + %16536 = OpShiftRightArithmetic %v4int %16910 %770 + %10903 = OpConvertSToF %v4float %16536 + %20413 = OpVectorTimesScalar %v4float %10903 %float_3_05185094en05 + %23989 = OpExtInst %v4float %1 FMax %1284 %20413 + %14338 = OpShiftRightArithmetic %v4int %15375 %770 + %6607 = OpConvertSToF %v4float %14338 + %18247 = OpVectorTimesScalar %v4float %6607 %float_3_05185094en05 + %24070 = OpExtInst %v4float %1 FMax %1284 %18247 + %24330 = OpCompositeExtract %float %23989 0 + %14319 = OpCompositeExtract %float %24070 0 + %19232 = OpCompositeConstruct %v2float %24330 %14319 + %8561 = OpExtInst %uint %1 PackHalf2x16 %19232 + %23487 = OpCompositeExtract %float %23989 1 + %14759 = OpCompositeExtract %float %24070 1 + %19233 = OpCompositeConstruct %v2float %23487 %14759 + %8562 = OpExtInst %uint %1 PackHalf2x16 %19233 + %23488 = OpCompositeExtract %float %23989 2 + %14760 = OpCompositeExtract %float %24070 2 + %19234 = OpCompositeConstruct %v2float %23488 %14760 + %8563 = OpExtInst %uint %1 PackHalf2x16 %19234 + %23489 = OpCompositeExtract %float %23989 3 + %14761 = OpCompositeExtract %float %24070 3 + %19213 = OpCompositeConstruct %v2float %23489 %14761 + %8430 = OpExtInst %uint %1 PackHalf2x16 %19213 + %15035 = OpCompositeConstruct %v4uint %8561 %8562 %8563 %8430 + %17859 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %17859 %15035 + %21686 = OpIAdd %uint %21685 %int_1 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_32 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %6871 %16377 %10584 + OpSelectionMerge %12538 None + OpBranchConditional %15139 %11065 %12538 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %12538 + %12538 = OpLabel + %12107 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %15376 = OpBitcast %v4int %12107 + %16911 = OpShiftLeftLogical %v4int %15376 %770 + %16537 = OpShiftRightArithmetic %v4int %16911 %770 + %10904 = OpConvertSToF %v4float %16537 + %20414 = OpVectorTimesScalar %v4float %10904 %float_3_05185094en05 + %23990 = OpExtInst %v4float %1 FMax %1284 %20414 + %14339 = OpShiftRightArithmetic %v4int %15376 %770 + %6608 = OpConvertSToF %v4float %14339 + %18248 = OpVectorTimesScalar %v4float %6608 %float_3_05185094en05 + %24071 = OpExtInst %v4float %1 FMax %1284 %18248 + %24331 = OpCompositeExtract %float %23990 0 + %14320 = OpCompositeExtract %float %24071 0 + %19235 = OpCompositeConstruct %v2float %24331 %14320 + %8564 = OpExtInst %uint %1 PackHalf2x16 %19235 + %23490 = OpCompositeExtract %float %23990 1 + %14762 = OpCompositeExtract %float %24071 1 + %19236 = OpCompositeConstruct %v2float %23490 %14762 + %8565 = OpExtInst %uint %1 PackHalf2x16 %19236 + %23491 = OpCompositeExtract %float %23990 2 + %14763 = OpCompositeExtract %float %24071 2 + %19237 = OpCompositeConstruct %v2float %23491 %14763 + %8566 = OpExtInst %uint %1 PackHalf2x16 %19237 + %23492 = OpCompositeExtract %float %23990 3 + %14764 = OpCompositeExtract %float %24071 3 + %19214 = OpCompositeConstruct %v2float %23492 %14764 + %8431 = OpExtInst %uint %1 PackHalf2x16 %19214 + %15036 = OpCompositeConstruct %v4uint %8564 %8565 %8566 %8431 + %20158 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21686 + OpStore %20158 %15036 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_rgba16_snorm_float_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000061E3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, + 0x00000004, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, 0x0000000B, + 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, + 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, + 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x0004002B, + 0x0000000D, 0x00000341, 0xBF800000, 0x00040017, 0x0000001A, 0x0000000C, 0x00000004, 0x0004002B, + 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000D, 0x00000A38, 0x38000100, 0x0004002B, + 0x0000000B, 0x00000A0A, 0x00000000, 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, + 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, + 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, + 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, + 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, + 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, + 0x0000000C, 0x00000A39, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, + 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, + 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, + 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, + 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, + 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, + 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, + 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, + 0x0000000B, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, + 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A24, + 0x00000A10, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0003001D, + 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, + 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, + 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, + 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, + 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0004002B, 0x0000000B, 0x00000A25, + 0x00000009, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0007002C, 0x00000017, 0x000009CE, + 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, + 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, + 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, + 0x00000A3A, 0x0007002C, 0x0000001D, 0x00000504, 0x00000341, 0x00000341, 0x00000341, 0x00000341, + 0x0007002C, 0x0000001A, 0x00000302, 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x00050036, + 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, + 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, + 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, + 0x0000000B, 0x00005FDC, 0x00003526, 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, + 0x00000A0A, 0x000500C7, 0x0000000B, 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, + 0x00004384, 0x00003028, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, + 0x000500C7, 0x0000000B, 0x000061E2, 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, + 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, + 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, + 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, + 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, + 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, + 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, + 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, + 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A24, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, + 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, + 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, + 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, + 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, + 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, + 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, + 0x0000591A, 0x00005BEB, 0x00000A23, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, + 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, + 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, + 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, + 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, + 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00002764, + 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x000054B5, 0x00002764, 0x00000A16, 0x000300F7, + 0x00005F43, 0x00000002, 0x000400FA, 0x00004376, 0x00005768, 0x000051F2, 0x000200F8, 0x00005768, + 0x000300F7, 0x00001E0B, 0x00000002, 0x000400FA, 0x00004384, 0x00002BF8, 0x000018D9, 0x000200F8, + 0x00002BF8, 0x000500C3, 0x0000000C, 0x000032B3, 0x000044BE, 0x00000A17, 0x000500C3, 0x0000000C, + 0x0000601E, 0x000018DA, 0x00000A11, 0x000500C2, 0x0000000B, 0x00004947, 0x00005789, 0x00000A16, + 0x0004007C, 0x0000000C, 0x000018AA, 0x00004947, 0x00050084, 0x0000000C, 0x00005321, 0x0000601E, + 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000032B3, 0x00005321, 0x000500C2, 0x0000000B, + 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x00003901, 0x00002348, 0x00050084, + 0x0000000C, 0x000020F4, 0x00003B27, 0x00003901, 0x000500C3, 0x0000000C, 0x000032BA, 0x00005BEB, + 0x00000A1A, 0x00050080, 0x0000000C, 0x00005FEE, 0x000032BA, 0x000020F4, 0x000500C4, 0x0000000C, + 0x0000225D, 0x00005FEE, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, + 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, + 0x00005BEB, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000044BE, 0x00000A1D, 0x000500C4, + 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, + 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A25, 0x000500C3, 0x0000000C, + 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000044BE, 0x00000A14, + 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000601E, 0x000500C7, 0x0000000C, 0x00005A0C, + 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00005BEB, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, + 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, + 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, + 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, + 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A39, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, + 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x000018DA, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544B, 0x000047B4, 0x00000A25, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, + 0x000500C7, 0x0000000C, 0x00004ADE, 0x000044BE, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, + 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, + 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, + 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, + 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, + 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, + 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, + 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, + 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, + 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, + 0x00050080, 0x0000000C, 0x000054ED, 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, + 0x000018D9, 0x0004007C, 0x00000012, 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, + 0x000019AD, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, + 0x0000000C, 0x00002747, 0x000019AD, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, + 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, + 0x000018AB, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005347, 0x0000405C, 0x000018AB, 0x00050080, + 0x0000000C, 0x00003F5E, 0x000024FD, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, + 0x00000A28, 0x000500C7, 0x0000000C, 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003139, 0x00002747, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, + 0x00004397, 0x00000A13, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, + 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, + 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A39, 0x00050080, 0x0000000C, + 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002747, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, + 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, + 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, + 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, + 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, + 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, + 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, + 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, + 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, + 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, + 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, + 0x00001E0B, 0x000200F8, 0x00001E0B, 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, 0x00002BF8, + 0x00002F42, 0x000018D9, 0x000200F9, 0x00005F43, 0x000200F8, 0x000051F2, 0x0004007C, 0x0000000C, + 0x00003CBC, 0x00005789, 0x00050084, 0x0000000C, 0x000060B8, 0x000018DA, 0x00003CBC, 0x00050080, + 0x0000000C, 0x0000208E, 0x000060B8, 0x000044BE, 0x0004007C, 0x0000000C, 0x000022F8, 0x00005788, + 0x00050084, 0x0000000C, 0x00001E9F, 0x0000208E, 0x000022F8, 0x00050080, 0x0000000C, 0x00001F30, + 0x0000591A, 0x00001E9F, 0x000200F9, 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, + 0x00002A3E, 0x0000292C, 0x00001E0B, 0x00001F30, 0x000051F2, 0x0004007C, 0x0000000C, 0x00001A3F, + 0x00005EAC, 0x00050080, 0x0000000C, 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, + 0x00003EE9, 0x000056CD, 0x000500C2, 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, + 0x00000294, 0x00004315, 0x0000107A, 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00001CAA, + 0x00004315, 0x000500AA, 0x00000009, 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, 0x00000009, + 0x00005376, 0x000061E2, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, 0x00005376, + 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, + 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, + 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, + 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, + 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, + 0x00005879, 0x00001CAA, 0x00005F43, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, + 0x000061E2, 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, + 0x000030F9, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x000030F9, 0x000200F8, 0x00002B38, + 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, + 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, + 0x000030F9, 0x000200F8, 0x000030F9, 0x000700F5, 0x00000017, 0x00002F4A, 0x00005879, 0x00003463, + 0x000029E8, 0x00002B38, 0x0004007C, 0x0000001A, 0x00003C0F, 0x00002F4A, 0x000500C4, 0x0000001A, + 0x0000420E, 0x00003C0F, 0x00000302, 0x000500C3, 0x0000001A, 0x00004098, 0x0000420E, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002A97, 0x00004098, 0x0005008E, 0x0000001D, 0x00004FBD, 0x00002A97, + 0x00000A38, 0x0007000C, 0x0000001D, 0x00005DB5, 0x00000001, 0x00000028, 0x00000504, 0x00004FBD, + 0x000500C3, 0x0000001A, 0x00003802, 0x00003C0F, 0x00000302, 0x0004006F, 0x0000001D, 0x000019CF, + 0x00003802, 0x0005008E, 0x0000001D, 0x00004747, 0x000019CF, 0x00000A38, 0x0007000C, 0x0000001D, + 0x00005E06, 0x00000001, 0x00000028, 0x00000504, 0x00004747, 0x00050051, 0x0000000D, 0x00005F0A, + 0x00005DB5, 0x00000000, 0x00050051, 0x0000000D, 0x000037EF, 0x00005E06, 0x00000000, 0x00050050, + 0x00000013, 0x00004B20, 0x00005F0A, 0x000037EF, 0x0006000C, 0x0000000B, 0x00002171, 0x00000001, + 0x0000003A, 0x00004B20, 0x00050051, 0x0000000D, 0x00005BBF, 0x00005DB5, 0x00000001, 0x00050051, + 0x0000000D, 0x000039A7, 0x00005E06, 0x00000001, 0x00050050, 0x00000013, 0x00004B21, 0x00005BBF, + 0x000039A7, 0x0006000C, 0x0000000B, 0x00002172, 0x00000001, 0x0000003A, 0x00004B21, 0x00050051, + 0x0000000D, 0x00005BC0, 0x00005DB5, 0x00000002, 0x00050051, 0x0000000D, 0x000039A8, 0x00005E06, + 0x00000002, 0x00050050, 0x00000013, 0x00004B22, 0x00005BC0, 0x000039A8, 0x0006000C, 0x0000000B, + 0x00002173, 0x00000001, 0x0000003A, 0x00004B22, 0x00050051, 0x0000000D, 0x00005BC1, 0x00005DB5, + 0x00000003, 0x00050051, 0x0000000D, 0x000039A9, 0x00005E06, 0x00000003, 0x00050050, 0x00000013, + 0x00004B0D, 0x00005BC1, 0x000039A9, 0x0006000C, 0x0000000B, 0x000020EE, 0x00000001, 0x0000003A, + 0x00004B0D, 0x00070050, 0x00000017, 0x00003ABB, 0x00002171, 0x00002172, 0x00002173, 0x000020EE, + 0x00060041, 0x00000294, 0x000045C3, 0x0000140E, 0x00000A0B, 0x000054B5, 0x0003003E, 0x000045C3, + 0x00003ABB, 0x00050080, 0x0000000B, 0x000054B6, 0x000054B5, 0x00000A0E, 0x000300F7, 0x00001AD7, + 0x00000002, 0x000400FA, 0x00004376, 0x000055E9, 0x00001C25, 0x000200F8, 0x000055E9, 0x000200F9, + 0x00001AD7, 0x000200F8, 0x00001C25, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001AD7, 0x000700F5, + 0x0000000B, 0x0000456F, 0x00000A6A, 0x000055E9, 0x00000A3A, 0x00001C25, 0x000500C2, 0x0000000B, + 0x000041C0, 0x0000456F, 0x00000A16, 0x00050080, 0x0000000B, 0x00002ADB, 0x00005665, 0x000041C0, + 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, 0x00002ADB, 0x0004003D, 0x00000017, + 0x000019B2, 0x0000571A, 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, + 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, + 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, + 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, + 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, + 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x00001AD7, 0x00003FF9, 0x00002958, 0x000300F7, + 0x000030FA, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, 0x000030FA, 0x000200F8, 0x00002B39, + 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, + 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, + 0x000030FA, 0x000200F8, 0x000030FA, 0x000700F5, 0x00000017, 0x00002F4B, 0x00002AAC, 0x00003A1A, + 0x000029E9, 0x00002B39, 0x0004007C, 0x0000001A, 0x00003C10, 0x00002F4B, 0x000500C4, 0x0000001A, + 0x0000420F, 0x00003C10, 0x00000302, 0x000500C3, 0x0000001A, 0x00004099, 0x0000420F, 0x00000302, + 0x0004006F, 0x0000001D, 0x00002A98, 0x00004099, 0x0005008E, 0x0000001D, 0x00004FBE, 0x00002A98, + 0x00000A38, 0x0007000C, 0x0000001D, 0x00005DB6, 0x00000001, 0x00000028, 0x00000504, 0x00004FBE, + 0x000500C3, 0x0000001A, 0x00003803, 0x00003C10, 0x00000302, 0x0004006F, 0x0000001D, 0x000019D0, + 0x00003803, 0x0005008E, 0x0000001D, 0x00004748, 0x000019D0, 0x00000A38, 0x0007000C, 0x0000001D, + 0x00005E07, 0x00000001, 0x00000028, 0x00000504, 0x00004748, 0x00050051, 0x0000000D, 0x00005F0B, + 0x00005DB6, 0x00000000, 0x00050051, 0x0000000D, 0x000037F0, 0x00005E07, 0x00000000, 0x00050050, + 0x00000013, 0x00004B23, 0x00005F0B, 0x000037F0, 0x0006000C, 0x0000000B, 0x00002174, 0x00000001, + 0x0000003A, 0x00004B23, 0x00050051, 0x0000000D, 0x00005BC2, 0x00005DB6, 0x00000001, 0x00050051, + 0x0000000D, 0x000039AA, 0x00005E07, 0x00000001, 0x00050050, 0x00000013, 0x00004B24, 0x00005BC2, + 0x000039AA, 0x0006000C, 0x0000000B, 0x00002175, 0x00000001, 0x0000003A, 0x00004B24, 0x00050051, + 0x0000000D, 0x00005BC3, 0x00005DB6, 0x00000002, 0x00050051, 0x0000000D, 0x000039AB, 0x00005E07, + 0x00000002, 0x00050050, 0x00000013, 0x00004B25, 0x00005BC3, 0x000039AB, 0x0006000C, 0x0000000B, + 0x00002176, 0x00000001, 0x0000003A, 0x00004B25, 0x00050051, 0x0000000D, 0x00005BC4, 0x00005DB6, + 0x00000003, 0x00050051, 0x0000000D, 0x000039AC, 0x00005E07, 0x00000003, 0x00050050, 0x00000013, + 0x00004B0E, 0x00005BC4, 0x000039AC, 0x0006000C, 0x0000000B, 0x000020EF, 0x00000001, 0x0000003A, + 0x00004B0E, 0x00070050, 0x00000017, 0x00003ABC, 0x00002174, 0x00002175, 0x00002176, 0x000020EF, + 0x00060041, 0x00000294, 0x00004EBE, 0x0000140E, 0x00000A0B, 0x000054B6, 0x0003003E, 0x00004EBE, + 0x00003ABC, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_rgba16_snorm_float_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_rgba16_snorm_float_scaled_cs.h new file mode 100644 index 0000000..bf4513d --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_rgba16_snorm_float_scaled_cs.h @@ -0,0 +1,690 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %float_n1 = OpConstant %float -1 + %v4int = OpTypeVector %int 4 + %int_16 = OpConstant %int 16 +%float_3_05185094en05 = OpConstant %float 3.05185094e-05 + %uint_0 = OpConstant %uint 0 + %v2float = OpTypeVector %float 2 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %uint_3 = OpConstant %uint 3 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %uint_16 = OpConstant %uint 16 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2596 = OpConstantComposite %v3uint %uint_2 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %uint_9 = OpConstant %uint 9 + %uint_10 = OpConstant %uint 10 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %1284 = OpConstantComposite %v4float %float_n1 %float_n1 %float_n1 %float_n1 + %770 = OpConstantComposite %v4int %int_16 %int_16 %int_16 %int_16 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2596 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_8 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_1 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_1 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_9 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_9 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_9 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_10 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_3 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_1 + %23219 = OpBitwiseAnd %uint %10722 %uint_1 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_3 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %7338 = OpLoad %v4uint %20399 + %13760 = OpIEqual %bool %24990 %uint_1 + %21366 = OpIEqual %bool %24990 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %21313 %16376 %10583 + %19638 = OpIEqual %bool %24990 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %12537 None + OpBranchConditional %15139 %11064 %12537 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %12537 + %12537 = OpLabel + %12106 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %15375 = OpBitcast %v4int %12106 + %16910 = OpShiftLeftLogical %v4int %15375 %770 + %16536 = OpShiftRightArithmetic %v4int %16910 %770 + %10903 = OpConvertSToF %v4float %16536 + %20413 = OpVectorTimesScalar %v4float %10903 %float_3_05185094en05 + %23989 = OpExtInst %v4float %1 FMax %1284 %20413 + %14338 = OpShiftRightArithmetic %v4int %15375 %770 + %6607 = OpConvertSToF %v4float %14338 + %18247 = OpVectorTimesScalar %v4float %6607 %float_3_05185094en05 + %24070 = OpExtInst %v4float %1 FMax %1284 %18247 + %24330 = OpCompositeExtract %float %23989 0 + %14319 = OpCompositeExtract %float %24070 0 + %19232 = OpCompositeConstruct %v2float %24330 %14319 + %8561 = OpExtInst %uint %1 PackHalf2x16 %19232 + %23487 = OpCompositeExtract %float %23989 1 + %14759 = OpCompositeExtract %float %24070 1 + %19233 = OpCompositeConstruct %v2float %23487 %14759 + %8562 = OpExtInst %uint %1 PackHalf2x16 %19233 + %23488 = OpCompositeExtract %float %23989 2 + %14760 = OpCompositeExtract %float %24070 2 + %19234 = OpCompositeConstruct %v2float %23488 %14760 + %8563 = OpExtInst %uint %1 PackHalf2x16 %19234 + %23489 = OpCompositeExtract %float %23989 3 + %14761 = OpCompositeExtract %float %24070 3 + %19213 = OpCompositeConstruct %v2float %23489 %14761 + %8430 = OpExtInst %uint %1 PackHalf2x16 %19213 + %15035 = OpCompositeConstruct %v4uint %8561 %8562 %8563 %8430 + %17859 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %17859 %15035 + %15532 = OpIAdd %uint %11197 %int_1 + %6417 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %6417 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_32 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_32 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %24764 %16377 %10584 + OpSelectionMerge %12538 None + OpBranchConditional %15139 %11065 %12538 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %12538 + %12538 = OpLabel + %12107 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %15376 = OpBitcast %v4int %12107 + %16911 = OpShiftLeftLogical %v4int %15376 %770 + %16537 = OpShiftRightArithmetic %v4int %16911 %770 + %10904 = OpConvertSToF %v4float %16537 + %20414 = OpVectorTimesScalar %v4float %10904 %float_3_05185094en05 + %23990 = OpExtInst %v4float %1 FMax %1284 %20414 + %14339 = OpShiftRightArithmetic %v4int %15376 %770 + %6608 = OpConvertSToF %v4float %14339 + %18248 = OpVectorTimesScalar %v4float %6608 %float_3_05185094en05 + %24071 = OpExtInst %v4float %1 FMax %1284 %18248 + %24331 = OpCompositeExtract %float %23990 0 + %14320 = OpCompositeExtract %float %24071 0 + %19235 = OpCompositeConstruct %v2float %24331 %14320 + %8564 = OpExtInst %uint %1 PackHalf2x16 %19235 + %23490 = OpCompositeExtract %float %23990 1 + %14762 = OpCompositeExtract %float %24071 1 + %19236 = OpCompositeConstruct %v2float %23490 %14762 + %8565 = OpExtInst %uint %1 PackHalf2x16 %19236 + %23491 = OpCompositeExtract %float %23990 2 + %14763 = OpCompositeExtract %float %24071 2 + %19237 = OpCompositeConstruct %v2float %23491 %14763 + %8566 = OpExtInst %uint %1 PackHalf2x16 %19237 + %23492 = OpCompositeExtract %float %23990 3 + %14764 = OpCompositeExtract %float %24071 3 + %19214 = OpCompositeConstruct %v2float %23492 %14764 + %8431 = OpExtInst %uint %1 PackHalf2x16 %19214 + %15036 = OpCompositeConstruct %v4uint %8564 %8565 %8566 %8431 + %20158 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15532 + OpStore %20158 %15036 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_rgba16_snorm_float_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, + 0x00000004, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, + 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, + 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, 0x0004002B, + 0x0000000D, 0x00000341, 0xBF800000, 0x00040017, 0x0000001A, 0x0000000C, 0x00000004, 0x0004002B, + 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000D, 0x00000A38, 0x38000100, 0x0004002B, + 0x0000000B, 0x00000A0A, 0x00000000, 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, + 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, + 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, + 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, + 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, + 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, + 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A39, 0x0000000F, 0x0004002B, + 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, + 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, + 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, + 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, + 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, + 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, + 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, + 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x0005002C, 0x00000011, 0x00000787, + 0x00000A16, 0x00000A1F, 0x00040020, 0x00000291, 0x00000009, 0x00000014, 0x00040020, 0x00000292, + 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, + 0x00000A24, 0x00000A10, 0x00000A0A, 0x00000A0A, 0x00040017, 0x0000000F, 0x00000009, 0x00000002, + 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, + 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, 0x00000002, 0x00040020, 0x00000294, + 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, + 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, + 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, 0x00000A0D, 0x0005002C, 0x00000011, + 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0004002B, + 0x0000000B, 0x00000A28, 0x0000000A, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, + 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, + 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, + 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0007002C, + 0x0000001D, 0x00000504, 0x00000341, 0x00000341, 0x00000341, 0x00000341, 0x0007002C, 0x0000001A, + 0x00000302, 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x00000A3B, 0x00050036, 0x00000008, 0x0000161F, + 0x00000000, 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, + 0x00000A0A, 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, + 0x00000A0B, 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005F7D, + 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x000048EB, 0x00005F7D, 0x00000A0A, 0x000500C2, + 0x0000000B, 0x00001FCD, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x0000619E, 0x00001FCD, + 0x00000A13, 0x00050050, 0x00000011, 0x000022A7, 0x00003526, 0x00003526, 0x000500C2, 0x00000011, + 0x00001BAF, 0x000022A7, 0x00000787, 0x000500C7, 0x00000011, 0x00001997, 0x00001BAF, 0x000007A2, + 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, + 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, + 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, + 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, + 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, + 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, + 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, + 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A24, 0x0007004F, + 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, + 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, + 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, + 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, + 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, + 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, + 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A23, 0x00050051, 0x0000000C, + 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, + 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, + 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, + 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, + 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, + 0x00050080, 0x0000000B, 0x00001B12, 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x00002BBD, + 0x00001B12, 0x00000A16, 0x00050051, 0x0000000B, 0x000029E2, 0x0000538B, 0x00000000, 0x000500C2, + 0x0000000B, 0x00001DEE, 0x000029E2, 0x00000A0D, 0x00050051, 0x0000000B, 0x00002704, 0x0000538B, + 0x00000001, 0x00050050, 0x00000011, 0x00005C0B, 0x00001DEE, 0x00002704, 0x00050086, 0x00000011, + 0x00001F69, 0x00005C0B, 0x00001997, 0x00050051, 0x0000000B, 0x0000366C, 0x00001F69, 0x00000000, + 0x000500C4, 0x0000000B, 0x00004D4D, 0x0000366C, 0x00000A0D, 0x00050051, 0x0000000B, 0x000051A9, + 0x00001F69, 0x00000001, 0x00050051, 0x0000000B, 0x000059EE, 0x0000538B, 0x00000002, 0x00060050, + 0x00000014, 0x000024C9, 0x00004D4D, 0x000051A9, 0x000059EE, 0x000300F7, 0x00005341, 0x00000002, + 0x000400FA, 0x000048EB, 0x0000537D, 0x00002DD9, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, + 0x00002970, 0x000024C9, 0x00050051, 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, + 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, + 0x00000002, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, + 0x00005B4D, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, + 0x0000000C, 0x00005321, 0x0000405C, 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, + 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, + 0x0000308B, 0x00002348, 0x00050084, 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, + 0x0000000C, 0x00006242, 0x00002970, 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, + 0x00000A1A, 0x00050080, 0x0000000C, 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, + 0x0000225D, 0x000049FC, 0x00000A25, 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, + 0x000500C4, 0x0000000C, 0x000049FA, 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, + 0x00006242, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, + 0x0000000C, 0x0000454D, 0x00003138, 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, + 0x0000454D, 0x000500C4, 0x0000000C, 0x00001B88, 0x0000434B, 0x00000A25, 0x000500C3, 0x0000000C, + 0x00005DE3, 0x00001B88, 0x00000A1D, 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, + 0x00050080, 0x0000000C, 0x000035A3, 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, + 0x000035A3, 0x00000A0E, 0x000500C3, 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, + 0x0000000C, 0x0000496A, 0x00005A0C, 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, + 0x0000496A, 0x000500C7, 0x0000000C, 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544A, 0x00004ADD, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, + 0x000500C7, 0x0000000C, 0x0000335E, 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, + 0x000049FA, 0x0000335E, 0x000500C4, 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, + 0x0000000C, 0x00005AEA, 0x00005DE3, 0x00000A39, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, + 0x00005AEA, 0x000500C7, 0x0000000C, 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544B, 0x000047B4, 0x00000A25, 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, + 0x000500C7, 0x0000000C, 0x00004ADE, 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, + 0x00004ADE, 0x00000A17, 0x00050080, 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, + 0x0000000C, 0x00004FD6, 0x00003C4B, 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, + 0x00000A14, 0x000500C3, 0x0000000C, 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, + 0x000036D6, 0x00003332, 0x00000A20, 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, + 0x000500C4, 0x0000000C, 0x00005B32, 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, + 0x00003C4B, 0x00000A05, 0x00050080, 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, + 0x0000000C, 0x00005B33, 0x00002A9C, 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, + 0x0000040B, 0x00050080, 0x0000000C, 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, + 0x00005B34, 0x00002A9D, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005559, 0x00004158, 0x00000AC8, + 0x00050080, 0x0000000C, 0x00005EFA, 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, 0x0000566F, + 0x00005EFA, 0x000200F9, 0x00005341, 0x000200F8, 0x00002DD9, 0x0007004F, 0x00000011, 0x00002621, + 0x000024C9, 0x000024C9, 0x00000000, 0x00000001, 0x0004007C, 0x00000012, 0x000059CF, 0x00002621, + 0x00050051, 0x0000000C, 0x00001903, 0x000059CF, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FE, + 0x00001903, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002748, 0x000059CF, 0x00000001, 0x000500C3, + 0x0000000C, 0x0000405D, 0x00002748, 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00005788, + 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005347, + 0x0000405D, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FE, 0x00005347, 0x000500C4, + 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A28, 0x000500C7, 0x0000000C, 0x00002AB6, 0x00001903, + 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002748, 0x00000A35, 0x000500C4, 0x0000000C, + 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, + 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A13, 0x000500C7, 0x0000000C, 0x000027B1, + 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, + 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, + 0x00000A39, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, + 0x000047B5, 0x00002748, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, + 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, + 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, + 0x0000000C, 0x00004A33, 0x00002748, 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, + 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, + 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, + 0x00002748, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, + 0x0000000C, 0x00001EEC, 0x00001903, 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, + 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, + 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, + 0x000500C7, 0x0000000C, 0x00002E06, 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, + 0x00003C4D, 0x00002E06, 0x0004007C, 0x0000000B, 0x00005670, 0x0000394F, 0x000200F9, 0x00005341, + 0x000200F8, 0x00005341, 0x000700F5, 0x0000000B, 0x000024FC, 0x0000566F, 0x0000537D, 0x00005670, + 0x00002DD9, 0x00050084, 0x00000011, 0x00003FA8, 0x00001F69, 0x00001997, 0x00050082, 0x00000011, + 0x00003BBC, 0x00005C0B, 0x00003FA8, 0x00050051, 0x0000000B, 0x00001C87, 0x00001997, 0x00000000, + 0x00050051, 0x0000000B, 0x00005962, 0x00001997, 0x00000001, 0x00050084, 0x0000000B, 0x00003372, + 0x00001C87, 0x00005962, 0x00050084, 0x0000000B, 0x00003CA0, 0x000024FC, 0x00003372, 0x00050051, + 0x0000000B, 0x00003ED4, 0x00003BBC, 0x00000000, 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, + 0x00005962, 0x00050051, 0x0000000B, 0x00001AE6, 0x00003BBC, 0x00000001, 0x00050080, 0x0000000B, + 0x00002B25, 0x00003E12, 0x00001AE6, 0x000500C4, 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A0D, + 0x000500C7, 0x0000000B, 0x00005AB3, 0x000029E2, 0x00000A0D, 0x00050080, 0x0000000B, 0x00002557, + 0x0000609D, 0x00005AB3, 0x000500C4, 0x0000000B, 0x000040AD, 0x00002557, 0x00000A13, 0x00050080, + 0x0000000B, 0x00004EAA, 0x00003CA0, 0x000040AD, 0x00050080, 0x0000000B, 0x00003BA9, 0x00005EAC, + 0x00004EAA, 0x000500C2, 0x0000000B, 0x00003948, 0x00003BA9, 0x00000A16, 0x00060041, 0x00000294, + 0x00004FAF, 0x0000107A, 0x00000A0B, 0x00003948, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004FAF, + 0x000500AA, 0x00000009, 0x000035C0, 0x0000619E, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, + 0x0000619E, 0x00000A10, 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, + 0x00003463, 0x00000000, 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, + 0x000500C7, 0x00000017, 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, + 0x0000475F, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, + 0x00000017, 0x0000448D, 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, + 0x0000448D, 0x000200F9, 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, + 0x00001CAA, 0x00005341, 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x0000619E, + 0x00000A13, 0x000500A6, 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x000030F9, + 0x00000000, 0x000400FA, 0x00003B23, 0x00002B38, 0x000030F9, 0x000200F8, 0x00002B38, 0x000500C4, + 0x00000017, 0x00005E17, 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, + 0x000002ED, 0x000500C5, 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x000030F9, + 0x000200F8, 0x000030F9, 0x000700F5, 0x00000017, 0x00002F4A, 0x00005879, 0x00003463, 0x000029E8, + 0x00002B38, 0x0004007C, 0x0000001A, 0x00003C0F, 0x00002F4A, 0x000500C4, 0x0000001A, 0x0000420E, + 0x00003C0F, 0x00000302, 0x000500C3, 0x0000001A, 0x00004098, 0x0000420E, 0x00000302, 0x0004006F, + 0x0000001D, 0x00002A97, 0x00004098, 0x0005008E, 0x0000001D, 0x00004FBD, 0x00002A97, 0x00000A38, + 0x0007000C, 0x0000001D, 0x00005DB5, 0x00000001, 0x00000028, 0x00000504, 0x00004FBD, 0x000500C3, + 0x0000001A, 0x00003802, 0x00003C0F, 0x00000302, 0x0004006F, 0x0000001D, 0x000019CF, 0x00003802, + 0x0005008E, 0x0000001D, 0x00004747, 0x000019CF, 0x00000A38, 0x0007000C, 0x0000001D, 0x00005E06, + 0x00000001, 0x00000028, 0x00000504, 0x00004747, 0x00050051, 0x0000000D, 0x00005F0A, 0x00005DB5, + 0x00000000, 0x00050051, 0x0000000D, 0x000037EF, 0x00005E06, 0x00000000, 0x00050050, 0x00000013, + 0x00004B20, 0x00005F0A, 0x000037EF, 0x0006000C, 0x0000000B, 0x00002171, 0x00000001, 0x0000003A, + 0x00004B20, 0x00050051, 0x0000000D, 0x00005BBF, 0x00005DB5, 0x00000001, 0x00050051, 0x0000000D, + 0x000039A7, 0x00005E06, 0x00000001, 0x00050050, 0x00000013, 0x00004B21, 0x00005BBF, 0x000039A7, + 0x0006000C, 0x0000000B, 0x00002172, 0x00000001, 0x0000003A, 0x00004B21, 0x00050051, 0x0000000D, + 0x00005BC0, 0x00005DB5, 0x00000002, 0x00050051, 0x0000000D, 0x000039A8, 0x00005E06, 0x00000002, + 0x00050050, 0x00000013, 0x00004B22, 0x00005BC0, 0x000039A8, 0x0006000C, 0x0000000B, 0x00002173, + 0x00000001, 0x0000003A, 0x00004B22, 0x00050051, 0x0000000D, 0x00005BC1, 0x00005DB5, 0x00000003, + 0x00050051, 0x0000000D, 0x000039A9, 0x00005E06, 0x00000003, 0x00050050, 0x00000013, 0x00004B0D, + 0x00005BC1, 0x000039A9, 0x0006000C, 0x0000000B, 0x000020EE, 0x00000001, 0x0000003A, 0x00004B0D, + 0x00070050, 0x00000017, 0x00003ABB, 0x00002171, 0x00002172, 0x00002173, 0x000020EE, 0x00060041, + 0x00000294, 0x000045C3, 0x0000140E, 0x00000A0B, 0x00002BBD, 0x0003003E, 0x000045C3, 0x00003ABB, + 0x00050080, 0x0000000B, 0x00003CAC, 0x00002BBD, 0x00000A0E, 0x000500AC, 0x00000009, 0x00001911, + 0x00001C87, 0x00000A0D, 0x000300F7, 0x000060BC, 0x00000002, 0x000400FA, 0x00001911, 0x00005084, + 0x00005094, 0x000200F8, 0x00005084, 0x00050086, 0x0000000B, 0x00003697, 0x00001DEE, 0x00001C87, + 0x00050084, 0x0000000B, 0x0000237E, 0x00003697, 0x00001C87, 0x00050082, 0x0000000B, 0x00003171, + 0x00001DEE, 0x0000237E, 0x00050080, 0x0000000B, 0x00002527, 0x00003171, 0x00000A0D, 0x000500AA, + 0x00000009, 0x0000343F, 0x00002527, 0x00001C87, 0x000300F7, 0x00001EED, 0x00000000, 0x000400FA, + 0x0000343F, 0x0000569E, 0x00002191, 0x000200F8, 0x0000569E, 0x00050084, 0x0000000B, 0x00004B59, + 0x00000A6A, 0x00001C87, 0x000500C4, 0x0000000B, 0x0000540F, 0x00003171, 0x00000A16, 0x00050082, + 0x0000000B, 0x00004944, 0x00004B59, 0x0000540F, 0x000200F9, 0x00001EED, 0x000200F8, 0x00002191, + 0x000200F9, 0x00001EED, 0x000200F8, 0x00001EED, 0x000700F5, 0x0000000B, 0x0000292C, 0x00004944, + 0x0000569E, 0x00000A3A, 0x00002191, 0x000200F9, 0x000060BC, 0x000200F8, 0x00005094, 0x000200F9, + 0x000060BC, 0x000200F8, 0x000060BC, 0x000700F5, 0x0000000B, 0x000029BC, 0x0000292C, 0x00001EED, + 0x00000A6A, 0x00005094, 0x00050084, 0x0000000B, 0x0000492B, 0x000029BC, 0x00005962, 0x000500C2, + 0x0000000B, 0x0000406D, 0x0000492B, 0x00000A16, 0x00050080, 0x0000000B, 0x0000336B, 0x00003948, + 0x0000406D, 0x00060041, 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, 0x0000336B, 0x0004003D, + 0x00000017, 0x000019B2, 0x0000571A, 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, + 0x00002958, 0x00003A1A, 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, + 0x000009CE, 0x000500C4, 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, + 0x000050AD, 0x000019B2, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, + 0x000500C5, 0x00000017, 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, + 0x00003A1A, 0x000700F5, 0x00000017, 0x00002AAC, 0x000019B2, 0x000060BC, 0x00003FF9, 0x00002958, + 0x000300F7, 0x000030FA, 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, 0x000030FA, 0x000200F8, + 0x00002B39, 0x000500C4, 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, 0x000500C2, 0x00000017, + 0x00003BE8, 0x00002AAC, 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, + 0x000200F9, 0x000030FA, 0x000200F8, 0x000030FA, 0x000700F5, 0x00000017, 0x00002F4B, 0x00002AAC, + 0x00003A1A, 0x000029E9, 0x00002B39, 0x0004007C, 0x0000001A, 0x00003C10, 0x00002F4B, 0x000500C4, + 0x0000001A, 0x0000420F, 0x00003C10, 0x00000302, 0x000500C3, 0x0000001A, 0x00004099, 0x0000420F, + 0x00000302, 0x0004006F, 0x0000001D, 0x00002A98, 0x00004099, 0x0005008E, 0x0000001D, 0x00004FBE, + 0x00002A98, 0x00000A38, 0x0007000C, 0x0000001D, 0x00005DB6, 0x00000001, 0x00000028, 0x00000504, + 0x00004FBE, 0x000500C3, 0x0000001A, 0x00003803, 0x00003C10, 0x00000302, 0x0004006F, 0x0000001D, + 0x000019D0, 0x00003803, 0x0005008E, 0x0000001D, 0x00004748, 0x000019D0, 0x00000A38, 0x0007000C, + 0x0000001D, 0x00005E07, 0x00000001, 0x00000028, 0x00000504, 0x00004748, 0x00050051, 0x0000000D, + 0x00005F0B, 0x00005DB6, 0x00000000, 0x00050051, 0x0000000D, 0x000037F0, 0x00005E07, 0x00000000, + 0x00050050, 0x00000013, 0x00004B23, 0x00005F0B, 0x000037F0, 0x0006000C, 0x0000000B, 0x00002174, + 0x00000001, 0x0000003A, 0x00004B23, 0x00050051, 0x0000000D, 0x00005BC2, 0x00005DB6, 0x00000001, + 0x00050051, 0x0000000D, 0x000039AA, 0x00005E07, 0x00000001, 0x00050050, 0x00000013, 0x00004B24, + 0x00005BC2, 0x000039AA, 0x0006000C, 0x0000000B, 0x00002175, 0x00000001, 0x0000003A, 0x00004B24, + 0x00050051, 0x0000000D, 0x00005BC3, 0x00005DB6, 0x00000002, 0x00050051, 0x0000000D, 0x000039AB, + 0x00005E07, 0x00000002, 0x00050050, 0x00000013, 0x00004B25, 0x00005BC3, 0x000039AB, 0x0006000C, + 0x0000000B, 0x00002176, 0x00000001, 0x0000003A, 0x00004B25, 0x00050051, 0x0000000D, 0x00005BC4, + 0x00005DB6, 0x00000003, 0x00050051, 0x0000000D, 0x000039AC, 0x00005E07, 0x00000003, 0x00050050, + 0x00000013, 0x00004B0E, 0x00005BC4, 0x000039AC, 0x0006000C, 0x0000000B, 0x000020EF, 0x00000001, + 0x0000003A, 0x00004B0E, 0x00070050, 0x00000017, 0x00003ABC, 0x00002174, 0x00002175, 0x00002176, + 0x000020EF, 0x00060041, 0x00000294, 0x00004EBE, 0x0000140E, 0x00000A0B, 0x00003CAC, 0x0003003E, + 0x00004EBE, 0x00003ABC, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_rgba16_unorm_float_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_rgba16_unorm_float_cs.h new file mode 100644 index 0000000..c4e119b --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_rgba16_unorm_float_cs.h @@ -0,0 +1,611 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25059 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v3uint = OpTypeVector %uint 3 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %uint_65535 = OpConstant %uint 65535 +%float_1_52590219en05 = OpConstant %float 1.52590219e-05 + %uint_16 = OpConstant %uint 16 + %uint_0 = OpConstant %uint 0 + %v2float = OpTypeVector %float 2 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %uint_3 = OpConstant %uint 3 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2596 = OpConstantComposite %v3uint %uint_2 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %uint_9 = OpConstant %uint 9 + %uint_10 = OpConstant %uint 10 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %850 = OpConstantComposite %v4uint %uint_65535 %uint_65535 %uint_65535 %uint_65535 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24540 = OpBitwiseAnd %uint %13606 %uint_1 + %17270 = OpINotEqual %bool %24540 %uint_0 + %12328 = OpBitwiseAnd %uint %13606 %uint_2 + %17284 = OpINotEqual %bool %12328 %uint_0 + %7856 = OpShiftRightLogical %uint %13606 %uint_2 + %25058 = OpBitwiseAnd %uint %7856 %uint_3 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2596 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_8 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %10084 = OpIAdd %uint %10898 %22411 + %21685 = OpShiftRightLogical %uint %10084 %uint_4 + OpSelectionMerge %24387 DontFlatten + OpBranchConditional %17270 %22376 %20978 + %22376 = OpLabel + OpSelectionMerge %7691 DontFlatten + OpBranchConditional %17284 %11256 %6361 + %11256 = OpLabel + %12979 = OpShiftRightArithmetic %int %17598 %int_4 + %24606 = OpShiftRightArithmetic %int %6362 %int_2 + %18759 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %18759 + %21281 = OpIMul %int %24606 %6314 + %15143 = OpIAdd %int %12979 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %14593 = OpBitcast %int %9032 + %8436 = OpIMul %int %15143 %14593 + %12986 = OpShiftRightArithmetic %int %23531 %int_5 + %24558 = OpIAdd %int %12986 %8436 + %8797 = OpShiftLeftLogical %int %24558 %uint_9 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %23531 %int_7 + %12600 = OpBitwiseAnd %int %17598 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_9 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17598 %int_3 + %13731 = OpIAdd %int %8725 %24606 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %23531 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %6362 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_9 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17598 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %24224 = OpBitwiseAnd %int %16728 %int_63 + %21741 = OpIAdd %int %23348 %24224 + OpBranch %7691 + %6361 = OpLabel + %6573 = OpBitcast %v2int %17136 + %17090 = OpCompositeExtract %int %6573 0 + %9469 = OpShiftRightArithmetic %int %17090 %int_5 + %10055 = OpCompositeExtract %int %6573 1 + %16476 = OpShiftRightArithmetic %int %10055 %int_5 + %23373 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23373 + %21319 = OpIMul %int %16476 %6315 + %16222 = OpIAdd %int %9469 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_10 + %10934 = OpBitwiseAnd %int %17090 %int_7 + %12601 = OpBitwiseAnd %int %10055 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_3 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10055 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10055 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10055 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %17090 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %14157 = OpBitwiseAnd %int %16729 %int_63 + %12098 = OpIAdd %int %15437 %14157 + OpBranch %7691 + %7691 = OpLabel + %10540 = OpPhi %int %21741 %11256 %12098 %6361 + OpBranch %24387 + %20978 = OpLabel + %15548 = OpBitcast %int %22409 + %24760 = OpIMul %int %6362 %15548 + %8334 = OpIAdd %int %24760 %17598 + %8952 = OpBitcast %int %22408 + %7839 = OpIMul %int %8334 %8952 + %7984 = OpIAdd %int %22810 %7839 + OpBranch %24387 + %24387 = OpLabel + %10814 = OpPhi %int %10540 %7691 %7984 %20978 + %6719 = OpBitcast %int %24236 + %22221 = OpIAdd %int %6719 %10814 + %16105 = OpBitcast %uint %22221 + %22117 = OpShiftRightLogical %uint %16105 %uint_4 + %17173 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %22117 + %7338 = OpLoad %v4uint %17173 + %13760 = OpIEqual %bool %25058 %uint_1 + %21366 = OpIEqual %bool %25058 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %24387 %16376 %10583 + %19638 = OpIEqual %bool %25058 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %13962 None + OpBranchConditional %15139 %11064 %13962 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %13962 + %13962 = OpLabel + %16606 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %18240 = OpBitwiseAnd %v4uint %16606 %850 + %9137 = OpConvertUToF %v4float %18240 + %19365 = OpVectorTimesScalar %v4float %9137 %float_1_52590219en05 + %23367 = OpShiftRightLogical %v4uint %16606 %749 + %18492 = OpConvertUToF %v4float %23367 + %18450 = OpVectorTimesScalar %v4float %18492 %float_1_52590219en05 + %6268 = OpCompositeExtract %float %19365 0 + %13806 = OpCompositeExtract %float %18450 0 + %19232 = OpCompositeConstruct %v2float %6268 %13806 + %8561 = OpExtInst %uint %1 PackHalf2x16 %19232 + %23487 = OpCompositeExtract %float %19365 1 + %14759 = OpCompositeExtract %float %18450 1 + %19233 = OpCompositeConstruct %v2float %23487 %14759 + %8562 = OpExtInst %uint %1 PackHalf2x16 %19233 + %23488 = OpCompositeExtract %float %19365 2 + %14760 = OpCompositeExtract %float %18450 2 + %19234 = OpCompositeConstruct %v2float %23488 %14760 + %8563 = OpExtInst %uint %1 PackHalf2x16 %19234 + %23489 = OpCompositeExtract %float %19365 3 + %14761 = OpCompositeExtract %float %18450 3 + %19213 = OpCompositeConstruct %v2float %23489 %14761 + %8430 = OpExtInst %uint %1 PackHalf2x16 %19213 + %15035 = OpCompositeConstruct %v4uint %8561 %8562 %8563 %8430 + %17859 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21685 + OpStore %17859 %15035 + %21686 = OpIAdd %uint %21685 %int_1 + OpSelectionMerge %6871 DontFlatten + OpBranchConditional %17270 %21993 %7205 + %21993 = OpLabel + OpBranch %6871 + %7205 = OpLabel + OpBranch %6871 + %6871 = OpLabel + %17775 = OpPhi %uint %uint_32 %21993 %uint_16 %7205 + %16832 = OpShiftRightLogical %uint %17775 %uint_4 + %10971 = OpIAdd %uint %22117 %16832 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %10971 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %6871 %16377 %10584 + OpSelectionMerge %13963 None + OpBranchConditional %15139 %11065 %13963 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %13963 + %13963 = OpLabel + %16607 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %18241 = OpBitwiseAnd %v4uint %16607 %850 + %9138 = OpConvertUToF %v4float %18241 + %19366 = OpVectorTimesScalar %v4float %9138 %float_1_52590219en05 + %23368 = OpShiftRightLogical %v4uint %16607 %749 + %18493 = OpConvertUToF %v4float %23368 + %18451 = OpVectorTimesScalar %v4float %18493 %float_1_52590219en05 + %6269 = OpCompositeExtract %float %19366 0 + %13807 = OpCompositeExtract %float %18451 0 + %19235 = OpCompositeConstruct %v2float %6269 %13807 + %8564 = OpExtInst %uint %1 PackHalf2x16 %19235 + %23490 = OpCompositeExtract %float %19366 1 + %14762 = OpCompositeExtract %float %18451 1 + %19236 = OpCompositeConstruct %v2float %23490 %14762 + %8565 = OpExtInst %uint %1 PackHalf2x16 %19236 + %23491 = OpCompositeExtract %float %19366 2 + %14763 = OpCompositeExtract %float %18451 2 + %19237 = OpCompositeConstruct %v2float %23491 %14763 + %8566 = OpExtInst %uint %1 PackHalf2x16 %19237 + %23492 = OpCompositeExtract %float %19366 3 + %14764 = OpCompositeExtract %float %18451 3 + %19214 = OpCompositeConstruct %v2float %23492 %14764 + %8431 = OpExtInst %uint %1 PackHalf2x16 %19214 + %15036 = OpCompositeConstruct %v4uint %8564 %8565 %8566 %8431 + %20158 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %21686 + OpStore %20158 %15036 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_rgba16_unorm_float_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000061E3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000017, + 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, + 0x0000000C, 0x00000002, 0x00040017, 0x00000016, 0x0000000C, 0x00000003, 0x00020014, 0x00000009, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x0004002B, + 0x0000000B, 0x000001C1, 0x0000FFFF, 0x0004002B, 0x0000000D, 0x0000092A, 0x37800080, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x00040017, + 0x00000013, 0x0000000D, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, + 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, + 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, + 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, + 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, + 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, + 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, + 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, + 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, + 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, + 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, + 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, + 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, + 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, 0x0000000B, 0x00040020, 0x00000706, 0x00000009, + 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, + 0x00000000, 0x00040020, 0x00000288, 0x00000009, 0x0000000B, 0x00040020, 0x00000291, 0x00000009, + 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, 0x00000F48, + 0x00000001, 0x0006002C, 0x00000014, 0x00000A24, 0x00000A10, 0x00000A0A, 0x00000A0A, 0x00040017, + 0x0000000F, 0x00000009, 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, 0x000007B4, + 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, 0x0000107A, + 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, 0x00000017, + 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, 0x0004003B, + 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, 0x00000A6A, + 0x00000A0D, 0x0004002B, 0x0000000B, 0x00000A25, 0x00000009, 0x0004002B, 0x0000000B, 0x00000A28, + 0x0000000A, 0x0007002C, 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, + 0x0007002C, 0x00000017, 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, + 0x00000017, 0x0000072E, 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, + 0x000002ED, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0007002C, 0x00000017, 0x00000352, + 0x000001C1, 0x000001C1, 0x000001C1, 0x000001C1, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, + 0x00000502, 0x000200F8, 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, + 0x00002E68, 0x000200F8, 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, + 0x0004003D, 0x0000000B, 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005FDC, 0x00003526, + 0x00000A0D, 0x000500AB, 0x00000009, 0x00004376, 0x00005FDC, 0x00000A0A, 0x000500C7, 0x0000000B, + 0x00003028, 0x00003526, 0x00000A10, 0x000500AB, 0x00000009, 0x00004384, 0x00003028, 0x00000A0A, + 0x000500C2, 0x0000000B, 0x00001EB0, 0x00003526, 0x00000A10, 0x000500C7, 0x0000000B, 0x000061E2, + 0x00001EB0, 0x00000A13, 0x00050041, 0x00000288, 0x0000492C, 0x00000CE9, 0x00000A0E, 0x0004003D, + 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, 0x00004EBA, 0x00000CE9, 0x00000A11, + 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, 0x00000288, 0x00004EBB, 0x00000CE9, + 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, 0x00050041, 0x00000291, 0x00004EBC, + 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, 0x00004EBC, 0x00050041, 0x00000288, + 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, 0x0000578B, 0x00004EBD, 0x00050041, + 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, 0x0000000B, 0x000019C2, 0x00004E6E, + 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, 0x00000014, 0x0000538B, 0x00002A0E, + 0x00000A24, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, 0x0000538B, 0x00000000, 0x00000001, + 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, 0x00000000, 0x00000001, 0x000500AE, + 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, 0x00000009, 0x00006067, 0x00004288, + 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, 0x000055E8, 0x000019BA, 0x000200F8, + 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, 0x0004007C, 0x00000016, 0x00005BB6, + 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, 0x00000001, 0x00050051, 0x0000000C, + 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, 0x0000591A, 0x00005BEB, 0x00000A23, + 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, 0x0004007C, 0x0000000C, 0x000038A9, + 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, 0x000038A9, 0x00050051, 0x0000000C, + 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, 0x000056D4, 0x00002C0F, 0x000044BE, + 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, 0x0000000C, 0x00005FD7, 0x000056D4, + 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, 0x00005FD7, 0x0004007C, 0x0000000B, + 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00002764, 0x00002A92, 0x0000578B, 0x000500C2, + 0x0000000B, 0x000054B5, 0x00002764, 0x00000A16, 0x000300F7, 0x00005F43, 0x00000002, 0x000400FA, + 0x00004376, 0x00005768, 0x000051F2, 0x000200F8, 0x00005768, 0x000300F7, 0x00001E0B, 0x00000002, + 0x000400FA, 0x00004384, 0x00002BF8, 0x000018D9, 0x000200F8, 0x00002BF8, 0x000500C3, 0x0000000C, + 0x000032B3, 0x000044BE, 0x00000A17, 0x000500C3, 0x0000000C, 0x0000601E, 0x000018DA, 0x00000A11, + 0x000500C2, 0x0000000B, 0x00004947, 0x00005789, 0x00000A16, 0x0004007C, 0x0000000C, 0x000018AA, + 0x00004947, 0x00050084, 0x0000000C, 0x00005321, 0x0000601E, 0x000018AA, 0x00050080, 0x0000000C, + 0x00003B27, 0x000032B3, 0x00005321, 0x000500C2, 0x0000000B, 0x00002348, 0x00005788, 0x00000A19, + 0x0004007C, 0x0000000C, 0x00003901, 0x00002348, 0x00050084, 0x0000000C, 0x000020F4, 0x00003B27, + 0x00003901, 0x000500C3, 0x0000000C, 0x000032BA, 0x00005BEB, 0x00000A1A, 0x00050080, 0x0000000C, + 0x00005FEE, 0x000032BA, 0x000020F4, 0x000500C4, 0x0000000C, 0x0000225D, 0x00005FEE, 0x00000A25, + 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, + 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00005BEB, 0x00000A20, 0x000500C7, + 0x0000000C, 0x00003138, 0x000044BE, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, + 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, + 0x00001B88, 0x0000434B, 0x00000A25, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, + 0x000500C3, 0x0000000C, 0x00002215, 0x000044BE, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, + 0x00002215, 0x0000601E, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, + 0x0000000C, 0x00004112, 0x00005BEB, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, + 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, + 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, + 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, + 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, + 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, + 0x000047B4, 0x000018DA, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A25, + 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, + 0x000044BE, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, + 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, + 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, + 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, + 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, + 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, + 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, + 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005EA0, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x000054ED, + 0x00005B34, 0x00005EA0, 0x000200F9, 0x00001E0B, 0x000200F8, 0x000018D9, 0x0004007C, 0x00000012, + 0x000019AD, 0x000042F0, 0x00050051, 0x0000000C, 0x000042C2, 0x000019AD, 0x00000000, 0x000500C3, + 0x0000000C, 0x000024FD, 0x000042C2, 0x00000A1A, 0x00050051, 0x0000000C, 0x00002747, 0x000019AD, + 0x00000001, 0x000500C3, 0x0000000C, 0x0000405C, 0x00002747, 0x00000A1A, 0x000500C2, 0x0000000B, + 0x00005B4D, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x000018AB, 0x00005B4D, 0x00050084, + 0x0000000C, 0x00005347, 0x0000405C, 0x000018AB, 0x00050080, 0x0000000C, 0x00003F5E, 0x000024FD, + 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, 0x00000A28, 0x000500C7, 0x0000000C, + 0x00002AB6, 0x000042C2, 0x00000A20, 0x000500C7, 0x0000000C, 0x00003139, 0x00002747, 0x00000A35, + 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, 0x00050080, 0x0000000C, 0x00004397, + 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, 0x00004397, 0x00000A13, 0x000500C7, + 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, 0x0000000C, 0x00002F76, 0x000027B1, + 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, 0x00002F76, 0x000500C7, 0x0000000C, + 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, 0x00004D30, 0x00003C4C, 0x00003397, + 0x000500C7, 0x0000000C, 0x000047B5, 0x00002747, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544D, + 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, 0x00004D30, 0x0000544D, 0x000500C7, + 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, 0x0000000C, 0x00002416, 0x00005022, + 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002747, 0x00000A3B, 0x000500C4, 0x0000000C, + 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, 0x0000415A, 0x00002416, 0x00002F77, + 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, 0x000500C4, 0x0000000C, 0x0000544E, + 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, 0x0000415A, 0x0000544E, 0x000500C7, + 0x0000000C, 0x00005083, 0x00002747, 0x00000A23, 0x000500C3, 0x0000000C, 0x000041BF, 0x00005083, + 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, + 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, 0x00005453, 0x000035B6, 0x00000A14, + 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, 0x00050080, 0x0000000C, 0x00003C4D, + 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x0000374D, 0x00004159, 0x00000AC8, 0x00050080, + 0x0000000C, 0x00002F42, 0x00003C4D, 0x0000374D, 0x000200F9, 0x00001E0B, 0x000200F8, 0x00001E0B, + 0x000700F5, 0x0000000C, 0x0000292C, 0x000054ED, 0x00002BF8, 0x00002F42, 0x000018D9, 0x000200F9, + 0x00005F43, 0x000200F8, 0x000051F2, 0x0004007C, 0x0000000C, 0x00003CBC, 0x00005789, 0x00050084, + 0x0000000C, 0x000060B8, 0x000018DA, 0x00003CBC, 0x00050080, 0x0000000C, 0x0000208E, 0x000060B8, + 0x000044BE, 0x0004007C, 0x0000000C, 0x000022F8, 0x00005788, 0x00050084, 0x0000000C, 0x00001E9F, + 0x0000208E, 0x000022F8, 0x00050080, 0x0000000C, 0x00001F30, 0x0000591A, 0x00001E9F, 0x000200F9, + 0x00005F43, 0x000200F8, 0x00005F43, 0x000700F5, 0x0000000C, 0x00002A3E, 0x0000292C, 0x00001E0B, + 0x00001F30, 0x000051F2, 0x0004007C, 0x0000000C, 0x00001A3F, 0x00005EAC, 0x00050080, 0x0000000C, + 0x000056CD, 0x00001A3F, 0x00002A3E, 0x0004007C, 0x0000000B, 0x00003EE9, 0x000056CD, 0x000500C2, + 0x0000000B, 0x00005665, 0x00003EE9, 0x00000A16, 0x00060041, 0x00000294, 0x00004315, 0x0000107A, + 0x00000A0B, 0x00005665, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004315, 0x000500AA, 0x00000009, + 0x000035C0, 0x000061E2, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x000061E2, 0x00000A10, + 0x000500A6, 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, 0x00000000, + 0x000400FA, 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, + 0x0000475F, 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, + 0x000500C7, 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, + 0x000050AC, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, + 0x00003463, 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, 0x00005F43, + 0x00003FF8, 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x000061E2, 0x00000A13, 0x000500A6, + 0x00000009, 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x0000368A, 0x00000000, 0x000400FA, + 0x00003B23, 0x00002B38, 0x0000368A, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, + 0x00005879, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, + 0x00000017, 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x0000368A, 0x000200F8, 0x0000368A, + 0x000700F5, 0x00000017, 0x000040DE, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x000500C7, + 0x00000017, 0x00004740, 0x000040DE, 0x00000352, 0x00040070, 0x0000001D, 0x000023B1, 0x00004740, + 0x0005008E, 0x0000001D, 0x00004BA5, 0x000023B1, 0x0000092A, 0x000500C2, 0x00000017, 0x00005B47, + 0x000040DE, 0x000002ED, 0x00040070, 0x0000001D, 0x0000483C, 0x00005B47, 0x0005008E, 0x0000001D, + 0x00004812, 0x0000483C, 0x0000092A, 0x00050051, 0x0000000D, 0x0000187C, 0x00004BA5, 0x00000000, + 0x00050051, 0x0000000D, 0x000035EE, 0x00004812, 0x00000000, 0x00050050, 0x00000013, 0x00004B20, + 0x0000187C, 0x000035EE, 0x0006000C, 0x0000000B, 0x00002171, 0x00000001, 0x0000003A, 0x00004B20, + 0x00050051, 0x0000000D, 0x00005BBF, 0x00004BA5, 0x00000001, 0x00050051, 0x0000000D, 0x000039A7, + 0x00004812, 0x00000001, 0x00050050, 0x00000013, 0x00004B21, 0x00005BBF, 0x000039A7, 0x0006000C, + 0x0000000B, 0x00002172, 0x00000001, 0x0000003A, 0x00004B21, 0x00050051, 0x0000000D, 0x00005BC0, + 0x00004BA5, 0x00000002, 0x00050051, 0x0000000D, 0x000039A8, 0x00004812, 0x00000002, 0x00050050, + 0x00000013, 0x00004B22, 0x00005BC0, 0x000039A8, 0x0006000C, 0x0000000B, 0x00002173, 0x00000001, + 0x0000003A, 0x00004B22, 0x00050051, 0x0000000D, 0x00005BC1, 0x00004BA5, 0x00000003, 0x00050051, + 0x0000000D, 0x000039A9, 0x00004812, 0x00000003, 0x00050050, 0x00000013, 0x00004B0D, 0x00005BC1, + 0x000039A9, 0x0006000C, 0x0000000B, 0x000020EE, 0x00000001, 0x0000003A, 0x00004B0D, 0x00070050, + 0x00000017, 0x00003ABB, 0x00002171, 0x00002172, 0x00002173, 0x000020EE, 0x00060041, 0x00000294, + 0x000045C3, 0x0000140E, 0x00000A0B, 0x000054B5, 0x0003003E, 0x000045C3, 0x00003ABB, 0x00050080, + 0x0000000B, 0x000054B6, 0x000054B5, 0x00000A0E, 0x000300F7, 0x00001AD7, 0x00000002, 0x000400FA, + 0x00004376, 0x000055E9, 0x00001C25, 0x000200F8, 0x000055E9, 0x000200F9, 0x00001AD7, 0x000200F8, + 0x00001C25, 0x000200F9, 0x00001AD7, 0x000200F8, 0x00001AD7, 0x000700F5, 0x0000000B, 0x0000456F, + 0x00000A6A, 0x000055E9, 0x00000A3A, 0x00001C25, 0x000500C2, 0x0000000B, 0x000041C0, 0x0000456F, + 0x00000A16, 0x00050080, 0x0000000B, 0x00002ADB, 0x00005665, 0x000041C0, 0x00060041, 0x00000294, + 0x0000571A, 0x0000107A, 0x00000A0B, 0x00002ADB, 0x0004003D, 0x00000017, 0x000019B2, 0x0000571A, + 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, 0x000200F8, + 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, 0x00000017, + 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, 0x0000072E, + 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF9, + 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, 0x00000017, + 0x00002AAC, 0x000019B2, 0x00001AD7, 0x00003FF9, 0x00002958, 0x000300F7, 0x0000368B, 0x00000000, + 0x000400FA, 0x00003B23, 0x00002B39, 0x0000368B, 0x000200F8, 0x00002B39, 0x000500C4, 0x00000017, + 0x00005E18, 0x00002AAC, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, 0x000002ED, + 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x0000368B, 0x000200F8, + 0x0000368B, 0x000700F5, 0x00000017, 0x000040DF, 0x00002AAC, 0x00003A1A, 0x000029E9, 0x00002B39, + 0x000500C7, 0x00000017, 0x00004741, 0x000040DF, 0x00000352, 0x00040070, 0x0000001D, 0x000023B2, + 0x00004741, 0x0005008E, 0x0000001D, 0x00004BA6, 0x000023B2, 0x0000092A, 0x000500C2, 0x00000017, + 0x00005B48, 0x000040DF, 0x000002ED, 0x00040070, 0x0000001D, 0x0000483D, 0x00005B48, 0x0005008E, + 0x0000001D, 0x00004813, 0x0000483D, 0x0000092A, 0x00050051, 0x0000000D, 0x0000187D, 0x00004BA6, + 0x00000000, 0x00050051, 0x0000000D, 0x000035EF, 0x00004813, 0x00000000, 0x00050050, 0x00000013, + 0x00004B23, 0x0000187D, 0x000035EF, 0x0006000C, 0x0000000B, 0x00002174, 0x00000001, 0x0000003A, + 0x00004B23, 0x00050051, 0x0000000D, 0x00005BC2, 0x00004BA6, 0x00000001, 0x00050051, 0x0000000D, + 0x000039AA, 0x00004813, 0x00000001, 0x00050050, 0x00000013, 0x00004B24, 0x00005BC2, 0x000039AA, + 0x0006000C, 0x0000000B, 0x00002175, 0x00000001, 0x0000003A, 0x00004B24, 0x00050051, 0x0000000D, + 0x00005BC3, 0x00004BA6, 0x00000002, 0x00050051, 0x0000000D, 0x000039AB, 0x00004813, 0x00000002, + 0x00050050, 0x00000013, 0x00004B25, 0x00005BC3, 0x000039AB, 0x0006000C, 0x0000000B, 0x00002176, + 0x00000001, 0x0000003A, 0x00004B25, 0x00050051, 0x0000000D, 0x00005BC4, 0x00004BA6, 0x00000003, + 0x00050051, 0x0000000D, 0x000039AC, 0x00004813, 0x00000003, 0x00050050, 0x00000013, 0x00004B0E, + 0x00005BC4, 0x000039AC, 0x0006000C, 0x0000000B, 0x000020EF, 0x00000001, 0x0000003A, 0x00004B0E, + 0x00070050, 0x00000017, 0x00003ABC, 0x00002174, 0x00002175, 0x00002176, 0x000020EF, 0x00060041, + 0x00000294, 0x00004EBE, 0x0000140E, 0x00000A0B, 0x000054B6, 0x0003003E, 0x00004EBE, 0x00003ABC, + 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shaders/vulkan_spirv/texture_load_rgba16_unorm_float_scaled_cs.h b/src/graphics/shaders/vulkan_spirv/texture_load_rgba16_unorm_float_scaled_cs.h new file mode 100644 index 0000000..5860d63 --- /dev/null +++ b/src/graphics/shaders/vulkan_spirv/texture_load_rgba16_unorm_float_scaled_cs.h @@ -0,0 +1,673 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25155 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %5663 "main" %gl_GlobalInvocationID + OpExecutionMode %5663 LocalSize 4 32 1 + OpDecorate %_struct_1161 Block + OpMemberDecorate %_struct_1161 0 Offset 0 + OpMemberDecorate %_struct_1161 1 Offset 4 + OpMemberDecorate %_struct_1161 2 Offset 8 + OpMemberDecorate %_struct_1161 3 Offset 12 + OpMemberDecorate %_struct_1161 4 Offset 16 + OpMemberDecorate %_struct_1161 5 Offset 28 + OpMemberDecorate %_struct_1161 6 Offset 32 + OpMemberDecorate %_struct_1161 7 Offset 36 + OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId + OpDecorate %_runtimearr_v4uint ArrayStride 16 + OpDecorate %_struct_1972 BufferBlock + OpMemberDecorate %_struct_1972 0 NonWritable + OpMemberDecorate %_struct_1972 0 Offset 0 + OpDecorate %4218 NonWritable + OpDecorate %4218 Binding 0 + OpDecorate %4218 DescriptorSet 1 + OpDecorate %_runtimearr_v4uint_0 ArrayStride 16 + OpDecorate %_struct_1973 BufferBlock + OpMemberDecorate %_struct_1973 0 NonReadable + OpMemberDecorate %_struct_1973 0 Offset 0 + OpDecorate %5134 NonReadable + OpDecorate %5134 Binding 0 + OpDecorate %5134 DescriptorSet 0 + OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3int = OpTypeVector %int 3 + %bool = OpTypeBool + %v3uint = OpTypeVector %uint 3 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %uint_65535 = OpConstant %uint 65535 +%float_1_52590219en05 = OpConstant %float 1.52590219e-05 + %uint_16 = OpConstant %uint 16 + %uint_0 = OpConstant %uint 0 + %v2float = OpTypeVector %float 2 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %uint_3 = OpConstant %uint 3 +%uint_16711935 = OpConstant %uint 16711935 + %uint_8 = OpConstant %uint 8 +%uint_4278255360 = OpConstant %uint 4278255360 + %int_5 = OpConstant %int 5 + %uint_5 = OpConstant %uint 5 + %uint_7 = OpConstant %uint 7 + %int_7 = OpConstant %int 7 + %int_14 = OpConstant %int 14 + %int_2 = OpConstant %int 2 + %int_n16 = OpConstant %int -16 + %int_1 = OpConstant %int 1 + %int_15 = OpConstant %int 15 + %int_4 = OpConstant %int 4 + %int_n512 = OpConstant %int -512 + %int_3 = OpConstant %int 3 + %int_16 = OpConstant %int 16 + %int_448 = OpConstant %int 448 + %int_8 = OpConstant %int 8 + %int_6 = OpConstant %int 6 + %int_63 = OpConstant %int 63 + %uint_4 = OpConstant %uint 4 +%int_268435455 = OpConstant %int 268435455 + %int_n2 = OpConstant %int -2 + %uint_32 = OpConstant %uint 32 +%_struct_1161 = OpTypeStruct %uint %uint %uint %uint %v3uint %uint %uint %uint +%_ptr_PushConstant__struct_1161 = OpTypePointer PushConstant %_struct_1161 + %3305 = OpVariable %_ptr_PushConstant__struct_1161 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint + %1927 = OpConstantComposite %v2uint %uint_4 %uint_7 +%_ptr_PushConstant_v3uint = OpTypePointer PushConstant %v3uint +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input + %2596 = OpConstantComposite %v3uint %uint_2 %uint_0 %uint_0 + %v2bool = OpTypeVector %bool 2 +%_runtimearr_v4uint = OpTypeRuntimeArray %v4uint +%_struct_1972 = OpTypeStruct %_runtimearr_v4uint +%_ptr_Uniform__struct_1972 = OpTypePointer Uniform %_struct_1972 + %4218 = OpVariable %_ptr_Uniform__struct_1972 Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint +%_runtimearr_v4uint_0 = OpTypeRuntimeArray %v4uint +%_struct_1973 = OpTypeStruct %_runtimearr_v4uint_0 +%_ptr_Uniform__struct_1973 = OpTypePointer Uniform %_struct_1973 + %5134 = OpVariable %_ptr_Uniform__struct_1973 Uniform +%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_4 %uint_32 %uint_1 + %1954 = OpConstantComposite %v2uint %uint_7 %uint_7 + %uint_9 = OpConstant %uint 9 + %uint_10 = OpConstant %uint 10 + %2510 = OpConstantComposite %v4uint %uint_16711935 %uint_16711935 %uint_16711935 %uint_16711935 + %317 = OpConstantComposite %v4uint %uint_8 %uint_8 %uint_8 %uint_8 + %1838 = OpConstantComposite %v4uint %uint_4278255360 %uint_4278255360 %uint_4278255360 %uint_4278255360 + %749 = OpConstantComposite %v4uint %uint_16 %uint_16 %uint_16 %uint_16 + %850 = OpConstantComposite %v4uint %uint_65535 %uint_65535 %uint_65535 %uint_65535 + %5663 = OpFunction %void None %1282 + %15110 = OpLabel + OpSelectionMerge %19578 None + OpSwitch %uint_0 %11880 + %11880 = OpLabel + %24791 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_0 + %13606 = OpLoad %uint %24791 + %24445 = OpBitwiseAnd %uint %13606 %uint_2 + %18667 = OpINotEqual %bool %24445 %uint_0 + %8141 = OpShiftRightLogical %uint %13606 %uint_2 + %24990 = OpBitwiseAnd %uint %8141 %uint_3 + %8871 = OpCompositeConstruct %v2uint %13606 %13606 + %7087 = OpShiftRightLogical %v2uint %8871 %1927 + %6551 = OpBitwiseAnd %v2uint %7087 %1954 + %18732 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_1 + %24236 = OpLoad %uint %18732 + %20154 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_2 + %22408 = OpLoad %uint %20154 + %20155 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_3 + %22409 = OpLoad %uint %20155 + %20156 = OpAccessChain %_ptr_PushConstant_v3uint %3305 %int_4 + %22410 = OpLoad %v3uint %20156 + %20157 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_5 + %22411 = OpLoad %uint %20157 + %20078 = OpAccessChain %_ptr_PushConstant_uint %3305 %int_6 + %6594 = OpLoad %uint %20078 + %10766 = OpLoad %v3uint %gl_GlobalInvocationID + %21387 = OpShiftLeftLogical %v3uint %10766 %2596 + %17136 = OpVectorShuffle %v2uint %21387 %21387 0 1 + %9263 = OpVectorShuffle %v2uint %22410 %22410 0 1 + %17032 = OpUGreaterThanEqual %v2bool %17136 %9263 + %24679 = OpAny %bool %17032 + OpSelectionMerge %6586 DontFlatten + OpBranchConditional %24679 %21992 %6586 + %21992 = OpLabel + OpBranch %19578 + %6586 = OpLabel + %23478 = OpBitcast %v3int %21387 + %18710 = OpCompositeExtract %uint %22410 1 + %23531 = OpCompositeExtract %int %23478 0 + %22810 = OpIMul %int %23531 %int_8 + %6362 = OpCompositeExtract %int %23478 2 + %14505 = OpBitcast %int %18710 + %11279 = OpIMul %int %6362 %14505 + %17598 = OpCompositeExtract %int %23478 1 + %22228 = OpIAdd %int %11279 %17598 + %22405 = OpBitcast %int %6594 + %24535 = OpIMul %int %22228 %22405 + %8258 = OpIAdd %int %22810 %24535 + %10898 = OpBitcast %uint %8258 + %6930 = OpIAdd %uint %10898 %22411 + %11197 = OpShiftRightLogical %uint %6930 %uint_4 + %10722 = OpCompositeExtract %uint %21387 0 + %7662 = OpShiftRightLogical %uint %10722 %uint_1 + %9988 = OpCompositeExtract %uint %21387 1 + %23563 = OpCompositeConstruct %v2uint %7662 %9988 + %8041 = OpUDiv %v2uint %23563 %6551 + %13932 = OpCompositeExtract %uint %8041 0 + %19789 = OpShiftLeftLogical %uint %13932 %uint_1 + %20905 = OpCompositeExtract %uint %8041 1 + %23022 = OpCompositeExtract %uint %21387 2 + %9417 = OpCompositeConstruct %v3uint %19789 %20905 %23022 + OpSelectionMerge %21313 DontFlatten + OpBranchConditional %18667 %21373 %11737 + %21373 = OpLabel + %10608 = OpBitcast %v3int %9417 + %17090 = OpCompositeExtract %int %10608 1 + %9469 = OpShiftRightArithmetic %int %17090 %int_4 + %10055 = OpCompositeExtract %int %10608 2 + %16476 = OpShiftRightArithmetic %int %10055 %int_2 + %23373 = OpShiftRightLogical %uint %22409 %uint_4 + %6314 = OpBitcast %int %23373 + %21281 = OpIMul %int %16476 %6314 + %15143 = OpIAdd %int %9469 %21281 + %9032 = OpShiftRightLogical %uint %22408 %uint_5 + %12427 = OpBitcast %int %9032 + %10360 = OpIMul %int %15143 %12427 + %25154 = OpCompositeExtract %int %10608 0 + %20423 = OpShiftRightArithmetic %int %25154 %int_5 + %18940 = OpIAdd %int %20423 %10360 + %8797 = OpShiftLeftLogical %int %18940 %uint_9 + %11510 = OpBitwiseAnd %int %8797 %int_268435455 + %18938 = OpShiftLeftLogical %int %11510 %int_1 + %19768 = OpBitwiseAnd %int %25154 %int_7 + %12600 = OpBitwiseAnd %int %17090 %int_6 + %17741 = OpShiftLeftLogical %int %12600 %int_2 + %17227 = OpIAdd %int %19768 %17741 + %7048 = OpShiftLeftLogical %int %17227 %uint_9 + %24035 = OpShiftRightArithmetic %int %7048 %int_6 + %8725 = OpShiftRightArithmetic %int %17090 %int_3 + %13731 = OpIAdd %int %8725 %16476 + %23052 = OpBitwiseAnd %int %13731 %int_1 + %16658 = OpShiftRightArithmetic %int %25154 %int_3 + %18794 = OpShiftLeftLogical %int %23052 %int_1 + %13501 = OpIAdd %int %16658 %18794 + %19165 = OpBitwiseAnd %int %13501 %int_3 + %21578 = OpShiftLeftLogical %int %19165 %int_1 + %15435 = OpIAdd %int %23052 %21578 + %13150 = OpBitwiseAnd %int %24035 %int_n16 + %20336 = OpIAdd %int %18938 %13150 + %23345 = OpShiftLeftLogical %int %20336 %int_1 + %23274 = OpBitwiseAnd %int %24035 %int_15 + %10332 = OpIAdd %int %23345 %23274 + %18356 = OpBitwiseAnd %int %10055 %int_3 + %21579 = OpShiftLeftLogical %int %18356 %uint_9 + %16727 = OpIAdd %int %10332 %21579 + %19166 = OpBitwiseAnd %int %17090 %int_1 + %21580 = OpShiftLeftLogical %int %19166 %int_4 + %16728 = OpIAdd %int %16727 %21580 + %20438 = OpBitwiseAnd %int %15435 %int_1 + %9987 = OpShiftLeftLogical %int %20438 %int_3 + %13106 = OpShiftRightArithmetic %int %16728 %int_6 + %14038 = OpBitwiseAnd %int %13106 %int_7 + %13330 = OpIAdd %int %9987 %14038 + %23346 = OpShiftLeftLogical %int %13330 %int_3 + %23217 = OpBitwiseAnd %int %15435 %int_n2 + %10908 = OpIAdd %int %23346 %23217 + %23347 = OpShiftLeftLogical %int %10908 %int_2 + %23218 = OpBitwiseAnd %int %16728 %int_n512 + %10909 = OpIAdd %int %23347 %23218 + %23348 = OpShiftLeftLogical %int %10909 %int_3 + %21849 = OpBitwiseAnd %int %16728 %int_63 + %24314 = OpIAdd %int %23348 %21849 + %22127 = OpBitcast %uint %24314 + OpBranch %21313 + %11737 = OpLabel + %9761 = OpVectorShuffle %v2uint %9417 %9417 0 1 + %22991 = OpBitcast %v2int %9761 + %6403 = OpCompositeExtract %int %22991 0 + %9470 = OpShiftRightArithmetic %int %6403 %int_5 + %10056 = OpCompositeExtract %int %22991 1 + %16477 = OpShiftRightArithmetic %int %10056 %int_5 + %23374 = OpShiftRightLogical %uint %22408 %uint_5 + %6315 = OpBitcast %int %23374 + %21319 = OpIMul %int %16477 %6315 + %16222 = OpIAdd %int %9470 %21319 + %19086 = OpShiftLeftLogical %int %16222 %uint_10 + %10934 = OpBitwiseAnd %int %6403 %int_7 + %12601 = OpBitwiseAnd %int %10056 %int_14 + %17742 = OpShiftLeftLogical %int %12601 %int_2 + %17303 = OpIAdd %int %10934 %17742 + %6375 = OpShiftLeftLogical %int %17303 %uint_3 + %10161 = OpBitwiseAnd %int %6375 %int_n16 + %12150 = OpShiftLeftLogical %int %10161 %int_1 + %15436 = OpIAdd %int %19086 %12150 + %13207 = OpBitwiseAnd %int %6375 %int_15 + %19760 = OpIAdd %int %15436 %13207 + %18357 = OpBitwiseAnd %int %10056 %int_1 + %21581 = OpShiftLeftLogical %int %18357 %int_4 + %16729 = OpIAdd %int %19760 %21581 + %20514 = OpBitwiseAnd %int %16729 %int_n512 + %9238 = OpShiftLeftLogical %int %20514 %int_3 + %18995 = OpBitwiseAnd %int %10056 %int_16 + %12151 = OpShiftLeftLogical %int %18995 %int_7 + %16730 = OpIAdd %int %9238 %12151 + %19167 = OpBitwiseAnd %int %16729 %int_448 + %21582 = OpShiftLeftLogical %int %19167 %int_2 + %16708 = OpIAdd %int %16730 %21582 + %20611 = OpBitwiseAnd %int %10056 %int_8 + %16831 = OpShiftRightArithmetic %int %20611 %int_2 + %7916 = OpShiftRightArithmetic %int %6403 %int_3 + %13750 = OpIAdd %int %16831 %7916 + %21587 = OpBitwiseAnd %int %13750 %int_3 + %21583 = OpShiftLeftLogical %int %21587 %int_6 + %15437 = OpIAdd %int %16708 %21583 + %11782 = OpBitwiseAnd %int %16729 %int_63 + %14671 = OpIAdd %int %15437 %11782 + %22128 = OpBitcast %uint %14671 + OpBranch %21313 + %21313 = OpLabel + %9468 = OpPhi %uint %22127 %21373 %22128 %11737 + %16296 = OpIMul %v2uint %8041 %6551 + %15292 = OpISub %v2uint %23563 %16296 + %7303 = OpCompositeExtract %uint %6551 0 + %22882 = OpCompositeExtract %uint %6551 1 + %13170 = OpIMul %uint %7303 %22882 + %15520 = OpIMul %uint %9468 %13170 + %16084 = OpCompositeExtract %uint %15292 0 + %15890 = OpIMul %uint %16084 %22882 + %6886 = OpCompositeExtract %uint %15292 1 + %11045 = OpIAdd %uint %15890 %6886 + %24733 = OpShiftLeftLogical %uint %11045 %uint_1 + %23219 = OpBitwiseAnd %uint %10722 %uint_1 + %9559 = OpIAdd %uint %24733 %23219 + %16557 = OpShiftLeftLogical %uint %9559 %uint_3 + %20138 = OpIAdd %uint %15520 %16557 + %15273 = OpIAdd %uint %24236 %20138 + %14664 = OpShiftRightLogical %uint %15273 %uint_4 + %20399 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %14664 + %7338 = OpLoad %v4uint %20399 + %13760 = OpIEqual %bool %24990 %uint_1 + %21366 = OpIEqual %bool %24990 %uint_2 + %22150 = OpLogicalOr %bool %13760 %21366 + OpSelectionMerge %13411 None + OpBranchConditional %22150 %10583 %13411 + %10583 = OpLabel + %18271 = OpBitwiseAnd %v4uint %7338 %2510 + %9425 = OpShiftLeftLogical %v4uint %18271 %317 + %20652 = OpBitwiseAnd %v4uint %7338 %1838 + %17549 = OpShiftRightLogical %v4uint %20652 %317 + %16376 = OpBitwiseOr %v4uint %9425 %17549 + OpBranch %13411 + %13411 = OpLabel + %22649 = OpPhi %v4uint %7338 %21313 %16376 %10583 + %19638 = OpIEqual %bool %24990 %uint_3 + %15139 = OpLogicalOr %bool %21366 %19638 + OpSelectionMerge %13962 None + OpBranchConditional %15139 %11064 %13962 + %11064 = OpLabel + %24087 = OpShiftLeftLogical %v4uint %22649 %749 + %15335 = OpShiftRightLogical %v4uint %22649 %749 + %10728 = OpBitwiseOr %v4uint %24087 %15335 + OpBranch %13962 + %13962 = OpLabel + %16606 = OpPhi %v4uint %22649 %13411 %10728 %11064 + %18240 = OpBitwiseAnd %v4uint %16606 %850 + %9137 = OpConvertUToF %v4float %18240 + %19365 = OpVectorTimesScalar %v4float %9137 %float_1_52590219en05 + %23367 = OpShiftRightLogical %v4uint %16606 %749 + %18492 = OpConvertUToF %v4float %23367 + %18450 = OpVectorTimesScalar %v4float %18492 %float_1_52590219en05 + %6268 = OpCompositeExtract %float %19365 0 + %13806 = OpCompositeExtract %float %18450 0 + %19232 = OpCompositeConstruct %v2float %6268 %13806 + %8561 = OpExtInst %uint %1 PackHalf2x16 %19232 + %23487 = OpCompositeExtract %float %19365 1 + %14759 = OpCompositeExtract %float %18450 1 + %19233 = OpCompositeConstruct %v2float %23487 %14759 + %8562 = OpExtInst %uint %1 PackHalf2x16 %19233 + %23488 = OpCompositeExtract %float %19365 2 + %14760 = OpCompositeExtract %float %18450 2 + %19234 = OpCompositeConstruct %v2float %23488 %14760 + %8563 = OpExtInst %uint %1 PackHalf2x16 %19234 + %23489 = OpCompositeExtract %float %19365 3 + %14761 = OpCompositeExtract %float %18450 3 + %19213 = OpCompositeConstruct %v2float %23489 %14761 + %8430 = OpExtInst %uint %1 PackHalf2x16 %19213 + %15035 = OpCompositeConstruct %v4uint %8561 %8562 %8563 %8430 + %17859 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %11197 + OpStore %17859 %15035 + %15532 = OpIAdd %uint %11197 %int_1 + %6417 = OpUGreaterThan %bool %7303 %uint_1 + OpSelectionMerge %24764 DontFlatten + OpBranchConditional %6417 %20612 %20628 + %20612 = OpLabel + %13975 = OpUDiv %uint %7662 %7303 + %9086 = OpIMul %uint %13975 %7303 + %12657 = OpISub %uint %7662 %9086 + %9511 = OpIAdd %uint %12657 %uint_1 + %13375 = OpIEqual %bool %9511 %7303 + OpSelectionMerge %7917 None + OpBranchConditional %13375 %22174 %8593 + %22174 = OpLabel + %19289 = OpIMul %uint %uint_32 %7303 + %21519 = OpShiftLeftLogical %uint %12657 %uint_4 + %18756 = OpISub %uint %19289 %21519 + OpBranch %7917 + %8593 = OpLabel + OpBranch %7917 + %7917 = OpLabel + %10540 = OpPhi %uint %18756 %22174 %uint_16 %8593 + OpBranch %24764 + %20628 = OpLabel + OpBranch %24764 + %24764 = OpLabel + %10684 = OpPhi %uint %10540 %7917 %uint_32 %20628 + %18731 = OpIMul %uint %10684 %22882 + %16493 = OpShiftRightLogical %uint %18731 %uint_4 + %13163 = OpIAdd %uint %14664 %16493 + %22298 = OpAccessChain %_ptr_Uniform_v4uint %4218 %int_0 %13163 + %6578 = OpLoad %v4uint %22298 + OpSelectionMerge %14874 None + OpBranchConditional %22150 %10584 %14874 + %10584 = OpLabel + %18272 = OpBitwiseAnd %v4uint %6578 %2510 + %9426 = OpShiftLeftLogical %v4uint %18272 %317 + %20653 = OpBitwiseAnd %v4uint %6578 %1838 + %17550 = OpShiftRightLogical %v4uint %20653 %317 + %16377 = OpBitwiseOr %v4uint %9426 %17550 + OpBranch %14874 + %14874 = OpLabel + %10924 = OpPhi %v4uint %6578 %24764 %16377 %10584 + OpSelectionMerge %13963 None + OpBranchConditional %15139 %11065 %13963 + %11065 = OpLabel + %24088 = OpShiftLeftLogical %v4uint %10924 %749 + %15336 = OpShiftRightLogical %v4uint %10924 %749 + %10729 = OpBitwiseOr %v4uint %24088 %15336 + OpBranch %13963 + %13963 = OpLabel + %16607 = OpPhi %v4uint %10924 %14874 %10729 %11065 + %18241 = OpBitwiseAnd %v4uint %16607 %850 + %9138 = OpConvertUToF %v4float %18241 + %19366 = OpVectorTimesScalar %v4float %9138 %float_1_52590219en05 + %23368 = OpShiftRightLogical %v4uint %16607 %749 + %18493 = OpConvertUToF %v4float %23368 + %18451 = OpVectorTimesScalar %v4float %18493 %float_1_52590219en05 + %6269 = OpCompositeExtract %float %19366 0 + %13807 = OpCompositeExtract %float %18451 0 + %19235 = OpCompositeConstruct %v2float %6269 %13807 + %8564 = OpExtInst %uint %1 PackHalf2x16 %19235 + %23490 = OpCompositeExtract %float %19366 1 + %14762 = OpCompositeExtract %float %18451 1 + %19236 = OpCompositeConstruct %v2float %23490 %14762 + %8565 = OpExtInst %uint %1 PackHalf2x16 %19236 + %23491 = OpCompositeExtract %float %19366 2 + %14763 = OpCompositeExtract %float %18451 2 + %19237 = OpCompositeConstruct %v2float %23491 %14763 + %8566 = OpExtInst %uint %1 PackHalf2x16 %19237 + %23492 = OpCompositeExtract %float %19366 3 + %14764 = OpCompositeExtract %float %18451 3 + %19214 = OpCompositeConstruct %v2float %23492 %14764 + %8431 = OpExtInst %uint %1 PackHalf2x16 %19214 + %15036 = OpCompositeConstruct %v4uint %8564 %8565 %8566 %8431 + %20158 = OpAccessChain %_ptr_Uniform_v4uint %5134 %int_0 %15532 + OpStore %20158 %15036 + OpBranch %19578 + %19578 = OpLabel + OpReturn + OpFunctionEnd +#endif + +const uint32_t texture_load_rgba16_unorm_float_scaled_cs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006243, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0006000F, 0x00000005, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000F48, 0x00060010, 0x0000161F, + 0x00000011, 0x00000004, 0x00000020, 0x00000001, 0x00030047, 0x00000489, 0x00000002, 0x00050048, + 0x00000489, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000489, 0x00000001, 0x00000023, + 0x00000004, 0x00050048, 0x00000489, 0x00000002, 0x00000023, 0x00000008, 0x00050048, 0x00000489, + 0x00000003, 0x00000023, 0x0000000C, 0x00050048, 0x00000489, 0x00000004, 0x00000023, 0x00000010, + 0x00050048, 0x00000489, 0x00000005, 0x00000023, 0x0000001C, 0x00050048, 0x00000489, 0x00000006, + 0x00000023, 0x00000020, 0x00050048, 0x00000489, 0x00000007, 0x00000023, 0x00000024, 0x00040047, + 0x00000F48, 0x0000000B, 0x0000001C, 0x00040047, 0x000007DC, 0x00000006, 0x00000010, 0x00030047, + 0x000007B4, 0x00000003, 0x00040048, 0x000007B4, 0x00000000, 0x00000018, 0x00050048, 0x000007B4, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000107A, 0x00000018, 0x00040047, 0x0000107A, + 0x00000021, 0x00000000, 0x00040047, 0x0000107A, 0x00000022, 0x00000001, 0x00040047, 0x000007DD, + 0x00000006, 0x00000010, 0x00030047, 0x000007B5, 0x00000003, 0x00040048, 0x000007B5, 0x00000000, + 0x00000019, 0x00050048, 0x000007B5, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x0000140E, + 0x00000019, 0x00040047, 0x0000140E, 0x00000021, 0x00000000, 0x00040047, 0x0000140E, 0x00000022, + 0x00000000, 0x00040047, 0x00000BC3, 0x0000000B, 0x00000019, 0x00020013, 0x00000008, 0x00030021, + 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, + 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000016, + 0x0000000C, 0x00000003, 0x00020014, 0x00000009, 0x00040017, 0x00000014, 0x0000000B, 0x00000003, + 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x0004002B, + 0x0000000B, 0x000001C1, 0x0000FFFF, 0x0004002B, 0x0000000D, 0x0000092A, 0x37800080, 0x0004002B, + 0x0000000B, 0x00000A3A, 0x00000010, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x00040017, + 0x00000013, 0x0000000D, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, + 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, + 0x0000000B, 0x000008A6, 0x00FF00FF, 0x0004002B, 0x0000000B, 0x00000A22, 0x00000008, 0x0004002B, + 0x0000000B, 0x000005FD, 0xFF00FF00, 0x0004002B, 0x0000000C, 0x00000A1A, 0x00000005, 0x0004002B, + 0x0000000B, 0x00000A19, 0x00000005, 0x0004002B, 0x0000000B, 0x00000A1F, 0x00000007, 0x0004002B, + 0x0000000C, 0x00000A20, 0x00000007, 0x0004002B, 0x0000000C, 0x00000A35, 0x0000000E, 0x0004002B, + 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000C, 0x000009DB, 0xFFFFFFF0, 0x0004002B, + 0x0000000C, 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A38, 0x0000000F, 0x0004002B, + 0x0000000C, 0x00000A17, 0x00000004, 0x0004002B, 0x0000000C, 0x0000040B, 0xFFFFFE00, 0x0004002B, + 0x0000000C, 0x00000A14, 0x00000003, 0x0004002B, 0x0000000C, 0x00000A3B, 0x00000010, 0x0004002B, + 0x0000000C, 0x00000388, 0x000001C0, 0x0004002B, 0x0000000C, 0x00000A23, 0x00000008, 0x0004002B, + 0x0000000C, 0x00000A1D, 0x00000006, 0x0004002B, 0x0000000C, 0x00000AC8, 0x0000003F, 0x0004002B, + 0x0000000B, 0x00000A16, 0x00000004, 0x0004002B, 0x0000000C, 0x0000078B, 0x0FFFFFFF, 0x0004002B, + 0x0000000C, 0x00000A05, 0xFFFFFFFE, 0x0004002B, 0x0000000B, 0x00000A6A, 0x00000020, 0x000A001E, + 0x00000489, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x00000014, 0x0000000B, 0x0000000B, + 0x0000000B, 0x00040020, 0x00000706, 0x00000009, 0x00000489, 0x0004003B, 0x00000706, 0x00000CE9, + 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000288, 0x00000009, + 0x0000000B, 0x0005002C, 0x00000011, 0x00000787, 0x00000A16, 0x00000A1F, 0x00040020, 0x00000291, + 0x00000009, 0x00000014, 0x00040020, 0x00000292, 0x00000001, 0x00000014, 0x0004003B, 0x00000292, + 0x00000F48, 0x00000001, 0x0006002C, 0x00000014, 0x00000A24, 0x00000A10, 0x00000A0A, 0x00000A0A, + 0x00040017, 0x0000000F, 0x00000009, 0x00000002, 0x0003001D, 0x000007DC, 0x00000017, 0x0003001E, + 0x000007B4, 0x000007DC, 0x00040020, 0x00000A31, 0x00000002, 0x000007B4, 0x0004003B, 0x00000A31, + 0x0000107A, 0x00000002, 0x00040020, 0x00000294, 0x00000002, 0x00000017, 0x0003001D, 0x000007DD, + 0x00000017, 0x0003001E, 0x000007B5, 0x000007DD, 0x00040020, 0x00000A32, 0x00000002, 0x000007B5, + 0x0004003B, 0x00000A32, 0x0000140E, 0x00000002, 0x0006002C, 0x00000014, 0x00000BC3, 0x00000A16, + 0x00000A6A, 0x00000A0D, 0x0005002C, 0x00000011, 0x000007A2, 0x00000A1F, 0x00000A1F, 0x0004002B, + 0x0000000B, 0x00000A25, 0x00000009, 0x0004002B, 0x0000000B, 0x00000A28, 0x0000000A, 0x0007002C, + 0x00000017, 0x000009CE, 0x000008A6, 0x000008A6, 0x000008A6, 0x000008A6, 0x0007002C, 0x00000017, + 0x0000013D, 0x00000A22, 0x00000A22, 0x00000A22, 0x00000A22, 0x0007002C, 0x00000017, 0x0000072E, + 0x000005FD, 0x000005FD, 0x000005FD, 0x000005FD, 0x0007002C, 0x00000017, 0x000002ED, 0x00000A3A, + 0x00000A3A, 0x00000A3A, 0x00000A3A, 0x0007002C, 0x00000017, 0x00000352, 0x000001C1, 0x000001C1, + 0x000001C1, 0x000001C1, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, + 0x00003B06, 0x000300F7, 0x00004C7A, 0x00000000, 0x000300FB, 0x00000A0A, 0x00002E68, 0x000200F8, + 0x00002E68, 0x00050041, 0x00000288, 0x000060D7, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x0000000B, + 0x00003526, 0x000060D7, 0x000500C7, 0x0000000B, 0x00005F7D, 0x00003526, 0x00000A10, 0x000500AB, + 0x00000009, 0x000048EB, 0x00005F7D, 0x00000A0A, 0x000500C2, 0x0000000B, 0x00001FCD, 0x00003526, + 0x00000A10, 0x000500C7, 0x0000000B, 0x0000619E, 0x00001FCD, 0x00000A13, 0x00050050, 0x00000011, + 0x000022A7, 0x00003526, 0x00003526, 0x000500C2, 0x00000011, 0x00001BAF, 0x000022A7, 0x00000787, + 0x000500C7, 0x00000011, 0x00001997, 0x00001BAF, 0x000007A2, 0x00050041, 0x00000288, 0x0000492C, + 0x00000CE9, 0x00000A0E, 0x0004003D, 0x0000000B, 0x00005EAC, 0x0000492C, 0x00050041, 0x00000288, + 0x00004EBA, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000B, 0x00005788, 0x00004EBA, 0x00050041, + 0x00000288, 0x00004EBB, 0x00000CE9, 0x00000A14, 0x0004003D, 0x0000000B, 0x00005789, 0x00004EBB, + 0x00050041, 0x00000291, 0x00004EBC, 0x00000CE9, 0x00000A17, 0x0004003D, 0x00000014, 0x0000578A, + 0x00004EBC, 0x00050041, 0x00000288, 0x00004EBD, 0x00000CE9, 0x00000A1A, 0x0004003D, 0x0000000B, + 0x0000578B, 0x00004EBD, 0x00050041, 0x00000288, 0x00004E6E, 0x00000CE9, 0x00000A1D, 0x0004003D, + 0x0000000B, 0x000019C2, 0x00004E6E, 0x0004003D, 0x00000014, 0x00002A0E, 0x00000F48, 0x000500C4, + 0x00000014, 0x0000538B, 0x00002A0E, 0x00000A24, 0x0007004F, 0x00000011, 0x000042F0, 0x0000538B, + 0x0000538B, 0x00000000, 0x00000001, 0x0007004F, 0x00000011, 0x0000242F, 0x0000578A, 0x0000578A, + 0x00000000, 0x00000001, 0x000500AE, 0x0000000F, 0x00004288, 0x000042F0, 0x0000242F, 0x0004009A, + 0x00000009, 0x00006067, 0x00004288, 0x000300F7, 0x000019BA, 0x00000002, 0x000400FA, 0x00006067, + 0x000055E8, 0x000019BA, 0x000200F8, 0x000055E8, 0x000200F9, 0x00004C7A, 0x000200F8, 0x000019BA, + 0x0004007C, 0x00000016, 0x00005BB6, 0x0000538B, 0x00050051, 0x0000000B, 0x00004916, 0x0000578A, + 0x00000001, 0x00050051, 0x0000000C, 0x00005BEB, 0x00005BB6, 0x00000000, 0x00050084, 0x0000000C, + 0x0000591A, 0x00005BEB, 0x00000A23, 0x00050051, 0x0000000C, 0x000018DA, 0x00005BB6, 0x00000002, + 0x0004007C, 0x0000000C, 0x000038A9, 0x00004916, 0x00050084, 0x0000000C, 0x00002C0F, 0x000018DA, + 0x000038A9, 0x00050051, 0x0000000C, 0x000044BE, 0x00005BB6, 0x00000001, 0x00050080, 0x0000000C, + 0x000056D4, 0x00002C0F, 0x000044BE, 0x0004007C, 0x0000000C, 0x00005785, 0x000019C2, 0x00050084, + 0x0000000C, 0x00005FD7, 0x000056D4, 0x00005785, 0x00050080, 0x0000000C, 0x00002042, 0x0000591A, + 0x00005FD7, 0x0004007C, 0x0000000B, 0x00002A92, 0x00002042, 0x00050080, 0x0000000B, 0x00001B12, + 0x00002A92, 0x0000578B, 0x000500C2, 0x0000000B, 0x00002BBD, 0x00001B12, 0x00000A16, 0x00050051, + 0x0000000B, 0x000029E2, 0x0000538B, 0x00000000, 0x000500C2, 0x0000000B, 0x00001DEE, 0x000029E2, + 0x00000A0D, 0x00050051, 0x0000000B, 0x00002704, 0x0000538B, 0x00000001, 0x00050050, 0x00000011, + 0x00005C0B, 0x00001DEE, 0x00002704, 0x00050086, 0x00000011, 0x00001F69, 0x00005C0B, 0x00001997, + 0x00050051, 0x0000000B, 0x0000366C, 0x00001F69, 0x00000000, 0x000500C4, 0x0000000B, 0x00004D4D, + 0x0000366C, 0x00000A0D, 0x00050051, 0x0000000B, 0x000051A9, 0x00001F69, 0x00000001, 0x00050051, + 0x0000000B, 0x000059EE, 0x0000538B, 0x00000002, 0x00060050, 0x00000014, 0x000024C9, 0x00004D4D, + 0x000051A9, 0x000059EE, 0x000300F7, 0x00005341, 0x00000002, 0x000400FA, 0x000048EB, 0x0000537D, + 0x00002DD9, 0x000200F8, 0x0000537D, 0x0004007C, 0x00000016, 0x00002970, 0x000024C9, 0x00050051, + 0x0000000C, 0x000042C2, 0x00002970, 0x00000001, 0x000500C3, 0x0000000C, 0x000024FD, 0x000042C2, + 0x00000A17, 0x00050051, 0x0000000C, 0x00002747, 0x00002970, 0x00000002, 0x000500C3, 0x0000000C, + 0x0000405C, 0x00002747, 0x00000A11, 0x000500C2, 0x0000000B, 0x00005B4D, 0x00005789, 0x00000A16, + 0x0004007C, 0x0000000C, 0x000018AA, 0x00005B4D, 0x00050084, 0x0000000C, 0x00005321, 0x0000405C, + 0x000018AA, 0x00050080, 0x0000000C, 0x00003B27, 0x000024FD, 0x00005321, 0x000500C2, 0x0000000B, + 0x00002348, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, 0x0000308B, 0x00002348, 0x00050084, + 0x0000000C, 0x00002878, 0x00003B27, 0x0000308B, 0x00050051, 0x0000000C, 0x00006242, 0x00002970, + 0x00000000, 0x000500C3, 0x0000000C, 0x00004FC7, 0x00006242, 0x00000A1A, 0x00050080, 0x0000000C, + 0x000049FC, 0x00004FC7, 0x00002878, 0x000500C4, 0x0000000C, 0x0000225D, 0x000049FC, 0x00000A25, + 0x000500C7, 0x0000000C, 0x00002CF6, 0x0000225D, 0x0000078B, 0x000500C4, 0x0000000C, 0x000049FA, + 0x00002CF6, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00004D38, 0x00006242, 0x00000A20, 0x000500C7, + 0x0000000C, 0x00003138, 0x000042C2, 0x00000A1D, 0x000500C4, 0x0000000C, 0x0000454D, 0x00003138, + 0x00000A11, 0x00050080, 0x0000000C, 0x0000434B, 0x00004D38, 0x0000454D, 0x000500C4, 0x0000000C, + 0x00001B88, 0x0000434B, 0x00000A25, 0x000500C3, 0x0000000C, 0x00005DE3, 0x00001B88, 0x00000A1D, + 0x000500C3, 0x0000000C, 0x00002215, 0x000042C2, 0x00000A14, 0x00050080, 0x0000000C, 0x000035A3, + 0x00002215, 0x0000405C, 0x000500C7, 0x0000000C, 0x00005A0C, 0x000035A3, 0x00000A0E, 0x000500C3, + 0x0000000C, 0x00004112, 0x00006242, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000496A, 0x00005A0C, + 0x00000A0E, 0x00050080, 0x0000000C, 0x000034BD, 0x00004112, 0x0000496A, 0x000500C7, 0x0000000C, + 0x00004ADD, 0x000034BD, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544A, 0x00004ADD, 0x00000A0E, + 0x00050080, 0x0000000C, 0x00003C4B, 0x00005A0C, 0x0000544A, 0x000500C7, 0x0000000C, 0x0000335E, + 0x00005DE3, 0x000009DB, 0x00050080, 0x0000000C, 0x00004F70, 0x000049FA, 0x0000335E, 0x000500C4, + 0x0000000C, 0x00005B31, 0x00004F70, 0x00000A0E, 0x000500C7, 0x0000000C, 0x00005AEA, 0x00005DE3, + 0x00000A38, 0x00050080, 0x0000000C, 0x0000285C, 0x00005B31, 0x00005AEA, 0x000500C7, 0x0000000C, + 0x000047B4, 0x00002747, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544B, 0x000047B4, 0x00000A25, + 0x00050080, 0x0000000C, 0x00004157, 0x0000285C, 0x0000544B, 0x000500C7, 0x0000000C, 0x00004ADE, + 0x000042C2, 0x00000A0E, 0x000500C4, 0x0000000C, 0x0000544C, 0x00004ADE, 0x00000A17, 0x00050080, + 0x0000000C, 0x00004158, 0x00004157, 0x0000544C, 0x000500C7, 0x0000000C, 0x00004FD6, 0x00003C4B, + 0x00000A0E, 0x000500C4, 0x0000000C, 0x00002703, 0x00004FD6, 0x00000A14, 0x000500C3, 0x0000000C, + 0x00003332, 0x00004158, 0x00000A1D, 0x000500C7, 0x0000000C, 0x000036D6, 0x00003332, 0x00000A20, + 0x00050080, 0x0000000C, 0x00003412, 0x00002703, 0x000036D6, 0x000500C4, 0x0000000C, 0x00005B32, + 0x00003412, 0x00000A14, 0x000500C7, 0x0000000C, 0x00005AB1, 0x00003C4B, 0x00000A05, 0x00050080, + 0x0000000C, 0x00002A9C, 0x00005B32, 0x00005AB1, 0x000500C4, 0x0000000C, 0x00005B33, 0x00002A9C, + 0x00000A11, 0x000500C7, 0x0000000C, 0x00005AB2, 0x00004158, 0x0000040B, 0x00050080, 0x0000000C, + 0x00002A9D, 0x00005B33, 0x00005AB2, 0x000500C4, 0x0000000C, 0x00005B34, 0x00002A9D, 0x00000A14, + 0x000500C7, 0x0000000C, 0x00005559, 0x00004158, 0x00000AC8, 0x00050080, 0x0000000C, 0x00005EFA, + 0x00005B34, 0x00005559, 0x0004007C, 0x0000000B, 0x0000566F, 0x00005EFA, 0x000200F9, 0x00005341, + 0x000200F8, 0x00002DD9, 0x0007004F, 0x00000011, 0x00002621, 0x000024C9, 0x000024C9, 0x00000000, + 0x00000001, 0x0004007C, 0x00000012, 0x000059CF, 0x00002621, 0x00050051, 0x0000000C, 0x00001903, + 0x000059CF, 0x00000000, 0x000500C3, 0x0000000C, 0x000024FE, 0x00001903, 0x00000A1A, 0x00050051, + 0x0000000C, 0x00002748, 0x000059CF, 0x00000001, 0x000500C3, 0x0000000C, 0x0000405D, 0x00002748, + 0x00000A1A, 0x000500C2, 0x0000000B, 0x00005B4E, 0x00005788, 0x00000A19, 0x0004007C, 0x0000000C, + 0x000018AB, 0x00005B4E, 0x00050084, 0x0000000C, 0x00005347, 0x0000405D, 0x000018AB, 0x00050080, + 0x0000000C, 0x00003F5E, 0x000024FE, 0x00005347, 0x000500C4, 0x0000000C, 0x00004A8E, 0x00003F5E, + 0x00000A28, 0x000500C7, 0x0000000C, 0x00002AB6, 0x00001903, 0x00000A20, 0x000500C7, 0x0000000C, + 0x00003139, 0x00002748, 0x00000A35, 0x000500C4, 0x0000000C, 0x0000454E, 0x00003139, 0x00000A11, + 0x00050080, 0x0000000C, 0x00004397, 0x00002AB6, 0x0000454E, 0x000500C4, 0x0000000C, 0x000018E7, + 0x00004397, 0x00000A13, 0x000500C7, 0x0000000C, 0x000027B1, 0x000018E7, 0x000009DB, 0x000500C4, + 0x0000000C, 0x00002F76, 0x000027B1, 0x00000A0E, 0x00050080, 0x0000000C, 0x00003C4C, 0x00004A8E, + 0x00002F76, 0x000500C7, 0x0000000C, 0x00003397, 0x000018E7, 0x00000A38, 0x00050080, 0x0000000C, + 0x00004D30, 0x00003C4C, 0x00003397, 0x000500C7, 0x0000000C, 0x000047B5, 0x00002748, 0x00000A0E, + 0x000500C4, 0x0000000C, 0x0000544D, 0x000047B5, 0x00000A17, 0x00050080, 0x0000000C, 0x00004159, + 0x00004D30, 0x0000544D, 0x000500C7, 0x0000000C, 0x00005022, 0x00004159, 0x0000040B, 0x000500C4, + 0x0000000C, 0x00002416, 0x00005022, 0x00000A14, 0x000500C7, 0x0000000C, 0x00004A33, 0x00002748, + 0x00000A3B, 0x000500C4, 0x0000000C, 0x00002F77, 0x00004A33, 0x00000A20, 0x00050080, 0x0000000C, + 0x0000415A, 0x00002416, 0x00002F77, 0x000500C7, 0x0000000C, 0x00004ADF, 0x00004159, 0x00000388, + 0x000500C4, 0x0000000C, 0x0000544E, 0x00004ADF, 0x00000A11, 0x00050080, 0x0000000C, 0x00004144, + 0x0000415A, 0x0000544E, 0x000500C7, 0x0000000C, 0x00005083, 0x00002748, 0x00000A23, 0x000500C3, + 0x0000000C, 0x000041BF, 0x00005083, 0x00000A11, 0x000500C3, 0x0000000C, 0x00001EEC, 0x00001903, + 0x00000A14, 0x00050080, 0x0000000C, 0x000035B6, 0x000041BF, 0x00001EEC, 0x000500C7, 0x0000000C, + 0x00005453, 0x000035B6, 0x00000A14, 0x000500C4, 0x0000000C, 0x0000544F, 0x00005453, 0x00000A1D, + 0x00050080, 0x0000000C, 0x00003C4D, 0x00004144, 0x0000544F, 0x000500C7, 0x0000000C, 0x00002E06, + 0x00004159, 0x00000AC8, 0x00050080, 0x0000000C, 0x0000394F, 0x00003C4D, 0x00002E06, 0x0004007C, + 0x0000000B, 0x00005670, 0x0000394F, 0x000200F9, 0x00005341, 0x000200F8, 0x00005341, 0x000700F5, + 0x0000000B, 0x000024FC, 0x0000566F, 0x0000537D, 0x00005670, 0x00002DD9, 0x00050084, 0x00000011, + 0x00003FA8, 0x00001F69, 0x00001997, 0x00050082, 0x00000011, 0x00003BBC, 0x00005C0B, 0x00003FA8, + 0x00050051, 0x0000000B, 0x00001C87, 0x00001997, 0x00000000, 0x00050051, 0x0000000B, 0x00005962, + 0x00001997, 0x00000001, 0x00050084, 0x0000000B, 0x00003372, 0x00001C87, 0x00005962, 0x00050084, + 0x0000000B, 0x00003CA0, 0x000024FC, 0x00003372, 0x00050051, 0x0000000B, 0x00003ED4, 0x00003BBC, + 0x00000000, 0x00050084, 0x0000000B, 0x00003E12, 0x00003ED4, 0x00005962, 0x00050051, 0x0000000B, + 0x00001AE6, 0x00003BBC, 0x00000001, 0x00050080, 0x0000000B, 0x00002B25, 0x00003E12, 0x00001AE6, + 0x000500C4, 0x0000000B, 0x0000609D, 0x00002B25, 0x00000A0D, 0x000500C7, 0x0000000B, 0x00005AB3, + 0x000029E2, 0x00000A0D, 0x00050080, 0x0000000B, 0x00002557, 0x0000609D, 0x00005AB3, 0x000500C4, + 0x0000000B, 0x000040AD, 0x00002557, 0x00000A13, 0x00050080, 0x0000000B, 0x00004EAA, 0x00003CA0, + 0x000040AD, 0x00050080, 0x0000000B, 0x00003BA9, 0x00005EAC, 0x00004EAA, 0x000500C2, 0x0000000B, + 0x00003948, 0x00003BA9, 0x00000A16, 0x00060041, 0x00000294, 0x00004FAF, 0x0000107A, 0x00000A0B, + 0x00003948, 0x0004003D, 0x00000017, 0x00001CAA, 0x00004FAF, 0x000500AA, 0x00000009, 0x000035C0, + 0x0000619E, 0x00000A0D, 0x000500AA, 0x00000009, 0x00005376, 0x0000619E, 0x00000A10, 0x000500A6, + 0x00000009, 0x00005686, 0x000035C0, 0x00005376, 0x000300F7, 0x00003463, 0x00000000, 0x000400FA, + 0x00005686, 0x00002957, 0x00003463, 0x000200F8, 0x00002957, 0x000500C7, 0x00000017, 0x0000475F, + 0x00001CAA, 0x000009CE, 0x000500C4, 0x00000017, 0x000024D1, 0x0000475F, 0x0000013D, 0x000500C7, + 0x00000017, 0x000050AC, 0x00001CAA, 0x0000072E, 0x000500C2, 0x00000017, 0x0000448D, 0x000050AC, + 0x0000013D, 0x000500C5, 0x00000017, 0x00003FF8, 0x000024D1, 0x0000448D, 0x000200F9, 0x00003463, + 0x000200F8, 0x00003463, 0x000700F5, 0x00000017, 0x00005879, 0x00001CAA, 0x00005341, 0x00003FF8, + 0x00002957, 0x000500AA, 0x00000009, 0x00004CB6, 0x0000619E, 0x00000A13, 0x000500A6, 0x00000009, + 0x00003B23, 0x00005376, 0x00004CB6, 0x000300F7, 0x0000368A, 0x00000000, 0x000400FA, 0x00003B23, + 0x00002B38, 0x0000368A, 0x000200F8, 0x00002B38, 0x000500C4, 0x00000017, 0x00005E17, 0x00005879, + 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE7, 0x00005879, 0x000002ED, 0x000500C5, 0x00000017, + 0x000029E8, 0x00005E17, 0x00003BE7, 0x000200F9, 0x0000368A, 0x000200F8, 0x0000368A, 0x000700F5, + 0x00000017, 0x000040DE, 0x00005879, 0x00003463, 0x000029E8, 0x00002B38, 0x000500C7, 0x00000017, + 0x00004740, 0x000040DE, 0x00000352, 0x00040070, 0x0000001D, 0x000023B1, 0x00004740, 0x0005008E, + 0x0000001D, 0x00004BA5, 0x000023B1, 0x0000092A, 0x000500C2, 0x00000017, 0x00005B47, 0x000040DE, + 0x000002ED, 0x00040070, 0x0000001D, 0x0000483C, 0x00005B47, 0x0005008E, 0x0000001D, 0x00004812, + 0x0000483C, 0x0000092A, 0x00050051, 0x0000000D, 0x0000187C, 0x00004BA5, 0x00000000, 0x00050051, + 0x0000000D, 0x000035EE, 0x00004812, 0x00000000, 0x00050050, 0x00000013, 0x00004B20, 0x0000187C, + 0x000035EE, 0x0006000C, 0x0000000B, 0x00002171, 0x00000001, 0x0000003A, 0x00004B20, 0x00050051, + 0x0000000D, 0x00005BBF, 0x00004BA5, 0x00000001, 0x00050051, 0x0000000D, 0x000039A7, 0x00004812, + 0x00000001, 0x00050050, 0x00000013, 0x00004B21, 0x00005BBF, 0x000039A7, 0x0006000C, 0x0000000B, + 0x00002172, 0x00000001, 0x0000003A, 0x00004B21, 0x00050051, 0x0000000D, 0x00005BC0, 0x00004BA5, + 0x00000002, 0x00050051, 0x0000000D, 0x000039A8, 0x00004812, 0x00000002, 0x00050050, 0x00000013, + 0x00004B22, 0x00005BC0, 0x000039A8, 0x0006000C, 0x0000000B, 0x00002173, 0x00000001, 0x0000003A, + 0x00004B22, 0x00050051, 0x0000000D, 0x00005BC1, 0x00004BA5, 0x00000003, 0x00050051, 0x0000000D, + 0x000039A9, 0x00004812, 0x00000003, 0x00050050, 0x00000013, 0x00004B0D, 0x00005BC1, 0x000039A9, + 0x0006000C, 0x0000000B, 0x000020EE, 0x00000001, 0x0000003A, 0x00004B0D, 0x00070050, 0x00000017, + 0x00003ABB, 0x00002171, 0x00002172, 0x00002173, 0x000020EE, 0x00060041, 0x00000294, 0x000045C3, + 0x0000140E, 0x00000A0B, 0x00002BBD, 0x0003003E, 0x000045C3, 0x00003ABB, 0x00050080, 0x0000000B, + 0x00003CAC, 0x00002BBD, 0x00000A0E, 0x000500AC, 0x00000009, 0x00001911, 0x00001C87, 0x00000A0D, + 0x000300F7, 0x000060BC, 0x00000002, 0x000400FA, 0x00001911, 0x00005084, 0x00005094, 0x000200F8, + 0x00005084, 0x00050086, 0x0000000B, 0x00003697, 0x00001DEE, 0x00001C87, 0x00050084, 0x0000000B, + 0x0000237E, 0x00003697, 0x00001C87, 0x00050082, 0x0000000B, 0x00003171, 0x00001DEE, 0x0000237E, + 0x00050080, 0x0000000B, 0x00002527, 0x00003171, 0x00000A0D, 0x000500AA, 0x00000009, 0x0000343F, + 0x00002527, 0x00001C87, 0x000300F7, 0x00001EED, 0x00000000, 0x000400FA, 0x0000343F, 0x0000569E, + 0x00002191, 0x000200F8, 0x0000569E, 0x00050084, 0x0000000B, 0x00004B59, 0x00000A6A, 0x00001C87, + 0x000500C4, 0x0000000B, 0x0000540F, 0x00003171, 0x00000A16, 0x00050082, 0x0000000B, 0x00004944, + 0x00004B59, 0x0000540F, 0x000200F9, 0x00001EED, 0x000200F8, 0x00002191, 0x000200F9, 0x00001EED, + 0x000200F8, 0x00001EED, 0x000700F5, 0x0000000B, 0x0000292C, 0x00004944, 0x0000569E, 0x00000A3A, + 0x00002191, 0x000200F9, 0x000060BC, 0x000200F8, 0x00005094, 0x000200F9, 0x000060BC, 0x000200F8, + 0x000060BC, 0x000700F5, 0x0000000B, 0x000029BC, 0x0000292C, 0x00001EED, 0x00000A6A, 0x00005094, + 0x00050084, 0x0000000B, 0x0000492B, 0x000029BC, 0x00005962, 0x000500C2, 0x0000000B, 0x0000406D, + 0x0000492B, 0x00000A16, 0x00050080, 0x0000000B, 0x0000336B, 0x00003948, 0x0000406D, 0x00060041, + 0x00000294, 0x0000571A, 0x0000107A, 0x00000A0B, 0x0000336B, 0x0004003D, 0x00000017, 0x000019B2, + 0x0000571A, 0x000300F7, 0x00003A1A, 0x00000000, 0x000400FA, 0x00005686, 0x00002958, 0x00003A1A, + 0x000200F8, 0x00002958, 0x000500C7, 0x00000017, 0x00004760, 0x000019B2, 0x000009CE, 0x000500C4, + 0x00000017, 0x000024D2, 0x00004760, 0x0000013D, 0x000500C7, 0x00000017, 0x000050AD, 0x000019B2, + 0x0000072E, 0x000500C2, 0x00000017, 0x0000448E, 0x000050AD, 0x0000013D, 0x000500C5, 0x00000017, + 0x00003FF9, 0x000024D2, 0x0000448E, 0x000200F9, 0x00003A1A, 0x000200F8, 0x00003A1A, 0x000700F5, + 0x00000017, 0x00002AAC, 0x000019B2, 0x000060BC, 0x00003FF9, 0x00002958, 0x000300F7, 0x0000368B, + 0x00000000, 0x000400FA, 0x00003B23, 0x00002B39, 0x0000368B, 0x000200F8, 0x00002B39, 0x000500C4, + 0x00000017, 0x00005E18, 0x00002AAC, 0x000002ED, 0x000500C2, 0x00000017, 0x00003BE8, 0x00002AAC, + 0x000002ED, 0x000500C5, 0x00000017, 0x000029E9, 0x00005E18, 0x00003BE8, 0x000200F9, 0x0000368B, + 0x000200F8, 0x0000368B, 0x000700F5, 0x00000017, 0x000040DF, 0x00002AAC, 0x00003A1A, 0x000029E9, + 0x00002B39, 0x000500C7, 0x00000017, 0x00004741, 0x000040DF, 0x00000352, 0x00040070, 0x0000001D, + 0x000023B2, 0x00004741, 0x0005008E, 0x0000001D, 0x00004BA6, 0x000023B2, 0x0000092A, 0x000500C2, + 0x00000017, 0x00005B48, 0x000040DF, 0x000002ED, 0x00040070, 0x0000001D, 0x0000483D, 0x00005B48, + 0x0005008E, 0x0000001D, 0x00004813, 0x0000483D, 0x0000092A, 0x00050051, 0x0000000D, 0x0000187D, + 0x00004BA6, 0x00000000, 0x00050051, 0x0000000D, 0x000035EF, 0x00004813, 0x00000000, 0x00050050, + 0x00000013, 0x00004B23, 0x0000187D, 0x000035EF, 0x0006000C, 0x0000000B, 0x00002174, 0x00000001, + 0x0000003A, 0x00004B23, 0x00050051, 0x0000000D, 0x00005BC2, 0x00004BA6, 0x00000001, 0x00050051, + 0x0000000D, 0x000039AA, 0x00004813, 0x00000001, 0x00050050, 0x00000013, 0x00004B24, 0x00005BC2, + 0x000039AA, 0x0006000C, 0x0000000B, 0x00002175, 0x00000001, 0x0000003A, 0x00004B24, 0x00050051, + 0x0000000D, 0x00005BC3, 0x00004BA6, 0x00000002, 0x00050051, 0x0000000D, 0x000039AB, 0x00004813, + 0x00000002, 0x00050050, 0x00000013, 0x00004B25, 0x00005BC3, 0x000039AB, 0x0006000C, 0x0000000B, + 0x00002176, 0x00000001, 0x0000003A, 0x00004B25, 0x00050051, 0x0000000D, 0x00005BC4, 0x00004BA6, + 0x00000003, 0x00050051, 0x0000000D, 0x000039AC, 0x00004813, 0x00000003, 0x00050050, 0x00000013, + 0x00004B0E, 0x00005BC4, 0x000039AC, 0x0006000C, 0x0000000B, 0x000020EF, 0x00000001, 0x0000003A, + 0x00004B0E, 0x00070050, 0x00000017, 0x00003ABC, 0x00002174, 0x00002175, 0x00002176, 0x000020EF, + 0x00060041, 0x00000294, 0x00004EBE, 0x0000140E, 0x00000A0B, 0x00003CAC, 0x0003003E, 0x00004EBE, + 0x00003ABC, 0x000200F9, 0x00004C7A, 0x000200F8, 0x00004C7A, 0x000100FD, 0x00010038, +}; diff --git a/src/graphics/shared_memory.cpp b/src/graphics/shared_memory.cpp new file mode 100644 index 0000000..333becb --- /dev/null +++ b/src/graphics/shared_memory.cpp @@ -0,0 +1,785 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace rex::graphics { + +SharedMemory::SharedMemory(memory::Memory& memory) : memory_(memory) { + page_size_log2_ = rex::log2_ceil(uint32_t(rex::memory::page_size())); +} + +SharedMemory::~SharedMemory() { + ShutdownCommon(); +} + +void SharedMemory::InitializeCommon() { + num_system_page_flags_ = ((kBufferSize >> page_size_log2_) + 63) / 64; + valid_buffer_a_.assign(num_system_page_flags_, 0); + valid_buffer_b_.assign(num_system_page_flags_, 0); + system_page_flags_valid_and_gpu_written_.assign(num_system_page_flags_, 0); + active_valid_flags_.store(valid_buffer_a_.data(), std::memory_order_relaxed); + staging_valid_flags_.store(valid_buffer_b_.data(), std::memory_order_relaxed); + gpu_written_data_dirty_.store(false, std::memory_order_relaxed); + dirty_blocks_.store(0, std::memory_order_relaxed); + + memory_invalidation_callback_handle_ = + memory_.RegisterPhysicalMemoryInvalidationCallback(MemoryInvalidationCallbackThunk, this); +} + +void SharedMemory::InitializeSparseHostGpuMemory(uint32_t granularity_log2) { + assert_true(granularity_log2 <= kBufferSizeLog2); + assert_true(host_gpu_memory_sparse_granularity_log2_ == UINT32_MAX); + host_gpu_memory_sparse_granularity_log2_ = granularity_log2; + host_gpu_memory_sparse_allocated_.resize( + size_t(1) << (std::max(kBufferSizeLog2 - granularity_log2, uint32_t(6)) - 6)); +} + +void SharedMemory::ShutdownCommon() { + ReleaseTraceDownloadRanges(); + + FireWatches(0, (kBufferSize - 1) >> page_size_log2_, false); + assert_true(global_watches_.empty()); + // No watches now, so no references to the pools accessible by guest threads - + // safe not to enter the global critical region. + watch_node_first_free_ = nullptr; + watch_node_current_pool_allocated_ = 0; + for (WatchNode* pool : watch_node_pools_) { + delete[] pool; + } + watch_node_pools_.clear(); + watch_range_first_free_ = nullptr; + watch_range_current_pool_allocated_ = 0; + for (WatchRange* pool : watch_range_pools_) { + delete[] pool; + } + watch_range_pools_.clear(); + + if (memory_invalidation_callback_handle_ != nullptr) { + memory_.UnregisterPhysicalMemoryInvalidationCallback(memory_invalidation_callback_handle_); + memory_invalidation_callback_handle_ = nullptr; + } + + if (host_gpu_memory_sparse_used_bytes_) { + host_gpu_memory_sparse_used_bytes_ = 0; + COUNT_profile_set("gpu/shared_memory/host_gpu_memory_sparse_used_mb", 0); + } + if (host_gpu_memory_sparse_allocations_) { + host_gpu_memory_sparse_allocations_ = 0; + COUNT_profile_set("gpu/shared_memory/host_gpu_memory_sparse_allocations", 0); + } + host_gpu_memory_sparse_allocated_.clear(); + host_gpu_memory_sparse_allocated_.shrink_to_fit(); + host_gpu_memory_sparse_granularity_log2_ = UINT32_MAX; + + active_valid_flags_.store(nullptr, std::memory_order_relaxed); + staging_valid_flags_.store(nullptr, std::memory_order_relaxed); + valid_buffer_a_.clear(); + valid_buffer_a_.shrink_to_fit(); + valid_buffer_b_.clear(); + valid_buffer_b_.shrink_to_fit(); + system_page_flags_valid_and_gpu_written_.clear(); + system_page_flags_valid_and_gpu_written_.shrink_to_fit(); + num_system_page_flags_ = 0; + gpu_written_data_dirty_.store(false, std::memory_order_relaxed); + dirty_blocks_.store(0, std::memory_order_relaxed); +} + +void SharedMemory::InvalidateAllPages() { + auto global_lock = global_critical_region_.Acquire(); + + uint64_t* active = active_valid_flags_.load(std::memory_order_relaxed); + uint64_t* staging = staging_valid_flags_.load(std::memory_order_relaxed); + if (active && num_system_page_flags_) { + std::memset(active, 0, num_system_page_flags_ * sizeof(uint64_t)); + } + if (staging && num_system_page_flags_) { + std::memset(staging, 0, num_system_page_flags_ * sizeof(uint64_t)); + } + if (!system_page_flags_valid_and_gpu_written_.empty()) { + std::memset(system_page_flags_valid_and_gpu_written_.data(), 0, + num_system_page_flags_ * sizeof(uint64_t)); + } + + // Force a refresh on the next frame-end sync. + dirty_blocks_.store(UINT32_MAX, std::memory_order_relaxed); + gpu_written_data_dirty_.store(true, std::memory_order_relaxed); +} + +void SharedMemory::SetSystemPageBlocksValidWithGpuDataWritten() { + if (!gpu_written_data_dirty_.load(std::memory_order_relaxed)) { + return; + } + + uint64_t* staging = staging_valid_flags_.load(std::memory_order_acquire); + if (!staging || !num_system_page_flags_) { + gpu_written_data_dirty_.store(false, std::memory_order_relaxed); + dirty_blocks_.store(0, std::memory_order_relaxed); + return; + } + + uint32_t dirty_mask = dirty_blocks_.exchange(0, std::memory_order_relaxed); + uint32_t dirty_count = rex::bit_count(dirty_mask); + if (dirty_count == 0 || dirty_count > 16) { + std::memcpy(staging, system_page_flags_valid_and_gpu_written_.data(), + num_system_page_flags_ * sizeof(uint64_t)); + } else { + while (dirty_mask) { + uint32_t block_index; + rex::bit_scan_forward(dirty_mask, &block_index); + dirty_mask &= ~(uint32_t(1) << block_index); + uint32_t entry_offset = block_index * 64; + if (entry_offset >= num_system_page_flags_) { + continue; + } + uint32_t entry_count = std::min(uint32_t(64), num_system_page_flags_ - entry_offset); + std::memcpy(staging + entry_offset, + system_page_flags_valid_and_gpu_written_.data() + entry_offset, + entry_count * sizeof(uint64_t)); + } + } + + uint64_t* old_active = active_valid_flags_.exchange(staging, std::memory_order_acq_rel); + staging_valid_flags_.store(old_active, std::memory_order_release); + gpu_written_data_dirty_.store(false, std::memory_order_relaxed); +} + +void SharedMemory::ClearCache() { + // Keeping GPU-written data, so "invalidated by GPU". + FireWatches(0, (kBufferSize - 1) >> page_size_log2_, true); + // No watches now, so no references to the pools accessible by guest threads - + // safe not to enter the global critical region. + watch_node_first_free_ = nullptr; + watch_node_current_pool_allocated_ = 0; + for (WatchNode* pool : watch_node_pools_) { + delete[] pool; + } + watch_node_pools_.clear(); + watch_range_first_free_ = nullptr; + watch_range_current_pool_allocated_ = 0; + for (WatchRange* pool : watch_range_pools_) { + delete[] pool; + } + watch_range_pools_.clear(); + SetSystemPageBlocksValidWithGpuDataWritten(); +} + +SharedMemory::GlobalWatchHandle SharedMemory::RegisterGlobalWatch(GlobalWatchCallback callback, + void* callback_context) { + GlobalWatch* watch = new GlobalWatch; + watch->callback = callback; + watch->callback_context = callback_context; + + auto global_lock = global_critical_region_.Acquire(); + global_watches_.push_back(watch); + + return reinterpret_cast(watch); +} + +void SharedMemory::UnregisterGlobalWatch(GlobalWatchHandle handle) { + auto watch = reinterpret_cast(handle); + + { + auto global_lock = global_critical_region_.Acquire(); + auto it = std::find(global_watches_.begin(), global_watches_.end(), watch); + assert_false(it == global_watches_.end()); + if (it != global_watches_.end()) { + global_watches_.erase(it); + } + } + + delete watch; +} + +SharedMemory::WatchHandle SharedMemory::WatchMemoryRange(uint32_t start, uint32_t length, + WatchCallback callback, + void* callback_context, + void* callback_data, + uint64_t callback_argument) { + if (length == 0 || start >= kBufferSize) { + return nullptr; + } + length = std::min(length, kBufferSize - start); + uint32_t watch_page_first = start >> page_size_log2_; + uint32_t watch_page_last = (start + length - 1) >> page_size_log2_; + uint32_t bucket_first = watch_page_first << page_size_log2_ >> kWatchBucketSizeLog2; + uint32_t bucket_last = watch_page_last << page_size_log2_ >> kWatchBucketSizeLog2; + + auto global_lock = global_critical_region_.Acquire(); + + // Allocate the range. + WatchRange* range = watch_range_first_free_; + if (range != nullptr) { + watch_range_first_free_ = range->next_free; + } else { + if (watch_range_pools_.empty() || watch_range_current_pool_allocated_ >= kWatchRangePoolSize) { + watch_range_pools_.push_back(new WatchRange[kWatchRangePoolSize]); + watch_range_current_pool_allocated_ = 0; + } + range = &(watch_range_pools_.back()[watch_range_current_pool_allocated_++]); + } + range->callback = callback; + range->callback_context = callback_context; + range->callback_data = callback_data; + range->callback_argument = callback_argument; + range->page_first = watch_page_first; + range->page_last = watch_page_last; + + // Allocate and link the nodes. + WatchNode* node_previous = nullptr; + for (uint32_t i = bucket_first; i <= bucket_last; ++i) { + WatchNode* node = watch_node_first_free_; + if (node != nullptr) { + watch_node_first_free_ = node->next_free; + } else { + if (watch_node_pools_.empty() || watch_node_current_pool_allocated_ >= kWatchNodePoolSize) { + watch_node_pools_.push_back(new WatchNode[kWatchNodePoolSize]); + watch_node_current_pool_allocated_ = 0; + } + node = &(watch_node_pools_.back()[watch_node_current_pool_allocated_++]); + } + node->range = range; + node->range_node_next = nullptr; + if (node_previous != nullptr) { + node_previous->range_node_next = node; + } else { + range->node_first = node; + } + node_previous = node; + node->bucket_node_previous = nullptr; + node->bucket_node_next = watch_buckets_[i]; + if (watch_buckets_[i] != nullptr) { + watch_buckets_[i]->bucket_node_previous = node; + } + watch_buckets_[i] = node; + } + + return reinterpret_cast(range); +} + +void SharedMemory::UnwatchMemoryRange(WatchHandle handle) { + auto global_lock = global_critical_region_.Acquire(); + UnlinkWatchRange(reinterpret_cast(handle)); +} + +void SharedMemory::FireWatches(uint32_t page_first, uint32_t page_last, bool invalidated_by_gpu) { + uint32_t address_first = page_first << page_size_log2_; + uint32_t address_last = (page_last << page_size_log2_) + ((1 << page_size_log2_) - 1); + uint32_t bucket_first = address_first >> kWatchBucketSizeLog2; + uint32_t bucket_last = address_last >> kWatchBucketSizeLog2; + + auto global_lock = global_critical_region_.Acquire(); + + // Fire global watches. + for (const auto global_watch : global_watches_) { + global_watch->callback(global_lock, global_watch->callback_context, address_first, address_last, + invalidated_by_gpu); + } + + // Fire per-range watches. + for (uint32_t i = bucket_first; i <= bucket_last; ++i) { + WatchNode* node = watch_buckets_[i]; + while (node != nullptr) { + WatchRange* range = node->range; + // Store the next node now since when the callback is triggered, the links + // will be broken. + node = node->bucket_node_next; + if (page_first <= range->page_last && page_last >= range->page_first) { + range->callback(global_lock, range->callback_context, range->callback_data, + range->callback_argument, invalidated_by_gpu); + UnlinkWatchRange(range); + } + } + } +} + +void SharedMemory::RangeWrittenByGpu(uint32_t start, uint32_t length) { + if (length == 0 || start >= kBufferSize) { + return; + } + length = std::min(length, kBufferSize - start); + uint32_t end = start + length - 1; + uint32_t page_first = start >> page_size_log2_; + uint32_t page_last = end >> page_size_log2_; + + // Trigger modification callbacks so, for instance, resolved data is loaded to + // the texture. + FireWatches(page_first, page_last, true); + + // Mark the range as valid (so pages are not reuploaded until modified by the + // CPU) and watch it so the CPU can reuse it and this will be caught. + MakeRangeValid(start, length, true); +} + +bool SharedMemory::AllocateSparseHostGpuMemoryRange(uint32_t offset_allocations, + uint32_t length_allocations) { + assert_always( + "Sparse host GPU memory allocation has been initialized, but the " + "implementation doesn't provide AllocateSparseHostGpuMemoryRange"); + return false; +} + +void SharedMemory::MakeRangeValid(uint32_t start, uint32_t length, bool written_by_gpu) { + if (length == 0 || start >= kBufferSize) { + return; + } + length = std::min(length, kBufferSize - start); + uint32_t last = start + length - 1; + uint32_t valid_page_first = start >> page_size_log2_; + uint32_t valid_page_last = last >> page_size_log2_; + uint32_t valid_block_first = valid_page_first >> 6; + uint32_t valid_block_last = valid_page_last >> 6; + + { + auto global_lock = global_critical_region_.Acquire(); + uint64_t* valid_flags = active_valid_flags_.load(std::memory_order_relaxed); + + for (uint32_t i = valid_block_first; i <= valid_block_last; ++i) { + uint64_t valid_bits = UINT64_MAX; + if (i == valid_block_first) { + valid_bits &= ~((uint64_t(1) << (valid_page_first & 63)) - 1); + } + if (i == valid_block_last && (valid_page_last & 63) != 63) { + valid_bits &= (uint64_t(1) << ((valid_page_last & 63) + 1)) - 1; + } + if (valid_flags) { + valid_flags[i] |= valid_bits; + } + uint64_t old_gpu_written = system_page_flags_valid_and_gpu_written_[i]; + uint64_t new_gpu_written = + written_by_gpu ? (old_gpu_written | valid_bits) : (old_gpu_written & ~valid_bits); + if (new_gpu_written != old_gpu_written) { + system_page_flags_valid_and_gpu_written_[i] = new_gpu_written; + gpu_written_data_dirty_.store(true, std::memory_order_relaxed); + dirty_blocks_.fetch_or(uint32_t(1) << (i >> 6), std::memory_order_relaxed); + } + } + } + + if (memory_invalidation_callback_handle_) { + memory().EnablePhysicalMemoryAccessCallbacks( + valid_page_first << page_size_log2_, + (valid_page_last - valid_page_first + 1) << page_size_log2_, true, false); + } +} + +void SharedMemory::UnlinkWatchRange(WatchRange* range) { + uint32_t bucket = range->page_first << page_size_log2_ >> kWatchBucketSizeLog2; + WatchNode* node = range->node_first; + while (node != nullptr) { + WatchNode* node_next = node->range_node_next; + if (node->bucket_node_previous != nullptr) { + node->bucket_node_previous->bucket_node_next = node->bucket_node_next; + } else { + watch_buckets_[bucket] = node->bucket_node_next; + } + if (node->bucket_node_next != nullptr) { + node->bucket_node_next->bucket_node_previous = node->bucket_node_previous; + } + node->next_free = watch_node_first_free_; + watch_node_first_free_ = node; + node = node_next; + ++bucket; + } + range->next_free = watch_range_first_free_; + watch_range_first_free_ = range; +} + +bool SharedMemory::RequestRanges(const std::pair* ranges, size_t count) { + if (ranges == nullptr || !count) { + return true; + } + + // Some texture or buffer is empty, for example - safe to draw in this case. + std::vector> merged_ranges; + merged_ranges.reserve(count); + for (size_t i = 0; i < count; ++i) { + uint32_t start = ranges[i].first; + uint32_t length = ranges[i].second; + if (!length) { + continue; + } + if (start > kBufferSize || (kBufferSize - start) < length) { + return false; + } + merged_ranges.emplace_back(start, length); + } + if (merged_ranges.empty()) { + return true; + } + + SCOPE_profile_cpu_f("gpu"); + + std::sort(merged_ranges.begin(), merged_ranges.end(), + [](const std::pair& a, const std::pair& b) { + return a.first < b.first; + }); + size_t merged_write = 0; + for (size_t i = 1; i < merged_ranges.size(); ++i) { + std::pair& range_previous = merged_ranges[merged_write]; + const std::pair& range_current = merged_ranges[i]; + uint64_t previous_end = uint64_t(range_previous.first) + uint64_t(range_previous.second); + uint64_t current_start = uint64_t(range_current.first); + if (current_start <= previous_end) { + uint64_t current_end = current_start + uint64_t(range_current.second); + if (current_end > previous_end) { + range_previous.second = uint32_t(current_end - uint64_t(range_previous.first)); + } + } else { + merged_ranges[++merged_write] = range_current; + } + } + merged_ranges.resize(merged_write + 1); + + for (const std::pair& range : merged_ranges) { + if (!EnsureHostGpuMemoryAllocated(range.first, range.second)) { + return false; + } + } + + uint64_t* valid_flags = active_valid_flags_.load(std::memory_order_acquire); + if (valid_flags) { + bool all_valid = true; + for (const std::pair& range : merged_ranges) { + if (!range.second) { + continue; + } + uint32_t page_first = range.first >> page_size_log2_; + uint32_t page_last = (range.first + range.second - 1) >> page_size_log2_; + uint32_t block_first = page_first >> 6; + uint32_t block_last = page_last >> 6; + for (uint32_t i = block_first; i <= block_last; ++i) { + uint64_t block_valid = valid_flags[i]; + if (i == block_first) { + uint64_t block_before = (uint64_t(1) << (page_first & 63)) - 1; + block_valid |= block_before; + } + if (i == block_last && (page_last & 63) != 63) { + uint64_t block_inside = (uint64_t(1) << ((page_last & 63) + 1)) - 1; + block_valid |= ~block_inside; + } + if (block_valid != UINT64_MAX) { + all_valid = false; + break; + } + } + if (!all_valid) { + break; + } + } + if (all_valid) { + COUNT_profile_set("gpu/shared_memory/request_ranges_count", uint32_t(count)); + COUNT_profile_set("gpu/shared_memory/request_ranges_merged_count", + uint32_t(merged_ranges.size())); + COUNT_profile_set("gpu/shared_memory/request_ranges_upload_count", 0); + return true; + } + } + + upload_ranges_.clear(); + auto append_upload_range = [this](uint32_t page_start, uint32_t page_count) { + if (!page_count) { + return; + } + if (!upload_ranges_.empty()) { + std::pair& last_upload_range = upload_ranges_.back(); + if (last_upload_range.first + last_upload_range.second == page_start) { + last_upload_range.second += page_count; + return; + } + } + upload_ranges_.emplace_back(page_start, page_count); + }; + { + auto global_lock = global_critical_region_.Acquire(); + valid_flags = active_valid_flags_.load(std::memory_order_relaxed); + for (const std::pair& range : merged_ranges) { + uint32_t page_first = range.first >> page_size_log2_; + uint32_t page_last = (range.first + range.second - 1) >> page_size_log2_; + uint32_t block_first = page_first >> 6; + uint32_t block_last = page_last >> 6; + uint32_t range_start = UINT32_MAX; + for (uint32_t i = block_first; i <= block_last; ++i) { + uint64_t block_valid = valid_flags ? valid_flags[i] : 0; + // Consider pages in the block outside the requested range valid. + if (i == block_first) { + uint64_t block_before = (uint64_t(1) << (page_first & 63)) - 1; + block_valid |= block_before; + } + if (i == block_last && (page_last & 63) != 63) { + uint64_t block_inside = (uint64_t(1) << ((page_last & 63) + 1)) - 1; + block_valid |= ~block_inside; + } + + while (true) { + uint32_t block_page; + if (range_start == UINT32_MAX) { + // Check if need to open a new range. + if (!rex::bit_scan_forward(~block_valid, &block_page)) { + break; + } + range_start = (i << 6) + block_page; + } else { + // Check if need to close the range. + // Ignore the valid pages before the beginning of the range. + uint64_t block_valid_from_start = block_valid; + if (i == (range_start >> 6)) { + block_valid_from_start &= ~((uint64_t(1) << (range_start & 63)) - 1); + } + if (!rex::bit_scan_forward(block_valid_from_start, &block_page)) { + break; + } + append_upload_range(range_start, (i << 6) + block_page - range_start); + // In the next iteration within this block, consider this range + // valid since it has been queued for upload. + block_valid |= (uint64_t(1) << block_page) - 1; + range_start = UINT32_MAX; + } + } + } + if (range_start != UINT32_MAX) { + append_upload_range(range_start, page_last + 1 - range_start); + } + } + } + + COUNT_profile_set("gpu/shared_memory/request_ranges_count", uint32_t(count)); + COUNT_profile_set("gpu/shared_memory/request_ranges_merged_count", + uint32_t(merged_ranges.size())); + COUNT_profile_set("gpu/shared_memory/request_ranges_upload_count", + uint32_t(upload_ranges_.size())); + + if (upload_ranges_.empty()) { + return true; + } + + return UploadRanges(upload_ranges_); +} + +bool SharedMemory::RequestRange(uint32_t start, uint32_t length) { + std::pair range(start, length); + return RequestRanges(&range, 1); +} + +std::pair SharedMemory::MemoryInvalidationCallbackThunk( + void* context_ptr, uint32_t physical_address_start, uint32_t length, bool exact_range) { + return reinterpret_cast(context_ptr) + ->MemoryInvalidationCallback(physical_address_start, length, exact_range); +} + +std::pair SharedMemory::MemoryInvalidationCallback( + uint32_t physical_address_start, uint32_t length, bool exact_range) { + if (length == 0 || physical_address_start >= kBufferSize) { + return std::make_pair(uint32_t(0), UINT32_MAX); + } + length = std::min(length, kBufferSize - physical_address_start); + uint32_t physical_address_last = physical_address_start + (length - 1); + + uint32_t page_first = physical_address_start >> page_size_log2_; + uint32_t page_last = physical_address_last >> page_size_log2_; + uint32_t block_first = page_first >> 6; + uint32_t block_last = page_last >> 6; + + auto global_lock = global_critical_region_.Acquire(); + + if (!exact_range) { + // Check if a somewhat wider range (up to 256 KB with 4 KB pages) can be + // invalidated - if no GPU-written data nearby that was not intended to be + // invalidated since it's not in sync with CPU memory and can't be + // reuploaded. It's a lot cheaper to upload some excess data than to catch + // access violations - with 4 KB callbacks, 58410824 (being a + // software-rendered game) runs at 4 FPS on Intel Core i7-3770, with 64 KB, + // the CPU game code takes 3 ms to run per frame, but with 256 KB, it's + // 0.7 ms. + if (page_first & 63) { + uint64_t gpu_written_start = system_page_flags_valid_and_gpu_written_[block_first]; + gpu_written_start &= (uint64_t(1) << (page_first & 63)) - 1; + page_first = (page_first & ~uint32_t(63)) + (64 - rex::lzcnt(gpu_written_start)); + } + if ((page_last & 63) != 63) { + uint64_t gpu_written_end = system_page_flags_valid_and_gpu_written_[block_last]; + gpu_written_end &= ~((uint64_t(1) << ((page_last & 63) + 1)) - 1); + page_last = + (page_last & ~uint32_t(63)) + (std::max(rex::tzcnt(gpu_written_end), uint8_t(1)) - 1); + } + } + + uint32_t dirty_blocks_mask = 0; + uint64_t* valid_flags = active_valid_flags_.load(std::memory_order_relaxed); + for (uint32_t i = block_first; i <= block_last; ++i) { + uint64_t invalidate_bits = UINT64_MAX; + if (i == block_first) { + invalidate_bits &= ~((uint64_t(1) << (page_first & 63)) - 1); + } + if (i == block_last && (page_last & 63) != 63) { + invalidate_bits &= (uint64_t(1) << ((page_last & 63) + 1)) - 1; + } + if (valid_flags) { + valid_flags[i] &= ~invalidate_bits; + } + system_page_flags_valid_and_gpu_written_[i] &= ~invalidate_bits; + dirty_blocks_mask |= uint32_t(1) << (i >> 6); + } + gpu_written_data_dirty_.store(true, std::memory_order_relaxed); + dirty_blocks_.fetch_or(dirty_blocks_mask, std::memory_order_relaxed); + + FireWatches(page_first, page_last, false); + + return std::make_pair(page_first << page_size_log2_, (page_last - page_first + 1) + << page_size_log2_); +} + +void SharedMemory::PrepareForTraceDownload() { + ReleaseTraceDownloadRanges(); + assert_true(trace_download_ranges_.empty()); + assert_zero(trace_download_page_count_); + + // Invalidate the entire memory CPU->GPU memory copy so all the history + // doesn't have to be written into every frame trace, and collect the list of + // ranges with data modified on the GPU. + + uint32_t fire_watches_range_start = UINT32_MAX; + uint32_t gpu_written_range_start = UINT32_MAX; + auto global_lock = global_critical_region_.Acquire(); + uint64_t* valid_flags = active_valid_flags_.load(std::memory_order_relaxed); + for (uint32_t i = 0; i < num_system_page_flags_; ++i) { + uint64_t previously_valid_block = valid_flags ? valid_flags[i] : 0; + uint64_t gpu_written_block = system_page_flags_valid_and_gpu_written_[i]; + if (valid_flags) { + valid_flags[i] = gpu_written_block; + } + + // Fire watches on the invalidated pages. + uint64_t fire_watches_block = previously_valid_block & ~gpu_written_block; + uint64_t fire_watches_break_block = ~fire_watches_block; + while (true) { + uint32_t fire_watches_block_page; + if (!rex::bit_scan_forward(fire_watches_range_start == UINT32_MAX ? fire_watches_block + : fire_watches_break_block, + &fire_watches_block_page)) { + break; + } + uint32_t fire_watches_page = (i << 6) + fire_watches_block_page; + if (fire_watches_range_start == UINT32_MAX) { + fire_watches_range_start = fire_watches_page; + } else { + FireWatches(fire_watches_range_start, fire_watches_page - 1, false); + fire_watches_range_start = UINT32_MAX; + } + uint64_t fire_watches_block_mask = ~((uint64_t(1) << fire_watches_block_page) - 1); + fire_watches_block &= fire_watches_block_mask; + fire_watches_break_block &= fire_watches_block_mask; + } + + // Add to the GPU-written ranges. + uint64_t gpu_written_break_block = ~gpu_written_block; + while (true) { + uint32_t gpu_written_block_page; + if (!rex::bit_scan_forward( + gpu_written_range_start == UINT32_MAX ? gpu_written_block : gpu_written_break_block, + &gpu_written_block_page)) { + break; + } + uint32_t gpu_written_page = (i << 6) + gpu_written_block_page; + if (gpu_written_range_start == UINT32_MAX) { + gpu_written_range_start = gpu_written_page; + } else { + uint32_t gpu_written_range_length = gpu_written_page - gpu_written_range_start; + // Call EnsureHostGpuMemoryAllocated in case the page was marked as + // GPU-written not as a result to an actual write to the shared memory + // buffer, but, for instance, by resolving with resolution scaling (to a + // separate buffer). + if (EnsureHostGpuMemoryAllocated(gpu_written_range_start << page_size_log2_, + gpu_written_range_length << page_size_log2_)) { + trace_download_ranges_.push_back( + std::make_pair(gpu_written_range_start << page_size_log2_, + gpu_written_range_length << page_size_log2_)); + trace_download_page_count_ += gpu_written_range_length; + } + gpu_written_range_start = UINT32_MAX; + } + uint64_t gpu_written_block_mask = ~((uint64_t(1) << gpu_written_block_page) - 1); + gpu_written_block &= gpu_written_block_mask; + gpu_written_break_block &= gpu_written_block_mask; + } + } + uint32_t page_count = kBufferSize >> page_size_log2_; + if (fire_watches_range_start != UINT32_MAX) { + FireWatches(fire_watches_range_start, page_count - 1, false); + } + if (gpu_written_range_start != UINT32_MAX) { + uint32_t gpu_written_range_length = page_count - gpu_written_range_start; + if (EnsureHostGpuMemoryAllocated(gpu_written_range_start << page_size_log2_, + gpu_written_range_length << page_size_log2_)) { + trace_download_ranges_.push_back(std::make_pair(gpu_written_range_start << page_size_log2_, + gpu_written_range_length << page_size_log2_)); + trace_download_page_count_ += gpu_written_range_length; + } + } +} + +void SharedMemory::ReleaseTraceDownloadRanges() { + trace_download_ranges_.clear(); + trace_download_ranges_.shrink_to_fit(); + trace_download_page_count_ = 0; +} + +bool SharedMemory::EnsureHostGpuMemoryAllocated(uint32_t start, uint32_t length) { + if (host_gpu_memory_sparse_granularity_log2_ == UINT32_MAX) { + return true; + } + if (!length) { + return true; + } + if (start > kBufferSize || (kBufferSize - start) < length) { + return false; + } + uint32_t page_first = start >> page_size_log2_; + uint32_t page_last = (start + length - 1) >> page_size_log2_; + uint32_t allocation_first = + page_first << page_size_log2_ >> host_gpu_memory_sparse_granularity_log2_; + uint32_t allocation_last = + page_last << page_size_log2_ >> host_gpu_memory_sparse_granularity_log2_; + while (true) { + std::pair allocation_range = + rex::bit::GetNextRangeUnset(host_gpu_memory_sparse_allocated_.data(), allocation_first, + allocation_last - allocation_first + 1); + if (!allocation_range.second) { + break; + } + if (!AllocateSparseHostGpuMemoryRange(uint32_t(allocation_range.first), + uint32_t(allocation_range.second))) { + return false; + } + rex::bit::SetRange(host_gpu_memory_sparse_allocated_.data(), allocation_range.first, + allocation_range.second); + ++host_gpu_memory_sparse_allocations_; + COUNT_profile_set("gpu/shared_memory/host_gpu_memory_sparse_allocations", + host_gpu_memory_sparse_allocations_); + host_gpu_memory_sparse_used_bytes_ += uint32_t(allocation_range.second) + << host_gpu_memory_sparse_granularity_log2_; + COUNT_profile_set("gpu/shared_memory/host_gpu_memory_sparse_used_mb", + (host_gpu_memory_sparse_used_bytes_ + ((1 << 20) - 1)) >> 20); + allocation_first = uint32_t(allocation_range.first + allocation_range.second); + } + return true; +} + +} // namespace rex::graphics diff --git a/src/graphics/trace_dump.cpp b/src/graphics/trace_dump.cpp new file mode 100644 index 0000000..ad46ed6 --- /dev/null +++ b/src/graphics/trace_dump.cpp @@ -0,0 +1,152 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include & args) { + // Grab path from the flag or unnamed argument. + std::filesystem::path path; + std::filesystem::path output_path; + if (!REXCVAR_GET(target_trace_file).empty()) { + // Passed as a named argument. + // TODO(benvanik): find something better than gflags that supports + // unicode. + path = REXCVAR_GET(target_trace_file); + } else if (args.size() >= 2) { + // Passed as an unnamed argument. + path = rex::to_path(args[1]); + + if (args.size() >= 3) { + output_path = rex::to_path(args[2]); + } + } + + if (path.empty()) { + REXGPU_ERROR("No trace file specified"); + return 5; + } + + // Normalize the path and make absolute. + auto abs_path = std::filesystem::absolute(path); + REXGPU_INFO("Loading trace file {}...", rex::path_to_utf8(abs_path)); + + if (!Setup()) { + REXGPU_ERROR("Unable to setup trace dump tool"); + return 4; + } + if (!Load(std::move(abs_path))) { + REXGPU_ERROR("Unable to load trace file; not found?"); + return 5; + } + + // Root file name for outputs. + if (output_path.empty()) { + base_output_path_ = REXCVAR_GET(trace_dump_path); + auto output_name = path.filename().replace_extension(); + + base_output_path_ = base_output_path_ / output_name; + } else { + base_output_path_ = output_path; + } + + // Ensure output path exists. + rex::filesystem::CreateParentFolder(base_output_path_); + + return Run(); +} + +bool TraceDump::Setup() { + // Create the emulator but don't initialize so we can setup the window. + emulator_ = std::make_unique("", "", "", ""); + X_STATUS result = emulator_->Setup( + nullptr, nullptr, false, nullptr, [this]() { return CreateGraphicsSystem(); }, nullptr); + if (XFAILED(result)) { + REXGPU_ERROR("Failed to setup emulator: {:08X}", result); + return false; + } + graphics_system_ = emulator_->graphics_system(); + player_ = std::make_unique(graphics_system_); + return true; +} + +bool TraceDump::Load(const std::filesystem::path& trace_file_path) { + trace_file_path_ = trace_file_path; + + if (!player_->Open(rex::path_to_utf8(trace_file_path_))) { + REXGPU_ERROR("Could not load trace file"); + return false; + } + + return true; +} + +int TraceDump::Run() { + BeginHostCapture(); + player_->SeekFrame(0); + player_->SeekCommand(static_cast(player_->current_frame()->commands.size() - 1)); + player_->WaitOnPlayback(); + EndHostCapture(); + + // Capture. + int result = 0; + ui::Presenter* presenter = graphics_system_->presenter(); + ui::RawImage raw_image; + if (presenter && presenter->CaptureGuestOutput(raw_image)) { + // Save framebuffer png. + auto png_path = base_output_path_.replace_extension(".png"); + auto handle = filesystem::OpenFile(png_path, "wb"); + auto callback = [](void* context, void* data, int size) { + fwrite(data, 1, size, (FILE*)context); + }; + stbi_write_png_to_func(callback, handle, static_cast(raw_image.width), + static_cast(raw_image.height), 4, raw_image.data.data(), + static_cast(raw_image.stride)); + fclose(handle); + } else { + result = 1; + } + + player_.reset(); + emulator_.reset(); + return result; +} + +} // namespace rex::graphics diff --git a/src/graphics/trace_player.cpp b/src/graphics/trace_player.cpp new file mode 100644 index 0000000..b487aff --- /dev/null +++ b/src/graphics/trace_player.cpp @@ -0,0 +1,231 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include +#include +#include + +namespace rex::graphics { + +TracePlayer::TracePlayer(GraphicsSystem* graphics_system) + : graphics_system_(graphics_system), current_frame_index_(0), current_command_index_(-1) { + // Need to allocate all of physical memory so that we can write to it during + // playback. The 64 KB page heap is larger, covers the entire physical memory, + // so it is used instead of the 4 KB page one. + auto heap = graphics_system_->memory()->LookupHeapByType(true, 64 * 1024); + heap->AllocFixed(heap->heap_base(), heap->heap_size(), heap->page_size(), + memory::kMemoryAllocationReserve | memory::kMemoryAllocationCommit, + memory::kMemoryProtectRead | memory::kMemoryProtectWrite); + + playback_event_ = rex::thread::Event::CreateAutoResetEvent(false); + assert_not_null(playback_event_); +} + +const TraceReader::Frame* TracePlayer::current_frame() const { + if (current_frame_index_ >= frame_count()) { + return nullptr; + } + return frame(current_frame_index_); +} + +void TracePlayer::SeekFrame(int target_frame) { + if (current_frame_index_ == target_frame) { + return; + } + current_frame_index_ = target_frame; + auto frame = current_frame(); + current_command_index_ = int(frame->commands.size()) - 1; + + assert_true(frame->start_ptr <= frame->end_ptr); + PlayTrace(frame->start_ptr, frame->end_ptr - frame->start_ptr, TracePlaybackMode::kBreakOnSwap, + false); +} + +void TracePlayer::SeekCommand(int target_command) { + if (current_command_index_ == target_command) { + return; + } + int previous_command_index = current_command_index_; + current_command_index_ = target_command; + if (current_command_index_ == -1) { + return; + } + auto frame = current_frame(); + const auto& command = frame->commands[target_command]; + assert_true(frame->start_ptr <= command.end_ptr); + if (previous_command_index != -1 && target_command > previous_command_index) { + // Seek forward. + const auto& previous_command = frame->commands[previous_command_index]; + PlayTrace(previous_command.end_ptr, command.end_ptr - previous_command.end_ptr, + TracePlaybackMode::kBreakOnSwap, false); + } else { + // Full playback from frame start. + PlayTrace(frame->start_ptr, command.end_ptr - frame->start_ptr, TracePlaybackMode::kBreakOnSwap, + true); + } +} + +void TracePlayer::WaitOnPlayback() { + rex::thread::Wait(playback_event_.get(), true); +} + +void TracePlayer::PlayTrace(const uint8_t* trace_data, size_t trace_size, + TracePlaybackMode playback_mode, bool clear_caches) { + playing_trace_ = true; + graphics_system_->command_processor()->CallInThread( + [=]() { PlayTraceOnThread(trace_data, trace_size, playback_mode, clear_caches); }); +} + +void TracePlayer::PlayTraceOnThread(const uint8_t* trace_data, size_t trace_size, + TracePlaybackMode playback_mode, bool clear_caches) { + auto memory = graphics_system_->memory(); + auto command_processor = graphics_system_->command_processor(); + + if (clear_caches) { + command_processor->ClearCaches(); + } + + playback_percent_ = 0; + auto trace_end = trace_data + trace_size; + + playing_trace_ = true; + auto trace_ptr = trace_data; + bool pending_break = false; + const PacketStartCommand* pending_packet = nullptr; + while (trace_ptr < trace_data + trace_size) { + playback_percent_ = + uint32_t((float(trace_ptr - trace_data) / float(trace_end - trace_data)) * 10000); + + auto type = static_cast(memory::load(trace_ptr)); + switch (type) { + case TraceCommandType::kPrimaryBufferStart: { + auto cmd = reinterpret_cast(trace_ptr); + // + trace_ptr += sizeof(*cmd) + cmd->count * 4; + break; + } + case TraceCommandType::kPrimaryBufferEnd: { + auto cmd = reinterpret_cast(trace_ptr); + // + trace_ptr += sizeof(*cmd); + break; + } + case TraceCommandType::kIndirectBufferStart: { + auto cmd = reinterpret_cast(trace_ptr); + // + trace_ptr += sizeof(*cmd) + cmd->count * 4; + break; + } + case TraceCommandType::kIndirectBufferEnd: { + auto cmd = reinterpret_cast(trace_ptr); + // + trace_ptr += sizeof(*cmd); + break; + } + case TraceCommandType::kPacketStart: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd); + std::memcpy(memory->TranslatePhysical(cmd->base_ptr), trace_ptr, cmd->count * 4); + trace_ptr += cmd->count * 4; + pending_packet = cmd; + break; + } + case TraceCommandType::kPacketEnd: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd); + if (pending_packet) { + command_processor->ExecutePacket(pending_packet->base_ptr, pending_packet->count); + pending_packet = nullptr; + } + if (pending_break) { + playing_trace_ = false; + return; + } + break; + } + case TraceCommandType::kMemoryRead: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd); + DecompressMemory(cmd->encoding_format, trace_ptr, cmd->encoded_length, + memory->TranslatePhysical(cmd->base_ptr), cmd->decoded_length); + trace_ptr += cmd->encoded_length; + command_processor->TracePlaybackWroteMemory(cmd->base_ptr, cmd->decoded_length); + break; + } + case TraceCommandType::kMemoryWrite: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd); + // ? + // Assuming the command processor will do the same write. + trace_ptr += cmd->encoded_length; + break; + } + case TraceCommandType::kEdramSnapshot: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd); + std::unique_ptr edram_snapshot(new uint8_t[xenos::kEdramSizeBytes]); + DecompressMemory(cmd->encoding_format, trace_ptr, cmd->encoded_length, edram_snapshot.get(), + xenos::kEdramSizeBytes); + trace_ptr += cmd->encoded_length; + command_processor->RestoreEdramSnapshot(edram_snapshot.get()); + break; + } + case TraceCommandType::kEvent: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd); + switch (cmd->event_type) { + case EventCommand::Type::kSwap: { + if (playback_mode == TracePlaybackMode::kBreakOnSwap) { + pending_break = true; + } + break; + } + } + break; + } + case TraceCommandType::kRegisters: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd); + std::unique_ptr register_values(new uint32_t[cmd->register_count]); + DecompressMemory(cmd->encoding_format, trace_ptr, cmd->encoded_length, + register_values.get(), sizeof(uint32_t) * cmd->register_count); + trace_ptr += cmd->encoded_length; + command_processor->RestoreRegisters(cmd->first_register, register_values.get(), + cmd->register_count, cmd->execute_callbacks); + break; + } + case TraceCommandType::kGammaRamp: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd); + std::unique_ptr gamma_ramps(new uint32_t[256 + 3 * 128]); + DecompressMemory(cmd->encoding_format, trace_ptr, cmd->encoded_length, gamma_ramps.get(), + sizeof(uint32_t) * (256 + 3 * 128)); + trace_ptr += cmd->encoded_length; + command_processor->RestoreGammaRamp( + reinterpret_cast(gamma_ramps.get()), + reinterpret_cast(gamma_ramps.get() + 256), + cmd->rw_component); + break; + } + } + } + + playing_trace_ = false; + + playback_event_->Set(); +} + +} // namespace rex::graphics diff --git a/src/graphics/trace_reader.cpp b/src/graphics/trace_reader.cpp new file mode 100644 index 0000000..86eb1b3 --- /dev/null +++ b/src/graphics/trace_reader.cpp @@ -0,0 +1,250 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include (mmap_->data()); + trace_size_ = mmap_->size(); + + // Verify version. + auto header = reinterpret_cast(trace_data_); + if (header->version != kTraceFormatVersion) { + REXGPU_ERROR("Trace format version mismatch, code has {}, file has {}", kTraceFormatVersion, + header->version); + if (header->version < kTraceFormatVersion) { + REXGPU_ERROR("You need to regenerate your trace for the latest version"); + } + return false; + } + + REXGPU_INFO("Mapped {}b trace from {}", trace_size_, rex::path_to_utf8(path)); + REXGPU_INFO(" Version: {}", header->version); + auto commit_str = std::string(header->build_commit_sha, rex::countof(header->build_commit_sha)); + REXGPU_INFO(" Commit: {}", commit_str); + REXGPU_INFO(" Title ID: {}", header->title_id); + + ParseTrace(); + + return true; +} + +void TraceReader::Close() { + mmap_.reset(); + trace_data_ = nullptr; + trace_size_ = 0; +} + +void TraceReader::ParseTrace() { + // Skip file header. + auto trace_ptr = trace_data_; + trace_ptr += sizeof(TraceHeader); + + Frame current_frame; + current_frame.start_ptr = trace_ptr; + const PacketStartCommand* packet_start = nullptr; + const uint8_t* packet_start_ptr = nullptr; + const uint8_t* last_ptr = trace_ptr; + bool pending_break = false; + auto current_command_buffer = new CommandBuffer(); + current_frame.command_tree = std::unique_ptr(current_command_buffer); + + while (trace_ptr < trace_data_ + trace_size_) { + ++current_frame.command_count; + auto type = static_cast(memory::load(trace_ptr)); + switch (type) { + case TraceCommandType::kPrimaryBufferStart: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd) + cmd->count * 4; + break; + } + case TraceCommandType::kPrimaryBufferEnd: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd); + break; + } + case TraceCommandType::kIndirectBufferStart: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd) + cmd->count * 4; + + // Traverse down a level. + auto sub_command_buffer = new CommandBuffer(); + sub_command_buffer->parent = current_command_buffer; + current_command_buffer->commands.push_back(CommandBuffer::Command(sub_command_buffer)); + current_command_buffer = sub_command_buffer; + break; + } + case TraceCommandType::kIndirectBufferEnd: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd); + + // IB packet is wrapped in a kPacketStart/kPacketEnd. Skip the end. + auto end_cmd = reinterpret_cast(trace_ptr); + assert_true(end_cmd->type == TraceCommandType::kPacketEnd); + trace_ptr += sizeof(*cmd); + + // Go back up a level. If parent is null, this frame started in an + // indirect buffer. + if (current_command_buffer->parent) { + current_command_buffer = current_command_buffer->parent; + } + break; + } + case TraceCommandType::kPacketStart: { + auto cmd = reinterpret_cast(trace_ptr); + packet_start_ptr = trace_ptr; + packet_start = cmd; + trace_ptr += sizeof(*cmd) + cmd->count * 4; + break; + } + case TraceCommandType::kPacketEnd: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd); + if (!packet_start_ptr) { + continue; + } + auto packet_category = + PacketDisassembler::GetPacketCategory(packet_start_ptr + sizeof(*packet_start)); + switch (packet_category) { + case PacketCategory::kDraw: { + Frame::Command command; + command.type = Frame::Command::Type::kDraw; + command.head_ptr = packet_start_ptr; + command.start_ptr = last_ptr; + command.end_ptr = trace_ptr; + current_frame.commands.push_back(std::move(command)); + last_ptr = trace_ptr; + current_command_buffer->commands.push_back( + CommandBuffer::Command(uint32_t(current_frame.commands.size() - 1))); + break; + } + case PacketCategory::kSwap: { + Frame::Command command; + command.type = Frame::Command::Type::kSwap; + command.head_ptr = packet_start_ptr; + command.start_ptr = last_ptr; + command.end_ptr = trace_ptr; + current_frame.commands.push_back(std::move(command)); + last_ptr = trace_ptr; + current_command_buffer->commands.push_back( + CommandBuffer::Command(uint32_t(current_frame.commands.size() - 1))); + } break; + case PacketCategory::kGeneric: { + // Ignored. + break; + } + } + if (pending_break) { + current_frame.end_ptr = trace_ptr; + frames_.push_back(std::move(current_frame)); + current_command_buffer = new CommandBuffer(); + current_frame.command_tree = std::unique_ptr(current_command_buffer); + current_frame.start_ptr = trace_ptr; + current_frame.end_ptr = nullptr; + current_frame.command_count = 0; + pending_break = false; + } + break; + } + case TraceCommandType::kMemoryRead: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd) + cmd->encoded_length; + break; + } + case TraceCommandType::kMemoryWrite: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd) + cmd->encoded_length; + break; + } + case TraceCommandType::kEdramSnapshot: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd) + cmd->encoded_length; + break; + } + case TraceCommandType::kEvent: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd); + switch (cmd->event_type) { + case EventCommand::Type::kSwap: { + pending_break = true; + break; + } + } + break; + } + case TraceCommandType::kRegisters: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd) + cmd->encoded_length; + break; + } + case TraceCommandType::kGammaRamp: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd) + cmd->encoded_length; + break; + } + default: + // Broken trace file? + assert_unhandled_case(type); + break; + } + } + if (pending_break || current_frame.command_count) { + current_frame.end_ptr = trace_ptr; + frames_.push_back(std::move(current_frame)); + } +} + +bool TraceReader::DecompressMemory(MemoryEncodingFormat encoding_format, const void* src, + size_t src_size, void* dest, size_t dest_size) { + switch (encoding_format) { + case MemoryEncodingFormat::kNone: + assert_true(src_size == dest_size); + std::memcpy(dest, src, src_size); + return true; + case MemoryEncodingFormat::kSnappy: + return snappy::RawUncompress(reinterpret_cast(src), src_size, + reinterpret_cast(dest)); + default: + assert_unhandled_case(encoding_format); + return false; + } +} + +} // namespace rex::graphics diff --git a/src/graphics/trace_viewer.cpp b/src/graphics/trace_viewer.cpp new file mode 100644 index 0000000..c76b477 --- /dev/null +++ b/src/graphics/trace_viewer.cpp @@ -0,0 +1,1770 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include "thirdparty/half/include/half.hpp" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +DEFINE_string(target_trace_file, "", "Specifies the trace file to load.", "GPU"); + +namespace rex::graphics { + +using namespace rex::graphics::xenos; + +static const ImVec4 kColorError = ImVec4(255 / 255.0f, 0 / 255.0f, 0 / 255.0f, 255 / 255.0f); +static const ImVec4 kColorComment = ImVec4(42 / 255.0f, 179 / 255.0f, 0 / 255.0f, 255 / 255.0f); +static const ImVec4 kColorIgnored = ImVec4(100 / 255.0f, 100 / 255.0f, 100 / 255.0f, 255 / 255.0f); + +TraceViewer::TraceViewer(rex::ui::WindowedAppContext& app_context, const std::string_view name) + : rex::ui::WindowedApp(app_context, name, "some.trace"), window_listener_(*this) { + AddPositionalOption("target_trace_file"); +} + +TraceViewer::~TraceViewer() = default; + +bool TraceViewer::OnInitialize() { + std::string path = REXCVAR_GET(target_trace_file); + + // If no path passed, ask the user. + // On Android, however, there's no synchronous file picker, and the trace file + // must be picked externally and provided to the trace viewer activity via the + // intent. +#if !REX_PLATFORM_ANDROID + if (path.empty()) { + auto file_picker = rex::ui::FilePicker::Create(); + file_picker->set_mode(ui::FilePicker::Mode::kOpen); + file_picker->set_type(ui::FilePicker::Type::kFile); + file_picker->set_multi_selection(false); + file_picker->set_title("Select Trace File"); + file_picker->set_extensions({ + {"Supported Files", "*.xtr"}, + {"All Files (*.*)", "*.*"}, + }); + if (file_picker->Show()) { + auto selected_files = file_picker->selected_files(); + if (!selected_files.empty()) { + path = rex::path_to_utf8(selected_files[0]); + } + } + } +#endif // !REX_PLATFORM_ANDROID + + if (path.empty()) { + rex::ShowSimpleMessageBox(rex::SimpleMessageBoxType::Warning, "No trace file specified"); + return false; + } + + if (!Setup()) { + rex::ShowSimpleMessageBox(rex::SimpleMessageBoxType::Error, "Unable to setup trace viewer"); + return false; + } + if (!Load(path)) { + rex::ShowSimpleMessageBox(rex::SimpleMessageBoxType::Error, + "Unable to load trace file; not found?"); + return false; + } + return true; +} + +bool TraceViewer::Setup() { + enum : size_t { + kZOrderImGui, + kZOrderTraceViewerInput, + }; + + // Main display window. + assert_true(app_context().IsInUIThread()); + window_ = rex::ui::Window::Create(app_context(), "xenia-gpu-trace-viewer", 1920, 1080); + window_->AddListener(&window_listener_); + window_->AddInputListener(&window_listener_, kZOrderTraceViewerInput); + if (!window_->Open()) { + REXGPU_ERROR("Failed to open the main window"); + return false; + } + + // Create the emulator but don't initialize so we can setup the window. + emulator_ = std::make_unique("", "", "", ""); + X_STATUS result = emulator_->Setup( + window_.get(), nullptr, false, nullptr, [this]() { return CreateGraphicsSystem(); }, nullptr); + if (XFAILED(result)) { + REXGPU_ERROR("Failed to setup emulator: {:08X}", result); + return false; + } + memory_ = emulator_->memory(); + graphics_system_ = emulator_->graphics_system(); + + player_ = std::make_unique(graphics_system_); + + // Setup drawing to the window. + ui::Presenter* presenter = graphics_system_->presenter(); + if (!presenter) { + REXGPU_ERROR("Failed to initialize the presenter"); + return false; + } + rex::ui::GraphicsProvider& graphics_provider = *graphics_system_->provider(); + immediate_drawer_ = graphics_provider.CreateImmediateDrawer(); + if (!immediate_drawer_) { + REXGPU_ERROR("Failed to initialize the immediate drawer"); + return false; + } + immediate_drawer_->SetPresenter(presenter); + imgui_drawer_ = std::make_unique(window_.get(), kZOrderImGui); + imgui_drawer_->SetPresenterAndImmediateDrawer(presenter, immediate_drawer_.get()); + trace_viewer_dialog_ = + std::unique_ptr(new TraceViewerDialog(imgui_drawer_.get(), *this)); + window_->SetPresenter(presenter); + + return true; +} + +void TraceViewer::TraceViewerWindowListener::OnClosing(rex::ui::UIEvent& e) { + trace_viewer_.app_context().QuitFromUIThread(); +} + +void TraceViewer::TraceViewerWindowListener::OnKeyDown(rex::ui::KeyEvent& e) { + switch (e.virtual_key()) { + case rex::ui::VirtualKey::kF5: + trace_viewer_.graphics_system_->ClearCaches(); + break; + default: + return; + } + e.set_handled(true); +} + +void TraceViewer::TraceViewerDialog::OnDraw(ImGuiIO& io) { + trace_viewer_.DrawUI(); +} + +bool TraceViewer::Load(const std::string_view trace_file_path) { + window_->SetTitle("Xenia GPU Trace Viewer: " + std::string(trace_file_path)); + + if (!player_->Open(trace_file_path)) { + REXGPU_ERROR("Could not load trace file"); + return false; + } + + return true; +} + +void TraceViewer::DrawMultilineString(const std::string_view str) { + size_t i = 0; + bool done = false; + while (!done && i < str.size()) { + size_t next_i = str.find('\n', i); + if (next_i == std::string::npos) { + done = true; + next_i = str.size() - 1; + } + auto line = str.substr(i, next_i - i); + ImGui::Text("%s", std::string(line).c_str()); + i = next_i + 1; + } +} + +void TraceViewer::DrawUI() { + // ImGui::ShowDemoWindow(); + + DrawControllerUI(); + DrawCommandListUI(); + DrawStateUI(); + DrawPacketDisassemblerUI(); +} + +void TraceViewer::DrawControllerUI() { + ImGui::SetNextWindowPos(ImVec2(5, 5), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(340, 60)); + ImGui::SetNextWindowBgAlpha(kWindowBgAlpha); + if (!ImGui::Begin("Controller", nullptr)) { + ImGui::End(); + return; + } + + int target_frame = player_->current_frame_index(); + if (ImGui::Button("|<<")) { + target_frame = 0; + } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Reset to first frame"); + } + ImGui::SameLine(); + ImGui::PushButtonRepeat(true); + if (ImGui::Button(">>", ImVec2(0, 0))) { + if (target_frame + 1 < player_->frame_count()) { + ++target_frame; + } + } + ImGui::PopButtonRepeat(); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Next frame (hold for continuous)"); + } + ImGui::SameLine(); + if (ImGui::Button(">>|")) { + target_frame = player_->frame_count() - 1; + } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Skip to last frame"); + } + if (player_->is_playing_trace()) { + // Don't allow the user to change the frame index just yet... + // TODO: Find a way to disable the slider below. + target_frame = player_->current_frame_index(); + } + + ImGui::SameLine(); + ImGui::SliderInt("##", &target_frame, 0, player_->frame_count() - 1); + if (target_frame != player_->current_frame_index() && !player_->is_playing_trace()) { + player_->SeekFrame(target_frame); + } + ImGui::End(); +} + +void TraceViewer::DrawPacketDisassemblerUI() { + ImGui::SetNextWindowCollapsed(true, ImGuiCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(float(window_->GetActualLogicalWidth()) - 500 - 5, 5), + ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(500, 300)); + ImGui::SetNextWindowBgAlpha(kWindowBgAlpha); + if (!ImGui::Begin("Packet Disassembler", nullptr)) { + ImGui::End(); + return; + } + if (!player_->current_frame() || player_->current_command_index() == -1) { + ImGui::Text("No frame/command selected"); + ImGui::End(); + return; + } + + auto frame = player_->current_frame(); + const auto& command = frame->commands[player_->current_command_index()]; + const uint8_t* start_ptr = command.start_ptr; + const uint8_t* end_ptr = command.end_ptr; + + ImGui::Text("Frame #%d, command %d", player_->current_frame_index(), + player_->current_command_index()); + ImGui::Separator(); + ImGui::BeginChild("packet_disassembler_list"); + const PacketStartCommand* pending_packet = nullptr; + auto trace_ptr = start_ptr; + while (trace_ptr < end_ptr) { + auto type = static_cast(memory::load(trace_ptr)); + switch (type) { + case TraceCommandType::kPrimaryBufferStart: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd) + cmd->count * 4; + ImGui::BulletText("PrimaryBufferStart"); + break; + } + case TraceCommandType::kPrimaryBufferEnd: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd); + ImGui::BulletText("PrimaryBufferEnd"); + break; + } + case TraceCommandType::kIndirectBufferStart: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd) + cmd->count * 4; + ImGui::BulletText("IndirectBufferStart"); + break; + } + case TraceCommandType::kIndirectBufferEnd: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd); + ImGui::BulletText("IndirectBufferEnd"); + break; + } + case TraceCommandType::kPacketStart: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd) + cmd->count * 4; + pending_packet = cmd; + break; + } + case TraceCommandType::kPacketEnd: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd); + if (pending_packet) { + PacketInfo packet_info = {0}; + if (PacketDisassembler::DisasmPacket( + reinterpret_cast(pending_packet) + sizeof(PacketStartCommand), + &packet_info)) { + if (packet_info.predicated) { + ImGui::PushStyleColor(ImGuiCol_Text, kColorIgnored); + } + ImGui::BulletText("%s", packet_info.type_info->name); + ImGui::TreePush((const char*)0); + for (auto action : packet_info.actions) { + switch (action.type) { + case PacketAction::Type::kRegisterWrite: { + auto register_info = + rex::graphics::RegisterFile::GetRegisterInfo(action.register_write.index); + ImGui::Columns(2); + ImGui::Text("%.4X %s", action.register_write.index, + register_info ? register_info->name : "???"); + ImGui::NextColumn(); + if (!register_info || register_info->type == RegisterInfo::Type::kDword) { + ImGui::Text("%.8X", action.register_write.value); + } else { + ImGui::Text("%8f", + rex::memory::Reinterpret(action.register_write.value)); + } + ImGui::Columns(1); + break; + } + case PacketAction::Type::kSetBinMask: { + ImGui::Text("%.16" PRIX64, action.set_bin_mask.value); + break; + } + case PacketAction::Type::kSetBinSelect: { + ImGui::Text("%.16" PRIX64, action.set_bin_select.value); + break; + } + } + } + ImGui::TreePop(); + if (packet_info.predicated) { + ImGui::PopStyleColor(); + } + } else { + ImGui::BulletText(""); + } + pending_packet = nullptr; + } + break; + } + case TraceCommandType::kMemoryRead: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd) + cmd->encoded_length; + // ImGui::BulletText("MemoryRead"); + break; + } + case TraceCommandType::kMemoryWrite: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd) + cmd->encoded_length; + // ImGui::BulletText("MemoryWrite"); + break; + } + case TraceCommandType::kEdramSnapshot: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd) + cmd->encoded_length; + // ImGui::BulletText("EdramSnapshot"); + break; + } + case TraceCommandType::kEvent: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd); + switch (cmd->event_type) { + case EventCommand::Type::kSwap: { + ImGui::BulletText(""); + break; + } + } + break; + } + case TraceCommandType::kRegisters: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd) + cmd->encoded_length; + // ImGui::BulletText("Registers"); + break; + } + case TraceCommandType::kGammaRamp: { + auto cmd = reinterpret_cast(trace_ptr); + trace_ptr += sizeof(*cmd) + cmd->encoded_length; + // ImGui::BulletText("GammaRamp"); + break; + } + } + } + ImGui::EndChild(); + ImGui::End(); +} + +int TraceViewer::RecursiveDrawCommandBufferUI(const TraceReader::Frame* frame, + TraceReader::CommandBuffer* buffer) { + int selected_id = -1; + int column_width = int(ImGui::GetContentRegionMax().x); + + for (size_t i = 0; i < buffer->commands.size(); i++) { + switch (buffer->commands[i].type) { + case TraceReader::CommandBuffer::Command::Type::kBuffer: { + auto subtree = buffer->commands[i].command_subtree.get(); + if (!subtree->commands.size()) { + continue; + } + + ImGui::PushID(int(i)); + if (ImGui::TreeNode((void*)0, "Indirect Buffer %" PRIu64, i)) { + ImGui::Indent(); + auto id = RecursiveDrawCommandBufferUI(frame, buffer->commands[i].command_subtree.get()); + ImGui::Unindent(); + ImGui::TreePop(); + + if (id != -1) { + selected_id = id; + } + } + ImGui::PopID(); + } break; + + case TraceReader::CommandBuffer::Command::Type::kCommand: { + uint32_t command_id = buffer->commands[i].command_id; + + const auto& command = frame->commands[command_id]; + bool is_selected = command_id == player_->current_command_index(); + const char* label; + switch (command.type) { + case TraceReader::Frame::Command::Type::kDraw: + label = "Draw"; + break; + case TraceReader::Frame::Command::Type::kSwap: + label = "Swap"; + break; + } + + ImGui::PushID(command_id); + if (ImGui::Selectable(label, &is_selected)) { + selected_id = command_id; + } + ImGui::SameLine(column_width - 60.0f); + ImGui::Text("%d", command_id); + ImGui::PopID(); + // if (did_seek && target_command == i) { + // ImGui::SetScrollPosHere(); + // } + } break; + } + } + + return selected_id; +} + +void TraceViewer::DrawCommandListUI() { + ImGui::SetNextWindowPos(ImVec2(5, 70), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(200, 640)); + ImGui::SetNextWindowBgAlpha(kWindowBgAlpha); + if (!ImGui::Begin("Command List", nullptr)) { + ImGui::End(); + return; + } + + static const TracePlayer::Frame* previous_frame = nullptr; + auto frame = player_->current_frame(); + if (!frame) { + ImGui::End(); + return; + } + bool did_seek = false; + if (previous_frame != frame) { + did_seek = true; + previous_frame = frame; + } + int command_count = int(frame->commands.size()); + int target_command = player_->current_command_index(); + int column_width = int(ImGui::GetContentRegionMax().x); + ImGui::Text("Frame #%d", player_->current_frame_index()); + ImGui::Separator(); + if (ImGui::Button("reset")) { + target_command = -1; + } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Reset to before any frame commands"); + } + ImGui::SameLine(); + ImGui::PushButtonRepeat(true); + if (ImGui::Button("prev", ImVec2(0, 0))) { + if (target_command >= 0) { + --target_command; + } + } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Move to the previous command (hold)"); + } + ImGui::SameLine(); + if (ImGui::Button("next", ImVec2(0, 0))) { + if (target_command < command_count - 1) { + ++target_command; + } + } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Move to the next command (hold)"); + } + ImGui::PopButtonRepeat(); + ImGui::SameLine(); + if (ImGui::Button("end")) { + target_command = command_count - 1; + } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Move to the last command"); + } + if (player_->is_playing_trace()) { + // Don't allow the user to change the command index just yet... + // TODO: Find a way to disable the slider below. + target_command = player_->current_command_index(); + } + + ImGui::PushItemWidth(float(column_width - 15)); + ImGui::SliderInt("##", &target_command, -1, command_count - 1); + ImGui::PopItemWidth(); + + if (target_command != player_->current_command_index() && !player_->is_playing_trace()) { + did_seek = true; + player_->SeekCommand(target_command); + } + ImGui::Separator(); + ImGui::BeginChild("command_list"); + ImGui::PushID(-1); + bool is_selected = player_->current_command_index() == -1; + if (ImGui::Selectable("", &is_selected)) { + player_->SeekCommand(-1); + } + ImGui::PopID(); + if (did_seek && target_command == -1) { + ImGui::SetScrollHereY(0.5f); + } + + auto id = RecursiveDrawCommandBufferUI(frame, frame->command_tree.get()); + if (id != -1 && id != player_->current_command_index() && !player_->is_playing_trace()) { + player_->SeekCommand(id); + } + + ImGui::EndChild(); + ImGui::End(); +} + +TraceViewer::ShaderDisplayType TraceViewer::DrawShaderTypeUI() { + static ShaderDisplayType shader_display_type = ShaderDisplayType::kUcode; + ImGui::RadioButton("ucode", reinterpret_cast(&shader_display_type), + static_cast(ShaderDisplayType::kUcode)); + ImGui::SameLine(); + ImGui::RadioButton("translated", reinterpret_cast(&shader_display_type), + static_cast(ShaderDisplayType::kTranslated)); + ImGui::SameLine(); + ImGui::RadioButton("disasm", reinterpret_cast(&shader_display_type), + static_cast(ShaderDisplayType::kHostDisasm)); + return shader_display_type; +} + +void TraceViewer::DrawShaderUI(Shader* shader, ShaderDisplayType display_type) { + // Must be prepared for advanced display modes. + // FIXME(Triang3l): This should display the actual translation used in the + // draw, but it may depend on multiple backend-related factors, including + // drawing multiple times with multiple modifications, even depending on + // values obtained during translation of other modifications (for instance, + // a memexporting shader can be executed both as a vertex shader (to draw the + // points) and as a compute shader (to actually export) if the host doesn't + // support writes from vertex shaders. + const Shader::Translation* translation = nullptr; + if (display_type != ShaderDisplayType::kUcode) { + for (const auto& translation_pair : shader->translations()) { + if (translation_pair.second->is_valid()) { + translation = translation_pair.second; + } + } + if (!translation) { + ImGui::TextColored(kColorError, "ERROR: shader error during parsing/translation"); + return; + } + } + + switch (display_type) { + case ShaderDisplayType::kUcode: { + DrawMultilineString(shader->ucode_disassembly()); + break; + } + case ShaderDisplayType::kTranslated: { + const auto& str = translation->GetTranslatedBinaryString(); + size_t i = 0; + bool done = false; + while (!done && i < str.size()) { + size_t next_i = str.find('\n', i); + if (next_i == std::string::npos) { + done = true; + next_i = str.size() - 1; + } + auto line = str.substr(i, next_i - i); + if (line.find("//") != std::string::npos) { + ImGui::TextColored(kColorComment, "%s", line.c_str()); + } else { + ImGui::Text("%s", line.c_str()); + } + i = next_i + 1; + } + break; + } + case ShaderDisplayType::kHostDisasm: { + DrawMultilineString(translation->host_disassembly()); + break; + } + } +} + +// glBlendEquationSeparatei(i, blend_op, blend_op_alpha); +// glBlendFuncSeparatei(i, src_blend, dest_blend, src_blend_alpha, +// dest_blend_alpha); +void TraceViewer::DrawBlendMode(uint32_t src_blend, uint32_t dest_blend, uint32_t blend_op) { + static const char* kBlendNames[] = { + /* 0 */ "ZERO", + /* 1 */ "ONE", + /* 2 */ "UNK2", // ? + /* 3 */ "UNK3", // ? + /* 4 */ "SRC_COLOR", + /* 5 */ "ONE_MINUS_SRC_COLOR", + /* 6 */ "SRC_ALPHA", + /* 7 */ "ONE_MINUS_SRC_ALPHA", + /* 8 */ "DST_COLOR", + /* 9 */ "ONE_MINUS_DST_COLOR", + /* 10 */ "DST_ALPHA", + /* 11 */ "ONE_MINUS_DST_ALPHA", + /* 12 */ "CONSTANT_COLOR", + /* 13 */ "ONE_MINUS_CONSTANT_COLOR", + /* 14 */ "CONSTANT_ALPHA", + /* 15 */ "ONE_MINUS_CONSTANT_ALPHA", + /* 16 */ "SRC_ALPHA_SATURATE", + }; + const char* src_str = kBlendNames[src_blend]; + const char* dest_str = kBlendNames[dest_blend]; + const char* op_template; + switch (blend_op) { + case 0: // add + op_template = "%s + %s"; + break; + case 1: // subtract + op_template = "%s - %s"; + break; + case 2: // min + op_template = "min(%s, %s)"; + break; + case 3: // max + op_template = "max(%s, %s)"; + break; + case 4: // reverse subtract + op_template = "-(%s) + %s"; + break; + default: + op_template = "%s ? %s"; + break; + } + ImGui::Text(op_template, src_str, dest_str); +} + +void TraceViewer::DrawTextureInfo(const Shader::TextureBinding& texture_binding) { + auto& regs = *graphics_system_->register_file(); + + xenos::xe_gpu_texture_fetch_t fetch = regs.GetTextureFetch(texture_binding.fetch_constant); + if (fetch.type != xenos::FetchConstantType::kTexture && + (!REXCVAR_GET(gpu_allow_invalid_fetch_constants) || + fetch.type != xenos::FetchConstantType::kInvalidTexture)) { + DrawFailedTextureInfo(texture_binding, "Invalid fetch type"); + return; + } + TextureInfo texture_info; + if (!TextureInfo::Prepare(fetch, &texture_info)) { + DrawFailedTextureInfo(texture_binding, "Unable to parse texture fetcher info"); + return; + } + SamplerInfo sampler_info; + if (!SamplerInfo::Prepare(fetch, texture_binding.fetch_instr, &sampler_info)) { + DrawFailedTextureInfo(texture_binding, "Unable to parse sampler info"); + return; + } + auto texture = GetTextureEntry(texture_info, sampler_info); + + ImGui::Columns(2); + if (texture) { + ImVec2 button_size(256, 256); + if (ImGui::ImageButton("#texture_info_image", ImTextureID(texture), button_size, ImVec2(0, 0), + ImVec2(1, 1))) { + // show viewer + } + } else { + DrawFailedTextureInfo(texture_binding, "Failed to demand texture"); + } + ImGui::NextColumn(); + ImGui::Text("Fetch Slot: %u", texture_binding.fetch_constant); + ImGui::Text("Guest Address: %.8X", texture_info.memory.base_address); + ImGui::Text("Format: %s", texture_info.format_info()->name); + switch (texture_info.dimension) { + case xenos::DataDimension::k1D: + ImGui::Text("1D: %dpx", texture_info.width + 1); + break; + case xenos::DataDimension::k2DOrStacked: + ImGui::Text("2D: %dx%dpx", texture_info.width + 1, texture_info.height + 1); + break; + case xenos::DataDimension::k3D: + ImGui::Text("3D: %dx%dx%dpx", texture_info.width + 1, texture_info.height + 1, + texture_info.depth + 1); + break; + case xenos::DataDimension::kCube: + ImGui::Text("Cube: ?"); + break; + } + static const char* kSwizzleMap[] = {"R", "G", "B", "A", "0", "1"}; + ImGui::Text("Swizzle: %s%s%s%s", kSwizzleMap[(fetch.swizzle >> 0) & 0x7], + kSwizzleMap[(fetch.swizzle >> 3) & 0x7], kSwizzleMap[(fetch.swizzle >> 6) & 0x7], + kSwizzleMap[(fetch.swizzle >> 9) & 0x7]); + + ImGui::Columns(1); +} + +void TraceViewer::DrawFailedTextureInfo(const Shader::TextureBinding& texture_binding, + const char* message) { + // TODO(benvanik): better error info/etc. + ImGui::TextColored(kColorError, "ERROR: %s", message); +} + +void TraceViewer::DrawVertexFetcher(Shader* shader, const Shader::VertexBinding& vertex_binding, + const xe_gpu_vertex_fetch_t& fetch) { + const uint8_t* addr = memory_->TranslatePhysical(fetch.address << 2); + uint32_t vertex_count = fetch.size / vertex_binding.stride_words; + int column_count = 0; + for (const auto& attrib : vertex_binding.attributes) { + switch (attrib.fetch_instr.attributes.data_format) { + case xenos::VertexFormat::k_32: + case xenos::VertexFormat::k_32_FLOAT: + ++column_count; + break; + case xenos::VertexFormat::k_16_16: + case xenos::VertexFormat::k_16_16_FLOAT: + case xenos::VertexFormat::k_32_32: + case xenos::VertexFormat::k_32_32_FLOAT: + column_count += 2; + break; + case xenos::VertexFormat::k_10_11_11: + case xenos::VertexFormat::k_11_11_10: + case xenos::VertexFormat::k_32_32_32_FLOAT: + column_count += 3; + break; + case xenos::VertexFormat::k_8_8_8_8: + ++column_count; + break; + case xenos::VertexFormat::k_2_10_10_10: + case xenos::VertexFormat::k_16_16_16_16: + case xenos::VertexFormat::k_32_32_32_32: + case xenos::VertexFormat::k_16_16_16_16_FLOAT: + case xenos::VertexFormat::k_32_32_32_32_FLOAT: + column_count += 4; + break; + case xenos::VertexFormat::kUndefined: + assert_unhandled_case(attrib.fetch_instr.attributes.data_format); + break; + } + } + ImGui::BeginChild("#indices", ImVec2(0, 300)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10, 0)); + int display_start, display_end; + ImGui::CalcListClipping(vertex_count, ImGui::GetTextLineHeight(), &display_start, &display_end); + ImGui::Dummy(ImVec2(0, (display_start)*ImGui::GetTextLineHeight())); + ImGui::Columns(column_count); + if (display_start <= 1) { + for (size_t el_index = 0; el_index < vertex_binding.attributes.size(); ++el_index) { + const auto& attrib = vertex_binding.attributes[el_index]; + switch (attrib.fetch_instr.attributes.data_format) { + case xenos::VertexFormat::k_32: + case xenos::VertexFormat::k_32_FLOAT: + ImGui::Text("e%" PRId64 ".x", el_index); + ImGui::NextColumn(); + break; + case xenos::VertexFormat::k_16_16: + case xenos::VertexFormat::k_16_16_FLOAT: + case xenos::VertexFormat::k_32_32: + case xenos::VertexFormat::k_32_32_FLOAT: + ImGui::Text("e%" PRId64 ".x", el_index); + ImGui::NextColumn(); + ImGui::Text("e%" PRId64 ".y", el_index); + ImGui::NextColumn(); + break; + case xenos::VertexFormat::k_10_11_11: + case xenos::VertexFormat::k_11_11_10: + case xenos::VertexFormat::k_32_32_32_FLOAT: + ImGui::Text("e%" PRId64 ".x", el_index); + ImGui::NextColumn(); + ImGui::Text("e%" PRId64 ".y", el_index); + ImGui::NextColumn(); + ImGui::Text("e%" PRId64 ".z", el_index); + ImGui::NextColumn(); + break; + case xenos::VertexFormat::k_8_8_8_8: + ImGui::Text("e%" PRId64 ".xyzw", el_index); + ImGui::NextColumn(); + break; + case xenos::VertexFormat::k_2_10_10_10: + case xenos::VertexFormat::k_16_16_16_16: + case xenos::VertexFormat::k_32_32_32_32: + case xenos::VertexFormat::k_16_16_16_16_FLOAT: + case xenos::VertexFormat::k_32_32_32_32_FLOAT: + ImGui::Text("e%" PRId64 ".x", el_index); + ImGui::NextColumn(); + ImGui::Text("e%" PRId64 ".y", el_index); + ImGui::NextColumn(); + ImGui::Text("e%" PRId64 ".z", el_index); + ImGui::NextColumn(); + ImGui::Text("e%" PRId64 ".w", el_index); + ImGui::NextColumn(); + break; + case xenos::VertexFormat::kUndefined: + assert_unhandled_case(attrib.fetch_instr.attributes.data_format); + break; + } + } + ImGui::Separator(); + } + for (int i = display_start; i < display_end; ++i) { + const uint8_t* vstart = addr + i * vertex_binding.stride_words * 4; + for (const auto& attrib : vertex_binding.attributes) { +#define LOADEL(type, wo) \ + GpuSwap(memory::load(vstart + (attrib.fetch_instr.attributes.offset + wo) * 4), \ + fetch.endian) + switch (attrib.fetch_instr.attributes.data_format) { + case xenos::VertexFormat::k_32: + ImGui::Text("%.8X", LOADEL(uint32_t, 0)); + ImGui::NextColumn(); + break; + case xenos::VertexFormat::k_32_FLOAT: + ImGui::Text("%.3f", LOADEL(float, 0)); + ImGui::NextColumn(); + break; + case xenos::VertexFormat::k_16_16: { + auto e0 = LOADEL(uint32_t, 0); + ImGui::Text("%.4X", (e0 >> 16) & 0xFFFF); + ImGui::NextColumn(); + ImGui::Text("%.4X", (e0 >> 0) & 0xFFFF); + ImGui::NextColumn(); + } break; + case xenos::VertexFormat::k_16_16_FLOAT: { + auto e0 = LOADEL(uint32_t, 0); + ImGui::Text("%.2f", half_float::detail::half2float((e0 >> 16) & 0xFFFF)); + ImGui::NextColumn(); + ImGui::Text("%.2f", half_float::detail::half2float((e0 >> 0) & 0xFFFF)); + ImGui::NextColumn(); + } break; + case xenos::VertexFormat::k_32_32: + ImGui::Text("%.8X", LOADEL(uint32_t, 0)); + ImGui::NextColumn(); + ImGui::Text("%.8X", LOADEL(uint32_t, 1)); + ImGui::NextColumn(); + break; + case xenos::VertexFormat::k_32_32_FLOAT: + ImGui::Text("%.3f", LOADEL(float, 0)); + ImGui::NextColumn(); + ImGui::Text("%.3f", LOADEL(float, 1)); + ImGui::NextColumn(); + break; + case xenos::VertexFormat::k_10_11_11: + case xenos::VertexFormat::k_11_11_10: + ImGui::Text("??"); + ImGui::NextColumn(); + ImGui::Text("??"); + ImGui::NextColumn(); + ImGui::Text("??"); + ImGui::NextColumn(); + break; + case xenos::VertexFormat::k_32_32_32_FLOAT: + ImGui::Text("%.3f", LOADEL(float, 0)); + ImGui::NextColumn(); + ImGui::Text("%.3f", LOADEL(float, 1)); + ImGui::NextColumn(); + ImGui::Text("%.3f", LOADEL(float, 2)); + ImGui::NextColumn(); + break; + case xenos::VertexFormat::k_8_8_8_8: + ImGui::Text("%.8X", LOADEL(uint32_t, 0)); + ImGui::NextColumn(); + break; + case xenos::VertexFormat::k_2_10_10_10: { + auto e0 = LOADEL(uint32_t, 0); + ImGui::Text("??"); + ImGui::NextColumn(); + ImGui::Text("??"); + ImGui::NextColumn(); + ImGui::Text("??"); + ImGui::NextColumn(); + ImGui::Text("??"); + ImGui::NextColumn(); + } break; + case xenos::VertexFormat::k_16_16_16_16: { + auto e0 = LOADEL(uint32_t, 0); + auto e1 = LOADEL(uint32_t, 1); + ImGui::Text("%.4X", (e0 >> 16) & 0xFFFF); + ImGui::NextColumn(); + ImGui::Text("%.4X", (e0 >> 0) & 0xFFFF); + ImGui::NextColumn(); + ImGui::Text("%.4X", (e1 >> 16) & 0xFFFF); + ImGui::NextColumn(); + ImGui::Text("%.4X", (e1 >> 0) & 0xFFFF); + ImGui::NextColumn(); + } break; + case xenos::VertexFormat::k_32_32_32_32: + ImGui::Text("%.8X", LOADEL(uint32_t, 0)); + ImGui::NextColumn(); + ImGui::Text("%.8X", LOADEL(uint32_t, 1)); + ImGui::NextColumn(); + ImGui::Text("%.8X", LOADEL(uint32_t, 2)); + ImGui::NextColumn(); + ImGui::Text("%.8X", LOADEL(uint32_t, 3)); + ImGui::NextColumn(); + break; + case xenos::VertexFormat::k_16_16_16_16_FLOAT: { + auto e0 = LOADEL(uint32_t, 0); + auto e1 = LOADEL(uint32_t, 1); + ImGui::Text("%.2f", half_float::detail::half2float((e0 >> 16) & 0xFFFF)); + ImGui::NextColumn(); + ImGui::Text("%.2f", half_float::detail::half2float((e0 >> 0) & 0xFFFF)); + ImGui::NextColumn(); + ImGui::Text("%.2f", half_float::detail::half2float((e1 >> 16) & 0xFFFF)); + ImGui::NextColumn(); + ImGui::Text("%.2f", half_float::detail::half2float((e1 >> 0) & 0xFFFF)); + ImGui::NextColumn(); + } break; + case xenos::VertexFormat::k_32_32_32_32_FLOAT: + ImGui::Text("%.3f", LOADEL(float, 0)); + ImGui::NextColumn(); + ImGui::Text("%.3f", LOADEL(float, 1)); + ImGui::NextColumn(); + ImGui::Text("%.3f", LOADEL(float, 2)); + ImGui::NextColumn(); + ImGui::Text("%.3f", LOADEL(float, 3)); + ImGui::NextColumn(); + break; + case xenos::VertexFormat::kUndefined: + assert_unhandled_case(attrib.fetch_instr.attributes.data_format); + break; + } + } + } + ImGui::Columns(1); + ImGui::Dummy(ImVec2(0, (vertex_count - display_end) * ImGui::GetTextLineHeight())); + ImGui::PopStyleVar(); + ImGui::EndChild(); +} + +static const char* kCompareFuncNames[] = { + "", "<", "==", "<=", ">", "!=", ">=", "", +}; +static const char* kStencilFuncNames[] = { + "Keep", + "Zero", + "Replace", + "Increment and Wrap", + "Decrement and Wrap", + "Invert", + "Increment and Clamp", + "Decrement and Clamp", +}; +static const char* kIndexFormatNames[] = { + "uint16", + "uint32", +}; +static const char* kEndiannessNames[] = { + "unspecified endianness", + "8-in-16", + "8-in-32", + "16-in-32", +}; +static const char* kColorFormatNames[] = { + /* 0 */ "k_8_8_8_8", + /* 1 */ "k_8_8_8_8_GAMMA", + /* 2 */ "k_2_10_10_10", + /* 3 */ "k_2_10_10_10_FLOAT", + /* 4 */ "k_16_16", + /* 5 */ "k_16_16_16_16", + /* 6 */ "k_16_16_FLOAT", + /* 7 */ "k_16_16_16_16_FLOAT", + /* 8 */ "unknown(8)", + /* 9 */ "unknown(9)", + /* 10 */ "k_2_10_10_10_AS_10_10_10_10", + /* 11 */ "unknown(11)", + /* 12 */ "k_2_10_10_10_FLOAT_AS_16_16_16_16", + /* 13 */ "unknown(13)", + /* 14 */ "k_32_FLOAT", + /* 15 */ "k_32_32_FLOAT", +}; +static const char* kDepthFormatNames[] = { + "kD24S8", + "kD24FS8", +}; + +void ProgressBar(float frac, float width, float height = 0, + const ImVec4& color = ImVec4(0, 1, 0, 1), + const ImVec4& border_color = ImVec4(0, 1, 0, 1)) { + if (height == 0) { + height = ImGui::GetTextLineHeightWithSpacing(); + } + frac = rex::saturate(frac); + + const auto fontAtlas = ImGui::GetIO().Fonts; + + auto pos = ImGui::GetCursorScreenPos(); + auto col = ImGui::ColorConvertFloat4ToU32(color); + auto border_col = ImGui::ColorConvertFloat4ToU32(border_color); + + if (frac > 0) { + // Progress bar + ImGui::GetWindowDrawList()->AddRectFilled(pos, ImVec2(pos.x + width * frac, pos.y + height), + col); + } + if (border_color.w > 0.f) { + // Border + ImGui::GetWindowDrawList()->AddRect(pos, ImVec2(pos.x + width, pos.y + height), border_col); + } + + ImGui::Dummy(ImVec2(width, height)); +} + +void ZoomedImage(ImTextureID tex, ImVec2 rel_pos, ImVec2 tex_size, float focus_size, + ImVec2 image_size = ImVec2(128, 128)) { + ImVec2 focus; + focus.x = rel_pos.x - (focus_size * 0.5f); + focus.y = rel_pos.y - (focus_size * 0.5f); + + ImVec2 uv0 = ImVec2(focus.x / tex_size.x, focus.y / tex_size.y); + ImVec2 uv1 = ImVec2((focus.x + focus_size) / tex_size.x, (focus.y + focus_size) / tex_size.y); + ImGui::Image(tex, image_size, uv0, uv1); +} + +void TraceViewer::DrawStateUI() { + auto command_processor = graphics_system_->command_processor(); + auto& regs = *graphics_system_->register_file(); + + ImGui::SetNextWindowPos(ImVec2(float(window_->GetActualLogicalWidth()) - 500 - 5, 30), + ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(500, 680)); + ImGui::SetNextWindowBgAlpha(kWindowBgAlpha); + if (!ImGui::Begin("State", nullptr)) { + ImGui::End(); + return; + } + + if (!player_->current_frame() || player_->current_command_index() == -1) { + ImGui::Text("No frame/command selected"); + ImGui::End(); + return; + } + + auto frame = player_->current_frame(); + const auto& command = frame->commands[player_->current_command_index()]; + auto packet_head = command.head_ptr + sizeof(PacketStartCommand); + uint32_t packet = memory::load_and_swap(packet_head); + uint32_t packet_type = packet >> 30; + assert_true(packet_type == 0x03); + uint32_t opcode = (packet >> 8) & 0x7F; + struct { + xenos::PrimitiveType prim_type; + bool is_auto_index; + uint32_t index_count; + uint32_t index_buffer_ptr; + uint32_t index_buffer_size; + xenos::Endian index_endianness; + xenos::IndexFormat index_format; + } draw_info; + std::memset(&draw_info, 0, sizeof(draw_info)); + switch (opcode) { + case PM4_DRAW_INDX: { + uint32_t dword0 = memory::load_and_swap(packet_head + 4); + uint32_t dword1 = memory::load_and_swap(packet_head + 8); + draw_info.index_count = dword1 >> 16; + draw_info.prim_type = static_cast(dword1 & 0x3F); + uint32_t src_sel = (dword1 >> 6) & 0x3; + if (src_sel == 0x0) { + // Indexed draw. + draw_info.is_auto_index = false; + draw_info.index_buffer_ptr = memory::load_and_swap(packet_head + 12); + uint32_t index_size = memory::load_and_swap(packet_head + 16); + draw_info.index_endianness = static_cast(index_size >> 30); + index_size &= 0x00FFFFFF; + bool index_32bit = (dword1 >> 11) & 0x1; + draw_info.index_format = + index_32bit ? xenos::IndexFormat::kInt32 : xenos::IndexFormat::kInt16; + draw_info.index_buffer_size = index_size * (index_32bit ? 4 : 2); + } else if (src_sel == 0x2) { + // Auto draw. + draw_info.is_auto_index = true; + } else { + // Unknown source select. + assert_always(); + } + break; + } + case PM4_DRAW_INDX_2: { + uint32_t dword0 = memory::load_and_swap(packet_head + 4); + uint32_t src_sel = (dword0 >> 6) & 0x3; + assert_true(src_sel == 0x2); // 'SrcSel=AutoIndex' + draw_info.prim_type = static_cast(dword0 & 0x3F); + draw_info.is_auto_index = true; + draw_info.index_count = dword0 >> 16; + break; + } + } + + if (player_->is_playing_trace()) { + ImGui::Text("Playing trace..."); + float width = ImGui::GetWindowWidth() - 20.f; + + ProgressBar(float(player_->playback_percent()) / 10000.f, width); + ImGui::End(); + return; + } + + auto enable_mode = static_cast(regs[XE_GPU_REG_RB_MODECONTROL] & 0x7); + + const char* mode_name = "Unknown"; + switch (enable_mode) { + case EdramMode::kNoOperation: + ImGui::Text("Ignored Command %d", player_->current_command_index()); + break; + case EdramMode::kColorDepth: + case EdramMode::kDepthOnly: { + static const char* kPrimNames[] = { + "", "point list", "line list", "line strip", + "triangle list", "triangle fan", "triangle strip", "unknown 0x7", + "rectangle list", "unknown 0x9", "unknown 0xA", "unknown 0xB", + "line loop", "quad list", "quad strip", "unknown 0xF", + }; + ImGui::Text("%s Command %d: %s, %d indices", + enable_mode == EdramMode::kColorDepth ? "Color-Depth" : "Depth-only", + player_->current_command_index(), kPrimNames[int(draw_info.prim_type)], + draw_info.index_count); + break; + } + case EdramMode::kCopy: { + uint32_t copy_dest_base = regs[XE_GPU_REG_RB_COPY_DEST_BASE]; + ImGui::Text("Copy Command %d (to %.8X)", player_->current_command_index(), copy_dest_base); + break; + } + } + + ImGui::Columns(2); + ImGui::BulletText("Viewport State:"); + if (true) { + ImGui::TreePush((const void*)0); + uint32_t pa_su_sc_mode_cntl = regs[XE_GPU_REG_PA_SU_SC_MODE_CNTL]; + if ((pa_su_sc_mode_cntl >> 16) & 1) { + uint32_t window_offset = regs[XE_GPU_REG_PA_SC_WINDOW_OFFSET]; + int16_t window_offset_x = window_offset & 0x7FFF; + int16_t window_offset_y = (window_offset >> 16) & 0x7FFF; + if (window_offset_x & 0x4000) { + window_offset_x |= 0x8000; + } + if (window_offset_y & 0x4000) { + window_offset_y |= 0x8000; + } + ImGui::BulletText("Window Offset: %d, %d", window_offset_x, window_offset_y); + } else { + ImGui::BulletText("Window Offset: disabled"); + } + uint32_t window_scissor_tl = regs[XE_GPU_REG_PA_SC_WINDOW_SCISSOR_TL]; + uint32_t window_scissor_br = regs[XE_GPU_REG_PA_SC_WINDOW_SCISSOR_BR]; + ImGui::BulletText("Window Scissor: %d,%d to %d,%d (%d x %d)", window_scissor_tl & 0x7FFF, + (window_scissor_tl >> 16) & 0x7FFF, window_scissor_br & 0x7FFF, + (window_scissor_br >> 16) & 0x7FFF, + (window_scissor_br & 0x7FFF) - (window_scissor_tl & 0x7FFF), + ((window_scissor_br >> 16) & 0x7FFF) - ((window_scissor_tl >> 16) & 0x7FFF)); + uint32_t surface_info = regs[XE_GPU_REG_RB_SURFACE_INFO]; + uint32_t surface_hiz = (surface_info >> 18) & 0x3FFF; + uint32_t surface_pitch = surface_info & 0x3FFF; + auto surface_msaa = (surface_info >> 16) & 0x3; + static const char* kMsaaNames[] = { + "1X", + "2X", + "4X", + }; + ImGui::BulletText("Surface Pitch: %d", surface_pitch); + ImGui::BulletText("Surface HI-Z Pitch: %d", surface_hiz); + ImGui::BulletText("Surface MSAA: %s", kMsaaNames[surface_msaa]); + uint32_t vte_control = regs[XE_GPU_REG_PA_CL_VTE_CNTL]; + bool vport_xscale_enable = (vte_control & (1 << 0)) > 0; + bool vport_xoffset_enable = (vte_control & (1 << 1)) > 0; + bool vport_yscale_enable = (vte_control & (1 << 2)) > 0; + bool vport_yoffset_enable = (vte_control & (1 << 3)) > 0; + bool vport_zscale_enable = (vte_control & (1 << 4)) > 0; + bool vport_zoffset_enable = (vte_control & (1 << 5)) > 0; + assert_true(vport_xscale_enable == vport_yscale_enable == vport_zscale_enable == + vport_xoffset_enable == vport_yoffset_enable == vport_zoffset_enable); + if (!vport_xscale_enable) { + ImGui::PushStyleColor(ImGuiCol_Text, kColorIgnored); + } + ImGui::BulletText( + "Viewport Offset: %f, %f, %f", + vport_xoffset_enable ? regs.Get(XE_GPU_REG_PA_CL_VPORT_XOFFSET) : 0.0f, + vport_yoffset_enable ? regs.Get(XE_GPU_REG_PA_CL_VPORT_YOFFSET) : 0.0f, + vport_zoffset_enable ? regs.Get(XE_GPU_REG_PA_CL_VPORT_ZOFFSET) : 0.0f); + ImGui::BulletText("Viewport Scale: %f, %f, %f", + vport_xscale_enable ? regs.Get(XE_GPU_REG_PA_CL_VPORT_XSCALE) : 1.0f, + vport_yscale_enable ? regs.Get(XE_GPU_REG_PA_CL_VPORT_YSCALE) : 1.0f, + vport_zscale_enable ? regs.Get(XE_GPU_REG_PA_CL_VPORT_ZSCALE) : 1.0f); + if (!vport_xscale_enable) { + ImGui::PopStyleColor(); + } + + ImGui::BulletText("Vertex Format: %s, %s, %s, %s", ((vte_control >> 8) & 0x1) ? "x/w0" : "x", + ((vte_control >> 8) & 0x1) ? "y/w0" : "y", + ((vte_control >> 9) & 0x1) ? "z/w0" : "z", + ((vte_control >> 10) & 0x1) ? "w0" : "1/w0"); + uint32_t clip_control = regs[XE_GPU_REG_PA_CL_CLIP_CNTL]; + bool clip_enabled = ((clip_control >> 17) & 0x1) == 0; + bool dx_clip = ((clip_control >> 20) & 0x1) == 0x1; + ImGui::BulletText("Clip Enabled: %s, DX Clip: %s", clip_enabled ? "true" : "false", + dx_clip ? "true" : "false"); + ImGui::TreePop(); + } + ImGui::NextColumn(); + ImGui::BulletText("Rasterizer State:"); + if (true) { + ImGui::TreePush((const void*)0); + uint32_t pa_su_sc_mode_cntl = regs[XE_GPU_REG_PA_SU_SC_MODE_CNTL]; + uint32_t pa_sc_screen_scissor_tl = regs[XE_GPU_REG_PA_SC_SCREEN_SCISSOR_TL]; + uint32_t pa_sc_screen_scissor_br = regs[XE_GPU_REG_PA_SC_SCREEN_SCISSOR_BR]; + if (pa_sc_screen_scissor_tl != 0 && pa_sc_screen_scissor_br != 0x20002000) { + int32_t screen_scissor_x = pa_sc_screen_scissor_tl & 0x7FFF; + int32_t screen_scissor_y = (pa_sc_screen_scissor_tl >> 16) & 0x7FFF; + int32_t screen_scissor_w = (pa_sc_screen_scissor_br & 0x7FFF) - screen_scissor_x; + int32_t screen_scissor_h = ((pa_sc_screen_scissor_br >> 16) & 0x7FFF) - screen_scissor_y; + ImGui::BulletText("Scissor: %d,%d to %d,%d (%d x %d)", screen_scissor_x, screen_scissor_y, + screen_scissor_x + screen_scissor_w, screen_scissor_y + screen_scissor_h, + screen_scissor_w, screen_scissor_h); + } else { + ImGui::BulletText("Scissor: disabled"); + } + switch (pa_su_sc_mode_cntl & 0x3) { + case 0: + ImGui::BulletText("Culling: disabled"); + break; + case 1: + ImGui::BulletText("Culling: front-face"); + break; + case 2: + ImGui::BulletText("Culling: back-face"); + break; + } + if (pa_su_sc_mode_cntl & 0x4) { + ImGui::BulletText("Front-face: clockwise"); + } else { + ImGui::BulletText("Front-face: counter-clockwise"); + } + static const char* kFillModeNames[3] = { + "point", + "line", + "fill", + }; + bool poly_mode = ((pa_su_sc_mode_cntl >> 3) & 0x3) != 0; + if (poly_mode) { + uint32_t front_poly_mode = (pa_su_sc_mode_cntl >> 5) & 0x7; + uint32_t back_poly_mode = (pa_su_sc_mode_cntl >> 8) & 0x7; + // GL only supports both matching. + assert_true(front_poly_mode == back_poly_mode); + ImGui::BulletText("Polygon Mode: %s", kFillModeNames[front_poly_mode]); + } else { + ImGui::BulletText("Polygon Mode: fill"); + } + if (pa_su_sc_mode_cntl & (1 << 19)) { + ImGui::BulletText("Provoking Vertex: last"); + } else { + ImGui::BulletText("Provoking Vertex: first"); + } + ImGui::TreePop(); + } + ImGui::Columns(1); + + auto rb_surface_info = regs[XE_GPU_REG_RB_SURFACE_INFO]; + uint32_t surface_pitch = rb_surface_info & 0x3FFF; + auto surface_msaa = static_cast((rb_surface_info >> 16) & 0x3); + + if (ImGui::CollapsingHeader("Color Targets")) { + if (enable_mode != EdramMode::kDepthOnly) { + // Alpha testing -- ALPHAREF, ALPHAFUNC, ALPHATESTENABLE + // if(ALPHATESTENABLE && frag_out.a [<=/ALPHAFUNC] ALPHAREF) discard; + uint32_t color_control = regs[XE_GPU_REG_RB_COLORCONTROL]; + if ((color_control & 0x8) != 0) { + ImGui::BulletText("Alpha Test: %s %.2f", kCompareFuncNames[color_control & 0x7], + regs.Get(XE_GPU_REG_RB_ALPHA_REF)); + } else { + ImGui::PushStyleColor(ImGuiCol_Text, kColorIgnored); + ImGui::BulletText("Alpha Test: disabled"); + ImGui::PopStyleColor(); + } + + auto blend_color = ImVec4( + regs.Get(XE_GPU_REG_RB_BLEND_RED), regs.Get(XE_GPU_REG_RB_BLEND_GREEN), + regs.Get(XE_GPU_REG_RB_BLEND_BLUE), regs.Get(XE_GPU_REG_RB_BLEND_ALPHA)); + ImGui::BulletText("Blend Color: (%.2f,%.2f,%.2f,%.2f)", blend_color.x, blend_color.y, + blend_color.z, blend_color.w); + ImGui::SameLine(); + // TODO small_height (was true) parameter was removed + ImGui::ColorButton(nullptr, blend_color); + + uint32_t rb_color_mask = regs[XE_GPU_REG_RB_COLOR_MASK]; + uint32_t color_info[4] = { + regs[XE_GPU_REG_RB_COLOR_INFO], + regs[XE_GPU_REG_RB_COLOR1_INFO], + regs[XE_GPU_REG_RB_COLOR2_INFO], + regs[XE_GPU_REG_RB_COLOR3_INFO], + }; + uint32_t rb_blendcontrol[4] = { + regs[XE_GPU_REG_RB_BLENDCONTROL0], + regs[XE_GPU_REG_RB_BLENDCONTROL1], + regs[XE_GPU_REG_RB_BLENDCONTROL2], + regs[XE_GPU_REG_RB_BLENDCONTROL3], + }; + ImGui::Columns(2); + for (int i = 0; i < rex::countof(color_info); ++i) { + uint32_t blend_control = rb_blendcontrol[i]; + // A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND + auto src_blend = (blend_control & 0x0000001F) >> 0; + // A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND + auto dest_blend = (blend_control & 0x00001F00) >> 8; + // A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN + auto blend_op = (blend_control & 0x000000E0) >> 5; + // A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND + auto src_blend_alpha = (blend_control & 0x001F0000) >> 16; + // A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND + auto dest_blend_alpha = (blend_control & 0x1F000000) >> 24; + // A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN + auto blend_op_alpha = (blend_control & 0x00E00000) >> 21; + // A2XX_RB_COLORCONTROL_BLEND_DISABLE ?? Can't find this! + // Just guess based on actions. + bool blend_enable = + !((src_blend == 1) && (dest_blend == 0) && (blend_op == 0) && (src_blend_alpha == 1) && + (dest_blend_alpha == 0) && (blend_op_alpha == 0)); + if (blend_enable) { + if (src_blend == src_blend_alpha && dest_blend == dest_blend_alpha && + blend_op == blend_op_alpha) { + ImGui::BulletText("Blend %d: ", i); + ImGui::SameLine(); + DrawBlendMode(src_blend, dest_blend, blend_op); + } else { + ImGui::BulletText("Blend %d:", i); + ImGui::BulletText(" Color: "); + ImGui::SameLine(); + DrawBlendMode(src_blend, dest_blend, blend_op); + ImGui::BulletText(" Alpha: "); + ImGui::SameLine(); + DrawBlendMode(src_blend_alpha, dest_blend_alpha, blend_op_alpha); + } + } else { + ImGui::PushStyleColor(ImGuiCol_Text, kColorIgnored); + ImGui::BulletText("Blend %d: disabled", i); + ImGui::PopStyleColor(); + } + ImGui::NextColumn(); + uint32_t write_mask = (rb_color_mask >> (i * 4)) & 0xF; + if (write_mask) { + ImGui::BulletText( + "Write Mask %d: %s, %s, %s, %s", i, !!(write_mask & 0x1) ? "true" : "false", + !!(write_mask & 0x2) ? "true" : "false", !!(write_mask & 0x4) ? "true" : "false", + !!(write_mask & 0x8) ? "true" : "false"); + } else { + ImGui::PushStyleColor(ImGuiCol_Text, kColorIgnored); + ImGui::BulletText("Write Mask %d: disabled", i); + ImGui::PopStyleColor(); + } + ImGui::NextColumn(); + } + ImGui::Columns(1); + + ImGui::Columns(4); + for (int i = 0; i < rex::countof(color_info); ++i) { + uint32_t write_mask = (rb_color_mask >> (i * 4)) & 0xF; + uint32_t color_base = color_info[i] & 0xFFF; + auto color_format = + static_cast((color_info[i] >> 16) & 0xF); + ImVec2 button_pos = ImGui::GetCursorScreenPos(); + ImVec2 button_size(256, 256); + ImTextureID tex = 0; + ImGui::PushID(i); + if (write_mask) { + auto color_target = + GetColorRenderTarget(surface_pitch, surface_msaa, color_base, color_format); + tex = ImTextureID(color_target); + if (ImGui::ImageButton("#color_image", tex, button_size, ImVec2(0, 0), ImVec2(1, 1))) { + // show viewer + } + } else { + ImGui::ImageButton("#color_image", ImTextureID(0), button_size, ImVec2(0, 0), + ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(0, 0, 0, 0)); + } + ImGui::PopID(); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::Text("Color Target %d (%s), base %.4X, pitch %d, format %s", i, + write_mask ? "enabled" : "disabled", color_base, surface_pitch, + kColorFormatNames[uint32_t(color_format)]); + + if (tex) { + ImVec2 rel_pos; + rel_pos.x = ImGui::GetMousePos().x - button_pos.x; + rel_pos.y = ImGui::GetMousePos().y - button_pos.y; + ZoomedImage(tex, rel_pos, button_size, 32.f, ImVec2(256, 256)); + } + + ImGui::EndTooltip(); + } + ImGui::NextColumn(); + } + ImGui::Columns(1); + } else { + ImGui::PushStyleColor(ImGuiCol_Text, kColorIgnored); + ImGui::Text("Depth-only mode, no color targets"); + ImGui::PopStyleColor(); + } + } + + if (ImGui::CollapsingHeader("Depth/Stencil Target")) { + auto rb_depthcontrol = regs[XE_GPU_REG_RB_DEPTHCONTROL]; + auto rb_stencilrefmask = regs[XE_GPU_REG_RB_STENCILREFMASK]; + auto rb_depth_info = regs[XE_GPU_REG_RB_DEPTH_INFO]; + bool uses_depth = (rb_depthcontrol & 0x00000002) || (rb_depthcontrol & 0x00000004); + uint32_t stencil_ref = (rb_stencilrefmask & 0xFF); + uint32_t stencil_read_mask = (rb_stencilrefmask >> 8) & 0xFF; + uint32_t stencil_write_mask = (rb_stencilrefmask >> 16) & 0xFF; + bool uses_stencil = (rb_depthcontrol & 0x00000001) || (stencil_write_mask != 0); + + ImGui::Columns(2); + + if (rb_depthcontrol & 0x00000002) { + ImGui::BulletText("Depth Test: enabled"); + } else { + ImGui::PushStyleColor(ImGuiCol_Text, kColorIgnored); + ImGui::BulletText("Depth Test: disabled"); + } + ImGui::BulletText("Depth Func: %s", kCompareFuncNames[(rb_depthcontrol & 0x00000070) >> 4]); + if (!(rb_depthcontrol & 0x00000002)) { + ImGui::PopStyleColor(); + } + if (rb_depthcontrol & 0x00000004) { + ImGui::BulletText("Depth Write: enabled"); + } else { + ImGui::PushStyleColor(ImGuiCol_Text, kColorIgnored); + ImGui::BulletText("Depth Write: disabled"); + ImGui::PopStyleColor(); + } + + if (rb_depthcontrol & 0x00000001) { + ImGui::BulletText("Stencil Test: enabled"); + ImGui::BulletText("Stencil ref: 0x%.2X", stencil_ref); + ImGui::BulletText("Stencil read / write masks: 0x%.2X / 0x%.2X", stencil_read_mask, + stencil_write_mask); + ImGui::BulletText("Front State:"); + ImGui::Indent(); + ImGui::BulletText("Compare Op: %s", kCompareFuncNames[(rb_depthcontrol >> 8) & 0x7]); + ImGui::BulletText("Fail Op: %s", kStencilFuncNames[(rb_depthcontrol >> 11) & 0x7]); + ImGui::BulletText("Pass Op: %s", kStencilFuncNames[(rb_depthcontrol >> 14) & 0x7]); + ImGui::BulletText("Depth Fail Op: %s", kStencilFuncNames[(rb_depthcontrol >> 17) & 0x7]); + ImGui::Unindent(); + + // BACKFACE_ENABLE + if (!(rb_depthcontrol & 0x80)) { + ImGui::PushStyleColor(ImGuiCol_Text, kColorIgnored); + ImGui::BulletText("Back State (same as front)"); + ImGui::PopStyleColor(); + } else { + ImGui::BulletText("Back State:"); + ImGui::Indent(); + ImGui::BulletText("Compare Op: %s", kCompareFuncNames[(rb_depthcontrol >> 20) & 0x7]); + ImGui::BulletText("Fail Op: %s", kStencilFuncNames[(rb_depthcontrol >> 23) & 0x7]); + ImGui::BulletText("Pass Op: %s", kStencilFuncNames[(rb_depthcontrol >> 26) & 0x7]); + ImGui::BulletText("Depth Fail Op: %s", kStencilFuncNames[(rb_depthcontrol >> 29) & 0x7]); + ImGui::Unindent(); + } + } else { + ImGui::PushStyleColor(ImGuiCol_Text, kColorIgnored); + ImGui::BulletText("Stencil Test: disabled"); + ImGui::PopStyleColor(); + } + + ImGui::NextColumn(); + + if (uses_depth || uses_stencil) { + uint32_t depth_base = rb_depth_info & 0xFFF; + auto depth_format = static_cast((rb_depth_info >> 16) & 0x1); + auto depth_target = + GetDepthRenderTarget(surface_pitch, surface_msaa, depth_base, depth_format); + + auto button_pos = ImGui::GetCursorScreenPos(); + ImVec2 button_size(256, 256); + ImGui::ImageButton("#depth_stencil_image", ImTextureID(depth_target), button_size, + ImVec2(0, 0), ImVec2(1, 1)); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + + ImGui::Text("Depth Target: base %.4X, pitch %d, format %s", depth_base, surface_pitch, + kDepthFormatNames[uint32_t(depth_format)]); + + ImVec2 rel_pos; + rel_pos.x = ImGui::GetMousePos().x - button_pos.x; + rel_pos.y = ImGui::GetMousePos().y - button_pos.y; + ZoomedImage(ImTextureID(depth_target), rel_pos, button_size, 32.f, ImVec2(256, 256)); + + ImGui::EndTooltip(); + } + } else { + ImGui::Text("No depth target"); + } + + ImGui::Columns(1); + } + + if (ImGui::CollapsingHeader("Vertex Shader")) { + ShaderDisplayType shader_display_type = DrawShaderTypeUI(); + ImGui::BeginChild("#vertex_shader_text", ImVec2(0, 400)); + auto shader = command_processor->active_vertex_shader(); + if (shader) { + DrawShaderUI(shader, shader_display_type); + } else { + ImGui::TextColored(kColorError, "ERROR: no vertex shader set"); + } + ImGui::EndChild(); + } + if (ImGui::CollapsingHeader("Vertex Shader Output") && QueryVSOutputElementSize()) { + auto size = QueryVSOutputSize(); + auto el_size = QueryVSOutputElementSize(); + if (size > 0) { + std::vector vertices; + vertices.resize(size / 4); + QueryVSOutput(vertices.data(), size); + + ImGui::Text("%" PRIu64 " output vertices", vertices.size() / 4); + ImGui::SameLine(); + static bool normalize = false; + ImGui::Checkbox("Normalize", &normalize); + + ImGui::BeginChild("#vsvertices", ImVec2(0, 300)); + + int display_start, display_end; + ImGui::CalcListClipping(int(vertices.size() / 4), ImGui::GetTextLineHeight(), &display_start, + &display_end); + ImGui::Dummy(ImVec2(0, (display_start)*ImGui::GetTextLineHeight())); + + ImGui::Columns(int(el_size), "#vsvertices", true); + for (size_t i = display_start; i < display_end; i++) { + size_t start_vtx = i * el_size; + float verts[4] = {vertices[start_vtx], vertices[start_vtx + 1], vertices[start_vtx + 2], + vertices[start_vtx + 3]}; + assert_true(el_size <= rex::countof(verts)); + if (normalize) { + for (int j = 0; j < el_size; j++) { + verts[j] /= verts[3]; + } + } + + for (int j = 0; j < el_size; j++) { + ImGui::Text("%.3f", verts[j]); + ImGui::NextColumn(); + } + } + ImGui::Columns(1); + + ImGui::Dummy(ImVec2(0, ((vertices.size() / 4) - display_end) * ImGui::GetTextLineHeight())); + ImGui::EndChild(); + } else { + ImGui::Text("No vertex shader output"); + } + } + if (ImGui::CollapsingHeader("Pixel Shader")) { + ShaderDisplayType shader_display_type = DrawShaderTypeUI(); + ImGui::BeginChild("#pixel_shader_text", ImVec2(0, 400)); + auto shader = command_processor->active_pixel_shader(); + if (shader) { + DrawShaderUI(shader, shader_display_type); + } else { + ImGui::TextColored(kColorError, "ERROR: no pixel shader set"); + } + ImGui::EndChild(); + } + if (ImGui::CollapsingHeader("Index Buffer")) { + if (draw_info.is_auto_index) { + ImGui::Text("%d indices, auto-indexed", draw_info.index_count); + } else { + ImGui::Text("%d indices from buffer %.8X (%db), %s, %s", draw_info.index_count, + draw_info.index_buffer_ptr, draw_info.index_buffer_size, + kIndexFormatNames[int(draw_info.index_format)], + kEndiannessNames[int(draw_info.index_endianness)]); + uint32_t pa_su_sc_mode_cntl = regs[XE_GPU_REG_PA_SU_SC_MODE_CNTL]; + if (pa_su_sc_mode_cntl & (1 << 21)) { + uint32_t reset_index = regs[XE_GPU_REG_VGT_MULTI_PRIM_IB_RESET_INDX]; + if (draw_info.index_format == xenos::IndexFormat::kInt16) { + ImGui::Text("Reset Index: %.4X", reset_index & 0xFFFF); + } else { + ImGui::Text("Reset Index: %.8X", reset_index); + } + } else { + ImGui::Text("Reset Index: disabled"); + } + ImGui::BeginChild("#indices", ImVec2(0, 300)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); + int display_start, display_end; + ImGui::CalcListClipping(1 + draw_info.index_count, ImGui::GetTextLineHeight(), &display_start, + &display_end); + ImGui::Dummy(ImVec2(0, (display_start)*ImGui::GetTextLineHeight())); + ImGui::Columns(2, "#indices", true); + ImGui::SetColumnOffset(1, 60); + if (display_start <= 1) { + ImGui::Text("Ordinal"); + ImGui::NextColumn(); + ImGui::Text(" Value"); + ImGui::NextColumn(); + ImGui::Separator(); + } + uint32_t element_size = draw_info.index_format == xenos::IndexFormat::kInt32 ? 4 : 2; + const uint8_t* data_ptr = + memory_->TranslatePhysical(draw_info.index_buffer_ptr + (display_start * element_size)); + for (int i = display_start; i < display_end; ++i, data_ptr += element_size) { + if (i < 10) { + ImGui::Text(" %d", i); + } else if (i < 100) { + ImGui::Text(" %d", i); + } else if (i < 1000) { + ImGui::Text(" %d", i); + } else { + ImGui::Text(" %d", i); + } + ImGui::NextColumn(); + uint32_t value = + element_size == 4 + ? GpuSwap(memory::load(data_ptr), draw_info.index_endianness) + : GpuSwap(memory::load(data_ptr), draw_info.index_endianness); + ImGui::Text(" %d", value); + ImGui::NextColumn(); + } + ImGui::Columns(1); + ImGui::Dummy(ImVec2(0, (draw_info.index_count - display_end) * ImGui::GetTextLineHeight())); + ImGui::PopStyleVar(); + ImGui::EndChild(); + } + } + if (ImGui::CollapsingHeader("Vertex Buffers")) { + auto shader = command_processor->active_vertex_shader(); + if (shader) { + for (const auto& vertex_binding : shader->vertex_bindings()) { + xe_gpu_vertex_fetch_t fetch = regs.GetVertexFetch(vertex_binding.fetch_constant); + assert_true(fetch.endian == xenos::Endian::k8in32); + char tree_root_id[32]; + sprintf(tree_root_id, "#vertices_root_%d", vertex_binding.fetch_constant); + if (ImGui::TreeNode(tree_root_id, "vf%d: 0x%.8X (%db), %s", vertex_binding.fetch_constant, + fetch.address << 2, fetch.size * 4, + kEndiannessNames[int(fetch.endian)])) { + ImGui::BeginChild("#vertices", ImVec2(0, 300)); + DrawVertexFetcher(shader, vertex_binding, fetch); + ImGui::EndChild(); + ImGui::TreePop(); + } + } + } else { + ImGui::TextColored(kColorError, "ERROR: no vertex shader set"); + } + } + if (ImGui::CollapsingHeader("Vertex Textures")) { + auto shader = command_processor->active_vertex_shader(); + if (shader) { + const auto& texture_bindings = shader->texture_bindings(); + if (!texture_bindings.empty()) { + for (const auto& texture_binding : texture_bindings) { + DrawTextureInfo(texture_binding); + } + } else { + ImGui::Text("No vertex shader samplers"); + } + } else { + ImGui::TextColored(kColorError, "ERROR: no vertex shader set"); + } + } + if (ImGui::CollapsingHeader("Pixel Textures")) { + auto shader = command_processor->active_pixel_shader(); + if (shader) { + const auto& texture_bindings = shader->texture_bindings(); + if (!texture_bindings.empty()) { + for (const auto& texture_binding : texture_bindings) { + DrawTextureInfo(texture_binding); + } + } else { + ImGui::Text("No pixel shader samplers"); + } + } else { + ImGui::TextColored(kColorError, "ERROR: no pixel shader set"); + } + } + if (ImGui::CollapsingHeader("Fetch Constants (raw)")) { + ImGui::Columns(2); + for (int i = XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0; i <= XE_GPU_REG_SHADER_CONSTANT_FETCH_31_5; + ++i) { + ImGui::Text("f%02d_%d", (i - XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0) / 6, + (i - XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0) % 6); + ImGui::NextColumn(); + ImGui::Text("%.8X", regs[i]); + ImGui::NextColumn(); + } + ImGui::Columns(1); + } + if (ImGui::CollapsingHeader("ALU Constants")) { + ImGui::Columns(2); + for (int i = XE_GPU_REG_SHADER_CONSTANT_000_X; i <= XE_GPU_REG_SHADER_CONSTANT_511_X; i += 4) { + ImGui::Text("c%d", (i - XE_GPU_REG_SHADER_CONSTANT_000_X) / 4); + ImGui::NextColumn(); + ImGui::Text("%f, %f, %f, %f", regs.Get(i + 0), regs.Get(i + 1), + regs.Get(i + 2), regs.Get(i + 3)); + ImGui::NextColumn(); + } + ImGui::Columns(1); + } + if (ImGui::CollapsingHeader("Bool Constants")) { + ImGui::Columns(2); + for (int i = XE_GPU_REG_SHADER_CONSTANT_BOOL_000_031; + i <= XE_GPU_REG_SHADER_CONSTANT_BOOL_224_255; ++i) { + ImGui::Text("b%03d-%03d", (i - XE_GPU_REG_SHADER_CONSTANT_BOOL_000_031) * 32, + (i - XE_GPU_REG_SHADER_CONSTANT_BOOL_000_031) * 32 + 31); + ImGui::NextColumn(); + ImGui::Text("%.8X", regs[i]); + ImGui::NextColumn(); + } + ImGui::Columns(1); + } + if (ImGui::CollapsingHeader("Loop Constants")) { + ImGui::Columns(2); + for (int i = XE_GPU_REG_SHADER_CONSTANT_LOOP_00; i <= XE_GPU_REG_SHADER_CONSTANT_LOOP_31; ++i) { + ImGui::Text("l%d", i - XE_GPU_REG_SHADER_CONSTANT_LOOP_00); + ImGui::NextColumn(); + ImGui::Text("%.8X", regs[i]); + ImGui::NextColumn(); + } + ImGui::Columns(1); + } + ImGui::End(); +} + +} // namespace rex::graphics diff --git a/src/graphics/trace_writer.cpp b/src/graphics/trace_writer.cpp new file mode 100644 index 0000000..2a35689 --- /dev/null +++ b/src/graphics/trace_writer.cpp @@ -0,0 +1,370 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include + +// TODO(tomc): Enable on other platforms once the RTTI linking issue is resolved +#ifdef _WIN32 +#define REX_TRACE_USE_SNAPPY 1 +#include "snappy-sinksource.h" +#include "snappy.h" +#endif + +#include +#include +#include +#include +#include + +namespace rex::graphics { + +TraceWriter::TraceWriter(uint8_t* membase) : membase_(membase), file_(nullptr) {} + +TraceWriter::~TraceWriter() = default; + +bool TraceWriter::Open(const std::filesystem::path& path, uint32_t title_id) { + Close(); + + auto canonical_path = std::filesystem::absolute(path); + if (canonical_path.has_parent_path()) { + auto base_path = canonical_path.parent_path(); + std::filesystem::create_directories(base_path); + } + +#ifdef _WIN32 + file_ = _wfopen(canonical_path.c_str(), L"wb"); +#else + file_ = std::fopen(canonical_path.c_str(), "wb"); +#endif + if (!file_) { + REXGPU_ERROR("TraceWriter: Failed to open trace file: {}", canonical_path.string()); + return false; + } + + REXGPU_INFO("TraceWriter: Opened trace file: {}", canonical_path.string()); + + // Write header first. Must be at the top of the file. + TraceHeader header; + header.version = kTraceFormatVersion; + // Use a static commit string for rexglue + std::memset(header.build_commit_sha, 0, sizeof(header.build_commit_sha)); + std::strncpy(header.build_commit_sha, "rexglue-dev", sizeof(header.build_commit_sha) - 1); + header.title_id = title_id; + fwrite(&header, sizeof(header), 1, file_); + + cached_memory_reads_.clear(); + return true; +} + +void TraceWriter::Flush() { + if (file_) { + fflush(file_); + } +} + +void TraceWriter::Close() { + if (file_) { + cached_memory_reads_.clear(); + + fflush(file_); + fclose(file_); + file_ = nullptr; + REXGPU_INFO("TraceWriter: Closed trace file"); + } +} + +void TraceWriter::WritePrimaryBufferStart(uint32_t base_ptr, uint32_t count) { + if (!file_) { + return; + } + PrimaryBufferStartCommand cmd = { + TraceCommandType::kPrimaryBufferStart, + base_ptr, + 0, + }; + fwrite(&cmd, 1, sizeof(cmd), file_); +} + +void TraceWriter::WritePrimaryBufferEnd() { + if (!file_) { + return; + } + PrimaryBufferEndCommand cmd = { + TraceCommandType::kPrimaryBufferEnd, + }; + fwrite(&cmd, 1, sizeof(cmd), file_); +} + +void TraceWriter::WriteIndirectBufferStart(uint32_t base_ptr, uint32_t count) { + if (!file_) { + return; + } + IndirectBufferStartCommand cmd = { + TraceCommandType::kIndirectBufferStart, + base_ptr, + 0, + }; + fwrite(&cmd, 1, sizeof(cmd), file_); +} + +void TraceWriter::WriteIndirectBufferEnd() { + if (!file_) { + return; + } + IndirectBufferEndCommand cmd = { + TraceCommandType::kIndirectBufferEnd, + }; + fwrite(&cmd, 1, sizeof(cmd), file_); +} + +void TraceWriter::WritePacketStart(uint32_t base_ptr, uint32_t count) { + if (!file_) { + return; + } + PacketStartCommand cmd = { + TraceCommandType::kPacketStart, + base_ptr, + count, + }; + fwrite(&cmd, 1, sizeof(cmd), file_); + fwrite(membase_ + base_ptr, 4, count, file_); +} + +void TraceWriter::WritePacketEnd() { + if (!file_) { + return; + } + PacketEndCommand cmd = { + TraceCommandType::kPacketEnd, + }; + fwrite(&cmd, 1, sizeof(cmd), file_); +} + +void TraceWriter::WriteMemoryRead(uint32_t base_ptr, size_t length, const void* host_ptr) { + if (!file_) { + return; + } + WriteMemoryCommand(TraceCommandType::kMemoryRead, base_ptr, length, host_ptr); +} + +void TraceWriter::WriteMemoryReadCached(uint32_t base_ptr, size_t length) { + if (!file_) { + return; + } + + // HACK: length is guaranteed to be within 32-bits (guest memory) + uint64_t key = uint64_t(base_ptr) << 32 | uint64_t(length); + if (cached_memory_reads_.find(key) == cached_memory_reads_.end()) { + WriteMemoryCommand(TraceCommandType::kMemoryRead, base_ptr, length); + cached_memory_reads_.insert(key); + } +} + +void TraceWriter::WriteMemoryReadCachedNop(uint32_t base_ptr, size_t length) { + if (!file_) { + return; + } + + // HACK: length is guaranteed to be within 32-bits (guest memory) + uint64_t key = uint64_t(base_ptr) << 32 | uint64_t(length); + if (cached_memory_reads_.find(key) == cached_memory_reads_.end()) { + cached_memory_reads_.insert(key); + } +} + +void TraceWriter::WriteMemoryWrite(uint32_t base_ptr, size_t length, const void* host_ptr) { + if (!file_) { + return; + } + WriteMemoryCommand(TraceCommandType::kMemoryWrite, base_ptr, length, host_ptr); +} + +#if REX_TRACE_USE_SNAPPY +class SnappySink : public snappy::Sink { + public: + SnappySink(FILE* file) : file_(file) {} + + void Append(const char* bytes, size_t n) override { fwrite(bytes, 1, n, file_); } + + private: + FILE* file_ = nullptr; +}; +#endif + +void TraceWriter::WriteMemoryCommand(TraceCommandType type, uint32_t base_ptr, size_t length, + const void* host_ptr) { + MemoryCommand cmd = {}; + cmd.type = type; + cmd.base_ptr = base_ptr; + cmd.encoding_format = MemoryEncodingFormat::kNone; + cmd.encoded_length = cmd.decoded_length = static_cast(length); + + if (!host_ptr) { + host_ptr = membase_ + cmd.base_ptr; + } + +#if REX_TRACE_USE_SNAPPY + bool compress = compress_output_ && length > compression_threshold_; + if (compress) { + // Write the header now so we reserve space in the buffer. + long header_position = std::ftell(file_); + cmd.encoding_format = MemoryEncodingFormat::kSnappy; + fwrite(&cmd, 1, sizeof(cmd), file_); + + // Stream the content right to the buffer. + snappy::ByteArraySource snappy_source(reinterpret_cast(host_ptr), + cmd.decoded_length); + SnappySink snappy_sink(file_); + cmd.encoded_length = static_cast(snappy::Compress(&snappy_source, &snappy_sink)); + + // Seek back and overwrite the header with our final size. + std::fseek(file_, header_position, SEEK_SET); + fwrite(&cmd, 1, sizeof(cmd), file_); + std::fseek(file_, header_position + sizeof(cmd) + cmd.encoded_length, SEEK_SET); + } else +#endif + { + // Uncompressed - write buffer directly to the file. + cmd.encoding_format = MemoryEncodingFormat::kNone; + fwrite(&cmd, 1, sizeof(cmd), file_); + fwrite(host_ptr, 1, cmd.decoded_length, file_); + } +} + +void TraceWriter::WriteEdramSnapshot(const void* snapshot) { + EdramSnapshotCommand cmd = {}; + cmd.type = TraceCommandType::kEdramSnapshot; + +#if REX_TRACE_USE_SNAPPY + if (compress_output_) { + // Write the header now so we reserve space in the buffer. + long header_position = std::ftell(file_); + cmd.encoding_format = MemoryEncodingFormat::kSnappy; + fwrite(&cmd, 1, sizeof(cmd), file_); + + // Stream the content right to the buffer. + snappy::ByteArraySource snappy_source(reinterpret_cast(snapshot), + xenos::kEdramSizeBytes); + SnappySink snappy_sink(file_); + cmd.encoded_length = static_cast(snappy::Compress(&snappy_source, &snappy_sink)); + + // Seek back and overwrite the header with our final size. + std::fseek(file_, header_position, SEEK_SET); + fwrite(&cmd, 1, sizeof(cmd), file_); + std::fseek(file_, header_position + sizeof(cmd) + cmd.encoded_length, SEEK_SET); + } else +#endif + { + // Uncompressed - write buffer directly to the file. + cmd.encoding_format = MemoryEncodingFormat::kNone; + cmd.encoded_length = xenos::kEdramSizeBytes; + fwrite(&cmd, 1, sizeof(cmd), file_); + fwrite(snapshot, 1, xenos::kEdramSizeBytes, file_); + } +} + +void TraceWriter::WriteEvent(EventCommand::Type event_type) { + if (!file_) { + return; + } + EventCommand cmd = { + TraceCommandType::kEvent, + event_type, + }; + fwrite(&cmd, 1, sizeof(cmd), file_); +} + +void TraceWriter::WriteRegisters(uint32_t first_register, const uint32_t* register_values, + uint32_t register_count, bool execute_callbacks_on_play) { + RegistersCommand cmd = {}; + cmd.type = TraceCommandType::kRegisters; + cmd.first_register = first_register; + cmd.register_count = register_count; + cmd.execute_callbacks = execute_callbacks_on_play; + + uint32_t uncompressed_length = uint32_t(sizeof(uint32_t) * register_count); +#if REX_TRACE_USE_SNAPPY + if (compress_output_) { + // Write the header now so we reserve space in the buffer. + long header_position = std::ftell(file_); + cmd.encoding_format = MemoryEncodingFormat::kSnappy; + fwrite(&cmd, 1, sizeof(cmd), file_); + + // Stream the content right to the buffer. + snappy::ByteArraySource snappy_source(reinterpret_cast(register_values), + uncompressed_length); + SnappySink snappy_sink(file_); + cmd.encoded_length = static_cast(snappy::Compress(&snappy_source, &snappy_sink)); + + // Seek back and overwrite the header with our final size. + std::fseek(file_, header_position, SEEK_SET); + fwrite(&cmd, 1, sizeof(cmd), file_); + std::fseek(file_, header_position + sizeof(cmd) + cmd.encoded_length, SEEK_SET); + } else +#endif + { + // Uncompressed - write the values directly to the file. + cmd.encoding_format = MemoryEncodingFormat::kNone; + cmd.encoded_length = uncompressed_length; + fwrite(&cmd, 1, sizeof(cmd), file_); + fwrite(register_values, 1, uncompressed_length, file_); + } +} + +void TraceWriter::WriteGammaRamp(const reg::DC_LUT_30_COLOR* gamma_ramp_256_entry_table, + const reg::DC_LUT_PWL_DATA* gamma_ramp_pwl_rgb, + uint32_t gamma_ramp_rw_component) { + GammaRampCommand cmd = {}; + cmd.type = TraceCommandType::kGammaRamp; + cmd.rw_component = uint8_t(gamma_ramp_rw_component); + + constexpr uint32_t k256EntryTableUncompressedLength = sizeof(reg::DC_LUT_30_COLOR) * 256; + constexpr uint32_t kPWLUncompressedLength = sizeof(reg::DC_LUT_PWL_DATA) * 3 * 128; + constexpr uint32_t kUncompressedLength = + k256EntryTableUncompressedLength + kPWLUncompressedLength; +#if REX_TRACE_USE_SNAPPY + if (compress_output_) { + // Write the header now so we reserve space in the buffer. + long header_position = std::ftell(file_); + cmd.encoding_format = MemoryEncodingFormat::kSnappy; + fwrite(&cmd, 1, sizeof(cmd), file_); + + // Stream the content right to the buffer. + { + std::unique_ptr gamma_ramps(new char[kUncompressedLength]); + std::memcpy(gamma_ramps.get(), gamma_ramp_256_entry_table, k256EntryTableUncompressedLength); + std::memcpy(gamma_ramps.get() + k256EntryTableUncompressedLength, gamma_ramp_pwl_rgb, + kPWLUncompressedLength); + snappy::ByteArraySource snappy_source(gamma_ramps.get(), kUncompressedLength); + SnappySink snappy_sink(file_); + cmd.encoded_length = static_cast(snappy::Compress(&snappy_source, &snappy_sink)); + } + + // Seek back and overwrite the header with our final size. + std::fseek(file_, header_position, SEEK_SET); + fwrite(&cmd, 1, sizeof(cmd), file_); + std::fseek(file_, header_position + sizeof(cmd) + cmd.encoded_length, SEEK_SET); + } else +#endif + { + // Uncompressed - write the values directly to the file. + cmd.encoding_format = MemoryEncodingFormat::kNone; + cmd.encoded_length = kUncompressedLength; + fwrite(&cmd, 1, sizeof(cmd), file_); + fwrite(gamma_ramp_256_entry_table, 1, k256EntryTableUncompressedLength, file_); + fwrite(gamma_ramp_pwl_rgb, 1, kPWLUncompressedLength, file_); + } +} + +} // namespace rex::graphics diff --git a/src/graphics/util/draw.cpp b/src/graphics/util/draw.cpp new file mode 100644 index 0000000..f191b02 --- /dev/null +++ b/src/graphics/util/draw.cpp @@ -0,0 +1,1186 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2023 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(half_pixel_offset, true, "GPU", "Enable half pixel offset"); + +REXCVAR_DEFINE_BOOL(resolve_resolution_scale_fill_half_pixel_offset, true, "GPU", + "Fill half pixel offset during resolution scale resolve"); + +// Very prominent in 545407F2. +// DEFINE_bool( +// resolve_resolution_scale_fill_half_pixel_offset, true, +// "When using resolution scaling, apply the hack that stretches the first " +// "surely covered host pixel in the left and top sides of render target " +// "resolve areas to eliminate the gap caused by the half-pixel offset (this " +// "is necessary for certain games to display the scene graphics).", +// "GPU"); + +namespace rex::graphics::draw_util { + +bool IsRasterizationPotentiallyDone(const RegisterFile& regs, bool primitive_polygonal) { + // TODO(Triang3l): Investigate EdramMode::kNoOperation better, with respect to + // sample counting. Let's assume sample counting is a part of depth / stencil, + // thus disabled too. + xenos::EdramMode edram_mode = regs.Get().edram_mode; + if (edram_mode != xenos::EdramMode::kColorDepth && edram_mode != xenos::EdramMode::kDepthOnly) { + return false; + } + if (regs.Get().vs_export_mode == + xenos::VertexShaderExportMode::kMultipass || + !regs.Get().surface_pitch) { + return false; + } + if (primitive_polygonal) { + auto pa_su_sc_mode_cntl = regs.Get(); + if (pa_su_sc_mode_cntl.cull_front && pa_su_sc_mode_cntl.cull_back) { + // Both faces are culled. + return false; + } + } + return true; +} + +reg::RB_DEPTHCONTROL GetNormalizedDepthControl(const RegisterFile& regs) { + xenos::EdramMode edram_mode = regs.Get().edram_mode; + if (edram_mode != xenos::EdramMode::kColorDepth && edram_mode != xenos::EdramMode::kDepthOnly) { + // Both depth and stencil disabled (EDRAM depth and stencil ignored). + reg::RB_DEPTHCONTROL disabled; + disabled.value = 0; + return disabled; + } + reg::RB_DEPTHCONTROL depthcontrol = regs.Get(); + // For more reliable skipping of depth render target management for draws not + // requiring depth. + if (depthcontrol.z_enable && !depthcontrol.z_write_enable && + depthcontrol.zfunc == xenos::CompareFunction::kAlways) { + depthcontrol.z_enable = 0; + } + // Stencil is more complex and is expected to be usually enabled explicitly + // when needed. + return depthcontrol; +} + +// https://docs.microsoft.com/en-us/windows/win32/api/d3d11/ne-d3d11-d3d11_standard_multisample_quality_levels +const int8_t kD3D10StandardSamplePositions2x[2][2] = {{4, 4}, {-4, -4}}; +const int8_t kD3D10StandardSamplePositions4x[4][2] = {{-2, -6}, {6, -2}, {-6, 2}, {2, 6}}; + +void GetPreferredFacePolygonOffset(const RegisterFile& regs, bool primitive_polygonal, + float& scale_out, float& offset_out) { + float scale = 0.0f, offset = 0.0f; + auto pa_su_sc_mode_cntl = regs.Get(); + if (primitive_polygonal) { + // Prefer the front polygon offset because in general, front faces are the + // ones that are rendered (except for shadow volumes). + if (pa_su_sc_mode_cntl.poly_offset_front_enable && !pa_su_sc_mode_cntl.cull_front) { + scale = regs.Get(XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_SCALE); + offset = regs.Get(XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_OFFSET); + } + if (pa_su_sc_mode_cntl.poly_offset_back_enable && !pa_su_sc_mode_cntl.cull_back && !scale && + !offset) { + scale = regs.Get(XE_GPU_REG_PA_SU_POLY_OFFSET_BACK_SCALE); + offset = regs.Get(XE_GPU_REG_PA_SU_POLY_OFFSET_BACK_OFFSET); + } + } else { + // Non-triangle primitives use the front offset, but it's toggled via + // poly_offset_para_enable. + if (pa_su_sc_mode_cntl.poly_offset_para_enable) { + scale = regs.Get(XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_SCALE); + offset = regs.Get(XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_OFFSET); + } + } + scale_out = scale; + offset_out = offset; +} + +bool IsPixelShaderNeededWithRasterization(const Shader& shader, const RegisterFile& regs, + bool include_memory_export) { + assert_true(shader.type() == xenos::ShaderType::kPixel); + assert_true(shader.is_ucode_analyzed()); + + // See xenos::EdramMode for explanation why the pixel shader is only used when + // it's kColorDepth here. + if (regs.Get().edram_mode != xenos::EdramMode::kColorDepth) { + return false; + } + + // Discarding (explicitly or through alphatest or alpha to coverage) has side + // effects on pixel counting. + // + // Depth output only really matters if depth test is active, but it's used + // extremely rarely, and pretty much always intentionally - for simplicity, + // consider it as always mattering. + // + // Memory export is an obvious intentional side effect. + if (shader.kills_pixels() || shader.writes_depth() || + (include_memory_export && shader.memexport_eM_written()) || + (shader.writes_color_target(0) && + DoesCoverageDependOnAlpha(regs.Get()))) { + return true; + } + + // Check if a color target is actually written. + uint32_t rb_color_mask = regs[XE_GPU_REG_RB_COLOR_MASK]; + uint32_t rts_remaining = shader.writes_color_targets(); + uint32_t rt_index; + while (rex::bit_scan_forward(rts_remaining, &rt_index)) { + rts_remaining &= ~(uint32_t(1) << rt_index); + uint32_t format_component_count = GetColorRenderTargetFormatComponentCount( + regs.Get(reg::RB_COLOR_INFO::rt_register_indices[rt_index]) + .color_format); + if ((rb_color_mask >> (rt_index * 4)) & ((uint32_t(1) << format_component_count) - 1)) { + return true; + } + } + + // Only depth / stencil passthrough potentially. + return false; +} + +void GetHostViewportInfo(const RegisterFile& regs, uint32_t draw_resolution_scale_x, + uint32_t draw_resolution_scale_y, bool origin_bottom_left, uint32_t x_max, + uint32_t y_max, bool allow_reverse_z, + reg::RB_DEPTHCONTROL normalized_depth_control, bool convert_z_to_float24, + bool full_float24_in_0_to_1, bool pixel_shader_writes_depth, + ViewportInfo& viewport_info_out) { + assert_not_zero(draw_resolution_scale_x); + assert_not_zero(draw_resolution_scale_y); + + // A vertex position goes the following path: + // + // = Vertex shader output in clip space, (-w, -w, 0) ... (w, w, w) for + // Direct3D or (-w, -w, -w) ... (w, w, w) for OpenGL. + // > Clipping to the boundaries of the clip space if enabled. + // > Division by W if not pre-divided. + // = Normalized device coordinates, (-1, -1, 0) ... (1, 1, 1) for Direct3D or + // (-1, -1, -1) ... (1, 1, 1) for OpenGL. + // > Viewport scaling. + // > Viewport, window and half-pixel offsetting. + // = Actual position in render target pixels used for rasterization and depth + // buffer coordinates. + // + // On modern PC graphics APIs, all drawing is done with clipping enabled (only + // Z clipping can be replaced with viewport depth range clamping). + // + // On the Xbox 360, however, there are two cases: + // + // - Clipping is enabled: + // + // Drawing "as normal", primarily for the game world. Draws are clipped to + // the (-w, -w, 0) ... (w, w, w) or (-w, -w, -w) ... (w, w, w) clip space. + // + // Ideally all offsets in pixels (window offset, half-pixel offset) are + // post-clip, and thus they would need to be applied via the host viewport + // (also the Direct3D 11.3 specification defines this as the correct way of + // reproducing the original Direct3D 9 half-pixel offset behavior). + // + // However, in reality, only WARP actually truly clips to -W...W, with the + // viewport fractional offset actually accurately making samples outside the + // fractional rectangle unable to be covered. AMD, Intel and Nvidia, in + // Direct3D 12, all don't truly clip even a really huge primitive to -W...W. + // Instead, primitives still overflow the fractional rectangle and cover + // samples outside of it. The actual viewport scissor is floor(TopLeftX, + // TopLeftY) ... floor(TopLeftX + Width, TopLeftY + Height), with flooring + // and addition in float32 (with 0x3F7FFFFF TopLeftXY, or 1.0f - ULP, all + // the samples in the top row / left column can be covered, while with + // 0x3F800000, or 1.0f, none of them can be). + // + // We are reproducing the same behavior here - what would happen if we'd be + // passing the guest values directly to Direct3D 12. Also, for consistency + // across hardware and APIs (especially Vulkan with viewportSubPixelBits + // being 0 rather than at least 8 on some devices - Arm Mali, Imagination + // PowerVR), and for simplicity of math, and also for exact calculations in + // bounds checking in validation layers of the host APIs, we are returning + // integer viewport coordinates, handling the fractional offset in the + // vertex shaders instead, via ndc_scale and ndc_offset - it shouldn't + // significantly affect precision that we will be doing the offsetting in + // W-scaled rather than W-divided units, the ratios of exponents involved in + // the calculations stay the same, and everything ends up being 16.8 anyway + // on most hardware, so small precision differences are very unlikely to + // affect coverage. + // + // FIXME(Triang3l): Overestimate or more properly round the viewport scissor + // boundaries if this flooring causes gaps on the bottom / right side in real + // games if any are found using fractional viewport coordinates. Viewport + // scissoring is not an inherent result of the viewport scale / offset, these + // are used merely for transformation of coordinates; rather, it's done by + // intersecting the viewport and scissor rectangles in the guest driver and + // writing the common portion to PA_SC_WINDOW_SCISSOR, so how the scissor is + // computed for a fractional viewport is entirely up to the guest. + // + // Even though Xbox 360 games are designed for Direct3D, with 0...W range of + // Z in clip space, the GPU also allows -W...W. Since Xenia is not targeting + // OpenGL (where it would be toggled via glClipControl - or, on ES, it would + // always be -W...W), this function always remaps it to 0...W, though + // numerically not precisely (0 is moved to 0.5, locking the exponent near + // what was the truly floating-point 0 originally). It is the guest + // viewport's responsibility (haven't checked, but it's logical) to remap + // from -1...1 in the NDC to glDepthRange within the 0...1 range. Also -Z + // pointing forward in OpenGL doesn't matter here (the -W...W clip space is + // symmetric). + // + // - Clipping is disabled: + // + // The most common case of drawing without clipping in games is screen-space + // draws, most prominently clears, directly in render target coordinates. + // + // In this particular case (though all the general case arithmetic still + // applies), the vertex shader returns a position in pixels, pre-divided by + // W (though this doesn't matter if W is 1). + // + // Because clipping is disabled, this huge polygon with, for example, + // a (1280, 720, 0, 1) vertex, is not clipped to (-w, -w) ... (w, w), so the + // vertex becomes (1280, 720) in the NDC as well (even though in regular 3D + // draws with clipping, disregarding the guard band for simplicity, it can't + // be bigger than (1, 1) after clipping and the division by W). + // + // For these draws, the viewport is also usually disabled (though, again, it + // doesn't have to be - an enabled viewport would likely still work as + // usual) by disabling PA_CL_VTE_CNTL::VPORT_X/Y/Z_SCALE/OFFSET_ENA - which + // equals to having a viewport scale of (1, 1, 1) and offset of (0, 0, 0). + // This results in the NDC being treated directly as pixel coordinates. + // Normally, with clipping, this would make only a tiny 1x1 area in the + // corner of the render target being possible to cover (and 3 unreachable + // pixels outside of the render target). The window offset is then applied, + // if needed, as well as the half-pixel offset. + // + // It's also possible (though not verified) that without clipping, Z (as a + // result of, for instance, polygon offset, or explicit calculations in the + // vertex shader) may end up outside the viewport Z range. Direct3D 10 + // requires clamping to the viewport Z bounds in all cases in the + // output-merger according to the Direct3D 11.3 functional specification. A + // different behavior is likely on the Xbox 360, however, because while + // Direct3D 10-compatible AMD GPUs such as the R600 have + // PA_SC_VPORT_ZMIN/ZMAX registers, the Adreno 200 doesn't seem to have any + // equivalents, neither in PA nor in RB. This probably also applies to + // shader depth output - possibly doesn't need to be clamped as well. + // + // On the PC, we need to emulate disabled clipping by using a viewport at + // least as large as the scissor region within the render target, as well as + // the full viewport depth range (plus changing Z clipping to Z clamping on + // the host if possible), and rescale from the guest clip space to the host + // "no clip" clip space, as well as apply the viewport, the window offset, + // and the half-pixel offset, in the vertex shader. Ideally, the host + // viewport should have a power of 2 size - so scaling doesn't affect + // precision, and is merely an exponent bias. + // + // NDC XY point towards +XY on the render target - the viewport scale sign + // handles the remapping from Direct3D 9 -Y towards +U to a generic + // transformation from the NDC to pixel coordinates. + // + // TODO(Triang3l): Investigate the need for clamping of oDepth to 0...1 for + // D24FS8 as well. + + auto pa_cl_clip_cntl = regs.Get(); + auto pa_cl_vte_cntl = regs.Get(); + auto pa_su_sc_mode_cntl = regs.Get(); + auto pa_su_vtx_cntl = regs.Get(); + + // Obtain the original viewport values in a normalized way. + float scale_xy[] = { + pa_cl_vte_cntl.vport_x_scale_ena ? regs.Get(XE_GPU_REG_PA_CL_VPORT_XSCALE) : 1.0f, + pa_cl_vte_cntl.vport_y_scale_ena ? regs.Get(XE_GPU_REG_PA_CL_VPORT_YSCALE) : 1.0f, + }; + float scale_z = + pa_cl_vte_cntl.vport_z_scale_ena ? regs.Get(XE_GPU_REG_PA_CL_VPORT_ZSCALE) : 1.0f; + float offset_base_xy[] = { + pa_cl_vte_cntl.vport_x_offset_ena ? regs.Get(XE_GPU_REG_PA_CL_VPORT_XOFFSET) : 0.0f, + pa_cl_vte_cntl.vport_y_offset_ena ? regs.Get(XE_GPU_REG_PA_CL_VPORT_YOFFSET) : 0.0f, + }; + float offset_z = + pa_cl_vte_cntl.vport_z_offset_ena ? regs.Get(XE_GPU_REG_PA_CL_VPORT_ZOFFSET) : 0.0f; + // Calculate all the integer.0 or integer.5 offsetting exactly at full + // precision, separately so it can be used in other integer calculations + // without double rounding if needed. + float offset_add_xy[2] = {}; + if (pa_su_sc_mode_cntl.vtx_window_offset_enable) { + auto pa_sc_window_offset = regs.Get(); + offset_add_xy[0] += float(pa_sc_window_offset.window_x_offset); + offset_add_xy[1] += float(pa_sc_window_offset.window_y_offset); + } + if (REXCVAR_GET(half_pixel_offset) && pa_su_vtx_cntl.pix_center == xenos::PixelCenter::kD3DZero) { + offset_add_xy[0] += 0.5f; + offset_add_xy[1] += 0.5f; + } + + // The maximum value is at least the maximum host render target size anyway - + // and a guest pixel is always treated as a whole with resolution scaling. + uint32_t xy_max_unscaled[] = {x_max / draw_resolution_scale_x, y_max / draw_resolution_scale_y}; + assert_not_zero(xy_max_unscaled[0]); + assert_not_zero(xy_max_unscaled[1]); + + float z_min; + float z_max; + float ndc_scale[3]; + float ndc_offset[3]; + + if (pa_cl_clip_cntl.clip_disable) { + // Clipping is disabled - use a huge host viewport, perform pixel and depth + // offsetting in the vertex shader. + + // XY. + for (uint32_t i = 0; i < 2; ++i) { + viewport_info_out.xy_offset[i] = 0; + uint32_t extent_axis_unscaled = + std::min(xenos::kTexture2DCubeMaxWidthHeight, xy_max_unscaled[i]); + viewport_info_out.xy_extent[i] = + extent_axis_unscaled * (i ? draw_resolution_scale_y : draw_resolution_scale_x); + float extent_axis_unscaled_float = float(extent_axis_unscaled); + float pixels_to_ndc_axis = 2.0f / extent_axis_unscaled_float; + ndc_scale[i] = scale_xy[i] * pixels_to_ndc_axis; + ndc_offset[i] = (offset_base_xy[i] - extent_axis_unscaled_float * 0.5f + offset_add_xy[i]) * + pixels_to_ndc_axis; + } + + // Z. + z_min = 0.0f; + z_max = 1.0f; + ndc_scale[2] = scale_z; + ndc_offset[2] = offset_z; + } else { + // Clipping is enabled - perform pixel and depth offsetting via the host + // viewport. + + // XY. + for (uint32_t i = 0; i < 2; ++i) { + // With resolution scaling, do all viewport XY scissoring in guest pixels + // if fractional and for the half-pixel offset - we treat guest pixels as + // a whole, and also the half-pixel offset would be irreversible in guest + // vertices if we did flooring in host pixels. Instead of flooring, also + // doing truncation for simplicity - since maxing with 0 is done anyway + // (we only return viewports in the positive quarter-plane). + uint32_t axis_resolution_scale = i ? draw_resolution_scale_y : draw_resolution_scale_x; + float offset_axis = offset_base_xy[i] + offset_add_xy[i]; + float scale_axis = scale_xy[i]; + float scale_axis_abs = std::abs(scale_xy[i]); + float axis_max_unscaled_float = float(xy_max_unscaled[i]); + uint32_t axis_0_int = + uint32_t(rex::clamp_float(offset_axis - scale_axis_abs, 0.0f, axis_max_unscaled_float)); + uint32_t axis_1_int = + uint32_t(rex::clamp_float(offset_axis + scale_axis_abs, 0.0f, axis_max_unscaled_float)); + uint32_t axis_extent_int = axis_1_int - axis_0_int; + viewport_info_out.xy_offset[i] = axis_0_int * axis_resolution_scale; + viewport_info_out.xy_extent[i] = axis_extent_int * axis_resolution_scale; + float ndc_scale_axis; + float ndc_offset_axis; + if (axis_extent_int) { + // Rescale from the old bounds to the new ones, and also apply the sign. + // If the new bounds are smaller than the old, for instance, we're + // cropping - the new -W...W clip space is a subregion of the old one - + // the scale should be > 1 so the area being cut off ends up outside + // -W...W. If the new region should include more than the original clip + // space, a region previously outside -W...W should end up within it, so + // the scale should be < 1. + float axis_extent_rounded = float(axis_extent_int); + ndc_scale_axis = scale_axis * 2.0f / axis_extent_rounded; + // Move the origin of the snapped coordinates back to the original one. + ndc_offset_axis = (float(offset_axis) - (float(axis_0_int) + axis_extent_rounded * 0.5f)) * + 2.0f / axis_extent_rounded; + } else { + // Empty viewport (everything outside the viewport scissor). + ndc_scale_axis = 1.0f; + ndc_offset_axis = 0.0f; + } + ndc_scale[i] = ndc_scale_axis; + ndc_offset[i] = ndc_offset_axis; + } + + // Z. + float host_clip_offset_z; + float host_clip_scale_z; + if (pa_cl_clip_cntl.dx_clip_space_def) { + host_clip_offset_z = offset_z; + host_clip_scale_z = scale_z; + ndc_scale[2] = 1.0f; + ndc_offset[2] = 0.0f; + } else { + // Normalizing both Direct3D / Vulkan 0...W and OpenGL -W...W clip spaces + // to 0...W. We are not targeting OpenGL, but there we could accept the + // wanted clip space (Direct3D, OpenGL, or any) and return the actual one + // (Direct3D or OpenGL). + // + // If the guest wants to use -W...W clip space (-1...1 NDC) and a 0...1 + // depth range in the end, it's expected to use ZSCALE of 0.5 and ZOFFSET + // of 0.5. + // + // We are providing the near and the far (or offset and offset + scale) + // plane distances to the host API in a way that the near maps to Z = 0 + // and the far maps to Z = W in clip space (or Z = 1 in NDC). + // + // With D3D offset and scale that we want, assuming D3D clip space input, + // the formula for the depth would be: + // + // depth = offset_d3d + scale_d3d * ndc_z_d3d + // + // We are remapping the incoming OpenGL Z from -W...W to 0...W by scaling + // it by 0.5 and adding 0.5 * W to the result. So, our depth formula would + // be: + // + // depth = offset_d3d + scale_d3d * (ndc_z_gl * 0.5 + 0.5) + // + // The guest registers, however, contain the offset and the scale for + // remapping not from 0...W to near...far, but from -W...W to near...far, + // or: + // + // depth = offset_gl + scale_gl * ndc_z_gl + // + // Knowing offset_gl, scale_gl and how ndc_z_d3d can be obtained from + // ndc_z_gl, we need to derive the formulas for the needed offset_d3d and + // scale_d3d to apply them to the incoming ndc_z_d3d. + // + // depth = offset_gl + scale_gl * (ndc_z_d3d * 2 - 1) + // + // Expanding: + // + // depth = offset_gl + (scale_gl * ndc_z_d3d * 2 - scale_gl) + // + // Reordering: + // + // depth = (offset_gl - scale_gl) + (scale_gl * 2) * ndc_z_d3d + // offset_d3d = offset_gl - scale_gl + // scale_d3d = scale_gl * 2 + host_clip_offset_z = offset_z - scale_z; + host_clip_scale_z = scale_z * 2.0f; + // Need to remap -W...W clip space to 0...W via ndc_scale and ndc_offset - + // by scaling Z by 0.5 and adding 0.5 * W to it. + ndc_scale[2] = 0.5f; + ndc_offset[2] = 0.5f; + } + if (pixel_shader_writes_depth) { + // Allow the pixel shader to write any depth value since + // PA_SC_VPORT_ZMIN/ZMAX isn't present on the Adreno 200; guest pixel + // shaders don't have access to the original Z in the viewport space + // anyway and likely must write the depth on all execution paths. + z_min = 0.0f; + z_max = 1.0f; + } else { + // This clamping is not very correct, but just for safety. Direct3D + // doesn't allow an unrestricted depth range. Vulkan does, as an + // extension. But cases when this really matters are yet to be found - + // trying to fix this will result in more correct depth values, but + // incorrect clipping. + z_min = rex::saturate(host_clip_offset_z); + z_max = rex::saturate(host_clip_offset_z + host_clip_scale_z); + // Direct3D 12 doesn't allow reverse depth range - on some drivers it + // works, on some drivers it doesn't, actually, but it was never + // explicitly allowed by the specification. + if (!allow_reverse_z && z_min > z_max) { + std::swap(z_min, z_max); + ndc_scale[2] = -ndc_scale[2]; + ndc_offset[2] = 1.0f - ndc_offset[2]; + } + } + } + + if (normalized_depth_control.z_enable && + regs.Get().depth_format == xenos::DepthRenderTargetFormat::kD24FS8) { + if (convert_z_to_float24) { + // Need to adjust the bounds that the resulting depth values will be + // clamped to after the pixel shader. Preferring adding some error to + // interpolated Z instead if conversion can't be done exactly, without + // modifying clipping bounds by adjusting Z in vertex shaders, as that + // may cause polygons placed explicitly at Z = 0 or Z = W to be clipped. + // Rounding the bounds to the nearest even regardless of the depth + // rounding mode not to add even more error by truncating twice. + z_min = xenos::Float20e4To32(xenos::Float32To20e4(z_min, true)); + z_max = xenos::Float20e4To32(xenos::Float32To20e4(z_max, true)); + } + if (full_float24_in_0_to_1) { + // Remap the full [0...2) float24 range to [0...1) support data round-trip + // during render target ownership transfer of EDRAM tiles through depth + // input without unrestricted depth range. + z_min *= 0.5f; + z_max *= 0.5f; + } + } + viewport_info_out.z_min = z_min; + viewport_info_out.z_max = z_max; + + if (origin_bottom_left) { + ndc_scale[1] = -ndc_scale[1]; + ndc_offset[1] = -ndc_offset[1]; + } + for (uint32_t i = 0; i < 3; ++i) { + viewport_info_out.ndc_scale[i] = ndc_scale[i]; + viewport_info_out.ndc_offset[i] = ndc_offset[i]; + } +} + +void GetScissor(const RegisterFile& regs, Scissor& scissor_out, bool clamp_to_surface_pitch) { + auto pa_sc_window_scissor_tl = regs.Get(); + int32_t tl_x = int32_t(pa_sc_window_scissor_tl.tl_x); + int32_t tl_y = int32_t(pa_sc_window_scissor_tl.tl_y); + auto pa_sc_window_scissor_br = regs.Get(); + int32_t br_x = int32_t(pa_sc_window_scissor_br.br_x); + int32_t br_y = int32_t(pa_sc_window_scissor_br.br_y); + if (!pa_sc_window_scissor_tl.window_offset_disable) { + auto pa_sc_window_offset = regs.Get(); + tl_x += pa_sc_window_offset.window_x_offset; + tl_y += pa_sc_window_offset.window_y_offset; + br_x += pa_sc_window_offset.window_x_offset; + br_y += pa_sc_window_offset.window_y_offset; + } + // Screen scissor is not used by Direct3D 9 (always 0, 0 to 8192, 8192), but + // still handled here for completeness. + auto pa_sc_screen_scissor_tl = regs.Get(); + tl_x = std::max(tl_x, int32_t(pa_sc_screen_scissor_tl.tl_x)); + tl_y = std::max(tl_y, int32_t(pa_sc_screen_scissor_tl.tl_y)); + auto pa_sc_screen_scissor_br = regs.Get(); + br_x = std::min(br_x, int32_t(pa_sc_screen_scissor_br.br_x)); + br_y = std::min(br_y, int32_t(pa_sc_screen_scissor_br.br_y)); + if (clamp_to_surface_pitch) { + // Clamp the horizontal scissor to surface_pitch for safety, in case that's + // not done by the guest for some reason (it's not when doing draws without + // clipping in Direct3D 9, for instance), to prevent overflow - this is + // important for host implementations, both based on target-indepedent + // rasterization without render target width at all (pixel shader + // interlock-based custom RB implementations) and using conventional render + // targets, but padded to EDRAM tiles. + uint32_t surface_pitch = regs.Get().surface_pitch; + tl_x = std::min(tl_x, int32_t(surface_pitch)); + br_x = std::min(br_x, int32_t(surface_pitch)); + } + // Ensure the rectangle is non-negative, by collapsing it into a 0-sized one + // (not by reordering the bounds preserving the width / height, which would + // reveal samples not meant to be covered, unless TL > BR does that on a real + // console, but no evidence of such has ever been seen), and also drop + // negative offsets. + tl_x = std::max(tl_x, int32_t(0)); + tl_y = std::max(tl_y, int32_t(0)); + br_x = std::max(br_x, tl_x); + br_y = std::max(br_y, tl_y); + scissor_out.offset[0] = uint32_t(tl_x); + scissor_out.offset[1] = uint32_t(tl_y); + scissor_out.extent[0] = uint32_t(br_x - tl_x); + scissor_out.extent[1] = uint32_t(br_y - tl_y); +} + +uint32_t GetNormalizedColorMask(const RegisterFile& regs, + uint32_t pixel_shader_writes_color_targets) { + if (regs.Get().edram_mode != xenos::EdramMode::kColorDepth) { + return 0; + } + uint32_t normalized_color_mask = 0; + uint32_t rb_color_mask = regs[XE_GPU_REG_RB_COLOR_MASK]; + for (uint32_t i = 0; i < xenos::kMaxColorRenderTargets; ++i) { + // Exclude the render targets not statically written to by the pixel shader. + // If the shader doesn't write to a render target, it shouldn't be written + // to, and no ownership transfers should happen to it on the host even - + // otherwise, in 4D5307E6, one render target is being destroyed by a shader + // not writing anything, and in 58410955, the result of clearing the top + // tile is being ignored because there are 4 render targets bound with the + // same EDRAM base (clearly not correct usage), but the shader only clears + // 1, and then ownership of EDRAM portions by host render targets is + // conflicting. + if (!(pixel_shader_writes_color_targets & (uint32_t(1) << i))) { + continue; + } + // Check if any existing component is written to. + uint32_t format_component_mask = + (uint32_t(1) << xenos::GetColorRenderTargetFormatComponentCount( + regs.Get(reg::RB_COLOR_INFO::rt_register_indices[i]) + .color_format)) - + 1; + uint32_t rt_write_mask = (rb_color_mask >> (4 * i)) & format_component_mask; + if (!rt_write_mask) { + continue; + } + // Mark the non-existent components as written so in the host driver, no + // slow path (involving reading and merging components) is taken if the + // driver doesn't perform this check internally, and some components are not + // included in the mask even though they actually don't exist in the format. + rt_write_mask |= 0b1111 & ~format_component_mask; + // Add to the normalized mask. + normalized_color_mask |= rt_write_mask << (4 * i); + } + return normalized_color_mask; +} + +void AddMemExportRanges(const RegisterFile& regs, const Shader& shader, + std::vector& ranges_out) { + if (!shader.memexport_eM_written()) { + // The shader has eA writes, but no real exports. + return; + } + uint32_t float_constants_base = shader.type() == xenos::ShaderType::kVertex + ? regs.Get().base + : regs.Get().base; + for (uint32_t constant_index : shader.memexport_stream_constants()) { + xenos::xe_gpu_memexport_stream_t stream = + regs.GetMemExportStream(float_constants_base + constant_index); + // Safety checks for stream constants potentially not set up if the export + // isn't done on the control flow path taken by the shader (not checking the + // Y component because the index is more likely to be constructed + // arbitrarily). + // The hardware validates the upper bits of eA according to the + // IPR2015-00325 sequencer specification. + if (stream.const_0x1 != 0x1 || stream.const_0x4b0 != 0x4B0 || stream.const_0x96 != 0x96 || + !stream.index_count) { + continue; + } + const FormatInfo& format_info = *FormatInfo::Get(xenos::TextureFormat(stream.format)); + if (format_info.type != FormatType::kResolvable) { + REXGPU_ERROR("Unsupported memexport format {}", format_info.name); + // Translated shaders shouldn't be performing exports with an unknown + // format, the draw can still be performed. + continue; + } + // TODO(Triang3l): Remove the unresearched format logging when it's known + // how exactly these formats need to be handled (most importantly what + // components need to be stored and in which order). + switch (stream.format) { + case xenos::ColorFormat::k_8_A: + case xenos::ColorFormat::k_8_B: + case xenos::ColorFormat::k_8_8_8_8_A: + REXGPU_WARN( + "Memexport done to an unresearched format {}, report the game to " + "Xenia developers!", + format_info.name); + break; + default: + break; + } + uint32_t stream_size_bytes = stream.index_count * (format_info.bits_per_pixel >> 3); + // Try to reduce the number of shared memory operations when writing + // different elements into the same buffer through different exports + // (happens in 4D5307E6). + bool range_reused = false; + for (MemExportRange& range : ranges_out) { + if (range.base_address_dwords == stream.base_address) { + range.size_bytes = std::max(range.size_bytes, stream_size_bytes); + range_reused = true; + break; + } + } + // Add a new range if haven't expanded an existing one. + if (!range_reused) { + ranges_out.emplace_back(uint32_t(stream.base_address), stream_size_bytes); + } + } +} + +xenos::CopySampleSelect SanitizeCopySampleSelect(xenos::CopySampleSelect copy_sample_select, + xenos::MsaaSamples msaa_samples, bool is_depth) { + // Depth can't be averaged. + if (msaa_samples >= xenos::MsaaSamples::k4X) { + if (copy_sample_select > xenos::CopySampleSelect::k0123) { + copy_sample_select = xenos::CopySampleSelect::k0123; + } + if (is_depth) { + switch (copy_sample_select) { + case xenos::CopySampleSelect::k01: + case xenos::CopySampleSelect::k0123: + copy_sample_select = xenos::CopySampleSelect::k0; + break; + case xenos::CopySampleSelect::k23: + copy_sample_select = xenos::CopySampleSelect::k2; + break; + default: + break; + } + } + } else if (msaa_samples >= xenos::MsaaSamples::k2X) { + switch (copy_sample_select) { + case xenos::CopySampleSelect::k2: + copy_sample_select = xenos::CopySampleSelect::k0; + break; + case xenos::CopySampleSelect::k3: + copy_sample_select = xenos::CopySampleSelect::k1; + break; + default: + if (copy_sample_select > xenos::CopySampleSelect::k01) { + copy_sample_select = xenos::CopySampleSelect::k01; + } + } + if (is_depth && copy_sample_select == xenos::CopySampleSelect::k01) { + copy_sample_select = xenos::CopySampleSelect::k0; + } + } else { + copy_sample_select = xenos::CopySampleSelect::k0; + } + return copy_sample_select; +} + +void GetResolveEdramTileSpan(ResolveEdramInfo edram_info, ResolveCoordinateInfo coordinate_info, + uint32_t height_div_8, uint32_t& base_out, + uint32_t& row_length_used_out, uint32_t& rows_out) { + // Due to 64bpp, and also not to make an assumption that the offsets are + // limited to (80 - 8, 8 - 8) with 2x MSAA, and (40 - 8, 8 - 8) with 4x MSAA, + // still taking the offset into account. + uint32_t x_scale_log2 = + 3 + uint32_t(edram_info.msaa_samples >= xenos::MsaaSamples::k4X) + edram_info.format_is_64bpp; + uint32_t x0 = + (coordinate_info.edram_offset_x_div_8 << x_scale_log2) / xenos::kEdramTileWidthSamples; + uint32_t x1 = + (((coordinate_info.edram_offset_x_div_8 + coordinate_info.width_div_8) << x_scale_log2) + + (xenos::kEdramTileWidthSamples - 1)) / + xenos::kEdramTileWidthSamples; + uint32_t y_scale_log2 = 3 + uint32_t(edram_info.msaa_samples >= xenos::MsaaSamples::k2X); + uint32_t y0 = + (coordinate_info.edram_offset_y_div_8 << y_scale_log2) / xenos::kEdramTileHeightSamples; + uint32_t y1 = (((coordinate_info.edram_offset_y_div_8 + height_div_8) << y_scale_log2) + + (xenos::kEdramTileHeightSamples - 1)) / + xenos::kEdramTileHeightSamples; + base_out = edram_info.base_tiles + y0 * edram_info.pitch_tiles + x0; + row_length_used_out = x1 - x0; + rows_out = y1 - y0; +} + +const ResolveCopyShaderInfo resolve_copy_shader_info[size_t(ResolveCopyShaderIndex::kCount)] = { + {"Resolve Copy Fast 32bpp 1x/2xMSAA", false, 4, 4, 6, 3}, + {"Resolve Copy Fast 32bpp 4xMSAA", false, 4, 4, 6, 3}, + {"Resolve Copy Fast 64bpp 1x/2xMSAA", false, 4, 4, 5, 3}, + {"Resolve Copy Fast 64bpp 4xMSAA", false, 3, 4, 5, 3}, + {"Resolve Copy Full 8bpp", true, 2, 3, 6, 3}, + {"Resolve Copy Full 16bpp", true, 2, 3, 5, 3}, + {"Resolve Copy Full 32bpp", true, 2, 4, 5, 3}, + {"Resolve Copy Full 64bpp", true, 2, 4, 5, 3}, + {"Resolve Copy Full 128bpp", true, 2, 4, 4, 3}, +}; + +bool GetResolveInfo(const RegisterFile& regs, const memory::Memory& memory, + TraceWriter& trace_writer, uint32_t draw_resolution_scale_x, + uint32_t draw_resolution_scale_y, bool fixed_rg16_truncated_to_minus_1_to_1, + bool fixed_rgba16_truncated_to_minus_1_to_1, ResolveInfo& info_out) { + // Don't pass uninitialized values to shaders, not to leak data to frame + // captures. Also initialize an invalid resolve to empty. + info_out.coordinate_info.packed = 0; + info_out.height_div_8 = 0; + + auto rb_copy_control = regs.Get(); + info_out.rb_copy_control = rb_copy_control; + + if (rb_copy_control.copy_command != xenos::CopyCommand::kRaw && + rb_copy_control.copy_command != xenos::CopyCommand::kConvert) { + REXGPU_ERROR( + "Unsupported resolve copy command {}. Report the game to Xenia " + "developers", + uint32_t(rb_copy_control.copy_command)); + assert_always(); + return false; + } + + // Get the extent of pixels covered by the resolve rectangle, according to the + // top-left rasterization rule. + // D3D9 HACK: Vertices to use are always in vf0, and are written by the CPU. + xenos::xe_gpu_vertex_fetch_t fetch = regs.GetVertexFetch(0); + if (fetch.type != xenos::FetchConstantType::kVertex || fetch.size != 3 * 2) { + REXGPU_ERROR("Unsupported resolve vertex buffer format"); + assert_always(); + return false; + } + trace_writer.WriteMemoryRead(fetch.address * sizeof(uint32_t), fetch.size * sizeof(uint32_t)); + const float* vertices_guest = + reinterpret_cast(memory.TranslatePhysical(fetch.address * sizeof(uint32_t))); + // Most vertices have a negative half-pixel offset applied, which we reverse. + float half_pixel_offset = + regs.Get().pix_center == xenos::PixelCenter::kD3DZero ? 0.5f : 0.0f; + int32_t vertices_fixed[6]; + for (size_t i = 0; i < rex::countof(vertices_fixed); ++i) { + vertices_fixed[i] = ui::FloatToD3D11Fixed16p8(xenos::GpuSwap(vertices_guest[i], fetch.endian) + + half_pixel_offset); + } + // Inclusive. + int32_t x0 = std::min(std::min(vertices_fixed[0], vertices_fixed[2]), vertices_fixed[4]); + int32_t y0 = std::min(std::min(vertices_fixed[1], vertices_fixed[3]), vertices_fixed[5]); + // Exclusive. + int32_t x1 = std::max(std::max(vertices_fixed[0], vertices_fixed[2]), vertices_fixed[4]); + int32_t y1 = std::max(std::max(vertices_fixed[1], vertices_fixed[3]), vertices_fixed[5]); + // Top-left - include .5 (0.128 treated as 0 covered, 0.129 as 0 not covered). + x0 = (x0 + 127) >> 8; + y0 = (y0 + 127) >> 8; + // Bottom-right - exclude .5. + x1 = (x1 + 127) >> 8; + y1 = (y1 + 127) >> 8; + + auto pa_sc_window_offset = regs.Get(); + + // Apply the window offset to the vertices. + if (regs.Get().vtx_window_offset_enable) { + x0 += pa_sc_window_offset.window_x_offset; + y0 += pa_sc_window_offset.window_y_offset; + x1 += pa_sc_window_offset.window_x_offset; + y1 += pa_sc_window_offset.window_y_offset; + } + + // Apply the scissor and prevent negative origin (behind the EDRAM base). + Scissor scissor; + // False because clamping to the surface pitch will be done later (it will be + // aligned to the resolve alignment here, for resolving from render targets + // with a pitch that is not a multiple of 8). + GetScissor(regs, scissor, false); + int32_t scissor_right = int32_t(scissor.offset[0] + scissor.extent[0]); + int32_t scissor_bottom = int32_t(scissor.offset[1] + scissor.extent[1]); + x0 = std::clamp(x0, int32_t(scissor.offset[0]), scissor_right); + y0 = std::clamp(y0, int32_t(scissor.offset[1]), scissor_bottom); + x1 = std::clamp(x1, int32_t(scissor.offset[0]), scissor_right); + y1 = std::clamp(y1, int32_t(scissor.offset[1]), scissor_bottom); + + assert_true(x0 <= x1 && y0 <= y1); + + // Direct3D 9's D3DDevice_Resolve internally rounds the right/bottom of the + // rectangle internally to 8. While all the alignment should have already been + // done by Direct3D 9, just for safety of host implementation of resolve, + // force-align the rectangle by expanding (D3D9 expands to the right/bottom + // for some reason, haven't found how left/top is rounded, but logically it + // would make sense to expand to the left/top too). + x0 &= ~int32_t(xenos::kResolveAlignmentPixels - 1); + y0 &= ~int32_t(xenos::kResolveAlignmentPixels - 1); + x1 = rex::align(x1, int32_t(xenos::kResolveAlignmentPixels)); + y1 = rex::align(y1, int32_t(xenos::kResolveAlignmentPixels)); + + auto rb_surface_info = regs.Get(); + if (rb_surface_info.msaa_samples > xenos::MsaaSamples::k4X) { + // Safety check because a lot of code assumes up to 4x. + assert_always(); + REXGPU_ERROR( + "{}x MSAA requested by the guest in a resolve, Xenos only supports up " + "to 4x", + uint32_t(1) << uint32_t(rb_surface_info.msaa_samples)); + return false; + } + + // Clamp to the EDRAM surface pitch (maximum possible surface pitch is also + // assumed to be the largest resolvable size). + int32_t surface_pitch_aligned = + int32_t(rb_surface_info.surface_pitch & ~uint32_t(xenos::kResolveAlignmentPixels - 1)); + if (x1 > surface_pitch_aligned) { + REXGPU_ERROR("Resolve region {} <= x < {} is outside the surface pitch {}", x0, x1, + surface_pitch_aligned); + x0 = std::min(x0, surface_pitch_aligned); + x1 = std::min(x1, surface_pitch_aligned); + } + assert_true(x1 - x0 <= int32_t(xenos::kMaxResolveSize)); + + // Clamp the height to a sane value (to make sure it can fit in the packed + // shader constant). + if (y1 - y0 > int32_t(xenos::kMaxResolveSize)) { + REXGPU_ERROR("Resolve region {} <= y < {} is taller than {}", y0, y1, xenos::kMaxResolveSize); + y1 = y0 + int32_t(xenos::kMaxResolveSize); + } + + assert_true(x0 < x1 && y0 < y1); + if (x0 >= x1 || y0 >= y1) { + REXGPU_ERROR("Resolve region is empty"); + return false; + } + + info_out.coordinate_info.width_div_8 = uint32_t(x1 - x0) >> xenos::kResolveAlignmentPixelsLog2; + info_out.height_div_8 = uint32_t(y1 - y0) >> xenos::kResolveAlignmentPixelsLog2; + // 3 bits for each. + assert_true(draw_resolution_scale_x <= 7); + assert_true(draw_resolution_scale_y <= 7); + info_out.coordinate_info.draw_resolution_scale_x = draw_resolution_scale_x; + info_out.coordinate_info.draw_resolution_scale_y = draw_resolution_scale_y; + + // Handle the destination. + bool is_depth = rb_copy_control.copy_src_select >= xenos::kMaxColorRenderTargets; + // Get the sample selection to safely pass to the shader. + xenos::CopySampleSelect sample_select = SanitizeCopySampleSelect( + rb_copy_control.copy_sample_select, rb_surface_info.msaa_samples, is_depth); + if (rb_copy_control.copy_sample_select != sample_select) { + REXGPU_WARN( + "Incorrect resolve sample selected for {}-sample {}: {}, treating like " + "{}", + 1 << uint32_t(rb_surface_info.msaa_samples), is_depth ? "depth" : "color", + static_cast(rb_copy_control.copy_sample_select), + static_cast(sample_select)); + } + info_out.copy_dest_coordinate_info.copy_sample_select = sample_select; + // Get the format to pass to the shader in a unified way - for depth (for + // which Direct3D 9 specifies the k_8_8_8_8 uint destination format), make + // sure the shader won't try to do conversion - pass proper k_24_8 or + // k_24_8_FLOAT. + auto rb_copy_dest_info = regs.Get(); + xenos::TextureFormat dest_format; + auto rb_depth_info = regs.Get(); + if (is_depth) { + dest_format = DepthRenderTargetToTextureFormat(rb_depth_info.depth_format); + } else { + dest_format = xenos::TextureFormat(rb_copy_dest_info.copy_dest_format); + // For development feedback - not much known about these formats currently. + xenos::TextureFormat dest_closest_format; + switch (dest_format) { + case xenos::TextureFormat::k_8_A: + case xenos::TextureFormat::k_8_B: + dest_closest_format = xenos::TextureFormat::k_8; + break; + case xenos::TextureFormat::k_8_8_8_8_A: + dest_closest_format = xenos::TextureFormat::k_8_8_8_8; + break; + default: + dest_closest_format = dest_format; + } + if (dest_format != dest_closest_format) { + REXGPU_WARN( + "Resolving to format {}, which is untested - treating like {}. " + "Report the game to Xenia developers!", + FormatInfo::Get(dest_format)->name, FormatInfo::Get(dest_closest_format)->name); + } + } + + // Calculate the destination memory extent. + uint32_t rb_copy_dest_base = regs[XE_GPU_REG_RB_COPY_DEST_BASE]; + uint32_t copy_dest_base_adjusted = rb_copy_dest_base; + uint32_t copy_dest_extent_start, copy_dest_extent_end; + auto rb_copy_dest_pitch = regs.Get(); + uint32_t copy_dest_pitch_aligned_div_32 = + (rb_copy_dest_pitch.copy_dest_pitch + (xenos::kTextureTileWidthHeight - 1)) >> + xenos::kTextureTileWidthHeightLog2; + info_out.copy_dest_coordinate_info.pitch_aligned_div_32 = copy_dest_pitch_aligned_div_32; + info_out.copy_dest_coordinate_info.height_aligned_div_32 = + (rb_copy_dest_pitch.copy_dest_height + (xenos::kTextureTileWidthHeight - 1)) >> + xenos::kTextureTileWidthHeightLog2; + const FormatInfo& dest_format_info = *FormatInfo::Get(dest_format); + if (is_depth || dest_format_info.type == FormatType::kResolvable) { + uint32_t bpp_log2 = rex::log2_floor(dest_format_info.bits_per_pixel >> 3); + uint32_t dest_base_relative_x_mask = (UINT32_C(1) << xenos::GetTextureTiledXBaseGranularityLog2( + bool(rb_copy_dest_info.copy_dest_array), bpp_log2)) - + 1; + uint32_t dest_base_relative_y_mask = (UINT32_C(1) << xenos::GetTextureTiledYBaseGranularityLog2( + bool(rb_copy_dest_info.copy_dest_array), bpp_log2)) - + 1; + info_out.copy_dest_coordinate_info.offset_x_div_8 = + (uint32_t(x0) & dest_base_relative_x_mask) >> xenos::kResolveAlignmentPixelsLog2; + info_out.copy_dest_coordinate_info.offset_y_div_8 = + (uint32_t(y0) & dest_base_relative_y_mask) >> xenos::kResolveAlignmentPixelsLog2; + uint32_t dest_base_x = uint32_t(x0) & ~dest_base_relative_x_mask; + uint32_t dest_base_y = uint32_t(y0) & ~dest_base_relative_y_mask; + if (rb_copy_dest_info.copy_dest_array) { + // The base pointer is already adjusted to the Z / 8 (copy_dest_slice is + // 3-bit). + copy_dest_base_adjusted += texture_util::GetTiledOffset3D( + int32_t(dest_base_x), int32_t(dest_base_y), 0, rb_copy_dest_pitch.copy_dest_pitch, + rb_copy_dest_pitch.copy_dest_height, bpp_log2); + copy_dest_extent_start = + rb_copy_dest_base + texture_util::GetTiledAddressLowerBound3D( + uint32_t(x0), uint32_t(y0), rb_copy_dest_info.copy_dest_slice, + rb_copy_dest_pitch.copy_dest_pitch, + rb_copy_dest_pitch.copy_dest_height, bpp_log2); + copy_dest_extent_end = + rb_copy_dest_base + texture_util::GetTiledAddressUpperBound3D( + uint32_t(x1), uint32_t(y1), rb_copy_dest_info.copy_dest_slice + 1, + rb_copy_dest_pitch.copy_dest_pitch, + rb_copy_dest_pitch.copy_dest_height, bpp_log2); + } else { + copy_dest_base_adjusted += texture_util::GetTiledOffset2D( + int32_t(dest_base_x), int32_t(dest_base_y), rb_copy_dest_pitch.copy_dest_pitch, bpp_log2); + copy_dest_extent_start = + rb_copy_dest_base + + texture_util::GetTiledAddressLowerBound2D(uint32_t(x0), uint32_t(y0), + rb_copy_dest_pitch.copy_dest_pitch, bpp_log2); + copy_dest_extent_end = rb_copy_dest_base + texture_util::GetTiledAddressUpperBound2D( + uint32_t(x1), uint32_t(y1), + rb_copy_dest_pitch.copy_dest_pitch, bpp_log2); + } + } else { + REXGPU_ERROR("Tried to resolve to format {}, which is not a ColorFormat", + dest_format_info.name); + copy_dest_extent_start = copy_dest_base_adjusted; + copy_dest_extent_end = copy_dest_base_adjusted; + } + assert_true(copy_dest_extent_start >= copy_dest_base_adjusted); + assert_true(copy_dest_extent_end >= copy_dest_base_adjusted); + assert_true(copy_dest_extent_end >= copy_dest_extent_start); + info_out.copy_dest_base = copy_dest_base_adjusted; + info_out.copy_dest_extent_start = copy_dest_extent_start; + info_out.copy_dest_extent_length = copy_dest_extent_end - copy_dest_extent_start; + + // Offset relative to the beginning of the tile to put it in fewer bits. + uint32_t sample_count_log2_x = uint32_t(rb_surface_info.msaa_samples >= xenos::MsaaSamples::k4X); + uint32_t sample_count_log2_y = uint32_t(rb_surface_info.msaa_samples >= xenos::MsaaSamples::k2X); + uint32_t x0_samples = uint32_t(x0) << sample_count_log2_x; + uint32_t y0_samples = uint32_t(y0) << sample_count_log2_y; + uint32_t base_offset_x_tiles = x0_samples / xenos::kEdramTileWidthSamples; + uint32_t base_offset_y_tiles = y0_samples / xenos::kEdramTileHeightSamples; + info_out.coordinate_info.edram_offset_x_div_8 = + (x0_samples % xenos::kEdramTileWidthSamples) >> (sample_count_log2_x + 3); + info_out.coordinate_info.edram_offset_y_div_8 = + (y0_samples % xenos::kEdramTileHeightSamples) >> (sample_count_log2_y + 3); + uint32_t surface_pitch_tiles = xenos::GetSurfacePitchTiles(rb_surface_info.surface_pitch, + rb_surface_info.msaa_samples, false); + uint32_t edram_base_offset_tiles = + base_offset_y_tiles * surface_pitch_tiles + base_offset_x_tiles; + + // Write the color/depth EDRAM info. + bool fill_half_pixel_offset = + (draw_resolution_scale_x > 1 || draw_resolution_scale_y > 1) && + REXCVAR_GET(resolve_resolution_scale_fill_half_pixel_offset) && + REXCVAR_GET(half_pixel_offset) && + regs.Get().pix_center == xenos::PixelCenter::kD3DZero; + int32_t exp_bias = is_depth ? 0 : rb_copy_dest_info.copy_dest_exp_bias; + ResolveEdramInfo depth_edram_info; + depth_edram_info.packed = 0; + if (is_depth || rb_copy_control.depth_clear_enable) { + depth_edram_info.pitch_tiles = surface_pitch_tiles; + depth_edram_info.msaa_samples = rb_surface_info.msaa_samples; + depth_edram_info.is_depth = 1; + // If wrapping happens, it's fine, it doesn't matter how many times and + // where modulo xenos::kEdramTileCount is applied in this context. + depth_edram_info.base_tiles = rb_depth_info.depth_base + edram_base_offset_tiles; + depth_edram_info.format = uint32_t(rb_depth_info.depth_format); + depth_edram_info.format_is_64bpp = 0; + depth_edram_info.fill_half_pixel_offset = uint32_t(fill_half_pixel_offset); + info_out.depth_original_base = rb_depth_info.depth_base; + } else { + info_out.depth_original_base = 0; + } + info_out.depth_edram_info = depth_edram_info; + ResolveEdramInfo color_edram_info; + color_edram_info.packed = 0; + if (!is_depth) { + // Color. + auto color_info = regs.Get( + reg::RB_COLOR_INFO::rt_register_indices[rb_copy_control.copy_src_select]); + uint32_t is_64bpp = uint32_t(xenos::IsColorRenderTargetFormat64bpp(color_info.color_format)); + color_edram_info.pitch_tiles = surface_pitch_tiles << is_64bpp; + color_edram_info.msaa_samples = rb_surface_info.msaa_samples; + color_edram_info.is_depth = 0; + // If wrapping happens, it's fine, it doesn't matter how many times and + // where modulo xenos::kEdramTileCount is applied in this context. + color_edram_info.base_tiles = color_info.color_base + (edram_base_offset_tiles << is_64bpp); + color_edram_info.format = uint32_t(color_info.color_format); + color_edram_info.format_is_64bpp = is_64bpp; + color_edram_info.fill_half_pixel_offset = uint32_t(fill_half_pixel_offset); + if ((fixed_rg16_truncated_to_minus_1_to_1 && + color_info.color_format == xenos::ColorRenderTargetFormat::k_16_16) || + (fixed_rgba16_truncated_to_minus_1_to_1 && + color_info.color_format == xenos::ColorRenderTargetFormat::k_16_16_16_16)) { + // The texture expects 0x8001 = -32, 0x7FFF = 32, but the hack making + // 0x8001 = -1, 0x7FFF = 1 is used - revert (this won't be correct if the + // requested exponent bias is 27 or above, but it's a hack anyway, no need + // to create a new copy info structure with one more bit just for this). + exp_bias = std::min(exp_bias + int32_t(5), int32_t(31)); + } + info_out.color_original_base = color_info.color_base; + } else { + info_out.color_original_base = 0; + } + info_out.color_edram_info = color_edram_info; + + // Patch and write RB_COPY_DEST_INFO. + info_out.copy_dest_info = rb_copy_dest_info; + // Override with the depth format to make sure the shader doesn't have any + // reason to try to do k_8_8_8_8 packing. + info_out.copy_dest_info.copy_dest_format = xenos::ColorFormat(dest_format); + // Handle k_16_16 and k_16_16_16_16 range. + info_out.copy_dest_info.copy_dest_exp_bias = exp_bias; + if (is_depth) { + // Single component, nothing to swap. + info_out.copy_dest_info.copy_dest_swap = false; + } + + info_out.rb_depth_clear = regs[XE_GPU_REG_RB_DEPTH_CLEAR]; + info_out.rb_color_clear = regs[XE_GPU_REG_RB_COLOR_CLEAR]; + info_out.rb_color_clear_lo = regs[XE_GPU_REG_RB_COLOR_CLEAR_LO]; + + REXGPU_TRACE( + "Resolve: {},{} <= x,y < {},{}, {} -> {} at 0x{:08X} (potentially " + "modified memory range 0x{:08X} to 0x{:08X})", + x0, y0, x1, y1, + is_depth ? xenos::GetDepthRenderTargetFormatName( + xenos::DepthRenderTargetFormat(depth_edram_info.format)) + : xenos::GetColorRenderTargetFormatName( + xenos::ColorRenderTargetFormat(color_edram_info.format)), + dest_format_info.name, rb_copy_dest_base, copy_dest_extent_start, copy_dest_extent_end); + + return true; +} + +ResolveCopyShaderIndex ResolveInfo::GetCopyShader(uint32_t draw_resolution_scale_x, + uint32_t draw_resolution_scale_y, + ResolveCopyShaderConstants& constants_out, + uint32_t& group_count_x_out, + uint32_t& group_count_y_out) const { + ResolveCopyShaderIndex shader = ResolveCopyShaderIndex::kUnknown; + bool is_depth = IsCopyingDepth(); + ResolveEdramInfo edram_info = is_depth ? depth_edram_info : color_edram_info; + bool source_is_64bpp = !is_depth && color_edram_info.format_is_64bpp != 0; + if (is_depth || + (!copy_dest_info.copy_dest_exp_bias && + xenos::IsSingleCopySampleSelected(copy_dest_coordinate_info.copy_sample_select) && + xenos::IsColorResolveFormatBitwiseEquivalent( + xenos::ColorRenderTargetFormat(color_edram_info.format), + xenos::ColorFormat(copy_dest_info.copy_dest_format)))) { + if (edram_info.msaa_samples >= xenos::MsaaSamples::k4X) { + shader = source_is_64bpp ? ResolveCopyShaderIndex::kFast64bpp4xMSAA + : ResolveCopyShaderIndex::kFast32bpp4xMSAA; + } else { + shader = source_is_64bpp ? ResolveCopyShaderIndex::kFast64bpp1x2xMSAA + : ResolveCopyShaderIndex::kFast32bpp1x2xMSAA; + } + } else { + const FormatInfo& dest_format_info = + *FormatInfo::Get(xenos::TextureFormat(copy_dest_info.copy_dest_format)); + switch (dest_format_info.bits_per_pixel) { + case 8: + shader = ResolveCopyShaderIndex::kFull8bpp; + break; + case 16: + shader = ResolveCopyShaderIndex::kFull16bpp; + break; + case 32: + shader = ResolveCopyShaderIndex::kFull32bpp; + break; + case 64: + shader = ResolveCopyShaderIndex::kFull64bpp; + break; + case 128: + shader = ResolveCopyShaderIndex::kFull128bpp; + break; + default: + assert_unhandled_case(dest_format_info.bits_per_pixel); + } + } + + constants_out.dest_relative.edram_info = edram_info; + constants_out.dest_relative.coordinate_info = coordinate_info; + constants_out.dest_relative.dest_info = copy_dest_info; + constants_out.dest_relative.dest_coordinate_info = copy_dest_coordinate_info; + constants_out.dest_base = copy_dest_base; + + if (shader != ResolveCopyShaderIndex::kUnknown) { + uint32_t width = (coordinate_info.width_div_8 << xenos::kResolveAlignmentPixelsLog2) * + draw_resolution_scale_x; + uint32_t height = + (height_div_8 << xenos::kResolveAlignmentPixelsLog2) * draw_resolution_scale_y; + const ResolveCopyShaderInfo& shader_info = resolve_copy_shader_info[size_t(shader)]; + group_count_x_out = + (width + ((1 << shader_info.group_size_x_log2) - 1)) >> shader_info.group_size_x_log2; + group_count_y_out = + (height + ((1 << shader_info.group_size_y_log2) - 1)) >> shader_info.group_size_y_log2; + } else { + REXGPU_ERROR("No resolve copy compute shader for the provided configuration"); + assert_always(); + group_count_x_out = 0; + group_count_y_out = 0; + } + + return shader; +} + +} // namespace rex::graphics::draw_util diff --git a/src/graphics/util/draw_extent_estimator.cpp b/src/graphics/util/draw_extent_estimator.cpp new file mode 100644 index 0000000..47d40f7 --- /dev/null +++ b/src/graphics/util/draw_extent_estimator.cpp @@ -0,0 +1,344 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(execute_unclipped_draw_vs_on_cpu, false, "GPU", + "Execute unclipped draw vertex shader on CPU"); + +REXCVAR_DEFINE_BOOL(execute_unclipped_draw_vs_on_cpu_with_scissor, false, "GPU", + "Execute unclipped draw VS on CPU with scissor"); + +// DEFINE_bool( +// execute_unclipped_draw_vs_on_cpu, true, +// "Execute the vertex shader for draws with clipping disabled, primarily " +// "screen-space draws (such as clears), on the CPU when possible to estimate " +// "the extent of the EDRAM involved in the draw.\n" +// "Enabling this may significantly improve GPU performance as otherwise up " +// "to the entire EDRAM may be considered used in draws without clipping, " +// "potentially resulting in spurious EDRAM range ownership transfer round " +// "trips between host render targets.\n" +// "Also, on hosts where certain render target formats have to be emulated in " +// "a lossy way (for instance, 16-bit fixed-point via 16-bit floating-point), " +// "this prevents corruption of other render targets located after the " +// "current ones in the EDRAM by lossy range ownership transfers done for " +// "those draws.", +// "GPU"); +// DEFINE_bool( +// execute_unclipped_draw_vs_on_cpu_with_scissor, false, +// "Don't restrict the usage of execute_unclipped_draw_vs_on_cpu to only " +// "non-scissored draws (with the right and the bottom sides of the scissor " +// "rectangle at 8192 or beyond) even though if the scissor rectangle is " +// "present, it's usually sufficient for esimating the height of the render " +// "target.\n" +// "Enabling this may cause excessive processing of vertices on the CPU, as " +// "some games draw rectangles (for their UI, for instance) without clipping, " +// "but with a proper scissor rectangle.", +// "GPU"); + +namespace rex::graphics { + +void DrawExtentEstimator::PositionYExportSink::Export(ucode::ExportRegister export_register, + const float* value, uint32_t value_mask) { + if (export_register == ucode::ExportRegister::kVSPosition) { + if (value_mask & 0b0010) { + position_y_ = value[1]; + } + if (value_mask & 0b1000) { + position_w_ = value[3]; + } + } else if (export_register == ucode::ExportRegister::kVSPointSizeEdgeFlagKillVertex) { + if (value_mask & 0b0001) { + point_size_ = value[0]; + } + if (value_mask & 0b0100) { + vertex_kill_ = rex::memory::Reinterpret(value[2]); + } + } +} + +uint32_t DrawExtentEstimator::EstimateVertexMaxY(const Shader& vertex_shader) { + SCOPE_profile_cpu_f("gpu"); + + const RegisterFile& regs = register_file_; + + auto vgt_draw_initiator = regs.Get(); + if (!vgt_draw_initiator.num_indices) { + return 0; + } + if (vgt_draw_initiator.source_select != xenos::SourceSelect::kDMA && + vgt_draw_initiator.source_select != xenos::SourceSelect::kAutoIndex) { + // TODO(Triang3l): Support immediate indices. + return xenos::kTexture2DCubeMaxWidthHeight; + } + + // Not reproducing tessellation. + if (xenos::IsMajorModeExplicit(vgt_draw_initiator.major_mode, vgt_draw_initiator.prim_type) && + regs.Get().path_select == + xenos::VGTOutputPath::kTessellationEnable) { + return xenos::kTexture2DCubeMaxWidthHeight; + } + + assert_true(vertex_shader.type() == xenos::ShaderType::kVertex); + assert_true(vertex_shader.is_ucode_analyzed()); + if (!ShaderInterpreter::CanInterpretShader(vertex_shader)) { + return xenos::kTexture2DCubeMaxWidthHeight; + } + + auto vgt_dma_size = regs.Get(); + union { + const void* index_buffer; + const uint16_t* index_buffer_16; + const uint32_t* index_buffer_32; + }; + xenos::Endian index_endian = vgt_dma_size.swap_mode; + if (vgt_draw_initiator.source_select == xenos::SourceSelect::kDMA) { + xenos::IndexFormat index_format = vgt_draw_initiator.index_size; + uint32_t index_buffer_base = regs[XE_GPU_REG_VGT_DMA_BASE]; + uint32_t index_buffer_read_count = + std::min(uint32_t(vgt_draw_initiator.num_indices), uint32_t(vgt_dma_size.num_words)); + if (vgt_draw_initiator.index_size == xenos::IndexFormat::kInt16) { + // Handle the index endianness to same way as the PrimitiveProcessor. + if (index_endian == xenos::Endian::k8in32) { + index_endian = xenos::Endian::k8in16; + } else if (index_endian == xenos::Endian::k16in32) { + index_endian = xenos::Endian::kNone; + } + index_buffer_base &= ~uint32_t(sizeof(uint16_t) - 1); + if (trace_writer_) { + trace_writer_->WriteMemoryRead(index_buffer_base, + sizeof(uint16_t) * index_buffer_read_count); + } + } else { + assert_true(vgt_draw_initiator.index_size == xenos::IndexFormat::kInt32); + index_buffer_base &= ~uint32_t(sizeof(uint32_t) - 1); + if (trace_writer_) { + trace_writer_->WriteMemoryRead(index_buffer_base, + sizeof(uint32_t) * index_buffer_read_count); + } + } + index_buffer = memory_.TranslatePhysical(index_buffer_base); + } + auto pa_su_sc_mode_cntl = regs.Get(); + uint32_t reset_index = regs.Get().reset_indx; + uint32_t index_offset = regs.Get().indx_offset; + uint32_t min_index = regs.Get().min_indx; + uint32_t max_index = regs.Get().max_indx; + + auto pa_cl_vte_cntl = regs.Get(); + float viewport_y_scale = + pa_cl_vte_cntl.vport_y_scale_ena ? regs.Get(XE_GPU_REG_PA_CL_VPORT_YSCALE) : 1.0f; + float viewport_y_offset = + pa_cl_vte_cntl.vport_y_offset_ena ? regs.Get(XE_GPU_REG_PA_CL_VPORT_YOFFSET) : 0.0f; + + int32_t point_vertex_min_diameter_float = 0; + int32_t point_vertex_max_diameter_float = 0; + float point_constant_radius_y = 0.0f; + if (vgt_draw_initiator.prim_type == xenos::PrimitiveType::kPointList) { + auto pa_su_point_minmax = regs.Get(); + point_vertex_min_diameter_float = + rex::memory::Reinterpret(float(pa_su_point_minmax.min_size) * (2.0f / 16.0f)); + point_vertex_max_diameter_float = + rex::memory::Reinterpret(float(pa_su_point_minmax.max_size) * (2.0f / 16.0f)); + point_constant_radius_y = float(regs.Get().height) * (1.0f / 16.0f); + } + + float max_y = -FLT_MAX; + + shader_interpreter_.SetShader(vertex_shader); + + PositionYExportSink position_y_export_sink; + shader_interpreter_.SetExportSink(&position_y_export_sink); + for (uint32_t i = 0; i < vgt_draw_initiator.num_indices; ++i) { + uint32_t vertex_index; + if (vgt_draw_initiator.source_select == xenos::SourceSelect::kDMA) { + if (i < vgt_dma_size.num_words) { + if (vgt_draw_initiator.index_size == xenos::IndexFormat::kInt16) { + vertex_index = index_buffer_16[i]; + } else { + vertex_index = index_buffer_32[i]; + } + // The Xenos only uses 24 bits of the index (reset_indx is 24-bit). + vertex_index = xenos::GpuSwap(vertex_index, index_endian) & 0xFFFFFF; + } else { + vertex_index = 0; + } + if (pa_su_sc_mode_cntl.multi_prim_ib_ena && vertex_index == reset_index) { + continue; + } + } else { + assert_true(vgt_draw_initiator.source_select == xenos::SourceSelect::kAutoIndex); + vertex_index = i; + } + vertex_index = + std::min(max_index, std::max(min_index, (vertex_index + index_offset) & 0xFFFFFF)); + + position_y_export_sink.Reset(); + + shader_interpreter_.temp_registers()[0] = float(vertex_index); + shader_interpreter_.Execute(); + + if (position_y_export_sink.vertex_kill().has_value() && + (position_y_export_sink.vertex_kill().value() & ~(UINT32_C(1) << 31))) { + continue; + } + if (!position_y_export_sink.position_y().has_value()) { + continue; + } + float vertex_y = position_y_export_sink.position_y().value(); + if (!pa_cl_vte_cntl.vtx_xy_fmt) { + if (!position_y_export_sink.position_w().has_value()) { + continue; + } + vertex_y /= position_y_export_sink.position_w().value(); + } + + vertex_y = vertex_y * viewport_y_scale + viewport_y_offset; + + if (vgt_draw_initiator.prim_type == xenos::PrimitiveType::kPointList) { + float point_radius_y; + if (position_y_export_sink.point_size().has_value()) { + // Vertex-specified diameter. Clamped effectively as a signed integer in + // the hardware, -NaN, -Infinity ... -0 to the minimum, +Infinity, +NaN + // to the maximum. + point_radius_y = 0.5f * rex::memory::Reinterpret(std::min( + point_vertex_max_diameter_float, + std::max(point_vertex_min_diameter_float, + rex::memory::Reinterpret( + position_y_export_sink.point_size().value())))); + } else { + // Constant radius. + point_radius_y = point_constant_radius_y; + } + vertex_y += point_radius_y; + } + + // std::max is `a < b ? b : a`, thus in case of NaN, the first argument is + // always returned - max_y, which is initialized to a normalized value. + max_y = std::max(max_y, vertex_y); + } + shader_interpreter_.SetExportSink(nullptr); + + int32_t max_y_24p8 = ui::FloatToD3D11Fixed16p8(max_y); + // 16p8 range is -32768 to 32767+255/256, but it's stored as uint32_t here, + // as 24p8, so overflowing up to -8388608 to 8388608+255/256 is safe. The + // range of the window offset plus the half-pixel offset is -16384 to 16384.5, + // so it's safe to add both - adding it will neither move the 16p8 clamping + // bounds -32768 and 32767+255/256 into the 0...8192 screen space range, nor + // cause 24p8 overflow. + if (regs.Get().pix_center == xenos::PixelCenter::kD3DZero) { + max_y_24p8 += 128; + } + if (pa_su_sc_mode_cntl.vtx_window_offset_enable) { + max_y_24p8 += regs.Get().window_y_offset * 256; + } + // Top-left rule - .5 exclusive without MSAA, 1. exclusive with MSAA. + auto rb_surface_info = regs.Get(); + return (uint32_t(std::max(int32_t(0), max_y_24p8)) + + ((rb_surface_info.msaa_samples == xenos::MsaaSamples::k1X) ? 127 : 255)) >> + 8; +} + +uint32_t DrawExtentEstimator::EstimateMaxY(bool try_to_estimate_vertex_max_y, + const Shader& vertex_shader) { + SCOPE_profile_cpu_f("gpu"); + + const RegisterFile& regs = register_file_; + + auto pa_sc_window_offset = regs.Get(); + int32_t window_y_offset = pa_sc_window_offset.window_y_offset; + + // Scissor. + auto pa_sc_window_scissor_br = regs.Get(); + int32_t scissor_bottom = int32_t(pa_sc_window_scissor_br.br_y); + bool scissor_window_offset = !regs.Get().window_offset_disable; + if (scissor_window_offset) { + scissor_bottom += window_y_offset; + } + auto pa_sc_screen_scissor_br = regs.Get(); + scissor_bottom = std::min(scissor_bottom, int32_t(pa_sc_screen_scissor_br.br_y)); + uint32_t max_y = uint32_t(std::max(scissor_bottom, int32_t(0))); + + if (regs.Get().clip_disable) { + // Actual extent from the vertices. + if (try_to_estimate_vertex_max_y && REXCVAR_GET(execute_unclipped_draw_vs_on_cpu)) { + bool estimate_vertex_max_y; + if (REXCVAR_GET(execute_unclipped_draw_vs_on_cpu_with_scissor)) { + estimate_vertex_max_y = true; + } else { + estimate_vertex_max_y = false; + if (scissor_bottom >= xenos::kTexture2DCubeMaxWidthHeight) { + // Handle just the usual special 8192x8192 case in Direct3D 9 - 8192 + // may be a normal render target height (80x8192 is well within the + // EDRAM size, for instance), no need to process the vertices on the + // CPU in this case. + int32_t scissor_right = int32_t(pa_sc_window_scissor_br.br_x); + if (scissor_window_offset) { + scissor_right += pa_sc_window_offset.window_x_offset; + } + scissor_right = std::min(scissor_right, int32_t(pa_sc_screen_scissor_br.br_x)); + if (scissor_right >= xenos::kTexture2DCubeMaxWidthHeight) { + estimate_vertex_max_y = true; + } + } + } + if (estimate_vertex_max_y) { + max_y = std::min(max_y, EstimateVertexMaxY(vertex_shader)); + } + } + } else { + // Viewport. Though the Xenos itself doesn't have an implicit viewport + // scissor (it's set by Direct3D 9 when a viewport is used), on hosts, it + // usually exists and can't be disabled. + auto pa_cl_vte_cntl = regs.Get(); + float viewport_bottom = 0.0f; + // First calculate all the integer.0 or integer.5 offsetting exactly at full + // precision. + if (regs.Get().vtx_window_offset_enable) { + viewport_bottom += float(window_y_offset); + } + if (regs.Get().pix_center == xenos::PixelCenter::kD3DZero) { + viewport_bottom += 0.5f; + } + // Then apply the floating-point viewport offset. + if (pa_cl_vte_cntl.vport_y_offset_ena) { + viewport_bottom += regs.Get(XE_GPU_REG_PA_CL_VPORT_YOFFSET); + } + viewport_bottom += pa_cl_vte_cntl.vport_y_scale_ena + ? std::abs(regs.Get(XE_GPU_REG_PA_CL_VPORT_YSCALE)) + : 1.0f; + // Using floor, or, rather, truncation (because maxing with zero anyway) + // similar to how viewport scissoring behaves on real AMD, Intel and Nvidia + // GPUs on Direct3D 12 (but not WARP), also like in + // draw_util::GetHostViewportInfo. + // max(0.0f, viewport_bottom) to drop NaN and < 0 - max picks the first + // argument in the !(a < b) case (always for NaN), min as float (max_y is + // well below 2^24) to safely drop very large values. + max_y = uint32_t(std::min(float(max_y), std::max(0.0f, viewport_bottom))); + } + + return max_y; +} + +} // namespace rex::graphics diff --git a/src/graphics/vulkan/command_processor.cpp b/src/graphics/vulkan/command_processor.cpp new file mode 100644 index 0000000..a40436e --- /dev/null +++ b/src/graphics/vulkan/command_processor.cpp @@ -0,0 +1,6860 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Legacy backend compatibility aliases for shared readback controls. +REXCVAR_DEFINE_BOOL(vulkan_readback_resolve, false, "GPU/Vulkan", + "Read render-to-texture results on the CPU") + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +REXCVAR_DEFINE_BOOL(vulkan_readback_memexport, false, "GPU/Vulkan", + "Read data written by memory export in shaders on the CPU") + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +REXCVAR_DEFINE_BOOL(vulkan_async_skip_incomplete_frames, true, "GPU/Vulkan", + "When async shader compilation is enabled, skip presenting frames that " + "used placeholder pipelines to avoid visible flashing") + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +REXCVAR_DEFINE_BOOL(vulkan_submit_on_primary_buffer_end, true, "GPU/Vulkan", + "Submit command buffer when PM4 primary buffer ends") + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +REXCVAR_DEFINE_BOOL(vulkan_dynamic_rendering, true, "GPU/Vulkan", + "Use VK_KHR_dynamic_rendering for Vulkan GPU emulation when supported by the " + "device (falls back to render passes otherwise)") + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +namespace rex::graphics::vulkan { + +namespace { + +// glslang default built-in resource limits. +constexpr TBuiltInResource kGlslangDefaultTBuiltInResource = { + /* .maxLights = */ 32, + /* .maxClipPlanes = */ 6, + /* .maxTextureUnits = */ 32, + /* .maxTextureCoords = */ 32, + /* .maxVertexAttribs = */ 64, + /* .maxVertexUniformComponents = */ 4096, + /* .maxVaryingFloats = */ 64, + /* .maxVertexTextureImageUnits = */ 32, + /* .maxCombinedTextureImageUnits = */ 80, + /* .maxTextureImageUnits = */ 32, + /* .maxFragmentUniformComponents = */ 4096, + /* .maxDrawBuffers = */ 32, + /* .maxVertexUniformVectors = */ 128, + /* .maxVaryingVectors = */ 8, + /* .maxFragmentUniformVectors = */ 16, + /* .maxVertexOutputVectors = */ 16, + /* .maxFragmentInputVectors = */ 15, + /* .minProgramTexelOffset = */ -8, + /* .maxProgramTexelOffset = */ 7, + /* .maxClipDistances = */ 8, + /* .maxComputeWorkGroupCountX = */ 65535, + /* .maxComputeWorkGroupCountY = */ 65535, + /* .maxComputeWorkGroupCountZ = */ 65535, + /* .maxComputeWorkGroupSizeX = */ 1024, + /* .maxComputeWorkGroupSizeY = */ 1024, + /* .maxComputeWorkGroupSizeZ = */ 64, + /* .maxComputeUniformComponents = */ 1024, + /* .maxComputeTextureImageUnits = */ 16, + /* .maxComputeImageUniforms = */ 8, + /* .maxComputeAtomicCounters = */ 8, + /* .maxComputeAtomicCounterBuffers = */ 1, + /* .maxVaryingComponents = */ 60, + /* .maxVertexOutputComponents = */ 64, + /* .maxGeometryInputComponents = */ 64, + /* .maxGeometryOutputComponents = */ 128, + /* .maxFragmentInputComponents = */ 128, + /* .maxImageUnits = */ 8, + /* .maxCombinedImageUnitsAndFragmentOutputs = */ 8, + /* .maxCombinedShaderOutputResources = */ 8, + /* .maxImageSamples = */ 0, + /* .maxVertexImageUniforms = */ 0, + /* .maxTessControlImageUniforms = */ 0, + /* .maxTessEvaluationImageUniforms = */ 0, + /* .maxGeometryImageUniforms = */ 0, + /* .maxFragmentImageUniforms = */ 8, + /* .maxCombinedImageUniforms = */ 8, + /* .maxGeometryTextureImageUnits = */ 16, + /* .maxGeometryOutputVertices = */ 256, + /* .maxGeometryTotalOutputComponents = */ 1024, + /* .maxGeometryUniformComponents = */ 1024, + /* .maxGeometryVaryingComponents = */ 64, + /* .maxTessControlInputComponents = */ 128, + /* .maxTessControlOutputComponents = */ 128, + /* .maxTessControlTextureImageUnits = */ 16, + /* .maxTessControlUniformComponents = */ 1024, + /* .maxTessControlTotalOutputComponents = */ 4096, + /* .maxTessEvaluationInputComponents = */ 128, + /* .maxTessEvaluationOutputComponents = */ 128, + /* .maxTessEvaluationTextureImageUnits = */ 16, + /* .maxTessEvaluationUniformComponents = */ 1024, + /* .maxTessPatchComponents = */ 120, + /* .maxPatchVertices = */ 32, + /* .maxTessGenLevel = */ 64, + /* .maxViewports = */ 16, + /* .maxVertexAtomicCounters = */ 0, + /* .maxTessControlAtomicCounters = */ 0, + /* .maxTessEvaluationAtomicCounters = */ 0, + /* .maxGeometryAtomicCounters = */ 0, + /* .maxFragmentAtomicCounters = */ 8, + /* .maxCombinedAtomicCounters = */ 8, + /* .maxAtomicCounterBindings = */ 1, + /* .maxVertexAtomicCounterBuffers = */ 0, + /* .maxTessControlAtomicCounterBuffers = */ 0, + /* .maxTessEvaluationAtomicCounterBuffers = */ 0, + /* .maxGeometryAtomicCounterBuffers = */ 0, + /* .maxFragmentAtomicCounterBuffers = */ 1, + /* .maxCombinedAtomicCounterBuffers = */ 1, + /* .maxAtomicCounterBufferSize = */ 16384, + /* .maxTransformFeedbackBuffers = */ 4, + /* .maxTransformFeedbackInterleavedComponents = */ 64, + /* .maxCullDistances = */ 8, + /* .maxCombinedClipAndCullDistances = */ 8, + /* .maxSamples = */ 4, + /* .maxMeshOutputVerticesNV = */ 256, + /* .maxMeshOutputPrimitivesNV = */ 512, + /* .maxMeshWorkGroupSizeX_NV = */ 32, + /* .maxMeshWorkGroupSizeY_NV = */ 1, + /* .maxMeshWorkGroupSizeZ_NV = */ 1, + /* .maxTaskWorkGroupSizeX_NV = */ 32, + /* .maxTaskWorkGroupSizeY_NV = */ 1, + /* .maxTaskWorkGroupSizeZ_NV = */ 1, + /* .maxMeshViewCountNV = */ 4, + /* .maxDualSourceDrawBuffersEXT = */ 1, + /* .limits = */ + { + /* .nonInductiveForLoops = */ 1, + /* .whileLoops = */ 1, + /* .doWhileLoops = */ 1, + /* .generalUniformIndexing = */ 1, + /* .generalAttributeMatrixVectorIndexing = */ 1, + /* .generalVaryingIndexing = */ 1, + /* .generalSamplerIndexing = */ 1, + /* .generalVariableIndexing = */ 1, + /* .generalConstantMatrixVectorIndexing = */ 1, + }, +}; + +const char* GetSwapFxaaComputeSource(bool extreme_quality) { + return extreme_quality ? R"(#version 450 +layout(local_size_x = 16, local_size_y = 8, local_size_z = 1) in; + +layout(push_constant) uniform XeApplyGammaRampConstants { + uvec2 xe_fxaa_size; + vec2 xe_fxaa_size_inv; +}; + +layout(set = 0, binding = 0) uniform sampler2D xe_fxaa_source; +layout(set = 1, binding = 0, rgb10_a2) writeonly uniform image2D xe_fxaa_dest; + +const vec3 kLumaWeights = vec3(0.299, 0.587, 0.114); +const float kEdgeThreshold = 0.063; +const float kEdgeThresholdMin = 0.0312; +const float kSpanMax = 12.0; +const float kDirReduceMul = 0.125; +const float kDirReduceMin = 1.0 / 128.0; + +float SampleLuma(vec2 uv) { + return textureLod(xe_fxaa_source, uv, 0.0).a; +} + +void main() { + uvec2 pixel = gl_GlobalInvocationID.xy; + if (any(greaterThanEqual(pixel, xe_fxaa_size))) { + return; + } + + vec2 uv = (vec2(pixel) + vec2(0.5)) * xe_fxaa_size_inv; + vec2 texel = xe_fxaa_size_inv; + vec4 rgbm = textureLod(xe_fxaa_source, uv, 0.0); + + float lumaM = rgbm.a; + float lumaNW = SampleLuma(uv + vec2(-texel.x, -texel.y)); + float lumaNE = SampleLuma(uv + vec2( texel.x, -texel.y)); + float lumaSW = SampleLuma(uv + vec2(-texel.x, texel.y)); + float lumaSE = SampleLuma(uv + vec2( texel.x, texel.y)); + + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + float lumaRange = lumaMax - lumaMin; + + vec3 result = rgbm.rgb; + if (lumaRange >= max(kEdgeThresholdMin, lumaMax * kEdgeThreshold)) { + vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max( + (lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * kDirReduceMul), + kDirReduceMin); + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = clamp(dir * rcpDirMin, vec2(-kSpanMax), vec2(kSpanMax)) * texel; + + vec3 rgbA = + 0.5 * + (textureLod(xe_fxaa_source, uv + dir * (1.0 / 3.0 - 0.5), 0.0).rgb + + textureLod(xe_fxaa_source, uv + dir * (2.0 / 3.0 - 0.5), 0.0).rgb); + vec3 rgbB = + rgbA * 0.5 + + 0.25 * + (textureLod(xe_fxaa_source, uv + dir * -0.5, 0.0).rgb + + textureLod(xe_fxaa_source, uv + dir * 0.5, 0.0).rgb); + float lumaB = dot(rgbB, kLumaWeights); + result = (lumaB < lumaMin || lumaB > lumaMax) ? rgbA : rgbB; + } + + imageStore(xe_fxaa_dest, ivec2(pixel), vec4(result, 1.0)); +} +)" + : R"(#version 450 +layout(local_size_x = 16, local_size_y = 8, local_size_z = 1) in; + +layout(push_constant) uniform XeApplyGammaRampConstants { + uvec2 xe_fxaa_size; + vec2 xe_fxaa_size_inv; +}; + +layout(set = 0, binding = 0) uniform sampler2D xe_fxaa_source; +layout(set = 1, binding = 0, rgb10_a2) writeonly uniform image2D xe_fxaa_dest; + +const vec3 kLumaWeights = vec3(0.299, 0.587, 0.114); +const float kEdgeThreshold = 0.166; +const float kEdgeThresholdMin = 0.0833; +const float kSpanMax = 8.0; +const float kDirReduceMul = 0.125; +const float kDirReduceMin = 1.0 / 128.0; + +float SampleLuma(vec2 uv) { + return textureLod(xe_fxaa_source, uv, 0.0).a; +} + +void main() { + uvec2 pixel = gl_GlobalInvocationID.xy; + if (any(greaterThanEqual(pixel, xe_fxaa_size))) { + return; + } + + vec2 uv = (vec2(pixel) + vec2(0.5)) * xe_fxaa_size_inv; + vec2 texel = xe_fxaa_size_inv; + vec4 rgbm = textureLod(xe_fxaa_source, uv, 0.0); + + float lumaM = rgbm.a; + float lumaNW = SampleLuma(uv + vec2(-texel.x, -texel.y)); + float lumaNE = SampleLuma(uv + vec2( texel.x, -texel.y)); + float lumaSW = SampleLuma(uv + vec2(-texel.x, texel.y)); + float lumaSE = SampleLuma(uv + vec2( texel.x, texel.y)); + + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + float lumaRange = lumaMax - lumaMin; + + vec3 result = rgbm.rgb; + if (lumaRange >= max(kEdgeThresholdMin, lumaMax * kEdgeThreshold)) { + vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max( + (lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * kDirReduceMul), + kDirReduceMin); + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = clamp(dir * rcpDirMin, vec2(-kSpanMax), vec2(kSpanMax)) * texel; + + vec3 rgbA = + 0.5 * + (textureLod(xe_fxaa_source, uv + dir * (1.0 / 3.0 - 0.5), 0.0).rgb + + textureLod(xe_fxaa_source, uv + dir * (2.0 / 3.0 - 0.5), 0.0).rgb); + vec3 rgbB = + rgbA * 0.5 + + 0.25 * + (textureLod(xe_fxaa_source, uv + dir * -0.5, 0.0).rgb + + textureLod(xe_fxaa_source, uv + dir * 0.5, 0.0).rgb); + float lumaB = dot(rgbB, kLumaWeights); + result = (lumaB < lumaMin || lumaB > lumaMax) ? rgbA : rgbB; + } + + imageStore(xe_fxaa_dest, ivec2(pixel), vec4(result, 1.0)); +} +)"; +} + +const char* GetSwapApplyGammaTablePixelRbSwapSource() { + return R"(#version 450 +layout(set = 0, binding = 0) uniform textureBuffer xe_apply_gamma_ramp; +layout(set = 1, binding = 0) uniform texture2D xe_apply_gamma_source; + +layout(location = 0) out vec4 xe_apply_gamma_color; + +void main() { + ivec2 pixel = ivec2(gl_FragCoord.xy); + uvec3 source = uvec3(texelFetch(xe_apply_gamma_source, pixel, 0).rgb * 255.0 + vec3(0.5)).bgr; + xe_apply_gamma_color = vec4( + texelFetch(xe_apply_gamma_ramp, int(source.r)).b, + texelFetch(xe_apply_gamma_ramp, int(source.g)).g, + texelFetch(xe_apply_gamma_ramp, int(source.b)).r, + 1.0); +} +)"; +} + +const char* GetSwapApplyGammaPwlPixelRbSwapSource() { + return R"(#version 450 +layout(set = 0, binding = 0) uniform utextureBuffer xe_apply_gamma_ramp; +layout(set = 1, binding = 0) uniform texture2D xe_apply_gamma_source; + +layout(location = 0) out vec4 xe_apply_gamma_color; + +float ApplyPwl(uint source_value_10b, uint channel) { + uint source_value_base = source_value_10b >> 3u; + uvec4 pwl = texelFetch(xe_apply_gamma_ramp, int(source_value_base * 3u + channel)); + float value = float(pwl.x) + float((source_value_10b & 7u) * pwl.y) * 0.125; + return clamp(value * 1.52737048e-05, 0.0, 1.0); +} + +void main() { + ivec2 pixel = ivec2(gl_FragCoord.xy); + uvec3 source = uvec3(texelFetch(xe_apply_gamma_source, pixel, 0).rgb * 1023.0 + vec3(0.5)).bgr; + xe_apply_gamma_color = vec4( + ApplyPwl(source.r, 0u), + ApplyPwl(source.g, 1u), + ApplyPwl(source.b, 2u), + 1.0); +} +)"; +} + +const char* GetSwapApplyGammaTableComputeRbSwapSource() { + return R"(#version 450 +layout(local_size_x = 16, local_size_y = 8, local_size_z = 1) in; + +layout(push_constant) uniform XeApplyGammaRampConstants { + uvec2 xe_apply_gamma_size; +}; + +layout(set = 0, binding = 0) uniform textureBuffer xe_apply_gamma_ramp; +layout(set = 1, binding = 0) uniform texture2D xe_apply_gamma_source; +layout(set = 2, binding = 0, rgb10_a2) writeonly uniform image2D xe_apply_gamma_dest; + +void main() { + ivec2 pixel = ivec2(gl_GlobalInvocationID.xy); + if (any(greaterThanEqual(uvec2(pixel), xe_apply_gamma_size))) { + return; + } + + uvec3 source = uvec3(texelFetch(xe_apply_gamma_source, pixel, 0).rgb * 255.0 + vec3(0.5)).bgr; + imageStore( + xe_apply_gamma_dest, pixel, + vec4(texelFetch(xe_apply_gamma_ramp, int(source.r)).b, + texelFetch(xe_apply_gamma_ramp, int(source.g)).g, + texelFetch(xe_apply_gamma_ramp, int(source.b)).r, 1.0)); +} +)"; +} + +const char* GetSwapApplyGammaPwlComputeRbSwapSource() { + return R"(#version 450 +layout(local_size_x = 16, local_size_y = 8, local_size_z = 1) in; + +layout(push_constant) uniform XeApplyGammaRampConstants { + uvec2 xe_apply_gamma_size; +}; + +layout(set = 0, binding = 0) uniform utextureBuffer xe_apply_gamma_ramp; +layout(set = 1, binding = 0) uniform texture2D xe_apply_gamma_source; +layout(set = 2, binding = 0, rgb10_a2) writeonly uniform image2D xe_apply_gamma_dest; + +float ApplyPwl(uint source_value_10b, uint channel) { + uint source_value_base = source_value_10b >> 3u; + uvec4 pwl = texelFetch(xe_apply_gamma_ramp, int(source_value_base * 3u + channel)); + float value = float(pwl.x) + float((source_value_10b & 7u) * pwl.y) * 0.125; + return clamp(value * 1.52737048e-05, 0.0, 1.0); +} + +void main() { + ivec2 pixel = ivec2(gl_GlobalInvocationID.xy); + if (any(greaterThanEqual(uvec2(pixel), xe_apply_gamma_size))) { + return; + } + + uvec3 source = uvec3(texelFetch(xe_apply_gamma_source, pixel, 0).rgb * 1023.0 + vec3(0.5)).bgr; + imageStore(xe_apply_gamma_dest, pixel, + vec4(ApplyPwl(source.r, 0u), ApplyPwl(source.g, 1u), + ApplyPwl(source.b, 2u), 1.0)); +} +)"; +} + +const char* GetSwapApplyGammaTableFxaaLumaComputeRbSwapSource() { + return R"(#version 450 +layout(local_size_x = 16, local_size_y = 8, local_size_z = 1) in; + +layout(push_constant) uniform XeApplyGammaRampConstants { + uvec2 xe_apply_gamma_size; +}; + +layout(set = 0, binding = 0) uniform textureBuffer xe_apply_gamma_ramp; +layout(set = 1, binding = 0) uniform texture2D xe_apply_gamma_source; +layout(set = 2, binding = 0, rgba16f) writeonly uniform image2D xe_apply_gamma_dest; + +const vec3 kLumaWeights = vec3(0.299, 0.587, 0.114); + +void main() { + ivec2 pixel = ivec2(gl_GlobalInvocationID.xy); + if (any(greaterThanEqual(uvec2(pixel), xe_apply_gamma_size))) { + return; + } + + uvec3 source = uvec3(texelFetch(xe_apply_gamma_source, pixel, 0).rgb * 255.0 + vec3(0.5)).bgr; + vec3 rgb = vec3(texelFetch(xe_apply_gamma_ramp, int(source.r)).b, + texelFetch(xe_apply_gamma_ramp, int(source.g)).g, + texelFetch(xe_apply_gamma_ramp, int(source.b)).r); + imageStore(xe_apply_gamma_dest, pixel, vec4(rgb, dot(rgb, kLumaWeights))); +} +)"; +} + +const char* GetSwapApplyGammaPwlFxaaLumaComputeRbSwapSource() { + return R"(#version 450 +layout(local_size_x = 16, local_size_y = 8, local_size_z = 1) in; + +layout(push_constant) uniform XeApplyGammaRampConstants { + uvec2 xe_apply_gamma_size; +}; + +layout(set = 0, binding = 0) uniform utextureBuffer xe_apply_gamma_ramp; +layout(set = 1, binding = 0) uniform texture2D xe_apply_gamma_source; +layout(set = 2, binding = 0, rgba16f) writeonly uniform image2D xe_apply_gamma_dest; + +const vec3 kLumaWeights = vec3(0.299, 0.587, 0.114); + +float ApplyPwl(uint source_value_10b, uint channel) { + uint source_value_base = source_value_10b >> 3u; + uvec4 pwl = texelFetch(xe_apply_gamma_ramp, int(source_value_base * 3u + channel)); + float value = float(pwl.x) + float((source_value_10b & 7u) * pwl.y) * 0.125; + return clamp(value * 1.52737048e-05, 0.0, 1.0); +} + +void main() { + ivec2 pixel = ivec2(gl_GlobalInvocationID.xy); + if (any(greaterThanEqual(uvec2(pixel), xe_apply_gamma_size))) { + return; + } + + uvec3 source = uvec3(texelFetch(xe_apply_gamma_source, pixel, 0).rgb * 1023.0 + vec3(0.5)).bgr; + vec3 rgb = vec3(ApplyPwl(source.r, 0u), ApplyPwl(source.g, 1u), + ApplyPwl(source.b, 2u)); + imageStore(xe_apply_gamma_dest, pixel, vec4(rgb, dot(rgb, kLumaWeights))); +} +)"; +} + +bool CompileGlslToSpirvInternal(EShLanguage stage, std::string_view source, + std::vector& spirv_out, std::string& error_out) { + static std::once_flag glslang_initialize_once; + std::call_once(glslang_initialize_once, []() { glslang::InitializeProcess(); }); + + const char* source_c_str = source.data(); + glslang::TShader shader(stage); + shader.setStrings(&source_c_str, 1); + shader.setEnvInput(glslang::EShSourceGlsl, stage, glslang::EShClientVulkan, 450); + shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_0); + shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_0); + + EShMessages messages = EShMessages(EShMsgSpvRules | EShMsgVulkanRules); + if (!shader.parse(&kGlslangDefaultTBuiltInResource, 450, false, messages)) { + error_out = "glslang shader parse failed"; + if (const char* shader_log = shader.getInfoLog(); + shader_log != nullptr && shader_log[0] != '\0') { + error_out += ": "; + error_out += shader_log; + } + return false; + } + + glslang::TProgram program; + program.addShader(&shader); + if (!program.link(messages)) { + error_out = "glslang program link failed"; + if (const char* program_log = program.getInfoLog(); + program_log != nullptr && program_log[0] != '\0') { + error_out += ": "; + error_out += program_log; + } + return false; + } + + const glslang::TIntermediate* intermediate = program.getIntermediate(stage); + if (intermediate == nullptr) { + error_out = "glslang produced no stage intermediate"; + return false; + } + + glslang::SpvOptions spv_options = {}; + spv_options.disableOptimizer = true; + spv_options.optimizeSize = false; + glslang::GlslangToSpv(*intermediate, spirv_out, &spv_options); + if (spirv_out.empty()) { + error_out = "glslang produced empty SPIR-V"; + return false; + } + return true; +} + +} // namespace + +// Generated with `xb buildshaders`. +namespace shaders { +#include "../shaders/vulkan_spirv/apply_gamma_pwl_cs.h" +#include "../shaders/vulkan_spirv/apply_gamma_pwl_fxaa_luma_ps.h" +#include "../shaders/vulkan_spirv/apply_gamma_pwl_fxaa_luma_cs.h" +#include "../shaders/vulkan_spirv/apply_gamma_pwl_ps.h" +#include "../shaders/vulkan_spirv/apply_gamma_table_cs.h" +#include "../shaders/vulkan_spirv/apply_gamma_table_fxaa_luma_ps.h" +#include "../shaders/vulkan_spirv/apply_gamma_table_fxaa_luma_cs.h" +#include "../shaders/vulkan_spirv/apply_gamma_table_ps.h" +#include "../shaders/vulkan_spirv/fullscreen_cw_vs.h" +#include "../shaders/vulkan_spirv/resolve_downscale_cs.h" +} // namespace shaders + +const VkDescriptorPoolSize VulkanCommandProcessor::kDescriptorPoolSizeUniformBuffer = { + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + SpirvShaderTranslator::kConstantBufferCount* kLinkedTypeDescriptorPoolSetCount}; + +const VkDescriptorPoolSize VulkanCommandProcessor::kDescriptorPoolSizeStorageBuffer = { + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2 * kLinkedTypeDescriptorPoolSetCount}; + +// 2x descriptors for texture images because of unsigned and signed bindings. +const VkDescriptorPoolSize VulkanCommandProcessor::kDescriptorPoolSizeTextures[2] = { + {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2 * kLinkedTypeDescriptorPoolSetCount}, + {VK_DESCRIPTOR_TYPE_SAMPLER, kLinkedTypeDescriptorPoolSetCount}, +}; + +VulkanCommandProcessor::VulkanCommandProcessor(VulkanGraphicsSystem* graphics_system, + system::KernelState* kernel_state) + : CommandProcessor(graphics_system, kernel_state), + deferred_command_buffer_(*this), + transient_descriptor_allocator_uniform_buffer_( + static_cast(graphics_system->provider()) + ->vulkan_device(), + &kDescriptorPoolSizeUniformBuffer, 1, kLinkedTypeDescriptorPoolSetCount), + transient_descriptor_allocator_storage_buffer_( + static_cast(graphics_system->provider()) + ->vulkan_device(), + &kDescriptorPoolSizeStorageBuffer, 1, kLinkedTypeDescriptorPoolSetCount), + transient_descriptor_allocator_textures_( + static_cast(graphics_system->provider()) + ->vulkan_device(), + kDescriptorPoolSizeTextures, uint32_t(rex::countof(kDescriptorPoolSizeTextures)), + kLinkedTypeDescriptorPoolSetCount) { + legacy_readback_memexport_cvar_name_ = "vulkan_readback_memexport"; +} + +VulkanCommandProcessor::~VulkanCommandProcessor() = default; + +void VulkanCommandProcessor::ClearCaches() { + CommandProcessor::ClearCaches(); + InvalidateAllVertexBufferResidency(); + cache_clear_requested_ = true; +} + +void VulkanCommandProcessor::InvalidateGpuMemory() { + if (shared_memory_) { + shared_memory_->InvalidateAllPages(); + } +} + +void VulkanCommandProcessor::InvalidateAllVertexBufferResidency() { + vertex_buffers_in_sync_[0] = 0; + vertex_buffers_in_sync_[1] = 0; + for (VertexBufferState& state : vertex_buffer_states_) { + state.address = UINT32_MAX; + state.size = UINT32_MAX; + } +} + +void VulkanCommandProcessor::InvalidateVertexBufferResidency(uint32_t vfetch_index) { + if (vfetch_index >= vertex_buffer_states_.size()) { + return; + } + vertex_buffers_in_sync_[vfetch_index >> 6] &= ~(uint64_t(1) << (vfetch_index & 63)); +} + +void VulkanCommandProcessor::InvalidateVertexBufferResidencyRange(uint32_t first_vfetch, + uint32_t last_vfetch) { + if (first_vfetch > last_vfetch) { + std::swap(first_vfetch, last_vfetch); + } + if (first_vfetch >= vertex_buffer_states_.size()) { + return; + } + last_vfetch = std::min(last_vfetch, uint32_t(vertex_buffer_states_.size() - 1)); + for (uint32_t vfetch_index = first_vfetch; vfetch_index <= last_vfetch; ++vfetch_index) { + InvalidateVertexBufferResidency(vfetch_index); + } +} + +void VulkanCommandProcessor::InitializeShaderStorage(const std::filesystem::path& cache_root, + uint32_t title_id, bool blocking) { + CommandProcessor::InitializeShaderStorage(cache_root, title_id, blocking); + pipeline_cache_->InitializeShaderStorage(cache_root, title_id, blocking); +} + +void VulkanCommandProcessor::TracePlaybackWroteMemory(uint32_t base_ptr, uint32_t length) { + shared_memory_->MemoryInvalidationCallback(base_ptr, length, true); + primitive_processor_->MemoryInvalidationCallback(base_ptr, length, true); +} + +void VulkanCommandProcessor::RestoreEdramSnapshot(const void* snapshot) { + if (!BeginSubmission(true)) { + return; + } + render_target_cache_->RestoreEdramSnapshot(snapshot); +} + +bool VulkanCommandProcessor::ExecutePacketType3_EVENT_WRITE_ZPD(memory::RingBuffer* reader, + uint32_t packet, uint32_t count) { + if (!REXCVAR_GET(occlusion_query_enable) || !occlusion_query_resources_available_) { + return CommandProcessor::ExecutePacketType3_EVENT_WRITE_ZPD(reader, packet, count); + } + + const uint32_t kQueryFinished = rex::byte_swap(0xFFFFFEED); + assert_true(count == 1); + uint32_t initiator = reader->ReadAndSwap(); + WriteRegister(XE_GPU_REG_VGT_EVENT_INITIATOR, initiator & 0x3F); + + uint32_t sample_count_addr = register_file_->values[XE_GPU_REG_RB_SAMPLE_COUNT_ADDR]; + auto* sample_counts = + memory_->TranslatePhysical(sample_count_addr); + if (!sample_counts) { + DisableHostOcclusionQueries(); + return true; + } + + auto write_fallback_result = [sample_counts]() -> bool { + auto fake_sample_count = REXCVAR_GET(query_occlusion_fake_sample_count); + if (fake_sample_count < 0) { + return true; + } + bool is_end_via_z_pass = + sample_counts->ZPass_A == kQueryFinished && sample_counts->ZPass_B == kQueryFinished; + bool is_end_via_z_fail = + sample_counts->ZFail_A == kQueryFinished && sample_counts->ZFail_B == kQueryFinished; + std::memset(sample_counts, 0, sizeof(xenos::xe_gpu_depth_sample_counts)); + if (is_end_via_z_pass || is_end_via_z_fail) { + sample_counts->ZPass_A = fake_sample_count; + sample_counts->Total_A = fake_sample_count; + } + return true; + }; + + bool is_end_via_z_pass = + sample_counts->ZPass_A == kQueryFinished && sample_counts->ZPass_B == kQueryFinished; + bool is_end_via_z_fail = + sample_counts->ZFail_A == kQueryFinished && sample_counts->ZFail_B == kQueryFinished; + bool is_end = is_end_via_z_pass || is_end_via_z_fail; + + if (!is_end) { + if (active_occlusion_query_.valid && + active_occlusion_query_.sample_count_address != sample_count_addr) { + DisableHostOcclusionQueries(); + return write_fallback_result(); + } + if (!BeginGuestOcclusionQuery(sample_count_addr)) { + return write_fallback_result(); + } + return true; + } + + if (!active_occlusion_query_.valid || + active_occlusion_query_.sample_count_address != sample_count_addr) { + DisableHostOcclusionQueries(); + return write_fallback_result(); + } + + if (!EndGuestOcclusionQuery(sample_count_addr)) { + return write_fallback_result(); + } + return true; +} + +std::string VulkanCommandProcessor::GetWindowTitleText() const { + std::ostringstream title; + title << "Vulkan"; + if (render_target_cache_) { + switch (render_target_cache_->GetPath()) { + case RenderTargetCache::Path::kHostRenderTargets: + title << " - FBO"; + break; + case RenderTargetCache::Path::kPixelShaderInterlock: + title << " - FSI"; + break; + default: + break; + } + uint32_t draw_resolution_scale_x = + texture_cache_ ? texture_cache_->draw_resolution_scale_x() : 1; + uint32_t draw_resolution_scale_y = + texture_cache_ ? texture_cache_->draw_resolution_scale_y() : 1; + if (draw_resolution_scale_x > 1 || draw_resolution_scale_y > 1) { + title << ' ' << draw_resolution_scale_x << 'x' << draw_resolution_scale_y; + } + } + title << " - HEAVILY INCOMPLETE, early development"; + return title.str(); +} + +bool VulkanCommandProcessor::CompileGlslToSpirv(VkShaderStageFlagBits stage, + std::string_view source, + std::vector& spirv_out, + std::string& error_out) const { + EShLanguage glslang_stage; + switch (stage) { + case VK_SHADER_STAGE_VERTEX_BIT: + glslang_stage = EShLangVertex; + break; + case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: + glslang_stage = EShLangTessControl; + break; + case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: + glslang_stage = EShLangTessEvaluation; + break; + case VK_SHADER_STAGE_GEOMETRY_BIT: + glslang_stage = EShLangGeometry; + break; + case VK_SHADER_STAGE_FRAGMENT_BIT: + glslang_stage = EShLangFragment; + break; + case VK_SHADER_STAGE_COMPUTE_BIT: + glslang_stage = EShLangCompute; + break; + default: + error_out = fmt::format("Unsupported Vulkan shader stage mask {}", uint32_t(stage)); + return false; + } + return CompileGlslToSpirvInternal(glslang_stage, source, spirv_out, error_out); +} + +bool VulkanCommandProcessor::SetupContext() { + if (!CommandProcessor::SetupContext()) { + REXGPU_ERROR("Failed to initialize base command processor context"); + return false; + } + InvalidateAllVertexBufferResidency(); + + const ui::vulkan::VulkanDevice* const vulkan_device = GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + const ui::vulkan::VulkanDevice::Properties& device_properties = vulkan_device->properties(); + + // The unconditional inclusion of the vertex shader stage also covers the case + // of manual index / factor buffer fetch (the system constants and the shared + // memory are needed for that) in the tessellation vertex shader when + // fullDrawIndexUint32 is not supported. + guest_shader_pipeline_stages_ = + VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + guest_shader_vertex_stages_ = VK_SHADER_STAGE_VERTEX_BIT; + if (device_properties.tessellationShader) { + guest_shader_pipeline_stages_ |= VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | + VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT; + guest_shader_vertex_stages_ |= + VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; + } + if (!device_properties.vertexPipelineStoresAndAtomics) { + // For memory export from vertex shaders converted to compute shaders. + guest_shader_pipeline_stages_ |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + guest_shader_vertex_stages_ |= VK_SHADER_STAGE_COMPUTE_BIT; + } + + // 16384 is bigger than any single uniform buffer that Xenia needs, but is the + // minimum maxUniformBufferRange, thus the safe minimum amount. + uniform_buffer_pool_ = std::make_unique( + vulkan_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + rex::align(std::max(ui::GraphicsUploadBufferPool::kDefaultPageSize, size_t(16384)), + size_t(device_properties.minUniformBufferOffsetAlignment))); + + // Descriptor set layouts that don't depend on the setup of other subsystems. + VkShaderStageFlags guest_shader_stages = + guest_shader_vertex_stages_ | VK_SHADER_STAGE_FRAGMENT_BIT; + // Empty. + VkDescriptorSetLayoutCreateInfo descriptor_set_layout_create_info; + descriptor_set_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + descriptor_set_layout_create_info.pNext = nullptr; + descriptor_set_layout_create_info.flags = 0; + descriptor_set_layout_create_info.bindingCount = 0; + descriptor_set_layout_create_info.pBindings = nullptr; + if (dfn.vkCreateDescriptorSetLayout(device, &descriptor_set_layout_create_info, nullptr, + &descriptor_set_layout_empty_) != VK_SUCCESS) { + REXGPU_ERROR("Failed to create an empty Vulkan descriptor set layout"); + return false; + } + // Guest draw constants. + VkDescriptorSetLayoutBinding + descriptor_set_layout_bindings_constants[SpirvShaderTranslator::kConstantBufferCount] = {}; + for (uint32_t i = 0; i < SpirvShaderTranslator::kConstantBufferCount; ++i) { + VkDescriptorSetLayoutBinding& constants_binding = descriptor_set_layout_bindings_constants[i]; + constants_binding.binding = i; + constants_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + constants_binding.descriptorCount = 1; + constants_binding.pImmutableSamplers = nullptr; + } + descriptor_set_layout_bindings_constants[SpirvShaderTranslator::kConstantBufferSystem] + .stageFlags = + guest_shader_stages | + (device_properties.tessellationShader ? VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT : 0) | + (device_properties.geometryShader ? VK_SHADER_STAGE_GEOMETRY_BIT : 0); + descriptor_set_layout_bindings_constants[SpirvShaderTranslator::kConstantBufferFloatVertex] + .stageFlags = guest_shader_vertex_stages_; + descriptor_set_layout_bindings_constants[SpirvShaderTranslator::kConstantBufferFloatPixel] + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + descriptor_set_layout_bindings_constants[SpirvShaderTranslator::kConstantBufferBoolLoop] + .stageFlags = guest_shader_stages; + descriptor_set_layout_bindings_constants[SpirvShaderTranslator::kConstantBufferFetch].stageFlags = + guest_shader_stages; + descriptor_set_layout_create_info.bindingCount = + uint32_t(rex::countof(descriptor_set_layout_bindings_constants)); + descriptor_set_layout_create_info.pBindings = descriptor_set_layout_bindings_constants; + if (dfn.vkCreateDescriptorSetLayout(device, &descriptor_set_layout_create_info, nullptr, + &descriptor_set_layout_constants_) != VK_SUCCESS) { + REXGPU_ERROR( + "Failed to create a Vulkan descriptor set layout for guest draw " + "constant buffers"); + return false; + } + // Transient: storage buffer for compute shaders. + VkDescriptorSetLayoutBinding descriptor_set_layout_binding_transient; + descriptor_set_layout_binding_transient.binding = 0; + descriptor_set_layout_binding_transient.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + descriptor_set_layout_binding_transient.descriptorCount = 1; + descriptor_set_layout_binding_transient.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + descriptor_set_layout_binding_transient.pImmutableSamplers = nullptr; + descriptor_set_layout_create_info.bindingCount = 1; + descriptor_set_layout_create_info.pBindings = &descriptor_set_layout_binding_transient; + if (dfn.vkCreateDescriptorSetLayout( + device, &descriptor_set_layout_create_info, nullptr, + &descriptor_set_layouts_single_transient_[size_t( + SingleTransientDescriptorLayout::kStorageBufferCompute)]) != VK_SUCCESS) { + REXGPU_ERROR( + "Failed to create a Vulkan descriptor set layout for a storage buffer " + "bound to the compute shader"); + return false; + } + // Transient: two storage buffers for compute shaders. + VkDescriptorSetLayoutBinding descriptor_set_layout_bindings_transient_pair[2]; + descriptor_set_layout_bindings_transient_pair[0] = descriptor_set_layout_binding_transient; + descriptor_set_layout_bindings_transient_pair[1] = descriptor_set_layout_binding_transient; + descriptor_set_layout_bindings_transient_pair[1].binding = 1; + descriptor_set_layout_create_info.bindingCount = 2; + descriptor_set_layout_create_info.pBindings = descriptor_set_layout_bindings_transient_pair; + if (dfn.vkCreateDescriptorSetLayout( + device, &descriptor_set_layout_create_info, nullptr, + &descriptor_set_layouts_single_transient_[size_t( + SingleTransientDescriptorLayout::kStorageBufferPairCompute)]) != VK_SUCCESS) { + REXGPU_ERROR( + "Failed to create a Vulkan descriptor set layout for two storage " + "buffers bound to the compute shader"); + return false; + } + + shared_memory_ = std::make_unique(*this, *memory_, trace_writer_, + guest_shader_pipeline_stages_); + if (!shared_memory_->Initialize()) { + REXGPU_ERROR("Failed to initialize shared memory"); + return false; + } + + primitive_processor_ = std::make_unique( + *register_file_, *memory_, trace_writer_, *shared_memory_, *this); + if (!primitive_processor_->Initialize()) { + REXGPU_ERROR("Failed to initialize the geometric primitive processor"); + return false; + } + + uint32_t shared_memory_binding_count_log2 = + SpirvShaderTranslator::GetSharedMemoryStorageBufferCountLog2( + device_properties.maxStorageBufferRange); + uint32_t shared_memory_binding_count = UINT32_C(1) << shared_memory_binding_count_log2; + + uint32_t draw_resolution_scale_x, draw_resolution_scale_y; + bool draw_resolution_scale_not_clamped = + TextureCache::GetConfigDrawResolutionScale(draw_resolution_scale_x, draw_resolution_scale_y); + if (!draw_resolution_scale_not_clamped) { + REXGPU_WARN( + "The requested draw resolution scale is not supported by the " + "emulator, reducing to {}x{}", + draw_resolution_scale_x, draw_resolution_scale_y); + } + if (draw_resolution_scale_x > 1 || draw_resolution_scale_y > 1) { + REXGPU_WARN( + "Vulkan draw resolution scaling is experimental and may not affect all " + "titles correctly"); + } + if (!device_properties.fragmentStoresAndAtomics) { + REXGPU_ERROR( + "Vulkan fragmentStoresAndAtomics is required for GPU emulation and " + "D3D12 parity, but unsupported by the selected device"); + return false; + } + if (!device_properties.vertexPipelineStoresAndAtomics) { + REXGPU_ERROR( + "Vulkan vertexPipelineStoresAndAtomics is required for GPU emulation and " + "D3D12 parity, but unsupported by the selected device"); + return false; + } + if (!device_properties.geometryShader) { + if (REXCVAR_GET(vulkan_require_geometry_shader)) { + REXGPU_ERROR( + "Vulkan geometryShader is required for GPU emulation " + "(vulkan_require_geometry_shader=true), but unsupported by the " + "selected device"); + return false; + } + REXGPU_WARN( + "Vulkan geometryShader is not supported by the device; primitive " + "fallback conversion/expansion paths will be used"); + } + if (!device_properties.fillModeNonSolid) { + if (REXCVAR_GET(vulkan_require_fill_mode_non_solid)) { + REXGPU_ERROR( + "Vulkan fillModeNonSolid is required for GPU emulation " + "(vulkan_require_fill_mode_non_solid=true), but unsupported by the " + "selected device"); + return false; + } + REXGPU_WARN( + "Vulkan fillModeNonSolid is not supported by the device; line/point " + "polygon modes will fall back to solid fill"); + } + + // Requires the transient descriptor set layouts. + render_target_cache_ = std::make_unique( + *register_file_, *memory_, trace_writer_, draw_resolution_scale_x, draw_resolution_scale_y, + *this); + if (!render_target_cache_->Initialize(shared_memory_binding_count)) { + REXGPU_ERROR("Failed to initialize the render target cache"); + return false; + } + + // Shared memory and EDRAM descriptor set layout. + bool edram_fragment_shader_interlock = + render_target_cache_->GetPath() == RenderTargetCache::Path::kPixelShaderInterlock; + VkDescriptorSetLayoutBinding shared_memory_and_edram_descriptor_set_layout_bindings[2]; + shared_memory_and_edram_descriptor_set_layout_bindings[0].binding = 0; + shared_memory_and_edram_descriptor_set_layout_bindings[0].descriptorType = + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + shared_memory_and_edram_descriptor_set_layout_bindings[0].descriptorCount = + shared_memory_binding_count; + shared_memory_and_edram_descriptor_set_layout_bindings[0].stageFlags = guest_shader_stages; + shared_memory_and_edram_descriptor_set_layout_bindings[0].pImmutableSamplers = nullptr; + VkDescriptorSetLayoutCreateInfo shared_memory_and_edram_descriptor_set_layout_create_info; + shared_memory_and_edram_descriptor_set_layout_create_info.sType = + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + shared_memory_and_edram_descriptor_set_layout_create_info.pNext = nullptr; + shared_memory_and_edram_descriptor_set_layout_create_info.flags = 0; + shared_memory_and_edram_descriptor_set_layout_create_info.pBindings = + shared_memory_and_edram_descriptor_set_layout_bindings; + if (edram_fragment_shader_interlock) { + // EDRAM. + shared_memory_and_edram_descriptor_set_layout_bindings[1].binding = 1; + shared_memory_and_edram_descriptor_set_layout_bindings[1].descriptorType = + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + shared_memory_and_edram_descriptor_set_layout_bindings[1].descriptorCount = 1; + shared_memory_and_edram_descriptor_set_layout_bindings[1].stageFlags = + VK_SHADER_STAGE_FRAGMENT_BIT; + shared_memory_and_edram_descriptor_set_layout_bindings[1].pImmutableSamplers = nullptr; + shared_memory_and_edram_descriptor_set_layout_create_info.bindingCount = 2; + } else { + shared_memory_and_edram_descriptor_set_layout_create_info.bindingCount = 1; + } + if (dfn.vkCreateDescriptorSetLayout( + device, &shared_memory_and_edram_descriptor_set_layout_create_info, nullptr, + &descriptor_set_layout_shared_memory_and_edram_) != VK_SUCCESS) { + REXGPU_ERROR( + "Failed to create a Vulkan descriptor set layout for the shared memory " + "and the EDRAM"); + return false; + } + + pipeline_cache_ = std::make_unique( + *this, *register_file_, *render_target_cache_, guest_shader_vertex_stages_); + if (!pipeline_cache_->Initialize()) { + REXGPU_ERROR("Failed to initialize the graphics pipeline cache"); + return false; + } + + // Requires the transient descriptor set layouts. + texture_cache_ = + VulkanTextureCache::Create(*register_file_, *shared_memory_, draw_resolution_scale_x, + draw_resolution_scale_y, *this, guest_shader_pipeline_stages_); + if (!texture_cache_) { + REXGPU_ERROR("Failed to initialize the texture cache"); + return false; + } + + // Shared memory and EDRAM common bindings. + VkDescriptorPoolSize descriptor_pool_sizes[1]; + descriptor_pool_sizes[0].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + descriptor_pool_sizes[0].descriptorCount = + shared_memory_binding_count + uint32_t(edram_fragment_shader_interlock); + VkDescriptorPoolCreateInfo descriptor_pool_create_info; + descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + descriptor_pool_create_info.pNext = nullptr; + descriptor_pool_create_info.flags = 0; + descriptor_pool_create_info.maxSets = 1; + descriptor_pool_create_info.poolSizeCount = 1; + descriptor_pool_create_info.pPoolSizes = descriptor_pool_sizes; + if (dfn.vkCreateDescriptorPool(device, &descriptor_pool_create_info, nullptr, + &shared_memory_and_edram_descriptor_pool_) != VK_SUCCESS) { + REXGPU_ERROR( + "Failed to create the Vulkan descriptor pool for shared memory and " + "EDRAM"); + return false; + } + VkDescriptorSetAllocateInfo descriptor_set_allocate_info; + descriptor_set_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + descriptor_set_allocate_info.pNext = nullptr; + descriptor_set_allocate_info.descriptorPool = shared_memory_and_edram_descriptor_pool_; + descriptor_set_allocate_info.descriptorSetCount = 1; + descriptor_set_allocate_info.pSetLayouts = &descriptor_set_layout_shared_memory_and_edram_; + if (dfn.vkAllocateDescriptorSets(device, &descriptor_set_allocate_info, + &shared_memory_and_edram_descriptor_set_) != VK_SUCCESS) { + REXGPU_ERROR( + "Failed to allocate the Vulkan descriptor set for shared memory and " + "EDRAM"); + return false; + } + VkDescriptorBufferInfo + shared_memory_descriptor_buffers_info[SharedMemory::kBufferSize / (128 << 20)]; + uint32_t shared_memory_binding_range = + SharedMemory::kBufferSize >> shared_memory_binding_count_log2; + for (uint32_t i = 0; i < shared_memory_binding_count; ++i) { + VkDescriptorBufferInfo& shared_memory_descriptor_buffer_info = + shared_memory_descriptor_buffers_info[i]; + shared_memory_descriptor_buffer_info.buffer = shared_memory_->buffer(); + shared_memory_descriptor_buffer_info.offset = shared_memory_binding_range * i; + shared_memory_descriptor_buffer_info.range = shared_memory_binding_range; + } + VkWriteDescriptorSet write_descriptor_sets[2]; + VkWriteDescriptorSet& write_descriptor_set_shared_memory = write_descriptor_sets[0]; + write_descriptor_set_shared_memory.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_descriptor_set_shared_memory.pNext = nullptr; + write_descriptor_set_shared_memory.dstSet = shared_memory_and_edram_descriptor_set_; + write_descriptor_set_shared_memory.dstBinding = 0; + write_descriptor_set_shared_memory.dstArrayElement = 0; + write_descriptor_set_shared_memory.descriptorCount = shared_memory_binding_count; + write_descriptor_set_shared_memory.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + write_descriptor_set_shared_memory.pImageInfo = nullptr; + write_descriptor_set_shared_memory.pBufferInfo = shared_memory_descriptor_buffers_info; + write_descriptor_set_shared_memory.pTexelBufferView = nullptr; + VkDescriptorBufferInfo edram_descriptor_buffer_info; + if (edram_fragment_shader_interlock) { + edram_descriptor_buffer_info.buffer = render_target_cache_->edram_buffer(); + edram_descriptor_buffer_info.offset = 0; + edram_descriptor_buffer_info.range = VK_WHOLE_SIZE; + VkWriteDescriptorSet& write_descriptor_set_edram = write_descriptor_sets[1]; + write_descriptor_set_edram.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_descriptor_set_edram.pNext = nullptr; + write_descriptor_set_edram.dstSet = shared_memory_and_edram_descriptor_set_; + write_descriptor_set_edram.dstBinding = 1; + write_descriptor_set_edram.dstArrayElement = 0; + write_descriptor_set_edram.descriptorCount = 1; + write_descriptor_set_edram.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + write_descriptor_set_edram.pImageInfo = nullptr; + write_descriptor_set_edram.pBufferInfo = &edram_descriptor_buffer_info; + write_descriptor_set_edram.pTexelBufferView = nullptr; + } + dfn.vkUpdateDescriptorSets(device, 1 + uint32_t(edram_fragment_shader_interlock), + write_descriptor_sets, 0, nullptr); + + // Swap objects. + + // Gamma ramp, either device-local and host-visible at once, or separate + // device-local texel buffer and host-visible upload buffer. + gamma_ramp_256_entry_table_current_frame_ = UINT32_MAX; + gamma_ramp_pwl_current_frame_ = UINT32_MAX; + // Try to create a device-local host-visible buffer first, to skip copying. + constexpr uint32_t kGammaRampSize256EntryTable = sizeof(uint32_t) * 256; + constexpr uint32_t kGammaRampSizePWL = sizeof(uint16_t) * 2 * 3 * 128; + constexpr uint32_t kGammaRampSize = kGammaRampSize256EntryTable + kGammaRampSizePWL; + VkBufferCreateInfo gamma_ramp_host_visible_buffer_create_info; + gamma_ramp_host_visible_buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + gamma_ramp_host_visible_buffer_create_info.pNext = nullptr; + gamma_ramp_host_visible_buffer_create_info.flags = 0; + gamma_ramp_host_visible_buffer_create_info.size = kGammaRampSize * kMaxFramesInFlight; + gamma_ramp_host_visible_buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT; + gamma_ramp_host_visible_buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + gamma_ramp_host_visible_buffer_create_info.queueFamilyIndexCount = 0; + gamma_ramp_host_visible_buffer_create_info.pQueueFamilyIndices = nullptr; + if (dfn.vkCreateBuffer(device, &gamma_ramp_host_visible_buffer_create_info, nullptr, + &gamma_ramp_buffer_) == VK_SUCCESS) { + bool use_gamma_ramp_host_visible_buffer = false; + VkMemoryRequirements gamma_ramp_host_visible_buffer_memory_requirements; + dfn.vkGetBufferMemoryRequirements(device, gamma_ramp_buffer_, + &gamma_ramp_host_visible_buffer_memory_requirements); + uint32_t gamma_ramp_host_visible_buffer_memory_types = + gamma_ramp_host_visible_buffer_memory_requirements.memoryTypeBits & + (vulkan_device->memory_types().device_local & vulkan_device->memory_types().host_visible); + VkMemoryAllocateInfo gamma_ramp_host_visible_buffer_memory_allocate_info; + // Prefer a host-uncached (because it's write-only) memory type, but try a + // host-cached host-visible device-local one as well. + if (rex::bit_scan_forward( + gamma_ramp_host_visible_buffer_memory_types & + ~vulkan_device->memory_types().host_cached, + &(gamma_ramp_host_visible_buffer_memory_allocate_info.memoryTypeIndex)) || + rex::bit_scan_forward( + gamma_ramp_host_visible_buffer_memory_types, + &(gamma_ramp_host_visible_buffer_memory_allocate_info.memoryTypeIndex))) { + VkMemoryAllocateInfo* gamma_ramp_host_visible_buffer_memory_allocate_info_last = + &gamma_ramp_host_visible_buffer_memory_allocate_info; + gamma_ramp_host_visible_buffer_memory_allocate_info.sType = + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + gamma_ramp_host_visible_buffer_memory_allocate_info.pNext = nullptr; + gamma_ramp_host_visible_buffer_memory_allocate_info.allocationSize = + gamma_ramp_host_visible_buffer_memory_requirements.size; + VkMemoryDedicatedAllocateInfo gamma_ramp_host_visible_buffer_memory_dedicated_allocate_info; + if (vulkan_device->extensions().ext_1_1_KHR_dedicated_allocation) { + gamma_ramp_host_visible_buffer_memory_allocate_info_last->pNext = + &gamma_ramp_host_visible_buffer_memory_dedicated_allocate_info; + gamma_ramp_host_visible_buffer_memory_allocate_info_last = + reinterpret_cast( + &gamma_ramp_host_visible_buffer_memory_dedicated_allocate_info); + gamma_ramp_host_visible_buffer_memory_dedicated_allocate_info.sType = + VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO; + gamma_ramp_host_visible_buffer_memory_dedicated_allocate_info.pNext = nullptr; + gamma_ramp_host_visible_buffer_memory_dedicated_allocate_info.image = VK_NULL_HANDLE; + gamma_ramp_host_visible_buffer_memory_dedicated_allocate_info.buffer = gamma_ramp_buffer_; + } + if (dfn.vkAllocateMemory(device, &gamma_ramp_host_visible_buffer_memory_allocate_info, + nullptr, &gamma_ramp_buffer_memory_) == VK_SUCCESS) { + if (dfn.vkBindBufferMemory(device, gamma_ramp_buffer_, gamma_ramp_buffer_memory_, 0) == + VK_SUCCESS) { + if (dfn.vkMapMemory(device, gamma_ramp_buffer_memory_, 0, VK_WHOLE_SIZE, 0, + &gamma_ramp_upload_mapping_) == VK_SUCCESS) { + use_gamma_ramp_host_visible_buffer = true; + gamma_ramp_upload_memory_size_ = + gamma_ramp_host_visible_buffer_memory_allocate_info.allocationSize; + gamma_ramp_upload_memory_type_ = + gamma_ramp_host_visible_buffer_memory_allocate_info.memoryTypeIndex; + } + } + if (!use_gamma_ramp_host_visible_buffer) { + dfn.vkFreeMemory(device, gamma_ramp_buffer_memory_, nullptr); + gamma_ramp_buffer_memory_ = VK_NULL_HANDLE; + } + } + } + if (!use_gamma_ramp_host_visible_buffer) { + dfn.vkDestroyBuffer(device, gamma_ramp_buffer_, nullptr); + gamma_ramp_buffer_ = VK_NULL_HANDLE; + } + } + if (gamma_ramp_buffer_ == VK_NULL_HANDLE) { + // Create separate buffers for the shader and uploading. + if (!ui::vulkan::util::CreateDedicatedAllocationBuffer( + vulkan_device, kGammaRampSize, + VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, + ui::vulkan::util::MemoryPurpose::kDeviceLocal, gamma_ramp_buffer_, + gamma_ramp_buffer_memory_)) { + REXGPU_ERROR("Failed to create the gamma ramp buffer"); + return false; + } + if (!ui::vulkan::util::CreateDedicatedAllocationBuffer( + vulkan_device, kGammaRampSize * kMaxFramesInFlight, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + ui::vulkan::util::MemoryPurpose::kUpload, gamma_ramp_upload_buffer_, + gamma_ramp_upload_buffer_memory_, &gamma_ramp_upload_memory_type_, + &gamma_ramp_upload_memory_size_)) { + REXGPU_ERROR("Failed to create the gamma ramp upload buffer"); + return false; + } + if (dfn.vkMapMemory(device, gamma_ramp_upload_buffer_memory_, 0, VK_WHOLE_SIZE, 0, + &gamma_ramp_upload_mapping_) != VK_SUCCESS) { + REXGPU_ERROR("Failed to map the gamma ramp upload buffer"); + return false; + } + } + + // Gamma ramp buffer views. + uint32_t gamma_ramp_frame_count = + gamma_ramp_upload_buffer_ == VK_NULL_HANDLE ? kMaxFramesInFlight : 1; + VkBufferViewCreateInfo gamma_ramp_buffer_view_create_info; + gamma_ramp_buffer_view_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; + gamma_ramp_buffer_view_create_info.pNext = nullptr; + gamma_ramp_buffer_view_create_info.flags = 0; + gamma_ramp_buffer_view_create_info.buffer = gamma_ramp_buffer_; + // 256-entry table. + gamma_ramp_buffer_view_create_info.format = VK_FORMAT_A2B10G10R10_UNORM_PACK32; + gamma_ramp_buffer_view_create_info.range = kGammaRampSize256EntryTable; + for (uint32_t i = 0; i < gamma_ramp_frame_count; ++i) { + gamma_ramp_buffer_view_create_info.offset = kGammaRampSize * i; + if (dfn.vkCreateBufferView(device, &gamma_ramp_buffer_view_create_info, nullptr, + &gamma_ramp_buffer_views_[i * 2]) != VK_SUCCESS) { + REXGPU_ERROR("Failed to create a 256-entry table gamma ramp buffer view"); + return false; + } + } + // Piecewise linear. + gamma_ramp_buffer_view_create_info.format = VK_FORMAT_R16G16_UINT; + gamma_ramp_buffer_view_create_info.range = kGammaRampSizePWL; + for (uint32_t i = 0; i < gamma_ramp_frame_count; ++i) { + gamma_ramp_buffer_view_create_info.offset = kGammaRampSize * i + kGammaRampSize256EntryTable; + if (dfn.vkCreateBufferView(device, &gamma_ramp_buffer_view_create_info, nullptr, + &gamma_ramp_buffer_views_[i * 2 + 1]) != VK_SUCCESS) { + REXGPU_ERROR("Failed to create a PWL gamma ramp buffer view"); + return false; + } + } + + // Swap descriptor set layouts. + VkDescriptorSetLayoutBinding swap_descriptor_set_layout_binding; + swap_descriptor_set_layout_binding.binding = 0; + swap_descriptor_set_layout_binding.descriptorCount = 1; + swap_descriptor_set_layout_binding.stageFlags = + VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT; + swap_descriptor_set_layout_binding.pImmutableSamplers = nullptr; + VkDescriptorSetLayoutCreateInfo swap_descriptor_set_layout_create_info; + swap_descriptor_set_layout_create_info.sType = + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + swap_descriptor_set_layout_create_info.pNext = nullptr; + swap_descriptor_set_layout_create_info.flags = 0; + swap_descriptor_set_layout_create_info.bindingCount = 1; + swap_descriptor_set_layout_create_info.pBindings = &swap_descriptor_set_layout_binding; + swap_descriptor_set_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + if (dfn.vkCreateDescriptorSetLayout(device, &swap_descriptor_set_layout_create_info, nullptr, + &swap_descriptor_set_layout_sampled_image_) != VK_SUCCESS) { + REXGPU_ERROR( + "Failed to create the presentation sampled image descriptor set " + "layout"); + return false; + } + swap_descriptor_set_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; + if (dfn.vkCreateDescriptorSetLayout(device, &swap_descriptor_set_layout_create_info, nullptr, + &swap_descriptor_set_layout_uniform_texel_buffer_) != + VK_SUCCESS) { + REXGPU_ERROR( + "Failed to create the presentation uniform texel buffer descriptor set " + "layout"); + return false; + } + swap_descriptor_set_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + swap_descriptor_set_layout_binding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + if (dfn.vkCreateDescriptorSetLayout(device, &swap_descriptor_set_layout_create_info, nullptr, + &swap_descriptor_set_layout_combined_image_sampler_) != + VK_SUCCESS) { + REXGPU_ERROR( + "Failed to create the presentation combined image sampler descriptor " + "set layout"); + return false; + } + swap_descriptor_set_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + if (dfn.vkCreateDescriptorSetLayout(device, &swap_descriptor_set_layout_create_info, nullptr, + &swap_descriptor_set_layout_storage_image_) != VK_SUCCESS) { + REXGPU_ERROR( + "Failed to create the presentation storage image descriptor set " + "layout"); + return false; + } + + // Swap descriptor pool. + std::array swap_descriptor_pool_sizes; + VkDescriptorPoolCreateInfo swap_descriptor_pool_create_info; + swap_descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + swap_descriptor_pool_create_info.pNext = nullptr; + swap_descriptor_pool_create_info.flags = 0; + swap_descriptor_pool_create_info.maxSets = 0; + swap_descriptor_pool_create_info.poolSizeCount = 0; + swap_descriptor_pool_create_info.pPoolSizes = swap_descriptor_pool_sizes.data(); + { + VkDescriptorPoolSize& swap_descriptor_pool_size_sampled_image = + swap_descriptor_pool_sizes[swap_descriptor_pool_create_info.poolSizeCount++]; + swap_descriptor_pool_size_sampled_image.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + // Source images. + swap_descriptor_pool_size_sampled_image.descriptorCount = kMaxFramesInFlight; + swap_descriptor_pool_create_info.maxSets += kMaxFramesInFlight; + } + { + VkDescriptorPoolSize& swap_descriptor_pool_size_combined_image_sampler = + swap_descriptor_pool_sizes[swap_descriptor_pool_create_info.poolSizeCount++]; + swap_descriptor_pool_size_combined_image_sampler.type = + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + swap_descriptor_pool_size_combined_image_sampler.descriptorCount = kMaxFramesInFlight; + swap_descriptor_pool_create_info.maxSets += kMaxFramesInFlight; + } + { + VkDescriptorPoolSize& swap_descriptor_pool_size_storage_image = + swap_descriptor_pool_sizes[swap_descriptor_pool_create_info.poolSizeCount++]; + swap_descriptor_pool_size_storage_image.type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + swap_descriptor_pool_size_storage_image.descriptorCount = kMaxFramesInFlight * 2; + swap_descriptor_pool_create_info.maxSets += kMaxFramesInFlight * 2; + } + // 256-entry table and PWL gamma ramps. If the gamma ramp buffer is + // host-visible, for multiple frames. + uint32_t gamma_ramp_buffer_view_count = 2 * gamma_ramp_frame_count; + { + VkDescriptorPoolSize& swap_descriptor_pool_size_uniform_texel_buffer = + swap_descriptor_pool_sizes[swap_descriptor_pool_create_info.poolSizeCount++]; + swap_descriptor_pool_size_uniform_texel_buffer.type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; + swap_descriptor_pool_size_uniform_texel_buffer.descriptorCount = gamma_ramp_buffer_view_count; + swap_descriptor_pool_create_info.maxSets += gamma_ramp_buffer_view_count; + } + if (dfn.vkCreateDescriptorPool(device, &swap_descriptor_pool_create_info, nullptr, + &swap_descriptor_pool_) != VK_SUCCESS) { + REXGPU_ERROR("Failed to create the presentation descriptor pool"); + return false; + } + + // Swap descriptor set allocation. + VkDescriptorSetAllocateInfo swap_descriptor_set_allocate_info; + swap_descriptor_set_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + swap_descriptor_set_allocate_info.pNext = nullptr; + swap_descriptor_set_allocate_info.descriptorPool = swap_descriptor_pool_; + swap_descriptor_set_allocate_info.descriptorSetCount = 1; + swap_descriptor_set_allocate_info.pSetLayouts = &swap_descriptor_set_layout_uniform_texel_buffer_; + for (uint32_t i = 0; i < gamma_ramp_buffer_view_count; ++i) { + if (dfn.vkAllocateDescriptorSets(device, &swap_descriptor_set_allocate_info, + &swap_descriptors_gamma_ramp_[i]) != VK_SUCCESS) { + REXGPU_ERROR("Failed to allocate the gamma ramp descriptor sets"); + return false; + } + } + swap_descriptor_set_allocate_info.pSetLayouts = &swap_descriptor_set_layout_sampled_image_; + for (uint32_t i = 0; i < kMaxFramesInFlight; ++i) { + if (dfn.vkAllocateDescriptorSets(device, &swap_descriptor_set_allocate_info, + &swap_descriptors_source_[i]) != VK_SUCCESS) { + REXGPU_ERROR("Failed to allocate the presentation source image descriptor sets"); + return false; + } + } + swap_descriptor_set_allocate_info.pSetLayouts = + &swap_descriptor_set_layout_combined_image_sampler_; + for (uint32_t i = 0; i < kMaxFramesInFlight; ++i) { + if (dfn.vkAllocateDescriptorSets(device, &swap_descriptor_set_allocate_info, + &swap_descriptors_fxaa_source_[i]) != VK_SUCCESS) { + REXGPU_ERROR( + "Failed to allocate the presentation FXAA source image descriptor " + "sets"); + return false; + } + } + swap_descriptor_set_allocate_info.pSetLayouts = &swap_descriptor_set_layout_storage_image_; + for (uint32_t i = 0; i < kMaxFramesInFlight; ++i) { + if (dfn.vkAllocateDescriptorSets(device, &swap_descriptor_set_allocate_info, + &swap_descriptors_destination_storage_[i]) != VK_SUCCESS) { + REXGPU_ERROR( + "Failed to allocate the presentation destination storage image " + "descriptor sets"); + return false; + } + } + for (uint32_t i = 0; i < kMaxFramesInFlight; ++i) { + if (dfn.vkAllocateDescriptorSets(device, &swap_descriptor_set_allocate_info, + &swap_descriptors_fxaa_destination_storage_[i]) != + VK_SUCCESS) { + REXGPU_ERROR( + "Failed to allocate the presentation FXAA destination storage image " + "descriptor sets"); + return false; + } + } + + // Gamma ramp descriptor sets. + VkWriteDescriptorSet gamma_ramp_write_descriptor_set; + gamma_ramp_write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + gamma_ramp_write_descriptor_set.pNext = nullptr; + gamma_ramp_write_descriptor_set.dstBinding = 0; + gamma_ramp_write_descriptor_set.dstArrayElement = 0; + gamma_ramp_write_descriptor_set.descriptorCount = 1; + gamma_ramp_write_descriptor_set.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; + gamma_ramp_write_descriptor_set.pImageInfo = nullptr; + gamma_ramp_write_descriptor_set.pBufferInfo = nullptr; + for (uint32_t i = 0; i < gamma_ramp_buffer_view_count; ++i) { + gamma_ramp_write_descriptor_set.dstSet = swap_descriptors_gamma_ramp_[i]; + gamma_ramp_write_descriptor_set.pTexelBufferView = &gamma_ramp_buffer_views_[i]; + dfn.vkUpdateDescriptorSets(device, 1, &gamma_ramp_write_descriptor_set, 0, nullptr); + } + + // Linear sampler for FXAA. + VkSamplerCreateInfo swap_sampler_create_info; + swap_sampler_create_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + swap_sampler_create_info.pNext = nullptr; + swap_sampler_create_info.flags = 0; + swap_sampler_create_info.magFilter = VK_FILTER_LINEAR; + swap_sampler_create_info.minFilter = VK_FILTER_LINEAR; + swap_sampler_create_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + swap_sampler_create_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + swap_sampler_create_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + swap_sampler_create_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + swap_sampler_create_info.mipLodBias = 0.0f; + swap_sampler_create_info.anisotropyEnable = VK_FALSE; + swap_sampler_create_info.maxAnisotropy = 1.0f; + swap_sampler_create_info.compareEnable = VK_FALSE; + swap_sampler_create_info.compareOp = VK_COMPARE_OP_NEVER; + swap_sampler_create_info.minLod = 0.0f; + swap_sampler_create_info.maxLod = 0.0f; + swap_sampler_create_info.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK; + swap_sampler_create_info.unnormalizedCoordinates = VK_FALSE; + if (dfn.vkCreateSampler(device, &swap_sampler_create_info, nullptr, + &swap_sampler_linear_clamp_) != VK_SUCCESS) { + REXGPU_ERROR("Failed to create the presentation FXAA sampler"); + return false; + } + + // Gamma ramp application pipeline layout. + std::array + swap_apply_gamma_descriptor_set_layouts{}; + swap_apply_gamma_descriptor_set_layouts[kSwapApplyGammaDescriptorSetRamp] = + swap_descriptor_set_layout_uniform_texel_buffer_; + swap_apply_gamma_descriptor_set_layouts[kSwapApplyGammaDescriptorSetSource] = + swap_descriptor_set_layout_sampled_image_; + VkPipelineLayoutCreateInfo swap_apply_gamma_pipeline_layout_create_info; + swap_apply_gamma_pipeline_layout_create_info.sType = + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + swap_apply_gamma_pipeline_layout_create_info.pNext = nullptr; + swap_apply_gamma_pipeline_layout_create_info.flags = 0; + swap_apply_gamma_pipeline_layout_create_info.setLayoutCount = + uint32_t(swap_apply_gamma_descriptor_set_layouts.size()); + swap_apply_gamma_pipeline_layout_create_info.pSetLayouts = + swap_apply_gamma_descriptor_set_layouts.data(); + swap_apply_gamma_pipeline_layout_create_info.pushConstantRangeCount = 0; + swap_apply_gamma_pipeline_layout_create_info.pPushConstantRanges = nullptr; + if (dfn.vkCreatePipelineLayout(device, &swap_apply_gamma_pipeline_layout_create_info, nullptr, + &swap_apply_gamma_pipeline_layout_) != VK_SUCCESS) { + REXGPU_ERROR("Failed to create the gamma ramp application pipeline layout"); + return false; + } + + // Gamma ramp application compute pipeline layout. + std::array + swap_apply_gamma_compute_descriptor_set_layouts{}; + swap_apply_gamma_compute_descriptor_set_layouts[kSwapApplyGammaComputeDescriptorSetRamp] = + swap_descriptor_set_layout_uniform_texel_buffer_; + swap_apply_gamma_compute_descriptor_set_layouts[kSwapApplyGammaComputeDescriptorSetSource] = + swap_descriptor_set_layout_sampled_image_; + swap_apply_gamma_compute_descriptor_set_layouts[kSwapApplyGammaComputeDescriptorSetDestination] = + swap_descriptor_set_layout_storage_image_; + VkPushConstantRange swap_apply_gamma_compute_push_constant_range; + swap_apply_gamma_compute_push_constant_range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + swap_apply_gamma_compute_push_constant_range.offset = 0; + swap_apply_gamma_compute_push_constant_range.size = sizeof(SwapApplyGammaConstants); + swap_apply_gamma_pipeline_layout_create_info.setLayoutCount = + uint32_t(swap_apply_gamma_compute_descriptor_set_layouts.size()); + swap_apply_gamma_pipeline_layout_create_info.pSetLayouts = + swap_apply_gamma_compute_descriptor_set_layouts.data(); + swap_apply_gamma_pipeline_layout_create_info.pushConstantRangeCount = 1; + swap_apply_gamma_pipeline_layout_create_info.pPushConstantRanges = + &swap_apply_gamma_compute_push_constant_range; + if (dfn.vkCreatePipelineLayout(device, &swap_apply_gamma_pipeline_layout_create_info, nullptr, + &swap_apply_gamma_compute_pipeline_layout_) != VK_SUCCESS) { + REXGPU_ERROR("Failed to create the gamma ramp application compute pipeline layout"); + return false; + } + + // FXAA compute pipeline layout. + std::array swap_fxaa_descriptor_set_layouts{}; + swap_fxaa_descriptor_set_layouts[kSwapFxaaDescriptorSetSource] = + swap_descriptor_set_layout_combined_image_sampler_; + swap_fxaa_descriptor_set_layouts[kSwapFxaaDescriptorSetDestination] = + swap_descriptor_set_layout_storage_image_; + VkPushConstantRange swap_fxaa_push_constant_range; + swap_fxaa_push_constant_range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + swap_fxaa_push_constant_range.offset = 0; + swap_fxaa_push_constant_range.size = sizeof(SwapFxaaConstants); + swap_apply_gamma_pipeline_layout_create_info.setLayoutCount = + uint32_t(swap_fxaa_descriptor_set_layouts.size()); + swap_apply_gamma_pipeline_layout_create_info.pSetLayouts = + swap_fxaa_descriptor_set_layouts.data(); + swap_apply_gamma_pipeline_layout_create_info.pushConstantRangeCount = 1; + swap_apply_gamma_pipeline_layout_create_info.pPushConstantRanges = &swap_fxaa_push_constant_range; + if (dfn.vkCreatePipelineLayout(device, &swap_apply_gamma_pipeline_layout_create_info, nullptr, + &swap_fxaa_pipeline_layout_) != VK_SUCCESS) { + REXGPU_ERROR("Failed to create the FXAA compute pipeline layout"); + return false; + } + + // Gamma application render pass. Doesn't make assumptions about outer usage + // (explicit barriers must be used instead) for simplicity of use in different + // scenarios with different pipelines. + VkAttachmentDescription swap_apply_gamma_render_pass_attachment; + swap_apply_gamma_render_pass_attachment.flags = 0; + swap_apply_gamma_render_pass_attachment.format = ui::vulkan::VulkanPresenter::kGuestOutputFormat; + swap_apply_gamma_render_pass_attachment.samples = VK_SAMPLE_COUNT_1_BIT; + swap_apply_gamma_render_pass_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + swap_apply_gamma_render_pass_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + swap_apply_gamma_render_pass_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + swap_apply_gamma_render_pass_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + swap_apply_gamma_render_pass_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + swap_apply_gamma_render_pass_attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + VkAttachmentReference swap_apply_gamma_render_pass_color_attachment; + swap_apply_gamma_render_pass_color_attachment.attachment = 0; + swap_apply_gamma_render_pass_color_attachment.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + VkSubpassDescription swap_apply_gamma_render_pass_subpass = {}; + swap_apply_gamma_render_pass_subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + swap_apply_gamma_render_pass_subpass.colorAttachmentCount = 1; + swap_apply_gamma_render_pass_subpass.pColorAttachments = + &swap_apply_gamma_render_pass_color_attachment; + VkSubpassDependency swap_apply_gamma_render_pass_dependencies[2]; + for (uint32_t i = 0; i < 2; ++i) { + VkSubpassDependency& swap_apply_gamma_render_pass_dependency = + swap_apply_gamma_render_pass_dependencies[i]; + swap_apply_gamma_render_pass_dependency.srcSubpass = i ? 0 : VK_SUBPASS_EXTERNAL; + swap_apply_gamma_render_pass_dependency.dstSubpass = i ? VK_SUBPASS_EXTERNAL : 0; + swap_apply_gamma_render_pass_dependency.srcStageMask = + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + swap_apply_gamma_render_pass_dependency.dstStageMask = + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + swap_apply_gamma_render_pass_dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + swap_apply_gamma_render_pass_dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + swap_apply_gamma_render_pass_dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; + } + VkRenderPassCreateInfo swap_apply_gamma_render_pass_create_info; + swap_apply_gamma_render_pass_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + swap_apply_gamma_render_pass_create_info.pNext = nullptr; + swap_apply_gamma_render_pass_create_info.flags = 0; + swap_apply_gamma_render_pass_create_info.attachmentCount = 1; + swap_apply_gamma_render_pass_create_info.pAttachments = &swap_apply_gamma_render_pass_attachment; + swap_apply_gamma_render_pass_create_info.subpassCount = 1; + swap_apply_gamma_render_pass_create_info.pSubpasses = &swap_apply_gamma_render_pass_subpass; + swap_apply_gamma_render_pass_create_info.dependencyCount = + uint32_t(rex::countof(swap_apply_gamma_render_pass_dependencies)); + swap_apply_gamma_render_pass_create_info.pDependencies = + swap_apply_gamma_render_pass_dependencies; + if (dfn.vkCreateRenderPass(device, &swap_apply_gamma_render_pass_create_info, nullptr, + &swap_apply_gamma_render_pass_) != VK_SUCCESS) { + REXGPU_ERROR("Failed to create the gamma ramp application render pass"); + return false; + } + + // Gamma ramp application pipeline. + // Using a graphics pipeline, not a compute one, because storage image support + // is optional for VK_FORMAT_A2B10G10R10_UNORM_PACK32. + + enum SwapApplyGammaPixelShader { + kSwapApplyGammaPixelShader256EntryTable, + kSwapApplyGammaPixelShaderPWL, + kSwapApplyGammaPixelShader256EntryTableFxaaLuma, + kSwapApplyGammaPixelShaderPWLFxaaLuma, + + kSwapApplyGammaPixelShaderCount, + }; + std::array swap_apply_gamma_pixel_shaders{}; + bool swap_apply_gamma_pixel_shaders_created = + (swap_apply_gamma_pixel_shaders[kSwapApplyGammaPixelShader256EntryTable] = + ui::vulkan::util::CreateShaderModule(vulkan_device, shaders::apply_gamma_table_ps, + sizeof(shaders::apply_gamma_table_ps))) != + VK_NULL_HANDLE && + (swap_apply_gamma_pixel_shaders[kSwapApplyGammaPixelShaderPWL] = + ui::vulkan::util::CreateShaderModule(vulkan_device, shaders::apply_gamma_pwl_ps, + sizeof(shaders::apply_gamma_pwl_ps))) != + VK_NULL_HANDLE && + (swap_apply_gamma_pixel_shaders[kSwapApplyGammaPixelShader256EntryTableFxaaLuma] = + ui::vulkan::util::CreateShaderModule( + vulkan_device, shaders::apply_gamma_table_fxaa_luma_ps, + sizeof(shaders::apply_gamma_table_fxaa_luma_ps))) != VK_NULL_HANDLE && + (swap_apply_gamma_pixel_shaders[kSwapApplyGammaPixelShaderPWLFxaaLuma] = + ui::vulkan::util::CreateShaderModule( + vulkan_device, shaders::apply_gamma_pwl_fxaa_luma_ps, + sizeof(shaders::apply_gamma_pwl_fxaa_luma_ps))) != VK_NULL_HANDLE; + if (!swap_apply_gamma_pixel_shaders_created) { + REXGPU_ERROR("Failed to create the gamma ramp application pixel shader modules"); + for (VkShaderModule swap_apply_gamma_pixel_shader : swap_apply_gamma_pixel_shaders) { + if (swap_apply_gamma_pixel_shader != VK_NULL_HANDLE) { + dfn.vkDestroyShaderModule(device, swap_apply_gamma_pixel_shader, nullptr); + } + } + return false; + } + + VkPipelineShaderStageCreateInfo swap_apply_gamma_pipeline_stages[2]; + swap_apply_gamma_pipeline_stages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + swap_apply_gamma_pipeline_stages[0].pNext = nullptr; + swap_apply_gamma_pipeline_stages[0].flags = 0; + swap_apply_gamma_pipeline_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; + swap_apply_gamma_pipeline_stages[0].module = ui::vulkan::util::CreateShaderModule( + vulkan_device, shaders::fullscreen_cw_vs, sizeof(shaders::fullscreen_cw_vs)); + if (swap_apply_gamma_pipeline_stages[0].module == VK_NULL_HANDLE) { + REXGPU_ERROR("Failed to create the gamma ramp application vertex shader module"); + for (VkShaderModule swap_apply_gamma_pixel_shader : swap_apply_gamma_pixel_shaders) { + assert_true(swap_apply_gamma_pixel_shader != VK_NULL_HANDLE); + dfn.vkDestroyShaderModule(device, swap_apply_gamma_pixel_shader, nullptr); + } + return false; + } + swap_apply_gamma_pipeline_stages[0].pName = "main"; + swap_apply_gamma_pipeline_stages[0].pSpecializationInfo = nullptr; + swap_apply_gamma_pipeline_stages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + swap_apply_gamma_pipeline_stages[1].pNext = nullptr; + swap_apply_gamma_pipeline_stages[1].flags = 0; + swap_apply_gamma_pipeline_stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; + // The fragment shader module will be specified later. + swap_apply_gamma_pipeline_stages[1].pName = "main"; + swap_apply_gamma_pipeline_stages[1].pSpecializationInfo = nullptr; + + VkPipelineVertexInputStateCreateInfo swap_apply_gamma_pipeline_vertex_input_state = {}; + swap_apply_gamma_pipeline_vertex_input_state.sType = + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + + VkPipelineInputAssemblyStateCreateInfo swap_apply_gamma_pipeline_input_assembly_state; + swap_apply_gamma_pipeline_input_assembly_state.sType = + VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + swap_apply_gamma_pipeline_input_assembly_state.pNext = nullptr; + swap_apply_gamma_pipeline_input_assembly_state.flags = 0; + swap_apply_gamma_pipeline_input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + swap_apply_gamma_pipeline_input_assembly_state.primitiveRestartEnable = VK_FALSE; + + VkPipelineViewportStateCreateInfo swap_apply_gamma_pipeline_viewport_state; + swap_apply_gamma_pipeline_viewport_state.sType = + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + swap_apply_gamma_pipeline_viewport_state.pNext = nullptr; + swap_apply_gamma_pipeline_viewport_state.flags = 0; + swap_apply_gamma_pipeline_viewport_state.viewportCount = 1; + swap_apply_gamma_pipeline_viewport_state.pViewports = nullptr; + swap_apply_gamma_pipeline_viewport_state.scissorCount = 1; + swap_apply_gamma_pipeline_viewport_state.pScissors = nullptr; + + VkPipelineRasterizationStateCreateInfo swap_apply_gamma_pipeline_rasterization_state = {}; + swap_apply_gamma_pipeline_rasterization_state.sType = + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + swap_apply_gamma_pipeline_rasterization_state.polygonMode = VK_POLYGON_MODE_FILL; + swap_apply_gamma_pipeline_rasterization_state.cullMode = VK_CULL_MODE_NONE; + swap_apply_gamma_pipeline_rasterization_state.frontFace = VK_FRONT_FACE_CLOCKWISE; + swap_apply_gamma_pipeline_rasterization_state.lineWidth = 1.0f; + + VkPipelineMultisampleStateCreateInfo swap_apply_gamma_pipeline_multisample_state = {}; + swap_apply_gamma_pipeline_multisample_state.sType = + VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + swap_apply_gamma_pipeline_multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + + VkPipelineColorBlendAttachmentState swap_apply_gamma_pipeline_color_blend_attachment_state = {}; + swap_apply_gamma_pipeline_color_blend_attachment_state.colorWriteMask = + VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | + VK_COLOR_COMPONENT_A_BIT; + VkPipelineColorBlendStateCreateInfo swap_apply_gamma_pipeline_color_blend_state = {}; + swap_apply_gamma_pipeline_color_blend_state.sType = + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + swap_apply_gamma_pipeline_color_blend_state.attachmentCount = 1; + swap_apply_gamma_pipeline_color_blend_state.pAttachments = + &swap_apply_gamma_pipeline_color_blend_attachment_state; + + static const VkDynamicState kSwapApplyGammaPipelineDynamicStates[] = { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, + }; + VkPipelineDynamicStateCreateInfo swap_apply_gamma_pipeline_dynamic_state; + swap_apply_gamma_pipeline_dynamic_state.sType = + VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + swap_apply_gamma_pipeline_dynamic_state.pNext = nullptr; + swap_apply_gamma_pipeline_dynamic_state.flags = 0; + swap_apply_gamma_pipeline_dynamic_state.dynamicStateCount = + uint32_t(rex::countof(kSwapApplyGammaPipelineDynamicStates)); + swap_apply_gamma_pipeline_dynamic_state.pDynamicStates = kSwapApplyGammaPipelineDynamicStates; + + VkGraphicsPipelineCreateInfo swap_apply_gamma_pipeline_create_info; + swap_apply_gamma_pipeline_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + swap_apply_gamma_pipeline_create_info.pNext = nullptr; + swap_apply_gamma_pipeline_create_info.flags = 0; + swap_apply_gamma_pipeline_create_info.stageCount = + uint32_t(rex::countof(swap_apply_gamma_pipeline_stages)); + swap_apply_gamma_pipeline_create_info.pStages = swap_apply_gamma_pipeline_stages; + swap_apply_gamma_pipeline_create_info.pVertexInputState = + &swap_apply_gamma_pipeline_vertex_input_state; + swap_apply_gamma_pipeline_create_info.pInputAssemblyState = + &swap_apply_gamma_pipeline_input_assembly_state; + swap_apply_gamma_pipeline_create_info.pTessellationState = nullptr; + swap_apply_gamma_pipeline_create_info.pViewportState = &swap_apply_gamma_pipeline_viewport_state; + swap_apply_gamma_pipeline_create_info.pRasterizationState = + &swap_apply_gamma_pipeline_rasterization_state; + swap_apply_gamma_pipeline_create_info.pMultisampleState = + &swap_apply_gamma_pipeline_multisample_state; + swap_apply_gamma_pipeline_create_info.pDepthStencilState = nullptr; + swap_apply_gamma_pipeline_create_info.pColorBlendState = + &swap_apply_gamma_pipeline_color_blend_state; + swap_apply_gamma_pipeline_create_info.pDynamicState = &swap_apply_gamma_pipeline_dynamic_state; + swap_apply_gamma_pipeline_create_info.layout = swap_apply_gamma_pipeline_layout_; + swap_apply_gamma_pipeline_create_info.renderPass = swap_apply_gamma_render_pass_; + swap_apply_gamma_pipeline_create_info.subpass = 0; + swap_apply_gamma_pipeline_create_info.basePipelineHandle = VK_NULL_HANDLE; + swap_apply_gamma_pipeline_create_info.basePipelineIndex = -1; + std::array swap_apply_gamma_pipeline_pixel_shaders = { + swap_apply_gamma_pixel_shaders[kSwapApplyGammaPixelShader256EntryTable], + swap_apply_gamma_pixel_shaders[kSwapApplyGammaPixelShaderPWL], + swap_apply_gamma_pixel_shaders[kSwapApplyGammaPixelShader256EntryTableFxaaLuma], + swap_apply_gamma_pixel_shaders[kSwapApplyGammaPixelShaderPWLFxaaLuma], + }; + std::array swap_apply_gamma_pipelines = { + &swap_apply_gamma_256_entry_table_pipeline_, + &swap_apply_gamma_pwl_pipeline_, + &swap_apply_gamma_256_entry_table_fxaa_luma_pipeline_, + &swap_apply_gamma_pwl_fxaa_luma_pipeline_, + }; + std::array swap_apply_gamma_pipeline_create_results; + for (size_t i = 0; i < swap_apply_gamma_pipelines.size(); ++i) { + swap_apply_gamma_pipeline_stages[1].module = swap_apply_gamma_pipeline_pixel_shaders[i]; + swap_apply_gamma_pipeline_create_results[i] = dfn.vkCreateGraphicsPipelines( + device, VK_NULL_HANDLE, 1, &swap_apply_gamma_pipeline_create_info, nullptr, + swap_apply_gamma_pipelines[i]); + } + if (!vulkan_device->properties().imageViewFormatSwizzle) { + auto create_rb_swap_pipeline = [&](const char* source, VkPipeline& pipeline_out, + const char* pipeline_name) { + std::vector pixel_spirv; + std::string compile_error; + if (!CompileGlslToSpirv(VK_SHADER_STAGE_FRAGMENT_BIT, source, pixel_spirv, compile_error)) { + REXGPU_WARN("Failed to compile {} shader to SPIR-V: {}", pipeline_name, compile_error); + return; + } + VkShaderModule pixel_shader_module = ui::vulkan::util::CreateShaderModule( + vulkan_device, pixel_spirv.data(), sizeof(uint32_t) * pixel_spirv.size()); + if (pixel_shader_module == VK_NULL_HANDLE) { + REXGPU_WARN("Failed to create {} shader module", pipeline_name); + return; + } + swap_apply_gamma_pipeline_stages[1].module = pixel_shader_module; + if (dfn.vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, + &swap_apply_gamma_pipeline_create_info, nullptr, + &pipeline_out) != VK_SUCCESS) { + REXGPU_WARN("Failed to create {} pipeline", pipeline_name); + pipeline_out = VK_NULL_HANDLE; + } + dfn.vkDestroyShaderModule(device, pixel_shader_module, nullptr); + }; + create_rb_swap_pipeline(GetSwapApplyGammaTablePixelRbSwapSource(), + swap_apply_gamma_256_entry_table_rb_swap_pipeline_, + "swap gamma table red/blue fallback"); + create_rb_swap_pipeline(GetSwapApplyGammaPwlPixelRbSwapSource(), + swap_apply_gamma_pwl_rb_swap_pipeline_, + "swap gamma PWL red/blue fallback"); + } + dfn.vkDestroyShaderModule(device, swap_apply_gamma_pipeline_stages[0].module, nullptr); + for (VkShaderModule swap_apply_gamma_pixel_shader : swap_apply_gamma_pixel_shaders) { + assert_true(swap_apply_gamma_pixel_shader != VK_NULL_HANDLE); + dfn.vkDestroyShaderModule(device, swap_apply_gamma_pixel_shader, nullptr); + } + if (std::any_of(swap_apply_gamma_pipeline_create_results.begin(), + swap_apply_gamma_pipeline_create_results.end(), + [](VkResult result) { return result != VK_SUCCESS; })) { + REXGPU_ERROR("Failed to create the gamma ramp application pipelines"); + return false; + } + + // Gamma ramp application compute pipelines. + swap_apply_gamma_compute_256_entry_table_pipeline_ = ui::vulkan::util::CreateComputePipeline( + vulkan_device, swap_apply_gamma_compute_pipeline_layout_, shaders::apply_gamma_table_cs, + sizeof(shaders::apply_gamma_table_cs)); + if (swap_apply_gamma_compute_256_entry_table_pipeline_ == VK_NULL_HANDLE) { + REXGPU_WARN( + "Failed to create the 256-entry table gamma ramp application compute " + "pipeline, keeping graphics fallback"); + } + swap_apply_gamma_compute_256_entry_table_fxaa_luma_pipeline_ = + ui::vulkan::util::CreateComputePipeline( + vulkan_device, swap_apply_gamma_compute_pipeline_layout_, + shaders::apply_gamma_table_fxaa_luma_cs, sizeof(shaders::apply_gamma_table_fxaa_luma_cs)); + if (swap_apply_gamma_compute_256_entry_table_fxaa_luma_pipeline_ == VK_NULL_HANDLE) { + REXGPU_WARN( + "Failed to create the 256-entry table gamma ramp application compute " + "pipeline with luma output"); + } + swap_apply_gamma_compute_pwl_pipeline_ = ui::vulkan::util::CreateComputePipeline( + vulkan_device, swap_apply_gamma_compute_pipeline_layout_, shaders::apply_gamma_pwl_cs, + sizeof(shaders::apply_gamma_pwl_cs)); + if (swap_apply_gamma_compute_pwl_pipeline_ == VK_NULL_HANDLE) { + REXGPU_WARN("Failed to create the PWL gamma ramp application compute pipeline"); + } + swap_apply_gamma_compute_pwl_fxaa_luma_pipeline_ = ui::vulkan::util::CreateComputePipeline( + vulkan_device, swap_apply_gamma_compute_pipeline_layout_, + shaders::apply_gamma_pwl_fxaa_luma_cs, sizeof(shaders::apply_gamma_pwl_fxaa_luma_cs)); + if (swap_apply_gamma_compute_pwl_fxaa_luma_pipeline_ == VK_NULL_HANDLE) { + REXGPU_WARN( + "Failed to create the PWL gamma ramp application compute pipeline with " + "luma output"); + } + if (!vulkan_device->properties().imageViewFormatSwizzle) { + auto create_rb_swap_compute_pipeline = [&](const char* source, VkPipeline& pipeline_out, + const char* pipeline_name) { + std::vector compute_spirv; + std::string compile_error; + if (!CompileGlslToSpirv(VK_SHADER_STAGE_COMPUTE_BIT, source, compute_spirv, compile_error)) { + REXGPU_WARN("Failed to compile {} shader to SPIR-V: {}", pipeline_name, compile_error); + return; + } + pipeline_out = ui::vulkan::util::CreateComputePipeline( + vulkan_device, swap_apply_gamma_compute_pipeline_layout_, compute_spirv.data(), + sizeof(uint32_t) * compute_spirv.size()); + if (pipeline_out == VK_NULL_HANDLE) { + REXGPU_WARN("Failed to create {} pipeline", pipeline_name); + } + }; + create_rb_swap_compute_pipeline(GetSwapApplyGammaTableComputeRbSwapSource(), + swap_apply_gamma_compute_256_entry_table_rb_swap_pipeline_, + "swap gamma table compute red/blue fallback"); + create_rb_swap_compute_pipeline(GetSwapApplyGammaPwlComputeRbSwapSource(), + swap_apply_gamma_compute_pwl_rb_swap_pipeline_, + "swap gamma PWL compute red/blue fallback"); + create_rb_swap_compute_pipeline( + GetSwapApplyGammaTableFxaaLumaComputeRbSwapSource(), + swap_apply_gamma_compute_256_entry_table_fxaa_luma_rb_swap_pipeline_, + "swap gamma table FXAA-luma compute red/blue fallback"); + create_rb_swap_compute_pipeline(GetSwapApplyGammaPwlFxaaLumaComputeRbSwapSource(), + swap_apply_gamma_compute_pwl_fxaa_luma_rb_swap_pipeline_, + "swap gamma PWL FXAA-luma compute red/blue fallback"); + } + + // FXAA compute pipelines, compiled to SPIR-V at runtime. + std::vector swap_fxaa_spirv; + std::string swap_fxaa_compile_error; + if (!CompileGlslToSpirv(VK_SHADER_STAGE_COMPUTE_BIT, GetSwapFxaaComputeSource(false), + swap_fxaa_spirv, swap_fxaa_compile_error)) { + REXGPU_WARN("Failed to compile FXAA compute shader to SPIR-V: {}", swap_fxaa_compile_error); + } else { + swap_fxaa_pipeline_ = ui::vulkan::util::CreateComputePipeline( + vulkan_device, swap_fxaa_pipeline_layout_, swap_fxaa_spirv.data(), + sizeof(uint32_t) * swap_fxaa_spirv.size()); + if (swap_fxaa_pipeline_ == VK_NULL_HANDLE) { + REXGPU_WARN("Failed to create the FXAA compute pipeline"); + } + } + + std::vector swap_fxaa_extreme_spirv; + std::string swap_fxaa_extreme_compile_error; + if (!CompileGlslToSpirv(VK_SHADER_STAGE_COMPUTE_BIT, GetSwapFxaaComputeSource(true), + swap_fxaa_extreme_spirv, swap_fxaa_extreme_compile_error)) { + REXGPU_WARN("Failed to compile extreme FXAA compute shader to SPIR-V: {}", + swap_fxaa_extreme_compile_error); + } else { + swap_fxaa_extreme_pipeline_ = ui::vulkan::util::CreateComputePipeline( + vulkan_device, swap_fxaa_pipeline_layout_, swap_fxaa_extreme_spirv.data(), + sizeof(uint32_t) * swap_fxaa_extreme_spirv.size()); + if (swap_fxaa_extreme_pipeline_ == VK_NULL_HANDLE) { + REXGPU_WARN("Failed to create the extreme-quality FXAA compute pipeline"); + } + } + + VkPipelineLayoutCreateInfo resolve_downscale_layout_create_info = {}; + resolve_downscale_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + VkDescriptorSetLayout resolve_downscale_set_layout = + descriptor_set_layouts_single_transient_[size_t( + SingleTransientDescriptorLayout::kStorageBufferPairCompute)]; + resolve_downscale_layout_create_info.setLayoutCount = 1; + resolve_downscale_layout_create_info.pSetLayouts = &resolve_downscale_set_layout; + VkPushConstantRange resolve_downscale_push_constant_range = {}; + resolve_downscale_push_constant_range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + resolve_downscale_push_constant_range.offset = 0; + resolve_downscale_push_constant_range.size = sizeof(ResolveDownscaleConstants); + resolve_downscale_layout_create_info.pushConstantRangeCount = 1; + resolve_downscale_layout_create_info.pPushConstantRanges = &resolve_downscale_push_constant_range; + if (dfn.vkCreatePipelineLayout(device, &resolve_downscale_layout_create_info, nullptr, + &resolve_downscale_pipeline_layout_) == VK_SUCCESS) { + resolve_downscale_pipeline_ = ui::vulkan::util::CreateComputePipeline( + vulkan_device, resolve_downscale_pipeline_layout_, shaders::resolve_downscale_cs, + sizeof(shaders::resolve_downscale_cs)); + if (resolve_downscale_pipeline_ == VK_NULL_HANDLE) { + REXGPU_WARN("Failed to create Vulkan resolve-downscale readback pipeline"); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipelineLayout, device, + resolve_downscale_pipeline_layout_); + } + } else { + REXGPU_WARN("Failed to create Vulkan resolve-downscale pipeline layout"); + } + + occlusion_query_resources_available_ = InitializeOcclusionQueryResources(); + + // Just not to expose uninitialized memory. + std::memset(&system_constants_, 0, sizeof(system_constants_)); + + return true; +} + +void VulkanCommandProcessor::ShutdownContext() { + AwaitAllQueueOperationsCompletion(); + InvalidateAllVertexBufferResidency(); + ShutdownOcclusionQueryResources(); + + const ui::vulkan::VulkanDevice* const vulkan_device = GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + DestroyScratchBuffer(); + + for (auto& readback_pair : readback_buffers_) { + ReadbackBuffer& readback = readback_pair.second; + for (uint32_t i = 0; i < 2; ++i) { + if (readback.mapped_data[i] && readback.memories[i] != VK_NULL_HANDLE) { + dfn.vkUnmapMemory(device, readback.memories[i]); + } + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyBuffer, device, readback.buffers[i]); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkFreeMemory, device, readback.memories[i]); + readback.mapped_data[i] = nullptr; + readback.sizes[i] = 0; + readback.submission_written[i] = 0; + readback.written_size[i] = 0; + } + } + readback_buffers_.clear(); + for (auto& readback_pair : memexport_readback_buffers_) { + ReadbackBuffer& readback = readback_pair.second; + for (uint32_t i = 0; i < 2; ++i) { + if (readback.mapped_data[i] && readback.memories[i] != VK_NULL_HANDLE) { + dfn.vkUnmapMemory(device, readback.memories[i]); + } + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyBuffer, device, readback.buffers[i]); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkFreeMemory, device, readback.memories[i]); + readback.mapped_data[i] = nullptr; + readback.sizes[i] = 0; + readback.submission_written[i] = 0; + readback.written_size[i] = 0; + } + } + memexport_readback_buffers_.clear(); + + resolve_downscale_buffer_size_ = 0; + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyBuffer, device, resolve_downscale_buffer_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkFreeMemory, device, + resolve_downscale_buffer_memory_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, + resolve_downscale_pipeline_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipelineLayout, device, + resolve_downscale_pipeline_layout_); + + for (SwapFramebuffer& swap_framebuffer : swap_framebuffers_) { + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyFramebuffer, device, + swap_framebuffer.framebuffer); + } + DestroySwapFxaaSourceImage(); + + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, + swap_fxaa_extreme_pipeline_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, swap_fxaa_pipeline_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, + swap_apply_gamma_compute_pwl_fxaa_luma_pipeline_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, + swap_apply_gamma_compute_pwl_pipeline_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, + swap_apply_gamma_compute_pwl_fxaa_luma_rb_swap_pipeline_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, + swap_apply_gamma_compute_pwl_rb_swap_pipeline_); + ui::vulkan::util::DestroyAndNullHandle( + dfn.vkDestroyPipeline, device, swap_apply_gamma_compute_256_entry_table_fxaa_luma_pipeline_); + ui::vulkan::util::DestroyAndNullHandle( + dfn.vkDestroyPipeline, device, + swap_apply_gamma_compute_256_entry_table_fxaa_luma_rb_swap_pipeline_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, + swap_apply_gamma_compute_256_entry_table_pipeline_); + ui::vulkan::util::DestroyAndNullHandle( + dfn.vkDestroyPipeline, device, swap_apply_gamma_compute_256_entry_table_rb_swap_pipeline_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, + swap_apply_gamma_pwl_rb_swap_pipeline_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, + swap_apply_gamma_256_entry_table_rb_swap_pipeline_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, + swap_apply_gamma_pwl_pipeline_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, + swap_apply_gamma_pwl_fxaa_luma_pipeline_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, + swap_apply_gamma_256_entry_table_pipeline_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, + swap_apply_gamma_256_entry_table_fxaa_luma_pipeline_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyRenderPass, device, + swap_apply_gamma_render_pass_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipelineLayout, device, + swap_fxaa_pipeline_layout_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipelineLayout, device, + swap_apply_gamma_compute_pipeline_layout_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipelineLayout, device, + swap_apply_gamma_pipeline_layout_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroySampler, device, swap_sampler_linear_clamp_); + + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyDescriptorPool, device, + swap_descriptor_pool_); + + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyDescriptorSetLayout, device, + swap_descriptor_set_layout_uniform_texel_buffer_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyDescriptorSetLayout, device, + swap_descriptor_set_layout_storage_image_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyDescriptorSetLayout, device, + swap_descriptor_set_layout_combined_image_sampler_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyDescriptorSetLayout, device, + swap_descriptor_set_layout_sampled_image_); + for (VkBufferView& gamma_ramp_buffer_view : gamma_ramp_buffer_views_) { + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyBufferView, device, gamma_ramp_buffer_view); + } + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyBuffer, device, gamma_ramp_upload_buffer_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkFreeMemory, device, + gamma_ramp_upload_buffer_memory_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyBuffer, device, gamma_ramp_buffer_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkFreeMemory, device, gamma_ramp_buffer_memory_); + + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyDescriptorPool, device, + shared_memory_and_edram_descriptor_pool_); + + texture_cache_.reset(); + + pipeline_cache_.reset(); + + render_target_cache_.reset(); + + primitive_processor_.reset(); + + shared_memory_.reset(); + + ClearTransientDescriptorPools(); + + for (const auto& pipeline_layout_pair : pipeline_layouts_) { + dfn.vkDestroyPipelineLayout(device, pipeline_layout_pair.second.GetPipelineLayout(), nullptr); + } + pipeline_layouts_.clear(); + for (const auto& descriptor_set_layout_pair : descriptor_set_layouts_textures_) { + dfn.vkDestroyDescriptorSetLayout(device, descriptor_set_layout_pair.second, nullptr); + } + descriptor_set_layouts_textures_.clear(); + + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyDescriptorSetLayout, device, + descriptor_set_layout_shared_memory_and_edram_); + for (VkDescriptorSetLayout& descriptor_set_layout_single_transient : + descriptor_set_layouts_single_transient_) { + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyDescriptorSetLayout, device, + descriptor_set_layout_single_transient); + } + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyDescriptorSetLayout, device, + descriptor_set_layout_constants_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyDescriptorSetLayout, device, + descriptor_set_layout_empty_); + + uniform_buffer_pool_.reset(); + + sparse_bind_wait_stage_mask_ = 0; + sparse_buffer_binds_.clear(); + sparse_memory_binds_.clear(); + + deferred_command_buffer_.Reset(); + for (const auto& command_buffer_pair : command_buffers_submitted_) { + dfn.vkDestroyCommandPool(device, command_buffer_pair.second.pool, nullptr); + } + command_buffers_submitted_.clear(); + for (const CommandBuffer& command_buffer : command_buffers_writable_) { + dfn.vkDestroyCommandPool(device, command_buffer.pool, nullptr); + } + command_buffers_writable_.clear(); + + for (const auto& destroy_pair : destroy_framebuffers_) { + dfn.vkDestroyFramebuffer(device, destroy_pair.second, nullptr); + } + destroy_framebuffers_.clear(); + for (const auto& destroy_pair : destroy_image_views_) { + dfn.vkDestroyImageView(device, destroy_pair.second, nullptr); + } + destroy_image_views_.clear(); + for (const auto& destroy_pair : destroy_buffers_) { + dfn.vkDestroyBuffer(device, destroy_pair.second, nullptr); + } + destroy_buffers_.clear(); + for (const auto& destroy_pair : destroy_images_) { + dfn.vkDestroyImage(device, destroy_pair.second, nullptr); + } + destroy_images_.clear(); + for (const auto& destroy_pair : destroy_memory_) { + dfn.vkFreeMemory(device, destroy_pair.second, nullptr); + } + destroy_memory_.clear(); + + std::memset(closed_frame_submissions_, 0, sizeof(closed_frame_submissions_)); + frame_completed_ = 0; + frame_current_ = 1; + frame_open_ = false; + + for (const auto& semaphore : submissions_in_flight_semaphores_) { + dfn.vkDestroySemaphore(device, semaphore.second, nullptr); + } + submissions_in_flight_semaphores_.clear(); + for (VkFence& fence : submissions_in_flight_fences_) { + dfn.vkDestroyFence(device, fence, nullptr); + } + submissions_in_flight_fences_.clear(); + current_submission_wait_stage_masks_.clear(); + for (VkSemaphore semaphore : current_submission_wait_semaphores_) { + dfn.vkDestroySemaphore(device, semaphore, nullptr); + } + current_submission_wait_semaphores_.clear(); + submission_completed_ = 0; + submission_open_ = false; + + for (VkSemaphore semaphore : semaphores_free_) { + dfn.vkDestroySemaphore(device, semaphore, nullptr); + } + semaphores_free_.clear(); + for (VkFence fence : fences_free_) { + dfn.vkDestroyFence(device, fence, nullptr); + } + fences_free_.clear(); + + device_lost_ = false; + + CommandProcessor::ShutdownContext(); +} + +void VulkanCommandProcessor::WriteRegister(uint32_t index, uint32_t value) { + CommandProcessor::WriteRegister(index, value); + + if (index >= XE_GPU_REG_SHADER_CONSTANT_000_X && index <= XE_GPU_REG_SHADER_CONSTANT_511_W) { + if (frame_open_) { + uint32_t float_constant_index = (index - XE_GPU_REG_SHADER_CONSTANT_000_X) >> 2; + if (float_constant_index >= 256) { + float_constant_index -= 256; + if (current_float_constant_map_pixel_[float_constant_index >> 6] & + (1ull << (float_constant_index & 63))) { + current_constant_buffers_up_to_date_ &= + ~(UINT32_C(1) << SpirvShaderTranslator::kConstantBufferFloatPixel); + } + } else { + if (current_float_constant_map_vertex_[float_constant_index >> 6] & + (1ull << (float_constant_index & 63))) { + current_constant_buffers_up_to_date_ &= + ~(UINT32_C(1) << SpirvShaderTranslator::kConstantBufferFloatVertex); + } + } + } + } else if (index >= XE_GPU_REG_SHADER_CONSTANT_BOOL_000_031 && + index <= XE_GPU_REG_SHADER_CONSTANT_LOOP_31) { + current_constant_buffers_up_to_date_ &= + ~(UINT32_C(1) << SpirvShaderTranslator::kConstantBufferBoolLoop); + } else if (index >= XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 && + index <= XE_GPU_REG_SHADER_CONSTANT_FETCH_31_5) { + current_constant_buffers_up_to_date_ &= + ~(UINT32_C(1) << SpirvShaderTranslator::kConstantBufferFetch); + if (texture_cache_) { + texture_cache_->TextureFetchConstantWritten((index - XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0) / + 6); + } + InvalidateVertexBufferResidency((index - XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0) / 2); + } +} + +void VulkanCommandProcessor::WriteRegistersFromMem(uint32_t start_index, uint32_t* base, + uint32_t num_registers) { + if (!num_registers) { + return; + } + uint32_t end_index = start_index + num_registers - 1; + + auto range_has_any_constant_usage = [](const uint64_t* usage_map, uint32_t first_constant, + uint32_t last_constant) -> bool { + if (first_constant > last_constant) { + return false; + } + uint32_t first_word = first_constant >> 6; + uint32_t last_word = last_constant >> 6; + uint32_t first_bit = first_constant & 63; + uint32_t last_bit = last_constant & 63; + if (first_word == last_word) { + uint32_t bit_count = last_bit - first_bit + 1; + uint64_t mask = bit_count == 64 ? UINT64_MAX : ((UINT64_C(1) << bit_count) - 1) << first_bit; + return (usage_map[first_word] & mask) != 0; + } + if (usage_map[first_word] & (UINT64_MAX << first_bit)) { + return true; + } + for (uint32_t word = first_word + 1; word < last_word; ++word) { + if (usage_map[word]) { + return true; + } + } + uint64_t last_mask = last_bit == 63 ? UINT64_MAX : ((UINT64_C(1) << (last_bit + 1)) - 1); + return (usage_map[last_word] & last_mask) != 0; + }; + + if (start_index >= XE_GPU_REG_SHADER_CONSTANT_000_X && + end_index <= XE_GPU_REG_SHADER_CONSTANT_511_W) { + memory::copy_and_swap(register_file_->values + start_index, base, num_registers); + if (frame_open_) { + uint32_t first_float_constant = (start_index - XE_GPU_REG_SHADER_CONSTANT_000_X) >> 2; + uint32_t last_float_constant = (end_index - XE_GPU_REG_SHADER_CONSTANT_000_X) >> 2; + if (first_float_constant < 256) { + uint32_t last_vertex_constant = std::min(last_float_constant, 255u); + if (range_has_any_constant_usage(current_float_constant_map_vertex_, first_float_constant, + last_vertex_constant)) { + current_constant_buffers_up_to_date_ &= + ~(UINT32_C(1) << SpirvShaderTranslator::kConstantBufferFloatVertex); + } + } + if (last_float_constant >= 256) { + uint32_t first_pixel_constant = + first_float_constant >= 256 ? first_float_constant - 256 : 0; + uint32_t last_pixel_constant = last_float_constant - 256; + if (range_has_any_constant_usage(current_float_constant_map_pixel_, first_pixel_constant, + last_pixel_constant)) { + current_constant_buffers_up_to_date_ &= + ~(UINT32_C(1) << SpirvShaderTranslator::kConstantBufferFloatPixel); + } + } + } + return; + } + + if (start_index >= XE_GPU_REG_SHADER_CONSTANT_BOOL_000_031 && + end_index <= XE_GPU_REG_SHADER_CONSTANT_LOOP_31) { + memory::copy_and_swap(register_file_->values + start_index, base, num_registers); + current_constant_buffers_up_to_date_ &= + ~(UINT32_C(1) << SpirvShaderTranslator::kConstantBufferBoolLoop); + return; + } + + if (start_index >= XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 && + end_index <= XE_GPU_REG_SHADER_CONSTANT_FETCH_31_5) { + memory::copy_and_swap(register_file_->values + start_index, base, num_registers); + current_constant_buffers_up_to_date_ &= + ~(UINT32_C(1) << SpirvShaderTranslator::kConstantBufferFetch); + uint32_t first_fetch_dword = start_index - XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0; + uint32_t last_fetch_dword = end_index - XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0; + if (texture_cache_) { + texture_cache_->TextureFetchConstantsWritten(first_fetch_dword / 6, last_fetch_dword / 6); + } + InvalidateVertexBufferResidencyRange(first_fetch_dword / 2, last_fetch_dword / 2); + return; + } + + CommandProcessor::WriteRegistersFromMem(start_index, base, num_registers); +} + +void VulkanCommandProcessor::SparseBindBuffer(VkBuffer buffer, uint32_t bind_count, + const VkSparseMemoryBind* binds, + VkPipelineStageFlags wait_stage_mask) { + if (!bind_count) { + return; + } + SparseBufferBind& buffer_bind = sparse_buffer_binds_.emplace_back(); + buffer_bind.buffer = buffer; + buffer_bind.bind_offset = sparse_memory_binds_.size(); + buffer_bind.bind_count = bind_count; + sparse_memory_binds_.reserve(sparse_memory_binds_.size() + bind_count); + sparse_memory_binds_.insert(sparse_memory_binds_.end(), binds, binds + bind_count); + sparse_bind_wait_stage_mask_ |= wait_stage_mask; +} + +void VulkanCommandProcessor::OnGammaRamp256EntryTableValueWritten() { + gamma_ramp_256_entry_table_current_frame_ = UINT32_MAX; +} + +void VulkanCommandProcessor::OnGammaRampPWLValueWritten() { + gamma_ramp_pwl_current_frame_ = UINT32_MAX; +} + +void VulkanCommandProcessor::IssueSwap(uint32_t frontbuffer_ptr, uint32_t frontbuffer_width, + uint32_t frontbuffer_height) { + SCOPE_profile_cpu_f("gpu"); + vertex_buffers_in_sync_[0] = 0; + vertex_buffers_in_sync_[1] = 0; + + if (!graphics_system_) + return; + ui::Presenter* presenter = graphics_system_->presenter(); + if (!presenter) { + REXGPU_ERROR("XELOG_GPU PRESENT: NO PRESENTER"); + return; + } + + // In case the swap command is the only one in the frame. + if (!BeginSubmission(true)) { + REXGPU_ERROR("XELOG_GPU PRESENT: BeginSubmission FAILED"); + return; + } + + bool skip_present_due_async_placeholder = REXCVAR_GET(async_shader_compilation) && + REXCVAR_GET(vulkan_async_skip_incomplete_frames) && + frame_used_async_placeholder_pipeline_; + if (skip_present_due_async_placeholder) { + static bool skipped_incomplete_frame_logged = false; + if (!skipped_incomplete_frame_logged) { + skipped_incomplete_frame_logged = true; + REXGPU_WARN( + "Skipping Vulkan frame presentation due to async placeholder draw " + "usage in this frame"); + } + EndSubmission(true); + return; + } + + SwapPostEffect swap_post_effect = GetActualSwapPostEffect(); + + // Obtain the actual swap source texture size (resolution-scaled if it's a + // resolve destination, or not otherwise). + uint32_t frontbuffer_width_scaled, frontbuffer_height_scaled; + uint32_t frontbuffer_width_unscaled = 0, frontbuffer_height_unscaled = 0; + xenos::TextureFormat frontbuffer_format; + bool swap_source_needs_rb_swap = false; + VkImageView swap_texture_view = texture_cache_->RequestSwapTexture( + frontbuffer_width_scaled, frontbuffer_height_scaled, frontbuffer_format, + &frontbuffer_width_unscaled, &frontbuffer_height_unscaled, &swap_source_needs_rb_swap); + if (swap_texture_view == VK_NULL_HANDLE) { + REXGPU_ERROR("XELOG_GPU PRESENT: swap_texture_view=NULL"); + return; + } + // The swap gamma / FXAA pass samples source texels by pixel index, but swap + // textures may be allocation-padded. Prefer the active frontbuffer region + // from the swap packet, scaled proportionally to the actual source texture. + auto get_active_swap_dimension = [](uint32_t packet_unscaled, uint32_t source_unscaled, + uint32_t source_scaled) -> uint32_t { + if (!source_scaled) { + return 0; + } + uint32_t active_unscaled = packet_unscaled ? packet_unscaled : source_unscaled; + if (!active_unscaled) { + return source_scaled; + } + if (source_unscaled) { + active_unscaled = std::min(active_unscaled, source_unscaled); + uint64_t active_scaled = + (uint64_t(active_unscaled) * source_scaled + (source_unscaled >> 1)) / source_unscaled; + return uint32_t(std::clamp(active_scaled, 1, source_scaled)); + } + return std::min(active_unscaled, source_scaled); + }; + uint32_t guest_output_width = get_active_swap_dimension( + frontbuffer_width, frontbuffer_width_unscaled, frontbuffer_width_scaled); + uint32_t guest_output_height = get_active_swap_dimension( + frontbuffer_height, frontbuffer_height_unscaled, frontbuffer_height_scaled); + if (!guest_output_width) { + guest_output_width = frontbuffer_width_scaled + ? frontbuffer_width_scaled + : (frontbuffer_width ? frontbuffer_width : frontbuffer_width_unscaled); + } + if (!guest_output_height) { + guest_output_height = + frontbuffer_height_scaled + ? frontbuffer_height_scaled + : (frontbuffer_height ? frontbuffer_height : frontbuffer_height_unscaled); + } + bool swap_source_scaled = frontbuffer_width_unscaled && frontbuffer_height_unscaled && + (frontbuffer_width_scaled != frontbuffer_width_unscaled || + frontbuffer_height_scaled != frontbuffer_height_unscaled); + if (texture_cache_->IsDrawResolutionScaled()) { + static bool draw_scale_cache_mismatch_logged = false; + uint32_t texture_scale_x = texture_cache_->draw_resolution_scale_x(); + uint32_t texture_scale_y = texture_cache_->draw_resolution_scale_y(); + uint32_t rt_scale_x = + render_target_cache_ ? render_target_cache_->draw_resolution_scale_x() : texture_scale_x; + uint32_t rt_scale_y = + render_target_cache_ ? render_target_cache_->draw_resolution_scale_y() : texture_scale_y; + if (!draw_scale_cache_mismatch_logged && + (texture_scale_x != rt_scale_x || texture_scale_y != rt_scale_y)) { + draw_scale_cache_mismatch_logged = true; + REXGPU_WARN( + "Vulkan draw-scale mismatch: texture cache is {}x{}, render target " + "cache is {}x{}", + texture_scale_x, texture_scale_y, rt_scale_x, rt_scale_y); + } + static bool draw_scale_swap_sizes_logged = false; + if (!draw_scale_swap_sizes_logged) { + draw_scale_swap_sizes_logged = true; + REXGPU_WARN( + "Vulkan draw-scale swap sizing: packet={}x{}, src_scaled={}x{}, " + "src_unscaled={}x{}, active={}x{}", + frontbuffer_width, frontbuffer_height, frontbuffer_width_scaled, + frontbuffer_height_scaled, frontbuffer_width_unscaled, frontbuffer_height_unscaled, + guest_output_width, guest_output_height); + } + } + if (texture_cache_->IsDrawResolutionScaled() && !swap_source_scaled) { + static bool draw_scale_swap_unscaled_logged = false; + if (!draw_scale_swap_unscaled_logged) { + draw_scale_swap_unscaled_logged = true; + REXGPU_WARN( + "Vulkan draw resolution scaling is enabled, but the swap source is " + "unscaled ({}x{}). This title may be presenting from an unscaled " + "resolve path.", + frontbuffer_width_scaled, frontbuffer_height_scaled); + } + } + REXGPU_DEBUG( + "XELOG_GPU PRESENT: swap_texture_view={:p} packet_size={}x{} src_size={}x{} " + "src_unscaled={}x{} guest_output_size={}x{} format={}", + static_cast(swap_texture_view), frontbuffer_width, frontbuffer_height, + frontbuffer_width_scaled, frontbuffer_height_scaled, frontbuffer_width_unscaled, + frontbuffer_height_unscaled, guest_output_width, guest_output_height, + static_cast(frontbuffer_format)); + + system::X_VIDEO_MODE video_mode; + kernel::xboxkrnl::VdQueryVideoMode(&video_mode); + uint32_t display_width = std::max(uint32_t(1), uint32_t(video_mode.display_width)); + uint32_t display_height = std::max(uint32_t(1), uint32_t(video_mode.display_height)); + + presenter->RefreshGuestOutput( + guest_output_width, guest_output_height, display_width, display_height, + [this, guest_output_width, guest_output_height, frontbuffer_format, swap_texture_view, + swap_post_effect, + swap_source_needs_rb_swap](ui::Presenter::GuestOutputRefreshContext& context) -> bool { + // In case the swap command is the only one in the frame. + if (!BeginSubmission(true)) { + return false; + } + + auto& vulkan_context = + static_cast(context); + uint64_t guest_output_image_version = vulkan_context.image_version(); + + const ui::vulkan::VulkanDevice* const vulkan_device = GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + uint32_t swap_frame_index = uint32_t(frame_current_ % kMaxFramesInFlight); + bool use_fxaa = swap_post_effect == SwapPostEffect::kFxaa || + swap_post_effect == SwapPostEffect::kFxaaExtreme; + + // This is according to D3D::InitializePresentationParameters from a + // game executable, which initializes the 256-entry table gamma ramp for + // 8_8_8_8 output and the PWL gamma ramp for 2_10_10_10. + // TODO(Triang3l): Choose between the table and PWL based on + // DC_LUTA_CONTROL, support both for all formats (and also different + // increments for PWL). + bool use_pwl_gamma_ramp = + frontbuffer_format == xenos::TextureFormat::k_2_10_10_10 || + frontbuffer_format == xenos::TextureFormat::k_2_10_10_10_AS_16_16_16_16; + bool swap_source_requires_compute_rb_swap = + !vulkan_device->properties().imageViewFormatSwizzle && swap_source_needs_rb_swap; + auto select_swap_apply_gamma_compute_pipeline = [&](bool use_pwl, + bool use_fxaa_luma) -> VkPipeline { + if (use_pwl) { + if (use_fxaa_luma) { + return swap_source_requires_compute_rb_swap + ? swap_apply_gamma_compute_pwl_fxaa_luma_rb_swap_pipeline_ + : swap_apply_gamma_compute_pwl_fxaa_luma_pipeline_; + } + return swap_source_requires_compute_rb_swap + ? swap_apply_gamma_compute_pwl_rb_swap_pipeline_ + : swap_apply_gamma_compute_pwl_pipeline_; + } + if (use_fxaa_luma) { + return swap_source_requires_compute_rb_swap + ? swap_apply_gamma_compute_256_entry_table_fxaa_luma_rb_swap_pipeline_ + : swap_apply_gamma_compute_256_entry_table_fxaa_luma_pipeline_; + } + return swap_source_requires_compute_rb_swap + ? swap_apply_gamma_compute_256_entry_table_rb_swap_pipeline_ + : swap_apply_gamma_compute_256_entry_table_pipeline_; + }; + VkPipeline swap_apply_gamma_compute_pipeline = + select_swap_apply_gamma_compute_pipeline(use_pwl_gamma_ramp, use_fxaa); + + if (use_fxaa) { + if (swap_apply_gamma_compute_pipeline == VK_NULL_HANDLE || + swap_fxaa_pipeline_ == VK_NULL_HANDLE || + swap_fxaa_extreme_pipeline_ == VK_NULL_HANDLE) { + static bool fxaa_pipelines_unavailable_logged = false; + if (!fxaa_pipelines_unavailable_logged) { + if (swap_source_requires_compute_rb_swap) { + REXGPU_WARN( + "Vulkan FXAA swap effect requested but FXAA compute " + "pipelines (including RB-swap fallback) are unavailable, " + "falling back to gamma only"); + } else { + REXGPU_WARN( + "Vulkan FXAA swap effect requested but FXAA compute " + "pipelines are unavailable, falling back to gamma only"); + } + fxaa_pipelines_unavailable_logged = true; + } + use_fxaa = false; + } else if (!EnsureSwapFxaaSourceImage(guest_output_width, guest_output_height)) { + static bool fxaa_source_image_failed_logged = false; + if (!fxaa_source_image_failed_logged) { + REXGPU_WARN( + "Failed to create the Vulkan FXAA source image, falling " + "back to gamma-only presentation"); + fxaa_source_image_failed_logged = true; + } + use_fxaa = false; + } + } + if (!use_fxaa) { + swap_apply_gamma_compute_pipeline = + select_swap_apply_gamma_compute_pipeline(use_pwl_gamma_ramp, false); + } + if (swap_source_requires_compute_rb_swap && + swap_apply_gamma_compute_pipeline == VK_NULL_HANDLE) { + static bool compute_rb_swap_fallback_missing_logged = false; + if (!compute_rb_swap_fallback_missing_logged) { + compute_rb_swap_fallback_missing_logged = true; + REXGPU_WARN( + "Vulkan imageViewFormatSwizzle is unavailable and the swap " + "source needs red/blue swizzle, but the compute fallback " + "pipeline is unavailable; falling back to graphics " + "presentation path"); + } + } + bool use_compute_gamma = swap_apply_gamma_compute_pipeline != VK_NULL_HANDLE; + + // TODO(Triang3l): FXAA can result in more than 8 bits of precision. + context.SetIs8bpc(!use_pwl_gamma_ramp && !use_fxaa); + + // Update the gamma ramp if it's out of date. + uint32_t& gamma_ramp_frame_index_ref = use_pwl_gamma_ramp + ? gamma_ramp_pwl_current_frame_ + : gamma_ramp_256_entry_table_current_frame_; + if (gamma_ramp_frame_index_ref == UINT32_MAX) { + constexpr uint32_t kGammaRampSize256EntryTable = sizeof(uint32_t) * 256; + constexpr uint32_t kGammaRampSizePWL = sizeof(uint16_t) * 2 * 3 * 128; + constexpr uint32_t kGammaRampSize = kGammaRampSize256EntryTable + kGammaRampSizePWL; + uint32_t gamma_ramp_offset_in_frame = + use_pwl_gamma_ramp ? kGammaRampSize256EntryTable : 0; + uint32_t gamma_ramp_upload_offset = + kGammaRampSize * swap_frame_index + gamma_ramp_offset_in_frame; + uint32_t gamma_ramp_size = + use_pwl_gamma_ramp ? kGammaRampSizePWL : kGammaRampSize256EntryTable; + void* gamma_ramp_frame_upload = + reinterpret_cast(gamma_ramp_upload_mapping_) + gamma_ramp_upload_offset; + if (std::endian::native != std::endian::little && use_pwl_gamma_ramp) { + // R16G16 is first R16, where the shader expects the base, and + // second G16, where the delta should be, but gamma_ramp_pwl_rgb() + // is an array of 32-bit DC_LUT_PWL_DATA registers - swap 16 bits in + // each 32. + auto gamma_ramp_pwl_upload = + reinterpret_cast(gamma_ramp_frame_upload); + const reg::DC_LUT_PWL_DATA* gamma_ramp_pwl = gamma_ramp_pwl_rgb(); + for (size_t i = 0; i < 128 * 3; ++i) { + reg::DC_LUT_PWL_DATA& gamma_ramp_pwl_upload_entry = gamma_ramp_pwl_upload[i]; + reg::DC_LUT_PWL_DATA gamma_ramp_pwl_entry = gamma_ramp_pwl[i]; + gamma_ramp_pwl_upload_entry.base = gamma_ramp_pwl_entry.delta; + gamma_ramp_pwl_upload_entry.delta = gamma_ramp_pwl_entry.base; + } + } else { + std::memcpy(gamma_ramp_frame_upload, + use_pwl_gamma_ramp ? static_cast(gamma_ramp_pwl_rgb()) + : static_cast(gamma_ramp_256_entry_table()), + gamma_ramp_size); + } + bool gamma_ramp_has_upload_buffer = gamma_ramp_upload_buffer_memory_ != VK_NULL_HANDLE; + VkPipelineStageFlags gamma_ramp_read_stage_mask = + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + ui::vulkan::util::FlushMappedMemoryRange( + vulkan_device, + gamma_ramp_has_upload_buffer ? gamma_ramp_upload_buffer_memory_ + : gamma_ramp_buffer_memory_, + gamma_ramp_upload_memory_type_, gamma_ramp_upload_offset, + gamma_ramp_upload_memory_size_, gamma_ramp_size); + if (gamma_ramp_has_upload_buffer) { + // Copy from the host-visible buffer to the device-local one. + PushBufferMemoryBarrier(gamma_ramp_buffer_, gamma_ramp_offset_in_frame, gamma_ramp_size, + gamma_ramp_read_stage_mask, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, false); + SubmitBarriers(true); + VkBufferCopy gamma_ramp_buffer_copy; + gamma_ramp_buffer_copy.srcOffset = gamma_ramp_upload_offset; + gamma_ramp_buffer_copy.dstOffset = gamma_ramp_offset_in_frame; + gamma_ramp_buffer_copy.size = gamma_ramp_size; + deferred_command_buffer_.CmdVkCopyBuffer(gamma_ramp_upload_buffer_, gamma_ramp_buffer_, + 1, &gamma_ramp_buffer_copy); + PushBufferMemoryBarrier(gamma_ramp_buffer_, gamma_ramp_offset_in_frame, gamma_ramp_size, + VK_PIPELINE_STAGE_TRANSFER_BIT, gamma_ramp_read_stage_mask, + VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, + VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, false); + } + // The device-local, but not host-visible, gamma ramp buffer doesn't + // have per-frame sets of gamma ramps. + gamma_ramp_frame_index_ref = gamma_ramp_has_upload_buffer ? 0 : swap_frame_index; + } + + VkDescriptorSet swap_descriptor_source = swap_descriptors_source_[swap_frame_index]; + VkDescriptorImageInfo swap_descriptor_source_image_info; + swap_descriptor_source_image_info.sampler = VK_NULL_HANDLE; + swap_descriptor_source_image_info.imageView = swap_texture_view; + swap_descriptor_source_image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + VkWriteDescriptorSet swap_descriptor_source_write; + swap_descriptor_source_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + swap_descriptor_source_write.pNext = nullptr; + swap_descriptor_source_write.dstSet = swap_descriptor_source; + swap_descriptor_source_write.dstBinding = 0; + swap_descriptor_source_write.dstArrayElement = 0; + swap_descriptor_source_write.descriptorCount = 1; + swap_descriptor_source_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + swap_descriptor_source_write.pImageInfo = &swap_descriptor_source_image_info; + swap_descriptor_source_write.pBufferInfo = nullptr; + swap_descriptor_source_write.pTexelBufferView = nullptr; + dfn.vkUpdateDescriptorSets(device, 1, &swap_descriptor_source_write, 0, nullptr); + + VkImageSubresourceRange guest_output_subresource_range = + ui::vulkan::util::InitializeSubresourceRange(); + if (use_compute_gamma) { + // Transition the destination image for compute writes. Contents are + // fully overwritten, so old layout can always be UNDEFINED. + PushImageMemoryBarrier(vulkan_context.image(), guest_output_subresource_range, + vulkan_context.image_ever_written_previously() + ? ui::vulkan::VulkanPresenter::kGuestOutputInternalStageMask + : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + vulkan_context.image_ever_written_previously() + ? ui::vulkan::VulkanPresenter::kGuestOutputInternalAccessMask + : 0, + VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_GENERAL); + if (use_fxaa) { + PushImageMemoryBarrier(swap_fxaa_source_image_, guest_output_subresource_range, + swap_fxaa_source_stage_mask_ ? swap_fxaa_source_stage_mask_ + : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + swap_fxaa_source_access_mask_, VK_ACCESS_SHADER_WRITE_BIT, + swap_fxaa_source_layout_, VK_IMAGE_LAYOUT_GENERAL); + } + SubmitBarriers(true); + + if (use_fxaa) { + swap_fxaa_source_stage_mask_ = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + swap_fxaa_source_access_mask_ = VK_ACCESS_SHADER_WRITE_BIT; + swap_fxaa_source_layout_ = VK_IMAGE_LAYOUT_GENERAL; + swap_fxaa_source_image_submission_ = GetCurrentSubmission(); + } + + VkDescriptorSet swap_descriptor_destination_storage = + swap_descriptors_destination_storage_[swap_frame_index]; + VkDescriptorImageInfo swap_descriptor_destination_storage_image_info; + swap_descriptor_destination_storage_image_info.sampler = VK_NULL_HANDLE; + swap_descriptor_destination_storage_image_info.imageView = + use_fxaa ? swap_fxaa_source_image_view_ : vulkan_context.image_view(); + swap_descriptor_destination_storage_image_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL; + VkWriteDescriptorSet swap_descriptor_destination_storage_write; + swap_descriptor_destination_storage_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + swap_descriptor_destination_storage_write.pNext = nullptr; + swap_descriptor_destination_storage_write.dstSet = swap_descriptor_destination_storage; + swap_descriptor_destination_storage_write.dstBinding = 0; + swap_descriptor_destination_storage_write.dstArrayElement = 0; + swap_descriptor_destination_storage_write.descriptorCount = 1; + swap_descriptor_destination_storage_write.descriptorType = + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + swap_descriptor_destination_storage_write.pImageInfo = + &swap_descriptor_destination_storage_image_info; + swap_descriptor_destination_storage_write.pBufferInfo = nullptr; + swap_descriptor_destination_storage_write.pTexelBufferView = nullptr; + dfn.vkUpdateDescriptorSets(device, 1, &swap_descriptor_destination_storage_write, 0, + nullptr); + + std::array + swap_apply_gamma_compute_descriptor_sets{}; + swap_apply_gamma_compute_descriptor_sets[kSwapApplyGammaComputeDescriptorSetRamp] = + swap_descriptors_gamma_ramp_[2 * gamma_ramp_frame_index_ref + + uint32_t(use_pwl_gamma_ramp)]; + swap_apply_gamma_compute_descriptor_sets[kSwapApplyGammaComputeDescriptorSetSource] = + swap_descriptor_source; + swap_apply_gamma_compute_descriptor_sets[kSwapApplyGammaComputeDescriptorSetDestination] = + swap_descriptor_destination_storage; + deferred_command_buffer_.CmdVkBindDescriptorSets( + VK_PIPELINE_BIND_POINT_COMPUTE, swap_apply_gamma_compute_pipeline_layout_, 0, + uint32_t(swap_apply_gamma_compute_descriptor_sets.size()), + swap_apply_gamma_compute_descriptor_sets.data(), 0, nullptr); + SwapApplyGammaConstants swap_apply_gamma_constants = { + {guest_output_width, guest_output_height}}; + deferred_command_buffer_.CmdVkPushConstants( + swap_apply_gamma_compute_pipeline_layout_, VK_SHADER_STAGE_COMPUTE_BIT, 0, + sizeof(swap_apply_gamma_constants), &swap_apply_gamma_constants); + BindExternalComputePipeline(swap_apply_gamma_compute_pipeline); + uint32_t group_count_x = (guest_output_width + 15) / 16; + uint32_t group_count_y = (guest_output_height + 7) / 8; + deferred_command_buffer_.CmdVkDispatch(group_count_x, group_count_y, 1); + + if (use_fxaa) { + // Make the FXAA source image readable and bind a separate + // destination storage descriptor targeting the guest output image. + PushImageMemoryBarrier(swap_fxaa_source_image_, guest_output_subresource_range, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_SHADER_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + SubmitBarriers(true); + swap_fxaa_source_stage_mask_ = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + swap_fxaa_source_access_mask_ = VK_ACCESS_SHADER_READ_BIT; + swap_fxaa_source_layout_ = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + swap_fxaa_source_image_submission_ = GetCurrentSubmission(); + + VkDescriptorSet swap_descriptor_fxaa_source = + swap_descriptors_fxaa_source_[swap_frame_index]; + VkDescriptorImageInfo swap_descriptor_fxaa_source_image_info; + swap_descriptor_fxaa_source_image_info.sampler = swap_sampler_linear_clamp_; + swap_descriptor_fxaa_source_image_info.imageView = swap_fxaa_source_image_view_; + swap_descriptor_fxaa_source_image_info.imageLayout = + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + VkWriteDescriptorSet swap_descriptor_fxaa_source_write; + swap_descriptor_fxaa_source_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + swap_descriptor_fxaa_source_write.pNext = nullptr; + swap_descriptor_fxaa_source_write.dstSet = swap_descriptor_fxaa_source; + swap_descriptor_fxaa_source_write.dstBinding = 0; + swap_descriptor_fxaa_source_write.dstArrayElement = 0; + swap_descriptor_fxaa_source_write.descriptorCount = 1; + swap_descriptor_fxaa_source_write.descriptorType = + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + swap_descriptor_fxaa_source_write.pImageInfo = &swap_descriptor_fxaa_source_image_info; + swap_descriptor_fxaa_source_write.pBufferInfo = nullptr; + swap_descriptor_fxaa_source_write.pTexelBufferView = nullptr; + dfn.vkUpdateDescriptorSets(device, 1, &swap_descriptor_fxaa_source_write, 0, nullptr); + + VkDescriptorSet swap_descriptor_fxaa_destination_storage = + swap_descriptors_fxaa_destination_storage_[swap_frame_index]; + VkDescriptorImageInfo swap_descriptor_fxaa_destination_storage_image_info; + swap_descriptor_fxaa_destination_storage_image_info.sampler = VK_NULL_HANDLE; + swap_descriptor_fxaa_destination_storage_image_info.imageView = + vulkan_context.image_view(); + swap_descriptor_fxaa_destination_storage_image_info.imageLayout = + VK_IMAGE_LAYOUT_GENERAL; + VkWriteDescriptorSet swap_descriptor_fxaa_destination_storage_write = + swap_descriptor_destination_storage_write; + swap_descriptor_fxaa_destination_storage_write.dstSet = + swap_descriptor_fxaa_destination_storage; + swap_descriptor_fxaa_destination_storage_write.pImageInfo = + &swap_descriptor_fxaa_destination_storage_image_info; + dfn.vkUpdateDescriptorSets(device, 1, &swap_descriptor_fxaa_destination_storage_write, + 0, nullptr); + + std::array swap_fxaa_descriptor_sets{}; + swap_fxaa_descriptor_sets[kSwapFxaaDescriptorSetSource] = swap_descriptor_fxaa_source; + swap_fxaa_descriptor_sets[kSwapFxaaDescriptorSetDestination] = + swap_descriptor_fxaa_destination_storage; + deferred_command_buffer_.CmdVkBindDescriptorSets( + VK_PIPELINE_BIND_POINT_COMPUTE, swap_fxaa_pipeline_layout_, 0, + uint32_t(swap_fxaa_descriptor_sets.size()), swap_fxaa_descriptor_sets.data(), 0, + nullptr); + SwapFxaaConstants swap_fxaa_constants = { + {guest_output_width, guest_output_height}, + {1.0f / float(guest_output_width), 1.0f / float(guest_output_height)}}; + deferred_command_buffer_.CmdVkPushConstants( + swap_fxaa_pipeline_layout_, VK_SHADER_STAGE_COMPUTE_BIT, 0, + sizeof(swap_fxaa_constants), &swap_fxaa_constants); + BindExternalComputePipeline(swap_post_effect == SwapPostEffect::kFxaaExtreme + ? swap_fxaa_extreme_pipeline_ + : swap_fxaa_pipeline_); + deferred_command_buffer_.CmdVkDispatch(group_count_x, group_count_y, 1); + } + + // Insert the release barrier. + PushImageMemoryBarrier(vulkan_context.image(), guest_output_subresource_range, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + ui::vulkan::VulkanPresenter::kGuestOutputInternalStageMask, + VK_ACCESS_SHADER_WRITE_BIT, + ui::vulkan::VulkanPresenter::kGuestOutputInternalAccessMask, + VK_IMAGE_LAYOUT_GENERAL, + ui::vulkan::VulkanPresenter::kGuestOutputInternalLayout); + } else { + // Make sure a framebuffer is available for the current guest output + // image version. + size_t swap_framebuffer_index = SIZE_MAX; + size_t swap_framebuffer_new_index = SIZE_MAX; + // Try to find the existing framebuffer for the current guest output + // image version, or an unused (without an existing framebuffer, or + // with one, but that has never actually been used dynamically) slot. + for (size_t i = 0; i < swap_framebuffers_.size(); ++i) { + const SwapFramebuffer& existing_swap_framebuffer = swap_framebuffers_[i]; + if (existing_swap_framebuffer.framebuffer != VK_NULL_HANDLE && + existing_swap_framebuffer.version == guest_output_image_version) { + swap_framebuffer_index = i; + break; + } + if (existing_swap_framebuffer.framebuffer == VK_NULL_HANDLE || + !existing_swap_framebuffer.last_submission) { + swap_framebuffer_new_index = i; + } + } + if (swap_framebuffer_index == SIZE_MAX) { + if (swap_framebuffer_new_index == SIZE_MAX) { + // Replace the earliest used framebuffer. + swap_framebuffer_new_index = 0; + for (size_t i = 1; i < swap_framebuffers_.size(); ++i) { + if (swap_framebuffers_[i].last_submission < + swap_framebuffers_[swap_framebuffer_new_index].last_submission) { + swap_framebuffer_new_index = i; + } + } + } + swap_framebuffer_index = swap_framebuffer_new_index; + SwapFramebuffer& new_swap_framebuffer = swap_framebuffers_[swap_framebuffer_new_index]; + if (new_swap_framebuffer.framebuffer != VK_NULL_HANDLE) { + if (submission_completed_ >= new_swap_framebuffer.last_submission) { + dfn.vkDestroyFramebuffer(device, new_swap_framebuffer.framebuffer, nullptr); + } else { + destroy_framebuffers_.emplace_back(new_swap_framebuffer.last_submission, + new_swap_framebuffer.framebuffer); + } + new_swap_framebuffer.framebuffer = VK_NULL_HANDLE; + } + VkImageView guest_output_image_view = vulkan_context.image_view(); + VkFramebufferCreateInfo swap_framebuffer_create_info; + swap_framebuffer_create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + swap_framebuffer_create_info.pNext = nullptr; + swap_framebuffer_create_info.flags = 0; + swap_framebuffer_create_info.renderPass = swap_apply_gamma_render_pass_; + swap_framebuffer_create_info.attachmentCount = 1; + swap_framebuffer_create_info.pAttachments = &guest_output_image_view; + swap_framebuffer_create_info.width = guest_output_width; + swap_framebuffer_create_info.height = guest_output_height; + swap_framebuffer_create_info.layers = 1; + if (dfn.vkCreateFramebuffer(device, &swap_framebuffer_create_info, nullptr, + &new_swap_framebuffer.framebuffer) != VK_SUCCESS) { + REXGPU_ERROR("Failed to create the Vulkan framebuffer for presentation"); + return false; + } + new_swap_framebuffer.version = guest_output_image_version; + // The actual submission index will be set if the framebuffer is + // actually used, not dropped due to some error. + new_swap_framebuffer.last_submission = 0; + } + + if (vulkan_context.image_ever_written_previously()) { + // Insert a barrier after the last presenter's usage of the guest + // output image. Will be overwriting all the contents, so oldLayout + // layout is UNDEFINED. The render pass will do the layout + // transition, but newLayout must not be UNDEFINED. + PushImageMemoryBarrier(vulkan_context.image(), guest_output_subresource_range, + ui::vulkan::VulkanPresenter::kGuestOutputInternalStageMask, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + ui::vulkan::VulkanPresenter::kGuestOutputInternalAccessMask, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + } + + // End the current render pass before inserting barriers and starting + // a new one, and insert the barrier. + SubmitBarriers(true); + + SwapFramebuffer& swap_framebuffer = swap_framebuffers_[swap_framebuffer_index]; + swap_framebuffer.last_submission = GetCurrentSubmission(); + + VkRenderPassBeginInfo render_pass_begin_info; + render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + render_pass_begin_info.pNext = nullptr; + render_pass_begin_info.renderPass = swap_apply_gamma_render_pass_; + render_pass_begin_info.framebuffer = swap_framebuffer.framebuffer; + render_pass_begin_info.renderArea.offset.x = 0; + render_pass_begin_info.renderArea.offset.y = 0; + render_pass_begin_info.renderArea.extent.width = guest_output_width; + render_pass_begin_info.renderArea.extent.height = guest_output_height; + render_pass_begin_info.clearValueCount = 0; + render_pass_begin_info.pClearValues = nullptr; + deferred_command_buffer_.CmdVkBeginRenderPass(&render_pass_begin_info, + VK_SUBPASS_CONTENTS_INLINE); + + VkViewport viewport; + viewport.x = 0.0f; + viewport.y = 0.0f; + viewport.width = float(guest_output_width); + viewport.height = float(guest_output_height); + viewport.minDepth = 0.0f; + viewport.maxDepth = 1.0f; + SetViewport(viewport); + VkRect2D scissor; + scissor.offset.x = 0; + scissor.offset.y = 0; + scissor.extent.width = guest_output_width; + scissor.extent.height = guest_output_height; + SetScissor(scissor); + + VkPipeline swap_apply_gamma_pipeline = use_pwl_gamma_ramp + ? swap_apply_gamma_pwl_pipeline_ + : swap_apply_gamma_256_entry_table_pipeline_; + if (!vulkan_device->properties().imageViewFormatSwizzle && swap_source_needs_rb_swap) { + VkPipeline swap_apply_gamma_rb_swap_pipeline = + use_pwl_gamma_ramp ? swap_apply_gamma_pwl_rb_swap_pipeline_ + : swap_apply_gamma_256_entry_table_rb_swap_pipeline_; + if (swap_apply_gamma_rb_swap_pipeline != VK_NULL_HANDLE) { + swap_apply_gamma_pipeline = swap_apply_gamma_rb_swap_pipeline; + } else { + static bool swap_rb_swap_fallback_missing_logged = false; + if (!swap_rb_swap_fallback_missing_logged) { + swap_rb_swap_fallback_missing_logged = true; + REXGPU_WARN( + "Vulkan imageViewFormatSwizzle is unavailable and the " + "swap source needs red/blue swizzle, but the graphics " + "fallback RB-swap shader pipeline is unavailable"); + } + } + } + BindExternalGraphicsPipeline(swap_apply_gamma_pipeline); + + std::array swap_descriptor_sets{}; + swap_descriptor_sets[kSwapApplyGammaDescriptorSetRamp] = + swap_descriptors_gamma_ramp_[2 * gamma_ramp_frame_index_ref + + uint32_t(use_pwl_gamma_ramp)]; + swap_descriptor_sets[kSwapApplyGammaDescriptorSetSource] = swap_descriptor_source; + deferred_command_buffer_.CmdVkBindDescriptorSets( + VK_PIPELINE_BIND_POINT_GRAPHICS, swap_apply_gamma_pipeline_layout_, 0, + uint32_t(swap_descriptor_sets.size()), swap_descriptor_sets.data(), 0, nullptr); + + deferred_command_buffer_.CmdVkDraw(3, 1, 0, 0); + deferred_command_buffer_.CmdVkEndRenderPass(); + + // Insert the release barrier. + PushImageMemoryBarrier(vulkan_context.image(), guest_output_subresource_range, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + ui::vulkan::VulkanPresenter::kGuestOutputInternalStageMask, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + ui::vulkan::VulkanPresenter::kGuestOutputInternalAccessMask, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + ui::vulkan::VulkanPresenter::kGuestOutputInternalLayout); + } + + // Need to submit all the commands before giving the image back to the + // presenter so it can submit its own commands for displaying it to the + // queue, and also need to submit the release barrier. + EndSubmission(true); + return true; + }); + + // End the frame even if did not present for any reason (the image refresher + // was not called), to prevent leaking per-frame resources. + EndSubmission(true); +} + +bool VulkanCommandProcessor::PushBufferMemoryBarrier( + VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size, VkPipelineStageFlags src_stage_mask, + VkPipelineStageFlags dst_stage_mask, VkAccessFlags src_access_mask, + VkAccessFlags dst_access_mask, uint32_t src_queue_family_index, uint32_t dst_queue_family_index, + bool skip_if_equal) { + if (skip_if_equal && src_stage_mask == dst_stage_mask && src_access_mask == dst_access_mask && + src_queue_family_index == dst_queue_family_index) { + return false; + } + + // Separate different barriers for overlapping buffer ranges into different + // pipeline barrier commands. + for (const VkBufferMemoryBarrier& other_buffer_memory_barrier : + pending_barriers_buffer_memory_barriers_) { + if (other_buffer_memory_barrier.buffer != buffer || + (size != VK_WHOLE_SIZE && offset + size <= other_buffer_memory_barrier.offset) || + (other_buffer_memory_barrier.size != VK_WHOLE_SIZE && + other_buffer_memory_barrier.offset + other_buffer_memory_barrier.size <= offset)) { + continue; + } + if (other_buffer_memory_barrier.offset == offset && other_buffer_memory_barrier.size == size && + other_buffer_memory_barrier.srcAccessMask == src_access_mask && + other_buffer_memory_barrier.dstAccessMask == dst_access_mask && + other_buffer_memory_barrier.srcQueueFamilyIndex == src_queue_family_index && + other_buffer_memory_barrier.dstQueueFamilyIndex == dst_queue_family_index) { + // The barrier is already pending. + current_pending_barrier_.src_stage_mask |= src_stage_mask; + current_pending_barrier_.dst_stage_mask |= dst_stage_mask; + return true; + } + SplitPendingBarrier(); + break; + } + + current_pending_barrier_.src_stage_mask |= src_stage_mask; + current_pending_barrier_.dst_stage_mask |= dst_stage_mask; + VkBufferMemoryBarrier& buffer_memory_barrier = + pending_barriers_buffer_memory_barriers_.emplace_back(); + buffer_memory_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; + buffer_memory_barrier.pNext = nullptr; + buffer_memory_barrier.srcAccessMask = src_access_mask; + buffer_memory_barrier.dstAccessMask = dst_access_mask; + buffer_memory_barrier.srcQueueFamilyIndex = src_queue_family_index; + buffer_memory_barrier.dstQueueFamilyIndex = dst_queue_family_index; + buffer_memory_barrier.buffer = buffer; + buffer_memory_barrier.offset = offset; + buffer_memory_barrier.size = size; + return true; +} + +bool VulkanCommandProcessor::PushImageMemoryBarrier( + VkImage image, const VkImageSubresourceRange& subresource_range, + VkPipelineStageFlags src_stage_mask, VkPipelineStageFlags dst_stage_mask, + VkAccessFlags src_access_mask, VkAccessFlags dst_access_mask, VkImageLayout old_layout, + VkImageLayout new_layout, uint32_t src_queue_family_index, uint32_t dst_queue_family_index, + bool skip_if_equal) { + if (skip_if_equal && src_stage_mask == dst_stage_mask && src_access_mask == dst_access_mask && + old_layout == new_layout && src_queue_family_index == dst_queue_family_index) { + return false; + } + + // Separate different barriers for overlapping image subresource ranges into + // different pipeline barrier commands. + for (const VkImageMemoryBarrier& other_image_memory_barrier : + pending_barriers_image_memory_barriers_) { + if (other_image_memory_barrier.image != image || + !(other_image_memory_barrier.subresourceRange.aspectMask & subresource_range.aspectMask) || + (subresource_range.levelCount != VK_REMAINING_MIP_LEVELS && + subresource_range.baseMipLevel + subresource_range.levelCount <= + other_image_memory_barrier.subresourceRange.baseMipLevel) || + (other_image_memory_barrier.subresourceRange.levelCount != VK_REMAINING_MIP_LEVELS && + other_image_memory_barrier.subresourceRange.baseMipLevel + + other_image_memory_barrier.subresourceRange.levelCount <= + subresource_range.baseMipLevel) || + (subresource_range.layerCount != VK_REMAINING_ARRAY_LAYERS && + subresource_range.baseArrayLayer + subresource_range.layerCount <= + other_image_memory_barrier.subresourceRange.baseArrayLayer) || + (other_image_memory_barrier.subresourceRange.layerCount != VK_REMAINING_ARRAY_LAYERS && + other_image_memory_barrier.subresourceRange.baseArrayLayer + + other_image_memory_barrier.subresourceRange.layerCount <= + subresource_range.baseArrayLayer)) { + continue; + } + if (other_image_memory_barrier.subresourceRange.aspectMask == subresource_range.aspectMask && + other_image_memory_barrier.subresourceRange.baseMipLevel == + subresource_range.baseMipLevel && + other_image_memory_barrier.subresourceRange.levelCount == subresource_range.levelCount && + other_image_memory_barrier.subresourceRange.baseArrayLayer == + subresource_range.baseArrayLayer && + other_image_memory_barrier.subresourceRange.layerCount == subresource_range.layerCount && + other_image_memory_barrier.srcAccessMask == src_access_mask && + other_image_memory_barrier.dstAccessMask == dst_access_mask && + other_image_memory_barrier.oldLayout == old_layout && + other_image_memory_barrier.newLayout == new_layout && + other_image_memory_barrier.srcQueueFamilyIndex == src_queue_family_index && + other_image_memory_barrier.dstQueueFamilyIndex == dst_queue_family_index) { + // The barrier is already pending. + current_pending_barrier_.src_stage_mask |= src_stage_mask; + current_pending_barrier_.dst_stage_mask |= dst_stage_mask; + return true; + } + SplitPendingBarrier(); + break; + } + + current_pending_barrier_.src_stage_mask |= src_stage_mask; + current_pending_barrier_.dst_stage_mask |= dst_stage_mask; + VkImageMemoryBarrier& image_memory_barrier = + pending_barriers_image_memory_barriers_.emplace_back(); + image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + image_memory_barrier.pNext = nullptr; + image_memory_barrier.srcAccessMask = src_access_mask; + image_memory_barrier.dstAccessMask = dst_access_mask; + image_memory_barrier.oldLayout = old_layout; + image_memory_barrier.newLayout = new_layout; + image_memory_barrier.srcQueueFamilyIndex = src_queue_family_index; + image_memory_barrier.dstQueueFamilyIndex = dst_queue_family_index; + image_memory_barrier.image = image; + image_memory_barrier.subresourceRange = subresource_range; + return true; +} + +bool VulkanCommandProcessor::SubmitBarriers(bool force_end_render_pass) { + assert_true(submission_open_); + SplitPendingBarrier(); + if (pending_barriers_.empty()) { + if (force_end_render_pass) { + EndRenderPass(); + } + return false; + } + EndRenderPass(); + for (auto it = pending_barriers_.cbegin(); it != pending_barriers_.cend(); ++it) { + auto it_next = std::next(it); + bool is_last = it_next == pending_barriers_.cend(); + // .data() + offset, not &[offset], for buffer and image barriers, because + // if there are no buffer or image memory barriers in the last pipeline + // barriers, the offsets may be equal to the sizes of the vectors. + deferred_command_buffer_.CmdVkPipelineBarrier( + it->src_stage_mask ? it->src_stage_mask : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + it->dst_stage_mask ? it->dst_stage_mask : VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, + nullptr, + uint32_t((is_last ? pending_barriers_buffer_memory_barriers_.size() + : it_next->buffer_memory_barriers_offset) - + it->buffer_memory_barriers_offset), + pending_barriers_buffer_memory_barriers_.data() + it->buffer_memory_barriers_offset, + uint32_t((is_last ? pending_barriers_image_memory_barriers_.size() + : it_next->image_memory_barriers_offset) - + it->image_memory_barriers_offset), + pending_barriers_image_memory_barriers_.data() + it->image_memory_barriers_offset); + } + pending_barriers_.clear(); + pending_barriers_buffer_memory_barriers_.clear(); + pending_barriers_image_memory_barriers_.clear(); + current_pending_barrier_.buffer_memory_barriers_offset = 0; + current_pending_barrier_.image_memory_barriers_offset = 0; + return true; +} + +void VulkanCommandProcessor::SubmitBarriersAndEnterRenderTargetCacheRenderPass( + VkRenderPass render_pass, const VulkanRenderTargetCache::Framebuffer* framebuffer) { + SubmitBarriers(false); + const ui::vulkan::VulkanDevice* vulkan_device = GetVulkanDevice(); + bool use_dynamic_rendering = + REXCVAR_GET(vulkan_dynamic_rendering) && vulkan_device->properties().dynamicRendering; + + if (use_dynamic_rendering) { + if (in_render_pass_ && current_framebuffer_ == framebuffer && + current_render_pass_ == VK_NULL_HANDLE) { + return; + } + } else { + if (current_render_pass_ == render_pass && current_framebuffer_ == framebuffer) { + return; + } + } + + if (in_render_pass_) { + if (use_dynamic_rendering) { + deferred_command_buffer_.CmdVkEndRendering(); + } else { + deferred_command_buffer_.CmdVkEndRenderPass(); + } + in_render_pass_ = false; + } + + current_render_pass_ = use_dynamic_rendering ? VK_NULL_HANDLE : render_pass; + current_framebuffer_ = framebuffer; + + if (use_dynamic_rendering) { + VkRenderingAttachmentInfo color_attachments[xenos::kMaxColorRenderTargets]; + VkRenderingAttachmentInfo depth_attachment; + VkRenderingAttachmentInfo stencil_attachment; + uint32_t color_attachment_count = 0; + render_target_cache_->GetLastUpdateRenderingAttachments( + color_attachments, &color_attachment_count, &depth_attachment, &stencil_attachment); + bool has_depth = depth_attachment.sType == VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + bool has_stencil = stencil_attachment.sType == VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + + VkRenderingInfo rendering_info = {}; + rendering_info.sType = VK_STRUCTURE_TYPE_RENDERING_INFO; + rendering_info.pNext = nullptr; + rendering_info.flags = 0; + rendering_info.renderArea.offset.x = 0; + rendering_info.renderArea.offset.y = 0; + rendering_info.renderArea.extent = framebuffer->host_extent; + rendering_info.layerCount = 1; + rendering_info.viewMask = 0; + rendering_info.colorAttachmentCount = color_attachment_count; + rendering_info.pColorAttachments = color_attachment_count ? color_attachments : nullptr; + rendering_info.pDepthAttachment = has_depth ? &depth_attachment : nullptr; + rendering_info.pStencilAttachment = has_stencil ? &stencil_attachment : nullptr; + deferred_command_buffer_.CmdVkBeginRendering(&rendering_info); + } else { + VkRenderPassBeginInfo render_pass_begin_info; + render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + render_pass_begin_info.pNext = nullptr; + render_pass_begin_info.renderPass = render_pass; + render_pass_begin_info.framebuffer = framebuffer->framebuffer; + render_pass_begin_info.renderArea.offset.x = 0; + render_pass_begin_info.renderArea.offset.y = 0; + // TODO(Triang3l): Actual dirty width / height in the deferred command + // buffer. + render_pass_begin_info.renderArea.extent = framebuffer->host_extent; + render_pass_begin_info.clearValueCount = 0; + render_pass_begin_info.pClearValues = nullptr; + deferred_command_buffer_.CmdVkBeginRenderPass(&render_pass_begin_info, + VK_SUBPASS_CONTENTS_INLINE); + } + in_render_pass_ = true; +} + +void VulkanCommandProcessor::SubmitBarriersAndEnterRenderTargetCacheRenderPass( + VkRenderPass render_pass, const VulkanRenderTargetCache::Framebuffer* framebuffer, + VkImageView transfer_dest_view, bool transfer_dest_is_depth) { + SubmitBarriers(false); + const ui::vulkan::VulkanDevice* vulkan_device = GetVulkanDevice(); + bool use_dynamic_rendering = + REXCVAR_GET(vulkan_dynamic_rendering) && vulkan_device->properties().dynamicRendering; + + if (use_dynamic_rendering) { + if (in_render_pass_ && current_framebuffer_ == framebuffer && + current_render_pass_ == VK_NULL_HANDLE) { + return; + } + } else { + if (current_render_pass_ == render_pass && current_framebuffer_ == framebuffer) { + return; + } + } + + if (in_render_pass_) { + if (use_dynamic_rendering) { + deferred_command_buffer_.CmdVkEndRendering(); + } else { + deferred_command_buffer_.CmdVkEndRenderPass(); + } + in_render_pass_ = false; + } + + current_render_pass_ = use_dynamic_rendering ? VK_NULL_HANDLE : render_pass; + current_framebuffer_ = framebuffer; + + if (use_dynamic_rendering) { + VkRenderingAttachmentInfo color_attachment = {}; + VkRenderingAttachmentInfo depth_attachment = {}; + VkRenderingAttachmentInfo stencil_attachment = {}; + + if (transfer_dest_is_depth) { + depth_attachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + depth_attachment.pNext = nullptr; + depth_attachment.imageView = transfer_dest_view; + depth_attachment.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + depth_attachment.resolveMode = VK_RESOLVE_MODE_NONE; + depth_attachment.resolveImageView = VK_NULL_HANDLE; + depth_attachment.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + depth_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + depth_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + depth_attachment.clearValue = {}; + stencil_attachment = depth_attachment; + } else { + color_attachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + color_attachment.pNext = nullptr; + color_attachment.imageView = transfer_dest_view; + color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + color_attachment.resolveMode = VK_RESOLVE_MODE_NONE; + color_attachment.resolveImageView = VK_NULL_HANDLE; + color_attachment.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + color_attachment.clearValue = {}; + } + + VkRenderingInfo rendering_info = {}; + rendering_info.sType = VK_STRUCTURE_TYPE_RENDERING_INFO; + rendering_info.pNext = nullptr; + rendering_info.flags = 0; + rendering_info.renderArea.offset.x = 0; + rendering_info.renderArea.offset.y = 0; + rendering_info.renderArea.extent = framebuffer->host_extent; + rendering_info.layerCount = 1; + rendering_info.viewMask = 0; + rendering_info.colorAttachmentCount = transfer_dest_is_depth ? 0 : 1; + rendering_info.pColorAttachments = transfer_dest_is_depth ? nullptr : &color_attachment; + rendering_info.pDepthAttachment = transfer_dest_is_depth ? &depth_attachment : nullptr; + rendering_info.pStencilAttachment = transfer_dest_is_depth ? &stencil_attachment : nullptr; + deferred_command_buffer_.CmdVkBeginRendering(&rendering_info); + } else { + VkRenderPassBeginInfo render_pass_begin_info; + render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + render_pass_begin_info.pNext = nullptr; + render_pass_begin_info.renderPass = render_pass; + render_pass_begin_info.framebuffer = framebuffer->framebuffer; + render_pass_begin_info.renderArea.offset.x = 0; + render_pass_begin_info.renderArea.offset.y = 0; + render_pass_begin_info.renderArea.extent = framebuffer->host_extent; + render_pass_begin_info.clearValueCount = 0; + render_pass_begin_info.pClearValues = nullptr; + deferred_command_buffer_.CmdVkBeginRenderPass(&render_pass_begin_info, + VK_SUBPASS_CONTENTS_INLINE); + } + in_render_pass_ = true; +} + +void VulkanCommandProcessor::EndRenderPass() { + assert_true(submission_open_); + if (!in_render_pass_) { + return; + } + if (current_render_pass_ == VK_NULL_HANDLE) { + deferred_command_buffer_.CmdVkEndRendering(); + } else { + deferred_command_buffer_.CmdVkEndRenderPass(); + } + current_render_pass_ = VK_NULL_HANDLE; + current_framebuffer_ = nullptr; + in_render_pass_ = false; +} + +VkDescriptorSet VulkanCommandProcessor::AllocateSingleTransientDescriptor( + SingleTransientDescriptorLayout transient_descriptor_layout) { + assert_true(frame_open_); + VkDescriptorSet descriptor_set; + std::vector& transient_descriptors_free = + single_transient_descriptors_free_[size_t(transient_descriptor_layout)]; + if (!transient_descriptors_free.empty()) { + descriptor_set = transient_descriptors_free.back(); + transient_descriptors_free.pop_back(); + } else { + const ui::vulkan::VulkanDevice* const vulkan_device = GetVulkanDevice(); + [[maybe_unused]] const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + [[maybe_unused]] const VkDevice device = vulkan_device->device(); + bool is_storage_buffer = + transient_descriptor_layout == SingleTransientDescriptorLayout::kStorageBufferCompute || + transient_descriptor_layout == SingleTransientDescriptorLayout::kStorageBufferPairCompute; + ui::vulkan::LinkedTypeDescriptorSetAllocator& transient_descriptor_allocator = + is_storage_buffer ? transient_descriptor_allocator_storage_buffer_ + : transient_descriptor_allocator_uniform_buffer_; + VkDescriptorPoolSize descriptor_count; + descriptor_count.type = + is_storage_buffer ? VK_DESCRIPTOR_TYPE_STORAGE_BUFFER : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + descriptor_count.descriptorCount = + transient_descriptor_layout == SingleTransientDescriptorLayout::kStorageBufferPairCompute + ? 2 + : 1; + descriptor_set = transient_descriptor_allocator.Allocate( + GetSingleTransientDescriptorLayout(transient_descriptor_layout), &descriptor_count, 1); + if (descriptor_set == VK_NULL_HANDLE) { + return VK_NULL_HANDLE; + } + } + UsedSingleTransientDescriptor used_descriptor; + used_descriptor.frame = frame_current_; + used_descriptor.layout = transient_descriptor_layout; + used_descriptor.set = descriptor_set; + single_transient_descriptors_used_.emplace_back(used_descriptor); + return descriptor_set; +} + +VkDescriptorSetLayout VulkanCommandProcessor::GetTextureDescriptorSetLayout(bool is_vertex, + size_t texture_count, + size_t sampler_count) { + size_t binding_count = texture_count + sampler_count; + if (!binding_count) { + return descriptor_set_layout_empty_; + } + + TextureDescriptorSetLayoutKey texture_descriptor_set_layout_key; + texture_descriptor_set_layout_key.texture_count = uint32_t(texture_count); + texture_descriptor_set_layout_key.sampler_count = uint32_t(sampler_count); + texture_descriptor_set_layout_key.is_vertex = uint32_t(is_vertex); + auto it_existing = descriptor_set_layouts_textures_.find(texture_descriptor_set_layout_key); + if (it_existing != descriptor_set_layouts_textures_.end()) { + return it_existing->second; + } + + const ui::vulkan::VulkanDevice* const vulkan_device = GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + descriptor_set_layout_bindings_.clear(); + descriptor_set_layout_bindings_.reserve(binding_count); + VkShaderStageFlags stage_flags = + is_vertex ? guest_shader_vertex_stages_ : VK_SHADER_STAGE_FRAGMENT_BIT; + for (size_t i = 0; i < texture_count; ++i) { + VkDescriptorSetLayoutBinding& descriptor_set_layout_binding = + descriptor_set_layout_bindings_.emplace_back(); + descriptor_set_layout_binding.binding = uint32_t(i); + descriptor_set_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + descriptor_set_layout_binding.descriptorCount = 1; + descriptor_set_layout_binding.stageFlags = stage_flags; + } + for (size_t i = 0; i < sampler_count; ++i) { + VkDescriptorSetLayoutBinding& descriptor_set_layout_binding = + descriptor_set_layout_bindings_.emplace_back(); + descriptor_set_layout_binding.binding = uint32_t(texture_count + i); + descriptor_set_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; + descriptor_set_layout_binding.descriptorCount = 1; + descriptor_set_layout_binding.stageFlags = stage_flags; + } + VkDescriptorSetLayoutCreateInfo descriptor_set_layout_create_info; + descriptor_set_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + descriptor_set_layout_create_info.pNext = nullptr; + descriptor_set_layout_create_info.flags = 0; + descriptor_set_layout_create_info.bindingCount = uint32_t(binding_count); + descriptor_set_layout_create_info.pBindings = descriptor_set_layout_bindings_.data(); + VkDescriptorSetLayout texture_descriptor_set_layout; + if (dfn.vkCreateDescriptorSetLayout(device, &descriptor_set_layout_create_info, nullptr, + &texture_descriptor_set_layout) != VK_SUCCESS) { + return VK_NULL_HANDLE; + } + descriptor_set_layouts_textures_.emplace(texture_descriptor_set_layout_key, + texture_descriptor_set_layout); + return texture_descriptor_set_layout; +} + +const VulkanPipelineCache::PipelineLayoutProvider* VulkanCommandProcessor::GetPipelineLayout( + size_t texture_count_pixel, size_t sampler_count_pixel, size_t texture_count_vertex, + size_t sampler_count_vertex) { + PipelineLayoutKey pipeline_layout_key; + pipeline_layout_key.texture_count_pixel = uint16_t(texture_count_pixel); + pipeline_layout_key.sampler_count_pixel = uint16_t(sampler_count_pixel); + pipeline_layout_key.texture_count_vertex = uint16_t(texture_count_vertex); + pipeline_layout_key.sampler_count_vertex = uint16_t(sampler_count_vertex); + { + auto it = pipeline_layouts_.find(pipeline_layout_key); + if (it != pipeline_layouts_.end()) { + return &it->second; + } + } + + VkDescriptorSetLayout descriptor_set_layout_textures_vertex = + GetTextureDescriptorSetLayout(true, texture_count_vertex, sampler_count_vertex); + if (descriptor_set_layout_textures_vertex == VK_NULL_HANDLE) { + REXGPU_ERROR( + "Failed to obtain a Vulkan descriptor set layout for {} sampled images " + "and {} samplers for guest vertex shaders", + texture_count_vertex, sampler_count_vertex); + return nullptr; + } + VkDescriptorSetLayout descriptor_set_layout_textures_pixel = + GetTextureDescriptorSetLayout(false, texture_count_pixel, sampler_count_pixel); + if (descriptor_set_layout_textures_pixel == VK_NULL_HANDLE) { + REXGPU_ERROR( + "Failed to obtain a Vulkan descriptor set layout for {} sampled images " + "and {} samplers for guest pixel shaders", + texture_count_pixel, sampler_count_pixel); + return nullptr; + } + + VkDescriptorSetLayout descriptor_set_layouts[SpirvShaderTranslator::kDescriptorSetCount]; + // Immutable layouts. + descriptor_set_layouts[SpirvShaderTranslator::kDescriptorSetSharedMemoryAndEdram] = + descriptor_set_layout_shared_memory_and_edram_; + descriptor_set_layouts[SpirvShaderTranslator::kDescriptorSetConstants] = + descriptor_set_layout_constants_; + // Mutable layouts. + descriptor_set_layouts[SpirvShaderTranslator::kDescriptorSetTexturesVertex] = + descriptor_set_layout_textures_vertex; + descriptor_set_layouts[SpirvShaderTranslator::kDescriptorSetTexturesPixel] = + descriptor_set_layout_textures_pixel; + + const ui::vulkan::VulkanDevice* const vulkan_device = GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + VkPipelineLayoutCreateInfo pipeline_layout_create_info; + pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipeline_layout_create_info.pNext = nullptr; + pipeline_layout_create_info.flags = 0; + pipeline_layout_create_info.setLayoutCount = uint32_t(rex::countof(descriptor_set_layouts)); + pipeline_layout_create_info.pSetLayouts = descriptor_set_layouts; + pipeline_layout_create_info.pushConstantRangeCount = 0; + pipeline_layout_create_info.pPushConstantRanges = nullptr; + VkPipelineLayout pipeline_layout; + if (dfn.vkCreatePipelineLayout(device, &pipeline_layout_create_info, nullptr, &pipeline_layout) != + VK_SUCCESS) { + REXGPU_ERROR( + "Failed to create a Vulkan pipeline layout for guest drawing with {} " + "pixel shader and {} vertex shader textures", + texture_count_pixel, texture_count_vertex); + return nullptr; + } + auto emplaced_pair = pipeline_layouts_.emplace( + std::piecewise_construct, std::forward_as_tuple(pipeline_layout_key), + std::forward_as_tuple(pipeline_layout, descriptor_set_layout_textures_vertex, + descriptor_set_layout_textures_pixel)); + // unordered_map insertion doesn't invalidate element references. + return &emplaced_pair.first->second; +} + +VulkanCommandProcessor::ScratchBufferAcquisition VulkanCommandProcessor::AcquireScratchGpuBuffer( + VkDeviceSize size, VkPipelineStageFlags initial_stage_mask, VkAccessFlags initial_access_mask) { + assert_true(submission_open_); + assert_false(scratch_buffer_used_); + if (!submission_open_ || scratch_buffer_used_ || !size) { + return ScratchBufferAcquisition(); + } + + uint64_t submission_current = GetCurrentSubmission(); + + if (scratch_buffer_ != VK_NULL_HANDLE && size <= scratch_buffer_size_) { + // Already used previously - transition. + PushBufferMemoryBarrier(scratch_buffer_, 0, VK_WHOLE_SIZE, scratch_buffer_last_stage_mask_, + initial_stage_mask, scratch_buffer_last_access_mask_, + initial_access_mask); + scratch_buffer_last_stage_mask_ = initial_stage_mask; + scratch_buffer_last_access_mask_ = initial_access_mask; + scratch_buffer_last_usage_submission_ = submission_current; + scratch_buffer_used_ = true; + return ScratchBufferAcquisition(*this, scratch_buffer_, initial_stage_mask, + initial_access_mask); + } + + size = rex::align(size, kScratchBufferSizeIncrement); + + const ui::vulkan::VulkanDevice* const vulkan_device = GetVulkanDevice(); + + VkDeviceMemory new_scratch_buffer_memory; + VkBuffer new_scratch_buffer; + // VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT for + // texture loading. + if (!ui::vulkan::util::CreateDedicatedAllocationBuffer( + vulkan_device, size, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, + ui::vulkan::util::MemoryPurpose::kDeviceLocal, new_scratch_buffer, + new_scratch_buffer_memory)) { + REXGPU_ERROR("VulkanCommandProcessor: Failed to create a {} MB scratch GPU buffer", size >> 20); + return ScratchBufferAcquisition(); + } + + if (submission_completed_ >= scratch_buffer_last_usage_submission_) { + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + if (scratch_buffer_ != VK_NULL_HANDLE) { + dfn.vkDestroyBuffer(device, scratch_buffer_, nullptr); + } + if (scratch_buffer_memory_ != VK_NULL_HANDLE) { + dfn.vkFreeMemory(device, scratch_buffer_memory_, nullptr); + } + } else { + if (scratch_buffer_ != VK_NULL_HANDLE) { + destroy_buffers_.emplace_back(scratch_buffer_last_usage_submission_, scratch_buffer_); + } + if (scratch_buffer_memory_ != VK_NULL_HANDLE) { + destroy_memory_.emplace_back(scratch_buffer_last_usage_submission_, scratch_buffer_memory_); + } + } + + scratch_buffer_memory_ = new_scratch_buffer_memory; + scratch_buffer_ = new_scratch_buffer; + scratch_buffer_size_ = size; + // Not used yet, no need for a barrier. + scratch_buffer_last_stage_mask_ = initial_access_mask; + scratch_buffer_last_access_mask_ = initial_stage_mask; + scratch_buffer_last_usage_submission_ = submission_current; + scratch_buffer_used_ = true; + return ScratchBufferAcquisition(*this, new_scratch_buffer, initial_stage_mask, + initial_access_mask); +} + +void VulkanCommandProcessor::BindExternalGraphicsPipeline(VkPipeline pipeline, + bool keep_dynamic_depth_bias, + bool keep_dynamic_blend_constants, + bool keep_dynamic_stencil_mask_ref) { + if (!keep_dynamic_depth_bias) { + dynamic_depth_bias_update_needed_ = true; + } + if (!keep_dynamic_blend_constants) { + dynamic_blend_constants_update_needed_ = true; + } + if (!keep_dynamic_stencil_mask_ref) { + dynamic_stencil_compare_mask_front_update_needed_ = true; + dynamic_stencil_compare_mask_back_update_needed_ = true; + dynamic_stencil_write_mask_front_update_needed_ = true; + dynamic_stencil_write_mask_back_update_needed_ = true; + dynamic_stencil_reference_front_update_needed_ = true; + dynamic_stencil_reference_back_update_needed_ = true; + } + if (current_external_graphics_pipeline_ == pipeline) { + return; + } + deferred_command_buffer_.CmdVkBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + current_external_graphics_pipeline_ = pipeline; + current_guest_graphics_pipeline_ = VK_NULL_HANDLE; + current_guest_graphics_pipeline_layout_ = VK_NULL_HANDLE; +} + +void VulkanCommandProcessor::BindExternalComputePipeline(VkPipeline pipeline) { + if (current_external_compute_pipeline_ == pipeline) { + return; + } + deferred_command_buffer_.CmdVkBindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); + current_external_compute_pipeline_ = pipeline; +} + +void VulkanCommandProcessor::SetViewport(const VkViewport& viewport) { + if (!dynamic_viewport_update_needed_) { + dynamic_viewport_update_needed_ |= dynamic_viewport_.x != viewport.x; + dynamic_viewport_update_needed_ |= dynamic_viewport_.y != viewport.y; + dynamic_viewport_update_needed_ |= dynamic_viewport_.width != viewport.width; + dynamic_viewport_update_needed_ |= dynamic_viewport_.height != viewport.height; + dynamic_viewport_update_needed_ |= dynamic_viewport_.minDepth != viewport.minDepth; + dynamic_viewport_update_needed_ |= dynamic_viewport_.maxDepth != viewport.maxDepth; + } + if (dynamic_viewport_update_needed_) { + dynamic_viewport_ = viewport; + deferred_command_buffer_.CmdVkSetViewport(0, 1, &dynamic_viewport_); + dynamic_viewport_update_needed_ = false; + } +} + +void VulkanCommandProcessor::SetScissor(const VkRect2D& scissor) { + if (!dynamic_scissor_update_needed_) { + dynamic_scissor_update_needed_ |= dynamic_scissor_.offset.x != scissor.offset.x; + dynamic_scissor_update_needed_ |= dynamic_scissor_.offset.y != scissor.offset.y; + dynamic_scissor_update_needed_ |= dynamic_scissor_.extent.width != scissor.extent.width; + dynamic_scissor_update_needed_ |= dynamic_scissor_.extent.height != scissor.extent.height; + } + if (dynamic_scissor_update_needed_) { + dynamic_scissor_ = scissor; + deferred_command_buffer_.CmdVkSetScissor(0, 1, &dynamic_scissor_); + dynamic_scissor_update_needed_ = false; + } +} + +void VulkanCommandProcessor::OnPrimaryBufferEnd() { + if (REXCVAR_GET(vulkan_submit_on_primary_buffer_end) && submission_open_ && + CanEndSubmissionImmediately()) { + EndSubmission(false); + } +} + +Shader* VulkanCommandProcessor::LoadShader(xenos::ShaderType shader_type, uint32_t guest_address, + const uint32_t* host_address, uint32_t dword_count) { + return pipeline_cache_->LoadShader(shader_type, host_address, dword_count); +} + +bool VulkanCommandProcessor::IssueDraw(xenos::PrimitiveType prim_type, uint32_t index_count, + IndexBufferInfo* index_buffer_info, + bool major_mode_explicit) { +#if XE_GPU_FINE_GRAINED_DRAW_SCOPES + SCOPE_profile_cpu_f("gpu"); +#endif // XE_GPU_FINE_GRAINED_DRAW_SCOPES + + const RegisterFile& regs = *register_file_; + (void)index_buffer_info; + auto draw_fail = [&](const char* stage) { + auto vgt_draw_initiator = regs.Get(); + REXGPU_ERROR( + "Vulkan IssueDraw failed at {} " + "(prim_type={}, index_count={}, source_select={}, major_mode={}, explicit_major={}, " + "path_select={}, tess_mode={}, edram_mode={})", + stage, uint32_t(prim_type), index_count, uint32_t(vgt_draw_initiator.source_select), + uint32_t(vgt_draw_initiator.major_mode), uint32_t(major_mode_explicit), + uint32_t(regs.Get().path_select), + uint32_t(regs.Get().tess_mode), + uint32_t(regs.Get().edram_mode)); + return false; + }; + + xenos::EdramMode edram_mode = regs.Get().edram_mode; + if (edram_mode == xenos::EdramMode::kCopy) { + // Special copy handling. + return IssueCopy(); + } + + bool surface_pitch_is_zero = regs.Get().surface_pitch == 0; + + const ui::vulkan::VulkanDevice::Properties& device_properties = GetVulkanDevice()->properties(); + + memexport_ranges_.clear(); + + // Vertex shader analysis. + auto vertex_shader = static_cast(active_vertex_shader()); + if (!vertex_shader) { + // Always need a vertex shader. + return draw_fail("missing_vertex_shader"); + } + pipeline_cache_->AnalyzeShaderUcode(*vertex_shader); + bool memexport_used_vertex = vertex_shader->memexport_eM_written() != 0; + if (memexport_used_vertex) { + if (!device_properties.vertexPipelineStoresAndAtomics) { + REXGPU_ERROR( + "Vertex shader memexport draw encountered without " + "vertexPipelineStoresAndAtomics support"); + return false; + } + draw_util::AddMemExportRanges(regs, *vertex_shader, memexport_ranges_); + } + + // Pixel shader analysis. + bool primitive_polygonal = draw_util::IsPrimitivePolygonal(regs); + bool is_rasterization_done = draw_util::IsRasterizationPotentiallyDone(regs, primitive_polygonal); + if (surface_pitch_is_zero && is_rasterization_done) { + // Doesn't actually draw. + // Unlikely that zero would even really be legal though. + return true; + } + VulkanShader* pixel_shader = nullptr; + if (is_rasterization_done) { + // See xenos::EdramMode for explanation why the pixel shader is only used + // when it's kColorDepth here. + if (edram_mode == xenos::EdramMode::kColorDepth) { + pixel_shader = static_cast(active_pixel_shader()); + if (pixel_shader) { + pipeline_cache_->AnalyzeShaderUcode(*pixel_shader); + if (!draw_util::IsPixelShaderNeededWithRasterization(*pixel_shader, regs)) { + pixel_shader = nullptr; + } + } + } + } else { + // Disabling pixel shader for this case is also required by the pipeline + // cache. + if (!memexport_used_vertex) { + // This draw has no effect. + return true; + } + } + bool memexport_used_pixel = pixel_shader && (pixel_shader->memexport_eM_written() != 0); + if (memexport_used_pixel) { + if (!device_properties.fragmentStoresAndAtomics) { + REXGPU_ERROR( + "Pixel shader memexport draw encountered without " + "fragmentStoresAndAtomics support"); + return false; + } + draw_util::AddMemExportRanges(regs, *pixel_shader, memexport_ranges_); + } + reg::RB_DEPTHCONTROL normalized_depth_control = draw_util::GetNormalizedDepthControl(regs); + + uint32_t ps_param_gen_pos = UINT32_MAX; + uint32_t interpolator_mask = + pixel_shader ? (vertex_shader->writes_interpolators() & + pixel_shader->GetInterpolatorInputMask(regs.Get(), + regs.Get(), + ps_param_gen_pos)) + : 0; + + PrimitiveProcessor::ProcessingResult primitive_processing_result; + SpirvShaderTranslator::Modification vertex_shader_modification; + SpirvShaderTranslator::Modification pixel_shader_modification; + VulkanShader::VulkanTranslation* vertex_shader_translation; + VulkanShader::VulkanTranslation* pixel_shader_translation; + bool memexport_writes_possible = memexport_used_vertex || memexport_used_pixel; + + // Two iterations because a submission (even the current one - in which case + // it needs to be ended, and a new one must be started) may need to be awaited + // in case of a sampler count overflow, and if that happens, all subsystem + // updates done previously must be performed again because the updates done + // before the awaiting may be referencing objects destroyed by + // CompletedSubmissionUpdated. + for (uint32_t i = 0; i < 2; ++i) { + if (!BeginSubmission(true)) { + return draw_fail("begin_submission"); + } + + // Process primitives. + if (!primitive_processor_->Process(primitive_processing_result)) { + return draw_fail("primitive_processing"); + } + if (!primitive_processing_result.host_draw_vertex_count) { + // Nothing to draw. + return true; + } + if (primitive_processing_result.host_primitive_type == xenos::PrimitiveType::kTriangleFan) { + // Vulkan uses the same fan-to-list conversion policy as D3D12. + REXGPU_ERROR( + "PrimitiveProcessor returned triangle fan for Vulkan draw; expected " + "triangle list conversion for D3D12 parity"); + assert_always(); + return false; + } + // Tessellation and rectangle expansion variants for rasterization are + // produced by the primitive processor and are handled by the Vulkan + // pipeline cache. + Shader::HostVertexShaderType host_vertex_shader_type = + primitive_processing_result.host_vertex_shader_type; + if (host_vertex_shader_type != Shader::HostVertexShaderType::kVertex && + host_vertex_shader_type != Shader::HostVertexShaderType::kPointListAsTriangleStrip && + host_vertex_shader_type != Shader::HostVertexShaderType::kRectangleListAsTriangleStrip && + !Shader::IsHostVertexShaderTypeDomain(host_vertex_shader_type)) { + REXGPU_ERROR("Unsupported Vulkan host vertex shader type {}", + uint32_t(host_vertex_shader_type)); + return false; + } + + // Shader modifications. + vertex_shader_modification = pipeline_cache_->GetCurrentVertexShaderModification( + *vertex_shader, primitive_processing_result.host_vertex_shader_type, interpolator_mask, + ps_param_gen_pos != UINT32_MAX); + pixel_shader_modification = pixel_shader ? pipeline_cache_->GetCurrentPixelShaderModification( + *pixel_shader, interpolator_mask, + ps_param_gen_pos, normalized_depth_control) + : SpirvShaderTranslator::Modification(0); + + // Translate the shaders now to obtain the sampler bindings. + vertex_shader_translation = static_cast( + vertex_shader->GetOrCreateTranslation(vertex_shader_modification.value)); + pixel_shader_translation = + pixel_shader ? static_cast( + pixel_shader->GetOrCreateTranslation(pixel_shader_modification.value)) + : nullptr; + if (!pipeline_cache_->EnsureShadersTranslated(vertex_shader_translation, + pixel_shader_translation)) { + return draw_fail("shader_translation"); + } + + // Obtain the samplers. Note that the bindings don't depend on the shader + // modification, so if on the second iteration of this loop it becomes + // different for some reason (like a race condition with the guest in index + // buffer processing in the primitive processor resulting in different host + // vertex shader types), the bindings will stay the same. + // TODO(Triang3l): Sampler caching and reuse for adjacent draws within one + // submission. + uint32_t samplers_overflowed_count = 0; + for (uint32_t j = 0; j < 2; ++j) { + std::vector>& shader_samplers = + j ? current_samplers_pixel_ : current_samplers_vertex_; + if (!i) { + shader_samplers.clear(); + } + const VulkanShader* shader = j ? pixel_shader : vertex_shader; + if (!shader) { + continue; + } + const std::vector& shader_sampler_bindings = + shader->GetSamplerBindingsAfterTranslation(); + if (!i) { + shader_samplers.reserve(shader_sampler_bindings.size()); + for (const VulkanShader::SamplerBinding& shader_sampler_binding : shader_sampler_bindings) { + shader_samplers.emplace_back(texture_cache_->GetSamplerParameters(shader_sampler_binding), + VK_NULL_HANDLE); + } + } + for (std::pair& shader_sampler_pair : + shader_samplers) { + // UseSampler calls are needed even on the second iteration in case the + // submission was broken (and thus the last usage submission indices for + // the used samplers need to be updated) due to an overflow within one + // submission. Though sampler overflow is a very rare situation overall. + bool sampler_overflowed; + VkSampler shader_sampler = + texture_cache_->UseSampler(shader_sampler_pair.first, sampler_overflowed); + shader_sampler_pair.second = shader_sampler; + if (shader_sampler == VK_NULL_HANDLE) { + if (!sampler_overflowed || i) { + // If !sampler_overflowed, just failed to create a sampler for some + // reason. + // If i == 1, an overflow has happened twice, can't recover from it + // anymore (would enter an infinite loop otherwise if the number of + // attempts was not limited to 2). Possibly too many unique samplers + // in one draw, or failed to await submission completion. + return draw_fail("sampler_acquisition"); + } + ++samplers_overflowed_count; + } + } + } + if (!samplers_overflowed_count) { + break; + } + assert_zero(i); + // Free space for as many samplers as how many haven't been allocated + // successfully - obtain the submission index that needs to be awaited to + // reuse `samplers_overflowed_count` slots. This must be done after all the + // UseSampler calls, not inside the loop calling UseSampler, because earlier + // UseSampler calls may "mark for deletion" some samplers that later + // UseSampler calls in the loop may actually demand. + uint64_t sampler_overflow_await_submission = + texture_cache_->GetSubmissionToAwaitOnSamplerOverflow(samplers_overflowed_count); + assert_true(sampler_overflow_await_submission <= GetCurrentSubmission()); + CheckSubmissionFenceAndDeviceLoss(sampler_overflow_await_submission); + } + + uint32_t normalized_color_mask = + pixel_shader ? draw_util::GetNormalizedColorMask(regs, pixel_shader->writes_color_targets()) + : 0; + + // Update the textures before most other work in the submission because + // samplers depend on this (and in case of sampler overflow in a submission, + // submissions must be split) - may perform dispatches and copying. + uint32_t used_texture_mask = + vertex_shader->GetUsedTextureMaskAfterTranslation() | + (pixel_shader != nullptr ? pixel_shader->GetUsedTextureMaskAfterTranslation() : 0); + texture_cache_->RequestTextures(used_texture_mask); + + const VulkanPipelineCache::PipelineLayoutProvider* pipeline_layout_provider; + // Set up the render targets - this may perform dispatches and draws. + if (!render_target_cache_->Update(is_rasterization_done, normalized_depth_control, + normalized_color_mask, *vertex_shader)) { + return draw_fail("render_target_update"); + } + + // Create the pipeline (for this, need the render pass from the render target + // cache), translating the shaders - doing this now to obtain the used + // textures. + VkPipeline pipeline; + void* pipeline_handle = nullptr; + if (!pipeline_cache_->ConfigurePipeline(vertex_shader_translation, pixel_shader_translation, + primitive_processing_result, normalized_depth_control, + normalized_color_mask, + render_target_cache_->last_update_render_pass_key(), + pipeline, pipeline_layout_provider, &pipeline_handle)) { + return draw_fail("configure_pipeline"); + } + bool pipeline_is_placeholder = false; + // Reload the current handle state to observe async hot-swap completions that + // may happen between pipeline configuration and binding. + pipeline_cache_->GetPipelineAndLayoutByHandle(pipeline_handle, pipeline, pipeline_layout_provider, + &pipeline_is_placeholder); + if (REXCVAR_GET(async_shader_compilation) && pipeline_is_placeholder) { + frame_used_async_placeholder_pipeline_ = true; + return true; + } + if (pipeline == VK_NULL_HANDLE || pipeline_layout_provider == nullptr) { + return draw_fail("pipeline_lookup"); + } + if (current_guest_graphics_pipeline_ != pipeline) { + deferred_command_buffer_.CmdVkBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + current_guest_graphics_pipeline_ = pipeline; + current_external_graphics_pipeline_ = VK_NULL_HANDLE; + } + + // Update the graphics pipeline, and if the new graphics pipeline has a + // different layout, invalidate incompatible descriptor sets before updating + // current_guest_graphics_pipeline_layout_. + auto pipeline_layout = static_cast(pipeline_layout_provider); + if (current_guest_graphics_pipeline_layout_ != pipeline_layout) { + if (current_guest_graphics_pipeline_layout_) { + // Keep descriptor set layouts for which the new pipeline layout is + // compatible with the previous one (pipeline layouts are compatible for + // set N if set layouts 0 through N are compatible). + uint32_t descriptor_sets_kept = uint32_t(SpirvShaderTranslator::kDescriptorSetCount); + if (current_guest_graphics_pipeline_layout_->descriptor_set_layout_textures_vertex_ref() != + pipeline_layout->descriptor_set_layout_textures_vertex_ref()) { + descriptor_sets_kept = std::min( + descriptor_sets_kept, uint32_t(SpirvShaderTranslator::kDescriptorSetTexturesVertex)); + } + if (current_guest_graphics_pipeline_layout_->descriptor_set_layout_textures_pixel_ref() != + pipeline_layout->descriptor_set_layout_textures_pixel_ref()) { + descriptor_sets_kept = std::min( + descriptor_sets_kept, uint32_t(SpirvShaderTranslator::kDescriptorSetTexturesPixel)); + } + } else { + // No or unknown pipeline layout previously bound - all bindings are in an + // indeterminate state. + current_graphics_descriptor_sets_bound_up_to_date_ = 0; + } + current_guest_graphics_pipeline_layout_ = pipeline_layout; + } + + bool host_render_targets_used = + render_target_cache_->GetPath() == RenderTargetCache::Path::kHostRenderTargets; + uint32_t draw_resolution_scale_x = texture_cache_->draw_resolution_scale_x(); + uint32_t draw_resolution_scale_y = texture_cache_->draw_resolution_scale_y(); + + // Get dynamic rasterizer state. + draw_util::ViewportInfo viewport_info; + // Just handling maxViewportDimensions is enough - viewportBoundsRange[1] must + // be at least 2 * max(maxViewportDimensions[0...1]) - 1, and + // maxViewportDimensions must be greater than or equal to the size of the + // largest possible framebuffer attachment (if the viewport has positive + // offset and is between maxViewportDimensions and viewportBoundsRange[1], + // GetHostViewportInfo will adjust ndc_scale/ndc_offset to clamp it, and the + // clamped range will be outside the largest possible framebuffer anyway. + // FIXME(Triang3l): Possibly handle maxViewportDimensions and + // viewportBoundsRange separately because when using fragment shader + // interlocks, framebuffers are not used, while the range may be wider than + // dimensions? Though viewport bigger than 4096 - the smallest possible + // maximum dimension (which is below the 8192 texture size limit on the Xbox + // 360) - and with offset, is probably a situation that never happens in real + // life. Or even disregard the viewport bounds range in the fragment shader + // interlocks case completely - apply the viewport and the scissor offset + // directly to pixel address and to things like ps_param_gen. + draw_util::GetHostViewportInfo( + regs, draw_resolution_scale_x, draw_resolution_scale_y, false, + device_properties.maxViewportDimensions[0], device_properties.maxViewportDimensions[1], true, + normalized_depth_control, + host_render_targets_used && render_target_cache_->depth_float24_convert_in_pixel_shader(), + host_render_targets_used, pixel_shader && pixel_shader->writes_depth(), viewport_info); + + // Update dynamic graphics pipeline state. + UpdateDynamicState(viewport_info, primitive_polygonal, normalized_depth_control); + + auto vgt_draw_initiator = regs.Get(); + + // Whether to load the guest 32-bit (usually big-endian) vertex index + // indirectly in the vertex shader if full 32-bit indices are not supported by + // the host. + bool shader_32bit_index_dma = + !device_properties.fullDrawIndexUint32 && + primitive_processing_result.index_buffer_type == + PrimitiveProcessor::ProcessedIndexBufferType::kGuestDMA && + vgt_draw_initiator.index_size == xenos::IndexFormat::kInt32 && + primitive_processing_result.host_vertex_shader_type == Shader::HostVertexShaderType::kVertex; + if (!device_properties.fullDrawIndexUint32 && + primitive_processing_result.index_buffer_type == + PrimitiveProcessor::ProcessedIndexBufferType::kGuestDMA && + vgt_draw_initiator.index_size == xenos::IndexFormat::kInt32 && + primitive_processing_result.host_vertex_shader_type != + Shader::HostVertexShaderType::kVertex) { + // PrimitiveProcessor is expected to pre-convert this case to + // ProcessedIndexBufferType::kHostConverted with host-endian 24-bit + // indices. Keep drawing, but report if that pre-conversion didn't happen. + static bool non_vertex_32bit_guest_dma_no_full_uint32_logged = false; + if (!non_vertex_32bit_guest_dma_no_full_uint32_logged) { + REXGPU_WARN( + "Vulkan draw has host vertex shader type {} with guest DMA 32-bit " + "indices on a device without fullDrawIndexUint32; expected " + "PrimitiveProcessor to return host-converted indices", + uint32_t(primitive_processing_result.host_vertex_shader_type)); + non_vertex_32bit_guest_dma_no_full_uint32_logged = true; + } + } + + // Update system constants before uploading them. + UpdateSystemConstantValues(primitive_polygonal, primitive_processing_result, + shader_32bit_index_dma, 0, viewport_info, used_texture_mask, + normalized_depth_control, normalized_color_mask); + + // Update uniform buffers and descriptor sets after binding the pipeline with + // the new layout. + if (!UpdateBindings(vertex_shader, pixel_shader)) { + return draw_fail("update_bindings"); + } + + // Ensure vertex buffers are resident. + const Shader::ConstantRegisterMap& constant_map_vertex = vertex_shader->constant_register_map(); + for (uint32_t i = 0; i < rex::countof(constant_map_vertex.vertex_fetch_bitmap); ++i) { + uint32_t vfetch_bits_remaining = constant_map_vertex.vertex_fetch_bitmap[i]; + uint32_t j; + while (rex::bit_scan_forward(vfetch_bits_remaining, &j)) { + vfetch_bits_remaining &= ~(uint32_t(1) << j); + uint32_t vfetch_index = i * 32 + j; + uint64_t vfetch_bit = uint64_t(1) << (vfetch_index & 63); + if (vertex_buffers_in_sync_[vfetch_index >> 6] & vfetch_bit) { + continue; + } + xenos::xe_gpu_vertex_fetch_t vfetch_constant = regs.GetVertexFetch(vfetch_index); + switch (vfetch_constant.type) { + case xenos::FetchConstantType::kVertex: + break; + case xenos::FetchConstantType::kInvalidVertex: + if (REXCVAR_GET(gpu_allow_invalid_fetch_constants)) { + break; + } + REXGPU_WARN( + "Vertex fetch constant {} ({:08X} {:08X}) has \"invalid\" type! " + "This " + "is incorrect behavior, but you can try bypassing this by " + "launching Xenia with --gpu_allow_invalid_fetch_constants=true.", + vfetch_index, vfetch_constant.dword_0, vfetch_constant.dword_1); + return false; + default: + REXGPU_WARN("Vertex fetch constant {} ({:08X} {:08X}) is completely invalid!", + vfetch_index, vfetch_constant.dword_0, vfetch_constant.dword_1); + return false; + } + VertexBufferState& state = vertex_buffer_states_[vfetch_index]; + if (state.address == vfetch_constant.address && state.size == vfetch_constant.size) { + vertex_buffers_in_sync_[vfetch_index >> 6] |= vfetch_bit; + continue; + } + if (!shared_memory_->RequestRange(vfetch_constant.address << 2, vfetch_constant.size << 2)) { + REXGPU_ERROR( + "Failed to request vertex buffer at 0x{:08X} (size {}) in the shared " + "memory", + vfetch_constant.address << 2, vfetch_constant.size << 2); + return false; + } + state.address = vfetch_constant.address; + state.size = vfetch_constant.size; + vertex_buffers_in_sync_[vfetch_index >> 6] |= vfetch_bit; + } + } + + // Synchronize the memory pages backing memory scatter export streams, and + // calculate the range that includes the streams for the buffer barrier. + uint32_t memexport_extent_start = UINT32_MAX, memexport_extent_end = 0; + for (const draw_util::MemExportRange& memexport_range : memexport_ranges_) { + uint32_t memexport_range_base_bytes = memexport_range.base_address_dwords << 2; + if (!shared_memory_->RequestRange(memexport_range_base_bytes, memexport_range.size_bytes)) { + REXGPU_ERROR( + "Failed to request memexport stream at 0x{:08X} (size {}) in the " + "shared memory", + memexport_range_base_bytes, memexport_range.size_bytes); + return false; + } + memexport_extent_start = std::min(memexport_extent_start, memexport_range_base_bytes); + memexport_extent_end = + std::max(memexport_extent_end, memexport_range_base_bytes + memexport_range.size_bytes); + } + if (memexport_writes_possible && memexport_ranges_.empty()) { + if (!shared_memory_->RequestRange(0, SharedMemory::kBufferSize)) { + REXGPU_ERROR( + "Failed to request full shared memory residency for unresolved " + "memexport destinations"); + return false; + } + } + + ScratchBufferAcquisition guest_dma_index_scratch_buffer; + if (primitive_processing_result.index_buffer_type == + PrimitiveProcessor::ProcessedIndexBufferType::kGuestDMA && + !shader_32bit_index_dma && memexport_writes_possible) { + // Align with D3D12 behavior where memexporting draws using guest DMA indices + // read a snapshot of indices to avoid read/write aliasing through shared + // memory. + VkDeviceSize guest_dma_index_size = + VkDeviceSize(primitive_processing_result.host_draw_vertex_count) * + (primitive_processing_result.host_index_format == xenos::IndexFormat::kInt16 + ? sizeof(uint16_t) + : sizeof(uint32_t)); + if (guest_dma_index_size) { + guest_dma_index_scratch_buffer = AcquireScratchGpuBuffer( + guest_dma_index_size, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT); + if (guest_dma_index_scratch_buffer.buffer() == VK_NULL_HANDLE) { + return draw_fail("guest_dma_index_scratch_buffer"); + } + + shared_memory_->Use(VulkanSharedMemory::Usage::kRead); + SubmitBarriers(true); + + VkBufferCopy guest_dma_index_copy_region = {}; + guest_dma_index_copy_region.srcOffset = primitive_processing_result.guest_index_base; + guest_dma_index_copy_region.dstOffset = 0; + guest_dma_index_copy_region.size = guest_dma_index_size; + deferred_command_buffer_.CmdVkCopyBuffer(shared_memory_->buffer(), + guest_dma_index_scratch_buffer.buffer(), 1, + &guest_dma_index_copy_region); + PushBufferMemoryBarrier( + guest_dma_index_scratch_buffer.buffer(), 0, guest_dma_index_size, + guest_dma_index_scratch_buffer.GetStageMask(), VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, + guest_dma_index_scratch_buffer.GetAccessMask(), VK_ACCESS_INDEX_READ_BIT); + guest_dma_index_scratch_buffer.SetStageMask(VK_PIPELINE_STAGE_VERTEX_INPUT_BIT); + guest_dma_index_scratch_buffer.SetAccessMask(VK_ACCESS_INDEX_READ_BIT); + } + } + + // Insert the shared memory barrier if needed. + // TODO(Triang3l): Find some PM4 command that can be used for indication of + // when memexports should be awaited instead of inserting the barrier in Use + // every time if memory export was done in the previous draw? + if (memexport_extent_start < memexport_extent_end) { + shared_memory_->Use( + VulkanSharedMemory::Usage::kGuestDrawReadWrite, + std::make_pair(memexport_extent_start, memexport_extent_end - memexport_extent_start)); + } else if (memexport_writes_possible) { + // Stream constants can be invalid or dynamic, making the exact destination + // unknown. Keep synchronization conservative similarly to D3D12 UAV + // handling for memexport-capable draws. + shared_memory_->Use(VulkanSharedMemory::Usage::kGuestDrawReadWrite, + std::make_pair(0u, SharedMemory::kBufferSize)); + } else { + shared_memory_->Use(VulkanSharedMemory::Usage::kRead); + } + + // After all commands that may dispatch, copy or insert barriers, submit + // the barriers (may end the render pass), and (re)enter the render pass + // before drawing. + SubmitBarriersAndEnterRenderTargetCacheRenderPass( + render_target_cache_->last_update_render_pass(), + render_target_cache_->last_update_framebuffer()); + + // Draw. + if (primitive_processing_result.index_buffer_type == + PrimitiveProcessor::ProcessedIndexBufferType::kNone || + shader_32bit_index_dma) { + deferred_command_buffer_.CmdVkDraw(primitive_processing_result.host_draw_vertex_count, 1, 0, 0); + } else { + std::pair index_buffer; + switch (primitive_processing_result.index_buffer_type) { + case PrimitiveProcessor::ProcessedIndexBufferType::kGuestDMA: + if (guest_dma_index_scratch_buffer.buffer() != VK_NULL_HANDLE) { + index_buffer.first = guest_dma_index_scratch_buffer.buffer(); + index_buffer.second = 0; + } else { + index_buffer.first = shared_memory_->buffer(); + index_buffer.second = primitive_processing_result.guest_index_base; + } + break; + case PrimitiveProcessor::ProcessedIndexBufferType::kHostConverted: + index_buffer = primitive_processor_->GetConvertedIndexBuffer( + primitive_processing_result.host_index_buffer_handle); + break; + case PrimitiveProcessor::ProcessedIndexBufferType::kHostBuiltinForAuto: + case PrimitiveProcessor::ProcessedIndexBufferType::kHostBuiltinForDMA: + index_buffer = primitive_processor_->GetBuiltinIndexBuffer( + primitive_processing_result.host_index_buffer_handle); + break; + default: + assert_unhandled_case(primitive_processing_result.index_buffer_type); + return draw_fail("unexpected_index_buffer_type"); + } + deferred_command_buffer_.CmdVkBindIndexBuffer( + index_buffer.first, index_buffer.second, + primitive_processing_result.host_index_format == xenos::IndexFormat::kInt16 + ? VK_INDEX_TYPE_UINT16 + : VK_INDEX_TYPE_UINT32); + deferred_command_buffer_.CmdVkDrawIndexed(primitive_processing_result.host_draw_vertex_count, 1, + 0, 0, 0); + } + + // Invalidate textures in memexported memory and watch for changes. + if (!memexport_ranges_.empty()) { + for (const draw_util::MemExportRange& memexport_range : memexport_ranges_) { + shared_memory_->RangeWrittenByGpu(memexport_range.base_address_dwords << 2, + memexport_range.size_bytes); + } + } else if (memexport_writes_possible) { + // Stream constants can be invalid or dynamic, so exact destinations may be + // unknown. Keep invalidation conservative in this case. + shared_memory_->RangeWrittenByGpu(0, SharedMemory::kBufferSize); + } + + if (IsReadbackMemexportEnabled(REXCVAR_GET(vulkan_readback_memexport)) && + !memexport_ranges_.empty()) { + uint32_t memexport_total_size = 0; + for (const draw_util::MemExportRange& memexport_range : memexport_ranges_) { + memexport_total_size += memexport_range.size_bytes; + } + if (memexport_total_size) { + if (REXCVAR_GET(readback_memexport_fast)) { + IssueDraw_MemexportReadbackFastPath(memexport_total_size); + } else { + IssueDraw_MemexportReadbackFullPath(memexport_total_size); + } + } + } + + return true; +} + +bool VulkanCommandProcessor::IssueDraw_MemexportReadbackFullPath(uint32_t total_size) { + if (!total_size || memexport_ranges_.empty()) { + return true; + } + + const ui::vulkan::VulkanDevice* const vulkan_device = GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + VkBuffer readback_buffer = VK_NULL_HANDLE; + VkDeviceMemory readback_memory = VK_NULL_HANDLE; + uint32_t readback_memory_type = UINT32_MAX; + VkDeviceSize readback_memory_size = 0; + if (!ui::vulkan::util::CreateDedicatedAllocationBuffer( + vulkan_device, total_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, + ui::vulkan::util::MemoryPurpose::kReadback, readback_buffer, readback_memory, + &readback_memory_type, &readback_memory_size)) { + REXGPU_ERROR("Failed to create a Vulkan memexport readback buffer"); + return true; + } + + shared_memory_->Use(VulkanSharedMemory::Usage::kRead); + SubmitBarriers(true); + + uint32_t readback_offset = 0; + for (const draw_util::MemExportRange& memexport_range : memexport_ranges_) { + VkBufferCopy readback_region = {}; + readback_region.srcOffset = memexport_range.base_address_dwords << 2; + readback_region.dstOffset = readback_offset; + readback_region.size = memexport_range.size_bytes; + deferred_command_buffer_.CmdVkCopyBuffer(shared_memory_->buffer(), readback_buffer, 1, + &readback_region); + readback_offset += memexport_range.size_bytes; + } + PushBufferMemoryBarrier(readback_buffer, 0, total_size, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_HOST_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_HOST_READ_BIT); + + if (!AwaitAllQueueOperationsCompletion()) { + REXGPU_ERROR("Failed to await completion of Vulkan memexport readback"); + dfn.vkDestroyBuffer(device, readback_buffer, nullptr); + dfn.vkFreeMemory(device, readback_memory, nullptr); + return true; + } + + void* readback_mapping = nullptr; + if (dfn.vkMapMemory(device, readback_memory, 0, VK_WHOLE_SIZE, 0, &readback_mapping) != + VK_SUCCESS) { + REXGPU_ERROR("Failed to map a Vulkan memexport readback buffer"); + dfn.vkDestroyBuffer(device, readback_buffer, nullptr); + dfn.vkFreeMemory(device, readback_memory, nullptr); + return true; + } + + if (!(vulkan_device->memory_types().host_coherent & (uint32_t(1) << readback_memory_type))) { + VkMappedMemoryRange readback_memory_range = {}; + readback_memory_range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + readback_memory_range.memory = readback_memory; + readback_memory_range.offset = 0; + readback_memory_range.size = std::min( + rex::round_up(VkDeviceSize(total_size), vulkan_device->properties().nonCoherentAtomSize), + readback_memory_size); + dfn.vkInvalidateMappedMemoryRanges(device, 1, &readback_memory_range); + } + + const uint8_t* readback_bytes = reinterpret_cast(readback_mapping); + for (const draw_util::MemExportRange& memexport_range : memexport_ranges_) { + std::memcpy(memory_->TranslatePhysical(memexport_range.base_address_dwords << 2), + readback_bytes, memexport_range.size_bytes); + readback_bytes += memexport_range.size_bytes; + } + dfn.vkUnmapMemory(device, readback_memory); + dfn.vkDestroyBuffer(device, readback_buffer, nullptr); + dfn.vkFreeMemory(device, readback_memory, nullptr); + return true; +} + +bool VulkanCommandProcessor::IssueDraw_MemexportReadbackFastPath(uint32_t total_size) { + if (!total_size || memexport_ranges_.empty()) { + return true; + } + + const ui::vulkan::VulkanDevice* const vulkan_device = GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + const uint64_t readback_key = + MakeMemexportReadbackKey(memexport_ranges_.front().base_address_dwords, total_size); + ReadbackBuffer& readback = memexport_readback_buffers_[readback_key]; + readback.last_used_frame = frame_current_; + + auto ensure_readback_slot = [&](uint32_t index, uint32_t size) -> bool { + if (readback.buffers[index] != VK_NULL_HANDLE && readback.memories[index] != VK_NULL_HANDLE && + readback.mapped_data[index] != nullptr && size <= readback.sizes[index]) { + return true; + } + + VkBuffer new_buffer = VK_NULL_HANDLE; + VkDeviceMemory new_memory = VK_NULL_HANDLE; + if (!ui::vulkan::util::CreateDedicatedAllocationBuffer( + vulkan_device, size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, + ui::vulkan::util::MemoryPurpose::kReadback, new_buffer, new_memory)) { + return false; + } + + void* new_mapping = nullptr; + if (dfn.vkMapMemory(device, new_memory, 0, VK_WHOLE_SIZE, 0, &new_mapping) != VK_SUCCESS) { + dfn.vkDestroyBuffer(device, new_buffer, nullptr); + dfn.vkFreeMemory(device, new_memory, nullptr); + return false; + } + + if (readback.buffers[index] != VK_NULL_HANDLE || readback.memories[index] != VK_NULL_HANDLE) { + if (!AwaitAllQueueOperationsCompletion()) { + dfn.vkUnmapMemory(device, new_memory); + dfn.vkDestroyBuffer(device, new_buffer, nullptr); + dfn.vkFreeMemory(device, new_memory, nullptr); + return false; + } + if (readback.mapped_data[index] != nullptr && readback.memories[index] != VK_NULL_HANDLE) { + dfn.vkUnmapMemory(device, readback.memories[index]); + } + if (readback.buffers[index] != VK_NULL_HANDLE) { + dfn.vkDestroyBuffer(device, readback.buffers[index], nullptr); + } + if (readback.memories[index] != VK_NULL_HANDLE) { + dfn.vkFreeMemory(device, readback.memories[index], nullptr); + } + } + + readback.buffers[index] = new_buffer; + readback.memories[index] = new_memory; + readback.mapped_data[index] = new_mapping; + readback.sizes[index] = size; + readback.submission_written[index] = 0; + readback.written_size[index] = 0; + return true; + }; + + const uint32_t write_index = readback.current_index; + const uint32_t read_index = 1 - write_index; + const uint32_t readback_size = AlignReadbackBufferSize(total_size); + if (!ensure_readback_slot(write_index, readback_size)) { + return IssueDraw_MemexportReadbackFullPath(total_size); + } + + shared_memory_->Use(VulkanSharedMemory::Usage::kRead); + SubmitBarriers(true); + + uint32_t readback_offset = 0; + for (const draw_util::MemExportRange& memexport_range : memexport_ranges_) { + VkBufferCopy readback_region = {}; + readback_region.srcOffset = memexport_range.base_address_dwords << 2; + readback_region.dstOffset = readback_offset; + readback_region.size = memexport_range.size_bytes; + deferred_command_buffer_.CmdVkCopyBuffer(shared_memory_->buffer(), + readback.buffers[write_index], 1, &readback_region); + readback_offset += memexport_range.size_bytes; + } + PushBufferMemoryBarrier(readback.buffers[write_index], 0, total_size, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT); + readback.submission_written[write_index] = GetCurrentSubmission(); + readback.written_size[write_index] = total_size; + + CheckSubmissionFenceAndDeviceLoss(0); + bool previous_slot_ready = + readback.buffers[read_index] != VK_NULL_HANDLE && + readback.memories[read_index] != VK_NULL_HANDLE && + readback.mapped_data[read_index] != nullptr && total_size <= readback.sizes[read_index] && + total_size <= readback.written_size[read_index] && readback.submission_written[read_index] && + readback.submission_written[read_index] <= submission_completed_; + if (!previous_slot_ready) { + IssueDraw_MemexportReadbackFullPath(total_size); + readback.current_index = read_index; + return true; + } + + VkMappedMemoryRange readback_memory_range = {}; + readback_memory_range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + readback_memory_range.memory = readback.memories[read_index]; + readback_memory_range.offset = 0; + readback_memory_range.size = VK_WHOLE_SIZE; + dfn.vkInvalidateMappedMemoryRanges(device, 1, &readback_memory_range); + + const uint8_t* readback_bytes = + reinterpret_cast(readback.mapped_data[read_index]); + for (const draw_util::MemExportRange& memexport_range : memexport_ranges_) { + std::memcpy(memory_->TranslatePhysical(memexport_range.base_address_dwords << 2), + readback_bytes, memexport_range.size_bytes); + readback_bytes += memexport_range.size_bytes; + } + + readback.current_index = read_index; + return true; +} + +bool VulkanCommandProcessor::IssueCopy() { +#if XE_GPU_FINE_GRAINED_DRAW_SCOPES + SCOPE_profile_cpu_f("gpu"); +#endif // XE_GPU_FINE_GRAINED_DRAW_SCOPES + + if (!BeginSubmission(true)) { + return false; + } + + ReadbackResolveMode readback_mode = GetReadbackResolveMode(REXCVAR_GET(vulkan_readback_resolve)); + if (readback_mode == ReadbackResolveMode::kDisabled) { + uint32_t written_address, written_length; + return render_target_cache_->Resolve(*memory_, *shared_memory_, *texture_cache_, + written_address, written_length); + } + + return IssueCopy_ReadbackResolvePath(); +} + +bool VulkanCommandProcessor::IssueCopy_ReadbackResolvePath() { + const ui::vulkan::VulkanDevice* const vulkan_device = GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + uint32_t written_address, written_length; + if (!render_target_cache_->Resolve(*memory_, *shared_memory_, *texture_cache_, written_address, + written_length)) { + return false; + } + + if (!written_length) { + return true; + } + + if (!memory_->TranslatePhysical(written_address)) { + return true; + } + + ReadbackResolveMode readback_mode = GetReadbackResolveMode(REXCVAR_GET(vulkan_readback_resolve)); + if (readback_mode == ReadbackResolveMode::kDisabled) { + return true; + } + + auto ensure_readback_slot = [&](ReadbackBuffer& readback, uint32_t index, uint32_t size) -> bool { + if (readback.buffers[index] != VK_NULL_HANDLE && size <= readback.sizes[index] && + readback.mapped_data[index] != nullptr) { + return true; + } + + VkBuffer new_buffer = VK_NULL_HANDLE; + VkDeviceMemory new_memory = VK_NULL_HANDLE; + if (!ui::vulkan::util::CreateDedicatedAllocationBuffer( + vulkan_device, size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, + ui::vulkan::util::MemoryPurpose::kReadback, new_buffer, new_memory)) { + REXGPU_ERROR("Failed to create a {} MB Vulkan resolve readback buffer", size >> 20); + return false; + } + + void* new_mapping = nullptr; + if (dfn.vkMapMemory(device, new_memory, 0, VK_WHOLE_SIZE, 0, &new_mapping) != VK_SUCCESS) { + REXGPU_ERROR("Failed to map a Vulkan resolve readback buffer"); + dfn.vkDestroyBuffer(device, new_buffer, nullptr); + dfn.vkFreeMemory(device, new_memory, nullptr); + return false; + } + + if (readback.buffers[index] != VK_NULL_HANDLE || readback.memories[index] != VK_NULL_HANDLE) { + if (!AwaitAllQueueOperationsCompletion()) { + dfn.vkUnmapMemory(device, new_memory); + dfn.vkDestroyBuffer(device, new_buffer, nullptr); + dfn.vkFreeMemory(device, new_memory, nullptr); + return false; + } + if (readback.mapped_data[index] != nullptr && readback.memories[index] != VK_NULL_HANDLE) { + dfn.vkUnmapMemory(device, readback.memories[index]); + } + if (readback.buffers[index] != VK_NULL_HANDLE) { + dfn.vkDestroyBuffer(device, readback.buffers[index], nullptr); + } + if (readback.memories[index] != VK_NULL_HANDLE) { + dfn.vkFreeMemory(device, readback.memories[index], nullptr); + } + } + + readback.buffers[index] = new_buffer; + readback.memories[index] = new_memory; + readback.mapped_data[index] = new_mapping; + readback.sizes[index] = size; + return true; + }; + + bool is_scaled = texture_cache_->IsDrawResolutionScaled(); + uint64_t resolve_key = MakeReadbackResolveKey(written_address, written_length); + ReadbackBuffer& readback = readback_buffers_[resolve_key]; + readback.last_used_frame = frame_current_; + uint32_t write_index = readback.current_index; + uint32_t readback_size = AlignReadbackBufferSize(written_length); + if (!ensure_readback_slot(readback, write_index, readback_size)) { + return true; + } + + if (is_scaled) { + if (!resolve_downscale_pipeline_ || !resolve_downscale_pipeline_layout_) { + return true; + } + + reg::RB_COPY_DEST_INFO copy_dest_info = register_file_->Get(); + const FormatInfo* format_info = FormatInfo::Get(uint32_t(copy_dest_info.copy_dest_format)); + uint32_t bits_per_pixel = format_info->bits_per_pixel; + if (bits_per_pixel != 8 && bits_per_pixel != 16 && bits_per_pixel != 32 && + bits_per_pixel != 64) { + return true; + } + + uint32_t pixel_size_log2; + if (!rex::bit_scan_forward(bits_per_pixel >> 3, &pixel_size_log2)) { + return true; + } + uint32_t tile_size_1x = 32 * 32 * (uint32_t(1) << pixel_size_log2); + uint32_t tile_count = written_length / tile_size_1x; + if (!tile_count) { + return true; + } + + uint64_t scaled_start = 0, scaled_length = 0; + if (!texture_cache_->GetScaledResolveRange(written_address, written_length, 0, scaled_start, + scaled_length)) { + return true; + } + if (!scaled_length) { + return true; + } + + VkBuffer scaled_resolve_buffer = texture_cache_->scaled_resolve_buffer(); + if (scaled_resolve_buffer == VK_NULL_HANDLE || scaled_start > uint64_t(UINT32_MAX)) { + return true; + } + + uint32_t downscale_buffer_size = AlignReadbackBufferSize(written_length); + if (downscale_buffer_size > resolve_downscale_buffer_size_) { + VkBuffer new_buffer = VK_NULL_HANDLE; + VkDeviceMemory new_memory = VK_NULL_HANDLE; + if (!ui::vulkan::util::CreateDedicatedAllocationBuffer( + vulkan_device, downscale_buffer_size, + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + ui::vulkan::util::MemoryPurpose::kDeviceLocal, new_buffer, new_memory)) { + REXGPU_ERROR("Failed to create a {} MB Vulkan resolve downscale buffer", + downscale_buffer_size >> 20); + return true; + } + if (resolve_downscale_buffer_ != VK_NULL_HANDLE || + resolve_downscale_buffer_memory_ != VK_NULL_HANDLE) { + if (!AwaitAllQueueOperationsCompletion()) { + dfn.vkDestroyBuffer(device, new_buffer, nullptr); + dfn.vkFreeMemory(device, new_memory, nullptr); + return true; + } + if (resolve_downscale_buffer_ != VK_NULL_HANDLE) { + dfn.vkDestroyBuffer(device, resolve_downscale_buffer_, nullptr); + } + if (resolve_downscale_buffer_memory_ != VK_NULL_HANDLE) { + dfn.vkFreeMemory(device, resolve_downscale_buffer_memory_, nullptr); + } + } + resolve_downscale_buffer_ = new_buffer; + resolve_downscale_buffer_memory_ = new_memory; + resolve_downscale_buffer_size_ = downscale_buffer_size; + } + if (resolve_downscale_buffer_ == VK_NULL_HANDLE) { + return true; + } + + VkDescriptorSet descriptor_set = AllocateSingleTransientDescriptor( + SingleTransientDescriptorLayout::kStorageBufferPairCompute); + if (descriptor_set == VK_NULL_HANDLE) { + return true; + } + + VkDescriptorBufferInfo buffer_infos[2] = {}; + buffer_infos[0].buffer = scaled_resolve_buffer; + buffer_infos[0].offset = 0; + buffer_infos[0].range = VK_WHOLE_SIZE; + buffer_infos[1].buffer = resolve_downscale_buffer_; + buffer_infos[1].offset = 0; + buffer_infos[1].range = written_length; + + VkWriteDescriptorSet descriptor_writes[2] = {}; + for (uint32_t i = 0; i < 2; ++i) { + descriptor_writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptor_writes[i].dstSet = descriptor_set; + descriptor_writes[i].dstBinding = i; + descriptor_writes[i].descriptorCount = 1; + descriptor_writes[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + descriptor_writes[i].pBufferInfo = &buffer_infos[i]; + } + dfn.vkUpdateDescriptorSets(device, 2, descriptor_writes, 0, nullptr); + + texture_cache_->UseScaledResolveBufferForRead(); + SubmitBarriers(true); + + VkBufferMemoryBarrier pre_barrier = {}; + pre_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; + pre_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + pre_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + pre_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + pre_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + pre_barrier.buffer = resolve_downscale_buffer_; + pre_barrier.offset = 0; + pre_barrier.size = written_length; + deferred_command_buffer_.CmdVkPipelineBarrier( + VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 1, &pre_barrier, 0, nullptr); + + BindExternalComputePipeline(resolve_downscale_pipeline_); + + ResolveDownscaleConstants constants; + constants.scale_x = texture_cache_->draw_resolution_scale_x(); + constants.scale_y = texture_cache_->draw_resolution_scale_y(); + constants.pixel_size_log2 = pixel_size_log2; + constants.tile_count = tile_count; + constants.source_offset_bytes = uint32_t(scaled_start); + constants.half_pixel_offset = (REXCVAR_GET(readback_resolve_half_pixel_offset) && + (constants.scale_x > 1 || constants.scale_y > 1)) + ? 1u + : 0u; + deferred_command_buffer_.CmdVkPushConstants(resolve_downscale_pipeline_layout_, + VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(constants), + &constants); + deferred_command_buffer_.CmdVkBindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, + resolve_downscale_pipeline_layout_, 0, 1, + &descriptor_set, 0, nullptr); + deferred_command_buffer_.CmdVkDispatch(tile_count, 1, 1); + + VkBufferMemoryBarrier downscale_barrier = {}; + downscale_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; + downscale_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + downscale_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + downscale_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + downscale_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + downscale_barrier.buffer = resolve_downscale_buffer_; + downscale_barrier.offset = 0; + downscale_barrier.size = written_length; + deferred_command_buffer_.CmdVkPipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, + &downscale_barrier, 0, nullptr); + + VkBufferCopy readback_region = {}; + readback_region.srcOffset = 0; + readback_region.dstOffset = 0; + readback_region.size = written_length; + deferred_command_buffer_.CmdVkCopyBuffer(resolve_downscale_buffer_, + readback.buffers[write_index], 1, &readback_region); + } else { + shared_memory_->Use(VulkanSharedMemory::Usage::kRead); + SubmitBarriers(true); + + VkBufferCopy readback_region = {}; + readback_region.srcOffset = written_address; + readback_region.dstOffset = 0; + readback_region.size = written_length; + deferred_command_buffer_.CmdVkCopyBuffer(shared_memory_->buffer(), + readback.buffers[write_index], 1, &readback_region); + } + + PushBufferMemoryBarrier(readback.buffers[write_index], 0, written_length, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT); + + bool use_delayed_sync = + readback_mode == ReadbackResolveMode::kFast || readback_mode == ReadbackResolveMode::kSome; + uint32_t read_index = write_index; + if (use_delayed_sync) { + read_index = 1 - write_index; + } else if (!AwaitAllQueueOperationsCompletion()) { + return true; + } + + bool is_cache_miss = false; + if (use_delayed_sync && (readback.buffers[read_index] == VK_NULL_HANDLE || + written_length > readback.sizes[read_index] || + readback.mapped_data[read_index] == nullptr)) { + is_cache_miss = true; + read_index = write_index; + if (!AwaitAllQueueOperationsCompletion()) { + return true; + } + } + + bool should_copy = (readback_mode == ReadbackResolveMode::kSome) ? is_cache_miss : true; + if (should_copy && readback.buffers[read_index] != VK_NULL_HANDLE && + written_length <= readback.sizes[read_index] && readback.mapped_data[read_index] != nullptr) { + VkMappedMemoryRange readback_memory_range = {}; + readback_memory_range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + readback_memory_range.memory = readback.memories[read_index]; + readback_memory_range.offset = 0; + readback_memory_range.size = VK_WHOLE_SIZE; + dfn.vkInvalidateMappedMemoryRanges(device, 1, &readback_memory_range); + + uint8_t* destination = memory_->TranslatePhysical(written_address); + if (destination) { + std::memcpy(destination, readback.mapped_data[read_index], written_length); + } + } + + readback.current_index = 1 - readback.current_index; + return true; +} + +void VulkanCommandProcessor::EvictOldReadbackBuffers( + std::unordered_map& buffer_map) { + if (buffer_map.empty()) { + return; + } + + const uint64_t eviction_frame_floor = (frame_current_ > kReadbackBufferEvictionAgeFrames) + ? (frame_current_ - kReadbackBufferEvictionAgeFrames) + : 0; + const ui::vulkan::VulkanDevice* const vulkan_device = GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + for (auto it = buffer_map.begin(); it != buffer_map.end();) { + ReadbackBuffer& readback = it->second; + bool evict = + buffer_map.size() > kMaxReadbackBuffers || readback.last_used_frame < eviction_frame_floor; + if (!evict) { + ++it; + continue; + } + for (uint32_t i = 0; i < 2; ++i) { + if (readback.mapped_data[i] && readback.memories[i] != VK_NULL_HANDLE) { + dfn.vkUnmapMemory(device, readback.memories[i]); + } + if (readback.buffers[i] != VK_NULL_HANDLE) { + dfn.vkDestroyBuffer(device, readback.buffers[i], nullptr); + } + if (readback.memories[i] != VK_NULL_HANDLE) { + dfn.vkFreeMemory(device, readback.memories[i], nullptr); + } + readback.buffers[i] = VK_NULL_HANDLE; + readback.memories[i] = VK_NULL_HANDLE; + readback.mapped_data[i] = nullptr; + readback.sizes[i] = 0; + readback.submission_written[i] = 0; + readback.written_size[i] = 0; + } + it = buffer_map.erase(it); + } +} + +bool VulkanCommandProcessor::InitializeOcclusionQueryResources() { + active_occlusion_query_ = {}; + occlusion_query_cursor_ = 0; + occlusion_query_resources_available_ = false; + occlusion_query_pool_ = VK_NULL_HANDLE; + occlusion_query_readback_buffer_ = VK_NULL_HANDLE; + occlusion_query_readback_memory_ = VK_NULL_HANDLE; + occlusion_query_readback_memory_type_ = UINT32_MAX; + occlusion_query_readback_memory_size_ = 0; + occlusion_query_readback_mapping_ = nullptr; + + const ui::vulkan::VulkanDevice* vulkan_device = GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + VkDevice device = vulkan_device->device(); + + VkQueryPoolCreateInfo pool_info = {}; + pool_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; + pool_info.queryType = VK_QUERY_TYPE_OCCLUSION; + pool_info.queryCount = kMaxOcclusionQueries; + if (dfn.vkCreateQueryPool(device, &pool_info, nullptr, &occlusion_query_pool_) != VK_SUCCESS) { + REXGPU_WARN( + "VulkanCommandProcessor: Failed to create occlusion query pool, using fake sample counts"); + return false; + } + + if (!ui::vulkan::util::CreateDedicatedAllocationBuffer( + vulkan_device, sizeof(uint64_t) * kMaxOcclusionQueries, VK_BUFFER_USAGE_TRANSFER_DST_BIT, + ui::vulkan::util::MemoryPurpose::kReadback, occlusion_query_readback_buffer_, + occlusion_query_readback_memory_, &occlusion_query_readback_memory_type_, + &occlusion_query_readback_memory_size_)) { + REXGPU_WARN( + "VulkanCommandProcessor: Failed to create occlusion query readback buffer, using fake " + "sample counts"); + ShutdownOcclusionQueryResources(); + return false; + } + + if (dfn.vkMapMemory(device, occlusion_query_readback_memory_, 0, VK_WHOLE_SIZE, 0, + reinterpret_cast(&occlusion_query_readback_mapping_)) != VK_SUCCESS) { + REXGPU_WARN( + "VulkanCommandProcessor: Failed to map occlusion query readback buffer, using fake sample " + "counts"); + ShutdownOcclusionQueryResources(); + return false; + } + + occlusion_query_resources_available_ = true; + return true; +} + +void VulkanCommandProcessor::ShutdownOcclusionQueryResources() { + DisableHostOcclusionQueries(); + + const ui::vulkan::VulkanDevice* vulkan_device = GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + VkDevice device = vulkan_device->device(); + + if (occlusion_query_readback_mapping_ && occlusion_query_readback_memory_ != VK_NULL_HANDLE) { + dfn.vkUnmapMemory(device, occlusion_query_readback_memory_); + } + occlusion_query_readback_mapping_ = nullptr; + if (occlusion_query_readback_buffer_ != VK_NULL_HANDLE) { + dfn.vkDestroyBuffer(device, occlusion_query_readback_buffer_, nullptr); + } + if (occlusion_query_readback_memory_ != VK_NULL_HANDLE) { + dfn.vkFreeMemory(device, occlusion_query_readback_memory_, nullptr); + } + if (occlusion_query_pool_ != VK_NULL_HANDLE) { + dfn.vkDestroyQueryPool(device, occlusion_query_pool_, nullptr); + } + + occlusion_query_pool_ = VK_NULL_HANDLE; + occlusion_query_readback_buffer_ = VK_NULL_HANDLE; + occlusion_query_readback_memory_ = VK_NULL_HANDLE; + occlusion_query_readback_memory_type_ = UINT32_MAX; + occlusion_query_readback_memory_size_ = 0; +} + +bool VulkanCommandProcessor::AcquireOcclusionQueryIndex(uint32_t& host_index_out) { + if (occlusion_query_cursor_ >= kMaxOcclusionQueries) { + occlusion_query_cursor_ = 0; + } + host_index_out = occlusion_query_cursor_++; + return true; +} + +void VulkanCommandProcessor::DisableHostOcclusionQueries() { + if (active_occlusion_query_.valid && occlusion_query_pool_ != VK_NULL_HANDLE) { + if (BeginSubmission(true)) { + deferred_command_buffer_.CmdVkEndQuery(occlusion_query_pool_, + active_occlusion_query_.host_index); + EndSubmission(false); + } + } + active_occlusion_query_ = {}; + occlusion_query_cursor_ = 0; + occlusion_query_resources_available_ = false; +} + +bool VulkanCommandProcessor::BeginGuestOcclusionQuery(uint32_t sample_count_address) { + if (!REXCVAR_GET(occlusion_query_enable) || !occlusion_query_resources_available_ || + occlusion_query_pool_ == VK_NULL_HANDLE || occlusion_query_readback_mapping_ == nullptr) { + return false; + } + if (active_occlusion_query_.valid) { + REXGPU_WARN( + "VulkanCommandProcessor: Occlusion query begin issued while another query is active"); + DisableHostOcclusionQueries(); + return false; + } + + uint32_t host_index = 0; + if (!AcquireOcclusionQueryIndex(host_index)) { + return false; + } + if (!BeginSubmission(true)) { + return false; + } + + EndRenderPass(); + + DeferredCommandBuffer& command_buffer = deferred_command_buffer(); + command_buffer.CmdVkResetQueryPool(occlusion_query_pool_, host_index, 1); + command_buffer.CmdVkBeginQuery(occlusion_query_pool_, host_index, 0); + active_occlusion_query_.sample_count_address = sample_count_address; + active_occlusion_query_.host_index = host_index; + active_occlusion_query_.valid = true; + return true; +} + +bool VulkanCommandProcessor::EndGuestOcclusionQuery(uint32_t sample_count_address) { + if (!REXCVAR_GET(occlusion_query_enable) || !occlusion_query_resources_available_ || + !active_occlusion_query_.valid || occlusion_query_pool_ == VK_NULL_HANDLE || + occlusion_query_readback_mapping_ == nullptr) { + return false; + } + + uint32_t host_index = active_occlusion_query_.host_index; + active_occlusion_query_ = {}; + + if (!BeginSubmission(true)) { + return false; + } + + EndRenderPass(); + + DeferredCommandBuffer& command_buffer = deferred_command_buffer(); + command_buffer.CmdVkEndQuery(occlusion_query_pool_, host_index); + command_buffer.CmdVkCopyQueryPoolResults(occlusion_query_pool_, host_index, 1, + occlusion_query_readback_buffer_, + sizeof(uint64_t) * host_index, sizeof(uint64_t), + VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT); + + if (!EndSubmission(false)) { + return false; + } + if (!AwaitAllQueueOperationsCompletion()) { + return false; + } + + const ui::vulkan::VulkanDevice* vulkan_device = GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + if (!(vulkan_device->memory_types().host_coherent & + (uint32_t(1) << occlusion_query_readback_memory_type_))) { + VkMappedMemoryRange memory_range = {}; + memory_range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + memory_range.memory = occlusion_query_readback_memory_; + memory_range.offset = 0; + memory_range.size = + std::min(rex::round_up(VkDeviceSize(sizeof(uint64_t) * kMaxOcclusionQueries), + vulkan_device->properties().nonCoherentAtomSize), + occlusion_query_readback_memory_size_); + dfn.vkInvalidateMappedMemoryRanges(device, 1, &memory_range); + } + + const uint64_t* results = reinterpret_cast(occlusion_query_readback_mapping_); + uint64_t samples = NormalizeOcclusionSamples(results[host_index]); + WriteGuestOcclusionResult(sample_count_address, samples); + return true; +} + +uint64_t VulkanCommandProcessor::NormalizeOcclusionSamples(uint64_t samples) const { + if (samples == 0 || !texture_cache_) { + return samples; + } + uint64_t scale_x = texture_cache_->draw_resolution_scale_x(); + uint64_t scale_y = texture_cache_->draw_resolution_scale_y(); + uint64_t scale = scale_x * scale_y; + if (scale <= 1) { + return samples; + } + return (samples + (scale >> 1)) / scale; +} + +void VulkanCommandProcessor::WriteGuestOcclusionResult(uint32_t sample_count_address, + uint64_t samples) { + auto* sample_counts = + memory_->TranslatePhysical(sample_count_address); + if (!sample_counts) { + return; + } + uint32_t clamped = samples > uint64_t(UINT32_MAX) ? UINT32_MAX : uint32_t(samples); + sample_counts->Total_A = clamped; + sample_counts->Total_B = 0; + sample_counts->ZPass_A = clamped; + sample_counts->ZPass_B = 0; + sample_counts->ZFail_A = 0; + sample_counts->ZFail_B = 0; + sample_counts->StencilFail_A = 0; + sample_counts->StencilFail_B = 0; +} + +void VulkanCommandProcessor::InitializeTrace() { + CommandProcessor::InitializeTrace(); + + if (!BeginSubmission(true)) { + return; + } + bool render_target_submitted = render_target_cache_->InitializeTraceSubmitDownloads(); + bool shared_memory_submitted = shared_memory_->InitializeTraceSubmitDownloads(); + if (!render_target_submitted && !shared_memory_submitted) { + return; + } + AwaitAllQueueOperationsCompletion(); + if (render_target_submitted) { + render_target_cache_->InitializeTraceCompleteDownloads(); + } + if (shared_memory_submitted) { + shared_memory_->InitializeTraceCompleteDownloads(); + } +} + +void VulkanCommandProcessor::CheckSubmissionFenceAndDeviceLoss(uint64_t await_submission) { + // Only report once, no need to retry a wait that won't succeed anyway. + if (device_lost_) { + return; + } + + if (await_submission >= GetCurrentSubmission()) { + if (submission_open_) { + EndSubmission(false); + } + // A submission won't be ended if it hasn't been started, or if ending + // has failed - clamp the index. + await_submission = GetCurrentSubmission() - 1; + } + + const ui::vulkan::VulkanDevice* const vulkan_device = GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + size_t fences_total = submissions_in_flight_fences_.size(); + size_t fences_awaited = 0; + if (await_submission > submission_completed_) { + // Await in a blocking way if requested. + // TODO(Triang3l): Await only one fence. "Fence signal operations that are + // defined by vkQueueSubmit additionally include in the first + // synchronization scope all commands that occur earlier in submission + // order." + VkResult wait_result = + dfn.vkWaitForFences(device, uint32_t(await_submission - submission_completed_), + submissions_in_flight_fences_.data(), VK_TRUE, UINT64_MAX); + if (wait_result == VK_SUCCESS) { + fences_awaited += await_submission - submission_completed_; + } else { + REXGPU_ERROR("Failed to await submission completion Vulkan fences"); + if (wait_result == VK_ERROR_DEVICE_LOST) { + device_lost_ = true; + } + } + } + // Check how far into the submissions the GPU currently is, in order because + // submission themselves can be executed out of order, but Xenia serializes + // that for simplicity. + while (fences_awaited < fences_total) { + VkResult fence_status = + dfn.vkWaitForFences(device, 1, &submissions_in_flight_fences_[fences_awaited], VK_TRUE, 0); + if (fence_status != VK_SUCCESS) { + if (fence_status == VK_ERROR_DEVICE_LOST) { + device_lost_ = true; + } + break; + } + ++fences_awaited; + } + if (device_lost_) { + if (graphics_system_) { + graphics_system_->OnHostGpuLossFromAnyThread(true); + } + return; + } + if (!fences_awaited) { + // Not updated - no need to reclaim or download things. + return; + } + // Reclaim fences. + fences_free_.reserve(fences_free_.size() + fences_awaited); + auto submissions_in_flight_fences_awaited_end = submissions_in_flight_fences_.cbegin(); + std::advance(submissions_in_flight_fences_awaited_end, fences_awaited); + fences_free_.insert(fences_free_.cend(), submissions_in_flight_fences_.cbegin(), + submissions_in_flight_fences_awaited_end); + submissions_in_flight_fences_.erase(submissions_in_flight_fences_.cbegin(), + submissions_in_flight_fences_awaited_end); + submission_completed_ += fences_awaited; + + // Reclaim semaphores. + while (!submissions_in_flight_semaphores_.empty()) { + const auto& semaphore_submission = submissions_in_flight_semaphores_.front(); + if (semaphore_submission.first > submission_completed_) { + break; + } + semaphores_free_.push_back(semaphore_submission.second); + submissions_in_flight_semaphores_.pop_front(); + } + + // Reclaim command pools. + while (!command_buffers_submitted_.empty()) { + const auto& command_buffer_pair = command_buffers_submitted_.front(); + if (command_buffer_pair.first > submission_completed_) { + break; + } + command_buffers_writable_.push_back(command_buffer_pair.second); + command_buffers_submitted_.pop_front(); + } + + shared_memory_->CompletedSubmissionUpdated(); + + primitive_processor_->CompletedSubmissionUpdated(); + + render_target_cache_->CompletedSubmissionUpdated(); + + texture_cache_->CompletedSubmissionUpdated(submission_completed_); + + // Destroy objects scheduled for destruction. + while (!destroy_framebuffers_.empty()) { + const auto& destroy_pair = destroy_framebuffers_.front(); + if (destroy_pair.first > submission_completed_) { + break; + } + dfn.vkDestroyFramebuffer(device, destroy_pair.second, nullptr); + destroy_framebuffers_.pop_front(); + } + while (!destroy_image_views_.empty()) { + const auto& destroy_pair = destroy_image_views_.front(); + if (destroy_pair.first > submission_completed_) { + break; + } + dfn.vkDestroyImageView(device, destroy_pair.second, nullptr); + destroy_image_views_.pop_front(); + } + while (!destroy_buffers_.empty()) { + const auto& destroy_pair = destroy_buffers_.front(); + if (destroy_pair.first > submission_completed_) { + break; + } + dfn.vkDestroyBuffer(device, destroy_pair.second, nullptr); + destroy_buffers_.pop_front(); + } + while (!destroy_images_.empty()) { + const auto& destroy_pair = destroy_images_.front(); + if (destroy_pair.first > submission_completed_) { + break; + } + dfn.vkDestroyImage(device, destroy_pair.second, nullptr); + destroy_images_.pop_front(); + } + while (!destroy_memory_.empty()) { + const auto& destroy_pair = destroy_memory_.front(); + if (destroy_pair.first > submission_completed_) { + break; + } + dfn.vkFreeMemory(device, destroy_pair.second, nullptr); + destroy_memory_.pop_front(); + } +} + +bool VulkanCommandProcessor::CanEndSubmissionImmediately() const { + return !submission_open_ || (!scratch_buffer_used_ && !pipeline_cache_->IsCreatingPipelines()); +} + +bool VulkanCommandProcessor::BeginSubmission(bool is_guest_command) { +#if XE_GPU_FINE_GRAINED_DRAW_SCOPES + SCOPE_profile_cpu_f("gpu"); +#endif // XE_GPU_FINE_GRAINED_DRAW_SCOPES + + if (device_lost_) { + return false; + } + + bool is_opening_frame = is_guest_command && !frame_open_; + if (submission_open_ && !is_opening_frame) { + return true; + } + + // Check the fence - needed for all kinds of submissions (to reclaim transient + // resources early) and specifically for frames (not to queue too many), and + // await the availability of the current frame. Also check whether the device + // is still available, and whether the await was successful. + uint64_t await_submission = + is_opening_frame ? closed_frame_submissions_[frame_current_ % kMaxFramesInFlight] : 0; + CheckSubmissionFenceAndDeviceLoss(await_submission); + if (device_lost_ || submission_completed_ < await_submission) { + return false; + } + + if (is_opening_frame) { + // Update the completed frame index, also obtaining the actual completed + // frame number (since the CPU may be actually less than 3 frames behind) + // before reclaiming resources tracked with the frame number. + frame_completed_ = std::max(frame_current_, uint64_t(kMaxFramesInFlight)) - kMaxFramesInFlight; + for (uint64_t frame = frame_completed_ + 1; frame < frame_current_; ++frame) { + if (closed_frame_submissions_[frame % kMaxFramesInFlight] > submission_completed_) { + break; + } + frame_completed_ = frame; + } + } + + if (!submission_open_) { + submission_open_ = true; + + // Start a new deferred command buffer - will submit it to the real one in + // the end of the submission (when async pipeline object creation requests + // are fulfilled). + deferred_command_buffer_.Reset(); + + // Reset cached state of the command buffer. + dynamic_viewport_update_needed_ = true; + dynamic_scissor_update_needed_ = true; + dynamic_depth_bias_update_needed_ = true; + dynamic_blend_constants_update_needed_ = true; + dynamic_stencil_compare_mask_front_update_needed_ = true; + dynamic_stencil_compare_mask_back_update_needed_ = true; + dynamic_stencil_write_mask_front_update_needed_ = true; + dynamic_stencil_write_mask_back_update_needed_ = true; + dynamic_stencil_reference_front_update_needed_ = true; + dynamic_stencil_reference_back_update_needed_ = true; + current_render_pass_ = VK_NULL_HANDLE; + current_framebuffer_ = nullptr; + in_render_pass_ = false; + current_guest_graphics_pipeline_ = VK_NULL_HANDLE; + current_external_graphics_pipeline_ = VK_NULL_HANDLE; + current_external_compute_pipeline_ = VK_NULL_HANDLE; + current_guest_graphics_pipeline_layout_ = nullptr; + current_graphics_descriptor_sets_bound_up_to_date_ = 0; + + primitive_processor_->BeginSubmission(); + + texture_cache_->BeginSubmission(GetCurrentSubmission()); + } + + if (is_opening_frame) { + frame_open_ = true; + frame_used_async_placeholder_pipeline_ = false; + + // Reset bindings that depend on transient data. + std::memset(current_float_constant_map_vertex_, 0, sizeof(current_float_constant_map_vertex_)); + std::memset(current_float_constant_map_pixel_, 0, sizeof(current_float_constant_map_pixel_)); + std::memset(current_graphics_descriptor_sets_, 0, sizeof(current_graphics_descriptor_sets_)); + current_constant_buffers_up_to_date_ = 0; + current_graphics_descriptor_sets_[SpirvShaderTranslator::kDescriptorSetSharedMemoryAndEdram] = + shared_memory_and_edram_descriptor_set_; + current_graphics_descriptor_set_values_up_to_date_ = + UINT32_C(1) << SpirvShaderTranslator::kDescriptorSetSharedMemoryAndEdram; + + // Reclaim pool pages - no need to do this every small submission since some + // may be reused. + // FIXME(Triang3l): This will result in a memory leak if the guest is not + // presenting. + uniform_buffer_pool_->Reclaim(frame_completed_); + while (!single_transient_descriptors_used_.empty()) { + const UsedSingleTransientDescriptor& used_transient_descriptor = + single_transient_descriptors_used_.front(); + if (used_transient_descriptor.frame > frame_completed_) { + break; + } + single_transient_descriptors_free_[size_t(used_transient_descriptor.layout)].push_back( + used_transient_descriptor.set); + single_transient_descriptors_used_.pop_front(); + } + while (!constants_transient_descriptors_used_.empty()) { + const std::pair& used_transient_descriptor = + constants_transient_descriptors_used_.front(); + if (used_transient_descriptor.first > frame_completed_) { + break; + } + constants_transient_descriptors_free_.push_back(used_transient_descriptor.second); + constants_transient_descriptors_used_.pop_front(); + } + while (!texture_transient_descriptor_sets_used_.empty()) { + const UsedTextureTransientDescriptorSet& used_transient_descriptor_set = + texture_transient_descriptor_sets_used_.front(); + if (used_transient_descriptor_set.frame > frame_completed_) { + break; + } + auto it = texture_transient_descriptor_sets_free_.find(used_transient_descriptor_set.layout); + if (it == texture_transient_descriptor_sets_free_.end()) { + it = texture_transient_descriptor_sets_free_ + .emplace(std::piecewise_construct, + std::forward_as_tuple(used_transient_descriptor_set.layout), + std::forward_as_tuple()) + .first; + } + it->second.push_back(used_transient_descriptor_set.set); + texture_transient_descriptor_sets_used_.pop_front(); + } + + EvictOldReadbackBuffers(readback_buffers_); + EvictOldReadbackBuffers(memexport_readback_buffers_); + + primitive_processor_->BeginFrame(); + + texture_cache_->BeginFrame(); + } + + return true; +} + +bool VulkanCommandProcessor::EndSubmission(bool is_swap) { + const ui::vulkan::VulkanDevice* const vulkan_device = GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + // Make sure everything needed for submitting exist. + if (submission_open_) { + if (fences_free_.empty()) { + VkFenceCreateInfo fence_create_info; + fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fence_create_info.pNext = nullptr; + fence_create_info.flags = 0; + VkFence fence; + if (dfn.vkCreateFence(device, &fence_create_info, nullptr, &fence) != VK_SUCCESS) { + REXGPU_ERROR("Failed to create a Vulkan fence"); + // Try to submit later. Completely dropping the submission is not + // permitted because resources would be left in an undefined state. + return false; + } + fences_free_.push_back(fence); + } + if (!sparse_memory_binds_.empty() && semaphores_free_.empty()) { + VkSemaphoreCreateInfo semaphore_create_info; + semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + semaphore_create_info.pNext = nullptr; + semaphore_create_info.flags = 0; + VkSemaphore semaphore; + if (dfn.vkCreateSemaphore(device, &semaphore_create_info, nullptr, &semaphore) != + VK_SUCCESS) { + REXGPU_ERROR("Failed to create a Vulkan semaphore"); + return false; + } + semaphores_free_.push_back(semaphore); + } + if (command_buffers_writable_.empty()) { + CommandBuffer command_buffer; + VkCommandPoolCreateInfo command_pool_create_info; + command_pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + command_pool_create_info.pNext = nullptr; + command_pool_create_info.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT; + command_pool_create_info.queueFamilyIndex = vulkan_device->queue_family_graphics_compute(); + if (dfn.vkCreateCommandPool(device, &command_pool_create_info, nullptr, + &command_buffer.pool) != VK_SUCCESS) { + REXGPU_ERROR("Failed to create a Vulkan command pool"); + return false; + } + VkCommandBufferAllocateInfo command_buffer_allocate_info; + command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + command_buffer_allocate_info.pNext = nullptr; + command_buffer_allocate_info.commandPool = command_buffer.pool; + command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + command_buffer_allocate_info.commandBufferCount = 1; + if (dfn.vkAllocateCommandBuffers(device, &command_buffer_allocate_info, + &command_buffer.buffer) != VK_SUCCESS) { + REXGPU_ERROR("Failed to allocate a Vulkan command buffer"); + dfn.vkDestroyCommandPool(device, command_buffer.pool, nullptr); + return false; + } + command_buffers_writable_.push_back(command_buffer); + } + } + + bool is_closing_frame = is_swap && frame_open_; + + if (is_closing_frame) { + texture_cache_->EndFrame(); + + primitive_processor_->EndFrame(); + } + + if (submission_open_) { + assert_false(scratch_buffer_used_); + + if (active_occlusion_query_.valid && occlusion_query_pool_ != VK_NULL_HANDLE) { + deferred_command_buffer_.CmdVkEndQuery(occlusion_query_pool_, + active_occlusion_query_.host_index); + active_occlusion_query_ = {}; + } + + EndRenderPass(); + + pipeline_cache_->EndSubmission(); + + render_target_cache_->EndSubmission(); + + primitive_processor_->EndSubmission(); + + shared_memory_->EndSubmission(); + + uniform_buffer_pool_->FlushWrites(); + + // Submit sparse binds earlier, before executing the deferred command + // buffer, to reduce latency. + if (!sparse_memory_binds_.empty()) { + sparse_buffer_bind_infos_temp_.clear(); + sparse_buffer_bind_infos_temp_.reserve(sparse_buffer_binds_.size()); + for (const SparseBufferBind& sparse_buffer_bind : sparse_buffer_binds_) { + VkSparseBufferMemoryBindInfo& sparse_buffer_bind_info = + sparse_buffer_bind_infos_temp_.emplace_back(); + sparse_buffer_bind_info.buffer = sparse_buffer_bind.buffer; + sparse_buffer_bind_info.bindCount = sparse_buffer_bind.bind_count; + sparse_buffer_bind_info.pBinds = + sparse_memory_binds_.data() + sparse_buffer_bind.bind_offset; + } + assert_false(semaphores_free_.empty()); + VkSemaphore bind_sparse_semaphore = semaphores_free_.back(); + VkBindSparseInfo bind_sparse_info; + bind_sparse_info.sType = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO; + bind_sparse_info.pNext = nullptr; + bind_sparse_info.waitSemaphoreCount = 0; + bind_sparse_info.pWaitSemaphores = nullptr; + bind_sparse_info.bufferBindCount = uint32_t(sparse_buffer_bind_infos_temp_.size()); + bind_sparse_info.pBufferBinds = + !sparse_buffer_bind_infos_temp_.empty() ? sparse_buffer_bind_infos_temp_.data() : nullptr; + bind_sparse_info.imageOpaqueBindCount = 0; + bind_sparse_info.pImageOpaqueBinds = nullptr; + bind_sparse_info.imageBindCount = 0; + bind_sparse_info.pImageBinds = 0; + bind_sparse_info.signalSemaphoreCount = 1; + bind_sparse_info.pSignalSemaphores = &bind_sparse_semaphore; + VkResult bind_sparse_result; + { + ui::vulkan::VulkanDevice::Queue::Acquisition queue_acquisition = + vulkan_device->AcquireQueue(vulkan_device->queue_family_sparse_binding(), 0); + bind_sparse_result = + dfn.vkQueueBindSparse(queue_acquisition.queue(), 1, &bind_sparse_info, VK_NULL_HANDLE); + } + if (bind_sparse_result != VK_SUCCESS) { + REXGPU_ERROR("Failed to submit Vulkan sparse binds"); + return false; + } + current_submission_wait_semaphores_.push_back(bind_sparse_semaphore); + semaphores_free_.pop_back(); + current_submission_wait_stage_masks_.push_back(sparse_bind_wait_stage_mask_); + sparse_bind_wait_stage_mask_ = 0; + sparse_buffer_binds_.clear(); + sparse_memory_binds_.clear(); + } + + SubmitBarriers(true); + + assert_false(command_buffers_writable_.empty()); + CommandBuffer command_buffer = command_buffers_writable_.back(); + if (dfn.vkResetCommandPool(device, command_buffer.pool, 0) != VK_SUCCESS) { + REXGPU_ERROR("Failed to reset a Vulkan command pool"); + return false; + } + VkCommandBufferBeginInfo command_buffer_begin_info; + command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + command_buffer_begin_info.pNext = nullptr; + command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + command_buffer_begin_info.pInheritanceInfo = nullptr; + if (dfn.vkBeginCommandBuffer(command_buffer.buffer, &command_buffer_begin_info) != VK_SUCCESS) { + REXGPU_ERROR("Failed to begin a Vulkan command buffer"); + return false; + } + deferred_command_buffer_.Execute(command_buffer.buffer); + if (dfn.vkEndCommandBuffer(command_buffer.buffer) != VK_SUCCESS) { + REXGPU_ERROR("Failed to end a Vulkan command buffer"); + return false; + } + + VkSubmitInfo submit_info; + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.pNext = nullptr; + if (!current_submission_wait_semaphores_.empty()) { + submit_info.waitSemaphoreCount = uint32_t(current_submission_wait_semaphores_.size()); + submit_info.pWaitSemaphores = current_submission_wait_semaphores_.data(); + submit_info.pWaitDstStageMask = current_submission_wait_stage_masks_.data(); + } else { + submit_info.waitSemaphoreCount = 0; + submit_info.pWaitSemaphores = nullptr; + submit_info.pWaitDstStageMask = nullptr; + } + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = &command_buffer.buffer; + submit_info.signalSemaphoreCount = 0; + submit_info.pSignalSemaphores = nullptr; + assert_false(fences_free_.empty()); + VkFence fence = fences_free_.back(); + if (dfn.vkResetFences(device, 1, &fence) != VK_SUCCESS) { + REXGPU_ERROR("Failed to reset a Vulkan submission fence"); + return false; + } + VkResult submit_result; + { + ui::vulkan::VulkanDevice::Queue::Acquisition queue_acquisition = + vulkan_device->AcquireQueue(vulkan_device->queue_family_graphics_compute(), 0); + submit_result = dfn.vkQueueSubmit(queue_acquisition.queue(), 1, &submit_info, fence); + } + if (submit_result != VK_SUCCESS) { + REXGPU_ERROR("Failed to submit a Vulkan command buffer"); + if (submit_result == VK_ERROR_DEVICE_LOST && !device_lost_) { + device_lost_ = true; + if (graphics_system_) { + graphics_system_->OnHostGpuLossFromAnyThread(true); + } + } + return false; + } + uint64_t submission_current = GetCurrentSubmission(); + current_submission_wait_stage_masks_.clear(); + for (VkSemaphore semaphore : current_submission_wait_semaphores_) { + submissions_in_flight_semaphores_.emplace_back(submission_current, semaphore); + } + current_submission_wait_semaphores_.clear(); + command_buffers_submitted_.emplace_back(submission_current, command_buffer); + command_buffers_writable_.pop_back(); + // Increments the current submission number, going to the next submission. + submissions_in_flight_fences_.push_back(fence); + fences_free_.pop_back(); + + submission_open_ = false; + } + + if (is_closing_frame) { + if (REXCVAR_GET(clear_memory_page_state) && shared_memory_) { + shared_memory_->SetSystemPageBlocksValidWithGpuDataWritten(); + } + frame_open_ = false; + // Submission already closed now, so minus 1. + closed_frame_submissions_[(frame_current_++) % kMaxFramesInFlight] = GetCurrentSubmission() - 1; + + if (cache_clear_requested_ && AwaitAllQueueOperationsCompletion()) { + cache_clear_requested_ = false; + + DestroyScratchBuffer(); + + for (SwapFramebuffer& swap_framebuffer : swap_framebuffers_) { + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyFramebuffer, device, + swap_framebuffer.framebuffer); + } + + assert_true(command_buffers_submitted_.empty()); + for (const CommandBuffer& command_buffer : command_buffers_writable_) { + dfn.vkDestroyCommandPool(device, command_buffer.pool, nullptr); + } + command_buffers_writable_.clear(); + + ClearTransientDescriptorPools(); + + uniform_buffer_pool_->ClearCache(); + + texture_cache_->ClearCache(); + + render_target_cache_->ClearCache(); + + // Not clearing the pipeline layouts and the descriptor set layouts as + // they're referenced by pipelines, which are not destroyed. + + primitive_processor_->ClearCache(); + + shared_memory_->ClearCache(); + } + } + + return true; +} + +void VulkanCommandProcessor::ClearTransientDescriptorPools() { + texture_transient_descriptor_sets_free_.clear(); + texture_transient_descriptor_sets_used_.clear(); + transient_descriptor_allocator_textures_.Reset(); + + constants_transient_descriptors_free_.clear(); + constants_transient_descriptors_used_.clear(); + for (std::vector& transient_descriptors_free : + single_transient_descriptors_free_) { + transient_descriptors_free.clear(); + } + single_transient_descriptors_used_.clear(); + transient_descriptor_allocator_storage_buffer_.Reset(); + transient_descriptor_allocator_uniform_buffer_.Reset(); +} + +void VulkanCommandProcessor::SplitPendingBarrier() { + size_t pending_buffer_memory_barrier_count = pending_barriers_buffer_memory_barriers_.size(); + size_t pending_image_memory_barrier_count = pending_barriers_image_memory_barriers_.size(); + if (!current_pending_barrier_.src_stage_mask && !current_pending_barrier_.dst_stage_mask && + current_pending_barrier_.buffer_memory_barriers_offset >= + pending_buffer_memory_barrier_count && + current_pending_barrier_.image_memory_barriers_offset >= pending_image_memory_barrier_count) { + return; + } + pending_barriers_.emplace_back(current_pending_barrier_); + current_pending_barrier_.src_stage_mask = 0; + current_pending_barrier_.dst_stage_mask = 0; + current_pending_barrier_.buffer_memory_barriers_offset = pending_buffer_memory_barrier_count; + current_pending_barrier_.image_memory_barriers_offset = pending_image_memory_barrier_count; +} + +void VulkanCommandProcessor::DestroyScratchBuffer() { + assert_false(scratch_buffer_used_); + + const ui::vulkan::VulkanDevice* const vulkan_device = GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + scratch_buffer_last_usage_submission_ = 0; + scratch_buffer_last_access_mask_ = 0; + scratch_buffer_last_stage_mask_ = 0; + scratch_buffer_size_ = 0; + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyBuffer, device, scratch_buffer_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkFreeMemory, device, scratch_buffer_memory_); +} + +bool VulkanCommandProcessor::EnsureSwapFxaaSourceImage(uint32_t width, uint32_t height) { + assert_true(submission_open_); + if (!width || !height) { + return false; + } + if (swap_fxaa_source_image_ != VK_NULL_HANDLE && swap_fxaa_source_image_width_ == width && + swap_fxaa_source_image_height_ == height) { + return true; + } + + const ui::vulkan::VulkanDevice* const vulkan_device = GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + if (swap_fxaa_source_image_ != VK_NULL_HANDLE) { + const uint64_t destroy_submission = swap_fxaa_source_image_submission_; + const uint64_t deferred_destroy_submission = GetCurrentSubmission(); + if (submission_completed_ >= destroy_submission) { + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyImageView, device, + swap_fxaa_source_image_view_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyImage, device, swap_fxaa_source_image_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkFreeMemory, device, + swap_fxaa_source_image_memory_); + } else { + if (swap_fxaa_source_image_view_ != VK_NULL_HANDLE) { + destroy_image_views_.emplace_back(deferred_destroy_submission, + swap_fxaa_source_image_view_); + swap_fxaa_source_image_view_ = VK_NULL_HANDLE; + } + if (swap_fxaa_source_image_ != VK_NULL_HANDLE) { + destroy_images_.emplace_back(deferred_destroy_submission, swap_fxaa_source_image_); + swap_fxaa_source_image_ = VK_NULL_HANDLE; + } + if (swap_fxaa_source_image_memory_ != VK_NULL_HANDLE) { + destroy_memory_.emplace_back(deferred_destroy_submission, swap_fxaa_source_image_memory_); + swap_fxaa_source_image_memory_ = VK_NULL_HANDLE; + } + } + } + swap_fxaa_source_image_width_ = 0; + swap_fxaa_source_image_height_ = 0; + swap_fxaa_source_image_submission_ = 0; + swap_fxaa_source_stage_mask_ = 0; + swap_fxaa_source_access_mask_ = 0; + swap_fxaa_source_layout_ = VK_IMAGE_LAYOUT_UNDEFINED; + + VkImageCreateInfo image_create_info; + image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + image_create_info.pNext = nullptr; + image_create_info.flags = 0; + image_create_info.imageType = VK_IMAGE_TYPE_2D; + image_create_info.format = VK_FORMAT_R16G16B16A16_SFLOAT; + image_create_info.extent.width = width; + image_create_info.extent.height = height; + image_create_info.extent.depth = 1; + image_create_info.mipLevels = 1; + image_create_info.arrayLayers = 1; + image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; + image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; + image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT; + image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + image_create_info.queueFamilyIndexCount = 0; + image_create_info.pQueueFamilyIndices = nullptr; + image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + if (!ui::vulkan::util::CreateDedicatedAllocationImage( + vulkan_device, image_create_info, ui::vulkan::util::MemoryPurpose::kDeviceLocal, + swap_fxaa_source_image_, swap_fxaa_source_image_memory_)) { + REXGPU_ERROR("Failed to create the FXAA source image"); + return false; + } + + VkImageViewCreateInfo image_view_create_info; + image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + image_view_create_info.pNext = nullptr; + image_view_create_info.flags = 0; + image_view_create_info.image = swap_fxaa_source_image_; + image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; + image_view_create_info.format = image_create_info.format; + image_view_create_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_create_info.subresourceRange = ui::vulkan::util::InitializeSubresourceRange(); + if (dfn.vkCreateImageView(device, &image_view_create_info, nullptr, + &swap_fxaa_source_image_view_) != VK_SUCCESS) { + REXGPU_ERROR("Failed to create the FXAA source image view"); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyImage, device, swap_fxaa_source_image_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkFreeMemory, device, + swap_fxaa_source_image_memory_); + return false; + } + + swap_fxaa_source_image_width_ = width; + swap_fxaa_source_image_height_ = height; + swap_fxaa_source_image_submission_ = 0; + swap_fxaa_source_stage_mask_ = 0; + swap_fxaa_source_access_mask_ = 0; + swap_fxaa_source_layout_ = VK_IMAGE_LAYOUT_UNDEFINED; + return true; +} + +void VulkanCommandProcessor::DestroySwapFxaaSourceImage() { + const ui::vulkan::VulkanDevice* const vulkan_device = GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyImageView, device, + swap_fxaa_source_image_view_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyImage, device, swap_fxaa_source_image_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkFreeMemory, device, swap_fxaa_source_image_memory_); + swap_fxaa_source_image_width_ = 0; + swap_fxaa_source_image_height_ = 0; + swap_fxaa_source_image_submission_ = 0; + swap_fxaa_source_stage_mask_ = 0; + swap_fxaa_source_access_mask_ = 0; + swap_fxaa_source_layout_ = VK_IMAGE_LAYOUT_UNDEFINED; +} + +void VulkanCommandProcessor::UpdateDynamicState(const draw_util::ViewportInfo& viewport_info, + bool primitive_polygonal, + reg::RB_DEPTHCONTROL normalized_depth_control) { +#if XE_GPU_FINE_GRAINED_DRAW_SCOPES + SCOPE_profile_cpu_f("gpu"); +#endif // XE_GPU_FINE_GRAINED_DRAW_SCOPES + + const RegisterFile& regs = *register_file_; + uint32_t draw_resolution_scale_x = texture_cache_ ? texture_cache_->draw_resolution_scale_x() : 1; + uint32_t draw_resolution_scale_y = texture_cache_ ? texture_cache_->draw_resolution_scale_y() : 1; + + // Window parameters. + // http://ftp.tku.edu.tw/NetBSD/NetBSD-current/xsrc/external/mit/xf86-video-ati/dist/src/r600_reg_auto_r6xx.h + // See r200UpdateWindow: + // https://github.com/freedreno/mesa/blob/master/src/mesa/drivers/dri/r200/r200_state.c + auto pa_sc_window_offset = regs.Get(); + + // Viewport. + VkViewport viewport; + if (viewport_info.xy_extent[0] && viewport_info.xy_extent[1]) { + viewport.x = float(viewport_info.xy_offset[0]); + viewport.y = float(viewport_info.xy_offset[1]); + viewport.width = float(viewport_info.xy_extent[0]); + viewport.height = float(viewport_info.xy_extent[1]); + } else { + // Vulkan viewport width must be greater than 0.0f, but the Xenia viewport + // may be empty for various reasons - set the viewport to outside the + // framebuffer. + viewport.x = -1.0f; + viewport.y = -1.0f; + viewport.width = 1.0f; + viewport.height = 1.0f; + } + viewport.minDepth = viewport_info.z_min; + viewport.maxDepth = viewport_info.z_max; + SetViewport(viewport); + + // Scissor. + draw_util::Scissor scissor; + draw_util::GetScissor(regs, scissor); + scissor.offset[0] *= draw_resolution_scale_x; + scissor.offset[1] *= draw_resolution_scale_y; + scissor.extent[0] *= draw_resolution_scale_x; + scissor.extent[1] *= draw_resolution_scale_y; + VkRect2D scissor_rect; + scissor_rect.offset.x = int32_t(scissor.offset[0]); + scissor_rect.offset.y = int32_t(scissor.offset[1]); + scissor_rect.extent.width = scissor.extent[0]; + scissor_rect.extent.height = scissor.extent[1]; + SetScissor(scissor_rect); + + if (render_target_cache_->GetPath() == RenderTargetCache::Path::kHostRenderTargets) { + // Depth bias. + float depth_bias_constant_factor, depth_bias_slope_factor; + draw_util::GetPreferredFacePolygonOffset(regs, primitive_polygonal, depth_bias_slope_factor, + depth_bias_constant_factor); + depth_bias_constant_factor *= + regs.Get().depth_format == xenos::DepthRenderTargetFormat::kD24S8 + ? draw_util::kD3D10PolygonOffsetFactorUnorm24 + : draw_util::kD3D10PolygonOffsetFactorFloat24; + // With non-square resolution scaling, make sure the worst-case impact is + // reverted (slope only along the scaled axis), thus max. More bias is + // better than less bias, because less bias means Z fighting with the + // background is more likely. + depth_bias_slope_factor *= xenos::kPolygonOffsetScaleSubpixelUnit * + float(std::max(draw_resolution_scale_x, draw_resolution_scale_y)); + // std::memcmp instead of != so in case of NaN, every draw won't be + // invalidating it. + dynamic_depth_bias_update_needed_ |= + std::memcmp(&dynamic_depth_bias_constant_factor_, &depth_bias_constant_factor, + sizeof(float)) != 0; + dynamic_depth_bias_update_needed_ |= std::memcmp(&dynamic_depth_bias_slope_factor_, + &depth_bias_slope_factor, sizeof(float)) != 0; + if (dynamic_depth_bias_update_needed_) { + dynamic_depth_bias_constant_factor_ = depth_bias_constant_factor; + dynamic_depth_bias_slope_factor_ = depth_bias_slope_factor; + deferred_command_buffer_.CmdVkSetDepthBias(dynamic_depth_bias_constant_factor_, 0.0f, + dynamic_depth_bias_slope_factor_); + dynamic_depth_bias_update_needed_ = false; + } + + // Blend constants. + float blend_constants[] = { + regs.Get(XE_GPU_REG_RB_BLEND_RED), + regs.Get(XE_GPU_REG_RB_BLEND_GREEN), + regs.Get(XE_GPU_REG_RB_BLEND_BLUE), + regs.Get(XE_GPU_REG_RB_BLEND_ALPHA), + }; + dynamic_blend_constants_update_needed_ |= + std::memcmp(dynamic_blend_constants_, blend_constants, sizeof(float) * 4) != 0; + if (dynamic_blend_constants_update_needed_) { + std::memcpy(dynamic_blend_constants_, blend_constants, sizeof(float) * 4); + deferred_command_buffer_.CmdVkSetBlendConstants(dynamic_blend_constants_); + dynamic_blend_constants_update_needed_ = false; + } + + // Stencil masks and references. + // Due to pretty complex conditions involving registers not directly related + // to stencil (primitive type, culling), changing the values only when + // stencil is actually needed. However, due to the way dynamic state needs + // to be set in Vulkan, which doesn't take into account whether the state + // actually has effect on drawing, and because the masks and the references + // are always dynamic in Xenia guest pipelines, they must be set in the + // command buffer before any draw. + if (normalized_depth_control.stencil_enable) { + Register stencil_ref_mask_front_reg, stencil_ref_mask_back_reg; + if (primitive_polygonal && normalized_depth_control.backface_enable) { + if (GetVulkanDevice()->properties().separateStencilMaskRef) { + stencil_ref_mask_front_reg = XE_GPU_REG_RB_STENCILREFMASK; + stencil_ref_mask_back_reg = XE_GPU_REG_RB_STENCILREFMASK_BF; + } else { + // Choose the back face values only if drawing only back faces. + stencil_ref_mask_front_reg = regs.Get().cull_front + ? XE_GPU_REG_RB_STENCILREFMASK_BF + : XE_GPU_REG_RB_STENCILREFMASK; + stencil_ref_mask_back_reg = stencil_ref_mask_front_reg; + } + } else { + stencil_ref_mask_front_reg = XE_GPU_REG_RB_STENCILREFMASK; + stencil_ref_mask_back_reg = XE_GPU_REG_RB_STENCILREFMASK; + } + auto stencil_ref_mask_front = regs.Get(stencil_ref_mask_front_reg); + auto stencil_ref_mask_back = regs.Get(stencil_ref_mask_back_reg); + // Compare mask. + dynamic_stencil_compare_mask_front_update_needed_ |= + dynamic_stencil_compare_mask_front_ != stencil_ref_mask_front.stencilmask; + dynamic_stencil_compare_mask_front_ = stencil_ref_mask_front.stencilmask; + dynamic_stencil_compare_mask_back_update_needed_ |= + dynamic_stencil_compare_mask_back_ != stencil_ref_mask_back.stencilmask; + dynamic_stencil_compare_mask_back_ = stencil_ref_mask_back.stencilmask; + // Write mask. + dynamic_stencil_write_mask_front_update_needed_ |= + dynamic_stencil_write_mask_front_ != stencil_ref_mask_front.stencilwritemask; + dynamic_stencil_write_mask_front_ = stencil_ref_mask_front.stencilwritemask; + dynamic_stencil_write_mask_back_update_needed_ |= + dynamic_stencil_write_mask_back_ != stencil_ref_mask_back.stencilwritemask; + dynamic_stencil_write_mask_back_ = stencil_ref_mask_back.stencilwritemask; + // Reference. + dynamic_stencil_reference_front_update_needed_ |= + dynamic_stencil_reference_front_ != stencil_ref_mask_front.stencilref; + dynamic_stencil_reference_front_ = stencil_ref_mask_front.stencilref; + dynamic_stencil_reference_back_update_needed_ |= + dynamic_stencil_reference_back_ != stencil_ref_mask_back.stencilref; + dynamic_stencil_reference_back_ = stencil_ref_mask_back.stencilref; + } + // Using VK_STENCIL_FACE_FRONT_AND_BACK for higher safety when running on + // the Vulkan portability subset without separateStencilMaskRef. + if (dynamic_stencil_compare_mask_front_update_needed_ || + dynamic_stencil_compare_mask_back_update_needed_) { + if (dynamic_stencil_compare_mask_front_ == dynamic_stencil_compare_mask_back_) { + deferred_command_buffer_.CmdVkSetStencilCompareMask(VK_STENCIL_FACE_FRONT_AND_BACK, + dynamic_stencil_compare_mask_front_); + } else { + if (dynamic_stencil_compare_mask_front_update_needed_) { + deferred_command_buffer_.CmdVkSetStencilCompareMask(VK_STENCIL_FACE_FRONT_BIT, + dynamic_stencil_compare_mask_front_); + } + if (dynamic_stencil_compare_mask_back_update_needed_) { + deferred_command_buffer_.CmdVkSetStencilCompareMask(VK_STENCIL_FACE_BACK_BIT, + dynamic_stencil_compare_mask_back_); + } + } + dynamic_stencil_compare_mask_front_update_needed_ = false; + dynamic_stencil_compare_mask_back_update_needed_ = false; + } + if (dynamic_stencil_write_mask_front_update_needed_ || + dynamic_stencil_write_mask_back_update_needed_) { + if (dynamic_stencil_write_mask_front_ == dynamic_stencil_write_mask_back_) { + deferred_command_buffer_.CmdVkSetStencilWriteMask(VK_STENCIL_FACE_FRONT_AND_BACK, + dynamic_stencil_write_mask_front_); + } else { + if (dynamic_stencil_write_mask_front_update_needed_) { + deferred_command_buffer_.CmdVkSetStencilWriteMask(VK_STENCIL_FACE_FRONT_BIT, + dynamic_stencil_write_mask_front_); + } + if (dynamic_stencil_write_mask_back_update_needed_) { + deferred_command_buffer_.CmdVkSetStencilWriteMask(VK_STENCIL_FACE_BACK_BIT, + dynamic_stencil_write_mask_back_); + } + } + dynamic_stencil_write_mask_front_update_needed_ = false; + dynamic_stencil_write_mask_back_update_needed_ = false; + } + if (dynamic_stencil_reference_front_update_needed_ || + dynamic_stencil_reference_back_update_needed_) { + if (dynamic_stencil_reference_front_ == dynamic_stencil_reference_back_) { + deferred_command_buffer_.CmdVkSetStencilReference(VK_STENCIL_FACE_FRONT_AND_BACK, + dynamic_stencil_reference_front_); + } else { + if (dynamic_stencil_reference_front_update_needed_) { + deferred_command_buffer_.CmdVkSetStencilReference(VK_STENCIL_FACE_FRONT_BIT, + dynamic_stencil_reference_front_); + } + if (dynamic_stencil_reference_back_update_needed_) { + deferred_command_buffer_.CmdVkSetStencilReference(VK_STENCIL_FACE_BACK_BIT, + dynamic_stencil_reference_back_); + } + } + dynamic_stencil_reference_front_update_needed_ = false; + dynamic_stencil_reference_back_update_needed_ = false; + } + } + + // TODO(Triang3l): VK_EXT_extended_dynamic_state and + // VK_EXT_extended_dynamic_state2. +} + +void VulkanCommandProcessor::UpdateSystemConstantValues( + bool primitive_polygonal, + const PrimitiveProcessor::ProcessingResult& primitive_processing_result, + bool shader_32bit_index_dma, uint32_t compute_memexport_vertex_count, + const draw_util::ViewportInfo& viewport_info, uint32_t used_texture_mask, + reg::RB_DEPTHCONTROL normalized_depth_control, uint32_t normalized_color_mask) { +#if XE_GPU_FINE_GRAINED_DRAW_SCOPES + SCOPE_profile_cpu_f("gpu"); +#endif // XE_GPU_FINE_GRAINED_DRAW_SCOPES + + const RegisterFile& regs = *register_file_; + auto pa_cl_clip_cntl = regs.Get(); + auto pa_cl_vte_cntl = regs.Get(); + auto pa_su_sc_mode_cntl = regs.Get(); + auto rb_alpha_ref = regs.Get(XE_GPU_REG_RB_ALPHA_REF); + auto rb_colorcontrol = regs.Get(); + auto rb_depth_info = regs.Get(); + auto rb_stencilrefmask = regs.Get(); + auto rb_stencilrefmask_bf = regs.Get(XE_GPU_REG_RB_STENCILREFMASK_BF); + auto rb_surface_info = regs.Get(); + auto vgt_dma_size = regs.Get(); + auto vgt_draw_initiator = regs.Get(); + auto vgt_indx_offset = regs.Get(XE_GPU_REG_VGT_INDX_OFFSET); + auto vgt_max_vtx_indx = regs.Get(XE_GPU_REG_VGT_MAX_VTX_INDX); + auto vgt_min_vtx_indx = regs.Get(XE_GPU_REG_VGT_MIN_VTX_INDX); + + bool edram_fragment_shader_interlock = + render_target_cache_->GetPath() == RenderTargetCache::Path::kPixelShaderInterlock; + uint32_t draw_resolution_scale_x = texture_cache_->draw_resolution_scale_x(); + uint32_t draw_resolution_scale_y = texture_cache_->draw_resolution_scale_y(); + + // Get the color info register values for each render target. Also, for FSI, + // exclude components that don't exist in the format from the write mask. + // Don't exclude fully overlapping render targets, however - two render + // targets with the same base address are used in the lighting pass of + // 4D5307E6, for example, with the needed one picked with dynamic control + // flow. + reg::RB_COLOR_INFO color_infos[xenos::kMaxColorRenderTargets]; + float rt_clamp[4][4]; + // Two UINT32_MAX if no components actually existing in the RT are written. + uint32_t rt_keep_masks[4][2]; + for (uint32_t i = 0; i < xenos::kMaxColorRenderTargets; ++i) { + auto color_info = regs.Get(reg::RB_COLOR_INFO::rt_register_indices[i]); + color_infos[i] = color_info; + if (edram_fragment_shader_interlock) { + RenderTargetCache::GetPSIColorFormatInfo( + color_info.color_format, (normalized_color_mask >> (i * 4)) & 0b1111, rt_clamp[i][0], + rt_clamp[i][1], rt_clamp[i][2], rt_clamp[i][3], rt_keep_masks[i][0], rt_keep_masks[i][1]); + } + } + + // Disable depth and stencil if it aliases a color render target (for + // instance, during the XBLA logo in 58410954, though depth writing is already + // disabled there). + bool depth_stencil_enabled = + normalized_depth_control.stencil_enable || normalized_depth_control.z_enable; + if (edram_fragment_shader_interlock && depth_stencil_enabled) { + for (uint32_t i = 0; i < 4; ++i) { + if (rb_depth_info.depth_base == color_infos[i].color_base && + (rt_keep_masks[i][0] != UINT32_MAX || rt_keep_masks[i][1] != UINT32_MAX)) { + depth_stencil_enabled = false; + break; + } + } + } + + bool dirty = false; + + // Flags. + uint32_t flags = 0; + // Vertex index shader loading. + if (shader_32bit_index_dma) { + flags |= SpirvShaderTranslator::kSysFlag_VertexIndexLoad; + } + if (primitive_processing_result.index_buffer_type == + PrimitiveProcessor::ProcessedIndexBufferType::kHostBuiltinForDMA || + primitive_processing_result.index_buffer_type == + PrimitiveProcessor::ProcessedIndexBufferType::kGuestDMA || + primitive_processing_result.index_buffer_type == + PrimitiveProcessor::ProcessedIndexBufferType::kHostConverted) { + flags |= SpirvShaderTranslator::kSysFlag_ComputeOrPrimitiveVertexIndexLoad; + if (vgt_draw_initiator.index_size == xenos::IndexFormat::kInt32) { + flags |= SpirvShaderTranslator ::kSysFlag_ComputeOrPrimitiveVertexIndexLoad32Bit; + } + // Point and rectangle expansion uses primitive restart only in the host + // built-in strip index buffer; guest indices are not reset-based there. + bool compute_or_primitive_vertex_index_reset = + primitive_processing_result.host_primitive_reset_enabled && + primitive_processing_result.host_vertex_shader_type != + Shader::HostVertexShaderType::kPointListAsTriangleStrip && + primitive_processing_result.host_vertex_shader_type != + Shader::HostVertexShaderType::kRectangleListAsTriangleStrip; + if (compute_or_primitive_vertex_index_reset) { + flags |= SpirvShaderTranslator::kSysFlag_ComputeOrPrimitiveVertexIndexReset; + } + } + if (primitive_processing_result.host_vertex_shader_type == + Shader::HostVertexShaderType::kTriangleDomainPatchIndexed) { + flags |= SpirvShaderTranslator::kSysFlag_ComputeMemExportPatchIndexInRegister1; + } + if (primitive_processing_result.host_vertex_shader_type == + Shader::HostVertexShaderType::kTriangleDomainCPIndexed) { + flags |= SpirvShaderTranslator::kSysFlag_ComputeMemExportTriangleCPIndexed; + } else if (primitive_processing_result.host_vertex_shader_type == + Shader::HostVertexShaderType::kQuadDomainCPIndexed) { + flags |= SpirvShaderTranslator::kSysFlag_ComputeMemExportQuadCPIndexed; + } + if (primitive_processing_result.tessellation_mode == xenos::TessellationMode::kAdaptive && + (primitive_processing_result.host_vertex_shader_type == + Shader::HostVertexShaderType::kTriangleDomainPatchIndexed || + primitive_processing_result.host_vertex_shader_type == + Shader::HostVertexShaderType::kQuadDomainPatchIndexed)) { + flags |= SpirvShaderTranslator::kSysFlag_ComputeMemExportPatchIndexFromInvocation; + } + // W0 division control. + // http://www.x.org/docs/AMD/old/evergreen_3D_registers_v2.pdf + // 8: VTX_XY_FMT = true: the incoming XY have already been multiplied by 1/W0. + // = false: multiply the X, Y coordinates by 1/W0. + // 9: VTX_Z_FMT = true: the incoming Z has already been multiplied by 1/W0. + // = false: multiply the Z coordinate by 1/W0. + // 10: VTX_W0_FMT = true: the incoming W0 is not 1/W0. Perform the reciprocal + // to get 1/W0. + if (pa_cl_vte_cntl.vtx_xy_fmt) { + flags |= SpirvShaderTranslator::kSysFlag_XYDividedByW; + } + if (pa_cl_vte_cntl.vtx_z_fmt) { + flags |= SpirvShaderTranslator::kSysFlag_ZDividedByW; + } + if (pa_cl_vte_cntl.vtx_w0_fmt) { + flags |= SpirvShaderTranslator::kSysFlag_WNotReciprocal; + } + // Whether the primitive is polygonal, and gl_FrontFacing matters. + if (primitive_polygonal) { + flags |= SpirvShaderTranslator::kSysFlag_PrimitivePolygonal; + } + // Primitive type. + if (draw_util::IsPrimitiveLine(regs)) { + flags |= SpirvShaderTranslator::kSysFlag_PrimitiveLine; + } + // MSAA sample count. + flags |= uint32_t(rb_surface_info.msaa_samples) + << SpirvShaderTranslator::kSysFlag_MsaaSamples_Shift; + // Depth format. + if (rb_depth_info.depth_format == xenos::DepthRenderTargetFormat::kD24FS8) { + flags |= SpirvShaderTranslator::kSysFlag_DepthFloat24; + } + // Alpha test. + xenos::CompareFunction alpha_test_function = rb_colorcontrol.alpha_test_enable + ? rb_colorcontrol.alpha_func + : xenos::CompareFunction::kAlways; + flags |= uint32_t(alpha_test_function) << SpirvShaderTranslator::kSysFlag_AlphaPassIfLess_Shift; + // Gamma writing. + if (!render_target_cache_->gamma_render_target_as_unorm16()) { + // Keep parity with D3D12: gamma targets in this path are converted via + // explicit Xenos PWL gamma logic in shaders rather than via host sRGB + // attachment conversion semantics. + for (uint32_t i = 0; i < xenos::kMaxColorRenderTargets; ++i) { + if (color_infos[i].color_format == xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA) { + flags |= SpirvShaderTranslator::kSysFlag_ConvertColor0ToGamma << i; + } + } + } + if (edram_fragment_shader_interlock && depth_stencil_enabled) { + flags |= SpirvShaderTranslator::kSysFlag_FSIDepthStencil; + if (normalized_depth_control.z_enable) { + flags |= uint32_t(normalized_depth_control.zfunc) + << SpirvShaderTranslator::kSysFlag_FSIDepthPassIfLess_Shift; + if (normalized_depth_control.z_write_enable) { + flags |= SpirvShaderTranslator::kSysFlag_FSIDepthWrite; + } + } else { + // In case stencil is used without depth testing - always pass, and + // don't modify the stored depth. + flags |= SpirvShaderTranslator::kSysFlag_FSIDepthPassIfLess | + SpirvShaderTranslator::kSysFlag_FSIDepthPassIfEqual | + SpirvShaderTranslator::kSysFlag_FSIDepthPassIfGreater; + } + if (normalized_depth_control.stencil_enable) { + flags |= SpirvShaderTranslator::kSysFlag_FSIStencilTest; + } + // Hint - if not applicable to the shader, will not have effect. + if (alpha_test_function == xenos::CompareFunction::kAlways && + !rb_colorcontrol.alpha_to_mask_enable) { + flags |= SpirvShaderTranslator::kSysFlag_FSIDepthStencilEarlyWrite; + } + } + dirty |= system_constants_.flags != flags; + system_constants_.flags = flags; + + // Index buffer address for loading in the shaders. + if (flags & (SpirvShaderTranslator::kSysFlag_VertexIndexLoad | + SpirvShaderTranslator::kSysFlag_ComputeOrPrimitiveVertexIndexLoad)) { + dirty |= + system_constants_.vertex_index_load_address != primitive_processing_result.guest_index_base; + system_constants_.vertex_index_load_address = primitive_processing_result.guest_index_base; + } + + // Primitive reset index for shader-side index loading. + uint32_t vertex_index_reset = + (flags & SpirvShaderTranslator::kSysFlag_ComputeOrPrimitiveVertexIndexReset) + ? regs.Get().reset_indx + : 0; + dirty |= system_constants_.vertex_index_reset != vertex_index_reset; + system_constants_.vertex_index_reset = vertex_index_reset; + dirty |= system_constants_.compute_memexport_vertex_count != compute_memexport_vertex_count; + system_constants_.compute_memexport_vertex_count = compute_memexport_vertex_count; + + // Index or tessellation edge factor buffer endianness. + xenos::Endian guest_index_endian = vgt_dma_size.swap_mode; + if (vgt_draw_initiator.index_size == xenos::IndexFormat::kInt16 && + guest_index_endian != xenos::Endian::kNone && guest_index_endian != xenos::Endian::k8in16) { + guest_index_endian = + guest_index_endian == xenos::Endian::k8in32 ? xenos::Endian::k8in16 : xenos::Endian::kNone; + } + xenos::Endian index_endian = + (flags & SpirvShaderTranslator::kSysFlag_ComputeOrPrimitiveVertexIndexLoad) + ? guest_index_endian + : primitive_processing_result.host_shader_index_endian; + dirty |= system_constants_.vertex_index_endian != index_endian; + system_constants_.vertex_index_endian = index_endian; + + dirty |= system_constants_.line_loop_closing_index != + primitive_processing_result.line_loop_closing_index; + system_constants_.line_loop_closing_index = primitive_processing_result.line_loop_closing_index; + + // Vertex index offset. + dirty |= system_constants_.vertex_base_index != vgt_indx_offset; + system_constants_.vertex_base_index = vgt_indx_offset; + + // Vertex index range. + dirty |= system_constants_.vertex_index_min != vgt_min_vtx_indx; + dirty |= system_constants_.vertex_index_max != vgt_max_vtx_indx; + system_constants_.vertex_index_min = vgt_min_vtx_indx; + system_constants_.vertex_index_max = vgt_max_vtx_indx; + + // User clip planes (UCP_ENA_#), when not CLIP_DISABLE. + // The shader knows only the total count - tightly packing the user clip + // planes that are actually used. + if (!pa_cl_clip_cntl.clip_disable) { + float* user_clip_plane_write_ptr = system_constants_.user_clip_planes[0]; + uint32_t user_clip_planes_remaining = pa_cl_clip_cntl.ucp_ena; + uint32_t user_clip_plane_index; + while (rex::bit_scan_forward(user_clip_planes_remaining, &user_clip_plane_index)) { + user_clip_planes_remaining &= ~(UINT32_C(1) << user_clip_plane_index); + const void* user_clip_plane_regs = + ®s[XE_GPU_REG_PA_CL_UCP_0_X + user_clip_plane_index * 4]; + if (std::memcmp(user_clip_plane_write_ptr, user_clip_plane_regs, 4 * sizeof(float))) { + dirty = true; + std::memcpy(user_clip_plane_write_ptr, user_clip_plane_regs, 4 * sizeof(float)); + } + user_clip_plane_write_ptr += 4; + } + } + + // Tessellation factor range, plus 1.0 according to + // https://www.slideshare.net/blackdevilvikas/next-generation-graphics-programming-on-xbox-360. + float tessellation_factor_min = regs.Get(XE_GPU_REG_VGT_HOS_MIN_TESS_LEVEL) + 1.0f; + float tessellation_factor_max = regs.Get(XE_GPU_REG_VGT_HOS_MAX_TESS_LEVEL) + 1.0f; + dirty |= system_constants_.tessellation_factor_range_min != tessellation_factor_min; + dirty |= system_constants_.tessellation_factor_range_max != tessellation_factor_max; + system_constants_.tessellation_factor_range_min = tessellation_factor_min; + system_constants_.tessellation_factor_range_max = tessellation_factor_max; + + // Conversion to host normalized device coordinates. + for (uint32_t i = 0; i < 3; ++i) { + dirty |= system_constants_.ndc_scale[i] != viewport_info.ndc_scale[i]; + dirty |= system_constants_.ndc_offset[i] != viewport_info.ndc_offset[i]; + system_constants_.ndc_scale[i] = viewport_info.ndc_scale[i]; + system_constants_.ndc_offset[i] = viewport_info.ndc_offset[i]; + } + + // Point size. + if (vgt_draw_initiator.prim_type == xenos::PrimitiveType::kPointList) { + auto pa_su_point_minmax = regs.Get(); + auto pa_su_point_size = regs.Get(); + float point_vertex_diameter_min = float(pa_su_point_minmax.min_size) * (2.0f / 16.0f); + float point_vertex_diameter_max = float(pa_su_point_minmax.max_size) * (2.0f / 16.0f); + float point_constant_diameter_x = float(pa_su_point_size.width) * (2.0f / 16.0f); + float point_constant_diameter_y = float(pa_su_point_size.height) * (2.0f / 16.0f); + dirty |= system_constants_.point_vertex_diameter_min != point_vertex_diameter_min; + dirty |= system_constants_.point_vertex_diameter_max != point_vertex_diameter_max; + dirty |= system_constants_.point_constant_diameter[0] != point_constant_diameter_x; + dirty |= system_constants_.point_constant_diameter[1] != point_constant_diameter_y; + system_constants_.point_vertex_diameter_min = point_vertex_diameter_min; + system_constants_.point_vertex_diameter_max = point_vertex_diameter_max; + system_constants_.point_constant_diameter[0] = point_constant_diameter_x; + system_constants_.point_constant_diameter[1] = point_constant_diameter_y; + // 2 because 1 in the NDC is half of the viewport's axis, 0.5 for diameter + // to radius conversion to avoid multiplying the per-vertex diameter by an + // additional constant in the shader. + float point_screen_diameter_to_ndc_radius_x = + (/* 0.5f * 2.0f * */ float(draw_resolution_scale_x)) / + std::max(viewport_info.xy_extent[0], uint32_t(1)); + float point_screen_diameter_to_ndc_radius_y = + (/* 0.5f * 2.0f * */ float(draw_resolution_scale_y)) / + std::max(viewport_info.xy_extent[1], uint32_t(1)); + dirty |= system_constants_.point_screen_diameter_to_ndc_radius[0] != + point_screen_diameter_to_ndc_radius_x; + dirty |= system_constants_.point_screen_diameter_to_ndc_radius[1] != + point_screen_diameter_to_ndc_radius_y; + system_constants_.point_screen_diameter_to_ndc_radius[0] = + point_screen_diameter_to_ndc_radius_x; + system_constants_.point_screen_diameter_to_ndc_radius[1] = + point_screen_diameter_to_ndc_radius_y; + } + + // Texture signedness / gamma. + uint32_t textures_resolution_scaled = 0; + { + uint32_t textures_remaining = used_texture_mask; + uint32_t texture_index; + while (rex::bit_scan_forward(textures_remaining, &texture_index)) { + textures_remaining &= ~(UINT32_C(1) << texture_index); + uint32_t& texture_signs_uint = system_constants_.texture_swizzled_signs[texture_index >> 2]; + uint32_t texture_signs_shift = 8 * (texture_index & 3); + uint8_t texture_signs = texture_cache_->GetActiveTextureSwizzledSigns(texture_index); + uint32_t texture_signs_shifted = uint32_t(texture_signs) << texture_signs_shift; + uint32_t texture_signs_mask = ((UINT32_C(1) << 8) - 1) << texture_signs_shift; + dirty |= (texture_signs_uint & texture_signs_mask) != texture_signs_shifted; + texture_signs_uint = (texture_signs_uint & ~texture_signs_mask) | texture_signs_shifted; + textures_resolution_scaled |= + uint32_t(texture_cache_->IsActiveTextureResolutionScaled(texture_index)) << texture_index; + } + } + dirty |= system_constants_.textures_resolution_scaled != textures_resolution_scaled; + system_constants_.textures_resolution_scaled = textures_resolution_scaled; + + // Texture host swizzle in the shader. + if (!GetVulkanDevice()->properties().imageViewFormatSwizzle) { + uint32_t textures_remaining = used_texture_mask; + uint32_t texture_index; + while (rex::bit_scan_forward(textures_remaining, &texture_index)) { + textures_remaining &= ~(UINT32_C(1) << texture_index); + uint32_t& texture_swizzles_uint = system_constants_.texture_swizzles[texture_index >> 1]; + uint32_t texture_swizzle_shift = 12 * (texture_index & 1); + uint32_t texture_swizzle = texture_cache_->GetActiveTextureHostSwizzle(texture_index); + uint32_t texture_swizzle_shifted = uint32_t(texture_swizzle) << texture_swizzle_shift; + uint32_t texture_swizzle_mask = ((UINT32_C(1) << 12) - 1) << texture_swizzle_shift; + dirty |= (texture_swizzles_uint & texture_swizzle_mask) != texture_swizzle_shifted; + texture_swizzles_uint = + (texture_swizzles_uint & ~texture_swizzle_mask) | texture_swizzle_shifted; + } + } + + // Alpha test. + dirty |= system_constants_.alpha_test_reference != rb_alpha_ref; + system_constants_.alpha_test_reference = rb_alpha_ref; + uint32_t alpha_to_mask = + rb_colorcontrol.alpha_to_mask_enable ? (rb_colorcontrol.value >> 24) | (UINT32_C(1) << 8) : 0; + dirty |= system_constants_.alpha_to_mask != alpha_to_mask; + system_constants_.alpha_to_mask = alpha_to_mask; + + uint32_t edram_tile_dwords_scaled = xenos::kEdramTileWidthSamples * + xenos::kEdramTileHeightSamples * + (draw_resolution_scale_x * draw_resolution_scale_y); + + // EDRAM pitch for FSI render target writing. + if (edram_fragment_shader_interlock) { + // Align, then multiply by 32bpp tile size in dwords. + uint32_t edram_32bpp_tile_pitch_dwords_scaled = + ((rb_surface_info.surface_pitch * + (rb_surface_info.msaa_samples >= xenos::MsaaSamples::k4X ? 2 : 1)) + + (xenos::kEdramTileWidthSamples - 1)) / + xenos::kEdramTileWidthSamples * edram_tile_dwords_scaled; + dirty |= system_constants_.edram_32bpp_tile_pitch_dwords_scaled != + edram_32bpp_tile_pitch_dwords_scaled; + system_constants_.edram_32bpp_tile_pitch_dwords_scaled = edram_32bpp_tile_pitch_dwords_scaled; + } + + // Color exponent bias and FSI render target writing. + for (uint32_t i = 0; i < xenos::kMaxColorRenderTargets; ++i) { + reg::RB_COLOR_INFO color_info = color_infos[i]; + // Exponent bias is in bits 20:25 of RB_COLOR_INFO. + int32_t color_exp_bias = color_info.color_exp_bias; + if (render_target_cache_->GetPath() == RenderTargetCache::Path::kHostRenderTargets && + (color_info.color_format == xenos::ColorRenderTargetFormat::k_16_16 && + !render_target_cache_->IsFixedRG16TruncatedToMinus1To1() || + color_info.color_format == xenos::ColorRenderTargetFormat::k_16_16_16_16 && + !render_target_cache_->IsFixedRGBA16TruncatedToMinus1To1())) { + // Remap from -32...32 to -1...1 by dividing the output values by 32, + // losing blending correctness, but getting the full range. + color_exp_bias -= 5; + } + float color_exp_bias_scale; + *reinterpret_cast(&color_exp_bias_scale) = + UINT32_C(0x3F800000) + (color_exp_bias << 23); + dirty |= system_constants_.color_exp_bias[i] != color_exp_bias_scale; + system_constants_.color_exp_bias[i] = color_exp_bias_scale; + if (edram_fragment_shader_interlock) { + dirty |= system_constants_.edram_rt_keep_mask[i][0] != rt_keep_masks[i][0]; + system_constants_.edram_rt_keep_mask[i][0] = rt_keep_masks[i][0]; + dirty |= system_constants_.edram_rt_keep_mask[i][1] != rt_keep_masks[i][1]; + system_constants_.edram_rt_keep_mask[i][1] = rt_keep_masks[i][1]; + if (rt_keep_masks[i][0] != UINT32_MAX || rt_keep_masks[i][1] != UINT32_MAX) { + uint32_t rt_base_dwords_scaled = color_info.color_base * edram_tile_dwords_scaled; + dirty |= system_constants_.edram_rt_base_dwords_scaled[i] != rt_base_dwords_scaled; + system_constants_.edram_rt_base_dwords_scaled[i] = rt_base_dwords_scaled; + uint32_t format_flags = RenderTargetCache::AddPSIColorFormatFlags(color_info.color_format); + dirty |= system_constants_.edram_rt_format_flags[i] != format_flags; + system_constants_.edram_rt_format_flags[i] = format_flags; + uint32_t blend_factors_ops = + regs[reg::RB_BLENDCONTROL::rt_register_indices[i]] & 0x1FFF1FFF; + dirty |= system_constants_.edram_rt_blend_factors_ops[i] != blend_factors_ops; + system_constants_.edram_rt_blend_factors_ops[i] = blend_factors_ops; + // Can't do float comparisons here because NaNs would result in always + // setting the dirty flag. + dirty |= + std::memcmp(system_constants_.edram_rt_clamp[i], rt_clamp[i], 4 * sizeof(float)) != 0; + std::memcpy(system_constants_.edram_rt_clamp[i], rt_clamp[i], 4 * sizeof(float)); + } + } + } + + if (edram_fragment_shader_interlock) { + uint32_t depth_base_dwords_scaled = rb_depth_info.depth_base * edram_tile_dwords_scaled; + dirty |= system_constants_.edram_depth_base_dwords_scaled != depth_base_dwords_scaled; + system_constants_.edram_depth_base_dwords_scaled = depth_base_dwords_scaled; + + // For non-polygons, front polygon offset is used, and it's enabled if + // POLY_OFFSET_PARA_ENABLED is set, for polygons, separate front and back + // are used. + float poly_offset_front_scale = 0.0f, poly_offset_front_offset = 0.0f; + float poly_offset_back_scale = 0.0f, poly_offset_back_offset = 0.0f; + if (primitive_polygonal) { + if (pa_su_sc_mode_cntl.poly_offset_front_enable) { + poly_offset_front_scale = regs.Get(XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_SCALE); + poly_offset_front_offset = regs.Get(XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_OFFSET); + } + if (pa_su_sc_mode_cntl.poly_offset_back_enable) { + poly_offset_back_scale = regs.Get(XE_GPU_REG_PA_SU_POLY_OFFSET_BACK_SCALE); + poly_offset_back_offset = regs.Get(XE_GPU_REG_PA_SU_POLY_OFFSET_BACK_OFFSET); + } + } else { + if (pa_su_sc_mode_cntl.poly_offset_para_enable) { + poly_offset_front_scale = regs.Get(XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_SCALE); + poly_offset_front_offset = regs.Get(XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_OFFSET); + poly_offset_back_scale = poly_offset_front_scale; + poly_offset_back_offset = poly_offset_front_offset; + } + } + // With non-square resolution scaling, make sure the worst-case impact is + // reverted (slope only along the scaled axis), thus max. More bias is + // better than less bias, because less bias means Z fighting with the + // background is more likely. + float poly_offset_scale_factor = xenos::kPolygonOffsetScaleSubpixelUnit * + std::max(draw_resolution_scale_x, draw_resolution_scale_y); + poly_offset_front_scale *= poly_offset_scale_factor; + poly_offset_back_scale *= poly_offset_scale_factor; + dirty |= system_constants_.edram_poly_offset_front_scale != poly_offset_front_scale; + system_constants_.edram_poly_offset_front_scale = poly_offset_front_scale; + dirty |= system_constants_.edram_poly_offset_front_offset != poly_offset_front_offset; + system_constants_.edram_poly_offset_front_offset = poly_offset_front_offset; + dirty |= system_constants_.edram_poly_offset_back_scale != poly_offset_back_scale; + system_constants_.edram_poly_offset_back_scale = poly_offset_back_scale; + dirty |= system_constants_.edram_poly_offset_back_offset != poly_offset_back_offset; + system_constants_.edram_poly_offset_back_offset = poly_offset_back_offset; + + if (depth_stencil_enabled && normalized_depth_control.stencil_enable) { + uint32_t stencil_front_reference_masks = rb_stencilrefmask.value & 0xFFFFFF; + dirty |= + system_constants_.edram_stencil_front_reference_masks != stencil_front_reference_masks; + system_constants_.edram_stencil_front_reference_masks = stencil_front_reference_masks; + uint32_t stencil_func_ops = (normalized_depth_control.value >> 8) & ((1 << 12) - 1); + dirty |= system_constants_.edram_stencil_front_func_ops != stencil_func_ops; + system_constants_.edram_stencil_front_func_ops = stencil_func_ops; + + if (primitive_polygonal && normalized_depth_control.backface_enable) { + uint32_t stencil_back_reference_masks = rb_stencilrefmask_bf.value & 0xFFFFFF; + dirty |= + system_constants_.edram_stencil_back_reference_masks != stencil_back_reference_masks; + system_constants_.edram_stencil_back_reference_masks = stencil_back_reference_masks; + uint32_t stencil_func_ops_bf = (normalized_depth_control.value >> 20) & ((1 << 12) - 1); + dirty |= system_constants_.edram_stencil_back_func_ops != stencil_func_ops_bf; + system_constants_.edram_stencil_back_func_ops = stencil_func_ops_bf; + } else { + dirty |= std::memcmp(system_constants_.edram_stencil_back, + system_constants_.edram_stencil_front, 2 * sizeof(uint32_t)) != 0; + std::memcpy(system_constants_.edram_stencil_back, system_constants_.edram_stencil_front, + 2 * sizeof(uint32_t)); + } + } + + dirty |= system_constants_.edram_blend_constant[0] != regs.Get(XE_GPU_REG_RB_BLEND_RED); + system_constants_.edram_blend_constant[0] = regs.Get(XE_GPU_REG_RB_BLEND_RED); + dirty |= + system_constants_.edram_blend_constant[1] != regs.Get(XE_GPU_REG_RB_BLEND_GREEN); + system_constants_.edram_blend_constant[1] = regs.Get(XE_GPU_REG_RB_BLEND_GREEN); + dirty |= system_constants_.edram_blend_constant[2] != regs.Get(XE_GPU_REG_RB_BLEND_BLUE); + system_constants_.edram_blend_constant[2] = regs.Get(XE_GPU_REG_RB_BLEND_BLUE); + dirty |= + system_constants_.edram_blend_constant[3] != regs.Get(XE_GPU_REG_RB_BLEND_ALPHA); + system_constants_.edram_blend_constant[3] = regs.Get(XE_GPU_REG_RB_BLEND_ALPHA); + } + + if (dirty) { + current_constant_buffers_up_to_date_ &= + ~(UINT32_C(1) << SpirvShaderTranslator::kConstantBufferSystem); + } +} + +bool VulkanCommandProcessor::UpdateBindings(const VulkanShader* vertex_shader, + const VulkanShader* pixel_shader) { +#if XE_GPU_FINE_GRAINED_DRAW_SCOPES + SCOPE_profile_cpu_f("gpu"); +#endif // XE_GPU_FINE_GRAINED_DRAW_SCOPES + + const RegisterFile& regs = *register_file_; + + const ui::vulkan::VulkanDevice* const vulkan_device = GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + // Invalidate constant buffers and descriptors for changed data. + + // Float constants. + // These are the constant base addresses/ranges for shaders. + // We have these hardcoded right now cause nothing seems to differ on the Xbox + // 360 (however, OpenGL ES on Adreno 200 on Android has different ranges). + assert_true(regs[XE_GPU_REG_SQ_VS_CONST] == 0x000FF000 || + regs[XE_GPU_REG_SQ_VS_CONST] == 0x00000000); + assert_true(regs[XE_GPU_REG_SQ_PS_CONST] == 0x000FF100 || + regs[XE_GPU_REG_SQ_PS_CONST] == 0x00000000); + // Check if the float constant layout is still the same and get the counts. + const Shader::ConstantRegisterMap& float_constant_map_vertex = + vertex_shader->constant_register_map(); + uint32_t float_constant_count_vertex = float_constant_map_vertex.float_count; + for (uint32_t i = 0; i < 4; ++i) { + if (current_float_constant_map_vertex_[i] != float_constant_map_vertex.float_bitmap[i]) { + current_float_constant_map_vertex_[i] = float_constant_map_vertex.float_bitmap[i]; + // If no float constants at all, any buffer can be reused for them, so not + // invalidating. + if (float_constant_count_vertex) { + current_constant_buffers_up_to_date_ &= + ~(UINT32_C(1) << SpirvShaderTranslator::kConstantBufferFloatVertex); + } + } + } + uint32_t float_constant_count_pixel = 0; + if (pixel_shader != nullptr) { + const Shader::ConstantRegisterMap& float_constant_map_pixel = + pixel_shader->constant_register_map(); + float_constant_count_pixel = float_constant_map_pixel.float_count; + for (uint32_t i = 0; i < 4; ++i) { + if (current_float_constant_map_pixel_[i] != float_constant_map_pixel.float_bitmap[i]) { + current_float_constant_map_pixel_[i] = float_constant_map_pixel.float_bitmap[i]; + if (float_constant_count_pixel) { + current_constant_buffers_up_to_date_ &= + ~(UINT32_C(1) << SpirvShaderTranslator::kConstantBufferFloatPixel); + } + } + } + } else { + std::memset(current_float_constant_map_pixel_, 0, sizeof(current_float_constant_map_pixel_)); + } + + // Write the new constant buffers. + constexpr uint32_t kAllConstantBuffersMask = + (UINT32_C(1) << SpirvShaderTranslator::kConstantBufferCount) - 1; + assert_zero(current_constant_buffers_up_to_date_ & ~kAllConstantBuffersMask); + if ((current_constant_buffers_up_to_date_ & kAllConstantBuffersMask) != kAllConstantBuffersMask) { + current_graphics_descriptor_set_values_up_to_date_ &= + ~(UINT32_C(1) << SpirvShaderTranslator::kDescriptorSetConstants); + size_t uniform_buffer_alignment = + size_t(vulkan_device->properties().minUniformBufferOffsetAlignment); + // System constants. + if (!(current_constant_buffers_up_to_date_ & + (UINT32_C(1) << SpirvShaderTranslator::kConstantBufferSystem))) { + VkDescriptorBufferInfo& buffer_info = + current_constant_buffer_infos_[SpirvShaderTranslator::kConstantBufferSystem]; + uint8_t* mapping = uniform_buffer_pool_->Request( + frame_current_, sizeof(SpirvShaderTranslator::SystemConstants), uniform_buffer_alignment, + buffer_info.buffer, buffer_info.offset); + if (!mapping) { + return false; + } + buffer_info.range = sizeof(SpirvShaderTranslator::SystemConstants); + std::memcpy(mapping, &system_constants_, sizeof(SpirvShaderTranslator::SystemConstants)); + current_constant_buffers_up_to_date_ |= UINT32_C(1) + << SpirvShaderTranslator::kConstantBufferSystem; + } + // Vertex shader float constants. + if (!(current_constant_buffers_up_to_date_ & + (UINT32_C(1) << SpirvShaderTranslator::kConstantBufferFloatVertex))) { + VkDescriptorBufferInfo& buffer_info = + current_constant_buffer_infos_[SpirvShaderTranslator::kConstantBufferFloatVertex]; + // Even if the shader doesn't need any float constants, a valid binding + // must still be provided (the pipeline layout always has float constants, + // for both the vertex shader and the pixel shader), so if the first draw + // in the frame doesn't have float constants at all, still allocate a + // dummy buffer. + size_t float_constants_size = + sizeof(float) * 4 * std::max(float_constant_count_vertex, UINT32_C(1)); + uint8_t* mapping = uniform_buffer_pool_->Request(frame_current_, float_constants_size, + uniform_buffer_alignment, buffer_info.buffer, + buffer_info.offset); + if (!mapping) { + return false; + } + buffer_info.range = VkDeviceSize(float_constants_size); + for (uint32_t i = 0; i < 4; ++i) { + uint64_t float_constant_map_entry = current_float_constant_map_vertex_[i]; + uint32_t float_constant_index; + while (rex::bit_scan_forward(float_constant_map_entry, &float_constant_index)) { + float_constant_map_entry &= ~(1ull << float_constant_index); + std::memcpy( + mapping, + ®s[XE_GPU_REG_SHADER_CONSTANT_000_X + (i << 8) + (float_constant_index << 2)], + sizeof(float) * 4); + mapping += sizeof(float) * 4; + } + } + current_constant_buffers_up_to_date_ |= UINT32_C(1) + << SpirvShaderTranslator::kConstantBufferFloatVertex; + } + // Pixel shader float constants. + if (!(current_constant_buffers_up_to_date_ & + (UINT32_C(1) << SpirvShaderTranslator::kConstantBufferFloatPixel))) { + VkDescriptorBufferInfo& buffer_info = + current_constant_buffer_infos_[SpirvShaderTranslator::kConstantBufferFloatPixel]; + size_t float_constants_size = + sizeof(float) * 4 * std::max(float_constant_count_pixel, UINT32_C(1)); + uint8_t* mapping = uniform_buffer_pool_->Request(frame_current_, float_constants_size, + uniform_buffer_alignment, buffer_info.buffer, + buffer_info.offset); + if (!mapping) { + return false; + } + buffer_info.range = VkDeviceSize(float_constants_size); + for (uint32_t i = 0; i < 4; ++i) { + uint64_t float_constant_map_entry = current_float_constant_map_pixel_[i]; + uint32_t float_constant_index; + while (rex::bit_scan_forward(float_constant_map_entry, &float_constant_index)) { + float_constant_map_entry &= ~(1ull << float_constant_index); + std::memcpy( + mapping, + ®s[XE_GPU_REG_SHADER_CONSTANT_256_X + (i << 8) + (float_constant_index << 2)], + sizeof(float) * 4); + mapping += sizeof(float) * 4; + } + } + current_constant_buffers_up_to_date_ |= UINT32_C(1) + << SpirvShaderTranslator::kConstantBufferFloatPixel; + } + // Bool and loop constants. + if (!(current_constant_buffers_up_to_date_ & + (UINT32_C(1) << SpirvShaderTranslator::kConstantBufferBoolLoop))) { + VkDescriptorBufferInfo& buffer_info = + current_constant_buffer_infos_[SpirvShaderTranslator::kConstantBufferBoolLoop]; + constexpr size_t kBoolLoopConstantsSize = sizeof(uint32_t) * (8 + 32); + uint8_t* mapping = uniform_buffer_pool_->Request(frame_current_, kBoolLoopConstantsSize, + uniform_buffer_alignment, buffer_info.buffer, + buffer_info.offset); + if (!mapping) { + return false; + } + buffer_info.range = VkDeviceSize(kBoolLoopConstantsSize); + std::memcpy(mapping, ®s[XE_GPU_REG_SHADER_CONSTANT_BOOL_000_031], kBoolLoopConstantsSize); + current_constant_buffers_up_to_date_ |= UINT32_C(1) + << SpirvShaderTranslator::kConstantBufferBoolLoop; + } + // Fetch constants. + if (!(current_constant_buffers_up_to_date_ & + (UINT32_C(1) << SpirvShaderTranslator::kConstantBufferFetch))) { + VkDescriptorBufferInfo& buffer_info = + current_constant_buffer_infos_[SpirvShaderTranslator::kConstantBufferFetch]; + constexpr size_t kFetchConstantsSize = sizeof(uint32_t) * 6 * 32; + uint8_t* mapping = uniform_buffer_pool_->Request(frame_current_, kFetchConstantsSize, + uniform_buffer_alignment, buffer_info.buffer, + buffer_info.offset); + if (!mapping) { + return false; + } + buffer_info.range = VkDeviceSize(kFetchConstantsSize); + std::memcpy(mapping, ®s[XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0], kFetchConstantsSize); + current_constant_buffers_up_to_date_ |= UINT32_C(1) + << SpirvShaderTranslator::kConstantBufferFetch; + } + } + + // Textures and samplers. + const std::vector& samplers_vertex = + vertex_shader->GetSamplerBindingsAfterTranslation(); + const std::vector& textures_vertex = + vertex_shader->GetTextureBindingsAfterTranslation(); + uint32_t sampler_count_vertex = uint32_t(samplers_vertex.size()); + uint32_t texture_count_vertex = uint32_t(textures_vertex.size()); + const std::vector* samplers_pixel; + const std::vector* textures_pixel; + uint32_t sampler_count_pixel, texture_count_pixel; + if (pixel_shader) { + samplers_pixel = &pixel_shader->GetSamplerBindingsAfterTranslation(); + textures_pixel = &pixel_shader->GetTextureBindingsAfterTranslation(); + sampler_count_pixel = uint32_t(samplers_pixel->size()); + texture_count_pixel = uint32_t(textures_pixel->size()); + } else { + samplers_pixel = nullptr; + textures_pixel = nullptr; + sampler_count_pixel = 0; + texture_count_pixel = 0; + } + // TODO(Triang3l): Reuse texture and sampler bindings if not changed. + current_graphics_descriptor_set_values_up_to_date_ &= + ~((UINT32_C(1) << SpirvShaderTranslator::kDescriptorSetTexturesVertex) | + (UINT32_C(1) << SpirvShaderTranslator::kDescriptorSetTexturesPixel)); + + // Make sure new descriptor sets are bound to the command buffer. + + current_graphics_descriptor_sets_bound_up_to_date_ &= + current_graphics_descriptor_set_values_up_to_date_; + + // Fill the texture and sampler write image infos. + + bool write_vertex_textures = + (texture_count_vertex || sampler_count_vertex) && + !(current_graphics_descriptor_set_values_up_to_date_ & + (UINT32_C(1) << SpirvShaderTranslator::kDescriptorSetTexturesVertex)); + bool write_pixel_textures = + (texture_count_pixel || sampler_count_pixel) && + !(current_graphics_descriptor_set_values_up_to_date_ & + (UINT32_C(1) << SpirvShaderTranslator::kDescriptorSetTexturesPixel)); + descriptor_write_image_info_.clear(); + descriptor_write_image_info_.reserve( + (write_vertex_textures ? texture_count_vertex + sampler_count_vertex : 0) + + (write_pixel_textures ? texture_count_pixel + sampler_count_pixel : 0)); + size_t vertex_texture_image_info_offset = descriptor_write_image_info_.size(); + if (write_vertex_textures && texture_count_vertex) { + for (const VulkanShader::TextureBinding& texture_binding : textures_vertex) { + VkDescriptorImageInfo& descriptor_image_info = descriptor_write_image_info_.emplace_back(); + descriptor_image_info.imageView = texture_cache_->GetActiveBindingOrNullImageView( + texture_binding.fetch_constant, texture_binding.dimension, + bool(texture_binding.is_signed)); + descriptor_image_info.imageLayout = descriptor_image_info.imageView != VK_NULL_HANDLE + ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL + : VK_IMAGE_LAYOUT_UNDEFINED; + } + } + size_t vertex_sampler_image_info_offset = descriptor_write_image_info_.size(); + if (write_vertex_textures && sampler_count_vertex) { + for (const std::pair& sampler_pair : + current_samplers_vertex_) { + VkDescriptorImageInfo& descriptor_image_info = descriptor_write_image_info_.emplace_back(); + descriptor_image_info.sampler = sampler_pair.second; + } + } + size_t pixel_texture_image_info_offset = descriptor_write_image_info_.size(); + if (write_pixel_textures && texture_count_pixel) { + for (const VulkanShader::TextureBinding& texture_binding : *textures_pixel) { + VkDescriptorImageInfo& descriptor_image_info = descriptor_write_image_info_.emplace_back(); + descriptor_image_info.imageView = texture_cache_->GetActiveBindingOrNullImageView( + texture_binding.fetch_constant, texture_binding.dimension, + bool(texture_binding.is_signed)); + descriptor_image_info.imageLayout = descriptor_image_info.imageView != VK_NULL_HANDLE + ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL + : VK_IMAGE_LAYOUT_UNDEFINED; + } + } + size_t pixel_sampler_image_info_offset = descriptor_write_image_info_.size(); + if (write_pixel_textures && sampler_count_pixel) { + for (const std::pair& sampler_pair : + current_samplers_pixel_) { + VkDescriptorImageInfo& descriptor_image_info = descriptor_write_image_info_.emplace_back(); + descriptor_image_info.sampler = sampler_pair.second; + } + } + + // Write the new descriptor sets. + + // Consecutive bindings updated via a single VkWriteDescriptorSet must have + // identical stage flags, but for the constants they vary. Plus vertex and + // pixel texture images and samplers. + std::array + write_descriptor_sets; + uint32_t write_descriptor_set_count = 0; + uint32_t write_descriptor_set_bits = 0; + assert_not_zero(current_graphics_descriptor_set_values_up_to_date_ & + (UINT32_C(1) << SpirvShaderTranslator::kDescriptorSetSharedMemoryAndEdram)); + // Constant buffers. + if (!(current_graphics_descriptor_set_values_up_to_date_ & + (UINT32_C(1) << SpirvShaderTranslator::kDescriptorSetConstants))) { + VkDescriptorSet constants_descriptor_set; + if (!constants_transient_descriptors_free_.empty()) { + constants_descriptor_set = constants_transient_descriptors_free_.back(); + constants_transient_descriptors_free_.pop_back(); + } else { + VkDescriptorPoolSize constants_descriptor_count; + constants_descriptor_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + constants_descriptor_count.descriptorCount = SpirvShaderTranslator::kConstantBufferCount; + constants_descriptor_set = transient_descriptor_allocator_uniform_buffer_.Allocate( + descriptor_set_layout_constants_, &constants_descriptor_count, 1); + if (constants_descriptor_set == VK_NULL_HANDLE) { + return false; + } + } + constants_transient_descriptors_used_.emplace_back(frame_current_, constants_descriptor_set); + // Consecutive bindings updated via a single VkWriteDescriptorSet must have + // identical stage flags, but for the constants they vary. + for (uint32_t i = 0; i < SpirvShaderTranslator::kConstantBufferCount; ++i) { + VkWriteDescriptorSet& write_constants = write_descriptor_sets[write_descriptor_set_count++]; + write_constants.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_constants.pNext = nullptr; + write_constants.dstSet = constants_descriptor_set; + write_constants.dstBinding = i; + write_constants.dstArrayElement = 0; + write_constants.descriptorCount = 1; + write_constants.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + write_constants.pImageInfo = nullptr; + write_constants.pBufferInfo = ¤t_constant_buffer_infos_[i]; + write_constants.pTexelBufferView = nullptr; + } + write_descriptor_set_bits |= UINT32_C(1) << SpirvShaderTranslator::kDescriptorSetConstants; + current_graphics_descriptor_sets_[SpirvShaderTranslator::kDescriptorSetConstants] = + constants_descriptor_set; + } + // Vertex shader textures and samplers. + if (write_vertex_textures) { + VkWriteDescriptorSet* write_textures = + write_descriptor_sets.data() + write_descriptor_set_count; + uint32_t texture_descriptor_set_write_count = WriteTransientTextureBindings( + true, texture_count_vertex, sampler_count_vertex, + current_guest_graphics_pipeline_layout_->descriptor_set_layout_textures_vertex_ref(), + descriptor_write_image_info_.data() + vertex_texture_image_info_offset, + descriptor_write_image_info_.data() + vertex_sampler_image_info_offset, write_textures); + if (!texture_descriptor_set_write_count) { + return false; + } + write_descriptor_set_count += texture_descriptor_set_write_count; + write_descriptor_set_bits |= UINT32_C(1) << SpirvShaderTranslator::kDescriptorSetTexturesVertex; + current_graphics_descriptor_sets_[SpirvShaderTranslator::kDescriptorSetTexturesVertex] = + write_textures[0].dstSet; + } + // Pixel shader textures and samplers. + if (write_pixel_textures) { + VkWriteDescriptorSet* write_textures = + write_descriptor_sets.data() + write_descriptor_set_count; + uint32_t texture_descriptor_set_write_count = WriteTransientTextureBindings( + false, texture_count_pixel, sampler_count_pixel, + current_guest_graphics_pipeline_layout_->descriptor_set_layout_textures_pixel_ref(), + descriptor_write_image_info_.data() + pixel_texture_image_info_offset, + descriptor_write_image_info_.data() + pixel_sampler_image_info_offset, write_textures); + if (!texture_descriptor_set_write_count) { + return false; + } + write_descriptor_set_count += texture_descriptor_set_write_count; + write_descriptor_set_bits |= UINT32_C(1) << SpirvShaderTranslator::kDescriptorSetTexturesPixel; + current_graphics_descriptor_sets_[SpirvShaderTranslator::kDescriptorSetTexturesPixel] = + write_textures[0].dstSet; + } + // Write. + if (write_descriptor_set_count) { + dfn.vkUpdateDescriptorSets(device, write_descriptor_set_count, write_descriptor_sets.data(), 0, + nullptr); + } + // Only make valid if all descriptor sets have been allocated and written + // successfully. + current_graphics_descriptor_set_values_up_to_date_ |= write_descriptor_set_bits; + + // Bind the new descriptor sets. + uint32_t descriptor_sets_needed = (UINT32_C(1) << SpirvShaderTranslator::kDescriptorSetCount) - 1; + if (!texture_count_vertex && !sampler_count_vertex) { + descriptor_sets_needed &= ~(UINT32_C(1) << SpirvShaderTranslator::kDescriptorSetTexturesVertex); + } + if (!texture_count_pixel && !sampler_count_pixel) { + descriptor_sets_needed &= ~(UINT32_C(1) << SpirvShaderTranslator::kDescriptorSetTexturesPixel); + } + uint32_t descriptor_sets_remaining = + descriptor_sets_needed & ~current_graphics_descriptor_sets_bound_up_to_date_; + uint32_t descriptor_set_index; + while (rex::bit_scan_forward(descriptor_sets_remaining, &descriptor_set_index)) { + uint32_t descriptor_set_mask_tzcnt = + rex::tzcnt(~(descriptor_sets_remaining | ((UINT32_C(1) << descriptor_set_index) - 1))); + deferred_command_buffer_.CmdVkBindDescriptorSets( + VK_PIPELINE_BIND_POINT_GRAPHICS, + current_guest_graphics_pipeline_layout_->GetPipelineLayout(), descriptor_set_index, + descriptor_set_mask_tzcnt - descriptor_set_index, + current_graphics_descriptor_sets_ + descriptor_set_index, 0, nullptr); + if (descriptor_set_mask_tzcnt >= 32) { + break; + } + descriptor_sets_remaining &= ~((UINT32_C(1) << descriptor_set_mask_tzcnt) - 1); + } + current_graphics_descriptor_sets_bound_up_to_date_ |= descriptor_sets_needed; + + return true; +} + +uint32_t VulkanCommandProcessor::WriteTransientTextureBindings( + bool is_vertex, uint32_t texture_count, uint32_t sampler_count, + VkDescriptorSetLayout descriptor_set_layout, const VkDescriptorImageInfo* texture_image_info, + const VkDescriptorImageInfo* sampler_image_info, + VkWriteDescriptorSet* descriptor_set_writes_out) { + assert_true(frame_open_); + if (!texture_count && !sampler_count) { + return 0; + } + TextureDescriptorSetLayoutKey texture_descriptor_set_layout_key; + texture_descriptor_set_layout_key.texture_count = texture_count; + texture_descriptor_set_layout_key.sampler_count = sampler_count; + texture_descriptor_set_layout_key.is_vertex = uint32_t(is_vertex); + VkDescriptorSet texture_descriptor_set; + auto textures_free_it = + texture_transient_descriptor_sets_free_.find(texture_descriptor_set_layout_key); + if (textures_free_it != texture_transient_descriptor_sets_free_.end() && + !textures_free_it->second.empty()) { + texture_descriptor_set = textures_free_it->second.back(); + textures_free_it->second.pop_back(); + } else { + std::array texture_descriptor_counts; + uint32_t texture_descriptor_counts_count = 0; + if (texture_count) { + VkDescriptorPoolSize& texture_descriptor_count = + texture_descriptor_counts[texture_descriptor_counts_count++]; + texture_descriptor_count.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + texture_descriptor_count.descriptorCount = texture_count; + } + if (sampler_count) { + VkDescriptorPoolSize& texture_descriptor_count = + texture_descriptor_counts[texture_descriptor_counts_count++]; + texture_descriptor_count.type = VK_DESCRIPTOR_TYPE_SAMPLER; + texture_descriptor_count.descriptorCount = sampler_count; + } + assert_not_zero(texture_descriptor_counts_count); + texture_descriptor_set = transient_descriptor_allocator_textures_.Allocate( + descriptor_set_layout, texture_descriptor_counts.data(), texture_descriptor_counts_count); + if (texture_descriptor_set == VK_NULL_HANDLE) { + return 0; + } + } + UsedTextureTransientDescriptorSet& used_texture_descriptor_set = + texture_transient_descriptor_sets_used_.emplace_back(); + used_texture_descriptor_set.frame = frame_current_; + used_texture_descriptor_set.layout = texture_descriptor_set_layout_key; + used_texture_descriptor_set.set = texture_descriptor_set; + uint32_t descriptor_set_write_count = 0; + if (texture_count) { + VkWriteDescriptorSet& descriptor_set_write = + descriptor_set_writes_out[descriptor_set_write_count++]; + descriptor_set_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptor_set_write.pNext = nullptr; + descriptor_set_write.dstSet = texture_descriptor_set; + descriptor_set_write.dstBinding = 0; + descriptor_set_write.dstArrayElement = 0; + descriptor_set_write.descriptorCount = texture_count; + descriptor_set_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + descriptor_set_write.pImageInfo = texture_image_info; + descriptor_set_write.pBufferInfo = nullptr; + descriptor_set_write.pTexelBufferView = nullptr; + } + if (sampler_count) { + VkWriteDescriptorSet& descriptor_set_write = + descriptor_set_writes_out[descriptor_set_write_count++]; + descriptor_set_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptor_set_write.pNext = nullptr; + descriptor_set_write.dstSet = texture_descriptor_set; + descriptor_set_write.dstBinding = texture_count; + descriptor_set_write.dstArrayElement = 0; + descriptor_set_write.descriptorCount = sampler_count; + descriptor_set_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; + descriptor_set_write.pImageInfo = sampler_image_info; + descriptor_set_write.pBufferInfo = nullptr; + descriptor_set_write.pTexelBufferView = nullptr; + } + assert_not_zero(descriptor_set_write_count); + return descriptor_set_write_count; +} + +} // namespace rex::graphics::vulkan diff --git a/src/graphics/vulkan/deferred_command_buffer.cpp b/src/graphics/vulkan/deferred_command_buffer.cpp new file mode 100644 index 0000000..b49e033 --- /dev/null +++ b/src/graphics/vulkan/deferred_command_buffer.cpp @@ -0,0 +1,427 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace rex::graphics::vulkan { + +DeferredCommandBuffer::DeferredCommandBuffer(const VulkanCommandProcessor& command_processor, + size_t initial_size) + : command_processor_(command_processor) { + command_stream_.reserve(initial_size / sizeof(uintmax_t)); +} + +void DeferredCommandBuffer::Reset() { + command_stream_.clear(); +} + +void DeferredCommandBuffer::Execute(VkCommandBuffer command_buffer) { +#if XE_GPU_FINE_GRAINED_DRAW_SCOPES + SCOPE_profile_cpu_f("gpu"); +#endif // XE_GPU_FINE_GRAINED_DRAW_SCOPES + + const ui::vulkan::VulkanDevice::Functions& dfn = + command_processor_.GetVulkanDevice()->functions(); + const uintmax_t* stream = command_stream_.data(); + size_t stream_remaining = command_stream_.size(); + while (stream_remaining) { + const CommandHeader& header = *reinterpret_cast(stream); + stream += kCommandHeaderSizeElements; + stream_remaining -= kCommandHeaderSizeElements; + + switch (header.command) { + case Command::kVkBeginRenderPass: { + auto& args = *reinterpret_cast(stream); + size_t offset_bytes = sizeof(ArgsVkBeginRenderPass); + VkRenderPassBeginInfo render_pass_begin_info; + render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + render_pass_begin_info.pNext = nullptr; + render_pass_begin_info.renderPass = args.render_pass; + render_pass_begin_info.framebuffer = args.framebuffer; + render_pass_begin_info.renderArea = args.render_area; + render_pass_begin_info.clearValueCount = args.clear_value_count; + if (render_pass_begin_info.clearValueCount) { + offset_bytes = rex::align(offset_bytes, alignof(VkClearValue)); + render_pass_begin_info.pClearValues = reinterpret_cast( + reinterpret_cast(stream) + offset_bytes); + offset_bytes += sizeof(VkClearValue) * render_pass_begin_info.clearValueCount; + } else { + render_pass_begin_info.pClearValues = nullptr; + } + dfn.vkCmdBeginRenderPass(command_buffer, &render_pass_begin_info, args.contents); + } break; + + case Command::kVkBeginQuery: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdBeginQuery(command_buffer, args.query_pool, args.query, args.flags); + } break; + + case Command::kVkBindDescriptorSets: { + auto& args = *reinterpret_cast(stream); + size_t offset_bytes = + rex::align(sizeof(ArgsVkBindDescriptorSets), alignof(VkDescriptorSet)); + const VkDescriptorSet* descriptor_sets = reinterpret_cast( + reinterpret_cast(stream) + offset_bytes); + offset_bytes += sizeof(VkDescriptorSet) * args.descriptor_set_count; + const uint32_t* dynamic_offsets = nullptr; + if (args.dynamic_offset_count) { + offset_bytes = rex::align(offset_bytes, alignof(uint32_t)); + dynamic_offsets = reinterpret_cast( + reinterpret_cast(stream) + offset_bytes); + offset_bytes += sizeof(uint32_t) * args.dynamic_offset_count; + } + dfn.vkCmdBindDescriptorSets(command_buffer, args.pipeline_bind_point, args.layout, + args.first_set, args.descriptor_set_count, descriptor_sets, + args.dynamic_offset_count, dynamic_offsets); + } break; + + case Command::kVkBindIndexBuffer: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdBindIndexBuffer(command_buffer, args.buffer, args.offset, args.index_type); + } break; + + case Command::kVkBindPipeline: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdBindPipeline(command_buffer, args.pipeline_bind_point, args.pipeline); + } break; + + case Command::kVkBindVertexBuffers: { + auto& args = *reinterpret_cast(stream); + size_t offset_bytes = rex::align(sizeof(ArgsVkBindVertexBuffers), alignof(VkBuffer)); + const VkBuffer* buffers = reinterpret_cast( + reinterpret_cast(stream) + offset_bytes); + offset_bytes = + rex::align(offset_bytes + sizeof(VkBuffer) * args.binding_count, alignof(VkDeviceSize)); + const VkDeviceSize* offsets = reinterpret_cast( + reinterpret_cast(stream) + offset_bytes); + dfn.vkCmdBindVertexBuffers(command_buffer, args.first_binding, args.binding_count, buffers, + offsets); + } break; + + case Command::kVkClearAttachments: { + auto& args = *reinterpret_cast(stream); + size_t offset_bytes = + rex::align(sizeof(ArgsVkClearAttachments), alignof(VkClearAttachment)); + const VkClearAttachment* attachments = reinterpret_cast( + reinterpret_cast(stream) + offset_bytes); + offset_bytes = rex::align(offset_bytes + sizeof(VkClearAttachment) * args.attachment_count, + alignof(VkClearRect)); + const VkClearRect* rects = reinterpret_cast( + reinterpret_cast(stream) + offset_bytes); + dfn.vkCmdClearAttachments(command_buffer, args.attachment_count, attachments, + args.rect_count, rects); + } break; + + case Command::kVkClearColorImage: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdClearColorImage( + command_buffer, args.image, args.image_layout, &args.color, args.range_count, + reinterpret_cast( + reinterpret_cast(stream) + + rex::align(sizeof(ArgsVkClearColorImage), alignof(VkImageSubresourceRange)))); + } break; + + case Command::kVkCopyBuffer: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdCopyBuffer(command_buffer, args.src_buffer, args.dst_buffer, args.region_count, + reinterpret_cast( + reinterpret_cast(stream) + + rex::align(sizeof(ArgsVkCopyBuffer), alignof(VkBufferCopy)))); + } break; + + case Command::kVkCopyBufferToImage: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdCopyBufferToImage( + command_buffer, args.src_buffer, args.dst_image, args.dst_image_layout, + args.region_count, + reinterpret_cast( + reinterpret_cast(stream) + + rex::align(sizeof(ArgsVkCopyBufferToImage), alignof(VkBufferImageCopy)))); + } break; + + case Command::kVkCopyQueryPoolResults: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdCopyQueryPoolResults(command_buffer, args.query_pool, args.first_query, + args.query_count, args.dst_buffer, args.dst_offset, + args.stride, args.flags); + } break; + + case Command::kVkDispatch: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdDispatch(command_buffer, args.group_count_x, args.group_count_y, + args.group_count_z); + } break; + + case Command::kVkDraw: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdDraw(command_buffer, args.vertex_count, args.instance_count, args.first_vertex, + args.first_instance); + } break; + + case Command::kVkDrawIndexed: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdDrawIndexed(command_buffer, args.index_count, args.instance_count, + args.first_index, args.vertex_offset, args.first_instance); + } break; + + case Command::kVkEndQuery: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdEndQuery(command_buffer, args.query_pool, args.query); + } break; + + case Command::kVkEndRenderPass: + dfn.vkCmdEndRenderPass(command_buffer); + break; + + case Command::kVkBeginRendering: { + auto& args = *reinterpret_cast(stream); + size_t offset_bytes = + rex::align(sizeof(ArgsVkBeginRendering), alignof(VkRenderingAttachmentInfo)); + const VkRenderingAttachmentInfo* color_attachments = + args.color_attachment_count + ? reinterpret_cast( + reinterpret_cast(stream) + offset_bytes) + : nullptr; + offset_bytes += sizeof(VkRenderingAttachmentInfo) * args.color_attachment_count; + const VkRenderingAttachmentInfo* depth_attachment = + args.has_depth_attachment ? reinterpret_cast( + reinterpret_cast(stream) + offset_bytes) + : nullptr; + if (args.has_depth_attachment) { + offset_bytes += sizeof(VkRenderingAttachmentInfo); + } + const VkRenderingAttachmentInfo* stencil_attachment = + args.has_stencil_attachment + ? reinterpret_cast( + reinterpret_cast(stream) + offset_bytes) + : nullptr; + VkRenderingInfo rendering_info = {}; + rendering_info.sType = VK_STRUCTURE_TYPE_RENDERING_INFO; + rendering_info.flags = args.flags; + rendering_info.renderArea = args.render_area; + rendering_info.layerCount = args.layer_count; + rendering_info.viewMask = args.view_mask; + rendering_info.colorAttachmentCount = args.color_attachment_count; + rendering_info.pColorAttachments = color_attachments; + rendering_info.pDepthAttachment = depth_attachment; + rendering_info.pStencilAttachment = stencil_attachment; + dfn.vkCmdBeginRendering(command_buffer, &rendering_info); + } break; + + case Command::kVkEndRendering: + dfn.vkCmdEndRendering(command_buffer); + break; + + case Command::kVkPipelineBarrier: { + auto& args = *reinterpret_cast(stream); + size_t barrier_offset_bytes = sizeof(ArgsVkPipelineBarrier); + const VkMemoryBarrier* memory_barriers = nullptr; + if (args.memory_barrier_count) { + barrier_offset_bytes = rex::align(barrier_offset_bytes, alignof(VkMemoryBarrier)); + memory_barriers = reinterpret_cast( + reinterpret_cast(stream) + barrier_offset_bytes); + barrier_offset_bytes += sizeof(VkMemoryBarrier) * args.memory_barrier_count; + } + const VkBufferMemoryBarrier* buffer_memory_barriers = nullptr; + if (args.buffer_memory_barrier_count) { + barrier_offset_bytes = rex::align(barrier_offset_bytes, alignof(VkBufferMemoryBarrier)); + buffer_memory_barriers = reinterpret_cast( + reinterpret_cast(stream) + barrier_offset_bytes); + barrier_offset_bytes += sizeof(VkBufferMemoryBarrier) * args.buffer_memory_barrier_count; + } + const VkImageMemoryBarrier* image_memory_barriers = nullptr; + if (args.image_memory_barrier_count) { + barrier_offset_bytes = rex::align(barrier_offset_bytes, alignof(VkImageMemoryBarrier)); + image_memory_barriers = reinterpret_cast( + reinterpret_cast(stream) + barrier_offset_bytes); + barrier_offset_bytes += sizeof(VkImageMemoryBarrier) * args.image_memory_barrier_count; + } + dfn.vkCmdPipelineBarrier(command_buffer, args.src_stage_mask, args.dst_stage_mask, + args.dependency_flags, args.memory_barrier_count, memory_barriers, + args.buffer_memory_barrier_count, buffer_memory_barriers, + args.image_memory_barrier_count, image_memory_barriers); + } break; + + case Command::kVkPushConstants: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdPushConstants( + command_buffer, args.layout, args.stage_flags, args.offset, args.size, + reinterpret_cast(stream) + sizeof(ArgsVkPushConstants)); + } break; + + case Command::kVkResetQueryPool: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdResetQueryPool(command_buffer, args.query_pool, args.first_query, + args.query_count); + } break; + + case Command::kVkSetBlendConstants: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdSetBlendConstants(command_buffer, args.blend_constants); + } break; + + case Command::kVkSetDepthBias: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdSetDepthBias(command_buffer, args.depth_bias_constant_factor, + args.depth_bias_clamp, args.depth_bias_slope_factor); + } break; + + case Command::kVkSetScissor: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdSetScissor(command_buffer, args.first_scissor, args.scissor_count, + reinterpret_cast( + reinterpret_cast(stream) + + rex::align(sizeof(ArgsVkSetScissor), alignof(VkRect2D)))); + } break; + + case Command::kVkSetStencilCompareMask: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdSetStencilCompareMask(command_buffer, args.face_mask, args.mask_reference); + } break; + + case Command::kVkSetStencilReference: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdSetStencilReference(command_buffer, args.face_mask, args.mask_reference); + } break; + + case Command::kVkSetStencilWriteMask: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdSetStencilWriteMask(command_buffer, args.face_mask, args.mask_reference); + } break; + + case Command::kVkSetViewport: { + auto& args = *reinterpret_cast(stream); + dfn.vkCmdSetViewport(command_buffer, args.first_viewport, args.viewport_count, + reinterpret_cast( + reinterpret_cast(stream) + + rex::align(sizeof(ArgsVkSetViewport), alignof(VkViewport)))); + } break; + + default: + assert_unhandled_case(header.command); + break; + } + + stream += header.arguments_size_elements; + stream_remaining -= header.arguments_size_elements; + } +} + +void DeferredCommandBuffer::CmdVkPipelineBarrier( + VkPipelineStageFlags src_stage_mask, VkPipelineStageFlags dst_stage_mask, + VkDependencyFlags dependency_flags, uint32_t memory_barrier_count, + const VkMemoryBarrier* memory_barriers, uint32_t buffer_memory_barrier_count, + const VkBufferMemoryBarrier* buffer_memory_barriers, uint32_t image_memory_barrier_count, + const VkImageMemoryBarrier* image_memory_barriers) { + size_t arguments_size = sizeof(ArgsVkPipelineBarrier); + size_t memory_barriers_offset = 0; + if (memory_barrier_count) { + arguments_size = rex::align(arguments_size, alignof(VkMemoryBarrier)); + memory_barriers_offset = arguments_size; + arguments_size += sizeof(VkMemoryBarrier) * memory_barrier_count; + } + size_t buffer_memory_barriers_offset = 0; + if (buffer_memory_barrier_count) { + arguments_size = rex::align(arguments_size, alignof(VkBufferMemoryBarrier)); + buffer_memory_barriers_offset = arguments_size; + arguments_size += sizeof(VkBufferMemoryBarrier) * buffer_memory_barrier_count; + } + size_t image_memory_barriers_offset = 0; + if (image_memory_barrier_count) { + arguments_size = rex::align(arguments_size, alignof(VkImageMemoryBarrier)); + image_memory_barriers_offset = arguments_size; + arguments_size += sizeof(VkImageMemoryBarrier) * image_memory_barrier_count; + } + uint8_t* args_ptr = + reinterpret_cast(WriteCommand(Command::kVkPipelineBarrier, arguments_size)); + auto& args = *reinterpret_cast(args_ptr); + args.src_stage_mask = src_stage_mask; + args.dst_stage_mask = dst_stage_mask; + args.dependency_flags = dependency_flags; + args.memory_barrier_count = memory_barrier_count; + args.buffer_memory_barrier_count = buffer_memory_barrier_count; + args.image_memory_barrier_count = image_memory_barrier_count; + if (memory_barrier_count) { + std::memcpy(args_ptr + memory_barriers_offset, memory_barriers, + sizeof(VkMemoryBarrier) * memory_barrier_count); + } + if (buffer_memory_barrier_count) { + std::memcpy(args_ptr + buffer_memory_barriers_offset, buffer_memory_barriers, + sizeof(VkBufferMemoryBarrier) * buffer_memory_barrier_count); + } + if (image_memory_barrier_count) { + std::memcpy(args_ptr + image_memory_barriers_offset, image_memory_barriers, + sizeof(VkImageMemoryBarrier) * image_memory_barrier_count); + } +} + +void DeferredCommandBuffer::CmdVkBeginRendering(const VkRenderingInfo* rendering_info) { + assert_null(rendering_info->pNext); + + size_t arguments_size = + rex::align(sizeof(ArgsVkBeginRendering), alignof(VkRenderingAttachmentInfo)); + size_t color_attachments_offset = arguments_size; + arguments_size += sizeof(VkRenderingAttachmentInfo) * rendering_info->colorAttachmentCount; + size_t depth_attachment_offset = arguments_size; + if (rendering_info->pDepthAttachment) { + arguments_size += sizeof(VkRenderingAttachmentInfo); + } + size_t stencil_attachment_offset = arguments_size; + if (rendering_info->pStencilAttachment) { + arguments_size += sizeof(VkRenderingAttachmentInfo); + } + + uint8_t* args_ptr = + reinterpret_cast(WriteCommand(Command::kVkBeginRendering, arguments_size)); + auto& args = *reinterpret_cast(args_ptr); + args.flags = rendering_info->flags; + args.render_area = rendering_info->renderArea; + args.layer_count = rendering_info->layerCount; + args.view_mask = rendering_info->viewMask; + args.color_attachment_count = rendering_info->colorAttachmentCount; + args.has_depth_attachment = rendering_info->pDepthAttachment != nullptr; + args.has_stencil_attachment = rendering_info->pStencilAttachment != nullptr; + + if (rendering_info->colorAttachmentCount) { + std::memcpy(args_ptr + color_attachments_offset, rendering_info->pColorAttachments, + sizeof(VkRenderingAttachmentInfo) * rendering_info->colorAttachmentCount); + } + if (rendering_info->pDepthAttachment) { + std::memcpy(args_ptr + depth_attachment_offset, rendering_info->pDepthAttachment, + sizeof(VkRenderingAttachmentInfo)); + } + if (rendering_info->pStencilAttachment) { + std::memcpy(args_ptr + stencil_attachment_offset, rendering_info->pStencilAttachment, + sizeof(VkRenderingAttachmentInfo)); + } +} + +void* DeferredCommandBuffer::WriteCommand(Command command, size_t arguments_size_bytes) { + size_t arguments_size_elements = + (arguments_size_bytes + sizeof(uintmax_t) - 1) / sizeof(uintmax_t); + size_t offset = command_stream_.size(); + command_stream_.resize(offset + kCommandHeaderSizeElements + arguments_size_elements); + CommandHeader& header = *reinterpret_cast(command_stream_.data() + offset); + header.command = command; + header.arguments_size_elements = uint32_t(arguments_size_elements); + return command_stream_.data() + (offset + kCommandHeaderSizeElements); +} + +} // namespace rex::graphics::vulkan diff --git a/src/graphics/vulkan/graphics_system.cpp b/src/graphics/vulkan/graphics_system.cpp new file mode 100644 index 0000000..df3f98f --- /dev/null +++ b/src/graphics/vulkan/graphics_system.cpp @@ -0,0 +1,35 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +namespace rex::graphics::vulkan { + +VulkanGraphicsSystem::VulkanGraphicsSystem() {} + +VulkanGraphicsSystem::~VulkanGraphicsSystem() {} + +std::string VulkanGraphicsSystem::name() const { + return "Vulkan"; +} + +void VulkanGraphicsSystem::CreateProvider(bool with_presentation) { + provider_ = rex::ui::vulkan::VulkanProvider::Create(true, with_presentation); +} + +std::unique_ptr VulkanGraphicsSystem::CreateCommandProcessor() { + return std::make_unique(this, kernel_state_); +} + +} // namespace rex::graphics::vulkan diff --git a/src/graphics/vulkan/pipeline_cache.cpp b/src/graphics/vulkan/pipeline_cache.cpp new file mode 100644 index 0000000..91ac08f --- /dev/null +++ b/src/graphics/vulkan/pipeline_cache.cpp @@ -0,0 +1,3702 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_INT32( + vulkan_pipeline_creation_threads, -1, "GPU/Vulkan", + "Number of pipeline creation threads for Vulkan async pipeline creation (-1 for auto)") + .range(-1, 32) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_BOOL(vulkan_tessellation_wireframe, false, "GPU/Vulkan", + "Render tessellation as wireframe") + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +namespace rex::graphics::vulkan { + +namespace { + +constexpr std::string_view kPlaceholderPixelShaderSource = R"(#version 460 +layout(location = 0) out vec4 oC0; +void main() { + // Avoid full-screen black flashes while async pipelines are warming up. + discard; +} +)"; + +constexpr bool IsTriangleDomainHostVertexShaderType( + Shader::HostVertexShaderType host_vertex_shader_type) { + return host_vertex_shader_type == Shader::HostVertexShaderType::kTriangleDomainCPIndexed || + host_vertex_shader_type == Shader::HostVertexShaderType::kTriangleDomainPatchIndexed; +} + +constexpr bool IsQuadDomainHostVertexShaderType( + Shader::HostVertexShaderType host_vertex_shader_type) { + return host_vertex_shader_type == Shader::HostVertexShaderType::kQuadDomainCPIndexed || + host_vertex_shader_type == Shader::HostVertexShaderType::kQuadDomainPatchIndexed; +} + +constexpr bool IsPatchIndexedHostVertexShaderType( + Shader::HostVertexShaderType host_vertex_shader_type) { + return host_vertex_shader_type == Shader::HostVertexShaderType::kTriangleDomainPatchIndexed || + host_vertex_shader_type == Shader::HostVertexShaderType::kQuadDomainPatchIndexed; +} + +std::string GetTessellationSystemConstantsBlockGlsl() { + std::string source; + source += "layout(set = 0, binding = 0, std140) uniform XeSystemConstants {\n"; + source += fmt::format(" layout(offset = {}) uint xe_vertex_index_endian;\n", + offsetof(SpirvShaderTranslator::SystemConstants, vertex_index_endian)); + source += fmt::format(" layout(offset = {}) int xe_vertex_base_index;\n", + offsetof(SpirvShaderTranslator::SystemConstants, vertex_base_index)); + source += fmt::format(" layout(offset = {}) uint xe_vertex_index_min;\n", + offsetof(SpirvShaderTranslator::SystemConstants, vertex_index_min)); + source += fmt::format(" layout(offset = {}) uint xe_vertex_index_max;\n", + offsetof(SpirvShaderTranslator::SystemConstants, vertex_index_max)); + source += + fmt::format(" layout(offset = {}) float xe_tessellation_factor_range_min;\n", + offsetof(SpirvShaderTranslator::SystemConstants, tessellation_factor_range_min)); + source += + fmt::format(" layout(offset = {}) float xe_tessellation_factor_range_max;\n", + offsetof(SpirvShaderTranslator::SystemConstants, tessellation_factor_range_max)); + source += "} xe_system_cbuffer;\n"; + return source; +} + +std::string GetTessellationIndexedVertexShaderGlsl() { + std::string source; + source += "#version 450\n"; + source += GetTessellationSystemConstantsBlockGlsl(); + source += R"( +layout(location = 0) out float xe_out_value; + +uint xe_swap_8_in_16(uint value) { + return ((value << 8u) & 0xFF00FF00u) | ((value >> 8u) & 0x00FF00FFu); +} + +uint xe_swap_16_in_32(uint value) { + return ((value & 0x0000FFFFu) << 16u) | (value >> 16u); +} + +void main() { + uint value = uint(gl_VertexIndex); + uint endian = xe_system_cbuffer.xe_vertex_index_endian; + if (endian == 1u || endian == 2u || endian == 3u) { + value = xe_swap_8_in_16(value); + } + if (endian == 2u || endian == 3u) { + value = xe_swap_16_in_32(value); + } + value = uint(int(value) + xe_system_cbuffer.xe_vertex_base_index); + value &= 0x00FFFFFFu; + value = max(value, xe_system_cbuffer.xe_vertex_index_min); + value = min(value, xe_system_cbuffer.xe_vertex_index_max); + xe_out_value = float(value); +} +)"; + return source; +} + +std::string GetTessellationAdaptiveVertexShaderGlsl() { + std::string source; + source += "#version 450\n"; + source += GetTessellationSystemConstantsBlockGlsl(); + source += R"( +layout(location = 0) out float xe_out_value; + +uint xe_swap_8_in_16(uint value) { + return ((value << 8u) & 0xFF00FF00u) | ((value >> 8u) & 0x00FF00FFu); +} + +uint xe_swap_16_in_32(uint value) { + return ((value & 0x0000FFFFu) << 16u) | (value >> 16u); +} + +void main() { + uint value = uint(gl_VertexIndex); + uint endian = xe_system_cbuffer.xe_vertex_index_endian; + if (endian == 1u || endian == 2u || endian == 3u) { + value = xe_swap_8_in_16(value); + } + if (endian == 2u || endian == 3u) { + value = xe_swap_16_in_32(value); + } + float tessellation_factor = float(value) + 1.0; + tessellation_factor = max( + tessellation_factor, xe_system_cbuffer.xe_tessellation_factor_range_min); + tessellation_factor = min( + tessellation_factor, xe_system_cbuffer.xe_tessellation_factor_range_max); + xe_out_value = tessellation_factor; +} +)"; + return source; +} + +std::string GetTessellationControlShaderGlsl(Shader::HostVertexShaderType host_vertex_shader_type, + xenos::TessellationMode tessellation_mode, + uint32_t input_control_points, + uint32_t output_control_points) { + std::string source; + source += "#version 450\n"; + source += GetTessellationSystemConstantsBlockGlsl(); + source += "layout(location = 0) in float xe_input_value[];\n"; + source += "layout(location = 0) patch out vec4 xe_out_patch_control_point_indices;\n"; + // In GLSL, primitive mode / spacing / winding are TES layout qualifiers. + // TCS only supports `layout(vertices = N) out`. + source += fmt::format("layout(vertices = {}) out;\n", output_control_points); + + source += R"( +void main() { + gl_out[gl_InvocationID].gl_Position = vec4(0.0); + if (gl_InvocationID != 0u) { + return; + } + + vec4 patch_control_point_indices = vec4(0.0); +)"; + if (tessellation_mode == xenos::TessellationMode::kAdaptive) { + source += R"( + uint patch_index = uint(int(gl_PrimitiveID) + xe_system_cbuffer.xe_vertex_base_index); + patch_index &= 0x00FFFFFFu; + patch_index = max(patch_index, xe_system_cbuffer.xe_vertex_index_min); + patch_index = min(patch_index, xe_system_cbuffer.xe_vertex_index_max); + patch_control_point_indices.x = float(patch_index); +)"; + if (IsTriangleDomainHostVertexShaderType(host_vertex_shader_type)) { + source += R"( + gl_TessLevelOuter[0] = xe_input_value[1]; + gl_TessLevelOuter[1] = xe_input_value[2]; + gl_TessLevelOuter[2] = xe_input_value[0]; + gl_TessLevelInner[0] = min(min(xe_input_value[2], xe_input_value[1]), + xe_input_value[0]); +)"; + } else { + source += R"( + gl_TessLevelOuter[0] = xe_input_value[3]; + gl_TessLevelOuter[1] = xe_input_value[0]; + gl_TessLevelOuter[2] = xe_input_value[1]; + gl_TessLevelOuter[3] = xe_input_value[2]; + gl_TessLevelInner[0] = min(xe_input_value[2], xe_input_value[0]); + gl_TessLevelInner[1] = min(xe_input_value[1], xe_input_value[3]); +)"; + } + } else { + if (IsPatchIndexedHostVertexShaderType(host_vertex_shader_type)) { + source += " patch_control_point_indices.x = xe_input_value[0];\n"; + } else { + source += " patch_control_point_indices.x = xe_input_value[0];\n"; + if (input_control_points >= 2) { + source += " patch_control_point_indices.y = xe_input_value[1];\n"; + } + if (input_control_points >= 3) { + source += " patch_control_point_indices.z = xe_input_value[2];\n"; + } + if (input_control_points >= 4) { + source += " patch_control_point_indices.w = xe_input_value[3];\n"; + } + } + source += R"( + float tessellation_factor = xe_system_cbuffer.xe_tessellation_factor_range_max; +)"; + if (IsTriangleDomainHostVertexShaderType(host_vertex_shader_type)) { + source += R"( + gl_TessLevelOuter[0] = tessellation_factor; + gl_TessLevelOuter[1] = tessellation_factor; + gl_TessLevelOuter[2] = tessellation_factor; + gl_TessLevelInner[0] = tessellation_factor; +)"; + } else { + source += R"( + gl_TessLevelOuter[0] = tessellation_factor; + gl_TessLevelOuter[1] = tessellation_factor; + gl_TessLevelOuter[2] = tessellation_factor; + gl_TessLevelOuter[3] = tessellation_factor; + gl_TessLevelInner[0] = tessellation_factor; + gl_TessLevelInner[1] = tessellation_factor; +)"; + } + } + source += R"( + xe_out_patch_control_point_indices = patch_control_point_indices; +} +)"; + return source; +} + +} // namespace + +VulkanPipelineCache::VulkanPipelineCache(VulkanCommandProcessor& command_processor, + const RegisterFile& register_file, + VulkanRenderTargetCache& render_target_cache, + VkShaderStageFlags guest_shader_vertex_stages) + : command_processor_(command_processor), + register_file_(register_file), + render_target_cache_(render_target_cache), + guest_shader_vertex_stages_(guest_shader_vertex_stages) {} + +VulkanPipelineCache::~VulkanPipelineCache() { + Shutdown(); +} + +bool VulkanPipelineCache::Initialize() { + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + + bool edram_fragment_shader_interlock = + render_target_cache_.GetPath() == RenderTargetCache::Path::kPixelShaderInterlock; + + shader_translator_ = std::make_unique( + SpirvShaderTranslator::Features(vulkan_device), + render_target_cache_.msaa_2x_attachments_supported(), + render_target_cache_.msaa_2x_no_attachments_supported(), edram_fragment_shader_interlock, + render_target_cache_.draw_resolution_scale_x(), + render_target_cache_.draw_resolution_scale_y()); + + if (edram_fragment_shader_interlock) { + std::vector depth_only_fragment_shader_code = + shader_translator_->CreateDepthOnlyFragmentShader(); + depth_only_fragment_shader_ = ui::vulkan::util::CreateShaderModule( + vulkan_device, reinterpret_cast(depth_only_fragment_shader_code.data()), + depth_only_fragment_shader_code.size()); + if (depth_only_fragment_shader_ == VK_NULL_HANDLE) { + REXGPU_ERROR( + "VulkanPipelineCache: Failed to create the depth/stencil-only " + "fragment shader for the fragment shader interlock render backend " + "implementation"); + return false; + } + } else { + std::vector depth_float24_truncate_fragment_shader_code = + shader_translator_->CreateDepthOnlyFragmentShader( + SpirvShaderTranslator::Modification::DepthStencilMode::kFloat24Truncating); + depth_float24_truncate_fragment_shader_ = ui::vulkan::util::CreateShaderModule( + vulkan_device, + reinterpret_cast(depth_float24_truncate_fragment_shader_code.data()), + depth_float24_truncate_fragment_shader_code.size()); + if (depth_float24_truncate_fragment_shader_ == VK_NULL_HANDLE) { + REXGPU_ERROR( + "VulkanPipelineCache: Failed to create the float24 truncating " + "depth-only fragment shader"); + return false; + } + std::vector depth_float24_round_fragment_shader_code = + shader_translator_->CreateDepthOnlyFragmentShader( + SpirvShaderTranslator::Modification::DepthStencilMode::kFloat24Rounding); + depth_float24_round_fragment_shader_ = ui::vulkan::util::CreateShaderModule( + vulkan_device, + reinterpret_cast(depth_float24_round_fragment_shader_code.data()), + depth_float24_round_fragment_shader_code.size()); + if (depth_float24_round_fragment_shader_ == VK_NULL_HANDLE) { + REXGPU_ERROR( + "VulkanPipelineCache: Failed to create the float24 rounding " + "depth-only fragment shader"); + return false; + } + } + + std::vector placeholder_pixel_shader_spirv; + std::string placeholder_pixel_shader_compile_error; + if (command_processor_.CompileGlslToSpirv( + VK_SHADER_STAGE_FRAGMENT_BIT, kPlaceholderPixelShaderSource, + placeholder_pixel_shader_spirv, placeholder_pixel_shader_compile_error)) { + placeholder_pixel_shader_ = ui::vulkan::util::CreateShaderModule( + vulkan_device, placeholder_pixel_shader_spirv.data(), + placeholder_pixel_shader_spirv.size() * sizeof(uint32_t)); + } else { + REXGPU_WARN("VulkanPipelineCache: Failed to compile placeholder pixel shader: {}", + placeholder_pixel_shader_compile_error); + } + if (placeholder_pixel_shader_ == VK_NULL_HANDLE) { + REXGPU_WARN( + "VulkanPipelineCache: Failed to create placeholder pixel shader - " + "async placeholder hot-swap will be unavailable"); + } + + uint32_t logical_processor_count = rex::thread::logical_processor_count(); + if (!logical_processor_count) { + logical_processor_count = 6; + } + creation_threads_busy_ = 0; + startup_loading_ = false; + creation_completion_event_ = rex::thread::Event::CreateManualResetEvent(true); + assert_not_null(creation_completion_event_); + creation_completion_set_event_ = false; + creation_threads_shutdown_from_ = SIZE_MAX; + if (REXCVAR_GET(vulkan_pipeline_creation_threads) != 0) { + size_t creation_thread_count; + if (REXCVAR_GET(vulkan_pipeline_creation_threads) < 0) { + creation_thread_count = std::max(logical_processor_count * 3 / 4, uint32_t(1)); + } else { + creation_thread_count = std::min(uint32_t(REXCVAR_GET(vulkan_pipeline_creation_threads)), + logical_processor_count); + } + for (size_t i = 0; i < creation_thread_count; ++i) { + std::unique_ptr creation_thread = + rex::thread::Thread::Create({}, [this, i]() { CreationThread(i); }); + assert_not_null(creation_thread); + creation_thread->set_name("Vulkan Pipelines"); + creation_threads_.push_back(std::move(creation_thread)); + } + } + + return true; +} + +void VulkanPipelineCache::InitializeShaderStorage(const std::filesystem::path& cache_root, + uint32_t title_id, bool blocking) { + ShutdownShaderStorage(); + { + std::lock_guard lock(creation_request_lock_); + startup_loading_ = false; + } + + auto shader_storage_root = cache_root / "shaders"; + auto shader_storage_shareable_root = shader_storage_root / "shareable"; + if (!std::filesystem::exists(shader_storage_shareable_root)) { + if (!std::filesystem::create_directories(shader_storage_shareable_root)) { + REXGPU_ERROR( + "Failed to create the shareable shader storage directory, persistent " + "shader storage will be disabled: {}", + rex::path_to_utf8(shader_storage_shareable_root)); + return; + } + } + + bool edram_fragment_shader_interlock = + render_target_cache_.GetPath() == RenderTargetCache::Path::kPixelShaderInterlock; + + // Initialize the pipeline storage stream - read pipeline descriptions and + // collect used shader modifications to translate. + std::vector pipeline_stored_descriptions; + // . + std::set> shader_translations_needed; + auto pipeline_storage_file_path = + shader_storage_shareable_root / + fmt::format("{:08X}.{}.vk.xpso", title_id, edram_fragment_shader_interlock ? "fsi" : "fbo"); + pipeline_storage_file_ = rex::filesystem::OpenFile(pipeline_storage_file_path, "a+b"); + if (!pipeline_storage_file_) { + REXGPU_ERROR( + "Failed to open the Vulkan pipeline description storage file for " + "writing, persistent shader storage will be disabled: {}", + rex::path_to_utf8(pipeline_storage_file_path)); + return; + } + pipeline_storage_file_flush_needed_ = false; + // 'XEPS'. + const uint32_t pipeline_storage_magic = 0x53504558; + const uint32_t pipeline_storage_magic_api = edram_fragment_shader_interlock ? 1u : 0u; + const uint32_t pipeline_storage_version_swapped = rex::byte_swap( + std::max(PipelineDescription::kVersion, SpirvShaderTranslator::Modification::kVersion)); + struct { + uint32_t magic; + uint32_t magic_api; + uint32_t version_swapped; + } pipeline_storage_file_header; + if (fread(&pipeline_storage_file_header, sizeof(pipeline_storage_file_header), 1, + pipeline_storage_file_) && + pipeline_storage_file_header.magic == pipeline_storage_magic && + pipeline_storage_file_header.magic_api == pipeline_storage_magic_api && + pipeline_storage_file_header.version_swapped == pipeline_storage_version_swapped) { + rex::filesystem::Seek(pipeline_storage_file_, 0, SEEK_END); + int64_t pipeline_storage_told_end = rex::filesystem::Tell(pipeline_storage_file_); + size_t pipeline_storage_told_count = + size_t(pipeline_storage_told_end >= int64_t(sizeof(pipeline_storage_file_header)) + ? (uint64_t(pipeline_storage_told_end) - sizeof(pipeline_storage_file_header)) / + sizeof(PipelineStoredDescription) + : 0); + if (pipeline_storage_told_count && + rex::filesystem::Seek(pipeline_storage_file_, int64_t(sizeof(pipeline_storage_file_header)), + SEEK_SET)) { + pipeline_stored_descriptions.resize(pipeline_storage_told_count); + pipeline_stored_descriptions.resize( + fread(pipeline_stored_descriptions.data(), sizeof(PipelineStoredDescription), + pipeline_storage_told_count, pipeline_storage_file_)); + size_t pipeline_storage_read_count = pipeline_stored_descriptions.size(); + size_t pipeline_storage_kept_count = 0; + size_t pipeline_storage_skipped_unsupported_count = 0; + size_t pipeline_storage_skipped_corrupted_count = 0; + for (size_t i = 0; i < pipeline_storage_read_count; ++i) { + const PipelineStoredDescription pipeline_stored_description = + pipeline_stored_descriptions[i]; + // Validate file integrity, stop and truncate the stream if data is + // corrupted. + if (XXH3_64bits(&pipeline_stored_description.description, + sizeof(pipeline_stored_description.description)) != + pipeline_stored_description.description_hash) { + pipeline_storage_skipped_corrupted_count = pipeline_storage_read_count - i; + pipeline_storage_read_count = i; + break; + } + if (!ArePipelineRequirementsMet(pipeline_stored_description.description)) { + ++pipeline_storage_skipped_unsupported_count; + continue; + } + pipeline_stored_descriptions[pipeline_storage_kept_count++] = pipeline_stored_description; + // Mark the shader modifications as needed for translation. + shader_translations_needed.emplace( + pipeline_stored_description.description.vertex_shader_hash, + pipeline_stored_description.description.vertex_shader_modification); + if (pipeline_stored_description.description.pixel_shader_hash) { + shader_translations_needed.emplace( + pipeline_stored_description.description.pixel_shader_hash, + pipeline_stored_description.description.pixel_shader_modification); + } + } + pipeline_stored_descriptions.resize(pipeline_storage_kept_count); + if (pipeline_storage_skipped_unsupported_count || pipeline_storage_skipped_corrupted_count) { + REXGPU_INFO( + "VulkanPipelineCache: Pipeline storage filtering kept {} descriptions (skipped {} " + "unsupported, {} corrupted)", + pipeline_storage_kept_count, pipeline_storage_skipped_unsupported_count, + pipeline_storage_skipped_corrupted_count); + } + } + } + + // Initialize the Xenos shader storage stream. + auto shader_storage_file_path = + shader_storage_shareable_root / fmt::format("{:08X}.xsh", title_id); + shader_storage_file_ = rex::filesystem::OpenFile(shader_storage_file_path, "a+b"); + if (!shader_storage_file_) { + REXGPU_ERROR( + "Failed to open the guest shader storage file for writing, persistent " + "shader storage will be disabled: {}", + rex::path_to_utf8(shader_storage_file_path)); + fclose(pipeline_storage_file_); + pipeline_storage_file_ = nullptr; + return; + } + ++shader_storage_index_; + shader_storage_file_flush_needed_ = false; + struct { + uint32_t magic; + uint32_t version_swapped; + } shader_storage_file_header; + // 'XESH'. + const uint32_t shader_storage_magic = 0x48534558; + if (fread(&shader_storage_file_header, sizeof(shader_storage_file_header), 1, + shader_storage_file_) && + shader_storage_file_header.magic == shader_storage_magic && + rex::byte_swap(shader_storage_file_header.version_swapped) == ShaderStoredHeader::kVersion) { + uint64_t shader_storage_valid_bytes = sizeof(shader_storage_file_header); + // Load shaders written by previous runs until the end of the file or until + // a corrupted one is detected. + ShaderStoredHeader shader_header; + std::vector ucode_dwords; + ucode_dwords.reserve(0xFFFF); + while (true) { + if (!fread(&shader_header, sizeof(shader_header), 1, shader_storage_file_)) { + break; + } + size_t ucode_byte_count = shader_header.ucode_dword_count * sizeof(uint32_t); + ucode_dwords.resize(shader_header.ucode_dword_count); + if (shader_header.ucode_dword_count && + !fread(ucode_dwords.data(), ucode_byte_count, 1, shader_storage_file_)) { + break; + } + uint64_t ucode_data_hash = XXH3_64bits(ucode_dwords.data(), ucode_byte_count); + if (shader_header.ucode_data_hash != ucode_data_hash) { + // Validation failed. + break; + } + shader_storage_valid_bytes += sizeof(shader_header) + ucode_byte_count; + VulkanShader* shader = LoadShader(shader_header.type, ucode_dwords.data(), + shader_header.ucode_dword_count, ucode_data_hash); + if (shader->ucode_storage_index() == shader_storage_index_) { + // Appeared twice in this file for some reason - skip. + continue; + } + // Loaded from the current storage - don't write again. + shader->set_ucode_storage_index(shader_storage_index_); + } + rex::filesystem::TruncateStdioFile(shader_storage_file_, shader_storage_valid_bytes); + } else { + rex::filesystem::TruncateStdioFile(shader_storage_file_, 0); + shader_storage_file_header.magic = shader_storage_magic; + shader_storage_file_header.version_swapped = rex::byte_swap(ShaderStoredHeader::kVersion); + fwrite(&shader_storage_file_header, sizeof(shader_storage_file_header), 1, + shader_storage_file_); + } + + // Translate shader modifications needed for stored pipelines. + for (const std::pair& translation_needed : shader_translations_needed) { + auto shader_it = shaders_.find(translation_needed.first); + if (shader_it == shaders_.end()) { + continue; + } + auto* shader = shader_it->second; + if (!shader->is_ucode_analyzed()) { + shader->AnalyzeUcode(ucode_disasm_buffer_); + } + bool translation_is_new = false; + auto* translation = static_cast( + shader->GetOrCreateTranslation(translation_needed.second, &translation_is_new)); + if (!translation->is_translated() && + !TranslateAnalyzedShader(*shader_translator_, *translation)) { + if (translation_is_new) { + shader->DestroyTranslation(translation_needed.second); + } + } + } + + // Create the pipelines. + std::vector pipeline_creations; + pipeline_creations.reserve(pipeline_stored_descriptions.size()); + for (const PipelineStoredDescription& pipeline_stored_description : + pipeline_stored_descriptions) { + const PipelineDescription& pipeline_description = pipeline_stored_description.description; + + auto find_it = pipelines_.find(pipeline_description); + if (find_it != pipelines_.end()) { + continue; + } + auto& pipeline = *pipelines_.emplace(pipeline_description, Pipeline()).first; + PipelineCreationArguments creation_arguments; + if (!TryGetPipelineCreationArgumentsForDescription(pipeline_description, &pipeline, + creation_arguments)) { + pipelines_.erase(pipeline_description); + continue; + } + uint32_t bound_rts = 0; + for (uint32_t i = 0; i < xenos::kMaxColorRenderTargets; ++i) { + if (pipeline_description.render_targets[i].color_write_mask) { + bound_rts |= uint32_t(1) << i; + } + } + uint32_t shader_writes_color_targets = + creation_arguments.pixel_shader + ? creation_arguments.pixel_shader->shader().writes_color_targets() + : 0; + bool shader_writes_depth = creation_arguments.pixel_shader + ? creation_arguments.pixel_shader->shader().writes_depth() + : pipeline_description.depth_write_enable != 0; + creation_arguments.priority = pipeline_util::CalculatePipelinePriority( + bound_rts, shader_writes_color_targets, shader_writes_depth); + pipeline_creations.push_back(creation_arguments); + } + + if (!pipeline_creations.empty()) { + { + std::lock_guard lock(creation_request_lock_); + startup_loading_ = true; + } + uint32_t logical_processor_count = rex::thread::logical_processor_count(); + if (!logical_processor_count) { + // Pick some reasonable amount if couldn't determine the number of cores. + logical_processor_count = 6; + } + size_t creation_thread_count; + if (REXCVAR_GET(vulkan_pipeline_creation_threads) == 0) { + creation_thread_count = 1; + } else if (REXCVAR_GET(vulkan_pipeline_creation_threads) < 0) { + creation_thread_count = std::max(logical_processor_count * 3 / 4, uint32_t(1)); + } else { + creation_thread_count = std::min(uint32_t(REXCVAR_GET(vulkan_pipeline_creation_threads)), + logical_processor_count); + } + if (!blocking) { + // Vulkan currently doesn't support deferred pipeline handles at draw time, + // so complete preload creation regardless of blocking mode. + creation_thread_count = std::max(creation_thread_count, size_t(1)); + } + creation_thread_count = std::min(creation_thread_count, pipeline_creations.size()); + + std::atomic next_creation_index(0); + std::atomic created_pipeline_count(0); + auto creation_worker = [this, &pipeline_creations, &next_creation_index, + &created_pipeline_count]() { + while (true) { + size_t creation_index = next_creation_index.fetch_add(1); + if (creation_index >= pipeline_creations.size()) { + break; + } + if (EnsurePipelineCreated(pipeline_creations[creation_index])) { + created_pipeline_count.fetch_add(1); + } + } + }; + + if (creation_thread_count <= 1) { + creation_worker(); + } else { + std::vector> creation_threads; + creation_threads.reserve(creation_thread_count); + for (size_t i = 0; i < creation_thread_count; ++i) { + std::unique_ptr creation_thread = + rex::thread::Thread::Create({}, creation_worker); + assert_not_null(creation_thread); + creation_thread->set_name("Vulkan Pipelines"); + creation_threads.push_back(std::move(creation_thread)); + } + for (const auto& creation_thread : creation_threads) { + rex::thread::Wait(creation_thread.get(), false); + } + } + + REXGPU_INFO("Created {} graphics pipelines from Vulkan storage ({} requested)", + created_pipeline_count.load(), pipeline_creations.size()); + { + std::lock_guard lock(creation_request_lock_); + startup_loading_ = false; + } + } + + // If any pipeline descriptions were corrupted (or the whole file has excess + // bytes in the end), truncate to the last valid pipeline description. + rex::filesystem::TruncateStdioFile( + pipeline_storage_file_, + uint64_t(sizeof(pipeline_storage_file_header) + + sizeof(PipelineStoredDescription) * pipeline_stored_descriptions.size())); + if (pipeline_stored_descriptions.empty()) { + rex::filesystem::TruncateStdioFile(pipeline_storage_file_, 0); + pipeline_storage_file_header.magic = pipeline_storage_magic; + pipeline_storage_file_header.magic_api = pipeline_storage_magic_api; + pipeline_storage_file_header.version_swapped = pipeline_storage_version_swapped; + fwrite(&pipeline_storage_file_header, sizeof(pipeline_storage_file_header), 1, + pipeline_storage_file_); + } + + shader_storage_cache_root_ = cache_root; + shader_storage_title_id_ = title_id; + + // Start the storage writing thread. + storage_write_flush_shaders_ = false; + storage_write_flush_pipelines_ = false; + storage_write_thread_shutdown_ = false; + storage_write_thread_ = rex::thread::Thread::Create({}, [this]() { StorageWriteThread(); }); + assert_not_null(storage_write_thread_); + storage_write_thread_->set_name("Vulkan Storage writer"); +} + +void VulkanPipelineCache::ShutdownShaderStorage() { + if (storage_write_thread_) { + { + std::lock_guard lock(storage_write_request_lock_); + storage_write_thread_shutdown_ = true; + } + storage_write_request_cond_.notify_all(); + rex::thread::Wait(storage_write_thread_.get(), false); + storage_write_thread_.reset(); + } + storage_write_shader_queue_.clear(); + storage_write_pipeline_queue_.clear(); + + if (pipeline_storage_file_) { + fclose(pipeline_storage_file_); + pipeline_storage_file_ = nullptr; + pipeline_storage_file_flush_needed_ = false; + } + + if (shader_storage_file_) { + fclose(shader_storage_file_); + shader_storage_file_ = nullptr; + shader_storage_file_flush_needed_ = false; + } + + shader_storage_cache_root_.clear(); + shader_storage_title_id_ = 0; +} + +void VulkanPipelineCache::EndSubmission() { + if (shader_storage_file_flush_needed_ || pipeline_storage_file_flush_needed_) { + { + std::lock_guard lock(storage_write_request_lock_); + if (shader_storage_file_flush_needed_) { + storage_write_flush_shaders_ = true; + } + if (pipeline_storage_file_flush_needed_) { + storage_write_flush_pipelines_ = true; + } + } + storage_write_request_cond_.notify_one(); + shader_storage_file_flush_needed_ = false; + pipeline_storage_file_flush_needed_ = false; + } + + if (!creation_threads_.empty()) { + bool startup_loading = false; + { + std::lock_guard lock(creation_request_lock_); + startup_loading = startup_loading_; + } + if (startup_loading) { + creation_request_cond_.notify_one(); + } else { + // Help worker threads on the processor thread to reduce warm-up latency. + CreateQueuedPipelinesOnProcessorThread(); + bool await_creation_completion_event; + { + std::lock_guard lock(creation_request_lock_); + // The queue is empty because of CreateQueuedPipelinesOnProcessorThread, + // only check in-flight creation by worker threads. + await_creation_completion_event = creation_threads_busy_ != 0; + if (await_creation_completion_event) { + creation_completion_event_->Reset(); + creation_completion_set_event_ = true; + } + } + if (await_creation_completion_event) { + creation_request_cond_.notify_one(); + rex::thread::Wait(creation_completion_event_.get(), false); + } + } + } + + ProcessDeferredPipelineDestructions(false); +} + +void VulkanPipelineCache::Shutdown() { + // Shut down creation threads before destroying any pipelines they may touch. + if (!creation_threads_.empty()) { + { + std::lock_guard lock(creation_request_lock_); + creation_threads_shutdown_from_ = 0; + } + creation_request_cond_.notify_all(); + for (size_t i = 0; i < creation_threads_.size(); ++i) { + rex::thread::Wait(creation_threads_[i].get(), false); + } + creation_threads_.clear(); + } + { + std::lock_guard lock(creation_request_lock_); + while (!creation_queue_.empty()) { + creation_queue_.pop(); + } + creation_threads_busy_ = 0; + startup_loading_ = false; + creation_completion_set_event_ = false; + creation_threads_shutdown_from_ = SIZE_MAX; + } + creation_completion_event_.reset(); + + ShutdownShaderStorage(); + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + ProcessDeferredPipelineDestructions(true); + + // Destroy all pipelines. + last_pipeline_ = nullptr; + for (const auto& pipeline_pair : pipelines_) { + VkPipeline pipeline = pipeline_pair.second.pipeline.load(std::memory_order_acquire); + if (pipeline != VK_NULL_HANDLE) { + dfn.vkDestroyPipeline(device, pipeline, nullptr); + } + } + pipelines_.clear(); + + // Destroy all internal shaders. + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyShaderModule, device, + depth_only_fragment_shader_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyShaderModule, device, + depth_float24_truncate_fragment_shader_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyShaderModule, device, + depth_float24_round_fragment_shader_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyShaderModule, device, + placeholder_pixel_shader_); + if (tessellation_indexed_vertex_shader_ != VK_NULL_HANDLE) { + dfn.vkDestroyShaderModule(device, tessellation_indexed_vertex_shader_, nullptr); + tessellation_indexed_vertex_shader_ = VK_NULL_HANDLE; + } + if (tessellation_adaptive_vertex_shader_ != VK_NULL_HANDLE) { + dfn.vkDestroyShaderModule(device, tessellation_adaptive_vertex_shader_, nullptr); + tessellation_adaptive_vertex_shader_ = VK_NULL_HANDLE; + } + tessellation_indexed_vertex_shader_attempted_ = false; + tessellation_adaptive_vertex_shader_attempted_ = false; + for (const auto& tessellation_control_shader_pair : tessellation_control_shaders_) { + if (tessellation_control_shader_pair.second != VK_NULL_HANDLE) { + dfn.vkDestroyShaderModule(device, tessellation_control_shader_pair.second, nullptr); + } + } + tessellation_control_shaders_.clear(); + for (const auto& geometry_shader_pair : geometry_shaders_) { + if (geometry_shader_pair.second != VK_NULL_HANDLE) { + dfn.vkDestroyShaderModule(device, geometry_shader_pair.second, nullptr); + } + } + geometry_shaders_.clear(); + + // Destroy all translated shaders. + for (auto it : shaders_) { + delete it.second; + } + shaders_.clear(); + shader_storage_index_ = 0; + texture_binding_layout_map_.clear(); + texture_binding_layouts_.clear(); + + // Shut down shader translation. + shader_translator_.reset(); +} + +VulkanShader* VulkanPipelineCache::LoadShader(xenos::ShaderType shader_type, + const uint32_t* host_address, uint32_t dword_count) { + // Hash the input memory and lookup the shader. + return LoadShader(shader_type, host_address, dword_count, + XXH3_64bits(host_address, dword_count * sizeof(uint32_t))); +} + +VulkanShader* VulkanPipelineCache::LoadShader(xenos::ShaderType shader_type, + const uint32_t* host_address, uint32_t dword_count, + uint64_t data_hash) { + auto it = shaders_.find(data_hash); + if (it != shaders_.end()) { + // Shader has been previously loaded. + return it->second; + } + // Always create the shader and stash it away. + // We need to track it even if it fails translation so we know not to try + // again. + VulkanShader* shader = new VulkanShader(command_processor_.GetVulkanDevice(), shader_type, + data_hash, host_address, dword_count); + shaders_.emplace(data_hash, shader); + return shader; +} + +SpirvShaderTranslator::Modification VulkanPipelineCache::GetCurrentVertexShaderModification( + const Shader& shader, Shader::HostVertexShaderType host_vertex_shader_type, + uint32_t interpolator_mask, bool ps_param_gen_used) const { + assert_true(shader.type() == xenos::ShaderType::kVertex); + assert_true(shader.is_ucode_analyzed()); + const auto& regs = register_file_; + const auto& device_properties = command_processor_.GetVulkanDevice()->properties(); + + SpirvShaderTranslator::Modification modification( + shader_translator_->GetDefaultVertexShaderModification( + shader.GetDynamicAddressableRegisterCount(regs.Get().vs_num_reg), + host_vertex_shader_type)); + + modification.vertex.interpolator_mask = interpolator_mask; + if (Shader::IsHostVertexShaderTypeDomain(host_vertex_shader_type)) { + modification.vertex.tessellation_mode = uint32_t(regs.Get().tess_mode); + } else { + modification.vertex.tessellation_mode = 0; + } + + auto pa_cl_clip_cntl = regs.Get(); + uint32_t user_clip_planes = pa_cl_clip_cntl.clip_disable ? 0 : pa_cl_clip_cntl.ucp_ena; + if (user_clip_planes) { + if (pa_cl_clip_cntl.ucp_cull_only_ena && device_properties.shaderCullDistance) { + modification.vertex.user_clip_plane_cull = 1; + } else if (!device_properties.shaderClipDistance && device_properties.shaderCullDistance) { + // Fallback if clip distances are unavailable. + modification.vertex.user_clip_plane_cull = 1; + } else if (!device_properties.shaderClipDistance) { + // No supported clip/cull built-in for user clip planes. + user_clip_planes = 0; + modification.vertex.user_clip_plane_cull = 0; + } else { + modification.vertex.user_clip_plane_cull = 0; + } + } else { + modification.vertex.user_clip_plane_cull = 0; + } + modification.vertex.user_clip_plane_count = rex::bit_count(user_clip_planes); + modification.vertex.point_ps_ucp_mode = pa_cl_clip_cntl.ps_ucp_mode; + + if (host_vertex_shader_type == Shader::HostVertexShaderType::kPointListAsTriangleStrip) { + modification.vertex.output_point_parameters = uint32_t(ps_param_gen_used); + } else { + modification.vertex.output_point_parameters = + uint32_t((shader.writes_point_size_edge_flag_kill_vertex() & 0b001) && + regs.Get().prim_type == xenos::PrimitiveType::kPointList); + } + modification.vertex.vertex_kill_and = uint32_t( + device_properties.shaderCullDistance && + (shader.writes_point_size_edge_flag_kill_vertex() & 0b100) && !pa_cl_clip_cntl.vtx_kill_or); + + return modification; +} + +SpirvShaderTranslator::Modification VulkanPipelineCache::GetCurrentPixelShaderModification( + const Shader& shader, uint32_t interpolator_mask, uint32_t param_gen_pos, + reg::RB_DEPTHCONTROL normalized_depth_control) const { + assert_true(shader.type() == xenos::ShaderType::kPixel); + assert_true(shader.is_ucode_analyzed()); + const auto& regs = register_file_; + + SpirvShaderTranslator::Modification modification( + shader_translator_->GetDefaultPixelShaderModification( + shader.GetDynamicAddressableRegisterCount(regs.Get().ps_num_reg))); + + modification.pixel.interpolator_mask = interpolator_mask; + modification.pixel.interpolators_centroid = + interpolator_mask & ~xenos::GetInterpolatorSamplingPattern( + regs.Get().msaa_samples, + regs.Get().sc_sample_cntl, + regs.Get().sampling_pattern); + + if (param_gen_pos < xenos::kMaxInterpolators) { + modification.pixel.param_gen_enable = 1; + modification.pixel.param_gen_interpolator = param_gen_pos; + modification.pixel.param_gen_point = + uint32_t(regs.Get().prim_type == xenos::PrimitiveType::kPointList); + } else { + modification.pixel.param_gen_enable = 0; + modification.pixel.param_gen_interpolator = 0; + modification.pixel.param_gen_point = 0; + } + + if (render_target_cache_.GetPath() == RenderTargetCache::Path::kHostRenderTargets) { + using DepthStencilMode = SpirvShaderTranslator::Modification::DepthStencilMode; + if (render_target_cache_.depth_float24_convert_in_pixel_shader() && + normalized_depth_control.z_enable && + regs.Get().depth_format == xenos::DepthRenderTargetFormat::kD24FS8) { + // For host D32 depth, emulate guest D24FS8 float24 depth behavior. + modification.pixel.depth_stencil_mode = render_target_cache_.depth_float24_round() + ? DepthStencilMode::kFloat24Rounding + : DepthStencilMode::kFloat24Truncating; + } else { + if (shader.implicit_early_z_write_allowed() && + (!shader.writes_color_target(0) || + !draw_util::DoesCoverageDependOnAlpha(regs.Get()))) { + modification.pixel.depth_stencil_mode = DepthStencilMode::kEarlyHint; + } else { + modification.pixel.depth_stencil_mode = DepthStencilMode::kNoModifiers; + } + } + } + + return modification; +} + +bool VulkanPipelineCache::EnsureShadersTranslated(VulkanShader::VulkanTranslation* vertex_shader, + VulkanShader::VulkanTranslation* pixel_shader) { + // Edge flags are not supported yet (because polygon primitives are not). + assert_true(register_file_.Get().vs_export_mode != + xenos::VertexShaderExportMode::kPosition2VectorsEdge && + register_file_.Get().vs_export_mode != + xenos::VertexShaderExportMode::kPosition2VectorsEdgeKill); + assert_false(register_file_.Get().gen_index_vtx); + if (!vertex_shader->is_translated()) { + vertex_shader->shader().AnalyzeUcode(ucode_disasm_buffer_); + if (!TranslateAnalyzedShader(*shader_translator_, *vertex_shader)) { + REXGPU_ERROR("Failed to translate the vertex shader!"); + return false; + } + } + if (!vertex_shader->is_valid()) { + // Translation attempted previously, but not valid. + return false; + } + if (pixel_shader != nullptr) { + if (!pixel_shader->is_translated()) { + pixel_shader->shader().AnalyzeUcode(ucode_disasm_buffer_); + if (!TranslateAnalyzedShader(*shader_translator_, *pixel_shader)) { + REXGPU_ERROR("Failed to translate the pixel shader!"); + return false; + } + } + if (!pixel_shader->is_valid()) { + // Translation attempted previously, but not valid. + return false; + } + } + return true; +} + +bool VulkanPipelineCache::ConfigurePipeline( + VulkanShader::VulkanTranslation* vertex_shader, VulkanShader::VulkanTranslation* pixel_shader, + const PrimitiveProcessor::ProcessingResult& primitive_processing_result, + reg::RB_DEPTHCONTROL normalized_depth_control, uint32_t normalized_color_mask, + VulkanRenderTargetCache::RenderPassKey render_pass_key, VkPipeline& pipeline_out, + const PipelineLayoutProvider*& pipeline_layout_out, void** pipeline_handle_out) { +#if XE_GPU_FINE_GRAINED_DRAW_SCOPES + SCOPE_profile_cpu_f("gpu"); +#endif // XE_GPU_FINE_GRAINED_DRAW_SCOPES + + // Ensure shaders are translated - needed now for GetCurrentStateDescription. + if (!EnsureShadersTranslated(vertex_shader, pixel_shader)) { + return false; + } + if (shader_storage_file_ && + vertex_shader->shader().ucode_storage_index() != shader_storage_index_) { + vertex_shader->shader().set_ucode_storage_index(shader_storage_index_); + assert_not_null(storage_write_thread_); + shader_storage_file_flush_needed_ = true; + { + std::lock_guard lock(storage_write_request_lock_); + storage_write_shader_queue_.push_back(&vertex_shader->shader()); + } + storage_write_request_cond_.notify_all(); + } + if (pixel_shader && shader_storage_file_ && + pixel_shader->shader().ucode_storage_index() != shader_storage_index_) { + pixel_shader->shader().set_ucode_storage_index(shader_storage_index_); + assert_not_null(storage_write_thread_); + shader_storage_file_flush_needed_ = true; + { + std::lock_guard lock(storage_write_request_lock_); + storage_write_shader_queue_.push_back(&pixel_shader->shader()); + } + storage_write_request_cond_.notify_all(); + } + + PipelineDescription description; + if (!GetCurrentStateDescription(vertex_shader, pixel_shader, primitive_processing_result, + normalized_depth_control, normalized_color_mask, render_pass_key, + description)) { + REXGPU_ERROR( + "VulkanPipelineCache: GetCurrentStateDescription failed " + "(guest_prim={}, host_prim={}, host_vs_type={}, tess_mode={}, host_reset={}, " + "render_pass_key=0x{:08X})", + uint32_t(primitive_processing_result.guest_primitive_type), + uint32_t(primitive_processing_result.host_primitive_type), + uint32_t(primitive_processing_result.host_vertex_shader_type), + uint32_t(primitive_processing_result.tessellation_mode), + uint32_t(primitive_processing_result.host_primitive_reset_enabled), render_pass_key.key); + return false; + } + if (last_pipeline_ && last_pipeline_->first == description) { + VkPipeline last_pipeline = last_pipeline_->second.pipeline.load(std::memory_order_acquire); + const PipelineLayoutProvider* last_pipeline_layout = + last_pipeline_->second.pipeline_layout.load(std::memory_order_acquire); + if (last_pipeline != VK_NULL_HANDLE && last_pipeline_layout != nullptr) { + pipeline_out = last_pipeline; + pipeline_layout_out = last_pipeline_layout; + if (pipeline_handle_out) { + *pipeline_handle_out = const_cast(&last_pipeline_->second); + } + return true; + } + } + + bool use_async = REXCVAR_GET(async_shader_compilation) && !creation_threads_.empty() && + pixel_shader && placeholder_pixel_shader_ != VK_NULL_HANDLE; + uint8_t async_priority = pipeline_util::kPriorityLowest; + if (use_async) { + uint32_t bound_rts = + pipeline_util::GetBoundRTMaskFromNormalizedColorMask(normalized_color_mask); + uint32_t shader_writes_color_targets = + pixel_shader ? pixel_shader->shader().writes_color_targets() : 0; + bool shader_writes_depth = pixel_shader ? pixel_shader->shader().writes_depth() + : normalized_depth_control.z_write_enable != 0; + async_priority = pipeline_util::CalculatePipelinePriority( + bound_rts, shader_writes_color_targets, shader_writes_depth); + } + + auto it = pipelines_.find(description); + if (it != pipelines_.end()) { + VkPipeline found_pipeline = it->second.pipeline.load(std::memory_order_acquire); + if (found_pipeline == VK_NULL_HANDLE) { + PipelineCreationArguments creation_arguments; + if (!TryGetPipelineCreationArgumentsForDescription(description, &*it, creation_arguments) || + !EnsurePipelineCreated(creation_arguments)) { + return false; + } + found_pipeline = it->second.pipeline.load(std::memory_order_acquire); + } + const PipelineLayoutProvider* found_pipeline_layout = + it->second.pipeline_layout.load(std::memory_order_acquire); + last_pipeline_ = &*it; + pipeline_out = found_pipeline; + pipeline_layout_out = found_pipeline_layout; + if (pipeline_handle_out) { + *pipeline_handle_out = &it->second; + } + return pipeline_out != VK_NULL_HANDLE && pipeline_layout_out != nullptr; + } + + // Create the pipeline if not already existing. + auto& pipeline = *pipelines_.emplace(description, Pipeline()).first; + PipelineCreationArguments creation_arguments_real; + if (!TryGetPipelineCreationArgumentsForDescription(description, &pipeline, + creation_arguments_real)) { + pipelines_.erase(description); + return false; + } + + bool queued_async_creation = false; + if (use_async) { + creation_arguments_real.priority = async_priority; + PipelineCreationArguments creation_arguments_placeholder; + if (TryGetPipelineCreationArgumentsForDescription(description, &pipeline, + creation_arguments_placeholder, true)) { + pipeline.second.is_placeholder.store(true, std::memory_order_release); + if (EnsurePipelineCreated(creation_arguments_placeholder, placeholder_pixel_shader_)) { + { + std::lock_guard lock(creation_request_lock_); + creation_queue_.push(creation_arguments_real); + } + creation_request_cond_.notify_one(); + queued_async_creation = true; + } else { + pipeline.second.is_placeholder.store(false, std::memory_order_release); + } + } + } + + if (!queued_async_creation && !EnsurePipelineCreated(creation_arguments_real)) { + pipelines_.erase(description); + return false; + } + if (!queued_async_creation) { + pipeline.second.is_placeholder.store(false, std::memory_order_release); + } + + if (pipeline_storage_file_) { + assert_not_null(storage_write_thread_); + pipeline_storage_file_flush_needed_ = true; + { + std::lock_guard lock(storage_write_request_lock_); + storage_write_pipeline_queue_.emplace_back(); + PipelineStoredDescription& stored_description = storage_write_pipeline_queue_.back(); + stored_description.description_hash = description.GetHash(); + std::memcpy(&stored_description.description, &description, sizeof(description)); + } + storage_write_request_cond_.notify_all(); + } + last_pipeline_ = &pipeline; + pipeline_out = pipeline.second.pipeline.load(std::memory_order_acquire); + pipeline_layout_out = pipeline.second.pipeline_layout.load(std::memory_order_acquire); + if (pipeline_handle_out) { + *pipeline_handle_out = &pipeline.second; + } + return pipeline_out != VK_NULL_HANDLE && pipeline_layout_out != nullptr; +} + +bool VulkanPipelineCache::IsCreatingPipelines() const { + std::lock_guard lock(creation_request_lock_); + if (creation_threads_.empty()) { + return startup_loading_; + } + return startup_loading_ || !creation_queue_.empty() || creation_threads_busy_ != 0; +} + +void VulkanPipelineCache::GetPipelineAndLayoutByHandle( + void* handle, VkPipeline& pipeline_out, const PipelineLayoutProvider*& pipeline_layout_out, + bool* is_placeholder_out) const { + if (!handle) { + pipeline_out = VK_NULL_HANDLE; + pipeline_layout_out = nullptr; + if (is_placeholder_out) { + *is_placeholder_out = false; + } + return; + } + const auto* pipeline = reinterpret_cast(handle); + pipeline_out = pipeline->pipeline.load(std::memory_order_acquire); + pipeline_layout_out = pipeline->pipeline_layout.load(std::memory_order_acquire); + if (is_placeholder_out) { + *is_placeholder_out = pipeline->is_placeholder.load(std::memory_order_acquire); + } +} + +bool VulkanPipelineCache::TranslateAnalyzedShader(SpirvShaderTranslator& translator, + VulkanShader::VulkanTranslation& translation) { + VulkanShader& shader = static_cast(translation.shader()); + + // Perform translation. + // If this fails the shader will be marked as invalid and ignored later. + if (!translator.TranslateAnalyzedShader(translation)) { + REXGPU_ERROR("Shader {:016X} translation failed; marking as ignored", shader.ucode_data_hash()); + return false; + } + if (translation.GetOrCreateShaderModule() == VK_NULL_HANDLE) { + return false; + } + + // TODO(Triang3l): Log that the shader has been successfully translated in + // common code. + + // Set up the texture binding layout. + if (shader.EnterBindingLayoutUserUIDSetup()) { + // Obtain the unique IDs of the binding layout if there are any texture + // bindings, for invalidation in the command processor. + size_t texture_binding_layout_uid = kLayoutUIDEmpty; + const std::vector& texture_bindings = + shader.GetTextureBindingsAfterTranslation(); + size_t texture_binding_count = texture_bindings.size(); + if (texture_binding_count) { + size_t texture_binding_layout_bytes = + texture_binding_count * sizeof(*texture_bindings.data()); + uint64_t texture_binding_layout_hash = + XXH3_64bits(texture_bindings.data(), texture_binding_layout_bytes); + auto found_range = texture_binding_layout_map_.equal_range(texture_binding_layout_hash); + for (auto it = found_range.first; it != found_range.second; ++it) { + if (it->second.vector_span_length == texture_binding_count && + !std::memcmp(texture_binding_layouts_.data() + it->second.vector_span_offset, + texture_bindings.data(), texture_binding_layout_bytes)) { + texture_binding_layout_uid = it->second.uid; + break; + } + } + if (texture_binding_layout_uid == kLayoutUIDEmpty) { + static_assert(kLayoutUIDEmpty == 0, + "Layout UID is size + 1 because it's assumed that 0 is the UID for " + "an empty layout"); + texture_binding_layout_uid = texture_binding_layout_map_.size() + 1; + LayoutUID new_uid; + new_uid.uid = texture_binding_layout_uid; + new_uid.vector_span_offset = texture_binding_layouts_.size(); + new_uid.vector_span_length = texture_binding_count; + texture_binding_layouts_.resize(new_uid.vector_span_offset + texture_binding_count); + std::memcpy(texture_binding_layouts_.data() + new_uid.vector_span_offset, + texture_bindings.data(), texture_binding_layout_bytes); + texture_binding_layout_map_.emplace(texture_binding_layout_hash, new_uid); + } + } + shader.SetTextureBindingLayoutUserUID(texture_binding_layout_uid); + + // Use the sampler count for samplers because it's the only thing that must + // be the same for layouts to be compatible in this case + // (instruction-specified parameters are used as overrides for creating + // actual samplers). + static_assert(kLayoutUIDEmpty == 0, + "Empty layout UID is assumed to be 0 because for bindful samplers, the " + "UID is their count"); + shader.SetSamplerBindingLayoutUserUID(shader.GetSamplerBindingsAfterTranslation().size()); + } + + return true; +} + +void VulkanPipelineCache::WritePipelineRenderTargetDescription( + reg::RB_BLENDCONTROL blend_control, uint32_t write_mask, + PipelineRenderTarget& render_target_out) const { + if (write_mask) { + assert_zero(write_mask & ~uint32_t(0b1111)); + // 32 because of 0x1F mask, for safety (all unknown to zero). + static const PipelineBlendFactor kBlendFactorMap[32] = { + /* 0 */ PipelineBlendFactor::kZero, + /* 1 */ PipelineBlendFactor::kOne, + /* 2 */ PipelineBlendFactor::kZero, // ? + /* 3 */ PipelineBlendFactor::kZero, // ? + /* 4 */ PipelineBlendFactor::kSrcColor, + /* 5 */ PipelineBlendFactor::kOneMinusSrcColor, + /* 6 */ PipelineBlendFactor::kSrcAlpha, + /* 7 */ PipelineBlendFactor::kOneMinusSrcAlpha, + /* 8 */ PipelineBlendFactor::kDstColor, + /* 9 */ PipelineBlendFactor::kOneMinusDstColor, + /* 10 */ PipelineBlendFactor::kDstAlpha, + /* 11 */ PipelineBlendFactor::kOneMinusDstAlpha, + /* 12 */ PipelineBlendFactor::kConstantColor, + /* 13 */ PipelineBlendFactor::kOneMinusConstantColor, + /* 14 */ PipelineBlendFactor::kConstantAlpha, + /* 15 */ PipelineBlendFactor::kOneMinusConstantAlpha, + /* 16 */ PipelineBlendFactor::kSrcAlphaSaturate, + }; + render_target_out.src_color_blend_factor = + kBlendFactorMap[uint32_t(blend_control.color_srcblend)]; + render_target_out.dst_color_blend_factor = + kBlendFactorMap[uint32_t(blend_control.color_destblend)]; + render_target_out.color_blend_op = blend_control.color_comb_fcn; + render_target_out.src_alpha_blend_factor = + kBlendFactorMap[uint32_t(blend_control.alpha_srcblend)]; + render_target_out.dst_alpha_blend_factor = + kBlendFactorMap[uint32_t(blend_control.alpha_destblend)]; + render_target_out.alpha_blend_op = blend_control.alpha_comb_fcn; + if (!command_processor_.GetVulkanDevice()->properties().constantAlphaColorBlendFactors) { + if (blend_control.color_srcblend == xenos::BlendFactor::kConstantAlpha) { + render_target_out.src_color_blend_factor = PipelineBlendFactor::kConstantColor; + } else if (blend_control.color_srcblend == xenos::BlendFactor::kOneMinusConstantAlpha) { + render_target_out.src_color_blend_factor = PipelineBlendFactor::kOneMinusConstantColor; + } + if (blend_control.color_destblend == xenos::BlendFactor::kConstantAlpha) { + render_target_out.dst_color_blend_factor = PipelineBlendFactor::kConstantColor; + } else if (blend_control.color_destblend == xenos::BlendFactor::kOneMinusConstantAlpha) { + render_target_out.dst_color_blend_factor = PipelineBlendFactor::kOneMinusConstantColor; + } + } + } else { + render_target_out.src_color_blend_factor = PipelineBlendFactor::kOne; + render_target_out.dst_color_blend_factor = PipelineBlendFactor::kZero; + render_target_out.color_blend_op = xenos::BlendOp::kAdd; + render_target_out.src_alpha_blend_factor = PipelineBlendFactor::kOne; + render_target_out.dst_alpha_blend_factor = PipelineBlendFactor::kZero; + render_target_out.alpha_blend_op = xenos::BlendOp::kAdd; + } + render_target_out.color_write_mask = write_mask; +} + +bool VulkanPipelineCache::GetCurrentStateDescription( + const VulkanShader::VulkanTranslation* vertex_shader, + const VulkanShader::VulkanTranslation* pixel_shader, + const PrimitiveProcessor::ProcessingResult& primitive_processing_result, + reg::RB_DEPTHCONTROL normalized_depth_control, uint32_t normalized_color_mask, + VulkanRenderTargetCache::RenderPassKey render_pass_key, + PipelineDescription& description_out) const { + description_out.Reset(); + + const ui::vulkan::VulkanDevice::Properties& device_properties = + command_processor_.GetVulkanDevice()->properties(); + + const RegisterFile& regs = register_file_; + auto pa_su_sc_mode_cntl = regs.Get(); + + description_out.vertex_shader_hash = vertex_shader->shader().ucode_data_hash(); + description_out.vertex_shader_modification = vertex_shader->modification(); + SpirvShaderTranslator::Modification vertex_shader_modification( + description_out.vertex_shader_modification); + Shader::HostVertexShaderType host_vertex_shader_type = + vertex_shader_modification.vertex.host_vertex_shader_type; + if (pixel_shader) { + description_out.pixel_shader_hash = pixel_shader->shader().ucode_data_hash(); + description_out.pixel_shader_modification = pixel_shader->modification(); + SpirvShaderTranslator::Modification pixel_shader_modification( + description_out.pixel_shader_modification); + using DepthStencilMode = SpirvShaderTranslator::Modification::DepthStencilMode; + description_out.sample_rate_shading = + !pixel_shader->shader().writes_depth() && + (pixel_shader_modification.pixel.depth_stencil_mode == + DepthStencilMode::kFloat24Truncating || + pixel_shader_modification.pixel.depth_stencil_mode == DepthStencilMode::kFloat24Rounding); + } + description_out.render_pass_key = render_pass_key; + + bool tessellated = primitive_processing_result.IsTessellated(); + PipelineGeometryShader geometry_shader = PipelineGeometryShader::kNone; + PipelinePrimitiveTopology primitive_topology; + if (tessellated) { + switch (primitive_processing_result.host_primitive_type) { + case xenos::PrimitiveType::kTriangleList: + case xenos::PrimitiveType::kQuadList: + case xenos::PrimitiveType::kTrianglePatch: + case xenos::PrimitiveType::kQuadPatch: + primitive_topology = PipelinePrimitiveTopology::kPatchList; + break; + default: + return false; + } + description_out.tessellation_mode = primitive_processing_result.tessellation_mode; + } else { + // Fallback expansion in the vertex shader for primitive types that may be + // emulated through geometry shaders on GS-capable hosts. + if (host_vertex_shader_type == Shader::HostVertexShaderType::kPointListAsTriangleStrip || + host_vertex_shader_type == Shader::HostVertexShaderType::kRectangleListAsTriangleStrip) { + if (primitive_processing_result.host_primitive_type != xenos::PrimitiveType::kTriangleStrip || + !primitive_processing_result.host_primitive_reset_enabled) { + assert_always(); + return false; + } + primitive_topology = PipelinePrimitiveTopology::kTriangleStrip; + } else { + switch (primitive_processing_result.host_primitive_type) { + case xenos::PrimitiveType::kPointList: + geometry_shader = PipelineGeometryShader::kPointList; + primitive_topology = PipelinePrimitiveTopology::kPointList; + break; + case xenos::PrimitiveType::kLineList: + primitive_topology = PipelinePrimitiveTopology::kLineList; + break; + case xenos::PrimitiveType::kLineStrip: + primitive_topology = PipelinePrimitiveTopology::kLineStrip; + break; + case xenos::PrimitiveType::kTriangleList: + primitive_topology = PipelinePrimitiveTopology::kTriangleList; + break; + case xenos::PrimitiveType::kTriangleFan: + // Triangle fans on Vulkan are expected to be converted to triangle + // lists in primitive processing for parity with D3D12 behavior. + assert_always(); + return false; + case xenos::PrimitiveType::kTriangleStrip: + primitive_topology = PipelinePrimitiveTopology::kTriangleStrip; + break; + case xenos::PrimitiveType::kRectangleList: + geometry_shader = PipelineGeometryShader::kRectangleList; + primitive_topology = PipelinePrimitiveTopology::kTriangleList; + break; + case xenos::PrimitiveType::kQuadList: + geometry_shader = PipelineGeometryShader::kQuadList; + primitive_topology = PipelinePrimitiveTopology::kLineListWithAdjacency; + break; + default: + return false; + } + } + } + description_out.geometry_shader = geometry_shader; + description_out.primitive_topology = primitive_topology; + description_out.primitive_restart = primitive_processing_result.host_primitive_reset_enabled; + + description_out.depth_clamp_enable = + device_properties.depthClamp && regs.Get().clip_disable; + + // Tessellated draws are patch-domain polygonal primitives regardless of guest + // register ambiguity in non-explicit major mode configurations. + bool primitive_polygonal = tessellated ? true : draw_util::IsPrimitivePolygonal(regs); + bool rasterization_enabled = draw_util::IsRasterizationPotentiallyDone(regs, primitive_polygonal); + if (!rasterization_enabled) { + // Keep parity with D3D12 by fully disabling rasterization for draws where + // only non-raster stages (for instance, vertex memexport) can have side + // effects. + description_out.rasterizer_discard = 1; + return true; + } + if (primitive_polygonal) { + // Vulkan only allows the polygon mode to be set for both faces - pick the + // most special one (more likely to represent the developer's deliberate + // intentions - fill is very generic, wireframe is common in debug, points + // are for pretty unusual things, but closer to debug purposes too - on the + // Xenos, points have the lowest register value and triangles have the + // highest) based on which faces are not culled. + bool cull_front = pa_su_sc_mode_cntl.cull_front; + bool cull_back = pa_su_sc_mode_cntl.cull_back; + description_out.cull_front = cull_front; + description_out.cull_back = cull_back; + if (device_properties.fillModeNonSolid) { + xenos::PolygonType polygon_type = xenos::PolygonType::kTriangles; + if (!cull_front) { + polygon_type = std::min(polygon_type, pa_su_sc_mode_cntl.polymode_front_ptype); + } + if (!cull_back) { + polygon_type = std::min(polygon_type, pa_su_sc_mode_cntl.polymode_back_ptype); + } + if (pa_su_sc_mode_cntl.poly_mode != xenos::PolygonModeEnable::kDualMode) { + polygon_type = xenos::PolygonType::kTriangles; + } + switch (polygon_type) { + case xenos::PolygonType::kPoints: + case xenos::PolygonType::kLines: + // Keep non-triangle polygon fill behavior aligned with D3D12 (which + // maps both point and line polygon modes to wireframe). + description_out.polygon_mode = PipelinePolygonMode::kLine; + break; + case xenos::PolygonType::kTriangles: + description_out.polygon_mode = PipelinePolygonMode::kFill; + break; + default: + assert_unhandled_case(polygon_type); + return false; + } + } else { + description_out.polygon_mode = PipelinePolygonMode::kFill; + } + description_out.front_face_clockwise = pa_su_sc_mode_cntl.face != 0; + } else { + description_out.polygon_mode = PipelinePolygonMode::kFill; + } + if (tessellated && REXCVAR_GET(vulkan_tessellation_wireframe) && + device_properties.fillModeNonSolid) { + description_out.polygon_mode = PipelinePolygonMode::kLine; + } + + if (render_target_cache_.GetPath() == RenderTargetCache::Path::kHostRenderTargets) { + if (render_pass_key.depth_and_color_used & 1) { + if (normalized_depth_control.z_enable) { + description_out.depth_write_enable = normalized_depth_control.z_write_enable; + description_out.depth_compare_op = normalized_depth_control.zfunc; + } else { + description_out.depth_compare_op = xenos::CompareFunction::kAlways; + } + if (normalized_depth_control.stencil_enable) { + description_out.stencil_test_enable = 1; + description_out.stencil_front_fail_op = normalized_depth_control.stencilfail; + description_out.stencil_front_pass_op = normalized_depth_control.stencilzpass; + description_out.stencil_front_depth_fail_op = normalized_depth_control.stencilzfail; + description_out.stencil_front_compare_op = normalized_depth_control.stencilfunc; + if (primitive_polygonal && normalized_depth_control.backface_enable) { + description_out.stencil_back_fail_op = normalized_depth_control.stencilfail_bf; + description_out.stencil_back_pass_op = normalized_depth_control.stencilzpass_bf; + description_out.stencil_back_depth_fail_op = normalized_depth_control.stencilzfail_bf; + description_out.stencil_back_compare_op = normalized_depth_control.stencilfunc_bf; + } else { + description_out.stencil_back_fail_op = description_out.stencil_front_fail_op; + description_out.stencil_back_pass_op = description_out.stencil_front_pass_op; + description_out.stencil_back_depth_fail_op = description_out.stencil_front_depth_fail_op; + description_out.stencil_back_compare_op = description_out.stencil_front_compare_op; + } + } + } + + // Color blending and write masks (filled only for the attachments present + // in the render pass object). + uint32_t render_pass_color_rts = render_pass_key.depth_and_color_used >> 1; + assert_true(device_properties.independentBlend); + uint32_t render_pass_color_rts_remaining = render_pass_color_rts; + uint32_t color_rt_index; + while (rex::bit_scan_forward(render_pass_color_rts_remaining, &color_rt_index)) { + render_pass_color_rts_remaining &= ~(uint32_t(1) << color_rt_index); + WritePipelineRenderTargetDescription( + regs.Get(reg::RB_BLENDCONTROL::rt_register_indices[color_rt_index]), + (normalized_color_mask >> (color_rt_index * 4)) & 0b1111, + description_out.render_targets[color_rt_index]); + } + } + + return true; +} + +bool VulkanPipelineCache::ArePipelineRequirementsMet(const PipelineDescription& description) const { + VkShaderStageFlags vertex_shader_stage = + Shader::IsHostVertexShaderTypeDomain( + SpirvShaderTranslator::Modification(description.vertex_shader_modification) + .vertex.host_vertex_shader_type) + ? VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT + : VK_SHADER_STAGE_VERTEX_BIT; + if (!(guest_shader_vertex_stages_ & vertex_shader_stage)) { + return false; + } + + const ui::vulkan::VulkanDevice::Properties& device_properties = + command_processor_.GetVulkanDevice()->properties(); + + if (!device_properties.geometryShader && + description.geometry_shader != PipelineGeometryShader::kNone) { + return false; + } + + // Keep fan handling consistent with D3D12 by always using primitive + // processor conversion to triangle lists instead of native fan topologies. + if (description.primitive_topology == PipelinePrimitiveTopology::kTriangleFan) { + return false; + } + + if (!device_properties.depthClamp && description.depth_clamp_enable) { + return false; + } + + if (!device_properties.pointPolygons && description.polygon_mode == PipelinePolygonMode::kPoint) { + return false; + } + + if (!device_properties.fillModeNonSolid && + description.polygon_mode != PipelinePolygonMode::kFill) { + return false; + } + + assert_true(device_properties.independentBlend); + + if (!device_properties.constantAlphaColorBlendFactors) { + uint32_t color_rts_remaining = description.render_pass_key.depth_and_color_used >> 1; + uint32_t color_rt_index; + while (rex::bit_scan_forward(color_rts_remaining, &color_rt_index)) { + color_rts_remaining &= ~(uint32_t(1) << color_rt_index); + const PipelineRenderTarget& color_rt = description.render_targets[color_rt_index]; + if (color_rt.src_color_blend_factor == PipelineBlendFactor::kConstantAlpha || + color_rt.src_color_blend_factor == PipelineBlendFactor::kOneMinusConstantAlpha || + color_rt.dst_color_blend_factor == PipelineBlendFactor::kConstantAlpha || + color_rt.dst_color_blend_factor == PipelineBlendFactor::kOneMinusConstantAlpha) { + return false; + } + } + } + + return true; +} + +uint32_t VulkanPipelineCache::GetTessellationPatchControlPointCount( + Shader::HostVertexShaderType host_vertex_shader_type, + xenos::TessellationMode tessellation_mode) { + switch (tessellation_mode) { + case xenos::TessellationMode::kDiscrete: + case xenos::TessellationMode::kContinuous: + switch (host_vertex_shader_type) { + case Shader::HostVertexShaderType::kTriangleDomainCPIndexed: + return 3; + case Shader::HostVertexShaderType::kTriangleDomainPatchIndexed: + return 1; + case Shader::HostVertexShaderType::kQuadDomainCPIndexed: + return 4; + case Shader::HostVertexShaderType::kQuadDomainPatchIndexed: + return 1; + default: + return 0; + } + case xenos::TessellationMode::kAdaptive: + switch (host_vertex_shader_type) { + case Shader::HostVertexShaderType::kTriangleDomainPatchIndexed: + return 3; + case Shader::HostVertexShaderType::kQuadDomainPatchIndexed: + return 4; + default: + return 0; + } + default: + return 0; + } +} + +VkShaderModule VulkanPipelineCache::GetTessellationVertexShader(bool adaptive) { + bool& attempted = adaptive ? tessellation_adaptive_vertex_shader_attempted_ + : tessellation_indexed_vertex_shader_attempted_; + VkShaderModule& shader_module = + adaptive ? tessellation_adaptive_vertex_shader_ : tessellation_indexed_vertex_shader_; + if (attempted) { + return shader_module; + } + attempted = true; + + std::vector shader_spirv; + std::string compile_error; + std::string source = adaptive ? GetTessellationAdaptiveVertexShaderGlsl() + : GetTessellationIndexedVertexShaderGlsl(); + if (!command_processor_.CompileGlslToSpirv(VK_SHADER_STAGE_VERTEX_BIT, source, shader_spirv, + compile_error)) { + REXGPU_ERROR( + "VulkanPipelineCache: Failed to compile tessellation {} vertex " + "shader: {}", + adaptive ? "adaptive" : "indexed", compile_error); + shader_module = VK_NULL_HANDLE; + return shader_module; + } + + shader_module = ui::vulkan::util::CreateShaderModule(command_processor_.GetVulkanDevice(), + shader_spirv.data(), + sizeof(uint32_t) * shader_spirv.size()); + if (shader_module == VK_NULL_HANDLE) { + REXGPU_ERROR( + "VulkanPipelineCache: Failed to create tessellation {} vertex " + "shader module", + adaptive ? "adaptive" : "indexed"); + } + return shader_module; +} + +VkShaderModule VulkanPipelineCache::GetTessellationControlShader( + Shader::HostVertexShaderType host_vertex_shader_type, + xenos::TessellationMode tessellation_mode) { + TessellationControlShaderKey key; + key.host_vertex_shader_type = host_vertex_shader_type; + key.tessellation_mode = tessellation_mode; + auto it = tessellation_control_shaders_.find(key); + if (it != tessellation_control_shaders_.end()) { + return it->second; + } + + uint32_t input_control_points = + GetTessellationPatchControlPointCount(host_vertex_shader_type, tessellation_mode); + uint32_t output_control_points = 0; + if (tessellation_mode == xenos::TessellationMode::kAdaptive) { + output_control_points = 1; + } else if (IsPatchIndexedHostVertexShaderType(host_vertex_shader_type)) { + output_control_points = 1; + } else if (IsTriangleDomainHostVertexShaderType(host_vertex_shader_type)) { + output_control_points = 3; + } else if (IsQuadDomainHostVertexShaderType(host_vertex_shader_type)) { + output_control_points = 4; + } + if (!input_control_points || !output_control_points) { + tessellation_control_shaders_.emplace(key, VK_NULL_HANDLE); + return VK_NULL_HANDLE; + } + + std::vector shader_spirv; + std::string compile_error; + std::string source = GetTessellationControlShaderGlsl( + host_vertex_shader_type, tessellation_mode, input_control_points, output_control_points); + if (!command_processor_.CompileGlslToSpirv(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, source, + shader_spirv, compile_error)) { + REXGPU_ERROR( + "VulkanPipelineCache: Failed to compile tessellation control shader " + "0x{:08X}: {}", + key.key, compile_error); + tessellation_control_shaders_.emplace(key, VK_NULL_HANDLE); + return VK_NULL_HANDLE; + } + + VkShaderModule shader_module = ui::vulkan::util::CreateShaderModule( + command_processor_.GetVulkanDevice(), shader_spirv.data(), + sizeof(uint32_t) * shader_spirv.size()); + if (shader_module == VK_NULL_HANDLE) { + REXGPU_ERROR( + "VulkanPipelineCache: Failed to create tessellation control shader " + "module 0x{:08X}", + key.key); + } + tessellation_control_shaders_.emplace(key, shader_module); + return shader_module; +} + +bool VulkanPipelineCache::GetGeometryShaderKey( + PipelineGeometryShader geometry_shader_type, + SpirvShaderTranslator::Modification vertex_shader_modification, + SpirvShaderTranslator::Modification pixel_shader_modification, GeometryShaderKey& key_out) { + if (geometry_shader_type == PipelineGeometryShader::kNone) { + return false; + } + // For kPointListAsTriangleStrip, output_point_parameters has a different + // meaning (the coordinates, not the size). However, the AsTriangleStrip host + // vertex shader types are needed specifically when geometry shaders are not + // supported as fallbacks. + if (vertex_shader_modification.vertex.host_vertex_shader_type == + Shader::HostVertexShaderType::kPointListAsTriangleStrip || + vertex_shader_modification.vertex.host_vertex_shader_type == + Shader::HostVertexShaderType::kRectangleListAsTriangleStrip) { + assert_always(); + return false; + } + GeometryShaderKey key; + key.type = geometry_shader_type; + key.interpolator_count = rex::bit_count(vertex_shader_modification.vertex.interpolator_mask); + key.user_clip_plane_count = vertex_shader_modification.vertex.user_clip_plane_count; + key.user_clip_plane_cull = vertex_shader_modification.vertex.user_clip_plane_cull; + key.has_vertex_kill_and = vertex_shader_modification.vertex.vertex_kill_and; + key.has_point_size = vertex_shader_modification.vertex.output_point_parameters; + key.has_point_coordinates = pixel_shader_modification.pixel.param_gen_point; + key.point_ps_ucp_mode = vertex_shader_modification.vertex.point_ps_ucp_mode; + key_out = key; + return true; +} + +VkShaderModule VulkanPipelineCache::GetGeometryShader(GeometryShaderKey key) { + auto it = geometry_shaders_.find(key); + if (it != geometry_shaders_.end()) { + return it->second; + } + + std::vector id_vector_temp; + std::vector uint_vector_temp; + + spv::ExecutionMode input_primitive_execution_mode = spv::ExecutionMode(0); + uint32_t input_primitive_vertex_count = 0; + spv::ExecutionMode output_primitive_execution_mode = spv::ExecutionMode(0); + uint32_t output_max_vertices = 0; + switch (key.type) { + case PipelineGeometryShader::kPointList: + // Point to a strip of 2 triangles. + input_primitive_execution_mode = spv::ExecutionModeInputPoints; + input_primitive_vertex_count = 1; + output_primitive_execution_mode = spv::ExecutionModeOutputTriangleStrip; + output_max_vertices = 4; + break; + case PipelineGeometryShader::kRectangleList: + // Triangle to a strip of 2 triangles. + input_primitive_execution_mode = spv::ExecutionModeTriangles; + input_primitive_vertex_count = 3; + output_primitive_execution_mode = spv::ExecutionModeOutputTriangleStrip; + output_max_vertices = 4; + break; + case PipelineGeometryShader::kQuadList: + // 4 vertices passed via a line list with adjacency to a strip of 2 + // triangles. + input_primitive_execution_mode = spv::ExecutionModeInputLinesAdjacency; + input_primitive_vertex_count = 4; + output_primitive_execution_mode = spv::ExecutionModeOutputTriangleStrip; + output_max_vertices = 4; + break; + default: + assert_unhandled_case(key.type); + } + + uint32_t clip_distance_count = key.user_clip_plane_cull ? 0 : key.user_clip_plane_count; + uint32_t point_user_cull_distance_count = + key.type == PipelineGeometryShader::kPointList && key.user_clip_plane_cull + ? key.user_clip_plane_count + : 0; + uint32_t cull_distance_count = point_user_cull_distance_count + key.has_vertex_kill_and; + bool point_recalculate_clip_distances = key.type == PipelineGeometryShader::kPointList && + clip_distance_count && key.point_ps_ucp_mode >= 2; + bool point_recalculate_cull_distances = key.type == PipelineGeometryShader::kPointList && + point_user_cull_distance_count && + key.point_ps_ucp_mode >= 3; + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Properties& device_properties = vulkan_device->properties(); + const ui::vulkan::VulkanDevice::Extensions& device_extensions = vulkan_device->extensions(); + spv::SpvBuildLogger builder_logger; + spv::SpvBuildLogger* builder_logger_ptr = nullptr; + spv::SpvVersion spirv_version; + if (device_properties.apiVersion >= VK_MAKE_API_VERSION(0, 1, 2, 0)) { + spirv_version = spv::Spv_1_5; + } else if (device_extensions.ext_1_2_KHR_spirv_1_4) { + spirv_version = spv::Spv_1_4; + } else if (device_properties.apiVersion >= VK_MAKE_API_VERSION(0, 1, 1, 0)) { + spirv_version = spv::Spv_1_3; + } else { + spirv_version = spv::Spv_1_0; + // Keep the build log around for compatibility diagnostics on older paths. + builder_logger_ptr = &builder_logger; + } + SpirvBuilder builder(spirv_version, (SpirvShaderTranslator::kSpirvMagicToolId << 16) | 1, + builder_logger_ptr); + spv::Id ext_inst_glsl_std_450 = builder.import("GLSL.std.450"); + builder.addCapability(spv::CapabilityGeometry); + if (clip_distance_count) { + builder.addCapability(spv::CapabilityClipDistance); + } + if (cull_distance_count) { + builder.addCapability(spv::CapabilityCullDistance); + } + bool denorm_flush_to_zero_float32 = device_properties.shaderDenormFlushToZeroFloat32; + bool signed_zero_inf_nan_preserve_float32 = + device_properties.shaderSignedZeroInfNanPreserveFloat32; + bool rounding_mode_rte_float32 = device_properties.shaderRoundingModeRTEFloat32; + if (spirv_version < spv::Spv_1_4) { + if (denorm_flush_to_zero_float32 || signed_zero_inf_nan_preserve_float32 || + rounding_mode_rte_float32) { + builder.addExtension("SPV_KHR_float_controls"); + } + } + builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450); + builder.setSource(spv::SourceLanguageUnknown, 0); + + std::vector main_interface; + + spv::Id type_void = builder.makeVoidType(); + spv::Id type_bool = builder.makeBoolType(); + spv::Id type_bool4 = builder.makeVectorType(type_bool, 4); + spv::Id type_int = builder.makeIntType(32); + spv::Id type_float = builder.makeFloatType(32); + spv::Id type_float2 = builder.makeVectorType(type_float, 2); + spv::Id type_float3 = builder.makeVectorType(type_float, 3); + spv::Id type_float4 = builder.makeVectorType(type_float, 4); + spv::Id type_float4_array_6 = + builder.makeArrayType(type_float4, builder.makeUintConstant(6), sizeof(float) * 4); + builder.addDecoration(type_float4_array_6, spv::DecorationArrayStride, sizeof(float) * 4); + spv::Id type_clip_distances = + clip_distance_count + ? builder.makeArrayType(type_float, builder.makeUintConstant(clip_distance_count), 0) + : spv::NoType; + spv::Id type_cull_distances = + cull_distance_count + ? builder.makeArrayType(type_float, builder.makeUintConstant(cull_distance_count), 0) + : spv::NoType; + + // System constants. + // For points: + // - float2 point_constant_diameter + // - float2 point_screen_diameter_to_ndc_radius + // - float3 ndc_scale + // - float3 ndc_offset + // - float4[6] user_clip_planes + enum PointConstant : uint32_t { + kPointConstantConstantDiameter, + kPointConstantScreenDiameterToNdcRadius, + kPointConstantNdcScale, + kPointConstantNdcOffset, + kPointConstantUserClipPlanes, + kPointConstantCount, + }; + spv::Id type_system_constants = spv::NoType; + if (key.type == PipelineGeometryShader::kPointList) { + id_vector_temp.clear(); + id_vector_temp.resize(kPointConstantCount); + id_vector_temp[kPointConstantConstantDiameter] = type_float2; + id_vector_temp[kPointConstantScreenDiameterToNdcRadius] = type_float2; + id_vector_temp[kPointConstantNdcScale] = type_float3; + id_vector_temp[kPointConstantNdcOffset] = type_float3; + id_vector_temp[kPointConstantUserClipPlanes] = type_float4_array_6; + type_system_constants = builder.makeStructType(id_vector_temp, "XeSystemConstants"); + builder.addMemberName(type_system_constants, kPointConstantConstantDiameter, + "point_constant_diameter"); + builder.addMemberDecoration( + type_system_constants, kPointConstantConstantDiameter, spv::DecorationOffset, + int(offsetof(SpirvShaderTranslator::SystemConstants, point_constant_diameter))); + builder.addMemberName(type_system_constants, kPointConstantScreenDiameterToNdcRadius, + "point_screen_diameter_to_ndc_radius"); + builder.addMemberDecoration( + type_system_constants, kPointConstantScreenDiameterToNdcRadius, spv::DecorationOffset, + int(offsetof(SpirvShaderTranslator::SystemConstants, point_screen_diameter_to_ndc_radius))); + builder.addMemberName(type_system_constants, kPointConstantNdcScale, "ndc_scale"); + builder.addMemberDecoration(type_system_constants, kPointConstantNdcScale, + spv::DecorationOffset, + int(offsetof(SpirvShaderTranslator::SystemConstants, ndc_scale))); + builder.addMemberName(type_system_constants, kPointConstantNdcOffset, "ndc_offset"); + builder.addMemberDecoration(type_system_constants, kPointConstantNdcOffset, + spv::DecorationOffset, + int(offsetof(SpirvShaderTranslator::SystemConstants, ndc_offset))); + builder.addMemberName(type_system_constants, kPointConstantUserClipPlanes, "user_clip_planes"); + builder.addMemberDecoration( + type_system_constants, kPointConstantUserClipPlanes, spv::DecorationOffset, + int(offsetof(SpirvShaderTranslator::SystemConstants, user_clip_planes))); + } + spv::Id uniform_system_constants = spv::NoResult; + if (type_system_constants != spv::NoType) { + builder.addDecoration(type_system_constants, spv::DecorationBlock); + uniform_system_constants = + builder.createVariable(spv::NoPrecision, spv::StorageClassUniform, type_system_constants, + "xe_uniform_system_constants"); + builder.addDecoration(uniform_system_constants, spv::DecorationDescriptorSet, + int(SpirvShaderTranslator::kDescriptorSetConstants)); + builder.addDecoration(uniform_system_constants, spv::DecorationBinding, + int(SpirvShaderTranslator::kConstantBufferSystem)); + main_interface.push_back(uniform_system_constants); + } + + // Inputs and outputs - matching glslang order, in gl_PerVertex gl_in[], + // user-defined outputs, user-defined inputs, out gl_PerVertex. + + spv::Id const_input_primitive_vertex_count = + builder.makeUintConstant(input_primitive_vertex_count); + + // in gl_PerVertex gl_in[]. + // gl_Position. + id_vector_temp.clear(); + uint32_t member_in_gl_per_vertex_position = uint32_t(id_vector_temp.size()); + id_vector_temp.push_back(type_float4); + spv::Id const_member_in_gl_per_vertex_position = + builder.makeIntConstant(int32_t(member_in_gl_per_vertex_position)); + // gl_ClipDistance. + uint32_t member_in_gl_per_vertex_clip_distance = UINT32_MAX; + spv::Id const_member_in_gl_per_vertex_clip_distance = spv::NoResult; + if (clip_distance_count) { + member_in_gl_per_vertex_clip_distance = uint32_t(id_vector_temp.size()); + id_vector_temp.push_back(type_clip_distances); + const_member_in_gl_per_vertex_clip_distance = + builder.makeIntConstant(int32_t(member_in_gl_per_vertex_clip_distance)); + } + // gl_CullDistance. + uint32_t member_in_gl_per_vertex_cull_distance = UINT32_MAX; + if (cull_distance_count) { + member_in_gl_per_vertex_cull_distance = uint32_t(id_vector_temp.size()); + id_vector_temp.push_back(type_cull_distances); + } + // Structure and array. + spv::Id type_struct_in_gl_per_vertex = builder.makeStructType(id_vector_temp, "gl_PerVertex"); + builder.addMemberName(type_struct_in_gl_per_vertex, member_in_gl_per_vertex_position, + "gl_Position"); + builder.addMemberDecoration(type_struct_in_gl_per_vertex, member_in_gl_per_vertex_position, + spv::DecorationBuiltIn, spv::BuiltInPosition); + if (clip_distance_count) { + builder.addMemberName(type_struct_in_gl_per_vertex, member_in_gl_per_vertex_clip_distance, + "gl_ClipDistance"); + builder.addMemberDecoration(type_struct_in_gl_per_vertex, member_in_gl_per_vertex_clip_distance, + spv::DecorationBuiltIn, spv::BuiltInClipDistance); + } + if (cull_distance_count) { + builder.addMemberName(type_struct_in_gl_per_vertex, member_in_gl_per_vertex_cull_distance, + "gl_CullDistance"); + builder.addMemberDecoration(type_struct_in_gl_per_vertex, member_in_gl_per_vertex_cull_distance, + spv::DecorationBuiltIn, spv::BuiltInCullDistance); + } + builder.addDecoration(type_struct_in_gl_per_vertex, spv::DecorationBlock); + spv::Id type_array_in_gl_per_vertex = + builder.makeArrayType(type_struct_in_gl_per_vertex, const_input_primitive_vertex_count, 0); + spv::Id in_gl_per_vertex = builder.createVariable(spv::NoPrecision, spv::StorageClassInput, + type_array_in_gl_per_vertex, "gl_in"); + main_interface.push_back(in_gl_per_vertex); + + uint32_t output_location = 0; + + // Interpolators outputs. + std::array out_interpolators; + for (uint32_t i = 0; i < key.interpolator_count; ++i) { + spv::Id out_interpolator = + builder.createVariable(spv::NoPrecision, spv::StorageClassOutput, type_float4, + fmt::format("xe_out_interpolator_{}", i).c_str()); + out_interpolators[i] = out_interpolator; + builder.addDecoration(out_interpolator, spv::DecorationLocation, int(output_location)); + builder.addDecoration(out_interpolator, spv::DecorationInvariant); + main_interface.push_back(out_interpolator); + ++output_location; + } + + // Point coordinate output. + spv::Id out_point_coordinates = spv::NoResult; + if (key.has_point_coordinates) { + out_point_coordinates = builder.createVariable(spv::NoPrecision, spv::StorageClassOutput, + type_float2, "xe_out_point_coordinates"); + builder.addDecoration(out_point_coordinates, spv::DecorationLocation, int(output_location)); + builder.addDecoration(out_point_coordinates, spv::DecorationInvariant); + main_interface.push_back(out_point_coordinates); + ++output_location; + } + + uint32_t input_location = 0; + + // Interpolator inputs. + std::array in_interpolators; + for (uint32_t i = 0; i < key.interpolator_count; ++i) { + spv::Id in_interpolator = builder.createVariable( + spv::NoPrecision, spv::StorageClassInput, + builder.makeArrayType(type_float4, const_input_primitive_vertex_count, 0), + fmt::format("xe_in_interpolator_{}", i).c_str()); + in_interpolators[i] = in_interpolator; + builder.addDecoration(in_interpolator, spv::DecorationLocation, int(input_location)); + main_interface.push_back(in_interpolator); + ++input_location; + } + + // Point size input. + spv::Id in_point_size = spv::NoResult; + if (key.has_point_size) { + in_point_size = builder.createVariable( + spv::NoPrecision, spv::StorageClassInput, + builder.makeArrayType(type_float, const_input_primitive_vertex_count, 0), + "xe_in_point_size"); + builder.addDecoration(in_point_size, spv::DecorationLocation, int(input_location)); + main_interface.push_back(in_point_size); + ++input_location; + } + + // out gl_PerVertex. + // gl_Position. + id_vector_temp.clear(); + uint32_t member_out_gl_per_vertex_position = uint32_t(id_vector_temp.size()); + id_vector_temp.push_back(type_float4); + spv::Id const_member_out_gl_per_vertex_position = + builder.makeIntConstant(int32_t(member_out_gl_per_vertex_position)); + // gl_ClipDistance. + uint32_t member_out_gl_per_vertex_clip_distance = UINT32_MAX; + spv::Id const_member_out_gl_per_vertex_clip_distance = spv::NoResult; + if (clip_distance_count) { + member_out_gl_per_vertex_clip_distance = uint32_t(id_vector_temp.size()); + id_vector_temp.push_back(type_clip_distances); + const_member_out_gl_per_vertex_clip_distance = + builder.makeIntConstant(int32_t(member_out_gl_per_vertex_clip_distance)); + } + // Structure. + spv::Id type_struct_out_gl_per_vertex = builder.makeStructType(id_vector_temp, "gl_PerVertex"); + builder.addMemberName(type_struct_out_gl_per_vertex, member_out_gl_per_vertex_position, + "gl_Position"); + builder.addMemberDecoration(type_struct_out_gl_per_vertex, member_out_gl_per_vertex_position, + spv::DecorationBuiltIn, spv::BuiltInPosition); + if (clip_distance_count) { + builder.addMemberName(type_struct_out_gl_per_vertex, member_out_gl_per_vertex_clip_distance, + "gl_ClipDistance"); + builder.addMemberDecoration(type_struct_out_gl_per_vertex, + member_out_gl_per_vertex_clip_distance, spv::DecorationBuiltIn, + spv::BuiltInClipDistance); + } + builder.addDecoration(type_struct_out_gl_per_vertex, spv::DecorationBlock); + spv::Id out_gl_per_vertex = builder.createVariable(spv::NoPrecision, spv::StorageClassOutput, + type_struct_out_gl_per_vertex, ""); + builder.addDecoration(out_gl_per_vertex, spv::DecorationInvariant); + main_interface.push_back(out_gl_per_vertex); + + // Begin the main function. + std::vector main_param_types; + std::vector> main_precisions; + spv::Block* main_entry; + spv::Function* main_function = builder.makeFunctionEntry( + spv::NoPrecision, type_void, "main", main_param_types, main_precisions, &main_entry); + spv::Instruction* entry_point = + builder.addEntryPoint(spv::ExecutionModelGeometry, main_function, "main"); + for (spv::Id interface_id : main_interface) { + entry_point->addIdOperand(interface_id); + } + builder.addExecutionMode(main_function, input_primitive_execution_mode); + builder.addExecutionMode(main_function, spv::ExecutionModeInvocations, 1); + builder.addExecutionMode(main_function, output_primitive_execution_mode); + builder.addExecutionMode(main_function, spv::ExecutionModeOutputVertices, + int(output_max_vertices)); + if (denorm_flush_to_zero_float32) { + builder.addCapability(spv::CapabilityDenormFlushToZero); + builder.addExecutionMode(main_function, spv::ExecutionModeDenormFlushToZero, 32); + } + if (signed_zero_inf_nan_preserve_float32) { + builder.addCapability(spv::CapabilitySignedZeroInfNanPreserve); + builder.addExecutionMode(main_function, spv::ExecutionModeSignedZeroInfNanPreserve, 32); + } + if (rounding_mode_rte_float32) { + builder.addCapability(spv::CapabilityRoundingModeRTE); + builder.addExecutionMode(main_function, spv::ExecutionModeRoundingModeRTE, 32); + } + + // Note that after every OpEmitVertex, all output variables are undefined. + + // Discard the whole primitive if any vertex has a NaN position (may also be + // set to NaN for emulation of vertex killing with the OR operator). + for (uint32_t i = 0; i < input_primitive_vertex_count; ++i) { + id_vector_temp.clear(); + id_vector_temp.push_back(builder.makeIntConstant(int32_t(i))); + id_vector_temp.push_back(const_member_in_gl_per_vertex_position); + spv::Id position_is_nan = builder.createUnaryOp( + spv::OpAny, type_bool, + builder.createUnaryOp( + spv::OpIsNan, type_bool4, + builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), + spv::NoPrecision))); + spv::Block& discard_predecessor = *builder.getBuildPoint(); + spv::Block& discard_then_block = builder.makeNewBlock(); + spv::Block& discard_merge_block = builder.makeNewBlock(); + builder.createSelectionMerge(&discard_merge_block, spv::SelectionControlDontFlattenMask); + { + std::unique_ptr branch_conditional_op( + std::make_unique(spv::OpBranchConditional)); + branch_conditional_op->addIdOperand(position_is_nan); + branch_conditional_op->addIdOperand(discard_then_block.getId()); + branch_conditional_op->addIdOperand(discard_merge_block.getId()); + branch_conditional_op->addImmediateOperand(1); + branch_conditional_op->addImmediateOperand(2); + discard_predecessor.addInstruction(std::move(branch_conditional_op)); + } + discard_then_block.addPredecessor(&discard_predecessor); + discard_merge_block.addPredecessor(&discard_predecessor); + builder.setBuildPoint(&discard_then_block); + builder.createNoResultOp(spv::OpReturn); + builder.setBuildPoint(&discard_merge_block); + } + + // Cull the whole primitive if any cull distance for all vertices in the + // primitive is < 0. + // For point lists with ps_ucp_mode 3, user cull plane distances are + // calculated per expanded vertex later. + if (cull_distance_count) { + spv::Id const_member_in_gl_per_vertex_cull_distance = + builder.makeIntConstant(int32_t(member_in_gl_per_vertex_cull_distance)); + spv::Id const_float_0 = builder.makeFloatConstant(0.0f); + spv::Id cull_condition = spv::NoResult; + uint32_t cull_distance_start = + point_recalculate_cull_distances ? point_user_cull_distance_count : 0; + if (cull_distance_start < cull_distance_count) { + for (uint32_t i = cull_distance_start; i < cull_distance_count; ++i) { + for (uint32_t j = 0; j < input_primitive_vertex_count; ++j) { + id_vector_temp.clear(); + id_vector_temp.push_back(builder.makeIntConstant(int32_t(j))); + id_vector_temp.push_back(const_member_in_gl_per_vertex_cull_distance); + id_vector_temp.push_back(builder.makeIntConstant(int32_t(i))); + spv::Id cull_distance_is_negative = builder.createBinOp( + spv::OpFOrdLessThan, type_bool, + builder.createLoad(builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, + id_vector_temp), + spv::NoPrecision), + const_float_0); + if (cull_condition != spv::NoResult) { + cull_condition = builder.createBinOp(spv::OpLogicalAnd, type_bool, cull_condition, + cull_distance_is_negative); + } else { + cull_condition = cull_distance_is_negative; + } + } + } + assert_true(cull_condition != spv::NoResult); + spv::Block& discard_predecessor = *builder.getBuildPoint(); + spv::Block& discard_then_block = builder.makeNewBlock(); + spv::Block& discard_merge_block = builder.makeNewBlock(); + builder.createSelectionMerge(&discard_merge_block, spv::SelectionControlDontFlattenMask); + { + std::unique_ptr branch_conditional_op( + std::make_unique(spv::OpBranchConditional)); + branch_conditional_op->addIdOperand(cull_condition); + branch_conditional_op->addIdOperand(discard_then_block.getId()); + branch_conditional_op->addIdOperand(discard_merge_block.getId()); + branch_conditional_op->addImmediateOperand(1); + branch_conditional_op->addImmediateOperand(2); + discard_predecessor.addInstruction(std::move(branch_conditional_op)); + } + discard_then_block.addPredecessor(&discard_predecessor); + discard_merge_block.addPredecessor(&discard_predecessor); + builder.setBuildPoint(&discard_then_block); + builder.createNoResultOp(spv::OpReturn); + builder.setBuildPoint(&discard_merge_block); + } + } + + switch (key.type) { + case PipelineGeometryShader::kPointList: { + // Expand the point sprite, with left-to-right, top-to-bottom UVs. + + spv::Id const_int_0 = builder.makeIntConstant(0); + spv::Id const_int_1 = builder.makeIntConstant(1); + spv::Id const_float_0 = builder.makeFloatConstant(0.0f); + + // Load the point diameter in guest pixels. + id_vector_temp.clear(); + id_vector_temp.push_back(builder.makeIntConstant(int32_t(kPointConstantConstantDiameter))); + id_vector_temp.push_back(const_int_0); + spv::Id point_guest_diameter_x = + builder.createLoad(builder.createAccessChain(spv::StorageClassUniform, + uniform_system_constants, id_vector_temp), + spv::NoPrecision); + id_vector_temp.back() = const_int_1; + spv::Id point_guest_diameter_y = + builder.createLoad(builder.createAccessChain(spv::StorageClassUniform, + uniform_system_constants, id_vector_temp), + spv::NoPrecision); + if (key.has_point_size) { + // The vertex shader's header writes -1.0 to point_size by default, so + // any non-negative value means that it was overwritten by the + // translated vertex shader, and needs to be used instead of the + // constant size. The per-vertex diameter is already clamped in the + // vertex shader (combined with making it non-negative). + id_vector_temp.clear(); + // 0 is the input primitive vertex index. + id_vector_temp.push_back(const_int_0); + spv::Id point_vertex_diameter = builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_point_size, id_vector_temp), + spv::NoPrecision); + spv::Id point_vertex_diameter_written = builder.createBinOp( + spv::OpFOrdGreaterThanEqual, type_bool, point_vertex_diameter, const_float_0); + point_guest_diameter_x = + builder.createTriOp(spv::OpSelect, type_float, point_vertex_diameter_written, + point_vertex_diameter, point_guest_diameter_x); + point_guest_diameter_y = + builder.createTriOp(spv::OpSelect, type_float, point_vertex_diameter_written, + point_vertex_diameter, point_guest_diameter_y); + } + + // 4D5307F1 has zero-size snowflakes, drop them quicker, and also drop + // points with a constant size of zero since point lists may also be used + // as just "compute" with memexport. + spv::Id point_size_not_zero = + builder.createBinOp(spv::OpLogicalAnd, type_bool, + builder.createBinOp(spv::OpFOrdGreaterThan, type_bool, + point_guest_diameter_x, const_float_0), + builder.createBinOp(spv::OpFOrdGreaterThan, type_bool, + point_guest_diameter_y, const_float_0)); + spv::Block& point_size_zero_predecessor = *builder.getBuildPoint(); + spv::Block& point_size_zero_then_block = builder.makeNewBlock(); + spv::Block& point_size_zero_merge_block = builder.makeNewBlock(); + builder.createSelectionMerge(&point_size_zero_merge_block, + spv::SelectionControlDontFlattenMask); + { + std::unique_ptr branch_conditional_op( + std::make_unique(spv::OpBranchConditional)); + branch_conditional_op->addIdOperand(point_size_not_zero); + branch_conditional_op->addIdOperand(point_size_zero_merge_block.getId()); + branch_conditional_op->addIdOperand(point_size_zero_then_block.getId()); + branch_conditional_op->addImmediateOperand(2); + branch_conditional_op->addImmediateOperand(1); + point_size_zero_predecessor.addInstruction(std::move(branch_conditional_op)); + } + point_size_zero_then_block.addPredecessor(&point_size_zero_predecessor); + point_size_zero_merge_block.addPredecessor(&point_size_zero_predecessor); + builder.setBuildPoint(&point_size_zero_then_block); + builder.createNoResultOp(spv::OpReturn); + builder.setBuildPoint(&point_size_zero_merge_block); + + // Transform the diameter in the guest screen coordinates to radius in the + // normalized device coordinates, and then to the clip space by + // multiplying by W. + id_vector_temp.clear(); + id_vector_temp.push_back( + builder.makeIntConstant(int32_t(kPointConstantScreenDiameterToNdcRadius))); + id_vector_temp.push_back(const_int_0); + spv::Id point_radius_x = builder.createNoContractionBinOp( + spv::OpFMul, type_float, point_guest_diameter_x, + builder.createLoad(builder.createAccessChain(spv::StorageClassUniform, + uniform_system_constants, id_vector_temp), + spv::NoPrecision)); + id_vector_temp.back() = const_int_1; + spv::Id point_radius_y = builder.createNoContractionBinOp( + spv::OpFMul, type_float, point_guest_diameter_y, + builder.createLoad(builder.createAccessChain(spv::StorageClassUniform, + uniform_system_constants, id_vector_temp), + spv::NoPrecision)); + id_vector_temp.clear(); + // 0 is the input primitive vertex index. + id_vector_temp.push_back(const_int_0); + id_vector_temp.push_back(const_member_in_gl_per_vertex_position); + spv::Id point_position = builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), + spv::NoPrecision); + spv::Id point_w = builder.createCompositeExtract(point_position, type_float, 3); + point_radius_x = + builder.createNoContractionBinOp(spv::OpFMul, type_float, point_radius_x, point_w); + point_radius_y = + builder.createNoContractionBinOp(spv::OpFMul, type_float, point_radius_y, point_w); + + // Load the inputs for the guest point. + // Interpolators. + std::array point_interpolators; + id_vector_temp.clear(); + // 0 is the input primitive vertex index. + id_vector_temp.push_back(const_int_0); + for (uint32_t i = 0; i < key.interpolator_count; ++i) { + point_interpolators[i] = builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_interpolators[i], id_vector_temp), + spv::NoPrecision); + } + // Positions. + spv::Id point_x = builder.createCompositeExtract(point_position, type_float, 0); + spv::Id point_y = builder.createCompositeExtract(point_position, type_float, 1); + std::array point_edge_x, point_edge_y; + for (uint32_t i = 0; i < 2; ++i) { + spv::Op point_radius_add_op = i ? spv::OpFAdd : spv::OpFSub; + point_edge_x[i] = builder.createNoContractionBinOp(point_radius_add_op, type_float, point_x, + point_radius_x); + point_edge_y[i] = builder.createNoContractionBinOp(point_radius_add_op, type_float, point_y, + point_radius_y); + }; + spv::Id point_z = builder.createCompositeExtract(point_position, type_float, 2); + // Clip distances. + spv::Id point_clip_distances = spv::NoResult; + std::vector point_user_clip_planes; + point_user_clip_planes.reserve(clip_distance_count); + spv::Id point_ndc_scale = spv::NoResult; + spv::Id point_ndc_offset = spv::NoResult; + if (point_recalculate_clip_distances || point_recalculate_cull_distances) { + id_vector_temp.clear(); + id_vector_temp.push_back(builder.makeIntConstant(int32_t(kPointConstantNdcScale))); + point_ndc_scale = + builder.createLoad(builder.createAccessChain(spv::StorageClassUniform, + uniform_system_constants, id_vector_temp), + spv::NoPrecision); + id_vector_temp.clear(); + id_vector_temp.push_back(builder.makeIntConstant(int32_t(kPointConstantNdcOffset))); + point_ndc_offset = + builder.createLoad(builder.createAccessChain(spv::StorageClassUniform, + uniform_system_constants, id_vector_temp), + spv::NoPrecision); + uint32_t point_user_clip_plane_count = + point_recalculate_cull_distances ? point_user_cull_distance_count : clip_distance_count; + for (uint32_t i = 0; i < point_user_clip_plane_count; ++i) { + id_vector_temp.clear(); + id_vector_temp.push_back(builder.makeIntConstant(int32_t(kPointConstantUserClipPlanes))); + id_vector_temp.push_back(builder.makeIntConstant(int32_t(i))); + point_user_clip_planes.push_back(builder.createLoad( + builder.createAccessChain(spv::StorageClassUniform, uniform_system_constants, + id_vector_temp), + spv::NoPrecision)); + } + } else if (clip_distance_count) { + id_vector_temp.clear(); + // 0 is the input primitive vertex index. + id_vector_temp.push_back(const_int_0); + id_vector_temp.push_back(const_member_in_gl_per_vertex_clip_distance); + point_clip_distances = builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), + spv::NoPrecision); + } + + if (point_recalculate_cull_distances) { + // Cull if any user clip plane has all expanded vertices outside. + std::array point_guest_positions; + for (uint32_t i = 0; i < 4; ++i) { + uint32_t point_vertex_x = i >> 1; + uint32_t point_vertex_y = i & 1; + id_vector_temp.clear(); + id_vector_temp.push_back(point_edge_x[point_vertex_x]); + id_vector_temp.push_back(point_edge_y[point_vertex_y]); + id_vector_temp.push_back(point_z); + id_vector_temp.push_back(point_w); + spv::Id point_vertex_position = + builder.createCompositeConstruct(type_float4, id_vector_temp); + id_vector_temp.clear(); + id_vector_temp.push_back( + builder.createCompositeExtract(point_vertex_position, type_float, 0)); + id_vector_temp.push_back( + builder.createCompositeExtract(point_vertex_position, type_float, 1)); + id_vector_temp.push_back( + builder.createCompositeExtract(point_vertex_position, type_float, 2)); + spv::Id point_vertex_position_xyz = + builder.createCompositeConstruct(type_float3, id_vector_temp); + spv::Id point_guest_position_xyz = builder.createNoContractionBinOp( + spv::OpFSub, type_float3, point_vertex_position_xyz, + builder.createNoContractionBinOp(spv::OpVectorTimesScalar, type_float3, + point_ndc_offset, point_w)); + point_guest_position_xyz = builder.createNoContractionBinOp( + spv::OpFDiv, type_float3, point_guest_position_xyz, point_ndc_scale); + id_vector_temp.clear(); + id_vector_temp.push_back( + builder.createCompositeExtract(point_guest_position_xyz, type_float, 0)); + id_vector_temp.push_back( + builder.createCompositeExtract(point_guest_position_xyz, type_float, 1)); + id_vector_temp.push_back( + builder.createCompositeExtract(point_guest_position_xyz, type_float, 2)); + id_vector_temp.push_back(point_w); + point_guest_positions[i] = builder.createCompositeConstruct(type_float4, id_vector_temp); + } + spv::Id point_cull_condition = spv::NoResult; + for (uint32_t i = 0; i < point_user_cull_distance_count; ++i) { + spv::Id point_plane_cull_condition = spv::NoResult; + for (uint32_t j = 0; j < 4; ++j) { + spv::Id point_distance_is_negative = builder.createBinOp( + spv::OpFOrdLessThan, type_bool, + builder.createBinOp(spv::OpDot, type_float, point_guest_positions[j], + point_user_clip_planes[i]), + const_float_0); + if (point_plane_cull_condition != spv::NoResult) { + point_plane_cull_condition = + builder.createBinOp(spv::OpLogicalAnd, type_bool, point_plane_cull_condition, + point_distance_is_negative); + } else { + point_plane_cull_condition = point_distance_is_negative; + } + } + if (point_cull_condition != spv::NoResult) { + point_cull_condition = builder.createBinOp( + spv::OpLogicalOr, type_bool, point_cull_condition, point_plane_cull_condition); + } else { + point_cull_condition = point_plane_cull_condition; + } + } + assert_true(point_cull_condition != spv::NoResult); + spv::Block& point_cull_predecessor = *builder.getBuildPoint(); + spv::Block& point_cull_then_block = builder.makeNewBlock(); + spv::Block& point_cull_merge_block = builder.makeNewBlock(); + builder.createSelectionMerge(&point_cull_merge_block, spv::SelectionControlDontFlattenMask); + { + std::unique_ptr branch_conditional_op( + std::make_unique(spv::OpBranchConditional)); + branch_conditional_op->addIdOperand(point_cull_condition); + branch_conditional_op->addIdOperand(point_cull_then_block.getId()); + branch_conditional_op->addIdOperand(point_cull_merge_block.getId()); + branch_conditional_op->addImmediateOperand(1); + branch_conditional_op->addImmediateOperand(2); + point_cull_predecessor.addInstruction(std::move(branch_conditional_op)); + } + point_cull_then_block.addPredecessor(&point_cull_predecessor); + point_cull_merge_block.addPredecessor(&point_cull_predecessor); + builder.setBuildPoint(&point_cull_then_block); + builder.createNoResultOp(spv::OpReturn); + builder.setBuildPoint(&point_cull_merge_block); + } + + for (uint32_t i = 0; i < 4; ++i) { + // Same interpolators for the entire sprite. + for (uint32_t j = 0; j < key.interpolator_count; ++j) { + builder.createStore(point_interpolators[j], out_interpolators[j]); + } + // Top-left, bottom-left, top-right, bottom-right order (chosen + // arbitrarily, simply based on counterclockwise meaning front with + // frontFace = VkFrontFace(0), but faceness is ignored for non-polygon + // primitive types). + uint32_t point_vertex_x = i >> 1; + uint32_t point_vertex_y = i & 1; + // Point coordinates. + if (key.has_point_coordinates) { + id_vector_temp.clear(); + id_vector_temp.push_back(builder.makeFloatConstant(float(point_vertex_x))); + id_vector_temp.push_back(builder.makeFloatConstant(float(point_vertex_y))); + builder.createStore(builder.makeCompositeConstant(type_float2, id_vector_temp), + out_point_coordinates); + } + // Position. + id_vector_temp.clear(); + id_vector_temp.push_back(point_edge_x[point_vertex_x]); + id_vector_temp.push_back(point_edge_y[point_vertex_y]); + id_vector_temp.push_back(point_z); + id_vector_temp.push_back(point_w); + spv::Id point_vertex_position = + builder.createCompositeConstruct(type_float4, id_vector_temp); + id_vector_temp.clear(); + id_vector_temp.push_back(const_member_out_gl_per_vertex_position); + builder.createStore( + point_vertex_position, + builder.createAccessChain(spv::StorageClassOutput, out_gl_per_vertex, id_vector_temp)); + // Clip distances. + if (point_recalculate_clip_distances) { + // Convert host clip space back to guest clip space before applying + // user clip planes. + id_vector_temp.clear(); + id_vector_temp.push_back( + builder.createCompositeExtract(point_vertex_position, type_float, 0)); + id_vector_temp.push_back( + builder.createCompositeExtract(point_vertex_position, type_float, 1)); + id_vector_temp.push_back( + builder.createCompositeExtract(point_vertex_position, type_float, 2)); + spv::Id point_vertex_position_xyz = + builder.createCompositeConstruct(type_float3, id_vector_temp); + spv::Id point_guest_position_xyz = builder.createNoContractionBinOp( + spv::OpFSub, type_float3, point_vertex_position_xyz, + builder.createNoContractionBinOp(spv::OpVectorTimesScalar, type_float3, + point_ndc_offset, point_w)); + point_guest_position_xyz = builder.createNoContractionBinOp( + spv::OpFDiv, type_float3, point_guest_position_xyz, point_ndc_scale); + id_vector_temp.clear(); + id_vector_temp.push_back( + builder.createCompositeExtract(point_guest_position_xyz, type_float, 0)); + id_vector_temp.push_back( + builder.createCompositeExtract(point_guest_position_xyz, type_float, 1)); + id_vector_temp.push_back( + builder.createCompositeExtract(point_guest_position_xyz, type_float, 2)); + id_vector_temp.push_back(point_w); + spv::Id point_guest_position = + builder.createCompositeConstruct(type_float4, id_vector_temp); + for (uint32_t j = 0; j < clip_distance_count; ++j) { + id_vector_temp.clear(); + id_vector_temp.push_back(const_member_out_gl_per_vertex_clip_distance); + id_vector_temp.push_back(builder.makeIntConstant(int32_t(j))); + builder.createStore(builder.createBinOp(spv::OpDot, type_float, point_guest_position, + point_user_clip_planes[j]), + builder.createAccessChain(spv::StorageClassOutput, + out_gl_per_vertex, id_vector_temp)); + } + } else if (clip_distance_count) { + id_vector_temp.clear(); + id_vector_temp.push_back(const_member_out_gl_per_vertex_clip_distance); + builder.createStore(point_clip_distances, + builder.createAccessChain(spv::StorageClassOutput, out_gl_per_vertex, + id_vector_temp)); + } + // Emit the vertex. + builder.createNoResultOp(spv::OpEmitVertex); + } + builder.createNoResultOp(spv::OpEndPrimitive); + } break; + + case PipelineGeometryShader::kRectangleList: { + // Construct a strip with the fourth vertex generated by mirroring a + // vertex across the longest edge (the diagonal). + // + // Possible options: + // + // 0---1 + // | /| + // | / | - 12 is the longest edge, strip 0123 (most commonly used) + // |/ | v3 = v0 + (v1 - v0) + (v2 - v0), or v3 = -v0 + v1 + v2 + // 2--[3] + // + // 1---2 + // | /| + // | / | - 20 is the longest edge, strip 1203 + // |/ | + // 0--[3] + // + // 2---0 + // | /| + // | / | - 01 is the longest edge, strip 2013 + // |/ | + // 1--[3] + + spv::Id const_int_0 = builder.makeIntConstant(0); + spv::Id const_int_1 = builder.makeIntConstant(1); + spv::Id const_int_2 = builder.makeIntConstant(2); + spv::Id const_int_3 = builder.makeIntConstant(3); + + // Get squares of edge lengths to choose the longest edge. + // [0] - 12, [1] - 20, [2] - 01. + spv::Id edge_lengths[3]; + id_vector_temp.resize(3); + id_vector_temp[1] = const_member_in_gl_per_vertex_position; + for (uint32_t i = 0; i < 3; ++i) { + id_vector_temp[0] = builder.makeIntConstant(int32_t((1 + i) % 3)); + id_vector_temp[2] = const_int_0; + spv::Id edge_0_x = builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), + spv::NoPrecision); + id_vector_temp[2] = const_int_1; + spv::Id edge_0_y = builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), + spv::NoPrecision); + id_vector_temp[0] = builder.makeIntConstant(int32_t((2 + i) % 3)); + id_vector_temp[2] = const_int_0; + spv::Id edge_1_x = builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), + spv::NoPrecision); + id_vector_temp[2] = const_int_1; + spv::Id edge_1_y = builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), + spv::NoPrecision); + spv::Id edge_x = builder.createBinOp(spv::OpFSub, type_float, edge_1_x, edge_0_x); + spv::Id edge_y = builder.createBinOp(spv::OpFSub, type_float, edge_1_y, edge_0_y); + edge_lengths[i] = builder.createBinOp( + spv::OpFAdd, type_float, builder.createBinOp(spv::OpFMul, type_float, edge_x, edge_x), + builder.createBinOp(spv::OpFMul, type_float, edge_y, edge_y)); + } + + // Choose the index of the first vertex in the strip based on which edge + // is the longest, and calculate the indices of the other vertices. + spv::Id vertex_indices[3]; + // If 12 > 20 && 12 > 01, then 12 is the longest edge, and the strip is + // 0123. Otherwise, if 20 > 01, then 20 is the longest, and the strip is + // 1203, but if not, 01 is the longest, and the strip is 2013. + vertex_indices[0] = builder.createTriOp( + spv::OpSelect, type_int, + builder.createBinOp(spv::OpLogicalAnd, type_bool, + builder.createBinOp(spv::OpFOrdGreaterThan, type_bool, + edge_lengths[0], edge_lengths[1]), + builder.createBinOp(spv::OpFOrdGreaterThan, type_bool, + edge_lengths[0], edge_lengths[2])), + const_int_0, + builder.createTriOp(spv::OpSelect, type_int, + builder.createBinOp(spv::OpFOrdGreaterThan, type_bool, + edge_lengths[1], edge_lengths[2]), + const_int_1, const_int_2)); + for (uint32_t i = 1; i < 3; ++i) { + // vertex_indices[i] = (vertex_indices[0] + i) % 3 + spv::Id vertex_index_without_wrapping = builder.createBinOp( + spv::OpIAdd, type_int, vertex_indices[0], builder.makeIntConstant(int32_t(i))); + vertex_indices[i] = builder.createTriOp( + spv::OpSelect, type_int, + builder.createBinOp(spv::OpSLessThan, type_bool, vertex_index_without_wrapping, + const_int_3), + vertex_index_without_wrapping, + builder.createBinOp(spv::OpISub, type_int, vertex_index_without_wrapping, const_int_3)); + } + + // Initialize the point coordinates output for safety if this shader type + // is used with has_point_coordinates for some reason. + spv::Id const_point_coordinates_zero = spv::NoResult; + if (key.has_point_coordinates) { + spv::Id const_float_0 = builder.makeFloatConstant(0.0f); + id_vector_temp.clear(); + id_vector_temp.push_back(const_float_0); + id_vector_temp.push_back(const_float_0); + const_point_coordinates_zero = builder.makeCompositeConstant(type_float2, id_vector_temp); + } + + // Emit the triangle in the strip that consists of the original vertices. + for (uint32_t i = 0; i < 3; ++i) { + spv::Id vertex_index = vertex_indices[i]; + // Interpolators. + id_vector_temp.clear(); + id_vector_temp.push_back(vertex_index); + for (uint32_t j = 0; j < key.interpolator_count; ++j) { + builder.createStore( + builder.createLoad(builder.createAccessChain(spv::StorageClassInput, + in_interpolators[j], id_vector_temp), + spv::NoPrecision), + out_interpolators[j]); + } + // Point coordinates. + if (key.has_point_coordinates) { + builder.createStore(const_point_coordinates_zero, out_point_coordinates); + } + // Position. + id_vector_temp.clear(); + id_vector_temp.push_back(vertex_index); + id_vector_temp.push_back(const_member_in_gl_per_vertex_position); + spv::Id vertex_position = builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), + spv::NoPrecision); + id_vector_temp.clear(); + id_vector_temp.push_back(const_member_out_gl_per_vertex_position); + builder.createStore( + vertex_position, + builder.createAccessChain(spv::StorageClassOutput, out_gl_per_vertex, id_vector_temp)); + // Clip distances. + if (clip_distance_count) { + id_vector_temp.clear(); + id_vector_temp.push_back(vertex_index); + id_vector_temp.push_back(const_member_in_gl_per_vertex_clip_distance); + spv::Id vertex_clip_distances = builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), + spv::NoPrecision); + id_vector_temp.clear(); + id_vector_temp.push_back(const_member_out_gl_per_vertex_clip_distance); + builder.createStore(vertex_clip_distances, + builder.createAccessChain(spv::StorageClassOutput, out_gl_per_vertex, + id_vector_temp)); + } + // Emit the vertex. + builder.createNoResultOp(spv::OpEmitVertex); + } + + // Construct the fourth vertex. + // Interpolators. + for (uint32_t i = 0; i < key.interpolator_count; ++i) { + spv::Id in_interpolator = in_interpolators[i]; + id_vector_temp.clear(); + id_vector_temp.push_back(vertex_indices[0]); + spv::Id vertex_interpolator_v0 = builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_interpolator, id_vector_temp), + spv::NoPrecision); + id_vector_temp[0] = vertex_indices[1]; + spv::Id vertex_interpolator_v01 = builder.createNoContractionBinOp( + spv::OpFSub, type_float4, + builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_interpolator, id_vector_temp), + spv::NoPrecision), + vertex_interpolator_v0); + id_vector_temp[0] = vertex_indices[2]; + spv::Id vertex_interpolator_v3 = builder.createNoContractionBinOp( + spv::OpFAdd, type_float4, vertex_interpolator_v01, + builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_interpolator, id_vector_temp), + spv::NoPrecision)); + builder.createStore(vertex_interpolator_v3, out_interpolators[i]); + } + // Point coordinates. + if (key.has_point_coordinates) { + builder.createStore(const_point_coordinates_zero, out_point_coordinates); + } + // Position. + id_vector_temp.clear(); + id_vector_temp.push_back(vertex_indices[0]); + id_vector_temp.push_back(const_member_in_gl_per_vertex_position); + spv::Id vertex_position_v0 = builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), + spv::NoPrecision); + id_vector_temp[0] = vertex_indices[1]; + spv::Id vertex_position_v01 = builder.createNoContractionBinOp( + spv::OpFSub, type_float4, + builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), + spv::NoPrecision), + vertex_position_v0); + id_vector_temp[0] = vertex_indices[2]; + spv::Id vertex_position_v3 = builder.createNoContractionBinOp( + spv::OpFAdd, type_float4, vertex_position_v01, + builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), + spv::NoPrecision)); + id_vector_temp.clear(); + id_vector_temp.push_back(const_member_out_gl_per_vertex_position); + builder.createStore( + vertex_position_v3, + builder.createAccessChain(spv::StorageClassOutput, out_gl_per_vertex, id_vector_temp)); + // Clip distances. + for (uint32_t i = 0; i < clip_distance_count; ++i) { + spv::Id const_int_i = builder.makeIntConstant(int32_t(i)); + id_vector_temp.clear(); + id_vector_temp.push_back(vertex_indices[0]); + id_vector_temp.push_back(const_member_in_gl_per_vertex_clip_distance); + id_vector_temp.push_back(const_int_i); + spv::Id vertex_clip_distance_v0 = builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), + spv::NoPrecision); + id_vector_temp[0] = vertex_indices[1]; + spv::Id vertex_clip_distance_v01 = builder.createNoContractionBinOp( + spv::OpFSub, type_float, + builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), + spv::NoPrecision), + vertex_clip_distance_v0); + id_vector_temp[0] = vertex_indices[2]; + spv::Id vertex_clip_distance_v3 = builder.createNoContractionBinOp( + spv::OpFAdd, type_float, vertex_clip_distance_v01, + builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), + spv::NoPrecision)); + id_vector_temp.clear(); + id_vector_temp.push_back(const_member_out_gl_per_vertex_clip_distance); + id_vector_temp.push_back(const_int_i); + builder.createStore( + vertex_clip_distance_v3, + builder.createAccessChain(spv::StorageClassOutput, out_gl_per_vertex, id_vector_temp)); + } + // Emit the vertex. + builder.createNoResultOp(spv::OpEmitVertex); + builder.createNoResultOp(spv::OpEndPrimitive); + } break; + + case PipelineGeometryShader::kQuadList: { + // Initialize the point coordinates output for safety if this shader type + // is used with has_point_coordinates for some reason. + spv::Id const_point_coordinates_zero = spv::NoResult; + if (key.has_point_coordinates) { + spv::Id const_float_0 = builder.makeFloatConstant(0.0f); + id_vector_temp.clear(); + id_vector_temp.push_back(const_float_0); + id_vector_temp.push_back(const_float_0); + const_point_coordinates_zero = builder.makeCompositeConstant(type_float2, id_vector_temp); + } + + // Build the triangle strip from the original quad vertices in the + // 0, 1, 3, 2 order (like specified for GL_QUAD_STRIP). + // TODO(Triang3l): Find the correct decomposition of quads into triangles + // on the real hardware. + for (uint32_t i = 0; i < 4; ++i) { + spv::Id const_vertex_index = builder.makeIntConstant(int32_t(i ^ (i >> 1))); + // Interpolators. + id_vector_temp.clear(); + id_vector_temp.push_back(const_vertex_index); + for (uint32_t j = 0; j < key.interpolator_count; ++j) { + builder.createStore( + builder.createLoad(builder.createAccessChain(spv::StorageClassInput, + in_interpolators[j], id_vector_temp), + spv::NoPrecision), + out_interpolators[j]); + } + // Point coordinates. + if (key.has_point_coordinates) { + builder.createStore(const_point_coordinates_zero, out_point_coordinates); + } + // Position. + id_vector_temp.clear(); + id_vector_temp.push_back(const_vertex_index); + id_vector_temp.push_back(const_member_in_gl_per_vertex_position); + spv::Id vertex_position = builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), + spv::NoPrecision); + id_vector_temp.clear(); + id_vector_temp.push_back(const_member_out_gl_per_vertex_position); + builder.createStore( + vertex_position, + builder.createAccessChain(spv::StorageClassOutput, out_gl_per_vertex, id_vector_temp)); + // Clip distances. + if (clip_distance_count) { + id_vector_temp.clear(); + id_vector_temp.push_back(const_vertex_index); + id_vector_temp.push_back(const_member_in_gl_per_vertex_clip_distance); + spv::Id vertex_clip_distances = builder.createLoad( + builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), + spv::NoPrecision); + id_vector_temp.clear(); + id_vector_temp.push_back(const_member_out_gl_per_vertex_clip_distance); + builder.createStore(vertex_clip_distances, + builder.createAccessChain(spv::StorageClassOutput, out_gl_per_vertex, + id_vector_temp)); + } + // Emit the vertex. + builder.createNoResultOp(spv::OpEmitVertex); + } + builder.createNoResultOp(spv::OpEndPrimitive); + } break; + + default: + assert_unhandled_case(key.type); + } + + // End the main function. + builder.leaveFunction(); + + // Serialize the shader code. + std::vector shader_code; + builder.dump(shader_code); + + // Create the shader module, and store the handle even if creation fails not + // to try to create it again later. + VkShaderModule shader_module = ui::vulkan::util::CreateShaderModule( + command_processor_.GetVulkanDevice(), reinterpret_cast(shader_code.data()), + sizeof(uint32_t) * shader_code.size()); + if (shader_module == VK_NULL_HANDLE) { + REXGPU_ERROR( + "VulkanPipelineCache: Failed to create the primitive type geometry " + "shader 0x{:08X}", + key.key); + } + geometry_shaders_.emplace(key, shader_module); + return shader_module; +} + +bool VulkanPipelineCache::TryGetPipelineCreationArgumentsForDescription( + const PipelineDescription& description, + std::pair* pipeline, + PipelineCreationArguments& creation_arguments, bool for_placeholder) { + auto fail = [&](const char* reason) { + REXGPU_ERROR( + "VulkanPipelineCache: TryGetPipelineCreationArgumentsForDescription " + "failed: {} (vs={:016X}, ps={:016X}, topo={}, geom={}, tess_mode={}, " + "for_placeholder={}, render_pass_key=0x{:08X})", + reason, description.vertex_shader_hash, description.pixel_shader_hash, + uint32_t(description.primitive_topology), uint32_t(description.geometry_shader), + uint32_t(description.tessellation_mode), uint32_t(for_placeholder), + description.render_pass_key.key); + return false; + }; + + if (!pipeline) { + return fail("null_pipeline_storage"); + } + if (!ArePipelineRequirementsMet(description)) { + return fail("pipeline_requirements_not_met"); + } + + auto vertex_shader_it = shaders_.find(description.vertex_shader_hash); + if (vertex_shader_it == shaders_.end()) { + return fail("vertex_shader_not_found"); + } + auto* vertex_shader = static_cast( + vertex_shader_it->second->GetTranslation(description.vertex_shader_modification)); + if (!vertex_shader || !vertex_shader->is_translated() || !vertex_shader->is_valid()) { + return fail("vertex_shader_translation_missing_or_invalid"); + } + SpirvShaderTranslator::Modification vertex_shader_modification( + description.vertex_shader_modification); + Shader::HostVertexShaderType host_vertex_shader_type = + vertex_shader_modification.vertex.host_vertex_shader_type; + bool tessellated = Shader::IsHostVertexShaderTypeDomain(host_vertex_shader_type); + + VulkanShader::VulkanTranslation* pixel_shader = nullptr; + if (description.pixel_shader_hash && !for_placeholder) { + auto pixel_shader_it = shaders_.find(description.pixel_shader_hash); + if (pixel_shader_it == shaders_.end()) { + return fail("pixel_shader_not_found"); + } + pixel_shader = static_cast( + pixel_shader_it->second->GetTranslation(description.pixel_shader_modification)); + if (!pixel_shader || !pixel_shader->is_translated() || !pixel_shader->is_valid()) { + return fail("pixel_shader_translation_missing_or_invalid"); + } + } + SpirvShaderTranslator::Modification pixel_shader_modification( + description.pixel_shader_modification); + + VkShaderModule tessellation_vertex_shader = VK_NULL_HANDLE; + VkShaderModule tessellation_control_shader = VK_NULL_HANDLE; + uint32_t tessellation_patch_control_points = 0; + if (tessellated) { + xenos::TessellationMode tessellation_mode = description.tessellation_mode; + tessellation_patch_control_points = + GetTessellationPatchControlPointCount(host_vertex_shader_type, tessellation_mode); + if (!tessellation_patch_control_points) { + return fail("tessellation_patch_control_points_zero"); + } + tessellation_vertex_shader = + GetTessellationVertexShader(tessellation_mode == xenos::TessellationMode::kAdaptive); + if (tessellation_vertex_shader == VK_NULL_HANDLE) { + return fail("tessellation_vertex_shader_unavailable"); + } + tessellation_control_shader = + GetTessellationControlShader(host_vertex_shader_type, tessellation_mode); + if (tessellation_control_shader == VK_NULL_HANDLE) { + return fail("tessellation_control_shader_unavailable"); + } + } + + VkShaderModule geometry_shader = VK_NULL_HANDLE; + GeometryShaderKey geometry_shader_key; + if (GetGeometryShaderKey(description.geometry_shader, vertex_shader_modification, + pixel_shader_modification, geometry_shader_key)) { + geometry_shader = GetGeometryShader(geometry_shader_key); + if (geometry_shader == VK_NULL_HANDLE) { + return fail("geometry_shader_unavailable"); + } + } + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + bool use_dynamic_rendering = + REXCVAR_GET(vulkan_dynamic_rendering) && vulkan_device->properties().dynamicRendering; + VkRenderPass render_pass = VK_NULL_HANDLE; + if (!use_dynamic_rendering) { + render_pass = + render_target_cache_.GetPath() == RenderTargetCache::Path::kPixelShaderInterlock + ? render_target_cache_.GetFragmentShaderInterlockRenderPass() + : render_target_cache_.GetHostRenderTargetsRenderPass(description.render_pass_key); + if (render_pass == VK_NULL_HANDLE) { + return fail("render_pass_unavailable"); + } + } + + const PipelineLayoutProvider* pipeline_layout = command_processor_.GetPipelineLayout( + (!for_placeholder && pixel_shader) ? static_cast(pixel_shader->shader()) + .GetTextureBindingsAfterTranslation() + .size() + : 0, + (!for_placeholder && pixel_shader) ? static_cast(pixel_shader->shader()) + .GetSamplerBindingsAfterTranslation() + .size() + : 0, + static_cast(vertex_shader->shader()) + .GetTextureBindingsAfterTranslation() + .size(), + static_cast(vertex_shader->shader()) + .GetSamplerBindingsAfterTranslation() + .size()); + if (!pipeline_layout) { + return fail("pipeline_layout_unavailable"); + } + + creation_arguments.pipeline = pipeline; + creation_arguments.pipeline_layout = pipeline_layout; + creation_arguments.vertex_shader = vertex_shader; + creation_arguments.pixel_shader = for_placeholder ? nullptr : pixel_shader; + creation_arguments.tessellation_vertex_shader = tessellation_vertex_shader; + creation_arguments.tessellation_control_shader = tessellation_control_shader; + creation_arguments.tessellation_patch_control_points = tessellation_patch_control_points; + creation_arguments.geometry_shader = geometry_shader; + creation_arguments.render_pass = render_pass; + return true; +} + +bool VulkanPipelineCache::EnsurePipelineCreated(const PipelineCreationArguments& creation_arguments, + VkShaderModule fragment_shader_override) { + VkPipeline existing_pipeline = + creation_arguments.pipeline->second.pipeline.load(std::memory_order_acquire); + bool is_placeholder = + creation_arguments.pipeline->second.is_placeholder.load(std::memory_order_acquire); + bool creating_placeholder = fragment_shader_override != VK_NULL_HANDLE; + if (existing_pipeline != VK_NULL_HANDLE) { + if (!is_placeholder || creating_placeholder) { + return true; + } + } + + // This function preferably should validate the description to prevent + // unsupported behavior that may be dangerous/crashing because pipelines can + // be created from the disk storage. + + if (creation_arguments.pixel_shader) { + REXGPU_INFO("Creating graphics pipeline state with VS {:016X}, PS {:016X}", + creation_arguments.vertex_shader->shader().ucode_data_hash(), + creation_arguments.pixel_shader->shader().ucode_data_hash()); + } else { + REXGPU_INFO("Creating graphics pipeline state with VS {:016X}", + creation_arguments.vertex_shader->shader().ucode_data_hash()); + } + + const PipelineDescription& description = creation_arguments.pipeline->first; + if (!ArePipelineRequirementsMet(description)) { + assert_always( + "When creating a new pipeline, the description must not require " + "unsupported features, and when loading the pipeline storage, " + "pipelines with unsupported features must be filtered out"); + return false; + } + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + + bool edram_fragment_shader_interlock = + render_target_cache_.GetPath() == RenderTargetCache::Path::kPixelShaderInterlock; + + bool tessellated = description.primitive_topology == PipelinePrimitiveTopology::kPatchList; + + std::array shader_stages; + uint32_t shader_stage_count = 0; + + // Vertex or tessellation evaluation shader (plus helper stages for tessellation). + assert_true(creation_arguments.vertex_shader->is_translated()); + if (!creation_arguments.vertex_shader->is_valid()) { + return false; + } + if (tessellated) { + if (creation_arguments.tessellation_vertex_shader == VK_NULL_HANDLE || + creation_arguments.tessellation_control_shader == VK_NULL_HANDLE || + !creation_arguments.tessellation_patch_control_points) { + return false; + } + + VkPipelineShaderStageCreateInfo& shader_stage_vertex = shader_stages[shader_stage_count++]; + shader_stage_vertex.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shader_stage_vertex.pNext = nullptr; + shader_stage_vertex.flags = 0; + shader_stage_vertex.stage = VK_SHADER_STAGE_VERTEX_BIT; + shader_stage_vertex.module = creation_arguments.tessellation_vertex_shader; + shader_stage_vertex.pName = "main"; + shader_stage_vertex.pSpecializationInfo = nullptr; + + VkPipelineShaderStageCreateInfo& shader_stage_tess_control = + shader_stages[shader_stage_count++]; + shader_stage_tess_control.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shader_stage_tess_control.pNext = nullptr; + shader_stage_tess_control.flags = 0; + shader_stage_tess_control.stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; + shader_stage_tess_control.module = creation_arguments.tessellation_control_shader; + shader_stage_tess_control.pName = "main"; + shader_stage_tess_control.pSpecializationInfo = nullptr; + + VkPipelineShaderStageCreateInfo& shader_stage_tess_eval = shader_stages[shader_stage_count++]; + shader_stage_tess_eval.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shader_stage_tess_eval.pNext = nullptr; + shader_stage_tess_eval.flags = 0; + shader_stage_tess_eval.stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; + shader_stage_tess_eval.module = creation_arguments.vertex_shader->shader_module(); + assert_true(shader_stage_tess_eval.module != VK_NULL_HANDLE); + shader_stage_tess_eval.pName = "main"; + shader_stage_tess_eval.pSpecializationInfo = nullptr; + } else { + VkPipelineShaderStageCreateInfo& shader_stage_vertex = shader_stages[shader_stage_count++]; + shader_stage_vertex.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shader_stage_vertex.pNext = nullptr; + shader_stage_vertex.flags = 0; + shader_stage_vertex.stage = VK_SHADER_STAGE_VERTEX_BIT; + shader_stage_vertex.module = creation_arguments.vertex_shader->shader_module(); + assert_true(shader_stage_vertex.module != VK_NULL_HANDLE); + shader_stage_vertex.pName = "main"; + shader_stage_vertex.pSpecializationInfo = nullptr; + } + // Geometry shader. + if (creation_arguments.geometry_shader != VK_NULL_HANDLE) { + if (tessellated) { + return false; + } + VkPipelineShaderStageCreateInfo& shader_stage_geometry = shader_stages[shader_stage_count++]; + shader_stage_geometry.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shader_stage_geometry.pNext = nullptr; + shader_stage_geometry.flags = 0; + shader_stage_geometry.stage = VK_SHADER_STAGE_GEOMETRY_BIT; + shader_stage_geometry.module = creation_arguments.geometry_shader; + shader_stage_geometry.pName = "main"; + shader_stage_geometry.pSpecializationInfo = nullptr; + } + // Fragment shader. + VkPipelineShaderStageCreateInfo& shader_stage_fragment = shader_stages[shader_stage_count++]; + shader_stage_fragment.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shader_stage_fragment.pNext = nullptr; + shader_stage_fragment.flags = 0; + shader_stage_fragment.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + shader_stage_fragment.module = VK_NULL_HANDLE; + shader_stage_fragment.pName = "main"; + shader_stage_fragment.pSpecializationInfo = nullptr; + if (fragment_shader_override != VK_NULL_HANDLE) { + shader_stage_fragment.module = fragment_shader_override; + } else if (creation_arguments.pixel_shader) { + assert_true(creation_arguments.pixel_shader->is_translated()); + if (!creation_arguments.pixel_shader->is_valid()) { + return false; + } + shader_stage_fragment.module = creation_arguments.pixel_shader->shader_module(); + assert_true(shader_stage_fragment.module != VK_NULL_HANDLE); + } else { + if (edram_fragment_shader_interlock) { + shader_stage_fragment.module = depth_only_fragment_shader_; + } else if (render_target_cache_.depth_float24_convert_in_pixel_shader() && + (description.render_pass_key.depth_and_color_used & 1) && + (description.depth_compare_op != xenos::CompareFunction::kAlways || + description.depth_write_enable) && + description.render_pass_key.depth_format == + xenos::DepthRenderTargetFormat::kD24FS8) { + shader_stage_fragment.module = render_target_cache_.depth_float24_round() + ? depth_float24_round_fragment_shader_ + : depth_float24_truncate_fragment_shader_; + if (shader_stage_fragment.module == VK_NULL_HANDLE) { + return false; + } + } + } + if (shader_stage_fragment.module == VK_NULL_HANDLE) { + --shader_stage_count; + } + + VkPipelineVertexInputStateCreateInfo vertex_input_state = {}; + vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + + VkPipelineInputAssemblyStateCreateInfo input_assembly_state; + input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + input_assembly_state.pNext = nullptr; + input_assembly_state.flags = 0; + switch (description.primitive_topology) { + case PipelinePrimitiveTopology::kPointList: + input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; + assert_false(description.primitive_restart); + if (description.primitive_restart) { + return false; + } + break; + case PipelinePrimitiveTopology::kLineList: + input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST; + assert_false(description.primitive_restart); + if (description.primitive_restart) { + return false; + } + break; + case PipelinePrimitiveTopology::kLineStrip: + input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP; + break; + case PipelinePrimitiveTopology::kTriangleList: + input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + assert_false(description.primitive_restart); + if (description.primitive_restart) { + return false; + } + break; + case PipelinePrimitiveTopology::kTriangleStrip: + input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; + break; + case PipelinePrimitiveTopology::kTriangleFan: + // Keep parity with D3D12 by requiring triangle fan to list conversion in + // PrimitiveProcessor rather than emitting native fan pipelines. + assert_always(); + return false; + case PipelinePrimitiveTopology::kLineListWithAdjacency: + input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY; + assert_false(description.primitive_restart); + if (description.primitive_restart) { + return false; + } + break; + case PipelinePrimitiveTopology::kPatchList: + input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; + assert_false(description.primitive_restart); + if (description.primitive_restart) { + return false; + } + break; + default: + assert_unhandled_case(description.primitive_topology); + return false; + } + input_assembly_state.primitiveRestartEnable = description.primitive_restart ? VK_TRUE : VK_FALSE; + + VkPipelineViewportStateCreateInfo viewport_state; + viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + viewport_state.pNext = nullptr; + viewport_state.flags = 0; + viewport_state.viewportCount = 1; + viewport_state.pViewports = nullptr; + viewport_state.scissorCount = 1; + viewport_state.pScissors = nullptr; + + VkPipelineRasterizationStateCreateInfo rasterization_state = {}; + rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rasterization_state.rasterizerDiscardEnable = description.rasterizer_discard ? VK_TRUE : VK_FALSE; + rasterization_state.depthClampEnable = description.depth_clamp_enable ? VK_TRUE : VK_FALSE; + switch (description.polygon_mode) { + case PipelinePolygonMode::kFill: + rasterization_state.polygonMode = VK_POLYGON_MODE_FILL; + break; + case PipelinePolygonMode::kLine: + rasterization_state.polygonMode = VK_POLYGON_MODE_LINE; + break; + case PipelinePolygonMode::kPoint: + rasterization_state.polygonMode = VK_POLYGON_MODE_POINT; + break; + default: + assert_unhandled_case(description.polygon_mode); + return false; + } + rasterization_state.cullMode = VK_CULL_MODE_NONE; + if (description.cull_front) { + rasterization_state.cullMode |= VK_CULL_MODE_FRONT_BIT; + } + if (description.cull_back) { + rasterization_state.cullMode |= VK_CULL_MODE_BACK_BIT; + } + rasterization_state.frontFace = + description.front_face_clockwise ? VK_FRONT_FACE_CLOCKWISE : VK_FRONT_FACE_COUNTER_CLOCKWISE; + // Depth bias is dynamic (even toggling - pipeline creation is expensive). + // "If no depth attachment is present, r is undefined" in the depth bias + // formula, though Z has no effect on anything if a depth attachment is not + // used (the guest shader can't access Z), enabling only when there's a + // depth / stencil attachment for correctness. + rasterization_state.depthBiasEnable = + (!edram_fragment_shader_interlock && (description.render_pass_key.depth_and_color_used & 0b1)) + ? VK_TRUE + : VK_FALSE; + // TODO(Triang3l): Wide lines. + rasterization_state.lineWidth = 1.0f; + + bool subpass_has_attachments = + !edram_fragment_shader_interlock && description.render_pass_key.depth_and_color_used != 0; + VkSampleMask sample_mask = UINT32_MAX; + VkPipelineMultisampleStateCreateInfo multisample_state = {}; + multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + if (description.rasterizer_discard) { + // Keep rasterizer-discard pipelines independent from guest MSAA state, as + // done by D3D12 when rasterization is disabled. + multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + } else if (!edram_fragment_shader_interlock && !subpass_has_attachments) { + // Keep parity with D3D12 host-render-target path, where draws without + // color/depth attachments must run at 1x sample count. + multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + } else if (description.render_pass_key.msaa_samples == xenos::MsaaSamples::k2X && + !render_target_cache_.IsMsaa2xSupported(subpass_has_attachments)) { + // Using sample 0 as 0 and 3 as 1 for 2x instead (not exactly the same + // sample locations, but still top-left and bottom-right - however, this can + // be adjusted with custom sample locations). + multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT; + // Keep parity with D3D12 ROV: sample masks are ignored without attachments. + if (subpass_has_attachments) { + sample_mask = 0b1001; + multisample_state.pSampleMask = &sample_mask; + } + } else { + multisample_state.rasterizationSamples = + VkSampleCountFlagBits(uint32_t(1) << uint32_t(description.render_pass_key.msaa_samples)); + } + if (description.sample_rate_shading && + multisample_state.rasterizationSamples != VK_SAMPLE_COUNT_1_BIT) { + multisample_state.sampleShadingEnable = VK_TRUE; + multisample_state.minSampleShading = 1.0f; + } + + VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {}; + depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + depth_stencil_state.pNext = nullptr; + if (!edram_fragment_shader_interlock) { + if (description.depth_write_enable || + description.depth_compare_op != xenos::CompareFunction::kAlways) { + depth_stencil_state.depthTestEnable = VK_TRUE; + depth_stencil_state.depthWriteEnable = description.depth_write_enable ? VK_TRUE : VK_FALSE; + depth_stencil_state.depthCompareOp = + VkCompareOp(uint32_t(VK_COMPARE_OP_NEVER) + uint32_t(description.depth_compare_op)); + } + if (description.stencil_test_enable) { + depth_stencil_state.stencilTestEnable = VK_TRUE; + depth_stencil_state.front.failOp = + VkStencilOp(uint32_t(VK_STENCIL_OP_KEEP) + uint32_t(description.stencil_front_fail_op)); + depth_stencil_state.front.passOp = + VkStencilOp(uint32_t(VK_STENCIL_OP_KEEP) + uint32_t(description.stencil_front_pass_op)); + depth_stencil_state.front.depthFailOp = VkStencilOp( + uint32_t(VK_STENCIL_OP_KEEP) + uint32_t(description.stencil_front_depth_fail_op)); + depth_stencil_state.front.compareOp = VkCompareOp( + uint32_t(VK_COMPARE_OP_NEVER) + uint32_t(description.stencil_front_compare_op)); + depth_stencil_state.back.failOp = + VkStencilOp(uint32_t(VK_STENCIL_OP_KEEP) + uint32_t(description.stencil_back_fail_op)); + depth_stencil_state.back.passOp = + VkStencilOp(uint32_t(VK_STENCIL_OP_KEEP) + uint32_t(description.stencil_back_pass_op)); + depth_stencil_state.back.depthFailOp = VkStencilOp( + uint32_t(VK_STENCIL_OP_KEEP) + uint32_t(description.stencil_back_depth_fail_op)); + depth_stencil_state.back.compareOp = VkCompareOp( + uint32_t(VK_COMPARE_OP_NEVER) + uint32_t(description.stencil_back_compare_op)); + } + } + + VkPipelineColorBlendStateCreateInfo color_blend_state = {}; + color_blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + VkPipelineColorBlendAttachmentState color_blend_attachments[xenos::kMaxColorRenderTargets] = {}; + if (!edram_fragment_shader_interlock) { + uint32_t color_rts_used = description.render_pass_key.depth_and_color_used >> 1; + { + static const VkBlendFactor kBlendFactorMap[] = { + VK_BLEND_FACTOR_ZERO, + VK_BLEND_FACTOR_ONE, + VK_BLEND_FACTOR_SRC_COLOR, + VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, + VK_BLEND_FACTOR_DST_COLOR, + VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, + VK_BLEND_FACTOR_SRC_ALPHA, + VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + VK_BLEND_FACTOR_DST_ALPHA, + VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, + VK_BLEND_FACTOR_CONSTANT_COLOR, + VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, + VK_BLEND_FACTOR_CONSTANT_ALPHA, + VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, + VK_BLEND_FACTOR_SRC_ALPHA_SATURATE, + }; + // 8 entries for safety since 3 bits from the guest are passed directly. + static const VkBlendOp kBlendOpMap[] = {VK_BLEND_OP_ADD, + VK_BLEND_OP_SUBTRACT, + VK_BLEND_OP_MIN, + VK_BLEND_OP_MAX, + VK_BLEND_OP_REVERSE_SUBTRACT, + VK_BLEND_OP_ADD, + VK_BLEND_OP_ADD, + VK_BLEND_OP_ADD}; + assert_true(vulkan_device->properties().independentBlend); + uint32_t color_rts_remaining = color_rts_used; + uint32_t color_rt_index; + while (rex::bit_scan_forward(color_rts_remaining, &color_rt_index)) { + color_rts_remaining &= ~(uint32_t(1) << color_rt_index); + VkPipelineColorBlendAttachmentState& color_blend_attachment = + color_blend_attachments[color_rt_index]; + const PipelineRenderTarget& color_rt = description.render_targets[color_rt_index]; + if (color_rt.src_color_blend_factor != PipelineBlendFactor::kOne || + color_rt.dst_color_blend_factor != PipelineBlendFactor::kZero || + color_rt.color_blend_op != xenos::BlendOp::kAdd || + color_rt.src_alpha_blend_factor != PipelineBlendFactor::kOne || + color_rt.dst_alpha_blend_factor != PipelineBlendFactor::kZero || + color_rt.alpha_blend_op != xenos::BlendOp::kAdd) { + color_blend_attachment.blendEnable = VK_TRUE; + color_blend_attachment.srcColorBlendFactor = + kBlendFactorMap[uint32_t(color_rt.src_color_blend_factor)]; + color_blend_attachment.dstColorBlendFactor = + kBlendFactorMap[uint32_t(color_rt.dst_color_blend_factor)]; + color_blend_attachment.colorBlendOp = kBlendOpMap[uint32_t(color_rt.color_blend_op)]; + color_blend_attachment.srcAlphaBlendFactor = + kBlendFactorMap[uint32_t(color_rt.src_alpha_blend_factor)]; + color_blend_attachment.dstAlphaBlendFactor = + kBlendFactorMap[uint32_t(color_rt.dst_alpha_blend_factor)]; + color_blend_attachment.alphaBlendOp = kBlendOpMap[uint32_t(color_rt.alpha_blend_op)]; + } + color_blend_attachment.colorWriteMask = VkColorComponentFlags(color_rt.color_write_mask); + } + } + color_blend_state.attachmentCount = 32 - rex::lzcnt(color_rts_used); + color_blend_state.pAttachments = color_blend_attachments; + } + + std::array dynamic_states; + VkPipelineDynamicStateCreateInfo dynamic_state; + dynamic_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynamic_state.pNext = nullptr; + dynamic_state.flags = 0; + dynamic_state.dynamicStateCount = 0; + dynamic_state.pDynamicStates = dynamic_states.data(); + // Regardless of whether some of this state actually has any effect on the + // pipeline, marking all as dynamic because otherwise, binding any pipeline + // with such state not marked as dynamic will cause the dynamic state to be + // invalidated (again, even if it has no effect). + dynamic_states[dynamic_state.dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT; + dynamic_states[dynamic_state.dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR; + if (!edram_fragment_shader_interlock) { + dynamic_states[dynamic_state.dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BIAS; + dynamic_states[dynamic_state.dynamicStateCount++] = VK_DYNAMIC_STATE_BLEND_CONSTANTS; + dynamic_states[dynamic_state.dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK; + dynamic_states[dynamic_state.dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK; + dynamic_states[dynamic_state.dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE; + } + + VkPipelineTessellationStateCreateInfo tessellation_state = {}; + if (tessellated) { + tessellation_state.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; + tessellation_state.patchControlPoints = creation_arguments.tessellation_patch_control_points; + } + + VkPipelineRenderingCreateInfo pipeline_rendering_create_info = {}; + VkFormat color_attachment_formats[xenos::kMaxColorRenderTargets] = {}; + bool use_dynamic_rendering = + REXCVAR_GET(vulkan_dynamic_rendering) && vulkan_device->properties().dynamicRendering; + if (use_dynamic_rendering) { + pipeline_rendering_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO; + pipeline_rendering_create_info.pNext = nullptr; + pipeline_rendering_create_info.viewMask = 0; + + uint32_t color_attachment_count = 0; + const auto& key = description.render_pass_key; + xenos::ColorRenderTargetFormat color_formats[] = { + key.color_0_view_format, key.color_1_view_format, key.color_2_view_format, + key.color_3_view_format}; + for (uint32_t i = 0; i < xenos::kMaxColorRenderTargets; ++i) { + if (key.depth_and_color_used & (1 << (1 + i))) { + color_attachment_formats[i] = render_target_cache_.GetColorVulkanFormat(color_formats[i]); + color_attachment_count = i + 1; + } + } + pipeline_rendering_create_info.colorAttachmentCount = color_attachment_count; + pipeline_rendering_create_info.pColorAttachmentFormats = + color_attachment_count ? color_attachment_formats : nullptr; + + if (key.depth_and_color_used & 0b1) { + VkFormat depth_format = render_target_cache_.GetDepthVulkanFormat(key.depth_format); + pipeline_rendering_create_info.depthAttachmentFormat = depth_format; + pipeline_rendering_create_info.stencilAttachmentFormat = depth_format; + } + } + + VkGraphicsPipelineCreateInfo pipeline_create_info; + pipeline_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipeline_create_info.pNext = use_dynamic_rendering ? &pipeline_rendering_create_info : nullptr; + pipeline_create_info.flags = 0; + pipeline_create_info.stageCount = shader_stage_count; + pipeline_create_info.pStages = shader_stages.data(); + pipeline_create_info.pVertexInputState = &vertex_input_state; + pipeline_create_info.pInputAssemblyState = &input_assembly_state; + pipeline_create_info.pTessellationState = tessellated ? &tessellation_state : nullptr; + pipeline_create_info.pViewportState = &viewport_state; + pipeline_create_info.pRasterizationState = &rasterization_state; + pipeline_create_info.pMultisampleState = &multisample_state; + pipeline_create_info.pDepthStencilState = &depth_stencil_state; + pipeline_create_info.pColorBlendState = &color_blend_state; + pipeline_create_info.pDynamicState = &dynamic_state; + if (creation_arguments.pipeline_layout == nullptr) { + return false; + } + pipeline_create_info.layout = creation_arguments.pipeline_layout->GetPipelineLayout(); + pipeline_create_info.renderPass = + use_dynamic_rendering ? VK_NULL_HANDLE : creation_arguments.render_pass; + pipeline_create_info.subpass = 0; + pipeline_create_info.basePipelineHandle = VK_NULL_HANDLE; + pipeline_create_info.basePipelineIndex = -1; + + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + VkPipeline pipeline; + VkResult create_result = dfn.vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, + &pipeline_create_info, nullptr, &pipeline); + if (create_result != VK_SUCCESS) { + uint64_t ps_hash = creation_arguments.pixel_shader + ? creation_arguments.pixel_shader->shader().ucode_data_hash() + : 0; + REXGPU_ERROR( + "VulkanPipelineCache: vkCreateGraphicsPipelines failed (result={}, vs={:016X}, " + "ps={:016X}, topo={}, geom={}, tess_mode={}, patch_cp={}, render_pass_key=0x{:08X}, " + "dynamic_rendering={})", + int32_t(create_result), creation_arguments.vertex_shader->shader().ucode_data_hash(), + ps_hash, uint32_t(description.primitive_topology), uint32_t(description.geometry_shader), + uint32_t(description.tessellation_mode), + creation_arguments.tessellation_patch_control_points, description.render_pass_key.key, + uint32_t(use_dynamic_rendering)); + return false; + } + bool was_placeholder = + creation_arguments.pipeline->second.is_placeholder.load(std::memory_order_acquire); + VkPipeline old_pipeline = + creation_arguments.pipeline->second.pipeline.exchange(pipeline, std::memory_order_acq_rel); + creation_arguments.pipeline->second.pipeline_layout.store(creation_arguments.pipeline_layout, + std::memory_order_release); + if (creating_placeholder) { + creation_arguments.pipeline->second.is_placeholder.store(true, std::memory_order_release); + } else { + creation_arguments.pipeline->second.is_placeholder.store(false, std::memory_order_release); + if (was_placeholder && old_pipeline != VK_NULL_HANDLE) { + std::lock_guard lock(deferred_destroy_lock_); + deferred_destroy_pipelines_.emplace_back(command_processor_.GetCurrentSubmission(), + old_pipeline); + } + } + + return true; +} + +void VulkanPipelineCache::CreationThread(size_t thread_index) { + while (true) { + PipelineCreationArguments creation_arguments; + { + std::unique_lock lock(creation_request_lock_); + if (thread_index >= creation_threads_shutdown_from_ || creation_queue_.empty()) { + if (creation_completion_set_event_ && creation_threads_busy_ == 0) { + creation_completion_set_event_ = false; + creation_completion_event_->Set(); + } + if (thread_index >= creation_threads_shutdown_from_) { + return; + } + creation_request_cond_.wait(lock); + continue; + } + creation_arguments = creation_queue_.top(); + creation_queue_.pop(); + ++creation_threads_busy_; + } + + bool created = EnsurePipelineCreated(creation_arguments); + if (!created) { + bool has_placeholder = + creation_arguments.pipeline->second.is_placeholder.load(std::memory_order_acquire); + VkPipeline pipeline = + creation_arguments.pipeline->second.pipeline.load(std::memory_order_acquire); + if (has_placeholder && pipeline != VK_NULL_HANDLE) { + // Keep the placeholder resident and stop waiting for a real pipeline. + creation_arguments.pipeline->second.is_placeholder.store(false, std::memory_order_release); + } else { + creation_arguments.pipeline->second.pipeline.store(VK_NULL_HANDLE, + std::memory_order_release); + } + } + + { + std::lock_guard lock(creation_request_lock_); + --creation_threads_busy_; + } + } +} + +void VulkanPipelineCache::CreateQueuedPipelinesOnProcessorThread() { + assert_false(creation_threads_.empty()); + while (true) { + PipelineCreationArguments creation_arguments; + { + std::lock_guard lock(creation_request_lock_); + if (creation_queue_.empty()) { + break; + } + creation_arguments = creation_queue_.top(); + creation_queue_.pop(); + } + bool created = EnsurePipelineCreated(creation_arguments); + if (!created) { + bool has_placeholder = + creation_arguments.pipeline->second.is_placeholder.load(std::memory_order_acquire); + VkPipeline pipeline = + creation_arguments.pipeline->second.pipeline.load(std::memory_order_acquire); + if (has_placeholder && pipeline != VK_NULL_HANDLE) { + creation_arguments.pipeline->second.is_placeholder.store(false, std::memory_order_release); + } else { + creation_arguments.pipeline->second.pipeline.store(VK_NULL_HANDLE, + std::memory_order_release); + } + } + } +} + +void VulkanPipelineCache::ProcessDeferredPipelineDestructions(bool force_all) { + std::vector pipelines_to_destroy; + uint64_t completed_submission = command_processor_.GetCompletedSubmission(); + { + std::lock_guard lock(deferred_destroy_lock_); + if (deferred_destroy_pipelines_.empty()) { + return; + } + auto it = deferred_destroy_pipelines_.begin(); + while (it != deferred_destroy_pipelines_.end()) { + if (force_all || it->first <= completed_submission) { + pipelines_to_destroy.push_back(it->second); + it = deferred_destroy_pipelines_.erase(it); + } else if (!force_all) { + // The queue is sorted by submission index. + break; + } else { + ++it; + } + } + } + if (pipelines_to_destroy.empty()) { + return; + } + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + for (VkPipeline pipeline : pipelines_to_destroy) { + if (pipeline != VK_NULL_HANDLE) { + dfn.vkDestroyPipeline(device, pipeline, nullptr); + } + } +} + +void VulkanPipelineCache::StorageWriteThread() { + ShaderStoredHeader shader_header; + // Don't leak anything in unused bits. + std::memset(&shader_header, 0, sizeof(shader_header)); + + std::vector ucode_guest_endian; + ucode_guest_endian.reserve(0xFFFF); + + bool flush_shaders = false; + bool flush_pipelines = false; + + while (true) { + if (flush_shaders) { + flush_shaders = false; + assert_not_null(shader_storage_file_); + fflush(shader_storage_file_); + } + if (flush_pipelines) { + flush_pipelines = false; + assert_not_null(pipeline_storage_file_); + fflush(pipeline_storage_file_); + } + + const Shader* shader = nullptr; + PipelineStoredDescription pipeline_description; + bool write_pipeline = false; + { + std::unique_lock lock(storage_write_request_lock_); + if (storage_write_thread_shutdown_) { + return; + } + if (!storage_write_shader_queue_.empty()) { + shader = storage_write_shader_queue_.front(); + storage_write_shader_queue_.pop_front(); + } else if (storage_write_flush_shaders_) { + storage_write_flush_shaders_ = false; + flush_shaders = true; + } + if (!storage_write_pipeline_queue_.empty()) { + std::memcpy(&pipeline_description, &storage_write_pipeline_queue_.front(), + sizeof(pipeline_description)); + storage_write_pipeline_queue_.pop_front(); + write_pipeline = true; + } else if (storage_write_flush_pipelines_) { + storage_write_flush_pipelines_ = false; + flush_pipelines = true; + } + if (!shader && !write_pipeline) { + storage_write_request_cond_.wait(lock); + continue; + } + } + + if (shader) { + shader_header.ucode_data_hash = shader->ucode_data_hash(); + shader_header.ucode_dword_count = shader->ucode_dword_count(); + shader_header.type = shader->type(); + assert_not_null(shader_storage_file_); + fwrite(&shader_header, sizeof(shader_header), 1, shader_storage_file_); + if (shader_header.ucode_dword_count) { + ucode_guest_endian.resize(shader_header.ucode_dword_count); + // Need to swap because the hash is calculated for the shader with guest + // endianness. + memory::copy_and_swap(ucode_guest_endian.data(), shader->ucode_dwords(), + shader_header.ucode_dword_count); + fwrite(ucode_guest_endian.data(), shader_header.ucode_dword_count * sizeof(uint32_t), 1, + shader_storage_file_); + } + } + + if (write_pipeline) { + assert_not_null(pipeline_storage_file_); + fwrite(&pipeline_description, sizeof(pipeline_description), 1, pipeline_storage_file_); + } + } +} + +} // namespace rex::graphics::vulkan diff --git a/src/graphics/vulkan/primitive_processor.cpp b/src/graphics/vulkan/primitive_processor.cpp new file mode 100644 index 0000000..cdbedae --- /dev/null +++ b/src/graphics/vulkan/primitive_processor.cpp @@ -0,0 +1,234 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(vulkan_force_expand_point_sprites_in_vs, false, "GPU/Vulkan", + "Force Vulkan point sprite expansion in the vertex shader, even when geometry " + "shaders are available") + .lifecycle(rex::cvar::Lifecycle::kInitOnly); +REXCVAR_DEFINE_BOOL( + vulkan_force_expand_rectangle_lists_in_vs, false, "GPU/Vulkan", + "Force Vulkan rectangle list expansion in the vertex shader, even when geometry " + "shaders are available") + .lifecycle(rex::cvar::Lifecycle::kInitOnly); +REXCVAR_DEFINE_BOOL(vulkan_force_convert_quad_lists_to_triangle_lists, false, "GPU/Vulkan", + "Force Vulkan quad list conversion to triangle lists in primitive processing, " + "even when geometry shaders are available") + .lifecycle(rex::cvar::Lifecycle::kInitOnly); + +namespace rex::graphics::vulkan { + +VulkanPrimitiveProcessor::~VulkanPrimitiveProcessor() { + Shutdown(true); +} + +bool VulkanPrimitiveProcessor::Initialize() { + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Properties& device_properties = vulkan_device->properties(); + // Keep triangle fan handling aligned with D3D12 by always converting fans to + // lists in the shared primitive processor path. + constexpr bool triangle_fans_supported_without_conversion = false; + + // Default to D3D12-like geometry-shader-based handling when available, but + // allow opting into Vulkan fallback paths for debugging and downlevel + // compatibility testing. + bool geometry_shader_primitive_emulation_allowed = device_properties.geometryShader; + bool quad_lists_supported_without_conversion = + geometry_shader_primitive_emulation_allowed && + !REXCVAR_GET(vulkan_force_convert_quad_lists_to_triangle_lists); + bool point_sprites_supported_without_vs_expansion = + geometry_shader_primitive_emulation_allowed && + !REXCVAR_GET(vulkan_force_expand_point_sprites_in_vs); + bool rectangle_lists_supported_without_vs_expansion = + geometry_shader_primitive_emulation_allowed && + !REXCVAR_GET(vulkan_force_expand_rectangle_lists_in_vs); + + if (!InitializeCommon( + device_properties.fullDrawIndexUint32, triangle_fans_supported_without_conversion, false, + quad_lists_supported_without_conversion, point_sprites_supported_without_vs_expansion, + rectangle_lists_supported_without_vs_expansion)) { + Shutdown(); + return false; + } + frame_index_buffer_pool_ = std::make_unique( + vulkan_device, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, + std::max(size_t(kMinRequiredConvertedIndexBufferSize), + ui::GraphicsUploadBufferPool::kDefaultPageSize)); + return true; +} + +void VulkanPrimitiveProcessor::Shutdown(bool from_destructor) { + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + frame_index_buffers_.clear(); + frame_index_buffer_pool_.reset(); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyBuffer, device, builtin_index_buffer_upload_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkFreeMemory, device, + builtin_index_buffer_upload_memory_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyBuffer, device, builtin_index_buffer_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkFreeMemory, device, builtin_index_buffer_memory_); + + if (!from_destructor) { + ShutdownCommon(); + } +} + +void VulkanPrimitiveProcessor::CompletedSubmissionUpdated() { + if (builtin_index_buffer_upload_ != VK_NULL_HANDLE && + command_processor_.GetCompletedSubmission() >= builtin_index_buffer_upload_submission_) { + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyBuffer, device, + builtin_index_buffer_upload_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkFreeMemory, device, + builtin_index_buffer_upload_memory_); + } +} + +void VulkanPrimitiveProcessor::BeginSubmission() { + if (builtin_index_buffer_upload_ != VK_NULL_HANDLE && + builtin_index_buffer_upload_submission_ == UINT64_MAX) { + // No need to submit deferred barriers - builtin_index_buffer_ has never + // been used yet, and builtin_index_buffer_upload_ is written before + // submitting commands reading it. + + command_processor_.EndRenderPass(); + + DeferredCommandBuffer& command_buffer = command_processor_.deferred_command_buffer(); + + VkBufferCopy* copy_region = + command_buffer.CmdCopyBufferEmplace(builtin_index_buffer_upload_, builtin_index_buffer_, 1); + copy_region->srcOffset = 0; + copy_region->dstOffset = 0; + copy_region->size = builtin_index_buffer_size_; + + command_processor_.PushBufferMemoryBarrier( + builtin_index_buffer_, 0, VK_WHOLE_SIZE, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INDEX_READ_BIT); + + builtin_index_buffer_upload_submission_ = command_processor_.GetCurrentSubmission(); + } +} + +void VulkanPrimitiveProcessor::BeginFrame() { + frame_index_buffer_pool_->Reclaim(command_processor_.GetCompletedFrame()); +} + +void VulkanPrimitiveProcessor::EndSubmission() { + frame_index_buffer_pool_->FlushWrites(); +} + +void VulkanPrimitiveProcessor::EndFrame() { + ClearPerFrameCache(); + frame_index_buffers_.clear(); +} + +bool VulkanPrimitiveProcessor::InitializeBuiltinIndexBuffer( + size_t size_bytes, std::function fill_callback) { + assert_not_zero(size_bytes); + assert_true(builtin_index_buffer_ == VK_NULL_HANDLE); + assert_true(builtin_index_buffer_memory_ == VK_NULL_HANDLE); + assert_true(builtin_index_buffer_upload_ == VK_NULL_HANDLE); + assert_true(builtin_index_buffer_upload_memory_ == VK_NULL_HANDLE); + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + builtin_index_buffer_size_ = VkDeviceSize(size_bytes); + if (!ui::vulkan::util::CreateDedicatedAllocationBuffer( + vulkan_device, builtin_index_buffer_size_, + VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, + ui::vulkan::util::MemoryPurpose::kDeviceLocal, builtin_index_buffer_, + builtin_index_buffer_memory_)) { + REXGPU_ERROR( + "Vulkan primitive processor: Failed to create the built-in index " + "buffer GPU resource with {} bytes", + size_bytes); + return false; + } + uint32_t upload_memory_type; + if (!ui::vulkan::util::CreateDedicatedAllocationBuffer( + vulkan_device, builtin_index_buffer_size_, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + ui::vulkan::util::MemoryPurpose::kUpload, builtin_index_buffer_upload_, + builtin_index_buffer_upload_memory_, &upload_memory_type)) { + REXGPU_ERROR( + "Vulkan primitive processor: Failed to create the built-in index " + "buffer upload resource with {} bytes", + size_bytes); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyBuffer, device, builtin_index_buffer_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkFreeMemory, device, builtin_index_buffer_memory_); + return false; + } + + void* mapping; + if (dfn.vkMapMemory(device, builtin_index_buffer_upload_memory_, 0, VK_WHOLE_SIZE, 0, &mapping) != + VK_SUCCESS) { + REXGPU_ERROR( + "Vulkan primitive processor: Failed to map the built-in index buffer " + "upload resource with {} bytes", + size_bytes); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyBuffer, device, + builtin_index_buffer_upload_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkFreeMemory, device, + builtin_index_buffer_upload_memory_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyBuffer, device, builtin_index_buffer_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkFreeMemory, device, builtin_index_buffer_memory_); + return false; + } + fill_callback(mapping); + ui::vulkan::util::FlushMappedMemoryRange(vulkan_device, builtin_index_buffer_memory_, + upload_memory_type); + dfn.vkUnmapMemory(device, builtin_index_buffer_upload_memory_); + + // Schedule uploading in the first submission. + builtin_index_buffer_upload_submission_ = UINT64_MAX; + return true; +} + +void* VulkanPrimitiveProcessor::RequestHostConvertedIndexBufferForCurrentFrame( + xenos::IndexFormat format, uint32_t index_count, bool coalign_for_simd, + uint32_t coalignment_original_address, size_t& backend_handle_out) { + size_t index_size = format == xenos::IndexFormat::kInt16 ? sizeof(uint16_t) : sizeof(uint32_t); + VkBuffer buffer; + VkDeviceSize offset; + uint8_t* mapping = frame_index_buffer_pool_->Request( + command_processor_.GetCurrentFrame(), + index_size * index_count + (coalign_for_simd ? XE_GPU_PRIMITIVE_PROCESSOR_SIMD_SIZE : 0), + index_size, buffer, offset); + if (!mapping) { + return nullptr; + } + if (coalign_for_simd) { + ptrdiff_t coalignment_offset = GetSimdCoalignmentOffset(mapping, coalignment_original_address); + mapping += coalignment_offset; + offset = VkDeviceSize(offset + coalignment_offset); + } + backend_handle_out = frame_index_buffers_.size(); + frame_index_buffers_.emplace_back(buffer, offset); + return mapping; +} + +} // namespace rex::graphics::vulkan diff --git a/src/graphics/vulkan/render_target_cache.cpp b/src/graphics/vulkan/render_target_cache.cpp new file mode 100644 index 0000000..05d1e5c --- /dev/null +++ b/src/graphics/vulkan/render_target_cache.cpp @@ -0,0 +1,6359 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_STRING(render_target_path_vulkan, "", "GPU/Vulkan", + "Vulkan render target implementation path") + .lifecycle(rex::cvar::Lifecycle::kInitOnly); + +// DEFINE_string( +// render_target_path_vulkan, "", +// "Render target emulation path to use on Vulkan.\n" +// "Use: [any, fbo, fsi]\n" +// " fbo:\n" +// " Host framebuffers and fixed-function blending and depth / stencil " +// "testing, copying between render targets when needed.\n" +// " Lower accuracy (limited pixel format support).\n" +// " Performance limited primarily by render target layout changes requiring " +// "copying, but generally higher.\n" +// " fsi:\n" +// " Manual pixel packing, blending and depth / stencil testing, with free " +// "render target layout changes.\n" +// " Requires a GPU supporting fragment shader interlock.\n" +// " Highest accuracy (all pixel formats handled in software).\n" +// " Performance limited primarily by overdraw.\n" +// " Any other value:\n" +// " Choose what is considered the most optimal for the system (currently " +// "always FB because the FSI path is much slower now).", +// "GPU"); + +namespace rex::graphics::vulkan { + +// Generated with `xb buildshaders`. +namespace shaders { +#include "../shaders/vulkan_spirv/host_depth_store_1xmsaa_cs.h" +#include "../shaders/vulkan_spirv/host_depth_store_2xmsaa_cs.h" +#include "../shaders/vulkan_spirv/host_depth_store_4xmsaa_cs.h" +#include "../shaders/vulkan_spirv/passthrough_position_xy_vs.h" +#include "../shaders/vulkan_spirv/resolve_clear_32bpp_cs.h" +#include "../shaders/vulkan_spirv/resolve_clear_32bpp_scaled_cs.h" +#include "../shaders/vulkan_spirv/resolve_clear_64bpp_cs.h" +#include "../shaders/vulkan_spirv/resolve_clear_64bpp_scaled_cs.h" +#include "../shaders/vulkan_spirv/resolve_fast_32bpp_1x2xmsaa_cs.h" +#include "../shaders/vulkan_spirv/resolve_fast_32bpp_1x2xmsaa_scaled_cs.h" +#include "../shaders/vulkan_spirv/resolve_fast_32bpp_4xmsaa_cs.h" +#include "../shaders/vulkan_spirv/resolve_fast_32bpp_4xmsaa_scaled_cs.h" +#include "../shaders/vulkan_spirv/resolve_fast_64bpp_1x2xmsaa_cs.h" +#include "../shaders/vulkan_spirv/resolve_fast_64bpp_1x2xmsaa_scaled_cs.h" +#include "../shaders/vulkan_spirv/resolve_fast_64bpp_4xmsaa_cs.h" +#include "../shaders/vulkan_spirv/resolve_fast_64bpp_4xmsaa_scaled_cs.h" +#include "../shaders/vulkan_spirv/resolve_full_128bpp_cs.h" +#include "../shaders/vulkan_spirv/resolve_full_128bpp_scaled_cs.h" +#include "../shaders/vulkan_spirv/resolve_full_16bpp_cs.h" +#include "../shaders/vulkan_spirv/resolve_full_16bpp_scaled_cs.h" +#include "../shaders/vulkan_spirv/resolve_full_32bpp_cs.h" +#include "../shaders/vulkan_spirv/resolve_full_32bpp_scaled_cs.h" +#include "../shaders/vulkan_spirv/resolve_full_64bpp_cs.h" +#include "../shaders/vulkan_spirv/resolve_full_64bpp_scaled_cs.h" +#include "../shaders/vulkan_spirv/resolve_full_8bpp_cs.h" +#include "../shaders/vulkan_spirv/resolve_full_8bpp_scaled_cs.h" +} // namespace shaders + +const VulkanRenderTargetCache::ResolveCopyShaderCode + VulkanRenderTargetCache::kResolveCopyShaders[size_t( + draw_util::ResolveCopyShaderIndex::kCount)] = { + {shaders::resolve_fast_32bpp_1x2xmsaa_cs, sizeof(shaders::resolve_fast_32bpp_1x2xmsaa_cs), + shaders::resolve_fast_32bpp_1x2xmsaa_scaled_cs, + sizeof(shaders::resolve_fast_32bpp_1x2xmsaa_scaled_cs)}, + {shaders::resolve_fast_32bpp_4xmsaa_cs, sizeof(shaders::resolve_fast_32bpp_4xmsaa_cs), + shaders::resolve_fast_32bpp_4xmsaa_scaled_cs, + sizeof(shaders::resolve_fast_32bpp_4xmsaa_scaled_cs)}, + {shaders::resolve_fast_64bpp_1x2xmsaa_cs, sizeof(shaders::resolve_fast_64bpp_1x2xmsaa_cs), + shaders::resolve_fast_64bpp_1x2xmsaa_scaled_cs, + sizeof(shaders::resolve_fast_64bpp_1x2xmsaa_scaled_cs)}, + {shaders::resolve_fast_64bpp_4xmsaa_cs, sizeof(shaders::resolve_fast_64bpp_4xmsaa_cs), + shaders::resolve_fast_64bpp_4xmsaa_scaled_cs, + sizeof(shaders::resolve_fast_64bpp_4xmsaa_scaled_cs)}, + {shaders::resolve_full_8bpp_cs, sizeof(shaders::resolve_full_8bpp_cs), + shaders::resolve_full_8bpp_scaled_cs, sizeof(shaders::resolve_full_8bpp_scaled_cs)}, + {shaders::resolve_full_16bpp_cs, sizeof(shaders::resolve_full_16bpp_cs), + shaders::resolve_full_16bpp_scaled_cs, sizeof(shaders::resolve_full_16bpp_scaled_cs)}, + {shaders::resolve_full_32bpp_cs, sizeof(shaders::resolve_full_32bpp_cs), + shaders::resolve_full_32bpp_scaled_cs, sizeof(shaders::resolve_full_32bpp_scaled_cs)}, + {shaders::resolve_full_64bpp_cs, sizeof(shaders::resolve_full_64bpp_cs), + shaders::resolve_full_64bpp_scaled_cs, sizeof(shaders::resolve_full_64bpp_scaled_cs)}, + {shaders::resolve_full_128bpp_cs, sizeof(shaders::resolve_full_128bpp_cs), + shaders::resolve_full_128bpp_scaled_cs, sizeof(shaders::resolve_full_128bpp_scaled_cs)}, +}; + +const VulkanRenderTargetCache::TransferPipelineLayoutInfo + VulkanRenderTargetCache::kTransferPipelineLayoutInfos[size_t( + TransferPipelineLayoutIndex::kCount)] = { + // kColor + {kTransferUsedDescriptorSetColorTextureBit, kTransferUsedPushConstantDwordAddressBit}, + // kDepth + {kTransferUsedDescriptorSetDepthStencilTexturesBit, + kTransferUsedPushConstantDwordAddressBit}, + // kColorToStencilBit + {kTransferUsedDescriptorSetColorTextureBit, + kTransferUsedPushConstantDwordAddressBit | kTransferUsedPushConstantDwordStencilMaskBit}, + // kDepthToStencilBit + {kTransferUsedDescriptorSetDepthStencilTexturesBit, + kTransferUsedPushConstantDwordAddressBit | kTransferUsedPushConstantDwordStencilMaskBit}, + // kColorAndHostDepthTexture + {kTransferUsedDescriptorSetHostDepthStencilTexturesBit | + kTransferUsedDescriptorSetColorTextureBit, + kTransferUsedPushConstantDwordHostDepthAddressBit | + kTransferUsedPushConstantDwordAddressBit}, + // kColorAndHostDepthBuffer + {kTransferUsedDescriptorSetHostDepthBufferBit | kTransferUsedDescriptorSetColorTextureBit, + kTransferUsedPushConstantDwordHostDepthAddressBit | + kTransferUsedPushConstantDwordAddressBit}, + // kDepthAndHostDepthTexture + {kTransferUsedDescriptorSetHostDepthStencilTexturesBit | + kTransferUsedDescriptorSetDepthStencilTexturesBit, + kTransferUsedPushConstantDwordHostDepthAddressBit | + kTransferUsedPushConstantDwordAddressBit}, + // kDepthAndHostDepthBuffer + {kTransferUsedDescriptorSetHostDepthBufferBit | + kTransferUsedDescriptorSetDepthStencilTexturesBit, + kTransferUsedPushConstantDwordHostDepthAddressBit | + kTransferUsedPushConstantDwordAddressBit}, +}; + +const VulkanRenderTargetCache::TransferModeInfo + VulkanRenderTargetCache::kTransferModes[size_t(TransferMode::kCount)] = { + // kColorToDepth + {TransferOutput::kDepth, TransferPipelineLayoutIndex::kColor}, + // kColorToColor + {TransferOutput::kColor, TransferPipelineLayoutIndex::kColor}, + // kDepthToDepth + {TransferOutput::kDepth, TransferPipelineLayoutIndex::kDepth}, + // kDepthToColor + {TransferOutput::kColor, TransferPipelineLayoutIndex::kDepth}, + // kColorToStencilBit + {TransferOutput::kStencilBit, TransferPipelineLayoutIndex::kColorToStencilBit}, + // kDepthToStencilBit + {TransferOutput::kStencilBit, TransferPipelineLayoutIndex::kDepthToStencilBit}, + // kColorAndHostDepthToDepth + {TransferOutput::kDepth, TransferPipelineLayoutIndex::kColorAndHostDepthTexture}, + // kDepthAndHostDepthToDepth + {TransferOutput::kDepth, TransferPipelineLayoutIndex::kDepthAndHostDepthTexture}, + // kColorAndHostDepthCopyToDepth + {TransferOutput::kDepth, TransferPipelineLayoutIndex::kColorAndHostDepthBuffer}, + // kDepthAndHostDepthCopyToDepth + {TransferOutput::kDepth, TransferPipelineLayoutIndex::kDepthAndHostDepthBuffer}, +}; + +VulkanRenderTargetCache::VulkanRenderTargetCache(const RegisterFile& register_file, + const memory::Memory& memory, + TraceWriter& trace_writer, + uint32_t draw_resolution_scale_x, + uint32_t draw_resolution_scale_y, + VulkanCommandProcessor& command_processor) + : RenderTargetCache(register_file, memory, &trace_writer, draw_resolution_scale_x, + draw_resolution_scale_y), + command_processor_(command_processor), + trace_writer_(trace_writer) {} + +VulkanRenderTargetCache::~VulkanRenderTargetCache() { + Shutdown(true); +} + +bool VulkanRenderTargetCache::Initialize(uint32_t shared_memory_binding_count) { + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanInstance::Functions& ifn = vulkan_device->vulkan_instance()->functions(); + const VkPhysicalDevice physical_device = vulkan_device->physical_device(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + const ui::vulkan::VulkanDevice::Properties& device_properties = vulkan_device->properties(); + + bool fsi_path_supported = + (device_properties.fragmentShaderSampleInterlock || + device_properties.fragmentShaderPixelInterlock) && + device_properties.fragmentStoresAndAtomics && device_properties.sampleRateShading && + device_properties.standardSampleLocations && + shared_memory_binding_count < device_properties.maxPerStageDescriptorStorageBuffers; + if (REXCVAR_GET(render_target_path_vulkan) == "fsi") { + path_ = Path::kPixelShaderInterlock; + } else { + path_ = Path::kHostRenderTargets; + } + // Fragment shader interlock is a feature implemented by pretty advanced GPUs, + // closer to Direct3D 11 / OpenGL ES 3.2 level mainly, not Direct3D 10 / + // OpenGL ES 3.1. Thus, it's fine to demand a wide range of other optional + // features for the fragment shader interlock backend to work. + if (path_ == Path::kPixelShaderInterlock) { + // Interlocking between fragments with common sample coverage is enough, but + // interlocking more is acceptable too (fragmentShaderShadingRateInterlock + // would be okay too, but it's unlikely that an implementation would + // advertise only it and not any other ones, as it's a very specific feature + // interacting with another optional feature that is variable shading rate, + // so there's no need to overcomplicate the checks and the shader execution + // mode setting). + // Sample-rate shading is required by certain SPIR-V revisions to access the + // sample mask fragment shader input. + // Stanard sample locations are needed for calculating the depth at the + // samples. + // It's unlikely that a device exposing fragment shader interlock won't have + // a large enough storage buffer range and a sufficient SSBO slot count for + // all the shared memory buffers and the EDRAM buffer - an in a conflict + // between, for instance, the ability to vfetch and memexport in fragment + // shaders, and the usage of fragment shader interlock, prefer the former + // for simplicity. + if (!fsi_path_supported) { + path_ = Path::kHostRenderTargets; + } + } + + // Format support. + constexpr VkFormatFeatureFlags kUsedDepthFormatFeatures = + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; + constexpr VkFormatFeatureFlags kUsedColorFormatFeatures = + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; + bool gamma_render_target_as_unorm16_requested = + path_ == Path::kHostRenderTargets && REXCVAR_GET(gamma_render_target_as_unorm16); + VkFormatProperties depth_unorm24_properties; + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_D24_UNORM_S8_UINT, + &depth_unorm24_properties); + depth_unorm24_vulkan_format_supported_ = (depth_unorm24_properties.optimalTilingFeatures & + kUsedDepthFormatFeatures) == kUsedDepthFormatFeatures; + VkFormatProperties color_rg16_snorm_properties; + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R16G16_SNORM, + &color_rg16_snorm_properties); + VkFormatProperties color_rgba16_snorm_properties; + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R16G16B16A16_SNORM, + &color_rgba16_snorm_properties); + VkFormatProperties color_rg16_sfloat_properties; + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R16G16_SFLOAT, + &color_rg16_sfloat_properties); + VkFormatProperties color_rgba16_sfloat_properties; + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R16G16B16A16_SFLOAT, + &color_rgba16_sfloat_properties); + VkFormatProperties color_rgba16_unorm_properties; + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R16G16B16A16_UNORM, + &color_rgba16_unorm_properties); + bool color_rg16_snorm_supported = (color_rg16_snorm_properties.optimalTilingFeatures & + kUsedColorFormatFeatures) == kUsedColorFormatFeatures; + bool color_rgba16_snorm_supported = (color_rgba16_snorm_properties.optimalTilingFeatures & + kUsedColorFormatFeatures) == kUsedColorFormatFeatures; + bool color_rg16_sfloat_supported = (color_rg16_sfloat_properties.optimalTilingFeatures & + kUsedColorFormatFeatures) == kUsedColorFormatFeatures; + bool color_rgba16_sfloat_supported = (color_rgba16_sfloat_properties.optimalTilingFeatures & + kUsedColorFormatFeatures) == kUsedColorFormatFeatures; + bool color_rgba16_unorm_supported = (color_rgba16_unorm_properties.optimalTilingFeatures & + kUsedColorFormatFeatures) == kUsedColorFormatFeatures; + bool color_rg16_draw_format_supported = true; + if (!color_rg16_snorm_supported) { + if (color_rg16_sfloat_supported) { + color_rg16_draw_format_fallback_to_float_ = true; + REXGPU_WARN( + "VulkanRenderTargetCache: R16G16_SNORM render target support is unavailable; " + "falling back to R16G16_SFLOAT for k_16_16"); + } else { + color_rg16_draw_format_supported = false; + } + } + bool color_rgba16_draw_format_supported = true; + if (!color_rgba16_snorm_supported) { + if (color_rgba16_sfloat_supported) { + color_rgba16_draw_format_fallback_to_float_ = true; + REXGPU_WARN( + "VulkanRenderTargetCache: R16G16B16A16_SNORM render target support is unavailable; " + "falling back to R16G16B16A16_SFLOAT for k_16_16_16_16"); + } else { + color_rgba16_draw_format_supported = false; + } + } + if (path_ == Path::kHostRenderTargets && + (!color_rg16_draw_format_supported || !color_rgba16_draw_format_supported)) { + if (fsi_path_supported) { + REXGPU_WARN( + "VulkanRenderTargetCache: Host render target 16-bit formats are unsupported " + "(R16G16: {}, R16G16B16A16: {}); switching to fragment shader interlock " + "path for D3D12 parity", + color_rg16_draw_format_supported ? "available" : "unavailable", + color_rgba16_draw_format_supported ? "available" : "unavailable"); + path_ = Path::kPixelShaderInterlock; + } else { + REXGPU_ERROR( + "VulkanRenderTargetCache: Host render target 16-bit formats are unsupported " + "(R16G16: {}, R16G16B16A16: {}), and fragment shader interlock fallback " + "is unavailable", + color_rg16_draw_format_supported ? "available" : "unavailable", + color_rgba16_draw_format_supported ? "available" : "unavailable"); + return false; + } + } + if (path_ == Path::kHostRenderTargets && gamma_render_target_as_unorm16_requested && + !color_rgba16_unorm_supported) { + if (fsi_path_supported) { + REXGPU_WARN( + "VulkanRenderTargetCache: R16G16B16A16_UNORM render target support " + "is unavailable for k_8_8_8_8_GAMMA linear storage; switching to " + "fragment shader interlock path for D3D12 parity"); + path_ = Path::kPixelShaderInterlock; + } else { + REXGPU_ERROR( + "VulkanRenderTargetCache: R16G16B16A16_UNORM render target support " + "is unavailable for k_8_8_8_8_GAMMA linear storage, and fragment " + "shader interlock fallback is unavailable"); + return false; + } + } + VkFormatProperties color_rg16_uint_properties; + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R16G16_UINT, + &color_rg16_uint_properties); + VkFormatProperties color_rgba16_uint_properties; + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R16G16B16A16_UINT, + &color_rgba16_uint_properties); + VkFormatProperties color_r32_uint_properties; + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R32_UINT, + &color_r32_uint_properties); + VkFormatProperties color_rg32_uint_properties; + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R32G32_UINT, + &color_rg32_uint_properties); + color_16bit_transfer_uint_formats_supported_ = + (color_rg16_uint_properties.optimalTilingFeatures & kUsedColorFormatFeatures) == + kUsedColorFormatFeatures && + (color_rgba16_uint_properties.optimalTilingFeatures & kUsedColorFormatFeatures) == + kUsedColorFormatFeatures; + if (!color_16bit_transfer_uint_formats_supported_) { + REXGPU_WARN( + "VulkanRenderTargetCache: R16G16/R16G16B16A16 UINT ownership transfer formats are not " + "supported"); + } + color_32bit_transfer_uint_formats_supported_ = + (color_r32_uint_properties.optimalTilingFeatures & kUsedColorFormatFeatures) == + kUsedColorFormatFeatures && + (color_rg32_uint_properties.optimalTilingFeatures & kUsedColorFormatFeatures) == + kUsedColorFormatFeatures; + if (!color_32bit_transfer_uint_formats_supported_) { + REXGPU_WARN( + "VulkanRenderTargetCache: R32/R32G32 UINT ownership transfer formats are not supported"); + } + if ((device_properties.framebufferColorSampleCounts & VK_SAMPLE_COUNT_4_BIT) && + !(device_properties.sampledImageIntegerSampleCounts & VK_SAMPLE_COUNT_4_BIT)) { + REXGPU_WARN("VulkanRenderTargetCache: 4x integer sampled-image support is unavailable"); + } + + // 2x MSAA support. + if (REXCVAR_GET(native_2x_msaa)) { + msaa_2x_attachments_supported_ = + (device_properties.framebufferColorSampleCounts & + device_properties.framebufferDepthSampleCounts & + device_properties.framebufferStencilSampleCounts & + device_properties.sampledImageColorSampleCounts & + device_properties.sampledImageDepthSampleCounts & + device_properties.sampledImageStencilSampleCounts & VK_SAMPLE_COUNT_2_BIT); + msaa_2x_no_attachments_supported_ = + (device_properties.framebufferNoAttachmentsSampleCounts & VK_SAMPLE_COUNT_2_BIT) != 0; + } else { + msaa_2x_attachments_supported_ = false; + msaa_2x_no_attachments_supported_ = false; + } + bool integer_transfer_sample_1x_supported = + (device_properties.framebufferColorSampleCounts & VK_SAMPLE_COUNT_1_BIT) != 0 && + (device_properties.sampledImageIntegerSampleCounts & VK_SAMPLE_COUNT_1_BIT) != 0; + bool integer_transfer_sample_2x_supported = + (device_properties.framebufferColorSampleCounts & VK_SAMPLE_COUNT_2_BIT) != 0 && + (device_properties.sampledImageIntegerSampleCounts & VK_SAMPLE_COUNT_2_BIT) != 0; + bool integer_transfer_sample_4x_supported = + (device_properties.framebufferColorSampleCounts & VK_SAMPLE_COUNT_4_BIT) == 0 || + (device_properties.sampledImageIntegerSampleCounts & VK_SAMPLE_COUNT_4_BIT) != 0; + bool bit_exact_host_color_transfer_supported = + color_16bit_transfer_uint_formats_supported_ && + color_32bit_transfer_uint_formats_supported_ && integer_transfer_sample_1x_supported && + integer_transfer_sample_4x_supported && + (!msaa_2x_attachments_supported_ || integer_transfer_sample_2x_supported); + if (path_ == Path::kHostRenderTargets && !bit_exact_host_color_transfer_supported) { + if (fsi_path_supported) { + REXGPU_WARN( + "VulkanRenderTargetCache: Host render target ownership transfers " + "can't be bit-exact on this device; switching to fragment shader " + "interlock path for D3D12 parity"); + path_ = Path::kPixelShaderInterlock; + } else { + REXGPU_ERROR( + "VulkanRenderTargetCache: Bit-exact host render target ownership " + "transfers require UINT transfer formats and integer sampled-image " + "MSAA support, and fragment shader interlock fallback is unavailable"); + return false; + } + } + + // Descriptor set layouts. + VkDescriptorSetLayoutBinding descriptor_set_layout_bindings[2]; + descriptor_set_layout_bindings[0].binding = 0; + descriptor_set_layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + descriptor_set_layout_bindings[0].descriptorCount = 1; + descriptor_set_layout_bindings[0].stageFlags = + VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT; + descriptor_set_layout_bindings[0].pImmutableSamplers = nullptr; + VkDescriptorSetLayoutCreateInfo descriptor_set_layout_create_info; + descriptor_set_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + descriptor_set_layout_create_info.pNext = nullptr; + descriptor_set_layout_create_info.flags = 0; + descriptor_set_layout_create_info.bindingCount = 1; + descriptor_set_layout_create_info.pBindings = descriptor_set_layout_bindings; + if (dfn.vkCreateDescriptorSetLayout(device, &descriptor_set_layout_create_info, nullptr, + &descriptor_set_layout_storage_buffer_) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the descriptor set layout " + "with one storage buffer"); + Shutdown(); + return false; + } + descriptor_set_layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + if (dfn.vkCreateDescriptorSetLayout(device, &descriptor_set_layout_create_info, nullptr, + &descriptor_set_layout_sampled_image_) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the descriptor set layout " + "with one sampled image"); + Shutdown(); + return false; + } + descriptor_set_layout_bindings[1].binding = 1; + descriptor_set_layout_bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + descriptor_set_layout_bindings[1].descriptorCount = 1; + descriptor_set_layout_bindings[1].stageFlags = descriptor_set_layout_bindings[0].stageFlags; + descriptor_set_layout_bindings[1].pImmutableSamplers = nullptr; + descriptor_set_layout_create_info.bindingCount = 2; + if (dfn.vkCreateDescriptorSetLayout(device, &descriptor_set_layout_create_info, nullptr, + &descriptor_set_layout_sampled_image_x2_) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the descriptor set layout " + "with two sampled images"); + Shutdown(); + return false; + } + + // Descriptor set pools. + // The pool sizes were chosen without a specific reason. + VkDescriptorPoolSize descriptor_set_layout_size; + descriptor_set_layout_size.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + descriptor_set_layout_size.descriptorCount = 1; + descriptor_set_pool_sampled_image_ = std::make_unique( + vulkan_device, 256, 1, &descriptor_set_layout_size, descriptor_set_layout_sampled_image_); + descriptor_set_layout_size.descriptorCount = 2; + descriptor_set_pool_sampled_image_x2_ = + std::make_unique( + vulkan_device, 256, 1, &descriptor_set_layout_size, + descriptor_set_layout_sampled_image_x2_); + + // EDRAM contents reinterpretation buffer. + // 90 MB with 9x resolution scaling - within the minimum + // maxStorageBufferRange. + if (!ui::vulkan::util::CreateDedicatedAllocationBuffer( + vulkan_device, + VkDeviceSize(xenos::kEdramSizeBytes * + (draw_resolution_scale_x() * draw_resolution_scale_y())), + VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, + ui::vulkan::util::MemoryPurpose::kDeviceLocal, edram_buffer_, edram_buffer_memory_)) { + REXGPU_ERROR("VulkanRenderTargetCache: Failed to create the EDRAM buffer"); + Shutdown(); + return false; + } + if (GetPath() == Path::kPixelShaderInterlock) { + // The first operation will likely be drawing. + edram_buffer_usage_ = EdramBufferUsage::kFragmentReadWrite; + } else { + // The first operation will likely be depth self-comparison. + edram_buffer_usage_ = EdramBufferUsage::kFragmentRead; + } + edram_buffer_modification_status_ = EdramBufferModificationStatus::kUnmodified; + VkDescriptorPoolSize edram_storage_buffer_descriptor_pool_size; + edram_storage_buffer_descriptor_pool_size.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + edram_storage_buffer_descriptor_pool_size.descriptorCount = 1; + VkDescriptorPoolCreateInfo edram_storage_buffer_descriptor_pool_create_info; + edram_storage_buffer_descriptor_pool_create_info.sType = + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + edram_storage_buffer_descriptor_pool_create_info.pNext = nullptr; + edram_storage_buffer_descriptor_pool_create_info.flags = 0; + edram_storage_buffer_descriptor_pool_create_info.maxSets = 1; + edram_storage_buffer_descriptor_pool_create_info.poolSizeCount = 1; + edram_storage_buffer_descriptor_pool_create_info.pPoolSizes = + &edram_storage_buffer_descriptor_pool_size; + if (dfn.vkCreateDescriptorPool(device, &edram_storage_buffer_descriptor_pool_create_info, nullptr, + &edram_storage_buffer_descriptor_pool_) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the EDRAM buffer storage " + "buffer descriptor pool"); + Shutdown(); + return false; + } + VkDescriptorSetAllocateInfo edram_storage_buffer_descriptor_set_allocate_info; + edram_storage_buffer_descriptor_set_allocate_info.sType = + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + edram_storage_buffer_descriptor_set_allocate_info.pNext = nullptr; + edram_storage_buffer_descriptor_set_allocate_info.descriptorPool = + edram_storage_buffer_descriptor_pool_; + edram_storage_buffer_descriptor_set_allocate_info.descriptorSetCount = 1; + edram_storage_buffer_descriptor_set_allocate_info.pSetLayouts = + &descriptor_set_layout_storage_buffer_; + if (dfn.vkAllocateDescriptorSets(device, &edram_storage_buffer_descriptor_set_allocate_info, + &edram_storage_buffer_descriptor_set_) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to allocate the EDRAM buffer storage " + "buffer descriptor set"); + Shutdown(); + return false; + } + VkDescriptorBufferInfo edram_storage_buffer_descriptor_buffer_info; + edram_storage_buffer_descriptor_buffer_info.buffer = edram_buffer_; + edram_storage_buffer_descriptor_buffer_info.offset = 0; + edram_storage_buffer_descriptor_buffer_info.range = VK_WHOLE_SIZE; + VkWriteDescriptorSet edram_storage_buffer_descriptor_write; + edram_storage_buffer_descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + edram_storage_buffer_descriptor_write.pNext = nullptr; + edram_storage_buffer_descriptor_write.dstSet = edram_storage_buffer_descriptor_set_; + edram_storage_buffer_descriptor_write.dstBinding = 0; + edram_storage_buffer_descriptor_write.dstArrayElement = 0; + edram_storage_buffer_descriptor_write.descriptorCount = 1; + edram_storage_buffer_descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + edram_storage_buffer_descriptor_write.pImageInfo = nullptr; + edram_storage_buffer_descriptor_write.pBufferInfo = &edram_storage_buffer_descriptor_buffer_info; + edram_storage_buffer_descriptor_write.pTexelBufferView = nullptr; + dfn.vkUpdateDescriptorSets(device, 1, &edram_storage_buffer_descriptor_write, 0, nullptr); + + bool draw_resolution_scaled = IsDrawResolutionScaled(); + + // Resolve copy pipeline layout. + VkDescriptorSetLayout resolve_copy_descriptor_set_layouts[kResolveCopyDescriptorSetCount] = {}; + resolve_copy_descriptor_set_layouts[kResolveCopyDescriptorSetEdram] = + descriptor_set_layout_storage_buffer_; + resolve_copy_descriptor_set_layouts[kResolveCopyDescriptorSetDest] = + command_processor_.GetSingleTransientDescriptorLayout( + VulkanCommandProcessor::SingleTransientDescriptorLayout ::kStorageBufferCompute); + VkPushConstantRange resolve_copy_push_constant_range; + resolve_copy_push_constant_range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + resolve_copy_push_constant_range.offset = 0; + // Potentially binding all of the shared memory at 1x resolution, but only + // portions with scaled resolution. + resolve_copy_push_constant_range.size = + draw_resolution_scaled ? sizeof(draw_util::ResolveCopyShaderConstants::DestRelative) + : sizeof(draw_util::ResolveCopyShaderConstants); + VkPipelineLayoutCreateInfo resolve_copy_pipeline_layout_create_info; + resolve_copy_pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + resolve_copy_pipeline_layout_create_info.pNext = nullptr; + resolve_copy_pipeline_layout_create_info.flags = 0; + resolve_copy_pipeline_layout_create_info.setLayoutCount = kResolveCopyDescriptorSetCount; + resolve_copy_pipeline_layout_create_info.pSetLayouts = resolve_copy_descriptor_set_layouts; + resolve_copy_pipeline_layout_create_info.pushConstantRangeCount = 1; + resolve_copy_pipeline_layout_create_info.pPushConstantRanges = &resolve_copy_push_constant_range; + if (dfn.vkCreatePipelineLayout(device, &resolve_copy_pipeline_layout_create_info, nullptr, + &resolve_copy_pipeline_layout_) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the resolve copy pipeline " + "layout"); + Shutdown(); + return false; + } + + // Direct resolve pipeline layouts (destination storage buffer + source image). + auto create_direct_resolve_pipeline_layout = [&](VkDescriptorSetLayout source_layout, + VkPipelineLayout* pipeline_layout_out) { + VkDescriptorSetLayout descriptor_set_layouts[] = { + command_processor_.GetSingleTransientDescriptorLayout( + VulkanCommandProcessor::SingleTransientDescriptorLayout::kStorageBufferCompute), + source_layout, + }; + VkPushConstantRange push_constant_range; + push_constant_range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + push_constant_range.offset = 0; + push_constant_range.size = sizeof(DirectResolvePushConstants); + VkPipelineLayoutCreateInfo pipeline_layout_create_info; + pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipeline_layout_create_info.pNext = nullptr; + pipeline_layout_create_info.flags = 0; + pipeline_layout_create_info.setLayoutCount = uint32_t(rex::countof(descriptor_set_layouts)); + pipeline_layout_create_info.pSetLayouts = descriptor_set_layouts; + pipeline_layout_create_info.pushConstantRangeCount = 1; + pipeline_layout_create_info.pPushConstantRanges = &push_constant_range; + if (dfn.vkCreatePipelineLayout(device, &pipeline_layout_create_info, nullptr, + pipeline_layout_out) != VK_SUCCESS) { + *pipeline_layout_out = VK_NULL_HANDLE; + } + }; + create_direct_resolve_pipeline_layout(descriptor_set_layout_sampled_image_, + &direct_resolve_pipeline_layout_color_); + create_direct_resolve_pipeline_layout(descriptor_set_layout_sampled_image_x2_, + &direct_resolve_pipeline_layout_depth_); + + // Resolve copy pipelines. + for (size_t i = 0; i < size_t(draw_util::ResolveCopyShaderIndex::kCount); ++i) { + const draw_util::ResolveCopyShaderInfo& resolve_copy_shader_info = + draw_util::resolve_copy_shader_info[i]; + const ResolveCopyShaderCode& resolve_copy_shader_code = kResolveCopyShaders[i]; + // Somewhat verification whether resolve_copy_shaders_ is up to date. + assert_true(resolve_copy_shader_code.unscaled && resolve_copy_shader_code.unscaled_size_bytes && + resolve_copy_shader_code.scaled && resolve_copy_shader_code.scaled_size_bytes); + VkPipeline resolve_copy_pipeline = ui::vulkan::util::CreateComputePipeline( + vulkan_device, resolve_copy_pipeline_layout_, + draw_resolution_scaled ? resolve_copy_shader_code.scaled + : resolve_copy_shader_code.unscaled, + draw_resolution_scaled ? resolve_copy_shader_code.scaled_size_bytes + : resolve_copy_shader_code.unscaled_size_bytes); + if (resolve_copy_pipeline == VK_NULL_HANDLE) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the resolve copy " + "pipeline {}", + resolve_copy_shader_info.debug_name); + Shutdown(); + return false; + } + vulkan_device->SetObjectName(VK_OBJECT_TYPE_PIPELINE, resolve_copy_pipeline, + resolve_copy_shader_info.debug_name); + resolve_copy_pipelines_[i] = resolve_copy_pipeline; + } + + if (path_ == Path::kHostRenderTargets) { + // Host render targets. + + gamma_render_target_as_unorm16_ = gamma_render_target_as_unorm16_requested; + + depth_float24_round_ = REXCVAR_GET(depth_float24_round); + depth_float24_convert_in_pixel_shader_ = REXCVAR_GET(depth_float24_convert_in_pixel_shader); + + // Host depth storing pipeline layout. + VkDescriptorSetLayout host_depth_store_descriptor_set_layouts[] = { + // Destination EDRAM storage buffer. + descriptor_set_layout_storage_buffer_, + // Source depth / stencil texture (only depth is used). + descriptor_set_layout_sampled_image_x2_, + }; + VkPushConstantRange host_depth_store_push_constant_range; + host_depth_store_push_constant_range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + host_depth_store_push_constant_range.offset = 0; + host_depth_store_push_constant_range.size = sizeof(HostDepthStoreConstants); + VkPipelineLayoutCreateInfo host_depth_store_pipeline_layout_create_info; + host_depth_store_pipeline_layout_create_info.sType = + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + host_depth_store_pipeline_layout_create_info.pNext = nullptr; + host_depth_store_pipeline_layout_create_info.flags = 0; + host_depth_store_pipeline_layout_create_info.setLayoutCount = + uint32_t(rex::countof(host_depth_store_descriptor_set_layouts)); + host_depth_store_pipeline_layout_create_info.pSetLayouts = + host_depth_store_descriptor_set_layouts; + host_depth_store_pipeline_layout_create_info.pushConstantRangeCount = 1; + host_depth_store_pipeline_layout_create_info.pPushConstantRanges = + &host_depth_store_push_constant_range; + if (dfn.vkCreatePipelineLayout(device, &host_depth_store_pipeline_layout_create_info, nullptr, + &host_depth_store_pipeline_layout_) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the host depth storing " + "pipeline layout"); + Shutdown(); + return false; + } + const std::pair host_depth_store_shaders[] = { + {shaders::host_depth_store_1xmsaa_cs, sizeof(shaders::host_depth_store_1xmsaa_cs)}, + {shaders::host_depth_store_2xmsaa_cs, sizeof(shaders::host_depth_store_2xmsaa_cs)}, + {shaders::host_depth_store_4xmsaa_cs, sizeof(shaders::host_depth_store_4xmsaa_cs)}, + }; + for (size_t i = 0; i < rex::countof(host_depth_store_shaders); ++i) { + const std::pair host_depth_store_shader = + host_depth_store_shaders[i]; + VkPipeline host_depth_store_pipeline = ui::vulkan::util::CreateComputePipeline( + vulkan_device, host_depth_store_pipeline_layout_, host_depth_store_shader.first, + host_depth_store_shader.second); + if (host_depth_store_pipeline == VK_NULL_HANDLE) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the {}-sample host " + "depth storing pipeline", + uint32_t(1) << i); + Shutdown(); + return false; + } + host_depth_store_pipelines_[i] = host_depth_store_pipeline; + } + + // Transfer and clear vertex buffer, for quads of up to tile granularity. + transfer_vertex_buffer_pool_ = std::make_unique( + vulkan_device, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, + std::max( + ui::vulkan::VulkanUploadBufferPool::kDefaultPageSize, + sizeof(float) * 2 * 6 * Transfer::kMaxCutoutBorderRectangles * xenos::kEdramTileCount)); + + // Transfer vertex shader. + transfer_passthrough_vertex_shader_ = + ui::vulkan::util::CreateShaderModule(vulkan_device, shaders::passthrough_position_xy_vs, + sizeof(shaders::passthrough_position_xy_vs)); + if (transfer_passthrough_vertex_shader_ == VK_NULL_HANDLE) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the render target " + "ownership transfer vertex shader"); + Shutdown(); + return false; + } + + // Transfer pipeline layouts. + VkDescriptorSetLayout + transfer_pipeline_layout_descriptor_set_layouts[kTransferUsedDescriptorSetCount]; + VkPushConstantRange transfer_pipeline_layout_push_constant_range; + transfer_pipeline_layout_push_constant_range.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + transfer_pipeline_layout_push_constant_range.offset = 0; + VkPipelineLayoutCreateInfo transfer_pipeline_layout_create_info; + transfer_pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + transfer_pipeline_layout_create_info.pNext = nullptr; + transfer_pipeline_layout_create_info.flags = 0; + transfer_pipeline_layout_create_info.pSetLayouts = + transfer_pipeline_layout_descriptor_set_layouts; + transfer_pipeline_layout_create_info.pPushConstantRanges = + &transfer_pipeline_layout_push_constant_range; + for (size_t i = 0; i < size_t(TransferPipelineLayoutIndex::kCount); ++i) { + const TransferPipelineLayoutInfo& transfer_pipeline_layout_info = + kTransferPipelineLayoutInfos[i]; + transfer_pipeline_layout_create_info.setLayoutCount = 0; + uint32_t transfer_pipeline_layout_descriptor_sets_remaining = + transfer_pipeline_layout_info.used_descriptor_sets; + uint32_t transfer_pipeline_layout_descriptor_set_index; + while (rex::bit_scan_forward(transfer_pipeline_layout_descriptor_sets_remaining, + &transfer_pipeline_layout_descriptor_set_index)) { + transfer_pipeline_layout_descriptor_sets_remaining &= + ~(uint32_t(1) << transfer_pipeline_layout_descriptor_set_index); + VkDescriptorSetLayout transfer_pipeline_layout_descriptor_set_layout = VK_NULL_HANDLE; + switch (TransferUsedDescriptorSet(transfer_pipeline_layout_descriptor_set_index)) { + case kTransferUsedDescriptorSetHostDepthBuffer: + transfer_pipeline_layout_descriptor_set_layout = descriptor_set_layout_storage_buffer_; + break; + case kTransferUsedDescriptorSetHostDepthStencilTextures: + case kTransferUsedDescriptorSetDepthStencilTextures: + transfer_pipeline_layout_descriptor_set_layout = + descriptor_set_layout_sampled_image_x2_; + break; + case kTransferUsedDescriptorSetColorTexture: + transfer_pipeline_layout_descriptor_set_layout = descriptor_set_layout_sampled_image_; + break; + default: + assert_unhandled_case( + TransferUsedDescriptorSet(transfer_pipeline_layout_descriptor_set_index)); + } + transfer_pipeline_layout_descriptor_set_layouts[transfer_pipeline_layout_create_info + .setLayoutCount++] = + transfer_pipeline_layout_descriptor_set_layout; + } + transfer_pipeline_layout_push_constant_range.size = + uint32_t(sizeof(uint32_t) * + rex::bit_count(transfer_pipeline_layout_info.used_push_constant_dwords)); + transfer_pipeline_layout_create_info.pushConstantRangeCount = + transfer_pipeline_layout_info.used_push_constant_dwords ? 1 : 0; + if (dfn.vkCreatePipelineLayout(device, &transfer_pipeline_layout_create_info, nullptr, + &transfer_pipeline_layouts_[i]) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the render target " + "ownership transfer pipeline layout {}", + i); + Shutdown(); + return false; + } + } + + // Dump pipeline layouts. + VkDescriptorSetLayout dump_pipeline_layout_descriptor_set_layouts[kDumpDescriptorSetCount]; + dump_pipeline_layout_descriptor_set_layouts[kDumpDescriptorSetEdram] = + descriptor_set_layout_storage_buffer_; + dump_pipeline_layout_descriptor_set_layouts[kDumpDescriptorSetSource] = + descriptor_set_layout_sampled_image_; + VkPushConstantRange dump_pipeline_layout_push_constant_range; + dump_pipeline_layout_push_constant_range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + dump_pipeline_layout_push_constant_range.offset = 0; + dump_pipeline_layout_push_constant_range.size = sizeof(uint32_t) * kDumpPushConstantCount; + VkPipelineLayoutCreateInfo dump_pipeline_layout_create_info; + dump_pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + dump_pipeline_layout_create_info.pNext = nullptr; + dump_pipeline_layout_create_info.flags = 0; + dump_pipeline_layout_create_info.setLayoutCount = + uint32_t(rex::countof(dump_pipeline_layout_descriptor_set_layouts)); + dump_pipeline_layout_create_info.pSetLayouts = dump_pipeline_layout_descriptor_set_layouts; + dump_pipeline_layout_create_info.pushConstantRangeCount = 1; + dump_pipeline_layout_create_info.pPushConstantRanges = + &dump_pipeline_layout_push_constant_range; + if (dfn.vkCreatePipelineLayout(device, &dump_pipeline_layout_create_info, nullptr, + &dump_pipeline_layout_color_) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the color render target " + "dumping pipeline layout"); + Shutdown(); + return false; + } + dump_pipeline_layout_descriptor_set_layouts[kDumpDescriptorSetSource] = + descriptor_set_layout_sampled_image_x2_; + if (dfn.vkCreatePipelineLayout(device, &dump_pipeline_layout_create_info, nullptr, + &dump_pipeline_layout_depth_) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the depth render target " + "dumping pipeline layout"); + Shutdown(); + return false; + } + } else if (path_ == Path::kPixelShaderInterlock) { + // Pixel (fragment) shader interlock. + + // Keep parity with D3D12 ROV, which uses 2x-as-4x in this path. + msaa_2x_attachments_supported_ = false; + msaa_2x_no_attachments_supported_ = false; + + // Blending is done in linear space directly in shaders. + gamma_render_target_as_unorm16_ = false; + + // Always true float24 depth rounded to the nearest even. + depth_float24_round_ = true; + depth_float24_convert_in_pixel_shader_ = true; + + // The pipeline layout and the pipelines for clearing the EDRAM buffer in + // resolves. + VkPushConstantRange resolve_fsi_clear_push_constant_range; + resolve_fsi_clear_push_constant_range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + resolve_fsi_clear_push_constant_range.offset = 0; + resolve_fsi_clear_push_constant_range.size = sizeof(draw_util::ResolveClearShaderConstants); + VkPipelineLayoutCreateInfo resolve_fsi_clear_pipeline_layout_create_info; + resolve_fsi_clear_pipeline_layout_create_info.sType = + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + resolve_fsi_clear_pipeline_layout_create_info.pNext = nullptr; + resolve_fsi_clear_pipeline_layout_create_info.flags = 0; + resolve_fsi_clear_pipeline_layout_create_info.setLayoutCount = 1; + resolve_fsi_clear_pipeline_layout_create_info.pSetLayouts = + &descriptor_set_layout_storage_buffer_; + resolve_fsi_clear_pipeline_layout_create_info.pushConstantRangeCount = 1; + resolve_fsi_clear_pipeline_layout_create_info.pPushConstantRanges = + &resolve_fsi_clear_push_constant_range; + if (dfn.vkCreatePipelineLayout(device, &resolve_fsi_clear_pipeline_layout_create_info, nullptr, + &resolve_fsi_clear_pipeline_layout_) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the resolve EDRAM buffer " + "clear pipeline layout"); + Shutdown(); + return false; + } + resolve_fsi_clear_32bpp_pipeline_ = ui::vulkan::util::CreateComputePipeline( + vulkan_device, resolve_fsi_clear_pipeline_layout_, + draw_resolution_scaled ? shaders::resolve_clear_32bpp_scaled_cs + : shaders::resolve_clear_32bpp_cs, + draw_resolution_scaled ? sizeof(shaders::resolve_clear_32bpp_scaled_cs) + : sizeof(shaders::resolve_clear_32bpp_cs)); + if (resolve_fsi_clear_32bpp_pipeline_ == VK_NULL_HANDLE) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the 32bpp resolve EDRAM " + "buffer clear pipeline"); + Shutdown(); + return false; + } + resolve_fsi_clear_64bpp_pipeline_ = ui::vulkan::util::CreateComputePipeline( + vulkan_device, resolve_fsi_clear_pipeline_layout_, + draw_resolution_scaled ? shaders::resolve_clear_64bpp_scaled_cs + : shaders::resolve_clear_64bpp_cs, + draw_resolution_scaled ? sizeof(shaders::resolve_clear_64bpp_scaled_cs) + : sizeof(shaders::resolve_clear_64bpp_cs)); + if (resolve_fsi_clear_64bpp_pipeline_ == VK_NULL_HANDLE) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the 64bpp resolve EDRAM " + "buffer clear pipeline"); + Shutdown(); + return false; + } + + // Common render pass. + VkSubpassDescription fsi_subpass = {}; + fsi_subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + // Fragment shader interlock provides synchronization and ordering within a + // subpass, create an external by-region dependency to maintain interlocking + // between passes. Framebuffer-global dependencies will be made with + // explicit barriers when the addressing of the EDRAM buffer relatively to + // the fragment coordinates is changed. + VkSubpassDependency fsi_subpass_dependencies[2]; + fsi_subpass_dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL; + fsi_subpass_dependencies[0].dstSubpass = 0; + fsi_subpass_dependencies[0].srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + fsi_subpass_dependencies[0].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + fsi_subpass_dependencies[0].srcAccessMask = + VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + fsi_subpass_dependencies[0].dstAccessMask = + VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + fsi_subpass_dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; + fsi_subpass_dependencies[1] = fsi_subpass_dependencies[0]; + std::swap(fsi_subpass_dependencies[1].srcSubpass, fsi_subpass_dependencies[1].dstSubpass); + VkRenderPassCreateInfo fsi_render_pass_create_info; + fsi_render_pass_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + fsi_render_pass_create_info.pNext = nullptr; + fsi_render_pass_create_info.flags = 0; + fsi_render_pass_create_info.attachmentCount = 0; + fsi_render_pass_create_info.pAttachments = nullptr; + fsi_render_pass_create_info.subpassCount = 1; + fsi_render_pass_create_info.pSubpasses = &fsi_subpass; + fsi_render_pass_create_info.dependencyCount = uint32_t(rex::countof(fsi_subpass_dependencies)); + fsi_render_pass_create_info.pDependencies = fsi_subpass_dependencies; + if (dfn.vkCreateRenderPass(device, &fsi_render_pass_create_info, nullptr, &fsi_render_pass_) != + VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the fragment shader " + "interlock render backend render pass"); + Shutdown(); + return false; + } + + // Common framebuffer. + VkFramebufferCreateInfo fsi_framebuffer_create_info; + fsi_framebuffer_create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + fsi_framebuffer_create_info.pNext = nullptr; + fsi_framebuffer_create_info.flags = 0; + fsi_framebuffer_create_info.renderPass = fsi_render_pass_; + fsi_framebuffer_create_info.attachmentCount = 0; + fsi_framebuffer_create_info.pAttachments = nullptr; + fsi_framebuffer_create_info.width = + std::min(xenos::kTexture2DCubeMaxWidthHeight * draw_resolution_scale_x(), + device_properties.maxFramebufferWidth); + fsi_framebuffer_create_info.height = + std::min(xenos::kTexture2DCubeMaxWidthHeight * draw_resolution_scale_y(), + device_properties.maxFramebufferHeight); + fsi_framebuffer_create_info.layers = 1; + if (dfn.vkCreateFramebuffer(device, &fsi_framebuffer_create_info, nullptr, + &fsi_framebuffer_.framebuffer) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the fragment shader " + "interlock render backend framebuffer"); + Shutdown(); + return false; + } + fsi_framebuffer_.host_extent.width = fsi_framebuffer_create_info.width; + fsi_framebuffer_.host_extent.height = fsi_framebuffer_create_info.height; + } else { + assert_unhandled_case(path_); + Shutdown(); + return false; + } + + // Reset the last update structures, to keep the defaults consistent between + // paths regardless of whether the update for the path actually modifies them. + last_update_render_pass_key_ = RenderPassKey(); + last_update_render_pass_ = VK_NULL_HANDLE; + last_update_framebuffer_pitch_tiles_at_32bpp_ = 0; + std::memset(last_update_framebuffer_attachments_, 0, + sizeof(last_update_framebuffer_attachments_)); + last_update_framebuffer_ = VK_NULL_HANDLE; + + InitializeCommon(); + return true; +} + +void VulkanRenderTargetCache::Shutdown(bool from_destructor) { + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + ResetTraceDownload(); + + // Destroy all render targets before the descriptor set pool is destroyed - + // may happen if shutting down the VulkanRenderTargetCache by destroying it, + // so ShutdownCommon is called by the RenderTargetCache destructor, when it's + // already too late. + DestroyAllRenderTargets(true); + + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, + resolve_fsi_clear_64bpp_pipeline_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, + resolve_fsi_clear_32bpp_pipeline_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipelineLayout, device, + resolve_fsi_clear_pipeline_layout_); + + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyFramebuffer, device, + fsi_framebuffer_.framebuffer); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyRenderPass, device, fsi_render_pass_); + + for (const auto& dump_pipeline_pair : dump_pipelines_) { + // May be null to prevent recreation attempts. + if (dump_pipeline_pair.second != VK_NULL_HANDLE) { + dfn.vkDestroyPipeline(device, dump_pipeline_pair.second, nullptr); + } + } + dump_pipelines_.clear(); + for (const auto& direct_resolve_pipeline_pair : direct_resolve_pipelines_) { + bool aliased_resolve_copy_pipeline = false; + for (VkPipeline resolve_copy_pipeline : resolve_copy_pipelines_) { + if (direct_resolve_pipeline_pair.second == resolve_copy_pipeline) { + aliased_resolve_copy_pipeline = true; + break; + } + } + if (direct_resolve_pipeline_pair.second != VK_NULL_HANDLE && !aliased_resolve_copy_pipeline) { + dfn.vkDestroyPipeline(device, direct_resolve_pipeline_pair.second, nullptr); + } + } + direct_resolve_pipelines_.clear(); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipelineLayout, device, + direct_resolve_pipeline_layout_depth_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipelineLayout, device, + direct_resolve_pipeline_layout_color_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipelineLayout, device, + dump_pipeline_layout_depth_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipelineLayout, device, + dump_pipeline_layout_color_); + + for (const auto& transfer_pipeline_array_pair : transfer_pipelines_) { + for (VkPipeline transfer_pipeline : transfer_pipeline_array_pair.second) { + // May be null to prevent recreation attempts. + if (transfer_pipeline != VK_NULL_HANDLE) { + dfn.vkDestroyPipeline(device, transfer_pipeline, nullptr); + } + } + } + transfer_pipelines_.clear(); + for (const auto& transfer_shader_pair : transfer_shaders_) { + if (transfer_shader_pair.second != VK_NULL_HANDLE) { + dfn.vkDestroyShaderModule(device, transfer_shader_pair.second, nullptr); + } + } + transfer_shaders_.clear(); + for (size_t i = 0; i < size_t(TransferPipelineLayoutIndex::kCount); ++i) { + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipelineLayout, device, + transfer_pipeline_layouts_[i]); + } + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyShaderModule, device, + transfer_passthrough_vertex_shader_); + transfer_vertex_buffer_pool_.reset(); + edram_snapshot_restore_pool_.reset(); + + for (size_t i = 0; i < rex::countof(host_depth_store_pipelines_); ++i) { + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, + host_depth_store_pipelines_[i]); + } + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipelineLayout, device, + host_depth_store_pipeline_layout_); + + last_update_framebuffer_ = VK_NULL_HANDLE; + for (const auto& framebuffer_pair : framebuffers_) { + dfn.vkDestroyFramebuffer(device, framebuffer_pair.second.framebuffer, nullptr); + } + framebuffers_.clear(); + + last_update_render_pass_ = VK_NULL_HANDLE; + for (const auto& render_pass_pair : render_passes_) { + if (render_pass_pair.second != VK_NULL_HANDLE) { + dfn.vkDestroyRenderPass(device, render_pass_pair.second, nullptr); + } + } + render_passes_.clear(); + + for (VkPipeline& resolve_copy_pipeline : resolve_copy_pipelines_) { + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, resolve_copy_pipeline); + } + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyPipelineLayout, device, + resolve_copy_pipeline_layout_); + + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyDescriptorPool, device, + edram_storage_buffer_descriptor_pool_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyBuffer, device, edram_buffer_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkFreeMemory, device, edram_buffer_memory_); + + descriptor_set_pool_sampled_image_x2_.reset(); + descriptor_set_pool_sampled_image_.reset(); + + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyDescriptorSetLayout, device, + descriptor_set_layout_sampled_image_x2_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyDescriptorSetLayout, device, + descriptor_set_layout_sampled_image_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyDescriptorSetLayout, device, + descriptor_set_layout_storage_buffer_); + + if (!from_destructor) { + ShutdownCommon(); + } +} + +void VulkanRenderTargetCache::ClearCache() { + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + // Framebuffer objects must be destroyed because they reference views of + // attachment images, which may be removed by the common ClearCache. + last_update_framebuffer_ = VK_NULL_HANDLE; + for (const auto& framebuffer_pair : framebuffers_) { + dfn.vkDestroyFramebuffer(device, framebuffer_pair.second.framebuffer, nullptr); + } + framebuffers_.clear(); + + last_update_render_pass_ = VK_NULL_HANDLE; + for (const auto& render_pass_pair : render_passes_) { + dfn.vkDestroyRenderPass(device, render_pass_pair.second, nullptr); + } + render_passes_.clear(); + + RenderTargetCache::ClearCache(); +} + +void VulkanRenderTargetCache::CompletedSubmissionUpdated() { + if (edram_snapshot_restore_pool_) { + edram_snapshot_restore_pool_->Reclaim(command_processor_.GetCompletedSubmission()); + } + if (transfer_vertex_buffer_pool_) { + transfer_vertex_buffer_pool_->Reclaim(command_processor_.GetCompletedSubmission()); + } +} + +void VulkanRenderTargetCache::EndSubmission() { + if (edram_snapshot_restore_pool_) { + edram_snapshot_restore_pool_->FlushWrites(); + } + if (transfer_vertex_buffer_pool_) { + transfer_vertex_buffer_pool_->FlushWrites(); + } +} + +void VulkanRenderTargetCache::ResetTraceDownload() { + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyBuffer, device, + edram_snapshot_download_buffer_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkFreeMemory, device, + edram_snapshot_download_buffer_memory_); + edram_snapshot_download_buffer_memory_type_ = UINT32_MAX; + edram_snapshot_download_buffer_memory_size_ = 0; +} + +bool VulkanRenderTargetCache::InitializeTraceSubmitDownloads() { + ResetTraceDownload(); + + if (IsDrawResolutionScaled()) { + // No 1:1 mapping. + return false; + } + + if (!ui::vulkan::util::CreateDedicatedAllocationBuffer( + command_processor_.GetVulkanDevice(), xenos::kEdramSizeBytes, + VK_BUFFER_USAGE_TRANSFER_DST_BIT, ui::vulkan::util::MemoryPurpose::kReadback, + edram_snapshot_download_buffer_, edram_snapshot_download_buffer_memory_, + &edram_snapshot_download_buffer_memory_type_, + &edram_snapshot_download_buffer_memory_size_)) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create an EDRAM snapshot download " + "buffer"); + ResetTraceDownload(); + return false; + } + + if (GetPath() == Path::kHostRenderTargets) { + // Dump all host render targets to edram_buffer_. + if (!DumpRenderTargets(0, xenos::kEdramTileCount, 1, xenos::kEdramTileCount)) { + REXGPU_ERROR("VulkanRenderTargetCache: Failed to dump host render targets for trace"); + ResetTraceDownload(); + return false; + } + } + + UseEdramBuffer(EdramBufferUsage::kTransferRead); + command_processor_.SubmitBarriers(true); + DeferredCommandBuffer& command_buffer = command_processor_.deferred_command_buffer(); + VkBufferCopy edram_download_copy; + edram_download_copy.srcOffset = 0; + edram_download_copy.dstOffset = 0; + edram_download_copy.size = xenos::kEdramSizeBytes; + command_buffer.CmdVkCopyBuffer(edram_buffer_, edram_snapshot_download_buffer_, 1, + &edram_download_copy); + command_processor_.PushBufferMemoryBarrier( + edram_snapshot_download_buffer_, 0, VK_WHOLE_SIZE, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_HOST_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT); + return true; +} + +void VulkanRenderTargetCache::InitializeTraceCompleteDownloads() { + if (edram_snapshot_download_buffer_memory_ == VK_NULL_HANDLE) { + return; + } + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + void* edram_snapshot_download_mapping = nullptr; + if (dfn.vkMapMemory(device, edram_snapshot_download_buffer_memory_, 0, VK_WHOLE_SIZE, 0, + &edram_snapshot_download_mapping) == VK_SUCCESS) { + if (!(vulkan_device->memory_types().host_coherent & + (uint32_t(1) << edram_snapshot_download_buffer_memory_type_))) { + VkMappedMemoryRange edram_snapshot_download_memory_range = {}; + edram_snapshot_download_memory_range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + edram_snapshot_download_memory_range.memory = edram_snapshot_download_buffer_memory_; + edram_snapshot_download_memory_range.offset = 0; + edram_snapshot_download_memory_range.size = + std::min(rex::round_up(VkDeviceSize(xenos::kEdramSizeBytes), + vulkan_device->properties().nonCoherentAtomSize), + edram_snapshot_download_buffer_memory_size_); + dfn.vkInvalidateMappedMemoryRanges(device, 1, &edram_snapshot_download_memory_range); + } + + trace_writer_.WriteEdramSnapshot(edram_snapshot_download_mapping); + dfn.vkUnmapMemory(device, edram_snapshot_download_buffer_memory_); + } else { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to map the EDRAM snapshot download " + "buffer"); + } + + ResetTraceDownload(); +} + +void VulkanRenderTargetCache::RestoreEdramSnapshot(const void* snapshot) { + if (IsDrawResolutionScaled()) { + // No 1:1 mapping. + return; + } + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + if (!edram_snapshot_restore_pool_) { + edram_snapshot_restore_pool_ = std::make_unique( + vulkan_device, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, xenos::kEdramSizeBytes); + } + VkBuffer upload_buffer; + VkDeviceSize upload_buffer_offset; + uint8_t* upload_buffer_mapping = edram_snapshot_restore_pool_->Request( + command_processor_.GetCurrentSubmission(), xenos::kEdramSizeBytes, 1, upload_buffer, + upload_buffer_offset); + if (!upload_buffer_mapping) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to get a buffer for restoring an " + "EDRAM snapshot"); + return; + } + + DeferredCommandBuffer& command_buffer = command_processor_.deferred_command_buffer(); + + switch (GetPath()) { + case Path::kHostRenderTargets: { + // k_32_FLOAT because it's unambiguous. + VulkanRenderTarget* full_edram_render_target = + static_cast(PrepareFullEdram1280xRenderTargetForSnapshotRestoration( + xenos::ColorRenderTargetFormat::k_32_FLOAT)); + if (!full_edram_render_target) { + return; + } + assert_false(full_edram_render_target->key().is_depth); + assert_false(full_edram_render_target->key().Is64bpp()); + uint32_t pitch_tiles = full_edram_render_target->key().pitch_tiles_at_32bpp; + uint32_t tile_rows = xenos::kEdramTileCount / pitch_tiles; + assert_true(pitch_tiles * tile_rows == xenos::kEdramTileCount); + uint32_t row_pitch_samples = pitch_tiles * xenos::kEdramTileWidthSamples; + VkDeviceSize row_pitch_bytes = VkDeviceSize(row_pitch_samples) * sizeof(uint32_t); + const uint8_t* snapshot_sample_row = reinterpret_cast(snapshot); + for (uint32_t y_tile = 0; y_tile < tile_rows; ++y_tile) { + uint8_t* upload_buffer_tile_row_origin = + upload_buffer_mapping + row_pitch_bytes * xenos::kEdramTileHeightSamples * y_tile; + for (uint32_t x_tile = 0; x_tile < pitch_tiles; ++x_tile) { + uint8_t* upload_buffer_sample_row = + upload_buffer_tile_row_origin + + sizeof(uint32_t) * xenos::kEdramTileWidthSamples * x_tile; + for (uint32_t sample_row = 0; sample_row < xenos::kEdramTileHeightSamples; ++sample_row) { + std::memcpy(upload_buffer_sample_row, snapshot_sample_row, + sizeof(uint32_t) * xenos::kEdramTileWidthSamples); + snapshot_sample_row += sizeof(uint32_t) * xenos::kEdramTileWidthSamples; + upload_buffer_sample_row += row_pitch_bytes; + } + } + } + command_processor_.PushImageMemoryBarrier( + full_edram_render_target->image(), + ui::vulkan::util::InitializeSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT), + full_edram_render_target->current_stage_mask(), VK_PIPELINE_STAGE_TRANSFER_BIT, + full_edram_render_target->current_access_mask(), VK_ACCESS_TRANSFER_WRITE_BIT, + full_edram_render_target->current_layout(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + full_edram_render_target->SetUsage(VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + command_processor_.SubmitBarriers(true); + VkBufferImageCopy copy_region = {}; + copy_region.bufferOffset = upload_buffer_offset; + copy_region.bufferRowLength = row_pitch_samples; + copy_region.bufferImageHeight = xenos::kEdramTileHeightSamples * tile_rows; + copy_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + copy_region.imageSubresource.mipLevel = 0; + copy_region.imageSubresource.baseArrayLayer = 0; + copy_region.imageSubresource.layerCount = 1; + copy_region.imageOffset.x = 0; + copy_region.imageOffset.y = 0; + copy_region.imageOffset.z = 0; + copy_region.imageExtent.width = row_pitch_samples; + copy_region.imageExtent.height = xenos::kEdramTileHeightSamples * tile_rows; + copy_region.imageExtent.depth = 1; + command_buffer.CmdVkCopyBufferToImage(upload_buffer, full_edram_render_target->image(), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©_region); + } break; + + case Path::kPixelShaderInterlock: { + std::memcpy(upload_buffer_mapping, snapshot, xenos::kEdramSizeBytes); + UseEdramBuffer(EdramBufferUsage::kTransferWrite); + command_processor_.SubmitBarriers(true); + VkBufferCopy copy_region = {}; + copy_region.srcOffset = upload_buffer_offset; + copy_region.dstOffset = 0; + copy_region.size = xenos::kEdramSizeBytes; + command_buffer.CmdVkCopyBuffer(upload_buffer, edram_buffer_, 1, ©_region); + } break; + + default: + assert_unhandled_case(GetPath()); + } +} + +bool VulkanRenderTargetCache::Resolve(const memory::Memory& memory, + VulkanSharedMemory& shared_memory, + VulkanTextureCache& texture_cache, + uint32_t& written_address_out, uint32_t& written_length_out) { + written_address_out = 0; + written_length_out = 0; + + bool draw_resolution_scaled = IsDrawResolutionScaled(); + + draw_util::ResolveInfo resolve_info; + if (!draw_util::GetResolveInfo(register_file(), memory, trace_writer_, draw_resolution_scale_x(), + draw_resolution_scale_y(), IsFixedRG16TruncatedToMinus1To1(), + IsFixedRGBA16TruncatedToMinus1To1(), resolve_info)) { + return false; + } + + // Nothing to copy/clear. + if (!resolve_info.coordinate_info.width_div_8 || !resolve_info.height_div_8) { + return true; + } + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + DeferredCommandBuffer& command_buffer = command_processor_.deferred_command_buffer(); + + // Copying. + bool copied = false; + if (resolve_info.copy_dest_extent_length) { + draw_util::ResolveCopyShaderConstants copy_shader_constants; + uint32_t copy_group_count_x, copy_group_count_y; + draw_util::ResolveCopyShaderIndex copy_shader = + resolve_info.GetCopyShader(draw_resolution_scale_x(), draw_resolution_scale_y(), + copy_shader_constants, copy_group_count_x, copy_group_count_y); + assert_true(copy_group_count_x && copy_group_count_y); + if (copy_shader != draw_util::ResolveCopyShaderIndex::kUnknown) { + const draw_util::ResolveCopyShaderInfo& copy_shader_info = + draw_util::resolve_copy_shader_info[size_t(copy_shader)]; + bool direct_resolved = false; + if (GetPath() == Path::kHostRenderTargets) { + if (REXCVAR_GET(direct_host_resolve)) { + direct_resolved = + TryResolveCopyDirectly(resolve_info, copy_shader, draw_resolution_scaled); + if (direct_resolved) { + ++direct_resolve_success_count_; + } else { + ++direct_resolve_fallback_count_; + } + } + if (!direct_resolved) { + // Dump the current contents of the render targets owning the affected + // range to edram_buffer_. + uint32_t dump_base; + uint32_t dump_row_length_used; + uint32_t dump_rows; + uint32_t dump_pitch; + resolve_info.GetCopyEdramTileSpan(dump_base, dump_row_length_used, dump_rows, dump_pitch); + if (!DumpRenderTargets(dump_base, dump_row_length_used, dump_rows, dump_pitch)) { + REXGPU_ERROR("VulkanRenderTargetCache: Failed to dump host render targets for resolve"); + return false; + } + } + } + + uint32_t copy_dest_range_unscaled = resolve_info.copy_dest_extent_start - + resolve_info.copy_dest_base + + resolve_info.copy_dest_extent_length; + uint64_t copy_dest_base = resolve_info.copy_dest_base; + uint64_t copy_dest_range_length = copy_dest_range_unscaled; + uint64_t copy_dest_use_start = resolve_info.copy_dest_extent_start; + uint64_t copy_dest_use_length = resolve_info.copy_dest_extent_length; + if (draw_resolution_scaled) { + if (!texture_cache.GetScaledResolveRange( + resolve_info.copy_dest_base, copy_dest_range_unscaled, + copy_shader_info.dest_bpe_log2, copy_dest_base, copy_dest_range_length) || + !texture_cache.GetScaledResolveRange( + resolve_info.copy_dest_extent_start, resolve_info.copy_dest_extent_length, + copy_shader_info.dest_bpe_log2, copy_dest_use_start, copy_dest_use_length)) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to map scaled resolve " + "destination range (base={:08X}, length={:08X})", + resolve_info.copy_dest_base, copy_dest_range_unscaled); + return false; + } + } + + // Make sure there is memory to write to. + bool copy_dest_committed; + if (draw_resolution_scaled) { + copy_dest_committed = texture_cache.CommitScaledResolveRange( + resolve_info.copy_dest_base, copy_dest_range_unscaled, copy_shader_info.dest_bpe_log2); + } else { + copy_dest_committed = shared_memory.RequestRange(resolve_info.copy_dest_extent_start, + resolve_info.copy_dest_extent_length); + } + if (!copy_dest_committed) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to obtain the resolve destination " + "memory region"); + } else { + // TODO(Triang3l): Switching between descriptors if exceeding + // maxStorageBufferRange. + // TODO(Triang3l): Use a single 512 MB shared memory binding if + // possible. + VkDescriptorSet descriptor_set_dest = command_processor_.AllocateSingleTransientDescriptor( + VulkanCommandProcessor::SingleTransientDescriptorLayout ::kStorageBufferCompute); + if (descriptor_set_dest != VK_NULL_HANDLE) { + // Write the destination descriptor. + VkDescriptorBufferInfo write_descriptor_set_dest_buffer_info; + write_descriptor_set_dest_buffer_info.buffer = draw_resolution_scaled + ? texture_cache.scaled_resolve_buffer() + : shared_memory.buffer(); + write_descriptor_set_dest_buffer_info.offset = copy_dest_base; + write_descriptor_set_dest_buffer_info.range = copy_dest_range_length; + VkWriteDescriptorSet write_descriptor_set_dest; + write_descriptor_set_dest.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_descriptor_set_dest.pNext = nullptr; + write_descriptor_set_dest.dstSet = descriptor_set_dest; + write_descriptor_set_dest.dstBinding = 0; + write_descriptor_set_dest.dstArrayElement = 0; + write_descriptor_set_dest.descriptorCount = 1; + write_descriptor_set_dest.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + write_descriptor_set_dest.pImageInfo = nullptr; + write_descriptor_set_dest.pBufferInfo = &write_descriptor_set_dest_buffer_info; + write_descriptor_set_dest.pTexelBufferView = nullptr; + dfn.vkUpdateDescriptorSets(device, 1, &write_descriptor_set_dest, 0, nullptr); + + // Submit the resolve. + if (draw_resolution_scaled) { + texture_cache.UseScaledResolveBufferForWrite(copy_dest_use_start, copy_dest_use_length); + } else { + shared_memory.Use(VulkanSharedMemory::Usage::kComputeWrite, + std::pair(uint32_t(copy_dest_use_start), + uint32_t(copy_dest_use_length))); + } + UseEdramBuffer(EdramBufferUsage::kComputeRead); + command_processor_.BindExternalComputePipeline( + resolve_copy_pipelines_[size_t(copy_shader)]); + VkDescriptorSet descriptor_sets[kResolveCopyDescriptorSetCount] = {}; + descriptor_sets[kResolveCopyDescriptorSetEdram] = edram_storage_buffer_descriptor_set_; + descriptor_sets[kResolveCopyDescriptorSetDest] = descriptor_set_dest; + command_buffer.CmdVkBindDescriptorSets( + VK_PIPELINE_BIND_POINT_COMPUTE, resolve_copy_pipeline_layout_, 0, + uint32_t(rex::countof(descriptor_sets)), descriptor_sets, 0, nullptr); + if (draw_resolution_scaled) { + command_buffer.CmdVkPushConstants( + resolve_copy_pipeline_layout_, VK_SHADER_STAGE_COMPUTE_BIT, 0, + sizeof(copy_shader_constants.dest_relative), ©_shader_constants.dest_relative); + } else { + // TODO(Triang3l): Proper dest_base in case of one 512 MB shared + // memory binding, or multiple shared memory bindings in case of + // splitting due to maxStorageBufferRange overflow. + copy_shader_constants.dest_base -= + uint32_t(write_descriptor_set_dest_buffer_info.offset); + command_buffer.CmdVkPushConstants( + resolve_copy_pipeline_layout_, VK_SHADER_STAGE_COMPUTE_BIT, 0, + sizeof(copy_shader_constants), ©_shader_constants); + } + command_processor_.SubmitBarriers(true); + command_buffer.CmdVkDispatch(copy_group_count_x, copy_group_count_y, 1); + + // Invalidate textures and mark the range as scaled if needed. + texture_cache.MarkRangeAsResolved(resolve_info.copy_dest_extent_start, + resolve_info.copy_dest_extent_length); + written_address_out = resolve_info.copy_dest_extent_start; + written_length_out = resolve_info.copy_dest_extent_length; + copied = true; + } + } + } + } else { + copied = true; + } + + // Clearing. + bool cleared = false; + bool clear_depth = resolve_info.IsClearingDepth(); + bool clear_color = resolve_info.IsClearingColor(); + if (clear_depth || clear_color) { + switch (GetPath()) { + case Path::kHostRenderTargets: { + Transfer::Rectangle clear_rectangle; + RenderTarget* clear_render_targets[2]; + // If PrepareHostRenderTargetsResolveClear returns false, may be just an + // empty region (success) or an error - don't care. + if (PrepareHostRenderTargetsResolveClear(resolve_info, clear_rectangle, + clear_render_targets[0], clear_transfers_[0], + clear_render_targets[1], clear_transfers_[1])) { + uint64_t clear_values[2]; + clear_values[0] = resolve_info.rb_depth_clear; + clear_values[1] = + resolve_info.rb_color_clear | (uint64_t(resolve_info.rb_color_clear_lo) << 32); + PerformTransfersAndResolveClears(2, clear_render_targets, clear_transfers_, clear_values, + &clear_rectangle); + } + cleared = true; + } break; + case Path::kPixelShaderInterlock: { + UseEdramBuffer(EdramBufferUsage::kComputeWrite); + // Should be safe to only commit once (if was accessed as unordered or + // with fragment shader interlock previously - if there was nothing to + // copy, only to clear, for some reason, for instance), overlap of the + // depth and the color ranges is highly unlikely. + CommitEdramBufferShaderWrites(); + command_buffer.CmdVkBindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, + resolve_fsi_clear_pipeline_layout_, 0, 1, + &edram_storage_buffer_descriptor_set_, 0, nullptr); + std::pair clear_group_count = resolve_info.GetClearShaderGroupCount( + draw_resolution_scale_x(), draw_resolution_scale_y()); + assert_true(clear_group_count.first && clear_group_count.second); + if (clear_depth) { + command_processor_.BindExternalComputePipeline(resolve_fsi_clear_32bpp_pipeline_); + draw_util::ResolveClearShaderConstants depth_clear_constants; + resolve_info.GetDepthClearShaderConstants(depth_clear_constants); + command_buffer.CmdVkPushConstants(resolve_fsi_clear_pipeline_layout_, + VK_SHADER_STAGE_COMPUTE_BIT, 0, + sizeof(depth_clear_constants), &depth_clear_constants); + command_processor_.SubmitBarriers(true); + command_buffer.CmdVkDispatch(clear_group_count.first, clear_group_count.second, 1); + } + if (clear_color) { + command_processor_.BindExternalComputePipeline( + resolve_info.color_edram_info.format_is_64bpp ? resolve_fsi_clear_64bpp_pipeline_ + : resolve_fsi_clear_32bpp_pipeline_); + draw_util::ResolveClearShaderConstants color_clear_constants; + resolve_info.GetColorClearShaderConstants(color_clear_constants); + if (clear_depth) { + // Non-RT-specific constants have already been set. + command_buffer.CmdVkPushConstants( + resolve_fsi_clear_pipeline_layout_, VK_SHADER_STAGE_COMPUTE_BIT, + uint32_t(offsetof(draw_util::ResolveClearShaderConstants, rt_specific)), + sizeof(color_clear_constants.rt_specific), &color_clear_constants.rt_specific); + } else { + command_buffer.CmdVkPushConstants( + resolve_fsi_clear_pipeline_layout_, VK_SHADER_STAGE_COMPUTE_BIT, 0, + sizeof(color_clear_constants), &color_clear_constants); + } + command_processor_.SubmitBarriers(true); + command_buffer.CmdVkDispatch(clear_group_count.first, clear_group_count.second, 1); + } + MarkEdramBufferModified(); + cleared = true; + } break; + default: + assert_unhandled_case(GetPath()); + } + } else { + cleared = true; + } + + return copied && cleared; +} + +bool VulkanRenderTargetCache::Update(bool is_rasterization_done, + reg::RB_DEPTHCONTROL normalized_depth_control, + uint32_t normalized_color_mask, const Shader& vertex_shader) { + if (!RenderTargetCache::Update(is_rasterization_done, normalized_depth_control, + normalized_color_mask, vertex_shader)) { + return false; + } + + auto rb_surface_info = register_file().Get(); + + RenderPassKey render_pass_key; + // Needed even with the fragment shader interlock render backend for passing + // the sample count to the pipeline cache. + render_pass_key.msaa_samples = rb_surface_info.msaa_samples; + + switch (GetPath()) { + case Path::kHostRenderTargets: { + RenderTarget* const* depth_and_color_render_targets = + last_update_accumulated_render_targets(); + + PerformTransfersAndResolveClears(1 + xenos::kMaxColorRenderTargets, + depth_and_color_render_targets, last_update_transfers()); + + if (depth_and_color_render_targets[0]) { + render_pass_key.depth_and_color_used |= 1 << 0; + render_pass_key.depth_format = depth_and_color_render_targets[0]->key().GetDepthFormat(); + } + if (depth_and_color_render_targets[1]) { + render_pass_key.depth_and_color_used |= 1 << 1; + render_pass_key.color_0_view_format = + depth_and_color_render_targets[1]->key().GetColorFormat(); + } + if (depth_and_color_render_targets[2]) { + render_pass_key.depth_and_color_used |= 1 << 2; + render_pass_key.color_1_view_format = + depth_and_color_render_targets[2]->key().GetColorFormat(); + } + if (depth_and_color_render_targets[3]) { + render_pass_key.depth_and_color_used |= 1 << 3; + render_pass_key.color_2_view_format = + depth_and_color_render_targets[3]->key().GetColorFormat(); + } + if (depth_and_color_render_targets[4]) { + render_pass_key.depth_and_color_used |= 1 << 4; + render_pass_key.color_3_view_format = + depth_and_color_render_targets[4]->key().GetColorFormat(); + } + + const Framebuffer* framebuffer = last_update_framebuffer_; + VkRenderPass render_pass = last_update_render_pass_key_ == render_pass_key + ? last_update_render_pass_ + : VK_NULL_HANDLE; + if (render_pass == VK_NULL_HANDLE) { + render_pass = GetHostRenderTargetsRenderPass(render_pass_key); + if (render_pass == VK_NULL_HANDLE) { + return false; + } + // Framebuffer for a different render pass needed now. + framebuffer = nullptr; + } + + uint32_t pitch_tiles_at_32bpp = + ((rb_surface_info.surface_pitch + << uint32_t(rb_surface_info.msaa_samples >= xenos::MsaaSamples::k4X)) + + (xenos::kEdramTileWidthSamples - 1)) / + xenos::kEdramTileWidthSamples; + if (framebuffer) { + if (last_update_framebuffer_pitch_tiles_at_32bpp_ != pitch_tiles_at_32bpp || + std::memcmp(last_update_framebuffer_attachments_, depth_and_color_render_targets, + sizeof(last_update_framebuffer_attachments_))) { + framebuffer = nullptr; + } + } + if (!framebuffer) { + framebuffer = GetHostRenderTargetsFramebuffer(render_pass_key, pitch_tiles_at_32bpp, + depth_and_color_render_targets); + if (!framebuffer) { + return false; + } + } + + // Successful update - write the new configuration. + last_update_render_pass_key_ = render_pass_key; + last_update_render_pass_ = render_pass; + last_update_framebuffer_pitch_tiles_at_32bpp_ = pitch_tiles_at_32bpp; + std::memcpy(last_update_framebuffer_attachments_, depth_and_color_render_targets, + sizeof(last_update_framebuffer_attachments_)); + last_update_framebuffer_ = framebuffer; + + // Transition the used render targets. + for (uint32_t i = 0; i < 1 + xenos::kMaxColorRenderTargets; ++i) { + RenderTarget* rt = depth_and_color_render_targets[i]; + if (!rt) { + continue; + } + auto& vulkan_rt = *static_cast(rt); + VkPipelineStageFlags rt_dst_stage_mask; + VkAccessFlags rt_dst_access_mask; + VkImageLayout rt_new_layout; + VulkanRenderTarget::GetDrawUsage(i == 0, &rt_dst_stage_mask, &rt_dst_access_mask, + &rt_new_layout); + command_processor_.PushImageMemoryBarrier( + vulkan_rt.image(), + ui::vulkan::util::InitializeSubresourceRange( + i ? VK_IMAGE_ASPECT_COLOR_BIT + : (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)), + vulkan_rt.current_stage_mask(), rt_dst_stage_mask, vulkan_rt.current_access_mask(), + rt_dst_access_mask, vulkan_rt.current_layout(), rt_new_layout); + vulkan_rt.SetUsage(rt_dst_stage_mask, rt_dst_access_mask, rt_new_layout); + } + } break; + + case Path::kPixelShaderInterlock: { + // For FSI, only the barrier is needed - already scheduled if required. + // But the buffer will be used for FSI drawing now. + UseEdramBuffer(EdramBufferUsage::kFragmentReadWrite); + // Commit preceding unordered (but not FSI) writes like clears as they + // aren't synchronized with FSI accesses. + CommitEdramBufferShaderWrites(EdramBufferModificationStatus::kViaUnordered); + // TODO(Triang3l): Check if this draw call modifies color or depth / + // stencil, at least coarsely, to prevent useless barriers. + MarkEdramBufferModified(EdramBufferModificationStatus::kViaFragmentShaderInterlock); + last_update_render_pass_key_ = render_pass_key; + last_update_render_pass_ = fsi_render_pass_; + last_update_framebuffer_ = &fsi_framebuffer_; + } break; + + default: + assert_unhandled_case(GetPath()); + return false; + } + + return true; +} + +void VulkanRenderTargetCache::GetLastUpdateRenderingAttachments( + VkRenderingAttachmentInfo* color_attachments, uint32_t* color_attachment_count_out, + VkRenderingAttachmentInfo* depth_attachment, + VkRenderingAttachmentInfo* stencil_attachment) const { + RenderPassKey key = last_update_render_pass_key_; + RenderTarget* const* rts = last_update_accumulated_render_targets(); + + std::memset(depth_attachment, 0, sizeof(VkRenderingAttachmentInfo)); + std::memset(stencil_attachment, 0, sizeof(VkRenderingAttachmentInfo)); + + if ((key.depth_and_color_used & 0b1) && rts[0]) { + const auto* vulkan_rt = static_cast(rts[0]); + depth_attachment->sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + depth_attachment->pNext = nullptr; + depth_attachment->imageView = vulkan_rt->view_depth_stencil(); + depth_attachment->imageLayout = VulkanRenderTarget::kDepthDrawLayout; + depth_attachment->resolveMode = VK_RESOLVE_MODE_NONE; + depth_attachment->resolveImageView = VK_NULL_HANDLE; + depth_attachment->resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + depth_attachment->loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + depth_attachment->storeOp = VK_ATTACHMENT_STORE_OP_STORE; + depth_attachment->clearValue = {}; + *stencil_attachment = *depth_attachment; + } + + uint32_t color_attachment_count = 0; + for (uint32_t i = 0; i < xenos::kMaxColorRenderTargets; ++i) { + VkRenderingAttachmentInfo& color_attachment = color_attachments[i]; + std::memset(&color_attachment, 0, sizeof(VkRenderingAttachmentInfo)); + if ((key.depth_and_color_used & (1 << (1 + i))) && rts[1 + i]) { + const auto* vulkan_rt = static_cast(rts[1 + i]); + color_attachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + color_attachment.pNext = nullptr; + color_attachment.imageView = vulkan_rt->view_depth_color(); + color_attachment.imageLayout = VulkanRenderTarget::kColorDrawLayout; + color_attachment.resolveMode = VK_RESOLVE_MODE_NONE; + color_attachment.resolveImageView = VK_NULL_HANDLE; + color_attachment.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + color_attachment.clearValue = {}; + color_attachment_count = i + 1; + } + } + *color_attachment_count_out = color_attachment_count; +} + +VkRenderPass VulkanRenderTargetCache::GetHostRenderTargetsRenderPass(RenderPassKey key) { + assert_true(GetPath() == Path::kHostRenderTargets); + + auto it = render_passes_.find(key); + if (it != render_passes_.end()) { + return it->second; + } + + VkSampleCountFlagBits samples; + switch (key.msaa_samples) { + case xenos::MsaaSamples::k1X: + samples = VK_SAMPLE_COUNT_1_BIT; + break; + case xenos::MsaaSamples::k2X: + samples = IsMsaa2xSupported(key.depth_and_color_used != 0) ? VK_SAMPLE_COUNT_2_BIT + : VK_SAMPLE_COUNT_4_BIT; + break; + case xenos::MsaaSamples::k4X: + samples = VK_SAMPLE_COUNT_4_BIT; + break; + default: + return VK_NULL_HANDLE; + } + + VkAttachmentDescription attachments[1 + xenos::kMaxColorRenderTargets]; + if (key.depth_and_color_used & 0b1) { + VkAttachmentDescription& attachment = attachments[0]; + attachment.flags = 0; + attachment.format = GetDepthVulkanFormat(key.depth_format); + attachment.samples = samples; + attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; + attachment.initialLayout = VulkanRenderTarget::kDepthDrawLayout; + attachment.finalLayout = VulkanRenderTarget::kDepthDrawLayout; + } + VkAttachmentReference color_attachments[xenos::kMaxColorRenderTargets]; + xenos::ColorRenderTargetFormat color_formats[] = { + key.color_0_view_format, + key.color_1_view_format, + key.color_2_view_format, + key.color_3_view_format, + }; + for (uint32_t i = 0; i < xenos::kMaxColorRenderTargets; ++i) { + VkAttachmentReference& color_attachment = color_attachments[i]; + color_attachment.layout = VulkanRenderTarget::kColorDrawLayout; + uint32_t attachment_bit = uint32_t(1) << (1 + i); + if (!(key.depth_and_color_used & attachment_bit)) { + color_attachment.attachment = VK_ATTACHMENT_UNUSED; + continue; + } + uint32_t attachment_index = rex::bit_count(key.depth_and_color_used & (attachment_bit - 1)); + color_attachment.attachment = attachment_index; + VkAttachmentDescription& attachment = attachments[attachment_index]; + attachment.flags = 0; + xenos::ColorRenderTargetFormat color_format = color_formats[i]; + attachment.format = key.color_rts_use_transfer_formats + ? GetColorOwnershipTransferVulkanFormat(color_format, key.msaa_samples) + : GetColorVulkanFormat(color_format); + attachment.samples = samples; + attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachment.initialLayout = VulkanRenderTarget::kColorDrawLayout; + attachment.finalLayout = VulkanRenderTarget::kColorDrawLayout; + } + + VkAttachmentReference depth_stencil_attachment; + depth_stencil_attachment.attachment = (key.depth_and_color_used & 0b1) ? 0 : VK_ATTACHMENT_UNUSED; + depth_stencil_attachment.layout = VulkanRenderTarget::kDepthDrawLayout; + + VkSubpassDescription subpass; + subpass.flags = 0; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.inputAttachmentCount = 0; + subpass.pInputAttachments = nullptr; + subpass.colorAttachmentCount = 32 - rex::lzcnt(uint32_t(key.depth_and_color_used >> 1)); + subpass.pColorAttachments = color_attachments; + subpass.pResolveAttachments = nullptr; + subpass.pDepthStencilAttachment = + (key.depth_and_color_used & 0b1) ? &depth_stencil_attachment : nullptr; + subpass.preserveAttachmentCount = 0; + subpass.pPreserveAttachments = nullptr; + + VkPipelineStageFlags dependency_stage_mask = 0; + VkAccessFlags dependency_access_mask = 0; + if (key.depth_and_color_used & 0b1) { + dependency_stage_mask |= VulkanRenderTarget::kDepthDrawStageMask; + dependency_access_mask |= VulkanRenderTarget::kDepthDrawAccessMask; + } + if (key.depth_and_color_used >> 1) { + dependency_stage_mask |= VulkanRenderTarget::kColorDrawStageMask; + dependency_access_mask |= VulkanRenderTarget::kColorDrawAccessMask; + } + VkSubpassDependency subpass_dependencies[2]; + subpass_dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL; + subpass_dependencies[0].dstSubpass = 0; + subpass_dependencies[0].srcStageMask = dependency_stage_mask; + subpass_dependencies[0].dstStageMask = dependency_stage_mask; + subpass_dependencies[0].srcAccessMask = dependency_access_mask; + subpass_dependencies[0].dstAccessMask = dependency_access_mask; + subpass_dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; + subpass_dependencies[1].srcSubpass = 0; + subpass_dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL; + subpass_dependencies[1].srcStageMask = dependency_stage_mask; + subpass_dependencies[1].dstStageMask = dependency_stage_mask; + subpass_dependencies[1].srcAccessMask = dependency_access_mask; + subpass_dependencies[1].dstAccessMask = dependency_access_mask; + subpass_dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; + + VkRenderPassCreateInfo render_pass_create_info; + render_pass_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + render_pass_create_info.pNext = nullptr; + render_pass_create_info.flags = 0; + render_pass_create_info.attachmentCount = rex::bit_count(key.depth_and_color_used); + render_pass_create_info.pAttachments = attachments; + render_pass_create_info.subpassCount = 1; + render_pass_create_info.pSubpasses = &subpass; + render_pass_create_info.dependencyCount = + key.depth_and_color_used ? uint32_t(rex::countof(subpass_dependencies)) : 0; + render_pass_create_info.pDependencies = subpass_dependencies; + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + VkRenderPass render_pass; + if (dfn.vkCreateRenderPass(device, &render_pass_create_info, nullptr, &render_pass) != + VK_SUCCESS) { + REXGPU_ERROR("VulkanRenderTargetCache: Failed to create a render pass"); + render_passes_.emplace(key, VK_NULL_HANDLE); + return VK_NULL_HANDLE; + } + render_passes_.emplace(key, render_pass); + return render_pass; +} + +VkFormat VulkanRenderTargetCache::GetDepthVulkanFormat( + xenos::DepthRenderTargetFormat format) const { + if (format == xenos::DepthRenderTargetFormat::kD24S8 && depth_unorm24_vulkan_format_supported()) { + return VK_FORMAT_D24_UNORM_S8_UINT; + } + return VK_FORMAT_D32_SFLOAT_S8_UINT; +} + +bool VulkanRenderTargetCache::IsColor16FormatFloatLike( + xenos::ColorRenderTargetFormat format) const { + switch (format) { + case xenos::ColorRenderTargetFormat::k_16_16: + return color_rg16_draw_format_fallback_to_float_; + case xenos::ColorRenderTargetFormat::k_16_16_16_16: + return color_rgba16_draw_format_fallback_to_float_; + case xenos::ColorRenderTargetFormat::k_16_16_FLOAT: + case xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT: + return true; + default: + return false; + } +} + +VkFormat VulkanRenderTargetCache::GetColorVulkanFormat( + xenos::ColorRenderTargetFormat format) const { + switch (format) { + case xenos::ColorRenderTargetFormat::k_8_8_8_8: + return VK_FORMAT_R8G8B8A8_UNORM; + case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA: + return gamma_render_target_as_unorm16_ ? VK_FORMAT_R16G16B16A16_UNORM + : VK_FORMAT_R8G8B8A8_UNORM; + case xenos::ColorRenderTargetFormat::k_2_10_10_10: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: + return VK_FORMAT_A8B8G8R8_UNORM_PACK32; + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16: + return VK_FORMAT_R16G16B16A16_SFLOAT; + case xenos::ColorRenderTargetFormat::k_16_16: + return color_rg16_draw_format_fallback_to_float_ ? VK_FORMAT_R16G16_SFLOAT + : VK_FORMAT_R16G16_SNORM; + case xenos::ColorRenderTargetFormat::k_16_16_16_16: + return color_rgba16_draw_format_fallback_to_float_ ? VK_FORMAT_R16G16B16A16_SFLOAT + : VK_FORMAT_R16G16B16A16_SNORM; + case xenos::ColorRenderTargetFormat::k_16_16_FLOAT: + return VK_FORMAT_R16G16_SFLOAT; + case xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT: + return VK_FORMAT_R16G16B16A16_SFLOAT; + case xenos::ColorRenderTargetFormat::k_32_FLOAT: + return VK_FORMAT_R32_SFLOAT; + case xenos::ColorRenderTargetFormat::k_32_32_FLOAT: + return VK_FORMAT_R32G32_SFLOAT; + default: + assert_unhandled_case(format); + return VK_FORMAT_UNDEFINED; + } +} + +VkFormat VulkanRenderTargetCache::GetColorOwnershipTransferVulkanFormat( + xenos::ColorRenderTargetFormat format, xenos::MsaaSamples msaa_samples, + bool* is_integer_out) const { + if (is_integer_out) { + *is_integer_out = true; + } + VkSampleCountFlagBits transfer_sample_count = + VkSampleCountFlagBits(uint32_t(1) << uint32_t(msaa_samples)); + if (transfer_sample_count == VK_SAMPLE_COUNT_2_BIT && !msaa_2x_attachments_supported_) { + // 2x guest color render targets are allocated as 4x host render targets in + // this mode. + transfer_sample_count = VK_SAMPLE_COUNT_4_BIT; + } + const ui::vulkan::VulkanDevice::Properties& device_properties = + command_processor_.GetVulkanDevice()->properties(); + bool integer_transfer_sample_count_supported = + (device_properties.framebufferColorSampleCounts & transfer_sample_count) != 0 && + (device_properties.sampledImageIntegerSampleCounts & transfer_sample_count) != 0; + // Floating-point numbers have NaNs that need to be propagated without + // modifications to the bit representation, and SNORM has two representations + // of -1. + switch (format) { + case xenos::ColorRenderTargetFormat::k_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_FLOAT: + if (color_16bit_transfer_uint_formats_supported_ && integer_transfer_sample_count_supported) { + return VK_FORMAT_R16G16_UINT; + } + if (is_integer_out) { + *is_integer_out = false; + } + return GetColorVulkanFormat(format); + case xenos::ColorRenderTargetFormat::k_16_16_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT: + if (color_16bit_transfer_uint_formats_supported_ && integer_transfer_sample_count_supported) { + return VK_FORMAT_R16G16B16A16_UINT; + } + if (is_integer_out) { + *is_integer_out = false; + } + return GetColorVulkanFormat(format); + case xenos::ColorRenderTargetFormat::k_32_FLOAT: + if (color_32bit_transfer_uint_formats_supported_ && integer_transfer_sample_count_supported) { + return VK_FORMAT_R32_UINT; + } + if (is_integer_out) { + *is_integer_out = false; + } + return GetColorVulkanFormat(format); + case xenos::ColorRenderTargetFormat::k_32_32_FLOAT: + if (color_32bit_transfer_uint_formats_supported_ && integer_transfer_sample_count_supported) { + return VK_FORMAT_R32G32_UINT; + } + if (is_integer_out) { + *is_integer_out = false; + } + return GetColorVulkanFormat(format); + default: + if (is_integer_out) { + *is_integer_out = false; + } + return GetColorVulkanFormat(format); + } +} + +VulkanRenderTargetCache::VulkanRenderTarget::~VulkanRenderTarget() { + const ui::vulkan::VulkanDevice* const vulkan_device = + render_target_cache_.command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + ui::vulkan::SingleLayoutDescriptorSetPool& descriptor_set_pool = + key().is_depth ? *render_target_cache_.descriptor_set_pool_sampled_image_x2_ + : *render_target_cache_.descriptor_set_pool_sampled_image_; + descriptor_set_pool.Free(descriptor_set_index_transfer_source_); + if (view_color_transfer_separate_ != VK_NULL_HANDLE) { + dfn.vkDestroyImageView(device, view_color_transfer_separate_, nullptr); + } + if (view_srgb_ != VK_NULL_HANDLE) { + dfn.vkDestroyImageView(device, view_srgb_, nullptr); + } + if (view_stencil_ != VK_NULL_HANDLE) { + dfn.vkDestroyImageView(device, view_stencil_, nullptr); + } + if (view_depth_stencil_ != VK_NULL_HANDLE) { + dfn.vkDestroyImageView(device, view_depth_stencil_, nullptr); + } + dfn.vkDestroyImageView(device, view_depth_color_, nullptr); + dfn.vkDestroyImage(device, image_, nullptr); + dfn.vkFreeMemory(device, memory_, nullptr); +} + +uint32_t VulkanRenderTargetCache::GetMaxRenderTargetWidth() const { + const ui::vulkan::VulkanDevice::Properties& device_properties = + command_processor_.GetVulkanDevice()->properties(); + return std::min(device_properties.maxFramebufferWidth, device_properties.maxImageDimension2D); +} + +uint32_t VulkanRenderTargetCache::GetMaxRenderTargetHeight() const { + const ui::vulkan::VulkanDevice::Properties& device_properties = + command_processor_.GetVulkanDevice()->properties(); + return std::min(device_properties.maxFramebufferHeight, device_properties.maxImageDimension2D); +} + +RenderTargetCache::RenderTarget* VulkanRenderTargetCache::CreateRenderTarget(RenderTargetKey key) { + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + // Create the image. + + VkImageCreateInfo image_create_info; + image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + image_create_info.pNext = nullptr; + image_create_info.flags = 0; + image_create_info.imageType = VK_IMAGE_TYPE_2D; + image_create_info.extent.width = key.GetWidth() * draw_resolution_scale_x(); + image_create_info.extent.height = + GetRenderTargetHeight(key.pitch_tiles_at_32bpp, key.msaa_samples) * draw_resolution_scale_y(); + image_create_info.extent.depth = 1; + image_create_info.mipLevels = 1; + image_create_info.arrayLayers = 1; + if (key.msaa_samples == xenos::MsaaSamples::k2X && !msaa_2x_attachments_supported_) { + image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; + } else { + image_create_info.samples = VkSampleCountFlagBits(uint32_t(1) << uint32_t(key.msaa_samples)); + } + image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; + image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; + image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + image_create_info.queueFamilyIndexCount = 0; + image_create_info.pQueueFamilyIndices = nullptr; + image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + VkFormat transfer_format; + bool is_srgb_view_needed = false; + if (key.is_depth) { + image_create_info.format = GetDepthVulkanFormat(key.GetDepthFormat()); + transfer_format = image_create_info.format; + image_create_info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + } else { + xenos::ColorRenderTargetFormat color_format = key.GetColorFormat(); + image_create_info.format = GetColorVulkanFormat(color_format); + transfer_format = GetColorOwnershipTransferVulkanFormat(color_format, key.msaa_samples); + is_srgb_view_needed = false; + if (image_create_info.format != transfer_format || is_srgb_view_needed) { + image_create_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; + } + image_create_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + } + if (image_create_info.format == VK_FORMAT_UNDEFINED) { + REXGPU_ERROR("VulkanRenderTargetCache: Unknown {} render target format {}", + key.is_depth ? "depth" : "color", static_cast(key.resource_format)); + return nullptr; + } + VkImage image; + VkDeviceMemory memory; + if (!ui::vulkan::util::CreateDedicatedAllocationImage( + vulkan_device, image_create_info, ui::vulkan::util::MemoryPurpose::kDeviceLocal, image, + memory)) { + REXGPU_ERROR( + "VulkanRenderTarget: Failed to create a {}x{} {}xMSAA {} render target " + "image", + image_create_info.extent.width, image_create_info.extent.height, + uint32_t(1) << uint32_t(key.msaa_samples), key.GetFormatName()); + return nullptr; + } + + // Create the image views. + + VkImageViewCreateInfo view_create_info; + view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + view_create_info.pNext = nullptr; + view_create_info.flags = 0; + view_create_info.image = image; + view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; + view_create_info.format = image_create_info.format; + view_create_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; + view_create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; + view_create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; + view_create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; + view_create_info.subresourceRange = ui::vulkan::util::InitializeSubresourceRange( + key.is_depth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT); + VkImageView view_depth_color; + if (dfn.vkCreateImageView(device, &view_create_info, nullptr, &view_depth_color) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTarget: Failed to create a {} view for a {}x{} {}xMSAA {} " + "render target", + key.is_depth ? "depth" : "color", image_create_info.extent.width, + image_create_info.extent.height, uint32_t(1) << uint32_t(key.msaa_samples), + key.GetFormatName()); + dfn.vkDestroyImage(device, image, nullptr); + dfn.vkFreeMemory(device, memory, nullptr); + return nullptr; + } + VkImageView view_depth_stencil = VK_NULL_HANDLE; + VkImageView view_stencil = VK_NULL_HANDLE; + VkImageView view_srgb = VK_NULL_HANDLE; + VkImageView view_color_transfer_separate = VK_NULL_HANDLE; + if (key.is_depth) { + view_create_info.subresourceRange.aspectMask = + VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + if (dfn.vkCreateImageView(device, &view_create_info, nullptr, &view_depth_stencil) != + VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTarget: Failed to create a depth / stencil view for a " + "{}x{} {}xMSAA {} render target", + image_create_info.extent.width, image_create_info.extent.height, + uint32_t(1) << uint32_t(key.msaa_samples), + xenos::GetDepthRenderTargetFormatName(key.GetDepthFormat())); + dfn.vkDestroyImageView(device, view_depth_color, nullptr); + dfn.vkDestroyImage(device, image, nullptr); + dfn.vkFreeMemory(device, memory, nullptr); + return nullptr; + } + view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; + if (dfn.vkCreateImageView(device, &view_create_info, nullptr, &view_stencil) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTarget: Failed to create a stencil view for a {}x{} " + "{}xMSAA render target", + image_create_info.extent.width, image_create_info.extent.height, + uint32_t(1) << uint32_t(key.msaa_samples), + xenos::GetDepthRenderTargetFormatName(key.GetDepthFormat())); + dfn.vkDestroyImageView(device, view_depth_stencil, nullptr); + dfn.vkDestroyImageView(device, view_depth_color, nullptr); + dfn.vkDestroyImage(device, image, nullptr); + dfn.vkFreeMemory(device, memory, nullptr); + return nullptr; + } + } else { + if (is_srgb_view_needed) { + view_create_info.format = VK_FORMAT_R8G8B8A8_SRGB; + if (dfn.vkCreateImageView(device, &view_create_info, nullptr, &view_srgb) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTarget: Failed to create an sRGB view for a {}x{} " + "{}xMSAA render target", + image_create_info.extent.width, image_create_info.extent.height, + uint32_t(1) << uint32_t(key.msaa_samples), + xenos::GetColorRenderTargetFormatName(key.GetColorFormat())); + dfn.vkDestroyImageView(device, view_depth_color, nullptr); + dfn.vkDestroyImage(device, image, nullptr); + dfn.vkFreeMemory(device, memory, nullptr); + return nullptr; + } + } + if (transfer_format != image_create_info.format) { + view_create_info.format = transfer_format; + if (dfn.vkCreateImageView(device, &view_create_info, nullptr, + &view_color_transfer_separate) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTarget: Failed to create a transfer view for a {}x{} " + "{}xMSAA {} render target", + image_create_info.extent.width, image_create_info.extent.height, + uint32_t(1) << uint32_t(key.msaa_samples), key.GetFormatName()); + if (view_srgb != VK_NULL_HANDLE) { + dfn.vkDestroyImageView(device, view_srgb, nullptr); + } + dfn.vkDestroyImageView(device, view_depth_color, nullptr); + dfn.vkDestroyImage(device, image, nullptr); + dfn.vkFreeMemory(device, memory, nullptr); + return nullptr; + } + } + } + + ui::vulkan::SingleLayoutDescriptorSetPool& descriptor_set_pool = + key.is_depth ? *descriptor_set_pool_sampled_image_x2_ : *descriptor_set_pool_sampled_image_; + size_t descriptor_set_index_transfer_source = descriptor_set_pool.Allocate(); + if (descriptor_set_index_transfer_source == SIZE_MAX) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to allocate sampled image descriptors " + "for a {} render target", + key.is_depth ? "depth/stencil" : "color"); + if (view_color_transfer_separate != VK_NULL_HANDLE) { + dfn.vkDestroyImageView(device, view_color_transfer_separate, nullptr); + } + if (view_srgb != VK_NULL_HANDLE) { + dfn.vkDestroyImageView(device, view_srgb, nullptr); + } + dfn.vkDestroyImageView(device, view_depth_color, nullptr); + dfn.vkDestroyImage(device, image, nullptr); + dfn.vkFreeMemory(device, memory, nullptr); + return nullptr; + } + VkDescriptorSet descriptor_set_transfer_source = + descriptor_set_pool.Get(descriptor_set_index_transfer_source); + VkWriteDescriptorSet descriptor_set_write[2]; + VkDescriptorImageInfo descriptor_set_write_depth_color; + descriptor_set_write_depth_color.sampler = VK_NULL_HANDLE; + descriptor_set_write_depth_color.imageView = view_color_transfer_separate != VK_NULL_HANDLE + ? view_color_transfer_separate + : view_depth_color; + descriptor_set_write_depth_color.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + descriptor_set_write[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptor_set_write[0].pNext = nullptr; + descriptor_set_write[0].dstSet = descriptor_set_transfer_source; + descriptor_set_write[0].dstBinding = 0; + descriptor_set_write[0].dstArrayElement = 0; + descriptor_set_write[0].descriptorCount = 1; + descriptor_set_write[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + descriptor_set_write[0].pImageInfo = &descriptor_set_write_depth_color; + descriptor_set_write[0].pBufferInfo = nullptr; + descriptor_set_write[0].pTexelBufferView = nullptr; + VkDescriptorImageInfo descriptor_set_write_stencil; + if (key.is_depth) { + descriptor_set_write_stencil.sampler = VK_NULL_HANDLE; + descriptor_set_write_stencil.imageView = view_stencil; + descriptor_set_write_stencil.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + descriptor_set_write[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptor_set_write[1].pNext = nullptr; + descriptor_set_write[1].dstSet = descriptor_set_transfer_source; + descriptor_set_write[1].dstBinding = 1; + descriptor_set_write[1].dstArrayElement = 0; + descriptor_set_write[1].descriptorCount = 1; + descriptor_set_write[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + descriptor_set_write[1].pImageInfo = &descriptor_set_write_stencil; + descriptor_set_write[1].pBufferInfo = nullptr; + descriptor_set_write[1].pTexelBufferView = nullptr; + } + dfn.vkUpdateDescriptorSets(device, key.is_depth ? 2 : 1, descriptor_set_write, 0, nullptr); + + return new VulkanRenderTarget(key, *this, image, memory, view_depth_color, view_depth_stencil, + view_stencil, view_srgb, view_color_transfer_separate, + descriptor_set_index_transfer_source); +} + +bool VulkanRenderTargetCache::IsHostDepthEncodingDifferent( + xenos::DepthRenderTargetFormat format) const { + switch (format) { + case xenos::DepthRenderTargetFormat::kD24S8: + return !depth_unorm24_vulkan_format_supported(); + case xenos::DepthRenderTargetFormat::kD24FS8: + return !depth_float24_convert_in_pixel_shader_; + } + return false; +} + +bool VulkanRenderTargetCache::IsGammaFormatHostStorageSeparate() const { + return gamma_render_target_as_unorm16_; +} + +void VulkanRenderTargetCache::RequestPixelShaderInterlockBarrier() { + // Keep parity with D3D12 ROV interlock barrier requests by committing any + // pending EDRAM shader writes, not only FSI writes. + CommitEdramBufferShaderWrites(); +} + +void VulkanRenderTargetCache::GetEdramBufferUsageMasks(EdramBufferUsage usage, + VkPipelineStageFlags& stage_mask_out, + VkAccessFlags& access_mask_out) { + switch (usage) { + case EdramBufferUsage::kFragmentRead: + stage_mask_out = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + access_mask_out = VK_ACCESS_SHADER_READ_BIT; + break; + case EdramBufferUsage::kFragmentReadWrite: + stage_mask_out = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + access_mask_out = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + break; + case EdramBufferUsage::kComputeRead: + stage_mask_out = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + access_mask_out = VK_ACCESS_SHADER_READ_BIT; + break; + case EdramBufferUsage::kComputeWrite: + stage_mask_out = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + access_mask_out = VK_ACCESS_SHADER_WRITE_BIT; + break; + case EdramBufferUsage::kTransferRead: + stage_mask_out = VK_PIPELINE_STAGE_TRANSFER_BIT; + access_mask_out = VK_ACCESS_TRANSFER_READ_BIT; + break; + case EdramBufferUsage::kTransferWrite: + stage_mask_out = VK_PIPELINE_STAGE_TRANSFER_BIT; + access_mask_out = VK_ACCESS_TRANSFER_WRITE_BIT; + break; + default: + assert_unhandled_case(usage); + } +} + +void VulkanRenderTargetCache::UseEdramBuffer(EdramBufferUsage new_usage) { + if (edram_buffer_usage_ == new_usage) { + return; + } + VkPipelineStageFlags src_stage_mask, dst_stage_mask; + VkAccessFlags src_access_mask, dst_access_mask; + GetEdramBufferUsageMasks(edram_buffer_usage_, src_stage_mask, src_access_mask); + GetEdramBufferUsageMasks(new_usage, dst_stage_mask, dst_access_mask); + if (command_processor_.PushBufferMemoryBarrier(edram_buffer_, 0, VK_WHOLE_SIZE, src_stage_mask, + dst_stage_mask, src_access_mask, + dst_access_mask)) { + // Resetting edram_buffer_modification_status_ only if the barrier has been + // truly inserted. + edram_buffer_modification_status_ = EdramBufferModificationStatus::kUnmodified; + } + edram_buffer_usage_ = new_usage; +} + +void VulkanRenderTargetCache::MarkEdramBufferModified( + EdramBufferModificationStatus modification_status) { + assert_true(modification_status != EdramBufferModificationStatus::kUnmodified); + switch (edram_buffer_usage_) { + case EdramBufferUsage::kFragmentReadWrite: + // max because being modified via unordered access requires stricter + // synchronization than via fragment shader interlocks. + edram_buffer_modification_status_ = + std::max(edram_buffer_modification_status_, modification_status); + break; + case EdramBufferUsage::kComputeWrite: + assert_true(modification_status == EdramBufferModificationStatus::kViaUnordered); + modification_status = EdramBufferModificationStatus::kViaUnordered; + edram_buffer_modification_status_ = + std::max(edram_buffer_modification_status_, modification_status); + break; + default: + assert_always( + "While changing the usage of the EDRAM buffer before marking it as " + "modified is handled safely (but will cause spurious marking as " + "modified after the changes have been implicitly committed by the " + "usage switch), normally that shouldn't be done and is an " + "indication of architectural mistakes. Alternatively, this may " + "indicate that the usage switch has been forgotten before writing, " + "which is a clearly invalid situation."); + } +} + +void VulkanRenderTargetCache::CommitEdramBufferShaderWrites( + EdramBufferModificationStatus commit_status) { + assert_true(commit_status != EdramBufferModificationStatus::kUnmodified); + if (edram_buffer_modification_status_ < commit_status) { + return; + } + VkPipelineStageFlags stage_mask; + VkAccessFlags access_mask; + GetEdramBufferUsageMasks(edram_buffer_usage_, stage_mask, access_mask); + if (!(access_mask & VK_ACCESS_SHADER_WRITE_BIT)) { + // Keep behavior robust similarly to D3D12 when an unexpected state is + // encountered: avoid emitting an invalid barrier but still treat writes as + // committed for ownership tracking. + assert_always("EDRAM writes committed from a non-shader-write usage"); + edram_buffer_modification_status_ = EdramBufferModificationStatus::kUnmodified; + PixelShaderInterlockFullEdramBarrierPlaced(); + return; + } + command_processor_.PushBufferMemoryBarrier( + edram_buffer_, 0, VK_WHOLE_SIZE, stage_mask, stage_mask, access_mask, access_mask, + VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, false); + edram_buffer_modification_status_ = EdramBufferModificationStatus::kUnmodified; + PixelShaderInterlockFullEdramBarrierPlaced(); +} + +const VulkanRenderTargetCache::Framebuffer* +VulkanRenderTargetCache::GetHostRenderTargetsFramebuffer( + RenderPassKey render_pass_key, uint32_t pitch_tiles_at_32bpp, + const RenderTarget* const* depth_and_color_render_targets) { + FramebufferKey key; + key.render_pass_key = render_pass_key; + key.pitch_tiles_at_32bpp = pitch_tiles_at_32bpp; + if (render_pass_key.depth_and_color_used & (1 << 0)) { + key.depth_base_tiles = depth_and_color_render_targets[0]->key().base_tiles; + } + if (render_pass_key.depth_and_color_used & (1 << 1)) { + key.color_0_base_tiles = depth_and_color_render_targets[1]->key().base_tiles; + } + if (render_pass_key.depth_and_color_used & (1 << 2)) { + key.color_1_base_tiles = depth_and_color_render_targets[2]->key().base_tiles; + } + if (render_pass_key.depth_and_color_used & (1 << 3)) { + key.color_2_base_tiles = depth_and_color_render_targets[3]->key().base_tiles; + } + if (render_pass_key.depth_and_color_used & (1 << 4)) { + key.color_3_base_tiles = depth_and_color_render_targets[4]->key().base_tiles; + } + auto it = framebuffers_.find(key); + if (it != framebuffers_.end()) { + return &it->second; + } + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + const ui::vulkan::VulkanDevice::Properties& device_properties = vulkan_device->properties(); + + VkRenderPass render_pass = GetHostRenderTargetsRenderPass(render_pass_key); + if (render_pass == VK_NULL_HANDLE) { + return nullptr; + } + + VkImageView attachments[1 + xenos::kMaxColorRenderTargets]; + uint32_t attachment_count = 0; + uint32_t depth_and_color_rts_remaining = render_pass_key.depth_and_color_used; + uint32_t rt_index; + while (rex::bit_scan_forward(depth_and_color_rts_remaining, &rt_index)) { + depth_and_color_rts_remaining &= ~(uint32_t(1) << rt_index); + const auto& vulkan_rt = + *static_cast(depth_and_color_render_targets[rt_index]); + VkImageView attachment; + if (rt_index) { + attachment = render_pass_key.color_rts_use_transfer_formats ? vulkan_rt.view_color_transfer() + : vulkan_rt.view_depth_color(); + } else { + attachment = vulkan_rt.view_depth_stencil(); + } + attachments[attachment_count++] = attachment; + } + + VkFramebufferCreateInfo framebuffer_create_info; + framebuffer_create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + framebuffer_create_info.pNext = nullptr; + framebuffer_create_info.flags = 0; + framebuffer_create_info.renderPass = render_pass; + framebuffer_create_info.attachmentCount = attachment_count; + framebuffer_create_info.pAttachments = attachments; + VkExtent2D host_extent; + if (pitch_tiles_at_32bpp) { + host_extent.width = + RenderTargetKey::GetWidth(pitch_tiles_at_32bpp, render_pass_key.msaa_samples); + host_extent.height = GetRenderTargetHeight(pitch_tiles_at_32bpp, render_pass_key.msaa_samples); + } else { + assert_zero(render_pass_key.depth_and_color_used); + // Still needed for occlusion queries. + host_extent.width = xenos::kTexture2DCubeMaxWidthHeight; + host_extent.height = xenos::kTexture2DCubeMaxWidthHeight; + } + // Limiting to the device limit for the case of no attachments, for which + // there's no limit imposed by the sizes of the attachments that have been + // created successfully. + host_extent.width = std::min(host_extent.width * draw_resolution_scale_x(), + device_properties.maxFramebufferWidth); + host_extent.height = std::min(host_extent.height * draw_resolution_scale_y(), + device_properties.maxFramebufferHeight); + framebuffer_create_info.width = host_extent.width; + framebuffer_create_info.height = host_extent.height; + framebuffer_create_info.layers = 1; + VkFramebuffer framebuffer; + if (dfn.vkCreateFramebuffer(device, &framebuffer_create_info, nullptr, &framebuffer) != + VK_SUCCESS) { + return nullptr; + } + // Creates at a persistent location - safe to use pointers. + return &framebuffers_ + .emplace(std::piecewise_construct, std::forward_as_tuple(key), + std::forward_as_tuple(framebuffer, host_extent)) + .first->second; +} + +VkShaderModule VulkanRenderTargetCache::GetTransferShader(TransferShaderKey key) { + auto shader_it = transfer_shaders_.find(key); + if (shader_it != transfer_shaders_.end()) { + return shader_it->second; + } + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Properties& device_properties = vulkan_device->properties(); + + std::vector id_vector_temp; + std::vector uint_vector_temp; + + SpirvBuilder builder(spv::Spv_1_0, (SpirvShaderTranslator::kSpirvMagicToolId << 16) | 1, nullptr); + spv::Id ext_inst_glsl_std_450 = builder.import("GLSL.std.450"); + builder.addCapability(spv::CapabilityShader); + builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450); + builder.setSource(spv::SourceLanguageUnknown, 0); + + spv::Id type_void = builder.makeVoidType(); + spv::Id type_bool = builder.makeBoolType(); + spv::Id type_int = builder.makeIntType(32); + spv::Id type_int2 = builder.makeVectorType(type_int, 2); + spv::Id type_uint = builder.makeUintType(32); + spv::Id type_uint2 = builder.makeVectorType(type_uint, 2); + spv::Id type_uint4 = builder.makeVectorType(type_uint, 4); + spv::Id type_float = builder.makeFloatType(32); + spv::Id type_float2 = builder.makeVectorType(type_float, 2); + spv::Id type_float4 = builder.makeVectorType(type_float, 4); + + const TransferModeInfo& mode = kTransferModes[size_t(key.mode)]; + const TransferPipelineLayoutInfo& pipeline_layout_info = + kTransferPipelineLayoutInfos[size_t(mode.pipeline_layout)]; + + // If not dest_is_color, it's depth, or stencil bit - 40-sample columns are + // swapped as opposed to color source. + bool dest_is_color = (mode.output == TransferOutput::kColor); + xenos::ColorRenderTargetFormat dest_color_format = + xenos::ColorRenderTargetFormat(key.dest_resource_format); + xenos::DepthRenderTargetFormat dest_depth_format = + xenos::DepthRenderTargetFormat(key.dest_resource_format); + bool dest_is_64bpp = dest_is_color && xenos::IsColorRenderTargetFormat64bpp(dest_color_format); + + xenos::ColorRenderTargetFormat source_color_format = + xenos::ColorRenderTargetFormat(key.source_resource_format); + xenos::DepthRenderTargetFormat source_depth_format = + xenos::DepthRenderTargetFormat(key.source_resource_format); + // If not source_is_color, it's depth / stencil - 40-sample columns are + // swapped as opposed to color destination. + bool source_is_color = + (pipeline_layout_info.used_descriptor_sets & kTransferUsedDescriptorSetColorTextureBit) != 0; + bool source_is_64bpp; + uint32_t source_color_format_component_count; + uint32_t source_color_texture_component_mask; + bool source_color_is_uint; + spv::Id source_color_component_type; + if (source_is_color) { + assert_zero(pipeline_layout_info.used_descriptor_sets & + kTransferUsedDescriptorSetDepthStencilTexturesBit); + source_is_64bpp = xenos::IsColorRenderTargetFormat64bpp(source_color_format); + source_color_format_component_count = + xenos::GetColorRenderTargetFormatComponentCount(source_color_format); + if (mode.output == TransferOutput::kStencilBit) { + if (source_is_64bpp && !dest_is_64bpp) { + // Need one component, but choosing from the two 32bpp halves of the + // 64bpp sample. + source_color_texture_component_mask = + 0b1 | (0b1 << (source_color_format_component_count >> 1)); + } else { + // Red is at least 8 bits per component in all formats. + source_color_texture_component_mask = 0b1; + } + } else { + source_color_texture_component_mask = + (uint32_t(1) << source_color_format_component_count) - 1; + } + GetColorOwnershipTransferVulkanFormat(source_color_format, key.source_msaa_samples, + &source_color_is_uint); + source_color_component_type = source_color_is_uint ? type_uint : type_float; + } else { + source_is_64bpp = false; + source_color_format_component_count = 0; + source_color_texture_component_mask = 0; + source_color_is_uint = false; + source_color_component_type = spv::NoType; + } + + std::vector main_interface; + + // Outputs. + bool shader_uses_stencil_reference_output = + mode.output == TransferOutput::kDepth && + vulkan_device->extensions().ext_EXT_shader_stencil_export; + bool dest_color_is_uint = false; + uint32_t dest_color_component_count = 0; + spv::Id type_fragment_data_component = spv::NoResult; + spv::Id type_fragment_data = spv::NoResult; + spv::Id output_fragment_data = spv::NoResult; + spv::Id output_fragment_depth = spv::NoResult; + spv::Id output_fragment_stencil_ref = spv::NoResult; + switch (mode.output) { + case TransferOutput::kColor: + GetColorOwnershipTransferVulkanFormat(dest_color_format, key.dest_msaa_samples, + &dest_color_is_uint); + dest_color_component_count = + xenos::GetColorRenderTargetFormatComponentCount(dest_color_format); + type_fragment_data_component = dest_color_is_uint ? type_uint : type_float; + type_fragment_data = + dest_color_component_count > 1 + ? builder.makeVectorType(type_fragment_data_component, dest_color_component_count) + : type_fragment_data_component; + output_fragment_data = + builder.createVariable(spv::NoPrecision, spv::StorageClassOutput, type_fragment_data, + "xe_transfer_fragment_data"); + builder.addDecoration(output_fragment_data, spv::DecorationLocation, key.dest_color_rt_index); + main_interface.push_back(output_fragment_data); + break; + case TransferOutput::kDepth: + output_fragment_depth = builder.createVariable(spv::NoPrecision, spv::StorageClassOutput, + type_float, "gl_FragDepth"); + builder.addDecoration(output_fragment_depth, spv::DecorationBuiltIn, spv::BuiltInFragDepth); + main_interface.push_back(output_fragment_depth); + if (shader_uses_stencil_reference_output) { + builder.addExtension("SPV_EXT_shader_stencil_export"); + builder.addCapability(spv::CapabilityStencilExportEXT); + output_fragment_stencil_ref = builder.createVariable( + spv::NoPrecision, spv::StorageClassOutput, type_int, "gl_FragStencilRefARB"); + builder.addDecoration(output_fragment_stencil_ref, spv::DecorationBuiltIn, + spv::BuiltInFragStencilRefEXT); + main_interface.push_back(output_fragment_stencil_ref); + } + break; + default: + break; + } + + // Bindings. + // Generating SPIR-V 1.0, no need to add bindings to the entry point's + // interface until SPIR-V 1.4. + // Color source. + bool source_is_multisampled = key.source_msaa_samples != xenos::MsaaSamples::k1X; + spv::Id source_color_texture = spv::NoResult; + if (pipeline_layout_info.used_descriptor_sets & kTransferUsedDescriptorSetColorTextureBit) { + source_color_texture = builder.createVariable( + spv::NoPrecision, spv::StorageClassUniformConstant, + builder.makeImageType(source_color_component_type, spv::Dim2D, false, false, + source_is_multisampled, 1, spv::ImageFormatUnknown), + "xe_transfer_color"); + builder.addDecoration(source_color_texture, spv::DecorationDescriptorSet, + rex::bit_count(pipeline_layout_info.used_descriptor_sets & + (kTransferUsedDescriptorSetColorTextureBit - 1))); + builder.addDecoration(source_color_texture, spv::DecorationBinding, 0); + } + // Depth / stencil source. + spv::Id source_depth_texture = spv::NoResult; + spv::Id source_stencil_texture = spv::NoResult; + if (pipeline_layout_info.used_descriptor_sets & + kTransferUsedDescriptorSetDepthStencilTexturesBit) { + uint32_t source_depth_stencil_descriptor_set = + rex::bit_count(pipeline_layout_info.used_descriptor_sets & + (kTransferUsedDescriptorSetDepthStencilTexturesBit - 1)); + // Using `depth == false` in makeImageType because comparisons are not + // required, and other values of `depth` are causing issues in drivers. + // https://github.com/microsoft/DirectXShaderCompiler/issues/1107 + if (mode.output != TransferOutput::kStencilBit) { + source_depth_texture = builder.createVariable( + spv::NoPrecision, spv::StorageClassUniformConstant, + builder.makeImageType(type_float, spv::Dim2D, false, false, source_is_multisampled, 1, + spv::ImageFormatUnknown), + "xe_transfer_depth"); + builder.addDecoration(source_depth_texture, spv::DecorationDescriptorSet, + source_depth_stencil_descriptor_set); + builder.addDecoration(source_depth_texture, spv::DecorationBinding, 0); + } + if (mode.output != TransferOutput::kDepth || shader_uses_stencil_reference_output) { + source_stencil_texture = builder.createVariable( + spv::NoPrecision, spv::StorageClassUniformConstant, + builder.makeImageType(type_uint, spv::Dim2D, false, false, source_is_multisampled, 1, + spv::ImageFormatUnknown), + "xe_transfer_stencil"); + builder.addDecoration(source_stencil_texture, spv::DecorationDescriptorSet, + source_depth_stencil_descriptor_set); + builder.addDecoration(source_stencil_texture, spv::DecorationBinding, 1); + } + } + // Host depth source buffer. + spv::Id host_depth_source_buffer = spv::NoResult; + if (pipeline_layout_info.used_descriptor_sets & kTransferUsedDescriptorSetHostDepthBufferBit) { + id_vector_temp.clear(); + id_vector_temp.push_back(builder.makeRuntimeArray(type_uint)); + // Storage buffers have std430 packing, no padding to 4-component vectors. + builder.addDecoration(id_vector_temp.back(), spv::DecorationArrayStride, sizeof(uint32_t)); + spv::Id type_host_depth_source_buffer = + builder.makeStructType(id_vector_temp, "XeTransferHostDepthBuffer"); + builder.addMemberName(type_host_depth_source_buffer, 0, "host_depth"); + builder.addMemberDecoration(type_host_depth_source_buffer, 0, spv::DecorationNonWritable); + builder.addMemberDecoration(type_host_depth_source_buffer, 0, spv::DecorationOffset, 0); + // Block since SPIR-V 1.3, but since SPIR-V 1.0 is generated, it's + // BufferBlock. + builder.addDecoration(type_host_depth_source_buffer, spv::DecorationBufferBlock); + // StorageBuffer since SPIR-V 1.3, but since SPIR-V 1.0 is generated, it's + // Uniform. + host_depth_source_buffer = + builder.createVariable(spv::NoPrecision, spv::StorageClassUniform, + type_host_depth_source_buffer, "xe_transfer_host_depth_buffer"); + builder.addDecoration(host_depth_source_buffer, spv::DecorationDescriptorSet, + rex::bit_count(pipeline_layout_info.used_descriptor_sets & + (kTransferUsedDescriptorSetHostDepthBufferBit - 1))); + builder.addDecoration(host_depth_source_buffer, spv::DecorationBinding, 0); + } + // Host depth source texture (the depth / stencil descriptor set is reused, + // but stencil is not needed). + spv::Id host_depth_source_texture = spv::NoResult; + if (pipeline_layout_info.used_descriptor_sets & + kTransferUsedDescriptorSetHostDepthStencilTexturesBit) { + host_depth_source_texture = builder.createVariable( + spv::NoPrecision, spv::StorageClassUniformConstant, + builder.makeImageType(type_float, spv::Dim2D, false, false, + key.host_depth_source_msaa_samples != xenos::MsaaSamples::k1X, 1, + spv::ImageFormatUnknown), + "xe_transfer_host_depth"); + builder.addDecoration( + host_depth_source_texture, spv::DecorationDescriptorSet, + rex::bit_count(pipeline_layout_info.used_descriptor_sets & + (kTransferUsedDescriptorSetHostDepthStencilTexturesBit - 1))); + builder.addDecoration(host_depth_source_texture, spv::DecorationBinding, 0); + } + // Push constants. + id_vector_temp.clear(); + uint32_t push_constants_member_host_depth_address = UINT32_MAX; + if (pipeline_layout_info.used_push_constant_dwords & + kTransferUsedPushConstantDwordHostDepthAddressBit) { + push_constants_member_host_depth_address = uint32_t(id_vector_temp.size()); + id_vector_temp.push_back(type_uint); + } + uint32_t push_constants_member_address = UINT32_MAX; + if (pipeline_layout_info.used_push_constant_dwords & kTransferUsedPushConstantDwordAddressBit) { + push_constants_member_address = uint32_t(id_vector_temp.size()); + id_vector_temp.push_back(type_uint); + } + uint32_t push_constants_member_stencil_mask = UINT32_MAX; + if (pipeline_layout_info.used_push_constant_dwords & + kTransferUsedPushConstantDwordStencilMaskBit) { + push_constants_member_stencil_mask = uint32_t(id_vector_temp.size()); + id_vector_temp.push_back(type_uint); + } + spv::Id push_constants = spv::NoResult; + if (!id_vector_temp.empty()) { + spv::Id type_push_constants = builder.makeStructType(id_vector_temp, "XeTransferPushConstants"); + if (pipeline_layout_info.used_push_constant_dwords & + kTransferUsedPushConstantDwordHostDepthAddressBit) { + assert_true(push_constants_member_host_depth_address != UINT32_MAX); + builder.addMemberName(type_push_constants, push_constants_member_host_depth_address, + "host_depth_address"); + builder.addMemberDecoration( + type_push_constants, push_constants_member_host_depth_address, spv::DecorationOffset, + sizeof(uint32_t) * + rex::bit_count(pipeline_layout_info.used_push_constant_dwords & + (kTransferUsedPushConstantDwordHostDepthAddressBit - 1))); + } + if (pipeline_layout_info.used_push_constant_dwords & kTransferUsedPushConstantDwordAddressBit) { + assert_true(push_constants_member_address != UINT32_MAX); + builder.addMemberName(type_push_constants, push_constants_member_address, "address"); + builder.addMemberDecoration( + type_push_constants, push_constants_member_address, spv::DecorationOffset, + sizeof(uint32_t) * rex::bit_count(pipeline_layout_info.used_push_constant_dwords & + (kTransferUsedPushConstantDwordAddressBit - 1))); + } + if (pipeline_layout_info.used_push_constant_dwords & + kTransferUsedPushConstantDwordStencilMaskBit) { + assert_true(push_constants_member_stencil_mask != UINT32_MAX); + builder.addMemberName(type_push_constants, push_constants_member_stencil_mask, + "stencil_mask"); + builder.addMemberDecoration( + type_push_constants, push_constants_member_stencil_mask, spv::DecorationOffset, + sizeof(uint32_t) * rex::bit_count(pipeline_layout_info.used_push_constant_dwords & + (kTransferUsedPushConstantDwordStencilMaskBit - 1))); + } + builder.addDecoration(type_push_constants, spv::DecorationBlock); + push_constants = builder.createVariable(spv::NoPrecision, spv::StorageClassPushConstant, + type_push_constants, "xe_transfer_push_constants"); + } + + // Coordinate inputs. + spv::Id input_fragment_coord = + builder.createVariable(spv::NoPrecision, spv::StorageClassInput, type_float4, "gl_FragCoord"); + builder.addDecoration(input_fragment_coord, spv::DecorationBuiltIn, spv::BuiltInFragCoord); + main_interface.push_back(input_fragment_coord); + spv::Id input_sample_id = spv::NoResult; + spv::Id spec_const_sample_id = spv::NoResult; + if (key.dest_msaa_samples != xenos::MsaaSamples::k1X) { + if (device_properties.sampleRateShading) { + // One draw for all samples. + builder.addCapability(spv::CapabilitySampleRateShading); + input_sample_id = + builder.createVariable(spv::NoPrecision, spv::StorageClassInput, type_int, "gl_SampleID"); + builder.addDecoration(input_sample_id, spv::DecorationFlat); + builder.addDecoration(input_sample_id, spv::DecorationBuiltIn, spv::BuiltInSampleId); + main_interface.push_back(input_sample_id); + } else { + // One sample per draw, with different sample masks. + spec_const_sample_id = builder.makeUintConstant(0, true); + builder.addName(spec_const_sample_id, "xe_transfer_sample_id"); + builder.addDecoration(spec_const_sample_id, spv::DecorationSpecId, 0); + } + } + + // Begin the main function. + std::vector main_param_types; + std::vector> main_precisions; + spv::Block* main_entry; + spv::Function* main_function = builder.makeFunctionEntry( + spv::NoPrecision, type_void, "main", main_param_types, main_precisions, &main_entry); + + // Working with unsigned numbers for simplicity now, bitcasting to signed will + // be done at texture fetch. + + uint32_t tile_width_samples = xenos::kEdramTileWidthSamples * draw_resolution_scale_x(); + uint32_t tile_height_samples = xenos::kEdramTileHeightSamples * draw_resolution_scale_y(); + + // Split the destination pixel index into 32bpp tile and 32bpp-tile-relative + // pixel index. + // Note that division by non-power-of-two constants will include a 4-cycle + // 32*32 multiplication on AMD, even though so many bits are not needed for + // the pixel position - however, if an OpUnreachable path is inserted for the + // case when the position has upper bits set, for some reason, the code for it + // is not eliminated when compiling the shader for AMD via RenderDoc on + // Windows, as of June 2022. + uint_vector_temp.clear(); + uint_vector_temp.push_back(0); + uint_vector_temp.push_back(1); + spv::Id dest_pixel_coord = builder.createUnaryOp( + spv::OpConvertFToU, type_uint2, + builder.createRvalueSwizzle(spv::NoPrecision, type_float2, + builder.createLoad(input_fragment_coord, spv::NoPrecision), + uint_vector_temp)); + spv::Id dest_pixel_x = builder.createCompositeExtract(dest_pixel_coord, type_uint, 0); + spv::Id const_dest_tile_width_pixels = builder.makeUintConstant( + tile_width_samples >> + (uint32_t(dest_is_64bpp) + uint32_t(key.dest_msaa_samples >= xenos::MsaaSamples::k4X))); + spv::Id dest_tile_index_x = + builder.createBinOp(spv::OpUDiv, type_uint, dest_pixel_x, const_dest_tile_width_pixels); + spv::Id dest_tile_pixel_x = + builder.createBinOp(spv::OpUMod, type_uint, dest_pixel_x, const_dest_tile_width_pixels); + spv::Id dest_pixel_y = builder.createCompositeExtract(dest_pixel_coord, type_uint, 1); + spv::Id const_dest_tile_height_pixels = builder.makeUintConstant( + tile_height_samples >> uint32_t(key.dest_msaa_samples >= xenos::MsaaSamples::k2X)); + spv::Id dest_tile_index_y = + builder.createBinOp(spv::OpUDiv, type_uint, dest_pixel_y, const_dest_tile_height_pixels); + spv::Id dest_tile_pixel_y = + builder.createBinOp(spv::OpUMod, type_uint, dest_pixel_y, const_dest_tile_height_pixels); + + assert_true(push_constants_member_address != UINT32_MAX); + id_vector_temp.clear(); + id_vector_temp.push_back(builder.makeIntConstant(int32_t(push_constants_member_address))); + spv::Id address_constant = builder.createLoad( + builder.createAccessChain(spv::StorageClassPushConstant, push_constants, id_vector_temp), + spv::NoPrecision); + + // Calculate the 32bpp tile index from its X and Y parts. + spv::Id dest_tile_index = builder.createBinOp( + spv::OpIAdd, type_uint, + builder.createBinOp( + spv::OpIMul, type_uint, + builder.createTriOp(spv::OpBitFieldUExtract, type_uint, address_constant, + builder.makeUintConstant(0), + builder.makeUintConstant(xenos::kEdramPitchTilesBits)), + dest_tile_index_y), + dest_tile_index_x); + + // Load the destination sample index. + spv::Id dest_sample_id = spv::NoResult; + if (key.dest_msaa_samples != xenos::MsaaSamples::k1X) { + if (device_properties.sampleRateShading) { + assert_true(input_sample_id != spv::NoResult); + dest_sample_id = builder.createUnaryOp(spv::OpBitcast, type_uint, + builder.createLoad(input_sample_id, spv::NoPrecision)); + } else { + assert_true(spec_const_sample_id != spv::NoResult); + // Already uint. + dest_sample_id = spec_const_sample_id; + } + } + + // Transform the destination framebuffer pixel and sample coordinates into the + // source texture pixel and sample coordinates. + + // First sample bit at 4x with Vulkan standard locations - horizontal sample. + // Second sample bit at 4x with Vulkan standard locations - vertical sample. + // At 2x: + // - Native 2x: top is 1 in Vulkan, bottom is 0. + // - 2x as 4x: top is 0, bottom is 3. + + spv::Id source_sample_id = dest_sample_id; + spv::Id source_tile_pixel_x = dest_tile_pixel_x; + spv::Id source_tile_pixel_y = dest_tile_pixel_y; + spv::Id source_color_half = spv::NoResult; + if (!source_is_64bpp && dest_is_64bpp) { + // 32bpp -> 64bpp, need two samples of the source. + if (key.source_msaa_samples >= xenos::MsaaSamples::k4X) { + // 32bpp -> 64bpp, 4x ->. + // Source has 32bpp halves in two adjacent samples. + if (key.dest_msaa_samples >= xenos::MsaaSamples::k4X) { + // 32bpp -> 64bpp, 4x -> 4x. + // 1 destination horizontal sample = 2 source horizontal samples. + // D p0,0 s0,0 = S p0,0 s0,0 | S p0,0 s1,0 + // D p0,0 s1,0 = S p1,0 s0,0 | S p1,0 s1,0 + // D p0,0 s0,1 = S p0,0 s0,1 | S p0,0 s1,1 + // D p0,0 s1,1 = S p1,0 s0,1 | S p1,0 s1,1 + // Thus destination horizontal sample -> source horizontal pixel, + // vertical samples are 1:1. + source_sample_id = builder.createBinOp(spv::OpBitwiseAnd, type_uint, dest_sample_id, + builder.makeUintConstant(1 << 1)); + source_tile_pixel_x = builder.createQuadOp(spv::OpBitFieldInsert, type_uint, dest_sample_id, + dest_tile_pixel_x, builder.makeUintConstant(1), + builder.makeUintConstant(31)); + } else if (key.dest_msaa_samples == xenos::MsaaSamples::k2X) { + // 32bpp -> 64bpp, 4x -> 2x. + // 1 destination horizontal pixel = 2 source horizontal samples. + // D p0,0 s0 = S p0,0 s0,0 | S p0,0 s1,0 + // D p0,0 s1 = S p0,0 s0,1 | S p0,0 s1,1 + // D p1,0 s0 = S p1,0 s0,0 | S p1,0 s1,0 + // D p1,0 s1 = S p1,0 s0,1 | S p1,0 s1,1 + // Pixel index can be reused. Sample 1 (for native 2x) or 0 (for 2x as + // 4x) should become samples 01, sample 0 or 3 should become samples 23. + if (msaa_2x_attachments_supported_) { + source_sample_id = + builder.createBinOp(spv::OpShiftLeftLogical, type_uint, + builder.createBinOp(spv::OpBitwiseXor, type_uint, dest_sample_id, + builder.makeUintConstant(1)), + builder.makeUintConstant(1)); + } else { + source_sample_id = builder.createBinOp(spv::OpBitwiseAnd, type_uint, dest_sample_id, + builder.makeUintConstant(1 << 1)); + } + } else { + // 32bpp -> 64bpp, 4x -> 1x. + // 1 destination horizontal pixel = 2 source horizontal samples. + // D p0,0 = S p0,0 s0,0 | S p0,0 s1,0 + // D p0,1 = S p0,0 s0,1 | S p0,0 s1,1 + // Horizontal pixel index can be reused. Vertical pixel 1 should + // become sample 2. + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, builder.makeUintConstant(0), dest_tile_pixel_y, + builder.makeUintConstant(1), builder.makeUintConstant(1)); + source_tile_pixel_y = builder.createBinOp(spv::OpShiftRightLogical, type_uint, + dest_tile_pixel_y, builder.makeUintConstant(1)); + } + } else { + // 32bpp -> 64bpp, 1x/2x ->. + // Source has 32bpp halves in two adjacent pixels. + if (key.dest_msaa_samples >= xenos::MsaaSamples::k4X) { + // 32bpp -> 64bpp, 1x/2x -> 4x. + // The X part. + // 1 destination horizontal sample = 2 source horizontal pixels. + source_tile_pixel_x = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createBinOp(spv::OpShiftLeftLogical, type_uint, dest_tile_pixel_x, + builder.makeUintConstant(2)), + dest_sample_id, builder.makeUintConstant(1), builder.makeUintConstant(1)); + // Y is handled by common code. + } else { + // 32bpp -> 64bpp, 1x/2x -> 1x/2x. + // The X part. + // 1 destination horizontal pixel = 2 source horizontal pixels. + source_tile_pixel_x = builder.createBinOp(spv::OpShiftLeftLogical, type_uint, + dest_tile_pixel_x, builder.makeUintConstant(1)); + // Y is handled by common code. + } + } + } else if (source_is_64bpp && !dest_is_64bpp) { + // 64bpp -> 32bpp, also the half to load. + if (key.dest_msaa_samples >= xenos::MsaaSamples::k4X) { + // 64bpp -> 32bpp, -> 4x. + // The needed half is in the destination horizontal sample index. + if (key.source_msaa_samples >= xenos::MsaaSamples::k4X) { + // 64bpp -> 32bpp, 4x -> 4x. + // D p0,0 s0,0 = S s0,0 low + // D p0,0 s1,0 = S s0,0 high + // D p1,0 s0,0 = S s1,0 low + // D p1,0 s1,0 = S s1,0 high + // Vertical pixel and sample (second bit) addressing is the same. + // However, 1 horizontal destination pixel = 1 horizontal source sample. + source_sample_id = builder.createQuadOp(spv::OpBitFieldInsert, type_uint, dest_sample_id, + dest_tile_pixel_x, builder.makeUintConstant(0), + builder.makeUintConstant(1)); + // 2 destination horizontal samples = 1 source horizontal sample, thus + // 2 destination horizontal pixels = 1 source horizontal pixel. + source_tile_pixel_x = builder.createBinOp(spv::OpShiftRightLogical, type_uint, + dest_tile_pixel_x, builder.makeUintConstant(1)); + } else { + // 64bpp -> 32bpp, 1x/2x -> 4x. + // 2 destination horizontal samples = 1 source horizontal pixel, thus + // 1 destination horizontal pixel = 1 source horizontal pixel. Can reuse + // horizontal pixel index. + // Y is handled by common code. + } + // Half from the destination horizontal sample index. + source_color_half = builder.createBinOp(spv::OpBitwiseAnd, type_uint, dest_sample_id, + builder.makeUintConstant(1)); + } else { + // 64bpp -> 32bpp, -> 1x/2x. + // The needed half is in the destination horizontal pixel index. + if (key.source_msaa_samples >= xenos::MsaaSamples::k4X) { + // 64bpp -> 32bpp, 4x -> 1x/2x. + // (Destination horizontal pixel >> 1) & 1 = source horizontal sample + // (first bit). + source_sample_id = + builder.createTriOp(spv::OpBitFieldUExtract, type_uint, dest_tile_pixel_x, + builder.makeUintConstant(1), builder.makeUintConstant(1)); + if (key.dest_msaa_samples == xenos::MsaaSamples::k2X) { + // 64bpp -> 32bpp, 4x -> 2x. + // Destination vertical samples (1/0 in the first bit for native 2x or + // 0/1 in the second bit for 2x as 4x) = source vertical samples + // (second bit). + if (msaa_2x_attachments_supported_) { + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, source_sample_id, + builder.createBinOp(spv::OpBitwiseXor, type_uint, dest_sample_id, + builder.makeUintConstant(1)), + builder.makeUintConstant(1), builder.makeUintConstant(1)); + } else { + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, dest_sample_id, source_sample_id, + builder.makeUintConstant(0), builder.makeUintConstant(1)); + } + } else { + // 64bpp -> 32bpp, 4x -> 1x. + // 1 destination vertical pixel = 1 source vertical sample. + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, source_sample_id, source_tile_pixel_y, + builder.makeUintConstant(1), builder.makeUintConstant(1)); + source_tile_pixel_y = builder.createBinOp(spv::OpShiftRightLogical, type_uint, + dest_tile_pixel_y, builder.makeUintConstant(1)); + } + // 2 destination horizontal pixels = 1 source horizontal sample. + // 4 destination horizontal pixels = 1 source horizontal pixel. + source_tile_pixel_x = builder.createBinOp(spv::OpShiftRightLogical, type_uint, + dest_tile_pixel_x, builder.makeUintConstant(2)); + } else { + // 64bpp -> 32bpp, 1x/2x -> 1x/2x. + // The X part. + // 2 destination horizontal pixels = 1 destination source pixel. + source_tile_pixel_x = builder.createBinOp(spv::OpShiftRightLogical, type_uint, + dest_tile_pixel_x, builder.makeUintConstant(1)); + // Y is handled by common code. + } + // Half from the destination horizontal pixel index. + source_color_half = builder.createBinOp(spv::OpBitwiseAnd, type_uint, dest_tile_pixel_x, + builder.makeUintConstant(1)); + } + assert_true(source_color_half != spv::NoResult); + } else { + // Same bit count. + if (key.source_msaa_samples != key.dest_msaa_samples) { + if (key.source_msaa_samples >= xenos::MsaaSamples::k4X) { + // Same BPP, 4x -> 1x/2x. + if (key.dest_msaa_samples == xenos::MsaaSamples::k2X) { + // Same BPP, 4x -> 2x. + // Horizontal pixels to samples. Vertical sample (1/0 in the first bit + // for native 2x or 0/1 in the second bit for 2x as 4x) to second + // sample bit. + if (msaa_2x_attachments_supported_) { + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, dest_tile_pixel_x, + builder.createBinOp(spv::OpBitwiseXor, type_uint, dest_sample_id, + builder.makeUintConstant(1)), + builder.makeUintConstant(1), builder.makeUintConstant(31)); + } else { + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, dest_sample_id, dest_tile_pixel_x, + builder.makeUintConstant(0), builder.makeUintConstant(1)); + } + source_tile_pixel_x = builder.createBinOp(spv::OpShiftRightLogical, type_uint, + dest_tile_pixel_x, builder.makeUintConstant(1)); + } else { + // Same BPP, 4x -> 1x. + // Pixels to samples. + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createBinOp(spv::OpBitwiseAnd, type_uint, dest_tile_pixel_x, + builder.makeUintConstant(1)), + dest_tile_pixel_y, builder.makeUintConstant(1), builder.makeUintConstant(1)); + source_tile_pixel_x = builder.createBinOp(spv::OpShiftRightLogical, type_uint, + dest_tile_pixel_x, builder.makeUintConstant(1)); + source_tile_pixel_y = builder.createBinOp(spv::OpShiftRightLogical, type_uint, + dest_tile_pixel_y, builder.makeUintConstant(1)); + } + } else { + // Same BPP, 1x/2x -> 1x/2x/4x (as long as they're different). + // Only the X part - Y is handled by common code. + if (key.dest_msaa_samples >= xenos::MsaaSamples::k4X) { + // Horizontal samples to pixels. + source_tile_pixel_x = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, dest_sample_id, dest_tile_pixel_x, + builder.makeUintConstant(1), builder.makeUintConstant(31)); + } + } + } + } + // Common source Y and sample index for 1x/2x AA sources, independent of bits + // per sample. + if (key.source_msaa_samples < xenos::MsaaSamples::k4X && + key.source_msaa_samples != key.dest_msaa_samples) { + if (key.dest_msaa_samples >= xenos::MsaaSamples::k4X) { + // 1x/2x -> 4x. + if (key.source_msaa_samples == xenos::MsaaSamples::k2X) { + // 2x -> 4x. + // Vertical samples (second bit) of 4x destination to vertical sample + // (1, 0 for native 2x, or 0, 3 for 2x as 4x) of 2x source. + source_sample_id = builder.createBinOp(spv::OpShiftRightLogical, type_uint, dest_sample_id, + builder.makeUintConstant(1)); + if (msaa_2x_attachments_supported_) { + source_sample_id = builder.createBinOp(spv::OpBitwiseXor, type_uint, source_sample_id, + builder.makeUintConstant(1)); + } else { + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, source_sample_id, source_sample_id, + builder.makeUintConstant(1), builder.makeUintConstant(1)); + } + } else { + // 1x -> 4x. + // Vertical samples (second bit) to Y pixels. + source_tile_pixel_y = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createBinOp(spv::OpShiftRightLogical, type_uint, dest_sample_id, + builder.makeUintConstant(1)), + dest_tile_pixel_y, builder.makeUintConstant(1), builder.makeUintConstant(31)); + } + } else { + // 1x/2x -> different 1x/2x. + if (key.source_msaa_samples == xenos::MsaaSamples::k2X) { + // 2x -> 1x. + // Vertical pixels of 2x destination to vertical samples (1, 0 for + // native 2x, or 0, 3 for 2x as 4x) of 1x source. + source_sample_id = builder.createBinOp(spv::OpBitwiseAnd, type_uint, dest_tile_pixel_y, + builder.makeUintConstant(1)); + if (msaa_2x_attachments_supported_) { + source_sample_id = builder.createBinOp(spv::OpBitwiseXor, type_uint, source_sample_id, + builder.makeUintConstant(1)); + } else { + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, source_sample_id, source_sample_id, + builder.makeUintConstant(1), builder.makeUintConstant(1)); + } + source_tile_pixel_y = builder.createBinOp(spv::OpShiftRightLogical, type_uint, + dest_tile_pixel_y, builder.makeUintConstant(1)); + } else { + // 1x -> 2x. + // Vertical samples (1/0 in the first bit for native 2x or 0/1 in the + // second bit for 2x as 4x) of 2x destination to vertical pixels of 1x + // source. + if (msaa_2x_attachments_supported_) { + source_tile_pixel_y = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createBinOp(spv::OpBitwiseXor, type_uint, dest_sample_id, + builder.makeUintConstant(1)), + dest_tile_pixel_y, builder.makeUintConstant(1), builder.makeUintConstant(31)); + } else { + source_tile_pixel_y = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createBinOp(spv::OpShiftRightLogical, type_uint, dest_sample_id, + builder.makeUintConstant(1)), + dest_tile_pixel_y, builder.makeUintConstant(1), builder.makeUintConstant(31)); + } + } + } + } + + uint32_t source_pixel_width_dwords_log2 = + uint32_t(key.source_msaa_samples >= xenos::MsaaSamples::k4X) + uint32_t(source_is_64bpp); + + if (source_is_color != dest_is_color) { + // Copying between color and depth / stencil - swap 40-32bpp-sample columns + // in the pixel index within the source 32bpp tile. + uint32_t source_32bpp_tile_half_pixels = + tile_width_samples >> (1 + source_pixel_width_dwords_log2); + source_tile_pixel_x = builder.createUnaryOp( + spv::OpBitcast, type_uint, + builder.createBinOp( + spv::OpIAdd, type_int, + builder.createUnaryOp(spv::OpBitcast, type_int, source_tile_pixel_x), + builder.createTriOp( + spv::OpSelect, type_int, + builder.createBinOp(spv::OpULessThan, builder.makeBoolType(), source_tile_pixel_x, + builder.makeUintConstant(source_32bpp_tile_half_pixels)), + builder.makeIntConstant(int32_t(source_32bpp_tile_half_pixels)), + builder.makeIntConstant(-int32_t(source_32bpp_tile_half_pixels))))); + } + + // Transform the destination 32bpp tile index into the source. After the + // addition, it may be negative - in which case, the transfer is done across + // EDRAM addressing wrapping, and xenos::kEdramTileCount must be added to it, + // but `& (xenos::kEdramTileCount - 1)` handles that regardless of the sign. + spv::Id source_tile_index = builder.createBinOp( + spv::OpBitwiseAnd, type_uint, + builder.createUnaryOp( + spv::OpBitcast, type_uint, + builder.createBinOp( + spv::OpIAdd, type_int, + builder.createUnaryOp(spv::OpBitcast, type_int, dest_tile_index), + builder.createTriOp(spv::OpBitFieldSExtract, type_int, + builder.createUnaryOp(spv::OpBitcast, type_int, address_constant), + builder.makeUintConstant(xenos::kEdramPitchTilesBits * 2), + builder.makeUintConstant(xenos::kEdramBaseTilesBits + 1)))), + builder.makeUintConstant(xenos::kEdramTileCount - 1)); + // Split the source 32bpp tile index into X and Y tile index within the source + // image. + spv::Id source_pitch_tiles = + builder.createTriOp(spv::OpBitFieldUExtract, type_uint, address_constant, + builder.makeUintConstant(xenos::kEdramPitchTilesBits), + builder.makeUintConstant(xenos::kEdramPitchTilesBits)); + spv::Id source_tile_index_y = + builder.createBinOp(spv::OpUDiv, type_uint, source_tile_index, source_pitch_tiles); + spv::Id source_tile_index_x = + builder.createBinOp(spv::OpUMod, type_uint, source_tile_index, source_pitch_tiles); + // Finally calculate the source texture coordinates. + spv::Id source_pixel_x_int = builder.createUnaryOp( + spv::OpBitcast, type_int, + builder.createBinOp( + spv::OpIAdd, type_uint, + builder.createBinOp( + spv::OpIMul, type_uint, + builder.makeUintConstant(tile_width_samples >> source_pixel_width_dwords_log2), + source_tile_index_x), + source_tile_pixel_x)); + spv::Id source_pixel_y_int = builder.createUnaryOp( + spv::OpBitcast, type_int, + builder.createBinOp( + spv::OpIAdd, type_uint, + builder.createBinOp( + spv::OpIMul, type_uint, + builder.makeUintConstant(tile_height_samples >> uint32_t(key.source_msaa_samples >= + xenos::MsaaSamples::k2X)), + source_tile_index_y), + source_tile_pixel_y)); + + // Load the source. + + spv::Builder::TextureParameters source_texture_parameters = {}; + id_vector_temp.clear(); + id_vector_temp.push_back(source_pixel_x_int); + id_vector_temp.push_back(source_pixel_y_int); + spv::Id source_coordinates[2] = { + builder.createCompositeConstruct(type_int2, id_vector_temp), + }; + spv::Id source_sample_ids_int[2] = {}; + if (key.source_msaa_samples != xenos::MsaaSamples::k1X) { + source_sample_ids_int[0] = builder.createUnaryOp(spv::OpBitcast, type_int, source_sample_id); + } else { + source_texture_parameters.lod = builder.makeIntConstant(0); + } + // Go to the next sample or pixel along X if need to load two dwords. + bool source_load_is_two_32bpp_samples = !source_is_64bpp && dest_is_64bpp; + if (source_load_is_two_32bpp_samples) { + if (key.source_msaa_samples >= xenos::MsaaSamples::k4X) { + source_coordinates[1] = source_coordinates[0]; + source_sample_ids_int[1] = builder.createBinOp( + spv::OpBitwiseOr, type_int, source_sample_ids_int[0], builder.makeIntConstant(1)); + } else { + id_vector_temp.clear(); + id_vector_temp.push_back(builder.createBinOp(spv::OpBitwiseOr, type_int, source_pixel_x_int, + builder.makeIntConstant(1))); + id_vector_temp.push_back(source_pixel_y_int); + source_coordinates[1] = builder.createCompositeConstruct(type_int2, id_vector_temp); + source_sample_ids_int[1] = source_sample_ids_int[0]; + } + } + spv::Id source_color[2][4] = {}; + if (source_color_texture != spv::NoResult) { + source_texture_parameters.sampler = builder.createLoad(source_color_texture, spv::NoPrecision); + assert_true(source_color_component_type != spv::NoType); + spv::Id source_color_vec4_type = builder.makeVectorType(source_color_component_type, 4); + for (uint32_t i = 0; i <= uint32_t(source_load_is_two_32bpp_samples); ++i) { + source_texture_parameters.coords = source_coordinates[i]; + source_texture_parameters.sample = source_sample_ids_int[i]; + spv::Id source_color_vec4 = builder.createTextureCall( + spv::NoPrecision, source_color_vec4_type, false, true, false, false, false, + source_texture_parameters, spv::ImageOperandsMaskNone); + uint32_t source_color_components_remaining = source_color_texture_component_mask; + uint32_t source_color_component_index; + while ( + rex::bit_scan_forward(source_color_components_remaining, &source_color_component_index)) { + source_color_components_remaining &= ~(uint32_t(1) << source_color_component_index); + source_color[i][source_color_component_index] = builder.createCompositeExtract( + source_color_vec4, source_color_component_type, source_color_component_index); + } + } + } + spv::Id source_depth_float[2] = {}; + if (source_depth_texture != spv::NoResult) { + source_texture_parameters.sampler = builder.createLoad(source_depth_texture, spv::NoPrecision); + for (uint32_t i = 0; i <= uint32_t(source_load_is_two_32bpp_samples); ++i) { + source_texture_parameters.coords = source_coordinates[i]; + source_texture_parameters.sample = source_sample_ids_int[i]; + source_depth_float[i] = builder.createCompositeExtract( + builder.createTextureCall(spv::NoPrecision, type_float4, false, true, false, false, false, + source_texture_parameters, spv::ImageOperandsMaskNone), + type_float, 0); + } + } + spv::Id source_stencil[2] = {}; + if (source_stencil_texture != spv::NoResult) { + source_texture_parameters.sampler = + builder.createLoad(source_stencil_texture, spv::NoPrecision); + for (uint32_t i = 0; i <= uint32_t(source_load_is_two_32bpp_samples); ++i) { + source_texture_parameters.coords = source_coordinates[i]; + source_texture_parameters.sample = source_sample_ids_int[i]; + source_stencil[i] = builder.createCompositeExtract( + builder.createTextureCall(spv::NoPrecision, type_uint4, false, true, false, false, false, + source_texture_parameters, spv::ImageOperandsMaskNone), + type_uint, 0); + } + } + + // Pick the needed 32bpp half of the 64bpp color. + if (source_is_64bpp && !dest_is_64bpp) { + uint32_t source_color_half_component_count = source_color_format_component_count >> 1; + assert_true(source_color_half != spv::NoResult); + spv::Id source_color_is_second_half = builder.createBinOp( + spv::OpINotEqual, type_bool, source_color_half, builder.makeUintConstant(0)); + if (mode.output == TransferOutput::kStencilBit) { + source_color[0][0] = builder.createTriOp( + spv::OpSelect, source_color_component_type, source_color_is_second_half, + source_color[0][source_color_half_component_count], source_color[0][0]); + } else { + for (uint32_t i = 0; i < source_color_half_component_count; ++i) { + source_color[0][i] = builder.createTriOp( + spv::OpSelect, source_color_component_type, source_color_is_second_half, + source_color[0][source_color_half_component_count + i], source_color[0][i]); + } + } + } + + if (output_fragment_stencil_ref != spv::NoResult && source_stencil[0] != spv::NoResult) { + // For the depth -> depth case, write the stencil directly to the output. + assert_true(mode.output == TransferOutput::kDepth); + builder.createStore(builder.createUnaryOp(spv::OpBitcast, type_int, source_stencil[0]), + output_fragment_stencil_ref); + } + + const bool source_color_16_is_float = IsColor16FormatFloatLike(source_color_format); + const bool dest_color_16_is_float = IsColor16FormatFloatLike(dest_color_format); + spv::Id const_uint_0 = builder.makeUintConstant(0); + spv::Id const_uint_16 = builder.makeUintConstant(16); + spv::Id const_float_0 = builder.makeFloatConstant(0.0f); + spv::Id const_float_1 = builder.makeFloatConstant(1.0f); + spv::Id const_float_minus_1 = builder.makeFloatConstant(-1.0f); + spv::Id const_float_32767 = builder.makeFloatConstant(32767.0f); + spv::Id const_float_inv_32767 = builder.makeFloatConstant(1.0f / 32767.0f); + auto PWLGammaToLinear = [&](spv::Id gamma, bool gamma_pre_saturated) -> spv::Id { + if (!gamma_pre_saturated) { + gamma = builder.createTriBuiltinCall(type_float, ext_inst_glsl_std_450, GLSLstd450NClamp, + gamma, const_float_0, const_float_1); + } + spv::Id is_piece_at_least_3 = builder.createBinOp(spv::OpFOrdGreaterThanEqual, type_bool, gamma, + builder.makeFloatConstant(192.0f / 255.0f)); + spv::Id scale_3_or_2 = builder.createTriOp(spv::OpSelect, type_float, is_piece_at_least_3, + builder.makeFloatConstant(8.0f / 1024.0f), + builder.makeFloatConstant(4.0f / 1024.0f)); + spv::Id offset_3_or_2 = builder.createTriOp(spv::OpSelect, type_float, is_piece_at_least_3, + builder.makeFloatConstant(-1024.0f), + builder.makeFloatConstant(-256.0f)); + spv::Id is_piece_at_least_1 = builder.createBinOp(spv::OpFOrdGreaterThanEqual, type_bool, gamma, + builder.makeFloatConstant(64.0f / 255.0f)); + spv::Id scale_1_or_0 = builder.createTriOp(spv::OpSelect, type_float, is_piece_at_least_1, + builder.makeFloatConstant(2.0f / 1024.0f), + builder.makeFloatConstant(1.0f / 1024.0f)); + spv::Id offset_1_or_0 = builder.createTriOp(spv::OpSelect, type_float, is_piece_at_least_1, + builder.makeFloatConstant(-64.0f), const_float_0); + spv::Id is_piece_at_least_2 = builder.createBinOp(spv::OpFOrdGreaterThanEqual, type_bool, gamma, + builder.makeFloatConstant(96.0f / 255.0f)); + spv::Id scale = builder.createTriOp(spv::OpSelect, type_float, is_piece_at_least_2, + scale_3_or_2, scale_1_or_0); + spv::Id offset = builder.createTriOp(spv::OpSelect, type_float, is_piece_at_least_2, + offset_3_or_2, offset_1_or_0); + spv::Id linear = builder.createBinOp( + spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, + builder.createBinOp(spv::OpFMul, type_float, gamma, + builder.makeFloatConstant(255.0f * 1024.0f)), + scale), + offset); + linear = builder.createBinOp(spv::OpFAdd, type_float, linear, + builder.createUnaryBuiltinCall( + type_float, ext_inst_glsl_std_450, GLSLstd450Trunc, + builder.createBinOp(spv::OpFMul, type_float, linear, scale))); + return builder.createBinOp(spv::OpFMul, type_float, linear, + builder.makeFloatConstant(1.0f / 1023.0f)); + }; + auto LinearToPWLGamma = [&](spv::Id linear, bool linear_pre_saturated) -> spv::Id { + if (!linear_pre_saturated) { + linear = builder.createTriBuiltinCall(type_float, ext_inst_glsl_std_450, GLSLstd450NClamp, + linear, const_float_0, const_float_1); + } + spv::Id is_piece_at_least_3 = + builder.createBinOp(spv::OpFOrdGreaterThanEqual, type_bool, linear, + builder.makeFloatConstant(512.0f / 1023.0f)); + spv::Id scale_3_or_2 = builder.createTriOp(spv::OpSelect, type_float, is_piece_at_least_3, + builder.makeFloatConstant(1023.0f / 8.0f), + builder.makeFloatConstant(1023.0f / 4.0f)); + spv::Id offset_3_or_2 = builder.createTriOp(spv::OpSelect, type_float, is_piece_at_least_3, + builder.makeFloatConstant(128.0f / 255.0f), + builder.makeFloatConstant(64.0f / 255.0f)); + spv::Id is_piece_at_least_1 = builder.createBinOp( + spv::OpFOrdGreaterThanEqual, type_bool, linear, builder.makeFloatConstant(64.0f / 1023.0f)); + spv::Id scale_1_or_0 = builder.createTriOp(spv::OpSelect, type_float, is_piece_at_least_1, + builder.makeFloatConstant(1023.0f / 2.0f), + builder.makeFloatConstant(1023.0f)); + spv::Id offset_1_or_0 = + builder.createTriOp(spv::OpSelect, type_float, is_piece_at_least_1, + builder.makeFloatConstant(32.0f / 255.0f), const_float_0); + spv::Id is_piece_at_least_2 = + builder.createBinOp(spv::OpFOrdGreaterThanEqual, type_bool, linear, + builder.makeFloatConstant(128.0f / 1023.0f)); + spv::Id scale = builder.createTriOp(spv::OpSelect, type_float, is_piece_at_least_2, + scale_3_or_2, scale_1_or_0); + spv::Id offset = builder.createTriOp(spv::OpSelect, type_float, is_piece_at_least_2, + offset_3_or_2, offset_1_or_0); + return builder.createBinOp( + spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, + builder.createUnaryBuiltinCall( + type_float, ext_inst_glsl_std_450, GLSLstd450Trunc, + builder.createBinOp(spv::OpFMul, type_float, linear, scale)), + builder.makeFloatConstant(1.0f / 255.0f)), + offset); + }; + auto PackSource16ComponentToUint = [&](spv::Id component) -> spv::Id { + if (source_color_is_uint) { + return component; + } + if (source_color_16_is_float) { + id_vector_temp.clear(); + id_vector_temp.push_back(component); + id_vector_temp.push_back(const_float_0); + spv::Id packed_half = builder.createUnaryBuiltinCall( + type_uint, ext_inst_glsl_std_450, GLSLstd450PackHalf2x16, + builder.createCompositeConstruct(type_float2, id_vector_temp)); + return builder.createTriOp(spv::OpBitFieldUExtract, type_uint, packed_half, const_uint_0, + const_uint_16); + } + spv::Id component_clamped = + builder.createTriBuiltinCall(type_float, ext_inst_glsl_std_450, GLSLstd450NClamp, component, + const_float_minus_1, const_float_1); + spv::Id component_rounded = builder.createUnaryBuiltinCall( + type_float, ext_inst_glsl_std_450, GLSLstd450RoundEven, + builder.createBinOp(spv::OpFMul, type_float, component_clamped, const_float_32767)); + spv::Id component_snorm = + builder.createUnaryOp(spv::OpConvertFToS, type_int, component_rounded); + return builder.createTriOp(spv::OpBitFieldUExtract, type_uint, + builder.createUnaryOp(spv::OpBitcast, type_uint, component_snorm), + const_uint_0, const_uint_16); + }; + auto PackSource16PairToUint32 = [&](spv::Id component_0, spv::Id component_1) -> spv::Id { + return builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, PackSource16ComponentToUint(component_0), + PackSource16ComponentToUint(component_1), const_uint_16, const_uint_16); + }; + auto UnpackDest16ComponentFromUint32 = [&](spv::Id packed_word, + uint32_t component_index) -> spv::Id { + spv::Id component_offset = component_index & 1 ? const_uint_16 : const_uint_0; + if (dest_color_is_uint) { + return builder.createTriOp(spv::OpBitFieldUExtract, type_uint, packed_word, component_offset, + const_uint_16); + } + if (dest_color_16_is_float) { + spv::Id component_pair = builder.createUnaryBuiltinCall( + type_float2, ext_inst_glsl_std_450, GLSLstd450UnpackHalf2x16, packed_word); + return builder.createCompositeExtract(component_pair, type_float, component_index & 1); + } + spv::Id component_snorm = builder.createTriOp(spv::OpBitFieldSExtract, type_int, packed_word, + component_offset, const_uint_16); + spv::Id component_float = + builder.createBinOp(spv::OpFMul, type_float, + builder.createUnaryOp(spv::OpConvertSToF, type_float, component_snorm), + const_float_inv_32767); + return builder.createTriBuiltinCall(type_float, ext_inst_glsl_std_450, GLSLstd450NClamp, + component_float, const_float_minus_1, const_float_1); + }; + + if (dest_is_64bpp) { + // Construct the 64bpp color from two 32-bit samples or one 64-bit sample. + // If `packed` (two uints) are created, use the generic path involving + // unpacking. + // Otherwise, the fragment data output must be written to directly by the + // reached control flow path. + spv::Id packed[2] = {}; + if (source_is_color) { + switch (source_color_format) { + case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA: { + if (gamma_render_target_as_unorm16_) { + // 8_8_8_8_GAMMA is represented by linear stored in + // R16G16B16A16_UNORM. + for (uint32_t i = 0; i < 2; ++i) { + for (uint32_t j = 0; j < 3; ++j) { + source_color[i][j] = LinearToPWLGamma(source_color[i][j], true); + } + } + } + } + [[fallthrough]]; + case xenos::ColorRenderTargetFormat::k_8_8_8_8: { + spv::Id unorm_round_offset = builder.makeFloatConstant(0.5f); + spv::Id unorm_scale = builder.makeFloatConstant(255.0f); + spv::Id component_width = builder.makeUintConstant(8); + for (uint32_t i = 0; i < 2; ++i) { + packed[i] = builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp( + spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, source_color[i][0], unorm_scale), + unorm_round_offset)); + for (uint32_t j = 1; j < 4; ++j) { + packed[i] = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed[i], + builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp(spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, + source_color[i][j], unorm_scale), + unorm_round_offset)), + builder.makeUintConstant(8 * j), component_width); + } + } + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: { + spv::Id unorm_round_offset = builder.makeFloatConstant(0.5f); + spv::Id unorm_scale_rgb = builder.makeFloatConstant(1023.0f); + spv::Id width_rgb = builder.makeUintConstant(10); + spv::Id unorm_scale_a = builder.makeFloatConstant(3.0f); + spv::Id width_a = builder.makeUintConstant(2); + for (uint32_t i = 0; i < 2; ++i) { + packed[i] = builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp(spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, source_color[i][0], + unorm_scale_rgb), + unorm_round_offset)); + for (uint32_t j = 1; j < 4; ++j) { + packed[i] = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed[i], + builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp( + spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, source_color[i][j], + j == 3 ? unorm_scale_a : unorm_scale_rgb), + unorm_round_offset)), + builder.makeUintConstant(10 * j), j == 3 ? width_a : width_rgb); + } + } + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16: { + spv::Id width_rgb = builder.makeUintConstant(10); + spv::Id float_0 = builder.makeFloatConstant(0.0f); + spv::Id float_1 = builder.makeFloatConstant(1.0f); + spv::Id unorm_round_offset = builder.makeFloatConstant(0.5f); + spv::Id unorm_scale_a = builder.makeFloatConstant(3.0f); + spv::Id offset_a = builder.makeUintConstant(30); + spv::Id width_a = builder.makeUintConstant(2); + for (uint32_t i = 0; i < 2; ++i) { + // Float16 has a wider range for both color and alpha, also NaNs - + // clamp and convert. + packed[i] = SpirvShaderTranslator::UnclampedFloat32To7e3(builder, source_color[i][0], + ext_inst_glsl_std_450); + for (uint32_t j = 1; j < 3; ++j) { + packed[i] = + builder.createQuadOp(spv::OpBitFieldInsert, type_uint, packed[i], + SpirvShaderTranslator::UnclampedFloat32To7e3( + builder, source_color[i][j], ext_inst_glsl_std_450), + builder.makeUintConstant(10 * j), width_rgb); + } + // Saturate and convert the alpha. + spv::Id alpha_saturated = + builder.createTriBuiltinCall(type_float, ext_inst_glsl_std_450, GLSLstd450NClamp, + source_color[i][3], float_0, float_1); + packed[i] = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed[i], + builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp(spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, + alpha_saturated, unorm_scale_a), + unorm_round_offset)), + offset_a, width_a); + } + } break; + // Route through packed uint32 words so mixed source/destination + // transfer component types (integer vs float fallback) are handled + // uniformly. + case xenos::ColorRenderTargetFormat::k_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_FLOAT: { + for (uint32_t i = 0; i < 2; ++i) { + packed[i] = PackSource16PairToUint32(source_color[i][0], source_color[i][1]); + } + } break; + case xenos::ColorRenderTargetFormat::k_16_16_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT: { + for (uint32_t i = 0; i < 2; ++i) { + packed[i] = + PackSource16PairToUint32(source_color[0][i << 1], source_color[0][(i << 1) + 1]); + } + } break; + // Float32 is transferred as uint32 to preserve NaN encodings. However, + // multisampled sampled image support is optional in Vulkan. + case xenos::ColorRenderTargetFormat::k_32_FLOAT: { + for (uint32_t i = 0; i < 2; ++i) { + packed[i] = source_color[i][0]; + if (!source_color_is_uint) { + packed[i] = builder.createUnaryOp(spv::OpBitcast, type_uint, packed[i]); + } + } + } break; + case xenos::ColorRenderTargetFormat::k_32_32_FLOAT: { + for (uint32_t i = 0; i < 2; ++i) { + packed[i] = source_color[0][i]; + if (!source_color_is_uint) { + packed[i] = builder.createUnaryOp(spv::OpBitcast, type_uint, packed[i]); + } + } + } break; + } + } else { + assert_true(source_depth_texture != spv::NoResult); + assert_true(source_stencil_texture != spv::NoResult); + spv::Id depth_offset = builder.makeUintConstant(8); + spv::Id depth_width = builder.makeUintConstant(24); + for (uint32_t i = 0; i < 2; ++i) { + spv::Id depth24 = spv::NoResult; + switch (source_depth_format) { + case xenos::DepthRenderTargetFormat::kD24S8: { + // Round to the nearest even integer. This seems to be the + // correct conversion, adding +0.5 and rounding towards zero results + // in red instead of black in the 4D5307E6 clear shader. + depth24 = builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createUnaryBuiltinCall( + type_float, ext_inst_glsl_std_450, GLSLstd450RoundEven, + builder.createBinOp(spv::OpFMul, type_float, source_depth_float[i], + builder.makeFloatConstant(float(0xFFFFFF))))); + } break; + case xenos::DepthRenderTargetFormat::kD24FS8: { + depth24 = SpirvShaderTranslator::PreClampedDepthTo20e4( + builder, source_depth_float[i], depth_float24_round(), true, ext_inst_glsl_std_450); + } break; + } + // Merge depth and stencil. + packed[i] = builder.createQuadOp(spv::OpBitFieldInsert, type_uint, source_stencil[i], + depth24, depth_offset, depth_width); + } + } + // Common path unless there was a specialized one - unpack two packed 32-bit + // parts. + if (packed[0] != spv::NoResult) { + assert_true(packed[1] != spv::NoResult); + if (dest_color_format == xenos::ColorRenderTargetFormat::k_32_32_FLOAT) { + id_vector_temp.clear(); + id_vector_temp.push_back(packed[0]); + id_vector_temp.push_back(packed[1]); + // If integer transfer formats are unavailable for this sample count, + // ownership transfer falls back to float formats and raw bits are + // passed via bitcasts. + if (!dest_color_is_uint) { + for (spv::Id& float32 : id_vector_temp) { + float32 = builder.createUnaryOp(spv::OpBitcast, type_float, float32); + } + } + builder.createStore(builder.createCompositeConstruct(type_fragment_data, id_vector_temp), + output_fragment_data); + } else { + id_vector_temp.clear(); + for (uint32_t i = 0; i < 4; ++i) { + id_vector_temp.push_back(UnpackDest16ComponentFromUint32(packed[i >> 1], i)); + } + builder.createStore(builder.createCompositeConstruct(type_fragment_data, id_vector_temp), + output_fragment_data); + } + } + } else { + // If `packed` is created, use the generic path involving unpacking. + // - For a color destination, the packed 32bpp color. + // - For a depth / stencil destination, stencil in 0:7, depth in 8:31 + // normally, or depth in 0:23 and zeros in 24:31 with packed_only_depth. + // - For a stencil bit, stencil in 0:7. + // Otherwise, the fragment data or fragment depth / stencil output must be + // written to directly by the reached control flow path. + spv::Id packed = spv::NoResult; + bool packed_only_depth = false; + if (source_is_color) { + switch (source_color_format) { + case xenos::ColorRenderTargetFormat::k_8_8_8_8: + case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA: { + if (mode.output == TransferOutput::kStencilBit) { + if (source_color_format == xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA && + gamma_render_target_as_unorm16_) { + source_color[0][0] = LinearToPWLGamma(source_color[0][0], true); + } + packed = builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp(spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, source_color[0][0], + builder.makeFloatConstant(255.0f)), + builder.makeFloatConstant(0.5f))); + } else if (dest_is_color && + (dest_color_format == xenos::ColorRenderTargetFormat::k_8_8_8_8 || + dest_color_format == xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA)) { + if (source_color_format != dest_color_format) { + // Color space conversion between k_8_8_8_8 and + // k_8_8_8_8_GAMMA. + if (dest_color_format != xenos::ColorRenderTargetFormat::k_8_8_8_8) { + for (uint32_t i = 0; i < 3; ++i) { + source_color[0][i] = LinearToPWLGamma(source_color[0][i], true); + } + } else { + for (uint32_t i = 0; i < 3; ++i) { + source_color[0][i] = PWLGammaToLinear(source_color[0][i], true); + } + } + } + // Same or converted format - passthrough. + id_vector_temp.clear(); + for (uint32_t i = 0; i < 4; ++i) { + id_vector_temp.push_back(source_color[0][i]); + } + builder.createStore( + builder.createCompositeConstruct(type_fragment_data, id_vector_temp), + output_fragment_data); + } else if (mode.output == TransferOutput::kDepth) { + if (source_color_format == xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA && + gamma_render_target_as_unorm16_) { + for (uint32_t i = output_fragment_stencil_ref != spv::NoResult ? 0 : 1; i < 3; ++i) { + source_color[0][i] = LinearToPWLGamma(source_color[0][i], true); + } + } + // When need only depth, not stencil, skip the red component. + packed_only_depth = true; + if (output_fragment_stencil_ref != spv::NoResult) { + // Write the red component to the stencil reference. + builder.createStore( + builder.createUnaryOp( + spv::OpBitcast, type_int, + builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp( + spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, source_color[0][0], + builder.makeFloatConstant(255.0f)), + builder.makeFloatConstant(0.5f)))), + output_fragment_stencil_ref); + } + // Put depth in 0:23. + packed = builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp(spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, source_color[0][1], + builder.makeFloatConstant(255.0f)), + builder.makeFloatConstant(0.5f))); + spv::Id component_width = builder.makeUintConstant(8); + for (uint32_t i = 2; i < 4; ++i) { + packed = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed, + builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp( + spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, source_color[0][i], + builder.makeFloatConstant(255.0f)), + builder.makeFloatConstant(0.5f))), + builder.makeUintConstant(8 * (i - 1)), component_width); + } + } else { + if (source_color_format == xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA && + gamma_render_target_as_unorm16_) { + for (uint32_t i = 0; i < 3; ++i) { + source_color[0][i] = LinearToPWLGamma(source_color[0][i], true); + } + } + packed = builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp(spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, source_color[0][0], + builder.makeFloatConstant(255.0f)), + builder.makeFloatConstant(0.5f))); + spv::Id component_width = builder.makeUintConstant(8); + for (uint32_t i = 1; i < 4; ++i) { + packed = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed, + builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp( + spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, source_color[0][i], + builder.makeFloatConstant(255.0f)), + builder.makeFloatConstant(0.5f))), + builder.makeUintConstant(8 * i), component_width); + } + } + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: { + if (dest_is_color && + (dest_color_format == xenos::ColorRenderTargetFormat::k_2_10_10_10 || + dest_color_format == xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10)) { + id_vector_temp.clear(); + for (uint32_t i = 0; i < 4; ++i) { + id_vector_temp.push_back(source_color[0][i]); + } + builder.createStore( + builder.createCompositeConstruct(type_fragment_data, id_vector_temp), + output_fragment_data); + } else { + spv::Id unorm_round_offset = builder.makeFloatConstant(0.5f); + spv::Id unorm_scale_rgb = builder.makeFloatConstant(1023.0f); + packed = builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp(spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, source_color[0][0], + unorm_scale_rgb), + unorm_round_offset)); + if (mode.output != TransferOutput::kStencilBit) { + spv::Id width_rgb = builder.makeUintConstant(10); + spv::Id unorm_scale_a = builder.makeFloatConstant(3.0f); + spv::Id width_a = builder.makeUintConstant(2); + for (uint32_t i = 1; i < 4; ++i) { + packed = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed, + builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp( + spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, source_color[0][i], + i == 3 ? unorm_scale_a : unorm_scale_rgb), + unorm_round_offset)), + builder.makeUintConstant(10 * i), i == 3 ? width_a : width_rgb); + } + } + } + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16: { + if (dest_is_color && + (dest_color_format == xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT || + dest_color_format == + xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16)) { + id_vector_temp.clear(); + for (uint32_t i = 0; i < 4; ++i) { + id_vector_temp.push_back(source_color[0][i]); + } + builder.createStore( + builder.createCompositeConstruct(type_fragment_data, id_vector_temp), + output_fragment_data); + } else { + // Float16 has a wider range for both color and alpha, also NaNs - + // clamp and convert. + packed = SpirvShaderTranslator::UnclampedFloat32To7e3(builder, source_color[0][0], + ext_inst_glsl_std_450); + if (mode.output != TransferOutput::kStencilBit) { + spv::Id width_rgb = builder.makeUintConstant(10); + for (uint32_t i = 1; i < 3; ++i) { + packed = + builder.createQuadOp(spv::OpBitFieldInsert, type_uint, packed, + SpirvShaderTranslator::UnclampedFloat32To7e3( + builder, source_color[0][i], ext_inst_glsl_std_450), + builder.makeUintConstant(10 * i), width_rgb); + } + // Saturate and convert the alpha. + spv::Id alpha_saturated = builder.createTriBuiltinCall( + type_float, ext_inst_glsl_std_450, GLSLstd450NClamp, source_color[0][3], + builder.makeFloatConstant(0.0f), builder.makeFloatConstant(1.0f)); + packed = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed, + builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp( + spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, alpha_saturated, + builder.makeFloatConstant(3.0f)), + builder.makeFloatConstant(0.5f))), + builder.makeUintConstant(30), builder.makeUintConstant(2)); + } + } + } break; + case xenos::ColorRenderTargetFormat::k_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_FLOAT: + case xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT: { + // Route through packed uint32 so destination transfer type (integer + // vs float fallback) is reconstructed consistently. + packed = PackSource16ComponentToUint(source_color[0][0]); + if (mode.output != TransferOutput::kStencilBit) { + packed = builder.createQuadOp(spv::OpBitFieldInsert, type_uint, packed, + PackSource16ComponentToUint(source_color[0][1]), + const_uint_16, const_uint_16); + } + } break; + // Float32 is transferred as uint32 to preserve NaN encodings. However, + // multisampled sampled image support is optional in Vulkan. + case xenos::ColorRenderTargetFormat::k_32_FLOAT: + case xenos::ColorRenderTargetFormat::k_32_32_FLOAT: { + packed = source_color[0][0]; + if (!source_color_is_uint) { + packed = builder.createUnaryOp(spv::OpBitcast, type_uint, packed); + } + } break; + } + } else if (source_depth_float[0] != spv::NoResult) { + if (mode.output == TransferOutput::kDepth && dest_depth_format == source_depth_format) { + builder.createStore(source_depth_float[0], output_fragment_depth); + } else { + switch (source_depth_format) { + case xenos::DepthRenderTargetFormat::kD24S8: { + // Round to the nearest even integer. This seems to be the correct + // conversion, adding +0.5 and rounding towards zero results in red + // instead of black in the 4D5307E6 clear shader. + packed = builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createUnaryBuiltinCall( + type_float, ext_inst_glsl_std_450, GLSLstd450RoundEven, + builder.createBinOp(spv::OpFMul, type_float, source_depth_float[0], + builder.makeFloatConstant(float(0xFFFFFF))))); + } break; + case xenos::DepthRenderTargetFormat::kD24FS8: { + packed = SpirvShaderTranslator::PreClampedDepthTo20e4( + builder, source_depth_float[0], depth_float24_round(), true, ext_inst_glsl_std_450); + } break; + } + if (mode.output == TransferOutput::kDepth) { + packed_only_depth = true; + } else { + // Merge depth and stencil. + packed = builder.createQuadOp(spv::OpBitFieldInsert, type_uint, source_stencil[0], packed, + builder.makeUintConstant(8), builder.makeUintConstant(24)); + } + } + } + switch (mode.output) { + case TransferOutput::kColor: { + // Unless a special path was taken, unpack the raw 32bpp value into the + // 32bpp color output. + if (packed != spv::NoResult) { + switch (dest_color_format) { + case xenos::ColorRenderTargetFormat::k_8_8_8_8: + case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA: { + spv::Id component_width = builder.makeUintConstant(8); + spv::Id unorm_scale = builder.makeFloatConstant(1.0f / 255.0f); + id_vector_temp.clear(); + for (uint32_t i = 0; i < 4; ++i) { + id_vector_temp.push_back(builder.createBinOp( + spv::OpFMul, type_float, + builder.createUnaryOp( + spv::OpConvertUToF, type_float, + builder.createTriOp(spv::OpBitFieldUExtract, type_uint, packed, + builder.makeUintConstant(8 * i), component_width)), + unorm_scale)); + } + if (dest_color_format == xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA && + gamma_render_target_as_unorm16_) { + // 8_8_8_8_GAMMA is represented by linear stored in + // R16G16B16A16_UNORM. + for (uint32_t i = 0; i < 3; ++i) { + id_vector_temp[i] = PWLGammaToLinear(id_vector_temp[i], true); + } + } + builder.createStore( + builder.createCompositeConstruct(type_fragment_data, id_vector_temp), + output_fragment_data); + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: { + spv::Id width_rgb = builder.makeUintConstant(10); + spv::Id unorm_scale_rgb = builder.makeFloatConstant(1.0f / 1023.0f); + spv::Id width_a = builder.makeUintConstant(2); + spv::Id unorm_scale_a = builder.makeFloatConstant(1.0f / 3.0f); + id_vector_temp.clear(); + for (uint32_t i = 0; i < 4; ++i) { + id_vector_temp.push_back(builder.createBinOp( + spv::OpFMul, type_float, + builder.createUnaryOp( + spv::OpConvertUToF, type_float, + builder.createTriOp(spv::OpBitFieldUExtract, type_uint, packed, + builder.makeUintConstant(10 * i), + i == 3 ? width_a : width_rgb)), + i == 3 ? unorm_scale_a : unorm_scale_rgb)); + } + builder.createStore( + builder.createCompositeConstruct(type_fragment_data, id_vector_temp), + output_fragment_data); + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16: { + id_vector_temp.clear(); + // Color. + for (uint32_t i = 0; i < 3; ++i) { + id_vector_temp.push_back(SpirvShaderTranslator::Float7e3To32( + builder, packed, 10 * i, false, ext_inst_glsl_std_450)); + } + // Alpha. + id_vector_temp.push_back(builder.createBinOp( + spv::OpFMul, type_float, + builder.createUnaryOp(spv::OpConvertUToF, type_float, + builder.createTriOp(spv::OpBitFieldUExtract, type_uint, + packed, builder.makeUintConstant(30), + builder.makeUintConstant(2))), + builder.makeFloatConstant(1.0f / 3.0f))); + builder.createStore( + builder.createCompositeConstruct(type_fragment_data, id_vector_temp), + output_fragment_data); + } break; + case xenos::ColorRenderTargetFormat::k_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_FLOAT: { + id_vector_temp.clear(); + for (uint32_t i = 0; i < 2; ++i) { + id_vector_temp.push_back(UnpackDest16ComponentFromUint32(packed, i)); + } + builder.createStore( + builder.createCompositeConstruct(type_fragment_data, id_vector_temp), + output_fragment_data); + } break; + case xenos::ColorRenderTargetFormat::k_32_FLOAT: { + // Float32 is transferred as uint32 to preserve NaN encodings. + // If the integer transfer format is unavailable for this sample + // count, the transfer format is float and this bitcast path is + // used. + spv::Id float32 = packed; + if (!dest_color_is_uint) { + float32 = builder.createUnaryOp(spv::OpBitcast, type_float, float32); + } + builder.createStore(float32, output_fragment_data); + } break; + default: + // A 64bpp format (handled separately) or an invalid one. + assert_unhandled_case(dest_color_format); + } + } + } break; + case TransferOutput::kDepth: { + if (packed) { + spv::Id guest_depth24 = packed; + if (!packed_only_depth) { + // Extract the depth bits. + guest_depth24 = builder.createBinOp(spv::OpShiftRightLogical, type_uint, guest_depth24, + builder.makeUintConstant(8)); + } + // Load the host float32 depth, check if, when converted to the guest + // format, it's the same as the guest source, thus up to date, and if + // it is, write host float32 depth, otherwise do the guest -> host + // conversion. + spv::Id host_depth32 = spv::NoResult; + if (host_depth_source_texture != spv::NoResult) { + // Convert position and sample index from within the destination + // tile to within the host depth source tile, like for the guest + // render target, but for 32bpp -> 32bpp only. + spv::Id host_depth_source_sample_id = dest_sample_id; + spv::Id host_depth_source_tile_pixel_x = dest_tile_pixel_x; + spv::Id host_depth_source_tile_pixel_y = dest_tile_pixel_y; + if (key.host_depth_source_msaa_samples != key.dest_msaa_samples) { + if (key.host_depth_source_msaa_samples >= xenos::MsaaSamples::k4X) { + // 4x -> 1x/2x. + if (key.dest_msaa_samples == xenos::MsaaSamples::k2X) { + // 4x -> 2x. + // Horizontal pixels to samples. Vertical sample (1/0 in the + // first bit for native 2x or 0/1 in the second bit for 2x as + // 4x) to second sample bit. + if (msaa_2x_attachments_supported_) { + host_depth_source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, dest_tile_pixel_x, + builder.createBinOp(spv::OpBitwiseXor, type_uint, dest_sample_id, + builder.makeUintConstant(1)), + builder.makeUintConstant(1), builder.makeUintConstant(31)); + } else { + host_depth_source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, dest_sample_id, dest_tile_pixel_x, + builder.makeUintConstant(0), builder.makeUintConstant(1)); + } + host_depth_source_tile_pixel_x = + builder.createBinOp(spv::OpShiftRightLogical, type_uint, dest_tile_pixel_x, + builder.makeUintConstant(1)); + } else { + // 4x -> 1x. + // Pixels to samples. + host_depth_source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createBinOp(spv::OpBitwiseAnd, type_uint, dest_tile_pixel_x, + builder.makeUintConstant(1)), + dest_tile_pixel_y, builder.makeUintConstant(1), builder.makeUintConstant(1)); + host_depth_source_tile_pixel_x = + builder.createBinOp(spv::OpShiftRightLogical, type_uint, dest_tile_pixel_x, + builder.makeUintConstant(1)); + host_depth_source_tile_pixel_y = + builder.createBinOp(spv::OpShiftRightLogical, type_uint, dest_tile_pixel_y, + builder.makeUintConstant(1)); + } + } else { + // 1x/2x -> 1x/2x/4x (as long as they're different). + // Only the X part - Y is handled by common code. + if (key.dest_msaa_samples >= xenos::MsaaSamples::k4X) { + // Horizontal samples to pixels. + host_depth_source_tile_pixel_x = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, dest_sample_id, dest_tile_pixel_x, + builder.makeUintConstant(1), builder.makeUintConstant(31)); + } + } + // Host depth source Y and sample index for 1x/2x AA sources. + if (key.host_depth_source_msaa_samples < xenos::MsaaSamples::k4X) { + if (key.dest_msaa_samples >= xenos::MsaaSamples::k4X) { + // 1x/2x -> 4x. + if (key.host_depth_source_msaa_samples == xenos::MsaaSamples::k2X) { + // 2x -> 4x. + // Vertical samples (second bit) of 4x destination to + // vertical sample (1, 0 for native 2x, or 0, 3 for 2x as + // 4x) of 2x source. + host_depth_source_sample_id = + builder.createBinOp(spv::OpShiftRightLogical, type_uint, dest_sample_id, + builder.makeUintConstant(1)); + if (msaa_2x_attachments_supported_) { + host_depth_source_sample_id = builder.createBinOp( + spv::OpBitwiseXor, type_uint, host_depth_source_sample_id, + builder.makeUintConstant(1)); + } else { + host_depth_source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, host_depth_source_sample_id, + host_depth_source_sample_id, builder.makeUintConstant(1), + builder.makeUintConstant(1)); + } + } else { + // 1x -> 4x. + // Vertical samples (second bit) to Y pixels. + host_depth_source_tile_pixel_y = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createBinOp(spv::OpShiftRightLogical, type_uint, dest_sample_id, + builder.makeUintConstant(1)), + dest_tile_pixel_y, builder.makeUintConstant(1), + builder.makeUintConstant(31)); + } + } else { + // 1x/2x -> different 1x/2x. + if (key.host_depth_source_msaa_samples == xenos::MsaaSamples::k2X) { + // 2x -> 1x. + // Vertical pixels of 2x destination to vertical samples (1, + // 0 for native 2x, or 0, 3 for 2x as 4x) of 1x source. + host_depth_source_sample_id = + builder.createBinOp(spv::OpBitwiseAnd, type_uint, dest_tile_pixel_y, + builder.makeUintConstant(1)); + if (msaa_2x_attachments_supported_) { + host_depth_source_sample_id = builder.createBinOp( + spv::OpBitwiseXor, type_uint, host_depth_source_sample_id, + builder.makeUintConstant(1)); + } else { + host_depth_source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, host_depth_source_sample_id, + host_depth_source_sample_id, builder.makeUintConstant(1), + builder.makeUintConstant(1)); + } + host_depth_source_tile_pixel_y = + builder.createBinOp(spv::OpShiftRightLogical, type_uint, dest_tile_pixel_y, + builder.makeUintConstant(1)); + } else { + // 1x -> 2x. + // Vertical samples (1/0 in the first bit for native 2x or + // 0/1 in the second bit for 2x as 4x) of 2x destination to + // vertical pixels of 1x source. + if (msaa_2x_attachments_supported_) { + host_depth_source_tile_pixel_y = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createBinOp(spv::OpBitwiseXor, type_uint, dest_sample_id, + builder.makeUintConstant(1)), + dest_tile_pixel_y, builder.makeUintConstant(1), + builder.makeUintConstant(31)); + } else { + host_depth_source_tile_pixel_y = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createBinOp(spv::OpShiftRightLogical, type_uint, dest_sample_id, + builder.makeUintConstant(1)), + dest_tile_pixel_y, builder.makeUintConstant(1), + builder.makeUintConstant(31)); + } + } + } + } + } + assert_true(push_constants_member_host_depth_address != UINT32_MAX); + id_vector_temp.clear(); + id_vector_temp.push_back( + builder.makeIntConstant(int32_t(push_constants_member_host_depth_address))); + spv::Id host_depth_address_constant = + builder.createLoad(builder.createAccessChain(spv::StorageClassPushConstant, + push_constants, id_vector_temp), + spv::NoPrecision); + // Transform the destination tile index into the host depth source. + // After the addition, it may be negative - in which case, the + // transfer is done across EDRAM addressing wrapping, and + // xenos::kEdramTileCount must be added to it, but + // `& (xenos::kEdramTileCount - 1)` handles that regardless of the + // sign. + spv::Id host_depth_source_tile_index = builder.createBinOp( + spv::OpBitwiseAnd, type_uint, + builder.createUnaryOp( + spv::OpBitcast, type_uint, + builder.createBinOp( + spv::OpIAdd, type_int, + builder.createUnaryOp(spv::OpBitcast, type_int, dest_tile_index), + builder.createTriOp( + spv::OpBitFieldSExtract, type_int, + builder.createUnaryOp(spv::OpBitcast, type_int, + host_depth_address_constant), + builder.makeUintConstant(xenos::kEdramPitchTilesBits * 2), + builder.makeUintConstant(xenos::kEdramBaseTilesBits + 1)))), + builder.makeUintConstant(xenos::kEdramTileCount - 1)); + // Split the host depth source tile index into X and Y tile index + // within the source image. + spv::Id host_depth_source_pitch_tiles = + builder.createTriOp(spv::OpBitFieldUExtract, type_uint, host_depth_address_constant, + builder.makeUintConstant(xenos::kEdramPitchTilesBits), + builder.makeUintConstant(xenos::kEdramPitchTilesBits)); + spv::Id host_depth_source_tile_index_y = + builder.createBinOp(spv::OpUDiv, type_uint, host_depth_source_tile_index, + host_depth_source_pitch_tiles); + spv::Id host_depth_source_tile_index_x = + builder.createBinOp(spv::OpUMod, type_uint, host_depth_source_tile_index, + host_depth_source_pitch_tiles); + // Finally calculate the host depth source texture coordinates. + spv::Id host_depth_source_pixel_x_int = builder.createUnaryOp( + spv::OpBitcast, type_int, + builder.createBinOp( + spv::OpIAdd, type_uint, + builder.createBinOp(spv::OpIMul, type_uint, + builder.makeUintConstant(tile_width_samples >> + uint32_t(key.source_msaa_samples >= + xenos::MsaaSamples::k4X)), + host_depth_source_tile_index_x), + host_depth_source_tile_pixel_x)); + spv::Id host_depth_source_pixel_y_int = builder.createUnaryOp( + spv::OpBitcast, type_int, + builder.createBinOp( + spv::OpIAdd, type_uint, + builder.createBinOp(spv::OpIMul, type_uint, + builder.makeUintConstant(tile_height_samples >> + uint32_t(key.source_msaa_samples >= + xenos::MsaaSamples::k2X)), + host_depth_source_tile_index_y), + host_depth_source_tile_pixel_y)); + // Load the host depth source. + spv::Builder::TextureParameters host_depth_source_texture_parameters = {}; + host_depth_source_texture_parameters.sampler = + builder.createLoad(host_depth_source_texture, spv::NoPrecision); + id_vector_temp.clear(); + id_vector_temp.push_back(host_depth_source_pixel_x_int); + id_vector_temp.push_back(host_depth_source_pixel_y_int); + host_depth_source_texture_parameters.coords = + builder.createCompositeConstruct(type_int2, id_vector_temp); + if (key.host_depth_source_msaa_samples != xenos::MsaaSamples::k1X) { + host_depth_source_texture_parameters.sample = + builder.createUnaryOp(spv::OpBitcast, type_int, host_depth_source_sample_id); + } else { + host_depth_source_texture_parameters.lod = builder.makeIntConstant(0); + } + host_depth32 = builder.createCompositeExtract( + builder.createTextureCall(spv::NoPrecision, type_float4, false, true, false, false, + false, host_depth_source_texture_parameters, + spv::ImageOperandsMaskNone), + type_float, 0); + } else if (host_depth_source_buffer != spv::NoResult) { + // Get the address in the EDRAM scratch buffer and load from there. + // The beginning of the buffer is (0, 0) of the destination. + // 40-sample columns are not swapped for addressing simplicity + // (because this is used for depth -> depth transfers, where + // swapping isn't needed). + // Convert samples to pixels. + assert_true(key.host_depth_source_msaa_samples == xenos::MsaaSamples::k1X); + spv::Id dest_tile_sample_x = dest_tile_pixel_x; + spv::Id dest_tile_sample_y = dest_tile_pixel_y; + if (key.dest_msaa_samples >= xenos::MsaaSamples::k2X) { + if (key.dest_msaa_samples >= xenos::MsaaSamples::k4X) { + // Horizontal sample index in bit 0. + dest_tile_sample_x = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, dest_sample_id, dest_tile_pixel_x, + builder.makeUintConstant(1), builder.makeUintConstant(31)); + } + // Vertical sample index as 1 or 0 in bit 0 for true 2x or as 0 + // or 1 in bit 1 for 4x or for 2x emulated as 4x. + dest_tile_sample_y = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createBinOp((key.dest_msaa_samples == xenos::MsaaSamples::k2X && + msaa_2x_attachments_supported_) + ? spv::OpBitwiseXor + : spv::OpShiftRightLogical, + type_uint, dest_sample_id, builder.makeUintConstant(1)), + dest_tile_pixel_y, builder.makeUintConstant(1), builder.makeUintConstant(31)); + } + // Combine the tile sample index and the tile index. + // The tile index doesn't need to be wrapped, as the host depth is + // written to the beginning of the buffer, without the base offset. + spv::Id host_depth_offset = builder.createBinOp( + spv::OpIAdd, type_uint, + builder.createBinOp( + spv::OpIMul, type_uint, + builder.makeUintConstant(tile_width_samples * tile_height_samples), + dest_tile_index), + builder.createBinOp( + spv::OpIAdd, type_uint, + builder.createBinOp(spv::OpIMul, type_uint, + builder.makeUintConstant(tile_width_samples), + dest_tile_sample_y), + dest_tile_sample_x)); + id_vector_temp.clear(); + // The only SSBO structure member. + id_vector_temp.push_back(builder.makeIntConstant(0)); + id_vector_temp.push_back( + builder.createUnaryOp(spv::OpBitcast, type_int, host_depth_offset)); + // StorageBuffer since SPIR-V 1.3, but since SPIR-V 1.0 is + // generated, it's Uniform. + host_depth32 = builder.createUnaryOp( + spv::OpBitcast, type_float, + builder.createLoad( + builder.createAccessChain(spv::StorageClassUniform, host_depth_source_buffer, + id_vector_temp), + spv::NoPrecision)); + } + spv::Block* depth24_to_depth32_header = builder.getBuildPoint(); + spv::Id depth24_to_depth32_convert_id = spv::NoResult; + spv::Block* depth24_to_depth32_merge = nullptr; + spv::Id host_depth24 = spv::NoResult; + if (host_depth32 != spv::NoResult) { + // Convert the host depth value to the guest format and check if it + // matches the value in the currently owning guest render target. + switch (dest_depth_format) { + case xenos::DepthRenderTargetFormat::kD24S8: { + // Round to the nearest even integer. This seems to be the + // correct conversion, adding +0.5 and rounding towards zero + // results in red instead of black in the 4D5307E6 clear shader. + host_depth24 = builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createUnaryBuiltinCall( + type_float, ext_inst_glsl_std_450, GLSLstd450RoundEven, + builder.createBinOp(spv::OpFMul, type_float, host_depth32, + builder.makeFloatConstant(float(0xFFFFFF))))); + } break; + case xenos::DepthRenderTargetFormat::kD24FS8: { + host_depth24 = SpirvShaderTranslator::PreClampedDepthTo20e4( + builder, host_depth32, depth_float24_round(), true, ext_inst_glsl_std_450); + } break; + } + assert_true(host_depth24 != spv::NoResult); + // Update the header block pointer after the conversion (to avoid + // assuming that the conversion doesn't branch). + depth24_to_depth32_header = builder.getBuildPoint(); + spv::Id host_depth_outdated = + builder.createBinOp(spv::OpINotEqual, type_bool, guest_depth24, host_depth24); + spv::Block& depth24_to_depth32_convert_entry = builder.makeNewBlock(); + { + spv::Block& depth24_to_depth32_merge_block = builder.makeNewBlock(); + depth24_to_depth32_merge = &depth24_to_depth32_merge_block; + } + builder.createSelectionMerge(depth24_to_depth32_merge, spv::SelectionControlMaskNone); + builder.createConditionalBranch(host_depth_outdated, &depth24_to_depth32_convert_entry, + depth24_to_depth32_merge); + builder.setBuildPoint(&depth24_to_depth32_convert_entry); + } + // Convert the guest 24-bit depth to float32 (in an open conditional + // if the host depth is also loaded). + spv::Id guest_depth32 = spv::NoResult; + switch (dest_depth_format) { + case xenos::DepthRenderTargetFormat::kD24S8: { + // Multiplying by 1.0 / 0xFFFFFF produces an incorrect result (for + // 0xC00000, for instance - which is 2_10_10_10 clear to 0001) - + // rescale from 0...0xFFFFFF to 0...0x1000000 doing what true + // float division followed by multiplication does (on x86-64 MSVC + // with default SSE rounding) - values starting from 0x800000 + // become bigger by 1; then accurately bias the result's exponent. + guest_depth32 = builder.createBinOp( + spv::OpFMul, type_float, + builder.createUnaryOp( + spv::OpConvertUToF, type_float, + builder.createBinOp( + spv::OpIAdd, type_uint, guest_depth24, + builder.createBinOp(spv::OpShiftRightLogical, type_uint, guest_depth24, + builder.makeUintConstant(23)))), + builder.makeFloatConstant(1.0f / float(1 << 24))); + } break; + case xenos::DepthRenderTargetFormat::kD24FS8: { + guest_depth32 = SpirvShaderTranslator::Depth20e4To32(builder, guest_depth24, 0, true, + false, ext_inst_glsl_std_450); + } break; + } + assert_true(guest_depth32 != spv::NoResult); + spv::Id fragment_depth32 = guest_depth32; + if (host_depth32 != spv::NoResult) { + assert_not_null(depth24_to_depth32_merge); + spv::Id depth24_to_depth32_result_block_id = builder.getBuildPoint()->getId(); + builder.createBranch(depth24_to_depth32_merge); + builder.setBuildPoint(depth24_to_depth32_merge); + id_vector_temp.clear(); + id_vector_temp.push_back(guest_depth32); + id_vector_temp.push_back(depth24_to_depth32_result_block_id); + id_vector_temp.push_back(host_depth32); + id_vector_temp.push_back(depth24_to_depth32_header->getId()); + fragment_depth32 = builder.createOp(spv::OpPhi, type_float, id_vector_temp); + } + builder.createStore(fragment_depth32, output_fragment_depth); + // Unpack the stencil into the stencil reference output if needed and + // not already written. + if (!packed_only_depth && output_fragment_stencil_ref != spv::NoResult) { + builder.createStore( + builder.createUnaryOp(spv::OpBitcast, type_int, + builder.createBinOp(spv::OpBitwiseAnd, type_uint, packed, + builder.makeUintConstant(UINT8_MAX))), + output_fragment_stencil_ref); + } + } + } break; + case TransferOutput::kStencilBit: { + if (packed) { + // Kill the sample if the needed stencil bit is not set. + assert_true(push_constants_member_stencil_mask != UINT32_MAX); + id_vector_temp.clear(); + id_vector_temp.push_back( + builder.makeIntConstant(int32_t(push_constants_member_stencil_mask))); + spv::Id stencil_mask_constant = + builder.createLoad(builder.createAccessChain(spv::StorageClassPushConstant, + push_constants, id_vector_temp), + spv::NoPrecision); + SpirvBuilder::IfBuilder stencil_kill_if( + builder.createBinOp( + spv::OpIEqual, type_bool, + builder.createBinOp(spv::OpBitwiseAnd, type_uint, packed, stencil_mask_constant), + builder.makeUintConstant(0)), + spv::SelectionControlMaskNone, builder); + builder.createNoResultOp(spv::OpKill); + // OpKill terminates the block. + stencil_kill_if.makeEndIf(false); + } + } break; + } + } + + // End the main function and make it the entry point. + builder.leaveFunction(); + builder.addExecutionMode(main_function, spv::ExecutionModeOriginUpperLeft); + if (output_fragment_depth != spv::NoResult) { + builder.addExecutionMode(main_function, spv::ExecutionModeDepthReplacing); + } + if (output_fragment_stencil_ref != spv::NoResult) { + builder.addExecutionMode(main_function, spv::ExecutionModeStencilRefReplacingEXT); + } + spv::Instruction* entry_point = + builder.addEntryPoint(spv::ExecutionModelFragment, main_function, "main"); + for (spv::Id interface_id : main_interface) { + entry_point->addIdOperand(interface_id); + } + + // Serialize the shader code. + std::vector shader_code; + builder.dump(shader_code); + + // Create the shader module, and store the handle even if creation fails not + // to try to create it again later. + VkShaderModule shader_module = ui::vulkan::util::CreateShaderModule( + vulkan_device, reinterpret_cast(shader_code.data()), + sizeof(uint32_t) * shader_code.size()); + if (shader_module == VK_NULL_HANDLE) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the render target ownership " + "transfer shader 0x{:08X}", + key.key); + } + transfer_shaders_.emplace(key, shader_module); + return shader_module; +} + +VkPipeline const* VulkanRenderTargetCache::GetTransferPipelines(TransferPipelineKey key) { + auto pipeline_it = transfer_pipelines_.find(key); + if (pipeline_it != transfer_pipelines_.end()) { + return pipeline_it->second[0] != VK_NULL_HANDLE ? pipeline_it->second.data() : nullptr; + } + + const TransferModeInfo& mode = kTransferModes[size_t(key.shader_key.mode)]; + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + const ui::vulkan::VulkanDevice::Properties& device_properties = vulkan_device->properties(); + bool use_dynamic_rendering = + REXCVAR_GET(vulkan_dynamic_rendering) && device_properties.dynamicRendering; + + VkRenderPass render_pass = VK_NULL_HANDLE; + if (!use_dynamic_rendering) { + render_pass = GetHostRenderTargetsRenderPass(key.render_pass_key); + if (render_pass == VK_NULL_HANDLE) { + transfer_pipelines_.emplace(key, std::array{}); + return nullptr; + } + } + + VkShaderModule fragment_shader_module = GetTransferShader(key.shader_key); + if (fragment_shader_module == VK_NULL_HANDLE) { + transfer_pipelines_.emplace(key, std::array{}); + return nullptr; + } + + uint32_t dest_sample_count = uint32_t(1) << uint32_t(key.shader_key.dest_msaa_samples); + bool dest_is_masked_sample = dest_sample_count > 1 && !device_properties.sampleRateShading; + + VkPipelineShaderStageCreateInfo shader_stages[2]; + shader_stages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shader_stages[0].pNext = nullptr; + shader_stages[0].flags = 0; + shader_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; + shader_stages[0].module = transfer_passthrough_vertex_shader_; + shader_stages[0].pName = "main"; + shader_stages[0].pSpecializationInfo = nullptr; + shader_stages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shader_stages[1].pNext = nullptr; + shader_stages[1].flags = 0; + shader_stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; + shader_stages[1].module = fragment_shader_module; + shader_stages[1].pName = "main"; + shader_stages[1].pSpecializationInfo = nullptr; + VkSpecializationMapEntry sample_id_specialization_map_entry; + uint32_t sample_id_specialization_constant; + VkSpecializationInfo sample_id_specialization_info; + if (dest_is_masked_sample) { + sample_id_specialization_map_entry.constantID = 0; + sample_id_specialization_map_entry.offset = 0; + sample_id_specialization_map_entry.size = sizeof(uint32_t); + sample_id_specialization_constant = 0; + sample_id_specialization_info.mapEntryCount = 1; + sample_id_specialization_info.pMapEntries = &sample_id_specialization_map_entry; + sample_id_specialization_info.dataSize = sizeof(sample_id_specialization_constant); + sample_id_specialization_info.pData = &sample_id_specialization_constant; + shader_stages[1].pSpecializationInfo = &sample_id_specialization_info; + } + + VkVertexInputBindingDescription vertex_input_binding; + vertex_input_binding.binding = 0; + vertex_input_binding.stride = sizeof(float) * 2; + vertex_input_binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; + VkVertexInputAttributeDescription vertex_input_attribute; + vertex_input_attribute.location = 0; + vertex_input_attribute.binding = 0; + vertex_input_attribute.format = VK_FORMAT_R32G32_SFLOAT; + vertex_input_attribute.offset = 0; + VkPipelineVertexInputStateCreateInfo vertex_input_state; + vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + vertex_input_state.pNext = nullptr; + vertex_input_state.flags = 0; + vertex_input_state.vertexBindingDescriptionCount = 1; + vertex_input_state.pVertexBindingDescriptions = &vertex_input_binding; + vertex_input_state.vertexAttributeDescriptionCount = 1; + vertex_input_state.pVertexAttributeDescriptions = &vertex_input_attribute; + + VkPipelineInputAssemblyStateCreateInfo input_assembly_state; + input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + input_assembly_state.pNext = nullptr; + input_assembly_state.flags = 0; + input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + input_assembly_state.primitiveRestartEnable = VK_FALSE; + + // Dynamic, to stay within maxViewportDimensions while preferring a + // power-of-two factor for converting from pixel coordinates to NDC for exact + // precision. + VkPipelineViewportStateCreateInfo viewport_state; + viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + viewport_state.pNext = nullptr; + viewport_state.flags = 0; + viewport_state.viewportCount = 1; + viewport_state.pViewports = nullptr; + viewport_state.scissorCount = 1; + viewport_state.pScissors = nullptr; + + VkPipelineRasterizationStateCreateInfo rasterization_state = {}; + rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rasterization_state.polygonMode = VK_POLYGON_MODE_FILL; + rasterization_state.cullMode = VK_CULL_MODE_NONE; + rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; + rasterization_state.lineWidth = 1.0f; + + // For samples other than the first, will be changed for the pipelines for + // other samples. + VkSampleMask sample_mask = UINT32_MAX; + VkPipelineMultisampleStateCreateInfo multisample_state = {}; + multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + multisample_state.rasterizationSamples = + (dest_sample_count == 2 && !msaa_2x_attachments_supported_) + ? VK_SAMPLE_COUNT_4_BIT + : VkSampleCountFlagBits(dest_sample_count); + if (dest_sample_count > 1) { + if (device_properties.sampleRateShading) { + multisample_state.sampleShadingEnable = VK_TRUE; + multisample_state.minSampleShading = 1.0f; + if (dest_sample_count == 2 && !msaa_2x_attachments_supported_) { + // Emulating 2x MSAA as samples 0 and 3 of 4x MSAA when 2x is not + // supported. + sample_mask = 0b1001; + } + } else { + sample_mask = 0b1; + } + if (sample_mask != UINT32_MAX) { + multisample_state.pSampleMask = &sample_mask; + } + } + + // Whether the depth / stencil state is used depends on the presence of a + // depth attachment in the render pass - but not making assumptions about + // whether the render pass contains any specific attachments, so setting up + // valid depth / stencil state unconditionally. + VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {}; + depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + if (mode.output == TransferOutput::kDepth) { + depth_stencil_state.depthTestEnable = VK_TRUE; + depth_stencil_state.depthWriteEnable = VK_TRUE; + depth_stencil_state.depthCompareOp = + REXCVAR_GET(depth_transfer_not_equal_test) ? VK_COMPARE_OP_NOT_EQUAL : VK_COMPARE_OP_ALWAYS; + } + if ((mode.output == TransferOutput::kDepth && + vulkan_device->extensions().ext_EXT_shader_stencil_export) || + mode.output == TransferOutput::kStencilBit) { + depth_stencil_state.stencilTestEnable = VK_TRUE; + depth_stencil_state.front.failOp = VK_STENCIL_OP_KEEP; + depth_stencil_state.front.passOp = VK_STENCIL_OP_REPLACE; + depth_stencil_state.front.depthFailOp = VK_STENCIL_OP_REPLACE; + // Using ALWAYS, not NOT_EQUAL, so depth writing is unaffected by stencil + // being different. + depth_stencil_state.front.compareOp = VK_COMPARE_OP_ALWAYS; + // Will be dynamic for stencil bit output. + depth_stencil_state.front.writeMask = UINT8_MAX; + depth_stencil_state.front.reference = UINT8_MAX; + depth_stencil_state.back = depth_stencil_state.front; + } + + // Whether the color blend state is used depends on the presence of color + // attachments in the render pass - but not making assumptions about whether + // the render pass contains any specific attachments, so setting up valid + // color blend state unconditionally. + VkPipelineColorBlendAttachmentState color_blend_attachments[xenos::kMaxColorRenderTargets] = {}; + VkPipelineColorBlendStateCreateInfo color_blend_state = {}; + color_blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + color_blend_state.attachmentCount = + 32 - rex::lzcnt(key.render_pass_key.depth_and_color_used >> 1); + color_blend_state.pAttachments = color_blend_attachments; + if (mode.output == TransferOutput::kColor) { + assert_true(device_properties.independentBlend); + color_blend_attachments[key.shader_key.dest_color_rt_index].colorWriteMask = + VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | + VK_COLOR_COMPONENT_A_BIT; + } + + VkPipelineRenderingCreateInfo pipeline_rendering_create_info = {}; + VkFormat color_attachment_format = VK_FORMAT_UNDEFINED; + VkFormat depth_attachment_format = VK_FORMAT_UNDEFINED; + VkFormat stencil_attachment_format = VK_FORMAT_UNDEFINED; + if (use_dynamic_rendering) { + pipeline_rendering_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO; + pipeline_rendering_create_info.pNext = nullptr; + pipeline_rendering_create_info.viewMask = 0; + if (key.render_pass_key.depth_and_color_used & 0b1) { + depth_attachment_format = GetDepthVulkanFormat(key.render_pass_key.depth_format); + stencil_attachment_format = depth_attachment_format; + pipeline_rendering_create_info.colorAttachmentCount = 0; + pipeline_rendering_create_info.pColorAttachmentFormats = nullptr; + } else { + color_attachment_format = + GetColorOwnershipTransferVulkanFormat(key.render_pass_key.color_0_view_format); + pipeline_rendering_create_info.colorAttachmentCount = 1; + pipeline_rendering_create_info.pColorAttachmentFormats = &color_attachment_format; + } + pipeline_rendering_create_info.depthAttachmentFormat = depth_attachment_format; + pipeline_rendering_create_info.stencilAttachmentFormat = stencil_attachment_format; + } + + std::array dynamic_states; + VkPipelineDynamicStateCreateInfo dynamic_state; + dynamic_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynamic_state.pNext = nullptr; + dynamic_state.flags = 0; + dynamic_state.dynamicStateCount = 0; + dynamic_state.pDynamicStates = dynamic_states.data(); + dynamic_states[dynamic_state.dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT; + dynamic_states[dynamic_state.dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR; + if (mode.output == TransferOutput::kStencilBit) { + dynamic_states[dynamic_state.dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK; + } + + std::array pipelines{}; + VkGraphicsPipelineCreateInfo pipeline_create_info; + pipeline_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipeline_create_info.pNext = use_dynamic_rendering ? &pipeline_rendering_create_info : nullptr; + pipeline_create_info.flags = 0; + if (dest_is_masked_sample) { + pipeline_create_info.flags |= VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT; + } + pipeline_create_info.stageCount = uint32_t(rex::countof(shader_stages)); + pipeline_create_info.pStages = shader_stages; + pipeline_create_info.pVertexInputState = &vertex_input_state; + pipeline_create_info.pInputAssemblyState = &input_assembly_state; + pipeline_create_info.pTessellationState = nullptr; + pipeline_create_info.pViewportState = &viewport_state; + pipeline_create_info.pRasterizationState = &rasterization_state; + pipeline_create_info.pMultisampleState = &multisample_state; + pipeline_create_info.pDepthStencilState = &depth_stencil_state; + pipeline_create_info.pColorBlendState = &color_blend_state; + pipeline_create_info.pDynamicState = &dynamic_state; + pipeline_create_info.layout = transfer_pipeline_layouts_[size_t(mode.pipeline_layout)]; + pipeline_create_info.renderPass = use_dynamic_rendering ? VK_NULL_HANDLE : render_pass; + pipeline_create_info.subpass = 0; + pipeline_create_info.basePipelineHandle = VK_NULL_HANDLE; + pipeline_create_info.basePipelineIndex = -1; + if (dfn.vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipeline_create_info, nullptr, + &pipelines[0]) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the render target ownership " + "transfer pipeline for render pass 0x{:08X}, shader 0x{:08X}", + key.render_pass_key.key, key.shader_key.key); + transfer_pipelines_.emplace(key, std::array{}); + return nullptr; + } + if (dest_is_masked_sample) { + assert_true(multisample_state.pSampleMask == &sample_mask); + pipeline_create_info.flags = + (pipeline_create_info.flags & ~VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT) | + VK_PIPELINE_CREATE_DERIVATIVE_BIT; + pipeline_create_info.basePipelineHandle = pipelines[0]; + for (uint32_t i = 1; i < dest_sample_count; ++i) { + // Emulating 2x MSAA as samples 0 and 3 of 4x MSAA when 2x is not + // supported. + uint32_t host_sample_index = + (dest_sample_count == 2 && !msaa_2x_attachments_supported_ && i == 1) ? 3 : i; + sample_id_specialization_constant = host_sample_index; + sample_mask = uint32_t(1) << host_sample_index; + if (dfn.vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipeline_create_info, nullptr, + &pipelines[i]) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create the render target " + "ownership transfer pipeline for render pass 0x{:08X}, shader " + "0x{:08X}, sample {}", + key.render_pass_key.key, key.shader_key.key, i); + for (uint32_t j = 0; j < i; ++j) { + dfn.vkDestroyPipeline(device, pipelines[j], nullptr); + } + transfer_pipelines_.emplace(key, std::array{}); + return nullptr; + } + } + } + return transfer_pipelines_.emplace(key, pipelines).first->second.data(); +} + +void VulkanRenderTargetCache::PerformTransfersAndResolveClears( + uint32_t render_target_count, RenderTarget* const* render_targets, + const std::vector* render_target_transfers, + const uint64_t* render_target_resolve_clear_values, + const Transfer::Rectangle* resolve_clear_rectangle) { + assert_true(GetPath() == Path::kHostRenderTargets); + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + uint64_t current_submission = command_processor_.GetCurrentSubmission(); + DeferredCommandBuffer& command_buffer = command_processor_.deferred_command_buffer(); + + bool resolve_clear_needed = render_target_resolve_clear_values && resolve_clear_rectangle; + VkClearRect resolve_clear_rect; + if (resolve_clear_needed) { + // Assuming the rectangle is already clamped by the setup function from the + // common render target cache. + resolve_clear_rect.rect.offset.x = + int32_t(resolve_clear_rectangle->x_pixels * draw_resolution_scale_x()); + resolve_clear_rect.rect.offset.y = + int32_t(resolve_clear_rectangle->y_pixels * draw_resolution_scale_y()); + resolve_clear_rect.rect.extent.width = + resolve_clear_rectangle->width_pixels * draw_resolution_scale_x(); + resolve_clear_rect.rect.extent.height = + resolve_clear_rectangle->height_pixels * draw_resolution_scale_y(); + resolve_clear_rect.baseArrayLayer = 0; + resolve_clear_rect.layerCount = 1; + } + + // Do host depth storing for the depth destination (assuming there can be only + // one depth destination) where depth destination == host depth source. + bool host_depth_store_set_up = false; + for (uint32_t i = 0; i < render_target_count; ++i) { + RenderTarget* dest_rt = render_targets[i]; + if (!dest_rt) { + continue; + } + auto& dest_vulkan_rt = *static_cast(dest_rt); + RenderTargetKey dest_rt_key = dest_vulkan_rt.key(); + if (!dest_rt_key.is_depth) { + continue; + } + const std::vector& depth_transfers = render_target_transfers[i]; + for (const Transfer& transfer : depth_transfers) { + if (transfer.host_depth_source != dest_rt) { + continue; + } + if (!host_depth_store_set_up) { + // Pipeline. + command_processor_.BindExternalComputePipeline( + host_depth_store_pipelines_[size_t(dest_rt_key.msaa_samples)]); + // Descriptor set bindings. + VkDescriptorSet host_depth_store_descriptor_sets[] = { + edram_storage_buffer_descriptor_set_, + dest_vulkan_rt.GetDescriptorSetTransferSource(), + }; + command_buffer.CmdVkBindDescriptorSets( + VK_PIPELINE_BIND_POINT_COMPUTE, host_depth_store_pipeline_layout_, 0, + uint32_t(rex::countof(host_depth_store_descriptor_sets)), + host_depth_store_descriptor_sets, 0, nullptr); + // Render target constant. + HostDepthStoreRenderTargetConstant host_depth_store_render_target_constant = + GetHostDepthStoreRenderTargetConstant(dest_rt_key.pitch_tiles_at_32bpp, + msaa_2x_attachments_supported_); + command_buffer.CmdVkPushConstants( + host_depth_store_pipeline_layout_, VK_SHADER_STAGE_COMPUTE_BIT, + uint32_t(offsetof(HostDepthStoreConstants, render_target)), + sizeof(host_depth_store_render_target_constant), + &host_depth_store_render_target_constant); + // Barriers - don't need to try to combine them with the rest of + // render target transfer barriers now - if this happens, after host + // depth storing, SHADER_READ -> DEPTH_STENCIL_ATTACHMENT_WRITE will be + // done anyway even in the best case, so it's not possible to have all + // the barriers in one place here. + UseEdramBuffer(EdramBufferUsage::kComputeWrite); + // Always transitioning both depth and stencil, not storing separate + // usage flags for depth and stencil. + command_processor_.PushImageMemoryBarrier( + dest_vulkan_rt.image(), + ui::vulkan::util::InitializeSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT | + VK_IMAGE_ASPECT_STENCIL_BIT), + dest_vulkan_rt.current_stage_mask(), VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + dest_vulkan_rt.current_access_mask(), VK_ACCESS_SHADER_READ_BIT, + dest_vulkan_rt.current_layout(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + dest_vulkan_rt.SetUsage(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + host_depth_store_set_up = true; + } + Transfer::Rectangle transfer_rectangles[Transfer::kMaxRectanglesWithCutout]; + uint32_t transfer_rectangle_count = transfer.GetRectangles( + dest_rt_key.base_tiles, dest_rt_key.pitch_tiles_at_32bpp, dest_rt_key.msaa_samples, false, + transfer_rectangles, resolve_clear_rectangle); + assert_not_zero(transfer_rectangle_count); + HostDepthStoreRectangleConstant host_depth_store_rectangle_constant; + for (uint32_t j = 0; j < transfer_rectangle_count; ++j) { + uint32_t group_count_x, group_count_y; + GetHostDepthStoreRectangleInfo(transfer_rectangles[j], dest_rt_key.msaa_samples, + host_depth_store_rectangle_constant, group_count_x, + group_count_y); + command_buffer.CmdVkPushConstants( + host_depth_store_pipeline_layout_, VK_SHADER_STAGE_COMPUTE_BIT, + uint32_t(offsetof(HostDepthStoreConstants, rectangle)), + sizeof(host_depth_store_rectangle_constant), &host_depth_store_rectangle_constant); + command_processor_.SubmitBarriers(true); + command_buffer.CmdVkDispatch(group_count_x, group_count_y, 1); + MarkEdramBufferModified(); + } + } + break; + } + + constexpr VkPipelineStageFlags kSourceStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + constexpr VkAccessFlags kSourceAccessMask = VK_ACCESS_SHADER_READ_BIT; + constexpr VkImageLayout kSourceLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + // Try to insert as many barriers as possible in one place, hoping that in the + // best case (no cross-copying between current render targets), barriers will + // need to be only inserted here, not between transfers. In case of + // cross-copying, if the destination use is going to happen before the source + // use, choose the destination state, otherwise the source state - to match + // the order in which transfers will actually happen (otherwise there will be + // just a useless switch back and forth). + for (uint32_t i = 0; i < render_target_count; ++i) { + RenderTarget* dest_rt = render_targets[i]; + if (!dest_rt) { + continue; + } + const std::vector& dest_transfers = render_target_transfers[i]; + if (!resolve_clear_needed && dest_transfers.empty()) { + continue; + } + // Transition the destination, only if not going to be used as a source + // earlier. + bool dest_used_previously_as_source = false; + for (uint32_t j = 0; j < i; ++j) { + for (const Transfer& previous_transfer : render_target_transfers[j]) { + if (previous_transfer.source == dest_rt || previous_transfer.host_depth_source == dest_rt) { + dest_used_previously_as_source = true; + break; + } + } + } + if (!dest_used_previously_as_source) { + auto& dest_vulkan_rt = *static_cast(dest_rt); + VkPipelineStageFlags dest_dst_stage_mask; + VkAccessFlags dest_dst_access_mask; + VkImageLayout dest_new_layout; + dest_vulkan_rt.GetDrawUsage(&dest_dst_stage_mask, &dest_dst_access_mask, &dest_new_layout); + command_processor_.PushImageMemoryBarrier( + dest_vulkan_rt.image(), + ui::vulkan::util::InitializeSubresourceRange( + dest_vulkan_rt.key().is_depth + ? (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) + : VK_IMAGE_ASPECT_COLOR_BIT), + dest_vulkan_rt.current_stage_mask(), dest_dst_stage_mask, + dest_vulkan_rt.current_access_mask(), dest_dst_access_mask, + dest_vulkan_rt.current_layout(), dest_new_layout); + dest_vulkan_rt.SetUsage(dest_dst_stage_mask, dest_dst_access_mask, dest_new_layout); + } + // Transition the sources, only if not going to be used as destinations + // earlier. + for (const Transfer& transfer : dest_transfers) { + bool source_previously_used_as_dest = false; + bool host_depth_source_previously_used_as_dest = false; + for (uint32_t j = 0; j < i; ++j) { + if (render_target_transfers[j].empty()) { + continue; + } + const RenderTarget* previous_rt = render_targets[j]; + if (transfer.source == previous_rt) { + source_previously_used_as_dest = true; + } + if (transfer.host_depth_source == previous_rt) { + host_depth_source_previously_used_as_dest = true; + } + } + if (!source_previously_used_as_dest) { + auto& source_vulkan_rt = *static_cast(transfer.source); + command_processor_.PushImageMemoryBarrier( + source_vulkan_rt.image(), + ui::vulkan::util::InitializeSubresourceRange( + source_vulkan_rt.key().is_depth + ? (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) + : VK_IMAGE_ASPECT_COLOR_BIT), + source_vulkan_rt.current_stage_mask(), kSourceStageMask, + source_vulkan_rt.current_access_mask(), kSourceAccessMask, + source_vulkan_rt.current_layout(), kSourceLayout); + source_vulkan_rt.SetUsage(kSourceStageMask, kSourceAccessMask, kSourceLayout); + } + // transfer.host_depth_source == dest_rt means the EDRAM buffer will be + // used instead, no need to transition. + if (transfer.host_depth_source && transfer.host_depth_source != dest_rt && + !host_depth_source_previously_used_as_dest) { + auto& host_depth_source_vulkan_rt = + *static_cast(transfer.host_depth_source); + command_processor_.PushImageMemoryBarrier( + host_depth_source_vulkan_rt.image(), + ui::vulkan::util::InitializeSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT | + VK_IMAGE_ASPECT_STENCIL_BIT), + host_depth_source_vulkan_rt.current_stage_mask(), kSourceStageMask, + host_depth_source_vulkan_rt.current_access_mask(), kSourceAccessMask, + host_depth_source_vulkan_rt.current_layout(), kSourceLayout); + host_depth_source_vulkan_rt.SetUsage(kSourceStageMask, kSourceAccessMask, kSourceLayout); + } + } + } + if (host_depth_store_set_up) { + // Will be reading copied host depth from the EDRAM buffer. + UseEdramBuffer(EdramBufferUsage::kFragmentRead); + } + + // Perform the transfers and clears. + + TransferPipelineLayoutIndex last_transfer_pipeline_layout_index = + TransferPipelineLayoutIndex::kCount; + uint32_t transfer_descriptor_sets_bound = 0; + uint32_t transfer_push_constants_set = 0; + VkDescriptorSet last_descriptor_set_host_depth_stencil_textures = VK_NULL_HANDLE; + VkDescriptorSet last_descriptor_set_depth_stencil_textures = VK_NULL_HANDLE; + VkDescriptorSet last_descriptor_set_color_texture = VK_NULL_HANDLE; + TransferAddressConstant last_host_depth_address_constant; + TransferAddressConstant last_address_constant; + + for (uint32_t i = 0; i < render_target_count; ++i) { + RenderTarget* dest_rt = render_targets[i]; + if (!dest_rt) { + continue; + } + + const std::vector& current_transfers = render_target_transfers[i]; + if (current_transfers.empty() && !resolve_clear_needed) { + continue; + } + + auto& dest_vulkan_rt = *static_cast(dest_rt); + RenderTargetKey dest_rt_key = dest_vulkan_rt.key(); + + // Late barriers in case there was cross-copying that prevented merging of + // barriers. + { + VkPipelineStageFlags dest_dst_stage_mask; + VkAccessFlags dest_dst_access_mask; + VkImageLayout dest_new_layout; + dest_vulkan_rt.GetDrawUsage(&dest_dst_stage_mask, &dest_dst_access_mask, &dest_new_layout); + command_processor_.PushImageMemoryBarrier( + dest_vulkan_rt.image(), + ui::vulkan::util::InitializeSubresourceRange( + dest_rt_key.is_depth ? (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) + : VK_IMAGE_ASPECT_COLOR_BIT), + dest_vulkan_rt.current_stage_mask(), dest_dst_stage_mask, + dest_vulkan_rt.current_access_mask(), dest_dst_access_mask, + dest_vulkan_rt.current_layout(), dest_new_layout); + dest_vulkan_rt.SetUsage(dest_dst_stage_mask, dest_dst_access_mask, dest_new_layout); + } + + // Get the objects needed for transfers to the destination. + // TODO(Triang3l): Reuse the guest render pass for transfers where possible + // (if the Vulkan format used for drawing is also usable for transfers - for + // instance, R8G8B8A8_UNORM can be used for both, so the guest pass can be + // reused, but R16G16B16A16_SFLOAT render targets use R16G16B16A16_UINT for + // transfers, so the transfer pass has to be separate) to avoid stores and + // loads on tile-based devices to make this actually applicable. Also + // overall perform all non-cross-copying transfers for the current + // framebuffer configuration in a single pass, to load / store only once. + RenderPassKey transfer_render_pass_key; + transfer_render_pass_key.msaa_samples = dest_rt_key.msaa_samples; + if (dest_rt_key.is_depth) { + transfer_render_pass_key.depth_and_color_used = 0b1; + transfer_render_pass_key.depth_format = dest_rt_key.GetDepthFormat(); + } else { + transfer_render_pass_key.depth_and_color_used = 0b1 << 1; + transfer_render_pass_key.color_0_view_format = dest_rt_key.GetColorFormat(); + transfer_render_pass_key.color_rts_use_transfer_formats = 1; + } + VkRenderPass transfer_render_pass = GetHostRenderTargetsRenderPass(transfer_render_pass_key); + if (transfer_render_pass == VK_NULL_HANDLE) { + continue; + } + const RenderTarget* transfer_framebuffer_render_targets[1 + xenos::kMaxColorRenderTargets] = {}; + transfer_framebuffer_render_targets[dest_rt_key.is_depth ? 0 : 1] = dest_rt; + const Framebuffer* transfer_framebuffer = + GetHostRenderTargetsFramebuffer(transfer_render_pass_key, dest_rt_key.pitch_tiles_at_32bpp, + transfer_framebuffer_render_targets); + if (!transfer_framebuffer) { + continue; + } + // Don't enter the render pass immediately - may still insert source + // barriers later. + VkImageView transfer_dest_view = dest_rt_key.is_depth ? dest_vulkan_rt.view_depth_stencil() + : dest_vulkan_rt.view_color_transfer(); + + if (!current_transfers.empty()) { + uint32_t dest_pitch_tiles = dest_rt_key.GetPitchTiles(); + bool dest_is_64bpp = dest_rt_key.Is64bpp(); + + // Gather shader keys and sort to reduce pipeline state and binding + // switches. Also gather stencil rectangles to clear if needed. + bool need_stencil_bit_draws = + dest_rt_key.is_depth && !vulkan_device->extensions().ext_EXT_shader_stencil_export; + current_transfer_invocations_.clear(); + current_transfer_invocations_.reserve(current_transfers.size() + << uint32_t(need_stencil_bit_draws)); + uint32_t rt_sort_index = 0; + TransferShaderKey new_transfer_shader_key; + new_transfer_shader_key.dest_msaa_samples = dest_rt_key.msaa_samples; + new_transfer_shader_key.dest_resource_format = dest_rt_key.resource_format; + uint32_t stencil_clear_rectangle_count = 0; + for (uint32_t j = 0; j <= uint32_t(need_stencil_bit_draws); ++j) { + // j == 0 - color or depth. + // j == 1 - stencil bits. + // Stencil bit writing always requires a different root signature, + // handle these separately. Stencil never has a host depth source. + // Clear previously set sort indices. + for (const Transfer& transfer : current_transfers) { + auto host_depth_source_vulkan_rt = + static_cast(transfer.host_depth_source); + if (host_depth_source_vulkan_rt) { + host_depth_source_vulkan_rt->SetTemporarySortIndex(UINT32_MAX); + } + assert_not_null(transfer.source); + auto& source_vulkan_rt = *static_cast(transfer.source); + source_vulkan_rt.SetTemporarySortIndex(UINT32_MAX); + } + for (const Transfer& transfer : current_transfers) { + assert_not_null(transfer.source); + auto& source_vulkan_rt = *static_cast(transfer.source); + VulkanRenderTarget* host_depth_source_vulkan_rt = + j ? nullptr : static_cast(transfer.host_depth_source); + if (host_depth_source_vulkan_rt && + host_depth_source_vulkan_rt->temporary_sort_index() == UINT32_MAX) { + host_depth_source_vulkan_rt->SetTemporarySortIndex(rt_sort_index++); + } + if (source_vulkan_rt.temporary_sort_index() == UINT32_MAX) { + source_vulkan_rt.SetTemporarySortIndex(rt_sort_index++); + } + RenderTargetKey source_rt_key = source_vulkan_rt.key(); + new_transfer_shader_key.source_msaa_samples = source_rt_key.msaa_samples; + new_transfer_shader_key.source_resource_format = source_rt_key.resource_format; + bool host_depth_source_is_copy = host_depth_source_vulkan_rt == &dest_vulkan_rt; + // The host depth copy buffer has only raw samples. + new_transfer_shader_key.host_depth_source_msaa_samples = + (host_depth_source_vulkan_rt && !host_depth_source_is_copy) + ? host_depth_source_vulkan_rt->key().msaa_samples + : xenos::MsaaSamples::k1X; + if (j) { + new_transfer_shader_key.mode = source_rt_key.is_depth + ? TransferMode::kDepthToStencilBit + : TransferMode::kColorToStencilBit; + stencil_clear_rectangle_count += transfer.GetRectangles( + dest_rt_key.base_tiles, dest_pitch_tiles, dest_rt_key.msaa_samples, dest_is_64bpp, + nullptr, resolve_clear_rectangle); + } else { + if (dest_rt_key.is_depth) { + if (host_depth_source_vulkan_rt) { + if (host_depth_source_is_copy) { + new_transfer_shader_key.mode = source_rt_key.is_depth + ? TransferMode::kDepthAndHostDepthCopyToDepth + : TransferMode::kColorAndHostDepthCopyToDepth; + } else { + new_transfer_shader_key.mode = source_rt_key.is_depth + ? TransferMode::kDepthAndHostDepthToDepth + : TransferMode::kColorAndHostDepthToDepth; + } + } else { + new_transfer_shader_key.mode = source_rt_key.is_depth ? TransferMode::kDepthToDepth + : TransferMode::kColorToDepth; + } + } else { + new_transfer_shader_key.mode = source_rt_key.is_depth ? TransferMode::kDepthToColor + : TransferMode::kColorToColor; + } + } + current_transfer_invocations_.emplace_back(transfer, new_transfer_shader_key); + if (j) { + current_transfer_invocations_.back().transfer.host_depth_source = nullptr; + } + } + } + std::sort(current_transfer_invocations_.begin(), current_transfer_invocations_.end()); + + for (auto it = current_transfer_invocations_.cbegin(); + it != current_transfer_invocations_.cend(); ++it) { + assert_not_null(it->transfer.source); + auto& source_vulkan_rt = *static_cast(it->transfer.source); + command_processor_.PushImageMemoryBarrier( + source_vulkan_rt.image(), + ui::vulkan::util::InitializeSubresourceRange( + source_vulkan_rt.key().is_depth + ? (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) + : VK_IMAGE_ASPECT_COLOR_BIT), + source_vulkan_rt.current_stage_mask(), kSourceStageMask, + source_vulkan_rt.current_access_mask(), kSourceAccessMask, + source_vulkan_rt.current_layout(), kSourceLayout); + source_vulkan_rt.SetUsage(kSourceStageMask, kSourceAccessMask, kSourceLayout); + auto host_depth_source_vulkan_rt = + static_cast(it->transfer.host_depth_source); + if (host_depth_source_vulkan_rt) { + TransferShaderKey transfer_shader_key = it->shader_key; + if (transfer_shader_key.mode == TransferMode::kDepthAndHostDepthCopyToDepth || + transfer_shader_key.mode == TransferMode::kColorAndHostDepthCopyToDepth) { + // Reading copied host depth from the EDRAM buffer. + UseEdramBuffer(EdramBufferUsage::kFragmentRead); + } else { + // Reading host depth from the texture. + command_processor_.PushImageMemoryBarrier( + host_depth_source_vulkan_rt->image(), + ui::vulkan::util::InitializeSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT | + VK_IMAGE_ASPECT_STENCIL_BIT), + host_depth_source_vulkan_rt->current_stage_mask(), kSourceStageMask, + host_depth_source_vulkan_rt->current_access_mask(), kSourceAccessMask, + host_depth_source_vulkan_rt->current_layout(), kSourceLayout); + host_depth_source_vulkan_rt->SetUsage(kSourceStageMask, kSourceAccessMask, + kSourceLayout); + } + } + } + + // Perform the transfers for the render target. + + command_processor_.SubmitBarriersAndEnterRenderTargetCacheRenderPass( + transfer_render_pass, transfer_framebuffer, transfer_dest_view, dest_rt_key.is_depth); + + if (stencil_clear_rectangle_count) { + VkClearAttachment* stencil_clear_attachment; + VkClearRect* stencil_clear_rect_write_ptr; + command_buffer.CmdClearAttachmentsEmplace(1, stencil_clear_attachment, + stencil_clear_rectangle_count, + stencil_clear_rect_write_ptr); + stencil_clear_attachment->aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; + stencil_clear_attachment->colorAttachment = 0; + stencil_clear_attachment->clearValue.depthStencil.depth = 0.0f; + stencil_clear_attachment->clearValue.depthStencil.stencil = 0; + for (const Transfer& transfer : current_transfers) { + Transfer::Rectangle transfer_stencil_clear_rectangles[Transfer::kMaxRectanglesWithCutout]; + uint32_t transfer_stencil_clear_rectangle_count = transfer.GetRectangles( + dest_rt_key.base_tiles, dest_pitch_tiles, dest_rt_key.msaa_samples, dest_is_64bpp, + transfer_stencil_clear_rectangles, resolve_clear_rectangle); + for (uint32_t j = 0; j < transfer_stencil_clear_rectangle_count; ++j) { + const Transfer::Rectangle& stencil_clear_rectangle = + transfer_stencil_clear_rectangles[j]; + stencil_clear_rect_write_ptr->rect.offset.x = + int32_t(stencil_clear_rectangle.x_pixels * draw_resolution_scale_x()); + stencil_clear_rect_write_ptr->rect.offset.y = + int32_t(stencil_clear_rectangle.y_pixels * draw_resolution_scale_y()); + stencil_clear_rect_write_ptr->rect.extent.width = + stencil_clear_rectangle.width_pixels * draw_resolution_scale_x(); + stencil_clear_rect_write_ptr->rect.extent.height = + stencil_clear_rectangle.height_pixels * draw_resolution_scale_y(); + stencil_clear_rect_write_ptr->baseArrayLayer = 0; + stencil_clear_rect_write_ptr->layerCount = 1; + ++stencil_clear_rect_write_ptr; + } + } + } + + // Prefer power of two viewports for exact division by simply biasing the + // exponent. + VkViewport transfer_viewport; + transfer_viewport.x = 0.0f; + transfer_viewport.y = 0.0f; + transfer_viewport.width = + float(std::min(rex::next_pow2(transfer_framebuffer->host_extent.width), + vulkan_device->properties().maxViewportDimensions[0])); + transfer_viewport.height = + float(std::min(rex::next_pow2(transfer_framebuffer->host_extent.height), + vulkan_device->properties().maxViewportDimensions[1])); + transfer_viewport.minDepth = 0.0f; + transfer_viewport.maxDepth = 1.0f; + command_processor_.SetViewport(transfer_viewport); + float pixels_to_ndc_x = (2.0f / transfer_viewport.width) * float(draw_resolution_scale_x()); + float pixels_to_ndc_y = (2.0f / transfer_viewport.height) * float(draw_resolution_scale_y()); + VkRect2D transfer_scissor; + transfer_scissor.offset.x = 0; + transfer_scissor.offset.y = 0; + transfer_scissor.extent = transfer_framebuffer->host_extent; + command_processor_.SetScissor(transfer_scissor); + + for (auto it = current_transfer_invocations_.cbegin(); + it != current_transfer_invocations_.cend(); ++it) { + const TransferInvocation& transfer_invocation_first = *it; + // Will be merging transfers from the same source into one mesh. + auto it_merged_first = it, it_merged_last = it; + uint32_t transfer_rectangle_count = transfer_invocation_first.transfer.GetRectangles( + dest_rt_key.base_tiles, dest_pitch_tiles, dest_rt_key.msaa_samples, dest_is_64bpp, + nullptr, resolve_clear_rectangle); + for (auto it_merge = std::next(it_merged_first); + it_merge != current_transfer_invocations_.cend(); ++it_merge) { + if (!transfer_invocation_first.CanBeMergedIntoOneDraw(*it_merge)) { + break; + } + transfer_rectangle_count += it_merge->transfer.GetRectangles( + dest_rt_key.base_tiles, dest_pitch_tiles, dest_rt_key.msaa_samples, dest_is_64bpp, + nullptr, resolve_clear_rectangle); + it_merged_last = it_merge; + } + assert_not_zero(transfer_rectangle_count); + // Skip the merged transfers in the subsequent iterations. + it = it_merged_last; + + assert_not_null(it->transfer.source); + auto& source_vulkan_rt = *static_cast(it->transfer.source); + auto host_depth_source_vulkan_rt = + static_cast(it->transfer.host_depth_source); + TransferShaderKey transfer_shader_key = it->shader_key; + const TransferModeInfo& transfer_mode_info = + kTransferModes[size_t(transfer_shader_key.mode)]; + TransferPipelineLayoutIndex transfer_pipeline_layout_index = + transfer_mode_info.pipeline_layout; + const TransferPipelineLayoutInfo& transfer_pipeline_layout_info = + kTransferPipelineLayoutInfos[size_t(transfer_pipeline_layout_index)]; + uint32_t transfer_sample_pipeline_count = vulkan_device->properties().sampleRateShading + ? 1 + : uint32_t(1) + << uint32_t(dest_rt_key.msaa_samples); + bool transfer_is_stencil_bit = (transfer_pipeline_layout_info.used_push_constant_dwords & + kTransferUsedPushConstantDwordStencilMaskBit) != 0; + + uint32_t transfer_vertex_count = 6 * transfer_rectangle_count; + VkBuffer transfer_vertex_buffer; + VkDeviceSize transfer_vertex_buffer_offset; + float* transfer_rectangle_write_ptr = + reinterpret_cast(transfer_vertex_buffer_pool_->Request( + current_submission, sizeof(float) * 2 * transfer_vertex_count, sizeof(float), + transfer_vertex_buffer, transfer_vertex_buffer_offset)); + if (!transfer_rectangle_write_ptr) { + continue; + } + for (auto it_merged = it_merged_first; it_merged <= it_merged_last; ++it_merged) { + Transfer::Rectangle transfer_invocation_rectangles[Transfer::kMaxRectanglesWithCutout]; + uint32_t transfer_invocation_rectangle_count = it_merged->transfer.GetRectangles( + dest_rt_key.base_tiles, dest_pitch_tiles, dest_rt_key.msaa_samples, dest_is_64bpp, + transfer_invocation_rectangles, resolve_clear_rectangle); + assert_not_zero(transfer_invocation_rectangle_count); + for (uint32_t j = 0; j < transfer_invocation_rectangle_count; ++j) { + const Transfer::Rectangle& transfer_rectangle = transfer_invocation_rectangles[j]; + float transfer_rectangle_x0 = -1.0f + transfer_rectangle.x_pixels * pixels_to_ndc_x; + float transfer_rectangle_y0 = -1.0f + transfer_rectangle.y_pixels * pixels_to_ndc_y; + float transfer_rectangle_x1 = + transfer_rectangle_x0 + transfer_rectangle.width_pixels * pixels_to_ndc_x; + float transfer_rectangle_y1 = + transfer_rectangle_y0 + transfer_rectangle.height_pixels * pixels_to_ndc_y; + // O-* + // |/ + // * + *(transfer_rectangle_write_ptr++) = transfer_rectangle_x0; + *(transfer_rectangle_write_ptr++) = transfer_rectangle_y0; + // *-* + // |/ + // O + *(transfer_rectangle_write_ptr++) = transfer_rectangle_x0; + *(transfer_rectangle_write_ptr++) = transfer_rectangle_y1; + // *-O + // |/ + // * + *(transfer_rectangle_write_ptr++) = transfer_rectangle_x1; + *(transfer_rectangle_write_ptr++) = transfer_rectangle_y0; + // O + // /| + // *-* + *(transfer_rectangle_write_ptr++) = transfer_rectangle_x1; + *(transfer_rectangle_write_ptr++) = transfer_rectangle_y0; + // * + // /| + // O-* + *(transfer_rectangle_write_ptr++) = transfer_rectangle_x0; + *(transfer_rectangle_write_ptr++) = transfer_rectangle_y1; + // * + // /| + // *-O + *(transfer_rectangle_write_ptr++) = transfer_rectangle_x1; + *(transfer_rectangle_write_ptr++) = transfer_rectangle_y1; + } + } + command_buffer.CmdVkBindVertexBuffers(0, 1, &transfer_vertex_buffer, + &transfer_vertex_buffer_offset); + + const VkPipeline* transfer_pipelines = GetTransferPipelines( + TransferPipelineKey(transfer_render_pass_key, transfer_shader_key)); + if (!transfer_pipelines) { + continue; + } + command_processor_.BindExternalGraphicsPipeline(transfer_pipelines[0]); + if (last_transfer_pipeline_layout_index != transfer_pipeline_layout_index) { + last_transfer_pipeline_layout_index = transfer_pipeline_layout_index; + transfer_descriptor_sets_bound = 0; + transfer_push_constants_set = 0; + } + + // Invalidate outdated bindings. + if (transfer_pipeline_layout_info.used_descriptor_sets & + kTransferUsedDescriptorSetHostDepthStencilTexturesBit) { + assert_not_null(host_depth_source_vulkan_rt); + VkDescriptorSet descriptor_set_host_depth_stencil_textures = + host_depth_source_vulkan_rt->GetDescriptorSetTransferSource(); + if (last_descriptor_set_host_depth_stencil_textures != + descriptor_set_host_depth_stencil_textures) { + last_descriptor_set_host_depth_stencil_textures = + descriptor_set_host_depth_stencil_textures; + transfer_descriptor_sets_bound &= + ~kTransferUsedDescriptorSetHostDepthStencilTexturesBit; + } + } + if (transfer_pipeline_layout_info.used_descriptor_sets & + kTransferUsedDescriptorSetDepthStencilTexturesBit) { + VkDescriptorSet descriptor_set_depth_stencil_textures = + source_vulkan_rt.GetDescriptorSetTransferSource(); + if (last_descriptor_set_depth_stencil_textures != descriptor_set_depth_stencil_textures) { + last_descriptor_set_depth_stencil_textures = descriptor_set_depth_stencil_textures; + transfer_descriptor_sets_bound &= ~kTransferUsedDescriptorSetDepthStencilTexturesBit; + } + } + if (transfer_pipeline_layout_info.used_descriptor_sets & + kTransferUsedDescriptorSetColorTextureBit) { + VkDescriptorSet descriptor_set_color_texture = + source_vulkan_rt.GetDescriptorSetTransferSource(); + if (last_descriptor_set_color_texture != descriptor_set_color_texture) { + last_descriptor_set_color_texture = descriptor_set_color_texture; + transfer_descriptor_sets_bound &= ~kTransferUsedDescriptorSetColorTextureBit; + } + } + if (transfer_pipeline_layout_info.used_push_constant_dwords & + kTransferUsedPushConstantDwordHostDepthAddressBit) { + assert_not_null(host_depth_source_vulkan_rt); + RenderTargetKey host_depth_source_rt_key = host_depth_source_vulkan_rt->key(); + TransferAddressConstant host_depth_address_constant; + host_depth_address_constant.dest_pitch = dest_pitch_tiles; + host_depth_address_constant.source_pitch = host_depth_source_rt_key.GetPitchTiles(); + host_depth_address_constant.source_to_dest = + int32_t(dest_rt_key.base_tiles) - int32_t(host_depth_source_rt_key.base_tiles); + if (last_host_depth_address_constant != host_depth_address_constant) { + last_host_depth_address_constant = host_depth_address_constant; + transfer_push_constants_set &= ~kTransferUsedPushConstantDwordHostDepthAddressBit; + } + } + if (transfer_pipeline_layout_info.used_push_constant_dwords & + kTransferUsedPushConstantDwordAddressBit) { + RenderTargetKey source_rt_key = source_vulkan_rt.key(); + TransferAddressConstant address_constant; + address_constant.dest_pitch = dest_pitch_tiles; + address_constant.source_pitch = source_rt_key.GetPitchTiles(); + address_constant.source_to_dest = + int32_t(dest_rt_key.base_tiles) - int32_t(source_rt_key.base_tiles); + if (last_address_constant != address_constant) { + last_address_constant = address_constant; + transfer_push_constants_set &= ~kTransferUsedPushConstantDwordAddressBit; + } + } + + // Apply the new bindings. + // TODO(Triang3l): Merge binding updates into spans. + VkPipelineLayout transfer_pipeline_layout = + transfer_pipeline_layouts_[size_t(transfer_pipeline_layout_index)]; + uint32_t transfer_descriptor_sets_unbound = + transfer_pipeline_layout_info.used_descriptor_sets & ~transfer_descriptor_sets_bound; + if (transfer_descriptor_sets_unbound & kTransferUsedDescriptorSetHostDepthBufferBit) { + command_buffer.CmdVkBindDescriptorSets( + VK_PIPELINE_BIND_POINT_GRAPHICS, transfer_pipeline_layout, + rex::bit_count(transfer_pipeline_layout_info.used_descriptor_sets & + (kTransferUsedDescriptorSetHostDepthBufferBit - 1)), + 1, &edram_storage_buffer_descriptor_set_, 0, nullptr); + transfer_descriptor_sets_bound |= kTransferUsedDescriptorSetHostDepthBufferBit; + } + if (transfer_descriptor_sets_unbound & + kTransferUsedDescriptorSetHostDepthStencilTexturesBit) { + command_buffer.CmdVkBindDescriptorSets( + VK_PIPELINE_BIND_POINT_GRAPHICS, transfer_pipeline_layout, + rex::bit_count(transfer_pipeline_layout_info.used_descriptor_sets & + (kTransferUsedDescriptorSetHostDepthStencilTexturesBit - 1)), + 1, &last_descriptor_set_host_depth_stencil_textures, 0, nullptr); + transfer_descriptor_sets_bound |= kTransferUsedDescriptorSetHostDepthStencilTexturesBit; + } + if (transfer_descriptor_sets_unbound & kTransferUsedDescriptorSetDepthStencilTexturesBit) { + command_buffer.CmdVkBindDescriptorSets( + VK_PIPELINE_BIND_POINT_GRAPHICS, transfer_pipeline_layout, + rex::bit_count(transfer_pipeline_layout_info.used_descriptor_sets & + (kTransferUsedDescriptorSetDepthStencilTexturesBit - 1)), + 1, &last_descriptor_set_depth_stencil_textures, 0, nullptr); + transfer_descriptor_sets_bound |= kTransferUsedDescriptorSetDepthStencilTexturesBit; + } + if (transfer_descriptor_sets_unbound & kTransferUsedDescriptorSetColorTextureBit) { + command_buffer.CmdVkBindDescriptorSets( + VK_PIPELINE_BIND_POINT_GRAPHICS, transfer_pipeline_layout, + rex::bit_count(transfer_pipeline_layout_info.used_descriptor_sets & + (kTransferUsedDescriptorSetColorTextureBit - 1)), + 1, &last_descriptor_set_color_texture, 0, nullptr); + transfer_descriptor_sets_bound |= kTransferUsedDescriptorSetColorTextureBit; + } + uint32_t transfer_push_constants_unset = + transfer_pipeline_layout_info.used_push_constant_dwords & ~transfer_push_constants_set; + if (transfer_push_constants_unset & kTransferUsedPushConstantDwordHostDepthAddressBit) { + command_buffer.CmdVkPushConstants( + transfer_pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT, + sizeof(uint32_t) * + rex::bit_count(transfer_pipeline_layout_info.used_push_constant_dwords & + (kTransferUsedPushConstantDwordHostDepthAddressBit - 1)), + sizeof(uint32_t), &last_host_depth_address_constant); + transfer_push_constants_set |= kTransferUsedPushConstantDwordHostDepthAddressBit; + } + if (transfer_push_constants_unset & kTransferUsedPushConstantDwordAddressBit) { + command_buffer.CmdVkPushConstants( + transfer_pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT, + sizeof(uint32_t) * + rex::bit_count(transfer_pipeline_layout_info.used_push_constant_dwords & + (kTransferUsedPushConstantDwordAddressBit - 1)), + sizeof(uint32_t), &last_address_constant); + transfer_push_constants_set |= kTransferUsedPushConstantDwordAddressBit; + } + + for (uint32_t j = 0; j < transfer_sample_pipeline_count; ++j) { + if (j) { + command_processor_.BindExternalGraphicsPipeline(transfer_pipelines[j]); + } + for (uint32_t k = 0; k < uint32_t(transfer_is_stencil_bit ? 8 : 1); ++k) { + if (transfer_is_stencil_bit) { + uint32_t transfer_stencil_bit = uint32_t(1) << k; + command_buffer.CmdVkPushConstants( + transfer_pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT, + sizeof(uint32_t) * + rex::bit_count(transfer_pipeline_layout_info.used_push_constant_dwords & + (kTransferUsedPushConstantDwordStencilMaskBit - 1)), + sizeof(uint32_t), &transfer_stencil_bit); + command_buffer.CmdVkSetStencilWriteMask(VK_STENCIL_FACE_FRONT_AND_BACK, + transfer_stencil_bit); + } + command_buffer.CmdVkDraw(transfer_vertex_count, 1, 0, 0); + } + } + } + } + + // Perform the clear. + if (resolve_clear_needed) { + command_processor_.SubmitBarriersAndEnterRenderTargetCacheRenderPass( + transfer_render_pass, transfer_framebuffer, transfer_dest_view, dest_rt_key.is_depth); + VkClearAttachment resolve_clear_attachment; + resolve_clear_attachment.colorAttachment = 0; + std::memset(&resolve_clear_attachment.clearValue, 0, + sizeof(resolve_clear_attachment.clearValue)); + uint64_t clear_value = render_target_resolve_clear_values[i]; + if (dest_rt_key.is_depth) { + resolve_clear_attachment.aspectMask = + VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + uint32_t depth_guest_clear_value = (uint32_t(clear_value) >> 8) & 0xFFFFFF; + switch (dest_rt_key.GetDepthFormat()) { + case xenos::DepthRenderTargetFormat::kD24S8: + resolve_clear_attachment.clearValue.depthStencil.depth = + xenos::UNorm24To32(depth_guest_clear_value); + break; + case xenos::DepthRenderTargetFormat::kD24FS8: + // Taking [0, 2) -> [0, 1) remapping into account. + resolve_clear_attachment.clearValue.depthStencil.depth = + xenos::Float20e4To32(depth_guest_clear_value) * 0.5f; + break; + } + resolve_clear_attachment.clearValue.depthStencil.stencil = uint32_t(clear_value) & 0xFF; + } else { + resolve_clear_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + bool dest_color_transfer_is_uint = false; + GetColorOwnershipTransferVulkanFormat( + dest_rt_key.GetColorFormat(), dest_rt_key.msaa_samples, &dest_color_transfer_is_uint); + switch (dest_rt_key.GetColorFormat()) { + case xenos::ColorRenderTargetFormat::k_8_8_8_8: + case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA: { + for (uint32_t j = 0; j < 4; ++j) { + resolve_clear_attachment.clearValue.color.float32[j] = + ((clear_value >> (j * 8)) & 0xFF) * (1.0f / 0xFF); + } + if (dest_rt_key.GetColorFormat() == xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA && + gamma_render_target_as_unorm16_) { + // 8_8_8_8_GAMMA is represented by linear stored in + // R16G16B16A16_UNORM. + for (uint32_t j = 0; j < 3; ++j) { + resolve_clear_attachment.clearValue.color.float32[j] = + xenos::PWLGammaToLinear(resolve_clear_attachment.clearValue.color.float32[j]); + } + } + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: { + for (uint32_t j = 0; j < 3; ++j) { + resolve_clear_attachment.clearValue.color.float32[j] = + ((clear_value >> (j * 10)) & 0x3FF) * (1.0f / 0x3FF); + } + resolve_clear_attachment.clearValue.color.float32[3] = + ((clear_value >> 30) & 0x3) * (1.0f / 0x3); + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16: { + for (uint32_t j = 0; j < 3; ++j) { + resolve_clear_attachment.clearValue.color.float32[j] = + xenos::Float7e3To32((clear_value >> (j * 10)) & 0x3FF); + } + resolve_clear_attachment.clearValue.color.float32[3] = + ((clear_value >> 30) & 0x3) * (1.0f / 0x3); + } break; + case xenos::ColorRenderTargetFormat::k_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_FLOAT: { + // Using uint for transfers and clears of both. Disregarding the + // current -32...32 vs. -1...1 settings for consistency with color + // clear via depth aliasing. + for (uint32_t j = 0; j < 2; ++j) { + uint16_t component = uint16_t((clear_value >> (j * 16)) & 0xFFFF); + if (dest_color_transfer_is_uint) { + resolve_clear_attachment.clearValue.color.uint32[j] = component; + } else if (IsColor16FormatFloatLike(dest_rt_key.GetColorFormat())) { + resolve_clear_attachment.clearValue.color.float32[j] = + rex::xenos_half_to_float(component); + } else { + resolve_clear_attachment.clearValue.color.float32[j] = + std::max(float(int16_t(component)) * (1.0f / 32767.0f), -1.0f); + } + } + } break; + case xenos::ColorRenderTargetFormat::k_16_16_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT: { + // Using uint for transfers and clears of both. Disregarding the + // current -32...32 vs. -1...1 settings for consistency with color + // clear via depth aliasing. + for (uint32_t j = 0; j < 4; ++j) { + uint16_t component = uint16_t((clear_value >> (j * 16)) & 0xFFFF); + if (dest_color_transfer_is_uint) { + resolve_clear_attachment.clearValue.color.uint32[j] = component; + } else if (IsColor16FormatFloatLike(dest_rt_key.GetColorFormat())) { + resolve_clear_attachment.clearValue.color.float32[j] = + rex::xenos_half_to_float(component); + } else { + resolve_clear_attachment.clearValue.color.float32[j] = + std::max(float(int16_t(component)) * (1.0f / 32767.0f), -1.0f); + } + } + } break; + case xenos::ColorRenderTargetFormat::k_32_FLOAT: { + uint32_t component = uint32_t(clear_value); + if (dest_color_transfer_is_uint) { + // Using uint for proper denormal and NaN handling. + resolve_clear_attachment.clearValue.color.uint32[0] = component; + } else { + std::memcpy(&resolve_clear_attachment.clearValue.color.float32[0], &component, + sizeof(component)); + } + } break; + case xenos::ColorRenderTargetFormat::k_32_32_FLOAT: { + uint32_t component_0 = uint32_t(clear_value); + uint32_t component_1 = uint32_t(clear_value >> 32); + if (dest_color_transfer_is_uint) { + // Using uint for proper denormal and NaN handling. + resolve_clear_attachment.clearValue.color.uint32[0] = component_0; + resolve_clear_attachment.clearValue.color.uint32[1] = component_1; + } else { + std::memcpy(&resolve_clear_attachment.clearValue.color.float32[0], &component_0, + sizeof(component_0)); + std::memcpy(&resolve_clear_attachment.clearValue.color.float32[1], &component_1, + sizeof(component_1)); + } + } break; + } + } + command_buffer.CmdVkClearAttachments(1, &resolve_clear_attachment, 1, &resolve_clear_rect); + } + } +} + +VkPipeline VulkanRenderTargetCache::GetDumpPipeline(DumpPipelineKey key) { + auto pipeline_it = dump_pipelines_.find(key); + if (pipeline_it != dump_pipelines_.end()) { + return pipeline_it->second; + } + + std::vector id_vector_temp; + + SpirvBuilder builder(spv::Spv_1_0, (SpirvShaderTranslator::kSpirvMagicToolId << 16) | 1, nullptr); + spv::Id ext_inst_glsl_std_450 = builder.import("GLSL.std.450"); + builder.addCapability(spv::CapabilityShader); + builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450); + builder.setSource(spv::SourceLanguageUnknown, 0); + + spv::Id type_void = builder.makeVoidType(); + spv::Id type_int = builder.makeIntType(32); + spv::Id type_int2 = builder.makeVectorType(type_int, 2); + spv::Id type_uint = builder.makeUintType(32); + spv::Id type_uint2 = builder.makeVectorType(type_uint, 2); + spv::Id type_uint3 = builder.makeVectorType(type_uint, 3); + spv::Id type_float = builder.makeFloatType(32); + + // Bindings. + // EDRAM buffer. + bool format_is_64bpp = + !key.is_depth && xenos::IsColorRenderTargetFormat64bpp(key.GetColorFormat()); + id_vector_temp.clear(); + id_vector_temp.push_back(builder.makeRuntimeArray(format_is_64bpp ? type_uint2 : type_uint)); + // Storage buffers have std430 packing, no padding to 4-component vectors. + builder.addDecoration(id_vector_temp.back(), spv::DecorationArrayStride, + sizeof(uint32_t) << uint32_t(format_is_64bpp)); + spv::Id type_edram = builder.makeStructType(id_vector_temp, "XeEdram"); + builder.addMemberName(type_edram, 0, "edram"); + builder.addMemberDecoration(type_edram, 0, spv::DecorationNonReadable); + builder.addMemberDecoration(type_edram, 0, spv::DecorationOffset, 0); + // Block since SPIR-V 1.3, but since SPIR-V 1.0 is generated, it's + // BufferBlock. + builder.addDecoration(type_edram, spv::DecorationBufferBlock); + // StorageBuffer since SPIR-V 1.3, but since SPIR-V 1.0 is generated, it's + // Uniform. + spv::Id edram_buffer = + builder.createVariable(spv::NoPrecision, spv::StorageClassUniform, type_edram, "xe_edram"); + builder.addDecoration(edram_buffer, spv::DecorationDescriptorSet, kDumpDescriptorSetEdram); + builder.addDecoration(edram_buffer, spv::DecorationBinding, 0); + // Color or depth source. + bool source_is_multisampled = key.msaa_samples != xenos::MsaaSamples::k1X; + bool source_is_uint; + if (key.is_depth) { + source_is_uint = false; + } else { + GetColorOwnershipTransferVulkanFormat(key.GetColorFormat(), key.msaa_samples, &source_is_uint); + } + spv::Id source_component_type = source_is_uint ? type_uint : type_float; + spv::Id source_texture = builder.createVariable( + spv::NoPrecision, spv::StorageClassUniformConstant, + builder.makeImageType(source_component_type, spv::Dim2D, false, false, source_is_multisampled, + 1, spv::ImageFormatUnknown), + "xe_edram_dump_source"); + builder.addDecoration(source_texture, spv::DecorationDescriptorSet, kDumpDescriptorSetSource); + builder.addDecoration(source_texture, spv::DecorationBinding, 0); + // Stencil source. + spv::Id source_stencil_texture = spv::NoResult; + if (key.is_depth) { + source_stencil_texture = builder.createVariable( + spv::NoPrecision, spv::StorageClassUniformConstant, + builder.makeImageType(type_uint, spv::Dim2D, false, false, source_is_multisampled, 1, + spv::ImageFormatUnknown), + "xe_edram_dump_stencil"); + builder.addDecoration(source_stencil_texture, spv::DecorationDescriptorSet, + kDumpDescriptorSetSource); + builder.addDecoration(source_stencil_texture, spv::DecorationBinding, 1); + } + // Push constants. + id_vector_temp.clear(); + id_vector_temp.reserve(kDumpPushConstantCount); + for (uint32_t i = 0; i < kDumpPushConstantCount; ++i) { + id_vector_temp.push_back(type_uint); + } + spv::Id type_push_constants = builder.makeStructType(id_vector_temp, "XeEdramDumpPushConstants"); + builder.addMemberName(type_push_constants, kDumpPushConstantPitches, "pitches"); + builder.addMemberDecoration(type_push_constants, kDumpPushConstantPitches, spv::DecorationOffset, + int(sizeof(uint32_t) * kDumpPushConstantPitches)); + builder.addMemberName(type_push_constants, kDumpPushConstantOffsets, "offsets"); + builder.addMemberDecoration(type_push_constants, kDumpPushConstantOffsets, spv::DecorationOffset, + int(sizeof(uint32_t) * kDumpPushConstantOffsets)); + builder.addDecoration(type_push_constants, spv::DecorationBlock); + spv::Id push_constants = + builder.createVariable(spv::NoPrecision, spv::StorageClassPushConstant, type_push_constants, + "xe_edram_dump_push_constants"); + + // gl_GlobalInvocationID input. + spv::Id input_global_invocation_id = builder.createVariable( + spv::NoPrecision, spv::StorageClassInput, type_uint3, "gl_GlobalInvocationID"); + builder.addDecoration(input_global_invocation_id, spv::DecorationBuiltIn, + spv::BuiltInGlobalInvocationId); + + // Begin the main function. + std::vector main_param_types; + std::vector> main_precisions; + spv::Block* main_entry; + spv::Function* main_function = builder.makeFunctionEntry( + spv::NoPrecision, type_void, "main", main_param_types, main_precisions, &main_entry); + + // For now, as the exact addressing in 64bpp render targets relatively to + // 32bpp is unknown, treating 64bpp tiles as storing 40x16 samples rather than + // 80x16 for simplicity of addressing into the texture. + + // Split the destination sample index into the 32bpp tile and the + // 32bpp-tile-relative sample index. + // Note that division by non-power-of-two constants will include a 4-cycle + // 32*32 multiplication on AMD, even though so many bits are not needed for + // the sample position - however, if an OpUnreachable path is inserted for the + // case when the position has upper bits set, for some reason, the code for it + // is not eliminated when compiling the shader for AMD via RenderDoc on + // Windows, as of June 2022. + spv::Id global_invocation_id = builder.createLoad(input_global_invocation_id, spv::NoPrecision); + spv::Id rectangle_sample_x = builder.createCompositeExtract(global_invocation_id, type_uint, 0); + uint32_t tile_width = + (xenos::kEdramTileWidthSamples >> uint32_t(format_is_64bpp)) * draw_resolution_scale_x(); + spv::Id const_tile_width = builder.makeUintConstant(tile_width); + spv::Id rectangle_tile_index_x = + builder.createBinOp(spv::OpUDiv, type_uint, rectangle_sample_x, const_tile_width); + spv::Id tile_sample_x = + builder.createBinOp(spv::OpUMod, type_uint, rectangle_sample_x, const_tile_width); + spv::Id rectangle_sample_y = builder.createCompositeExtract(global_invocation_id, type_uint, 1); + uint32_t tile_height = xenos::kEdramTileHeightSamples * draw_resolution_scale_y(); + spv::Id const_tile_height = builder.makeUintConstant(tile_height); + spv::Id rectangle_tile_index_y = + builder.createBinOp(spv::OpUDiv, type_uint, rectangle_sample_y, const_tile_height); + spv::Id tile_sample_y = + builder.createBinOp(spv::OpUMod, type_uint, rectangle_sample_y, const_tile_height); + + // Get the tile index in the EDRAM relative to the dump rectangle base tile. + id_vector_temp.clear(); + id_vector_temp.push_back(builder.makeIntConstant(kDumpPushConstantPitches)); + spv::Id pitches_constant = builder.createLoad( + builder.createAccessChain(spv::StorageClassPushConstant, push_constants, id_vector_temp), + spv::NoPrecision); + spv::Id const_uint_0 = builder.makeUintConstant(0); + spv::Id const_edram_pitch_tiles_bits = builder.makeUintConstant(xenos::kEdramPitchTilesBits); + spv::Id rectangle_tile_index = builder.createBinOp( + spv::OpIAdd, type_uint, + builder.createBinOp(spv::OpIMul, type_uint, + builder.createTriOp(spv::OpBitFieldUExtract, type_uint, pitches_constant, + const_uint_0, const_edram_pitch_tiles_bits), + rectangle_tile_index_y), + rectangle_tile_index_x); + // Add the base tile in the dispatch to the dispatch-local tile index, not + // wrapping yet so in case of a wraparound, the address relative to the base + // in the image after subtraction of the base won't be negative. + id_vector_temp.clear(); + id_vector_temp.push_back(builder.makeIntConstant(kDumpPushConstantOffsets)); + spv::Id offsets_constant = builder.createLoad( + builder.createAccessChain(spv::StorageClassPushConstant, push_constants, id_vector_temp), + spv::NoPrecision); + spv::Id const_edram_base_tiles_bits_plus_1 = + builder.makeUintConstant(xenos::kEdramBaseTilesBits + 1); + spv::Id edram_tile_index_non_wrapped = + builder.createBinOp(spv::OpIAdd, type_uint, + builder.createTriOp(spv::OpBitFieldUExtract, type_uint, offsets_constant, + const_uint_0, const_edram_base_tiles_bits_plus_1), + rectangle_tile_index); + + // Combine the tile sample index and the tile index, wrapping the tile + // addressing, into the EDRAM sample index. + spv::Id edram_sample_address = builder.createBinOp( + spv::OpIAdd, type_uint, + builder.createBinOp( + spv::OpIMul, type_uint, builder.makeUintConstant(tile_width * tile_height), + builder.createBinOp(spv::OpBitwiseAnd, type_uint, edram_tile_index_non_wrapped, + builder.makeUintConstant(xenos::kEdramTileCount - 1))), + builder.createBinOp( + spv::OpIAdd, type_uint, + builder.createBinOp(spv::OpIMul, type_uint, const_tile_width, tile_sample_y), + tile_sample_x)); + if (key.is_depth) { + // Swap 40-sample columns in the depth buffer in the destination address to + // get the final address of the sample in the EDRAM. + uint32_t tile_width_half = tile_width >> 1; + edram_sample_address = builder.createUnaryOp( + spv::OpBitcast, type_uint, + builder.createBinOp( + spv::OpIAdd, type_int, + builder.createUnaryOp(spv::OpBitcast, type_int, edram_sample_address), + builder.createTriOp( + spv::OpSelect, type_int, + builder.createBinOp(spv::OpULessThan, builder.makeBoolType(), tile_sample_x, + builder.makeUintConstant(tile_width_half)), + builder.makeIntConstant(int32_t(tile_width_half)), + builder.makeIntConstant(-int32_t(tile_width_half))))); + } + + // Get the linear tile index within the source texture. + spv::Id source_tile_index = builder.createBinOp( + spv::OpISub, type_uint, edram_tile_index_non_wrapped, + builder.createTriOp(spv::OpBitFieldUExtract, type_uint, offsets_constant, + const_edram_base_tiles_bits_plus_1, + builder.makeUintConstant(xenos::kEdramBaseTilesBits))); + // Split the linear tile index in the source texture into X and Y in tiles. + spv::Id source_pitch_tiles = + builder.createTriOp(spv::OpBitFieldUExtract, type_uint, pitches_constant, + const_edram_pitch_tiles_bits, const_edram_pitch_tiles_bits); + spv::Id source_tile_index_y = + builder.createBinOp(spv::OpUDiv, type_uint, source_tile_index, source_pitch_tiles); + spv::Id source_tile_index_x = + builder.createBinOp(spv::OpUMod, type_uint, source_tile_index, source_pitch_tiles); + // Combine the source tile offset and the sample index within the tile. + spv::Id source_sample_x = builder.createBinOp( + spv::OpIAdd, type_uint, + builder.createBinOp(spv::OpIMul, type_uint, const_tile_width, source_tile_index_x), + tile_sample_x); + spv::Id source_sample_y = builder.createBinOp( + spv::OpIAdd, type_uint, + builder.createBinOp(spv::OpIMul, type_uint, const_tile_height, source_tile_index_y), + tile_sample_y); + // Get the source pixel coordinate and the sample index within the pixel. + spv::Id source_pixel_x = source_sample_x, source_pixel_y = source_sample_y; + spv::Id source_sample_id = spv::NoResult; + if (source_is_multisampled) { + spv::Id const_uint_1 = builder.makeUintConstant(1); + source_pixel_y = + builder.createBinOp(spv::OpShiftRightLogical, type_uint, source_sample_y, const_uint_1); + if (key.msaa_samples >= xenos::MsaaSamples::k4X) { + source_pixel_x = + builder.createBinOp(spv::OpShiftRightLogical, type_uint, source_sample_x, const_uint_1); + // 4x MSAA source texture sample index - bit 0 for horizontal, bit 1 for + // vertical. + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createBinOp(spv::OpBitwiseAnd, type_uint, source_sample_x, const_uint_1), + source_sample_y, const_uint_1, const_uint_1); + } else { + // 2x MSAA source texture sample index - convert from the guest to + // the Vulkan standard sample locations. + source_sample_id = builder.createTriOp( + spv::OpSelect, type_uint, + builder.createBinOp( + spv::OpINotEqual, builder.makeBoolType(), + builder.createBinOp(spv::OpBitwiseAnd, type_uint, source_sample_y, const_uint_1), + const_uint_0), + builder.makeUintConstant( + draw_util::GetD3D10SampleIndexForGuest2xMSAA(1, msaa_2x_attachments_supported_)), + builder.makeUintConstant( + draw_util::GetD3D10SampleIndexForGuest2xMSAA(0, msaa_2x_attachments_supported_))); + } + } + + // Load the source, and pack the value into one or two 32-bit integers. + spv::Id packed[2] = {}; + spv::Builder::TextureParameters source_texture_parameters = {}; + source_texture_parameters.sampler = builder.createLoad(source_texture, spv::NoPrecision); + id_vector_temp.clear(); + id_vector_temp.push_back(builder.createUnaryOp(spv::OpBitcast, type_int, source_pixel_x)); + id_vector_temp.push_back(builder.createUnaryOp(spv::OpBitcast, type_int, source_pixel_y)); + source_texture_parameters.coords = builder.createCompositeConstruct(type_int2, id_vector_temp); + if (source_is_multisampled) { + source_texture_parameters.sample = + builder.createUnaryOp(spv::OpBitcast, type_int, source_sample_id); + } else { + source_texture_parameters.lod = builder.makeIntConstant(0); + } + spv::Id source_vec4 = builder.createTextureCall( + spv::NoPrecision, builder.makeVectorType(source_component_type, 4), false, true, false, false, + false, source_texture_parameters, spv::ImageOperandsMaskNone); + const bool source_color_16_is_float = + !key.is_depth && IsColor16FormatFloatLike(key.GetColorFormat()); + spv::Id const_uint_16 = builder.makeUintConstant(16); + spv::Id const_float_0 = builder.makeFloatConstant(0.0f); + spv::Id const_float_1 = builder.makeFloatConstant(1.0f); + spv::Id const_float_minus_1 = builder.makeFloatConstant(-1.0f); + spv::Id const_float_32767 = builder.makeFloatConstant(32767.0f); + auto LinearToPWLGamma = [&](spv::Id linear, bool linear_pre_saturated) -> spv::Id { + if (!linear_pre_saturated) { + linear = builder.createTriBuiltinCall(type_float, ext_inst_glsl_std_450, GLSLstd450NClamp, + linear, const_float_0, const_float_1); + } + spv::Id is_piece_at_least_3 = + builder.createBinOp(spv::OpFOrdGreaterThanEqual, builder.makeBoolType(), linear, + builder.makeFloatConstant(512.0f / 1023.0f)); + spv::Id scale_3_or_2 = builder.createTriOp(spv::OpSelect, type_float, is_piece_at_least_3, + builder.makeFloatConstant(1023.0f / 8.0f), + builder.makeFloatConstant(1023.0f / 4.0f)); + spv::Id offset_3_or_2 = builder.createTriOp(spv::OpSelect, type_float, is_piece_at_least_3, + builder.makeFloatConstant(128.0f / 255.0f), + builder.makeFloatConstant(64.0f / 255.0f)); + spv::Id is_piece_at_least_1 = + builder.createBinOp(spv::OpFOrdGreaterThanEqual, builder.makeBoolType(), linear, + builder.makeFloatConstant(64.0f / 1023.0f)); + spv::Id scale_1_or_0 = builder.createTriOp(spv::OpSelect, type_float, is_piece_at_least_1, + builder.makeFloatConstant(1023.0f / 2.0f), + builder.makeFloatConstant(1023.0f)); + spv::Id offset_1_or_0 = + builder.createTriOp(spv::OpSelect, type_float, is_piece_at_least_1, + builder.makeFloatConstant(32.0f / 255.0f), const_float_0); + spv::Id is_piece_at_least_2 = + builder.createBinOp(spv::OpFOrdGreaterThanEqual, builder.makeBoolType(), linear, + builder.makeFloatConstant(128.0f / 1023.0f)); + spv::Id scale = builder.createTriOp(spv::OpSelect, type_float, is_piece_at_least_2, + scale_3_or_2, scale_1_or_0); + spv::Id offset = builder.createTriOp(spv::OpSelect, type_float, is_piece_at_least_2, + offset_3_or_2, offset_1_or_0); + return builder.createBinOp( + spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, + builder.createUnaryBuiltinCall( + type_float, ext_inst_glsl_std_450, GLSLstd450Trunc, + builder.createBinOp(spv::OpFMul, type_float, linear, scale)), + builder.makeFloatConstant(1.0f / 255.0f)), + offset); + }; + auto PackDumpSource16ComponentToUint = [&](spv::Id component) -> spv::Id { + if (source_is_uint) { + return component; + } + if (source_color_16_is_float) { + id_vector_temp.clear(); + id_vector_temp.push_back(component); + id_vector_temp.push_back(const_float_0); + spv::Id packed_half = builder.createUnaryBuiltinCall( + type_uint, ext_inst_glsl_std_450, GLSLstd450PackHalf2x16, + builder.createCompositeConstruct(builder.makeVectorType(type_float, 2), id_vector_temp)); + return builder.createTriOp(spv::OpBitFieldUExtract, type_uint, packed_half, const_uint_0, + const_uint_16); + } + spv::Id component_clamped = + builder.createTriBuiltinCall(type_float, ext_inst_glsl_std_450, GLSLstd450NClamp, component, + const_float_minus_1, const_float_1); + spv::Id component_rounded = builder.createUnaryBuiltinCall( + type_float, ext_inst_glsl_std_450, GLSLstd450RoundEven, + builder.createBinOp(spv::OpFMul, type_float, component_clamped, const_float_32767)); + spv::Id component_snorm = + builder.createUnaryOp(spv::OpConvertFToS, type_int, component_rounded); + return builder.createTriOp(spv::OpBitFieldUExtract, type_uint, + builder.createUnaryOp(spv::OpBitcast, type_uint, component_snorm), + const_uint_0, const_uint_16); + }; + auto PackDumpSource16PairToUint32 = [&](spv::Id component_0, spv::Id component_1) -> spv::Id { + return builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, PackDumpSource16ComponentToUint(component_0), + PackDumpSource16ComponentToUint(component_1), const_uint_16, const_uint_16); + }; + if (key.is_depth) { + source_texture_parameters.sampler = + builder.createLoad(source_stencil_texture, spv::NoPrecision); + spv::Id source_stencil = builder.createCompositeExtract( + builder.createTextureCall(spv::NoPrecision, builder.makeVectorType(type_uint, 4), false, + true, false, false, false, source_texture_parameters, + spv::ImageOperandsMaskNone), + type_uint, 0); + spv::Id source_depth32 = builder.createCompositeExtract(source_vec4, type_float, 0); + switch (key.GetDepthFormat()) { + case xenos::DepthRenderTargetFormat::kD24S8: { + // Round to the nearest even integer. This seems to be the correct + // conversion, adding +0.5 and rounding towards zero results in red + // instead of black in the 4D5307E6 clear shader. + packed[0] = builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createUnaryBuiltinCall( + type_float, ext_inst_glsl_std_450, GLSLstd450RoundEven, + builder.createBinOp(spv::OpFMul, type_float, source_depth32, + builder.makeFloatConstant(float(0xFFFFFF))))); + } break; + case xenos::DepthRenderTargetFormat::kD24FS8: { + packed[0] = SpirvShaderTranslator::PreClampedDepthTo20e4( + builder, source_depth32, depth_float24_round(), true, ext_inst_glsl_std_450); + } break; + } + packed[0] = builder.createQuadOp(spv::OpBitFieldInsert, type_uint, source_stencil, packed[0], + builder.makeUintConstant(8), builder.makeUintConstant(24)); + } else { + switch (key.GetColorFormat()) { + case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA: { + if (gamma_render_target_as_unorm16_) { + // 8_8_8_8_GAMMA is represented by linear stored in + // R16G16B16A16_UNORM. + id_vector_temp.clear(); + for (uint32_t i = 0; i < 3; ++i) { + id_vector_temp.push_back( + LinearToPWLGamma(builder.createCompositeExtract(source_vec4, type_float, i), true)); + } + } + } + [[fallthrough]]; + case xenos::ColorRenderTargetFormat::k_8_8_8_8: { + spv::Id unorm_round_offset = builder.makeFloatConstant(0.5f); + spv::Id unorm_scale = builder.makeFloatConstant(255.0f); + spv::Id color_0 = builder.createCompositeExtract(source_vec4, type_float, 0); + if (key.GetColorFormat() == xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA && + gamma_render_target_as_unorm16_) { + color_0 = id_vector_temp[0]; + } + packed[0] = builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp(spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, color_0, unorm_scale), + unorm_round_offset)); + spv::Id component_width = builder.makeUintConstant(8); + for (uint32_t i = 1; i < 4; ++i) { + spv::Id color_i = builder.createCompositeExtract(source_vec4, type_float, i); + if (key.GetColorFormat() == xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA && + gamma_render_target_as_unorm16_ && i < 3) { + color_i = id_vector_temp[i]; + } + packed[0] = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed[0], + builder.createUnaryOp(spv::OpConvertFToU, type_uint, + builder.createBinOp(spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, + color_i, unorm_scale), + unorm_round_offset)), + builder.makeUintConstant(8 * i), component_width); + } + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: { + spv::Id unorm_round_offset = builder.makeFloatConstant(0.5f); + spv::Id unorm_scale_rgb = builder.makeFloatConstant(1023.0f); + packed[0] = builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp( + spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, + builder.createCompositeExtract(source_vec4, type_float, 0), + unorm_scale_rgb), + unorm_round_offset)); + spv::Id width_rgb = builder.makeUintConstant(10); + spv::Id unorm_scale_a = builder.makeFloatConstant(3.0f); + spv::Id width_a = builder.makeUintConstant(2); + for (uint32_t i = 1; i < 4; ++i) { + packed[0] = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed[0], + builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp(spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, + builder.createCompositeExtract( + source_vec4, type_float, i), + i == 3 ? unorm_scale_a : unorm_scale_rgb), + unorm_round_offset)), + builder.makeUintConstant(10 * i), i == 3 ? width_a : width_rgb); + } + } break; + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT: + case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16: { + // Float16 has a wider range for both color and alpha, also NaNs - clamp + // and convert. + packed[0] = SpirvShaderTranslator::UnclampedFloat32To7e3( + builder, builder.createCompositeExtract(source_vec4, type_float, 0), + ext_inst_glsl_std_450); + spv::Id width_rgb = builder.makeUintConstant(10); + for (uint32_t i = 1; i < 3; ++i) { + packed[0] = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed[0], + SpirvShaderTranslator::UnclampedFloat32To7e3( + builder, builder.createCompositeExtract(source_vec4, type_float, i), + ext_inst_glsl_std_450), + builder.makeUintConstant(10 * i), width_rgb); + } + // Saturate and convert the alpha. + spv::Id alpha_saturated = builder.createTriBuiltinCall( + type_float, ext_inst_glsl_std_450, GLSLstd450NClamp, + builder.createCompositeExtract(source_vec4, type_float, 3), + builder.makeFloatConstant(0.0f), builder.makeFloatConstant(1.0f)); + packed[0] = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed[0], + builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp(spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, alpha_saturated, + builder.makeFloatConstant(3.0f)), + builder.makeFloatConstant(0.5f))), + builder.makeUintConstant(30), builder.makeUintConstant(2)); + } break; + case xenos::ColorRenderTargetFormat::k_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_16_16: + case xenos::ColorRenderTargetFormat::k_16_16_FLOAT: + case xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT: { + for (uint32_t i = 0; i <= uint32_t(format_is_64bpp); ++i) { + packed[i] = PackDumpSource16PairToUint32( + builder.createCompositeExtract(source_vec4, source_component_type, 2 * i), + builder.createCompositeExtract(source_vec4, source_component_type, 2 * i + 1)); + } + } break; + // Float32 is transferred as uint32 to preserve NaN encodings. However, + // multisampled sampled image support is optional in Vulkan. + case xenos::ColorRenderTargetFormat::k_32_FLOAT: + case xenos::ColorRenderTargetFormat::k_32_32_FLOAT: { + for (uint32_t i = 0; i <= uint32_t(format_is_64bpp); ++i) { + spv::Id& packed_ref = packed[i]; + packed_ref = builder.createCompositeExtract(source_vec4, source_component_type, i); + if (!source_is_uint) { + packed_ref = builder.createUnaryOp(spv::OpBitcast, type_uint, packed_ref); + } + } + } break; + } + } + + // Write the packed value to the EDRAM buffer. + spv::Id store_value = packed[0]; + if (format_is_64bpp) { + id_vector_temp.clear(); + id_vector_temp.push_back(packed[0]); + id_vector_temp.push_back(packed[1]); + store_value = builder.createCompositeConstruct(type_uint2, id_vector_temp); + } + id_vector_temp.clear(); + // The only SSBO structure member. + id_vector_temp.push_back(builder.makeIntConstant(0)); + id_vector_temp.push_back(builder.createUnaryOp(spv::OpBitcast, type_int, edram_sample_address)); + // StorageBuffer since SPIR-V 1.3, but since SPIR-V 1.0 is generated, it's + // Uniform. + builder.createStore(store_value, builder.createAccessChain(spv::StorageClassUniform, edram_buffer, + id_vector_temp)); + + // End the main function and make it the entry point. + builder.leaveFunction(); + builder.addExecutionMode(main_function, spv::ExecutionModeLocalSize, kDumpSamplesPerGroupX, + kDumpSamplesPerGroupY, 1); + spv::Instruction* entry_point = + builder.addEntryPoint(spv::ExecutionModelGLCompute, main_function, "main"); + // Bindings only need to be added to the entry point's interface starting with + // SPIR-V 1.4 - emitting 1.0 here, so only inputs / outputs. + entry_point->addIdOperand(input_global_invocation_id); + + // Serialize the shader code. + std::vector shader_code; + builder.dump(shader_code); + + // Create the pipeline, and store the handle even if creation fails not to try + // to create it again later. + VkPipeline pipeline = ui::vulkan::util::CreateComputePipeline( + command_processor_.GetVulkanDevice(), + key.is_depth ? dump_pipeline_layout_depth_ : dump_pipeline_layout_color_, + reinterpret_cast(shader_code.data()), sizeof(uint32_t) * shader_code.size()); + if (pipeline == VK_NULL_HANDLE) { + REXGPU_ERROR( + "VulkanRenderTargetCache: Failed to create a render target dumping " + "pipeline for {}-sample render targets with format {}", + UINT32_C(1) << uint32_t(key.msaa_samples), + key.is_depth ? xenos::GetDepthRenderTargetFormatName(key.GetDepthFormat()) + : xenos::GetColorRenderTargetFormatName(key.GetColorFormat())); + } + dump_pipelines_.emplace(key, pipeline); + return pipeline; +} + +VkPipeline VulkanRenderTargetCache::GetDirectResolvePipeline(DirectResolvePipelineKey key) { + auto pipeline_it = direct_resolve_pipelines_.find(key); + if (pipeline_it != direct_resolve_pipelines_.end()) { + return pipeline_it->second; + } + VkPipeline pipeline = VK_NULL_HANDLE; + // Until dedicated direct host RT -> shared memory shaders are added, reuse + // the resolve copy pipelines to keep all resolve shader modes wired for the + // direct preflight path. + size_t copy_shader_index = size_t(key.copy_shader); + if (copy_shader_index < size_t(draw_util::ResolveCopyShaderIndex::kCount)) { + pipeline = resolve_copy_pipelines_[copy_shader_index]; + } + direct_resolve_pipelines_.emplace(key, pipeline); + return pipeline; +} + +bool VulkanRenderTargetCache::TryResolveCopyDirectly(const draw_util::ResolveInfo& resolve_info, + draw_util::ResolveCopyShaderIndex copy_shader, + bool draw_resolution_scaled) { + ++direct_resolve_attempt_count_; + (void)copy_shader; + (void)draw_resolution_scaled; + if (direct_resolve_pipeline_layout_color_ == VK_NULL_HANDLE || + direct_resolve_pipeline_layout_depth_ == VK_NULL_HANDLE) { + return false; + } + + uint32_t dump_base; + uint32_t dump_row_length_used; + uint32_t dump_rows; + uint32_t dump_pitch; + resolve_info.GetCopyEdramTileSpan(dump_base, dump_row_length_used, dump_rows, dump_pitch); + GetResolveCopyDispatchesToDump(dump_base, dump_row_length_used, dump_rows, dump_pitch, + dump_rectangles_, direct_resolve_dispatches_); + if (direct_resolve_dispatches_.empty()) { + return false; + } + + for (const ResolveCopyDumpRectangle& rectangle : dump_rectangles_) { + const auto* render_target = static_cast(rectangle.render_target); + if (render_target == nullptr) { + return false; + } + DumpPipelineKey dump_pipeline_key; + dump_pipeline_key.msaa_samples = render_target->key().msaa_samples; + dump_pipeline_key.resource_format = render_target->key().resource_format; + dump_pipeline_key.is_depth = render_target->key().is_depth; + if (GetDumpPipeline(dump_pipeline_key) == VK_NULL_HANDLE) { + return false; + } + DirectResolvePipelineKey direct_pipeline_key; + direct_pipeline_key.dump_pipeline_key = dump_pipeline_key; + direct_pipeline_key.copy_shader = copy_shader; + direct_pipeline_key.draw_resolution_scaled = draw_resolution_scaled; + if (GetDirectResolvePipeline(direct_pipeline_key) == VK_NULL_HANDLE) { + return false; + } + } + + // Dedicated direct resolve dispatches are staged behind the same preflight; + // keep using the existing dump path until source-image direct shaders land. + return DumpRenderTargets(dump_base, dump_row_length_used, dump_rows, dump_pitch); +} + +bool VulkanRenderTargetCache::DumpRenderTargets(uint32_t dump_base, uint32_t dump_row_length_used, + uint32_t dump_rows, uint32_t dump_pitch) { + assert_true(GetPath() == Path::kHostRenderTargets); + + GetResolveCopyRectanglesToDump(dump_base, dump_row_length_used, dump_rows, dump_pitch, + dump_rectangles_); + if (dump_rectangles_.empty()) { + return true; + } + + // Clear previously set temporary indices. + for (const ResolveCopyDumpRectangle& rectangle : dump_rectangles_) { + static_cast(rectangle.render_target)->SetTemporarySortIndex(UINT32_MAX); + } + // Gather all needed barriers and info needed to sort the invocations. + UseEdramBuffer(EdramBufferUsage::kComputeWrite); + dump_invocations_.clear(); + dump_invocations_.reserve(dump_rectangles_.size()); + uint32_t rt_sort_index = 0; + for (const ResolveCopyDumpRectangle& rectangle : dump_rectangles_) { + auto& vulkan_rt = *static_cast(rectangle.render_target); + RenderTargetKey rt_key = vulkan_rt.key(); + command_processor_.PushImageMemoryBarrier( + vulkan_rt.image(), + ui::vulkan::util::InitializeSubresourceRange( + rt_key.is_depth ? (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) + : VK_IMAGE_ASPECT_COLOR_BIT), + vulkan_rt.current_stage_mask(), VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + vulkan_rt.current_access_mask(), VK_ACCESS_SHADER_READ_BIT, vulkan_rt.current_layout(), + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + vulkan_rt.SetUsage(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + if (vulkan_rt.temporary_sort_index() == UINT32_MAX) { + vulkan_rt.SetTemporarySortIndex(rt_sort_index++); + } + DumpPipelineKey pipeline_key; + pipeline_key.msaa_samples = rt_key.msaa_samples; + pipeline_key.resource_format = rt_key.resource_format; + pipeline_key.is_depth = rt_key.is_depth; + dump_invocations_.emplace_back(rectangle, pipeline_key); + } + + // Sort the invocations to reduce context and binding switches. + std::sort(dump_invocations_.begin(), dump_invocations_.end()); + + // Dump the render targets. + DeferredCommandBuffer& command_buffer = command_processor_.deferred_command_buffer(); + bool edram_buffer_bound = false; + VkDescriptorSet last_source_descriptor_set = VK_NULL_HANDLE; + DumpPitches last_pitches; + DumpOffsets last_offsets; + bool pitches_bound = false, offsets_bound = false; + bool all_pipelines_available = true; + for (const DumpInvocation& invocation : dump_invocations_) { + const ResolveCopyDumpRectangle& rectangle = invocation.rectangle; + auto& vulkan_rt = *static_cast(rectangle.render_target); + RenderTargetKey rt_key = vulkan_rt.key(); + DumpPipelineKey pipeline_key = invocation.pipeline_key; + VkPipeline pipeline = GetDumpPipeline(pipeline_key); + if (!pipeline) { + all_pipelines_available = false; + continue; + } + command_processor_.BindExternalComputePipeline(pipeline); + + VkPipelineLayout pipeline_layout = + rt_key.is_depth ? dump_pipeline_layout_depth_ : dump_pipeline_layout_color_; + + // Only need to bind the EDRAM buffer once (relying on pipeline layout + // compatibility). + if (!edram_buffer_bound) { + edram_buffer_bound = true; + command_buffer.CmdVkBindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_layout, + kDumpDescriptorSetEdram, 1, + &edram_storage_buffer_descriptor_set_, 0, nullptr); + } + + VkDescriptorSet source_descriptor_set = vulkan_rt.GetDescriptorSetTransferSource(); + if (last_source_descriptor_set != source_descriptor_set) { + last_source_descriptor_set = source_descriptor_set; + command_buffer.CmdVkBindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_layout, + kDumpDescriptorSetSource, 1, &source_descriptor_set, 0, + nullptr); + } + + DumpPitches pitches; + pitches.dest_pitch = dump_pitch; + pitches.source_pitch = rt_key.GetPitchTiles(); + if (last_pitches != pitches) { + last_pitches = pitches; + pitches_bound = false; + } + if (!pitches_bound) { + pitches_bound = true; + command_buffer.CmdVkPushConstants(pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, + sizeof(uint32_t) * kDumpPushConstantPitches, + sizeof(last_pitches), &last_pitches); + } + + DumpOffsets offsets; + offsets.source_base_tiles = rt_key.base_tiles; + ResolveCopyDumpRectangle::Dispatch dispatches[ResolveCopyDumpRectangle::kMaxDispatches]; + uint32_t dispatch_count = rectangle.GetDispatches(dump_pitch, dump_row_length_used, dispatches); + for (uint32_t i = 0; i < dispatch_count; ++i) { + const ResolveCopyDumpRectangle::Dispatch& dispatch = dispatches[i]; + offsets.dispatch_first_tile = dump_base + dispatch.offset; + if (last_offsets != offsets) { + last_offsets = offsets; + offsets_bound = false; + } + if (!offsets_bound) { + offsets_bound = true; + command_buffer.CmdVkPushConstants(pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, + sizeof(uint32_t) * kDumpPushConstantOffsets, + sizeof(last_offsets), &last_offsets); + } + command_processor_.SubmitBarriers(true); + command_buffer.CmdVkDispatch( + (draw_resolution_scale_x() * + (xenos::kEdramTileWidthSamples >> uint32_t(rt_key.Is64bpp())) * + dispatch.width_tiles + + (kDumpSamplesPerGroupX - 1)) / + kDumpSamplesPerGroupX, + (draw_resolution_scale_y() * xenos::kEdramTileHeightSamples * dispatch.height_tiles + + (kDumpSamplesPerGroupY - 1)) / + kDumpSamplesPerGroupY, + 1); + } + MarkEdramBufferModified(); + } + return all_pipelines_available; +} + +} // namespace rex::graphics::vulkan diff --git a/src/graphics/vulkan/shader.cpp b/src/graphics/vulkan/shader.cpp new file mode 100644 index 0000000..c2805b2 --- /dev/null +++ b/src/graphics/vulkan/shader.cpp @@ -0,0 +1,72 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include + +namespace rex::graphics::vulkan { + +VulkanShader::VulkanTranslation::~VulkanTranslation() { + if (shader_module_) { + const ui::vulkan::VulkanDevice* const vulkan_device = + static_cast(shader()).vulkan_device_; + vulkan_device->functions().vkDestroyShaderModule(vulkan_device->device(), shader_module_, + nullptr); + } +} + +VkShaderModule VulkanShader::VulkanTranslation::GetOrCreateShaderModule() { + if (!is_valid()) { + return VK_NULL_HANDLE; + } + if (shader_module_ != VK_NULL_HANDLE) { + return shader_module_; + } + const ui::vulkan::VulkanDevice* const vulkan_device = + static_cast(shader()).vulkan_device_; + VkShaderModuleCreateInfo shader_module_create_info; + shader_module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + shader_module_create_info.pNext = nullptr; + shader_module_create_info.flags = 0; + shader_module_create_info.codeSize = translated_binary().size(); + shader_module_create_info.pCode = reinterpret_cast(translated_binary().data()); + if (vulkan_device->functions().vkCreateShaderModule(vulkan_device->device(), + &shader_module_create_info, nullptr, + &shader_module_) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanShader::VulkanTranslation: Failed to create a Vulkan shader " + "module for shader {:016X} modification {:016X}", + shader().ucode_data_hash(), modification()); + MakeInvalid(); + return VK_NULL_HANDLE; + } + return shader_module_; +} + +VulkanShader::VulkanShader(const ui::vulkan::VulkanDevice* const vulkan_device, + const xenos::ShaderType shader_type, const uint64_t ucode_data_hash, + const uint32_t* const ucode_dwords, const size_t ucode_dword_count, + const std::endian ucode_source_endian) + : SpirvShader(shader_type, ucode_data_hash, ucode_dwords, ucode_dword_count, + ucode_source_endian), + vulkan_device_(vulkan_device) { + assert_not_null(vulkan_device); +} + +Shader::Translation* VulkanShader::CreateTranslationInstance(uint64_t modification) { + return new VulkanTranslation(*this, modification); +} + +} // namespace rex::graphics::vulkan diff --git a/src/graphics/vulkan/shared_memory.cpp b/src/graphics/vulkan/shared_memory.cpp new file mode 100644 index 0000000..b52ae15 --- /dev/null +++ b/src/graphics/vulkan/shared_memory.cpp @@ -0,0 +1,447 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(vulkan_sparse_shared_memory, true, "GPU/Vulkan", + "Use sparse shared memory on Vulkan") + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +namespace rex::graphics::vulkan { + +VulkanSharedMemory::VulkanSharedMemory(VulkanCommandProcessor& command_processor, + memory::Memory& memory, TraceWriter& trace_writer, + VkPipelineStageFlags guest_shader_pipeline_stages) + : SharedMemory(memory), + command_processor_(command_processor), + trace_writer_(trace_writer), + guest_shader_pipeline_stages_(guest_shader_pipeline_stages) {} + +VulkanSharedMemory::~VulkanSharedMemory() { + Shutdown(true); +} + +bool VulkanSharedMemory::Initialize() { + InitializeCommon(); + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + const VkBufferCreateFlags sparse_flags = + VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT; + + // Try to create a sparse buffer. + VkBufferCreateInfo buffer_create_info; + buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + buffer_create_info.pNext = nullptr; + buffer_create_info.flags = sparse_flags; + buffer_create_info.size = kBufferSize; + buffer_create_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT; + buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + buffer_create_info.queueFamilyIndexCount = 0; + buffer_create_info.pQueueFamilyIndices = nullptr; + if (REXCVAR_GET(vulkan_sparse_shared_memory) && + vulkan_device->properties().sparseResidencyBuffer) { + if (dfn.vkCreateBuffer(device, &buffer_create_info, nullptr, &buffer_) == VK_SUCCESS) { + VkMemoryRequirements buffer_memory_requirements; + dfn.vkGetBufferMemoryRequirements(device, buffer_, &buffer_memory_requirements); + if (rex::bit_scan_forward(buffer_memory_requirements.memoryTypeBits & + vulkan_device->memory_types().device_local, + &buffer_memory_type_)) { + uint32_t allocation_size_log2; + rex::bit_scan_forward(std::max(uint64_t(buffer_memory_requirements.alignment), uint64_t(1)), + &allocation_size_log2); + if (allocation_size_log2 < kBufferSizeLog2) { + // Maximum of 1024 allocations in the worst case for all of the + // buffer because of the overall 4096 allocation count limit on + // Windows drivers. + InitializeSparseHostGpuMemory(std::max( + allocation_size_log2, + std::max(kHostGpuMemoryOptimalSparseAllocationLog2, kBufferSizeLog2 - uint32_t(10)))); + } else { + // Shouldn't happen on any real platform, but no point allocating the + // buffer sparsely. + dfn.vkDestroyBuffer(device, buffer_, nullptr); + buffer_ = VK_NULL_HANDLE; + } + } else { + REXGPU_ERROR( + "Shared memory: Failed to get a device-local Vulkan memory type " + "for the sparse buffer"); + dfn.vkDestroyBuffer(device, buffer_, nullptr); + buffer_ = VK_NULL_HANDLE; + } + } else { + REXGPU_ERROR("Shared memory: Failed to create the {} MB Vulkan sparse buffer", + kBufferSize >> 20); + } + } + + // Create a non-sparse buffer if there were issues with the sparse buffer. + if (buffer_ == VK_NULL_HANDLE) { + REXGPU_INFO( + "Vulkan sparse binding is not used for shared memory emulation - video " + "memory usage may increase significantly because a full {} MB buffer " + "will be created", + kBufferSize >> 20); + buffer_create_info.flags &= ~sparse_flags; + if (dfn.vkCreateBuffer(device, &buffer_create_info, nullptr, &buffer_) != VK_SUCCESS) { + REXGPU_ERROR("Shared memory: Failed to create the {} MB Vulkan buffer", kBufferSize >> 20); + Shutdown(); + return false; + } + VkMemoryRequirements buffer_memory_requirements; + dfn.vkGetBufferMemoryRequirements(device, buffer_, &buffer_memory_requirements); + if (!rex::bit_scan_forward( + buffer_memory_requirements.memoryTypeBits & vulkan_device->memory_types().device_local, + &buffer_memory_type_)) { + REXGPU_ERROR( + "Shared memory: Failed to get a device-local Vulkan memory type for " + "the buffer"); + Shutdown(); + return false; + } + VkMemoryAllocateInfo buffer_memory_allocate_info; + VkMemoryAllocateInfo* buffer_memory_allocate_info_last = &buffer_memory_allocate_info; + buffer_memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + buffer_memory_allocate_info.pNext = nullptr; + buffer_memory_allocate_info.allocationSize = buffer_memory_requirements.size; + buffer_memory_allocate_info.memoryTypeIndex = buffer_memory_type_; + VkMemoryDedicatedAllocateInfo buffer_memory_dedicated_allocate_info; + if (vulkan_device->extensions().ext_1_1_KHR_dedicated_allocation) { + buffer_memory_allocate_info_last->pNext = &buffer_memory_dedicated_allocate_info; + buffer_memory_allocate_info_last = + reinterpret_cast(&buffer_memory_dedicated_allocate_info); + buffer_memory_dedicated_allocate_info.sType = + VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO; + buffer_memory_dedicated_allocate_info.pNext = nullptr; + buffer_memory_dedicated_allocate_info.image = VK_NULL_HANDLE; + buffer_memory_dedicated_allocate_info.buffer = buffer_; + } + VkDeviceMemory buffer_memory; + if (dfn.vkAllocateMemory(device, &buffer_memory_allocate_info, nullptr, &buffer_memory) != + VK_SUCCESS) { + REXGPU_ERROR( + "Shared memory: Failed to allocate {} MB of memory for the Vulkan " + "buffer", + kBufferSize >> 20); + Shutdown(); + return false; + } + buffer_memory_.push_back(buffer_memory); + if (dfn.vkBindBufferMemory(device, buffer_, buffer_memory, 0) != VK_SUCCESS) { + REXGPU_ERROR("Shared memory: Failed to bind memory to the Vulkan buffer"); + Shutdown(); + return false; + } + } + + // The first usage will likely be uploading. + last_usage_ = Usage::kTransferDestination; + last_written_range_ = std::make_pair(0, 0); + + upload_buffer_pool_ = std::make_unique( + vulkan_device, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + rex::align(ui::vulkan::VulkanUploadBufferPool::kDefaultPageSize, size_t(1) + << page_size_log2())); + + return true; +} + +void VulkanSharedMemory::Shutdown(bool from_destructor) { + ResetTraceDownload(); + + upload_buffer_pool_.reset(); + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyBuffer, device, buffer_); + for (VkDeviceMemory memory : buffer_memory_) { + dfn.vkFreeMemory(device, memory, nullptr); + } + buffer_memory_.clear(); + + // If calling from the destructor, the SharedMemory destructor will call + // ShutdownCommon. + if (!from_destructor) { + ShutdownCommon(); + } +} + +void VulkanSharedMemory::CompletedSubmissionUpdated() { + upload_buffer_pool_->Reclaim(command_processor_.GetCompletedSubmission()); +} + +void VulkanSharedMemory::EndSubmission() { + upload_buffer_pool_->FlushWrites(); +} + +void VulkanSharedMemory::Use(Usage usage, std::pair written_range) { + written_range.first = std::min(written_range.first, kBufferSize); + written_range.second = std::min(written_range.second, kBufferSize - written_range.first); + assert_true(usage != Usage::kRead || !written_range.second); + if (last_usage_ != usage || last_written_range_.second) { + VkPipelineStageFlags src_stage_mask, dst_stage_mask; + VkAccessFlags src_access_mask, dst_access_mask; + GetUsageMasks(last_usage_, src_stage_mask, src_access_mask); + GetUsageMasks(usage, dst_stage_mask, dst_access_mask); + VkDeviceSize offset, size; + if (last_usage_ == usage) { + // Committing the previous write, while not changing the access mask + // (passing false as whether to skip the barrier if no masks are changed + // for this reason). + offset = VkDeviceSize(last_written_range_.first); + size = VkDeviceSize(last_written_range_.second); + } else { + // Changing the stage and access mask - all preceding writes must be + // available not only to the source stage, but to the destination as well. + offset = 0; + size = VK_WHOLE_SIZE; + last_usage_ = usage; + } + command_processor_.PushBufferMemoryBarrier( + buffer_, offset, size, src_stage_mask, dst_stage_mask, src_access_mask, dst_access_mask, + VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, false); + } + last_written_range_ = written_range; +} + +bool VulkanSharedMemory::InitializeTraceSubmitDownloads() { + ResetTraceDownload(); + PrepareForTraceDownload(); + uint32_t download_page_count = trace_download_page_count(); + if (!download_page_count) { + return false; + } + + if (!ui::vulkan::util::CreateDedicatedAllocationBuffer( + command_processor_.GetVulkanDevice(), download_page_count << page_size_log2(), + VK_BUFFER_USAGE_TRANSFER_DST_BIT, ui::vulkan::util::MemoryPurpose::kReadback, + trace_download_buffer_, trace_download_buffer_memory_)) { + REXGPU_ERROR( + "Shared memory: Failed to create a {} KB GPU-written memory download " + "buffer for frame tracing", + download_page_count << page_size_log2() >> 10); + ResetTraceDownload(); + return false; + } + + Use(Usage::kRead); + command_processor_.SubmitBarriers(true); + DeferredCommandBuffer& command_buffer = command_processor_.deferred_command_buffer(); + + size_t download_range_count = trace_download_ranges().size(); + VkBufferCopy* download_regions = command_buffer.CmdCopyBufferEmplace( + buffer_, trace_download_buffer_, uint32_t(download_range_count)); + VkDeviceSize download_buffer_offset = 0; + for (size_t i = 0; i < download_range_count; ++i) { + VkBufferCopy& download_region = download_regions[i]; + const std::pair& download_range = trace_download_ranges()[i]; + download_region.srcOffset = download_range.first; + download_region.dstOffset = download_buffer_offset; + download_region.size = download_range.second; + download_buffer_offset += download_range.second; + } + + command_processor_.PushBufferMemoryBarrier( + trace_download_buffer_, 0, VK_WHOLE_SIZE, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_HOST_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT); + + return true; +} + +void VulkanSharedMemory::InitializeTraceCompleteDownloads() { + if (!trace_download_buffer_memory_) { + return; + } + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + void* download_mapping; + if (dfn.vkMapMemory(device, trace_download_buffer_memory_, 0, VK_WHOLE_SIZE, 0, + &download_mapping) == VK_SUCCESS) { + uint32_t download_buffer_offset = 0; + for (const auto& download_range : trace_download_ranges()) { + trace_writer_.WriteMemoryRead( + download_range.first, download_range.second, + reinterpret_cast(download_mapping) + download_buffer_offset); + } + dfn.vkUnmapMemory(device, trace_download_buffer_memory_); + } else { + REXGPU_ERROR( + "Shared memory: Failed to map the GPU-written memory download buffer " + "for frame tracing"); + } + ResetTraceDownload(); +} + +bool VulkanSharedMemory::AllocateSparseHostGpuMemoryRange(uint32_t offset_allocations, + uint32_t length_allocations) { + if (!length_allocations) { + return true; + } + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + VkMemoryAllocateInfo memory_allocate_info; + memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + memory_allocate_info.pNext = nullptr; + memory_allocate_info.allocationSize = length_allocations + << host_gpu_memory_sparse_granularity_log2(); + memory_allocate_info.memoryTypeIndex = buffer_memory_type_; + VkDeviceMemory memory; + if (dfn.vkAllocateMemory(device, &memory_allocate_info, nullptr, &memory) != VK_SUCCESS) { + REXGPU_ERROR("Shared memory: Failed to allocate sparse buffer memory"); + return false; + } + buffer_memory_.push_back(memory); + + VkSparseMemoryBind bind; + bind.resourceOffset = offset_allocations << host_gpu_memory_sparse_granularity_log2(); + bind.size = memory_allocate_info.allocationSize; + bind.memory = memory; + bind.memoryOffset = 0; + bind.flags = 0; + VkPipelineStageFlags bind_wait_stage_mask = + VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | + VK_PIPELINE_STAGE_TRANSFER_BIT; + if (vulkan_device->properties().tessellationShader) { + bind_wait_stage_mask |= VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT; + } + command_processor_.SparseBindBuffer(buffer_, 1, &bind, bind_wait_stage_mask); + + return true; +} + +bool VulkanSharedMemory::UploadRanges( + const std::vector>& upload_page_ranges) { + if (upload_page_ranges.empty()) { + return true; + } + // upload_page_ranges are sorted, use them to determine the range for the + // ordering barrier. + Use(Usage::kTransferDestination, + std::make_pair(upload_page_ranges.front().first << page_size_log2(), + (upload_page_ranges.back().first + upload_page_ranges.back().second - + upload_page_ranges.front().first) + << page_size_log2())); + command_processor_.SubmitBarriers(true); + DeferredCommandBuffer& command_buffer = command_processor_.deferred_command_buffer(); + uint64_t submission_current = command_processor_.GetCurrentSubmission(); + bool successful = true; + upload_regions_.clear(); + VkBuffer upload_buffer_previous = VK_NULL_HANDLE; + for (auto upload_range : upload_page_ranges) { + uint32_t upload_range_start = upload_range.first; + uint32_t upload_range_length = upload_range.second; + trace_writer_.WriteMemoryRead(upload_range_start << page_size_log2(), + upload_range_length << page_size_log2()); + while (upload_range_length) { + VkBuffer upload_buffer; + VkDeviceSize upload_buffer_offset, upload_buffer_size; + uint8_t* upload_buffer_mapping = upload_buffer_pool_->RequestPartial( + submission_current, upload_range_length << page_size_log2(), + size_t(1) << page_size_log2(), upload_buffer, upload_buffer_offset, upload_buffer_size); + if (upload_buffer_mapping == nullptr) { + REXGPU_ERROR("Shared memory: Failed to get a Vulkan upload buffer"); + successful = false; + break; + } + MakeRangeValid(upload_range_start << page_size_log2(), uint32_t(upload_buffer_size), false); + std::memcpy(upload_buffer_mapping, + memory().TranslatePhysical(upload_range_start << page_size_log2()), + upload_buffer_size); + if (upload_buffer_previous != upload_buffer && !upload_regions_.empty()) { + assert_true(upload_buffer_previous != VK_NULL_HANDLE); + command_buffer.CmdVkCopyBuffer(upload_buffer_previous, buffer_, + uint32_t(upload_regions_.size()), upload_regions_.data()); + upload_regions_.clear(); + } + upload_buffer_previous = upload_buffer; + VkBufferCopy& upload_region = upload_regions_.emplace_back(); + upload_region.srcOffset = upload_buffer_offset; + upload_region.dstOffset = VkDeviceSize(upload_range_start << page_size_log2()); + upload_region.size = upload_buffer_size; + uint32_t upload_buffer_pages = uint32_t(upload_buffer_size >> page_size_log2()); + upload_range_start += upload_buffer_pages; + upload_range_length -= upload_buffer_pages; + } + if (!successful) { + break; + } + } + if (!upload_regions_.empty()) { + assert_true(upload_buffer_previous != VK_NULL_HANDLE); + command_buffer.CmdVkCopyBuffer(upload_buffer_previous, buffer_, + uint32_t(upload_regions_.size()), upload_regions_.data()); + upload_regions_.clear(); + } + return successful; +} + +void VulkanSharedMemory::GetUsageMasks(Usage usage, VkPipelineStageFlags& stage_mask, + VkAccessFlags& access_mask) const { + switch (usage) { + case Usage::kComputeWrite: + stage_mask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + access_mask = VK_ACCESS_SHADER_READ_BIT; + return; + case Usage::kTransferDestination: + stage_mask = VK_PIPELINE_STAGE_TRANSFER_BIT; + access_mask = VK_ACCESS_TRANSFER_WRITE_BIT; + return; + default: + break; + } + stage_mask = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | guest_shader_pipeline_stages_; + access_mask = VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_SHADER_READ_BIT; + switch (usage) { + case Usage::kRead: + stage_mask |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT; + access_mask |= VK_ACCESS_TRANSFER_READ_BIT; + break; + case Usage::kGuestDrawReadWrite: + access_mask |= VK_ACCESS_SHADER_WRITE_BIT; + break; + default: + assert_unhandled_case(usage); + } +} + +void VulkanSharedMemory::ResetTraceDownload() { + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyBuffer, device, trace_download_buffer_); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkFreeMemory, device, trace_download_buffer_memory_); + ReleaseTraceDownloadRanges(); +} + +} // namespace rex::graphics::vulkan diff --git a/src/graphics/vulkan/texture_cache.cpp b/src/graphics/vulkan/texture_cache.cpp new file mode 100644 index 0000000..fc46bf8 --- /dev/null +++ b/src/graphics/vulkan/texture_cache.cpp @@ -0,0 +1,3223 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(non_seamless_cube_map, false, "GPU", "Use non-seamless cube map sampling"); + +namespace rex::graphics::vulkan { + +// Generated with `xb buildshaders`. +namespace shaders { +#include "../shaders/vulkan_spirv/texture_load_128bpb_cs.h" +#include "../shaders/vulkan_spirv/texture_load_128bpb_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_16bpb_cs.h" +#include "../shaders/vulkan_spirv/texture_load_16bpb_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_32bpb_cs.h" +#include "../shaders/vulkan_spirv/texture_load_32bpb_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_64bpb_cs.h" +#include "../shaders/vulkan_spirv/texture_load_64bpb_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_8bpb_cs.h" +#include "../shaders/vulkan_spirv/texture_load_8bpb_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_bgrg8_rgb8_cs.h" +#include "../shaders/vulkan_spirv/texture_load_ctx1_cs.h" +#include "../shaders/vulkan_spirv/texture_load_depth_float_cs.h" +#include "../shaders/vulkan_spirv/texture_load_depth_float_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_depth_unorm_cs.h" +#include "../shaders/vulkan_spirv/texture_load_depth_unorm_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_dxn_rg8_cs.h" +#include "../shaders/vulkan_spirv/texture_load_dxt1_rgba8_cs.h" +#include "../shaders/vulkan_spirv/texture_load_dxt3_rgba8_cs.h" +#include "../shaders/vulkan_spirv/texture_load_dxt3a_cs.h" +#include "../shaders/vulkan_spirv/texture_load_dxt3aas1111_argb4_cs.h" +#include "../shaders/vulkan_spirv/texture_load_dxt5_rgba8_cs.h" +#include "../shaders/vulkan_spirv/texture_load_dxt5a_r8_cs.h" +#include "../shaders/vulkan_spirv/texture_load_gbgr8_rgb8_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r10g11b11_rgba16_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r10g11b11_rgba16_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r10g11b11_rgba16_snorm_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r10g11b11_rgba16_snorm_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r11g11b10_rgba16_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r11g11b10_rgba16_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r11g11b10_rgba16_snorm_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r11g11b10_rgba16_snorm_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r16_snorm_float_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r16_snorm_float_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r16_unorm_float_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r16_unorm_float_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r4g4b4a4_a4r4g4b4_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r4g4b4a4_a4r4g4b4_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r5g5b5a1_b5g5r5a1_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r5g5b5a1_b5g5r5a1_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r5g5b6_b5g6r5_swizzle_rbga_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r5g5b6_b5g6r5_swizzle_rbga_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r5g6b5_b5g6r5_cs.h" +#include "../shaders/vulkan_spirv/texture_load_r5g6b5_b5g6r5_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_rg16_snorm_float_cs.h" +#include "../shaders/vulkan_spirv/texture_load_rg16_snorm_float_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_rg16_unorm_float_cs.h" +#include "../shaders/vulkan_spirv/texture_load_rg16_unorm_float_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_rgba16_snorm_float_cs.h" +#include "../shaders/vulkan_spirv/texture_load_rgba16_snorm_float_scaled_cs.h" +#include "../shaders/vulkan_spirv/texture_load_rgba16_unorm_float_cs.h" +#include "../shaders/vulkan_spirv/texture_load_rgba16_unorm_float_scaled_cs.h" +} // namespace shaders + +namespace { + +// Keep invalid fetch constant texture reads aligned with D3D12 null SRV +// descriptors, which force all sampled channels to 0. +constexpr VkFormat kInvalidTextureFetchFallbackFormat = VK_FORMAT_R8G8B8A8_UNORM; +const VkClearColorValue kInvalidTextureFetchFallbackColor = {{0.0f, 0.0f, 0.0f, 0.0f}}; + +} // namespace + +static_assert(VK_FORMAT_UNDEFINED == VkFormat(0), + "Assuming that skipping a VkFormat in an initializer results in " + "VK_FORMAT_UNDEFINED"); +const VulkanTextureCache::HostFormatPair VulkanTextureCache::kBestHostFormats[64] = { + // k_1_REVERSE + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_1 + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_8 + {{kLoadShaderIndex8bpb, VK_FORMAT_R8_UNORM}, + {kLoadShaderIndex8bpb, VK_FORMAT_R8_SNORM}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR, + true}, + // k_1_5_5_5 + // Red and blue swapped in the load shader for simplicity. + {{kLoadShaderIndexR5G5B5A1ToB5G5R5A1, VK_FORMAT_A1R5G5B5_UNORM_PACK16}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_5_6_5 + // Red and blue swapped in the load shader for simplicity. + {{kLoadShaderIndexR5G6B5ToB5G6R5, VK_FORMAT_R5G6B5_UNORM_PACK16}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, + // k_6_5_5 + // On the host, green bits in blue, blue bits in green. + {{kLoadShaderIndexR5G5B6ToB5G6R5WithRBGASwizzle, VK_FORMAT_R5G6B5_UNORM_PACK16}, + {kLoadShaderIndexUnknown}, + XE_GPU_MAKE_TEXTURE_SWIZZLE(R, B, G, G)}, + // k_8_8_8_8 + {{kLoadShaderIndex32bpb, VK_FORMAT_R8G8B8A8_UNORM}, + {kLoadShaderIndex32bpb, VK_FORMAT_R8G8B8A8_SNORM}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA, + true}, + // k_2_10_10_10 + // Signed 2_10_10_10 is unsupported on D3D12, keep Vulkan behavior aligned. + {{kLoadShaderIndex32bpb, VK_FORMAT_A2B10G10R10_UNORM_PACK32}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_8_A + {{kLoadShaderIndex8bpb, VK_FORMAT_R8_UNORM}, + {kLoadShaderIndex8bpb, VK_FORMAT_R8_SNORM}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR, + true}, + // k_8_B + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_8_8 + {{kLoadShaderIndex16bpb, VK_FORMAT_R8G8_UNORM}, + {kLoadShaderIndex16bpb, VK_FORMAT_R8G8_SNORM}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG, + true}, + // k_Cr_Y1_Cb_Y0_REP + // VK_FORMAT_G8B8G8R8_422_UNORM (added in + // VK_KHR_sampler_ycbcr_conversion and promoted to Vulkan 1.1) is + // optional. + // Signed variant is unsupported on D3D12. + {{kLoadShaderIndex32bpb, VK_FORMAT_G8B8G8R8_422_UNORM, true}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, + // k_Y1_Cr_Y0_Cb_REP + // VK_FORMAT_B8G8R8G8_422_UNORM (added in + // VK_KHR_sampler_ycbcr_conversion and promoted to Vulkan 1.1) is + // optional. + // Signed variant is unsupported on D3D12. + {{kLoadShaderIndex32bpb, VK_FORMAT_B8G8R8G8_422_UNORM, true}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, + // k_16_16_EDRAM + // Not usable as a texture, also has -32...32 range. + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_8_8_8_8_A + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_4_4_4_4 + // Components swapped in the load shader for simplicity. + {{kLoadShaderIndexRGBA4ToARGB4, VK_FORMAT_B4G4R4A4_UNORM_PACK16}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_10_11_11 + // Runtime fallback to float16 may be enabled if normalized RGBA16 host + // formats are not linearly filterable. + {{kLoadShaderIndexR11G11B10ToRGBA16, VK_FORMAT_R16G16B16A16_UNORM}, + {kLoadShaderIndexR11G11B10ToRGBA16SNorm, VK_FORMAT_R16G16B16A16_SNORM}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, + // k_11_11_10 + // Runtime fallback to float16 may be enabled if normalized RGBA16 host + // formats are not linearly filterable. + {{kLoadShaderIndexR10G11B11ToRGBA16, VK_FORMAT_R16G16B16A16_UNORM}, + {kLoadShaderIndexR10G11B11ToRGBA16SNorm, VK_FORMAT_R16G16B16A16_SNORM}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, + // k_DXT1 + // VK_FORMAT_BC1_RGBA_UNORM_BLOCK is optional. + {{kLoadShaderIndex64bpb, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, true}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_DXT2_3 + // VK_FORMAT_BC2_UNORM_BLOCK is optional. + {{kLoadShaderIndex128bpb, VK_FORMAT_BC2_UNORM_BLOCK, true}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_DXT4_5 + // VK_FORMAT_BC3_UNORM_BLOCK is optional. + {{kLoadShaderIndex128bpb, VK_FORMAT_BC3_UNORM_BLOCK, true}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_16_16_16_16_EDRAM + // Not usable as a texture, also has -32...32 range. + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_24_8 + // Keep signed and unsigned sampling on the same R32 float descriptor path + // for parity with D3D12. + {{kLoadShaderIndexDepthUnorm, VK_FORMAT_R32_SFLOAT}, + {kLoadShaderIndexDepthUnorm, VK_FORMAT_R32_SFLOAT}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR, + true}, + // k_24_8_FLOAT + // Keep signed and unsigned sampling on the same R32 float descriptor path + // for parity with D3D12. + {{kLoadShaderIndexDepthFloat, VK_FORMAT_R32_SFLOAT}, + {kLoadShaderIndexDepthFloat, VK_FORMAT_R32_SFLOAT}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR, + true}, + // k_16 + // VK_FORMAT_R16_UNORM and VK_FORMAT_R16_SNORM are optional. + {{kLoadShaderIndex16bpb, VK_FORMAT_R16_UNORM}, + {kLoadShaderIndex16bpb, VK_FORMAT_R16_SNORM}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR, + true}, + // k_16_16 + // VK_FORMAT_R16G16_UNORM and VK_FORMAT_R16G16_SNORM are optional. + {{kLoadShaderIndex32bpb, VK_FORMAT_R16G16_UNORM}, + {kLoadShaderIndex32bpb, VK_FORMAT_R16G16_SNORM}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG, + true}, + // k_16_16_16_16 + // VK_FORMAT_R16G16B16A16_UNORM and VK_FORMAT_R16G16B16A16_SNORM are + // optional. + {{kLoadShaderIndex64bpb, VK_FORMAT_R16G16B16A16_UNORM}, + {kLoadShaderIndex64bpb, VK_FORMAT_R16G16B16A16_SNORM}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA, + true}, + // k_16_EXPAND + {{kLoadShaderIndex16bpb, VK_FORMAT_R16_SFLOAT}, + {kLoadShaderIndex16bpb, VK_FORMAT_R16_SFLOAT}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR, + true}, + // k_16_16_EXPAND + {{kLoadShaderIndex32bpb, VK_FORMAT_R16G16_SFLOAT}, + {kLoadShaderIndex32bpb, VK_FORMAT_R16G16_SFLOAT}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG, + true}, + // k_16_16_16_16_EXPAND + {{kLoadShaderIndex64bpb, VK_FORMAT_R16G16B16A16_SFLOAT}, + {kLoadShaderIndex64bpb, VK_FORMAT_R16G16B16A16_SFLOAT}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA, + true}, + // k_16_FLOAT + {{kLoadShaderIndex16bpb, VK_FORMAT_R16_SFLOAT}, + {kLoadShaderIndex16bpb, VK_FORMAT_R16_SFLOAT}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR, + true}, + // k_16_16_FLOAT + {{kLoadShaderIndex32bpb, VK_FORMAT_R16G16_SFLOAT}, + {kLoadShaderIndex32bpb, VK_FORMAT_R16G16_SFLOAT}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG, + true}, + // k_16_16_16_16_FLOAT + {{kLoadShaderIndex64bpb, VK_FORMAT_R16G16B16A16_SFLOAT}, + {kLoadShaderIndex64bpb, VK_FORMAT_R16G16B16A16_SFLOAT}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA, + true}, + // k_32 + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_32_32 + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_32_32_32_32 + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_32_FLOAT + {{kLoadShaderIndex32bpb, VK_FORMAT_R32_SFLOAT}, + {kLoadShaderIndex32bpb, VK_FORMAT_R32_SFLOAT}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR, + true}, + // k_32_32_FLOAT + {{kLoadShaderIndex64bpb, VK_FORMAT_R32G32_SFLOAT}, + {kLoadShaderIndex64bpb, VK_FORMAT_R32G32_SFLOAT}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG, + true}, + // k_32_32_32_32_FLOAT + {{kLoadShaderIndex128bpb, VK_FORMAT_R32G32B32A32_SFLOAT}, + {kLoadShaderIndex128bpb, VK_FORMAT_R32G32B32A32_SFLOAT}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA, + true}, + // k_32_AS_8 + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_32_AS_8_8 + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_16_MPEG + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_16_16_MPEG + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_8_INTERLACED + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_32_AS_8_INTERLACED + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_32_AS_8_8_INTERLACED + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_16_INTERLACED + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_16_MPEG_INTERLACED + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_16_16_MPEG_INTERLACED + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_DXN + // VK_FORMAT_BC5_UNORM_BLOCK is optional. + {{kLoadShaderIndex128bpb, VK_FORMAT_BC5_UNORM_BLOCK, true}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_8_8_8_8_AS_16_16_16_16 + {{kLoadShaderIndex32bpb, VK_FORMAT_R8G8B8A8_UNORM}, + {kLoadShaderIndex32bpb, VK_FORMAT_R8G8B8A8_SNORM}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA, + true}, + // k_DXT1_AS_16_16_16_16 + // VK_FORMAT_BC1_RGBA_UNORM_BLOCK is optional. + {{kLoadShaderIndex64bpb, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, true}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_DXT2_3_AS_16_16_16_16 + // VK_FORMAT_BC2_UNORM_BLOCK is optional. + {{kLoadShaderIndex128bpb, VK_FORMAT_BC2_UNORM_BLOCK, true}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_DXT4_5_AS_16_16_16_16 + // VK_FORMAT_BC3_UNORM_BLOCK is optional. + {{kLoadShaderIndex128bpb, VK_FORMAT_BC3_UNORM_BLOCK, true}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_2_10_10_10_AS_16_16_16_16 + // Signed 2_10_10_10 is unsupported on D3D12, keep Vulkan behavior aligned. + {{kLoadShaderIndex32bpb, VK_FORMAT_A2B10G10R10_UNORM_PACK32}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_10_11_11_AS_16_16_16_16 + // Runtime fallback to float16 may be enabled if normalized RGBA16 host + // formats are not linearly filterable. + {{kLoadShaderIndexR11G11B10ToRGBA16, VK_FORMAT_R16G16B16A16_UNORM}, + {kLoadShaderIndexR11G11B10ToRGBA16SNorm, VK_FORMAT_R16G16B16A16_SNORM}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, + // k_11_11_10_AS_16_16_16_16 + // Runtime fallback to float16 may be enabled if normalized RGBA16 host + // formats are not linearly filterable. + {{kLoadShaderIndexR10G11B11ToRGBA16, VK_FORMAT_R16G16B16A16_UNORM}, + {kLoadShaderIndexR10G11B11ToRGBA16SNorm, VK_FORMAT_R16G16B16A16_SNORM}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, + // k_32_32_32_FLOAT + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, + // k_DXT3A + {{kLoadShaderIndexDXT3A, VK_FORMAT_R8_UNORM}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_DXT5A + // VK_FORMAT_BC4_UNORM_BLOCK is optional. + {{kLoadShaderIndex64bpb, VK_FORMAT_BC4_UNORM_BLOCK, true}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, + // k_CTX1 + {{kLoadShaderIndexCTX1, VK_FORMAT_R8G8_UNORM}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, + // k_DXT3A_AS_1_1_1_1 + {{kLoadShaderIndexDXT3AAs1111ToARGB4, VK_FORMAT_B4G4R4A4_UNORM_PACK16}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_8_8_8_8_GAMMA_EDRAM + // Not usable as a texture. + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, + // k_2_10_10_10_FLOAT_EDRAM + // Not usable as a texture. + {{kLoadShaderIndexUnknown}, {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, +}; + +// Vulkan requires 2x1 (4:2:2) subsampled images to have an even width. +// Always decompressing them to RGBA8 UNORM for D3D12 parity. + +const VulkanTextureCache::HostFormatPair VulkanTextureCache::kHostFormatGBGRUnaligned = { + {kLoadShaderIndexGBGR8ToRGB8, VK_FORMAT_R8G8B8A8_UNORM, false, true}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB, + false}; + +const VulkanTextureCache::HostFormatPair VulkanTextureCache::kHostFormatBGRGUnaligned = { + {kLoadShaderIndexBGRG8ToRGB8, VK_FORMAT_R8G8B8A8_UNORM, false, true}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB, + false}; + +// Keep BC unaligned fallback mapping compatible with the D3D12 texture cache +// decompression mapping. +const VulkanTextureCache::HostFormatPair VulkanTextureCache::kHostFormatDXT1Unaligned = { + {kLoadShaderIndexDXT1ToRGBA8, VK_FORMAT_R8G8B8A8_UNORM, false, true}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA, + false}; + +const VulkanTextureCache::HostFormatPair VulkanTextureCache::kHostFormatDXT2_3Unaligned = { + {kLoadShaderIndexDXT3ToRGBA8, VK_FORMAT_R8G8B8A8_UNORM, false, true}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA, + false}; + +const VulkanTextureCache::HostFormatPair VulkanTextureCache::kHostFormatDXT4_5Unaligned = { + {kLoadShaderIndexDXT5ToRGBA8, VK_FORMAT_R8G8B8A8_UNORM, false, true}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA, + false}; + +const VulkanTextureCache::HostFormatPair VulkanTextureCache::kHostFormatDXNUnaligned = { + {kLoadShaderIndexDXNToRG8, VK_FORMAT_R8G8_UNORM, false, true}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG, + false}; + +const VulkanTextureCache::HostFormatPair VulkanTextureCache::kHostFormatDXT5AUnaligned = { + {kLoadShaderIndexDXT5AToR8, VK_FORMAT_R8_UNORM, false, true}, + {kLoadShaderIndexUnknown}, + xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR, + false}; + +VulkanTextureCache::~VulkanTextureCache() { + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + for (const std::pair& sampler_pair : samplers_) { + dfn.vkDestroySampler(device, sampler_pair.second.sampler, nullptr); + } + samplers_.clear(); + custom_border_color_sampler_count_ = 0; + COUNT_profile_set("gpu/texture_cache/vulkan/samplers", 0); + sampler_used_last_ = nullptr; + sampler_used_first_ = nullptr; + + ShutdownScaledResolveBuffer(); + + if (null_image_view_3d_ != VK_NULL_HANDLE) { + dfn.vkDestroyImageView(device, null_image_view_3d_, nullptr); + } + if (null_image_view_cube_ != VK_NULL_HANDLE) { + dfn.vkDestroyImageView(device, null_image_view_cube_, nullptr); + } + if (null_image_view_2d_array_ != VK_NULL_HANDLE) { + dfn.vkDestroyImageView(device, null_image_view_2d_array_, nullptr); + } + if (null_image_3d_ != VK_NULL_HANDLE) { + dfn.vkDestroyImage(device, null_image_3d_, nullptr); + } + if (null_image_2d_array_cube_ != VK_NULL_HANDLE) { + dfn.vkDestroyImage(device, null_image_2d_array_cube_, nullptr); + } + for (VkDeviceMemory null_images_memory : null_images_memory_) { + if (null_images_memory != VK_NULL_HANDLE) { + dfn.vkFreeMemory(device, null_images_memory, nullptr); + } + } + for (VkPipeline load_pipeline : load_pipelines_scaled_) { + if (load_pipeline != VK_NULL_HANDLE) { + dfn.vkDestroyPipeline(device, load_pipeline, nullptr); + } + } + for (VkPipeline load_pipeline : load_pipelines_) { + if (load_pipeline != VK_NULL_HANDLE) { + dfn.vkDestroyPipeline(device, load_pipeline, nullptr); + } + } + if (load_pipeline_layout_ != VK_NULL_HANDLE) { + dfn.vkDestroyPipelineLayout(device, load_pipeline_layout_, nullptr); + } + + // Textures memory is allocated using the Vulkan Memory Allocator, destroy all + // textures before destroying VMA. + DestroyAllTextures(true); + + if (vma_allocator_ != VK_NULL_HANDLE) { + vmaDestroyAllocator(vma_allocator_); + } +} + +void VulkanTextureCache::BeginSubmission(uint64_t new_submission_index) { + TextureCache::BeginSubmission(new_submission_index); + + if (!null_images_cleared_ && null_image_2d_array_cube_ != VK_NULL_HANDLE && + null_image_3d_ != VK_NULL_HANDLE) { + VkImage null_images[] = {null_image_2d_array_cube_, null_image_3d_}; + VkImageSubresourceRange null_image_subresource_range( + ui::vulkan::util::InitializeSubresourceRange()); + for (size_t i = 0; i < rex::countof(null_images); ++i) { + command_processor_.PushImageMemoryBarrier( + null_images[i], null_image_subresource_range, 0, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, + VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, + false); + } + command_processor_.SubmitBarriers(true); + DeferredCommandBuffer& command_buffer = command_processor_.deferred_command_buffer(); + VkClearColorValue null_image_clear_color = kInvalidTextureFetchFallbackColor; + for (size_t i = 0; i < rex::countof(null_images); ++i) { + command_buffer.CmdVkClearColorImage(null_images[i], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + &null_image_clear_color, 1, + &null_image_subresource_range); + } + for (size_t i = 0; i < rex::countof(null_images); ++i) { + command_processor_.PushImageMemoryBarrier( + null_images[i], null_image_subresource_range, VK_PIPELINE_STAGE_TRANSFER_BIT, + guest_shader_pipeline_stages_, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, false); + } + null_images_cleared_ = true; + } +} + +void VulkanTextureCache::BeginFrame() { + TextureCache::BeginFrame(); + + std::memset(unsupported_format_features_used_, 0, sizeof(unsupported_format_features_used_)); +} + +void VulkanTextureCache::EndFrame() { + bool unsupported_header_written = false; + for (uint32_t i = 0; i < 64; ++i) { + uint32_t unsupported_features = unsupported_format_features_used_[i]; + if (!unsupported_features) { + continue; + } + if (!unsupported_header_written) { + REXGPU_ERROR("Unsupported texture formats used in the frame:"); + unsupported_header_written = true; + } + REXGPU_ERROR("* {}{}{}{}", FormatInfo::Get(xenos::TextureFormat(i))->name, + unsupported_features & kUnsupportedResourceBit ? " resource" : "", + unsupported_features & kUnsupportedUnormBit ? " unsigned" : "", + unsupported_features & kUnsupportedSnormBit ? " signed" : ""); + unsupported_format_features_used_[i] = 0; + } +} + +void VulkanTextureCache::RequestTextures(uint32_t used_texture_mask) { +#if XE_GPU_FINE_GRAINED_DRAW_SCOPES + SCOPE_profile_cpu_f("gpu"); +#endif // XE_GPU_FINE_GRAINED_DRAW_SCOPES + + TextureCache::RequestTextures(used_texture_mask); + + // Pre-create 3D-as-2D wrappers while still in texture request phase. + if (REXCVAR_GET(gpu_3d_to_2d_texture)) { + uint32_t textures_3d = used_texture_mask; + uint32_t index_3d; + while (rex::bit_scan_forward(textures_3d, &index_3d)) { + textures_3d &= ~(uint32_t(1) << index_3d); + const TextureBinding* binding = GetValidTextureBinding(index_3d); + if (!binding || binding->key.dimension != xenos::DataDimension::k3D) { + continue; + } + VulkanTexture* texture = static_cast(binding->texture); + if (texture) { + texture->GetOrCreate3DAs2DImageView(false, binding->host_swizzle); + } + VulkanTexture* texture_signed = static_cast(binding->texture_signed); + if (texture_signed) { + texture_signed->GetOrCreate3DAs2DImageView(true, binding->host_swizzle); + } + } + } + + // Transition the textures into the needed usage. + VkPipelineStageFlags dst_stage_mask; + VkAccessFlags dst_access_mask; + VkImageLayout new_layout; + GetTextureUsageMasks(VulkanTexture::Usage::kGuestShaderSampled, dst_stage_mask, dst_access_mask, + new_layout); + uint32_t textures_remaining = used_texture_mask; + uint32_t index; + while (rex::bit_scan_forward(textures_remaining, &index)) { + textures_remaining &= ~(uint32_t(1) << index); + const TextureBinding* binding = GetValidTextureBinding(index); + if (!binding) { + continue; + } + VulkanTexture* binding_texture = static_cast(binding->texture); + if (binding_texture != nullptr) { + // Will be referenced by the command buffer, so mark as used. + binding_texture->MarkAsUsed(); + VulkanTexture::Usage old_usage = + binding_texture->SetUsage(VulkanTexture::Usage::kGuestShaderSampled); + if (old_usage != VulkanTexture::Usage::kGuestShaderSampled) { + VkPipelineStageFlags src_stage_mask; + VkAccessFlags src_access_mask; + VkImageLayout old_layout; + GetTextureUsageMasks(old_usage, src_stage_mask, src_access_mask, old_layout); + command_processor_.PushImageMemoryBarrier(binding_texture->image(), + ui::vulkan::util::InitializeSubresourceRange(), + src_stage_mask, dst_stage_mask, src_access_mask, + dst_access_mask, old_layout, new_layout); + } + } + VulkanTexture* binding_texture_signed = static_cast(binding->texture_signed); + if (binding_texture_signed != nullptr) { + binding_texture_signed->MarkAsUsed(); + VulkanTexture::Usage old_usage = + binding_texture_signed->SetUsage(VulkanTexture::Usage::kGuestShaderSampled); + if (old_usage != VulkanTexture::Usage::kGuestShaderSampled) { + VkPipelineStageFlags src_stage_mask; + VkAccessFlags src_access_mask; + VkImageLayout old_layout; + GetTextureUsageMasks(old_usage, src_stage_mask, src_access_mask, old_layout); + command_processor_.PushImageMemoryBarrier(binding_texture_signed->image(), + ui::vulkan::util::InitializeSubresourceRange(), + src_stage_mask, dst_stage_mask, src_access_mask, + dst_access_mask, old_layout, new_layout); + } + } + } +} + +VkImageView VulkanTextureCache::GetActiveBindingOrNullImageView(uint32_t fetch_constant_index, + xenos::FetchOpDimension dimension, + bool is_signed) { + VkImageView image_view = VK_NULL_HANDLE; + const TextureBinding* binding = GetValidTextureBinding(fetch_constant_index); + if (binding && AreDimensionsCompatible(dimension, binding->key.dimension)) { + bool force_special_view = + binding->key.dimension == xenos::DataDimension::k3D && + (dimension == xenos::FetchOpDimension::k1D || dimension == xenos::FetchOpDimension::k2D); + if (force_special_view) { + Texture* texture = nullptr; + bool use_signed = is_signed && texture_util::IsAnySignSigned(binding->swizzled_signs); + if (use_signed && IsSignedVersionSeparateForFormat(binding->key)) { + texture = binding->texture_signed; + } else { + texture = binding->texture; + } + if (texture) { + image_view = static_cast(texture)->GetOrCreate3DAs2DImageView( + use_signed, binding->host_swizzle); + } + } else { + const VulkanTextureBinding& vulkan_binding = vulkan_texture_bindings_[fetch_constant_index]; + image_view = + is_signed ? vulkan_binding.image_view_signed : vulkan_binding.image_view_unsigned; + } + } + if (image_view != VK_NULL_HANDLE) { + return image_view; + } + if (command_processor_.GetVulkanDevice()->properties().nullDescriptor) { + return VK_NULL_HANDLE; + } + switch (dimension) { + case xenos::FetchOpDimension::k3DOrStacked: + return null_image_view_3d_; + case xenos::FetchOpDimension::kCube: + return null_image_view_cube_; + default: + return null_image_view_2d_array_; + } +} + +VulkanTextureCache::SamplerParameters VulkanTextureCache::GetSamplerParameters( + const VulkanShader::SamplerBinding& binding) const { + const auto& regs = register_file(); + xenos::xe_gpu_texture_fetch_t fetch = regs.GetTextureFetch(binding.fetch_constant); + + SamplerParameters parameters; + + xenos::ClampMode fetch_clamp_x, fetch_clamp_y, fetch_clamp_z; + texture_util::GetClampModesForDimension(fetch, fetch_clamp_x, fetch_clamp_y, fetch_clamp_z); + parameters.clamp_x = NormalizeClampMode(fetch_clamp_x); + parameters.clamp_y = NormalizeClampMode(fetch_clamp_y); + parameters.clamp_z = NormalizeClampMode(fetch_clamp_z); + if (xenos::ClampModeUsesBorder(parameters.clamp_x) || + xenos::ClampModeUsesBorder(parameters.clamp_y) || + xenos::ClampModeUsesBorder(parameters.clamp_z)) { + parameters.border_color = fetch.border_color; + } else { + parameters.border_color = xenos::BorderColor::k_ABGR_Black; + } + + xenos::TextureFilter mag_filter = binding.mag_filter == xenos::TextureFilter::kUseFetchConst + ? fetch.mag_filter + : binding.mag_filter; + parameters.mag_linear = mag_filter == xenos::TextureFilter::kLinear; + xenos::TextureFilter min_filter = binding.min_filter == xenos::TextureFilter::kUseFetchConst + ? fetch.min_filter + : binding.min_filter; + parameters.min_linear = min_filter == xenos::TextureFilter::kLinear; + xenos::TextureFilter mip_filter = binding.mip_filter == xenos::TextureFilter::kUseFetchConst + ? fetch.mip_filter + : binding.mip_filter; + parameters.mip_linear = mip_filter == xenos::TextureFilter::kLinear; + xenos::AnisoFilter aniso_filter = binding.aniso_filter == xenos::AnisoFilter::kUseFetchConst + ? fetch.aniso_filter + : binding.aniso_filter; + aniso_filter = std::min(aniso_filter, max_anisotropy_); + if (parameters.mag_linear || parameters.min_linear || parameters.mip_linear || + aniso_filter != xenos::AnisoFilter::kDisabled) { + // Check if the texture is actually filterable on the host. + bool linear_filterable = true; + TextureKey texture_key; + uint8_t texture_swizzled_signs; + BindingInfoFromFetchConstant(fetch, texture_key, &texture_swizzled_signs); + if (texture_key.is_valid) { + const HostFormatPair& host_format_pair = GetHostFormatPair(texture_key); + if ((texture_util::IsAnySignNotSigned(texture_swizzled_signs) && + !host_format_pair.format_unsigned.linear_filterable) || + (texture_util::IsAnySignSigned(texture_swizzled_signs) && + !host_format_pair.format_signed.linear_filterable)) { + linear_filterable = false; + } + } else { + linear_filterable = false; + } + if (!linear_filterable) { + parameters.mag_linear = 0; + parameters.min_linear = 0; + parameters.mip_linear = 0; + aniso_filter = xenos::AnisoFilter::kDisabled; + } + } + bool min_mag_linear = parameters.mag_linear && parameters.min_linear; + bool mip_filter_bilinear_or_trilinear = + mip_filter == xenos::TextureFilter::kPoint || mip_filter == xenos::TextureFilter::kLinear; + parameters.mip_base_map = mip_filter == xenos::TextureFilter::kBaseMap; + uint32_t mip_min_level, mip_max_level; + texture_util::GetSubresourcesFromFetchConstant(fetch, nullptr, nullptr, nullptr, nullptr, nullptr, + &mip_min_level, &mip_max_level); + parameters.mip_min_level = mip_min_level; + bool has_mips = mip_max_level > mip_min_level; + int32_t anisotropic_override = REXCVAR_GET(anisotropic_override); + if (anisotropic_override > -1 && anisotropic_override < 6 && has_mips && + !parameters.mip_base_map && min_mag_linear && mip_filter_bilinear_or_trilinear) { + aniso_filter = xenos::AnisoFilter(anisotropic_override); + } + aniso_filter = std::min(aniso_filter, max_anisotropy_); + if (aniso_filter != xenos::AnisoFilter::kDisabled) { + // Match D3D12 behavior: anisotropic filtering forces linear min/mag/mip. + parameters.mag_linear = 1; + parameters.min_linear = 1; + parameters.mip_linear = 1; + } + parameters.aniso_filter = aniso_filter; + + return parameters; +} + +VkSampler VulkanTextureCache::UseSampler(SamplerParameters parameters, bool& has_overflown_out) { + assert_true(command_processor_.submission_open()); + uint64_t submission_current = command_processor_.GetCurrentSubmission(); + + // Try to find an existing sampler. + auto it_existing = samplers_.find(parameters); + if (it_existing != samplers_.end()) { + std::pair& sampler = *it_existing; + assert_true(sampler.second.last_usage_submission <= submission_current); + // This is called very frequently, don't relink unless needed for caching. + if (sampler.second.last_usage_submission < submission_current) { + // Move to the front of the LRU queue. + sampler.second.last_usage_submission = submission_current; + if (sampler.second.used_next) { + if (sampler.second.used_previous) { + sampler.second.used_previous->second.used_next = sampler.second.used_next; + } else { + sampler_used_first_ = sampler.second.used_next; + } + sampler.second.used_next->second.used_previous = sampler.second.used_previous; + sampler.second.used_previous = sampler_used_last_; + sampler.second.used_next = nullptr; + sampler_used_last_->second.used_next = &sampler; + sampler_used_last_ = &sampler; + } + } + has_overflown_out = false; + return sampler.second.sampler; + } + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + // See if an existing sampler can be destroyed to create space for the new + // one. + if (samplers_.size() >= sampler_max_count_) { + assert_not_null(sampler_used_first_); + if (!sampler_used_first_) { + has_overflown_out = false; + return VK_NULL_HANDLE; + } + if (sampler_used_first_->second.last_usage_submission > + command_processor_.GetCompletedSubmission()) { + has_overflown_out = true; + return VK_NULL_HANDLE; + } + auto it_reuse = samplers_.find(sampler_used_first_->first); + if (sampler_used_first_->second.uses_custom_border_color) { + assert_true(custom_border_color_sampler_count_ > 0); + if (custom_border_color_sampler_count_) { + --custom_border_color_sampler_count_; + } + } + dfn.vkDestroySampler(device, sampler_used_first_->second.sampler, nullptr); + if (sampler_used_first_->second.used_next) { + sampler_used_first_->second.used_next->second.used_previous = + sampler_used_first_->second.used_previous; + } else { + sampler_used_last_ = sampler_used_first_->second.used_previous; + } + sampler_used_first_ = sampler_used_first_->second.used_next; + assert_true(it_reuse != samplers_.end()); + if (it_reuse != samplers_.end()) { + // This destroys the Sampler object. + samplers_.erase(it_reuse); + COUNT_profile_set("gpu/texture_cache/vulkan/samplers", samplers_.size()); + } else { + has_overflown_out = false; + return VK_NULL_HANDLE; + } + } + + // Create a new sampler and make it the least recently used. + // The values are normalized, and unsupported ones are excluded, in + // GetSamplerParameters. + VkSamplerCreateInfo sampler_create_info = {}; + sampler_create_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + if (vulkan_device->properties().nonSeamlessCubeMap && REXCVAR_GET(non_seamless_cube_map)) { + sampler_create_info.flags |= VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT; + } + sampler_create_info.magFilter = parameters.mag_linear ? VK_FILTER_LINEAR : VK_FILTER_NEAREST; + sampler_create_info.minFilter = parameters.min_linear ? VK_FILTER_LINEAR : VK_FILTER_NEAREST; + sampler_create_info.mipmapMode = + parameters.mip_linear ? VK_SAMPLER_MIPMAP_MODE_LINEAR : VK_SAMPLER_MIPMAP_MODE_NEAREST; + static const VkSamplerAddressMode kAddressModeMap[] = { + // kRepeat + VK_SAMPLER_ADDRESS_MODE_REPEAT, + // kMirroredRepeat + VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, + // kClampToEdge + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + // kMirrorClampToEdge + VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, + // kClampToHalfway + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + // kMirrorClampToHalfway + VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, + // kClampToBorder + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, + // kMirrorClampToBorder + VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, + }; + sampler_create_info.addressModeU = kAddressModeMap[uint32_t(parameters.clamp_x)]; + sampler_create_info.addressModeV = kAddressModeMap[uint32_t(parameters.clamp_y)]; + sampler_create_info.addressModeW = kAddressModeMap[uint32_t(parameters.clamp_z)]; + // LOD biasing is performed in shaders. + if (parameters.aniso_filter != xenos::AnisoFilter::kDisabled) { + sampler_create_info.anisotropyEnable = VK_TRUE; + sampler_create_info.maxAnisotropy = + float(UINT32_C(1) << (uint32_t(parameters.aniso_filter) - + uint32_t(xenos::AnisoFilter::kMax_1_1))); + } + sampler_create_info.minLod = float(parameters.mip_min_level); + if (parameters.mip_base_map) { + assert_false(parameters.mip_linear); + sampler_create_info.maxLod = sampler_create_info.minLod + 0.25f; + } else { + sampler_create_info.maxLod = VK_LOD_CLAMP_NONE; + } + bool uses_custom_border_color = false; + VkSamplerCustomBorderColorCreateInfoEXT sampler_custom_border_color_create_info = {}; + const bool custom_border_colors_supported = vulkan_device->properties().customBorderColors; + const bool custom_border_color_slots_available = + custom_border_color_sampler_count_ < vulkan_device->properties().maxCustomBorderColorSamplers; + switch (parameters.border_color) { + case xenos::BorderColor::k_ABGR_White: + sampler_create_info.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; + break; + case xenos::BorderColor::k_ACBYCR_Black: + case xenos::BorderColor::k_ACBCRY_Black: + if (custom_border_colors_supported && custom_border_color_slots_available) { + sampler_create_info.borderColor = VK_BORDER_COLOR_FLOAT_CUSTOM_EXT; + sampler_custom_border_color_create_info.sType = + VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT; + sampler_custom_border_color_create_info.pNext = sampler_create_info.pNext; + sampler_custom_border_color_create_info.customBorderColor.float32[0] = + parameters.border_color == xenos::BorderColor::k_ACBYCR_Black ? 0.5f : 0.0f; + sampler_custom_border_color_create_info.customBorderColor.float32[1] = + parameters.border_color == xenos::BorderColor::k_ACBYCR_Black ? 0.0f : 0.5f; + sampler_custom_border_color_create_info.customBorderColor.float32[2] = 0.5f; + sampler_custom_border_color_create_info.customBorderColor.float32[3] = 0.0f; + sampler_custom_border_color_create_info.format = + vulkan_device->properties().customBorderColorWithoutFormat + ? VK_FORMAT_UNDEFINED + : VK_FORMAT_R32G32B32A32_SFLOAT; + sampler_create_info.pNext = &sampler_custom_border_color_create_info; + uses_custom_border_color = true; + } else { + static bool custom_border_color_fallback_logged = false; + if (!custom_border_color_fallback_logged) { + custom_border_color_fallback_logged = true; + if (!custom_border_colors_supported) { + REXGPU_WARN( + "VulkanTextureCache: VK_EXT_custom_border_color support is unavailable; " + "falling back to transparent black for YCbCr border color sampling"); + } else { + REXGPU_WARN( + "VulkanTextureCache: maxCustomBorderColorSamplers limit ({}) reached; " + "falling back to transparent black for additional YCbCr border samplers", + vulkan_device->properties().maxCustomBorderColorSamplers); + } + } + sampler_create_info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; + } + break; + default: + sampler_create_info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; + break; + } + VkSampler vulkan_sampler; + if (dfn.vkCreateSampler(device, &sampler_create_info, nullptr, &vulkan_sampler) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanTextureCache: Failed to create the sampler for parameters " + "0x{:08X}", + parameters.value); + has_overflown_out = false; + return VK_NULL_HANDLE; + } + std::pair& new_sampler = + *(samplers_ + .emplace(std::piecewise_construct, std::forward_as_tuple(parameters), + std::forward_as_tuple()) + .first); + COUNT_profile_set("gpu/texture_cache/vulkan/samplers", samplers_.size()); + new_sampler.second.sampler = vulkan_sampler; + new_sampler.second.uses_custom_border_color = uses_custom_border_color; + new_sampler.second.last_usage_submission = submission_current; + new_sampler.second.used_previous = sampler_used_last_; + new_sampler.second.used_next = nullptr; + if (uses_custom_border_color) { + ++custom_border_color_sampler_count_; + } + if (sampler_used_last_) { + sampler_used_last_->second.used_next = &new_sampler; + } else { + sampler_used_first_ = &new_sampler; + } + sampler_used_last_ = &new_sampler; + return vulkan_sampler; +} + +uint64_t VulkanTextureCache::GetSubmissionToAwaitOnSamplerOverflow( + uint32_t overflowed_sampler_count) const { + if (!overflowed_sampler_count) { + return 0; + } + std::pair* sampler_used = sampler_used_first_; + if (!sampler_used_first_) { + return 0; + } + for (uint32_t samplers_remaining = overflowed_sampler_count - 1; samplers_remaining; + --samplers_remaining) { + std::pair* sampler_used_next = sampler_used->second.used_next; + if (!sampler_used_next) { + break; + } + sampler_used = sampler_used_next; + } + return sampler_used->second.last_usage_submission; +} + +VkImageView VulkanTextureCache::RequestSwapTexture(uint32_t& width_scaled_out, + uint32_t& height_scaled_out, + xenos::TextureFormat& format_out, + uint32_t* width_unscaled_out, + uint32_t* height_unscaled_out, + bool* swap_source_needs_rb_swap_out) { + const auto& regs = register_file(); + xenos::xe_gpu_texture_fetch_t fetch = regs.GetTextureFetch(0); + TextureKey key; + BindingInfoFromFetchConstant(fetch, key, nullptr); + if (!key.is_valid || key.base_page == 0 || key.dimension != xenos::DataDimension::k2DOrStacked) { + return nullptr; + } + VulkanTexture* texture = static_cast(FindOrCreateTexture(key)); + if (!texture) { + return VK_NULL_HANDLE; + } + uint32_t host_swizzle = GuestToHostSwizzle(fetch.swizzle, GetHostFormatSwizzle(key)); + if (swap_source_needs_rb_swap_out) { + auto swizzle_component = [](uint32_t swizzle, + uint32_t component_index) -> xenos::XE_GPU_TEXTURE_SWIZZLE { + return xenos::XE_GPU_TEXTURE_SWIZZLE((swizzle >> (3 * component_index)) & 0b111); + }; + *swap_source_needs_rb_swap_out = + swizzle_component(host_swizzle, 0) == xenos::XE_GPU_TEXTURE_SWIZZLE_B && + swizzle_component(host_swizzle, 1) == xenos::XE_GPU_TEXTURE_SWIZZLE_G && + swizzle_component(host_swizzle, 2) == xenos::XE_GPU_TEXTURE_SWIZZLE_R; + } + VkImageView texture_view = texture->GetView(false, host_swizzle, false); + if (texture_view == VK_NULL_HANDLE) { + return VK_NULL_HANDLE; + } + if (!LoadTextureData(*texture)) { + return VK_NULL_HANDLE; + } + texture->MarkAsUsed(); + VulkanTexture::Usage old_usage = texture->SetUsage(VulkanTexture::Usage::kSwapSampled); + if (old_usage != VulkanTexture::Usage::kSwapSampled) { + VkPipelineStageFlags src_stage_mask, dst_stage_mask; + VkAccessFlags src_access_mask, dst_access_mask; + VkImageLayout old_layout, new_layout; + GetTextureUsageMasks(old_usage, src_stage_mask, src_access_mask, old_layout); + GetTextureUsageMasks(VulkanTexture::Usage::kSwapSampled, dst_stage_mask, dst_access_mask, + new_layout); + command_processor_.PushImageMemoryBarrier( + texture->image(), ui::vulkan::util::InitializeSubresourceRange(), src_stage_mask, + dst_stage_mask, src_access_mask, dst_access_mask, old_layout, new_layout); + } + // Only texture->key, not the result of BindingInfoFromFetchConstant, contains + // whether the texture is scaled. + key = texture->key(); + if (width_unscaled_out) { + *width_unscaled_out = key.GetWidth(); + } + if (height_unscaled_out) { + *height_unscaled_out = key.GetHeight(); + } + width_scaled_out = key.GetWidth() * (key.scaled_resolve ? draw_resolution_scale_x() : 1); + height_scaled_out = key.GetHeight() * (key.scaled_resolve ? draw_resolution_scale_y() : 1); + format_out = key.format; + return texture_view; +} + +bool VulkanTextureCache::IsSignedVersionSeparateForFormat(TextureKey key) const { + const HostFormatPair& host_format_pair = GetHostFormatPair(key); + if (host_format_pair.format_unsigned.format == VK_FORMAT_UNDEFINED || + host_format_pair.format_signed.format == VK_FORMAT_UNDEFINED) { + // Just one signedness. + return false; + } + return !host_format_pair.unsigned_signed_compatible; +} + +bool VulkanTextureCache::IsScaledResolveSupportedForFormat(TextureKey key) const { + if (!IsDrawResolutionScaled()) { + return false; + } + const HostFormatPair& host_format_pair = GetHostFormatPair(key); + bool host_format_is_signed; + if (IsSignedVersionSeparateForFormat(key)) { + host_format_is_signed = bool(key.signed_separate); + } else { + host_format_is_signed = host_format_pair.format_unsigned.load_shader == kLoadShaderIndexUnknown; + } + LoadShaderIndex load_shader = + (host_format_is_signed ? host_format_pair.format_signed : host_format_pair.format_unsigned) + .load_shader; + return load_shader != kLoadShaderIndexUnknown && + load_pipelines_scaled_[load_shader] != VK_NULL_HANDLE; +} + +uint32_t VulkanTextureCache::GetHostFormatSwizzle(TextureKey key) const { + return GetHostFormatPair(key).swizzle; +} + +uint32_t VulkanTextureCache::GetMaxHostTextureWidthHeight(xenos::DataDimension dimension) const { + const ui::vulkan::VulkanDevice::Properties& device_properties = + command_processor_.GetVulkanDevice()->properties(); + switch (dimension) { + case xenos::DataDimension::k1D: + case xenos::DataDimension::k2DOrStacked: + // 1D and 2D are emulated as 2D arrays. + return device_properties.maxImageDimension2D; + case xenos::DataDimension::k3D: + return device_properties.maxImageDimension3D; + case xenos::DataDimension::kCube: + return device_properties.maxImageDimensionCube; + default: + assert_unhandled_case(dimension); + return 0; + } +} + +uint32_t VulkanTextureCache::GetMaxHostTextureDepthOrArraySize( + xenos::DataDimension dimension) const { + const ui::vulkan::VulkanDevice::Properties& device_properties = + command_processor_.GetVulkanDevice()->properties(); + switch (dimension) { + case xenos::DataDimension::k1D: + case xenos::DataDimension::k2DOrStacked: + // 1D and 2D are emulated as 2D arrays. + return device_properties.maxImageArrayLayers; + case xenos::DataDimension::k3D: + return device_properties.maxImageDimension3D; + case xenos::DataDimension::kCube: + // Not requesting the imageCubeArray feature, and the Xenos doesn't + // support cube map arrays. + return 6; + default: + assert_unhandled_case(dimension); + return 0; + } +} + +std::unique_ptr VulkanTextureCache::CreateTexture(TextureKey key) { + VkFormat formats[] = {VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED}; + const HostFormatPair& host_format = GetHostFormatPair(key); + if (host_format.format_signed.format == VK_FORMAT_UNDEFINED) { + // Only the unsigned format may be available, if at all. + formats[0] = host_format.format_unsigned.format; + } else if (host_format.format_unsigned.format == VK_FORMAT_UNDEFINED) { + // Only the signed format may be available, if at all. + formats[0] = host_format.format_signed.format; + } else { + // Both unsigned and signed formats are available. + if (IsSignedVersionSeparateForFormat(key)) { + formats[0] = key.signed_separate ? host_format.format_signed.format + : host_format.format_unsigned.format; + } else { + // Same format for unsigned and signed, or compatible formats. + formats[0] = host_format.format_unsigned.format; + if (host_format.format_signed.format != host_format.format_unsigned.format) { + assert_not_zero(host_format.unsigned_signed_compatible); + formats[1] = host_format.format_signed.format; + } + } + } + if (formats[0] == VK_FORMAT_UNDEFINED) { + unsupported_format_features_used_[uint32_t(key.format)] |= kUnsupportedResourceBit; + return nullptr; + } + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + bool is_3d = key.dimension == xenos::DataDimension::k3D; + uint32_t depth_or_array_size = key.GetDepthOrArraySize(); + + VkImageCreateInfo image_create_info; + VkImageCreateInfo* image_create_info_last = &image_create_info; + image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + image_create_info.pNext = nullptr; + image_create_info.flags = 0; + if (formats[1] != VK_FORMAT_UNDEFINED) { + image_create_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; + } + if (key.dimension == xenos::DataDimension::kCube) { + image_create_info.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; + } + image_create_info.imageType = is_3d ? VK_IMAGE_TYPE_3D : VK_IMAGE_TYPE_2D; + image_create_info.format = formats[0]; + image_create_info.extent.width = key.GetWidth(); + image_create_info.extent.height = key.GetHeight(); + if (key.scaled_resolve) { + image_create_info.extent.width *= draw_resolution_scale_x(); + image_create_info.extent.height *= draw_resolution_scale_y(); + } + image_create_info.extent.depth = is_3d ? depth_or_array_size : 1; + image_create_info.mipLevels = key.mip_max_level + 1; + image_create_info.arrayLayers = is_3d ? 1 : depth_or_array_size; + image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; + image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; + image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + image_create_info.queueFamilyIndexCount = 0; + image_create_info.pQueueFamilyIndices = nullptr; + image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + VkImageFormatListCreateInfo image_format_list_create_info; + if (formats[1] != VK_FORMAT_UNDEFINED && + vulkan_device->extensions().ext_1_2_KHR_image_format_list) { + image_create_info_last->pNext = &image_format_list_create_info; + image_create_info_last = reinterpret_cast(&image_format_list_create_info); + image_format_list_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO; + image_format_list_create_info.pNext = nullptr; + image_format_list_create_info.viewFormatCount = 2; + image_format_list_create_info.pViewFormats = formats; + } + + VmaAllocationCreateInfo allocation_create_info = {}; + allocation_create_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; + + VkImage image; + VmaAllocation allocation; + if (vmaCreateImage(vma_allocator_, &image_create_info, &allocation_create_info, &image, + &allocation, nullptr)) { + return nullptr; + } + + return std::unique_ptr(new VulkanTexture(*this, key, image, allocation)); +} + +bool VulkanTextureCache::EnsureScaledResolveMemoryCommitted(uint32_t start_unscaled, + uint32_t length_unscaled, + uint32_t length_scaled_alignment_log2) { + uint64_t start_scaled, length_scaled; + if (!GetScaledResolveRange(start_unscaled, length_unscaled, length_scaled_alignment_log2, + start_scaled, length_scaled)) { + return false; + } + return EnsureScaledResolveBufferAllocated(start_scaled, length_scaled); +} + +bool VulkanTextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture, bool load_base, + bool load_mips) { + VulkanTexture& vulkan_texture = static_cast(texture); + TextureKey texture_key = vulkan_texture.key(); + + // Get the pipeline. + const HostFormatPair& host_format_pair = GetHostFormatPair(texture_key); + bool host_format_is_signed; + if (IsSignedVersionSeparateForFormat(texture_key)) { + host_format_is_signed = bool(texture_key.signed_separate); + } else { + host_format_is_signed = host_format_pair.format_unsigned.load_shader == kLoadShaderIndexUnknown; + } + const HostFormat& host_format = + host_format_is_signed ? host_format_pair.format_signed : host_format_pair.format_unsigned; + LoadShaderIndex load_shader = host_format.load_shader; + if (load_shader == kLoadShaderIndexUnknown) { + return false; + } + VkPipeline pipeline = texture_key.scaled_resolve ? load_pipelines_scaled_[load_shader] + : load_pipelines_[load_shader]; + if (pipeline == VK_NULL_HANDLE) { + return false; + } + const LoadShaderInfo& load_shader_info = GetLoadShaderInfo(load_shader); + LoadShaderIndex load_shader_float_convert = kLoadShaderIndexUnknown; + if (host_format.format == VK_FORMAT_R16G16B16A16_SFLOAT) { + switch (load_shader) { + case kLoadShaderIndexR10G11B11ToRGBA16: + case kLoadShaderIndexR11G11B10ToRGBA16: + load_shader_float_convert = kLoadShaderIndexRGBA16UNormToFloat; + break; + case kLoadShaderIndexR10G11B11ToRGBA16SNorm: + case kLoadShaderIndexR11G11B10ToRGBA16SNorm: + load_shader_float_convert = kLoadShaderIndexRGBA16SNormToFloat; + break; + default: + break; + } + } + const LoadShaderInfo* load_shader_info_float_convert = nullptr; + VkPipeline pipeline_float_convert = VK_NULL_HANDLE; + if (load_shader_float_convert != kLoadShaderIndexUnknown) { + pipeline_float_convert = texture_key.scaled_resolve + ? load_pipelines_scaled_[load_shader_float_convert] + : load_pipelines_[load_shader_float_convert]; + if (pipeline_float_convert == VK_NULL_HANDLE) { + return false; + } + load_shader_info_float_convert = &GetLoadShaderInfo(load_shader_float_convert); + } + + // Get the guest layout. + const texture_util::TextureGuestLayout& guest_layout = vulkan_texture.guest_layout(); + xenos::DataDimension dimension = texture_key.dimension; + bool is_3d = dimension == xenos::DataDimension::k3D; + bool is_3d_tiling = is_3d || vulkan_texture.force_load_3d_tiling(); + uint32_t width = texture_key.GetWidth(); + uint32_t height = texture_key.GetHeight(); + uint32_t depth_or_array_size = texture_key.GetDepthOrArraySize(); + uint32_t depth = is_3d ? depth_or_array_size : 1; + uint32_t array_size = is_3d ? 1 : depth_or_array_size; + xenos::TextureFormat guest_format = texture_key.format; + const FormatInfo* guest_format_info = FormatInfo::Get(guest_format); + uint32_t block_width = guest_format_info->block_width; + uint32_t block_height = guest_format_info->block_height; + uint32_t bytes_per_block = guest_format_info->bytes_per_block(); + uint32_t level_first = load_base ? 0 : 1; + uint32_t level_last = load_mips ? texture_key.mip_max_level : 0; + assert_true(level_first <= level_last); + uint32_t level_packed = guest_layout.packed_level; + uint32_t level_stored_first = std::min(level_first, level_packed); + uint32_t level_stored_last = std::min(level_last, level_packed); + uint32_t texture_resolution_scale_x = texture_key.scaled_resolve ? draw_resolution_scale_x() : 1; + uint32_t texture_resolution_scale_y = texture_key.scaled_resolve ? draw_resolution_scale_y() : 1; + + // The loop counter can mean two things depending on whether the packed mip + // tail is stored as mip 0, because in this case, it would be ambiguous since + // both the base and the mips would be on "level 0", but stored in separate + // places. + uint32_t loop_level_first, loop_level_last; + if (level_packed == 0) { + // Packed mip tail is the level 0 - may need to load mip tails for the base, + // the mips, or both. + // Loop iteration 0 - base packed mip tail. + // Loop iteration 1 - mips packed mip tail. + loop_level_first = uint32_t(level_first != 0); + loop_level_last = uint32_t(level_last != 0); + } else { + // Packed mip tail is not the level 0. + // Loop iteration is the actual level being loaded. + loop_level_first = level_stored_first; + loop_level_last = level_stored_last; + } + + // Get the host layout and the buffer. + uint32_t host_block_width = host_format.block_compressed ? block_width : 1; + uint32_t host_block_height = host_format.block_compressed ? block_height : 1; + uint32_t host_x_blocks_per_thread = UINT32_C(1) + << load_shader_info.guest_x_blocks_per_thread_log2; + if (!host_format.block_compressed) { + // Decompressing guest blocks. + host_x_blocks_per_thread *= block_width; + } + VkDeviceSize host_buffer_size = 0; + struct HostLayout { + VkDeviceSize offset_bytes; + VkDeviceSize slice_size_bytes; + uint32_t x_pitch_blocks; + uint32_t y_pitch_blocks; + }; + HostLayout host_layout_base; + // Indexing is the same as for guest stored mips: + // 1...min(level_last, level_packed) if level_packed is not 0, or only 0 if + // level_packed == 0. + HostLayout host_layout_mips[xenos::kTextureMaxMips]; + for (uint32_t loop_level = loop_level_first; loop_level <= loop_level_last; ++loop_level) { + bool is_base = loop_level == 0; + uint32_t level = (level_packed == 0) ? 0 : loop_level; + HostLayout& level_host_layout = is_base ? host_layout_base : host_layout_mips[level]; + level_host_layout.offset_bytes = host_buffer_size; + uint32_t level_guest_x_extent_texels_unscaled; + uint32_t level_guest_y_extent_texels_unscaled; + uint32_t level_guest_z_extent_texels; + if (level == level_packed) { + // Loading the packed tail for the base or the mips - load the whole tail + // to copy regions out of it. + const texture_util::TextureGuestLayout::Level& guest_layout_packed = + is_base ? guest_layout.base : guest_layout.mips[level]; + level_guest_x_extent_texels_unscaled = guest_layout_packed.x_extent_blocks * block_width; + level_guest_y_extent_texels_unscaled = guest_layout_packed.y_extent_blocks * block_height; + level_guest_z_extent_texels = guest_layout_packed.z_extent; + } else { + level_guest_x_extent_texels_unscaled = std::max(width >> level, UINT32_C(1)); + level_guest_y_extent_texels_unscaled = std::max(height >> level, UINT32_C(1)); + level_guest_z_extent_texels = std::max(depth >> level, UINT32_C(1)); + } + level_host_layout.x_pitch_blocks = + rex::round_up((level_guest_x_extent_texels_unscaled * texture_resolution_scale_x + + (host_block_width - 1)) / + host_block_width, + host_x_blocks_per_thread); + level_host_layout.y_pitch_blocks = + (level_guest_y_extent_texels_unscaled * texture_resolution_scale_y + + (host_block_height - 1)) / + host_block_height; + level_host_layout.slice_size_bytes = + VkDeviceSize(load_shader_info.bytes_per_host_block) * level_host_layout.x_pitch_blocks * + level_host_layout.y_pitch_blocks * level_guest_z_extent_texels; + host_buffer_size += level_host_layout.slice_size_bytes * array_size; + } + VulkanCommandProcessor::ScratchBufferAcquisition scratch_buffer_acquisition( + command_processor_.AcquireScratchGpuBuffer( + host_buffer_size, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_SHADER_WRITE_BIT)); + VkBuffer scratch_buffer = scratch_buffer_acquisition.buffer(); + if (scratch_buffer == VK_NULL_HANDLE) { + return false; + } + + // Begin loading. + // TODO(Triang3l): Going from one descriptor to another on per-array-layer + // or even per-8-depth-slices level to stay within maxStorageBufferRange. + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + VulkanSharedMemory& vulkan_shared_memory = static_cast(shared_memory()); + std::array write_descriptor_sets; + uint32_t write_descriptor_set_count = 0; + VkDescriptorSet descriptor_set_dest = command_processor_.AllocateSingleTransientDescriptor( + VulkanCommandProcessor::SingleTransientDescriptorLayout ::kStorageBufferCompute); + if (!descriptor_set_dest) { + return false; + } + VkDescriptorBufferInfo write_descriptor_set_dest_buffer_info; + { + write_descriptor_set_dest_buffer_info.buffer = scratch_buffer; + write_descriptor_set_dest_buffer_info.offset = 0; + write_descriptor_set_dest_buffer_info.range = host_buffer_size; + VkWriteDescriptorSet& write_descriptor_set_dest = + write_descriptor_sets[write_descriptor_set_count++]; + write_descriptor_set_dest.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_descriptor_set_dest.pNext = nullptr; + write_descriptor_set_dest.dstSet = descriptor_set_dest; + write_descriptor_set_dest.dstBinding = 0; + write_descriptor_set_dest.dstArrayElement = 0; + write_descriptor_set_dest.descriptorCount = 1; + write_descriptor_set_dest.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + write_descriptor_set_dest.pImageInfo = nullptr; + write_descriptor_set_dest.pBufferInfo = &write_descriptor_set_dest_buffer_info; + write_descriptor_set_dest.pTexelBufferView = nullptr; + } + // TODO(Triang3l): Use a single 512 MB shared memory binding if possible. + // TODO(Triang3l): Scaled resolve buffer bindings. + // Aligning because if the data for a vector in a storage buffer is provided + // partially, the value read may still be (0, 0, 0, 0), and small (especially + // linear) textures won't be loaded correctly. + uint32_t source_length_alignment = UINT32_C(1) << load_shader_info.source_bpe_log2; + VkDescriptorSet descriptor_set_source_base = VK_NULL_HANDLE; + VkDescriptorSet descriptor_set_source_mips = VK_NULL_HANDLE; + VkDescriptorBufferInfo write_descriptor_set_source_base_buffer_info; + VkDescriptorBufferInfo write_descriptor_set_source_mips_buffer_info; + if (level_first == 0) { + descriptor_set_source_base = command_processor_.AllocateSingleTransientDescriptor( + VulkanCommandProcessor::SingleTransientDescriptorLayout ::kStorageBufferCompute); + if (!descriptor_set_source_base) { + return false; + } + uint32_t source_base_start_unscaled = texture_key.base_page << 12; + uint64_t source_base_start; + uint64_t source_base_range; + if (texture_key.scaled_resolve) { + if (!GetScaledResolveRange(source_base_start_unscaled, vulkan_texture.GetGuestBaseSize(), + load_shader_info.source_bpe_log2, source_base_start, + source_base_range)) { + return false; + } + write_descriptor_set_source_base_buffer_info.buffer = scaled_resolve_buffer_; + } else { + source_base_start = source_base_start_unscaled; + source_base_range = rex::align(uint64_t(vulkan_texture.GetGuestBaseSize()), + uint64_t(source_length_alignment)); + if (source_base_range > uint64_t(SharedMemory::kBufferSize) - source_base_start) { + return false; + } + write_descriptor_set_source_base_buffer_info.buffer = vulkan_shared_memory.buffer(); + } + write_descriptor_set_source_base_buffer_info.offset = source_base_start; + write_descriptor_set_source_base_buffer_info.range = source_base_range; + VkWriteDescriptorSet& write_descriptor_set_source_base = + write_descriptor_sets[write_descriptor_set_count++]; + write_descriptor_set_source_base.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_descriptor_set_source_base.pNext = nullptr; + write_descriptor_set_source_base.dstSet = descriptor_set_source_base; + write_descriptor_set_source_base.dstBinding = 0; + write_descriptor_set_source_base.dstArrayElement = 0; + write_descriptor_set_source_base.descriptorCount = 1; + write_descriptor_set_source_base.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + write_descriptor_set_source_base.pImageInfo = nullptr; + write_descriptor_set_source_base.pBufferInfo = &write_descriptor_set_source_base_buffer_info; + write_descriptor_set_source_base.pTexelBufferView = nullptr; + } + if (level_last != 0) { + descriptor_set_source_mips = command_processor_.AllocateSingleTransientDescriptor( + VulkanCommandProcessor::SingleTransientDescriptorLayout ::kStorageBufferCompute); + if (!descriptor_set_source_mips) { + return false; + } + uint32_t source_mips_start_unscaled = texture_key.mip_page << 12; + uint64_t source_mips_start; + uint64_t source_mips_range; + if (texture_key.scaled_resolve) { + if (!GetScaledResolveRange(source_mips_start_unscaled, vulkan_texture.GetGuestMipsSize(), + load_shader_info.source_bpe_log2, source_mips_start, + source_mips_range)) { + return false; + } + write_descriptor_set_source_mips_buffer_info.buffer = scaled_resolve_buffer_; + } else { + source_mips_start = source_mips_start_unscaled; + source_mips_range = rex::align(uint64_t(vulkan_texture.GetGuestMipsSize()), + uint64_t(source_length_alignment)); + if (source_mips_range > uint64_t(SharedMemory::kBufferSize) - source_mips_start) { + return false; + } + write_descriptor_set_source_mips_buffer_info.buffer = vulkan_shared_memory.buffer(); + } + write_descriptor_set_source_mips_buffer_info.offset = source_mips_start; + write_descriptor_set_source_mips_buffer_info.range = source_mips_range; + VkWriteDescriptorSet& write_descriptor_set_source_mips = + write_descriptor_sets[write_descriptor_set_count++]; + write_descriptor_set_source_mips.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_descriptor_set_source_mips.pNext = nullptr; + write_descriptor_set_source_mips.dstSet = descriptor_set_source_mips; + write_descriptor_set_source_mips.dstBinding = 0; + write_descriptor_set_source_mips.dstArrayElement = 0; + write_descriptor_set_source_mips.descriptorCount = 1; + write_descriptor_set_source_mips.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + write_descriptor_set_source_mips.pImageInfo = nullptr; + write_descriptor_set_source_mips.pBufferInfo = &write_descriptor_set_source_mips_buffer_info; + write_descriptor_set_source_mips.pTexelBufferView = nullptr; + } + if (write_descriptor_set_count) { + dfn.vkUpdateDescriptorSets(device, write_descriptor_set_count, write_descriptor_sets.data(), 0, + nullptr); + } + if (texture_key.scaled_resolve) { + UseScaledResolveBufferForRead(); + } else { + vulkan_shared_memory.Use(VulkanSharedMemory::Usage::kRead); + } + + // Submit the copy buffer population commands. + + DeferredCommandBuffer& command_buffer = command_processor_.deferred_command_buffer(); + + command_processor_.BindExternalComputePipeline(pipeline); + + command_buffer.CmdVkBindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, load_pipeline_layout_, + kLoadDescriptorSetIndexDestination, 1, + &descriptor_set_dest, 0, nullptr); + + VkDescriptorSet descriptor_set_source_current = VK_NULL_HANDLE; + + LoadConstants load_constants; + // 3 bits for each. + assert_true(texture_resolution_scale_x <= 7); + assert_true(texture_resolution_scale_y <= 7); + load_constants.is_tiled_3d_endian_scale = + uint32_t(texture_key.tiled) | (uint32_t(is_3d_tiling) << 1) | + (uint32_t(texture_key.endianness) << 2) | (texture_resolution_scale_x << 4) | + (texture_resolution_scale_y << 7); + + uint32_t guest_x_blocks_per_group_log2 = load_shader_info.GetGuestXBlocksPerGroupLog2(); + for (uint32_t loop_level = loop_level_first; loop_level <= loop_level_last; ++loop_level) { + bool is_base = loop_level == 0; + uint32_t level = (level_packed == 0) ? 0 : loop_level; + + VkDescriptorSet descriptor_set_source = + is_base ? descriptor_set_source_base : descriptor_set_source_mips; + if (descriptor_set_source_current != descriptor_set_source) { + descriptor_set_source_current = descriptor_set_source; + command_buffer.CmdVkBindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, load_pipeline_layout_, + kLoadDescriptorSetIndexSource, 1, + &descriptor_set_source, 0, nullptr); + } + + // TODO(Triang3l): guest_offset relative to the storage buffer origin. + load_constants.guest_offset = 0; + if (!is_base) { + load_constants.guest_offset += guest_layout.mip_offsets_bytes[level] * + (texture_resolution_scale_x * texture_resolution_scale_y); + } + const texture_util::TextureGuestLayout::Level& level_guest_layout = + is_base ? guest_layout.base : guest_layout.mips[level]; + uint32_t level_guest_pitch = level_guest_layout.row_pitch_bytes; + if (texture_key.tiled) { + // Shaders expect pitch in blocks for tiled textures. + level_guest_pitch /= bytes_per_block; + assert_zero(level_guest_pitch & (xenos::kTextureTileWidthHeight - 1)); + } + load_constants.guest_pitch_aligned = level_guest_pitch; + load_constants.guest_z_stride_block_rows_aligned = level_guest_layout.z_slice_stride_block_rows; + assert_true(!is_3d_tiling || !(load_constants.guest_z_stride_block_rows_aligned & + (xenos::kTextureTileWidthHeight - 1))); + + uint32_t level_width, level_height, level_depth; + if (level == level_packed) { + // This is the packed mip tail, containing not only the specified level, + // but also other levels at different offsets - load the entire needed + // extents. + level_width = level_guest_layout.x_extent_blocks * block_width; + level_height = level_guest_layout.y_extent_blocks * block_height; + level_depth = level_guest_layout.z_extent; + } else { + level_width = std::max(width >> level, UINT32_C(1)); + level_height = std::max(height >> level, UINT32_C(1)); + level_depth = std::max(depth >> level, UINT32_C(1)); + } + load_constants.size_blocks[0] = + (level_width + (block_width - 1)) / block_width * texture_resolution_scale_x; + load_constants.size_blocks[1] = + (level_height + (block_height - 1)) / block_height * texture_resolution_scale_y; + load_constants.size_blocks[2] = level_depth; + load_constants.height_texels = level_height; + + uint32_t group_count_x = + (load_constants.size_blocks[0] + ((UINT32_C(1) << guest_x_blocks_per_group_log2) - 1)) >> + guest_x_blocks_per_group_log2; + uint32_t group_count_y = + (load_constants.size_blocks[1] + ((UINT32_C(1) << kLoadGuestYBlocksPerGroupLog2) - 1)) >> + kLoadGuestYBlocksPerGroupLog2; + + // TODO(Triang3l): host_offset relative to the storage buffer origin. + const HostLayout& level_host_layout = is_base ? host_layout_base : host_layout_mips[level]; + load_constants.host_offset = uint32_t(level_host_layout.offset_bytes); + load_constants.host_pitch = + load_shader_info.bytes_per_host_block * level_host_layout.x_pitch_blocks; + + command_buffer.CmdVkPushConstants(load_pipeline_layout_, VK_SHADER_STAGE_COMPUTE_BIT, 0, + sizeof(load_constants), &load_constants); + + uint32_t level_array_slice_stride_bytes_scaled = + level_guest_layout.array_slice_stride_bytes * + (texture_resolution_scale_x * texture_resolution_scale_y); + for (uint32_t slice = 0; slice < array_size; ++slice) { + if (slice != 0) { + command_buffer.CmdVkPushConstants(load_pipeline_layout_, VK_SHADER_STAGE_COMPUTE_BIT, + offsetof(LoadConstants, guest_offset), + sizeof(load_constants.guest_offset), + &load_constants.guest_offset); + command_buffer.CmdVkPushConstants(load_pipeline_layout_, VK_SHADER_STAGE_COMPUTE_BIT, + offsetof(LoadConstants, host_offset), + sizeof(load_constants.host_offset), + &load_constants.host_offset); + } + command_processor_.SubmitBarriers(true); + command_buffer.CmdVkDispatch(group_count_x, group_count_y, load_constants.size_blocks[2]); + load_constants.guest_offset += level_array_slice_stride_bytes_scaled; + load_constants.host_offset += uint32_t(level_host_layout.slice_size_bytes); + } + } + + if (pipeline_float_convert != VK_NULL_HANDLE) { + assert_not_null(load_shader_info_float_convert); + static std::array float_fallback_log_mask = {}; + uint8_t float_fallback_log_bit = host_format_is_signed ? uint8_t(1 << 1) : uint8_t(1 << 0); + uint8_t& float_fallback_log_state = float_fallback_log_mask[uint32_t(texture_key.format)]; + if ((float_fallback_log_state & float_fallback_log_bit) == 0) { + float_fallback_log_state |= float_fallback_log_bit; + REXGPU_INFO("VulkanTextureCache: Using two-pass float fallback for format {} ({})", + FormatInfo::Get(texture_key.format)->name, + host_format_is_signed ? "signed" : "unsigned"); + } + // Make the normalized intermediate data visible for conversion and keep it + // writable for in-place conversion to float16. + command_processor_.PushBufferMemoryBarrier( + scratch_buffer, 0, VK_WHOLE_SIZE, + scratch_buffer_acquisition.SetStageMask(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT), + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + scratch_buffer_acquisition.SetAccessMask(VK_ACCESS_SHADER_READ_BIT | + VK_ACCESS_SHADER_WRITE_BIT), + VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT); + + command_processor_.BindExternalComputePipeline(pipeline_float_convert); + command_buffer.CmdVkBindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, load_pipeline_layout_, + kLoadDescriptorSetIndexDestination, 1, + &descriptor_set_dest, 0, nullptr); + command_buffer.CmdVkBindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, load_pipeline_layout_, + kLoadDescriptorSetIndexSource, 1, &descriptor_set_dest, + 0, nullptr); + + LoadConstants load_constants_float_convert; + // Linear source and destination in the same scratch buffer, 1x1 scaling. + load_constants_float_convert.is_tiled_3d_endian_scale = + (uint32_t(is_3d) << 1) | (UINT32_C(1) << 4) | (UINT32_C(1) << 7); + uint32_t guest_x_blocks_per_group_log2_float_convert = + load_shader_info_float_convert->GetGuestXBlocksPerGroupLog2(); + + for (uint32_t loop_level = loop_level_first; loop_level <= loop_level_last; ++loop_level) { + bool is_base = loop_level == 0; + uint32_t level = (level_packed == 0) ? 0 : loop_level; + + const texture_util::TextureGuestLayout::Level& level_guest_layout = + is_base ? guest_layout.base : guest_layout.mips[level]; + uint32_t level_width, level_height, level_depth; + if (level == level_packed) { + level_width = level_guest_layout.x_extent_blocks * block_width; + level_height = level_guest_layout.y_extent_blocks * block_height; + level_depth = level_guest_layout.z_extent; + } else { + level_width = std::max(width >> level, UINT32_C(1)); + level_height = std::max(height >> level, UINT32_C(1)); + level_depth = std::max(depth >> level, UINT32_C(1)); + } + load_constants_float_convert.size_blocks[0] = + (level_width + (block_width - 1)) / block_width * texture_resolution_scale_x; + load_constants_float_convert.size_blocks[1] = + (level_height + (block_height - 1)) / block_height * texture_resolution_scale_y; + load_constants_float_convert.size_blocks[2] = level_depth; + load_constants_float_convert.height_texels = level_height; + + uint32_t group_count_x = + (load_constants_float_convert.size_blocks[0] + + ((UINT32_C(1) << guest_x_blocks_per_group_log2_float_convert) - 1)) >> + guest_x_blocks_per_group_log2_float_convert; + uint32_t group_count_y = (load_constants_float_convert.size_blocks[1] + + ((UINT32_C(1) << kLoadGuestYBlocksPerGroupLog2) - 1)) >> + kLoadGuestYBlocksPerGroupLog2; + + const HostLayout& level_host_layout = is_base ? host_layout_base : host_layout_mips[level]; + load_constants_float_convert.guest_offset = uint32_t(level_host_layout.offset_bytes); + load_constants_float_convert.guest_pitch_aligned = + load_shader_info_float_convert->bytes_per_host_block * level_host_layout.x_pitch_blocks; + load_constants_float_convert.guest_z_stride_block_rows_aligned = + level_host_layout.y_pitch_blocks; + load_constants_float_convert.host_offset = uint32_t(level_host_layout.offset_bytes); + load_constants_float_convert.host_pitch = + load_shader_info_float_convert->bytes_per_host_block * level_host_layout.x_pitch_blocks; + + command_buffer.CmdVkPushConstants(load_pipeline_layout_, VK_SHADER_STAGE_COMPUTE_BIT, 0, + sizeof(load_constants_float_convert), + &load_constants_float_convert); + + uint32_t level_array_slice_stride_bytes = uint32_t(level_host_layout.slice_size_bytes); + for (uint32_t slice = 0; slice < array_size; ++slice) { + if (slice != 0) { + command_buffer.CmdVkPushConstants(load_pipeline_layout_, VK_SHADER_STAGE_COMPUTE_BIT, + offsetof(LoadConstants, guest_offset), + sizeof(load_constants_float_convert.guest_offset), + &load_constants_float_convert.guest_offset); + command_buffer.CmdVkPushConstants(load_pipeline_layout_, VK_SHADER_STAGE_COMPUTE_BIT, + offsetof(LoadConstants, host_offset), + sizeof(load_constants_float_convert.host_offset), + &load_constants_float_convert.host_offset); + } + command_processor_.SubmitBarriers(true); + command_buffer.CmdVkDispatch(group_count_x, group_count_y, + load_constants_float_convert.size_blocks[2]); + load_constants_float_convert.guest_offset += level_array_slice_stride_bytes; + load_constants_float_convert.host_offset += level_array_slice_stride_bytes; + } + } + } + + // Submit copying from the copy buffer to the host texture. + command_processor_.PushBufferMemoryBarrier( + scratch_buffer, 0, VK_WHOLE_SIZE, + scratch_buffer_acquisition.SetStageMask(VK_PIPELINE_STAGE_TRANSFER_BIT), + VK_PIPELINE_STAGE_TRANSFER_BIT, + scratch_buffer_acquisition.SetAccessMask(VK_ACCESS_TRANSFER_READ_BIT), + VK_ACCESS_TRANSFER_READ_BIT); + vulkan_texture.MarkAsUsed(); + VulkanTexture::Usage texture_old_usage = + vulkan_texture.SetUsage(VulkanTexture::Usage::kTransferDestination); + if (texture_old_usage != VulkanTexture::Usage::kTransferDestination) { + VkPipelineStageFlags texture_src_stage_mask, texture_dst_stage_mask; + VkAccessFlags texture_src_access_mask, texture_dst_access_mask; + VkImageLayout texture_old_layout, texture_new_layout; + GetTextureUsageMasks(texture_old_usage, texture_src_stage_mask, texture_src_access_mask, + texture_old_layout); + GetTextureUsageMasks(VulkanTexture::Usage::kTransferDestination, texture_dst_stage_mask, + texture_dst_access_mask, texture_new_layout); + command_processor_.PushImageMemoryBarrier( + vulkan_texture.image(), ui::vulkan::util::InitializeSubresourceRange(), + texture_src_stage_mask, texture_dst_stage_mask, texture_src_access_mask, + texture_dst_access_mask, texture_old_layout, texture_new_layout); + } + command_processor_.SubmitBarriers(true); + VkBufferImageCopy* copy_regions = command_buffer.CmdCopyBufferToImageEmplace( + scratch_buffer, vulkan_texture.image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + level_last - level_first + 1); + for (uint32_t level = level_first; level <= level_last; ++level) { + VkBufferImageCopy& copy_region = copy_regions[level - level_first]; + const HostLayout& level_host_layout = + level != 0 ? host_layout_mips[std::min(level, level_packed)] : host_layout_base; + copy_region.bufferOffset = level_host_layout.offset_bytes; + if (level >= level_packed) { + uint32_t level_offset_blocks_x, level_offset_blocks_y, level_offset_z; + texture_util::GetPackedMipOffset(width, height, depth, guest_format, level, + level_offset_blocks_x, level_offset_blocks_y, + level_offset_z); + uint32_t level_offset_host_blocks_x = texture_resolution_scale_x * level_offset_blocks_x; + uint32_t level_offset_host_blocks_y = texture_resolution_scale_y * level_offset_blocks_y; + if (!host_format.block_compressed) { + level_offset_host_blocks_x *= block_width; + level_offset_host_blocks_y *= block_height; + } + copy_region.bufferOffset += + load_shader_info.bytes_per_host_block * + (level_offset_host_blocks_x + + level_host_layout.x_pitch_blocks * + (level_offset_host_blocks_y + + level_host_layout.y_pitch_blocks * VkDeviceSize(level_offset_z))); + } + copy_region.bufferRowLength = level_host_layout.x_pitch_blocks * host_block_width; + copy_region.bufferImageHeight = level_host_layout.y_pitch_blocks * host_block_height; + copy_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + copy_region.imageSubresource.mipLevel = level; + copy_region.imageSubresource.baseArrayLayer = 0; + copy_region.imageSubresource.layerCount = array_size; + copy_region.imageOffset.x = 0; + copy_region.imageOffset.y = 0; + copy_region.imageOffset.z = 0; + copy_region.imageExtent.width = + std::max((width * texture_resolution_scale_x) >> level, UINT32_C(1)); + copy_region.imageExtent.height = + std::max((height * texture_resolution_scale_y) >> level, UINT32_C(1)); + copy_region.imageExtent.depth = std::max(depth >> level, UINT32_C(1)); + } + + return true; +} + +void VulkanTextureCache::UpdateTextureBindingsImpl(uint32_t fetch_constant_mask) { + uint32_t bindings_remaining = fetch_constant_mask; + uint32_t binding_index; + while (rex::bit_scan_forward(bindings_remaining, &binding_index)) { + bindings_remaining &= ~(UINT32_C(1) << binding_index); + VulkanTextureBinding& vulkan_binding = vulkan_texture_bindings_[binding_index]; + vulkan_binding.Reset(); + const TextureBinding* binding = GetValidTextureBinding(binding_index); + if (!binding) { + continue; + } + const HostFormatPair& host_format_pair = GetHostFormatPair(binding->key); + bool uses_unsigned = texture_util::IsAnySignNotSigned(binding->swizzled_signs); + bool uses_signed = texture_util::IsAnySignSigned(binding->swizzled_signs); + xenos::TextureFormat format = binding->key.format; + if (uses_unsigned && host_format_pair.format_unsigned.format == VK_FORMAT_UNDEFINED) { + unsupported_format_features_used_[uint32_t(format)] |= kUnsupportedUnormBit; + } + if (uses_signed && host_format_pair.format_signed.format == VK_FORMAT_UNDEFINED) { + unsupported_format_features_used_[uint32_t(format)] |= kUnsupportedSnormBit; + } + if (IsSignedVersionSeparateForFormat(binding->key)) { + if (binding->texture && uses_unsigned && + host_format_pair.format_unsigned.format != VK_FORMAT_UNDEFINED) { + vulkan_binding.image_view_unsigned = + static_cast(binding->texture)->GetView(false, binding->host_swizzle); + } + if (binding->texture_signed && uses_signed && + host_format_pair.format_signed.format != VK_FORMAT_UNDEFINED) { + vulkan_binding.image_view_signed = static_cast(binding->texture_signed) + ->GetView(true, binding->host_swizzle); + } + } else { + VulkanTexture* texture = static_cast(binding->texture); + if (texture) { + if (uses_unsigned && host_format_pair.format_unsigned.format != VK_FORMAT_UNDEFINED) { + vulkan_binding.image_view_unsigned = texture->GetView(false, binding->host_swizzle); + } + if (uses_signed && host_format_pair.format_signed.format != VK_FORMAT_UNDEFINED) { + vulkan_binding.image_view_signed = texture->GetView(true, binding->host_swizzle); + } + } + } + } +} + +VulkanTextureCache::VulkanTexture::VulkanTexture(VulkanTextureCache& texture_cache, + const TextureKey& key, VkImage image, + VmaAllocation allocation, bool track_usage) + : Texture(texture_cache, key, track_usage), image_(image), allocation_(allocation) { + VmaAllocationInfo allocation_info; + vmaGetAllocationInfo(texture_cache.vma_allocator_, allocation_, &allocation_info); + SetHostMemoryUsage(uint64_t(allocation_info.size)); +} + +VulkanTextureCache::VulkanTexture::~VulkanTexture() { + const VulkanTextureCache& vulkan_texture_cache = + static_cast(texture_cache()); + const ui::vulkan::VulkanDevice* const vulkan_device = + vulkan_texture_cache.command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + for (const auto& view_pair : views_) { + dfn.vkDestroyImageView(device, view_pair.second, nullptr); + } + if (image_view_3d_as_2d_unsigned_ != VK_NULL_HANDLE) { + dfn.vkDestroyImageView(device, image_view_3d_as_2d_unsigned_, nullptr); + } + if (image_view_3d_as_2d_signed_ != VK_NULL_HANDLE) { + dfn.vkDestroyImageView(device, image_view_3d_as_2d_signed_, nullptr); + } + vmaDestroyImage(vulkan_texture_cache.vma_allocator_, image_, allocation_); +} + +VkImageView VulkanTextureCache::VulkanTexture::GetView(bool is_signed, uint32_t host_swizzle, + bool is_array) { + xenos::DataDimension dimension = key().dimension; + if (dimension == xenos::DataDimension::k3D || dimension == xenos::DataDimension::kCube) { + is_array = false; + } + + const VulkanTextureCache& vulkan_texture_cache = + static_cast(texture_cache()); + + ViewKey view_key; + + const HostFormatPair& host_format_pair = vulkan_texture_cache.GetHostFormatPair(key()); + VkFormat format = + (is_signed ? host_format_pair.format_signed : host_format_pair.format_unsigned).format; + if (format == VK_FORMAT_UNDEFINED) { + return VK_NULL_HANDLE; + } + // If not distinguishing between unsigned and signed formats for the same + // image, don't create two views. As this happens within an image, no need to + // care about whether unsigned and signed images are separate - if they are + // (or if there are only unsigned or only signed images), this image will have + // either all views unsigned or all views signed. + view_key.is_signed_separate_view = is_signed && (host_format_pair.format_signed.format != + host_format_pair.format_unsigned.format); + + const ui::vulkan::VulkanDevice* const vulkan_device = + vulkan_texture_cache.command_processor_.GetVulkanDevice(); + + if (!vulkan_device->properties().imageViewFormatSwizzle) { + host_swizzle = xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA; + } + view_key.host_swizzle = host_swizzle; + + view_key.is_array = uint32_t(is_array); + + // Try to find an existing view. + auto it = views_.find(view_key); + if (it != views_.end()) { + return it->second; + } + + // Create a new view. + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + VkImageViewCreateInfo view_create_info; + view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + view_create_info.pNext = nullptr; + view_create_info.flags = 0; + view_create_info.image = image(); + view_create_info.format = format; + view_create_info.components.r = GetComponentSwizzle(host_swizzle, 0); + view_create_info.components.g = GetComponentSwizzle(host_swizzle, 1); + view_create_info.components.b = GetComponentSwizzle(host_swizzle, 2); + view_create_info.components.a = GetComponentSwizzle(host_swizzle, 3); + view_create_info.subresourceRange = ui::vulkan::util::InitializeSubresourceRange(); + switch (dimension) { + case xenos::DataDimension::k3D: + view_create_info.viewType = VK_IMAGE_VIEW_TYPE_3D; + break; + case xenos::DataDimension::kCube: + view_create_info.viewType = VK_IMAGE_VIEW_TYPE_CUBE; + break; + default: + if (is_array) { + view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + } else { + view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; + view_create_info.subresourceRange.layerCount = 1; + } + break; + } + VkImageView view; + if (dfn.vkCreateImageView(device, &view_create_info, nullptr, &view) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanTextureCache: Failed to create an image view for Vulkan format " + "{} ({}signed) with swizzle 0x{:3X}", + uint32_t(format), is_signed ? "" : "un", host_swizzle); + return VK_NULL_HANDLE; + } + views_.emplace(view_key, view); + return view; +} + +VkImageView VulkanTextureCache::VulkanTexture::GetOrCreate3DAs2DImageView(bool is_signed, + uint32_t host_swizzle) { + if (!REXCVAR_GET(gpu_3d_to_2d_texture)) { + return VK_NULL_HANDLE; + } + + VkImageView& cached_view = + is_signed ? image_view_3d_as_2d_signed_ : image_view_3d_as_2d_unsigned_; + if (cached_view != VK_NULL_HANDLE) { + return cached_view; + } + + VulkanTextureCache& vulkan_texture_cache = static_cast(texture_cache()); + + if (!texture_3d_as_2d_) { + const HostFormatPair& host_format_pair = vulkan_texture_cache.GetHostFormatPair(key()); + VkFormat wrapper_format = host_format_pair.format_unsigned.format; + if (wrapper_format == VK_FORMAT_UNDEFINED) { + wrapper_format = host_format_pair.format_signed.format; + } + if (wrapper_format == VK_FORMAT_UNDEFINED) { + return VK_NULL_HANDLE; + } + + VkImageCreateInfo image_create_info = {}; + image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + image_create_info.pNext = nullptr; + image_create_info.flags = 0; + image_create_info.imageType = VK_IMAGE_TYPE_2D; + image_create_info.format = wrapper_format; + image_create_info.extent.width = key().GetWidth(); + image_create_info.extent.height = key().GetHeight(); + image_create_info.extent.depth = 1; + image_create_info.mipLevels = 1; + image_create_info.arrayLayers = 1; + image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; + image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; + image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + image_create_info.queueFamilyIndexCount = 0; + image_create_info.pQueueFamilyIndices = nullptr; + image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + VmaAllocationCreateInfo allocation_create_info = {}; + allocation_create_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; + + VkImage image_2d; + VmaAllocation allocation_2d; + if (vmaCreateImage(vulkan_texture_cache.vma_allocator_, &image_create_info, + &allocation_create_info, &image_2d, &allocation_2d, nullptr) != VK_SUCCESS) { + REXGPU_ERROR("VulkanTextureCache: Failed to create 3D-as-2D wrapper image"); + return VK_NULL_HANDLE; + } + + TextureKey key_2d = key(); + key_2d.depth_or_array_size_minus_1 = 0; + key_2d.mip_max_level = 0; + texture_3d_as_2d_.reset( + new VulkanTexture(vulkan_texture_cache, key_2d, image_2d, allocation_2d, false)); + texture_3d_as_2d_->SetForceLoad3DTiling(true); + + if (!vulkan_texture_cache.LoadTextureData(*texture_3d_as_2d_)) { + REXGPU_ERROR("VulkanTextureCache: Failed to load 3D-as-2D wrapper data"); + texture_3d_as_2d_.reset(); + return VK_NULL_HANDLE; + } + + if (!vulkan_texture_cache.command_processor_.PushImageMemoryBarrier( + texture_3d_as_2d_->image(), ui::vulkan::util::InitializeSubresourceRange(), + VK_PIPELINE_STAGE_TRANSFER_BIT, vulkan_texture_cache.guest_shader_pipeline_stages_, + VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)) { + texture_3d_as_2d_.reset(); + return VK_NULL_HANDLE; + } + texture_3d_as_2d_->SetUsage(Usage::kGuestShaderSampled); + } + + const HostFormatPair& host_format_pair = vulkan_texture_cache.GetHostFormatPair(key()); + VkFormat view_format = + (is_signed ? host_format_pair.format_signed : host_format_pair.format_unsigned).format; + if (view_format == VK_FORMAT_UNDEFINED) { + return VK_NULL_HANDLE; + } + + const ui::vulkan::VulkanDevice* const vulkan_device = + vulkan_texture_cache.command_processor_.GetVulkanDevice(); + if (!vulkan_device->properties().imageViewFormatSwizzle) { + host_swizzle = xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA; + } + + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + VkImageViewCreateInfo view_create_info = {}; + view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + view_create_info.pNext = nullptr; + view_create_info.flags = 0; + view_create_info.image = texture_3d_as_2d_->image(); + view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + view_create_info.format = view_format; + view_create_info.components.r = GetComponentSwizzle(host_swizzle, 0); + view_create_info.components.g = GetComponentSwizzle(host_swizzle, 1); + view_create_info.components.b = GetComponentSwizzle(host_swizzle, 2); + view_create_info.components.a = GetComponentSwizzle(host_swizzle, 3); + view_create_info.subresourceRange = ui::vulkan::util::InitializeSubresourceRange(); + view_create_info.subresourceRange.layerCount = 1; + + if (dfn.vkCreateImageView(device, &view_create_info, nullptr, &cached_view) != VK_SUCCESS) { + REXGPU_ERROR("VulkanTextureCache: Failed to create 3D-as-2D wrapper image view"); + return VK_NULL_HANDLE; + } + + return cached_view; +} + +VulkanTextureCache::VulkanTextureCache(const RegisterFile& register_file, + VulkanSharedMemory& shared_memory, + uint32_t draw_resolution_scale_x, + uint32_t draw_resolution_scale_y, + VulkanCommandProcessor& command_processor, + VkPipelineStageFlags guest_shader_pipeline_stages) + : TextureCache(register_file, shared_memory, draw_resolution_scale_x, draw_resolution_scale_y), + command_processor_(command_processor), + guest_shader_pipeline_stages_(guest_shader_pipeline_stages) {} + +bool VulkanTextureCache::InitializeScaledResolveBuffer() { + assert_true(IsDrawResolutionScaled()); + + uint64_t scale_area = uint64_t(draw_resolution_scale_x()) * uint64_t(draw_resolution_scale_y()); + scaled_resolve_buffer_size_ = uint64_t(SharedMemory::kBufferSize) * scale_area; + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + const VkBufferCreateFlags sparse_flags = + VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT; + + VkBufferCreateInfo buffer_create_info; + buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + buffer_create_info.pNext = nullptr; + buffer_create_info.flags = sparse_flags; + buffer_create_info.size = scaled_resolve_buffer_size_; + buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + buffer_create_info.queueFamilyIndexCount = 0; + buffer_create_info.pQueueFamilyIndices = nullptr; + + if (vulkan_device->properties().sparseResidencyBuffer && + dfn.vkCreateBuffer(device, &buffer_create_info, nullptr, &scaled_resolve_buffer_) == + VK_SUCCESS) { + VkMemoryRequirements memory_requirements; + dfn.vkGetBufferMemoryRequirements(device, scaled_resolve_buffer_, &memory_requirements); + if (rex::bit_scan_forward( + memory_requirements.memoryTypeBits & vulkan_device->memory_types().device_local, + &scaled_resolve_buffer_memory_type_)) { + uint32_t alignment_log2; + rex::bit_scan_forward(std::max(memory_requirements.alignment, VkDeviceSize(1)), + &alignment_log2); + uint32_t size_log2 = rex::log2_ceil(scaled_resolve_buffer_size_); + uint32_t preferred_log2 = std::max(uint32_t(0), size_log2 - uint32_t(10)); + scaled_resolve_sparse_granularity_log2_ = + std::max(alignment_log2, std::max(uint32_t(22), preferred_log2)); + scaled_resolve_sparse_granularity_log2_ = + std::min(scaled_resolve_sparse_granularity_log2_, size_log2); + uint32_t allocation_count_log2 = + std::max(uint32_t(6), size_log2 - scaled_resolve_sparse_granularity_log2_); + scaled_resolve_sparse_allocated_.resize(size_t(1) << (allocation_count_log2 - uint32_t(6))); + scaled_resolve_buffer_sparse_ = true; + } else { + dfn.vkDestroyBuffer(device, scaled_resolve_buffer_, nullptr); + scaled_resolve_buffer_ = VK_NULL_HANDLE; + } + } + + if (scaled_resolve_buffer_ == VK_NULL_HANDLE) { + buffer_create_info.flags = 0; + if (!ui::vulkan::util::CreateDedicatedAllocationBuffer( + vulkan_device, scaled_resolve_buffer_size_, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, + ui::vulkan::util::MemoryPurpose::kDeviceLocal, scaled_resolve_buffer_, + scaled_resolve_buffer_memory_.emplace_back(), &scaled_resolve_buffer_memory_type_)) { + REXGPU_ERROR( + "VulkanTextureCache: Failed to create a scaled resolve buffer with " + "{} MB address space", + scaled_resolve_buffer_size_ >> 20); + return false; + } + scaled_resolve_buffer_sparse_ = false; + scaled_resolve_sparse_granularity_log2_ = UINT32_MAX; + scaled_resolve_sparse_allocated_.clear(); + } + + scaled_resolve_last_usage_write_ = false; + scaled_resolve_last_written_range_ = std::make_pair(uint64_t(0), uint64_t(0)); + return true; +} + +void VulkanTextureCache::ShutdownScaledResolveBuffer() { + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyBuffer, device, scaled_resolve_buffer_); + for (VkDeviceMemory memory : scaled_resolve_buffer_memory_) { + dfn.vkFreeMemory(device, memory, nullptr); + } + scaled_resolve_buffer_memory_.clear(); + scaled_resolve_sparse_allocated_.clear(); + scaled_resolve_buffer_size_ = 0; + scaled_resolve_buffer_sparse_ = false; + scaled_resolve_buffer_memory_type_ = UINT32_MAX; + scaled_resolve_sparse_granularity_log2_ = UINT32_MAX; + scaled_resolve_last_usage_write_ = false; + scaled_resolve_last_written_range_ = std::make_pair(uint64_t(0), uint64_t(0)); +} + +bool VulkanTextureCache::GetScaledResolveRange(uint32_t start_unscaled, uint32_t length_unscaled, + uint32_t length_scaled_alignment_log2, + uint64_t& start_scaled_out, + uint64_t& length_scaled_out) const { + if (!IsDrawResolutionScaled()) { + return false; + } + if (length_unscaled == 0) { + start_scaled_out = 0; + length_scaled_out = 0; + return true; + } + if (start_unscaled > SharedMemory::kBufferSize || + (SharedMemory::kBufferSize - start_unscaled) < length_unscaled) { + return false; + } + + uint64_t scale_area = uint64_t(draw_resolution_scale_x()) * uint64_t(draw_resolution_scale_y()); + uint64_t start_scaled = uint64_t(start_unscaled) * scale_area; + uint64_t length_scaled = uint64_t(length_unscaled) * scale_area; + uint64_t alignment = uint64_t(1) << length_scaled_alignment_log2; + length_scaled = rex::align(length_scaled, alignment); + + if (start_scaled > scaled_resolve_buffer_size_ || + length_scaled > scaled_resolve_buffer_size_ - start_scaled) { + return false; + } + + start_scaled_out = start_scaled; + length_scaled_out = length_scaled; + return true; +} + +bool VulkanTextureCache::EnsureScaledResolveBufferAllocated(uint64_t start_scaled, + uint64_t length_scaled) { + if (!length_scaled || !scaled_resolve_buffer_sparse_) { + return true; + } + uint32_t allocation_first = uint32_t(start_scaled >> scaled_resolve_sparse_granularity_log2_); + uint32_t allocation_last = + uint32_t((start_scaled + (length_scaled - 1)) >> scaled_resolve_sparse_granularity_log2_); + while (true) { + std::pair allocation_range = + rex::bit::GetNextRangeUnset(scaled_resolve_sparse_allocated_.data(), allocation_first, + allocation_last - allocation_first + 1); + if (!allocation_range.second) { + break; + } + + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + VkMemoryAllocateInfo memory_allocate_info; + memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + memory_allocate_info.pNext = nullptr; + memory_allocate_info.allocationSize = VkDeviceSize(allocation_range.second) + << scaled_resolve_sparse_granularity_log2_; + memory_allocate_info.memoryTypeIndex = scaled_resolve_buffer_memory_type_; + VkDeviceMemory allocation_memory; + if (dfn.vkAllocateMemory(device, &memory_allocate_info, nullptr, &allocation_memory) != + VK_SUCCESS) { + REXGPU_ERROR( + "VulkanTextureCache: Failed to allocate sparse memory for the " + "scaled resolve buffer"); + return false; + } + scaled_resolve_buffer_memory_.push_back(allocation_memory); + + VkSparseMemoryBind bind; + bind.resourceOffset = VkDeviceSize(allocation_range.first) + << scaled_resolve_sparse_granularity_log2_; + bind.size = memory_allocate_info.allocationSize; + bind.memory = allocation_memory; + bind.memoryOffset = 0; + bind.flags = 0; + command_processor_.SparseBindBuffer( + scaled_resolve_buffer_, 1, &bind, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT); + + rex::bit::SetRange(scaled_resolve_sparse_allocated_.data(), allocation_range.first, + allocation_range.second); + allocation_first = uint32_t(allocation_range.first + allocation_range.second); + } + return true; +} + +void VulkanTextureCache::GetScaledResolveUsageMasks(VkPipelineStageFlags& stage_mask_out, + VkAccessFlags& access_mask_out, + bool write) const { + stage_mask_out = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + access_mask_out = VK_ACCESS_SHADER_READ_BIT; + if (write) { + access_mask_out |= VK_ACCESS_SHADER_WRITE_BIT; + } +} + +void VulkanTextureCache::UseScaledResolveBufferForRead() { + if (!scaled_resolve_buffer_) { + return; + } + if (!scaled_resolve_last_usage_write_ && !scaled_resolve_last_written_range_.second) { + return; + } + + VkPipelineStageFlags src_stage_mask, dst_stage_mask; + VkAccessFlags src_access_mask, dst_access_mask; + GetScaledResolveUsageMasks(src_stage_mask, src_access_mask, scaled_resolve_last_usage_write_); + GetScaledResolveUsageMasks(dst_stage_mask, dst_access_mask, false); + VkDeviceSize offset; + VkDeviceSize size; + if (!scaled_resolve_last_usage_write_) { + offset = VkDeviceSize(scaled_resolve_last_written_range_.first); + size = VkDeviceSize(scaled_resolve_last_written_range_.second); + } else { + offset = 0; + size = VK_WHOLE_SIZE; + scaled_resolve_last_usage_write_ = false; + } + command_processor_.PushBufferMemoryBarrier( + scaled_resolve_buffer_, offset, size, src_stage_mask, dst_stage_mask, src_access_mask, + dst_access_mask, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, false); + scaled_resolve_last_written_range_ = std::make_pair(uint64_t(0), uint64_t(0)); +} + +void VulkanTextureCache::UseScaledResolveBufferForWrite(uint64_t written_start_scaled, + uint64_t written_length_scaled) { + if (!scaled_resolve_buffer_) { + return; + } + if (written_start_scaled > scaled_resolve_buffer_size_) { + written_start_scaled = scaled_resolve_buffer_size_; + } + written_length_scaled = + std::min(written_length_scaled, scaled_resolve_buffer_size_ - written_start_scaled); + + if (scaled_resolve_last_usage_write_ && scaled_resolve_last_written_range_.second) { + VkPipelineStageFlags stage_mask; + VkAccessFlags access_mask; + GetScaledResolveUsageMasks(stage_mask, access_mask, true); + command_processor_.PushBufferMemoryBarrier( + scaled_resolve_buffer_, VkDeviceSize(scaled_resolve_last_written_range_.first), + VkDeviceSize(scaled_resolve_last_written_range_.second), stage_mask, stage_mask, + access_mask, access_mask, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, false); + } else if (!scaled_resolve_last_usage_write_) { + VkPipelineStageFlags src_stage_mask, dst_stage_mask; + VkAccessFlags src_access_mask, dst_access_mask; + GetScaledResolveUsageMasks(src_stage_mask, src_access_mask, false); + GetScaledResolveUsageMasks(dst_stage_mask, dst_access_mask, true); + command_processor_.PushBufferMemoryBarrier( + scaled_resolve_buffer_, 0, VK_WHOLE_SIZE, src_stage_mask, dst_stage_mask, src_access_mask, + dst_access_mask, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, false); + scaled_resolve_last_usage_write_ = true; + } + + scaled_resolve_last_written_range_ = std::make_pair(written_start_scaled, written_length_scaled); +} + +bool VulkanTextureCache::Initialize() { + const ui::vulkan::VulkanDevice* const vulkan_device = command_processor_.GetVulkanDevice(); + const ui::vulkan::VulkanInstance::Functions& ifn = vulkan_device->vulkan_instance()->functions(); + const VkPhysicalDevice physical_device = vulkan_device->physical_device(); + const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + const ui::vulkan::VulkanDevice::Properties& device_properties = vulkan_device->properties(); + + // Vulkan Memory Allocator. + + vma_allocator_ = ui::vulkan::CreateVmaAllocator(vulkan_device, true); + if (vma_allocator_ == VK_NULL_HANDLE) { + return false; + } + + if (IsDrawResolutionScaled() && !InitializeScaledResolveBuffer()) { + return false; + } + + // Image formats. + + // Initialize to the best formats. + for (size_t i = 0; i < rex::countof(host_formats_); ++i) { + host_formats_[i] = kBestHostFormats[i]; + } + + // Check format support and switch to fallbacks if needed. + constexpr VkFormatFeatureFlags kLinearFilterFeatures = + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; + VkFormatProperties r16_unorm_properties; + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R16_UNORM, + &r16_unorm_properties); + VkFormatProperties r16_snorm_properties; + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R16_SNORM, + &r16_snorm_properties); + VkFormatProperties r16g16_unorm_properties; + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R16G16_UNORM, + &r16g16_unorm_properties); + VkFormatProperties r16g16_snorm_properties; + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R16G16_SNORM, + &r16g16_snorm_properties); + VkFormatProperties r16g16b16a16_unorm_properties; + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R16G16B16A16_UNORM, + &r16g16b16a16_unorm_properties); + VkFormatProperties r16g16b16a16_snorm_properties; + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R16G16B16A16_SNORM, + &r16g16b16a16_snorm_properties); + VkFormatProperties r16g16b16a16_sfloat_properties; + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R16G16B16A16_SFLOAT, + &r16g16b16a16_sfloat_properties); + VkFormatProperties format_properties; + // k_Cr_Y1_Cb_Y0_REP, k_Y1_Cr_Y0_Cb_REP. + HostFormatPair& host_format_gbgr = + host_formats_[uint32_t(xenos::TextureFormat::k_Cr_Y1_Cb_Y0_REP)]; + assert_true(host_format_gbgr.format_unsigned.format == VK_FORMAT_G8B8G8R8_422_UNORM_KHR); + assert_true(host_format_gbgr.format_signed.format == VK_FORMAT_UNDEFINED); + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_G8B8G8R8_422_UNORM_KHR, + &format_properties); + if ((format_properties.optimalTilingFeatures & kLinearFilterFeatures) != kLinearFilterFeatures) { + host_format_gbgr.format_unsigned.load_shader = kLoadShaderIndexGBGR8ToRGB8; + host_format_gbgr.format_unsigned.format = VK_FORMAT_R8G8B8A8_UNORM; + host_format_gbgr.format_unsigned.block_compressed = false; + host_format_gbgr.unsigned_signed_compatible = false; + } + HostFormatPair& host_format_bgrg = + host_formats_[uint32_t(xenos::TextureFormat::k_Y1_Cr_Y0_Cb_REP)]; + assert_true(host_format_bgrg.format_unsigned.format == VK_FORMAT_B8G8R8G8_422_UNORM_KHR); + assert_true(host_format_bgrg.format_signed.format == VK_FORMAT_UNDEFINED); + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_B8G8R8G8_422_UNORM_KHR, + &format_properties); + if ((format_properties.optimalTilingFeatures & kLinearFilterFeatures) != kLinearFilterFeatures) { + host_format_bgrg.format_unsigned.load_shader = kLoadShaderIndexBGRG8ToRGB8; + host_format_bgrg.format_unsigned.format = VK_FORMAT_R8G8B8A8_UNORM; + host_format_bgrg.format_unsigned.block_compressed = false; + host_format_bgrg.unsigned_signed_compatible = false; + } + // k_10_11_11, k_11_11_10 (+ _AS_16_16_16_16 variants) - if normalized + // R16G16B16A16 is not linearly filterable, decode to normalized 16-bit in a + // scratch buffer first, then convert it to float16 in-place in a second pass + // before copying to the image. + bool rgba16_norm_filterable = + (r16g16b16a16_unorm_properties.optimalTilingFeatures & kLinearFilterFeatures) == + kLinearFilterFeatures && + (r16g16b16a16_snorm_properties.optimalTilingFeatures & kLinearFilterFeatures) == + kLinearFilterFeatures; + bool rgba16_float_filterable = (r16g16b16a16_sfloat_properties.optimalTilingFeatures & + kLinearFilterFeatures) == kLinearFilterFeatures; + if (!rgba16_norm_filterable) { + if (!rgba16_float_filterable) { + REXGPU_ERROR( + "VulkanTextureCache: Neither normalized nor float16 RGBA16 formats are linearly " + "filterable for 10_11_11/11_11_10 texture fallback"); + return false; + } + REXGPU_WARN("VulkanTextureCache: Using RGBA16 float fallback for 10_11_11 / 11_11_10 textures"); + constexpr std::array kR10G11B11Formats = { + xenos::TextureFormat::k_10_11_11, + xenos::TextureFormat::k_11_11_10, + xenos::TextureFormat::k_10_11_11_AS_16_16_16_16, + xenos::TextureFormat::k_11_11_10_AS_16_16_16_16, + }; + for (xenos::TextureFormat format : kR10G11B11Formats) { + HostFormatPair& host_format = host_formats_[uint32_t(format)]; + assert_true(host_format.format_unsigned.format == VK_FORMAT_R16G16B16A16_UNORM); + assert_true(host_format.format_signed.format == VK_FORMAT_R16G16B16A16_SNORM); + host_format.format_unsigned.format = VK_FORMAT_R16G16B16A16_SFLOAT; + host_format.format_signed.format = VK_FORMAT_R16G16B16A16_SFLOAT; + // Different source signednesses still need separate decoded data. + host_format.unsigned_signed_compatible = false; + } + } + // S3TC. + // Not checking the textureCompressionBC feature because its availability + // means that all BC formats are supported, however, the device may expose + // some BC formats without this feature. Xenia doesn't use BC6H and BC7 at + // all, and has fallbacks for each used format. + // TODO(Triang3l): Raise the host texture memory usage limit if S3TC has to be + // decompressed. + // TODO(Triang3l): S3TC -> 5551 or 4444 as an option. + // TODO(Triang3l): S3TC -> ETC2 / EAC (a huge research topic). + HostFormatPair& host_format_dxt1 = host_formats_[uint32_t(xenos::TextureFormat::k_DXT1)]; + assert_true(host_format_dxt1.format_unsigned.format == VK_FORMAT_BC1_RGBA_UNORM_BLOCK); + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, + &format_properties); + if ((format_properties.optimalTilingFeatures & kLinearFilterFeatures) != kLinearFilterFeatures) { + host_format_dxt1.format_unsigned.load_shader = kLoadShaderIndexDXT1ToRGBA8; + host_format_dxt1.format_unsigned.format = VK_FORMAT_R8G8B8A8_UNORM; + host_format_dxt1.format_unsigned.block_compressed = false; + host_formats_[uint32_t(xenos::TextureFormat::k_DXT1_AS_16_16_16_16)] = host_format_dxt1; + } + HostFormatPair& host_format_dxt2_3 = host_formats_[uint32_t(xenos::TextureFormat::k_DXT2_3)]; + assert_true(host_format_dxt2_3.format_unsigned.format == VK_FORMAT_BC2_UNORM_BLOCK); + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_BC2_UNORM_BLOCK, + &format_properties); + if ((format_properties.optimalTilingFeatures & kLinearFilterFeatures) != kLinearFilterFeatures) { + host_format_dxt2_3.format_unsigned.load_shader = kLoadShaderIndexDXT3ToRGBA8; + host_format_dxt2_3.format_unsigned.format = VK_FORMAT_R8G8B8A8_UNORM; + host_format_dxt2_3.format_unsigned.block_compressed = false; + host_formats_[uint32_t(xenos::TextureFormat::k_DXT2_3_AS_16_16_16_16)] = host_format_dxt2_3; + } + HostFormatPair& host_format_dxt4_5 = host_formats_[uint32_t(xenos::TextureFormat::k_DXT4_5)]; + assert_true(host_format_dxt4_5.format_unsigned.format == VK_FORMAT_BC3_UNORM_BLOCK); + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_BC3_UNORM_BLOCK, + &format_properties); + if ((format_properties.optimalTilingFeatures & kLinearFilterFeatures) != kLinearFilterFeatures) { + host_format_dxt4_5.format_unsigned.load_shader = kLoadShaderIndexDXT5ToRGBA8; + host_format_dxt4_5.format_unsigned.format = VK_FORMAT_R8G8B8A8_UNORM; + host_format_dxt4_5.format_unsigned.block_compressed = false; + host_formats_[uint32_t(xenos::TextureFormat::k_DXT4_5_AS_16_16_16_16)] = host_format_dxt4_5; + } + HostFormatPair& host_format_dxn = host_formats_[uint32_t(xenos::TextureFormat::k_DXN)]; + assert_true(host_format_dxn.format_unsigned.format == VK_FORMAT_BC5_UNORM_BLOCK); + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_BC5_UNORM_BLOCK, + &format_properties); + if ((format_properties.optimalTilingFeatures & kLinearFilterFeatures) != kLinearFilterFeatures) { + host_format_dxn.format_unsigned.load_shader = kLoadShaderIndexDXNToRG8; + host_format_dxn.format_unsigned.format = VK_FORMAT_R8G8_UNORM; + host_format_dxn.format_unsigned.block_compressed = false; + } + HostFormatPair& host_format_dxt5a = host_formats_[uint32_t(xenos::TextureFormat::k_DXT5A)]; + assert_true(host_format_dxt5a.format_unsigned.format == VK_FORMAT_BC4_UNORM_BLOCK); + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_BC4_UNORM_BLOCK, + &format_properties); + if ((format_properties.optimalTilingFeatures & kLinearFilterFeatures) != kLinearFilterFeatures) { + host_format_dxt5a.format_unsigned.load_shader = kLoadShaderIndexDXT5AToR8; + host_format_dxt5a.format_unsigned.format = VK_FORMAT_R8_UNORM; + host_format_dxt5a.format_unsigned.block_compressed = false; + } + // Keep signed format support aligned with D3D12 for texture formats where + // D3D12 doesn't expose signed sampling paths. + constexpr std::array kD3D12SignedUnsupportedFormats = { + xenos::TextureFormat::k_1_5_5_5, + xenos::TextureFormat::k_5_6_5, + xenos::TextureFormat::k_6_5_5, + xenos::TextureFormat::k_2_10_10_10, + xenos::TextureFormat::k_Cr_Y1_Cb_Y0_REP, + xenos::TextureFormat::k_Y1_Cr_Y0_Cb_REP, + xenos::TextureFormat::k_4_4_4_4, + xenos::TextureFormat::k_DXT1, + xenos::TextureFormat::k_DXT2_3, + xenos::TextureFormat::k_DXT4_5, + xenos::TextureFormat::k_DXN, + xenos::TextureFormat::k_DXT5A, + xenos::TextureFormat::k_CTX1, + xenos::TextureFormat::k_DXT1_AS_16_16_16_16, + xenos::TextureFormat::k_DXT2_3_AS_16_16_16_16, + xenos::TextureFormat::k_DXT4_5_AS_16_16_16_16, + xenos::TextureFormat::k_2_10_10_10_AS_16_16_16_16, + xenos::TextureFormat::k_DXT3A, + xenos::TextureFormat::k_DXT3A_AS_1_1_1_1, + }; + for (xenos::TextureFormat format : kD3D12SignedUnsupportedFormats) { + HostFormatPair& host_format = host_formats_[uint32_t(format)]; + host_format.format_signed.load_shader = kLoadShaderIndexUnknown; + host_format.format_signed.format = VK_FORMAT_UNDEFINED; + host_format.format_signed.linear_filterable = false; + host_format.unsigned_signed_compatible = false; + } + // k_16, k_16_16, k_16_16_16_16 - UNORM / SNORM are optional, fall back to + // SFLOAT, which is mandatory and is always filterable. + // For D3D12 parity, prefer keeping normalized-format sampling filterable over + // keeping fixed-point precision if the host lacks linear filtering support on + // UNORM/SNORM variants. + VkFormatFeatureFlags norm16_required_features = kLinearFilterFeatures; + HostFormatPair& host_format_16 = host_formats_[uint32_t(xenos::TextureFormat::k_16)]; + assert_true(host_format_16.format_unsigned.format == VK_FORMAT_R16_UNORM); + if ((r16_unorm_properties.optimalTilingFeatures & norm16_required_features) != + norm16_required_features) { + host_format_16.format_unsigned.load_shader = kLoadShaderIndexR16UNormToFloat; + host_format_16.format_unsigned.format = VK_FORMAT_R16_SFLOAT; + } + assert_true(host_format_16.format_signed.format == VK_FORMAT_R16_SNORM); + if ((r16_snorm_properties.optimalTilingFeatures & norm16_required_features) != + norm16_required_features) { + host_format_16.format_signed.load_shader = kLoadShaderIndexR16SNormToFloat; + host_format_16.format_signed.format = VK_FORMAT_R16_SFLOAT; + } + host_format_16.unsigned_signed_compatible = + (host_format_16.format_unsigned.format == VK_FORMAT_R16_UNORM && + host_format_16.format_signed.format == VK_FORMAT_R16_SNORM) || + (host_format_16.format_unsigned.format == VK_FORMAT_R16_SFLOAT && + host_format_16.format_signed.format == VK_FORMAT_R16_SFLOAT); + HostFormatPair& host_format_16_16 = host_formats_[uint32_t(xenos::TextureFormat::k_16_16)]; + assert_true(host_format_16_16.format_unsigned.format == VK_FORMAT_R16G16_UNORM); + if ((r16g16_unorm_properties.optimalTilingFeatures & norm16_required_features) != + norm16_required_features) { + host_format_16_16.format_unsigned.load_shader = kLoadShaderIndexRG16UNormToFloat; + host_format_16_16.format_unsigned.format = VK_FORMAT_R16G16_SFLOAT; + } + assert_true(host_format_16_16.format_signed.format == VK_FORMAT_R16G16_SNORM); + if ((r16g16_snorm_properties.optimalTilingFeatures & norm16_required_features) != + norm16_required_features) { + host_format_16_16.format_signed.load_shader = kLoadShaderIndexRG16SNormToFloat; + host_format_16_16.format_signed.format = VK_FORMAT_R16G16_SFLOAT; + } + host_format_16_16.unsigned_signed_compatible = + (host_format_16_16.format_unsigned.format == VK_FORMAT_R16G16_UNORM && + host_format_16_16.format_signed.format == VK_FORMAT_R16G16_SNORM) || + (host_format_16_16.format_unsigned.format == VK_FORMAT_R16G16_SFLOAT && + host_format_16_16.format_signed.format == VK_FORMAT_R16G16_SFLOAT); + HostFormatPair& host_format_16_16_16_16 = + host_formats_[uint32_t(xenos::TextureFormat::k_16_16_16_16)]; + assert_true(host_format_16_16_16_16.format_unsigned.format == VK_FORMAT_R16G16B16A16_UNORM); + if ((r16g16b16a16_unorm_properties.optimalTilingFeatures & norm16_required_features) != + norm16_required_features) { + host_format_16_16_16_16.format_unsigned.load_shader = kLoadShaderIndexRGBA16UNormToFloat; + host_format_16_16_16_16.format_unsigned.format = VK_FORMAT_R16G16B16A16_SFLOAT; + } + assert_true(host_format_16_16_16_16.format_signed.format == VK_FORMAT_R16G16B16A16_SNORM); + if ((r16g16b16a16_snorm_properties.optimalTilingFeatures & norm16_required_features) != + norm16_required_features) { + host_format_16_16_16_16.format_signed.load_shader = kLoadShaderIndexRGBA16SNormToFloat; + host_format_16_16_16_16.format_signed.format = VK_FORMAT_R16G16B16A16_SFLOAT; + } + host_format_16_16_16_16.unsigned_signed_compatible = + (host_format_16_16_16_16.format_unsigned.format == VK_FORMAT_R16G16B16A16_UNORM && + host_format_16_16_16_16.format_signed.format == VK_FORMAT_R16G16B16A16_SNORM) || + (host_format_16_16_16_16.format_unsigned.format == VK_FORMAT_R16G16B16A16_SFLOAT && + host_format_16_16_16_16.format_signed.format == VK_FORMAT_R16G16B16A16_SFLOAT); + + // Normalize format information structures. + for (size_t i = 0; i < rex::countof(host_formats_); ++i) { + HostFormatPair& host_format = host_formats_[i]; + // load_shader_index is left uninitialized for the tail (non-existent + // formats), kLoadShaderIndexUnknown may be non-zero, and format support may + // be disabled by setting the format to VK_FORMAT_UNDEFINED. + if (host_format.format_unsigned.format == VK_FORMAT_UNDEFINED) { + host_format.format_unsigned.load_shader = kLoadShaderIndexUnknown; + } + assert_false(host_format.format_unsigned.load_shader == kLoadShaderIndexUnknown && + host_format.format_unsigned.format != VK_FORMAT_UNDEFINED); + if (host_format.format_unsigned.load_shader == kLoadShaderIndexUnknown) { + host_format.format_unsigned.format = VK_FORMAT_UNDEFINED; + // Surely known it's unsupported with these two conditions. + host_format.format_unsigned.linear_filterable = false; + } + if (host_format.format_signed.format == VK_FORMAT_UNDEFINED) { + host_format.format_signed.load_shader = kLoadShaderIndexUnknown; + } + assert_false(host_format.format_signed.load_shader == kLoadShaderIndexUnknown && + host_format.format_signed.format != VK_FORMAT_UNDEFINED); + if (host_format.format_signed.load_shader == kLoadShaderIndexUnknown) { + host_format.format_signed.format = VK_FORMAT_UNDEFINED; + // Surely known it's unsupported with these two conditions. + host_format.format_signed.linear_filterable = false; + } + + // Check if the formats are supported and are linear-filterable. + if (host_format.format_unsigned.format != VK_FORMAT_UNDEFINED) { + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, host_format.format_unsigned.format, + &format_properties); + if (format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) { + host_format.format_unsigned.linear_filterable = + (format_properties.optimalTilingFeatures & + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) != 0; + } else { + host_format.format_unsigned.format = VK_FORMAT_UNDEFINED; + host_format.format_unsigned.load_shader = kLoadShaderIndexUnknown; + host_format.format_unsigned.linear_filterable = false; + } + } + if (host_format.format_signed.format != VK_FORMAT_UNDEFINED) { + ifn.vkGetPhysicalDeviceFormatProperties(physical_device, host_format.format_signed.format, + &format_properties); + if (format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) { + host_format.format_signed.linear_filterable = + (format_properties.optimalTilingFeatures & + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) != 0; + } else { + host_format.format_signed.format = VK_FORMAT_UNDEFINED; + host_format.format_signed.load_shader = kLoadShaderIndexUnknown; + host_format.format_signed.linear_filterable = false; + } + } + + // Log which formats are not supported or supported via fallbacks. + const HostFormatPair& best_host_format = kBestHostFormats[i]; + const char* guest_format_name = FormatInfo::Get(xenos::TextureFormat(i))->name; + if (best_host_format.format_unsigned.format != VK_FORMAT_UNDEFINED) { + assert_not_null(guest_format_name); + if (host_format.format_unsigned.format != VK_FORMAT_UNDEFINED) { + if (host_format.format_unsigned.format != best_host_format.format_unsigned.format) { + REXGPU_INFO( + "VulkanTextureCache: Format {} (unsigned) is supported via a " + "fallback format (using the Vulkan format {} instead of the " + "preferred {})", + guest_format_name, uint32_t(host_format.format_unsigned.format), + uint32_t(best_host_format.format_unsigned.format)); + } + } else { + REXGPU_INFO( + "VulkanTextureCache: Format {} (unsigned) is not supported by the " + "device (preferred Vulkan format is {})", + guest_format_name, uint32_t(best_host_format.format_unsigned.format)); + } + } + if (best_host_format.format_signed.format != VK_FORMAT_UNDEFINED) { + assert_not_null(guest_format_name); + if (host_format.format_signed.format != VK_FORMAT_UNDEFINED) { + if (host_format.format_signed.format != best_host_format.format_signed.format) { + REXGPU_INFO( + "VulkanTextureCache: Format {} (signed) is supported via a " + "fallback format (using the Vulkan format {} instead of the " + "preferred {})", + guest_format_name, uint32_t(host_format.format_signed.format), + uint32_t(best_host_format.format_signed.format)); + } + } else { + REXGPU_INFO( + "VulkanTextureCache: Format {} (signed) is not supported by the " + "device (preferred Vulkan format is {})", + guest_format_name, uint32_t(best_host_format.format_signed.format)); + } + } + + // Signednesses with different load shaders must have the data loaded + // differently, therefore can't share the image even if the format is the + // same. Also, if there's only one version, simplify the logic - there can't + // be compatibility between two formats when one of them is undefined. + if (host_format.format_unsigned.format != VK_FORMAT_UNDEFINED && + host_format.format_signed.format != VK_FORMAT_UNDEFINED) { + if (host_format.format_unsigned.load_shader == host_format.format_signed.load_shader) { + if (host_format.format_unsigned.format == host_format.format_signed.format) { + // Same format after all the fallbacks - force compatibilty. + host_format.unsigned_signed_compatible = true; + } + } else { + host_format.unsigned_signed_compatible = false; + } + // Formats within the same compatibility class must have the same block + // size, though the fallbacks are configured incorrectly if that's not the + // case (since such formats just can't be in one compatibility class). + assert_false(host_format.unsigned_signed_compatible && + host_format.format_unsigned.block_compressed != + host_format.format_signed.block_compressed); + if (host_format.unsigned_signed_compatible && + host_format.format_unsigned.block_compressed != + host_format.format_signed.block_compressed) { + host_format.unsigned_signed_compatible = false; + } + } else { + host_format.unsigned_signed_compatible = false; + } + } + + // Load pipeline layout. + + VkDescriptorSetLayout load_descriptor_set_layouts[kLoadDescriptorSetCount] = {}; + VkDescriptorSetLayout load_descriptor_set_layout_storage_buffer = + command_processor_.GetSingleTransientDescriptorLayout( + VulkanCommandProcessor::SingleTransientDescriptorLayout ::kStorageBufferCompute); + assert_true(load_descriptor_set_layout_storage_buffer != VK_NULL_HANDLE); + load_descriptor_set_layouts[kLoadDescriptorSetIndexDestination] = + load_descriptor_set_layout_storage_buffer; + load_descriptor_set_layouts[kLoadDescriptorSetIndexSource] = + load_descriptor_set_layout_storage_buffer; + VkPushConstantRange load_pipeline_layout_push_constant_range; + load_pipeline_layout_push_constant_range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + load_pipeline_layout_push_constant_range.offset = 0; + load_pipeline_layout_push_constant_range.size = sizeof(LoadConstants); + VkPipelineLayoutCreateInfo load_pipeline_layout_create_info; + load_pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + load_pipeline_layout_create_info.pNext = nullptr; + load_pipeline_layout_create_info.flags = 0; + load_pipeline_layout_create_info.setLayoutCount = kLoadDescriptorSetCount; + load_pipeline_layout_create_info.pSetLayouts = load_descriptor_set_layouts; + load_pipeline_layout_create_info.pushConstantRangeCount = 1; + load_pipeline_layout_create_info.pPushConstantRanges = &load_pipeline_layout_push_constant_range; + if (dfn.vkCreatePipelineLayout(device, &load_pipeline_layout_create_info, nullptr, + &load_pipeline_layout_)) { + REXGPU_ERROR("VulkanTexture: Failed to create the texture load pipeline layout"); + return false; + } + + // Load pipelines, only the ones needed for the formats that will be used. + + bool load_shaders_needed[kLoadShaderCount] = {}; + auto mark_host_format_pair_load_shaders_needed = [&](const HostFormatPair& host_format_pair) { + if (host_format_pair.format_unsigned.load_shader != kLoadShaderIndexUnknown) { + load_shaders_needed[host_format_pair.format_unsigned.load_shader] = true; + } + if (host_format_pair.format_signed.load_shader != kLoadShaderIndexUnknown) { + load_shaders_needed[host_format_pair.format_signed.load_shader] = true; + } + }; + for (size_t i = 0; i < rex::countof(host_formats_); ++i) { + mark_host_format_pair_load_shaders_needed(host_formats_[i]); + } + mark_host_format_pair_load_shaders_needed(kHostFormatGBGRUnaligned); + mark_host_format_pair_load_shaders_needed(kHostFormatBGRGUnaligned); + mark_host_format_pair_load_shaders_needed(kHostFormatDXT1Unaligned); + mark_host_format_pair_load_shaders_needed(kHostFormatDXT2_3Unaligned); + mark_host_format_pair_load_shaders_needed(kHostFormatDXT4_5Unaligned); + mark_host_format_pair_load_shaders_needed(kHostFormatDXNUnaligned); + mark_host_format_pair_load_shaders_needed(kHostFormatDXT5AUnaligned); + + std::pair load_shader_code[kLoadShaderCount] = {}; + load_shader_code[kLoadShaderIndex8bpb] = + std::make_pair(shaders::texture_load_8bpb_cs, sizeof(shaders::texture_load_8bpb_cs)); + load_shader_code[kLoadShaderIndex16bpb] = + std::make_pair(shaders::texture_load_16bpb_cs, sizeof(shaders::texture_load_16bpb_cs)); + load_shader_code[kLoadShaderIndex32bpb] = + std::make_pair(shaders::texture_load_32bpb_cs, sizeof(shaders::texture_load_32bpb_cs)); + load_shader_code[kLoadShaderIndex64bpb] = + std::make_pair(shaders::texture_load_64bpb_cs, sizeof(shaders::texture_load_64bpb_cs)); + load_shader_code[kLoadShaderIndex128bpb] = + std::make_pair(shaders::texture_load_128bpb_cs, sizeof(shaders::texture_load_128bpb_cs)); + load_shader_code[kLoadShaderIndexR5G5B5A1ToB5G5R5A1] = + std::make_pair(shaders::texture_load_r5g5b5a1_b5g5r5a1_cs, + sizeof(shaders::texture_load_r5g5b5a1_b5g5r5a1_cs)); + load_shader_code[kLoadShaderIndexR5G6B5ToB5G6R5] = std::make_pair( + shaders::texture_load_r5g6b5_b5g6r5_cs, sizeof(shaders::texture_load_r5g6b5_b5g6r5_cs)); + load_shader_code[kLoadShaderIndexR5G5B6ToB5G6R5WithRBGASwizzle] = + std::make_pair(shaders::texture_load_r5g5b6_b5g6r5_swizzle_rbga_cs, + sizeof(shaders::texture_load_r5g5b6_b5g6r5_swizzle_rbga_cs)); + load_shader_code[kLoadShaderIndexRGBA4ToARGB4] = + std::make_pair(shaders::texture_load_r4g4b4a4_a4r4g4b4_cs, + sizeof(shaders::texture_load_r4g4b4a4_a4r4g4b4_cs)); + load_shader_code[kLoadShaderIndexGBGR8ToRGB8] = std::make_pair( + shaders::texture_load_gbgr8_rgb8_cs, sizeof(shaders::texture_load_gbgr8_rgb8_cs)); + load_shader_code[kLoadShaderIndexBGRG8ToRGB8] = std::make_pair( + shaders::texture_load_bgrg8_rgb8_cs, sizeof(shaders::texture_load_bgrg8_rgb8_cs)); + load_shader_code[kLoadShaderIndexR10G11B11ToRGBA16] = std::make_pair( + shaders::texture_load_r10g11b11_rgba16_cs, sizeof(shaders::texture_load_r10g11b11_rgba16_cs)); + load_shader_code[kLoadShaderIndexR10G11B11ToRGBA16SNorm] = + std::make_pair(shaders::texture_load_r10g11b11_rgba16_snorm_cs, + sizeof(shaders::texture_load_r10g11b11_rgba16_snorm_cs)); + load_shader_code[kLoadShaderIndexR11G11B10ToRGBA16] = std::make_pair( + shaders::texture_load_r11g11b10_rgba16_cs, sizeof(shaders::texture_load_r11g11b10_rgba16_cs)); + load_shader_code[kLoadShaderIndexR11G11B10ToRGBA16SNorm] = + std::make_pair(shaders::texture_load_r11g11b10_rgba16_snorm_cs, + sizeof(shaders::texture_load_r11g11b10_rgba16_snorm_cs)); + load_shader_code[kLoadShaderIndexR16UNormToFloat] = std::make_pair( + shaders::texture_load_r16_unorm_float_cs, sizeof(shaders::texture_load_r16_unorm_float_cs)); + load_shader_code[kLoadShaderIndexR16SNormToFloat] = std::make_pair( + shaders::texture_load_r16_snorm_float_cs, sizeof(shaders::texture_load_r16_snorm_float_cs)); + load_shader_code[kLoadShaderIndexRG16UNormToFloat] = std::make_pair( + shaders::texture_load_rg16_unorm_float_cs, sizeof(shaders::texture_load_rg16_unorm_float_cs)); + load_shader_code[kLoadShaderIndexRG16SNormToFloat] = std::make_pair( + shaders::texture_load_rg16_snorm_float_cs, sizeof(shaders::texture_load_rg16_snorm_float_cs)); + load_shader_code[kLoadShaderIndexRGBA16UNormToFloat] = + std::make_pair(shaders::texture_load_rgba16_unorm_float_cs, + sizeof(shaders::texture_load_rgba16_unorm_float_cs)); + load_shader_code[kLoadShaderIndexRGBA16SNormToFloat] = + std::make_pair(shaders::texture_load_rgba16_snorm_float_cs, + sizeof(shaders::texture_load_rgba16_snorm_float_cs)); + load_shader_code[kLoadShaderIndexDXT1ToRGBA8] = std::make_pair( + shaders::texture_load_dxt1_rgba8_cs, sizeof(shaders::texture_load_dxt1_rgba8_cs)); + load_shader_code[kLoadShaderIndexDXT3ToRGBA8] = std::make_pair( + shaders::texture_load_dxt3_rgba8_cs, sizeof(shaders::texture_load_dxt3_rgba8_cs)); + load_shader_code[kLoadShaderIndexDXT5ToRGBA8] = std::make_pair( + shaders::texture_load_dxt5_rgba8_cs, sizeof(shaders::texture_load_dxt5_rgba8_cs)); + load_shader_code[kLoadShaderIndexDXNToRG8] = + std::make_pair(shaders::texture_load_dxn_rg8_cs, sizeof(shaders::texture_load_dxn_rg8_cs)); + load_shader_code[kLoadShaderIndexDXT3A] = + std::make_pair(shaders::texture_load_dxt3a_cs, sizeof(shaders::texture_load_dxt3a_cs)); + load_shader_code[kLoadShaderIndexDXT3AAs1111ToARGB4] = + std::make_pair(shaders::texture_load_dxt3aas1111_argb4_cs, + sizeof(shaders::texture_load_dxt3aas1111_argb4_cs)); + load_shader_code[kLoadShaderIndexDXT5AToR8] = + std::make_pair(shaders::texture_load_dxt5a_r8_cs, sizeof(shaders::texture_load_dxt5a_r8_cs)); + load_shader_code[kLoadShaderIndexCTX1] = + std::make_pair(shaders::texture_load_ctx1_cs, sizeof(shaders::texture_load_ctx1_cs)); + load_shader_code[kLoadShaderIndexDepthUnorm] = std::make_pair( + shaders::texture_load_depth_unorm_cs, sizeof(shaders::texture_load_depth_unorm_cs)); + load_shader_code[kLoadShaderIndexDepthFloat] = std::make_pair( + shaders::texture_load_depth_float_cs, sizeof(shaders::texture_load_depth_float_cs)); + std::pair load_shader_code_scaled[kLoadShaderCount] = {}; + if (IsDrawResolutionScaled()) { + load_shader_code_scaled[kLoadShaderIndex8bpb] = std::make_pair( + shaders::texture_load_8bpb_scaled_cs, sizeof(shaders::texture_load_8bpb_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndex16bpb] = std::make_pair( + shaders::texture_load_16bpb_scaled_cs, sizeof(shaders::texture_load_16bpb_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndex32bpb] = std::make_pair( + shaders::texture_load_32bpb_scaled_cs, sizeof(shaders::texture_load_32bpb_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndex64bpb] = std::make_pair( + shaders::texture_load_64bpb_scaled_cs, sizeof(shaders::texture_load_64bpb_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndex128bpb] = std::make_pair( + shaders::texture_load_128bpb_scaled_cs, sizeof(shaders::texture_load_128bpb_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndexR5G5B5A1ToB5G5R5A1] = + std::make_pair(shaders::texture_load_r5g5b5a1_b5g5r5a1_scaled_cs, + sizeof(shaders::texture_load_r5g5b5a1_b5g5r5a1_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndexR5G6B5ToB5G6R5] = + std::make_pair(shaders::texture_load_r5g6b5_b5g6r5_scaled_cs, + sizeof(shaders::texture_load_r5g6b5_b5g6r5_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndexR5G5B6ToB5G6R5WithRBGASwizzle] = + std::make_pair(shaders::texture_load_r5g5b6_b5g6r5_swizzle_rbga_scaled_cs, + sizeof(shaders::texture_load_r5g5b6_b5g6r5_swizzle_rbga_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndexRGBA4ToARGB4] = + std::make_pair(shaders::texture_load_r4g4b4a4_a4r4g4b4_scaled_cs, + sizeof(shaders::texture_load_r4g4b4a4_a4r4g4b4_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndexR10G11B11ToRGBA16] = + std::make_pair(shaders::texture_load_r10g11b11_rgba16_scaled_cs, + sizeof(shaders::texture_load_r10g11b11_rgba16_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndexR10G11B11ToRGBA16SNorm] = + std::make_pair(shaders::texture_load_r10g11b11_rgba16_snorm_scaled_cs, + sizeof(shaders::texture_load_r10g11b11_rgba16_snorm_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndexR11G11B10ToRGBA16] = + std::make_pair(shaders::texture_load_r11g11b10_rgba16_scaled_cs, + sizeof(shaders::texture_load_r11g11b10_rgba16_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndexR11G11B10ToRGBA16SNorm] = + std::make_pair(shaders::texture_load_r11g11b10_rgba16_snorm_scaled_cs, + sizeof(shaders::texture_load_r11g11b10_rgba16_snorm_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndexR16UNormToFloat] = + std::make_pair(shaders::texture_load_r16_unorm_float_scaled_cs, + sizeof(shaders::texture_load_r16_unorm_float_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndexR16SNormToFloat] = + std::make_pair(shaders::texture_load_r16_snorm_float_scaled_cs, + sizeof(shaders::texture_load_r16_snorm_float_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndexRG16UNormToFloat] = + std::make_pair(shaders::texture_load_rg16_unorm_float_scaled_cs, + sizeof(shaders::texture_load_rg16_unorm_float_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndexRG16SNormToFloat] = + std::make_pair(shaders::texture_load_rg16_snorm_float_scaled_cs, + sizeof(shaders::texture_load_rg16_snorm_float_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndexRGBA16UNormToFloat] = + std::make_pair(shaders::texture_load_rgba16_unorm_float_scaled_cs, + sizeof(shaders::texture_load_rgba16_unorm_float_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndexRGBA16SNormToFloat] = + std::make_pair(shaders::texture_load_rgba16_snorm_float_scaled_cs, + sizeof(shaders::texture_load_rgba16_snorm_float_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndexDepthUnorm] = + std::make_pair(shaders::texture_load_depth_unorm_scaled_cs, + sizeof(shaders::texture_load_depth_unorm_scaled_cs)); + load_shader_code_scaled[kLoadShaderIndexDepthFloat] = + std::make_pair(shaders::texture_load_depth_float_scaled_cs, + sizeof(shaders::texture_load_depth_float_scaled_cs)); + } + + for (size_t i = 0; i < kLoadShaderCount; ++i) { + if (!load_shaders_needed[i]) { + continue; + } + const std::pair& current_load_shader_code = load_shader_code[i]; + assert_not_null(current_load_shader_code.first); + load_pipelines_[i] = ui::vulkan::util::CreateComputePipeline( + vulkan_device, load_pipeline_layout_, current_load_shader_code.first, + current_load_shader_code.second); + if (load_pipelines_[i] == VK_NULL_HANDLE) { + REXGPU_ERROR( + "VulkanTextureCache: Failed to create the texture loading pipeline " + "for shader {}", + i); + return false; + } + if (IsDrawResolutionScaled()) { + const std::pair& current_load_shader_code_scaled = + load_shader_code_scaled[i]; + if (current_load_shader_code_scaled.first) { + load_pipelines_scaled_[i] = ui::vulkan::util::CreateComputePipeline( + vulkan_device, load_pipeline_layout_, current_load_shader_code_scaled.first, + current_load_shader_code_scaled.second); + if (load_pipelines_scaled_[i] == VK_NULL_HANDLE) { + REXGPU_ERROR( + "VulkanTextureCache: Failed to create the resolution-scaled " + "texture loading pipeline for shader {}", + i); + return false; + } + } + } + } + + // Use true null descriptors when supported; otherwise, keep compatibility + // fallback null images. + if (device_properties.nullDescriptor) { + null_images_cleared_ = true; + } else { + // Null images as a replacement for unneeded bindings and for bindings for + // which the real image hasn't been created. + VkImageCreateInfo null_image_create_info; + null_image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + null_image_create_info.pNext = nullptr; + null_image_create_info.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; + null_image_create_info.imageType = VK_IMAGE_TYPE_2D; + // Match D3D12 null SRV behavior: invalid fetch constants read (0, 0, 0, 0). + null_image_create_info.format = kInvalidTextureFetchFallbackFormat; + null_image_create_info.extent.width = 1; + null_image_create_info.extent.height = 1; + null_image_create_info.extent.depth = 1; + null_image_create_info.mipLevels = 1; + null_image_create_info.arrayLayers = 6; + null_image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; + null_image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; + null_image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + null_image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + null_image_create_info.queueFamilyIndexCount = 0; + null_image_create_info.pQueueFamilyIndices = nullptr; + null_image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + if (dfn.vkCreateImage(device, &null_image_create_info, nullptr, &null_image_2d_array_cube_) != + VK_SUCCESS) { + REXGPU_ERROR( + "VulkanTextureCache: Failed to create the null 2D array and cube " + "image"); + return false; + } + + null_image_create_info.flags &= ~VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; + null_image_create_info.imageType = VK_IMAGE_TYPE_3D; + null_image_create_info.arrayLayers = 1; + if (dfn.vkCreateImage(device, &null_image_create_info, nullptr, &null_image_3d_) != + VK_SUCCESS) { + REXGPU_ERROR("VulkanTextureCache: Failed to create the null 3D image"); + return false; + } + + VkMemoryRequirements null_image_memory_requirements_2d_array_cube_; + dfn.vkGetImageMemoryRequirements(device, null_image_2d_array_cube_, + &null_image_memory_requirements_2d_array_cube_); + VkMemoryRequirements null_image_memory_requirements_3d_; + dfn.vkGetImageMemoryRequirements(device, null_image_3d_, &null_image_memory_requirements_3d_); + uint32_t null_image_memory_type_common = ui::vulkan::util::ChooseMemoryType( + vulkan_device->memory_types(), + null_image_memory_requirements_2d_array_cube_.memoryTypeBits & + null_image_memory_requirements_3d_.memoryTypeBits, + ui::vulkan::util::MemoryPurpose::kDeviceLocal); + if (null_image_memory_type_common != UINT32_MAX) { + // Place both null images in one memory allocation because maximum total + // memory allocation count is limited. + VkDeviceSize null_image_memory_offset_3d_ = + rex::align(null_image_memory_requirements_2d_array_cube_.size, + std::max(null_image_memory_requirements_3d_.alignment, VkDeviceSize(1))); + VkMemoryAllocateInfo null_image_memory_allocate_info; + null_image_memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + null_image_memory_allocate_info.pNext = nullptr; + null_image_memory_allocate_info.allocationSize = + null_image_memory_offset_3d_ + null_image_memory_requirements_3d_.size; + null_image_memory_allocate_info.memoryTypeIndex = null_image_memory_type_common; + if (dfn.vkAllocateMemory(device, &null_image_memory_allocate_info, nullptr, + &null_images_memory_[0]) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanTextureCache: Failed to allocate the memory for the null " + "images"); + return false; + } + if (dfn.vkBindImageMemory(device, null_image_2d_array_cube_, null_images_memory_[0], 0) != + VK_SUCCESS) { + REXGPU_ERROR( + "VulkanTextureCache: Failed to bind the memory to the null 2D array " + "and cube image"); + return false; + } + if (dfn.vkBindImageMemory(device, null_image_3d_, null_images_memory_[0], + null_image_memory_offset_3d_) != VK_SUCCESS) { + REXGPU_ERROR("VulkanTextureCache: Failed to bind the memory to the null 3D image"); + return false; + } + } else { + // Place each null image in separate allocations. + const uint32_t null_image_memory_type_2d_array_cube = ui::vulkan::util::ChooseMemoryType( + vulkan_device->memory_types(), + null_image_memory_requirements_2d_array_cube_.memoryTypeBits, + ui::vulkan::util::MemoryPurpose::kDeviceLocal); + const uint32_t null_image_memory_type_3d = ui::vulkan::util::ChooseMemoryType( + vulkan_device->memory_types(), null_image_memory_requirements_3d_.memoryTypeBits, + ui::vulkan::util::MemoryPurpose::kDeviceLocal); + if (null_image_memory_type_2d_array_cube == UINT32_MAX || + null_image_memory_type_3d == UINT32_MAX) { + REXGPU_ERROR( + "VulkanTextureCache: Failed to get the memory types for the null " + "images"); + return false; + } + + VkMemoryAllocateInfo null_image_memory_allocate_info; + VkMemoryAllocateInfo* null_image_memory_allocate_info_last = &null_image_memory_allocate_info; + null_image_memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + null_image_memory_allocate_info.pNext = nullptr; + null_image_memory_allocate_info.allocationSize = + null_image_memory_requirements_2d_array_cube_.size; + null_image_memory_allocate_info.memoryTypeIndex = null_image_memory_type_2d_array_cube; + VkMemoryDedicatedAllocateInfo null_image_memory_dedicated_allocate_info; + if (vulkan_device->extensions().ext_1_1_KHR_dedicated_allocation) { + null_image_memory_allocate_info_last->pNext = &null_image_memory_dedicated_allocate_info; + null_image_memory_allocate_info_last = + reinterpret_cast(&null_image_memory_dedicated_allocate_info); + null_image_memory_dedicated_allocate_info.sType = + VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO; + null_image_memory_dedicated_allocate_info.pNext = nullptr; + null_image_memory_dedicated_allocate_info.image = null_image_2d_array_cube_; + null_image_memory_dedicated_allocate_info.buffer = VK_NULL_HANDLE; + } + if (dfn.vkAllocateMemory(device, &null_image_memory_allocate_info, nullptr, + &null_images_memory_[0]) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanTextureCache: Failed to allocate the memory for the null 2D " + "array and cube image"); + return false; + } + if (dfn.vkBindImageMemory(device, null_image_2d_array_cube_, null_images_memory_[0], 0) != + VK_SUCCESS) { + REXGPU_ERROR( + "VulkanTextureCache: Failed to bind the memory to the null 2D array " + "and cube image"); + return false; + } + + null_image_memory_allocate_info.allocationSize = null_image_memory_requirements_3d_.size; + null_image_memory_allocate_info.memoryTypeIndex = null_image_memory_type_3d; + null_image_memory_dedicated_allocate_info.image = null_image_3d_; + if (dfn.vkAllocateMemory(device, &null_image_memory_allocate_info, nullptr, + &null_images_memory_[1]) != VK_SUCCESS) { + REXGPU_ERROR( + "VulkanTextureCache: Failed to allocate the memory for the null 3D " + "image"); + return false; + } + if (dfn.vkBindImageMemory(device, null_image_3d_, null_images_memory_[1], 0) != VK_SUCCESS) { + REXGPU_ERROR("VulkanTextureCache: Failed to bind the memory to the null 3D image"); + return false; + } + } + + VkImageViewCreateInfo null_image_view_create_info; + null_image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + null_image_view_create_info.pNext = nullptr; + null_image_view_create_info.flags = 0; + null_image_view_create_info.image = null_image_2d_array_cube_; + null_image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + null_image_view_create_info.format = null_image_create_info.format; + // Micro-optimization if this has any effect on the host GPU at all, use only + // constant components instead of the real texels. + VkComponentSwizzle null_image_view_swizzle = device_properties.imageViewFormatSwizzle + ? VK_COMPONENT_SWIZZLE_ZERO + : VK_COMPONENT_SWIZZLE_IDENTITY; + null_image_view_create_info.components.r = null_image_view_swizzle; + null_image_view_create_info.components.g = null_image_view_swizzle; + null_image_view_create_info.components.b = null_image_view_swizzle; + null_image_view_create_info.components.a = null_image_view_swizzle; + null_image_view_create_info.subresourceRange = ui::vulkan::util::InitializeSubresourceRange( + VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, 1); + if (dfn.vkCreateImageView(device, &null_image_view_create_info, nullptr, + &null_image_view_2d_array_) != VK_SUCCESS) { + REXGPU_ERROR("VulkanTextureCache: Failed to create the null 2D array image view"); + return false; + } + null_image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_CUBE; + null_image_view_create_info.subresourceRange.layerCount = 6; + if (dfn.vkCreateImageView(device, &null_image_view_create_info, nullptr, + &null_image_view_cube_) != VK_SUCCESS) { + REXGPU_ERROR("VulkanTextureCache: Failed to create the null cube image view"); + return false; + } + null_image_view_create_info.image = null_image_3d_; + null_image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_3D; + null_image_view_create_info.subresourceRange.layerCount = 1; + if (dfn.vkCreateImageView(device, &null_image_view_create_info, nullptr, + &null_image_view_3d_) != VK_SUCCESS) { + REXGPU_ERROR("VulkanTextureCache: Failed to create the null 3D image view"); + return false; + } + + null_images_cleared_ = false; + } + + // Samplers. + + // Some MoltenVK devices have a maximum of 2048, 1024, or even 96 samplers, + // below Vulkan's minimum requirement of 4000. + // Assuming that the current VulkanTextureCache is the only one on this + // VkDevice (true in a regular emulation scenario), so taking over all the + // allocation slots exclusively. + // Also leaving a few slots for use by things like overlay applications. + sampler_max_count_ = + device_properties.maxSamplerAllocationCount - ui::vulkan::UISamplers::kSamplerCount - 16; + + if (device_properties.samplerAnisotropy) { + max_anisotropy_ = xenos::AnisoFilter( + uint32_t(xenos::AnisoFilter::kMax_1_1) + + (31 - rex::lzcnt(uint32_t( + std::min(16.0f, std::max(1.0f, device_properties.maxSamplerAnisotropy)))))); + } else { + max_anisotropy_ = xenos::AnisoFilter::kDisabled; + } + + return true; +} + +const VulkanTextureCache::HostFormatPair& VulkanTextureCache::GetHostFormatPair( + TextureKey key) const { + const HostFormatPair& host_format_pair = host_formats_[uint32_t(key.format)]; + if (!host_format_pair.format_unsigned.block_compressed && + !host_format_pair.format_signed.block_compressed) { + return host_format_pair; + } + + // Keep unaligned decompression selection aligned with D3D12 fallback behavior: + // only select unaligned fallback mappings when block alignment is actually + // violated for the current guest format. + const FormatInfo* format_info = FormatInfo::Get(key.format); + if (!(key.GetWidth() & (format_info->block_width - 1)) && + !(key.GetHeight() & (format_info->block_height - 1))) { + return host_format_pair; + } + + switch (key.format) { + case xenos::TextureFormat::k_Cr_Y1_Cb_Y0_REP: + return kHostFormatGBGRUnaligned; + case xenos::TextureFormat::k_Y1_Cr_Y0_Cb_REP: + return kHostFormatBGRGUnaligned; + case xenos::TextureFormat::k_DXT1: + case xenos::TextureFormat::k_DXT1_AS_16_16_16_16: + return kHostFormatDXT1Unaligned; + case xenos::TextureFormat::k_DXT2_3: + case xenos::TextureFormat::k_DXT2_3_AS_16_16_16_16: + return kHostFormatDXT2_3Unaligned; + case xenos::TextureFormat::k_DXT4_5: + case xenos::TextureFormat::k_DXT4_5_AS_16_16_16_16: + return kHostFormatDXT4_5Unaligned; + case xenos::TextureFormat::k_DXN: + return kHostFormatDXNUnaligned; + case xenos::TextureFormat::k_DXT5A: + return kHostFormatDXT5AUnaligned; + default: + return host_format_pair; + } +} + +void VulkanTextureCache::GetTextureUsageMasks(VulkanTexture::Usage usage, + VkPipelineStageFlags& stage_mask, + VkAccessFlags& access_mask, VkImageLayout& layout) { + stage_mask = 0; + access_mask = 0; + layout = VK_IMAGE_LAYOUT_UNDEFINED; + switch (usage) { + case VulkanTexture::Usage::kUndefined: + break; + case VulkanTexture::Usage::kTransferDestination: + stage_mask = VK_PIPELINE_STAGE_TRANSFER_BIT; + access_mask = VK_ACCESS_TRANSFER_WRITE_BIT; + layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + break; + case VulkanTexture::Usage::kGuestShaderSampled: + stage_mask = guest_shader_pipeline_stages_; + access_mask = VK_ACCESS_SHADER_READ_BIT; + layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + break; + case VulkanTexture::Usage::kSwapSampled: + // The swap texture is likely to be used only for the presentation + // post-processing passes, and not during emulation where it'd be used in + // other stages. + stage_mask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + access_mask = VK_ACCESS_SHADER_READ_BIT; + layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + break; + } +} + +xenos::ClampMode VulkanTextureCache::NormalizeClampMode(xenos::ClampMode clamp_mode) const { + if (clamp_mode == xenos::ClampMode::kClampToHalfway) { + // No GL_CLAMP (clamp to half edge, half border) equivalent in Vulkan, but + // there's no Direct3D 9 equivalent anyway, and too weird to be suitable for + // intentional real usage. + return xenos::ClampMode::kClampToEdge; + } + if (clamp_mode == xenos::ClampMode::kMirrorClampToEdge || + clamp_mode == xenos::ClampMode::kMirrorClampToHalfway || + clamp_mode == xenos::ClampMode::kMirrorClampToBorder) { + // No equivalents for anything other than kMirrorClampToEdge in Vulkan. + return command_processor_.GetVulkanDevice()->properties().samplerMirrorClampToEdge + ? xenos::ClampMode::kMirrorClampToEdge + : xenos::ClampMode::kMirroredRepeat; + } + return clamp_mode; +} + +} // namespace rex::graphics::vulkan diff --git a/src/graphics/xenos.cpp b/src/graphics/xenos.cpp new file mode 100644 index 0000000..4140de7 --- /dev/null +++ b/src/graphics/xenos.cpp @@ -0,0 +1,214 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include + +namespace rex::graphics { +namespace xenos { + +// Based on X360GammaToLinear and X360LinearToGamma from the Source Engine, with +// additional logic from Direct3D 9 code in game executable disassembly, located +// via the floating-point constants involved. +// https://github.com/ValveSoftware/source-sdk-2013/blob/master/mp/src/mathlib/color_conversion.cpp#L329 +// These are provided here in part as a reference for shader translators. + +float PWLGammaToLinear(float gamma) { + // Not found in game executables, so just using the logic similar to that in + // the Source Engine. + gamma = rex::saturate(gamma); + float scale, offset; + // While the compiled code for linear to gamma conversion uses `vcmpgtfp + // constant, value` comparison (constant > value, or value < constant), it's + // preferable to use `value >= constant` condition for the higher pieces, as + // it will never pass for NaN, and in case of NaN, the 0...64/255 case will be + // selected regardless of whether it's saturated before or after the + // comparisons (always pre-saturating here, but shader translators may choose + // to saturate later for convenience), as saturation will flush NaN to 0. + if (gamma >= 96.0f / 255.0f) { + if (gamma >= 192.0f / 255.0f) { + scale = 8.0f / 1024.0f; + offset = -1024.0f; + } else { + scale = 4.0f / 1024.0f; + offset = -256.0f; + } + } else { + if (gamma >= 64.0f / 255.0f) { + scale = 2.0f / 1024.0f; + offset = -64.0f; + } else { + scale = 1.0f / 1024.0f; + offset = 0.0f; + // No `floor` term in this case in the Source Engine, but for the largest + // value, 1.0, `floor(255.0f * (1.0f / 1024.0f))` is 0 anyway. + } + } + // Though in the Source Engine, the 1/1024 multiplication is done for the + // truncated part specifically, pre-baking it into the scale is lossless - + // both 1024 and `scale` are powers of 2. + float linear = gamma * ((255.0f * 1024.0f) * scale) + offset; + // For consistency with linear to gamma, and because it's more logical here + // (0 rather than 1 at -epsilon), using `trunc` instead of `floor`. + linear += std::trunc(linear * scale); + linear *= 1.0f / 1023.0f; + // Clamping is not necessary (1 * (255 * 8) - 1024 + 7 is exactly 1023). + return linear; +} + +float LinearToPWLGamma(float linear) { + linear = rex::saturate(linear); + float scale, offset; + // While the compiled code uses `vcmpgtfp constant, value` comparison + // (constant > value, or value < constant), it's preferable to use `value >= + // constant` condition for the higher pieces, as it will never pass for NaN, + // and in case of NaN, the 0...64/1023 case will be selected regardless of + // whether it's saturated before or after the comparisons (always + // pre-saturating here, but shader translators may choose to saturate later + // for convenience), as saturation will flush NaN to 0. + if (linear >= 128.0f / 1023.0f) { + if (linear >= 512.0f / 1023.0f) { + scale = 1023.0f / 8.0f; + offset = 128.0f / 255.0f; + } else { + scale = 1023.0f / 4.0f; + offset = 64.0f / 255.0f; + } + } else { + if (linear >= 64.0f / 1023.0f) { + scale = 1023.0f / 2.0f; + offset = 32.0f / 255.0f; + } else { + scale = 1023.0f; + offset = 0.0f; + } + } + // The truncation isn't in X360LinearToGamma in the Source Engine, but is + // there in Direct3D 9 disassembly (the `vrfiz` instructions). + // It also prevents conversion of 1.0 to 1.0034313725490196078431372549016 + // that's handled via clamping in the Source Engine. + // 127.875 (1023 / 8) is truncated to 127, which, after scaling, becomes + // 127 / 255, and when 128 / 255 is added, the result is 1. + return std::trunc(linear * scale) * (1.0f / 255.0f) + offset; +} + +// https://github.com/Microsoft/DirectXTex/blob/master/DirectXTex/DirectXTexConvert.cpp + +float Float7e3To32(uint32_t f10) { + f10 &= 0x3FF; + if (!f10) { + return 0.0f; + } + uint32_t mantissa = f10 & 0x7F; + uint32_t exponent = f10 >> 7; + if (!exponent) { + // Normalize the value in the resulting float. + // do { Exponent--; Mantissa <<= 1; } while ((Mantissa & 0x80) == 0) + uint32_t mantissa_lzcnt = rex::lzcnt(mantissa) - (32 - 8); + exponent = uint32_t(1 - int32_t(mantissa_lzcnt)); + mantissa = (mantissa << mantissa_lzcnt) & 0x7F; + } + return rex::memory::Reinterpret(uint32_t(((exponent + 124) << 23) | (mantissa << 3))); +} + +// Based on CFloat24 from d3dref9.dll and the 6e4 code from: +// https://github.com/Microsoft/DirectXTex/blob/master/DirectXTex/DirectXTexConvert.cpp +// 6e4 has a different exponent bias allowing [0,512) values, 20e4 allows [0,2). + +uint32_t Float32To20e4(float f32, bool round_to_nearest_even) { + if (!(f32 > 0.0f)) { + // Positive only, and not -0 or NaN. + return 0; + } + auto f32u32 = rex::memory::Reinterpret(f32); + if (f32u32 >= 0x3FFFFFF8) { + // Saturate. + return 0xFFFFFF; + } + if (f32u32 < 0x38800000) { + // The number is too small to be represented as a normalized 20e4. + // Convert it to a denormalized value. + uint32_t shift = std::min(uint32_t(113 - (f32u32 >> 23)), uint32_t(24)); + f32u32 = (0x800000 | (f32u32 & 0x7FFFFF)) >> shift; + } else { + // Rebias the exponent to represent the value as a normalized 20e4. + f32u32 += 0xC8000000u; + } + if (round_to_nearest_even) { + f32u32 += 3 + ((f32u32 >> 3) & 1); + } + return (f32u32 >> 3) & 0xFFFFFF; +} + +float Float20e4To32(uint32_t f24) { + f24 &= 0xFFFFFF; + if (!f24) { + return 0.0f; + } + uint32_t mantissa = f24 & 0xFFFFF; + uint32_t exponent = f24 >> 20; + if (!exponent) { + // Normalize the value in the resulting float. + // do { Exponent--; Mantissa <<= 1; } while ((Mantissa & 0x100000) == 0) + uint32_t mantissa_lzcnt = rex::lzcnt(mantissa) - (32 - 21); + exponent = uint32_t(1 - int32_t(mantissa_lzcnt)); + mantissa = (mantissa << mantissa_lzcnt) & 0xFFFFF; + } + return rex::memory::Reinterpret(uint32_t(((exponent + 112) << 23) | (mantissa << 3))); +} + +const char* GetColorRenderTargetFormatName(ColorRenderTargetFormat format) { + switch (format) { + case ColorRenderTargetFormat::k_8_8_8_8: + return "k_8_8_8_8"; + case ColorRenderTargetFormat::k_8_8_8_8_GAMMA: + return "k_8_8_8_8_GAMMA"; + case ColorRenderTargetFormat::k_2_10_10_10: + return "k_2_10_10_10"; + case ColorRenderTargetFormat::k_2_10_10_10_FLOAT: + return "k_2_10_10_10_FLOAT"; + case ColorRenderTargetFormat::k_16_16: + return "k_16_16"; + case ColorRenderTargetFormat::k_16_16_16_16: + return "k_16_16_16_16"; + case ColorRenderTargetFormat::k_16_16_FLOAT: + return "k_16_16_FLOAT"; + case ColorRenderTargetFormat::k_16_16_16_16_FLOAT: + return "k_16_16_16_16_FLOAT"; + case ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: + return "k_2_10_10_10_AS_10_10_10_10"; + case ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16: + return "k_2_10_10_10_FLOAT_AS_16_16_16_16"; + case ColorRenderTargetFormat::k_32_FLOAT: + return "k_32_FLOAT"; + case ColorRenderTargetFormat::k_32_32_FLOAT: + return "k_32_32_FLOAT"; + default: + return "kUnknown"; + } +} + +const char* GetDepthRenderTargetFormatName(DepthRenderTargetFormat format) { + switch (format) { + case DepthRenderTargetFormat::kD24S8: + return "kD24S8"; + case DepthRenderTargetFormat::kD24FS8: + return "kD24FS8"; + default: + return "kUnknown"; + } +} + +} // namespace xenos +} // namespace rex::graphics diff --git a/src/input/CMakeLists.txt b/src/input/CMakeLists.txt new file mode 100644 index 0000000..698967d --- /dev/null +++ b/src/input/CMakeLists.txt @@ -0,0 +1,21 @@ +# rexinput - Input system library +# Input system and drivers for Xbox 360 controller emulation + +add_library(rexinput OBJECT + input_system.cpp + mnk/mnk_input_driver.cpp + nop/nop_input_driver.cpp +) +add_library(rex::input ALIAS rexinput) + +target_include_directories(rexinput PUBLIC + $ + $ +) +if(WIN32) + target_sources(rexinput PRIVATE sdl/sdl_input_driver.cpp xinput/xinput_input_driver.cpp) +else() + target_sources(rexinput PRIVATE sdl/sdl_input_driver.cpp) +endif() + +target_link_libraries(rexinput PUBLIC rexcore rexui SDL3::SDL3) diff --git a/src/input/input_system.cpp b/src/input/input_system.cpp new file mode 100644 index 0000000..e132acb --- /dev/null +++ b/src/input/input_system.cpp @@ -0,0 +1,195 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_STRING(input_backend, "sdl", "Input", "Input backend: sdl, xinput") + .allowed({"sdl", "xinput"}); + +REXCVAR_DEFINE_BOOL(guide_button, false, "Input", "Enable guide button pass-through"); +namespace rex::input { + +InputSystem::InputSystem(rex::ui::Window* window) : window_(window) {} + +InputSystem::~InputSystem() = default; + +X_STATUS InputSystem::Setup() { + return X_STATUS_SUCCESS; +} + +void InputSystem::Shutdown() { + drivers_.clear(); +} + +void InputSystem::AddDriver(std::unique_ptr driver) { + drivers_.push_back(std::move(driver)); +} + +void InputSystem::AttachWindow(rex::ui::Window* window) { + window_ = window; + for (auto& driver : drivers_) { + driver->OnWindowAvailable(window); + } +} + +void InputSystem::SetActiveCallback(std::function callback) { + for (auto& driver : drivers_) { + driver->set_is_active_callback(callback); + } +} + +X_RESULT InputSystem::GetCapabilities(uint32_t user_index, uint32_t flags, + X_INPUT_CAPABILITIES* out_caps) { + SCOPE_profile_cpu_f("hid"); + + bool any_connected = false; + for (auto& driver : drivers_) { + X_RESULT result = driver->GetCapabilities(user_index, flags, out_caps); + if (result != X_ERROR_DEVICE_NOT_CONNECTED) { + any_connected = true; + } + if (result == X_ERROR_SUCCESS) { + return result; + } + } + return any_connected ? X_ERROR_EMPTY : X_ERROR_DEVICE_NOT_CONNECTED; +} + +X_RESULT InputSystem::GetState(uint32_t user_index, X_INPUT_STATE* out_state) { + SCOPE_profile_cpu_f("hid"); + + bool any_connected = false; + bool first_result = true; + X_INPUT_STATE merged = {}; + + for (auto& driver : drivers_) { + X_INPUT_STATE state = {}; + X_RESULT result = driver->GetState(user_index, &state); + if (result != X_ERROR_DEVICE_NOT_CONNECTED) { + any_connected = true; + } + if (result == X_ERROR_SUCCESS) { + if (first_result) { + merged = state; + first_result = false; + } else { + // Merge: OR buttons, max triggers, max-magnitude sticks + merged.gamepad.buttons = static_cast(merged.gamepad.buttons) | + static_cast(state.gamepad.buttons); + merged.gamepad.left_trigger = + std::max(merged.gamepad.left_trigger, state.gamepad.left_trigger); + merged.gamepad.right_trigger = + std::max(merged.gamepad.right_trigger, state.gamepad.right_trigger); + + auto merge_axis = [](int16_t a, int16_t b) -> int16_t { + return (std::abs(static_cast(a)) >= std::abs(static_cast(b))) ? a : b; + }; + merged.gamepad.thumb_lx = merge_axis(merged.gamepad.thumb_lx, state.gamepad.thumb_lx); + merged.gamepad.thumb_ly = merge_axis(merged.gamepad.thumb_ly, state.gamepad.thumb_ly); + merged.gamepad.thumb_rx = merge_axis(merged.gamepad.thumb_rx, state.gamepad.thumb_rx); + merged.gamepad.thumb_ry = merge_axis(merged.gamepad.thumb_ry, state.gamepad.thumb_ry); + + if (static_cast(state.packet_number) > + static_cast(merged.packet_number)) { + merged.packet_number = state.packet_number; + } + } + } + } + + if (first_result) { + return any_connected ? X_ERROR_EMPTY : X_ERROR_DEVICE_NOT_CONNECTED; + } + + if (out_state) { + *out_state = merged; + } + return X_ERROR_SUCCESS; +} + +X_RESULT InputSystem::SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration) { + SCOPE_profile_cpu_f("hid"); + + bool any_connected = false; + for (auto& driver : drivers_) { + X_RESULT result = driver->SetState(user_index, vibration); + if (result != X_ERROR_DEVICE_NOT_CONNECTED) { + any_connected = true; + } + if (result == X_ERROR_SUCCESS) { + return result; + } + } + return any_connected ? X_ERROR_EMPTY : X_ERROR_DEVICE_NOT_CONNECTED; +} + +X_RESULT InputSystem::GetKeystroke(uint32_t user_index, uint32_t flags, + X_INPUT_KEYSTROKE* out_keystroke) { + SCOPE_profile_cpu_f("hid"); + + bool any_connected = false; + for (auto& driver : drivers_) { + X_RESULT result = driver->GetKeystroke(user_index, flags, out_keystroke); + if (result != X_ERROR_DEVICE_NOT_CONNECTED) { + any_connected = true; + } + if (result == X_ERROR_SUCCESS || result == X_ERROR_EMPTY) { + return result; + } + } + return any_connected ? X_ERROR_EMPTY : X_ERROR_DEVICE_NOT_CONNECTED; +} + +std::unique_ptr CreateDefaultInputSystem(bool tool_mode) { + auto input = std::make_unique(nullptr); + + if (!tool_mode) { +#if REX_PLATFORM_WIN32 + if (REXCVAR_GET(input_backend) == "xinput") { + auto xinput_driver = std::make_unique(nullptr, 0); + if (xinput_driver->Setup() == X_STATUS_SUCCESS) { + input->AddDriver(std::move(xinput_driver)); + } + } +#endif + + if (REXCVAR_GET(input_backend) == "sdl") { + auto sdl_driver = std::make_unique(nullptr, 0); + if (sdl_driver->Setup() == X_STATUS_SUCCESS) { + input->AddDriver(std::move(sdl_driver)); + } + } + + // MnK driver (keyboard/mouse -> controller emulation) + auto mnk_driver = std::make_unique(nullptr, 0); + if (mnk_driver->Setup() == X_STATUS_SUCCESS) { + input->AddDriver(std::move(mnk_driver)); + } + } + + // NOP driver (primary in tool mode, fallback otherwise) + uint8_t nop_index = tool_mode ? 0 : 1; + input->AddDriver(std::make_unique(nullptr, nop_index)); + return input; +} + +} // namespace rex::input diff --git a/src/input/mnk/mnk_input_driver.cpp b/src/input/mnk/mnk_input_driver.cpp new file mode 100644 index 0000000..b8eae3c --- /dev/null +++ b/src/input/mnk/mnk_input_driver.cpp @@ -0,0 +1,392 @@ +/** + * @file input/mnk/mnk_input_driver.cpp + * @brief Keyboard/mouse input driver implementation. + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if REX_PLATFORM_WIN32 +#include +#include +#endif + +REXCVAR_DEFINE_BOOL(mnk_mode, false, "Input", "Enable keyboard/mouse controller emulation"); +REXCVAR_DEFINE_INT32(mnk_user_index, 0, "Input", "Controller slot (0-3) for MnK").range(0, 3); +REXCVAR_DEFINE_DOUBLE(mnk_sensitivity, 1.0, "Input", "Mouse sensitivity for right stick") + .range(0.01, 10.0); + +REXCVAR_DEFINE_STRING(keybind_a, "Space", "Input/Keybinds/Controller", "A button"); +REXCVAR_DEFINE_STRING(keybind_b, "Shift", "Input/Keybinds/Controller", "B button"); +REXCVAR_DEFINE_STRING(keybind_x, "R", "Input/Keybinds/Controller", "X button"); +REXCVAR_DEFINE_STRING(keybind_y, "E", "Input/Keybinds/Controller", "Y button"); +REXCVAR_DEFINE_STRING(keybind_left_trigger, "RMB", "Input/Keybinds/Controller", "Left trigger"); +REXCVAR_DEFINE_STRING(keybind_right_trigger, "LMB", "Input/Keybinds/Controller", "Right trigger"); +REXCVAR_DEFINE_STRING(keybind_left_shoulder, "Q", "Input/Keybinds/Controller", "Left shoulder"); +REXCVAR_DEFINE_STRING(keybind_right_shoulder, "F", "Input/Keybinds/Controller", "Right shoulder"); +REXCVAR_DEFINE_STRING(keybind_lstick_up, "W", "Input/Keybinds/Controller", "Left stick up"); +REXCVAR_DEFINE_STRING(keybind_lstick_down, "S", "Input/Keybinds/Controller", "Left stick down"); +REXCVAR_DEFINE_STRING(keybind_lstick_left, "A", "Input/Keybinds/Controller", "Left stick left"); +REXCVAR_DEFINE_STRING(keybind_lstick_right, "D", "Input/Keybinds/Controller", "Left stick right"); +REXCVAR_DEFINE_STRING(keybind_lstick_press, "C", "Input/Keybinds/Controller", "Left stick press"); +REXCVAR_DEFINE_STRING(keybind_rstick_press, "MMB", "Input/Keybinds/Controller", + "Right stick press"); +REXCVAR_DEFINE_STRING(keybind_dpad_up, "Up", "Input/Keybinds/Controller", "D-pad up"); +REXCVAR_DEFINE_STRING(keybind_dpad_down, "Down", "Input/Keybinds/Controller", "D-pad down"); +REXCVAR_DEFINE_STRING(keybind_dpad_left, "Left", "Input/Keybinds/Controller", "D-pad left"); +REXCVAR_DEFINE_STRING(keybind_dpad_right, "Right", "Input/Keybinds/Controller", "D-pad right"); +REXCVAR_DEFINE_STRING(keybind_back, "Tab", "Input/Keybinds/Controller", "Back button"); +REXCVAR_DEFINE_STRING(keybind_start, "Escape", "Input/Keybinds/Controller", "Start button"); +REXCVAR_DEFINE_STRING(keybind_guide, "", "Input/Keybinds/Controller", "Guide button"); + +namespace rex::input::mnk { + +using rex::ui::VirtualKey; + +MnkInputDriver::MnkInputDriver(rex::ui::Window* window, size_t window_z_order) + : InputDriver(window, window_z_order) {} + +MnkInputDriver::~MnkInputDriver() { + // Detach handled by OnClosing; if window outlives the driver, clean up here. + if (attached_window_) { + attached_window_->RemoveInputListener(this); + attached_window_->RemoveListener(this); + attached_window_ = nullptr; + } +} + +X_STATUS MnkInputDriver::Setup() { + REXLOG_INFO("MnK input driver initialized"); + return X_STATUS_SUCCESS; +} + +void MnkInputDriver::OnWindowAvailable(rex::ui::Window* window) { + if (window) { + attached_window_ = window; + window->AddInputListener(this, window_z_order()); + window->AddListener(this); + } +} + +void MnkInputDriver::OnClosing(rex::ui::UIEvent&) { + if (attached_window_) { + if (mouse_captured_) { + mouse_captured_ = false; + attached_window_->SetCursorVisibility(rex::ui::Window::CursorVisibility::kVisible); + attached_window_->ReleaseMouse(); + } + attached_window_->RemoveInputListener(this); + attached_window_->RemoveListener(this); + attached_window_ = nullptr; + } +} + +uint32_t MnkInputDriver::UserIndex() const { + return static_cast(REXCVAR_GET(mnk_user_index)); +} + +bool MnkInputDriver::IsEnabled() const { + return REXCVAR_GET(mnk_mode); +} + +static bool IsBindPressed(const bool (&key_down)[256], const std::string& cvar_val) { + VirtualKey vk = rex::ui::ParseVirtualKey(cvar_val); + if (vk == VirtualKey::kNone) + return false; + uint16_t idx = static_cast(vk); + return idx < 256 && key_down[idx]; +} + +X_RESULT MnkInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags, + X_INPUT_CAPABILITIES* out_caps) { + if (!IsEnabled() || user_index != UserIndex()) { + return X_ERROR_DEVICE_NOT_CONNECTED; + } + if (out_caps) { + std::memset(out_caps, 0, sizeof(*out_caps)); + out_caps->type = 0x01; + out_caps->sub_type = 0x01; + out_caps->flags = 0; + out_caps->gamepad.buttons = 0xFFFF; + out_caps->gamepad.left_trigger = 0xFF; + out_caps->gamepad.right_trigger = 0xFF; + out_caps->gamepad.thumb_lx = static_cast(0x7FFF); + out_caps->gamepad.thumb_ly = static_cast(0x7FFF); + out_caps->gamepad.thumb_rx = static_cast(0x7FFF); + out_caps->gamepad.thumb_ry = static_cast(0x7FFF); + out_caps->vibration.left_motor_speed = 0xFFFF; + out_caps->vibration.right_motor_speed = 0xFFFF; + } + return X_ERROR_SUCCESS; +} + +X_RESULT MnkInputDriver::GetState(uint32_t user_index, X_INPUT_STATE* out_state) { + if (!IsEnabled() || user_index != UserIndex()) { + return X_ERROR_DEVICE_NOT_CONNECTED; + } + + UpdateMouseCapture(); + + if (!is_active() || !has_focus_) { + if (out_state) { + std::memset(out_state, 0, sizeof(*out_state)); + out_state->packet_number = packet_number_; + } + return X_ERROR_SUCCESS; + } + + std::lock_guard lock(state_mutex_); + + uint16_t buttons = 0; + if (IsBindPressed(key_down_, REXCVAR_GET(keybind_a))) + buttons |= X_INPUT_GAMEPAD_A; + if (IsBindPressed(key_down_, REXCVAR_GET(keybind_b))) + buttons |= X_INPUT_GAMEPAD_B; + if (IsBindPressed(key_down_, REXCVAR_GET(keybind_x))) + buttons |= X_INPUT_GAMEPAD_X; + if (IsBindPressed(key_down_, REXCVAR_GET(keybind_y))) + buttons |= X_INPUT_GAMEPAD_Y; + if (IsBindPressed(key_down_, REXCVAR_GET(keybind_left_shoulder))) + buttons |= X_INPUT_GAMEPAD_LEFT_SHOULDER; + if (IsBindPressed(key_down_, REXCVAR_GET(keybind_right_shoulder))) + buttons |= X_INPUT_GAMEPAD_RIGHT_SHOULDER; + if (IsBindPressed(key_down_, REXCVAR_GET(keybind_lstick_press))) + buttons |= X_INPUT_GAMEPAD_LEFT_THUMB; + if (IsBindPressed(key_down_, REXCVAR_GET(keybind_rstick_press))) + buttons |= X_INPUT_GAMEPAD_RIGHT_THUMB; + if (IsBindPressed(key_down_, REXCVAR_GET(keybind_back))) + buttons |= X_INPUT_GAMEPAD_BACK; + if (IsBindPressed(key_down_, REXCVAR_GET(keybind_start))) + buttons |= X_INPUT_GAMEPAD_START; + if (IsBindPressed(key_down_, REXCVAR_GET(keybind_guide))) + buttons |= X_INPUT_GAMEPAD_GUIDE; + if (IsBindPressed(key_down_, REXCVAR_GET(keybind_dpad_up))) + buttons |= X_INPUT_GAMEPAD_DPAD_UP; + if (IsBindPressed(key_down_, REXCVAR_GET(keybind_dpad_down))) + buttons |= X_INPUT_GAMEPAD_DPAD_DOWN; + if (IsBindPressed(key_down_, REXCVAR_GET(keybind_dpad_left))) + buttons |= X_INPUT_GAMEPAD_DPAD_LEFT; + if (IsBindPressed(key_down_, REXCVAR_GET(keybind_dpad_right))) + buttons |= X_INPUT_GAMEPAD_DPAD_RIGHT; + + uint8_t lt = IsBindPressed(key_down_, REXCVAR_GET(keybind_left_trigger)) ? 0xFF : 0; + uint8_t rt = IsBindPressed(key_down_, REXCVAR_GET(keybind_right_trigger)) ? 0xFF : 0; + + int32_t lx = 0; + int32_t ly = 0; + if (IsBindPressed(key_down_, REXCVAR_GET(keybind_lstick_left))) + lx -= INT16_MAX; + if (IsBindPressed(key_down_, REXCVAR_GET(keybind_lstick_right))) + lx += INT16_MAX; + if (IsBindPressed(key_down_, REXCVAR_GET(keybind_lstick_up))) + ly += INT16_MAX; + if (IsBindPressed(key_down_, REXCVAR_GET(keybind_lstick_down))) + ly -= INT16_MAX; + + double sensitivity = REXCVAR_GET(mnk_sensitivity); + constexpr double kBaseScale = 200.0; + int32_t rx = static_cast(mouse_dx_ * sensitivity * kBaseScale); + int32_t ry = static_cast(-mouse_dy_ * sensitivity * kBaseScale); + mouse_dx_ = 0; + mouse_dy_ = 0; + + auto clamp16 = [](int32_t v) -> int16_t { + return static_cast(std::clamp(v, (int32_t)INT16_MIN, (int32_t)INT16_MAX)); + }; + + packet_number_++; + + if (out_state) { + out_state->packet_number = packet_number_; + out_state->gamepad.buttons = buttons; + out_state->gamepad.left_trigger = lt; + out_state->gamepad.right_trigger = rt; + out_state->gamepad.thumb_lx = clamp16(lx); + out_state->gamepad.thumb_ly = clamp16(ly); + out_state->gamepad.thumb_rx = clamp16(rx); + out_state->gamepad.thumb_ry = clamp16(ry); + } + return X_ERROR_SUCCESS; +} + +X_RESULT MnkInputDriver::SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration) { + if (!IsEnabled() || user_index != UserIndex()) { + return X_ERROR_DEVICE_NOT_CONNECTED; + } + return X_ERROR_SUCCESS; +} + +X_RESULT MnkInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags, + X_INPUT_KEYSTROKE* out_keystroke) { + if (!IsEnabled() || user_index != UserIndex()) { + return X_ERROR_DEVICE_NOT_CONNECTED; + } + std::lock_guard lock(state_mutex_); + if (keystroke_queue_.empty()) { + return X_ERROR_EMPTY; + } + if (out_keystroke) { + *out_keystroke = keystroke_queue_.front(); + } + keystroke_queue_.pop(); + return X_ERROR_SUCCESS; +} + +void MnkInputDriver::EnqueueKeystroke(uint16_t vk_pad, bool down) { + X_INPUT_KEYSTROKE ks = {}; + ks.virtual_key = vk_pad; + ks.unicode = 0; + ks.flags = down ? X_INPUT_KEYSTROKE_KEYDOWN : X_INPUT_KEYSTROKE_KEYUP; + ks.user_index = static_cast(UserIndex()); + ks.hid_code = 0; + keystroke_queue_.push(ks); +} + +void MnkInputDriver::CenterCursor() { + if (!attached_window_) + return; + int32_t cx = static_cast(attached_window_->GetActualLogicalWidth() / 2); + int32_t cy = static_cast(attached_window_->GetActualLogicalHeight() / 2); + prev_mouse_x_ = cx; + prev_mouse_y_ = cy; +#if REX_PLATFORM_WIN32 + auto* win32_window = dynamic_cast(attached_window_); + if (win32_window && win32_window->hwnd()) { + POINT pt = {static_cast(cx), static_cast(cy)}; + ClientToScreen(win32_window->hwnd(), &pt); + SetCursorPos(pt.x, pt.y); + } +#endif +} + +void MnkInputDriver::UpdateMouseCapture() { + if (!attached_window_) + return; + + bool should_capture = IsEnabled() && has_focus_ && is_active(); + + if (should_capture && !mouse_captured_) { + mouse_captured_ = true; + attached_window_->SetCursorVisibility(rex::ui::Window::CursorVisibility::kHidden); + attached_window_->CaptureMouse(); + // Reset deltas to avoid a spike on capture start + mouse_dx_ = 0; + mouse_dy_ = 0; + } else if (!should_capture && mouse_captured_) { + mouse_captured_ = false; + attached_window_->SetCursorVisibility(rex::ui::Window::CursorVisibility::kVisible); + attached_window_->ReleaseMouse(); + } + + // Re-center cursor each frame while captured to prevent edge clamping + if (mouse_captured_) { + CenterCursor(); + } +} + +void MnkInputDriver::SetKeyState(uint16_t vk, bool down) { + if (vk < 256) { + key_down_[vk] = down; + } +} + +void MnkInputDriver::OnKeyDown(rex::ui::KeyEvent& e) { + if (!IsEnabled() || !has_focus_) + return; + std::lock_guard lock(state_mutex_); + uint16_t vk = static_cast(e.virtual_key()); + SetKeyState(vk, true); +} + +void MnkInputDriver::OnKeyUp(rex::ui::KeyEvent& e) { + if (!IsEnabled()) + return; + std::lock_guard lock(state_mutex_); + uint16_t vk = static_cast(e.virtual_key()); + SetKeyState(vk, false); +} + +void MnkInputDriver::OnMouseDown(rex::ui::MouseEvent& e) { + if (!IsEnabled() || !has_focus_) + return; + std::lock_guard lock(state_mutex_); + switch (e.button()) { + case rex::ui::MouseEvent::Button::kLeft: + SetKeyState(static_cast(VirtualKey::kLButton), true); + break; + case rex::ui::MouseEvent::Button::kRight: + SetKeyState(static_cast(VirtualKey::kRButton), true); + break; + case rex::ui::MouseEvent::Button::kMiddle: + SetKeyState(static_cast(VirtualKey::kMButton), true); + break; + default: + break; + } +} + +void MnkInputDriver::OnMouseUp(rex::ui::MouseEvent& e) { + if (!IsEnabled()) + return; + std::lock_guard lock(state_mutex_); + switch (e.button()) { + case rex::ui::MouseEvent::Button::kLeft: + SetKeyState(static_cast(VirtualKey::kLButton), false); + break; + case rex::ui::MouseEvent::Button::kRight: + SetKeyState(static_cast(VirtualKey::kRButton), false); + break; + case rex::ui::MouseEvent::Button::kMiddle: + SetKeyState(static_cast(VirtualKey::kMButton), false); + break; + default: + break; + } +} + +void MnkInputDriver::OnMouseMove(rex::ui::MouseEvent& e) { + if (!IsEnabled() || !has_focus_) + return; + std::lock_guard lock(state_mutex_); + int32_t x = e.x(); + int32_t y = e.y(); + mouse_dx_ += x - prev_mouse_x_; + mouse_dy_ += y - prev_mouse_y_; + prev_mouse_x_ = x; + prev_mouse_y_ = y; +} + +void MnkInputDriver::OnLostFocus(rex::ui::UISetupEvent&) { + std::lock_guard lock(state_mutex_); + has_focus_ = false; + std::memset(key_down_, 0, sizeof(key_down_)); + mouse_dx_ = 0; + mouse_dy_ = 0; + if (mouse_captured_ && attached_window_) { + mouse_captured_ = false; + attached_window_->SetCursorVisibility(rex::ui::Window::CursorVisibility::kVisible); + attached_window_->ReleaseMouse(); + } +} + +void MnkInputDriver::OnGotFocus(rex::ui::UISetupEvent&) { + std::lock_guard lock(state_mutex_); + has_focus_ = true; +} + +} // namespace rex::input::mnk diff --git a/src/input/nop/nop_input_driver.cpp b/src/input/nop/nop_input_driver.cpp new file mode 100644 index 0000000..cdc0ca7 --- /dev/null +++ b/src/input/nop/nop_input_driver.cpp @@ -0,0 +1,84 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include + +namespace rex::input::nop { + +NopInputDriver::NopInputDriver(rex::ui::Window* window, size_t window_z_order) + : InputDriver(window, window_z_order) {} + +NopInputDriver::~NopInputDriver() = default; + +X_STATUS NopInputDriver::Setup() { + return X_STATUS_SUCCESS; +} + +// Spoof a connected controller for user 0 so games don't pause +// waiting for input. Returns idle state (no buttons pressed). + +X_RESULT NopInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags, + X_INPUT_CAPABILITIES* out_caps) { + if (user_index != 0) { + return X_ERROR_DEVICE_NOT_CONNECTED; + } + if (out_caps) { + std::memset(out_caps, 0, sizeof(*out_caps)); + out_caps->type = 0x01; // XINPUT_DEVTYPE_GAMEPAD + out_caps->sub_type = 0x01; // XINPUT_DEVSUBTYPE_GAMEPAD + out_caps->flags = 0; + // Report standard gamepad capabilities + out_caps->gamepad.buttons = 0xFFFF; // All buttons supported + out_caps->gamepad.left_trigger = 0xFF; + out_caps->gamepad.right_trigger = 0xFF; + out_caps->gamepad.thumb_lx = static_cast(0x7FFF); + out_caps->gamepad.thumb_ly = static_cast(0x7FFF); + out_caps->gamepad.thumb_rx = static_cast(0x7FFF); + out_caps->gamepad.thumb_ry = static_cast(0x7FFF); + out_caps->vibration.left_motor_speed = 0xFFFF; + out_caps->vibration.right_motor_speed = 0xFFFF; + } + return X_ERROR_SUCCESS; +} + +X_RESULT NopInputDriver::GetState(uint32_t user_index, X_INPUT_STATE* out_state) { + if (user_index != 0) { + return X_ERROR_DEVICE_NOT_CONNECTED; + } + if (out_state) { + std::memset(out_state, 0, sizeof(*out_state)); + // Return idle controller state (no buttons pressed) + } + return X_ERROR_SUCCESS; +} + +X_RESULT NopInputDriver::SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration) { + if (user_index != 0) { + return X_ERROR_DEVICE_NOT_CONNECTED; + } + // Accept vibration but do nothing + return X_ERROR_SUCCESS; +} + +X_RESULT NopInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags, + X_INPUT_KEYSTROKE* out_keystroke) { + if (user_index != 0) { + return X_ERROR_DEVICE_NOT_CONNECTED; + } + // No keystrokes available + return X_ERROR_EMPTY; +} + +} // namespace rex::input::nop diff --git a/src/input/sdl/sdl_input_driver.cpp b/src/input/sdl/sdl_input_driver.cpp new file mode 100644 index 0000000..bdef585 --- /dev/null +++ b/src/input/sdl/sdl_input_driver.cpp @@ -0,0 +1,725 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_STRING(hid_mappings_file, "gamecontrollerdb.txt", "Input", + "Path to SDL gamecontroller mappings file"); + +namespace rex::input::sdl { + +SDLInputDriver::SDLInputDriver(rex::ui::Window* window, size_t window_z_order) + : InputDriver(window, window_z_order), + sdl_events_initialized_(false), + SDL_Gamepad_initialized_(false), + sdl_events_unflushed_(0), + sdl_pumpevents_queued_(false), + controllers_(), + controllers_mutex_(), + keystroke_states_() {} + +SDLInputDriver::~SDLInputDriver() {} + +X_STATUS SDLInputDriver::Setup() { + if (!TestSDLVersion()) { + return X_STATUS_UNSUCCESSFUL; + } + + return X_STATUS_SUCCESS; +} + +void SDLInputDriver::OnWindowAvailable(rex::ui::Window* window) { + if (window && !attached_window_) { + attached_window_ = window; + window->AddListener(this); + window->app_context().CallInUIThreadSynchronous([this]() { + // Initialize SDL events subsystem + if (!SDL_InitSubSystem(SDL_INIT_EVENTS)) { + REXLOG_ERROR("SDL: Failed to init events subsystem: {}", SDL_GetError()); + return; + } + sdl_events_initialized_ = true; + pending_events_.reserve(64); + + // With an event watch we will always get notified, even if the event queue + // is full, which can happen if another subsystem does not clear its events. + SDL_AddEventWatch( + [](void* userdata, SDL_Event* event) -> bool { + if (!userdata || !event) { + assert_always(); + return false; + } + + const auto type = event->type; + if (type < SDL_EVENT_JOYSTICK_AXIS_MOTION || type >= SDL_EVENT_FINGER_DOWN) { + return false; + } + + // If another part of rex uses another SDL subsystem that generates + // events, this may seem like a bad idea. They will however not + // subscribe to controller events so we get away with that. + const auto driver = static_cast(userdata); + driver->HandleEvent(*event); + + return false; + }, + this); + + // Initialize game controller subsystem + if (!SDL_InitSubSystem(SDL_INIT_GAMEPAD)) { + REXLOG_ERROR("SDL: Failed to init gamecontroller subsystem: {}", SDL_GetError()); + return; + } + SDL_Gamepad_initialized_ = true; + + // Load custom controller mappings if available + if (!REXCVAR_GET(hid_mappings_file).empty()) { + std::filesystem::path mappings_path(REXCVAR_GET(hid_mappings_file)); + if (!std::filesystem::exists(mappings_path)) { + REXLOG_WARN("SDL GameControllerDB: file '{}' does not exist.", + REXCVAR_GET(hid_mappings_file)); + } else { + auto mappings_result = + SDL_AddGamepadMappingsFromFile(REXCVAR_GET(hid_mappings_file).c_str()); + if (mappings_result < 0) { + REXLOG_ERROR("SDL GameControllerDB: error loading file '{}': {}.", + REXCVAR_GET(hid_mappings_file), mappings_result); + } else { + REXLOG_INFO("SDL GameControllerDB: loaded {} mappings.", mappings_result); + } + } + } + REXLOG_INFO("SDL input driver initialized successfully"); + }); + } +} + +void SDLInputDriver::OnClosing(rex::ui::UIEvent&) { + if (attached_window_) { + attached_window_->RemoveListener(this); + if (sdl_pumpevents_queued_) { + attached_window_->app_context().CallInUIThreadSynchronous( + [this]() { attached_window_->app_context().ExecutePendingFunctionsFromUIThread(); }); + } + for (size_t i = 0; i < controllers_.size(); i++) { + if (controllers_.at(i).sdl) { + SDL_CloseGamepad(controllers_.at(i).sdl); + controllers_.at(i) = {}; + } + } + if (SDL_Gamepad_initialized_) { + SDL_QuitSubSystem(SDL_INIT_GAMEPAD); + SDL_Gamepad_initialized_ = false; + } + if (sdl_events_initialized_) { + SDL_QuitSubSystem(SDL_INIT_EVENTS); + sdl_events_initialized_ = false; + } + attached_window_ = nullptr; + } +} + +void SDLInputDriver::OnLostFocus(rex::ui::UISetupEvent&) {} + +void SDLInputDriver::OnGotFocus(rex::ui::UISetupEvent&) {} + +X_RESULT SDLInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags, + X_INPUT_CAPABILITIES* out_caps) { + assert(sdl_events_initialized_ && SDL_Gamepad_initialized_); + if (user_index >= HID_SDL_USER_COUNT || !out_caps) { + return X_ERROR_BAD_ARGUMENTS; + } + + QueueControllerUpdate(); + + auto guard = DrainAndLock(); + + auto controller = GetControllerState(user_index); + if (!controller) { + return X_ERROR_DEVICE_NOT_CONNECTED; + } + + // Unfortunately drivers can't present all information immediately (e.g. + // battery information) so this needs to be refreshed every time. + UpdateXCapabilities(*controller); + + std::memcpy(out_caps, &controller->caps, sizeof(*out_caps)); + + return X_ERROR_SUCCESS; +} + +X_RESULT SDLInputDriver::GetState(uint32_t user_index, X_INPUT_STATE* out_state) { + assert(sdl_events_initialized_ && SDL_Gamepad_initialized_); + if (user_index >= HID_SDL_USER_COUNT) { + return X_ERROR_BAD_ARGUMENTS; + } + + auto is_active = this->is_active(); + + if (is_active) { + QueueControllerUpdate(); + } + + auto guard = DrainAndLock(); + + auto controller = GetControllerState(user_index); + if (!controller) { + return X_ERROR_DEVICE_NOT_CONNECTED; + } + + // Make sure packet_number is only incremented by 1, even if there have been + // multiple updates between GetState calls. Also track `is_active` to + // increment the packet number if it changed. + if ((is_active != controller->is_active) || (is_active && controller->state_changed)) { + controller->state.packet_number++; + controller->is_active = is_active; + controller->state_changed = false; + } + std::memcpy(out_state, &controller->state, sizeof(*out_state)); + if (!is_active) { + // Simulate an "untouched" controller. When we become active again the + // pressed buttons aren't lost and will be visible again. + std::memset(&out_state->gamepad, 0, sizeof(out_state->gamepad)); + } + return X_ERROR_SUCCESS; +} + +X_RESULT SDLInputDriver::SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration) { + assert(sdl_events_initialized_ && SDL_Gamepad_initialized_); + if (user_index >= HID_SDL_USER_COUNT) { + return X_ERROR_BAD_ARGUMENTS; + } + + QueueControllerUpdate(); + + auto guard = DrainAndLock(); + + auto controller = GetControllerState(user_index); + if (!controller) { + return X_ERROR_DEVICE_NOT_CONNECTED; + } + +#if SDL_VERSION_ATLEAST(2, 0, 9) + if (SDL_RumbleGamepad(controller->sdl, vibration->left_motor_speed, vibration->right_motor_speed, + 0)) { + return X_ERROR_FUNCTION_FAILED; + } else { + return X_ERROR_SUCCESS; + } +#else + return X_ERROR_SUCCESS; +#endif +} + +X_RESULT SDLInputDriver::GetKeystroke(uint32_t users, uint32_t flags, + X_INPUT_KEYSTROKE* out_keystroke) { + // TODO(JoelLinn): Figure out the flags + // https://github.com/evilC/UCR/blob/0489929e2a8e39caa3484c67f3993d3fba39e46f/Libraries/XInput.ahk#L85-L98 + assert(sdl_events_initialized_ && SDL_Gamepad_initialized_); + bool user_any = users == 0xFF; + if (users >= HID_SDL_USER_COUNT && !user_any) { + return X_ERROR_BAD_ARGUMENTS; + } + if (!out_keystroke) { + return X_ERROR_BAD_ARGUMENTS; + } + + // The order of this list is also the order in which events are send if + // multiple buttons change at once. + static_assert(sizeof(X_INPUT_GAMEPAD::buttons) == 2); + static constexpr std::array kVkLookup = { + // 00 - True buttons from xinput button field + rex::ui::VirtualKey::kXInputPadDpadUp, + rex::ui::VirtualKey::kXInputPadDpadDown, + rex::ui::VirtualKey::kXInputPadDpadLeft, + rex::ui::VirtualKey::kXInputPadDpadRight, + rex::ui::VirtualKey::kXInputPadStart, + rex::ui::VirtualKey::kXInputPadBack, + rex::ui::VirtualKey::kXInputPadLThumbPress, + rex::ui::VirtualKey::kXInputPadRThumbPress, + rex::ui::VirtualKey::kXInputPadLShoulder, + rex::ui::VirtualKey::kXInputPadRShoulder, + rex::ui::VirtualKey::kNone, /* Guide has no VK */ + rex::ui::VirtualKey::kNone, /* Unknown */ + rex::ui::VirtualKey::kXInputPadA, + rex::ui::VirtualKey::kXInputPadB, + rex::ui::VirtualKey::kXInputPadX, + rex::ui::VirtualKey::kXInputPadY, + // 16 - Fake buttons generated from analog inputs + rex::ui::VirtualKey::kXInputPadLTrigger, + rex::ui::VirtualKey::kXInputPadRTrigger, + // 18 + rex::ui::VirtualKey::kXInputPadLThumbUp, + rex::ui::VirtualKey::kXInputPadLThumbDown, + rex::ui::VirtualKey::kXInputPadLThumbRight, + rex::ui::VirtualKey::kXInputPadLThumbLeft, + rex::ui::VirtualKey::kXInputPadLThumbUpLeft, + rex::ui::VirtualKey::kXInputPadLThumbUpRight, + rex::ui::VirtualKey::kXInputPadLThumbDownRight, + rex::ui::VirtualKey::kXInputPadLThumbDownLeft, + // 26 + rex::ui::VirtualKey::kXInputPadRThumbUp, + rex::ui::VirtualKey::kXInputPadRThumbDown, + rex::ui::VirtualKey::kXInputPadRThumbRight, + rex::ui::VirtualKey::kXInputPadRThumbLeft, + rex::ui::VirtualKey::kXInputPadRThumbUpLeft, + rex::ui::VirtualKey::kXInputPadRThumbUpRight, + rex::ui::VirtualKey::kXInputPadRThumbDownRight, + rex::ui::VirtualKey::kXInputPadRThumbDownLeft, + }; + + auto is_active = this->is_active(); + + if (is_active) { + QueueControllerUpdate(); + } + + auto guard = DrainAndLock(); + + for (uint32_t user_index = (user_any ? 0 : users); + user_index < (user_any ? HID_SDL_USER_COUNT : users + 1); user_index++) { + auto controller = GetControllerState(user_index); + if (!controller) { + if (user_any) { + continue; + } else { + return X_ERROR_DEVICE_NOT_CONNECTED; + } + } + + // If input is not active (e.g. due to a dialog overlay), force buttons to + // "unpressed". The algorithm will automatically send UP events when + // `is_active()` goes low and DOWN events when it goes high again. + const uint64_t curr_butts = + is_active + ? (controller->state.gamepad.buttons | AnalogToKeyfield(controller->state.gamepad)) + : uint64_t(0); + KeystrokeState& last = keystroke_states_.at(user_index); + + // Handle repeating + auto guest_now = rex::chrono::Clock::QueryGuestUptimeMillis(); + static_assert(HID_SDL_REPEAT_DELAY >= HID_SDL_REPEAT_RATE); + if (last.repeat_state == RepeatState::Waiting && + (last.repeat_time + HID_SDL_REPEAT_DELAY < guest_now)) { + last.repeat_state = RepeatState::Repeating; + } + if (last.repeat_state == RepeatState::Repeating && + (last.repeat_time + HID_SDL_REPEAT_RATE < guest_now)) { + last.repeat_time = guest_now; + rex::ui::VirtualKey vk = kVkLookup.at(last.repeat_butt_idx); + assert_true(vk != rex::ui::VirtualKey::kNone); + out_keystroke->virtual_key = uint16_t(vk); + out_keystroke->unicode = 0; + out_keystroke->user_index = user_index; + out_keystroke->hid_code = 0; + out_keystroke->flags = X_INPUT_KEYSTROKE_KEYDOWN | X_INPUT_KEYSTROKE_REPEAT; + return X_ERROR_SUCCESS; + } + + auto butts_changed = curr_butts ^ last.buttons; + if (!butts_changed) { + continue; + } + + // First try to clear buttons with up events. This is to match xinput + // behaviour when transitioning thumb sticks, e.g. so that THUMB_UPLEFT is + // up before THUMB_LEFT is down. + for (auto [clear_pass, i] = std::tuple{true, 0}; i < 2; clear_pass = false, i++) { + for (uint8_t i = 0; i < uint8_t(std::size(kVkLookup)); i++) { + auto fbutton = uint64_t(1) << i; + if (!(butts_changed & fbutton)) { + continue; + } + rex::ui::VirtualKey vk = kVkLookup.at(i); + if (vk == rex::ui::VirtualKey::kNone) { + continue; + } + + out_keystroke->virtual_key = uint16_t(vk); + out_keystroke->unicode = 0; + out_keystroke->user_index = user_index; + out_keystroke->hid_code = 0; + + bool is_pressed = curr_butts & fbutton; + if (clear_pass && !is_pressed) { + // up + out_keystroke->flags = X_INPUT_KEYSTROKE_KEYUP; + last.buttons &= ~fbutton; + last.repeat_state = RepeatState::Idle; + return X_ERROR_SUCCESS; + } + if (!clear_pass && is_pressed) { + // down + out_keystroke->flags = X_INPUT_KEYSTROKE_KEYDOWN; + last.buttons |= fbutton; + last.repeat_state = RepeatState::Waiting; + last.repeat_butt_idx = i; + last.repeat_time = guest_now; + return X_ERROR_SUCCESS; + } + } + } + } + return X_ERROR_EMPTY; +} + +void SDLInputDriver::HandleEvent(const SDL_Event& event) { + // This callback will likely run on the thread that posts the event, which + // may be a dedicated thread SDL has created for the joystick subsystem. + + // Event queue should never be (this) full + assert(SDL_PeepEvents(nullptr, 0, SDL_PEEKEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST) < 0xFFFF); + + // The queue could grow up to 3.5MB since it is never polled. + if (++sdl_events_unflushed_ > 64) { + SDL_FlushEvents(SDL_EVENT_JOYSTICK_AXIS_MOTION, SDL_EVENT_FINGER_DOWN - 1); + sdl_events_unflushed_ = 0; + } + + // Buffer only - no controllers_mutex_ acquisition here. + // This breaks the lock ordering inversion between controllers_mutex_ and + // SDL's internal joystick lock that caused deadlocks. + std::lock_guard guard(event_queue_mutex_); + pending_events_.push_back(event); +} + +std::unique_lock SDLInputDriver::DrainAndLock() { + std::vector events; + { + std::lock_guard guard(event_queue_mutex_); + events.swap(pending_events_); + } + std::unique_lock guard(controllers_mutex_); + for (const auto& event : events) { + ProcessEventLocked(event); + } + return guard; +} + +void SDLInputDriver::ProcessEventLocked(const SDL_Event& event) { + switch (event.type) { + case SDL_EVENT_GAMEPAD_ADDED: + OnControllerDeviceAddedLocked(event); + break; + case SDL_EVENT_GAMEPAD_REMOVED: + OnControllerDeviceRemovedLocked(event); + break; + case SDL_EVENT_GAMEPAD_AXIS_MOTION: + OnControllerDeviceAxisMotionLocked(event); + break; + case SDL_EVENT_GAMEPAD_BUTTON_DOWN: + case SDL_EVENT_GAMEPAD_BUTTON_UP: + OnControllerDeviceButtonChangedLocked(event); + break; + default: + break; + } +} + +void SDLInputDriver::OnControllerDeviceAddedLocked(const SDL_Event& event) { + // Open the controller. + const auto controller = SDL_OpenGamepad(event.cdevice.which); + if (!controller) { + assert_always(); + return; + } + REXLOG_INFO( + "SDL OnControllerDeviceAdded: \"{}\", " + "JoystickType({}), " + "GameControllerType({}), " + "VendorID(0x{:04X}), " + "ProductID(0x{:04X})", + SDL_GetGamepadName(controller), + static_cast(SDL_GetJoystickType(SDL_GetGamepadJoystick(controller))), + static_cast(SDL_GetGamepadType(controller)), SDL_GetGamepadVendor(controller), + SDL_GetGamepadProduct(controller)); + int user_id = -1; + // Check if the controller has a player index LED. + user_id = SDL_GetGamepadPlayerIndex(controller); + // Is that id already taken? + if (user_id < 0 || user_id >= static_cast(controllers_.size()) || + controllers_.at(user_id).sdl) { + user_id = -1; + } + // No player index or already taken, just take the first free slot. + if (user_id < 0) { + for (size_t i = 0; i < controllers_.size(); i++) { + if (!controllers_.at(i).sdl) { + user_id = static_cast(i); +#if SDL_VERSION_ATLEAST(2, 0, 12) + SDL_SetGamepadPlayerIndex(controller, user_id); +#endif + break; + } + } + } + if (user_id >= 0) { + auto& state = controllers_.at(user_id); + state = {controller, {}}; + // XInput seems to start with packet_number = 1 . + state.state_changed = true; + UpdateXCapabilities(state); + + REXLOG_INFO("SDL OnControllerDeviceAdded: Added at index {}.", user_id); + } else { + // No more controllers needed, close it. + SDL_CloseGamepad(controller); + REXLOG_WARN("SDL OnControllerDeviceAdded: Ignored. No free slots."); + } +} + +void SDLInputDriver::OnControllerDeviceRemovedLocked(const SDL_Event& event) { + // Find the disconnected gamecontroller and close it. + auto idx = GetControllerIndexFromInstanceID(event.cdevice.which); + if (idx) { + SDL_CloseGamepad(controllers_.at(*idx).sdl); + controllers_.at(*idx) = {}; + keystroke_states_.at(*idx) = {}; + REXLOG_INFO("SDL OnControllerDeviceRemoved: Removed at player index {}.", *idx); + } else { + // Can happen in case all slots where full previously. + REXLOG_WARN("SDL OnControllerDeviceRemoved: Ignored. Unused device."); + } +} + +void SDLInputDriver::OnControllerDeviceAxisMotionLocked(const SDL_Event& event) { + auto idx = GetControllerIndexFromInstanceID(event.gaxis.which); + assert(idx); + auto& pad = controllers_.at(*idx).state.gamepad; + switch (event.gaxis.axis) { + case SDL_GAMEPAD_AXIS_LEFTX: + pad.thumb_lx = event.gaxis.value; + break; + case SDL_GAMEPAD_AXIS_LEFTY: + pad.thumb_ly = ~event.gaxis.value; + break; + case SDL_GAMEPAD_AXIS_RIGHTX: + pad.thumb_rx = event.gaxis.value; + break; + case SDL_GAMEPAD_AXIS_RIGHTY: + pad.thumb_ry = ~event.gaxis.value; + break; + case SDL_GAMEPAD_AXIS_LEFT_TRIGGER: + pad.left_trigger = static_cast(event.gaxis.value >> 7); + break; + case SDL_GAMEPAD_AXIS_RIGHT_TRIGGER: + pad.right_trigger = static_cast(event.gaxis.value >> 7); + break; + default: + assert_always(); + break; + } + controllers_.at(*idx).state_changed = true; +} + +void SDLInputDriver::OnControllerDeviceButtonChangedLocked(const SDL_Event& event) { + // Define a lookup table to map between SDL and XInput button codes. + // These need to be in the order of the SDL_GamepadButton enum. + static constexpr std::array::type, 21> + xbutton_lookup = { + // Standard buttons: + X_INPUT_GAMEPAD_A, + X_INPUT_GAMEPAD_B, + X_INPUT_GAMEPAD_X, + X_INPUT_GAMEPAD_Y, + X_INPUT_GAMEPAD_BACK, + X_INPUT_GAMEPAD_GUIDE, + X_INPUT_GAMEPAD_START, + X_INPUT_GAMEPAD_LEFT_THUMB, + X_INPUT_GAMEPAD_RIGHT_THUMB, + X_INPUT_GAMEPAD_LEFT_SHOULDER, + X_INPUT_GAMEPAD_RIGHT_SHOULDER, + X_INPUT_GAMEPAD_DPAD_UP, + X_INPUT_GAMEPAD_DPAD_DOWN, + X_INPUT_GAMEPAD_DPAD_LEFT, + X_INPUT_GAMEPAD_DPAD_RIGHT, + // There are additional buttons only available on some controllers. + // For now just assign sensible defaults + // Misc: + X_INPUT_GAMEPAD_GUIDE, + // Xbox Elite paddles: + X_INPUT_GAMEPAD_Y, + X_INPUT_GAMEPAD_B, + X_INPUT_GAMEPAD_X, + X_INPUT_GAMEPAD_A, + // PS touchpad button + X_INPUT_GAMEPAD_GUIDE, + }; + static_assert(SDL_GAMEPAD_BUTTON_SOUTH == 0); + static_assert(SDL_GAMEPAD_BUTTON_DPAD_RIGHT == 14); + + auto idx = GetControllerIndexFromInstanceID(event.gdevice.which); + assert(idx); + auto& controller = controllers_.at(*idx); + + uint16_t xbuttons = controller.state.gamepad.buttons; + // Lookup the XInput button code. + if (event.gbutton.button >= xbutton_lookup.size()) { + // A newer SDL Version may have added new buttons. + REXLOG_INFO("SDL HID: Unknown button was pressed: {}.", event.gbutton.button); + return; + } + auto xbutton = xbutton_lookup.at(event.gbutton.button); + // Pressed or released? + if (event.gbutton.down) { + if (xbutton == X_INPUT_GAMEPAD_GUIDE && !REXCVAR_GET(guide_button)) { + return; + } + xbuttons |= xbutton; + } else { + xbuttons &= ~xbutton; + } + controller.state.gamepad.buttons = xbuttons; + controller.state_changed = true; +} + +std::optional SDLInputDriver::GetControllerIndexFromInstanceID(SDL_JoystickID instance_id) { + // Loop through our controllers and try to match the given ID. + for (size_t i = 0; i < controllers_.size(); i++) { + auto controller = controllers_.at(i).sdl; + if (!controller) { + continue; + } + auto joystick = SDL_GetGamepadJoystick(controller); + assert(joystick); + auto joy_instance_id = SDL_GetJoystickID(joystick); + assert(joy_instance_id >= 0); + if (joy_instance_id == instance_id) { + return i; + } + } + return std::nullopt; +} + +SDLInputDriver::ControllerState* SDLInputDriver::GetControllerState(uint32_t user_index) { + if (user_index >= controllers_.size()) { + return nullptr; + } + auto controller = &controllers_.at(user_index); + if (!controller->sdl) { + return nullptr; + } + return controller; +} + +bool SDLInputDriver::TestSDLVersion() const { + REXLOG_INFO("SDL: Using version {}.{}.{}", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, + SDL_MICRO_VERSION); + return true; +} + +void SDLInputDriver::UpdateXCapabilities(ControllerState& state) { + assert(state.sdl); + uint16_t cap_flags = 0x0; + + // The RAWINPUT driver combines and enhances input from different APIs. For + // details, see `SDL_rawinputjoystick.c`. This correlation however has latency + // which might confuse games calling `GetCapabilities()` (The power level is + // only available after the controller has been "touched"). Generally that + // should not be a problem, when in doubt disable the RAWINPUT driver via hint + // (env var). + + if (SDL_GetJoystickConnectionState(SDL_GetGamepadJoystick(state.sdl)) == + SDL_JOYSTICK_CONNECTION_WIRELESS) { + cap_flags |= X_INPUT_CAPS_WIRELESS; + } + + // Check if all navigational buttons are present + static constexpr std::array nav_buttons = { + SDL_GAMEPAD_BUTTON_START, SDL_GAMEPAD_BUTTON_BACK, SDL_GAMEPAD_BUTTON_DPAD_UP, + SDL_GAMEPAD_BUTTON_DPAD_DOWN, SDL_GAMEPAD_BUTTON_DPAD_LEFT, SDL_GAMEPAD_BUTTON_DPAD_RIGHT, + }; + for (auto it = nav_buttons.begin(); it < nav_buttons.end(); it++) { + if (!SDL_GamepadHasButton(state.sdl, *it)) { + cap_flags |= X_INPUT_CAPS_NO_NAVIGATION; + break; + } + } + + auto& c = state.caps; + c.type = 0x01; // XINPUT_DEVTYPE_GAMEPAD + c.sub_type = 0x01; // XINPUT_DEVSUBTYPE_GAMEPAD + c.flags = cap_flags; + c.gamepad.buttons = 0xF3FF | (REXCVAR_GET(guide_button) ? X_INPUT_GAMEPAD_GUIDE : 0x0); + c.gamepad.left_trigger = 0xFF; + c.gamepad.right_trigger = 0xFF; + c.gamepad.thumb_lx = static_cast(0xFFFFu); + c.gamepad.thumb_ly = static_cast(0xFFFFu); + c.gamepad.thumb_rx = static_cast(0xFFFFu); + c.gamepad.thumb_ry = static_cast(0xFFFFu); + c.vibration.left_motor_speed = 0xFFFFu; + c.vibration.right_motor_speed = 0xFFFFu; +} + +void SDLInputDriver::QueueControllerUpdate() { + // Pump SDL events to ensure controller state is up to date. + bool is_queued = false; + sdl_pumpevents_queued_.compare_exchange_strong(is_queued, true); + if (!is_queued) { + attached_window_->app_context().CallInUIThread([this]() { + SDL_PumpEvents(); + sdl_pumpevents_queued_ = false; + }); + } +} + +// Check if the analog inputs exceed their thresholds to become a button press +// and build the bitfield. +inline uint64_t SDLInputDriver::AnalogToKeyfield(const X_INPUT_GAMEPAD& gamepad) const { + uint64_t f = 0; + + f |= static_cast(gamepad.left_trigger > HID_SDL_TRIGG_THRES) << 16; + f |= static_cast(gamepad.right_trigger > HID_SDL_TRIGG_THRES) << 17; + + auto thumb_x = static_cast(gamepad.thumb_lx); + auto thumb_y = static_cast(gamepad.thumb_ly); + for (size_t i = 0; i <= 8; i = i + 8) { + uint64_t u = thumb_y > HID_SDL_THUMB_THRES; + uint64_t d = thumb_y < ~HID_SDL_THUMB_THRES; + uint64_t r = thumb_x > HID_SDL_THUMB_THRES; + uint64_t l = thumb_x < ~HID_SDL_THUMB_THRES; + if (u && l) { + u = l = 0; + f |= uint64_t(1) << (22 + i); + } + if (u && r) { + u = r = 0; + f |= uint64_t(1) << (23 + i); + } + if (d && r) { + d = r = 0; + f |= uint64_t(1) << (24 + i); + } + if (d && l) { + d = l = 0; + f |= uint64_t(1) << (25 + i); + } + f |= u << (18 + i); + f |= d << (19 + i); + f |= r << (20 + i); + f |= l << (21 + i); + + thumb_x = static_cast(gamepad.thumb_rx); + thumb_y = static_cast(gamepad.thumb_ry); + } + return f; +} + +} // namespace rex::input::sdl diff --git a/src/input/xinput/xinput_input_driver.cpp b/src/input/xinput/xinput_input_driver.cpp new file mode 100644 index 0000000..844612b --- /dev/null +++ b/src/input/xinput/xinput_input_driver.cpp @@ -0,0 +1,231 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Sanjay Govind, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include // NOLINT(build/include_order) + +namespace rex::input::xinput { + +XinputInputDriver::XinputInputDriver(rex::ui::Window* window, size_t window_z_order) + : InputDriver(window, window_z_order), + module_(nullptr), + XInputGetCapabilities_(nullptr), + XInputGetState_(nullptr), + XInputGetStateEx_(nullptr), + XInputGetKeystroke_(nullptr), + XInputSetState_(nullptr), + XInputEnable_(nullptr) {} + +XinputInputDriver::~XinputInputDriver() { + if (module_) { + FreeLibrary((HMODULE)module_); + module_ = nullptr; + XInputGetCapabilities_ = nullptr; + XInputGetState_ = nullptr; + XInputGetStateEx_ = nullptr; + XInputGetKeystroke_ = nullptr; + XInputSetState_ = nullptr; + XInputEnable_ = nullptr; + } +} + +X_STATUS XinputInputDriver::Setup() { + HMODULE module = LoadLibraryW(L"xinput1_4.dll"); + if (!module) { + return X_STATUS_DLL_NOT_FOUND; + } + + // Support guide button with XInput using XInputGetStateEx + // https://source.winehq.org/git/wine.git/?a=commit;h=de3591ca9803add117fbacb8abe9b335e2e44977 + auto const XInputGetStateEx = (LPCSTR)100; + + // Required. + auto xigc = GetProcAddress(module, "XInputGetCapabilities"); + auto xigs = GetProcAddress(module, "XInputGetState"); + auto xigsEx = GetProcAddress(module, XInputGetStateEx); + auto xigk = GetProcAddress(module, "XInputGetKeystroke"); + auto xiss = GetProcAddress(module, "XInputSetState"); + + // Not required. + auto xie = GetProcAddress(module, "XInputEnable"); + + // Only fail when we don't have the bare essentials; + if (!xigc || !xigs || !xigk || !xiss) { + FreeLibrary(module); + return X_STATUS_PROCEDURE_NOT_FOUND; + } + + module_ = module; + XInputGetCapabilities_ = xigc; + XInputGetState_ = xigs; + XInputGetStateEx_ = xigsEx; + XInputGetKeystroke_ = xigk; + XInputSetState_ = xiss; + XInputEnable_ = xie; + + return X_STATUS_SUCCESS; +} + +constexpr uint64_t SKIP_INVALID_CONTROLLER_TIME = 1100; +static uint64_t last_invalid_time[4]; + +static DWORD should_skip(uint32_t user_index) { + uint64_t time = last_invalid_time[user_index]; + if (time) { + uint64_t deltatime = rex::chrono::Clock::QueryHostUptimeMillis() - time; + + if (deltatime < SKIP_INVALID_CONTROLLER_TIME) { + return ERROR_DEVICE_NOT_CONNECTED; + } + last_invalid_time[user_index] = 0; + } + return 0; +} + +static void set_skip(uint32_t user_index) { + last_invalid_time[user_index] = rex::chrono::Clock::QueryHostUptimeMillis(); +} + +X_RESULT XinputInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags, + X_INPUT_CAPABILITIES* out_caps) { + DWORD skipper = should_skip(user_index); + if (skipper) { + return skipper; + } + XINPUT_CAPABILITIES native_caps; + auto xigc = (decltype(&XInputGetCapabilities))XInputGetCapabilities_; + DWORD result = xigc(user_index, flags & ~X_INPUT_DEVTYPE::XINPUT_DEVTYPE_KEYBOARD, &native_caps); + if (result) { + if (result == ERROR_DEVICE_NOT_CONNECTED) { + set_skip(user_index); + } + return result; + } + + out_caps->type = native_caps.Type; + out_caps->sub_type = native_caps.SubType; + out_caps->flags = native_caps.Flags; + out_caps->gamepad.buttons = native_caps.Gamepad.wButtons; + out_caps->gamepad.left_trigger = native_caps.Gamepad.bLeftTrigger; + out_caps->gamepad.right_trigger = native_caps.Gamepad.bRightTrigger; + out_caps->gamepad.thumb_lx = native_caps.Gamepad.sThumbLX; + out_caps->gamepad.thumb_ly = native_caps.Gamepad.sThumbLY; + out_caps->gamepad.thumb_rx = native_caps.Gamepad.sThumbRX; + out_caps->gamepad.thumb_ry = native_caps.Gamepad.sThumbRY; + out_caps->vibration.left_motor_speed = native_caps.Vibration.wLeftMotorSpeed; + out_caps->vibration.right_motor_speed = native_caps.Vibration.wRightMotorSpeed; + + return result; +} + +X_RESULT XinputInputDriver::GetState(uint32_t user_index, X_INPUT_STATE* out_state) { + DWORD skipper = should_skip(user_index); + if (skipper) { + return skipper; + } + + // Added padding in case we are using XInputGetStateEx + struct { + XINPUT_STATE state; + unsigned int dwPaddingReserved; + } native_state; + + // If the guide button is enabled use XInputGetStateEx, otherwise use the + // default XInputGetState. + auto xigs = REXCVAR_GET(guide_button) ? (decltype(&XInputGetState))XInputGetStateEx_ + : (decltype(&XInputGetState))XInputGetState_; + + DWORD result = xigs(user_index, &native_state.state); + if (result) { + if (result == ERROR_DEVICE_NOT_CONNECTED) { + set_skip(user_index); + } + return result; + } + + out_state->packet_number = native_state.state.dwPacketNumber; + out_state->gamepad.buttons = native_state.state.Gamepad.wButtons; + out_state->gamepad.left_trigger = native_state.state.Gamepad.bLeftTrigger; + out_state->gamepad.right_trigger = native_state.state.Gamepad.bRightTrigger; + out_state->gamepad.thumb_lx = native_state.state.Gamepad.sThumbLX; + out_state->gamepad.thumb_ly = native_state.state.Gamepad.sThumbLY; + out_state->gamepad.thumb_rx = native_state.state.Gamepad.sThumbRX; + out_state->gamepad.thumb_ry = native_state.state.Gamepad.sThumbRY; + + return result; +} + +X_RESULT XinputInputDriver::SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration) { + DWORD skipper = should_skip(user_index); + if (skipper) { + return skipper; + } + XINPUT_VIBRATION native_vibration; + native_vibration.wLeftMotorSpeed = vibration->left_motor_speed; + native_vibration.wRightMotorSpeed = vibration->right_motor_speed; + auto xiss = (decltype(&XInputSetState))XInputSetState_; + DWORD result = xiss(user_index, &native_vibration); + if (result == ERROR_DEVICE_NOT_CONNECTED) { + set_skip(user_index); + } + return result; +} + +X_RESULT XinputInputDriver::GetKeystroke(uint32_t users, uint32_t flags, + X_INPUT_KEYSTROKE* out_keystroke) { + // We may want to filter flags/user_index before sending to native. + // flags is reserved on desktop. + DWORD result; + bool user_any = users == 0xFF; + // XInputGetKeystroke on Windows has a bug where it will return + // ERROR_SUCCESS (0) even if the device is not connected: + // https://stackoverflow.com/questions/23669238/xinputgetkeystroke-returning-error-success-while-controller-is-unplugged + // + // So we first check if the device is connected via XInputGetCapabilities, so + // we are not passing back an uninitialized X_INPUT_KEYSTROKE structure. + // If any user (0xFF) is polled this bug does not occur but GetCapabilities + // would fail so we need to skip it. + if (!user_any) { + XINPUT_CAPABILITIES caps; + auto xigc = (decltype(&XInputGetCapabilities))XInputGetCapabilities_; + result = xigc(users, 0, &caps); + if (result) { + return result; + } + } + + XINPUT_KEYSTROKE native_keystroke; + auto xigk = (decltype(&XInputGetKeystroke))XInputGetKeystroke_; + result = xigk(users, 0, &native_keystroke); + if (result) { + return result; + } + + out_keystroke->virtual_key = native_keystroke.VirtualKey; + out_keystroke->unicode = native_keystroke.Unicode; + out_keystroke->flags = native_keystroke.Flags; + out_keystroke->user_index = native_keystroke.UserIndex; + out_keystroke->hid_code = native_keystroke.HidCode; + // X_ERROR_EMPTY if no new keys + // X_ERROR_DEVICE_NOT_CONNECTED if no device + // X_ERROR_SUCCESS if key + return result; +} +} // namespace rex::input::xinput diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt new file mode 100644 index 0000000..99ea636 --- /dev/null +++ b/src/kernel/CMakeLists.txt @@ -0,0 +1,69 @@ +set(REXKERNEL_SOURCES + kernel_init.cpp + + # XAM subsystem - provides __imp__Xam* symbols + xam/xam_module.cpp + xam/xam_avatar.cpp + xam/xam_content.cpp + xam/xam_content_aggregate.cpp + xam/xam_content_device.cpp + xam/xam_debug.cpp + xam/xam_enum.cpp + xam/xam_info.cpp + xam/xam_input.cpp + xam/xam_locale.cpp + xam/xam_msg.cpp + xam/xam_net.cpp + xam/xam_notify.cpp + xam/xam_nui.cpp + xam/xam_party.cpp + xam/xam_task.cpp + xam/xam_ui.cpp + xam/xam_user.cpp + xam/xam_video.cpp + xam/xam_voice.cpp + xam/xam_misc.cpp + xam/apps/xam_app.cpp + xam/apps/xgi_app.cpp + xam/apps/xlivebase_app.cpp + xam/apps/xmp_app.cpp + + # XBDM subsystem - provides __imp__Xbdm* symbols + xbdm/xbdm_module.cpp + xbdm/xbdm_misc.cpp + + # xboxkrnl exports - provides __imp__ symbols for generated code + # xboxkrnl/cert_monitor.cpp # TODO: Translate JIT methods for AOT + # xboxkrnl/debug_monitor.cpp # TODO: Translate JIT methods for AOT + xboxkrnl/xboxkrnl_crypt.cpp + xboxkrnl/xboxkrnl_debug.cpp + xboxkrnl/xboxkrnl_error.cpp + xboxkrnl/xboxkrnl_hal.cpp + xboxkrnl/xboxkrnl_hid.cpp + xboxkrnl/xboxkrnl_io.cpp + xboxkrnl/xboxkrnl_io_info.cpp + xboxkrnl/xboxkrnl_memory.cpp + xboxkrnl/xboxkrnl_misc.cpp + xboxkrnl/xboxkrnl_module.cpp + xboxkrnl/xboxkrnl_modules.cpp + xboxkrnl/xboxkrnl_ob.cpp + xboxkrnl/xboxkrnl_rtl.cpp + xboxkrnl/xboxkrnl_strings.cpp + xboxkrnl/xboxkrnl_threading.cpp + # xboxkrnl/xboxkrnl_usbcam.cpp # TODO: lol eventually. + xboxkrnl/xboxkrnl_video.cpp + xboxkrnl/xboxkrnl_xconfig.cpp + xboxkrnl/xboxkrnl_audio.cpp + xboxkrnl/xboxkrnl_audio_xma.cpp + + crt/heap.cpp + crt/file.cpp + crt/memory.cpp + crt/string.cpp + crt/threading.cpp +) + +list(TRANSFORM REXKERNEL_SOURCES PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/") +target_sources(rexruntime PRIVATE ${REXKERNEL_SOURCES}) + +target_link_libraries(rexruntime PRIVATE o1heap rexcore rexfilesystem rexgraphics rexui rexaudio rexinput imgui) diff --git a/src/kernel/crt/file.cpp b/src/kernel/crt/file.cpp new file mode 100644 index 0000000..39bda8c --- /dev/null +++ b/src/kernel/crt/file.cpp @@ -0,0 +1,617 @@ +/** + * @file kernel/crt/file.cpp + * + * @brief rexcrt File I/O hooks -- Win32-style CRT wrappers backed by VFS. + * Generic implementations with no game-specific logic. + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using rex::X_STATUS; + +namespace rex::kernel::crt { + +constexpr uint32_t kCreateNew = 1; +constexpr uint32_t kCreateAlways = 2; +constexpr uint32_t kOpenExisting = 3; +constexpr uint32_t kOpenAlways = 4; +constexpr uint32_t kTruncateExisting = 5; + +constexpr uint32_t kFileBegin = 0; +constexpr uint32_t kFileCurrent = 1; +constexpr uint32_t kFileEnd = 2; + +constexpr uint32_t kInvalidHandleValue = 0xFFFFFFFF; + +static rex::filesystem::FileDisposition MapDisposition(uint32_t win32_disp) { + using FD = rex::filesystem::FileDisposition; + switch (win32_disp) { + case kCreateNew: + return FD::kCreate; + case kCreateAlways: + return FD::kOverwriteIf; + case kOpenExisting: + return FD::kOpen; + case kOpenAlways: + return FD::kOpenIf; + case kTruncateExisting: + return FD::kOverwrite; + default: + return FD::kOpen; + } +} + +u32 CreateFileA_entry(mapped_string lpFileName, u32 dwDesiredAccess, u32 dwShareMode, + mapped_void lpSecurityAttributes, u32 dwCreationDisposition, + u32 dwFlagsAndAttributes, u32 hTemplateFile) { + const char* path = static_cast(lpFileName); + auto* ks = REX_KERNEL_STATE(); + auto disposition = MapDisposition(static_cast(dwCreationDisposition)); + + rex::filesystem::File* vfs_file = nullptr; + rex::filesystem::FileAction action; + X_STATUS status = ks->file_system()->OpenFile(nullptr, path, disposition, + static_cast(dwDesiredAccess), false, true, + &vfs_file, &action); + + if (XFAILED(status) || !vfs_file) { + REXKRNL_NOISY_DEBUG("rexcrt_CreateFileA: FAILED path='{}' status={:#x}", path, status); + return kInvalidHandleValue; + } + + auto* xfile = new rex::system::XFile(ks, vfs_file, true); + auto handle = xfile->handle(); + REXKRNL_NOISY_DEBUG("rexcrt_CreateFileA: '{}' -> handle={:#x}", path, handle); + return handle; +} + +u32 ReadFile_entry(u32 hFile, mapped_void lpBuffer, u32 nNumberOfBytesToRead, + mapped_u32 lpNumberOfBytesRead, mapped_void lpOverlapped) { + auto file = REX_KERNEL_OBJECTS()->LookupObject(static_cast(hFile)); + if (!file) { + REXKRNL_WARN("rexcrt_ReadFile: invalid handle {:#x}", static_cast(hFile)); + if (lpNumberOfBytesRead) + *lpNumberOfBytesRead = 0; + return 0; + } + + uint64_t offset = static_cast(-1); + if (lpOverlapped) { + auto* ov = reinterpret_cast*>( + static_cast(static_cast(lpOverlapped))); + offset = + (static_cast(static_cast(ov[3])) << 32) | static_cast(ov[2]); + } + + uint32_t bytes_read = 0; + X_STATUS status = file->Read(lpBuffer.guest_address(), + static_cast(nNumberOfBytesToRead), offset, &bytes_read, 0); + + if (lpOverlapped) { + auto* ov = reinterpret_cast*>( + static_cast(static_cast(lpOverlapped))); + ov[0] = 0; + ov[1] = bytes_read; + } else if (lpNumberOfBytesRead) { + *lpNumberOfBytesRead = bytes_read; + } + + return XSUCCEEDED(status) ? 1u : 0u; +} + +u32 WriteFile_entry(u32 hFile, mapped_void lpBuffer, u32 nNumberOfBytesToWrite, + mapped_u32 lpNumberOfBytesWritten, mapped_void lpOverlapped) { + auto file = REX_KERNEL_OBJECTS()->LookupObject(static_cast(hFile)); + if (!file) { + if (lpNumberOfBytesWritten) + *lpNumberOfBytesWritten = 0; + return 0; + } + + uint64_t offset = static_cast(-1); + if (lpOverlapped) { + auto* ov = reinterpret_cast*>( + static_cast(static_cast(lpOverlapped))); + offset = + (static_cast(static_cast(ov[3])) << 32) | static_cast(ov[2]); + } + + uint32_t bytes_written = 0; + X_STATUS status = + file->Write(lpBuffer.guest_address(), static_cast(nNumberOfBytesToWrite), offset, + &bytes_written, 0); + + if (lpOverlapped) { + auto* ov = reinterpret_cast*>( + static_cast(static_cast(lpOverlapped))); + ov[0] = 0; + ov[1] = bytes_written; + } else if (lpNumberOfBytesWritten) { + *lpNumberOfBytesWritten = bytes_written; + } + + return XSUCCEEDED(status) ? 1u : 0u; +} + +u32 SetFilePointer_entry(u32 hFile, u32 lDistanceToMove, mapped_u32 lpDistanceToMoveHigh, + u32 dwMoveMethod) { + auto file = REX_KERNEL_OBJECTS()->LookupObject(static_cast(hFile)); + if (!file) + return kInvalidHandleValue; + + int64_t distance = static_cast(static_cast(lDistanceToMove)); + if (lpDistanceToMoveHigh) { + distance |= + static_cast(static_cast(static_cast(*lpDistanceToMoveHigh))) + << 32; + } + + uint64_t new_pos = 0; + switch (static_cast(dwMoveMethod)) { + case kFileBegin: + new_pos = static_cast(distance); + break; + case kFileCurrent: + new_pos = file->position() + distance; + break; + case kFileEnd: + new_pos = file->entry()->size() + distance; + break; + default: + return kInvalidHandleValue; + } + + file->set_position(new_pos); + if (lpDistanceToMoveHigh) + *lpDistanceToMoveHigh = static_cast(new_pos >> 32); + return static_cast(new_pos & 0xFFFFFFFF); +} + +u32 GetFileSize_entry(u32 hFile, mapped_u32 lpFileSizeHigh) { + auto file = REX_KERNEL_OBJECTS()->LookupObject(static_cast(hFile)); + if (!file) + return kInvalidHandleValue; + + uint64_t size = file->entry()->size(); + if (lpFileSizeHigh) + *lpFileSizeHigh = static_cast(size >> 32); + return static_cast(size & 0xFFFFFFFF); +} + +u32 GetFileSizeEx_entry(u32 hFile, mapped_void lpFileSize) { + auto file = REX_KERNEL_OBJECTS()->LookupObject(static_cast(hFile)); + if (!file) + return 0; + + uint64_t size = file->entry()->size(); + if (lpFileSize) { + auto* out = + reinterpret_cast*>(static_cast(static_cast(lpFileSize))); + out[0] = static_cast(size >> 32); + out[1] = static_cast(size & 0xFFFFFFFF); + } + return 1; +} + +u32 SetEndOfFile_entry(u32 hFile) { + auto file = REX_KERNEL_OBJECTS()->LookupObject(static_cast(hFile)); + if (!file) + return 0; + X_STATUS status = file->SetLength(file->position()); + return XSUCCEEDED(status) ? 1u : 0u; +} + +u32 FlushFileBuffers_entry(u32 hFile) { + (void)hFile; + return 1; +} + +u32 DeleteFileA_entry(mapped_string lpFileName) { + const char* path = static_cast(lpFileName); + bool ok = REX_KERNEL_FS()->DeletePath(path); + if (!ok) + REXKRNL_NOISY_DEBUG("rexcrt_DeleteFileA: FAILED '{}'", path); + return ok ? 1u : 0u; +} + +u32 CloseHandle_entry(u32 hObject) { + uint32_t h = static_cast(hObject); + if (h == kInvalidHandleValue || h == 0) + return 0; + auto status = REX_KERNEL_OBJECTS()->ReleaseHandle(h); + if (XFAILED(status)) { + REXKRNL_WARN("rexcrt_CloseHandle: unknown handle {:#x}", h); + return 0; + } + return 1; +} + +static void FillFindData(mapped_void lpFindFileData, rex::filesystem::Entry* entry) { + auto* buf = static_cast(static_cast(lpFindFileData)); + std::memset(buf, 0, 0x140); + + auto* fields = reinterpret_cast*>(buf); + fields[0] = entry->attributes(); // 0x00 dwFileAttributes + fields[1] = + static_cast(entry->create_timestamp() & 0xFFFFFFFF); // 0x04 ftCreationTime.Low + fields[2] = static_cast(entry->create_timestamp() >> 32); // 0x08 ftCreationTime.High + fields[3] = + static_cast(entry->access_timestamp() & 0xFFFFFFFF); // 0x0C ftLastAccessTime.Low + fields[4] = static_cast(entry->access_timestamp() >> 32); // 0x10 ftLastAccessTime.High + fields[5] = + static_cast(entry->write_timestamp() & 0xFFFFFFFF); // 0x14 ftLastWriteTime.Low + fields[6] = static_cast(entry->write_timestamp() >> 32); // 0x18 ftLastWriteTime.High + fields[7] = static_cast(entry->size() >> 32); // 0x1C nFileSizeHigh + fields[8] = static_cast(entry->size() & 0xFFFFFFFF); // 0x20 nFileSizeLow + // 0x24 dwReserved0, 0x28 dwReserved1 already zero + + // 0x2C cFileName[260] + const auto& name = entry->name(); + std::strncpy(reinterpret_cast(buf + 0x2C), name.c_str(), 259); + // 0x130 cAlternateFileName[14] already zero +} + +u32 FindFirstFileA_entry(mapped_string lpFileName, mapped_void lpFindFileData) { + const char* path = static_cast(lpFileName); + auto dir = rex::string::utf8_find_base_guest_path(path); + auto pattern = rex::string::utf8_find_name_from_guest_path(path); + + auto* ks = REX_KERNEL_STATE(); + rex::filesystem::File* vfs_file = nullptr; + rex::filesystem::FileAction action; + X_STATUS status = ks->file_system()->OpenFile( + nullptr, dir, rex::filesystem::FileDisposition::kOpen, 0, true, false, &vfs_file, &action); + if (XFAILED(status) || !vfs_file) { + REXKRNL_DEBUG("rexcrt_FindFirstFileA: dir not found '{}'", dir); + return kInvalidHandleValue; + } + + auto* xfile = new rex::system::XFile(ks, vfs_file, true); + xfile->SetFindPattern(pattern); + + auto* entry = xfile->FindNext(); + if (!entry) { + REXKRNL_DEBUG("rexcrt_FindFirstFileA: no matches for '{}' in '{}'", pattern, dir); + REX_KERNEL_OBJECTS()->ReleaseHandle(xfile->handle()); + return kInvalidHandleValue; + } + + FillFindData(lpFindFileData, entry); + REXKRNL_TRACE("rexcrt_FindFirstFileA: '{}' first match='{}' handle={:#x}", path, entry->name(), + xfile->handle()); + return xfile->handle(); +} + +u32 FindNextFileA_entry(u32 hFindFile, mapped_void lpFindFileData) { + auto file = + REX_KERNEL_OBJECTS()->LookupObject(static_cast(hFindFile)); + if (!file) + return 0; + + auto* entry = file->FindNext(); + if (!entry) + return 0; + + FillFindData(lpFindFileData, entry); + return 1; +} + +u32 FindClose_entry(u32 hFindFile) { + return CloseHandle_entry(hFindFile); +} + +u32 CreateDirectoryA_entry(mapped_string lpPathName, mapped_void lpSecurityAttributes) { + const char* path = static_cast(lpPathName); + auto* entry = REX_KERNEL_FS()->CreatePath(path, rex::filesystem::kFileAttributeDirectory); + return entry ? 1u : 0u; +} + +u32 MoveFileA_entry(mapped_string lpExistingFileName, mapped_string lpNewFileName) { + const char* src = static_cast(lpExistingFileName); + const char* dst = static_cast(lpNewFileName); + + auto* fs = REX_KERNEL_FS(); + auto* src_entry = fs->ResolvePath(src); + if (!src_entry) { + REXKRNL_DEBUG("rexcrt_MoveFileA: source not found '{}'", src); + return 0; + } + // Win32 MoveFileA fails if the destination already exists; callers wanting + // overwrite semantics use MoveFileExA with MOVEFILE_REPLACE_EXISTING. + if (fs->ResolvePath(dst)) { + REXKRNL_DEBUG("rexcrt_MoveFileA: destination exists '{}'", dst); + return 0; + } + + src_entry->Rename(rex::to_path(dst)); + REXKRNL_TRACE("rexcrt_MoveFileA: '{}' -> '{}'", src, dst); + return 1; +} + +u32 SetFileAttributesA_entry(mapped_string lpFileName, u32 dwFileAttributes) { + (void)lpFileName; + (void)dwFileAttributes; + return 1; +} + +u32 GetFileAttributesA_entry(mapped_string lpFileName) { + const char* path = static_cast(lpFileName); + auto* entry = REX_KERNEL_FS()->ResolvePath(path); + if (!entry) { + REXKRNL_DEBUG("rexcrt_GetFileAttributesA: not found '{}'", path); + return kInvalidHandleValue; // INVALID_FILE_ATTRIBUTES + } + REXKRNL_TRACE("rexcrt_GetFileAttributesA: '{}' -> attrs={:#x}", path, entry->attributes()); + return entry->attributes(); +} + +u32 GetFileAttributesExA_entry(u32 fInfoLevelId, mapped_string lpFileName, + mapped_void lpFileInformation) { + const char* path = static_cast(lpFileName); + auto* entry = REX_KERNEL_FS()->ResolvePath(path); + if (!entry) { + REXKRNL_DEBUG("rexcrt_GetFileAttributesExA: not found '{}'", path); + return 0; + } + + // Fill WIN32_FILE_ATTRIBUTE_DATA (GetFileExInfoStandard = 0) + auto* buf = + reinterpret_cast*>(static_cast(static_cast(lpFileInformation))); + buf[0] = entry->attributes(); // dwFileAttributes + buf[1] = static_cast(entry->create_timestamp() & 0xFFFFFFFF); // ftCreationTime.Low + buf[2] = static_cast(entry->create_timestamp() >> 32); // ftCreationTime.High + buf[3] = static_cast(entry->access_timestamp() & 0xFFFFFFFF); // ftLastAccessTime.Low + buf[4] = static_cast(entry->access_timestamp() >> 32); // ftLastAccessTime.High + buf[5] = static_cast(entry->write_timestamp() & 0xFFFFFFFF); // ftLastWriteTime.Low + buf[6] = static_cast(entry->write_timestamp() >> 32); // ftLastWriteTime.High + buf[7] = static_cast(entry->size() >> 32); // nFileSizeHigh + buf[8] = static_cast(entry->size() & 0xFFFFFFFF); // nFileSizeLow + return 1; +} + +u32 SetFilePointerEx_entry(u32 hFile, u32 distHigh, u32 distLow, mapped_void lpNewFilePointer, + u32 dwMoveMethod) { + auto file = REX_KERNEL_OBJECTS()->LookupObject(static_cast(hFile)); + if (!file) + return 0; + + int64_t distance = + static_cast((static_cast(static_cast(distHigh)) << 32) | + static_cast(distLow)); + + uint64_t new_pos = 0; + switch (static_cast(dwMoveMethod)) { + case kFileBegin: + new_pos = static_cast(distance); + break; + case kFileCurrent: + new_pos = file->position() + distance; + break; + case kFileEnd: + new_pos = file->entry()->size() + distance; + break; + default: + return 0; + } + + file->set_position(new_pos); + + if (lpNewFilePointer) { + auto* out = reinterpret_cast*>( + static_cast(static_cast(lpNewFilePointer))); + out[0] = static_cast(new_pos & 0xFFFFFFFF); // LowPart + out[1] = static_cast(new_pos >> 32); // HighPart + } + return 1; +} + +u32 SetFileTime_entry(u32 hFile, mapped_void lpCreationTime, mapped_void lpLastAccessTime, + mapped_void lpLastWriteTime) { + // VFS doesn't support modifying timestamps; report success. + (void)hFile; + (void)lpCreationTime; + (void)lpLastAccessTime; + (void)lpLastWriteTime; + return 1; +} + +u32 CompareFileTime_entry(mapped_void lpFileTime1, mapped_void lpFileTime2) { + auto* ft1 = + reinterpret_cast*>(static_cast(static_cast(lpFileTime1))); + auto* ft2 = + reinterpret_cast*>(static_cast(static_cast(lpFileTime2))); + // FILETIME: { dwLowDateTime, dwHighDateTime } + uint64_t t1 = + (static_cast(static_cast(ft1[1])) << 32) | static_cast(ft1[0]); + uint64_t t2 = + (static_cast(static_cast(ft2[1])) << 32) | static_cast(ft2[0]); + if (t1 < t2) + return static_cast(-1); + if (t1 > t2) + return 1u; + return 0u; +} + +u32 CopyFileA_entry(mapped_string lpExistingFileName, mapped_string lpNewFileName, + u32 bFailIfExists) { + const char* src = static_cast(lpExistingFileName); + const char* dst = static_cast(lpNewFileName); + + auto* ks = REX_KERNEL_STATE(); + + // Open source for reading + rex::filesystem::File* src_file = nullptr; + rex::filesystem::FileAction action; + X_STATUS status = ks->file_system()->OpenFile( + nullptr, src, rex::filesystem::FileDisposition::kOpen, + rex::filesystem::FileAccess::kFileReadData, false, true, &src_file, &action); + if (XFAILED(status) || !src_file) { + REXKRNL_DEBUG("rexcrt_CopyFileA: failed to open source '{}'", src); + return 0; + } + + // Open/create destination + auto disp = static_cast(bFailIfExists) ? rex::filesystem::FileDisposition::kCreate + : rex::filesystem::FileDisposition::kOverwriteIf; + rex::filesystem::File* dst_file = nullptr; + status = + ks->file_system()->OpenFile(nullptr, dst, disp, rex::filesystem::FileAccess::kFileWriteData, + false, true, &dst_file, &action); + if (XFAILED(status) || !dst_file) { + src_file->Destroy(); + REXKRNL_DEBUG("rexcrt_CopyFileA: failed to open dest '{}'", dst); + return 0; + } + + // Copy data in 64KB chunks + constexpr size_t kBufSize = 65536; + auto buf = std::make_unique(kBufSize); + uint64_t offset = 0; + bool ok = true; + for (;;) { + size_t bytes_read = 0; + status = src_file->ReadSync(std::span(buf.get(), kBufSize), offset, &bytes_read); + if (XFAILED(status) || bytes_read == 0) + break; + + size_t bytes_written = 0; + status = dst_file->WriteSync(std::span(buf.get(), bytes_read), offset, + &bytes_written); + if (XFAILED(status) || bytes_written != bytes_read) { + ok = false; + break; + } + offset += bytes_read; + } + + dst_file->Destroy(); + src_file->Destroy(); + REXKRNL_TRACE("rexcrt_CopyFileA: '{}' -> '{}' {}", src, dst, ok ? "OK" : "FAILED"); + return ok ? 1u : 0u; +} + +u32 RemoveDirectoryA_entry(mapped_string lpPathName) { + const char* path = static_cast(lpPathName); + bool ok = REX_KERNEL_FS()->DeletePath(path); + if (!ok) + REXKRNL_DEBUG("rexcrt_RemoveDirectoryA: FAILED '{}'", path); + return ok ? 1u : 0u; +} + +u32 GetFileType_entry(u32 hFile) { + auto file = REX_KERNEL_OBJECTS()->LookupObject(static_cast(hFile)); + if (!file) + return 0; // FILE_TYPE_UNKNOWN + return 1; // FILE_TYPE_DISK +} + +u32 GetDiskFreeSpaceExA_entry(mapped_string lpDirectoryName, + mapped_void lpFreeBytesAvailableToCaller, + mapped_void lpTotalNumberOfBytes, + mapped_void lpTotalNumberOfFreeBytes) { + const char* path = static_cast(lpDirectoryName); + auto* entry = REX_KERNEL_FS()->ResolvePath(path); + if (!entry) { + REXKRNL_DEBUG("rexcrt_GetDiskFreeSpaceExA: path not found '{}'", path); + return 0; + } + + auto* dev = entry->device(); + uint64_t bytes_per_au = + static_cast(dev->sectors_per_allocation_unit()) * dev->bytes_per_sector(); + uint64_t total_bytes = static_cast(dev->total_allocation_units()) * bytes_per_au; + uint64_t free_bytes = static_cast(dev->available_allocation_units()) * bytes_per_au; + + if (lpFreeBytesAvailableToCaller) { + auto* out = reinterpret_cast*>( + static_cast(static_cast(lpFreeBytesAvailableToCaller))); + out[0] = static_cast(free_bytes & 0xFFFFFFFF); + out[1] = static_cast(free_bytes >> 32); + } + if (lpTotalNumberOfBytes) { + auto* out = reinterpret_cast*>( + static_cast(static_cast(lpTotalNumberOfBytes))); + out[0] = static_cast(total_bytes & 0xFFFFFFFF); + out[1] = static_cast(total_bytes >> 32); + } + if (lpTotalNumberOfFreeBytes) { + auto* out = reinterpret_cast*>( + static_cast(static_cast(lpTotalNumberOfFreeBytes))); + out[0] = static_cast(free_bytes & 0xFFFFFFFF); + out[1] = static_cast(free_bytes >> 32); + } + + REXKRNL_TRACE("rexcrt_GetDiskFreeSpaceExA: '{}' total={}MB free={}MB", path, + total_bytes / (1024 * 1024), free_bytes / (1024 * 1024)); + return 1; +} + +} // namespace rex::kernel::crt + +REX_HOOK(rexcrt_CreateFileA, rex::kernel::crt::CreateFileA_entry) +REX_HOOK(rexcrt_ReadFile, rex::kernel::crt::ReadFile_entry) +REX_HOOK(rexcrt_WriteFile, rex::kernel::crt::WriteFile_entry) +REX_HOOK(rexcrt_SetFilePointer, rex::kernel::crt::SetFilePointer_entry) +REX_HOOK(rexcrt_GetFileSize, rex::kernel::crt::GetFileSize_entry) +REX_HOOK(rexcrt_GetFileSizeEx, rex::kernel::crt::GetFileSizeEx_entry) +REX_HOOK(rexcrt_SetEndOfFile, rex::kernel::crt::SetEndOfFile_entry) +REX_HOOK(rexcrt_FlushFileBuffers, rex::kernel::crt::FlushFileBuffers_entry) +REX_HOOK(rexcrt_DeleteFileA, rex::kernel::crt::DeleteFileA_entry) +REX_HOOK(rexcrt_CloseHandle, rex::kernel::crt::CloseHandle_entry) +REX_HOOK(rexcrt_FindFirstFileA, rex::kernel::crt::FindFirstFileA_entry) +REX_HOOK(rexcrt_FindNextFileA, rex::kernel::crt::FindNextFileA_entry) +REX_HOOK(rexcrt_FindClose, rex::kernel::crt::FindClose_entry) +REX_HOOK(rexcrt_CreateDirectoryA, rex::kernel::crt::CreateDirectoryA_entry) +REX_HOOK(rexcrt_MoveFileA, rex::kernel::crt::MoveFileA_entry) +REX_HOOK(rexcrt_SetFileAttributesA, rex::kernel::crt::SetFileAttributesA_entry) +REX_HOOK(rexcrt_GetFileAttributesA, rex::kernel::crt::GetFileAttributesA_entry) +REX_HOOK(rexcrt_GetFileAttributesExA, rex::kernel::crt::GetFileAttributesExA_entry) +REX_HOOK(rexcrt_SetFilePointerEx, rex::kernel::crt::SetFilePointerEx_entry) +REX_HOOK(rexcrt_SetFileTime, rex::kernel::crt::SetFileTime_entry) +REX_HOOK(rexcrt_CompareFileTime, rex::kernel::crt::CompareFileTime_entry) +REX_HOOK(rexcrt_CopyFileA, rex::kernel::crt::CopyFileA_entry) +REX_HOOK(rexcrt_RemoveDirectoryA, rex::kernel::crt::RemoveDirectoryA_entry) +REX_HOOK(rexcrt_GetFileType, rex::kernel::crt::GetFileType_entry) + +// XAM exports -- same implementations, for games that import file I/O from xam.xex +REX_EXPORT(__imp__CreateFileA, rex::kernel::crt::CreateFileA_entry) +REX_EXPORT(__imp__ReadFile, rex::kernel::crt::ReadFile_entry) +REX_EXPORT(__imp__WriteFile, rex::kernel::crt::WriteFile_entry) +REX_EXPORT(__imp__SetFilePointer, rex::kernel::crt::SetFilePointer_entry) +REX_EXPORT(__imp__GetFileSize, rex::kernel::crt::GetFileSize_entry) +REX_EXPORT(__imp__GetFileSizeEx, rex::kernel::crt::GetFileSizeEx_entry) +REX_EXPORT(__imp__SetEndOfFile, rex::kernel::crt::SetEndOfFile_entry) +REX_EXPORT(__imp__FlushFileBuffers, rex::kernel::crt::FlushFileBuffers_entry) +REX_EXPORT(__imp__DeleteFileA, rex::kernel::crt::DeleteFileA_entry) +REX_EXPORT(__imp__CloseHandle, rex::kernel::crt::CloseHandle_entry) +REX_EXPORT(__imp__FindFirstFileA, rex::kernel::crt::FindFirstFileA_entry) +REX_EXPORT(__imp__FindNextFileA, rex::kernel::crt::FindNextFileA_entry) +REX_EXPORT(__imp__CreateDirectoryA, rex::kernel::crt::CreateDirectoryA_entry) +REX_EXPORT(__imp__MoveFileA, rex::kernel::crt::MoveFileA_entry) +REX_EXPORT(__imp__SetFileAttributesA, rex::kernel::crt::SetFileAttributesA_entry) +REX_EXPORT(__imp__GetFileAttributesA, rex::kernel::crt::GetFileAttributesA_entry) +REX_EXPORT(__imp__GetFileAttributesExA, rex::kernel::crt::GetFileAttributesExA_entry) +REX_EXPORT(__imp__SetFilePointerEx, rex::kernel::crt::SetFilePointerEx_entry) +REX_EXPORT(__imp__SetFileTime, rex::kernel::crt::SetFileTime_entry) +REX_EXPORT(__imp__CompareFileTime, rex::kernel::crt::CompareFileTime_entry) +REX_EXPORT(__imp__CopyFileA, rex::kernel::crt::CopyFileA_entry) +REX_EXPORT(__imp__GetDiskFreeSpaceExA, rex::kernel::crt::GetDiskFreeSpaceExA_entry) diff --git a/src/kernel/crt/heap.cpp b/src/kernel/crt/heap.cpp new file mode 100644 index 0000000..045fa8b --- /dev/null +++ b/src/kernel/crt/heap.cpp @@ -0,0 +1,363 @@ +/** + * @file kernel/crt/heap.cpp + * + * @brief ReXHeap implementation using o1heap with size header pattern. + * Hooks RtlAllocateHeap, RtlFreeHeap, RtlSizeHeap, RtlReAllocateHeap. + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(rexcrt_heap_enable, false, "crt", + "Enable o1heap-backed CRT heap for RtlAllocateHeap/Free/Size/ReAlloc") + .lifecycle(rex::cvar::Lifecycle::kInitOnly); + +REXCVAR_DEFINE_UINT32(rexcrt_heap_size_mb, 256, "crt", "Heap size in megabytes") + .lifecycle(rex::cvar::Lifecycle::kInitOnly) + .range(1, 2048); + +// --------------------------------------------------------------------------- +// Size header: prepended to every allocation so we can answer RtlSizeHeap +// without o1heap exposing per-allocation usable size. +// --------------------------------------------------------------------------- +namespace { + +struct SizeHeader { + uint64_t requested_size; + uint64_t reserved; // padding to O1HEAP_ALIGNMENT +}; +static_assert(sizeof(SizeHeader) == O1HEAP_ALIGNMENT, + "SizeHeader must be exactly one O1HEAP_ALIGNMENT unit"); + +constexpr uint32_t kHeaderSize = static_cast(O1HEAP_ALIGNMENT); +constexpr uint32_t kMinSegmentSize = 4u * 1024u * 1024u; +constexpr uint32_t kDefaultGrowthSegmentSize = 64u * 1024u * 1024u; + +#ifndef HEAP_ZERO_MEMORY +constexpr uint32_t HEAP_ZERO_MEMORY = 0x00000008; +#endif + +} // namespace + +// --------------------------------------------------------------------------- +// ReXHeap implementation +// --------------------------------------------------------------------------- + +namespace rex::kernel::crt { + +void* ReXHeap::GuestToHost(uint32_t guest_addr) const { + return membase_ + guest_addr; +} + +uint32_t ReXHeap::HostToGuest(void* host_ptr) const { + return static_cast(static_cast(host_ptr) - membase_); +} + +bool ReXHeap::InHeap(uint32_t guest_addr) const { + std::lock_guard lock(mutex_); + return FindSegmentByGuestLocked(guest_addr) != nullptr; +} + +bool ReXHeap::Init(uint32_t heap_size_bytes, rex::memory::Memory* memory) { + memory_ = memory; + auto* mem = memory_; + if (!mem) { + REXKRNL_ERROR("rexcrt_heap: memory is null"); + return false; + } + + membase_ = mem->virtual_membase(); + if (!membase_) { + REXKRNL_ERROR("rexcrt_heap: virtual_membase is null"); + return false; + } + + initial_segment_size_ = + rex::align(std::max(heap_size_bytes, kMinSegmentSize), O1HEAP_ALIGNMENT); + + std::lock_guard lock(mutex_); + segments_.clear(); + if (!AllocateSegmentLocked(initial_segment_size_)) { + return false; + } + + const auto diagnostics = GetDiagnosticsLocked(); + REXKRNL_INFO("rexcrt_heap: initialized with {} segment(s), capacity={}MB", segments_.size(), + diagnostics.capacity / (1024 * 1024)); + return true; +} + +uint32_t ReXHeap::Alloc(uint32_t size, bool zero) { + std::lock_guard lock(mutex_); + return AllocLocked(size, zero); +} + +void ReXHeap::Free(uint32_t guest_addr) { + if (!guest_addr) + return; + std::lock_guard lock(mutex_); + auto* segment = FindSegmentByGuestLocked(guest_addr); + if (!segment || guest_addr < segment->guest_base + kHeaderSize) { + REXKRNL_WARN("rexcrt_RtlFreeHeap: skipping OOB ptr 0x{:08X}", guest_addr); + return; + } + + void* real_host = GuestToHost(guest_addr - kHeaderSize); + o1heapFree(segment->heap, real_host); +} + +uint32_t ReXHeap::Size(uint32_t guest_addr) { + if (!guest_addr) + return ~0u; + + std::lock_guard lock(mutex_); + auto* segment = FindSegmentByGuestLocked(guest_addr); + if (!segment || guest_addr < segment->guest_base + kHeaderSize) { + return ~0u; + } + + auto* hdr = static_cast(GuestToHost(guest_addr - kHeaderSize)); + return static_cast(hdr->requested_size); +} + +uint32_t ReXHeap::Realloc(uint32_t guest_addr, uint32_t new_size, bool zero_new) { + std::lock_guard lock(mutex_); + if (!guest_addr) { + return AllocLocked(new_size, zero_new); + } + if (new_size == 0) + new_size = 1; + + auto* segment = FindSegmentByGuestLocked(guest_addr); + if (!segment || guest_addr < segment->guest_base + kHeaderSize) { + // Pre-hook allocation outside our heap -- treat as fresh alloc. + REXKRNL_WARN("rexcrt_RtlReAllocateHeap: OOB ptr 0x{:08X}, treating as new alloc({})", + guest_addr, new_size); + return AllocLocked(new_size, zero_new); + } + + void* real_host = GuestToHost(guest_addr - kHeaderSize); + + auto* old_hdr = static_cast(real_host); + uint32_t old_size = static_cast(old_hdr->requested_size); + void* new_ptr = o1heapReallocate(segment->heap, real_host, new_size + kHeaderSize); + if (!new_ptr) { + // Cross-segment fallback: allocate a fresh block, copy, then free old. + uint32_t new_guest = AllocLocked(new_size, false); + if (!new_guest) { + REXKRNL_WARN("rexcrt_RtlReAllocateHeap: o1heapReallocate({}) failed", new_size); + return 0; + } + + void* new_user_ptr = GuestToHost(new_guest); + void* old_user_ptr = GuestToHost(guest_addr); + uint32_t copy_size = std::min(old_size, new_size); + std::memcpy(new_user_ptr, old_user_ptr, copy_size); + if (zero_new && new_size > old_size) { + std::memset(static_cast(new_user_ptr) + old_size, 0, new_size - old_size); + } + + o1heapFree(segment->heap, real_host); + return new_guest; + } + + auto* new_hdr = static_cast(new_ptr); + new_hdr->requested_size = new_size; + + void* user_ptr = static_cast(new_ptr) + kHeaderSize; + if (zero_new && new_size > old_size) { + std::memset(static_cast(user_ptr) + old_size, 0, new_size - old_size); + } + + return HostToGuest(user_ptr); +} + +HeapDiagnostics ReXHeap::GetDiagnostics() const { + std::lock_guard lock(mutex_); + return GetDiagnosticsLocked(); +} + +bool ReXHeap::AllocateSegmentLocked(uint32_t segment_size_bytes) { + auto* mem = memory_; + if (!mem) { + REXKRNL_ERROR("rexcrt_heap: kernel memory is null during segment allocation"); + return false; + } + + segment_size_bytes = + rex::align(std::max(segment_size_bytes, kMinSegmentSize), O1HEAP_ALIGNMENT); + + uint32_t guest_base = 0; + + // Allocate from the regular virtual heap (top-down) instead of the system + // heap. The system heap range is shared with kernel bookkeeping allocations + // (KernelState globals, thread PCR/TLS, module headers, etc.) and cannot + // accommodate a large contiguous rexcrt segment alongside them. + auto* vheap = mem->LookupHeapByType(false, 4096); + if (!vheap || + !vheap->Alloc(segment_size_bytes, O1HEAP_ALIGNMENT, + rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, true, + &guest_base)) { + REXKRNL_ERROR("rexcrt_heap: virtual heap allocation of {} bytes failed", segment_size_bytes); + return false; + } + + uint8_t* host_base = mem->TranslateVirtual(guest_base); + if (!host_base) { + REXKRNL_ERROR("rexcrt_heap: TranslateVirtual failed for guest base 0x{:08X}", guest_base); + return false; + } + + O1HeapInstance* heap = o1heapInit(host_base, segment_size_bytes); + if (!heap) { + REXKRNL_ERROR("rexcrt_heap: o1heapInit failed for segment 0x{:08X} size {}", guest_base, + segment_size_bytes); + return false; + } + + segments_.push_back( + HeapSegment{heap, guest_base, static_cast(guest_base + segment_size_bytes)}); + REXKRNL_INFO("rexcrt_heap: added segment guest=0x{:08X}-0x{:08X} size={}MB", guest_base, + guest_base + segment_size_bytes, segment_size_bytes / (1024 * 1024)); + return true; +} + +uint32_t ReXHeap::AllocLocked(uint32_t size, bool zero) { + if (size == 0) { + size = 1; + } + + const uint32_t alloc_size = size + kHeaderSize; + auto try_allocate_in_segment = [&](HeapSegment& segment) -> uint32_t { + void* ptr = o1heapAllocate(segment.heap, alloc_size); + if (!ptr) { + return 0; + } + + auto* hdr = static_cast(ptr); + hdr->requested_size = size; + hdr->reserved = 0; + + void* user_ptr = static_cast(ptr) + kHeaderSize; + if (zero) { + std::memset(user_ptr, 0, size); + } + return HostToGuest(user_ptr); + }; + + for (auto& segment : segments_) { + if (uint32_t guest = try_allocate_in_segment(segment)) { + return guest; + } + } + + const uint32_t min_required_segment = + rex::align(alloc_size + kHeaderSize, O1HEAP_ALIGNMENT); + const uint32_t growth_segment_size = + std::max({initial_segment_size_, kDefaultGrowthSegmentSize, min_required_segment}); + if (!AllocateSegmentLocked(growth_segment_size)) { + const auto diagnostics = GetDiagnosticsLocked(); + bool invariants_ok = true; + for (const auto& segment : segments_) { + invariants_ok = invariants_ok && o1heapDoInvariantsHold(segment.heap); + } + const uint64_t free_bytes = diagnostics.capacity - diagnostics.allocated; + REXKRNL_WARN( + "rexcrt_RtlAllocateHeap: o1heapAllocate({}) failed (segments={}, capacity={}MB, " + "allocated={}MB, free={}MB, oom_count={}, invariants_ok={})", + size, segments_.size(), diagnostics.capacity / (1024 * 1024), + diagnostics.allocated / (1024 * 1024), free_bytes / (1024 * 1024), diagnostics.oom_count, + invariants_ok); + return 0; + } + + if (uint32_t guest = try_allocate_in_segment(segments_.back())) { + return guest; + } + + const auto diagnostics = GetDiagnosticsLocked(); + const uint64_t free_bytes = diagnostics.capacity - diagnostics.allocated; + REXKRNL_WARN( + "rexcrt_RtlAllocateHeap: allocation still failed after growth for {} bytes " + "(segments={}, capacity={}MB, allocated={}MB, free={}MB, oom_count={})", + size, segments_.size(), diagnostics.capacity / (1024 * 1024), + diagnostics.allocated / (1024 * 1024), free_bytes / (1024 * 1024), diagnostics.oom_count); + return 0; +} + +ReXHeap::HeapSegment* ReXHeap::FindSegmentByGuestLocked(uint32_t guest_addr) { + auto it = std::find_if(segments_.begin(), segments_.end(), [&](const HeapSegment& segment) { + return guest_addr >= segment.guest_base && guest_addr < segment.guest_end; + }); + return it != segments_.end() ? &(*it) : nullptr; +} + +const ReXHeap::HeapSegment* ReXHeap::FindSegmentByGuestLocked(uint32_t guest_addr) const { + auto it = std::find_if(segments_.begin(), segments_.end(), [&](const HeapSegment& segment) { + return guest_addr >= segment.guest_base && guest_addr < segment.guest_end; + }); + return it != segments_.end() ? &(*it) : nullptr; +} + +HeapDiagnostics ReXHeap::GetDiagnosticsLocked() const { + HeapDiagnostics diagnostics{}; + for (const auto& segment : segments_) { + const auto d = o1heapGetDiagnostics(segment.heap); + diagnostics.capacity += d.capacity; + diagnostics.allocated += d.allocated; + diagnostics.peak_allocated += d.peak_allocated; + diagnostics.peak_request_size = std::max(diagnostics.peak_request_size, d.peak_request_size); + diagnostics.oom_count += d.oom_count; + } + return diagnostics; +} + +// --------------------------------------------------------------------------- +// Global instance + RTL hooks +// --------------------------------------------------------------------------- + +ReXHeap g_heap; + +u32 RtlAllocateHeap_entry(u32 hHeap, u32 dwFlags, u32 dwBytes) { + return g_heap.Alloc(dwBytes, dwFlags & HEAP_ZERO_MEMORY); +} + +u32 RtlFreeHeap_entry(u32 hHeap, u32 dwFlags, u32 ptr) { + g_heap.Free(static_cast(ptr)); + return 1; +} + +u32 RtlSizeHeap_entry(u32 hHeap, u32 dwFlags, u32 ptr) { + return g_heap.Size(static_cast(ptr)); +} + +u32 RtlReAllocateHeap_entry(u32 hHeap, u32 dwFlags, u32 ptr, u32 dwBytes) { + return g_heap.Realloc(static_cast(ptr), dwBytes, dwFlags & HEAP_ZERO_MEMORY); +} + +bool InitHeap(uint32_t heap_size_mb, rex::memory::Memory* memory) { + return g_heap.Init(heap_size_mb * 1024u * 1024u, memory); +} + +ReXHeap& GetHeap() { + return g_heap; +} + +} // namespace rex::kernel::crt + +REX_HOOK(rexcrt_RtlAllocateHeap, rex::kernel::crt::RtlAllocateHeap_entry) +REX_HOOK(rexcrt_RtlFreeHeap, rex::kernel::crt::RtlFreeHeap_entry) +REX_HOOK(rexcrt_RtlSizeHeap, rex::kernel::crt::RtlSizeHeap_entry) +REX_HOOK(rexcrt_RtlReAllocateHeap, rex::kernel::crt::RtlReAllocateHeap_entry) diff --git a/src/kernel/crt/memory.cpp b/src/kernel/crt/memory.cpp new file mode 100644 index 0000000..31c5384 --- /dev/null +++ b/src/kernel/crt/memory.cpp @@ -0,0 +1,85 @@ +/** + * @file kernel/crt/memory.cpp + * + * @brief Native memory operation hooks -- replaces recompiled PPC + * implementations of memcpy, memmove, memset, etc. + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ +#include + +#include + +namespace rex::kernel::crt { + +// --------------------------------------------------------------------------- +// Standard memory operations +// --------------------------------------------------------------------------- + +static void* native_memcpy(void* dst, const void* src, size_t n) { + return std::memcpy(dst, src, n); +} + +static void* native_memmove(void* dst, const void* src, size_t n) { + return std::memmove(dst, src, n); +} + +static void* native_memset(void* dst, int val, size_t n) { + return std::memset(dst, val, n); +} + +static void* native_memchr(const void* ptr, int val, size_t n) { + return const_cast(std::memchr(ptr, val, n)); +} + +// --------------------------------------------------------------------------- +// Xbox/VMX-optimized variants (same semantics, native speed) +// --------------------------------------------------------------------------- + +static void* native_XMemCpy(void* dst, const void* src, size_t n) { + return std::memcpy(dst, src, n); +} + +static void* native_XMemSet(void* dst, int val, size_t n) { + return std::memset(dst, val, n); +} + +static void* native_XMemSet128(void* dst, int val, size_t n) { + return std::memset(dst, val, n); +} + +static void* native_memset_vmx(void* dst, int val, size_t n) { + return std::memset(dst, val, n); +} + +// --------------------------------------------------------------------------- +// Secure variants (return errno_t) +// --------------------------------------------------------------------------- + +static int native_memcpy_s(void* dst, size_t dstsz, const void* src, size_t count) { + if (!dst || !src || count > dstsz) + return 22; // EINVAL + std::memcpy(dst, src, count); + return 0; +} + +static int native_memmove_s(void* dst, size_t dstsz, const void* src, size_t count) { + if (!dst || !src || count > dstsz) + return 22; // EINVAL + std::memmove(dst, src, count); + return 0; +} + +} // namespace rex::kernel::crt + +REX_HOOK(rexcrt_memcpy, rex::kernel::crt::native_memcpy) +REX_HOOK(rexcrt_memmove, rex::kernel::crt::native_memmove) +REX_HOOK(rexcrt_memset, rex::kernel::crt::native_memset) +REX_HOOK(rexcrt_memchr, rex::kernel::crt::native_memchr) +REX_HOOK(rexcrt_XMemCpy, rex::kernel::crt::native_XMemCpy) +REX_HOOK(rexcrt_XMemSet, rex::kernel::crt::native_XMemSet) +REX_HOOK(rexcrt_XMemSet128, rex::kernel::crt::native_XMemSet128) +REX_HOOK(rexcrt_memset_vmx, rex::kernel::crt::native_memset_vmx) +REX_HOOK(rexcrt_memcpy_s, rex::kernel::crt::native_memcpy_s) +REX_HOOK(rexcrt_memmove_s, rex::kernel::crt::native_memmove_s) diff --git a/src/kernel/crt/string.cpp b/src/kernel/crt/string.cpp new file mode 100644 index 0000000..eed3c6c --- /dev/null +++ b/src/kernel/crt/string.cpp @@ -0,0 +1,242 @@ +/** + * @file kernel/crt/string.cpp + * + * @brief Native string operation hooks -- replaces recompiled PPC + * implementations of strncmp, strchr, lstrlenA, etc. + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ +#include + +#include + +#if !REX_PLATFORM_WIN32 +#include +#endif + +#include + +namespace rex::kernel::crt { + +// --------------------------------------------------------------------------- +// C string operations +// --------------------------------------------------------------------------- + +static int native_strncmp(const char* s1, const char* s2, size_t n) { + return std::strncmp(s1, s2, n); +} + +static char* native_strncpy(char* dst, const char* src, size_t n) { + return std::strncpy(dst, src, n); +} + +static char* native_strchr(const char* s, int c) { + return const_cast(std::strchr(s, c)); +} + +static char* native_strstr(const char* haystack, const char* needle) { + return const_cast(std::strstr(haystack, needle)); +} + +static char* native_strrchr(const char* s, int c) { + return const_cast(std::strrchr(s, c)); +} + +static char* native_strtok(char* s, const char* delim) { + return std::strtok(s, delim); +} + +static int native_stricmp(const char* s1, const char* s2) { +#if REX_PLATFORM_WIN32 + return _stricmp(s1, s2); +#else + return strcasecmp(s1, s2); +#endif +} + +static int native_strcpy_s(char* dst, size_t dstsz, const char* src) { + if (!dst || !src || dstsz == 0) + return 22; // EINVAL +#if REX_PLATFORM_WIN32 + return strcpy_s(dst, dstsz, src); +#else + const size_t src_len = std::strlen(src); + if (src_len + 1 > dstsz) { + dst[0] = '\0'; + return 34; // ERANGE + } + std::memcpy(dst, src, src_len + 1); + return 0; +#endif +} + +// --------------------------------------------------------------------------- +// Win32 string functions (lstr*) +// --------------------------------------------------------------------------- + +static int native_lstrlenA(const char* s) { + return s ? static_cast(std::strlen(s)) : 0; +} + +static char* native_lstrcpyA(char* dst, const char* src) { + return std::strcpy(dst, src); +} + +static char* native_lstrcpynA(char* dst, const char* src, int maxlen) { + if (maxlen <= 0) + return dst; + std::strncpy(dst, src, maxlen - 1); + dst[maxlen - 1] = '\0'; + return dst; +} + +static char* native_lstrcatA(char* dst, const char* src) { + return std::strcat(dst, src); +} + +static int native_lstrcmpiA(const char* s1, const char* s2) { +#if REX_PLATFORM_WIN32 + return _stricmp(s1, s2); +#else + return strcasecmp(s1, s2); +#endif +} + +// --------------------------------------------------------------------------- +// C UTF-16 Widestring functions (int16_t*) +// --------------------------------------------------------------------------- + +static uint32_t native_wcslen(const int16_t* str) { + const int16_t* last = str; + while (*last++) + ; + return last - str - 1; +} + +static uint32_t native_wcscmp(const int16_t* lhs, const int16_t* rhs) { + while (*lhs && (*lhs == *rhs)) { + lhs++; + rhs++; + } + return (int)(*lhs) - (int)(*rhs); +} + +static uint32_t native_wcsncmp(const int16_t* lhs, const int16_t* rhs, int count) { + for (; count > 0; count--, lhs++, rhs++) { + if (*lhs != *rhs) + return (int)(*lhs) - (int)(*rhs); + + if (*lhs == L'\0') + return 0; + } + + return 0; +} + +static uint32_t native_wcscoll(const int16_t* lhs, const int16_t* rhs) { + if (lhs && rhs) + return native_wcscmp(lhs, rhs); + return 22; // EINVAL +} + +static int16_t* native_wcschr(const int16_t* str, int16_t ch) { + while (*str && *str != ch) + str++; + + return (*str == ch) ? (int16_t*)str : 0; +} + +static int16_t* native_wcsrchr(const int16_t* str, int16_t ch) { + const int16_t* res = 0; + + for (; *str; str++) + if (*str == ch) + res = str; + + return (int16_t*)(ch ? res : str); +} + +static int16_t* native_wcscpy(const int16_t* src, int16_t* dst) { + int16_t* d = dst; + + while ((*d++ = *src++)) + ; + + return dst; +} + +static int16_t* native_wcsncpy(int16_t* dest, const int16_t* src, int count) { + int16_t* d = dest; + while (count-- && (*d++ = *src++)) + ; + while (count--) + *d++ = 0; + return dest; +} + +static uint32_t native_wcsncpy_s(int16_t* dst, size_t dstsz, const int16_t* src, size_t count) { + if (!dst || !src || dstsz == 0) + return 22; // EINVAL + + size_t i = 0; + + for (; i < count && i + 1 < dstsz && src[i]; i++) + dst[i] = src[i]; + + if (i < dstsz) + dst[i] = 0; + else + dst[dstsz - 1] = 0; + + if (i < count && src[i] != 0) + return 34; // ERANGE + + return 0; +} + +static int16_t* native_wcsstr(const int16_t* dest, const int16_t* src) { + if (!*src) + return (int16_t*)dest; + + for (; *dest; dest++) { + const int16_t* d = dest; + const int16_t* s = src; + + while (*d && *s && *d == *s) { + d++; + s++; + } + + if (!*s) + return (int16_t*)dest; + } + + return 0; +} + +} // namespace rex::kernel::crt + +REX_HOOK(rexcrt_strncmp, rex::kernel::crt::native_strncmp) +REX_HOOK(rexcrt_strncpy, rex::kernel::crt::native_strncpy) +REX_HOOK(rexcrt_strchr, rex::kernel::crt::native_strchr) +REX_HOOK(rexcrt_strstr, rex::kernel::crt::native_strstr) +REX_HOOK(rexcrt_strrchr, rex::kernel::crt::native_strrchr) +REX_HOOK(rexcrt_strtok, rex::kernel::crt::native_strtok) +REX_HOOK(rexcrt__stricmp, rex::kernel::crt::native_stricmp) +REX_HOOK(rexcrt_strcpy_s, rex::kernel::crt::native_strcpy_s) +REX_HOOK(rexcrt_lstrlenA, rex::kernel::crt::native_lstrlenA) +REX_HOOK(rexcrt_lstrcpyA, rex::kernel::crt::native_lstrcpyA) +REX_HOOK(rexcrt_lstrcpynA, rex::kernel::crt::native_lstrcpynA) +REX_HOOK(rexcrt_lstrcatA, rex::kernel::crt::native_lstrcatA) +REX_HOOK(rexcrt_lstrcmpiA, rex::kernel::crt::native_lstrcmpiA) +REX_HOOK(rexcrt_wcslen, rex::kernel::crt::native_wcslen) +REX_HOOK(rexcrt_wcscmp, rex::kernel::crt::native_wcscmp) +REX_HOOK(rexcrt_wcsncmp, rex::kernel::crt::native_wcsncmp) +REX_HOOK(rexcrt_wcscoll, rex::kernel::crt::native_wcscoll) +REX_HOOK(rexcrt_wcschr, rex::kernel::crt::native_wcschr) +REX_HOOK(rexcrt_wcsrchr, rex::kernel::crt::native_wcsrchr) +REX_HOOK(rexcrt_wcscpy, rex::kernel::crt::native_wcscpy) +REX_HOOK(rexcrt_wcsncpy, rex::kernel::crt::native_wcsncpy) +REX_HOOK(rexcrt_wcsncpy_s, rex::kernel::crt::native_wcsncpy_s) +REX_HOOK(rexcrt_wcsstr, rex::kernel::crt::native_wcsstr) \ No newline at end of file diff --git a/src/kernel/crt/threading.cpp b/src/kernel/crt/threading.cpp new file mode 100644 index 0000000..22ba2fb --- /dev/null +++ b/src/kernel/crt/threading.cpp @@ -0,0 +1,342 @@ +/** + * @file kernel/crt/threading.cpp + * @brief rexcrt hooks for XAPI fiber functions + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::kernel::crt { +using namespace rex::system; + +namespace { + +std::atomic unique_fiber_count; + +/// get KTHREAD and PCR pointers from the current thread's context. +struct GuestThreadPtrs { + X_KTHREAD* kthread; + X_KPCR* pcr; + PPCContext* ctx; + memory::Memory* mem; +}; + +GuestThreadPtrs GetGuestThreadPtrs(XThread* thread) { + auto* ctx = thread->thread_state()->context(); + auto* mem = thread->kernel_state()->memory(); + auto* pcr = mem->TranslateVirtual(static_cast(ctx->r13.u64)); + auto* kthread = + mem->TranslateVirtual(static_cast(pcr->prcb_data.current_thread)); + return {kthread, pcr, ctx, mem}; +} + +/// update KTHREAD/PCR/ctx stack pointers +void UpdateGuestStackPointers(X_KTHREAD* kthread, X_KPCR* pcr, PPCContext* ctx, uint32_t sp, + uint32_t stack_alloc_base, uint32_t stack_base, + uint32_t stack_limit) { + kthread->stack_alloc_base = stack_alloc_base; + kthread->stack_base = stack_base; + kthread->stack_limit = stack_limit; + pcr->stack_base_ptr = stack_base; + pcr->stack_end_ptr = stack_limit; + ctx->r1.u64 = sp; +} + +//----------------------------------------------------------------------------- +// FiberEntryPoint -- host fiber entry for CreateFiber fibers +//----------------------------------------------------------------------------- + +struct FiberEntryArgs { + PPCFunc* start_fn; + uint32_t guest_fiber_addr; + KernelState* kernel_state; +}; + +static void FiberEntryPoint(void* raw_arg) { + auto args = std::unique_ptr(static_cast(raw_arg)); + auto* thread = XThread::GetCurrentThread(); + auto* mem = args->kernel_state->memory(); + PPCContext& ctx = *thread->thread_state()->context(); + + // Read fiber_data (lpParameter) from guest context buffer + auto* fiber = mem->TranslateVirtual(args->guest_fiber_addr); + ctx.r3.u64 = static_cast(fiber->fiber_data); + + // Call the fiber function + args->start_fn(ctx, mem->virtual_membase()); + + // Fiber returned (shouldn't per XDK) -- safe fallback + if (thread->main_fiber()) { + PROFILE_FIBER_LEAVE; + rex::thread::Fiber::SwitchTo(thread->main_fiber()); + } + REXKRNL_WARN("FiberEntryPoint: fiber function returned with no main fiber - terminating"); + std::terminate(); +} + +/// Helper for ConvertFiberToThread logic, shared by ConvertFiberToThread_entry +/// and DeleteFiber_entry (self-delete case). +u32 ConvertFiberToThread_impl(XThread* thread) { + auto* ks = thread->kernel_state(); + auto [kthread, pcr, ctx, mem] = GetGuestThreadPtrs(thread); + + uint32_t fiber_addr = kthread->fiber_ptr; + if (!fiber_addr) { + kthread->last_error = 0x501; // ERROR_ALREADY_THREAD + return 0; + } + + auto* info = ks->LookupFiber(fiber_addr); + if (info) { + info->host_fiber->Destroy(); + ks->UnregisterFiber(fiber_addr); + } + + kthread->fiber_ptr = 0u; + // Must null main_fiber_ AFTER Destroy() above to avoid double-free + // in ~XThread, which also calls main_fiber_->Destroy() if non-null. + thread->set_main_fiber(nullptr); + mem->SystemHeapFree(fiber_addr); + + return 1; // TRUE +} + +} // namespace + +//============================================================================= +// XAPI Fiber Function Implementations +//============================================================================= + +u32 ConvertThreadToFiber_entry(mapped_void lpParameter) { + auto* thread = XThread::GetCurrentThread(); + auto* ks = thread->kernel_state(); + auto [kthread, pcr, ctx, mem] = GetGuestThreadPtrs(thread); + + if (kthread->fiber_ptr) { + kthread->last_error = 0x500; // ERROR_ALREADY_FIBER + return 0; + } + + // Allocate guest fiber context buffer + uint32_t buf_addr = mem->SystemHeapAlloc(sizeof(X_FIBER_CONTEXT)); + if (!buf_addr) { + kthread->last_error = 8; // ERROR_NOT_ENOUGH_MEMORY + return 0; + } + auto* fiber = mem->TranslateVirtual(buf_addr); + std::memset(fiber, 0, sizeof(X_FIBER_CONTEXT)); + + // Populate from current KTHREAD stack state + fiber->fiber_data = lpParameter.guest_address(); + fiber->stack_alloc_base = kthread->stack_alloc_base; + fiber->stack_base = kthread->stack_base; + fiber->stack_limit = kthread->stack_limit; + fiber->sp_save = ctx->r1.u64; + + kthread->fiber_ptr = buf_addr; + + // Reuse existing host fiber from XThread::Execute() if available; + // otherwise create one (should not happen in normal flow). + auto* host_fiber = thread->main_fiber(); + if (!host_fiber) { + host_fiber = rex::thread::Fiber::ConvertCurrentThread(); + thread->set_main_fiber(host_fiber); + } + + ks->RegisterFiber(buf_addr, FiberInfo{host_fiber, unique_fiber_count++, buf_addr, 0, 0, true}); + + REXKRNL_DEBUG("ConvertThreadToFiber: fiber={:#010x} param={:#010x}", buf_addr, + lpParameter.guest_address()); + return buf_addr; +} + +u32 ConvertFiberToThread_entry() { + auto* thread = XThread::GetCurrentThread(); + auto result = ConvertFiberToThread_impl(thread); + if (result) { + REXKRNL_DEBUG("ConvertFiberToThread: success"); + } + return result; +} + +u32 CreateFiber_entry(u32 dwStackSize, u32 lpStartAddress, mapped_void lpParameter) { + auto* thread = XThread::GetCurrentThread(); + auto* ks = thread->kernel_state(); + auto* mem = ks->memory(); + + // Determine guest stack size + uint32_t guest_stack_size = dwStackSize; + if (guest_stack_size == 0) + guest_stack_size = 0x10000; // 64KB default + guest_stack_size = (guest_stack_size + 0xFFF) & ~0xFFF; // page-align + if (guest_stack_size < 0x4000) + guest_stack_size = 0x4000; // 16KB minimum + + // Allocate guest kernel stack (for PPC stack variables via ctx.r1). + // guest_stack_size is already page-aligned. + uint32_t stack_alignment = (guest_stack_size & 0xF000) ? 0x1000 : 0x10000; + uint32_t stack_address = 0; + mem->LookupHeap(0x70000000) + ->AllocRange(0x70000000, 0x7F000000, guest_stack_size, stack_alignment, + memory::kMemoryAllocationReserve | memory::kMemoryAllocationCommit, + memory::kMemoryProtectRead | memory::kMemoryProtectWrite, false, &stack_address); + if (!stack_address) { + auto [kthread, pcr, ctx, _mem] = GetGuestThreadPtrs(thread); + kthread->last_error = 8; // ERROR_NOT_ENOUGH_MEMORY + return 0; + } + uint32_t stack_top = stack_address + guest_stack_size; + uint32_t stack_bottom = stack_address; + uint32_t initial_sp = stack_top - 0x50; + + // Zero the initial 80-byte frame + std::memset(mem->TranslateVirtual(initial_sp), 0, 0x50); + + // Resolve start address to host function pointer + PPCFunc* start_fn = ks->function_dispatcher()->GetFunction(lpStartAddress); + + // Allocate guest fiber context buffer + uint32_t buf_addr = mem->SystemHeapAlloc(sizeof(X_FIBER_CONTEXT)); + if (!buf_addr) { + mem->LookupHeap(0x70000000)->Release(stack_address); + auto [kthread, pcr, ctx, _mem] = GetGuestThreadPtrs(thread); + kthread->last_error = 8; + return 0; + } + auto* fiber = mem->TranslateVirtual(buf_addr); + std::memset(fiber, 0, sizeof(X_FIBER_CONTEXT)); + + fiber->fiber_data = lpParameter.guest_address(); + fiber->stack_alloc_base = stack_top; + fiber->stack_base = stack_top; // = alloc_base initially + fiber->stack_limit = stack_bottom; + fiber->sp_save = initial_sp; + + // Create host fiber + size_t host_stack = + std::max(static_cast(guest_stack_size), static_cast(256u * 1024u)); + auto args_owner = std::make_unique(FiberEntryArgs{ + start_fn, + buf_addr, + ks, + }); + auto* host_fiber = rex::thread::Fiber::Create(host_stack, FiberEntryPoint, args_owner.get()); + if (host_fiber) { + args_owner.release(); // FiberEntryPoint takes ownership + } + + ks->RegisterFiber(buf_addr, FiberInfo{host_fiber, unique_fiber_count++, buf_addr, stack_top, + stack_bottom, false}); + + REXKRNL_DEBUG("CreateFiber: fiber={:#010x} start={:#010x} stack={:#x} param={:#010x}", buf_addr, + lpStartAddress, guest_stack_size, lpParameter.guest_address()); + return buf_addr; +} + +void DeleteFiber_entry(mapped_void lpFiber) { + auto* thread = XThread::GetCurrentThread(); + auto* ks = thread->kernel_state(); + auto* mem = ks->memory(); + auto [kthread, pcr, ctx, _mem] = GetGuestThreadPtrs(thread); + uint32_t fiber_addr = lpFiber.guest_address(); + + // Self-delete: ConvertFiberToThread + ExitThread + if (static_cast(kthread->fiber_ptr) == fiber_addr) { + REXKRNL_DEBUG("DeleteFiber: self-delete fiber={:#010x}", fiber_addr); + PROFILE_FIBER_LEAVE; + ConvertFiberToThread_impl(thread); + thread->Exit(1); // does not return + return; + } + + REXKRNL_DEBUG("DeleteFiber: fiber={:#010x}", fiber_addr); + + auto* info = ks->LookupFiber(fiber_addr); + if (info) { + if (!info->is_thread_fiber && info->guest_stack_bottom) { + mem->LookupHeap(0x70000000)->Release(info->guest_stack_bottom); + } + if (info->host_fiber) { + info->host_fiber->Destroy(); + } + ks->UnregisterFiber(fiber_addr); + } + mem->SystemHeapFree(fiber_addr); +} + +void SwitchToFiber_entry(mapped_void lpFiber) { + auto* thread = XThread::GetCurrentThread(); + auto* ks = thread->kernel_state(); + auto* mem = ks->memory(); + auto [kthread, pcr, ctx, _mem] = GetGuestThreadPtrs(thread); + uint32_t target_addr = lpFiber.guest_address(); + + // Validate target + auto* target_info = ks->LookupFiber(target_addr); + if (!target_info || !target_info->host_fiber) { + REXKRNL_WARN("SwitchToFiber: no valid fiber for {:#010x}, skipping", target_addr); + return; + } + + // Save outgoing fiber's non-volatile registers and SP + uint32_t current_addr = static_cast(kthread->fiber_ptr); + if (current_addr) { + auto* current_fiber = mem->TranslateVirtual(current_addr); + ctx->SaveNonVolatiles(current_fiber->register_save_area); + current_fiber->sp_save = ctx->r1.u64; + } + + // Set target as active + kthread->fiber_ptr = target_addr; + + // Restore target's non-volatile registers and guest stack state + auto* target_fiber = mem->TranslateVirtual(target_addr); + ctx->RestoreNonVolatiles(target_fiber->register_save_area); + UpdateGuestStackPointers(kthread, pcr, ctx, static_cast(target_fiber->sp_save), + static_cast(target_fiber->stack_alloc_base), + static_cast(target_fiber->stack_base), + static_cast(target_fiber->stack_limit)); + + // profiling + if (target_info->host_fiber == thread->main_fiber()) { + PROFILE_FIBER_LEAVE; + } else { + PROFILE_FIBER_ENTER(ks->GetOrCreateFiberName(target_info->uid, thread->name().c_str())); + } + + // Host fiber switch -- suspends here, resumes when switched back + rex::thread::Fiber::SwitchTo(target_info->host_fiber); + // Resumed: non-volatile regs and stack state already restored by the fiber that switched back. +} + +} // namespace rex::kernel::crt + +//============================================================================= +// REXCRT_EXPORT wiring +//============================================================================= + +REX_HOOK(rexcrt_ConvertThreadToFiber, rex::kernel::crt::ConvertThreadToFiber_entry) +REX_HOOK(rexcrt_ConvertFiberToThread, rex::kernel::crt::ConvertFiberToThread_entry) +REX_HOOK(rexcrt_CreateFiber, rex::kernel::crt::CreateFiber_entry) +REX_HOOK(rexcrt_DeleteFiber, rex::kernel::crt::DeleteFiber_entry) +REX_HOOK(rexcrt_SwitchToFiber, rex::kernel::crt::SwitchToFiber_entry) diff --git a/src/kernel/export_table_post.inc b/src/kernel/export_table_post.inc new file mode 100644 index 0000000..8a69c1d --- /dev/null +++ b/src/kernel/export_table_post.inc @@ -0,0 +1,13 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +// Post-include file for an export table. + +#undef FLAG +#undef XE_EXPORT diff --git a/src/kernel/export_table_pre.inc b/src/kernel/export_table_pre.inc new file mode 100644 index 0000000..b7373c9 --- /dev/null +++ b/src/kernel/export_table_pre.inc @@ -0,0 +1,28 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +/** + * Pre-include file for an export table. + * Use this to build tables of exports: + * + * // Build the export table used for resolution. + * #include "rex/kernel/util/export_table_pre.inc" + * static Export my_module_export_table[] = { + * #include "xenia/kernel/my_module/my_module_table.inc" + * }; + * #include "rex/kernel/util/export_table_post.inc" + * export_resolver_->RegisterTable( + * "my_module.xex", + * my_module_export_table, rex::countof(my_module_export_table)); + */ + +#define XE_EXPORT(module, ordinal, name, type) \ + rex::runtime::Export(ordinal, rex::runtime::Export::Type::type, #name) + +#define FLAG(t) kXEKernelExportFlag##t diff --git a/src/kernel/kernel_init.cpp b/src/kernel/kernel_init.cpp new file mode 100644 index 0000000..fc96d45 --- /dev/null +++ b/src/kernel/kernel_init.cpp @@ -0,0 +1,37 @@ +/** + * @file kernel/kernel_init.cpp + * @brief Kernel initialization - loads kernel modules and registers apps + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::kernel { + +void InitializeKernel(Runtime* runtime, system::KernelState* kernel_state) { + auto* app_mgr = kernel_state->app_manager(); + app_mgr->RegisterApp(std::make_unique(kernel_state)); + app_mgr->RegisterApp(std::make_unique(kernel_state)); + app_mgr->RegisterApp(std::make_unique(kernel_state)); + app_mgr->RegisterApp(std::make_unique(kernel_state)); + + kernel_state->LoadKernelModule(); + kernel_state->LoadKernelModule(); + kernel_state->LoadKernelModule(); +} + +} // namespace rex::kernel diff --git a/src/kernel/xam/apps/xam_app.cpp b/src/kernel/xam/apps/xam_app.cpp new file mode 100644 index 0000000..7f10ece --- /dev/null +++ b/src/kernel/xam/apps/xam_app.cpp @@ -0,0 +1,113 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +namespace rex { +namespace kernel { +namespace xam { +using namespace rex::system; +using namespace rex::system::xam; +namespace apps { +using namespace rex::system; + +XamApp::XamApp(KernelState* kernel_state) : App(kernel_state, 0xFE) {} + +X_HRESULT XamApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, + uint32_t buffer_length) { + // NOTE: buffer_length may be zero or valid. + auto buffer = memory_->TranslateVirtual(buffer_ptr); + switch (message) { + case 0x0002000E: { + struct message_data { + rex::be user_index; + rex::be unk_04; + rex::be extra_ptr; + rex::be buffer_ptr; + rex::be buffer_size; + rex::be unk_14; + rex::be length_ptr; + rex::be unk_1C; + }* data = reinterpret_cast(buffer); + REXKRNL_DEBUG( + "XamAppEnumerateContentAggregate({}, {:08X}, {:08X}, {:08X}, {}, " + "{:08X}, {:08X}, {:08X})", + (uint32_t)data->user_index, (uint32_t)data->unk_04, (uint32_t)data->extra_ptr, + (uint32_t)data->buffer_ptr, (uint32_t)data->buffer_size, (uint32_t)data->unk_14, + (uint32_t)data->length_ptr, (uint32_t)data->unk_1C); + auto extra = memory_->TranslateVirtual(data->extra_ptr); + auto buffer = memory_->TranslateVirtual(data->buffer_ptr); + auto e = kernel_state_->object_table()->LookupObject(extra->handle); + if (!e || !buffer || !extra) { + return X_E_INVALIDARG; + } + assert_true(extra->magic == kXObjSignature); + if (data->buffer_size) { + std::memset(buffer, 0, data->buffer_size); + } + uint32_t item_count = 0; + auto result = e->WriteItems(data->buffer_ptr, buffer, &item_count); + + if (result == X_ERROR_SUCCESS && item_count >= 1) { + if (data->length_ptr) { + auto length_ptr = memory_->TranslateVirtual*>(data->length_ptr); + *length_ptr = 1; + } + return X_E_SUCCESS; + } + return X_E_NO_MORE_FILES; + } + case 0x00020021: { + struct message_data { + char unk_00[64]; + rex::be unk_40; // KeGetCurrentProcessType() < 1 ? 1 : 0 + rex::be unk_44; // ? output_ptr ? + rex::be unk_48; // ? overlapped_ptr ? + }* data = reinterpret_cast(buffer); + assert_true(buffer_length == sizeof(message_data)); + auto unk = memory_->TranslateVirtual*>(data->unk_44); + *unk = 0; + REXKRNL_DEBUG("XamApp(0x00020021)('{}', {:08X}, {:08X}, {:08X})", data->unk_00, + (uint32_t)data->unk_40, (uint32_t)data->unk_44, (uint32_t)data->unk_48); + return X_E_SUCCESS; + } + case 0x00021012: { + REXKRNL_DEBUG("XamApp(0x00021012)"); + return X_E_SUCCESS; + } + case 0x00022005: { + struct message_data { + rex::be unk_00; // ? output_ptr ? + rex::be unk_04; // ? value/jump to? ? + }* data = reinterpret_cast(buffer); + assert_true(buffer_length == sizeof(message_data)); + auto unk = memory_->TranslateVirtual*>(data->unk_00); + auto adr = *unk; + REXKRNL_DEBUG("XamApp(0x00022005)(%.8X, %.8X)", (uint32_t)data->unk_00, + (uint32_t)data->unk_04); + return X_E_SUCCESS; + } + } + REXKRNL_ERROR( + "Unimplemented XAM message app={:08X}, msg={:08X}, arg1={:08X}, " + "arg2={:08X}", + app_id(), message, buffer_ptr, buffer_length); + return X_E_FAIL; +} + +} // namespace apps +} // namespace xam +} // namespace kernel +} // namespace rex diff --git a/src/kernel/xam/apps/xgi_app.cpp b/src/kernel/xam/apps/xgi_app.cpp new file mode 100644 index 0000000..7fd57ec --- /dev/null +++ b/src/kernel/xam/apps/xgi_app.cpp @@ -0,0 +1,426 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +namespace rex { +namespace kernel { +namespace xam { +using namespace rex::system; +using namespace rex::system::xam; +namespace apps { +using namespace rex::system; + +XgiApp::XgiApp(KernelState* kernel_state) : App(kernel_state, 0xFB) {} + +// http://mb.mirage.org/bugzilla/xliveless/main.c + +X_HRESULT XgiApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, + uint32_t buffer_length) { + // NOTE: buffer_length may be zero or valid. + auto buffer = memory_->TranslateVirtual(buffer_ptr); + switch (message) { + case 0x000B0006: { + assert_true(!buffer_length || buffer_length == 24); + // dword r3 user index + // dword (unwritten?) + // qword 0 + // dword r4 context enum + // dword r5 value + uint32_t user_index = memory::load_and_swap(buffer + 0); + uint32_t context_id = memory::load_and_swap(buffer + 16); + uint32_t context_value = memory::load_and_swap(buffer + 20); + REXKRNL_DEBUG("XGIUserSetContextEx({:08X}, {:08X}, {:08X})", user_index, context_id, + context_value); + return X_E_SUCCESS; + } + case 0x000B0007: { + uint32_t user_index = memory::load_and_swap(buffer + 0); + uint32_t property_id = memory::load_and_swap(buffer + 16); + uint32_t value_size = memory::load_and_swap(buffer + 20); + uint32_t value_ptr = memory::load_and_swap(buffer + 24); + REXKRNL_DEBUG("XGIUserSetPropertyEx({:08X}, {:08X}, {}, {:08X})", user_index, property_id, + value_size, value_ptr); + return X_E_SUCCESS; + } + case 0x000B0008: { + assert_true(!buffer_length || buffer_length == 8); + uint32_t achievement_count = memory::load_and_swap(buffer + 0); + uint32_t achievements_ptr = memory::load_and_swap(buffer + 4); + REXKRNL_DEBUG("XGIUserWriteAchievements({:08X}, {:08X})", achievement_count, + achievements_ptr); + return X_E_SUCCESS; + } + case 0x000B0010: { + assert_true(!buffer_length || buffer_length == 28); + // Sequence: + // - XamSessionCreateHandle + // - XamSessionRefObjByHandle + // - [this] + // - CloseHandle + uint32_t session_ptr = memory::load_and_swap(buffer + 0); + uint32_t flags = memory::load_and_swap(buffer + 4); + uint32_t num_slots_public = memory::load_and_swap(buffer + 8); + uint32_t num_slots_private = memory::load_and_swap(buffer + 12); + uint32_t user_xuid = memory::load_and_swap(buffer + 16); + uint32_t session_info_ptr = memory::load_and_swap(buffer + 20); + uint32_t nonce_ptr = memory::load_and_swap(buffer + 24); + + REXKRNL_DEBUG( + "XGISessionCreateImpl({:08X}, {:08X}, {}, {}, {:08X}, {:08X}, " + "{:08X})", + session_ptr, flags, num_slots_public, num_slots_private, user_xuid, session_info_ptr, + nonce_ptr); + return X_E_SUCCESS; + } + case 0x000B0011: { + assert_true(!buffer_length || buffer_length == 16); + + uint32_t obj_ptr = memory::load_and_swap(buffer + 0); + uint32_t flags = memory::load_and_swap(buffer + 4); + uint64_t session_nonce = memory::load_and_swap(buffer + 8); + + REXKRNL_DEBUG("XGISessionDelete({:08X}, {:08X}, {:016X})", obj_ptr, flags, session_nonce); + + return X_E_SUCCESS; + } + case 0x000B0012: { + assert_true(!buffer_length || buffer_length == 20); + uint32_t session_ptr = memory::load_and_swap(buffer + 0); + uint32_t user_count = memory::load_and_swap(buffer + 4); + uint32_t unk_0 = memory::load_and_swap(buffer + 8); + uint32_t user_index_array = memory::load_and_swap(buffer + 12); + uint32_t private_slots_array = memory::load_and_swap(buffer + 16); + + assert_zero(unk_0); + REXKRNL_DEBUG("XGISessionJoinLocal({:08X}, {}, {}, {:08X}, {:08X})", session_ptr, user_count, + unk_0, user_index_array, private_slots_array); + return X_E_SUCCESS; + } + case 0x000B0014: { + assert_true(!buffer_length || buffer_length == 16); + + uint32_t obj_ptr = memory::load_and_swap(buffer + 0); + uint32_t flags = memory::load_and_swap(buffer + 4); + uint64_t session_nonce = memory::load_and_swap(buffer + 8); + + REXKRNL_DEBUG("XSessionStart({:08X}, {:08X}, {:016X})", obj_ptr, flags, session_nonce); + + return X_STATUS_SUCCESS; + } + case 0x000B0015: { + // send high scores? + assert_true(!buffer_length || buffer_length == 16); + + uint32_t obj_ptr = memory::load_and_swap(buffer + 0); + uint32_t flags = memory::load_and_swap(buffer + 4); + uint64_t session_nonce = memory::load_and_swap(buffer + 8); + + REXKRNL_DEBUG("XSessionEnd({:08X}, {:08X}, {:016X})", obj_ptr, flags, session_nonce); + + return X_E_SUCCESS; + } + case 0x000B0016: { + assert_true(!buffer_length || buffer_length == 32); + + uint32_t proc_index = memory::load_and_swap(buffer + 0); + uint32_t user_index = memory::load_and_swap(buffer + 4); + uint32_t num_results = memory::load_and_swap(buffer + 8); + uint16_t num_props = memory::load_and_swap(buffer + 12); + uint16_t num_ctx = memory::load_and_swap(buffer + 14); + uint32_t props_ptr = memory::load_and_swap(buffer + 16); + uint32_t ctx_ptr = memory::load_and_swap(buffer + 20); + uint32_t results_buffer_size = memory::load_and_swap(buffer + 24); + uint32_t search_results_ptr = memory::load_and_swap(buffer + 28); + + REXKRNL_DEBUG("XSessionSearch({}, {}, {}, {}, {}, {:08X}, {:08X}, {}, {:08X})", proc_index, + user_index, num_results, num_props, num_ctx, props_ptr, ctx_ptr, + results_buffer_size, search_results_ptr); + return X_E_SUCCESS; + } + case 0x000B0018: { + assert_true(!buffer_length || buffer_length == 16); + + uint32_t obj_ptr = memory::load_and_swap(buffer + 0); + uint32_t flags = memory::load_and_swap(buffer + 4); + uint32_t maxPublicSlots = memory::load_and_swap(buffer + 8); + uint16_t maxPrivateSlots = memory::load_and_swap(buffer + 12); + + REXKRNL_DEBUG("XSessionModify({:08X}, {:08X}, {:08X}, {:08X})", obj_ptr, flags, + maxPublicSlots, maxPrivateSlots); + + return X_E_SUCCESS; + } + case 0x000B001C: { + assert_true(!buffer_length || buffer_length == 36); + + // session_search + uint32_t proc_index = memory::load_and_swap(buffer + 0); + uint32_t user_index = memory::load_and_swap(buffer + 4); + uint32_t num_results = memory::load_and_swap(buffer + 8); + uint16_t num_props = memory::load_and_swap(buffer + 12); + uint16_t num_ctx = memory::load_and_swap(buffer + 14); + uint32_t props_ptr = memory::load_and_swap(buffer + 16); + uint32_t ctx_ptr = memory::load_and_swap(buffer + 20); + uint32_t results_buffer_size = memory::load_and_swap(buffer + 24); + uint32_t search_results_ptr = memory::load_and_swap(buffer + 28); + // + uint32_t num_users = memory::load_and_swap(buffer + 32); + + REXKRNL_DEBUG("XSessionSearchEx({}, {}, {}, {}, {}, {:08X}, {:08X}, {}, {:08X}, {})", + proc_index, user_index, num_results, num_props, num_ctx, props_ptr, ctx_ptr, + results_buffer_size, search_results_ptr, num_users); + + return X_E_SUCCESS; + } + case 0x000B001D: { + assert_true(!buffer_length || buffer_length == 24); + + uint32_t obj_ptr = memory::load_and_swap(buffer + 0); + uint32_t details_buffer_size = memory::load_and_swap(buffer + 4); + uint32_t session_details_ptr = memory::load_and_swap(buffer + 8); + uint32_t reserved1 = memory::load_and_swap(buffer + 12); + uint32_t reserved2 = memory::load_and_swap(buffer + 16); + uint32_t reserved3 = memory::load_and_swap(buffer + 20); + + REXKRNL_DEBUG("XSessionGetDetails({:08X}, {}, {:08X}, {}, {}, {})", obj_ptr, + details_buffer_size, session_details_ptr, reserved1, reserved2, reserved3); + + return X_E_SUCCESS; + } + case 0x000B001E: { + assert_true(!buffer_length || buffer_length == 24); + + uint32_t obj_ptr = memory::load_and_swap(buffer + 0); + uint32_t session_info_ptr = memory::load_and_swap(buffer + 4); + uint32_t user_index = memory::load_and_swap(buffer + 8); + uint32_t reserved1 = memory::load_and_swap(buffer + 12); + uint32_t reserved2 = memory::load_and_swap(buffer + 16); + uint32_t reserved3 = memory::load_and_swap(buffer + 20); + + REXKRNL_DEBUG("XSessionMigrateHost({:08X}, {:08X}, {}, {}, {}, {})", obj_ptr, + session_info_ptr, user_index, reserved1, reserved2, reserved3); + + return X_E_SUCCESS; + } + case 0x000B0019: { + assert_true(!buffer_length || buffer_length == 8); + + uint32_t user_index = memory::load_and_swap(buffer + 0); + uint32_t session_info_ptr = memory::load_and_swap(buffer + 4); + + REXKRNL_DEBUG("XSessionGetInvitationData - unimplemented({}, {:08X})", user_index, + session_info_ptr); + + return X_E_SUCCESS; + } + case 0x000B001A: { + assert_true(!buffer_length || buffer_length == 28); + + uint32_t obj_ptr = memory::load_and_swap(buffer + 0); + uint32_t flags = memory::load_and_swap(buffer + 4); + uint64_t session_nonce = memory::load_and_swap(buffer + 8); + uint32_t session_duration_sec = memory::load_and_swap(buffer + 16); // 300 + uint32_t results_buffer_size = memory::load_and_swap(buffer + 20); + uint32_t results_ptr = memory::load_and_swap(buffer + 24); + + REXKRNL_DEBUG("XSessionArbitrationRegister({:08X}, {:08X}, {:016X}, {:08X}, {:08X}, {:08X})", + obj_ptr, flags, session_nonce, session_duration_sec, results_buffer_size, + results_ptr); + + return X_E_SUCCESS; + } + case 0x000B001B: { + assert_true(!buffer_length || buffer_length == 32); + + uint32_t user_index = memory::load_and_swap(buffer + 0); + uint32_t num_session_ids = memory::load_and_swap(buffer + 4); + uint32_t session_ids_ptr = memory::load_and_swap(buffer + 8); + uint32_t results_buffer_size = memory::load_and_swap(buffer + 12); + uint32_t search_results_ptr = memory::load_and_swap(buffer + 16); + uint32_t reserved1 = memory::load_and_swap(buffer + 20); + uint32_t reserved2 = memory::load_and_swap(buffer + 24); + uint32_t reserved3 = memory::load_and_swap(buffer + 28); + + REXKRNL_DEBUG("XSessionSearchByID({}, {:08X}, {:08X}, {:08X}, {:08X}, {}, {}, {})", + user_index, num_session_ids, session_ids_ptr, results_buffer_size, + search_results_ptr, reserved1, reserved2, reserved3); + + return X_E_SUCCESS; + } + case 0x000B001F: { + assert_true(!buffer_length || buffer_length == 24); + + uint32_t obj_ptr = memory::load_and_swap(buffer + 0); + uint32_t array_count = memory::load_and_swap(buffer + 4); + uint32_t xuid_array_ptr = memory::load_and_swap(buffer + 8); + uint32_t reserved1 = memory::load_and_swap(buffer + 12); + uint32_t reserved2 = memory::load_and_swap(buffer + 16); + uint32_t reserved3 = memory::load_and_swap(buffer + 20); + + REXKRNL_DEBUG("XSessionModifySkill({:08X}, {}, {:08X}, {}, {}, {})", obj_ptr, array_count, + xuid_array_ptr, reserved1, reserved2, reserved3); + + return X_E_SUCCESS; + } + case 0x000B0020: { + assert_true(!buffer_length || buffer_length == 8); + + uint32_t user_index = memory::load_and_swap(buffer + 0); + uint32_t view_id = memory::load_and_swap(buffer + 4); + + REXKRNL_DEBUG("XUserResetStatsView({:08X}, {})", user_index, view_id); + + return X_E_SUCCESS; + } + case 0x000B0021: { + assert_true(!buffer_length || buffer_length == 28); + + uint32_t title_id = memory::load_and_swap(buffer + 0); + uint32_t xuids_count = memory::load_and_swap(buffer + 4); + uint32_t xuids_ptr = memory::load_and_swap(buffer + 8); + uint32_t specs_count = memory::load_and_swap(buffer + 12); + uint32_t specs_ptr = memory::load_and_swap(buffer + 16); + uint32_t results_size = memory::load_and_swap(buffer + 20); + uint32_t results_ptr = memory::load_and_swap(buffer + 24); + + REXKRNL_DEBUG("XUserReadStats({}, {}, {:08X}, {}, {:08X}, {}, {:08X})", title_id, xuids_count, + xuids_ptr, specs_count, specs_ptr, results_size, results_ptr); + + return X_E_SUCCESS; + } + case 0x000B0025: { + assert_true(!buffer_length || buffer_length == 20); + + uint32_t obj_ptr = memory::load_and_swap(buffer + 0); + uint64_t xuid = memory::load_and_swap(buffer + 4); + uint32_t num_views = memory::load_and_swap(buffer + 12); + uint32_t views_ptr = memory::load_and_swap(buffer + 16); + + REXKRNL_DEBUG("XSessionWriteStats({:08X}, {:016X}, {:08X}, {:08X})", obj_ptr, xuid, num_views, + views_ptr); + + return X_E_SUCCESS; + } + case 0x000B0026: { + assert_true(!buffer_length || buffer_length == 20); + + uint32_t obj_ptr = memory::load_and_swap(buffer + 0); + uint64_t xuid = memory::load_and_swap(buffer + 4); + uint32_t num_views = memory::load_and_swap(buffer + 12); + uint32_t views_ptr = memory::load_and_swap(buffer + 16); + + REXKRNL_DEBUG("XSessionFlushStats({:08X}, {:016X}, {:08X}, {:08X})", obj_ptr, xuid, num_views, + views_ptr); + + return X_E_SUCCESS; + } + case 0x000B0036: { + // Called after opening xbox live arcade and clicking on xbox live v5759 + // to 5787 and called after clicking xbox live in the game library from + // v6683 to v6717 + // Does not get sent a buffer + REXKRNL_DEBUG("XInvalidateGamerTileCache, unimplemented"); + return X_E_FAIL; + } + case 0x000B003D: { + assert_true(!buffer_length || buffer_length == 16); + + uint32_t user_index = memory::load_and_swap(buffer + 0); + uint32_t AnId_buffer_size = memory::load_and_swap(buffer + 4); + uint32_t AnId_buffer_ptr = memory::load_and_swap(buffer + 8); + uint32_t block = memory::load_and_swap(buffer + 12); + + REXKRNL_DEBUG("XUserGetANID({:08X}, {:08X}, {:08X}, {:08X})", user_index, AnId_buffer_size, + AnId_buffer_ptr, block); + + return X_E_SUCCESS; + } + case 0x000B0041: { + assert_true(!buffer_length || buffer_length == 32); + // 00000000 2789fecc 00000000 00000000 200491e0 00000000 200491f0 20049340 + uint32_t user_index = memory::load_and_swap(buffer + 0); + uint32_t context_ptr = memory::load_and_swap(buffer + 16); + auto context = context_ptr ? memory_->TranslateVirtual(context_ptr) : nullptr; + uint32_t context_id = context ? memory::load_and_swap(context + 0) : 0; + REXKRNL_DEBUG("XGIUserGetContext({:08X}, {:08X}, {:08X}))", user_index, context_ptr, + context_id); + uint32_t value = 0; + if (context) { + memory::store_and_swap(context + 4, value); + } + return X_E_FAIL; + } + case 0x000B0060: { + assert_true(!buffer_length || buffer_length == 32); + + uint32_t user_index = memory::load_and_swap(buffer + 0); + uint32_t num_session_ids = memory::load_and_swap(buffer + 4); + uint32_t session_ids_ptr = memory::load_and_swap(buffer + 8); + uint32_t results_buffer_size = memory::load_and_swap(buffer + 12); + uint32_t search_results_ptr = memory::load_and_swap(buffer + 16); + uint32_t reserved1 = memory::load_and_swap(buffer + 20); + uint32_t reserved2 = memory::load_and_swap(buffer + 24); + uint32_t reserved3 = memory::load_and_swap(buffer + 28); + + REXKRNL_DEBUG("XSessionSearchByIds({:08X}, {:08X}, {:08X}, {:08X}, {:08X}, {}, {}, {})", + user_index, num_session_ids, session_ids_ptr, results_buffer_size, + search_results_ptr, reserved1, reserved2, reserved3); + + return X_E_SUCCESS; + } + case 0x000B0065: { + assert_true(!buffer_length || buffer_length == 52); + + uint32_t proc_index = memory::load_and_swap(buffer + 0); + uint32_t user_index = memory::load_and_swap(buffer + 4); + uint32_t num_results = memory::load_and_swap(buffer + 8); + uint16_t num_weighted_properties = memory::load_and_swap(buffer + 12); + uint16_t num_weighted_contexts = memory::load_and_swap(buffer + 14); + uint32_t weighted_search_properties_ptr = memory::load_and_swap(buffer + 16); + uint32_t weighted_search_contexts_ptr = memory::load_and_swap(buffer + 20); + uint16_t num_props = memory::load_and_swap(buffer + 24); + uint16_t num_ctx = memory::load_and_swap(buffer + 26); + uint32_t non_weighted_search_properties_ptr = memory::load_and_swap(buffer + 28); + uint32_t non_weighted_search_contexts_ptr = memory::load_and_swap(buffer + 32); + uint32_t results_buffer_size = memory::load_and_swap(buffer + 36); + uint32_t search_results_ptr = memory::load_and_swap(buffer + 40); + uint32_t num_users = memory::load_and_swap(buffer + 44); + uint32_t weighted_search = memory::load_and_swap(buffer + 48); + + REXKRNL_DEBUG( + "XSessionSearchWeighted({:08X}, {:08X}, {:08X}, {}, {}, {:08X}, {:08X}, {}, {}, {:08X}, " + "{:08X}, {:08X}, {:08X}, {:08X}, {:08X})", + proc_index, user_index, num_results, num_weighted_properties, num_weighted_contexts, + weighted_search_properties_ptr, weighted_search_contexts_ptr, num_props, num_ctx, + non_weighted_search_properties_ptr, non_weighted_search_contexts_ptr, results_buffer_size, + search_results_ptr, num_users, weighted_search); + + return X_E_SUCCESS; + } + case 0x000B0071: { + REXKRNL_DEBUG("XGI 0x000B0071, unimplemented"); + return X_E_SUCCESS; + } + } + REXKRNL_ERROR( + "Unimplemented XGI message app={:08X}, msg={:08X}, arg1={:08X}, " + "arg2={:08X}", + app_id(), message, buffer_ptr, buffer_length); + return X_E_FAIL; +} + +} // namespace apps +} // namespace xam +} // namespace kernel +} // namespace rex diff --git a/src/kernel/xam/apps/xlivebase_app.cpp b/src/kernel/xam/apps/xlivebase_app.cpp new file mode 100644 index 0000000..ea25e12 --- /dev/null +++ b/src/kernel/xam/apps/xlivebase_app.cpp @@ -0,0 +1,87 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +namespace rex { +namespace kernel { +namespace xam { +using namespace rex::system; +using namespace rex::system::xam; +namespace apps { +using namespace rex::system; + +XLiveBaseApp::XLiveBaseApp(KernelState* kernel_state) : App(kernel_state, 0xFC) {} + +// http://mb.mirage.org/bugzilla/xliveless/main.c + +X_HRESULT XLiveBaseApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, + uint32_t buffer_length) { + // NOTE: buffer_length may be zero or valid. + auto buffer = memory_->TranslateVirtual(buffer_ptr); + switch (message) { + case 0x00058004: { + // Called on startup, seems to just return a bool in the buffer. + assert_true(!buffer_length || buffer_length == 4); + REXKRNL_DEBUG("XLiveBaseGetLogonId({:08X})", buffer_ptr); + memory::store_and_swap(buffer + 0, 1); // ? + return X_E_SUCCESS; + } + case 0x00058006: { + assert_true(!buffer_length || buffer_length == 4); + REXKRNL_DEBUG("XLiveBaseGetNatType({:08X})", buffer_ptr); + memory::store_and_swap(buffer + 0, 1); // XONLINE_NAT_OPEN + return X_E_SUCCESS; + } + case 0x00058007: { + // Occurs if title calls XOnlineGetServiceInfo, expects dwServiceId + // and pServiceInfo. pServiceInfo should contain pointer to + // XONLINE_SERVICE_INFO structure. + REXKRNL_DEBUG("CXLiveLogon::GetServiceInfo({:08X}, {:08X})", buffer_ptr, buffer_length); + return 0x80151802; // ERROR_CONNECTION_INVALID + } + case 0x00058020: { + // 0x00058004 is called right before this. + // We should create a XamEnumerate-able empty list here, but I'm not + // sure of the format. + // buffer_length seems to be the same ptr sent to 0x00058004. + REXKRNL_DEBUG("CXLiveFriends::Enumerate({:08X}, {:08X}) unimplemented", buffer_ptr, + buffer_length); + return X_E_FAIL; + } + case 0x00058023: { + REXKRNL_DEBUG( + "CXLiveMessaging::XMessageGameInviteGetAcceptedInfo({:08X}, {:08X}) " + "unimplemented", + buffer_ptr, buffer_length); + return X_E_FAIL; + } + case 0x00058046: { + // Required to be successful for 4D530910 to detect signed-in profile + // Doesn't seem to set anything in the given buffer, probably only takes + // input + REXKRNL_DEBUG("XLiveBaseUnk58046({:08X}, {:08X}) unimplemented", buffer_ptr, buffer_length); + return X_E_SUCCESS; + } + } + REXKRNL_ERROR( + "Unimplemented XLIVEBASE message app={:08X}, msg={:08X}, arg1={:08X}, " + "arg2={:08X}", + app_id(), message, buffer_ptr, buffer_length); + return X_E_FAIL; +} + +} // namespace apps +} // namespace xam +} // namespace kernel +} // namespace rex diff --git a/src/kernel/xam/apps/xmp_app.cpp b/src/kernel/xam/apps/xmp_app.cpp new file mode 100644 index 0000000..a5e9088 --- /dev/null +++ b/src/kernel/xam/apps/xmp_app.cpp @@ -0,0 +1,480 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +namespace rex { +namespace kernel { +namespace xam { +using namespace rex::system; +using namespace rex::system::xam; +namespace apps { +using namespace rex::system; + +XmpApp::XmpApp(KernelState* kernel_state) + : App(kernel_state, 0xFA), + state_(State::kIdle), + playback_client_(PlaybackClient::kTitle), + playback_mode_(PlaybackMode::kUnknown), + repeat_mode_(RepeatMode::kUnknown), + unknown_flags_(0), + volume_(1.0f), + active_playlist_(nullptr), + active_song_index_(0), + next_playlist_handle_(1), + next_song_handle_(1) {} + +X_HRESULT XmpApp::XMPGetStatus(uint32_t state_ptr) { + if (!XThread::GetCurrentThread()->main_thread()) { + // Some stupid games will hammer this on a thread - induce a delay + // here to keep from starving real threads. + rex::thread::Sleep(std::chrono::milliseconds(1)); + } + + REXKRNL_TRACE("XMPGetStatus({:08X})", state_ptr); + memory::store_and_swap(memory_->TranslateVirtual(state_ptr), + static_cast(state_)); + return X_E_SUCCESS; +} + +X_HRESULT XmpApp::XMPCreateTitlePlaylist(uint32_t songs_ptr, uint32_t song_count, + uint32_t playlist_name_ptr, + const std::u16string& playlist_name, uint32_t flags, + uint32_t out_song_handles, uint32_t out_playlist_handle) { + REXKRNL_DEBUG( + "XMPCreateTitlePlaylist({:08X}, {:08X}, {:08X}({}), {:08X}, {:08X}, " + "{:08X})", + songs_ptr, song_count, playlist_name_ptr, rex::string::to_utf8(playlist_name), flags, + out_song_handles, out_playlist_handle); + auto playlist = std::make_unique(); + playlist->handle = ++next_playlist_handle_; + playlist->name = playlist_name; + playlist->flags = flags; + if (songs_ptr) { + for (uint32_t i = 0; i < song_count; ++i) { + auto song = std::make_unique(); + song->handle = ++next_song_handle_; + uint8_t* song_base = memory_->TranslateVirtual(songs_ptr + (i * 36)); + song->file_path = memory::load_and_swap( + memory_->TranslateVirtual(memory::load_and_swap(song_base + 0))); + song->name = memory::load_and_swap( + memory_->TranslateVirtual(memory::load_and_swap(song_base + 4))); + song->artist = memory::load_and_swap( + memory_->TranslateVirtual(memory::load_and_swap(song_base + 8))); + song->album = memory::load_and_swap( + memory_->TranslateVirtual(memory::load_and_swap(song_base + 12))); + song->album_artist = memory::load_and_swap( + memory_->TranslateVirtual(memory::load_and_swap(song_base + 16))); + song->genre = memory::load_and_swap( + memory_->TranslateVirtual(memory::load_and_swap(song_base + 20))); + song->track_number = memory::load_and_swap(song_base + 24); + song->duration_ms = memory::load_and_swap(song_base + 28); + song->format = static_cast(memory::load_and_swap(song_base + 32)); + if (out_song_handles) { + memory::store_and_swap(memory_->TranslateVirtual(out_song_handles + (i * 4)), + song->handle); + } + playlist->songs.emplace_back(std::move(song)); + } + } + if (out_playlist_handle) { + memory::store_and_swap(memory_->TranslateVirtual(out_playlist_handle), + playlist->handle); + } + + auto global_lock = global_critical_region_.Acquire(); + playlists_.insert({playlist->handle, playlist.get()}); + playlist.release(); + return X_E_SUCCESS; +} + +X_HRESULT XmpApp::XMPDeleteTitlePlaylist(uint32_t playlist_handle) { + REXKRNL_DEBUG("XMPDeleteTitlePlaylist({:08X})", playlist_handle); + auto global_lock = global_critical_region_.Acquire(); + auto it = playlists_.find(playlist_handle); + if (it == playlists_.end()) { + REXKRNL_ERROR("Playlist {:08X} not found", playlist_handle); + return X_E_NOTFOUND; + } + auto playlist = it->second; + if (playlist == active_playlist_) { + XMPStop(0); + } + playlists_.erase(it); + delete playlist; + return X_E_SUCCESS; +} + +X_HRESULT XmpApp::XMPPlayTitlePlaylist(uint32_t playlist_handle, uint32_t song_handle) { + REXKRNL_DEBUG("XMPPlayTitlePlaylist({:08X}, {:08X})", playlist_handle, song_handle); + Playlist* playlist = nullptr; + { + auto global_lock = global_critical_region_.Acquire(); + auto it = playlists_.find(playlist_handle); + if (it == playlists_.end()) { + REXKRNL_ERROR("Playlist {:08X} not found", playlist_handle); + return X_E_NOTFOUND; + } + playlist = it->second; + } + + if (playback_client_ == PlaybackClient::kSystem) { + REXKRNL_WARN("XMPPlayTitlePlaylist: System playback is enabled!"); + return X_E_SUCCESS; + } + + // Start playlist? + REXKRNL_WARN("Playlist playback not supported"); + active_playlist_ = playlist; + active_song_index_ = 0; + state_ = State::kPlaying; + OnStateChanged(); + kernel_state_->BroadcastNotification(kMsgPlaybackBehaviorChanged, 1); + return X_E_SUCCESS; +} + +X_HRESULT XmpApp::XMPContinue() { + REXKRNL_DEBUG("XMPContinue()"); + if (state_ == State::kPaused) { + state_ = State::kPlaying; + } + OnStateChanged(); + return X_E_SUCCESS; +} + +X_HRESULT XmpApp::XMPStop(uint32_t unk) { + assert_zero(unk); + REXKRNL_DEBUG("XMPStop({:08X})", unk); + active_playlist_ = nullptr; // ? + active_song_index_ = 0; + state_ = State::kIdle; + OnStateChanged(); + return X_E_SUCCESS; +} + +X_HRESULT XmpApp::XMPPause() { + REXKRNL_DEBUG("XMPPause()"); + if (state_ == State::kPlaying) { + state_ = State::kPaused; + } + OnStateChanged(); + return X_E_SUCCESS; +} + +X_HRESULT XmpApp::XMPNext() { + REXKRNL_DEBUG("XMPNext()"); + if (!active_playlist_) { + return X_E_NOTFOUND; + } + state_ = State::kPlaying; + active_song_index_ = (active_song_index_ + 1) % active_playlist_->songs.size(); + OnStateChanged(); + return X_E_SUCCESS; +} + +X_HRESULT XmpApp::XMPPrevious() { + REXKRNL_DEBUG("XMPPrevious()"); + if (!active_playlist_) { + return X_E_NOTFOUND; + } + state_ = State::kPlaying; + if (!active_song_index_) { + active_song_index_ = static_cast(active_playlist_->songs.size()) - 1; + } else { + --active_song_index_; + } + OnStateChanged(); + return X_E_SUCCESS; +} + +void XmpApp::OnStateChanged() { + kernel_state_->BroadcastNotification(kMsgStateChanged, static_cast(state_)); +} + +X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, + uint32_t buffer_length) { + // NOTE: buffer_length may be zero or valid. + auto buffer = memory_->TranslateVirtual(buffer_ptr); + switch (message) { + case 0x00070002: { + assert_true(!buffer_length || buffer_length == 12); + uint32_t xmp_client = memory::load_and_swap(buffer + 0); + uint32_t storage_ptr = memory::load_and_swap(buffer + 4); + uint32_t song_handle = memory::load_and_swap(buffer + 8); // 0? + uint32_t playlist_handle = + memory::load_and_swap(memory_->TranslateVirtual(storage_ptr)); + assert_true(xmp_client == 0x00000002); + return XMPPlayTitlePlaylist(playlist_handle, song_handle); + } + case 0x00070003: { + assert_true(!buffer_length || buffer_length == 4); + uint32_t xmp_client = memory::load_and_swap(buffer + 0); + assert_true(xmp_client == 0x00000002); + return XMPContinue(); + } + case 0x00070004: { + assert_true(!buffer_length || buffer_length == 8); + uint32_t xmp_client = memory::load_and_swap(buffer + 0); + uint32_t unk = memory::load_and_swap(buffer + 4); + assert_true(xmp_client == 0x00000002); + return XMPStop(unk); + } + case 0x00070005: { + assert_true(!buffer_length || buffer_length == 4); + uint32_t xmp_client = memory::load_and_swap(buffer + 0); + assert_true(xmp_client == 0x00000002); + return XMPPause(); + } + case 0x00070006: { + assert_true(!buffer_length || buffer_length == 4); + uint32_t xmp_client = memory::load_and_swap(buffer + 0); + assert_true(xmp_client == 0x00000002); + return XMPNext(); + } + case 0x00070007: { + assert_true(!buffer_length || buffer_length == 4); + uint32_t xmp_client = memory::load_and_swap(buffer + 0); + assert_true(xmp_client == 0x00000002); + return XMPPrevious(); + } + case 0x00070008: { + assert_true(!buffer_length || buffer_length == 16); + struct { + rex::be xmp_client; + rex::be playback_mode; + rex::be repeat_mode; + rex::be flags; + }* args = memory_->TranslateVirtual(buffer_ptr); + static_assert_size(decltype(*args), 16); + + assert_true(args->xmp_client == 0x00000002 || args->xmp_client == 0x00000000); + REXKRNL_DEBUG("XMPSetPlaybackBehavior({:08X}, {:08X}, {:08X})", uint32_t(args->playback_mode), + uint32_t(args->repeat_mode), uint32_t(args->flags)); + playback_mode_ = static_cast(uint32_t(args->playback_mode)); + repeat_mode_ = static_cast(uint32_t(args->repeat_mode)); + unknown_flags_ = args->flags; + kernel_state_->BroadcastNotification(kMsgPlaybackBehaviorChanged, 0); + return X_E_SUCCESS; + } + case 0x00070009: { + assert_true(!buffer_length || buffer_length == 8); + uint32_t xmp_client = memory::load_and_swap(buffer + 0); + uint32_t state_ptr = memory::load_and_swap(buffer + 4); // out ptr to 4b - expect 0 + assert_true(xmp_client == 0x00000002); + return XMPGetStatus(state_ptr); + } + case 0x0007000B: { + assert_true(!buffer_length || buffer_length == 8); + struct { + rex::be xmp_client; + rex::be volume_ptr; + }* args = memory_->TranslateVirtual(buffer_ptr); + static_assert_size(decltype(*args), 8); + + assert_true(args->xmp_client == 0x00000002); + REXKRNL_DEBUG("XMPGetVolume({:08X})", uint32_t(args->volume_ptr)); + memory::store_and_swap(memory_->TranslateVirtual(args->volume_ptr), volume_); + return X_E_SUCCESS; + } + case 0x0007000C: { + assert_true(!buffer_length || buffer_length == 8); + struct { + rex::be xmp_client; + rex::be value; + }* args = memory_->TranslateVirtual(buffer_ptr); + static_assert_size(decltype(*args), 8); + + assert_true(args->xmp_client == 0x00000002); + REXKRNL_DEBUG("XMPSetVolume({:g})", float(args->value)); + volume_ = args->value; + return X_E_SUCCESS; + } + case 0x0007000D: { + assert_true(!buffer_length || buffer_length == 36); + struct { + rex::be xmp_client; + rex::be storage_ptr; + rex::be storage_size; + rex::be songs_ptr; + rex::be song_count; + rex::be playlist_name_ptr; + rex::be flags; + rex::be song_handles_ptr; + rex::be playlist_handle_ptr; + }* args = memory_->TranslateVirtual(buffer_ptr); + static_assert_size(decltype(*args), 36); + + memory::store_and_swap(memory_->TranslateVirtual(args->playlist_handle_ptr), + args->storage_ptr); + assert_true(args->xmp_client == 0x00000002 || args->xmp_client == 0x00000000); + std::u16string playlist_name; + if (!args->playlist_name_ptr) { + playlist_name = u""; + } else { + playlist_name = memory::load_and_swap( + memory_->TranslateVirtual(args->playlist_name_ptr)); + } + // dummy_alloc_ptr is the result of a XamAlloc of storage_size. + assert_true(uint32_t(args->storage_size) == 4 + uint32_t(args->song_count) * 128); + return XMPCreateTitlePlaylist(args->songs_ptr, args->song_count, args->playlist_name_ptr, + playlist_name, args->flags, args->song_handles_ptr, + args->storage_ptr); + } + case 0x0007000E: { + assert_true(!buffer_length || buffer_length == 12); + struct { + rex::be xmp_client; + rex::be unk_ptr; // 0 + rex::be info_ptr; + }* args = memory_->TranslateVirtual(buffer_ptr); + static_assert_size(decltype(*args), 12); + + auto info = memory_->TranslateVirtual(args->info_ptr); + assert_true(args->xmp_client == 0x00000002); + assert_zero(args->unk_ptr); + REXKRNL_ERROR("XMPGetInfo?({:08X}, {:08X})", uint32_t(args->unk_ptr), + uint32_t(args->info_ptr)); + if (!active_playlist_) { + return X_E_FAIL; + } + auto& song = active_playlist_->songs[active_song_index_]; + memory::store_and_swap(info + 0, song->handle); + memory::store_and_swap(info + 4 + 572 + 0, song->name); + memory::store_and_swap(info + 4 + 572 + 40, song->artist); + memory::store_and_swap(info + 4 + 572 + 80, song->album); + memory::store_and_swap(info + 4 + 572 + 120, song->album_artist); + memory::store_and_swap(info + 4 + 572 + 160, song->genre); + memory::store_and_swap(info + 4 + 572 + 200, song->track_number); + memory::store_and_swap(info + 4 + 572 + 204, song->duration_ms); + memory::store_and_swap(info + 4 + 572 + 208, static_cast(song->format)); + return X_E_SUCCESS; + } + case 0x00070013: { + assert_true(!buffer_length || buffer_length == 8); + struct { + rex::be xmp_client; + rex::be storage_ptr; + }* args = memory_->TranslateVirtual(buffer_ptr); + static_assert_size(decltype(*args), 8); + + uint32_t playlist_handle = + memory::load_and_swap(memory_->TranslateVirtual(args->storage_ptr)); + assert_true(args->xmp_client == 0x00000002 || args->xmp_client == 0x00000000); + return XMPDeleteTitlePlaylist(playlist_handle); + } + case 0x0007001A: { + // XMPSetPlaybackController + assert_true(!buffer_length || buffer_length == 12); + struct { + rex::be xmp_client; + rex::be controller; + rex::be playback_client; + }* args = memory_->TranslateVirtual(buffer_ptr); + static_assert_size(decltype(*args), 12); + + assert_true((args->xmp_client == 0x00000002 && args->controller == 0x00000000) || + (args->xmp_client == 0x00000000 && args->controller == 0x00000001)); + REXKRNL_DEBUG("XMPSetPlaybackController({:08X}, {:08X})", uint32_t(args->controller), + uint32_t(args->playback_client)); + + playback_client_ = PlaybackClient(uint32_t(args->playback_client)); + kernel_state_->BroadcastNotification(kMsgPlaybackControllerChanged, !args->playback_client); + return X_E_SUCCESS; + } + case 0x0007001B: { + // XMPGetPlaybackController + assert_true(!buffer_length || buffer_length == 12); + struct { + rex::be xmp_client; + rex::be controller_ptr; + rex::be locked_ptr; + }* args = memory_->TranslateVirtual(buffer_ptr); + static_assert_size(decltype(*args), 12); + + assert_true(args->xmp_client == 0x00000002); + REXKRNL_DEBUG("XMPGetPlaybackController({:08X}, {:08X}, {:08X})", uint32_t(args->xmp_client), + uint32_t(args->controller_ptr), uint32_t(args->locked_ptr)); + memory::store_and_swap(memory_->TranslateVirtual(args->controller_ptr), 0); + memory::store_and_swap(memory_->TranslateVirtual(args->locked_ptr), 0); + + if (!XThread::GetCurrentThread()->main_thread()) { + // Atrain spawns a thread 82437FD0 to call this in a tight loop forever. + rex::thread::Sleep(std::chrono::milliseconds(10)); + } + + return X_E_SUCCESS; + } + case 0x00070029: { + // XMPGetPlaybackBehavior + assert_true(!buffer_length || buffer_length == 16); + struct { + rex::be xmp_client; + rex::be playback_mode_ptr; + rex::be repeat_mode_ptr; + rex::be unk3_ptr; + }* args = memory_->TranslateVirtual(buffer_ptr); + static_assert_size(decltype(*args), 16); + + assert_true(args->xmp_client == 0x00000002 || args->xmp_client == 0x00000000); + REXKRNL_DEBUG("XMPGetPlaybackBehavior({:08X}, {:08X}, {:08X})", + uint32_t(args->playback_mode_ptr), uint32_t(args->repeat_mode_ptr), + uint32_t(args->unk3_ptr)); + if (args->playback_mode_ptr) { + memory::store_and_swap(memory_->TranslateVirtual(args->playback_mode_ptr), + static_cast(playback_mode_)); + } + if (args->repeat_mode_ptr) { + memory::store_and_swap(memory_->TranslateVirtual(args->repeat_mode_ptr), + static_cast(repeat_mode_)); + } + if (args->unk3_ptr) { + memory::store_and_swap(memory_->TranslateVirtual(args->unk3_ptr), unknown_flags_); + } + return X_E_SUCCESS; + } + case 0x0007002E: { + assert_true(!buffer_length || buffer_length == 12); + // Query of size for XamAlloc - the result of the alloc is passed to + // 0x0007000D. + struct { + rex::be xmp_client; + rex::be song_count; + rex::be size_ptr; + }* args = memory_->TranslateVirtual(buffer_ptr); + static_assert_size(decltype(*args), 12); + + assert_true(args->xmp_client == 0x00000002 || args->xmp_client == 0x00000000); + // We don't use the storage, so just fudge the number. + memory::store_and_swap(memory_->TranslateVirtual(args->size_ptr), + 4 + uint32_t(args->song_count) * 128); + return X_E_SUCCESS; + } + case 0x0007003D: { + // XMPCaptureOutput - not sure how this works :/ + REXKRNL_DEBUG("XMPCaptureOutput(...)"); + assert_always("XMP output not unimplemented"); + return X_E_FAIL; + } + } + REXKRNL_ERROR( + "Unimplemented XMP message app={:08X}, msg={:08X}, arg1={:08X}, " + "arg2={:08X}", + app_id(), message, buffer_ptr, buffer_length); + return X_E_FAIL; +} + +} // namespace apps +} // namespace xam +} // namespace kernel +} // namespace rex diff --git a/src/kernel/xam/export_table.inc b/src/kernel/xam/export_table.inc new file mode 100644 index 0000000..2e22f56 --- /dev/null +++ b/src/kernel/xam/export_table.inc @@ -0,0 +1,1749 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +// This is a partial file designed to be included by other files when +// constructing various tables. + +// clang-format off + +XE_EXPORT(xam, 0x00000001, NetDll_WSAStartup, kFunction), +XE_EXPORT(xam, 0x00000002, NetDll_WSACleanup, kFunction), +XE_EXPORT(xam, 0x00000003, NetDll_socket, kFunction), +XE_EXPORT(xam, 0x00000004, NetDll_closesocket, kFunction), +XE_EXPORT(xam, 0x00000005, NetDll_shutdown, kFunction), +XE_EXPORT(xam, 0x00000006, NetDll_ioctlsocket, kFunction), +XE_EXPORT(xam, 0x00000007, NetDll_setsockopt, kFunction), +XE_EXPORT(xam, 0x00000008, NetDll_getsockopt, kFunction), +XE_EXPORT(xam, 0x00000009, NetDll_getsockname, kFunction), +XE_EXPORT(xam, 0x0000000A, NetDll_getpeername, kFunction), +XE_EXPORT(xam, 0x0000000B, NetDll_bind, kFunction), +XE_EXPORT(xam, 0x0000000C, NetDll_connect, kFunction), +XE_EXPORT(xam, 0x0000000D, NetDll_listen, kFunction), +XE_EXPORT(xam, 0x0000000E, NetDll_accept, kFunction), +XE_EXPORT(xam, 0x0000000F, NetDll_select, kFunction), +XE_EXPORT(xam, 0x00000010, NetDll_WSAGetOverlappedResult, kFunction), +XE_EXPORT(xam, 0x00000011, NetDll_WSACancelOverlappedIO, kFunction), +XE_EXPORT(xam, 0x00000012, NetDll_recv, kFunction), +XE_EXPORT(xam, 0x00000013, NetDll_WSARecv, kFunction), +XE_EXPORT(xam, 0x00000014, NetDll_recvfrom, kFunction), +XE_EXPORT(xam, 0x00000015, NetDll_WSARecvFrom, kFunction), +XE_EXPORT(xam, 0x00000016, NetDll_send, kFunction), +XE_EXPORT(xam, 0x00000017, NetDll_WSASend, kFunction), +XE_EXPORT(xam, 0x00000018, NetDll_sendto, kFunction), +XE_EXPORT(xam, 0x00000019, NetDll_WSASendTo, kFunction), +XE_EXPORT(xam, 0x0000001A, NetDll_inet_addr, kFunction), +XE_EXPORT(xam, 0x0000001B, NetDll_WSAGetLastError, kFunction), +XE_EXPORT(xam, 0x0000001C, NetDll_WSASetLastError, kFunction), +XE_EXPORT(xam, 0x0000001D, NetDll_WSACreateEvent, kFunction), +XE_EXPORT(xam, 0x0000001E, NetDll_WSACloseEvent, kFunction), +XE_EXPORT(xam, 0x0000001F, NetDll_WSASetEvent, kFunction), +XE_EXPORT(xam, 0x00000020, NetDll_WSAResetEvent, kFunction), +XE_EXPORT(xam, 0x00000021, NetDll_WSAWaitForMultipleEvents, kFunction), +XE_EXPORT(xam, 0x00000022, NetDll___WSAFDIsSet, kFunction), +XE_EXPORT(xam, 0x00000023, NetDll_WSAEventSelect, kFunction), +XE_EXPORT(xam, 0x00000024, NetDll_WSAStartupEx, kFunction), +XE_EXPORT(xam, 0x00000033, NetDll_XNetStartup, kFunction), +XE_EXPORT(xam, 0x00000034, NetDll_XNetCleanup, kFunction), +XE_EXPORT(xam, 0x00000035, NetDll_XNetRandom, kFunction), +XE_EXPORT(xam, 0x00000036, NetDll_XNetCreateKey, kFunction), +XE_EXPORT(xam, 0x00000037, NetDll_XNetRegisterKey, kFunction), +XE_EXPORT(xam, 0x00000038, NetDll_XNetUnregisterKey, kFunction), +XE_EXPORT(xam, 0x00000039, NetDll_XNetXnAddrToInAddr, kFunction), +XE_EXPORT(xam, 0x0000003A, NetDll_XNetServerToInAddr, kFunction), +XE_EXPORT(xam, 0x0000003B, NetDll_XNetTsAddrToInAddr, kFunction), +XE_EXPORT(xam, 0x0000003C, NetDll_XNetInAddrToXnAddr, kFunction), +XE_EXPORT(xam, 0x0000003D, NetDll_XNetInAddrToServer, kFunction), +XE_EXPORT(xam, 0x0000003E, NetDll_XNetInAddrToString, kFunction), +XE_EXPORT(xam, 0x0000003F, NetDll_XNetUnregisterInAddr, kFunction), +XE_EXPORT(xam, 0x00000040, NetDll_XNetXnAddrToMachineId, kFunction), +XE_EXPORT(xam, 0x00000041, NetDll_XNetConnect, kFunction), +XE_EXPORT(xam, 0x00000042, NetDll_XNetGetConnectStatus, kFunction), +XE_EXPORT(xam, 0x00000043, NetDll_XNetDnsLookup, kFunction), +XE_EXPORT(xam, 0x00000044, NetDll_XNetDnsRelease, kFunction), +XE_EXPORT(xam, 0x00000045, NetDll_XNetQosListen, kFunction), +XE_EXPORT(xam, 0x00000046, NetDll_XNetQosLookup, kFunction), +XE_EXPORT(xam, 0x00000047, NetDll_XNetQosServiceLookup, kFunction), +XE_EXPORT(xam, 0x00000048, NetDll_XNetQosRelease, kFunction), +XE_EXPORT(xam, 0x00000049, NetDll_XNetGetTitleXnAddr, kFunction), +XE_EXPORT(xam, 0x0000004A, NetDll_XNetGetDebugXnAddr, kFunction), +XE_EXPORT(xam, 0x0000004B, NetDll_XNetGetEthernetLinkStatus, kFunction), +XE_EXPORT(xam, 0x0000004C, NetDll_XNetGetBroadcastVersionStatus, kFunction), +XE_EXPORT(xam, 0x0000004D, NetDll_XNetQosGetListenStats, kFunction), +XE_EXPORT(xam, 0x0000004E, NetDll_XNetGetOpt, kFunction), +XE_EXPORT(xam, 0x0000004F, NetDll_XNetSetOpt, kFunction), +XE_EXPORT(xam, 0x00000050, NetDll_XNetStartupEx, kFunction), +XE_EXPORT(xam, 0x00000051, NetDll_XNetReplaceKey, kFunction), +XE_EXPORT(xam, 0x00000052, NetDll_XNetGetXnAddrPlatform, kFunction), +XE_EXPORT(xam, 0x00000053, NetDll_XNetGetSystemLinkPort, kFunction), +XE_EXPORT(xam, 0x00000054, NetDll_XNetSetSystemLinkPort, kFunction), +XE_EXPORT(xam, 0x00000055, NetDll_XNetDnsReverseLookup, kFunction), +XE_EXPORT(xam, 0x00000056, NetDll_XNetDnsReverseRelease, kFunction), +XE_EXPORT(xam, 0x00000065, NetDll_XnpLoadConfigParams, kFunction), +XE_EXPORT(xam, 0x00000066, NetDll_XnpSaveConfigParams, kFunction), +XE_EXPORT(xam, 0x00000067, NetDll_XnpConfigUPnP, kFunction), +XE_EXPORT(xam, 0x00000068, NetDll_XnpConfig, kFunction), +XE_EXPORT(xam, 0x00000069, NetDll_XnpGetConfigStatus, kFunction), +XE_EXPORT(xam, 0x0000006A, NetDll_XnpLoadMachineAccount, kFunction), +XE_EXPORT(xam, 0x0000006B, NetDll_XnpSaveMachineAccount, kFunction), +XE_EXPORT(xam, 0x0000006C, NetDll_XnpCapture, kFunction), +XE_EXPORT(xam, 0x0000006D, NetDll_XnpEthernetInterceptSetCallbacks, kFunction), +XE_EXPORT(xam, 0x0000006E, NetDll_XnpEthernetInterceptXmit, kFunction), +XE_EXPORT(xam, 0x0000006F, NetDll_XnpEthernetInterceptRecv, kFunction), +XE_EXPORT(xam, 0x00000070, NetDll_XnpLogonGetStatus, kFunction), +XE_EXPORT(xam, 0x00000071, NetDll_XnpLogonGetQFlags, kFunction), +XE_EXPORT(xam, 0x00000072, NetDll_XnpLogonSetQFlags, kFunction), +XE_EXPORT(xam, 0x00000073, NetDll_XnpLogonSetQEvent, kFunction), +XE_EXPORT(xam, 0x00000074, NetDll_XnpLogonClearQEvent, kFunction), +XE_EXPORT(xam, 0x00000075, NetDll_XnpLogonGetQVals, kFunction), +XE_EXPORT(xam, 0x00000076, NetDll_XnpLogonSetQVals, kFunction), +XE_EXPORT(xam, 0x00000077, NetDll_XnpLogonSetPState, kFunction), +XE_EXPORT(xam, 0x00000078, NetDll_XnpGetVlanXboxName, kFunction), +XE_EXPORT(xam, 0x00000079, NetDll_XnpSetVlanXboxName, kFunction), +XE_EXPORT(xam, 0x0000007A, NetDll_XnpGetActiveSocketList, kFunction), +XE_EXPORT(xam, 0x0000007B, NetDll_XnpNoteSystemTime, kFunction), +XE_EXPORT(xam, 0x0000007C, NetDll_XnpRegisterKeyForCallerType, kFunction), +XE_EXPORT(xam, 0x0000007D, NetDll_XnpUnregisterKeyForCallerType, kFunction), +XE_EXPORT(xam, 0x0000007E, NetDll_XnpLogonGetChallenge, kFunction), +XE_EXPORT(xam, 0x0000007F, NetDll_XnpLogonClearChallenge, kFunction), +XE_EXPORT(xam, 0x00000080, NetDll_XnpLogonSetChallengeResponse, kFunction), +XE_EXPORT(xam, 0x00000081, NetDll_XnpGetSecAssocList, kFunction), +XE_EXPORT(xam, 0x00000082, NetDll_XnpGetKeyList, kFunction), +XE_EXPORT(xam, 0x00000083, NetDll_XnpGetQosLookupList, kFunction), +XE_EXPORT(xam, 0x00000084, NetDll_XnpPersistTitleState, kFunction), +XE_EXPORT(xam, 0x00000085, NetDll_XnpReplaceKeyForCallerType, kFunction), +XE_EXPORT(xam, 0x00000086, NetDll_XnpEthernetInterceptSetExtendedReceiveCallback, kFunction), +XE_EXPORT(xam, 0x00000087, NetDll_XnpQosHistoryLoad, kFunction), +XE_EXPORT(xam, 0x00000088, NetDll_XnpQosHistorySaveMeasurements, kFunction), +XE_EXPORT(xam, 0x00000089, NetDll_XnpQosHistoryGetEntries, kFunction), +XE_EXPORT(xam, 0x0000008A, NetDll_XnpQosHistoryGetAggregateMeasurement, kFunction), +XE_EXPORT(xam, 0x0000008B, NetDll_XnpToolSetCallbacks, kFunction), +XE_EXPORT(xam, 0x0000008C, NetDll_XnpToolIpProxyInject, kFunction), +XE_EXPORT(xam, 0x0000008D, NetDll_XnpUpdateConfigParams, kFunction), +XE_EXPORT(xam, 0x0000008E, NetDll_XnpEthernetInterceptXmitAsIp, kFunction), +XE_EXPORT(xam, 0x0000008F, NetDll_XnpConfigUPnPPortAndExternalAddr, kFunction), +XE_EXPORT(xam, 0x00000097, NetDll_XmlDownloadStart, kFunction), +XE_EXPORT(xam, 0x00000098, NetDll_XmlDownloadContinue, kFunction), +XE_EXPORT(xam, 0x00000099, NetDll_XmlDownloadStop, kFunction), +XE_EXPORT(xam, 0x0000009A, NetDll_XmlDownloadGetParseTime, kFunction), +XE_EXPORT(xam, 0x0000009B, NetDll_XmlDownloadGetReceivedDataSize, kFunction), +XE_EXPORT(xam, 0x000000C6, XnpGetXwppMemoryLogSnapshot, kFunction), +XE_EXPORT(xam, 0x000000C7, XnpGetXwppRuntimeFilter, kFunction), +XE_EXPORT(xam, 0x000000C9, NetDll_XHttpStartup, kFunction), +XE_EXPORT(xam, 0x000000CA, NetDll_XHttpShutdown, kFunction), +XE_EXPORT(xam, 0x000000CB, NetDll_XHttpOpen, kFunction), +XE_EXPORT(xam, 0x000000CC, NetDll_XHttpCloseHandle, kFunction), +XE_EXPORT(xam, 0x000000CD, NetDll_XHttpConnect, kFunction), +XE_EXPORT(xam, 0x000000CE, NetDll_XHttpSetStatusCallback, kFunction), +XE_EXPORT(xam, 0x000000CF, NetDll_XHttpOpenRequest, kFunction), +XE_EXPORT(xam, 0x000000D0, NetDll_XHttpOpenRequestUsingMemory, kFunction), +XE_EXPORT(xam, 0x000000D1, NetDll_XHttpSendRequest, kFunction), +XE_EXPORT(xam, 0x000000D2, NetDll_XHttpReceiveResponse, kFunction), +XE_EXPORT(xam, 0x000000D3, NetDll_XHttpQueryHeaders, kFunction), +XE_EXPORT(xam, 0x000000D4, NetDll_XHttpReadData, kFunction), +XE_EXPORT(xam, 0x000000D5, NetDll_XHttpWriteData, kFunction), +XE_EXPORT(xam, 0x000000D6, NetDll_XHttpQueryOption, kFunction), +XE_EXPORT(xam, 0x000000D7, NetDll_XHttpSetOption, kFunction), +XE_EXPORT(xam, 0x000000D8, NetDll_XHttpDoWork, kFunction), +XE_EXPORT(xam, 0x000000D9, NetDll_XHttpSetCredentials, kFunction), +XE_EXPORT(xam, 0x000000DA, NetDll_XHttpQueryAuthSchemes, kFunction), +XE_EXPORT(xam, 0x000000DB, NetDll_XHttpCrackUrlW, kFunction), +XE_EXPORT(xam, 0x000000DC, NetDll_XHttpCrackUrl, kFunction), +XE_EXPORT(xam, 0x000000DD, NetDll_XHttpCreateUrl, kFunction), +XE_EXPORT(xam, 0x000000DE, NetDll_XHttpCreateUrlW, kFunction), +XE_EXPORT(xam, 0x000000DF, NetDll_XHttpResetPerfCounters, kFunction), +XE_EXPORT(xam, 0x000000E0, NetDll_XHttpGetPerfCounters, kFunction), +XE_EXPORT(xam, 0x000000FB, NetDll_UpnpStartup, kFunction), +XE_EXPORT(xam, 0x000000FC, NetDll_UpnpCleanup, kFunction), +XE_EXPORT(xam, 0x000000FD, NetDll_UpnpSearchCreate, kFunction), +XE_EXPORT(xam, 0x000000FE, NetDll_UpnpSearchGetDevices, kFunction), +XE_EXPORT(xam, 0x000000FF, NetDll_UpnpDescribeCreate, kFunction), +XE_EXPORT(xam, 0x00000100, NetDll_UpnpDescribeGetResults, kFunction), +XE_EXPORT(xam, 0x00000101, NetDll_UpnpActionCalculateWorkBufferSize, kFunction), +XE_EXPORT(xam, 0x00000102, NetDll_UpnpActionCreate, kFunction), +XE_EXPORT(xam, 0x00000103, NetDll_UpnpActionGetResults, kFunction), +XE_EXPORT(xam, 0x00000104, NetDll_UpnpEventCreate, kFunction), +XE_EXPORT(xam, 0x00000105, NetDll_UpnpEventGetCurrentState, kFunction), +XE_EXPORT(xam, 0x00000106, NetDll_UpnpEventUnsubscribe, kFunction), +XE_EXPORT(xam, 0x00000107, NetDll_UpnpDoWork, kFunction), +XE_EXPORT(xam, 0x00000108, NetDll_UpnpCloseHandle, kFunction), +XE_EXPORT(xam, 0x0000012D, XNetLogonGetLoggedOnUsers, kFunction), +XE_EXPORT(xam, 0x0000012E, XNetLogonGetNatType, kFunction), +XE_EXPORT(xam, 0x0000012F, XNetLogonTaskStart, kFunction), +XE_EXPORT(xam, 0x00000130, XNetLogonTaskClose, kFunction), +XE_EXPORT(xam, 0x00000131, XNetLogonTaskContinue, kFunction), +XE_EXPORT(xam, 0x00000132, XNetLogonGetServiceInfo, kFunction), +XE_EXPORT(xam, 0x00000133, XNetLogonGetUserPrivileges, kFunction), +XE_EXPORT(xam, 0x00000134, XNetLogonSetConsoleCertificate, kFunction), +XE_EXPORT(xam, 0x00000135, XNetLogonGetMachineID, kFunction), +XE_EXPORT(xam, 0x00000136, XNetLogonGetTitleID, kFunction), +XE_EXPORT(xam, 0x00000137, XNetLogonGetTitleVersion, kFunction), +XE_EXPORT(xam, 0x00000138, XNetLogonGetServiceNetworkID, kFunction), +XE_EXPORT(xam, 0x00000139, XNetLogonGetDnsString, kFunction), +XE_EXPORT(xam, 0x0000013A, XNetLogonSetTitleID, kFunction), +XE_EXPORT(xam, 0x0000013B, XNetLogonGetExtendedStatus, kFunction), +XE_EXPORT(xam, 0x0000013C, XNetLogonClearTicketCaches, kFunction), +XE_EXPORT(xam, 0x0000013D, XNetLogonInitOverrideInfo, kFunction), +XE_EXPORT(xam, 0x0000013E, XNetLogonGetLastUPnPStatus, kFunction), +XE_EXPORT(xam, 0x0000013F, XNetLogonGetFlowToken, kFunction), +XE_EXPORT(xam, 0x00000140, XNetLogonGetTicketOpt, kFunction), +XE_EXPORT(xam, 0x00000141, XNetLogonSetTicketOpt, kFunction), +XE_EXPORT(xam, 0x00000142, XNetLogonGetState, kFunction), +XE_EXPORT(xam, 0x00000190, XamInputGetCapabilities, kFunction), +XE_EXPORT(xam, 0x00000191, XamInputGetState, kFunction), +XE_EXPORT(xam, 0x00000192, XamInputSetState, kFunction), +XE_EXPORT(xam, 0x00000193, XamInputGetKeystroke, kFunction), +XE_EXPORT(xam, 0x00000194, XamInputEnableAutobind, kFunction), +XE_EXPORT(xam, 0x00000195, XamInputRawState, kFunction), +XE_EXPORT(xam, 0x00000196, XamEnableSystemAppInput, kFunction), +XE_EXPORT(xam, 0x00000197, XamInputGetDeviceStats, kFunction), +XE_EXPORT(xam, 0x00000198, XamInputGetKeystrokeEx, kFunction), +XE_EXPORT(xam, 0x00000199, XamInputGetKeystrokeHud, kFunction), +XE_EXPORT(xam, 0x0000019A, XamInputSetLayoutKeyboard, kFunction), +XE_EXPORT(xam, 0x0000019B, XamInputToggleKeyLocks, kFunction), +XE_EXPORT(xam, 0x0000019C, XamInputResetLayoutKeyboard, kFunction), +XE_EXPORT(xam, 0x0000019D, XamInputGetKeystrokeHudEx, kFunction), +XE_EXPORT(xam, 0x0000019E, XamInputSetKeyboardTranslationHud, kFunction), +XE_EXPORT(xam, 0x0000019F, XamSetInactivityTime, kFunction), +XE_EXPORT(xam, 0x000001A0, XamEnableInactivityProcessing, kFunction), +XE_EXPORT(xam, 0x000001A1, XamResetInactivity, kFunction), +XE_EXPORT(xam, 0x000001A2, XamSetInactivityTimeFromConfig, kFunction), +XE_EXPORT(xam, 0x000001A3, XamLoaderGetMediaInfo, kFunction), +XE_EXPORT(xam, 0x000001A4, XamLoaderLaunchTitle, kFunction), +XE_EXPORT(xam, 0x000001A5, XamLoaderLaunchTitleEx, kFunction), +XE_EXPORT(xam, 0x000001A6, XamLoaderSetLaunchData, kFunction), +XE_EXPORT(xam, 0x000001A7, XamLoaderGetLaunchDataSize, kFunction), +XE_EXPORT(xam, 0x000001A8, XamLoaderGetLaunchData, kFunction), +XE_EXPORT(xam, 0x000001A9, XamLoaderTerminateTitle, kFunction), +XE_EXPORT(xam, 0x000001AA, XamLoaderGetDvdTrayState, kFunction), +XE_EXPORT(xam, 0x000001AB, XamLoaderGetGameInfo, kFunction), +XE_EXPORT(xam, 0x000001AC, XamLoaderLaunchTitleOnDvd, kFunction), +XE_EXPORT(xam, 0x000001AD, XamLoaderSetSpindleSpeed, kFunction), +XE_EXPORT(xam, 0x000001AE, XamTaskCreateQueue, kFunction), +XE_EXPORT(xam, 0x000001AF, XamTaskSchedule, kFunction), +XE_EXPORT(xam, 0x000001B0, XamTaskReschedule, kFunction), +XE_EXPORT(xam, 0x000001B1, XamTaskCloseHandle, kFunction), +XE_EXPORT(xam, 0x000001B2, XamTaskCancel, kFunction), +XE_EXPORT(xam, 0x000001B3, XamTaskShouldExit, kFunction), +XE_EXPORT(xam, 0x000001B4, XamTaskWaitOnCompletion, kFunction), +XE_EXPORT(xam, 0x000001B5, XamTaskModify, kFunction), +XE_EXPORT(xam, 0x000001B6, XamTaskGetCurrentTask, kFunction), +XE_EXPORT(xam, 0x000001B7, XamTaskGetAttributes, kFunction), +XE_EXPORT(xam, 0x000001B8, XamExecutingOnBehalfOfTitle, kFunction), +XE_EXPORT(xam, 0x000001B9, XamInputSendStayAliveRequest, kFunction), +XE_EXPORT(xam, 0x000001BA, XamInputGetUserVibrationLevel, kFunction), +XE_EXPORT(xam, 0x000001BB, XamIsSystemTitleId, kFunction), +XE_EXPORT(xam, 0x000001BC, XamLoaderIsTitleTerminatePending, kFunction), +XE_EXPORT(xam, 0x000001BD, XamInputSetTextMessengerIndicator, kFunction), +XE_EXPORT(xam, 0x000001BE, XamLoaderGetPriorTitleId, kFunction), +XE_EXPORT(xam, 0x000001BF, XamIsXbox1TitleId, kFunction), +XE_EXPORT(xam, 0x000001C0, XamInputSetKeyLocks, kFunction), +XE_EXPORT(xam, 0x000001C1, XamInputGetKeyLocks, kFunction), +XE_EXPORT(xam, 0x000001C2, XamTaskGetStatus, kFunction), +XE_EXPORT(xam, 0x000001C3, XamGetRootObj, kFunction), +XE_EXPORT(xam, 0x000001C4, XamDevAuthSetFault, kFunction), +XE_EXPORT(xam, 0x000001C5, XamGetDefaultSystemImage, kFunction), +XE_EXPORT(xam, 0x000001C6, XamGetWCNConfigFile, kFunction), +XE_EXPORT(xam, 0x000001C7, XamSetPowerMode, kFunction), +XE_EXPORT(xam, 0x000001C8, XamExecuteChallenge, kFunction), +XE_EXPORT(xam, 0x000001C9, XamGetDefaultImage, kFunction), +XE_EXPORT(xam, 0x000001CA, XamMuteSound, kFunction), +XE_EXPORT(xam, 0x000001CB, XamGetOnlineSchema, kFunction), +XE_EXPORT(xam, 0x000001CC, XamSetDashContext, kFunction), +XE_EXPORT(xam, 0x000001CD, XamGetDashContext, kFunction), +XE_EXPORT(xam, 0x000001CE, XamIsCurrentTitleDash, kFunction), +XE_EXPORT(xam, 0x000001CF, XamGetCurrentTitleId, kFunction), +XE_EXPORT(xam, 0x000001D0, XamSetCurrentTitleDash, kFunction), +XE_EXPORT(xam, 0x000001D1, XamAllocHeapFreeSpace, kFunction), +XE_EXPORT(xam, 0x000001D2, XamSetDashContextEx, kFunction), +XE_EXPORT(xam, 0x000001D3, XamGetDashContextEx, kFunction), +XE_EXPORT(xam, 0x000001D4, XamSetHudContext, kFunction), +XE_EXPORT(xam, 0x000001D5, XamGetHudContext, kFunction), +XE_EXPORT(xam, 0x000001D6, XCustomGetBannerImage, kFunction), +XE_EXPORT(xam, 0x000001D7, Refresh, kFunction), +XE_EXPORT(xam, 0x000001D8, XCustomSetAction, kFunction), +XE_EXPORT(xam, 0x000001D9, XCustomGetLastActionPress, kFunction), +XE_EXPORT(xam, 0x000001DA, XCustomSetDynamicActions, kFunction), +XE_EXPORT(xam, 0x000001DB, XCustomBroadcastActionEvent, kFunction), +XE_EXPORT(xam, 0x000001DC, XCustomGetLastActionPressEx, kFunction), +XE_EXPORT(xam, 0x000001DD, XCustomRegisterDynamicActions, kFunction), +XE_EXPORT(xam, 0x000001DE, XCustomUnregisterDynamicActions, kFunction), +XE_EXPORT(xam, 0x000001DF, XCustomGetCurrentGamercard, kFunction), +XE_EXPORT(xam, 0x000001E0, XamDbgPrint, kFunction), +XE_EXPORT(xam, 0x000001E1, XamDbgSetOutputLevel, kFunction), +XE_EXPORT(xam, 0x000001E2, XamDbgSetBreakLevel, kFunction), +XE_EXPORT(xam, 0x000001E3, XamLoaderGetMediaInfoEx, kFunction), +XE_EXPORT(xam, 0x000001E4, XamLoaderSetGameInfo, kFunction), +XE_EXPORT(xam, 0x000001E5, XamFormatMessage, kFunction), +XE_EXPORT(xam, 0x000001E6, XamUniSortCmpString, kFunction), +XE_EXPORT(xam, 0x000001E7, XamFormatTimeString, kFunction), +XE_EXPORT(xam, 0x000001E8, XamFormatDateString, kFunction), +XE_EXPORT(xam, 0x000001E9, XamGetLocaleDateFormat, kFunction), +XE_EXPORT(xam, 0x000001EA, XamAlloc, kFunction), +XE_EXPORT(xam, 0x000001EB, XamAllocEx, kFunction), +XE_EXPORT(xam, 0x000001EC, XamFree, kFunction), +XE_EXPORT(xam, 0x000001ED, XamAllocSize, kFunction), +XE_EXPORT(xam, 0x000001EE, XamAllocMountIPTVHeap, kFunction), +XE_EXPORT(xam, 0x000001EF, XamAllocUnmountIPTVHeap, kFunction), +XE_EXPORT(xam, 0x000001F0, XamAllocFreeIPTVHeap, kFunction), +XE_EXPORT(xam, 0x000001F1, XamDeviceRemap, kFunction), +XE_EXPORT(xam, 0x000001F2, XamLoaderGetClearCache, kFunction), +XE_EXPORT(xam, 0x000001F3, XamLoaderSetClearCache, kFunction), +XE_EXPORT(xam, 0x000001F4, XMsgInProcessCall, kFunction), +XE_EXPORT(xam, 0x000001F5, XMsgCompleteIORequest, kFunction), +XE_EXPORT(xam, 0x000001F6, XMsgSystemProcessCall, kFunction), +XE_EXPORT(xam, 0x000001F7, XMsgStartIORequest, kFunction), +XE_EXPORT(xam, 0x000001F8, XMsgCancelIORequest, kFunction), +XE_EXPORT(xam, 0x000001F9, XMsgAcquireAsyncMessageFromOverlapped, kFunction), +XE_EXPORT(xam, 0x000001FA, XMsgReleaseAsyncMessageToOverlapped, kFunction), +XE_EXPORT(xam, 0x000001FB, XamGetOverlappedResult, kFunction), +XE_EXPORT(xam, 0x000001FC, XMsgStartIORequestEx, kFunction), +XE_EXPORT(xam, 0x000001FD, XamAppAllocateInterappWorkspace, kFunction), +XE_EXPORT(xam, 0x000001FE, XamAppGetInterappWorkspace, kFunction), +XE_EXPORT(xam, 0x000001FF, XamAppFreeInterappWorkspace, kFunction), +XE_EXPORT(xam, 0x00000200, XamFeatureEnabled, kFunction), +XE_EXPORT(xam, 0x00000201, XamFeatureEnforceImageBudget, kFunction), +XE_EXPORT(xam, 0x00000202, XamFeatureSetMask, kFunction), +XE_EXPORT(xam, 0x00000203, XamFeatureEnableDisable, kFunction), +XE_EXPORT(xam, 0x00000204, XuiControlSetItemAssociation, kFunction), +XE_EXPORT(xam, 0x00000205, XamGetTitleGlobalStorageValue, kFunction), +XE_EXPORT(xam, 0x00000206, XamSetTitleGlobalStorageValue, kFunction), +XE_EXPORT(xam, 0x00000207, XamUserValidateAvatarManifest, kFunction), +XE_EXPORT(xam, 0x00000208, XamUserGetDeviceContext, kFunction), +XE_EXPORT(xam, 0x00000209, XamUserLookupDevice, kFunction), +XE_EXPORT(xam, 0x0000020A, XamUserGetXUID, kFunction), +XE_EXPORT(xam, 0x0000020B, XamUserLogon, kFunction), +XE_EXPORT(xam, 0x0000020C, XamUserGetGamerTag, kFunction), +XE_EXPORT(xam, 0x0000020D, XamUserGetUserIndexMask, kFunction), +XE_EXPORT(xam, 0x0000020E, XamUserGetName, kFunction), +XE_EXPORT(xam, 0x0000020F, XamLookupCommonStringByIndex, kFunction), +XE_EXPORT(xam, 0x00000210, XamUserGetSigninState, kFunction), +XE_EXPORT(xam, 0x00000211, XamUserGetIndexFromXUID, kFunction), +XE_EXPORT(xam, 0x00000212, XamUserCheckPrivilege, kFunction), +XE_EXPORT(xam, 0x00000213, XamUserAreUsersFriends, kFunction), +XE_EXPORT(xam, 0x00000214, XamSetUserPresetPresenceState, kFunction), +XE_EXPORT(xam, 0x00000215, XamGetUserPresetPresenceState, kFunction), +XE_EXPORT(xam, 0x00000216, XamUserGetUserFlagsFromXUID, kFunction), +XE_EXPORT(xam, 0x00000217, XamUserGetMembershipTierFromXUID, kFunction), +XE_EXPORT(xam, 0x00000218, XamUserGetOnlineCountryFromXUID, kFunction), +XE_EXPORT(xam, 0x00000219, XamUserReadProfileSettings, kFunction), +XE_EXPORT(xam, 0x0000021A, XamUserWriteProfileSettings, kFunction), +XE_EXPORT(xam, 0x0000021B, XamUserGetMembershipTier, kFunction), +XE_EXPORT(xam, 0x0000021C, XamUserGetUserFlags, kFunction), +XE_EXPORT(xam, 0x0000021D, XamUserGetRequestedUserIndexMask, kFunction), +XE_EXPORT(xam, 0x0000021E, XamUserIsGuest, kFunction), +XE_EXPORT(xam, 0x0000021F, XamUserProfileSync, kFunction), +XE_EXPORT(xam, 0x00000220, XamUserFlushLogonQueue, kFunction), +XE_EXPORT(xam, 0x00000221, XamUserIsOnlineEnabled, kFunction), +XE_EXPORT(xam, 0x00000222, XamUserGetCachedUserFlags, kFunction), +XE_EXPORT(xam, 0x00000223, XamAreMixedAccountsSignedIn, kFunction), +XE_EXPORT(xam, 0x00000224, XamUserLogonEx, kFunction), +XE_EXPORT(xam, 0x00000225, XamSetUserShowMessengerFriends, kFunction), +XE_EXPORT(xam, 0x00000226, XamGetUserShowMessengerFriends, kFunction), +XE_EXPORT(xam, 0x00000227, XamUserGetSigninInfo, kFunction), +XE_EXPORT(xam, 0x00000228, XamUserIsPartial, kFunction), +XE_EXPORT(xam, 0x00000229, XamUserGetOnlineLanguageFromXUID, kFunction), +XE_EXPORT(xam, 0x0000022A, XamUserReadProfileSettingsEx, kFunction), +XE_EXPORT(xam, 0x0000022B, XamSystemUpdaterLogon, kFunction), +XE_EXPORT(xam, 0x0000022C, XamUserGetUsersMissingAvatars, kFunction), +XE_EXPORT(xam, 0x0000022D, XamIsChildAccountSignedIn, kFunction), +XE_EXPORT(xam, 0x0000022E, XamUserPrefetchProfileSettings, kFunction), +XE_EXPORT(xam, 0x0000022F, XamUserInvalidateProfileSetting, kFunction), +XE_EXPORT(xam, 0x00000230, XamProfileCreate, kFunction), +XE_EXPORT(xam, 0x00000231, XamProfileCreateEnumerator, kFunction), +XE_EXPORT(xam, 0x00000232, XamProfileEnumerate, kFunction), +XE_EXPORT(xam, 0x00000233, XamProfileDelete, kFunction), +XE_EXPORT(xam, 0x00000234, XamProfileGetCreationStatus, kFunction), +XE_EXPORT(xam, 0x00000235, XamProfileFindAccount, kFunction), +XE_EXPORT(xam, 0x00000236, XamProfileRenameAccount, kFunction), +XE_EXPORT(xam, 0x00000237, XamProfileOpen, kFunction), +XE_EXPORT(xam, 0x00000238, XamProfileClose, kFunction), +XE_EXPORT(xam, 0x00000239, XamProfileSaveAccountInfo, kFunction), +XE_EXPORT(xam, 0x0000023A, XamProfileLoadAccountInfo, kFunction), +XE_EXPORT(xam, 0x0000023B, XamProfileRecoverTitle, kFunction), +XE_EXPORT(xam, 0x0000023C, XamProfileSaveWindowsLiveCredentials, kFunction), +XE_EXPORT(xam, 0x0000023D, XamProfileLoadWindowsLiveCredentials, kFunction), +XE_EXPORT(xam, 0x0000023E, XamProfileIsSaveWindowsLiveCredsEnabled, kFunction), +XE_EXPORT(xam, 0x0000023F, XamProfileSetSaveWindowsLiveCredsEnabled, kFunction), +XE_EXPORT(xam, 0x00000240, XamSetProfileReadTestHook, kFunction), +XE_EXPORT(xam, 0x00000241, XamProfileGetLastSync, kFunction), +XE_EXPORT(xam, 0x00000242, XamAccountRecoveryRecoverTitle, kFunction), +XE_EXPORT(xam, 0x00000243, XamProfileControlPec, kFunction), +XE_EXPORT(xam, 0x00000244, XamAppLoad, kFunction), +XE_EXPORT(xam, 0x00000245, XamAppUnloadSelf, kFunction), +XE_EXPORT(xam, 0x00000246, XamAppUnloadStack, kFunction), +XE_EXPORT(xam, 0x00000247, XamSendMessageToLoadedApps, kFunction), +XE_EXPORT(xam, 0x00000248, XamAppRequestLoad, kFunction), +XE_EXPORT(xam, 0x00000249, XamAppUnrequestLoad, kFunction), +XE_EXPORT(xam, 0x0000024A, XamNavigate, kFunction), +XE_EXPORT(xam, 0x0000024B, XamRegisterSysApp, kFunction), +XE_EXPORT(xam, 0x0000024C, XamUnregisterSysApp, kFunction), +XE_EXPORT(xam, 0x0000024D, XamAppReinitialize, kFunction), +XE_EXPORT(xam, 0x0000024E, XamCreateEnumeratorHandle, kFunction), +XE_EXPORT(xam, 0x0000024F, XamGetPrivateEnumStructureFromHandle, kFunction), +XE_EXPORT(xam, 0x00000250, XamEnumerate, kFunction), +XE_EXPORT(xam, 0x00000251, XamLoadSysApp, kFunction), +XE_EXPORT(xam, 0x00000252, XamUnloadSysApp, kFunction), +XE_EXPORT(xam, 0x00000253, XamReloadSysApp, kFunction), +XE_EXPORT(xam, 0x00000254, XamAppLoadPass2SysApps, kFunction), +XE_EXPORT(xam, 0x00000255, XamProfileGetLiveLegalLocale, kFunction), +XE_EXPORT(xam, 0x00000256, XamUserIsParentalControlled, kFunction), +XE_EXPORT(xam, 0x00000257, XamContentLaunchImageFromFileInternal, kFunction), +XE_EXPORT(xam, 0x00000258, XamContentCreate, kFunction), +XE_EXPORT(xam, 0x00000259, XamContentCreateEx, kFunction), +XE_EXPORT(xam, 0x0000025A, XamContentClose, kFunction), +XE_EXPORT(xam, 0x0000025B, XamContentDelete, kFunction), +XE_EXPORT(xam, 0x0000025C, XamContentCreateEnumerator, kFunction), +XE_EXPORT(xam, 0x0000025D, XamContentCreateDeviceEnumerator, kFunction), +XE_EXPORT(xam, 0x0000025E, XamContentGetDeviceData, kFunction), +XE_EXPORT(xam, 0x0000025F, XamContentGetDeviceName, kFunction), +XE_EXPORT(xam, 0x00000260, XamContentSetThumbnail, kFunction), +XE_EXPORT(xam, 0x00000261, XamContentGetThumbnail, kFunction), +XE_EXPORT(xam, 0x00000262, XamContentGetCreator, kFunction), +XE_EXPORT(xam, 0x00000263, XamContentLaunchImage, kFunction), +XE_EXPORT(xam, 0x00000264, XamContentGetAttributes, kFunction), +XE_EXPORT(xam, 0x00000265, XamContentGetDeviceState, kFunction), +XE_EXPORT(xam, 0x00000266, XamContentGetLicenseMask, kFunction), +XE_EXPORT(xam, 0x00000267, XamContentFlush, kFunction), +XE_EXPORT(xam, 0x00000268, XamContentResolve, kFunction), +XE_EXPORT(xam, 0x00000269, XamContentOpenFile, kFunction), +XE_EXPORT(xam, 0x0000026A, XamContentInstall, kFunction), +XE_EXPORT(xam, 0x0000026B, XamContentLockUnlockPackageHeaders, kFunction), +XE_EXPORT(xam, 0x0000026C, XamContentCopyInternal, kFunction), +XE_EXPORT(xam, 0x0000026D, XamContentMoveInternal, kFunction), +XE_EXPORT(xam, 0x0000026E, XamContentGetMetaDataInternal, kFunction), +XE_EXPORT(xam, 0x0000026F, XamContentCreateEnumeratorInternal, kFunction), +XE_EXPORT(xam, 0x00000270, XamContentDeleteInternal, kFunction), +XE_EXPORT(xam, 0x00000271, XamContentCreateInternal, kFunction), +XE_EXPORT(xam, 0x00000272, XamContentSetThumbnailInternal, kFunction), +XE_EXPORT(xam, 0x00000273, XamContentLaunchImageInternal, kFunction), +XE_EXPORT(xam, 0x00000274, XamContentWritePackageHeader, kFunction), +XE_EXPORT(xam, 0x00000275, XamContentDismountAndClosePackage, kFunction), +XE_EXPORT(xam, 0x00000276, XamContentResolveInternal, kFunction), +XE_EXPORT(xam, 0x00000277, XamContentGetAttributesInternal, kFunction), +XE_EXPORT(xam, 0x00000278, XamContentOpenFileInternal, kFunction), +XE_EXPORT(xam, 0x00000279, XamContentAggregateCreateEnumerator, kFunction), +XE_EXPORT(xam, 0x0000027A, XamContentCreateAndMountPackage, kFunction), +XE_EXPORT(xam, 0x0000027B, XamContentOpenPackageFile, kFunction), +XE_EXPORT(xam, 0x0000027C, XamContentMountPackage, kFunction), +XE_EXPORT(xam, 0x0000027D, XamContentFlushPackage, kFunction), +XE_EXPORT(xam, 0x0000027E, XamContentClosePackageFile, kFunction), +XE_EXPORT(xam, 0x0000027F, XamContentDuplicateFileHandle, kFunction), +XE_EXPORT(xam, 0x00000280, XamGetExecutionId, kFunction), +XE_EXPORT(xam, 0x00000281, XamGetGameRatings, kFunction), +XE_EXPORT(xam, 0x00000282, XamGetSystemVersion, kFunction), +XE_EXPORT(xam, 0x00000283, XamContentGetLocalizedString, kFunction), +XE_EXPORT(xam, 0x00000284, XamContentGetDefaultDevice, kFunction), +XE_EXPORT(xam, 0x00000285, XamContentInstallInternal, kFunction), +XE_EXPORT(xam, 0x00000286, XamContentSetMediaMetaDataInternal, kFunction), +XE_EXPORT(xam, 0x00000287, XamContentGetDeviceSerialNumber, kFunction), +XE_EXPORT(xam, 0x00000288, XamContentGetMountedPackageByRootName, kFunction), +XE_EXPORT(xam, 0x00000289, XamContentRegisterChangeCallback, kFunction), +XE_EXPORT(xam, 0x0000028A, XamNotifyCreateListener, kFunction), +XE_EXPORT(xam, 0x0000028B, XNotifyGetNext, kFunction), +XE_EXPORT(xam, 0x0000028C, XNotifyPositionUI, kFunction), +XE_EXPORT(xam, 0x0000028D, XNotifyDelayUI, kFunction), +XE_EXPORT(xam, 0x0000028E, XNotifyBroadcast, kFunction), +XE_EXPORT(xam, 0x0000028F, XNotifyRegisterArea, kFunction), +XE_EXPORT(xam, 0x00000290, XNotifyQueueUI, kFunction), +XE_EXPORT(xam, 0x00000291, XamNotifyCreateListenerInternal, kFunction), +XE_EXPORT(xam, 0x00000292, XNotifyUISetOptions, kFunction), +XE_EXPORT(xam, 0x00000293, XNotifyUIGetOptions, kFunction), +XE_EXPORT(xam, 0x00000294, XamContentLaunchImageInternalEx, kFunction), +XE_EXPORT(xam, 0x00000295, XamShutdown, kFunction), +XE_EXPORT(xam, 0x00000296, XamAllocDevkitHeapAvailable, kFunction), +XE_EXPORT(xam, 0x00000297, XamNotifyCreateListenerRangeInternal, kFunction), +XE_EXPORT(xam, 0x00000298, XNotifyQueueUIEx, kFunction), +XE_EXPORT(xam, 0x00000299, XamAppRequestLoadEx, kFunction), +XE_EXPORT(xam, 0x0000029A, XuiPNGTextureLoader, kFunction), +XE_EXPORT(xam, 0x0000029B, XuiRenderGetXuiDevice, kFunction), +XE_EXPORT(xam, 0x0000029C, XuiDefault_False, kFunction), +XE_EXPORT(xam, 0x0000029D, XamUserGetReportingInfo, kFunction), +XE_EXPORT(xam, 0x0000029E, XamUpdateStart, kFunction), +XE_EXPORT(xam, 0x0000029F, XamUpdateGetProgress, kFunction), +XE_EXPORT(xam, 0x000002A0, XamUpdateGetExtenderInstance, kFunction), +XE_EXPORT(xam, 0x000002A1, XamUpdateFinish, kFunction), +XE_EXPORT(xam, 0x000002A2, XamUpdateAttachExtenderInstance, kFunction), +XE_EXPORT(xam, 0x000002A3, XamUpdateAllocateExtenderBuffer, kFunction), +XE_EXPORT(xam, 0x000002A4, XamRestartTitleLoadAfterUpdate, kFunction), +XE_EXPORT(xam, 0x000002A5, XamUIThreadDisableFontPatching, kFunction), +XE_EXPORT(xam, 0x000002A6, XamUpdateGetBaseSystemVersion, kFunction), +XE_EXPORT(xam, 0x000002A7, XamUpdateGetCurrentSystemVersion, kFunction), +XE_EXPORT(xam, 0x000002A8, XamUIThreadEnableFontPatching, kFunction), +XE_EXPORT(xam, 0x000002A9, XamTerminateTitleForUpdate, kFunction), +XE_EXPORT(xam, 0x000002AA, XamSystemUpdateInstallLocal, kFunction), +XE_EXPORT(xam, 0x000002AB, XamUpdateChainPass3FromPass2, kFunction), +XE_EXPORT(xam, 0x000002AD, XamInputGetCapabilitiesEx, kFunction), +XE_EXPORT(xam, 0x000002AE, XamUserIsUnsafeProgrammingAllowed, kFunction), +XE_EXPORT(xam, 0x000002AF, XamDevAuthSetFaultEx, kFunction), +XE_EXPORT(xam, 0x000002B0, XamUpdateGetData, kFunction), +XE_EXPORT(xam, 0x000002B1, XamCacheIntegrityCheck, kFunction), +XE_EXPORT(xam, 0x000002B2, XamCacheStoreFile, kFunction), +XE_EXPORT(xam, 0x000002B3, XamCacheFetchFile, kFunction), +XE_EXPORT(xam, 0x000002B4, XamCacheOpenFile, kFunction), +XE_EXPORT(xam, 0x000002B5, XamCacheCloseFile, kFunction), +XE_EXPORT(xam, 0x000002B6, XamGetCachedTitleName, kFunction), +XE_EXPORT(xam, 0x000002B7, XamCacheReset, kFunction), +XE_EXPORT(xam, 0x000002B8, XamGetCachedGamerTag, kFunction), +XE_EXPORT(xam, 0x000002B9, XamGetCachedGamerTagW, kFunction), +XE_EXPORT(xam, 0x000002BA, XamCacheDeleteFile, kFunction), +XE_EXPORT(xam, 0x000002BB, XamCacheRenameFile, kFunction), +XE_EXPORT(xam, 0x000002BC, XamShowSigninUI, kFunction), +XE_EXPORT(xam, 0x000002BD, XamShowSigninUIEx, kFunction), +XE_EXPORT(xam, 0x000002BE, XamShowSigninUIp, kFunction), +XE_EXPORT(xam, 0x000002BF, XamShowFriendsUI, kFunction), +XE_EXPORT(xam, 0x000002C0, XamShowMessagesUI, kFunction), +XE_EXPORT(xam, 0x000002C1, XamShowKeyboardUI, kFunction), +XE_EXPORT(xam, 0x000002C2, XamShowQuickChatUI, kFunction), +XE_EXPORT(xam, 0x000002C3, XamShowVoiceMailUI, kFunction), +XE_EXPORT(xam, 0x000002C4, XamShowGamerCardUI, kFunction), +XE_EXPORT(xam, 0x000002C5, XamShowAchievementsUI, kFunction), +XE_EXPORT(xam, 0x000002C6, XamShowPlayerReviewUI, kFunction), +XE_EXPORT(xam, 0x000002C7, XamShowMarketplaceUI, kFunction), +XE_EXPORT(xam, 0x000002C8, XamShowPlayersUI, kFunction), +XE_EXPORT(xam, 0x000002C9, XamShowUpdaterUI, kFunction), +XE_EXPORT(xam, 0x000002CA, XamShowMessageBoxUI, kFunction), +XE_EXPORT(xam, 0x000002CB, XamShowDeviceSelectorUI, kFunction), +XE_EXPORT(xam, 0x000002CC, XamShowMessageComposeUI, kFunction), +XE_EXPORT(xam, 0x000002CD, XamShowGameInviteUI, kFunction), +XE_EXPORT(xam, 0x000002CE, XamShowFriendRequestUI, kFunction), +XE_EXPORT(xam, 0x000002CF, XamShowCreateProfileUI, kFunction), +XE_EXPORT(xam, 0x000002D0, XamShowGamesUI, kFunction), +XE_EXPORT(xam, 0x000002D1, XamShowLiveSignupUI, kFunction), +XE_EXPORT(xam, 0x000002D2, XamShowFriendsUIp, kFunction), +XE_EXPORT(xam, 0x000002D3, XamShowComplaintUI, kFunction), +XE_EXPORT(xam, 0x000002D4, XamShowReputationUI, kFunction), +XE_EXPORT(xam, 0x000002D5, XamShowGamerCardUIForXUID, kFunction), +XE_EXPORT(xam, 0x000002D6, XamShowForcedNameChangeUI, kFunction), +XE_EXPORT(xam, 0x000002D7, XamShowLiveUpsellUI, kFunction), +XE_EXPORT(xam, 0x000002D8, XamShowPasscodeVerifyUI, kFunction), +XE_EXPORT(xam, 0x000002D9, XamShowDirtyDiscErrorUI, kFunction), +XE_EXPORT(xam, 0x000002DA, XamShowSignupCreditCardUI, kFunction), +XE_EXPORT(xam, 0x000002DB, XamShowPrivateChatInviteUI, kFunction), +XE_EXPORT(xam, 0x000002DC, XamShowMessageBoxUIEx, kFunction), +XE_EXPORT(xam, 0x000002DD, XamShowRecentMessageUI, kFunction), +XE_EXPORT(xam, 0x000002DE, XamShowRecentMessageUIEx, kFunction), +XE_EXPORT(xam, 0x000002DF, XamShowMessagesUIEx, kFunction), +XE_EXPORT(xam, 0x000002E0, XamShowAchievementDetailsUI, kFunction), +XE_EXPORT(xam, 0x000002E1, XamShowPersonalizationUI, kFunction), +XE_EXPORT(xam, 0x000002E2, XamShowChangeGamerTileUI, kFunction), +XE_EXPORT(xam, 0x000002E3, XamShowVoiceSettingsUI, kFunction), +XE_EXPORT(xam, 0x000002E4, XamShowVideoChatInviteUI, kFunction), +XE_EXPORT(xam, 0x000002E5, XamShowCustomMessageComposeUI, kFunction), +XE_EXPORT(xam, 0x000002E6, XamShowCustomPlayerListUI, kFunction), +XE_EXPORT(xam, 0x000002E7, XamShowMarketplaceDownloadItemsUI, kFunction), +XE_EXPORT(xam, 0x000002E8, XamShowMarketplaceUIEx, kFunction), +XE_EXPORT(xam, 0x000002E9, XamShowMessageBox, kFunction), +XE_EXPORT(xam, 0x000002EA, XamIsSysUiInvokedByXenonButton, kFunction), +XE_EXPORT(xam, 0x000002EB, XamIsSysUiInvokedByTitle, kFunction), +XE_EXPORT(xam, 0x000002EC, XamIsUIActive, kFunction), +XE_EXPORT(xam, 0x000002ED, XamSysUiDisableAutoClose, kFunction), +XE_EXPORT(xam, 0x000002EE, XamUserCreateAchievementEnumerator, kFunction), +XE_EXPORT(xam, 0x000002EF, XamReadTile, kFunction), +XE_EXPORT(xam, 0x000002F0, XamWriteGamerTile, kFunction), +XE_EXPORT(xam, 0x000002F1, XamWriteTile, kFunction), +XE_EXPORT(xam, 0x000002F2, XamReadImage, kFunction), +XE_EXPORT(xam, 0x000002F3, XamUserCreateTitlesPlayedEnumerator, kFunction), +XE_EXPORT(xam, 0x000002F4, XamDecompressPNGToTexture, kFunction), +XE_EXPORT(xam, 0x000002F5, XamReadTileToTexture, kFunction), +XE_EXPORT(xam, 0x000002F6, XamReadString, kFunction), +XE_EXPORT(xam, 0x000002F7, XamUserCreateStatsEnumerator, kFunction), +XE_EXPORT(xam, 0x000002F8, XamPrepareGamerTiles, kFunction), +XE_EXPORT(xam, 0x000002F9, XamClearTitle, kFunction), +XE_EXPORT(xam, 0x000002FA, XamReadStrings, kFunction), +XE_EXPORT(xam, 0x000002FB, XamWriteGamerTileEx, kFunction), +XE_EXPORT(xam, 0x000002FC, XamReadTileEx, kFunction), +XE_EXPORT(xam, 0x000002FD, XamReadTileToTextureEx, kFunction), +XE_EXPORT(xam, 0x000002FE, XamShowMessengerUI, kFunction), +XE_EXPORT(xam, 0x000002FF, XamShowKeyboardUIMessenger, kFunction), +XE_EXPORT(xam, 0x00000300, XamShowLiveUpsellUIEx, kFunction), +XE_EXPORT(xam, 0x00000301, XamShowJoinSessionInProgressUI, kFunction), +XE_EXPORT(xam, 0x00000302, XamShowGraduateUserUI, kFunction), +XE_EXPORT(xam, 0x00000303, XamShowGamerCardUIForXUIDp, kFunction), +XE_EXPORT(xam, 0x00000304, XamShowGuideUI, kFunction), +XE_EXPORT(xam, 0x00000305, XamShowPartyUI, kFunction), +XE_EXPORT(xam, 0x00000306, XamShowPartyInviteUI, kFunction), +XE_EXPORT(xam, 0x00000307, XamUserAddRecentPlayer, kFunction), +XE_EXPORT(xam, 0x00000308, XamUserUpdateRecentPlayer, kFunction), +XE_EXPORT(xam, 0x00000309, XamUserCreatePlayerEnumerator, kFunction), +XE_EXPORT(xam, 0x0000030A, XamParseGamerTileKey, kFunction), +XE_EXPORT(xam, 0x0000030B, XamShowCommunitySessionsUI, kFunction), +XE_EXPORT(xam, 0x0000030C, XamVoiceCreate, kFunction), +XE_EXPORT(xam, 0x0000030D, XamVoiceHeadsetPresent, kFunction), +XE_EXPORT(xam, 0x0000030E, XamVoiceSubmitPacket, kFunction), +XE_EXPORT(xam, 0x0000030F, XamVoiceClose, kFunction), +XE_EXPORT(xam, 0x00000310, XamVoiceGetBatteryStatus, kFunction), +XE_EXPORT(xam, 0x00000311, Refresh_, kFunction), +XE_EXPORT(xam, 0x00000312, Refresh_0, kFunction), +XE_EXPORT(xam, 0x00000313, XamShowJoinSessionByIdInProgressUI, kFunction), +XE_EXPORT(xam, 0x00000314, XamShowPartyJoinInProgressUI, kFunction), +XE_EXPORT(xam, 0x00000315, XamBuildSharedSystemResourceLocator, kFunction), +XE_EXPORT(xam, 0x00000316, XamSessionCreateHandle, kFunction), +XE_EXPORT(xam, 0x00000317, XamSessionRefObjByHandle, kFunction), +XE_EXPORT(xam, 0x00000318, XamVoiceGetMicArrayStatus, kFunction), +XE_EXPORT(xam, 0x00000319, XamVoiceSetAudioCaptureRoutine, kFunction), +XE_EXPORT(xam, 0x0000031A, XamVoiceGetDirectionalData, kFunction), +XE_EXPORT(xam, 0x0000031B, XamBuildResourceLocator, kFunction), +XE_EXPORT(xam, 0x0000031C, XamBuildLegacySystemResourceLocator, kFunction), +XE_EXPORT(xam, 0x0000031D, XamBuildGamercardResourceLocator, kFunction), +XE_EXPORT(xam, 0x0000031E, XamBuildDynamicResourceLocator, kFunction), +XE_EXPORT(xam, 0x0000031F, XamBuildXamResourceLocator, kFunction), +XE_EXPORT(xam, 0x00000320, XuiAnimRun, kFunction), +XE_EXPORT(xam, 0x00000321, XuiApplyLocale, kFunction), +XE_EXPORT(xam, 0x00000322, XuiBubbleMessage, kFunction), +XE_EXPORT(xam, 0x00000323, XuiControlIsBackButton, kFunction), +XE_EXPORT(xam, 0x00000324, XuiControlIsNavButton, kFunction), +XE_EXPORT(xam, 0x00000325, XuiCreateObject, kFunction), +XE_EXPORT(xam, 0x00000326, XuiDestroyObject, kFunction), +XE_EXPORT(xam, 0x00000327, XuiDynamicCast, kFunction), +XE_EXPORT(xam, 0x00000328, XuiElementAddChild, kFunction), +XE_EXPORT(xam, 0x00000329, XuiElementFindNamedFrame, kFunction), +XE_EXPORT(xam, 0x0000032A, XuiElementGetChildById, kFunction), +XE_EXPORT(xam, 0x0000032B, XuiElementGetFirstChild, kFunction), +XE_EXPORT(xam, 0x0000032C, XuiElementGetFocus, kFunction), +XE_EXPORT(xam, 0x0000032D, XuiElementGetFocusUser, kFunction), +XE_EXPORT(xam, 0x0000032E, XuiElementGetId, kFunction), +XE_EXPORT(xam, 0x0000032F, XuiElementGetLastChild, kFunction), +XE_EXPORT(xam, 0x00000330, XuiElementGetNext, kFunction), +XE_EXPORT(xam, 0x00000331, XuiElementGetParent, kFunction), +XE_EXPORT(xam, 0x00000332, XuiElementGetUserFocus, kFunction), +XE_EXPORT(xam, 0x00000333, XuiElementInitFocus, kFunction), +XE_EXPORT(xam, 0x00000334, XuiElementInitUserFocus, kFunction), +XE_EXPORT(xam, 0x00000335, XuiElementPlayTimeline, kFunction), +XE_EXPORT(xam, 0x00000336, XuiElementSetBounds, kFunction), +XE_EXPORT(xam, 0x00000337, XuiElementSetFocus, kFunction), +XE_EXPORT(xam, 0x00000338, XuiElementSetUserFocus, kFunction), +XE_EXPORT(xam, 0x00000339, XuiElementTreeGetFocus, kFunction), +XE_EXPORT(xam, 0x0000033A, XuiFindClass, kFunction), +XE_EXPORT(xam, 0x0000033B, XuiFreeStringTable, kFunction), +XE_EXPORT(xam, 0x0000033C, XuiGetBaseObject, kFunction), +XE_EXPORT(xam, 0x0000033D, XuiGetClass, kFunction), +XE_EXPORT(xam, 0x0000033E, XuiGetObjectClass, kFunction), +XE_EXPORT(xam, 0x0000033F, XuiGetOuter, kFunction), +XE_EXPORT(xam, 0x00000340, XuiInit, kFunction), +XE_EXPORT(xam, 0x00000341, XuiLoadFromBinary, kFunction), +XE_EXPORT(xam, 0x00000342, XuiLoadStringTableFromFile, kFunction), +XE_EXPORT(xam, 0x00000343, XuiVisualGetBasePath, kFunction), +XE_EXPORT(xam, 0x00000344, XuiLookupStringTable, kFunction), +XE_EXPORT(xam, 0x00000345, XuiNavButtonGetPressPath, kFunction), +XE_EXPORT(xam, 0x00000346, XuiObjectFromHandle, kFunction), +XE_EXPORT(xam, 0x00000347, XuiObjectGetProperty, kFunction), +XE_EXPORT(xam, 0x00000348, XuiObjectGetPropertyId, kFunction), +XE_EXPORT(xam, 0x00000349, XuiProcessInput, kFunction), +XE_EXPORT(xam, 0x0000034A, XuiRegisterClass, kFunction), +XE_EXPORT(xam, 0x0000034B, XuiRenderBegin, kFunction), +XE_EXPORT(xam, 0x0000034C, XuiRenderCreateDC, kFunction), +XE_EXPORT(xam, 0x0000034D, XuiRenderDCDeviceChanged, kFunction), +XE_EXPORT(xam, 0x0000034E, XuiRenderDestroyDC, kFunction), +XE_EXPORT(xam, 0x0000034F, XuiRenderEnd, kFunction), +XE_EXPORT(xam, 0x00000350, XuiRenderGetBackBufferSize, kFunction), +XE_EXPORT(xam, 0x00000351, XuiRenderInit, kFunction), +XE_EXPORT(xam, 0x00000352, XuiRenderInitShared, kFunction), +XE_EXPORT(xam, 0x00000353, XuiRenderPresent, kFunction), +XE_EXPORT(xam, 0x00000354, XuiRenderSetViewTransform, kFunction), +XE_EXPORT(xam, 0x00000355, XuiRenderUninit, kFunction), +XE_EXPORT(xam, 0x00000356, XamShowNuiGuideUI, kFunction), +XE_EXPORT(xam, 0x00000357, XuiSceneCreate, kFunction), +XE_EXPORT(xam, 0x00000358, XuiSceneNavigateBack, kFunction), +XE_EXPORT(xam, 0x00000359, XuiSceneNavigateFirst, kFunction), +XE_EXPORT(xam, 0x0000035A, XuiSceneNavigateForward, kFunction), +XE_EXPORT(xam, 0x0000035B, XuiScenePlayBackFromTransition, kFunction), +XE_EXPORT(xam, 0x0000035C, XuiScenePlayBackToTransition, kFunction), +XE_EXPORT(xam, 0x0000035D, XuiScenePlayFromTransition, kFunction), +XE_EXPORT(xam, 0x0000035E, XuiScenePlayToTransition, kFunction), +XE_EXPORT(xam, 0x0000035F, XuiSendMessage, kFunction), +XE_EXPORT(xam, 0x00000360, XuiSetLocale, kFunction), +XE_EXPORT(xam, 0x00000361, XuiUninit, kFunction), +XE_EXPORT(xam, 0x00000362, XuiUnregisterClass, kFunction), +XE_EXPORT(xam, 0x00000363, XuiTextElementSetText, kFunction), +XE_EXPORT(xam, 0x00000364, XuiSetTimer, kFunction), +XE_EXPORT(xam, 0x00000365, XuiTimersRun, kFunction), +XE_EXPORT(xam, 0x00000366, XuiTextElementGetText, kFunction), +XE_EXPORT(xam, 0x00000367, XuiVisualSetBasePath, kFunction), +XE_EXPORT(xam, 0x00000368, XuiHandleIsValid, kFunction), +XE_EXPORT(xam, 0x00000369, XuiAlloc, kFunction), +XE_EXPORT(xam, 0x0000036A, XuiFree, kFunction), +XE_EXPORT(xam, 0x0000036B, XuiDefault_True, kFunction), +XE_EXPORT(xam, 0x0000036C, XuiDefault_EmptyString, kFunction), +XE_EXPORT(xam, 0x0000036D, XuiDefault_IntegerZero, kFunction), +XE_EXPORT(xam, 0x0000036E, XuiCopyString, kFunction), +XE_EXPORT(xam, 0x0000036F, XuiRealloc, kFunction), +XE_EXPORT(xam, 0x00000370, XuiControlPlayOptionalVisual, kFunction), +XE_EXPORT(xam, 0x00000371, XuiKillTimer, kFunction), +XE_EXPORT(xam, 0x00000372, XuiElementEnableInput, kFunction), +XE_EXPORT(xam, 0x00000373, XuiElementInputEnabled, kFunction), +XE_EXPORT(xam, 0x00000374, XuiIsInstanceOf, kFunction), +XE_EXPORT(xam, 0x00000375, XuiResourceComposeLocator, kFunction), +XE_EXPORT(xam, 0x00000376, XuiResourceLocatorIsAbsolute, kFunction), +XE_EXPORT(xam, 0x00000377, XuiBroadcastMessage, kFunction), +XE_EXPORT(xam, 0x00000378, XuiElementDisallowRecursiveTimelineControl, kFunction), +XE_EXPORT(xam, 0x00000379, XUIElementPropVal_Construct, kFunction), +XE_EXPORT(xam, 0x0000037A, XUIElementPropVal_Destruct, kFunction), +XE_EXPORT(xam, 0x0000037B, XUIElementPropVal_SetString, kFunction), +XE_EXPORT(xam, 0x0000037C, XuiObjectSetProperty, kFunction), +XE_EXPORT(xam, 0x0000037D, XuiElementGetOpacity, kFunction), +XE_EXPORT(xam, 0x0000037E, XuiElementSetOpacity, kFunction), +XE_EXPORT(xam, 0x0000037F, XuiEditSetTextLimit, kFunction), +XE_EXPORT(xam, 0x00000380, XuiEditGetTextLimit, kFunction), +XE_EXPORT(xam, 0x00000381, XuiSliderSetValue, kFunction), +XE_EXPORT(xam, 0x00000382, XuiSliderGetValue, kFunction), +XE_EXPORT(xam, 0x00000383, XuiSliderSetRange, kFunction), +XE_EXPORT(xam, 0x00000384, XuiElementUnlink, kFunction), +XE_EXPORT(xam, 0x00000385, XuiElementInsertChild, kFunction), +XE_EXPORT(xam, 0x00000386, XuiSceneNavigateBackToFirst, kFunction), +XE_EXPORT(xam, 0x00000387, XuiProgressBarSetRange, kFunction), +XE_EXPORT(xam, 0x00000388, XuiProgressBarSetValue, kFunction), +XE_EXPORT(xam, 0x00000389, XuiProgressBarGetValue, kFunction), +XE_EXPORT(xam, 0x0000038A, XuiControlAttachVisual, kFunction), +XE_EXPORT(xam, 0x0000038B, XuiCreateTextureBrush, kFunction), +XE_EXPORT(xam, 0x0000038C, XuiDestroyBrush, kFunction), +XE_EXPORT(xam, 0x0000038D, XUIElementPropVal_SetColorFromUint, kFunction), +XE_EXPORT(xam, 0x0000038E, XuiFigureSetFill, kFunction), +XE_EXPORT(xam, 0x0000038F, XuiSliderGetRange, kFunction), +XE_EXPORT(xam, 0x00000390, XuiFigureSetTexture, kFunction), +XE_EXPORT(xam, 0x00000391, XuiControlGetItemAssociation, kFunction), +XE_EXPORT(xam, 0x00000392, XuiResourceLoadAll, kFunction), +XE_EXPORT(xam, 0x00000393, XuiImageElementSetImagePath, kFunction), +XE_EXPORT(xam, 0x00000394, XuiImageElementGetImagePath, kFunction), +XE_EXPORT(xam, 0x00000395, XuiControlGetVisual, kFunction), +XE_EXPORT(xam, 0x00000396, XuiControlGetNavigation, kFunction), +XE_EXPORT(xam, 0x00000397, XuiLookupStringTableByIndex, kFunction), +XE_EXPORT(xam, 0x00000398, XUIElementPropVal_SetBool, kFunction), +XE_EXPORT(xam, 0x00000399, XuiElementHasFocus, kFunction), +XE_EXPORT(xam, 0x0000039A, XUIElementPropVal_SetUint, kFunction), +XE_EXPORT(xam, 0x0000039B, XUIElementPropVal_Clear, kFunction), +XE_EXPORT(xam, 0x0000039C, XuiEditSetTextFormatInfo, kFunction), +XE_EXPORT(xam, 0x0000039D, XuiCreateSolidBrush, kFunction), +XE_EXPORT(xam, 0x0000039E, XuiSceneInterruptTransitions, kFunction), +XE_EXPORT(xam, 0x0000039F, XuiResourceOpen, kFunction), +XE_EXPORT(xam, 0x000003A0, XuiResourceRead, kFunction), +XE_EXPORT(xam, 0x000003A1, XuiResourceClose, kFunction), +XE_EXPORT(xam, 0x000003A2, XuiVisualCreateInstance, kFunction), +XE_EXPORT(xam, 0x000003A3, XuiElementGetTimeline, kFunction), +XE_EXPORT(xam, 0x000003A4, GetCodecVersion, kFunction), +XE_EXPORT(xam, 0x000003A5, XuiElementIsDescendant, kFunction), +XE_EXPORT(xam, 0x000003A6, XuiSetMessageFilter, kFunction), +XE_EXPORT(xam, 0x000003A7, XuiAttachTextureBrush, kFunction), +XE_EXPORT(xam, 0x000003A8, XuiElementBeginRender, kFunction), +XE_EXPORT(xam, 0x000003A9, XuiElementEndRender, kFunction), +XE_EXPORT(xam, 0x000003AA, XuiDrawShape, kFunction), +XE_EXPORT(xam, 0x000003AB, XuiSelectBrushEx, kFunction), +XE_EXPORT(xam, 0x000003AC, XuiFigureGetShape, kFunction), +XE_EXPORT(xam, 0x000003AD, XuiFillRect, kFunction), +XE_EXPORT(xam, 0x000003AE, XuiVec2TransformCoord, kFunction), +XE_EXPORT(xam, 0x000003AF, XuiMatrixMultiply, kFunction), +XE_EXPORT(xam, 0x000003B0, XuiElementGetXForm, kFunction), +XE_EXPORT(xam, 0x000003B1, XuiElementSetPosition, kFunction), +XE_EXPORT(xam, 0x000003B2, XuiSelectBrush, kFunction), +XE_EXPORT(xam, 0x000003B3, XuiElementRenderChildren, kFunction), +XE_EXPORT(xam, 0x000003B4, XuiFreeUnusedTextures, kFunction), +XE_EXPORT(xam, 0x000003B5, XuiListEnableItemOverride, kFunction), +XE_EXPORT(xam, 0x000003B6, XuiListGetDefaultItemSize, kFunction), +XE_EXPORT(xam, 0x000003B7, XuiResourceSeek, kFunction), +XE_EXPORT(xam, 0x000003B8, XuiElementDiscardResources, kFunction), +XE_EXPORT(xam, 0x000003B9, XuiTabSceneGoto, kFunction), +XE_EXPORT(xam, 0x000003BA, XuiTabSceneGetCurrentTab, kFunction), +XE_EXPORT(xam, 0x000003BB, XamShowWhatsOnUI, kFunction), +XE_EXPORT(xam, 0x000003BC, XamShowEditProfileUI, kFunction), +XE_EXPORT(xam, 0x000003BD, XamShowStorePickerUI, kFunction), +XE_EXPORT(xam, 0x000003BE, XamShowTermsOfUseUI, kFunction), +XE_EXPORT(xam, 0x000003BF, XamShowJoinPartyUI, kFunction), +XE_EXPORT(xam, 0x000003C0, XamShowWordRegisterUI, kFunction), +XE_EXPORT(xam, 0x000003C1, XamOverrideHudOpenType, kFunction), +XE_EXPORT(xam, 0x000003C2, XamShowAchievementsUIEx, kFunction), +XE_EXPORT(xam, 0x000003C3, XamUserGetUserTenure, kFunction), +XE_EXPORT(xam, 0x000003C4, XamUserGetSubscriptionType, kFunction), +XE_EXPORT(xam, 0x000003C5, XamShowGameVoiceChannelUI, kFunction), +XE_EXPORT(xam, 0x000003C6, XamShowAvatarAwardsUI, kFunction), +XE_EXPORT(xam, 0x000003C7, XamShowAvatarAwardGamesUI, kFunction), +XE_EXPORT(xam, 0x000003C8, XamShowVideoRichPresenceUI, kFunction), +XE_EXPORT(xam, 0x000003C9, XamHudGetUserIndex, kFunction), +XE_EXPORT(xam, 0x000003CA, XGetAudioFlags, kFunction), +XE_EXPORT(xam, 0x000003CB, XGetAVPack, kFunction), +XE_EXPORT(xam, 0x000003CC, XGetGameRegion, kFunction), +XE_EXPORT(xam, 0x000003CD, XGetLanguage, kFunction), +XE_EXPORT(xam, 0x000003CE, XapipGetLocale, kFunction), +XE_EXPORT(xam, 0x000003CF, XGetVideoFlags, kFunction), +XE_EXPORT(xam, 0x000003D0, XGetVideoStandard, kFunction), +XE_EXPORT(xam, 0x000003D1, XGetVideoMode, kFunction), +XE_EXPORT(xam, 0x000003D2, XamGetLanguage, kFunction), +XE_EXPORT(xam, 0x000003D3, XUITimeline_Run, kFunction), +XE_EXPORT(xam, 0x000003D4, XamSetAutomation, kFunction), +XE_EXPORT(xam, 0x000003D5, XAutomationpBindController, kFunction), +XE_EXPORT(xam, 0x000003D6, XAutomationpUnbindController, kFunction), +XE_EXPORT(xam, 0x000003D7, XAutomationpInputXenonButton, kFunction), +XE_EXPORT(xam, 0x000003D8, XAutomationpInputPress, kFunction), +XE_EXPORT(xam, 0x000003D9, XAutomationpInputSetState, kFunction), +XE_EXPORT(xam, 0x000003DA, XamEnableOverdraw, kFunction), +XE_EXPORT(xam, 0x000003DB, g_XuiAutomation, kVariable), +XE_EXPORT(xam, 0x000003DC, XamVoiceGetMicArrayAudio, kFunction), +XE_EXPORT(xam, 0x000003DD, XampSystemInput, kFunction), +XE_EXPORT(xam, 0x000003DE, XamInputControl, kFunction), +XE_EXPORT(xam, 0x000003DF, XuiElementGetPosition, kFunction), +XE_EXPORT(xam, 0x000003E0, XamIsMessageBoxActive, kFunction), +XE_EXPORT(xam, 0x000003E1, XamIsBackgroundSceneInTransition, kFunction), +XE_EXPORT(xam, 0x000003E2, XuiElementTreeHasFocus, kFunction), +XE_EXPORT(xam, 0x000003E3, XuiFigureClose, kFunction), +XE_EXPORT(xam, 0x000003E4, GamerCardStartup, kFunction), +XE_EXPORT(xam, 0x000003E5, GamerCardCleanup, kFunction), +XE_EXPORT(xam, 0x000003E6, GamerCardRegisterControls, kFunction), +XE_EXPORT(xam, 0x000003E7, GamerCardUnregisterControls, kFunction), +XE_EXPORT(xam, 0x000003E8, RtlFindFirstFile, kFunction), +XE_EXPORT(xam, 0x000003E9, RtlFindNextFile, kFunction), +XE_EXPORT(xam, 0x000003EA, RtlGetModuleFileName, kFunction), +XE_EXPORT(xam, 0x000003EB, RtlOutputDebugString, kFunction), +XE_EXPORT(xam, 0x000003EC, RtlRemoveDirectory, kFunction), +XE_EXPORT(xam, 0x000003ED, RtlSleep, kFunction), +XE_EXPORT(xam, 0x000003EE, RtlGetLastError, kFunction), +XE_EXPORT(xam, 0x000003EF, RtlSetLastError, kFunction), +XE_EXPORT(xam, 0x000003F0, RtlSetLastNTError, kFunction), +XE_EXPORT(xam, 0x000003F1, RtlDebugPrint, kFunction), +XE_EXPORT(xam, 0x000003F2, RtlDebugError, kFunction), +XE_EXPORT(xam, 0x000003F3, XDebugWarning, kFunction), +XE_EXPORT(xam, 0x000003F4, RtlDebugTrace, kFunction), +XE_EXPORT(xam, 0x000003F5, RtlDebugEntry, kFunction), +XE_EXPORT(xam, 0x000003F6, RtlDebugExit, kFunction), +XE_EXPORT(xam, 0x000003F7, RtlGetAttributesOnHeapAlloc, kFunction), +XE_EXPORT(xam, 0x000003F8, RtlSetAttributesOnHeapAlloc, kFunction), +XE_EXPORT(xam, 0x000003F9, XuiFigureSetShape, kFunction), +XE_EXPORT(xam, 0x000003FA, RtlCreateHeap, kFunction), +XE_EXPORT(xam, 0x000003FB, RtlDestroyHeap, kFunction), +XE_EXPORT(xam, 0x000003FC, RtlAllocateHeap, kFunction), +XE_EXPORT(xam, 0x000003FD, RtlAllocateHeapSlowly, kFunction), +XE_EXPORT(xam, 0x000003FE, RtlReAllocateHeap, kFunction), +XE_EXPORT(xam, 0x000003FF, RtlFreeHeap, kFunction), +XE_EXPORT(xam, 0x00000400, RtlFreeHeapSlowly, kFunction), +XE_EXPORT(xam, 0x00000401, RtlSizeHeap, kFunction), +XE_EXPORT(xam, 0x00000402, RtlZeroHeap, kFunction), +XE_EXPORT(xam, 0x00000403, RtlDebugWalkHeap, kFunction), +XE_EXPORT(xam, 0x00000404, RtlWalkHeap, kFunction), +XE_EXPORT(xam, 0x00000405, RtlLockHeap, kFunction), +XE_EXPORT(xam, 0x00000406, RtlUnlockHeap, kFunction), +XE_EXPORT(xam, 0x00000407, RtlValidateHeap, kFunction), +XE_EXPORT(xam, 0x00000408, RtlDebugCompactHeap, kFunction), +XE_EXPORT(xam, 0x00000409, RtlCompactHeap, kFunction), +XE_EXPORT(xam, 0x0000040A, XamAppSetTestOption, kFunction), +XE_EXPORT(xam, 0x0000040B, XamAppReportError, kFunction), +XE_EXPORT(xam, 0x0000040C, XamIsNuiUIActive, kFunction), +XE_EXPORT(xam, 0x0000040D, XamVerifyPasscode, kFunction), +XE_EXPORT(xam, 0x0000040E, OutputDebugStringA, kFunction), +XE_EXPORT(xam, 0x0000040F, DebugBreak, kFunction), +XE_EXPORT(xam, 0x00000410, GetCurrentThreadId, kFunction), +XE_EXPORT(xam, 0x00000411, XDebugError, kFunction), +XE_EXPORT(xam, 0x00000412, XDebugWarning_, kFunction), +XE_EXPORT(xam, 0x00000413, RtlDebugSetLevel, kFunction), +XE_EXPORT(xam, 0x00000414, CloseHandle, kFunction), +XE_EXPORT(xam, 0x00000415, GetTickCount, kFunction), +XE_EXPORT(xam, 0x00000416, GetLastError, kFunction), +XE_EXPORT(xam, 0x00000417, SetFilePointer, kFunction), +XE_EXPORT(xam, 0x00000418, SetFilePointerEx, kFunction), +XE_EXPORT(xam, 0x00000419, SetLastError, kFunction), +XE_EXPORT(xam, 0x0000041A, MultiByteToWideChar, kFunction), +XE_EXPORT(xam, 0x0000041B, WideCharToMultiByte, kFunction), +XE_EXPORT(xam, 0x0000041C, ReadFile, kFunction), +XE_EXPORT(xam, 0x0000041D, FlushFileBuffers, kFunction), +XE_EXPORT(xam, 0x0000041E, WriteFile, kFunction), +XE_EXPORT(xam, 0x0000041F, OutputDebugStringW, kFunction), +XE_EXPORT(xam, 0x00000420, SetEvent, kFunction), +XE_EXPORT(xam, 0x00000421, XapiFormatTimeOut, kFunction), +XE_EXPORT(xam, 0x00000422, CreateMutexA, kFunction), +XE_EXPORT(xam, 0x00000423, OpenMutexA, kFunction), +XE_EXPORT(xam, 0x00000424, ReleaseMutex, kFunction), +XE_EXPORT(xam, 0x00000425, WaitForSingleObject, kFunction), +XE_EXPORT(xam, 0x00000426, WaitForSingleObjectEx, kFunction), +XE_EXPORT(xam, 0x00000427, GetFileSize, kFunction), +XE_EXPORT(xam, 0x00000428, GetFileSizeEx, kFunction), +XE_EXPORT(xam, 0x00000429, XapiDirectoryInformationToFindData, kFunction), +XE_EXPORT(xam, 0x0000042A, XapiFormatObjectAttributes, kFunction), +XE_EXPORT(xam, 0x0000042B, ResetEvent, kFunction), +XE_EXPORT(xam, 0x0000042C, wsprintfA, kFunction), +XE_EXPORT(xam, 0x0000042D, wsprintfW, kFunction), +XE_EXPORT(xam, 0x0000042E, GetOverlappedResult, kFunction), +XE_EXPORT(xam, 0x0000042F, QueryPerformanceCounter, kFunction), +XE_EXPORT(xam, 0x00000430, QueryPerformanceFrequency, kFunction), +XE_EXPORT(xam, 0x00000431, LocalAlloc, kFunction), +XE_EXPORT(xam, 0x00000432, LocalFree, kFunction), +XE_EXPORT(xam, 0x00000433, RaiseException, kFunction), +XE_EXPORT(xam, 0x00000434, RtlUniform, kFunction), +XE_EXPORT(xam, 0x00000435, RtlRandom, kFunction), +XE_EXPORT(xam, 0x00000436, Sleep, kFunction), +XE_EXPORT(xam, 0x00000437, SleepEx, kFunction), +XE_EXPORT(xam, 0x00000438, XMemSet, kFunction), +XE_EXPORT(xam, 0x00000439, XRegisterThreadNotifyRoutine, kFunction), +XE_EXPORT(xam, 0x0000043A, XGetOverlappedExtendedError, kFunction), +XE_EXPORT(xam, 0x0000043B, XGetOverlappedResult, kFunction), +XE_EXPORT(xam, 0x0000043C, CreateThread, kFunction), +XE_EXPORT(xam, 0x0000043D, ResumeThread, kFunction), +XE_EXPORT(xam, 0x0000043E, ExitThread, kFunction), +XE_EXPORT(xam, 0x0000043F, GetTimeZoneInformation, kFunction), +XE_EXPORT(xam, 0x00000440, GetSystemTimeAsFileTime, kFunction), +XE_EXPORT(xam, 0x00000441, SystemTimeToFileTime, kFunction), +XE_EXPORT(xam, 0x00000442, FileTimeToSystemTime, kFunction), +XE_EXPORT(xam, 0x00000443, GetSystemTime, kFunction), +XE_EXPORT(xam, 0x00000444, GetLocalTime, kFunction), +XE_EXPORT(xam, 0x00000445, CreateDirectoryA, kFunction), +XE_EXPORT(xam, 0x00000446, CreateEventA, kFunction), +XE_EXPORT(xam, 0x00000447, CreateFileA, kFunction), +XE_EXPORT(xam, 0x00000448, DeleteFileA, kFunction), +XE_EXPORT(xam, 0x00000449, FindFirstFileA, kFunction), +XE_EXPORT(xam, 0x0000044A, FindNextFileA, kFunction), +XE_EXPORT(xam, 0x0000044B, GetFileAttributesA, kFunction), +XE_EXPORT(xam, 0x0000044C, XamLoaderGetCurrentTitleD3DVersion, kFunction), +XE_EXPORT(xam, 0x0000044D, GetFileAttributesExA, kFunction), +XE_EXPORT(xam, 0x0000044E, GetModuleHandleA, kFunction), +XE_EXPORT(xam, 0x0000044F, GetDiskFreeSpaceExA, kFunction), +XE_EXPORT(xam, 0x00000450, CopyFileA, kFunction), +XE_EXPORT(xam, 0x00000451, SetEndOfFile, kFunction), +XE_EXPORT(xam, 0x00000452, XamFamilyAddParentalExemptionToList, kFunction), +XE_EXPORT(xam, 0x00000453, XamFamilyIsParentalValidationRequired, kFunction), +XE_EXPORT(xam, 0x00000454, PIXBeginCapture, kFunction), +XE_EXPORT(xam, 0x00000455, PIXEndCapture, kFunction), +XE_EXPORT(xam, 0x00000456, PIXAddCounter, kFunction), +XE_EXPORT(xam, 0x00000457, PIXGetGPUSlot, kFunction), +XE_EXPORT(xam, 0x00000458, SetWaitableTimer, kFunction), +XE_EXPORT(xam, 0x00000459, CancelWaitableTimer, kFunction), +XE_EXPORT(xam, 0x0000045A, CreateWaitableTimerA, kFunction), +XE_EXPORT(xam, 0x0000045B, DuplicateHandle, kFunction), +XE_EXPORT(xam, 0x0000045C, XapipCreateThread, kFunction), +XE_EXPORT(xam, 0x0000045D, lstrcpyA, kFunction), +XE_EXPORT(xam, 0x0000045E, lstrcpyW, kFunction), +XE_EXPORT(xam, 0x0000045F, lstrcpynA, kFunction), +XE_EXPORT(xam, 0x00000460, lstrcpynW, kFunction), +XE_EXPORT(xam, 0x00000461, lstrcatA, kFunction), +XE_EXPORT(xam, 0x00000462, lstrcatW, kFunction), +XE_EXPORT(xam, 0x00000463, lstrlenA, kFunction), +XE_EXPORT(xam, 0x00000464, lstrlenW, kFunction), +XE_EXPORT(xam, 0x00000465, IsBadReadPtr, kFunction), +XE_EXPORT(xam, 0x00000466, IsBadWritePtr, kFunction), +XE_EXPORT(xam, 0x00000467, FileTimeToLocalFileTime, kFunction), +XE_EXPORT(xam, 0x00000468, XMemCpy, kFunction), +XE_EXPORT(xam, 0x00000469, XMemCpyStreaming, kFunction), +XE_EXPORT(xam, 0x0000046A, XamHudSetUserIndex, kFunction), +XE_EXPORT(xam, 0x0000046B, XamShowNuiTroubleshooterUI, kFunction), +XE_EXPORT(xam, 0x0000046C, XamTestShowNuiTroubleshooterUI, kFunction), +XE_EXPORT(xam, 0x0000046D, XamShowPasscodeVerifyUIEx, kFunction), +XE_EXPORT(xam, 0x0000046E, XamShowNuiAchievementsUI, kFunction), +XE_EXPORT(xam, 0x0000046F, XamShowNuiCommunitySessionsUI, kFunction), +XE_EXPORT(xam, 0x00000470, XamShowNuiDeviceSelectorUI, kFunction), +XE_EXPORT(xam, 0x00000471, XamShowNuiDirtyDiscErrorUI, kFunction), +XE_EXPORT(xam, 0x00000472, XamShowNuiFriendsUI, kFunction), +XE_EXPORT(xam, 0x00000473, XamShowNuiGameInviteUI, kFunction), +XE_EXPORT(xam, 0x00000474, XamShowNuiGamerCardUIForXUID, kFunction), +XE_EXPORT(xam, 0x00000475, XamShowNuiMarketplaceDownloadItemsUI, kFunction), +XE_EXPORT(xam, 0x00000476, XamShowNuiMarketplaceUI, kFunction), +XE_EXPORT(xam, 0x00000477, XamShowNuiMessageBoxUI, kFunction), +XE_EXPORT(xam, 0x00000478, XamShowNuiPartyUI, kFunction), +XE_EXPORT(xam, 0x00000479, XamShowNuiFriendRequestUI, kFunction), +XE_EXPORT(xam, 0x0000047A, XamShowNuiSigninUI, kFunction), +XE_EXPORT(xam, 0x0000047B, XamShowNuiControllerRequiredUI, kFunction), +XE_EXPORT(xam, 0x0000047C, XamShowNuiGamesUI, kFunction), +XE_EXPORT(xam, 0x0000047D, XamShowNuiHardwareRequiredUI, kFunction), +XE_EXPORT(xam, 0x0000047E, XamCacheStoreFileByString, kFunction), +XE_EXPORT(xam, 0x0000047F, XamCacheFetchFileByString, kFunction), +XE_EXPORT(xam, 0x00000480, XamCacheDeleteFileByString, kFunction), +XE_EXPORT(xam, 0x00000481, XamGetCachedTitleNameEx, kFunction), +XE_EXPORT(xam, 0x00000482, XamXlfsInitializeUploadQueue, kFunction), +XE_EXPORT(xam, 0x00000483, XamXlfsUninitializeUploadQueue, kFunction), +XE_EXPORT(xam, 0x00000484, XamXlfsMountUploadQueueInstance, kFunction), +XE_EXPORT(xam, 0x00000485, XamXlfsUnmountUploadQueueInstance, kFunction), +XE_EXPORT(xam, 0x00000486, XamVoiceRecordUserPrivileges, kFunction), +XE_EXPORT(xam, 0x00000487, XamXlfsInitializeUploadQueueWithTestHooks, kFunction), +XE_EXPORT(xam, 0x00000488, XamXlfsNotifyContentDeletion, kFunction), +XE_EXPORT(xam, 0x00000489, XMemAlloc, kFunction), +XE_EXPORT(xam, 0x0000048A, XMemFree, kFunction), +XE_EXPORT(xam, 0x0000048B, XMemSize, kFunction), +XE_EXPORT(xam, 0x0000048C, XamVoiceSetMicArrayIdleUsers, kFunction), +XE_EXPORT(xam, 0x0000048D, XamVoiceMuteMicArray, kFunction), +XE_EXPORT(xam, 0x0000048E, XamVoiceGetMicArrayUnderrunStatus, kFunction), +XE_EXPORT(xam, 0x0000048F, XuiSceneEnableTransitionDependency, kFunction), +XE_EXPORT(xam, 0x00000490, XamVoiceGetMicArrayAudioEx, kFunction), +XE_EXPORT(xam, 0x00000491, XamVoiceDisableMicArray, kFunction), +XE_EXPORT(xam, 0x00000492, XamUserGetDeviceId, kFunction), +XE_EXPORT(xam, 0x00000493, XamUpdateEtxLogUpdateTaskStart, kFunction), +XE_EXPORT(xam, 0x00000494, XamUpdateEtxLogUpdateTaskSuccess, kFunction), +XE_EXPORT(xam, 0x00000495, XamUpdateEtxLogUpdateTaskFailure, kFunction), +XE_EXPORT(xam, 0x00000496, XamEtxFlushLogs, kFunction), +XE_EXPORT(xam, 0x00000497, XamVoiceIsActiveProcess, kFunction), +XE_EXPORT(xam, 0x00000498, XamInactivityGetInactivityInterruptTime, kFunction), +XE_EXPORT(xam, 0x00000499, XamInactivitySetInactivityInterruptTime, kFunction), +XE_EXPORT(xam, 0x0000049A, XamInactivityGetLastActivityTime, kFunction), +XE_EXPORT(xam, 0x0000049B, XamInactivitySetDetectionTaskPeriod, kFunction), +XE_EXPORT(xam, 0x0000049C, XamInactivityEnablePowerDown, kFunction), +XE_EXPORT(xam, 0x0000049D, XamUpdateGetChainMarker, kFunction), +XE_EXPORT(xam, 0x0000049E, XGetVideoCapabilities, kFunction), +XE_EXPORT(xam, 0x0000049F, XMsgProcessRequest, kFunction), +XE_EXPORT(xam, 0x000004A0, XGetDisplaySize, kFunction), +XE_EXPORT(xam, 0x000004A1, XamInputNonControllerGetRaw, kFunction), +XE_EXPORT(xam, 0x000004A2, XamInputNonControllerSetRaw, kFunction), +XE_EXPORT(xam, 0x000004A3, XamVoiceSetMicArrayBeamAngle, kFunction), +XE_EXPORT(xam, 0x000004A4, XamUserGetAge, kFunction), +XE_EXPORT(xam, 0x000004A5, XamUserGetAgeGroup, kFunction), +XE_EXPORT(xam, 0x000004A6, XamVoiceGetMicArrayFilenameDesc, kFunction), +XE_EXPORT(xam, 0x000004A7, XamLoaderGetState, kFunction), +XE_EXPORT(xam, 0x000004A8, XamTaskQueryProperty, kFunction), +XE_EXPORT(xam, 0x000004A9, XamGetLocale, kFunction), +XE_EXPORT(xam, 0x000004AA, XamQueryTimeZoneInformation, kFunction), +XE_EXPORT(xam, 0x000004AB, XamSetTimeZoneInformation, kFunction), +XE_EXPORT(xam, 0x000004AC, XamLaunchURI, kFunction), +XE_EXPORT(xam, 0x000004AF, XamShowNuiMessagesUI, kFunction), +XE_EXPORT(xam, 0x000004B0, XMPRegisterCodec, kFunction), +XE_EXPORT(xam, 0x000004B1, XamNavigateBack, kFunction), +XE_EXPORT(xam, 0x000004B2, XamPushBackURI, kFunction), +XE_EXPORT(xam, 0x000004B3, XamUserOverrideDeviceBindings, kFunction), +XE_EXPORT(xam, 0x000004B4, XamUserOverrideBindingCallbacks, kFunction), +XE_EXPORT(xam, 0x000004B5, XamUserOverrideUserInfo, kFunction), +XE_EXPORT(xam, 0x000004B6, XamUserContentRestrictionGetFlags, kFunction), +XE_EXPORT(xam, 0x000004B7, XamUserContentRestrictionGetRating, kFunction), +XE_EXPORT(xam, 0x000004B8, XamUserContentRestrictionCheckAccess, kFunction), +XE_EXPORT(xam, 0x000004B9, XamShowFitnessBodyProfileUI, kFunction), +XE_EXPORT(xam, 0x000004BA, XamFitnessAddBodyProfileRecord, kFunction), +XE_EXPORT(xam, 0x000004BB, XamFamilyGetMembers, kFunction), +XE_EXPORT(xam, 0x000004BC, XampXAuthStartup, kFunction), +XE_EXPORT(xam, 0x000004BD, XampXAuthShutdown, kFunction), +XE_EXPORT(xam, 0x000004BE, XamGetToken, kFunction), +XE_EXPORT(xam, 0x000004BF, XamFreeToken, kFunction), +XE_EXPORT(xam, 0x000004C0, XamGetAppliesTo, kFunction), +XE_EXPORT(xam, 0x000004C1, XamFitnessClearBodyProfileRecords, kFunction), +XE_EXPORT(xam, 0x000004C2, XamFitnessGetCurrentBodyProfileRecord, kFunction), +XE_EXPORT(xam, 0x000004C3, XamFitnessGetAllBodyProfileRecords, kFunction), +XE_EXPORT(xam, 0x000004C4, XamFitnessGetAllTitleSummaries, kFunction), +XE_EXPORT(xam, 0x000004C5, XamFitnessGetOverallSummary, kFunction), +XE_EXPORT(xam, 0x000004C6, XamFitnessAddFitnessEvent, kFunction), +XE_EXPORT(xam, 0x000004C7, XamLrcGetInput, kFunction), +XE_EXPORT(xam, 0x000004C8, XamLrcGetInputWithSeek, kFunction), +XE_EXPORT(xam, 0x000004C9, XamLrcSetMediaState, kFunction), +XE_EXPORT(xam, 0x000004CA, XamPixSetDirtyCounters, kFunction), +XE_EXPORT(xam, 0x000004CB, XamFitnessCreateFitnessEventEnumerator, kFunction), +XE_EXPORT(xam, 0x000004CC, XamFitnessInitialize, kFunction), +XE_EXPORT(xam, 0x000004CD, XamRequestToken, kFunction), +XE_EXPORT(xam, 0x000004CE, XamResolveURI, kFunction), +XE_EXPORT(xam, 0x000004CF, XamContentGetOnlineCreator, kFunction), +XE_EXPORT(xam, 0x000004D0, XamShowBrandedKeyboardUI, kFunction), +XE_EXPORT(xam, 0x000004D1, XamBackgroundDownloadNetworkStorageEnable, kFunction), +XE_EXPORT(xam, 0x000004D2, XamBackgroundDownloadNetworkStorageIsEnabled, kFunction), +XE_EXPORT(xam, 0x000004D3, XamShowNuiJoinSessionInProgressUI, kFunction), +XE_EXPORT(xam, 0x000004D4, XamBase64Decode, kFunction), +XE_EXPORT(xam, 0x000004D5, XamCertDecode, kFunction), +XE_EXPORT(xam, 0x000004D6, XamCertDecodeRsaPublicKey, kFunction), +XE_EXPORT(xam, 0x000004D7, XamCertValidateStruct, kFunction), +XE_EXPORT(xam, 0x000004D8, XamFitnessConvertByteMetToFloatMet, kFunction), +XE_EXPORT(xam, 0x000004D9, XamXgiBlobTrackerSetMockInfo, kFunction), +XE_EXPORT(xam, 0x000004DA, XamFitnessMsgTimeToSystemTime, kFunction), +XE_EXPORT(xam, 0x000004DB, XamFitnessSystemTimeToMsgTime, kFunction), +XE_EXPORT(xam, 0x000004DC, XamShowFitnessWarnAboutPrivacyUI, kFunction), +XE_EXPORT(xam, 0x000004DD, XamShowFitnessWarnAboutTimeUI, kFunction), +XE_EXPORT(xam, 0x000004DE, XamFitnessUnInitialize, kFunction), +XE_EXPORT(xam, 0x000004DF, XamBackgroundDownloadNetworkStorageOnContentChange, kFunction), +XE_EXPORT(xam, 0x000004E0, XamLiveBaseConfigureInMemoryMockResponse, kFunction), +XE_EXPORT(xam, 0x000004E1, InjectConnectionServerNotification, kFunction), +XE_EXPORT(xam, 0x000004E2, XamFitnessConvertFloatMetToByteMet, kFunction), +XE_EXPORT(xam, 0x000004E3, XamGetGamerTileKeyFromGamertag, kFunction), +XE_EXPORT(xam, 0x000004E4, XamBackgroundDownloadNetworkStorageRegisterChangeCallback, kFunction), +XE_EXPORT(xam, 0x000004E5, XamFindOrCreateInternalPassportAccount, kFunction), +XE_EXPORT(xam, 0x000004E6, XOnlinepFriendsRequest, kFunction), +XE_EXPORT(xam, 0x000004E7, XOnlinepFriendsAcceptRequest, kFunction), +XE_EXPORT(xam, 0x000004E8, XOnlinepFriendsRejectRequest, kFunction), +XE_EXPORT(xam, 0x000004E9, XOnlinepFriendsRemove, kFunction), +XE_EXPORT(xam, 0x000004EA, XFriendsCreateEnumerator, kFunction), +XE_EXPORT(xam, 0x000004EB, XamBackgroundDownloadNetworkStorageIsRunning, kFunction), +XE_EXPORT(xam, 0x000004EC, XamCertGetSerialNumber, kFunction), +XE_EXPORT(xam, 0x000004ED, XamShowOptionsUI, kFunction), +XE_EXPORT(xam, 0x000004EE, XampXAuthGetTitleBuffer, kFunction), +XE_EXPORT(xam, 0x000004EF, XamGetSTSTokenCache, kFunction), +XE_EXPORT(xam, 0x000004F0, XamUserGetOnlineXUIDFromOfflineXUID, kFunction), +XE_EXPORT(xam, 0x000004F1, XamIsUserUsingMetricSystem, kFunction), +XE_EXPORT(xam, 0x000004F2, XamShowNuiVideoRichPresenceUI, kFunction), +XE_EXPORT(xam, 0x000004F3, XamAppAllocateInterappWorkspaceEx, kFunction), +XE_EXPORT(xam, 0x000004F4, XampKioskSetTestMock, kFunction), +XE_EXPORT(xam, 0x000004F5, XamNetworkStatusGetInformation, kFunction), +XE_EXPORT(xam, 0x000004F6, XamNetworkStatusAddAddress, kFunction), +XE_EXPORT(xam, 0x000004F7, XamUserReadUserPreference, kFunction), +XE_EXPORT(xam, 0x000004F8, XamUserWriteUserPreference, kFunction), +XE_EXPORT(xam, 0x000004F9, XamShowFitnessClearUI, kFunction), +XE_EXPORT(xam, 0x000004FA, XamFitnessClearAll, kFunction), +XE_EXPORT(xam, 0x000004FB, XamFitnessGetPrivacySettings, kFunction), +XE_EXPORT(xam, 0x000004FC, XamWaitForNSAL, kFunction), +XE_EXPORT(xam, 0x000004FD, XamMarkInternalAccountTrustedOnConsole, kFunction), +XE_EXPORT(xam, 0x000004FE, XamBackgroundDownloadNetworkStorageGetProgress, kFunction), +XE_EXPORT(xam, 0x000004FF, XamCopyFile, kFunction), +XE_EXPORT(xam, 0x00000500, XamMoveFile, kFunction), +XE_EXPORT(xam, 0x00000501, XamDeleteFile, kFunction), +XE_EXPORT(xam, 0x00000502, XamUserOverrideGlobalState, kFunction), +XE_EXPORT(xam, 0x00000503, XamGetAdaptersCollection, kFunction), +XE_EXPORT(xam, 0x00000504, XampKioskIsSimulationMode, kFunction), +XE_EXPORT(xam, 0x00000505, XamIsUIThread, kFunction), +XE_EXPORT(xam, 0x00000506, XamInputSendXenonButtonPress, kFunction), +XE_EXPORT(xam, 0x00000507, XamDebugGetURISchemeCount, kFunction), +XE_EXPORT(xam, 0x00000508, XamDebugGetURISchemeInfo, kFunction), +XE_EXPORT(xam, 0x00000509, XamGetOnlineCountryFromLocale, kFunction), +XE_EXPORT(xam, 0x0000050A, XTestOnlineIsConnectedToLive, kFunction), +XE_EXPORT(xam, 0x0000050B, XamGetConsoleFriendlyName, kFunction), +XE_EXPORT(xam, 0x0000050C, XamSetConsoleFriendlyName, kFunction), +XE_EXPORT(xam, 0x0000050D, XamGetCountry, kFunction), +XE_EXPORT(xam, 0x0000050E, XamPackageManagerGetFilePathW, kFunction), +XE_EXPORT(xam, 0x0000050F, XamGetCurrentDemand, kFunction), +XE_EXPORT(xam, 0x00000510, XamCompleteDemand, kFunction), +XE_EXPORT(xam, 0x00000511, XamDemand, kFunction), +XE_EXPORT(xam, 0x00000512, XamFormatSystemDateString, kFunction), +XE_EXPORT(xam, 0x00000513, XamDebugGetBackURI, kFunction), +XE_EXPORT(xam, 0x00000514, XamIsCurrentTitleIptv, kFunction), +XE_EXPORT(xam, 0x00000515, XamIsIptvEnabled, kFunction), +XE_EXPORT(xam, 0x00000516, XamIsDvrRecording, kFunction), +XE_EXPORT(xam, 0x00000517, XamIptvUninstall, kFunction), +XE_EXPORT(xam, 0x00000518, XamGetDvrStorage, kFunction), +XE_EXPORT(xam, 0x00000519, XamSetDvrStorage, kFunction), +XE_EXPORT(xam, 0x0000051A, XamIptvGetServiceName, kFunction), +XE_EXPORT(xam, 0x0000051B, XamNuiHudGetEngagedEnrollmentIndex, kFunction), +XE_EXPORT(xam, 0x0000051C, XamProfileSetCachedWindowsLiveEmail, kFunction), +XE_EXPORT(xam, 0x0000051D, XamProfileGetCachedWindowsLiveEmail, kFunction), +XE_EXPORT(xam, 0x0000051E, XamUserResetSubscriptionType, kFunction), +XE_EXPORT(xam, 0x0000051F, XamLrcSetTitlePort, kFunction), +XE_EXPORT(xam, 0x00000520, XamLrcVerifyClientId, kFunction), +XE_EXPORT(xam, 0x00000521, XamLrcEncryptDecryptTitleMessage, kFunction), +XE_EXPORT(xam, 0x00000522, XamFitnessGetSyncStatus, kFunction), +XE_EXPORT(xam, 0x00000523, XamFitnessInitializeForOneUser, kFunction), +XE_EXPORT(xam, 0x00000524, XamFitnessGetSuggestedPrivacySettings, kFunction), +XE_EXPORT(xam, 0x00000525, XampFitnessLetFireAndForgetsCatchUpInternal, kFunction), +XE_EXPORT(xam, 0x00000526, XamInputGetFailedConnectionOrBind, kFunction), +XE_EXPORT(xam, 0x00000527, XuiSceneIsInTransition, kFunction), +XE_EXPORT(xam, 0x00000528, XamIsOnPrivateNetwork, kFunction), +XE_EXPORT(xam, 0x00000529, XamInputSetMinMaxAuthDelay, kFunction), +XE_EXPORT(xam, 0x0000052A, XamInputNonControllerGetRawEx, kFunction), +XE_EXPORT(xam, 0x0000052B, XamInputNonControllerSetRawEx, kFunction), +XE_EXPORT(xam, 0x0000052C, XamMarketplaceAcquireFreeContent, kFunction), +XE_EXPORT(xam, 0x0000052D, XamGetClosedCaptioningState, kFunction), +XE_EXPORT(xam, 0x0000052E, XamGetClosedCaptioningSettings, kFunction), +XE_EXPORT(xam, 0x0000052F, XamSetClosedCaptioningState, kFunction), +XE_EXPORT(xam, 0x00000530, XamLoaderGetLogonTitle, kFunction), +XE_EXPORT(xam, 0x00000531, XamBeginDemand, kFunction), +XE_EXPORT(xam, 0x00000532, XamGetErrorStringFromWebService, kFunction), +XE_EXPORT(xam, 0x00000533, XamGetModernPresenceWorkspaceSize, kFunction), +XE_EXPORT(xam, 0x00000534, XamGetModernPresence, kFunction), +XE_EXPORT(xam, 0x00000535, XamGetSingleModernPresence, kFunction), +XE_EXPORT(xam, 0x00000536, XamGetModernPresenceImageUrl, kFunction), +XE_EXPORT(xam, 0x00000537, XGetSSLCertBypassEnabled, kFunction), +XE_EXPORT(xam, 0x00000538, XamIsNetworkCaptivePortal, kFunction), +XE_EXPORT(xam, 0x00000539, XamShowAndWaitForMessageBoxEx, kFunction), +XE_EXPORT(xam, 0x0000053B, XamGetCurrencyFormat, kFunction), +XE_EXPORT(xam, 0x0000053C, XamFormatCurrency, kFunction), +XE_EXPORT(xam, 0x0000053D, XamReportTLSConnect, kFunction), +XE_EXPORT(xam, 0x0000053E, XamGetXSTSTokenExpiryPeriodMS, kFunction), +XE_EXPORT(xam, 0x0000053F, XamGetUserBalance, kFunction), +XE_EXPORT(xam, 0x00000540, XamIsGuideDisabled, kFunction), +XE_EXPORT(xam, 0x00000541, XampCallXAccountTransitionStoredValuePointsToCurrency, kFunction), +XE_EXPORT(xam, 0x00000542, XampSetMockCallXAccountTransitionStoredValuePointsToCurrency, kFunction), +XE_EXPORT(xam, 0x00000543, XamShowCsvTransitionUI, kFunction), +XE_EXPORT(xam, 0x00000544, XamAskUserForCSVDrainagePermission, kFunction), +XE_EXPORT(xam, 0x00000545, XamIsCSVDrainageSupported, kFunction), +XE_EXPORT(xam, 0x0000056C, XamGetTLSConfig, kFunction), +XE_EXPORT(xam, 0x00000577, XamGetServiceEndpoint, kFunction), +XE_EXPORT(xam, 0x00000578, XamReminderGetItems, kFunction), +XE_EXPORT(xam, 0x00000579, XamReminderClearItems, kFunction), +XE_EXPORT(xam, 0x0000057A, XamReminderItemAdd, kFunction), +XE_EXPORT(xam, 0x0000057B, XamReminderItemRemove, kFunction), +XE_EXPORT(xam, 0x0000057C, XamReminderGetNextItem, kFunction), +XE_EXPORT(xam, 0x0000057D, XamReminderGetModifiedTime, kFunction), +XE_EXPORT(xam, 0x0000057E, XamReminderClearCache, kFunction), +XE_EXPORT(xam, 0x0000057F, XamLrcKeyboardGetInput, kFunction), +XE_EXPORT(xam, 0x00000580, XamLrcKeyboardGetRequiredBufferSize, kFunction), +XE_EXPORT(xam, 0x00000581, XamLrcKeyboardRegister, kFunction), +XE_EXPORT(xam, 0x00000582, XamLrcKeyboardUnregister, kFunction), +XE_EXPORT(xam, 0x00000583, XamLrcKeyboardUpdateText, kFunction), +XE_EXPORT(xam, 0x00000584, XamValidateCountry, kFunction), +XE_EXPORT(xam, 0x00000585, XamGetOnlineCountryString, kFunction), +XE_EXPORT(xam, 0x00000586, XamGetCountryString, kFunction), +XE_EXPORT(xam, 0x00000587, XamGetLanguageString, kFunction), +XE_EXPORT(xam, 0x00000588, XamGetLanguageLocaleString, kFunction), +XE_EXPORT(xam, 0x00000589, XamGetOnlineLanguageAndCountryString, kFunction), +XE_EXPORT(xam, 0x0000058A, XamGetLanguageLocaleFallbackString, kFunction), +XE_EXPORT(xam, 0x0000058B, XamGetOnlineLanguageAndCountry, kFunction), +XE_EXPORT(xam, 0x0000058C, XamGetLanguageTypeface, kFunction), +XE_EXPORT(xam, 0x0000058D, XamGetLanguageTypefacePatch, kFunction), +XE_EXPORT(xam, 0x0000058E, XamGetLocaleString, kFunction), +XE_EXPORT(xam, 0x0000058F, XamGetLocaleFromOnlineCountry, kFunction), +XE_EXPORT(xam, 0x00000590, XamOfflineTimerSetData, kFunction), +XE_EXPORT(xam, 0x00000591, XamOfflineTimerResume, kFunction), +XE_EXPORT(xam, 0x00000592, XamOfflineTimerSuspend, kFunction), +XE_EXPORT(xam, 0x00000593, XamOfflineTimerIsRunning, kFunction), +XE_EXPORT(xam, 0x00000594, XamOfflineTimerIsEnabled, kFunction), +XE_EXPORT(xam, 0x00000595, XamOfflineTimerGetTimeRemaining, kFunction), +XE_EXPORT(xam, 0x00000596, XamOfflineTimerGetContractData, kFunction), +XE_EXPORT(xam, 0x00000597, XamOfflineTimerInitialize, kFunction), +XE_EXPORT(xam, 0x00000598, XamOfflineTimerGetData, kFunction), +XE_EXPORT(xam, 0x00000599, XamPlayToRegister, kFunction), +XE_EXPORT(xam, 0x0000059A, XamPlayToReportPlaybackState, kFunction), +XE_EXPORT(xam, 0x0000059B, XamPlayToUnregister, kFunction), +XE_EXPORT(xam, 0x0000059C, XamShowTFAUI, kFunction), +XE_EXPORT(xam, 0x0000059D, OnReconnect, kFunction), +XE_EXPORT(xam, 0x0000059E, XamGetOnlineCountryFeatures, kFunction), +XE_EXPORT(xam, 0x0000059F, XamLogLocalizationEtx, kFunction), +XE_EXPORT(xam, 0x000005A0, XampXAuthIsLocalSocketAllowed, kFunction), +XE_EXPORT(xam, 0x000005A1, XamPlayToGetRequest, kFunction), +XE_EXPORT(xam, 0x000005A2, XamPlayToCancelGetRequest, kFunction), +XE_EXPORT(xam, 0x000005A3, XamPlayToCompleteRequest, kFunction), +XE_EXPORT(xam, 0x000005A4, XamFitnessGetTitleSummaries, kFunction), +XE_EXPORT(xam, 0x000005A5, XamFitnessGetTitleSummary, kFunction), +XE_EXPORT(xam, 0x000005A6, XamOfflineTimerShutdown, kFunction), +XE_EXPORT(xam, 0x000005A7, XamFitnessContainsFitnessData, kFunction), +XE_EXPORT(xam, 0x000005A8, XamGetLanguageFromOnlineLanguage, kFunction), +XE_EXPORT(xam, 0x000005A9, XamGetOnlineLanguageString, kFunction), +XE_EXPORT(xam, 0x000005AA, XamGetCountryFromOnlineCountry, kFunction), +XE_EXPORT(xam, 0x000005D7, XamGetLocaleEx, kFunction), +XE_EXPORT(xam, 0x000005D8, XamOfflineTimerForceQuery, kFunction), +XE_EXPORT(xam, 0x000005D9, XamShowCreateProfileUIEx, kFunction), +XE_EXPORT(xam, 0x000005DA, XTLGetLanguageV2, kFunction), +XE_EXPORT(xam, 0x000005DB, XTLGetLocaleV1, kFunction), +XE_EXPORT(xam, 0x000005DC, XamAvatarInitialize, kFunction), +XE_EXPORT(xam, 0x000005DD, XamAvatarShutdown, kFunction), +XE_EXPORT(xam, 0x000005DE, XamAvatarGetManifestLocalUser, kFunction), +XE_EXPORT(xam, 0x000005DF, XamAvatarGetManifestsByXuid, kFunction), +XE_EXPORT(xam, 0x000005E0, XamAvatarGetAssetsResultSize, kFunction), +XE_EXPORT(xam, 0x000005E1, XamAvatarGetAssets, kFunction), +XE_EXPORT(xam, 0x000005E2, XamAvatarGenerateMipMaps, kFunction), +XE_EXPORT(xam, 0x000005E3, XamAvatarSetCustomAsset, kFunction), +XE_EXPORT(xam, 0x000005E4, XamAvatarSetManifest, kFunction), +XE_EXPORT(xam, 0x000005E5, EnumerateMediaObjects, kFunction), +XE_EXPORT(xam, 0x000005E6, EnumerateMediaObjects_, kFunction), +XE_EXPORT(xam, 0x000005E7, XamAvatarLoadAnimation, kFunction), +XE_EXPORT(xam, 0x000005E8, XamAvatarBeginEnumAssets, kFunction), +XE_EXPORT(xam, 0x000005E9, XamAvatarEndEnumAssets, kFunction), +XE_EXPORT(xam, 0x000005EA, XamAvatarEnumAssets, kFunction), +XE_EXPORT(xam, 0x000005EB, XamAvatarGetMetadataRandom, kFunction), +XE_EXPORT(xam, 0x000005EC, EnumerateMediaObjects_0, kFunction), +XE_EXPORT(xam, 0x000005ED, EnumerateMediaObjects_1, kFunction), +XE_EXPORT(xam, 0x000005EE, XamAvatarGetMetadataSignedOutProfileCount, kFunction), +XE_EXPORT(xam, 0x000005EF, XamAvatarGetMetadataSignedOutProfile, kFunction), +XE_EXPORT(xam, 0x000005F0, EnumerateMediaObjects_2, kFunction), +XE_EXPORT(xam, 0x000005F1, XamAvatarManifestGetBodyType, kFunction), +XE_EXPORT(xam, 0x000005F2, XamAvatarGetInstrumentation, kFunction), +XE_EXPORT(xam, 0x000005F3, XamAvatarGetAssetIcon, kFunction), +XE_EXPORT(xam, 0x000005F4, XamAvatarWearNow, kFunction), +XE_EXPORT(xam, 0x000005F5, XamAvatarGetAssetBinary, kFunction), +XE_EXPORT(xam, 0x000005F6, XamAvatarReinstallAwardedAsset, kFunction), +XE_EXPORT(xam, 0x000005F7, XamAvatarGetInstalledAssetPackageDescription, kFunction), +XE_EXPORT(xam, 0x000005F8, XamAvatarSetMocks, kFunction), +XE_EXPORT(xam, 0x000005F9, XamLrcKeyboardValidateTextChange, kFunction), +XE_EXPORT(xam, 0x000005FA, XamLrcKeyboardApplyTextChange, kFunction), +XE_EXPORT(xam, 0x000005FB, XamLrcLogSessionSummary, kFunction), +XE_EXPORT(xam, 0x000005FC, XamLrcLogError, kFunction), +XE_EXPORT(xam, 0x0000060E, XamContentMountInstalledGame, kFunction), +XE_EXPORT(xam, 0x0000060F, XamContentIsGameInstalledToHDD, kFunction), +XE_EXPORT(xam, 0x00000610, XamContentQueryLicenseInternal, kFunction), +XE_EXPORT(xam, 0x00000611, XamContentGetDeviceVolumePath, kFunction), +XE_EXPORT(xam, 0x00000612, XamContentDeviceCheckUpdates, kFunction), +XE_EXPORT(xam, 0x00000613, XamContentGetHeaderInternal, kFunction), +XE_EXPORT(xam, 0x00000614, XamNetworkStorageGetNetworkDevice, kFunction), +XE_EXPORT(xam, 0x00000615, XamNetworkStorageDeviceHasCacheFile, kFunction), +XE_EXPORT(xam, 0x00000616, XamNetworkStorageCreateCacheOnDevice, kFunction), +XE_EXPORT(xam, 0x00000617, XamNetworkStorageDeleteCacheOnDevice, kFunction), +XE_EXPORT(xam, 0x00000618, XamNetworkStorageGetStatus, kFunction), +XE_EXPORT(xam, 0x00000619, XamNetworkStorageIsSupportedContentType, kFunction), +XE_EXPORT(xam, 0x0000061A, XamNetworkStorageSetTestMock, kFunction), +XE_EXPORT(xam, 0x0000061B, XamNetworkStorageGetLastSyncTime, kFunction), +XE_EXPORT(xam, 0x0000061C, XamShowNetworkStorageSyncUI, kFunction), +XE_EXPORT(xam, 0x0000061D, XamUserIsLogonPreviewModeEnabled, kFunction), +XE_EXPORT(xam, 0x0000061E, XamUserLockLogonPreviewMode, kFunction), +XE_EXPORT(xam, 0x0000061F, XamUserUnlockLogonPreviewMode, kFunction), +XE_EXPORT(xam, 0x00000620, XamNetworkStorageIsUserInSync, kFunction), +XE_EXPORT(xam, 0x00000621, XamNetworkStorageSetUserInSync, kFunction), +XE_EXPORT(xam, 0x00000622, XamNetworkStorageOnSigninChanged, kFunction), +XE_EXPORT(xam, 0x00000623, XamNetworkStorageSignInTestMock, kFunction), +XE_EXPORT(xam, 0x00000624, XamShowFofUI, kFunction), +XE_EXPORT(xam, 0x00000625, CompareFileTime, kFunction), +XE_EXPORT(xam, 0x00000626, SetFileTime, kFunction), +XE_EXPORT(xam, 0x00000627, XamNetworkStorageGetTitleProperties, kFunction), +XE_EXPORT(xam, 0x00000628, XamNetworkStorageLockFile, kFunction), +XE_EXPORT(xam, 0x00000629, XamNetworkStorageUserHasPrivilege, kFunction), +XE_EXPORT(xam, 0x0000062A, XamNetworkStorageIsTitleExempt, kFunction), +XE_EXPORT(xam, 0x0000062B, XamContentExistsOnDeviceInternal, kFunction), +XE_EXPORT(xam, 0x0000062C, XamNetworkStorageGetBackingDevice, kFunction), +XE_EXPORT(xam, 0x0000062D, XamNetworkStorageIsEnabledInLiveHive, kFunction), +XE_EXPORT(xam, 0x0000062E, XamNetworkStorageIsCheckingSyncStates, kFunction), +XE_EXPORT(xam, 0x0000062F, XamNetworkStorageUserNeedsToSync, kFunction), +XE_EXPORT(xam, 0x00000630, XamNetworkStorageGetUserNetworkSyncTime, kFunction), +XE_EXPORT(xam, 0x00000631, XamNetworkStorageGetUserProperties, kFunction), +XE_EXPORT(xam, 0x00000632, XamNetworkStorageAppLauncherLaunchIfRunning, kFunction), +XE_EXPORT(xam, 0x00000633, XamNetworkStorageSetTitleProperties, kFunction), +XE_EXPORT(xam, 0x00000634, XamNetworkStorageGetUserLastError, kFunction), +XE_EXPORT(xam, 0x00000635, XamNetworkStorageCheckOutTitle, kFunction), +XE_EXPORT(xam, 0x00000636, XamNetworkStorageShouldHideFromTitle, kFunction), +XE_EXPORT(xam, 0x00000637, XamNetworkStorageOnUserSyncChange, kFunction), +XE_EXPORT(xam, 0x00000638, XamNetworkStorageHasUserEnabledStorage, kFunction), +XE_EXPORT(xam, 0x00000639, XamContentGetLocalizedDeviceData, kFunction), +XE_EXPORT(xam, 0x00000640, XamPackageManagerFindPackageContainingIndexedXEX, kFunction), +XE_EXPORT(xam, 0x00000641, XamPackageManagerReinitialize, kFunction), +XE_EXPORT(xam, 0x00000642, XamPackageManagerGetAuthoritativeManifestVersion, kFunction), +XE_EXPORT(xam, 0x00000643, XamGetCurrentSystemOnlineManifestRevision, kFunction), +XE_EXPORT(xam, 0x00000644, XamPackageManagerDeleteExtendedPartition, kFunction), +XE_EXPORT(xam, 0x00000645, XamPackageManagerHasExtendedPartition, kFunction), +XE_EXPORT(xam, 0x00000646, XamPackageManagerGetExperienceMode, kFunction), +XE_EXPORT(xam, 0x00000647, XamPackageManagerGetFeatureRequiresUpdateStrings, kFunction), +XE_EXPORT(xam, 0x00000648, XamPackageManagerGetFileSize, kFunction), +XE_EXPORT(xam, 0x00000649, XampDemandUpdateGetAttributes, kFunction), +XE_EXPORT(xam, 0x0000064A, XampDemandUpdateGetExtendedAttributes, kFunction), +XE_EXPORT(xam, 0x0000064B, XampDemandUpdateGetInstance, kFunction), +XE_EXPORT(xam, 0x0000064C, XampDemandUpdateSetRefreshTestFlags, kFunction), +XE_EXPORT(xam, 0x0000064D, XampDemandUpdateIsRefreshTestFlagSet, kFunction), +XE_EXPORT(xam, 0x0000064E, XampDemandUpdateGetManifestLocalPath, kFunction), +XE_EXPORT(xam, 0x0000064F, XampDemandUpdateRefreshManifest, kFunction), +XE_EXPORT(xam, 0x00000650, XdfInitialize, kFunction), +XE_EXPORT(xam, 0x00000651, XdfShutdown, kFunction), +XE_EXPORT(xam, 0x00000652, XdfGetExpectedDownloadSize, kFunction), +XE_EXPORT(xam, 0x00000653, XdfGetItem, kFunction), +XE_EXPORT(xam, 0x00000654, XdfCacheItem, kFunction), +XE_EXPORT(xam, 0x00000655, XdfLoadXexFromCache, kFunction), +XE_EXPORT(xam, 0x00000656, XdfLoadXex, kFunction), +XE_EXPORT(xam, 0x00000657, XdfCancelRequest, kFunction), +XE_EXPORT(xam, 0x00000658, XdfResumeDelayedItem, kFunction), +XE_EXPORT(xam, 0x00000659, XdfLaunchNewImageFromCache, kFunction), +XE_EXPORT(xam, 0x0000065A, XampDemandUpdateRefreshManifestDuringLogon, kFunction), +XE_EXPORT(xam, 0x0000065B, XampDemandUpdateCheckOnlineManifestChanged, kFunction), +XE_EXPORT(xam, 0x0000065C, XampDemandUpdateRunCacheCleaner, kFunction), +XE_EXPORT(xam, 0x00000685, XamUpdateGetTitleUpdateSizeThreshold, kFunction), +XE_EXPORT(xam, 0x00000686, XamXStudioRequest, kFunction), +XE_EXPORT(xam, 0x00000687, XamNotifyDelayUIInternal, kFunction), +XE_EXPORT(xam, 0x000006A4, XamShowAvatarMiniCreatorUI, kFunction), +XE_EXPORT(xam, 0x000006A5, XamShowGoldUpgradeUI, kFunction), +XE_EXPORT(xam, 0x000006A6, XamResumeUpdaterUI, kFunction), +XE_EXPORT(xam, 0x000006A7, XamShowDirectAcquireUI, kFunction), +XE_EXPORT(xam, 0x000006A8, XamShowPaymentOptionsUI, kFunction), +XE_EXPORT(xam, 0x000006A9, XamShowMultiplayerUpgradeUI, kFunction), +XE_EXPORT(xam, 0x00000708, XamGetLiveHiveValueA, kFunction), +XE_EXPORT(xam, 0x00000709, XamGetLiveHiveValueW, kFunction), +XE_EXPORT(xam, 0x0000070A, XamGetLiveHiveValueDuringLogonAttemptA, kFunction), +XE_EXPORT(xam, 0x0000070B, XamSetUserPresetWindowsLiveCreds, kFunction), +XE_EXPORT(xam, 0x0000070C, XamQueryLiveHiveA, kFunction), +XE_EXPORT(xam, 0x0000070D, XamQueryLiveHiveW, kFunction), +XE_EXPORT(xam, 0x0000070E, XamGetLiveHiveValueDuringLogonAttemptExA, kFunction), +XE_EXPORT(xam, 0x0000070F, XamGetUserPresetWindowsLiveCreds, kFunction), +XE_EXPORT(xam, 0x00000710, XamGetUserNeedTFA, kFunction), +XE_EXPORT(xam, 0x00000711, XamSetUserNeedTFA, kFunction), +XE_EXPORT(xam, 0x00000712, XamGetUserInMemoryWindowsLiveCreds, kFunction), +XE_EXPORT(xam, 0x0000076C, XamDownloadMarketplaceStoresList, kFunction), +XE_EXPORT(xam, 0x0000076D, XamGetStoreFront, kFunction), +XE_EXPORT(xam, 0x0000076E, XamSetStagingMode, kFunction), +XE_EXPORT(xam, 0x0000076F, XamGetStagingMode, kFunction), +XE_EXPORT(xam, 0x00000770, XamAppGetSessionId, kFunction), +XE_EXPORT(xam, 0x00000771, XamAccountRecoveryRecoverAllProfileData, kFunction), +XE_EXPORT(xam, 0x00000772, XamAccountRecoveryGetProgress, kFunction), +XE_EXPORT(xam, 0x000007D0, XamDoesOmniNeedConfiguration, kFunction), +XE_EXPORT(xam, 0x000007D1, XamFirstRunExperienceShouldRun, kFunction), +XE_EXPORT(xam, 0x000007D2, GetProcessHeap, kFunction), +XE_EXPORT(xam, 0x000007D3, UnhandledExceptionFilter, kFunction), +XE_EXPORT(xam, 0x000007D4, SetUnhandledExceptionFilter, kFunction), +XE_EXPORT(xam, 0x000007D5, XamIsOptionalMediaUpdateInstalled, kFunction), +XE_EXPORT(xam, 0x000007D6, XamShowOptionalMediaUpdateRequiredUI, kFunction), +XE_EXPORT(xam, 0x000007D7, XamShowOptionalMediaUpdateRequiredUIEx, kFunction), +XE_EXPORT(xam, 0x000007D8, XamShowFirstRunWelcomeUI, kFunction), +XE_EXPORT(xam, 0x000007D9, XamTaskCreateQueueEx, kFunction), +XE_EXPORT(xam, 0x000007DA, XamSetDashBackstackData, kFunction), +XE_EXPORT(xam, 0x000007DB, XamLaunchAvatarEditor, kFunction), +XE_EXPORT(xam, 0x000007DC, XamGetDashBackstackData, kFunction), +XE_EXPORT(xam, 0x000007DD, XamGetDashBackstackNodesCount, kFunction), +XE_EXPORT(xam, 0x000007DE, XamSetLastActiveUserData, kFunction), +XE_EXPORT(xam, 0x000007DF, XamGetLastActiveUserData, kFunction), +XE_EXPORT(xam, 0x000007E0, XamSetActiveDashAppInfo, kFunction), +XE_EXPORT(xam, 0x000007E1, XamGetActiveDashAppInfo, kFunction), +XE_EXPORT(xam, 0x000007E2, XamLoaderRegisterLaunchRequestCallback, kFunction), +XE_EXPORT(xam, 0x000007E3, XamLoadExtraAVCodecs2, kFunction), +XE_EXPORT(xam, 0x000007E4, XamUnloadExtraAVCodecs2, kFunction), +XE_EXPORT(xam, 0x00000802, XamUserCreateAvatarAssetEnumerator, kFunction), +XE_EXPORT(xam, 0x00000803, XamInitializeGameTileCache, kFunction), +XE_EXPORT(xam, 0x00000804, XamDestroyGameTileCache, kFunction), +XE_EXPORT(xam, 0x00000805, XamReadGameTileImage, kFunction), +XE_EXPORT(xam, 0x00000806, XamShouldThrottleAccountInfoCall, kFunction), +XE_EXPORT(xam, 0x00000807, XuiClassDerivesFrom, kFunction), +XE_EXPORT(xam, 0x00000808, XuiFreeVisuals, kFunction), +XE_EXPORT(xam, 0x00000809, XuiGetBaseClass, kFunction), +XE_EXPORT(xam, 0x0000080A, XuiLoadVisualFromBinary, kFunction), +XE_EXPORT(xam, 0x0000080B, XuiResourceGetBuffer, kFunction), +XE_EXPORT(xam, 0x0000080C, XuiResourceGetTotalSize, kFunction), +XE_EXPORT(xam, 0x0000080D, XuiElementGetUserData, kFunction), +XE_EXPORT(xam, 0x0000080E, XuiElementSetUserData, kFunction), +XE_EXPORT(xam, 0x0000080F, XuiTabSceneGetCount, kFunction), +XE_EXPORT(xam, 0x00000810, XuiSliderGetStep, kFunction), +XE_EXPORT(xam, 0x00000811, XuiSliderSetStep, kFunction), +XE_EXPORT(xam, 0x00000812, XuiProgressBarGetRange, kFunction), +XE_EXPORT(xam, 0x00000813, XuiElementSetHittable, kFunction), +XE_EXPORT(xam, 0x00000814, XuiElementPlayNamedFrames, kFunction), +XE_EXPORT(xam, 0x00000815, XuiElementGetPivot, kFunction), +XE_EXPORT(xam, 0x00000816, XuiElementGetPrev, kFunction), +XE_EXPORT(xam, 0x00000817, XuiElementGetScale, kFunction), +XE_EXPORT(xam, 0x00000818, XuiElementSetPivot, kFunction), +XE_EXPORT(xam, 0x00000819, XuiElementSetRotation, kFunction), +XE_EXPORT(xam, 0x0000081A, XuiElementSetScale, kFunction), +XE_EXPORT(xam, 0x0000081B, XuiControlWantsUnfocusedInput, kFunction), +XE_EXPORT(xam, 0x0000081C, XuiResourceOpenNoLoc, kFunction), +XE_EXPORT(xam, 0x0000081D, XuiResourceReleasePackage, kFunction), +XE_EXPORT(xam, 0x0000081E, XuiResourceGetPackageEntryInfo, kFunction), +XE_EXPORT(xam, 0x0000081F, XuiResourceGetPackageEntryCount, kFunction), +XE_EXPORT(xam, 0x00000820, XuiResourceOpenPackage, kFunction), +XE_EXPORT(xam, 0x00000821, XamCodeCoverageFileOpen, kFunction), +XE_EXPORT(xam, 0x00000822, XamCodeCoverageFileClose, kFunction), +XE_EXPORT(xam, 0x00000823, XamCodeCoverageFileLseek, kFunction), +XE_EXPORT(xam, 0x00000824, XamCodeCoverageFileRead, kFunction), +XE_EXPORT(xam, 0x00000825, XamCodeCoverageFileWrite, kFunction), +XE_EXPORT(xam, 0x00000826, Refresh_1, kFunction), +XE_EXPORT(xam, 0x00000827, XampHeapGetInfo, kFunction), +XE_EXPORT(xam, 0x00000828, XampHeapGetCount, kFunction), +XE_EXPORT(xam, 0x00000829, XamShowPamUI, kFunction), +XE_EXPORT(xam, 0x0000082A, XuiElementLayoutTree, kFunction), +XE_EXPORT(xam, 0x0000082B, XamRegisterScreenSaverCallback, kFunction), +XE_EXPORT(xam, 0x0000082C, XUIElementPropVal_SetInt, kFunction), +XE_EXPORT(xam, 0x0000082D, XUIElementPropVal_SetFloat, kFunction), +XE_EXPORT(xam, 0x0000082E, XuiObjectGetPropertyDef, kFunction), +XE_EXPORT(xam, 0x0000082F, XuiRenderGetDevice, kFunction), +XE_EXPORT(xam, 0x00000830, XuiRenderRestoreState, kFunction), +XE_EXPORT(xam, 0x00000831, XuiElementGetFullXForm, kFunction), +XE_EXPORT(xam, 0x00000832, XuiRenderGetViewTransform, kFunction), +XE_EXPORT(xam, 0x00000833, XuiRenderGetColorSpace, kFunction), +XE_EXPORT(xam, 0x00000834, XamPngEncode, kFunction), +XE_EXPORT(xam, 0x00000835, XamPngDecode, kFunction), +XE_EXPORT(xam, 0x00000836, XamPngEncodeEx, kFunction), +XE_EXPORT(xam, 0x00000837, XuiTextElementMeasureText, kFunction), +XE_EXPORT(xam, 0x00000838, XamLoaderShouldConfirmReboot, kFunction), +XE_EXPORT(xam, 0x00000839, XamLoaderRebootToDash, kFunction), +XE_EXPORT(xam, 0x0000083A, XamNuiHudGetEngagedTrackingID, kFunction), +XE_EXPORT(xam, 0x0000083B, XamLoaderLaunchTitleForReason, kFunction), +XE_EXPORT(xam, 0x0000083C, XamNuiHudSetEngagedTrackingID, kFunction), +XE_EXPORT(xam, 0x0000083D, XuiBrushGetTexture, kFunction), +XE_EXPORT(xam, 0x0000083E, XamSetupTexture, kFunction), +XE_EXPORT(xam, 0x0000083F, XuiElementGetDescendantById, kFunction), +XE_EXPORT(xam, 0x00000840, XamLoaderIsKinectUIPreferredForLogonTitle, kFunction), +XE_EXPORT(xam, 0x00000841, XamSetupCameraPreviewStuff, kFunction), +XE_EXPORT(xam, 0x00000842, XamReleaseCameraPreviewStuff, kFunction), +XE_EXPORT(xam, 0x00000843, XamRenderCameraPreviewStuff, kFunction), +XE_EXPORT(xam, 0x00000848, XamAccountRecoveryGetSetTitleSyncTime, kFunction), +XE_EXPORT(xam, 0x00000849, XamReadBiometricData, kFunction), +XE_EXPORT(xam, 0x0000084A, XamWriteBiometricData, kFunction), +XE_EXPORT(xam, 0x0000084B, XamD3DResourceDescriptorCreate, kFunction), +XE_EXPORT(xam, 0x0000084C, XamD3DResourceDescriptorAddRef, kFunction), +XE_EXPORT(xam, 0x0000084D, XamD3DResourceDescriptorRelease, kFunction), +XE_EXPORT(xam, 0x0000084E, XamD3DResourceAddRef, kFunction), +XE_EXPORT(xam, 0x0000084F, XamD3DResourceSet, kFunction), +XE_EXPORT(xam, 0x00000850, XamD3DResourceIsBusy, kFunction), +XE_EXPORT(xam, 0x00000851, XamD3DResourceRelease, kFunction), +XE_EXPORT(xam, 0x00000852, ControlPackGetCursorPosition, kFunction), +XE_EXPORT(xam, 0x00000853, ControlPackShouldShowCursor, kFunction), +XE_EXPORT(xam, 0x00000858, XamFlushAgraTemperatureReport, kFunction), +XE_EXPORT(xam, 0x00000859, XamNatalDeviceAudioCalibrate, kFunction), +XE_EXPORT(xam, 0x0000085A, XamNuiIdentityGetEnrollmentInfo, kFunction), +XE_EXPORT(xam, 0x0000085B, XamNuiIdentityUnenroll, kFunction), +XE_EXPORT(xam, 0x0000085C, XamNuiIdentityGetColorTexture, kFunction), +XE_EXPORT(xam, 0x0000085D, XamReportKinectSettingsChangedEvent, kFunction), +XE_EXPORT(xam, 0x0000085E, XamNuiEnableChatMic, kFunction), +XE_EXPORT(xam, 0x0000085F, XamNuiIsChatMicEnabled, kFunction), +XE_EXPORT(xam, 0x00000860, XamNuiGetDepthCalibration, kFunction), +XE_EXPORT(xam, 0x00000861, XamNuiStoreDepthCalibration, kFunction), +XE_EXPORT(xam, 0x00000862, XamUserNuiIsBiometricEnabled, kFunction), +XE_EXPORT(xam, 0x00000863, XamUserNuiEnableBiometric, kFunction), +XE_EXPORT(xam, 0x00000864, XamNuiCameraSetFlags, kFunction), +XE_EXPORT(xam, 0x00000865, XamNuiCameraRememberFloor, kFunction), +XE_EXPORT(xam, 0x00000866, XamUserNuiGetUserIndexForBind, kFunction), +XE_EXPORT(xam, 0x00000867, XamUserNuiGetUserIndexForSignin, kFunction), +XE_EXPORT(xam, 0x00000868, XamUserNuiBind, kFunction), +XE_EXPORT(xam, 0x00000869, XamUserNuiGetUserIndex, kFunction), +XE_EXPORT(xam, 0x0000086A, XamUserNuiGetEnrollmentIndex, kFunction), +XE_EXPORT(xam, 0x0000086B, XamUserNuiUnbind, kFunction), +XE_EXPORT(xam, 0x0000086C, XamNuiIdentityGetQualityFlagsMessage, kFunction), +XE_EXPORT(xam, 0x0000086D, XamNuiCameraTiltSetCallback, kFunction), +XE_EXPORT(xam, 0x0000086E, XamNuiHudIsEnabled, kFunction), +XE_EXPORT(xam, 0x0000086F, XamNuiCameraGetTiltControllerType, kFunction), +XE_EXPORT(xam, 0x00000870, XamNuiCameraTiltGetStatus, kFunction), +XE_EXPORT(xam, 0x00000871, XamNuiIdentityGetQualityFlags, kFunction), +XE_EXPORT(xam, 0x00000872, XamNuiIdentityEnrollForSignIn, kFunction), +XE_EXPORT(xam, 0x00000873, XamNuiIdentityGetSessionId, kFunction), +XE_EXPORT(xam, 0x00000874, XamNuiIdentityIdentifyWithBiometric, kFunction), +XE_EXPORT(xam, 0x00000875, ControlPackGetHandleManager, kFunction), +XE_EXPORT(xam, 0x00000876, XamEnableNuiAutomation, kFunction), +XE_EXPORT(xam, 0x00000877, XamNuiGetSystemGestureControl, kFunction), +XE_EXPORT(xam, 0x00000878, XamGetPasscodeKeyFromVirtualKey, kFunction), +XE_EXPORT(xam, 0x00000879, XamEnableNatalPlayback, kFunction), +XE_EXPORT(xam, 0x0000087A, XamIsNuiAutomationEnabled, kFunction), +XE_EXPORT(xam, 0x0000087B, XamIsNatalPlaybackEnabled, kFunction), +XE_EXPORT(xam, 0x0000087C, XamNuiHudInterpretFrame, kFunction), +XE_EXPORT(xam, 0x0000087D, XamNuiHudEnableInputFilter, kFunction), +XE_EXPORT(xam, 0x0000087E, ControlpackNuiCursorSetTrackingId, kFunction), +XE_EXPORT(xam, 0x0000087F, XamNuiHudGetInitializeFlags, kFunction), +XE_EXPORT(xam, 0x00000880, XamNuiCameraElevationSetAngle, kFunction), +XE_EXPORT(xam, 0x00000881, XamNuiCameraElevationGetAngle, kFunction), +XE_EXPORT(xam, 0x00000882, XamNuiCameraElevationAutoTilt, kFunction), +XE_EXPORT(xam, 0x00000883, XamNuiCameraElevationStopMovement, kFunction), +XE_EXPORT(xam, 0x00000884, XamNuiCameraElevationSetCallback, kFunction), +XE_EXPORT(xam, 0x00000885, XamNuiGetDeviceStatus, kFunction), +XE_EXPORT(xam, 0x00000886, XamNuiNatalCameraUpdateStarting, kFunction), +XE_EXPORT(xam, 0x00000887, XamNuiNatalCameraUpdateComplete, kFunction), +XE_EXPORT(xam, 0x00000888, XamNuiHudGetVersions, kFunction), +XE_EXPORT(xam, 0x00000889, XamGetHUDElementByPath, kFunction), +XE_EXPORT(xam, 0x0000088A, XamGetHUDElementByAutoId, kFunction), +XE_EXPORT(xam, 0x0000088B, XuiElementGetScreenPositionCenter, kFunction), +XE_EXPORT(xam, 0x0000088C, XamNuiCameraElevationReverseAutoTilt, kFunction), +XE_EXPORT(xam, 0x0000088D, ControlPackSimpleCursorGetRayFromScreenPosition, kFunction), +XE_EXPORT(xam, 0x0000088E, ControlPackSideNavControlGetNuiHandle, kFunction), +XE_EXPORT(xam, 0x0000088F, XamFindHUDElementByXuiId, kFunction), +XE_EXPORT(xam, 0x00000890, XamNuiIsDeviceReady, kFunction), +XE_EXPORT(xam, 0x00000891, XamNuiSetForceDeviceOff, kFunction), +XE_EXPORT(xam, 0x00000892, XamNuiPlayerEngagementUpdate, kFunction), +XE_EXPORT(xam, 0x00000893, XamNuiSkeletonGetBestSkeletonIndex, kFunction), +XE_EXPORT(xam, 0x00000894, XamNuiSkeletonScoreUpdate, kFunction), +XE_EXPORT(xam, 0x00000895, XamNuiCameraTiltReportStatus, kFunction), +XE_EXPORT(xam, 0x00000896, XamNuiCameraAdjustTilt, kFunction), +XE_EXPORT(xam, 0x00000897, XamNuiIdentityAbort, kFunction), +XE_EXPORT(xam, 0x00000898, D3DDevice_CreateVertexShader, kFunction), +XE_EXPORT(xam, 0x00000899, D3DDevice_CreatePixelShader, kFunction), +XE_EXPORT(xam, 0x0000089A, D3DDevice_CreateTexture, kFunction), +XE_EXPORT(xam, 0x0000089B, D3DDevice_CreateVertexBuffer, kFunction), +XE_EXPORT(xam, 0x0000089C, D3DDevice_CreateIndexBuffer, kFunction), +XE_EXPORT(xam, 0x0000089D, D3DDevice_CreateVertexDeclaration, kFunction), +XE_EXPORT(xam, 0x0000089E, D3DVertexBuffer_Unlock, kFunction), +XE_EXPORT(xam, 0x0000089F, D3DVertexBuffer_Lock, kFunction), +XE_EXPORT(xam, 0x000008A0, D3DIndexBuffer_Unlock, kFunction), +XE_EXPORT(xam, 0x000008A1, D3DIndexBuffer_Lock, kFunction), +XE_EXPORT(xam, 0x000008A2, D3DTexture_UnlockRect, kFunction), +XE_EXPORT(xam, 0x000008A3, D3DTexture_LockRect, kFunction), +XE_EXPORT(xam, 0x000008A4, D3DDevice_Clear, kFunction), +XE_EXPORT(xam, 0x000008A5, D3DDevice_SetViewport, kFunction), +XE_EXPORT(xam, 0x000008A6, D3DDevice_GetViewport, kFunction), +XE_EXPORT(xam, 0x000008A7, D3DVertexShader_Release, kFunction), +XE_EXPORT(xam, 0x000008A8, D3DPixelShader_Release, kFunction), +XE_EXPORT(xam, 0x000008A9, D3DVertexDeclaration_Release, kFunction), +XE_EXPORT(xam, 0x000008AA, D3DResource_Release, kFunction), +XE_EXPORT(xam, 0x000008AB, D3DDevice_Release, kFunction), +XE_EXPORT(xam, 0x000008AC, D3DDevice_SetVertexShader, kFunction), +XE_EXPORT(xam, 0x000008AD, D3DDevice_SetPixelShader, kFunction), +XE_EXPORT(xam, 0x000008AE, D3DDevice_SetTexture, kFunction), +XE_EXPORT(xam, 0x000008AF, D3DDevice_SetVertexDeclaration, kFunction), +XE_EXPORT(xam, 0x000008B0, D3DDevice_SetIndices, kFunction), +XE_EXPORT(xam, 0x000008B1, D3DDevice_SetStreamSource, kFunction), +XE_EXPORT(xam, 0x000008B2, D3DDevice_DrawVertices, kFunction), +XE_EXPORT(xam, 0x000008B3, D3DDevice_DrawVerticesUP, kFunction), +XE_EXPORT(xam, 0x000008B4, D3DDevice_DrawIndexedVertices, kFunction), +XE_EXPORT(xam, 0x000008B5, D3DDevice_DrawIndexedVerticesUP, kFunction), +XE_EXPORT(xam, 0x000008B6, D3DDevice_SetVertexShaderConstantF_ParameterCheck, kFunction), +XE_EXPORT(xam, 0x000008B7, D3DDevice_SetPixelShaderConstantF_ParameterCheck, kFunction), +XE_EXPORT(xam, 0x000008B8, D3DDevice_SetSamplerState_ParameterCheck, kFunction), +XE_EXPORT(xam, 0x000008B9, D3DDevice_SetRenderState_ParameterCheck, kFunction), +XE_EXPORT(xam, 0x000008BA, D3DDevice_GetRenderState_ParameterCheck, kFunction), +XE_EXPORT(xam, 0x000008BB, D3DDevice_SetVertexShaderConstantFN, kFunction), +XE_EXPORT(xam, 0x000008BC, D3DDevice_SetPixelShaderConstantFN, kFunction), +XE_EXPORT(xam, 0x000008BD, D3DDevice_GetRenderState_ZEnable, kFunction), +XE_EXPORT(xam, 0x000008BE, D3DDevice_GetRenderState_CullMode, kFunction), +XE_EXPORT(xam, 0x000008BF, D3DDevice_GetRenderState_AlphaBlendEnable, kFunction), +XE_EXPORT(xam, 0x000008C0, D3DDevice_GetRenderState_SrcBlendAlpha, kFunction), +XE_EXPORT(xam, 0x000008C1, D3DDevice_GetRenderState_DestBlendAlpha, kFunction), +XE_EXPORT(xam, 0x000008C2, D3DDevice_GetRenderState_BlendOp, kFunction), +XE_EXPORT(xam, 0x000008C3, D3DDevice_GetRenderState_ViewportEnable, kFunction), +XE_EXPORT(xam, 0x000008C4, D3DDevice_SetRenderState_ZEnable, kFunction), +XE_EXPORT(xam, 0x000008C5, D3DDevice_SetRenderState_CullMode, kFunction), +XE_EXPORT(xam, 0x000008C6, D3DDevice_SetRenderState_AlphaBlendEnable, kFunction), +XE_EXPORT(xam, 0x000008C7, D3DDevice_SetRenderState_SrcBlendAlpha, kFunction), +XE_EXPORT(xam, 0x000008C8, D3DDevice_SetRenderState_DestBlendAlpha, kFunction), +XE_EXPORT(xam, 0x000008C9, D3DDevice_SetRenderState_BlendOp, kFunction), +XE_EXPORT(xam, 0x000008CA, D3DDevice_SetRenderState_ViewportEnable, kFunction), +XE_EXPORT(xam, 0x000008CB, D3DDevice_SetSamplerState_MagFilter, kFunction), +XE_EXPORT(xam, 0x000008CC, D3DDevice_SetSamplerState_MinFilter, kFunction), +XE_EXPORT(xam, 0x000008CD, D3DDevice_SetSamplerState_AddressU, kFunction), +XE_EXPORT(xam, 0x000008CE, D3DDevice_SetSamplerState_AddressV, kFunction), +XE_EXPORT(xam, 0x000008CF, XGSetTextureHeader, kFunction), +XE_EXPORT(xam, 0x000008D0, XGGetTextureDesc, kFunction), +XE_EXPORT(xam, 0x000008D1, XGOffsetResourceAddress, kFunction), +XE_EXPORT(xam, 0x000008D2, D3DResource_AddRef, kFunction), +XE_EXPORT(xam, 0x000008D3, D3DVertexShader_AddRef, kFunction), +XE_EXPORT(xam, 0x000008D4, D3DPixelShader_AddRef, kFunction), +XE_EXPORT(xam, 0x000008D5, D3DVertexDeclaration_AddRef, kFunction), +XE_EXPORT(xam, 0x000008D6, XGSetTextureHeaderEx, kFunction), +XE_EXPORT(xam, 0x000008D7, D3DDevice_GetRenderTarget, kFunction), +XE_EXPORT(xam, 0x000008D8, D3DDevice_SetRenderTarget, kFunction), +XE_EXPORT(xam, 0x000008D9, D3DDevice_GetDepthStencilSurface, kFunction), +XE_EXPORT(xam, 0x000008DA, D3DDevice_SetDepthStencilSurface, kFunction), +XE_EXPORT(xam, 0x000008DB, D3DDevice_Resolve, kFunction), +XE_EXPORT(xam, 0x000008DC, D3DDevice_SetPixelShaderConstantB, kFunction), +XE_EXPORT(xam, 0x000008DD, XamNuiGetDeviceSerialNumber, kFunction), +XE_EXPORT(xam, 0x000008DE, XamNuiGetLoadedDepthCalibration, kFunction), +XE_EXPORT(xam, 0x000008DF, XamNuiGetTrueColorInfo, kFunction), +XE_EXPORT(xam, 0x000008E0, XamNuiGetCameraIntrinsics, kFunction), +XE_EXPORT(xam, 0x000008E1, XamNuiGetFanRate, kFunction), +XE_EXPORT(xam, 0x000008E2, XamNuiGetSupportString, kFunction), +XE_EXPORT(xam, 0x000008E3, XamKinectGetHardwareType, kFunction), +XE_EXPORT(xam, 0x000008FC, XamXtwManagerGetVariableCount, kFunction), +XE_EXPORT(xam, 0x000008FD, XamXtwManagerGetId, kFunction), +XE_EXPORT(xam, 0x000008FE, XamXtwManagerGetValue, kFunction), +XE_EXPORT(xam, 0x000008FF, XamXtwManagerSetValue, kFunction), +XE_EXPORT(xam, 0x00000900, XamXtwManagerIncrement, kFunction), +XE_EXPORT(xam, 0x00000901, XamXtwManagerDecrement, kFunction), +XE_EXPORT(xam, 0x00000902, XamXtwManagerResetValue, kFunction), +XE_EXPORT(xam, 0x00000903, XamXtwManagerResetAll, kFunction), +XE_EXPORT(xam, 0x00000904, XamXtwManagerGetDataFilePath, kFunction), +XE_EXPORT(xam, 0x00000905, XamXtwManagerDeleteDataFile, kFunction), +XE_EXPORT(xam, 0x00000906, XamXtwManagerSave, kFunction), +XE_EXPORT(xam, 0x00000907, XamXtwManagerLoad, kFunction), +XE_EXPORT(xam, 0x00000908, XamGetXTweakManager, kFunction), +XE_EXPORT(xam, 0x000009BB, XamMediaVerificationCreate, kFunction), +XE_EXPORT(xam, 0x000009BC, XamMediaVerificationClose, kFunction), +XE_EXPORT(xam, 0x000009BD, XamMediaVerificationVerify, kFunction), +XE_EXPORT(xam, 0x000009BE, XamMediaVerificationFailedBlocks, kFunction), +XE_EXPORT(xam, 0x000009BF, XamMediaVerificationInject, kFunction), +XE_EXPORT(xam, 0x000009C0, XamShowBadDiscErrorUI, kFunction), +XE_EXPORT(xam, 0x000009C4, XamBackgroundDownloadSetMode, kFunction), +XE_EXPORT(xam, 0x000009C5, XamBackgroundDownloadIsEnabled, kFunction), +XE_EXPORT(xam, 0x000009C6, XamBackgroundDownloadGetActiveItem, kFunction), +XE_EXPORT(xam, 0x000009C7, XamBackgroundDownloadGetItems, kFunction), +XE_EXPORT(xam, 0x000009C8, XamBackgroundDownloadClearItems, kFunction), +XE_EXPORT(xam, 0x000009C9, XamBackgroundDownloadItemAdd, kFunction), +XE_EXPORT(xam, 0x000009CA, XamBackgroundDownloadItemRemove, kFunction), +XE_EXPORT(xam, 0x000009CB, XamBackgroundDownloadItemMakeFirst, kFunction), +XE_EXPORT(xam, 0x000009CC, XamBackgroundDownloadSetForegroundPriority, kFunction), +XE_EXPORT(xam, 0x000009CD, XamBackgroundDownloadGetForegroundPriority, kFunction), +XE_EXPORT(xam, 0x000009CE, XamBackgroundDownloadItemToContentData, kFunction), +XE_EXPORT(xam, 0x000009CF, XamBackgroundDownloadItemGetStatus, kFunction), +XE_EXPORT(xam, 0x000009D0, XamBackgroundDownloadHistoryGetItem, kFunction), +XE_EXPORT(xam, 0x000009D1, XamBackgroundDownloadItemGetHistoryStatus, kFunction), +XE_EXPORT(xam, 0x000009D2, XamBackgroundDownloadItemSetHistoryStatus, kFunction), +XE_EXPORT(xam, 0x000009D3, XamBackgroundDownloadItemGetStatusAsync, kFunction), +XE_EXPORT(xam, 0x000009D4, XamBackgroundDownloadItemGetStatusEx, kFunction), +XE_EXPORT(xam, 0x000009D5, XamBackgroundDownloadItemGetHistoryStatusEx, kFunction), +XE_EXPORT(xam, 0x000009D6, XamBackgroundDownloadBindItems, kFunction), +XE_EXPORT(xam, 0x000009D7, XamBackgroundDownloadSetPollingActive, kFunction), +XE_EXPORT(xam, 0x000009D8, XamBackgroundDownloadGetPollingActive, kFunction), +XE_EXPORT(xam, 0x000009D9, XamBackgroundDownloadGetMode, kFunction), +XE_EXPORT(xam, 0x000009DA, XamBackgroundDownloadGetUnexpectedChangeCount, kFunction), +XE_EXPORT(xam, 0x000009DB, XamBackgroundDownloadIsItemForThisConsole, kFunction), +XE_EXPORT(xam, 0x000009DC, XamBackgroundDownloadSelectDevice, kFunction), +XE_EXPORT(xam, 0x000009DD, XamBackgroundDownloadItemModify, kFunction), +XE_EXPORT(xam, 0x000009DE, XamBackgroundDownloadCacheLegacyMappingInfo, kFunction), +XE_EXPORT(xam, 0x000009DF, XamBackgroundDownloadGetLegacyMappingInfo, kFunction), +XE_EXPORT(xam, 0x000009E0, XamBackgroundDownloadGetLegacyId, kFunction), +XE_EXPORT(xam, 0x000009E1, XamBackgroundDownloadDoFail, kFunction), +XE_EXPORT(xam, 0x000009E2, XamDownloadSingleItem, kFunction), +XE_EXPORT(xam, 0x000009E3, XamDownloadInSingleItemMode, kFunction), +XE_EXPORT(xam, 0x00000A28, XamSwapDisc, kFunction), +XE_EXPORT(xam, 0x00000A29, XamSwapDiscPatchAddress, kVariable), +XE_EXPORT(xam, 0x00000A2A, XamSwapCancel, kFunction), +XE_EXPORT(xam, 0x00000A2B, XamContentSetAttributes, kFunction), +XE_EXPORT(xam, 0x00000A32, XamRamDriveCreate, kFunction), +XE_EXPORT(xam, 0x00000A33, XamRamDriveDestroy, kFunction), +XE_EXPORT(xam, 0x00000A5A, XamPlayTimerGetData, kFunction), +XE_EXPORT(xam, 0x00000A5B, XamPlayTimerSetData, kFunction), +XE_EXPORT(xam, 0x00000A5C, XamPlayTimerResume, kFunction), +XE_EXPORT(xam, 0x00000A5D, XamPlayTimerSuspend, kFunction), +XE_EXPORT(xam, 0x00000A5E, XamPlayTimerIsRunning, kFunction), +XE_EXPORT(xam, 0x00000A5F, XamPlayTimerIsEnabled, kFunction), +XE_EXPORT(xam, 0x00000A60, XamPlayTimerGetNextResetDate, kFunction), +XE_EXPORT(xam, 0x00000A61, XamPlayTimerFormatDurationString, kFunction), +XE_EXPORT(xam, 0x00000A62, XamPlayTimerGetTimeRemaining, kFunction), +XE_EXPORT(xam, 0x00000A63, XamPlayTimerUpdateTimeRemaining, kFunction), +XE_EXPORT(xam, 0x00000A64, XamPlayTimerForceNotification, kFunction), +XE_EXPORT(xam, 0x00000A65, XamPlayTimerRefreshResetDate, kFunction), +XE_EXPORT(xam, 0x00000A66, XuiResourceOpenAndVerifyNoLoc, kFunction), +XE_EXPORT(xam, 0x00000A6E, UpnpAVServerSearchInitialize, kFunction), +XE_EXPORT(xam, 0x00000A6F, UpnpAVServerSearchDestroy, kFunction), +XE_EXPORT(xam, 0x00000A70, UpnpAVServerSearchStart, kFunction), +XE_EXPORT(xam, 0x00000A71, Destroy, kFunction), +XE_EXPORT(xam, 0x00000A72, UpnpAVServerSearchDoWork, kFunction), +XE_EXPORT(xam, 0x00000A73, UpnpAVServerSearchGetNextServer, kFunction), +XE_EXPORT(xam, 0x00000A8C, XCustomBroadcastGamercardEvent, kFunction), +XE_EXPORT(xam, 0x00000A8D, XamCustomGetCurrentActions, kFunction), +XE_EXPORT(xam, 0x00000AA0, XamInstrumentationLogEvent, kFunction), +XE_EXPORT(xam, 0x00000AA1, XamRegisterSMCNotification, kFunction), +XE_EXPORT(xam, 0x00000AA8, XamIsScreenSaverActive, kFunction), +XE_EXPORT(xam, 0x00000AAA, XamInstrumentationLogEventEx, kFunction), +XE_EXPORT(xam, 0x00000AAB, XamInstrumentationGetSourceConfig, kFunction), +XE_EXPORT(xam, 0x00000AAC, XamInstrumentationDebugConfig, kFunction), +XE_EXPORT(xam, 0x00000ADC, CurlCreateCacheEntry, kFunction), +XE_EXPORT(xam, 0x00000ADD, CurlOpenCacheEntry, kFunction), +XE_EXPORT(xam, 0x00000ADE, CurlSetCacheEntryExpireTime, kFunction), +XE_EXPORT(xam, 0x00000ADF, CurlReadCacheEntryHeaders, kFunction), +XE_EXPORT(xam, 0x00000AE0, CurlReadCacheEntryContent, kFunction), +XE_EXPORT(xam, 0x00000AE1, CurlWriteCacheEntryContent, kFunction), +XE_EXPORT(xam, 0x00000AE2, CurlCloseCacheEntry, kFunction), +XE_EXPORT(xam, 0x00000AE3, CurlEnumerateCacheEntry, kFunction), +XE_EXPORT(xam, 0x00000AE5, CurlWipeBackingFiles, kFunction), +XE_EXPORT(xam, 0x00000AE7, CurlOpenTitleBackingFile, kFunction), +XE_EXPORT(xam, 0x00000AEA, XamUserIsPartialProfile, kFunction), +XE_EXPORT(xam, 0x00000AEB, XamLocateTitle, kFunction), +XE_EXPORT(xam, 0x00000AEC, XamProfileGetLocalTitleCount, kFunction), +XE_EXPORT(xam, 0x00000AED, XamContentRemoveCacheDevice, kFunction), +XE_EXPORT(xam, 0x00000AEE, XamContentAddCacheDevice, kFunction), +XE_EXPORT(xam, 0x00000AF0, XamSetSecurityViolationDetected, kFunction), +XE_EXPORT(xam, 0x00000AF1, XamIsSecurityViolationDetected, kFunction), +XE_EXPORT(xam, 0x00000AF2, XamIsAnySecurityViolationDetected, kFunction), +XE_EXPORT(xam, 0x00000AF3, XamGetSecurityViolationsDetected, kFunction), +XE_EXPORT(xam, 0x00000AF4, XamActivateCounterMeasure, kFunction), +XE_EXPORT(xam, 0x00000AF5, XamDeactivateCounterMeasure, kFunction), +XE_EXPORT(xam, 0x00000AF6, XamIsCounterMeasureActivated, kFunction), +XE_EXPORT(xam, 0x00000AF7, XamGetActiveCounterMeasures, kFunction), +XE_EXPORT(xam, 0x00000AF8, XamPmdIdentify, kFunction), +XE_EXPORT(xam, 0x00000AF9, XamPmdSendCommand, kFunction), +XE_EXPORT(xam, 0x00000AFA, XamPmdReadReport, kFunction), +XE_EXPORT(xam, 0x00000AFC, XamPartyCreate, kFunction), +XE_EXPORT(xam, 0x00000AFD, XamPartyLeave, kFunction), +XE_EXPORT(xam, 0x00000AFE, XamPartySendInviteDeprecated, kFunction), +XE_EXPORT(xam, 0x00000AFF, XamPartyGetUserList, kFunction), +XE_EXPORT(xam, 0x00000B00, XamPartySendGameInvites, kFunction), +XE_EXPORT(xam, 0x00000B01, XamPartyJoin, kFunction), +XE_EXPORT(xam, 0x00000B02, XamPartyKickUser, kFunction), +XE_EXPORT(xam, 0x00000B03, XamPartyAddLocalUsers, kFunction), +XE_EXPORT(xam, 0x00000B04, XamConvertEmoticons, kFunction), +XE_EXPORT(xam, 0x00000B05, XamGetLocaleTimeFormat, kFunction), +XE_EXPORT(xam, 0x00000B06, XamPartyRemoveLocalUsers, kFunction), +XE_EXPORT(xam, 0x00000B07, XamPartyGetUserListInternal, kFunction), +XE_EXPORT(xam, 0x00000B08, XamPartySetJoinable, kFunction), +XE_EXPORT(xam, 0x00000B09, XamPartyGetJoinable, kFunction), +XE_EXPORT(xam, 0x00000B0A, XamPartyGetInfo, kFunction), +XE_EXPORT(xam, 0x00000B0B, XamPartySetCustomData, kFunction), +XE_EXPORT(xam, 0x00000B0C, XamPartySetConnectivityGraph, kFunction), +XE_EXPORT(xam, 0x00000B0D, XamPartyGetRoutingTable, kFunction), +XE_EXPORT(xam, 0x00000B0E, XamPartyAutomationInprocCall, kFunction), +XE_EXPORT(xam, 0x00000B0F, XamPartyGetState, kFunction), +XE_EXPORT(xam, 0x00000B10, XamPartyGetBandwidth, kFunction), +XE_EXPORT(xam, 0x00000B11, XamPartyGetNetworkCounters, kFunction), +XE_EXPORT(xam, 0x00000B12, XamShowQuickLaunchUI, kFunction), +XE_EXPORT(xam, 0x00000B13, XamPartyIsCoordinator, kFunction), +XE_EXPORT(xam, 0x00000B14, XamPartyGetFormation, kFunction), +XE_EXPORT(xam, 0x00000B15, XamPartySendInvite, kFunction), +XE_EXPORT(xam, 0x00000B16, XamPartySetTestDelay, kFunction), +XE_EXPORT(xam, 0x00000B17, XamPartyOverrideNatType, kFunction), +XE_EXPORT(xam, 0x00000B18, XamPartyGetAccessLevel, kFunction), +XE_EXPORT(xam, 0x00000B19, XamPartySetTestFlags, kFunction), +XE_EXPORT(xam, 0x00000B1A, XamIsSystemExperienceTitleId, kFunction), +XE_EXPORT(xam, 0x00000B1B, XamPartyJoinEx, kFunction), +XE_EXPORT(xam, 0x00000B1C, XamPartyGetInfoEx, kFunction), +XE_EXPORT(xam, 0x00000B20, XamIsCurrentTitleDatacenterClient, kFunction), +XE_EXPORT(xam, 0x00000B22, XamTaskSetCancelSubTasks, kFunction), +XE_EXPORT(xam, 0x00000B23, XamTaskGetCompletionStatus, kFunction), +XE_EXPORT(xam, 0x00000B24, XamTaskCancelWaitAndCloseWaitTask, kFunction), +XE_EXPORT(xam, 0x00000B27, XamDataCenterLog, kFunction), +XE_EXPORT(xam, 0x00000B28, XamDataCenterGetDhcpOptionResponseHostnameAndPort, kFunction), +XE_EXPORT(xam, 0x00000B29, XamDataCenterLogEvent, kFunction), +XE_EXPORT(xam, 0x00000B2A, XamDataCenterShowForceSignInMessage, kFunction), +XE_EXPORT(xam, 0x00000B2C, XamWebInstrumentationCreateReport, kFunction), +XE_EXPORT(xam, 0x00000B2D, XamWebInstrumentationSetUserVar, kFunction), +XE_EXPORT(xam, 0x00000B2E, XamWebInstrumentationSetUserVarNoEscape, kFunction), +XE_EXPORT(xam, 0x00000B2F, XamWebInstrumentationGetURL, kFunction), +XE_EXPORT(xam, 0x00000B30, XamWebInstrumentationSendReport, kFunction), +XE_EXPORT(xam, 0x00000B31, XamWebInstrumentationDestroyReport, kFunction), +XE_EXPORT(xam, 0x00000B32, XamWebInstrumentationCreateSampledReport, kFunction), +XE_EXPORT(xam, 0x00000B33, XampSetSamplingRandomValue, kFunction), +XE_EXPORT(xam, 0x00000B34, XampWebInstrumentationSetProfileCounts, kFunction), +XE_EXPORT(xam, 0x00000B35, XamWebInstrumentationGetURLEx, kFunction), +XE_EXPORT(xam, 0x00000B36, XampSetOmnitureCallbackFunction, kFunction), +XE_EXPORT(xam, 0x00000B37, XamShowQuickChatUIp, kFunction), +XE_EXPORT(xam, 0x00000B38, XamShowSocialPostUI, kFunction), +XE_EXPORT(xam, 0x00000B39, XamShowBeaconsUI, kFunction), +XE_EXPORT(xam, 0x00000B3A, XamShowMarketplacePurchaseOrderUI, kFunction), +XE_EXPORT(xam, 0x00000B3B, XamShowMarketplaceGetOrderReceipts, kFunction), +XE_EXPORT(xam, 0x00000B3C, XamShowGenericOnlineAppUI, kFunction), +XE_EXPORT(xam, 0x00000B3D, XamUserAllowedToPostToSocialNetwork, kFunction), +XE_EXPORT(xam, 0x00000B3E, XamShowMarketplacePurchaseOrderUIEx, kFunction), +XE_EXPORT(xam, 0x00000B3F, DebugXamShowMessageBoxUI_Wait, kFunction), +XE_EXPORT(xam, 0x00000B43, XamSetCountry, kFunction), +XE_EXPORT(xam, 0x00000B44, XamIsCurrentTitleDatacenterDash, kFunction), +XE_EXPORT(xam, 0x00000B45, XamLoaderRebootToServerDash, kFunction), +XE_EXPORT(xam, 0x00000B46, XamIsDataCenterMode, kFunction), +XE_EXPORT(xam, 0x00000B48, XamUserGetXUIDForTFA, kFunction), +XE_EXPORT(xam, 0x00000B4A, XamVerifyXSignerSignature, kFunction), diff --git a/src/kernel/xam/xam_avatar.cpp b/src/kernel/xam/xam_avatar.cpp new file mode 100644 index 0000000..4b5bdc9 --- /dev/null +++ b/src/kernel/xam/xam_avatar.cpp @@ -0,0 +1,66 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include + +namespace rex { +namespace kernel { +namespace xam { + +u32 XamAvatarInitialize_entry(u32 unk1, // 1, 4, etc + u32 unk2, // 0 or 1 + u32 processor_number, // for thread creation? + mapped_u32 function_ptrs, // 20b, 5 pointers + mapped_void unk5, // ptr in data segment + u32 unk6 // flags - 0x00300000, 0x30, etc +) { + // Negative to fail. Game should immediately call XamAvatarShutdown. + return ~0u; +} + +void XamAvatarShutdown_entry() { + // No-op. +} + +} // namespace xam +} // namespace kernel +} // namespace rex + +REX_EXPORT(__imp__XamAvatarInitialize, rex::kernel::xam::XamAvatarInitialize_entry) +REX_EXPORT(__imp__XamAvatarShutdown, rex::kernel::xam::XamAvatarShutdown_entry) + +REX_EXPORT_STUB(__imp__XamAvatarBeginEnumAssets); +REX_EXPORT_STUB(__imp__XamAvatarEndEnumAssets); +REX_EXPORT_STUB(__imp__XamAvatarEnumAssets); +REX_EXPORT_STUB(__imp__XamAvatarGenerateMipMaps); +REX_EXPORT_STUB(__imp__XamAvatarGetAssetBinary); +REX_EXPORT_STUB(__imp__XamAvatarGetAssetIcon); +REX_EXPORT_STUB(__imp__XamAvatarGetAssets); +REX_EXPORT_STUB(__imp__XamAvatarGetAssetsResultSize); +REX_EXPORT_STUB(__imp__XamAvatarGetInstalledAssetPackageDescription); +REX_EXPORT_STUB(__imp__XamAvatarGetInstrumentation); +REX_EXPORT_STUB(__imp__XamAvatarGetManifestLocalUser); +REX_EXPORT_STUB(__imp__XamAvatarGetManifestsByXuid); +REX_EXPORT_STUB(__imp__XamAvatarGetMetadataRandom); +REX_EXPORT_STUB(__imp__XamAvatarGetMetadataSignedOutProfile); +REX_EXPORT_STUB(__imp__XamAvatarGetMetadataSignedOutProfileCount); +REX_EXPORT_STUB(__imp__XamAvatarLoadAnimation); +REX_EXPORT_STUB(__imp__XamAvatarManifestGetBodyType); +REX_EXPORT_STUB(__imp__XamAvatarReinstallAwardedAsset); +REX_EXPORT_STUB(__imp__XamAvatarSetCustomAsset); +REX_EXPORT_STUB(__imp__XamAvatarSetManifest); +REX_EXPORT_STUB(__imp__XamAvatarSetMocks); +REX_EXPORT_STUB(__imp__XamAvatarWearNow); diff --git a/src/kernel/xam/xam_content.cpp b/src/kernel/xam/xam_content.cpp new file mode 100644 index 0000000..1b410b2 --- /dev/null +++ b/src/kernel/xam/xam_content.cpp @@ -0,0 +1,468 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_UINT32(license_mask, 0, "Kernel", "Set license mask for activated content"); + +namespace rex { +namespace kernel { +namespace xam { +using namespace rex::system; +using namespace rex::system::xam; + +u32 XamContentGetLicenseMask_entry(mapped_u32 mask_ptr, mapped_void overlapped_ptr) { + // Each bit in the mask represents a granted license. Available licenses + // seems to vary from game to game, but most appear to use bit 0 to indicate + // if the game is purchased or not. + *mask_ptr = REXCVAR_GET(license_mask); + + if (overlapped_ptr) { + REX_KERNEL_STATE()->CompleteOverlappedImmediate(overlapped_ptr.guest_address(), + X_ERROR_SUCCESS); + return X_ERROR_IO_PENDING; + } else { + return X_ERROR_SUCCESS; + } +} + +u32 XamContentResolve_entry(u32 user_index, mapped_void content_data_ptr, mapped_void buffer_ptr, + u32 buffer_size, u32 unk1, u32 unk2, u32 unk3) { + auto content_data = content_data_ptr.as(); + + // Result of buffer_ptr is sent to RtlInitAnsiString. + // buffer_size is usually 260 (max path). + // Games expect zero if resolve was successful. + assert_always(); + REXKRNL_WARN("XamContentResolve unimplemented!"); + return X_ERROR_NOT_FOUND; +} + +// https://github.com/MrColdbird/gameservice/blob/master/ContentManager.cpp +// https://github.com/LestaD/SourceEngine2007/blob/master/se2007/engine/xboxsystem.cpp#L499 +u32 XamContentCreateEnumerator_entry(u32 user_index, u32 device_id, u32 content_type, + u32 content_flags, u32 items_per_enumerate, + mapped_u32 buffer_size_ptr, mapped_u32 handle_out) { + assert_not_null(handle_out); + + auto device_info = device_id == 0 ? nullptr : GetDummyDeviceInfo(device_id); + if ((device_id && device_info == nullptr) || !handle_out) { + if (buffer_size_ptr) { + *buffer_size_ptr = 0; + } + return X_E_INVALIDARG; + } + + if (buffer_size_ptr) { + *buffer_size_ptr = sizeof(XCONTENT_DATA) * items_per_enumerate; + } + + uint64_t xuid = REX_KERNEL_STATE()->user_profile()->xuid(); + + auto e = make_object>(REX_KERNEL_STATE(), items_per_enumerate); + auto result = e->Initialize(0xFF, 0xFE, 0x20005, 0x20007, 0); + if (XFAILED(result)) { + return result; + } + + if (!device_info || device_info->device_id == DummyDeviceId::HDD) { + // Enumerate user-specific content + auto content_datas = REX_KERNEL_STATE()->content_manager()->ListContent( + static_cast(DummyDeviceId::HDD), xuid, XContentType(uint32_t(content_type))); + for (const auto& content_data : content_datas) { + auto item = e->AppendItem(); + *item = content_data; + } + + // Also enumerate common content (xuid=0) + if (xuid != 0) { + auto common_datas = REX_KERNEL_STATE()->content_manager()->ListContent( + static_cast(DummyDeviceId::HDD), 0, XContentType(uint32_t(content_type))); + for (const auto& content_data : common_datas) { + auto item = e->AppendItem(); + *item = content_data; + } + } + } + + if (!device_info || device_info->device_id == DummyDeviceId::ODD) { + // TODO(gibbed): disc drive content + } + + REXKRNL_DEBUG("XamContentCreateEnumerator: added {} items to enumerator", e->item_count()); + + *handle_out = e->handle(); + return X_ERROR_SUCCESS; +} + +enum class kDispositionState : uint32_t { Unknown = 0, Create = 1, Open = 2 }; + +u32 xeXamContentCreate(u32 user_index, mapped_string root_name, mapped_void content_data_ptr, + u32 content_data_size, u32 flags, mapped_u32 disposition_ptr, + mapped_u32 license_mask_ptr, u32 cache_size, u64 content_size, + mapped_void overlapped_ptr) { + uint64_t xuid = REX_KERNEL_STATE()->user_profile()->xuid(); + + XCONTENT_AGGREGATE_DATA content_data; + if (content_data_size == sizeof(XCONTENT_DATA)) { + content_data = *content_data_ptr.as(); + } else if (content_data_size == sizeof(XCONTENT_AGGREGATE_DATA)) { + content_data = *content_data_ptr.as(); + } else { + assert_always(); + return X_ERROR_INVALID_PARAMETER; + } + + if (content_data.content_type == XContentType::kMarketplaceContent) { + xuid = 0; + } + + auto content_manager = REX_KERNEL_STATE()->content_manager(); + + if (overlapped_ptr && disposition_ptr) { + *disposition_ptr = 0; + } + + auto run = [content_manager, xuid, root_name = root_name.value(), flags, content_data, + disposition_ptr, + license_mask_ptr](uint32_t& extended_error, uint32_t& length) -> X_RESULT { + X_RESULT result = X_ERROR_INVALID_PARAMETER; + kDispositionState disposition = kDispositionState::Unknown; + switch (flags & 0xF) { + case 1: // CREATE_NEW + // Fail if exists. + if (content_manager->ContentExists(xuid, content_data)) { + result = X_ERROR_ALREADY_EXISTS; + } else { + disposition = kDispositionState::Create; + } + break; + case 2: // CREATE_ALWAYS + // Overwrite existing, if any. + // Close any existing mount under this root name first. + // Games may reuse the same root without explicitly closing. + content_manager->CloseContent(root_name); + if (content_manager->ContentExists(xuid, content_data)) { + content_manager->DeleteContent(xuid, content_data); + } + // Check filesystem state after deletion attempt to decide + // whether to create fresh or open existing. + if (content_manager->ContentExists(xuid, content_data)) { + disposition = kDispositionState::Open; + } else { + disposition = kDispositionState::Create; + } + break; + case 3: // OPEN_EXISTING + // Open only if exists. + if (!content_manager->ContentExists(xuid, content_data)) { + result = X_ERROR_PATH_NOT_FOUND; + } else { + disposition = kDispositionState::Open; + } + break; + case 4: // OPEN_ALWAYS + // Create if needed. + if (!content_manager->ContentExists(xuid, content_data)) { + disposition = kDispositionState::Create; + } else { + disposition = kDispositionState::Open; + } + break; + case 5: // TRUNCATE_EXISTING + // Fail if doesn't exist, if does exist delete and recreate. + if (!content_manager->ContentExists(xuid, content_data)) { + result = X_ERROR_PATH_NOT_FOUND; + } else { + content_manager->CloseContent(root_name); + content_manager->DeleteContent(xuid, content_data); + if (content_manager->ContentExists(xuid, content_data)) { + disposition = kDispositionState::Open; + } else { + disposition = kDispositionState::Create; + } + } + break; + default: + assert_unhandled_case(flags & 0xF); + break; + } + + uint32_t content_license = 0; + if (disposition == kDispositionState::Create) { + result = content_manager->CreateContent(root_name, xuid, content_data); + if (XSUCCEEDED(result)) { + content_manager->WriteContentHeaderFile(xuid, content_data); + } + } else if (disposition == kDispositionState::Open) { + result = content_manager->OpenContent(root_name, xuid, content_data, content_license); + } + + if (license_mask_ptr && XSUCCEEDED(result)) { + *license_mask_ptr = content_license; + } + + if (disposition_ptr) { + *disposition_ptr = static_cast(disposition); + } + + extended_error = X_HRESULT_FROM_WIN32(result); + length = static_cast(disposition); + return result; + }; + + if (!overlapped_ptr) { + uint32_t extended_error, length; + return run(extended_error, length); + } else { + REX_KERNEL_STATE()->CompleteOverlappedDeferredEx(run, overlapped_ptr.guest_address()); + return X_ERROR_IO_PENDING; + } +} + +u32 XamContentCreateEx_entry(u32 user_index, mapped_string root_name, mapped_void content_data_ptr, + u32 flags, mapped_u32 disposition_ptr, mapped_u32 license_mask_ptr, + u32 cache_size, u64 content_size, mapped_void overlapped_ptr) { + return xeXamContentCreate(user_index, root_name, content_data_ptr, sizeof(XCONTENT_DATA), flags, + disposition_ptr, license_mask_ptr, cache_size, content_size, + overlapped_ptr); +} + +u32 XamContentCreate_entry(u32 user_index, mapped_string root_name, mapped_void content_data_ptr, + u32 flags, mapped_u32 disposition_ptr, mapped_u32 license_mask_ptr, + mapped_void overlapped_ptr) { + return xeXamContentCreate(user_index, root_name, content_data_ptr, sizeof(XCONTENT_DATA), flags, + disposition_ptr, license_mask_ptr, 0, 0, overlapped_ptr); +} + +u32 XamContentCreateInternal_entry(mapped_string root_name, mapped_void content_data_ptr, u32 flags, + mapped_u32 disposition_ptr, mapped_u32 license_mask_ptr, + u32 cache_size, u64 content_size, mapped_void overlapped_ptr) { + return xeXamContentCreate(0xFE, root_name, content_data_ptr, sizeof(XCONTENT_AGGREGATE_DATA), + flags, disposition_ptr, license_mask_ptr, cache_size, content_size, + overlapped_ptr); +} + +u32 XamContentOpenFile_entry(u32 user_index, mapped_string root_name, mapped_string path, u32 flags, + mapped_u32 disposition_ptr, mapped_u32 license_mask_ptr, + mapped_void overlapped_ptr) { + // TODO(gibbed): arguments assumed based on XamContentCreate. + return X_ERROR_FILE_NOT_FOUND; +} + +u32 XamContentFlush_entry(mapped_string root_name, mapped_void overlapped_ptr) { + X_RESULT result = X_ERROR_SUCCESS; + if (overlapped_ptr) { + REX_KERNEL_STATE()->CompleteOverlappedImmediate(overlapped_ptr.guest_address(), result); + return X_ERROR_IO_PENDING; + } else { + return result; + } +} + +u32 XamContentClose_entry(mapped_string root_name, mapped_void overlapped_ptr) { + // Closes a previously opened root from XamContentCreate*. + auto result = REX_KERNEL_STATE()->content_manager()->CloseContent(root_name.value()); + + if (overlapped_ptr) { + REX_KERNEL_STATE()->CompleteOverlappedImmediate(overlapped_ptr.guest_address(), result); + return X_ERROR_IO_PENDING; + } else { + return result; + } +} + +u32 XamContentGetCreator_entry(u32 user_index, mapped_void content_data_ptr, + mapped_u32 is_creator_ptr, mapped_u64 creator_xuid_ptr, + mapped_void overlapped_ptr) { + auto result = X_ERROR_SUCCESS; + + uint64_t xuid = REX_KERNEL_STATE()->user_profile()->xuid(); + XCONTENT_AGGREGATE_DATA content_data = *content_data_ptr.as(); + + bool content_exists = REX_KERNEL_STATE()->content_manager()->ContentExists(xuid, content_data); + + if (content_exists) { + if (content_data.content_type == XContentType::kSavedGame) { + // User always creates saves. + *is_creator_ptr = 1; + if (creator_xuid_ptr) { + *creator_xuid_ptr = xuid; + } + } else { + *is_creator_ptr = 0; + if (creator_xuid_ptr) { + *creator_xuid_ptr = 0; + } + } + } else { + result = X_ERROR_PATH_NOT_FOUND; + } + + if (overlapped_ptr) { + REX_KERNEL_STATE()->CompleteOverlappedImmediate(overlapped_ptr.guest_address(), result); + return X_ERROR_IO_PENDING; + } else { + return result; + } +} + +u32 XamContentGetThumbnail_entry(u32 user_index, mapped_void content_data_ptr, + mapped_void buffer_ptr, mapped_u32 buffer_size_ptr, + mapped_void overlapped_ptr) { + assert_not_null(buffer_size_ptr); + uint32_t buffer_size = *buffer_size_ptr; + uint64_t xuid = REX_KERNEL_STATE()->user_profile()->xuid(); + XCONTENT_AGGREGATE_DATA content_data = *content_data_ptr.as(); + + // Get thumbnail (if it exists). + std::vector buffer; + auto result = + REX_KERNEL_STATE()->content_manager()->GetContentThumbnail(xuid, content_data, &buffer); + + *buffer_size_ptr = uint32_t(buffer.size()); + + if (XSUCCEEDED(result)) { + // Write data, if we were given a pointer. + // This may have just been a size query. + if (buffer_ptr) { + if (buffer_size < buffer.size()) { + // Dest buffer too small. + result = X_ERROR_INSUFFICIENT_BUFFER; + } else { + // Copy data. + std::memcpy((uint8_t*)buffer_ptr, buffer.data(), buffer.size()); + } + } + } + + if (overlapped_ptr) { + REX_KERNEL_STATE()->CompleteOverlappedImmediate(overlapped_ptr.guest_address(), result); + return X_ERROR_IO_PENDING; + } else { + return result; + } +} + +u32 XamContentSetThumbnail_entry(u32 user_index, mapped_void content_data_ptr, + mapped_void buffer_ptr, u32 buffer_size, + mapped_void overlapped_ptr) { + uint64_t xuid = REX_KERNEL_STATE()->user_profile()->xuid(); + XCONTENT_AGGREGATE_DATA content_data = *content_data_ptr.as(); + + // Buffer is PNG data. + auto buffer = std::vector((uint8_t*)buffer_ptr, (uint8_t*)buffer_ptr + buffer_size); + auto result = REX_KERNEL_STATE()->content_manager()->SetContentThumbnail(xuid, content_data, + std::move(buffer)); + + if (overlapped_ptr) { + REX_KERNEL_STATE()->CompleteOverlappedImmediate(overlapped_ptr.guest_address(), result); + return X_ERROR_IO_PENDING; + } else { + return result; + } +} + +u32 XamContentDelete_entry(u32 user_index, mapped_void content_data_ptr, + mapped_void overlapped_ptr) { + uint64_t xuid = REX_KERNEL_STATE()->user_profile()->xuid(); + XCONTENT_AGGREGATE_DATA content_data = *content_data_ptr.as(); + + auto result = REX_KERNEL_STATE()->content_manager()->DeleteContent(xuid, content_data); + + if (overlapped_ptr) { + REX_KERNEL_STATE()->CompleteOverlappedImmediate(overlapped_ptr.guest_address(), result); + return X_ERROR_IO_PENDING; + } else { + return result; + } +} + +u32 XamContentDeleteInternal_entry(mapped_void content_data_ptr, mapped_void overlapped_ptr) { + // INFO: Analysis of xam.xex shows that "internal" functions are wrappers with + // 0xFE as user_index + uint64_t xuid = REX_KERNEL_STATE()->user_profile()->xuid(); + XCONTENT_AGGREGATE_DATA content_data = *content_data_ptr.as(); + + auto result = REX_KERNEL_STATE()->content_manager()->DeleteContent(xuid, content_data); + + if (overlapped_ptr) { + REX_KERNEL_STATE()->CompleteOverlappedImmediate(overlapped_ptr.guest_address(), result); + return X_ERROR_IO_PENDING; + } else { + return result; + } +} + +} // namespace xam +} // namespace kernel +} // namespace rex + +REX_EXPORT(__imp__XamContentGetLicenseMask, rex::kernel::xam::XamContentGetLicenseMask_entry) +REX_EXPORT(__imp__XamContentResolve, rex::kernel::xam::XamContentResolve_entry) +REX_EXPORT(__imp__XamContentCreateEnumerator, rex::kernel::xam::XamContentCreateEnumerator_entry) +REX_EXPORT(__imp__XamContentCreateEx, rex::kernel::xam::XamContentCreateEx_entry) +REX_EXPORT(__imp__XamContentCreate, rex::kernel::xam::XamContentCreate_entry) +REX_EXPORT(__imp__XamContentCreateInternal, rex::kernel::xam::XamContentCreateInternal_entry) +REX_EXPORT(__imp__XamContentOpenFile, rex::kernel::xam::XamContentOpenFile_entry) +REX_EXPORT(__imp__XamContentFlush, rex::kernel::xam::XamContentFlush_entry) +REX_EXPORT(__imp__XamContentClose, rex::kernel::xam::XamContentClose_entry) +REX_EXPORT(__imp__XamContentGetCreator, rex::kernel::xam::XamContentGetCreator_entry) +REX_EXPORT(__imp__XamContentGetThumbnail, rex::kernel::xam::XamContentGetThumbnail_entry) +REX_EXPORT(__imp__XamContentSetThumbnail, rex::kernel::xam::XamContentSetThumbnail_entry) +REX_EXPORT(__imp__XamContentDelete, rex::kernel::xam::XamContentDelete_entry) +REX_EXPORT(__imp__XamContentDeleteInternal, rex::kernel::xam::XamContentDeleteInternal_entry) + +REX_EXPORT_STUB(__imp__XamContentClosePackageFile); +REX_EXPORT_STUB(__imp__XamContentCopyInternal); +REX_EXPORT_STUB(__imp__XamContentCreateAndMountPackage); +REX_EXPORT_STUB(__imp__XamContentCreateEnumeratorInternal); +REX_EXPORT_STUB(__imp__XamContentDismountAndClosePackage); +REX_EXPORT_STUB(__imp__XamContentDuplicateFileHandle); +REX_EXPORT_STUB(__imp__XamContentExistsOnDeviceInternal); +REX_EXPORT_STUB(__imp__XamContentFlushPackage); +REX_EXPORT_STUB(__imp__XamContentGetAttributes); +REX_EXPORT_STUB(__imp__XamContentGetAttributesInternal); +REX_EXPORT_STUB(__imp__XamContentGetHeaderInternal); +REX_EXPORT_STUB(__imp__XamContentGetLocalizedString); +REX_EXPORT_STUB(__imp__XamContentGetMetaDataInternal); +REX_EXPORT_STUB(__imp__XamContentGetMountedPackageByRootName); +REX_EXPORT_STUB(__imp__XamContentGetOnlineCreator); +REX_EXPORT_STUB(__imp__XamContentInstall); +REX_EXPORT_STUB(__imp__XamContentInstallInternal); +REX_EXPORT_STUB(__imp__XamContentIsGameInstalledToHDD); +REX_EXPORT_STUB(__imp__XamContentLaunchImage); +REX_EXPORT_STUB(__imp__XamContentLaunchImageFromFileInternal); +REX_EXPORT_STUB(__imp__XamContentLaunchImageInternal); +REX_EXPORT_STUB(__imp__XamContentLaunchImageInternalEx); +REX_EXPORT_STUB(__imp__XamContentLockUnlockPackageHeaders); +REX_EXPORT_STUB(__imp__XamContentMountInstalledGame); +REX_EXPORT_STUB(__imp__XamContentMountPackage); +REX_EXPORT_STUB(__imp__XamContentMoveInternal); +REX_EXPORT_STUB(__imp__XamContentOpenFileInternal); +REX_EXPORT_STUB(__imp__XamContentOpenPackageFile); +REX_EXPORT_STUB(__imp__XamContentQueryLicenseInternal); +REX_EXPORT_STUB(__imp__XamContentRegisterChangeCallback); +REX_EXPORT_STUB(__imp__XamContentResolveInternal); +REX_EXPORT_STUB(__imp__XamContentSetAttributes); +REX_EXPORT_STUB(__imp__XamContentSetMediaMetaDataInternal); +REX_EXPORT_STUB(__imp__XamContentSetThumbnailInternal); +REX_EXPORT_STUB(__imp__XamContentWritePackageHeader); diff --git a/src/kernel/xam/xam_content_aggregate.cpp b/src/kernel/xam/xam_content_aggregate.cpp new file mode 100644 index 0000000..2436bbd --- /dev/null +++ b/src/kernel/xam/xam_content_aggregate.cpp @@ -0,0 +1,157 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex { +namespace kernel { +namespace xam { +using namespace rex::system; +using namespace rex::system::xam; + +void AddODDContentTest(object_ref> e, + XContentType content_type) { + auto root_entry = REX_KERNEL_FS()->ResolvePath("game:\\Content\\0000000000000000"); + if (!root_entry) { + return; + } + + auto content_type_path = fmt::format("{:08X}", uint32_t(content_type)); + + rex::filesystem::WildcardEngine title_find_engine; + title_find_engine.SetRule("????????"); + + rex::filesystem::WildcardEngine content_find_engine; + content_find_engine.SetRule("????????????????"); + + size_t title_find_index = 0; + rex::filesystem::Entry* title_entry; + for (;;) { + title_entry = root_entry->IterateChildren(title_find_engine, &title_find_index); + if (!title_entry) { + break; + } + + auto title_id = rex::string::from_string(title_entry->name(), true); + + auto content_root_entry = title_entry->ResolvePath(content_type_path); + if (content_root_entry) { + size_t content_find_index = 0; + rex::filesystem::Entry* content_entry; + for (;;) { + content_entry = + content_root_entry->IterateChildren(content_find_engine, &content_find_index); + if (!content_entry) { + break; + } + + auto item = e->AppendItem(); + assert_not_null(item); + if (item) { + item->device_id = static_cast(DummyDeviceId::ODD); + item->content_type = content_type; + item->set_display_name(string::to_utf16(content_entry->name())); + item->set_file_name(content_entry->name()); + item->title_id = title_id; + } + } + } + } +} + +u32 XamContentAggregateCreateEnumerator_entry(u64 xuid, u32 device_id, u32 content_type, u32 unk3, + mapped_u32 handle_out) { + assert_not_null(handle_out); + + auto device_info = device_id == 0 ? nullptr : GetDummyDeviceInfo(device_id); + if ((device_id && device_info == nullptr) || !handle_out) { + return X_E_INVALIDARG; + } + + auto e = make_object>(REX_KERNEL_STATE(), 1); + X_KENUMERATOR_CONTENT_AGGREGATE* extra; + auto result = e->Initialize(0xFF, 0xFE, 0x2000E, 0x20010, 0, &extra); + if (XFAILED(result)) { + return result; + } + + extra->magic = kXObjSignature; + extra->handle = e->handle(); + + auto content_type_enum = XContentType(uint32_t(content_type)); + + uint64_t userxuid = REX_KERNEL_STATE()->user_profile()->xuid(); + + if (!device_info || device_info->device_type == DeviceType::HDD) { + // Fetch any alternate title IDs defined in the XEX header + // (used by games to load saves from other titles, etc) + std::vector title_ids{kCurrentlyRunningTitleId}; + auto exe_module = REX_KERNEL_STATE()->GetExecutableModule(); + if (exe_module && exe_module->xex_module()) { + const auto& alt_ids = exe_module->xex_module()->opt_alternate_title_ids(); + std::copy(alt_ids.cbegin(), alt_ids.cend(), std::back_inserter(title_ids)); + } + + for (auto& title_id : title_ids) { + // Get user-specific content + auto content_datas = REX_KERNEL_STATE()->content_manager()->ListContent( + static_cast(DummyDeviceId::HDD), xuid, content_type_enum, title_id); + for (const auto& content_data : content_datas) { + auto item = e->AppendItem(); + assert_not_null(item); + if (item) { + *item = content_data; + } + } + + // Also get common content (xuid=0) + if (userxuid != 0) { + auto common_datas = REX_KERNEL_STATE()->content_manager()->ListContent( + static_cast(DummyDeviceId::HDD), 0, content_type_enum, title_id); + for (const auto& content_data : common_datas) { + auto item = e->AppendItem(); + assert_not_null(item); + if (item) { + *item = content_data; + } + } + } + } + } + + if (!device_info || device_info->device_type == DeviceType::ODD) { + AddODDContentTest(e, content_type_enum); + } + + REXKRNL_DEBUG("XamContentAggregateCreateEnumerator: added {} items to enumerator", + e->item_count()); + + *handle_out = e->handle(); + return X_ERROR_SUCCESS; +} + +} // namespace xam +} // namespace kernel +} // namespace rex + +REX_EXPORT(__imp__XamContentAggregateCreateEnumerator, + rex::kernel::xam::XamContentAggregateCreateEnumerator_entry) diff --git a/src/kernel/xam/xam_content_device.cpp b/src/kernel/xam/xam_content_device.cpp new file mode 100644 index 0000000..3c51815 --- /dev/null +++ b/src/kernel/xam/xam_content_device.cpp @@ -0,0 +1,187 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex { +namespace kernel { +namespace xam { +using namespace rex::system; +using namespace rex::system::xam; + +// TODO(gibbed): real information. +// +// Until we expose real information about a HDD device, we +// claim there is 3GB free on a 4GB dummy HDD. +// +// There is a possibility that certain games are bugged in that +// they incorrectly only look at the lower 32-bits of free_bytes, +// when it is a 64-bit value. Which means any size above ~4GB +// will not be recognized properly. +#define ONE_GB (1024ull * 1024ull * 1024ull) + +static const DummyDeviceInfo dummy_hdd_device_info_ = { + DummyDeviceId::HDD, DeviceType::HDD, + 20ull * ONE_GB, // 20GB + 3ull * ONE_GB, // 3GB, so it looks a little used. + u"Dummy HDD", +}; +static const DummyDeviceInfo dummy_odd_device_info_ = { + DummyDeviceId::ODD, DeviceType::ODD, + 7ull * ONE_GB, // 7GB (rough maximum) + 0ull * ONE_GB, // read-only FS, so no free space + u"Dummy ODD", +}; +static const DummyDeviceInfo* dummy_device_infos_[] = { + &dummy_hdd_device_info_, + &dummy_odd_device_info_, +}; +#undef ONE_GB + +const DummyDeviceInfo* GetDummyDeviceInfo(uint32_t device_id) { + const auto& begin = std::begin(dummy_device_infos_); + const auto& end = std::end(dummy_device_infos_); + auto it = std::find_if(begin, end, [device_id](const auto& item) { + return static_cast(item->device_id) == device_id; + }); + return it == end ? nullptr : *it; +} + +u32 XamContentGetDeviceName_entry(u32 device_id, mapped_wstring name_buffer, u32 name_capacity) { + auto device_info = GetDummyDeviceInfo(device_id); + if (device_info == nullptr) { + return X_ERROR_DEVICE_NOT_CONNECTED; + } + auto name = std::u16string(device_info->name); + if (name_capacity < name.size() + 1) { + return X_ERROR_INSUFFICIENT_BUFFER; + } + rex::string::util_copy_and_swap_truncating(name_buffer, name, name_capacity); + return X_ERROR_SUCCESS; +} + +u32 XamContentGetDeviceState_entry(u32 device_id, mapped_void overlapped_ptr) { + auto device_info = GetDummyDeviceInfo(device_id); + if (device_info == nullptr) { + if (overlapped_ptr) { + REX_KERNEL_STATE()->CompleteOverlappedImmediateEx( + overlapped_ptr.guest_address(), X_ERROR_FUNCTION_FAILED, X_ERROR_DEVICE_NOT_CONNECTED, 0); + return X_ERROR_IO_PENDING; + } else { + return X_ERROR_DEVICE_NOT_CONNECTED; + } + } + if (overlapped_ptr) { + REX_KERNEL_STATE()->CompleteOverlappedImmediate(overlapped_ptr.guest_address(), + X_ERROR_SUCCESS); + return X_ERROR_IO_PENDING; + } else { + return X_ERROR_SUCCESS; + } +} + +typedef struct { + rex::be device_id; + rex::be device_type; + rex::be total_bytes; + rex::be free_bytes; + union { + rex::be name[28]; + char16_t name_chars[28]; + }; +} X_CONTENT_DEVICE_DATA; +static_assert_size(X_CONTENT_DEVICE_DATA, 0x50); + +u32 XamContentGetDeviceData_entry(u32 device_id, ppc_ptr_t device_data) { + auto device_info = GetDummyDeviceInfo(device_id); + if (device_info == nullptr) { + return X_ERROR_DEVICE_NOT_CONNECTED; + } + device_data.Zero(); + device_data->device_id = static_cast(device_info->device_id); + device_data->device_type = static_cast(device_info->device_type); + device_data->total_bytes = device_info->total_bytes; + device_data->free_bytes = device_info->free_bytes; + rex::string::util_copy_and_swap_truncating(device_data->name_chars, device_info->name, + rex::countof(device_data->name_chars)); + return X_ERROR_SUCCESS; +} + +u32 XamContentCreateDeviceEnumerator_entry(u32 content_type, u32 content_flags, u32 max_count, + mapped_u32 buffer_size_ptr, mapped_u32 handle_out) { + assert_not_null(handle_out); + + if (buffer_size_ptr) { + *buffer_size_ptr = sizeof(X_CONTENT_DEVICE_DATA) * max_count; + } + + auto e = make_object>(REX_KERNEL_STATE(), max_count); + auto result = e->Initialize(0xFE, 0xFE, 0x2000A, 0x20009, 0); + if (XFAILED(result)) { + return result; + } + + for (const auto& device_info : dummy_device_infos_) { + // Copy our dummy device into the enumerator + auto device_data = e->AppendItem(); + assert_not_null(device_data); + if (device_data) { + device_data->device_id = static_cast(device_info->device_id); + device_data->device_type = static_cast(device_info->device_type); + device_data->total_bytes = device_info->total_bytes; + device_data->free_bytes = device_info->free_bytes; + rex::string::util_copy_and_swap_truncating(device_data->name_chars, device_info->name, + rex::countof(device_data->name_chars)); + } + } + + *handle_out = e->handle(); + return X_ERROR_SUCCESS; +} + +} // namespace xam +} // namespace kernel +} // namespace rex + +// fix me later +namespace rex { +namespace system { +namespace xam { + +const DummyDeviceInfo* GetDummyDeviceInfo(uint32_t device_id) { + return rex::kernel::xam::GetDummyDeviceInfo(device_id); +} + +} // namespace xam +} // namespace system +} // namespace rex + +REX_EXPORT(__imp__XamContentGetDeviceName, rex::kernel::xam::XamContentGetDeviceName_entry) +REX_EXPORT(__imp__XamContentGetDeviceState, rex::kernel::xam::XamContentGetDeviceState_entry) +REX_EXPORT(__imp__XamContentGetDeviceData, rex::kernel::xam::XamContentGetDeviceData_entry) +REX_EXPORT(__imp__XamContentCreateDeviceEnumerator, + rex::kernel::xam::XamContentCreateDeviceEnumerator_entry) + +REX_EXPORT_STUB(__imp__XamContentAddCacheDevice); +REX_EXPORT_STUB(__imp__XamContentDeviceCheckUpdates); +REX_EXPORT_STUB(__imp__XamContentGetDefaultDevice); +REX_EXPORT_STUB(__imp__XamContentGetDeviceSerialNumber); +REX_EXPORT_STUB(__imp__XamContentGetDeviceVolumePath); +REX_EXPORT_STUB(__imp__XamContentGetLocalizedDeviceData); +REX_EXPORT_STUB(__imp__XamContentRemoveCacheDevice); diff --git a/src/kernel/xam/xam_debug.cpp b/src/kernel/xam/xam_debug.cpp new file mode 100644 index 0000000..682f0e9 --- /dev/null +++ b/src/kernel/xam/xam_debug.cpp @@ -0,0 +1,69 @@ +/** + * @file kernel/xam/xam_debug.cpp + * @brief XAM debug export implementations + * + * @copyright Copyright 2022 Ben Vanik. All rights reserved. (Xenia Project) + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +namespace rex { +namespace kernel { +namespace xam { + +// OutputDebugStringA - ANSI debug string output +void OutputDebugStringA_entry(mapped_string string) { + if (string) { + REXKRNL_INFO("OutputDebugStringA: {}", string.value()); + } +} + +// OutputDebugStringW - Unicode debug string output +void OutputDebugStringW_entry(mapped_wstring string) { + if (string) { + // Convert char16_t to UTF-8 for logging (simple ASCII fallback) + std::u16string_view sv = string.value(); + std::string utf8; + utf8.reserve(sv.size()); + for (char16_t c : sv) { + if (c < 0x80) { + utf8.push_back(static_cast(c)); + } else { + utf8.push_back('?'); // Non-ASCII fallback + } + } + REXKRNL_INFO("OutputDebugStringW: {}", utf8); + } +} + +// RtlOutputDebugString - Same as OutputDebugStringA +void RtlOutputDebugString_entry(mapped_string string) { + if (string) { + REXKRNL_INFO("RtlOutputDebugString: {}", string.value()); + } +} + +// RtlDebugTrace - Debug trace output +void RtlDebugTrace_entry(mapped_string string) { + if (string) { + REXKRNL_INFO("RtlDebugTrace: {}", string.value()); + } +} + +} // namespace xam +} // namespace kernel +} // namespace rex + +// Hook registrations +REX_EXPORT(__imp__OutputDebugStringA, rex::kernel::xam::OutputDebugStringA_entry) +REX_EXPORT(__imp__OutputDebugStringW, rex::kernel::xam::OutputDebugStringW_entry) +REX_EXPORT(__imp__RtlOutputDebugString, rex::kernel::xam::RtlOutputDebugString_entry) +REX_EXPORT(__imp__RtlDebugTrace, rex::kernel::xam::RtlDebugTrace_entry) diff --git a/src/kernel/xam/xam_enum.cpp b/src/kernel/xam/xam_enum.cpp new file mode 100644 index 0000000..b8d4c40 --- /dev/null +++ b/src/kernel/xam/xam_enum.cpp @@ -0,0 +1,115 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if REX_PLATFORM_WIN32 +#include +#endif + +#include + +namespace rex { +namespace kernel { +namespace xam { +using namespace rex::system; +using namespace rex::system::xam; + +// https://github.com/LestaD/SourceEngine2007/blob/master/se2007/engine/xboxsystem.cpp#L518 +uint32_t xeXamEnumerate(uint32_t handle, uint32_t flags, mapped_void buffer_ptr, + uint32_t buffer_size, uint32_t* items_returned, uint32_t overlapped_ptr) { + assert_true(flags == 0); + + auto e = REX_KERNEL_OBJECTS()->LookupObject(handle); + if (!e) { + return X_ERROR_INVALID_HANDLE; + } + + auto run = [e, buffer_ptr](uint32_t& extended_error, uint32_t& length) -> X_RESULT { + X_RESULT result; + uint32_t item_count = 0; + if (!buffer_ptr) { + result = X_ERROR_INVALID_PARAMETER; + } else { + result = e->WriteItems(buffer_ptr.guest_address(), buffer_ptr.as(), &item_count); + } + extended_error = X_HRESULT_FROM_WIN32(result); + length = item_count; + return result; + }; + + if (items_returned) { + assert_true(!overlapped_ptr); + uint32_t extended_error; + uint32_t item_count; + X_RESULT result = run(extended_error, item_count); + *items_returned = result == X_ERROR_SUCCESS ? item_count : 0; + return result; + } else if (overlapped_ptr) { + assert_true(!items_returned); + REX_KERNEL_STATE()->CompleteOverlappedDeferredEx(run, overlapped_ptr); + return X_ERROR_IO_PENDING; + } else { + assert_always(); + return X_ERROR_INVALID_PARAMETER; + } +} + +u32 XamEnumerate_entry(u32 handle, u32 flags, mapped_void buffer, u32 buffer_length, + mapped_u32 items_returned, ppc_ptr_t overlapped) { + uint32_t dummy; + auto result = + xeXamEnumerate(handle, flags, buffer, buffer_length, + !overlapped.guest_address() ? &dummy : nullptr, overlapped.guest_address()); + if (!overlapped && items_returned) { + *items_returned = dummy; + } + return result; +} + +u32 XamCreateEnumeratorHandle_entry(u32 unk1, u32 unk2, u32 unk3, u32 unk4, u32 unk5, u32 unk6, + u32 unk7, u32 unk8) { + return X_ERROR_INVALID_PARAMETER; +} + +u32 XamGetPrivateEnumStructureFromHandle_entry(u32 handle, mapped_u32 out_object_ptr) { + auto e = REX_KERNEL_OBJECTS()->LookupObject(handle); + if (!e) { + return X_STATUS_INVALID_HANDLE; + } + + // Caller takes the reference. + // It's released in ObDereferenceObject. + e->RetainHandle(); + + if (out_object_ptr.guest_address()) { + *out_object_ptr = e->guest_object(); + } + + return X_STATUS_SUCCESS; +} + +} // namespace xam +} // namespace kernel +} // namespace rex + +REX_EXPORT(__imp__XamEnumerate, rex::kernel::xam::XamEnumerate_entry) +REX_EXPORT(__imp__XamCreateEnumeratorHandle, rex::kernel::xam::XamCreateEnumeratorHandle_entry) +REX_EXPORT(__imp__XamGetPrivateEnumStructureFromHandle, + rex::kernel::xam::XamGetPrivateEnumStructureFromHandle_entry) diff --git a/src/kernel/xam/xam_info.cpp b/src/kernel/xam/xam_info.cpp new file mode 100644 index 0000000..6331e4f --- /dev/null +++ b/src/kernel/xam/xam_info.cpp @@ -0,0 +1,365 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if REX_PLATFORM_WIN32 +#include +#endif + +#include +#include + +namespace rex { +namespace kernel { +namespace xam { +using namespace rex::system; + +u32 XamFeatureEnabled_entry(u32 unk) { + return 0; +} + +// Empty stub schema binary. +uint8_t schema_bin[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2C, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, +}; + +u32 XamGetOnlineSchema_entry() { + static uint32_t schema_guest = 0; + + if (!schema_guest) { + schema_guest = REX_KERNEL_MEMORY()->SystemHeapAlloc(8 + sizeof(schema_bin)); + auto schema = REX_KERNEL_MEMORY()->TranslateVirtual(schema_guest); + std::memcpy(schema + 8, schema_bin, sizeof(schema_bin)); + memory::store_and_swap(schema + 0, schema_guest + 8); + memory::store_and_swap(schema + 4, sizeof(schema_bin)); + } + + // return pointer to the schema ptr/schema size struct + return schema_guest; +} + +#if REX_PLATFORM_WIN32 +static SYSTEMTIME xeGetLocalSystemTime(uint64_t filetime) { + FILETIME t; + t.dwHighDateTime = filetime >> 32; + t.dwLowDateTime = (uint32_t)filetime; + + SYSTEMTIME st; + SYSTEMTIME local_st; + FileTimeToSystemTime(&t, &st); + SystemTimeToTzSpecificLocalTime(NULL, &st, &local_st); + return local_st; +} +#endif + +void XamFormatDateString_entry(u32 unk, u64 filetime, mapped_void output_buffer, u32 output_count) { + std::memset(output_buffer, 0, output_count * sizeof(char16_t)); + +// TODO: implement this for other platforms +#if REX_PLATFORM_WIN32 + auto st = xeGetLocalSystemTime(filetime); + // TODO: format this depending on users locale? + auto str = fmt::format(u"{:02d}/{:02d}/{}", st.wMonth, st.wDay, st.wYear); + rex::string::util_copy_and_swap_truncating(output_buffer.as(), str, output_count); +#else + assert_always(); +#endif +} + +void XamFormatTimeString_entry(u32 unk, u64 filetime, mapped_void output_buffer, u32 output_count) { + std::memset(output_buffer, 0, output_count * sizeof(char16_t)); + +// TODO: implement this for other platforms +#if REX_PLATFORM_WIN32 + auto st = xeGetLocalSystemTime(filetime); + // TODO: format this depending on users locale? + auto str = fmt::format(u"{:02d}:{:02d}", st.wHour, st.wMinute); + rex::string::util_copy_and_swap_truncating(output_buffer.as(), str, output_count); +#else + assert_always(); +#endif +} + +u32 keXamBuildResourceLocator(uint64_t module, std::u16string_view container, + std::u16string_view resource, mapped_void buffer_ptr, + uint32_t buffer_count) { + std::u16string path; + if (!module) { + path = fmt::format(u"file://media:/{}.xzp#{}", container, resource); + REXKRNL_DEBUG("XamBuildResourceLocator({0}) returning locator to local file {0}.xzp", + rex::string::to_utf8(container)); + } else { + path = fmt::format(u"section://{:X},{}#{}", (uint32_t)module, container, resource); + } + rex::string::util_copy_and_swap_truncating(buffer_ptr.as(), path, buffer_count); + return 0; +} + +u32 XamBuildResourceLocator_entry(u64 module, mapped_wstring container, mapped_wstring resource, + mapped_void buffer_ptr, u32 buffer_count) { + return keXamBuildResourceLocator(module, container.value(), resource.value(), buffer_ptr, + buffer_count); +} + +u32 XamBuildGamercardResourceLocator_entry(mapped_wstring filename, mapped_void buffer_ptr, + u32 buffer_count) { + // On an actual xbox these funcs would return a locator to xam.xex resources, + // but for Xenia we can return a locator to the resources as local files. (big + // thanks to MS for letting XamBuildResourceLocator return local file + // locators!) + + // If you're running an app that'll need them, make sure to extract xam.xex + // resources with xextool ("xextool -d . xam.xex") and add a .xzp extension. + + return keXamBuildResourceLocator(0, u"gamercrd", filename.value(), buffer_ptr, buffer_count); +} + +u32 XamBuildSharedSystemResourceLocator_entry(mapped_wstring filename, mapped_void buffer_ptr, + u32 buffer_count) { + // see notes inside XamBuildGamercardResourceLocator above + return keXamBuildResourceLocator(0, u"shrdres", filename.value(), buffer_ptr, buffer_count); +} + +u32 XamBuildLegacySystemResourceLocator_entry(mapped_wstring filename, mapped_void buffer_ptr, + u32 buffer_count) { + return XamBuildSharedSystemResourceLocator_entry(filename, buffer_ptr, buffer_count); +} + +u32 XamBuildXamResourceLocator_entry(mapped_wstring filename, mapped_void buffer_ptr, + u32 buffer_count) { + return keXamBuildResourceLocator(0, u"xam", filename.value(), buffer_ptr, buffer_count); +} + +u32 XamGetSystemVersion_entry() { + // eh, just picking one. If we go too low we may break new games, but + // this value seems to be used for conditionally loading symbols and if + // we pretend to be old we have less to worry with implementing. + // 0x200A3200 + // 0x20096B00 + return 0; +} + +void XCustomRegisterDynamicActions_entry() { + // ??? +} + +u32 XGetAVPack_entry() { + // DWORD + // Not sure what the values are for this, but 6 is VGA. + // Other likely values are 3/4/8 for HDMI or something. + // Games seem to use this as a PAL check - if the result is not 3/4/6/8 + // they explode with errors if not in PAL mode. + REXKRNL_IMPORT_RESULT("XGetAVPack", "6"); + return 6; +} + +uint32_t xeXGetGameRegion() { + return 0xFFFFu; +} + +u32 XGetGameRegion_entry() { + return xeXGetGameRegion(); +} + +u32 XGetLanguage_entry() { + auto desired_language = XLanguage::kEnglish; + + // Switch the language based on game region. + // TODO(benvanik): pull from xex header. + uint32_t game_region = XEX_REGION_NTSCU; + if (game_region & XEX_REGION_NTSCU) { + desired_language = XLanguage::kEnglish; + } else if (game_region & XEX_REGION_NTSCJ) { + desired_language = XLanguage::kJapanese; + } + // Add more overrides? + + return uint32_t(desired_language); +} + +u32 XamGetCurrentTitleId_entry() { + // NOTE(tomc): Switched this up to get title ID from executable module instead of runtime + // (emulator) + auto module = REX_KERNEL_STATE()->GetExecutableModule(); + if (module) { + return module->title_id(); + } + return 0; +} + +u32 XamGetExecutionId_entry(mapped_u32 info_ptr) { + auto module = REX_KERNEL_STATE()->GetExecutableModule(); + assert_not_null(module); + + uint32_t guest_hdr_ptr; + X_STATUS result = module->GetOptHeader(XEX_HEADER_EXECUTION_INFO, &guest_hdr_ptr); + + if (XFAILED(result)) { + return result; + } + + *info_ptr = guest_hdr_ptr; + return X_STATUS_SUCCESS; +} + +u32 XamLoaderSetLaunchData_entry(mapped_void data, u32 size) { + auto xam = REX_KERNEL_STATE()->GetKernelModule("xam.xex"); + auto& loader_data = xam->loader_data(); + loader_data.launch_data_present = size ? true : false; + loader_data.launch_data.resize(size); + std::memcpy(loader_data.launch_data.data(), data, size); + return 0; +} + +u32 XamLoaderGetLaunchDataSize_entry(mapped_u32 size_ptr) { + if (!size_ptr) { + return X_ERROR_INVALID_PARAMETER; + } + + auto xam = REX_KERNEL_STATE()->GetKernelModule("xam.xex"); + auto& loader_data = xam->loader_data(); + if (!loader_data.launch_data_present) { + *size_ptr = 0; + return X_ERROR_NOT_FOUND; + } + + *size_ptr = uint32_t(xam->loader_data().launch_data.size()); + return X_ERROR_SUCCESS; +} + +u32 XamLoaderGetLaunchData_entry(mapped_void buffer_ptr, u32 buffer_size) { + auto xam = REX_KERNEL_STATE()->GetKernelModule("xam.xex"); + auto& loader_data = xam->loader_data(); + if (!loader_data.launch_data_present) { + return X_ERROR_NOT_FOUND; + } + + uint32_t copy_size = std::min(uint32_t(loader_data.launch_data.size()), uint32_t(buffer_size)); + std::memcpy(buffer_ptr, loader_data.launch_data.data(), copy_size); + return X_ERROR_SUCCESS; +} + +void XamLoaderLaunchTitle_entry(mapped_string raw_name_ptr, u32 flags) { + auto xam = REX_KERNEL_STATE()->GetKernelModule("xam.xex"); + + auto& loader_data = xam->loader_data(); + loader_data.launch_flags = flags; + + // Translate the launch path to a full path. + if (raw_name_ptr) { + auto path = raw_name_ptr.value(); + if (path.empty()) { + loader_data.launch_path = "game:\\default.xex"; + } else { + if (rex::string::utf8_find_name_from_guest_path(path) == path) { + path = rex::string::utf8_join_guest_paths( + rex::string::utf8_find_base_guest_path( + REX_KERNEL_STATE()->GetExecutableModule()->path()), + path); + } + loader_data.launch_path = path; + } + } else { + assert_always("Game requested exit to dashboard via XamLoaderLaunchTitle"); + } + + // This function does not return. + REX_KERNEL_STATE()->TerminateTitle(); +} + +void XamLoaderTerminateTitle_entry() { + // This function does not return. + REX_KERNEL_STATE()->TerminateTitle(); +} + +u32 XamAlloc_entry(u32 unk, u32 size, mapped_u32 out_ptr) { + assert_true(unk == 0); + + // Allocate from the heap. Not sure why XAM does this specially, perhaps + // it keeps stuff in a separate heap? + uint32_t ptr = REX_KERNEL_MEMORY()->SystemHeapAlloc(size); + *out_ptr = ptr; + + return X_ERROR_SUCCESS; +} + +u32 XamFree_entry(mapped_u32 ptr) { + REX_KERNEL_MEMORY()->SystemHeapFree(ptr.guest_address()); + + return X_ERROR_SUCCESS; +} + +u32 XamQueryLiveHiveW_entry(mapped_wstring name, mapped_void out_buf, u32 out_size, + u32 type /* guess */) { + return X_STATUS_INVALID_PARAMETER_1; +} + +u32 XamLoaderGetDvdTrayState_entry(mapped_u32 out_state) { + // 0 = tray open, 1 = tray closed with disc + if (out_state) + *out_state = 1; + return X_STATUS_SUCCESS; +} + +u32 XamSwapDisc_entry(u32 disc_number) { + // Stub for multi-disc games. Single-disc games (like Blue Dragon's reblue test) + // don't need this, but the game may look it up dynamically via XexGetProcedureAddress. + REXKRNL_DEBUG("XamSwapDisc({}) - stub, returning success", (uint32_t)disc_number); + return X_STATUS_SUCCESS; +} + +} // namespace xam +} // namespace kernel +} // namespace rex + +REX_EXPORT(__imp__XamFeatureEnabled, rex::kernel::xam::XamFeatureEnabled_entry) +REX_EXPORT(__imp__XamGetOnlineSchema, rex::kernel::xam::XamGetOnlineSchema_entry) +REX_EXPORT(__imp__XamFormatDateString, rex::kernel::xam::XamFormatDateString_entry) +REX_EXPORT(__imp__XamFormatTimeString, rex::kernel::xam::XamFormatTimeString_entry) +REX_EXPORT(__imp__XamBuildResourceLocator, rex::kernel::xam::XamBuildResourceLocator_entry) +REX_EXPORT(__imp__XamBuildGamercardResourceLocator, + rex::kernel::xam::XamBuildGamercardResourceLocator_entry) +REX_EXPORT(__imp__XamBuildSharedSystemResourceLocator, + rex::kernel::xam::XamBuildSharedSystemResourceLocator_entry) +REX_EXPORT(__imp__XamBuildLegacySystemResourceLocator, + rex::kernel::xam::XamBuildLegacySystemResourceLocator_entry) +REX_EXPORT(__imp__XamBuildXamResourceLocator, rex::kernel::xam::XamBuildXamResourceLocator_entry) +REX_EXPORT(__imp__XamGetSystemVersion, rex::kernel::xam::XamGetSystemVersion_entry) +REX_EXPORT(__imp__XCustomRegisterDynamicActions, + rex::kernel::xam::XCustomRegisterDynamicActions_entry) +REX_EXPORT(__imp__XGetAVPack, rex::kernel::xam::XGetAVPack_entry) +REX_EXPORT(__imp__XGetGameRegion, rex::kernel::xam::XGetGameRegion_entry) +REX_EXPORT(__imp__XGetLanguage, rex::kernel::xam::XGetLanguage_entry) +REX_EXPORT(__imp__XamGetCurrentTitleId, rex::kernel::xam::XamGetCurrentTitleId_entry) +REX_EXPORT(__imp__XamGetExecutionId, rex::kernel::xam::XamGetExecutionId_entry) +REX_EXPORT(__imp__XamLoaderSetLaunchData, rex::kernel::xam::XamLoaderSetLaunchData_entry) +REX_EXPORT(__imp__XamLoaderGetLaunchDataSize, rex::kernel::xam::XamLoaderGetLaunchDataSize_entry) +REX_EXPORT(__imp__XamLoaderGetLaunchData, rex::kernel::xam::XamLoaderGetLaunchData_entry) +REX_EXPORT(__imp__XamLoaderLaunchTitle, rex::kernel::xam::XamLoaderLaunchTitle_entry) +REX_EXPORT(__imp__XamLoaderTerminateTitle, rex::kernel::xam::XamLoaderTerminateTitle_entry) +REX_EXPORT(__imp__XamAlloc, rex::kernel::xam::XamAlloc_entry) +REX_EXPORT(__imp__XamFree, rex::kernel::xam::XamFree_entry) +REX_EXPORT(__imp__XamQueryLiveHiveW, rex::kernel::xam::XamQueryLiveHiveW_entry) +REX_EXPORT(__imp__XamLoaderGetDvdTrayState, rex::kernel::xam::XamLoaderGetDvdTrayState_entry) +REX_EXPORT(__imp__XamSwapDisc, rex::kernel::xam::XamSwapDisc_entry) diff --git a/src/kernel/xam/xam_input.cpp b/src/kernel/xam/xam_input.cpp new file mode 100644 index 0000000..80c3634 --- /dev/null +++ b/src/kernel/xam/xam_input.cpp @@ -0,0 +1,234 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#pragma GCC diagnostic ignored "-Wunused-parameter" + +namespace rex { +namespace kernel { +namespace xam { +using namespace rex::system; + +using rex::input::X_INPUT_CAPABILITIES; +using rex::input::X_INPUT_KEYSTROKE; +using rex::input::X_INPUT_STATE; +using rex::input::X_INPUT_VIBRATION; + +constexpr uint32_t XINPUT_FLAG_GAMEPAD = 0x01; +constexpr uint32_t XINPUT_FLAG_ANY_USER = 1 << 30; + +rex::input::InputSystem* input_system() { + return static_cast(REX_KERNEL_STATE()->emulator()->input_system()); +} + +void XamResetInactivity_entry() { + // Do we need to do anything? +} + +u32 XamEnableInactivityProcessing_entry(u32 unk, u32 enable) { + return X_ERROR_SUCCESS; +} + +// https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputgetcapabilities(v=vs.85).aspx +u32 XamInputGetCapabilities_entry(u32 user_index, u32 flags, ppc_ptr_t caps) { + REXKRNL_TRACE("[XAM] XamInputGetCapabilities called: user={}, flags=0x{:X}", (uint32_t)user_index, + (uint32_t)flags); + if (!caps) { + return X_ERROR_BAD_ARGUMENTS; + } + + if ((flags & 0xFF) && (flags & XINPUT_FLAG_GAMEPAD) == 0) { + // Ignore any query for other types of devices. + return X_ERROR_DEVICE_NOT_CONNECTED; + } + + uint32_t actual_user_index = user_index; + if ((actual_user_index & 0xFF) == 0xFF || (flags & XINPUT_FLAG_ANY_USER)) { + // Always pin user to 0. + actual_user_index = 0; + } + + auto* is = input_system(); + return is->GetCapabilities(actual_user_index, flags, caps); +} + +u32 XamInputGetCapabilitiesEx_entry(u32 unk, u32 user_index, u32 flags, + ppc_ptr_t caps) { + if (!caps) { + return X_ERROR_BAD_ARGUMENTS; + } + + if ((flags & 0xFF) && (flags & XINPUT_FLAG_GAMEPAD) == 0) { + // Ignore any query for other types of devices. + return X_ERROR_DEVICE_NOT_CONNECTED; + } + + uint32_t actual_user_index = user_index; + if ((actual_user_index & 0xFF) == 0xFF || (flags & XINPUT_FLAG_ANY_USER)) { + // Always pin user to 0. + actual_user_index = 0; + } + + (void)unk; // Unused in this implementation + auto* is = input_system(); + return is->GetCapabilities(actual_user_index, flags, caps); +} + +// https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputgetstate(v=vs.85).aspx +u32 XamInputGetState_entry(u32 user_index, u32 flags, ppc_ptr_t input_state) { + // Games call this with a NULL state ptr, probably as a query. + static int call_count = 0; + if (++call_count <= 5) { + REXKRNL_TRACE("[XAM] XamInputGetState called: user={}, flags=0x{:X}", (uint32_t)user_index, + (uint32_t)flags); + } + + if ((flags & 0xFF) && (flags & XINPUT_FLAG_GAMEPAD) == 0) { + // Ignore any query for other types of devices. + return X_ERROR_DEVICE_NOT_CONNECTED; + } + + uint32_t actual_user_index = user_index; + if ((actual_user_index & 0xFF) == 0xFF || (flags & XINPUT_FLAG_ANY_USER)) { + // Always pin user to 0. + actual_user_index = 0; + } + + auto* is = input_system(); + return is->GetState(actual_user_index, input_state); +} + +// https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputsetstate(v=vs.85).aspx +u32 XamInputSetState_entry(u32 user_index, u32 unk, ppc_ptr_t vibration) { + if (!vibration) { + return X_ERROR_BAD_ARGUMENTS; + } + + uint32_t actual_user_index = user_index; + if ((user_index & 0xFF) == 0xFF) { + // Always pin user to 0. + actual_user_index = 0; + } + + (void)unk; // Unused in this implementation + auto* is = input_system(); + return is->SetState(actual_user_index, vibration); +} + +// https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputgetkeystroke(v=vs.85).aspx +u32 XamInputGetKeystroke_entry(u32 user_index, u32 flags, ppc_ptr_t keystroke) { + // https://github.com/CodeAsm/ffplay360/blob/master/Common/AtgXime.cpp + // user index = index or XUSER_INDEX_ANY + // flags = XINPUT_FLAG_GAMEPAD (| _ANYUSER | _ANYDEVICE) + + if (!keystroke) { + return X_ERROR_BAD_ARGUMENTS; + } + + if ((flags & 0xFF) && (flags & XINPUT_FLAG_GAMEPAD) == 0) { + // Ignore any query for other types of devices. + return X_ERROR_DEVICE_NOT_CONNECTED; + } + + uint32_t actual_user_index = user_index; + if ((actual_user_index & 0xFF) == 0xFF || (flags & XINPUT_FLAG_ANY_USER)) { + // Always pin user to 0. + actual_user_index = 0; + } + + auto* is = input_system(); + return is->GetKeystroke(actual_user_index, flags, keystroke); +} + +// Same as non-ex, just takes a pointer to user index. +u32 XamInputGetKeystrokeEx_entry(mapped_u32 user_index_ptr, u32 flags, + ppc_ptr_t keystroke) { + if (!keystroke) { + return X_ERROR_BAD_ARGUMENTS; + } + + if ((flags & 0xFF) && (flags & XINPUT_FLAG_GAMEPAD) == 0) { + // Ignore any query for other types of devices. + return X_ERROR_DEVICE_NOT_CONNECTED; + } + + uint32_t user_index = *user_index_ptr; + if ((user_index & 0xFF) == 0xFF || (flags & XINPUT_FLAG_ANY_USER)) { + // Always pin user to 0. + user_index = 0; + } + + auto* is = input_system(); + auto result = is->GetKeystroke(user_index, flags, keystroke); + if (XSUCCEEDED(result)) { + *user_index_ptr = keystroke->user_index; + } + return result; +} + +i32 XamUserGetDeviceContext_entry(u32 user_index, u32 unk, mapped_u32 out_ptr) { + // Games check the result - usually with some masking. + // If this function fails they assume zero, so let's fail AND + // set zero just to be safe. + *out_ptr = 0; + if (!user_index || (user_index & 0xFF) == 0xFF) { + return X_E_SUCCESS; + } else { + return X_E_DEVICE_NOT_CONNECTED; + } +} + +} // namespace xam +} // namespace kernel +} // namespace rex + +REX_EXPORT(__imp__XamResetInactivity, rex::kernel::xam::XamResetInactivity_entry) +REX_EXPORT(__imp__XamEnableInactivityProcessing, + rex::kernel::xam::XamEnableInactivityProcessing_entry) +REX_EXPORT(__imp__XamInputGetCapabilities, rex::kernel::xam::XamInputGetCapabilities_entry) +REX_EXPORT(__imp__XamInputGetCapabilitiesEx, rex::kernel::xam::XamInputGetCapabilitiesEx_entry) +REX_EXPORT(__imp__XamInputGetState, rex::kernel::xam::XamInputGetState_entry) +REX_EXPORT(__imp__XamInputSetState, rex::kernel::xam::XamInputSetState_entry) +REX_EXPORT(__imp__XamInputGetKeystroke, rex::kernel::xam::XamInputGetKeystroke_entry) +REX_EXPORT(__imp__XamInputGetKeystrokeEx, rex::kernel::xam::XamInputGetKeystrokeEx_entry) +REX_EXPORT(__imp__XamUserGetDeviceContext, rex::kernel::xam::XamUserGetDeviceContext_entry) + +REX_EXPORT_STUB(__imp__XamInputControl); +REX_EXPORT_STUB(__imp__XamInputEnableAutobind); +REX_EXPORT_STUB(__imp__XamInputGetDeviceStats); +REX_EXPORT_STUB(__imp__XamInputGetFailedConnectionOrBind); +REX_EXPORT_STUB(__imp__XamInputGetKeyLocks); +REX_EXPORT_STUB(__imp__XamInputGetKeystrokeHud); +REX_EXPORT_STUB(__imp__XamInputGetKeystrokeHudEx); +REX_EXPORT_STUB(__imp__XamInputGetUserVibrationLevel); +REX_EXPORT_STUB(__imp__XamInputNonControllerGetRaw); +REX_EXPORT_STUB(__imp__XamInputNonControllerGetRawEx); +REX_EXPORT_STUB(__imp__XamInputNonControllerSetRaw); +REX_EXPORT_STUB(__imp__XamInputNonControllerSetRawEx); +REX_EXPORT_STUB(__imp__XamInputRawState); +REX_EXPORT_STUB(__imp__XamInputResetLayoutKeyboard); +REX_EXPORT_STUB(__imp__XamInputSendStayAliveRequest); +REX_EXPORT_STUB(__imp__XamInputSendXenonButtonPress); +REX_EXPORT_STUB(__imp__XamInputSetKeyLocks); +REX_EXPORT_STUB(__imp__XamInputSetKeyboardTranslationHud); +REX_EXPORT_STUB(__imp__XamInputSetLayoutKeyboard); +REX_EXPORT_STUB(__imp__XamInputSetMinMaxAuthDelay); +REX_EXPORT_STUB(__imp__XamInputSetTextMessengerIndicator); +REX_EXPORT_STUB(__imp__XamInputToggleKeyLocks); diff --git a/src/kernel/xam/xam_locale.cpp b/src/kernel/xam/xam_locale.cpp new file mode 100644 index 0000000..4496ac3 --- /dev/null +++ b/src/kernel/xam/xam_locale.cpp @@ -0,0 +1,431 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_UINT32(user_country, 103, "Kernel", "User's country ID"); + +// TODO(gibbed): put these forward decls in a header somewhere. + +namespace rex { +namespace kernel { +namespace xam { +uint32_t xeXGetGameRegion(); +} // namespace xam +} // namespace kernel +} // namespace rex + +namespace rex { +namespace kernel { +namespace xam { + +// Table lookups. + +uint8_t xeXamGetOnlineCountryFromLocale(uint8_t id) { + static uint8_t const table[] = { + 2, 6, 5, 8, 13, 16, 19, 20, 21, 23, 25, 32, 34, 24, 37, 39, 42, 46, 44, 50, 53, 56, + 71, 74, 76, 75, 82, 84, 91, 93, 109, 31, 90, 18, 101, 35, 103, 88, 236, 99, 4, 89, 45, 1, + }; +#pragma warning(suppress : 6385) + return id < rex::countof(table) ? table[id] : 0; +} + +const char16_t* xeXamGetOnlineCountryString(uint8_t id) { + static const char16_t* const table[] = { + u"ZZ", u"AE", u"AL", u"AM", u"AR", u"AT", u"AU", u"AZ", u"BE", u"BG", u"BH", + u"BN", u"BO", u"BR", u"BY", u"BZ", u"CA", nullptr, u"CH", u"CL", u"CN", u"CO", + u"CR", u"CZ", u"DE", u"DK", u"DO", u"DZ", u"EC", u"EE", u"EG", u"ES", u"FI", + u"FO", u"FR", u"GB", u"GE", u"GR", u"GT", u"HK", u"HN", u"HR", u"HU", u"ID", + u"IE", u"IL", u"IN", u"IQ", u"IR", u"IS", u"IT", u"JM", u"JO", u"JP", u"KE", + u"KG", u"KR", u"KW", u"KZ", u"LB", u"LI", u"LT", u"LU", u"LV", u"LY", u"MA", + u"MC", u"MK", u"MN", u"MO", u"MV", u"MX", u"MY", u"NI", u"NL", u"NO", u"NZ", + u"OM", u"PA", u"PE", u"PH", u"PK", u"PL", u"PR", u"PT", u"PY", u"QA", u"RO", + u"RU", u"SA", u"SE", u"SG", u"SI", u"SK", nullptr, u"SV", u"SY", u"TH", u"TN", + u"TR", u"TT", u"TW", u"UA", u"US", u"UY", u"UZ", u"VE", u"VN", u"YE", u"ZA", + u"ZW", u"AF", nullptr, u"AD", u"AO", u"AI", nullptr, u"AG", u"AW", u"BS", u"BD", + u"BB", u"BJ", u"BM", u"BT", u"BA", u"BW", u"BF", u"BI", u"KH", u"CM", u"CV", + u"KY", u"CF", u"TD", u"CX", u"CC", u"KM", u"CG", u"CD", u"CK", u"CI", u"CY", + u"DJ", u"DM", nullptr, u"GQ", u"ER", u"ET", u"FK", u"FJ", u"GF", u"PF", u"GA", + u"GM", u"GH", u"GI", u"GL", u"GD", u"GP", nullptr, u"GG", u"GN", u"GW", u"GY", + u"HT", u"JE", u"KI", u"LA", u"LS", u"LR", u"MG", u"MW", u"ML", u"MT", u"MH", + u"MQ", u"MR", u"MU", u"YT", u"FM", u"MD", u"ME", u"MS", u"MZ", u"MM", u"NA", + u"NR", u"NP", u"AN", u"NC", u"NE", u"NG", u"NU", u"NF", nullptr, u"PW", u"PS", + u"PG", u"PN", u"RE", u"RW", u"WS", u"SM", u"ST", u"SN", u"RS", u"SC", u"SL", + u"SB", u"SO", u"LK", u"SH", u"KN", u"LC", u"PM", u"VC", u"SR", u"SZ", u"TJ", + u"TZ", u"TL", u"TG", u"TK", u"TO", u"TM", u"TC", u"TV", u"UG", u"VU", u"VA", + nullptr, u"VG", u"WF", u"EH", u"ZM", u"ZZ", + }; +#pragma warning(suppress : 6385) + return id < rex::countof(table) ? table[id] : nullptr; +} + +const char16_t* xeXamGetCountryString(uint8_t id) { + static const char16_t* const table[] = { + u"ZZ", u"AE", u"AL", u"AM", u"AR", u"AT", u"AU", u"AZ", u"BE", u"BG", u"BH", u"BN", u"BO", + u"BR", u"BY", u"BZ", u"CA", nullptr, u"CH", u"CL", u"CN", u"CO", u"CR", u"CZ", u"DE", u"DK", + u"DO", u"DZ", u"EC", u"EE", u"EG", u"ES", u"FI", u"FO", u"FR", u"GB", u"GE", u"GR", u"GT", + u"HK", u"HN", u"HR", u"HU", u"ID", u"IE", u"IL", u"IN", u"IQ", u"IR", u"IS", u"IT", u"JM", + u"JO", u"JP", u"KE", u"KG", u"KR", u"KW", u"KZ", u"LB", u"LI", u"LT", u"LU", u"LV", u"LY", + u"MA", u"MC", u"MK", u"MN", u"MO", u"MV", u"MX", u"MY", u"NI", u"NL", u"NO", u"NZ", u"OM", + u"PA", u"PE", u"PH", u"PK", u"PL", u"PR", u"PT", u"PY", u"QA", u"RO", u"RU", u"SA", u"SE", + u"SG", u"SI", u"SK", nullptr, u"SV", u"SY", u"TH", u"TN", u"TR", u"TT", u"TW", u"UA", u"US", + u"UY", u"UZ", u"VE", u"VN", u"YE", u"ZA", u"ZW", u"ZZ", + }; +#pragma warning(suppress : 6385) + return id < rex::countof(table) ? table[id] : nullptr; +} + +const char16_t* xeXamGetLanguageString(uint8_t id) { + static const char16_t* const table[] = { + u"zz", u"en", u"ja", u"de", u"fr", u"es", u"it", u"ko", u"zh", + u"pt", nullptr, u"pl", u"ru", u"sv", u"tr", u"nb", u"nl", u"zh", + }; +#pragma warning(suppress : 6385) + return id < rex::countof(table) ? table[id] : nullptr; +} + +const char16_t* xeXamGetLocaleString(uint8_t id) { + static const char16_t* const table[] = { + u"ZZ", u"AU", u"AT", u"BE", u"BR", u"CA", u"CL", u"CN", u"CO", u"CZ", u"DK", + u"FI", u"FR", u"DE", u"GR", u"HK", u"HU", u"IN", u"IE", u"IT", u"JP", u"KR", + u"MX", u"NL", u"NZ", u"NO", u"PL", u"PT", u"SG", u"SK", u"ZA", u"ES", u"SE", + u"CH", u"TW", u"GB", u"US", u"RU", u"ZZ", u"TR", u"AR", u"SA", u"IL", u"AE", + }; +#pragma warning(suppress : 6385) + return id < rex::countof(table) ? table[id] : nullptr; +} + +uint8_t xeXamGetLocaleFromOnlineCountry(uint8_t id) { + static uint8_t const table[] = { + 0, 43, 0, 0, 40, 2, 1, 0, 3, 0, 0, 0, 0, 4, 0, 0, 5, 0, 33, 6, 7, 8, 0, 9, + 13, 10, 0, 0, 0, 0, 0, 31, 11, 0, 12, 35, 0, 14, 0, 15, 0, 0, 16, 0, 18, 42, 17, 0, + 0, 0, 19, 0, 0, 20, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, + 0, 0, 23, 25, 24, 0, 0, 0, 0, 0, 26, 0, 27, 0, 0, 0, 37, 41, 32, 28, 0, 29, 0, 0, + 0, 0, 0, 39, 0, 34, 0, 36, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, + }; +#pragma warning(suppress : 6385) + return id < rex::countof(table) ? table[id] : 0; +} + +uint8_t xeXamGetLanguageFromOnlineLanguage(uint8_t id) { + static uint8_t const table[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 17, 11, 12, 1, 1, 15, 16, 13, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + }; +#pragma warning(suppress : 6385) + return id < rex::countof(table) ? table[id] : 0; +} + +const char16_t* xeXamGetOnlineLanguageString(uint8_t id) { + static const char16_t* const table[] = { + u"zz", u"en", u"ja", u"de", u"fr", u"es", u"it", u"ko", u"zh", u"pt", u"zh", u"pl", u"ru", + u"da", u"fi", u"nb", u"nl", u"sv", u"cs", u"el", u"hu", u"sk", u"id", u"ms", u"ar", u"bg", + u"et", u"hr", u"he", u"is", u"kk", u"lt", u"lv", u"ro", u"sl", u"th", u"tr", u"uk", u"vi", + u"ps", u"sq", u"hy", u"bn", u"be", u"km", u"am", u"fo", u"ka", u"kl", u"sw", u"ky", u"lb", + u"mk", u"mt", u"mn", u"ne", u"ur", u"rw", u"wo", u"si", u"tk", + }; +#pragma warning(suppress : 6385) + return id < rex::countof(table) ? table[id] : nullptr; +} + +uint8_t xeXamGetCountryFromOnlineCountry(uint8_t id) { + static uint8_t const table[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, + }; +#pragma warning(suppress : 6385) + return id < rex::countof(table) ? table[id] : 0; +} + +uint8_t xeXamGetLocaleFromCountry(uint8_t id) { + static uint8_t const table[] = { + 0, 43, 0, 0, 40, 2, 1, 0, 3, 0, 0, 0, 0, 4, 0, 0, 5, 0, 33, 6, 7, 8, 0, + 9, 13, 10, 0, 0, 0, 0, 0, 31, 11, 0, 12, 35, 0, 14, 0, 15, 0, 0, 16, 0, 18, 42, + 17, 0, 0, 0, 19, 0, 0, 20, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 22, 0, 0, 23, 25, 24, 0, 0, 0, 0, 0, 26, 0, 27, 0, 0, 0, 37, 41, 32, 28, + 0, 29, 0, 0, 0, 0, 0, 39, 0, 34, 0, 36, 0, 0, 0, 0, 0, 30, 0, 38, + }; +#pragma warning(suppress : 6385) + return id < rex::countof(table) ? table[id] : 0; +} + +// Helpers. + +uint8_t xeXamGetLocaleEx(uint8_t max_country_id, uint8_t max_locale_id) { + // TODO(gibbed): rework when XConfig is cleanly implemented. + uint8_t country_id = static_cast(REXCVAR_GET(user_country)); + /*if (XSUCCEEDED(xboxkrnl::xeExGetXConfigSetting( + 3, 14, &country_id, sizeof(country_id), nullptr))) {*/ + if (country_id <= max_country_id) { + uint8_t locale_id = xeXamGetLocaleFromCountry(country_id); + if (locale_id <= max_locale_id) { + return locale_id; + } + } + /*}*/ + + // couldn't find locale, fallback from game region. + auto game_region = xeXGetGameRegion(); + auto region = static_cast((game_region & 0xFF00u) >> 8); + if (region == 1) { + return game_region == 0x101 ? 20 /* JP */ : 21 /* KR */; + } + return region == 2 ? 35 /* GB */ : 36 /* US */; +} + +uint8_t xeXamGetLocale() { + return xeXamGetLocaleEx(111, 43); +} + +// Exports. + +u32 XamGetLocale_entry() { + return static_cast(xeXamGetLocale()); +} + +u32 XamGetOnlineCountryFromLocale_entry(u32 id) { + return xeXamGetOnlineCountryFromLocale(id); +} + +u32 XamGetOnlineCountryString_entry(u32 id, u32 buffer_length, mapped_wstring buffer) { + if (buffer_length >= 0x80000000u) { + return X_E_INVALIDARG; + } + + auto str = xeXamGetOnlineCountryString(static_cast(id)); + if (!str) { + return X_E_NOTFOUND; + } + + const auto value = std::u16string(str); + if (value.size() + 1 > buffer_length) { + return X_HRESULT_FROM_WIN32(X_ERROR_INSUFFICIENT_BUFFER); + } + + memory::store_and_swap(buffer, value); + static_cast(buffer)[value.size()] = 0; + return X_E_SUCCESS; +} + +u32 XamGetCountryString_entry(u32 id, u32 buffer_length, mapped_wstring buffer) { + if (buffer_length >= 0x80000000u) { + return X_E_INVALIDARG; + } + + auto str = xeXamGetCountryString(static_cast(id)); + if (!str) { + return X_E_NOTFOUND; + } + + const auto value = std::u16string(str); + if (value.size() + 1 > buffer_length) { + return X_HRESULT_FROM_WIN32(X_ERROR_INSUFFICIENT_BUFFER); + } + + memory::store_and_swap(buffer, value); + static_cast(buffer)[value.size()] = 0; + return X_E_SUCCESS; +} + +u32 XamGetLanguageString_entry(u32 id, u32 buffer_length, mapped_wstring buffer) { + if (buffer_length >= 0x80000000u) { + return X_E_INVALIDARG; + } + + auto str = xeXamGetLanguageString(static_cast(id)); + if (!str) { + return X_E_NOTFOUND; + } + + const auto value = std::u16string(str); + if (value.size() + 1 > buffer_length) { + return X_HRESULT_FROM_WIN32(X_ERROR_INSUFFICIENT_BUFFER); + } + + memory::store_and_swap(buffer, value); + static_cast(buffer)[value.size()] = 0; + return X_E_SUCCESS; +} + +u32 XamGetLanguageLocaleString_entry(u32 language_id, u32 locale_id, u32 buffer_length, + mapped_wstring buffer) { + if (buffer_length >= 0x80000000u) { + return X_E_INVALIDARG; + } + + auto language_str = xeXamGetLanguageString(static_cast(language_id)); + if (!language_str) { + return X_E_NOTFOUND; + } + + auto locale_str = xeXamGetLocaleString(static_cast(locale_id)); + if (!locale_str) { + return X_E_NOTFOUND; + } + + const auto value = std::u16string(language_str) + u"-" + std::u16string(locale_str); + if (value.size() + 1 > buffer_length) { + return X_HRESULT_FROM_WIN32(X_ERROR_INSUFFICIENT_BUFFER); + } + + memory::store_and_swap(buffer, value); + static_cast(buffer)[value.size()] = 0; + return X_E_SUCCESS; +} + +u32 XamGetOnlineLanguageAndCountryString_entry(u32 language_id, u32 country_id, u32 buffer_length, + mapped_wstring buffer) { + if (buffer_length >= 0x80000000u) { + return X_E_INVALIDARG; + } + + auto language_str = xeXamGetOnlineLanguageString(static_cast(language_id)); + if (!language_str) { + return X_E_NOTFOUND; + } + + auto country_str = xeXamGetOnlineCountryString(static_cast(country_id)); + if (!country_str) { + return X_E_NOTFOUND; + } + + const auto value = std::u16string(language_str) + u"-" + std::u16string(country_str); + if (value.size() + 1 > buffer_length) { + return X_HRESULT_FROM_WIN32(X_ERROR_INSUFFICIENT_BUFFER); + } + + memory::store_and_swap(buffer, value); + static_cast(buffer)[value.size()] = 0; + return X_E_SUCCESS; +} + +u32 XamGetLocaleString_entry(u32 id, u32 buffer_length, mapped_wstring buffer) { + if (buffer_length >= 0x80000000u) { + return X_E_INVALIDARG; + } + + auto str = xeXamGetLocaleString(static_cast(id)); + if (!str) { + return X_E_NOTFOUND; + } + + const auto value = std::u16string(str); + if (value.size() + 1 > buffer_length) { + return X_HRESULT_FROM_WIN32(X_ERROR_INSUFFICIENT_BUFFER); + } + + memory::store_and_swap(buffer, value); + static_cast(buffer)[value.size()] = 0; + return X_E_SUCCESS; +} + +u32 XamGetLocaleFromOnlineCountry_entry(u32 id) { + return xeXamGetLocaleFromOnlineCountry(static_cast(id)); +} + +u32 XamGetLanguageFromOnlineLanguage_entry(u32 id) { + return xeXamGetLanguageFromOnlineLanguage(static_cast(id)); +} + +u32 XamGetOnlineLanguageString_entry(u32 id, u32 buffer_length, mapped_wstring buffer) { + if (buffer_length >= 0x80000000u) { + return X_E_INVALIDARG; + } + + auto str = xeXamGetOnlineLanguageString(static_cast(id)); + if (!str) { + return X_E_NOTFOUND; + } + + const auto value = std::u16string(str); + if (value.size() + 1 > buffer_length) { + return X_HRESULT_FROM_WIN32(X_ERROR_INSUFFICIENT_BUFFER); + } + + memory::store_and_swap(buffer, value); + static_cast(buffer)[value.size()] = 0; + return X_E_SUCCESS; +} + +u32 XamGetCountryFromOnlineCountry_entry(u32 id) { + return xeXamGetCountryFromOnlineCountry(static_cast(id)); +} + +u32 XamGetLocaleEx_entry(u32 max_country_id, u32 max_locale_id) { + return xeXamGetLocaleEx(static_cast(max_country_id), + static_cast(max_locale_id)); +} + +} // namespace xam +} // namespace kernel +} // namespace rex + +REX_EXPORT(__imp__XamGetLocale, rex::kernel::xam::XamGetLocale_entry) +REX_EXPORT(__imp__XamGetOnlineCountryFromLocale, + rex::kernel::xam::XamGetOnlineCountryFromLocale_entry) +REX_EXPORT(__imp__XamGetOnlineCountryString, rex::kernel::xam::XamGetOnlineCountryString_entry) +REX_EXPORT(__imp__XamGetCountryString, rex::kernel::xam::XamGetCountryString_entry) +REX_EXPORT(__imp__XamGetLanguageString, rex::kernel::xam::XamGetLanguageString_entry) +REX_EXPORT(__imp__XamGetLanguageLocaleString, rex::kernel::xam::XamGetLanguageLocaleString_entry) +REX_EXPORT(__imp__XamGetOnlineLanguageAndCountryString, + rex::kernel::xam::XamGetOnlineLanguageAndCountryString_entry) +REX_EXPORT(__imp__XamGetLocaleString, rex::kernel::xam::XamGetLocaleString_entry) +REX_EXPORT(__imp__XamGetLocaleFromOnlineCountry, + rex::kernel::xam::XamGetLocaleFromOnlineCountry_entry) +REX_EXPORT(__imp__XamGetLanguageFromOnlineLanguage, + rex::kernel::xam::XamGetLanguageFromOnlineLanguage_entry) +REX_EXPORT(__imp__XamGetOnlineLanguageString, rex::kernel::xam::XamGetOnlineLanguageString_entry) +REX_EXPORT(__imp__XamGetCountryFromOnlineCountry, + rex::kernel::xam::XamGetCountryFromOnlineCountry_entry) +REX_EXPORT(__imp__XamGetLocaleEx, rex::kernel::xam::XamGetLocaleEx_entry) + +REX_EXPORT_STUB(__imp__XamFormatCurrency); +REX_EXPORT_STUB(__imp__XamFormatMessage); +REX_EXPORT_STUB(__imp__XamFormatSystemDateString); +REX_EXPORT_STUB(__imp__XamGetCountry); +REX_EXPORT_STUB(__imp__XamGetCurrencyFormat); +REX_EXPORT_STUB(__imp__XamGetLanguage); +REX_EXPORT_STUB(__imp__XamGetLanguageLocaleFallbackString); +REX_EXPORT_STUB(__imp__XamGetLanguageTypeface); +REX_EXPORT_STUB(__imp__XamGetLanguageTypefacePatch); +REX_EXPORT_STUB(__imp__XamGetLocaleDateFormat); +REX_EXPORT_STUB(__imp__XamGetLocaleTimeFormat); +REX_EXPORT_STUB(__imp__XamGetOnlineCountryFeatures); +REX_EXPORT_STUB(__imp__XamGetOnlineLanguageAndCountry); +REX_EXPORT_STUB(__imp__XamGetStoreFront); +REX_EXPORT_STUB(__imp__XamUniSortCmpString); +REX_EXPORT_STUB(__imp__XamValidateCountry); diff --git a/src/kernel/xam/xam_misc.cpp b/src/kernel/xam/xam_misc.cpp new file mode 100644 index 0000000..ff6cb56 --- /dev/null +++ b/src/kernel/xam/xam_misc.cpp @@ -0,0 +1,1035 @@ +/** + * @file rexkernel/xam/xam_misc.cpp + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include +#include +#include + +// kinda gross but oh well +REX_EXPORT_STUB(__imp__CancelWaitableTimer); +REX_EXPORT_STUB(__imp__ControlPackGetCursorPosition); +REX_EXPORT_STUB(__imp__ControlPackGetHandleManager); +REX_EXPORT_STUB(__imp__ControlPackShouldShowCursor); +REX_EXPORT_STUB(__imp__ControlPackSideNavControlGetNuiHandle); +REX_EXPORT_STUB(__imp__ControlPackSimpleCursorGetRayFromScreenPosition); +REX_EXPORT_STUB(__imp__ControlpackNuiCursorSetTrackingId); +REX_EXPORT_STUB(__imp__CreateEventA); +REX_EXPORT_STUB(__imp__CreateMutexA); +REX_EXPORT_STUB(__imp__CreateThread); +REX_EXPORT_STUB(__imp__CreateWaitableTimerA); +REX_EXPORT_STUB(__imp__CurlCloseCacheEntry); +REX_EXPORT_STUB(__imp__CurlCreateCacheEntry); +REX_EXPORT_STUB(__imp__CurlEnumerateCacheEntry); +REX_EXPORT_STUB(__imp__CurlOpenCacheEntry); +REX_EXPORT_STUB(__imp__CurlOpenTitleBackingFile); +REX_EXPORT_STUB(__imp__CurlReadCacheEntryContent); +REX_EXPORT_STUB(__imp__CurlReadCacheEntryHeaders); +REX_EXPORT_STUB(__imp__CurlSetCacheEntryExpireTime); +REX_EXPORT_STUB(__imp__CurlWipeBackingFiles); +REX_EXPORT_STUB(__imp__CurlWriteCacheEntryContent); +REX_EXPORT_STUB(__imp__D3DDevice_Clear); +REX_EXPORT_STUB(__imp__D3DDevice_CreateIndexBuffer); +REX_EXPORT_STUB(__imp__D3DDevice_CreatePixelShader); +REX_EXPORT_STUB(__imp__D3DDevice_CreateTexture); +REX_EXPORT_STUB(__imp__D3DDevice_CreateVertexBuffer); +REX_EXPORT_STUB(__imp__D3DDevice_CreateVertexDeclaration); +REX_EXPORT_STUB(__imp__D3DDevice_CreateVertexShader); +REX_EXPORT_STUB(__imp__D3DDevice_DrawIndexedVertices); +REX_EXPORT_STUB(__imp__D3DDevice_DrawIndexedVerticesUP); +REX_EXPORT_STUB(__imp__D3DDevice_DrawVertices); +REX_EXPORT_STUB(__imp__D3DDevice_DrawVerticesUP); +REX_EXPORT_STUB(__imp__D3DDevice_GetDepthStencilSurface); +REX_EXPORT_STUB(__imp__D3DDevice_GetRenderState_AlphaBlendEnable); +REX_EXPORT_STUB(__imp__D3DDevice_GetRenderState_BlendOp); +REX_EXPORT_STUB(__imp__D3DDevice_GetRenderState_CullMode); +REX_EXPORT_STUB(__imp__D3DDevice_GetRenderState_DestBlendAlpha); +REX_EXPORT_STUB(__imp__D3DDevice_GetRenderState_ParameterCheck); +REX_EXPORT_STUB(__imp__D3DDevice_GetRenderState_SrcBlendAlpha); +REX_EXPORT_STUB(__imp__D3DDevice_GetRenderState_ViewportEnable); +REX_EXPORT_STUB(__imp__D3DDevice_GetRenderState_ZEnable); +REX_EXPORT_STUB(__imp__D3DDevice_GetRenderTarget); +REX_EXPORT_STUB(__imp__D3DDevice_GetViewport); +REX_EXPORT_STUB(__imp__D3DDevice_Release); +REX_EXPORT_STUB(__imp__D3DDevice_Resolve); +REX_EXPORT_STUB(__imp__D3DDevice_SetDepthStencilSurface); +REX_EXPORT_STUB(__imp__D3DDevice_SetIndices); +REX_EXPORT_STUB(__imp__D3DDevice_SetPixelShader); +REX_EXPORT_STUB(__imp__D3DDevice_SetPixelShaderConstantB); +REX_EXPORT_STUB(__imp__D3DDevice_SetPixelShaderConstantFN); +REX_EXPORT_STUB(__imp__D3DDevice_SetPixelShaderConstantF_ParameterCheck); +REX_EXPORT_STUB(__imp__D3DDevice_SetRenderState_AlphaBlendEnable); +REX_EXPORT_STUB(__imp__D3DDevice_SetRenderState_BlendOp); +REX_EXPORT_STUB(__imp__D3DDevice_SetRenderState_CullMode); +REX_EXPORT_STUB(__imp__D3DDevice_SetRenderState_DestBlendAlpha); +REX_EXPORT_STUB(__imp__D3DDevice_SetRenderState_ParameterCheck); +REX_EXPORT_STUB(__imp__D3DDevice_SetRenderState_SrcBlendAlpha); +REX_EXPORT_STUB(__imp__D3DDevice_SetRenderState_ViewportEnable); +REX_EXPORT_STUB(__imp__D3DDevice_SetRenderState_ZEnable); +REX_EXPORT_STUB(__imp__D3DDevice_SetRenderTarget); +REX_EXPORT_STUB(__imp__D3DDevice_SetSamplerState_AddressU); +REX_EXPORT_STUB(__imp__D3DDevice_SetSamplerState_AddressV); +REX_EXPORT_STUB(__imp__D3DDevice_SetSamplerState_MagFilter); +REX_EXPORT_STUB(__imp__D3DDevice_SetSamplerState_MinFilter); +REX_EXPORT_STUB(__imp__D3DDevice_SetSamplerState_ParameterCheck); +REX_EXPORT_STUB(__imp__D3DDevice_SetStreamSource); +REX_EXPORT_STUB(__imp__D3DDevice_SetTexture); +REX_EXPORT_STUB(__imp__D3DDevice_SetVertexDeclaration); +REX_EXPORT_STUB(__imp__D3DDevice_SetVertexShader); +REX_EXPORT_STUB(__imp__D3DDevice_SetVertexShaderConstantFN); +REX_EXPORT_STUB(__imp__D3DDevice_SetVertexShaderConstantF_ParameterCheck); +REX_EXPORT_STUB(__imp__D3DDevice_SetViewport); +REX_EXPORT_STUB(__imp__D3DIndexBuffer_Lock); +REX_EXPORT_STUB(__imp__D3DIndexBuffer_Unlock); +REX_EXPORT_STUB(__imp__D3DPixelShader_AddRef); +REX_EXPORT_STUB(__imp__D3DPixelShader_Release); +REX_EXPORT_STUB(__imp__D3DResource_AddRef); +REX_EXPORT_STUB(__imp__D3DResource_Release); +REX_EXPORT_STUB(__imp__D3DTexture_LockRect); +REX_EXPORT_STUB(__imp__D3DTexture_UnlockRect); +REX_EXPORT_STUB(__imp__D3DVertexBuffer_Lock); +REX_EXPORT_STUB(__imp__D3DVertexBuffer_Unlock); +REX_EXPORT_STUB(__imp__D3DVertexDeclaration_AddRef); +REX_EXPORT_STUB(__imp__D3DVertexDeclaration_Release); +REX_EXPORT_STUB(__imp__D3DVertexShader_AddRef); +REX_EXPORT_STUB(__imp__D3DVertexShader_Release); +REX_EXPORT_STUB(__imp__DebugBreak); +REX_EXPORT_STUB(__imp__DebugXamShowMessageBoxUI_Wait); +REX_EXPORT_STUB(__imp__Destroy); +REX_EXPORT_STUB(__imp__DuplicateHandle); +REX_EXPORT_STUB(__imp__EnumerateMediaObjects); +REX_EXPORT_STUB(__imp__EnumerateMediaObjects_); +REX_EXPORT_STUB(__imp__EnumerateMediaObjects_0); +REX_EXPORT_STUB(__imp__EnumerateMediaObjects_1); +REX_EXPORT_STUB(__imp__EnumerateMediaObjects_2); +REX_EXPORT_STUB(__imp__ExitThread); +REX_EXPORT_STUB(__imp__FileTimeToLocalFileTime); +REX_EXPORT_STUB(__imp__FileTimeToSystemTime); +REX_EXPORT_STUB(__imp__GamerCardCleanup); +REX_EXPORT_STUB(__imp__GamerCardRegisterControls); +REX_EXPORT_STUB(__imp__GamerCardStartup); +REX_EXPORT_STUB(__imp__GamerCardUnregisterControls); +REX_EXPORT_STUB(__imp__GetCodecVersion); +REX_EXPORT_STUB(__imp__GetCurrentThreadId); +REX_EXPORT_STUB(__imp__GetLastError); +REX_EXPORT_STUB(__imp__GetLocalTime); +REX_EXPORT_STUB(__imp__GetModuleHandleA); +REX_EXPORT_STUB(__imp__GetOverlappedResult); +REX_EXPORT_STUB(__imp__GetProcessHeap); +REX_EXPORT_STUB(__imp__GetSystemTime); +REX_EXPORT_STUB(__imp__GetSystemTimeAsFileTime); +REX_EXPORT_STUB(__imp__GetTickCount); +REX_EXPORT_STUB(__imp__GetTimeZoneInformation); +REX_EXPORT_STUB(__imp__InjectConnectionServerNotification); +REX_EXPORT_STUB(__imp__IsBadReadPtr); +REX_EXPORT_STUB(__imp__IsBadWritePtr); +REX_EXPORT_STUB(__imp__LocalAlloc); +REX_EXPORT_STUB(__imp__LocalFree); +REX_EXPORT_STUB(__imp__MultiByteToWideChar); +REX_EXPORT_STUB(__imp__OnReconnect); +REX_EXPORT_STUB(__imp__OpenMutexA); +REX_EXPORT_STUB(__imp__PIXAddCounter); +REX_EXPORT_STUB(__imp__PIXBeginCapture); +REX_EXPORT_STUB(__imp__PIXEndCapture); +REX_EXPORT_STUB(__imp__PIXGetGPUSlot); +REX_EXPORT_STUB(__imp__QueryPerformanceCounter); +REX_EXPORT_STUB(__imp__QueryPerformanceFrequency); +REX_EXPORT_STUB(__imp__RaiseException); +REX_EXPORT_STUB(__imp__Refresh); +REX_EXPORT_STUB(__imp__Refresh_); +REX_EXPORT_STUB(__imp__Refresh_0); +REX_EXPORT_STUB(__imp__Refresh_1); +REX_EXPORT_STUB(__imp__ReleaseMutex); +REX_EXPORT_STUB(__imp__ResetEvent); +REX_EXPORT_STUB(__imp__ResumeThread); +REX_EXPORT_STUB(__imp__RtlAllocateHeap); +REX_EXPORT_STUB(__imp__RtlAllocateHeapSlowly); +REX_EXPORT_STUB(__imp__RtlCompactHeap); +REX_EXPORT_STUB(__imp__RtlCreateHeap); +REX_EXPORT_STUB(__imp__RtlDebugCompactHeap); +REX_EXPORT_STUB(__imp__RtlDebugEntry); +REX_EXPORT_STUB(__imp__RtlDebugError); +REX_EXPORT_STUB(__imp__RtlDebugExit); +REX_EXPORT_STUB(__imp__RtlDebugPrint); +REX_EXPORT_STUB(__imp__RtlDebugSetLevel); +REX_EXPORT_STUB(__imp__RtlDebugWalkHeap); +REX_EXPORT_STUB(__imp__RtlDestroyHeap); +REX_EXPORT_STUB(__imp__RtlFindFirstFile); +REX_EXPORT_STUB(__imp__RtlFindNextFile); +REX_EXPORT_STUB(__imp__RtlFreeHeap); +REX_EXPORT_STUB(__imp__RtlFreeHeapSlowly); +REX_EXPORT_STUB(__imp__RtlGetAttributesOnHeapAlloc); +REX_EXPORT_STUB(__imp__RtlGetLastError); +REX_EXPORT_STUB(__imp__RtlGetModuleFileName); +REX_EXPORT_STUB(__imp__RtlLockHeap); +REX_EXPORT_STUB(__imp__RtlRandom); +REX_EXPORT_STUB(__imp__RtlReAllocateHeap); +REX_EXPORT_STUB(__imp__RtlRemoveDirectory); +REX_EXPORT_STUB(__imp__RtlSetAttributesOnHeapAlloc); +REX_EXPORT_STUB(__imp__RtlSetLastError); +REX_EXPORT_STUB(__imp__RtlSetLastNTError); +REX_EXPORT_STUB(__imp__RtlSizeHeap); +REX_EXPORT_STUB(__imp__RtlSleep); +REX_EXPORT_STUB(__imp__RtlUniform); +REX_EXPORT_STUB(__imp__RtlUnlockHeap); +REX_EXPORT_STUB(__imp__RtlValidateHeap); +REX_EXPORT_STUB(__imp__RtlWalkHeap); +REX_EXPORT_STUB(__imp__RtlZeroHeap); +REX_EXPORT_STUB(__imp__SetEvent); +REX_EXPORT_STUB(__imp__SetLastError); +REX_EXPORT_STUB(__imp__SetUnhandledExceptionFilter); +REX_EXPORT_STUB(__imp__SetWaitableTimer); +REX_EXPORT_STUB(__imp__Sleep); +REX_EXPORT_STUB(__imp__SleepEx); +REX_EXPORT_STUB(__imp__SystemTimeToFileTime); +REX_EXPORT_STUB(__imp__UnhandledExceptionFilter); +REX_EXPORT_STUB(__imp__UpnpAVServerSearchDestroy); +REX_EXPORT_STUB(__imp__UpnpAVServerSearchDoWork); +REX_EXPORT_STUB(__imp__UpnpAVServerSearchGetNextServer); +REX_EXPORT_STUB(__imp__UpnpAVServerSearchInitialize); +REX_EXPORT_STUB(__imp__UpnpAVServerSearchStart); +REX_EXPORT_STUB(__imp__WaitForSingleObject); +REX_EXPORT_STUB(__imp__WaitForSingleObjectEx); +REX_EXPORT_STUB(__imp__WideCharToMultiByte); +REX_EXPORT_STUB(__imp__XAutomationpBindController); +REX_EXPORT_STUB(__imp__XAutomationpInputPress); +REX_EXPORT_STUB(__imp__XAutomationpInputSetState); +REX_EXPORT_STUB(__imp__XAutomationpInputXenonButton); +REX_EXPORT_STUB(__imp__XAutomationpUnbindController); +REX_EXPORT_STUB(__imp__XCustomBroadcastActionEvent); +REX_EXPORT_STUB(__imp__XCustomBroadcastGamercardEvent); +REX_EXPORT_STUB(__imp__XCustomGetBannerImage); +REX_EXPORT_STUB(__imp__XCustomGetCurrentGamercard); +REX_EXPORT_STUB(__imp__XCustomGetLastActionPress); +REX_EXPORT_STUB(__imp__XCustomGetLastActionPressEx); +REX_EXPORT_STUB(__imp__XCustomSetAction); +REX_EXPORT_STUB(__imp__XCustomSetDynamicActions); +REX_EXPORT_STUB(__imp__XCustomUnregisterDynamicActions); +REX_EXPORT_STUB(__imp__XDebugError); +REX_EXPORT_STUB(__imp__XDebugWarning); +REX_EXPORT_STUB(__imp__XDebugWarning_); +REX_EXPORT_STUB(__imp__XFriendsCreateEnumerator); +REX_EXPORT_STUB(__imp__XGGetTextureDesc); +REX_EXPORT_STUB(__imp__XGOffsetResourceAddress); +REX_EXPORT_STUB(__imp__XGSetTextureHeader); +REX_EXPORT_STUB(__imp__XGSetTextureHeaderEx); +REX_EXPORT_STUB(__imp__XGetAudioFlags); +REX_EXPORT_STUB(__imp__XGetDisplaySize); +REX_EXPORT_STUB(__imp__XGetOverlappedExtendedError); +REX_EXPORT_STUB(__imp__XGetOverlappedResult); +REX_EXPORT_STUB(__imp__XGetSSLCertBypassEnabled); +REX_EXPORT_STUB(__imp__XMPRegisterCodec); +REX_EXPORT_STUB(__imp__XMemAlloc); +REX_EXPORT_STUB(__imp__XMemCpy); +REX_EXPORT_STUB(__imp__XMemCpyStreaming); +REX_EXPORT_STUB(__imp__XMemFree); +REX_EXPORT_STUB(__imp__XMemSet); +REX_EXPORT_STUB(__imp__XMemSize); +REX_EXPORT_STUB(__imp__XNetLogonClearTicketCaches); +REX_EXPORT_STUB(__imp__XNetLogonGetDnsString); +REX_EXPORT_STUB(__imp__XNetLogonGetExtendedStatus); +REX_EXPORT_STUB(__imp__XNetLogonGetFlowToken); +REX_EXPORT_STUB(__imp__XNetLogonGetLastUPnPStatus); +REX_EXPORT_STUB(__imp__XNetLogonGetLoggedOnUsers); +REX_EXPORT_STUB(__imp__XNetLogonGetMachineID); +REX_EXPORT_STUB(__imp__XNetLogonGetNatType); +REX_EXPORT_STUB(__imp__XNetLogonGetServiceInfo); +REX_EXPORT_STUB(__imp__XNetLogonGetServiceNetworkID); +REX_EXPORT_STUB(__imp__XNetLogonGetState); +REX_EXPORT_STUB(__imp__XNetLogonGetTicketOpt); +REX_EXPORT_STUB(__imp__XNetLogonGetTitleID); +REX_EXPORT_STUB(__imp__XNetLogonGetTitleVersion); +REX_EXPORT_STUB(__imp__XNetLogonGetUserPrivileges); +REX_EXPORT_STUB(__imp__XNetLogonInitOverrideInfo); +REX_EXPORT_STUB(__imp__XNetLogonSetConsoleCertificate); +REX_EXPORT_STUB(__imp__XNetLogonSetTicketOpt); +REX_EXPORT_STUB(__imp__XNetLogonSetTitleID); +REX_EXPORT_STUB(__imp__XNetLogonTaskClose); +REX_EXPORT_STUB(__imp__XNetLogonTaskContinue); +REX_EXPORT_STUB(__imp__XNetLogonTaskStart); +REX_EXPORT_STUB(__imp__XOnlinepFriendsAcceptRequest); +REX_EXPORT_STUB(__imp__XOnlinepFriendsRejectRequest); +REX_EXPORT_STUB(__imp__XOnlinepFriendsRemove); +REX_EXPORT_STUB(__imp__XOnlinepFriendsRequest); +REX_EXPORT_STUB(__imp__XRegisterThreadNotifyRoutine); +REX_EXPORT_STUB(__imp__XTLGetLanguageV2); +REX_EXPORT_STUB(__imp__XTLGetLocaleV1); +REX_EXPORT_STUB(__imp__XTestOnlineIsConnectedToLive); +REX_EXPORT_STUB(__imp__XUIElementPropVal_Clear); +REX_EXPORT_STUB(__imp__XUIElementPropVal_Construct); +REX_EXPORT_STUB(__imp__XUIElementPropVal_Destruct); +REX_EXPORT_STUB(__imp__XUIElementPropVal_SetBool); +REX_EXPORT_STUB(__imp__XUIElementPropVal_SetColorFromUint); +REX_EXPORT_STUB(__imp__XUIElementPropVal_SetFloat); +REX_EXPORT_STUB(__imp__XUIElementPropVal_SetInt); +REX_EXPORT_STUB(__imp__XUIElementPropVal_SetString); +REX_EXPORT_STUB(__imp__XUIElementPropVal_SetUint); +REX_EXPORT_STUB(__imp__XUITimeline_Run); +REX_EXPORT_STUB(__imp__XamAccountRecoveryGetProgress); +REX_EXPORT_STUB(__imp__XamAccountRecoveryGetSetTitleSyncTime); +REX_EXPORT_STUB(__imp__XamAccountRecoveryRecoverAllProfileData); +REX_EXPORT_STUB(__imp__XamAccountRecoveryRecoverTitle); +REX_EXPORT_STUB(__imp__XamActivateCounterMeasure); +REX_EXPORT_STUB(__imp__XamAllocDevkitHeapAvailable); +REX_EXPORT_STUB(__imp__XamAllocEx); +REX_EXPORT_STUB(__imp__XamAllocFreeIPTVHeap); +REX_EXPORT_STUB(__imp__XamAllocHeapFreeSpace); +REX_EXPORT_STUB(__imp__XamAllocMountIPTVHeap); +REX_EXPORT_STUB(__imp__XamAllocSize); +REX_EXPORT_STUB(__imp__XamAllocUnmountIPTVHeap); +REX_EXPORT_STUB(__imp__XamAppAllocateInterappWorkspace); +REX_EXPORT_STUB(__imp__XamAppAllocateInterappWorkspaceEx); +REX_EXPORT_STUB(__imp__XamAppFreeInterappWorkspace); +REX_EXPORT_STUB(__imp__XamAppGetInterappWorkspace); +REX_EXPORT_STUB(__imp__XamAppGetSessionId); +REX_EXPORT_STUB(__imp__XamAppLoad); +REX_EXPORT_STUB(__imp__XamAppLoadPass2SysApps); +REX_EXPORT_STUB(__imp__XamAppReinitialize); +REX_EXPORT_STUB(__imp__XamAppReportError); +REX_EXPORT_STUB(__imp__XamAppRequestLoad); +REX_EXPORT_STUB(__imp__XamAppRequestLoadEx); +REX_EXPORT_STUB(__imp__XamAppSetTestOption); +REX_EXPORT_STUB(__imp__XamAppUnloadSelf); +REX_EXPORT_STUB(__imp__XamAppUnloadStack); +REX_EXPORT_STUB(__imp__XamAppUnrequestLoad); +REX_EXPORT_STUB(__imp__XamAreMixedAccountsSignedIn); +REX_EXPORT_STUB(__imp__XamAskUserForCSVDrainagePermission); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadBindItems); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadCacheLegacyMappingInfo); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadClearItems); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadDoFail); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadGetActiveItem); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadGetForegroundPriority); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadGetItems); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadGetLegacyId); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadGetLegacyMappingInfo); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadGetMode); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadGetPollingActive); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadGetUnexpectedChangeCount); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadHistoryGetItem); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadIsEnabled); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadIsItemForThisConsole); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadItemAdd); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadItemGetHistoryStatus); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadItemGetHistoryStatusEx); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadItemGetStatus); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadItemGetStatusAsync); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadItemGetStatusEx); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadItemMakeFirst); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadItemModify); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadItemRemove); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadItemSetHistoryStatus); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadItemToContentData); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadNetworkStorageEnable); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadNetworkStorageGetProgress); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadNetworkStorageIsEnabled); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadNetworkStorageIsRunning); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadNetworkStorageOnContentChange); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadNetworkStorageRegisterChangeCallback); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadSelectDevice); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadSetForegroundPriority); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadSetMode); +REX_EXPORT_STUB(__imp__XamBackgroundDownloadSetPollingActive); +REX_EXPORT_STUB(__imp__XamBase64Decode); +REX_EXPORT_STUB(__imp__XamBeginDemand); +REX_EXPORT_STUB(__imp__XamBuildDynamicResourceLocator); +REX_EXPORT_STUB(__imp__XamCacheCloseFile); +REX_EXPORT_STUB(__imp__XamCacheDeleteFile); +REX_EXPORT_STUB(__imp__XamCacheDeleteFileByString); +REX_EXPORT_STUB(__imp__XamCacheFetchFile); +REX_EXPORT_STUB(__imp__XamCacheFetchFileByString); +REX_EXPORT_STUB(__imp__XamCacheIntegrityCheck); +REX_EXPORT_STUB(__imp__XamCacheOpenFile); +REX_EXPORT_STUB(__imp__XamCacheRenameFile); +REX_EXPORT_STUB(__imp__XamCacheReset); +REX_EXPORT_STUB(__imp__XamCacheStoreFile); +REX_EXPORT_STUB(__imp__XamCacheStoreFileByString); +REX_EXPORT_STUB(__imp__XamCertDecode); +REX_EXPORT_STUB(__imp__XamCertDecodeRsaPublicKey); +REX_EXPORT_STUB(__imp__XamCertGetSerialNumber); +REX_EXPORT_STUB(__imp__XamCertValidateStruct); +REX_EXPORT_STUB(__imp__XamClearTitle); +REX_EXPORT_STUB(__imp__XamCodeCoverageFileClose); +REX_EXPORT_STUB(__imp__XamCodeCoverageFileLseek); +REX_EXPORT_STUB(__imp__XamCodeCoverageFileOpen); +REX_EXPORT_STUB(__imp__XamCodeCoverageFileRead); +REX_EXPORT_STUB(__imp__XamCodeCoverageFileWrite); +REX_EXPORT_STUB(__imp__XamCompleteDemand); +REX_EXPORT_STUB(__imp__XamConvertEmoticons); +REX_EXPORT_STUB(__imp__XamCopyFile); +REX_EXPORT_STUB(__imp__XamCustomGetCurrentActions); +REX_EXPORT_STUB(__imp__XamD3DResourceAddRef); +REX_EXPORT_STUB(__imp__XamD3DResourceDescriptorAddRef); +REX_EXPORT_STUB(__imp__XamD3DResourceDescriptorCreate); +REX_EXPORT_STUB(__imp__XamD3DResourceDescriptorRelease); +REX_EXPORT_STUB(__imp__XamD3DResourceIsBusy); +REX_EXPORT_STUB(__imp__XamD3DResourceRelease); +REX_EXPORT_STUB(__imp__XamD3DResourceSet); +REX_EXPORT_STUB(__imp__XamDataCenterGetDhcpOptionResponseHostnameAndPort); +REX_EXPORT_STUB(__imp__XamDataCenterLog); +REX_EXPORT_STUB(__imp__XamDataCenterLogEvent); +REX_EXPORT_STUB(__imp__XamDataCenterShowForceSignInMessage); +REX_EXPORT_STUB(__imp__XamDbgSetBreakLevel); +REX_EXPORT_STUB(__imp__XamDbgSetOutputLevel); +REX_EXPORT_STUB(__imp__XamDeactivateCounterMeasure); +REX_EXPORT_STUB(__imp__XamDebugGetBackURI); +REX_EXPORT_STUB(__imp__XamDebugGetURISchemeCount); +REX_EXPORT_STUB(__imp__XamDebugGetURISchemeInfo); +REX_EXPORT_STUB(__imp__XamDecompressPNGToTexture); +REX_EXPORT_STUB(__imp__XamDeleteFile); +REX_EXPORT_STUB(__imp__XamDemand); +REX_EXPORT_STUB(__imp__XamDestroyGameTileCache); +REX_EXPORT_STUB(__imp__XamDevAuthSetFault); +REX_EXPORT_STUB(__imp__XamDevAuthSetFaultEx); +REX_EXPORT_STUB(__imp__XamDeviceRemap); +REX_EXPORT_STUB(__imp__XamDoesOmniNeedConfiguration); +REX_EXPORT_STUB(__imp__XamDownloadInSingleItemMode); +REX_EXPORT_STUB(__imp__XamDownloadMarketplaceStoresList); +REX_EXPORT_STUB(__imp__XamDownloadSingleItem); +REX_EXPORT_STUB(__imp__XamEnableOverdraw); +REX_EXPORT_STUB(__imp__XamEnableSystemAppInput); +REX_EXPORT_STUB(__imp__XamEtxFlushLogs); +REX_EXPORT_STUB(__imp__XamExecuteChallenge); +REX_EXPORT_STUB(__imp__XamExecutingOnBehalfOfTitle); +REX_EXPORT_STUB(__imp__XamFamilyAddParentalExemptionToList); +REX_EXPORT_STUB(__imp__XamFamilyGetMembers); +REX_EXPORT_STUB(__imp__XamFamilyIsParentalValidationRequired); +REX_EXPORT_STUB(__imp__XamFeatureEnableDisable); +REX_EXPORT_STUB(__imp__XamFeatureEnforceImageBudget); +REX_EXPORT_STUB(__imp__XamFeatureSetMask); +REX_EXPORT_STUB(__imp__XamFindHUDElementByXuiId); +REX_EXPORT_STUB(__imp__XamFindOrCreateInternalPassportAccount); +REX_EXPORT_STUB(__imp__XamFirstRunExperienceShouldRun); +REX_EXPORT_STUB(__imp__XamFitnessAddBodyProfileRecord); +REX_EXPORT_STUB(__imp__XamFitnessAddFitnessEvent); +REX_EXPORT_STUB(__imp__XamFitnessClearAll); +REX_EXPORT_STUB(__imp__XamFitnessClearBodyProfileRecords); +REX_EXPORT_STUB(__imp__XamFitnessContainsFitnessData); +REX_EXPORT_STUB(__imp__XamFitnessConvertByteMetToFloatMet); +REX_EXPORT_STUB(__imp__XamFitnessConvertFloatMetToByteMet); +REX_EXPORT_STUB(__imp__XamFitnessCreateFitnessEventEnumerator); +REX_EXPORT_STUB(__imp__XamFitnessGetAllBodyProfileRecords); +REX_EXPORT_STUB(__imp__XamFitnessGetAllTitleSummaries); +REX_EXPORT_STUB(__imp__XamFitnessGetCurrentBodyProfileRecord); +REX_EXPORT_STUB(__imp__XamFitnessGetOverallSummary); +REX_EXPORT_STUB(__imp__XamFitnessGetPrivacySettings); +REX_EXPORT_STUB(__imp__XamFitnessGetSuggestedPrivacySettings); +REX_EXPORT_STUB(__imp__XamFitnessGetSyncStatus); +REX_EXPORT_STUB(__imp__XamFitnessGetTitleSummaries); +REX_EXPORT_STUB(__imp__XamFitnessGetTitleSummary); +REX_EXPORT_STUB(__imp__XamFitnessInitialize); +REX_EXPORT_STUB(__imp__XamFitnessInitializeForOneUser); +REX_EXPORT_STUB(__imp__XamFitnessMsgTimeToSystemTime); +REX_EXPORT_STUB(__imp__XamFitnessSystemTimeToMsgTime); +REX_EXPORT_STUB(__imp__XamFitnessUnInitialize); +REX_EXPORT_STUB(__imp__XamFlushAgraTemperatureReport); +REX_EXPORT_STUB(__imp__XamFreeToken); +REX_EXPORT_STUB(__imp__XamGetActiveCounterMeasures); +REX_EXPORT_STUB(__imp__XamGetActiveDashAppInfo); +REX_EXPORT_STUB(__imp__XamGetAdaptersCollection); +REX_EXPORT_STUB(__imp__XamGetAppliesTo); +REX_EXPORT_STUB(__imp__XamGetCachedGamerTag); +REX_EXPORT_STUB(__imp__XamGetCachedGamerTagW); +REX_EXPORT_STUB(__imp__XamGetCachedTitleName); +REX_EXPORT_STUB(__imp__XamGetCachedTitleNameEx); +REX_EXPORT_STUB(__imp__XamGetClosedCaptioningSettings); +REX_EXPORT_STUB(__imp__XamGetClosedCaptioningState); +REX_EXPORT_STUB(__imp__XamGetConsoleFriendlyName); +REX_EXPORT_STUB(__imp__XamGetCurrentDemand); +REX_EXPORT_STUB(__imp__XamGetCurrentSystemOnlineManifestRevision); +REX_EXPORT_STUB(__imp__XamGetDashBackstackData); +REX_EXPORT_STUB(__imp__XamGetDashBackstackNodesCount); +REX_EXPORT_STUB(__imp__XamGetDashContext); +REX_EXPORT_STUB(__imp__XamGetDashContextEx); +REX_EXPORT_STUB(__imp__XamGetDefaultImage); +REX_EXPORT_STUB(__imp__XamGetDefaultSystemImage); +REX_EXPORT_STUB(__imp__XamGetDvrStorage); +REX_EXPORT_STUB(__imp__XamGetErrorStringFromWebService); +REX_EXPORT_STUB(__imp__XamGetGameRatings); +REX_EXPORT_STUB(__imp__XamGetGamerTileKeyFromGamertag); +REX_EXPORT_STUB(__imp__XamGetHUDElementByAutoId); +REX_EXPORT_STUB(__imp__XamGetHUDElementByPath); +REX_EXPORT_STUB(__imp__XamGetHudContext); +REX_EXPORT_STUB(__imp__XamGetLastActiveUserData); +REX_EXPORT_STUB(__imp__XamGetLiveHiveValueA); +REX_EXPORT_STUB(__imp__XamGetLiveHiveValueDuringLogonAttemptA); +REX_EXPORT_STUB(__imp__XamGetLiveHiveValueDuringLogonAttemptExA); +REX_EXPORT_STUB(__imp__XamGetLiveHiveValueW); +REX_EXPORT_STUB(__imp__XamGetModernPresence); +REX_EXPORT_STUB(__imp__XamGetModernPresenceImageUrl); +REX_EXPORT_STUB(__imp__XamGetModernPresenceWorkspaceSize); +REX_EXPORT_STUB(__imp__XamGetPasscodeKeyFromVirtualKey); +REX_EXPORT_STUB(__imp__XamGetRootObj); +REX_EXPORT_STUB(__imp__XamGetSTSTokenCache); +REX_EXPORT_STUB(__imp__XamGetSecurityViolationsDetected); +REX_EXPORT_STUB(__imp__XamGetServiceEndpoint); +REX_EXPORT_STUB(__imp__XamGetSingleModernPresence); +REX_EXPORT_STUB(__imp__XamGetStagingMode); +REX_EXPORT_STUB(__imp__XamGetTLSConfig); +REX_EXPORT_STUB(__imp__XamGetTitleGlobalStorageValue); +REX_EXPORT_STUB(__imp__XamGetToken); +REX_EXPORT_STUB(__imp__XamGetUserBalance); +REX_EXPORT_STUB(__imp__XamGetUserInMemoryWindowsLiveCreds); +REX_EXPORT_STUB(__imp__XamGetUserNeedTFA); +REX_EXPORT_STUB(__imp__XamGetUserPresetPresenceState); +REX_EXPORT_STUB(__imp__XamGetUserPresetWindowsLiveCreds); +REX_EXPORT_STUB(__imp__XamGetUserShowMessengerFriends); +REX_EXPORT_STUB(__imp__XamGetWCNConfigFile); +REX_EXPORT_STUB(__imp__XamGetXSTSTokenExpiryPeriodMS); +REX_EXPORT_STUB(__imp__XamGetXTweakManager); +REX_EXPORT_STUB(__imp__XamHudGetUserIndex); +REX_EXPORT_STUB(__imp__XamHudSetUserIndex); +REX_EXPORT_STUB(__imp__XamInactivityEnablePowerDown); +REX_EXPORT_STUB(__imp__XamInactivityGetInactivityInterruptTime); +REX_EXPORT_STUB(__imp__XamInactivityGetLastActivityTime); +REX_EXPORT_STUB(__imp__XamInactivitySetDetectionTaskPeriod); +REX_EXPORT_STUB(__imp__XamInactivitySetInactivityInterruptTime); +REX_EXPORT_STUB(__imp__XamInitializeGameTileCache); +REX_EXPORT_STUB(__imp__XamInstrumentationDebugConfig); +REX_EXPORT_STUB(__imp__XamInstrumentationGetSourceConfig); +REX_EXPORT_STUB(__imp__XamInstrumentationLogEvent); +REX_EXPORT_STUB(__imp__XamInstrumentationLogEventEx); +REX_EXPORT_STUB(__imp__XamIptvGetServiceName); +REX_EXPORT_STUB(__imp__XamIptvUninstall); +REX_EXPORT_STUB(__imp__XamIsAnySecurityViolationDetected); +REX_EXPORT_STUB(__imp__XamIsBackgroundSceneInTransition); +REX_EXPORT_STUB(__imp__XamIsCSVDrainageSupported); +REX_EXPORT_STUB(__imp__XamIsChildAccountSignedIn); +REX_EXPORT_STUB(__imp__XamIsCounterMeasureActivated); +REX_EXPORT_STUB(__imp__XamIsCurrentTitleDash); +REX_EXPORT_STUB(__imp__XamIsCurrentTitleDatacenterClient); +REX_EXPORT_STUB(__imp__XamIsCurrentTitleDatacenterDash); +REX_EXPORT_STUB(__imp__XamIsCurrentTitleIptv); +REX_EXPORT_STUB(__imp__XamIsDataCenterMode); +REX_EXPORT_STUB(__imp__XamIsDvrRecording); +REX_EXPORT_STUB(__imp__XamIsIptvEnabled); +REX_EXPORT_STUB(__imp__XamIsNatalPlaybackEnabled); +REX_EXPORT_STUB(__imp__XamIsNetworkCaptivePortal); +REX_EXPORT_STUB(__imp__XamIsNuiAutomationEnabled); +REX_EXPORT_STUB(__imp__XamIsOnPrivateNetwork); +REX_EXPORT_STUB(__imp__XamIsOptionalMediaUpdateInstalled); +REX_EXPORT_STUB(__imp__XamIsScreenSaverActive); +REX_EXPORT_STUB(__imp__XamIsSecurityViolationDetected); +REX_EXPORT_STUB(__imp__XamIsSystemExperienceTitleId); +REX_EXPORT_STUB(__imp__XamIsSystemTitleId); +REX_EXPORT_STUB(__imp__XamIsUserUsingMetricSystem); +REX_EXPORT_STUB(__imp__XamIsXbox1TitleId); +REX_EXPORT_STUB(__imp__XamLaunchAvatarEditor); +REX_EXPORT_STUB(__imp__XamLaunchURI); +REX_EXPORT_STUB(__imp__XamLiveBaseConfigureInMemoryMockResponse); +REX_EXPORT_STUB(__imp__XamLoadSysApp); +REX_EXPORT_STUB(__imp__XamLoaderGetClearCache); +REX_EXPORT_STUB(__imp__XamLoaderGetCurrentTitleD3DVersion); +REX_EXPORT_STUB(__imp__XamLoaderGetGameInfo); +REX_EXPORT_STUB(__imp__XamLoaderGetLogonTitle); +REX_EXPORT_STUB(__imp__XamLoaderGetMediaInfo); +REX_EXPORT_STUB(__imp__XamLoaderGetMediaInfoEx); +REX_EXPORT_STUB(__imp__XamLoaderGetPriorTitleId); +REX_EXPORT_STUB(__imp__XamLoaderGetState); +REX_EXPORT_STUB(__imp__XamLoaderIsKinectUIPreferredForLogonTitle); +REX_EXPORT_STUB(__imp__XamLoaderIsTitleTerminatePending); +REX_EXPORT_STUB(__imp__XamLoaderLaunchTitleEx); +REX_EXPORT_STUB(__imp__XamLoaderLaunchTitleForReason); +REX_EXPORT_STUB(__imp__XamLoaderLaunchTitleOnDvd); +REX_EXPORT_STUB(__imp__XamLoaderRebootToDash); +REX_EXPORT_STUB(__imp__XamLoaderRebootToServerDash); +REX_EXPORT_STUB(__imp__XamLoaderRegisterLaunchRequestCallback); +REX_EXPORT_STUB(__imp__XamLoaderSetClearCache); +REX_EXPORT_STUB(__imp__XamLoaderSetGameInfo); +REX_EXPORT_STUB(__imp__XamLoaderSetSpindleSpeed); +REX_EXPORT_STUB(__imp__XamLoaderShouldConfirmReboot); +REX_EXPORT_STUB(__imp__XamLocateTitle); +REX_EXPORT_STUB(__imp__XamLogLocalizationEtx); +REX_EXPORT_STUB(__imp__XamLookupCommonStringByIndex); +REX_EXPORT_STUB(__imp__XamLrcEncryptDecryptTitleMessage); +REX_EXPORT_STUB(__imp__XamLrcGetInput); +REX_EXPORT_STUB(__imp__XamLrcGetInputWithSeek); +REX_EXPORT_STUB(__imp__XamLrcKeyboardApplyTextChange); +REX_EXPORT_STUB(__imp__XamLrcKeyboardGetInput); +REX_EXPORT_STUB(__imp__XamLrcKeyboardGetRequiredBufferSize); +REX_EXPORT_STUB(__imp__XamLrcKeyboardRegister); +REX_EXPORT_STUB(__imp__XamLrcKeyboardUnregister); +REX_EXPORT_STUB(__imp__XamLrcKeyboardUpdateText); +REX_EXPORT_STUB(__imp__XamLrcKeyboardValidateTextChange); +REX_EXPORT_STUB(__imp__XamLrcLogError); +REX_EXPORT_STUB(__imp__XamLrcLogSessionSummary); +REX_EXPORT_STUB(__imp__XamLrcSetMediaState); +REX_EXPORT_STUB(__imp__XamLrcSetTitlePort); +REX_EXPORT_STUB(__imp__XamLrcVerifyClientId); +REX_EXPORT_STUB(__imp__XamMarkInternalAccountTrustedOnConsole); +REX_EXPORT_STUB(__imp__XamMarketplaceAcquireFreeContent); +REX_EXPORT_STUB(__imp__XamMediaVerificationClose); +REX_EXPORT_STUB(__imp__XamMediaVerificationCreate); +REX_EXPORT_STUB(__imp__XamMediaVerificationFailedBlocks); +REX_EXPORT_STUB(__imp__XamMediaVerificationInject); +REX_EXPORT_STUB(__imp__XamMediaVerificationVerify); +REX_EXPORT_STUB(__imp__XamMoveFile); +REX_EXPORT_STUB(__imp__XamNetworkStatusAddAddress); +REX_EXPORT_STUB(__imp__XamNetworkStatusGetInformation); +REX_EXPORT_STUB(__imp__XamNetworkStorageAppLauncherLaunchIfRunning); +REX_EXPORT_STUB(__imp__XamNetworkStorageCheckOutTitle); +REX_EXPORT_STUB(__imp__XamNetworkStorageCreateCacheOnDevice); +REX_EXPORT_STUB(__imp__XamNetworkStorageDeleteCacheOnDevice); +REX_EXPORT_STUB(__imp__XamNetworkStorageDeviceHasCacheFile); +REX_EXPORT_STUB(__imp__XamNetworkStorageGetBackingDevice); +REX_EXPORT_STUB(__imp__XamNetworkStorageGetLastSyncTime); +REX_EXPORT_STUB(__imp__XamNetworkStorageGetNetworkDevice); +REX_EXPORT_STUB(__imp__XamNetworkStorageGetStatus); +REX_EXPORT_STUB(__imp__XamNetworkStorageGetTitleProperties); +REX_EXPORT_STUB(__imp__XamNetworkStorageGetUserLastError); +REX_EXPORT_STUB(__imp__XamNetworkStorageGetUserNetworkSyncTime); +REX_EXPORT_STUB(__imp__XamNetworkStorageGetUserProperties); +REX_EXPORT_STUB(__imp__XamNetworkStorageHasUserEnabledStorage); +REX_EXPORT_STUB(__imp__XamNetworkStorageIsCheckingSyncStates); +REX_EXPORT_STUB(__imp__XamNetworkStorageIsEnabledInLiveHive); +REX_EXPORT_STUB(__imp__XamNetworkStorageIsSupportedContentType); +REX_EXPORT_STUB(__imp__XamNetworkStorageIsTitleExempt); +REX_EXPORT_STUB(__imp__XamNetworkStorageIsUserInSync); +REX_EXPORT_STUB(__imp__XamNetworkStorageLockFile); +REX_EXPORT_STUB(__imp__XamNetworkStorageOnSigninChanged); +REX_EXPORT_STUB(__imp__XamNetworkStorageOnUserSyncChange); +REX_EXPORT_STUB(__imp__XamNetworkStorageSetTestMock); +REX_EXPORT_STUB(__imp__XamNetworkStorageSetTitleProperties); +REX_EXPORT_STUB(__imp__XamNetworkStorageSetUserInSync); +REX_EXPORT_STUB(__imp__XamNetworkStorageShouldHideFromTitle); +REX_EXPORT_STUB(__imp__XamNetworkStorageSignInTestMock); +REX_EXPORT_STUB(__imp__XamNetworkStorageUserHasPrivilege); +REX_EXPORT_STUB(__imp__XamNetworkStorageUserNeedsToSync); +REX_EXPORT_STUB(__imp__XamOfflineTimerForceQuery); +REX_EXPORT_STUB(__imp__XamOfflineTimerGetContractData); +REX_EXPORT_STUB(__imp__XamOfflineTimerGetData); +REX_EXPORT_STUB(__imp__XamOfflineTimerGetTimeRemaining); +REX_EXPORT_STUB(__imp__XamOfflineTimerInitialize); +REX_EXPORT_STUB(__imp__XamOfflineTimerIsEnabled); +REX_EXPORT_STUB(__imp__XamOfflineTimerIsRunning); +REX_EXPORT_STUB(__imp__XamOfflineTimerResume); +REX_EXPORT_STUB(__imp__XamOfflineTimerSetData); +REX_EXPORT_STUB(__imp__XamOfflineTimerShutdown); +REX_EXPORT_STUB(__imp__XamOfflineTimerSuspend); +REX_EXPORT_STUB(__imp__XamPackageManagerDeleteExtendedPartition); +REX_EXPORT_STUB(__imp__XamPackageManagerFindPackageContainingIndexedXEX); +REX_EXPORT_STUB(__imp__XamPackageManagerGetAuthoritativeManifestVersion); +REX_EXPORT_STUB(__imp__XamPackageManagerGetExperienceMode); +REX_EXPORT_STUB(__imp__XamPackageManagerGetFeatureRequiresUpdateStrings); +REX_EXPORT_STUB(__imp__XamPackageManagerGetFilePathW); +REX_EXPORT_STUB(__imp__XamPackageManagerGetFileSize); +REX_EXPORT_STUB(__imp__XamPackageManagerHasExtendedPartition); +REX_EXPORT_STUB(__imp__XamPackageManagerReinitialize); +REX_EXPORT_STUB(__imp__XamPixSetDirtyCounters); +REX_EXPORT_STUB(__imp__XamPlayTimerForceNotification); +REX_EXPORT_STUB(__imp__XamPlayTimerFormatDurationString); +REX_EXPORT_STUB(__imp__XamPlayTimerGetData); +REX_EXPORT_STUB(__imp__XamPlayTimerGetNextResetDate); +REX_EXPORT_STUB(__imp__XamPlayTimerGetTimeRemaining); +REX_EXPORT_STUB(__imp__XamPlayTimerIsEnabled); +REX_EXPORT_STUB(__imp__XamPlayTimerIsRunning); +REX_EXPORT_STUB(__imp__XamPlayTimerRefreshResetDate); +REX_EXPORT_STUB(__imp__XamPlayTimerResume); +REX_EXPORT_STUB(__imp__XamPlayTimerSetData); +REX_EXPORT_STUB(__imp__XamPlayTimerSuspend); +REX_EXPORT_STUB(__imp__XamPlayTimerUpdateTimeRemaining); +REX_EXPORT_STUB(__imp__XamPlayToCancelGetRequest); +REX_EXPORT_STUB(__imp__XamPlayToCompleteRequest); +REX_EXPORT_STUB(__imp__XamPlayToGetRequest); +REX_EXPORT_STUB(__imp__XamPlayToRegister); +REX_EXPORT_STUB(__imp__XamPlayToReportPlaybackState); +REX_EXPORT_STUB(__imp__XamPlayToUnregister); +REX_EXPORT_STUB(__imp__XamPmdIdentify); +REX_EXPORT_STUB(__imp__XamPmdReadReport); +REX_EXPORT_STUB(__imp__XamPmdSendCommand); +REX_EXPORT_STUB(__imp__XamPngDecode); +REX_EXPORT_STUB(__imp__XamPngEncode); +REX_EXPORT_STUB(__imp__XamPngEncodeEx); +REX_EXPORT_STUB(__imp__XamPrepareGamerTiles); +REX_EXPORT_STUB(__imp__XamProfileClose); +REX_EXPORT_STUB(__imp__XamProfileControlPec); +REX_EXPORT_STUB(__imp__XamProfileCreate); +REX_EXPORT_STUB(__imp__XamProfileCreateEnumerator); +REX_EXPORT_STUB(__imp__XamProfileDelete); +REX_EXPORT_STUB(__imp__XamProfileEnumerate); +REX_EXPORT_STUB(__imp__XamProfileFindAccount); +REX_EXPORT_STUB(__imp__XamProfileGetCachedWindowsLiveEmail); +REX_EXPORT_STUB(__imp__XamProfileGetCreationStatus); +REX_EXPORT_STUB(__imp__XamProfileGetLastSync); +REX_EXPORT_STUB(__imp__XamProfileGetLiveLegalLocale); +REX_EXPORT_STUB(__imp__XamProfileGetLocalTitleCount); +REX_EXPORT_STUB(__imp__XamProfileIsSaveWindowsLiveCredsEnabled); +REX_EXPORT_STUB(__imp__XamProfileLoadAccountInfo); +REX_EXPORT_STUB(__imp__XamProfileLoadWindowsLiveCredentials); +REX_EXPORT_STUB(__imp__XamProfileOpen); +REX_EXPORT_STUB(__imp__XamProfileRecoverTitle); +REX_EXPORT_STUB(__imp__XamProfileRenameAccount); +REX_EXPORT_STUB(__imp__XamProfileSaveAccountInfo); +REX_EXPORT_STUB(__imp__XamProfileSaveWindowsLiveCredentials); +REX_EXPORT_STUB(__imp__XamProfileSetCachedWindowsLiveEmail); +REX_EXPORT_STUB(__imp__XamProfileSetSaveWindowsLiveCredsEnabled); +REX_EXPORT_STUB(__imp__XamPushBackURI); +REX_EXPORT_STUB(__imp__XamQueryLiveHiveA); +REX_EXPORT_STUB(__imp__XamQueryTimeZoneInformation); +REX_EXPORT_STUB(__imp__XamRamDriveCreate); +REX_EXPORT_STUB(__imp__XamRamDriveDestroy); +REX_EXPORT_STUB(__imp__XamReadBiometricData); +REX_EXPORT_STUB(__imp__XamReadGameTileImage); +REX_EXPORT_STUB(__imp__XamReadImage); +REX_EXPORT_STUB(__imp__XamReadString); +REX_EXPORT_STUB(__imp__XamReadStrings); +REX_EXPORT_STUB(__imp__XamReadTile); +REX_EXPORT_STUB(__imp__XamReadTileEx); +REX_EXPORT_STUB(__imp__XamReadTileToTextureEx); +REX_EXPORT_STUB(__imp__XamRegisterSMCNotification); +REX_EXPORT_STUB(__imp__XamRegisterScreenSaverCallback); +REX_EXPORT_STUB(__imp__XamRegisterSysApp); +REX_EXPORT_STUB(__imp__XamReleaseCameraPreviewStuff); +REX_EXPORT_STUB(__imp__XamReloadSysApp); +REX_EXPORT_STUB(__imp__XamReminderClearCache); +REX_EXPORT_STUB(__imp__XamReminderClearItems); +REX_EXPORT_STUB(__imp__XamReminderGetItems); +REX_EXPORT_STUB(__imp__XamReminderGetModifiedTime); +REX_EXPORT_STUB(__imp__XamReminderGetNextItem); +REX_EXPORT_STUB(__imp__XamReminderItemAdd); +REX_EXPORT_STUB(__imp__XamReminderItemRemove); +REX_EXPORT_STUB(__imp__XamRenderCameraPreviewStuff); +REX_EXPORT_STUB(__imp__XamReportKinectSettingsChangedEvent); +REX_EXPORT_STUB(__imp__XamReportTLSConnect); +REX_EXPORT_STUB(__imp__XamRequestToken); +REX_EXPORT_STUB(__imp__XamResolveURI); +REX_EXPORT_STUB(__imp__XamRestartTitleLoadAfterUpdate); +REX_EXPORT_STUB(__imp__XamResumeUpdaterUI); +REX_EXPORT_STUB(__imp__XamSendMessageToLoadedApps); +REX_EXPORT_STUB(__imp__XamSetActiveDashAppInfo); +REX_EXPORT_STUB(__imp__XamSetAutomation); +REX_EXPORT_STUB(__imp__XamSetClosedCaptioningState); +REX_EXPORT_STUB(__imp__XamSetConsoleFriendlyName); +REX_EXPORT_STUB(__imp__XamSetCountry); +REX_EXPORT_STUB(__imp__XamSetCurrentTitleDash); +REX_EXPORT_STUB(__imp__XamSetDashBackstackData); +REX_EXPORT_STUB(__imp__XamSetDashContext); +REX_EXPORT_STUB(__imp__XamSetDashContextEx); +REX_EXPORT_STUB(__imp__XamSetDvrStorage); +REX_EXPORT_STUB(__imp__XamSetHudContext); +REX_EXPORT_STUB(__imp__XamSetInactivityTime); +REX_EXPORT_STUB(__imp__XamSetInactivityTimeFromConfig); +REX_EXPORT_STUB(__imp__XamSetLastActiveUserData); +REX_EXPORT_STUB(__imp__XamSetPowerMode); +REX_EXPORT_STUB(__imp__XamSetProfileReadTestHook); +REX_EXPORT_STUB(__imp__XamSetSecurityViolationDetected); +REX_EXPORT_STUB(__imp__XamSetStagingMode); +REX_EXPORT_STUB(__imp__XamSetTimeZoneInformation); +REX_EXPORT_STUB(__imp__XamSetTitleGlobalStorageValue); +REX_EXPORT_STUB(__imp__XamSetUserNeedTFA); +REX_EXPORT_STUB(__imp__XamSetUserPresetPresenceState); +REX_EXPORT_STUB(__imp__XamSetUserPresetWindowsLiveCreds); +REX_EXPORT_STUB(__imp__XamSetUserShowMessengerFriends); +REX_EXPORT_STUB(__imp__XamSetupCameraPreviewStuff); +REX_EXPORT_STUB(__imp__XamSetupTexture); +REX_EXPORT_STUB(__imp__XamShouldThrottleAccountInfoCall); +REX_EXPORT_STUB(__imp__XamShutdown); +REX_EXPORT_STUB(__imp__XamSwapCancel); +REX_EXPORT_STUB(__imp__XamSystemUpdateInstallLocal); +REX_EXPORT_STUB(__imp__XamSystemUpdaterLogon); +REX_EXPORT_STUB(__imp__XamTerminateTitleForUpdate); +REX_EXPORT_STUB(__imp__XamTestShowNuiTroubleshooterUI); +REX_EXPORT_STUB(__imp__XamUIThreadDisableFontPatching); +REX_EXPORT_STUB(__imp__XamUIThreadEnableFontPatching); +REX_EXPORT_STUB(__imp__XamUnloadSysApp); +REX_EXPORT_STUB(__imp__XamUnregisterSysApp); +REX_EXPORT_STUB(__imp__XamUpdateAllocateExtenderBuffer); +REX_EXPORT_STUB(__imp__XamUpdateAttachExtenderInstance); +REX_EXPORT_STUB(__imp__XamUpdateChainPass3FromPass2); +REX_EXPORT_STUB(__imp__XamUpdateEtxLogUpdateTaskFailure); +REX_EXPORT_STUB(__imp__XamUpdateEtxLogUpdateTaskStart); +REX_EXPORT_STUB(__imp__XamUpdateEtxLogUpdateTaskSuccess); +REX_EXPORT_STUB(__imp__XamUpdateFinish); +REX_EXPORT_STUB(__imp__XamUpdateGetBaseSystemVersion); +REX_EXPORT_STUB(__imp__XamUpdateGetChainMarker); +REX_EXPORT_STUB(__imp__XamUpdateGetCurrentSystemVersion); +REX_EXPORT_STUB(__imp__XamUpdateGetData); +REX_EXPORT_STUB(__imp__XamUpdateGetExtenderInstance); +REX_EXPORT_STUB(__imp__XamUpdateGetProgress); +REX_EXPORT_STUB(__imp__XamUpdateGetTitleUpdateSizeThreshold); +REX_EXPORT_STUB(__imp__XamUpdateStart); +REX_EXPORT_STUB(__imp__XamVerifyXSignerSignature); +REX_EXPORT_STUB(__imp__XamWaitForNSAL); +REX_EXPORT_STUB(__imp__XamWebInstrumentationCreateReport); +REX_EXPORT_STUB(__imp__XamWebInstrumentationCreateSampledReport); +REX_EXPORT_STUB(__imp__XamWebInstrumentationDestroyReport); +REX_EXPORT_STUB(__imp__XamWebInstrumentationGetURL); +REX_EXPORT_STUB(__imp__XamWebInstrumentationGetURLEx); +REX_EXPORT_STUB(__imp__XamWebInstrumentationSendReport); +REX_EXPORT_STUB(__imp__XamWebInstrumentationSetUserVar); +REX_EXPORT_STUB(__imp__XamWebInstrumentationSetUserVarNoEscape); +REX_EXPORT_STUB(__imp__XamWriteBiometricData); +REX_EXPORT_STUB(__imp__XamWriteGamerTileEx); +REX_EXPORT_STUB(__imp__XamWriteTile); +REX_EXPORT_STUB(__imp__XamXStudioRequest); +REX_EXPORT_STUB(__imp__XamXgiBlobTrackerSetMockInfo); +REX_EXPORT_STUB(__imp__XamXlfsInitializeUploadQueue); +REX_EXPORT_STUB(__imp__XamXlfsInitializeUploadQueueWithTestHooks); +REX_EXPORT_STUB(__imp__XamXlfsMountUploadQueueInstance); +REX_EXPORT_STUB(__imp__XamXlfsNotifyContentDeletion); +REX_EXPORT_STUB(__imp__XamXlfsUninitializeUploadQueue); +REX_EXPORT_STUB(__imp__XamXlfsUnmountUploadQueueInstance); +REX_EXPORT_STUB(__imp__XamXtwManagerDecrement); +REX_EXPORT_STUB(__imp__XamXtwManagerDeleteDataFile); +REX_EXPORT_STUB(__imp__XamXtwManagerGetDataFilePath); +REX_EXPORT_STUB(__imp__XamXtwManagerGetId); +REX_EXPORT_STUB(__imp__XamXtwManagerGetValue); +REX_EXPORT_STUB(__imp__XamXtwManagerGetVariableCount); +REX_EXPORT_STUB(__imp__XamXtwManagerIncrement); +REX_EXPORT_STUB(__imp__XamXtwManagerLoad); +REX_EXPORT_STUB(__imp__XamXtwManagerResetAll); +REX_EXPORT_STUB(__imp__XamXtwManagerResetValue); +REX_EXPORT_STUB(__imp__XamXtwManagerSave); +REX_EXPORT_STUB(__imp__XamXtwManagerSetValue); +REX_EXPORT_STUB(__imp__XampCallXAccountTransitionStoredValuePointsToCurrency); +REX_EXPORT_STUB(__imp__XampDemandUpdateCheckOnlineManifestChanged); +REX_EXPORT_STUB(__imp__XampDemandUpdateGetAttributes); +REX_EXPORT_STUB(__imp__XampDemandUpdateGetExtendedAttributes); +REX_EXPORT_STUB(__imp__XampDemandUpdateGetInstance); +REX_EXPORT_STUB(__imp__XampDemandUpdateGetManifestLocalPath); +REX_EXPORT_STUB(__imp__XampDemandUpdateIsRefreshTestFlagSet); +REX_EXPORT_STUB(__imp__XampDemandUpdateRefreshManifest); +REX_EXPORT_STUB(__imp__XampDemandUpdateRefreshManifestDuringLogon); +REX_EXPORT_STUB(__imp__XampDemandUpdateRunCacheCleaner); +REX_EXPORT_STUB(__imp__XampDemandUpdateSetRefreshTestFlags); +REX_EXPORT_STUB(__imp__XampFitnessLetFireAndForgetsCatchUpInternal); +REX_EXPORT_STUB(__imp__XampHeapGetCount); +REX_EXPORT_STUB(__imp__XampHeapGetInfo); +REX_EXPORT_STUB(__imp__XampKioskIsSimulationMode); +REX_EXPORT_STUB(__imp__XampKioskSetTestMock); +REX_EXPORT_STUB(__imp__XampSetMockCallXAccountTransitionStoredValuePointsToCurrency); +REX_EXPORT_STUB(__imp__XampSetOmnitureCallbackFunction); +REX_EXPORT_STUB(__imp__XampSetSamplingRandomValue); +REX_EXPORT_STUB(__imp__XampSystemInput); +REX_EXPORT_STUB(__imp__XampWebInstrumentationSetProfileCounts); +REX_EXPORT_STUB(__imp__XampXAuthGetTitleBuffer); +REX_EXPORT_STUB(__imp__XampXAuthIsLocalSocketAllowed); +REX_EXPORT_STUB(__imp__XampXAuthShutdown); +REX_EXPORT_STUB(__imp__XampXAuthStartup); +REX_EXPORT_STUB(__imp__XapiDirectoryInformationToFindData); +REX_EXPORT_STUB(__imp__XapiFormatObjectAttributes); +REX_EXPORT_STUB(__imp__XapiFormatTimeOut); +REX_EXPORT_STUB(__imp__XapipCreateThread); +REX_EXPORT_STUB(__imp__XapipGetLocale); +REX_EXPORT_STUB(__imp__XdfCacheItem); +REX_EXPORT_STUB(__imp__XdfCancelRequest); +REX_EXPORT_STUB(__imp__XdfGetExpectedDownloadSize); +REX_EXPORT_STUB(__imp__XdfGetItem); +REX_EXPORT_STUB(__imp__XdfInitialize); +REX_EXPORT_STUB(__imp__XdfLaunchNewImageFromCache); +REX_EXPORT_STUB(__imp__XdfLoadXex); +REX_EXPORT_STUB(__imp__XdfLoadXexFromCache); +REX_EXPORT_STUB(__imp__XdfResumeDelayedItem); +REX_EXPORT_STUB(__imp__XdfShutdown); +REX_EXPORT_STUB(__imp__XnpGetXwppMemoryLogSnapshot); +REX_EXPORT_STUB(__imp__XnpGetXwppRuntimeFilter); +REX_EXPORT_STUB(__imp__XuiAlloc); +REX_EXPORT_STUB(__imp__XuiAnimRun); +REX_EXPORT_STUB(__imp__XuiApplyLocale); +REX_EXPORT_STUB(__imp__XuiAttachTextureBrush); +REX_EXPORT_STUB(__imp__XuiBroadcastMessage); +REX_EXPORT_STUB(__imp__XuiBrushGetTexture); +REX_EXPORT_STUB(__imp__XuiBubbleMessage); +REX_EXPORT_STUB(__imp__XuiClassDerivesFrom); +REX_EXPORT_STUB(__imp__XuiControlAttachVisual); +REX_EXPORT_STUB(__imp__XuiControlGetItemAssociation); +REX_EXPORT_STUB(__imp__XuiControlGetNavigation); +REX_EXPORT_STUB(__imp__XuiControlGetVisual); +REX_EXPORT_STUB(__imp__XuiControlIsBackButton); +REX_EXPORT_STUB(__imp__XuiControlIsNavButton); +REX_EXPORT_STUB(__imp__XuiControlPlayOptionalVisual); +REX_EXPORT_STUB(__imp__XuiControlSetItemAssociation); +REX_EXPORT_STUB(__imp__XuiControlWantsUnfocusedInput); +REX_EXPORT_STUB(__imp__XuiCopyString); +REX_EXPORT_STUB(__imp__XuiCreateObject); +REX_EXPORT_STUB(__imp__XuiCreateSolidBrush); +REX_EXPORT_STUB(__imp__XuiCreateTextureBrush); +REX_EXPORT_STUB(__imp__XuiDefault_EmptyString); +REX_EXPORT_STUB(__imp__XuiDefault_False); +REX_EXPORT_STUB(__imp__XuiDefault_IntegerZero); +REX_EXPORT_STUB(__imp__XuiDefault_True); +REX_EXPORT_STUB(__imp__XuiDestroyBrush); +REX_EXPORT_STUB(__imp__XuiDestroyObject); +REX_EXPORT_STUB(__imp__XuiDrawShape); +REX_EXPORT_STUB(__imp__XuiDynamicCast); +REX_EXPORT_STUB(__imp__XuiEditGetTextLimit); +REX_EXPORT_STUB(__imp__XuiEditSetTextFormatInfo); +REX_EXPORT_STUB(__imp__XuiEditSetTextLimit); +REX_EXPORT_STUB(__imp__XuiElementAddChild); +REX_EXPORT_STUB(__imp__XuiElementBeginRender); +REX_EXPORT_STUB(__imp__XuiElementDisallowRecursiveTimelineControl); +REX_EXPORT_STUB(__imp__XuiElementDiscardResources); +REX_EXPORT_STUB(__imp__XuiElementEnableInput); +REX_EXPORT_STUB(__imp__XuiElementEndRender); +REX_EXPORT_STUB(__imp__XuiElementFindNamedFrame); +REX_EXPORT_STUB(__imp__XuiElementGetChildById); +REX_EXPORT_STUB(__imp__XuiElementGetDescendantById); +REX_EXPORT_STUB(__imp__XuiElementGetFirstChild); +REX_EXPORT_STUB(__imp__XuiElementGetFocus); +REX_EXPORT_STUB(__imp__XuiElementGetFocusUser); +REX_EXPORT_STUB(__imp__XuiElementGetFullXForm); +REX_EXPORT_STUB(__imp__XuiElementGetId); +REX_EXPORT_STUB(__imp__XuiElementGetLastChild); +REX_EXPORT_STUB(__imp__XuiElementGetNext); +REX_EXPORT_STUB(__imp__XuiElementGetOpacity); +REX_EXPORT_STUB(__imp__XuiElementGetParent); +REX_EXPORT_STUB(__imp__XuiElementGetPivot); +REX_EXPORT_STUB(__imp__XuiElementGetPosition); +REX_EXPORT_STUB(__imp__XuiElementGetPrev); +REX_EXPORT_STUB(__imp__XuiElementGetScale); +REX_EXPORT_STUB(__imp__XuiElementGetScreenPositionCenter); +REX_EXPORT_STUB(__imp__XuiElementGetTimeline); +REX_EXPORT_STUB(__imp__XuiElementGetUserData); +REX_EXPORT_STUB(__imp__XuiElementGetUserFocus); +REX_EXPORT_STUB(__imp__XuiElementGetXForm); +REX_EXPORT_STUB(__imp__XuiElementHasFocus); +REX_EXPORT_STUB(__imp__XuiElementInitFocus); +REX_EXPORT_STUB(__imp__XuiElementInitUserFocus); +REX_EXPORT_STUB(__imp__XuiElementInputEnabled); +REX_EXPORT_STUB(__imp__XuiElementInsertChild); +REX_EXPORT_STUB(__imp__XuiElementIsDescendant); +REX_EXPORT_STUB(__imp__XuiElementLayoutTree); +REX_EXPORT_STUB(__imp__XuiElementPlayNamedFrames); +REX_EXPORT_STUB(__imp__XuiElementPlayTimeline); +REX_EXPORT_STUB(__imp__XuiElementRenderChildren); +REX_EXPORT_STUB(__imp__XuiElementSetBounds); +REX_EXPORT_STUB(__imp__XuiElementSetFocus); +REX_EXPORT_STUB(__imp__XuiElementSetHittable); +REX_EXPORT_STUB(__imp__XuiElementSetOpacity); +REX_EXPORT_STUB(__imp__XuiElementSetPivot); +REX_EXPORT_STUB(__imp__XuiElementSetPosition); +REX_EXPORT_STUB(__imp__XuiElementSetRotation); +REX_EXPORT_STUB(__imp__XuiElementSetScale); +REX_EXPORT_STUB(__imp__XuiElementSetUserData); +REX_EXPORT_STUB(__imp__XuiElementSetUserFocus); +REX_EXPORT_STUB(__imp__XuiElementTreeGetFocus); +REX_EXPORT_STUB(__imp__XuiElementTreeHasFocus); +REX_EXPORT_STUB(__imp__XuiElementUnlink); +REX_EXPORT_STUB(__imp__XuiFigureClose); +REX_EXPORT_STUB(__imp__XuiFigureGetShape); +REX_EXPORT_STUB(__imp__XuiFigureSetFill); +REX_EXPORT_STUB(__imp__XuiFigureSetShape); +REX_EXPORT_STUB(__imp__XuiFigureSetTexture); +REX_EXPORT_STUB(__imp__XuiFillRect); +REX_EXPORT_STUB(__imp__XuiFindClass); +REX_EXPORT_STUB(__imp__XuiFree); +REX_EXPORT_STUB(__imp__XuiFreeStringTable); +REX_EXPORT_STUB(__imp__XuiFreeUnusedTextures); +REX_EXPORT_STUB(__imp__XuiFreeVisuals); +REX_EXPORT_STUB(__imp__XuiGetBaseClass); +REX_EXPORT_STUB(__imp__XuiGetBaseObject); +REX_EXPORT_STUB(__imp__XuiGetClass); +REX_EXPORT_STUB(__imp__XuiGetObjectClass); +REX_EXPORT_STUB(__imp__XuiGetOuter); +REX_EXPORT_STUB(__imp__XuiHandleIsValid); +REX_EXPORT_STUB(__imp__XuiImageElementGetImagePath); +REX_EXPORT_STUB(__imp__XuiImageElementSetImagePath); +REX_EXPORT_STUB(__imp__XuiInit); +REX_EXPORT_STUB(__imp__XuiIsInstanceOf); +REX_EXPORT_STUB(__imp__XuiKillTimer); +REX_EXPORT_STUB(__imp__XuiListEnableItemOverride); +REX_EXPORT_STUB(__imp__XuiListGetDefaultItemSize); +REX_EXPORT_STUB(__imp__XuiLoadFromBinary); +REX_EXPORT_STUB(__imp__XuiLoadStringTableFromFile); +REX_EXPORT_STUB(__imp__XuiLoadVisualFromBinary); +REX_EXPORT_STUB(__imp__XuiLookupStringTable); +REX_EXPORT_STUB(__imp__XuiLookupStringTableByIndex); +REX_EXPORT_STUB(__imp__XuiMatrixMultiply); +REX_EXPORT_STUB(__imp__XuiNavButtonGetPressPath); +REX_EXPORT_STUB(__imp__XuiObjectFromHandle); +REX_EXPORT_STUB(__imp__XuiObjectGetProperty); +REX_EXPORT_STUB(__imp__XuiObjectGetPropertyDef); +REX_EXPORT_STUB(__imp__XuiObjectGetPropertyId); +REX_EXPORT_STUB(__imp__XuiObjectSetProperty); +REX_EXPORT_STUB(__imp__XuiPNGTextureLoader); +REX_EXPORT_STUB(__imp__XuiProcessInput); +REX_EXPORT_STUB(__imp__XuiProgressBarGetRange); +REX_EXPORT_STUB(__imp__XuiProgressBarGetValue); +REX_EXPORT_STUB(__imp__XuiProgressBarSetRange); +REX_EXPORT_STUB(__imp__XuiProgressBarSetValue); +REX_EXPORT_STUB(__imp__XuiRealloc); +REX_EXPORT_STUB(__imp__XuiRegisterClass); +REX_EXPORT_STUB(__imp__XuiRenderBegin); +REX_EXPORT_STUB(__imp__XuiRenderCreateDC); +REX_EXPORT_STUB(__imp__XuiRenderDCDeviceChanged); +REX_EXPORT_STUB(__imp__XuiRenderDestroyDC); +REX_EXPORT_STUB(__imp__XuiRenderEnd); +REX_EXPORT_STUB(__imp__XuiRenderGetBackBufferSize); +REX_EXPORT_STUB(__imp__XuiRenderGetColorSpace); +REX_EXPORT_STUB(__imp__XuiRenderGetDevice); +REX_EXPORT_STUB(__imp__XuiRenderGetViewTransform); +REX_EXPORT_STUB(__imp__XuiRenderGetXuiDevice); +REX_EXPORT_STUB(__imp__XuiRenderInit); +REX_EXPORT_STUB(__imp__XuiRenderInitShared); +REX_EXPORT_STUB(__imp__XuiRenderPresent); +REX_EXPORT_STUB(__imp__XuiRenderRestoreState); +REX_EXPORT_STUB(__imp__XuiRenderSetViewTransform); +REX_EXPORT_STUB(__imp__XuiRenderUninit); +REX_EXPORT_STUB(__imp__XuiResourceClose); +REX_EXPORT_STUB(__imp__XuiResourceComposeLocator); +REX_EXPORT_STUB(__imp__XuiResourceGetBuffer); +REX_EXPORT_STUB(__imp__XuiResourceGetPackageEntryCount); +REX_EXPORT_STUB(__imp__XuiResourceGetPackageEntryInfo); +REX_EXPORT_STUB(__imp__XuiResourceGetTotalSize); +REX_EXPORT_STUB(__imp__XuiResourceLoadAll); +REX_EXPORT_STUB(__imp__XuiResourceLocatorIsAbsolute); +REX_EXPORT_STUB(__imp__XuiResourceOpen); +REX_EXPORT_STUB(__imp__XuiResourceOpenAndVerifyNoLoc); +REX_EXPORT_STUB(__imp__XuiResourceOpenNoLoc); +REX_EXPORT_STUB(__imp__XuiResourceOpenPackage); +REX_EXPORT_STUB(__imp__XuiResourceRead); +REX_EXPORT_STUB(__imp__XuiResourceReleasePackage); +REX_EXPORT_STUB(__imp__XuiResourceSeek); +REX_EXPORT_STUB(__imp__XuiSceneCreate); +REX_EXPORT_STUB(__imp__XuiSceneEnableTransitionDependency); +REX_EXPORT_STUB(__imp__XuiSceneInterruptTransitions); +REX_EXPORT_STUB(__imp__XuiSceneIsInTransition); +REX_EXPORT_STUB(__imp__XuiSceneNavigateBack); +REX_EXPORT_STUB(__imp__XuiSceneNavigateBackToFirst); +REX_EXPORT_STUB(__imp__XuiSceneNavigateFirst); +REX_EXPORT_STUB(__imp__XuiSceneNavigateForward); +REX_EXPORT_STUB(__imp__XuiScenePlayBackFromTransition); +REX_EXPORT_STUB(__imp__XuiScenePlayBackToTransition); +REX_EXPORT_STUB(__imp__XuiScenePlayFromTransition); +REX_EXPORT_STUB(__imp__XuiScenePlayToTransition); +REX_EXPORT_STUB(__imp__XuiSelectBrush); +REX_EXPORT_STUB(__imp__XuiSelectBrushEx); +REX_EXPORT_STUB(__imp__XuiSendMessage); +REX_EXPORT_STUB(__imp__XuiSetLocale); +REX_EXPORT_STUB(__imp__XuiSetMessageFilter); +REX_EXPORT_STUB(__imp__XuiSetTimer); +REX_EXPORT_STUB(__imp__XuiSliderGetRange); +REX_EXPORT_STUB(__imp__XuiSliderGetStep); +REX_EXPORT_STUB(__imp__XuiSliderGetValue); +REX_EXPORT_STUB(__imp__XuiSliderSetRange); +REX_EXPORT_STUB(__imp__XuiSliderSetStep); +REX_EXPORT_STUB(__imp__XuiSliderSetValue); +REX_EXPORT_STUB(__imp__XuiTabSceneGetCount); +REX_EXPORT_STUB(__imp__XuiTabSceneGetCurrentTab); +REX_EXPORT_STUB(__imp__XuiTabSceneGoto); +REX_EXPORT_STUB(__imp__XuiTextElementGetText); +REX_EXPORT_STUB(__imp__XuiTextElementMeasureText); +REX_EXPORT_STUB(__imp__XuiTextElementSetText); +REX_EXPORT_STUB(__imp__XuiTimersRun); +REX_EXPORT_STUB(__imp__XuiUninit); +REX_EXPORT_STUB(__imp__XuiUnregisterClass); +REX_EXPORT_STUB(__imp__XuiVec2TransformCoord); +REX_EXPORT_STUB(__imp__XuiVisualCreateInstance); +REX_EXPORT_STUB(__imp__XuiVisualGetBasePath); +REX_EXPORT_STUB(__imp__XuiVisualSetBasePath); +REX_EXPORT_STUB(__imp__lstrcatA); +REX_EXPORT_STUB(__imp__lstrcatW); +REX_EXPORT_STUB(__imp__lstrcpyA); +REX_EXPORT_STUB(__imp__lstrcpyW); +REX_EXPORT_STUB(__imp__lstrcpynA); +REX_EXPORT_STUB(__imp__lstrcpynW); +REX_EXPORT_STUB(__imp__lstrlenA); +REX_EXPORT_STUB(__imp__lstrlenW); +REX_EXPORT_STUB(__imp__wsprintfA); +REX_EXPORT_STUB(__imp__wsprintfW); diff --git a/src/kernel/xam/xam_module.cpp b/src/kernel/xam/xam_module.cpp new file mode 100644 index 0000000..6bad7c7 --- /dev/null +++ b/src/kernel/xam/xam_module.cpp @@ -0,0 +1,74 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2019 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include +#include + +namespace rex { +namespace kernel { +namespace xam { +using namespace rex::system; +using namespace rex::system::xam; + +std::atomic xam_dialogs_shown_ = {0}; + +bool xeXamIsUIActive() { + return xam_dialogs_shown_ > 0; +} + +XamModule::XamModule(Runtime* emulator, KernelState* kernel_state) + : KernelModule(kernel_state, "xe:\\xam.xex"), loader_data_() { + RegisterExportTable(export_resolver_); + + // Register all exported functions. + // #define XE_MODULE_EXPORT_GROUP(m, n) \ +// Register##n##Exports(export_resolver_, kernel_state_); + // #include + // #undef XE_MODULE_EXPORT_GROUP +} + +std::vector xam_exports(4096); + +rex::runtime::Export* RegisterExport_xam(rex::runtime::Export* export_entry) { + assert_true(export_entry->ordinal < xam_exports.size()); + xam_exports[export_entry->ordinal] = export_entry; + return export_entry; +} + +void XamModule::RegisterExportTable(rex::runtime::ExportResolver* export_resolver) { + assert_not_null(export_resolver); + +// Build the export table used for resolution. +#include "../export_table_pre.inc" + static rex::runtime::Export xam_export_table[] = { +#include "export_table.inc" + }; +#include "../export_table_post.inc" + for (size_t i = 0; i < rex::countof(xam_export_table); ++i) { + auto& export_entry = xam_export_table[i]; + assert_true(export_entry.ordinal < xam_exports.size()); + if (!xam_exports[export_entry.ordinal]) { + xam_exports[export_entry.ordinal] = &export_entry; + } + } + export_resolver->RegisterTable("xam.xex", &xam_exports); +} + +XamModule::~XamModule() {} + +} // namespace xam +} // namespace kernel +} // namespace rex diff --git a/src/kernel/xam/xam_msg.cpp b/src/kernel/xam/xam_msg.cpp new file mode 100644 index 0000000..704eb0c --- /dev/null +++ b/src/kernel/xam/xam_msg.cpp @@ -0,0 +1,142 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex { +namespace kernel { +namespace xam { +using namespace rex::system; +using namespace rex::system::xam; + +u32 XMsgInProcessCall_entry(u32 app, u32 message, u32 arg1, u32 arg2) { + auto result = REX_KERNEL_STATE()->app_manager()->DispatchMessageSync(app, message, arg1, arg2); + if (result == X_ERROR_NOT_FOUND) { + REXKRNL_ERROR("XMsgInProcessCall: app {:08X} undefined", app); + } + return result; +} + +u32 XMsgSystemProcessCall_entry(u32 app, u32 message, u32 buffer, u32 buffer_length) { + auto result = + REX_KERNEL_STATE()->app_manager()->DispatchMessageAsync(app, message, buffer, buffer_length); + if (result == X_ERROR_NOT_FOUND) { + REXKRNL_ERROR("XMsgSystemProcessCall: app {:08X} undefined", app); + } + return result; +} + +struct XMSGSTARTIOREQUEST_UNKNOWNARG { + be unk_0; + be unk_1; +}; + +X_HRESULT xeXMsgStartIORequestEx(uint32_t app, uint32_t message, uint32_t overlapped_ptr, + uint32_t buffer_ptr, uint32_t buffer_length, + XMSGSTARTIOREQUEST_UNKNOWNARG* unknown) { + auto result = REX_KERNEL_STATE()->app_manager()->DispatchMessageAsync(app, message, buffer_ptr, + buffer_length); + if (result == X_E_NOTFOUND) { + REXKRNL_ERROR("XMsgStartIORequestEx: app {:08X} undefined", app); + result = X_E_INVALIDARG; + XThread::SetLastError(X_ERROR_NOT_FOUND); + } + if (overlapped_ptr) { + REX_KERNEL_STATE()->CompleteOverlappedImmediate(overlapped_ptr, result); + result = X_ERROR_IO_PENDING; + } + if (result == X_ERROR_SUCCESS || result == X_ERROR_IO_PENDING) { + XThread::SetLastError(0); + } + return result; +} + +u32 XMsgStartIORequestEx_entry(u32 app, u32 message, ppc_ptr_t overlapped_ptr, + u32 buffer_ptr, u32 buffer_length, + ppc_ptr_t unknown_ptr) { + return xeXMsgStartIORequestEx(app, message, overlapped_ptr.guest_address(), buffer_ptr, + buffer_length, unknown_ptr); +} + +u32 XMsgStartIORequest_entry(u32 app, u32 message, ppc_ptr_t overlapped_ptr, + u32 buffer_ptr, u32 buffer_length) { + return xeXMsgStartIORequestEx(app, message, overlapped_ptr.guest_address(), buffer_ptr, + buffer_length, nullptr); +} + +u32 XMsgCancelIORequest_entry(ppc_ptr_t overlapped_ptr, u32 wait) { + X_HANDLE event_handle = XOverlappedGetEvent(overlapped_ptr); + if (event_handle && wait) { + auto ev = REX_KERNEL_OBJECTS()->LookupObject(event_handle); + if (ev) { + ev->Wait(0, 0, true, nullptr); + } + } + + return 0; +} + +u32 XMsgCompleteIORequest_entry(ppc_ptr_t overlapped_ptr, u32 result, + u32 extended_error, u32 length) { + REX_KERNEL_STATE()->CompleteOverlappedImmediateEx(overlapped_ptr.guest_address(), result, + extended_error, length); + return X_ERROR_SUCCESS; +} + +u32 XamGetOverlappedResult_entry(ppc_ptr_t overlapped_ptr, mapped_u32 length_ptr, + u32 unknown) { + uint32_t result; + if (overlapped_ptr->result != X_ERROR_IO_PENDING) { + result = overlapped_ptr->result; + } else if (!overlapped_ptr->event) { + result = X_ERROR_IO_INCOMPLETE; + } else { + auto ev = REX_KERNEL_OBJECTS()->LookupObject(overlapped_ptr->event); + result = ev->Wait(3, 1, 0, nullptr); + if (XSUCCEEDED(result)) { + result = overlapped_ptr->result; + } else { + result = xboxkrnl::xeRtlNtStatusToDosError(result); + } + } + if (XSUCCEEDED(result) && length_ptr) { + *length_ptr = overlapped_ptr->length; + } + return result; +} + +} // namespace xam +} // namespace kernel +} // namespace rex + +REX_EXPORT(__imp__XMsgInProcessCall, rex::kernel::xam::XMsgInProcessCall_entry) +REX_EXPORT(__imp__XMsgSystemProcessCall, rex::kernel::xam::XMsgSystemProcessCall_entry) +REX_EXPORT(__imp__XMsgStartIORequestEx, rex::kernel::xam::XMsgStartIORequestEx_entry) +REX_EXPORT(__imp__XMsgStartIORequest, rex::kernel::xam::XMsgStartIORequest_entry) +REX_EXPORT(__imp__XMsgCancelIORequest, rex::kernel::xam::XMsgCancelIORequest_entry) +REX_EXPORT(__imp__XMsgCompleteIORequest, rex::kernel::xam::XMsgCompleteIORequest_entry) +REX_EXPORT(__imp__XamGetOverlappedResult, rex::kernel::xam::XamGetOverlappedResult_entry) + +REX_EXPORT_STUB(__imp__XMsgAcquireAsyncMessageFromOverlapped); +REX_EXPORT_STUB(__imp__XMsgProcessRequest); +REX_EXPORT_STUB(__imp__XMsgReleaseAsyncMessageToOverlapped); diff --git a/src/kernel/xam/xam_net.cpp b/src/kernel/xam/xam_net.cpp new file mode 100644 index 0000000..12cec94 --- /dev/null +++ b/src/kernel/xam/xam_net.cpp @@ -0,0 +1,1098 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if REX_PLATFORM_WIN32 +// NOTE: must be included last as it expects windows.h to already be included. +#define _WINSOCK_DEPRECATED_NO_WARNINGS // inet_addr +#include // NOLINT(build/include_order) +#elif REX_PLATFORM_LINUX +#include +#include +#include +#include +#endif + +namespace rex { +namespace kernel { +namespace xam { +using namespace rex::system; +using namespace rex::system::xam; + +// https://github.com/G91/TitanOffLine/blob/1e692d9bb9dfac386d08045ccdadf4ae3227bb5e/xkelib/xam/xamNet.h +enum { + XNCALLER_INVALID = 0x0, + XNCALLER_TITLE = 0x1, + XNCALLER_SYSAPP = 0x2, + XNCALLER_XBDM = 0x3, + XNCALLER_TEST = 0x4, + NUM_XNCALLER_TYPES = 0x4, +}; + +// https://github.com/pmrowla/hl2sdk-csgo/blob/master/common/xbox/xboxstubs.h +typedef struct { + // FYI: IN_ADDR should be in network-byte order. + in_addr ina; // IP address (zero if not static/DHCP) + in_addr inaOnline; // Online IP address (zero if not online) + rex::be wPortOnline; // Online port + uint8_t abEnet[6]; // Ethernet MAC address + uint8_t abOnline[20]; // Online identification +} XNADDR; + +typedef struct { + rex::be status; + rex::be cina; + in_addr aina[8]; +} XNDNS; + +typedef struct { + uint8_t flags; + uint8_t reserved; + rex::be probes_xmit; + rex::be probes_recv; + rex::be data_len; + rex::be data_ptr; + rex::be rtt_min_in_msecs; + rex::be rtt_med_in_msecs; + rex::be up_bits_per_sec; + rex::be down_bits_per_sec; +} XNQOSINFO; + +typedef struct { + rex::be count; + rex::be count_pending; + XNQOSINFO info[1]; +} XNQOS; + +struct Xsockaddr_t { + rex::be sa_family; + char sa_data[14]; +}; + +struct X_WSADATA { + rex::be version; + rex::be version_high; + char description[256 + 1]; + char system_status[128 + 1]; + rex::be max_sockets; + rex::be max_udpdg; + rex::be vendor_info_ptr; +}; + +struct XWSABUF { + rex::be len; + rex::be buf_ptr; +}; + +struct XWSAOVERLAPPED { + rex::be internal; + rex::be internal_high; + union { + struct { + rex::be low; + rex::be high; + } offset; // must be named to avoid GCC error + rex::be pointer; + }; + rex::be event_handle; +}; + +void LoadSockaddr(const uint8_t* ptr, sockaddr* out_addr) { + out_addr->sa_family = memory::load_and_swap(ptr + 0); + switch (out_addr->sa_family) { + case AF_INET: { + auto in_addr = reinterpret_cast(out_addr); + in_addr->sin_port = memory::load_and_swap(ptr + 2); + // Maybe? Depends on type. + in_addr->sin_addr.s_addr = *(uint32_t*)(ptr + 4); + break; + } + default: + assert_unhandled_case(out_addr->sa_family); + break; + } +} + +void StoreSockaddr(const sockaddr& addr, uint8_t* ptr) { + switch (addr.sa_family) { + case AF_UNSPEC: + std::memset(ptr, 0, sizeof(addr)); + break; + case AF_INET: { + auto& in_addr = reinterpret_cast(addr); + memory::store_and_swap(ptr + 0, in_addr.sin_family); + memory::store_and_swap(ptr + 2, in_addr.sin_port); + // Maybe? Depends on type. + memory::store_and_swap(ptr + 4, in_addr.sin_addr.s_addr); + break; + } + default: + assert_unhandled_case(addr.sa_family); + break; + } +} + +// https://github.com/joolswills/mameox/blob/master/MAMEoX/Sources/xbox_Network.cpp#L136 +struct XNetStartupParams { + uint8_t cfgSizeOfStruct; + uint8_t cfgFlags; + uint8_t cfgSockMaxDgramSockets; + uint8_t cfgSockMaxStreamSockets; + uint8_t cfgSockDefaultRecvBufsizeInK; + uint8_t cfgSockDefaultSendBufsizeInK; + uint8_t cfgKeyRegMax; + uint8_t cfgSecRegMax; + uint8_t cfgQosDataLimitDiv4; + uint8_t cfgQosProbeTimeoutInSeconds; + uint8_t cfgQosProbeRetries; + uint8_t cfgQosSrvMaxSimultaneousResponses; + uint8_t cfgQosPairWaitTimeInSeconds; +}; + +XNetStartupParams xnet_startup_params = {}; + +u32 NetDll_XNetStartup_entry(u32 caller, ppc_ptr_t params) { + if (params) { + assert_true(params->cfgSizeOfStruct == sizeof(XNetStartupParams)); + std::memcpy(&xnet_startup_params, params, sizeof(XNetStartupParams)); + } + + auto xam = REX_KERNEL_STATE()->GetKernelModule("xam.xex"); + + /* + if (!xam->xnet()) { + auto xnet = new XNet(REX_KERNEL_STATE()); + xnet->Initialize(); + + xam->set_xnet(xnet); + } + */ + + return 0; +} + +u32 NetDll_XNetCleanup_entry(u32 caller, mapped_void params) { + auto xam = REX_KERNEL_STATE()->GetKernelModule("xam.xex"); + // auto xnet = xam->xnet(); + // xam->set_xnet(nullptr); + + // TODO: Shut down and delete. + // delete xnet; + + return 0; +} + +u32 NetDll_XNetGetOpt_entry(u32 one, u32 option_id, mapped_void buffer_ptr, + mapped_u32 buffer_size) { + assert_true(one == 1); + switch (option_id) { + case 1: + if (*buffer_size < sizeof(XNetStartupParams)) { + *buffer_size = sizeof(XNetStartupParams); + return 0x2738; // WSAEMSGSIZE + } + std::memcpy(buffer_ptr, &xnet_startup_params, sizeof(XNetStartupParams)); + return 0; + default: + REXKRNL_ERROR("NetDll_XNetGetOpt: option {} unimplemented", option_id); + return 0x2726; // WSAEINVAL + } +} + +u32 NetDll_XNetRandom_entry(u32 caller, mapped_void buffer_ptr, u32 length) { + // For now, constant values. + // This makes replicating things easier. + std::memset(buffer_ptr, 0xBB, length); + + return 0; +} + +u32 NetDll_WSAStartup_entry(u32 caller, u16 version, ppc_ptr_t data_ptr) { +// TODO(benvanik): abstraction layer needed. +#if REX_PLATFORM_WIN32 + WSADATA wsaData; + ZeroMemory(&wsaData, sizeof(WSADATA)); + int ret = WSAStartup(version, &wsaData); + + auto data_out = REX_KERNEL_MEMORY()->TranslateVirtual(data_ptr.guest_address()); + + if (data_ptr) { + data_ptr->version = wsaData.wVersion; + data_ptr->version_high = wsaData.wHighVersion; + std::memcpy(&data_ptr->description, wsaData.szDescription, 0x100); + std::memcpy(&data_ptr->system_status, wsaData.szSystemStatus, 0x80); + data_ptr->max_sockets = wsaData.iMaxSockets; + data_ptr->max_udpdg = wsaData.iMaxUdpDg; + + // Some games (5841099F) want this value round-tripped - they'll compare if + // it changes and bugcheck if it does. + uint32_t vendor_ptr = memory::load_and_swap(data_out + 0x190); + memory::store_and_swap(data_out + 0x190, vendor_ptr); + } +#else + int ret = 0; + if (data_ptr) { + // Guess these values! + data_ptr->version = version; + data_ptr->description[0] = '\0'; + data_ptr->system_status[0] = '\0'; + data_ptr->max_sockets = 100; + data_ptr->max_udpdg = 1024; + } +#endif + + // DEBUG + /* + auto xam = REX_KERNEL_STATE()->GetKernelModule("xam.xex"); + if (!xam->xnet()) { + auto xnet = new XNet(REX_KERNEL_STATE()); + xnet->Initialize(); + + xam->set_xnet(xnet); + } + */ + + return ret; +} + +u32 NetDll_WSACleanup_entry(u32 caller) { + // This does nothing. Xenia needs WSA running. + return 0; +} + +u32 NetDll_WSAGetLastError_entry() { + return XThread::GetLastError(); +} + +u32 NetDll_WSARecvFrom_entry(u32 caller, u32 socket, ppc_ptr_t buffers_ptr, + u32 buffer_count, mapped_u32 num_bytes_recv, mapped_u32 flags_ptr, + ppc_ptr_t from_addr, + ppc_ptr_t overlapped_ptr, + mapped_void completion_routine_ptr) { + if (overlapped_ptr) { + // auto evt = REX_KERNEL_OBJECTS()->LookupObject( + // overlapped_ptr->event_handle); + + // if (evt) { + // //evt->Set(0, false); + //} + } + + // we're not going to be receiving packets any time soon + // return error so we don't wait on that - Cancerous + return -1; +} + +// If the socket is a VDP socket, buffer 0 is the game data length, and buffer 1 +// is the unencrypted game data. +u32 NetDll_WSASendTo_entry(u32 caller, u32 socket_handle, ppc_ptr_t buffers, + u32 num_buffers, mapped_u32 num_bytes_sent, u32 flags, + ppc_ptr_t to_ptr, u32 to_len, + ppc_ptr_t overlapped, mapped_void completion_routine) { + assert(!overlapped); + assert(!completion_routine); + + auto socket = REX_KERNEL_OBJECTS()->LookupObject(socket_handle); + if (!socket) { + // WSAENOTSOCK + XThread::SetLastError(0x2736); + return -1; + } + + // Our sockets implementation doesn't support multiple buffers, so we need + // to combine the buffers the game has given us! + std::vector combined_buffer_mem; + uint32_t combined_buffer_size = 0; + uint32_t combined_buffer_offset = 0; + for (uint32_t i = 0; i < num_buffers; i++) { + combined_buffer_size += buffers[i].len; + combined_buffer_mem.resize(combined_buffer_size); + uint8_t* combined_buffer = combined_buffer_mem.data(); + + std::memcpy(combined_buffer + combined_buffer_offset, + REX_KERNEL_MEMORY()->TranslateVirtual(buffers[i].buf_ptr), buffers[i].len); + combined_buffer_offset += buffers[i].len; + } + + N_XSOCKADDR_IN native_to(to_ptr); + socket->SendTo(combined_buffer_mem.data(), combined_buffer_size, flags, &native_to, to_len); + + // TODO: Instantly complete overlapped + + return 0; +} + +u32 NetDll_WSAWaitForMultipleEvents_entry(u32 num_events, mapped_u32 events, u32 wait_all, + u32 timeout, u32 alertable) { + if (num_events > 64) { + XThread::SetLastError(87); // ERROR_INVALID_PARAMETER + return ~0u; + } + + uint64_t timeout_wait = (uint64_t)timeout; + + X_STATUS result = 0; + do { + result = xboxkrnl::xeNtWaitForMultipleObjectsEx(num_events, events, wait_all, 1, alertable, + timeout != -1 ? &timeout_wait : nullptr); + } while (result == X_STATUS_ALERTED); + + if (XFAILED(result)) { + uint32_t error = xboxkrnl::xeRtlNtStatusToDosError(result); + XThread::SetLastError(error); + return ~0u; + } + return 0; +} + +u32 NetDll_WSACreateEvent_entry() { + XEvent* ev = new XEvent(REX_KERNEL_STATE()); + ev->Initialize(true, false); + return ev->handle(); +} + +u32 NetDll_WSACloseEvent_entry(u32 event_handle) { + X_STATUS result = REX_KERNEL_OBJECTS()->ReleaseHandle(event_handle); + if (XFAILED(result)) { + uint32_t error = xboxkrnl::xeRtlNtStatusToDosError(result); + XThread::SetLastError(error); + return 0; + } + return 1; +} + +u32 NetDll_WSAResetEvent_entry(u32 event_handle) { + X_STATUS result = xboxkrnl::xeNtClearEvent(event_handle); + if (XFAILED(result)) { + uint32_t error = xboxkrnl::xeRtlNtStatusToDosError(result); + XThread::SetLastError(error); + return 0; + } + return 1; +} + +u32 NetDll_WSASetEvent_entry(u32 event_handle) { + X_STATUS result = xboxkrnl::xeNtSetEvent(event_handle, nullptr); + if (XFAILED(result)) { + uint32_t error = xboxkrnl::xeRtlNtStatusToDosError(result); + XThread::SetLastError(error); + return 0; + } + return 1; +} + +struct XnAddrStatus { + // Address acquisition is not yet complete + static const uint32_t XNET_GET_XNADDR_PENDING = 0x00000000; + // XNet is uninitialized or no debugger found + static const uint32_t XNET_GET_XNADDR_NONE = 0x00000001; + // Host has ethernet address (no IP address) + static const uint32_t XNET_GET_XNADDR_ETHERNET = 0x00000002; + // Host has statically assigned IP address + static const uint32_t XNET_GET_XNADDR_STATIC = 0x00000004; + // Host has DHCP assigned IP address + static const uint32_t XNET_GET_XNADDR_DHCP = 0x00000008; + // Host has PPPoE assigned IP address + static const uint32_t XNET_GET_XNADDR_PPPOE = 0x00000010; + // Host has one or more gateways configured + static const uint32_t XNET_GET_XNADDR_GATEWAY = 0x00000020; + // Host has one or more DNS servers configured + static const uint32_t XNET_GET_XNADDR_DNS = 0x00000040; + // Host is currently connected to online service + static const uint32_t XNET_GET_XNADDR_ONLINE = 0x00000080; + // Network configuration requires troubleshooting + static const uint32_t XNET_GET_XNADDR_TROUBLESHOOT = 0x00008000; +}; + +u32 NetDll_XNetGetTitleXnAddr_entry(u32 caller, ppc_ptr_t addr_ptr) { + // Just return a loopback address atm. + addr_ptr->ina.s_addr = htonl(INADDR_LOOPBACK); + addr_ptr->inaOnline.s_addr = 0; + addr_ptr->wPortOnline = 0; + + // TODO(gibbed): A proper mac address. + // RakNet's 360 version appears to depend on abEnet to create "random" 64-bit + // numbers. A zero value will cause RakPeer::Startup to fail. This causes + // 58411436 to crash on startup. + // The 360-specific code is scrubbed from the RakNet repo, but there's still + // traces of what it's doing which match the game code. + // https://github.com/facebookarchive/RakNet/blob/master/Source/RakPeer.cpp#L382 + // https://github.com/facebookarchive/RakNet/blob/master/Source/RakPeer.cpp#L4527 + // https://github.com/facebookarchive/RakNet/blob/master/Source/RakPeer.cpp#L4467 + // "Mac address is a poor solution because you can't have multiple connections + // from the same system" + std::memset(addr_ptr->abEnet, 0xCC, 6); + + std::memset(addr_ptr->abOnline, 0, 20); + + return XnAddrStatus::XNET_GET_XNADDR_STATIC; +} + +u32 NetDll_XNetGetDebugXnAddr_entry(u32 caller, ppc_ptr_t addr_ptr) { + addr_ptr.Zero(); + + // XNET_GET_XNADDR_NONE causes caller to gracefully return. + return XnAddrStatus::XNET_GET_XNADDR_NONE; +} + +u32 NetDll_XNetXnAddrToMachineId_entry(u32 caller, ppc_ptr_t addr_ptr, mapped_u32 id_ptr) { + // Tell the caller we're not signed in to live (non-zero ret) + return 1; +} + +void NetDll_XNetInAddrToString_entry(u32 caller, u32 in_addr, mapped_string string_out, + u32 string_size) { + rex::string::rex_strcpy(string_out, string_size, "666.666.666.666"); +} + +// This converts a XNet address to an IN_ADDR. The IN_ADDR is used for +// subsequent socket calls (like a handle to a XNet address) +u32 NetDll_XNetXnAddrToInAddr_entry(u32 caller, ppc_ptr_t xn_addr, mapped_void xid, + mapped_void in_addr) { + return 1; +} + +// Does the reverse of the above. +// FIXME: Arguments may not be correct. +u32 NetDll_XNetInAddrToXnAddr_entry(u32 caller, mapped_void in_addr, ppc_ptr_t xn_addr, + mapped_void xid) { + return 1; +} + +// https://www.google.com/patents/WO2008112448A1?cl=en +// Reserves a port for use by system link +u32 NetDll_XNetSetSystemLinkPort_entry(u32 caller, u32 port) { + return 1; +} + +// https://github.com/ILOVEPIE/Cxbx-Reloaded/blob/master/src/CxbxKrnl/EmuXOnline.h#L39 +struct XEthernetStatus { + static const uint32_t XNET_ETHERNET_LINK_ACTIVE = 0x01; + static const uint32_t XNET_ETHERNET_LINK_100MBPS = 0x02; + static const uint32_t XNET_ETHERNET_LINK_10MBPS = 0x04; + static const uint32_t XNET_ETHERNET_LINK_FULL_DUPLEX = 0x08; + static const uint32_t XNET_ETHERNET_LINK_HALF_DUPLEX = 0x10; +}; + +u32 NetDll_XNetGetEthernetLinkStatus_entry(u32 caller) { + return 0; +} + +u32 NetDll_XNetDnsLookup_entry(u32 caller, mapped_string host, u32 event_handle, mapped_u32 pdns) { + // TODO(gibbed): actually implement this + if (pdns) { + auto dns_guest = REX_KERNEL_MEMORY()->SystemHeapAlloc(sizeof(XNDNS)); + auto dns = REX_KERNEL_MEMORY()->TranslateVirtual(dns_guest); + dns->status = 1; // non-zero = error + *pdns = dns_guest; + } + if (event_handle) { + auto ev = REX_KERNEL_OBJECTS()->LookupObject(event_handle); + assert_not_null(ev); + ev->Set(0, false); + } + return 0; +} + +u32 NetDll_XNetDnsRelease_entry(u32 caller, ppc_ptr_t dns) { + if (!dns) { + return X_STATUS_INVALID_PARAMETER; + } + REX_KERNEL_MEMORY()->SystemHeapFree(dns.guest_address()); + return 0; +} + +u32 NetDll_XNetQosServiceLookup_entry(u32 caller, u32 flags, u32 event_handle, mapped_u32 pqos) { + // Set pqos as some games will try accessing it despite non-successful result + if (pqos) { + auto qos_guest = REX_KERNEL_MEMORY()->SystemHeapAlloc(sizeof(XNQOS)); + auto qos = REX_KERNEL_MEMORY()->TranslateVirtual(qos_guest); + qos->count = qos->count_pending = 0; + *pqos = qos_guest; + } + if (event_handle) { + auto ev = REX_KERNEL_OBJECTS()->LookupObject(event_handle); + assert_not_null(ev); + ev->Set(0, false); + } + return 0; +} + +u32 NetDll_XNetQosRelease_entry(u32 caller, ppc_ptr_t qos) { + if (!qos) { + return X_STATUS_INVALID_PARAMETER; + } + REX_KERNEL_MEMORY()->SystemHeapFree(qos.guest_address()); + return 0; +} + +u32 NetDll_XNetQosListen_entry(u32 caller, mapped_void id, mapped_void data, u32 data_size, u32 r7, + u32 flags) { + return X_ERROR_FUNCTION_FAILED; +} + +u32 NetDll_inet_addr_entry(mapped_string addr_ptr) { + if (!addr_ptr) { + return -1; + } + + uint32_t addr = inet_addr(addr_ptr); + // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-inet_addr#return-value + // Based on console research it seems like x360 uses old version of inet_addr + // In case of empty string it return 0 instead of -1 + if (addr == -1 && !addr_ptr.value().length()) { + return 0; + } + + return rex::byte_swap(addr); +} + +u32 NetDll_socket_entry(u32 caller, u32 af, u32 type, u32 protocol) { + XSocket* socket = new XSocket(REX_KERNEL_STATE()); + X_STATUS result = + socket->Initialize(XSocket::AddressFamily((uint32_t)af), XSocket::Type((uint32_t)type), + XSocket::Protocol((uint32_t)protocol)); + + if (XFAILED(result)) { + socket->Release(); + + uint32_t error = xboxkrnl::xeRtlNtStatusToDosError(result); + XThread::SetLastError(error); + return -1; + } + + return socket->handle(); +} + +u32 NetDll_closesocket_entry(u32 caller, u32 socket_handle) { + auto socket = REX_KERNEL_OBJECTS()->LookupObject(socket_handle); + if (!socket) { + // WSAENOTSOCK + XThread::SetLastError(0x2736); + return -1; + } + + // TODO: Absolutely delete this object. It is no longer valid after calling + // closesocket. + socket->Close(); + socket->ReleaseHandle(); + return 0; +} + +i32 NetDll_shutdown_entry(u32 caller, u32 socket_handle, i32 how) { + auto socket = REX_KERNEL_OBJECTS()->LookupObject(socket_handle); + if (!socket) { + // WSAENOTSOCK + XThread::SetLastError(0x2736); + return -1; + } + + auto ret = socket->Shutdown(how); + if (ret == -1) { +#if REX_PLATFORM_WIN32 + uint32_t error_code = WSAGetLastError(); + XThread::SetLastError(error_code); +#else + XThread::SetLastError(0x0); +#endif + } + return ret; +} + +u32 NetDll_setsockopt_entry(u32 caller, u32 socket_handle, u32 level, u32 optname, + mapped_void optval_ptr, u32 optlen) { + auto socket = REX_KERNEL_OBJECTS()->LookupObject(socket_handle); + if (!socket) { + // WSAENOTSOCK + XThread::SetLastError(0x2736); + return -1; + } + + X_STATUS status = socket->SetOption(level, optname, optval_ptr, optlen); + return XSUCCEEDED(status) ? 0 : -1; +} + +u32 NetDll_ioctlsocket_entry(u32 caller, u32 socket_handle, u32 cmd, mapped_void arg_ptr) { + auto socket = REX_KERNEL_OBJECTS()->LookupObject(socket_handle); + if (!socket) { + // WSAENOTSOCK + XThread::SetLastError(0x2736); + return -1; + } + + X_STATUS status = socket->IOControl(cmd, arg_ptr); + if (XFAILED(status)) { + XThread::SetLastError(xboxkrnl::xeRtlNtStatusToDosError(status)); + return -1; + } + + // TODO + return 0; +} + +u32 NetDll_bind_entry(u32 caller, u32 socket_handle, ppc_ptr_t name, u32 namelen) { + auto socket = REX_KERNEL_OBJECTS()->LookupObject(socket_handle); + if (!socket) { + // WSAENOTSOCK + XThread::SetLastError(0x2736); + return -1; + } + + N_XSOCKADDR_IN native_name(name); + X_STATUS status = socket->Bind(&native_name, namelen); + if (XFAILED(status)) { + XThread::SetLastError(xboxkrnl::xeRtlNtStatusToDosError(status)); + return -1; + } + + return 0; +} + +u32 NetDll_connect_entry(u32 caller, u32 socket_handle, ppc_ptr_t name, u32 namelen) { + auto socket = REX_KERNEL_OBJECTS()->LookupObject(socket_handle); + if (!socket) { + // WSAENOTSOCK + XThread::SetLastError(0x2736); + return -1; + } + + N_XSOCKADDR native_name(name); + X_STATUS status = socket->Connect(&native_name, namelen); + if (XFAILED(status)) { + XThread::SetLastError(xboxkrnl::xeRtlNtStatusToDosError(status)); + return -1; + } + + return 0; +} + +u32 NetDll_listen_entry(u32 caller, u32 socket_handle, i32 backlog) { + auto socket = REX_KERNEL_OBJECTS()->LookupObject(socket_handle); + if (!socket) { + // WSAENOTSOCK + XThread::SetLastError(0x2736); + return -1; + } + + X_STATUS status = socket->Listen(backlog); + if (XFAILED(status)) { + XThread::SetLastError(xboxkrnl::xeRtlNtStatusToDosError(status)); + return -1; + } + + return 0; +} + +u32 NetDll_accept_entry(u32 caller, u32 socket_handle, ppc_ptr_t addr_ptr, + mapped_u32 addrlen_ptr) { + if (!addr_ptr) { + // WSAEFAULT + XThread::SetLastError(0x271E); + return -1; + } + + auto socket = REX_KERNEL_OBJECTS()->LookupObject(socket_handle); + if (!socket) { + // WSAENOTSOCK + XThread::SetLastError(0x2736); + return -1; + } + + N_XSOCKADDR native_addr(addr_ptr); + int native_len = *addrlen_ptr; + auto new_socket = socket->Accept(&native_addr, &native_len); + if (new_socket) { + addr_ptr->address_family = native_addr.address_family; + std::memcpy(addr_ptr->sa_data, native_addr.sa_data, *addrlen_ptr - 2); + *addrlen_ptr = native_len; + + return new_socket->handle(); + } else { + return -1; + } +} + +struct x_fd_set { + rex::be fd_count; + rex::be fd_array[64]; +}; + +struct host_set { + uint32_t count; + object_ref sockets[64]; + + void Load(const x_fd_set* guest_set) { + assert_true(guest_set->fd_count < 64); + this->count = guest_set->fd_count; + for (uint32_t i = 0; i < this->count; ++i) { + auto socket_handle = static_cast(guest_set->fd_array[i]); + if (socket_handle == -1) { + this->count = i; + break; + } + // Convert from Xenia -> native + auto socket = REX_KERNEL_OBJECTS()->LookupObject(socket_handle); + assert_not_null(socket); + this->sockets[i] = socket; + } + } + + void Store(x_fd_set* guest_set) { + guest_set->fd_count = 0; + for (uint32_t i = 0; i < this->count; ++i) { + auto socket = this->sockets[i]; + guest_set->fd_array[guest_set->fd_count++] = socket->handle(); + } + } + + void Store(fd_set* native_set) { + FD_ZERO(native_set); + for (uint32_t i = 0; i < this->count; ++i) { + FD_SET(this->sockets[i]->native_handle(), native_set); + } + } + + void UpdateFrom(fd_set* native_set) { + uint32_t new_count = 0; + for (uint32_t i = 0; i < this->count; ++i) { + auto socket = this->sockets[i]; + if (FD_ISSET(socket->native_handle(), native_set)) { + this->sockets[new_count++] = socket; + } + } + this->count = new_count; + } +}; + +i32 NetDll_select_entry(i32 caller, i32 nfds, ppc_ptr_t readfds, + ppc_ptr_t writefds, ppc_ptr_t exceptfds, + mapped_void timeout_ptr) { + host_set host_readfds = {}; + fd_set native_readfds = {}; + if (readfds) { + host_readfds.Load(readfds); + host_readfds.Store(&native_readfds); + } + host_set host_writefds = {}; + fd_set native_writefds = {}; + if (writefds) { + host_writefds.Load(writefds); + host_writefds.Store(&native_writefds); + } + host_set host_exceptfds = {}; + fd_set native_exceptfds = {}; + if (exceptfds) { + host_exceptfds.Load(exceptfds); + host_exceptfds.Store(&native_exceptfds); + } + timeval* timeout_in = nullptr; + timeval timeout; + if (timeout_ptr) { + timeout = {static_cast(timeout_ptr.as_array()[0]), + static_cast(timeout_ptr.as_array()[1])}; + chrono::Clock::ScaleGuestDurationTimeval(reinterpret_cast(&timeout.tv_sec), + reinterpret_cast(&timeout.tv_usec)); + timeout_in = &timeout; + } + int ret = select(nfds, readfds ? &native_readfds : nullptr, writefds ? &native_writefds : nullptr, + exceptfds ? &native_exceptfds : nullptr, timeout_in); + if (readfds) { + host_readfds.UpdateFrom(&native_readfds); + host_readfds.Store(readfds); + } + if (writefds) { + host_writefds.UpdateFrom(&native_writefds); + host_writefds.Store(writefds); + } + if (exceptfds) { + host_exceptfds.UpdateFrom(&native_exceptfds); + host_exceptfds.Store(exceptfds); + } + + // TODO(gibbed): modify ret to be what's actually copied to the guest fd_sets? + return ret; +} + +u32 NetDll_recv_entry(u32 caller, u32 socket_handle, mapped_void buf_ptr, u32 buf_len, u32 flags) { + auto socket = REX_KERNEL_OBJECTS()->LookupObject(socket_handle); + if (!socket) { + // WSAENOTSOCK + XThread::SetLastError(0x2736); + return -1; + } + + return socket->Recv(buf_ptr, buf_len, flags); +} + +u32 NetDll_recvfrom_entry(u32 caller, u32 socket_handle, mapped_void buf_ptr, u32 buf_len, + u32 flags, ppc_ptr_t from_ptr, mapped_u32 fromlen_ptr) { + auto socket = REX_KERNEL_OBJECTS()->LookupObject(socket_handle); + if (!socket) { + // WSAENOTSOCK + XThread::SetLastError(0x2736); + return -1; + } + + N_XSOCKADDR_IN native_from; + if (from_ptr) { + native_from = *from_ptr; + } + uint32_t native_fromlen = fromlen_ptr ? fromlen_ptr.value() : 0; + int ret = + socket->RecvFrom(buf_ptr, buf_len, flags, &native_from, fromlen_ptr ? &native_fromlen : 0); + + if (from_ptr) { + from_ptr->sin_family = native_from.sin_family; + from_ptr->sin_port = native_from.sin_port; + from_ptr->sin_addr = native_from.sin_addr; + std::memset(from_ptr->x_sin_zero, 0, sizeof(from_ptr->x_sin_zero)); + } + if (fromlen_ptr) { + *fromlen_ptr = native_fromlen; + } + + if (ret == -1) { +// TODO: Better way of getting the error code +#if REX_PLATFORM_WIN32 + uint32_t error_code = WSAGetLastError(); + XThread::SetLastError(error_code); +#else + XThread::SetLastError(0x0); +#endif + } + + return ret; +} + +u32 NetDll_send_entry(u32 caller, u32 socket_handle, mapped_void buf_ptr, u32 buf_len, u32 flags) { + auto socket = REX_KERNEL_OBJECTS()->LookupObject(socket_handle); + if (!socket) { + // WSAENOTSOCK + XThread::SetLastError(0x2736); + return -1; + } + + return socket->Send(buf_ptr, buf_len, flags); +} + +u32 NetDll_sendto_entry(u32 caller, u32 socket_handle, mapped_void buf_ptr, u32 buf_len, u32 flags, + ppc_ptr_t to_ptr, u32 to_len) { + auto socket = REX_KERNEL_OBJECTS()->LookupObject(socket_handle); + if (!socket) { + // WSAENOTSOCK + XThread::SetLastError(0x2736); + return -1; + } + + N_XSOCKADDR_IN native_to(to_ptr); + return socket->SendTo(buf_ptr, buf_len, flags, &native_to, to_len); +} + +u32 NetDll___WSAFDIsSet_entry(u32 socket_handle, ppc_ptr_t fd_set) { + const uint8_t max_fd_count = std::min((uint32_t)fd_set->fd_count, uint32_t(64)); + for (uint8_t i = 0; i < max_fd_count; i++) { + if (fd_set->fd_array[i] == socket_handle) { + return 1; + } + } + return 0; +} + +void NetDll_WSASetLastError_entry(u32 error_code) { + XThread::SetLastError(error_code); +} + +} // namespace xam +} // namespace kernel +} // namespace rex + +REX_EXPORT(__imp__NetDll_XNetStartup, rex::kernel::xam::NetDll_XNetStartup_entry) +REX_EXPORT(__imp__NetDll_XNetCleanup, rex::kernel::xam::NetDll_XNetCleanup_entry) +REX_EXPORT(__imp__NetDll_XNetGetOpt, rex::kernel::xam::NetDll_XNetGetOpt_entry) +REX_EXPORT(__imp__NetDll_XNetRandom, rex::kernel::xam::NetDll_XNetRandom_entry) +REX_EXPORT(__imp__NetDll_WSAStartup, rex::kernel::xam::NetDll_WSAStartup_entry) +REX_EXPORT(__imp__NetDll_WSACleanup, rex::kernel::xam::NetDll_WSACleanup_entry) +REX_EXPORT(__imp__NetDll_WSAGetLastError, rex::kernel::xam::NetDll_WSAGetLastError_entry) +REX_EXPORT(__imp__NetDll_WSARecvFrom, rex::kernel::xam::NetDll_WSARecvFrom_entry) +REX_EXPORT(__imp__NetDll_WSASendTo, rex::kernel::xam::NetDll_WSASendTo_entry) +REX_EXPORT(__imp__NetDll_WSAWaitForMultipleEvents, + rex::kernel::xam::NetDll_WSAWaitForMultipleEvents_entry) +REX_EXPORT(__imp__NetDll_WSACreateEvent, rex::kernel::xam::NetDll_WSACreateEvent_entry) +REX_EXPORT(__imp__NetDll_WSACloseEvent, rex::kernel::xam::NetDll_WSACloseEvent_entry) +REX_EXPORT(__imp__NetDll_WSAResetEvent, rex::kernel::xam::NetDll_WSAResetEvent_entry) +REX_EXPORT(__imp__NetDll_WSASetEvent, rex::kernel::xam::NetDll_WSASetEvent_entry) +REX_EXPORT(__imp__NetDll_XNetGetTitleXnAddr, rex::kernel::xam::NetDll_XNetGetTitleXnAddr_entry) +REX_EXPORT(__imp__NetDll_XNetGetDebugXnAddr, rex::kernel::xam::NetDll_XNetGetDebugXnAddr_entry) +REX_EXPORT(__imp__NetDll_XNetXnAddrToMachineId, + rex::kernel::xam::NetDll_XNetXnAddrToMachineId_entry) +REX_EXPORT(__imp__NetDll_XNetInAddrToString, rex::kernel::xam::NetDll_XNetInAddrToString_entry) +REX_EXPORT(__imp__NetDll_XNetXnAddrToInAddr, rex::kernel::xam::NetDll_XNetXnAddrToInAddr_entry) +REX_EXPORT(__imp__NetDll_XNetInAddrToXnAddr, rex::kernel::xam::NetDll_XNetInAddrToXnAddr_entry) +REX_EXPORT(__imp__NetDll_XNetSetSystemLinkPort, + rex::kernel::xam::NetDll_XNetSetSystemLinkPort_entry) +REX_EXPORT(__imp__NetDll_XNetGetEthernetLinkStatus, + rex::kernel::xam::NetDll_XNetGetEthernetLinkStatus_entry) +REX_EXPORT(__imp__NetDll_XNetDnsLookup, rex::kernel::xam::NetDll_XNetDnsLookup_entry) +REX_EXPORT(__imp__NetDll_XNetDnsRelease, rex::kernel::xam::NetDll_XNetDnsRelease_entry) +REX_EXPORT(__imp__NetDll_XNetQosServiceLookup, rex::kernel::xam::NetDll_XNetQosServiceLookup_entry) +REX_EXPORT(__imp__NetDll_XNetQosRelease, rex::kernel::xam::NetDll_XNetQosRelease_entry) +REX_EXPORT(__imp__NetDll_XNetQosListen, rex::kernel::xam::NetDll_XNetQosListen_entry) +REX_EXPORT(__imp__NetDll_inet_addr, rex::kernel::xam::NetDll_inet_addr_entry) +REX_EXPORT(__imp__NetDll_socket, rex::kernel::xam::NetDll_socket_entry) +REX_EXPORT(__imp__NetDll_closesocket, rex::kernel::xam::NetDll_closesocket_entry) +REX_EXPORT(__imp__NetDll_shutdown, rex::kernel::xam::NetDll_shutdown_entry) +REX_EXPORT(__imp__NetDll_setsockopt, rex::kernel::xam::NetDll_setsockopt_entry) +REX_EXPORT(__imp__NetDll_ioctlsocket, rex::kernel::xam::NetDll_ioctlsocket_entry) +REX_EXPORT(__imp__NetDll_bind, rex::kernel::xam::NetDll_bind_entry) +REX_EXPORT(__imp__NetDll_connect, rex::kernel::xam::NetDll_connect_entry) +REX_EXPORT(__imp__NetDll_listen, rex::kernel::xam::NetDll_listen_entry) +REX_EXPORT(__imp__NetDll_accept, rex::kernel::xam::NetDll_accept_entry) +REX_EXPORT(__imp__NetDll_select, rex::kernel::xam::NetDll_select_entry) +REX_EXPORT(__imp__NetDll_recv, rex::kernel::xam::NetDll_recv_entry) +REX_EXPORT(__imp__NetDll_recvfrom, rex::kernel::xam::NetDll_recvfrom_entry) +REX_EXPORT(__imp__NetDll_send, rex::kernel::xam::NetDll_send_entry) +REX_EXPORT(__imp__NetDll_sendto, rex::kernel::xam::NetDll_sendto_entry) +REX_EXPORT(__imp__NetDll___WSAFDIsSet, rex::kernel::xam::NetDll___WSAFDIsSet_entry) +REX_EXPORT(__imp__NetDll_WSASetLastError, rex::kernel::xam::NetDll_WSASetLastError_entry) + +REX_EXPORT_STUB(__imp__NetDll_UpnpActionCalculateWorkBufferSize); +REX_EXPORT_STUB(__imp__NetDll_UpnpActionCreate); +REX_EXPORT_STUB(__imp__NetDll_UpnpActionGetResults); +REX_EXPORT_STUB(__imp__NetDll_UpnpCleanup); +REX_EXPORT_STUB(__imp__NetDll_UpnpCloseHandle); +REX_EXPORT_STUB(__imp__NetDll_UpnpDescribeCreate); +REX_EXPORT_STUB(__imp__NetDll_UpnpDescribeGetResults); +REX_EXPORT_STUB(__imp__NetDll_UpnpDoWork); +REX_EXPORT_STUB(__imp__NetDll_UpnpEventCreate); +REX_EXPORT_STUB(__imp__NetDll_UpnpEventGetCurrentState); +REX_EXPORT_STUB(__imp__NetDll_UpnpEventUnsubscribe); +REX_EXPORT_STUB(__imp__NetDll_UpnpSearchCreate); +REX_EXPORT_STUB(__imp__NetDll_UpnpSearchGetDevices); +REX_EXPORT_STUB(__imp__NetDll_UpnpStartup); +REX_EXPORT_STUB(__imp__NetDll_WSACancelOverlappedIO); +REX_EXPORT_STUB(__imp__NetDll_WSAEventSelect); +REX_EXPORT_STUB(__imp__NetDll_WSAGetOverlappedResult); +REX_EXPORT_STUB(__imp__NetDll_WSARecv); +REX_EXPORT_STUB(__imp__NetDll_WSASend); +REX_EXPORT_STUB(__imp__NetDll_WSAStartupEx); +REX_EXPORT_STUB(__imp__NetDll_XHttpCloseHandle); +REX_EXPORT_STUB(__imp__NetDll_XHttpConnect); +REX_EXPORT_STUB(__imp__NetDll_XHttpCrackUrl); +REX_EXPORT_STUB(__imp__NetDll_XHttpCrackUrlW); +REX_EXPORT_STUB(__imp__NetDll_XHttpCreateUrl); +REX_EXPORT_STUB(__imp__NetDll_XHttpCreateUrlW); +REX_EXPORT_STUB(__imp__NetDll_XHttpDoWork); +REX_EXPORT_STUB(__imp__NetDll_XHttpGetPerfCounters); +REX_EXPORT_STUB(__imp__NetDll_XHttpOpen); +REX_EXPORT_STUB(__imp__NetDll_XHttpOpenRequest); +REX_EXPORT_STUB(__imp__NetDll_XHttpOpenRequestUsingMemory); +REX_EXPORT_STUB(__imp__NetDll_XHttpQueryAuthSchemes); +REX_EXPORT_STUB(__imp__NetDll_XHttpQueryHeaders); +REX_EXPORT_STUB(__imp__NetDll_XHttpQueryOption); +REX_EXPORT_STUB(__imp__NetDll_XHttpReadData); +REX_EXPORT_STUB(__imp__NetDll_XHttpReceiveResponse); +REX_EXPORT_STUB(__imp__NetDll_XHttpResetPerfCounters); +REX_EXPORT_STUB(__imp__NetDll_XHttpSendRequest); +REX_EXPORT_STUB(__imp__NetDll_XHttpSetCredentials); +REX_EXPORT_STUB(__imp__NetDll_XHttpSetOption); +REX_EXPORT_STUB(__imp__NetDll_XHttpSetStatusCallback); +REX_EXPORT_STUB(__imp__NetDll_XHttpShutdown); +REX_EXPORT_STUB(__imp__NetDll_XHttpStartup); +REX_EXPORT_STUB(__imp__NetDll_XHttpWriteData); +REX_EXPORT_STUB(__imp__NetDll_XNetConnect); +REX_EXPORT_STUB(__imp__NetDll_XNetCreateKey); +REX_EXPORT_STUB(__imp__NetDll_XNetDnsReverseLookup); +REX_EXPORT_STUB(__imp__NetDll_XNetDnsReverseRelease); +REX_EXPORT_STUB(__imp__NetDll_XNetGetBroadcastVersionStatus); +REX_EXPORT_STUB(__imp__NetDll_XNetGetConnectStatus); +REX_EXPORT_STUB(__imp__NetDll_XNetGetSystemLinkPort); +REX_EXPORT_STUB(__imp__NetDll_XNetGetXnAddrPlatform); +REX_EXPORT_STUB(__imp__NetDll_XNetInAddrToServer); +REX_EXPORT_STUB(__imp__NetDll_XNetQosGetListenStats); +REX_EXPORT_STUB(__imp__NetDll_XNetQosLookup); +REX_EXPORT_STUB(__imp__NetDll_XNetRegisterKey); +REX_EXPORT_STUB(__imp__NetDll_XNetReplaceKey); +REX_EXPORT_STUB(__imp__NetDll_XNetServerToInAddr); +REX_EXPORT_STUB(__imp__NetDll_XNetSetOpt); +REX_EXPORT_STUB(__imp__NetDll_XNetStartupEx); +REX_EXPORT_STUB(__imp__NetDll_XNetTsAddrToInAddr); +REX_EXPORT_STUB(__imp__NetDll_XNetUnregisterInAddr); +REX_EXPORT_STUB(__imp__NetDll_XNetUnregisterKey); +REX_EXPORT_STUB(__imp__NetDll_XmlDownloadContinue); +REX_EXPORT_STUB(__imp__NetDll_XmlDownloadGetParseTime); +REX_EXPORT_STUB(__imp__NetDll_XmlDownloadGetReceivedDataSize); +REX_EXPORT_STUB(__imp__NetDll_XmlDownloadStart); +REX_EXPORT_STUB(__imp__NetDll_XmlDownloadStop); +REX_EXPORT_STUB(__imp__NetDll_XnpCapture); +REX_EXPORT_STUB(__imp__NetDll_XnpConfig); +REX_EXPORT_STUB(__imp__NetDll_XnpConfigUPnP); +REX_EXPORT_STUB(__imp__NetDll_XnpConfigUPnPPortAndExternalAddr); +REX_EXPORT_STUB(__imp__NetDll_XnpEthernetInterceptRecv); +REX_EXPORT_STUB(__imp__NetDll_XnpEthernetInterceptSetCallbacks); +REX_EXPORT_STUB(__imp__NetDll_XnpEthernetInterceptSetExtendedReceiveCallback); +REX_EXPORT_STUB(__imp__NetDll_XnpEthernetInterceptXmit); +REX_EXPORT_STUB(__imp__NetDll_XnpEthernetInterceptXmitAsIp); +REX_EXPORT_STUB(__imp__NetDll_XnpGetActiveSocketList); +REX_EXPORT_STUB(__imp__NetDll_XnpGetConfigStatus); +REX_EXPORT_STUB(__imp__NetDll_XnpGetKeyList); +REX_EXPORT_STUB(__imp__NetDll_XnpGetQosLookupList); +REX_EXPORT_STUB(__imp__NetDll_XnpGetSecAssocList); +REX_EXPORT_STUB(__imp__NetDll_XnpGetVlanXboxName); +REX_EXPORT_STUB(__imp__NetDll_XnpLoadConfigParams); +REX_EXPORT_STUB(__imp__NetDll_XnpLoadMachineAccount); +REX_EXPORT_STUB(__imp__NetDll_XnpLogonClearChallenge); +REX_EXPORT_STUB(__imp__NetDll_XnpLogonClearQEvent); +REX_EXPORT_STUB(__imp__NetDll_XnpLogonGetChallenge); +REX_EXPORT_STUB(__imp__NetDll_XnpLogonGetQFlags); +REX_EXPORT_STUB(__imp__NetDll_XnpLogonGetQVals); +REX_EXPORT_STUB(__imp__NetDll_XnpLogonGetStatus); +REX_EXPORT_STUB(__imp__NetDll_XnpLogonSetChallengeResponse); +REX_EXPORT_STUB(__imp__NetDll_XnpLogonSetPState); +REX_EXPORT_STUB(__imp__NetDll_XnpLogonSetQEvent); +REX_EXPORT_STUB(__imp__NetDll_XnpLogonSetQFlags); +REX_EXPORT_STUB(__imp__NetDll_XnpLogonSetQVals); +REX_EXPORT_STUB(__imp__NetDll_XnpNoteSystemTime); +REX_EXPORT_STUB(__imp__NetDll_XnpPersistTitleState); +REX_EXPORT_STUB(__imp__NetDll_XnpQosHistoryGetAggregateMeasurement); +REX_EXPORT_STUB(__imp__NetDll_XnpQosHistoryGetEntries); +REX_EXPORT_STUB(__imp__NetDll_XnpQosHistoryLoad); +REX_EXPORT_STUB(__imp__NetDll_XnpQosHistorySaveMeasurements); +REX_EXPORT_STUB(__imp__NetDll_XnpRegisterKeyForCallerType); +REX_EXPORT_STUB(__imp__NetDll_XnpReplaceKeyForCallerType); +REX_EXPORT_STUB(__imp__NetDll_XnpSaveConfigParams); +REX_EXPORT_STUB(__imp__NetDll_XnpSaveMachineAccount); +REX_EXPORT_STUB(__imp__NetDll_XnpSetVlanXboxName); +REX_EXPORT_STUB(__imp__NetDll_XnpToolIpProxyInject); +REX_EXPORT_STUB(__imp__NetDll_XnpToolSetCallbacks); +REX_EXPORT_STUB(__imp__NetDll_XnpUnregisterKeyForCallerType); +REX_EXPORT_STUB(__imp__NetDll_XnpUpdateConfigParams); +REX_EXPORT_STUB(__imp__NetDll_getpeername); +REX_EXPORT_STUB(__imp__NetDll_getsockname); +REX_EXPORT_STUB(__imp__NetDll_getsockopt); diff --git a/src/kernel/xam/xam_notify.cpp b/src/kernel/xam/xam_notify.cpp new file mode 100644 index 0000000..9abcef6 --- /dev/null +++ b/src/kernel/xam/xam_notify.cpp @@ -0,0 +1,125 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include + +namespace rex { +namespace kernel { +namespace xam { +using namespace rex::system; +using namespace rex::system::xam; + +uint32_t xeXamNotifyCreateListener(uint64_t mask, uint32_t is_system, uint32_t max_version) { + assert_true(max_version < 11); + + if (max_version > 10) { + max_version = 10; + } + + auto listener = object_ref(new XNotifyListener(REX_KERNEL_STATE())); + listener->Initialize(mask, max_version); + + // Handle ref is incremented, so return that. + uint32_t handle = listener->handle(); + + REXKRNL_DEBUG( + "XamNotifyCreateListener(mask={:#018x}, is_system={}, max_version={}) -> handle={:08X}", mask, + is_system, max_version, handle); + + return handle; +} + +u32 XamNotifyCreateListener_entry(u64 mask, u32 max_version) { + return xeXamNotifyCreateListener(mask, 0, max_version); +} + +u32 XamNotifyCreateListenerInternal_entry(u64 mask, u32 is_system, u32 max_version) { + return xeXamNotifyCreateListener(mask, is_system, max_version); +} + +// https://github.com/CodeAsm/ffplay360/blob/master/Common/AtgSignIn.cpp +u32 XNotifyGetNext_entry(u32 handle, u32 match_id, mapped_u32 id_ptr, mapped_u32 param_ptr) { + if (param_ptr) { + *param_ptr = 0; + } + + if (!id_ptr) { + return 0; + } + *id_ptr = 0; + + // Grab listener. + auto listener = REX_KERNEL_OBJECTS()->LookupObject(handle); + if (!listener) { + return 0; + } + + bool dequeued = false; + uint32_t id = 0; + uint32_t param = 0; + if (match_id) { + // Asking for a specific notification + id = match_id; + dequeued = listener->DequeueNotification(match_id, ¶m); + } else { + // Just get next. + dequeued = listener->DequeueNotification(&id, ¶m); + } + + *id_ptr = dequeued ? id : 0; + // param_ptr may be null - 555307F0 Demo explicitly passes nullptr in the + // code. + // https://github.com/xenia-project/xenia/pull/1577 + if (param_ptr) { + *param_ptr = dequeued ? param : 0; + } + + if (dequeued) { + REXKRNL_NOISY_DEBUG("XNotifyGetNext({:08X}, {:08X}) -> id={:#x}, param={}", uint32_t(handle), + uint32_t(match_id), id, param); + } + return dequeued ? 1 : 0; +} + +u32 XNotifyDelayUI_entry(u32 delay_ms) { + // Ignored. + return 0; +} + +void XNotifyPositionUI_entry(u32 position) { + // Ignored. +} + +} // namespace xam +} // namespace kernel +} // namespace rex + +REX_EXPORT(__imp__XamNotifyCreateListener, rex::kernel::xam::XamNotifyCreateListener_entry) +REX_EXPORT(__imp__XamNotifyCreateListenerInternal, + rex::kernel::xam::XamNotifyCreateListenerInternal_entry) +REX_EXPORT(__imp__XNotifyGetNext, rex::kernel::xam::XNotifyGetNext_entry) +REX_EXPORT(__imp__XNotifyDelayUI, rex::kernel::xam::XNotifyDelayUI_entry) +REX_EXPORT(__imp__XNotifyPositionUI, rex::kernel::xam::XNotifyPositionUI_entry) + +REX_EXPORT_STUB(__imp__XNotifyBroadcast); +REX_EXPORT_STUB(__imp__XNotifyQueueUI); +REX_EXPORT_STUB(__imp__XNotifyQueueUIEx); +REX_EXPORT_STUB(__imp__XNotifyRegisterArea); +REX_EXPORT_STUB(__imp__XNotifyUIGetOptions); +REX_EXPORT_STUB(__imp__XNotifyUISetOptions); +REX_EXPORT_STUB(__imp__XamNotifyCreateListenerRangeInternal); +REX_EXPORT_STUB(__imp__XamNotifyDelayUIInternal); diff --git a/src/kernel/xam/xam_nui.cpp b/src/kernel/xam/xam_nui.cpp new file mode 100644 index 0000000..bf10967 --- /dev/null +++ b/src/kernel/xam/xam_nui.cpp @@ -0,0 +1,125 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +namespace rex { +namespace kernel { +namespace xam { + +extern std::atomic xam_dialogs_shown_; + +struct X_NUI_DEVICE_STATUS { + rex::be unk0; + rex::be unk1; + rex::be unk2; + rex::be status; + rex::be unk4; + rex::be unk5; +}; +static_assert(sizeof(X_NUI_DEVICE_STATUS) == 24, "Size matters"); + +void XamNuiGetDeviceStatus_entry(ppc_ptr_t status_ptr) { + status_ptr.Zero(); + status_ptr->status = 0; // Not connected. +} + +u32 XamShowNuiTroubleshooterUI_entry(u32 unk1, u32 unk2, u32 unk3) { + // unk1 is 0xFF - possibly user index? + // unk2, unk3 appear to always be zero. + + if (REXCVAR_GET(headless)) { + return 0; + } + // TODO(tomc): Implement imgui stuff + // const Runtime* emulator = REX_KERNEL_STATE()->emulator(); + // ui::Window* display_window = emulator->display_window(); + // ui::ImGuiDrawer* imgui_drawer = emulator->imgui_drawer(); + // if (display_window && imgui_drawer) { + // rex::thread::Fence fence; + // if (display_window->app_context().CallInUIThreadSynchronous([&]() { + // rex::ui::ImGuiDialog::ShowMessageBox( + // imgui_drawer, "NUI Troubleshooter", + // "The game has indicated there is a problem with NUI (Kinect).") + // ->Then(&fence); + // })) { + // ++xam_dialogs_shown_; + // fence.Wait(); + // --xam_dialogs_shown_; + // } + //} + + return 0; +} + +} // namespace xam +} // namespace kernel +} // namespace rex + +REX_EXPORT(__imp__XamNuiGetDeviceStatus, rex::kernel::xam::XamNuiGetDeviceStatus_entry) +REX_EXPORT(__imp__XamShowNuiTroubleshooterUI, rex::kernel::xam::XamShowNuiTroubleshooterUI_entry) + +REX_EXPORT_STUB(__imp__XamEnableNatalPlayback); +REX_EXPORT_STUB(__imp__XamEnableNuiAutomation); +REX_EXPORT_STUB(__imp__XamKinectGetHardwareType); +REX_EXPORT_STUB(__imp__XamNatalDeviceAudioCalibrate); +REX_EXPORT_STUB(__imp__XamNuiCameraAdjustTilt); +REX_EXPORT_STUB(__imp__XamNuiCameraElevationAutoTilt); +REX_EXPORT_STUB(__imp__XamNuiCameraElevationGetAngle); +REX_EXPORT_STUB(__imp__XamNuiCameraElevationReverseAutoTilt); +REX_EXPORT_STUB(__imp__XamNuiCameraElevationSetAngle); +REX_EXPORT_STUB(__imp__XamNuiCameraElevationSetCallback); +REX_EXPORT_STUB(__imp__XamNuiCameraElevationStopMovement); +REX_EXPORT_STUB(__imp__XamNuiCameraGetTiltControllerType); +REX_EXPORT_STUB(__imp__XamNuiCameraRememberFloor); +REX_EXPORT_STUB(__imp__XamNuiCameraSetFlags); +REX_EXPORT_STUB(__imp__XamNuiCameraTiltGetStatus); +REX_EXPORT_STUB(__imp__XamNuiCameraTiltReportStatus); +REX_EXPORT_STUB(__imp__XamNuiCameraTiltSetCallback); +REX_EXPORT_STUB(__imp__XamNuiEnableChatMic); +REX_EXPORT_STUB(__imp__XamNuiGetCameraIntrinsics); +REX_EXPORT_STUB(__imp__XamNuiGetDepthCalibration); +REX_EXPORT_STUB(__imp__XamNuiGetDeviceSerialNumber); +REX_EXPORT_STUB(__imp__XamNuiGetFanRate); +REX_EXPORT_STUB(__imp__XamNuiGetLoadedDepthCalibration); +REX_EXPORT_STUB(__imp__XamNuiGetSupportString); +REX_EXPORT_STUB(__imp__XamNuiGetSystemGestureControl); +REX_EXPORT_STUB(__imp__XamNuiGetTrueColorInfo); +REX_EXPORT_STUB(__imp__XamNuiHudEnableInputFilter); +REX_EXPORT_STUB(__imp__XamNuiHudGetEngagedEnrollmentIndex); +REX_EXPORT_STUB(__imp__XamNuiHudGetEngagedTrackingID); +REX_EXPORT_STUB(__imp__XamNuiHudGetInitializeFlags); +REX_EXPORT_STUB(__imp__XamNuiHudGetVersions); +REX_EXPORT_STUB(__imp__XamNuiHudInterpretFrame); +REX_EXPORT_STUB(__imp__XamNuiHudIsEnabled); +REX_EXPORT_STUB(__imp__XamNuiHudSetEngagedTrackingID); +REX_EXPORT_STUB(__imp__XamNuiIdentityAbort); +REX_EXPORT_STUB(__imp__XamNuiIdentityEnrollForSignIn); +REX_EXPORT_STUB(__imp__XamNuiIdentityGetColorTexture); +REX_EXPORT_STUB(__imp__XamNuiIdentityGetEnrollmentInfo); +REX_EXPORT_STUB(__imp__XamNuiIdentityGetQualityFlags); +REX_EXPORT_STUB(__imp__XamNuiIdentityGetQualityFlagsMessage); +REX_EXPORT_STUB(__imp__XamNuiIdentityGetSessionId); +REX_EXPORT_STUB(__imp__XamNuiIdentityIdentifyWithBiometric); +REX_EXPORT_STUB(__imp__XamNuiIdentityUnenroll); +REX_EXPORT_STUB(__imp__XamNuiIsChatMicEnabled); +REX_EXPORT_STUB(__imp__XamNuiIsDeviceReady); +REX_EXPORT_STUB(__imp__XamNuiNatalCameraUpdateComplete); +REX_EXPORT_STUB(__imp__XamNuiNatalCameraUpdateStarting); +REX_EXPORT_STUB(__imp__XamNuiPlayerEngagementUpdate); +REX_EXPORT_STUB(__imp__XamNuiSetForceDeviceOff); +REX_EXPORT_STUB(__imp__XamNuiSkeletonGetBestSkeletonIndex); +REX_EXPORT_STUB(__imp__XamNuiSkeletonScoreUpdate); +REX_EXPORT_STUB(__imp__XamNuiStoreDepthCalibration); diff --git a/src/kernel/xam/xam_party.cpp b/src/kernel/xam/xam_party.cpp new file mode 100644 index 0000000..d75d65e --- /dev/null +++ b/src/kernel/xam/xam_party.cpp @@ -0,0 +1,76 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +namespace rex { +namespace kernel { +namespace xam { + +u32 XamPartyGetUserList_entry(u32 player_count, mapped_u32 party_list) { + // 5345085D wants specifically this code to skip loading party data. + // This code is not documented in NT_STATUS code list + return 0x807D0003; +} + +u32 XamPartySendGameInvites_entry(u32 r3, u32 r4, u32 r5) { + return X_ERROR_FUNCTION_FAILED; +} + +u32 XamPartySetCustomData_entry(u32 r3, u32 r4, u32 r5) { + return X_ERROR_FUNCTION_FAILED; +} + +u32 XamPartyGetBandwidth_entry(u32 r3, u32 r4) { + return X_ERROR_FUNCTION_FAILED; +} + +} // namespace xam +} // namespace kernel +} // namespace rex + +REX_EXPORT(__imp__XamPartyGetUserList, rex::kernel::xam::XamPartyGetUserList_entry) +REX_EXPORT(__imp__XamPartySendGameInvites, rex::kernel::xam::XamPartySendGameInvites_entry) +REX_EXPORT(__imp__XamPartySetCustomData, rex::kernel::xam::XamPartySetCustomData_entry) +REX_EXPORT(__imp__XamPartyGetBandwidth, rex::kernel::xam::XamPartyGetBandwidth_entry) + +REX_EXPORT_STUB(__imp__XamPartyAddLocalUsers); +REX_EXPORT_STUB(__imp__XamPartyAutomationInprocCall); +REX_EXPORT_STUB(__imp__XamPartyCreate); +REX_EXPORT_STUB(__imp__XamPartyGetAccessLevel); +REX_EXPORT_STUB(__imp__XamPartyGetFormation); +REX_EXPORT_STUB(__imp__XamPartyGetInfo); +REX_EXPORT_STUB(__imp__XamPartyGetInfoEx); +REX_EXPORT_STUB(__imp__XamPartyGetJoinable); +REX_EXPORT_STUB(__imp__XamPartyGetNetworkCounters); +REX_EXPORT_STUB(__imp__XamPartyGetRoutingTable); +REX_EXPORT_STUB(__imp__XamPartyGetState); +REX_EXPORT_STUB(__imp__XamPartyGetUserListInternal); +REX_EXPORT_STUB(__imp__XamPartyIsCoordinator); +REX_EXPORT_STUB(__imp__XamPartyJoin); +REX_EXPORT_STUB(__imp__XamPartyJoinEx); +REX_EXPORT_STUB(__imp__XamPartyKickUser); +REX_EXPORT_STUB(__imp__XamPartyLeave); +REX_EXPORT_STUB(__imp__XamPartyOverrideNatType); +REX_EXPORT_STUB(__imp__XamPartyRemoveLocalUsers); +REX_EXPORT_STUB(__imp__XamPartySendInvite); +REX_EXPORT_STUB(__imp__XamPartySendInviteDeprecated); +REX_EXPORT_STUB(__imp__XamPartySetConnectivityGraph); +REX_EXPORT_STUB(__imp__XamPartySetJoinable); +REX_EXPORT_STUB(__imp__XamPartySetTestDelay); +REX_EXPORT_STUB(__imp__XamPartySetTestFlags); diff --git a/src/kernel/xam/xam_task.cpp b/src/kernel/xam/xam_task.cpp new file mode 100644 index 0000000..5f2a529 --- /dev/null +++ b/src/kernel/xam/xam_task.cpp @@ -0,0 +1,103 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if REX_PLATFORM_WIN32 +#include +#endif + +#include + +namespace rex { +namespace kernel { +namespace xam { +using namespace rex::system; +using namespace rex::system::xam; + +struct XTASK_MESSAGE { + be unknown_00; + be unknown_04; + be unknown_08; + be callback_arg_ptr; + be event_handle; + be unknown_14; + be task_handle; +}; +static_assert_size(XTASK_MESSAGE, 0x1C); + +u32 XamTaskSchedule_entry(mapped_void callback, ppc_ptr_t message, + mapped_u32 unknown, mapped_u32 handle_ptr) { + // TODO(gibbed): figure out what this is for + *handle_ptr = 12345; + + uint32_t stack_size = REX_KERNEL_STATE()->GetExecutableModule()->stack_size(); + + // Stack must be aligned to 16kb pages + stack_size = std::max((uint32_t)0x4000, ((stack_size + 0xFFF) & 0xFFFFF000)); + + auto thread = + object_ref(new XThread(REX_KERNEL_STATE(), stack_size, 0, callback.guest_address(), + message.guest_address(), 0, true)); + + X_STATUS result = thread->Create(); + + if (XFAILED(result)) { + // Failed! + REXKRNL_ERROR("XAM task creation failed: {:08X}", result); + return result; + } + + REXKRNL_DEBUG("XAM task ({:08X}) scheduled asynchronously", callback.guest_address()); + + return X_STATUS_SUCCESS; +} + +u32 XamTaskShouldExit_entry(u32 r3) { + return 0; +} + +u32 XamTaskCloseHandle_entry(u32 handle) { + REXKRNL_DEBUG("XamTaskCloseHandle({:#x}) - stub", (uint32_t)handle); + return X_STATUS_SUCCESS; +} + +} // namespace xam +} // namespace kernel +} // namespace rex + +REX_EXPORT(__imp__XamTaskSchedule, rex::kernel::xam::XamTaskSchedule_entry) +REX_EXPORT(__imp__XamTaskShouldExit, rex::kernel::xam::XamTaskShouldExit_entry) +REX_EXPORT(__imp__XamTaskCloseHandle, rex::kernel::xam::XamTaskCloseHandle_entry) + +REX_EXPORT_STUB(__imp__XamTaskCancel); +REX_EXPORT_STUB(__imp__XamTaskCancelWaitAndCloseWaitTask); +REX_EXPORT_STUB(__imp__XamTaskCreateQueue); +REX_EXPORT_STUB(__imp__XamTaskCreateQueueEx); +REX_EXPORT_STUB(__imp__XamTaskGetAttributes); +REX_EXPORT_STUB(__imp__XamTaskGetCompletionStatus); +REX_EXPORT_STUB(__imp__XamTaskGetCurrentTask); +REX_EXPORT_STUB(__imp__XamTaskGetStatus); +REX_EXPORT_STUB(__imp__XamTaskModify); +REX_EXPORT_STUB(__imp__XamTaskQueryProperty); +REX_EXPORT_STUB(__imp__XamTaskReschedule); +REX_EXPORT_STUB(__imp__XamTaskSetCancelSubTasks); +REX_EXPORT_STUB(__imp__XamTaskWaitOnCompletion); diff --git a/src/kernel/xam/xam_ui.cpp b/src/kernel/xam/xam_ui.cpp new file mode 100644 index 0000000..edb3b3d --- /dev/null +++ b/src/kernel/xam/xam_ui.cpp @@ -0,0 +1,694 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include + +#include + +REXCVAR_DEFINE_BOOL(headless, false, "Kernel", + "Don't display any UI, using defaults for prompts as needed"); +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex { +namespace kernel { +namespace xam { +using namespace rex::system; + +// TODO(gibbed): This is all one giant WIP that seems to work better than the +// previous immediate synchronous completion of dialogs. +// +// The deferred execution of dialog handling is done in such a way that there is +// a pre-, peri- (completion), and post- callback steps. +// +// pre(); +// result = completion(); +// CompleteOverlapped(result); +// post(); +// +// There are games that are batshit insane enough to wait for the X_OVERLAPPED +// to be completed (ie not X_ERROR_PENDING) before creating a listener to +// receive a notification, which is why we have distinct pre- and post- steps. +// +// We deliberately delay the XN_SYS_UI = false notification to give games time +// to create a listener (if they're insane enough do this). + +extern std::atomic xam_dialogs_shown_; + +class XamDialog : public rex::ui::ImGuiDialog { + public: + void set_close_callback(std::function close_callback) { + close_callback_ = close_callback; + } + + protected: + XamDialog(rex::ui::ImGuiDrawer* imgui_drawer) : rex::ui::ImGuiDialog(imgui_drawer) {} + + void OnClose() override { + if (close_callback_) { + close_callback_(); + } + } + + private: + std::function close_callback_ = nullptr; +}; + +template +X_RESULT xeXamDispatchDialog(T* dialog, std::function close_callback, + uint32_t overlapped) { + auto pre = []() { + // Broadcast XN_SYS_UI = true + REX_KERNEL_STATE()->BroadcastNotification(0x9, true); + }; + auto run = [dialog, close_callback]() -> X_RESULT { + X_RESULT result; + dialog->set_close_callback( + [&dialog, &result, &close_callback]() { result = close_callback(dialog); }); + rex::thread::Fence fence; + rex::ui::WindowedAppContext* app_context = REX_KERNEL_STATE()->emulator()->app_context(); + if (app_context && + app_context->CallInUIThreadSynchronous([&dialog, &fence]() { dialog->Then(&fence); })) { + ++xam_dialogs_shown_; + fence.Wait(); + --xam_dialogs_shown_; + } else { + delete dialog; + } + // dialog should be deleted at this point! + return result; + }; + auto post = []() { + rex::thread::Sleep(std::chrono::milliseconds(100)); + // Broadcast XN_SYS_UI = false + REX_KERNEL_STATE()->BroadcastNotification(0x9, false); + }; + if (!overlapped) { + pre(); + auto result = run(); + post(); + return result; + } else { + REX_KERNEL_STATE()->CompleteOverlappedDeferred(run, overlapped, pre, post); + return X_ERROR_IO_PENDING; + } +} + +template +X_RESULT xeXamDispatchDialogEx(T* dialog, + std::function close_callback, + uint32_t overlapped) { + auto pre = []() { + // Broadcast XN_SYS_UI = true + REX_KERNEL_STATE()->BroadcastNotification(0x9, true); + }; + auto run = [dialog, close_callback](uint32_t& extended_error, uint32_t& length) -> X_RESULT { + rex::ui::WindowedAppContext* app_context = REX_KERNEL_STATE()->emulator()->app_context(); + X_RESULT result; + dialog->set_close_callback([&dialog, &result, &extended_error, &length, &close_callback]() { + result = close_callback(dialog, extended_error, length); + }); + rex::thread::Fence fence; + if (app_context && + app_context->CallInUIThreadSynchronous([&dialog, &fence]() { dialog->Then(&fence); })) { + ++xam_dialogs_shown_; + fence.Wait(); + --xam_dialogs_shown_; + } else { + delete dialog; + } + // dialog should be deleted at this point! + return result; + }; + auto post = []() { + rex::thread::Sleep(std::chrono::milliseconds(100)); + // Broadcast XN_SYS_UI = false + REX_KERNEL_STATE()->BroadcastNotification(0x9, false); + }; + if (!overlapped) { + pre(); + uint32_t extended_error, length; + auto result = run(extended_error, length); + post(); + // TODO(gibbed): do something with extended_error/length? + return result; + } else { + REX_KERNEL_STATE()->CompleteOverlappedDeferredEx(run, overlapped, pre, post); + return X_ERROR_IO_PENDING; + } +} + +X_RESULT xeXamDispatchHeadless(std::function run_callback, uint32_t overlapped) { + auto pre = []() { + REXKRNL_DEBUG("xeXamDispatchHeadless: Broadcasting XN_SYS_UI = true"); + // Broadcast XN_SYS_UI = true + REX_KERNEL_STATE()->BroadcastNotification(0x9, true); + }; + auto post = []() { + rex::thread::Sleep(std::chrono::milliseconds(100)); + REXKRNL_DEBUG("xeXamDispatchHeadless: Broadcasting XN_SYS_UI = false"); + // Broadcast XN_SYS_UI = false + REX_KERNEL_STATE()->BroadcastNotification(0x9, false); + }; + if (!overlapped) { + pre(); + auto result = run_callback(); + post(); + return result; + } else { + REX_KERNEL_STATE()->CompleteOverlappedDeferred(run_callback, overlapped, pre, post); + return X_ERROR_IO_PENDING; + } +} + +X_RESULT xeXamDispatchHeadlessEx(std::function run_callback, + uint32_t overlapped) { + auto pre = []() { + // Broadcast XN_SYS_UI = true + REX_KERNEL_STATE()->BroadcastNotification(0x9, true); + }; + auto post = []() { + rex::thread::Sleep(std::chrono::milliseconds(100)); + // Broadcast XN_SYS_UI = false + REX_KERNEL_STATE()->BroadcastNotification(0x9, false); + }; + if (!overlapped) { + pre(); + uint32_t extended_error, length; + auto result = run_callback(extended_error, length); + post(); + // TODO(gibbed): do something with extended_error/length? + return result; + } else { + REX_KERNEL_STATE()->CompleteOverlappedDeferredEx(run_callback, overlapped, pre, post); + return X_ERROR_IO_PENDING; + } +} + +u32 XamIsUIActive_entry() { + return xeXamIsUIActive(); +} + +class MessageBoxDialog : public XamDialog { + public: + MessageBoxDialog(rex::ui::ImGuiDrawer* imgui_drawer, std::string title, std::string description, + std::vector buttons, uint32_t default_button) + : XamDialog(imgui_drawer), + title_(title), + description_(description), + buttons_(std::move(buttons)), + default_button_(default_button), + chosen_button_(default_button) { + if (!title_.size()) { + title_ = "Message Box"; + } + } + + uint32_t chosen_button() const { return chosen_button_; } + + void OnDraw(ImGuiIO& io) override { + bool first_draw = false; + if (!has_opened_) { + ImGui::OpenPopup(title_.c_str()); + has_opened_ = true; + first_draw = true; + } + if (ImGui::BeginPopupModal(title_.c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { + if (description_.size()) { + ImGui::Text("%s", description_.c_str()); + } + if (first_draw) { + ImGui::SetKeyboardFocusHere(); + } + for (size_t i = 0; i < buttons_.size(); ++i) { + if (ImGui::Button(buttons_[i].c_str())) { + chosen_button_ = static_cast(i); + ImGui::CloseCurrentPopup(); + Close(); + } + ImGui::SameLine(); + } + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::EndPopup(); + } else { + Close(); + } + } + + private: + bool has_opened_ = false; + std::string title_; + std::string description_; + std::vector buttons_; + uint32_t default_button_ = 0; + uint32_t chosen_button_ = 0; +}; + +// https://www.se7ensins.com/forums/threads/working-xshowmessageboxui.844116/ +u32 XamShowMessageBoxUI_entry(u32 user_index, mapped_wstring title_ptr, mapped_wstring text_ptr, + u32 button_count, mapped_u32 button_ptrs, u32 active_button, + u32 flags, mapped_u32 result_ptr, mapped_void overlapped) { + REXKRNL_DEBUG( + "XamShowMessageBoxUI({:08X}, {:08X}, {:08X}, {:08X}, {:08X}, {:08X}, {:08X}, {:08X}, {:08X})", + uint32_t(user_index), title_ptr.guest_address(), text_ptr.guest_address(), + uint32_t(button_count), button_ptrs.guest_address(), uint32_t(active_button), uint32_t(flags), + result_ptr.guest_address(), overlapped.guest_address()); + std::string title; + if (title_ptr) { + title = rex::string::to_utf8(title_ptr.value()); + } else { + title = ""; // TODO(gibbed): default title based on flags? + } + + std::vector buttons; + for (uint32_t i = 0; i < button_count; ++i) { + uint32_t button_ptr = button_ptrs[i]; + auto button = rex::memory::load_and_swap( + REX_KERNEL_MEMORY()->TranslateVirtual(button_ptr)); + buttons.push_back(rex::string::to_utf8(button)); + } + + X_RESULT result; + if (REXCVAR_GET(headless)) { + // Auto-pick the focused button. + auto run = [result_ptr, active_button]() -> X_RESULT { + *result_ptr = static_cast(active_button); + return X_ERROR_SUCCESS; + }; + result = xeXamDispatchHeadless(run, overlapped.guest_address()); + } else { + // TODO(benvanik): setup icon states. + switch (flags & 0xF) { + case 0: + // config.pszMainIcon = nullptr; + break; + case 1: + // config.pszMainIcon = TD_ERROR_ICON; + break; + case 2: + // config.pszMainIcon = TD_WARNING_ICON; + break; + case 3: + // config.pszMainIcon = TD_INFORMATION_ICON; + break; + } + auto close = [result_ptr](MessageBoxDialog* dialog) -> X_RESULT { + *result_ptr = dialog->chosen_button(); + return X_ERROR_SUCCESS; + }; + const Runtime* emulator = REX_KERNEL_STATE()->emulator(); + ui::ImGuiDrawer* imgui_drawer = emulator->imgui_drawer(); + if (imgui_drawer) { + result = xeXamDispatchDialog( + new MessageBoxDialog(imgui_drawer, title, rex::string::to_utf8(text_ptr.value()), buttons, + active_button), + close, overlapped.guest_address()); + } else { + // Fallback to headless if no drawer available + auto run = [result_ptr, active_button]() -> X_RESULT { + *result_ptr = static_cast(active_button); + return X_ERROR_SUCCESS; + }; + result = xeXamDispatchHeadless(run, overlapped.guest_address()); + } + } + return result; +} + +class KeyboardInputDialog : public XamDialog { + public: + KeyboardInputDialog(rex::ui::ImGuiDrawer* imgui_drawer, std::string title, + std::string description, std::string default_text, size_t max_length) + : XamDialog(imgui_drawer), + title_(title), + description_(description), + default_text_(default_text), + max_length_(max_length), + text_buffer_() { + if (!title_.size()) { + if (!description_.size()) { + title_ = "Keyboard Input"; + } else { + title_ = description_; + description_ = ""; + } + } + text_ = default_text; + text_buffer_.resize(max_length); + rex::string::util_copy_truncating(text_buffer_.data(), default_text_, text_buffer_.size()); + } + + const std::string& text() const { return text_; } + bool cancelled() const { return cancelled_; } + + void OnDraw(ImGuiIO& io) override { + bool first_draw = false; + if (!has_opened_) { + ImGui::OpenPopup(title_.c_str()); + has_opened_ = true; + first_draw = true; + } + if (ImGui::BeginPopupModal(title_.c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { + if (description_.size()) { + ImGui::TextWrapped("%s", description_.c_str()); + } + if (first_draw) { + ImGui::SetKeyboardFocusHere(); + } + if (ImGui::InputText("##body", text_buffer_.data(), text_buffer_.size(), + ImGuiInputTextFlags_EnterReturnsTrue)) { + text_ = std::string(text_buffer_.data(), text_buffer_.size()); + cancelled_ = false; + ImGui::CloseCurrentPopup(); + Close(); + } + if (ImGui::Button("OK")) { + text_ = std::string(text_buffer_.data(), text_buffer_.size()); + cancelled_ = false; + ImGui::CloseCurrentPopup(); + Close(); + } + ImGui::SameLine(); + if (ImGui::Button("Cancel")) { + text_ = ""; + cancelled_ = true; + ImGui::CloseCurrentPopup(); + Close(); + } + ImGui::Spacing(); + ImGui::EndPopup(); + } else { + Close(); + } + } + + private: + bool has_opened_ = false; + std::string title_; + std::string description_; + std::string default_text_; + size_t max_length_ = 0; + std::vector text_buffer_; + std::string text_ = ""; + bool cancelled_ = true; +}; + +// https://www.se7ensins.com/forums/threads/release-how-to-use-xshowkeyboardui-release.906568/ +u32 XamShowKeyboardUI_entry(u32 user_index, u32 flags, mapped_wstring default_text, + mapped_wstring title, mapped_wstring description, mapped_wstring buffer, + u32 buffer_length, mapped_void overlapped) { + REXKRNL_DEBUG("XamShowKeyboardUI({:08X}, {:08X}, {:08X}, {:08X}, {:08X}, {:08X}, {:08X}, {:08X})", + uint32_t(user_index), uint32_t(flags), default_text.guest_address(), + title.guest_address(), description.guest_address(), buffer.guest_address(), + uint32_t(buffer_length), overlapped.guest_address()); + if (!buffer) { + return X_ERROR_INVALID_PARAMETER; + } + + assert_true(overlapped.guest_address() != 0); + + auto buffer_size = static_cast(buffer_length) * 2; + + X_RESULT result; + if (REXCVAR_GET(headless)) { + auto run = [default_text, buffer, buffer_length, buffer_size]() -> X_RESULT { + // Redirect default_text back into the buffer. + if (!default_text) { + std::memset(buffer, 0, buffer_size); + } else { + rex::string::util_copy_and_swap_truncating(buffer, default_text.value(), buffer_length); + } + return X_ERROR_SUCCESS; + }; + result = xeXamDispatchHeadless(run, overlapped.guest_address()); + } else { + auto close = [buffer, buffer_length](KeyboardInputDialog* dialog, uint32_t& extended_error, + uint32_t& length) -> X_RESULT { + if (dialog->cancelled()) { + extended_error = X_ERROR_CANCELLED; + length = 0; + return X_ERROR_SUCCESS; + } else { + // Zero the output buffer. + auto text = rex::string::to_utf16(dialog->text()); + rex::string::util_copy_and_swap_truncating(buffer, text, buffer_length); + extended_error = X_ERROR_SUCCESS; + length = 0; + return X_ERROR_SUCCESS; + } + }; + const Runtime* emulator = REX_KERNEL_STATE()->emulator(); + ui::ImGuiDrawer* imgui_drawer = emulator->imgui_drawer(); + + // Read and convert title/description/default_text from guest memory as utf16 to utf8 strings + std::string title_str = title + ? rex::string::to_utf8(rex::memory::load_and_swap( + REX_KERNEL_MEMORY()->TranslateVirtual(title.guest_address()))) + : ""; + std::string desc_str = + description ? rex::string::to_utf8(rex::memory::load_and_swap( + REX_KERNEL_MEMORY()->TranslateVirtual(description.guest_address()))) + : ""; + std::string def_text_str = + default_text ? rex::string::to_utf8(rex::memory::load_and_swap( + REX_KERNEL_MEMORY()->TranslateVirtual(default_text.guest_address()))) + : ""; + + if (imgui_drawer) { + uint32_t buffer_length_safe = buffer_length + 1; // +1 for null terminator, just in case + result = xeXamDispatchDialogEx( + new KeyboardInputDialog(imgui_drawer, title_str, desc_str, def_text_str, + buffer_length_safe), + close, overlapped.guest_address()); + } else { + // Fallback to headless + auto run = [default_text, buffer, buffer_length, buffer_size]() -> X_RESULT { + if (!default_text) { + std::memset(buffer, 0, buffer_size); + } else { + rex::string::util_copy_and_swap_truncating(buffer, default_text.value(), buffer_length); + } + return X_ERROR_SUCCESS; + }; + result = xeXamDispatchHeadless(run, overlapped.guest_address()); + } + } + return result; +} + +u32 XamShowDeviceSelectorUI_entry(u32 user_index, u32 content_type, u32 content_flags, + u64 total_requested, mapped_u32 device_id_ptr, + mapped_void overlapped) { + REXKRNL_DEBUG("XamShowDeviceSelectorUI({:08X}, {:08X}, {:08X}, {:016X}, {:08X}, {:08X})", + uint32_t(user_index), uint32_t(content_type), uint32_t(content_flags), + uint64_t(total_requested), device_id_ptr.guest_address(), + overlapped.guest_address()); + return xeXamDispatchHeadless( + [device_id_ptr]() -> X_RESULT { + // NOTE: 0x00000001 is our dummy device ID from xam_content.cc + *device_id_ptr = 0x00000001; + return X_ERROR_SUCCESS; + }, + overlapped.guest_address()); +} + +void XamShowDirtyDiscErrorUI_entry(u32 user_index) { + REXKRNL_ERROR("XamShowDirtyDiscErrorUI called! user_index={}", uint32_t(user_index)); + REXKRNL_ERROR("This indicates a disc/file read error - check that all game files exist"); + + const Runtime* emulator = REX_KERNEL_STATE()->emulator(); + ui::ImGuiDrawer* imgui_drawer = emulator->imgui_drawer(); + if (imgui_drawer) { + xeXamDispatchDialog( + new MessageBoxDialog(imgui_drawer, "Disc Read Error", + "There's been an issue reading content from the game disc.\nThis is " + "likely caused by bad or unimplemented file IO calls.", + {"OK"}, 0), + [](MessageBoxDialog*) -> X_RESULT { return X_ERROR_SUCCESS; }, 0); + } else { + // No UI available - log prominently and pause to let user see the error + REXKRNL_ERROR("==========================================="); + REXKRNL_ERROR("FATAL: Disc Read Error (no UI to display)"); + REXKRNL_ERROR("Check that all game content files are present"); + REXKRNL_ERROR("Missing files or bad mounts cause this error"); + REXKRNL_ERROR("==========================================="); + } + // This is death, and should never return. + // TODO(benvanik): cleaner exit. + exit(1); +} + +u32 XamShowPartyUI_entry(u32 r3, u32 r4) { + return X_ERROR_FUNCTION_FAILED; +} + +u32 XamShowCommunitySessionsUI_entry(u32 r3, u32 r4) { + return X_ERROR_FUNCTION_FAILED; +} + +uint32_t XamShowMessageBoxUIEx_entry() { + // TODO(tomc): implement properly + static bool warned = false; + if (!warned) { + REXKRNL_WARN("[STUB] XamShowMessageBoxUIEx - not implemented"); + warned = true; + } + return 0; +} + +} // namespace xam +} // namespace kernel +} // namespace rex + +REX_EXPORT(__imp__XamIsUIActive, rex::kernel::xam::XamIsUIActive_entry) +REX_EXPORT(__imp__XamShowMessageBoxUI, rex::kernel::xam::XamShowMessageBoxUI_entry) +REX_EXPORT(__imp__XamShowKeyboardUI, rex::kernel::xam::XamShowKeyboardUI_entry) +REX_EXPORT(__imp__XamShowDeviceSelectorUI, rex::kernel::xam::XamShowDeviceSelectorUI_entry) +REX_EXPORT(__imp__XamShowDirtyDiscErrorUI, rex::kernel::xam::XamShowDirtyDiscErrorUI_entry) +REX_EXPORT(__imp__XamShowPartyUI, rex::kernel::xam::XamShowPartyUI_entry) +REX_EXPORT(__imp__XamShowCommunitySessionsUI, rex::kernel::xam::XamShowCommunitySessionsUI_entry) +REX_EXPORT(__imp__XamShowMessageBoxUIEx, rex::kernel::xam::XamShowMessageBoxUIEx_entry) + +REX_EXPORT_STUB(__imp__XamIsGuideDisabled); +REX_EXPORT_STUB(__imp__XamIsMessageBoxActive); +REX_EXPORT_STUB(__imp__XamIsNuiUIActive); +REX_EXPORT_STUB(__imp__XamIsSysUiInvokedByTitle); +REX_EXPORT_STUB(__imp__XamIsSysUiInvokedByXenonButton); +REX_EXPORT_STUB(__imp__XamIsUIThread); +REX_EXPORT_STUB(__imp__XamNavigate); +REX_EXPORT_STUB(__imp__XamNavigateBack); +REX_EXPORT_STUB(__imp__XamOverrideHudOpenType); +REX_EXPORT_STUB(__imp__XamShowAchievementDetailsUI); +REX_EXPORT_STUB(__imp__XamShowAchievementsUI); +REX_EXPORT_STUB(__imp__XamShowAchievementsUIEx); +REX_EXPORT_STUB(__imp__XamShowAndWaitForMessageBoxEx); +REX_EXPORT_STUB(__imp__XamShowAvatarAwardGamesUI); +REX_EXPORT_STUB(__imp__XamShowAvatarAwardsUI); +REX_EXPORT_STUB(__imp__XamShowAvatarMiniCreatorUI); +REX_EXPORT_STUB(__imp__XamShowBadDiscErrorUI); +REX_EXPORT_STUB(__imp__XamShowBeaconsUI); +REX_EXPORT_STUB(__imp__XamShowBrandedKeyboardUI); +REX_EXPORT_STUB(__imp__XamShowChangeGamerTileUI); +REX_EXPORT_STUB(__imp__XamShowComplaintUI); +REX_EXPORT_STUB(__imp__XamShowCreateProfileUI); +REX_EXPORT_STUB(__imp__XamShowCreateProfileUIEx); +REX_EXPORT_STUB(__imp__XamShowCsvTransitionUI); +REX_EXPORT_STUB(__imp__XamShowCustomMessageComposeUI); +REX_EXPORT_STUB(__imp__XamShowCustomPlayerListUI); +REX_EXPORT_STUB(__imp__XamShowDirectAcquireUI); +REX_EXPORT_STUB(__imp__XamShowEditProfileUI); +REX_EXPORT_STUB(__imp__XamShowFirstRunWelcomeUI); +REX_EXPORT_STUB(__imp__XamShowFitnessBodyProfileUI); +REX_EXPORT_STUB(__imp__XamShowFitnessClearUI); +REX_EXPORT_STUB(__imp__XamShowFitnessWarnAboutPrivacyUI); +REX_EXPORT_STUB(__imp__XamShowFitnessWarnAboutTimeUI); +REX_EXPORT_STUB(__imp__XamShowFofUI); +REX_EXPORT_STUB(__imp__XamShowForcedNameChangeUI); +REX_EXPORT_STUB(__imp__XamShowFriendRequestUI); +REX_EXPORT_STUB(__imp__XamShowFriendsUI); +REX_EXPORT_STUB(__imp__XamShowFriendsUIp); +REX_EXPORT_STUB(__imp__XamShowGameInviteUI); +REX_EXPORT_STUB(__imp__XamShowGameVoiceChannelUI); +REX_EXPORT_STUB(__imp__XamShowGamerCardUI); +REX_EXPORT_STUB(__imp__XamShowGamerCardUIForXUID); +REX_EXPORT_STUB(__imp__XamShowGamerCardUIForXUIDp); +REX_EXPORT_STUB(__imp__XamShowGamesUI); +REX_EXPORT_STUB(__imp__XamShowGenericOnlineAppUI); +REX_EXPORT_STUB(__imp__XamShowGoldUpgradeUI); +REX_EXPORT_STUB(__imp__XamShowGraduateUserUI); +REX_EXPORT_STUB(__imp__XamShowGuideUI); +REX_EXPORT_STUB(__imp__XamShowJoinPartyUI); +REX_EXPORT_STUB(__imp__XamShowJoinSessionByIdInProgressUI); +REX_EXPORT_STUB(__imp__XamShowJoinSessionInProgressUI); +REX_EXPORT_STUB(__imp__XamShowKeyboardUIMessenger); +REX_EXPORT_STUB(__imp__XamShowLiveSignupUI); +REX_EXPORT_STUB(__imp__XamShowLiveUpsellUI); +REX_EXPORT_STUB(__imp__XamShowLiveUpsellUIEx); +REX_EXPORT_STUB(__imp__XamShowMarketplaceDownloadItemsUI); +REX_EXPORT_STUB(__imp__XamShowMarketplaceGetOrderReceipts); +REX_EXPORT_STUB(__imp__XamShowMarketplacePurchaseOrderUI); +REX_EXPORT_STUB(__imp__XamShowMarketplacePurchaseOrderUIEx); +REX_EXPORT_STUB(__imp__XamShowMarketplaceUI); +REX_EXPORT_STUB(__imp__XamShowMarketplaceUIEx); +REX_EXPORT_STUB(__imp__XamShowMessageBox); +REX_EXPORT_STUB(__imp__XamShowMessageComposeUI); +REX_EXPORT_STUB(__imp__XamShowMessagesUI); +REX_EXPORT_STUB(__imp__XamShowMessagesUIEx); +REX_EXPORT_STUB(__imp__XamShowMessengerUI); +REX_EXPORT_STUB(__imp__XamShowMultiplayerUpgradeUI); +REX_EXPORT_STUB(__imp__XamShowNetworkStorageSyncUI); +REX_EXPORT_STUB(__imp__XamShowNuiAchievementsUI); +REX_EXPORT_STUB(__imp__XamShowNuiCommunitySessionsUI); +REX_EXPORT_STUB(__imp__XamShowNuiControllerRequiredUI); +REX_EXPORT_STUB(__imp__XamShowNuiDeviceSelectorUI); +REX_EXPORT_STUB(__imp__XamShowNuiDirtyDiscErrorUI); +REX_EXPORT_STUB(__imp__XamShowNuiFriendRequestUI); +REX_EXPORT_STUB(__imp__XamShowNuiFriendsUI); +REX_EXPORT_STUB(__imp__XamShowNuiGameInviteUI); +REX_EXPORT_STUB(__imp__XamShowNuiGamerCardUIForXUID); +REX_EXPORT_STUB(__imp__XamShowNuiGamesUI); +REX_EXPORT_STUB(__imp__XamShowNuiGuideUI); +REX_EXPORT_STUB(__imp__XamShowNuiHardwareRequiredUI); +REX_EXPORT_STUB(__imp__XamShowNuiJoinSessionInProgressUI); +REX_EXPORT_STUB(__imp__XamShowNuiMarketplaceDownloadItemsUI); +REX_EXPORT_STUB(__imp__XamShowNuiMarketplaceUI); +REX_EXPORT_STUB(__imp__XamShowNuiMessageBoxUI); +REX_EXPORT_STUB(__imp__XamShowNuiMessagesUI); +REX_EXPORT_STUB(__imp__XamShowNuiPartyUI); +REX_EXPORT_STUB(__imp__XamShowNuiSigninUI); +REX_EXPORT_STUB(__imp__XamShowNuiVideoRichPresenceUI); +REX_EXPORT_STUB(__imp__XamShowOptionalMediaUpdateRequiredUI); +REX_EXPORT_STUB(__imp__XamShowOptionalMediaUpdateRequiredUIEx); +REX_EXPORT_STUB(__imp__XamShowOptionsUI); +REX_EXPORT_STUB(__imp__XamShowPamUI); +REX_EXPORT_STUB(__imp__XamShowPartyInviteUI); +REX_EXPORT_STUB(__imp__XamShowPartyJoinInProgressUI); +REX_EXPORT_STUB(__imp__XamShowPasscodeVerifyUI); +REX_EXPORT_STUB(__imp__XamShowPasscodeVerifyUIEx); +REX_EXPORT_STUB(__imp__XamShowPaymentOptionsUI); +REX_EXPORT_STUB(__imp__XamShowPersonalizationUI); +REX_EXPORT_STUB(__imp__XamShowPlayerReviewUI); +REX_EXPORT_STUB(__imp__XamShowPlayersUI); +REX_EXPORT_STUB(__imp__XamShowPrivateChatInviteUI); +REX_EXPORT_STUB(__imp__XamShowQuickChatUI); +REX_EXPORT_STUB(__imp__XamShowQuickChatUIp); +REX_EXPORT_STUB(__imp__XamShowQuickLaunchUI); +REX_EXPORT_STUB(__imp__XamShowRecentMessageUI); +REX_EXPORT_STUB(__imp__XamShowRecentMessageUIEx); +REX_EXPORT_STUB(__imp__XamShowReputationUI); +REX_EXPORT_STUB(__imp__XamShowSigninUIEx); +REX_EXPORT_STUB(__imp__XamShowSigninUIp); +REX_EXPORT_STUB(__imp__XamShowSignupCreditCardUI); +REX_EXPORT_STUB(__imp__XamShowSocialPostUI); +REX_EXPORT_STUB(__imp__XamShowStorePickerUI); +REX_EXPORT_STUB(__imp__XamShowTFAUI); +REX_EXPORT_STUB(__imp__XamShowTermsOfUseUI); +REX_EXPORT_STUB(__imp__XamShowUpdaterUI); +REX_EXPORT_STUB(__imp__XamShowVideoChatInviteUI); +REX_EXPORT_STUB(__imp__XamShowVideoRichPresenceUI); +REX_EXPORT_STUB(__imp__XamShowVoiceMailUI); +REX_EXPORT_STUB(__imp__XamShowVoiceSettingsUI); +REX_EXPORT_STUB(__imp__XamShowWhatsOnUI); +REX_EXPORT_STUB(__imp__XamShowWordRegisterUI); +REX_EXPORT_STUB(__imp__XamSysUiDisableAutoClose); diff --git a/src/kernel/xam/xam_user.cpp b/src/kernel/xam/xam_user.cpp new file mode 100644 index 0000000..a016440 --- /dev/null +++ b/src/kernel/xam/xam_user.cpp @@ -0,0 +1,785 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_UINT32(user_language, 1, "Kernel", "User's language ID"); + +namespace rex { +namespace kernel { +namespace xam { +using namespace rex::system; +using namespace rex::system::xam; + +i32 XamUserGetXUID_entry(u32 user_index, u32 type_mask, mapped_u64 xuid_ptr) { + assert_true(type_mask == 1 || type_mask == 2 || type_mask == 3 || type_mask == 4 || + type_mask == 7); + if (!xuid_ptr) { + return X_E_INVALIDARG; + } + uint32_t result = X_E_NO_SUCH_USER; + uint64_t xuid = 0; + if (user_index < 4) { + if (user_index == 0) { + const auto& user_profile = REX_KERNEL_STATE()->user_profile(); + auto type = user_profile->type() & type_mask; + if (type & (2 | 4)) { + // maybe online profile? + xuid = user_profile->xuid(); + result = X_E_SUCCESS; + } else if (type & 1) { + // maybe offline profile? + xuid = user_profile->xuid(); + result = X_E_SUCCESS; + } + } + } else { + result = X_E_INVALIDARG; + } + *xuid_ptr = xuid; + return result; +} + +u32 XamUserGetSigninState_entry(u32 user_index) { + uint32_t signin_state = 0; + if (user_index < 4) { + if (user_index == 0) { + const auto& user_profile = REX_KERNEL_STATE()->user_profile(); + signin_state = user_profile->signin_state(); + } + } + return signin_state; +} + +typedef struct { + rex::be xuid; + rex::be unk08; // maybe zero? + rex::be signin_state; + rex::be unk10; // ? + rex::be unk14; // ? + char name[16]; +} X_USER_SIGNIN_INFO; +static_assert_size(X_USER_SIGNIN_INFO, 40); + +i32 XamUserGetSigninInfo_entry(u32 user_index, u32 flags, ppc_ptr_t info) { + if (!info) { + return X_E_INVALIDARG; + } + + std::memset(info, 0, sizeof(X_USER_SIGNIN_INFO)); + if (user_index) { + return X_E_NO_SUCH_USER; + } + + const auto& user_profile = REX_KERNEL_STATE()->user_profile(); + info->xuid = user_profile->xuid(); + info->signin_state = user_profile->signin_state(); + rex::string::util_copy_truncating(info->name, user_profile->name(), rex::countof(info->name)); + return X_E_SUCCESS; +} + +u32 XamUserGetName_entry(u32 user_index, mapped_string buffer, u32 buffer_len) { + if (user_index >= 4) { + return X_E_INVALIDARG; + } + + if (user_index) { + return X_E_NO_SUCH_USER; + } + + const auto& user_profile = REX_KERNEL_STATE()->user_profile(); + const auto& user_name = user_profile->name(); + rex::string::util_copy_truncating(buffer, user_name, std::min(buffer_len, uint32_t(16))); + return X_E_SUCCESS; +} + +u32 XamUserGetGamerTag_entry(u32 user_index, mapped_wstring buffer, u32 buffer_len) { + if (user_index >= 4) { + return X_E_INVALIDARG; + } + + if (user_index) { + return X_E_NO_SUCH_USER; + } + + if (!buffer || buffer_len < 16) { + return X_E_INVALIDARG; + } + + const auto& user_profile = REX_KERNEL_STATE()->user_profile(); + auto user_name = rex::string::to_utf16(user_profile->name()); + rex::string::util_copy_and_swap_truncating(buffer, user_name, std::min(buffer_len, uint32_t(16))); + return X_E_SUCCESS; +} + +typedef struct { + rex::be setting_count; + rex::be settings_ptr; +} X_USER_READ_PROFILE_SETTINGS; +static_assert_size(X_USER_READ_PROFILE_SETTINGS, 8); + +// https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/Generic/xboxtools.cpp +uint32_t XamUserReadProfileSettingsEx(uint32_t title_id, uint32_t user_index, uint32_t xuid_count, + be* xuids, uint32_t setting_count, + be* setting_ids, uint32_t unk, + be* buffer_size_ptr, uint8_t* buffer, + XAM_OVERLAPPED* overlapped) { + if (!xuid_count) { + assert_null(xuids); + } else { + assert_true(xuid_count == 1); + assert_not_null(xuids); + // TODO(gibbed): allow proper lookup of arbitrary XUIDs + const auto& user_profile = REX_KERNEL_STATE()->user_profile(); + assert_true(static_cast(xuids[0]) == user_profile->xuid()); + // TODO(gibbed): we assert here, but in case a title passes xuid_count > 1 + // until it's implemented for release builds... + xuid_count = 1; + } + assert_zero(unk); // probably flags + + // must have at least 1 to 32 settings + if (setting_count < 1 || setting_count > 32) { + return X_ERROR_INVALID_PARAMETER; + } + + // buffer size pointer must be valid + if (!buffer_size_ptr) { + return X_ERROR_INVALID_PARAMETER; + } + + // if buffer size is non-zero, buffer pointer must be valid + auto buffer_size = static_cast(*buffer_size_ptr); + if (buffer_size && !buffer) { + return X_ERROR_INVALID_PARAMETER; + } + + uint32_t needed_header_size = 0; + uint32_t needed_data_size = 0; + for (uint32_t i = 0; i < setting_count; ++i) { + needed_header_size += sizeof(X_USER_PROFILE_SETTING); + UserProfile::Setting::Key setting_key; + setting_key.value = static_cast(setting_ids[i]); + switch (static_cast(setting_key.type)) { + case UserProfile::Setting::Type::WSTRING: + case UserProfile::Setting::Type::BINARY: + needed_data_size += setting_key.size; + break; + default: + break; + } + } + if (xuids) { + needed_header_size *= xuid_count; + needed_data_size *= xuid_count; + } + needed_header_size += sizeof(X_USER_READ_PROFILE_SETTINGS); + + uint32_t needed_size = needed_header_size + needed_data_size; + if (!buffer || buffer_size < needed_size) { + if (!buffer_size) { + *buffer_size_ptr = needed_size; + } + return X_ERROR_INSUFFICIENT_BUFFER; + } + + // Title ID = 0 means us. + // 0xfffe07d1 = profile? + + if (!xuids && user_index) { + // Only support user 0. + if (overlapped) { + REX_KERNEL_STATE()->CompleteOverlappedImmediate( + REX_KERNEL_MEMORY()->HostToGuestVirtual(overlapped), X_ERROR_NO_SUCH_USER); + return X_ERROR_IO_PENDING; + } + return X_ERROR_NO_SUCH_USER; + } + + const auto& user_profile = REX_KERNEL_STATE()->user_profile(); + + // First call asks for size (fill buffer_size_ptr). + // Second call asks for buffer contents with that size. + + // TODO(gibbed): setting validity checking without needing a user profile + // object. + bool any_missing = false; + for (uint32_t i = 0; i < setting_count; ++i) { + auto setting_id = static_cast(setting_ids[i]); + auto setting = user_profile->GetSetting(setting_id); + if (!setting) { + any_missing = true; + REXKRNL_ERROR( + "xeXamUserReadProfileSettingsEx requested unimplemented setting " + "{:08X}", + setting_id); + } + } + if (any_missing) { + // TODO(benvanik): don't fail? most games don't even check! + if (overlapped) { + REX_KERNEL_STATE()->CompleteOverlappedImmediate( + REX_KERNEL_MEMORY()->HostToGuestVirtual(overlapped), X_ERROR_INVALID_PARAMETER); + return X_ERROR_IO_PENDING; + } + return X_ERROR_INVALID_PARAMETER; + } + + auto out_header = reinterpret_cast(buffer); + auto out_setting = reinterpret_cast(&out_header[1]); + out_header->setting_count = static_cast(setting_count); + out_header->settings_ptr = REX_KERNEL_MEMORY()->HostToGuestVirtual(out_setting); + + UserProfile::SettingByteStream out_stream(REX_KERNEL_MEMORY()->HostToGuestVirtual(buffer), buffer, + buffer_size, needed_header_size); + for (uint32_t n = 0; n < setting_count; ++n) { + uint32_t setting_id = setting_ids[n]; + auto setting = user_profile->GetSetting(setting_id); + + std::memset(out_setting, 0, sizeof(X_USER_PROFILE_SETTING)); + out_setting->from = !setting || !setting->is_set ? 0 : setting->is_title_specific() ? 2 : 1; + if (xuids) { + out_setting->xuid = user_profile->xuid(); + } else { + out_setting->user_index = static_cast(user_index); + } + out_setting->setting_id = setting_id; + + if (setting && setting->is_set) { + setting->Append(&out_setting->data, &out_stream); + } + ++out_setting; + } + + if (overlapped) { + REX_KERNEL_STATE()->CompleteOverlappedImmediate( + REX_KERNEL_MEMORY()->HostToGuestVirtual(overlapped), X_ERROR_SUCCESS); + return X_ERROR_IO_PENDING; + } + return X_ERROR_SUCCESS; +} + +u32 XamUserReadProfileSettings_entry(u32 title_id, u32 user_index, u32 xuid_count, mapped_u64 xuids, + u32 setting_count, mapped_u32 setting_ids, + mapped_u32 buffer_size_ptr, mapped_void buffer_ptr, + ppc_ptr_t overlapped) { + return XamUserReadProfileSettingsEx(title_id, user_index, xuid_count, xuids, setting_count, + setting_ids, 0, buffer_size_ptr, buffer_ptr, overlapped); +} + +u32 XamUserReadProfileSettingsEx_entry(u32 title_id, u32 user_index, u32 xuid_count, + mapped_u64 xuids, u32 setting_count, mapped_u32 setting_ids, + mapped_u32 buffer_size_ptr, u32 unk_2, + mapped_void buffer_ptr, + ppc_ptr_t overlapped) { + return XamUserReadProfileSettingsEx(title_id, user_index, xuid_count, xuids, setting_count, + setting_ids, unk_2, buffer_size_ptr, buffer_ptr, overlapped); +} + +u32 XamUserWriteProfileSettings_entry(u32 title_id, u32 user_index, u32 setting_count, + ppc_ptr_t settings, + ppc_ptr_t overlapped) { + if (!setting_count || !settings) { + return X_ERROR_INVALID_PARAMETER; + } + + if (user_index) { + // Only support user 0. + if (overlapped) { + REX_KERNEL_STATE()->CompleteOverlappedImmediate(overlapped.guest_address(), + X_ERROR_NO_SUCH_USER); + return X_ERROR_IO_PENDING; + } + return X_ERROR_NO_SUCH_USER; + } + + // Update and save settings. + const auto& user_profile = REX_KERNEL_STATE()->user_profile(); + + for (uint32_t n = 0; n < setting_count; ++n) { + const X_USER_PROFILE_SETTING& setting = settings[n]; + + auto setting_type = static_cast(setting.data.type); + if (setting_type == UserProfile::Setting::Type::UNSET) { + continue; + } + + REXKRNL_DEBUG( + "XamUserWriteProfileSettings: setting index [{}]:" + " from={} setting_id={:08X} data.type={}", + n, (uint32_t)setting.from, (uint32_t)setting.setting_id, setting.data.type); + + switch (setting_type) { + case UserProfile::Setting::Type::CONTENT: + case UserProfile::Setting::Type::BINARY: { + uint8_t* binary_ptr = REX_KERNEL_MEMORY()->TranslateVirtual(setting.data.binary.ptr); + size_t binary_size = setting.data.binary.size; + std::vector bytes; + if (setting.data.binary.ptr) { + // Copy provided data + bytes.resize(binary_size); + std::memcpy(bytes.data(), binary_ptr, binary_size); + } else { + // Data pointer was NULL, so just fill with zeroes + bytes.resize(binary_size, 0); + } + user_profile->AddSetting( + std::make_unique(setting.setting_id, bytes)); + } break; + case UserProfile::Setting::Type::WSTRING: + case UserProfile::Setting::Type::DOUBLE: + case UserProfile::Setting::Type::FLOAT: + case UserProfile::Setting::Type::INT32: + case UserProfile::Setting::Type::INT64: + case UserProfile::Setting::Type::DATETIME: + default: { + REXKRNL_ERROR("XamUserWriteProfileSettings: Unimplemented data type {}", setting_type); + } break; + }; + } + + if (overlapped) { + REX_KERNEL_STATE()->CompleteOverlappedImmediate(overlapped.guest_address(), X_ERROR_SUCCESS); + return X_ERROR_IO_PENDING; + } + return X_ERROR_SUCCESS; +} + +u32 XamUserCheckPrivilege_entry(u32 user_index, u32 mask, mapped_u32 out_value) { + // checking all users? + if (user_index != 0xFF) { + if (user_index >= 4) { + return X_ERROR_INVALID_PARAMETER; + } + + if (user_index) { + return X_ERROR_NO_SUCH_USER; + } + } + + // If we deny everything, games should hopefully not try to do stuff. + *out_value = 0; + return X_ERROR_SUCCESS; +} + +u32 XamUserContentRestrictionGetFlags_entry(u32 user_index, mapped_u32 out_flags) { + if (user_index) { + return X_ERROR_NO_SUCH_USER; + } + + // No restrictions? + *out_flags = 0; + return X_ERROR_SUCCESS; +} + +u32 XamUserContentRestrictionGetRating_entry(u32 user_index, u32 unk1, mapped_u32 out_unk2, + mapped_u32 out_unk3) { + if (user_index) { + return X_ERROR_NO_SUCH_USER; + } + + // Some games have special case paths for 3F that differ from the failure + // path, so my guess is that's 'don't care'. + *out_unk2 = 0x3F; + *out_unk3 = 0; + return X_ERROR_SUCCESS; +} + +u32 XamUserContentRestrictionCheckAccess_entry(u32 user_index, u32 unk1, u32 unk2, u32 unk3, + u32 unk4, mapped_u32 out_unk5, u32 overlapped_ptr) { + *out_unk5 = 1; + + if (overlapped_ptr) { + // TODO(benvanik): does this need the access arg on it? + REX_KERNEL_STATE()->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); + } + + return X_ERROR_SUCCESS; +} + +u32 XamUserIsOnlineEnabled_entry(u32 user_index) { + return 1; +} + +u32 XamUserGetMembershipTier_entry(u32 user_index) { + if (user_index >= 4) { + return X_ERROR_INVALID_PARAMETER; + } + if (user_index) { + return X_ERROR_NO_SUCH_USER; + } + return 6 /* 6 appears to be Gold */; +} + +u32 XamUserAreUsersFriends_entry(u32 user_index, u32 unk1, u32 unk2, mapped_u32 out_value, + u32 overlapped_ptr) { + uint32_t are_friends = 0; + X_RESULT result; + + if (user_index >= 4) { + result = X_ERROR_INVALID_PARAMETER; + } else { + if (user_index == 0) { + const auto& user_profile = REX_KERNEL_STATE()->user_profile(); + if (user_profile->signin_state() == 0) { + result = X_ERROR_NOT_LOGGED_ON; + } else { + // No friends! + are_friends = 0; + result = X_ERROR_SUCCESS; + } + } else { + // Only support user 0. + result = X_ERROR_NO_SUCH_USER; // if user is local -> X_ERROR_NOT_LOGGED_ON + } + } + + if (out_value) { + assert_true(!overlapped_ptr); + *out_value = result == X_ERROR_SUCCESS ? are_friends : 0; + return result; + } else if (overlapped_ptr) { + assert_true(!out_value); + REX_KERNEL_STATE()->CompleteOverlappedImmediateEx( + overlapped_ptr, result == X_ERROR_SUCCESS ? X_ERROR_SUCCESS : X_ERROR_FUNCTION_FAILED, + X_HRESULT_FROM_WIN32(result), result == X_ERROR_SUCCESS ? are_friends : 0); + return X_ERROR_IO_PENDING; + } else { + assert_always(); + return X_ERROR_INVALID_PARAMETER; + } +} + +u32 XamShowSigninUI_entry(u32 unk, u32 unk_mask) { + // Mask values vary. Probably matching user types? Local/remote? + + // To fix game modes that display a 4 profile signin UI (even if playing + // alone): + // XN_SYS_SIGNINCHANGED + REX_KERNEL_STATE()->BroadcastNotification(0x0000000A, 1); + // Games seem to sit and loop until we trigger this notification: + // XN_SYS_UI (off) + REX_KERNEL_STATE()->BroadcastNotification(0x00000009, 0); + return X_ERROR_SUCCESS; +} + +// TODO(gibbed): probably a FILETIME/LARGE_INTEGER, unknown currently +struct X_ACHIEVEMENT_UNLOCK_TIME { + rex::be unk_0; + rex::be unk_4; +}; + +struct X_ACHIEVEMENT_DETAILS { + rex::be id; + rex::be label_ptr; + rex::be description_ptr; + rex::be unachieved_ptr; + rex::be image_id; + rex::be gamerscore; + X_ACHIEVEMENT_UNLOCK_TIME unlock_time; + rex::be flags; + + static const size_t kStringBufferSize = 464; +}; +static_assert_size(X_ACHIEVEMENT_DETAILS, 36); + +class XStaticAchievementEnumerator : public XEnumerator { + public: + struct AchievementDetails { + uint32_t id; + std::u16string label; + std::u16string description; + std::u16string unachieved; + uint32_t image_id; + uint32_t gamerscore; + struct { + uint32_t unk_0; + uint32_t unk_4; + } unlock_time; + uint32_t flags; + }; + + XStaticAchievementEnumerator(KernelState* kernel_state, size_t items_per_enumerate, + uint32_t flags) + : XEnumerator(kernel_state, items_per_enumerate, + sizeof(X_ACHIEVEMENT_DETAILS) + + (!!(flags & 7) ? X_ACHIEVEMENT_DETAILS::kStringBufferSize : 0)), + flags_(flags) {} + + void AppendItem(AchievementDetails item) { items_.push_back(std::move(item)); } + + uint32_t WriteItems(uint32_t buffer_ptr, uint8_t* buffer_data, uint32_t* written_count) override { + size_t count = std::min(items_.size() - current_item_, items_per_enumerate()); + if (!count) { + return X_ERROR_NO_MORE_FILES; + } + + size_t size = count * item_size(); + + auto details = reinterpret_cast(buffer_data); + size_t string_offset = items_per_enumerate() * sizeof(X_ACHIEVEMENT_DETAILS); + auto string_buffer = + StringBuffer{buffer_ptr + static_cast(string_offset), &buffer_data[string_offset], + count * X_ACHIEVEMENT_DETAILS::kStringBufferSize}; + for (size_t i = 0, o = current_item_; i < count; ++i, ++current_item_) { + const auto& item = items_[current_item_]; + details[i].id = item.id; + details[i].label_ptr = !!(flags_ & 1) ? AppendString(string_buffer, item.label) : 0; + details[i].description_ptr = + !!(flags_ & 2) ? AppendString(string_buffer, item.description) : 0; + details[i].unachieved_ptr = !!(flags_ & 4) ? AppendString(string_buffer, item.unachieved) : 0; + details[i].image_id = item.image_id; + details[i].gamerscore = item.gamerscore; + details[i].unlock_time.unk_0 = item.unlock_time.unk_0; + details[i].unlock_time.unk_4 = item.unlock_time.unk_4; + details[i].flags = item.flags; + } + + if (written_count) { + *written_count = static_cast(count); + } + + return X_ERROR_SUCCESS; + } + + private: + struct StringBuffer { + uint32_t ptr; + uint8_t* data; + size_t remaining_bytes; + }; + + uint32_t AppendString(StringBuffer& sb, const std::u16string_view string) { + size_t count = string.length() + 1; + size_t size = count * sizeof(char16_t); + if (size > sb.remaining_bytes) { + assert_always(); + return 0; + } + auto ptr = sb.ptr; + rex::string::util_copy_and_swap_truncating(reinterpret_cast(sb.data), string, count); + sb.ptr += static_cast(size); + sb.data += size; + sb.remaining_bytes -= size; + return ptr; + } + + private: + uint32_t flags_; + std::vector items_; + size_t current_item_ = 0; +}; + +u32 XamUserCreateAchievementEnumerator_entry(u32 title_id, u32 user_index, u32 xuid, u32 flags, + u32 offset, u32 count, mapped_u32 buffer_size_ptr, + mapped_u32 handle_ptr) { + if (!count || !buffer_size_ptr || !handle_ptr) { + return X_ERROR_INVALID_PARAMETER; + } + + if (user_index >= 4) { + return X_ERROR_INVALID_PARAMETER; + } + + size_t entry_size = sizeof(X_ACHIEVEMENT_DETAILS); + if (flags & 7) { + entry_size += X_ACHIEVEMENT_DETAILS::kStringBufferSize; + } + + if (buffer_size_ptr) { + *buffer_size_ptr = static_cast(entry_size) * count; + } + + auto e = object_ref( + new XStaticAchievementEnumerator(REX_KERNEL_STATE(), count, flags)); + auto result = e->Initialize(user_index, 0xFB, 0xB000A, 0xB000B, 0); + if (XFAILED(result)) { + return result; + } + + const util::XdbfGameData db = REX_KERNEL_STATE()->title_xdbf(); + + if (db.is_valid()) { + const XLanguage language = + db.GetExistingLanguage(static_cast(REXCVAR_GET(user_language))); + const std::vector achievement_list = db.GetAchievements(); + + for (const util::XdbfAchievementTableEntry& entry : achievement_list) { + auto item = XStaticAchievementEnumerator::AchievementDetails{ + entry.id, + rex::string::to_utf16(db.GetStringTableEntry(language, entry.label_id)), + rex::string::to_utf16(db.GetStringTableEntry(language, entry.description_id)), + rex::string::to_utf16(db.GetStringTableEntry(language, entry.unachieved_id)), + entry.image_id, + entry.gamerscore, + {0, 0}, + entry.flags}; + + e->AppendItem(item); + } + } + + *handle_ptr = e->handle(); + return X_ERROR_SUCCESS; +} + +u32 XamParseGamerTileKey_entry(mapped_u32 key_ptr, mapped_u32 out1_ptr, mapped_u32 out2_ptr, + mapped_u32 out3_ptr) { + *out1_ptr = 0xC0DE0001; + *out2_ptr = 0xC0DE0002; + *out3_ptr = 0xC0DE0003; + return X_ERROR_SUCCESS; +} + +u32 XamReadTileToTexture_entry(u32 unknown, u32 title_id, u64 tile_id, u32 user_index, + mapped_void buffer_ptr, u32 stride, u32 height, u32 overlapped_ptr) { + // TODO(gibbed): unknown=0,2,3,9 + if (!tile_id) { + return X_ERROR_INVALID_PARAMETER; + } + + size_t size = size_t(stride) * size_t(height); + std::memset(buffer_ptr, 0xFF, size); + + if (overlapped_ptr) { + REX_KERNEL_STATE()->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); + return X_ERROR_IO_PENDING; + } + return X_ERROR_SUCCESS; +} + +u32 XamWriteGamerTile_entry(u32 arg1, u32 arg2, u32 arg3, u32 arg4, u32 arg5, u32 overlapped_ptr) { + if (overlapped_ptr) { + REX_KERNEL_STATE()->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); + return X_ERROR_IO_PENDING; + } + return X_ERROR_SUCCESS; +} + +u32 XamSessionCreateHandle_entry(mapped_u32 handle_ptr) { + *handle_ptr = 0xCAFEDEAD; + return X_ERROR_SUCCESS; +} + +u32 XamSessionRefObjByHandle_entry(u32 handle, mapped_u32 obj_ptr) { + assert_true(handle == 0xCAFEDEAD); + // TODO(PermaNull): Implement this properly, + // For the time being returning 0xDEADF00D will prevent crashing. + *obj_ptr = 0xDEADF00D; + return X_ERROR_SUCCESS; +} + +} // namespace xam +} // namespace kernel +} // namespace rex + +REX_EXPORT(__imp__XamUserGetXUID, rex::kernel::xam::XamUserGetXUID_entry) +REX_EXPORT(__imp__XamUserGetSigninState, rex::kernel::xam::XamUserGetSigninState_entry) +REX_EXPORT(__imp__XamUserGetSigninInfo, rex::kernel::xam::XamUserGetSigninInfo_entry) +REX_EXPORT(__imp__XamUserGetName, rex::kernel::xam::XamUserGetName_entry) +REX_EXPORT(__imp__XamUserGetGamerTag, rex::kernel::xam::XamUserGetGamerTag_entry) +REX_EXPORT(__imp__XamUserReadProfileSettings, rex::kernel::xam::XamUserReadProfileSettings_entry) +REX_EXPORT(__imp__XamUserReadProfileSettingsEx, + rex::kernel::xam::XamUserReadProfileSettingsEx_entry) +REX_EXPORT(__imp__XamUserWriteProfileSettings, rex::kernel::xam::XamUserWriteProfileSettings_entry) +REX_EXPORT(__imp__XamUserCheckPrivilege, rex::kernel::xam::XamUserCheckPrivilege_entry) +REX_EXPORT(__imp__XamUserContentRestrictionGetFlags, + rex::kernel::xam::XamUserContentRestrictionGetFlags_entry) +REX_EXPORT(__imp__XamUserContentRestrictionGetRating, + rex::kernel::xam::XamUserContentRestrictionGetRating_entry) +REX_EXPORT(__imp__XamUserContentRestrictionCheckAccess, + rex::kernel::xam::XamUserContentRestrictionCheckAccess_entry) +REX_EXPORT(__imp__XamUserIsOnlineEnabled, rex::kernel::xam::XamUserIsOnlineEnabled_entry) +REX_EXPORT(__imp__XamUserGetMembershipTier, rex::kernel::xam::XamUserGetMembershipTier_entry) +REX_EXPORT(__imp__XamUserAreUsersFriends, rex::kernel::xam::XamUserAreUsersFriends_entry) +REX_EXPORT(__imp__XamShowSigninUI, rex::kernel::xam::XamShowSigninUI_entry) +REX_EXPORT(__imp__XamUserCreateAchievementEnumerator, + rex::kernel::xam::XamUserCreateAchievementEnumerator_entry) +REX_EXPORT(__imp__XamParseGamerTileKey, rex::kernel::xam::XamParseGamerTileKey_entry) +REX_EXPORT(__imp__XamReadTileToTexture, rex::kernel::xam::XamReadTileToTexture_entry) +REX_EXPORT(__imp__XamWriteGamerTile, rex::kernel::xam::XamWriteGamerTile_entry) +REX_EXPORT(__imp__XamSessionCreateHandle, rex::kernel::xam::XamSessionCreateHandle_entry) +REX_EXPORT(__imp__XamSessionRefObjByHandle, rex::kernel::xam::XamSessionRefObjByHandle_entry) + +REX_EXPORT_STUB(__imp__XamUserAddRecentPlayer); +REX_EXPORT_STUB(__imp__XamUserAllowedToPostToSocialNetwork); +REX_EXPORT_STUB(__imp__XamUserCreateAvatarAssetEnumerator); +REX_EXPORT_STUB(__imp__XamUserCreatePlayerEnumerator); +REX_EXPORT_STUB(__imp__XamUserCreateStatsEnumerator); +REX_EXPORT_STUB(__imp__XamUserCreateTitlesPlayedEnumerator); +REX_EXPORT_STUB(__imp__XamUserFlushLogonQueue); +REX_EXPORT_STUB(__imp__XamUserGetAge); +REX_EXPORT_STUB(__imp__XamUserGetAgeGroup); +REX_EXPORT_STUB(__imp__XamUserGetCachedUserFlags); +REX_EXPORT_STUB(__imp__XamUserGetDeviceId); +REX_EXPORT_STUB(__imp__XamUserGetIndexFromXUID); +REX_EXPORT_STUB(__imp__XamUserGetMembershipTierFromXUID); +REX_EXPORT_STUB(__imp__XamUserGetOnlineCountryFromXUID); +REX_EXPORT_STUB(__imp__XamUserGetOnlineLanguageFromXUID); +REX_EXPORT_STUB(__imp__XamUserGetOnlineXUIDFromOfflineXUID); +REX_EXPORT_STUB(__imp__XamUserGetReportingInfo); +REX_EXPORT_STUB(__imp__XamUserGetRequestedUserIndexMask); +REX_EXPORT_STUB(__imp__XamUserGetSubscriptionType); +REX_EXPORT_STUB(__imp__XamUserGetUserFlags); +REX_EXPORT_STUB(__imp__XamUserGetUserFlagsFromXUID); +REX_EXPORT_STUB(__imp__XamUserGetUserIndexMask); +REX_EXPORT_STUB(__imp__XamUserGetUserTenure); +REX_EXPORT_STUB(__imp__XamUserGetUsersMissingAvatars); +REX_EXPORT_STUB(__imp__XamUserGetXUIDForTFA); +REX_EXPORT_STUB(__imp__XamUserInvalidateProfileSetting); +REX_EXPORT_STUB(__imp__XamUserIsGuest); +REX_EXPORT_STUB(__imp__XamUserIsLogonPreviewModeEnabled); +REX_EXPORT_STUB(__imp__XamUserIsParentalControlled); +REX_EXPORT_STUB(__imp__XamUserIsPartial); +REX_EXPORT_STUB(__imp__XamUserIsPartialProfile); +REX_EXPORT_STUB(__imp__XamUserIsUnsafeProgrammingAllowed); +REX_EXPORT_STUB(__imp__XamUserLockLogonPreviewMode); +REX_EXPORT_STUB(__imp__XamUserLogon); +REX_EXPORT_STUB(__imp__XamUserLogonEx); +REX_EXPORT_STUB(__imp__XamUserLookupDevice); +REX_EXPORT_STUB(__imp__XamUserNuiBind); +REX_EXPORT_STUB(__imp__XamUserNuiEnableBiometric); +REX_EXPORT_STUB(__imp__XamUserNuiGetEnrollmentIndex); +REX_EXPORT_STUB(__imp__XamUserNuiGetUserIndex); +REX_EXPORT_STUB(__imp__XamUserNuiGetUserIndexForBind); +REX_EXPORT_STUB(__imp__XamUserNuiGetUserIndexForSignin); +REX_EXPORT_STUB(__imp__XamUserNuiIsBiometricEnabled); +REX_EXPORT_STUB(__imp__XamUserNuiUnbind); +REX_EXPORT_STUB(__imp__XamUserOverrideBindingCallbacks); +REX_EXPORT_STUB(__imp__XamUserOverrideDeviceBindings); +REX_EXPORT_STUB(__imp__XamUserOverrideGlobalState); +REX_EXPORT_STUB(__imp__XamUserOverrideUserInfo); +REX_EXPORT_STUB(__imp__XamUserPrefetchProfileSettings); +REX_EXPORT_STUB(__imp__XamUserProfileSync); +REX_EXPORT_STUB(__imp__XamUserReadUserPreference); +REX_EXPORT_STUB(__imp__XamUserResetSubscriptionType); +REX_EXPORT_STUB(__imp__XamUserUnlockLogonPreviewMode); +REX_EXPORT_STUB(__imp__XamUserUpdateRecentPlayer); +REX_EXPORT_STUB(__imp__XamUserValidateAvatarManifest); +REX_EXPORT_STUB(__imp__XamUserWriteUserPreference); +REX_EXPORT_STUB(__imp__XamVerifyPasscode); diff --git a/src/kernel/xam/xam_video.cpp b/src/kernel/xam/xam_video.cpp new file mode 100644 index 0000000..d2b2ef7 --- /dev/null +++ b/src/kernel/xam/xam_video.cpp @@ -0,0 +1,44 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include + +namespace rex { +namespace kernel { +namespace xam { +using namespace rex::system; + +void XGetVideoMode_entry(ppc_ptr_t video_mode) { + // TODO(benvanik): actually check to see if these are the same. + xboxkrnl::VdQueryVideoMode(std::move(video_mode)); +} + +u32 XGetVideoCapabilities_entry() { + return 0; +} + +} // namespace xam +} // namespace kernel +} // namespace rex + +REX_EXPORT(__imp__XGetVideoMode, rex::kernel::xam::XGetVideoMode_entry) +REX_EXPORT(__imp__XGetVideoCapabilities, rex::kernel::xam::XGetVideoCapabilities_entry) + +REX_EXPORT_STUB(__imp__XGetVideoFlags); +REX_EXPORT_STUB(__imp__XGetVideoStandard); +REX_EXPORT_STUB(__imp__XamLoadExtraAVCodecs2); +REX_EXPORT_STUB(__imp__XamUnloadExtraAVCodecs2); diff --git a/src/kernel/xam/xam_voice.cpp b/src/kernel/xam/xam_voice.cpp new file mode 100644 index 0000000..e48d6ce --- /dev/null +++ b/src/kernel/xam/xam_voice.cpp @@ -0,0 +1,70 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include +#include +#include +#include +#include +#include + +namespace rex { +namespace kernel { +namespace xam { + +u32 XamVoiceIsActiveProcess_entry() { + // Returning 0 here will short-circuit a bunch of voice stuff. + return 0; +} + +u32 XamVoiceCreate_entry(u32 unk1, // 0 + u32 unk2, // 0xF + mapped_u32 out_voice_ptr) { + // Null out the ptr. + out_voice_ptr.Zero(); + return X_ERROR_ACCESS_DENIED; +} + +u32 XamVoiceClose_entry(mapped_void voice_ptr) { + return 0; +} + +u32 XamVoiceHeadsetPresent_entry(mapped_void voice_ptr) { + return 0; +} + +} // namespace xam +} // namespace kernel +} // namespace rex + +REX_EXPORT(__imp__XamVoiceIsActiveProcess, rex::kernel::xam::XamVoiceIsActiveProcess_entry) +REX_EXPORT(__imp__XamVoiceCreate, rex::kernel::xam::XamVoiceCreate_entry) +REX_EXPORT(__imp__XamVoiceClose, rex::kernel::xam::XamVoiceClose_entry) +REX_EXPORT(__imp__XamVoiceHeadsetPresent, rex::kernel::xam::XamVoiceHeadsetPresent_entry) + +REX_EXPORT_STUB(__imp__XamMuteSound); +REX_EXPORT_STUB(__imp__XamVoiceDisableMicArray); +REX_EXPORT_STUB(__imp__XamVoiceGetBatteryStatus); +REX_EXPORT_STUB(__imp__XamVoiceGetDirectionalData); +REX_EXPORT_STUB(__imp__XamVoiceGetMicArrayAudio); +REX_EXPORT_STUB(__imp__XamVoiceGetMicArrayAudioEx); +REX_EXPORT_STUB(__imp__XamVoiceGetMicArrayFilenameDesc); +REX_EXPORT_STUB(__imp__XamVoiceGetMicArrayStatus); +REX_EXPORT_STUB(__imp__XamVoiceGetMicArrayUnderrunStatus); +REX_EXPORT_STUB(__imp__XamVoiceMuteMicArray); +REX_EXPORT_STUB(__imp__XamVoiceRecordUserPrivileges); +REX_EXPORT_STUB(__imp__XamVoiceSetAudioCaptureRoutine); +REX_EXPORT_STUB(__imp__XamVoiceSetMicArrayBeamAngle); +REX_EXPORT_STUB(__imp__XamVoiceSetMicArrayIdleUsers); +REX_EXPORT_STUB(__imp__XamVoiceSubmitPacket); diff --git a/src/kernel/xbdm/export_table.inc b/src/kernel/xbdm/export_table.inc new file mode 100644 index 0000000..ab217b3 --- /dev/null +++ b/src/kernel/xbdm/export_table.inc @@ -0,0 +1,269 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +// This is a partial file designed to be included by other files when +// constructing various tables. + +// clang-format off + +XE_EXPORT(xbdm, 0x00000001, DmAllocatePool, kFunction), +XE_EXPORT(xbdm, 0x00000002, DmAllocatePoolWithTag, kFunction), +XE_EXPORT(xbdm, 0x00000003, DmCloseCounters, kFunction), +XE_EXPORT(xbdm, 0x00000004, DmCloseLoadedModules, kFunction), +XE_EXPORT(xbdm, 0x00000005, DmCloseModuleSections_, kFunction), +XE_EXPORT(xbdm, 0x00000006, DmCloseNotificationSession, kFunction), +XE_EXPORT(xbdm, 0x00000007, DmClosePerformanceCounter, kFunction), +XE_EXPORT(xbdm, 0x00000008, DmContinueThread, kFunction), +XE_EXPORT(xbdm, 0x00000009, DmFreePool, kFunction), +XE_EXPORT(xbdm, 0x0000000A, DmGetMemory, kFunction), +XE_EXPORT(xbdm, 0x0000000B, DmGetModuleLongName, kFunction), +XE_EXPORT(xbdm, 0x0000000C, DmGetProcAddress, kFunction), +XE_EXPORT(xbdm, 0x0000000D, DmGetThreadContext, kFunction), +XE_EXPORT(xbdm, 0x0000000F, DmGetThreadList, kFunction), +XE_EXPORT(xbdm, 0x00000010, DmGetXbeInfo, kFunction), +XE_EXPORT(xbdm, 0x00000011, DmGetXboxName, kFunction), +XE_EXPORT(xbdm, 0x00000013, DmGo, kFunction), +XE_EXPORT(xbdm, 0x00000014, DmHaltThread, kFunction), +XE_EXPORT(xbdm, 0x00000015, DmIsDebuggerPresent, kFunction), +XE_EXPORT(xbdm, 0x00000016, DmIsThreadStopped, kFunction), +XE_EXPORT(xbdm, 0x00000017, DmLoadExtension, kFunction), +XE_EXPORT(xbdm, 0x00000018, DmNotify, kFunction), +XE_EXPORT(xbdm, 0x00000019, DmOpenNotificationSession, kFunction), +XE_EXPORT(xbdm, 0x0000001A, DmOpenPerformanceCounter, kFunction), +XE_EXPORT(xbdm, 0x0000001B, DmQueryPerformanceCounterHandle, kFunction), +XE_EXPORT(xbdm, 0x0000001C, DmReboot, kFunction), +XE_EXPORT(xbdm, 0x0000001E, DmRegisterCommandProcessor, kFunction), +XE_EXPORT(xbdm, 0x00000020, DmRegisterNotificationProcessor, kFunction), +XE_EXPORT(xbdm, 0x00000021, DmRegisterPerformanceCounter, kFunction), +XE_EXPORT(xbdm, 0x00000022, DmRemoveBreakpoint, kFunction), +XE_EXPORT(xbdm, 0x00000023, DmResumeThread, kFunction), +XE_EXPORT(xbdm, 0x00000024, DmSendNotificationString, kFunction), +XE_EXPORT(xbdm, 0x00000025, DmSetBreakpoint, kFunction), +XE_EXPORT(xbdm, 0x00000026, DmSetDataBreakpoint, kFunction), +XE_EXPORT(xbdm, 0x00000027, DmSetInitialBreakpoint, kFunction), +XE_EXPORT(xbdm, 0x00000028, DmSetMemory, kFunction), +XE_EXPORT(xbdm, 0x00000029, DmSetThreadContext, kFunction), +XE_EXPORT(xbdm, 0x0000002A, DmSetTitle, kFunction), +XE_EXPORT(xbdm, 0x0000002B, DmSetXboxName, kFunction), +XE_EXPORT(xbdm, 0x0000002D, DmStop, kFunction), +XE_EXPORT(xbdm, 0x0000002E, DmStopOn, kFunction), +XE_EXPORT(xbdm, 0x00000030, DmSuspendThread, kFunction), +XE_EXPORT(xbdm, 0x00000031, DmThreadUserData, kFunction), +XE_EXPORT(xbdm, 0x00000032, DmUnloadExtension, kFunction), +XE_EXPORT(xbdm, 0x00000033, DmWalkLoadedModules, kFunction), +XE_EXPORT(xbdm, 0x00000034, DmWalkModuleSections, kFunction), +XE_EXPORT(xbdm, 0x00000035, DmWalkPerformanceCounters, kFunction), +XE_EXPORT(xbdm, 0x00000037, DmCloseCounters_0, kFunction), +XE_EXPORT(xbdm, 0x00000038, DmIsBreakpoint, kFunction), +XE_EXPORT(xbdm, 0x00000039, DmCloseCounters_1, kFunction), +XE_EXPORT(xbdm, 0x0000003A, DmSetUserAccess, kFunction), +XE_EXPORT(xbdm, 0x0000003B, DmGetUserAccess, kFunction), +XE_EXPORT(xbdm, 0x0000003C, DmWalkUserList, kFunction), +XE_EXPORT(xbdm, 0x0000003D, DmAddUser, kFunction), +XE_EXPORT(xbdm, 0x0000003E, DmEnableSecurity, kFunction), +XE_EXPORT(xbdm, 0x0000003F, DmIsSecurityEnabled, kFunction), +XE_EXPORT(xbdm, 0x00000040, DmRemoveUser, kFunction), +XE_EXPORT(xbdm, 0x00000041, __CAP_Start_Profiling, kFunction), +XE_EXPORT(xbdm, 0x00000042, __CAP_End_Profiling, kFunction), +XE_EXPORT(xbdm, 0x00000046, __CAP_Enter_Function, kFunction), +XE_EXPORT(xbdm, 0x00000047, __CAP_Exit_Function, kFunction), +XE_EXPORT(xbdm, 0x00000048, DmRegisterCommandProcessorEx, kFunction), +XE_EXPORT(xbdm, 0x00000049, DmStartProfiling, kFunction), +XE_EXPORT(xbdm, 0x0000004A, DmStopProfiling, kFunction), +XE_EXPORT(xbdm, 0x0000004B, DmQueryMemoryStatistics, kFunction), +XE_EXPORT(xbdm, 0x0000004C, DmEnableStackTrace, kFunction), +XE_EXPORT(xbdm, 0x0000004D, DmQueryAllocationTypeName, kFunction), +XE_EXPORT(xbdm, 0x0000004E, DmRegisterAllocationType, kFunction), +XE_EXPORT(xbdm, 0x0000004F, DmInsertAllocationEntry, kFunction), +XE_EXPORT(xbdm, 0x00000050, DmRemoveAllocationEntry, kFunction), +XE_EXPORT(xbdm, 0x00000051, DmSetTitleEx, kFunction), +XE_EXPORT(xbdm, 0x00000052, DmCaptureStackBackTrace, kFunction), +XE_EXPORT(xbdm, 0x00000053, DmCrashDump, kFunction), +XE_EXPORT(xbdm, 0x00000054, DmIsFastCAPEnabled, kFunction), +XE_EXPORT(xbdm, 0x00000055, DmGetFileAccessCount, kFunction), +XE_EXPORT(xbdm, 0x00000058, DmGetUtilityDriveInfo, kFunction), +XE_EXPORT(xbdm, 0x00000059, DmGetThreadInfoEx, kFunction), +XE_EXPORT(xbdm, 0x0000005A, DmSetProfilingOptions, kFunction), +XE_EXPORT(xbdm, 0x0000005B, DmQuerySystemSettings, kFunction), +XE_EXPORT(xbdm, 0x0000005C, DmSaveSystemSettings, kFunction), +XE_EXPORT(xbdm, 0x0000006A, DmpGetPgoModuleHandleForBaseAddress, kFunction), +XE_EXPORT(xbdm, 0x0000006B, DmpOnPgoModuleLoad, kFunction), +XE_EXPORT(xbdm, 0x0000006C, DmPgoStartDataCollection, kFunction), +XE_EXPORT(xbdm, 0x0000006D, DmPgoStopDataCollection, kFunction), +XE_EXPORT(xbdm, 0x0000006E, DmPgoSaveSnapshot, kFunction), +XE_EXPORT(xbdm, 0x0000006F, IrtClientAbort, kFunction), +XE_EXPORT(xbdm, 0x00000070, IrtPogoInit, kFunction), +XE_EXPORT(xbdm, 0x00000071, IrtSetStaticInfo, kFunction), +XE_EXPORT(xbdm, 0x00000072, IrtAutoSweepW, kFunction), +XE_EXPORT(xbdm, 0x00000073, IrtAutoSweepA, kFunction), +XE_EXPORT(xbdm, 0x00000075, DmGetDumpMode, kFunction), +XE_EXPORT(xbdm, 0x00000076, DmSetDumpMode, kFunction), +XE_EXPORT(xbdm, 0x00000077, DmGetDumpSettings, kFunction), +XE_EXPORT(xbdm, 0x00000078, DmSetDumpSettings, kFunction), +XE_EXPORT(xbdm, 0x00000079, DmGetEventDeferFlags, kFunction), +XE_EXPORT(xbdm, 0x0000007A, DmSetEventDeferFlags, kFunction), +XE_EXPORT(xbdm, 0x0000007B, DmWalkCommittedMemory, kFunction), +XE_EXPORT(xbdm, 0x0000007C, DmCloseCounters_2, kFunction), +XE_EXPORT(xbdm, 0x0000007D, DmRebootEx, kFunction), +XE_EXPORT(xbdm, 0x00000082, DmMountFdfxVolume, kFunction), +XE_EXPORT(xbdm, 0x00000083, DmCapGetFileHeader, kFunction), +XE_EXPORT(xbdm, 0x00000084, DmCapFreeFileHeader, kFunction), +XE_EXPORT(xbdm, 0x00000085, DmTraceStartRecording, kFunction), +XE_EXPORT(xbdm, 0x00000086, DmTraceStartRecordingFunction, kFunction), +XE_EXPORT(xbdm, 0x00000087, DmTraceSetBufferSize, kFunction), +XE_EXPORT(xbdm, 0x00000088, DmTraceStopRecording, kFunction), +XE_EXPORT(xbdm, 0x00000089, DmTraceSaveBuffer, kFunction), +XE_EXPORT(xbdm, 0x0000008C, DmGetConsoleType, kFunction), +XE_EXPORT(xbdm, 0x0000008D, DmMapDevkitDrive, kFunction), +XE_EXPORT(xbdm, 0x0000008E, DmWalkLoadedModulesEx, kFunction), +XE_EXPORT(xbdm, 0x0000008F, DmGetXexHeaderField, kFunction), +XE_EXPORT(xbdm, 0x00000090, DmGetMouseChanges, kFunction), +XE_EXPORT(xbdm, 0x00000091, DmFindPdbSignature, kFunction), +XE_EXPORT(xbdm, 0x00000092, DmGetProfilingStatus, kFunction), +XE_EXPORT(xbdm, 0x00000093, DmOpticalDiscLogStart, kFunction), +XE_EXPORT(xbdm, 0x00000094, DmOpticalDiscLogStop, kFunction), +XE_EXPORT(xbdm, 0x00000095, DmStartSamplingProfiler, kFunction), +XE_EXPORT(xbdm, 0x00000096, DmStopSamplingProfiler, kFunction), +XE_EXPORT(xbdm, 0x00000097, DmGetSamplingProfilerInfo, kFunction), +XE_EXPORT(xbdm, 0x00000098, DmStartFileEventCapture, kFunction), +XE_EXPORT(xbdm, 0x00000099, DmStopFileEventCapture, kFunction), +XE_EXPORT(xbdm, 0x0000009A, DmSetFileEventMarker, kFunction), +XE_EXPORT(xbdm, 0x0000009B, DmMarkPseudoCreateBegin, kFunction), +XE_EXPORT(xbdm, 0x0000009C, DmMarkPseudoCreateEnd, kFunction), +XE_EXPORT(xbdm, 0x0000009D, DmMarkPseudoEventBegin, kFunction), +XE_EXPORT(xbdm, 0x0000009E, DmMarkPseudoEventEnd, kFunction), +XE_EXPORT(xbdm, 0x0000009F, DmMarkFileEventWorkerThreadBegin, kFunction), +XE_EXPORT(xbdm, 0x000000A0, DmMarkFileEventWorkerThreadEnd, kFunction), +XE_EXPORT(xbdm, 0x000000A1, DmGetSystemInfo, kFunction), +XE_EXPORT(xbdm, 0x000000A2, DmAbortProfiling, kFunction), +XE_EXPORT(xbdm, 0x000000A3, DmNetCaptureStart, kFunction), +XE_EXPORT(xbdm, 0x000000A4, DmNetCaptureStop, kFunction), +XE_EXPORT(xbdm, 0x000000A5, DmQueryTitleMemoryStatistics, kFunction), +XE_EXPORT(xbdm, 0x000000A6, DmAutomationGetInputProcess, kFunction), +XE_EXPORT(xbdm, 0x000000A7, DmAutomationBindController, kFunction), +XE_EXPORT(xbdm, 0x000000A8, DmAutomationUnbindController, kFunction), +XE_EXPORT(xbdm, 0x000000A9, DmAutomationConnectController, kFunction), +XE_EXPORT(xbdm, 0x000000AA, DmAutomationDisconnectController, kFunction), +XE_EXPORT(xbdm, 0x000000AB, DmAutomationSetGamepadState, kFunction), +XE_EXPORT(xbdm, 0x000000AC, DmAutomationQueueGamepadState, kFunction), +XE_EXPORT(xbdm, 0x000000AD, DmAutomationClearGamepadQueue, kFunction), +XE_EXPORT(xbdm, 0x000000AE, DmAutomationQueryGamepadQueue, kFunction), +XE_EXPORT(xbdm, 0x000000AF, DmAutomationGetUserDefaultProfile, kFunction), +XE_EXPORT(xbdm, 0x000000B0, DmAutomationSetUserDefaultProfile, kFunction), +XE_EXPORT(xbdm, 0x000000B1, DmTraceIsRecording, kFunction), +XE_EXPORT(xbdm, 0x000000B2, DmLoadDebuggerExtension, kFunction), +XE_EXPORT(xbdm, 0x000000B3, DmUnloadDebuggerExtension, kFunction), +XE_EXPORT(xbdm, 0x000000B4, DmCreateSystemThread, kFunction), +XE_EXPORT(xbdm, 0x000000B5, PEPLELookup, kFunction), +XE_EXPORT(xbdm, 0x000000B6, PEPLELookupCompact, kFunction), +XE_EXPORT(xbdm, 0x000000B7, PVPLELookup, kFunction), +XE_EXPORT(xbdm, 0x000000B8, PVPLELookupCompact, kFunction), +XE_EXPORT(xbdm, 0x000000B9, PVPLELookupCompactMDS, kFunction), +XE_EXPORT(xbdm, 0x000000BA, PVPLEFilteredLookup, kFunction), +XE_EXPORT(xbdm, 0x000000BB, PVPLEFilteredLookupCompact, kFunction), +XE_EXPORT(xbdm, 0x000000BC, PVPLEFilteredLookupCompactMDS, kFunction), +XE_EXPORT(xbdm, 0x000000BD, PVPLETemplatedLookup, kFunction), +XE_EXPORT(xbdm, 0x000000BE, PVPLETemplatedLookupCompact, kFunction), +XE_EXPORT(xbdm, 0x000000BF, PVPLETemplatedLookupCompactMDS, kFunction), +XE_EXPORT(xbdm, 0x000000C0, DmpPgoCounterOverflow, kFunction), +XE_EXPORT(xbdm, 0x000000C1, UpdateMDSProbeState, kFunction), +XE_EXPORT(xbdm, 0x000000C2, DmGetHttpRegistration, kFunction), +XE_EXPORT(xbdm, 0x000000C3, DmTraceSetIOThread, kFunction), +XE_EXPORT(xbdm, 0x000000C4, DmPMCInstallAndStart, kFunction), +XE_EXPORT(xbdm, 0x000000C5, DmPMCStopAndReport, kFunction), +XE_EXPORT(xbdm, 0x000000C6, DmPMCInstallSetup, kFunction), +XE_EXPORT(xbdm, 0x000000C7, DmPMCUnInstallSetup, kFunction), +XE_EXPORT(xbdm, 0x000000C8, DmPMCResetCounters, kFunction), +XE_EXPORT(xbdm, 0x000000C9, DmPMCSetTriggerProcessor, kFunction), +XE_EXPORT(xbdm, 0x000000CA, DmPMCStart, kFunction), +XE_EXPORT(xbdm, 0x000000CB, DmPMCStop, kFunction), +XE_EXPORT(xbdm, 0x000000CC, DmPMCGetCounter, kFunction), +XE_EXPORT(xbdm, 0x000000CD, DmPMCGetCounters, kFunction), +XE_EXPORT(xbdm, 0x000000CE, DmPMCGetCounterName, kFunction), +XE_EXPORT(xbdm, 0x000000CF, DmPMCDumpCounters, kFunction), +XE_EXPORT(xbdm, 0x000000D0, DmPMCDumpCountersVerbose, kFunction), +XE_EXPORT(xbdm, 0x000000D1, DmPMCGetCounterCostEstimate, kFunction), +XE_EXPORT(xbdm, 0x000000D2, DmPMCGetCounterSource, kFunction), +XE_EXPORT(xbdm, 0x000000D3, DmPMCComputeFrequency, kFunction), +XE_EXPORT(xbdm, 0x000000D4, DmGetAdditionalTitleMemorySetting, kFunction), +XE_EXPORT(xbdm, 0x000000D5, DmGetDebugMemorySize, kFunction), +XE_EXPORT(xbdm, 0x000000D6, DmGetConsoleDebugMemoryStatus, kFunction), +XE_EXPORT(xbdm, 0x000000D7, DmNetSimSetLinkStatusHidden, kFunction), +XE_EXPORT(xbdm, 0x000000D8, DmNetSimInsertQueue, kFunction), +XE_EXPORT(xbdm, 0x000000D9, DmNetSimRemoveQueue, kFunction), +XE_EXPORT(xbdm, 0x000000DA, DmNetSimRemoveAllQueues, kFunction), +XE_EXPORT(xbdm, 0x000000DB, DmNetSimModifyQueueSettings, kFunction), +XE_EXPORT(xbdm, 0x000000DC, DmGetConsoleFeatures, kFunction), +XE_EXPORT(xbdm, 0x000000DD, DmNetSimGetQueueStats, kFunction), +XE_EXPORT(xbdm, 0x000000DE, DmNetSimGetQueueSettings, kFunction), +XE_EXPORT(xbdm, 0x000000DF, DmNetSimGetNumQueues, kFunction), +XE_EXPORT(xbdm, 0x000000E0, DmNetSimInsertIpv4Redirect, kFunction), +XE_EXPORT(xbdm, 0x000000E1, DmNetSimRemoveIpv4Redirect, kFunction), +XE_EXPORT(xbdm, 0x000000E2, DmNetSimGetNumIpv4Redirects, kFunction), +XE_EXPORT(xbdm, 0x0000012C, XLFAllocate, kFunction), +XE_EXPORT(xbdm, 0x0000012D, XLFFree, kFunction), +XE_EXPORT(xbdm, 0x0000012E, XLFQueueAdd, kFunction), +XE_EXPORT(xbdm, 0x0000012F, XLFQueueAllocated, kFunction), +XE_EXPORT(xbdm, 0x00000130, XLFQueueCreate, kFunction), +XE_EXPORT(xbdm, 0x00000131, XLFQueueDestroy, kFunction), +XE_EXPORT(xbdm, 0x00000132, XLFQueueGetEntryCount, kFunction), +XE_EXPORT(xbdm, 0x00000133, XLFQueueIsEmpty, kFunction), +XE_EXPORT(xbdm, 0x00000134, XLFQueueRemove, kFunction), +XE_EXPORT(xbdm, 0x00000135, XLFQueueUnsafeDump, kFunction), +XE_EXPORT(xbdm, 0x00000136, XLFStackAllocated, kFunction), +XE_EXPORT(xbdm, 0x00000137, XLFStackCreate, kFunction), +XE_EXPORT(xbdm, 0x00000138, XLFStackDestroy, kFunction), +XE_EXPORT(xbdm, 0x00000139, XLFStackGetEntryCount, kFunction), +XE_EXPORT(xbdm, 0x0000013A, XLFStackIsEmpty, kFunction), +XE_EXPORT(xbdm, 0x0000013B, XLFStackPop, kFunction), +XE_EXPORT(xbdm, 0x0000013C, XLFStackPush, kFunction), +XE_EXPORT(xbdm, 0x0000013D, XLFStackUnsafeDump, kFunction), +XE_EXPORT(xbdm, 0x00000140, XLFPriorityQueueAdd, kFunction), +XE_EXPORT(xbdm, 0x00000141, XLFPriorityQueueAllocated, kFunction), +XE_EXPORT(xbdm, 0x00000142, XLFPriorityQueueCreate, kFunction), +XE_EXPORT(xbdm, 0x00000143, XLFPriorityQueueDestroy, kFunction), +XE_EXPORT(xbdm, 0x00000144, XLFPriorityQueueGetEntryCount, kFunction), +XE_EXPORT(xbdm, 0x00000145, XLFPriorityQueueIsEmpty, kFunction), +XE_EXPORT(xbdm, 0x00000146, XLFPriorityQueueRemoveFirst, kFunction), +XE_EXPORT(xbdm, 0x00000147, XLFPriorityQueueRemove, kFunction), +XE_EXPORT(xbdm, 0x00000148, XLFPriorityQueueUnsafeDump, kFunction), +XE_EXPORT(xbdm, 0x0000014A, XLFHashTableAdd, kFunction), +XE_EXPORT(xbdm, 0x0000014B, XLFHashTableAllocated, kFunction), +XE_EXPORT(xbdm, 0x0000014C, XLFHashTableCreate, kFunction), +XE_EXPORT(xbdm, 0x0000014D, XLFHashTableDestroy, kFunction), +XE_EXPORT(xbdm, 0x0000014E, XLFHashTableGetEntryCount, kFunction), +XE_EXPORT(xbdm, 0x0000014F, XLFHashTableIsEmpty, kFunction), +XE_EXPORT(xbdm, 0x00000150, XLFHashTableRemoveFirst, kFunction), +XE_EXPORT(xbdm, 0x00000151, XLFHashTableRemove, kFunction), +XE_EXPORT(xbdm, 0x00000152, XLFHashTableUnsafeDump, kFunction), +XE_EXPORT(xbdm, 0x00000154, XLFPoolAcquireLock, kFunction), +XE_EXPORT(xbdm, 0x00000155, XLFPoolAllocated, kFunction), +XE_EXPORT(xbdm, 0x00000156, XLFPoolCreate, kFunction), +XE_EXPORT(xbdm, 0x00000157, XLFPoolCreateLock, kFunction), +XE_EXPORT(xbdm, 0x00000158, XLFPoolDestroy, kFunction), +XE_EXPORT(xbdm, 0x00000159, XLFPoolDestroyLock, kFunction), +XE_EXPORT(xbdm, 0x0000015A, XLFPoolIncreaseEvents, kFunction), +XE_EXPORT(xbdm, 0x0000015B, XLFPoolIncreaseLocks, kFunction), +XE_EXPORT(xbdm, 0x0000015C, XLFPoolInitializeLock, kFunction), +XE_EXPORT(xbdm, 0x0000015D, XLFPoolNumberOfEvents, kFunction), +XE_EXPORT(xbdm, 0x0000015E, XLFPoolNumberOfLocks, kFunction), +XE_EXPORT(xbdm, 0x0000015F, XLFPoolReleaseLock, kFunction), +XE_EXPORT(xbdm, 0x00000163, XLFStartLog, kFunction), +XE_EXPORT(xbdm, 0x00000164, XLFStartUserLog, kFunction), +XE_EXPORT(xbdm, 0x00000165, XLFInitializeLog, kFunction), +XE_EXPORT(xbdm, 0x00000166, XLFInitializeUserLog, kFunction), +XE_EXPORT(xbdm, 0x00000168, XLFEndLog, kFunction), +XE_EXPORT(xbdm, 0x00000169, XLFLogPrint, kFunction), +XE_EXPORT(xbdm, 0x0000016A, XLFLogPrintV, kFunction), +XE_EXPORT(xbdm, 0x0000016B, XLFLogBuffer, kFunction), +XE_EXPORT(xbdm, 0x0000016C, XLFLogMessageStats, kFunction), +XE_EXPORT(xbdm, 0x00000172, XLockFreeGetErrorHandler, kFunction), +XE_EXPORT(xbdm, 0x00000173, XLockFreeSetErrorHandler, kFunction), +XE_EXPORT(xbdm, 0x00000174, DmExecuteThreadRPC, kFunction), +XE_EXPORT(xbdm, 0x00000175, DmGetDebuggerConnection, kFunction), diff --git a/src/kernel/xbdm/xbdm_misc.cpp b/src/kernel/xbdm/xbdm_misc.cpp new file mode 100644 index 0000000..94217b7 --- /dev/null +++ b/src/kernel/xbdm/xbdm_misc.cpp @@ -0,0 +1,270 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Xenia Canary. All rights reserved. + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Joseph Lee; 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +REX_EXPORT_STUB(__imp__DmAllocatePool); +REX_EXPORT_STUB(__imp__DmAllocatePoolWithTag); +REX_EXPORT_STUB(__imp__DmCloseCounters); +REX_EXPORT_STUB(__imp__DmCloseLoadedModules); +REX_EXPORT_STUB(__imp__DmCloseModuleSections_); +REX_EXPORT_STUB(__imp__DmCloseNotificationSession); +REX_EXPORT_STUB(__imp__DmClosePerformanceCounter); +REX_EXPORT_STUB(__imp__DmContinueThread); +REX_EXPORT_STUB(__imp__DmFreePool); +REX_EXPORT_STUB(__imp__DmGetMemory); +REX_EXPORT_STUB(__imp__DmGetModuleLongName); +REX_EXPORT_STUB(__imp__DmGetProcAddress); +REX_EXPORT_STUB(__imp__DmGetThreadContext); +REX_EXPORT_STUB(__imp__DmGetThreadList); +REX_EXPORT_STUB(__imp__DmGetXbeInfo); +REX_EXPORT_STUB(__imp__DmGetXboxName); +REX_EXPORT_STUB(__imp__DmGo); +REX_EXPORT_STUB(__imp__DmHaltThread); +REX_EXPORT_STUB(__imp__DmIsDebuggerPresent); +REX_EXPORT_STUB(__imp__DmIsThreadStopped); +REX_EXPORT_STUB(__imp__DmLoadExtension); +REX_EXPORT_STUB(__imp__DmNotify); +REX_EXPORT_STUB(__imp__DmOpenNotificationSession); +REX_EXPORT_STUB(__imp__DmOpenPerformanceCounter); +REX_EXPORT_STUB(__imp__DmQueryPerformanceCounterHandle); +REX_EXPORT_STUB(__imp__DmReboot); +REX_EXPORT_STUB(__imp__DmRegisterCommandProcessor); +REX_EXPORT_STUB(__imp__DmRegisterNotificationProcessor); +REX_EXPORT_STUB(__imp__DmRegisterPerformanceCounter); +REX_EXPORT_STUB(__imp__DmRemoveBreakpoint); +REX_EXPORT_STUB(__imp__DmResumeThread); +REX_EXPORT_STUB(__imp__DmSendNotificationString); +REX_EXPORT_STUB(__imp__DmSetBreakpoint); +REX_EXPORT_STUB(__imp__DmSetDataBreakpoint); +REX_EXPORT_STUB(__imp__DmSetInitialBreakpoint); +REX_EXPORT_STUB(__imp__DmSetMemory); +REX_EXPORT_STUB(__imp__DmSetThreadContext); +REX_EXPORT_STUB(__imp__DmSetTitle); +REX_EXPORT_STUB(__imp__DmSetXboxName); +REX_EXPORT_STUB(__imp__DmStop); +REX_EXPORT_STUB(__imp__DmStopOn); +REX_EXPORT_STUB(__imp__DmSuspendThread); +REX_EXPORT_STUB(__imp__DmThreadUserData); +REX_EXPORT_STUB(__imp__DmUnloadExtension); +REX_EXPORT_STUB_RETURN(__imp__DmWalkLoadedModules, 0x82DA0104); +REX_EXPORT_STUB(__imp__DmWalkModuleSections); +REX_EXPORT_STUB(__imp__DmWalkPerformanceCounters); +REX_EXPORT_STUB(__imp__DmCloseCounters_0); +REX_EXPORT_STUB(__imp__DmIsBreakpoint); +REX_EXPORT_STUB(__imp__DmCloseCounters_1); +REX_EXPORT_STUB(__imp__DmSetUserAccess); +REX_EXPORT_STUB(__imp__DmGetUserAccess); +REX_EXPORT_STUB(__imp__DmWalkUserList); +REX_EXPORT_STUB(__imp__DmAddUser); +REX_EXPORT_STUB(__imp__DmEnableSecurity); +REX_EXPORT_STUB(__imp__DmIsSecurityEnabled); +REX_EXPORT_STUB(__imp__DmRemoveUser); +REX_EXPORT_STUB(__imp____CAP_Start_Profiling); +REX_EXPORT_STUB(__imp____CAP_End_Profiling); +REX_EXPORT_STUB(__imp____CAP_Enter_Function); +REX_EXPORT_STUB(__imp____CAP_Exit_Function); +REX_EXPORT_STUB_RETURN(__imp__DmRegisterCommandProcessorEx, 0); +REX_EXPORT_STUB(__imp__DmStartProfiling); +REX_EXPORT_STUB(__imp__DmStopProfiling); +REX_EXPORT_STUB(__imp__DmQueryMemoryStatistics); +REX_EXPORT_STUB(__imp__DmEnableStackTrace); +REX_EXPORT_STUB(__imp__DmQueryAllocationTypeName); +REX_EXPORT_STUB(__imp__DmRegisterAllocationType); +REX_EXPORT_STUB(__imp__DmInsertAllocationEntry); +REX_EXPORT_STUB(__imp__DmRemoveAllocationEntry); +REX_EXPORT_STUB(__imp__DmSetTitleEx); +REX_EXPORT_STUB(__imp__DmCaptureStackBackTrace); +REX_EXPORT_STUB(__imp__DmCrashDump); +REX_EXPORT_STUB(__imp__DmIsFastCAPEnabled); +REX_EXPORT_STUB(__imp__DmGetFileAccessCount); +REX_EXPORT_STUB(__imp__DmGetUtilityDriveInfo); +REX_EXPORT_STUB(__imp__DmGetThreadInfoEx); +REX_EXPORT_STUB(__imp__DmSetProfilingOptions); +REX_EXPORT_STUB(__imp__DmQuerySystemSettings); +REX_EXPORT_STUB(__imp__DmSaveSystemSettings); +REX_EXPORT_STUB(__imp__DmpGetPgoModuleHandleForBaseAddress); +REX_EXPORT_STUB(__imp__DmpOnPgoModuleLoad); +REX_EXPORT_STUB(__imp__DmPgoStartDataCollection); +REX_EXPORT_STUB(__imp__DmPgoStopDataCollection); +REX_EXPORT_STUB(__imp__DmPgoSaveSnapshot); +REX_EXPORT_STUB(__imp__IrtClientAbort); +REX_EXPORT_STUB(__imp__IrtPogoInit); +REX_EXPORT_STUB(__imp__IrtSetStaticInfo); +REX_EXPORT_STUB(__imp__IrtAutoSweepW); +REX_EXPORT_STUB(__imp__IrtAutoSweepA); +REX_EXPORT_STUB(__imp__DmGetDumpMode); +REX_EXPORT_STUB(__imp__DmSetDumpMode); +REX_EXPORT_STUB(__imp__DmGetDumpSettings); +REX_EXPORT_STUB(__imp__DmSetDumpSettings); +REX_EXPORT_STUB(__imp__DmGetEventDeferFlags); +REX_EXPORT_STUB(__imp__DmSetEventDeferFlags); +REX_EXPORT_STUB(__imp__DmWalkCommittedMemory); +REX_EXPORT_STUB(__imp__DmCloseCounters_2); +REX_EXPORT_STUB(__imp__DmRebootEx); +REX_EXPORT_STUB(__imp__DmMountFdfxVolume); +REX_EXPORT_STUB(__imp__DmCapGetFileHeader); +REX_EXPORT_STUB(__imp__DmCapFreeFileHeader); +REX_EXPORT_STUB(__imp__DmTraceStartRecording); +REX_EXPORT_STUB(__imp__DmTraceStartRecordingFunction); +REX_EXPORT_STUB(__imp__DmTraceSetBufferSize); +REX_EXPORT_STUB(__imp__DmTraceStopRecording); +REX_EXPORT_STUB(__imp__DmTraceSaveBuffer); +REX_EXPORT_STUB(__imp__DmGetConsoleType); +REX_EXPORT_STUB(__imp__DmMapDevkitDrive); +REX_EXPORT_STUB(__imp__DmWalkLoadedModulesEx); +REX_EXPORT_STUB(__imp__DmGetXexHeaderField); +REX_EXPORT_STUB(__imp__DmGetMouseChanges); +REX_EXPORT_STUB(__imp__DmFindPdbSignature); +REX_EXPORT_STUB(__imp__DmGetProfilingStatus); +REX_EXPORT_STUB(__imp__DmOpticalDiscLogStart); +REX_EXPORT_STUB(__imp__DmOpticalDiscLogStop); +REX_EXPORT_STUB(__imp__DmStartSamplingProfiler); +REX_EXPORT_STUB(__imp__DmStopSamplingProfiler); +REX_EXPORT_STUB(__imp__DmGetSamplingProfilerInfo); +REX_EXPORT_STUB(__imp__DmStartFileEventCapture); +REX_EXPORT_STUB(__imp__DmStopFileEventCapture); +REX_EXPORT_STUB(__imp__DmSetFileEventMarker); +REX_EXPORT_STUB(__imp__DmMarkPseudoCreateBegin); +REX_EXPORT_STUB(__imp__DmMarkPseudoCreateEnd); +REX_EXPORT_STUB(__imp__DmMarkPseudoEventBegin); +REX_EXPORT_STUB(__imp__DmMarkPseudoEventEnd); +REX_EXPORT_STUB(__imp__DmMarkFileEventWorkerThreadBegin); +REX_EXPORT_STUB(__imp__DmMarkFileEventWorkerThreadEnd); +REX_EXPORT_STUB(__imp__DmGetSystemInfo); +REX_EXPORT_STUB(__imp__DmAbortProfiling); +REX_EXPORT_STUB(__imp__DmNetCaptureStart); +REX_EXPORT_STUB(__imp__DmNetCaptureStop); +REX_EXPORT_STUB(__imp__DmQueryTitleMemoryStatistics); +REX_EXPORT_STUB(__imp__DmAutomationGetInputProcess); +REX_EXPORT_STUB(__imp__DmAutomationBindController); +REX_EXPORT_STUB(__imp__DmAutomationUnbindController); +REX_EXPORT_STUB(__imp__DmAutomationConnectController); +REX_EXPORT_STUB(__imp__DmAutomationDisconnectController); +REX_EXPORT_STUB(__imp__DmAutomationSetGamepadState); +REX_EXPORT_STUB(__imp__DmAutomationQueueGamepadState); +REX_EXPORT_STUB(__imp__DmAutomationClearGamepadQueue); +REX_EXPORT_STUB(__imp__DmAutomationQueryGamepadQueue); +REX_EXPORT_STUB(__imp__DmAutomationGetUserDefaultProfile); +REX_EXPORT_STUB(__imp__DmAutomationSetUserDefaultProfile); +REX_EXPORT_STUB(__imp__DmTraceIsRecording); +REX_EXPORT_STUB(__imp__DmLoadDebuggerExtension); +REX_EXPORT_STUB(__imp__DmUnloadDebuggerExtension); +REX_EXPORT_STUB(__imp__DmCreateSystemThread); +REX_EXPORT_STUB(__imp__PEPLELookup); +REX_EXPORT_STUB(__imp__PEPLELookupCompact); +REX_EXPORT_STUB(__imp__PVPLELookup); +REX_EXPORT_STUB(__imp__PVPLELookupCompact); +REX_EXPORT_STUB(__imp__PVPLELookupCompactMDS); +REX_EXPORT_STUB(__imp__PVPLEFilteredLookup); +REX_EXPORT_STUB(__imp__PVPLEFilteredLookupCompact); +REX_EXPORT_STUB(__imp__PVPLEFilteredLookupCompactMDS); +REX_EXPORT_STUB(__imp__PVPLETemplatedLookup); +REX_EXPORT_STUB(__imp__PVPLETemplatedLookupCompact); +REX_EXPORT_STUB(__imp__PVPLETemplatedLookupCompactMDS); +REX_EXPORT_STUB(__imp__DmpPgoCounterOverflow); +REX_EXPORT_STUB(__imp__UpdateMDSProbeState); +REX_EXPORT_STUB(__imp__DmGetHttpRegistration); +REX_EXPORT_STUB(__imp__DmTraceSetIOThread); +REX_EXPORT_STUB(__imp__DmPMCInstallAndStart); +REX_EXPORT_STUB(__imp__DmPMCStopAndReport); +REX_EXPORT_STUB(__imp__DmPMCInstallSetup); +REX_EXPORT_STUB(__imp__DmPMCUnInstallSetup); +REX_EXPORT_STUB(__imp__DmPMCResetCounters); +REX_EXPORT_STUB(__imp__DmPMCSetTriggerProcessor); +REX_EXPORT_STUB(__imp__DmPMCStart); +REX_EXPORT_STUB(__imp__DmPMCStop); +REX_EXPORT_STUB(__imp__DmPMCGetCounter); +REX_EXPORT_STUB(__imp__DmPMCGetCounters); +REX_EXPORT_STUB(__imp__DmPMCGetCounterName); +REX_EXPORT_STUB(__imp__DmPMCDumpCounters); +REX_EXPORT_STUB(__imp__DmPMCDumpCountersVerbose); +REX_EXPORT_STUB(__imp__DmPMCGetCounterCostEstimate); +REX_EXPORT_STUB(__imp__DmPMCGetCounterSource); +REX_EXPORT_STUB(__imp__DmPMCComputeFrequency); +REX_EXPORT_STUB(__imp__DmGetAdditionalTitleMemorySetting); +REX_EXPORT_STUB(__imp__DmGetDebugMemorySize); +REX_EXPORT_STUB(__imp__DmGetConsoleDebugMemoryStatus); +REX_EXPORT_STUB(__imp__DmNetSimSetLinkStatusHidden); +REX_EXPORT_STUB(__imp__DmNetSimInsertQueue); +REX_EXPORT_STUB(__imp__DmNetSimRemoveQueue); +REX_EXPORT_STUB(__imp__DmNetSimRemoveAllQueues); +REX_EXPORT_STUB(__imp__DmNetSimModifyQueueSettings); +REX_EXPORT_STUB(__imp__DmGetConsoleFeatures); +REX_EXPORT_STUB(__imp__DmNetSimGetQueueStats); +REX_EXPORT_STUB(__imp__DmNetSimGetQueueSettings); +REX_EXPORT_STUB(__imp__DmNetSimGetNumQueues); +REX_EXPORT_STUB(__imp__DmNetSimInsertIpv4Redirect); +REX_EXPORT_STUB(__imp__DmNetSimRemoveIpv4Redirect); +REX_EXPORT_STUB(__imp__DmNetSimGetNumIpv4Redirects); +REX_EXPORT_STUB(__imp__XLFAllocate); +REX_EXPORT_STUB(__imp__XLFFree); +REX_EXPORT_STUB(__imp__XLFQueueAdd); +REX_EXPORT_STUB(__imp__XLFQueueAllocated); +REX_EXPORT_STUB(__imp__XLFQueueCreate); +REX_EXPORT_STUB(__imp__XLFQueueDestroy); +REX_EXPORT_STUB(__imp__XLFQueueGetEntryCount); +REX_EXPORT_STUB(__imp__XLFQueueIsEmpty); +REX_EXPORT_STUB(__imp__XLFQueueRemove); +REX_EXPORT_STUB(__imp__XLFQueueUnsafeDump); +REX_EXPORT_STUB(__imp__XLFStackAllocated); +REX_EXPORT_STUB(__imp__XLFStackCreate); +REX_EXPORT_STUB(__imp__XLFStackDestroy); +REX_EXPORT_STUB(__imp__XLFStackGetEntryCount); +REX_EXPORT_STUB(__imp__XLFStackIsEmpty); +REX_EXPORT_STUB(__imp__XLFStackPop); +REX_EXPORT_STUB(__imp__XLFStackPush); +REX_EXPORT_STUB(__imp__XLFStackUnsafeDump); +REX_EXPORT_STUB(__imp__XLFPriorityQueueAdd); +REX_EXPORT_STUB(__imp__XLFPriorityQueueAllocated); +REX_EXPORT_STUB(__imp__XLFPriorityQueueCreate); +REX_EXPORT_STUB(__imp__XLFPriorityQueueDestroy); +REX_EXPORT_STUB(__imp__XLFPriorityQueueGetEntryCount); +REX_EXPORT_STUB(__imp__XLFPriorityQueueIsEmpty); +REX_EXPORT_STUB(__imp__XLFPriorityQueueRemoveFirst); +REX_EXPORT_STUB(__imp__XLFPriorityQueueRemove); +REX_EXPORT_STUB(__imp__XLFPriorityQueueUnsafeDump); +REX_EXPORT_STUB(__imp__XLFHashTableAdd); +REX_EXPORT_STUB(__imp__XLFHashTableAllocated); +REX_EXPORT_STUB(__imp__XLFHashTableCreate); +REX_EXPORT_STUB(__imp__XLFHashTableDestroy); +REX_EXPORT_STUB(__imp__XLFHashTableGetEntryCount); +REX_EXPORT_STUB(__imp__XLFHashTableIsEmpty); +REX_EXPORT_STUB(__imp__XLFHashTableRemoveFirst); +REX_EXPORT_STUB(__imp__XLFHashTableRemove); +REX_EXPORT_STUB(__imp__XLFHashTableUnsafeDump); +REX_EXPORT_STUB(__imp__XLFPoolAcquireLock); +REX_EXPORT_STUB(__imp__XLFPoolAllocated); +REX_EXPORT_STUB(__imp__XLFPoolCreate); +REX_EXPORT_STUB(__imp__XLFPoolCreateLock); +REX_EXPORT_STUB(__imp__XLFPoolDestroy); +REX_EXPORT_STUB(__imp__XLFPoolDestroyLock); +REX_EXPORT_STUB(__imp__XLFPoolIncreaseEvents); +REX_EXPORT_STUB(__imp__XLFPoolIncreaseLocks); +REX_EXPORT_STUB(__imp__XLFPoolInitializeLock); +REX_EXPORT_STUB(__imp__XLFPoolNumberOfEvents); +REX_EXPORT_STUB(__imp__XLFPoolNumberOfLocks); +REX_EXPORT_STUB(__imp__XLFPoolReleaseLock); +REX_EXPORT_STUB(__imp__XLFStartLog); +REX_EXPORT_STUB(__imp__XLFStartUserLog); +REX_EXPORT_STUB(__imp__XLFInitializeLog); +REX_EXPORT_STUB(__imp__XLFInitializeUserLog); +REX_EXPORT_STUB(__imp__XLFEndLog); +REX_EXPORT_STUB(__imp__XLFLogPrint); +REX_EXPORT_STUB(__imp__XLFLogPrintV); +REX_EXPORT_STUB(__imp__XLFLogBuffer); +REX_EXPORT_STUB(__imp__XLFLogMessageStats); +REX_EXPORT_STUB(__imp__XLockFreeGetErrorHandler); +REX_EXPORT_STUB(__imp__XLockFreeSetErrorHandler); +REX_EXPORT_STUB(__imp__DmExecuteThreadRPC); +REX_EXPORT_STUB(__imp__DmGetDebuggerConnection); diff --git a/src/kernel/xbdm/xbdm_module.cpp b/src/kernel/xbdm/xbdm_module.cpp new file mode 100644 index 0000000..d3faba7 --- /dev/null +++ b/src/kernel/xbdm/xbdm_module.cpp @@ -0,0 +1,67 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2019 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Joseph Lee, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include +#include + +namespace rex { +namespace kernel { +namespace xbdm { +using namespace rex::system; + +XbdmModule::XbdmModule(Runtime* emulator, KernelState* kernel_state) + : KernelModule(kernel_state, "xe:\\xbdm.xex") { + RegisterExportTable(export_resolver_); + + // Register all exported functions. + // #define XE_MODULE_EXPORT_GROUP(m, n) \ +// Register##n##Exports(export_resolver_, kernel_state_); + // #include + // #undef XE_MODULE_EXPORT_GROUP +} + +std::vector xbdm_exports(4096); + +rex::runtime::Export* RegisterExport_xbdm(rex::runtime::Export* export_entry) { + assert_true(export_entry->ordinal < xbdm_exports.size()); + xbdm_exports[export_entry->ordinal] = export_entry; + return export_entry; +} + +void XbdmModule::RegisterExportTable(rex::runtime::ExportResolver* export_resolver) { + assert_not_null(export_resolver); + +// Build the export table used for resolution. +#include "../export_table_pre.inc" + static rex::runtime::Export xbdm_export_table[] = { +#include "export_table.inc" + }; +#include "../export_table_post.inc" + for (size_t i = 0; i < rex::countof(xbdm_export_table); ++i) { + auto& export_entry = xbdm_export_table[i]; + assert_true(export_entry.ordinal < xbdm_exports.size()); + if (!xbdm_exports[export_entry.ordinal]) { + xbdm_exports[export_entry.ordinal] = &export_entry; + } + } + export_resolver->RegisterTable("xbdm.xex", &xbdm_exports); +} + +XbdmModule::~XbdmModule() {} + +} // namespace xbdm +} // namespace kernel +} // namespace rex diff --git a/src/kernel/xboxkrnl/cert_monitor.cpp b/src/kernel/xboxkrnl/cert_monitor.cpp new file mode 100644 index 0000000..c2786e6 --- /dev/null +++ b/src/kernel/xboxkrnl/cert_monitor.cpp @@ -0,0 +1,34 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { + +void KeCertMonitorCallback(PPCContext* ppc_context, rex::system::KernelState* kernel_state) { + auto id = ppc_context->r[3]; + auto arg = ppc_context->r[4]; + REXKRNL_DEBUG("KeCertMonitorCallback({}, {:08X})", id, arg); + // TODO: Implement cert monitor callback if needed +} + +} // namespace rex::kernel::xboxkrnl diff --git a/src/kernel/xboxkrnl/debug_monitor.cpp b/src/kernel/xboxkrnl/debug_monitor.cpp new file mode 100644 index 0000000..8223e52 --- /dev/null +++ b/src/kernel/xboxkrnl/debug_monitor.cpp @@ -0,0 +1,83 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(kernel_pix, false, "Kernel", "Enable PIX debugging support"); + +namespace rex::kernel::xboxkrnl { + +enum class DebugMonitorCommand { + PIXCommandResult = 27, + SetPIXCallback = 28, + Unknown66 = 66, + Unknown89 = 89, + Unknown94 = 94, +}; + +void KeDebugMonitorCallback(PPCContext* ppc_context, rex::system::KernelState* kernel_state) { + auto id = static_cast(ppc_context->r[3] & 0xFFFFFFFFu); + auto arg = static_cast(ppc_context->r[4] & 0xFFFFFFFFu); + + REXKRNL_DEBUG("KeDebugMonitorCallback({}, {:08X})", static_cast(id), arg); + + if (!REXCVAR_GET(kernel_pix)) { + ppc_context->r[3] = static_cast(-1); + return; + } + + switch (id) { + case DebugMonitorCommand::PIXCommandResult: { + auto s = kernel_state->memory()->TranslateVirtual(arg); + rex::debug::DebugPrint("{}\n", s); + REXKRNL_DEBUG("PIX command result: {}\n", s); + ppc_context->r[3] = 0; + break; + } + case DebugMonitorCommand::SetPIXCallback: + // TODO: Implement PIX callback if needed + ppc_context->r[3] = 0; + break; + case DebugMonitorCommand::Unknown66: { + struct callback_info { + rex::be callback_fn; + rex::be callback_arg; // D3D device object? + }; + auto cbi = kernel_state->memory()->TranslateVirtual(arg); + ppc_context->r[3] = 0; + break; + } + case DebugMonitorCommand::Unknown89: + // arg = function pointer? + ppc_context->r[3] = 0; + break; + case DebugMonitorCommand::Unknown94: + ppc_context->r[3] = 0; + break; + default: + ppc_context->r[3] = static_cast(-1); + break; + } +} + +} // namespace rex::kernel::xboxkrnl diff --git a/src/kernel/xboxkrnl/export_table.inc b/src/kernel/xboxkrnl/export_table.inc new file mode 100644 index 0000000..0e04470 --- /dev/null +++ b/src/kernel/xboxkrnl/export_table.inc @@ -0,0 +1,936 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +// This is a partial file designed to be included by other files when +// constructing various tables. + +// clang-format off + +XE_EXPORT(xboxkrnl, 0x00000001, DbgBreakPoint, kFunction), +XE_EXPORT(xboxkrnl, 0x00000002, DbgBreakPointWithStatus, kFunction), +XE_EXPORT(xboxkrnl, 0x00000003, DbgPrint, kFunction), +XE_EXPORT(xboxkrnl, 0x00000004, DbgPrompt, kFunction), +XE_EXPORT(xboxkrnl, 0x00000005, DumpGetRawDumpInfo, kFunction), +XE_EXPORT(xboxkrnl, 0x00000006, DumpWriteDump, kFunction), +XE_EXPORT(xboxkrnl, 0x00000007, ExAcquireReadWriteLockExclusive, kFunction), +XE_EXPORT(xboxkrnl, 0x00000008, ExAcquireReadWriteLockShared, kFunction), +XE_EXPORT(xboxkrnl, 0x00000009, ExAllocatePool, kFunction), +XE_EXPORT(xboxkrnl, 0x0000000A, ExAllocatePoolWithTag, kFunction), +XE_EXPORT(xboxkrnl, 0x0000000B, ExAllocatePoolTypeWithTag, kFunction), +XE_EXPORT(xboxkrnl, 0x0000000C, ExConsoleGameRegion, kVariable), +XE_EXPORT(xboxkrnl, 0x0000000D, ExCreateThread, kFunction), +XE_EXPORT(xboxkrnl, 0x0000000E, ExEventObjectType, kVariable), +XE_EXPORT(xboxkrnl, 0x0000000F, ExFreePool, kFunction), +XE_EXPORT(xboxkrnl, 0x00000010, ExGetXConfigSetting, kFunction), +XE_EXPORT(xboxkrnl, 0x00000011, ExInitializeReadWriteLock, kFunction), +XE_EXPORT(xboxkrnl, 0x00000012, ExMutantObjectType, kVariable), +XE_EXPORT(xboxkrnl, 0x00000013, ExQueryPoolBlockSize, kFunction), +XE_EXPORT(xboxkrnl, 0x00000014, ExRegisterThreadNotification, kFunction), +XE_EXPORT(xboxkrnl, 0x00000015, ExRegisterTitleTerminateNotification, kFunction), +XE_EXPORT(xboxkrnl, 0x00000016, ExReleaseReadWriteLock, kFunction), +XE_EXPORT(xboxkrnl, 0x00000017, ExSemaphoreObjectType, kVariable), +XE_EXPORT(xboxkrnl, 0x00000018, ExSetXConfigSetting, kFunction), +XE_EXPORT(xboxkrnl, 0x00000019, ExTerminateThread, kFunction), +XE_EXPORT(xboxkrnl, 0x0000001A, ExTerminateTitleProcess, kFunction), +XE_EXPORT(xboxkrnl, 0x0000001B, ExThreadObjectType, kVariable), +XE_EXPORT(xboxkrnl, 0x0000001C, ExTimerObjectType, kVariable), +XE_EXPORT(xboxkrnl, 0x0000001D, MmDoubleMapMemory, kFunction), +XE_EXPORT(xboxkrnl, 0x0000001E, MmUnmapMemory, kFunction), +XE_EXPORT(xboxkrnl, 0x0000001F, XeKeysGetConsoleCertificate, kFunction), +XE_EXPORT(xboxkrnl, 0x00000020, FscGetCacheElementCount, kFunction), +XE_EXPORT(xboxkrnl, 0x00000021, FscSetCacheElementCount, kFunction), +XE_EXPORT(xboxkrnl, 0x00000022, HalGetCurrentAVPack, kFunction), +XE_EXPORT(xboxkrnl, 0x00000023, HalGpioControl, kFunction), +XE_EXPORT(xboxkrnl, 0x00000024, HalOpenCloseODDTray, kFunction), +XE_EXPORT(xboxkrnl, 0x00000025, HalReadWritePCISpace, kFunction), +XE_EXPORT(xboxkrnl, 0x00000026, HalRegisterPowerDownNotification, kFunction), +XE_EXPORT(xboxkrnl, 0x00000027, HalRegisterSMCNotification, kFunction), +XE_EXPORT(xboxkrnl, 0x00000028, HalReturnToFirmware, kFunction), +XE_EXPORT(xboxkrnl, 0x00000029, HalSendSMCMessage, kFunction), +XE_EXPORT(xboxkrnl, 0x0000002A, HalSetAudioEnable, kFunction), +XE_EXPORT(xboxkrnl, 0x0000002B, InterlockedFlushSList, kFunction), +XE_EXPORT(xboxkrnl, 0x0000002C, InterlockedPopEntrySList, kFunction), +XE_EXPORT(xboxkrnl, 0x0000002D, InterlockedPushEntrySList, kFunction), +XE_EXPORT(xboxkrnl, 0x0000002E, IoAcquireDeviceObjectLock, kFunction), +XE_EXPORT(xboxkrnl, 0x0000002F, IoAllocateIrp, kFunction), +XE_EXPORT(xboxkrnl, 0x00000030, IoBuildAsynchronousFsdRequest, kFunction), +XE_EXPORT(xboxkrnl, 0x00000031, IoBuildDeviceIoControlRequest, kFunction), +XE_EXPORT(xboxkrnl, 0x00000032, IoBuildSynchronousFsdRequest, kFunction), +XE_EXPORT(xboxkrnl, 0x00000033, IoCallDriver, kFunction), +XE_EXPORT(xboxkrnl, 0x00000034, IoCheckShareAccess, kFunction), +XE_EXPORT(xboxkrnl, 0x00000035, IoCompleteRequest, kFunction), +XE_EXPORT(xboxkrnl, 0x00000036, IoCompletionObjectType, kVariable), +XE_EXPORT(xboxkrnl, 0x00000037, IoCreateDevice, kFunction), +XE_EXPORT(xboxkrnl, 0x00000038, IoCreateFile, kFunction), +XE_EXPORT(xboxkrnl, 0x00000039, IoDeleteDevice, kFunction), +XE_EXPORT(xboxkrnl, 0x0000003A, IoDeviceObjectType, kVariable), +XE_EXPORT(xboxkrnl, 0x0000003B, IoDismountVolume, kFunction), +XE_EXPORT(xboxkrnl, 0x0000003C, IoDismountVolumeByFileHandle, kFunction), +XE_EXPORT(xboxkrnl, 0x0000003D, IoDismountVolumeByName, kFunction), +XE_EXPORT(xboxkrnl, 0x0000003E, IoFileObjectType, kVariable), +XE_EXPORT(xboxkrnl, 0x0000003F, IoFreeIrp, kFunction), +XE_EXPORT(xboxkrnl, 0x00000040, IoInitializeIrp, kFunction), +XE_EXPORT(xboxkrnl, 0x00000041, IoInvalidDeviceRequest, kFunction), +XE_EXPORT(xboxkrnl, 0x00000042, ExSetBetaFeaturesEnabled, kFunction), +XE_EXPORT(xboxkrnl, 0x00000043, IoQueueThreadIrp, kFunction), +XE_EXPORT(xboxkrnl, 0x00000044, IoReleaseDeviceObjectLock, kFunction), +XE_EXPORT(xboxkrnl, 0x00000045, IoRemoveShareAccess, kFunction), +XE_EXPORT(xboxkrnl, 0x00000046, IoSetIoCompletion, kFunction), +XE_EXPORT(xboxkrnl, 0x00000047, IoSetShareAccess, kFunction), +XE_EXPORT(xboxkrnl, 0x00000048, IoStartNextPacket, kFunction), +XE_EXPORT(xboxkrnl, 0x00000049, IoStartNextPacketByKey, kFunction), +XE_EXPORT(xboxkrnl, 0x0000004A, IoStartPacket, kFunction), +XE_EXPORT(xboxkrnl, 0x0000004B, IoSynchronousDeviceIoControlRequest, kFunction), +XE_EXPORT(xboxkrnl, 0x0000004C, IoSynchronousFsdRequest, kFunction), +XE_EXPORT(xboxkrnl, 0x0000004D, KeAcquireSpinLockAtRaisedIrql, kFunction), +XE_EXPORT(xboxkrnl, 0x0000004E, KeAlertResumeThread, kFunction), +XE_EXPORT(xboxkrnl, 0x0000004F, KeAlertThread, kFunction), +XE_EXPORT(xboxkrnl, 0x00000050, KeBlowFuses, kFunction), +XE_EXPORT(xboxkrnl, 0x00000051, KeBoostPriorityThread, kFunction), +XE_EXPORT(xboxkrnl, 0x00000052, KeBugCheck, kFunction), +XE_EXPORT(xboxkrnl, 0x00000053, KeBugCheckEx, kFunction), +XE_EXPORT(xboxkrnl, 0x00000054, KeCancelTimer, kFunction), +XE_EXPORT(xboxkrnl, 0x00000055, KeConnectInterrupt, kFunction), +XE_EXPORT(xboxkrnl, 0x00000056, KeContextFromKframes, kFunction), +XE_EXPORT(xboxkrnl, 0x00000057, KeContextToKframes, kFunction), +XE_EXPORT(xboxkrnl, 0x00000058, KeCreateUserMode, kFunction), +XE_EXPORT(xboxkrnl, 0x00000059, KeDebugMonitorData, kVariable), +XE_EXPORT(xboxkrnl, 0x0000005A, KeDelayExecutionThread, kFunction), +XE_EXPORT(xboxkrnl, 0x0000005B, KeDeleteUserMode, kFunction), +XE_EXPORT(xboxkrnl, 0x0000005C, KeDisconnectInterrupt, kFunction), +XE_EXPORT(xboxkrnl, 0x0000005D, KeEnableFpuExceptions, kFunction), +XE_EXPORT(xboxkrnl, 0x0000005E, KeEnablePPUPerformanceMonitor, kFunction), +XE_EXPORT(xboxkrnl, 0x0000005F, KeEnterCriticalRegion, kFunction), +XE_EXPORT(xboxkrnl, 0x00000060, KeEnterUserMode, kFunction), +XE_EXPORT(xboxkrnl, 0x00000061, KeFlushCacheRange, kFunction), +XE_EXPORT(xboxkrnl, 0x00000062, KeFlushCurrentEntireTb, kFunction), +XE_EXPORT(xboxkrnl, 0x00000063, KeFlushEntireTb, kFunction), +XE_EXPORT(xboxkrnl, 0x00000064, KeFlushUserModeCurrentTb, kFunction), +XE_EXPORT(xboxkrnl, 0x00000065, KeFlushUserModeTb, kFunction), +XE_EXPORT(xboxkrnl, 0x00000066, KeGetCurrentProcessType, kFunction), +XE_EXPORT(xboxkrnl, 0x00000067, KeGetPMWRegister, kFunction), +XE_EXPORT(xboxkrnl, 0x00000068, KeGetPRVRegister, kFunction), +XE_EXPORT(xboxkrnl, 0x00000069, KeGetSocRegister, kFunction), +XE_EXPORT(xboxkrnl, 0x0000006A, KeGetSpecialPurposeRegister, kFunction), +XE_EXPORT(xboxkrnl, 0x0000006B, KeLockL2, kFunction), +XE_EXPORT(xboxkrnl, 0x0000006C, KeUnlockL2, kFunction), +XE_EXPORT(xboxkrnl, 0x0000006D, KeInitializeApc, kFunction), +XE_EXPORT(xboxkrnl, 0x0000006E, KeInitializeDeviceQueue, kFunction), +XE_EXPORT(xboxkrnl, 0x0000006F, KeInitializeDpc, kFunction), +XE_EXPORT(xboxkrnl, 0x00000070, KeInitializeEvent, kFunction), +XE_EXPORT(xboxkrnl, 0x00000071, KeInitializeInterrupt, kFunction), +XE_EXPORT(xboxkrnl, 0x00000072, KeInitializeMutant, kFunction), +XE_EXPORT(xboxkrnl, 0x00000073, KeInitializeQueue, kFunction), +XE_EXPORT(xboxkrnl, 0x00000074, KeInitializeSemaphore, kFunction), +XE_EXPORT(xboxkrnl, 0x00000075, KeInitializeTimerEx, kFunction), +XE_EXPORT(xboxkrnl, 0x00000076, KeInsertByKeyDeviceQueue, kFunction), +XE_EXPORT(xboxkrnl, 0x00000077, KeInsertDeviceQueue, kFunction), +XE_EXPORT(xboxkrnl, 0x00000078, KeInsertHeadQueue, kFunction), +XE_EXPORT(xboxkrnl, 0x00000079, KeInsertQueue, kFunction), +XE_EXPORT(xboxkrnl, 0x0000007A, KeInsertQueueApc, kFunction), +XE_EXPORT(xboxkrnl, 0x0000007B, KeInsertQueueDpc, kFunction), +XE_EXPORT(xboxkrnl, 0x0000007C, KeIpiGenericCall, kFunction), +XE_EXPORT(xboxkrnl, 0x0000007D, KeLeaveCriticalRegion, kFunction), +XE_EXPORT(xboxkrnl, 0x0000007E, KeLeaveUserMode, kFunction), +XE_EXPORT(xboxkrnl, 0x0000007F, KePulseEvent, kFunction), +XE_EXPORT(xboxkrnl, 0x00000080, KeQueryBackgroundProcessors, kFunction), +XE_EXPORT(xboxkrnl, 0x00000081, KeQueryBasePriorityThread, kFunction), +XE_EXPORT(xboxkrnl, 0x00000082, KeQueryInterruptTime, kFunction), +XE_EXPORT(xboxkrnl, 0x00000083, KeQueryPerformanceFrequency, kFunction), +XE_EXPORT(xboxkrnl, 0x00000084, KeQuerySystemTime, kFunction), +XE_EXPORT(xboxkrnl, 0x00000085, KeRaiseIrqlToDpcLevel, kFunction), +XE_EXPORT(xboxkrnl, 0x00000086, KeRegisterDriverNotification, kFunction), +XE_EXPORT(xboxkrnl, 0x00000087, KeReleaseMutant, kFunction), +XE_EXPORT(xboxkrnl, 0x00000088, KeReleaseSemaphore, kFunction), +XE_EXPORT(xboxkrnl, 0x00000089, KeReleaseSpinLockFromRaisedIrql, kFunction), +XE_EXPORT(xboxkrnl, 0x0000008A, KeRemoveByKeyDeviceQueue, kFunction), +XE_EXPORT(xboxkrnl, 0x0000008B, KeRemoveDeviceQueue, kFunction), +XE_EXPORT(xboxkrnl, 0x0000008C, KeRemoveEntryDeviceQueue, kFunction), +XE_EXPORT(xboxkrnl, 0x0000008D, KeRemoveQueue, kFunction), +XE_EXPORT(xboxkrnl, 0x0000008E, KeRemoveQueueDpc, kFunction), +XE_EXPORT(xboxkrnl, 0x0000008F, KeResetEvent, kFunction), +XE_EXPORT(xboxkrnl, 0x00000090, KeRestoreFloatingPointState, kFunction), +XE_EXPORT(xboxkrnl, 0x00000091, KeRestoreVectorUnitState, kFunction), +XE_EXPORT(xboxkrnl, 0x00000092, KeResumeThread, kFunction), +XE_EXPORT(xboxkrnl, 0x00000093, KeRetireDpcList, kFunction), +XE_EXPORT(xboxkrnl, 0x00000094, KeRundownQueue, kFunction), +XE_EXPORT(xboxkrnl, 0x00000095, KeSaveFloatingPointState, kFunction), +XE_EXPORT(xboxkrnl, 0x00000096, KeSaveVectorUnitState, kFunction), +XE_EXPORT(xboxkrnl, 0x00000097, KeSetAffinityThread, kFunction), +XE_EXPORT(xboxkrnl, 0x00000098, KeSetBackgroundProcessors, kFunction), +XE_EXPORT(xboxkrnl, 0x00000099, KeSetBasePriorityThread, kFunction), +XE_EXPORT(xboxkrnl, 0x0000009A, KeSetCurrentProcessType, kFunction), +XE_EXPORT(xboxkrnl, 0x0000009B, KeSetCurrentStackPointers, kFunction), +XE_EXPORT(xboxkrnl, 0x0000009C, KeSetDisableBoostThread, kFunction), +XE_EXPORT(xboxkrnl, 0x0000009D, KeSetEvent, kFunction), +XE_EXPORT(xboxkrnl, 0x0000009E, KeSetEventBoostPriority, kFunction), +XE_EXPORT(xboxkrnl, 0x0000009F, KeSetPMWRegister, kFunction), +XE_EXPORT(xboxkrnl, 0x000000A0, KeSetPowerMode, kFunction), +XE_EXPORT(xboxkrnl, 0x000000A1, KeSetPRVRegister, kFunction), +XE_EXPORT(xboxkrnl, 0x000000A2, KeSetPriorityClassThread, kFunction), +XE_EXPORT(xboxkrnl, 0x000000A3, KeSetPriorityThread, kFunction), +XE_EXPORT(xboxkrnl, 0x000000A4, KeSetSocRegister, kFunction), +XE_EXPORT(xboxkrnl, 0x000000A5, KeSetSpecialPurposeRegister, kFunction), +XE_EXPORT(xboxkrnl, 0x000000A6, KeSetTimer, kFunction), +XE_EXPORT(xboxkrnl, 0x000000A7, KeSetTimerEx, kFunction), +XE_EXPORT(xboxkrnl, 0x000000A8, KeStallExecutionProcessor, kFunction), +XE_EXPORT(xboxkrnl, 0x000000A9, KeSuspendThread, kFunction), +XE_EXPORT(xboxkrnl, 0x000000AA, KeSweepDcacheRange, kFunction), +XE_EXPORT(xboxkrnl, 0x000000AB, KeSweepIcacheRange, kFunction), +XE_EXPORT(xboxkrnl, 0x000000AC, KeTestAlertThread, kFunction), +XE_EXPORT(xboxkrnl, 0x000000AD, KeTimeStampBundle, kVariable), +XE_EXPORT(xboxkrnl, 0x000000AE, KeTryToAcquireSpinLockAtRaisedIrql, kFunction), +XE_EXPORT(xboxkrnl, 0x000000AF, KeWaitForMultipleObjects, kFunction), +XE_EXPORT(xboxkrnl, 0x000000B0, KeWaitForSingleObject, kFunction), +XE_EXPORT(xboxkrnl, 0x000000B1, KfAcquireSpinLock, kFunction), +XE_EXPORT(xboxkrnl, 0x000000B2, KfRaiseIrql, kFunction), +XE_EXPORT(xboxkrnl, 0x000000B3, KfLowerIrql, kFunction), +XE_EXPORT(xboxkrnl, 0x000000B4, KfReleaseSpinLock, kFunction), +XE_EXPORT(xboxkrnl, 0x000000B5, KiBugCheckData, kVariable), +XE_EXPORT(xboxkrnl, 0x000000B6, LDICreateDecompression, kFunction), +XE_EXPORT(xboxkrnl, 0x000000B7, LDIDecompress, kFunction), +XE_EXPORT(xboxkrnl, 0x000000B8, LDIDestroyDecompression, kFunction), +XE_EXPORT(xboxkrnl, 0x000000B9, MmAllocatePhysicalMemory, kFunction), +XE_EXPORT(xboxkrnl, 0x000000BA, MmAllocatePhysicalMemoryEx, kFunction), +XE_EXPORT(xboxkrnl, 0x000000BB, MmCreateKernelStack, kFunction), +XE_EXPORT(xboxkrnl, 0x000000BC, MmDeleteKernelStack, kFunction), +XE_EXPORT(xboxkrnl, 0x000000BD, MmFreePhysicalMemory, kFunction), +XE_EXPORT(xboxkrnl, 0x000000BE, MmGetPhysicalAddress, kFunction), +XE_EXPORT(xboxkrnl, 0x000000BF, MmIsAddressValid, kFunction), +XE_EXPORT(xboxkrnl, 0x000000C0, MmLockAndMapSegmentArray, kFunction), +XE_EXPORT(xboxkrnl, 0x000000C1, MmLockUnlockBufferPages, kFunction), +XE_EXPORT(xboxkrnl, 0x000000C2, MmMapIoSpace, kFunction), +XE_EXPORT(xboxkrnl, 0x000000C3, MmPersistPhysicalMemoryAllocation, kFunction), +XE_EXPORT(xboxkrnl, 0x000000C4, MmQueryAddressProtect, kFunction), +XE_EXPORT(xboxkrnl, 0x000000C5, MmQueryAllocationSize, kFunction), +XE_EXPORT(xboxkrnl, 0x000000C6, MmQueryStatistics, kFunction), +XE_EXPORT(xboxkrnl, 0x000000C7, MmSetAddressProtect, kFunction), +XE_EXPORT(xboxkrnl, 0x000000C8, MmSplitPhysicalMemoryAllocation, kFunction), +XE_EXPORT(xboxkrnl, 0x000000C9, MmUnlockAndUnmapSegmentArray, kFunction), +XE_EXPORT(xboxkrnl, 0x000000CA, MmUnmapIoSpace, kFunction), +XE_EXPORT(xboxkrnl, 0x000000CB, Nls844UnicodeCaseTable, kVariable), +XE_EXPORT(xboxkrnl, 0x000000CC, NtAllocateVirtualMemory, kFunction), +XE_EXPORT(xboxkrnl, 0x000000CD, NtCancelTimer, kFunction), +XE_EXPORT(xboxkrnl, 0x000000CE, NtClearEvent, kFunction), +XE_EXPORT(xboxkrnl, 0x000000CF, NtClose, kFunction), +XE_EXPORT(xboxkrnl, 0x000000D0, NtCreateDirectoryObject, kFunction), +XE_EXPORT(xboxkrnl, 0x000000D1, NtCreateEvent, kFunction), +XE_EXPORT(xboxkrnl, 0x000000D2, NtCreateFile, kFunction), +XE_EXPORT(xboxkrnl, 0x000000D3, NtCreateIoCompletion, kFunction), +XE_EXPORT(xboxkrnl, 0x000000D4, NtCreateMutant, kFunction), +XE_EXPORT(xboxkrnl, 0x000000D5, NtCreateSemaphore, kFunction), +XE_EXPORT(xboxkrnl, 0x000000D6, NtCreateSymbolicLinkObject, kFunction), +XE_EXPORT(xboxkrnl, 0x000000D7, NtCreateTimer, kFunction), +XE_EXPORT(xboxkrnl, 0x000000D8, NtDeleteFile, kFunction), +XE_EXPORT(xboxkrnl, 0x000000D9, NtDeviceIoControlFile, kFunction), +XE_EXPORT(xboxkrnl, 0x000000DA, NtDuplicateObject, kFunction), +XE_EXPORT(xboxkrnl, 0x000000DB, NtFlushBuffersFile, kFunction), +XE_EXPORT(xboxkrnl, 0x000000DC, NtFreeVirtualMemory, kFunction), +XE_EXPORT(xboxkrnl, 0x000000DD, NtMakeTemporaryObject, kFunction), +XE_EXPORT(xboxkrnl, 0x000000DE, NtOpenDirectoryObject, kFunction), +XE_EXPORT(xboxkrnl, 0x000000DF, NtOpenFile, kFunction), +XE_EXPORT(xboxkrnl, 0x000000E0, NtOpenSymbolicLinkObject, kFunction), +XE_EXPORT(xboxkrnl, 0x000000E1, NtProtectVirtualMemory, kFunction), +XE_EXPORT(xboxkrnl, 0x000000E2, NtPulseEvent, kFunction), +XE_EXPORT(xboxkrnl, 0x000000E3, NtQueueApcThread, kFunction), +XE_EXPORT(xboxkrnl, 0x000000E4, NtQueryDirectoryFile, kFunction), +XE_EXPORT(xboxkrnl, 0x000000E5, NtQueryDirectoryObject, kFunction), +XE_EXPORT(xboxkrnl, 0x000000E6, NtQueryEvent, kFunction), +XE_EXPORT(xboxkrnl, 0x000000E7, NtQueryFullAttributesFile, kFunction), +XE_EXPORT(xboxkrnl, 0x000000E8, NtQueryInformationFile, kFunction), +XE_EXPORT(xboxkrnl, 0x000000E9, NtQueryIoCompletion, kFunction), +XE_EXPORT(xboxkrnl, 0x000000EA, NtQueryMutant, kFunction), +XE_EXPORT(xboxkrnl, 0x000000EB, NtQuerySemaphore, kFunction), +XE_EXPORT(xboxkrnl, 0x000000EC, NtQuerySymbolicLinkObject, kFunction), +XE_EXPORT(xboxkrnl, 0x000000ED, NtQueryTimer, kFunction), +XE_EXPORT(xboxkrnl, 0x000000EE, NtQueryVirtualMemory, kFunction), +XE_EXPORT(xboxkrnl, 0x000000EF, NtQueryVolumeInformationFile, kFunction), +XE_EXPORT(xboxkrnl, 0x000000F0, NtReadFile, kFunction), +XE_EXPORT(xboxkrnl, 0x000000F1, NtReadFileScatter, kFunction), +XE_EXPORT(xboxkrnl, 0x000000F2, NtReleaseMutant, kFunction), +XE_EXPORT(xboxkrnl, 0x000000F3, NtReleaseSemaphore, kFunction), +XE_EXPORT(xboxkrnl, 0x000000F4, NtRemoveIoCompletion, kFunction), +XE_EXPORT(xboxkrnl, 0x000000F5, NtResumeThread, kFunction), +XE_EXPORT(xboxkrnl, 0x000000F6, NtSetEvent, kFunction), +XE_EXPORT(xboxkrnl, 0x000000F7, NtSetInformationFile, kFunction), +XE_EXPORT(xboxkrnl, 0x000000F8, NtSetIoCompletion, kFunction), +XE_EXPORT(xboxkrnl, 0x000000F9, NtSetSystemTime, kFunction), +XE_EXPORT(xboxkrnl, 0x000000FA, NtSetTimerEx, kFunction), +XE_EXPORT(xboxkrnl, 0x000000FB, NtSignalAndWaitForSingleObjectEx, kFunction), +XE_EXPORT(xboxkrnl, 0x000000FC, NtSuspendThread, kFunction), +XE_EXPORT(xboxkrnl, 0x000000FD, NtWaitForSingleObjectEx, kFunction), +XE_EXPORT(xboxkrnl, 0x000000FE, NtWaitForMultipleObjectsEx, kFunction), +XE_EXPORT(xboxkrnl, 0x000000FF, NtWriteFile, kFunction), +XE_EXPORT(xboxkrnl, 0x00000100, NtWriteFileGather, kFunction), +XE_EXPORT(xboxkrnl, 0x00000101, NtYieldExecution, kFunction), +XE_EXPORT(xboxkrnl, 0x00000102, ObCreateObject, kFunction), +XE_EXPORT(xboxkrnl, 0x00000103, ObCreateSymbolicLink, kFunction), +XE_EXPORT(xboxkrnl, 0x00000104, ObDeleteSymbolicLink, kFunction), +XE_EXPORT(xboxkrnl, 0x00000105, ObDereferenceObject, kFunction), +XE_EXPORT(xboxkrnl, 0x00000106, ObDirectoryObjectType, kVariable), +XE_EXPORT(xboxkrnl, 0x00000107, ObGetWaitableObject, kFunction), +XE_EXPORT(xboxkrnl, 0x00000108, ObInsertObject, kFunction), +XE_EXPORT(xboxkrnl, 0x00000109, ObIsTitleObject, kFunction), +XE_EXPORT(xboxkrnl, 0x0000010A, ObLookupAnyThreadByThreadId, kFunction), +XE_EXPORT(xboxkrnl, 0x0000010B, ObLookupThreadByThreadId, kFunction), +XE_EXPORT(xboxkrnl, 0x0000010C, ObMakeTemporaryObject, kFunction), +XE_EXPORT(xboxkrnl, 0x0000010D, ObOpenObjectByName, kFunction), +XE_EXPORT(xboxkrnl, 0x0000010E, ObOpenObjectByPointer, kFunction), +XE_EXPORT(xboxkrnl, 0x0000010F, ObReferenceObject, kFunction), +XE_EXPORT(xboxkrnl, 0x00000110, ObReferenceObjectByHandle, kFunction), +XE_EXPORT(xboxkrnl, 0x00000111, ObReferenceObjectByName, kFunction), +XE_EXPORT(xboxkrnl, 0x00000112, ObSymbolicLinkObjectType, kVariable), +XE_EXPORT(xboxkrnl, 0x00000113, ObTranslateSymbolicLink, kFunction), +XE_EXPORT(xboxkrnl, 0x00000114, RtlAnsiStringToUnicodeString, kFunction), +XE_EXPORT(xboxkrnl, 0x00000115, RtlAppendStringToString, kFunction), +XE_EXPORT(xboxkrnl, 0x00000116, RtlAppendUnicodeStringToString, kFunction), +XE_EXPORT(xboxkrnl, 0x00000117, RtlAppendUnicodeToString, kFunction), +XE_EXPORT(xboxkrnl, 0x00000118, RtlAssert, kFunction), +XE_EXPORT(xboxkrnl, 0x00000119, RtlCaptureContext, kFunction), +XE_EXPORT(xboxkrnl, 0x0000011A, RtlCompareMemory, kFunction), +XE_EXPORT(xboxkrnl, 0x0000011B, RtlCompareMemoryUlong, kFunction), +XE_EXPORT(xboxkrnl, 0x0000011C, RtlCompareString, kFunction), +XE_EXPORT(xboxkrnl, 0x0000011D, RtlCompareStringN, kFunction), +XE_EXPORT(xboxkrnl, 0x0000011E, RtlCompareUnicodeString, kFunction), +XE_EXPORT(xboxkrnl, 0x0000011F, RtlCompareUnicodeStringN, kFunction), +XE_EXPORT(xboxkrnl, 0x00000120, RtlCompareUtf8ToUnicode, kFunction), +XE_EXPORT(xboxkrnl, 0x00000121, RtlCopyString, kFunction), +XE_EXPORT(xboxkrnl, 0x00000122, RtlCopyUnicodeString, kFunction), +XE_EXPORT(xboxkrnl, 0x00000123, RtlCreateUnicodeString, kFunction), +XE_EXPORT(xboxkrnl, 0x00000124, RtlDowncaseUnicodeChar, kFunction), +XE_EXPORT(xboxkrnl, 0x00000125, RtlEnterCriticalSection, kFunction), +XE_EXPORT(xboxkrnl, 0x00000126, RtlFillMemoryUlong, kFunction), +XE_EXPORT(xboxkrnl, 0x00000127, RtlFreeAnsiString, kFunction), +XE_EXPORT(xboxkrnl, 0x00000128, RtlFreeUnicodeString, kFunction), +XE_EXPORT(xboxkrnl, 0x00000129, RtlGetCallersAddress, kFunction), +XE_EXPORT(xboxkrnl, 0x0000012A, RtlGetStackLimits, kFunction), +XE_EXPORT(xboxkrnl, 0x0000012B, RtlImageXexHeaderField, kFunction), +XE_EXPORT(xboxkrnl, 0x0000012C, RtlInitAnsiString, kFunction), +XE_EXPORT(xboxkrnl, 0x0000012D, RtlInitUnicodeString, kFunction), +XE_EXPORT(xboxkrnl, 0x0000012E, RtlInitializeCriticalSection, kFunction), +XE_EXPORT(xboxkrnl, 0x0000012F, RtlInitializeCriticalSectionAndSpinCount, kFunction), +XE_EXPORT(xboxkrnl, 0x00000130, RtlLeaveCriticalSection, kFunction), +XE_EXPORT(xboxkrnl, 0x00000131, RtlLookupFunctionEntry, kFunction), +XE_EXPORT(xboxkrnl, 0x00000132, RtlLowerChar, kFunction), +XE_EXPORT(xboxkrnl, 0x00000133, RtlMultiByteToUnicodeN, kFunction), +XE_EXPORT(xboxkrnl, 0x00000134, RtlMultiByteToUnicodeSize, kFunction), +XE_EXPORT(xboxkrnl, 0x00000135, RtlNtStatusToDosError, kFunction), +XE_EXPORT(xboxkrnl, 0x00000136, RtlRaiseException, kFunction), +XE_EXPORT(xboxkrnl, 0x00000137, RtlRaiseStatus, kFunction), +XE_EXPORT(xboxkrnl, 0x00000138, RtlRip, kFunction), +XE_EXPORT(xboxkrnl, 0x00000139, _scprintf, kFunction), +XE_EXPORT(xboxkrnl, 0x0000013A, _snprintf, kFunction), +XE_EXPORT(xboxkrnl, 0x0000013B, sprintf, kFunction), +XE_EXPORT(xboxkrnl, 0x0000013C, _scwprintf, kFunction), +XE_EXPORT(xboxkrnl, 0x0000013D, _snwprintf, kFunction), +XE_EXPORT(xboxkrnl, 0x0000013E, swprintf, kFunction), +XE_EXPORT(xboxkrnl, 0x0000013F, RtlTimeFieldsToTime, kFunction), +XE_EXPORT(xboxkrnl, 0x00000140, RtlTimeToTimeFields, kFunction), +XE_EXPORT(xboxkrnl, 0x00000141, RtlTryEnterCriticalSection, kFunction), +XE_EXPORT(xboxkrnl, 0x00000142, RtlUnicodeStringToAnsiString, kFunction), +XE_EXPORT(xboxkrnl, 0x00000143, RtlUnicodeToMultiByteN, kFunction), +XE_EXPORT(xboxkrnl, 0x00000144, RtlUnicodeToMultiByteSize, kFunction), +XE_EXPORT(xboxkrnl, 0x00000145, RtlUnicodeToUtf8, kFunction), +XE_EXPORT(xboxkrnl, 0x00000146, RtlUnicodeToUtf8Size, kFunction), +XE_EXPORT(xboxkrnl, 0x00000147, RtlUnwind, kFunction), +XE_EXPORT(xboxkrnl, 0x00000148, RtlUnwind2, kFunction), +XE_EXPORT(xboxkrnl, 0x00000149, RtlUpcaseUnicodeChar, kFunction), +XE_EXPORT(xboxkrnl, 0x0000014A, RtlUpperChar, kFunction), +XE_EXPORT(xboxkrnl, 0x0000014B, RtlVirtualUnwind, kFunction), +XE_EXPORT(xboxkrnl, 0x0000014C, _vscprintf, kFunction), +XE_EXPORT(xboxkrnl, 0x0000014D, _vsnprintf, kFunction), +XE_EXPORT(xboxkrnl, 0x0000014E, vsprintf, kFunction), +XE_EXPORT(xboxkrnl, 0x0000014F, _vscwprintf, kFunction), +XE_EXPORT(xboxkrnl, 0x00000150, _vsnwprintf, kFunction), +XE_EXPORT(xboxkrnl, 0x00000151, vswprintf, kFunction), +XE_EXPORT(xboxkrnl, 0x00000152, KeTlsAlloc, kFunction), +XE_EXPORT(xboxkrnl, 0x00000153, KeTlsFree, kFunction), +XE_EXPORT(xboxkrnl, 0x00000154, KeTlsGetValue, kFunction), +XE_EXPORT(xboxkrnl, 0x00000155, KeTlsSetValue, kFunction), +XE_EXPORT(xboxkrnl, 0x00000156, XboxHardwareInfo, kVariable), +XE_EXPORT(xboxkrnl, 0x00000157, XboxKrnlBaseVersion, kVariable), +XE_EXPORT(xboxkrnl, 0x00000158, XboxKrnlVersion, kVariable), +XE_EXPORT(xboxkrnl, 0x00000159, XeCryptAesKey, kFunction), +XE_EXPORT(xboxkrnl, 0x0000015A, XeCryptAesEcb, kFunction), +XE_EXPORT(xboxkrnl, 0x0000015B, XeCryptAesCbc, kFunction), +XE_EXPORT(xboxkrnl, 0x0000015C, XeCryptBnDwLeDhEqualBase, kFunction), +XE_EXPORT(xboxkrnl, 0x0000015D, XeCryptBnDwLeDhInvalBase, kFunction), +XE_EXPORT(xboxkrnl, 0x0000015E, XeCryptBnDwLeDhModExp, kFunction), +XE_EXPORT(xboxkrnl, 0x0000015F, XeCryptBnDw_Copy, kFunction), +XE_EXPORT(xboxkrnl, 0x00000160, XeCryptBnDw_SwapLeBe, kFunction), +XE_EXPORT(xboxkrnl, 0x00000161, XeCryptBnDw_Zero, kFunction), +XE_EXPORT(xboxkrnl, 0x00000162, XeCryptBnDwLePkcs1Format, kFunction), +XE_EXPORT(xboxkrnl, 0x00000163, XeCryptBnDwLePkcs1Verify, kFunction), +XE_EXPORT(xboxkrnl, 0x00000164, XeCryptBnQwBeSigCreate, kFunction), +XE_EXPORT(xboxkrnl, 0x00000165, XeCryptBnQwBeSigFormat, kFunction), +XE_EXPORT(xboxkrnl, 0x00000166, XeCryptBnQwBeSigVerify, kFunction), +XE_EXPORT(xboxkrnl, 0x00000167, XeCryptBnQwNeModExp, kFunction), +XE_EXPORT(xboxkrnl, 0x00000168, XeCryptBnQwNeModExpRoot, kFunction), +XE_EXPORT(xboxkrnl, 0x00000169, XeCryptBnQwNeModInv, kFunction), +XE_EXPORT(xboxkrnl, 0x0000016A, XeCryptBnQwNeModMul, kFunction), +XE_EXPORT(xboxkrnl, 0x0000016B, XeCryptBnQwNeRsaKeyGen, kFunction), +XE_EXPORT(xboxkrnl, 0x0000016C, XeCryptBnQwNeRsaPrvCrypt, kFunction), +XE_EXPORT(xboxkrnl, 0x0000016D, XeCryptBnQwNeRsaPubCrypt, kFunction), +XE_EXPORT(xboxkrnl, 0x0000016E, XeCryptBnQw_Copy, kFunction), +XE_EXPORT(xboxkrnl, 0x0000016F, XeCryptBnQw_SwapDwQw, kFunction), +XE_EXPORT(xboxkrnl, 0x00000170, XeCryptBnQw_SwapDwQwLeBe, kFunction), +XE_EXPORT(xboxkrnl, 0x00000171, XeCryptBnQw_SwapLeBe, kFunction), +XE_EXPORT(xboxkrnl, 0x00000172, XeCryptBnQw_Zero, kFunction), +XE_EXPORT(xboxkrnl, 0x00000173, XeCryptChainAndSumMac, kFunction), +XE_EXPORT(xboxkrnl, 0x00000174, XeCryptDesParity, kFunction), +XE_EXPORT(xboxkrnl, 0x00000175, XeCryptDesKey, kFunction), +XE_EXPORT(xboxkrnl, 0x00000176, XeCryptDesEcb, kFunction), +XE_EXPORT(xboxkrnl, 0x00000177, XeCryptDesCbc, kFunction), +XE_EXPORT(xboxkrnl, 0x00000178, XeCryptDes3Key, kFunction), +XE_EXPORT(xboxkrnl, 0x00000179, XeCryptDes3Ecb, kFunction), +XE_EXPORT(xboxkrnl, 0x0000017A, XeCryptDes3Cbc, kFunction), +XE_EXPORT(xboxkrnl, 0x0000017B, XeCryptHmacMd5Init, kFunction), +XE_EXPORT(xboxkrnl, 0x0000017C, XeCryptHmacMd5Update, kFunction), +XE_EXPORT(xboxkrnl, 0x0000017D, XeCryptHmacMd5Final, kFunction), +XE_EXPORT(xboxkrnl, 0x0000017E, XeCryptHmacMd5, kFunction), +XE_EXPORT(xboxkrnl, 0x0000017F, XeCryptHmacShaInit, kFunction), +XE_EXPORT(xboxkrnl, 0x00000180, XeCryptHmacShaUpdate, kFunction), +XE_EXPORT(xboxkrnl, 0x00000181, XeCryptHmacShaFinal, kFunction), +XE_EXPORT(xboxkrnl, 0x00000182, XeCryptHmacSha, kFunction), +XE_EXPORT(xboxkrnl, 0x00000183, XeCryptHmacShaVerify, kFunction), +XE_EXPORT(xboxkrnl, 0x00000184, XeCryptMd5Init, kFunction), +XE_EXPORT(xboxkrnl, 0x00000185, XeCryptMd5Update, kFunction), +XE_EXPORT(xboxkrnl, 0x00000186, XeCryptMd5Final, kFunction), +XE_EXPORT(xboxkrnl, 0x00000187, XeCryptMd5, kFunction), +XE_EXPORT(xboxkrnl, 0x00000188, XeCryptParveEcb, kFunction), +XE_EXPORT(xboxkrnl, 0x00000189, XeCryptParveCbcMac, kFunction), +XE_EXPORT(xboxkrnl, 0x0000018A, XeCryptRandom, kFunction), +XE_EXPORT(xboxkrnl, 0x0000018B, XeCryptRc4Key, kFunction), +XE_EXPORT(xboxkrnl, 0x0000018C, XeCryptRc4Ecb, kFunction), +XE_EXPORT(xboxkrnl, 0x0000018D, XeCryptRc4, kFunction), +XE_EXPORT(xboxkrnl, 0x0000018E, XeCryptRotSumSha, kFunction), +XE_EXPORT(xboxkrnl, 0x0000018F, XeCryptShaInit, kFunction), +XE_EXPORT(xboxkrnl, 0x00000190, XeCryptShaUpdate, kFunction), +XE_EXPORT(xboxkrnl, 0x00000191, XeCryptShaFinal, kFunction), +XE_EXPORT(xboxkrnl, 0x00000192, XeCryptSha, kFunction), +XE_EXPORT(xboxkrnl, 0x00000193, XexExecutableModuleHandle, kVariable), +XE_EXPORT(xboxkrnl, 0x00000194, XexCheckExecutablePrivilege, kFunction), +XE_EXPORT(xboxkrnl, 0x00000195, XexGetModuleHandle, kFunction), +XE_EXPORT(xboxkrnl, 0x00000196, XexGetModuleSection, kFunction), +XE_EXPORT(xboxkrnl, 0x00000197, XexGetProcedureAddress, kFunction), +XE_EXPORT(xboxkrnl, 0x00000198, XexLoadExecutable, kFunction), +XE_EXPORT(xboxkrnl, 0x00000199, XexLoadImage, kFunction), +XE_EXPORT(xboxkrnl, 0x0000019A, XexLoadImageFromMemory, kFunction), +XE_EXPORT(xboxkrnl, 0x0000019B, XexLoadImageHeaders, kFunction), +XE_EXPORT(xboxkrnl, 0x0000019C, XexPcToFileHeader, kFunction), +XE_EXPORT(xboxkrnl, 0x0000019D, KiApcNormalRoutineNop_, kFunction), +XE_EXPORT(xboxkrnl, 0x0000019E, XexRegisterPatchDescriptor, kFunction), +XE_EXPORT(xboxkrnl, 0x0000019F, XexSendDeferredNotifications, kFunction), +XE_EXPORT(xboxkrnl, 0x000001A0, XexStartExecutable, kFunction), +XE_EXPORT(xboxkrnl, 0x000001A1, XexUnloadImage, kFunction), +XE_EXPORT(xboxkrnl, 0x000001A2, XexUnloadImageAndExitThread, kFunction), +XE_EXPORT(xboxkrnl, 0x000001A3, XexUnloadTitleModules, kFunction), +XE_EXPORT(xboxkrnl, 0x000001A4, XexVerifyImageHeaders, kFunction), +XE_EXPORT(xboxkrnl, 0x000001A5, __C_specific_handler, kFunction), +XE_EXPORT(xboxkrnl, 0x000001A6, DbgLoadImageSymbols, kFunction), +XE_EXPORT(xboxkrnl, 0x000001A7, DbgUnLoadImageSymbols, kFunction), +XE_EXPORT(xboxkrnl, 0x000001A8, RtlImageDirectoryEntryToData, kFunction), +XE_EXPORT(xboxkrnl, 0x000001A9, RtlImageNtHeader, kFunction), +XE_EXPORT(xboxkrnl, 0x000001AA, ExDebugMonitorService, kFunction), +XE_EXPORT(xboxkrnl, 0x000001AB, MmDbgReadCheck, kFunction), +XE_EXPORT(xboxkrnl, 0x000001AC, MmDbgReleaseAddress, kFunction), +XE_EXPORT(xboxkrnl, 0x000001AD, MmDbgWriteCheck, kFunction), +XE_EXPORT(xboxkrnl, 0x000001AE, ExLoadedCommandLine, kVariable), +XE_EXPORT(xboxkrnl, 0x000001AF, ExLoadedImageName, kVariable), +XE_EXPORT(xboxkrnl, 0x000001B0, VdBlockUntilGUIIdle, kFunction), +XE_EXPORT(xboxkrnl, 0x000001B1, VdCallGraphicsNotificationRoutines, kFunction), +XE_EXPORT(xboxkrnl, 0x000001B2, VdDisplayFatalError, kFunction), +XE_EXPORT(xboxkrnl, 0x000001B3, VdEnableClosedCaption, kFunction), +XE_EXPORT(xboxkrnl, 0x000001B4, VdEnableDisableClockGating, kFunction), +XE_EXPORT(xboxkrnl, 0x000001B5, VdEnableDisablePowerSavingMode, kFunction), +XE_EXPORT(xboxkrnl, 0x000001B6, VdEnableRingBufferRPtrWriteBack, kFunction), +XE_EXPORT(xboxkrnl, 0x000001B7, VdGenerateGPUCSCCoefficients, kFunction), +XE_EXPORT(xboxkrnl, 0x000001B8, VdGetClosedCaptionReadyStatus, kFunction), +XE_EXPORT(xboxkrnl, 0x000001B9, VdGetCurrentDisplayGamma, kFunction), +XE_EXPORT(xboxkrnl, 0x000001BA, VdGetCurrentDisplayInformation, kFunction), +XE_EXPORT(xboxkrnl, 0x000001BB, VdGetDisplayModeOverride, kFunction), +XE_EXPORT(xboxkrnl, 0x000001BC, VdGetGraphicsAsicID, kFunction), +XE_EXPORT(xboxkrnl, 0x000001BD, VdGetSystemCommandBuffer, kFunction), +XE_EXPORT(xboxkrnl, 0x000001BE, VdGlobalDevice, kVariable), +XE_EXPORT(xboxkrnl, 0x000001BF, VdGlobalXamDevice, kVariable), +XE_EXPORT(xboxkrnl, 0x000001C0, VdGpuClockInMHz, kVariable), +XE_EXPORT(xboxkrnl, 0x000001C1, VdHSIOCalibrationLock, kVariable), +XE_EXPORT(xboxkrnl, 0x000001C2, VdInitializeEngines, kFunction), +XE_EXPORT(xboxkrnl, 0x000001C3, VdInitializeRingBuffer, kFunction), +XE_EXPORT(xboxkrnl, 0x000001C4, VdInitializeScaler, kFunction), +XE_EXPORT(xboxkrnl, 0x000001C5, VdInitializeScalerCommandBuffer, kFunction), +XE_EXPORT(xboxkrnl, 0x000001C6, VdIsHSIOTrainingSucceeded, kFunction), +XE_EXPORT(xboxkrnl, 0x000001C7, VdPersistDisplay, kFunction), +XE_EXPORT(xboxkrnl, 0x000001C8, VdQuerySystemCommandBuffer, kFunction), +XE_EXPORT(xboxkrnl, 0x000001C9, VdQueryVideoFlags, kFunction), +XE_EXPORT(xboxkrnl, 0x000001CA, VdQueryVideoMode, kFunction), +XE_EXPORT(xboxkrnl, 0x000001CB, VdReadDVERegisterUlong, kFunction), +XE_EXPORT(xboxkrnl, 0x000001CC, VdReadWriteHSIOCalibrationFlag, kFunction), +XE_EXPORT(xboxkrnl, 0x000001CD, VdRegisterGraphicsNotification, kFunction), +XE_EXPORT(xboxkrnl, 0x000001CE, VdRegisterXamGraphicsNotification, kFunction), +XE_EXPORT(xboxkrnl, 0x000001CF, VdSendClosedCaptionData, kFunction), +XE_EXPORT(xboxkrnl, 0x000001D0, VdSetCGMSOption, kFunction), +XE_EXPORT(xboxkrnl, 0x000001D1, VdSetColorProfileAdjustment, kFunction), +XE_EXPORT(xboxkrnl, 0x000001D2, VdSetCscMatricesOverride, kFunction), +XE_EXPORT(xboxkrnl, 0x000001D3, VdSetDisplayMode, kFunction), +XE_EXPORT(xboxkrnl, 0x000001D4, VdSetDisplayModeOverride, kFunction), +XE_EXPORT(xboxkrnl, 0x000001D5, VdSetGraphicsInterruptCallback, kFunction), +XE_EXPORT(xboxkrnl, 0x000001D6, VdSetHDCPOption, kFunction), +XE_EXPORT(xboxkrnl, 0x000001D7, VdSetMacrovisionOption, kFunction), +XE_EXPORT(xboxkrnl, 0x000001D8, VdSetSystemCommandBuffer, kFunction), +XE_EXPORT(xboxkrnl, 0x000001D9, VdSetSystemCommandBufferGpuIdentifierAddress, kFunction), +XE_EXPORT(xboxkrnl, 0x000001DA, VdSetWSSData, kFunction), +XE_EXPORT(xboxkrnl, 0x000001DB, VdSetWSSOption, kFunction), +XE_EXPORT(xboxkrnl, 0x000001DC, VdShutdownEngines, kFunction), +XE_EXPORT(xboxkrnl, 0x000001DD, VdTurnDisplayOff, kFunction), +XE_EXPORT(xboxkrnl, 0x000001DE, VdTurnDisplayOn, kFunction), +XE_EXPORT(xboxkrnl, 0x000001DF, KiApcNormalRoutineNop, kFunction), +XE_EXPORT(xboxkrnl, 0x000001E0, VdWriteDVERegisterUlong, kFunction), +XE_EXPORT(xboxkrnl, 0x000001E1, XVoicedHeadsetPresent, kFunction), +XE_EXPORT(xboxkrnl, 0x000001E2, XVoicedSubmitPacket, kFunction), +XE_EXPORT(xboxkrnl, 0x000001E3, XVoicedClose, kFunction), +XE_EXPORT(xboxkrnl, 0x000001E4, XVoicedActivate, kFunction), +XE_EXPORT(xboxkrnl, 0x000001E5, XInputdGetCapabilities, kFunction), +XE_EXPORT(xboxkrnl, 0x000001E6, XInputdReadState, kFunction), +XE_EXPORT(xboxkrnl, 0x000001E7, XInputdWriteState, kFunction), +XE_EXPORT(xboxkrnl, 0x000001E8, XInputdNotify, kFunction), +XE_EXPORT(xboxkrnl, 0x000001E9, XInputdRawState, kFunction), +XE_EXPORT(xboxkrnl, 0x000001EA, HidGetCapabilities, kFunction), +XE_EXPORT(xboxkrnl, 0x000001EB, HidReadKeys, kFunction), +XE_EXPORT(xboxkrnl, 0x000001EC, XInputdGetDeviceStats, kFunction), +XE_EXPORT(xboxkrnl, 0x000001ED, XInputdResetDevice, kFunction), +XE_EXPORT(xboxkrnl, 0x000001EE, XInputdSetRingOfLight, kFunction), +XE_EXPORT(xboxkrnl, 0x000001EF, XInputdSetRFPowerMode, kFunction), +XE_EXPORT(xboxkrnl, 0x000001F0, XInputdSetRadioFrequency, kFunction), +XE_EXPORT(xboxkrnl, 0x000001F1, HidGetLastInputTime, kFunction), +XE_EXPORT(xboxkrnl, 0x000001F2, XAudioRenderDriverInitialize, kFunction), +XE_EXPORT(xboxkrnl, 0x000001F3, XAudioRegisterRenderDriverClient, kFunction), +XE_EXPORT(xboxkrnl, 0x000001F4, XAudioUnregisterRenderDriverClient, kFunction), +XE_EXPORT(xboxkrnl, 0x000001F5, XAudioSubmitRenderDriverFrame, kFunction), +XE_EXPORT(xboxkrnl, 0x000001F6, XAudioRenderDriverLock, kFunction), +XE_EXPORT(xboxkrnl, 0x000001F7, XAudioGetVoiceCategoryVolumeChangeMask, kFunction), +XE_EXPORT(xboxkrnl, 0x000001F8, XAudioGetVoiceCategoryVolume, kFunction), +XE_EXPORT(xboxkrnl, 0x000001F9, XAudioSetVoiceCategoryVolume, kFunction), +XE_EXPORT(xboxkrnl, 0x000001FA, XAudioBeginDigitalBypassMode, kFunction), +XE_EXPORT(xboxkrnl, 0x000001FB, XAudioEndDigitalBypassMode, kFunction), +XE_EXPORT(xboxkrnl, 0x000001FC, XAudioSubmitDigitalPacket, kFunction), +XE_EXPORT(xboxkrnl, 0x000001FD, XAudioQueryDriverPerformance, kFunction), +XE_EXPORT(xboxkrnl, 0x000001FE, XAudioGetRenderDriverThread, kFunction), +XE_EXPORT(xboxkrnl, 0x000001FF, XAudioGetSpeakerConfig, kFunction), +XE_EXPORT(xboxkrnl, 0x00000200, XAudioSetSpeakerConfig, kFunction), +XE_EXPORT(xboxkrnl, 0x00000201, NicSetUnicastAddress, kFunction), +XE_EXPORT(xboxkrnl, 0x00000202, NicAttach, kFunction), +XE_EXPORT(xboxkrnl, 0x00000203, NicDetach, kFunction), +XE_EXPORT(xboxkrnl, 0x00000204, NicXmit, kFunction), +XE_EXPORT(xboxkrnl, 0x00000205, NicUpdateMcastMembership, kFunction), +XE_EXPORT(xboxkrnl, 0x00000206, NicFlushXmitQueue, kFunction), +XE_EXPORT(xboxkrnl, 0x00000207, NicShutdown, kFunction), +XE_EXPORT(xboxkrnl, 0x00000208, NicGetLinkState, kFunction), +XE_EXPORT(xboxkrnl, 0x00000209, NicGetStats, kFunction), +XE_EXPORT(xboxkrnl, 0x0000020A, NicGetOpt, kFunction), +XE_EXPORT(xboxkrnl, 0x0000020B, NicSetOpt, kFunction), +XE_EXPORT(xboxkrnl, 0x0000020C, DrvSetSysReqCallback, kFunction), +XE_EXPORT(xboxkrnl, 0x0000020D, DrvSetUserBindingCallback, kFunction), +XE_EXPORT(xboxkrnl, 0x0000020E, DrvSetContentStorageCallback, kFunction), +XE_EXPORT(xboxkrnl, 0x0000020F, DrvSetAutobind, kFunction), +XE_EXPORT(xboxkrnl, 0x00000210, DrvGetContentStorageNotification, kFunction), +XE_EXPORT(xboxkrnl, 0x00000211, MtpdBeginTransaction, kFunction), +XE_EXPORT(xboxkrnl, 0x00000212, MtpdCancelTransaction, kFunction), +XE_EXPORT(xboxkrnl, 0x00000213, MtpdEndTransaction, kFunction), +XE_EXPORT(xboxkrnl, 0x00000214, MtpdGetCurrentDevices, kFunction), +XE_EXPORT(xboxkrnl, 0x00000215, MtpdReadData, kFunction), +XE_EXPORT(xboxkrnl, 0x00000216, MtpdReadEvent, kFunction), +XE_EXPORT(xboxkrnl, 0x00000217, MtpdResetDevice, kFunction), +XE_EXPORT(xboxkrnl, 0x00000218, MtpdSendData, kFunction), +XE_EXPORT(xboxkrnl, 0x00000219, MtpdVerifyProximity, kFunction), +XE_EXPORT(xboxkrnl, 0x0000021A, XUsbcamSetCaptureMode, kFunction), +XE_EXPORT(xboxkrnl, 0x0000021B, XUsbcamGetConfig, kFunction), +XE_EXPORT(xboxkrnl, 0x0000021C, XUsbcamSetConfig, kFunction), +XE_EXPORT(xboxkrnl, 0x0000021D, XUsbcamGetState, kFunction), +XE_EXPORT(xboxkrnl, 0x0000021E, XUsbcamReadFrame, kFunction), +XE_EXPORT(xboxkrnl, 0x0000021F, XUsbcamSnapshot, kFunction), +XE_EXPORT(xboxkrnl, 0x00000220, XUsbcamSetView, kFunction), +XE_EXPORT(xboxkrnl, 0x00000221, XUsbcamGetView, kFunction), +XE_EXPORT(xboxkrnl, 0x00000222, XUsbcamCreate, kFunction), +XE_EXPORT(xboxkrnl, 0x00000223, XUsbcamDestroy, kFunction), +XE_EXPORT(xboxkrnl, 0x00000224, XMACreateContext, kFunction), +XE_EXPORT(xboxkrnl, 0x00000225, XMAInitializeContext, kFunction), +XE_EXPORT(xboxkrnl, 0x00000226, XMAReleaseContext, kFunction), +XE_EXPORT(xboxkrnl, 0x00000227, XMAEnableContext, kFunction), +XE_EXPORT(xboxkrnl, 0x00000228, XMADisableContext, kFunction), +XE_EXPORT(xboxkrnl, 0x00000229, XMAGetOutputBufferWriteOffset, kFunction), +XE_EXPORT(xboxkrnl, 0x0000022A, XMASetOutputBufferReadOffset, kFunction), +XE_EXPORT(xboxkrnl, 0x0000022B, XMAGetOutputBufferReadOffset, kFunction), +XE_EXPORT(xboxkrnl, 0x0000022C, XMASetOutputBufferValid, kFunction), +XE_EXPORT(xboxkrnl, 0x0000022D, XMAIsOutputBufferValid, kFunction), +XE_EXPORT(xboxkrnl, 0x0000022E, XMASetInputBuffer0Valid, kFunction), +XE_EXPORT(xboxkrnl, 0x0000022F, XMAIsInputBuffer0Valid, kFunction), +XE_EXPORT(xboxkrnl, 0x00000230, XMASetInputBuffer1Valid, kFunction), +XE_EXPORT(xboxkrnl, 0x00000231, XMAIsInputBuffer1Valid, kFunction), +XE_EXPORT(xboxkrnl, 0x00000232, XMASetInputBuffer0, kFunction), +XE_EXPORT(xboxkrnl, 0x00000233, XMASetInputBuffer1, kFunction), +XE_EXPORT(xboxkrnl, 0x00000234, XMAGetPacketMetadata, kFunction), +XE_EXPORT(xboxkrnl, 0x00000235, XMABlockWhileInUse, kFunction), +XE_EXPORT(xboxkrnl, 0x00000236, XMASetLoopData, kFunction), +XE_EXPORT(xboxkrnl, 0x00000237, XMASetInputBufferReadOffset, kFunction), +XE_EXPORT(xboxkrnl, 0x00000238, XMAGetInputBufferReadOffset, kFunction), +XE_EXPORT(xboxkrnl, 0x00000239, ExIsBetaFeatureEnabled, kFunction), +XE_EXPORT(xboxkrnl, 0x0000023A, XeKeysGetFactoryChallenge, kFunction), +XE_EXPORT(xboxkrnl, 0x0000023B, XeKeysSetFactoryResponse, kFunction), +XE_EXPORT(xboxkrnl, 0x0000023C, XeKeysInitializeFuses, kFunction), +XE_EXPORT(xboxkrnl, 0x0000023D, XeKeysSaveBootLoader, kFunction), +XE_EXPORT(xboxkrnl, 0x0000023E, XeKeysSaveKeyVault, kFunction), +XE_EXPORT(xboxkrnl, 0x0000023F, XeKeysGetStatus, kFunction), +XE_EXPORT(xboxkrnl, 0x00000240, XeKeysGeneratePrivateKey, kFunction), +XE_EXPORT(xboxkrnl, 0x00000241, XeKeysGetKeyProperties, kFunction), +XE_EXPORT(xboxkrnl, 0x00000242, XeKeysSetKey, kFunction), +XE_EXPORT(xboxkrnl, 0x00000243, XeKeysGenerateRandomKey, kFunction), +XE_EXPORT(xboxkrnl, 0x00000244, XeKeysGetKey, kFunction), +XE_EXPORT(xboxkrnl, 0x00000245, XeKeysGetDigest, kFunction), +XE_EXPORT(xboxkrnl, 0x00000246, XeKeysGetConsoleID, kFunction), +XE_EXPORT(xboxkrnl, 0x00000247, XeKeysGetConsoleType, kFunction), +XE_EXPORT(xboxkrnl, 0x00000248, XeKeysQwNeRsaPrvCrypt, kFunction), +XE_EXPORT(xboxkrnl, 0x00000249, XeKeysHmacSha, kFunction), +XE_EXPORT(xboxkrnl, 0x0000024A, XInputdPassThroughRFCommand, kFunction), +XE_EXPORT(xboxkrnl, 0x0000024B, XeKeysAesCbc, kFunction), +XE_EXPORT(xboxkrnl, 0x0000024C, XeKeysDes2Cbc, kFunction), +XE_EXPORT(xboxkrnl, 0x0000024D, XeKeysDesCbc, kFunction), +XE_EXPORT(xboxkrnl, 0x0000024E, XeKeysObscureKey, kFunction), +XE_EXPORT(xboxkrnl, 0x0000024F, XeKeysHmacShaUsingKey, kFunction), +XE_EXPORT(xboxkrnl, 0x00000250, XeKeysSaveBootLoaderEx, kFunction), +XE_EXPORT(xboxkrnl, 0x00000251, XeKeysAesCbcUsingKey, kFunction), +XE_EXPORT(xboxkrnl, 0x00000252, XeKeysDes2CbcUsingKey, kFunction), +XE_EXPORT(xboxkrnl, 0x00000253, XeKeysDesCbcUsingKey, kFunction), +XE_EXPORT(xboxkrnl, 0x00000254, XeKeysObfuscate, kFunction), +XE_EXPORT(xboxkrnl, 0x00000255, XeKeysUnObfuscate, kFunction), +XE_EXPORT(xboxkrnl, 0x00000256, XeKeysConsolePrivateKeySign, kFunction), +XE_EXPORT(xboxkrnl, 0x00000257, XeKeysConsoleSignatureVerification, kFunction), +XE_EXPORT(xboxkrnl, 0x00000258, XeKeysVerifyRSASignature, kFunction), +XE_EXPORT(xboxkrnl, 0x00000259, StfsCreateDevice, kFunction), +XE_EXPORT(xboxkrnl, 0x0000025A, StfsControlDevice, kFunction), +XE_EXPORT(xboxkrnl, 0x0000025B, VdSwap, kFunction), +XE_EXPORT(xboxkrnl, 0x0000025C, HalFsbInterruptCount, kVariable), +XE_EXPORT(xboxkrnl, 0x0000025D, XeKeysSaveSystemUpdate, kFunction), +XE_EXPORT(xboxkrnl, 0x0000025E, XeKeysLockSystemUpdate, kFunction), +XE_EXPORT(xboxkrnl, 0x0000025F, XeKeysExecute, kFunction), +XE_EXPORT(xboxkrnl, 0x00000260, XeKeysGetVersions, kFunction), +XE_EXPORT(xboxkrnl, 0x00000261, XInputdPowerDownDevice, kFunction), +XE_EXPORT(xboxkrnl, 0x00000262, AniBlockOnAnimation, kFunction), +XE_EXPORT(xboxkrnl, 0x00000263, AniTerminateAnimation, kFunction), +XE_EXPORT(xboxkrnl, 0x00000264, XUsbcamReset, kFunction), +XE_EXPORT(xboxkrnl, 0x00000265, AniSetLogo, kFunction), +XE_EXPORT(xboxkrnl, 0x00000266, KeCertMonitorData, kVariable), +XE_EXPORT(xboxkrnl, 0x00000267, HalIsExecutingPowerDownDpc, kFunction), +XE_EXPORT(xboxkrnl, 0x00000268, VdInitializeEDRAM, kFunction), +XE_EXPORT(xboxkrnl, 0x00000269, VdRetrainEDRAM, kFunction), +XE_EXPORT(xboxkrnl, 0x0000026A, VdRetrainEDRAMWorker, kFunction), +XE_EXPORT(xboxkrnl, 0x0000026B, VdHSIOTrainCount, kVariable), +XE_EXPORT(xboxkrnl, 0x0000026C, HalGetPowerUpCause, kFunction), +XE_EXPORT(xboxkrnl, 0x0000026D, VdHSIOTrainingStatus, kVariable), +XE_EXPORT(xboxkrnl, 0x0000026E, RgcBindInfo, kVariable), +XE_EXPORT(xboxkrnl, 0x0000026F, VdReadEEDIDBlock, kFunction), +XE_EXPORT(xboxkrnl, 0x00000270, VdEnumerateVideoModes, kFunction), +XE_EXPORT(xboxkrnl, 0x00000271, VdEnableHDCP, kFunction), +XE_EXPORT(xboxkrnl, 0x00000272, VdRegisterHDCPNotification, kFunction), +XE_EXPORT(xboxkrnl, 0x00000273, HidReadMouseChanges, kFunction), +XE_EXPORT(xboxkrnl, 0x00000274, DumpSetCollectionFacility, kFunction), +XE_EXPORT(xboxkrnl, 0x00000275, XexTransformImageKey, kFunction), +XE_EXPORT(xboxkrnl, 0x00000276, XAudioOverrideSpeakerConfig, kFunction), +XE_EXPORT(xboxkrnl, 0x00000277, XInputdReadTextKeystroke, kFunction), +XE_EXPORT(xboxkrnl, 0x00000278, DrvXenonButtonPressed, kFunction), +XE_EXPORT(xboxkrnl, 0x00000279, DrvBindToUser, kFunction), +XE_EXPORT(xboxkrnl, 0x0000027A, XexGetModuleImportVersions, kFunction), +XE_EXPORT(xboxkrnl, 0x0000027B, RtlComputeCrc32, kFunction), +XE_EXPORT(xboxkrnl, 0x0000027C, XeKeysSetRevocationList, kFunction), +XE_EXPORT(xboxkrnl, 0x0000027D, HalRegisterPowerDownCallback, kFunction), +XE_EXPORT(xboxkrnl, 0x0000027E, VdGetDisplayDiscoveryData, kFunction), +XE_EXPORT(xboxkrnl, 0x0000027F, XInputdSendStayAliveRequest, kFunction), +XE_EXPORT(xboxkrnl, 0x00000280, XVoicedSendVPort, kFunction), +XE_EXPORT(xboxkrnl, 0x00000281, XVoicedGetBatteryStatus, kFunction), +XE_EXPORT(xboxkrnl, 0x00000282, XInputdFFGetDeviceInfo, kFunction), +XE_EXPORT(xboxkrnl, 0x00000283, XInputdFFSetEffect, kFunction), +XE_EXPORT(xboxkrnl, 0x00000284, XInputdFFUpdateEffect, kFunction), +XE_EXPORT(xboxkrnl, 0x00000285, XInputdFFEffectOperation, kFunction), +XE_EXPORT(xboxkrnl, 0x00000286, XInputdFFDeviceControl, kFunction), +XE_EXPORT(xboxkrnl, 0x00000287, XInputdFFSetDeviceGain, kFunction), +XE_EXPORT(xboxkrnl, 0x00000288, XInputdFFCancelIo, kFunction), +XE_EXPORT(xboxkrnl, 0x00000289, XInputdFFSetRumble, kFunction), +XE_EXPORT(xboxkrnl, 0x0000028A, NtAllocateEncryptedMemory, kFunction), +XE_EXPORT(xboxkrnl, 0x0000028B, NtFreeEncryptedMemory, kFunction), +XE_EXPORT(xboxkrnl, 0x0000028C, XeKeysExSaveKeyVault, kFunction), +XE_EXPORT(xboxkrnl, 0x0000028D, XeKeysExSetKey, kFunction), +XE_EXPORT(xboxkrnl, 0x0000028E, XeKeysExGetKey, kFunction), +XE_EXPORT(xboxkrnl, 0x0000028F, DrvSetDeviceConfigChangeCallback, kFunction), +XE_EXPORT(xboxkrnl, 0x00000290, DrvDeviceConfigChange, kFunction), +XE_EXPORT(xboxkrnl, 0x00000291, HalRegisterHdDvdRomNotification, kFunction), +XE_EXPORT(xboxkrnl, 0x00000292, XeKeysSecurityInitialize, kFunction), +XE_EXPORT(xboxkrnl, 0x00000293, XeKeysSecurityLoadSettings, kFunction), +XE_EXPORT(xboxkrnl, 0x00000294, XeKeysSecuritySaveSettings, kFunction), +XE_EXPORT(xboxkrnl, 0x00000295, XeKeysSecuritySetDetected, kFunction), +XE_EXPORT(xboxkrnl, 0x00000296, XeKeysSecurityGetDetected, kFunction), +XE_EXPORT(xboxkrnl, 0x00000297, XeKeysSecuritySetActivated, kFunction), +XE_EXPORT(xboxkrnl, 0x00000298, XeKeysSecurityGetActivated, kFunction), +XE_EXPORT(xboxkrnl, 0x00000299, XeKeysDvdAuthAP25InstallTable, kFunction), +XE_EXPORT(xboxkrnl, 0x0000029A, XeKeysDvdAuthAP25GetTableVersion, kFunction), +XE_EXPORT(xboxkrnl, 0x0000029B, XeKeysGetProtectedFlag, kFunction), +XE_EXPORT(xboxkrnl, 0x0000029C, XeKeysSetProtectedFlag, kFunction), +XE_EXPORT(xboxkrnl, 0x0000029D, KeEnablePFMInterrupt, kFunction), +XE_EXPORT(xboxkrnl, 0x0000029E, KeDisablePFMInterrupt, kFunction), +XE_EXPORT(xboxkrnl, 0x0000029F, KeSetProfilerISR, kFunction), +XE_EXPORT(xboxkrnl, 0x000002A0, VdStartDisplayDiscovery, kFunction), +XE_EXPORT(xboxkrnl, 0x000002A1, VdSetHDCPRevocationList, kFunction), +XE_EXPORT(xboxkrnl, 0x000002A2, XeKeysGetUpdateSequence, kFunction), +XE_EXPORT(xboxkrnl, 0x000002A3, XeKeysDvdAuthExActivate, kFunction), +XE_EXPORT(xboxkrnl, 0x000002A4, KeGetImagePageTableEntry, kFunction), +XE_EXPORT(xboxkrnl, 0x000002A5, HalRegisterBackgroundModeTransitionCallback, kFunction), +XE_EXPORT(xboxkrnl, 0x000002A6, AniStartBootAnimation, kFunction), +XE_EXPORT(xboxkrnl, 0x000002A7, HalClampUnclampOutputDACs, kFunction), +XE_EXPORT(xboxkrnl, 0x000002A8, HalPowerDownToBackgroundMode, kFunction), +XE_EXPORT(xboxkrnl, 0x000002A9, HalNotifyAddRemoveBackgroundTask, kFunction), +XE_EXPORT(xboxkrnl, 0x000002AA, HalCallBackgroundModeNotificationRoutines, kFunction), +XE_EXPORT(xboxkrnl, 0x000002AB, HalFsbResetCount, kVariable), +XE_EXPORT(xboxkrnl, 0x000002AC, HalGetMemoryInformation, kFunction), +XE_EXPORT(xboxkrnl, 0x000002AD, XInputdGetLastTextInputTime, kFunction), +XE_EXPORT(xboxkrnl, 0x000002AE, VdEnableWMAProOverHDMI, kFunction), +XE_EXPORT(xboxkrnl, 0x000002AF, XeKeysRevokeSaveSettings, kFunction), +XE_EXPORT(xboxkrnl, 0x000002B0, XInputdSetTextMessengerIndicator, kFunction), +XE_EXPORT(xboxkrnl, 0x000002B1, MicDeviceRequest, kFunction), +XE_EXPORT(xboxkrnl, 0x000002B2, XeKeysGetMediaID, kFunction), +XE_EXPORT(xboxkrnl, 0x000002B3, XeKeysLoadKeyVault, kFunction), +XE_EXPORT(xboxkrnl, 0x000002B4, KeGetVidInfo, kFunction), +XE_EXPORT(xboxkrnl, 0x000002B5, HalNotifyBackgroundModeTransitionComplete, kFunction), +XE_EXPORT(xboxkrnl, 0x000002B6, IoAcquireCancelSpinLock, kFunction), +XE_EXPORT(xboxkrnl, 0x000002B7, IoReleaseCancelSpinLock, kFunction), +XE_EXPORT(xboxkrnl, 0x000002B8, NtCancelIoFile, kFunction), +XE_EXPORT(xboxkrnl, 0x000002B9, NtCancelIoFileEx, kFunction), +XE_EXPORT(xboxkrnl, 0x000002BA, HalFinalizePowerLossRecovery, kFunction), +XE_EXPORT(xboxkrnl, 0x000002BB, HalSetPowerLossRecovery, kFunction), +XE_EXPORT(xboxkrnl, 0x000002BC, ExReadModifyWriteXConfigSettingUlong, kFunction), +XE_EXPORT(xboxkrnl, 0x000002BD, HalRegisterXamPowerDownCallback, kFunction), +XE_EXPORT(xboxkrnl, 0x000002BE, ExCancelAlarm, kFunction), +XE_EXPORT(xboxkrnl, 0x000002BF, ExInitializeAlarm, kFunction), +XE_EXPORT(xboxkrnl, 0x000002C0, ExSetAlarm, kFunction), +XE_EXPORT(xboxkrnl, 0x000002C1, XexActivationGetNonce, kFunction), +XE_EXPORT(xboxkrnl, 0x000002C2, XexActivationSetLicense, kFunction), +XE_EXPORT(xboxkrnl, 0x000002C3, IptvSetBoundaryKey, kFunction), +XE_EXPORT(xboxkrnl, 0x000002C4, IptvSetSessionKey, kFunction), +XE_EXPORT(xboxkrnl, 0x000002C5, IptvVerifyOmac1Signature, kFunction), +XE_EXPORT(xboxkrnl, 0x000002C6, IptvGetAesCtrTransform, kFunction), +XE_EXPORT(xboxkrnl, 0x000002C7, SataCdRomRecordReset, kFunction), +XE_EXPORT(xboxkrnl, 0x000002C8, XInputdSetTextDeviceKeyLocks, kFunction), +XE_EXPORT(xboxkrnl, 0x000002C9, XInputdGetTextDeviceKeyLocks, kFunction), +XE_EXPORT(xboxkrnl, 0x000002CA, XexActivationVerifyOwnership, kFunction), +XE_EXPORT(xboxkrnl, 0x000002CB, XexDisableVerboseDbgPrint, kFunction), +XE_EXPORT(xboxkrnl, 0x000002CC, SvodCreateDevice, kFunction), +XE_EXPORT(xboxkrnl, 0x000002CD, RtlCaptureStackBackTrace, kFunction), +XE_EXPORT(xboxkrnl, 0x000002CE, XeKeysRevokeUpdateDynamic, kFunction), +XE_EXPORT(xboxkrnl, 0x000002CF, XexImportTraceEnable, kFunction), +XE_EXPORT(xboxkrnl, 0x000002D0, ExRegisterXConfigNotification, kFunction), +XE_EXPORT(xboxkrnl, 0x000002D1, XeKeysSecuritySetStat, kFunction), +XE_EXPORT(xboxkrnl, 0x000002D2, VdQueryRealVideoMode, kFunction), +XE_EXPORT(xboxkrnl, 0x000002D3, XexSetExecutablePrivilege, kFunction), +XE_EXPORT(xboxkrnl, 0x000002D4, XAudioSuspendRenderDriverClients, kFunction), +XE_EXPORT(xboxkrnl, 0x000002D5, IptvGetSessionKeyHash, kFunction), +XE_EXPORT(xboxkrnl, 0x000002D6, VdSetCGMSState, kFunction), +XE_EXPORT(xboxkrnl, 0x000002D7, VdSetSCMSState, kFunction), +XE_EXPORT(xboxkrnl, 0x000002D8, KeFlushMultipleTb, kFunction), +XE_EXPORT(xboxkrnl, 0x000002D9, VdGetOption, kFunction), +XE_EXPORT(xboxkrnl, 0x000002DA, VdSetOption, kFunction), +XE_EXPORT(xboxkrnl, 0x000002DB, UsbdBootEnumerationDoneEvent, kVariable), +XE_EXPORT(xboxkrnl, 0x000002DC, StfsDeviceErrorEvent, kVariable), +XE_EXPORT(xboxkrnl, 0x000002DD, ExTryToAcquireReadWriteLockExclusive, kFunction), +XE_EXPORT(xboxkrnl, 0x000002DE, ExTryToAcquireReadWriteLockShared, kFunction), +XE_EXPORT(xboxkrnl, 0x000002DF, XexSetLastKdcTime, kFunction), +XE_EXPORT(xboxkrnl, 0x000002E0, XInputdControl, kFunction), +XE_EXPORT(xboxkrnl, 0x000002E1, RmcDeviceRequest, kFunction), +XE_EXPORT(xboxkrnl, 0x000002E2, LDIResetDecompression, kFunction), +XE_EXPORT(xboxkrnl, 0x000002E3, NicRegisterDevice, kFunction), +XE_EXPORT(xboxkrnl, 0x000002E4, UsbdAddDeviceComplete, kFunction), +XE_EXPORT(xboxkrnl, 0x000002E5, UsbdCancelAsyncTransfer, kFunction), +XE_EXPORT(xboxkrnl, 0x000002E6, UsbdGetDeviceSpeed, kFunction), +XE_EXPORT(xboxkrnl, 0x000002E7, UsbdGetDeviceTopology, kFunction), +XE_EXPORT(xboxkrnl, 0x000002E8, UsbdGetEndpointDescriptor, kFunction), +XE_EXPORT(xboxkrnl, 0x000002E9, UsbdIsDeviceAuthenticated, kFunction), +XE_EXPORT(xboxkrnl, 0x000002EA, UsbdOpenDefaultEndpoint, kFunction), +XE_EXPORT(xboxkrnl, 0x000002EB, UsbdOpenEndpoint, kFunction), +XE_EXPORT(xboxkrnl, 0x000002EC, UsbdQueueAsyncTransfer, kFunction), +XE_EXPORT(xboxkrnl, 0x000002ED, UsbdQueueCloseDefaultEndpoint, kFunction), +XE_EXPORT(xboxkrnl, 0x000002EE, UsbdQueueCloseEndpoint, kFunction), +XE_EXPORT(xboxkrnl, 0x000002EF, UsbdRemoveDeviceComplete, kFunction), +XE_EXPORT(xboxkrnl, 0x000002F0, KeRemoveQueueApc, kFunction), +XE_EXPORT(xboxkrnl, 0x000002F1, UsbdDriverLoadRequiredEvent, kVariable), +XE_EXPORT(xboxkrnl, 0x000002F2, UsbdGetRequiredDrivers, kFunction), +XE_EXPORT(xboxkrnl, 0x000002F3, UsbdRegisterDriverObject, kFunction), +XE_EXPORT(xboxkrnl, 0x000002F4, UsbdUnregisterDriverObject, kFunction), +XE_EXPORT(xboxkrnl, 0x000002F5, UsbdCallAndBlockOnDpcRoutine, kFunction), +XE_EXPORT(xboxkrnl, 0x000002F6, UsbdResetDevice, kFunction), +XE_EXPORT(xboxkrnl, 0x000002F7, UsbdGetDeviceDescriptor, kFunction), +XE_EXPORT(xboxkrnl, 0x000002F8, NomnilGetExtension, kFunction), +XE_EXPORT(xboxkrnl, 0x000002F9, NomnilStartCloseDevice, kFunction), +XE_EXPORT(xboxkrnl, 0x000002FA, WifiBeginAuthentication, kFunction), +XE_EXPORT(xboxkrnl, 0x000002FB, WifiCheckCounterMeasures, kFunction), +XE_EXPORT(xboxkrnl, 0x000002FC, WifiChooseAuthenCipherSetFromBSSID, kFunction), +XE_EXPORT(xboxkrnl, 0x000002FD, WifiCompleteAuthentication, kFunction), +XE_EXPORT(xboxkrnl, 0x000002FE, WifiGetAssociationIE, kFunction), +XE_EXPORT(xboxkrnl, 0x000002FF, WifiOnMICError, kFunction), +XE_EXPORT(xboxkrnl, 0x00000300, WifiPrepareAuthenticationContext, kFunction), +XE_EXPORT(xboxkrnl, 0x00000301, WifiRecvEAPOLPacket, kFunction), +XE_EXPORT(xboxkrnl, 0x00000302, WifiDeduceNetworkType, kFunction), +XE_EXPORT(xboxkrnl, 0x00000303, NicUnregisterDevice, kFunction), +XE_EXPORT(xboxkrnl, 0x00000304, DumpXitThread, kFunction), +XE_EXPORT(xboxkrnl, 0x00000305, XInputdSetWifiChannel, kFunction), +XE_EXPORT(xboxkrnl, 0x00000306, NomnilSetLed, kFunction), +XE_EXPORT(xboxkrnl, 0x00000307, WifiCalculateRegulatoryDomain, kFunction), +XE_EXPORT(xboxkrnl, 0x00000308, WifiSelectAdHocChannel, kFunction), +XE_EXPORT(xboxkrnl, 0x00000309, WifiChannelToFrequency, kFunction), +XE_EXPORT(xboxkrnl, 0x0000030A, MmGetPoolPagesType, kFunction), +XE_EXPORT(xboxkrnl, 0x0000030B, ExExpansionInstall, kFunction), +XE_EXPORT(xboxkrnl, 0x0000030C, ExExpansionCall, kFunction), +XE_EXPORT(xboxkrnl, 0x0000030D, PsCamDeviceRequest, kFunction), +XE_EXPORT(xboxkrnl, 0x0000030E, McaDeviceRequest, kFunction), +XE_EXPORT(xboxkrnl, 0x0000030F, DetroitDeviceRequest, kFunction), +XE_EXPORT(xboxkrnl, 0x00000310, XeCryptSha256Init, kFunction), +XE_EXPORT(xboxkrnl, 0x00000311, XeCryptSha256Update, kFunction), +XE_EXPORT(xboxkrnl, 0x00000312, XeCryptSha256Final, kFunction), +XE_EXPORT(xboxkrnl, 0x00000313, XeCryptSha256, kFunction), +XE_EXPORT(xboxkrnl, 0x00000314, XeCryptSha384Init, kFunction), +XE_EXPORT(xboxkrnl, 0x00000315, XeCryptSha384Update, kFunction), +XE_EXPORT(xboxkrnl, 0x00000316, XInputdGetDevicePid, kFunction), +XE_EXPORT(xboxkrnl, 0x00000317, HalGetNotedArgonErrors, kFunction), +XE_EXPORT(xboxkrnl, 0x00000318, XeCryptSha384Final, kFunction), +XE_EXPORT(xboxkrnl, 0x00000319, HalReadArgonEeprom, kFunction), +XE_EXPORT(xboxkrnl, 0x0000031A, HalWriteArgonEeprom, kFunction), +XE_EXPORT(xboxkrnl, 0x0000031B, XeKeysFcrtLoad, kFunction), +XE_EXPORT(xboxkrnl, 0x0000031C, XeKeysFcrtSave, kFunction), +XE_EXPORT(xboxkrnl, 0x0000031D, XeKeysFcrtSet, kFunction), +XE_EXPORT(xboxkrnl, 0x0000031E, XeCryptSha384, kFunction), +XE_EXPORT(xboxkrnl, 0x0000031F, XeCryptSha512Init, kFunction), +XE_EXPORT(xboxkrnl, 0x00000320, XAudioRegisterRenderDriverMECClient, kFunction), +XE_EXPORT(xboxkrnl, 0x00000321, XAudioUnregisterRenderDriverMECClient, kFunction), +XE_EXPORT(xboxkrnl, 0x00000322, XAudioCaptureRenderDriverFrame, kFunction), +XE_EXPORT(xboxkrnl, 0x00000323, XeCryptSha512Update, kFunction), +XE_EXPORT(xboxkrnl, 0x00000324, XeCryptSha512Final, kFunction), +XE_EXPORT(xboxkrnl, 0x00000325, XeCryptSha512, kFunction), +XE_EXPORT(xboxkrnl, 0x00000326, XeCryptBnQwNeCompare, kFunction), +XE_EXPORT(xboxkrnl, 0x00000327, XVoicedGetDirectionalData, kFunction), +XE_EXPORT(xboxkrnl, 0x00000328, DrvSetMicArrayStartCallback, kFunction), +XE_EXPORT(xboxkrnl, 0x00000329, DevAuthGetStatistics, kFunction), +XE_EXPORT(xboxkrnl, 0x0000032A, NullCableRequest, kFunction), +XE_EXPORT(xboxkrnl, 0x0000032B, XeKeysRevokeIsDeviceRevoked, kFunction), +XE_EXPORT(xboxkrnl, 0x0000032C, DumpUpdateDumpSettings, kFunction), +XE_EXPORT(xboxkrnl, 0x0000032D, EtxConsumerDisableEventType, kFunction), +XE_EXPORT(xboxkrnl, 0x0000032E, EtxConsumerEnableEventType, kFunction), +XE_EXPORT(xboxkrnl, 0x0000032F, EtxConsumerProcessLogs, kFunction), +XE_EXPORT(xboxkrnl, 0x00000330, EtxConsumerRegister, kFunction), +XE_EXPORT(xboxkrnl, 0x00000331, EtxConsumerUnregister, kFunction), +XE_EXPORT(xboxkrnl, 0x00000332, EtxProducerLog, kFunction), +XE_EXPORT(xboxkrnl, 0x00000333, EtxProducerLogV, kFunction), +XE_EXPORT(xboxkrnl, 0x00000334, EtxProducerRegister, kFunction), +XE_EXPORT(xboxkrnl, 0x00000335, EtxProducerUnregister, kFunction), +XE_EXPORT(xboxkrnl, 0x00000336, EtxConsumerFlushBuffers, kFunction), +XE_EXPORT(xboxkrnl, 0x00000337, EtxProducerLogXwpp, kFunction), +XE_EXPORT(xboxkrnl, 0x00000338, EtxProducerLogXwppV, kFunction), +XE_EXPORT(xboxkrnl, 0x00000339, UsbdEnableDisableRootHubPort, kFunction), +XE_EXPORT(xboxkrnl, 0x0000033A, EtxBufferRegister, kFunction), +XE_EXPORT(xboxkrnl, 0x0000033B, EtxBufferUnregister, kFunction), +XE_EXPORT(xboxkrnl, 0x0000033C, DumpRegisterDedicatedDataBlock, kFunction), +XE_EXPORT(xboxkrnl, 0x0000033D, XeKeysDvdAuthExSave, kFunction), +XE_EXPORT(xboxkrnl, 0x0000033E, XeKeysDvdAuthExInstall, kFunction), +XE_EXPORT(xboxkrnl, 0x0000033F, XexShimDisable, kFunction), +XE_EXPORT(xboxkrnl, 0x00000340, XexShimEnable, kFunction), +XE_EXPORT(xboxkrnl, 0x00000341, XexShimEntryDisable, kFunction), +XE_EXPORT(xboxkrnl, 0x00000342, XexShimEntryEnable, kFunction), +XE_EXPORT(xboxkrnl, 0x00000343, XexShimEntryRegister, kFunction), +XE_EXPORT(xboxkrnl, 0x00000344, XexShimLock, kFunction), +XE_EXPORT(xboxkrnl, 0x00000345, XboxKrnlVersion4Digit, kVariable), +XE_EXPORT(xboxkrnl, 0x00000346, XeKeysObfuscateEx, kFunction), +XE_EXPORT(xboxkrnl, 0x00000347, XeKeysUnObfuscateEx, kFunction), +XE_EXPORT(xboxkrnl, 0x00000348, XexTitleHash, kFunction), +XE_EXPORT(xboxkrnl, 0x00000349, XexTitleHashClose, kFunction), +XE_EXPORT(xboxkrnl, 0x0000034A, XexTitleHashContinue, kFunction), +XE_EXPORT(xboxkrnl, 0x0000034B, XexTitleHashOpen, kFunction), +XE_EXPORT(xboxkrnl, 0x0000034C, XAudioGetRenderDriverTic, kFunction), +XE_EXPORT(xboxkrnl, 0x0000034D, XAudioEnableDucker, kFunction), +XE_EXPORT(xboxkrnl, 0x0000034E, XAudioSetDuckerLevel, kFunction), +XE_EXPORT(xboxkrnl, 0x0000034F, XAudioIsDuckerEnabled, kFunction), +XE_EXPORT(xboxkrnl, 0x00000350, XAudioGetDuckerLevel, kFunction), +XE_EXPORT(xboxkrnl, 0x00000351, XAudioGetDuckerThreshold, kFunction), +XE_EXPORT(xboxkrnl, 0x00000352, XAudioSetDuckerThreshold, kFunction), +XE_EXPORT(xboxkrnl, 0x00000353, XAudioGetDuckerAttackTime, kFunction), +XE_EXPORT(xboxkrnl, 0x00000354, XAudioSetDuckerAttackTime, kFunction), +XE_EXPORT(xboxkrnl, 0x00000355, XAudioGetDuckerReleaseTime, kFunction), +XE_EXPORT(xboxkrnl, 0x00000356, XAudioSetDuckerReleaseTime, kFunction), +XE_EXPORT(xboxkrnl, 0x00000357, XAudioGetDuckerHoldTime, kFunction), +XE_EXPORT(xboxkrnl, 0x00000358, XAudioSetDuckerHoldTime, kFunction), +XE_EXPORT(xboxkrnl, 0x00000359, DevAuthShouldAlwaysEnforce, kFunction), +XE_EXPORT(xboxkrnl, 0x0000035A, XAudioGetUnderrunCount, kFunction), +XE_EXPORT(xboxkrnl, 0x0000035B, DrvSetAudioLatencyCallback, kFunction), +XE_EXPORT(xboxkrnl, 0x0000035C, XVoicedIsActiveProcess, kFunction), +XE_EXPORT(xboxkrnl, 0x0000035D, KeExecuteOnProtectedStack, kFunction), +XE_EXPORT(xboxkrnl, 0x0000035E, XeKeysVerifyPIRSSignature, kFunction), +XE_EXPORT(xboxkrnl, 0x0000035F, XeCryptAesCtr, kFunction), +XE_EXPORT(xboxkrnl, 0x00000360, XeCryptAesCbcMac, kFunction), +XE_EXPORT(xboxkrnl, 0x00000361, XeCryptAesDmMac, kFunction), +XE_EXPORT(xboxkrnl, 0x00000362, EmaExecute, kFunction), +XE_EXPORT(xboxkrnl, 0x00000363, XeKeysGetTruncatedSecondaryConsoleId, kFunction), +XE_EXPORT(xboxkrnl, 0x00000364, ExFreeDebugPool, kFunction), +XE_EXPORT(xboxkrnl, 0x00000365, VdQueryVideoCapabilities, kFunction), +XE_EXPORT(xboxkrnl, 0x00000366, UsbdGetDeviceRootPortType, kFunction), +XE_EXPORT(xboxkrnl, 0x00000367, VdGet3dVideoFormat, kFunction), +XE_EXPORT(xboxkrnl, 0x00000368, VdGetWSS2Data, kFunction), +XE_EXPORT(xboxkrnl, 0x00000369, VdSet3dVideoFormat, kFunction), +XE_EXPORT(xboxkrnl, 0x0000036A, VdSetWSS2Data, kFunction), +XE_EXPORT(xboxkrnl, 0x0000036B, XexReserveCodeBuffer, kFunction), +XE_EXPORT(xboxkrnl, 0x0000036C, XexCommitCodeBuffer, kFunction), +XE_EXPORT(xboxkrnl, 0x0000036D, RtlSetVectoredExceptionHandler, kFunction), +XE_EXPORT(xboxkrnl, 0x0000036E, RtlClearVectoredExceptionHandler, kFunction), +XE_EXPORT(xboxkrnl, 0x0000036F, XAudioSetProcessFrameCallback, kFunction), +XE_EXPORT(xboxkrnl, 0x00000370, UsbdGetRootHubDeviceNode, kFunction), +XE_EXPORT(xboxkrnl, 0x00000371, UsbdGetPortDeviceNode, kFunction), +XE_EXPORT(xboxkrnl, 0x00000372, UsbdGetNatalHub, kFunction), +XE_EXPORT(xboxkrnl, 0x00000373, UsbdGetNatalHardwareVersion, kFunction), +XE_EXPORT(xboxkrnl, 0x00000374, UsbdNatalHubRegisterNotificationCallback, kFunction), +XE_EXPORT(xboxkrnl, 0x00000375, KeCallAndBlockOnDpcRoutine, kFunction), +XE_EXPORT(xboxkrnl, 0x00000376, KeCallAndWaitForDpcRoutine, kFunction), +XE_EXPORT(xboxkrnl, 0x00000377, TidDeviceRequest, kFunction), +XE_EXPORT(xboxkrnl, 0x00000378, DmPrintData, kFunction), +XE_EXPORT(xboxkrnl, 0x00000379, VdSetStudioRGBMode, kFunction), +XE_EXPORT(xboxkrnl, 0x0000037A, UsbdTitleDriverResetAllUnrecognizedPorts, kFunction), +XE_EXPORT(xboxkrnl, 0x0000037B, UsbdTitleDriverSetUnrecognizedPort, kFunction), +XE_EXPORT(xboxkrnl, 0x0000037C, UsbdResetEndpoint, kFunction), +XE_EXPORT(xboxkrnl, 0x0000037D, UsbdSetTimer, kFunction), +XE_EXPORT(xboxkrnl, 0x0000037E, UsbdCancelTimer, kFunction), +XE_EXPORT(xboxkrnl, 0x0000037F, UsbdQueueIsochTransfer, kFunction), +XE_EXPORT(xboxkrnl, 0x00000380, KeSetPageRelocationCallback, kFunction), +XE_EXPORT(xboxkrnl, 0x00000381, XexRegisterUsermodeModule, kFunction), +XE_EXPORT(xboxkrnl, 0x00000383, TitleDeviceAuthRequest, kFunction), +XE_EXPORT(xboxkrnl, 0x00000384, KeRegisterSwapNotification, kFunction), +XE_EXPORT(xboxkrnl, 0x00000385, XInputdGetFailedConnectionOrBind, kFunction), +XE_EXPORT(xboxkrnl, 0x00000386, XInputdSetFailedConnectionOrBindCallback, kFunction), +XE_EXPORT(xboxkrnl, 0x00000388, XInputdSetMinMaxAuthDelay, kFunction), +XE_EXPORT(xboxkrnl, 0x00000389, VgcHandler_SetHandlers, kFunction), +XE_EXPORT(xboxkrnl, 0x0000038A, VvcHandlerCancelTransfers, kFunction), +XE_EXPORT(xboxkrnl, 0x0000038B, VvcHandlerRetrieveVoiceExtension, kFunction), +XE_EXPORT(xboxkrnl, 0x0000038D, MmResetLowestAvailablePages, kFunction), +XE_EXPORT(xboxkrnl, 0x00000394, VeSetHandlers, kFunction), +XE_EXPORT(xboxkrnl, 0x00000395, HalConfigureVeDevice, kFunction), +XE_EXPORT(xboxkrnl, 0x00000396, XeCryptSha224Init, kFunction), +XE_EXPORT(xboxkrnl, 0x00000397, XeCryptAesCreateKeySchedule, kFunction), +XE_EXPORT(xboxkrnl, 0x00000398, XeCryptAesEncryptOne, kFunction), +XE_EXPORT(xboxkrnl, 0x00000399, XeCryptAesDecryptOne, kFunction), +XE_EXPORT(xboxkrnl, 0x0000039A, XeCryptAesCbcEncrypt, kFunction), +XE_EXPORT(xboxkrnl, 0x0000039B, XeCryptAesCbcDecrypt, kFunction), +XE_EXPORT(xboxkrnl, 0x0000039C, XeCryptAesGcmInitialize, kFunction), +XE_EXPORT(xboxkrnl, 0x0000039D, XeCryptAesGcmUpdate, kFunction), +XE_EXPORT(xboxkrnl, 0x0000039E, XeCryptAesGcmFinalize, kFunction), +XE_EXPORT(xboxkrnl, 0x0000039F, XeCryptEccGetCurveParameters, kFunction), +XE_EXPORT(xboxkrnl, 0x000003A0, XeCryptEccEcdhGenerateKeypair, kFunction), +XE_EXPORT(xboxkrnl, 0x000003A1, XeCryptEccEcdhExponentiate, kFunction), +XE_EXPORT(xboxkrnl, 0x000003A2, XeCryptEccEcdsaGenerateSignature, kFunction), +XE_EXPORT(xboxkrnl, 0x000003A3, XeCryptEccEcdsaVerifySignature, kFunction), diff --git a/src/kernel/xboxkrnl/xboxkrnl_audio.cpp b/src/kernel/xboxkrnl/xboxkrnl_audio.cpp new file mode 100644 index 0000000..86e7888 --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_audio.cpp @@ -0,0 +1,150 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { +using namespace rex::system; + +u32 XAudioGetSpeakerConfig_entry(mapped_u32 config_ptr) { + *config_ptr = 0x00010001; + return X_ERROR_SUCCESS; +} + +u32 XAudioGetVoiceCategoryVolumeChangeMask_entry(mapped_void driver_ptr, mapped_u32 out_ptr) { + assert_true((driver_ptr.guest_address() & 0xFFFF0000) == 0x41550000); + + rex::thread::Sleep(std::chrono::microseconds(1)); + + // Checking these bits to see if any voice volume changed. + // I think. + *out_ptr = 0; + return X_ERROR_SUCCESS; +} + +u32 XAudioGetVoiceCategoryVolume_entry(u32 unk, mapped_f32 out_ptr) { + // Expects a floating point single. Volume %? + *out_ptr = 1.0f; + + return X_ERROR_SUCCESS; +} + +u32 XAudioEnableDucker_entry(u32 unk) { + return X_ERROR_SUCCESS; +} + +u32 XAudioRegisterRenderDriverClient_entry(mapped_u32 callback_ptr, mapped_u32 driver_ptr) { + REXKRNL_DEBUG("XAudioRegisterRenderDriverClient called! callback_ptr={:08X} driver_ptr={:08X}", + callback_ptr.guest_address(), driver_ptr.guest_address()); + if (!callback_ptr) { + return X_E_INVALIDARG; + } + + uint32_t callback = callback_ptr[0]; + + if (!callback) { + return X_E_INVALIDARG; + } + uint32_t callback_arg = callback_ptr[1]; + + auto* audio_system = + static_cast(REX_KERNEL_STATE()->emulator()->audio_system()); + + size_t index; + auto result = audio_system->RegisterClient(callback, callback_arg, &index); + if (XFAILED(result)) { + return result; + } + + assert_true(!(index & ~0x0000FFFF)); + *driver_ptr = 0x41550000 | (static_cast(index) & 0x0000FFFF); + return X_ERROR_SUCCESS; +} + +u32 XAudioUnregisterRenderDriverClient_entry(mapped_void driver_ptr) { + assert_true((driver_ptr.guest_address() & 0xFFFF0000) == 0x41550000); + + auto* audio_system = + static_cast(REX_KERNEL_STATE()->emulator()->audio_system()); + audio_system->UnregisterClient(driver_ptr.guest_address() & 0x0000FFFF); + return X_ERROR_SUCCESS; +} + +u32 XAudioSubmitRenderDriverFrame_entry(mapped_void driver_ptr, mapped_void samples_ptr) { + assert_true((driver_ptr.guest_address() & 0xFFFF0000) == 0x41550000); + + static uint32_t submit_krnl_count = 0; + if (submit_krnl_count < 10) { + REXKRNL_DEBUG("XAudioSubmitRenderDriverFrame: driver={:08X} samples={:08X}", + driver_ptr.guest_address(), samples_ptr.guest_address()); + submit_krnl_count++; + } + + auto* audio_system = + static_cast(REX_KERNEL_STATE()->emulator()->audio_system()); + audio_system->SubmitFrame(driver_ptr.guest_address() & 0x0000FFFF, samples_ptr.guest_address()); + + return X_ERROR_SUCCESS; +} + +} // namespace rex::kernel::xboxkrnl + +REX_EXPORT(__imp__XAudioGetSpeakerConfig, rex::kernel::xboxkrnl::XAudioGetSpeakerConfig_entry) +REX_EXPORT(__imp__XAudioGetVoiceCategoryVolumeChangeMask, + rex::kernel::xboxkrnl::XAudioGetVoiceCategoryVolumeChangeMask_entry) +REX_EXPORT(__imp__XAudioGetVoiceCategoryVolume, + rex::kernel::xboxkrnl::XAudioGetVoiceCategoryVolume_entry) +REX_EXPORT(__imp__XAudioEnableDucker, rex::kernel::xboxkrnl::XAudioEnableDucker_entry) +REX_EXPORT(__imp__XAudioRegisterRenderDriverClient, + rex::kernel::xboxkrnl::XAudioRegisterRenderDriverClient_entry) +REX_EXPORT(__imp__XAudioUnregisterRenderDriverClient, + rex::kernel::xboxkrnl::XAudioUnregisterRenderDriverClient_entry) +REX_EXPORT(__imp__XAudioSubmitRenderDriverFrame, + rex::kernel::xboxkrnl::XAudioSubmitRenderDriverFrame_entry) + +REX_EXPORT_STUB(__imp__XAudioRenderDriverInitialize); +REX_EXPORT_STUB(__imp__XAudioRenderDriverLock); +REX_EXPORT_STUB(__imp__XAudioSetVoiceCategoryVolume); +REX_EXPORT_STUB(__imp__XAudioBeginDigitalBypassMode); +REX_EXPORT_STUB(__imp__XAudioEndDigitalBypassMode); +REX_EXPORT_STUB(__imp__XAudioSubmitDigitalPacket); +REX_EXPORT_STUB(__imp__XAudioQueryDriverPerformance); +REX_EXPORT_STUB(__imp__XAudioGetRenderDriverThread); +REX_EXPORT_STUB(__imp__XAudioSetSpeakerConfig); +REX_EXPORT_STUB(__imp__XAudioOverrideSpeakerConfig); +REX_EXPORT_STUB(__imp__XAudioSuspendRenderDriverClients); +REX_EXPORT_STUB(__imp__XAudioRegisterRenderDriverMECClient); +REX_EXPORT_STUB(__imp__XAudioUnregisterRenderDriverMECClient); +REX_EXPORT_STUB(__imp__XAudioCaptureRenderDriverFrame); +REX_EXPORT_STUB(__imp__XAudioGetRenderDriverTic); +REX_EXPORT_STUB(__imp__XAudioSetDuckerLevel); +REX_EXPORT_STUB(__imp__XAudioIsDuckerEnabled); +REX_EXPORT_STUB(__imp__XAudioGetDuckerLevel); +REX_EXPORT_STUB(__imp__XAudioGetDuckerThreshold); +REX_EXPORT_STUB(__imp__XAudioSetDuckerThreshold); +REX_EXPORT_STUB(__imp__XAudioGetDuckerAttackTime); +REX_EXPORT_STUB(__imp__XAudioSetDuckerAttackTime); +REX_EXPORT_STUB(__imp__XAudioGetDuckerReleaseTime); +REX_EXPORT_STUB(__imp__XAudioSetDuckerReleaseTime); +REX_EXPORT_STUB(__imp__XAudioGetDuckerHoldTime); +REX_EXPORT_STUB(__imp__XAudioSetDuckerHoldTime); +REX_EXPORT_STUB(__imp__XAudioGetUnderrunCount); +REX_EXPORT_STUB(__imp__XAudioSetProcessFrameCallback); diff --git a/src/kernel/xboxkrnl/xboxkrnl_audio_xma.cpp b/src/kernel/xboxkrnl/xboxkrnl_audio_xma.cpp new file mode 100644 index 0000000..a84b5f5 --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_audio_xma.cpp @@ -0,0 +1,382 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { +using namespace rex::system; + +using rex::audio::XMA_CONTEXT_DATA; + +// See audio_system.cc for implementation details. +// +// XMA details: +// https://devel.nuclex.org/external/svn/directx/trunk/include/xma2defs.h +// https://github.com/gdawg/fsbext/blob/master/src/xma_header.h +// +// XMA is undocumented, but the methods are pretty simple. +// Games do this sequence to decode (now): +// (not sure we are setting buffer validity/offsets right) +// d> XMACreateContext(20656800) +// d> XMAIsInputBuffer0Valid(000103E0) +// d> XMAIsInputBuffer1Valid(000103E0) +// d> XMADisableContext(000103E0, 0) +// d> XMABlockWhileInUse(000103E0) +// d> XMAInitializeContext(000103E0, 20008810) +// d> XMASetOutputBufferValid(000103E0) +// d> XMASetInputBuffer0Valid(000103E0) +// d> XMAEnableContext(000103E0) +// d> XMAGetOutputBufferWriteOffset(000103E0) +// d> XMAGetOutputBufferReadOffset(000103E0) +// d> XMAIsOutputBufferValid(000103E0) +// d> XMAGetOutputBufferReadOffset(000103E0) +// d> XMAGetOutputBufferWriteOffset(000103E0) +// d> XMAIsInputBuffer0Valid(000103E0) +// d> XMAIsInputBuffer1Valid(000103E0) +// d> XMAIsInputBuffer0Valid(000103E0) +// d> XMAIsInputBuffer1Valid(000103E0) +// d> XMAReleaseContext(000103E0) +// +// XAudio2 uses XMA under the covers, and seems to map with the same +// restrictions of frame/subframe/etc: +// https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.xaudio2.xaudio2_buffer(v=vs.85).aspx + +u32 XMACreateContext_entry(mapped_u32 context_out_ptr) { + REXKRNL_NOISY_DEBUG("XMACreateContext called!"); + auto xma_decoder = + static_cast(REX_KERNEL_STATE()->emulator()->audio_system()) + ->xma_decoder(); + uint32_t context_ptr = xma_decoder->AllocateContext(); + *context_out_ptr = context_ptr; + if (!context_ptr) { + return X_STATUS_NO_MEMORY; + } + return X_STATUS_SUCCESS; +} + +u32 XMAReleaseContext_entry(mapped_void context_ptr) { + auto xma_decoder = + static_cast(REX_KERNEL_STATE()->emulator()->audio_system()) + ->xma_decoder(); + xma_decoder->ReleaseContext(context_ptr.guest_address()); + return 0; +} + +void StoreXmaContextIndexedRegister(system::KernelState* kernel_state, uint32_t base_reg, + uint32_t context_ptr) { + uint32_t context_physical_address = REX_KERNEL_MEMORY()->GetPhysicalAddress(context_ptr); + assert_true(context_physical_address != UINT32_MAX); + auto xma_decoder = + static_cast(kernel_state->emulator()->audio_system())->xma_decoder(); + uint32_t hw_index = + (context_physical_address - xma_decoder->context_array_ptr()) / sizeof(XMA_CONTEXT_DATA); + uint32_t reg_num = base_reg + (hw_index >> 5) * 4; + uint32_t reg_value = 1 << (hw_index & 0x1F); + xma_decoder->WriteRegister(reg_num, rex::byte_swap(reg_value)); +} + +struct XMA_LOOP_DATA { + rex::be loop_start; + rex::be loop_end; + uint8_t loop_count; + uint8_t loop_subframe_end; + uint8_t loop_subframe_skip; +}; +static_assert_size(XMA_LOOP_DATA, 12); + +struct XMA_CONTEXT_INIT { + rex::be input_buffer_0_ptr; + rex::be input_buffer_0_packet_count; + rex::be input_buffer_1_ptr; + rex::be input_buffer_1_packet_count; + rex::be input_buffer_read_offset; + rex::be output_buffer_ptr; + rex::be output_buffer_block_count; + rex::be work_buffer; + rex::be subframe_decode_count; + rex::be channel_count; + rex::be sample_rate; + XMA_LOOP_DATA loop_data; +}; +static_assert_size(XMA_CONTEXT_INIT, 56); + +u32 XMAInitializeContext_entry(mapped_void context_ptr, ppc_ptr_t context_init) { + // Input buffers may be null (buffer 1 in 415607D4). + // Convert to host endianness. + uint32_t input_buffer_0_guest_ptr = context_init->input_buffer_0_ptr; + uint32_t input_buffer_0_physical_address = 0; + if (input_buffer_0_guest_ptr) { + input_buffer_0_physical_address = + REX_KERNEL_MEMORY()->GetPhysicalAddress(input_buffer_0_guest_ptr); + // Xenia-specific safety check. + assert_true(input_buffer_0_physical_address != UINT32_MAX); + if (input_buffer_0_physical_address == UINT32_MAX) { + REXKRNL_ERROR("XMAInitializeContext: Invalid input buffer 0 virtual address {:08X}", + input_buffer_0_guest_ptr); + return X_E_FALSE; + } + } + uint32_t input_buffer_1_guest_ptr = context_init->input_buffer_1_ptr; + uint32_t input_buffer_1_physical_address = 0; + if (input_buffer_1_guest_ptr) { + input_buffer_1_physical_address = + REX_KERNEL_MEMORY()->GetPhysicalAddress(input_buffer_1_guest_ptr); + assert_true(input_buffer_1_physical_address != UINT32_MAX); + if (input_buffer_1_physical_address == UINT32_MAX) { + REXKRNL_ERROR("XMAInitializeContext: Invalid input buffer 1 virtual address {:08X}", + input_buffer_1_guest_ptr); + return X_E_FALSE; + } + } + uint32_t output_buffer_guest_ptr = context_init->output_buffer_ptr; + assert_not_zero(output_buffer_guest_ptr); + uint32_t output_buffer_physical_address = + REX_KERNEL_MEMORY()->GetPhysicalAddress(output_buffer_guest_ptr); + assert_true(output_buffer_physical_address != UINT32_MAX); + if (output_buffer_physical_address == UINT32_MAX) { + REXKRNL_ERROR("XMAInitializeContext: Invalid output buffer virtual address {:08X}", + output_buffer_guest_ptr); + return X_E_FALSE; + } + + std::memset(context_ptr, 0, sizeof(XMA_CONTEXT_DATA)); + + XMA_CONTEXT_DATA context(context_ptr); + + context.input_buffer_0_ptr = input_buffer_0_physical_address; + context.input_buffer_0_packet_count = context_init->input_buffer_0_packet_count; + context.input_buffer_1_ptr = input_buffer_1_physical_address; + context.input_buffer_1_packet_count = context_init->input_buffer_1_packet_count; + context.input_buffer_read_offset = context_init->input_buffer_read_offset; + context.output_buffer_ptr = output_buffer_physical_address; + context.output_buffer_block_count = context_init->output_buffer_block_count; + + // context.work_buffer = context_init->work_buffer; // ? + context.subframe_decode_count = context_init->subframe_decode_count; + context.is_stereo = context_init->channel_count >= 1; + context.sample_rate = context_init->sample_rate; + + context.loop_start = context_init->loop_data.loop_start; + context.loop_end = context_init->loop_data.loop_end; + context.loop_count = context_init->loop_data.loop_count; + context.loop_subframe_end = context_init->loop_data.loop_subframe_end; + context.loop_subframe_skip = context_init->loop_data.loop_subframe_skip; + + context.Store(context_ptr); + + StoreXmaContextIndexedRegister(REX_KERNEL_STATE(), 0x1A80, context_ptr.guest_address()); + + return 0; +} + +u32 XMASetLoopData_entry(mapped_void context_ptr, ppc_ptr_t loop_data) { + XMA_CONTEXT_DATA context(context_ptr); + + context.loop_start = loop_data->loop_start; + context.loop_end = loop_data->loop_end; + context.loop_count = loop_data->loop_count; + context.loop_subframe_end = loop_data->loop_subframe_end; + context.loop_subframe_skip = loop_data->loop_subframe_skip; + + context.Store(context_ptr); + + return 0; +} + +u32 XMAGetInputBufferReadOffset_entry(mapped_void context_ptr) { + XMA_CONTEXT_DATA context(context_ptr); + return context.input_buffer_read_offset; +} + +u32 XMASetInputBufferReadOffset_entry(mapped_void context_ptr, u32 value) { + XMA_CONTEXT_DATA context(context_ptr); + context.input_buffer_read_offset = value; + context.Store(context_ptr); + + return 0; +} + +u32 XMASetInputBuffer0_entry(mapped_void context_ptr, mapped_void buffer, u32 packet_count) { + uint32_t buffer_physical_address = + REX_KERNEL_MEMORY()->GetPhysicalAddress(buffer.guest_address()); + assert_true(buffer_physical_address != UINT32_MAX); + if (buffer_physical_address == UINT32_MAX) { + // Xenia-specific safety check. + REXKRNL_ERROR("XMASetInputBuffer0: Invalid buffer virtual address {:08X}", + buffer.guest_address()); + return X_E_FALSE; + } + + XMA_CONTEXT_DATA context(context_ptr); + + context.input_buffer_0_ptr = buffer_physical_address; + context.input_buffer_0_packet_count = packet_count; + + context.Store(context_ptr); + + return 0; +} + +u32 XMAIsInputBuffer0Valid_entry(mapped_void context_ptr) { + XMA_CONTEXT_DATA context(context_ptr); + return context.input_buffer_0_valid; +} + +u32 XMASetInputBuffer0Valid_entry(mapped_void context_ptr) { + XMA_CONTEXT_DATA context(context_ptr); + context.input_buffer_0_valid = 1; + context.Store(context_ptr); + + return 0; +} + +u32 XMASetInputBuffer1_entry(mapped_void context_ptr, mapped_void buffer, u32 packet_count) { + uint32_t buffer_physical_address = + REX_KERNEL_MEMORY()->GetPhysicalAddress(buffer.guest_address()); + assert_true(buffer_physical_address != UINT32_MAX); + if (buffer_physical_address == UINT32_MAX) { + // Xenia-specific safety check. + REXKRNL_ERROR("XMASetInputBuffer1: Invalid buffer virtual address {:08X}", + buffer.guest_address()); + return X_E_FALSE; + } + + XMA_CONTEXT_DATA context(context_ptr); + + context.input_buffer_1_ptr = buffer_physical_address; + context.input_buffer_1_packet_count = packet_count; + + context.Store(context_ptr); + + return 0; +} + +u32 XMAIsInputBuffer1Valid_entry(mapped_void context_ptr) { + XMA_CONTEXT_DATA context(context_ptr); + return context.input_buffer_1_valid; +} + +u32 XMASetInputBuffer1Valid_entry(mapped_void context_ptr) { + XMA_CONTEXT_DATA context(context_ptr); + context.input_buffer_1_valid = 1; + context.Store(context_ptr); + + return 0; +} + +u32 XMAIsOutputBufferValid_entry(mapped_void context_ptr) { + XMA_CONTEXT_DATA context(context_ptr); + return context.output_buffer_valid; +} + +u32 XMASetOutputBufferValid_entry(mapped_void context_ptr) { + XMA_CONTEXT_DATA context(context_ptr); + context.output_buffer_valid = 1; + context.Store(context_ptr); + + return 0; +} + +u32 XMAGetOutputBufferReadOffset_entry(mapped_void context_ptr) { + XMA_CONTEXT_DATA context(context_ptr); + return context.output_buffer_read_offset; +} + +u32 XMASetOutputBufferReadOffset_entry(mapped_void context_ptr, u32 value) { + XMA_CONTEXT_DATA context(context_ptr); + context.output_buffer_read_offset = value; + context.Store(context_ptr); + + return 0; +} + +u32 XMAGetOutputBufferWriteOffset_entry(mapped_void context_ptr) { + XMA_CONTEXT_DATA context(context_ptr); + return context.output_buffer_write_offset; +} + +u32 XMAGetPacketMetadata_entry(mapped_void context_ptr) { + XMA_CONTEXT_DATA context(context_ptr); + return context.packet_metadata; +} + +u32 XMAEnableContext_entry(mapped_void context_ptr) { + StoreXmaContextIndexedRegister(REX_KERNEL_STATE(), 0x1940, context_ptr.guest_address()); + return 0; +} + +u32 XMADisableContext_entry(mapped_void context_ptr, u32 wait) { + X_HRESULT result = X_E_SUCCESS; + StoreXmaContextIndexedRegister(REX_KERNEL_STATE(), 0x1A40, context_ptr.guest_address()); + if (!static_cast(REX_KERNEL_STATE()->emulator()->audio_system()) + ->xma_decoder() + ->BlockOnContext(context_ptr.guest_address(), !wait)) { + result = X_E_FALSE; + } + return result; +} + +u32 XMABlockWhileInUse_entry(mapped_void context_ptr) { + do { + XMA_CONTEXT_DATA context(context_ptr); + if (!context.input_buffer_0_valid && !context.input_buffer_1_valid) { + break; + } + if (!context.work_buffer_ptr) { + break; + } + rex::thread::Sleep(std::chrono::milliseconds(1)); + } while (true); + return 0; +} + +} // namespace rex::kernel::xboxkrnl + +REX_EXPORT(__imp__XMACreateContext, rex::kernel::xboxkrnl::XMACreateContext_entry) +REX_EXPORT(__imp__XMAReleaseContext, rex::kernel::xboxkrnl::XMAReleaseContext_entry) +REX_EXPORT(__imp__XMAInitializeContext, rex::kernel::xboxkrnl::XMAInitializeContext_entry) +REX_EXPORT(__imp__XMASetLoopData, rex::kernel::xboxkrnl::XMASetLoopData_entry) +REX_EXPORT(__imp__XMAGetInputBufferReadOffset, + rex::kernel::xboxkrnl::XMAGetInputBufferReadOffset_entry) +REX_EXPORT(__imp__XMASetInputBufferReadOffset, + rex::kernel::xboxkrnl::XMASetInputBufferReadOffset_entry) +REX_EXPORT(__imp__XMASetInputBuffer0, rex::kernel::xboxkrnl::XMASetInputBuffer0_entry) +REX_EXPORT(__imp__XMAIsInputBuffer0Valid, rex::kernel::xboxkrnl::XMAIsInputBuffer0Valid_entry) +REX_EXPORT(__imp__XMASetInputBuffer0Valid, rex::kernel::xboxkrnl::XMASetInputBuffer0Valid_entry) +REX_EXPORT(__imp__XMASetInputBuffer1, rex::kernel::xboxkrnl::XMASetInputBuffer1_entry) +REX_EXPORT(__imp__XMAIsInputBuffer1Valid, rex::kernel::xboxkrnl::XMAIsInputBuffer1Valid_entry) +REX_EXPORT(__imp__XMASetInputBuffer1Valid, rex::kernel::xboxkrnl::XMASetInputBuffer1Valid_entry) +REX_EXPORT(__imp__XMAIsOutputBufferValid, rex::kernel::xboxkrnl::XMAIsOutputBufferValid_entry) +REX_EXPORT(__imp__XMASetOutputBufferValid, rex::kernel::xboxkrnl::XMASetOutputBufferValid_entry) +REX_EXPORT(__imp__XMAGetOutputBufferReadOffset, + rex::kernel::xboxkrnl::XMAGetOutputBufferReadOffset_entry) +REX_EXPORT(__imp__XMASetOutputBufferReadOffset, + rex::kernel::xboxkrnl::XMASetOutputBufferReadOffset_entry) +REX_EXPORT(__imp__XMAGetOutputBufferWriteOffset, + rex::kernel::xboxkrnl::XMAGetOutputBufferWriteOffset_entry) +REX_EXPORT(__imp__XMAGetPacketMetadata, rex::kernel::xboxkrnl::XMAGetPacketMetadata_entry) +REX_EXPORT(__imp__XMAEnableContext, rex::kernel::xboxkrnl::XMAEnableContext_entry) +REX_EXPORT(__imp__XMADisableContext, rex::kernel::xboxkrnl::XMADisableContext_entry) +REX_EXPORT(__imp__XMABlockWhileInUse, rex::kernel::xboxkrnl::XMABlockWhileInUse_entry) diff --git a/src/kernel/xboxkrnl/xboxkrnl_crypt.cpp b/src/kernel/xboxkrnl/xboxkrnl_crypt.cpp new file mode 100644 index 0000000..765e042 --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_crypt.cpp @@ -0,0 +1,814 @@ +/** +****************************************************************************** +* Xenia : Xbox 360 Emulator Research Project * +****************************************************************************** +* Copyright 2022 Ben Vanik. All rights reserved. * +* Released under the BSD license - see LICENSE in the root for more details. * +****************************************************************************** +* +* @modified Tom Clay, 2026 - Adapted for ReXGlue runtime +*/ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include + +#include +#include +#include +#include +#include +#include +#include + +#if REX_PLATFORM_WIN32 +#include + +#include +#endif + +#include "crypto/TinySHA1.hpp" +#include "crypto/des/des.cpp" +#include "crypto/des/des.h" +#include "crypto/des/des3.h" +#include "crypto/des/descbc.h" +#include "crypto/sha256.cpp" +#include "crypto/sha256.h" + +extern "C" { +#include "aes_128/aes.h" +} + +namespace rex::kernel::xboxkrnl { + +typedef struct { + uint8_t S[256]; // 0x0 + uint8_t i; // 0x100 + uint8_t j; // 0x101 +} XECRYPT_RC4_STATE; +static_assert_size(XECRYPT_RC4_STATE, 0x102); + +void XeCryptRc4Key_entry(ppc_ptr_t rc4_ctx, mapped_void key, u32 key_size) { + // Setup RC4 state + rc4_ctx->i = rc4_ctx->j = 0; + for (uint32_t x = 0; x < 0x100; x++) { + rc4_ctx->S[x] = (uint8_t)x; + } + + uint32_t idx = 0; + for (uint32_t x = 0; x < 0x100; x++) { + idx = (idx + rc4_ctx->S[x] + key[x % 0x10]) % 0x100; + uint8_t temp = rc4_ctx->S[idx]; + rc4_ctx->S[idx] = rc4_ctx->S[x]; + rc4_ctx->S[x] = temp; + } +} + +void XeCryptRc4Ecb_entry(ppc_ptr_t rc4_ctx, mapped_void data, u32 size) { + // Crypt data + for (uint32_t idx = 0; idx < size; idx++) { + rc4_ctx->i = (rc4_ctx->i + 1) % 0x100; + rc4_ctx->j = (rc4_ctx->j + rc4_ctx->S[rc4_ctx->i]) % 0x100; + uint8_t temp = rc4_ctx->S[rc4_ctx->i]; + rc4_ctx->S[rc4_ctx->i] = rc4_ctx->S[rc4_ctx->j]; + rc4_ctx->S[rc4_ctx->j] = temp; + + uint8_t a = data[idx]; + uint8_t b = rc4_ctx->S[(rc4_ctx->S[rc4_ctx->i] + rc4_ctx->S[rc4_ctx->j]) % 0x100]; + data[idx] = (uint8_t)(a ^ b); + } +} + +void XeCryptRc4_entry(mapped_void key, u32 key_size, mapped_void data, u32 size) { + XECRYPT_RC4_STATE rc4_ctx; + XeCryptRc4Key_entry(ppc_ptr_t::from_host(&rc4_ctx), key, key_size); + XeCryptRc4Ecb_entry(ppc_ptr_t::from_host(&rc4_ctx), data, size); +} + +typedef struct { + rex::be count; // 0x0 + rex::be state[5]; // 0x4 + uint8_t buffer[64]; // 0x18 +} XECRYPT_SHA_STATE; +static_assert_size(XECRYPT_SHA_STATE, 0x58); + +void InitSha1(sha1::SHA1* sha, const XECRYPT_SHA_STATE* state) { + uint32_t digest[5]; + std::copy(std::begin(state->state), std::end(state->state), digest); + + sha->init(digest, state->buffer, state->count); +} + +void StoreSha1(const sha1::SHA1* sha, XECRYPT_SHA_STATE* state) { + std::copy_n(sha->getDigest(), rex::countof(state->state), state->state); + + state->count = static_cast(sha->getByteCount()); + std::copy_n(sha->getBlock(), sha->getBlockByteIndex(), state->buffer); +} + +void XeCryptShaInit_entry(ppc_ptr_t sha_state) { + sha_state.Zero(); + + sha_state->state[0] = 0x67452301; + sha_state->state[1] = 0xEFCDAB89; + sha_state->state[2] = 0x98BADCFE; + sha_state->state[3] = 0x10325476; + sha_state->state[4] = 0xC3D2E1F0; +} + +void XeCryptShaUpdate_entry(ppc_ptr_t sha_state, mapped_void input, + u32 input_size) { + sha1::SHA1 sha; + InitSha1(&sha, sha_state); + + sha.processBytes(input, input_size); + + StoreSha1(&sha, sha_state); +} + +void XeCryptShaFinal_entry(ppc_ptr_t sha_state, ppc_ptr_t out, + u32 out_size) { + sha1::SHA1 sha; + InitSha1(&sha, sha_state); + + uint8_t digest[0x14]; + sha.finalize(digest); + + std::copy_n(digest, std::min(rex::countof(digest), out_size), static_cast(out)); + std::copy_n(sha.getDigest(), rex::countof(sha_state->state), sha_state->state); +} + +void XeCryptSha_entry(mapped_void input_1, u32 input_1_size, mapped_void input_2, u32 input_2_size, + mapped_void input_3, u32 input_3_size, mapped_void output, u32 output_size) { + sha1::SHA1 sha; + + if (input_1 && input_1_size) { + sha.processBytes(input_1, input_1_size); + } + if (input_2 && input_2_size) { + sha.processBytes(input_2, input_2_size); + } + if (input_3 && input_3_size) { + sha.processBytes(input_3, input_3_size); + } + + uint8_t digest[0x14]; + sha.finalize(digest); + std::copy_n(digest, std::min(rex::countof(digest), output_size), output.as()); +} + +// TODO: Size of this struct hasn't been confirmed yet. +typedef struct { + rex::be count; // 0x0 + rex::be state[8]; // 0x4 + uint8_t buffer[64]; // 0x24 +} XECRYPT_SHA256_STATE; + +void XeCryptSha256Init_entry(ppc_ptr_t sha_state) { + sha_state.Zero(); + + sha_state->state[0] = 0x6a09e667; + sha_state->state[1] = 0xbb67ae85; + sha_state->state[2] = 0x3c6ef372; + sha_state->state[3] = 0xa54ff53a; + sha_state->state[4] = 0x510e527f; + sha_state->state[5] = 0x9b05688c; + sha_state->state[6] = 0x1f83d9ab; + sha_state->state[7] = 0x5be0cd19; +} + +void XeCryptSha256Update_entry(ppc_ptr_t sha_state, mapped_void input, + u32 input_size) { + sha256::SHA256 sha; + std::copy(std::begin(sha_state->state), std::end(sha_state->state), sha.getHashValues()); + std::copy(std::begin(sha_state->buffer), std::end(sha_state->buffer), sha.getBuffer()); + sha.setTotalSize(sha_state->count); + + sha.add(input, input_size); + + std::copy_n(sha.getHashValues(), rex::countof(sha_state->state), sha_state->state); + std::copy_n(sha.getBuffer(), rex::countof(sha_state->buffer), sha_state->buffer); + sha_state->count = static_cast(sha.getTotalSize()); +} + +void XeCryptSha256Final_entry(ppc_ptr_t sha_state, ppc_ptr_t out, + u32 out_size) { + sha256::SHA256 sha; + std::copy(std::begin(sha_state->state), std::end(sha_state->state), sha.getHashValues()); + std::copy(std::begin(sha_state->buffer), std::end(sha_state->buffer), sha.getBuffer()); + sha.setTotalSize(sha_state->count); + + uint8_t hash[32]; + sha.getHash(hash); + + std::copy_n(hash, std::min(rex::countof(hash), out_size), static_cast(out)); + std::copy(std::begin(hash), std::end(hash), sha_state->buffer); +} + +// Byteswaps each 8 bytes +void XeCryptBnQw_SwapDwQwLeBe_entry(ppc_ptr_t qw_inp, ppc_ptr_t qw_out, + u32 size) { + memory::copy_and_swap(qw_out, qw_inp, size); +} + +typedef struct { + rex::be size; // size of modulus in 8 byte units + rex::be public_exponent; + rex::be pad_8; + + // followed by modulus, followed by any private-key data +} XECRYPT_RSA; +static_assert_size(XECRYPT_RSA, 0x10); + +u32 XeCryptBnQwNeRsaPubCrypt_entry(ppc_ptr_t qw_a, ppc_ptr_t qw_b, + ppc_ptr_t rsa) { + // 0 indicates failure (but not a BOOL return value) +#if !REX_PLATFORM_WIN32 + REXKRNL_ERROR( + "XeCryptBnQwNeRsaPubCrypt called but no implementation available for " + "this platform!"); + assert_always(); + return 1; +#else + uint32_t modulus_size = rsa->size * 8; + + // Convert XECRYPT blob into BCrypt format + ULONG key_size = sizeof(BCRYPT_RSAKEY_BLOB) + sizeof(uint32_t) + modulus_size; + auto key_buf = std::make_unique(key_size); + auto* key_header = reinterpret_cast(key_buf.get()); + + key_header->Magic = BCRYPT_RSAPUBLIC_MAGIC; + key_header->BitLength = modulus_size * 8; + key_header->cbPublicExp = sizeof(uint32_t); + key_header->cbModulus = modulus_size; + key_header->cbPrime1 = key_header->cbPrime2 = 0; + + // Copy in exponent/modulus, luckily these are BE inside BCrypt blob + uint32_t* key_exponent = reinterpret_cast(&key_header[1]); + *key_exponent = rsa->public_exponent.value; + + // ...except modulus needs to be reversed in 64-bit chunks for BCrypt to make + // use of it properly for some reason + uint64_t* key_modulus = reinterpret_cast(&key_exponent[1]); + uint64_t* xecrypt_modulus = reinterpret_cast(&rsa[1]); + std::reverse_copy(xecrypt_modulus, xecrypt_modulus + rsa->size, key_modulus); + + BCRYPT_ALG_HANDLE hAlgorithm = NULL; + NTSTATUS status = + BCryptOpenAlgorithmProvider(&hAlgorithm, BCRYPT_RSA_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); + + if (!BCRYPT_SUCCESS(status)) { + REXKRNL_ERROR( + "XeCryptBnQwNeRsaPubCrypt: BCryptOpenAlgorithmProvider failed with " + "status {:#X}!", + status); + return 0; + } + + BCRYPT_KEY_HANDLE hKey = NULL; + status = BCryptImportKeyPair(hAlgorithm, NULL, BCRYPT_RSAPUBLIC_BLOB, &hKey, key_buf.get(), + key_size, 0); + + if (!BCRYPT_SUCCESS(status)) { + REXKRNL_ERROR( + "XeCryptBnQwNeRsaPubCrypt: BCryptImportKeyPair failed with status " + "{:#X}!", + status); + + if (hAlgorithm) { + BCryptCloseAlgorithmProvider(hAlgorithm, 0); + } + + return 0; + } + + // Byteswap & reverse the input into output, as BCrypt wants MSB first + uint64_t* output = qw_b; + uint8_t* output_bytes = reinterpret_cast(output); + memory::copy_and_swap(output, qw_a, rsa->size); + std::reverse(output_bytes, output_bytes + modulus_size); + + // BCryptDecrypt only works with private keys, fortunately BCryptEncrypt + // performs the right actions needed for us to decrypt the input + ULONG result_size = 0; + status = BCryptEncrypt(hKey, output_bytes, modulus_size, nullptr, nullptr, 0, output_bytes, + modulus_size, &result_size, BCRYPT_PAD_NONE); + + assert(result_size == modulus_size); + + if (!BCRYPT_SUCCESS(status)) { + REXKRNL_ERROR("XeCryptBnQwNeRsaPubCrypt: BCryptEncrypt failed with status {:#X}!", status); + } else { + // Reverse data & byteswap again so data is as game expects + std::reverse(output_bytes, output_bytes + modulus_size); + memory::copy_and_swap(output, output, rsa->size); + } + + if (hKey) { + BCryptDestroyKey(hKey); + } + if (hAlgorithm) { + BCryptCloseAlgorithmProvider(hAlgorithm, 0); + } + + return BCRYPT_SUCCESS(status) ? 1 : 0; +#endif +} +#if REX_PLATFORM_WIN32 + +#else + +#endif + +u32 XeCryptBnDwLePkcs1Verify_entry(mapped_void hash, mapped_void sig, u32 size) { + // BOOL return value + return 1; +} + +void XeCryptRandom_entry(mapped_void buf, u32 buf_size) { + std::memset(buf, 0xFD, buf_size); +} + +struct XECRYPT_DES_STATE { + uint32_t keytab[16][2]; +}; + +// Sets bit 0 to make the parity odd +void XeCryptDesParity_entry(mapped_void inp, u32 inp_size, mapped_void out_ptr) { + DES::set_parity(inp, inp_size, out_ptr); +} + +struct XECRYPT_DES3_STATE { + XECRYPT_DES_STATE des_state[3]; +}; + +void XeCryptDes3Key_entry(ppc_ptr_t state_ptr, mapped_u64 key) { + DES3 des3(key[0], key[1], key[2]); + DES* des = des3.getDES(); + + // Store our DES state into the state. + for (int i = 0; i < 3; i++) { + std::memcpy(state_ptr->des_state[i].keytab, des[i].get_sub_key(), 128); + } +} + +void XeCryptDes3Ecb_entry(ppc_ptr_t state_ptr, mapped_u64 inp, mapped_u64 out, + u32 encrypt) { + DES3 des3((ui64*)state_ptr->des_state[0].keytab, (ui64*)state_ptr->des_state[1].keytab, + (ui64*)state_ptr->des_state[2].keytab); + + if (encrypt) { + *out = des3.encrypt(*inp); + } else { + *out = des3.decrypt(*inp); + } +} + +void XeCryptDes3Cbc_entry(ppc_ptr_t state_ptr, mapped_u64 inp, u32 inp_size, + mapped_u64 out, mapped_u64 feed, u32 encrypt) { + DES3 des3((ui64*)state_ptr->des_state[0].keytab, (ui64*)state_ptr->des_state[1].keytab, + (ui64*)state_ptr->des_state[2].keytab); + + // DES can only do 8-byte chunks at a time! + assert_true(inp_size % 8 == 0); + + uint64_t last_block = *feed; + for (uint32_t i = 0; i < inp_size / 8; i++) { + uint64_t block = inp[i]; + if (encrypt) { + last_block = des3.encrypt(block ^ last_block); + out[i] = last_block; + } else { + out[i] = des3.decrypt(block) ^ last_block; + last_block = block; + } + } + + *feed = last_block; +} + +struct XECRYPT_AES_STATE { + uint8_t keytabenc[11][4][4]; // 0x0 + uint8_t keytabdec[11][4][4]; // 0xB0 +}; +static_assert_size(XECRYPT_AES_STATE, 0x160); + +static inline uint8_t xeXeCryptAesMul2(uint8_t a) { + return (a & 0x80) ? ((a << 1) ^ 0x1B) : (a << 1); +} + +void XeCryptAesKey_entry(ppc_ptr_t state_ptr, mapped_void key) { + aes_key_schedule_128(key, reinterpret_cast(state_ptr->keytabenc)); + // Decryption key schedule not needed by openluopworld/aes_128, but generated + // to fill the context structure properly. + std::memcpy(state_ptr->keytabdec[0], state_ptr->keytabenc[10], 16); + // Inverse MixColumns. + for (uint32_t i = 1; i < 10; ++i) { + const uint8_t* enc = reinterpret_cast(state_ptr->keytabenc[10 - i]); + uint8_t* dec = reinterpret_cast(state_ptr->keytabdec[i]); + uint8_t t, u, v; + t = enc[0] ^ enc[1] ^ enc[2] ^ enc[3]; + dec[0] = t ^ enc[0] ^ xeXeCryptAesMul2(enc[0] ^ enc[1]); + dec[1] = t ^ enc[1] ^ xeXeCryptAesMul2(enc[1] ^ enc[2]); + dec[2] = t ^ enc[2] ^ xeXeCryptAesMul2(enc[2] ^ enc[3]); + dec[3] = t ^ enc[3] ^ xeXeCryptAesMul2(enc[3] ^ enc[0]); + u = xeXeCryptAesMul2(xeXeCryptAesMul2(enc[0] ^ enc[2])); + v = xeXeCryptAesMul2(xeXeCryptAesMul2(enc[1] ^ enc[3])); + t = xeXeCryptAesMul2(u ^ v); + dec[0] ^= t ^ u; + dec[1] ^= t ^ v; + dec[2] ^= t ^ u; + dec[3] ^= t ^ v; + t = enc[4] ^ enc[5] ^ enc[6] ^ enc[7]; + dec[4] = t ^ enc[4] ^ xeXeCryptAesMul2(enc[4] ^ enc[5]); + dec[5] = t ^ enc[5] ^ xeXeCryptAesMul2(enc[5] ^ enc[6]); + dec[6] = t ^ enc[6] ^ xeXeCryptAesMul2(enc[6] ^ enc[7]); + dec[7] = t ^ enc[7] ^ xeXeCryptAesMul2(enc[7] ^ enc[4]); + u = xeXeCryptAesMul2(xeXeCryptAesMul2(enc[4] ^ enc[6])); + v = xeXeCryptAesMul2(xeXeCryptAesMul2(enc[5] ^ enc[7])); + t = xeXeCryptAesMul2(u ^ v); + dec[4] ^= t ^ u; + dec[5] ^= t ^ v; + dec[6] ^= t ^ u; + dec[7] ^= t ^ v; + t = enc[8] ^ enc[9] ^ enc[10] ^ enc[11]; + dec[8] = t ^ enc[8] ^ xeXeCryptAesMul2(enc[8] ^ enc[9]); + dec[9] = t ^ enc[9] ^ xeXeCryptAesMul2(enc[9] ^ enc[10]); + dec[10] = t ^ enc[10] ^ xeXeCryptAesMul2(enc[10] ^ enc[11]); + dec[11] = t ^ enc[11] ^ xeXeCryptAesMul2(enc[11] ^ enc[8]); + u = xeXeCryptAesMul2(xeXeCryptAesMul2(enc[8] ^ enc[10])); + v = xeXeCryptAesMul2(xeXeCryptAesMul2(enc[9] ^ enc[11])); + t = xeXeCryptAesMul2(u ^ v); + dec[8] ^= t ^ u; + dec[9] ^= t ^ v; + dec[10] ^= t ^ u; + dec[11] ^= t ^ v; + t = enc[12] ^ enc[13] ^ enc[14] ^ enc[15]; + dec[12] = t ^ enc[12] ^ xeXeCryptAesMul2(enc[12] ^ enc[13]); + dec[13] = t ^ enc[13] ^ xeXeCryptAesMul2(enc[13] ^ enc[14]); + dec[14] = t ^ enc[14] ^ xeXeCryptAesMul2(enc[14] ^ enc[15]); + dec[15] = t ^ enc[15] ^ xeXeCryptAesMul2(enc[15] ^ enc[12]); + u = xeXeCryptAesMul2(xeXeCryptAesMul2(enc[12] ^ enc[14])); + v = xeXeCryptAesMul2(xeXeCryptAesMul2(enc[13] ^ enc[15])); + t = xeXeCryptAesMul2(u ^ v); + dec[12] ^= t ^ u; + dec[13] ^= t ^ v; + dec[14] ^= t ^ u; + dec[15] ^= t ^ v; + } + std::memcpy(state_ptr->keytabdec[10], state_ptr->keytabenc[0], 16); + // TODO(Triang3l): Verify the order in keytabenc and everything in keytabdec. +} + +void XeCryptAesEcb_entry(ppc_ptr_t state_ptr, mapped_void inp_ptr, + mapped_void out_ptr, u32 encrypt) { + const uint8_t* keytab = reinterpret_cast(state_ptr->keytabenc); + if (encrypt) { + aes_encrypt_128(keytab, inp_ptr, out_ptr); + } else { + aes_decrypt_128(keytab, inp_ptr, out_ptr); + } +} + +void XeCryptAesCbc_entry(ppc_ptr_t state_ptr, mapped_void inp_ptr, u32 inp_size, + mapped_void out_ptr, mapped_void feed_ptr, u32 encrypt) { + const uint8_t* keytab = reinterpret_cast(state_ptr->keytabenc); + const uint8_t* inp = inp_ptr.as(); + uint8_t* out = out_ptr.as(); + uint8_t* feed = feed_ptr.as(); + if (encrypt) { + for (uint32_t i = 0; i < inp_size; i += 16) { + for (uint32_t j = 0; j < 16; ++j) { + feed[j] ^= inp[j]; + } + aes_encrypt_128(keytab, feed, feed); + std::memcpy(out, feed, 16); + inp += 16; + out += 16; + } + } else { + for (uint32_t i = 0; i < inp_size; i += 16) { + // In case inp == out. + uint8_t tmp[16]; + std::memcpy(tmp, inp, 16); + aes_decrypt_128(keytab, inp, out); + for (uint32_t j = 0; j < 16; ++j) { + out[j] ^= feed[j]; + } + std::memcpy(feed, tmp, 16); + inp += 16; + out += 16; + } + } +} + +void XeCryptHmacSha_entry(mapped_void key, u32 key_size_in, mapped_void inp_1, u32 inp_1_size, + mapped_void inp_2, u32 inp_2_size, mapped_void inp_3, u32 inp_3_size, + mapped_void out, u32 out_size) { + uint32_t key_size = key_size_in; + sha1::SHA1 sha; + uint8_t kpad_i[0x40]; + uint8_t kpad_o[0x40]; + uint8_t tmp_key[0x40]; + std::memset(kpad_i, 0x36, 0x40); + std::memset(kpad_o, 0x5C, 0x40); + + // Setup HMAC key + // If > block size, use its hash + if (key_size > 0x40) { + sha1::SHA1 sha_key; + sha_key.processBytes(key, key_size); + sha_key.finalize((uint8_t*)tmp_key); + + key_size = 0x14u; + } else { + std::memcpy(tmp_key, key, key_size); + } + + for (uint32_t i = 0; i < key_size; i++) { + kpad_i[i] = tmp_key[i] ^ 0x36; + kpad_o[i] = tmp_key[i] ^ 0x5C; + } + + // Inner + sha.processBytes(kpad_i, 0x40); + + if (inp_1_size) { + sha.processBytes(inp_1, inp_1_size); + } + + if (inp_2_size) { + sha.processBytes(inp_2, inp_2_size); + } + + if (inp_3_size) { + sha.processBytes(inp_3, inp_3_size); + } + + uint8_t digest[0x14]; + sha.finalize(digest); + sha.reset(); + + // Outer + sha.processBytes(kpad_o, 0x40); + sha.processBytes(digest, 0x14); + sha.finalize(digest); + + std::memcpy(out, digest, std::min((uint32_t)out_size, 0x14u)); +} + +// Keys +// TODO: Array of keys we need + +// Retail key 0x19 +static const uint8_t key19[] = {0xE1, 0xBC, 0x15, 0x9C, 0x73, 0xB1, 0xEA, 0xE9, + 0xAB, 0x31, 0x70, 0xF3, 0xAD, 0x47, 0xEB, 0xF3}; + +u32 XeKeysHmacSha_entry(u32 key_num, mapped_void inp_1, u32 inp_1_size, mapped_void inp_2, + u32 inp_2_size, mapped_void inp_3, u32 inp_3_size, mapped_void out, + u32 out_size) { + const uint8_t* key = nullptr; + if (key_num == 0x19) { + key = key19; + } + + if (key) { + XeCryptHmacSha_entry(mapped_void::from_host((void*)key), 0x10, inp_1, inp_1_size, inp_2, + inp_2_size, inp_3, inp_3_size, out, out_size); + + return X_STATUS_SUCCESS; + } + + return X_STATUS_UNSUCCESSFUL; +} + +static const uint8_t xe_key_obfuscation_key[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +u32 XeKeysAesCbcUsingKey_entry(mapped_void obscured_key, mapped_void inp_ptr, u32 inp_size, + mapped_void out_ptr, mapped_void feed_ptr, u32 encrypt) { + uint8_t key[16]; + + // Deobscure key + XECRYPT_AES_STATE aes; + XeCryptAesKey_entry(ppc_ptr_t::from_host(&aes), + mapped_void::from_host((void*)xe_key_obfuscation_key)); + XeCryptAesEcb_entry(ppc_ptr_t::from_host(&aes), obscured_key, + mapped_void::from_host(key), 0); + + // Run CBC using deobscured key + XeCryptAesKey_entry(ppc_ptr_t::from_host(&aes), mapped_void::from_host(key)); + XeCryptAesCbc_entry(ppc_ptr_t::from_host(&aes), inp_ptr, inp_size, out_ptr, + feed_ptr, encrypt); + + return X_STATUS_SUCCESS; +} + +u32 XeKeysObscureKey_entry(mapped_void input, mapped_void output) { + // Based on HvxKeysObscureKey + // Seems to encrypt input with per-console KEY_OBFUSCATION_KEY (key 0x18) + + XECRYPT_AES_STATE aes; + XeCryptAesKey_entry(ppc_ptr_t::from_host(&aes), + mapped_void::from_host((void*)xe_key_obfuscation_key)); + XeCryptAesEcb_entry(ppc_ptr_t::from_host(&aes), input, output, 1); + + return X_STATUS_SUCCESS; +} + +u32 XeKeysHmacShaUsingKey_entry(mapped_void obscured_key, mapped_void inp_1, u32 inp_1_size, + mapped_void inp_2, u32 inp_2_size, mapped_void inp_3, + u32 inp_3_size, mapped_void out, u32 out_size) { + if (!obscured_key) { + return X_STATUS_INVALID_PARAMETER; + } + + uint8_t key[16]; + + // Deobscure key + XECRYPT_AES_STATE aes; + XeCryptAesKey_entry(ppc_ptr_t::from_host(&aes), + mapped_void::from_host((void*)xe_key_obfuscation_key)); + XeCryptAesEcb_entry(ppc_ptr_t::from_host(&aes), obscured_key, + mapped_void::from_host(key), 0); + + XeCryptHmacSha_entry(mapped_void::from_host(key), 0x10, inp_1, inp_1_size, inp_2, inp_2_size, + inp_3, inp_3_size, out, out_size); + return X_STATUS_SUCCESS; +} + +u32 XeKeysConsolePrivateKeySign_entry(mapped_void hash, mapped_void signature) { + REXKRNL_DEBUG("XeKeysConsolePrivateKeySign - stub"); + return 0; // Success +} + +u32 XeKeysConsoleSignatureVerification_entry(mapped_void hash, mapped_void signature, + mapped_void pubkey) { + REXKRNL_DEBUG("XeKeysConsoleSignatureVerification - stub"); + return 0; // Success (signature valid) +} + +REX_EXPORT_STUB(__imp__XeKeysGetConsoleCertificate); +REX_EXPORT_STUB(__imp__XeCryptBnDwLeDhEqualBase); +REX_EXPORT_STUB(__imp__XeCryptBnDwLeDhInvalBase); +REX_EXPORT_STUB(__imp__XeCryptBnDwLeDhModExp); +REX_EXPORT_STUB(__imp__XeCryptBnDw_Copy); +REX_EXPORT_STUB(__imp__XeCryptBnDw_SwapLeBe); +REX_EXPORT_STUB(__imp__XeCryptBnDw_Zero); +REX_EXPORT_STUB(__imp__XeCryptBnDwLePkcs1Format); +REX_EXPORT_STUB(__imp__XeCryptBnQwBeSigCreate); +REX_EXPORT_STUB(__imp__XeCryptBnQwBeSigFormat); +REX_EXPORT_STUB(__imp__XeCryptBnQwBeSigVerify); +REX_EXPORT_STUB(__imp__XeCryptBnQwNeModExp); +REX_EXPORT_STUB(__imp__XeCryptBnQwNeModExpRoot); +REX_EXPORT_STUB(__imp__XeCryptBnQwNeModInv); +REX_EXPORT_STUB(__imp__XeCryptBnQwNeModMul); +REX_EXPORT_STUB(__imp__XeCryptBnQwNeRsaKeyGen); +REX_EXPORT_STUB(__imp__XeCryptBnQwNeRsaPrvCrypt); +REX_EXPORT_STUB(__imp__XeCryptBnQw_Copy); +REX_EXPORT_STUB(__imp__XeCryptBnQw_SwapDwQw); +REX_EXPORT_STUB(__imp__XeCryptBnQw_SwapLeBe); +REX_EXPORT_STUB(__imp__XeCryptBnQw_Zero); +REX_EXPORT_STUB(__imp__XeCryptChainAndSumMac); +REX_EXPORT_STUB(__imp__XeCryptDesKey); +REX_EXPORT_STUB(__imp__XeCryptDesEcb); +REX_EXPORT_STUB(__imp__XeCryptDesCbc); +REX_EXPORT_STUB(__imp__XeCryptHmacMd5Init); +REX_EXPORT_STUB(__imp__XeCryptHmacMd5Update); +REX_EXPORT_STUB(__imp__XeCryptHmacMd5Final); +REX_EXPORT_STUB(__imp__XeCryptHmacMd5); +REX_EXPORT_STUB(__imp__XeCryptHmacShaInit); +REX_EXPORT_STUB(__imp__XeCryptHmacShaUpdate); +REX_EXPORT_STUB(__imp__XeCryptHmacShaFinal); +REX_EXPORT_STUB(__imp__XeCryptHmacShaVerify); +REX_EXPORT_STUB(__imp__XeCryptMd5Init); +REX_EXPORT_STUB(__imp__XeCryptMd5Update); +REX_EXPORT_STUB(__imp__XeCryptMd5Final); +REX_EXPORT_STUB(__imp__XeCryptMd5); +REX_EXPORT_STUB(__imp__XeCryptParveEcb); +REX_EXPORT_STUB(__imp__XeCryptParveCbcMac); +REX_EXPORT_STUB(__imp__XeCryptRotSumSha); +REX_EXPORT_STUB(__imp__XeCryptSha256); +REX_EXPORT_STUB(__imp__XeCryptSha384Init); +REX_EXPORT_STUB(__imp__XeCryptSha384Update); +REX_EXPORT_STUB(__imp__XeCryptSha384Final); +REX_EXPORT_STUB(__imp__XeCryptSha384); +REX_EXPORT_STUB(__imp__XeCryptSha512Init); +REX_EXPORT_STUB(__imp__XeCryptSha512Update); +REX_EXPORT_STUB(__imp__XeCryptSha512Final); +REX_EXPORT_STUB(__imp__XeCryptSha512); +REX_EXPORT_STUB(__imp__XeCryptBnQwNeCompare); +REX_EXPORT_STUB(__imp__XeKeysGetFactoryChallenge); +REX_EXPORT_STUB(__imp__XeKeysSetFactoryResponse); +REX_EXPORT_STUB(__imp__XeKeysInitializeFuses); +REX_EXPORT_STUB(__imp__XeKeysSaveBootLoader); +REX_EXPORT_STUB(__imp__XeKeysSaveKeyVault); +REX_EXPORT_STUB(__imp__XeKeysGetStatus); +REX_EXPORT_STUB(__imp__XeKeysGeneratePrivateKey); +REX_EXPORT_STUB(__imp__XeKeysGetKeyProperties); +REX_EXPORT_STUB(__imp__XeKeysSetKey); +REX_EXPORT_STUB(__imp__XeKeysGenerateRandomKey); +REX_EXPORT_STUB(__imp__XeKeysGetKey); +REX_EXPORT_STUB(__imp__XeKeysGetDigest); +REX_EXPORT_STUB(__imp__XeKeysGetConsoleID); +REX_EXPORT_STUB(__imp__XeKeysGetConsoleType); +REX_EXPORT_STUB(__imp__XeKeysQwNeRsaPrvCrypt); +REX_EXPORT_STUB(__imp__XeKeysAesCbc); +REX_EXPORT_STUB(__imp__XeKeysDes2Cbc); +REX_EXPORT_STUB(__imp__XeKeysDesCbc); +REX_EXPORT_STUB(__imp__XeKeysSaveBootLoaderEx); +REX_EXPORT_STUB(__imp__XeKeysDes2CbcUsingKey); +REX_EXPORT_STUB(__imp__XeKeysDesCbcUsingKey); +REX_EXPORT_STUB(__imp__XeKeysObfuscate); +REX_EXPORT_STUB(__imp__XeKeysUnObfuscate); +REX_EXPORT_STUB(__imp__XeKeysVerifyRSASignature); +REX_EXPORT_STUB(__imp__XeKeysSaveSystemUpdate); +REX_EXPORT_STUB(__imp__XeKeysLockSystemUpdate); +REX_EXPORT_STUB(__imp__XeKeysExecute); +REX_EXPORT_STUB(__imp__XeKeysGetVersions); +REX_EXPORT_STUB(__imp__XeKeysSetRevocationList); +REX_EXPORT_STUB(__imp__XeKeysExSaveKeyVault); +REX_EXPORT_STUB(__imp__XeKeysExSetKey); +REX_EXPORT_STUB(__imp__XeKeysExGetKey); +REX_EXPORT_STUB(__imp__XeKeysSecurityInitialize); +REX_EXPORT_STUB(__imp__XeKeysSecurityLoadSettings); +REX_EXPORT_STUB(__imp__XeKeysSecuritySaveSettings); +REX_EXPORT_STUB(__imp__XeKeysSecuritySetDetected); +REX_EXPORT_STUB(__imp__XeKeysSecurityGetDetected); +REX_EXPORT_STUB(__imp__XeKeysSecuritySetActivated); +REX_EXPORT_STUB(__imp__XeKeysSecurityGetActivated); +REX_EXPORT_STUB(__imp__XeKeysDvdAuthAP25InstallTable); +REX_EXPORT_STUB(__imp__XeKeysDvdAuthAP25GetTableVersion); +REX_EXPORT_STUB(__imp__XeKeysGetProtectedFlag); +REX_EXPORT_STUB(__imp__XeKeysSetProtectedFlag); +REX_EXPORT_STUB(__imp__XeKeysGetUpdateSequence); +REX_EXPORT_STUB(__imp__XeKeysDvdAuthExActivate); +REX_EXPORT_STUB(__imp__XeKeysRevokeSaveSettings); +REX_EXPORT_STUB(__imp__XeKeysGetMediaID); +REX_EXPORT_STUB(__imp__XeKeysLoadKeyVault); +REX_EXPORT_STUB(__imp__XeKeysRevokeUpdateDynamic); +REX_EXPORT_STUB(__imp__XeKeysSecuritySetStat); +REX_EXPORT_STUB(__imp__XeKeysFcrtLoad); +REX_EXPORT_STUB(__imp__XeKeysFcrtSave); +REX_EXPORT_STUB(__imp__XeKeysFcrtSet); +REX_EXPORT_STUB(__imp__XeKeysRevokeIsDeviceRevoked); +REX_EXPORT_STUB(__imp__XeKeysDvdAuthExSave); +REX_EXPORT_STUB(__imp__XeKeysDvdAuthExInstall); +REX_EXPORT_STUB(__imp__XeKeysObfuscateEx); +REX_EXPORT_STUB(__imp__XeKeysUnObfuscateEx); +REX_EXPORT_STUB(__imp__XeKeysVerifyPIRSSignature); +REX_EXPORT_STUB(__imp__XeCryptAesCtr); +REX_EXPORT_STUB(__imp__XeCryptAesCbcMac); +REX_EXPORT_STUB(__imp__XeCryptAesDmMac); +REX_EXPORT_STUB(__imp__XeKeysGetTruncatedSecondaryConsoleId); +REX_EXPORT_STUB(__imp__XeCryptSha224Init); +REX_EXPORT_STUB(__imp__XeCryptAesCreateKeySchedule); +REX_EXPORT_STUB(__imp__XeCryptAesEncryptOne); +REX_EXPORT_STUB(__imp__XeCryptAesDecryptOne); +REX_EXPORT_STUB(__imp__XeCryptAesCbcEncrypt); +REX_EXPORT_STUB(__imp__XeCryptAesCbcDecrypt); +REX_EXPORT_STUB(__imp__XeCryptAesGcmInitialize); +REX_EXPORT_STUB(__imp__XeCryptAesGcmUpdate); +REX_EXPORT_STUB(__imp__XeCryptAesGcmFinalize); +REX_EXPORT_STUB(__imp__XeCryptEccGetCurveParameters); +REX_EXPORT_STUB(__imp__XeCryptEccEcdhGenerateKeypair); +REX_EXPORT_STUB(__imp__XeCryptEccEcdhExponentiate); +REX_EXPORT_STUB(__imp__XeCryptEccEcdsaGenerateSignature); +REX_EXPORT_STUB(__imp__XeCryptEccEcdsaVerifySignature); + +} // namespace rex::kernel::xboxkrnl + +REX_EXPORT(__imp__XeCryptRc4Key, rex::kernel::xboxkrnl::XeCryptRc4Key_entry) +REX_EXPORT(__imp__XeCryptRc4Ecb, rex::kernel::xboxkrnl::XeCryptRc4Ecb_entry) +REX_EXPORT(__imp__XeCryptRc4, rex::kernel::xboxkrnl::XeCryptRc4_entry) +REX_EXPORT(__imp__XeCryptShaInit, rex::kernel::xboxkrnl::XeCryptShaInit_entry) +REX_EXPORT(__imp__XeCryptShaUpdate, rex::kernel::xboxkrnl::XeCryptShaUpdate_entry) +REX_EXPORT(__imp__XeCryptShaFinal, rex::kernel::xboxkrnl::XeCryptShaFinal_entry) +REX_EXPORT(__imp__XeCryptSha, rex::kernel::xboxkrnl::XeCryptSha_entry) +REX_EXPORT(__imp__XeCryptSha256Init, rex::kernel::xboxkrnl::XeCryptSha256Init_entry) +REX_EXPORT(__imp__XeCryptSha256Update, rex::kernel::xboxkrnl::XeCryptSha256Update_entry) +REX_EXPORT(__imp__XeCryptSha256Final, rex::kernel::xboxkrnl::XeCryptSha256Final_entry) +REX_EXPORT(__imp__XeCryptBnQw_SwapDwQwLeBe, rex::kernel::xboxkrnl::XeCryptBnQw_SwapDwQwLeBe_entry) +REX_EXPORT(__imp__XeCryptBnQwNeRsaPubCrypt, rex::kernel::xboxkrnl::XeCryptBnQwNeRsaPubCrypt_entry) +REX_EXPORT(__imp__XeCryptBnDwLePkcs1Verify, rex::kernel::xboxkrnl::XeCryptBnDwLePkcs1Verify_entry) +REX_EXPORT(__imp__XeCryptRandom, rex::kernel::xboxkrnl::XeCryptRandom_entry) +REX_EXPORT(__imp__XeCryptDesParity, rex::kernel::xboxkrnl::XeCryptDesParity_entry) +REX_EXPORT(__imp__XeCryptDes3Key, rex::kernel::xboxkrnl::XeCryptDes3Key_entry) +REX_EXPORT(__imp__XeCryptDes3Ecb, rex::kernel::xboxkrnl::XeCryptDes3Ecb_entry) +REX_EXPORT(__imp__XeCryptDes3Cbc, rex::kernel::xboxkrnl::XeCryptDes3Cbc_entry) +REX_EXPORT(__imp__XeCryptAesKey, rex::kernel::xboxkrnl::XeCryptAesKey_entry) +REX_EXPORT(__imp__XeCryptAesEcb, rex::kernel::xboxkrnl::XeCryptAesEcb_entry) +REX_EXPORT(__imp__XeCryptAesCbc, rex::kernel::xboxkrnl::XeCryptAesCbc_entry) +REX_EXPORT(__imp__XeCryptHmacSha, rex::kernel::xboxkrnl::XeCryptHmacSha_entry) +REX_EXPORT(__imp__XeKeysHmacSha, rex::kernel::xboxkrnl::XeKeysHmacSha_entry) +REX_EXPORT(__imp__XeKeysAesCbcUsingKey, rex::kernel::xboxkrnl::XeKeysAesCbcUsingKey_entry) +REX_EXPORT(__imp__XeKeysObscureKey, rex::kernel::xboxkrnl::XeKeysObscureKey_entry) +REX_EXPORT(__imp__XeKeysHmacShaUsingKey, rex::kernel::xboxkrnl::XeKeysHmacShaUsingKey_entry) +REX_EXPORT(__imp__XeKeysConsolePrivateKeySign, + rex::kernel::xboxkrnl::XeKeysConsolePrivateKeySign_entry) +REX_EXPORT(__imp__XeKeysConsoleSignatureVerification, + rex::kernel::xboxkrnl::XeKeysConsoleSignatureVerification_entry) + +REX_EXPORT_STUB(__imp__DevAuthGetStatistics); +REX_EXPORT_STUB(__imp__DevAuthShouldAlwaysEnforce); diff --git a/src/kernel/xboxkrnl/xboxkrnl_debug.cpp b/src/kernel/xboxkrnl/xboxkrnl_debug.cpp new file mode 100644 index 0000000..670c446 --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_debug.cpp @@ -0,0 +1,179 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { +using namespace rex::system; + +void DbgBreakPoint_entry() { + rex::debug::Break(); +} + +// https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx +typedef struct { + rex::be type; + rex::be name_ptr; + rex::be thread_id; + rex::be flags; +} X_THREADNAME_INFO; +static_assert_size(X_THREADNAME_INFO, 0x10); + +void HandleSetThreadName(ppc_ptr_t record) { + // SetThreadName. FFS. + // https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx + + // TODO(benvanik): check record->number_parameters to make sure it's a + // correct size. + auto thread_info = reinterpret_cast(&record->exception_information[0]); + + assert_true(thread_info->type == 0x1000); + + if (!thread_info->name_ptr) { + REXKRNL_DEBUG("SetThreadName called with null name_ptr"); + return; + } + + // 4D5307D6 (and its demo) has a bug where it ends up passing freed memory for + // the name, so at the point of SetThreadName it's filled with junk. + + // TODO(gibbed): cvar for thread name encoding for conversion, some games use + // SJIS and there's no way to automatically know this. + auto name = + std::string(REX_KERNEL_MEMORY()->TranslateVirtual(thread_info->name_ptr)); + std::replace_if(name.begin(), name.end(), [](auto c) { return c < 32 || c > 127; }, '?'); + + object_ref thread; + if (thread_info->thread_id == -1) { + // Current thread. + thread = retain_object(XThread::GetCurrentThread()); + } else { + // Lookup thread by ID. + thread = REX_KERNEL_STATE()->GetThreadByID(thread_info->thread_id); + } + + if (thread) { + REXKRNL_DEBUG("SetThreadName({}, {})", thread->thread_id(), name); + thread->set_name(name); + } + + // TODO(benvanik): unwinding required here? +} + +typedef struct { + rex::be mdisp; + rex::be pdisp; + rex::be vdisp; +} x_PMD; + +typedef struct { + rex::be properties; + rex::be type_ptr; + x_PMD this_displacement; + rex::be size_or_offset; + rex::be copy_function_ptr; +} x_s__CatchableType; + +typedef struct { + rex::be number_catchable_types; + rex::be catchable_type_ptrs[1]; +} x_s__CatchableTypeArray; + +typedef struct { + rex::be attributes; + rex::be unwind_ptr; + rex::be forward_compat_ptr; + rex::be catchable_type_array_ptr; +} x_s__ThrowInfo; + +void HandleCppException(ppc_ptr_t record) { + // C++ exception. + // https://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx + // http://www.drdobbs.com/visual-c-exception-handling-instrumentat/184416600 + // http://www.openrce.org/articles/full_view/21 + + assert_true(record->number_parameters == 3); + assert_true(record->exception_information[0] == 0x19930520); + + auto thrown_ptr = record->exception_information[1]; + auto thrown = REX_KERNEL_MEMORY()->TranslateVirtual(thrown_ptr); + auto vftable_ptr = *reinterpret_cast*>(thrown); + + auto throw_info_ptr = record->exception_information[2]; + auto throw_info = REX_KERNEL_MEMORY()->TranslateVirtual(throw_info_ptr); + auto catchable_types = REX_KERNEL_MEMORY()->TranslateVirtual( + throw_info->catchable_type_array_ptr); + + rex::debug::Break(); +} + +void RtlRaiseException_entry(ppc_ptr_t record) { + switch (record->code) { + case 0x406D1388: { + HandleSetThreadName(record); + return; + } + case 0xE06D7363: { + HandleCppException(record); + return; + } + } + + // TODO(benvanik): unwinding. + // This is going to suck. + rex::debug::Break(); +} + +void KeBugCheckEx_entry(u32 code, u32 param1, u32 param2, u32 param3, u32 param4) { + REXKRNL_DEBUG("*** STOP: 0x{:08X} (0x{:08X}, 0x{:08X}, 0x{:08X}, 0x{:08X})", code, param1, param2, + param3, param4); + fflush(stdout); + rex::debug::Break(); + assert_always(); +} + +void KeBugCheck_entry(u32 code) { + KeBugCheckEx_entry(code, 0, 0, 0, 0); +} + +} // namespace rex::kernel::xboxkrnl + +REX_EXPORT(__imp__DbgBreakPoint, rex::kernel::xboxkrnl::DbgBreakPoint_entry) +REX_EXPORT(__imp__RtlRaiseException, rex::kernel::xboxkrnl::RtlRaiseException_entry) +REX_EXPORT(__imp__KeBugCheckEx, rex::kernel::xboxkrnl::KeBugCheckEx_entry) +REX_EXPORT(__imp__KeBugCheck, rex::kernel::xboxkrnl::KeBugCheck_entry) + +REX_EXPORT_STUB(__imp__DbgBreakPointWithStatus); +REX_EXPORT_STUB(__imp__DbgPrompt); +REX_EXPORT_STUB(__imp__DbgLoadImageSymbols); +REX_EXPORT_STUB(__imp__DbgUnLoadImageSymbols); +REX_EXPORT_STUB(__imp__DmPrintData); + +REX_EXPORT_STUB(__imp__DumpGetRawDumpInfo); +REX_EXPORT_STUB(__imp__DumpRegisterDedicatedDataBlock); +REX_EXPORT_STUB(__imp__DumpSetCollectionFacility); +REX_EXPORT_STUB(__imp__DumpUpdateDumpSettings); +REX_EXPORT_STUB(__imp__DumpWriteDump); +REX_EXPORT_STUB(__imp__DumpXitThread); +REX_EXPORT_STUB(__imp__RtlAssert); +REX_EXPORT_STUB(__imp__RtlRaiseStatus); +REX_EXPORT_STUB(__imp__RtlRip); diff --git a/src/kernel/xboxkrnl/xboxkrnl_error.cpp b/src/kernel/xboxkrnl/xboxkrnl_error.cpp new file mode 100644 index 0000000..e772bfd --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_error.cpp @@ -0,0 +1,1025 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { + +struct error_lookup_table { + uint32_t base_code; + size_t count; + const uint32_t* entries; +}; + +// TODO(gibbed): replace these with named error codes +const uint32_t error_table_0x00000103[] = { + 0x000003E5, // 0x00000103 + 0, // + 0x000000EA, // 0x00000105 + 0x00000514, // 0x00000106 + 0x00000515, // 0x00000107 + 0, // + 0, // + 0, // + 0, // + 0x000003FE, // 0x0000010C + 0x00000516, // 0x0000010D +}; + +const uint32_t error_table_0x40000002[] = { + 0x00000057, // 0x40000002 + 0, // + 0, // + 0, // + 0x00000517, // 0x40000006 + 0, // + 0x00000460, // 0x40000008 + 0x000003F6, // 0x40000009 + 0, // + 0, // + 0x00000461, // 0x4000000C + 0x00000518, // 0x4000000D +}; + +const uint32_t error_table_0x40020056[] = { + 0x00000720, // 0x40020056 +}; + +const uint32_t error_table_0x400200AF[] = { + 0x00000779, // 0x400200AF +}; + +const uint32_t error_table_0x80000001[] = { + 0x80000001, // 0x80000001 + 0x000003E6, // 0x80000002 + 0x80000003, // 0x80000003 + 0x80000004, // 0x80000004 + 0x000000EA, // 0x80000005 + 0x00000012, // 0x80000006 + 0, // + 0, // + 0, // + 0, // + 0x0000056F, // 0x8000000B + 0, // + 0x0000012B, // 0x8000000D + 0x0000001C, // 0x8000000E + 0x00000015, // 0x8000000F + 0x00000015, // 0x80000010 + 0x000000AA, // 0x80000011 + 0x00000103, // 0x80000012 + 0x000000FE, // 0x80000013 + 0x000000FF, // 0x80000014 + 0x000000FF, // 0x80000015 + 0x00000456, // 0x80000016 + 0, // + 0, // + 0, // + 0x00000103, // 0x8000001A + 0x0000044D, // 0x8000001B + 0x00000456, // 0x8000001C + 0x00000457, // 0x8000001D + 0x0000044C, // 0x8000001E + 0x0000044E, // 0x8000001F + 0, // + 0x0000044F, // 0x80000021 + 0x00000450, // 0x80000022 + 0, // + 0, // + 0x00000962, // 0x80000025 +}; + +const uint32_t error_table_0x80000288[] = { + 0x0000048D, // 0x80000288 + 0x0000048E, // 0x80000289 +}; + +const uint32_t error_table_0x80090300[] = { + 0x000005AA, // 0x80090300 + 0x00000006, // 0x80090301 + 0x00000001, // 0x80090302 + 0x00000035, // 0x80090303 + 0x0000054F, // 0x80090304 + 0x00000554, // 0x80090305 + 0x00000120, // 0x80090306 + 0x00000554, // 0x80090307 + 0x00000057, // 0x80090308 + 0x00000057, // 0x80090309 + 0x00000032, // 0x8009030A + 0x00000558, // 0x8009030B + 0x0000052E, // 0x8009030C + 0x00000057, // 0x8009030D + 0x00000520, // 0x8009030E + 0x00000005, // 0x8009030F + 0x00000005, // 0x80090310 + 0x0000051F, // 0x80090311 + 0, // + 0, // + 0, // + 0, // + 0x00000554, // 0x80090316 + 0, // + 0x000006F8, // 0x80090318 + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0x00000057, // 0x80090320 + 0x0000007A, // 0x80090321 + 0x00000574, // 0x80090322 + 0, // + 0, // + 0x000006FE, // 0x80090325 + 0x00000057, // 0x80090326 + 0x00000057, // 0x80090327 + 0x00000532, // 0x80090328 + 0x00001770, // 0x80090329 + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0x00001771, // 0x80090330 + 0x00000001, // 0x80090331 +}; + +const uint32_t error_table_0xC0000001[] = { + 0x0000001F, // 0xC0000001 + 0x00000001, // 0xC0000002 + 0x00000057, // 0xC0000003 + 0x00000018, // 0xC0000004 + 0x000003E6, // 0xC0000005 + 0x000003E7, // 0xC0000006 + 0x000005AE, // 0xC0000007 + 0x00000006, // 0xC0000008 + 0x000003E9, // 0xC0000009 + 0x000000C1, // 0xC000000A + 0x00000057, // 0xC000000B + 0, // + 0x00000057, // 0xC000000D + 0x00000002, // 0xC000000E + 0x00000002, // 0xC000000F + 0x00000001, // 0xC0000010 + 0x00000026, // 0xC0000011 + 0x00000022, // 0xC0000012 + 0x00000015, // 0xC0000013 + 0x000006F9, // 0xC0000014 + 0x0000001B, // 0xC0000015 + 0x000000EA, // 0xC0000016 + 0x00000008, // 0xC0000017 + 0x000001E7, // 0xC0000018 + 0x000001E7, // 0xC0000019 + 0x00000057, // 0xC000001A + 0x00000057, // 0xC000001B + 0x00000001, // 0xC000001C + 0xC000001D, // 0xC000001D + 0x00000005, // 0xC000001E + 0x00000005, // 0xC000001F + 0x000000C1, // 0xC0000020 + 0x00000005, // 0xC0000021 + 0x00000005, // 0xC0000022 + 0x0000007A, // 0xC0000023 + 0x00000006, // 0xC0000024 + 0xC0000025, // 0xC0000025 + 0xC0000026, // 0xC0000026 + 0, // + 0, // + 0, // + 0x0000009E, // 0xC000002A + 0xC000002B, // 0xC000002B + 0x000001E7, // 0xC000002C + 0x000001E7, // 0xC000002D + 0, // + 0, // + 0x00000057, // 0xC0000030 + 0, // + 0x00000571, // 0xC0000032 + 0x0000007B, // 0xC0000033 + 0x00000002, // 0xC0000034 + 0x000000B7, // 0xC0000035 + 0, // + 0x00000006, // 0xC0000037 + 0, // + 0x000000A1, // 0xC0000039 + 0x00000003, // 0xC000003A + 0x000000A1, // 0xC000003B + 0x0000045D, // 0xC000003C + 0x0000045D, // 0xC000003D + 0x00000017, // 0xC000003E + 0x00000017, // 0xC000003F + 0x00000008, // 0xC0000040 + 0x00000005, // 0xC0000041 + 0x00000006, // 0xC0000042 + 0x00000020, // 0xC0000043 + 0x00000718, // 0xC0000044 + 0x00000057, // 0xC0000045 + 0x00000120, // 0xC0000046 + 0x0000012A, // 0xC0000047 + 0x00000057, // 0xC0000048 + 0x00000057, // 0xC0000049 + 0x0000009C, // 0xC000004A + 0x00000005, // 0xC000004B + 0x00000057, // 0xC000004C + 0x00000057, // 0xC000004D + 0x00000057, // 0xC000004E + 0x0000011A, // 0xC000004F + 0x000000FF, // 0xC0000050 + 0x00000570, // 0xC0000051 + 0x00000570, // 0xC0000052 + 0x00000570, // 0xC0000053 + 0x00000021, // 0xC0000054 + 0x00000021, // 0xC0000055 + 0x00000005, // 0xC0000056 + 0x00000032, // 0xC0000057 + 0x00000519, // 0xC0000058 + 0x0000051A, // 0xC0000059 + 0x0000051B, // 0xC000005A + 0x0000051C, // 0xC000005B + 0x0000051D, // 0xC000005C + 0x0000051E, // 0xC000005D + 0x0000051F, // 0xC000005E + 0x00000520, // 0xC000005F + 0x00000521, // 0xC0000060 + 0x00000522, // 0xC0000061 + 0x00000523, // 0xC0000062 + 0x00000524, // 0xC0000063 + 0x00000525, // 0xC0000064 + 0x00000526, // 0xC0000065 + 0x00000527, // 0xC0000066 + 0x00000528, // 0xC0000067 + 0x00000529, // 0xC0000068 + 0x0000052A, // 0xC0000069 + 0x00000056, // 0xC000006A + 0x0000052C, // 0xC000006B + 0x0000052D, // 0xC000006C + 0x0000052E, // 0xC000006D + 0x0000052F, // 0xC000006E + 0x00000530, // 0xC000006F + 0x00000531, // 0xC0000070 + 0x00000532, // 0xC0000071 + 0x00000533, // 0xC0000072 + 0x00000534, // 0xC0000073 + 0x00000535, // 0xC0000074 + 0x00000536, // 0xC0000075 + 0x00000537, // 0xC0000076 + 0x00000538, // 0xC0000077 + 0x00000539, // 0xC0000078 + 0x0000053A, // 0xC0000079 + 0x0000007F, // 0xC000007A + 0x000000C1, // 0xC000007B + 0x000003F0, // 0xC000007C + 0x0000053C, // 0xC000007D + 0x0000009E, // 0xC000007E + 0x00000070, // 0xC000007F + 0x0000053D, // 0xC0000080 + 0x0000053E, // 0xC0000081 + 0x00000044, // 0xC0000082 + 0x00000103, // 0xC0000083 + 0x0000053F, // 0xC0000084 + 0x00000103, // 0xC0000085 + 0x0000009A, // 0xC0000086 + 0x0000000E, // 0xC0000087 + 0x000001E7, // 0xC0000088 + 0x00000714, // 0xC0000089 + 0x00000715, // 0xC000008A + 0x00000716, // 0xC000008B + 0xC000008C, // 0xC000008C + 0xC000008D, // 0xC000008D + 0xC000008E, // 0xC000008E + 0xC000008F, // 0xC000008F + 0xC0000090, // 0xC0000090 + 0xC0000091, // 0xC0000091 + 0xC0000092, // 0xC0000092 + 0xC0000093, // 0xC0000093 + 0xC0000094, // 0xC0000094 + 0x00000216, // 0xC0000095 + 0xC0000096, // 0xC0000096 + 0x00000008, // 0xC0000097 + 0x000003EE, // 0xC0000098 + 0x00000540, // 0xC0000099 + 0x000005AA, // 0xC000009A + 0x00000003, // 0xC000009B + 0x00000017, // 0xC000009C + 0x0000048F, // 0xC000009D + 0x00000015, // 0xC000009E + 0x000001E7, // 0xC000009F + 0x000001E7, // 0xC00000A0 + 0x000005AD, // 0xC00000A1 + 0x00000013, // 0xC00000A2 + 0x00000015, // 0xC00000A3 + 0x00000541, // 0xC00000A4 + 0x00000542, // 0xC00000A5 + 0x00000543, // 0xC00000A6 + 0x00000544, // 0xC00000A7 + 0x00000545, // 0xC00000A8 + 0x00000057, // 0xC00000A9 + 0, // + 0x000000E7, // 0xC00000AB + 0x000000E7, // 0xC00000AC + 0x000000E6, // 0xC00000AD + 0x000000E7, // 0xC00000AE + 0x00000001, // 0xC00000AF + 0x000000E9, // 0xC00000B0 + 0x000000E8, // 0xC00000B1 + 0x00000217, // 0xC00000B2 + 0x00000218, // 0xC00000B3 + 0x000000E6, // 0xC00000B4 + 0x00000079, // 0xC00000B5 + 0x00000026, // 0xC00000B6 + 0, // + 0, // + 0, // + 0x00000005, // 0xC00000BA + 0x00000032, // 0xC00000BB + 0x00000033, // 0xC00000BC + 0x00000034, // 0xC00000BD + 0x00000035, // 0xC00000BE + 0x00000036, // 0xC00000BF + 0x00000037, // 0xC00000C0 + 0x00000038, // 0xC00000C1 + 0x00000039, // 0xC00000C2 + 0x0000003A, // 0xC00000C3 + 0x0000003B, // 0xC00000C4 + 0x0000003C, // 0xC00000C5 + 0x0000003D, // 0xC00000C6 + 0x0000003E, // 0xC00000C7 + 0x0000003F, // 0xC00000C8 + 0x00000040, // 0xC00000C9 + 0x00000041, // 0xC00000CA + 0x00000042, // 0xC00000CB + 0x00000043, // 0xC00000CC + 0x00000044, // 0xC00000CD + 0x00000045, // 0xC00000CE + 0x00000046, // 0xC00000CF + 0x00000047, // 0xC00000D0 + 0x00000048, // 0xC00000D1 + 0x00000058, // 0xC00000D2 + 0, // + 0x00000011, // 0xC00000D4 + 0x00000005, // 0xC00000D5 + 0x000000F0, // 0xC00000D6 + 0x00000546, // 0xC00000D7 + 0, // + 0x000000E8, // 0xC00000D9 + 0x00000547, // 0xC00000DA + 0, // + 0x00000548, // 0xC00000DC + 0x00000549, // 0xC00000DD + 0x0000054A, // 0xC00000DE + 0x0000054B, // 0xC00000DF + 0x0000054C, // 0xC00000E0 + 0x0000054D, // 0xC00000E1 + 0x0000012C, // 0xC00000E2 + 0x0000012D, // 0xC00000E3 + 0x0000054E, // 0xC00000E4 + 0x0000054F, // 0xC00000E5 + 0x00000550, // 0xC00000E6 + 0x00000551, // 0xC00000E7 + 0x000006F8, // 0xC00000E8 + 0, // + 0, // + 0, // + 0, // + 0x00000552, // 0xC00000ED + 0x00000553, // 0xC00000EE + 0x00000057, // 0xC00000EF + 0x00000057, // 0xC00000F0 + 0x00000057, // 0xC00000F1 + 0x00000057, // 0xC00000F2 + 0x00000057, // 0xC00000F3 + 0x00000057, // 0xC00000F4 + 0x00000057, // 0xC00000F5 + 0x00000057, // 0xC00000F6 + 0x00000057, // 0xC00000F7 + 0x00000057, // 0xC00000F8 + 0x00000057, // 0xC00000F9 + 0x00000057, // 0xC00000FA + 0x00000003, // 0xC00000FB + 0, // + 0x000003E9, // 0xC00000FD + 0x00000554, // 0xC00000FE + 0, // + 0x000000CB, // 0xC0000100 + 0x00000091, // 0xC0000101 + 0x00000570, // 0xC0000102 + 0x0000010B, // 0xC0000103 + 0x00000555, // 0xC0000104 + 0x00000556, // 0xC0000105 + 0x000000CE, // 0xC0000106 + 0x00000961, // 0xC0000107 + 0x00000964, // 0xC0000108 + 0x0000013D, // 0xC0000109 + 0x00000005, // 0xC000010A + 0x00000557, // 0xC000010B + 0, // + 0x00000558, // 0xC000010D + 0x00000420, // 0xC000010E + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0x000005A4, // 0xC0000117 + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0x000003EE, // 0xC000011E + 0x00000004, // 0xC000011F + 0x000003E3, // 0xC0000120 + 0x00000005, // 0xC0000121 + 0x000004BA, // 0xC0000122 + 0x00000005, // 0xC0000123 + 0x0000055B, // 0xC0000124 + 0x0000055C, // 0xC0000125 + 0x0000055D, // 0xC0000126 + 0x0000055E, // 0xC0000127 + 0x00000006, // 0xC0000128 + 0, // + 0, // + 0x0000055F, // 0xC000012B + 0, // + 0x000005AF, // 0xC000012D + 0, // + 0, // + 0x000000C1, // 0xC0000130 + 0, // + 0, // + 0x00000576, // 0xC0000133 + 0, // + 0x0000007E, // 0xC0000135 + 0, // + 0, // + 0x000000B6, // 0xC0000138 + 0x0000007F, // 0xC0000139 + 0, // + 0x00000040, // 0xC000013B + 0x00000040, // 0xC000013C + 0x00000033, // 0xC000013D + 0x0000003B, // 0xC000013E + 0x0000003B, // 0xC000013F + 0x0000003B, // 0xC0000140 + 0x0000003B, // 0xC0000141 + 0x0000045A, // 0xC0000142 + 0, // + 0, // + 0, // + 0, // + 0, // + 0x0000007C, // 0xC0000148 + 0x00000056, // 0xC0000149 + 0, // + 0x0000006D, // 0xC000014B + 0x000003F1, // 0xC000014C + 0x000003F8, // 0xC000014D + 0, // + 0x000003ED, // 0xC000014F + 0x0000045E, // 0xC0000150 + 0x00000560, // 0xC0000151 + 0x00000561, // 0xC0000152 + 0x00000562, // 0xC0000153 + 0x00000563, // 0xC0000154 + 0x00000564, // 0xC0000155 + 0x00000565, // 0xC0000156 + 0x00000566, // 0xC0000157 + 0x00000567, // 0xC0000158 + 0x000003EF, // 0xC0000159 + 0x00000568, // 0xC000015A + 0x00000569, // 0xC000015B + 0x000003F9, // 0xC000015C + 0x0000056A, // 0xC000015D + 0, // + 0, // + 0, // + 0, // + 0x00000459, // 0xC0000162 + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0x00000466, // 0xC0000169 + 0x00000467, // 0xC000016A + 0x00000468, // 0xC000016B + 0x0000045F, // 0xC000016C + 0, // + 0, // + 0, // + 0, // + 0, // + 0x00000451, // 0xC0000172 + 0x00000452, // 0xC0000173 + 0x00000453, // 0xC0000174 + 0x00000454, // 0xC0000175 + 0x00000455, // 0xC0000176 + 0x00000469, // 0xC0000177 + 0x00000458, // 0xC0000178 + 0, // + 0x0000056B, // 0xC000017A + 0x0000056C, // 0xC000017B + 0x000003FA, // 0xC000017C + 0x000003FB, // 0xC000017D + 0x0000056D, // 0xC000017E + 0x0000056E, // 0xC000017F + 0x000003FC, // 0xC0000180 + 0x000003FD, // 0xC0000181 + 0x00000057, // 0xC0000182 + 0x0000045D, // 0xC0000183 + 0x00000016, // 0xC0000184 + 0x0000045D, // 0xC0000185 + 0x0000045D, // 0xC0000186 + 0, // + 0x000005DE, // 0xC0000188 + 0x00000013, // 0xC0000189 + 0x000006FA, // 0xC000018A + 0x000006FB, // 0xC000018B + 0x000006FC, // 0xC000018C + 0x000006FD, // 0xC000018D + 0x000005DC, // 0xC000018E + 0x000005DD, // 0xC000018F + 0x000006FE, // 0xC0000190 + 0, // + 0x00000700, // 0xC0000192 + 0x00000701, // 0xC0000193 + 0x0000046B, // 0xC0000194 + 0x000004C3, // 0xC0000195 + 0x000004C4, // 0xC0000196 + 0x000005DF, // 0xC0000197 + 0x0000070F, // 0xC0000198 + 0x00000710, // 0xC0000199 + 0x00000711, // 0xC000019A + 0x00000712, // 0xC000019B +}; + +const uint32_t error_table_0xC0000202[] = { + 0x00000572, // 0xC0000202 + 0x0000003B, // 0xC0000203 + 0x00000717, // 0xC0000204 + 0x0000046A, // 0xC0000205 + 0x000006F8, // 0xC0000206 + 0x000004BE, // 0xC0000207 + 0x000004BE, // 0xC0000208 + 0x00000044, // 0xC0000209 + 0x00000034, // 0xC000020A + 0x00000040, // 0xC000020B + 0x00000040, // 0xC000020C + 0x00000040, // 0xC000020D + 0x00000044, // 0xC000020E + 0x0000003B, // 0xC000020F + 0x0000003B, // 0xC0000210 + 0x0000003B, // 0xC0000211 + 0x0000003B, // 0xC0000212 + 0x0000003B, // 0xC0000213 + 0x0000003B, // 0xC0000214 + 0x0000003B, // 0xC0000215 + 0x00000032, // 0xC0000216 + 0x00000032, // 0xC0000217 + 0, // + 0, // + 0, // + 0, // + 0x000017E6, // 0xC000021C + 0, // + 0, // + 0, // + 0x0000046C, // 0xC0000220 + 0x000000C1, // 0xC0000221 + 0, // + 0, // + 0x00000773, // 0xC0000224 + 0x00000490, // 0xC0000225 + 0, // + 0, // + 0, // + 0, // + 0xC000022A, // 0xC000022A + 0xC000022B, // 0xC000022B + 0, // + 0x000004D5, // 0xC000022D + 0, // + 0, // + 0x00000492, // 0xC0000230 + 0, // + 0, // + 0x00000774, // 0xC0000233 + 0x00000775, // 0xC0000234 + 0x00000006, // 0xC0000235 + 0x000004C9, // 0xC0000236 + 0x000004CA, // 0xC0000237 + 0x000004CB, // 0xC0000238 + 0x000004CC, // 0xC0000239 + 0x000004CD, // 0xC000023A + 0x000004CE, // 0xC000023B + 0x000004CF, // 0xC000023C + 0x000004D0, // 0xC000023D + 0x000004D1, // 0xC000023E + 0x000004D2, // 0xC000023F + 0x000004D3, // 0xC0000240 + 0x000004D4, // 0xC0000241 + 0, // + 0x000004C8, // 0xC0000243 + 0, // + 0, // + 0x000004D6, // 0xC0000246 + 0x000004D7, // 0xC0000247 + 0x000004D8, // 0xC0000248 + 0x000000C1, // 0xC0000249 + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0x0000054F, // 0xC0000253 + 0, // + 0, // + 0, // + 0x000004D0, // 0xC0000257 + 0, // + 0x00000573, // 0xC0000259 + 0, // + 0, // + 0, // + 0, // + 0x00000422, // 0xC000025E + 0, // + 0, // + 0, // + 0x000000B6, // 0xC0000262 + 0x0000007F, // 0xC0000263 + 0x00000120, // 0xC0000264 + 0x00000476, // 0xC0000265 + 0, // + 0x000010FE, // 0xC0000267 + 0, // + 0, // + 0, // + 0, // + 0x000007D1, // 0xC000026C + 0x000004B1, // 0xC000026D + 0x00000015, // 0xC000026E + 0, // + 0, // + 0, // + 0x00000491, // 0xC0000272 + 0, // + 0, // + 0x00001126, // 0xC0000275 + 0x00001129, // 0xC0000276 + 0x0000112A, // 0xC0000277 + 0x00001128, // 0xC0000278 + 0x00000780, // 0xC0000279 + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0x00000781, // 0xC0000280 + 0x000000A1, // 0xC0000281 + 0, // + 0x00000488, // 0xC0000283 + 0x00000489, // 0xC0000284 + 0x0000048A, // 0xC0000285 + 0x0000048B, // 0xC0000286 + 0x0000048C, // 0xC0000287 + 0, // + 0, // + 0x00000005, // 0xC000028A + 0x00000005, // 0xC000028B + 0, // + 0x00000005, // 0xC000028D + 0x00000005, // 0xC000028E + 0x00000005, // 0xC000028F + 0x00000005, // 0xC0000290 + 0x00001777, // 0xC0000291 + 0x00001778, // 0xC0000292 + 0x00001772, // 0xC0000293 + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0x00000001, // 0xC000029C + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0x00001127, // 0xC00002B2 + 0, // + 0, // + 0, // + 0x00000651, // 0xC00002B6 + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0x00000575, // 0xC00002C3 + 0, // + 0x000003E6, // 0xC00002C5 + 0, // + 0, // + 0, // + 0, // + 0x000010E8, // 0xC00002CA + 0, // + 0x000004E3, // 0xC00002CC + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0x00000052, // 0xC00002EA +}; + +const uint32_t error_table_0xC0020001[] = { + 0x000006A4, // 0xC0020001 + 0x000006A5, // 0xC0020002 + 0x00000006, // 0xC0020003 + 0x000006A7, // 0xC0020004 + 0x000006A8, // 0xC0020005 + 0x000006A9, // 0xC0020006 + 0x000006AA, // 0xC0020007 + 0x000006AB, // 0xC0020008 + 0x000006AC, // 0xC0020009 + 0x000006AD, // 0xC002000A + 0x000006AE, // 0xC002000B + 0x000006AF, // 0xC002000C + 0x000006B0, // 0xC002000D + 0x000006B1, // 0xC002000E + 0x000006B2, // 0xC002000F + 0x000006B3, // 0xC0020010 + 0x000006B4, // 0xC0020011 + 0x000006B5, // 0xC0020012 + 0x000006B6, // 0xC0020013 + 0x000006B7, // 0xC0020014 + 0x000006B8, // 0xC0020015 + 0x000006B9, // 0xC0020016 + 0x000006BA, // 0xC0020017 + 0x000006BB, // 0xC0020018 + 0x000006BC, // 0xC0020019 + 0x000006BD, // 0xC002001A + 0x000006BE, // 0xC002001B + 0x000006BF, // 0xC002001C + 0x000006C0, // 0xC002001D + 0, // + 0x000006C2, // 0xC002001F + 0, // + 0x000006C4, // 0xC0020021 + 0x000006C5, // 0xC0020022 + 0x000006C6, // 0xC0020023 + 0x000006C7, // 0xC0020024 + 0x000006C8, // 0xC0020025 + 0x000006C9, // 0xC0020026 + 0, // + 0x000006CB, // 0xC0020028 + 0x000006CC, // 0xC0020029 + 0x000006CD, // 0xC002002A + 0x000006CE, // 0xC002002B + 0x000006CF, // 0xC002002C + 0x000006D0, // 0xC002002D + 0x000006D1, // 0xC002002E + 0x000006D2, // 0xC002002F + 0x000006D3, // 0xC0020030 + 0x000006D4, // 0xC0020031 + 0x000006D5, // 0xC0020032 + 0x000006D6, // 0xC0020033 + 0x000006D7, // 0xC0020034 + 0x000006D8, // 0xC0020035 + 0x000006D9, // 0xC0020036 + 0x000006DA, // 0xC0020037 + 0x000006DB, // 0xC0020038 + 0x000006DC, // 0xC0020039 + 0x000006DD, // 0xC002003A + 0x000006DE, // 0xC002003B + 0x000006DF, // 0xC002003C + 0x000006E0, // 0xC002003D + 0x000006E1, // 0xC002003E + 0x000006E2, // 0xC002003F + 0x000006E3, // 0xC0020040 + 0x000006E4, // 0xC0020041 + 0x000006E5, // 0xC0020042 + 0x000006E6, // 0xC0020043 + 0x000006E7, // 0xC0020044 + 0x000006E8, // 0xC0020045 + 0x000006E9, // 0xC0020046 + 0x000006EA, // 0xC0020047 + 0x000006EB, // 0xC0020048 + 0x000006FF, // 0xC0020049 + 0x0000070E, // 0xC002004A + 0x0000076A, // 0xC002004B + 0x0000076B, // 0xC002004C + 0x0000076C, // 0xC002004D + 0, // + 0x00000719, // 0xC002004F + 0x0000071A, // 0xC0020050 + 0x0000071B, // 0xC0020051 + 0x0000071C, // 0xC0020052 + 0x0000071D, // 0xC0020053 + 0x0000071E, // 0xC0020054 + 0x0000071F, // 0xC0020055 + 0, // + 0x00000721, // 0xC0020057 + 0x00000722, // 0xC0020058 + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0, // + 0x0000077A, // 0xC0020062 + 0x0000077B, // 0xC0020063 +}; + +const uint32_t error_table_0xC0030001[] = { + 0x000006EC, // 0xC0030001 + 0x000006ED, // 0xC0030002 + 0x000006EE, // 0xC0030003 + 0x00000006, // 0xC0030004 + 0x00000006, // 0xC0030005 + 0x000006F1, // 0xC0030006 + 0x000006F2, // 0xC0030007 + 0x000006F3, // 0xC0030008 + 0x000006F4, // 0xC0030009 + 0x000006F5, // 0xC003000A + 0x000006F6, // 0xC003000B + 0x000006F7, // 0xC003000C +}; + +const uint32_t error_table_0xC0030059[] = { + 0x00000723, // 0xC0030059 + 0x00000724, // 0xC003005A + 0x00000725, // 0xC003005B + 0x00000726, // 0xC003005C + 0, // + 0x00000728, // 0xC003005E + 0x0000077C, // 0xC003005F + 0x0000077D, // 0xC0030060 + 0x0000077E, // 0xC0030061 +}; + +const uint32_t error_table_0xC0050003[] = { + 0x0000045D, // 0xC0050003 + 0x00000456, // 0xC0050004 +}; + +const uint32_t error_table_0xC0980001[] = { + 0x00000037, // 0xC0980001 + 0x00000037, // 0xC0980002 + 0, // + 0, // + 0, // + 0, // + 0, // + 0x00000037, // 0xC0980008 +}; + +#define MAKE_ENTRY(x) {x, rex::countof(error_table_##x), error_table_##x} +const error_lookup_table error_tables[] = { + MAKE_ENTRY(0x00000103), MAKE_ENTRY(0x40000002), MAKE_ENTRY(0x40020056), MAKE_ENTRY(0x400200AF), + MAKE_ENTRY(0x80000001), MAKE_ENTRY(0x80000288), MAKE_ENTRY(0x80090300), MAKE_ENTRY(0xC0000001), + MAKE_ENTRY(0xC0000202), MAKE_ENTRY(0xC0020001), MAKE_ENTRY(0xC0030001), MAKE_ENTRY(0xC0030059), + MAKE_ENTRY(0xC0050003), MAKE_ENTRY(0xC0980001), {0, 0, nullptr}, +}; +#undef MAKE_ENTRY + +uint32_t xeRtlNtStatusToDosError(uint32_t source_status) { + uint32_t status = source_status; + if (!status || (status & 0x20000000)) { + return status; + } + + if ((status >> 16) == 0x8007) { + return status & 0xFFFF; + } + + if ((status & 0xF0000000) == 0xD0000000) { + // High bits doesn't matter. + status &= ~0x30000000; + } + + auto error_table = &error_tables[0]; + while (error_table->base_code) { + if (status < error_table->base_code) { + break; + } + auto index = status - error_table->base_code; + if (index < error_table->count) { + uint32_t result = error_table->entries[index]; + if (!result) { + break; + } + REXKRNL_IMPORT_TRACE("xeRtlNtStatusToDosError", "status=0x{:X} => 0x{:X}", status, result); + return result; + } + ++error_table; + } + + if ((status >> 16) == 0xC001) { + return status & 0xFFFF; + } + + REXKRNL_IMPORT_TRACE("xeRtlNtStatusToDosError", "lookup failed for 0x{:X}", status); + return 317; // ERROR_MR_MID_NOT_FOUND +} + +u32 RtlNtStatusToDosError_entry(u32 source_status) { + uint32_t result = xeRtlNtStatusToDosError(source_status); + REXKRNL_IMPORT_TRACE("RtlNtStatusToDosError", "status={:#x} -> {}", source_status, result); + return result; +} + +} // namespace rex::kernel::xboxkrnl + +REX_EXPORT(__imp__RtlNtStatusToDosError, rex::kernel::xboxkrnl::RtlNtStatusToDosError_entry) diff --git a/src/kernel/xboxkrnl/xboxkrnl_hal.cpp b/src/kernel/xboxkrnl/xboxkrnl_hal.cpp new file mode 100644 index 0000000..2575f9d --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_hal.cpp @@ -0,0 +1,66 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include +#include +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { + +void HalReturnToFirmware_entry(u32 routine) { + // void + // IN FIRMWARE_REENTRY Routine + + // Routine must be 1 'HalRebootRoutine' + assert_true(routine == 1); + + // TODO(benvank): diediedie much more gracefully + // Not sure how to blast back up the stack in LLVM without exceptions, though. + REXKRNL_ERROR("Game requested shutdown via HalReturnToFirmware"); + exit(0); +} + +} // namespace rex::kernel::xboxkrnl + +REX_EXPORT(__imp__HalReturnToFirmware, rex::kernel::xboxkrnl::HalReturnToFirmware_entry) + +REX_EXPORT_STUB(__imp__HalGetCurrentAVPack); +REX_EXPORT_STUB(__imp__HalGpioControl); +REX_EXPORT_STUB(__imp__HalOpenCloseODDTray); +REX_EXPORT_STUB(__imp__HalReadWritePCISpace); +REX_EXPORT_STUB(__imp__HalRegisterPowerDownNotification); +REX_EXPORT_STUB(__imp__HalRegisterSMCNotification); +REX_EXPORT_STUB(__imp__HalSendSMCMessage); +REX_EXPORT_STUB(__imp__HalSetAudioEnable); +REX_EXPORT_STUB(__imp__HalIsExecutingPowerDownDpc); +REX_EXPORT_STUB(__imp__HalGetPowerUpCause); +REX_EXPORT_STUB(__imp__HalRegisterPowerDownCallback); +REX_EXPORT_STUB(__imp__HalRegisterBackgroundModeTransitionCallback); +REX_EXPORT_STUB(__imp__HalClampUnclampOutputDACs); +REX_EXPORT_STUB(__imp__HalPowerDownToBackgroundMode); +REX_EXPORT_STUB(__imp__HalNotifyAddRemoveBackgroundTask); +REX_EXPORT_STUB(__imp__HalCallBackgroundModeNotificationRoutines); +REX_EXPORT_STUB(__imp__HalGetMemoryInformation); +REX_EXPORT_STUB(__imp__HalNotifyBackgroundModeTransitionComplete); +REX_EXPORT_STUB(__imp__HalFinalizePowerLossRecovery); +REX_EXPORT_STUB(__imp__HalSetPowerLossRecovery); +REX_EXPORT_STUB(__imp__HalRegisterXamPowerDownCallback); +REX_EXPORT_STUB(__imp__HalRegisterHdDvdRomNotification); +REX_EXPORT_STUB(__imp__HalGetNotedArgonErrors); +REX_EXPORT_STUB(__imp__HalReadArgonEeprom); +REX_EXPORT_STUB(__imp__HalWriteArgonEeprom); +REX_EXPORT_STUB(__imp__HalConfigureVeDevice); diff --git a/src/kernel/xboxkrnl/xboxkrnl_hid.cpp b/src/kernel/xboxkrnl/xboxkrnl_hid.cpp new file mode 100644 index 0000000..b511f62 --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_hid.cpp @@ -0,0 +1,112 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include +#include +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { + +u32 HidReadKeys_entry(u32 unk1, u32 unk2, u32 unk3) { + /* TODO(gibbed): + * Games check for the following errors: + * 0xC000009D - translated to 0x48F - ERROR_DEVICE_NOT_CONNECTED + * 0x103 - translated to 0x10D2 - ERROR_EMPTY + * Other errors appear to be ignored? + * + * unk1 is 0 + * unk2 is a pointer to &unk3[2], possibly a 6-byte buffer + * unk3 is a pointer to a 20-byte buffer + */ + return 0xC000009D; +} + +u32 HidGetCapabilities_entry(u32 unk1, u32 caps_ptr) { + // HidGetCapabilities - ordinal 0x01EA + // Returns capabilities for HID device (keyboard/mouse) + // Not supported in rexglue - return unsuccessful + return X_STATUS_UNSUCCESSFUL; +} + +u32 HidGetLastInputTime_entry(mapped_u32 time_ptr) { + // HidGetLastInputTime - ordinal 0x01F1 + // Returns the last time any HID input was received + if (time_ptr) { + *time_ptr = 0; + } + return X_STATUS_SUCCESS; +} + +u32 HidReadMouseChanges_entry(u32 unk1, u32 unk2) { + // HidReadMouseChanges - ordinal 0x0273 + // Reads mouse input changes - not supported in rexglue + return X_STATUS_UNSUCCESSFUL; +} + +} // namespace rex::kernel::xboxkrnl + +REX_EXPORT(__imp__HidReadKeys, rex::kernel::xboxkrnl::HidReadKeys_entry) +REX_EXPORT(__imp__HidGetCapabilities, rex::kernel::xboxkrnl::HidGetCapabilities_entry) +REX_EXPORT(__imp__HidGetLastInputTime, rex::kernel::xboxkrnl::HidGetLastInputTime_entry) +REX_EXPORT(__imp__HidReadMouseChanges, rex::kernel::xboxkrnl::HidReadMouseChanges_entry) + +// XInputd stubs +REX_EXPORT_STUB(__imp__XInputdGetCapabilities); +REX_EXPORT_STUB(__imp__XInputdReadState); +REX_EXPORT_STUB(__imp__XInputdWriteState); +REX_EXPORT_STUB(__imp__XInputdNotify); +REX_EXPORT_STUB(__imp__XInputdRawState); +REX_EXPORT_STUB(__imp__XInputdGetDeviceStats); +REX_EXPORT_STUB(__imp__XInputdResetDevice); +REX_EXPORT_STUB(__imp__XInputdSetRingOfLight); +REX_EXPORT_STUB(__imp__XInputdSetRFPowerMode); +REX_EXPORT_STUB(__imp__XInputdSetRadioFrequency); +REX_EXPORT_STUB(__imp__XInputdPassThroughRFCommand); +REX_EXPORT_STUB(__imp__XInputdPowerDownDevice); +REX_EXPORT_STUB(__imp__XInputdReadTextKeystroke); +REX_EXPORT_STUB(__imp__XInputdSendStayAliveRequest); +REX_EXPORT_STUB(__imp__XInputdFFGetDeviceInfo); +REX_EXPORT_STUB(__imp__XInputdFFSetEffect); +REX_EXPORT_STUB(__imp__XInputdFFUpdateEffect); +REX_EXPORT_STUB(__imp__XInputdFFEffectOperation); +REX_EXPORT_STUB(__imp__XInputdFFDeviceControl); +REX_EXPORT_STUB(__imp__XInputdFFSetDeviceGain); +REX_EXPORT_STUB(__imp__XInputdFFCancelIo); +REX_EXPORT_STUB(__imp__XInputdFFSetRumble); +REX_EXPORT_STUB(__imp__XInputdGetLastTextInputTime); +REX_EXPORT_STUB(__imp__XInputdSetTextMessengerIndicator); +REX_EXPORT_STUB(__imp__XInputdSetTextDeviceKeyLocks); +REX_EXPORT_STUB(__imp__XInputdGetTextDeviceKeyLocks); +REX_EXPORT_STUB(__imp__XInputdControl); +REX_EXPORT_STUB(__imp__XInputdSetWifiChannel); +REX_EXPORT_STUB(__imp__XInputdGetDevicePid); +REX_EXPORT_STUB(__imp__XInputdGetFailedConnectionOrBind); +REX_EXPORT_STUB(__imp__XInputdSetFailedConnectionOrBindCallback); +REX_EXPORT_STUB(__imp__XInputdSetMinMaxAuthDelay); + +// Drv stubs +REX_EXPORT_STUB(__imp__DrvSetSysReqCallback); +REX_EXPORT_STUB(__imp__DrvSetUserBindingCallback); +REX_EXPORT_STUB(__imp__DrvSetContentStorageCallback); +REX_EXPORT_STUB(__imp__DrvSetAutobind); +REX_EXPORT_STUB(__imp__DrvGetContentStorageNotification); +REX_EXPORT_STUB(__imp__DrvXenonButtonPressed); +REX_EXPORT_STUB(__imp__DrvBindToUser); +REX_EXPORT_STUB(__imp__DrvSetDeviceConfigChangeCallback); +REX_EXPORT_STUB(__imp__DrvDeviceConfigChange); +REX_EXPORT_STUB(__imp__DrvSetMicArrayStartCallback); +REX_EXPORT_STUB(__imp__DrvSetAudioLatencyCallback); diff --git a/src/kernel/xboxkrnl/xboxkrnl_io.cpp b/src/kernel/xboxkrnl/xboxkrnl_io.cpp new file mode 100644 index 0000000..3f1a852 --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_io.cpp @@ -0,0 +1,820 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { +using namespace rex::system; + +struct CreateOptions { + // https://processhacker.sourceforge.io/doc/ntioapi_8h.html + static const uint32_t FILE_DIRECTORY_FILE = 0x00000001; + // Optimization - files access will be sequential, not random. + static const uint32_t FILE_SEQUENTIAL_ONLY = 0x00000004; + static const uint32_t FILE_SYNCHRONOUS_IO_ALERT = 0x00000010; + static const uint32_t FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020; + static const uint32_t FILE_NON_DIRECTORY_FILE = 0x00000040; + // Optimization - file access will be random, not sequential. + static const uint32_t FILE_RANDOM_ACCESS = 0x00000800; +}; + +static bool IsValidPath(const std::string_view s, bool is_pattern) { + // TODO(gibbed): validate path components individually + bool got_asterisk = false; + for (const auto& c : s) { + if (c <= 31 || c >= 127) { + return false; + } + if (got_asterisk) { + // * must be followed by a . (*.) + // + // 4D530819 has a bug in its game code where it attempts to + // FindFirstFile() with filters of "Game:\\*_X3.rkv", "Game:\\m*_X3.rkv", + // and "Game:\\w*_X3.rkv" and will infinite loop if the path filter is + // allowed. + if (c != '.') { + return false; + } + got_asterisk = false; + } + switch (c) { + case '"': + // case '*': + case '+': + case ',': + // case ':': + // case ';': + case '<': + // case '=': + case '>': + // case '?': + case '|': { + return false; + } + case '*': { + // Pattern-specific (for NtQueryDirectoryFile) + if (!is_pattern) { + return false; + } + got_asterisk = true; + break; + } + case '?': { + // Pattern-specific (for NtQueryDirectoryFile) + if (!is_pattern) { + return false; + } + break; + } + default: { + break; + } + } + } + return true; +} + +u32 NtCreateFile_entry(mapped_u32 handle_out, u32 desired_access, + ppc_ptr_t object_attrs, + ppc_ptr_t io_status_block, mapped_u64 allocation_size_ptr, + u32 file_attributes, u32 share_access, u32 creation_disposition, + u32 create_options) { + // note used. maybe later + // uint64_t allocation_size = 0; // is this correct??? + // if (allocation_size_ptr) { + // allocation_size = *allocation_size_ptr; + //} + + if (!object_attrs) { + // ..? Some games do this. This parameter is not optional. + return X_STATUS_INVALID_PARAMETER; + } + assert_not_null(handle_out); + + auto object_name = REX_KERNEL_MEMORY()->TranslateVirtual(object_attrs->name_ptr); + + rex::filesystem::Entry* root_entry = nullptr; + + // Compute path, possibly attrs relative. + auto target_path = util::TranslateAnsiPath(REX_KERNEL_MEMORY(), object_name); + REXKRNL_IMPORT_TRACE( + "NtCreateFile", "path={} access={:#x} attrs={:#x} share={:#x} disp={:#x} options={:#x}", + target_path, (uint32_t)desired_access, (uint32_t)file_attributes, (uint32_t)share_access, + (uint32_t)creation_disposition, (uint32_t)create_options); + + // Enforce that the path is ASCII. + if (!IsValidPath(target_path, false)) { + return X_STATUS_OBJECT_NAME_INVALID; + } + + if (object_attrs->root_directory != 0xFFFFFFFD && // ObDosDevices + object_attrs->root_directory != 0) { + auto root_file = REX_KERNEL_OBJECTS()->LookupObject(object_attrs->root_directory); + assert_not_null(root_file); + assert_true(root_file->type() == XObject::Type::File); + + root_entry = root_file->entry(); + } + + // Attempt open (or create). + rex::filesystem::File* vfs_file; + rex::filesystem::FileAction file_action; + X_STATUS result = REX_KERNEL_FS()->OpenFile( + root_entry, target_path, rex::filesystem::FileDisposition((uint32_t)creation_disposition), + desired_access, (create_options & CreateOptions::FILE_DIRECTORY_FILE) != 0, + (create_options & CreateOptions::FILE_NON_DIRECTORY_FILE) != 0, &vfs_file, &file_action); + object_ref file = nullptr; + + X_HANDLE handle = X_INVALID_HANDLE_VALUE; + if (XSUCCEEDED(result)) { + // If true, desired_access SYNCHRONIZE flag must be set. + bool synchronous = (create_options & CreateOptions::FILE_SYNCHRONOUS_IO_ALERT) || + (create_options & CreateOptions::FILE_SYNCHRONOUS_IO_NONALERT); + file = object_ref(new XFile(REX_KERNEL_STATE(), vfs_file, synchronous)); + + // Handle ref is incremented, so return that. + handle = file->handle(); + } + + if (io_status_block) { + io_status_block->status = result; + io_status_block->information = (uint32_t)file_action; + } + + *handle_out = handle; + if (XFAILED(result)) { + REXKRNL_IMPORT_FAIL("NtCreateFile", "path='{}' -> {:#x}", target_path, result); + } else { + REXKRNL_IMPORT_RESULT("NtCreateFile", "{:#x} handle={:#x}", result, handle); + } + return result; +} + +u32 NtOpenFile_entry(mapped_u32 handle_out, u32 desired_access, + ppc_ptr_t object_attributes, + ppc_ptr_t io_status_block, u32 open_options) { + return NtCreateFile_entry(handle_out, desired_access, object_attributes, io_status_block, nullptr, + 0, 0, static_cast(rex::filesystem::FileDisposition::kOpen), + open_options); +} + +u32 NtReadFile_entry(u32 file_handle, u32 event_handle, mapped_void apc_routine_ptr, + mapped_void apc_context, ppc_ptr_t io_status_block, + mapped_void buffer, u32 buffer_length, mapped_u64 byte_offset_ptr) { + uint64_t byte_offset = byte_offset_ptr ? static_cast(*byte_offset_ptr) : 0; + const bool apc_requested = (static_cast(apc_routine_ptr) & ~1u) != 0; + REXKRNL_IMPORT_TRACE( + "NtReadFile", + "handle={:#x} event={:#x} apc={:#x} apc_ctx={:#x} iosb={:#x} buf={:#x} len={:#x} offset={}", + (uint32_t)file_handle, (uint32_t)event_handle, apc_routine_ptr.guest_address(), + apc_context.guest_address(), io_status_block.guest_address(), buffer.guest_address(), + (uint32_t)buffer_length, byte_offset_ptr ? (int64_t)byte_offset : -1); + X_STATUS result = X_STATUS_SUCCESS; + bool apc_queued = false; + + bool signal_event = false; + auto ev = REX_KERNEL_OBJECTS()->LookupObject(event_handle); + if (event_handle && !ev) { + result = X_STATUS_INVALID_HANDLE; + } + + auto file = REX_KERNEL_OBJECTS()->LookupObject(file_handle); + if (!file) { + result = X_STATUS_INVALID_HANDLE; + } + + if (XSUCCEEDED(result)) { + if (true || file->is_synchronous()) { + // Synchronous. + uint32_t bytes_read = 0; + result = file->Read(buffer.guest_address(), buffer_length, + byte_offset_ptr ? static_cast(*byte_offset_ptr) : -1, + &bytes_read, apc_context.guest_address()); + if (io_status_block) { + io_status_block->status = result; + io_status_block->information = bytes_read; + } + + // Queue the APC callback. It must be delivered via the APC mechanism even + // though were are completing immediately. + // Low bit probably means do not queue to IO ports. + if ((uint32_t)apc_routine_ptr & ~1) { + if (apc_context && result == X_STATUS_SUCCESS) { + auto thread = XThread::GetCurrentThread(); + uint32_t apc_routine = static_cast(apc_routine_ptr) & ~1u; + uint32_t apc_ctx = apc_context.guest_address(); + uint32_t apc_arg1 = io_status_block.guest_address(); + REXKRNL_IMPORT_TRACE("NtReadFile", + "queue_apc thid={} normal={:#x} ctx={:#x} arg1={:#x} arg2=0", + thread ? thread->thread_id() : 0, apc_routine, apc_ctx, apc_arg1); + thread->EnqueueApc(apc_routine, apc_ctx, apc_arg1, 0); + apc_queued = true; + } else { + REXKRNL_IMPORT_TRACE("NtReadFile", "skip_apc_queue (apc_ctx={:#x}, status={:#x})", + apc_context.guest_address(), result); + } + } + + if (!file->is_synchronous() && result != X_STATUS_END_OF_FILE) { + result = X_STATUS_PENDING; + } + + // Mark that we should signal the event now. We do this after + // we have written the info out. + signal_event = true; + } else { + // TODO(benvanik): async. + + // X_STATUS_PENDING if not returning immediately. + // XFile is waitable and signalled after each async req completes. + // reset the input event (->Reset()) + /*xeNtReadFileState* call_state = new xeNtReadFileState(); + XAsyncRequest* request = new XAsyncRequest( + state, file, + (XAsyncRequest::CompletionCallback)xeNtReadFileCompleted, + call_state);*/ + // result = file->Read(buffer.guest_address(), buffer_length, byte_offset, + // request); + if (io_status_block) { + io_status_block->status = X_STATUS_PENDING; + io_status_block->information = 0; + } + + result = X_STATUS_PENDING; + } + } + + if (XFAILED(result) && io_status_block) { + io_status_block->status = result; + io_status_block->information = 0; + } + + if (ev && signal_event) { + ev->Set(0, false); + } + + // Log detailed completion info for debugging async IO issues + if (file) { + REXKRNL_IMPORT_RESULT( + "NtReadFile", + "{:#x} (sync={}, iosb_status={:#x}, iosb_info={}, ev_signaled={}, apc_requested={}, " + "apc_queued={})", + result, file->is_synchronous(), + io_status_block ? (uint32_t)io_status_block->status : 0xDEAD, + io_status_block ? (uint32_t)io_status_block->information : 0, ev && signal_event, + apc_requested, apc_queued); + } else { + REXKRNL_IMPORT_RESULT("NtReadFile", "{:#x} (apc_requested={}, apc_queued={})", result, + apc_requested, apc_queued); + } + return result; +} + +u32 NtReadFileScatter_entry(u32 file_handle, u32 event_handle, mapped_void apc_routine_ptr, + mapped_void apc_context, ppc_ptr_t io_status_block, + mapped_u32 segment_array, u32 length, mapped_u64 byte_offset_ptr) { + X_STATUS result = X_STATUS_SUCCESS; + + bool signal_event = false; + auto ev = REX_KERNEL_OBJECTS()->LookupObject(event_handle); + if (event_handle && !ev) { + result = X_STATUS_INVALID_HANDLE; + } + + auto file = REX_KERNEL_OBJECTS()->LookupObject(file_handle); + if (!file) { + result = X_STATUS_INVALID_HANDLE; + } + + if (XSUCCEEDED(result)) { + if (true || file->is_synchronous()) { + // Synchronous. + uint32_t bytes_read = 0; + result = file->ReadScatter(segment_array.guest_address(), length, + byte_offset_ptr ? static_cast(*byte_offset_ptr) : -1, + &bytes_read, apc_context.guest_address()); + if (io_status_block) { + io_status_block->status = result; + io_status_block->information = bytes_read; + } + + // Queue the APC callback. It must be delivered via the APC mechanism even + // though were are completing immediately. + // Low bit probably means do not queue to IO ports. + if ((uint32_t)apc_routine_ptr & ~1) { + if (apc_context) { + auto thread = XThread::GetCurrentThread(); + thread->EnqueueApc(static_cast(apc_routine_ptr) & ~1u, + apc_context.guest_address(), io_status_block.guest_address(), 0); + } + } + + if (!file->is_synchronous()) { + result = X_STATUS_PENDING; + } + + // Mark that we should signal the event now. We do this after + // we have written the info out. + signal_event = true; + } else { + // TODO(benvanik): async. + + // TODO: On Windows it might be worth trying to use Win32 ReadFileScatter + // here instead of handling it ourselves + + // X_STATUS_PENDING if not returning immediately. + // XFile is waitable and signalled after each async req completes. + // reset the input event (->Reset()) + /*xeNtReadFileState* call_state = new xeNtReadFileState(); + XAsyncRequest* request = new XAsyncRequest( + state, file, + (XAsyncRequest::CompletionCallback)xeNtReadFileCompleted, + call_state);*/ + // result = file->Read(buffer.guest_address(), buffer_length, byte_offset, + // request); + if (io_status_block) { + io_status_block->status = X_STATUS_PENDING; + io_status_block->information = 0; + } + + result = X_STATUS_PENDING; + } + } + + if (XFAILED(result) && io_status_block) { + io_status_block->status = result; + io_status_block->information = 0; + } + + if (ev && signal_event) { + ev->Set(0, false); + } + + return result; +} + +u32 NtWriteFile_entry(u32 file_handle, u32 event_handle, u32 apc_routine, mapped_void apc_context, + ppc_ptr_t io_status_block, mapped_void buffer, + u32 buffer_length, mapped_u64 byte_offset_ptr) { + X_STATUS result = X_STATUS_SUCCESS; + + // Grab event to signal. + bool signal_event = false; + auto ev = REX_KERNEL_OBJECTS()->LookupObject(event_handle); + if (event_handle && !ev) { + result = X_STATUS_INVALID_HANDLE; + } + + // Grab file. + auto file = REX_KERNEL_OBJECTS()->LookupObject(file_handle); + if (!file) { + result = X_STATUS_INVALID_HANDLE; + } + + // Execute write. + if (XSUCCEEDED(result)) { + // TODO(benvanik): async path. + if (true || file->is_synchronous()) { + // Synchronous request. + uint32_t bytes_written = 0; + result = file->Write(buffer.guest_address(), buffer_length, + byte_offset_ptr ? static_cast(*byte_offset_ptr) : -1, + &bytes_written, apc_context.guest_address()); + + if (io_status_block) { + io_status_block->status = result; + io_status_block->information = static_cast(bytes_written); + } + + // Queue the APC callback. It must be delivered via the APC mechanism even + // though were are completing immediately. + // Low bit probably means do not queue to IO ports. + if ((uint32_t)apc_routine & ~1) { + if (apc_context) { + auto thread = XThread::GetCurrentThread(); + thread->EnqueueApc(static_cast(apc_routine) & ~1u, apc_context.guest_address(), + io_status_block.guest_address(), 0); + } + } + + if (!file->is_synchronous()) { + result = X_STATUS_PENDING; + } + + // Mark that we should signal the event now. We do this after + // we have written the info out. + signal_event = true; + } else { + // X_STATUS_PENDING if not returning immediately. + result = X_STATUS_PENDING; + + if (io_status_block) { + io_status_block->status = X_STATUS_PENDING; + io_status_block->information = 0; + } + } + } + + if (XFAILED(result) && io_status_block) { + io_status_block->status = result; + io_status_block->information = 0; + } + + if (ev && signal_event) { + ev->Set(0, false); + } + + return result; +} + +u32 NtCreateIoCompletion_entry(mapped_u32 out_handle, u32 desired_access, + mapped_void object_attribs, u32 num_concurrent_threads) { + auto completion = new XIOCompletion(REX_KERNEL_STATE()); + if (out_handle) { + *out_handle = completion->handle(); + } + + return X_STATUS_SUCCESS; +} + +u32 NtSetIoCompletion_entry(u32 handle, u32 key_context, u32 apc_context, u32 completion_status, + u32 num_bytes) { + auto port = REX_KERNEL_OBJECTS()->LookupObject(handle); + if (!port) { + return X_STATUS_INVALID_HANDLE; + } + + XIOCompletion::IONotification notification; + notification.key_context = key_context; + notification.apc_context = apc_context; + notification.num_bytes = num_bytes; + notification.status = completion_status; + + port->QueueNotification(notification); + return X_STATUS_SUCCESS; +} + +// Dequeues a packet from the completion port. +u32 NtRemoveIoCompletion_entry(u32 handle, mapped_u32 key_context, mapped_u32 apc_context, + ppc_ptr_t io_status_block, mapped_u64 timeout) { + X_STATUS status = X_STATUS_SUCCESS; + // uint32_t info = 0; + + auto port = REX_KERNEL_OBJECTS()->LookupObject(handle); + if (!port) { + status = X_STATUS_INVALID_HANDLE; + } + + uint64_t timeout_ticks = timeout ? static_cast(*timeout) + : static_cast(std::numeric_limits::min()); + XIOCompletion::IONotification notification; + if (port->WaitForNotification(timeout_ticks, ¬ification)) { + if (key_context) { + *key_context = notification.key_context; + } + if (apc_context) { + *apc_context = notification.apc_context; + } + + if (io_status_block) { + io_status_block->status = notification.status; + io_status_block->information = notification.num_bytes; + } + } else { + status = X_STATUS_TIMEOUT; + } + + return status; +} + +u32 NtQueryFullAttributesFile_entry(ppc_ptr_t obj_attribs, + ppc_ptr_t file_info) { + auto object_name = REX_KERNEL_MEMORY()->TranslateVirtual(obj_attribs->name_ptr); + auto path_str = util::TranslateAnsiPath(REX_KERNEL_MEMORY(), object_name); + REXKRNL_IMPORT_TRACE("NtQueryFullAttributesFile", "path={}", path_str); + + object_ref root_file; + if (obj_attribs->root_directory != 0xFFFFFFFD && // ObDosDevices + obj_attribs->root_directory != 0) { + root_file = REX_KERNEL_OBJECTS()->LookupObject(obj_attribs->root_directory); + assert_not_null(root_file); + assert_true(root_file->type() == XObject::Type::File); + assert_always(); + } + + auto target_path = util::TranslateAnsiPath(REX_KERNEL_MEMORY(), object_name); + + // Enforce that the path is ASCII. + if (!IsValidPath(target_path, false)) { + return X_STATUS_OBJECT_NAME_INVALID; + } + + // Resolve the file using the virtual file system. + auto entry = REX_KERNEL_FS()->ResolvePath(target_path); + if (entry) { + // Found. + file_info->creation_time = entry->create_timestamp(); + file_info->last_access_time = entry->access_timestamp(); + file_info->last_write_time = entry->write_timestamp(); + file_info->change_time = entry->write_timestamp(); + file_info->allocation_size = entry->allocation_size(); + file_info->end_of_file = entry->size(); + file_info->attributes = entry->attributes(); + + REXKRNL_IMPORT_RESULT("NtQueryFullAttributesFile", "0x0 size={}", (uint64_t)entry->size()); + return X_STATUS_SUCCESS; + } + + REXKRNL_IMPORT_RESULT("NtQueryFullAttributesFile", "X_STATUS_NO_SUCH_FILE"); + return X_STATUS_NO_SUCH_FILE; +} + +u32 NtQueryDirectoryFile_entry(u32 file_handle, u32 event_handle, u32 apc_routine, + mapped_void apc_context, + ppc_ptr_t io_status_block, + ppc_ptr_t file_info_ptr, u32 length, + ppc_ptr_t file_name, u32 restart_scan) { + if (length < 72) { + return X_STATUS_INFO_LENGTH_MISMATCH; + } + + X_STATUS result = X_STATUS_UNSUCCESSFUL; + uint32_t info = 0; + + auto file = REX_KERNEL_OBJECTS()->LookupObject(file_handle); + auto name = util::TranslateAnsiPath(REX_KERNEL_MEMORY(), file_name); + + // Enforce that the path is ASCII. + if (!IsValidPath(name, true)) { + return X_STATUS_INVALID_PARAMETER; + } + + if (file) { + // X_FILE_DIRECTORY_INFORMATION dir_info = {0}; + result = file->QueryDirectory(file_info_ptr, length, name, restart_scan != 0); + if (XSUCCEEDED(result)) { + info = length; + } + } else { + result = X_STATUS_NO_SUCH_FILE; + } + + if (XFAILED(result)) { + info = 0; + } + + if (io_status_block) { + io_status_block->status = result; + io_status_block->information = info; + } + + return result; +} + +u32 NtFlushBuffersFile_entry(u32 file_handle, ppc_ptr_t io_status_block_ptr) { + auto result = X_STATUS_SUCCESS; + + if (io_status_block_ptr) { + io_status_block_ptr->status = result; + io_status_block_ptr->information = 0; + } + + return result; +} + +// https://docs.microsoft.com/en-us/windows/win32/devnotes/ntopensymboliclinkobject +u32 NtOpenSymbolicLinkObject_entry(mapped_u32 handle_out, + ppc_ptr_t object_attrs) { + if (!object_attrs) { + return X_STATUS_INVALID_PARAMETER; + } + assert_not_null(handle_out); + + assert_true(object_attrs->attributes == 64); // case insensitive + + auto object_name = REX_KERNEL_MEMORY()->TranslateVirtual(object_attrs->name_ptr); + + auto target_path = util::TranslateAnsiPath(REX_KERNEL_MEMORY(), object_name); + + // Enforce that the path is ASCII. + if (!IsValidPath(target_path, false)) { + return X_STATUS_OBJECT_NAME_INVALID; + } + + if (object_attrs->root_directory != 0) { + assert_always(); + } + + if (rex::string::utf8_starts_with(target_path, "\\??\\")) { + target_path = target_path.substr(4); // Strip the full qualifier + } + + std::string link_path; + if (!REX_KERNEL_FS()->FindSymbolicLink(target_path, link_path)) { + return X_STATUS_NO_SUCH_FILE; + } + + object_ref symlink(new XSymbolicLink(REX_KERNEL_STATE())); + symlink->Initialize(target_path, link_path); + + *handle_out = symlink->handle(); + + return X_STATUS_SUCCESS; +} + +// https://docs.microsoft.com/en-us/windows/win32/devnotes/ntquerysymboliclinkobject +u32 NtQuerySymbolicLinkObject_entry(u32 handle, ppc_ptr_t target) { + auto symlink = REX_KERNEL_OBJECTS()->LookupObject(handle); + if (!symlink) { + return X_STATUS_NO_SUCH_FILE; + } + auto length = std::min(static_cast(target->maximum_length), symlink->target().size()); + if (length > 0) { + auto target_buf = REX_KERNEL_MEMORY()->TranslateVirtual(target->pointer); + std::memcpy(target_buf, symlink->target().c_str(), length); + } + target->length = static_cast(length); + return X_STATUS_SUCCESS; +} + +u32 FscGetCacheElementCount_entry(u32 r3) { + return 0; +} + +u32 FscSetCacheElementCount_entry(u32 unk_0, u32 unk_1) { + // unk_0 = 0 + // unk_1 looks like a count? in what units? 256 is a common value + return X_STATUS_SUCCESS; +} + +u32 NtDeviceIoControlFile_entry(u32 handle, u32 event_handle, u32 apc_routine, u32 apc_context, + u32 io_status_block, u32 io_control_code, mapped_void input_buffer, + u32 input_buffer_len, mapped_void output_buffer, + u32 output_buffer_len) { + // Called by XMountUtilityDrive cache-mounting code + // (checks if the returned values look valid, values below seem to pass the + // checks) + const uint32_t cache_size = 0xFF000; + + const uint32_t X_IOCTL_DISK_GET_DRIVE_GEOMETRY = 0x70000; + const uint32_t X_IOCTL_DISK_GET_PARTITION_INFO = 0x74004; + + if (io_control_code == X_IOCTL_DISK_GET_DRIVE_GEOMETRY) { + if (output_buffer_len < 0x8) { + assert_always(); + return X_STATUS_BUFFER_TOO_SMALL; + } + memory::store_and_swap(output_buffer, cache_size / 512); + memory::store_and_swap(output_buffer + 4, 512); + } else if (io_control_code == X_IOCTL_DISK_GET_PARTITION_INFO) { + if (output_buffer_len < 0x10) { + assert_always(); + return X_STATUS_BUFFER_TOO_SMALL; + } + memory::store_and_swap(output_buffer, 0); + memory::store_and_swap(output_buffer + 8, cache_size); + } else { + REXKRNL_DEBUG("NtDeviceIoControlFile(0x{:X}) - unhandled IOCTL!", uint32_t(io_control_code)); + assert_always(); + return X_STATUS_INVALID_PARAMETER; + } + + return X_STATUS_SUCCESS; +} + +u32 IoCreateDevice_entry(u32 device_struct, u32 r4, u32 r5, u32 r6, u32 r7, mapped_u32 out_struct) { + // Called from XMountUtilityDrive XAM-task code + // That code tries writing things to a pointer at out_struct+0x18 + // We'll alloc some scratch space for it so it doesn't cause any exceptions + + // 0x24 is guessed size from accesses to out_struct - likely incorrect + auto out_guest = REX_KERNEL_MEMORY()->SystemHeapAlloc(0x24); + + auto out = REX_KERNEL_MEMORY()->TranslateVirtual(out_guest); + memset(out, 0, 0x24); + + // XMountUtilityDrive writes some kind of header here + // 0x1000 bytes should be enough to store it + auto out_guest2 = REX_KERNEL_MEMORY()->SystemHeapAlloc(0x1000); + memory::store_and_swap(out + 0x18, out_guest2); + + *out_struct = out_guest; + return X_STATUS_SUCCESS; +} + +u32 IoDismountVolumeByFileHandle_entry(u32 handle) { + REXKRNL_WARN("IoDismountVolumeByFileHandle({:#x}) - stub", (uint32_t)handle); + return X_STATUS_SUCCESS; +} + +u32 IoDismountVolumeByName_entry(ppc_ptr_t name) { + REXKRNL_WARN("IoDismountVolumeByName - stub"); + return X_STATUS_SUCCESS; +} + +u32 IoSynchronousDeviceIoControlRequest_entry(u32 ioctl, mapped_void device_object, + mapped_void input_buffer, u32 input_length, + mapped_void output_buffer, u32 output_length, + mapped_u32 returned_length, u32 unk) { + REXKRNL_WARN("IoSynchronousDeviceIoControlRequest({:#x}) - stub", (uint32_t)ioctl); + return X_STATUS_SUCCESS; +} + +u32 StfsCreateDevice_entry(mapped_void device_object, u32 flags, mapped_u32 out_device) { + REXKRNL_WARN("StfsCreateDevice - stub"); + // if (out_device) *out_device = 0; + return X_STATUS_SUCCESS; +} + +u32 StfsControlDevice_entry(mapped_void device_object, u32 ioctl, mapped_void input_buffer, + u32 input_length, mapped_void output_buffer, u32 output_length) { + REXKRNL_WARN("StfsControlDevice({:#x}) - stub", (uint32_t)ioctl); + return X_STATUS_SUCCESS; +} + +} // namespace rex::kernel::xboxkrnl + +REX_EXPORT(__imp__NtCreateFile, rex::kernel::xboxkrnl::NtCreateFile_entry) +REX_EXPORT(__imp__NtOpenFile, rex::kernel::xboxkrnl::NtOpenFile_entry) +REX_EXPORT(__imp__NtReadFile, rex::kernel::xboxkrnl::NtReadFile_entry) +REX_EXPORT(__imp__NtReadFileScatter, rex::kernel::xboxkrnl::NtReadFileScatter_entry) +REX_EXPORT(__imp__NtWriteFile, rex::kernel::xboxkrnl::NtWriteFile_entry) +REX_EXPORT(__imp__NtCreateIoCompletion, rex::kernel::xboxkrnl::NtCreateIoCompletion_entry) +REX_EXPORT(__imp__NtSetIoCompletion, rex::kernel::xboxkrnl::NtSetIoCompletion_entry) +REX_EXPORT(__imp__NtRemoveIoCompletion, rex::kernel::xboxkrnl::NtRemoveIoCompletion_entry) +REX_EXPORT(__imp__NtQueryFullAttributesFile, rex::kernel::xboxkrnl::NtQueryFullAttributesFile_entry) +REX_EXPORT(__imp__NtQueryDirectoryFile, rex::kernel::xboxkrnl::NtQueryDirectoryFile_entry) +REX_EXPORT(__imp__NtFlushBuffersFile, rex::kernel::xboxkrnl::NtFlushBuffersFile_entry) +REX_EXPORT(__imp__NtOpenSymbolicLinkObject, rex::kernel::xboxkrnl::NtOpenSymbolicLinkObject_entry) +REX_EXPORT(__imp__NtQuerySymbolicLinkObject, rex::kernel::xboxkrnl::NtQuerySymbolicLinkObject_entry) +REX_EXPORT(__imp__FscGetCacheElementCount, rex::kernel::xboxkrnl::FscGetCacheElementCount_entry) +REX_EXPORT(__imp__FscSetCacheElementCount, rex::kernel::xboxkrnl::FscSetCacheElementCount_entry) +REX_EXPORT(__imp__NtDeviceIoControlFile, rex::kernel::xboxkrnl::NtDeviceIoControlFile_entry) +REX_EXPORT(__imp__IoCreateDevice, rex::kernel::xboxkrnl::IoCreateDevice_entry) +REX_EXPORT(__imp__IoDismountVolumeByFileHandle, + rex::kernel::xboxkrnl::IoDismountVolumeByFileHandle_entry) +REX_EXPORT(__imp__IoDismountVolumeByName, rex::kernel::xboxkrnl::IoDismountVolumeByName_entry) +REX_EXPORT(__imp__IoSynchronousDeviceIoControlRequest, + rex::kernel::xboxkrnl::IoSynchronousDeviceIoControlRequest_entry) +REX_EXPORT(__imp__StfsCreateDevice, rex::kernel::xboxkrnl::StfsCreateDevice_entry) +REX_EXPORT(__imp__StfsControlDevice, rex::kernel::xboxkrnl::StfsControlDevice_entry) + +REX_EXPORT_STUB(__imp__IoAcquireDeviceObjectLock); +REX_EXPORT_STUB(__imp__IoAllocateIrp); +REX_EXPORT_STUB(__imp__IoBuildAsynchronousFsdRequest); +REX_EXPORT_STUB(__imp__IoBuildDeviceIoControlRequest); +REX_EXPORT_STUB(__imp__IoBuildSynchronousFsdRequest); +REX_EXPORT_STUB(__imp__IoCallDriver); +REX_EXPORT_STUB(__imp__IoCheckShareAccess); +REX_EXPORT_STUB(__imp__IoCompleteRequest); +REX_EXPORT_STUB(__imp__IoCreateFile); +REX_EXPORT_STUB(__imp__IoDeleteDevice); +REX_EXPORT_STUB(__imp__IoDismountVolume); +REX_EXPORT_STUB(__imp__IoFreeIrp); +REX_EXPORT_STUB(__imp__IoInitializeIrp); +REX_EXPORT_STUB(__imp__IoInvalidDeviceRequest); +REX_EXPORT_STUB(__imp__IoQueueThreadIrp); +REX_EXPORT_STUB(__imp__IoReleaseDeviceObjectLock); +REX_EXPORT_STUB(__imp__IoRemoveShareAccess); +REX_EXPORT_STUB(__imp__IoSetIoCompletion); +REX_EXPORT_STUB(__imp__IoSetShareAccess); +REX_EXPORT_STUB(__imp__IoStartNextPacket); +REX_EXPORT_STUB(__imp__IoStartNextPacketByKey); +REX_EXPORT_STUB(__imp__IoStartPacket); +REX_EXPORT_STUB(__imp__IoSynchronousFsdRequest); +REX_EXPORT_STUB(__imp__NtDeleteFile); +REX_EXPORT_STUB(__imp__NtSetSystemTime); +REX_EXPORT_STUB(__imp__NtWriteFileGather); +REX_EXPORT_STUB(__imp__IoAcquireCancelSpinLock); +REX_EXPORT_STUB(__imp__IoReleaseCancelSpinLock); +REX_EXPORT_STUB(__imp__NtCancelIoFile); +REX_EXPORT_STUB(__imp__NtCancelIoFileEx); +REX_EXPORT_STUB(__imp__SvodCreateDevice); + +REX_EXPORT_STUB(__imp__SataCdRomRecordReset); diff --git a/src/kernel/xboxkrnl/xboxkrnl_io_info.cpp b/src/kernel/xboxkrnl/xboxkrnl_io_info.cpp new file mode 100644 index 0000000..bd5de65 --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_io_info.cpp @@ -0,0 +1,461 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { +using namespace rex::system; + +static bool IsValidPath(const std::string_view s, bool is_pattern) { + // TODO(gibbed): validate path components individually. + bool got_asterisk = false; + for (const auto& c : s) { + if (c <= 31 || c >= 127) { + return false; + } + if (got_asterisk) { + if (c != '.') { + return false; + } + got_asterisk = false; + } + switch (c) { + case '"': + case '+': + case ',': + case ';': + case '<': + case '=': + case '>': + case '|': { + return false; + } + case '*': { + if (!is_pattern) { + return false; + } + got_asterisk = true; + break; + } + case '?': { + if (!is_pattern) { + return false; + } + break; + } + default: { + break; + } + } + } + return true; +} + +uint32_t GetQueryFileInfoMinimumLength(uint32_t info_class) { + switch (info_class) { + case XFileInternalInformation: + return sizeof(X_FILE_INTERNAL_INFORMATION); + case XFilePositionInformation: + return sizeof(X_FILE_POSITION_INFORMATION); + case XFileXctdCompressionInformation: + return sizeof(X_FILE_XCTD_COMPRESSION_INFORMATION); + case XFileNetworkOpenInformation: + return sizeof(X_FILE_NETWORK_OPEN_INFORMATION); + // TODO(gibbed): structures to get the size of. + case XFileModeInformation: + case XFileAlignmentInformation: + case XFileSectorInformation: + case XFileIoPriorityInformation: + return 4; + case XFileNameInformation: + case XFileAllocationInformation: + return 8; + case XFileBasicInformation: + return 40; + default: + return 0; + } +} + +u32 NtQueryInformationFile_entry(u32 file_handle, ppc_ptr_t io_status_block_ptr, + mapped_void info_ptr, u32 info_length, u32 info_class) { + uint32_t minimum_length = GetQueryFileInfoMinimumLength(info_class); + if (!minimum_length) { + return X_STATUS_INVALID_INFO_CLASS; + } + + if (info_length < minimum_length) { + return X_STATUS_INFO_LENGTH_MISMATCH; + } + + auto file = REX_KERNEL_OBJECTS()->LookupObject(file_handle); + if (!file) { + return X_STATUS_INVALID_HANDLE; + } + + info_ptr.Zero(info_length); + + X_STATUS status = X_STATUS_SUCCESS; + uint32_t out_length; + + switch (info_class) { + case XFileInternalInformation: { + // Internal unique file pointer. Not sure why anyone would want this. + // TODO(benvanik): use pointer to fs::entry? + auto info = info_ptr.as(); + info->index_number = rex::memory::hash_combine(0, file->path()); + out_length = sizeof(*info); + break; + } + case XFilePositionInformation: { + auto info = info_ptr.as(); + info->current_byte_offset = file->position(); + out_length = sizeof(*info); + break; + } + case XFileSectorInformation: { + REXKRNL_DEBUG("Stub XFileSectorInformation!"); + auto info = info_ptr.as(); + size_t fname_hash = rex::memory::hash_combine(82589933LL, file->path()); + *info = static_cast(fname_hash ^ (fname_hash >> 32)); + out_length = sizeof(uint32_t); + break; + } + case XFileXctdCompressionInformation: { + REXKRNL_ERROR( + "NtQueryInformationFile(XFileXctdCompressionInformation) " + "unimplemented"); + // Files that are XCTD compressed begin with the magic 0x0FF512ED but we + // shouldn't detect this that way. There's probably a flag somewhere + // (attributes?) that defines if it's compressed or not. + status = X_STATUS_INVALID_PARAMETER; + out_length = 0; + break; + }; + case XFileNetworkOpenInformation: { + // Make sure we're working with up-to-date information, just in case the + // file size has changed via something other than NtSetInfoFile + // (eg. seems NtWriteFile might extend the file in some cases) + file->entry()->update(); + + auto info = info_ptr.as(); + info->creation_time = file->entry()->create_timestamp(); + info->last_access_time = file->entry()->access_timestamp(); + info->last_write_time = file->entry()->write_timestamp(); + info->change_time = file->entry()->write_timestamp(); + info->allocation_size = file->entry()->allocation_size(); + info->end_of_file = file->entry()->size(); + info->attributes = file->entry()->attributes(); + out_length = sizeof(*info); + break; + } + case XFileAlignmentInformation: { + // Requested by XMountUtilityDrive XAM-task + auto info = info_ptr.as(); + *info = 0; // FILE_BYTE_ALIGNMENT? + out_length = sizeof(*info); + break; + } + default: { + // Unsupported, for now. + assert_always(); + status = X_STATUS_INVALID_PARAMETER; + out_length = 0; + break; + } + } + + if (io_status_block_ptr) { + io_status_block_ptr->status = status; + io_status_block_ptr->information = out_length; + } + + return status; +} + +uint32_t GetSetFileInfoMinimumLength(uint32_t info_class) { + switch (info_class) { + case XFileRenameInformation: + return sizeof(X_FILE_RENAME_INFORMATION); + case XFileDispositionInformation: + return sizeof(X_FILE_DISPOSITION_INFORMATION); + case XFilePositionInformation: + return sizeof(X_FILE_POSITION_INFORMATION); + case XFileCompletionInformation: + return sizeof(X_FILE_COMPLETION_INFORMATION); + case XFileAllocationInformation: + return sizeof(X_FILE_ALLOCATION_INFORMATION); + case XFileEndOfFileInformation: + return sizeof(X_FILE_END_OF_FILE_INFORMATION); + // TODO(gibbed): structures to get the size of. + case XFileModeInformation: + case XFileIoPriorityInformation: + return 4; + case XFileMountPartitionInformation: + return 8; + case XFileLinkInformation: + return 16; + case XFileBasicInformation: + return 40; + case XFileMountPartitionsInformation: + return 152; + default: + return 0; + } +} + +u32 NtSetInformationFile_entry(u32 file_handle, ppc_ptr_t io_status_block, + mapped_void info_ptr, u32 info_length, u32 info_class) { + uint32_t minimum_length = GetSetFileInfoMinimumLength(info_class); + if (!minimum_length) { + return X_STATUS_INVALID_INFO_CLASS; + } + + if (info_length < minimum_length) { + return X_STATUS_INFO_LENGTH_MISMATCH; + } + + auto file = REX_KERNEL_OBJECTS()->LookupObject(file_handle); + if (!file) { + return X_STATUS_INVALID_HANDLE; + } + + X_STATUS result = X_STATUS_SUCCESS; + uint32_t out_length; + + switch (info_class) { + case XFileBasicInformation: { + auto info = info_ptr.as(); + + bool basic_result = true; + if (info->creation_time) { + basic_result &= file->entry()->SetCreateTimestamp(info->creation_time); + } + + if (info->last_access_time) { + basic_result &= file->entry()->SetAccessTimestamp(info->last_access_time); + } + + if (info->last_write_time) { + basic_result &= file->entry()->SetWriteTimestamp(info->last_write_time); + } + + basic_result &= file->entry()->SetAttributes(info->attributes); + if (!basic_result) { + result = X_STATUS_UNSUCCESSFUL; + } + + out_length = sizeof(*info); + break; + } + case XFileDispositionInformation: { + auto info = info_ptr.as(); + bool delete_on_close = info->delete_file ? true : false; + file->entry()->SetForDeletion(delete_on_close); + out_length = 0; + REXKRNL_WARN("NtSetInformationFile set deleting flag for {} on close to: {}", file->name(), + delete_on_close); + break; + } + case XFilePositionInformation: { + auto info = info_ptr.as(); + file->set_position(info->current_byte_offset); + out_length = sizeof(*info); + break; + } + case XFileRenameInformation: { + auto info = info_ptr.as(); + auto target_path = util::TranslateAnsiPath(REX_KERNEL_MEMORY(), &info->ansi_string); + if (!IsValidPath(target_path, false)) { + return X_STATUS_OBJECT_NAME_INVALID; + } + + auto target_file_path = rex::to_path(target_path); + if (!target_file_path.has_filename()) { + return X_STATUS_INVALID_PARAMETER; + } + + result = file->Rename(target_file_path); + out_length = sizeof(*info); + break; + } + case XFileAllocationInformation: { + auto info = info_ptr.as(); + result = file->SetLength(info->allocation_size); + out_length = sizeof(*info); + + // Update the file entry information. + file->entry()->update(); + break; + } + case XFileEndOfFileInformation: { + auto info = info_ptr.as(); + result = file->SetLength(info->end_of_file); + out_length = sizeof(*info); + + // Update the files rex::filesystem::Entry information + file->entry()->update(); + break; + } + case XFileCompletionInformation: { + // Info contains IO Completion handle and completion key + auto info = info_ptr.as(); + auto handle = uint32_t(info->handle); + auto key = uint32_t(info->key); + out_length = sizeof(*info); + auto port = REX_KERNEL_OBJECTS()->LookupObject(handle); + if (!port) { + result = X_STATUS_INVALID_HANDLE; + } else { + file->RegisterIOCompletionPort(key, port); + } + break; + } + default: + // Unsupported, for now. + assert_always(); + out_length = 0; + break; + } + + if (io_status_block) { + io_status_block->status = result; + io_status_block->information = out_length; + } + + return result; +} + +uint32_t GetQueryVolumeInfoMinimumLength(uint32_t info_class) { + switch (info_class) { + case XFileFsVolumeInformation: + return sizeof(X_FILE_FS_VOLUME_INFORMATION); + case XFileFsSizeInformation: + return sizeof(X_FILE_FS_SIZE_INFORMATION); + case XFileFsDeviceInformation: + return sizeof(X_FILE_FS_DEVICE_INFORMATION); + case XFileFsAttributeInformation: + return sizeof(X_FILE_FS_ATTRIBUTE_INFORMATION); + default: + REXKRNL_WARN("Unimplemented Info Class: 0x{:08x}", info_class); + return 0; + } +} + +u32 NtQueryVolumeInformationFile_entry(u32 file_handle, + ppc_ptr_t io_status_block_ptr, + mapped_void info_ptr, u32 info_length, u32 info_class) { + uint32_t minimum_length = GetQueryVolumeInfoMinimumLength(info_class); + if (!minimum_length) { + return X_STATUS_INVALID_INFO_CLASS; + } + + if (info_length < minimum_length) { + return X_STATUS_INFO_LENGTH_MISMATCH; + } + + auto file = REX_KERNEL_OBJECTS()->LookupObject(file_handle); + if (!file) { + return X_STATUS_INVALID_HANDLE; + } + + info_ptr.Zero(info_length); + + X_STATUS status = X_STATUS_SUCCESS; + uint32_t out_length; + + switch (info_class) { + case XFileFsVolumeInformation: { + auto info = info_ptr.as(); + info->creation_time = 0; + info->serial_number = 0; // set for FATX, but we don't do that currently + info->supports_objects = 0; + info->label_length = 0; + out_length = offsetof(X_FILE_FS_VOLUME_INFORMATION, label); + break; + } + case XFileFsSizeInformation: { + auto device = file->device(); + auto info = info_ptr.as(); + info->total_allocation_units = device->total_allocation_units(); + info->available_allocation_units = device->available_allocation_units(); + info->sectors_per_allocation_unit = device->sectors_per_allocation_unit(); + info->bytes_per_sector = device->bytes_per_sector(); + // TODO(gibbed): sanity check, XCTD userland code seems to require this. + assert_true(info->bytes_per_sector == 0x200); + out_length = sizeof(*info); + break; + } + case XFileFsAttributeInformation: { + auto device = file->device(); + const auto& name = device->name(); + auto info = info_ptr.as(); + info->attributes = device->attributes(); + info->component_name_max_length = device->component_name_max_length(); + info->name_length = uint32_t(name.size()); + if (info_length >= 12 + name.size()) { + std::memcpy(info->name, name.data(), name.size()); + out_length = offsetof(X_FILE_FS_ATTRIBUTE_INFORMATION, name) + info->name_length; + } else { + status = X_STATUS_BUFFER_OVERFLOW; + out_length = offsetof(X_FILE_FS_ATTRIBUTE_INFORMATION, name); + } + break; + } + case XFileFsDeviceInformation: { + auto info = info_ptr.as(); + REXKRNL_WARN("Stub XFileFsDeviceInformation!"); + info->device_type = FILE_DEVICE_UNKNOWN; + info->characteristics = 0; + out_length = sizeof(X_FILE_FS_DEVICE_INFORMATION); + break; + } + default: { + // Unsupported, for now. + assert_always(); + out_length = 0; + break; + } + } + + if (io_status_block_ptr) { + io_status_block_ptr->status = status; + io_status_block_ptr->information = out_length; + } + + return status; +} + +} // namespace rex::kernel::xboxkrnl + +REX_EXPORT(__imp__NtQueryInformationFile, rex::kernel::xboxkrnl::NtQueryInformationFile_entry) +REX_EXPORT(__imp__NtSetInformationFile, rex::kernel::xboxkrnl::NtSetInformationFile_entry) +REX_EXPORT(__imp__NtQueryVolumeInformationFile, + rex::kernel::xboxkrnl::NtQueryVolumeInformationFile_entry) diff --git a/src/kernel/xboxkrnl/xboxkrnl_memory.cpp b/src/kernel/xboxkrnl/xboxkrnl_memory.cpp new file mode 100644 index 0000000..8684eda --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_memory.cpp @@ -0,0 +1,771 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { +using namespace rex::system; + +uint32_t ToXdkProtectFlags(uint32_t protect) { + uint32_t result = 0; + if (!(protect & memory::kMemoryProtectRead) && !(protect & memory::kMemoryProtectWrite)) { + result = X_PAGE_NOACCESS; + } else if ((protect & memory::kMemoryProtectRead) && !(protect & memory::kMemoryProtectWrite)) { + result = X_PAGE_READONLY; + } else { + result = X_PAGE_READWRITE; + } + if (protect & memory::kMemoryProtectNoCache) { + result |= X_PAGE_NOCACHE; + } + if (protect & memory::kMemoryProtectWriteCombine) { + result |= X_PAGE_WRITECOMBINE; + } + return result; +} + +uint32_t FromXdkProtectFlags(uint32_t protect) { + uint32_t result = 0; + if ((protect & X_PAGE_READONLY) | (protect & X_PAGE_EXECUTE_READ)) { + result = memory::kMemoryProtectRead; + } else if ((protect & X_PAGE_READWRITE) | (protect & X_PAGE_EXECUTE_READWRITE)) { + result = memory::kMemoryProtectRead | memory::kMemoryProtectWrite; + } + if (protect & X_PAGE_NOCACHE) { + result |= memory::kMemoryProtectNoCache; + } + if (protect & X_PAGE_WRITECOMBINE) { + result |= memory::kMemoryProtectWriteCombine; + } + return result; +} + +u32 NtAllocateVirtualMemory_entry(mapped_u32 base_addr_ptr, mapped_u32 region_size_ptr, + u32 alloc_type, u32 protect_bits, u32 debug_memory) { + uint32_t input_base = base_addr_ptr ? static_cast(*base_addr_ptr) : 0; + uint32_t input_size = region_size_ptr ? static_cast(*region_size_ptr) : 0; + REXKRNL_IMPORT_TRACE( + "NtAllocateVirtualMemory", "base={:#x} size={:#x} type={:#x} protect={:#x} debug={}", + input_base, input_size, (uint32_t)alloc_type, (uint32_t)protect_bits, (uint32_t)debug_memory); + + // NTSTATUS + // _Inout_ PVOID *BaseAddress, + // _Inout_ PSIZE_T RegionSize, + // _In_ ULONG AllocationType, + // _In_ ULONG Protect + // _In_ BOOLEAN DebugMemory + + assert_not_null(base_addr_ptr); + assert_not_null(region_size_ptr); + + // Set to TRUE when allocation is from devkit memory area. + // assert_true(debug_memory == 0); + // just warn tf am i gunna do about it + if ((uint32_t)debug_memory != 0) + REXKRNL_WARN("attmpted allocation to devkit memory area (debug_memory={})", + (uint32_t)debug_memory); + + // This allocates memory from the kernel heap, which is initialized on startup + // and shared by both the kernel implementation and user code. + // The xe_memory_ref object is used to actually get the memory, and although + // it's simple today we could extend it to do better things in the future. + + // Must request a size. + if (!base_addr_ptr || !region_size_ptr || !*region_size_ptr) { + return X_STATUS_INVALID_PARAMETER; + } + // Check allocation type. + if (!(alloc_type & (X_MEM_COMMIT | X_MEM_RESET | X_MEM_RESERVE))) { + return X_STATUS_INVALID_PARAMETER; + } + // If MEM_RESET is set only MEM_RESET can be set. + if (alloc_type & X_MEM_RESET && (alloc_type & ~X_MEM_RESET)) { + return X_STATUS_INVALID_PARAMETER; + } + // Don't allow games to set execute bits. + if (protect_bits & (X_PAGE_EXECUTE | X_PAGE_EXECUTE_READ | X_PAGE_EXECUTE_READWRITE | + X_PAGE_EXECUTE_WRITECOPY)) { + REXKRNL_WARN("Game setting EXECUTE bit on allocation"); + } + + uint32_t page_size; + if (*base_addr_ptr != 0) { + // ignore specified page size when base address is specified. + auto heap = REX_KERNEL_MEMORY()->LookupHeap(*base_addr_ptr); + if (!heap || heap->heap_type() != memory::HeapType::kGuestVirtual) { + return X_STATUS_INVALID_PARAMETER; + } + page_size = heap->page_size(); + } else { + // Adjust size. + page_size = 4 * 1024; + if (alloc_type & X_MEM_LARGE_PAGES) { + page_size = 64 * 1024; + } + } + + // Round the base address down to the nearest page boundary. + uint32_t adjusted_base = *base_addr_ptr - (*base_addr_ptr % page_size); + // For some reason, some games pass in negative sizes. + uint32_t adjusted_size = + int32_t(*region_size_ptr) < 0 ? -int32_t(region_size_ptr.value()) : region_size_ptr.value(); + // Use 64KB allocation granularity when no base address is specified, + // matching Xbox 360 behavior. With a base address, use the heap's page size. + adjusted_size = rex::round_up(adjusted_size, adjusted_base ? page_size : 64 * 1024); + + // Allocate. + uint32_t allocation_type = 0; + if (alloc_type & X_MEM_RESERVE) { + allocation_type |= memory::kMemoryAllocationReserve; + } + if (alloc_type & X_MEM_COMMIT) { + allocation_type |= memory::kMemoryAllocationCommit; + } + if (alloc_type & X_MEM_RESET) { + REXKRNL_ERROR("X_MEM_RESET not implemented"); + assert_always(); + } + uint32_t protect = FromXdkProtectFlags(protect_bits); + uint32_t address = 0; + memory::BaseHeap* heap; + memory::HeapAllocationInfo prev_alloc_info = {}; + bool was_commited = false; + + if (adjusted_base != 0) { + heap = REX_KERNEL_MEMORY()->LookupHeap(adjusted_base); + if (!heap) { + return X_STATUS_INVALID_PARAMETER; + } + if (heap->page_size() != page_size) { + // Specified the wrong page size for the wrong heap. + return X_STATUS_ACCESS_DENIED; + } + was_commited = heap->QueryRegionInfo(adjusted_base, &prev_alloc_info) && + (prev_alloc_info.state & memory::kMemoryAllocationCommit) != 0; + + if (heap->AllocFixed(adjusted_base, adjusted_size, page_size, allocation_type, protect)) { + address = adjusted_base; + } + } else { + bool top_down = !!(alloc_type & X_MEM_TOP_DOWN); + heap = REX_KERNEL_MEMORY()->LookupHeapByType(false, page_size); + heap->Alloc(adjusted_size, page_size, allocation_type, protect, top_down, &address); + } + if (!address) { + // Failed - assume no memory available. + return X_STATUS_NO_MEMORY; + } + + // Zero memory, if needed. + if (address && !(alloc_type & X_MEM_NOZERO)) { + if (alloc_type & X_MEM_COMMIT) { + if (!(protect & memory::kMemoryProtectWrite)) { + heap->Protect(address, adjusted_size, + memory::kMemoryProtectRead | memory::kMemoryProtectWrite); + } + if (!was_commited) { + REX_KERNEL_MEMORY()->Zero(address, adjusted_size); + } + if (!(protect & memory::kMemoryProtectWrite)) { + heap->Protect(address, adjusted_size, protect); + } + } + } + // Stash back. + // Maybe set X_STATUS_ALREADY_COMMITTED if MEM_COMMIT? + *base_addr_ptr = address; + *region_size_ptr = adjusted_size; + REXKRNL_IMPORT_RESULT("NtAllocateVirtualMemory", "0x0 addr={:#x} size={:#x}", address, + adjusted_size); + return X_STATUS_SUCCESS; +} + +u32 NtProtectVirtualMemory_entry(mapped_u32 base_addr_ptr, mapped_u32 region_size_ptr, + u32 protect_bits, mapped_u32 old_protect, u32 debug_memory) { + // Set to TRUE when this memory refers to devkit memory area. + assert_true(debug_memory == 0); + + // Must request a size. + if (!base_addr_ptr || !region_size_ptr || !*region_size_ptr) { + return X_STATUS_INVALID_PARAMETER; + } + + // Don't allow games to set execute bits. + if (protect_bits & (X_PAGE_EXECUTE | X_PAGE_EXECUTE_READ | X_PAGE_EXECUTE_READWRITE | + X_PAGE_EXECUTE_WRITECOPY)) { + REXKRNL_WARN("Game setting EXECUTE bit on protect"); + return X_STATUS_INVALID_PAGE_PROTECTION; + } + + auto heap = REX_KERNEL_MEMORY()->LookupHeap(*base_addr_ptr); + if (heap->heap_type() != memory::HeapType::kGuestVirtual) { + return X_STATUS_INVALID_PARAMETER; + } + // Adjust the base downwards to the nearest page boundary. + uint32_t adjusted_base = *base_addr_ptr - (*base_addr_ptr % heap->page_size()); + uint32_t adjusted_size = rex::round_up(*region_size_ptr, heap->page_size()); + uint32_t protect = FromXdkProtectFlags(protect_bits); + + uint32_t tmp_old_protect = 0; + + // FIXME: I think it's valid for NtProtectVirtualMemory to span regions, but + // as of now our implementation will fail in this case. Need to verify. + if (!heap->Protect(adjusted_base, adjusted_size, protect, &tmp_old_protect)) { + return X_STATUS_ACCESS_DENIED; + } + + // Write back output variables. + *base_addr_ptr = adjusted_base; + *region_size_ptr = adjusted_size; + + if (old_protect) { + *old_protect = tmp_old_protect; + } + + return X_STATUS_SUCCESS; +} + +u32 NtFreeVirtualMemory_entry(mapped_u32 base_addr_ptr, mapped_u32 region_size_ptr, u32 free_type, + u32 debug_memory) { + uint32_t base_addr_value = *base_addr_ptr; + uint32_t region_size_value = *region_size_ptr; + REXKRNL_IMPORT_TRACE("NtFreeVirtualMemory", "base={:#x} size={:#x} type={:#x} debug={}", + base_addr_value, region_size_value, (uint32_t)free_type, + (uint32_t)debug_memory); + // X_MEM_DECOMMIT | X_MEM_RELEASE + + // NTSTATUS + // _Inout_ PVOID *BaseAddress, + // _Inout_ PSIZE_T RegionSize, + // _In_ ULONG FreeType + // _In_ BOOLEAN DebugMemory + + // Set to TRUE when freeing external devkit memory. + assert_true(debug_memory == 0); + + if (!base_addr_value) { + return X_STATUS_MEMORY_NOT_ALLOCATED; + } + + auto heap = REX_KERNEL_MEMORY()->LookupHeap(base_addr_value); + if (heap->heap_type() != memory::HeapType::kGuestVirtual) { + return X_STATUS_INVALID_PARAMETER; + } + bool result = false; + if (free_type == X_MEM_DECOMMIT) { + // If zero, we may need to query size (free whole region). + assert_not_zero(region_size_value); + + region_size_value = rex::round_up(region_size_value, heap->page_size()); + result = heap->Decommit(base_addr_value, region_size_value); + } else { + result = heap->Release(base_addr_value, ®ion_size_value); + } + if (!result) { + return X_STATUS_UNSUCCESSFUL; + } + + *base_addr_ptr = base_addr_value; + *region_size_ptr = region_size_value; + REXKRNL_IMPORT_RESULT("NtFreeVirtualMemory", "0x0"); + return X_STATUS_SUCCESS; +} + +struct X_MEMORY_BASIC_INFORMATION { + be base_address; + be allocation_base; + be allocation_protect; + be region_size; + be state; + be protect; + be type; +}; + +u32 NtQueryVirtualMemory_entry(u32 base_address, + ppc_ptr_t memory_basic_information_ptr, + u32 region_type) { + switch ((uint32_t)region_type) { + case 0: + case 1: + case 2: + break; + default: + return X_STATUS_INVALID_PARAMETER; + } + + auto heap = REX_KERNEL_MEMORY()->LookupHeap(base_address); + memory::HeapAllocationInfo alloc_info; + if (heap == nullptr || !heap->QueryRegionInfo(base_address, &alloc_info)) { + return X_STATUS_INVALID_PARAMETER; + } + + memory_basic_information_ptr->base_address = alloc_info.base_address; + memory_basic_information_ptr->allocation_base = alloc_info.allocation_base; + memory_basic_information_ptr->allocation_protect = + ToXdkProtectFlags(alloc_info.allocation_protect); + memory_basic_information_ptr->region_size = alloc_info.region_size; + // https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-memory_basic_information + // State: ... This member can be one of the following values: MEM_COMMIT, + // MEM_FREE, MEM_RESERVE. + // State queried by Beautiful Katamari before displaying the loading screen. + uint32_t x_state; + if (alloc_info.state & memory::kMemoryAllocationCommit) { + assert_not_zero(alloc_info.state & memory::kMemoryAllocationReserve); + x_state = X_MEM_COMMIT; + } else if (alloc_info.state & memory::kMemoryAllocationReserve) { + x_state = X_MEM_RESERVE; + } else { + x_state = X_MEM_FREE; + } + memory_basic_information_ptr->state = x_state; + memory_basic_information_ptr->protect = ToXdkProtectFlags(alloc_info.protect); + memory_basic_information_ptr->type = X_MEM_PRIVATE; + + return X_STATUS_SUCCESS; +} + +u32 MmAllocatePhysicalMemoryEx_entry(u32 flags, u32 region_size, u32 protect_bits, + u32 min_addr_range, u32 max_addr_range, u32 alignment) { + REXKRNL_IMPORT_TRACE("MmAllocatePhysicalMemoryEx", + "flags={:#x} size={:#x} protect={:#x} min={:#x} max={:#x} align={:#x}", + (uint32_t)flags, (uint32_t)region_size, (uint32_t)protect_bits, + (uint32_t)min_addr_range, (uint32_t)max_addr_range, (uint32_t)alignment); + + // Check protection bits. + if (!(protect_bits & (X_PAGE_READONLY | X_PAGE_READWRITE))) { + REXKRNL_ERROR("MmAllocatePhysicalMemoryEx: bad protection bits"); + return 0; + } + + // Either may be OR'ed into protect_bits: + // X_PAGE_NOCACHE + // X_PAGE_WRITECOMBINE + // We could use this to detect what's likely GPU-synchronized memory + // and let the GPU know we're messing with it (or even allocate from + // the GPU). At least the D3D command buffer is X_PAGE_WRITECOMBINE. + + // Calculate page size. + // Default = 4KB + // X_MEM_LARGE_PAGES = 64KB + // X_MEM_16MB_PAGES = 16MB + uint32_t page_size = 4 * 1024; + if (protect_bits & X_MEM_LARGE_PAGES) { + page_size = 64 * 1024; + } else if (protect_bits & X_MEM_16MB_PAGES) { + page_size = 16 * 1024 * 1024; + } + + // Round up the region size and alignment to the next page. + uint32_t adjusted_size = rex::round_up(region_size, page_size); + uint32_t adjusted_alignment = rex::round_up(alignment, page_size); + + uint32_t allocation_type = memory::kMemoryAllocationReserve | memory::kMemoryAllocationCommit; + uint32_t protect = FromXdkProtectFlags(protect_bits); + bool top_down = true; + auto heap = + static_cast(REX_KERNEL_MEMORY()->LookupHeapByType(true, page_size)); + // min_addr_range/max_addr_range are bounds in physical memory, not virtual. + uint32_t heap_base = heap->heap_base(); + uint32_t heap_physical_address_offset = heap->GetPhysicalAddress(heap_base); + // NOTE: xenia-canary has a per-title workaround (ignore_offset_for_ranged_allocations cvar) + // for title 545108B4 where min_addr_range comparison fails due to 0x1000 offset. + // If needed, set heap_physical_address_offset = 0 when min_addr_range && max_addr_range. + // Reference: xenia-canary 81aaf98e0. + uint32_t heap_min_addr = rex::sat_sub(min_addr_range, heap_physical_address_offset); + uint32_t heap_max_addr = rex::sat_sub(max_addr_range, heap_physical_address_offset); + uint32_t heap_size = heap->heap_size(); + heap_min_addr = heap_base + std::min(heap_min_addr, heap_size - 1); + heap_max_addr = heap_base + std::min(heap_max_addr, heap_size - 1); + uint32_t base_address; + if (!heap->AllocRange(heap_min_addr, heap_max_addr, adjusted_size, adjusted_alignment, + allocation_type, protect, top_down, &base_address)) { + // Failed - assume no memory available. + return 0; + } + REXKRNL_IMPORT_RESULT("MmAllocatePhysicalMemoryEx", "addr={:#x}", base_address); + + return base_address; +} + +u32 MmAllocatePhysicalMemory_entry(u32 flags, u32 region_size, u32 protect_bits) { + return MmAllocatePhysicalMemoryEx_entry(flags, region_size, protect_bits, 0, 0xFFFFFFFFu, 0); +} + +void MmFreePhysicalMemory_entry(u32 type, u32 base_address) { + REXKRNL_IMPORT_TRACE("MmFreePhysicalMemory", "type={:#x} addr={:#x}", (uint32_t)type, + (uint32_t)base_address); + + assert_true((base_address & 0x1F) == 0); + + auto heap = REX_KERNEL_MEMORY()->LookupHeap(base_address); + heap->Release(base_address); +} + +u32 MmQueryAddressProtect_entry(u32 base_address) { + auto heap = REX_KERNEL_MEMORY()->LookupHeap(base_address); + uint32_t access; + if (!heap->QueryProtect(base_address, &access)) { + access = 0; + } + access = !access ? 0 : ToXdkProtectFlags(access); + + return access; +} + +void MmSetAddressProtect_entry(mapped_void base_address, u32 region_size, u32 protect_bits) { + constexpr uint32_t required_protect_bits = X_PAGE_NOACCESS | X_PAGE_READONLY | X_PAGE_READWRITE | + X_PAGE_EXECUTE_READ | X_PAGE_EXECUTE_READWRITE; + + if (rex::bit_count(uint32_t(protect_bits) & required_protect_bits) != 1) { + assert_false(rex::bit_count(uint32_t(protect_bits) & required_protect_bits) > 1); + return; + } + + uint32_t protect = FromXdkProtectFlags(protect_bits); + auto heap = REX_KERNEL_MEMORY()->LookupHeap(base_address.guest_address()); + if (!heap) { + return; + } + if (heap->heap_type() == memory::HeapType::kGuestXex) { + return; + } + + heap->Protect(base_address.guest_address(), region_size, protect); +} + +u32 MmQueryAllocationSize_entry(mapped_void base_address) { + auto heap = REX_KERNEL_MEMORY()->LookupHeap(base_address.guest_address()); + uint32_t size; + if (!heap->QuerySize(base_address.guest_address(), &size)) { + size = 0; + } + + return size; +} + +// https://code.google.com/p/vdash/source/browse/trunk/vdash/include/kernel.h +struct X_MM_QUERY_STATISTICS_SECTION { + rex::be available_pages; + rex::be total_virtual_memory_bytes; + rex::be reserved_virtual_memory_bytes; + rex::be physical_pages; + rex::be pool_pages; + rex::be stack_pages; + rex::be image_pages; + rex::be heap_pages; + rex::be virtual_pages; + rex::be page_table_pages; + rex::be cache_pages; +}; + +struct X_MM_QUERY_STATISTICS_RESULT { + rex::be size; + rex::be total_physical_pages; + rex::be kernel_pages; + X_MM_QUERY_STATISTICS_SECTION title; + X_MM_QUERY_STATISTICS_SECTION system; + rex::be highest_physical_page; +}; +static_assert_size(X_MM_QUERY_STATISTICS_RESULT, 104); + +u32 MmQueryStatistics_entry(ppc_ptr_t stats_ptr) { + if (!stats_ptr) { + return X_STATUS_INVALID_PARAMETER; + } + + const uint32_t size = sizeof(X_MM_QUERY_STATISTICS_RESULT); + + if (stats_ptr->size != size) { + return X_STATUS_BUFFER_TOO_SMALL; + } + + // Zero out the struct. + stats_ptr.Zero(); + + // Set the constants the game is likely asking for. + // These numbers are mostly guessed. If the game is just checking for + // memory, this should satisfy it. If it's actually verifying things + // this won't work :/ + stats_ptr->size = size; + + stats_ptr->total_physical_pages = 0x00020000; // 512mb / 4kb pages + stats_ptr->kernel_pages = 0x00000100; + + uint32_t reserved_pages = 0; + uint32_t unreserved_pages = 0; + uint32_t used_pages = 0; + uint32_t reserved_pages_bytes = 0; + const memory::BaseHeap* physical_heaps[3] = { + REX_KERNEL_MEMORY()->LookupHeapByType(true, 0x1000), + REX_KERNEL_MEMORY()->LookupHeapByType(true, 0x10000), + REX_KERNEL_MEMORY()->LookupHeapByType(true, 0x1000000)}; + + REX_KERNEL_MEMORY()->GetHeapsPageStatsSummary(physical_heaps, std::size(physical_heaps), + unreserved_pages, reserved_pages, used_pages, + reserved_pages_bytes); + + assert_true(used_pages < stats_ptr->total_physical_pages); + + stats_ptr->title.available_pages = + stats_ptr->total_physical_pages - stats_ptr->kernel_pages - used_pages; + stats_ptr->title.total_virtual_memory_bytes = 0x2FFE0000; + stats_ptr->title.reserved_virtual_memory_bytes = reserved_pages_bytes; + stats_ptr->title.physical_pages = 0x00001000; // TODO(gibbed): FIXME + stats_ptr->title.pool_pages = 0x00000010; + stats_ptr->title.stack_pages = 0x00000100; + stats_ptr->title.image_pages = 0x00000100; + stats_ptr->title.heap_pages = 0x00000100; + stats_ptr->title.virtual_pages = 0x00000100; + stats_ptr->title.page_table_pages = 0x00000100; + stats_ptr->title.cache_pages = 0x00000100; + + stats_ptr->system.available_pages = 0x00000000; + stats_ptr->system.total_virtual_memory_bytes = 0x00000000; + stats_ptr->system.reserved_virtual_memory_bytes = 0x00000000; + stats_ptr->system.physical_pages = 0x00000000; + stats_ptr->system.pool_pages = 0x00000000; + stats_ptr->system.stack_pages = 0x00000000; + stats_ptr->system.image_pages = 0x00000000; + stats_ptr->system.heap_pages = 0x00000000; + stats_ptr->system.virtual_pages = 0x00000000; + stats_ptr->system.page_table_pages = 0x00000000; + stats_ptr->system.cache_pages = 0x00000000; + + stats_ptr->highest_physical_page = 0x0001FFFF; + + return X_STATUS_SUCCESS; +} + +// https://msdn.microsoft.com/en-us/library/windows/hardware/ff554547(v=vs.85).aspx +u32 MmGetPhysicalAddress_entry(u32 base_address) { + // base_address = result of MmAllocatePhysicalMemory. + uint32_t physical_address = REX_KERNEL_MEMORY()->GetPhysicalAddress(base_address); + assert_true(physical_address != UINT32_MAX); + if (physical_address == UINT32_MAX) { + physical_address = 0; + } + REXKRNL_IMPORT_RESULT("MmGetPhysicalAddress", "addr={:#x} -> {:#x}", (uint32_t)base_address, + physical_address); + return physical_address; +} + +u32 MmMapIoSpace_entry(u32 unk0, mapped_void src_address, u32 size, u32 flags) { + // I've only seen this used to map XMA audio contexts. + // The code seems fine with taking the src address, so this just returns that. + // If others start using it there could be problems. + assert_true(unk0 == 2); + assert_true(size == 0x40); + assert_true(flags == 0x404); + + return src_address.guest_address(); +} + +struct X_POOL_ALLOC_HEADER { + uint8_t unk_0; + uint8_t unk_1; + uint8_t unk_2; + uint8_t unk_3; + rex::be tag; +}; +static_assert_size(X_POOL_ALLOC_HEADER, 8); + +u32 ExAllocatePoolTypeWithTag_entry(u32 size, u32 tag, u32 zero) { + if (size <= 0xFD8) { + uint32_t adjusted_size = size + sizeof(X_POOL_ALLOC_HEADER); + uint32_t addr = REX_KERNEL_MEMORY()->SystemHeapAlloc(adjusted_size, 64); + if (!addr) + return 0; + auto header = REX_KERNEL_MEMORY()->TranslateVirtual(addr); + header->unk_2 = 170; // magic marker + header->tag = (uint32_t)tag; + return addr + sizeof(X_POOL_ALLOC_HEADER); + } else { + return REX_KERNEL_MEMORY()->SystemHeapAlloc(size, 4096); + } +} + +u32 ExAllocatePool_entry(u32 size) { + const uint32_t none = 0x656E6F4E; // 'None' + return ExAllocatePoolTypeWithTag_entry(size, none, 0); +} + +void ExFreePool_entry(mapped_void base_address) { + uint32_t addr = base_address.guest_address(); + if ((addr & (4096 - 1)) == 0) { + // Page-aligned: large allocation with no pool header. + REX_KERNEL_MEMORY()->SystemHeapFree(addr); + } else { + // Small allocation: subtract pool header to get real alloc base. + REX_KERNEL_MEMORY()->SystemHeapFree(addr - sizeof(X_POOL_ALLOC_HEADER)); + } +} + +u32 KeGetImagePageTableEntry_entry(mapped_void address) { + auto heap = REX_KERNEL_MEMORY()->LookupHeap(address.guest_address()); + if (!heap || heap->heap_type() != memory::HeapType::kGuestXex) { + return 0; + } + uint32_t result = address.guest_address() - heap->heap_base(); + result /= heap->page_size(); + if (heap->page_size() < 65536) { + result |= 0x40000000; + } + return result & 0x400FFFFF; +} + +u32 KeLockL2_entry() { + // TODO + return 0; +} + +void KeUnlockL2_entry() {} + +u32 MmCreateKernelStack_entry(u32 stack_size, u32 r4) { + assert_zero(r4); // Unknown argument. + + auto stack_size_aligned = (stack_size + 0xFFF) & 0xFFFFF000; + uint32_t stack_alignment = (stack_size & 0xF000) ? 0x1000 : 0x10000; + + uint32_t stack_address; + REX_KERNEL_STATE() + ->memory() + ->LookupHeap(0x70000000) + ->AllocRange(0x70000000, 0x7F000000, stack_size_aligned, stack_alignment, + memory::kMemoryAllocationReserve | memory::kMemoryAllocationCommit, + memory::kMemoryProtectRead | memory::kMemoryProtectWrite, false, &stack_address); + return stack_address + stack_size; +} + +u32 MmDeleteKernelStack_entry(mapped_void stack_base, mapped_void stack_end) { + // Release the stack (where stack_end is the low address) + if (REX_KERNEL_STATE()->memory()->LookupHeap(0x70000000)->Release(stack_end.guest_address())) { + return X_STATUS_SUCCESS; + } + + return X_STATUS_UNSUCCESSFUL; +} + +u32 ExAllocatePoolWithTag_entry(u32 numbytes, u32 tag, u32 zero) { + return ExAllocatePoolTypeWithTag_entry(numbytes, tag, zero); +} + +u32 MmIsAddressValid_entry(u32 address) { + auto heap = REX_KERNEL_MEMORY()->LookupHeap(address); + if (!heap) { + return 0; + } + return heap->QueryRangeAccess(address, address) != rex::memory::PageAccess::kNoAccess; +} + +u32 NtAllocateEncryptedMemory_entry(u32 unk, u32 region_size, mapped_u32 base_addr_ptr) { + if (!region_size) { + return X_STATUS_INVALID_PARAMETER; + } + + const uint32_t region_size_adjusted = rex::round_up(uint32_t(region_size), 64 * 1024); + if (region_size_adjusted > 16 * 1024 * 1024) { + return X_STATUS_INVALID_PARAMETER; + } + + uint32_t out_address = 0; + auto heap = REX_KERNEL_MEMORY()->LookupHeap(0x8C000000); + if (!heap) { + return X_STATUS_UNSUCCESSFUL; + } + if (!heap->AllocRange( + 0x8C000000, 0x8FFFFFFF, region_size_adjusted, 64 * 1024, memory::kMemoryAllocationCommit, + memory::kMemoryProtectRead | memory::kMemoryProtectWrite, false, &out_address)) { + return X_STATUS_UNSUCCESSFUL; + } + + REXKRNL_IMPORT_RESULT("NtAllocateEncryptedMemory", "addr={:#x}", out_address); + *base_addr_ptr = out_address; + return X_STATUS_SUCCESS; +} + +u32 NtFreeEncryptedMemory_entry(u32 region_type, mapped_u32 base_address_ptr) { + if (!base_address_ptr) { + return X_STATUS_INVALID_PARAMETER; + } + + auto heap = REX_KERNEL_MEMORY()->LookupHeap(0x80000000); + if (!heap) { + return X_STATUS_INVALID_PARAMETER; + } + const uint32_t encrypt_address = heap->heap_base() + heap->page_size() * (*base_address_ptr); + + auto encrypt_heap = REX_KERNEL_MEMORY()->LookupHeap(encrypt_address); + if (!encrypt_heap || encrypt_heap->heap_type() != memory::HeapType::kGuestXex) { + return X_STATUS_INVALID_PARAMETER; + } + + REX_KERNEL_MEMORY()->SystemHeapFree(encrypt_address); + return X_STATUS_SUCCESS; +} + +} // namespace rex::kernel::xboxkrnl + +REX_EXPORT(__imp__NtAllocateVirtualMemory, rex::kernel::xboxkrnl::NtAllocateVirtualMemory_entry) +REX_EXPORT(__imp__NtProtectVirtualMemory, rex::kernel::xboxkrnl::NtProtectVirtualMemory_entry) +REX_EXPORT(__imp__NtFreeVirtualMemory, rex::kernel::xboxkrnl::NtFreeVirtualMemory_entry) +REX_EXPORT(__imp__NtQueryVirtualMemory, rex::kernel::xboxkrnl::NtQueryVirtualMemory_entry) +REX_EXPORT(__imp__MmAllocatePhysicalMemoryEx, + rex::kernel::xboxkrnl::MmAllocatePhysicalMemoryEx_entry) +REX_EXPORT(__imp__MmAllocatePhysicalMemory, rex::kernel::xboxkrnl::MmAllocatePhysicalMemory_entry) +REX_EXPORT(__imp__MmFreePhysicalMemory, rex::kernel::xboxkrnl::MmFreePhysicalMemory_entry) +REX_EXPORT(__imp__MmQueryAddressProtect, rex::kernel::xboxkrnl::MmQueryAddressProtect_entry) +REX_EXPORT(__imp__MmSetAddressProtect, rex::kernel::xboxkrnl::MmSetAddressProtect_entry) +REX_EXPORT(__imp__MmQueryAllocationSize, rex::kernel::xboxkrnl::MmQueryAllocationSize_entry) +REX_EXPORT(__imp__MmQueryStatistics, rex::kernel::xboxkrnl::MmQueryStatistics_entry) +REX_EXPORT(__imp__MmGetPhysicalAddress, rex::kernel::xboxkrnl::MmGetPhysicalAddress_entry) +REX_EXPORT(__imp__MmMapIoSpace, rex::kernel::xboxkrnl::MmMapIoSpace_entry) +REX_EXPORT(__imp__ExAllocatePoolTypeWithTag, rex::kernel::xboxkrnl::ExAllocatePoolTypeWithTag_entry) +REX_EXPORT(__imp__ExAllocatePool, rex::kernel::xboxkrnl::ExAllocatePool_entry) +REX_EXPORT(__imp__ExFreePool, rex::kernel::xboxkrnl::ExFreePool_entry) +REX_EXPORT(__imp__KeGetImagePageTableEntry, rex::kernel::xboxkrnl::KeGetImagePageTableEntry_entry) +REX_EXPORT(__imp__KeLockL2, rex::kernel::xboxkrnl::KeLockL2_entry) +REX_EXPORT(__imp__KeUnlockL2, rex::kernel::xboxkrnl::KeUnlockL2_entry) +REX_EXPORT(__imp__MmCreateKernelStack, rex::kernel::xboxkrnl::MmCreateKernelStack_entry) +REX_EXPORT(__imp__MmDeleteKernelStack, rex::kernel::xboxkrnl::MmDeleteKernelStack_entry) + +REX_EXPORT(__imp__ExAllocatePoolWithTag, rex::kernel::xboxkrnl::ExAllocatePoolWithTag_entry) +REX_EXPORT_STUB(__imp__ExQueryPoolBlockSize); +REX_EXPORT_STUB(__imp__MmDoubleMapMemory); +REX_EXPORT_STUB(__imp__MmUnmapMemory); +REX_EXPORT(__imp__MmIsAddressValid, rex::kernel::xboxkrnl::MmIsAddressValid_entry) +REX_EXPORT_STUB(__imp__MmLockAndMapSegmentArray); +REX_EXPORT_STUB(__imp__MmLockUnlockBufferPages); +REX_EXPORT_STUB(__imp__MmPersistPhysicalMemoryAllocation); +REX_EXPORT_STUB(__imp__MmSplitPhysicalMemoryAllocation); +REX_EXPORT_STUB(__imp__MmUnlockAndUnmapSegmentArray); +REX_EXPORT_STUB(__imp__MmUnmapIoSpace); +REX_EXPORT(__imp__NtAllocateEncryptedMemory, rex::kernel::xboxkrnl::NtAllocateEncryptedMemory_entry) +REX_EXPORT(__imp__NtFreeEncryptedMemory, rex::kernel::xboxkrnl::NtFreeEncryptedMemory_entry) +REX_EXPORT_STUB(__imp__ExDebugMonitorService); +REX_EXPORT_STUB(__imp__MmDbgReadCheck); +REX_EXPORT_STUB(__imp__MmDbgReleaseAddress); +REX_EXPORT_STUB(__imp__MmDbgWriteCheck); +REX_EXPORT_STUB(__imp__MmGetPoolPagesType); +REX_EXPORT_STUB(__imp__ExExpansionInstall); +REX_EXPORT_STUB(__imp__ExExpansionCall); +REX_EXPORT_STUB(__imp__MmResetLowestAvailablePages); diff --git a/src/kernel/xboxkrnl/xboxkrnl_misc.cpp b/src/kernel/xboxkrnl/xboxkrnl_misc.cpp new file mode 100644 index 0000000..58b6000 --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_misc.cpp @@ -0,0 +1,179 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include +#include +#include +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { + +void KeEnableFpuExceptions_entry(u32 enabled) { + // TODO(benvanik): can we do anything about exceptions? +} + +} // namespace rex::kernel::xboxkrnl + +REX_EXPORT(__imp__KeEnableFpuExceptions, rex::kernel::xboxkrnl::KeEnableFpuExceptions_entry) + +REX_EXPORT_STUB(__imp__ExSetBetaFeaturesEnabled); +REX_EXPORT_STUB(__imp__ExIsBetaFeatureEnabled); +REX_EXPORT_STUB(__imp__AniBlockOnAnimation); +REX_EXPORT_STUB(__imp__AniTerminateAnimation); +REX_EXPORT_STUB(__imp__AniSetLogo); +REX_EXPORT_STUB(__imp__AniStartBootAnimation); +REX_EXPORT_STUB(__imp__EtxConsumerDisableEventType); +REX_EXPORT_STUB(__imp__EtxConsumerEnableEventType); +REX_EXPORT_STUB(__imp__EtxConsumerProcessLogs); +REX_EXPORT_STUB(__imp__EtxConsumerRegister); +REX_EXPORT_STUB(__imp__EtxConsumerUnregister); +REX_EXPORT_STUB(__imp__EtxProducerLog); +REX_EXPORT_STUB(__imp__EtxProducerLogV); +REX_EXPORT_STUB(__imp__EtxProducerRegister); +REX_EXPORT_STUB(__imp__EtxProducerUnregister); +REX_EXPORT_STUB(__imp__EtxConsumerFlushBuffers); +REX_EXPORT_STUB(__imp__EtxProducerLogXwpp); +REX_EXPORT_STUB(__imp__EtxProducerLogXwppV); +REX_EXPORT_STUB(__imp__EtxBufferRegister); +REX_EXPORT_STUB(__imp__EtxBufferUnregister); +REX_EXPORT_STUB(__imp__KeEnablePPUPerformanceMonitor); +REX_EXPORT_STUB(__imp__KeEnterUserMode); +REX_EXPORT_STUB(__imp__KeLeaveUserMode); +REX_EXPORT_STUB(__imp__KeCreateUserMode); +REX_EXPORT_STUB(__imp__KeDeleteUserMode); +REX_EXPORT_STUB(__imp__KeEnablePFMInterrupt); +REX_EXPORT_STUB(__imp__KeDisablePFMInterrupt); +REX_EXPORT_STUB(__imp__KeSetProfilerISR); +REX_EXPORT_STUB(__imp__KeGetVidInfo); +REX_EXPORT_STUB(__imp__KeExecuteOnProtectedStack); +REX_EXPORT_STUB(__imp__EmaExecute); +REX_EXPORT_STUB(__imp__ExRegisterThreadNotification); +REX_EXPORT_STUB(__imp__ExTerminateTitleProcess); +REX_EXPORT_STUB(__imp__ExFreeDebugPool); +REX_EXPORT_STUB(__imp__ExReadModifyWriteXConfigSettingUlong); +REX_EXPORT_STUB(__imp__ExRegisterXConfigNotification); +REX_EXPORT_STUB(__imp__ExCancelAlarm); +REX_EXPORT_STUB(__imp__ExInitializeAlarm); +REX_EXPORT_STUB(__imp__ExSetAlarm); +REX_EXPORT_STUB(__imp__KeBlowFuses); +REX_EXPORT_STUB(__imp__KeGetPMWRegister); +REX_EXPORT_STUB(__imp__KeGetPRVRegister); +REX_EXPORT_STUB(__imp__KeGetSocRegister); +REX_EXPORT_STUB(__imp__KeGetSpecialPurposeRegister); +REX_EXPORT_STUB(__imp__KeSetPMWRegister); +REX_EXPORT_STUB(__imp__KeSetPowerMode); +REX_EXPORT_STUB(__imp__KeSetPRVRegister); +REX_EXPORT_STUB(__imp__KeSetSocRegister); +REX_EXPORT_STUB(__imp__KeSetSpecialPurposeRegister); +REX_EXPORT_STUB(__imp__KeCallAndBlockOnDpcRoutine); +REX_EXPORT_STUB(__imp__KeCallAndWaitForDpcRoutine); +REX_EXPORT_STUB(__imp__KeSetPageRelocationCallback); +REX_EXPORT_STUB(__imp__KeRegisterSwapNotification); + +REX_EXPORT_STUB(__imp__DetroitDeviceRequest); +REX_EXPORT_STUB(__imp__IptvGetAesCtrTransform); +REX_EXPORT_STUB(__imp__IptvGetSessionKeyHash); +REX_EXPORT_STUB(__imp__IptvSetBoundaryKey); +REX_EXPORT_STUB(__imp__IptvSetSessionKey); +REX_EXPORT_STUB(__imp__IptvVerifyOmac1Signature); +REX_EXPORT_STUB(__imp__McaDeviceRequest); +REX_EXPORT_STUB(__imp__MicDeviceRequest); +REX_EXPORT_STUB(__imp__MtpdBeginTransaction); +REX_EXPORT_STUB(__imp__MtpdCancelTransaction); +REX_EXPORT_STUB(__imp__MtpdEndTransaction); +REX_EXPORT_STUB(__imp__MtpdGetCurrentDevices); +REX_EXPORT_STUB(__imp__MtpdReadData); +REX_EXPORT_STUB(__imp__MtpdReadEvent); +REX_EXPORT_STUB(__imp__MtpdResetDevice); +REX_EXPORT_STUB(__imp__MtpdSendData); +REX_EXPORT_STUB(__imp__MtpdVerifyProximity); +REX_EXPORT_STUB(__imp__NicAttach); +REX_EXPORT_STUB(__imp__NicDetach); +REX_EXPORT_STUB(__imp__NicFlushXmitQueue); +REX_EXPORT_STUB(__imp__NicGetLinkState); +REX_EXPORT_STUB(__imp__NicGetOpt); +REX_EXPORT_STUB(__imp__NicGetStats); +REX_EXPORT_STUB(__imp__NicRegisterDevice); +REX_EXPORT_STUB(__imp__NicSetOpt); +REX_EXPORT_STUB(__imp__NicSetUnicastAddress); +REX_EXPORT_STUB(__imp__NicShutdown); +REX_EXPORT_STUB(__imp__NicUnregisterDevice); +REX_EXPORT_STUB(__imp__NicUpdateMcastMembership); +REX_EXPORT_STUB(__imp__NicXmit); +REX_EXPORT_STUB(__imp__NomnilGetExtension); +REX_EXPORT_STUB(__imp__NomnilSetLed); +REX_EXPORT_STUB(__imp__NomnilStartCloseDevice); +REX_EXPORT_STUB(__imp__NullCableRequest); +REX_EXPORT_STUB(__imp__PsCamDeviceRequest); +REX_EXPORT_STUB(__imp__RmcDeviceRequest); +REX_EXPORT_STUB(__imp__TidDeviceRequest); +REX_EXPORT_STUB(__imp__TitleDeviceAuthRequest); +REX_EXPORT_STUB(__imp__UsbdAddDeviceComplete); +REX_EXPORT_STUB(__imp__UsbdCallAndBlockOnDpcRoutine); +REX_EXPORT_STUB(__imp__UsbdCancelAsyncTransfer); +REX_EXPORT_STUB(__imp__UsbdCancelTimer); +REX_EXPORT_STUB(__imp__UsbdEnableDisableRootHubPort); +REX_EXPORT_STUB(__imp__UsbdGetDeviceDescriptor); +REX_EXPORT_STUB(__imp__UsbdGetDeviceRootPortType); +REX_EXPORT_STUB(__imp__UsbdGetDeviceSpeed); +REX_EXPORT_STUB(__imp__UsbdGetDeviceTopology); +REX_EXPORT_STUB(__imp__UsbdGetEndpointDescriptor); +REX_EXPORT_STUB(__imp__UsbdGetNatalHardwareVersion); +REX_EXPORT_STUB(__imp__UsbdGetNatalHub); +REX_EXPORT_STUB(__imp__UsbdGetPortDeviceNode); +REX_EXPORT_STUB(__imp__UsbdGetRequiredDrivers); +REX_EXPORT_STUB(__imp__UsbdGetRootHubDeviceNode); +REX_EXPORT_STUB(__imp__UsbdIsDeviceAuthenticated); +REX_EXPORT_STUB(__imp__UsbdNatalHubRegisterNotificationCallback); +REX_EXPORT_STUB(__imp__UsbdOpenDefaultEndpoint); +REX_EXPORT_STUB(__imp__UsbdOpenEndpoint); +REX_EXPORT_STUB(__imp__UsbdQueueAsyncTransfer); +REX_EXPORT_STUB(__imp__UsbdQueueCloseDefaultEndpoint); +REX_EXPORT_STUB(__imp__UsbdQueueCloseEndpoint); +REX_EXPORT_STUB(__imp__UsbdQueueIsochTransfer); +REX_EXPORT_STUB(__imp__UsbdRegisterDriverObject); +REX_EXPORT_STUB(__imp__UsbdRemoveDeviceComplete); +REX_EXPORT_STUB(__imp__UsbdResetDevice); +REX_EXPORT_STUB(__imp__UsbdResetEndpoint); +REX_EXPORT_STUB(__imp__UsbdSetTimer); +REX_EXPORT_STUB(__imp__UsbdTitleDriverResetAllUnrecognizedPorts); +REX_EXPORT_STUB(__imp__UsbdTitleDriverSetUnrecognizedPort); +REX_EXPORT_STUB(__imp__UsbdUnregisterDriverObject); +REX_EXPORT_STUB(__imp__VeSetHandlers); +REX_EXPORT_STUB(__imp__VgcHandler_SetHandlers); +REX_EXPORT_STUB(__imp__VvcHandlerCancelTransfers); +REX_EXPORT_STUB(__imp__VvcHandlerRetrieveVoiceExtension); +REX_EXPORT_STUB(__imp__WifiBeginAuthentication); +REX_EXPORT_STUB(__imp__WifiCalculateRegulatoryDomain); +REX_EXPORT_STUB(__imp__WifiChannelToFrequency); +REX_EXPORT_STUB(__imp__WifiCheckCounterMeasures); +REX_EXPORT_STUB(__imp__WifiChooseAuthenCipherSetFromBSSID); +REX_EXPORT_STUB(__imp__WifiCompleteAuthentication); +REX_EXPORT_STUB(__imp__WifiDeduceNetworkType); +REX_EXPORT_STUB(__imp__WifiGetAssociationIE); +REX_EXPORT_STUB(__imp__WifiOnMICError); +REX_EXPORT_STUB(__imp__WifiPrepareAuthenticationContext); +REX_EXPORT_STUB(__imp__WifiRecvEAPOLPacket); +REX_EXPORT_STUB(__imp__WifiSelectAdHocChannel); +REX_EXPORT_STUB(__imp__XVoicedActivate); +REX_EXPORT_STUB(__imp__XVoicedClose); +REX_EXPORT_STUB(__imp__XVoicedGetBatteryStatus); +REX_EXPORT_STUB(__imp__XVoicedGetDirectionalData); +REX_EXPORT_STUB(__imp__XVoicedHeadsetPresent); +REX_EXPORT_STUB(__imp__XVoicedIsActiveProcess); +REX_EXPORT_STUB(__imp__XVoicedSendVPort); +REX_EXPORT_STUB(__imp__XVoicedSubmitPacket); diff --git a/src/kernel/xboxkrnl/xboxkrnl_module.cpp b/src/kernel/xboxkrnl/xboxkrnl_module.cpp new file mode 100644 index 0000000..dcb3af6 --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_module.cpp @@ -0,0 +1,263 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(log_high_frequency_kernel_calls, false, "Kernel", + "Log kernel calls with the kHighFrequency tag"); + +REXCVAR_DEFINE_STRING(cl, "", "Kernel", "Specify additional command-line provided to guest"); + +REXCVAR_DEFINE_BOOL(kernel_debug_monitor, false, "Kernel", "Enable debug monitor"); + +REXCVAR_DEFINE_BOOL(kernel_cert_monitor, false, "Kernel", "Enable cert monitor"); + +namespace rex::kernel::xboxkrnl { +using namespace rex::system; + +bool XboxkrnlModule::SendPIXCommand(const char* cmd) { + // TODO: JIT - PIX commands require JIT processor->Execute + // if (!REXCVAR_GET(kernel_pix)) { + // return false; + // } + // ... + (void)cmd; + return false; +} + +XboxkrnlModule::XboxkrnlModule(Runtime* emulator, KernelState* kernel_state) + : KernelModule(kernel_state, "xe:\\xboxkrnl.exe"), timestamp_timer_(nullptr) { + RegisterExportTable(export_resolver_); + + // Register video variable exports (VdGlobalDevice, VdGpuClockInMHz, etc.) + RegisterVideoExports(export_resolver_, kernel_state_); + + // KeDebugMonitorData (?*) + // Set to a valid value when a remote debugger is attached. + // Offset 0x18 is a 4b pointer to a handler function that seems to take two + // arguments. If we wanted to see what would happen we could fake that. + uint32_t pKeDebugMonitorData; + if (!REXCVAR_GET(kernel_debug_monitor)) { + pKeDebugMonitorData = memory_->SystemHeapAlloc(4); + auto lpKeDebugMonitorData = memory_->TranslateVirtual(pKeDebugMonitorData); + memory::store_and_swap(lpKeDebugMonitorData, 0); + } else { + pKeDebugMonitorData = memory_->SystemHeapAlloc(4 + sizeof(X_KEDEBUGMONITORDATA)); + memory::store_and_swap(memory_->TranslateVirtual(pKeDebugMonitorData), + pKeDebugMonitorData + 4); + auto lpKeDebugMonitorData = + memory_->TranslateVirtual(pKeDebugMonitorData + 4); + std::memset(lpKeDebugMonitorData, 0, sizeof(X_KEDEBUGMONITORDATA)); + // TODO: JIT - GenerateTrampoline requires JIT + // lpKeDebugMonitorData->callback_fn = + // GenerateTrampoline("KeDebugMonitorCallback", KeDebugMonitorCallback); + } + export_resolver_->SetVariableMapping("xboxkrnl.exe", 0x0059, pKeDebugMonitorData); + + // KeCertMonitorData (?*) + // Always set to zero, ignored. + uint32_t pKeCertMonitorData; + if (!REXCVAR_GET(kernel_cert_monitor)) { + pKeCertMonitorData = memory_->SystemHeapAlloc(4); + auto lpKeCertMonitorData = memory_->TranslateVirtual(pKeCertMonitorData); + memory::store_and_swap(lpKeCertMonitorData, 0); + } else { + pKeCertMonitorData = memory_->SystemHeapAlloc(4 + sizeof(X_KECERTMONITORDATA)); + memory::store_and_swap(memory_->TranslateVirtual(pKeCertMonitorData), + pKeCertMonitorData + 4); + auto lpKeCertMonitorData = + memory_->TranslateVirtual(pKeCertMonitorData + 4); + std::memset(lpKeCertMonitorData, 0, sizeof(X_KECERTMONITORDATA)); + // TODO: JIT - GenerateTrampoline requires JIT + // lpKeCertMonitorData->callback_fn = + // GenerateTrampoline("KeCertMonitorCallback", KeCertMonitorCallback); + } + export_resolver_->SetVariableMapping("xboxkrnl.exe", 0x0266, pKeCertMonitorData); + + // XboxHardwareInfo (XboxHardwareInfo_t, 16b) + // flags cpu# ? ? ? ? ? ? + // 0x00000000, 0x06, 0x00, 0x00, 0x00, 0x00000000, 0x0000, 0x0000 + // Games seem to check if bit 26 (0x20) is set, which at least for xbox1 + // was whether an HDD was present. Not sure what the other flags are. + // + // aomega08 says the value is 0x02000817, bit 27: debug mode on. + // When that is set, though, allocs crash in weird ways. + // + // From kernel dissasembly, after storage is initialized + // XboxHardwareInfo flags is set with flag 5 (0x20). + uint32_t pXboxHardwareInfo = memory_->SystemHeapAlloc(16); + auto lpXboxHardwareInfo = memory_->TranslateVirtual(pXboxHardwareInfo); + export_resolver_->SetVariableMapping("xboxkrnl.exe", 0x0156, pXboxHardwareInfo); + memory::store_and_swap(lpXboxHardwareInfo + 0, 0x20); // flags + memory::store_and_swap(lpXboxHardwareInfo + 4, 0x06); // cpu count + // Remaining 11b are zeroes? + + // ExConsoleGameRegion, probably same values as keyvault region uses? + // Just return all 0xFF, should satisfy anything that checks it + uint32_t pExConsoleGameRegion = memory_->SystemHeapAlloc(4); + auto lpExConsoleGameRegion = memory_->TranslateVirtual(pExConsoleGameRegion); + export_resolver_->SetVariableMapping("xboxkrnl.exe", 0x000C, pExConsoleGameRegion); + memory::store(lpExConsoleGameRegion, 0xFFFFFFFF); + + // XexExecutableModuleHandle (?**) + // Games try to dereference this to get a pointer to some module struct. + // So far it seems like it's just in loader code, and only used to look up + // the XexHeaderBase for use by RtlImageXexHeaderField. + // We fake it so that the address passed to that looks legit. + // 0x80100FFC <- pointer to structure + // 0x80101000 <- our module structure + // 0x80101058 <- pointer to xex header + // 0x80101100 <- xex header base + uint32_t ppXexExecutableModuleHandle = memory_->SystemHeapAlloc(4); + export_resolver_->SetVariableMapping("xboxkrnl.exe", 0x0193, ppXexExecutableModuleHandle); + + // ExLoadedImageName (char*) + // The full path to loaded image/xex including its name. + // Used usually in custom dashboards (Aurora) + // Todo(Gliniak): Confirm that official kernel always allocate space for this + // variable. + uint32_t ppExLoadedImageName = memory_->SystemHeapAlloc(kExLoadedImageNameSize); + export_resolver_->SetVariableMapping("xboxkrnl.exe", 0x01AF, ppExLoadedImageName); + + // ExLoadedCommandLine (char*) + // The name of the xex. Not sure this is ever really used on real devices. + // Perhaps it's how swap disc/etc data is sent? + // Always set to "default.xex" (with quotes) for now. + // TODO(gibbed): set this to the actual module name. + std::string command_line("\"default.xex\""); + if (!REXCVAR_GET(cl).empty()) { + command_line += " " + REXCVAR_GET(cl); + } + uint32_t command_line_length = + rex::align(static_cast(command_line.length()) + 1, 1024u); + uint32_t pExLoadedCommandLine = memory_->SystemHeapAlloc(command_line_length); + auto lpExLoadedCommandLine = memory_->TranslateVirtual(pExLoadedCommandLine); + export_resolver_->SetVariableMapping("xboxkrnl.exe", 0x01AE, pExLoadedCommandLine); + std::memset(lpExLoadedCommandLine, 0, command_line_length); + std::memcpy(lpExLoadedCommandLine, command_line.c_str(), command_line.length()); + + // XboxKrnlVersion (8b) + // Kernel version, looks like 2b.2b.2b.2b. + // I've only seen games check >=, so we just fake something here. + uint32_t pXboxKrnlVersion = memory_->SystemHeapAlloc(8); + auto lpXboxKrnlVersion = memory_->TranslateVirtual(pXboxKrnlVersion); + export_resolver_->SetVariableMapping("xboxkrnl.exe", 0x0158, pXboxKrnlVersion); + memory::store_and_swap(lpXboxKrnlVersion + 0, 2); + memory::store_and_swap(lpXboxKrnlVersion + 2, 0xFFFF); + memory::store_and_swap(lpXboxKrnlVersion + 4, 0xFFFF); + memory::store_and_swap(lpXboxKrnlVersion + 6, 0x80); + memory::store_and_swap(lpXboxKrnlVersion + 7, 0x00); + + // KeTimeStampBundle (24b) + // This must be updated during execution, at 1ms intevals. + // We setup a system timer here to do that. + uint32_t pKeTimeStampBundle = memory_->SystemHeapAlloc(24); + auto lpKeTimeStampBundle = memory_->TranslateVirtual(pKeTimeStampBundle); + export_resolver_->SetVariableMapping("xboxkrnl.exe", 0x00AD, pKeTimeStampBundle); + memory::store_and_swap(lpKeTimeStampBundle + 0, 0); + memory::store_and_swap(lpKeTimeStampBundle + 8, 0); + memory::store_and_swap(lpKeTimeStampBundle + 16, + chrono::Clock::QueryGuestUptimeMillis()); + memory::store_and_swap(lpKeTimeStampBundle + 20, 0); + timestamp_timer_ = rex::thread::HighResolutionTimer::CreateRepeating( + std::chrono::milliseconds(1), [lpKeTimeStampBundle]() { + memory::store_and_swap(lpKeTimeStampBundle + 16, + chrono::Clock::QueryGuestUptimeMillis()); + }); + + // Wire kernel object type variables to KernelGuestGlobals. + // KernelGuestGlobals is allocated in KernelState ctor, which runs before this. + auto kgg = kernel_state_->GetKernelGuestGlobals(); + assert_not_zero(kgg); + export_resolver_->SetVariableMapping("xboxkrnl.exe", 0x001B, + kgg + offsetof(KernelGuestGlobals, ExThreadObjectType)); + export_resolver_->SetVariableMapping("xboxkrnl.exe", 0x000E, + kgg + offsetof(KernelGuestGlobals, ExEventObjectType)); + export_resolver_->SetVariableMapping("xboxkrnl.exe", 0x0012, + kgg + offsetof(KernelGuestGlobals, ExMutantObjectType)); + export_resolver_->SetVariableMapping("xboxkrnl.exe", 0x0017, + kgg + offsetof(KernelGuestGlobals, ExSemaphoreObjectType)); + export_resolver_->SetVariableMapping("xboxkrnl.exe", 0x001C, + kgg + offsetof(KernelGuestGlobals, ExTimerObjectType)); + export_resolver_->SetVariableMapping("xboxkrnl.exe", 0x0036, + kgg + offsetof(KernelGuestGlobals, IoCompletionObjectType)); + export_resolver_->SetVariableMapping("xboxkrnl.exe", 0x003A, + kgg + offsetof(KernelGuestGlobals, IoDeviceObjectType)); + export_resolver_->SetVariableMapping("xboxkrnl.exe", 0x003E, + kgg + offsetof(KernelGuestGlobals, IoFileObjectType)); + export_resolver_->SetVariableMapping("xboxkrnl.exe", 0x0106, + kgg + offsetof(KernelGuestGlobals, ObDirectoryObjectType)); + export_resolver_->SetVariableMapping( + "xboxkrnl.exe", 0x0112, kgg + offsetof(KernelGuestGlobals, ObSymbolicLinkObjectType)); + export_resolver_->SetVariableMapping( + "xboxkrnl.exe", 0x02DB, kgg + offsetof(KernelGuestGlobals, UsbdBootEnumerationDoneEvent)); +} + +static auto& get_xboxkrnl_exports() { + static std::vector xboxkrnl_exports(4096); + return xboxkrnl_exports; +} + +rex::runtime::Export* RegisterExport_xboxkrnl(rex::runtime::Export* export_entry) { + auto& xboxkrnl_exports = get_xboxkrnl_exports(); + assert_true(export_entry->ordinal < xboxkrnl_exports.size()); + xboxkrnl_exports[export_entry->ordinal] = export_entry; + return export_entry; +} + +void XboxkrnlModule::RegisterExportTable(rex::runtime::ExportResolver* export_resolver) { + assert_not_null(export_resolver); + +// Build the export table used for resolution. +#include "../export_table_pre.inc" + static rex::runtime::Export xboxkrnl_export_table[] = { +#include "export_table.inc" + }; +#include "../export_table_post.inc" + auto& xboxkrnl_exports = get_xboxkrnl_exports(); + for (size_t i = 0; i < rex::countof(xboxkrnl_export_table); ++i) { + auto& export_entry = xboxkrnl_export_table[i]; + assert_true(export_entry.ordinal < xboxkrnl_exports.size()); + if (!xboxkrnl_exports[export_entry.ordinal]) { + xboxkrnl_exports[export_entry.ordinal] = &export_entry; + } + } + export_resolver->RegisterTable("xboxkrnl.exe", &xboxkrnl_exports); +} + +XboxkrnlModule::~XboxkrnlModule() = default; + +} // namespace rex::kernel::xboxkrnl diff --git a/src/kernel/xboxkrnl/xboxkrnl_modules.cpp b/src/kernel/xboxkrnl/xboxkrnl_modules.cpp new file mode 100644 index 0000000..dcd2001 --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_modules.cpp @@ -0,0 +1,264 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { +using namespace rex::system; + +u32 XexCheckExecutablePrivilege_entry(u32 privilege) { + REXKRNL_IMPORT_TRACE("XexCheckExecutablePrivilege", "priv={}", (uint32_t)privilege); + // BOOL + // DWORD Privilege + + // Privilege is bit position in xe_xex2_system_flags enum - so: + // Privilege=6 -> 0x00000040 -> XEX_SYSTEM_INSECURE_SOCKETS + uint32_t mask = 1 << privilege; + + auto module = REX_KERNEL_STATE()->GetExecutableModule(); + if (!module) { + return 0; + } + + uint32_t flags = 0; + module->GetOptHeader(XEX_HEADER_SYSTEM_FLAGS, &flags); + + return (flags & mask) > 0; +} + +u32 XexGetModuleHandle_entry(mapped_string module_name, mapped_u32 hmodule_ptr) { + object_ref module; + + if (!module_name) { + module = REX_KERNEL_STATE()->GetExecutableModule(); + } else { + module = REX_KERNEL_STATE()->GetModule(module_name.value()); + } + + if (!module) { + *hmodule_ptr = 0; + return X_ERROR_NOT_FOUND; + } + + // NOTE: we don't retain the handle for return. + *hmodule_ptr = module->hmodule_ptr(); + + return X_ERROR_SUCCESS; +} + +u32 XexGetModuleSection_entry(mapped_void hmodule, mapped_string name, mapped_u32 data_ptr, + mapped_u32 size_ptr) { + X_STATUS result = X_STATUS_SUCCESS; + + auto module = XModule::GetFromHModule(REX_KERNEL_STATE(), hmodule); + if (module) { + uint32_t section_data = 0; + uint32_t section_size = 0; + result = module->GetSection(name.value(), §ion_data, §ion_size); + if (XSUCCEEDED(result)) { + *data_ptr = section_data; + *size_ptr = section_size; + } + } else { + result = X_STATUS_INVALID_HANDLE; + } + + return result; +} + +u32 XexLoadImage_entry(mapped_string module_name, u32 module_flags, u32 min_version, + mapped_u32 hmodule_ptr) { + X_STATUS result = X_STATUS_NO_SUCH_FILE; + + uint32_t hmodule = 0; + { + // Lookup + load_count++ must be atomic vs XexUnloadImage to prevent + // resurrecting a module between the read of hmodule and the increment. + // The fresh-load path can't share this lock: LoadUserModule runs + // DllMain ATTACH outside the global lock by design. + auto lock = rex::thread::global_critical_region::AcquireDirect(); + auto module = REX_KERNEL_STATE()->GetModule(module_name.value()); + if (module) { + hmodule = module->hmodule_ptr(); + auto ldr_data = REX_KERNEL_MEMORY()->TranslateVirtual(hmodule); + ldr_data->load_count++; + result = X_STATUS_SUCCESS; + } + } + + if (!hmodule) { + auto user_module = REX_KERNEL_STATE()->LoadUserModule(module_name.value()); + if (user_module) { + // Released by the last XexUnloadImage call. + auto user_module_raw = user_module.release(); + hmodule = user_module_raw->hmodule_ptr(); + auto lock = rex::thread::global_critical_region::AcquireDirect(); + auto ldr_data = REX_KERNEL_MEMORY()->TranslateVirtual(hmodule); + ldr_data->load_count++; + result = X_STATUS_SUCCESS; + } + } + + *hmodule_ptr = hmodule; + + return result; +} + +u32 XexUnloadImage_entry(mapped_void hmodule) { + auto module = XModule::GetFromHModule(REX_KERNEL_STATE(), hmodule); + if (!module) { + return X_STATUS_INVALID_HANDLE; + } + if (module->module_type() == XModule::ModuleType::kKernelModule) { + return X_STATUS_SUCCESS; + } + + // Decrement-and-check under the global lock so concurrent unloads can't both + // observe zero and double-free. + bool last_ref; + { + auto lock = rex::thread::global_critical_region::AcquireDirect(); + auto ldr_data = hmodule.as(); + last_ref = (--ldr_data->load_count == 0); + } + + if (last_ref) { + module->Release(); + REX_KERNEL_STATE()->UnloadUserModule( + object_ref(reinterpret_cast(module.release()))); + } + + return X_STATUS_SUCCESS; +} + +u32 XexGetProcedureAddress_entry(mapped_void hmodule, u32 ordinal, mapped_u32 out_function_ptr) { + // May be entry point? + assert_not_zero(ordinal); + + uint32_t caller_address = 0; + auto* thread = XThread::GetCurrentThread(); + if (thread && thread->thread_state() && thread->thread_state()->context()) { + caller_address = static_cast(thread->thread_state()->context()->lr); + } + + bool is_string_name = (ordinal & 0xFFFF0000) != 0; + auto string_name = reinterpret_cast(REX_KERNEL_MEMORY()->TranslateVirtual(ordinal)); + + X_STATUS result = X_STATUS_INVALID_HANDLE; + + object_ref module; + if (!hmodule) { + module = REX_KERNEL_STATE()->GetExecutableModule(); + } else { + module = XModule::GetFromHModule(REX_KERNEL_STATE(), hmodule); + } + if (module) { + uint32_t ptr; + if (is_string_name) { + ptr = module->GetProcAddressByName(string_name); + } else { + ptr = module->GetProcAddressByOrdinal(ordinal, caller_address); + } + if (ptr) { + *out_function_ptr = ptr; + result = X_STATUS_SUCCESS; + } else { + if (is_string_name) { + REXKRNL_WARN("ERROR: XexGetProcedureAddress export '{}' in '{}' not found!", string_name, + module->name()); + } else { + REXKRNL_WARN( + "ERROR: XexGetProcedureAddress ordinal {} (0x{:X}) in '{}' not " + "found!", + ordinal, ordinal, module->name()); + } + *out_function_ptr = 0; + result = X_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND; + } + } + + return result; +} + +void ExRegisterTitleTerminateNotification_entry(ppc_ptr_t reg, + u32 create) { + if (create) { + // Adding. + REX_KERNEL_STATE()->RegisterTitleTerminateNotification(reg->notification_routine, + reg->priority); + } else { + // Removing. + REX_KERNEL_STATE()->RemoveTitleTerminateNotification(reg->notification_routine); + } +} + +u32 XexLoadImageHeaders_entry(mapped_string path, mapped_void headers) { + REXKRNL_DEBUG("XexLoadImageHeaders({}) - stub", path.value()); + return X_STATUS_NOT_IMPLEMENTED; +} + +} // namespace rex::kernel::xboxkrnl + +REX_EXPORT(__imp__XexCheckExecutablePrivilege, + rex::kernel::xboxkrnl::XexCheckExecutablePrivilege_entry) +REX_EXPORT(__imp__XexGetModuleHandle, rex::kernel::xboxkrnl::XexGetModuleHandle_entry) +REX_EXPORT(__imp__XexGetModuleSection, rex::kernel::xboxkrnl::XexGetModuleSection_entry) +REX_EXPORT(__imp__XexLoadImage, rex::kernel::xboxkrnl::XexLoadImage_entry) +REX_EXPORT(__imp__XexUnloadImage, rex::kernel::xboxkrnl::XexUnloadImage_entry) +REX_EXPORT(__imp__XexGetProcedureAddress, rex::kernel::xboxkrnl::XexGetProcedureAddress_entry) +REX_EXPORT(__imp__ExRegisterTitleTerminateNotification, + rex::kernel::xboxkrnl::ExRegisterTitleTerminateNotification_entry) +REX_EXPORT(__imp__XexLoadImageHeaders, rex::kernel::xboxkrnl::XexLoadImageHeaders_entry) + +REX_EXPORT_STUB(__imp__XexLoadExecutable); +REX_EXPORT_STUB(__imp__XexLoadImageFromMemory); +REX_EXPORT_STUB(__imp__XexPcToFileHeader); +REX_EXPORT_STUB(__imp__XexRegisterPatchDescriptor); +REX_EXPORT_STUB(__imp__XexSendDeferredNotifications); +REX_EXPORT_STUB(__imp__XexStartExecutable); +REX_EXPORT_STUB(__imp__XexUnloadImageAndExitThread); +REX_EXPORT_STUB(__imp__XexUnloadTitleModules); +REX_EXPORT_STUB(__imp__XexVerifyImageHeaders); +REX_EXPORT_STUB(__imp__XexGetModuleImportVersions); +REX_EXPORT_STUB(__imp__XexActivationGetNonce); +REX_EXPORT_STUB(__imp__XexActivationSetLicense); +REX_EXPORT_STUB(__imp__XexActivationVerifyOwnership); +REX_EXPORT_STUB(__imp__XexDisableVerboseDbgPrint); +REX_EXPORT_STUB(__imp__XexImportTraceEnable); +REX_EXPORT_STUB(__imp__XexSetExecutablePrivilege); +REX_EXPORT_STUB(__imp__XexSetLastKdcTime); +REX_EXPORT_STUB(__imp__XexTransformImageKey); +REX_EXPORT_STUB(__imp__XexShimDisable); +REX_EXPORT_STUB(__imp__XexShimEnable); +REX_EXPORT_STUB(__imp__XexShimEntryDisable); +REX_EXPORT_STUB(__imp__XexShimEntryEnable); +REX_EXPORT_STUB(__imp__XexShimEntryRegister); +REX_EXPORT_STUB(__imp__XexShimLock); +REX_EXPORT_STUB(__imp__XexTitleHash); +REX_EXPORT_STUB(__imp__XexTitleHashClose); +REX_EXPORT_STUB(__imp__XexTitleHashContinue); +REX_EXPORT_STUB(__imp__XexTitleHashOpen); +REX_EXPORT_STUB(__imp__XexReserveCodeBuffer); +REX_EXPORT_STUB(__imp__XexCommitCodeBuffer); +REX_EXPORT_STUB(__imp__XexRegisterUsermodeModule); +REX_EXPORT_STUB(__imp__LDICreateDecompression); +REX_EXPORT_STUB(__imp__LDIDecompress); +REX_EXPORT_STUB(__imp__LDIDestroyDecompression); +REX_EXPORT_STUB(__imp__LDIResetDecompression); diff --git a/src/kernel/xboxkrnl/xboxkrnl_ob.cpp b/src/kernel/xboxkrnl/xboxkrnl_ob.cpp new file mode 100644 index 0000000..5709e6d --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_ob.cpp @@ -0,0 +1,275 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { +using namespace rex::system; + +u32 ObOpenObjectByName_entry(mapped_void obj_attributes_ptr, mapped_void object_type_ptr, u32 unk, + mapped_u32 handle_ptr) { + // r3 = ptr to info? + // +0 = -4 + // +4 = name ptr + // +8 = 0 + // r4 = ExEventObjectType | ExSemaphoreObjectType | ExTimerObjectType + // r5 = 0 + // r6 = out_ptr (handle?) + + if (!obj_attributes_ptr) { + return X_STATUS_INVALID_PARAMETER; + } + + auto obj_attributes = REX_KERNEL_MEMORY()->TranslateVirtual( + obj_attributes_ptr.guest_address()); + assert_true(obj_attributes->name_ptr != 0); + auto name = util::TranslateAnsiStringAddress(REX_KERNEL_MEMORY(), obj_attributes->name_ptr); + + X_HANDLE handle = X_INVALID_HANDLE_VALUE; + X_STATUS result = REX_KERNEL_OBJECTS()->GetObjectByName(name, &handle); + if (XSUCCEEDED(result)) { + *handle_ptr = handle; + } + + return result; +} + +u32 ObOpenObjectByPointer_entry(mapped_void object_ptr, mapped_u32 out_handle_ptr) { + auto object = XObject::GetNativeObject(REX_KERNEL_STATE(), object_ptr); + if (!object) { + return X_STATUS_UNSUCCESSFUL; + } + + // Retain the handle. Will be released in NtClose. + object->RetainHandle(); + *out_handle_ptr = object->handle(); + return X_STATUS_SUCCESS; +} + +u32 ObLookupThreadByThreadId_entry(u32 thread_id, mapped_u32 out_object_ptr) { + auto thread = REX_KERNEL_STATE()->GetThreadByID(thread_id); + if (!thread) { + return X_STATUS_NOT_FOUND; + } + + // Retain the object. Will be released in ObDereferenceObject. + thread->RetainHandle(); + *out_object_ptr = thread->guest_object(); + return X_STATUS_SUCCESS; +} + +u32 ObReferenceObjectByHandle_entry(u32 handle, u32 object_type_ptr, mapped_u32 out_object_ptr) { + REXKRNL_IMPORT_TRACE("ObReferenceObjectByHandle", "handle={:#x} type={:#x}", (uint32_t)handle, + (uint32_t)object_type_ptr); + + object_ref object; + + // Handle pseudo-handles. + uint32_t handle_val = static_cast(handle); + if (handle_val == 0xFFFFFFFE) { + // CurrentThread pseudo-handle. + auto thread = XThread::GetCurrentThread(); + if (!thread) { + return X_STATUS_INVALID_HANDLE; + } + object = retain_object(static_cast(thread)); + } else { + object = REX_KERNEL_OBJECTS()->LookupObject(handle); + } + + if (!object) { + return X_STATUS_INVALID_HANDLE; + } + + uint32_t native_ptr = object->guest_object(); + + // Type check using real KernelGuestGlobals addresses. + if (object_type_ptr) { + uint32_t globals_base = REX_KERNEL_STATE()->GetKernelGuestGlobals(); + uint32_t expected_type = 0; + switch (object->type()) { + case XObject::Type::Thread: + expected_type = globals_base + offsetof(KernelGuestGlobals, ExThreadObjectType); + break; + case XObject::Type::Event: + expected_type = globals_base + offsetof(KernelGuestGlobals, ExEventObjectType); + break; + case XObject::Type::Mutant: + expected_type = globals_base + offsetof(KernelGuestGlobals, ExMutantObjectType); + break; + case XObject::Type::Semaphore: + expected_type = globals_base + offsetof(KernelGuestGlobals, ExSemaphoreObjectType); + break; + case XObject::Type::Timer: + expected_type = globals_base + offsetof(KernelGuestGlobals, ExTimerObjectType); + break; + default: + break; + } + if (expected_type && object_type_ptr != expected_type) { + return X_STATUS_OBJECT_TYPE_MISMATCH; + } + } + + // Caller takes the reference. + // It's released in ObDereferenceObject. + object->RetainHandle(); + if (out_object_ptr.guest_address()) { + *out_object_ptr = native_ptr; + } + REXKRNL_IMPORT_RESULT("ObReferenceObjectByHandle", "0x0 obj={:#x}", native_ptr); + return X_STATUS_SUCCESS; +} + +u32 ObReferenceObjectByName_entry(mapped_string name, u32 attributes, u32 object_type_ptr, + mapped_void parse_context, mapped_u32 out_object_ptr) { + X_HANDLE handle = X_INVALID_HANDLE_VALUE; + X_STATUS result = REX_KERNEL_OBJECTS()->GetObjectByName(name.value(), &handle); + if (XSUCCEEDED(result)) { + return ObReferenceObjectByHandle_entry(handle, object_type_ptr, out_object_ptr); + } + + return result; +} + +u32 ObDereferenceObject_entry(u32 native_ptr) { + REXKRNL_IMPORT_TRACE("ObDereferenceObject", "ptr={:#x}", (uint32_t)native_ptr); + // Check if a dummy value from ObReferenceObjectByHandle. + if (native_ptr == 0xDEADF00D) { + return 0; + } + + auto object = XObject::GetNativeObject( + REX_KERNEL_STATE(), REX_KERNEL_MEMORY()->TranslateVirtual(native_ptr)); + if (object) { + object->ReleaseHandle(); + } + + return 0; +} + +u32 ObCreateSymbolicLink_entry(ppc_ptr_t path_ptr, + ppc_ptr_t target_ptr) { + auto path = rex::string::utf8_canonicalize_guest_path( + util::TranslateAnsiPath(REX_KERNEL_MEMORY(), path_ptr)); + auto target = rex::string::utf8_canonicalize_guest_path( + util::TranslateAnsiPath(REX_KERNEL_MEMORY(), target_ptr)); + + if (rex::string::utf8_starts_with(path, u8"\\??\\")) { + path = path.substr(4); // Strip the full qualifier + } + + if (!REX_KERNEL_FS()->RegisterSymbolicLink(path, target)) { + return X_STATUS_UNSUCCESSFUL; + } + + return X_STATUS_SUCCESS; +} + +u32 ObDeleteSymbolicLink_entry(ppc_ptr_t path_ptr) { + auto path = util::TranslateAnsiPath(REX_KERNEL_MEMORY(), path_ptr); + if (!REX_KERNEL_FS()->UnregisterSymbolicLink(path)) { + return X_STATUS_UNSUCCESSFUL; + } + + return X_STATUS_SUCCESS; +} + +u32 NtDuplicateObject_entry(u32 handle, mapped_u32 new_handle_ptr, u32 options) { + // NOTE: new_handle_ptr can be zero to just close a handle. + // NOTE: this function seems to be used to get the current thread handle + // (passed handle=-2). + // This function actually just creates a new handle to the same object. + // Most games use it to get real handles to the current thread or whatever. + + X_HANDLE new_handle = X_INVALID_HANDLE_VALUE; + X_STATUS result = REX_KERNEL_OBJECTS()->DuplicateHandle(handle, &new_handle); + + if (new_handle_ptr) { + *new_handle_ptr = new_handle; + } + + if (options == 1 /* DUPLICATE_CLOSE_SOURCE */) { + // Always close the source object. + REX_KERNEL_OBJECTS()->RemoveHandle(handle); + } + + return result; +} + +u32 NtClose_entry(u32 handle) { + REXKRNL_IMPORT_TRACE("NtClose", "handle={:#x}", (uint32_t)handle); + auto result = REX_KERNEL_OBJECTS()->ReleaseHandle(handle); + REXKRNL_IMPORT_RESULT("NtClose", "{:#x}", result); + return result; +} + +u32 NtQueryEvent_entry(u32 handle, mapped_u32 out_struc) { + X_STATUS result = X_STATUS_SUCCESS; + + auto ev = REX_KERNEL_OBJECTS()->LookupObject(handle); + if (ev) { + uint32_t type_tmp, state_tmp; + ev->Query(&type_tmp, &state_tmp); + out_struc[0] = type_tmp; + out_struc[1] = state_tmp; + } else { + result = X_STATUS_INVALID_HANDLE; + } + + return result; +} + +} // namespace rex::kernel::xboxkrnl + +REX_EXPORT(__imp__ObOpenObjectByName, rex::kernel::xboxkrnl::ObOpenObjectByName_entry) +REX_EXPORT(__imp__ObOpenObjectByPointer, rex::kernel::xboxkrnl::ObOpenObjectByPointer_entry) +REX_EXPORT(__imp__ObLookupThreadByThreadId, rex::kernel::xboxkrnl::ObLookupThreadByThreadId_entry) +REX_EXPORT(__imp__ObReferenceObjectByHandle, rex::kernel::xboxkrnl::ObReferenceObjectByHandle_entry) +REX_EXPORT(__imp__ObReferenceObjectByName, rex::kernel::xboxkrnl::ObReferenceObjectByName_entry) +REX_EXPORT(__imp__ObDereferenceObject, rex::kernel::xboxkrnl::ObDereferenceObject_entry) +REX_EXPORT(__imp__ObCreateSymbolicLink, rex::kernel::xboxkrnl::ObCreateSymbolicLink_entry) +REX_EXPORT(__imp__ObDeleteSymbolicLink, rex::kernel::xboxkrnl::ObDeleteSymbolicLink_entry) +REX_EXPORT(__imp__NtDuplicateObject, rex::kernel::xboxkrnl::NtDuplicateObject_entry) +REX_EXPORT(__imp__NtClose, rex::kernel::xboxkrnl::NtClose_entry) +REX_EXPORT(__imp__NtQueryEvent, rex::kernel::xboxkrnl::NtQueryEvent_entry) + +REX_EXPORT_STUB(__imp__ObCreateObject); +REX_EXPORT_STUB(__imp__ObGetWaitableObject); +REX_EXPORT_STUB(__imp__ObInsertObject); +REX_EXPORT_STUB(__imp__ObIsTitleObject); +REX_EXPORT_STUB(__imp__ObLookupAnyThreadByThreadId); +REX_EXPORT_STUB(__imp__ObMakeTemporaryObject); +REX_EXPORT_STUB(__imp__ObReferenceObject); +REX_EXPORT_STUB(__imp__ObTranslateSymbolicLink); +REX_EXPORT_STUB(__imp__NtCreateDirectoryObject); +REX_EXPORT_STUB(__imp__NtCreateSymbolicLinkObject); +REX_EXPORT_STUB(__imp__NtMakeTemporaryObject); +REX_EXPORT_STUB(__imp__NtOpenDirectoryObject); +REX_EXPORT_STUB(__imp__NtQueryDirectoryObject); +REX_EXPORT_STUB(__imp__NtQueryIoCompletion); +REX_EXPORT_STUB(__imp__NtQueryMutant); +REX_EXPORT_STUB(__imp__NtQuerySemaphore); +REX_EXPORT_STUB(__imp__NtQueryTimer); diff --git a/src/kernel/xboxkrnl/xboxkrnl_rtl.cpp b/src/kernel/xboxkrnl/xboxkrnl_rtl.cpp new file mode 100644 index 0000000..8b862fc --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_rtl.cpp @@ -0,0 +1,630 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { +using namespace rex::system; + +// https://msdn.microsoft.com/en-us/library/ff561778 +u32 RtlCompareMemory_entry(mapped_void source1, mapped_void source2, u32 length) { + uint8_t* p1 = source1; + uint8_t* p2 = source2; + + // Note that the return value is the number of bytes that match, so it's best + // we just do this ourselves vs. using memcmp. + // On Windows we could use the builtin function. + + uint32_t c = 0; + for (uint32_t n = 0; n < length; n++, p1++, p2++) { + if (*p1 == *p2) { + c++; + } + } + + return c; +} + +// https://msdn.microsoft.com/en-us/library/ff552123 +u32 RtlCompareMemoryUlong_entry(mapped_void source, u32 length, u32 pattern) { + // Return 0 if source/length not aligned + if (source.guest_address() % 4 || length % 4) { + return 0; + } + + uint32_t n = 0; + for (uint32_t i = 0; i < (length / 4); i++) { + // FIXME: This assumes as_array returns rex::be + uint32_t val = source.as_array()[i]; + if (val == pattern) { + n++; + } + } + + return n; +} + +// https://msdn.microsoft.com/en-us/library/ff552263 +void RtlFillMemoryUlong_entry(mapped_void destination, u32 length, u32 pattern) { + // NOTE: length must be % 4, so we can work on uint32s. + uint32_t count = length >> 2; + + uint32_t* p = destination.as(); + uint32_t swapped_pattern = rex::byte_swap(pattern); + for (uint32_t n = 0; n < count; n++, p++) { + *p = swapped_pattern; + } +} + +u32 RtlUpperChar_entry(u32 in) { + char c = in & 0xFF; + if (c >= 'a' && c <= 'z') { + return c ^ 0x20; + } + + return c; +} + +u32 RtlLowerChar_entry(u32 in) { + char c = in & 0xFF; + if (c >= 'A' && c <= 'Z') { + return c ^ 0x20; + } + + return c; +} + +u32 RtlCompareString_entry(mapped_string string_1, mapped_string string_2, u32 case_insensitive) { + int ret = case_insensitive ? rex::string::compare_case(string_1, string_2) + : std::strcmp(string_1, string_2); + + return ret; +} + +u32 RtlCompareStringN_entry(mapped_string string_1, u32 string_1_len, mapped_string string_2, + u32 string_2_len, u32 case_insensitive) { + uint32_t len1 = string_1_len; + uint32_t len2 = string_2_len; + + if (string_1_len == 0xFFFF) { + len1 = uint32_t(std::strlen(string_1)); + } + if (string_2_len == 0xFFFF) { + len2 = uint32_t(std::strlen(string_2)); + } + auto len = std::min(string_1_len, string_2_len); + + int ret = case_insensitive ? rex::string::compare_case_n(string_1, string_2, len) + : std::strncmp(string_1, string_2, len); + + return ret; +} + +// https://msdn.microsoft.com/en-us/library/ff561918 +void RtlInitAnsiString_entry(ppc_ptr_t destination, mapped_string source) { + REXKRNL_IMPORT_TRACE("RtlInitAnsiString", "str={}", source ? source.value() : "(null)"); + if (source) { + uint16_t length = (uint16_t)strlen(source); + destination->length = length; + destination->maximum_length = length + 1; + } else { + destination->reset(); + } + + destination->pointer = source.guest_address(); +} + +// https://msdn.microsoft.com/en-us/library/ff561899 +void RtlFreeAnsiString_entry(ppc_ptr_t string) { + if (string->pointer) { + REX_KERNEL_MEMORY()->SystemHeapFree(string->pointer); + } + + string->reset(); +} + +// https://msdn.microsoft.com/en-us/library/ff561934 +void RtlInitUnicodeString_entry(ppc_ptr_t destination, mapped_wstring source) { + if (source) { + destination->length = (uint16_t)source.value().size() * 2; + destination->maximum_length = (uint16_t)(source.value().size() + 1) * 2; + destination->pointer = source.guest_address(); + } else { + destination->reset(); + } +} + +// https://msdn.microsoft.com/en-us/library/ff561903 +void RtlFreeUnicodeString_entry(ppc_ptr_t string) { + if (string->pointer) { + REX_KERNEL_MEMORY()->SystemHeapFree(string->pointer); + } + + string->reset(); +} + +void RtlCopyString_entry(ppc_ptr_t destination, ppc_ptr_t source) { + if (!source) { + destination->length = 0; + return; + } + + auto length = std::min(destination->maximum_length, source->length); + if (length > 0) { + auto dst_buf = REX_KERNEL_MEMORY()->TranslateVirtual(destination->pointer); + auto src_buf = REX_KERNEL_MEMORY()->TranslateVirtual(source->pointer); + std::memcpy(dst_buf, src_buf, length); + } + destination->length = length; +} + +void RtlCopyUnicodeString_entry(ppc_ptr_t destination, + ppc_ptr_t source) { + if (!source) { + destination->length = 0; + return; + } + + auto length = std::min(destination->maximum_length, source->length); + if (length > 0) { + auto dst_buf = REX_KERNEL_MEMORY()->TranslateVirtual(destination->pointer); + auto src_buf = REX_KERNEL_MEMORY()->TranslateVirtual(source->pointer); + std::memcpy(dst_buf, src_buf, length * 2); + } + destination->length = length; +} + +// https://msdn.microsoft.com/en-us/library/ff562969 +u32 RtlUnicodeStringToAnsiString_entry(ppc_ptr_t destination_ptr, + ppc_ptr_t source_ptr, u32 alloc_dest) { + // NTSTATUS + // _Inout_ PANSI_STRING DestinationString, + // _In_ PCUNICODE_STRING SourceString, + // _In_ BOOLEAN AllocateDestinationString + + std::u16string unicode_str = util::TranslateUnicodeString(REX_KERNEL_MEMORY(), source_ptr); + std::string ansi_str = rex::string::to_utf8(unicode_str); + if (ansi_str.size() > 0xFFFF - 1) { + return X_STATUS_INVALID_PARAMETER_2; + } + + X_STATUS result = X_STATUS_SUCCESS; + if (alloc_dest) { + uint32_t buffer_ptr = REX_KERNEL_MEMORY()->SystemHeapAlloc(uint32_t(ansi_str.size() + 1)); + + memcpy(REX_KERNEL_MEMORY()->TranslateVirtual(buffer_ptr), ansi_str.data(), ansi_str.size() + 1); + destination_ptr->length = static_cast(ansi_str.size()); + destination_ptr->maximum_length = static_cast(ansi_str.size() + 1); + destination_ptr->pointer = static_cast(buffer_ptr); + } else { + uint32_t buffer_capacity = destination_ptr->maximum_length; + auto buffer_ptr = REX_KERNEL_MEMORY()->TranslateVirtual(destination_ptr->pointer); + if (buffer_capacity < ansi_str.size() + 1) { + // Too large - we just write what we can. + result = X_STATUS_BUFFER_OVERFLOW; + memcpy(buffer_ptr, ansi_str.data(), buffer_capacity - 1); + } else { + memcpy(buffer_ptr, ansi_str.data(), ansi_str.size() + 1); + } + buffer_ptr[buffer_capacity - 1] = 0; // \0 + } + return result; +} + +// https://msdn.microsoft.com/en-us/library/ff553113 +u32 RtlMultiByteToUnicodeN_entry(mapped_u16 destination_ptr, u32 destination_len, + mapped_u32 written_ptr, ppc_ptr_t source_ptr, + u32 source_len) { + uint32_t copy_len = destination_len >> 1; + copy_len = copy_len < source_len ? copy_len : source_len; + + // TODO(benvanik): maybe use MultiByteToUnicode on Win32? would require + // swapping. + + for (uint32_t i = 0; i < copy_len; i++) { + destination_ptr[i] = source_ptr[i]; + } + + if (written_ptr.guest_address() != 0) { + *written_ptr = copy_len << 1; + } + + return 0; +} + +// https://msdn.microsoft.com/en-us/library/ff553261 +u32 RtlUnicodeToMultiByteN_entry(ppc_ptr_t destination_ptr, u32 destination_len, + mapped_u32 written_ptr, mapped_u16 source_ptr, u32 source_len) { + uint32_t copy_len = source_len >> 1; + copy_len = copy_len < destination_len ? copy_len : destination_len; + + // TODO(benvanik): maybe use UnicodeToMultiByte on Win32? + for (uint32_t i = 0; i < copy_len; i++) { + uint16_t c = source_ptr[i]; + destination_ptr[i] = c < 256 ? (uint8_t)c : '?'; + } + + if (written_ptr.guest_address() != 0) { + *written_ptr = copy_len; + } + return 0; +} + +// https://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/Executable%20Images/RtlImageNtHeader.html +u32 RtlImageNtHeader_entry(mapped_void module) { + if (!module) { + return 0; + } + + // Little-endian! no swapping! + + auto dos_header = module.as(); + auto dos_magic = *reinterpret_cast(&dos_header[0x00]); + if (dos_magic != 0x5A4D) { // 'MZ' + return 0; + } + auto dos_lfanew = *reinterpret_cast(&dos_header[0x3C]); + + auto nt_header = &dos_header[dos_lfanew]; + auto nt_magic = *reinterpret_cast(&nt_header[0x00]); + if (nt_magic != 0x4550) { // 'PE' + return 0; + } + return REX_KERNEL_MEMORY()->HostToGuestVirtual(nt_header); +} + +u32 RtlImageXexHeaderField_entry(ppc_ptr_t xex_header, u32 field_dword) { + uint32_t field_value = 0; + uint32_t field = field_dword; // VS acts weird going from u32 -> enum + + UserModule::GetOptHeader(REX_KERNEL_MEMORY(), xex_header, xex2_header_keys(field), &field_value); + + return field_value; +} + +// Unfortunately the Windows RTL_CRITICAL_SECTION object is bigger than the one +// on the 360 (32b vs. 28b). This means that we can't do in-place splatting of +// the critical sections. Also, the 360 never calls RtlDeleteCriticalSection +// so we can't clean up the native handles. +// +// Because of this, we reimplement it poorly. Hooray. +// We have 28b to work with so we need to be careful. We map our struct directly +// into guest memory, as it should be opaque and so long as our size is right +// the user code will never know. +// +// Ref: +// https://web.archive.org/web/20161214022602/https://msdn.microsoft.com/en-us/magazine/cc164040.aspx +// Ref: +// https://github.com/reactos/reactos/blob/master/sdk/lib/rtl/critical.c + +// This structure tries to match the one on the 360 as best I can figure out. +// Unfortunately some games have the critical sections pre-initialized in +// their embedded data and InitializeCriticalSection will never be called. +#pragma pack(push, 1) +struct X_RTL_CRITICAL_SECTION { + X_DISPATCH_HEADER header; + int32_t lock_count; // 0x10 -1 -> 0 on first lock + rex::be recursion_count; // 0x14 0 -> 1 on first lock + rex::be owning_thread; // 0x18 PKTHREAD 0 unless locked +}; +#pragma pack(pop) +static_assert_size(X_RTL_CRITICAL_SECTION, 28); + +void xeRtlInitializeCriticalSection(X_RTL_CRITICAL_SECTION* cs, uint32_t cs_ptr) { + cs->header.type = 1; // EventSynchronizationObject (auto reset) + cs->header.absolute = 0; // spin count div 256 + cs->header.signal_state = 0; + cs->lock_count = -1; + cs->recursion_count = 0; + cs->owning_thread = 0; +} + +void RtlInitializeCriticalSection_entry(ppc_ptr_t cs) { + REXKRNL_IMPORT_TRACE("RtlInitializeCriticalSection", "cs={:#x}", cs.guest_address()); + xeRtlInitializeCriticalSection(cs, cs.guest_address()); +} + +X_STATUS xeRtlInitializeCriticalSectionAndSpinCount(X_RTL_CRITICAL_SECTION* cs, uint32_t cs_ptr, + uint32_t spin_count) { + // Spin count is rounded up to 256 intervals then packed in. + // uint32_t spin_count_div_256 = (uint32_t)floor(spin_count / 256.0f + 0.5f); + uint32_t spin_count_div_256 = (spin_count + 255) >> 8; + if (spin_count_div_256 > 255) { + spin_count_div_256 = 255; + } + + cs->header.type = 1; // EventSynchronizationObject (auto reset) + cs->header.absolute = spin_count_div_256; + cs->header.signal_state = 0; + cs->lock_count = -1; + cs->recursion_count = 0; + cs->owning_thread = 0; + + return X_STATUS_SUCCESS; +} + +u32 RtlInitializeCriticalSectionAndSpinCount_entry(ppc_ptr_t cs, + u32 spin_count) { + return xeRtlInitializeCriticalSectionAndSpinCount(cs, cs.guest_address(), spin_count); +} + +void RtlEnterCriticalSection_entry(ppc_ptr_t cs) { + uint32_t cur_thread = XThread::GetCurrentThread()->guest_object(); + uint32_t spin_count = cs->header.absolute * 256; + + if (cs->owning_thread == cur_thread) { + // We already own the lock. + rex::thread::atomic_inc(&cs->lock_count); + cs->recursion_count++; + return; + } + + // Spin loop + while (spin_count--) { + if (rex::thread::atomic_cas(-1, 0, &cs->lock_count)) { + // Acquired. + cs->owning_thread = cur_thread; + cs->recursion_count = 1; + return; + } + } + + if (rex::thread::atomic_inc(&cs->lock_count) != 0) { + // Create a full waiter. + xeKeWaitForSingleObject(reinterpret_cast(cs.host_address()), 8, 0, 0, nullptr); + } + + assert_true(cs->owning_thread == 0); + cs->owning_thread = cur_thread; + cs->recursion_count = 1; +} + +u32 RtlTryEnterCriticalSection_entry(ppc_ptr_t cs) { + uint32_t thread = XThread::GetCurrentThread()->guest_object(); + + if (rex::thread::atomic_cas(-1, 0, &cs->lock_count)) { + // Able to steal the lock right away. + cs->owning_thread = thread; + cs->recursion_count = 1; + return 1; + } else if (cs->owning_thread == thread) { + // Already own the lock. + rex::thread::atomic_inc(&cs->lock_count); + ++cs->recursion_count; + return 1; + } + + // Failed to acquire lock. + return 0; +} + +void RtlLeaveCriticalSection_entry(ppc_ptr_t cs) { + assert_true(cs->owning_thread == XThread::GetCurrentThread()->guest_object()); + + // Drop recursion count - if it isn't zero we still have the lock. + assert_true(cs->recursion_count > 0); + if (--cs->recursion_count != 0) { + assert_true(cs->recursion_count >= 0); + + rex::thread::atomic_dec(&cs->lock_count); + return; + } + + // Not owned - unlock! + cs->owning_thread = 0; + if (rex::thread::atomic_dec(&cs->lock_count) != -1) { + // There were waiters - wake one of them. + xeKeSetEvent(reinterpret_cast(cs.host_address()), 1, 0); + } +} + +struct X_TIME_FIELDS { + rex::be year; + rex::be month; + rex::be day; + rex::be hour; + rex::be minute; + rex::be second; + rex::be milliseconds; + rex::be weekday; +}; +static_assert_size(X_TIME_FIELDS, 16); + +// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtltimetotimefields +void RtlTimeToTimeFields_entry(mapped_u64 time_ptr, ppc_ptr_t time_fields_ptr) { + // Use host clock because we don't want scaling to be applied, just conversion + using rex::chrono::WinSystemClock; + auto tp = WinSystemClock::to_sys(WinSystemClock::from_file_time(time_ptr.value())); + auto dp = std::chrono::floor(tp); + auto year_month_day = std::chrono::year_month_day{dp}; + auto weekday = std::chrono::weekday{dp}; + auto time = std::chrono::hh_mm_ss{std::chrono::floor(tp - dp)}; + time_fields_ptr->year = static_cast(year_month_day.year()); + time_fields_ptr->month = static_cast(year_month_day.month()); + time_fields_ptr->day = static_cast(year_month_day.day()); + time_fields_ptr->weekday = weekday.c_encoding(); + time_fields_ptr->hour = time.hours().count(); + time_fields_ptr->minute = time.minutes().count(); + time_fields_ptr->second = static_cast(time.seconds().count()); + time_fields_ptr->milliseconds = static_cast(time.subseconds().count()); +} + +// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtltimefieldstotime +u32 RtlTimeFieldsToTime_entry(ppc_ptr_t time_fields_ptr, mapped_u64 time_ptr) { + using rex::chrono::WinSystemClock; + if (time_fields_ptr->year < 1601 || time_fields_ptr->month < 1 || time_fields_ptr->month > 12 || + time_fields_ptr->day < 1 || time_fields_ptr->day > 31 || time_fields_ptr->hour > 23 || + time_fields_ptr->minute > 59 || time_fields_ptr->second > 59 || + time_fields_ptr->milliseconds > 999) { + return 0; + } + auto year = std::chrono::year{time_fields_ptr->year}; + auto month = std::chrono::month{time_fields_ptr->month}; + auto day = std::chrono::day{time_fields_ptr->day}; + auto year_month_day = std::chrono::year_month_day{year, month, day}; + if (!year_month_day.ok()) { + return 0; + } + auto dp = static_cast(year_month_day); + std::chrono::system_clock::time_point time = dp; + time += std::chrono::hours{time_fields_ptr->hour}; + time += std::chrono::minutes{time_fields_ptr->minute}; + time += std::chrono::seconds{time_fields_ptr->second}; + time += std::chrono::milliseconds{time_fields_ptr->milliseconds}; + *time_ptr = WinSystemClock::to_file_time(WinSystemClock::from_sys(time)); + return 1; +} + +static uint32_t crc32_table[256] = { + 0x00000000u, 0x77073096u, 0xEE0E612Cu, 0x990951BAu, 0x076DC419u, 0x706AF48Fu, 0xE963A535u, + 0x9E6495A3u, 0x0EDB8832u, 0x79DCB8A4u, 0xE0D5E91Eu, 0x97D2D988u, 0x09B64C2Bu, 0x7EB17CBDu, + 0xE7B82D07u, 0x90BF1D91u, 0x1DB71064u, 0x6AB020F2u, 0xF3B97148u, 0x84BE41DEu, 0x1ADAD47Du, + 0x6DDDE4EBu, 0xF4D4B551u, 0x83D385C7u, 0x136C9856u, 0x646BA8C0u, 0xFD62F97Au, 0x8A65C9ECu, + 0x14015C4Fu, 0x63066CD9u, 0xFA0F3D63u, 0x8D080DF5u, 0x3B6E20C8u, 0x4C69105Eu, 0xD56041E4u, + 0xA2677172u, 0x3C03E4D1u, 0x4B04D447u, 0xD20D85FDu, 0xA50AB56Bu, 0x35B5A8FAu, 0x42B2986Cu, + 0xDBBBC9D6u, 0xACBCF940u, 0x32D86CE3u, 0x45DF5C75u, 0xDCD60DCFu, 0xABD13D59u, 0x26D930ACu, + 0x51DE003Au, 0xC8D75180u, 0xBFD06116u, 0x21B4F4B5u, 0x56B3C423u, 0xCFBA9599u, 0xB8BDA50Fu, + 0x2802B89Eu, 0x5F058808u, 0xC60CD9B2u, 0xB10BE924u, 0x2F6F7C87u, 0x58684C11u, 0xC1611DABu, + 0xB6662D3Du, 0x76DC4190u, 0x01DB7106u, 0x98D220BCu, 0xEFD5102Au, 0x71B18589u, 0x06B6B51Fu, + 0x9FBFE4A5u, 0xE8B8D433u, 0x7807C9A2u, 0x0F00F934u, 0x9609A88Eu, 0xE10E9818u, 0x7F6A0DBBu, + 0x086D3D2Du, 0x91646C97u, 0xE6635C01u, 0x6B6B51F4u, 0x1C6C6162u, 0x856530D8u, 0xF262004Eu, + 0x6C0695EDu, 0x1B01A57Bu, 0x8208F4C1u, 0xF50FC457u, 0x65B0D9C6u, 0x12B7E950u, 0x8BBEB8EAu, + 0xFCB9887Cu, 0x62DD1DDFu, 0x15DA2D49u, 0x8CD37CF3u, 0xFBD44C65u, 0x4DB26158u, 0x3AB551CEu, + 0xA3BC0074u, 0xD4BB30E2u, 0x4ADFA541u, 0x3DD895D7u, 0xA4D1C46Du, 0xD3D6F4FBu, 0x4369E96Au, + 0x346ED9FCu, 0xAD678846u, 0xDA60B8D0u, 0x44042D73u, 0x33031DE5u, 0xAA0A4C5Fu, 0xDD0D7CC9u, + 0x5005713Cu, 0x270241AAu, 0xBE0B1010u, 0xC90C2086u, 0x5768B525u, 0x206F85B3u, 0xB966D409u, + 0xCE61E49Fu, 0x5EDEF90Eu, 0x29D9C998u, 0xB0D09822u, 0xC7D7A8B4u, 0x59B33D17u, 0x2EB40D81u, + 0xB7BD5C3Bu, 0xC0BA6CADu, 0xEDB88320u, 0x9ABFB3B6u, 0x03B6E20Cu, 0x74B1D29Au, 0xEAD54739u, + 0x9DD277AFu, 0x04DB2615u, 0x73DC1683u, 0xE3630B12u, 0x94643B84u, 0x0D6D6A3Eu, 0x7A6A5AA8u, + 0xE40ECF0Bu, 0x9309FF9Du, 0x0A00AE27u, 0x7D079EB1u, 0xF00F9344u, 0x8708A3D2u, 0x1E01F268u, + 0x6906C2FEu, 0xF762575Du, 0x806567CBu, 0x196C3671u, 0x6E6B06E7u, 0xFED41B76u, 0x89D32BE0u, + 0x10DA7A5Au, 0x67DD4ACCu, 0xF9B9DF6Fu, 0x8EBEEFF9u, 0x17B7BE43u, 0x60B08ED5u, 0xD6D6A3E8u, + 0xA1D1937Eu, 0x38D8C2C4u, 0x4FDFF252u, 0xD1BB67F1u, 0xA6BC5767u, 0x3FB506DDu, 0x48B2364Bu, + 0xD80D2BDAu, 0xAF0A1B4Cu, 0x36034AF6u, 0x41047A60u, 0xDF60EFC3u, 0xA867DF55u, 0x316E8EEFu, + 0x4669BE79u, 0xCB61B38Cu, 0xBC66831Au, 0x256FD2A0u, 0x5268E236u, 0xCC0C7795u, 0xBB0B4703u, + 0x220216B9u, 0x5505262Fu, 0xC5BA3BBEu, 0xB2BD0B28u, 0x2BB45A92u, 0x5CB36A04u, 0xC2D7FFA7u, + 0xB5D0CF31u, 0x2CD99E8Bu, 0x5BDEAE1Du, 0x9B64C2B0u, 0xEC63F226u, 0x756AA39Cu, 0x026D930Au, + 0x9C0906A9u, 0xEB0E363Fu, 0x72076785u, 0x05005713u, 0x95BF4A82u, 0xE2B87A14u, 0x7BB12BAEu, + 0x0CB61B38u, 0x92D28E9Bu, 0xE5D5BE0Du, 0x7CDCEFB7u, 0x0BDBDF21u, 0x86D3D2D4u, 0xF1D4E242u, + 0x68DDB3F8u, 0x1FDA836Eu, 0x81BE16CDu, 0xF6B9265Bu, 0x6FB077E1u, 0x18B74777u, 0x88085AE6u, + 0xFF0F6A70u, 0x66063BCAu, 0x11010B5Cu, 0x8F659EFFu, 0xF862AE69u, 0x616BFFD3u, 0x166CCF45u, + 0xA00AE278u, 0xD70DD2EEu, 0x4E048354u, 0x3903B3C2u, 0xA7672661u, 0xD06016F7u, 0x4969474Du, + 0x3E6E77DBu, 0xAED16A4Au, 0xD9D65ADCu, 0x40DF0B66u, 0x37D83BF0u, 0xA9BCAE53u, 0xDEBB9EC5u, + 0x47B2CF7Fu, 0x30B5FFE9u, 0xBDBDF21Cu, 0xCABAC28Au, 0x53B39330u, 0x24B4A3A6u, 0xBAD03605u, + 0xCDD70693u, 0x54DE5729u, 0x23D967BFu, 0xB3667A2Eu, 0xC4614AB8u, 0x5D681B02u, 0x2A6F2B94u, + 0xB40BBE37u, 0xC30C8EA1u, 0x5A05DF1Bu, 0x2D02EF8Du, +}; + +u32 RtlComputeCrc32_entry(u32 seed, mapped_void buffer, u32 length) { + if (!length) { + return seed; + } + uint32_t hash = ~seed; + for (uint32_t i = 0; i < length; ++i) { + hash = crc32_table[buffer[i] ^ (hash & 0xFF)] ^ (hash >> 8); + } + return ~hash; +} + +void RtlCaptureContext_entry() { + // TODO(tomc): do we even need this? + REXKRNL_WARN("[STUB] RtlCaptureContext called - not implemented"); +} + +void RtlUnwind_entry() { + // TODO(tomc): do we even need this? + REXKRNL_WARN("[STUB] RtlUnwind called - not implemented"); +} + +void __C_specific_handler_entry() { + // TODO(tomc): do we even need this? + REXKRNL_WARN("[STUB] __C_specific_handler called - not implemented"); +} + +REX_EXPORT_STUB(__imp__RtlAnsiStringToUnicodeString); +REX_EXPORT_STUB(__imp__RtlAppendStringToString); +REX_EXPORT_STUB(__imp__RtlAppendUnicodeStringToString); +REX_EXPORT_STUB(__imp__RtlAppendUnicodeToString); +REX_EXPORT_STUB(__imp__RtlCompareUnicodeString); +REX_EXPORT_STUB(__imp__RtlCompareUnicodeStringN); +REX_EXPORT_STUB(__imp__RtlCompareUtf8ToUnicode); +REX_EXPORT_STUB(__imp__RtlCreateUnicodeString); +REX_EXPORT_STUB(__imp__RtlDowncaseUnicodeChar); +REX_EXPORT_STUB(__imp__RtlGetCallersAddress); +REX_EXPORT_STUB(__imp__RtlGetStackLimits); +REX_EXPORT_STUB(__imp__RtlLookupFunctionEntry); +REX_EXPORT_STUB(__imp__RtlMultiByteToUnicodeSize); +REX_EXPORT_STUB(__imp__RtlUnicodeToMultiByteSize); +REX_EXPORT_STUB(__imp__RtlUnicodeToUtf8); +REX_EXPORT_STUB(__imp__RtlUnicodeToUtf8Size); +REX_EXPORT_STUB(__imp__RtlUnwind2); +REX_EXPORT_STUB(__imp__RtlUpcaseUnicodeChar); +REX_EXPORT_STUB(__imp__RtlVirtualUnwind); +REX_EXPORT_STUB(__imp__RtlImageDirectoryEntryToData); +REX_EXPORT_STUB(__imp__RtlCaptureStackBackTrace); +REX_EXPORT_STUB(__imp__RtlSetVectoredExceptionHandler); +REX_EXPORT_STUB(__imp__RtlClearVectoredExceptionHandler); + +} // namespace rex::kernel::xboxkrnl + +REX_EXPORT(__imp__RtlCompareMemory, rex::kernel::xboxkrnl::RtlCompareMemory_entry) +REX_EXPORT(__imp__RtlCompareMemoryUlong, rex::kernel::xboxkrnl::RtlCompareMemoryUlong_entry) +REX_EXPORT(__imp__RtlFillMemoryUlong, rex::kernel::xboxkrnl::RtlFillMemoryUlong_entry) +REX_EXPORT(__imp__RtlUpperChar, rex::kernel::xboxkrnl::RtlUpperChar_entry) +REX_EXPORT(__imp__RtlLowerChar, rex::kernel::xboxkrnl::RtlLowerChar_entry) +REX_EXPORT(__imp__RtlCompareString, rex::kernel::xboxkrnl::RtlCompareString_entry) +REX_EXPORT(__imp__RtlCompareStringN, rex::kernel::xboxkrnl::RtlCompareStringN_entry) +REX_EXPORT(__imp__RtlInitAnsiString, rex::kernel::xboxkrnl::RtlInitAnsiString_entry) +REX_EXPORT(__imp__RtlFreeAnsiString, rex::kernel::xboxkrnl::RtlFreeAnsiString_entry) +REX_EXPORT(__imp__RtlInitUnicodeString, rex::kernel::xboxkrnl::RtlInitUnicodeString_entry) +REX_EXPORT(__imp__RtlFreeUnicodeString, rex::kernel::xboxkrnl::RtlFreeUnicodeString_entry) +REX_EXPORT(__imp__RtlCopyString, rex::kernel::xboxkrnl::RtlCopyString_entry) +REX_EXPORT(__imp__RtlCopyUnicodeString, rex::kernel::xboxkrnl::RtlCopyUnicodeString_entry) +REX_EXPORT(__imp__RtlUnicodeStringToAnsiString, + rex::kernel::xboxkrnl::RtlUnicodeStringToAnsiString_entry) +REX_EXPORT(__imp__RtlMultiByteToUnicodeN, rex::kernel::xboxkrnl::RtlMultiByteToUnicodeN_entry) +REX_EXPORT(__imp__RtlUnicodeToMultiByteN, rex::kernel::xboxkrnl::RtlUnicodeToMultiByteN_entry) +REX_EXPORT(__imp__RtlImageNtHeader, rex::kernel::xboxkrnl::RtlImageNtHeader_entry) +REX_EXPORT(__imp__RtlImageXexHeaderField, rex::kernel::xboxkrnl::RtlImageXexHeaderField_entry) +REX_EXPORT(__imp__RtlInitializeCriticalSection, + rex::kernel::xboxkrnl::RtlInitializeCriticalSection_entry) +REX_EXPORT(__imp__RtlInitializeCriticalSectionAndSpinCount, + rex::kernel::xboxkrnl::RtlInitializeCriticalSectionAndSpinCount_entry) +REX_EXPORT(__imp__RtlEnterCriticalSection, rex::kernel::xboxkrnl::RtlEnterCriticalSection_entry) +REX_EXPORT(__imp__RtlTryEnterCriticalSection, + rex::kernel::xboxkrnl::RtlTryEnterCriticalSection_entry) +REX_EXPORT(__imp__RtlLeaveCriticalSection, rex::kernel::xboxkrnl::RtlLeaveCriticalSection_entry) +REX_EXPORT(__imp__RtlTimeToTimeFields, rex::kernel::xboxkrnl::RtlTimeToTimeFields_entry) +REX_EXPORT(__imp__RtlTimeFieldsToTime, rex::kernel::xboxkrnl::RtlTimeFieldsToTime_entry) +REX_EXPORT(__imp__RtlComputeCrc32, rex::kernel::xboxkrnl::RtlComputeCrc32_entry) +REX_EXPORT(__imp__RtlCaptureContext, rex::kernel::xboxkrnl::RtlCaptureContext_entry) +REX_EXPORT(__imp__RtlUnwind, rex::kernel::xboxkrnl::RtlUnwind_entry) +REX_EXPORT(__imp____C_specific_handler, rex::kernel::xboxkrnl::__C_specific_handler_entry) diff --git a/src/kernel/xboxkrnl/xboxkrnl_strings.cpp b/src/kernel/xboxkrnl/xboxkrnl_strings.cpp new file mode 100644 index 0000000..b67878a --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_strings.cpp @@ -0,0 +1,360 @@ +/** + * @file kernel/xboxkrnl/xboxkrnl_strings.cpp + * @brief Xbox kernel string function exports + * + * @copyright Copyright 2022 Ben Vanik. All rights reserved. (Xenia Project) + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace rex::system::format; +using rex::memory::GuestPtr; + +//============================================================================= +// DbgPrint / XamDbgPrint +//============================================================================= + +REX_HOOK_RAW(__imp__DbgPrint) { + uint32_t format_ptr = ctx.r3.u32; + if (!format_ptr) { + ctx.r3.u64 = 0; + return; + } + auto format = GuestPtr(base, format_ptr); + + StackArgList args(ctx, base, 1); + StringFormatData data(format); + + int32_t count = format_core(base, data, args, false); + if (count > 0) { + auto str = data.str(); + // Trim trailing whitespace + while (!str.empty() && std::isspace(static_cast(str.back()))) { + str.pop_back(); + } + REXKRNL_INFO("DbgPrint: {}", str); + } + + ctx.r3.u64 = 0; // NTSTATUS success +} + +REX_HOOK_RAW(__imp__XamDbgPrint) { + uint32_t format_ptr = ctx.r3.u32; + if (!format_ptr) { + ctx.r3.u64 = 0; + return; + } + auto format = GuestPtr(base, format_ptr); + + StackArgList args(ctx, base, 1); + StringFormatData data(format); + + int32_t count = format_core(base, data, args, false); + if (count > 0) { + auto str = data.str(); + while (!str.empty() && std::isspace(static_cast(str.back()))) { + str.pop_back(); + } + REXKRNL_INFO("XamDbgPrint: {}", str); + } + + ctx.r3.u64 = 0; +} + +//============================================================================= +// sprintf / _snprintf (narrow, stack varargs) +//============================================================================= + +REX_HOOK_RAW(__imp__sprintf) { + uint32_t buffer_ptr = ctx.r3.u32; + uint32_t format_ptr = ctx.r4.u32; + + if (buffer_ptr == 0 || format_ptr == 0) { + ctx.r3.u64 = static_cast(-1); + return; + } + + auto buffer = GuestPtr(base, buffer_ptr); + auto format = GuestPtr(base, format_ptr); + + StackArgList args(ctx, base, 2); + StringFormatData data(format); + + int32_t count = format_core(base, data, args, false); + if (count <= 0) { + buffer[0] = '\0'; + } else { + std::memcpy(buffer, data.str().c_str(), count); + buffer[count] = '\0'; + } + ctx.r3.u64 = count; +} + +REX_HOOK_RAW(__imp___snprintf) { + uint32_t buffer_ptr = ctx.r3.u32; + int32_t buffer_count = static_cast(ctx.r4.u32); + uint32_t format_ptr = ctx.r5.u32; + + if (buffer_ptr == 0 || buffer_count <= 0 || format_ptr == 0) { + ctx.r3.u64 = static_cast(-1); + return; + } + + auto buffer = GuestPtr(base, buffer_ptr); + auto format = GuestPtr(base, format_ptr); + + StackArgList args(ctx, base, 3); + StringFormatData data(format); + + int32_t count = format_core(base, data, args, false); + if (count < 0) { + if (buffer_count > 0) { + buffer[0] = '\0'; + } + } else if (count <= buffer_count) { + std::memcpy(buffer, data.str().c_str(), count); + if (count < buffer_count) { + buffer[count] = '\0'; + } + } else { + std::memcpy(buffer, data.str().c_str(), buffer_count); + count = -1; + } + ctx.r3.u64 = count; +} + +//============================================================================= +// swprintf / _snwprintf (wide, stack varargs) +//============================================================================= + +REX_HOOK_RAW(__imp__swprintf) { + uint32_t buffer_ptr = ctx.r3.u32; + uint32_t format_ptr = ctx.r4.u32; + + if (buffer_ptr == 0 || format_ptr == 0) { + ctx.r3.u64 = static_cast(-1); + return; + } + + auto buffer = GuestPtr(base, buffer_ptr); + auto format = GuestPtr(base, format_ptr); + + StackArgList args(ctx, base, 2); + WideStringFormatData data(format); + + int32_t count = format_core(base, data, args, true); + if (count <= 0) { + buffer[0] = '\0'; + } else { + rex::memory::copy_and_swap(buffer, reinterpret_cast(data.wstr().c_str()), + count); + buffer[count] = '\0'; + } + ctx.r3.u64 = count; +} + +REX_HOOK_RAW(__imp___snwprintf) { + uint32_t buffer_ptr = ctx.r3.u32; + int32_t buffer_count = static_cast(ctx.r4.u32); + uint32_t format_ptr = ctx.r5.u32; + + if (buffer_ptr == 0 || buffer_count <= 0 || format_ptr == 0) { + ctx.r3.u64 = static_cast(-1); + return; + } + + auto buffer = GuestPtr(base, buffer_ptr); + auto format = GuestPtr(base, format_ptr); + + StackArgList args(ctx, base, 3); + WideStringFormatData data(format); + + int32_t count = format_core(base, data, args, true); + if (count < 0) { + if (buffer_count > 0) { + buffer[0] = '\0'; + } + } else if (count <= buffer_count) { + rex::memory::copy_and_swap(buffer, reinterpret_cast(data.wstr().c_str()), + count); + if (count < buffer_count) { + buffer[count] = '\0'; + } + } else { + rex::memory::copy_and_swap(buffer, reinterpret_cast(data.wstr().c_str()), + buffer_count); + count = -1; + } + ctx.r3.u64 = count; +} + +//============================================================================= +// vsprintf / _vsnprintf (narrow, va_list from memory) +//============================================================================= + +REX_HOOK_RAW(__imp__vsprintf) { + uint32_t buffer_ptr = ctx.r3.u32; + uint32_t format_ptr = ctx.r4.u32; + uint32_t arg_ptr = ctx.r5.u32; + + if (buffer_ptr == 0 || format_ptr == 0) { + ctx.r3.u64 = static_cast(-1); + return; + } + + auto buffer = GuestPtr(base, buffer_ptr); + auto format = GuestPtr(base, format_ptr); + + ArrayArgList args(base, arg_ptr); + StringFormatData data(format); + + int32_t count = format_core(base, data, args, false); + if (count <= 0) { + buffer[0] = '\0'; + } else { + std::memcpy(buffer, data.str().c_str(), count); + buffer[count] = '\0'; + } + ctx.r3.u64 = count; +} + +REX_HOOK_RAW(__imp___vsnprintf) { + uint32_t buffer_ptr = ctx.r3.u32; + int32_t buffer_count = static_cast(ctx.r4.u32); + uint32_t format_ptr = ctx.r5.u32; + uint32_t arg_ptr = ctx.r6.u32; + + if (buffer_ptr == 0 || buffer_count <= 0 || format_ptr == 0) { + ctx.r3.u64 = static_cast(-1); + return; + } + + auto buffer = GuestPtr(base, buffer_ptr); + auto format = GuestPtr(base, format_ptr); + + ArrayArgList args(base, arg_ptr); + StringFormatData data(format); + + int32_t count = format_core(base, data, args, false); + if (count < 0) { + if (buffer_count > 0) { + buffer[0] = '\0'; + } + } else if (count <= buffer_count) { + std::memcpy(buffer, data.str().c_str(), count); + if (count < buffer_count) { + buffer[count] = '\0'; + } + } else { + std::memcpy(buffer, data.str().c_str(), buffer_count); + } + ctx.r3.u64 = count; +} + +//============================================================================= +// vswprintf / _vsnwprintf / _vscwprintf (wide, va_list from memory) +//============================================================================= + +REX_HOOK_RAW(__imp__vswprintf) { + uint32_t buffer_ptr = ctx.r3.u32; + uint32_t format_ptr = ctx.r4.u32; + uint32_t arg_ptr = ctx.r5.u32; + + if (buffer_ptr == 0 || format_ptr == 0) { + ctx.r3.u64 = static_cast(-1); + return; + } + + auto buffer = GuestPtr(base, buffer_ptr); + auto format = GuestPtr(base, format_ptr); + + ArrayArgList args(base, arg_ptr); + WideStringFormatData data(format); + + int32_t count = format_core(base, data, args, true); + if (count <= 0) { + buffer[0] = '\0'; + } else { + rex::memory::copy_and_swap(buffer, reinterpret_cast(data.wstr().c_str()), + count); + buffer[count] = '\0'; + } + ctx.r3.u64 = count; +} + +REX_HOOK_RAW(__imp___vsnwprintf) { + uint32_t buffer_ptr = ctx.r3.u32; + int32_t buffer_count = static_cast(ctx.r4.u32); + uint32_t format_ptr = ctx.r5.u32; + uint32_t arg_ptr = ctx.r6.u32; + + if (buffer_ptr == 0 || buffer_count <= 0 || format_ptr == 0) { + ctx.r3.u64 = static_cast(-1); + return; + } + + auto buffer = GuestPtr(base, buffer_ptr); + auto format = GuestPtr(base, format_ptr); + + ArrayArgList args(base, arg_ptr); + WideStringFormatData data(format); + + int32_t count = format_core(base, data, args, true); + if (count < 0) { + if (buffer_count > 0) { + buffer[0] = '\0'; + } + } else if (count <= buffer_count) { + rex::memory::copy_and_swap(buffer, reinterpret_cast(data.wstr().c_str()), + count); + if (count < buffer_count) { + buffer[count] = '\0'; + } + } else { + rex::memory::copy_and_swap(buffer, reinterpret_cast(data.wstr().c_str()), + buffer_count); + } + ctx.r3.u64 = count; +} + +REX_HOOK_RAW(__imp___vscwprintf) { + uint32_t format_ptr = ctx.r3.u32; + uint32_t arg_ptr = ctx.r4.u32; + + if (format_ptr == 0) { + ctx.r3.u64 = static_cast(-1); + return; + } + + auto format = GuestPtr(base, format_ptr); + + ArrayArgList args(base, arg_ptr); + WideCountFormatData data(format); + + int32_t count = format_core(base, data, args, true); + assert_true(count < 0 || data.count() == count); + ctx.r3.u64 = count; +} + +//============================================================================= +// Export stubs +//============================================================================= + +REX_EXPORT_STUB(__imp___scprintf); +REX_EXPORT_STUB(__imp___scwprintf); +REX_EXPORT_STUB(__imp___vscprintf); diff --git a/src/kernel/xboxkrnl/xboxkrnl_threading.cpp b/src/kernel/xboxkrnl/xboxkrnl_threading.cpp new file mode 100644 index 0000000..4351404 --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_threading.cpp @@ -0,0 +1,1552 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { +using namespace rex::system; +using rex::runtime::current_ppc_context; + +// r13 + 0x100: pointer to thread local state +// Thread local state: +// 0x058: kernel time +// 0x14C: thread id +// 0x150: if >0 then error states don't get set +// 0x160: last error + +// GetCurrentThreadId: +// lwz r11, 0x100(r13) +// lwz r3, 0x14C(r11) + +// RtlGetLastError: +// lwz r11, 0x150(r13) +// if (r11 == 0) { +// lwz r11, 0x100(r13) +// stw r3, 0x160(r11) +// } + +// RtlSetLastError: +// lwz r11, 0x150(r13) +// if (r11 == 0) { +// lwz r11, 0x100(r13) +// stw r3, 0x160(r11) +// } + +// RtlSetLastNTError: +// r3 = RtlNtStatusToDosError(r3) +// lwz r11, 0x150(r13) +// if (r11 == 0) { +// lwz r11, 0x100(r13) +// stw r3, 0x160(r11) +// } + +template +object_ref LookupNamedObject(KernelState* kernel_state, uint32_t obj_attributes_ptr) { + // If the name exists and its type matches, we can return that (ref+1) + // with a success of NAME_EXISTS. + // If the name exists and its type doesn't match, we do NAME_COLLISION. + // Otherwise, we add like normal. + if (!obj_attributes_ptr) { + return nullptr; + } + auto obj_attributes = + kernel_state->memory()->TranslateVirtual(obj_attributes_ptr); + assert_true(obj_attributes->name_ptr != 0); + auto name = util::TranslateAnsiStringAddress(kernel_state->memory(), obj_attributes->name_ptr); + if (!name.empty()) { + X_HANDLE handle = X_INVALID_HANDLE_VALUE; + X_RESULT result = kernel_state->object_table()->GetObjectByName(name, &handle); + if (XSUCCEEDED(result)) { + // Found something! It's been retained, so return. + auto obj = kernel_state->object_table()->LookupObject(handle); + if (obj) { + // The caller will do as it likes. + obj->ReleaseHandle(); + return obj; + } + } + } + return nullptr; +} + +u32 ExCreateThread_entry(mapped_u32 handle_ptr, u32 stack_size, mapped_u32 thread_id_ptr, + u32 xapi_thread_startup, mapped_void start_address, + mapped_void start_context, u32 creation_flags) { + REXKRNL_IMPORT_TRACE( + "ExCreateThread", "stack={:#x} xapi_startup={:#x} start={:#x} context={:#x} flags={:#x}", + (uint32_t)stack_size, (uint32_t)xapi_thread_startup, start_address.guest_address(), + start_context.guest_address(), (uint32_t)creation_flags); + // http://jafile.com/uploads/scoop/main.cpp.txt + // DWORD + // LPHANDLE Handle, + // DWORD StackSize, + // LPDWORD ThreadId, + // LPVOID XapiThreadStartup, ?? often 0 + // LPVOID StartAddress, + // LPVOID StartContext, + // DWORD CreationFlags // 0x80? + + // Determine target process based on creation flags. + uint32_t guest_process = REX_KERNEL_STATE()->GetTitleProcess(); + if (creation_flags & 2) { + REXKRNL_WARN("[ExCreateThread] Guest is creating a system thread!"); + guest_process = REX_KERNEL_STATE()->GetSystemProcess(); + } + + // Inherit default stack size + uint32_t actual_stack_size = stack_size; + + if (actual_stack_size == 0) { + actual_stack_size = REX_KERNEL_STATE()->GetExecutableModule()->stack_size(); + } + + // Stack must be aligned to 16kb pages + actual_stack_size = std::max((uint32_t)0x4000, ((actual_stack_size + 0xFFF) & 0xFFFFF000)); + + auto thread = object_ref(new XThread( + REX_KERNEL_STATE(), actual_stack_size, xapi_thread_startup, start_address.guest_address(), + start_context.guest_address(), creation_flags, true, false, guest_process)); + + X_STATUS result = thread->Create(); + if (XFAILED(result)) { + // Failed! + REXKRNL_ERROR("Thread creation failed: {:08X}", result); + return result; + } + + if (XSUCCEEDED(result)) { + if (handle_ptr) { + if (creation_flags & 0x80) { + *handle_ptr = thread->guest_object(); + } else { + *handle_ptr = thread->handle(); + } + } + if (thread_id_ptr) { + *thread_id_ptr = thread->thread_id(); + } + } + REXKRNL_IMPORT_RESULT("ExCreateThread", "{:#x} handle={:#x} tid={}", result, + handle_ptr ? (uint32_t)*handle_ptr : 0, + thread_id_ptr ? (uint32_t)*thread_id_ptr : 0); + return result; +} + +u32 ExTerminateThread_entry(u32 exit_code) { + XThread* thread = XThread::GetCurrentThread(); + + // NOTE: this kills us right now. We won't return from it. + return thread->Exit(exit_code); +} + +u32 NtResumeThread_entry(u32 handle, mapped_u32 suspend_count_ptr) { + X_RESULT result = X_STATUS_INVALID_HANDLE; + uint32_t suspend_count = 0; + + auto thread = REX_KERNEL_OBJECTS()->LookupObject(handle); + if (thread) { + REXKRNL_TRACE("[NtResumeThread] handle={:08X} thread={}", uint32_t(handle), thread->name()); + result = thread->Resume(&suspend_count); + } else { + REXKRNL_WARN("[NtResumeThread] handle={:08X} NOT FOUND", uint32_t(handle)); + } + if (suspend_count_ptr) { + *suspend_count_ptr = suspend_count; + } + + REXKRNL_TRACE("[NtResumeThread] -> {:#x} suspend_count={}", result, suspend_count); + return result; +} + +u32 KeResumeThread_entry(mapped_void thread_ptr) { + X_STATUS result = X_STATUS_SUCCESS; + auto thread = XObject::GetNativeObject(REX_KERNEL_STATE(), thread_ptr); + if (thread) { + REXKRNL_TRACE("[KeResumeThread] ptr={:08X} thread={}", thread_ptr.guest_address(), + thread->name()); + result = thread->Resume(); + } else { + REXKRNL_WARN("[KeResumeThread] ptr={:08X} NOT FOUND", thread_ptr.guest_address()); + result = X_STATUS_INVALID_HANDLE; + } + + REXKRNL_TRACE("[KeResumeThread] -> {:#x}", result); + return result; +} + +u32 NtSuspendThread_entry(u32 handle, mapped_u32 suspend_count_ptr) { + X_RESULT result = X_STATUS_SUCCESS; + uint32_t suspend_count = 0; + + auto thread = REX_KERNEL_OBJECTS()->LookupObject(handle); + if (thread) { + if (thread->type() != XObject::Type::Thread) { + return X_STATUS_OBJECT_TYPE_MISMATCH; + } + + auto guest_thread = thread->guest_object(); + if (guest_thread->terminated) { + return X_STATUS_THREAD_IS_TERMINATING; + } + + REXKRNL_TRACE("[NtSuspendThread] handle={:08X} thread={}", uint32_t(handle), thread->name()); +#if REX_PLATFORM_LINUX + auto* current_thread = XThread::GetCurrentThread(); + bool is_self_suspend = current_thread && current_thread == thread.get(); + if (is_self_suspend) { + REXKRNL_TRACE("[NtSuspendThread] self-suspend for thread={:08X}", uint32_t(handle)); + suspend_count = thread->SelfSuspend(); + result = X_STATUS_SUCCESS; + } else { + result = thread->Suspend(&suspend_count); + } +#else + result = thread->Suspend(&suspend_count); +#endif + } else { + REXKRNL_WARN("[NtSuspendThread] handle={:08X} NOT FOUND", uint32_t(handle)); + result = X_STATUS_INVALID_HANDLE; + } + + if (suspend_count_ptr) { + *suspend_count_ptr = suspend_count; + } + + REXKRNL_TRACE("[NtSuspendThread] -> {:#x} suspend_count={}", result, suspend_count); + return result; +} + +namespace { + +void UpdateGuestStackPointers(X_KTHREAD* kthread, X_KPCR* pcr, PPCContext* ctx, uint32_t sp, + uint32_t stack_alloc_base, uint32_t stack_base, + uint32_t stack_limit) { + kthread->stack_alloc_base = stack_alloc_base; + kthread->stack_base = stack_base; + kthread->stack_limit = stack_limit; + pcr->stack_base_ptr = stack_base; + pcr->stack_end_ptr = stack_limit; + ctx->r1.u64 = sp; +} + +} // namespace + +void KeSetCurrentStackPointers_entry(mapped_void stack_ptr, ppc_ptr_t thread, + mapped_void stack_alloc_base, mapped_void stack_base, + mapped_void stack_limit) { + auto current_thread = XThread::GetCurrentThread(); + auto context = current_thread->thread_state()->context(); + auto pcr = + REX_KERNEL_MEMORY()->TranslateVirtual(static_cast(context->r13.u64)); + + UpdateGuestStackPointers(thread, pcr, context, stack_ptr.guest_address(), + stack_alloc_base.value(), stack_base.value(), stack_limit.value()); +} + +u32 KeSetAffinityThread_entry(mapped_void thread_ptr, u32 affinity, + mapped_u32 previous_affinity_ptr) { + REXKRNL_IMPORT_TRACE("KeSetAffinityThread", "thread={:#x} affinity={:#x}", + thread_ptr.guest_address(), (uint32_t)affinity); + // The Xbox 360, according to disassembly of KeSetAffinityThread, unlike + // Windows NT, stores the previous affinity via the pointer provided as an + // argument, not in the return value - the return value is used for the + // result. + if (!affinity) { + return X_STATUS_INVALID_PARAMETER; + } + auto thread = XObject::GetNativeObject(REX_KERNEL_STATE(), thread_ptr); + if (!thread) { + REXKRNL_IMPORT_WARN("KeSetAffinityThread", "invalid thread handle ptr={:#x}", + thread_ptr.guest_address()); + return X_STATUS_INVALID_HANDLE; + } + if (previous_affinity_ptr) { + *previous_affinity_ptr = uint32_t(1) << thread->active_cpu(); + } + thread->SetAffinity(affinity); + REXKRNL_IMPORT_RESULT("KeSetAffinityThread", "0x0"); + return X_STATUS_SUCCESS; +} + +u32 KeQueryBasePriorityThread_entry(mapped_void thread_ptr) { + REXKRNL_IMPORT_TRACE("KeQueryBasePriorityThread", "thread={:#x}", thread_ptr.guest_address()); + int32_t priority = 0; + + auto thread = XObject::GetNativeObject(REX_KERNEL_STATE(), thread_ptr); + if (thread) { + priority = thread->QueryPriority(); + } + + REXKRNL_IMPORT_RESULT("KeQueryBasePriorityThread", "{}", priority); + return priority; +} + +u32 KeSetBasePriorityThread_entry(mapped_void thread_ptr, u32 increment) { + REXKRNL_IMPORT_TRACE("KeSetBasePriorityThread", "thread={:#x} increment={}", + thread_ptr.guest_address(), (int32_t)increment); + int32_t prev_priority = 0; + auto thread = XObject::GetNativeObject(REX_KERNEL_STATE(), thread_ptr); + + if (thread) { + prev_priority = thread->QueryPriority(); + thread->SetPriority(increment); + } + REXKRNL_IMPORT_RESULT("KeSetBasePriorityThread", "prev_priority={}", prev_priority); + + return prev_priority; +} + +u32 KeSetDisableBoostThread_entry(ppc_ptr_t thread_ptr, u32 disabled) { + auto old_boost_disabled = reinterpret_cast(&thread_ptr->boost_disabled) + ->exchange(static_cast(disabled)); + return old_boost_disabled; +} + +u32 KeGetCurrentProcessType_entry() { + auto current_thread = XThread::GetCurrentThread(); + auto context = current_thread->thread_state()->context(); + auto pcr = + REX_KERNEL_MEMORY()->TranslateVirtual(static_cast(context->r13.u64)); + + if (pcr->prcb_data.dpc_active) { + return pcr->processtype_value_in_dpc; + } + + auto thread = REX_KERNEL_MEMORY()->TranslateVirtual(pcr->prcb_data.current_thread); + return thread->process_type; +} + +void KeSetCurrentProcessType_entry(u32 type) { + // One of X_PROCTYPE_? + assert_true(type <= 2); + + REX_KERNEL_STATE()->set_process_type(type); + + auto current_thread = XThread::GetCurrentThread(); + auto context = current_thread->thread_state()->context(); + auto pcr = + REX_KERNEL_MEMORY()->TranslateVirtual(static_cast(context->r13.u64)); + + if (pcr->prcb_data.dpc_active) { + pcr->processtype_value_in_dpc = static_cast(type); + } +} + +u32 KeQueryPerformanceFrequency_entry() { + uint64_t result = chrono::Clock::guest_tick_frequency(); + return static_cast(result); +} + +u32 KeDelayExecutionThread_entry(u32 processor_mode, u32 alertable, mapped_u64 interval_ptr) { + XThread* thread = XThread::GetCurrentThread(); + + if (alertable) { + thread->DeliverAPCs(); + } + + X_STATUS result = thread->Delay(processor_mode, alertable, *interval_ptr); + + if (alertable && result == X_STATUS_USER_APC) { + thread->DeliverAPCs(); + } + + return result; +} + +u32 NtYieldExecution_entry() { + rex::thread::MaybeYield(); + return X_STATUS_SUCCESS; +} + +void KeQuerySystemTime_entry(mapped_u64 time_ptr) { + uint64_t time = chrono::Clock::QueryGuestSystemTime(); + if (time_ptr) { + *time_ptr = time; + } +} + +// https://msdn.microsoft.com/en-us/library/ms686801 +u32 KeTlsAlloc_entry() { + uint32_t slot = REX_KERNEL_STATE()->AllocateTLS(current_ppc_context()); + if (slot != X_TLS_OUT_OF_INDEXES) { + XThread::GetCurrentThread()->SetTLSValue(slot, 0); + } + REXKRNL_IMPORT_RESULT("KeTlsAlloc", "slot={}", slot); + return slot; +} + +// https://msdn.microsoft.com/en-us/library/ms686804 +u32 KeTlsFree_entry(u32 tls_index) { + REXKRNL_IMPORT_TRACE("KeTlsFree", "slot={}", (uint32_t)tls_index); + if (tls_index == X_TLS_OUT_OF_INDEXES) { + REXKRNL_IMPORT_RESULT("KeTlsFree", "0 (invalid)"); + return 0; + } + + REX_KERNEL_STATE()->FreeTLS(current_ppc_context(), tls_index); + REXKRNL_IMPORT_RESULT("KeTlsFree", "1"); + return 1; +} + +// https://msdn.microsoft.com/en-us/library/ms686812 +u32 KeTlsGetValue_entry(u32 tls_index) { + // xboxkrnl doesn't actually have an error branch - it always succeeds, even + // if it overflows the TLS. + uint32_t value = 0; + if (XThread::GetCurrentThread()->GetTLSValue(tls_index, &value)) { + return value; + } + + return 0; +} + +// https://msdn.microsoft.com/en-us/library/ms686818 +u32 KeTlsSetValue_entry(u32 tls_index, u32 tls_value) { + REXKRNL_IMPORT_TRACE("KeTlsSetValue", "slot={} value={:#x}", (uint32_t)tls_index, + (uint32_t)tls_value); + // xboxkrnl doesn't actually have an error branch - it always succeeds, even + // if it overflows the TLS. + if (XThread::GetCurrentThread()->SetTLSValue(tls_index, tls_value)) { + REXKRNL_IMPORT_RESULT("KeTlsSetValue", "1"); + return 1; + } + + REXKRNL_IMPORT_RESULT("KeTlsSetValue", "0"); + return 0; +} + +void KeInitializeEvent_entry(ppc_ptr_t event_ptr, u32 event_type, u32 initial_state) { + event_ptr.Zero(); + event_ptr->header.type = event_type; + event_ptr->header.signal_state = (uint32_t)initial_state; + auto ev = XObject::GetNativeObject(REX_KERNEL_STATE(), event_ptr, event_type); + if (!ev) { + assert_always(); + return; + } +} + +uint32_t xeKeSetEvent(X_KEVENT* event_ptr, uint32_t increment, uint32_t wait) { + auto ev = XObject::GetNativeObject(REX_KERNEL_STATE(), event_ptr); + if (!ev) { + assert_always(); + return 0; + } + + return ev->Set(increment, !!wait); +} + +u32 KeSetEvent_entry(ppc_ptr_t event_ptr, u32 increment, u32 wait) { + return xeKeSetEvent(event_ptr, increment, wait); +} + +u32 KePulseEvent_entry(ppc_ptr_t event_ptr, u32 increment, u32 wait) { + auto ev = XObject::GetNativeObject(REX_KERNEL_STATE(), event_ptr); + if (!ev) { + assert_always(); + return 0; + } + + return ev->Pulse(increment, !!wait); +} + +u32 KeResetEvent_entry(ppc_ptr_t event_ptr) { + auto ev = XObject::GetNativeObject(REX_KERNEL_STATE(), event_ptr); + if (!ev) { + assert_always(); + return 0; + } + + return ev->Reset(); +} + +u32 NtCreateEvent_entry(mapped_u32 handle_ptr, ppc_ptr_t obj_attributes_ptr, + u32 event_type, u32 initial_state) { + // Check for an existing timer with the same name. + auto existing_object = + LookupNamedObject(REX_KERNEL_STATE(), obj_attributes_ptr.guest_address()); + if (existing_object) { + if (existing_object->type() == XObject::Type::Event) { + if (handle_ptr) { + existing_object->RetainHandle(); + *handle_ptr = existing_object->handle(); + } + return X_STATUS_OBJECT_NAME_EXISTS; + } else { + return X_STATUS_INVALID_HANDLE; + } + } + + auto ev = object_ref(new XEvent(REX_KERNEL_STATE())); + ev->Initialize(!event_type, !!initial_state); + + // obj_attributes may have a name inside of it, if != NULL. + if (obj_attributes_ptr) { + ev->SetAttributes(obj_attributes_ptr.guest_address()); + } + + if (handle_ptr) { + *handle_ptr = ev->handle(); + } + return X_STATUS_SUCCESS; +} + +uint32_t xeNtSetEvent(uint32_t handle, rex::be* previous_state_ptr) { + X_STATUS result = X_STATUS_SUCCESS; + + auto ev = REX_KERNEL_OBJECTS()->LookupObject(handle); + if (ev) { + int32_t was_signalled = ev->Set(0, false); + if (previous_state_ptr) { + *previous_state_ptr = static_cast(was_signalled); + } + } else { + result = X_STATUS_INVALID_HANDLE; + } + + return result; +} + +u32 NtSetEvent_entry(u32 handle, mapped_u32 previous_state_ptr) { + return xeNtSetEvent(handle, previous_state_ptr); +} + +u32 NtPulseEvent_entry(u32 handle, mapped_u32 previous_state_ptr) { + X_STATUS result = X_STATUS_SUCCESS; + + auto ev = REX_KERNEL_OBJECTS()->LookupObject(handle); + if (ev) { + int32_t was_signalled = ev->Pulse(0, false); + if (previous_state_ptr) { + *previous_state_ptr = static_cast(was_signalled); + } + } else { + result = X_STATUS_INVALID_HANDLE; + } + + return result; +} + +uint32_t xeNtClearEvent(uint32_t handle) { + X_STATUS result = X_STATUS_SUCCESS; + + auto ev = REX_KERNEL_OBJECTS()->LookupObject(handle); + if (ev) { + ev->Reset(); + } else { + result = X_STATUS_INVALID_HANDLE; + } + + return result; +} + +u32 NtClearEvent_entry(u32 handle) { + return xeNtClearEvent(handle); +} + +// https://msdn.microsoft.com/en-us/library/windows/hardware/ff552150(v=vs.85).aspx +void KeInitializeSemaphore_entry(ppc_ptr_t semaphore_ptr, u32 count, u32 limit) { + semaphore_ptr->header.type = 5; // SemaphoreObject + semaphore_ptr->header.signal_state = (uint32_t)count; + semaphore_ptr->limit = (uint32_t)limit; + + auto sem = XObject::GetNativeObject(REX_KERNEL_STATE(), semaphore_ptr, + 5 /* SemaphoreObject */); + if (!sem) { + assert_always(); + return; + } +} + +uint32_t xeKeReleaseSemaphore(X_KSEMAPHORE* semaphore_ptr, uint32_t increment, uint32_t adjustment, + uint32_t wait) { + auto sem = XObject::GetNativeObject(REX_KERNEL_STATE(), semaphore_ptr); + if (!sem) { + assert_always(); + return 0; + } + + // TODO(benvanik): increment thread priority? + // TODO(benvanik): wait? + + int32_t previous_count = 0; + [[maybe_unused]] bool success = + sem->ReleaseSemaphore(static_cast(adjustment), &previous_count); + return static_cast(previous_count); +} + +u32 KeReleaseSemaphore_entry(ppc_ptr_t semaphore_ptr, u32 increment, u32 adjustment, + u32 wait) { + return xeKeReleaseSemaphore(semaphore_ptr, increment, adjustment, wait); +} + +u32 NtCreateSemaphore_entry(mapped_u32 handle_ptr, mapped_void obj_attributes_ptr, u32 count, + u32 limit) { + // Check for an existing semaphore with the same name. + auto existing_object = + LookupNamedObject(REX_KERNEL_STATE(), obj_attributes_ptr.guest_address()); + if (existing_object) { + if (existing_object->type() == XObject::Type::Semaphore) { + if (handle_ptr) { + existing_object->RetainHandle(); + *handle_ptr = existing_object->handle(); + } + return X_STATUS_OBJECT_NAME_EXISTS; + } else { + return X_STATUS_INVALID_HANDLE; + } + } + + auto sem = object_ref(new XSemaphore(REX_KERNEL_STATE())); + if (!sem->Initialize((int32_t)count, (int32_t)limit)) { + if (handle_ptr) { + *handle_ptr = 0; + } + sem->ReleaseHandle(); + return X_STATUS_INVALID_PARAMETER; + } + + // obj_attributes may have a name inside of it, if != NULL. + if (obj_attributes_ptr) { + sem->SetAttributes(obj_attributes_ptr.guest_address()); + } + + if (handle_ptr) { + *handle_ptr = sem->handle(); + } + + return X_STATUS_SUCCESS; +} + +u32 NtReleaseSemaphore_entry(u32 sem_handle, u32 release_count, mapped_u32 previous_count_ptr) { + X_STATUS result = X_STATUS_SUCCESS; + int32_t previous_count = 0; + + auto sem = REX_KERNEL_OBJECTS()->LookupObject(sem_handle); + if (sem) { + bool success = sem->ReleaseSemaphore(static_cast(release_count), &previous_count); + if (!success) { + result = X_STATUS_SEMAPHORE_LIMIT_EXCEEDED; + } + } else { + result = X_STATUS_INVALID_HANDLE; + } + if (previous_count_ptr) { + *previous_count_ptr = (uint32_t)previous_count; + } + + return result; +} + +u32 NtCreateMutant_entry(mapped_u32 handle_out, ppc_ptr_t obj_attributes, + u32 initial_owner) { + // Check for an existing timer with the same name. + auto existing_object = + LookupNamedObject(REX_KERNEL_STATE(), obj_attributes.guest_address()); + if (existing_object) { + if (existing_object->type() == XObject::Type::Mutant) { + if (handle_out) { + existing_object->RetainHandle(); + *handle_out = existing_object->handle(); + } + return X_STATUS_OBJECT_NAME_EXISTS; + } else { + return X_STATUS_INVALID_HANDLE; + } + } + + auto mutant = object_ref(new XMutant(REX_KERNEL_STATE())); + mutant->Initialize(initial_owner ? true : false); + + // obj_attributes may have a name inside of it, if != NULL. + if (obj_attributes) { + mutant->SetAttributes(obj_attributes.guest_address()); + } + + if (handle_out) { + *handle_out = mutant->handle(); + } + + return X_STATUS_SUCCESS; +} + +u32 NtReleaseMutant_entry(u32 mutant_handle, u32 unknown) { + // This doesn't seem to be supported. + // int32_t previous_count_ptr = SHIM_GET_ARG_32(2); + + // Whatever arg 1 is all games seem to set it to 0, so whether it's + // abandon or wait we just say false. Which is good, cause they are + // both ignored. + assert_zero(unknown); + uint32_t priority_increment = 0; + bool abandon = false; + bool wait = false; + + X_STATUS result = X_STATUS_SUCCESS; + + auto mutant = REX_KERNEL_OBJECTS()->LookupObject(mutant_handle); + if (mutant) { + result = mutant->ReleaseMutant(priority_increment, abandon, wait); + } else { + result = X_STATUS_INVALID_HANDLE; + } + + return result; +} + +u32 NtCreateTimer_entry(mapped_u32 handle_ptr, mapped_void obj_attributes_ptr, u32 timer_type) { + // timer_type = NotificationTimer (0) or SynchronizationTimer (1) + + // Check for an existing timer with the same name. + auto existing_object = + LookupNamedObject(REX_KERNEL_STATE(), obj_attributes_ptr.guest_address()); + if (existing_object) { + if (existing_object->type() == XObject::Type::Timer) { + if (handle_ptr) { + existing_object->RetainHandle(); + *handle_ptr = existing_object->handle(); + } + return X_STATUS_OBJECT_NAME_EXISTS; + } else { + return X_STATUS_INVALID_HANDLE; + } + } + + auto timer = object_ref(new XTimer(REX_KERNEL_STATE())); + timer->Initialize(timer_type); + + // obj_attributes may have a name inside of it, if != NULL. + if (obj_attributes_ptr) { + timer->SetAttributes(obj_attributes_ptr.guest_address()); + } + + if (handle_ptr) { + *handle_ptr = timer->handle(); + } + + return X_STATUS_SUCCESS; +} + +void KeInitializeTimerEx_entry(ppc_ptr_t timer_ptr, u32 timer_type, u32 proc_type) { + assert_true(timer_type == 0 || timer_type == 1); + assert_true(proc_type < 3); + // Other fields are unmodified; they must carry through multiple calls. + timer_ptr->header.process_type = static_cast(proc_type & 0xFF); + timer_ptr->header.inserted = 0; + timer_ptr->header.type = static_cast(timer_type + 8); + timer_ptr->header.signal_state = 0; + // Initialize wait list to point to itself (empty list). + uint32_t wait_list_addr = + timer_ptr.guest_address() + offsetof(X_DISPATCH_HEADER, wait_list_flink); + timer_ptr->header.wait_list_flink = wait_list_addr; + timer_ptr->header.wait_list_blink = wait_list_addr; + timer_ptr->due_time = 0; + timer_ptr->period = 0; +} + +u32 NtSetTimerEx_entry(u32 timer_handle, mapped_u64 due_time_ptr, + mapped_void routine_ptr /*PTIMERAPCROUTINE*/, u32 unk_one, + mapped_void routine_arg, u32 resume, u32 period_ms, u32 unk_zero) { + assert_true(unk_one == 1); + assert_true(unk_zero == 0); + + uint64_t due_time = *due_time_ptr; + + X_STATUS result = X_STATUS_SUCCESS; + + auto timer = REX_KERNEL_OBJECTS()->LookupObject(timer_handle); + if (timer) { + result = timer->SetTimer(due_time, period_ms, routine_ptr.guest_address(), + routine_arg.guest_address(), resume ? true : false); + } else { + result = X_STATUS_INVALID_HANDLE; + } + + return result; +} + +u32 NtCancelTimer_entry(u32 timer_handle, mapped_u32 current_state_ptr) { + X_STATUS result = X_STATUS_SUCCESS; + + auto timer = REX_KERNEL_OBJECTS()->LookupObject(timer_handle); + if (timer) { + result = timer->Cancel(); + } else { + result = X_STATUS_INVALID_HANDLE; + } + if (current_state_ptr) { + *current_state_ptr = 0; + } + + return result; +} + +uint32_t xeKeWaitForSingleObject(void* object_ptr, uint32_t wait_reason, uint32_t processor_mode, + uint32_t alertable, uint64_t* timeout_ptr) { + auto object = XObject::GetNativeObject(REX_KERNEL_STATE(), object_ptr); + + if (!object) { + // The only kind-of failure code (though this should never happen) + assert_always(); + return X_STATUS_ABANDONED_WAIT_0; + } + + X_STATUS result = object->Wait(wait_reason, processor_mode, alertable, timeout_ptr); + + if (alertable && result == X_STATUS_USER_APC) { + XThread::GetCurrentThread()->DeliverAPCs(); + } + + return result; +} + +u32 KeWaitForSingleObject_entry(mapped_void object_ptr, u32 wait_reason, u32 processor_mode, + u32 alertable, mapped_u64 timeout_ptr) { + uint64_t timeout = timeout_ptr ? static_cast(*timeout_ptr) : 0u; + // REXKRNL_IMPORT_TRACE("KeWaitForSingleObject", "obj={:#x} reason={} mode={} alertable={} + // timeout={}", + // object_ptr.guest_address(), (uint32_t)wait_reason, + //(uint32_t)processor_mode, (uint32_t)alertable, + // timeout_ptr ? (int64_t)timeout : -1); + auto result = xeKeWaitForSingleObject(object_ptr, wait_reason, processor_mode, alertable, + timeout_ptr ? &timeout : nullptr); + // REXKRNL_IMPORT_RESULT("KeWaitForSingleObject", "{:#x}", result); + return result; +} + +u32 NtWaitForSingleObjectEx_entry(u32 object_handle, u32 wait_mode, u32 alertable, + mapped_u64 timeout_ptr) { + X_STATUS result = X_STATUS_SUCCESS; + + auto object = REX_KERNEL_OBJECTS()->LookupObject(object_handle); + if (object) { + uint64_t timeout = timeout_ptr ? static_cast(*timeout_ptr) : 0u; + result = object->Wait(3, wait_mode, alertable, timeout_ptr ? &timeout : nullptr); + if (alertable && result == X_STATUS_USER_APC) { + XThread::GetCurrentThread()->DeliverAPCs(); + } + } else { + result = X_STATUS_INVALID_HANDLE; + } + + return result; +} + +u32 KeWaitForMultipleObjects_entry(u32 count, mapped_u32 objects_ptr, u32 wait_type, + u32 wait_reason, u32 processor_mode, u32 alertable, + mapped_u64 timeout_ptr, mapped_void wait_block_array_ptr) { + assert_true(wait_type <= 1); + + std::vector> objects; + for (uint32_t n = 0; n < count; n++) { + auto object_ptr = REX_KERNEL_MEMORY()->TranslateVirtual(objects_ptr[n]); + auto object_ref = XObject::GetNativeObject(REX_KERNEL_STATE(), object_ptr); + if (!object_ref) { + return X_STATUS_INVALID_PARAMETER; + } + + objects.push_back(std::move(object_ref)); + } + + uint64_t timeout = timeout_ptr ? static_cast(*timeout_ptr) : 0u; + X_STATUS result = XObject::WaitMultiple( + uint32_t(objects.size()), reinterpret_cast(objects.data()), wait_type, wait_reason, + processor_mode, alertable, timeout_ptr ? &timeout : nullptr); + if (alertable && result == X_STATUS_USER_APC) { + XThread::GetCurrentThread()->DeliverAPCs(); + } + return result; +} + +uint32_t xeNtWaitForMultipleObjectsEx(uint32_t count, rex::be* handles, + uint32_t wait_type, uint32_t wait_mode, uint32_t alertable, + uint64_t* timeout_ptr) { + assert_true(wait_type <= 1); + + std::vector> objects; + for (uint32_t n = 0; n < count; n++) { + uint32_t object_handle = handles[n]; + auto object = REX_KERNEL_OBJECTS()->LookupObject(object_handle); + if (!object) { + return X_STATUS_INVALID_PARAMETER; + } + objects.push_back(std::move(object)); + } + + auto result = XObject::WaitMultiple(count, reinterpret_cast(objects.data()), wait_type, + 6, wait_mode, alertable, timeout_ptr); + if (alertable && result == X_STATUS_USER_APC) { + XThread::GetCurrentThread()->DeliverAPCs(); + } + return result; +} + +u32 NtWaitForMultipleObjectsEx_entry(u32 count, mapped_u32 handles, u32 wait_type, u32 wait_mode, + u32 alertable, mapped_u64 timeout_ptr) { + uint64_t timeout = timeout_ptr ? static_cast(*timeout_ptr) : 0u; + return xeNtWaitForMultipleObjectsEx(count, handles, wait_type, wait_mode, alertable, + timeout_ptr ? &timeout : nullptr); +} + +u32 NtSignalAndWaitForSingleObjectEx_entry(u32 signal_handle, u32 wait_handle, u32 alertable, + u32 r6, mapped_u64 timeout_ptr) { + X_STATUS result = X_STATUS_SUCCESS; + + auto signal_object = REX_KERNEL_OBJECTS()->LookupObject(signal_handle); + auto wait_object = REX_KERNEL_OBJECTS()->LookupObject(wait_handle); + if (signal_object && wait_object) { + uint64_t timeout = timeout_ptr ? static_cast(*timeout_ptr) : 0u; + result = XObject::SignalAndWait(signal_object.get(), wait_object.get(), 3, 1, alertable, + timeout_ptr ? &timeout : nullptr); + } else { + result = X_STATUS_INVALID_HANDLE; + } + + if (alertable && result == X_STATUS_USER_APC) { + XThread::GetCurrentThread()->DeliverAPCs(); + } + + return result; +} + +// Guest-memory IRQL helpers - read/write current_irql directly from PCR. +// Take PPCContext* explicitly so they work from any thread (including host threads +// during InitializeGuestObject, dispatch thread creation, etc.). +static unsigned char xeKfRaiseIrql(PPCContext* ctx, unsigned char new_irql) { + auto* mem = rex::system::kernel_state()->memory(); + auto pcr = mem->TranslateVirtual(static_cast(ctx->r13.u64)); + uint8_t old_irql = pcr->current_irql; + pcr->current_irql = new_irql; + return old_irql; +} + +static void xeKfLowerIrql(PPCContext* ctx, unsigned char new_irql) { + auto* mem = rex::system::kernel_state()->memory(); + auto pcr = mem->TranslateVirtual(static_cast(ctx->r13.u64)); + pcr->current_irql = new_irql; +} + +// Guest-memory spinlock helpers - store PCR address as owner (matching xenia). +// PPCContext* provides r13 (PCR address) without needing XThread::GetCurrentThread(). +uint32_t xeKeKfAcquireSpinLock(PPCContext* ctx, X_KSPINLOCK* lock, bool change_irql) { + uint32_t old_irql = change_irql ? xeKfRaiseIrql(ctx, IRQL_DISPATCH) : 0; + uint32_t pcr_addr = static_cast(ctx->r13.u64); + assert_true(lock->prcb_of_owner != rex::byte_swap(pcr_addr)); // deadlock detection + while (!rex::thread::atomic_cas(0u, rex::byte_swap(pcr_addr), &lock->prcb_of_owner.value)) { + rex::thread::MaybeYield(); + } + return old_irql; +} + +void xeKeKfReleaseSpinLock(PPCContext* ctx, X_KSPINLOCK* lock, uint32_t old_irql, + bool change_irql) { + assert_true(lock->prcb_of_owner == static_cast(ctx->r13.u64)); + rex::thread::atomic_store_release(0u, &lock->prcb_of_owner.value); + if (change_irql && old_irql < IRQL_DISPATCH) { + xeKfLowerIrql(ctx, static_cast(old_irql)); + } +} + +// Guest-memory APC helpers +void xeKeInitializeApc(XAPC* apc, uint32_t thread_ptr, uint32_t kernel_routine, + uint32_t rundown_routine, uint32_t normal_routine, uint32_t apc_mode, + uint32_t normal_context) { + apc->thread_ptr = thread_ptr; + apc->kernel_routine = kernel_routine; + apc->rundown_routine = rundown_routine; + apc->normal_routine = normal_routine; + apc->type = 18; // ApcObject + if (normal_routine) { + apc->apc_mode = apc_mode; + apc->normal_context = normal_context; + } else { + apc->apc_mode = 0; + apc->normal_context = 0; + } + apc->enqueued = 0; +} + +uint32_t xeKeInsertQueueApc(XAPC* apc, uint32_t arg1, uint32_t arg2, uint32_t priority_increment, + PPCContext* ctx) { + uint32_t thread_guest_pointer = apc->thread_ptr; + if (!thread_guest_pointer) { + return 0; + } + auto* mem = rex::system::kernel_state()->memory(); + auto target_thread = mem->TranslateVirtual(thread_guest_pointer); + auto old_irql = xeKeKfAcquireSpinLock(ctx, &target_thread->apc_lock); + uint32_t result; + if (!target_thread->may_queue_apcs || apc->enqueued) { + result = 0; + } else { + apc->arg1 = arg1; + apc->arg2 = arg2; + + auto& which_list = target_thread->apc_lists[apc->apc_mode]; + + if (apc->normal_routine) { + which_list.InsertTail(apc, mem); + } else { + // Kernel-mode APCs without normal_routine go before those with one. + XAPC* insertion_pos = nullptr; + for (auto&& sub_apc : which_list.IterateForward(mem)) { + insertion_pos = &sub_apc; + if (sub_apc.normal_routine) { + break; + } + } + if (!insertion_pos) { + which_list.InsertHead(apc, mem); + } else { + util::XeInsertHeadList(insertion_pos->list_entry.blink_ptr, &apc->list_entry, mem); + } + } + + apc->enqueued = 1; + result = 1; + } + xeKeKfReleaseSpinLock(ctx, &target_thread->apc_lock, old_irql); + return result; +} + +u32 KfAcquireSpinLock_entry(mapped_u32 lock_ptr) { + auto lock = reinterpret_cast(lock_ptr.host_address()); + return xeKeKfAcquireSpinLock(current_ppc_context(), lock); +} + +void KfReleaseSpinLock_entry(mapped_u32 lock_ptr, u32 old_irql) { + auto lock = reinterpret_cast(lock_ptr.host_address()); + xeKeKfReleaseSpinLock(current_ppc_context(), lock, old_irql); +} + +void KeAcquireSpinLockAtRaisedIrql_entry(mapped_u32 lock_ptr) { + auto lock = reinterpret_cast(lock_ptr.host_address()); + xeKeKfAcquireSpinLock(current_ppc_context(), lock, false); +} + +u32 KeTryToAcquireSpinLockAtRaisedIrql_entry(mapped_u32 lock_ptr) { + auto lock = reinterpret_cast(lock_ptr.host_address()); + auto* ctx = current_ppc_context(); + uint32_t pcr_addr = static_cast(ctx->r13.u64); + if (!rex::thread::atomic_cas(0u, rex::byte_swap(pcr_addr), &lock->prcb_of_owner.value)) { + return 0; + } + return 1; +} + +void KeReleaseSpinLockFromRaisedIrql_entry(mapped_u32 lock_ptr) { + auto lock = reinterpret_cast(lock_ptr.host_address()); + xeKeKfReleaseSpinLock(current_ppc_context(), lock, 0, false); +} + +void KeEnterCriticalRegion_entry() { + XThread::GetCurrentThread()->EnterCriticalRegion(); +} + +void KeLeaveCriticalRegion_entry() { + XThread::GetCurrentThread()->LeaveCriticalRegion(); +} + +u32 KeRaiseIrqlToDpcLevel_entry() { + return xeKfRaiseIrql(current_ppc_context(), IRQL_DISPATCH); +} + +void KfLowerIrql_entry(u32 old_value) { + xeKfLowerIrql(current_ppc_context(), + static_cast(static_cast(old_value))); +} + +u32 KfRaiseIrql_entry(u32 new_irql) { + return xeKfRaiseIrql(current_ppc_context(), + static_cast(static_cast(new_irql))); +} + +void NtQueueApcThread_entry(u32 thread_handle, mapped_void apc_routine, + mapped_void apc_routine_context, mapped_void arg1, mapped_void arg2) { + auto mem = REX_KERNEL_MEMORY(); + auto thread = REX_KERNEL_OBJECTS()->LookupObject(thread_handle); + + if (!thread) { + REXKRNL_ERROR("NtQueueApcThread: Incorrect thread handle! Might cause crash"); + return; + } + + if (!apc_routine) { + REXKRNL_ERROR("NtQueueApcThread: Incorrect apc routine! Might cause crash"); + return; + } + + uint32_t apc_ptr = mem->SystemHeapAlloc(XAPC::kSize); + if (!apc_ptr) { + return; + } + XAPC* apc = mem->TranslateVirtual(apc_ptr); + xeKeInitializeApc(apc, thread->guest_object(), XAPC::kDummyKernelRoutine, 0, + apc_routine.guest_address(), 1 /* user apc mode */, + apc_routine_context.guest_address()); + + if (!xeKeInsertQueueApc(apc, arg1.guest_address(), arg2.guest_address(), 0, + current_ppc_context())) { + mem->SystemHeapFree(apc_ptr); + return; + } + // Match Edge/Canary behavior: callback is only a wakeup hint. + // APC delivery happens via alertable wait handling. + thread->thread()->QueueUserCallback([]() {}); +} + +void KeInitializeApc_entry(ppc_ptr_t apc, mapped_void thread_ptr, mapped_void kernel_routine, + mapped_void rundown_routine, mapped_void normal_routine, + u32 processor_mode, mapped_void normal_context) { + xeKeInitializeApc(apc.host_address(), thread_ptr.guest_address(), kernel_routine.guest_address(), + rundown_routine.guest_address(), normal_routine.guest_address(), processor_mode, + normal_context.guest_address()); +} + +u32 KeInsertQueueApc_entry(ppc_ptr_t apc, mapped_void arg1, mapped_void arg2, + u32 priority_increment) { + return xeKeInsertQueueApc(apc.host_address(), arg1.guest_address(), arg2.guest_address(), + priority_increment, current_ppc_context()); +} + +u32 KeRemoveQueueApc_entry(ppc_ptr_t apc) { + uint32_t thread_guest_pointer = apc->thread_ptr; + if (!thread_guest_pointer) { + return 0; + } + auto* ctx = current_ppc_context(); + auto mem = REX_KERNEL_MEMORY(); + auto target_thread = mem->TranslateVirtual(thread_guest_pointer); + auto old_irql = xeKeKfAcquireSpinLock(ctx, &target_thread->apc_lock); + + bool result = false; + if (apc->enqueued) { + apc->enqueued = 0; + util::XeRemoveEntryList(&apc->list_entry, mem); + result = true; + } + + xeKeKfReleaseSpinLock(ctx, &target_thread->apc_lock, old_irql); + return result ? 1 : 0; +} + +u32 KiApcNormalRoutineNop_entry(u32 unk0 /* output? */, u32 unk1 /* 0x13 */) { + return 0; +} + +void KeInitializeDpc_entry(ppc_ptr_t dpc, mapped_void routine, mapped_void context) { + dpc->Initialize(routine.guest_address(), context.guest_address()); +} + +u32 KeInsertQueueDpc_entry(ppc_ptr_t dpc, u32 arg1, u32 arg2) { + assert_always("DPC does not dispatch yet; going to hang!"); + + uint32_t list_entry_ptr = dpc.guest_address() + 4; + + // Lock dispatcher. + auto global_lock = rex::thread::global_critical_region::AcquireDirect(); + auto dpc_list = REX_KERNEL_STATE()->dpc_list(); + + // If already in a queue, abort. + if (dpc_list->IsQueued(list_entry_ptr)) { + return 0; + } + + // Prep DPC. + dpc->arg1 = (uint32_t)arg1; + dpc->arg2 = (uint32_t)arg2; + + dpc_list->Insert(list_entry_ptr); + + return 1; +} + +u32 KeRemoveQueueDpc_entry(ppc_ptr_t dpc) { + bool result = false; + + uint32_t list_entry_ptr = dpc.guest_address() + 4; + + auto global_lock = rex::thread::global_critical_region::AcquireDirect(); + auto dpc_list = REX_KERNEL_STATE()->dpc_list(); + if (dpc_list->IsQueued(list_entry_ptr)) { + dpc_list->Remove(list_entry_ptr); + result = true; + } + + return result ? 1 : 0; +} + +// https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/blob/51e4dfcaacfdbd1a9692272931a436371492f72d/import/OpenXDK/include/xboxkrnl/xboxkrnl.h#L1372 +struct X_ERWLOCK { + be lock_count; // 0x0 + be writers_waiting_count; // 0x4 + be readers_waiting_count; // 0x8 + be readers_entry_count; // 0xC + X_KEVENT writer_event; // 0x10 + X_KSEMAPHORE reader_semaphore; // 0x20 + X_KSPINLOCK spin_lock; // 0x34 +}; +static_assert_size(X_ERWLOCK, 0x38); + +void ExInitializeReadWriteLock_entry(ppc_ptr_t lock_ptr) { + lock_ptr->lock_count = -1; + lock_ptr->writers_waiting_count = 0; + lock_ptr->readers_waiting_count = 0; + lock_ptr->readers_entry_count = 0; + // Create GuestPointers to struct members with correct guest addresses + ppc_ptr_t event_ptr(&lock_ptr->writer_event, + lock_ptr.guest_address() + offsetof(X_ERWLOCK, writer_event)); + ppc_ptr_t sem_ptr(&lock_ptr->reader_semaphore, + lock_ptr.guest_address() + offsetof(X_ERWLOCK, reader_semaphore)); + KeInitializeEvent_entry(event_ptr, 1, 0); + KeInitializeSemaphore_entry(sem_ptr, 0, 0x7FFFFFFF); + lock_ptr->spin_lock.prcb_of_owner = 0; +} + +void ExAcquireReadWriteLockExclusive_entry(ppc_ptr_t lock_ptr) { + auto* ctx = current_ppc_context(); + auto old_irql = xeKeKfAcquireSpinLock(ctx, &lock_ptr->spin_lock); + + int32_t lock_count = ++lock_ptr->lock_count; + if (!lock_count) { + xeKeKfReleaseSpinLock(ctx, &lock_ptr->spin_lock, old_irql); + return; + } + + lock_ptr->writers_waiting_count++; + + xeKeKfReleaseSpinLock(ctx, &lock_ptr->spin_lock, old_irql); + xeKeWaitForSingleObject(&lock_ptr->writer_event, 7, 0, 0, nullptr); +} + +u32 ExTryToAcquireReadWriteLockExclusive_entry(ppc_ptr_t lock_ptr) { + auto* ctx = current_ppc_context(); + auto old_irql = xeKeKfAcquireSpinLock(ctx, &lock_ptr->spin_lock); + + uint32_t result; + if (lock_ptr->lock_count < 0) { + lock_ptr->lock_count = 0; + result = 1; + } else { + result = 0; + } + + xeKeKfReleaseSpinLock(ctx, &lock_ptr->spin_lock, old_irql); + return result; +} + +void ExAcquireReadWriteLockShared_entry(ppc_ptr_t lock_ptr) { + auto* ctx = current_ppc_context(); + auto old_irql = xeKeKfAcquireSpinLock(ctx, &lock_ptr->spin_lock); + + int32_t lock_count = ++lock_ptr->lock_count; + if (!lock_count || (lock_ptr->readers_entry_count && !lock_ptr->writers_waiting_count)) { + lock_ptr->readers_entry_count++; + xeKeKfReleaseSpinLock(ctx, &lock_ptr->spin_lock, old_irql); + return; + } + + lock_ptr->readers_waiting_count++; + + xeKeKfReleaseSpinLock(ctx, &lock_ptr->spin_lock, old_irql); + xeKeWaitForSingleObject(&lock_ptr->reader_semaphore, 7, 0, 0, nullptr); +} + +u32 ExTryToAcquireReadWriteLockShared_entry(ppc_ptr_t lock_ptr) { + auto* ctx = current_ppc_context(); + auto old_irql = xeKeKfAcquireSpinLock(ctx, &lock_ptr->spin_lock); + + uint32_t result; + if (lock_ptr->lock_count < 0 || + (lock_ptr->readers_entry_count && !lock_ptr->writers_waiting_count)) { + lock_ptr->lock_count++; + lock_ptr->readers_entry_count++; + result = 1; + } else { + result = 0; + } + + xeKeKfReleaseSpinLock(ctx, &lock_ptr->spin_lock, old_irql); + return result; +} + +void ExReleaseReadWriteLock_entry(ppc_ptr_t lock_ptr) { + auto* ctx = current_ppc_context(); + auto old_irql = xeKeKfAcquireSpinLock(ctx, &lock_ptr->spin_lock); + + int32_t lock_count = --lock_ptr->lock_count; + + if (lock_count < 0) { + lock_ptr->readers_entry_count = 0; + xeKeKfReleaseSpinLock(ctx, &lock_ptr->spin_lock, old_irql); + return; + } + + if (!lock_ptr->readers_entry_count) { + auto readers_waiting_count = lock_ptr->readers_waiting_count; + if (readers_waiting_count) { + lock_ptr->readers_waiting_count = 0; + lock_ptr->readers_entry_count = readers_waiting_count; + xeKeKfReleaseSpinLock(ctx, &lock_ptr->spin_lock, old_irql); + xeKeReleaseSemaphore(&lock_ptr->reader_semaphore, 1, readers_waiting_count, 0); + return; + } + } + + auto readers_entry_count = --lock_ptr->readers_entry_count; + if (readers_entry_count) { + xeKeKfReleaseSpinLock(ctx, &lock_ptr->spin_lock, old_irql); + return; + } + + lock_ptr->writers_waiting_count--; + xeKeKfReleaseSpinLock(ctx, &lock_ptr->spin_lock, old_irql); + xeKeSetEvent(&lock_ptr->writer_event, 1, 0); +} + +// NOTE: This function is very commonly inlined, and probably won't be called! +u32 InterlockedPushEntrySList_entry(ppc_ptr_t plist_ptr, + ppc_ptr_t entry) { + assert_not_null(plist_ptr); + assert_not_null(entry); + + alignas(8) X_SLIST_HEADER old_hdr = *plist_ptr; + alignas(8) X_SLIST_HEADER new_hdr = {}; + uint32_t old_head = 0; + do { + old_hdr = *plist_ptr; + new_hdr.depth = old_hdr.depth + 1; + new_hdr.sequence = old_hdr.sequence + 1; + + old_head = old_hdr.next.next; + entry->next = old_hdr.next.next; + new_hdr.next.next = entry.guest_address(); + } while (!rex::thread::atomic_cas(*(uint64_t*)(&old_hdr), *(uint64_t*)(&new_hdr), + reinterpret_cast(plist_ptr.host_address()))); + + return old_head; +} + +u32 InterlockedPopEntrySList_entry(ppc_ptr_t plist_ptr) { + assert_not_null(plist_ptr); + + uint32_t popped = 0; + alignas(8) X_SLIST_HEADER old_hdr = {0}; + alignas(8) X_SLIST_HEADER new_hdr = {0}; + do { + old_hdr = *plist_ptr; + auto next = REX_KERNEL_MEMORY()->TranslateVirtual(old_hdr.next.next); + if (!old_hdr.next.next) { + return 0; + } + popped = old_hdr.next.next; + + new_hdr.depth = old_hdr.depth - 1; + new_hdr.next.next = next->next; + new_hdr.sequence = old_hdr.sequence; + } while (!rex::thread::atomic_cas(*(uint64_t*)(&old_hdr), *(uint64_t*)(&new_hdr), + reinterpret_cast(plist_ptr.host_address()))); + + return popped; +} + +u32 InterlockedFlushSList_entry(ppc_ptr_t plist_ptr) { + assert_not_null(plist_ptr); + + alignas(8) X_SLIST_HEADER old_hdr = *plist_ptr; + alignas(8) X_SLIST_HEADER new_hdr = {0}; + uint32_t first = 0; + do { + old_hdr = *plist_ptr; + first = old_hdr.next.next; + new_hdr.next.next = 0; + new_hdr.depth = 0; + new_hdr.sequence = 0; + } while (!rex::thread::atomic_cas(*(uint64_t*)(&old_hdr), *(uint64_t*)(&new_hdr), + reinterpret_cast(plist_ptr.host_address()))); + + return first; +} + +REX_EXPORT_STUB(__imp__KeInsertByKeyDeviceQueue); +REX_EXPORT_STUB(__imp__KeInsertDeviceQueue); +REX_EXPORT_STUB(__imp__KeInsertHeadQueue); +REX_EXPORT_STUB(__imp__KeInsertQueue); +REX_EXPORT_STUB(__imp__KeReleaseMutant); +REX_EXPORT_STUB(__imp__KeRemoveByKeyDeviceQueue); +REX_EXPORT_STUB(__imp__KeRemoveDeviceQueue); +REX_EXPORT_STUB(__imp__KeRemoveEntryDeviceQueue); +REX_EXPORT_STUB(__imp__KeRemoveQueue); +REX_EXPORT_STUB(__imp__KeSetEventBoostPriority); +REX_EXPORT_STUB(__imp__KiApcNormalRoutineNop_); + +u32 KeSuspendThread_entry(mapped_void kthread_ptr) { + auto thread = XObject::GetNativeObject(REX_KERNEL_STATE(), kthread_ptr); + uint32_t old_suspend_count = 0; + + if (thread) { + old_suspend_count = thread->suspend_count(); + uint32_t discarded = 0; + thread->Suspend(&discarded); + } + + return old_suspend_count; +} + +} // namespace rex::kernel::xboxkrnl + +REX_EXPORT(__imp__ExCreateThread, rex::kernel::xboxkrnl::ExCreateThread_entry) +REX_EXPORT(__imp__ExTerminateThread, rex::kernel::xboxkrnl::ExTerminateThread_entry) +REX_EXPORT(__imp__NtResumeThread, rex::kernel::xboxkrnl::NtResumeThread_entry) +REX_EXPORT(__imp__KeResumeThread, rex::kernel::xboxkrnl::KeResumeThread_entry) +REX_EXPORT(__imp__NtSuspendThread, rex::kernel::xboxkrnl::NtSuspendThread_entry) +REX_EXPORT(__imp__KeSuspendThread, rex::kernel::xboxkrnl::KeSuspendThread_entry) +REX_EXPORT(__imp__KeSetCurrentStackPointers, rex::kernel::xboxkrnl::KeSetCurrentStackPointers_entry) +REX_EXPORT(__imp__KeSetAffinityThread, rex::kernel::xboxkrnl::KeSetAffinityThread_entry) +REX_EXPORT(__imp__KeQueryBasePriorityThread, rex::kernel::xboxkrnl::KeQueryBasePriorityThread_entry) +REX_EXPORT(__imp__KeSetBasePriorityThread, rex::kernel::xboxkrnl::KeSetBasePriorityThread_entry) +REX_EXPORT(__imp__KeSetDisableBoostThread, rex::kernel::xboxkrnl::KeSetDisableBoostThread_entry) +REX_EXPORT(__imp__KeGetCurrentProcessType, rex::kernel::xboxkrnl::KeGetCurrentProcessType_entry) +REX_EXPORT(__imp__KeSetCurrentProcessType, rex::kernel::xboxkrnl::KeSetCurrentProcessType_entry) +REX_EXPORT(__imp__KeQueryPerformanceFrequency, + rex::kernel::xboxkrnl::KeQueryPerformanceFrequency_entry) +REX_EXPORT(__imp__KeDelayExecutionThread, rex::kernel::xboxkrnl::KeDelayExecutionThread_entry) +REX_EXPORT(__imp__NtYieldExecution, rex::kernel::xboxkrnl::NtYieldExecution_entry) +REX_EXPORT(__imp__KeQuerySystemTime, rex::kernel::xboxkrnl::KeQuerySystemTime_entry) +REX_EXPORT(__imp__KeTlsAlloc, rex::kernel::xboxkrnl::KeTlsAlloc_entry) +REX_EXPORT(__imp__KeTlsFree, rex::kernel::xboxkrnl::KeTlsFree_entry) +REX_EXPORT(__imp__KeTlsGetValue, rex::kernel::xboxkrnl::KeTlsGetValue_entry) +REX_EXPORT(__imp__KeTlsSetValue, rex::kernel::xboxkrnl::KeTlsSetValue_entry) +REX_EXPORT(__imp__KeInitializeEvent, rex::kernel::xboxkrnl::KeInitializeEvent_entry) +REX_EXPORT(__imp__KeSetEvent, rex::kernel::xboxkrnl::KeSetEvent_entry) +REX_EXPORT(__imp__KePulseEvent, rex::kernel::xboxkrnl::KePulseEvent_entry) +REX_EXPORT(__imp__KeResetEvent, rex::kernel::xboxkrnl::KeResetEvent_entry) +REX_EXPORT(__imp__NtCreateEvent, rex::kernel::xboxkrnl::NtCreateEvent_entry) +REX_EXPORT(__imp__NtSetEvent, rex::kernel::xboxkrnl::NtSetEvent_entry) +REX_EXPORT(__imp__NtPulseEvent, rex::kernel::xboxkrnl::NtPulseEvent_entry) +REX_EXPORT(__imp__NtClearEvent, rex::kernel::xboxkrnl::NtClearEvent_entry) +REX_EXPORT(__imp__KeInitializeSemaphore, rex::kernel::xboxkrnl::KeInitializeSemaphore_entry) +REX_EXPORT(__imp__KeReleaseSemaphore, rex::kernel::xboxkrnl::KeReleaseSemaphore_entry) +REX_EXPORT(__imp__NtCreateSemaphore, rex::kernel::xboxkrnl::NtCreateSemaphore_entry) +REX_EXPORT(__imp__NtReleaseSemaphore, rex::kernel::xboxkrnl::NtReleaseSemaphore_entry) +REX_EXPORT(__imp__NtCreateMutant, rex::kernel::xboxkrnl::NtCreateMutant_entry) +REX_EXPORT(__imp__NtReleaseMutant, rex::kernel::xboxkrnl::NtReleaseMutant_entry) +REX_EXPORT(__imp__NtCreateTimer, rex::kernel::xboxkrnl::NtCreateTimer_entry) +REX_EXPORT(__imp__NtSetTimerEx, rex::kernel::xboxkrnl::NtSetTimerEx_entry) +REX_EXPORT(__imp__NtCancelTimer, rex::kernel::xboxkrnl::NtCancelTimer_entry) +REX_EXPORT(__imp__KeInitializeTimerEx, rex::kernel::xboxkrnl::KeInitializeTimerEx_entry) +REX_EXPORT(__imp__KeWaitForSingleObject, rex::kernel::xboxkrnl::KeWaitForSingleObject_entry) +REX_EXPORT(__imp__NtWaitForSingleObjectEx, rex::kernel::xboxkrnl::NtWaitForSingleObjectEx_entry) +REX_EXPORT(__imp__KeWaitForMultipleObjects, rex::kernel::xboxkrnl::KeWaitForMultipleObjects_entry) +REX_EXPORT(__imp__NtWaitForMultipleObjectsEx, + rex::kernel::xboxkrnl::NtWaitForMultipleObjectsEx_entry) +REX_EXPORT(__imp__NtSignalAndWaitForSingleObjectEx, + rex::kernel::xboxkrnl::NtSignalAndWaitForSingleObjectEx_entry) +REX_EXPORT(__imp__KfAcquireSpinLock, rex::kernel::xboxkrnl::KfAcquireSpinLock_entry) +REX_EXPORT(__imp__KfReleaseSpinLock, rex::kernel::xboxkrnl::KfReleaseSpinLock_entry) +REX_EXPORT(__imp__KeAcquireSpinLockAtRaisedIrql, + rex::kernel::xboxkrnl::KeAcquireSpinLockAtRaisedIrql_entry) +REX_EXPORT(__imp__KeTryToAcquireSpinLockAtRaisedIrql, + rex::kernel::xboxkrnl::KeTryToAcquireSpinLockAtRaisedIrql_entry) +REX_EXPORT(__imp__KeReleaseSpinLockFromRaisedIrql, + rex::kernel::xboxkrnl::KeReleaseSpinLockFromRaisedIrql_entry) +REX_EXPORT(__imp__KeEnterCriticalRegion, rex::kernel::xboxkrnl::KeEnterCriticalRegion_entry) +REX_EXPORT(__imp__KeLeaveCriticalRegion, rex::kernel::xboxkrnl::KeLeaveCriticalRegion_entry) +REX_EXPORT(__imp__KeRaiseIrqlToDpcLevel, rex::kernel::xboxkrnl::KeRaiseIrqlToDpcLevel_entry) +REX_EXPORT(__imp__KfLowerIrql, rex::kernel::xboxkrnl::KfLowerIrql_entry) +REX_EXPORT(__imp__NtQueueApcThread, rex::kernel::xboxkrnl::NtQueueApcThread_entry) +REX_EXPORT(__imp__KeInitializeApc, rex::kernel::xboxkrnl::KeInitializeApc_entry) +REX_EXPORT(__imp__KeInsertQueueApc, rex::kernel::xboxkrnl::KeInsertQueueApc_entry) +REX_EXPORT(__imp__KeRemoveQueueApc, rex::kernel::xboxkrnl::KeRemoveQueueApc_entry) +REX_EXPORT(__imp__KiApcNormalRoutineNop, rex::kernel::xboxkrnl::KiApcNormalRoutineNop_entry) +REX_EXPORT(__imp__KeInitializeDpc, rex::kernel::xboxkrnl::KeInitializeDpc_entry) +REX_EXPORT(__imp__KeInsertQueueDpc, rex::kernel::xboxkrnl::KeInsertQueueDpc_entry) +REX_EXPORT(__imp__KeRemoveQueueDpc, rex::kernel::xboxkrnl::KeRemoveQueueDpc_entry) +REX_EXPORT(__imp__ExInitializeReadWriteLock, rex::kernel::xboxkrnl::ExInitializeReadWriteLock_entry) +REX_EXPORT(__imp__ExAcquireReadWriteLockExclusive, + rex::kernel::xboxkrnl::ExAcquireReadWriteLockExclusive_entry) +REX_EXPORT(__imp__ExTryToAcquireReadWriteLockExclusive, + rex::kernel::xboxkrnl::ExTryToAcquireReadWriteLockExclusive_entry) +REX_EXPORT(__imp__ExAcquireReadWriteLockShared, + rex::kernel::xboxkrnl::ExAcquireReadWriteLockShared_entry) +REX_EXPORT(__imp__ExTryToAcquireReadWriteLockShared, + rex::kernel::xboxkrnl::ExTryToAcquireReadWriteLockShared_entry) +REX_EXPORT(__imp__ExReleaseReadWriteLock, rex::kernel::xboxkrnl::ExReleaseReadWriteLock_entry) +REX_EXPORT(__imp__InterlockedPushEntrySList, rex::kernel::xboxkrnl::InterlockedPushEntrySList_entry) +REX_EXPORT(__imp__InterlockedPopEntrySList, rex::kernel::xboxkrnl::InterlockedPopEntrySList_entry) +REX_EXPORT(__imp__InterlockedFlushSList, rex::kernel::xboxkrnl::InterlockedFlushSList_entry) + +REX_EXPORT_STUB(__imp__KeAlertResumeThread); +REX_EXPORT_STUB(__imp__KeAlertThread); +REX_EXPORT_STUB(__imp__KeBoostPriorityThread); +REX_EXPORT_STUB(__imp__KeCancelTimer); +REX_EXPORT_STUB(__imp__KeConnectInterrupt); +REX_EXPORT_STUB(__imp__KeContextFromKframes); +REX_EXPORT_STUB(__imp__KeContextToKframes); +REX_EXPORT_STUB(__imp__KeDisconnectInterrupt); +REX_EXPORT_STUB(__imp__KeFlushCacheRange); +REX_EXPORT_STUB(__imp__KeFlushCurrentEntireTb); +REX_EXPORT_STUB(__imp__KeFlushEntireTb); +REX_EXPORT_STUB(__imp__KeFlushMultipleTb); +REX_EXPORT_STUB(__imp__KeFlushUserModeCurrentTb); +REX_EXPORT_STUB(__imp__KeFlushUserModeTb); +REX_EXPORT_STUB(__imp__KeInitializeDeviceQueue); +REX_EXPORT_STUB(__imp__KeInitializeInterrupt); +REX_EXPORT_STUB(__imp__KeInitializeMutant); +REX_EXPORT_STUB(__imp__KeInitializeQueue); +// REX_EXPORT_STUB(__imp__KeInitializeTimerEx); -- implemented below +REX_EXPORT_STUB(__imp__KeIpiGenericCall); +REX_EXPORT_STUB(__imp__KeQueryBackgroundProcessors); +REX_EXPORT_STUB(__imp__KeQueryInterruptTime); +REX_EXPORT_STUB(__imp__KeRegisterDriverNotification); +REX_EXPORT_STUB(__imp__KeRestoreFloatingPointState); +REX_EXPORT_STUB(__imp__KeRestoreVectorUnitState); +REX_EXPORT_STUB(__imp__KeRetireDpcList); +REX_EXPORT_STUB(__imp__KeRundownQueue); +REX_EXPORT_STUB(__imp__KeSaveFloatingPointState); +REX_EXPORT_STUB(__imp__KeSaveVectorUnitState); +REX_EXPORT_STUB(__imp__KeSetBackgroundProcessors); +REX_EXPORT_STUB(__imp__KeSetPriorityClassThread); +REX_EXPORT_STUB(__imp__KeSetPriorityThread); +REX_EXPORT_STUB(__imp__KeSetTimer); +REX_EXPORT_STUB(__imp__KeSetTimerEx); +REX_EXPORT_STUB(__imp__KeStallExecutionProcessor); +REX_EXPORT_STUB(__imp__KeSweepDcacheRange); +REX_EXPORT_STUB(__imp__KeSweepIcacheRange); +REX_EXPORT_STUB(__imp__KeTestAlertThread); +REX_EXPORT(__imp__KfRaiseIrql, rex::kernel::xboxkrnl::KfRaiseIrql_entry) diff --git a/src/kernel/xboxkrnl/xboxkrnl_usbcam.cpp b/src/kernel/xboxkrnl/xboxkrnl_usbcam.cpp new file mode 100644 index 0000000..e9d0b04 --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_usbcam.cpp @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { + +u32 XUsbcamCreate_entry(u32 buffer, + u32 buffer_size, // 0x4B000 640x480? + mapped_void unk3_ptr) { + // This function should return success. + // It looks like it only allocates space for usbcam support. + // returning error code might cause games to initialize incorrectly. + // "Carcassonne" initalization function checks for result from this + // function. If value is different than 0 instead of loading + // rest of the game it returns from initalization function and tries + // to run game normally which causes crash, due to uninitialized data. + return X_STATUS_SUCCESS; +} + +u32 XUsbcamGetState_entry() { + // 0 = not connected. + return 0; +} + +} // namespace rex::kernel::xboxkrnl + +REX_EXPORT(__imp__XUsbcamCreate, rex::kernel::xboxkrnl::XUsbcamCreate_entry) +REX_EXPORT(__imp__XUsbcamGetState, rex::kernel::xboxkrnl::XUsbcamGetState_entry) + +REX_EXPORT_STUB(__imp__XUsbcamSetCaptureMode); +REX_EXPORT_STUB(__imp__XUsbcamGetConfig); +REX_EXPORT_STUB(__imp__XUsbcamSetConfig); +REX_EXPORT_STUB(__imp__XUsbcamReadFrame); +REX_EXPORT_STUB(__imp__XUsbcamSnapshot); +REX_EXPORT_STUB(__imp__XUsbcamSetView); +REX_EXPORT_STUB(__imp__XUsbcamGetView); +REX_EXPORT_STUB(__imp__XUsbcamDestroy); +REX_EXPORT_STUB(__imp__XUsbcamReset); diff --git a/src/kernel/xboxkrnl/xboxkrnl_video.cpp b/src/kernel/xboxkrnl/xboxkrnl_video.cpp new file mode 100644 index 0000000..4bbd539 --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_video.cpp @@ -0,0 +1,572 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { +// Display gamma type: 0 - linear, 1 - sRGB (CRT), 2 - BT.709 (HDTV), 3 - power +constexpr uint32_t kDisplayGammaType = 2; +// Display gamma power (used with gamma type 3) +constexpr double kDisplayGammaPower = 2.22222233; + +uint32_t GetConfiguredVideoModeWidth() { + int32_t configured_width = REXCVAR_GET(video_mode_width); + if (!rex::cvar::HasNonDefaultValue("video_mode_width")) { + if (rex::cvar::HasNonDefaultValue("window_width") && REXCVAR_GET(window_width) > 0) { + configured_width = REXCVAR_GET(window_width); + } else { + int32_t preset_width = 0; + int32_t preset_height = 0; + if (rex::graphics::video_mode_util::TryGetResolutionPresetFromCVar(preset_width, + preset_height)) { + configured_width = preset_width; + } + } + } + return uint32_t(std::clamp(configured_width, 640, 0x0FFF)); +} + +uint32_t GetConfiguredVideoModeHeight() { + int32_t configured_height = REXCVAR_GET(video_mode_height); + if (!rex::cvar::HasNonDefaultValue("video_mode_height")) { + if (rex::cvar::HasNonDefaultValue("window_height") && REXCVAR_GET(window_height) > 0) { + configured_height = REXCVAR_GET(window_height); + } else { + int32_t preset_width = 0; + int32_t preset_height = 0; + if (rex::graphics::video_mode_util::TryGetResolutionPresetFromCVar(preset_width, + preset_height)) { + configured_height = preset_height; + } + } + } + return uint32_t(std::clamp(configured_height, 480, 0x0FFF)); +} + +float GetConfiguredVideoModeRefreshRate() { + double refresh_rate_hz = std::clamp(REXCVAR_GET(video_mode_refresh_rate), 24.0, 240.0); + return float(refresh_rate_hz); +} +} // namespace + +namespace rex::kernel::xboxkrnl { +using namespace rex::system; + +REX_EXPORT_STUB(__imp__VdBlockUntilGUIIdle); +REX_EXPORT_STUB(__imp__VdDisplayFatalError); +REX_EXPORT_STUB(__imp__VdEnableClosedCaption); +REX_EXPORT_STUB(__imp__VdEnableDisablePowerSavingMode); +REX_EXPORT_STUB(__imp__VdGenerateGPUCSCCoefficients); +REX_EXPORT_STUB(__imp__VdGetClosedCaptionReadyStatus); +REX_EXPORT_STUB(__imp__VdGetDisplayModeOverride); +REX_EXPORT_STUB(__imp__VdInitializeScaler); +REX_EXPORT_STUB(__imp__VdQuerySystemCommandBuffer); +REX_EXPORT_STUB(__imp__VdReadDVERegisterUlong); +REX_EXPORT_STUB(__imp__VdReadWriteHSIOCalibrationFlag); +REX_EXPORT_STUB(__imp__VdRegisterGraphicsNotification); +REX_EXPORT_STUB(__imp__VdRegisterXamGraphicsNotification); +REX_EXPORT_STUB(__imp__VdSendClosedCaptionData); +REX_EXPORT_STUB(__imp__VdSetCGMSOption); +REX_EXPORT_STUB(__imp__VdSetColorProfileAdjustment); +REX_EXPORT_STUB(__imp__VdSetCscMatricesOverride); +REX_EXPORT_STUB(__imp__VdSetHDCPOption); +REX_EXPORT_STUB(__imp__VdSetMacrovisionOption); +REX_EXPORT_STUB(__imp__VdSetSystemCommandBuffer); +REX_EXPORT_STUB(__imp__VdSetWSSData); +REX_EXPORT_STUB(__imp__VdSetWSSOption); +REX_EXPORT_STUB(__imp__VdTurnDisplayOff); +REX_EXPORT_STUB(__imp__VdTurnDisplayOn); +REX_EXPORT_STUB(__imp__VdWriteDVERegisterUlong); +REX_EXPORT_STUB(__imp__VdInitializeEDRAM); +REX_EXPORT_STUB(__imp__VdReadEEDIDBlock); +REX_EXPORT_STUB(__imp__VdEnumerateVideoModes); +REX_EXPORT_STUB(__imp__VdEnableHDCP); +REX_EXPORT_STUB(__imp__VdRegisterHDCPNotification); +REX_EXPORT_STUB(__imp__VdGetDisplayDiscoveryData); +REX_EXPORT_STUB(__imp__VdStartDisplayDiscovery); +REX_EXPORT_STUB(__imp__VdSetHDCPRevocationList); +REX_EXPORT_STUB(__imp__VdEnableWMAProOverHDMI); +REX_EXPORT_STUB(__imp__VdQueryRealVideoMode); +REX_EXPORT_STUB(__imp__VdSetCGMSState); +REX_EXPORT_STUB(__imp__VdSetSCMSState); +REX_EXPORT_STUB(__imp__VdGetOption); +REX_EXPORT_STUB(__imp__VdSetOption); +REX_EXPORT_STUB(__imp__VdQueryVideoCapabilities); +REX_EXPORT_STUB(__imp__VdGet3dVideoFormat); +REX_EXPORT_STUB(__imp__VdGetWSS2Data); +REX_EXPORT_STUB(__imp__VdSet3dVideoFormat); +REX_EXPORT_STUB(__imp__VdSetWSS2Data); +REX_EXPORT_STUB(__imp__VdSetStudioRGBMode); + +// https://web.archive.org/web/20150805074003/https://www.tweakoz.com/orkid/ +// http://www.tweakoz.com/orkid/dox/d3/d52/xb360init_8cpp_source.html +// https://github.com/Free60Project/xenosfb/ +// https://github.com/Free60Project/xenosfb/blob/master/src/xe.h +// https://github.com/gligli/libxemit +// https://web.archive.org/web/20090428095215/https://msdn.microsoft.com/en-us/library/bb313877.aspx +// https://web.archive.org/web/20100423054747/https://msdn.microsoft.com/en-us/library/bb313961.aspx +// https://web.archive.org/web/20100423054747/https://msdn.microsoft.com/en-us/library/bb313878.aspx +// https://web.archive.org/web/20090510235238/https://msdn.microsoft.com/en-us/library/bb313942.aspx +// https://svn.dd-wrt.com/browser/src/linux/universal/linux-3.8/drivers/gpu/drm/radeon/radeon_ring.c?rev=21595 +// https://www.microsoft.com/en-za/download/details.aspx?id=5313 -- "Stripped +// Down Direct3D: Xbox 360 Command Buffer and Resource Management" + +void VdGetCurrentDisplayGamma_entry(mapped_u32 type_ptr, mapped_f32 power_ptr) { + // 1 - sRGB. + // 2 - TV (BT.709). + // 3 - use the power written to *power_ptr. + // Anything else - linear. + // Used in D3D SetGammaRamp/SetPWLGamma to adjust the ramp for the display. + *type_ptr = kDisplayGammaType; + *power_ptr = float(kDisplayGammaPower); +} + +struct X_D3DPRIVATE_RECT { + rex::be x1; // 0x0 + rex::be y1; // 0x4 + rex::be x2; // 0x8 + rex::be y2; // 0xC +}; +static_assert_size(X_D3DPRIVATE_RECT, 0x10); + +struct X_D3DFILTER_PARAMETERS { + rex::be nyquist; // 0x0 + rex::be flicker_filter; // 0x4 + rex::be beta; // 0x8 +}; +static_assert_size(X_D3DFILTER_PARAMETERS, 0xC); + +struct X_D3DPRIVATE_SCALER_PARAMETERS { + X_D3DPRIVATE_RECT scaler_source_rect; // 0x0 + rex::be scaled_output_width; // 0x10 + rex::be scaled_output_height; // 0x14 + rex::be vertical_filter_type; // 0x18 + X_D3DFILTER_PARAMETERS vertical_filter_parameters; // 0x1C + rex::be horizontal_filter_type; // 0x28 + X_D3DFILTER_PARAMETERS horizontal_filter_parameters; // 0x2C +}; +static_assert_size(X_D3DPRIVATE_SCALER_PARAMETERS, 0x38); + +struct X_DISPLAY_INFO { + rex::be front_buffer_width; // 0x0 + rex::be front_buffer_height; // 0x2 + uint8_t front_buffer_color_format; // 0x4 + uint8_t front_buffer_pixel_format; // 0x5 + X_D3DPRIVATE_SCALER_PARAMETERS scaler_parameters; // 0x8 + rex::be display_window_overscan_left; // 0x40 + rex::be display_window_overscan_top; // 0x42 + rex::be display_window_overscan_right; // 0x44 + rex::be display_window_overscan_bottom; // 0x46 + rex::be display_width; // 0x48 + rex::be display_height; // 0x4A + rex::be display_refresh_rate; // 0x4C + rex::be display_interlaced; // 0x50 + uint8_t display_color_format; // 0x54 + rex::be actual_display_width; // 0x56 +}; +static_assert_size(X_DISPLAY_INFO, 0x58); + +void VdGetCurrentDisplayInformation_entry(ppc_ptr_t display_info) { + X_VIDEO_MODE mode; + VdQueryVideoMode(&mode); + display_info.Zero(); + display_info->front_buffer_width = (uint16_t)mode.display_width; + display_info->front_buffer_height = (uint16_t)mode.display_height; + + display_info->scaler_parameters.scaler_source_rect.x2 = mode.display_width; + display_info->scaler_parameters.scaler_source_rect.y2 = mode.display_height; + display_info->scaler_parameters.scaled_output_width = mode.display_width; + display_info->scaler_parameters.scaled_output_height = mode.display_height; + display_info->scaler_parameters.horizontal_filter_type = 1; + display_info->scaler_parameters.vertical_filter_type = 1; + + uint16_t overscan_x = uint16_t(uint32_t(mode.display_width) / 4); + uint16_t overscan_y = uint16_t(uint32_t(mode.display_height) / 4); + display_info->display_window_overscan_left = overscan_x; + display_info->display_window_overscan_top = overscan_y; + display_info->display_window_overscan_right = overscan_x; + display_info->display_window_overscan_bottom = overscan_y; + display_info->display_width = (uint16_t)mode.display_width; + display_info->display_height = (uint16_t)mode.display_height; + display_info->display_refresh_rate = mode.refresh_rate; + display_info->actual_display_width = (uint16_t)mode.display_width; +} + +void VdQueryVideoMode(X_VIDEO_MODE* video_mode) { + // Exposed as CVARs so the guest can observe custom display settings. + uint32_t display_width = GetConfiguredVideoModeWidth(); + uint32_t display_height = GetConfiguredVideoModeHeight(); + float refresh_rate_hz = GetConfiguredVideoModeRefreshRate(); + + std::memset(video_mode, 0, sizeof(X_VIDEO_MODE)); + video_mode->display_width = display_width; + video_mode->display_height = display_height; + video_mode->is_interlaced = 0; + video_mode->is_widescreen = display_width * 3 >= display_height * 4; + video_mode->is_hi_def = display_width >= 1280 || display_height >= 720; + video_mode->refresh_rate = refresh_rate_hz; + video_mode->video_standard = 1; // NTSC + video_mode->unknown_0x8a = 0x4A; + video_mode->unknown_0x01 = 0x01; +} + +void VdQueryVideoMode_entry(ppc_ptr_t video_mode) { + VdQueryVideoMode(video_mode); +} + +u32 VdQueryVideoFlags_entry() { + X_VIDEO_MODE mode; + VdQueryVideoMode(&mode); + + uint32_t flags = 0; + flags |= mode.is_widescreen ? 1 : 0; + flags |= mode.display_width >= 1024 ? 2 : 0; + flags |= mode.display_width >= 1920 ? 4 : 0; + + return flags; +} + +u32 VdSetDisplayMode_entry(u32 flags) { + // Often 0x40000000. + + // 0?ccf000 00000000 00000000 000000r0 + + // r: 0x00000002 | 1 + // f: 0x08000000 | 27 + // c: 0x30000000 | 28-29 + // ?: 0x40000000 | 30 + + // r: 1 = Resolution is 720x480 or 720x576 + // f: 1 = Texture format is k_2_10_10_10 or k_2_10_10_10_AS_16_16_16_16 + // c: Color space (0 = RGB, 1 = ?, 2 = ?) + // ?: (always set?) + + return 0; +} + +u32 VdSetDisplayModeOverride_entry(u32 unk0, u32 unk1, f64 refresh_rate, u32 unk3, u32 unk4) { + // refresh_rate = 0, 50, 59.9, etc. + return 0; +} + +u32 VdInitializeEngines_entry(u32 unk0, u32 callback, mapped_void arg, mapped_u32 pfp_ptr, + mapped_u32 me_ptr) { + // r3 = 0x4F810000 + // r4 = function ptr (cleanup callback?) + // r5 = function arg + // r6 = PFP Microcode + // r7 = ME Microcode + return 1; +} + +void VdShutdownEngines_entry() { + // Ignored for now. + // Games seem to call an Initialize/Shutdown pair to query info, then + // re-initialize. +} + +u32 VdGetGraphicsAsicID_entry() { + // Games compare for < 0x10 and do VdInitializeEDRAM, else other + // (retrain/etc). + return 0x11; +} + +u32 VdEnableDisableClockGating_entry(u32 enabled) { + // Ignored, as it really doesn't matter. + return 0; +} + +void VdSetGraphicsInterruptCallback_entry(u32 callback, mapped_void user_data) { + // callback takes 2 params + // r3 = bool 0/1 - 0 is normal interrupt, 1 is some acquire/lock mumble + // r4 = user_data (r4 of VdSetGraphicsInterruptCallback) + auto* graphics_system = + static_cast(REX_KERNEL_STATE()->emulator()->graphics_system()); + if (!graphics_system) + return; + graphics_system->SetInterruptCallback(callback, user_data.guest_address()); +} + +void VdInitializeRingBuffer_entry(mapped_void ptr, i32 size_log2) { + // r3 = result of MmGetPhysicalAddress + // r4 = log2(size) + // Buffer pointers are from MmAllocatePhysicalMemory with WRITE_COMBINE. + auto* graphics_system = + static_cast(REX_KERNEL_STATE()->emulator()->graphics_system()); + if (!graphics_system) + return; + graphics_system->InitializeRingBuffer(ptr.guest_address(), size_log2); +} + +void VdEnableRingBufferRPtrWriteBack_entry(mapped_void ptr, i32 block_size_log2) { + // r4 = log2(block size), 6, usually --- <=19 + auto* graphics_system = + static_cast(REX_KERNEL_STATE()->emulator()->graphics_system()); + if (!graphics_system) + return; + graphics_system->EnableReadPointerWriteBack(ptr.guest_address(), block_size_log2); +} + +void VdGetSystemCommandBuffer_entry(mapped_void p0_ptr, mapped_void p1_ptr) { + p0_ptr.Zero(0x94); + memory::store_and_swap(p0_ptr, 0xBEEF0000); + memory::store_and_swap(p1_ptr, 0xBEEF0001); +} + +void VdSetSystemCommandBufferGpuIdentifierAddress_entry(mapped_void unk) { + // r3 = 0x2B10(d3d?) + 8 +} + +// VdVerifyMEInitCommand +// r3 +// r4 = 19 +// no op? + +u32 VdInitializeScalerCommandBuffer_entry( + u32 scaler_source_xy, // ((uint16_t)y << 16) | (uint16_t)x + u32 scaler_source_wh, // ((uint16_t)h << 16) | (uint16_t)w + u32 scaled_output_xy, // ((uint16_t)y << 16) | (uint16_t)x + u32 scaled_output_wh, // ((uint16_t)h << 16) | (uint16_t)w + u32 front_buffer_wh, // ((uint16_t)h << 16) | (uint16_t)w + u32 vertical_filter_type, // 7? + ppc_ptr_t vertical_filter_params, // + u32 horizontal_filter_type, // 7? + ppc_ptr_t horizontal_filter_params, // + mapped_void unk9, // + mapped_void dest_ptr, // Points to the first 80000000h where the memcpy + // sources from. + u32 dest_count // Count in words. +) { + // We could fake the commands here, but I'm not sure the game checks for + // anything but success (non-zero ret). + // For now, we just fill it with NOPs. + auto dest = dest_ptr.as_array(); + for (size_t i = 0; i < dest_count; ++i) { + dest[i] = 0x80000000; + } + return (uint32_t)dest_count; +} + +struct BufferScaling { + rex::be fb_width; + rex::be fb_height; + rex::be bb_width; + rex::be bb_height; +}; +void AppendParam(string::StringBuffer* string_buffer, ppc_ptr_t param) { + string_buffer->AppendFormat("{:08X}(scale {}x{} -> {}x{}))", param.guest_address(), + uint16_t(param->bb_width), uint16_t(param->bb_height), + uint16_t(param->fb_width), uint16_t(param->fb_height)); +} + +u32 VdCallGraphicsNotificationRoutines_entry(u32 unk0, ppc_ptr_t args_ptr) { + assert_true(unk0 == 1); + + // TODO(benvanik): what does this mean, I forget: + // callbacks get 0, r3, r4 + + return 0; +} + +u32 VdIsHSIOTrainingSucceeded_entry() { + // BOOL return value + return 1; +} + +u32 VdPersistDisplay_entry(u32 unk0, mapped_u32 unk1_ptr) { + // unk1_ptr needs to be populated with a pointer passed to + // MmFreePhysicalMemory(1, *unk1_ptr). + if (unk1_ptr) { + auto heap = REX_KERNEL_MEMORY()->LookupHeapByType(true, 16 * 1024); + uint32_t unk1_value; + heap->Alloc(64, 32, memory::kMemoryAllocationReserve | memory::kMemoryAllocationCommit, + memory::kMemoryProtectNoAccess, false, &unk1_value); + *unk1_ptr = unk1_value; + } + + return 1; +} + +u32 VdRetrainEDRAMWorker_entry(u32 unk0) { + return 0; +} + +u32 VdRetrainEDRAM_entry(u32 unk0, u32 unk1, u32 unk2, u32 unk3, u32 unk4, u32 unk5) { + return 0; +} + +void VdSwap_entry(mapped_void buffer_ptr, // ptr into primary ringbuffer + mapped_void fetch_ptr, // frontbuffer Direct3D 9 texture header fetch + mapped_void unk2, // system writeback ptr + mapped_void unk3, // buffer from VdGetSystemCommandBuffer + mapped_void unk4, // from VdGetSystemCommandBuffer (0xBEEF0001) + mapped_u32 frontbuffer_ptr, // ptr to frontbuffer address + mapped_u32 texture_format_ptr, mapped_u32 color_space_ptr, mapped_u32 width, + mapped_u32 height) { + // All of these parameters are REQUIRED. + assert(buffer_ptr); + assert(fetch_ptr); + assert(frontbuffer_ptr); + assert(texture_format_ptr); + assert(width); + assert(height); + + namespace xenos = rex::graphics::xenos; + + xenos::xe_gpu_texture_fetch_t gpu_fetch; + memory::copy_and_swap_32_unaligned(&gpu_fetch, + reinterpret_cast(fetch_ptr.host_address()), 6); + + // The fetch constant passed is not a true GPU fetch constant, but rather, the + // fetch constant stored in the Direct3D 9 texture header, which contains the + // address in one of the virtual mappings of the physical memory rather than + // the physical address itself. We're emulating swapping in the GPU subsystem, + // which works with GPU memory addresses (physical addresses directly) from + // proper fetch constants like ones used to bind textures to shaders, not CPU + // MMU addresses, so translation from virtual to physical is needed. + uint32_t frontbuffer_virtual_address = gpu_fetch.base_address << 12; + assert_true(*frontbuffer_ptr == frontbuffer_virtual_address); + uint32_t frontbuffer_physical_address = + REX_KERNEL_MEMORY()->GetPhysicalAddress(frontbuffer_virtual_address); + assert_true(frontbuffer_physical_address != UINT32_MAX); + if (frontbuffer_physical_address == UINT32_MAX) { + // Xenia-specific safety check. + REXKRNL_ERROR("VdSwap: Invalid front buffer virtual address 0x{:08X}", + frontbuffer_virtual_address); + return; + } + gpu_fetch.base_address = frontbuffer_physical_address >> 12; + + auto texture_format = rex::graphics::xenos::TextureFormat(texture_format_ptr.value()); + auto color_space = *color_space_ptr; + assert_true(texture_format == rex::graphics::xenos::TextureFormat::k_8_8_8_8 || + texture_format == rex::graphics::xenos::TextureFormat::k_2_10_10_10_AS_16_16_16_16); + assert_true(color_space == 0); // RGB(0) + assert_true(*width == 1 + gpu_fetch.size_2d.width); + assert_true(*height == 1 + gpu_fetch.size_2d.height); + + // The caller seems to reserve 64 words (256b) in the primary ringbuffer + // for this method to do what it needs. We just zero them out and send a + // token value. It'd be nice to figure out what this is really doing so + // that we could simulate it, though due to TCR I bet all games need to + // use this method. + buffer_ptr.Zero(64 * 4); + + uint32_t offset = 0; + auto dwords = buffer_ptr.as_array(); + + // Write in the GPU texture fetch. + dwords[offset++] = + xenos::MakePacketType0(rex::graphics::XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0, 6); + dwords[offset++] = gpu_fetch.dword_0; + dwords[offset++] = gpu_fetch.dword_1; + dwords[offset++] = gpu_fetch.dword_2; + dwords[offset++] = gpu_fetch.dword_3; + dwords[offset++] = gpu_fetch.dword_4; + dwords[offset++] = gpu_fetch.dword_5; + + dwords[offset++] = xenos::MakePacketType3(xenos::PM4_XE_SWAP, 4); + dwords[offset++] = rex::graphics::xenos::kSwapSignature; + dwords[offset++] = frontbuffer_physical_address; + + dwords[offset++] = *width; + dwords[offset++] = *height; + + // Fill the rest of the buffer with NOP packets. + for (uint32_t i = offset; i < 64; i++) { + dwords[i] = xenos::MakePacketType2(); + } +} + +void RegisterVideoExports(rex::runtime::ExportResolver* export_resolver, + KernelState* kernel_state) { + auto memory = kernel_state->memory(); + + // VdGlobalDevice (4b) + // Pointer to a global D3D device. Games only seem to set this, so we don't + // have to do anything. We may want to read it back later, though. + uint32_t pVdGlobalDevice = memory->SystemHeapAlloc(4, 32, memory::kSystemHeapPhysical); + export_resolver->SetVariableMapping("xboxkrnl.exe", 0x01BE, pVdGlobalDevice); + memory::store_and_swap(memory->TranslateVirtual(pVdGlobalDevice), 0); + + // VdGlobalXamDevice (4b) + // Pointer to the XAM D3D device, which we don't have. + uint32_t pVdGlobalXamDevice = memory->SystemHeapAlloc(4, 32, memory::kSystemHeapPhysical); + export_resolver->SetVariableMapping("xboxkrnl.exe", 0x01BF, pVdGlobalXamDevice); + memory::store_and_swap(memory->TranslateVirtual(pVdGlobalXamDevice), 0); + + // VdGpuClockInMHz (4b) + // GPU clock. Xenos is 500MHz. Hope nothing is relying on this timing... + uint32_t pVdGpuClockInMHz = memory->SystemHeapAlloc(4, 32, memory::kSystemHeapPhysical); + export_resolver->SetVariableMapping("xboxkrnl.exe", 0x01C0, pVdGpuClockInMHz); + memory::store_and_swap(memory->TranslateVirtual(pVdGpuClockInMHz), 500); + + // VdHSIOCalibrationLock (28b) + // CriticalSection. + uint32_t pVdHSIOCalibrationLock = memory->SystemHeapAlloc(28, 32, memory::kSystemHeapPhysical); + export_resolver->SetVariableMapping("xboxkrnl.exe", 0x01C1, pVdHSIOCalibrationLock); + auto hsio_lock = memory->TranslateVirtual(pVdHSIOCalibrationLock); + xeRtlInitializeCriticalSectionAndSpinCount(hsio_lock, pVdHSIOCalibrationLock, 10000); +} + +} // namespace rex::kernel::xboxkrnl + +REX_EXPORT(__imp__VdGetCurrentDisplayGamma, rex::kernel::xboxkrnl::VdGetCurrentDisplayGamma_entry) +REX_EXPORT(__imp__VdGetCurrentDisplayInformation, + rex::kernel::xboxkrnl::VdGetCurrentDisplayInformation_entry) +REX_EXPORT(__imp__VdQueryVideoMode, rex::kernel::xboxkrnl::VdQueryVideoMode_entry) +REX_EXPORT(__imp__VdQueryVideoFlags, rex::kernel::xboxkrnl::VdQueryVideoFlags_entry) +REX_EXPORT(__imp__VdSetDisplayMode, rex::kernel::xboxkrnl::VdSetDisplayMode_entry) +REX_EXPORT(__imp__VdSetDisplayModeOverride, rex::kernel::xboxkrnl::VdSetDisplayModeOverride_entry) +REX_EXPORT(__imp__VdInitializeEngines, rex::kernel::xboxkrnl::VdInitializeEngines_entry) +REX_EXPORT(__imp__VdShutdownEngines, rex::kernel::xboxkrnl::VdShutdownEngines_entry) +REX_EXPORT(__imp__VdGetGraphicsAsicID, rex::kernel::xboxkrnl::VdGetGraphicsAsicID_entry) +REX_EXPORT(__imp__VdEnableDisableClockGating, + rex::kernel::xboxkrnl::VdEnableDisableClockGating_entry) +REX_EXPORT(__imp__VdSetGraphicsInterruptCallback, + rex::kernel::xboxkrnl::VdSetGraphicsInterruptCallback_entry) +REX_EXPORT(__imp__VdInitializeRingBuffer, rex::kernel::xboxkrnl::VdInitializeRingBuffer_entry) +REX_EXPORT(__imp__VdEnableRingBufferRPtrWriteBack, + rex::kernel::xboxkrnl::VdEnableRingBufferRPtrWriteBack_entry) +REX_EXPORT(__imp__VdGetSystemCommandBuffer, rex::kernel::xboxkrnl::VdGetSystemCommandBuffer_entry) +REX_EXPORT(__imp__VdSetSystemCommandBufferGpuIdentifierAddress, + rex::kernel::xboxkrnl::VdSetSystemCommandBufferGpuIdentifierAddress_entry) +REX_EXPORT(__imp__VdInitializeScalerCommandBuffer, + rex::kernel::xboxkrnl::VdInitializeScalerCommandBuffer_entry) +REX_EXPORT(__imp__VdCallGraphicsNotificationRoutines, + rex::kernel::xboxkrnl::VdCallGraphicsNotificationRoutines_entry) +REX_EXPORT(__imp__VdIsHSIOTrainingSucceeded, rex::kernel::xboxkrnl::VdIsHSIOTrainingSucceeded_entry) +REX_EXPORT(__imp__VdPersistDisplay, rex::kernel::xboxkrnl::VdPersistDisplay_entry) +REX_EXPORT(__imp__VdRetrainEDRAMWorker, rex::kernel::xboxkrnl::VdRetrainEDRAMWorker_entry) +REX_EXPORT(__imp__VdRetrainEDRAM, rex::kernel::xboxkrnl::VdRetrainEDRAM_entry) +REX_EXPORT(__imp__VdSwap, rex::kernel::xboxkrnl::VdSwap_entry) diff --git a/src/kernel/xboxkrnl/xboxkrnl_xconfig.cpp b/src/kernel/xboxkrnl/xboxkrnl_xconfig.cpp new file mode 100644 index 0000000..f4ad126 --- /dev/null +++ b/src/kernel/xboxkrnl/xboxkrnl_xconfig.cpp @@ -0,0 +1,131 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Disable warnings about unused parameters for kernel functions +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::kernel::xboxkrnl { + +X_STATUS xeExGetXConfigSetting(uint16_t category, uint16_t setting, void* buffer, + uint16_t buffer_size, uint16_t* required_size) { + uint16_t setting_size = 0; + alignas(uint32_t) uint8_t value[4]; + + // TODO(benvanik): have real structs here that just get copied from. + // https://free60project.github.io/wiki/XConfig.html + // https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/Generic/ExConfig.h + switch (category) { + case 0x0002: + // XCONFIG_SECURED_CATEGORY + switch (setting) { + case 0x0002: // XCONFIG_SECURED_AV_REGION + setting_size = 4; + memory::store_and_swap(value, 0x00001000); // USA/Canada + break; + default: + REXKRNL_WARN("Unimplemented XConfig SECURED setting 0x{:04X}", setting); + return X_STATUS_INVALID_PARAMETER_2; + } + break; + case 0x0003: + // XCONFIG_USER_CATEGORY + switch (setting) { + case 0x0001: // XCONFIG_USER_TIME_ZONE_BIAS + case 0x0002: // XCONFIG_USER_TIME_ZONE_STD_NAME + case 0x0003: // XCONFIG_USER_TIME_ZONE_DLT_NAME + case 0x0004: // XCONFIG_USER_TIME_ZONE_STD_DATE + case 0x0005: // XCONFIG_USER_TIME_ZONE_DLT_DATE + case 0x0006: // XCONFIG_USER_TIME_ZONE_STD_BIAS + case 0x0007: // XCONFIG_USER_TIME_ZONE_DLT_BIAS + setting_size = 4; + // TODO(benvanik): get this value. + memory::store_and_swap(value, 0); + break; + case 0x0009: // XCONFIG_USER_LANGUAGE + setting_size = 4; + memory::store_and_swap(value, REXCVAR_GET(user_language)); + break; + case 0x000A: // XCONFIG_USER_VIDEO_FLAGS + setting_size = 4; + memory::store_and_swap(value, 0x00040000); + break; + case 0x000B: // XCONFIG_USER_AUDIO_FLAGS + setting_size = 4; + memory::store_and_swap(value, 0x00010001); + break; + case 0x000C: // XCONFIG_USER_RETAIL_FLAGS + setting_size = 4; + memory::store_and_swap(value, 0x40); + break; + case 0x000E: // XCONFIG_USER_COUNTRY + setting_size = 1; + value[0] = static_cast(REXCVAR_GET(user_country)); + break; + case 0x0019: // XCONFIG_USER_PC_FLAGS + setting_size = 1; + // XBLAllowed | XBLMembershipCreationAllowed + value[0] = 0x03; + break; + default: + REXKRNL_WARN("Unimplemented XConfig USER setting 0x{:04X}", setting); + return X_STATUS_INVALID_PARAMETER_2; + } + break; + default: + REXKRNL_WARN("Unimplemented XConfig category 0x{:04X}", category); + return X_STATUS_INVALID_PARAMETER_1; + } + + if (buffer) { + if (buffer_size < setting_size) { + return X_STATUS_BUFFER_TOO_SMALL; + } + std::memcpy(buffer, value, setting_size); + } else { + if (buffer_size) { + return X_STATUS_INVALID_PARAMETER_3; + } + } + + if (required_size) { + *required_size = setting_size; + } + + return X_STATUS_SUCCESS; +} + +u32 ExGetXConfigSetting_entry(u16 category, u16 setting, mapped_void buffer_ptr, u16 buffer_size, + mapped_u16 required_size_ptr) { + uint16_t required_size = 0; + X_STATUS result = + xeExGetXConfigSetting(category, setting, buffer_ptr, buffer_size, &required_size); + + if (required_size_ptr) { + *required_size_ptr = required_size; + } + + return result; +} + +} // namespace rex::kernel::xboxkrnl + +REX_EXPORT(__imp__ExGetXConfigSetting, rex::kernel::xboxkrnl::ExGetXConfigSetting_entry) +REX_EXPORT_STUB(__imp__ExSetXConfigSetting); diff --git a/src/rexglue/CMakeLists.txt b/src/rexglue/CMakeLists.txt new file mode 100644 index 0000000..54488ba --- /dev/null +++ b/src/rexglue/CMakeLists.txt @@ -0,0 +1,41 @@ +# ReXGlue + +add_executable(rexglue + main.cpp + ui/ui.cpp + ui/progress.cpp + commands/codegen_command.cpp + commands/init_command.cpp + commands/test_recompiler.cpp + commands/migration_scan.cpp + commands/legacy_config.cpp +) + +target_include_directories(rexglue + PRIVATE + ${REXGLUE_ROOT}/src + ${REXGLUE_ROOT}/thirdparty/disasm + ${REXGLUE_ROOT}/thirdparty/cli11/include +) + +target_link_libraries(rexglue + PRIVATE + rexcodegen +) + +# Delay-load FidelityFX DLLs so rexglue can run in tool mode without them. +if(WIN32) + if(TARGET amd_fidelityfx_vk) + target_link_options(rexglue PRIVATE + "LINKER:/DELAYLOAD:$") + endif() + if(TARGET amd_fidelityfx_dx12) + target_link_options(rexglue PRIVATE + "LINKER:/DELAYLOAD:$") + endif() + if(TARGET amd_fidelityfx_vk OR TARGET amd_fidelityfx_dx12) + target_link_libraries(rexglue PRIVATE delayimp) + endif() +endif() + +add_executable(rex::rexglue ALIAS rexglue) diff --git a/src/rexglue/cli_utils.h b/src/rexglue/cli_utils.h new file mode 100644 index 0000000..d232639 --- /dev/null +++ b/src/rexglue/cli_utils.h @@ -0,0 +1,26 @@ +/** + * @file rexglue/cli_utils.h + * @brief Shared types for rexglue CLI subcommands + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#pragma once + +#include + +#include + +namespace rexglue::cli { + +struct CliContext { + bool verbose = false; + bool overwrite_existing = false; + bool generate_despite_errors = false; + bool skip_upgrade_consent = false; +}; + +using DeferredAction = std::function()>; + +} // namespace rexglue::cli diff --git a/src/rexglue/commands/codegen_command.cpp b/src/rexglue/commands/codegen_command.cpp new file mode 100644 index 0000000..ad25d49 --- /dev/null +++ b/src/rexglue/commands/codegen_command.cpp @@ -0,0 +1,424 @@ +/** + * @file rexglue/commands/codegen_command.cpp + * @brief Code generation command implementation + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include "codegen_command.h" +#include "../ui/progress.h" +#include "../ui/ui.h" +#include "legacy_config.h" +#include "migration_scan.h" +#include "template_utils.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +namespace rexglue::cli { + +namespace { + +namespace fs = std::filesystem; + +struct ActionStrings { + std::string_view verb; + std::string_view label; +}; + +ActionStrings ActionStringsFor(OverwriteAction action) { + switch (action) { + case OverwriteAction::Write: + return {"Wrote", "write "}; + case OverwriteAction::Delete: + return {"Deleted", "delete"}; + } + return {"Touched", "? "}; +} + +bool ApplyEntry(const OverwriteEntry& entry) { + std::error_code ec; + switch (entry.action) { + case OverwriteAction::Write: { + if (auto parent = entry.path.parent_path(); !parent.empty()) { + fs::create_directories(parent, ec); + if (ec) { + REXLOG_ERROR("Failed to create directory for {}: {}", entry.path.string(), ec.message()); + return false; + } + } + std::ofstream out(entry.path); + if (!out) { + REXLOG_ERROR("Failed to open for write: {}", entry.path.string()); + return false; + } + out << entry.rendered_content; + if (!out.good()) { + REXLOG_ERROR("Failed to write: {}", entry.path.string()); + return false; + } + return true; + } + case OverwriteAction::Delete: + if (!fs::exists(entry.path)) + return true; + if (!fs::remove(entry.path, ec) || ec) { + REXLOG_ERROR("Failed to delete {}: {}", entry.path.string(), ec.message()); + return false; + } + return true; + } + return false; +} + +Result ApplyPlan(const std::vector& plan) { + for (const auto& entry : plan) { + if (!ApplyEntry(entry)) { + return Err(rex::ErrorCategory::IO, + fmt::format("Failed to apply: {}", entry.path.string())); + } + REXLOG_TRACE("{}: {}", ActionStringsFor(entry.action).verb, entry.path.generic_string()); + } + return rex::Ok(); +} + +Result PromptConsent(const std::vector& plan, bool force) { + std::vector rows; + for (const auto& e : plan) { + if (e.silent) + continue; + rows.push_back({ActionStringsFor(e.action).label, e.path.generic_string(), e.reason}); + } + if (rows.empty()) + return rex::Ok(); + + ui::PlanTable( + fmt::format("Migration: {} file(s) will be rewritten before codegen runs.", rows.size()), + rows); + + if (force) + return rex::Ok(); + if (!ui::Confirm("Apply migration and continue?")) { + return Err(rex::ErrorCategory::UserAbort, "Upgrade declined; codegen aborted."); + } + return rex::Ok(); +} + +void EmitManualReview(std::span warnings, std::string_view header) { + if (warnings.empty()) + return; + std::vector rows; + rows.reserve(warnings.size()); + for (const auto& w : warnings) { + rows.push_back( + {fmt::format("{}:{}", w.file.generic_string(), w.line_number), w.detail, w.hint}); + } + ui::ManualReviewList(std::string(header), rows); +} + +MigrationFindings ScanProjectMigrations(const fs::path& project_dir, std::string_view project_name, + std::string_view sdk_version, + std::string_view entrypoint_out_dir) { + MigrationFindings out; + auto add_rewrites = [&](std::vector entries) { + out.rewrites.insert(out.rewrites.end(), std::make_move_iterator(entries.begin()), + std::make_move_iterator(entries.end())); + }; + auto add_warnings = [&](std::vector entries) { + out.warnings.insert(out.warnings.end(), std::make_move_iterator(entries.begin()), + std::make_move_iterator(entries.end())); + }; + + add_rewrites(ScanSdkTemplateDrift(project_dir, project_name, sdk_version, entrypoint_out_dir)); + add_rewrites(ScanSourceIncludeRewrites(project_dir, project_name)); + auto idents = ScanLegacyIdentifiers(project_dir); + add_rewrites(std::move(idents.rewrites)); + add_warnings(std::move(idents.warnings)); + add_warnings(ScanCallSitePatterns(project_dir)); + return out; +} + +void ReportStaleIncludes(const fs::path& manifest_path, + const rex::codegen::ProjectRecompiler& recompiler) { + std::unordered_set written(recompiler.writtenFiles().begin(), + recompiler.writtenFiles().end()); + std::unordered_set removed; + for (const auto& f : recompiler.deletedFiles()) { + if (!written.contains(f)) { + removed.insert(f); + } + } + if (removed.empty()) + return; + + auto matches = ScanStaleIncludes(manifest_path.parent_path() / "src", removed); + EmitManualReview(matches, + fmt::format("{} source file(s) reference headers no longer emitted by codegen:", + matches.size())); +} + +Result RecompileProject(const fs::path& manifest_path, const CliContext& ctx, + const std::vector& targets) { + auto manifest = rex::codegen::ManifestConfig::Load(manifest_path); + if (!manifest) { + return Err(rex::ErrorCategory::Config, "Failed to load manifest"); + } + std::string title = fmt::format("Recompiling {}", manifest->projectName); + rex::codegen::ProjectRecompiler recompiler(std::move(*manifest)); + ui::ProgressView progress(title); + rex::codegen::ProjectRecompilerOptions opts{ + .targets = targets, + .force = ctx.generate_despite_errors, + .reporter = &progress, + }; + auto result = recompiler.Run(opts); + if (!result) + return result; + + ReportStaleIncludes(manifest_path, recompiler); + return rex::Ok(); +} + +struct ManifestSummary { + std::string project_name; + std::string sdk_version; + std::string entrypoint_out_dir; + std::size_t module_count = 0; +}; + +rex::Result LoadManifestSummary(const fs::path& manifest_path) { + auto manifest = rex::codegen::ManifestConfig::Load(manifest_path); + if (!manifest) { + return Err(rex::ErrorCategory::Config, "Failed to load manifest"); + } + return rex::Ok(ManifestSummary{ + .project_name = manifest->projectName, + .sdk_version = manifest->sdkVersion.value_or(""), + .entrypoint_out_dir = manifest->entrypoint.recompiler.outDirectoryPath, + .module_count = manifest->modules.size(), + }); +} + +void EmitProjectHeader(const fs::path& manifest_path, const ManifestSummary& summary) { + std::vector rows; + rows.push_back({"Manifest", manifest_path.generic_string()}); + if (!summary.project_name.empty()) { + rows.push_back({"Project", summary.project_name}); + } + if (summary.module_count > 0) { + rows.push_back({"Modules", fmt::format("{} DLL{}", summary.module_count, + summary.module_count == 1 ? "" : "s")}); + } + if (!summary.sdk_version.empty()) { + rows.push_back({"SDK", fmt::format("{} (project last generated by {})", REXGLUE_VERSION_STRING, + summary.sdk_version)}); + } else { + rows.push_back({"SDK", REXGLUE_VERSION_STRING}); + } + ui::KeyValueBlock("", rows); +} + +struct CodegenArgs { + std::string config_path; + std::vector targets; +}; + +} // namespace + +Result DiscoverManifestInCwd() { + std::error_code ec; + fs::path cwd = fs::current_path(ec); + if (ec) { + return Err(rex::ErrorCategory::IO, + fmt::format("Cannot read current directory: {}", ec.message())); + } + + std::vector manifests; + std::vector other_tomls; + for (const auto& entry : fs::directory_iterator(cwd, ec)) { + if (ec) + break; + if (!entry.is_regular_file()) + continue; + if (entry.path().extension() != ".toml") + continue; + auto stem = entry.path().stem().string(); + if (stem.size() >= 9 && std::string_view{stem}.substr(stem.size() - 9) == "_manifest") { + manifests.push_back(entry.path()); + } else { + other_tomls.push_back(entry.path()); + } + } + + if (manifests.size() == 1) + return rex::Ok(manifests.front().string()); + if (manifests.size() > 1) { + return Err( + rex::ErrorCategory::Config, + fmt::format("Multiple *_manifest.toml files in {}; pass one explicitly", cwd.string())); + } + if (other_tomls.size() == 1) + return rex::Ok(other_tomls.front().string()); + if (other_tomls.size() > 1) { + return Err( + rex::ErrorCategory::Config, + fmt::format("Multiple .toml files in {}; pass the manifest explicitly", cwd.string())); + } + return Err(rex::ErrorCategory::Config, + fmt::format("No manifest .toml found in {}", cwd.string())); +} + +Result CodegenFromConfig(const std::string& config_path, const CliContext& ctx, + const std::vector& targets) { + REXLOG_TRACE("Generating code with config: {}", config_path); + + toml::table parsed_tbl; + try { + parsed_tbl = toml::parse_file(config_path); + } catch (const toml::parse_error& err) { + return Err(rex::ErrorCategory::Config, + fmt::format("Failed to parse {}: {}", config_path, err.what())); + } + + std::vector pre_plan; + std::vector post_plan; + std::vector warnings; + bool from_legacy = false; + + fs::path manifest_path; + ManifestSummary summary; + const std::string current_version = REXGLUE_VERSION_NUMERIC; + + auto append_findings = [&](MigrationFindings findings) { + post_plan.insert(post_plan.end(), std::make_move_iterator(findings.rewrites.begin()), + std::make_move_iterator(findings.rewrites.end())); + warnings.insert(warnings.end(), std::make_move_iterator(findings.warnings.begin()), + std::make_move_iterator(findings.warnings.end())); + }; + + if (parsed_tbl.contains("project")) { + manifest_path = config_path; + auto loaded = LoadManifestSummary(manifest_path); + if (!loaded) + return Err(loaded.error()); + summary = std::move(*loaded); + append_findings(ScanProjectMigrations(manifest_path.parent_path(), summary.project_name, + current_version, summary.entrypoint_out_dir)); + } else { + fs::path legacy_path = config_path; + auto converted = ConvertLegacyConfig(legacy_path); + if (!converted) { + return Err( + rex::ErrorCategory::Config, + fmt::format("Cannot convert legacy config {}: missing project_name or file_path", + legacy_path.string())); + } + manifest_path = converted->manifest_path; + summary.project_name = converted->project_name; + summary.entrypoint_out_dir = converted->out_directory_path; + + if (fs::exists(manifest_path)) { + REXLOG_WARN("Both {} and {} exist; using the manifest. Remove the legacy file when ready.", + manifest_path.filename().string(), legacy_path.filename().string()); + auto loaded = LoadManifestSummary(manifest_path); + if (!loaded) + return Err(loaded.error()); + summary = std::move(*loaded); + append_findings(ScanProjectMigrations(manifest_path.parent_path(), summary.project_name, + current_version, summary.entrypoint_out_dir)); + } else { + from_legacy = true; + pre_plan.push_back({manifest_path, std::move(converted->manifest_content), + OverwriteAction::Write, /*silent=*/false, + fmt::format("upgrade format to v{}", current_version)}); + if (!converted->stripped_legacy_content.empty()) { + post_plan.push_back({legacy_path, std::move(converted->stripped_legacy_content), + OverwriteAction::Write, /*silent=*/false, + "strip absorbed fields (kept as include target)"}); + } else { + post_plan.push_back({legacy_path, "", OverwriteAction::Delete, /*silent=*/false, + "absorbed into the new manifest"}); + } + + auto cmake_rewrites = + ScanCmakeReferences(legacy_path.parent_path(), legacy_path.filename().string(), + manifest_path.filename().string()); + post_plan.insert(post_plan.end(), std::make_move_iterator(cmake_rewrites.begin()), + std::make_move_iterator(cmake_rewrites.end())); + + append_findings(ScanProjectMigrations(legacy_path.parent_path(), summary.project_name, + current_version, summary.entrypoint_out_dir)); + } + } + + EmitProjectHeader(manifest_path, summary); + EmitManualReview(warnings, + fmt::format("Migration: {} site(s) need manual review:", warnings.size())); + + std::vector consent_view = pre_plan; + consent_view.insert(consent_view.end(), post_plan.begin(), post_plan.end()); + if (auto consent = PromptConsent(consent_view, ctx.skip_upgrade_consent); !consent) + return consent; + + if (auto applied = ApplyPlan(pre_plan); !applied) + return applied; + + if (auto run_result = RecompileProject(manifest_path, ctx, targets); !run_result) { + if (from_legacy) { + std::error_code ec; + fs::remove(manifest_path, ec); + REXLOG_ERROR("Codegen failed; manifest write rolled back. Legacy config is unchanged."); + } + return run_result; + } + + if (auto applied = ApplyPlan(post_plan); !applied) + return applied; + + if (!rex::codegen::ManifestConfig::WriteSdkVersionStamp(manifest_path, current_version)) { + REXLOG_WARN("Failed to stamp manifest sdkVersion; next run may re-prompt"); + } + return rex::Ok(); +} + +void RegisterCodegen(CLI::App& parent, const CliContext& ctx, DeferredAction& pending) { + auto args = std::make_shared(); + auto* sub = parent.add_subcommand("codegen", "Analyze and generate C++ code")->fallthrough(); + sub->add_option("config", args->config_path, + "Path to manifest TOML (auto-discovered in cwd if omitted)") + ->type_name("PATH"); + sub->add_option("--target", args->targets, + "DLL target to build (repeatable; entrypoint always included)") + ->type_name("NAME") + ->take_all(); + + sub->callback([args, &ctx, &pending]() { + pending = [args, &ctx]() -> Result { + std::string path = args->config_path; + if (path.empty()) { + auto discovered = DiscoverManifestInCwd(); + if (!discovered) + return Err(discovered.error()); + path = *discovered; + } + return CodegenFromConfig(path, ctx, args->targets); + }; + }); +} + +} // namespace rexglue::cli diff --git a/src/rexglue/commands/codegen_command.h b/src/rexglue/commands/codegen_command.h new file mode 100644 index 0000000..aeddd19 --- /dev/null +++ b/src/rexglue/commands/codegen_command.h @@ -0,0 +1,33 @@ +/** + * @file rexglue/commands/codegen_command.h + * @brief Code generation command interface + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#pragma once + +#include "../cli_utils.h" + +#include +#include + +#include + +namespace CLI { +class App; +} + +namespace rexglue::cli { + +using rex::Result; + +Result CodegenFromConfig(const std::string& config_path, const CliContext& ctx, + const std::vector& targets); + +Result DiscoverManifestInCwd(); + +void RegisterCodegen(CLI::App& parent, const CliContext& ctx, DeferredAction& pending); + +} // namespace rexglue::cli diff --git a/src/rexglue/commands/init_command.cpp b/src/rexglue/commands/init_command.cpp new file mode 100644 index 0000000..9dcbef1 --- /dev/null +++ b/src/rexglue/commands/init_command.cpp @@ -0,0 +1,437 @@ +/** + * @file rexglue/commands/init_command.cpp + * @brief Project initialization command implementation + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include "init_command.h" +#include "../ui/ui.h" +#include "template_utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace fs = std::filesystem; + +namespace rexglue::cli { + +using rex::Err; +using rex::ErrorCategory; +using rex::Ok; + +namespace { + +std::string LowercaseAscii(std::string s) { + std::transform(s.begin(), s.end(), s.begin(), + [](unsigned char c) { return static_cast(std::tolower(c)); }); + return s; +} + +std::string ManifestPath(const fs::path& target, const fs::path& base) { + std::error_code ec; + fs::path rel = fs::relative(target, base, ec); + if (ec || rel.empty()) { + return LowercaseAscii(target.generic_string()); + } + return LowercaseAscii(rel.generic_string()); +} + +std::string ModuleStem(const fs::path& xex) { + std::string stem = LowercaseAscii(xex.stem().string()); + std::replace(stem.begin(), stem.end(), '.', '_'); + std::replace(stem.begin(), stem.end(), ' ', '_'); + return stem; +} + +std::string IsoUtcStamp() { + auto now = std::chrono::system_clock::now(); + auto t = std::chrono::system_clock::to_time_t(now); + return fmt::format("{:%Y-%m-%d %H:%M:%S} UTC", fmt::gmtime(t)); +} + +fs::path ResolveDir(const std::string& raw, std::error_code& ec) { + fs::path p = fs::absolute(raw, ec); + if (ec) + return p; + fs::path canon = fs::weakly_canonical(p, ec); + if (ec) { + ec.clear(); + return p; + } + return canon; +} + +} // namespace + +Result InitProject(const InitOptions& opts, const CliContext& ctx) { + (void)ctx; + + if (opts.project_name.empty()) + return Err(ErrorCategory::Config, "--project_name is required"); + if (opts.xex_path.empty()) + return Err(ErrorCategory::Config, "--xex_path is required (path to entrypoint XEX)"); + + std::string validation_error; + if (!validate_app_name(opts.project_name, validation_error)) + return Err(ErrorCategory::Config, validation_error); + auto names = parse_app_name(opts.project_name); + + std::error_code ec; + fs::path projectRoot = + opts.project_root.empty() ? fs::current_path(ec) : ResolveDir(opts.project_root, ec); + if (ec) + return Err(ErrorCategory::IO, "Failed to resolve project root: " + ec.message()); + + fs::path xexAbs = ResolveDir(opts.xex_path, ec); + if (ec) + return Err(ErrorCategory::IO, + "Failed to resolve --xex_path '" + opts.xex_path + "': " + ec.message()); + if (!fs::exists(xexAbs)) + return Err(ErrorCategory::IO, "Entrypoint XEX not found: " + xexAbs.string()); + if (!fs::is_regular_file(xexAbs)) + return Err(ErrorCategory::IO, "--xex_path is not a regular file: " + xexAbs.string()); + + std::string xexStem = xexAbs.stem().string(); + if (xexStem.empty()) + return Err(ErrorCategory::Config, "--xex_path has no filename: " + opts.xex_path); + + fs::path gameRootAbs; + if (opts.game_root.empty()) { + gameRootAbs = xexAbs.parent_path(); + } else { + gameRootAbs = ResolveDir(opts.game_root, ec); + if (ec) + return Err(ErrorCategory::IO, + "Failed to resolve --game_root '" + opts.game_root + "': " + ec.message()); + } + if (!fs::exists(gameRootAbs) || !fs::is_directory(gameRootAbs)) + return Err(ErrorCategory::IO, "--game_root is not a directory: " + gameRootAbs.string()); + + fs::path xexRelToGame = fs::relative(xexAbs, gameRootAbs, ec); + if (ec || xexRelToGame.empty() || *xexRelToGame.begin() == fs::path("..")) { + return Err(ErrorCategory::Config, "--xex_path (" + xexAbs.string() + + ") is not inside --game_root (" + + gameRootAbs.string() + ")"); + } + + std::string outDir = LowercaseAscii("generated/" + xexStem); + std::string xexRelManifest = ManifestPath(xexAbs, projectRoot); + std::string gameRootRelManifest = ManifestPath(gameRootAbs, projectRoot); + + nlohmann::json modulesJson = nlohmann::json::array(); + if (opts.scan_dlls) { + std::vector dllPaths; + fs::recursive_directory_iterator it(gameRootAbs, fs::directory_options::skip_permission_denied, + ec); + fs::recursive_directory_iterator end; + for (; !ec && it != end; it.increment(ec)) { + if (!it->is_regular_file()) + continue; + if (LowercaseAscii(it->path().extension().string()) != ".dll") + continue; + dllPaths.push_back(it->path()); + } + std::sort(dllPaths.begin(), dllPaths.end()); + + for (const auto& dllAbs : dllPaths) { + fs::path relUnderGame = fs::relative(dllAbs, gameRootAbs, ec); + if (ec || relUnderGame.empty()) { + ec.clear(); + continue; + } + modulesJson.push_back({ + {"guest_path", rex::codegen::CanonicalizeModuleGuestPath(relUnderGame.generic_string(), + names.snake_case)}, + {"file_path", ManifestPath(dllAbs, projectRoot)}, + {"out_directory_path", "generated/" + ModuleStem(dllAbs)}, + }); + } + } + + rex::codegen::TemplateRegistry registry; + if (!opts.template_dir.empty()) + registry.loadOverrides(opts.template_dir); + + nlohmann::json data = { + {"names", names_to_json(names)}, + {"sdk_version", REXGLUE_VERSION_NUMERIC}, + {"sdk_version_full", REXGLUE_VERSION_STRING}, + {"generated_on", IsoUtcStamp()}, + {"include_stamp", true}, + {"xex_path", xexRelManifest}, + {"game_root", gameRootRelManifest}, + {"out_directory_path", outDir}, + {"entrypoint_out_dir", outDir}, + {"modules", modulesJson}, + }; + std::string jsonStr = data.dump(); + + std::vector header_rows; + header_rows.push_back({"Project", names.snake_case}); + header_rows.push_back({"Root", projectRoot.string()}); + header_rows.push_back({"Entrypoint", xexRelManifest}); + header_rows.push_back({"Game root", gameRootRelManifest}); + if (opts.scan_dlls) { + header_rows.push_back({"DLL modules", std::to_string(modulesJson.size())}); + } + ui::KeyValueBlock("Initializing project:", header_rows); + + if (fs::exists(projectRoot) && !fs::is_directory(projectRoot)) { + return Err(ErrorCategory::IO, + "Path exists but is not a directory: " + projectRoot.string()); + } + + enum class RegeneratePolicy { AlwaysRegenerate, FirstInitOnly, RequiresForce }; + struct Render { + std::string template_id; + fs::path out; + RegeneratePolicy policy; + }; + std::string app_header = names.snake_case + "_app.h"; + std::string manifest_file = names.snake_case + "_manifest.toml"; + std::vector renders = { + {"init/cmakelists", projectRoot / "CMakeLists.txt", RegeneratePolicy::RequiresForce}, + {"init/rexglue_cmake", projectRoot / "generated" / "rexglue.cmake", + RegeneratePolicy::AlwaysRegenerate}, + {"init/main_cpp", projectRoot / "src" / "main.cpp", RegeneratePolicy::FirstInitOnly}, + {"init/app_header", projectRoot / "src" / app_header, RegeneratePolicy::FirstInitOnly}, + {"init/manifest_toml", projectRoot / manifest_file, RegeneratePolicy::RequiresForce}, + {"init/cmake_presets", projectRoot / "CMakePresets.json", RegeneratePolicy::RequiresForce}, + }; + + if (!opts.force) { + std::vector blocked; + for (const auto& r : renders) { + if (r.policy == RegeneratePolicy::RequiresForce && fs::exists(r.out)) { + blocked.push_back(fs::relative(r.out, projectRoot).generic_string()); + } + } + if (!blocked.empty()) { + std::string msg = "Existing project files would be overwritten. Use --force to proceed:"; + for (const auto& path : blocked) { + msg += "\n - " + path; + } + return Err(ErrorCategory::IO, msg); + } + } + + REXLOG_TRACE("Creating directory structure..."); + for (const auto& dir : {projectRoot, projectRoot / "src", projectRoot / "generated"}) { + fs::create_directories(dir, ec); + if (ec) { + return Err(ErrorCategory::IO, + fmt::format("Failed to create {}: {}", dir.string(), ec.message())); + } + } + + REXLOG_TRACE("Generating project files..."); + for (const auto& r : renders) { + if (r.policy == RegeneratePolicy::FirstInitOnly && fs::exists(r.out)) { + REXLOG_DEBUG(" Skipped {} (preserving user content)", + fs::relative(r.out, projectRoot).generic_string()); + continue; + } + if (!write_file_atomic(r.out, registry.render(r.template_id, jsonStr))) { + return Err(ErrorCategory::IO, "Failed to write " + r.out.string()); + } + REXLOG_DEBUG(" Created {}", fs::relative(r.out, projectRoot).generic_string()); + } + return Ok(); +} + +Result InitModule(const InitModuleOptions& opts, const CliContext& ctx) { + (void)ctx; + + fs::path root = fs::absolute(opts.app_root); + std::error_code dir_ec; + fs::path manifestPath; + for (const auto& entry : fs::directory_iterator(root, dir_ec)) { + if (entry.path().extension() == ".toml" && + rex::codegen::ManifestConfig::IsManifest(entry.path())) { + manifestPath = entry.path(); + break; + } + } + if (dir_ec) { + return Err(ErrorCategory::IO, fmt::format("Cannot read project root '{}': {}", + root.string(), dir_ec.message())); + } + if (manifestPath.empty()) { + return Err(ErrorCategory::Config, + "No manifest found in project root. Run 'rexglue init' first."); + } + + auto manifest = rex::codegen::ManifestConfig::Load(manifestPath); + if (!manifest) + return Err(ErrorCategory::Config, "Failed to load manifest"); + + fs::path xexAbs = fs::weakly_canonical(fs::absolute(opts.xex_path)); + if (!fs::exists(xexAbs)) + return Err(ErrorCategory::IO, fmt::format("XEX file not found: {} (resolved from {})", + xexAbs.string(), opts.xex_path)); + std::string moduleName = ModuleStem(xexAbs); + std::string xexRel = fs::relative(xexAbs, root).generic_string(); + std::string guestPath = + rex::codegen::CanonicalizeModuleGuestPath(opts.guest_path, manifest->projectName); + + toml::table manifestTbl; + try { + manifestTbl = toml::parse_file(manifestPath.string()); + } catch (const toml::parse_error& err) { + return Err(ErrorCategory::Config, fmt::format("Manifest parse error: {}", err.what())); + } + if (auto* modulesArr = manifestTbl["modules"].as_array()) { + for (const auto& mod : *modulesArr) { + auto* modTbl = mod.as_table(); + if (!modTbl) + continue; + if ((*modTbl)["file_path"].value_or("") == xexRel || + (*modTbl)["guest_path"].value_or("") == guestPath) { + REXLOG_TRACE("Manifest already lists this module; nothing to do."); + return Ok(); + } + } + } + + std::ifstream in(manifestPath); + if (!in) + return Err(ErrorCategory::IO, + "Failed to open manifest for reading: " + manifestPath.string()); + std::stringstream ss; + ss << in.rdbuf(); + std::string content = ss.str(); + in.close(); + + if (!content.empty() && content.back() != '\n') + content.push_back('\n'); + content += fmt::format( + "\n[[modules]]\nguest_path = \"{}\"\nfile_path = \"{}\"\nout_directory_path = " + "\"generated/{}\"\nincludes = []\n", + guestPath, xexRel, moduleName); + + fs::path tmpPath = manifestPath; + tmpPath += ".tmp"; + { + std::ofstream out(tmpPath, std::ios::binary); + if (!out) + return Err(ErrorCategory::IO, + "Failed to open manifest tmp for writing: " + tmpPath.string()); + out << content; + if (!out.good()) { + std::error_code ignore; + fs::remove(tmpPath, ignore); + return Err(ErrorCategory::IO, "Failed while writing manifest tmp: " + tmpPath.string()); + } + } + std::error_code ec; + fs::rename(tmpPath, manifestPath, ec); + if (ec) { + std::error_code ignore; + fs::remove(tmpPath, ignore); + return Err(ErrorCategory::IO, + "Failed to rename manifest tmp into place: " + ec.message()); + } + + std::vector rows; + rows.push_back({"file_path", xexRel}); + rows.push_back({"guest_path", guestPath}); + ui::KeyValueBlock(fmt::format("Module '{}' added to manifest:", moduleName), rows); + return Ok(); +} + +namespace { + +struct InitArgs { + std::string project_name; + std::string project_root; + std::string xex_path; + std::string game_root; + std::string template_dir; + bool scan_dll = false; +}; + +struct InitModuleArgs { + std::string app_root; + std::string xex_path; + std::string guest_path; +}; + +} // namespace + +void RegisterInit(CLI::App& parent, const CliContext& ctx, DeferredAction& pending) { + auto* init = parent.add_subcommand("init", "Initialize a new project")->fallthrough(); + auto args = std::make_shared(); + init->add_option("--project-name", args->project_name, + "Project name (becomes [project].name in the manifest)") + ->type_name("NAME") + ->required(); + init->add_option("--xex-path", args->xex_path, "Path to entrypoint XEX (e.g. assets/Default.xex)") + ->type_name("PATH") + ->required(); + init->add_option("--game-root", args->game_root, "Game asset root for DLL guest-path derivation") + ->type_name("PATH"); + init->add_option("--project-root", args->project_root, + "Where to create the project (defaults to current directory)") + ->type_name("PATH"); + init->add_flag("--scan-dll", args->scan_dll, + "Scan --game-root for .dll files and add each as a [[modules]] entry"); + init->add_option("--template-dir", args->template_dir, "Custom template directory for overrides") + ->type_name("PATH"); + + auto* mod = + init->add_subcommand("module", "Add a DLL module to an existing project")->fallthrough(); + auto modArgs = std::make_shared(); + mod->add_option("--project-root", modArgs->app_root, "Project root containing the manifest") + ->type_name("PATH") + ->required(); + mod->add_option("--xex-path", modArgs->xex_path, "Path to the DLL XEX") + ->type_name("PATH") + ->required(); + mod->add_option("--guest-path", modArgs->guest_path, "Guest path for XexLoadImage matching") + ->type_name("PATH") + ->required(); + + init->callback([args, &ctx, &pending]() { + pending = [args, &ctx]() -> Result { + InitOptions opts; + opts.project_name = args->project_name; + opts.project_root = args->project_root; + opts.xex_path = args->xex_path; + opts.game_root = args->game_root; + opts.scan_dlls = args->scan_dll; + opts.template_dir = args->template_dir; + opts.force = ctx.overwrite_existing; + return InitProject(opts, ctx); + }; + }); + mod->callback([modArgs, &ctx, &pending]() { + pending = [modArgs, &ctx]() -> Result { + InitModuleOptions opts; + opts.app_root = modArgs->app_root; + opts.xex_path = modArgs->xex_path; + opts.guest_path = modArgs->guest_path; + return InitModule(opts, ctx); + }; + }); +} + +} // namespace rexglue::cli diff --git a/src/rexglue/commands/init_command.h b/src/rexglue/commands/init_command.h new file mode 100644 index 0000000..2976b43 --- /dev/null +++ b/src/rexglue/commands/init_command.h @@ -0,0 +1,46 @@ +/** + * @file rexglue/commands/init_command.h + * @brief Project initialization command interface + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#pragma once + +#include "../cli_utils.h" + +#include + +#include + +namespace CLI { +class App; +} + +namespace rexglue::cli { + +using rex::Result; + +struct InitOptions { + std::string project_name; + std::string xex_path; + std::string game_root; + std::string project_root; + bool scan_dlls = false; + std::string template_dir; + bool force = false; +}; + +struct InitModuleOptions { + std::string app_root; + std::string xex_path; + std::string guest_path; +}; + +Result InitProject(const InitOptions& opts, const CliContext& ctx); +Result InitModule(const InitModuleOptions& opts, const CliContext& ctx); + +void RegisterInit(CLI::App& parent, const CliContext& ctx, DeferredAction& pending); + +} // namespace rexglue::cli diff --git a/src/rexglue/commands/legacy_config.cpp b/src/rexglue/commands/legacy_config.cpp new file mode 100644 index 0000000..108f0cc --- /dev/null +++ b/src/rexglue/commands/legacy_config.cpp @@ -0,0 +1,273 @@ +/** + * @file rexglue/commands/legacy_config.cpp + * @brief Legacy single-file config -> manifest conversion + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include "legacy_config.h" +#include "template_utils.h" + +#include +#include +#include + +#include + +#include + +namespace rexglue::cli { + +namespace { + +namespace fs = std::filesystem; + +std::optional ParseSectionHeader(std::string_view line) { + auto first = line.find_first_not_of(" \t"); + if (first == std::string_view::npos) + return std::nullopt; + if (line[first] != '[' || (first + 1 < line.size() && line[first + 1] == '[')) + return std::nullopt; + auto end = line.find(']', first + 1); + if (end == std::string_view::npos) + return std::nullopt; + return std::string(line.substr(first + 1, end - first - 1)); +} + +bool LineSetsKey(std::string_view line, std::string_view key) { + auto first = line.find_first_not_of(" \t"); + if (first == std::string_view::npos) + return false; + if (line.compare(first, key.size(), key) != 0) + return false; + auto after = first + key.size(); + while (after < line.size() && (line[after] == ' ' || line[after] == '\t')) + ++after; + return after < line.size() && line[after] == '='; +} + +size_t FindAssignmentEndLine(const std::vector& lines, size_t start_line) { + int depth = 0; + bool seen_open = false; + for (size_t j = start_line; j < lines.size(); ++j) { + bool in_string = false; + char quote = 0; + for (size_t k = 0; k < lines[j].size(); ++k) { + char c = lines[j][k]; + if (in_string) { + if (c == '\\' && k + 1 < lines[j].size()) { + ++k; + continue; + } + if (c == quote) + in_string = false; + continue; + } + if (c == '#') + break; + if (c == '"' || c == '\'') { + in_string = true; + quote = c; + continue; + } + if (c == '[') { + ++depth; + seen_open = true; + } else if (c == ']') { + --depth; + } + } + if (!seen_open) + return j; + if (depth <= 0) + return j; + } + return lines.size() - 1; +} + +std::string RenderTomlString(std::string_view value) { + std::string out = "\""; + for (char c : value) { + switch (c) { + case '\\': + out.append("\\\\"); + break; + case '"': + out.append("\\\""); + break; + case '\n': + out.append("\\n"); + break; + case '\t': + out.append("\\t"); + break; + default: + out.push_back(c); + } + } + out.push_back('"'); + return out; +} + +std::string RenderKeyString(std::string_view key, std::string_view value) { + std::string out; + out.append(key); + out.append(" = "); + out.append(RenderTomlString(value)); + return out; +} + +std::vector SplitLines(std::string_view content) { + std::vector lines; + std::string buf; + for (char c : content) { + if (c == '\n') { + lines.push_back(std::move(buf)); + buf.clear(); + } else if (c != '\r') { + buf.push_back(c); + } + } + if (!buf.empty()) + lines.push_back(std::move(buf)); + return lines; +} + +} // namespace + +std::optional ConvertLegacyConfig(const fs::path& legacy_path) { + toml::table tbl; + try { + tbl = toml::parse_file(legacy_path.string()); + } catch (const toml::parse_error& err) { + REXLOG_ERROR("Failed to parse legacy config {}: {}", legacy_path.string(), err.what()); + return std::nullopt; + } + + auto project_name = tbl["project_name"].value_or(""); + if (project_name.empty() || project_name == "rex") { + return std::nullopt; + } + auto file_path = tbl["file_path"].value_or(""); + if (file_path.empty()) { + REXLOG_ERROR("Legacy config {} missing required file_path", legacy_path.string()); + return std::nullopt; + } + auto out_directory_path = tbl["out_directory_path"].value_or(""); + if (out_directory_path.empty()) { + out_directory_path = "generated/" + fs::path(file_path).stem().string(); + } + + std::string legacy_content = read_file(legacy_path); + if (legacy_content.empty()) { + return std::nullopt; + } + std::vector lines = SplitLines(legacy_content); + + size_t first_section_idx = lines.size(); + for (size_t i = 0; i < lines.size(); ++i) { + if (ParseSectionHeader(lines[i])) { + first_section_idx = i; + break; + } + } + + static constexpr std::array kManifestEmittedKeys = { + "project_name", "file_path", "out_directory_path", "template_dir", + "patch_file_path", "patched_file_path", "includes", + }; + + std::string entrypoint_body; + size_t i = 0; + while (i < first_section_idx) { + auto first_nonws = lines[i].find_first_not_of(" \t"); + if (first_nonws == std::string::npos || lines[i][first_nonws] == '#') { + ++i; + continue; + } + bool emitted_by_manifest = false; + for (auto key : kManifestEmittedKeys) { + if (LineSetsKey(lines[i], key)) { + emitted_by_manifest = true; + break; + } + } + size_t end = FindAssignmentEndLine(lines, i); + if (!emitted_by_manifest) { + for (size_t j = i; j <= end; ++j) { + auto fn = lines[j].find_first_not_of(" \t"); + if (fn == std::string::npos) + continue; + entrypoint_body.append(lines[j]); + entrypoint_body.push_back('\n'); + } + } + i = end + 1; + } + + std::string stripped; + for (size_t j = first_section_idx; j < lines.size(); ++j) { + auto first_nonws = lines[j].find_first_not_of(" \t"); + if (first_nonws == std::string::npos) + continue; + if (lines[j][first_nonws] == '#') + continue; + if (ParseSectionHeader(lines[j]) && !stripped.empty()) + stripped.push_back('\n'); + stripped.append(lines[j]); + stripped.push_back('\n'); + } + + std::vector entrypoint_includes; + if (!stripped.empty()) + entrypoint_includes.push_back(legacy_path.filename().string()); + if (auto* arr = tbl["includes"].as_array()) { + for (const auto& elem : *arr) { + if (auto s = elem.value()) { + entrypoint_includes.push_back(*s); + } + } + } + + std::string manifest_content; + manifest_content += "[project]\n"; + manifest_content += RenderKeyString("name", project_name); + manifest_content += "\n\n[entrypoint]\n"; + manifest_content += RenderKeyString("file_path", file_path); + manifest_content += '\n'; + manifest_content += RenderKeyString("out_directory_path", out_directory_path); + manifest_content += '\n'; + for (auto key : {"template_dir", "patch_file_path", "patched_file_path"}) { + if (auto v = tbl[key].value()) { + manifest_content += RenderKeyString(key, *v); + manifest_content += '\n'; + } + } + if (!entrypoint_includes.empty()) { + manifest_content += "includes = [\n"; + for (const auto& inc : entrypoint_includes) { + manifest_content += " "; + manifest_content += RenderTomlString(inc); + manifest_content += ",\n"; + } + manifest_content += "]\n"; + } + if (!entrypoint_body.empty()) { + manifest_content += '\n'; + manifest_content += entrypoint_body; + manifest_content += '\n'; + } + + LegacyConversion result; + result.legacy_path = legacy_path; + result.project_name = project_name; + result.out_directory_path = out_directory_path; + auto names = parse_app_name(project_name); + result.manifest_path = legacy_path.parent_path() / (names.snake_case + "_manifest.toml"); + result.manifest_content = std::move(manifest_content); + result.stripped_legacy_content = std::move(stripped); + return result; +} + +} // namespace rexglue::cli diff --git a/src/rexglue/commands/legacy_config.h b/src/rexglue/commands/legacy_config.h new file mode 100644 index 0000000..b21960b --- /dev/null +++ b/src/rexglue/commands/legacy_config.h @@ -0,0 +1,28 @@ +/** + * @file rexglue/commands/legacy_config.h + * @brief One-shot conversion of pre-manifest single-file configs + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#pragma once + +#include +#include +#include + +namespace rexglue::cli { + +struct LegacyConversion { + std::filesystem::path manifest_path; + std::filesystem::path legacy_path; + std::string project_name; + std::string out_directory_path; + std::string manifest_content; + std::string stripped_legacy_content; +}; + +std::optional ConvertLegacyConfig(const std::filesystem::path& legacy_path); + +} // namespace rexglue::cli diff --git a/src/rexglue/commands/migration_scan.cpp b/src/rexglue/commands/migration_scan.cpp new file mode 100644 index 0000000..0c7bf4d --- /dev/null +++ b/src/rexglue/commands/migration_scan.cpp @@ -0,0 +1,557 @@ +/** + * @file rexglue/commands/migration_scan.cpp + * @brief Project-tree scanners for SDK upgrade-driven migrations + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "migration_scan.h" +#include "template_utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace rexglue::cli { + +namespace fs = std::filesystem; + +namespace { + +std::string ToLower(std::string s) { + std::transform(s.begin(), s.end(), s.begin(), + [](unsigned char c) { return static_cast(std::tolower(c)); }); + return s; +} + +bool IsSourceExtension(const fs::path& p) { + static const std::unordered_set kExts = {".cpp", ".cc", ".cxx", ".c", ".h", + ".hh", ".hpp", ".hxx", ".inl"}; + return kExts.contains(ToLower(p.extension().string())); +} + +bool IsCmakeFile(const fs::path& p) { + return p.filename() == "CMakeLists.txt" || p.extension() == ".cmake"; +} + +bool IsUnderGeneratedTree(const fs::path& project_root, const fs::path& target) { + std::error_code ec; + auto rel = fs::relative(target, project_root, ec); + if (ec) + return false; + auto first = rel.begin(); + return first != rel.end() && first->generic_string() == "generated"; +} + +template +void WalkProjectFiles(const fs::path& project_root, Accept accept, Visit visit) { + std::error_code ec; + if (!fs::is_directory(project_root, ec)) + return; + fs::recursive_directory_iterator it(project_root, fs::directory_options::skip_permission_denied, + ec); + if (ec) + return; + for (fs::recursive_directory_iterator end; it != end; it.increment(ec)) { + if (ec) { + ec.clear(); + continue; + } + if (it->is_directory()) { + if (IsUnderGeneratedTree(project_root, it->path())) + it.disable_recursion_pending(); + continue; + } + if (!it->is_regular_file() || !accept(it->path())) + continue; + visit(it->path()); + } +} + +bool IsPathTokenChar(char c) { + unsigned char uc = static_cast(c); + return std::isalnum(uc) != 0 || c == '_' || c == '-' || c == '.' || c == '/' || c == '\\'; +} + +bool ReplaceAllPathTokens(std::string& haystack, std::string_view needle, + std::string_view replacement) { + if (needle.empty()) + return false; + bool replaced = false; + std::string::size_type pos = 0; + while ((pos = haystack.find(needle, pos)) != std::string::npos) { + bool boundary_before = pos == 0 || !IsPathTokenChar(haystack[pos - 1]); + bool boundary_after = + pos + needle.size() >= haystack.size() || !IsPathTokenChar(haystack[pos + needle.size()]); + if (!boundary_before || !boundary_after) { + pos += needle.size(); + continue; + } + haystack.replace(pos, needle.size(), replacement); + pos += replacement.size(); + replaced = true; + } + return replaced; +} + +bool IsIdentStart(char c) { + unsigned char uc = static_cast(c); + return std::isalpha(uc) != 0 || c == '_'; +} + +bool IsIdentChar(char c) { + unsigned char uc = static_cast(c); + return std::isalnum(uc) != 0 || c == '_'; +} + +std::string ExtractIncludeBasename(std::string_view target) { + auto pos = target.find_last_of("/\\"); + return std::string(pos == std::string_view::npos ? target : target.substr(pos + 1)); +} + +constexpr std::array kRules = {{ + {"PPC_HOOK", "REX_HOOK", ""}, + {"PPC_STUB", "REX_STUB", ""}, + {"PPC_STUB_LOG", "REX_STUB_LOG", ""}, + {"PPC_STUB_RETURN", "REX_STUB_RETURN", ""}, + {"PPC_FUNC", "REX_FUNC", ""}, + {"PPC_WEAK_FUNC", "REX_WEAK_FUNC", ""}, + {"PPC_FUNC_IMPL", "REX_EXTERN", "PPC_FUNC_IMPL was extern \"C\" PPC_FUNC; use REX_EXTERN"}, + {"PPC_EXTERN_IMPORT", "REX_EXTERN", + "PPC_EXTERN_IMPORT was extern \"C\" PPC_FUNC; use REX_EXTERN"}, + {"PPC_EXTERN_FUNC", "", "removed; declare with extern REX_FUNC(name)"}, + {"PPC_JOIN", "REX_JOIN", ""}, + {"PPC_XSTRINGIFY", "REX_XSTRINGIFY", ""}, + {"PPC_STRINGIFY", "REX_STRINGIFY", ""}, + {"PPC_ROUND_NEAREST", "rex::ppc::kRoundNearest", ""}, + {"PPC_ROUND_TOWARD_ZERO", "rex::ppc::kRoundTowardZero", ""}, + {"PPC_ROUND_UP", "rex::ppc::kRoundUp", ""}, + {"PPC_ROUND_DOWN", "rex::ppc::kRoundDown", ""}, + {"PPC_ROUND_MASK", "rex::ppc::kRoundMask", ""}, + {"PPC_CONFIG_NON_ARGUMENT_AS_LOCAL", "REX_CONFIG_NON_ARGUMENT_AS_LOCAL", ""}, + {"PPC_CONFIG_NON_VOLATILE_AS_LOCAL", "REX_CONFIG_NON_VOLATILE_AS_LOCAL", ""}, + {"PPC_CONFIG_SKIP_LR", "REX_CONFIG_SKIP_LR", ""}, + {"PPC_CONFIG_CTR_AS_LOCAL", "REX_CONFIG_CTR_AS_LOCAL", ""}, + {"PPC_CONFIG_XER_AS_LOCAL", "REX_CONFIG_XER_AS_LOCAL", ""}, + {"PPC_CONFIG_RESERVED_AS_LOCAL", "REX_CONFIG_RESERVED_AS_LOCAL", ""}, + {"PPC_CONFIG_SKIP_MSR", "REX_CONFIG_SKIP_MSR", ""}, + {"PPC_CONFIG_CR_AS_LOCAL", "REX_CONFIG_CR_AS_LOCAL", ""}, + {"PPC_FUNC_PROLOGUE", "REX_FUNC_PROLOGUE", ""}, + {"PPC_CALL_FUNC", "REX_CALL_FUNC", ""}, + {"PPC_LOOKUP_FUNC", "REX_LOOKUP_FUNC", ""}, + {"PPC_CALL_INDIRECT_FUNC", "REX_CALL_INDIRECT_FUNC", ""}, + {"PPC_SET_FLUSH_MODE", "REX_SET_FLUSH_MODE", ""}, + {"PPC_UNIMPLEMENTED", "REX_UNIMPLEMENTED", ""}, + {"PPC_QUERY_TIMEBASE", "REX_QUERY_TIMEBASE", ""}, + {"PPC_CHECK_GLOBAL_LOCK", "REX_CHECK_GLOBAL_LOCK", ""}, + {"PPC_ENTER_GLOBAL_LOCK", "REX_ENTER_GLOBAL_LOCK", ""}, + {"PPC_LEAVE_GLOBAL_LOCK", "REX_LEAVE_GLOBAL_LOCK", ""}, + {"PPC_PHYS_HOST_OFFSET", "REX_PHYS_HOST_OFFSET", ""}, + {"PPC_RAW_ADDR", "REX_RAW_ADDR", ""}, + {"PPC_LOAD_U8", "REX_LOAD_U8", ""}, + {"PPC_LOAD_U16", "REX_LOAD_U16", ""}, + {"PPC_LOAD_U32", "REX_LOAD_U32", ""}, + {"PPC_LOAD_U64", "REX_LOAD_U64", ""}, + {"PPC_LOAD_STRING", "REX_LOAD_STRING", ""}, + {"PPC_STORE_U8", "REX_STORE_U8", ""}, + {"PPC_STORE_U16", "REX_STORE_U16", ""}, + {"PPC_STORE_U32", "REX_STORE_U32", ""}, + {"PPC_STORE_U64", "REX_STORE_U64", ""}, + {"PPC_MEMORY_SIZE", "REX_MEMORY_SIZE", ""}, +}}; + +bool ConfirmSingleArgAllocateThunk(std::string_view line) { + auto name_pos = line.find("AllocateThunk"); + if (name_pos == std::string_view::npos) + return false; + auto open = line.find('(', name_pos); + if (open == std::string_view::npos) + return false; + int depth = 0; + bool any_arg = false; + for (std::size_t i = open; i < line.size(); ++i) { + char c = line[i]; + if (c == '(') { + ++depth; + } else if (c == ')') { + --depth; + if (depth == 0) + return any_arg; + } else if (c == ',' && depth == 1) { + return false; + } else if (depth == 1 && std::isspace(static_cast(c)) == 0) { + any_arg = true; + } + } + return false; +} + +constexpr std::array kCallSiteRules = {{ + {"GetArgument(\"game_directory\")", "removed positional argument 'game_directory'", "", + nullptr}, + {"AllocateThunk(", "single-arg AllocateThunk call", "second arg is now caller_address", + ConfirmSingleArgAllocateThunk}, +}}; + +using RuleIndex = std::unordered_map; + +RuleIndex BuildRuleIndex(std::span rules) { + RuleIndex idx; + idx.reserve(rules.size()); + for (const auto& r : rules) { + if (!r.legacy_token.empty()) + idx.emplace(r.legacy_token, &r); + } + return idx; +} + +std::string RenameReason(const BreakingChangeRule& rule) { + if (!rule.reason.empty()) + return std::string(rule.reason); + return fmt::format("renamed: {} -> {}", rule.legacy_token, rule.replacement); +} + +struct IdentifierScanResult { + std::string content; + std::set applied_reasons; +}; + +IdentifierScanResult ApplyIdentifierRules(const fs::path& path, std::string_view content, + const RuleIndex& rules, + std::vector& warnings) { + IdentifierScanResult result; + result.content.reserve(content.size()); + + std::size_t i = 0; + std::size_t line_start = 0; + std::size_t line_number = 1; + while (i < content.size()) { + char c = content[i]; + if (c == '\n') { + result.content.push_back(c); + ++i; + ++line_number; + line_start = i; + continue; + } + if (!IsIdentStart(c)) { + result.content.push_back(c); + ++i; + continue; + } + std::size_t start = i; + while (i < content.size() && IsIdentChar(content[i])) + ++i; + std::string_view tok(content.data() + start, i - start); + auto it = rules.find(tok); + if (it == rules.end()) { + result.content.append(tok); + continue; + } + const BreakingChangeRule& rule = *it->second; + if (!rule.replacement.empty()) { + result.content.append(rule.replacement); + result.applied_reasons.insert(RenameReason(rule)); + continue; + } + result.content.append(tok); + std::size_t line_end = content.find('\n', start); + if (line_end == std::string_view::npos) + line_end = content.size(); + while (line_end > line_start && content[line_end - 1] == '\r') + --line_end; + warnings.push_back({path, line_number, + std::string(content.substr(line_start, line_end - line_start)), + fmt::format("legacy identifier: {}", tok), std::string(rule.reason)}); + } + return result; +} + +std::string SummarizeRenames(const std::set& reasons) { + static constexpr std::size_t kMaxListed = 3; + std::string out; + std::size_t i = 0; + for (const auto& reason : reasons) { + if (i == kMaxListed) + break; + if (i > 0) + out += '\n'; + out += reason; + ++i; + } + if (reasons.size() > kMaxListed) + out += fmt::format("\n(+{} more)", reasons.size() - kMaxListed); + return out; +} + +} // namespace + +std::span DefaultBreakingChangeRules() { + return {kRules.data(), kRules.size()}; +} + +std::span DefaultCallSiteRules() { + return {kCallSiteRules.data(), kCallSiteRules.size()}; +} + +std::string RenderRexglueCmake(std::string_view project_name, std::string_view sdk_version, + std::string_view entrypoint_out_dir) { + rex::codegen::TemplateRegistry registry; + auto names = parse_app_name(std::string(project_name)); + nlohmann::json data = { + {"names", names_to_json(names)}, + {"sdk_version", std::string(sdk_version)}, + {"entrypoint_out_dir", std::string(entrypoint_out_dir)}, + }; + return registry.render("init/rexglue_cmake", data.dump()); +} + +std::vector ScanSdkTemplateDrift(const fs::path& project_root, + std::string_view project_name, + std::string_view sdk_version, + std::string_view entrypoint_out_dir) { + std::vector plan; + fs::path rexglue_cmake = project_root / "generated" / "rexglue.cmake"; + std::string rendered = RenderRexglueCmake(project_name, sdk_version, entrypoint_out_dir); + std::string on_disk = fs::exists(rexglue_cmake) ? read_file(rexglue_cmake) : std::string{}; + if (rendered != on_disk) { + plan.push_back({rexglue_cmake, std::move(rendered), OverwriteAction::Write, /*silent=*/true, + fmt::format("regenerate SDK helper for v{}", sdk_version)}); + } + return plan; +} + +std::vector ScanCmakeReferences(const fs::path& project_root, + std::string_view legacy_filename, + std::string_view manifest_filename) { + std::vector entries; + if (legacy_filename.empty() || manifest_filename.empty() || legacy_filename == manifest_filename) + return entries; + + WalkProjectFiles(project_root, IsCmakeFile, [&](const fs::path& path) { + std::string content = read_file(path); + if (content.empty()) + return; + std::string updated = content; + if (!ReplaceAllPathTokens(updated, legacy_filename, manifest_filename)) + return; + entries.push_back({path, std::move(updated), OverwriteAction::Write, /*silent=*/false, + fmt::format("{} -> {}", legacy_filename, manifest_filename)}); + }); + return entries; +} + +std::vector ScanSourceIncludeRewrites(const fs::path& project_root, + std::string_view project_name) { + std::vector entries; + if (project_name.empty()) + return entries; + + auto names = parse_app_name(std::string(project_name)); + std::string old_basename_lc = ToLower(names.snake_case + "_config.h"); + std::string new_basename = names.snake_case + "_init.h"; + std::string new_basename_lc = ToLower(new_basename); + + static const std::regex include_re(R"(^(\s*#\s*include\s*[<"])([^>"]+)([>"].*)$)"); + auto extract_target = [&](const std::string& line) -> std::optional { + std::smatch m; + if (!std::regex_search(line, m, include_re)) + return std::nullopt; + return m[2].str(); + }; + + WalkProjectFiles(project_root, IsSourceExtension, [&](const fs::path& path) { + std::string content = read_file(path); + if (content.empty()) + return; + + std::vector lines; + std::string buf; + for (char c : content) { + if (c == '\n') { + lines.push_back(std::move(buf)); + buf.clear(); + } else { + buf.push_back(c); + } + } + if (!buf.empty()) + lines.push_back(std::move(buf)); + bool has_trailing_newline = !content.empty() && content.back() == '\n'; + + bool has_init_include = false; + for (const auto& line : lines) { + auto target = extract_target(line); + if (target && ToLower(ExtractIncludeBasename(*target)) == new_basename_lc) { + has_init_include = true; + break; + } + } + + bool changed = false; + std::string out; + out.reserve(content.size()); + for (std::size_t li = 0; li < lines.size(); ++li) { + const std::string& line = lines[li]; + auto target = extract_target(line); + auto append_line = [&](std::string_view payload) { + out.append(payload); + if (li + 1 < lines.size() || has_trailing_newline) + out.push_back('\n'); + }; + + if (!target || ToLower(ExtractIncludeBasename(*target)) != old_basename_lc) { + append_line(line); + continue; + } + if (has_init_include) { + changed = true; + continue; + } + std::smatch m; + if (!std::regex_search(line, m, include_re)) { + append_line(line); + continue; + } + std::string prefix = m[1].str(); + std::string old_target = m[2].str(); + std::string suffix = m[3].str(); + std::string base = ExtractIncludeBasename(old_target); + std::string new_target = old_target; + new_target.replace(new_target.size() - base.size(), base.size(), new_basename); + append_line(prefix + new_target + suffix); + has_init_include = true; + changed = true; + } + + if (!changed) + return; + entries.push_back( + {path, std::move(out), OverwriteAction::Write, /*silent=*/false, + fmt::format("{}_config.h -> {}_init.h", names.snake_case, names.snake_case)}); + }); + return entries; +} + +MigrationFindings ScanLegacyIdentifiers(const fs::path& project_root, + std::span rules) { + MigrationFindings out; + RuleIndex index = BuildRuleIndex(rules); + if (index.empty()) + return out; + + WalkProjectFiles(project_root, IsSourceExtension, [&](const fs::path& path) { + std::string content = read_file(path); + if (content.empty()) + return; + + std::size_t warnings_before = out.warnings.size(); + auto result = ApplyIdentifierRules(path, content, index, out.warnings); + if (result.applied_reasons.empty()) + return; + std::string reason = SummarizeRenames(result.applied_reasons); + if (auto warning_count = out.warnings.size() - warnings_before; warning_count > 0) { + reason += fmt::format("\n(+{} warn-only)", warning_count); + } + out.rewrites.push_back( + {path, std::move(result.content), OverwriteAction::Write, /*silent=*/false, reason}); + }); + return out; +} + +std::vector ScanCallSitePatterns(const fs::path& project_root, + std::span rules) { + std::vector out; + if (rules.empty()) + return out; + + WalkProjectFiles(project_root, IsSourceExtension, [&](const fs::path& path) { + std::string content = read_file(path); + if (content.empty()) + return; + + std::size_t line_start = 0; + std::size_t line_number = 1; + for (std::size_t i = 0; i <= content.size(); ++i) { + bool eol = i == content.size() || content[i] == '\n'; + if (!eol) + continue; + std::size_t line_end = i; + while (line_end > line_start && content[line_end - 1] == '\r') + --line_end; + std::string_view line(content.data() + line_start, line_end - line_start); + for (const auto& rule : rules) { + if (line.find(rule.pattern) == std::string_view::npos) + continue; + if (rule.confirm && !rule.confirm(line)) + continue; + out.push_back({path, line_number, std::string(line), std::string(rule.detail), + std::string(rule.hint)}); + } + line_start = i + 1; + ++line_number; + } + }); + return out; +} + +std::vector ScanStaleIncludes( + const fs::path& src_dir, const std::unordered_set& removed_basenames) { + std::vector matches; + if (!fs::is_directory(src_dir)) + return matches; + + std::unordered_set removed_lower; + removed_lower.reserve(removed_basenames.size()); + for (const auto& name : removed_basenames) + removed_lower.insert(ToLower(name)); + + static const std::regex include_re(R"(^\s*#\s*include\s*[<"]([^>"]+)[>"])"); + + for (const auto& entry : fs::recursive_directory_iterator(src_dir)) { + if (!entry.is_regular_file() || !IsSourceExtension(entry.path())) + continue; + std::ifstream in(entry.path()); + if (!in) + continue; + std::string line; + std::size_t line_number = 0; + while (std::getline(in, line)) { + ++line_number; + std::smatch m; + if (!std::regex_search(line, m, include_re)) + continue; + std::string target = m[1].str(); + auto pos = target.find_last_of("/\\"); + std::string basename = pos == std::string::npos ? target : target.substr(pos + 1); + if (!removed_lower.contains(ToLower(basename))) + continue; + matches.push_back({entry.path(), line_number, line, fmt::format("stale include: {}", target), + "header no longer emitted by codegen; update or remove the include"}); + } + } + + std::sort(matches.begin(), matches.end(), [](const auto& a, const auto& b) { + if (a.file != b.file) + return a.file < b.file; + return a.line_number < b.line_number; + }); + return matches; +} + +} // namespace rexglue::cli diff --git a/src/rexglue/commands/migration_scan.h b/src/rexglue/commands/migration_scan.h new file mode 100644 index 0000000..e9cd41f --- /dev/null +++ b/src/rexglue/commands/migration_scan.h @@ -0,0 +1,92 @@ +/** + * @file rexglue/commands/migration_scan.h + * @brief Project-tree scanners for SDK upgrade-driven migrations + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace rexglue::cli { + +enum class OverwriteAction { + Write, + Delete, +}; + +struct OverwriteEntry { + std::filesystem::path path; + std::string rendered_content; + OverwriteAction action = OverwriteAction::Write; + bool silent = false; + std::string reason; +}; + +struct MigrationWarning { + std::filesystem::path file; + std::size_t line_number; + std::string raw_line; + std::string detail; + std::string hint; +}; + +struct MigrationFindings { + std::vector rewrites; + std::vector warnings; +}; + +struct BreakingChangeRule { + std::string_view legacy_token; + std::string_view replacement; + std::string_view reason; +}; + +struct CallSiteRule { + std::string_view pattern; + std::string_view detail; + std::string_view hint; + bool (*confirm)(std::string_view line) = nullptr; +}; + +std::span DefaultBreakingChangeRules(); +std::span DefaultCallSiteRules(); + +std::string RenderRexglueCmake(std::string_view project_name, std::string_view sdk_version, + std::string_view entrypoint_out_dir); + +std::vector ScanSdkTemplateDrift(const std::filesystem::path& project_root, + std::string_view project_name, + std::string_view sdk_version, + std::string_view entrypoint_out_dir); + +std::vector ScanCmakeReferences(const std::filesystem::path& project_root, + std::string_view legacy_filename, + std::string_view manifest_filename); + +std::vector ScanSourceIncludeRewrites(const std::filesystem::path& project_root, + std::string_view project_name); + +MigrationFindings ScanLegacyIdentifiers( + const std::filesystem::path& project_root, + std::span rules = DefaultBreakingChangeRules()); + +std::vector ScanCallSitePatterns( + const std::filesystem::path& project_root, + std::span rules = DefaultCallSiteRules()); + +std::vector ScanStaleIncludes( + const std::filesystem::path& src_dir, const std::unordered_set& removed_basenames); + +} // namespace rexglue::cli diff --git a/src/rexglue/commands/template_utils.h b/src/rexglue/commands/template_utils.h new file mode 100644 index 0000000..2b9f286 --- /dev/null +++ b/src/rexglue/commands/template_utils.h @@ -0,0 +1,138 @@ +/** + * @file rexglue/commands/template_utils.h + * @brief Shared utilities for init command + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace rexglue::cli { + +struct AppNameParts { + std::string snake_case; + std::string pascal_case; + std::string upper_case; +}; + +inline bool validate_app_name(const std::string& input, std::string& error) { + if (input.empty()) { + error = "App name must not be empty"; + return false; + } + if (!std::isalpha(static_cast(input[0]))) { + error = "App name must start with a letter"; + return false; + } + for (char c : input) { + if (!std::isalnum(static_cast(c)) && c != '_' && c != '-' && c != ' ') { + error = "App name contains invalid character '" + std::string(1, c) + + "'. Only alphanumeric, space, underscore, and dash are allowed"; + return false; + } + } + return true; +} + +inline AppNameParts parse_app_name(const std::string& input) { + std::vector words; + std::string current; + for (char c : input) { + if (c == ' ' || c == '_' || c == '-') { + if (!current.empty()) { + words.push_back(current); + current.clear(); + } + } else { + current += static_cast(std::tolower(static_cast(c))); + } + } + if (!current.empty()) { + words.push_back(current); + } + + AppNameParts parts; + for (size_t i = 0; i < words.size(); ++i) { + if (i > 0) + parts.snake_case += '_'; + parts.snake_case += words[i]; + } + for (const auto& w : words) { + std::string word = w; + if (!word.empty() && std::isalpha(static_cast(word[0]))) { + word[0] = static_cast(std::toupper(static_cast(word[0]))); + } + parts.pascal_case += word; + } + for (const auto& w : words) { + for (char c : w) { + parts.upper_case += static_cast(std::toupper(static_cast(c))); + } + } + return parts; +} + +inline nlohmann::json names_to_json(const AppNameParts& names) { + return {{"snake_case", names.snake_case}, + {"pascal_case", names.pascal_case}, + {"upper_case", names.upper_case}}; +} + +inline bool write_file(const std::filesystem::path& path, const std::string& content) { + std::ofstream file(path); + if (!file) { + REXLOG_ERROR("Failed to create file: {}", path.string()); + return false; + } + file << content; + return true; +} + +inline bool write_file_atomic(const std::filesystem::path& path, const std::string& content) { + std::filesystem::path tmp = path; + tmp += ".tmp"; + { + std::ofstream out(tmp, std::ios::binary); + if (!out) { + REXLOG_ERROR("Failed to open tmp file for write: {}", tmp.string()); + return false; + } + out << content; + if (!out.good()) { + std::error_code ignore; + std::filesystem::remove(tmp, ignore); + REXLOG_ERROR("Failed while writing tmp file: {}", tmp.string()); + return false; + } + } + std::error_code ec; + std::filesystem::rename(tmp, path, ec); + if (ec) { + std::error_code ignore; + std::filesystem::remove(tmp, ignore); + REXLOG_ERROR("Failed to rename {} to {}: {}", tmp.string(), path.string(), ec.message()); + return false; + } + return true; +} + +inline std::string read_file(const std::filesystem::path& path) { + std::ifstream in(path, std::ios::binary); + if (!in) + return {}; + return {std::istreambuf_iterator(in), std::istreambuf_iterator()}; +} + +} // namespace rexglue::cli diff --git a/src/rexglue/commands/test_recompiler.cpp b/src/rexglue/commands/test_recompiler.cpp new file mode 100644 index 0000000..179b2df --- /dev/null +++ b/src/rexglue/commands/test_recompiler.cpp @@ -0,0 +1,487 @@ +/** + * @file rexglue/commands/test_recompiler.cpp + * @brief Recompiler test command implementation + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include "test_recompiler.h" +#include "../ui/ui.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "codegen/template_registry_internal.h" + +namespace rexglue::cli { + +namespace { + +namespace fs = std::filesystem; +namespace codegen = rex::codegen; + +constexpr uint32_t kTestBaseAddress = 0x82010000; + +struct RegValue { + std::string reg; + std::string value; + bool is_vector = false; + bool is_float = false; + std::string vec_values[4]; +}; + +struct MemValue { + std::string address; + std::vector data; +}; + +struct TestSpec { + std::string name; + std::string symbol; + std::vector inputs; + std::vector outputs; + std::vector mem_inputs; + std::vector mem_outputs; +}; + +std::map ParseMapFile(const std::string& mapPath) { + std::map symbols; + rex::runtime::MapParseOptions options; + options.base_address = kTestBaseAddress; + + auto result = rex::runtime::ParseNmMap(mapPath, options); + if (!result) + return symbols; + for (const auto& sym : *result) { + if (sym.name.empty() || sym.name[0] == '.') + continue; + symbols[sym.address] = sym.name; + } + return symbols; +} + +std::vector ParseHexBytes(const std::string& hex) { + std::vector result; + for (size_t i = 0; i < hex.size(); i += 2) { + if (i + 1 >= hex.size()) + break; + if (hex[i] == ' ') { + i--; + continue; + } + uint8_t val = 0; + std::from_chars(&hex[i], &hex[i + 2], val, 16); + result.push_back(val); + } + return result; +} + +/* Source order is high-to-low; stored low-to-high to match runtime layout. */ +RegValue ParseVectorRegister(const std::string& line, std::string reg, size_t after) { + RegValue rv; + rv.reg = std::move(reg); + rv.is_vector = true; + auto open = line.find('[', after + 1); + auto c0 = line.find(',', open + 1); + auto c1 = line.find(',', c0 + 1); + auto c2 = line.find(',', c1 + 1); + auto close = line.find(']', c2 + 1); + rv.vec_values[3] = line.substr(open + 1, c0 - open - 1); + rv.vec_values[2] = line.substr(c0 + 2, c1 - c0 - 2); + rv.vec_values[1] = line.substr(c1 + 2, c2 - c1 - 2); + rv.vec_values[0] = line.substr(c2 + 2, close - c2 - 2); + return rv; +} + +RegValue ParseRegisterDirective(const std::string& line, size_t directive_idx) { + auto sp1 = line.find(' ', directive_idx); + auto sp2 = line.find(' ', sp1 + 1); + std::string reg = line.substr(sp1 + 1, sp2 - sp1 - 1); + if (!reg.empty() && reg[0] == 'v') + return ParseVectorRegister(line, std::move(reg), sp2); + + RegValue rv; + rv.reg = std::move(reg); + rv.value = line.substr(sp2 + 1); + rv.is_float = (line.find('.', sp2) != std::string::npos); + return rv; +} + +MemValue ParseMemoryDirective(const std::string& line, size_t directive_idx) { + auto sp1 = line.find(' ', directive_idx); + auto sp2 = line.find(' ', sp1 + 1); + MemValue mv; + mv.address = line.substr(sp1 + 1, sp2 - sp1 - 1); + mv.data = ParseHexBytes(line.substr(sp2 + 1)); + return mv; +} + +void ApplyDirective(const std::string& line, std::string_view reg_token, std::string_view mem_token, + std::vector& regs, std::vector& mems) { + if (line.size() <= 1 || line[1] != '_') + return; + if (auto idx = line.find(reg_token); idx != std::string::npos) { + regs.push_back(ParseRegisterDirective(line, idx)); + } else if (auto idx2 = line.find(mem_token); idx2 != std::string::npos) { + mems.push_back(ParseMemoryDirective(line, idx2)); + } +} + +std::string BuildHierarchicalName(const std::string& stem, const std::string& label) { + if (stem.starts_with("instr_")) { + std::string group = stem.substr(6); + std::string prefix = "test_" + group + "_"; + if (label.starts_with(prefix)) + return group + ".test_" + label.substr(prefix.size()); + if (label == "test_" + group) + return group + ".test"; + return group + "." + label; + } + if (stem.starts_with("seq_")) { + if (label.starts_with("seq_")) + return "seq.test_" + label.substr(4); + return "seq." + label; + } + return stem + "." + label; +} + +std::vector ParseTestSpecs(const std::string& asmPath, + const std::unordered_map& symbols) { + std::vector specs; + std::ifstream in(asmPath); + if (!in.is_open()) { + REXLOG_WARN("Unable to open assembly file: {}", asmPath); + return specs; + } + + std::string line; + bool in_block_comment = false; + auto getline = [&]() -> bool { + while (std::getline(in, line)) { + line = rex::string::trim_string(line); + if (in_block_comment) { + auto end = line.find("*/"); + if (end == std::string::npos) + continue; + in_block_comment = false; + line = rex::string::trim_string(line.substr(end + 2)); + if (line.empty()) + continue; + } + if (auto start = line.find("/*"); start != std::string::npos) { + if (auto end = line.find("*/", start + 2); end != std::string::npos) { + line = line.substr(0, start) + line.substr(end + 2); + } else { + in_block_comment = true; + line = line.substr(0, start); + } + line = rex::string::trim_string(line); + if (line.empty()) + continue; + } + return true; + } + return false; + }; + + while (getline()) { + if (line.empty() || line[0] == '#') + continue; + auto colonIndex = line.find(':'); + if (colonIndex == std::string::npos) + continue; + auto name = line.substr(0, colonIndex); + auto symbolIt = symbols.find(name); + if (symbolIt == symbols.end()) + continue; + + TestSpec spec; + spec.name = name; + spec.symbol = symbolIt->second; + + while (getline() && !line.empty() && line[0] == '#') { + ApplyDirective(line, "REGISTER_IN", "MEMORY_IN", spec.inputs, spec.mem_inputs); + } + while (line.empty() || line[0] != '#') { + if (!getline()) + break; + } + do { + ApplyDirective(line, "REGISTER_OUT", "MEMORY_OUT", spec.outputs, spec.mem_outputs); + } while (getline() && !line.empty() && line[0] == '#'); + + if (!spec.inputs.empty() || !spec.outputs.empty() || !spec.mem_inputs.empty() || + !spec.mem_outputs.empty()) { + specs.push_back(std::move(spec)); + } + } + return specs; +} + +nlohmann::json SerializeRegisters(const std::vector& regs) { + nlohmann::json arr = nlohmann::json::array(); + for (const auto& rv : regs) { + nlohmann::json reg; + reg["reg"] = rv.reg; + if (rv.reg == "cr") { + reg["type"] = "cr"; + reg["value"] = rv.value; + } else if (rv.is_vector) { + reg["type"] = "vector"; + reg["values"] = {rv.vec_values[3], rv.vec_values[2], rv.vec_values[1], rv.vec_values[0]}; + } else if (rv.is_float) { + reg["type"] = "float"; + reg["value"] = rv.value; + } else { + reg["type"] = "gpr"; + reg["value"] = rv.value; + } + arr.push_back(reg); + } + return arr; +} + +nlohmann::json SerializeMemory(const std::vector& mems) { + nlohmann::json arr = nlohmann::json::array(); + for (const auto& mv : mems) { + nlohmann::json mem; + mem["address"] = mv.address; + nlohmann::json bytes = nlohmann::json::array(); + for (size_t i = 0; i < mv.data.size(); ++i) { + bytes.push_back( + {{"offset", fmt::format("{:X}", i)}, {"value", fmt::format("{:02X}", mv.data[i])}}); + } + mem["bytes"] = bytes; + arr.push_back(mem); + } + return arr; +} + +std::string CategoryFromStem(std::string_view stem) { + auto contains = [&](std::string_view s) { return stem.find(s) != std::string_view::npos; }; + if (contains("add") || contains("sub") || contains("mul") || contains("div")) + return "arithmetic"; + if (contains("cmp")) + return "comparison"; + if (contains("and") || contains("or") || contains("xor") || contains("rl")) + return "logical"; + if (stem.starts_with("f") || contains("_f")) + return "floating_point"; + if (stem.starts_with("v") || contains("_v")) + return "vector"; + if (stem.starts_with("l") || stem.starts_with("st")) + return "memory"; + return "misc"; +} + +bool RecompileTests(std::string_view binDir, std::string_view asmDir, std::string_view outDir) { + std::array header_rows = {{ + {"Bin dir", std::string(binDir)}, + {"ASM dir", std::string(asmDir)}, + {"Output dir", std::string(outDir)}, + }}; + ui::KeyValueBlock("Recompiling PPC tests:", header_rows); + + fs::create_directories(outDir); + + std::map> functionsByFile; + std::vector allFunctionNames; + std::stringstream functionsOut; + + for (const auto& entry : fs::directory_iterator(binDir)) { + if (entry.path().extension() != ".bin") + continue; + auto stem = entry.path().stem().string(); + REXLOG_DEBUG("Processing binary file: {}", stem); + + std::vector fileData; + { + std::ifstream file(entry.path(), std::ios::binary | std::ios::ate); + if (!file) { + REXLOG_WARN("Failed to load binary file: {}", entry.path().string()); + continue; + } + auto size = file.tellg(); + file.seekg(0, std::ios::beg); + fileData.resize(static_cast(size)); + file.read(reinterpret_cast(fileData.data()), size); + } + if (fileData.empty()) + continue; + + auto mapPath = fmt::format("{}/{}.map", binDir, stem); + auto symbols = ParseMapFile(mapPath); + if (symbols.empty()) { + REXLOG_ERROR("No symbols found in map file: {}", mapPath); + continue; + } + + codegen::TestModule module; + module.Load(kTestBaseAddress, fileData.data(), fileData.size()); + module.set_name(stem); + + codegen::RecompilerConfig config; + config.outDirectoryPath = std::string(outDir); + auto ctx = + codegen::CodegenContext::Create(codegen::BinaryView::fromModule(module), std::move(config)); + + codegen::AnalyzeTestBinary(ctx, stem, symbols, kTestBaseAddress, fileData.data(), + fileData.size()); + + REXLOG_DEBUG(" Found {} functions", ctx.graph.functionCount()); + + std::vector functions; + for (const auto& [addr, node] : ctx.graph.functions()) + functions.push_back(node.get()); + std::sort(functions.begin(), functions.end(), + [](const auto* a, const auto* b) { return a->base() < b->base(); }); + + codegen::EmitContext emitCtx{ctx.binary(), ctx.Config(), ctx.graph, 0, nullptr}; + + std::string recompiledCode; + for (const auto* fn : functions) { + std::string code = fn->emitCpp(emitCtx); + if (code.empty()) + continue; + functionsByFile[stem].emplace(fn->base()); + allFunctionNames.push_back(fmt::format("{}_{:X}", stem, fn->base())); + recompiledCode += code; + } + functionsOut << recompiledCode << '\n'; + } + + std::unordered_map allSymbols; + for (const auto& [stem, addresses] : functionsByFile) { + auto mapPath = fmt::format("{}/{}.map", binDir, stem); + auto mapSymbols = ParseMapFile(mapPath); + for (const auto& [addr, name] : mapSymbols) { + if (addresses.count(addr)) + allSymbols.emplace(name, fmt::format("{}_{:X}", stem, addr)); + } + if (!mapSymbols.empty()) + continue; + + std::vector sortedAddresses(addresses.begin(), addresses.end()); + std::sort(sortedAddresses.begin(), sortedAddresses.end()); + std::ifstream in(fmt::format("{}/{}.s", asmDir, stem)); + if (!in.is_open()) + continue; + std::string line; + size_t functionIndex = 0; + while (std::getline(in, line)) { + if (line.empty() || line[0] == '#' || line[0] == '/' || line[0] == '*') + continue; + auto colonIdx = line.find(':'); + if (colonIdx == std::string::npos || line[0] == ' ' || line[0] == '\t' || line[0] == '.') + continue; + auto name = line.substr(0, colonIdx); + if (functionIndex < sortedAddresses.size()) { + allSymbols.emplace(name, fmt::format("{}_{:X}", stem, sortedAddresses[functionIndex])); + ++functionIndex; + } + } + } + + nlohmann::json templateData; + templateData["functions"] = nlohmann::json::array(); + for (const auto& funcName : allFunctionNames) + templateData["functions"].push_back({{"name", funcName}}); + templateData["functions_code"] = functionsOut.str(); + templateData["image_base"] = "82010000"; + templateData["image_size"] = "100000"; + templateData["code_base"] = "82010000"; + templateData["code_size"] = "100000"; + + templateData["tests"] = nlohmann::json::array(); + size_t totalTests = 0; + for (const auto& [stem, addresses] : functionsByFile) { + auto specs = ParseTestSpecs(fmt::format("{}/{}.s", asmDir, stem), allSymbols); + std::string category = CategoryFromStem(stem); + for (const auto& spec : specs) { + nlohmann::json testJson; + testJson["name"] = BuildHierarchicalName(stem, spec.name); + testJson["category"] = category; + testJson["stem"] = stem; + testJson["symbol"] = spec.symbol; + testJson["inputs"]["registers"] = SerializeRegisters(spec.inputs); + testJson["inputs"]["memory"] = SerializeMemory(spec.mem_inputs); + testJson["outputs"]["registers"] = SerializeRegisters(spec.outputs); + testJson["outputs"]["memory"] = SerializeMemory(spec.mem_outputs); + templateData["tests"].push_back(testJson); + ++totalTests; + } + } + + codegen::TemplateRegistry registry; + auto writeRendered = [&](std::string_view templateId, std::string_view filename) { + auto rendered = codegen::renderWithJson(registry, std::string(templateId), templateData); + std::ofstream out(fmt::format("{}/{}", outDir, filename)); + out << rendered; + }; + writeRendered("test/ppc_config_h", "ppc_config.h"); + writeRendered("test/ppc_test_decls_h", "ppc_test_decls.h"); + writeRendered("test/ppc_test_functions_cpp", "ppc_test_functions.cpp"); + writeRendered("test/ppc_test_cases_cpp", "ppc_test_cases.cpp"); + + REXLOG_TRACE("Generated {} test cases", totalTests); + return true; +} + +struct RecompileTestsArgs { + std::string bin_dir; + std::string asm_dir; + std::string output; +}; + +} // namespace + +void RegisterRecompileTests(CLI::App& parent, const CliContext& ctx, DeferredAction& pending) { + (void)ctx; + auto args = std::make_shared(); + auto* sub = parent.add_subcommand("recompile-tests", "Generate Catch2 tests from PPC assembly") + ->fallthrough(); + sub->add_option("--bin-dir", args->bin_dir, "Directory containing linked .bin and .map files") + ->type_name("PATH") + ->required(); + sub->add_option("--asm-dir", args->asm_dir, "Directory containing .s assembly source files") + ->type_name("PATH") + ->required(); + sub->add_option("--output", args->output, "Output path for recompile-tests") + ->type_name("PATH") + ->required(); + sub->callback([args, &pending]() { + pending = [args]() -> rex::Result { + if (!RecompileTests(args->bin_dir, args->asm_dir, args->output)) { + return Err(rex::ErrorCategory::Validation, "Test recompilation failed"); + } + return rex::Ok(); + }; + }); +} + +} // namespace rexglue::cli diff --git a/src/rexglue/commands/test_recompiler.h b/src/rexglue/commands/test_recompiler.h new file mode 100644 index 0000000..6ebe519 --- /dev/null +++ b/src/rexglue/commands/test_recompiler.h @@ -0,0 +1,21 @@ +/** + * @file rexglue/commands/test_recompiler.h + * @brief Recompiler test command interface + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#pragma once + +#include "../cli_utils.h" + +namespace CLI { +class App; +} + +namespace rexglue::cli { + +void RegisterRecompileTests(CLI::App& parent, const CliContext& ctx, DeferredAction& pending); + +} // namespace rexglue::cli diff --git a/src/rexglue/main.cpp b/src/rexglue/main.cpp new file mode 100644 index 0000000..d3f0dfc --- /dev/null +++ b/src/rexglue/main.cpp @@ -0,0 +1,116 @@ +/** + * @file rexglue/main.cpp + * @brief ReXGlue CLI tool entry point + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include "cli_utils.h" +#include "commands/codegen_command.h" +#include "commands/init_command.h" +#include "commands/test_recompiler.h" +#include "ui/ui.h" + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#else +#include +#endif + +namespace { + +std::string TitleString() { + return fmt::format("ReXGlue v{} - Xbox 360 Recompilation Toolkit", REXGLUE_VERSION_STRING); +} + +bool IsStderrTty() { +#ifdef _WIN32 + return _isatty(_fileno(stderr)) != 0; +#else + return isatty(fileno(stderr)) != 0; +#endif +} + +bool ColorEnabled(bool tty) { + if (const char* nc = std::getenv("NO_COLOR"); nc && *nc) + return false; + return tty; +} + +void ConfigureLogging(const std::string& level, const std::string& log_file, bool verbose) { + std::map category_levels; + auto config = rex::BuildLogConfig(log_file.empty() ? nullptr : log_file.c_str(), + verbose ? "trace" : level, category_levels); + config.log_to_console = true; + rex::InitLogging(config); + rex::RegisterLogLevelCallback(); +} + +} // namespace + +int main(int argc, char** argv) { + CLI::App app{TitleString(), "rexglue"}; + app.set_version_flag("--version", REXGLUE_VERSION_STRING); + app.require_subcommand(1); + + rexglue::cli::CliContext ctx; + std::string log_level = "info"; + std::string log_file; + bool verbose = false; + bool force = false; + + app.add_option("--log-level", log_level, "Log level (trace, debug, info, warn, error)") + ->type_name("LEVEL"); + app.add_option("--log-file", log_file, "Append diagnostics to file")->type_name("PATH"); + app.add_flag("-v,--verbose", verbose, "Equivalent to --log-level=trace"); + app.add_flag("-f,--force", force, "Skip confirmations and proceed"); + + rex::InitLoggingEarly(); + rex::cvar::ApplyEnvironment(); + + rexglue::cli::DeferredAction pending; + rexglue::cli::RegisterCodegen(app, ctx, pending); + rexglue::cli::RegisterInit(app, ctx, pending); + rexglue::cli::RegisterRecompileTests(app, ctx, pending); + + CLI11_PARSE(app, argc, argv); + + ConfigureLogging(log_level, log_file, verbose); + ctx.verbose = verbose; + ctx.overwrite_existing = force; + ctx.generate_despite_errors = force; + ctx.skip_upgrade_consent = force; + + bool tty = IsStderrTty(); + rexglue::ui::Init({.tty = tty, .color = ColorEnabled(tty)}); + rexglue::ui::Banner(TitleString()); + + auto start = std::chrono::steady_clock::now(); + rex::Result result = pending ? pending() : rex::Ok(); + auto elapsed = std::chrono::duration_cast( + std::chrono::steady_clock::now() - start); + + int exit_code = 0; + if (!result) { + rexglue::ui::FailureSummary(result.error().what(), elapsed); + exit_code = result.error().category == rex::ErrorCategory::UserAbort ? 2 : 1; + } else { + rexglue::ui::DoneSummary(elapsed); + } + rexglue::ui::Shutdown(); + return exit_code; +} diff --git a/src/rexglue/ui/glyphs.h b/src/rexglue/ui/glyphs.h new file mode 100644 index 0000000..1c0d13e --- /dev/null +++ b/src/rexglue/ui/glyphs.h @@ -0,0 +1,28 @@ +/** + * @file rexglue/ui/glyphs.h + * @brief Unicode glyph constants for ui rendering + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include + +namespace rexglue::ui::glyphs { + +/* U+2713 CHECK MARK */ +inline constexpr std::string_view kCheckMark = "\xE2\x9C\x93"; + +/* Braille spinner (U+280B U+2819 U+2839 U+2838 U+283C U+2834 U+2826 U+2827 U+2807 U+280F) */ +inline constexpr std::array kSpinnerFrames = { + "\xE2\xA0\x8B", "\xE2\xA0\x99", "\xE2\xA0\xB9", "\xE2\xA0\xB8", "\xE2\xA0\xBC", + "\xE2\xA0\xB4", "\xE2\xA0\xA6", "\xE2\xA0\xA7", "\xE2\xA0\x87", "\xE2\xA0\x8F", +}; + +} // namespace rexglue::ui::glyphs diff --git a/src/rexglue/ui/progress.cpp b/src/rexglue/ui/progress.cpp new file mode 100644 index 0000000..d8ab2a3 --- /dev/null +++ b/src/rexglue/ui/progress.cpp @@ -0,0 +1,188 @@ +/** + * @file rexglue/ui/progress.cpp + * @brief ProgressView implementation + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "progress.h" + +#include "glyphs.h" +#include "ui.h" + +#include + +namespace rexglue::ui { + +namespace { +constexpr std::string_view kEraseLine = "\r\033[K"; +constexpr auto kSpinnerInterval = std::chrono::milliseconds(100); +} // namespace + +ProgressView::ProgressView(std::string_view title) : title_(title) { + { + detail::GlobalSinkAccessor acc; + acc.writeColored(color::kBold, title_); + acc.writeRaw("\n"); + tty_ = detail::SinkIsTty(); + } + if (tty_) { + detail::SetSinkActiveProgress(true); + spinner_thread_ = std::thread(&ProgressView::spinnerLoop, this); + } +} + +ProgressView::~ProgressView() { + if (tty_) { + stop_spinner_.store(true, std::memory_order_release); + spinner_cv_.notify_all(); + if (spinner_thread_.joinable()) + spinner_thread_.join(); + detail::SetSinkActiveProgress(false); + } + std::lock_guard lock(state_mutex_); + if (active_line_kind_ != ActiveLineKind::None) { + detail::GlobalSinkAccessor acc; + acc.writeRaw(kEraseLine); + active_line_kind_ = ActiveLineKind::None; + } +} + +void ProgressView::clearActiveLine() { + if (active_line_kind_ == ActiveLineKind::None || !tty_) + return; + detail::GlobalSinkAccessor acc; + acc.writeRaw(kEraseLine); + active_line_kind_ = ActiveLineKind::None; +} + +void ProgressView::renderActiveLine() { + if (!tty_) + return; + detail::GlobalSinkAccessor acc; + acc.writeRaw(kEraseLine); + spinner_frame_ = (spinner_frame_ + 1) % glyphs::kSpinnerFrames.size(); + acc.writeColored(color::kCyan, glyphs::kSpinnerFrames[spinner_frame_]); + acc.writeRaw(" "); + if (active_line_kind_ == ActiveLineKind::Module) { + if (current_module_ >= modules_.size()) + return; + acc.writeColored(color::kBold, modules_[current_module_].name); + acc.writeRaw(" ["); + acc.writeColored(color::kDim, current_phase_.empty() ? std::string_view{"start"} + : std::string_view{current_phase_}); + acc.writeRaw("]"); + } else if (active_line_kind_ == ActiveLineKind::ProjectPhase) { + acc.writeColored(color::kBold, fmt::format("project::{}", current_project_phase_)); + } + acc.flush(); +} + +void ProgressView::spinnerLoop() { + std::unique_lock cv_lock(state_mutex_); + while (!stop_spinner_.load(std::memory_order_acquire)) { + if (active_line_kind_ != ActiveLineKind::None) + renderActiveLine(); + spinner_cv_.wait_for(cv_lock, kSpinnerInterval, + [this] { return stop_spinner_.load(std::memory_order_acquire); }); + } +} + +void ProgressView::moduleStarted(std::string_view name, std::size_t index, std::size_t total) { + (void)total; + std::lock_guard lock(state_mutex_); + current_module_ = index; + if (modules_.size() <= index) + modules_.resize(index + 1); + modules_[index].name = std::string(name); + current_phase_.clear(); + + if (!tty_) { + detail::GlobalSinkAccessor acc; + acc.writeLine(fmt::format(" start {}", name)); + return; + } + + active_line_kind_ = ActiveLineKind::Module; + renderActiveLine(); +} + +void ProgressView::phaseChanged(std::string_view name) { + std::lock_guard lock(state_mutex_); + if (current_module_ >= modules_.size()) + return; + modules_[current_module_].phases_seen.emplace_back(name); + current_phase_ = std::string(name); + + if (!tty_) { + detail::GlobalSinkAccessor acc; + acc.writeLine(fmt::format(" phase {}: {}", modules_[current_module_].name, name)); + return; + } + + active_line_kind_ = ActiveLineKind::Module; + renderActiveLine(); +} + +void ProgressView::moduleFinished(std::chrono::milliseconds elapsed) { + std::lock_guard lock(state_mutex_); + if (current_module_ >= modules_.size()) + return; + modules_[current_module_].elapsed = elapsed; + modules_[current_module_].finished = true; + + if (!tty_) { + detail::GlobalSinkAccessor acc; + acc.writeLine(fmt::format(" done {} ({:.1f}s)", modules_[current_module_].name, + elapsed.count() / 1000.0)); + return; + } + + detail::GlobalSinkAccessor acc; + acc.writeRaw(kEraseLine); + acc.writeRaw(" "); + acc.writeColored(color::kGreen, glyphs::kCheckMark); + acc.writeRaw(" "); + acc.writeRaw(modules_[current_module_].name); + acc.writeRaw(" "); + acc.writeColored(color::kDim, fmt::format("({:.1f}s)", elapsed.count() / 1000.0)); + acc.writeRaw("\n"); + active_line_kind_ = ActiveLineKind::None; +} + +void ProgressView::projectPhaseStarted(std::string_view name) { + std::lock_guard lock(state_mutex_); + current_project_phase_ = std::string(name); + + if (!tty_) { + detail::GlobalSinkAccessor acc; + acc.writeLine(fmt::format(" start project::{}", name)); + return; + } + + active_line_kind_ = ActiveLineKind::ProjectPhase; + renderActiveLine(); +} + +void ProgressView::projectPhaseFinished() { + std::lock_guard lock(state_mutex_); + if (!tty_) { + detail::GlobalSinkAccessor acc; + acc.writeLine(" done project phase"); + return; + } + + detail::GlobalSinkAccessor acc; + acc.writeRaw(kEraseLine); + acc.writeRaw(" "); + acc.writeColored(color::kGreen, glyphs::kCheckMark); + acc.writeRaw(" "); + acc.writeRaw(fmt::format("project::{}\n", current_project_phase_)); + active_line_kind_ = ActiveLineKind::None; +} + +} // namespace rexglue::ui diff --git a/src/rexglue/ui/progress.h b/src/rexglue/ui/progress.h new file mode 100644 index 0000000..010272e --- /dev/null +++ b/src/rexglue/ui/progress.h @@ -0,0 +1,72 @@ +/** + * @file rexglue/ui/progress.h + * @brief ProgressView -- task-list renderer for codegen pipeline + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace rexglue::ui { + +/** Per-module task-list view that implements rex::codegen::ProgressReporter. */ +class ProgressView final : public rex::codegen::ProgressReporter { + public: + explicit ProgressView(std::string_view title); + ~ProgressView() override; + + ProgressView(const ProgressView&) = delete; + ProgressView& operator=(const ProgressView&) = delete; + + void moduleStarted(std::string_view name, std::size_t index, std::size_t total) override; + void phaseChanged(std::string_view name) override; + void moduleFinished(std::chrono::milliseconds elapsed) override; + void projectPhaseStarted(std::string_view name) override; + void projectPhaseFinished() override; + + private: + struct ModuleEntry { + std::string name; + std::vector phases_seen; + std::chrono::milliseconds elapsed{0}; + bool finished = false; + }; + + enum class ActiveLineKind { None, Module, ProjectPhase }; + + void renderActiveLine(); + void clearActiveLine(); + void spinnerLoop(); + + std::mutex state_mutex_; + std::string title_; + std::vector modules_; + std::size_t current_module_ = 0; + std::string current_phase_; + std::string current_project_phase_; + std::size_t spinner_frame_ = 0; + ActiveLineKind active_line_kind_ = ActiveLineKind::None; + bool tty_ = false; + + std::atomic stop_spinner_{false}; + std::condition_variable spinner_cv_; + std::thread spinner_thread_; +}; + +} // namespace rexglue::ui diff --git a/src/rexglue/ui/ui.cpp b/src/rexglue/ui/ui.cpp new file mode 100644 index 0000000..49700aa --- /dev/null +++ b/src/rexglue/ui/ui.cpp @@ -0,0 +1,348 @@ +/** + * @file rexglue/ui/ui.cpp + * @brief Presentation layer implementation + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include "ui.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef _WIN32 +#include +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#define rexglue_isatty(fd) _isatty(fd) +#define rexglue_fileno(stream) _fileno(stream) +#else +#include +#define rexglue_isatty(fd) isatty(fd) +#define rexglue_fileno(stream) fileno(stream) +#endif + +#include + +namespace rexglue::ui { + +namespace { + +std::shared_ptr g_sink_ptr; +PresentationSink* g_sink = nullptr; + +void RequireGlobalSink() { + if (!g_sink) { + throw std::logic_error("rexglue::ui not initialised; call ui::Init first"); + } +} + +bool StdinIsTty() { + return rexglue_isatty(rexglue_fileno(stdin)) != 0; +} + +std::string_view LevelLetter(spdlog::level::level_enum lvl) { + switch (lvl) { + case spdlog::level::trace: + return "T"; + case spdlog::level::debug: + return "D"; + case spdlog::level::info: + return "I"; + case spdlog::level::warn: + return "W"; + case spdlog::level::err: + return "E"; + case spdlog::level::critical: + return "C"; + default: + return "?"; + } +} + +std::string_view LevelColor(spdlog::level::level_enum lvl) { + switch (lvl) { + case spdlog::level::trace: + return color::kDim; + case spdlog::level::debug: + return color::kCyan; + case spdlog::level::info: + return color::kGreen; + case spdlog::level::warn: + return color::kBoldYellow; + case spdlog::level::err: + case spdlog::level::critical: + return color::kBoldRed; + default: + return {}; + } +} + +bool ReadYesAnswer(std::istream& in) { + std::string line; + if (!std::getline(in, line)) + return false; + std::transform(line.begin(), line.end(), line.begin(), + [](unsigned char c) { return std::tolower(c); }); + auto first = line.find_first_not_of(" \t\r\n"); + if (first == std::string::npos) + return false; + auto last = line.find_last_not_of(" \t\r\n"); + std::string trimmed = line.substr(first, last - first + 1); + return trimmed == "y" || trimmed == "yes"; +} + +} // namespace + +PresentationSink::PresentationSink(std::ostream& out, bool tty, bool color) + : out_(out), tty_(tty), color_(color) {} + +void PresentationSink::sink_it_(const spdlog::details::log_msg& msg) { + if (active_progress_ && tty_) { + out_.write("\r\033[K", 4); + } + if (tty_) { + out_.put('['); + if (color_) { + auto col = LevelColor(msg.level); + out_.write(col.data(), static_cast(col.size())); + auto letter = LevelLetter(msg.level); + out_.write(letter.data(), static_cast(letter.size())); + out_.write(color::kReset.data(), static_cast(color::kReset.size())); + } else { + auto letter = LevelLetter(msg.level); + out_.write(letter.data(), static_cast(letter.size())); + } + out_.write("] ", 2); + } + out_.write(msg.payload.data(), static_cast(msg.payload.size())); + out_.put('\n'); +} + +void PresentationSink::flush_() { + out_.flush(); +} + +void PresentationSink::setActiveProgress(bool active) { + std::lock_guard lock(this->mutex_); + active_progress_ = active; +} + +namespace detail { + +GlobalSinkAccessor::GlobalSinkAccessor() { + RequireGlobalSink(); + g_sink->sink_mutex().lock(); +} + +GlobalSinkAccessor::~GlobalSinkAccessor() { + g_sink->sink_mutex().unlock(); +} + +void GlobalSinkAccessor::writeRaw(std::string_view s) { + g_sink->sink_out().write(s.data(), static_cast(s.size())); +} + +void GlobalSinkAccessor::writeLine(std::string_view s) { + writeRaw(s); + writeRaw("\n"); +} + +void GlobalSinkAccessor::flush() { + g_sink->sink_out().flush(); +} + +bool GlobalSinkAccessor::color() const { + return g_sink->color(); +} + +void GlobalSinkAccessor::writeColored(std::string_view code, std::string_view text) { + if (g_sink->color()) { + writeRaw(code); + writeRaw(text); + writeRaw(color::kReset); + } else { + writeRaw(text); + } +} + +void SetGlobalSinkForTesting(std::unique_ptr sink) { + Shutdown(); + g_sink_ptr = std::shared_ptr(sink.release()); + g_sink = g_sink_ptr.get(); +} + +bool SinkIsTty() { + RequireGlobalSink(); + return g_sink->tty(); +} + +void SetSinkActiveProgress(bool active) { + RequireGlobalSink(); + g_sink->setActiveProgress(active); +} + +bool ConfirmWithStream(std::string_view question, std::istream& in, bool stdin_is_tty) { + { + GlobalSinkAccessor acc; + acc.writeColored(color::kBold, question); + acc.writeRaw(" "); + acc.writeColored(color::kDim, "[y/N]:"); + acc.writeRaw(" "); + acc.flush(); + } + if (!stdin_is_tty) + return false; + return ReadYesAnswer(in); +} + +} // namespace detail + +void Init(const InitOptions& opts) { + if (g_sink) + return; + g_sink_ptr = std::make_shared(std::cerr, opts.tty, opts.color); + g_sink = g_sink_ptr.get(); + rex::ReplaceConsoleSink(g_sink_ptr); + +#ifdef _WIN32 + if (opts.tty) { + SetConsoleOutputCP(CP_UTF8); + if (opts.color) { + HANDLE h = GetStdHandle(STD_ERROR_HANDLE); + DWORD mode = 0; + if (h != INVALID_HANDLE_VALUE && GetConsoleMode(h, &mode)) { + SetConsoleMode(h, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING); + } + } + } +#endif +} + +void Shutdown() { + if (!g_sink) + return; + rex::ReplaceConsoleSink(nullptr); + g_sink_ptr.reset(); + g_sink = nullptr; +} + +void Banner(std::string_view title) { + detail::GlobalSinkAccessor acc; + acc.writeColored(color::kBold, title); + acc.writeRaw("\n\n"); +} + +void KeyValueBlock(std::string_view header, std::span rows) { + detail::GlobalSinkAccessor acc; + if (!header.empty()) { + acc.writeColored(color::kBold, header); + acc.writeRaw("\n"); + } + std::size_t key_width = 0; + for (const auto& r : rows) + key_width = std::max(key_width, r.key.size()); + for (const auto& r : rows) { + acc.writeRaw(" "); + acc.writeColored(color::kCyan, r.key); + acc.writeRaw(":"); + if (key_width > r.key.size()) { + acc.writeRaw(std::string(key_width - r.key.size() + 1, ' ')); + } else { + acc.writeRaw(" "); + } + acc.writeLine(r.value); + } + acc.writeRaw("\n"); +} + +void PlanTable(std::string_view header, std::span rows) { + detail::GlobalSinkAccessor acc; + if (!header.empty()) { + acc.writeColored(color::kBold, header); + acc.writeRaw("\n"); + } + std::size_t path_width = 0; + for (const auto& r : rows) + path_width = std::max(path_width, r.path.size()); + for (const auto& r : rows) { + acc.writeRaw(" ["); + auto trimmed_action = r.action_label; + while (!trimmed_action.empty() && trimmed_action.back() == ' ') + trimmed_action.remove_suffix(1); + if (trimmed_action == "write") { + acc.writeColored(color::kGreen, r.action_label); + } else if (trimmed_action == "delete") { + acc.writeColored(color::kRed, r.action_label); + } else { + acc.writeRaw(r.action_label); + } + acc.writeRaw("] "); + acc.writeRaw(r.path); + if (!r.reason.empty()) { + if (path_width > r.path.size()) { + acc.writeRaw(std::string(path_width - r.path.size() + 2, ' ')); + } else { + acc.writeRaw(" "); + } + acc.writeColored(color::kDim, r.reason); + } + acc.writeRaw("\n"); + } + acc.writeRaw("\n"); +} + +void ManualReviewList(std::string_view header, std::span rows) { + detail::GlobalSinkAccessor acc; + if (!header.empty()) { + acc.writeColored(color::kBoldYellow, header); + acc.writeRaw("\n"); + } + for (const auto& r : rows) { + acc.writeRaw(" "); + acc.writeColored(color::kCyan, r.location); + acc.writeRaw(" "); + acc.writeLine(r.detail); + if (!r.hint.empty()) { + acc.writeRaw(" "); + acc.writeColored(color::kDim, r.hint); + acc.writeRaw("\n"); + } + } + acc.writeRaw("\n"); +} + +bool Confirm(std::string_view question) { + return detail::ConfirmWithStream(question, std::cin, StdinIsTty()); +} + +void DoneSummary(std::chrono::milliseconds elapsed) { + detail::GlobalSinkAccessor acc; + acc.writeColored(color::kBoldGreen, fmt::format("Done in {:.1f}s.", elapsed.count() / 1000.0)); + acc.writeRaw("\n"); + acc.flush(); +} + +void FailureSummary(std::string_view reason, std::chrono::milliseconds elapsed) { + detail::GlobalSinkAccessor acc; + acc.writeColored(color::kBoldRed, + fmt::format("Failed: {} (after {:.1f}s)", reason, elapsed.count() / 1000.0)); + acc.writeRaw("\n"); + acc.flush(); +} + +} // namespace rexglue::ui diff --git a/src/rexglue/ui/ui.h b/src/rexglue/ui/ui.h new file mode 100644 index 0000000..f30b41f --- /dev/null +++ b/src/rexglue/ui/ui.h @@ -0,0 +1,135 @@ +/** + * @file rexglue/ui/ui.h + * @brief Presentation layer for the rexglue CLI + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace rexglue::ui { + +namespace detail { +class GlobalSinkAccessor; +} + +/** spdlog sink that also owns direct presentation output for the rexglue CLI. */ +class PresentationSink final : public spdlog::sinks::base_sink { + public: + PresentationSink(std::ostream& out, bool tty, bool color); + + bool tty() const { return tty_; } + bool color() const { return color_; } + + void setActiveProgress(bool active); + + protected: + void sink_it_(const spdlog::details::log_msg& msg) override; + void flush_() override; + + private: + friend class detail::GlobalSinkAccessor; + + std::mutex& sink_mutex() { return this->mutex_; } + std::ostream& sink_out() { return out_; } + + std::ostream& out_; + bool tty_; + bool color_; + bool active_progress_ = false; +}; + +struct InitOptions { + bool tty; + bool color; +}; + +void Init(const InitOptions& opts); +void Shutdown(); + +void Banner(std::string_view title); + +struct KeyValueRow { + std::string_view key; + std::string value; +}; +void KeyValueBlock(std::string_view header, std::span rows); + +struct PlanRow { + std::string_view action_label; + std::string path; + std::string reason; +}; +void PlanTable(std::string_view header, std::span rows); + +struct ManualReviewRow { + std::string location; + std::string detail; + std::string hint; +}; +void ManualReviewList(std::string_view header, std::span rows); + +[[nodiscard]] bool Confirm(std::string_view question); + +void DoneSummary(std::chrono::milliseconds elapsed); +void FailureSummary(std::string_view reason, std::chrono::milliseconds elapsed); + +namespace detail { + +void SetGlobalSinkForTesting(std::unique_ptr sink); + +[[nodiscard]] bool ConfirmWithStream(std::string_view question, std::istream& in, + bool stdin_is_tty); + +bool SinkIsTty(); + +void SetSinkActiveProgress(bool active); + +/** RAII lock on the global sink's mutex for write access. */ +class GlobalSinkAccessor { + public: + GlobalSinkAccessor(); + ~GlobalSinkAccessor(); + GlobalSinkAccessor(const GlobalSinkAccessor&) = delete; + GlobalSinkAccessor& operator=(const GlobalSinkAccessor&) = delete; + + void writeLine(std::string_view s); + void writeRaw(std::string_view s); + void flush(); + + bool color() const; + + void writeColored(std::string_view code, std::string_view text); +}; + +} // namespace detail + +namespace color { +inline constexpr std::string_view kReset = "\033[0m"; +inline constexpr std::string_view kBold = "\033[1m"; +inline constexpr std::string_view kDim = "\033[2m"; +inline constexpr std::string_view kRed = "\033[31m"; +inline constexpr std::string_view kGreen = "\033[32m"; +inline constexpr std::string_view kCyan = "\033[36m"; +inline constexpr std::string_view kBoldGreen = "\033[1;32m"; +inline constexpr std::string_view kBoldRed = "\033[1;31m"; +inline constexpr std::string_view kBoldYellow = "\033[1;33m"; +} // namespace color + +} // namespace rexglue::ui diff --git a/src/system/CMakeLists.txt b/src/system/CMakeLists.txt new file mode 100644 index 0000000..4c9d2e0 --- /dev/null +++ b/src/system/CMakeLists.txt @@ -0,0 +1,101 @@ +set(REXSYSTEM_SOURCES + runtime.cpp + kernel_state.cpp + xmemory.cpp + kernel_module.cpp + user_module.cpp + xthread.cpp + xevent.cpp + xfile.cpp + xmutant.cpp + xsemaphore.cpp + xtimer.cpp + xiocompletion.cpp + xnotifylistener.cpp + xenumerator.cpp + xsocket.cpp + xsymboliclink.cpp + xobject.cpp + xmodule.cpp + shared_library.cpp + guest_path.cpp + + # Utilities + util/object_table.cpp + util/native_list.cpp + util/xdbf_utils.cpp + util/gameinfo_utils.cpp + + # XAM services + xam/app_manager.cpp + xam/content_manager.cpp + xam/user_profile.cpp + + ppc_types.cpp + elf_module.cpp + entry_table.cpp + export_resolver.cpp + lzx.cpp + mmio_handler.cpp + map_parser.cpp + module.cpp + function_dispatcher.cpp + thread.cpp + thread_state.cpp + xex_module.cpp +) + +add_library(rexruntime SHARED ${REXSYSTEM_SOURCES}) +add_library(rex::runtime ALIAS rexruntime) +add_library(rex::system ALIAS rexruntime) +add_library(rex::kernel ALIAS rexruntime) + +set_target_properties(rexruntime PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE) + +target_include_directories(rexruntime PUBLIC + $ + $ +) +target_include_directories(rexruntime PRIVATE + ${REXGLUE_ROOT}/thirdparty +) + +target_link_libraries(rexruntime + PUBLIC + simde + fmt::fmt + spdlog::spdlog + tomlplusplus + SDL3::SDL3 + PRIVATE + aes128 + mspack +) + +if(REXGLUE_ENABLE_TRACY) + target_link_libraries(rexruntime PUBLIC TracyClient) + target_compile_definitions(rexruntime PUBLIC + $<$>:REXGLUE_ENABLE_PROFILING>) +endif() + +if(REXGLUE_ENABLE_PERF_COUNTERS) + target_compile_definitions(rexruntime PUBLIC + $<$>:REXGLUE_ENABLE_PERF_COUNTERS>) +endif() + +if(WIN32) + target_link_libraries(rexruntime PRIVATE ws2_32) +endif() + +if(REXGLUE_USE_D3D12) + target_link_libraries(rexruntime PUBLIC dxgi dxguid dxc-headers) + target_compile_definitions(rexruntime PUBLIC REX_HAS_D3D12=1) +endif() +if(REXGLUE_USE_VULKAN) + target_link_libraries(rexruntime PUBLIC + volk::volk + GPUOpen::VulkanMemoryAllocator + SPIRV-Tools-static + ) + target_compile_definitions(rexruntime PUBLIC REX_HAS_VULKAN=1) +endif() diff --git a/src/system/elf_module.cpp b/src/system/elf_module.cpp new file mode 100644 index 0000000..8ca96e3 --- /dev/null +++ b/src/system/elf_module.cpp @@ -0,0 +1,172 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +namespace rex::runtime { + +ElfModule::ElfModule(FunctionDispatcher* function_dispatcher, system::KernelState* /*kernel_state*/) + : Module(function_dispatcher) {} + +ElfModule::~ElfModule() = default; + +// ELF structures +struct elf32_ehdr { + uint8_t e_ident[16]; + rex::be e_type; + rex::be e_machine; + rex::be e_version; + rex::be e_entry; + rex::be e_phoff; + rex::be e_shoff; + rex::be e_flags; + rex::be e_ehsize; + rex::be e_phentsize; + rex::be e_phnum; + rex::be e_shentsize; + rex::be e_shnum; + rex::be e_shtrndx; +}; + +struct elf32_phdr { + rex::be p_type; + rex::be p_offset; + rex::be p_vaddr; + rex::be p_paddr; + rex::be p_filesz; + rex::be p_memsz; + rex::be p_flags; + rex::be p_align; +}; + +bool ElfModule::is_executable() const { + auto hdr = reinterpret_cast(elf_header_mem_.data()); + return hdr->e_entry != 0; +} + +bool ElfModule::Load(const std::string_view name, const std::string_view path, const void* elf_addr, + size_t elf_length) { + name_ = name; + path_ = path; + (void)elf_length; + + uint8_t* pelf = (uint8_t*)elf_addr; + elf32_ehdr* hdr = (elf32_ehdr*)(pelf + 0x0); + if (hdr->e_ident[0] != 0x7F || hdr->e_ident[1] != 'E' || hdr->e_ident[2] != 'L' || + hdr->e_ident[3] != 'F') { + // Not an ELF file! + return false; + } + + assert_true(hdr->e_ident[4] == 1); // 32bit + + if (hdr->e_type != 2 /* ET_EXEC */) { + // Not executable (shared objects not supported yet) + REXLOG_ERROR("ELF: Could not load ELF because it isn't executable!"); + return false; + } + + if (hdr->e_machine != 20 /* EM_PPC */) { + // Not a PPC ELF! + REXLOG_ERROR( + "ELF: Could not load ELF because target machine is not PPC! (target: " + "{})", + uint32_t(hdr->e_machine)); + return false; + } + + // Parse LOAD program headers and load into memory. + if (!hdr->e_phoff) { + REXLOG_ERROR("ELF: File doesn't have a program header!"); + return false; + } + + if (!hdr->e_entry) { + REXLOG_ERROR("ELF: Executable has no entry point!"); + return false; + } + + // Entry point virtual address + entry_point_ = hdr->e_entry; + + // Copy the ELF header + elf_header_mem_.resize(hdr->e_ehsize); + std::memcpy(elf_header_mem_.data(), hdr, hdr->e_ehsize); + + assert_true(hdr->e_phentsize == sizeof(elf32_phdr)); + elf32_phdr* phdr = (elf32_phdr*)(pelf + hdr->e_phoff); + + // Calculate base address and image size from loaded segments + uint32_t min_addr = UINT32_MAX; + uint32_t max_addr = 0; + + for (uint32_t i = 0; i < hdr->e_phnum; i++) { + if (phdr[i].p_type == 1 /* PT_LOAD */ || phdr[i].p_type == 2 /* PT_DYNAMIC */) { + // Track address range + uint32_t seg_start = phdr[i].p_vaddr; + uint32_t seg_end = phdr[i].p_vaddr + phdr[i].p_memsz; + min_addr = std::min(min_addr, seg_start); + max_addr = std::max(max_addr, seg_end); + + // Allocate and copy into memory. + // Base address @ 0x80000000 + if (phdr[i].p_vaddr < 0x80000000 || phdr[i].p_vaddr > 0x9FFFFFFF) { + REXLOG_ERROR("ELF: Could not allocate memory for section @ address 0x{:08X}", + uint32_t(phdr[i].p_vaddr)); + return false; + } + + uint32_t virtual_addr = phdr[i].p_vaddr & ~(phdr[i].p_align - 1); + uint32_t virtual_size = + rex::round_up(phdr[i].p_vaddr + phdr[i].p_memsz, uint32_t(phdr[i].p_align)) - + virtual_addr; + if (!memory() + ->LookupHeap(virtual_addr) + ->AllocFixed( + virtual_addr, virtual_size, phdr[i].p_align, + rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite)) { + REXLOG_ERROR("ELF: Could not allocate memory!"); + } + + auto p = memory()->TranslateVirtual(phdr[i].p_vaddr); + std::memset(p, 0, phdr[i].p_memsz); + std::memcpy(p, pelf + phdr[i].p_offset, phdr[i].p_filesz); + + // crack: No JIT backend to notify about executable code + // In JIT mode this would be: processor_->backend()->CommitExecutableRange(...) + (void)virtual_addr; + (void)virtual_size; + } + } + + // Set base address and image size + base_address_ = (min_addr != UINT32_MAX) ? min_addr : 0; + image_size_ = (max_addr > min_addr) ? (max_addr - min_addr) : 0; + + loaded_ = true; + return true; +} + +bool ElfModule::Unload() { + if (!loaded_) { + return true; + } + // crack: Memory allocated for ELF segments remains - no deallocation + loaded_ = false; + return true; +} + +} // namespace rex::runtime diff --git a/src/system/entry_table.cpp b/src/system/entry_table.cpp new file mode 100644 index 0000000..d8b05db --- /dev/null +++ b/src/system/entry_table.cpp @@ -0,0 +1,91 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +namespace rex::runtime { + +EntryTable::EntryTable() = default; + +EntryTable::~EntryTable() { + auto global_lock = global_critical_region_.Acquire(); + for (auto it : map_) { + Entry* entry = it.second; + delete entry; + } +} + +Entry* EntryTable::Get(uint32_t address) { + auto global_lock = global_critical_region_.Acquire(); + const auto& it = map_.find(address); + Entry* entry = it != map_.end() ? it->second : nullptr; + if (entry) { + // TODO(benvanik): wait if needed? + if (entry->status != Entry::STATUS_READY) { + entry = nullptr; + } + } + return entry; +} + +Entry::Status EntryTable::GetOrCreate(uint32_t address, Entry** out_entry) { + // TODO(benvanik): replace with a map with wait-free for find. + // https://github.com/facebook/folly/blob/master/folly/AtomicHashMap.h + + auto global_lock = global_critical_region_.Acquire(); + const auto& it = map_.find(address); + Entry* entry = it != map_.end() ? it->second : nullptr; + Entry::Status status; + if (entry) { + // If we aren't ready yet spin and wait. + if (entry->status == Entry::STATUS_COMPILING) { + // Still compiling, so spin. + do { + global_lock.unlock(); + // TODO(benvanik): sleep for less time? + rex::thread::Sleep(std::chrono::microseconds(10)); + global_lock.lock(); + } while (entry->status == Entry::STATUS_COMPILING); + } + status = entry->status; + } else { + // Create and return for initialization. + entry = new Entry(); + entry->address = address; + entry->end_address = 0; + entry->status = Entry::STATUS_COMPILING; + entry->function = 0; + map_[address] = entry; + status = Entry::STATUS_NEW; + } + global_lock.unlock(); + *out_entry = entry; + return status; +} + +std::vector EntryTable::FindWithAddress(uint32_t address) { + auto global_lock = global_critical_region_.Acquire(); + std::vector fns; + for (auto& it : map_) { + Entry* entry = it.second; + if (address >= entry->address && address <= entry->end_address) { + if (entry->status == Entry::STATUS_READY) { + fns.push_back(entry->function); + } + } + } + return fns; +} + +} // namespace rex::runtime +// (removed orphan xe namespace) diff --git a/src/system/export_resolver.cpp b/src/system/export_resolver.cpp new file mode 100644 index 0000000..59996b3 --- /dev/null +++ b/src/system/export_resolver.cpp @@ -0,0 +1,74 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +namespace rex::runtime { + +ExportResolver::Table::Table(const std::string_view module_name, + const std::vector* exports_by_ordinal) + : exports_by_ordinal_(exports_by_ordinal) { + module_name_ = rex::string::utf8_find_base_name_from_guest_path(module_name); + + exports_by_name_.reserve(exports_by_ordinal_->size()); + for (size_t i = 0; i < exports_by_ordinal_->size(); ++i) { + auto export_entry = exports_by_ordinal_->at(i); + if (export_entry) { + exports_by_name_.push_back(export_entry); + } + } + std::sort(exports_by_name_.begin(), exports_by_name_.end(), + [](Export* a, Export* b) { return std::strcmp(a->name, b->name) < 0; }); +} + +ExportResolver::ExportResolver() = default; + +ExportResolver::~ExportResolver() = default; + +void ExportResolver::RegisterTable(const std::string_view module_name, + const std::vector* exports) { + tables_.emplace_back(module_name, exports); + + all_exports_by_name_.reserve(all_exports_by_name_.size() + exports->size()); + for (size_t i = 0; i < exports->size(); ++i) { + auto export_entry = exports->at(i); + if (export_entry) { + all_exports_by_name_.push_back(export_entry); + } + } + std::sort(all_exports_by_name_.begin(), all_exports_by_name_.end(), + [](Export* a, Export* b) { return std::strcmp(a->name, b->name) < 0; }); +} + +Export* ExportResolver::GetExportByOrdinal(const std::string_view module_name, uint16_t ordinal) { + for (const auto& table : tables_) { + if (rex::string::utf8_starts_with_case(module_name, table.module_name())) { + if (ordinal >= table.exports_by_ordinal().size()) { + return nullptr; + } + return table.exports_by_ordinal().at(ordinal); + } + } + return nullptr; +} + +void ExportResolver::SetVariableMapping(const std::string_view module_name, uint16_t ordinal, + uint32_t value) { + auto export_entry = GetExportByOrdinal(module_name, ordinal); + assert_not_null(export_entry); + export_entry->tags |= ExportTag::kImplemented; + export_entry->variable_ptr = value; +} + +} // namespace rex::runtime diff --git a/src/system/function_dispatcher.cpp b/src/system/function_dispatcher.cpp new file mode 100644 index 0000000..67f7070 --- /dev/null +++ b/src/system/function_dispatcher.cpp @@ -0,0 +1,388 @@ +/** + * @file system/function_dispatcher.cpp + * @brief Guest function dispatch coordinator for recompiled code + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + * + * @remarks Derived from Xenia's runtime::Processor (Ben Vanik, 2020). + * Stripped of emulation-era dead code and renamed to reflect its + * role as a function dispatch table rather than a CPU emulator. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::runtime { + +namespace { + +FunctionDispatcher* GetBoundFunctionDispatcher() { + Runtime* runtime = Runtime::instance(); + return runtime ? runtime->function_dispatcher() : nullptr; +} + +} // namespace + +static void InvalidFunctionTrap(PPCContext& ctx, uint8_t* /*base*/) { + REX_FATAL("Call to invalid or unregistered function at guest address 0x{:08X}", + ctx.last_indirect_target); +} + +PPCFunc* ResolveIndirectFunction(uint32_t guest_address) { + FunctionDispatcher* dispatcher = GetBoundFunctionDispatcher(); + if (!dispatcher) { + return &InvalidFunctionTrap; + } + + if (PPCFunc* func = dispatcher->GetFunction(guest_address)) { + return func; + } + + return &InvalidFunctionTrap; +} + +FunctionDispatcher::FunctionDispatcher(rex::memory::Memory* memory, ExportResolver* export_resolver) + : memory_(memory), export_resolver_(export_resolver) {} + +FunctionDispatcher::~FunctionDispatcher() = default; + +bool FunctionDispatcher::Execute(ThreadState* thread_state, uint32_t address) { + SCOPE_profile_cpu_f("cpu"); + PROFILE_FUNCTION_DISPATCHED(); + + PPCFunc* fn = GetFunction(address); + if (!fn) { + REXCPU_ERROR("Execute({:08X}): function not in function table", address); + return false; + } + + auto* ctx = thread_state->context(); + auto* previous_thread_state = ThreadState::Get(); + + // Rebind the active guest thread for cross-module callbacks. + ThreadState::Bind(thread_state); + + // Pad out stack a bit, as some games seem to overwrite the caller by about 16 to 32b. + ctx->r1.u64 -= 64 + 112; + + uint64_t previous_lr = ctx->lr; + ctx->lr = 0xBCBCBCBC; + + fn(*ctx, memory_->virtual_membase()); + + ctx->lr = previous_lr; + ctx->r1.u64 += 64 + 112; + ThreadState::Bind(previous_thread_state); + + return true; +} + +uint64_t FunctionDispatcher::Execute(ThreadState* thread_state, uint32_t address, uint64_t args[], + size_t arg_count) { + SCOPE_profile_cpu_f("cpu"); + + auto* ctx = thread_state->context(); + + if (arg_count > 0) + ctx->r3.u64 = args[0]; + if (arg_count > 1) + ctx->r4.u64 = args[1]; + if (arg_count > 2) + ctx->r5.u64 = args[2]; + if (arg_count > 3) + ctx->r6.u64 = args[3]; + if (arg_count > 4) + ctx->r7.u64 = args[4]; + if (arg_count > 5) + ctx->r8.u64 = args[5]; + if (arg_count > 6) + ctx->r9.u64 = args[6]; + if (arg_count > 7) + ctx->r10.u64 = args[7]; + + // FIXME: stack-arg path assumes 32-bit values; 64-bit and float args are wrong. + if (arg_count > 8) { + auto stack_arg_base = + memory_->TranslateVirtual(static_cast(ctx->r1.u64) + 0x54 - (64 + 112)); + for (size_t i = 8; i < arg_count; i++) { + memory::store_and_swap(stack_arg_base + ((i - 8) * 8), + static_cast(args[i])); + } + } + + if (!Execute(thread_state, address)) { + return 0xDEADBABE; + } + return ctx->r3.u64; +} + +uint64_t FunctionDispatcher::ExecuteInterrupt(ThreadState* thread_state, uint32_t address, + uint64_t args[], size_t arg_count) { + SCOPE_profile_cpu_f("cpu"); + PROFILE_INTERRUPT_DISPATCHED(); + + // Hold the global lock during interrupt dispatch. + auto global_lock = global_critical_region_.Acquire(); + + auto* ctx = thread_state->context(); + assert_true(arg_count <= 5); + + if (arg_count > 0) + ctx->r3.u64 = args[0]; + if (arg_count > 1) + ctx->r4.u64 = args[1]; + if (arg_count > 2) + ctx->r5.u64 = args[2]; + if (arg_count > 3) + ctx->r6.u64 = args[3]; + if (arg_count > 4) + ctx->r7.u64 = args[4]; + + // TLS ptr must be zero during interrupts. Some games check this and early-exit + // routines when under interrupts. + auto pcr_address = memory_->TranslateVirtual(static_cast(ctx->r13.u64)); + uint32_t old_tls_ptr = memory::load_and_swap(pcr_address); + memory::store_and_swap(pcr_address, 0); + + if (!Execute(thread_state, address)) { + return 0xDEADBABE; + } + + // Restore TLS ptr. + memory::store_and_swap(pcr_address, old_tls_ptr); + + return ctx->r3.u64; +} + +// rexglue function table management + +bool FunctionDispatcher::InitializeFunctionTable(uint32_t code_base, uint32_t code_size, + uint32_t image_base, uint32_t image_size, + bool is_entrypoint) { + std::lock_guard lock(dispatch_mutex_); + + if (is_entrypoint && entrypoint_code_base_ != 0) { + REXLOG_ERROR("InitializeFunctionTable: entrypoint already registered at {:08X}", + entrypoint_code_base_); + return false; + } + + uint32_t new_table_end = image_base + image_size + (code_size + kThunkReserveSize) * 2; + uint32_t new_code_end = code_base + code_size + kThunkReserveSize; + for (const auto& existing : module_tables_) { + uint32_t existing_table_end = + existing.image_base + existing.image_size + (existing.code_size + kThunkReserveSize) * 2; + uint32_t existing_code_end = existing.code_base + existing.code_size + kThunkReserveSize; + if (image_base < existing_table_end && new_table_end > existing.image_base) { + REXLOG_ERROR("Module image range [{:08X}, {:08X}) overlaps existing [{:08X}, {:08X})", + image_base, new_table_end, existing.image_base, existing_table_end); + return false; + } + if (code_base < existing_code_end && new_code_end > existing.code_base) { + REXLOG_ERROR("Module code range [{:08X}, {:08X}) overlaps existing [{:08X}, {:08X})", + code_base, new_code_end, existing.code_base, existing_code_end); + return false; + } + } + + if (!memory_->InitializeFunctionTable(code_base, code_size, image_base, image_size)) { + REXLOG_ERROR("Failed to initialize guest memory function table"); + return false; + } + + module_tables_.push_back({ + .code_base = code_base, + .code_size = code_size, + .image_base = image_base, + .image_size = image_size, + .next_thunk_address = code_base + code_size, + .thunk_limit = code_base + code_size + kThunkReserveSize, + }); + + if (is_entrypoint) { + entrypoint_code_base_ = code_base; + } + + REXLOG_INFO("Function table initialized for module: code={:08X}-{:08X}, image={:08X}-{:08X}", + code_base, code_base + code_size, image_base, image_base + image_size); + return true; +} + +FunctionDispatcher::ModuleTableInfo* FunctionDispatcher::FindModuleByAddress( + uint32_t guest_address) { + for (auto& mod : module_tables_) { + if (guest_address >= mod.code_base && guest_address < mod.thunk_limit) { + return &mod; + } + } + return nullptr; +} + +uint32_t FunctionDispatcher::FindCallerModuleBase(uint32_t guest_address) { + std::lock_guard lock(dispatch_mutex_); + if (auto* mod = FindModuleByAddress(guest_address)) { + return mod->code_base; + } + return 0; +} + +bool FunctionDispatcher::SetFunction(uint32_t guest_address, ::PPCFunc* func) { + std::lock_guard lock(dispatch_mutex_); + assert_true(!module_tables_.empty()); + + if (!FindModuleByAddress(guest_address)) { + REXLOG_ERROR("SetFunction: address {:08X} outside all registered module ranges", guest_address); + return false; + } + + function_table_[guest_address] = func; + + if (!memory_->SetFunction(guest_address, func)) { + REXLOG_ERROR("SetFunction: dispatcher / Memory module-table state out of sync at {:08X}", + guest_address); + function_table_.erase(guest_address); + return false; + } + + if (recording_) { + recording_addresses_.push_back(guest_address); + } + return true; +} + +::PPCFunc* FunctionDispatcher::GetFunction(uint32_t guest_address) { + std::lock_guard lock(dispatch_mutex_); + auto it = function_table_.find(guest_address); + if (it != function_table_.end()) { + return it->second; + } + return nullptr; +} + +uint32_t FunctionDispatcher::AllocateThunk(::PPCFunc* func, uint32_t caller_address) { + std::lock_guard lock(dispatch_mutex_); + auto* mod = FindModuleByAddress(caller_address); + if (!mod) { + if (caller_address != 0) { + REXLOG_ERROR("AllocateThunk: caller_address {:08X} not in any registered module", + caller_address); + return 0; + } + if (entrypoint_code_base_ == 0) { + REXLOG_ERROR("AllocateThunk: caller_address=0 but no entrypoint registered"); + return 0; + } + mod = FindModuleByAddress(entrypoint_code_base_); + if (!mod) { + REXLOG_ERROR("AllocateThunk: entrypoint code_base {:08X} not in module_tables_", + entrypoint_code_base_); + return 0; + } + } + + if (mod->next_thunk_address >= mod->thunk_limit) { + REXLOG_ERROR("Thunk address space exhausted for module at {:08X}", mod->code_base); + return 0; + } + uint32_t addr = mod->next_thunk_address; + mod->next_thunk_address += 4; + if (!SetFunction(addr, func)) { + mod->next_thunk_address -= 4; + return 0; + } + return addr; +} + +void FunctionDispatcher::RegisterModule(const std::string& module_id, uint32_t code_base, + RegisterFn register_func) { + std::lock_guard lock(dispatch_mutex_); + if (recording_) { + REX_FATAL("RegisterModule called while already recording (re-entrancy)"); + return; + } + + if (module_addresses_.find(module_id) != module_addresses_.end()) { + REXLOG_WARN("RegisterModule: '{}' is already registered; cleaning up prior batch", module_id); + UnregisterModule(module_id); + } + + REXLOG_INFO("Registering module: {} (code_base={:08X})", module_id, code_base); + + recording_addresses_.clear(); + recording_ = true; + + struct RecordingGuard { + FunctionDispatcher* self; + ~RecordingGuard() { + self->recording_ = false; + self->recording_addresses_.clear(); + } + } guard{this}; + + register_func(this); + + ModuleRegistration reg; + reg.code_base = code_base; + reg.addresses = std::move(recording_addresses_); + + size_t count = reg.addresses.size(); + module_addresses_[module_id] = std::move(reg); + + REXLOG_INFO("Module '{}' registered {} functions", module_id, count); +} + +std::optional> FunctionDispatcher::UnregisterModule( + const std::string& module_id) { + std::lock_guard lock(dispatch_mutex_); + auto it = module_addresses_.find(module_id); + if (it == module_addresses_.end()) { + REXLOG_WARN("UnregisterModule: module '{}' not found", module_id); + return std::nullopt; + } + + REXLOG_INFO("Unregistering module: {} ({} functions)", module_id, it->second.addresses.size()); + + auto table_it = std::find_if(module_tables_.begin(), module_tables_.end(), + [code_base = it->second.code_base](const ModuleTableInfo& mti) { + return mti.code_base == code_base; + }); + + for (uint32_t addr : it->second.addresses) { + function_table_.erase(addr); + memory_->SetFunction(addr, nullptr); + } + + std::optional> cleared_range; + if (table_it != module_tables_.end()) { + uint32_t pool_start = table_it->code_base + table_it->code_size; + uint32_t pool_end = table_it->next_thunk_address; + for (uint32_t addr = pool_start; addr < pool_end; addr += 4) { + function_table_.erase(addr); + memory_->SetFunction(addr, nullptr); + } + cleared_range = std::make_pair(pool_start, pool_end); + + if (table_it->code_base == entrypoint_code_base_) { + entrypoint_code_base_ = 0; + } + memory_->DestroyFunctionTable(table_it->code_base); + module_tables_.erase(table_it); + } + + module_addresses_.erase(it); + + return cleared_range; +} + +} // namespace rex::runtime diff --git a/src/system/guest_path.cpp b/src/system/guest_path.cpp new file mode 100644 index 0000000..25a5d14 --- /dev/null +++ b/src/system/guest_path.cpp @@ -0,0 +1,44 @@ +/** + * @file system/guest_path.cpp + * @brief Guest path normalization for Xbox 360 VFS paths + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include + +#include +#include + +#include + +namespace rex::system { + +std::string NormalizeGuestPath(std::string_view path) { + // Manifest / config consumers expect POSIX-style guest paths: forward + // slashes, no device prefix, lowercase. The runtime VFS tolerates either + // separator, so converting backslashes here keeps writers (TOML) happy. + std::string result = rex::string::utf8_fix_path_separators(path, U'/'); + + auto colon = result.find(':'); + if (colon != std::string::npos && colon + 1 < result.size() && result[colon + 1] == '/') { + result.erase(0, colon + 2); + } + + result = rex::string::utf8_canonicalize_path(result, U'/'); + + while (!result.empty() && result.front() == '/') { + result.erase(result.begin()); + } + + std::transform(result.begin(), result.end(), result.begin(), + [](unsigned char c) { return static_cast(std::tolower(c)); }); + + return result; +} + +} // namespace rex::system diff --git a/src/system/kernel_module.cpp b/src/system/kernel_module.cpp new file mode 100644 index 0000000..1dc45d1 --- /dev/null +++ b/src/system/kernel_module.cpp @@ -0,0 +1,103 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include + +namespace rex::system { + +KernelModule::KernelModule(KernelState* kernel_state, const std::string_view path) + : XModule(kernel_state, ModuleType::kKernelModule) { + emulator_ = kernel_state->emulator(); + memory_ = emulator_->memory(); + export_resolver_ = kernel_state->emulator()->export_resolver(); + + path_ = path; + name_ = rex::string::utf8_find_base_name_from_guest_path(path); + + // Persist this object through reloads. + host_object_ = true; + + OnLoad(); +} + +KernelModule::~KernelModule() {} + +uint32_t KernelModule::GetProcAddressByOrdinal(uint16_t ordinal, uint32_t caller_address) { + // Look up the export in the resolver + auto export_entry = export_resolver_->GetExportByOrdinal(name_, ordinal); + if (!export_entry) { + REXSYS_DEBUG("GetProcAddressByOrdinal: ordinal {:04X} not found in {}", ordinal, name_); + return 0; + } + + if (export_entry->type == rex::runtime::Export::Type::kVariable) { + // Variables have guest addresses we can return directly + REXSYS_DEBUG("GetProcAddressByOrdinal: {} ({:04X}) -> variable at {:08X}", export_entry->name, + ordinal, export_entry->variable_ptr); + return export_entry->variable_ptr; + } + + auto* dispatcher = emulator_->function_dispatcher(); + uint32_t caller_module_base = dispatcher->FindCallerModuleBase(caller_address); + ThunkKey key{caller_module_base, ordinal}; + + // Check thunk cache first (already allocated for this caller's module) + auto thunk_it = thunk_cache_.find(key); + if (thunk_it != thunk_cache_.end()) { + REXSYS_DEBUG("GetProcAddressByOrdinal: {} ({:04X}) in {} -> cached thunk {:08X}", + export_entry->name, ordinal, name_, thunk_it->second); + return thunk_it->second; + } + + // Look up native implementation by name from the auto-registry + std::string imp_name = std::string("__imp__") + export_entry->name; + REXSYS_DEBUG("GetProcAddressByOrdinal: searching registry for '{}'", imp_name); + PPCFunc* func = rex::ppc::FindPPCFuncByName(imp_name.c_str()); + if (func) { + uint32_t thunk_addr = dispatcher->AllocateThunk(func, caller_address); + if (thunk_addr) { + thunk_cache_[key] = thunk_addr; + REXSYS_INFO("GetProcAddressByOrdinal: {} ({:04X}) in {} -> thunk at {:08X}", + export_entry->name, ordinal, name_, thunk_addr); + return thunk_addr; + } + } + + // No native implementation available + REXSYS_WARN("GetProcAddressByOrdinal: function {} ({:04X}) in {} - no native implementation", + export_entry->name, ordinal, name_); + return 0; +} + +uint32_t KernelModule::GetProcAddressByName(const std::string_view name) { + // TODO: Does this even work for kernel modules? + (void)name; + REXSYS_ERROR("KernelModule::GetProcAddressByName not implemented"); + return 0; +} + +void KernelModule::InvalidateThunkCacheInRange(uint32_t lo, uint32_t hi) { + for (auto it = thunk_cache_.begin(); it != thunk_cache_.end();) { + if (it->second >= lo && it->second < hi) { + it = thunk_cache_.erase(it); + } else { + ++it; + } + } +} + +} // namespace rex::system diff --git a/src/system/kernel_state.cpp b/src/system/kernel_state.cpp new file mode 100644 index 0000000..6e14ffe --- /dev/null +++ b/src/system/kernel_state.cpp @@ -0,0 +1,1244 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::system { + +constexpr uint32_t kDeferredOverlappedDelayMillis = 100; + +// This is a global object initialized with the XboxkrnlModule. +// It references the current kernel state object that all kernel methods should +// be using to stash their variables. +KernelState* shared_kernel_state_ = nullptr; + +KernelState* kernel_state() { + return shared_kernel_state_; +} + +KernelState::KernelState(Runtime* emulator) + : emulator_(emulator), + memory_(emulator->memory()), + dispatch_thread_running_(false), + dpc_list_(emulator->memory()) { + function_dispatcher_ = emulator->function_dispatcher(); + file_system_ = emulator->file_system(); + + app_manager_ = std::make_unique(); + user_profile_ = std::make_unique(); + user_profile_->set_kernel_state(this); + + auto user_data_root = emulator_->user_data_root(); + if (!user_data_root.empty()) { + user_data_root = std::filesystem::absolute(user_data_root); + } + content_manager_ = std::make_unique(this, user_data_root); + + if (shared_kernel_state_ != nullptr) { + REXSYS_ERROR("KernelState constructed but shared_kernel_state_ already set"); + rex::FatalError("Double initialization of KernelState"); + } + shared_kernel_state_ = this; + + // Allocate KernelGuestGlobals early so xboxkrnl module can wire exports. + kernel_guest_globals_ = memory_->SystemHeapAlloc(sizeof(KernelGuestGlobals)); + auto globals = memory_->TranslateVirtual(kernel_guest_globals_); + std::memset(globals, 0, sizeof(KernelGuestGlobals)); + + // Initialize object type pool tags + globals->ExThreadObjectType.pool_tag = memory::make_fourcc('T', 'h', 'r', 'd'); + globals->ExEventObjectType.pool_tag = memory::make_fourcc('E', 'v', 'n', 't'); + globals->ExMutantObjectType.pool_tag = memory::make_fourcc('M', 'u', 't', 'a'); + globals->ExSemaphoreObjectType.pool_tag = memory::make_fourcc('S', 'e', 'm', 'a'); + globals->ExTimerObjectType.pool_tag = memory::make_fourcc('T', 'i', 'm', 'r'); + globals->IoCompletionObjectType.pool_tag = memory::make_fourcc('I', 'o', 'C', 'p'); + globals->IoDeviceObjectType.pool_tag = memory::make_fourcc('I', 'o', 'D', 'v'); + globals->IoFileObjectType.pool_tag = memory::make_fourcc('I', 'o', 'F', 'l'); + globals->ObDirectoryObjectType.pool_tag = memory::make_fourcc('O', 'b', 'D', 'r'); + globals->ObSymbolicLinkObjectType.pool_tag = memory::make_fourcc('O', 'b', 'S', 'l'); + + // Initialize UsbdBootEnumerationDoneEvent as a signaled manual-reset event + auto* usbd_event = reinterpret_cast(&globals->UsbdBootEnumerationDoneEvent); + usbd_event->type = 1; // NotificationEvent + usbd_event->signal_state = 1; + + // Initialize OddObj self-referencing pointer + uint32_t oddobject_offset = kernel_guest_globals_ + offsetof(KernelGuestGlobals, OddObj); + globals->OddObj.field0 = 0x1000000; + globals->OddObj.field4 = 1; + globals->OddObj.points_to_self = + oddobject_offset + offsetof(X_UNKNOWN_TYPE_REFED, points_to_self); + globals->OddObj.points_to_prior = globals->OddObj.points_to_self; + + // Initialize process structs + InitializeProcess(&globals->idle_process, X_PROCTYPE_IDLE, 0, 0, 0); + globals->idle_process.quantum = 0x7F; + + InitializeProcess(&globals->system_process, X_PROCTYPE_SYSTEM, 2, 5, 9); + SetProcessTLSVars(&globals->system_process, 32, 0, 0); + + // Title process needs minimal initialization here so threads created before + // SetExecutableModule() (e.g. XMA decoder) can link into its thread_list. + // SetExecutableModule() will re-initialize it fully with XEX header values. + InitializeProcess(&globals->title_process, X_PROCTYPE_USER, 0, 0, 0); +} + +void KernelState::InitializeProcess(X_KPROCESS* process, uint32_t process_type, uint8_t unk_18, + uint8_t unk_19, uint8_t unk_1A) { + process->unk_18 = unk_18; + process->unk_19 = unk_19; + process->unk_1A = unk_1A; + process->unk_1B = 0x06; + process->quantum = 60; + process->clrdataa_masked_ptr = 0; + process->thread_count = 0; + process->kernel_stack_size = 16 * 1024; + process->tls_slot_size = 0x80; + process->process_type = static_cast(process_type); + util::XeInitializeListHead(&process->thread_list, memory_); + util::XeInitializeListHead(&process->unk_54, memory_); +} + +void KernelState::SetProcessTLSVars(X_KPROCESS* process, uint32_t num_slots, uint32_t tls_data_size, + uint32_t tls_raw_data_address) { + uint32_t slots_padded = (num_slots + 3) & ~uint32_t(3); + process->tls_slot_size = static_cast(4 * slots_padded); + process->tls_static_data_address = tls_raw_data_address; + + // Initialize TLS bitmap - mark used slots with 1s in HIGH bits (matching xenia). + // Xenia formula: bitmap[count_div32] = -1 << (32 - ((num_slots + 3) & 0x1C)) + uint32_t bitmap_slots = slots_padded / 32; + for (uint32_t i = 0; i < 8; i++) { + if (i < bitmap_slots) { + process->tls_slot_bitmap[i] = 0xFFFFFFFF; + } else if (i == bitmap_slots) { + uint32_t remaining = slots_padded % 32; + process->tls_slot_bitmap[i] = remaining ? ~0u << (32 - remaining) : 0; + } else { + process->tls_slot_bitmap[i] = 0; + } + } +} + +KernelState::~KernelState() { + app_manager_.reset(); + + // Stop the dispatch thread before touching the object table + if (dispatch_thread_running_) { + dispatch_thread_running_ = false; + dispatch_cond_.notify_all(); + dispatch_thread_->Wait(0, 0, 0, nullptr); + } + + // Unload through UnloadUserModule so the recompiled-DLL teardown runs. + // call_entry=false because guest DllMain is unsafe at shutdown. + while (!user_modules_.empty()) { + object_ref module = user_modules_.back(); + UnloadUserModule(module, /*call_entry=*/false); + } + executable_module_.reset(); + kernel_modules_.clear(); + if (!module_libraries_.empty()) { + REXSYS_ERROR("~KernelState: {} recompiled libraries still loaded after module sweep", + module_libraries_.size()); + module_libraries_.clear(); + } + + // Unregister all notify listeners. + notify_listeners_.clear(); + + // Safe to reset now: Runtime::Shutdown() has already stopped graphics, + // audio, and input before destroying KernelState. + object_table_.Reset(); + + // Destroy any host fibers that were not explicitly cleaned up. + for (auto& [guest_addr, info] : fiber_map_) { + if (info.host_fiber) { + info.host_fiber->Destroy(); + } + if (!info.is_thread_fiber && info.guest_stack_bottom) { + memory_->LookupHeap(0x70000000)->Release(info.guest_stack_bottom); + } + if (info.guest_context_addr) { + memory_->SystemHeapFree(info.guest_context_addr); + } + } + fiber_map_.clear(); + + if (kernel_guest_globals_) { + memory_->SystemHeapFree(kernel_guest_globals_); + kernel_guest_globals_ = 0; + } + + if (shared_kernel_state_ == this) { + shared_kernel_state_ = nullptr; + } else { + REXSYS_ERROR("~KernelState: shared_kernel_state_ does not match this instance"); + } + + // Drain last: FreeLibrary runs the DLL's host static dtors. + deferred_unload_libraries_.clear(); +} + +KernelState* KernelState::shared() { + return shared_kernel_state_; +} + +uint32_t KernelState::title_id() const { + assert_not_null(executable_module_); + + xex2_opt_execution_info* exec_info = 0; + executable_module_->GetOptHeader(XEX_HEADER_EXECUTION_INFO, &exec_info); + + if (exec_info) { + return exec_info->title_id; + } + + return 0; +} + +util::XdbfGameData KernelState::title_xdbf() const { + return module_xdbf(executable_module_); +} + +util::XdbfGameData KernelState::module_xdbf(object_ref exec_module) const { + assert_not_null(exec_module); + + uint32_t resource_data = 0; + uint32_t resource_size = 0; + if (XSUCCEEDED(exec_module->GetSection(fmt::format("{:08X}", exec_module->title_id()).c_str(), + &resource_data, &resource_size))) { + util::XdbfGameData db(memory()->TranslateVirtual(resource_data), resource_size); + return db; + } + return util::XdbfGameData(nullptr, resource_size); +} + +uint32_t KernelState::process_type() const { + auto globals = memory_->TranslateVirtual(kernel_guest_globals_); + return globals->title_process.process_type; +} + +void KernelState::set_process_type(uint32_t value) { + auto globals = memory_->TranslateVirtual(kernel_guest_globals_); + globals->title_process.process_type = uint8_t(value); +} + +uint32_t KernelState::AllocateTLS(PPCContext* context) { + if (!context) { + REXSYS_ERROR("AllocateTLS: null PPCContext"); + return X_TLS_OUT_OF_INDEXES; + } + + auto globals = memory()->TranslateVirtual(GetKernelGuestGlobals()); + auto tls_lock = &globals->tls_lock; + auto old_irql = kernel::xboxkrnl::xeKeKfAcquireSpinLock(context, tls_lock); + + uint32_t result = X_TLS_OUT_OF_INDEXES; + + auto current_thread = XThread::GetCurrentThread(); + if (!current_thread) { + REXSYS_ERROR("AllocateTLS: no current thread"); + kernel::xboxkrnl::xeKeKfReleaseSpinLock(context, tls_lock, old_irql); + return X_TLS_OUT_OF_INDEXES; + } + + auto process_ptr = memory()->TranslateVirtual( + static_cast(current_thread->guest_object()->process)); + if (!process_ptr) { + REXSYS_ERROR("AllocateTLS: failed to resolve current process"); + kernel::xboxkrnl::xeKeKfReleaseSpinLock(context, tls_lock, old_irql); + return X_TLS_OUT_OF_INDEXES; + } + + for (uint32_t bitmap_index = 0; bitmap_index < 8; ++bitmap_index) { + uint32_t bitmap_value = static_cast(process_ptr->tls_slot_bitmap[bitmap_index]); + uint32_t leading_zeros = rex::lzcnt(bitmap_value); + if (leading_zeros == 32) { + continue; + } + + uint32_t slot = bitmap_index * 32 + leading_zeros; + if (slot >= 256) { + continue; + } + + uint32_t bit_index = 31 - leading_zeros; + process_ptr->tls_slot_bitmap[bitmap_index] = bitmap_value & ~(1U << bit_index); + result = slot; + break; + } + + kernel::xboxkrnl::xeKeKfReleaseSpinLock(context, tls_lock, old_irql); + return result; +} + +void KernelState::FreeTLS(PPCContext* context, uint32_t slot) { + if (!context) { + REXSYS_ERROR("FreeTLS: null PPCContext"); + return; + } + if (slot >= 256) { + REXSYS_WARN("FreeTLS: invalid TLS slot {}", slot); + return; + } + + auto current_thread = XThread::GetCurrentThread(); + if (!current_thread) { + REXSYS_ERROR("FreeTLS: no current thread"); + return; + } + + auto current_kthread = current_thread->guest_object(); + if (!current_kthread) { + REXSYS_ERROR("FreeTLS: failed to resolve current KTHREAD"); + return; + } + + auto process_ptr = + memory()->TranslateVirtual(static_cast(current_kthread->process)); + if (!process_ptr) { + REXSYS_ERROR("FreeTLS: failed to resolve current process"); + return; + } + + auto globals = memory()->TranslateVirtual(GetKernelGuestGlobals()); + auto tls_lock = &globals->tls_lock; + auto old_irql = kernel::xboxkrnl::xeKeKfAcquireSpinLock(context, tls_lock); + + uint32_t bitmap_index = slot / 32; + uint32_t bit_mask = 1U << (31 - (slot % 32)); + uint32_t bitmap_value = static_cast(process_ptr->tls_slot_bitmap[bitmap_index]); + + if (bitmap_value & bit_mask) { + REXSYS_WARN("FreeTLS: slot {} already free", slot); + kernel::xboxkrnl::xeKeKfReleaseSpinLock(context, tls_lock, old_irql); + return; + } + + const std::vector> threads = object_table()->GetObjectsByType(); + uint32_t current_process_ptr = static_cast(current_kthread->process); + + for (const object_ref& thread : threads) { + if (!thread || !thread->is_guest_thread()) { + continue; + } + auto thread_kthread = thread->guest_object(); + if (thread_kthread && static_cast(thread_kthread->process) == current_process_ptr) { + thread->SetTLSValue(slot, 0); + } + } + + process_ptr->tls_slot_bitmap[bitmap_index] = bitmap_value | bit_mask; + + kernel::xboxkrnl::xeKeKfReleaseSpinLock(context, tls_lock, old_irql); +} + +void KernelState::RegisterTitleTerminateNotification(uint32_t routine, uint32_t priority) { + TerminateNotification notify; + notify.guest_routine = routine; + notify.priority = priority; + + terminate_notifications_.push_back(notify); +} + +void KernelState::RemoveTitleTerminateNotification(uint32_t routine) { + for (auto it = terminate_notifications_.begin(); it != terminate_notifications_.end(); it++) { + if (it->guest_routine == routine) { + terminate_notifications_.erase(it); + break; + } + } +} + +void KernelState::RegisterModule(XModule* module) {} + +void KernelState::UnregisterModule(XModule* module) {} + +bool KernelState::RegisterUserModule(object_ref module) { + auto lock = global_critical_region_.Acquire(); + + for (auto user_module : user_modules_) { + if (user_module->path() == module->path()) { + // Already loaded. + return false; + } + } + + user_modules_.push_back(module); + return true; +} + +void KernelState::UnregisterUserModule(UserModule* module) { + auto lock = global_critical_region_.Acquire(); + + for (auto it = user_modules_.begin(); it != user_modules_.end(); it++) { + if ((*it)->path() == module->path()) { + user_modules_.erase(it); + return; + } + } +} + +bool KernelState::IsKernelModule(const std::string_view name) { + if (name.empty()) { + // Executing module isn't a kernel module. + return false; + } + // NOTE: no global lock required as the kernel module list is static. + for (auto kernel_module : kernel_modules_) { + if (kernel_module->Matches(name)) { + return true; + } + } + return false; +} + +object_ref KernelState::GetKernelModule(const std::string_view name) { + assert_true(IsKernelModule(name)); + + for (auto kernel_module : kernel_modules_) { + if (kernel_module->Matches(name)) { + return retain_object(kernel_module.get()); + } + } + + return nullptr; +} + +object_ref KernelState::GetModule(const std::string_view name, bool user_only) { + if (name.empty()) { + // NULL name = self. + // TODO(benvanik): lookup module from caller address. + return GetExecutableModule(); + } else if (rex::string::utf8_equal_case(name, "kernel32.dll")) { + // Some games request this, for some reason. wtf. + return nullptr; + } + + // Search kernel modules under lock + if (!user_only) { + auto global_lock = global_critical_region_.Acquire(); + for (auto kernel_module : kernel_modules_) { + if (kernel_module->Matches(name)) { + return retain_object(kernel_module.get()); + } + } + } + + // Resolve path WITHOUT lock + auto path(name); + auto entry = file_system_->ResolvePath(name); + if (entry) { + path = entry->absolute_path(); + } + + // Search user modules under lock + { + auto global_lock = global_critical_region_.Acquire(); + for (auto user_module : user_modules_) { + if (user_module->Matches(path)) { + return retain_object(user_module.get()); + } + } + } + return nullptr; +} + +object_ref KernelState::PrepareModuleLaunch(object_ref module) { + if (!module->is_executable()) { + return nullptr; + } + + SetExecutableModule(module); + REXSYS_INFO("KernelState: Preparing module launch..."); + + // Create a thread to run in. + // We start suspended so the caller can inspect/attach before resume. + auto thread = object_ref(new XThread( + this, module->stack_size(), 0, module->entry_point(), 0, X_CREATE_SUSPENDED, true, true)); + + // We know this is the 'main thread'. + thread->set_name("Main XThread"); + + X_STATUS result = thread->Create(); + if (XFAILED(result)) { + REXSYS_ERROR("Could not create launch thread: {:08X}", result); + return nullptr; + } + + return thread; +} + +object_ref KernelState::LaunchModule(object_ref module) { + auto thread = PrepareModuleLaunch(std::move(module)); + if (thread) { + thread->Resume(); + } + return thread; +} + +object_ref KernelState::GetExecutableModule() { + if (!executable_module_) { + return nullptr; + } + return executable_module_; +} + +void KernelState::SetExecutableModule(object_ref module) { + if (module.get() == executable_module_.get()) { + return; + } + executable_module_ = std::move(module); + if (!executable_module_) { + return; + } + + // Update title process fields from the executable module. + // Do NOT call InitializeProcess() again - it was already called in the + // constructor, and threads (XMA decoder, dispatch) may already be linked + // into the thread_list. Reinitializing would orphan them. + auto globals = memory_->TranslateVirtual(kernel_guest_globals_); + auto* pib = &globals->title_process; + pib->unk_18 = 10; + pib->unk_19 = 13; + pib->unk_1A = 17; + + // Read default stack size from XEX header, align to 4KB, clamp to min 16KB. + uint32_t default_stack_size = 0; + executable_module_->GetOptHeader(XEX_HEADER_DEFAULT_STACK_SIZE, &default_stack_size); + if (default_stack_size) { + default_stack_size = rex::round_up(default_stack_size, 4096u); + if (default_stack_size < 16 * 1024) { + default_stack_size = 16 * 1024; + } + pib->kernel_stack_size = default_stack_size; + } + + // Update title process TLS info from the executable module. + xex2_opt_tls_info* tls_header = nullptr; + executable_module_->GetOptHeader(XEX_HEADER_TLS_INFO, &tls_header); + if (tls_header) { + pib->tls_data_size = tls_header->data_size; + pib->tls_raw_data_size = tls_header->raw_data_size; + SetProcessTLSVars(pib, tls_header->slot_count, tls_header->data_size, + tls_header->raw_data_address); + } + + // Setup the kernel's XexExecutableModuleHandle field. + auto export_entry = emulator_->function_dispatcher()->export_resolver()->GetExportByOrdinal( + "xboxkrnl.exe", 0x0193 /* XexExecutableModuleHandle */); + if (export_entry) { + assert_not_zero(export_entry->variable_ptr); + auto variable_ptr = memory_->TranslateVirtual*>(export_entry->variable_ptr); + *variable_ptr = executable_module_->hmodule_ptr(); + } + + // Setup the kernel's ExLoadedImageName field + export_entry = emulator_->function_dispatcher()->export_resolver()->GetExportByOrdinal( + "xboxkrnl.exe", 0x01AF /* ExLoadedImageName */); + if (export_entry) { + char* variable_ptr = memory_->TranslateVirtual(export_entry->variable_ptr); + rex::string::util_copy_truncating(variable_ptr, executable_module_->path(), + kExLoadedImageNameSize); + } + + // Spin up deferred dispatch worker. + // TODO(benvanik): move someplace more appropriate (out of ctor, but around + // here). + if (!dispatch_thread_running_) { + dispatch_thread_running_ = true; + dispatch_thread_ = object_ref(new XHostThread(this, 128 * 1024, 0, [this]() { + auto global_lock = global_critical_region_.AcquireDeferred(); + while (dispatch_thread_running_) { + global_lock.lock(); + if (dispatch_queue_.empty()) { + dispatch_cond_.wait(global_lock); + if (!dispatch_thread_running_) { + global_lock.unlock(); + break; + } + } + auto fn = std::move(dispatch_queue_.front()); + dispatch_queue_.pop_front(); + REXSYS_NOISY_DEBUG("Dispatch thread processing queued item ({} remaining)", + dispatch_queue_.size()); + global_lock.unlock(); + + // Throws out of fn leave the originating overlapped uncompleted and + // the waiting guest thread stuck; fail visibly rather than swallow. + try { + fn(); + } catch (const std::exception& e) { + REX_FATAL("Dispatch thread: deferred completion threw '{}'", e.what()); + } catch (...) { + REX_FATAL("Dispatch thread: deferred completion threw non-std exception"); + } + REXSYS_NOISY_DEBUG("Dispatch thread completed item"); + } + return 0; + })); + dispatch_thread_->set_name("Kernel Dispatch"); + X_STATUS create_status = dispatch_thread_->Create(); + if (XFAILED(create_status)) { + dispatch_thread_running_ = false; + dispatch_thread_.reset(); + REX_FATAL("Failed to create kernel dispatch thread (status {:#x})", create_status); + } + } +} + +void KernelState::LoadKernelModule(object_ref kernel_module) { + auto global_lock = global_critical_region_.Acquire(); + kernel_modules_.push_back(std::move(kernel_module)); +} + +object_ref KernelState::LoadUserModule(const std::string_view raw_name, + bool call_entry) { + // Some games try to load relative to launch module, others specify full path. + auto name = rex::string::utf8_find_name_from_guest_path(raw_name); + std::string path(raw_name); + if (name == raw_name) { + assert_not_null(executable_module_); + path = rex::string::utf8_join_guest_paths( + rex::string::utf8_find_base_guest_path(executable_module_->path()), name); + } + + // loading_paths_ serializes concurrent loaders of the same path; we + // can't hold the global lock across LoadFromFile or DllMain ATTACH. + { + auto global_lock = global_critical_region_.Acquire(); + for (auto& existing_module : user_modules_) { + if (existing_module->path() == path) { + return existing_module; + } + } + auto [it, inserted] = loading_paths_.emplace(path); + (void)it; + if (!inserted) { + REXSYS_WARN("LoadUserModule: '{}' already being loaded by another thread", path); + return nullptr; + } + } + + struct LoadingMarkerGuard { + KernelState* ks; + const std::string& key; + ~LoadingMarkerGuard() { + auto lock = ks->global_critical_region_.Acquire(); + ks->loading_paths_.erase(key); + } + } loading_guard{this, path}; + + auto module = object_ref(new UserModule(this)); + X_STATUS status = module->LoadFromFile(path); + if (XFAILED(status)) { + auto global_lock = global_critical_region_.Acquire(); + object_table()->ReleaseHandle(module->handle()); + return nullptr; + } + + module->Dump(); + + // Wire recompiled code (if any) before publishing to user_modules_, so a + // failure in this block leaves no half-loaded entry behind. + auto recomp = FindRecompiledModule(path); + bool wired_recomp = false; + if (recomp && !recomp->shared_lib_name.empty()) { + const std::string& lib_key = recomp->guest_path; + + { + auto global_lock = global_critical_region_.Acquire(); + auto [lib_it, inserted] = module_libraries_.emplace(lib_key, SharedLibrary{}); + if (!inserted) { + REXSYS_ERROR("Recompiled module '{}' already loaded; refusing duplicate load", lib_key); + object_table()->ReleaseHandle(module->handle()); + return nullptr; + } + } + + SharedLibrary library_local; + if (!library_local.Load(recomp->shared_lib_name)) { + REXSYS_ERROR("Failed to load shared library for module '{}'", recomp->pe_name); + } else { + auto register_func = reinterpret_cast( + library_local.GetSymbol("ReXModule_Register")); + if (!register_func) { + REXSYS_ERROR("ReXModule_Register not found in '{}'", recomp->shared_lib_name); + } else { + auto* xex = module->xex_module(); + auto* text = xex->GetPESection(".text"); + if (!text) { + REXSYS_ERROR("Module '{}' has no .text section", recomp->pe_name); + } else if (!function_dispatcher_->InitializeFunctionTable( + text->address, text->size, xex->base_address(), xex->image_size())) { + REXSYS_ERROR("InitializeFunctionTable failed for module '{}'", recomp->pe_name); + } else { + function_dispatcher_->RegisterModule(lib_key, text->address, register_func); + auto global_lock = global_critical_region_.Acquire(); + auto lib_it = module_libraries_.find(lib_key); + assert_true(lib_it != module_libraries_.end()); + lib_it->second = std::move(library_local); + wired_recomp = true; + } + } + } + + if (!wired_recomp) { + auto global_lock = global_critical_region_.Acquire(); + module_libraries_.erase(lib_key); + object_table()->ReleaseHandle(module->handle()); + return nullptr; + } + } + + { + auto global_lock = global_critical_region_.Acquire(); + user_modules_.push_back(module); + } + + if (module->is_dll_module() && module->entry_point() && call_entry) { + if (!XThread::IsInThread()) { + REXSYS_WARN("DllMain(DLL_PROCESS_ATTACH) skipped for '{}': not on a guest thread", + module->name()); + } else { + auto* thread = XThread::GetCurrentThread(); + uint64_t args[] = {module->hmodule_ptr(), 1 /* DLL_PROCESS_ATTACH */, 0}; + uint64_t dllmain_ret = + function_dispatcher_->Execute(thread->thread_state(), module->entry_point(), args, 3); + if (static_cast(dllmain_ret) == 0) { + REXSYS_ERROR("DllMain(DLL_PROCESS_ATTACH) returned FALSE for '{}'; rolling back load", + module->name()); + // call_entry=false: the guest already declined ATTACH, so don't run DETACH. + UnloadUserModule(module, /*call_entry=*/false); + return nullptr; + } + } + } + + return module; +} + +void KernelState::UnloadUserModule(const object_ref& module, bool call_entry) { + // Run guest DllMain DETACH outside the global lock to avoid deadlock with + // subsystem mutexes acquired from inside the guest callback. + if (module->is_dll_module() && module->entry_point() && call_entry) { + if (!XThread::IsInThread()) { + REXSYS_WARN("DllMain(DLL_PROCESS_DETACH) skipped for '{}': not on a guest thread", + module->name()); + } else { + auto* thread = XThread::GetCurrentThread(); + uint64_t args[] = {module->hmodule_ptr(), 0 /* DLL_PROCESS_DETACH */, 0}; + function_dispatcher_->Execute(thread->thread_state(), module->entry_point(), args, 3); + } + } + + bool found_module = false; + { + auto global_lock = global_critical_region_.Acquire(); + + auto recomp = FindRecompiledModule(module->path()); + if (recomp) { + const std::string& key = recomp->guest_path; + auto cleared_range = function_dispatcher_->UnregisterModule(key); + if (cleared_range) { + for (auto& km : kernel_modules_) { + km->InvalidateThunkCacheInRange(cleared_range->first, cleared_range->second); + } + } + + if (!recomp->shared_lib_name.empty()) { + auto lib_it = module_libraries_.find(key); + if (lib_it != module_libraries_.end()) { + deferred_unload_libraries_.push_back(std::move(lib_it->second)); + module_libraries_.erase(lib_it); + } + } + } + + auto iter = std::find_if(user_modules_.begin(), user_modules_.end(), + [&module](const auto& e) { return e->path() == module->path(); }); + if (iter != user_modules_.end()) { + user_modules_.erase(iter); + found_module = true; + } + + if (found_module) { + object_table()->ReleaseHandle(module->handle()); + } + } + + if (!found_module) { + REXSYS_ERROR("UnloadUserModule: module '{}' not found in user_modules_", module->path()); + } +} + +void KernelState::RegisterRecompiledModule(const char* pe_name, const char* guest_path, + const char* shared_lib_name) { + auto global_lock = global_critical_region_.Acquire(); + RecompiledModuleInfo info; + info.pe_name = pe_name ? pe_name : ""; + info.guest_path = guest_path ? NormalizeGuestPath(guest_path) : ""; + info.shared_lib_name = shared_lib_name ? shared_lib_name : ""; + + for (const auto& existing : recompiled_modules_) { + if (existing.guest_path == info.guest_path) { + REXSYS_ERROR( + "RegisterRecompiledModule: duplicate guest_path '{}' (existing pe='{}', new pe='{}')", + info.guest_path, existing.pe_name, info.pe_name); + return; + } + } + + REXSYS_INFO("Registered recompiled module: pe='{}' guest='{}' lib='{}'", info.pe_name, + info.guest_path, info.shared_lib_name); + recompiled_modules_.push_back(std::move(info)); +} + +std::optional KernelState::FindRecompiledModule( + std::string_view guest_path) { + auto global_lock = global_critical_region_.Acquire(); + auto normalized = NormalizeGuestPath(guest_path); + for (const auto& info : recompiled_modules_) { + if (info.guest_path == normalized) + return info; + } + return std::nullopt; +} + +void KernelState::TerminateTitle() { + REXSYS_DEBUG("KernelState::TerminateTitle"); + auto global_lock = global_critical_region_.Acquire(); + + // Suspend all running guest threads so they stop touching shared state. + std::vector suspended_threads; + for (auto it = threads_by_id_.begin(); it != threads_by_id_.end(); ++it) { + if (!XThread::IsInThread(it->second) && it->second->is_guest_thread() && + it->second->is_running()) { + it->second->thread()->Suspend(); + suspended_threads.push_back(it->second); + } + } + + // Terminate each suspended thread. Must drop the lock since Terminate waits. + global_lock.unlock(); + for (auto* thread : suspended_threads) { + thread->Terminate(0); + } + global_lock.lock(); + + // Remove all guest threads from the map. + for (auto it = threads_by_id_.begin(); it != threads_by_id_.end();) { + if (!XThread::IsInThread(it->second) && it->second->is_guest_thread()) { + it = threads_by_id_.erase(it); + } else { + ++it; + } + } + + // If called from a guest thread, self-terminate last. + if (XThread::IsInThread()) { + threads_by_id_.erase(XThread::GetCurrentThread()->thread_id()); + + // Now commit suicide (using Terminate, because we can't call into guest + // code anymore). + global_lock.unlock(); + XThread::GetCurrentThread()->Terminate(0); + } +} + +void KernelState::RegisterThread(XThread* thread) { + auto global_lock = global_critical_region_.Acquire(); + threads_by_id_[thread->thread_id()] = thread; + + // Thread count is now managed via thread-process linking in + // XThread::InitializeGuestObject and XThread::Exit. +} + +void KernelState::UnregisterThread(XThread* thread) { + auto global_lock = global_critical_region_.Acquire(); + auto it = threads_by_id_.find(thread->thread_id()); + if (it != threads_by_id_.end()) { + threads_by_id_.erase(it); + } +} + +void KernelState::OnThreadExecute(XThread* thread) { + auto global_lock = global_critical_region_.Acquire(); + + // Must be called on executing thread. + assert_true(XThread::GetCurrentThread() == thread); + + // TODO(tomc): Do we need this? + // Xenia would iterate user_modules_ and call function_dispatcher()->Execute() for + // each Note that this would require reimplementation of guest thread management + (void)thread; +} + +void KernelState::OnThreadExit(XThread* thread) { + auto global_lock = global_critical_region_.Acquire(); + + // Must be called on executing thread. + assert_true(XThread::GetCurrentThread() == thread); + + // TODO(tomc): Do we need this? Same idea as OnThreadExecute + (void)thread; +} + +object_ref KernelState::GetThreadByID(uint32_t thread_id) { + auto global_lock = global_critical_region_.Acquire(); + XThread* thread = nullptr; + auto it = threads_by_id_.find(thread_id); + if (it != threads_by_id_.end()) { + thread = it->second; + } + return retain_object(thread); +} + +void KernelState::RegisterNotifyListener(XNotifyListener* listener) { + auto global_lock = global_critical_region_.Acquire(); + notify_listeners_.push_back(retain_object(listener)); + + // Games seem to expect a few notifications on startup, only for the first + // listener. + // https://cs.rin.ru/forum/viewtopic.php?f=38&t=60668&hilit=resident+evil+5&start=375 + if (!has_notified_startup_ && listener->mask() & 0x00000001) { + has_notified_startup_ = true; + // XN_SYS_UI (on, off) + listener->EnqueueNotification(0x00000009, 1); + listener->EnqueueNotification(0x00000009, 0); + // XN_SYS_SIGNINCHANGED x2 + listener->EnqueueNotification(0x0000000A, 1); + listener->EnqueueNotification(0x0000000A, 1); + // XN_SYS_INPUTDEVICESCHANGED x2 + listener->EnqueueNotification(0x00000012, 0); + listener->EnqueueNotification(0x00000012, 0); + // XN_SYS_INPUTDEVICECONFIGCHANGED x2 + listener->EnqueueNotification(0x00000013, 0); + listener->EnqueueNotification(0x00000013, 0); + } +} + +void KernelState::UnregisterNotifyListener(XNotifyListener* listener) { + auto global_lock = global_critical_region_.Acquire(); + for (auto it = notify_listeners_.begin(); it != notify_listeners_.end(); ++it) { + if ((*it).get() == listener) { + notify_listeners_.erase(it); + break; + } + } +} + +void KernelState::BroadcastNotification(XNotificationID id, uint32_t data) { + std::vector> snapshot; + { + auto global_lock = global_critical_region_.Acquire(); + REXSYS_DEBUG("BroadcastNotification(id={:#x}, data={}) to {} listeners", + static_cast(id), data, notify_listeners_.size()); + snapshot = notify_listeners_; + } + for (const auto& notify_listener : snapshot) { + notify_listener->EnqueueNotification(id, data); + } +} + +void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result) { + CompleteOverlappedEx(overlapped_ptr, result, result, 0); +} + +void KernelState::CompleteOverlappedEx(uint32_t overlapped_ptr, X_RESULT result, + uint32_t extended_error, uint32_t length) { + auto ptr = memory()->TranslateVirtual(overlapped_ptr); + XOverlappedSetResult(ptr, result); + XOverlappedSetExtendedError(ptr, extended_error); + XOverlappedSetLength(ptr, length); + X_HANDLE event_handle = XOverlappedGetEvent(ptr); + if (event_handle) { + auto ev = object_table()->LookupObject(event_handle); + assert_not_null(ev); + if (ev) { + ev->Set(0, false); + } + } + if (XOverlappedGetCompletionRoutine(ptr)) { + X_HANDLE thread_handle = XOverlappedGetContext(ptr); + auto thread = object_table()->LookupObject(thread_handle); + if (thread) { + // Queue APC on the thread that requested the overlapped operation. + uint32_t routine = XOverlappedGetCompletionRoutine(ptr); + thread->EnqueueApc(routine, result, length, overlapped_ptr); + } + } +} + +void KernelState::CompleteOverlappedImmediate(uint32_t overlapped_ptr, X_RESULT result) { + // TODO(gibbed): there are games that check 'length' of overlapped as + // an indication of success. WTF? + // Setting length to -1 when not success seems to be helping. + uint32_t length = !result ? 0 : 0xFFFFFFFF; + CompleteOverlappedImmediateEx(overlapped_ptr, result, result, length); +} + +void KernelState::CompleteOverlappedImmediateEx(uint32_t overlapped_ptr, X_RESULT result, + uint32_t extended_error, uint32_t length) { + auto ptr = memory()->TranslateVirtual(overlapped_ptr); + XOverlappedSetContext(ptr, XThread::GetCurrentThreadHandle()); + CompleteOverlappedEx(overlapped_ptr, result, extended_error, length); +} + +void KernelState::CompleteOverlappedDeferred(std::function completion_callback, + uint32_t overlapped_ptr, X_RESULT result, + std::function pre_callback, + std::function post_callback) { + CompleteOverlappedDeferredEx(std::move(completion_callback), overlapped_ptr, result, result, 0, + pre_callback, post_callback); +} + +void KernelState::CompleteOverlappedDeferredEx(std::function completion_callback, + uint32_t overlapped_ptr, X_RESULT result, + uint32_t extended_error, uint32_t length, + std::function pre_callback, + std::function post_callback) { + CompleteOverlappedDeferredEx( + [completion_callback, result, extended_error, length](uint32_t& cb_extended_error, + uint32_t& cb_length) -> X_RESULT { + completion_callback(); + cb_extended_error = extended_error; + cb_length = length; + return result; + }, + overlapped_ptr, pre_callback, post_callback); +} + +void KernelState::CompleteOverlappedDeferred(std::function completion_callback, + uint32_t overlapped_ptr, + std::function pre_callback, + std::function post_callback) { + CompleteOverlappedDeferredEx( + [completion_callback](uint32_t& extended_error, uint32_t& length) -> X_RESULT { + auto result = completion_callback(); + extended_error = static_cast(result); + length = 0; + return result; + }, + overlapped_ptr, pre_callback, post_callback); +} + +void KernelState::CompleteOverlappedDeferredEx( + std::function completion_callback, uint32_t overlapped_ptr, + std::function pre_callback, std::function post_callback) { + REXSYS_DEBUG("CompleteOverlappedDeferredEx: queuing for overlapped {:08X}", overlapped_ptr); + auto ptr = memory()->TranslateVirtual(overlapped_ptr); + XOverlappedSetResult(ptr, X_ERROR_IO_PENDING); + XOverlappedSetContext(ptr, XThread::GetCurrentThreadHandle()); + auto global_lock = global_critical_region_.Acquire(); + dispatch_queue_.push_back( + [this, completion_callback, overlapped_ptr, pre_callback, post_callback]() { + REXSYS_DEBUG("Deferred overlapped {:08X}: running pre_callback", overlapped_ptr); + if (pre_callback) { + pre_callback(); + } + REXSYS_DEBUG("Deferred overlapped {:08X}: sleeping {}ms", overlapped_ptr, + kDeferredOverlappedDelayMillis); + rex::thread::Sleep(std::chrono::milliseconds(kDeferredOverlappedDelayMillis)); + uint32_t extended_error, length; + REXSYS_DEBUG("Deferred overlapped {:08X}: running completion", overlapped_ptr); + auto result = completion_callback(extended_error, length); + REXSYS_DEBUG("Deferred overlapped {:08X}: completing with result {:08X}", overlapped_ptr, + result); + CompleteOverlappedEx(overlapped_ptr, result, extended_error, length); + if (post_callback) { + REXSYS_DEBUG("Deferred overlapped {:08X}: running post_callback", overlapped_ptr); + post_callback(); + } + }); + dispatch_cond_.notify_all(); +} + +DPCImpersonationScope KernelState::BeginDPCImpersonation() { + auto* thread = XThread::GetCurrentThread(); + auto* ctx = thread->thread_state()->context(); + auto pcr = memory_->TranslateVirtual(static_cast(ctx->r13.u64)); + DPCImpersonationScope scope; + scope.previous_irql_ = pcr->current_irql; + pcr->current_irql = IRQL_DISPATCH; + pcr->prcb_data.dpc_active = 1; + return scope; +} + +void KernelState::EndDPCImpersonation(const DPCImpersonationScope& scope) { + auto* thread = XThread::GetCurrentThread(); + auto* ctx = thread->thread_state()->context(); + auto pcr = memory_->TranslateVirtual(static_cast(ctx->r13.u64)); + pcr->prcb_data.dpc_active = 0; + pcr->current_irql = scope.previous_irql_; +} + +bool KernelState::Save(stream::ByteStream* stream) { + REXSYS_DEBUG("Serializing the kernel..."); + stream->Write(kKernelSaveSignature); + + // Save the object table + object_table_.Save(stream); + + // Legacy save-state field (global TLS bitmap) no longer used. + stream->Write(uint32_t(0)); + + // We save XThreads absolutely first, as they will execute code upon save + // (which could modify the kernel state) + auto threads = object_table_.GetObjectsByType(); + uint32_t* num_threads_ptr = reinterpret_cast(stream->data() + stream->offset()); + stream->Write(static_cast(threads.size())); + + size_t num_threads = threads.size(); + REXSYS_DEBUG("Serializing {} threads...", threads.size()); + for (auto thread : threads) { + if (!thread->is_guest_thread()) { + // Don't save host threads. They can be reconstructed on startup. + num_threads--; + continue; + } + + if (!thread->Save(stream)) { + REXSYS_DEBUG("Failed to save thread \"{}\"", thread->name()); + num_threads--; + } + } + + *num_threads_ptr = static_cast(num_threads); + + // Save all other objects + auto objects = object_table_.GetAllObjects(); + uint32_t* num_objects_ptr = reinterpret_cast(stream->data() + stream->offset()); + stream->Write(static_cast(objects.size())); + + size_t num_objects = objects.size(); + REXSYS_DEBUG("Serializing {} objects...", num_objects); + for (auto object : objects) { + auto prev_offset = stream->offset(); + + if (object->is_host_object() || object->type() == XObject::Type::Thread) { + // Don't save host objects or save XThreads again + num_objects--; + continue; + } + + stream->Write(static_cast(object->type())); + if (!object->Save(stream)) { + REXSYS_DEBUG("Did not save object of type {}", object->type()); + assert_always(); + + // Revert backwards and overwrite if a save failed. + stream->set_offset(prev_offset); + num_objects--; + } + } + + *num_objects_ptr = static_cast(num_objects); + return true; +} + +bool KernelState::Restore(stream::ByteStream* stream) { + // Check the magic value. + if (stream->Read() != kKernelSaveSignature) { + return false; + } + + // Restore the object table + object_table_.Restore(stream); + + // Global TLS bitmap field is kept for old save-state compatibility. + auto num_bitmap_entries = stream->Read(); + for (uint32_t i = 0; i < num_bitmap_entries; i++) { + stream->Read(); + } + + uint32_t num_threads = stream->Read(); + REXSYS_DEBUG("Loading {} threads...", num_threads); + for (uint32_t i = 0; i < num_threads; i++) { + auto thread = XObject::Restore(this, XObject::Type::Thread, stream); + if (!thread) { + // Can't continue the restore or we risk misalignment. + assert_always(); + return false; + } + } + + uint32_t num_objects = stream->Read(); + REXSYS_DEBUG("Loading {} objects...", num_objects); + for (uint32_t i = 0; i < num_objects; i++) { + uint32_t type = stream->Read(); + + auto obj = XObject::Restore(this, XObject::Type(type), stream); + if (!obj) { + // Can't continue the restore or we risk misalignment. + assert_always(); + return false; + } + } + + return true; +} + +FiberInfo* KernelState::LookupFiber(uint32_t guest_addr) { + auto lock = global_critical_region_.Acquire(); + auto it = fiber_map_.find(guest_addr); + return it != fiber_map_.end() ? &it->second : nullptr; +} + +void KernelState::RegisterFiber(uint32_t guest_addr, const FiberInfo& info) { + auto lock = global_critical_region_.Acquire(); + fiber_map_[guest_addr] = info; +} + +void KernelState::UnregisterFiber(uint32_t guest_addr) { + auto lock = global_critical_region_.Acquire(); + fiber_map_.erase(guest_addr); +} + +const char* KernelState::GetOrCreateFiberName(uint32_t guest_addr, const char* thread_name) { + std::lock_guard lock(fiber_name_pool_mutex_); + auto it = fiber_name_pool_.find(guest_addr); + if (it != fiber_name_pool_.end()) { + return it->second.get(); + } + auto name = fmt::format("Fiber {:08X} ({})", guest_addr, thread_name); + auto buf = std::make_unique(name.size() + 1); + std::memcpy(buf.get(), name.c_str(), name.size() + 1); + const char* ptr = buf.get(); + fiber_name_pool_.emplace(guest_addr, std::move(buf)); + return ptr; +} + +} // namespace rex::system diff --git a/src/system/lzx.cpp b/src/system/lzx.cpp new file mode 100644 index 0000000..e3ffec4 --- /dev/null +++ b/src/system/lzx.cpp @@ -0,0 +1,188 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +typedef struct mspack_memory_file_t { + mspack_system sys; + void* buffer; + off_t buffer_size; + off_t offset; +} mspack_memory_file; + +mspack_memory_file* mspack_memory_open(mspack_system* sys, void* buffer, const size_t buffer_size) { + (void)sys; + assert_true(buffer_size < INT_MAX); + if (buffer_size >= INT_MAX) { + return NULL; + } + auto memfile = (mspack_memory_file*)std::calloc(1, sizeof(mspack_memory_file)); + if (!memfile) { + return NULL; + } + memfile->buffer = buffer; + memfile->buffer_size = (off_t)buffer_size; + memfile->offset = 0; + return memfile; +} + +void mspack_memory_close(mspack_memory_file* file) { + auto memfile = (mspack_memory_file*)file; + std::free(memfile); +} + +int mspack_memory_read(mspack_file* file, void* buffer, int chars) { + auto memfile = (mspack_memory_file*)file; + const off_t remaining = memfile->buffer_size - memfile->offset; + const off_t total = std::min(static_cast(chars), remaining); + std::memcpy(buffer, (uint8_t*)memfile->buffer + memfile->offset, total); + memfile->offset += total; + return (int)total; +} + +int mspack_memory_write(mspack_file* file, void* buffer, int chars) { + auto memfile = (mspack_memory_file*)file; + const off_t remaining = memfile->buffer_size - memfile->offset; + const off_t total = std::min(static_cast(chars), remaining); + std::memcpy((uint8_t*)memfile->buffer + memfile->offset, buffer, total); + memfile->offset += total; + return (int)total; +} + +void* mspack_memory_alloc(mspack_system* sys, size_t chars) { + return std::calloc(chars, 1); +} + +void mspack_memory_free(void* ptr) { + std::free(ptr); +} + +void mspack_memory_copy(void* src, void* dest, size_t chars) { + std::memcpy(dest, src, chars); +} + +mspack_system* mspack_memory_sys_create() { + auto sys = (mspack_system*)std::calloc(1, sizeof(mspack_system)); + if (!sys) { + return NULL; + } + sys->read = mspack_memory_read; + sys->write = mspack_memory_write; + sys->alloc = mspack_memory_alloc; + sys->free = mspack_memory_free; + sys->copy = mspack_memory_copy; + return sys; +} + +void mspack_memory_sys_destroy(struct mspack_system* sys) { + free(sys); +} + +int lzx_decompress(const void* lzx_data, size_t lzx_len, void* dest, size_t dest_len, + uint32_t window_size, void* window_data, size_t window_data_len) { + int result_code = 1; + + uint32_t window_bits; + if (!rex::bit_scan_forward(window_size, &window_bits)) { + return result_code; + } + + mspack_system* sys = mspack_memory_sys_create(); + mspack_memory_file* lzxsrc = mspack_memory_open(sys, (void*)lzx_data, lzx_len); + mspack_memory_file* lzxdst = mspack_memory_open(sys, dest, dest_len); + lzxd_stream* lzxd = lzxd_init(sys, (mspack_file*)lzxsrc, (mspack_file*)lzxdst, window_bits, 0, + 0x8000, (off_t)dest_len, 0); + + if (lzxd) { + if (window_data) { + // zero the window and then copy window_data to the end of it + auto padding_len = window_size - window_data_len; + std::memset(&lzxd->window[0], 0, padding_len); + std::memcpy(&lzxd->window[padding_len], window_data, window_data_len); + // TODO(gibbed): should this be set regardless if source window data is + // available or not? + lzxd->ref_data_size = window_size; + } + + result_code = lzxd_decompress(lzxd, (off_t)dest_len); + + lzxd_free(lzxd); + lzxd = NULL; + } + + if (lzxsrc) { + mspack_memory_close(lzxsrc); + lzxsrc = NULL; + } + + if (lzxdst) { + mspack_memory_close(lzxdst); + lzxdst = NULL; + } + + if (sys) { + mspack_memory_sys_destroy(sys); + sys = NULL; + } + + return result_code; +} + +int lzxdelta_apply_patch(rex::xex2_delta_patch* patch, size_t patch_len, uint32_t window_size, + void* dest) { + void* patch_end = (char*)patch + patch_len; + auto* cur_patch = patch; + + while (patch_end > cur_patch) { + int patch_sz = -4; // 0 byte patches need us to remove 4 byte from next + // patch addr because of patch_data field + if (cur_patch->compressed_len == 0 && cur_patch->uncompressed_len == 0 && + cur_patch->new_addr == 0 && cur_patch->old_addr == 0) + break; + switch (cur_patch->compressed_len) { + case 0: // fill with 0 + std::memset((char*)dest + cur_patch->new_addr, 0, cur_patch->uncompressed_len); + break; + case 1: // copy from old -> new + std::memcpy((char*)dest + cur_patch->new_addr, (char*)dest + cur_patch->old_addr, + cur_patch->uncompressed_len); + break; + default: // delta patch + patch_sz = cur_patch->compressed_len - 4; // -4 because of patch_data field + + int result = lzx_decompress(cur_patch->patch_data, cur_patch->compressed_len, + (char*)dest + cur_patch->new_addr, cur_patch->uncompressed_len, + window_size, (char*)dest + cur_patch->old_addr, + cur_patch->uncompressed_len); + + if (result) { + return result; + } + break; + } + + cur_patch++; + cur_patch = (rex::xex2_delta_patch*)((char*)cur_patch + patch_sz); // TODO: make this less ugly + } + + return 0; +} diff --git a/src/system/map_parser.cpp b/src/system/map_parser.cpp new file mode 100644 index 0000000..b5a61bb --- /dev/null +++ b/src/system/map_parser.cpp @@ -0,0 +1,162 @@ +/** + * @file runtime/map_parser.cpp + * @brief Implementation of map file parsing utilities + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include +#include +#include + +#include + +namespace rex::runtime { + +namespace { + +/** + * Determine symbol type from nm symbol type character. + */ +BinarySymbolType SymbolTypeFromNmChar(char c) { + switch (c) { + case 'T': + case 't': + return BinarySymbolType::Function; + case 'D': + case 'd': + case 'B': + case 'b': + case 'R': + case 'r': + return BinarySymbolType::Data; + case 'U': + return BinarySymbolType::Import; + default: + return BinarySymbolType::Unknown; + } +} + +/** + * Check if nm symbol type indicates a function. + */ +bool IsFunctionType(char c) { + return c == 'T' || c == 't'; +} + +} // namespace + +std::expected, MapParseError> ParseNmMapString( + std::string_view map_data, const MapParseOptions& options) { + std::vector symbols; + + // Parse line by line + size_t pos = 0; + while (pos < map_data.size()) { + // Find end of line + size_t eol = map_data.find('\n', pos); + if (eol == std::string_view::npos) { + eol = map_data.size(); + } + + std::string_view line = map_data.substr(pos, eol - pos); + pos = eol + 1; + + // Skip empty lines + if (line.empty()) + continue; + + // Remove trailing \r if present + if (!line.empty() && line.back() == '\r') { + line = line.substr(0, line.size() - 1); + } + + // nm format: "address type name" (space-separated) + // Example: "00000000 t test_add1" + + // Find first space (after address) + size_t space1 = line.find(' '); + if (space1 == std::string_view::npos) + continue; + + // Parse address + std::string_view addr_str = line.substr(0, space1); + uint32_t address = 0; + auto [ptr, ec] = + std::from_chars(addr_str.data(), addr_str.data() + addr_str.size(), address, 16); + if (ec != std::errc()) + continue; + + // Skip whitespace to find type + size_t type_pos = space1 + 1; + while (type_pos < line.size() && line[type_pos] == ' ') { + ++type_pos; + } + if (type_pos >= line.size()) + continue; + + char type_char = line[type_pos]; + + // Skip to name + size_t name_pos = type_pos + 1; + while (name_pos < line.size() && line[name_pos] == ' ') { + ++name_pos; + } + if (name_pos >= line.size()) + continue; + + std::string_view name = line.substr(name_pos); + + // Apply filters + if (options.functions_only && !IsFunctionType(type_char)) { + continue; + } + + if (!options.prefix_filter.empty()) { + if (!name.starts_with(options.prefix_filter)) { + continue; + } + } + + // Create symbol + BinarySymbol sym; + sym.name = std::string(name); + sym.address = address + options.base_address; + sym.size = 0; // nm doesn't provide size + sym.type = SymbolTypeFromNmChar(type_char); + + symbols.push_back(std::move(sym)); + } + + if (symbols.empty()) { + return std::unexpected(MapParseError::Empty); + } + + return symbols; +} + +std::expected, MapParseError> ParseNmMap( + const std::filesystem::path& map_path, const MapParseOptions& options) { + // Check if file exists + if (!std::filesystem::exists(map_path)) { + return std::unexpected(MapParseError::FileNotFound); + } + + // Read file contents + std::ifstream file(map_path, std::ios::binary); + if (!file) { + return std::unexpected(MapParseError::FileReadError); + } + + std::ostringstream ss; + ss << file.rdbuf(); + std::string contents = ss.str(); + + return ParseNmMapString(contents, options); +} + +} // namespace rex::runtime diff --git a/src/system/mmio_handler.cpp b/src/system/mmio_handler.cpp new file mode 100644 index 0000000..2b93005 --- /dev/null +++ b/src/system/mmio_handler.cpp @@ -0,0 +1,529 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace rex::arch; + +namespace rex::runtime { + +MMIOHandler* MMIOHandler::global_handler_ = nullptr; + +MMIOHandler* MMIOHandler::global_handler() { + return global_handler_; +} + +std::unique_ptr MMIOHandler::Install(uint8_t* virtual_membase, + uint8_t* physical_membase, uint8_t* membase_end, + HostToGuestVirtual host_to_guest_virtual, + const void* host_to_guest_virtual_context, + AccessViolationCallback access_violation_callback, + void* access_violation_callback_context) { + // There can be only one handler at a time. + assert_null(global_handler_); + if (global_handler_) { + return nullptr; + } + + auto handler = std::unique_ptr(new MMIOHandler( + virtual_membase, physical_membase, membase_end, host_to_guest_virtual, + host_to_guest_virtual_context, access_violation_callback, access_violation_callback_context)); + + // Install exception handler for memory coherence (SharedMemory write tracking). + // Note: MMIO operations are handled at the recompiler level via REX_MM_LOAD/STORE + // macros that call CheckLoad/CheckStore directly. + arch::ExceptionHandler::Install(ExceptionCallbackThunk, handler.get()); + + global_handler_ = handler.get(); + return handler; +} + +MMIOHandler::MMIOHandler(uint8_t* virtual_membase, uint8_t* physical_membase, uint8_t* membase_end, + HostToGuestVirtual host_to_guest_virtual, + const void* host_to_guest_virtual_context, + AccessViolationCallback access_violation_callback, + void* access_violation_callback_context) + : virtual_membase_(virtual_membase), + physical_membase_(physical_membase), + memory_end_(membase_end), + host_to_guest_virtual_(host_to_guest_virtual), + host_to_guest_virtual_context_(host_to_guest_virtual_context), + access_violation_callback_(access_violation_callback), + access_violation_callback_context_(access_violation_callback_context) {} + +MMIOHandler::~MMIOHandler() { + arch::ExceptionHandler::Uninstall(ExceptionCallbackThunk, this); + + if (global_handler_ == this) { + global_handler_ = nullptr; + } else { + REXLOG_ERROR("~MMIOHandler: global_handler_ does not match this instance"); + } +} + +bool MMIOHandler::RegisterRange(uint32_t virtual_address, uint32_t mask, uint32_t size, + void* context, MMIOReadCallback read_callback, + MMIOWriteCallback write_callback) { + mapped_ranges_.push_back({ + virtual_address, + mask, + size, + context, + read_callback, + write_callback, + }); + return true; +} + +MMIORange* MMIOHandler::LookupRange(uint32_t virtual_address) { + for (auto& range : mapped_ranges_) { + if ((virtual_address & range.mask) == range.address) { + return ⦥ + } + } + return nullptr; +} + +bool MMIOHandler::CheckLoad(uint32_t virtual_address, uint32_t* out_value) { + for (const auto& range : mapped_ranges_) { + if ((virtual_address & range.mask) == range.address) { + *out_value = + static_cast(range.read(nullptr, range.callback_context, virtual_address)); + return true; + } + } + return false; +} + +bool MMIOHandler::CheckStore(uint32_t virtual_address, uint32_t value) { + for (const auto& range : mapped_ranges_) { + if ((virtual_address & range.mask) == range.address) { + range.write(nullptr, range.callback_context, virtual_address, value); + return true; + } + } + return false; +} + +bool MMIOHandler::TryDecodeLoadStore(const uint8_t* p, DecodedLoadStore& decoded_out) { + std::memset(&decoded_out, 0, sizeof(decoded_out)); +#if REX_ARCH_AMD64 + uint8_t i = 0; // Current byte decode index. + uint8_t rex = 0; + if ((p[i] & 0xF0) == 0x40) { + rex = p[0]; + ++i; + } + if (p[i] == 0x0F && p[i + 1] == 0x38 && p[i + 2] == 0xF1) { + // MOVBE m32, r32 (store) + // https://web.archive.org/web/20170629091435/https://www.tptp.cc/mirrors/siyobik.info/instruction/MOVBE.html + // 44 0f 38 f1 a4 02 00 movbe DWORD PTR [rdx+rax*1+0x0],r12d + // 42 0f 38 f1 8c 22 00 movbe DWORD PTR [rdx+r12*1+0x0],ecx + // 0f 38 f1 8c 02 00 00 movbe DWORD PTR [rdx + rax * 1 + 0x0], ecx + decoded_out.is_load = false; + decoded_out.byte_swap = true; + i += 3; + } else if (p[i] == 0x0F && p[i + 1] == 0x38 && p[i + 2] == 0xF0) { + // MOVBE r32, m32 (load) + // https://web.archive.org/web/20170629091435/https://www.tptp.cc/mirrors/siyobik.info/instruction/MOVBE.html + // 44 0f 38 f0 a4 02 00 movbe r12d,DWORD PTR [rdx+rax*1+0x0] + // 42 0f 38 f0 8c 22 00 movbe ecx,DWORD PTR [rdx+r12*1+0x0] + // 46 0f 38 f0 a4 22 00 movbe r12d,DWORD PTR [rdx+r12*1+0x0] + // 0f 38 f0 8c 02 00 00 movbe ecx,DWORD PTR [rdx+rax*1+0x0] + // 0F 38 F0 1C 02 movbe ebx,dword ptr [rdx+rax] + decoded_out.is_load = true; + decoded_out.byte_swap = true; + i += 3; + } else if (p[i] == 0x89) { + // MOV m32, r32 (store) + // https://web.archive.org/web/20170629072136/https://www.tptp.cc/mirrors/siyobik.info/instruction/MOV.html + // 44 89 24 02 mov DWORD PTR[rdx + rax * 1], r12d + // 42 89 0c 22 mov DWORD PTR[rdx + r12 * 1], ecx + // 89 0c 02 mov DWORD PTR[rdx + rax * 1], ecx + decoded_out.is_load = false; + decoded_out.byte_swap = false; + ++i; + } else if (p[i] == 0x8B) { + // MOV r32, m32 (load) + // https://web.archive.org/web/20170629072136/https://www.tptp.cc/mirrors/siyobik.info/instruction/MOV.html + // 44 8b 24 02 mov r12d, DWORD PTR[rdx + rax * 1] + // 42 8b 0c 22 mov ecx, DWORD PTR[rdx + r12 * 1] + // 46 8b 24 22 mov r12d, DWORD PTR[rdx + r12 * 1] + // 8b 0c 02 mov ecx, DWORD PTR[rdx + rax * 1] + decoded_out.is_load = true; + decoded_out.byte_swap = false; + ++i; + } else if (p[i] == 0xC7) { + // MOV m32, simm32 + // https://web.archive.org/web/20161017042413/https://www.asmpedia.org/index.php?title=MOV + // C7 04 02 02 00 00 00 mov dword ptr [rdx+rax],2 + decoded_out.is_load = false; + decoded_out.byte_swap = false; + decoded_out.is_constant = true; + ++i; + } else { + return false; + } + + uint8_t rex_b = rex & 0b0001; + uint8_t rex_x = rex & 0b0010; + uint8_t rex_r = rex & 0b0100; + uint8_t rex_w = rex & 0b1000; + + // http://www.sandpile.org/x86/opc_rm.htm + // http://www.sandpile.org/x86/opc_sib.htm + uint8_t modrm = p[i++]; + uint8_t mod = (modrm & 0b11000000) >> 6; + uint8_t reg = (modrm & 0b00111000) >> 3; + uint8_t rm = (modrm & 0b00000111); + decoded_out.value_reg = reg + (rex_r ? 8 : 0); + decoded_out.mem_has_base = false; + decoded_out.mem_base_reg = 0; + decoded_out.mem_has_index = false; + decoded_out.mem_index_reg = 0; + decoded_out.mem_scale = 1; + decoded_out.mem_displacement = 0; + bool has_sib = false; + switch (rm) { + case 0b100: // SIB + has_sib = true; + break; + case 0b101: + if (mod == 0b00) { + // RIP-relative not supported. + return false; + } + decoded_out.mem_has_base = true; + decoded_out.mem_base_reg = rm + (rex_b ? 8 : 0); + break; + default: + decoded_out.mem_has_base = true; + decoded_out.mem_base_reg = rm + (rex_b ? 8 : 0); + break; + } + if (has_sib) { + uint8_t sib = p[i++]; + decoded_out.mem_scale = 1 << ((sib & 0b11000000) >> 8); + uint8_t sib_index = (sib & 0b00111000) >> 3; + uint8_t sib_base = (sib & 0b00000111); + switch (sib_index) { + case 0b100: + // No index. + break; + default: + decoded_out.mem_has_index = true; + decoded_out.mem_index_reg = sib_index + (rex_x ? 8 : 0); + decoded_out.mem_index_size = sizeof(uint64_t); + break; + } + switch (sib_base) { + case 0b101: + // Alternate rbp-relative addressing not supported. + assert_zero(mod); + return false; + default: + decoded_out.mem_has_base = true; + decoded_out.mem_base_reg = sib_base + (rex_b ? 8 : 0); + break; + } + } + switch (mod) { + case 0b00: { + decoded_out.mem_displacement += 0; + } break; + case 0b01: { + decoded_out.mem_displacement += int8_t(p[i++]); + } break; + case 0b10: { + decoded_out.mem_displacement += memory::load(p + i); + i += 4; + } break; + } + if (decoded_out.is_constant) { + decoded_out.constant = memory::load(p + i); + i += 4; + } + decoded_out.length = i; + return true; + +#elif REX_ARCH_ARM64 + decoded_out.length = sizeof(uint32_t); + uint32_t instruction = *reinterpret_cast(p); + + // Literal loading (PC-relative) is not handled. + + if ((instruction & kArm64LoadStoreAnyFMask) != kArm64LoadStoreAnyFixed) { + // Not a load or a store instruction. + return false; + } + + if ((instruction & kArm64LoadStorePairAnyFMask) == kArm64LoadStorePairAnyFixed) { + // Handling MMIO only for single 32-bit values, not for pairs. + return false; + } + + uint8_t value_reg_base; + switch (Arm64LoadStoreOp(instruction & kArm64LoadStoreMask)) { + case Arm64LoadStoreOp::kSTR_w: + decoded_out.is_load = false; + value_reg_base = DecodedLoadStore::kArm64ValueRegX0; + break; + case Arm64LoadStoreOp::kLDR_w: + decoded_out.is_load = true; + value_reg_base = DecodedLoadStore::kArm64ValueRegX0; + break; + case Arm64LoadStoreOp::kSTR_s: + decoded_out.is_load = false; + value_reg_base = DecodedLoadStore::kArm64ValueRegV0; + break; + case Arm64LoadStoreOp::kLDR_s: + decoded_out.is_load = true; + value_reg_base = DecodedLoadStore::kArm64ValueRegV0; + break; + default: + return false; + } + + // `Rt` field (load / store register). + decoded_out.value_reg = value_reg_base + (instruction & 31); + if (decoded_out.is_load && decoded_out.value_reg == DecodedLoadStore::kArm64ValueRegZero) { + // Zero constant rather than a register read. + decoded_out.is_constant = true; + decoded_out.constant = 0; + } + + decoded_out.mem_has_base = true; + // The base is Xn (for 0...30) or SP (for 31). + // `Rn` field (first source register). + decoded_out.mem_base_reg = (instruction >> 5) & 31; + + bool is_unsigned_offset = + (instruction & kArm64LoadStoreUnsignedOffsetFMask) == kArm64LoadStoreUnsignedOffsetFixed; + if (is_unsigned_offset) { + // LDR|STR Wt|St, [Xn|SP{, #pimm}] + uint32_t unsigned_offset = (instruction >> 10) & 4095; + decoded_out.mem_displacement = ptrdiff_t(sizeof(uint32_t) * unsigned_offset); + } else { + Arm64LoadStoreOffsetFixed offset = + Arm64LoadStoreOffsetFixed(instruction & kArm64LoadStoreOffsetFMask); + int32_t signed_offset = int32_t(instruction << (32 - (9 + 12))) >> (32 - 9); + switch (offset) { + case Arm64LoadStoreOffsetFixed::kUnscaledOffset: { + decoded_out.mem_displacement = signed_offset; + } break; + case Arm64LoadStoreOffsetFixed::kPostIndex: { + decoded_out.mem_base_writeback = true; + decoded_out.mem_base_writeback_offset = signed_offset; + } break; + case Arm64LoadStoreOffsetFixed::kPreIndex: { + decoded_out.mem_base_writeback = true; + decoded_out.mem_base_writeback_offset = signed_offset; + decoded_out.mem_displacement = signed_offset; + } break; + case Arm64LoadStoreOffsetFixed::kRegisterOffset: { + decoded_out.mem_index_reg = (instruction >> 16) & 31; + if (decoded_out.mem_index_reg != DecodedLoadStore::kArm64RegZero) { + decoded_out.mem_has_index = true; + uint32_t extend_mode = (instruction >> 13) & 0b111; + if (!(extend_mode & 0b010)) { + return false; + } + decoded_out.mem_index_size = (extend_mode & 0b001) ? sizeof(uint64_t) : sizeof(uint32_t); + decoded_out.mem_index_sign_extend = (extend_mode & 0b100) != 0; + decoded_out.mem_scale = (instruction & (UINT32_C(1) << 12)) ? sizeof(uint32_t) : 1; + } + } break; + default: + return false; + } + } + + return true; + +#else +#error TryDecodeLoadStore not implemented for the target CPU architecture. + return false; +#endif // REX_ARCH +} + +bool MMIOHandler::ExceptionCallbackThunk(arch::Exception* ex, void* data) { + return reinterpret_cast(data)->ExceptionCallback(ex); +} + +bool MMIOHandler::ExceptionCallback(arch::Exception* ex) { + if (ex->code() != arch::Exception::Code::kAccessViolation) { + return false; + } + arch::Exception::AccessViolationOperation operation = ex->access_violation_operation(); + if (operation != arch::Exception::AccessViolationOperation::kRead && + operation != arch::Exception::AccessViolationOperation::kWrite) { + // Data Execution Prevention or something else uninteresting. + return false; + } + bool is_write = operation == arch::Exception::AccessViolationOperation::kWrite; + if (ex->fault_address() < uint64_t(virtual_membase_) || + ex->fault_address() > uint64_t(memory_end_)) { + // Quick kill anything outside our mapping. + return false; + } + void* fault_host_address = reinterpret_cast(ex->fault_address()); + + // Access violations are pretty rare, so we can do a linear search here. + // Only check if in the virtual range, as we only support virtual ranges. + const MMIORange* range = nullptr; + uint32_t fault_guest_virtual_address = 0; + if (ex->fault_address() < uint64_t(physical_membase_)) { + fault_guest_virtual_address = + host_to_guest_virtual_(host_to_guest_virtual_context_, fault_host_address); + for (const auto& test_range : mapped_ranges_) { + if ((fault_guest_virtual_address & test_range.mask) == test_range.address) { + // Address is within the range of this mapping. + range = &test_range; + break; + } + } + } + if (!range) { + // Recheck if the pages are still protected (race condition - another thread + // clears the watch we just hit). + // Do this under the lock so we don't introduce another race condition. + auto lock = global_critical_region_.Acquire(); + memory::PageAccess cur_access; + size_t page_length = memory::page_size(); + memory::QueryProtect(fault_host_address, page_length, cur_access); + if (cur_access != memory::PageAccess::kNoAccess && + (!is_write || cur_access != memory::PageAccess::kReadOnly)) { + // Another thread has cleared this watch. Abort. + return true; + } + // The address is not found within any range, so either a write watch or an + // actual access violation. + if (access_violation_callback_) { + return access_violation_callback_(std::move(lock), access_violation_callback_context_, + fault_host_address, is_write); + } + return false; + } + + auto rip = ex->pc(); + auto p = reinterpret_cast(rip); + DecodedLoadStore decoded_load_store; + if (!TryDecodeLoadStore(p, decoded_load_store)) { + REXLOG_ERROR("Unable to decode MMIO load or store instruction at {:p}", + static_cast(p)); + assert_always("Unknown MMIO instruction type"); + return false; + } + + arch::HostThreadContext& thread_context = *ex->thread_context(); + +#if REX_ARCH_ARM64 + // Preserve the base address with the pre- or the post-index offset to write + // it after writing the result (since the base address register and the + // register to load to may be the same, in which case it should receive the + // original base address with the offset). + uintptr_t mem_base_writeback_address = 0; + if (decoded_load_store.mem_has_base && decoded_load_store.mem_base_writeback) { + if (decoded_load_store.mem_base_reg == DecodedLoadStore::kArm64MemBaseRegSp) { + mem_base_writeback_address = thread_context.sp; + } else { + assert_true(decoded_load_store.mem_base_reg <= 30); + mem_base_writeback_address = thread_context.x[decoded_load_store.mem_base_reg]; + } + mem_base_writeback_address += decoded_load_store.mem_base_writeback_offset; + } +#endif // REX_ARCH_ARM64 + + uint8_t value_reg = decoded_load_store.value_reg; + if (decoded_load_store.is_load) { + // Load of a memory value - read from range, swap, and store in the + // register. + uint32_t value = range->read(nullptr, range->callback_context, fault_guest_virtual_address); + if (!decoded_load_store.byte_swap) { + // We swap only if it's not a movbe, as otherwise we are swapping twice. + value = rex::byte_swap(value); + } +#if REX_ARCH_AMD64 + ex->ModifyIntRegister(value_reg) = value; +#elif REX_ARCH_ARM64 + if (value_reg >= DecodedLoadStore::kArm64ValueRegX0 && + value_reg <= (DecodedLoadStore::kArm64ValueRegX0 + 30)) { + ex->ModifyXRegister(value_reg - DecodedLoadStore::kArm64ValueRegX0) = value; + } else if (value_reg >= DecodedLoadStore::kArm64ValueRegV0 && + value_reg <= (DecodedLoadStore::kArm64ValueRegV0 + 31)) { + ex->ModifyVRegister(value_reg - DecodedLoadStore::kArm64ValueRegV0).u32[0] = value; + } else { + assert_true(value_reg == DecodedLoadStore::kArm64ValueRegZero); + // Register write is ignored for X31. + } +#else +#error Register value writing not implemented for the target CPU architecture. +#endif // REX_ARCH + } else { + // Store of a register value - read register, swap, write to range. + uint32_t value; + if (decoded_load_store.is_constant) { + value = uint32_t(decoded_load_store.constant); + } else { +#if REX_ARCH_AMD64 + value = uint32_t(thread_context.int_registers[value_reg]); +#elif REX_ARCH_ARM64 + if (value_reg >= DecodedLoadStore::kArm64ValueRegX0 && + value_reg <= (DecodedLoadStore::kArm64ValueRegX0 + 30)) { + value = uint32_t(thread_context.x[value_reg - DecodedLoadStore::kArm64ValueRegX0]); + } else if (value_reg >= DecodedLoadStore::kArm64ValueRegV0 && + value_reg <= (DecodedLoadStore::kArm64ValueRegV0 + 31)) { + value = thread_context.v[value_reg - DecodedLoadStore::kArm64ValueRegV0].u32[0]; + } else { + assert_true(value_reg == DecodedLoadStore::kArm64ValueRegZero); + value = 0; + } +#else +#error Register value reading not implemented for the target CPU architecture. +#endif // REX_ARCH + if (!decoded_load_store.byte_swap) { + // We swap only if it's not a movbe, as otherwise we are swapping twice. + value = rex::byte_swap(value); + } + } + range->write(nullptr, range->callback_context, fault_guest_virtual_address, value); + } + +#if REX_ARCH_ARM64 + // Write the base address with the pre- or the post-index offset, overwriting + // the register to load to if it's the same. + if (decoded_load_store.mem_has_base && decoded_load_store.mem_base_writeback) { + if (decoded_load_store.mem_base_reg == DecodedLoadStore::kArm64MemBaseRegSp) { + thread_context.sp = mem_base_writeback_address; + } else { + assert_true(decoded_load_store.mem_base_reg <= 30); + ex->ModifyXRegister(decoded_load_store.mem_base_reg) = mem_base_writeback_address; + } + } +#endif // REX_ARCH_ARM64 + + // Advance RIP to the next instruction so that we resume properly. + ex->set_resume_pc(rip + decoded_load_store.length); + + return true; +} + +} // namespace rex::runtime diff --git a/src/system/module.cpp b/src/system/module.cpp new file mode 100644 index 0000000..00832f1 --- /dev/null +++ b/src/system/module.cpp @@ -0,0 +1,98 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include + +namespace rex::runtime { + +Module::Module(FunctionDispatcher* function_dispatcher) + : function_dispatcher_(function_dispatcher), + memory_(function_dispatcher ? function_dispatcher->memory() : nullptr) {} + +Module::~Module() = default; + +bool Module::ContainsAddress(uint32_t address) { + (void)address; + return true; +} + +// Binary introspection default implementations +std::span Module::binary_sections() const { + return binary_sections_; +} + +const BinarySection* Module::FindSectionByName(std::string_view name) const { + for (const auto& sec : binary_sections_) { + if (sec.name == name) + return &sec; + } + return nullptr; +} + +const BinarySection* Module::FindSectionByAddress(uint32_t address) const { + for (const auto& sec : binary_sections_) { + if (address >= sec.virtual_address && address < sec.virtual_address + sec.virtual_size) { + return &sec; + } + } + return nullptr; +} + +std::span Module::binary_symbols() const { + return binary_symbols_; +} + +const BinarySymbol* Module::FindSymbolByName(std::string_view name) const { + for (const auto& sym : binary_symbols_) { + if (sym.name == name) + return &sym; + } + return nullptr; +} + +const BinarySymbol* Module::FindSymbolByAddress(uint32_t address) const { + for (const auto& sym : binary_symbols_) { + if (sym.address == address) + return &sym; + } + return nullptr; +} + +const BinarySymbol* Module::FindSymbolContainingAddress(uint32_t address) const { + for (const auto& sym : binary_symbols_) { + if (address >= sym.address && address < sym.address + sym.size) { + return &sym; + } + } + return nullptr; +} + +void Module::AddBinarySymbol(BinarySymbol symbol) { + binary_symbols_.push_back(std::move(symbol)); +} + +void Module::ClearBinarySymbols() { + binary_symbols_.clear(); +} + +bool Module::isExecutableSection(uint32_t address) const { + for (const auto& sec : binary_sections_) { + if (address >= sec.virtual_address && address < sec.virtual_address + sec.virtual_size) { + return sec.executable; + } + } + return false; +} + +} // namespace rex::runtime diff --git a/src/system/ppc_types.cpp b/src/system/ppc_types.cpp new file mode 100644 index 0000000..ddc6bd5 --- /dev/null +++ b/src/system/ppc_types.cpp @@ -0,0 +1,12 @@ +/** + * @file system/ppc_types.cpp + * @brief PPC thread-local state definitions + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include diff --git a/src/system/runtime.cpp b/src/system/runtime.cpp new file mode 100644 index 0000000..f9eac23 --- /dev/null +++ b/src/system/runtime.cpp @@ -0,0 +1,362 @@ +/** + * @file runtime/runtime.cpp + * @brief Runtime subsystem implementation + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include +#include +#include +#include +#include +#include +#include +#include // PPCFuncMapping +#include // SEH exception support +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_STRING(game_data_root, "", "Runtime", "Override game data path"); +REXCVAR_DEFINE_STRING(user_data_root, "", "Runtime", "Override user data path"); +REXCVAR_DEFINE_STRING(update_data_root, "", "Runtime", "Override update data path"); +REXCVAR_DEFINE_STRING(cache_path, "", "Runtime", "Override shader cache path"); + +namespace rex { + +// Static instance for global access +Runtime* Runtime::instance_ = nullptr; + +Runtime* Runtime::instance() { + return instance_; +} + +Runtime::Runtime(const std::filesystem::path& game_data_root, + const std::filesystem::path& user_data_root, + const std::filesystem::path& update_data_root, + const std::filesystem::path& cache_root) + : game_data_root_(game_data_root), + user_data_root_(user_data_root.empty() ? game_data_root : user_data_root), + update_data_root_(update_data_root), + cache_root_(cache_root) {} + +Runtime::~Runtime() { + Shutdown(); +} + +X_STATUS Runtime::Setup(RuntimeConfig config) { + if (instance_ != nullptr) { + REXSYS_ERROR("Runtime::Setup() called but global instance already exists"); + return X_STATUS_UNSUCCESSFUL; + } + instance_ = this; + + auto fail = [this](X_STATUS status, std::string_view reason) { + REXSYS_ERROR("Runtime::Setup failed: {}", reason); + Shutdown(); + return status; + }; + + // Start profiler (Tracy network threads, counter init) + rex::perf::Profiler::Startup(); + + // Initialize SEH exception support for hardware exception handling + rex::initialize_seh(); + + // Initialize clock + chrono::Clock::set_guest_tick_frequency(50000000); + chrono::Clock::set_guest_system_time_base(chrono::Clock::QueryHostSystemTime()); + chrono::Clock::set_guest_time_scalar(1.0); + + // Enable threading affinity configuration + thread::EnableAffinityConfiguration(); + + tool_mode_ = config.tool_mode; + + // Create memory system first + memory_ = std::make_unique(); + if (!memory_->Initialize()) { + return fail(X_STATUS_UNSUCCESSFUL, "memory init failed"); + } + + export_resolver_ = std::make_unique(); + + function_dispatcher_ = + std::make_unique(memory_.get(), export_resolver_.get()); + REXSYS_INFO("FunctionDispatcher initialized"); + + // Create virtual file system + file_system_ = std::make_unique(); + + // Create kernel state - this sets the global singleton + kernel_state_ = std::make_unique(this); + + // Initialize input from injected config + if (config.input_factory) { + input_system_ = config.input_factory(tool_mode_); + if (input_system_) { + X_STATUS input_status = input_system_->Setup(); + if (XFAILED(input_status)) { + REXSYS_WARN("Failed to initialize input system (status {:08X}) - input disabled", + input_status); + input_system_.reset(); + } else { + REXSYS_INFO("Input system initialized"); + } + } + } + + // HLE kernel modules and apps. + if (config.kernel_init) { + config.kernel_init(this, kernel_state_.get()); + } + + // Initialize the APU (Audio Processing Unit) from injected config + if (config.audio_factory) { + audio_system_ = config.audio_factory(function_dispatcher_.get()); + if (audio_system_) { + X_STATUS audio_status = audio_system_->Setup(kernel_state_.get()); + if (XFAILED(audio_status)) { + REXSYS_WARN("Failed to initialize audio system (status {:08X}) - audio disabled", + audio_status); + audio_system_.reset(); + } else { + REXSYS_INFO("Audio system initialized"); + } + } + } + + // Set up VFS: game_data_root as game:/d:, update_data_root as update: + if (!SetupVfs()) { + return fail(X_STATUS_UNSUCCESSFUL, "VFS setup failed"); + } + + // Skip GPU initialization in tool mode (for analysis tools like codegen) + if (tool_mode_) { + REXSYS_INFO("Runtime initialized in tool mode (no GPU)"); + setup_complete_ = true; + return X_STATUS_SUCCESS; + } + + // Initialize GPU from injected config + if (config.graphics) { + graphics_system_ = std::move(config.graphics); + bool with_presentation = (app_context_ != nullptr); + X_STATUS gpu_status = graphics_system_->Setup(function_dispatcher_.get(), kernel_state_.get(), + app_context_, with_presentation); + if (XFAILED(gpu_status)) { + return fail(gpu_status, "GPU setup failed"); + } + REXSYS_INFO("GPU system initialized (presentation={})", with_presentation); + } else { + REXSYS_INFO("Runtime initialized without graphics system (native rendering mode)"); + } + + REXSYS_INFO("Runtime initialized successfully"); + setup_complete_ = true; + return X_STATUS_SUCCESS; +} + +X_STATUS Runtime::Setup(const rex::PPCImageInfo& image_info, RuntimeConfig config) { + X_STATUS status = Setup(std::move(config)); + if (status != X_STATUS_SUCCESS) { + return status; + } + + if (!function_dispatcher_->InitializeFunctionTable(image_info.code_base, image_info.code_size, + image_info.image_base, image_info.image_size, + /*is_entrypoint=*/true)) { + REXSYS_ERROR("Failed to initialize function table"); + Shutdown(); + return X_STATUS_UNSUCCESSFUL; + } + + if (image_info.func_mappings) { + int count = 0; + int duplicates = 0; + int rejected = 0; + for (int i = 0; image_info.func_mappings[i].guest != 0; ++i) { + uint32_t guest = static_cast(image_info.func_mappings[i].guest); + auto* host = image_info.func_mappings[i].host; + if (!host) { + continue; + } + if (function_dispatcher_->GetFunction(guest)) { + REXSYS_WARN("func_mappings: duplicate guest address {:08X}", guest); + ++duplicates; + } + if (!function_dispatcher_->SetFunction(guest, host)) { + ++rejected; + } else { + ++count; + } + } + REXSYS_DEBUG("Registered {} recompiled functions ({} duplicates, {} rejected)", count, + duplicates, rejected); + if (rejected > 0) { + REXSYS_ERROR("PPCImageInfo registration: {} func_mappings entries rejected", rejected); + Shutdown(); + return X_STATUS_UNSUCCESSFUL; + } + } + + REXSYS_DEBUG("Runtime setup complete (code: {:08X}-{:08X}, image: {:08X}-{:08X})", + image_info.code_base, image_info.code_base + image_info.code_size, + image_info.image_base, image_info.image_base + image_info.image_size); + return X_STATUS_SUCCESS; +} + +void Runtime::Shutdown() { + if (!instance_ && !setup_complete_ && !memory_) { + return; + } + + if (instance_ == this) { + instance_ = nullptr; + } + + if (graphics_system_) { + graphics_system_->Shutdown(); + graphics_system_.reset(); + } + if (audio_system_) { + audio_system_->Shutdown(); + audio_system_.reset(); + } + if (input_system_) { + input_system_->Shutdown(); + input_system_.reset(); + } + kernel_state_.reset(); + function_dispatcher_.reset(); + export_resolver_.reset(); + file_system_.reset(); + memory_.reset(); + + rex::perf::Profiler::Shutdown(); + setup_complete_ = false; +} + +uint8_t* Runtime::virtual_membase() const { + return memory_ ? memory_->virtual_membase() : nullptr; +} + +bool Runtime::SetupVfs() { + if (game_data_root_.empty()) { + REXSYS_WARN("Runtime::SetupVfs: No game_data_root specified, skipping VFS setup"); + return true; + } + + auto abs_game_root = std::filesystem::absolute(game_data_root_); + if (!std::filesystem::exists(abs_game_root)) { + REXSYS_ERROR("Runtime::SetupVfs: game_data_root does not exist: {}", abs_game_root.string()); + return false; + } + + // Mount game_data_root as \Device\Harddisk0\Partition1 + auto mount_path = "\\Device\\Harddisk0\\Partition1"; + auto device = std::make_unique( + mount_path, abs_game_root, !REXCVAR_GET(allow_game_relative_writes)); + if (!device->Initialize()) { + REXSYS_ERROR("Runtime::SetupVfs: Failed to initialize host path device"); + return false; + } + if (!file_system_->RegisterDevice(std::move(device))) { + REXSYS_ERROR("Runtime::SetupVfs: Failed to register host path device"); + return false; + } + REXSYS_INFO(" Mounted {} at {}", abs_game_root.string(), mount_path); + + // Register symbolic links for game: and D: + file_system_->RegisterSymbolicLink("game:", mount_path); + file_system_->RegisterSymbolicLink("d:", mount_path); + REXSYS_DEBUG(" Registered symbolic links: game:, d:"); + + // Mount update_data_root as update:\ if provided + if (!update_data_root_.empty()) { + auto abs_update_root = std::filesystem::absolute(update_data_root_); + if (std::filesystem::exists(abs_update_root)) { + auto update_mount = "\\Device\\Harddisk0\\PartitionUpdate"; + auto update_device = + std::make_unique(update_mount, abs_update_root, true); + if (update_device->Initialize() && file_system_->RegisterDevice(std::move(update_device))) { + file_system_->RegisterSymbolicLink("update:", update_mount); + REXSYS_INFO(" Mounted {} at update:", abs_update_root.string()); + } + } + } + + // Setup NullDevice for raw HDD partition accesses + // Cache/STFC code baked into games tries reading/writing to these + // Using a NullDevice returns success to all IO requests, allowing games + // to believe cache/raw disk was accessed successfully. + // NOTE: Must be registered AFTER Partition1 so Partition1 requests don't + // go to NullDevice (VFS resolves devices in registration order) + auto null_paths = {std::string("\\Partition0"), std::string("\\Cache0"), std::string("\\Cache1")}; + auto null_device = + std::make_unique("\\Device\\Harddisk0", null_paths); + if (null_device->Initialize()) { + file_system_->RegisterDevice(std::move(null_device)); + REXSYS_DEBUG(" Registered NullDevice for \\Device\\Harddisk0\\{{Partition0,Cache0,Cache1}}"); + } + + // NOTE: Do NOT register a device for cache: paths + // Games handle "device not found" gracefully but don't handle actual device + // errors (like NAME_COLLISION) well. Let cache: fail cleanly. + + return true; +} + +X_STATUS Runtime::LoadXexImage(const std::string_view module_path) { + REXSYS_INFO("Loading XEX image: {}", std::string(module_path)); + + auto module = system::object_ref(new system::UserModule(kernel_state_.get())); + X_STATUS status = module->LoadFromFile(module_path); + if (XFAILED(status)) { + REXSYS_ERROR("Runtime::LoadXexImage: Failed to load module, status {:08X}", status); + return status; + } + + kernel_state_->SetExecutableModule(module); + REXSYS_DEBUG(" XEX image loaded successfully"); + return X_STATUS_SUCCESS; +} + +system::object_ref Runtime::PrepareModuleLaunch() { + auto executable = kernel_state_->GetExecutableModule(); + if (!executable) { + REXSYS_ERROR("Runtime::PrepareModuleLaunch: No executable module loaded"); + return nullptr; + } + + auto thread = kernel_state_->PrepareModuleLaunch(executable); + if (!thread) { + REXSYS_ERROR("Runtime::PrepareModuleLaunch: Failed to prepare module"); + return nullptr; + } + + REXSYS_DEBUG(" Module prepared on thread '{}'", thread->name()); + return thread; +} + +system::object_ref Runtime::LaunchModule() { + auto thread = PrepareModuleLaunch(); + if (thread) { + thread->Resume(); + REXSYS_DEBUG(" Module launched on thread '{}'", thread->name()); + } + return thread; +} + +} // namespace rex diff --git a/src/system/shared_library.cpp b/src/system/shared_library.cpp new file mode 100644 index 0000000..2de192b --- /dev/null +++ b/src/system/shared_library.cpp @@ -0,0 +1,121 @@ +/** + * @file system/shared_library.cpp + * @brief Platform-agnostic shared library loader + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include + +#include + +#include +#include +#include + +#ifdef _WIN32 +#include +#else +#include +#endif + +namespace rex::system { + +namespace { + +#ifdef _WIN32 +std::string FormatLastError(DWORD err) { + char* buffer = nullptr; + DWORD len = FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast(&buffer), 0, + nullptr); + std::string msg = (len && buffer) ? std::string(buffer, len) : std::string{}; + if (buffer) { + LocalFree(buffer); + } + while (!msg.empty() && (msg.back() == '\n' || msg.back() == '\r' || msg.back() == ' ')) { + msg.pop_back(); + } + return msg.empty() ? fmt::format("error {}", err) : fmt::format("{} (error {})", msg, err); +} +#endif + +} // namespace + +SharedLibrary::~SharedLibrary() { + Close(); +} + +SharedLibrary::SharedLibrary(SharedLibrary&& other) noexcept : handle_(other.handle_) { + other.handle_ = nullptr; +} + +SharedLibrary& SharedLibrary::operator=(SharedLibrary&& other) noexcept { + if (this != &other) { + Close(); + handle_ = other.handle_; + other.handle_ = nullptr; + } + return *this; +} + +bool SharedLibrary::Load(const std::string& name) { + assert_true(handle_ == nullptr); + if (handle_) { + REXSYS_ERROR("SharedLibrary::Load called over a live handle"); + return false; + } + auto exe_dir = rex::filesystem::GetExecutableFolder(); +#ifdef _WIN32 + std::string full_name = (exe_dir / (name + ".dll")).string(); + handle_ = LoadLibraryA(full_name.c_str()); + if (!handle_) { + DWORD err = GetLastError(); + REXSYS_ERROR("Failed to load shared library '{}': {}", full_name, FormatLastError(err)); + return false; + } +#else + std::string full_name = (exe_dir / ("lib" + name + ".so")).string(); + handle_ = dlopen(full_name.c_str(), RTLD_NOW); + if (!handle_) { + const char* err = dlerror(); + REXSYS_ERROR("Failed to load shared library '{}': {}", full_name, err ? err : "unknown"); + return false; + } +#endif + return true; +} + +void* SharedLibrary::GetSymbol(const char* name) { + if (!handle_) + return nullptr; +#ifdef _WIN32 + return reinterpret_cast(GetProcAddress(static_cast(handle_), name)); +#else + return dlsym(handle_, name); +#endif +} + +void SharedLibrary::Close() { + if (!handle_) { + return; + } +#ifdef _WIN32 + if (!FreeLibrary(static_cast(handle_))) { + REXSYS_ERROR("FreeLibrary failed: {}", FormatLastError(GetLastError())); + } +#else + if (dlclose(handle_) != 0) { + const char* err = dlerror(); + REXSYS_ERROR("dlclose failed: {}", err ? err : "unknown"); + } +#endif + handle_ = nullptr; +} + +} // namespace rex::system diff --git a/src/system/thread.cpp b/src/system/thread.cpp new file mode 100644 index 0000000..4e852f5 --- /dev/null +++ b/src/system/thread.cpp @@ -0,0 +1,33 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2017 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +namespace rex::runtime { + +thread_local Thread* Thread::current_thread_ = nullptr; + +Thread::Thread() {} +Thread::~Thread() {} + +bool Thread::IsInThread() { + return current_thread_ != nullptr; +} + +Thread* Thread::GetCurrentThread() { + return current_thread_; +} +uint32_t Thread::GetCurrentThreadId() { + return Thread::GetCurrentThread()->thread_state()->thread_id(); +} + +} // namespace rex::runtime \ No newline at end of file diff --git a/src/system/thread_state.cpp b/src/system/thread_state.cpp new file mode 100644 index 0000000..eb352a0 --- /dev/null +++ b/src/system/thread_state.cpp @@ -0,0 +1,65 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include +#include + +namespace rex::runtime { + +thread_local ThreadState* thread_state_ = nullptr; + +ThreadState::ThreadState(uint32_t thread_id, uint32_t stack_base, uint32_t pcr_address, + memory::Memory* memory) + : memory_(memory), pcr_address_(pcr_address), thread_id_(thread_id) { + if (thread_id_ == UINT_MAX) { + // System thread. Assign the system thread ID with a high bit + // set so people know what's up. + uint32_t system_thread_handle = rex::thread::current_thread_system_id(); + thread_id_ = 0x80000000 | system_thread_handle; + } + + // Initialize the PPCContext (context_ already points to context_storage_) + std::memset(context_, 0, sizeof(::PPCContext)); + + // Set initial registers + context_->r1.u64 = stack_base; // Stack pointer + context_->r13.u64 = pcr_address; // PCR address + + // Note(tomc): the rexglue abi passes memory base via 'base' parameter to each function call, + // so we don't need to store it in the context like JIT did. +} + +ThreadState::~ThreadState() { + if (thread_state_ == this) { + thread_state_ = nullptr; + } +} + +void ThreadState::Bind(ThreadState* thread_state) { + thread_state_ = thread_state; +} + +ThreadState* ThreadState::Get() { + return thread_state_; +} + +uint32_t ThreadState::GetThreadID() { + auto* thread_state = Get(); + return thread_state ? thread_state->thread_id_ : 0xFFFFFFFF; +} + +} // namespace rex::runtime diff --git a/src/system/user_module.cpp b/src/system/user_module.cpp new file mode 100644 index 0000000..6255e3c --- /dev/null +++ b/src/system/user_module.cpp @@ -0,0 +1,387 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(xex_apply_patches, false, "Kernel", + "Search for and apply XEX patches (path + 'p') on module load"); + +namespace rex::system { + +UserModule::UserModule(KernelState* kernel_state) + : XModule(kernel_state, ModuleType::kUserModule) {} + +UserModule::~UserModule() { + Unload(); +} + +uint32_t UserModule::title_id() const { + if (module_format_ != kModuleFormatXex) { + return 0; + } + auto header = xex_header(); + for (uint32_t i = 0; i < header->header_count; i++) { + auto& opt_header = header->headers[i]; + if (opt_header.key == XEX_HEADER_EXECUTION_INFO) { + auto opt_header_ptr = reinterpret_cast(header) + opt_header.offset; + auto opt_exec_info = reinterpret_cast(opt_header_ptr); + return static_cast(opt_exec_info->title_id); + } + } + return 0; +} + +X_STATUS UserModule::LoadFromFile(const std::string_view path) { + X_STATUS result = X_STATUS_UNSUCCESSFUL; + + // Resolve the file to open. + // TODO(benvanik): make this code shared? + auto fs_entry = kernel_state_->file_system()->ResolvePath(path); + if (!fs_entry) { + REXSYS_ERROR("File not found: {}", path); + return X_STATUS_NO_SUCH_FILE; + } + + path_ = fs_entry->absolute_path(); + name_ = rex::string::utf8_find_base_name_from_guest_path(path_); + + // If the FS supports mapping, map the file in and load from that. + if (fs_entry->can_map()) { + // Map. + auto mmap = fs_entry->OpenMapped(memory::MappedMemory::Mode::kRead); + if (!mmap) { + return result; + } + + // Load the module. + result = LoadFromMemory(mmap->data(), mmap->size()); + } else { + std::vector buffer(fs_entry->size()); + + // Open file for reading. + rex::filesystem::File* file = nullptr; + result = fs_entry->Open(rex::filesystem::FileAccess::kGenericRead, &file); + if (XFAILED(result)) { + return result; + } + + // Read entire file into memory. + // Ugh. + size_t bytes_read = 0; + result = file->ReadSync(std::span(buffer), 0, &bytes_read); + if (XFAILED(result)) { + return result; + } + + // Load the module. + result = LoadFromMemory(buffer.data(), bytes_read); + + // Close the file. + file->Destroy(); + } + + // Only XEX returns X_STATUS_PENDING + if (result != X_STATUS_PENDING) { + return result; + } + + if (REXCVAR_GET(xex_apply_patches)) { + // Search for xexp patch file + auto patch_entry = kernel_state_->file_system()->ResolvePath(path_ + "p"); + + if (patch_entry) { + auto patch_path = patch_entry->absolute_path(); + + REXSYS_DEBUG("Loading XEX patch from {}", patch_path); + + auto patch_module = object_ref(new UserModule(kernel_state_)); + result = patch_module->LoadFromFile(patch_path); + if (!result) { + result = patch_module->xex_module()->ApplyPatch(xex_module()); + if (result) { + REXSYS_ERROR("Failed to apply XEX patch, code: {}", result); + } + } else { + REXSYS_ERROR("Failed to load XEX patch, code: {}", result); + } + + if (result) { + return X_STATUS_UNSUCCESSFUL; + } + } + } + + return LoadXexContinue(); +} + +X_STATUS UserModule::LoadFromMemory(const void* addr, const size_t length) { + auto* dispatcher = kernel_state_->function_dispatcher(); + + // Detect format by magic bytes + be magic; + magic.value = memory::load(addr); + + if (magic == runtime::kXEX2Signature || magic == runtime::kXEX1Signature) { + module_format_ = kModuleFormatXex; + } else if (magic == runtime::kElfSignature) { + module_format_ = kModuleFormatElf; + } else { + REXSYS_ERROR("Unknown module magic: {:08X}", uint32_t(magic)); + return X_STATUS_NOT_IMPLEMENTED; + } + + if (module_format_ == kModuleFormatXex) { + // Create XexModule to parse and load the XEX image into guest memory + auto xex_module = new runtime::XexModule(dispatcher, kernel_state_); + if (!xex_module->Load(name_, path_, addr, length)) { + delete xex_module; + return X_STATUS_UNSUCCESSFUL; + } + + processor_module_ = xex_module; + + // Continue to LoadXexContinue (returns X_STATUS_PENDING per Xenia convention) + return X_STATUS_PENDING; + + } else if (module_format_ == kModuleFormatElf) { + // Create ElfModule to parse and load the ELF image into guest memory + auto elf_module = new runtime::ElfModule(dispatcher, kernel_state_); + if (!elf_module->Load(name_, path_, addr, length)) { + delete elf_module; + return X_STATUS_UNSUCCESSFUL; + } + + entry_point_ = elf_module->entry_point(); + stack_size_ = 1024 * 1024; // 1 MB default stack + is_dll_module_ = false; + + processor_module_ = elf_module; + OnLoad(); + return X_STATUS_SUCCESS; // ELF doesn't need LoadXexContinue + } + + return X_STATUS_UNSUCCESSFUL; +} + +X_STATUS UserModule::LoadXexContinue() { + // LoadXexContinue: finishes loading XEX after a patch has been applied (or + // patch wasn't found) + + if (!this->xex_module()) { + return X_STATUS_UNSUCCESSFUL; + } + + // If guest_xex_header is set we must have already loaded the XEX + if (guest_xex_header_) { + return X_STATUS_SUCCESS; + } + + // Finish XexModule load (PE sections/imports/symbols...) + if (!xex_module()->LoadContinue()) { + return X_STATUS_UNSUCCESSFUL; + } + + // Copy the xex2 header into guest memory. + auto header = this->xex_module()->xex_header(); + auto security_header = this->xex_module()->xex_security_info(); + guest_xex_header_ = memory()->SystemHeapAlloc(header->header_size); + + uint8_t* xex_header_ptr = memory()->TranslateVirtual(guest_xex_header_); + std::memcpy(xex_header_ptr, header, header->header_size); + + // Cache some commonly used headers... + this->xex_module()->GetOptHeader(XEX_HEADER_ENTRY_POINT, &entry_point_); + this->xex_module()->GetOptHeader(XEX_HEADER_DEFAULT_STACK_SIZE, &stack_size_); + is_dll_module_ = !!(header->module_flags & XEX_MODULE_DLL_MODULE); + + // Setup the loader data entry + auto ldr_data = memory()->TranslateVirtual(hmodule_ptr_); + + ldr_data->dll_base = 0; // GetProcAddress will read this. + ldr_data->xex_header_base = guest_xex_header_; + ldr_data->full_image_size = security_header->image_size; + ldr_data->image_base = this->xex_module()->base_address(); + ldr_data->entry_point = entry_point_; + + OnLoad(); + + return X_STATUS_SUCCESS; +} + +X_STATUS UserModule::Unload() { + if (module_format_ == kModuleFormatXex && (!processor_module_ || !xex_module()->loaded())) { + // Quick abort. + return X_STATUS_SUCCESS; + } + + if (module_format_ == kModuleFormatXex && processor_module_ && xex_module()->Unload()) { + OnUnload(); + return X_STATUS_SUCCESS; + } + + return X_STATUS_UNSUCCESSFUL; +} + +uint32_t UserModule::GetProcAddressByOrdinal(uint16_t ordinal, uint32_t caller_address) { + uint32_t guest_addr = xex_module()->GetProcAddress(ordinal); + if (!guest_addr || !caller_address) { + return guest_addr; + } + + auto* dispatcher = kernel_state_->function_dispatcher(); + auto* func = dispatcher->GetFunction(guest_addr); + if (!func) { + return guest_addr; + } + + return dispatcher->AllocateThunk(func, caller_address); +} + +uint32_t UserModule::GetProcAddressByName(std::string_view name) { + return xex_module()->GetProcAddress(name); +} + +X_STATUS UserModule::GetSection(const std::string_view name, uint32_t* out_section_data, + uint32_t* out_section_size) { + xex2_opt_resource_info* resource_header = nullptr; + if (!runtime::XexModule::GetOptHeader(xex_header(), XEX_HEADER_RESOURCE_INFO, &resource_header)) { + // No resources. + return X_STATUS_NOT_FOUND; + } + uint32_t count = (resource_header->size - 4) / sizeof(xex2_resource); + for (uint32_t i = 0; i < count; i++) { + auto& res = resource_header->resources[i]; + if (rex::string::utf8_equal_z(name, std::string_view(res.name, 8))) { + // Found! + *out_section_data = res.address; + *out_section_size = res.size; + return X_STATUS_SUCCESS; + } + } + + return X_STATUS_NOT_FOUND; +} + +X_STATUS UserModule::GetOptHeader(xex2_header_keys key, void** out_ptr) { + assert_not_null(out_ptr); + + if (module_format_ == kModuleFormatElf) { + // Quick die. + return X_STATUS_UNSUCCESSFUL; + } + + bool ret = xex_module()->GetOptHeader(key, out_ptr); + if (!ret) { + return X_STATUS_NOT_FOUND; + } + + return X_STATUS_SUCCESS; +} + +X_STATUS UserModule::GetOptHeader(xex2_header_keys key, uint32_t* out_header_guest_ptr) { + if (module_format_ == kModuleFormatElf) { + // Quick die. + return X_STATUS_UNSUCCESSFUL; + } + + auto header = memory()->TranslateVirtual(guest_xex_header_); + if (!header) { + return X_STATUS_UNSUCCESSFUL; + } + return GetOptHeader(memory(), header, key, out_header_guest_ptr); +} + +X_STATUS UserModule::GetOptHeader(const memory::Memory* memory, const xex2_header* header, + xex2_header_keys key, uint32_t* out_header_guest_ptr) { + assert_not_null(out_header_guest_ptr); + uint32_t field_value = 0; + bool field_found = false; + for (uint32_t i = 0; i < header->header_count; i++) { + auto& opt_header = header->headers[i]; + if (opt_header.key != key) { + continue; + } + field_found = true; + switch (opt_header.key & 0xFF) { + case 0x00: + // Return data stored in header value. + field_value = opt_header.value; + break; + case 0x01: + // Return pointer to data stored in header value. + field_value = memory->HostToGuestVirtual(&opt_header.value); + break; + default: + // Data stored at offset to header. + field_value = memory->HostToGuestVirtual(header) + opt_header.offset; + break; + } + break; + } + *out_header_guest_ptr = field_value; + if (!field_found) { + return X_STATUS_NOT_FOUND; + } + return X_STATUS_SUCCESS; +} + +bool UserModule::Save(stream::ByteStream* stream) { + if (!XModule::Save(stream)) { + return false; + } + + // A lot of the information stored on this class can be reconstructed at + // runtime. + + return true; +} + +object_ref UserModule::Restore(KernelState* kernel_state, stream::ByteStream* stream, + const std::string_view path) { + auto module = new UserModule(kernel_state); + + // XModule::Save took care of this earlier... + // TODO: Find a nicer way to represent that here. + if (!module->RestoreObject(stream)) { + return nullptr; + } + + auto result = module->LoadFromFile(path); + if (XFAILED(result)) { + REXSYS_DEBUG("UserModule::Restore LoadFromFile({}) FAILED - code {:08X}", path, result); + return nullptr; + } + + if (!kernel_state->RegisterUserModule(retain_object(module))) { + // Already loaded? + assert_always(); + } + + return object_ref(module); +} + +void UserModule::Dump() { + // TODO(tomc): do we need this? +} + +} // namespace rex::system diff --git a/src/system/util/gameinfo_utils.cpp b/src/system/util/gameinfo_utils.cpp new file mode 100644 index 0000000..dcf5cf1 --- /dev/null +++ b/src/system/util/gameinfo_utils.cpp @@ -0,0 +1,81 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2016 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +namespace rex { +namespace system { +namespace util { + +constexpr memory::fourcc_t kGameInfoExecSignature = memory::make_fourcc("EXEC"); +constexpr memory::fourcc_t kGameInfoCommSignature = memory::make_fourcc("COMM"); +constexpr memory::fourcc_t kGameInfoTitlSignature = memory::make_fourcc("TITL"); + +GameInfoWrapper::GameInfoWrapper(const uint8_t* data, size_t data_size) + : data_(data), data_size_(data_size) { + if (!data) { + return; + } + + const GameInfoBlockHeader* block_header(nullptr); + size_t data_offset(0); + while (data_offset < data_size_) { + block_header = reinterpret_cast(data_ + data_offset); + data_offset += sizeof(GameInfoBlockHeader); + + switch (block_header->magic) { + case kGameInfoExecSignature: + exec_.virtual_titleid = reinterpret_cast(data_ + data_offset); + data_offset += exec_.VirtualTitleIdLength + 1; + exec_.module_name = reinterpret_cast(data_ + data_offset); + data_offset += exec_.ModuleNameLength + 1; + exec_.build_description = reinterpret_cast(data_ + data_offset); + data_offset += exec_.BuildDescriptionLength + 1; + break; + case kGameInfoCommSignature: + assert_true(block_header->block_size == sizeof(GameInfoBlockComm)); + comm_ = reinterpret_cast(data_ + data_offset); + data_offset += block_header->block_size; + break; + case kGameInfoTitlSignature: + assert_true(block_header->block_size == sizeof(GameInfoBlockTitl)); + titl_ = reinterpret_cast(data_ + data_offset); + data_offset += block_header->block_size; + break; + default: + // Unsupported headers + data_ = nullptr; + return; + } + } + + if ((comm_ == nullptr) || (titl_ == nullptr) || (exec_.virtual_titleid == nullptr)) { + data_ = nullptr; + } +} + +uint32_t GameInfo::title_id() const { + return comm_->title_id; +} + +std::string GameInfo::virtual_title_id() const { + size_t virtual_titleid_length(std::strlen(exec_.virtual_titleid)); + return std::string(exec_.virtual_titleid, exec_.virtual_titleid + virtual_titleid_length); +} + +std::string GameInfo::module_name() const { + size_t module_name_length(std::strlen(exec_.module_name)); + return std::string(exec_.module_name, exec_.module_name + module_name_length); +} + +} // namespace util +} // namespace system +} // namespace rex diff --git a/src/system/util/native_list.cpp b/src/system/util/native_list.cpp new file mode 100644 index 0000000..d72ef82 --- /dev/null +++ b/src/system/util/native_list.cpp @@ -0,0 +1,69 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +namespace rex::system::util { + +NativeList::NativeList() = default; + +NativeList::NativeList(memory::Memory* memory) : memory_(memory), head_(kInvalidPointer) {} + +void NativeList::Insert(uint32_t ptr) { + memory::store_and_swap(memory_->TranslateVirtual(ptr + 0), head_); + memory::store_and_swap(memory_->TranslateVirtual(ptr + 4), 0); + if (head_) { + memory::store_and_swap(memory_->TranslateVirtual(head_ + 4), ptr); + } + head_ = ptr; +} + +bool NativeList::IsQueued(uint32_t ptr) { + uint32_t flink = memory::load_and_swap(memory_->TranslateVirtual(ptr + 0)); + uint32_t blink = memory::load_and_swap(memory_->TranslateVirtual(ptr + 4)); + return head_ == ptr || flink || blink; +} + +void NativeList::Remove(uint32_t ptr) { + uint32_t flink = memory::load_and_swap(memory_->TranslateVirtual(ptr + 0)); + uint32_t blink = memory::load_and_swap(memory_->TranslateVirtual(ptr + 4)); + if (ptr == head_) { + head_ = flink; + if (flink) { + memory::store_and_swap(memory_->TranslateVirtual(flink + 4), 0); + } + } else { + if (blink) { + memory::store_and_swap(memory_->TranslateVirtual(blink + 0), flink); + } + if (flink) { + memory::store_and_swap(memory_->TranslateVirtual(flink + 4), blink); + } + } + memory::store_and_swap(memory_->TranslateVirtual(ptr + 0), 0); + memory::store_and_swap(memory_->TranslateVirtual(ptr + 4), 0); +} + +uint32_t NativeList::Shift() { + if (!head_) { + return 0; + } + + uint32_t ptr = head_; + Remove(ptr); + return ptr; +} + +bool NativeList::HasPending() { + return head_ != kInvalidPointer; +} + +} // namespace rex::system::util diff --git a/src/system/util/object_table.cpp b/src/system/util/object_table.cpp new file mode 100644 index 0000000..6fbabd2 --- /dev/null +++ b/src/system/util/object_table.cpp @@ -0,0 +1,410 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include +#include + +namespace rex::system::util { + +ObjectTable::ObjectTable() {} + +ObjectTable::~ObjectTable() { + Reset(); +} + +void ObjectTable::Reset() { + auto global_lock = global_critical_region_.Acquire(); + + // Release all objects. + for (uint32_t n = 0; n < table_capacity_; n++) { + ObjectTableEntry& entry = table_[n]; + if (entry.object) { + entry.object->Release(); + } + } + + table_capacity_ = 0; + last_free_entry_ = 0; + free(table_); + table_ = nullptr; +} + +X_STATUS ObjectTable::FindFreeSlot(uint32_t* out_slot) { + // Find a free slot. + uint32_t slot = last_free_entry_; + uint32_t scan_count = 0; + while (scan_count < table_capacity_) { + ObjectTableEntry& entry = table_[slot]; + if (!entry.object) { + *out_slot = slot; + return X_STATUS_SUCCESS; + } + scan_count++; + slot = (slot + 1) % table_capacity_; + if (slot == 0) { + // Never allow 0 handles. + scan_count++; + slot++; + } + } + + // Table out of slots, expand. + uint32_t new_table_capacity = std::max(16 * 1024u, table_capacity_ * 2); + if (!Resize(new_table_capacity)) { + return X_STATUS_NO_MEMORY; + } + + // Never allow 0 handles. + slot = ++last_free_entry_; + *out_slot = slot; + + return X_STATUS_SUCCESS; +} + +bool ObjectTable::Resize(uint32_t new_capacity) { + uint32_t new_size = new_capacity * sizeof(ObjectTableEntry); + uint32_t old_size = table_capacity_ * sizeof(ObjectTableEntry); + auto new_table = reinterpret_cast(realloc(table_, new_size)); + if (!new_table) { + return false; + } + + // Zero out new entries. + if (new_size > old_size) { + std::memset(reinterpret_cast(new_table) + old_size, 0, new_size - old_size); + } + + last_free_entry_ = table_capacity_; + table_capacity_ = new_capacity; + table_ = new_table; + + return true; +} + +X_STATUS ObjectTable::AddHandle(XObject* object, X_HANDLE* out_handle) { + X_STATUS result = X_STATUS_SUCCESS; + + uint32_t handle = 0; + { + auto global_lock = global_critical_region_.Acquire(); + + // Find a free slot. + uint32_t slot = 0; + result = FindFreeSlot(&slot); + + // Stash. + if (XSUCCEEDED(result)) { + ObjectTableEntry& entry = table_[slot]; + entry.object = object; + entry.handle_ref_count = 1; + handle = XObject::kHandleBase + (slot << 2); + object->handles().push_back(handle); + + // Retain so long as the object is in the table. + object->Retain(); + + REXSYS_NOISY_DEBUG("Added handle:{:08X} for {}", handle, typeid(*object).name()); + } + } + + if (XSUCCEEDED(result)) { + if (out_handle) { + *out_handle = handle; + } + } + + return result; +} + +X_STATUS ObjectTable::DuplicateHandle(X_HANDLE handle, X_HANDLE* out_handle) { + X_STATUS result = X_STATUS_SUCCESS; + handle = TranslateHandle(handle); + + XObject* object = LookupObject(handle, false); + if (object) { + result = AddHandle(object, out_handle); + object->Release(); // Release the ref that LookupObject took + } else { + result = X_STATUS_INVALID_HANDLE; + } + + return result; +} + +X_STATUS ObjectTable::RetainHandle(X_HANDLE handle) { + auto global_lock = global_critical_region_.Acquire(); + + ObjectTableEntry* entry = LookupTable(handle); + if (!entry) { + return X_STATUS_INVALID_HANDLE; + } + + entry->handle_ref_count++; + return X_STATUS_SUCCESS; +} + +X_STATUS ObjectTable::ReleaseHandle(X_HANDLE handle) { + auto global_lock = global_critical_region_.Acquire(); + + ObjectTableEntry* entry = LookupTable(handle); + if (!entry) { + return X_STATUS_INVALID_HANDLE; + } + + if (--entry->handle_ref_count == 0) { + // No more references. Remove it from the table. + return RemoveHandle(handle); + } + + // FIXME: Return a status code telling the caller it wasn't released + // (but not a failure code) + return X_STATUS_SUCCESS; +} + +X_STATUS ObjectTable::RemoveHandle(X_HANDLE handle) { + X_STATUS result = X_STATUS_SUCCESS; + + handle = TranslateHandle(handle); + if (!handle) { + return X_STATUS_INVALID_HANDLE; + } + + ObjectTableEntry* entry = LookupTable(handle); + if (!entry) { + return X_STATUS_INVALID_HANDLE; + } + + auto global_lock = global_critical_region_.Acquire(); + if (entry->object) { + auto object = entry->object; + entry->object = nullptr; + assert_zero(entry->handle_ref_count); + entry->handle_ref_count = 0; + + // Walk the object's handles and remove this one. + auto handle_entry = std::find(object->handles().begin(), object->handles().end(), handle); + if (handle_entry != object->handles().end()) { + object->handles().erase(handle_entry); + } + + REXSYS_NOISY_DEBUG("Removed handle:{:08X} for {}", handle, typeid(*object).name()); + + // Remove object name from mapping to prevent naming collision. + if (!object->name().empty()) { + RemoveNameMapping(object->name()); + } + // Release now that the object has been removed from the table. + object->Release(); + } + + return X_STATUS_SUCCESS; +} + +std::vector> ObjectTable::GetAllObjects() { + auto lock = global_critical_region_.Acquire(); + std::vector> results; + + for (uint32_t slot = 0; slot < table_capacity_; slot++) { + auto& entry = table_[slot]; + if (entry.object && std::find(results.begin(), results.end(), entry.object) == results.end()) { + entry.object->Retain(); + results.push_back(object_ref(entry.object)); + } + } + + return results; +} + +void ObjectTable::PurgeAllObjects() { + auto lock = global_critical_region_.Acquire(); + for (uint32_t slot = 0; slot < table_capacity_; slot++) { + auto& entry = table_[slot]; + if (entry.object && !entry.object->is_host_object()) { + entry.handle_ref_count = 0; + entry.object->Release(); + + entry.object = nullptr; + } + } +} + +ObjectTable::ObjectTableEntry* ObjectTable::LookupTable(X_HANDLE handle) { + handle = TranslateHandle(handle); + if (!handle) { + return nullptr; + } + + auto global_lock = global_critical_region_.Acquire(); + + // Lower 2 bits are ignored. + uint32_t slot = GetHandleSlot(handle); + if (slot < table_capacity_) { + return &table_[slot]; + } + + return nullptr; +} + +// Generic lookup +template <> +object_ref ObjectTable::LookupObject(X_HANDLE handle) { + auto object = ObjectTable::LookupObject(handle, false); + auto result = object_ref(reinterpret_cast(object)); + return result; +} + +XObject* ObjectTable::LookupObject(X_HANDLE handle, bool already_locked) { + handle = TranslateHandle(handle); + if (!handle) { + return nullptr; + } + + XObject* object = nullptr; + if (!already_locked) { + global_critical_region_.mutex().lock(); + } + + // Lower 2 bits are ignored. + uint32_t slot = GetHandleSlot(handle); + + // Verify slot. + if (slot < table_capacity_) { + ObjectTableEntry& entry = table_[slot]; + if (entry.object) { + object = entry.object; + } + } + + // Retain the object pointer. + if (object) { + object->Retain(); + } + + if (!already_locked) { + global_critical_region_.mutex().unlock(); + } + + return object; +} + +void ObjectTable::GetObjectsByType(XObject::Type type, std::vector>* results) { + auto global_lock = global_critical_region_.Acquire(); + for (uint32_t slot = 0; slot < table_capacity_; ++slot) { + auto& entry = table_[slot]; + if (entry.object) { + if (entry.object->type() == type) { + entry.object->Retain(); + results->push_back(object_ref(entry.object)); + } + } + } +} + +X_HANDLE ObjectTable::TranslateHandle(X_HANDLE handle) { + if (handle == 0xFFFFFFFF) { + // CurrentProcess + // assert_always(); + return 0; + } else if (handle == 0xFFFFFFFE) { + // CurrentThread + return XThread::GetCurrentThreadHandle(); + } else { + return handle; + } +} + +X_STATUS ObjectTable::AddNameMapping(const std::string_view name, X_HANDLE handle) { + std::lock_guard name_lock(name_mutex_); + if (name_table_.count(string::string_key_case(name))) { + return X_STATUS_OBJECT_NAME_COLLISION; + } + name_table_.insert({string::string_key_case::create(name), handle}); + return X_STATUS_SUCCESS; +} + +void ObjectTable::RemoveNameMapping(const std::string_view name) { + // Names are case-insensitive. + std::lock_guard name_lock(name_mutex_); + auto it = name_table_.find(string::string_key_case(name)); + if (it != name_table_.end()) { + name_table_.erase(it); + } +} + +X_STATUS ObjectTable::GetObjectByName(const std::string_view name, X_HANDLE* out_handle) { + // Names are case-insensitive. + // Look up handle under name lock only -- do NOT hold name_mutex_ while + // acquiring global lock (RemoveHandle takes global -> name ordering). + X_HANDLE handle; + { + std::lock_guard name_lock(name_mutex_); + auto it = name_table_.find(string::string_key_case(name)); + if (it == name_table_.end()) { + *out_handle = X_INVALID_HANDLE_VALUE; + return X_STATUS_OBJECT_NAME_NOT_FOUND; + } + handle = it->second; + } + *out_handle = handle; + + // Retain under global lock via normal LookupObject path. + // The handle may have been removed between releasing name_mutex_ and + // acquiring global lock -- LookupObject returns nullptr in that case. + auto obj = LookupObject(handle, false); + if (obj) { + obj->RetainHandle(); + obj->Release(); + } + + return X_STATUS_SUCCESS; +} + +bool ObjectTable::Save(stream::ByteStream* stream) { + stream->Write(table_capacity_); + for (uint32_t i = 0; i < table_capacity_; i++) { + auto& entry = table_[i]; + stream->Write(entry.handle_ref_count); + } + + return true; +} + +bool ObjectTable::Restore(stream::ByteStream* stream) { + Resize(stream->Read()); + for (uint32_t i = 0; i < table_capacity_; i++) { + auto& entry = table_[i]; + // entry.object = nullptr; + entry.handle_ref_count = stream->Read(); + } + + return true; +} + +X_STATUS ObjectTable::RestoreHandle(X_HANDLE handle, XObject* object) { + uint32_t slot = GetHandleSlot(handle); + assert_true(table_capacity_ > slot); + + if (table_capacity_ > slot) { + auto& entry = table_[slot]; + entry.object = object; + object->Retain(); + } + + return X_STATUS_SUCCESS; +} + +} // namespace rex::system::util diff --git a/src/system/util/xdbf_utils.cpp b/src/system/util/xdbf_utils.cpp new file mode 100644 index 0000000..8250565 --- /dev/null +++ b/src/system/util/xdbf_utils.cpp @@ -0,0 +1,138 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2016 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +namespace rex { +namespace system { +namespace util { + +constexpr memory::fourcc_t kXdbfSignatureXdbf = memory::make_fourcc("XDBF"); +constexpr memory::fourcc_t kXdbfSignatureXstc = memory::make_fourcc("XSTC"); +constexpr memory::fourcc_t kXdbfSignatureXstr = memory::make_fourcc("XSTR"); +constexpr memory::fourcc_t kXdbfSignatureXach = memory::make_fourcc("XACH"); + +constexpr uint64_t kXdbfIdTitle = 0x8000; +constexpr uint64_t kXdbfIdXstc = 0x58535443; +constexpr uint64_t kXdbfIdXach = 0x58414348; + +XdbfWrapper::XdbfWrapper(const uint8_t* data, size_t data_size) + : data_(data), data_size_(data_size) { + if (!data || data_size <= sizeof(XbdfHeader)) { + data_ = nullptr; + return; + } + + const uint8_t* ptr = data_; + + header_ = reinterpret_cast(ptr); + ptr += sizeof(XbdfHeader); + if (header_->magic != kXdbfSignatureXdbf) { + data_ = nullptr; + return; + } + + entries_ = reinterpret_cast(ptr); + ptr += sizeof(XbdfEntry) * header_->entry_count; + + files_ = reinterpret_cast(ptr); + ptr += sizeof(XbdfFileLoc) * header_->free_count; + + content_offset_ = ptr; +} + +XdbfBlock XdbfWrapper::GetEntry(XdbfSection section, uint64_t id) const { + for (uint32_t i = 0; i < header_->entry_used; ++i) { + auto& entry = entries_[i]; + if (entry.section == static_cast(section) && entry.id == id) { + XdbfBlock block; + block.buffer = content_offset_ + entry.offset; + block.size = entry.size; + return block; + } + } + return {}; +} + +std::string XdbfWrapper::GetStringTableEntry(XLanguage language, uint16_t string_id) const { + auto language_block = GetEntry(XdbfSection::kStringTable, static_cast(language)); + if (!language_block) { + return ""; + } + + auto xstr_head = reinterpret_cast(language_block.buffer); + assert_true(xstr_head->magic == kXdbfSignatureXstr); + assert_true(xstr_head->version == 1); + + const uint8_t* ptr = language_block.buffer + sizeof(XdbfSectionHeader); + for (uint16_t i = 0; i < xstr_head->count; ++i) { + auto entry = reinterpret_cast(ptr); + ptr += sizeof(XdbfStringTableEntry); + if (entry->id == string_id) { + return std::string(reinterpret_cast(ptr), entry->string_length); + } + ptr += entry->string_length; + } + return ""; +} + +std::vector XdbfWrapper::GetAchievements() const { + std::vector achievements; + + auto achievement_table = GetEntry(XdbfSection::kMetadata, kXdbfIdXach); + if (!achievement_table) { + return achievements; + } + + auto xach_head = reinterpret_cast(achievement_table.buffer); + assert_true(xach_head->magic == kXdbfSignatureXach); + assert_true(xach_head->version == 1); + + const uint8_t* ptr = achievement_table.buffer + sizeof(XdbfSectionHeader); + for (uint16_t i = 0; i < xach_head->count; ++i) { + auto entry = reinterpret_cast(ptr); + ptr += sizeof(XdbfAchievementTableEntry); + achievements.push_back(*entry); + } + return achievements; +} + +XLanguage XdbfGameData::GetExistingLanguage(XLanguage language_to_check) const { + // A bit of a hack. Check if title in specific language exist. + // If it doesn't then for sure language is not supported. + return title(language_to_check).empty() ? default_language() : language_to_check; +} + +XdbfBlock XdbfGameData::icon() const { + return GetEntry(XdbfSection::kImage, kXdbfIdTitle); +} + +XLanguage XdbfGameData::default_language() const { + auto block = GetEntry(XdbfSection::kMetadata, kXdbfIdXstc); + if (!block.buffer) { + return XLanguage::kEnglish; + } + auto xstc = reinterpret_cast(block.buffer); + assert_true(xstc->magic == kXdbfSignatureXstc); + return static_cast(static_cast(xstc->default_language)); +} + +std::string XdbfGameData::title() const { + return GetStringTableEntry(default_language(), kXdbfIdTitle); +} + +std::string XdbfGameData::title(XLanguage language) const { + return GetStringTableEntry(language, kXdbfIdTitle); +} + +} // namespace util +} // namespace system +} // namespace rex diff --git a/src/system/xam/app_manager.cpp b/src/system/xam/app_manager.cpp new file mode 100644 index 0000000..9b882af --- /dev/null +++ b/src/system/xam/app_manager.cpp @@ -0,0 +1,56 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +namespace rex { +namespace system { +namespace xam { + +App::App(KernelState* kernel_state, uint32_t app_id) + : kernel_state_(kernel_state), memory_(kernel_state->memory()), app_id_(app_id) {} + +void AppManager::RegisterApp(std::unique_ptr app) { + assert_zero(app_lookup_.count(app->app_id())); + app_lookup_.insert({app->app_id(), app.get()}); + apps_.push_back(std::move(app)); +} + +X_HRESULT AppManager::DispatchMessageSync(uint32_t app_id, uint32_t message, uint32_t buffer_ptr, + uint32_t buffer_length) { + App* app; + { + auto it = app_lookup_.find(app_id); + if (it == app_lookup_.end()) { + return X_E_NOTFOUND; + } + app = it->second; + } + return app->DispatchMessageSync(message, buffer_ptr, buffer_length); +} + +X_HRESULT AppManager::DispatchMessageAsync(uint32_t app_id, uint32_t message, uint32_t buffer_ptr, + uint32_t buffer_length) { + App* app; + { + auto it = app_lookup_.find(app_id); + if (it == app_lookup_.end()) { + return X_E_NOTFOUND; + } + app = it->second; + } + return app->DispatchMessageSync(message, buffer_ptr, buffer_length); +} + +} // namespace xam +} // namespace system +} // namespace rex diff --git a/src/system/xam/content_manager.cpp b/src/system/xam/content_manager.cpp new file mode 100644 index 0000000..1ca9457 --- /dev/null +++ b/src/system/xam/content_manager.cpp @@ -0,0 +1,648 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex { +namespace system { +namespace xam { + +static const char* kThumbnailFileName = "__thumbnail.png"; + +static const char* kGameUserContentDirName = "profile"; + +static const char* kGameContentHeaderDirName = "Headers"; + +static int content_device_id_ = 0; + +ContentPackage::ContentPackage(KernelState* kernel_state, const std::string_view root_name, + const XCONTENT_AGGREGATE_DATA& data, + const std::filesystem::path& package_path) + : kernel_state_(kernel_state), root_name_(root_name), package_path_(package_path), license_(0) { + device_path_ = fmt::format("\\Device\\Content\\{0}\\", ++content_device_id_); + content_data_ = data; + + auto fs = kernel_state_->file_system(); + auto device = + std::make_unique(device_path_, package_path, false); + device->Initialize(); + fs->RegisterDevice(std::move(device)); + fs->RegisterSymbolicLink(root_name_ + ":", device_path_); +} + +ContentPackage::~ContentPackage() { + auto fs = kernel_state_->file_system(); + fs->UnregisterSymbolicLink(root_name_ + ":"); + fs->UnregisterDevice(device_path_); +} + +void ContentPackage::LoadPackageLicenseMask(const std::filesystem::path header_path) { + if (!std::filesystem::exists(header_path)) { + return; + } + + auto file = rex::filesystem::OpenFile(header_path, "rb"); + if (!file) { + return; + } + + auto file_size = std::filesystem::file_size(header_path); + if (file_size < sizeof(XCONTENT_AGGREGATE_DATA) + sizeof(license_)) { + fclose(file); + return; + } + + fseek(file, sizeof(XCONTENT_AGGREGATE_DATA), SEEK_SET); + fread(&license_, 1, sizeof(license_), file); + fclose(file); +} + +ContentManager::ContentManager(KernelState* kernel_state, const std::filesystem::path& root_path) + : kernel_state_(kernel_state), root_path_(root_path) {} + +ContentManager::~ContentManager() = default; + +std::filesystem::path ContentManager::ResolvePackageRoot(uint64_t xuid, XContentType content_type, + uint32_t title_id) { + if (title_id == kCurrentlyRunningTitleId) { + title_id = kernel_state_->title_id(); + } + auto xuid_str = fmt::format("{:016X}", xuid); + auto title_id_str = fmt::format("{:08X}", title_id); + auto content_type_str = fmt::format("{:08X}", uint32_t(content_type)); + + // Package root path: + // content_root/xuid/title_id/content_type/ + return root_path_ / xuid_str / title_id_str / content_type_str; +} + +std::filesystem::path ContentManager::ResolvePackagePath(uint64_t xuid, + const XCONTENT_AGGREGATE_DATA& data) { + uint64_t used_xuid = (data.xuid != uint64_t(-1) && data.xuid != 0) ? uint64_t(data.xuid) : xuid; + + // DLCs are stored in common directory + if (data.content_type == XContentType::kMarketplaceContent) { + used_xuid = 0; + } + + // Content path: + // content_root/xuid/title_id/content_type/data_file_name/ + auto package_root = ResolvePackageRoot(used_xuid, data.content_type, data.title_id); + return package_root / rex::to_path(data.file_name()); +} + +std::filesystem::path ContentManager::ResolvePackageHeaderPath(const std::string_view file_name, + uint64_t xuid, uint32_t title_id, + XContentType content_type) const { + if (title_id == kCurrentlyRunningTitleId) { + title_id = kernel_state_->title_id(); + } + + if (content_type == XContentType::kMarketplaceContent) { + xuid = 0; + } + + auto xuid_str = fmt::format("{:016X}", xuid); + auto title_id_str = fmt::format("{:08X}", title_id); + auto content_type_str = fmt::format("{:08X}", uint32_t(content_type)); + std::string final_name = std::string(file_name) + ".header"; + + // Header root path: + // content_root/xuid/title_id/Headers/content_type/filename.header + return root_path_ / xuid_str / title_id_str / kGameContentHeaderDirName / content_type_str / + final_name; +} + +std::vector ContentManager::ListContent(uint32_t device_id, uint64_t xuid, + XContentType content_type, + uint32_t title_id) { + std::vector result; + + if (title_id == kCurrentlyRunningTitleId) { + title_id = kernel_state_->title_id(); + } + + // Search path: + // content_root/xuid/title_id/type_name/* + auto package_root = ResolvePackageRoot(xuid, content_type, title_id); + auto file_infos = rex::filesystem::ListFiles(package_root); + for (const auto& file_info : file_infos) { + if (file_info.type != rex::filesystem::FileInfo::Type::kDirectory) { + // Directories only. + continue; + } + + XCONTENT_AGGREGATE_DATA content_data; + if (XSUCCEEDED(ReadContentHeaderFile(rex::path_to_utf8(file_info.name), xuid, title_id, + content_type, content_data))) { + result.emplace_back(std::move(content_data)); + } else { + content_data.device_id = device_id; + content_data.content_type = content_type; + content_data.set_display_name(rex::path_to_utf16(file_info.name)); + content_data.set_file_name(rex::path_to_utf8(file_info.name)); + content_data.title_id = title_id; + content_data.xuid = xuid; + result.emplace_back(std::move(content_data)); + } + } + + return result; +} + +std::unique_ptr ContentManager::ResolvePackage( + const std::string_view root_name, uint64_t xuid, const XCONTENT_AGGREGATE_DATA& data) { + auto package_path = ResolvePackagePath(xuid, data); + if (!std::filesystem::exists(package_path)) { + return nullptr; + } + auto package = std::make_unique(kernel_state_, root_name, data, package_path); + return package; +} + +bool ContentManager::ContentExists(uint64_t xuid, const XCONTENT_AGGREGATE_DATA& data) { + auto path = ResolvePackagePath(xuid, data); + return std::filesystem::exists(path); +} + +X_RESULT ContentManager::WriteContentHeaderFile(uint64_t xuid, XCONTENT_AGGREGATE_DATA data, + uint32_t license_mask) { + if (data.title_id == uint32_t(-1)) { + data.title_id = kernel_state_->title_id(); + } + if (data.xuid == uint64_t(-1)) { + data.xuid = xuid; + } + uint64_t used_xuid = (data.xuid != uint64_t(-1) && data.xuid != 0) ? uint64_t(data.xuid) : xuid; + + auto header_path = + ResolvePackageHeaderPath(data.file_name(), used_xuid, data.title_id, data.content_type); + auto parent_path = header_path.parent_path(); + + if (!std::filesystem::exists(parent_path)) { + if (!std::filesystem::create_directories(parent_path)) { + return X_ERROR_ACCESS_DENIED; + } + } + + rex::filesystem::CreateEmptyFile(header_path); + + auto file = rex::filesystem::OpenFile(header_path, "wb"); + if (!file) { + return X_ERROR_FILE_NOT_FOUND; + } + fwrite(&data, 1, sizeof(XCONTENT_AGGREGATE_DATA), file); + if (license_mask != 0) { + fwrite(&license_mask, 1, sizeof(license_mask), file); + } + fclose(file); + return X_ERROR_SUCCESS; +} + +X_RESULT ContentManager::ReadContentHeaderFile(const std::string_view file_name, uint64_t xuid, + uint32_t title_id, XContentType content_type, + XCONTENT_AGGREGATE_DATA& data) const { + auto header_file_path = ResolvePackageHeaderPath(file_name, xuid, title_id, content_type); + constexpr uint32_t header_size = sizeof(XCONTENT_AGGREGATE_DATA); + + if (!std::filesystem::exists(header_file_path)) { + return X_ERROR_FILE_NOT_FOUND; + } + + auto file = rex::filesystem::OpenFile(header_file_path, "rb"); + if (!file) { + return X_ERROR_FILE_NOT_FOUND; + } + + auto file_size = std::filesystem::file_size(header_file_path); + if (file_size < header_size) { + fclose(file); + return X_ERROR_FILE_NOT_FOUND; + } + + std::array buffer; + size_t result = fread(buffer.data(), 1, header_size, file); + fclose(file); + + if (result != header_size) { + return X_ERROR_FILE_NOT_FOUND; + } + + std::memcpy(&data, buffer.data(), buffer.size()); + return X_ERROR_SUCCESS; +} + +X_RESULT ContentManager::CreateContent(const std::string_view root_name, uint64_t xuid, + const XCONTENT_AGGREGATE_DATA& data) { + { + auto global_lock = global_critical_region_.Acquire(); + if (open_packages_.count(string::string_key_case(root_name))) { + return X_ERROR_ALREADY_EXISTS; + } + } + + auto package_path = ResolvePackagePath(xuid, data); + if (std::filesystem::exists(package_path)) { + return X_ERROR_ALREADY_EXISTS; + } + if (!std::filesystem::create_directories(package_path)) { + return X_ERROR_ACCESS_DENIED; + } + auto package = ResolvePackage(root_name, xuid, data); + assert_not_null(package); + + { + auto global_lock = global_critical_region_.Acquire(); + if (open_packages_.count(string::string_key_case(root_name))) { + return X_ERROR_ALREADY_EXISTS; + } + open_packages_.insert({string::string_key_case::create(root_name), package.release()}); + } + return X_ERROR_SUCCESS; +} + +X_RESULT ContentManager::OpenContent(const std::string_view root_name, uint64_t xuid, + const XCONTENT_AGGREGATE_DATA& data, + uint32_t& content_license) { + { + auto global_lock = global_critical_region_.Acquire(); + if (open_packages_.count(string::string_key_case(root_name))) { + return X_ERROR_ALREADY_EXISTS; + } + } + + auto package_path = ResolvePackagePath(xuid, data); + if (!std::filesystem::exists(package_path)) { + return X_ERROR_FILE_NOT_FOUND; + } + auto package = ResolvePackage(root_name, xuid, data); + assert_not_null(package); + package->LoadPackageLicenseMask(ResolvePackageHeaderPath( + data.file_name(), xuid, kernel_state_->title_id(), data.content_type)); + content_license = package->GetPackageLicense(); + + { + auto global_lock = global_critical_region_.Acquire(); + if (open_packages_.count(string::string_key_case(root_name))) { + return X_ERROR_ALREADY_EXISTS; + } + open_packages_.insert({string::string_key_case::create(root_name), package.release()}); + } + return X_ERROR_SUCCESS; +} + +X_RESULT ContentManager::CloseContent(const std::string_view root_name) { + ContentPackage* package = nullptr; + { + auto global_lock = global_critical_region_.Acquire(); + // Some games use different casing between Create and Close (e.g. "save" vs "SAVE") + auto it = open_packages_.find(string::string_key_case(root_name)); + if (it == open_packages_.end()) { + return X_ERROR_FILE_NOT_FOUND; + } + package = DetachPackage(it); + } + delete package; + return X_ERROR_SUCCESS; +} + +X_RESULT ContentManager::GetContentThumbnail(uint64_t xuid, const XCONTENT_AGGREGATE_DATA& data, + std::vector* buffer) { + auto global_lock = global_critical_region_.Acquire(); + auto package_path = ResolvePackagePath(xuid, data); + auto thumb_path = package_path / kThumbnailFileName; + if (std::filesystem::exists(thumb_path)) { + auto file = rex::filesystem::OpenFile(thumb_path, "rb"); + fseek(file, 0, SEEK_END); + size_t file_len = ftell(file); + fseek(file, 0, SEEK_SET); + buffer->resize(file_len); + fread(const_cast(buffer->data()), 1, buffer->size(), file); + fclose(file); + return X_ERROR_SUCCESS; + } else { + return X_ERROR_FILE_NOT_FOUND; + } +} + +X_RESULT ContentManager::SetContentThumbnail(uint64_t xuid, const XCONTENT_AGGREGATE_DATA& data, + std::vector buffer) { + auto global_lock = global_critical_region_.Acquire(); + auto package_path = ResolvePackagePath(xuid, data); + std::filesystem::create_directories(package_path); + if (std::filesystem::exists(package_path)) { + auto thumb_path = package_path / kThumbnailFileName; + auto file = rex::filesystem::OpenFile(thumb_path, "wb"); + fwrite(buffer.data(), 1, buffer.size(), file); + fclose(file); + return X_ERROR_SUCCESS; + } else { + return X_ERROR_FILE_NOT_FOUND; + } +} + +X_RESULT ContentManager::DeleteContent(uint64_t xuid, const XCONTENT_AGGREGATE_DATA& data) { + auto global_lock = global_critical_region_.Acquire(); + + if (IsContentOpen(data)) { + // TODO(Gliniak): Get real error code for this case. + return X_ERROR_ACCESS_DENIED; + } + + auto package_path = ResolvePackagePath(xuid, data); + std::error_code ec; + auto dir_removed = std::filesystem::remove_all(package_path, ec); + if (ec) { + return X_ERROR_ACCESS_DENIED; + } + + uint64_t used_xuid = (data.xuid != uint64_t(-1) && data.xuid != 0) ? uint64_t(data.xuid) : xuid; + auto header_path = + ResolvePackageHeaderPath(data.file_name(), used_xuid, data.title_id, data.content_type); + std::error_code ec2; + bool header_removed = std::filesystem::remove(header_path, ec2); + + if (dir_removed > 0 || header_removed) { + return X_ERROR_SUCCESS; + } + return X_ERROR_FILE_NOT_FOUND; +} + +X_RESULT ContentManager::UnmountContent(uint64_t xuid, const XCONTENT_AGGREGATE_DATA& data) { + ContentPackage* package = nullptr; + { + auto global_lock = global_critical_region_.Acquire(); + auto it = FindOpenPackageByData(data); + if (it == open_packages_.end()) { + return X_ERROR_FILE_NOT_FOUND; + } + package = DetachPackage(it); + } + delete package; + return X_ERROR_SUCCESS; +} + +X_RESULT ContentManager::UnmountAndDeleteContent(uint64_t xuid, + const XCONTENT_AGGREGATE_DATA& data) { + // Unmount phase: tolerant of not-mounted state + ContentPackage* package = nullptr; + { + auto global_lock = global_critical_region_.Acquire(); + auto it = FindOpenPackageByData(data); + if (it != open_packages_.end()) { + package = DetachPackage(it); + } + } + delete package; + + // Delete phase: remove package directory and .header file + auto package_path = ResolvePackagePath(xuid, data); + + uint64_t used_xuid = (data.xuid != uint64_t(-1) && data.xuid != 0) ? uint64_t(data.xuid) : xuid; + auto header_path = + ResolvePackageHeaderPath(data.file_name(), used_xuid, data.title_id, data.content_type); + + std::error_code ec; + auto dir_removed = std::filesystem::remove_all(package_path, ec); + if (ec) { + return X_ERROR_ACCESS_DENIED; + } + + std::error_code ec2; + bool header_removed = std::filesystem::remove(header_path, ec2); + + if (dir_removed > 0 || header_removed) { + return X_ERROR_SUCCESS; + } + return X_ERROR_FILE_NOT_FOUND; +} + +std::filesystem::path ContentManager::ResolveGameUserContentPath() { + auto title_id = fmt::format("{:08X}", kernel_state_->title_id()); + auto user_name = rex::to_path(kernel_state_->user_profile()->name()); + + // Per-game per-profile data location: + // content_root/title_id/profile/user_name + return root_path_ / title_id / kGameUserContentDirName / user_name; +} + +std::unordered_map::iterator +ContentManager::FindOpenPackageByData(const XCONTENT_AGGREGATE_DATA& data) { + // Resolve kCurrentlyRunningTitleId so both sides compare actual title IDs. + uint32_t query_title = data.title_id; + if (query_title == kCurrentlyRunningTitleId) { + query_title = kernel_state_->title_id(); + } + + for (auto it = open_packages_.begin(); it != open_packages_.end(); ++it) { + const auto& pkg = it->second->GetPackageContentData(); + + uint32_t pkg_title = pkg.title_id; + if (pkg_title == kCurrentlyRunningTitleId) { + pkg_title = kernel_state_->title_id(); + } + + // Match on content_type + file_name + resolved title_id. + // device_id is a virtual storage selector, not a content identifier. + if (data.content_type == pkg.content_type && data.file_name() == pkg.file_name() && + query_title == pkg_title) { + return it; + } + } + return open_packages_.end(); +} + +ContentPackage* ContentManager::DetachPackage( + std::unordered_map::iterator it) { + CloseOpenedFilesFromContent(it->first.view()); + ContentPackage* package = it->second; + open_packages_.erase(it); + return package; +} + +bool ContentManager::IsContentOpen(const XCONTENT_AGGREGATE_DATA& data) const { + return std::any_of(open_packages_.cbegin(), open_packages_.cend(), [&data](const auto& content) { + return data == content.second->GetPackageContentData(); + }); +} + +std::filesystem::path ContentManager::GetOpenPackagePath(const std::string_view root_name) const { + auto it = open_packages_.find(string::string_key_case(root_name)); + if (it == open_packages_.end()) { + return {}; + } + return it->second->package_path(); +} + +void ContentManager::CloseOpenedFilesFromContent(const std::string_view root_name) { + // TODO(Gliniak): Cleanup this code to care only about handles + // related to provided content + const std::vector> all_files_handles = + kernel_state_->object_table()->GetObjectsByType(XObject::Type::File); + + std::string resolved_path = ""; + kernel_state_->file_system()->FindSymbolicLink(std::string(root_name) + ':', resolved_path); + + for (const object_ref& file : all_files_handles) { + std::string file_path = file->entry()->absolute_path(); + bool is_file_inside_content = rex::string::utf8_starts_with(file_path, resolved_path); + + if (is_file_inside_content) { + file->ReleaseHandle(); + } + } +} + +static X_RESULT ExtractEntry(rex::filesystem::Entry* entry, + const std::filesystem::path& base_path) { + auto dest_path = base_path / rex::to_path(rex::string::utf8_fix_path_separators(entry->path())); + + if (entry->attributes() & rex::filesystem::kFileAttributeDirectory) { + std::error_code ec; + std::filesystem::create_directories(dest_path, ec); + if (ec) { + return X_ERROR_ACCESS_DENIED; + } + return X_ERROR_SUCCESS; + } + + // Ensure parent directory exists + std::error_code ec; + std::filesystem::create_directories(dest_path.parent_path(), ec); + + rex::filesystem::File* in_file = nullptr; + X_STATUS status = entry->Open(rex::filesystem::FileAccess::kFileReadData, &in_file); + if (status != X_STATUS_SUCCESS) { + return X_ERROR_ACCESS_DENIED; + } + + auto out_file = rex::filesystem::OpenFile(dest_path, "wb"); + if (!out_file) { + in_file->Destroy(); + return X_ERROR_ACCESS_DENIED; + } + + constexpr size_t kBufferSize = 4 * 1024 * 1024; // 4 MiB + auto buffer = std::make_unique(kBufferSize); + size_t remaining = entry->size(); + size_t offset = 0; + + while (remaining > 0) { + size_t bytes_read = 0; + size_t to_read = std::min(remaining, kBufferSize); + in_file->ReadSync(std::span(buffer.get(), to_read), offset, &bytes_read); + if (bytes_read == 0) { + break; + } + fwrite(buffer.get(), 1, bytes_read, out_file); + offset += bytes_read; + remaining -= bytes_read; + } + + fclose(out_file); + in_file->Destroy(); + return X_ERROR_SUCCESS; +} + +X_RESULT ContentManager::InstallContent(const std::filesystem::path& package_path) { + if (!std::filesystem::exists(package_path)) { + return X_ERROR_FILE_NOT_FOUND; + } + + // Mount the STFS package as a virtual filesystem device + auto device = std::make_unique("", package_path); + if (!device->Initialize()) { + return X_ERROR_ACCESS_DENIED; + } + + // Derive install destination: + // root_path_/0000000000000000/{title_id}/00000002/{filename}/ + auto file_name = rex::path_to_utf8(package_path.filename()); + + XCONTENT_AGGREGATE_DATA content_data; + content_data.device_id = static_cast(DummyDeviceId::HDD); + content_data.content_type = XContentType::kMarketplaceContent; + content_data.title_id = kernel_state_->title_id(); + content_data.xuid = 0; + content_data.set_file_name(file_name); + + // Read display name from STFS metadata + auto display_name = device->header().metadata.display_name(rex::system::XLanguage::kEnglish); + if (!display_name.empty()) { + content_data.set_display_name(display_name); + } else { + content_data.set_display_name(rex::path_to_utf16(package_path.filename())); + } + + auto install_path = ResolvePackagePath(0, content_data); + + // Create destination directory + std::error_code ec; + std::filesystem::create_directories(install_path, ec); + if (ec) { + return X_ERROR_ACCESS_DENIED; + } + + // Extract all files breadth-first + auto* root = device->ResolvePath(""); + if (!root) { + return X_ERROR_ACCESS_DENIED; + } + + std::queue queue; + queue.push(root); + + while (!queue.empty()) { + auto* entry = queue.front(); + queue.pop(); + + for (auto& child : entry->children()) { + queue.push(child.get()); + } + + auto result = ExtractEntry(entry, install_path); + if (result != X_ERROR_SUCCESS) { + return result; + } + } + + // Compute license mask from STFS header licenses + uint32_t license_mask = 0; + for (size_t i = 0; i < 0x10; i++) { + if (device->header().header.licenses[i].license_flags) { + license_mask |= device->header().header.licenses[i].license_bits; + } + } + + // Write .header file + return WriteContentHeaderFile(0, content_data, license_mask); +} + +} // namespace xam +} // namespace system +} // namespace rex diff --git a/src/system/xam/user_profile.cpp b/src/system/xam/user_profile.cpp new file mode 100644 index 0000000..a77f5e6 --- /dev/null +++ b/src/system/xam/user_profile.cpp @@ -0,0 +1,177 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include + +#include +#include +#include + +namespace rex { +namespace system { +namespace xam { + +UserProfile::UserProfile() { + // 58410A1F checks the user XUID against a mask of 0x00C0000000000000 (3<<54), + // if non-zero, it prevents the user from playing the game. + // "You do not have permissions to perform this operation." + xuid_ = 0xB13EBABEBABEBABE; + name_ = "User"; + + // https://cs.rin.ru/forum/viewtopic.php?f=38&t=60668&hilit=gfwl+live&start=195 + // https://github.com/arkem/py360/blob/master/py360/constants.py + // XPROFILE_GAMER_YAXIS_INVERSION + AddSetting(std::make_unique(0x10040002, 0)); + // XPROFILE_OPTION_CONTROLLER_VIBRATION + AddSetting(std::make_unique(0x10040003, 3)); + // XPROFILE_GAMERCARD_ZONE + AddSetting(std::make_unique(0x10040004, 0)); + // XPROFILE_GAMERCARD_REGION + AddSetting(std::make_unique(0x10040005, 0)); + // XPROFILE_GAMERCARD_CRED + AddSetting(std::make_unique(0x10040006, 0xFA)); + // XPROFILE_GAMERCARD_REP + AddSetting(std::make_unique(0x5004000B, 0.0f)); + // XPROFILE_OPTION_VOICE_MUTED + AddSetting(std::make_unique(0x1004000C, 0)); + // XPROFILE_OPTION_VOICE_THRU_SPEAKERS + AddSetting(std::make_unique(0x1004000D, 0)); + // XPROFILE_OPTION_VOICE_VOLUME + AddSetting(std::make_unique(0x1004000E, 0x64)); + // XPROFILE_GAMERCARD_MOTTO + AddSetting(std::make_unique(0x402C0011, u"")); + // XPROFILE_GAMERCARD_TITLES_PLAYED + AddSetting(std::make_unique(0x10040012, 1)); + // XPROFILE_GAMERCARD_ACHIEVEMENTS_EARNED + AddSetting(std::make_unique(0x10040013, 0)); + // XPROFILE_GAMER_DIFFICULTY + AddSetting(std::make_unique(0x10040015, 0)); + // XPROFILE_GAMER_CONTROL_SENSITIVITY + AddSetting(std::make_unique(0x10040018, 0)); + // Preferred color 1 + AddSetting(std::make_unique(0x1004001D, 0xFFFF0000u)); + // Preferred color 2 + AddSetting(std::make_unique(0x1004001E, 0xFF00FF00u)); + // XPROFILE_GAMER_ACTION_AUTO_AIM + AddSetting(std::make_unique(0x10040022, 1)); + // XPROFILE_GAMER_ACTION_AUTO_CENTER + AddSetting(std::make_unique(0x10040023, 0)); + // XPROFILE_GAMER_ACTION_MOVEMENT_CONTROL + AddSetting(std::make_unique(0x10040024, 0)); + // XPROFILE_GAMER_RACE_TRANSMISSION + AddSetting(std::make_unique(0x10040026, 0)); + // XPROFILE_GAMER_RACE_CAMERA_LOCATION + AddSetting(std::make_unique(0x10040027, 0)); + // XPROFILE_GAMER_RACE_BRAKE_CONTROL + AddSetting(std::make_unique(0x10040028, 0)); + // XPROFILE_GAMER_RACE_ACCELERATOR_CONTROL + AddSetting(std::make_unique(0x10040029, 0)); + // XPROFILE_GAMERCARD_TITLE_CRED_EARNED + AddSetting(std::make_unique(0x10040038, 0)); + // XPROFILE_GAMERCARD_TITLE_ACHIEVEMENTS_EARNED + AddSetting(std::make_unique(0x10040039, 0)); + + // If we set this, games will try to get it. + // XPROFILE_GAMERCARD_PICTURE_KEY + AddSetting(std::make_unique(0x4064000F, u"gamercard_picture_key")); + + // XPROFILE_TITLE_SPECIFIC1 + AddSetting(std::make_unique(0x63E83FFF)); + // XPROFILE_TITLE_SPECIFIC2 + AddSetting(std::make_unique(0x63E83FFE)); + // XPROFILE_TITLE_SPECIFIC3 + AddSetting(std::make_unique(0x63E83FFD)); +} + +void UserProfile::AddSetting(std::unique_ptr setting) { + Setting* previous_setting = setting.get(); + std::swap(settings_[setting->setting_id], previous_setting); + + if (setting->is_set && setting->is_title_specific()) { + SaveSetting(setting.get()); + } + + if (previous_setting) { + // replace: swap out the old setting from the owning list + for (auto vec_it = setting_list_.begin(); vec_it != setting_list_.end(); ++vec_it) { + if (vec_it->get() == previous_setting) { + vec_it->swap(setting); + break; + } + } + } else { + // new setting: add to the owning list + setting_list_.push_back(std::move(setting)); + } +} + +UserProfile::Setting* UserProfile::GetSetting(uint32_t setting_id) { + const auto& it = settings_.find(setting_id); + if (it == settings_.end()) { + return nullptr; + } + UserProfile::Setting* setting = it->second; + if (setting->is_title_specific()) { + // If what we have loaded in memory isn't for the title that is running + // right now, then load it from disk. + if (kernel_state_->title_id() != setting->loaded_title_id) { + LoadSetting(setting); + } + } + return setting; +} + +void UserProfile::LoadSetting(UserProfile::Setting* setting) { + if (setting->is_title_specific()) { + auto content_dir = kernel_state_->content_manager()->ResolveGameUserContentPath(); + auto setting_id = fmt::format("{:08X}", setting->setting_id); + auto file_path = content_dir / setting_id; + auto file = rex::filesystem::OpenFile(file_path, "rb"); + if (file) { + fseek(file, 0, SEEK_END); + uint32_t input_file_size = static_cast(ftell(file)); + fseek(file, 0, SEEK_SET); + + std::vector serialized_data(input_file_size); + fread(serialized_data.data(), 1, serialized_data.size(), file); + fclose(file); + setting->Deserialize(serialized_data); + setting->loaded_title_id = kernel_state_->title_id(); + } + } else { + // Unsupported for now. Other settings aren't per-game and need to be + // stored some other way. + REXSYS_WARN("Attempting to load unsupported profile setting from disk"); + } +} + +void UserProfile::SaveSetting(UserProfile::Setting* setting) { + if (setting->is_title_specific()) { + auto serialized_setting = setting->Serialize(); + auto content_dir = kernel_state_->content_manager()->ResolveGameUserContentPath(); + std::filesystem::create_directories(content_dir); + auto setting_id = fmt::format("{:08X}", setting->setting_id); + auto file_path = content_dir / setting_id; + auto file = rex::filesystem::OpenFile(file_path, "wb"); + fwrite(serialized_setting.data(), 1, serialized_setting.size(), file); + fclose(file); + } else { + // Unsupported for now. Other settings aren't per-game and need to be + // stored some other way. + REXSYS_WARN("Attempting to save unsupported profile setting to disk"); + } +} + +} // namespace xam +} // namespace system +} // namespace rex diff --git a/src/system/xenumerator.cpp b/src/system/xenumerator.cpp new file mode 100644 index 0000000..721c53a --- /dev/null +++ b/src/system/xenumerator.cpp @@ -0,0 +1,75 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +namespace rex::system { + +XEnumerator::XEnumerator(KernelState* kernel_state, size_t items_per_enumerate, size_t item_size) + : XObject(kernel_state, kObjectType), + items_per_enumerate_(items_per_enumerate), + item_size_(item_size) {} + +XEnumerator::~XEnumerator() = default; + +X_STATUS XEnumerator::Initialize(uint32_t user_index, uint32_t app_id, uint32_t open_message, + uint32_t close_message, uint32_t flags, uint32_t extra_size, + void** extra_buffer) { + auto native_object = CreateNative(sizeof(X_KENUMERATOR) + extra_size); + if (!native_object) { + return X_STATUS_NO_MEMORY; + } + auto guest_object = reinterpret_cast(native_object); + guest_object->app_id = app_id; + guest_object->open_message = open_message; + guest_object->close_message = close_message; + guest_object->user_index = user_index; + guest_object->items_per_enumerate = static_cast(items_per_enumerate_); + guest_object->flags = flags; + if (extra_buffer) { + *extra_buffer = !extra_buffer ? nullptr : &native_object[sizeof(X_KENUMERATOR)]; + } + return X_STATUS_SUCCESS; +} + +X_STATUS XEnumerator::Initialize(uint32_t user_index, uint32_t app_id, uint32_t open_message, + uint32_t close_message, uint32_t flags) { + return Initialize(user_index, app_id, open_message, close_message, flags, 0, nullptr); +} + +uint8_t* XStaticUntypedEnumerator::AppendItem() { + size_t offset = buffer_.size(); + buffer_.resize(offset + item_size()); + item_count_++; + return const_cast(&buffer_.data()[offset]); +} + +uint32_t XStaticUntypedEnumerator::WriteItems(uint32_t buffer_ptr, uint8_t* buffer_data, + uint32_t* written_count) { + size_t count = std::min(item_count_ - current_item_, items_per_enumerate()); + if (!count) { + return X_ERROR_NO_MORE_FILES; + } + + size_t size = count * item_size(); + size_t offset = current_item_ * item_size(); + std::memcpy(buffer_data, buffer_.data() + offset, size); + + current_item_ += count; + + if (written_count) { + *written_count = static_cast(count); + } + + return X_ERROR_SUCCESS; +} + +} // namespace rex::system diff --git a/src/system/xevent.cpp b/src/system/xevent.cpp new file mode 100644 index 0000000..c24fbd1 --- /dev/null +++ b/src/system/xevent.cpp @@ -0,0 +1,142 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +namespace rex::system { + +XEvent::XEvent(KernelState* kernel_state) : XObject(kernel_state, kObjectType) {} + +XEvent::~XEvent() = default; + +void XEvent::Initialize(bool manual_reset, bool initial_state) { + assert_false(event_); + + this->CreateNative(); + + if (manual_reset) { + event_ = rex::thread::Event::CreateManualResetEvent(initial_state); + } else { + event_ = rex::thread::Event::CreateAutoResetEvent(initial_state); + } + assert_not_null(event_); +} + +void XEvent::InitializeNative(void* native_ptr, X_DISPATCH_HEADER* header) { + assert_false(event_); + + switch (header->type) { + case 0x00: // EventNotificationObject (manual reset) + manual_reset_ = true; + break; + case 0x01: // EventSynchronizationObject (auto reset) + manual_reset_ = false; + break; + default: + assert_always(); + return; + } + + bool initial_state = header->signal_state ? true : false; + if (manual_reset_) { + event_ = rex::thread::Event::CreateManualResetEvent(initial_state); + } else { + event_ = rex::thread::Event::CreateAutoResetEvent(initial_state); + } + assert_not_null(event_); +} + +void XEvent::Query(uint32_t* out_type, uint32_t* out_state) { + if (out_type) { + *out_type = manual_reset_ ? 0x00 : 0x01; + } + if (out_state) { + // Query the live host event, not the stale guest header + auto result = rex::thread::Wait(event_.get(), false, std::chrono::milliseconds(0)); + if (result == rex::thread::WaitResult::kSuccess) { + *out_state = 1; + // Re-signal since we consumed the signal by waiting + event_->Set(); + } else { + *out_state = 0; + } + } +} + +int32_t XEvent::Set(uint32_t priority_increment, bool wait) { + event_->Set(); + return 1; +} + +int32_t XEvent::Pulse(uint32_t priority_increment, bool wait) { + event_->Pulse(); + return 1; +} + +int32_t XEvent::Reset() { + event_->Reset(); + return 1; +} + +void XEvent::Clear() { + event_->Reset(); +} + +bool XEvent::Save(stream::ByteStream* stream) { + REXSYS_DEBUG("XEvent {:08X} ({})", handle(), manual_reset_ ? "manual" : "auto"); + SaveObject(stream); + + bool signaled = true; + auto result = rex::thread::Wait(event_.get(), false, std::chrono::milliseconds(0)); + if (result == rex::thread::WaitResult::kSuccess) { + signaled = true; + } else if (result == rex::thread::WaitResult::kTimeout) { + signaled = false; + } else { + assert_always(); + } + + if (signaled) { + // Reset the event in-case it's an auto-reset. + event_->Set(); + } + + stream->Write(signaled); + stream->Write(manual_reset_); + + return true; +} + +object_ref XEvent::Restore(KernelState* kernel_state, stream::ByteStream* stream) { + auto evt = new XEvent(nullptr); + evt->kernel_state_ = kernel_state; + + evt->RestoreObject(stream); + bool signaled = stream->Read(); + evt->manual_reset_ = stream->Read(); + + if (evt->manual_reset_) { + evt->event_ = rex::thread::Event::CreateManualResetEvent(false); + } else { + evt->event_ = rex::thread::Event::CreateAutoResetEvent(false); + } + assert_not_null(evt->event_); + + if (signaled) { + evt->event_->Set(); + } + + return object_ref(evt); +} + +} // namespace rex::system diff --git a/src/system/xex_module.cpp b/src/system/xex_module.cpp new file mode 100644 index 0000000..04d44ae --- /dev/null +++ b/src/system/xex_module.cpp @@ -0,0 +1,1190 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include "crypto/TinySHA1.hpp" +#include "crypto/rijndael-alg-fst.c" +#include "crypto/rijndael-alg-fst.h" +#include "pe/pe_image.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const uint8_t xe_xex2_retail_key[16] = {0x20, 0xB1, 0x85, 0xA5, 0x9D, 0x28, 0xFD, 0xC3, + 0x40, 0x58, 0x3F, 0xBB, 0x08, 0x96, 0xBF, 0x91}; +static const uint8_t xe_xex2_devkit_key[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +void aes_decrypt_buffer(const uint8_t* session_key, const uint8_t* input_buffer, + const size_t input_size, uint8_t* output_buffer, const size_t output_size) { + uint32_t rk[4 * (MAXNR + 1)]; + uint8_t ivec[16] = {0}; + int32_t Nr = rijndaelKeySetupDec(rk, session_key, 128); + const uint8_t* ct = input_buffer; + uint8_t* pt = output_buffer; + for (size_t n = 0; n < input_size; n += 16, ct += 16, pt += 16) { + // Decrypt 16 uint8_ts from input -> output. + rijndaelDecrypt(rk, Nr, ct, pt); + for (size_t i = 0; i < 16; i++) { + // XOR with previous. + pt[i] ^= ivec[i]; + // Set previous. + ivec[i] = ct[i]; + } + } +} + +namespace rex::runtime { + +using rex::system::KernelState; + +XexModule::XexModule(FunctionDispatcher* function_dispatcher, KernelState* kernel_state) + : Module(function_dispatcher), kernel_state_(kernel_state) {} + +XexModule::~XexModule() {} + +bool XexModule::GetOptHeader(const xex2_header* header, xex2_header_keys key, void** out_ptr) { + assert_not_null(header); + assert_not_null(out_ptr); + + for (uint32_t i = 0; i < header->header_count; i++) { + const xex2_opt_header& opt_header = header->headers[i]; + if (opt_header.key == key) { + // Match! + switch (key & 0xFF) { + case 0x00: { + // We just return the value of the optional header. + // Assume that the output pointer points to a uint32_t. + *reinterpret_cast(out_ptr) = static_cast(opt_header.value); + } break; + case 0x01: { + // Pointer to the value on the optional header. + *out_ptr = const_cast(reinterpret_cast(&opt_header.value)); + } break; + default: { + // Pointer to the header. + *out_ptr = reinterpret_cast(uintptr_t(header) + opt_header.offset); + } break; + } + + return true; + } + } + + return false; +} + +bool XexModule::GetOptHeader(xex2_header_keys key, void** out_ptr) const { + return XexModule::GetOptHeader(xex_header(), key, out_ptr); +} + +const void* XexModule::GetSecurityInfo(const xex2_header* header) { + return reinterpret_cast(uintptr_t(header) + header->security_offset); +} + +const PESection* XexModule::GetPESection(const char* name) { + for (std::vector::iterator it = pe_sections_.begin(); it != pe_sections_.end(); ++it) { + if (!strcmp(it->name, name)) { + return &(*it); + } + } + return nullptr; +} + +uint32_t XexModule::GetProcAddress(uint16_t ordinal) const { + // First: Check the xex2 export table. + if (xex_security_info()->export_table) { + auto export_table = + memory()->TranslateVirtual(xex_security_info()->export_table); + + ordinal -= export_table->base; + if (ordinal >= export_table->count) { + REXLOG_ERROR("GetProcAddress({:03X}): ordinal out of bounds", ordinal); + return 0; + } + + uint32_t num = ordinal; + uint32_t ordinal_offset = export_table->ordOffset[num]; + ordinal_offset += export_table->imagebaseaddr << 16; + return ordinal_offset; + } + + // Second: Check the PE exports. + assert_not_zero(base_address_); + + xex2_opt_data_directory* pe_export_directory = 0; + if (GetOptHeader(XEX_HEADER_EXPORTS_BY_NAME, &pe_export_directory)) { + auto e = memory()->TranslateVirtual( + base_address_ + pe_export_directory->offset); + assert_not_null(e); + + uint32_t* function_table = reinterpret_cast(uintptr_t(e) + e->AddressOfFunctions); + + if (ordinal < e->NumberOfFunctions) { + return base_address_ + function_table[ordinal]; + } + } + + return 0; +} + +uint32_t XexModule::GetProcAddress(const std::string_view name) const { + assert_not_zero(base_address_); + + xex2_opt_data_directory* pe_export_directory = 0; + if (!GetOptHeader(XEX_HEADER_EXPORTS_BY_NAME, &pe_export_directory)) { + // No exports by name. + return 0; + } + + auto e = memory()->TranslateVirtual(base_address_ + + pe_export_directory->offset); + assert_not_null(e); + + // e->AddressOfX RVAs are relative to the IMAGE_EXPORT_DIRECTORY! + uint32_t* function_table = reinterpret_cast(uintptr_t(e) + e->AddressOfFunctions); + + // Names relative to directory + uint32_t* name_table = reinterpret_cast(uintptr_t(e) + e->AddressOfNames); + + // Table of ordinals (by name) + uint16_t* ordinal_table = reinterpret_cast(uintptr_t(e) + e->AddressOfNameOrdinals); + + for (uint32_t i = 0; i < e->NumberOfNames; i++) { + auto fn_name = reinterpret_cast(uintptr_t(e) + name_table[i]); + uint16_t ordinal = ordinal_table[i]; + uint32_t addr = base_address_ + function_table[ordinal]; + if (name == std::string_view(fn_name)) { + // We have a match! + return addr; + } + } + + // No match + return 0; +} + +int XexModule::ApplyPatch(XexModule* module) { + if (!is_patch()) { + // This isn't a XEX2 patch. + return 1; + } + + // Grab the delta descriptor and get to work. + xex2_opt_delta_patch_descriptor* patch_header = nullptr; + GetOptHeader(XEX_HEADER_DELTA_PATCH_DESCRIPTOR, reinterpret_cast(&patch_header)); + assert_not_null(patch_header); + + // Compare hash inside delta descriptor to base XEX signature + uint8_t digest[0x14]; + sha1::SHA1 s; + s.processBytes(module->xex_security_info()->rsa_signature, 0x100); + s.finalize(digest); + + if (memcmp(digest, patch_header->digest_source, 0x14) != 0) { + REXLOG_WARN( + "XEX patch signature hash doesn't match base XEX signature hash, patch " + "will likely fail!"); + } + + uint32_t size = module->xex_header()->header_size; + if (patch_header->delta_headers_source_offset > size) { + REXLOG_ERROR("XEX header patch source is outside base XEX header area"); + return 2; + } + + uint32_t header_size_available = size - patch_header->delta_headers_source_offset; + if (patch_header->delta_headers_source_size > header_size_available) { + REXLOG_ERROR("XEX header patch source is too large"); + return 3; + } + + if (patch_header->delta_headers_target_offset > patch_header->size_of_target_headers) { + REXLOG_ERROR("XEX header patch target is outside base XEX header area"); + return 4; + } + + uint32_t delta_target_size = + patch_header->size_of_target_headers - patch_header->delta_headers_target_offset; + if (patch_header->delta_headers_source_size > delta_target_size) { + return 5; // ? unsure what the point of this test is, kernel checks for it + // though + } + + // Patch base XEX header + uint32_t original_image_size = module->image_size(); + uint32_t header_target_size = patch_header->size_of_target_headers; + + if (!header_target_size) { + header_target_size = + patch_header->delta_headers_target_offset + patch_header->delta_headers_source_size; + } + + size_t mem_size = module->xex_header_mem_.size(); + + // Increase xex header buffer length if needed + if (header_target_size > module->xex_header_mem_.size()) { + module->xex_header_mem_.resize(header_target_size); + } + + auto header_ptr = (uint8_t*)module->xex_header(); + + // If headers_source_offset is set, copy [source_offset:source_size] to + // target_offset + if (patch_header->delta_headers_source_offset) { + memcpy(header_ptr + patch_header->delta_headers_target_offset, + header_ptr + patch_header->delta_headers_source_offset, + patch_header->delta_headers_source_size); + } + + // If new size is smaller than original, null out the difference + if (header_target_size < module->xex_header_mem_.size()) { + memset(header_ptr + header_target_size, 0, module->xex_header_mem_.size() - header_target_size); + } + + auto file_format_header = opt_file_format_info(); + assert_not_null(file_format_header); + + // Apply header patch... + uint32_t headerpatch_size = patch_header->info.compressed_len + 0xC; + + int result_code = + lzxdelta_apply_patch(&patch_header->info, headerpatch_size, + file_format_header->compression_info.normal.window_size, header_ptr); + if (result_code) { + REXLOG_ERROR("XEX header patch application failed, error code {}", result_code); + return result_code; + } + + // Decrease xex header buffer length if needed (but only after patching) + if (module->xex_header_mem_.size() > header_target_size) { + module->xex_header_mem_.resize(header_target_size); + } + + // Update security info context with latest security info data + module->ReadSecurityInfo(); + + uint32_t new_image_size = module->image_size(); + + // Check if we need to alloc new memory for the patched xex + if (new_image_size > original_image_size) { + uint32_t size_delta = new_image_size - original_image_size; + uint32_t addr_new_mem = module->base_address_ + original_image_size; + + bool alloc_result = + memory() + ->LookupHeap(addr_new_mem) + ->AllocFixed( + addr_new_mem, size_delta, 4096, + rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite); + + if (!alloc_result) { + REXLOG_ERROR("Unable to allocate XEX memory at {:08X}-{:08X}.", addr_new_mem, size_delta); + assert_always(); + return 6; + } + } + + uint8_t orig_session_key[0x10]; + memcpy(orig_session_key, module->session_key_, 0x10); + + // Header patch updated the base XEX key, need to redecrypt it + aes_decrypt_buffer(module->is_dev_kit_ ? xe_xex2_devkit_key : xe_xex2_retail_key, + reinterpret_cast(module->xex_security_info()->aes_key), 16, + module->session_key_, 16); + + // Decrypt the patch XEX's key using base XEX key + aes_decrypt_buffer(module->session_key_, + reinterpret_cast(xex_security_info()->aes_key), 16, + session_key_, 16); + + // Test delta key against our decrypted keys + // (kernel doesn't seem to check this, but it's the one use for the + // image_key_source field I can think of...) + uint8_t test_delta_key[0x10]; + aes_decrypt_buffer(module->session_key_, patch_header->image_key_source, 0x10, test_delta_key, + 0x10); + + if (memcmp(test_delta_key, orig_session_key, 0x10) != 0) { + REXLOG_ERROR("XEX patch image key doesn't match original XEX!"); + return 7; + } + + // Decrypt (if needed). + bool free_input = false; + const uint8_t* patch_buffer = xexp_data_mem_.data(); + const size_t patch_length = xexp_data_mem_.size(); + + const uint8_t* input_buffer = patch_buffer; + + switch (file_format_header->encryption_type) { + case XEX_ENCRYPTION_NONE: + // No-op. + break; + case XEX_ENCRYPTION_NORMAL: + // TODO: a way to do without a copy/alloc? + free_input = true; + input_buffer = (const uint8_t*)calloc(1, patch_length); + aes_decrypt_buffer(session_key_, patch_buffer, patch_length, (uint8_t*)input_buffer, + patch_length); + break; + default: + assert_always(); + return 8; + } + + const xex2_compressed_block_info* cur_block = + &file_format_header->compression_info.normal.first_block; + + const uint8_t* p = input_buffer; + uint8_t* base_exe = memory()->TranslateVirtual(module->base_address_); + + // If image_source_offset is set, copy [source_offset:source_size] to + // target_offset + if (patch_header->delta_image_source_offset) { + memcpy(base_exe + patch_header->delta_image_target_offset, + base_exe + patch_header->delta_image_source_offset, + patch_header->delta_image_source_size); + } + + // TODO: should we use new_image_size here instead? + uint32_t image_target_size = + patch_header->delta_image_target_offset + patch_header->delta_image_source_size; + + // If new size is smaller than original, null out the difference + if (image_target_size < original_image_size) { + memset(base_exe + image_target_size, 0, original_image_size - image_target_size); + } + + // Now loop through each block and apply the delta patches inside + while (cur_block->block_size) { + const auto* next_block = (const xex2_compressed_block_info*)p; + + // Compare block hash, if no match we probably used wrong decrypt key + s.reset(); + s.processBytes(p, cur_block->block_size); + s.finalize(digest); + + if (memcmp(digest, cur_block->block_hash, 0x14) != 0) { + result_code = 9; + REXLOG_ERROR("XEX patch block hash doesn't match hash inside block info!"); + break; + } + + // skip block info + p += 20; + p += 4; + + uint32_t block_data_size = cur_block->block_size - 20 - 4; + + // Apply delta patch + result_code = + lzxdelta_apply_patch((xex2_delta_patch*)p, block_data_size, + file_format_header->compression_info.normal.window_size, base_exe); + if (result_code) { + break; + } + + p += block_data_size; + cur_block = next_block; + } + + if (!result_code) { + // Decommit unused pages if new image size is smaller than original + if (original_image_size > new_image_size) { + uint32_t size_delta = original_image_size - new_image_size; + uint32_t addr_free_mem = module->base_address_ + new_image_size; + + bool free_result = memory()->LookupHeap(addr_free_mem)->Decommit(addr_free_mem, size_delta); + + if (!free_result) { + REXLOG_ERROR("Unable to decommit XEX memory at {:08X}-{:08X}.", addr_free_mem, size_delta); + assert_always(); + } + } + + xex2_version source_ver, target_ver; + source_ver = patch_header->source_version(); + target_ver = patch_header->target_version(); + REXLOG_INFO( + "XEX patch applied successfully: base version: {}.{}.{}.{}, new " + "version: {}.{}.{}.{}", + (uint32_t)source_ver.major, (uint32_t)source_ver.minor, (uint32_t)source_ver.build, + (uint32_t)source_ver.qfe, (uint32_t)target_ver.major, (uint32_t)target_ver.minor, + (uint32_t)target_ver.build, (uint32_t)target_ver.qfe); + } else { + REXLOG_ERROR("XEX patch application failed, error code {}", result_code); + } + + if (free_input) { + free((void*)input_buffer); + } + return result_code; +} + +int XexModule::ReadImage(const void* xex_addr, size_t xex_length, bool use_dev_key) { + if (!opt_file_format_info()) { + return 1; + } + + is_dev_kit_ = use_dev_key; + + if (is_patch()) { + // Make a copy of patch data for other XEX's to use with ApplyPatch() + const uint32_t data_len = static_cast(xex_length - xex_header()->header_size); + xexp_data_mem_.resize(data_len); + std::memcpy(xexp_data_mem_.data(), (uint8_t*)xex_addr + xex_header()->header_size, data_len); + return 0; + } + + memory()->LookupHeap(base_address_)->Reset(); + + aes_decrypt_buffer(use_dev_key ? xe_xex2_devkit_key : xe_xex2_retail_key, + reinterpret_cast(xex_security_info()->aes_key), 16, + session_key_, 16); + + int result_code = 0; + switch (opt_file_format_info()->compression_type) { + case XEX_COMPRESSION_NONE: + result_code = ReadImageUncompressed(xex_addr, xex_length); + break; + case XEX_COMPRESSION_BASIC: + result_code = ReadImageBasicCompressed(xex_addr, xex_length); + break; + case XEX_COMPRESSION_NORMAL: + result_code = ReadImageCompressed(xex_addr, xex_length); + break; + default: + assert_always(); + return 2; + } + + if (result_code) { + return result_code; + } + + if (is_patch() || is_valid_executable()) { + return 0; + } + + // Not a patch and image doesn't have proper PE header, return 3 + return 3; +} + +int XexModule::ReadImageUncompressed(const void* xex_addr, size_t xex_length) { + // Allocate in-place the XEX memory. + const uint32_t exe_length = static_cast(xex_length - xex_header()->header_size); + + uint32_t uncompressed_size = exe_length; + bool alloc_result = + memory() + ->LookupHeap(base_address_) + ->AllocFixed(base_address_, uncompressed_size, 4096, + rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite); + if (!alloc_result) { + REXLOG_ERROR("Unable to allocate XEX memory at {:08X}-{:08X}.", base_address_, + uncompressed_size); + return 2; + } + uint8_t* buffer = memory()->TranslateVirtual(base_address_); + std::memset(buffer, 0, uncompressed_size); + + const uint8_t* p = (const uint8_t*)xex_addr + xex_header()->header_size; + + switch (opt_file_format_info()->encryption_type) { + case XEX_ENCRYPTION_NONE: + if (exe_length > uncompressed_size) { + return 1; + } + memcpy(buffer, p, exe_length); + return 0; + case XEX_ENCRYPTION_NORMAL: + aes_decrypt_buffer(session_key_, p, exe_length, buffer, uncompressed_size); + return 0; + default: + assert_always(); + return 1; + } + + return 0; +} + +int XexModule::ReadImageBasicCompressed(const void* xex_addr, size_t xex_length) { + const uint32_t exe_length = static_cast(xex_length - xex_header()->header_size); + const uint8_t* source_buffer = (const uint8_t*)xex_addr + xex_header()->header_size; + const uint8_t* p = source_buffer; + + auto heap = memory()->LookupHeap(base_address_); + + // Calculate uncompressed length. + uint32_t uncompressed_size = 0; + + auto* file_info = opt_file_format_info(); + auto& comp_info = file_info->compression_info.basic; + + uint32_t block_count = (file_info->info_size - 8) / 8; + for (uint32_t n = 0; n < block_count; n++) { + const uint32_t data_size = comp_info.blocks[n].data_size; + const uint32_t zero_size = comp_info.blocks[n].zero_size; + uncompressed_size += data_size + zero_size; + } + + // Calculate the total size of the XEX image from its headers. + uint32_t total_size = 0; + for (uint32_t i = 0; i < xex_security_info()->page_descriptor_count; i++) { + // Byteswap the bitfield manually. + xex2_page_descriptor desc; + desc.value = rex::byte_swap(xex_security_info()->page_descriptors[i].value); + + total_size += desc.page_count * heap->page_size(); + } + + // Allocate in-place the XEX memory. + bool alloc_result = + heap->AllocFixed(base_address_, total_size, 4096, + rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite); + if (!alloc_result) { + REXLOG_ERROR("Unable to allocate XEX memory at {:08X}-{:08X}.", base_address_, + uncompressed_size); + return 1; + } + + uint8_t* buffer = memory()->TranslateVirtual(base_address_); + std::memset(buffer, 0, total_size); // Quickly zero the contents. + uint8_t* d = buffer; + + uint32_t rk[4 * (MAXNR + 1)]; + uint8_t ivec[16] = {0}; + int32_t Nr = rijndaelKeySetupDec(rk, session_key_, 128); + + for (size_t n = 0; n < block_count; n++) { + const uint32_t data_size = comp_info.blocks[n].data_size; + const uint32_t zero_size = comp_info.blocks[n].zero_size; + + switch (opt_file_format_info()->encryption_type) { + case XEX_ENCRYPTION_NONE: + if (data_size > uncompressed_size - (d - buffer)) { + // Overflow. + return 1; + } + memcpy(d, p, data_size); + break; + case XEX_ENCRYPTION_NORMAL: { + const uint8_t* ct = p; + uint8_t* pt = d; + for (size_t m = 0; m < data_size; m += 16, ct += 16, pt += 16) { + // Decrypt 16 uint8_ts from input -> output. + rijndaelDecrypt(rk, Nr, ct, pt); + for (size_t i = 0; i < 16; i++) { + // XOR with previous. + pt[i] ^= ivec[i]; + // Set previous. + ivec[i] = ct[i]; + } + } + } break; + default: + assert_always(); + return 1; + } + + p += data_size; + d += data_size + zero_size; + } + + return 0; +} + +int XexModule::ReadImageCompressed(const void* xex_addr, size_t xex_length) { + const uint32_t exe_length = static_cast(xex_length - xex_header()->header_size); + const uint8_t* exe_buffer = (const uint8_t*)xex_addr + xex_header()->header_size; + + // src -> dest: + // - decrypt (if encrypted) + // - de-block: + // 4b total size of next block in uint8_ts + // 20b hash of entire next block (including size/hash) + // Nb block uint8_ts + // - decompress block contents + + uint8_t* compress_buffer = NULL; + const uint8_t* p = NULL; + uint8_t* d = NULL; + sha1::SHA1 s; + + // Decrypt (if needed). + bool free_input = false; + const uint8_t* input_buffer = exe_buffer; + size_t input_size = exe_length; + + switch (opt_file_format_info()->encryption_type) { + case XEX_ENCRYPTION_NONE: + // No-op. + break; + case XEX_ENCRYPTION_NORMAL: + // TODO: a way to do without a copy/alloc? + free_input = true; + input_buffer = (const uint8_t*)calloc(1, exe_length); + aes_decrypt_buffer(session_key_, exe_buffer, exe_length, (uint8_t*)input_buffer, exe_length); + break; + default: + assert_always(); + return 1; + } + + const auto* compression_info = &opt_file_format_info()->compression_info; + const xex2_compressed_block_info* cur_block = &compression_info->normal.first_block; + + compress_buffer = (uint8_t*)calloc(1, exe_length); + + p = input_buffer; + d = compress_buffer; + + // De-block. + int result_code = 0; + + uint8_t block_calced_digest[0x14]; + while (cur_block->block_size) { + const uint8_t* pnext = p + cur_block->block_size; + const auto* next_block = (const xex2_compressed_block_info*)p; + + // Compare block hash, if no match we probably used wrong decrypt key + s.reset(); + s.processBytes(p, cur_block->block_size); + s.finalize(block_calced_digest); + if (memcmp(block_calced_digest, cur_block->block_hash, 0x14) != 0) { + result_code = 2; + break; + } + + // skip block info + p += 4; + p += 20; + + while (true) { + const size_t chunk_size = (p[0] << 8) | p[1]; + p += 2; + if (!chunk_size) { + break; + } + + memcpy(d, p, chunk_size); + p += chunk_size; + d += chunk_size; + } + + p = pnext; + cur_block = next_block; + } + + if (!result_code) { + uint32_t uncompressed_size = image_size(); + + // Allocate in-place the XEX memory. + bool alloc_result = + memory() + ->LookupHeap(base_address_) + ->AllocFixed( + base_address_, uncompressed_size, 4096, + rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite); + + if (alloc_result) { + uint8_t* buffer = memory()->TranslateVirtual(base_address_); + std::memset(buffer, 0, uncompressed_size); + + // Decompress into XEX base + result_code = lzx_decompress(compress_buffer, d - compress_buffer, buffer, uncompressed_size, + compression_info->normal.window_size, nullptr, 0); + } else { + REXLOG_ERROR("Unable to allocate XEX memory at {:08X}-{:08X}.", base_address_, + uncompressed_size); + result_code = 3; + } + } + + if (compress_buffer) { + free((void*)compress_buffer); + } + if (free_input) { + free((void*)input_buffer); + } + return result_code; +} + +int XexModule::ReadPEHeaders() { + const uint8_t* p = memory()->TranslateVirtual(base_address_); + + // Verify DOS signature (MZ). + auto doshdr = reinterpret_cast(p); + if (doshdr->e_magic != IMAGE_DOS_SIGNATURE) { + REXLOG_ERROR("PE signature mismatch; likely bad decryption/decompression"); + return 1; + } + + // Move to the NT header offset from the DOS header. + p += doshdr->e_lfanew; + + // Verify NT signature (PE\0\0). + auto nthdr = reinterpret_cast(p); + if (nthdr->Signature != IMAGE_NT_SIGNATURE) { + return 1; + } + + // Verify matches an Xbox PE. + const IMAGE_FILE_HEADER* filehdr = &nthdr->FileHeader; + if ((filehdr->Machine != IMAGE_FILE_MACHINE_POWERPCBE) || + !(filehdr->Characteristics & IMAGE_FILE_32BIT_MACHINE)) { + return 1; + } + // Verify the expected size. + if (filehdr->SizeOfOptionalHeader != IMAGE_SIZEOF_NT_OPTIONAL_HEADER) { + return 1; + } + + // Verify optional header is 32bit. + const IMAGE_OPTIONAL_HEADER32* opthdr = &nthdr->OptionalHeader; + if (opthdr->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + return 1; + } + // Verify subsystem. + if (opthdr->Subsystem != IMAGE_SUBSYSTEM_XBOX) { + return 1; + } + +// Linker version - likely 8+ +// Could be useful for recognizing certain patterns +// opthdr->MajorLinkerVersion; opthdr->MinorLinkerVersion; + +// Data directories of interest: +// EXPORT IMAGE_EXPORT_DIRECTORY +// IMPORT IMAGE_IMPORT_DESCRIPTOR[] +// EXCEPTION IMAGE_CE_RUNTIME_FUNCTION_ENTRY[] +// BASERELOC +// DEBUG IMAGE_DEBUG_DIRECTORY[] +// ARCHITECTURE /IMAGE_ARCHITECTURE_HEADER/ ----- import thunks! +// TLS IMAGE_TLS_DIRECTORY +// IAT Import Address Table ptr +// opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_X].VirtualAddress / .Size + +// The macros in pe_image.h don't work with clang, for some reason. +// offsetof seems to be unable to find OptionalHeader. +#define offsetof1(type, member) ((std::size_t)&(((type*)0)->member)) +#define IMAGE_FIRST_SECTION1(ntheader) \ + ((PIMAGE_SECTION_HEADER)((uint8_t*)ntheader + offsetof1(IMAGE_NT_HEADERS, OptionalHeader) + \ + ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader)) + + // Quick scan to determine bounds of sections. + size_t upper_address = 0; + const IMAGE_SECTION_HEADER* sechdr = IMAGE_FIRST_SECTION1(nthdr); + for (size_t n = 0; n < filehdr->NumberOfSections; n++, sechdr++) { + const size_t physical_address = opthdr->ImageBase + sechdr->VirtualAddress; + upper_address = std::max(upper_address, physical_address + sechdr->Misc.VirtualSize); + } + + // Setup/load sections. + sechdr = IMAGE_FIRST_SECTION1(nthdr); + for (size_t n = 0; n < filehdr->NumberOfSections; n++, sechdr++) { + PESection section; + memcpy(section.name, sechdr->Name, sizeof(sechdr->Name)); + section.name[8] = 0; + section.raw_address = sechdr->PointerToRawData; + section.raw_size = sechdr->SizeOfRawData; + section.address = base_address_ + sechdr->VirtualAddress; + section.size = sechdr->Misc.VirtualSize; + section.flags = sechdr->Characteristics; + pe_sections_.push_back(section); + } + + // Extract Exception DataDirectory (PDATA table location) + // This is the authoritative source for PDATA location, not the .pdata section header. + // The .pdata section's VirtualAddress may differ from the DataDirectory entry. + // NOTE: PE headers are little-endian (PE spec), no byte-swap needed. + exception_dir_rva_ = opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress; + exception_dir_size_ = opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size; + + // DumpTLSDirectory(pImageBase, pNTHeader, (PIMAGE_TLS_DIRECTORY32)0); + // DumpExportsSection(pImageBase, pNTHeader); + return 0; +} + +void XexModule::ReadSecurityInfo() { + if (xex_format_ == kFormatXex1) { + const xex1_security_info* xex1_sec_info = + reinterpret_cast(GetSecurityInfo(xex_header())); + + security_info_.rsa_signature = xex1_sec_info->rsa_signature; + security_info_.aes_key = xex1_sec_info->aes_key; + security_info_.image_size = xex1_sec_info->image_size; + security_info_.image_flags = xex1_sec_info->image_flags; + security_info_.export_table = xex1_sec_info->export_table; + security_info_.load_address = xex1_sec_info->load_address; + security_info_.page_descriptor_count = xex1_sec_info->page_descriptor_count; + security_info_.page_descriptors = xex1_sec_info->page_descriptors; + } else if (xex_format_ == kFormatXex2) { + const xex2_security_info* xex2_sec_info = + reinterpret_cast(GetSecurityInfo(xex_header())); + + security_info_.rsa_signature = xex2_sec_info->rsa_signature; + security_info_.aes_key = xex2_sec_info->aes_key; + security_info_.image_size = xex2_sec_info->image_size; + security_info_.image_flags = xex2_sec_info->image_flags; + security_info_.export_table = xex2_sec_info->export_table; + security_info_.load_address = xex2_sec_info->load_address; + security_info_.page_descriptor_count = xex2_sec_info->page_descriptor_count; + security_info_.page_descriptors = xex2_sec_info->page_descriptors; + } +} + +bool XexModule::Load(const std::string_view name, const std::string_view path, const void* xex_addr, + size_t xex_length) { + auto src_header = reinterpret_cast(xex_addr); + + if (src_header->magic == kXEX1Signature) { + xex_format_ = kFormatXex1; + } else if (src_header->magic == kXEX2Signature) { + xex_format_ = kFormatXex2; + } else { + return false; + } + + assert_false(loaded_); + loaded_ = true; + + // Read in XEX headers + xex_header_mem_.resize(src_header->header_size); + std::memcpy(xex_header_mem_.data(), src_header, src_header->header_size); + + // Read/convert XEX1/XEX2 security info to a common format + ReadSecurityInfo(); + + auto sec_header = xex_security_info(); + + // Try setting our base_address based on XEX_HEADER_IMAGE_BASE_ADDRESS, fall + // back to xex_security_info otherwise + base_address_ = xex_security_info()->load_address; + rex::be* base_addr_opt = nullptr; + if (GetOptHeader(XEX_HEADER_IMAGE_BASE_ADDRESS, &base_addr_opt)) + base_address_ = *base_addr_opt; + + // Setup debug info. + name_ = name; + path_ = path; + + uint8_t* data = memory()->TranslateVirtual(base_address_); + + // Load in the XEX basefile + // We'll try using both XEX2 keys to see if any give a valid PE + int result_code = ReadImage(xex_addr, xex_length, false); + if (result_code) { + REXLOG_WARN("XEX load failed with code {}, trying with devkit encryption key...", result_code); + + result_code = ReadImage(xex_addr, xex_length, true); + if (result_code) { + REXLOG_ERROR("XEX load failed with code {}, tried both encryption keys", result_code); + return false; + } + } + + // Note: caller will have to call LoadContinue once it's determined whether a + // patch file exists or not! + return true; +} + +bool XexModule::LoadContinue() { + // Second part of image load + // Split from Load() so that we can patch the XEX before loading this data + assert_false(finished_load_); + if (finished_load_) { + return true; + } + + finished_load_ = true; + + if (ReadPEHeaders()) { + REXLOG_ERROR("Failed to load XEX PE headers!"); + return false; + } + + // Parse any "unsafe" headers into safer variants + xex2_opt_generic_u32* alternate_titleids; + if (GetOptHeader(xex2_header_keys::XEX_HEADER_ALTERNATE_TITLE_IDS, &alternate_titleids)) { + auto count = alternate_titleids->count(); + for (uint32_t i = 0; i < count; i++) { + opt_alternate_title_ids_.push_back(alternate_titleids->values[i]); + } + } + + // Scan and find the low/high addresses. + // All code sections are continuous, so this should be easy. + auto heap = memory()->LookupHeap(base_address_); + auto page_size = heap->page_size(); + + low_address_ = UINT_MAX; + high_address_ = 0; + + auto sec_header = xex_security_info(); + for (uint32_t i = 0, page = 0; i < sec_header->page_descriptor_count; i++) { + // Byteswap the bitfield manually. + xex2_page_descriptor desc; + desc.value = rex::byte_swap(sec_header->page_descriptors[i].value); + + const auto start_address = base_address_ + (page * page_size); + const auto end_address = start_address + (desc.page_count * page_size); + if (desc.info == XEX_SECTION_CODE) { + low_address_ = std::min(low_address_, start_address); + high_address_ = std::max(high_address_, end_address); + } + + page += desc.page_count; + } + + // NOTE(tomc): Backend notification not needed - no JIT in rexglue + // processor_->backend()->CommitExecutableRange(low_address_, high_address_); + + // Add all imports (variables/functions). + xex2_opt_import_libraries* opt_import_libraries = nullptr; + GetOptHeader(XEX_HEADER_IMPORT_LIBRARIES, &opt_import_libraries); + + if (opt_import_libraries) { + // FIXME: Don't know if 32 is the actual limit, but haven't seen more than + // 2. + const char* string_table[32]; + std::memset(string_table, 0, sizeof(string_table)); + + // Parse the string table + for (size_t i = 0, o = 0; i < opt_import_libraries->string_table.size && + o < opt_import_libraries->string_table.count; + ++o) { + assert_true(o < rex::countof(string_table)); + const char* str = &opt_import_libraries->string_table.data[i]; + + string_table[o] = str; + i += std::strlen(str) + 1; + + // Padding + if ((i % 4) != 0) { + i += 4 - (i % 4); + } + } + + auto library_data = reinterpret_cast(opt_import_libraries); + uint32_t library_offset = opt_import_libraries->string_table.size + 12; + while (library_offset < opt_import_libraries->size) { + auto library = reinterpret_cast(library_data + library_offset); + if (!library->size) { + break; + } + size_t library_name_index = library->name_index & 0xFF; + assert_true(library_name_index < opt_import_libraries->string_table.count); + assert_not_null(string_table[library_name_index]); + auto library_name = std::string(string_table[library_name_index]); + SetupLibraryImports(library_name, library); + library_offset += library->size; + } + } + + // Setup memory protection. + for (uint32_t i = 0, page = 0; i < sec_header->page_descriptor_count; i++) { + // Byteswap the bitfield manually. + xex2_page_descriptor desc; + desc.value = rex::byte_swap(sec_header->page_descriptors[i].value); + + auto address = base_address_ + (page * page_size); + auto size = desc.page_count * page_size; + switch (desc.info) { + case XEX_SECTION_CODE: + case XEX_SECTION_READONLY_DATA: + heap->Protect(address, size, memory::kMemoryProtectRead); + break; + case XEX_SECTION_DATA: + heap->Protect(address, size, memory::kMemoryProtectRead | memory::kMemoryProtectWrite); + break; + } + + page += desc.page_count; + } + + // Populate binary introspection data + PopulateBinaryData(); + + return true; +} + +bool XexModule::Unload() { + if (!loaded_) { + return true; + } + loaded_ = false; + + // If this isn't a patch, just deallocate the memory occupied by the exe + if (!is_patch()) { + assert_not_zero(base_address_); + + memory()->LookupHeap(base_address_)->Release(base_address_); + } + + xex_header_mem_.resize(0); + + return true; +} + +bool XexModule::SetupLibraryImports(const std::string_view name, + const xex2_import_library* library) { + // NOTE(tomc): import resolution is done at compile time. + // however, we still need to patch variable imports in guest memory + // since they are accessed via memory loads, not function calls. + + auto base_name = rex::string::utf8_find_base_name_from_guest_path(name); + + // Get export resolver for variable import patching + auto* export_resolver = kernel_state_->emulator()->export_resolver(); + + ImportLibrary library_info; + library_info.name = base_name; + library_info.id = library->id; + library_info.version.value = library->version().value; + library_info.min_version.value = library->version_min().value; + + // Use a map to properly pair type 0 (variable) and type 1 (thunk) records by ordinal. + // Import table entries alternate: type 0 has ordinal info, type 1 has thunk address. + // They may not come in immediate succession, so we pair by ordinal. + std::unordered_map import_map; + + for (uint32_t i = 0; i < library->count; i++) { + uint32_t record_addr = library->import_table[i]; + if (!record_addr) + continue; + + auto record_slot = memory()->TranslateVirtual*>(record_addr); + uint32_t record_value = *record_slot; + + uint16_t record_type = (record_value & 0xFF000000) >> 24; + uint16_t ordinal = record_value & 0xFFFF; + + auto& import_info = import_map[ordinal]; + import_info.ordinal = ordinal; + + if (record_type == 0) { + // Variable import - value_address is where the variable value is stored + import_info.value_address = record_addr; + + // Patch variable imports in guest memory with the actual address + if (export_resolver) { + auto kernel_export = export_resolver->GetExportByOrdinal(base_name, ordinal); + if (kernel_export && kernel_export->type == runtime::Export::Type::kVariable) { + if (kernel_export->is_implemented() && kernel_export->variable_ptr) { + // Write the variable address to guest memory + *record_slot = kernel_export->variable_ptr; + REXLOG_DEBUG("Patched variable import {}:{:#x} ({}) -> {:#x}", base_name, ordinal, + kernel_export->name, kernel_export->variable_ptr); + } else { + // write garbage value if we don't have it implemented + *record_slot = 0xD000BEEF | (kernel_export->ordinal & 0xFFF) << 16; + REXLOG_WARN("Variable import {}:{:#x} ({}) not implemented", base_name, ordinal, + kernel_export->name); + } + } + } + } else if (record_type == 1) { + // Thunk import - thunk_address is the function pointer location + // This is the address we need for function table registration + import_info.thunk_address = record_addr; + } + } + + // Convert map to vector (sorted by ordinal for consistent output) + std::vector ordinals; + ordinals.reserve(import_map.size()); + for (const auto& [ordinal, _] : import_map) { + ordinals.push_back(ordinal); + } + std::sort(ordinals.begin(), ordinals.end()); + + for (uint16_t ordinal : ordinals) { + library_info.imports.push_back(import_map[ordinal]); + } + + import_libs_.push_back(library_info); + REXLOG_DEBUG("created symbols for import library {} with {} imports", base_name, + library_info.imports.size()); + + return true; +} + +bool XexModule::ContainsAddress(uint32_t address) { + return address >= low_address_ && address < high_address_; +} + +// Binary introspection implementation +void XexModule::PopulateBinaryData() { + binary_sections_.clear(); + binary_symbols_.clear(); + + // Populate sections from existing PE sections + for (const auto& pe_sec : pe_sections_) { + BinarySection sec; + sec.name = pe_sec.name; + sec.virtual_address = pe_sec.address; + sec.virtual_size = pe_sec.size; + sec.host_data = memory()->TranslateVirtual(pe_sec.address); + sec.executable = (pe_sec.flags & kXEPESectionMemoryExecute) != 0; + sec.writable = (pe_sec.flags & kXEPESectionMemoryWrite) != 0; + binary_sections_.push_back(std::move(sec)); + } + + // Populate symbols from import libraries + for (const auto& lib : import_libs_) { + for (const auto& import : lib.imports) { + BinarySymbol sym; + sym.name = fmt::format("{}@{}", lib.name, import.ordinal); + sym.address = import.thunk_address; + sym.size = 16; // Thunk size: 2 ordinal words + mtctr + bctr + sym.type = BinarySymbolType::Import; + binary_symbols_.push_back(std::move(sym)); + } + } +} + +std::span XexModule::binary_sections() const { + return binary_sections_; +} + +const BinarySection* XexModule::FindSectionByName(std::string_view name) const { + for (const auto& sec : binary_sections_) { + if (sec.name == name) + return &sec; + } + return nullptr; +} + +std::span XexModule::binary_symbols() const { + return binary_symbols_; +} + +} // namespace rex::runtime diff --git a/src/system/xfile.cpp b/src/system/xfile.cpp new file mode 100644 index 0000000..b0971cb --- /dev/null +++ b/src/system/xfile.cpp @@ -0,0 +1,375 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace rex::system { + +XFile::XFile(KernelState* kernel_state, rex::filesystem::File* file, bool synchronous) + : XObject(kernel_state, kObjectType), file_(file), is_synchronous_(synchronous) { + async_event_ = rex::thread::Event::CreateAutoResetEvent(false); + assert_not_null(async_event_); +} + +XFile::XFile() : XObject(kObjectType) { + async_event_ = rex::thread::Event::CreateAutoResetEvent(false); + assert_not_null(async_event_); +} + +XFile::~XFile() { + // TODO(benvanik): signal that the file is closing? + async_event_->Set(); + file_->Destroy(); +} + +uint64_t XFile::position() const { + std::lock_guard lock(file_lock_); + return position_; +} + +void XFile::set_position(uint64_t value) { + std::lock_guard lock(file_lock_); + position_ = value; +} + +X_STATUS XFile::QueryDirectory(X_FILE_DIRECTORY_INFORMATION* out_info, size_t length, + const std::string_view file_name, bool restart) { + std::lock_guard lock(file_lock_); + assert_not_null(out_info); + + rex::filesystem::Entry* entry = nullptr; + + if (!file_name.empty()) { + // Only queries in the current directory are supported for now. + assert_true(rex::string::utf8_find_any_of(file_name, "\\") == std::string_view::npos); + + find_engine_.SetRule(file_name); + + // Always restart the search? + find_index_ = 0; + entry = file_->entry()->IterateChildren(find_engine_, &find_index_); + if (!entry) { + return X_STATUS_NO_SUCH_FILE; + } + } else { + if (restart) { + find_index_ = 0; + } + + entry = file_->entry()->IterateChildren(find_engine_, &find_index_); + if (!entry) { + return X_STATUS_NO_MORE_FILES; + } + } + + auto end = reinterpret_cast(out_info) + length; + const auto& entry_name = entry->name(); + if (reinterpret_cast(&out_info->file_name[0]) + entry_name.size() > end) { + assert_always("Buffer overflow?"); + return X_STATUS_NO_SUCH_FILE; + } + + out_info->next_entry_offset = 0; + out_info->file_index = static_cast(find_index_); + out_info->creation_time = entry->create_timestamp(); + out_info->last_access_time = entry->access_timestamp(); + out_info->last_write_time = entry->write_timestamp(); + out_info->change_time = entry->write_timestamp(); + out_info->end_of_file = entry->size(); + out_info->allocation_size = entry->allocation_size(); + out_info->attributes = entry->attributes(); + out_info->file_name_length = static_cast(entry_name.size()); + std::memcpy(out_info->file_name, entry_name.data(), entry_name.size()); + + return X_STATUS_SUCCESS; +} + +X_STATUS XFile::Read(uint32_t buffer_guest_address, uint32_t buffer_length, uint64_t byte_offset, + uint32_t* out_bytes_read, uint32_t apc_context, bool notify_completion) { + std::lock_guard lock(file_lock_); + return ReadInternal(buffer_guest_address, buffer_length, byte_offset, out_bytes_read, apc_context, + notify_completion); +} + +X_STATUS XFile::ReadInternal(uint32_t buffer_guest_address, uint32_t buffer_length, + uint64_t byte_offset, uint32_t* out_bytes_read, uint32_t apc_context, + bool notify_completion) { + if (byte_offset == uint64_t(-1)) { + // Read from current position. + byte_offset = position_; + } + + size_t bytes_read = 0; + X_STATUS result = X_STATUS_SUCCESS; + // Zero length means success for a valid file object according to Windows + // tests. + if (buffer_length) { + if (UINT32_MAX - buffer_guest_address < buffer_length) { + result = X_STATUS_ACCESS_VIOLATION; + } else { + // Games often read directly to texture/vertex buffer memory - in this + // case, invalidation notifications must be sent. However, having any + // memory callbacks in the range will result in STATUS_ACCESS_VIOLATION at + // least on Windows, without anything being read or any callbacks being + // triggered. So for physical memory, host protection must be bypassed, + // and invalidation callbacks must be triggered manually (it's also wrong + // to trigger invalidation callbacks before reading in this case, because + // during the read, the guest may still access the data around the buffer + // that is located in the same host pages as the buffer's start and end, + // on the GPU - and that must not trigger a race condition). + uint32_t buffer_guest_high_address = buffer_guest_address + buffer_length - 1; + rex::memory::BaseHeap* buffer_start_heap = memory()->LookupHeap(buffer_guest_address); + const rex::memory::BaseHeap* buffer_end_heap = + memory()->LookupHeap(buffer_guest_high_address); + if (!buffer_start_heap || !buffer_end_heap || + (buffer_start_heap->heap_type() == memory::HeapType::kGuestPhysical) != + (buffer_end_heap->heap_type() == memory::HeapType::kGuestPhysical) || + (buffer_start_heap->heap_type() == memory::HeapType::kGuestPhysical && + buffer_start_heap != buffer_end_heap)) { + result = X_STATUS_ACCESS_VIOLATION; + } else { + rex::memory::PhysicalHeap* buffer_physical_heap = + buffer_start_heap->heap_type() == memory::HeapType::kGuestPhysical + ? static_cast(buffer_start_heap) + : nullptr; + if (buffer_physical_heap && buffer_physical_heap->QueryRangeAccess( + buffer_guest_address, buffer_guest_high_address) != + memory::PageAccess::kReadWrite) { + result = X_STATUS_ACCESS_VIOLATION; + } else { + result = file_->ReadSync( + std::span( + buffer_physical_heap + ? memory()->TranslatePhysical( + buffer_physical_heap->GetPhysicalAddress(buffer_guest_address)) + : memory()->TranslateVirtual(buffer_guest_address), + buffer_length), + size_t(byte_offset), &bytes_read); + if (XSUCCEEDED(result)) { + if (buffer_physical_heap) { + buffer_physical_heap->TriggerCallbacks( + rex::thread::global_critical_region::AcquireDirect(), buffer_guest_address, + buffer_length, true, true); + } + + if (byte_offset) { + position_ = byte_offset; + } + position_ += bytes_read; + } + } + } + } + } + + if (out_bytes_read) { + *out_bytes_read = uint32_t(bytes_read); + } + + if (notify_completion) { + XIOCompletion::IONotification notify; + notify.apc_context = apc_context; + notify.num_bytes = uint32_t(bytes_read); + notify.status = result; + + NotifyIOCompletionPorts(notify); + + async_event_->Set(); + } + + return result; +} + +X_STATUS XFile::ReadScatter(uint32_t segments_guest_address, uint32_t length, uint64_t byte_offset, + uint32_t* out_bytes_read, uint32_t apc_context) { + std::lock_guard lock(file_lock_); + X_STATUS result = X_STATUS_SUCCESS; + + // segments points to an array of buffer pointers of type + // "FILE_SEGMENT_ELEMENT", but they can just be treated as normal pointers + rex::be* segments = + reinterpret_cast*>(memory()->TranslateVirtual(segments_guest_address)); + + // TODO: not sure if this is meant to change depending on buffer address? + // (only game seen using this always seems to use 4096-byte buffers) + uint32_t page_size = 4096; + + uint32_t read_total = 0; + uint32_t read_remain = length; + while (read_remain) { + uint32_t read_length = read_remain; + uint32_t read_buffer = *segments; + if (read_length > page_size) { + read_length = page_size; + segments++; + } + + uint32_t bytes_read = 0; + result = ReadInternal( + read_buffer, read_length, + byte_offset + ? ((byte_offset != -1 && byte_offset != -2) ? byte_offset + read_total : byte_offset) + : -1, + &bytes_read, apc_context, false); + + if (result != X_STATUS_SUCCESS) { + break; + } + + read_total += bytes_read; + read_remain -= read_length; + } + + if (out_bytes_read) { + *out_bytes_read = uint32_t(read_total); + } + + XIOCompletion::IONotification notify; + notify.apc_context = apc_context; + notify.num_bytes = uint32_t(read_total); + notify.status = result; + + NotifyIOCompletionPorts(notify); + + async_event_->Set(); + + return result; +} + +X_STATUS XFile::Write(uint32_t buffer_guest_address, uint32_t buffer_length, uint64_t byte_offset, + uint32_t* out_bytes_written, uint32_t apc_context) { + std::lock_guard lock(file_lock_); + if (byte_offset == uint64_t(-1)) { + // Write from current position. + byte_offset = position_; + } + + size_t bytes_written = 0; + X_STATUS result = file_->WriteSync( + std::span(memory()->TranslateVirtual(buffer_guest_address), buffer_length), + size_t(byte_offset), &bytes_written); + if (XSUCCEEDED(result)) { + position_ += bytes_written; + } + + XIOCompletion::IONotification notify; + notify.apc_context = apc_context; + notify.num_bytes = uint32_t(bytes_written); + notify.status = result; + + NotifyIOCompletionPorts(notify); + + if (out_bytes_written) { + *out_bytes_written = uint32_t(bytes_written); + } + + async_event_->Set(); + return result; +} + +X_STATUS XFile::SetLength(size_t length) { + std::lock_guard lock(file_lock_); + return file_->SetLength(length); +} + +X_STATUS XFile::Rename(const std::filesystem::path& file_path) { + std::lock_guard lock(file_lock_); + entry()->Rename(file_path); + return X_STATUS_SUCCESS; +} + +void XFile::RegisterIOCompletionPort(uint32_t key, object_ref port) { + std::lock_guard lock(completion_port_lock_); + + completion_ports_.push_back({key, port}); +} + +void XFile::RemoveIOCompletionPort(uint32_t key) { + std::lock_guard lock(completion_port_lock_); + + for (auto it = completion_ports_.begin(); it != completion_ports_.end(); it++) { + if (it->first == key) { + completion_ports_.erase(it); + break; + } + } +} + +bool XFile::Save(stream::ByteStream* stream) { + REXSYS_DEBUG("XFile {:08X} ({})", handle(), file_->entry()->absolute_path().c_str()); + + if (!SaveObject(stream)) { + return false; + } + + stream->Write(file_->entry()->absolute_path()); + stream->Write(position_); + stream->Write(file_access()); + stream->Write((file_->entry()->attributes() & rex::filesystem::kFileAttributeDirectory) != + 0); + stream->Write(is_synchronous_); + + return true; +} + +object_ref XFile::Restore(KernelState* kernel_state, stream::ByteStream* stream) { + auto file = new XFile(); + file->kernel_state_ = kernel_state; + if (!file->RestoreObject(stream)) { + delete file; + return nullptr; + } + + auto abs_path = stream->Read(); + uint64_t position = stream->Read(); + auto access = stream->Read(); + auto is_directory = stream->Read(); + auto is_synchronous = stream->Read(); + + REXSYS_DEBUG("XFile {:08X} ({})", file->handle(), abs_path); + + rex::filesystem::File* vfs_file = nullptr; + rex::filesystem::FileAction action; + auto res = kernel_state->file_system()->OpenFile(nullptr, abs_path, + rex::filesystem::FileDisposition::kOpen, access, + is_directory, false, &vfs_file, &action); + if (XFAILED(res)) { + REXSYS_ERROR("Failed to open XFile: error {:08X}", res); + return object_ref(file); + } + + file->file_ = vfs_file; + file->position_ = position; + file->is_synchronous_ = is_synchronous; + + return object_ref(file); +} + +void XFile::NotifyIOCompletionPorts(XIOCompletion::IONotification& notification) { + std::lock_guard lock(completion_port_lock_); + + for (auto port : completion_ports_) { + notification.key_context = port.first; + port.second->QueueNotification(notification); + } +} + +} // namespace rex::system diff --git a/src/system/xiocompletion.cpp b/src/system/xiocompletion.cpp new file mode 100644 index 0000000..0a48dc9 --- /dev/null +++ b/src/system/xiocompletion.cpp @@ -0,0 +1,46 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +namespace rex::system { + +XIOCompletion::XIOCompletion(KernelState* kernel_state) : XObject(kernel_state, kObjectType) { + notification_semaphore_ = rex::thread::Semaphore::Create(0, kMaxNotifications); + assert_not_null(notification_semaphore_); +} + +XIOCompletion::~XIOCompletion() = default; + +void XIOCompletion::QueueNotification(IONotification& notification) { + std::unique_lock lock(notification_lock_); + + notifications_.push(notification); + notification_semaphore_->Release(1, nullptr); +} + +bool XIOCompletion::WaitForNotification(uint64_t wait_ticks, IONotification* notify) { + auto ms = std::chrono::milliseconds(TimeoutTicksToMs(wait_ticks)); + auto res = rex::thread::Wait(notification_semaphore_.get(), false, ms); + if (res == rex::thread::WaitResult::kSuccess) { + std::unique_lock lock(notification_lock_); + assert_false(notifications_.empty()); + + std::memcpy(notify, ¬ifications_.front(), sizeof(IONotification)); + notifications_.pop(); + + return true; + } + + return false; +} + +} // namespace rex::system diff --git a/src/system/xmemory.cpp b/src/system/xmemory.cpp new file mode 100644 index 0000000..ca7f4e8 --- /dev/null +++ b/src/system/xmemory.cpp @@ -0,0 +1,2051 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// TODO(benvanik): move xbox.h out +#include + +REXCVAR_DEFINE_BOOL(protect_zero, true, "Memory", "Protect the zero page from reads and writes") + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_BOOL(protect_on_release, false, "Memory", + "Protect released memory to prevent accesses"); + +REXCVAR_DEFINE_BOOL(scribble_heap, false, "Memory", "Scribble 0xCD into all allocated heap memory"); + +namespace rex::memory { + +uint32_t get_page_count(uint32_t value, uint32_t page_size, uint32_t page_size_shift) { + return rex::round_up(value, page_size) >> page_size_shift; +} + +/** + * Memory map: + * 0x00000000 - 0x3FFFFFFF (1024mb) - virtual 4k pages + * 0x40000000 - 0x7FFFFFFF (1024mb) - virtual 64k pages + * 0x80000000 - 0x8BFFFFFF ( 192mb) - xex 64k pages + * 0x8C000000 - 0x8FFFFFFF ( 64mb) - xex 64k pages (encrypted) + * 0x90000000 - 0x9FFFFFFF ( 256mb) - xex 4k pages + * 0xA0000000 - 0xBFFFFFFF ( 512mb) - physical 64k pages + * 0xC0000000 - 0xDFFFFFFF - physical 16mb pages + * 0xE0000000 - 0xFFFFFFFF - physical 4k pages + * + * We use the host OS to create an entire addressable range for this. That way + * we don't have to emulate a TLB. It'd be really cool to pass through page + * sizes or use madvice to let the OS know what to expect. + * + * We create our own heap of committed memory that lives at + * memory_HEAP_LOW to memory_HEAP_HIGH - all normal user allocations + * come from there. Since the Xbox has no paging, we know that the size of + * this heap will never need to be larger than ~512MB (realistically, smaller + * than that). We place it far away from the XEX data and keep the memory + * around it uncommitted so that we have some warning if things go astray. + * + * For XEX/GPU/etc data we allow placement allocations (base_address != 0) and + * commit the requested memory as needed. This bypasses the standard heap, but + * XEXs should never be overwriting anything so that's fine. We can also query + * for previous commits and assert that we really isn't committing twice. + * + * GPU memory is mapped onto the lower 512mb of the virtual 4k range (0). + * So 0xA0000000 = 0x00000000. A more sophisticated allocator could handle + * this. + */ + +static memory::Memory* active_memory_ = nullptr; + +void CrashDump() { + static std::atomic in_crash_dump(0); + if (in_crash_dump.fetch_add(1)) { + // rex::FatalError( + // "Hard crash: the memory system crashed while dumping a crash dump."); + return; + } + active_memory_->DumpMap(); + --in_crash_dump; +} + +Memory::Memory() { + system_page_size_ = uint32_t(rex::memory::page_size()); + system_allocation_granularity_ = uint32_t(rex::memory::allocation_granularity()); + assert_zero(active_memory_); + active_memory_ = this; +} + +Memory::~Memory() { + assert_true(active_memory_ == this); + active_memory_ = nullptr; + + // Uninstall the MMIO handler, as we won't be able to service more requests. + mmio_handler_.reset(); + + for (auto invalidation_callback : physical_memory_invalidation_callbacks_) { + delete invalidation_callback; + } + + heaps_.v00000000.Dispose(); + heaps_.v40000000.Dispose(); + heaps_.v80000000.Dispose(); + heaps_.v90000000.Dispose(); + heaps_.vA0000000.Dispose(); + heaps_.vC0000000.Dispose(); + heaps_.vE0000000.Dispose(); + heaps_.physical.Dispose(); + + // Unmap all views and close mapping. + if (mapping_ != rex::memory::kFileMappingHandleInvalid) { + UnmapViews(); + rex::memory::CloseFileMappingHandle(mapping_, file_name_); + mapping_base_ = nullptr; + mapping_ = rex::memory::kFileMappingHandleInvalid; + } + + virtual_membase_ = nullptr; + physical_membase_ = nullptr; +} + +bool Memory::Initialize() { + file_name_ = fmt::format("xenia_memory_{}", chrono::Clock::QueryHostTickCount()); + + // Create main page file-backed mapping. This is all reserved but + // uncommitted (so it shouldn't expand page file). + mapping_ = + rex::memory::CreateFileMappingHandle(file_name_, + // entire 4gb space + 512mb physical: + 0x11FFFFFFF, rex::memory::PageAccess::kReadWrite, false); + if (mapping_ == rex::memory::kFileMappingHandleInvalid) { + REXSYS_ERROR("Unable to reserve the 4gb guest address space."); + assert_always(); + return false; + } + + // Attempt to create our views. This may fail at the first address + // we pick, so try a few times. + mapping_base_ = 0; + for (size_t n = 32; n < 64; n++) { + auto mapping_base = reinterpret_cast(1ull << n); + if (!MapViews(mapping_base)) { + mapping_base_ = mapping_base; + break; + } + } + if (!mapping_base_) { + REXSYS_ERROR("Unable to find a continuous block in the 64bit address space."); + assert_always(); + return false; + } + virtual_membase_ = mapping_base_; + physical_membase_ = mapping_base_ + 0x100000000ull; + + // Prepare virtual heaps. + heaps_.v00000000.Initialize(this, virtual_membase_, memory::HeapType::kGuestVirtual, 0x00000000, + 0x40000000, 4096); + heaps_.v40000000.Initialize(this, virtual_membase_, memory::HeapType::kGuestVirtual, 0x40000000, + 0x40000000 - 0x01000000, 64 * 1024); + heaps_.v80000000.Initialize(this, virtual_membase_, memory::HeapType::kGuestXex, 0x80000000, + 0x10000000, 64 * 1024); + heaps_.v90000000.Initialize(this, virtual_membase_, memory::HeapType::kGuestXex, 0x90000000, + 0x10000000, 4096); + + // Prepare physical heaps. + heaps_.physical.Initialize(this, physical_membase_, memory::HeapType::kGuestPhysical, 0x00000000, + 0x20000000, 4096); + heaps_.vA0000000.Initialize(this, virtual_membase_, memory::HeapType::kGuestPhysical, 0xA0000000, + 0x20000000, 64 * 1024, &heaps_.physical); + heaps_.vC0000000.Initialize(this, virtual_membase_, memory::HeapType::kGuestPhysical, 0xC0000000, + 0x20000000, 16 * 1024 * 1024, &heaps_.physical); + heaps_.vE0000000.Initialize(this, virtual_membase_, memory::HeapType::kGuestPhysical, 0xE0000000, + 0x1FD00000, 4096, &heaps_.physical); + + // Protect the first and last 64kb of memory. + heaps_.v00000000.AllocFixed(0x00000000, 0x10000, 0x10000, + memory::kMemoryAllocationReserve | memory::kMemoryAllocationCommit, + !REXCVAR_GET(protect_zero) + ? memory::kMemoryProtectRead | memory::kMemoryProtectWrite + : memory::kMemoryProtectNoAccess); + heaps_.physical.AllocFixed(0x1FFF0000, 0x10000, 0x10000, memory::kMemoryAllocationReserve, + memory::kMemoryProtectNoAccess); + + // GPU writeback. + // 0xC... is physical, 0x7F... is virtual. We may need to overlay these. + heaps_.vC0000000.AllocFixed(0xC0000000, 0x01000000, 32, + memory::kMemoryAllocationReserve | memory::kMemoryAllocationCommit, + memory::kMemoryProtectRead | memory::kMemoryProtectWrite); + + // Pre-commit the physical memory range so the GPU can access it + // without page faults. Reference: xenia-canary 5f5be0668. + rex::memory::AllocFixed(heaps_.physical.TranslateRelative(0), heaps_.physical.heap_size(), + rex::memory::AllocationType::kCommit, + rex::memory::PageAccess::kReadWrite); + + // Install MMIO handler for physical address translation and MMIO ranges + mmio_handler_ = runtime::MMIOHandler::Install( + virtual_membase_, physical_membase_, physical_membase_ + 0x1FFFFFFF, HostToGuestVirtualThunk, + this, AccessViolationCallbackThunk, this); + if (!mmio_handler_) { + REXSYS_ERROR("Unable to install MMIO handlers"); + assert_always(); + return false; + } + REXSYS_DEBUG("Installed MMIO handler for physical address translation"); + + // ? + uint32_t unk_phys_alloc; + heaps_.vA0000000.Alloc(0x340000, 64 * 1024, memory::kMemoryAllocationReserve, + memory::kMemoryProtectNoAccess, true, &unk_phys_alloc); + + // Allocate region at start of XEX range. Title 544307D5 explicitly + // accesses 0x8000001C and expects a specific constant value. + // Reference: xenia-canary 78f97f8ff. + uint32_t unknown_xex_range; + heaps_.v80000000.Alloc(0x40000, 4 * 1024, memory::kMemoryAllocationCommit, + memory::kMemoryProtectRead | memory::kMemoryProtectWrite, false, + &unknown_xex_range); + + uint32_t value_to_write = rex::byte_swap(uint32_t(0x2a6e3f38)); + std::memcpy(TranslateVirtual(0x80000000 + 0x1C), &value_to_write, sizeof(uint32_t)); + + return true; +} + +static const struct { + uint64_t virtual_address_start; + uint64_t virtual_address_end; + uint64_t target_address; +} map_info[] = { + // (1024mb) - virtual 4k pages + { + 0x00000000, + 0x3FFFFFFF, + 0x0000000000000000ull, + }, + // (1024mb) - virtual 64k pages (cont) + { + 0x40000000, + 0x7EFFFFFF, + 0x0000000040000000ull, + }, + // (16mb) - GPU writeback + 15mb of XPS? + { + 0x7F000000, + 0x7FFFFFFF, + 0x0000000100000000ull, + }, + // (256mb) - xex 64k pages + { + 0x80000000, + 0x8FFFFFFF, + 0x0000000080000000ull, + }, + // (256mb) - xex 4k pages + { + 0x90000000, + 0x9FFFFFFF, + 0x0000000080000000ull, + }, + // (512mb) - physical 64k pages + { + 0xA0000000, + 0xBFFFFFFF, + 0x0000000100000000ull, + }, + // - physical 16mb pages + { + 0xC0000000, + 0xDFFFFFFF, + 0x0000000100000000ull, + }, + // - physical 4k pages + { + 0xE0000000, + 0xFFFFFFFF, + 0x0000000100001000ull, + }, + // - physical raw + { + 0x100000000, + 0x11FFFFFFF, + 0x0000000100000000ull, + }, +}; +int Memory::MapViews(uint8_t* mapping_base) { + assert_true(rex::countof(map_info) == rex::countof(views_.all_views)); + // 0xE0000000 4 KB offset is emulated via host_address_offset and on the CPU + // side if system allocation granularity is bigger than 4 KB. + uint64_t granularity_mask = ~uint64_t(system_allocation_granularity_ - 1); + for (size_t n = 0; n < rex::countof(map_info); n++) { + views_.all_views[n] = reinterpret_cast(rex::memory::MapFileView( + mapping_, mapping_base + map_info[n].virtual_address_start, + map_info[n].virtual_address_end - map_info[n].virtual_address_start + 1, + rex::memory::PageAccess::kReadWrite, map_info[n].target_address & granularity_mask)); + if (!views_.all_views[n]) { + // Failed, so bail and try again. + UnmapViews(); + return 1; + } + } + return 0; +} + +void Memory::UnmapViews() { + for (size_t n = 0; n < rex::countof(views_.all_views); n++) { + if (views_.all_views[n]) { + size_t length = map_info[n].virtual_address_end - map_info[n].virtual_address_start + 1; + rex::memory::UnmapFileView(mapping_, views_.all_views[n], length); + } + } +} + +void Memory::Reset() { + heaps_.v00000000.Reset(); + heaps_.v40000000.Reset(); + heaps_.v80000000.Reset(); + heaps_.v90000000.Reset(); + heaps_.physical.Reset(); +} + +const BaseHeap* Memory::LookupHeap(uint32_t address) const { + if (address < 0x40000000) { + return &heaps_.v00000000; + } else if (address < 0x7F000000) { + return &heaps_.v40000000; + } else if (address < 0x80000000) { + return nullptr; + } else if (address < 0x90000000) { + return &heaps_.v80000000; + } else if (address < 0xA0000000) { + return &heaps_.v90000000; + } else if (address < 0xC0000000) { + return &heaps_.vA0000000; + } else if (address < 0xE0000000) { + return &heaps_.vC0000000; + } else if (address < 0xFFD00000) { + return &heaps_.vE0000000; + } else { + return nullptr; + } +} + +BaseHeap* Memory::LookupHeapByType(bool physical, uint32_t page_size) { + if (physical) { + if (page_size <= 4096) { + return &heaps_.vE0000000; + } else if (page_size <= 64 * 1024) { + return &heaps_.vA0000000; + } else { + return &heaps_.vC0000000; + } + } else { + if (page_size <= 4096) { + return &heaps_.v00000000; + } else { + return &heaps_.v40000000; + } + } +} + +VirtualHeap* Memory::GetPhysicalHeap() { + return &heaps_.physical; +} + +uint32_t Memory::HostToGuestVirtual(const void* host_address) const { + size_t virtual_address = + reinterpret_cast(host_address) - reinterpret_cast(virtual_membase_); + uint32_t vE0000000_host_offset = heaps_.vE0000000.host_address_offset(); + size_t vE0000000_host_base = size_t(heaps_.vE0000000.heap_base()) + vE0000000_host_offset; + if (virtual_address >= vE0000000_host_base && + virtual_address <= (vE0000000_host_base + (heaps_.vE0000000.heap_size() - 1))) { + virtual_address -= vE0000000_host_offset; + } + return uint32_t(virtual_address); +} + +uint32_t Memory::HostToGuestVirtualThunk(const void* context, const void* host_address) { + return reinterpret_cast(context)->HostToGuestVirtual(host_address); +} + +uint32_t Memory::GetPhysicalAddress(uint32_t address) const { + const BaseHeap* heap = LookupHeap(address); + if (!heap || heap->heap_type() != memory::HeapType::kGuestPhysical) { + return UINT32_MAX; + } + return static_cast(heap)->GetPhysicalAddress(address); +} + +void Memory::Zero(uint32_t address, uint32_t size) { + std::memset(TranslateVirtual(address), 0, size); +} + +void Memory::Fill(uint32_t address, uint32_t size, uint8_t value) { + std::memset(TranslateVirtual(address), value, size); +} + +void Memory::Copy(uint32_t dest, uint32_t src, uint32_t size) { + uint8_t* pdest = TranslateVirtual(dest); + const uint8_t* psrc = TranslateVirtual(src); + std::memcpy(pdest, psrc, size); +} + +uint32_t Memory::SearchAligned(uint32_t start, uint32_t end, const uint32_t* values, + size_t value_count) { + assert_true(start <= end); + auto p = TranslateVirtual(start); + auto pe = TranslateVirtual(end); + while (p != pe) { + if (*p == values[0]) { + const uint32_t* pc = p + 1; + size_t matched = 1; + for (size_t n = 1; n < value_count; n++, pc++) { + if (*pc != values[n]) { + break; + } + matched++; + } + if (matched == value_count) { + return HostToGuestVirtual(p); + } + } + p++; + } + return 0; +} + +bool Memory::AddVirtualMappedRange(uint32_t virtual_address, uint32_t mask, uint32_t size, + void* context, runtime::MMIOReadCallback read_callback, + runtime::MMIOWriteCallback write_callback) { + if (!rex::memory::AllocFixed(TranslateVirtual(virtual_address), size, + rex::memory::AllocationType::kCommit, + rex::memory::PageAccess::kNoAccess)) { + REXSYS_ERROR("Unable to map range; commit/protect failed"); + return false; + } + return mmio_handler_->RegisterRange(virtual_address, mask, size, context, read_callback, + write_callback); +} + +runtime::MMIORange* Memory::LookupVirtualMappedRange(uint32_t virtual_address) { + return mmio_handler_->LookupRange(virtual_address); +} + +bool Memory::AccessViolationCallback(std::unique_lock global_lock_locked_once, + void* host_address, bool is_write) { + // Access via physical_membase_ is special, when need to bypass everything + // (for instance, for a data provider to actually write the data) so only + // triggering callbacks on virtual memory regions. + if (reinterpret_cast(host_address) < reinterpret_cast(virtual_membase_) || + reinterpret_cast(host_address) >= reinterpret_cast(physical_membase_)) { + return false; + } + uint32_t virtual_address = HostToGuestVirtual(host_address); + BaseHeap* heap = LookupHeap(virtual_address); + if (!heap) { + return false; + } + if (heap->heap_type() != memory::HeapType::kGuestPhysical) { + return false; + } + + // Access violation callbacks from the guest are triggered when the global + // critical region mutex is locked once. + // + // Will be rounded to physical page boundaries internally, so just pass 1 as + // the length - guranteed not to cross page boundaries also. + auto physical_heap = static_cast(heap); + if (physical_heap->TriggerCallbacks(std::move(global_lock_locked_once), virtual_address, 1, + is_write, false)) { + return true; + } + + // Recovery path for stale host protection state in physical memory: + // if guest metadata says the page is writable but host protection is still + // read-only / no-access, restore write access and resume execution. + if (is_write) { + constexpr uint32_t kWriteProtectMask = + memory::kMemoryProtectWrite | memory::kMemoryProtectWriteCombine; + uint32_t guest_protect = 0; + bool allow_write = false; + if (heap->QueryProtect(virtual_address, &guest_protect) && + (guest_protect & kWriteProtectMask)) { + allow_write = true; + } else { + // If write-watch left current protect stale, trust committed allocation + // metadata first for this alias. + HeapAllocationInfo guest_info{}; + if (heap->QueryRegionInfo(virtual_address, &guest_info) && + (guest_info.state & memory::kMemoryAllocationCommit) && + (guest_info.allocation_protect & kWriteProtectMask)) { + guest_protect = guest_info.protect; + allow_write = true; + } else { + // Alias-aware fallback: consult canonical 0x00000000 physical heap + // metadata when this alias has stale tracking. + uint32_t physical_address = GetPhysicalAddress(virtual_address); + if (physical_address != UINT32_MAX) { + uint32_t physical_protect = 0; + if (heaps_.physical.QueryProtect(physical_address, &physical_protect) && + (physical_protect & kWriteProtectMask)) { + guest_protect = physical_protect; + allow_write = true; + } else { + HeapAllocationInfo physical_info{}; + if (heaps_.physical.QueryRegionInfo(physical_address, &physical_info) && + (physical_info.state & memory::kMemoryAllocationCommit) && + (physical_info.allocation_protect & kWriteProtectMask)) { + guest_protect = physical_info.protect; + allow_write = true; + } + } + } + } + } + if (allow_write) { + size_t host_page_size = rex::memory::page_size(); + uintptr_t page_base = + reinterpret_cast(host_address) & ~(uintptr_t(host_page_size - 1)); + if (rex::memory::Protect(reinterpret_cast(page_base), host_page_size, + rex::memory::PageAccess::kReadWrite, nullptr)) { + REXSYS_WARN( + "Recovered stale physical page protection for guest {:08X} (host {:016X}, " + "guest_protect {:08X})", + virtual_address, static_cast(page_base), guest_protect); + return true; + } + } + + uint32_t current_guest_protect = 0; + heap->QueryProtect(virtual_address, ¤t_guest_protect); + uint32_t physical_address = GetPhysicalAddress(virtual_address); + uint32_t physical_protect = 0; + if (physical_address != UINT32_MAX) { + heaps_.physical.QueryProtect(physical_address, &physical_protect); + } + REXSYS_ERROR( + "Unhandled guest physical write fault: guest={:08X} host={:016X} phys={:08X} " + "guest_protect={:08X} physical_protect={:08X}", + virtual_address, static_cast(reinterpret_cast(host_address)), + physical_address, current_guest_protect, physical_protect); + } + + return false; +} + +bool Memory::AccessViolationCallbackThunk( + std::unique_lock global_lock_locked_once, void* context, + void* host_address, bool is_write) { + return reinterpret_cast(context)->AccessViolationCallback( + std::move(global_lock_locked_once), host_address, is_write); +} + +bool Memory::TriggerPhysicalMemoryCallbacks( + std::unique_lock global_lock_locked_once, uint32_t virtual_address, + uint32_t length, bool is_write, bool unwatch_exact_range, bool unprotect) { + BaseHeap* heap = LookupHeap(virtual_address); + if (!heap) { + return false; + } + if (heap->heap_type() == memory::HeapType::kGuestPhysical) { + auto physical_heap = static_cast(heap); + return physical_heap->TriggerCallbacks(std::move(global_lock_locked_once), virtual_address, + length, is_write, unwatch_exact_range, unprotect); + } + return false; +} + +void* Memory::RegisterPhysicalMemoryInvalidationCallback( + PhysicalMemoryInvalidationCallback callback, void* callback_context) { + auto entry = new std::pair(callback, callback_context); + auto lock = global_critical_region_.Acquire(); + physical_memory_invalidation_callbacks_.push_back(entry); + return entry; +} + +void Memory::UnregisterPhysicalMemoryInvalidationCallback(void* callback_handle) { + auto entry = + reinterpret_cast*>(callback_handle); + { + auto lock = global_critical_region_.Acquire(); + auto it = std::find(physical_memory_invalidation_callbacks_.begin(), + physical_memory_invalidation_callbacks_.end(), entry); + assert_true(it != physical_memory_invalidation_callbacks_.end()); + if (it != physical_memory_invalidation_callbacks_.end()) { + physical_memory_invalidation_callbacks_.erase(it); + } + } + delete entry; +} + +void Memory::EnablePhysicalMemoryAccessCallbacks(uint32_t physical_address, uint32_t length, + bool enable_invalidation_notifications, + bool enable_data_providers) { + heaps_.vA0000000.EnableAccessCallbacks(physical_address, length, + enable_invalidation_notifications, enable_data_providers); + heaps_.vC0000000.EnableAccessCallbacks(physical_address, length, + enable_invalidation_notifications, enable_data_providers); + heaps_.vE0000000.EnableAccessCallbacks(physical_address, length, + enable_invalidation_notifications, enable_data_providers); +} + +uint32_t Memory::SystemHeapAlloc(uint32_t size, uint32_t alignment, uint32_t system_heap_flags) { + // TODO(benvanik): lightweight pool. + bool is_physical = !!(system_heap_flags & memory::kSystemHeapPhysical); + auto heap = LookupHeapByType(is_physical, 4096); + uint32_t address; + if (!heap->AllocSystemHeap( + size, alignment, memory::kMemoryAllocationReserve | memory::kMemoryAllocationCommit, + memory::kMemoryProtectRead | memory::kMemoryProtectWrite, false, &address)) { + return 0; + } + Zero(address, size); + return address; +} + +void Memory::SystemHeapFree(uint32_t address, uint32_t* out_region_size) { + if (!address) { + return; + } + // TODO(benvanik): lightweight pool. + auto heap = LookupHeap(address); + heap->Release(address, out_region_size); +} + +void Memory::GetHeapsPageStatsSummary(const BaseHeap* const* provided_heaps, size_t heaps_count, + uint32_t& unreserved_pages, uint32_t& reserved_pages, + uint32_t& used_pages, uint32_t& reserved_bytes) { + // Heap array is fixed after init; page counts are approximate statistics. + for (size_t i = 0; i < heaps_count; i++) { + const BaseHeap* heap = provided_heaps[i]; + uint32_t heap_unreserved = heap->unreserved_page_count(); + uint32_t heap_reserved = heap->reserved_page_count(); + + unreserved_pages += heap_unreserved; + reserved_pages += heap_reserved; + used_pages += ((heap->total_page_count() - heap_unreserved) * heap->page_size()) / 4096; + reserved_bytes += heap_reserved * heap->page_size(); + } +} + +void Memory::DumpMap() { + REXSYS_ERROR("=================================================================="); + REXSYS_ERROR("Memory Dump"); + REXSYS_ERROR("=================================================================="); + REXSYS_ERROR(" System Page Size: {0} ({0:08X})", system_page_size_); + REXSYS_ERROR(" System Allocation Granularity: {0} ({0:08X})", system_allocation_granularity_); + REXSYS_ERROR(" Virtual Membase: {}", fmt::ptr(virtual_membase_)); + REXSYS_ERROR(" Physical Membase: {}", fmt::ptr(physical_membase_)); + REXSYS_ERROR(""); + REXSYS_ERROR("------------------------------------------------------------------"); + REXSYS_ERROR("Virtual Heaps"); + REXSYS_ERROR("------------------------------------------------------------------"); + REXSYS_ERROR(""); + heaps_.v00000000.DumpMap(); + heaps_.v40000000.DumpMap(); + heaps_.v80000000.DumpMap(); + heaps_.v90000000.DumpMap(); + REXSYS_ERROR(""); + REXSYS_ERROR("------------------------------------------------------------------"); + REXSYS_ERROR("Physical Heaps"); + REXSYS_ERROR("------------------------------------------------------------------"); + REXSYS_ERROR(""); + heaps_.physical.DumpMap(); + heaps_.vA0000000.DumpMap(); + heaps_.vC0000000.DumpMap(); + heaps_.vE0000000.DumpMap(); + REXSYS_ERROR(""); +} + +bool Memory::Save(stream::ByteStream* stream) { + REXSYS_DEBUG("Serializing memory..."); + heaps_.v00000000.Save(stream); + heaps_.v40000000.Save(stream); + heaps_.v80000000.Save(stream); + heaps_.v90000000.Save(stream); + heaps_.physical.Save(stream); + + return true; +} + +bool Memory::Restore(stream::ByteStream* stream) { + REXSYS_DEBUG("Restoring memory..."); + heaps_.v00000000.Restore(stream); + heaps_.v40000000.Restore(stream); + heaps_.v80000000.Restore(stream); + heaps_.v90000000.Restore(stream); + heaps_.physical.Restore(stream); + + return true; +} + +//============================================================================= +// Recompiled Code Function Table +//============================================================================= + +bool Memory::InitializeFunctionTable(uint32_t code_base, uint32_t code_size, uint32_t image_base, + uint32_t image_size) { + constexpr uint32_t kThunkReserveSize = runtime::FunctionDispatcher::kThunkReserveSize; + uint32_t table_base = image_base + image_size; + uint32_t table_size = (code_size + kThunkReserveSize) * 2; + + REXSYS_DEBUG( + "Initializing function table at {:08X}, size {:08X} for code {:08X}-{:08X} " + "(+{:08X} thunk reserve)", + table_base, table_size, code_base, code_base + code_size, kThunkReserveSize); + + if (!heaps_.v80000000.AllocFixed( + table_base, table_size, 0x10000, + memory::kMemoryAllocationReserve | memory::kMemoryAllocationCommit, + memory::kMemoryProtectRead | memory::kMemoryProtectWrite)) { + REXSYS_ERROR("Failed to allocate function table at {:08X}", table_base); + return false; + } + + Zero(table_base, table_size); + + std::lock_guard lock(function_tables_mutex_); + function_tables_.push_back({ + .table_base = table_base, + .code_base = code_base, + .code_size = code_size, + .thunk_reserve = kThunkReserveSize, + }); + + return true; +} + +bool Memory::DestroyFunctionTable(uint32_t code_base) { + uint32_t table_base = 0; + uint32_t table_size = 0; + uint32_t logged_code_base = 0; + uint32_t logged_code_size = 0; + { + std::lock_guard lock(function_tables_mutex_); + auto it = std::find_if( + function_tables_.begin(), function_tables_.end(), + [code_base](const FunctionTableEntry& entry) { return entry.code_base == code_base; }); + if (it == function_tables_.end()) { + return false; + } + table_base = it->table_base; + table_size = (it->code_size + it->thunk_reserve) * 2; + logged_code_base = it->code_base; + logged_code_size = it->code_size; + function_tables_.erase(it); + } + + REXSYS_DEBUG("Destroying function table at {:08X}, size {:08X} for code {:08X}-{:08X}", + table_base, table_size, logged_code_base, logged_code_base + logged_code_size); + + heaps_.v80000000.Release(table_base); + return true; +} + +bool Memory::SetFunction(uint32_t guest_address, PPCFunc* host_function) { + uint32_t table_address = 0; + { + std::lock_guard lock(function_tables_mutex_); + for (const auto& entry : function_tables_) { + uint32_t range_end = entry.code_base + entry.code_size + entry.thunk_reserve; + if (guest_address >= entry.code_base && guest_address < range_end) { + uint64_t offset = (uint64_t(guest_address) - entry.code_base) * 2; + table_address = entry.table_base + uint32_t(offset); + break; + } + } + } + if (!table_address) { + return false; + } + auto* slot = TranslateVirtual(table_address); + *slot = host_function; + return true; +} + +bool Memory::HasAnyFunctionTable() const { + std::lock_guard lock(function_tables_mutex_); + return !function_tables_.empty(); +} + +rex::memory::PageAccess ToPageAccess(uint32_t protect) { + bool is_writable = + (protect & memory::kMemoryProtectWrite) || (protect & memory::kMemoryProtectWriteCombine); + + if ((protect & memory::kMemoryProtectRead) && !is_writable) { + return rex::memory::PageAccess::kReadOnly; + } else if ((protect & memory::kMemoryProtectRead) && is_writable) { + return rex::memory::PageAccess::kReadWrite; + } else { + return rex::memory::PageAccess::kNoAccess; + } +} + +uint32_t FromPageAccess(rex::memory::PageAccess protect) { + switch (protect) { + case memory::PageAccess::kNoAccess: + return memory::kMemoryProtectNoAccess; + case memory::PageAccess::kReadOnly: + return memory::kMemoryProtectRead; + case memory::PageAccess::kReadWrite: + return memory::kMemoryProtectRead | memory::kMemoryProtectWrite; + case memory::PageAccess::kExecuteReadOnly: + // Guest memory cannot be executable - this should never happen :) + assert_always(); + return memory::kMemoryProtectRead; + case memory::PageAccess::kExecuteReadWrite: + // Guest memory cannot be executable - this should never happen :) + assert_always(); + return memory::kMemoryProtectRead | memory::kMemoryProtectWrite; + } + + return memory::kMemoryProtectNoAccess; +} + +BaseHeap::BaseHeap() : membase_(nullptr), heap_base_(0), heap_size_(0), page_size_(0) {} + +BaseHeap::~BaseHeap() = default; + +void BaseHeap::Initialize(memory::Memory* memory, uint8_t* membase, HeapType heap_type, + uint32_t heap_base, uint32_t heap_size, uint32_t page_size, + uint32_t host_address_offset) { + memory_ = memory; + membase_ = membase; + heap_type_ = heap_type; + heap_base_ = heap_base; + heap_size_ = heap_size; + page_size_ = page_size; + assert_true(rex::is_pow2(page_size_)); + page_size_shift_ = rex::log2_floor(page_size_); + host_address_offset_ = host_address_offset; + page_table_.resize(heap_size / page_size); + unreserved_page_count_ = uint32_t(page_table_.size()); +} + +void BaseHeap::Dispose() { + // Walk table and release all regions. + for (uint32_t page_number = 0; page_number < page_table_.size(); ++page_number) { + auto& page_entry = page_table_[page_number]; + if (page_entry.state) { + rex::memory::DeallocFixed(TranslateRelative(page_number << page_size_shift_), 0, + rex::memory::DeallocationType::kRelease); + page_number += page_entry.region_page_count; + } + } +} + +void BaseHeap::DumpMap() { + std::lock_guard heap_lock(heap_mutex_); + REXSYS_ERROR("------------------------------------------------------------------"); + REXSYS_ERROR("Heap: {:08X}-{:08X}", heap_base_, heap_base_ + (heap_size_ - 1)); + REXSYS_ERROR("------------------------------------------------------------------"); + REXSYS_ERROR(" Heap Base: {:08X}", heap_base_); + REXSYS_ERROR(" Heap Size: {0} ({0:08X})", heap_size_); + REXSYS_ERROR(" Page Size: {0} ({0:08X})", page_size_); + REXSYS_ERROR(" Page Count: {}", page_table_.size()); + REXSYS_ERROR(" Host Address Offset: {0} ({0:08X})", host_address_offset_); + bool is_empty_span = false; + uint32_t empty_span_start = 0; + for (uint32_t i = 0; i < uint32_t(page_table_.size()); ++i) { + auto& page = page_table_[i]; + if (!page.state) { + if (!is_empty_span) { + is_empty_span = true; + empty_span_start = i; + } + continue; + } + if (is_empty_span) { + REXSYS_ERROR(" {:08X}-{:08X} {:6d}p {:10d}b unreserved", + heap_base_ + (empty_span_start << page_size_shift_), + heap_base_ + (i << page_size_shift_), i - empty_span_start, + (i - empty_span_start) << page_size_shift_); + is_empty_span = false; + } + const char* state_name = " "; + if (page.state & memory::kMemoryAllocationCommit) { + state_name = "COM"; + } else if (page.state & memory::kMemoryAllocationReserve) { + state_name = "RES"; + } + char access_r = (page.current_protect & memory::kMemoryProtectRead) ? 'R' : ' '; + char access_w = (page.current_protect & memory::kMemoryProtectWrite) ? 'W' : ' '; + uint32_t region_pages = page.region_page_count; + REXSYS_ERROR(" {:08X}-{:08X} {:6d}p {:10d}b {} {}{}", heap_base_ + (i << page_size_shift_), + heap_base_ + ((i + region_pages) << page_size_shift_), region_pages, + region_pages << page_size_shift_, state_name, access_r, access_w); + i += region_pages - 1; + } + if (is_empty_span) { + REXSYS_ERROR(" {:08X}-{:08X} - {} unreserved pages)", + heap_base_ + (empty_span_start << page_size_shift_), heap_base_ + (heap_size_ - 1), + page_table_.size() - empty_span_start); + } +} + +uint32_t BaseHeap::GetTotalPageCount() { + return uint32_t(page_table_.size()); +} + +uint32_t BaseHeap::GetUnreservedPageCount() { + std::lock_guard heap_lock(heap_mutex_); + uint32_t count = 0; + bool is_empty_span = false; + uint32_t empty_span_start = 0; + uint32_t size = uint32_t(page_table_.size()); + for (uint32_t i = 0; i < size; ++i) { + auto& page = page_table_[i]; + if (!page.state) { + if (!is_empty_span) { + is_empty_span = true; + empty_span_start = i; + } + continue; + } + if (is_empty_span) { + is_empty_span = false; + count += i - empty_span_start; + } + i += page.region_page_count - 1; + } + if (is_empty_span) { + count += size - empty_span_start; + } + return count; +} + +bool BaseHeap::Save(stream::ByteStream* stream) { + REXSYS_DEBUG("Heap {:08X}-{:08X}", heap_base_, heap_base_ + (heap_size_ - 1)); + + for (size_t i = 0; i < page_table_.size(); i++) { + auto& page = page_table_[i]; + stream->Write(page.qword); + if (!page.state) { + // Unallocated. + continue; + } + + // TODO(DrChat): write compressed with snappy. + if (page.state & memory::kMemoryAllocationCommit) { + void* addr = TranslateRelative(i << page_size_shift_); + + memory::PageAccess old_access; + memory::Protect(addr, page_size_, memory::PageAccess::kReadWrite, &old_access); + + stream->Write(addr, page_size_); + + memory::Protect(addr, page_size_, old_access, nullptr); + } + } + + return true; +} + +bool BaseHeap::Restore(stream::ByteStream* stream) { + REXSYS_DEBUG("Heap {:08X}-{:08X}", heap_base_, heap_base_ + (heap_size_ - 1)); + + for (size_t i = 0; i < page_table_.size(); i++) { + auto& page = page_table_[i]; + page.qword = stream->Read(); + if (!page.state) { + // Unallocated. + continue; + } + + memory::PageAccess page_access = memory::PageAccess::kNoAccess; + if ((page.current_protect & memory::kMemoryProtectRead) && + (page.current_protect & memory::kMemoryProtectWrite)) { + page_access = memory::PageAccess::kReadWrite; + } else if (page.current_protect & memory::kMemoryProtectRead) { + page_access = memory::PageAccess::kReadOnly; + } + + // Commit the memory if it isn't already. We do not need to reserve any + // memory, as the mapping has already taken care of that. + if (page.state & memory::kMemoryAllocationCommit) { + rex::memory::AllocFixed(TranslateRelative(i << page_size_shift_), page_size_, + memory::AllocationType::kCommit, memory::PageAccess::kReadWrite); + } + + // Now read into memory. We'll set R/W protection first, then set the + // protection back to its previous state. + // TODO(DrChat): read compressed with snappy. + if (page.state & memory::kMemoryAllocationCommit) { + void* addr = TranslateRelative(i << page_size_shift_); + rex::memory::Protect(addr, page_size_, memory::PageAccess::kReadWrite, nullptr); + + stream->Read(addr, page_size_); + + rex::memory::Protect(addr, page_size_, page_access, nullptr); + } + } + + return true; +} + +void BaseHeap::Reset() { + // TODO(DrChat): protect pages. + std::memset(page_table_.data(), 0, sizeof(PageEntry) * page_table_.size()); + // TODO(Triang3l): Remove access callbacks from pages if this is a physical + // memory heap. +} + +bool BaseHeap::Alloc(uint32_t size, uint32_t alignment, uint32_t allocation_type, uint32_t protect, + bool top_down, uint32_t* out_address) { + *out_address = 0; + size = rex::round_up(size, page_size_); + alignment = rex::round_up(alignment, page_size_); + + // Reserve address space at the top for thread stacks. + // 0x3XXXXXXX is for system threads, 0x7XXXXXXX is for title threads. + uint32_t heap_virtual_guest_offset = 0; + if (heap_type_ == memory::HeapType::kGuestVirtual) { + heap_virtual_guest_offset = 0x10000000; + if (page_size_ == 0x10000) { + heap_virtual_guest_offset = 0x0F000000; + } + } + + uint32_t low_address = heap_base_; + uint32_t high_address = heap_base_ + (heap_size_ - 1) - heap_virtual_guest_offset; + return AllocRange(low_address, high_address, size, alignment, allocation_type, protect, top_down, + out_address); +} + +bool BaseHeap::AllocSystemHeap(uint32_t size, uint32_t alignment, uint32_t allocation_type, + uint32_t protect, bool top_down, uint32_t* out_address) { + *out_address = 0; + size = rex::round_up(size, page_size_); + alignment = rex::round_up(alignment, page_size_); + + uint32_t low_address = heap_base_; + if (heap_type_ == memory::HeapType::kGuestVirtual) { + low_address = heap_base_ + heap_size_ - 0x10000000; + } + uint32_t high_address = heap_base_ + (heap_size_ - 1); + return AllocRange(low_address, high_address, size, alignment, allocation_type, protect, top_down, + out_address); +} + +bool BaseHeap::AllocFixed(uint32_t base_address, uint32_t size, uint32_t alignment, + uint32_t allocation_type, uint32_t protect) { + alignment = rex::round_up(alignment, page_size_); + if (base_address % alignment != 0) { + if (base_address % page_size_ != 0) { + REXSYS_ERROR( + "BaseHeap::AllocFixed invalid base alignment: base={:08X} page_size={:08X} " + "requested_alignment={:08X} heap={:08X}-{:08X}", + base_address, page_size_, alignment, heap_base_, heap_base_ + (heap_size_ - 1)); + return false; + } + // Fixed allocations can only be guaranteed page-aligned. If callers provide + // a stricter alignment for an already-fixed address, fall back to page size. + REXSYS_WARN( + "BaseHeap::AllocFixed clamping alignment from {:08X} to page size {:08X} for " + "base={:08X}", + alignment, page_size_, base_address); + alignment = page_size_; + } + size = rex::align(size, alignment); + uint32_t page_count = get_page_count(size, page_size_, page_size_shift_); + uint32_t start_page_number = (base_address - heap_base_) >> page_size_shift_; + uint32_t end_page_number = start_page_number + page_count - 1; + if (start_page_number >= page_table_.size() || end_page_number > page_table_.size()) { + REXSYS_ERROR("BaseHeap::AllocFixed passed out of range address range"); + return false; + } + + std::lock_guard heap_lock(heap_mutex_); + + // - If we are reserving the entire range requested must not be already + // reserved. + // - If we are committing it's ok for pages within the range to already be + // committed. + for (uint32_t page_number = start_page_number; page_number <= end_page_number; ++page_number) { + uint32_t state = page_table_[page_number].state; + if ((allocation_type == memory::kMemoryAllocationReserve) && state) { + // Already reserved. + REXSYS_ERROR( + "BaseHeap::AllocFixed attempting to reserve an already reserved " + "range"); + return false; + } + if ((allocation_type == memory::kMemoryAllocationCommit) && + !(state & memory::kMemoryAllocationReserve)) { + // Attempting a commit-only op on an unreserved page. + // This may be OK. + REXSYS_WARN("BaseHeap::AllocFixed attempting commit on unreserved page"); + allocation_type |= memory::kMemoryAllocationReserve; + break; + } + } + + // Allocate from host. + if (allocation_type == memory::kMemoryAllocationReserve) { + // Reserve is not needed, as we are mapped already. + } else { + auto alloc_type = (allocation_type & memory::kMemoryAllocationCommit) + ? rex::memory::AllocationType::kCommit + : rex::memory::AllocationType::kReserve; + void* result = + rex::memory::AllocFixed(TranslateRelative(start_page_number << page_size_shift_), + page_count << page_size_shift_, alloc_type, ToPageAccess(protect)); + if (!result) { + REXSYS_ERROR("BaseHeap::AllocFixed failed to alloc range from host"); + return false; + } + + if (REXCVAR_GET(scribble_heap) && protect & memory::kMemoryProtectWrite) { + std::memset(result, 0xCD, page_count << page_size_shift_); + } + } + + // Set page state. + for (uint32_t page_number = start_page_number; page_number <= end_page_number; ++page_number) { + auto& page_entry = page_table_[page_number]; + if (allocation_type & memory::kMemoryAllocationReserve) { + if (!page_entry.state) { + unreserved_page_count_--; + } + // Region is based on reservation. + page_entry.base_address = start_page_number; + page_entry.region_page_count = page_count; + } + page_entry.allocation_protect = protect; + page_entry.current_protect = protect; + page_entry.state = memory::kMemoryAllocationReserve | allocation_type; + } + + return true; +} + +bool BaseHeap::AllocRange(uint32_t low_address, uint32_t high_address, uint32_t size, + uint32_t alignment, uint32_t allocation_type, uint32_t protect, + bool top_down, uint32_t* out_address) { + *out_address = 0; + + alignment = rex::round_up(alignment, page_size_); + uint32_t page_count = get_page_count(size, page_size_, page_size_shift_); + low_address = std::max(heap_base_, rex::align(low_address, alignment)); + high_address = std::min(heap_base_ + (heap_size_ - 1), rex::align(high_address, alignment)); + if (high_address < low_address) { + REXSYS_ERROR("BaseHeap::Alloc invalid requested range"); + return false; + } + uint32_t low_page_number = (low_address - heap_base_) >> page_size_shift_; + uint32_t high_page_number = (high_address - heap_base_) >> page_size_shift_; + low_page_number = std::min(uint32_t(page_table_.size()) - 1, low_page_number); + high_page_number = std::min(uint32_t(page_table_.size()) - 1, high_page_number); + if (high_page_number < low_page_number) { + REXSYS_ERROR("BaseHeap::Alloc invalid requested page range"); + return false; + } + + uint32_t available_page_count = high_page_number - low_page_number + 1; + if (!page_count || page_count > available_page_count) { + REXSYS_ERROR("BaseHeap::Alloc page count too big for requested range"); + return false; + } + + std::lock_guard heap_lock(heap_mutex_); + + // Find a free page range. + // The base page must match the requested alignment, so we first scan for + // a free aligned page and only then check for continuous free pages. + // TODO(benvanik): optimized searching (free list buckets, bitmap, etc). + uint32_t start_page_number = UINT_MAX; + uint32_t end_page_number = UINT_MAX; + uint32_t page_scan_stride = alignment >> page_size_shift_; + uint32_t max_base_page_number = high_page_number + 1 - page_count; + if (top_down) { + max_base_page_number -= max_base_page_number % page_scan_stride; + for (int64_t base_page_number = max_base_page_number; base_page_number >= low_page_number; + base_page_number -= page_scan_stride) { + if (page_table_[base_page_number].state != 0) { + // Base page not free, skip to next usable page. + continue; + } + // Check requested range to ensure free. + start_page_number = uint32_t(base_page_number); + end_page_number = uint32_t(base_page_number) + page_count - 1; + assert_true(end_page_number < page_table_.size()); + bool any_taken = false; + for (uint32_t page_number = uint32_t(base_page_number); + !any_taken && page_number <= end_page_number; ++page_number) { + bool is_free = page_table_[page_number].state == 0; + if (!is_free) { + // At least one page in the range is used, skip to next. + // We know we'll be starting at least before this page. + any_taken = true; + if (page_count > page_number) { + // Not enough space left to fit entire page range. Breaks outer + // loop. + base_page_number = -1; + } else { + base_page_number = page_number - page_count; + base_page_number -= base_page_number % page_scan_stride; + base_page_number += page_scan_stride; // cancel out loop logic + } + break; + } + } + if (!any_taken) { + // Found our place. + break; + } + // Retry. + start_page_number = end_page_number = UINT_MAX; + } + } else { + for (uint32_t base_page_number = low_page_number; base_page_number <= max_base_page_number; + base_page_number += page_scan_stride) { + if (page_table_[base_page_number].state != 0) { + // Base page not free, skip to next usable page. + continue; + } + // Check requested range to ensure free. + start_page_number = base_page_number; + end_page_number = base_page_number + page_count - 1; + bool any_taken = false; + for (uint32_t page_number = base_page_number; !any_taken && page_number <= end_page_number; + ++page_number) { + bool is_free = page_table_[page_number].state == 0; + if (!is_free) { + // At least one page in the range is used, skip to next. + // We know we'll be starting at least after this page. + any_taken = true; + base_page_number = rex::round_up(page_number + 1, page_scan_stride); + base_page_number -= page_scan_stride; // cancel out loop logic + break; + } + } + if (!any_taken) { + // Found our place. + break; + } + // Retry. + start_page_number = end_page_number = UINT_MAX; + } + } + if (start_page_number == UINT_MAX || end_page_number == UINT_MAX) { + // Out of memory. + REXSYS_ERROR("BaseHeap::Alloc failed to find contiguous range"); + assert_always("Heap exhausted!"); + return false; + } + + // Allocate from host. + if (allocation_type == memory::kMemoryAllocationReserve) { + // Reserve is not needed, as we are mapped already. + } else { + auto alloc_type = (allocation_type & memory::kMemoryAllocationCommit) + ? rex::memory::AllocationType::kCommit + : rex::memory::AllocationType::kReserve; + void* result = + rex::memory::AllocFixed(TranslateRelative(start_page_number << page_size_shift_), + page_count << page_size_shift_, alloc_type, ToPageAccess(protect)); + if (!result) { + REXSYS_ERROR("BaseHeap::Alloc failed to alloc range from host"); + return false; + } + + if (REXCVAR_GET(scribble_heap) && (protect & memory::kMemoryProtectWrite)) { + std::memset(result, 0xCD, page_count << page_size_shift_); + } + } + + // Set page state. + for (uint32_t page_number = start_page_number; page_number <= end_page_number; ++page_number) { + auto& page_entry = page_table_[page_number]; + if (!page_entry.state) { + unreserved_page_count_--; + } + page_entry.base_address = start_page_number; + page_entry.region_page_count = page_count; + page_entry.allocation_protect = protect; + page_entry.current_protect = protect; + page_entry.state = memory::kMemoryAllocationReserve | allocation_type; + } + + *out_address = heap_base_ + (start_page_number << page_size_shift_); + return true; +} + +bool BaseHeap::Decommit(uint32_t address, uint32_t size) { + uint32_t page_count = get_page_count(size, page_size_, page_size_shift_); + uint32_t start_page_number = (address - heap_base_) >> page_size_shift_; + uint32_t end_page_number = start_page_number + page_count - 1; + start_page_number = std::min(uint32_t(page_table_.size()) - 1, start_page_number); + end_page_number = std::min(uint32_t(page_table_.size()) - 1, end_page_number); + + std::lock_guard heap_lock(heap_mutex_); + + // Release from host. + // TODO(benvanik): find a way to actually decommit memory; + // mapped memory cannot be decommitted. + /*BOOL result = + VirtualFree(TranslateRelative(start_page_number << page_size_shift_), + page_count << page_size_shift_, MEM_DECOMMIT); + if (!result) { + PLOGW("BaseHeap::Decommit failed due to host VirtualFree failure"); + return false; + }*/ + + // Perform table change. + for (uint32_t page_number = start_page_number; page_number <= end_page_number; ++page_number) { + auto& page_entry = page_table_[page_number]; + page_entry.state &= ~memory::kMemoryAllocationCommit; + } + + return true; +} + +bool BaseHeap::Release(uint32_t base_address, uint32_t* out_region_size) { + std::lock_guard heap_lock(heap_mutex_); + + // Given address must be a region base address. + uint32_t base_page_number = (base_address - heap_base_) >> page_size_shift_; + auto base_page_entry = page_table_[base_page_number]; + if (base_page_entry.base_address != base_page_number) { + REXSYS_ERROR("BaseHeap::Release failed because address is not a region start"); + return false; + } + + if (heap_base_ == 0x00000000 && base_page_number == 0) { + REXSYS_ERROR("BaseHeap::Release: Attempt to free 0!"); + return false; + } + + if (out_region_size) { + *out_region_size = (base_page_entry.region_page_count << page_size_shift_); + } + + // Release from host not needed as mapping reserves the range for us. + // TODO(benvanik): protect with NOACCESS? + /*BOOL result = VirtualFree( + TranslateRelative(base_page_number << page_size_shift_), 0, MEM_RELEASE); + if (!result) { + PLOGE("BaseHeap::Release failed due to host VirtualFree failure"); + return false; + }*/ + // Instead, we just protect it, if we can. + if (page_size_ == rex::memory::page_size() || + ((base_page_entry.region_page_count << page_size_shift_) % rex::memory::page_size() == 0 && + ((base_page_number << page_size_shift_) % rex::memory::page_size() == 0))) { + // TODO(benvanik): figure out why games are using memory after releasing + // it. It's possible this is some virtual/physical stuff where the GPU + // still can access it. + if (REXCVAR_GET(protect_on_release)) { + if (!rex::memory::Protect(TranslateRelative(base_page_number << page_size_shift_), + base_page_entry.region_page_count << page_size_shift_, + rex::memory::PageAccess::kNoAccess, nullptr)) { + REXSYS_WARN("BaseHeap::Release failed due to host VirtualProtect failure"); + } + } + } + + // Perform table change. + uint32_t end_page_number = base_page_number + base_page_entry.region_page_count - 1; + for (uint32_t page_number = base_page_number; page_number <= end_page_number; ++page_number) { + auto& page_entry = page_table_[page_number]; + page_entry.qword = 0; + unreserved_page_count_++; + } + + return true; +} + +bool BaseHeap::Protect(uint32_t address, uint32_t size, uint32_t protect, uint32_t* old_protect) { + if (!size) { + REXSYS_ERROR("BaseHeap::Protect failed due to zero size"); + return false; + } + + // From the VirtualProtect MSDN page: + // + // "The region of affected pages includes all pages containing one or more + // bytes in the range from the lpAddress parameter to (lpAddress+dwSize). + // This means that a 2-byte range straddling a page boundary causes the + // protection attributes of both pages to be changed." + // + // "The access protection value can be set only on committed pages. If the + // state of any page in the specified region is not committed, the function + // fails and returns without modifying the access protection of any pages in + // the specified region." + + uint32_t start_page_number = (address - heap_base_) >> page_size_shift_; + if (start_page_number >= page_table_.size()) { + REXSYS_ERROR("BaseHeap::Protect failed due to out-of-bounds base address {:08X}", address); + return false; + } + uint32_t end_page_number = + uint32_t((uint64_t(address) + size - 1 - heap_base_) >> page_size_shift_); + if (end_page_number >= page_table_.size()) { + REXSYS_ERROR( + "BaseHeap::Protect failed due to out-of-bounds range ({:08X} bytes " + "from {:08x})", + size, address); + return false; + } + + std::lock_guard heap_lock(heap_mutex_); + + // Ensure all pages are in the same reserved region and all are committed. + uint32_t first_base_address = UINT_MAX; + for (uint32_t page_number = start_page_number; page_number <= end_page_number; ++page_number) { + auto page_entry = page_table_[page_number]; + if (first_base_address == UINT_MAX) { + first_base_address = page_entry.base_address; + } else if (first_base_address != page_entry.base_address) { + REXSYS_ERROR("BaseHeap::Protect failed due to request spanning regions"); + return false; + } + if (!(page_entry.state & memory::kMemoryAllocationCommit)) { + REXSYS_ERROR("BaseHeap::Protect failed due to uncommitted page"); + return false; + } + } + + // Attempt host change (hopefully won't fail). + // We can only do this if our size matches system page granularity. + uint32_t page_count = end_page_number - start_page_number + 1; + if (page_size_ == rex::memory::page_size() || + (((page_count << page_size_shift_) % rex::memory::page_size() == 0) && + ((start_page_number << page_size_shift_) % rex::memory::page_size() == 0))) { + memory::PageAccess old_protect_access; + if (!rex::memory::Protect(TranslateRelative(start_page_number << page_size_shift_), + page_count << page_size_shift_, ToPageAccess(protect), + old_protect ? &old_protect_access : nullptr)) { + REXSYS_ERROR("BaseHeap::Protect failed due to host VirtualProtect failure"); + return false; + } + + if (old_protect) { + *old_protect = FromPageAccess(old_protect_access); + } + } else { + REXSYS_WARN("BaseHeap::Protect: ignoring request as not 4k page aligned"); + return false; + } + + // Perform table change. + for (uint32_t page_number = start_page_number; page_number <= end_page_number; ++page_number) { + auto& page_entry = page_table_[page_number]; + page_entry.current_protect = protect; + } + + return true; +} + +bool BaseHeap::QueryRegionInfo(uint32_t base_address, HeapAllocationInfo* out_info) { + uint32_t start_page_number = (base_address - heap_base_) >> page_size_shift_; + if (start_page_number > page_table_.size()) { + REXSYS_ERROR("BaseHeap::QueryRegionInfo base page out of range"); + return false; + } + + std::lock_guard heap_lock(heap_mutex_); + + auto start_page_entry = page_table_[start_page_number]; + out_info->base_address = base_address; + out_info->allocation_base = 0; + out_info->allocation_protect = 0; + out_info->region_size = 0; + out_info->state = 0; + out_info->protect = 0; + if (start_page_entry.state) { + // Committed/reserved region. + out_info->allocation_base = heap_base_ + (start_page_entry.base_address << page_size_shift_); + out_info->allocation_protect = start_page_entry.allocation_protect; + out_info->allocation_size = start_page_entry.region_page_count << page_size_shift_; + out_info->state = start_page_entry.state; + out_info->protect = start_page_entry.current_protect; + + // Scan forward and report the size of the region matching the initial + // base address's attributes. + for (uint32_t page_number = start_page_number; + page_number < start_page_entry.base_address + start_page_entry.region_page_count; + ++page_number) { + auto page_entry = page_table_[page_number]; + if (page_entry.base_address != start_page_entry.base_address || + page_entry.state != start_page_entry.state || + page_entry.current_protect != start_page_entry.current_protect) { + // Different region or different properties within the region; done. + break; + } + out_info->region_size += page_size_; + } + } else { + // Free region. + for (uint32_t page_number = start_page_number; page_number < page_table_.size(); + ++page_number) { + auto page_entry = page_table_[page_number]; + if (page_entry.state) { + // First non-free page; done with region. + break; + } + out_info->region_size += page_size_; + } + } + return true; +} + +bool BaseHeap::QuerySize(uint32_t address, uint32_t* out_size) { + uint32_t page_number = (address - heap_base_) >> page_size_shift_; + if (page_number > page_table_.size()) { + REXSYS_ERROR("BaseHeap::QuerySize base page out of range"); + *out_size = 0; + return false; + } + std::lock_guard heap_lock(heap_mutex_); + auto page_entry = page_table_[page_number]; + *out_size = (page_entry.region_page_count << page_size_shift_); + return true; +} + +bool BaseHeap::QueryBaseAndSize(uint32_t* in_out_address, uint32_t* out_size) { + uint32_t page_number = (*in_out_address - heap_base_) >> page_size_shift_; + if (page_number > page_table_.size()) { + REXSYS_ERROR("BaseHeap::QuerySize base page out of range"); + *out_size = 0; + return false; + } + std::lock_guard heap_lock(heap_mutex_); + auto page_entry = page_table_[page_number]; + *in_out_address = (page_entry.base_address << page_size_shift_); + *out_size = (page_entry.region_page_count << page_size_shift_); + return true; +} + +bool BaseHeap::QueryProtect(uint32_t address, uint32_t* out_protect) { + uint32_t page_number = (address - heap_base_) >> page_size_shift_; + if (page_number > page_table_.size()) { + REXSYS_ERROR("BaseHeap::QueryProtect base page out of range"); + *out_protect = 0; + return false; + } + std::lock_guard heap_lock(heap_mutex_); + auto page_entry = page_table_[page_number]; + *out_protect = page_entry.current_protect; + return true; +} + +rex::memory::PageAccess BaseHeap::QueryRangeAccess(uint32_t low_address, uint32_t high_address) { + if (low_address > high_address || low_address < heap_base_ || + (high_address - heap_base_) >= heap_size_) { + return rex::memory::PageAccess::kNoAccess; + } + uint32_t low_page_number = (low_address - heap_base_) >> page_size_shift_; + uint32_t high_page_number = (high_address - heap_base_) >> page_size_shift_; + bool all_readable = true; + bool all_writable = true; + { + std::lock_guard heap_lock(heap_mutex_); + for (uint32_t i = low_page_number; i <= high_page_number; ++i) { + uint32_t page_protect = page_table_[i].current_protect; + if (!(page_protect & memory::kMemoryProtectRead)) { + all_readable = false; + } + if (!(page_protect & memory::kMemoryProtectWrite) && + !(page_protect & memory::kMemoryProtectWriteCombine)) { + all_writable = false; + } + } + } + if (all_readable && all_writable) { + return rex::memory::PageAccess::kReadWrite; + } else if (all_readable) { + return rex::memory::PageAccess::kReadOnly; + } else { + return rex::memory::PageAccess::kNoAccess; + } +} + +VirtualHeap::VirtualHeap() = default; + +VirtualHeap::~VirtualHeap() = default; + +void VirtualHeap::Initialize(memory::Memory* memory, uint8_t* membase, HeapType heap_type, + uint32_t heap_base, uint32_t heap_size, uint32_t page_size) { + BaseHeap::Initialize(memory, membase, heap_type, heap_base, heap_size, page_size); +} + +PhysicalHeap::PhysicalHeap() : parent_heap_(nullptr) {} + +PhysicalHeap::~PhysicalHeap() = default; + +void PhysicalHeap::Initialize(memory::Memory* memory, uint8_t* membase, HeapType heap_type, + uint32_t heap_base, uint32_t heap_size, uint32_t page_size, + VirtualHeap* parent_heap) { + uint32_t host_address_offset; + if (heap_base >= 0xE0000000 && rex::memory::allocation_granularity() > 0x1000) { + host_address_offset = 0x1000; + } else { + host_address_offset = 0; + } + + BaseHeap::Initialize(memory, membase, heap_type, heap_base, heap_size, page_size, + host_address_offset); + parent_heap_ = parent_heap; + system_page_size_ = uint32_t(rex::memory::page_size()); + + system_page_count_ = + (size_t(heap_size_) + host_address_offset + (system_page_size_ - 1)) / system_page_size_; + system_page_flags_.resize((system_page_count_ + 63) / 64); +} + +bool PhysicalHeap::Alloc(uint32_t size, uint32_t alignment, uint32_t allocation_type, + uint32_t protect, bool top_down, uint32_t* out_address) { + *out_address = 0; + + // Default top-down. Since parent heap is bottom-up this prevents + // collisions. + top_down = true; + + // Adjust alignment size our page size differs from the parent. + size = rex::round_up(size, page_size_); + alignment = rex::round_up(alignment, page_size_); + + std::lock_guard heap_lock(heap_mutex_); + + // Allocate from parent heap (gets our physical address in 0-512mb). + uint32_t parent_heap_start = GetPhysicalAddress(heap_base_); + uint32_t parent_heap_end = GetPhysicalAddress(heap_base_ + (heap_size_ - 1)); + uint32_t parent_address; + if (!parent_heap_->AllocRange(parent_heap_start, parent_heap_end, size, alignment, + allocation_type, protect, top_down, &parent_address)) { + REXSYS_ERROR("PhysicalHeap::Alloc unable to alloc physical memory in parent heap"); + return false; + } + + // Given the address we've reserved in the parent heap, pin that here. + // Shouldn't be possible for it to be allocated already. + uint32_t address = heap_base_ + parent_address - parent_heap_start; + if (!BaseHeap::AllocFixed(address, size, alignment, allocation_type, protect)) { + REXSYS_ERROR("PhysicalHeap::Alloc unable to pin physical memory in physical heap"); + // TODO(benvanik): don't leak parent memory. + return false; + } + *out_address = address; + return true; +} + +bool PhysicalHeap::AllocFixed(uint32_t base_address, uint32_t size, uint32_t alignment, + uint32_t allocation_type, uint32_t protect) { + // Adjust alignment size our page size differs from the parent. + size = rex::round_up(size, page_size_); + alignment = rex::round_up(alignment, page_size_); + + std::lock_guard heap_lock(heap_mutex_); + + // Allocate from parent heap (gets our physical address in 0-512mb). + // NOTE: this can potentially overwrite heap contents if there are already + // committed pages in the requested physical range. + // TODO(benvanik): flag for ensure-not-committed? + uint32_t parent_base_address = GetPhysicalAddress(base_address); + if (!parent_heap_->AllocFixed(parent_base_address, size, alignment, allocation_type, protect)) { + REXSYS_ERROR("PhysicalHeap::Alloc unable to alloc physical memory in parent heap"); + return false; + } + + // Given the address we've reserved in the parent heap, pin that here. + // Shouldn't be possible for it to be allocated already. + uint32_t address = heap_base_ + parent_base_address - GetPhysicalAddress(heap_base_); + if (!BaseHeap::AllocFixed(address, size, page_size_, allocation_type, protect)) { + REXSYS_ERROR("PhysicalHeap::Alloc unable to pin physical memory in physical heap"); + // TODO(benvanik): don't leak parent memory. + return false; + } + + return true; +} + +bool PhysicalHeap::AllocRange(uint32_t low_address, uint32_t high_address, uint32_t size, + uint32_t alignment, uint32_t allocation_type, uint32_t protect, + bool top_down, uint32_t* out_address) { + *out_address = 0; + + // Adjust alignment size our page size differs from the parent. + size = rex::round_up(size, page_size_); + alignment = rex::round_up(alignment, page_size_); + + std::lock_guard heap_lock(heap_mutex_); + + // Allocate from parent heap (gets our physical address in 0-512mb). + low_address = std::max(heap_base_, low_address); + high_address = std::min(heap_base_ + (heap_size_ - 1), high_address); + uint32_t parent_low_address = GetPhysicalAddress(low_address); + uint32_t parent_high_address = GetPhysicalAddress(high_address); + uint32_t parent_address; + if (!parent_heap_->AllocRange(parent_low_address, parent_high_address, size, alignment, + allocation_type, protect, top_down, &parent_address)) { + REXSYS_ERROR("PhysicalHeap::Alloc unable to alloc physical memory in parent heap"); + return false; + } + + // Given the address we've reserved in the parent heap, pin that here. + // Shouldn't be possible for it to be allocated already. + uint32_t address = heap_base_ + parent_address - GetPhysicalAddress(heap_base_); + if (!BaseHeap::AllocFixed(address, size, page_size_, allocation_type, protect)) { + REXSYS_ERROR("PhysicalHeap::Alloc unable to pin physical memory in physical heap"); + // TODO(benvanik): don't leak parent memory. + return false; + } + *out_address = address; + return true; +} + +bool PhysicalHeap::AllocSystemHeap(uint32_t size, uint32_t alignment, uint32_t allocation_type, + uint32_t protect, bool top_down, uint32_t* out_address) { + return Alloc(size, alignment, allocation_type, protect, top_down, out_address); +} + +bool PhysicalHeap::Decommit(uint32_t address, uint32_t size) { + auto global_lock = global_critical_region_.Acquire(); + + uint32_t parent_address = GetPhysicalAddress(address); + if (!parent_heap_->Decommit(parent_address, size)) { + REXSYS_ERROR("PhysicalHeap::Decommit failed due to parent heap failure"); + return false; + } + + // Not caring about the contents anymore. + TriggerCallbacks(std::move(global_lock), address, size, true, true); + + return BaseHeap::Decommit(address, size); +} + +bool PhysicalHeap::Release(uint32_t base_address, uint32_t* out_region_size) { + auto global_lock = global_critical_region_.Acquire(); + + uint32_t parent_base_address = GetPhysicalAddress(base_address); + if (!parent_heap_->Release(parent_base_address, out_region_size)) { + REXSYS_ERROR("PhysicalHeap::Release failed due to parent heap failure"); + return false; + } + + // Must invalidate here because the range being released may be reused in + // another mapping of physical memory - but callback flags are set in each + // heap separately (https://github.com/xenia-project/xenia/issues/1559 - + // dynamic vertices in 4D5307F2 start screen and menu allocated in 0xA0000000 + // at addresses that overlap intro video textures in 0xE0000000, with the + // state of the allocator as of February 24th, 2020). If memory is invalidated + // in Alloc instead, Alloc won't be aware of callbacks enabled in other heaps, + // thus callback handlers will keep considering this range valid forever. + uint32_t region_size; + if (QuerySize(base_address, ®ion_size)) { + TriggerCallbacks(std::move(global_lock), base_address, region_size, true, true); + } + + return BaseHeap::Release(base_address, out_region_size); +} + +bool PhysicalHeap::Protect(uint32_t address, uint32_t size, uint32_t protect, + uint32_t* old_protect) { + auto global_lock = global_critical_region_.Acquire(); + + // Only invalidate if making writable again, for simplicity - not when simply + // marking some range as immutable, for instance. + if (protect & memory::kMemoryProtectWrite) { + TriggerCallbacks(std::move(global_lock), address, size, true, true, false); + } + + if (!parent_heap_->Protect(GetPhysicalAddress(address), size, protect, old_protect)) { + REXSYS_ERROR("PhysicalHeap::Protect failed due to parent heap failure"); + return false; + } + + return BaseHeap::Protect(address, size, protect); +} + +void PhysicalHeap::EnableAccessCallbacks(uint32_t physical_address, uint32_t length, + bool enable_invalidation_notifications, + bool enable_data_providers) { + // TODO(Triang3l): Implement data providers. + assert_false(enable_data_providers); + if (!enable_invalidation_notifications && !enable_data_providers) { + return; + } + uint32_t physical_address_offset = GetPhysicalAddress(heap_base_); + if (physical_address < physical_address_offset) { + if (physical_address_offset - physical_address >= length) { + return; + } + length -= physical_address_offset - physical_address; + physical_address = physical_address_offset; + } + uint32_t heap_relative_address = physical_address - physical_address_offset; + if (heap_relative_address >= heap_size_) { + return; + } + length = std::min(length, heap_size_ - heap_relative_address); + if (length == 0) { + return; + } + + uint32_t system_page_first = (heap_relative_address + host_address_offset()) / system_page_size_; + uint32_t system_page_last = + (heap_relative_address + length - 1 + host_address_offset()) / system_page_size_; + system_page_last = std::min(system_page_last, system_page_count_ - 1); + assert_true(system_page_first <= system_page_last); + + // Update callback flags for system pages and make their protection stricter + // if needed. + rex::memory::PageAccess protect_access = enable_data_providers + ? rex::memory::PageAccess::kNoAccess + : rex::memory::PageAccess::kReadOnly; + uint8_t* protect_base = membase_ + heap_base_; + uint32_t protect_system_page_first = UINT32_MAX; + auto global_lock = global_critical_region_.Acquire(); + for (uint32_t i = system_page_first; i <= system_page_last; ++i) { + // Check if need to enable callbacks for the page and raise its protection. + // + // If enabling invalidation notifications: + // - Page writable and not watched for changes yet - protect and enable + // invalidation notifications. + // - Page seen as writable by the guest, but only needs data providers - + // just set the bits to enable invalidation notifications (already has + // even stricter protection than needed). + // - Page not writable as requested by the game - don't do anything (need + // real access violations here). + // If enabling data providers: + // - Page accessible (either read/write or read-only) and didn't need data + // providers initially - protect and enable data providers. + // - Otherwise - do nothing. + // + // It's safe not to await data provider completion here before protecting as + // this never makes protection lighter, so it can't interfere with page + // faults that await data providers. + // + // Enabling data providers doesn't need to be deferred - providers will be + // polled for the last time without releasing the lock. + SystemPageFlagsBlock& page_flags_block = system_page_flags_[i >> 6]; + uint64_t page_flags_bit = uint64_t(1) << (i & 63); + uint32_t guest_page_number = + rex::sat_sub(i * system_page_size_, host_address_offset()) >> page_size_shift_; + rex::memory::PageAccess current_page_access = + ToPageAccess(page_table_[guest_page_number].current_protect); + bool protect_system_page = false; + // Don't do anything with inaccessible pages - don't protect, don't enable + // callbacks - because real access violations are needed there. And don't + // enable invalidation notifications for read-only pages for the same + // reason. + if (current_page_access != rex::memory::PageAccess::kNoAccess) { + // TODO(Triang3l): Enable data providers. + if (enable_invalidation_notifications) { + if (current_page_access != rex::memory::PageAccess::kReadOnly && + (page_flags_block.notify_on_invalidation & page_flags_bit) == 0) { + // TODO(Triang3l): Check if data providers are already enabled. + // If data providers are already enabled for the page, it has even + // stricter protection. + protect_system_page = true; + page_flags_block.notify_on_invalidation |= page_flags_bit; + } + } + } + if (protect_system_page) { + if (protect_system_page_first == UINT32_MAX) { + protect_system_page_first = i; + } + } else { + if (protect_system_page_first != UINT32_MAX) { + rex::memory::Protect(protect_base + protect_system_page_first * system_page_size_, + (i - protect_system_page_first) * system_page_size_, protect_access); + protect_system_page_first = UINT32_MAX; + } + } + } + if (protect_system_page_first != UINT32_MAX) { + rex::memory::Protect(protect_base + protect_system_page_first * system_page_size_, + (system_page_last + 1 - protect_system_page_first) * system_page_size_, + protect_access); + } +} + +bool PhysicalHeap::TriggerCallbacks(std::unique_lock global_lock_locked_once, + uint32_t virtual_address, uint32_t length, bool is_write, + bool unwatch_exact_range, bool unprotect) { + // TODO(Triang3l): Support read watches. + assert_true(is_write); + if (!is_write) { + return false; + } + + if (virtual_address < heap_base_) { + if (heap_base_ - virtual_address >= length) { + return false; + } + length -= heap_base_ - virtual_address; + virtual_address = heap_base_; + } + uint32_t heap_relative_address = virtual_address - heap_base_; + if (heap_relative_address >= heap_size_) { + return false; + } + length = std::min(length, heap_size_ - heap_relative_address); + if (length == 0) { + return false; + } + + uint32_t system_page_first = (heap_relative_address + host_address_offset()) / system_page_size_; + uint32_t system_page_last = + (heap_relative_address + length - 1 + host_address_offset()) / system_page_size_; + system_page_last = std::min(system_page_last, system_page_count_ - 1); + assert_true(system_page_first <= system_page_last); + uint32_t block_index_first = system_page_first >> 6; + uint32_t block_index_last = system_page_last >> 6; + + // Check if watching any page, whether need to call the callback at all. + bool any_watched = false; + for (uint32_t i = block_index_first; i <= block_index_last; ++i) { + uint64_t block = system_page_flags_[i].notify_on_invalidation; + if (i == block_index_first) { + block &= ~((uint64_t(1) << (system_page_first & 63)) - 1); + } + if (i == block_index_last && (system_page_last & 63) != 63) { + block &= (uint64_t(1) << ((system_page_last & 63) + 1)) - 1; + } + if (block) { + any_watched = true; + break; + } + } + if (!any_watched) { + return false; + } + + // Trigger callbacks. + if (!unprotect) { + // If not doing anything with protection, no point in unwatching excess + // pages. + unwatch_exact_range = true; + } + uint32_t physical_address_offset = GetPhysicalAddress(heap_base_); + uint32_t physical_address_start = + rex::sat_sub(system_page_first * system_page_size_, host_address_offset()) + + physical_address_offset; + uint32_t physical_length = + std::min(rex::sat_sub(system_page_last * system_page_size_ + system_page_size_, + host_address_offset()) + + physical_address_offset - physical_address_start, + heap_size_ - (physical_address_start - physical_address_offset)); + uint32_t unwatch_first = 0; + uint32_t unwatch_last = UINT32_MAX; + for (auto invalidation_callback : memory_->physical_memory_invalidation_callbacks_) { + std::pair callback_unwatch_range = + invalidation_callback->first(invalidation_callback->second, physical_address_start, + physical_length, unwatch_exact_range); + if (!unwatch_exact_range) { + unwatch_first = std::max(unwatch_first, callback_unwatch_range.first); + unwatch_last = std::min( + unwatch_last, rex::sat_add(callback_unwatch_range.first, + std::max(callback_unwatch_range.second, uint32_t(1)) - 1)); + } + } + if (!unwatch_exact_range) { + // Always unwatch at least the requested pages. + unwatch_first = std::min(unwatch_first, physical_address_start); + unwatch_last = std::max(unwatch_last, physical_address_start + physical_length - 1); + // Don't unprotect too much if not caring much about the region (limit to + // 4 MB - somewhat random, but max 1024 iterations of the page loop). + const uint32_t kMaxUnwatchExcess = 4 * 1024 * 1024; + unwatch_first = std::max(unwatch_first, physical_address_start & ~(kMaxUnwatchExcess - 1)); + unwatch_last = std::min( + unwatch_last, (physical_address_start + physical_length - 1) | (kMaxUnwatchExcess - 1)); + // Convert to heap-relative addresses. + unwatch_first = rex::sat_sub(unwatch_first, physical_address_offset); + unwatch_last = rex::sat_sub(unwatch_last, physical_address_offset); + // Clamp to the heap upper bound. + unwatch_first = std::min(unwatch_first, heap_size_ - 1); + unwatch_last = std::min(unwatch_last, heap_size_ - 1); + // Convert to system pages and update the range. + unwatch_first += host_address_offset(); + unwatch_last += host_address_offset(); + assert_true(unwatch_first <= unwatch_last); + system_page_first = unwatch_first / system_page_size_; + system_page_last = unwatch_last / system_page_size_; + block_index_first = system_page_first >> 6; + block_index_last = system_page_last >> 6; + } + + // Unprotect ranges that need unprotection. + if (unprotect) { + uint8_t* protect_base = membase_ + heap_base_; + uint32_t unprotect_system_page_first = UINT32_MAX; + for (uint32_t i = system_page_first; i <= system_page_last; ++i) { + // Check if need to allow writing to this page. + bool unprotect_page = + (system_page_flags_[i >> 6].notify_on_invalidation & (uint64_t(1) << (i & 63))) != 0; + if (unprotect_page) { + uint32_t guest_page_number = + rex::sat_sub(i * system_page_size_, host_address_offset()) >> page_size_shift_; + if (ToPageAccess(page_table_[guest_page_number].current_protect) != + rex::memory::PageAccess::kReadWrite) { + unprotect_page = false; + } + } + if (unprotect_page) { + if (unprotect_system_page_first == UINT32_MAX) { + unprotect_system_page_first = i; + } + } else { + if (unprotect_system_page_first != UINT32_MAX) { + rex::memory::Protect(protect_base + unprotect_system_page_first * system_page_size_, + (i - unprotect_system_page_first) * system_page_size_, + rex::memory::PageAccess::kReadWrite); + unprotect_system_page_first = UINT32_MAX; + } + } + } + if (unprotect_system_page_first != UINT32_MAX) { + rex::memory::Protect(protect_base + unprotect_system_page_first * system_page_size_, + (system_page_last + 1 - unprotect_system_page_first) * system_page_size_, + rex::memory::PageAccess::kReadWrite); + } + } + + // Mark pages as not write-watched. + for (uint32_t i = block_index_first; i <= block_index_last; ++i) { + uint64_t mask = 0; + if (i == block_index_first) { + mask |= (uint64_t(1) << (system_page_first & 63)) - 1; + } + if (i == block_index_last && (system_page_last & 63) != 63) { + mask |= ~((uint64_t(1) << ((system_page_last & 63) + 1)) - 1); + } + system_page_flags_[i].notify_on_invalidation &= mask; + } + + return true; +} + +uint32_t PhysicalHeap::GetPhysicalAddress(uint32_t address) const { + assert_true(address >= heap_base_); + address -= heap_base_; + assert_true(address < heap_size_); + if (heap_base_ >= 0xE0000000) { + address += 0x1000; + } + return address; +} + +} // namespace rex::memory diff --git a/src/system/xmodule.cpp b/src/system/xmodule.cpp new file mode 100644 index 0000000..91cf657 --- /dev/null +++ b/src/system/xmodule.cpp @@ -0,0 +1,106 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include + +namespace rex::system { + +XModule::XModule(KernelState* kernel_state, ModuleType module_type) + : XObject(kernel_state, kObjectType), + module_type_(module_type), + processor_module_(nullptr), + hmodule_ptr_(0) { + // Loader data (HMODULE) + hmodule_ptr_ = memory()->SystemHeapAlloc(sizeof(X_LDR_DATA_TABLE_ENTRY)); + + // Hijack the checksum field to store our kernel object handle. + auto ldr_data = memory()->TranslateVirtual(hmodule_ptr_); + ldr_data->checksum = handle(); +} + +XModule::~XModule() { + kernel_state_->UnregisterModule(this); + + // Destroy the loader data. + memory()->SystemHeapFree(hmodule_ptr_); +} + +bool XModule::Matches(const std::string_view name) const { + return rex::string::utf8_equal_case(rex::string::utf8_find_name_from_guest_path(path()), name) || + rex::string::utf8_equal_case(this->name(), name) || + rex::string::utf8_equal_case(path(), name); +} // namespace system + +void XModule::OnLoad() { + kernel_state_->RegisterModule(this); +} + +void XModule::OnUnload() { + kernel_state_->UnregisterModule(this); +} + +X_STATUS XModule::GetSection(const std::string_view name, uint32_t* out_section_data, + uint32_t* out_section_size) { + return X_STATUS_UNSUCCESSFUL; +} + +object_ref XModule::GetFromHModule(KernelState* kernel_state, void* hmodule) { + // Grab the object from our stashed kernel handle + return kernel_state->object_table()->LookupObject(GetHandleFromHModule(hmodule)); +} + +uint32_t XModule::GetHandleFromHModule(void* hmodule) { + auto ldr_data = reinterpret_cast(hmodule); + return ldr_data->checksum; +} + +bool XModule::Save(stream::ByteStream* stream) { + REXSYS_DEBUG("XModule {:08X} ({})", handle(), path()); + + stream->Write(kModuleSaveSignature); + + stream->Write(path()); + stream->Write(hmodule_ptr_); + + if (!SaveObject(stream)) { + return false; + } + + return true; +} + +object_ref XModule::Restore(KernelState* kernel_state, stream::ByteStream* stream) { + if (stream->Read() != kModuleSaveSignature) { + return nullptr; + } + + auto path = stream->Read(); + auto hmodule_ptr = stream->Read(); + + // Can only save user modules at the moment, so just redirect. + // TODO: Find a way to call RestoreObject here before UserModule::Restore. + auto module = UserModule::Restore(kernel_state, stream, path); + if (!module) { + return nullptr; + } + + REXSYS_DEBUG("XModule {:08X} ({})", module->handle(), module->path()); + + module->hmodule_ptr_ = hmodule_ptr; + return module; +} + +} // namespace rex::system diff --git a/src/system/xmutant.cpp b/src/system/xmutant.cpp new file mode 100644 index 0000000..9303962 --- /dev/null +++ b/src/system/xmutant.cpp @@ -0,0 +1,92 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +namespace rex::system { + +XMutant::XMutant(KernelState* kernel_state) : XObject(kernel_state, kObjectType) {} + +XMutant::XMutant() : XObject(kObjectType) {} + +XMutant::~XMutant() = default; + +void XMutant::Initialize(bool initial_owner) { + assert_false(mutant_); + + mutant_ = rex::thread::Mutant::Create(initial_owner); + assert_not_null(mutant_); +} + +void XMutant::InitializeNative(void* native_ptr, X_DISPATCH_HEADER* header) { + assert_false(mutant_); + + // Haven't seen this yet, but it's possible. + assert_always(); +} + +X_STATUS XMutant::ReleaseMutant(uint32_t priority_increment, bool abandon, bool wait) { + // Call should succeed if we own the mutant, so go ahead and do this. + if (owning_thread_ == XThread::GetCurrentThread()) { + owning_thread_ = nullptr; + } + + // TODO(benvanik): abandoning. + assert_false(abandon); + if (mutant_->Release()) { + return X_STATUS_SUCCESS; + } else { + return X_STATUS_MUTANT_NOT_OWNED; + } +} + +bool XMutant::Save(stream::ByteStream* stream) { + if (!SaveObject(stream)) { + return false; + } + + uint32_t owning_thread_handle = owning_thread_ ? owning_thread_->handle() : 0; + stream->Write(owning_thread_handle); + REXSYS_DEBUG("XMutant {:08X} (owner: {:08X})", handle(), owning_thread_handle); + + return true; +} + +object_ref XMutant::Restore(KernelState* kernel_state, stream::ByteStream* stream) { + auto mutant = new XMutant(); + mutant->kernel_state_ = kernel_state; + + if (!mutant->RestoreObject(stream)) { + delete mutant; + return nullptr; + } + + mutant->Initialize(false); + + auto owning_thread_handle = stream->Read(); + if (owning_thread_handle) { + mutant->owning_thread_ = + kernel_state->object_table()->LookupObject(owning_thread_handle).get(); + mutant->owning_thread_->AcquireMutantOnStartup(retain_object(mutant)); + } + + return object_ref(mutant); +} + +void XMutant::WaitCallback() { + owning_thread_ = XThread::GetCurrentThread(); +} + +} // namespace rex::system diff --git a/src/system/xnotifylistener.cpp b/src/system/xnotifylistener.cpp new file mode 100644 index 0000000..eae1014 --- /dev/null +++ b/src/system/xnotifylistener.cpp @@ -0,0 +1,123 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +namespace rex::system { + +XNotifyListener::XNotifyListener(KernelState* kernel_state) : XObject(kernel_state, kObjectType) {} + +XNotifyListener::~XNotifyListener() {} + +void XNotifyListener::Initialize(uint64_t mask, uint32_t max_version) { + assert_false(wait_handle_); + + wait_handle_ = rex::thread::Event::CreateManualResetEvent(false); + assert_not_null(wait_handle_); + mask_ = mask; + max_version_ = max_version; + + kernel_state_->RegisterNotifyListener(this); +} + +void XNotifyListener::EnqueueNotification(XNotificationID id, uint32_t data) { + auto key = XNotificationKey(id); + // Ignore if the notification doesn't match our mask. + if ((mask_ & uint64_t(1ULL << key.mask_index)) == 0) { + return; + } + // Ignore if the notification is too new. + if (key.version > max_version_) { + return; + } + auto global_lock = global_critical_region_.Acquire(); + notifications_.push_back(std::pair(id, data)); + wait_handle_->Set(); +} + +bool XNotifyListener::DequeueNotification(XNotificationID* out_id, uint32_t* out_data) { + auto global_lock = global_critical_region_.Acquire(); + bool dequeued = false; + if (notifications_.size()) { + dequeued = true; + auto it = notifications_.begin(); + *out_id = it->first; + *out_data = it->second; + notifications_.erase(it); + if (!notifications_.size()) { + wait_handle_->Reset(); + } + } + return dequeued; +} + +bool XNotifyListener::DequeueNotification(XNotificationID id, uint32_t* out_data) { + auto global_lock = global_critical_region_.Acquire(); + if (!notifications_.size()) { + return false; + } + bool dequeued = false; + for (auto it = notifications_.begin(); it != notifications_.end(); ++it) { + if (it->first != id) { + continue; + } + dequeued = true; + *out_data = it->second; + notifications_.erase(it); + if (!notifications_.size()) { + wait_handle_->Reset(); + } + break; + } + return dequeued; +} + +bool XNotifyListener::Save(stream::ByteStream* stream) { + SaveObject(stream); + + stream->Write(mask_); + stream->Write(max_version_); + stream->Write(notifications_.size()); + for (auto pair : notifications_) { + stream->Write(pair.first); + stream->Write(pair.second); + } + + return true; +} + +object_ref XNotifyListener::Restore(KernelState* kernel_state, + stream::ByteStream* stream) { + auto notify = new XNotifyListener(nullptr); + notify->kernel_state_ = kernel_state; + + notify->RestoreObject(stream); + + auto mask = stream->Read(); + auto max_version = stream->Read(); + notify->Initialize(mask, max_version); + + auto notification_count_ = stream->Read(); + for (size_t i = 0; i < notification_count_; i++) { + std::pair pair; + pair.first = stream->Read(); + pair.second = stream->Read(); + notify->notifications_.push_back(pair); + } + + return object_ref(notify); +} + +} // namespace rex::system diff --git a/src/system/xobject.cpp b/src/system/xobject.cpp new file mode 100644 index 0000000..b328244 --- /dev/null +++ b/src/system/xobject.cpp @@ -0,0 +1,446 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include // For TranslateAnsiStringAddress +#include +// #include // TODO: JIT only +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rex::system { + +XObject::XObject(Type type) : kernel_state_(nullptr), pointer_ref_count_(1), type_(type) { + handles_.reserve(10); +} + +XObject::XObject(KernelState* kernel_state, Type type) + : kernel_state_(kernel_state), + type_(type), + pointer_ref_count_(1), + guest_object_ptr_(0), + allocated_guest_object_(false) { + handles_.reserve(10); + + // TODO: Assert kernel_state != nullptr in this constructor. + if (kernel_state) { + kernel_state->object_table()->AddHandle(this, nullptr); + } +} + +XObject::~XObject() { + // TODO: these are being asserted true... find out why + // assert_true(handles_.empty()); + // assert_zero(pointer_ref_count_); + + if (allocated_guest_object_) { + uint32_t ptr = guest_object_ptr_ - sizeof(X_OBJECT_HEADER); + auto header = memory()->TranslateVirtual(ptr); + + // Free the object creation info + if (header->object_type_ptr) { + memory()->SystemHeapFree(header->object_type_ptr); + } + + memory()->SystemHeapFree(ptr); + } +} + +rex::Runtime* XObject::emulator() const { + return kernel_state_->emulator_; +} +KernelState* XObject::kernel_state() const { + return kernel_state_; +} +rex::memory::Memory* XObject::memory() const { + return kernel_state_->memory(); +} + +XObject::Type XObject::type() const { + return type_; +} + +void XObject::RetainHandle() { + kernel_state_->object_table()->RetainHandle(handles_[0]); +} + +bool XObject::ReleaseHandle() { + // FIXME: Return true when handle is actually released. + return kernel_state_->object_table()->ReleaseHandle(handles_[0]) == X_STATUS_SUCCESS; +} + +void XObject::Retain() { + ++pointer_ref_count_; +} + +void XObject::Release() { + if (--pointer_ref_count_ == 0) { + delete this; + } +} + +X_STATUS XObject::Delete() { + if (kernel_state_ == nullptr) { + // Fake return value for api-scanner + return X_STATUS_SUCCESS; + } else { + if (!name_.empty()) { + kernel_state_->object_table()->RemoveNameMapping(name_); + } + return kernel_state_->object_table()->RemoveHandle(handles_[0]); + } +} + +bool XObject::SaveObject(stream::ByteStream* stream) { + stream->Write(allocated_guest_object_); + stream->Write(guest_object_ptr_); + + stream->Write(uint32_t(handles_.size())); + stream->Write(&handles_[0], handles_.size() * sizeof(X_HANDLE)); + + return true; +} + +bool XObject::RestoreObject(stream::ByteStream* stream) { + allocated_guest_object_ = stream->Read() > 0; + guest_object_ptr_ = stream->Read(); + + handles_.resize(stream->Read()); + stream->Read(&handles_[0], handles_.size() * sizeof(X_HANDLE)); + + // Restore our pointer to our handles in the object table. + for (size_t i = 0; i < handles_.size(); i++) { + kernel_state_->object_table()->RestoreHandle(handles_[i], this); + } + + return true; +} + +object_ref XObject::Restore(KernelState* kernel_state, Type type, + stream::ByteStream* stream) { + switch (type) { + case Type::Enumerator: + break; + case Type::Event: + return XEvent::Restore(kernel_state, stream); + case Type::File: + return XFile::Restore(kernel_state, stream); + case Type::IOCompletion: + break; + case Type::Module: + return XModule::Restore(kernel_state, stream); + case Type::Mutant: + return XMutant::Restore(kernel_state, stream); + case Type::NotifyListener: + return XNotifyListener::Restore(kernel_state, stream); + case Type::Semaphore: + return XSemaphore::Restore(kernel_state, stream); + case Type::Session: + break; + case Type::Socket: + break; + case Type::SymbolicLink: + return XSymbolicLink::Restore(kernel_state, stream); + case Type::Thread: + return XThread::Restore(kernel_state, stream); + case Type::Timer: + break; + case Type::Undefined: + break; + } + + assert_always("No restore handler exists for this object!"); + return nullptr; +} + +void XObject::SetAttributes(uint32_t obj_attributes_ptr) { + if (!obj_attributes_ptr) { + return; + } + + auto name = util::TranslateAnsiStringAddress( + memory(), + memory::load_and_swap(memory()->TranslateVirtual(obj_attributes_ptr + 4))); + if (!name.empty()) { + name_ = std::string(name); + kernel_state_->object_table()->AddNameMapping(name_, handles_[0]); + } +} + +uint32_t XObject::TimeoutTicksToMs(int64_t timeout_ticks) { + if (timeout_ticks > 0) { + // Absolute time, based on January 1, 1601. + // TODO(benvanik): convert time to relative time. + assert_always(); + return 0; + } else if (timeout_ticks < 0) { + // Relative time. + return (uint32_t)(-timeout_ticks / 10000); // Ticks -> MS + } else { + return 0; + } +} + +X_STATUS XObject::Wait(uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable, + uint64_t* opt_timeout) { + auto wait_handle = GetWaitHandle(); + if (!wait_handle) { + // Object doesn't support waiting. + return X_STATUS_SUCCESS; + } + + auto timeout_ms = opt_timeout ? std::chrono::milliseconds(chrono::Clock::ScaleGuestDurationMillis( + TimeoutTicksToMs(*opt_timeout))) + : std::chrono::milliseconds::max(); + + auto result = rex::thread::Wait(wait_handle, alertable ? true : false, timeout_ms); + switch (result) { + case rex::thread::WaitResult::kSuccess: + WaitCallback(); + return X_STATUS_SUCCESS; + case rex::thread::WaitResult::kUserCallback: + // Or X_STATUS_ALERTED? + return X_STATUS_USER_APC; + case rex::thread::WaitResult::kTimeout: + rex::thread::MaybeYield(); + return X_STATUS_TIMEOUT; + default: + case rex::thread::WaitResult::kAbandoned: + case rex::thread::WaitResult::kFailed: + return X_STATUS_ABANDONED_WAIT_0; + } +} + +X_STATUS XObject::SignalAndWait(XObject* signal_object, XObject* wait_object, uint32_t wait_reason, + uint32_t processor_mode, uint32_t alertable, + uint64_t* opt_timeout) { + auto timeout_ms = opt_timeout ? std::chrono::milliseconds(chrono::Clock::ScaleGuestDurationMillis( + TimeoutTicksToMs(*opt_timeout))) + : std::chrono::milliseconds::max(); + + auto result = + rex::thread::SignalAndWait(signal_object->GetWaitHandle(), wait_object->GetWaitHandle(), + alertable ? true : false, timeout_ms); + switch (result) { + case rex::thread::WaitResult::kSuccess: + wait_object->WaitCallback(); + return X_STATUS_SUCCESS; + case rex::thread::WaitResult::kUserCallback: + // Or X_STATUS_ALERTED? + return X_STATUS_USER_APC; + case rex::thread::WaitResult::kTimeout: + rex::thread::MaybeYield(); + return X_STATUS_TIMEOUT; + default: + case rex::thread::WaitResult::kAbandoned: + case rex::thread::WaitResult::kFailed: + return X_STATUS_ABANDONED_WAIT_0; + } +} + +X_STATUS XObject::WaitMultiple(uint32_t count, XObject** objects, uint32_t wait_type, + uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable, + uint64_t* opt_timeout) { + std::vector wait_handles(count); + for (size_t i = 0; i < count; ++i) { + wait_handles[i] = objects[i]->GetWaitHandle(); + assert_not_null(wait_handles[i]); + } + + auto timeout_ms = opt_timeout ? std::chrono::milliseconds(chrono::Clock::ScaleGuestDurationMillis( + TimeoutTicksToMs(*opt_timeout))) + : std::chrono::milliseconds::max(); + + if (wait_type) { + auto result = + rex::thread::WaitAny(std::move(wait_handles), alertable ? true : false, timeout_ms); + switch (result.first) { + case rex::thread::WaitResult::kSuccess: + objects[result.second]->WaitCallback(); + + return X_STATUS(result.second); + case rex::thread::WaitResult::kUserCallback: + // Or X_STATUS_ALERTED? + return X_STATUS_USER_APC; + case rex::thread::WaitResult::kTimeout: + rex::thread::MaybeYield(); + return X_STATUS_TIMEOUT; + default: + case rex::thread::WaitResult::kAbandoned: + return X_STATUS(X_STATUS_ABANDONED_WAIT_0 + result.second); + case rex::thread::WaitResult::kFailed: + return X_STATUS_UNSUCCESSFUL; + } + } else { + auto result = + rex::thread::WaitAll(std::move(wait_handles), alertable ? true : false, timeout_ms); + switch (result) { + case rex::thread::WaitResult::kSuccess: + for (uint32_t i = 0; i < count; i++) { + objects[i]->WaitCallback(); + } + + return X_STATUS_SUCCESS; + case rex::thread::WaitResult::kUserCallback: + // Or X_STATUS_ALERTED? + return X_STATUS_USER_APC; + case rex::thread::WaitResult::kTimeout: + rex::thread::MaybeYield(); + return X_STATUS_TIMEOUT; + default: + case rex::thread::WaitResult::kAbandoned: + case rex::thread::WaitResult::kFailed: + return X_STATUS_ABANDONED_WAIT_0; + } + } +} + +uint8_t* XObject::CreateNative(uint32_t size) { + auto global_lock = rex::thread::global_critical_region::AcquireDirect(); + + uint32_t total_size = size + sizeof(X_OBJECT_HEADER); + + auto mem = memory()->SystemHeapAlloc(total_size); + if (!mem) { + // Out of memory! + return nullptr; + } + + allocated_guest_object_ = true; + memory()->Zero(mem, total_size); + SetNativePointer(mem + sizeof(X_OBJECT_HEADER), true); + + auto header = memory()->TranslateVirtual(mem); + + auto object_type = memory()->SystemHeapAlloc(sizeof(X_OBJECT_TYPE)); + if (object_type) { + // Set it up in the header. + // Some kernel method is accessing this struct and dereferencing a member + // @ offset 0x14 + header->object_type_ptr = object_type; + } + + return memory()->TranslateVirtual(guest_object_ptr_); +} + +void XObject::SetNativePointer(uint32_t native_ptr, bool uninitialized) { + auto global_lock = rex::thread::global_critical_region::AcquireDirect(); + + // If hit: We've already setup the native ptr with CreateNative! + assert_zero(guest_object_ptr_); + + auto header = kernel_state_->memory()->TranslateVirtual(native_ptr); + + // Memory uninitialized, so don't bother with the check. + if (!uninitialized) { + assert_true(!(header->wait_list_blink & 0x1)); + } + + // Stash pointer in struct. + // FIXME: This assumes the object has a dispatch header (some don't!) + StashHandle(header, handle()); + + guest_object_ptr_ = native_ptr; +} + +object_ref XObject::GetNativeObject(KernelState* kernel_state, void* native_ptr, + int32_t as_type) { + assert_not_null(native_ptr); + + // Unfortunately the XDK seems to inline some KeInitialize calls, meaning + // we never see it and just randomly start getting passed events/timers/etc. + // Luckily it seems like all other calls (Set/Reset/Wait/etc) are used and + // we don't have to worry about PPC code poking the struct. Because of that, + // we init on first use, store our handle in the struct, and dereference it + // each time. + // We identify this by setting wait_list_flink to a magic value. When set, + // wait_list_blink will hold a handle to our object. + + auto global_lock = rex::thread::global_critical_region::AcquireDirect(); + + auto header = reinterpret_cast(native_ptr); + + if (as_type == -1) { + as_type = header->type; + } + + if (header->wait_list_flink == kXObjSignature) { + // Already initialized. + // TODO: assert if the type of the object != as_type + uint32_t handle = header->wait_list_blink; + auto object = kernel_state->object_table()->LookupObject(handle); + + // TODO(benvanik): assert nothing has been changed in the struct. + return object; + } else { + // First use, create new. + // https://www.nirsoft.net/kernel_struct/vista/KOBJECTS.html + XObject* object = nullptr; + switch (as_type) { + case 0: // EventNotificationObject + case 1: // EventSynchronizationObject + { + auto ev = new XEvent(kernel_state); + ev->InitializeNative(native_ptr, header); + object = ev; + } break; + case 2: // MutantObject + { + auto mutant = new XMutant(kernel_state); + mutant->InitializeNative(native_ptr, header); + object = mutant; + } break; + case 5: // SemaphoreObject + { + auto sem = new XSemaphore(kernel_state); + auto success = sem->InitializeNative(native_ptr, header); + // Can't report failure to the guest at late initialization: + assert_true(success); + object = sem; + } break; + case 3: // ProcessObject + case 4: // QueueObject + case 6: // ThreadObject + case 7: // GateObject + case 8: // TimerNotificationObject + case 9: // TimerSynchronizationObject + case 18: // ApcObject + case 19: // DpcObject + case 20: // DeviceQueueObject + case 21: // EventPairObject + case 22: // InterruptObject + case 23: // ProfileObject + case 24: // ThreadedDpcObject + default: + assert_always(); + return NULL; + } + + // Stash pointer in struct. + // FIXME: This assumes the object contains a dispatch header (some don't!) + StashHandle(header, object->handle()); + + return object_ref(object); + } +} + +} // namespace rex::system diff --git a/src/system/xsemaphore.cpp b/src/system/xsemaphore.cpp new file mode 100644 index 0000000..db830e4 --- /dev/null +++ b/src/system/xsemaphore.cpp @@ -0,0 +1,91 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +namespace rex::system { + +XSemaphore::XSemaphore(KernelState* kernel_state) : XObject(kernel_state, kObjectType) {} + +XSemaphore::~XSemaphore() = default; + +bool XSemaphore::Initialize(int32_t initial_count, int32_t maximum_count) { + assert_false(semaphore_); + + CreateNative(sizeof(X_KSEMAPHORE)); + + maximum_count_ = maximum_count; + semaphore_ = rex::thread::Semaphore::Create(initial_count, maximum_count); + return !!semaphore_; +} + +bool XSemaphore::InitializeNative(void* native_ptr, X_DISPATCH_HEADER* header) { + assert_false(semaphore_); + + auto semaphore = reinterpret_cast(native_ptr); + maximum_count_ = semaphore->limit; + semaphore_ = rex::thread::Semaphore::Create(semaphore->header.signal_state, semaphore->limit); + return !!semaphore_; +} + +bool XSemaphore::ReleaseSemaphore(int32_t release_count, int32_t* out_previous_count) { + int32_t previous_count = 0; + bool success = semaphore_->Release(release_count, &previous_count); + if (out_previous_count) { + *out_previous_count = previous_count; + } + return success; +} + +bool XSemaphore::Save(stream::ByteStream* stream) { + if (!SaveObject(stream)) { + return false; + } + + // Get the free number of slots from the semaphore. + uint32_t free_count = 0; + while (rex::thread::Wait(semaphore_.get(), false, std::chrono::milliseconds(0)) == + rex::thread::WaitResult::kSuccess) { + free_count++; + } + + REXSYS_DEBUG("XSemaphore {:08X} (count {}/{})", handle(), free_count, maximum_count_); + + // Restore the semaphore back to its previous count. + semaphore_->Release(free_count, nullptr); + + stream->Write(maximum_count_); + stream->Write(free_count); + + return true; +} + +object_ref XSemaphore::Restore(KernelState* kernel_state, stream::ByteStream* stream) { + auto sem = new XSemaphore(nullptr); + sem->kernel_state_ = kernel_state; + + if (!sem->RestoreObject(stream)) { + return nullptr; + } + + sem->maximum_count_ = stream->Read(); + auto free_count = stream->Read(); + REXSYS_DEBUG("XSemaphore {:08X} (count {}/{})", sem->handle(), free_count, sem->maximum_count_); + + sem->semaphore_ = rex::thread::Semaphore::Create(free_count, sem->maximum_count_); + assert_not_null(sem->semaphore_); + + return object_ref(sem); +} + +} // namespace rex::system diff --git a/src/system/xsocket.cpp b/src/system/xsocket.cpp new file mode 100644 index 0000000..0b44e06 --- /dev/null +++ b/src/system/xsocket.cpp @@ -0,0 +1,250 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include +// #include + +#include + +// Standard socket types used by Xbox API emulation +#if REX_PLATFORM_WIN32 +#include + +#include +#else +#include +#include +#include +#include +#endif + +namespace rex::system { + +XSocket::XSocket(KernelState* kernel_state) : XObject(kernel_state, kObjectType) {} + +XSocket::XSocket(KernelState* kernel_state, uint64_t native_handle) + : XObject(kernel_state, kObjectType), native_handle_(native_handle) {} + +XSocket::~XSocket() { + Close(); +} + +X_STATUS XSocket::Initialize(AddressFamily af, Type type, Protocol proto) { + af_ = af; + type_ = type; + proto_ = proto; + + if (proto == Protocol::IPPROTO_VDP) { + // VDP is a layer on top of UDP. + proto = Protocol::IPPROTO_UDP; + } + + native_handle_ = socket(af, type, proto); + if (native_handle_ == -1) { + return X_STATUS_UNSUCCESSFUL; + } + + return X_STATUS_SUCCESS; +} + +X_STATUS XSocket::Close() { + int ret = rex::net::socket_close(native_handle_); + if (ret != 0) { + return X_STATUS_UNSUCCESSFUL; + } + + return X_STATUS_SUCCESS; +} + +X_STATUS XSocket::SetOption(uint32_t level, uint32_t optname, void* optval_ptr, uint32_t optlen) { + if (level == 0xFFFF && (optname == 0x5801 || optname == 0x5802)) { + // Disable socket encryption + secure_ = false; + return X_STATUS_SUCCESS; + } + + int ret = setsockopt(native_handle_, level, optname, (char*)optval_ptr, optlen); + if (ret < 0) { + // TODO: WSAGetLastError() + return X_STATUS_UNSUCCESSFUL; + } + + // SO_BROADCAST + if (level == 0xFFFF && optname == 0x0020) { + broadcast_socket_ = true; + } + + return X_STATUS_SUCCESS; +} + +X_STATUS XSocket::IOControl(uint32_t cmd, uint8_t* arg_ptr) { + int ret = rex::net::socket_ioctl(native_handle_, cmd, arg_ptr); + if (ret < 0) { + // TODO: Get last error + return X_STATUS_UNSUCCESSFUL; + } + + return X_STATUS_SUCCESS; +} + +X_STATUS XSocket::Connect(N_XSOCKADDR* name, int name_len) { + int ret = connect(native_handle_, (sockaddr*)name, name_len); + if (ret < 0) { + return X_STATUS_UNSUCCESSFUL; + } + + return X_STATUS_SUCCESS; +} + +X_STATUS XSocket::Bind(N_XSOCKADDR_IN* name, int name_len) { + int ret = bind(native_handle_, (sockaddr*)name, name_len); + if (ret < 0) { + return X_STATUS_UNSUCCESSFUL; + } + + bound_ = true; + bound_port_ = name->sin_port; + + return X_STATUS_SUCCESS; +} + +X_STATUS XSocket::Listen(int backlog) { + int ret = listen(native_handle_, backlog); + if (ret < 0) { + return X_STATUS_UNSUCCESSFUL; + } + + return X_STATUS_SUCCESS; +} + +object_ref XSocket::Accept(N_XSOCKADDR* name, int* name_len) { + sockaddr n_sockaddr; + socklen_t n_name_len = sizeof(sockaddr); + uintptr_t ret = accept(native_handle_, &n_sockaddr, &n_name_len); + if (ret == -1) { + std::memset(name, 0, *name_len); + *name_len = 0; + return nullptr; + } + + std::memcpy(name, &n_sockaddr, n_name_len); + *name_len = n_name_len; + + // Create a kernel object to represent the new socket, and copy parameters + // over. + auto socket = object_ref(new XSocket(kernel_state_, ret)); + socket->af_ = af_; + socket->type_ = type_; + socket->proto_ = proto_; + + return socket; +} + +int XSocket::Shutdown(int how) { + return shutdown(native_handle_, how); +} + +int XSocket::Recv(uint8_t* buf, uint32_t buf_len, uint32_t flags) { + return recv(native_handle_, reinterpret_cast(buf), buf_len, flags); +} + +int XSocket::RecvFrom(uint8_t* buf, uint32_t buf_len, uint32_t flags, N_XSOCKADDR_IN* from, + uint32_t* from_len) { + // Pop from secure packets first + // TODO(DrChat): Enable when I commit XNet + /* + { + std::lock_guard lock(incoming_packet_mutex_); + if (incoming_packets_.size()) { + packet* pkt = (packet*)incoming_packets_.front(); + int data_len = pkt->data_len; + std::memcpy(buf, pkt->data, std::min((uint32_t)pkt->data_len, buf_len)); + + from->sin_family = 2; + from->sin_addr = pkt->src_ip; + from->sin_port = pkt->src_port; + + incoming_packets_.pop(); + uint8_t* pkt_ui8 = (uint8_t*)pkt; + delete[] pkt_ui8; + + return data_len; + } + } + */ + + sockaddr_in nfrom; + socklen_t nfromlen = sizeof(sockaddr_in); + int ret = recvfrom(native_handle_, reinterpret_cast(buf), buf_len, flags, + (sockaddr*)&nfrom, &nfromlen); + if (from) { + from->sin_family = nfrom.sin_family; + from->sin_addr = ntohl(nfrom.sin_addr.s_addr); // BE <- BE + from->sin_port = nfrom.sin_port; + std::memset(from->x_sin_zero, 0, sizeof(from->x_sin_zero)); + } + + if (from_len) { + *from_len = nfromlen; + } + + return ret; +} + +int XSocket::Send(const uint8_t* buf, uint32_t buf_len, uint32_t flags) { + return send(native_handle_, reinterpret_cast(buf), buf_len, flags); +} + +int XSocket::SendTo(uint8_t* buf, uint32_t buf_len, uint32_t flags, N_XSOCKADDR_IN* to, + uint32_t to_len) { + // Send 2 copies of the packet: One to XNet (for network security) and an + // unencrypted copy for other Xenia hosts. + // TODO(DrChat): Enable when I commit XNet. + /* + auto xam = kernel_state()->GetKernelModule("xam.xex"); + auto xnet = xam->xnet(); + if (xnet) { + xnet->SendPacket(this, to, buf, buf_len); + } + */ + + sockaddr_in nto; + if (to) { + nto.sin_addr.s_addr = to->sin_addr; + nto.sin_family = to->sin_family; + nto.sin_port = to->sin_port; + } + + return sendto(native_handle_, reinterpret_cast(buf), buf_len, flags, + to ? (sockaddr*)&nto : nullptr, to_len); +} + +bool XSocket::QueuePacket(uint32_t src_ip, uint16_t src_port, const uint8_t* buf, size_t len) { + packet* pkt = reinterpret_cast(new uint8_t[sizeof(packet) + len]); + pkt->src_ip = src_ip; + pkt->src_port = src_port; + + pkt->data_len = (uint16_t)len; + std::memcpy(pkt->data, buf, len); + + std::lock_guard lock(incoming_packet_mutex_); + incoming_packets_.push((uint8_t*)pkt); + + // TODO: Limit on number of incoming packets? + return true; +} + +} // namespace rex::system \ No newline at end of file diff --git a/src/system/xsymboliclink.cpp b/src/system/xsymboliclink.cpp new file mode 100644 index 0000000..eae8624 --- /dev/null +++ b/src/system/xsymboliclink.cpp @@ -0,0 +1,56 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +namespace rex::system { + +XSymbolicLink::XSymbolicLink(KernelState* kernel_state) + : XObject(kernel_state, kObjectType), path_(), target_() {} + +XSymbolicLink::XSymbolicLink() : XObject(kObjectType), path_(), target_() {} + +XSymbolicLink::~XSymbolicLink() {} + +void XSymbolicLink::Initialize(const std::string_view path, const std::string_view target) { + path_ = std::string(path); + target_ = std::string(target); + // TODO(gibbed): kernel_state_->RegisterSymbolicLink(this); +} + +bool XSymbolicLink::Save(stream::ByteStream* stream) { + if (!SaveObject(stream)) { + return false; + } + stream->Write(path_); + stream->Write(target_); + return true; +} + +object_ref XSymbolicLink::Restore(KernelState* kernel_state, + stream::ByteStream* stream) { + auto symlink = new XSymbolicLink(); + symlink->kernel_state_ = kernel_state; + if (!symlink->RestoreObject(stream)) { + delete symlink; + return nullptr; + } + + auto path = stream->Read(); + auto target = stream->Read(); + symlink->Initialize(path, target); + + return object_ref(symlink); +} + +} // namespace rex::system diff --git a/src/system/xthread.cpp b/src/system/xthread.cpp new file mode 100644 index 0000000..db31ff4 --- /dev/null +++ b/src/system/xthread.cpp @@ -0,0 +1,1437 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(ignore_thread_priorities, true, "Kernel", + "Ignores game-specified thread priorities"); + +REXCVAR_DEFINE_BOOL(ignore_thread_affinities, true, "Kernel", + "Ignores game-specified thread affinities"); + +namespace rex::system { + +const uint32_t XAPC::kSize; +const uint32_t XAPC::kDummyKernelRoutine; +const uint32_t XAPC::kDummyRundownRoutine; + +using namespace rex::literals; + +uint32_t next_xthread_id_ = 0; + +XThread::XThread(KernelState* kernel_state) + : XObject(kernel_state, kObjectType), guest_thread_(true) {} + +XThread::XThread(KernelState* kernel_state, uint32_t stack_size, uint32_t xapi_thread_startup, + uint32_t start_address, uint32_t start_context, uint32_t creation_flags, + bool guest_thread, bool main_thread, uint32_t guest_process) + : XObject(kernel_state, kObjectType), + thread_id_(++next_xthread_id_), + guest_thread_(guest_thread), + main_thread_(main_thread), + apc_lock_old_irql_(0) { + creation_params_.stack_size = stack_size; + creation_params_.xapi_thread_startup = xapi_thread_startup; + creation_params_.start_address = start_address; + creation_params_.start_context = start_context; + + // top 8 bits = processor ID (or 0 for default) + // bit 0 = 1 to create suspended + creation_params_.creation_flags = creation_flags; + creation_params_.guest_process = guest_process; + + // Adjust stack size - min of 16k. + if (creation_params_.stack_size < 16 * 1024) { + creation_params_.stack_size = 16 * 1024; + } + + if (!guest_thread_) { + host_object_ = true; + } + + // The kernel does not take a reference. We must unregister in the dtor. + kernel_state_->RegisterThread(this); +} + +XThread::~XThread() { + if (main_fiber_) { + main_fiber_->Destroy(); + main_fiber_ = nullptr; + } + + // Unregister first to prevent lookups while deleting. + kernel_state_->UnregisterThread(this); + + thread_.reset(); + + kernel_state_->memory()->SystemHeapFree(scratch_address_); + kernel_state_->memory()->SystemHeapFree(tls_static_address_); + kernel_state_->memory()->SystemHeapFree(pcr_address_); + FreeStack(); + + if (thread_) { + // TODO(benvanik): platform kill + REXSYS_ERROR("Thread disposed without exiting"); + } +} + +thread_local XThread* current_xthread_tls_ = nullptr; + +namespace { + +XThread* GetBoundCurrentXThread() { + return current_xthread_tls_; +} + +} // namespace + +bool XThread::IsInThread() { + return GetBoundCurrentXThread() != nullptr; +} + +bool XThread::IsInThread(XThread* other) { + return GetBoundCurrentXThread() == other; +} + +XThread* XThread::GetCurrentThread() { + XThread* thread = GetBoundCurrentXThread(); + if (!thread) { + assert_always("Attempting to use kernel stuff from a non-kernel thread"); + } + return thread; +} + +uint32_t XThread::GetCurrentThreadHandle() { + XThread* thread = XThread::GetCurrentThread(); + return thread->handle(); +} + +uint32_t XThread::GetCurrentThreadId() { + XThread* thread = XThread::GetCurrentThread(); + return thread->guest_object()->thread_id; +} + +uint32_t XThread::GetLastError() { + XThread* thread = XThread::GetCurrentThread(); + return thread->last_error(); +} + +void XThread::SetLastError(uint32_t error_code) { + XThread* thread = XThread::GetCurrentThread(); + thread->set_last_error(error_code); +} + +uint32_t XThread::last_error() { + return guest_object()->last_error; +} + +void XThread::set_last_error(uint32_t error_code) { + guest_object()->last_error = error_code; +} + +void XThread::set_name(const std::string_view name) { + std::lock_guard lock(thread_lock_); + thread_name_ = fmt::format("{} ({:08X})", name, handle()); + + if (thread_) { + // May be getting set before the thread is created. + // One the thread is ready it will handle it. + thread_->set_name(thread_name_); + } +} + +static uint8_t next_cpu = 0; +static uint8_t GetFakeCpuNumber(uint8_t proc_mask) { + // NOTE: proc_mask is logical processors, not physical processors or cores. + if (!proc_mask) { + next_cpu = (next_cpu + 1) % 6; + return next_cpu; // is this reasonable? + // TODO(Triang3l): Does the following apply here? + // https://docs.microsoft.com/en-us/windows/win32/dxtecharts/coding-for-multiple-cores + // "On Xbox 360, you must explicitly assign software threads to a particular + // hardware thread by using XSetThreadProcessor. Otherwise, all child + // threads will stay on the same hardware thread as the parent." + } + assert_false(proc_mask & 0xC0); + + uint8_t cpu_number = 7 - rex::lzcnt(proc_mask); + assert_true(1 << cpu_number == proc_mask); + assert_true(cpu_number < 6); + return cpu_number; +} + +void XThread::InitializeGuestObject() { + auto guest_thread = guest_object(); + uint32_t guest_ptr = guest_object(); + + guest_thread->header.type = 6; // ThreadObject + guest_thread->suspend_count = (creation_params_.creation_flags & X_CREATE_SUSPENDED) ? 1 : 0; + + // Self-referencing pointers for wait timeout timer/block + guest_thread->unk_10 = guest_ptr + 0x010; + guest_thread->unk_14 = guest_ptr + 0x010; + + guest_thread->wait_timeout_block.wait_list_entry.flink_ptr = guest_ptr + 0x20; + guest_thread->wait_timeout_block.wait_list_entry.blink_ptr = guest_ptr + 0x20; + guest_thread->wait_timeout_block.thread = guest_ptr; + guest_thread->wait_timeout_block.object = guest_ptr + 0x18; + guest_thread->wait_timeout_block.wait_result_xstatus = 0x0100; + guest_thread->wait_timeout_block.wait_type = 0x0201; + + guest_thread->stack_base = stack_base_; + guest_thread->stack_limit = stack_limit_; + guest_thread->stack_kernel = stack_base_ - 240; + guest_thread->tls_address = tls_dynamic_address_; + guest_thread->thread_state = 0; + + // Initialize APC lists (kernel + user mode) + guest_thread->apc_lists[0].Initialize(memory()); + guest_thread->apc_lists[1].Initialize(memory()); + + // Set process pointer - use guest_process if provided, else default to title process. + uint32_t process_ptr = creation_params_.guest_process + ? creation_params_.guest_process + : kernel_state_->process_info_block_address(); + guest_thread->process = process_ptr; + guest_thread->may_queue_apcs = 1; + + // Set PRCB pointers (derived from this thread's PCR). + uint32_t kpcrb = pcr_address_ + offsetof(X_KPCR, prcb_data); + guest_thread->a_prcb_ptr = kpcrb; + guest_thread->another_prcb_ptr = kpcrb; + + // PPCContext for spinlock helpers (valid before thread runs; r13 set at construction). + auto* ctx = thread_state_->context(); + + // Set per-thread process type and link into process thread list. + if (process_ptr) { + auto target_process = memory()->TranslateVirtual(process_ptr); + guest_thread->process_type = target_process->process_type; + guest_thread->process_type_dup = target_process->process_type; + + auto old_irql = + kernel::xboxkrnl::xeKeKfAcquireSpinLock(ctx, &target_process->thread_list_spinlock); + util::XeInsertTailList(&target_process->thread_list, &guest_thread->process_threads, memory()); + target_process->thread_count = target_process->thread_count + 1; + kernel::xboxkrnl::xeKeKfReleaseSpinLock(ctx, &target_process->thread_list_spinlock, old_irql); + } else { + guest_thread->process_type = X_PROCTYPE_USER; + guest_thread->process_type_dup = X_PROCTYPE_USER; + } + + guest_thread->msr_mask = 0xFDFFD7FF; + // current_cpu is expected to be initialized externally via SetActiveCpu. + guest_thread->stack_alloc_base = stack_base_; + guest_thread->create_time = chrono::Clock::QueryGuestSystemTime(); + + // Initialize timer_list as self-referencing + guest_thread->timer_list.flink_ptr = guest_ptr + offsetof(X_KTHREAD, timer_list); + guest_thread->timer_list.blink_ptr = guest_ptr + offsetof(X_KTHREAD, timer_list); + + guest_thread->thread_id = thread_id_; + guest_thread->start_address = creation_params_.start_address; + + // Initialize unk_154 list as self-referencing + guest_thread->unk_154.flink_ptr = guest_ptr + offsetof(X_KTHREAD, unk_154); + guest_thread->unk_154.blink_ptr = guest_ptr + offsetof(X_KTHREAD, unk_154); + + guest_thread->last_error = 0; + guest_thread->creation_flags = creation_params_.creation_flags; + guest_thread->unk_17C = 1; +} + +bool XThread::AllocateStack(uint32_t size) { + auto heap = memory()->LookupHeap(kStackAddressRangeBegin); + + auto alignment = heap->page_size(); + auto padding = heap->page_size() * 2; // Guard page size * 2 + size = rex::round_up(size, alignment); + auto actual_size = size + padding; + + uint32_t address = 0; + if (!heap->AllocRange(kStackAddressRangeBegin, kStackAddressRangeEnd, actual_size, alignment, + memory::kMemoryAllocationReserve | memory::kMemoryAllocationCommit, + memory::kMemoryProtectRead | memory::kMemoryProtectWrite, false, + &address)) { + return false; + } + + stack_alloc_base_ = address; + stack_alloc_size_ = actual_size; + stack_limit_ = address + (padding / 2); + stack_base_ = stack_limit_ + size; + + // Initialize the stack with junk + memory()->Fill(stack_alloc_base_, actual_size, 0xBE); + + // Setup the guard pages + heap->Protect(stack_alloc_base_, padding / 2, memory::kMemoryProtectNoAccess); + heap->Protect(stack_base_, padding / 2, memory::kMemoryProtectNoAccess); + + return true; +} + +void XThread::FreeStack() { + if (stack_alloc_base_) { + auto heap = memory()->LookupHeap(kStackAddressRangeBegin); + heap->Release(stack_alloc_base_); + + stack_alloc_base_ = 0; + stack_alloc_size_ = 0; + stack_base_ = 0; + stack_limit_ = 0; + } +} + +X_STATUS XThread::Create() { + // Thread kernel object. + if (!CreateNative()) { + REXSYS_WARN("Unable to allocate thread object"); + return X_STATUS_NO_MEMORY; + } + + // Allocate a stack. + if (!AllocateStack(creation_params_.stack_size)) { + return X_STATUS_NO_MEMORY; + } + + // Allocate thread scratch. + // This is used by interrupts/APCs/etc so we can round-trip pointers through. + scratch_size_ = 4 * 16; + scratch_address_ = memory()->SystemHeapAlloc(scratch_size_); + + // Allocate TLS block. + // Games will specify a certain number of 4b slots that each thread will get. + xex2_opt_tls_info* tls_header = nullptr; + auto module = kernel_state_->GetExecutableModule(); + if (module) { + module->GetOptHeader(XEX_HEADER_TLS_INFO, &tls_header); + } + + const uint32_t kDefaultTlsSlotCount = 1024; + uint32_t tls_slots = kDefaultTlsSlotCount; + uint32_t tls_extended_size = 0; + if (tls_header && tls_header->slot_count) { + tls_slots = tls_header->slot_count; + tls_extended_size = tls_header->data_size; + } + + // Allocate both the slots and the extended data. + // Some TLS is compiled with the binary (declspec(thread)) vars. The game + // will directly access those through 0(r13). + uint32_t tls_slot_size = tls_slots * 4; + tls_total_size_ = tls_slot_size + tls_extended_size; + tls_static_address_ = memory()->SystemHeapAlloc(tls_total_size_); + tls_dynamic_address_ = tls_static_address_ + tls_extended_size; + if (!tls_static_address_) { + REXSYS_WARN("Unable to allocate thread local storage block"); + return X_STATUS_NO_MEMORY; + } + + // Zero all of TLS. + memory()->Fill(tls_static_address_, tls_total_size_, 0); + if (tls_extended_size) { + // If game has extended data, copy in the default values. + assert_not_zero(tls_header->raw_data_address); + memory()->Copy(tls_static_address_, tls_header->raw_data_address, tls_header->raw_data_size); + } + + // Allocate thread state block from heap. + // https://web.archive.org/web/20170704035330/https://www.microsoft.com/msj/archive/S2CE.aspx + // This is set as r13 for user code and some special inlined Win32 calls + // (like GetLastError/etc) will poke it directly. + // We try to use it as our primary store of data just to keep things all + // consistent. + // 0x000: pointer to tls data + // 0x100: pointer to TEB(?) + // 0x10C: Current CPU(?) + // 0x150: if >0 then error states don't get set (DPC active bool?) + // TEB: + // 0x14C: thread id + // 0x160: last error + // So, at offset 0x100 we have a 4b pointer to offset 200, then have the + // structure. + pcr_address_ = memory()->SystemHeapAlloc(0x2D8); + if (!pcr_address_) { + REXSYS_WARN("Unable to allocate thread state block"); + return X_STATUS_NO_MEMORY; + } + + // Create thread state - needed for interrupt callbacks and kernel exports + thread_state_ = + std::make_unique(thread_id_, stack_base_, pcr_address_, memory()); + + REXSYS_NOISY_DEBUG("XThread{:08X} ({:X}) Stack: {:08X}-{:08X}", handle(), thread_id_, + stack_limit_, stack_base_); + + uint8_t cpu_index = GetFakeCpuNumber(static_cast(creation_params_.creation_flags >> 24)); + + // Initialize the KTHREAD object. + InitializeGuestObject(); + + X_KPCR* pcr = memory()->TranslateVirtual(pcr_address_); + + pcr->tls_ptr = tls_static_address_; + pcr->pcr_ptr = pcr_address_; + pcr->prcb_data.current_thread = guest_object(); + pcr->prcb = pcr_address_ + offsetof(X_KPCR, prcb_data); + pcr->host_stash = reinterpret_cast(thread_state_->context()); + pcr->current_irql = 0; + + pcr->stack_base_ptr = stack_base_; + pcr->stack_end_ptr = stack_limit_; + + pcr->prcb_data.dpc_active = 0; + + // Always retain when starting - the thread owns itself until exited. + RetainHandle(); + + rex::thread::Thread::CreationParameters params; + params.stack_size = 16_MiB; // Allocate a big host stack. + params.create_suspended = true; + thread_ = rex::thread::Thread::Create(params, [this]() { + rex::initialize_seh_thread(); + runtime::ThreadState::Bind(thread_state_.get()); + + // Set thread ID override. This is used by logging. + rex::thread::set_current_thread_id(handle()); + + // Set name immediately, if we have one. + thread_->set_name(thread_name_); + + PROFILE_THREAD_ENTER(thread_name_.c_str()); + PROFILE_THREAD_CREATED(); + + // Execute user code. + current_xthread_tls_ = this; + running_ = true; + Execute(); + running_ = false; + current_xthread_tls_ = nullptr; + + PROFILE_THREAD_EXITED(); + PROFILE_THREAD_EXIT(); + + // Release the self-reference to the thread. + ReleaseHandle(); + }); + + if (!thread_) { + // TODO(benvanik): translate error? + REXSYS_ERROR("CreateThread failed"); + return X_STATUS_NO_MEMORY; + } + + // Set the thread name based on host ID (for easier debugging). + if (thread_name_.empty()) { + set_name(fmt::format("XThread{:04X}", thread_->system_id())); + } + + if (creation_params_.creation_flags & 0x60) { + thread_->set_priority(creation_params_.creation_flags & 0x20 ? 1 : 0); + } + + // Assign the newly created thread to the logical processor, and also set up + // the current CPU in KPCR and KTHREAD. + SetActiveCpu(cpu_index); + + // TODO(tomc): do we need thread notifications (related to processor thread management)? + + if ((creation_params_.creation_flags & X_CREATE_SUSPENDED) == 0) { + // Start the thread now that we're all setup. + thread_->Resume(); + } + + return X_STATUS_SUCCESS; +} + +X_STATUS XThread::Exit(int exit_code) { + // This may only be called on the thread itself. + assert_true(XThread::GetCurrentThread() == this); + // Keep the object alive until Thread::Exit() transitions the host thread + // into pthread_exit(). Otherwise ReleaseHandle() below may delete `this` + // while this method is still running. + auto self = retain_object(this); + + // Mark as terminated before running down APCs. + auto kthread = guest_object(); + kthread->terminated = 1; + + // TODO(benvanik): dispatch events? waiters? etc? + RundownAPCs(); + + // Set exit code. + X_KTHREAD* thread = guest_object(); + thread->header.signal_state = 1; + thread->exit_status = exit_code; + + // Unlink thread from process thread list. + uint32_t process_guest = thread->process; + if (process_guest) { + auto* ctx = thread_state_->context(); + auto kprocess = memory()->TranslateVirtual(process_guest); + auto old_irql = kernel::xboxkrnl::xeKeKfAcquireSpinLock(ctx, &kprocess->thread_list_spinlock); + util::XeRemoveEntryList(&thread->process_threads, memory()); + kprocess->thread_count = kprocess->thread_count - 1; + kernel::xboxkrnl::xeKeKfReleaseSpinLock(ctx, &kprocess->thread_list_spinlock, old_irql); + } + + kernel_state_->OnThreadExit(this); + + // TODO(tomc): do we need thread notifications (related to processor thread management)? + + // NOTE: unless PlatformExit fails, expect it to never return! + current_xthread_tls_ = nullptr; + PROFILE_THREAD_EXIT(); + + running_ = false; + ReleaseHandle(); + + // NOTE: this does not return! + rex::thread::Thread::Exit(exit_code); + return X_STATUS_SUCCESS; +} + +X_STATUS XThread::Terminate(int exit_code) { + // TODO(benvanik): inform the profiler that this thread is exiting. + + // Set exit code. + X_KTHREAD* thread = guest_object(); + thread->header.signal_state = 1; + thread->exit_status = exit_code; + + // TODO(tomc): do we need thread notifications (related to processor thread management)? + + running_ = false; + if (XThread::IsInThread(this)) { + // Same lifetime rule as Exit(): don't allow ReleaseHandle() to destroy + // the thread object before Thread::Exit() reaches pthread_exit(). + auto self = retain_object(this); + ReleaseHandle(); + rex::thread::Thread::Exit(exit_code); + } else { + thread_->Terminate(exit_code); + ReleaseHandle(); + } + + return X_STATUS_SUCCESS; +} + +void XThread::Execute() { + REXSYS_NOISY_DEBUG("Execute thid {} (handle={:08X}, '{}', native={:08X})", thread_id_, handle(), + thread_name_, thread_->system_id()); + + // Let the kernel know we are starting. + kernel_state_->OnThreadExecute(this); + + // Dispatch any APCs that were queued before the thread was created first. + DeliverAPCs(); + + uint32_t address; + std::vector args; + bool want_exit_code; + int exit_code = 0; + + // If a XapiThreadStartup value is present, we use that as a trampoline. + // Otherwise, we are a raw thread. + if (creation_params_.xapi_thread_startup) { + address = creation_params_.xapi_thread_startup; + args.push_back(creation_params_.start_address); + args.push_back(creation_params_.start_context); + want_exit_code = false; + } else { + // Run user code. + address = creation_params_.start_address; + args.push_back(creation_params_.start_context); + want_exit_code = true; + } + + // NOTE(tomc): JIT execution replaced with direct function calls + // In rexglue, guest code is compiled ahead of time and called directly. + // The start_address points to a 32bit guest address, for which the function + // dispatcher maintains a lookup table to retrieve the host function pointer. + auto* runtime = Runtime::instance(); + if (!runtime || !runtime->function_dispatcher()) { + REXSYS_ERROR("XThread::Execute - Runtime not initialized"); + return; + } + + auto* dispatcher = runtime->function_dispatcher(); + auto* memory = runtime->memory(); + PPCFunc* func = dispatcher->GetFunction(address); + if (!func) { + REXSYS_ERROR("XThread::Execute - No function registered at {:08X}", address); + return; + } + + auto* ctx = thread_state_->context(); + uint8_t* base = memory->virtual_membase(); + + // Pass arguments in r3, r4, ... per PPC calling convention + if (args.size() > 0) + ctx->r3.u64 = args[0]; + if (args.size() > 1) + ctx->r4.u64 = args[1]; + if (args.size() > 2) + ctx->r5.u64 = args[2]; + if (args.size() > 3) + ctx->r6.u64 = args[3]; + if (args.size() > 4) + ctx->r7.u64 = args[4]; + if (args.size() > 5) + ctx->r8.u64 = args[5]; + if (args.size() > 6) + ctx->r9.u64 = args[6]; + if (args.size() > 7) + ctx->r10.u64 = args[7]; + + ctx->fpscr.InitHost(); + + // Convert this host thread to a fiber so SwitchTo works bidirectionally. + // Required on Windows before any CreateFiber; provides the fallback handle + // when another fiber switches back to the main execution context. + main_fiber_ = rex::thread::Fiber::ConvertCurrentThread(); + + // Execute the function + REXSYS_NOISY_DEBUG("XThread::Execute - Calling function at {:08X}", address); + func(*ctx, base); + + exit_code = static_cast(ctx->r3.u32); + + // If we got here it means the execute completed without an exit being called. + // Treat the return code as an implicit exit code (if desired). + Exit(!want_exit_code ? 0 : exit_code); +} + +void XThread::EnterCriticalRegion() { + guest_object()->apc_disable_count--; +} + +void XThread::LeaveCriticalRegion() { + auto kthread = guest_object(); + auto apc_disable_count = ++kthread->apc_disable_count; + if (apc_disable_count == 0) { + // NOTE: intentionally not calling CheckApcs() here. + // Delivering APCs here can cause them to fire in wrong contexts. + } +} + +void XThread::LockApc() { + auto kthread = guest_object(); + apc_lock_old_irql_ = + kernel::xboxkrnl::xeKeKfAcquireSpinLock(thread_state_->context(), &kthread->apc_lock); +} + +void XThread::UnlockApc(bool queue_delivery) { + auto kthread = guest_object(); + auto mem = memory(); + bool needs_apc = !kthread->apc_lists[0].empty(mem) || !kthread->apc_lists[1].empty(mem); + kernel::xboxkrnl::xeKeKfReleaseSpinLock(thread_state_->context(), &kthread->apc_lock, + apc_lock_old_irql_); + if (needs_apc && queue_delivery) { + // Match Edge/Canary behavior: callback is only a wakeup hint. + // User APC execution happens on alertable wait return paths. + thread_->QueueUserCallback([]() {}); + } +} + +void XThread::EnqueueApc(uint32_t normal_routine, uint32_t normal_context, uint32_t arg1, + uint32_t arg2) { + uint32_t apc_ptr = memory()->SystemHeapAlloc(XAPC::kSize); + if (!apc_ptr) { + REXSYS_WARN("EnqueueApc: allocation failed (thid={}, normal={:08X})", thread_id_, + normal_routine); + return; + } + auto apc = memory()->TranslateVirtual(apc_ptr); + kernel::xboxkrnl::xeKeInitializeApc(apc, guest_object(), XAPC::kDummyKernelRoutine, + XAPC::kDummyRundownRoutine, normal_routine, + 1 /* user apc mode */, normal_context); + + // Important: use the caller PPC context when queuing to another thread. + // Using the target thread context here can corrupt APC lock/IRQL bookkeeping. + PPCContext* queue_ctx = + runtime::ThreadState::Get() ? runtime::current_ppc_context() : thread_state_->context(); + + if (!kernel::xboxkrnl::xeKeInsertQueueApc(apc, arg1, arg2, 0, queue_ctx)) { + memory()->SystemHeapFree(apc_ptr); + REXSYS_ERROR( + "EnqueueApc: queue rejected (thid={}, normal={:08X}, ctx={:08X}, arg1={:08X}, " + "arg2={:08X})", + thread_id_, normal_routine, normal_context, arg1, arg2); + return; + } + // Match Edge/Canary behavior: callback is only a wakeup hint. + // APCs are delivered via alertable wait handling. + thread_->QueueUserCallback([]() {}); +} + +void XThread::DeliverAPCs() { + auto mem = memory(); + auto* ctx = thread_state_->context(); + auto kthread = guest_object(); + auto* dispatcher = kernel_state_->function_dispatcher(); + + auto old_irql = kernel::xboxkrnl::xeKeKfAcquireSpinLock(ctx, &kthread->apc_lock); + auto& user_apc_queue = kthread->apc_lists[1]; + + while (!user_apc_queue.empty(mem) && kthread->apc_disable_count == 0) { + PERF_counter_inc(kApcQueueDepth); + XAPC* apc = user_apc_queue.HeadObject(mem); + uint32_t apc_ptr = mem->HostToGuestVirtual(apc); + bool needs_freeing = apc->kernel_routine != XAPC::kDummyKernelRoutine; + + util::XeRemoveEntryList(&apc->list_entry, mem); + apc->enqueued = 0; + + kernel::xboxkrnl::xeKeKfReleaseSpinLock(ctx, &kthread->apc_lock, old_irql); + + uint8_t* scratch_ptr = mem->TranslateVirtual(scratch_address_); + memory::store_and_swap(scratch_ptr + 0, apc->normal_routine); + memory::store_and_swap(scratch_ptr + 4, apc->normal_context); + memory::store_and_swap(scratch_ptr + 8, apc->arg1); + memory::store_and_swap(scratch_ptr + 12, apc->arg2); + + if (apc->kernel_routine != XAPC::kDummyKernelRoutine) { + if (dispatcher->GetFunction(apc->kernel_routine)) { + uint64_t kernel_args[] = {apc_ptr, scratch_address_ + 0, scratch_address_ + 4, + scratch_address_ + 8, scratch_address_ + 12}; + dispatcher->Execute(thread_state_.get(), apc->kernel_routine, kernel_args, + rex::countof(kernel_args)); + } else { + REXSYS_ERROR("DeliverAPCs: kernel_routine {:08X} not found", uint32_t(apc->kernel_routine)); + } + } else { + mem->SystemHeapFree(apc_ptr); + needs_freeing = false; + } + + uint32_t normal_routine = memory::load_and_swap(scratch_ptr + 0); + uint32_t normal_context = memory::load_and_swap(scratch_ptr + 4); + uint32_t arg1 = memory::load_and_swap(scratch_ptr + 8); + uint32_t arg2 = memory::load_and_swap(scratch_ptr + 12); + + if (normal_routine) { + if (dispatcher->GetFunction(normal_routine)) { + uint64_t normal_args[] = {normal_context, arg1, arg2}; + dispatcher->Execute(thread_state_.get(), normal_routine, normal_args, + rex::countof(normal_args)); + } else { + REXSYS_ERROR("DeliverAPCs: normal_routine {:08X} not found", normal_routine); + } + } + + REXSYS_DEBUG("Completed delivery of APC to {:08X} ({:08X}, {:08X}, {:08X})", normal_routine, + normal_context, arg1, arg2); + + if (needs_freeing) { + mem->SystemHeapFree(apc_ptr); + } + + old_irql = kernel::xboxkrnl::xeKeKfAcquireSpinLock(ctx, &kthread->apc_lock); + } + + kernel::xboxkrnl::xeKeKfReleaseSpinLock(ctx, &kthread->apc_lock, old_irql); +} + +void XThread::RundownAPCs() { + assert_true(XThread::GetCurrentThread() == this); + auto mem = memory(); + auto kthread = guest_object(); + auto* ctx = thread_state_->context(); + + // Rundown both user (1) and kernel (0) APC lists. + for (int mode = 1; mode >= 0; --mode) { + auto old_irql = kernel::xboxkrnl::xeKeKfAcquireSpinLock(ctx, &kthread->apc_lock); + auto& apc_queue = kthread->apc_lists[mode]; + + while (!apc_queue.empty(mem)) { + XAPC* apc = apc_queue.HeadObject(mem); + uint32_t apc_ptr = mem->HostToGuestVirtual(apc); + bool needs_freeing = apc->kernel_routine == XAPC::kDummyKernelRoutine; + + util::XeRemoveEntryList(&apc->list_entry, mem); + apc->enqueued = 0; + + kernel::xboxkrnl::xeKeKfReleaseSpinLock(ctx, &kthread->apc_lock, old_irql); + + if (apc->rundown_routine == XAPC::kDummyRundownRoutine) { + // No-op. + } else if (apc->rundown_routine) { + auto fn = kernel_state_->function_dispatcher()->GetFunction(apc->rundown_routine); + if (fn) { + auto* ctx = thread_state_->context(); + ctx->r3.u64 = apc_ptr; + fn(*ctx, mem->virtual_membase()); + } else { + REXSYS_WARN("RundownAPCs: rundown_routine {:08X} not found", + uint32_t(apc->rundown_routine)); + } + } + + if (needs_freeing) { + mem->SystemHeapFree(apc_ptr); + } + + old_irql = kernel::xboxkrnl::xeKeKfAcquireSpinLock(ctx, &kthread->apc_lock); + } + kernel::xboxkrnl::xeKeKfReleaseSpinLock(ctx, &kthread->apc_lock, old_irql); + } +} + +int32_t XThread::QueryPriority() { + return thread_->priority(); +} + +void XThread::SetPriority(int32_t increment) { + priority_ = increment; + + // Write priority to guest X_KTHREAD struct. + auto kthread = guest_object(); + kthread->priority = static_cast(std::clamp(increment, 0, 31)); + + int32_t target_priority = 0; + if (increment > 0x22) { + target_priority = rex::thread::ThreadPriority::kHighest; + } else if (increment > 0x11) { + target_priority = rex::thread::ThreadPriority::kAboveNormal; + } else if (increment < -0x22) { + target_priority = rex::thread::ThreadPriority::kLowest; + } else if (increment < -0x11) { + target_priority = rex::thread::ThreadPriority::kBelowNormal; + } else { + target_priority = rex::thread::ThreadPriority::kNormal; + } + if (!REXCVAR_GET(ignore_thread_priorities)) { + thread_->set_priority(target_priority); + } +} + +void XThread::SetAffinity(uint32_t affinity) { + SetActiveCpu(GetFakeCpuNumber(affinity)); +} + +uint8_t XThread::active_cpu() const { + // Prefer reading from guest KTHREAD (always available for guest threads, + // kept in sync by SetActiveCpu). Avoids dependency on pcr_address_ which + // may not be set yet if the thread is mid-creation. + if (is_guest_thread()) { + auto* kthread = memory()->TranslateVirtual(guest_object()); + return kthread->current_cpu; + } + if (!pcr_address_) { + return 0; + } + const X_KPCR& pcr = *memory()->TranslateVirtual(pcr_address_); + return pcr.prcb_data.current_cpu; +} + +void XThread::SetActiveCpu(uint8_t cpu_index) { + // May be called during thread creation - don't skip if current == new. + + assert_true(cpu_index < 6); + + // Write to guest KTHREAD (always available for guest threads). + if (is_guest_thread()) { + X_KTHREAD& thread_object = *memory()->TranslateVirtual(guest_object()); + thread_object.current_cpu = cpu_index; + } + + // Write to PCR if allocated (may not be during early creation). + if (pcr_address_) { + X_KPCR& pcr = *memory()->TranslateVirtual(pcr_address_); + pcr.prcb_data.current_cpu = cpu_index; + } + + if (rex::thread::logical_processor_count() >= 6) { + if (!REXCVAR_GET(ignore_thread_affinities)) { + thread_->set_affinity_mask(uint64_t(1) << cpu_index); + } + } else { + REXSYS_WARN("Too few processor cores - scheduling will be wonky"); + } +} + +bool XThread::GetTLSValue(uint32_t slot, uint32_t* value_out) { + if (slot * 4 > tls_total_size_) { + return false; + } + + auto mem = memory()->TranslateVirtual(tls_dynamic_address_ + slot * 4); + *value_out = memory::load_and_swap(mem); + return true; +} + +bool XThread::SetTLSValue(uint32_t slot, uint32_t value) { + if (slot * 4 >= tls_total_size_) { + return false; + } + + auto mem = memory()->TranslateVirtual(tls_dynamic_address_ + slot * 4); + memory::store_and_swap(mem, value); + return true; +} + +uint32_t XThread::suspend_count() { + return guest_object()->suspend_count; +} + +X_STATUS XThread::Resume(uint32_t* out_suspend_count) { + auto guest_thread = guest_object(); + uint32_t unused_host_suspend_count = 0; + +#if REX_PLATFORM_WIN32 + uint8_t previous_suspend_count = + reinterpret_cast(&guest_thread->suspend_count)->fetch_sub(1); + if (out_suspend_count) { + *out_suspend_count = previous_suspend_count; + } + return thread_->Resume(&unused_host_suspend_count) ? X_STATUS_SUCCESS : X_STATUS_UNSUCCESSFUL; +#elif REX_PLATFORM_LINUX + bool should_resume_host = false; + { + std::lock_guard lock(suspend_mutex_); + uint8_t previous = guest_thread->suspend_count; + if (previous > 0) { + guest_thread->suspend_count--; + } + if (out_suspend_count) { + *out_suspend_count = previous; + } + should_resume_host = (guest_thread->suspend_count == 0); + suspend_cv_.notify_all(); + } + + // Self-suspended threads are resumed via guest suspend count transitions. + if (should_resume_host) { + thread_->Resume(&unused_host_suspend_count); + } + return X_STATUS_SUCCESS; +#else + uint8_t previous_suspend_count = guest_thread->suspend_count; + if (guest_thread->suspend_count > 0) { + --guest_thread->suspend_count; + } + if (out_suspend_count) { + *out_suspend_count = previous_suspend_count; + } + return thread_->Resume(&unused_host_suspend_count) ? X_STATUS_SUCCESS : X_STATUS_UNSUCCESSFUL; +#endif +} + +X_STATUS XThread::Suspend(uint32_t* out_suspend_count) { + auto guest_thread = guest_object(); + uint8_t previous_suspend_count = + reinterpret_cast(&guest_thread->suspend_count)->fetch_add(1); + if (out_suspend_count) { + *out_suspend_count = previous_suspend_count; + } + + uint32_t unused_host_suspend_count = 0; + // Wrapped to 0 - treat as not suspended. + if (guest_thread->suspend_count == 0) { + return X_STATUS_SUCCESS; + } + return thread_->Suspend(&unused_host_suspend_count) ? X_STATUS_SUCCESS : X_STATUS_UNSUCCESSFUL; +} + +#if REX_PLATFORM_LINUX +uint32_t XThread::SelfSuspend() { + auto guest_thread = guest_object(); + std::unique_lock lock(suspend_mutex_); + uint32_t previous = guest_thread->suspend_count; + guest_thread->suspend_count++; + suspend_cv_.wait(lock, [guest_thread]() { return guest_thread->suspend_count == 0; }); + return previous; +} +#endif + +X_STATUS XThread::Delay(uint32_t processor_mode, uint32_t alertable, uint64_t interval) { + int64_t timeout_ticks = interval; + uint32_t timeout_ms; + if (timeout_ticks > 0) { + // Absolute time, based on January 1, 1601. + // TODO(benvanik): convert time to relative time. + assert_always(); + timeout_ms = 0; + } else if (timeout_ticks < 0) { + // Relative time. + timeout_ms = uint32_t(-timeout_ticks / 10000); // Ticks -> MS + } else { + timeout_ms = 0; + } + timeout_ms = chrono::Clock::ScaleGuestDurationMillis(timeout_ms); + if (alertable) { + auto result = rex::thread::AlertableSleep(std::chrono::milliseconds(timeout_ms)); + switch (result) { + default: + case rex::thread::SleepResult::kSuccess: + return X_STATUS_SUCCESS; + case rex::thread::SleepResult::kAlerted: + return X_STATUS_USER_APC; + } + } else { + if (timeout_ms == 0) { + if (priority_ <= rex::thread::ThreadPriority::kBelowNormal) { + rex::thread::Sleep(std::chrono::microseconds(100)); + } else { + rex::thread::MaybeYield(); + } + } else { + rex::thread::Sleep(std::chrono::milliseconds(timeout_ms)); + } + } + + return X_STATUS_SUCCESS; +} + +struct ThreadSavedState { + uint32_t thread_id; + bool is_main_thread; // Is this the main thread? + bool is_running; + + uint32_t apc_head; + uint32_t tls_static_address; + uint32_t tls_dynamic_address; + uint32_t tls_total_size; + uint32_t pcr_address; + uint32_t stack_base; // High address + uint32_t stack_limit; // Low address + uint32_t stack_alloc_base; // Allocation address + uint32_t stack_alloc_size; // Allocation size + + // Context (invalid if not running) + struct { + uint64_t lr; + uint64_t ctr; + uint64_t r[32]; + double f[32]; + vec128_t v[128]; + uint32_t cr[8]; + uint32_t fpscr; + uint8_t xer_ca; + uint8_t xer_ov; + uint8_t xer_so; + uint8_t vscr_sat; + uint32_t pc; + } context; +}; + +// Save PPCContext to ThreadSavedState +static void SaveContext(const PPCContext* ctx, ThreadSavedState& state) { + state.context.lr = ctx->lr; + state.context.ctr = ctx->ctr.u64; + + // GPRs - copy individually since PPCContext uses named registers + state.context.r[0] = ctx->r0.u64; + state.context.r[1] = ctx->r1.u64; + state.context.r[2] = ctx->r2.u64; + state.context.r[3] = ctx->r3.u64; + state.context.r[4] = ctx->r4.u64; + state.context.r[5] = ctx->r5.u64; + state.context.r[6] = ctx->r6.u64; + state.context.r[7] = ctx->r7.u64; + state.context.r[8] = ctx->r8.u64; + state.context.r[9] = ctx->r9.u64; + state.context.r[10] = ctx->r10.u64; + state.context.r[11] = ctx->r11.u64; + state.context.r[12] = ctx->r12.u64; + state.context.r[13] = ctx->r13.u64; + // r14-r31: contiguous in PPCContext and state array + std::memcpy(&state.context.r[14], &ctx->r14, 18 * sizeof(uint64_t)); + + // FPRs + state.context.f[0] = ctx->f0.f64; + state.context.f[1] = ctx->f1.f64; + state.context.f[2] = ctx->f2.f64; + state.context.f[3] = ctx->f3.f64; + state.context.f[4] = ctx->f4.f64; + state.context.f[5] = ctx->f5.f64; + state.context.f[6] = ctx->f6.f64; + state.context.f[7] = ctx->f7.f64; + state.context.f[8] = ctx->f8.f64; + state.context.f[9] = ctx->f9.f64; + state.context.f[10] = ctx->f10.f64; + state.context.f[11] = ctx->f11.f64; + state.context.f[12] = ctx->f12.f64; + state.context.f[13] = ctx->f13.f64; + // f14-f31: contiguous in PPCContext and state array + std::memcpy(&state.context.f[14], &ctx->f14, 18 * sizeof(double)); + + // VRs (v0-v127) + std::memcpy(&state.context.v[0], &ctx->v0, sizeof(vec128_t)); + std::memcpy(&state.context.v[1], &ctx->v1, sizeof(vec128_t)); + std::memcpy(&state.context.v[2], &ctx->v2, sizeof(vec128_t)); + std::memcpy(&state.context.v[3], &ctx->v3, sizeof(vec128_t)); + std::memcpy(&state.context.v[4], &ctx->v4, sizeof(vec128_t)); + std::memcpy(&state.context.v[5], &ctx->v5, sizeof(vec128_t)); + std::memcpy(&state.context.v[6], &ctx->v6, sizeof(vec128_t)); + std::memcpy(&state.context.v[7], &ctx->v7, sizeof(vec128_t)); + std::memcpy(&state.context.v[8], &ctx->v8, sizeof(vec128_t)); + std::memcpy(&state.context.v[9], &ctx->v9, sizeof(vec128_t)); + std::memcpy(&state.context.v[10], &ctx->v10, sizeof(vec128_t)); + std::memcpy(&state.context.v[11], &ctx->v11, sizeof(vec128_t)); + std::memcpy(&state.context.v[12], &ctx->v12, sizeof(vec128_t)); + std::memcpy(&state.context.v[13], &ctx->v13, sizeof(vec128_t)); + // v14-v31: contiguous in PPCContext and state array + std::memcpy(&state.context.v[14], &ctx->v14, 18 * sizeof(vec128_t)); + std::memcpy(&state.context.v[32], &ctx->v32, sizeof(vec128_t)); + std::memcpy(&state.context.v[33], &ctx->v33, sizeof(vec128_t)); + std::memcpy(&state.context.v[34], &ctx->v34, sizeof(vec128_t)); + std::memcpy(&state.context.v[35], &ctx->v35, sizeof(vec128_t)); + std::memcpy(&state.context.v[36], &ctx->v36, sizeof(vec128_t)); + std::memcpy(&state.context.v[37], &ctx->v37, sizeof(vec128_t)); + std::memcpy(&state.context.v[38], &ctx->v38, sizeof(vec128_t)); + std::memcpy(&state.context.v[39], &ctx->v39, sizeof(vec128_t)); + std::memcpy(&state.context.v[40], &ctx->v40, sizeof(vec128_t)); + std::memcpy(&state.context.v[41], &ctx->v41, sizeof(vec128_t)); + std::memcpy(&state.context.v[42], &ctx->v42, sizeof(vec128_t)); + std::memcpy(&state.context.v[43], &ctx->v43, sizeof(vec128_t)); + std::memcpy(&state.context.v[44], &ctx->v44, sizeof(vec128_t)); + std::memcpy(&state.context.v[45], &ctx->v45, sizeof(vec128_t)); + std::memcpy(&state.context.v[46], &ctx->v46, sizeof(vec128_t)); + std::memcpy(&state.context.v[47], &ctx->v47, sizeof(vec128_t)); + std::memcpy(&state.context.v[48], &ctx->v48, sizeof(vec128_t)); + std::memcpy(&state.context.v[49], &ctx->v49, sizeof(vec128_t)); + std::memcpy(&state.context.v[50], &ctx->v50, sizeof(vec128_t)); + std::memcpy(&state.context.v[51], &ctx->v51, sizeof(vec128_t)); + std::memcpy(&state.context.v[52], &ctx->v52, sizeof(vec128_t)); + std::memcpy(&state.context.v[53], &ctx->v53, sizeof(vec128_t)); + std::memcpy(&state.context.v[54], &ctx->v54, sizeof(vec128_t)); + std::memcpy(&state.context.v[55], &ctx->v55, sizeof(vec128_t)); + std::memcpy(&state.context.v[56], &ctx->v56, sizeof(vec128_t)); + std::memcpy(&state.context.v[57], &ctx->v57, sizeof(vec128_t)); + std::memcpy(&state.context.v[58], &ctx->v58, sizeof(vec128_t)); + std::memcpy(&state.context.v[59], &ctx->v59, sizeof(vec128_t)); + std::memcpy(&state.context.v[60], &ctx->v60, sizeof(vec128_t)); + std::memcpy(&state.context.v[61], &ctx->v61, sizeof(vec128_t)); + std::memcpy(&state.context.v[62], &ctx->v62, sizeof(vec128_t)); + std::memcpy(&state.context.v[63], &ctx->v63, sizeof(vec128_t)); + // v64-v127: contiguous in PPCContext and state array + std::memcpy(&state.context.v[64], &ctx->v64, 64 * sizeof(vec128_t)); + + // CR fields + state.context.cr[0] = ctx->cr0.raw(); + state.context.cr[1] = ctx->cr1.raw(); + state.context.cr[2] = ctx->cr2.raw(); + state.context.cr[3] = ctx->cr3.raw(); + state.context.cr[4] = ctx->cr4.raw(); + state.context.cr[5] = ctx->cr5.raw(); + state.context.cr[6] = ctx->cr6.raw(); + state.context.cr[7] = ctx->cr7.raw(); + + // Other state + state.context.fpscr = ctx->fpscr.csr; + state.context.xer_ca = ctx->xer.ca; + state.context.xer_ov = ctx->xer.ov; + state.context.xer_so = ctx->xer.so; + state.context.vscr_sat = ctx->vscr_sat; +} + +// Load ThreadSavedState into PPCContext +static void LoadContext(PPCContext* ctx, const ThreadSavedState& state) { + ctx->lr = state.context.lr; + ctx->ctr.u64 = state.context.ctr; + + // GPRs + ctx->r0.u64 = state.context.r[0]; + ctx->r1.u64 = state.context.r[1]; + ctx->r2.u64 = state.context.r[2]; + ctx->r3.u64 = state.context.r[3]; + ctx->r4.u64 = state.context.r[4]; + ctx->r5.u64 = state.context.r[5]; + ctx->r6.u64 = state.context.r[6]; + ctx->r7.u64 = state.context.r[7]; + ctx->r8.u64 = state.context.r[8]; + ctx->r9.u64 = state.context.r[9]; + ctx->r10.u64 = state.context.r[10]; + ctx->r11.u64 = state.context.r[11]; + ctx->r12.u64 = state.context.r[12]; + ctx->r13.u64 = state.context.r[13]; + // r14-r31: contiguous in PPCContext and state array + std::memcpy(&ctx->r14, &state.context.r[14], 18 * sizeof(uint64_t)); + + // FPRs + ctx->f0.f64 = state.context.f[0]; + ctx->f1.f64 = state.context.f[1]; + ctx->f2.f64 = state.context.f[2]; + ctx->f3.f64 = state.context.f[3]; + ctx->f4.f64 = state.context.f[4]; + ctx->f5.f64 = state.context.f[5]; + ctx->f6.f64 = state.context.f[6]; + ctx->f7.f64 = state.context.f[7]; + ctx->f8.f64 = state.context.f[8]; + ctx->f9.f64 = state.context.f[9]; + ctx->f10.f64 = state.context.f[10]; + ctx->f11.f64 = state.context.f[11]; + ctx->f12.f64 = state.context.f[12]; + ctx->f13.f64 = state.context.f[13]; + // f14-f31: contiguous in PPCContext and state array + std::memcpy(&ctx->f14, &state.context.f[14], 18 * sizeof(double)); + + // VRs (v0-v127) + std::memcpy(&ctx->v0, &state.context.v[0], sizeof(vec128_t)); + std::memcpy(&ctx->v1, &state.context.v[1], sizeof(vec128_t)); + std::memcpy(&ctx->v2, &state.context.v[2], sizeof(vec128_t)); + std::memcpy(&ctx->v3, &state.context.v[3], sizeof(vec128_t)); + std::memcpy(&ctx->v4, &state.context.v[4], sizeof(vec128_t)); + std::memcpy(&ctx->v5, &state.context.v[5], sizeof(vec128_t)); + std::memcpy(&ctx->v6, &state.context.v[6], sizeof(vec128_t)); + std::memcpy(&ctx->v7, &state.context.v[7], sizeof(vec128_t)); + std::memcpy(&ctx->v8, &state.context.v[8], sizeof(vec128_t)); + std::memcpy(&ctx->v9, &state.context.v[9], sizeof(vec128_t)); + std::memcpy(&ctx->v10, &state.context.v[10], sizeof(vec128_t)); + std::memcpy(&ctx->v11, &state.context.v[11], sizeof(vec128_t)); + std::memcpy(&ctx->v12, &state.context.v[12], sizeof(vec128_t)); + std::memcpy(&ctx->v13, &state.context.v[13], sizeof(vec128_t)); + // v14-v31: contiguous in PPCContext and state array + std::memcpy(&ctx->v14, &state.context.v[14], 18 * sizeof(vec128_t)); + std::memcpy(&ctx->v32, &state.context.v[32], sizeof(vec128_t)); + std::memcpy(&ctx->v33, &state.context.v[33], sizeof(vec128_t)); + std::memcpy(&ctx->v34, &state.context.v[34], sizeof(vec128_t)); + std::memcpy(&ctx->v35, &state.context.v[35], sizeof(vec128_t)); + std::memcpy(&ctx->v36, &state.context.v[36], sizeof(vec128_t)); + std::memcpy(&ctx->v37, &state.context.v[37], sizeof(vec128_t)); + std::memcpy(&ctx->v38, &state.context.v[38], sizeof(vec128_t)); + std::memcpy(&ctx->v39, &state.context.v[39], sizeof(vec128_t)); + std::memcpy(&ctx->v40, &state.context.v[40], sizeof(vec128_t)); + std::memcpy(&ctx->v41, &state.context.v[41], sizeof(vec128_t)); + std::memcpy(&ctx->v42, &state.context.v[42], sizeof(vec128_t)); + std::memcpy(&ctx->v43, &state.context.v[43], sizeof(vec128_t)); + std::memcpy(&ctx->v44, &state.context.v[44], sizeof(vec128_t)); + std::memcpy(&ctx->v45, &state.context.v[45], sizeof(vec128_t)); + std::memcpy(&ctx->v46, &state.context.v[46], sizeof(vec128_t)); + std::memcpy(&ctx->v47, &state.context.v[47], sizeof(vec128_t)); + std::memcpy(&ctx->v48, &state.context.v[48], sizeof(vec128_t)); + std::memcpy(&ctx->v49, &state.context.v[49], sizeof(vec128_t)); + std::memcpy(&ctx->v50, &state.context.v[50], sizeof(vec128_t)); + std::memcpy(&ctx->v51, &state.context.v[51], sizeof(vec128_t)); + std::memcpy(&ctx->v52, &state.context.v[52], sizeof(vec128_t)); + std::memcpy(&ctx->v53, &state.context.v[53], sizeof(vec128_t)); + std::memcpy(&ctx->v54, &state.context.v[54], sizeof(vec128_t)); + std::memcpy(&ctx->v55, &state.context.v[55], sizeof(vec128_t)); + std::memcpy(&ctx->v56, &state.context.v[56], sizeof(vec128_t)); + std::memcpy(&ctx->v57, &state.context.v[57], sizeof(vec128_t)); + std::memcpy(&ctx->v58, &state.context.v[58], sizeof(vec128_t)); + std::memcpy(&ctx->v59, &state.context.v[59], sizeof(vec128_t)); + std::memcpy(&ctx->v60, &state.context.v[60], sizeof(vec128_t)); + std::memcpy(&ctx->v61, &state.context.v[61], sizeof(vec128_t)); + std::memcpy(&ctx->v62, &state.context.v[62], sizeof(vec128_t)); + std::memcpy(&ctx->v63, &state.context.v[63], sizeof(vec128_t)); + // v64-v127: contiguous in PPCContext and state array + std::memcpy(&ctx->v64, &state.context.v[64], 64 * sizeof(vec128_t)); + + // CR fields + ctx->cr0.set_raw(state.context.cr[0]); + ctx->cr1.set_raw(state.context.cr[1]); + ctx->cr2.set_raw(state.context.cr[2]); + ctx->cr3.set_raw(state.context.cr[3]); + ctx->cr4.set_raw(state.context.cr[4]); + ctx->cr5.set_raw(state.context.cr[5]); + ctx->cr6.set_raw(state.context.cr[6]); + ctx->cr7.set_raw(state.context.cr[7]); + + // Other state + ctx->fpscr.csr = state.context.fpscr; + ctx->xer.ca = state.context.xer_ca; + ctx->xer.ov = state.context.xer_ov; + ctx->xer.so = state.context.xer_so; + ctx->vscr_sat = state.context.vscr_sat; +} + +bool XThread::Save(stream::ByteStream* stream) { + if (!guest_thread_) { + // Host XThreads are expected to be recreated on their own. + return false; + } + + REXSYS_DEBUG("XThread {:08X} serializing...", handle()); + + uint32_t pc = 0; + if (running_) { + // TODO(tomc): do we need rexglue-compatible thread serialization? + // ideally any previous use for this (multi-dvds) are reworked in recomp to be + // single xex + REXSYS_WARN("XThread {:08X} serialization not implemented", handle()); + return false; + } + + if (!SaveObject(stream)) { + return false; + } + + stream->Write(kThreadSaveSignature); + stream->Write(thread_name_); + + ThreadSavedState state; + state.thread_id = thread_id_; + state.is_main_thread = main_thread_; + state.is_running = running_; + state.apc_head = 0; // APCs now live in guest-memory typed lists + state.tls_static_address = tls_static_address_; + state.tls_dynamic_address = tls_dynamic_address_; + state.tls_total_size = tls_total_size_; + state.pcr_address = pcr_address_; + state.stack_base = stack_base_; + state.stack_limit = stack_limit_; + state.stack_alloc_base = stack_alloc_base_; + state.stack_alloc_size = stack_alloc_size_; + + if (running_) { + auto context = thread_state_->context(); + SaveContext(context, state); + state.context.pc = pc; + } + + stream->Write(&state, sizeof(ThreadSavedState)); + return true; +} + +object_ref XThread::Restore(KernelState* kernel_state, stream::ByteStream* stream) { + // Kind-of a hack, but we need to set the kernel state outside of the object + // constructor so it doesn't register a handle with the object table. + auto thread = new XThread(nullptr); + thread->kernel_state_ = kernel_state; + + if (!thread->RestoreObject(stream)) { + return nullptr; + } + + if (stream->Read() != kThreadSaveSignature) { + REXSYS_ERROR("Could not restore XThread - invalid magic!"); + return nullptr; + } + + REXSYS_DEBUG("XThread {:08X}", thread->handle()); + + thread->thread_name_ = stream->Read(); + + ThreadSavedState state; + stream->Read(&state, sizeof(ThreadSavedState)); + thread->thread_id_ = state.thread_id; + thread->main_thread_ = state.is_main_thread; + thread->running_ = state.is_running; + // state.apc_head is ignored - APCs live in guest-memory typed lists + thread->tls_static_address_ = state.tls_static_address; + thread->tls_dynamic_address_ = state.tls_dynamic_address; + thread->tls_total_size_ = state.tls_total_size; + thread->pcr_address_ = state.pcr_address; + thread->stack_base_ = state.stack_base; + thread->stack_limit_ = state.stack_limit; + thread->stack_alloc_base_ = state.stack_alloc_base; + thread->stack_alloc_size_ = state.stack_alloc_size; + + // Register now that we know our thread ID. + kernel_state->RegisterThread(thread); + + // Create thread state + thread->thread_state_ = std::make_unique( + thread->thread_id_, thread->stack_base_, thread->pcr_address_, kernel_state->memory()); + + if (state.is_running) { + auto context = thread->thread_state_->context(); + LoadContext(context, state); + + // Always retain when starting - the thread owns itself until exited. + thread->RetainHandle(); + + rex::thread::Thread::CreationParameters params; + params.create_suspended = true; // Not done restoring yet. + params.stack_size = 16_MiB; + thread->thread_ = rex::thread::Thread::Create(params, [thread, state]() { + // Set thread ID override. This is used by logging. + rex::thread::set_current_thread_id(thread->handle()); + runtime::ThreadState::Bind(thread->thread_state_.get()); + + // Set name immediately, if we have one. + thread->thread_->set_name(thread->name()); + + PROFILE_THREAD_ENTER(thread->name().c_str()); + + current_xthread_tls_ = thread; + + // Acquire any mutants + for (auto mutant : thread->pending_mutant_acquires_) { + uint64_t timeout = 0; + auto status = mutant->Wait(0, 0, 0, &timeout); + assert_true(status == X_STATUS_SUCCESS); + } + thread->pending_mutant_acquires_.clear(); + + // Execute user code. + thread->running_ = true; + + // TODO(tomc): do we need this? threads would need different restoration approach + // see XThread::Save + REXSYS_ERROR("Thread restore not implemented"); + (void)state; + + current_xthread_tls_ = nullptr; + + PROFILE_THREAD_EXIT(); + + // Release the self-reference to the thread. + thread->ReleaseHandle(); + }); + assert_not_null(thread->thread_); + + // NOTE(tomc): if this is kept and processor notification dispatch is implemented, + // this needs to send a signal to the processor that a thread was started + } + + return object_ref(thread); +} + +XHostThread::XHostThread(KernelState* kernel_state, uint32_t stack_size, uint32_t creation_flags, + std::function host_fn) + : XThread(kernel_state, stack_size, 0, 0, 0, creation_flags, false), host_fn_(host_fn) { + // NOTE(tomc): there was a start suspended check here before but I don't think we need it. +} + +void XHostThread::Execute() { + REXSYS_INFO("XThread::Execute thid {} (handle={:08X}, '{}', native={:08X}, )", thread_id_, + handle(), thread_name_, thread_->system_id()); + + // Let the kernel know we are starting. + kernel_state_->OnThreadExecute(this); + + int ret = host_fn_(); + + // Exit. + Exit(ret); +} + +} // namespace rex::system diff --git a/src/system/xtimer.cpp b/src/system/xtimer.cpp new file mode 100644 index 0000000..2e499a1 --- /dev/null +++ b/src/system/xtimer.cpp @@ -0,0 +1,95 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +namespace rex::system { + +XTimer::XTimer(KernelState* kernel_state) : XObject(kernel_state, kObjectType) {} + +XTimer::~XTimer() = default; + +void XTimer::Initialize(uint32_t timer_type) { + assert_false(timer_); + switch (timer_type) { + case 0: // NotificationTimer + timer_ = rex::thread::Timer::CreateManualResetTimer(); + break; + case 1: // SynchronizationTimer + timer_ = rex::thread::Timer::CreateSynchronizationTimer(); + break; + default: + assert_always(); + break; + } + assert_not_null(timer_); +} + +X_STATUS XTimer::SetTimer(int64_t due_time, uint32_t period_ms, uint32_t routine, + uint32_t routine_arg, bool resume) { + using rex::chrono::WinSystemClock; + using rex::chrono::XSystemClock; + // Caller is checking for STATUS_TIMER_RESUME_IGNORED. + if (resume) { + return X_STATUS_TIMER_RESUME_IGNORED; + } + + period_ms = chrono::Clock::ScaleGuestDurationMillis(period_ms); + WinSystemClock::time_point due_tp; + if (due_time < 0) { + // Any timer implementation uses absolute times eventually, convert as early + // as possible for increased accuracy + auto after = rex::chrono::hundrednanoseconds(-due_time); + due_tp = std::chrono::clock_cast(XSystemClock::now() + after); + } else { + due_tp = std::chrono::clock_cast(XSystemClock::from_file_time(due_time)); + } + + // Stash routine for callback. + callback_thread_ = XThread::GetCurrentThread(); + callback_routine_ = routine; + callback_routine_arg_ = routine_arg; + + // This callback will only be issued when the timer is fired. + std::function callback = nullptr; + if (callback_routine_) { + callback = [this]() { + // Queue APC to call back routine with (arg, low, high). + // It'll be executed on the thread that requested the timer. + uint64_t time = rex::chrono::Clock::QueryGuestSystemTime(); + uint32_t time_low = static_cast(time); + uint32_t time_high = static_cast(time >> 32); + REXSYS_INFO("XTimer enqueuing timer callback to {:08X}({:08X}, {:08X}, {:08X})", + callback_routine_, callback_routine_arg_, time_low, time_high); + callback_thread_->EnqueueApc(callback_routine_, callback_routine_arg_, time_low, time_high); + }; + } + + bool result; + if (!period_ms) { + result = timer_->SetOnceAt(due_tp, std::move(callback)); + } else { + result = + timer_->SetRepeatingAt(due_tp, std::chrono::milliseconds(period_ms), std::move(callback)); + } + + return result ? X_STATUS_SUCCESS : X_STATUS_UNSUCCESSFUL; +} + +X_STATUS XTimer::Cancel() { + return timer_->Cancel() ? X_STATUS_SUCCESS : X_STATUS_UNSUCCESSFUL; +} + +} // namespace rex::system diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt new file mode 100644 index 0000000..18ad4ad --- /dev/null +++ b/src/ui/CMakeLists.txt @@ -0,0 +1,163 @@ +# rexui + +# Core UI sources +set(REXUI_CORE_SOURCES + graphics_upload_buffer_pool.cpp + graphics_util.cpp + imgui_dialog.cpp + imgui_drawer.cpp + immediate_drawer.cpp + keybinds.cpp + menu_item.cpp + presenter.cpp + renderdoc_api.cpp + window.cpp + windowed_app.cpp + windowed_app_context.cpp +) + +# Optional overlay dialogs +set(REXUI_OVERLAY_SOURCES + overlay/debug_overlay.cpp + overlay/console_overlay.cpp + overlay/settings_overlay.cpp +) + +# Vulkan UI backend +set(REXUI_VULKAN_SOURCES + vulkan/linked_type_descriptor_set_allocator.cpp + vulkan/single_layout_descriptor_set_pool.cpp + vulkan/spirv_tools_context.cpp + vulkan/ui_samplers.cpp + vulkan/vulkan_device.cpp + vulkan/vulkan_immediate_drawer.cpp + vulkan/vulkan_instance.cpp + vulkan/vulkan_mem_alloc.cpp + vulkan/vulkan_presenter.cpp + vulkan/vulkan_provider.cpp + vulkan/vulkan_submission_tracker.cpp + vulkan/vulkan_upload_buffer_pool.cpp + vulkan/vulkan_util.cpp +) + +# D3D12 UI backend +if(REXGLUE_USE_D3D12) + set(REXUI_D3D12_SOURCES + d3d12/d3d12_cpu_descriptor_pool.cpp + d3d12/d3d12_descriptor_heap_pool.cpp + d3d12/d3d12_immediate_drawer.cpp + d3d12/d3d12_presenter.cpp + d3d12/d3d12_provider.cpp + d3d12/d3d12_submission_tracker.cpp + d3d12/d3d12_upload_buffer_pool.cpp + d3d12/d3d12_util.cpp + ) +endif() + +# Platform-specific sources +if(WIN32) + set(REXUI_PLATFORM_SOURCES + surface_win.cpp + window_win.cpp + windowed_app_context_win.cpp + ) +else() + set(REXUI_PLATFORM_SOURCES + surface_gnulinux.cpp + window_gtk.cpp + windowed_app_context_gtk.cpp + ) +endif() + +# Combine sources +set(REXUI_SOURCES + ${REXUI_CORE_SOURCES} + ${REXUI_OVERLAY_SOURCES} + ${REXUI_PLATFORM_SOURCES} +) + +if(REXGLUE_USE_VULKAN) + list(APPEND REXUI_SOURCES ${REXUI_VULKAN_SOURCES}) +endif() + +if(REXGLUE_USE_D3D12) + list(APPEND REXUI_SOURCES ${REXUI_D3D12_SOURCES}) +endif() + +add_library(rexui OBJECT ${REXUI_SOURCES}) +add_library(rex::ui ALIAS rexui) + +target_include_directories(rexui PUBLIC + $ + $ +) +target_include_directories(rexui PRIVATE + ${REXGLUE_ROOT}/src # For ui/shaders/bytecode includes +) + +target_link_libraries(rexui PUBLIC + rexcore + renderdoc + imgui::imgui +) + +if(REXGLUE_FIDELITYFX_SOURCE_DIR AND EXISTS "${REXGLUE_FIDELITYFX_SOURCE_DIR}/sdk/include") + target_include_directories(rexui PRIVATE + "${REXGLUE_FIDELITYFX_SOURCE_DIR}/sdk/include" + "${REXGLUE_FIDELITYFX_SOURCE_DIR}/ffx-api/include" + ) + target_compile_definitions(rexui PRIVATE REX_HAS_FIDELITYFX_SDK=1) +endif() + +set(REXUI_HAS_FIDELITYFX_RUNTIME OFF) +if(TARGET amd_fidelityfx_vk) + target_link_libraries(rexui PRIVATE amd_fidelityfx_vk) + set(REXUI_HAS_FIDELITYFX_RUNTIME ON) +endif() +if(TARGET amd_fidelityfx_dx12) + target_link_libraries(rexui PRIVATE amd_fidelityfx_dx12) + set(REXUI_HAS_FIDELITYFX_RUNTIME ON) +endif() +if(REXUI_HAS_FIDELITYFX_RUNTIME) + target_compile_definitions(rexui PRIVATE REX_HAS_FIDELITYFX_RUNTIME=1) +endif() + +if(REXGLUE_USE_VULKAN) + target_link_libraries(rexui PUBLIC + volk::volk + GPUOpen::VulkanMemoryAllocator + SPIRV-Tools-static + ) +endif() + +# Platform-specific dependencies +if(WIN32) + target_link_libraries(rexui PUBLIC + dwmapi + Shcore + ) +else() + find_package(PkgConfig REQUIRED) + pkg_check_modules(GTK3 REQUIRED gtk+-3.0) + pkg_check_modules(X11_XCB REQUIRED x11-xcb) + + target_include_directories(rexui PRIVATE + ${GTK3_INCLUDE_DIRS} + ${X11_XCB_INCLUDE_DIRS} + ) + target_link_libraries(rexui PUBLIC + ${GTK3_LIBRARIES} + ${X11_XCB_LIBRARIES} + ) +endif() + +# D3D12 backend dependencies +if(REXGLUE_USE_D3D12) + target_link_libraries(rexui PUBLIC + dxgi + dxguid + dxc-headers + ) +endif() + + diff --git a/src/ui/d3d12/d3d12_cpu_descriptor_pool.cpp b/src/ui/d3d12/d3d12_cpu_descriptor_pool.cpp new file mode 100644 index 0000000..d427c98 --- /dev/null +++ b/src/ui/d3d12/d3d12_cpu_descriptor_pool.cpp @@ -0,0 +1,49 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include + +namespace rex::ui::d3d12 { + +D3D12CpuDescriptorPool::Descriptor D3D12CpuDescriptorPool::AllocateDescriptor() { + if (!freed_indices_.empty()) { + size_t index = freed_indices_.back(); + freed_indices_.pop_back(); + return Descriptor(shared_from_this(), index); + } + uint32_t heap_size = uint32_t(1) << heap_size_log2_; + if (!heaps_.empty() && last_heap_allocated_ < heap_size) { + return Descriptor(shared_from_this(), (heaps_.size() - 1) * heap_size + last_heap_allocated_++); + } + D3D12_DESCRIPTOR_HEAP_DESC descriptor_heap_desc; + descriptor_heap_desc.Type = type_; + descriptor_heap_desc.NumDescriptors = heap_size; + descriptor_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + descriptor_heap_desc.NodeMask = 0; + ID3D12DescriptorHeap* descriptor_heap; + if (FAILED(provider_.GetDevice()->CreateDescriptorHeap(&descriptor_heap_desc, + IID_PPV_ARGS(&descriptor_heap)))) { + REXLOG_ERROR( + "Failed to create a non-shader-visible descriptor heap for {} " + "descriptors", + heap_size); + return Descriptor(); + } + heaps_.push_back(descriptor_heap); + last_heap_allocated_ = 1; + return Descriptor(shared_from_this(), (heaps_.size() - 1) * heap_size); +} + +} // namespace rex::ui::d3d12 diff --git a/src/ui/d3d12/d3d12_descriptor_heap_pool.cpp b/src/ui/d3d12/d3d12_descriptor_heap_pool.cpp new file mode 100644 index 0000000..650f1d1 --- /dev/null +++ b/src/ui/d3d12/d3d12_descriptor_heap_pool.cpp @@ -0,0 +1,145 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +namespace rex::ui::d3d12 { + +D3D12DescriptorHeapPool::D3D12DescriptorHeapPool(ID3D12Device* device, + D3D12_DESCRIPTOR_HEAP_TYPE type, + uint32_t page_size) + : device_(device), type_(type), page_size_(page_size) {} + +D3D12DescriptorHeapPool::~D3D12DescriptorHeapPool() { + ClearCache(); +} + +void D3D12DescriptorHeapPool::Reclaim(uint64_t completed_submission_index) { + while (submitted_first_) { + if (submitted_first_->last_submission_index > completed_submission_index) { + break; + } + if (writable_last_) { + writable_last_->next = submitted_first_; + } else { + writable_first_ = submitted_first_; + } + writable_last_ = submitted_first_; + submitted_first_ = submitted_first_->next; + writable_last_->next = nullptr; + } + if (!submitted_first_) { + submitted_last_ = nullptr; + } +} + +void D3D12DescriptorHeapPool::ChangeSubmissionTimeline() { + // Reclaim all submitted pages. + if (writable_last_) { + writable_last_->next = submitted_first_; + } else { + writable_first_ = submitted_first_; + } + writable_last_ = submitted_last_; + submitted_first_ = nullptr; + submitted_last_ = nullptr; + + // Mark all pages as never used yet in the new timeline. + Page* page = writable_first_; + while (page) { + page->last_submission_index = 0; + page = page->next; + } +} + +void D3D12DescriptorHeapPool::ClearCache() { + // Not checking current_page_used_ != 0 because asking for 0 descriptors + // returns a valid heap also - but actually the new heap will be different now + // and the old one must be unbound since it doesn't exist anymore. + ++current_heap_index_; + current_page_used_ = 0; + while (submitted_first_) { + auto next = submitted_first_->next; + delete submitted_first_; + submitted_first_ = next; + } + submitted_last_ = nullptr; + while (writable_first_) { + auto next = writable_first_->next; + delete writable_first_; + writable_first_ = next; + } + writable_last_ = nullptr; +} + +uint64_t D3D12DescriptorHeapPool::Request(uint64_t submission_index, uint64_t previous_heap_index, + uint32_t count_for_partial_update, + uint32_t count_for_full_update, uint32_t& index_out) { + assert_true(count_for_partial_update <= count_for_full_update); + assert_true(count_for_full_update <= page_size_); + if (count_for_partial_update > count_for_full_update || count_for_full_update > page_size_) { + return kHeapIndexInvalid; + } + assert_true(!current_page_used_ || submission_index >= writable_first_->last_submission_index); + assert_true(!submitted_last_ || submission_index >= submitted_last_->last_submission_index); + // If the last full update happened on the current page, a partial update is + // possible. + uint32_t count = + previous_heap_index == current_heap_index_ ? count_for_partial_update : count_for_full_update; + // Go to the next page if there's not enough free space on the current one, + // or because the previous page may be outdated. In this case, a full update + // is necessary. + if (page_size_ - current_page_used_ < count) { + // Close the page that was current. + if (submitted_last_) { + submitted_last_->next = writable_first_; + } else { + submitted_first_ = writable_first_; + } + submitted_last_ = writable_first_; + writable_first_ = writable_first_->next; + submitted_last_->next = nullptr; + if (!writable_first_) { + writable_last_ = nullptr; + } + ++current_heap_index_; + current_page_used_ = 0; + count = count_for_full_update; + } + // Create the page if needed (may be the first call for the page). + if (!writable_first_) { + D3D12_DESCRIPTOR_HEAP_DESC new_heap_desc; + new_heap_desc.Type = type_; + new_heap_desc.NumDescriptors = page_size_; + new_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + new_heap_desc.NodeMask = 0; + Microsoft::WRL::ComPtr new_heap; + if (FAILED(device_->CreateDescriptorHeap(&new_heap_desc, IID_PPV_ARGS(&new_heap)))) { + REXLOG_ERROR("Failed to create a heap for {} shader-visible descriptors", page_size_); + return kHeapIndexInvalid; + } + writable_first_ = new Page; + writable_first_->heap = new_heap; + writable_first_->cpu_start = new_heap->GetCPUDescriptorHandleForHeapStart(); + writable_first_->gpu_start = new_heap->GetGPUDescriptorHandleForHeapStart(); + writable_first_->last_submission_index = submission_index; + writable_first_->next = nullptr; + writable_last_ = writable_first_; + } + writable_first_->last_submission_index = submission_index; + index_out = current_page_used_; + current_page_used_ += count; + return current_heap_index_; +} + +} // namespace rex::ui::d3d12 diff --git a/src/ui/d3d12/d3d12_immediate_drawer.cpp b/src/ui/d3d12/d3d12_immediate_drawer.cpp new file mode 100644 index 0000000..ce654c8 --- /dev/null +++ b/src/ui/d3d12/d3d12_immediate_drawer.cpp @@ -0,0 +1,655 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace rex::ui::d3d12 { + +// Generated with `xb buildshaders`. +namespace shaders { +#include "../shaders/bytecode/d3d12_5_1/immediate_ps.h" +#include "../shaders/bytecode/d3d12_5_1/immediate_vs.h" +} // namespace shaders + +D3D12ImmediateDrawer::D3D12ImmediateTexture::D3D12ImmediateTexture( + uint32_t width, uint32_t height, ID3D12Resource* resource, SamplerIndex sampler_index, + D3D12ImmediateDrawer* immediate_drawer, size_t immediate_drawer_index) + : ImmediateTexture(width, height), + resource_(resource), + sampler_index_(sampler_index), + immediate_drawer_(immediate_drawer), + immediate_drawer_index_(immediate_drawer_index) {} + +D3D12ImmediateDrawer::D3D12ImmediateTexture::~D3D12ImmediateTexture() { + if (immediate_drawer_) { + immediate_drawer_->OnImmediateTextureDestroyed(*this); + } +} + +void D3D12ImmediateDrawer::D3D12ImmediateTexture::OnImmediateDrawerDestroyed() { + immediate_drawer_ = nullptr; + // Lifetime is not managed anymore, so don't keep the resource either. + resource_.Reset(); +} + +D3D12ImmediateDrawer::~D3D12ImmediateDrawer() { + // Await GPU usage completion of all draws and texture uploads (which happen + // before draws). + auto d3d12_presenter = static_cast(presenter()); + if (d3d12_presenter) { + d3d12_presenter->AwaitUISubmissionCompletionFromUIThread(last_paint_submission_index_); + } + + // Texture resources and descriptors are owned and tracked by the immediate + // drawer. Zombie texture objects are supported, but are meaningless. + assert_true(textures_.empty()); + for (D3D12ImmediateTexture* texture : textures_) { + texture->OnImmediateDrawerDestroyed(); + } + textures_.clear(); +} + +bool D3D12ImmediateDrawer::Initialize() { + ID3D12Device* device = provider_.GetDevice(); + + // Create the root signature. + D3D12_ROOT_PARAMETER root_parameters[size_t(RootParameter::kCount)]; + D3D12_DESCRIPTOR_RANGE descriptor_range_texture, descriptor_range_sampler; + { + auto& root_parameter = root_parameters[size_t(RootParameter::kTexture)]; + root_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + root_parameter.DescriptorTable.NumDescriptorRanges = 1; + root_parameter.DescriptorTable.pDescriptorRanges = &descriptor_range_texture; + descriptor_range_texture.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + descriptor_range_texture.NumDescriptors = 1; + descriptor_range_texture.BaseShaderRegister = 0; + descriptor_range_texture.RegisterSpace = 0; + descriptor_range_texture.OffsetInDescriptorsFromTableStart = 0; + root_parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + } + { + auto& root_parameter = root_parameters[size_t(RootParameter::kSampler)]; + root_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + root_parameter.DescriptorTable.NumDescriptorRanges = 1; + root_parameter.DescriptorTable.pDescriptorRanges = &descriptor_range_sampler; + descriptor_range_sampler.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + descriptor_range_sampler.NumDescriptors = 1; + descriptor_range_sampler.BaseShaderRegister = 0; + descriptor_range_sampler.RegisterSpace = 0; + descriptor_range_sampler.OffsetInDescriptorsFromTableStart = 0; + root_parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + } + { + auto& root_parameter = root_parameters[size_t(RootParameter::kCoordinateSpaceSizeInv)]; + root_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + root_parameter.Constants.ShaderRegister = 0; + root_parameter.Constants.RegisterSpace = 0; + root_parameter.Constants.Num32BitValues = 2; + root_parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX; + } + D3D12_ROOT_SIGNATURE_DESC root_signature_desc; + root_signature_desc.NumParameters = UINT(RootParameter::kCount); + root_signature_desc.pParameters = root_parameters; + root_signature_desc.NumStaticSamplers = 0; + root_signature_desc.pStaticSamplers = nullptr; + root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + *(root_signature_.ReleaseAndGetAddressOf()) = + util::CreateRootSignature(provider_, root_signature_desc); + if (!root_signature_) { + REXLOG_ERROR("D3D12ImmediateDrawer: Failed to create the root signature"); + return false; + } + + // Create the pipelines. + D3D12_GRAPHICS_PIPELINE_STATE_DESC pipeline_desc = {}; + pipeline_desc.pRootSignature = root_signature_.Get(); + pipeline_desc.VS.pShaderBytecode = shaders::immediate_vs; + pipeline_desc.VS.BytecodeLength = sizeof(shaders::immediate_vs); + pipeline_desc.PS.pShaderBytecode = shaders::immediate_ps; + pipeline_desc.PS.BytecodeLength = sizeof(shaders::immediate_ps); + D3D12_RENDER_TARGET_BLEND_DESC& pipeline_blend_desc = pipeline_desc.BlendState.RenderTarget[0]; + pipeline_blend_desc.BlendEnable = TRUE; + pipeline_blend_desc.SrcBlend = D3D12_BLEND_SRC_ALPHA; + pipeline_blend_desc.DestBlend = D3D12_BLEND_INV_SRC_ALPHA; + pipeline_blend_desc.BlendOp = D3D12_BLEND_OP_ADD; + pipeline_blend_desc.SrcBlendAlpha = D3D12_BLEND_ONE; + pipeline_blend_desc.DestBlendAlpha = D3D12_BLEND_ONE; + pipeline_blend_desc.BlendOpAlpha = D3D12_BLEND_OP_ADD; + pipeline_blend_desc.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + pipeline_desc.SampleMask = UINT_MAX; + pipeline_desc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; + pipeline_desc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; + pipeline_desc.RasterizerState.FrontCounterClockwise = FALSE; + pipeline_desc.RasterizerState.DepthClipEnable = TRUE; + D3D12_INPUT_ELEMENT_DESC pipeline_input_elements[3] = {}; + pipeline_input_elements[0].SemanticName = "POSITION"; + pipeline_input_elements[0].Format = DXGI_FORMAT_R32G32_FLOAT; + pipeline_input_elements[0].AlignedByteOffset = offsetof(ImmediateVertex, x); + pipeline_input_elements[1].SemanticName = "TEXCOORD"; + pipeline_input_elements[1].Format = DXGI_FORMAT_R32G32_FLOAT; + pipeline_input_elements[1].AlignedByteOffset = offsetof(ImmediateVertex, u); + pipeline_input_elements[2].SemanticName = "COLOR"; + pipeline_input_elements[2].Format = DXGI_FORMAT_R8G8B8A8_UNORM; + pipeline_input_elements[2].AlignedByteOffset = offsetof(ImmediateVertex, color); + pipeline_desc.InputLayout.pInputElementDescs = pipeline_input_elements; + pipeline_desc.InputLayout.NumElements = UINT(rex::countof(pipeline_input_elements)); + pipeline_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + pipeline_desc.NumRenderTargets = 1; + pipeline_desc.RTVFormats[0] = D3D12Presenter::kSwapChainFormat; + pipeline_desc.SampleDesc.Count = 1; + if (FAILED( + device->CreateGraphicsPipelineState(&pipeline_desc, IID_PPV_ARGS(&pipeline_triangle_)))) { + REXLOG_ERROR("D3D12ImmediateDrawer: Failed to create the triangle pipeline"); + return false; + } + pipeline_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE; + if (FAILED(device->CreateGraphicsPipelineState(&pipeline_desc, IID_PPV_ARGS(&pipeline_line_)))) { + REXLOG_ERROR("D3D12ImmediateDrawer: Failed to create the line pipeline"); + return false; + } + + // Create the samplers. + D3D12_DESCRIPTOR_HEAP_DESC sampler_heap_desc; + sampler_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; + sampler_heap_desc.NumDescriptors = UINT(SamplerIndex::kCount); + sampler_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + sampler_heap_desc.NodeMask = 0; + if (FAILED(device->CreateDescriptorHeap(&sampler_heap_desc, IID_PPV_ARGS(&sampler_heap_)))) { + REXLOG_ERROR("D3D12ImmediateDrawer: Failed to create the sampler descriptor heap"); + return false; + } + sampler_heap_cpu_start_ = sampler_heap_->GetCPUDescriptorHandleForHeapStart(); + sampler_heap_gpu_start_ = sampler_heap_->GetGPUDescriptorHandleForHeapStart(); + uint32_t sampler_size = provider_.GetSamplerDescriptorSize(); + // Nearest neighbor, clamp. + D3D12_SAMPLER_DESC sampler_desc = {}; + sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; + sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + sampler_desc.MaxAnisotropy = 1; + D3D12_CPU_DESCRIPTOR_HANDLE sampler_handle; + sampler_handle.ptr = + sampler_heap_cpu_start_.ptr + uint32_t(SamplerIndex::kNearestClamp) * sampler_size; + device->CreateSampler(&sampler_desc, sampler_handle); + // Bilinear, clamp. + sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; + sampler_handle.ptr = + sampler_heap_cpu_start_.ptr + uint32_t(SamplerIndex::kLinearClamp) * sampler_size; + device->CreateSampler(&sampler_desc, sampler_handle); + // Bilinear, repeat. + sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + sampler_handle.ptr = + sampler_heap_cpu_start_.ptr + uint32_t(SamplerIndex::kLinearRepeat) * sampler_size; + device->CreateSampler(&sampler_desc, sampler_handle); + // Nearest neighbor, repeat. + sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; + sampler_handle.ptr = + sampler_heap_cpu_start_.ptr + uint32_t(SamplerIndex::kNearestRepeat) * sampler_size; + device->CreateSampler(&sampler_desc, sampler_handle); + + // Create pools for draws. + vertex_buffer_pool_ = std::make_unique(provider_); + texture_descriptor_pool_ = std::make_unique( + device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 2048); + + // Reset the current state. + batch_open_ = false; + + return true; +} + +std::unique_ptr D3D12ImmediateDrawer::CreateTexture(uint32_t width, + uint32_t height, + ImmediateTextureFilter filter, + bool is_repeated, + const uint8_t* data) { + ID3D12Device* device = provider_.GetDevice(); + D3D12_HEAP_FLAGS heap_flag_create_not_zeroed = provider_.GetHeapFlagCreateNotZeroed(); + + D3D12_RESOURCE_DESC resource_desc; + resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + resource_desc.Alignment = 0; + resource_desc.Width = width; + resource_desc.Height = height; + resource_desc.DepthOrArraySize = 1; + resource_desc.MipLevels = 1; + resource_desc.Format = D3D12ImmediateTexture::kFormat; + resource_desc.SampleDesc.Count = 1; + resource_desc.SampleDesc.Quality = 0; + resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + resource_desc.Flags = D3D12_RESOURCE_FLAG_NONE; + Microsoft::WRL::ComPtr resource; + if (SUCCEEDED(device->CreateCommittedResource( + &util::kHeapPropertiesDefault, heap_flag_create_not_zeroed, &resource_desc, + D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&resource)))) { + // Create and fill the upload buffer. + D3D12_PLACED_SUBRESOURCE_FOOTPRINT upload_footprint; + UINT64 upload_size; + device->GetCopyableFootprints(&resource_desc, 0, 1, 0, &upload_footprint, nullptr, nullptr, + &upload_size); + D3D12_RESOURCE_DESC upload_buffer_desc; + util::FillBufferResourceDesc(upload_buffer_desc, upload_size, D3D12_RESOURCE_FLAG_NONE); + Microsoft::WRL::ComPtr upload_buffer; + if (SUCCEEDED(device->CreateCommittedResource( + &util::kHeapPropertiesUpload, heap_flag_create_not_zeroed, &upload_buffer_desc, + D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&upload_buffer)))) { + D3D12_RANGE upload_buffer_read_range; + upload_buffer_read_range.Begin = 0; + upload_buffer_read_range.End = 0; + void* upload_buffer_mapping; + if (SUCCEEDED(upload_buffer->Map(0, &upload_buffer_read_range, &upload_buffer_mapping))) { + size_t data_row_length = sizeof(uint32_t) * width; + if (data_row_length == upload_footprint.Footprint.RowPitch) { + std::memcpy(upload_buffer_mapping, data, data_row_length * height); + } else { + uint8_t* upload_buffer_row = + reinterpret_cast(upload_buffer_mapping) + upload_footprint.Offset; + const uint8_t* data_row = data; + for (uint32_t i = 0; i < height; ++i) { + std::memcpy(upload_buffer_row, data_row, data_row_length); + data_row += data_row_length; + upload_buffer_row += upload_footprint.Footprint.RowPitch; + } + } + upload_buffer->Unmap(0, nullptr); + // Defer uploading and transition to the next draw. + // While the upload has not been yet completed, keep a reference to the + // resource because its lifetime is not tied to that of the + // ImmediateTexture (and thus to context's submissions) now. + PendingTextureUpload& pending_upload = + texture_uploads_pending_.emplace_back(resource.Get(), upload_buffer.Get()); + } else { + REXLOG_ERROR( + "D3D12ImmediateDrawer: Failed to map an upload buffer for a {}x{} " + "texture", + width, height); + upload_buffer.Reset(); + resource.Reset(); + } + } else { + REXLOG_ERROR( + "D3D12ImmediateDrawer: Failed to create an upload buffer for a {}x{} " + "texture", + width, height); + resource.Reset(); + } + } else { + REXLOG_ERROR("D3D12ImmediateDrawer: Failed to create a {}x{} texture", width, height); + } + + SamplerIndex sampler_index; + if (filter == ImmediateTextureFilter::kLinear) { + sampler_index = is_repeated ? SamplerIndex::kLinearRepeat : SamplerIndex::kLinearClamp; + } else { + sampler_index = is_repeated ? SamplerIndex::kNearestRepeat : SamplerIndex::kNearestClamp; + } + + // Manage by this immediate drawer if successfully created a resource. + std::unique_ptr texture = std::make_unique( + width, height, resource.Get(), sampler_index, resource ? this : nullptr, textures_.size()); + if (resource) { + textures_.push_back(texture.get()); + } + return std::move(texture); +} + +void D3D12ImmediateDrawer::Begin(UIDrawContext& ui_draw_context, float coordinate_space_width, + float coordinate_space_height) { + ImmediateDrawer::Begin(ui_draw_context, coordinate_space_width, coordinate_space_height); + + assert_false(batch_open_); + + const D3D12UIDrawContext& d3d12_ui_draw_context = + static_cast(ui_draw_context); + + // Update the submission index to be used throughout the current immediate + // drawer paint. + last_paint_submission_index_ = d3d12_ui_draw_context.submission_index_current(); + last_completed_submission_index_ = d3d12_ui_draw_context.submission_index_completed(); + + // Release deleted textures. + for (auto it = textures_deleted_.begin(); it != textures_deleted_.end();) { + if (it->second > last_completed_submission_index_) { + ++it; + continue; + } + if (std::next(it) != textures_deleted_.end()) { + *it = textures_deleted_.back(); + } + textures_deleted_.pop_back(); + } + + // Release upload buffers for completed texture uploads. + auto erase_uploads_end = texture_uploads_submitted_.begin(); + while (erase_uploads_end != texture_uploads_submitted_.end()) { + if (erase_uploads_end->submission_index > last_completed_submission_index_) { + break; + } + ++erase_uploads_end; + } + texture_uploads_submitted_.erase(texture_uploads_submitted_.begin(), erase_uploads_end); + + // Make sure textures created before the current frame are uploaded, even if + // nothing was drawn in the previous frames or nothing will be drawn in the + // current or subsequent ones, as that would result in upload buffers kept + // forever. + UploadTextures(); + + texture_descriptor_pool_->Reclaim(last_completed_submission_index_); + vertex_buffer_pool_->Reclaim(last_completed_submission_index_); + + // Begin drawing. + + ID3D12GraphicsCommandList* command_list = d3d12_ui_draw_context.command_list(); + + D3D12_VIEWPORT viewport; + viewport.TopLeftX = 0.0f; + viewport.TopLeftY = 0.0f; + viewport.Width = float(d3d12_ui_draw_context.render_target_width()); + viewport.Height = float(d3d12_ui_draw_context.render_target_height()); + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + command_list->RSSetViewports(1, &viewport); + + command_list->SetGraphicsRootSignature(root_signature_.Get()); + float coordinate_space_size_inv[2]; + coordinate_space_size_inv[0] = 1.0f / coordinate_space_width; + coordinate_space_size_inv[1] = 1.0f / coordinate_space_height; + command_list->SetGraphicsRoot32BitConstants(UINT(RootParameter::kCoordinateSpaceSizeInv), 2, + coordinate_space_size_inv, 0); + + current_scissor_.left = 0; + current_scissor_.top = 0; + current_scissor_.right = 0; + current_scissor_.bottom = 0; + + current_primitive_topology_ = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; + current_texture_ = nullptr; + current_texture_descriptor_heap_index_ = D3D12DescriptorHeapPool::kHeapIndexInvalid; + current_sampler_index_ = SamplerIndex::kInvalid; +} + +void D3D12ImmediateDrawer::BeginDrawBatch(const ImmediateDrawBatch& batch) { + assert_false(batch_open_); + + const D3D12UIDrawContext& d3d12_ui_draw_context = + *static_cast(ui_draw_context()); + + ID3D12GraphicsCommandList* command_list = d3d12_ui_draw_context.command_list(); + + // Bind the vertices. + D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view; + vertex_buffer_view.StrideInBytes = UINT(sizeof(ImmediateVertex)); + vertex_buffer_view.SizeInBytes = UINT(sizeof(ImmediateVertex)) * batch.vertex_count; + void* vertex_buffer_mapping = vertex_buffer_pool_->Request( + last_paint_submission_index_, vertex_buffer_view.SizeInBytes, sizeof(float), nullptr, nullptr, + &vertex_buffer_view.BufferLocation); + if (vertex_buffer_mapping == nullptr) { + REXLOG_ERROR("D3D12ImmediateDrawer: Failed to get a buffer for {} vertices", + batch.vertex_count); + return; + } + std::memcpy(vertex_buffer_mapping, batch.vertices, vertex_buffer_view.SizeInBytes); + command_list->IASetVertexBuffers(0, 1, &vertex_buffer_view); + + // Bind the indices. + batch_has_index_buffer_ = batch.indices != nullptr; + if (batch_has_index_buffer_) { + D3D12_INDEX_BUFFER_VIEW index_buffer_view; + index_buffer_view.SizeInBytes = UINT(sizeof(uint16_t)) * batch.index_count; + index_buffer_view.Format = DXGI_FORMAT_R16_UINT; + void* index_buffer_mapping = vertex_buffer_pool_->Request( + last_paint_submission_index_, index_buffer_view.SizeInBytes, sizeof(uint16_t), nullptr, + nullptr, &index_buffer_view.BufferLocation); + if (index_buffer_mapping == nullptr) { + REXLOG_ERROR("D3D12ImmediateDrawer: Failed to get a buffer for {} indices", + batch.index_count); + return; + } + std::memcpy(index_buffer_mapping, batch.indices, index_buffer_view.SizeInBytes); + command_list->IASetIndexBuffer(&index_buffer_view); + } + + batch_open_ = true; +} + +void D3D12ImmediateDrawer::Draw(const ImmediateDraw& draw) { + if (!batch_open_) { + // Could be an error while obtaining the vertex and index buffers. + return; + } + + const D3D12UIDrawContext& d3d12_ui_draw_context = + *static_cast(ui_draw_context()); + ID3D12GraphicsCommandList* command_list = d3d12_ui_draw_context.command_list(); + + // Set the scissor rectangle. + uint32_t scissor_left, scissor_top, scissor_width, scissor_height; + if (!ScissorToRenderTarget(draw, scissor_left, scissor_top, scissor_width, scissor_height)) { + // Nothing is visible (zero area is used as the default current_scissor_ + // value also). + return; + } + D3D12_RECT scissor; + scissor.left = LONG(scissor_left); + scissor.top = LONG(scissor_top); + scissor.right = LONG(scissor_left + scissor_width); + scissor.bottom = LONG(scissor_top + scissor_height); + if (current_scissor_.left != scissor.left || current_scissor_.top != scissor.top || + current_scissor_.right != scissor.right || current_scissor_.bottom != scissor.bottom) { + current_scissor_ = scissor; + command_list->RSSetScissorRects(1, &scissor); + } + + // Ensure texture data is available if any texture is loaded, upload all in a + // batch, then transition all at once. + UploadTextures(); + + // Bind the texture. If this is the first draw in a frame, the descriptor heap + // index will be invalid initially, and the texture will be bound regardless + // of what's in current_texture_. + auto texture = static_cast(draw.texture); + ID3D12Resource* texture_resource = texture ? texture->resource() : nullptr; + bool bind_texture = current_texture_ != texture_resource; + uint32_t texture_descriptor_index; + uint64_t texture_heap_index = texture_descriptor_pool_->Request( + last_paint_submission_index_, current_texture_descriptor_heap_index_, bind_texture ? 1 : 0, 1, + texture_descriptor_index); + if (texture_heap_index == D3D12DescriptorHeapPool::kHeapIndexInvalid) { + return; + } + if (texture_resource) { + texture->SetLastUsageSubmissionIndex(last_paint_submission_index_); + } + if (current_texture_descriptor_heap_index_ != texture_heap_index) { + current_texture_descriptor_heap_index_ = texture_heap_index; + bind_texture = true; + ID3D12DescriptorHeap* descriptor_heaps[] = {texture_descriptor_pool_->GetLastRequestHeap(), + sampler_heap_.Get()}; + command_list->SetDescriptorHeaps(2, descriptor_heaps); + } + + if (bind_texture) { + current_texture_ = texture_resource; + D3D12_SHADER_RESOURCE_VIEW_DESC texture_view_desc; + texture_view_desc.Format = D3D12ImmediateTexture::kFormat; + texture_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + if (texture_resource) { + texture_view_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + } else { + // No texture, solid color. + texture_view_desc.Shader4ComponentMapping = + D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1, + D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1, + D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1, + D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1); + } + texture_view_desc.Texture2D.MostDetailedMip = 0; + texture_view_desc.Texture2D.MipLevels = 1; + texture_view_desc.Texture2D.PlaneSlice = 0; + texture_view_desc.Texture2D.ResourceMinLODClamp = 0.0f; + provider_.GetDevice()->CreateShaderResourceView( + texture_resource, &texture_view_desc, + provider_.OffsetViewDescriptor(texture_descriptor_pool_->GetLastRequestHeapCPUStart(), + texture_descriptor_index)); + command_list->SetGraphicsRootDescriptorTable( + UINT(RootParameter::kTexture), + provider_.OffsetViewDescriptor(texture_descriptor_pool_->GetLastRequestHeapGPUStart(), + texture_descriptor_index)); + } + + // Bind the sampler. If the resource doesn't exist (solid color drawing), use + // nearest-neighbor and clamp so fetching is simpler. + SamplerIndex sampler_index = + texture_resource ? texture->sampler_index() : SamplerIndex::kNearestClamp; + if (current_sampler_index_ != sampler_index) { + current_sampler_index_ = sampler_index; + command_list->SetGraphicsRootDescriptorTable( + UINT(RootParameter::kSampler), + provider_.OffsetSamplerDescriptor(sampler_heap_gpu_start_, uint32_t(sampler_index))); + } + + // Set the primitive type and the pipeline for it. + D3D_PRIMITIVE_TOPOLOGY primitive_topology; + ID3D12PipelineState* pipeline; + switch (draw.primitive_type) { + case ImmediatePrimitiveType::kLines: + primitive_topology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; + pipeline = pipeline_line_.Get(); + break; + case ImmediatePrimitiveType::kTriangles: + primitive_topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + pipeline = pipeline_triangle_.Get(); + break; + default: + assert_unhandled_case(draw.primitive_type); + return; + } + if (current_primitive_topology_ != primitive_topology) { + current_primitive_topology_ = primitive_topology; + command_list->IASetPrimitiveTopology(primitive_topology); + command_list->SetPipelineState(pipeline); + } + + // Draw. + if (batch_has_index_buffer_) { + command_list->DrawIndexedInstanced(draw.count, 1, draw.index_offset, draw.base_vertex, 0); + } else { + command_list->DrawInstanced(draw.count, 1, draw.base_vertex, 0); + } +} + +void D3D12ImmediateDrawer::EndDrawBatch() { + batch_open_ = false; +} + +void D3D12ImmediateDrawer::End() { + assert_false(batch_open_); + + ImmediateDrawer::End(); +} + +void D3D12ImmediateDrawer::OnLeavePresenter() { + // Leaving the presenter's submission timeline - await GPU usage completion of + // all draws and texture uploads (which happen before draws) and reset + // submission indices. + D3D12Presenter& d3d12_presenter = *static_cast(presenter()); + d3d12_presenter.AwaitUISubmissionCompletionFromUIThread(last_paint_submission_index_); + + for (D3D12ImmediateTexture* texture : textures_) { + texture->SetLastUsageSubmissionIndex(0); + } + + texture_uploads_submitted_.clear(); + + vertex_buffer_pool_->ChangeSubmissionTimeline(); + texture_descriptor_pool_->ChangeSubmissionTimeline(); + + last_paint_submission_index_ = 0; + last_completed_submission_index_ = 0; +} + +void D3D12ImmediateDrawer::OnImmediateTextureDestroyed(D3D12ImmediateTexture& texture) { + // Remove from the texture list. + size_t texture_index = texture.immediate_drawer_index(); + assert_true(texture_index != SIZE_MAX); + D3D12ImmediateTexture*& texture_at_index = textures_[texture_index]; + texture_at_index = textures_.back(); + texture_at_index->SetImmediateDrawerIndex(texture_index); + textures_.pop_back(); + + // Queue for delayed release. + ID3D12Resource* resource = texture.resource(); + UINT64 last_usage_submission_index = texture.last_usage_submission_index(); + if (resource && last_usage_submission_index > last_completed_submission_index_) { + textures_deleted_.emplace_back(resource, last_usage_submission_index); + } +} + +void D3D12ImmediateDrawer::UploadTextures() { + if (texture_uploads_pending_.empty()) { + // Called often - don't initialize anything. + return; + } + + ID3D12Device* device = provider_.GetDevice(); + const D3D12UIDrawContext& d3d12_ui_draw_context = + *static_cast(ui_draw_context()); + ID3D12GraphicsCommandList* command_list = d3d12_ui_draw_context.command_list(); + + // Copy all at once, then transition all at once (not interleaving copying and + // pipeline barriers). + std::vector barriers; + barriers.reserve(texture_uploads_pending_.size()); + for (const PendingTextureUpload& pending_upload : texture_uploads_pending_) { + ID3D12Resource* texture = pending_upload.texture.Get(); + + D3D12_RESOURCE_DESC texture_desc = texture->GetDesc(); + D3D12_TEXTURE_COPY_LOCATION location_source, location_dest; + location_source.pResource = pending_upload.buffer.Get(); + location_source.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + device->GetCopyableFootprints(&texture_desc, 0, 1, 0, &location_source.PlacedFootprint, nullptr, + nullptr, nullptr); + location_dest.pResource = texture; + location_dest.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + location_dest.SubresourceIndex = 0; + command_list->CopyTextureRegion(&location_dest, 0, 0, 0, &location_source, nullptr); + + D3D12_RESOURCE_BARRIER& barrier = barriers.emplace_back(); + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.Transition.pResource = texture; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + + texture_uploads_submitted_.emplace_back(texture, pending_upload.buffer.Get(), + last_paint_submission_index_); + } + texture_uploads_pending_.clear(); + assert_false(barriers.empty()); + command_list->ResourceBarrier(UINT(barriers.size()), barriers.data()); +} + +} // namespace rex::ui::d3d12 diff --git a/src/ui/d3d12/d3d12_presenter.cpp b/src/ui/d3d12/d3d12_presenter.cpp new file mode 100644 index 0000000..8c1b5db --- /dev/null +++ b/src/ui/d3d12/d3d12_presenter.cpp @@ -0,0 +1,1516 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME +#include +#include +#include +#endif + +REXCVAR_DEFINE_BOOL(d3d12_allow_variable_refresh_rate_and_tearing, true, "UI/D3D12", + "Allow variable refresh rate and tearing"); + +namespace rex::ui::d3d12 { + +// Generated with `xb buildshaders`. +namespace shaders { +#include "ui/shaders/bytecode/d3d12_5_1/guest_output_bilinear_dither_ps.h" +#include "ui/shaders/bytecode/d3d12_5_1/guest_output_bilinear_ps.h" +#if defined(REX_HAS_FIDELITYFX_SDK) +#include "ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_cas_resample_dither_ps.h" +#include "ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_cas_resample_ps.h" +#include "ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_cas_sharpen_dither_ps.h" +#include "ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_cas_sharpen_ps.h" +#include "ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_fsr_easu_ps.h" +#include "ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_fsr_rcas_dither_ps.h" +#include "ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_fsr_rcas_ps.h" +#endif +#include "ui/shaders/bytecode/d3d12_5_1/guest_output_triangle_strip_rect_vs.h" +} // namespace shaders + +D3D12Presenter::~D3D12Presenter() { + // Await completion of the usage of everything before destroying anything. + // From most likely the latest to most likely the earliest to be signaled, so + // just one sleep will likely be needed. + paint_context_.AwaitSwapChainUsageCompletion(); + guest_output_resource_refresher_submission_tracker_.Shutdown(); + ui_submission_tracker_.Shutdown(); +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME + DestroyTemporalUpscalerContext(); +#endif +} + +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME +void D3D12Presenter::DestroyTemporalUpscalerContext() { + if (!temporal_upscaler_context_) { + return; + } + ffxContext* context = reinterpret_cast(&temporal_upscaler_context_); + ffxDestroyContext(context, nullptr); + temporal_upscaler_context_ = nullptr; + temporal_upscaler_max_render_width_ = 0; + temporal_upscaler_max_render_height_ = 0; + temporal_upscaler_max_output_width_ = 0; + temporal_upscaler_max_output_height_ = 0; +} + +bool D3D12Presenter::EnsureTemporalUpscalerContext(uint32_t render_width, uint32_t render_height, + uint32_t output_width, uint32_t output_height) { + if (!temporal_upscaler_context_ || temporal_upscaler_max_render_width_ != render_width || + temporal_upscaler_max_render_height_ != render_height || + temporal_upscaler_max_output_width_ != output_width || + temporal_upscaler_max_output_height_ != output_height) { + DestroyTemporalUpscalerContext(); + + ffxCreateContextDescUpscale create_desc = {}; + create_desc.header.type = FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE; + create_desc.header.pNext = nullptr; + create_desc.flags = FFX_UPSCALE_ENABLE_HIGH_DYNAMIC_RANGE | FFX_UPSCALE_ENABLE_AUTO_EXPOSURE; + create_desc.maxRenderSize.width = render_width; + create_desc.maxRenderSize.height = render_height; + create_desc.maxUpscaleSize.width = output_width; + create_desc.maxUpscaleSize.height = output_height; + create_desc.fpMessage = nullptr; + + ffxCreateBackendDX12Desc backend_desc = {}; + backend_desc.header.type = FFX_API_CREATE_CONTEXT_DESC_TYPE_BACKEND_DX12; + backend_desc.header.pNext = nullptr; + backend_desc.device = provider_.GetDevice(); + + create_desc.header.pNext = &backend_desc.header; + + ffxContext* context = reinterpret_cast(&temporal_upscaler_context_); + if (ffxCreateContext(context, &create_desc.header, nullptr) != FFX_API_RETURN_OK) { + REXLOG_WARN("D3D12Presenter: Failed to create FidelityFX temporal upscaler context"); + temporal_upscaler_context_ = nullptr; + return false; + } + + temporal_upscaler_max_render_width_ = render_width; + temporal_upscaler_max_render_height_ = render_height; + temporal_upscaler_max_output_width_ = output_width; + temporal_upscaler_max_output_height_ = output_height; + temporal_upscaler_provider_logged_ = false; + } + + if (!temporal_upscaler_provider_logged_) { + ffxQueryGetProviderVersion provider_version = {}; + provider_version.header.type = FFX_API_QUERY_DESC_TYPE_GET_PROVIDER_VERSION; + provider_version.header.pNext = nullptr; + ffxContext* context = reinterpret_cast(&temporal_upscaler_context_); + if (ffxQuery(context, &provider_version.header) == FFX_API_RETURN_OK && + provider_version.versionName) { + REXLOG_INFO("D3D12Presenter: FidelityFX upscaler provider {}", provider_version.versionName); + } + temporal_upscaler_provider_logged_ = true; + } + + return temporal_upscaler_context_ != nullptr; +} + +bool D3D12Presenter::DispatchTemporalUpscaler(ID3D12GraphicsCommandList* command_list, + ID3D12Resource* input_resource, uint32_t input_width, + uint32_t input_height, + ID3D12Resource* output_resource, + uint32_t output_width, uint32_t output_height, + const GuestOutputPaintConfig& config) { + if (!command_list || !input_resource || !output_resource || !input_width || !input_height || + !output_width || !output_height) { + return false; + } + if (!EnsureTemporalUpscalerContext(input_width, input_height, output_width, output_height)) { + return false; + } + + ffxDispatchDescUpscale dispatch_desc = {}; + dispatch_desc.header.type = FFX_API_DISPATCH_DESC_TYPE_UPSCALE; + dispatch_desc.header.pNext = nullptr; + dispatch_desc.commandList = command_list; + dispatch_desc.color = + ffxApiGetResourceDX12(input_resource, FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ); + dispatch_desc.depth = + ffxApiGetResourceDX12(input_resource, FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ, + FFX_API_RESOURCE_USAGE_DEPTHTARGET); + dispatch_desc.motionVectors = + ffxApiGetResourceDX12(input_resource, FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ); + dispatch_desc.exposure = + ffxApiGetResourceDX12(nullptr, FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ); + dispatch_desc.reactive = + ffxApiGetResourceDX12(nullptr, FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ); + dispatch_desc.transparencyAndComposition = + ffxApiGetResourceDX12(nullptr, FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ); + dispatch_desc.output = ffxApiGetResourceDX12( + output_resource, FFX_API_RESOURCE_STATE_UNORDERED_ACCESS, FFX_API_RESOURCE_USAGE_UAV); + dispatch_desc.jitterOffset.x = 0.0f; + dispatch_desc.jitterOffset.y = 0.0f; + dispatch_desc.motionVectorScale.x = float(input_width); + dispatch_desc.motionVectorScale.y = float(input_height); + dispatch_desc.renderSize.width = input_width; + dispatch_desc.renderSize.height = input_height; + dispatch_desc.upscaleSize.width = output_width; + dispatch_desc.upscaleSize.height = output_height; + dispatch_desc.enableSharpening = true; + dispatch_desc.sharpness = std::clamp(1.0f - config.GetFsrSharpnessReduction() * 0.5f, 0.0f, 1.0f); + // The presenter path doesn't currently provide accurate temporal inputs, + // so run in reset mode each frame to avoid history artifacts. + dispatch_desc.reset = true; + dispatch_desc.frameTimeDelta = 16.666f; + dispatch_desc.preExposure = 1.0f; + dispatch_desc.cameraNear = 0.1f; + dispatch_desc.cameraFar = 1000.0f; + dispatch_desc.cameraFovAngleVertical = 1.0472f; + dispatch_desc.viewSpaceToMetersFactor = 1.0f; + dispatch_desc.flags = 0; + + ffxContext* context = reinterpret_cast(&temporal_upscaler_context_); + if (ffxDispatch(context, &dispatch_desc.header) != FFX_API_RETURN_OK) { + return false; + } + + return true; +} +#endif + +Surface::TypeFlags D3D12Presenter::GetSupportedSurfaceTypes() const { + Surface::TypeFlags types = 0; +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_GAMES) + types |= Surface::kTypeFlag_Win32Hwnd; +#endif + return types; +} + +bool D3D12Presenter::CaptureGuestOutput(RawImage& image_out) { + Microsoft::WRL::ComPtr guest_output_resource; + { + uint32_t guest_output_mailbox_index; + std::unique_lock guest_output_consumer_lock( + ConsumeGuestOutput(guest_output_mailbox_index, nullptr, nullptr)); + if (guest_output_mailbox_index != UINT32_MAX) { + guest_output_resource = guest_output_resources_[guest_output_mailbox_index].second; + } + // Incremented the reference count of the guest output resource - safe to + // leave the consumer critical section now. + } + if (!guest_output_resource) { + return false; + } + + ID3D12Device* device = provider_.GetDevice(); + + D3D12_RESOURCE_DESC texture_desc = guest_output_resource->GetDesc(); + D3D12_TEXTURE_COPY_LOCATION copy_dest; + UINT64 copy_dest_size; + device->GetCopyableFootprints(&texture_desc, 0, 1, 0, ©_dest.PlacedFootprint, nullptr, + nullptr, ©_dest_size); + + D3D12_RESOURCE_DESC buffer_desc; + util::FillBufferResourceDesc(buffer_desc, copy_dest_size, D3D12_RESOURCE_FLAG_NONE); + Microsoft::WRL::ComPtr buffer; + // Create zeroed not to leak data in the row padding. + if (FAILED(device->CreateCommittedResource(&util::kHeapPropertiesReadback, D3D12_HEAP_FLAG_NONE, + &buffer_desc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, + IID_PPV_ARGS(&buffer)))) { + REXLOG_ERROR("D3D12Presenter: Failed to create the guest output capture buffer"); + return false; + } + + { + Microsoft::WRL::ComPtr command_allocator; + if (FAILED(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, + IID_PPV_ARGS(&command_allocator)))) { + REXLOG_ERROR( + "D3D12Presenter: Failed to create the guest output capturing command " + "allocator"); + return false; + } + Microsoft::WRL::ComPtr command_list; + if (FAILED(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, command_allocator.Get(), + nullptr, IID_PPV_ARGS(&command_list)))) { + REXLOG_ERROR( + "D3D12Presenter: Failed to create the guest output capturing command " + "list"); + return false; + } + + D3D12_RESOURCE_BARRIER barrier; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.Transition.pResource = guest_output_resource.Get(); + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + barrier.Transition.StateBefore = kGuestOutputInternalState; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE; + if constexpr (kGuestOutputInternalState != D3D12_RESOURCE_STATE_COPY_SOURCE) { + command_list->ResourceBarrier(1, &barrier); + } + copy_dest.pResource = buffer.Get(); + copy_dest.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + D3D12_TEXTURE_COPY_LOCATION copy_source; + copy_source.pResource = guest_output_resource.Get(); + copy_source.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + copy_source.SubresourceIndex = 0; + command_list->CopyTextureRegion(©_dest, 0, 0, 0, ©_source, nullptr); + if constexpr (kGuestOutputInternalState != D3D12_RESOURCE_STATE_COPY_SOURCE) { + std::swap(barrier.Transition.StateBefore, barrier.Transition.StateAfter); + command_list->ResourceBarrier(1, &barrier); + } + if (FAILED(command_list->Close())) { + REXLOG_ERROR( + "D3D12Presenter: Failed to close the guest output capturing command " + "list"); + return false; + } + + ID3D12CommandQueue* direct_queue = provider_.GetDirectQueue(); + + // Make sure that if any work is submitted, any `return` will cause an await + // before releasing the command allocator / list and the resource the RAII + // way in the destruction of the submission tracker - so create after the + // objects referenced in the submission - but don't submit anything if + // failed to initialize the fence. + D3D12SubmissionTracker submission_tracker; + if (!submission_tracker.Initialize(device, direct_queue)) { + return false; + } + ID3D12CommandList* execute_command_list = command_list.Get(); + direct_queue->ExecuteCommandLists(1, &execute_command_list); + if (!submission_tracker.NextSubmission()) { + REXLOG_ERROR("D3D12Presenter: Failed to signal the guest output capturing fence"); + return false; + } + if (!submission_tracker.AwaitAllSubmissionsCompletion()) { + REXLOG_ERROR("D3D12Presenter: Failed to await the guest output capturing fence"); + return false; + } + } + + D3D12_RANGE read_range; + read_range.Begin = copy_dest.PlacedFootprint.Offset; + read_range.End = copy_dest_size; + void* mapping; + if (FAILED(buffer->Map(0, &read_range, &mapping))) { + REXLOG_ERROR("D3D12Presenter: Failed to map the guest output capture buffer"); + return false; + } + image_out.width = uint32_t(texture_desc.Width); + image_out.height = uint32_t(texture_desc.Height); + image_out.stride = sizeof(uint32_t) * image_out.width; + image_out.data.resize(image_out.stride * image_out.height); + uint32_t* image_out_pixels = reinterpret_cast(image_out.data.data()); + for (uint32_t y = 0; y < image_out.height; ++y) { + uint32_t* dest_row = &image_out_pixels[size_t(image_out.width) * y]; + const uint32_t* source_row = reinterpret_cast( + reinterpret_cast(mapping) + copy_dest.PlacedFootprint.Offset + + size_t(copy_dest.PlacedFootprint.Footprint.RowPitch) * y); + for (uint32_t x = 0; x < image_out.width; ++x) { + dest_row[x] = Packed10bpcRGBTo8bpcBytes(source_row[x]); + } + } + // Unmapping will be done implicitly when the resource goes out of scope and + // gets destroyed. + return true; +} + +Presenter::SurfacePaintConnectResult +D3D12Presenter::ConnectOrReconnectPaintingToSurfaceFromUIThread(Surface& new_surface, + uint32_t new_surface_width, + uint32_t new_surface_height, + bool was_paintable, + bool& is_vsync_implicit_out) { + uint32_t new_swap_chain_width = + std::min(new_surface_width, uint32_t(D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION)); + uint32_t new_swap_chain_height = + std::min(new_surface_height, uint32_t(D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION)); + + // ConnectOrReconnectPaintingToSurfaceFromUIThread may be called only for the + // surface of the current swap chain or when the old swap chain has already + // been destroyed, if the surface is the same, try resizing. + if (paint_context_.swap_chain) { + if (was_paintable && paint_context_.swap_chain_width == new_swap_chain_width && + paint_context_.swap_chain_height == new_swap_chain_height) { + is_vsync_implicit_out = false; + return SurfacePaintConnectResult::kSuccessUnchanged; + } + paint_context_.AwaitSwapChainUsageCompletion(); + // Using the current swap_chain_allows_tearing_ value that's consistent with + // the creation of the swap chain because ResizeBuffers can't toggle the + // tearing flag. + for (Microsoft::WRL::ComPtr& swap_chain_buffer_ref : + paint_context_.swap_chain_buffers) { + swap_chain_buffer_ref.Reset(); + } + bool swap_chain_resized = SUCCEEDED(paint_context_.swap_chain->ResizeBuffers( + 0, UINT(new_swap_chain_width), UINT(new_swap_chain_height), DXGI_FORMAT_UNKNOWN, + paint_context_.swap_chain_allows_tearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0)); + if (swap_chain_resized) { + for (uint32_t i = 0; i < PaintContext::kSwapChainBufferCount; ++i) { + if (FAILED(paint_context_.swap_chain->GetBuffer( + i, IID_PPV_ARGS(&paint_context_.swap_chain_buffers[i])))) { + swap_chain_resized = false; + break; + } + } + if (swap_chain_resized) { + paint_context_.swap_chain_width = new_swap_chain_width; + paint_context_.swap_chain_height = new_swap_chain_height; + } + } + if (!swap_chain_resized) { + REXLOG_ERROR("D3D12Presenter: Failed to resize a swap chain"); + // Failed to resize, retry creating from scratch. + paint_context_.DestroySwapChain(); + } + } + + if (!paint_context_.swap_chain) { + // Create a new swap chain. + Surface::TypeIndex surface_type = new_surface.GetType(); + DXGI_SWAP_CHAIN_DESC1 swap_chain_desc; + swap_chain_desc.Width = UINT(new_swap_chain_width); + swap_chain_desc.Height = UINT(new_swap_chain_height); + swap_chain_desc.Format = kSwapChainFormat; + swap_chain_desc.Stereo = FALSE; + swap_chain_desc.SampleDesc.Count = 1; + swap_chain_desc.SampleDesc.Quality = 0; + swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swap_chain_desc.BufferCount = UINT(PaintContext::kSwapChainBufferCount); + // DXGI_SCALING_STRETCH may cause the content to "shake" while resizing, + // with relayout done for the guest output twice visually rather than once, + // and the UI becoming stretched and then jumping to normal. If it's + // possible to cover the entire surface without stretching, don't stretch. + // After resizing, the presenter repaints as soon as possible anyway, so + swap_chain_desc.Scaling = + (new_swap_chain_width == new_surface_width && new_swap_chain_height == new_surface_height) + ? DXGI_SCALING_NONE + : DXGI_SCALING_STRETCH; + swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + swap_chain_desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; + swap_chain_desc.Flags = 0; + if (REXCVAR_GET(d3d12_allow_variable_refresh_rate_and_tearing) && dxgi_supports_tearing_) { + // Allow tearing in borderless fullscreen to support variable refresh + // rate. + swap_chain_desc.Flags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING; + } + IDXGIFactory2* dxgi_factory = provider_.GetDXGIFactory(); + ID3D12CommandQueue* direct_queue = provider_.GetDirectQueue(); + Microsoft::WRL::ComPtr swap_chain_1; + switch (surface_type) { +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_GAMES) + case Surface::kTypeIndex_Win32Hwnd: { + HWND surface_hwnd = static_cast(new_surface).hwnd(); + if (FAILED(dxgi_factory->CreateSwapChainForHwnd( + direct_queue, surface_hwnd, &swap_chain_desc, nullptr, nullptr, &swap_chain_1))) { + REXLOG_ERROR("D3D12Presenter: Failed to create a swap chain for the HWND"); + return SurfacePaintConnectResult::kFailure; + } + // Disable automatic Alt+Enter handling - DXGI fullscreen doesn't + // support ALLOW_TEARING, and using custom fullscreen in ui::Win32Window + // anyway as with Alt+Enter the menu is kept, state changes are tracked + // better, and nothing is presented for some reason. + dxgi_factory->MakeWindowAssociation(surface_hwnd, DXGI_MWA_NO_ALT_ENTER); + } break; +#endif + default: + assert_unhandled_case(surface_type); + REXLOG_ERROR( + "D3D12Presenter: Tried to create a swap chain for an unsupported " + "Xenia surface type"); + return SurfacePaintConnectResult::kFailureSurfaceUnusable; + } + if (FAILED(swap_chain_1->QueryInterface(IID_PPV_ARGS(&paint_context_.swap_chain)))) { + REXLOG_ERROR( + "D3D12Presenter: Failed to get version 3 of the swap chain " + "interface"); + return SurfacePaintConnectResult::kFailure; + } + // From now on, in case of any failure, DestroySwapChain must be called + // before returning. + paint_context_.swap_chain_width = new_swap_chain_width; + paint_context_.swap_chain_height = new_swap_chain_height; + paint_context_.swap_chain_allows_tearing = + (swap_chain_desc.Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING) != 0; + for (uint32_t i = 0; i < PaintContext::kSwapChainBufferCount; ++i) { + if (FAILED(paint_context_.swap_chain->GetBuffer( + i, IID_PPV_ARGS(&paint_context_.swap_chain_buffers[i])))) { + REXLOG_ERROR("D3D12Presenter: Failed to get buffer {} of a {}-buffer swap chain", i, + PaintContext::kSwapChainBufferCount); + paint_context_.DestroySwapChain(); + return SurfacePaintConnectResult::kFailure; + } + } + } + + ID3D12Device* device = provider_.GetDevice(); + + // Create the RTV descriptors. + D3D12_CPU_DESCRIPTOR_HANDLE rtv_heap_start = + paint_context_.rtv_heap->GetCPUDescriptorHandleForHeapStart(); + D3D12_RENDER_TARGET_VIEW_DESC rtv_desc; + rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + rtv_desc.Texture2D.MipSlice = 0; + rtv_desc.Texture2D.PlaneSlice = 0; + for (uint32_t i = 0; i < PaintContext::kSwapChainBufferCount; ++i) { + ID3D12Resource* swap_chain_buffer = paint_context_.swap_chain_buffers[i].Get(); + rtv_desc.Format = kSwapChainFormat; + device->CreateRenderTargetView( + swap_chain_buffer, &rtv_desc, + provider_.OffsetRTVDescriptor(rtv_heap_start, PaintContext::kRTVIndexSwapChainBuffer0 + i)); + } + + is_vsync_implicit_out = false; + return SurfacePaintConnectResult::kSuccess; +} + +void D3D12Presenter::DisconnectPaintingFromSurfaceFromUIThreadImpl() { + paint_context_.DestroySwapChain(); +} + +bool D3D12Presenter::RefreshGuestOutputImpl( + uint32_t mailbox_index, uint32_t frontbuffer_width, uint32_t frontbuffer_height, + std::function refresher, bool& is_8bpc_out_ref) { + assert_not_zero(frontbuffer_width); + assert_not_zero(frontbuffer_height); + std::pair>& guest_output_resource_ref = + guest_output_resources_[mailbox_index]; + if (guest_output_resource_ref.second) { + D3D12_RESOURCE_DESC guest_output_resource_current_desc = + guest_output_resource_ref.second->GetDesc(); + if (guest_output_resource_current_desc.Width != frontbuffer_width || + guest_output_resource_current_desc.Height != frontbuffer_height) { + // Main target painting has its own reference to the textures for reading + // in its own submission tracker timeline, safe to release here. + guest_output_resource_refresher_submission_tracker_.AwaitSubmissionCompletion( + guest_output_resource_ref.first); + guest_output_resource_ref.second.Reset(); + } + } + if (!guest_output_resource_ref.second) { + ID3D12Device* device = provider_.GetDevice(); + D3D12_RESOURCE_DESC guest_output_resource_new_desc; + guest_output_resource_new_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + guest_output_resource_new_desc.Alignment = 0; + guest_output_resource_new_desc.Width = frontbuffer_width; + guest_output_resource_new_desc.Height = frontbuffer_height; + guest_output_resource_new_desc.DepthOrArraySize = 1; + guest_output_resource_new_desc.MipLevels = 1; + guest_output_resource_new_desc.Format = kGuestOutputFormat; + guest_output_resource_new_desc.SampleDesc.Count = 1; + guest_output_resource_new_desc.SampleDesc.Quality = 0; + guest_output_resource_new_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + guest_output_resource_new_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; + if (FAILED(device->CreateCommittedResource( + &util::kHeapPropertiesDefault, provider_.GetHeapFlagCreateNotZeroed(), + &guest_output_resource_new_desc, kGuestOutputInternalState, nullptr, + IID_PPV_ARGS(&guest_output_resource_ref.second)))) { + REXLOG_ERROR("D3D12Presenter: Failed to create the guest output {}x{} texture", + frontbuffer_width, frontbuffer_height); + return false; + } + } + D3D12GuestOutputRefreshContext context(is_8bpc_out_ref, guest_output_resource_ref.second.Get()); + bool refresher_succeeded = refresher(context); + // Even if the refresher has returned false, it still might have submitted + // some commands referencing the resource. It's better to put an excessive + // signal and wait slightly longer, for nothing important, while shutting down + // than to destroy the resource while it's still in use. + guest_output_resource_ref.first = + guest_output_resource_refresher_submission_tracker_.GetCurrentSubmission(); + guest_output_resource_refresher_submission_tracker_.NextSubmission(); + return refresher_succeeded; +} + +void D3D12Presenter::PaintContext::DestroySwapChain() { + if (!swap_chain) { + return; + } + AwaitSwapChainUsageCompletion(); + for (Microsoft::WRL::ComPtr& swap_chain_buffer_ref : swap_chain_buffers) { + swap_chain_buffer_ref.Reset(); + } + swap_chain.Reset(); + swap_chain_allows_tearing = false; + swap_chain_height = 0; + swap_chain_width = 0; +} + +Presenter::PaintResult D3D12Presenter::PaintAndPresentImpl(bool execute_ui_drawers) { + // Begin the command list with the command allocator not currently potentially + // used on the GPU. + UINT64 current_paint_submission = paint_context_.paint_submission_tracker.GetCurrentSubmission(); + UINT64 command_allocator_count = UINT64(paint_context_.command_allocators.size()); + if (current_paint_submission >= command_allocator_count) { + paint_context_.paint_submission_tracker.AwaitSubmissionCompletion(current_paint_submission - + command_allocator_count); + } + ID3D12CommandAllocator* command_allocator = + paint_context_.command_allocators[current_paint_submission % command_allocator_count].Get(); + command_allocator->Reset(); + ID3D12GraphicsCommandList* command_list = paint_context_.command_list.Get(); + command_list->Reset(command_allocator, nullptr); + + ID3D12Device* device = provider_.GetDevice(); + + // Obtain the RTV heap and the back buffer. + D3D12_CPU_DESCRIPTOR_HANDLE rtv_heap_start = + paint_context_.rtv_heap->GetCPUDescriptorHandleForHeapStart(); + UINT back_buffer_index = paint_context_.swap_chain->GetCurrentBackBufferIndex(); + D3D12_CPU_DESCRIPTOR_HANDLE back_buffer_rtv = provider_.OffsetRTVDescriptor( + rtv_heap_start, PaintContext::kRTVIndexSwapChainBuffer0 + back_buffer_index); + ID3D12Resource* back_buffer = paint_context_.swap_chain_buffers[back_buffer_index].Get(); + bool back_buffer_acquired = false; + bool back_buffer_bound = false; + bool back_buffer_clear_needed = true; + const float kBackBufferClearColor[] = {0.0f, 0.0f, 0.0f, 1.0f}; + + // Draw the guest output. + + GuestOutputProperties guest_output_properties; + GuestOutputPaintConfig guest_output_paint_config; + Microsoft::WRL::ComPtr guest_output_resource; + { + uint32_t guest_output_mailbox_index; + std::unique_lock guest_output_consumer_lock(ConsumeGuestOutput( + guest_output_mailbox_index, &guest_output_properties, &guest_output_paint_config)); + if (guest_output_mailbox_index != UINT32_MAX) { + guest_output_resource = guest_output_resources_[guest_output_mailbox_index].second; + } + // Incremented the reference count of the guest output resource - safe to + // leave the consumer critical section now as everything here either will be + // using the new reference or is exclusively owned by main target painting + // (and multiple threads can't paint the main target at the same time). + } + + if (guest_output_resource) { + GuestOutputPaintFlow guest_output_flow = GetGuestOutputPaintFlow( + guest_output_properties, paint_context_.swap_chain_width, paint_context_.swap_chain_height, + D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION, D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION, + guest_output_paint_config); + + // Check if all guest output paint effects are supported by the + // implementation. + if (guest_output_flow.effect_count) { + if (!guest_output_paint_final_pipelines_[size_t( + guest_output_flow.effects[guest_output_flow.effect_count - 1])]) { + guest_output_flow.effect_count = 0; + } + for (size_t i = 0; i + 1 < guest_output_flow.effect_count; ++i) { + if (!guest_output_paint_intermediate_pipelines_[size_t(guest_output_flow.effects[i])]) { + guest_output_flow.effect_count = 0; + break; + } + } + } + + if (guest_output_flow.effect_count) { + ID3D12DescriptorHeap* view_heap = paint_context_.view_heap.Get(); + D3D12_CPU_DESCRIPTOR_HANDLE view_heap_cpu_start = + view_heap->GetCPUDescriptorHandleForHeapStart(); + + // Store the main target reference to the guest output texture so it's not + // destroyed while it's still potentially in use by main target painting + // queued on the GPU. + size_t guest_output_resource_paint_ref_index = SIZE_MAX; + size_t guest_output_resource_paint_ref_new_index = SIZE_MAX; + // Try to find the existing reference to the same texture, or an already + // released (or a taken, but never actually used) slot. + for (size_t i = 0; i < paint_context_.guest_output_resource_paint_refs.size(); ++i) { + const std::pair>& + guest_output_resource_paint_ref = paint_context_.guest_output_resource_paint_refs[i]; + if (guest_output_resource_paint_ref.second == guest_output_resource) { + guest_output_resource_paint_ref_index = i; + break; + } + if (guest_output_resource_paint_ref_new_index == SIZE_MAX && + (!guest_output_resource_paint_ref.second || !guest_output_resource_paint_ref.first)) { + guest_output_resource_paint_ref_new_index = i; + } + } + if (guest_output_resource_paint_ref_index == SIZE_MAX) { + // New texture - store the reference and create the descriptors. + if (guest_output_resource_paint_ref_new_index == SIZE_MAX) { + // Replace the earliest used reference. + guest_output_resource_paint_ref_new_index = 0; + for (size_t i = 1; i < paint_context_.guest_output_resource_paint_refs.size(); ++i) { + if (paint_context_.guest_output_resource_paint_refs[i].first < + paint_context_ + .guest_output_resource_paint_refs[guest_output_resource_paint_ref_new_index] + .first) { + guest_output_resource_paint_ref_new_index = i; + } + } + // Await the completion of the usage of the old guest output + // resource and its SRV descriptors. + paint_context_.paint_submission_tracker.AwaitSubmissionCompletion( + paint_context_ + .guest_output_resource_paint_refs[guest_output_resource_paint_ref_new_index] + .first); + } + guest_output_resource_paint_ref_index = guest_output_resource_paint_ref_new_index; + // The actual submission index will be set if the texture is actually + // used, not dropped due to some error. + paint_context_.guest_output_resource_paint_refs[guest_output_resource_paint_ref_index] = + std::make_pair(UINT64(0), guest_output_resource); + // Create the SRV descriptor of the new texture. + D3D12_SHADER_RESOURCE_VIEW_DESC guest_output_resource_srv_desc; + guest_output_resource_srv_desc.Format = kGuestOutputFormat; + guest_output_resource_srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + guest_output_resource_srv_desc.Shader4ComponentMapping = + D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + guest_output_resource_srv_desc.Texture2D.MostDetailedMip = 0; + guest_output_resource_srv_desc.Texture2D.MipLevels = 1; + guest_output_resource_srv_desc.Texture2D.PlaneSlice = 0; + guest_output_resource_srv_desc.Texture2D.ResourceMinLODClamp = 0.0f; + device->CreateShaderResourceView( + guest_output_resource.Get(), &guest_output_resource_srv_desc, + provider_.OffsetViewDescriptor(view_heap_cpu_start, + PaintContext::kViewIndexGuestOutput0Srv + + uint32_t(guest_output_resource_paint_ref_index))); + } + + // Make sure intermediate textures of the needed size are available, and + // unneeded intermediate textures are destroyed. + for (size_t i = 0; i < kMaxGuestOutputPaintEffects - 1; ++i) { + std::pair intermediate_needed_size(0, 0); + if (i + 1 < guest_output_flow.effect_count) { + intermediate_needed_size = guest_output_flow.effect_output_sizes[i]; + } + Microsoft::WRL::ComPtr& intermediate_texture_ptr_ref = + paint_context_.guest_output_intermediate_textures[i]; + std::pair intermediate_current_size(0, 0); + if (intermediate_texture_ptr_ref) { + D3D12_RESOURCE_DESC intermediate_current_desc = intermediate_texture_ptr_ref->GetDesc(); + intermediate_current_size.first = uint32_t(intermediate_current_desc.Width); + intermediate_current_size.second = intermediate_current_desc.Height; + } + if (intermediate_current_size != intermediate_needed_size) { + if (intermediate_needed_size.first && intermediate_needed_size.second) { + // Need to replace immediately as a new texture with the requested + // size is needed. + if (intermediate_texture_ptr_ref) { + paint_context_.paint_submission_tracker.AwaitSubmissionCompletion( + paint_context_.guest_output_intermediate_texture_last_usage); + intermediate_texture_ptr_ref.Reset(); + } + // Resource. + D3D12_RESOURCE_DESC intermediate_desc; + intermediate_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + intermediate_desc.Alignment = 0; + intermediate_desc.Width = intermediate_needed_size.first; + intermediate_desc.Height = intermediate_needed_size.second; + intermediate_desc.DepthOrArraySize = 1; + intermediate_desc.MipLevels = 1; + intermediate_desc.Format = kGuestOutputIntermediateFormat; + intermediate_desc.SampleDesc.Count = 1; + intermediate_desc.SampleDesc.Quality = 0; + intermediate_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + intermediate_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | + D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; + if (FAILED(device->CreateCommittedResource( + &util::kHeapPropertiesDefault, provider_.GetHeapFlagCreateNotZeroed(), + &intermediate_desc, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, nullptr, + IID_PPV_ARGS(&intermediate_texture_ptr_ref)))) { + REXLOG_ERROR( + "D3D12Presenter: Failed to create a guest output " + "presentation intermediate texture"); + // Don't display the guest output, and don't try to create more + // intermediate textures (only destroy them). + guest_output_flow.effect_count = 0; + continue; + } + ID3D12Resource* intermediate_texture = intermediate_texture_ptr_ref.Get(); + // SRV. + D3D12_SHADER_RESOURCE_VIEW_DESC intermediate_srv_desc; + intermediate_srv_desc.Format = kGuestOutputIntermediateFormat; + intermediate_srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + intermediate_srv_desc.Shader4ComponentMapping = + D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + intermediate_srv_desc.Texture2D.MostDetailedMip = 0; + intermediate_srv_desc.Texture2D.MipLevels = 1; + intermediate_srv_desc.Texture2D.PlaneSlice = 0; + intermediate_srv_desc.Texture2D.ResourceMinLODClamp = 0.0f; + device->CreateShaderResourceView( + intermediate_texture, &intermediate_srv_desc, + provider_.OffsetViewDescriptor( + view_heap_cpu_start, + uint32_t(PaintContext::kViewIndexGuestOutputIntermediate0Srv + i))); + // RTV. + D3D12_RENDER_TARGET_VIEW_DESC intermediate_rtv_desc; + intermediate_rtv_desc.Format = kGuestOutputIntermediateFormat; + intermediate_rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + intermediate_rtv_desc.Texture2D.MipSlice = 0; + intermediate_rtv_desc.Texture2D.PlaneSlice = 0; + device->CreateRenderTargetView( + intermediate_texture, &intermediate_rtv_desc, + provider_.OffsetRTVDescriptor( + rtv_heap_start, uint32_t(PaintContext::kRTVIndexGuestOutputIntermediate0 + i))); + } else { + // Was previously needed, but not anymore - destroy when possible. + if (intermediate_texture_ptr_ref && + paint_context_.paint_submission_tracker.GetCompletedSubmission() >= + paint_context_.guest_output_intermediate_texture_last_usage) { + intermediate_texture_ptr_ref.Reset(); + } + } + } + } + + if (guest_output_flow.effect_count) { + paint_context_.guest_output_resource_paint_refs[guest_output_resource_paint_ref_index] + .first = current_paint_submission; + if (guest_output_flow.effect_count > 1) { + paint_context_.guest_output_intermediate_texture_last_usage = current_paint_submission; + } + + command_list->SetDescriptorHeaps(1, &view_heap); + } + + // This effect loop must not be aborted so the states of the resources + // involved are consistent. + D3D12_GPU_DESCRIPTOR_HANDLE view_heap_gpu_start = + view_heap->GetGPUDescriptorHandleForHeapStart(); + bool temporal_effect_selected = false; +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME + temporal_effect_selected = + guest_output_paint_config.GetEffect() == GuestOutputPaintConfig::Effect::kFsr2 || + guest_output_paint_config.GetEffect() == GuestOutputPaintConfig::Effect::kFsr3; +#endif + auto is_temporal_easu_effect = [&]([[maybe_unused]] size_t effect_index) { +#if defined(REX_HAS_FIDELITYFX_SDK) + return temporal_effect_selected && + guest_output_flow.effects[effect_index] == GuestOutputPaintEffect::kFsrEasu; +#else + return false; +#endif + }; + for (size_t i = 0; i < guest_output_flow.effect_count; ++i) { + bool is_final_effect = i + 1 >= guest_output_flow.effect_count; + + GuestOutputPaintEffect effect = guest_output_flow.effects[i]; +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME + bool use_temporal_upscaler = is_temporal_easu_effect(i); +#else + bool use_temporal_upscaler = false; +#endif + + ID3D12Resource* effect_dest_resource; + int32_t effect_rect_x, effect_rect_y; + D3D12_RESOURCE_STATES non_final_write_state = use_temporal_upscaler + ? D3D12_RESOURCE_STATE_UNORDERED_ACCESS + : D3D12_RESOURCE_STATE_RENDER_TARGET; + if (is_final_effect) { + effect_dest_resource = back_buffer; + if (!back_buffer_acquired) { + D3D12_RESOURCE_BARRIER barrier_present_to_rtv; + barrier_present_to_rtv.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier_present_to_rtv.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier_present_to_rtv.Transition.pResource = back_buffer; + barrier_present_to_rtv.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + barrier_present_to_rtv.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT; + barrier_present_to_rtv.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; + command_list->ResourceBarrier(1, &barrier_present_to_rtv); + back_buffer_acquired = true; + } + effect_rect_x = guest_output_flow.output_x; + effect_rect_y = guest_output_flow.output_y; + } else { + effect_dest_resource = paint_context_.guest_output_intermediate_textures[i].Get(); + if (!i) { + // If this is not the first effect, the transition has been done at + // the end of the previous effect in a single command. + D3D12_RESOURCE_BARRIER barrier_srv_to_write; + barrier_srv_to_write.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier_srv_to_write.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier_srv_to_write.Transition.pResource = effect_dest_resource; + barrier_srv_to_write.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + barrier_srv_to_write.Transition.StateBefore = + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + barrier_srv_to_write.Transition.StateAfter = non_final_write_state; + command_list->ResourceBarrier(1, &barrier_srv_to_write); + } + if (!use_temporal_upscaler) { + command_list->DiscardResource(effect_dest_resource, nullptr); + } + effect_rect_x = 0; + effect_rect_y = 0; + } + +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME + bool temporal_dispatch_done = false; + if (use_temporal_upscaler) { + uint32_t effect_input_width = 0, effect_input_height = 0; + guest_output_flow.GetEffectInputSize(i, effect_input_width, effect_input_height); + ID3D12Resource* effect_source_resource = + i ? paint_context_.guest_output_intermediate_textures[i - 1].Get() + : guest_output_resource.Get(); + temporal_dispatch_done = DispatchTemporalUpscaler( + command_list, effect_source_resource, effect_input_width, effect_input_height, + effect_dest_resource, guest_output_flow.effect_output_sizes[i].first, + guest_output_flow.effect_output_sizes[i].second, guest_output_paint_config); + if (!temporal_dispatch_done) { + D3D12_RESOURCE_BARRIER barrier_uav_to_rtv; + barrier_uav_to_rtv.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier_uav_to_rtv.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier_uav_to_rtv.Transition.pResource = effect_dest_resource; + barrier_uav_to_rtv.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + barrier_uav_to_rtv.Transition.StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + barrier_uav_to_rtv.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; + command_list->ResourceBarrier(1, &barrier_uav_to_rtv); + } + } +#else + bool temporal_dispatch_done = false; +#endif + + bool drew_graphics_effect = false; + if (!temporal_dispatch_done) { + if (is_final_effect) { + if (!back_buffer_bound) { + command_list->OMSetRenderTargets(1, &back_buffer_rtv, TRUE, nullptr); + back_buffer_bound = true; + } + } else { + D3D12_CPU_DESCRIPTOR_HANDLE intermediate_rtv = provider_.OffsetRTVDescriptor( + rtv_heap_start, uint32_t(PaintContext::kRTVIndexGuestOutputIntermediate0 + i)); + command_list->OMSetRenderTargets(1, &intermediate_rtv, TRUE, nullptr); + back_buffer_bound = false; + } + if (is_final_effect) { + back_buffer_bound = true; + } + D3D12_RESOURCE_DESC effect_dest_resource_desc = effect_dest_resource->GetDesc(); + D3D12_VIEWPORT viewport; + viewport.TopLeftX = 0.0f; + viewport.TopLeftY = 0.0f; + viewport.Width = float(effect_dest_resource_desc.Width); + viewport.Height = float(effect_dest_resource_desc.Height); + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + command_list->RSSetViewports(1, &viewport); + D3D12_RECT scissor; + scissor.left = 0; + scissor.top = 0; + scissor.right = LONG(effect_dest_resource_desc.Width); + scissor.bottom = LONG(effect_dest_resource_desc.Height); + command_list->RSSetScissorRects(1, &scissor); + + command_list->SetPipelineState( + is_final_effect ? guest_output_paint_final_pipelines_[size_t(effect)].Get() + : guest_output_paint_intermediate_pipelines_[size_t(effect)].Get()); + GuestOutputPaintRootSignatureIndex guest_output_paint_root_signature_index = + GetGuestOutputPaintRootSignatureIndex(effect); + command_list->SetGraphicsRootSignature( + guest_output_paint_root_signatures_[size_t(guest_output_paint_root_signature_index)] + .Get()); + + UINT effect_src_view_index = + UINT(i ? (PaintContext::kViewIndexGuestOutputIntermediate0Srv + (i - 1)) + : (PaintContext::kViewIndexGuestOutput0Srv + + guest_output_resource_paint_ref_index)); + command_list->SetGraphicsRootDescriptorTable( + UINT(GuestOutputPaintRootParameter::kSource), + provider_.OffsetViewDescriptor(view_heap_gpu_start, effect_src_view_index)); + + GuestOutputPaintRectangleConstants effect_rect_constants; + float effect_x_to_ndc = 2.0f / viewport.Width; + float effect_y_to_ndc = 2.0f / viewport.Height; + effect_rect_constants.x = -1.0f + float(effect_rect_x) * effect_x_to_ndc; + // +Y is -V. + effect_rect_constants.y = 1.0f - float(effect_rect_y) * effect_y_to_ndc; + effect_rect_constants.width = + float(guest_output_flow.effect_output_sizes[i].first) * effect_x_to_ndc; + effect_rect_constants.height = + -float(guest_output_flow.effect_output_sizes[i].second) * effect_y_to_ndc; + command_list->SetGraphicsRoot32BitConstants( + UINT(GuestOutputPaintRootParameter::kRectangle), + sizeof(effect_rect_constants) / sizeof(uint32_t), &effect_rect_constants, 0); + + UINT effect_constants_size = 0; + union { + BilinearConstants bilinear; +#if defined(REX_HAS_FIDELITYFX_SDK) + CasSharpenConstants cas_sharpen; + CasResampleConstants cas_resample; + FsrEasuConstants fsr_easu; + FsrRcasConstants fsr_rcas; +#endif + } effect_constants; + switch (guest_output_paint_root_signature_index) { + case kGuestOutputPaintRootSignatureIndexBilinear: { + effect_constants_size = sizeof(effect_constants.bilinear); + effect_constants.bilinear.Initialize(guest_output_flow, i); + } break; +#if defined(REX_HAS_FIDELITYFX_SDK) + case kGuestOutputPaintRootSignatureIndexCasSharpen: { + effect_constants_size = sizeof(effect_constants.cas_sharpen); + effect_constants.cas_sharpen.Initialize(guest_output_flow, i, + guest_output_paint_config); + } break; + case kGuestOutputPaintRootSignatureIndexCasResample: { + effect_constants_size = sizeof(effect_constants.cas_resample); + effect_constants.cas_resample.Initialize(guest_output_flow, i, + guest_output_paint_config); + } break; + case kGuestOutputPaintRootSignatureIndexFsrEasu: { + effect_constants_size = sizeof(effect_constants.fsr_easu); + effect_constants.fsr_easu.Initialize(guest_output_flow, i); + } break; + case kGuestOutputPaintRootSignatureIndexFsrRcas: { + effect_constants_size = sizeof(effect_constants.fsr_rcas); + effect_constants.fsr_rcas.Initialize(guest_output_flow, i, guest_output_paint_config); + } break; +#endif + default: + break; + } + if (effect_constants_size) { + command_list->SetGraphicsRoot32BitConstants( + UINT(GuestOutputPaintRootParameter::kEffectConstants), + effect_constants_size / sizeof(uint32_t), &effect_constants, 0); + } + + command_list->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + command_list->DrawInstanced(4, 1, 0, 0); + drew_graphics_effect = true; + } + + if (is_final_effect) { + if (drew_graphics_effect) { + // Clear the letterbox around the guest output if the guest output + // doesn't cover the entire back buffer. + if (guest_output_flow.letterbox_clear_rectangle_count) { + D3D12_RECT + letterbox_clear_d3d12_rectangles[GuestOutputPaintFlow::kMaxClearRectangles]; + for (size_t i = 0; i < guest_output_flow.letterbox_clear_rectangle_count; ++i) { + D3D12_RECT& letterbox_clear_d3d12_rectangle = letterbox_clear_d3d12_rectangles[i]; + const GuestOutputPaintFlow::ClearRectangle& letterbox_clear_rectangle = + guest_output_flow.letterbox_clear_rectangles[i]; + letterbox_clear_d3d12_rectangle.left = LONG(letterbox_clear_rectangle.x); + letterbox_clear_d3d12_rectangle.top = LONG(letterbox_clear_rectangle.y); + letterbox_clear_d3d12_rectangle.right = + LONG(letterbox_clear_rectangle.x + letterbox_clear_rectangle.width); + letterbox_clear_d3d12_rectangle.bottom = + LONG(letterbox_clear_rectangle.y + letterbox_clear_rectangle.height); + } + command_list->ClearRenderTargetView( + back_buffer_rtv, kBackBufferClearColor, + UINT(guest_output_flow.letterbox_clear_rectangle_count), + letterbox_clear_d3d12_rectangles); + } + back_buffer_clear_needed = false; + } + } else { + D3D12_RESOURCE_BARRIER barriers[2]; + UINT barrier_count = 0; + D3D12_RESOURCE_STATES effect_write_state = drew_graphics_effect + ? D3D12_RESOURCE_STATE_RENDER_TARGET + : D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + // Transition the newly written intermediate image to SRV for use as + // the source in the next effect. + { + assert_true(barrier_count < rex::countof(barriers)); + D3D12_RESOURCE_BARRIER& barrier_write_to_srv = barriers[barrier_count++]; + barrier_write_to_srv.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier_write_to_srv.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier_write_to_srv.Transition.pResource = effect_dest_resource; + barrier_write_to_srv.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + barrier_write_to_srv.Transition.StateBefore = effect_write_state; + barrier_write_to_srv.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + } + // Merge the current destination > next source transition with the + // acquisition of the destination for the next effect. + if (i + 2 < guest_output_flow.effect_count) { + // The next effect won't be the last - transition the next + // intermediate destination to its write state. + D3D12_RESOURCE_STATES next_write_state = is_temporal_easu_effect(i + 1) + ? D3D12_RESOURCE_STATE_UNORDERED_ACCESS + : D3D12_RESOURCE_STATE_RENDER_TARGET; + assert_true(barrier_count < rex::countof(barriers)); + D3D12_RESOURCE_BARRIER& barrier_srv_to_write = barriers[barrier_count++]; + barrier_srv_to_write.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier_srv_to_write.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier_srv_to_write.Transition.pResource = + paint_context_.guest_output_intermediate_textures[i + 1].Get(); + barrier_srv_to_write.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + barrier_srv_to_write.Transition.StateBefore = + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + barrier_srv_to_write.Transition.StateAfter = next_write_state; + } else { + // The next effect draws to the back buffer - merge into one + // ResourceBarrier command. + if (!back_buffer_acquired) { + assert_true(barrier_count < rex::countof(barriers)); + D3D12_RESOURCE_BARRIER& barrier_present_to_rtv = barriers[barrier_count++]; + barrier_present_to_rtv.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier_present_to_rtv.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier_present_to_rtv.Transition.pResource = back_buffer; + barrier_present_to_rtv.Transition.Subresource = + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + barrier_present_to_rtv.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT; + barrier_present_to_rtv.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; + back_buffer_acquired = true; + } + } + if (barrier_count) { + command_list->ResourceBarrier(barrier_count, barriers); + } + } + } + } + } + + // Release main target guest output texture references that aren't needed + // anymore (this is done after various potential guest-output-related main + // target submission tracker waits so the completed submission value is the + // most actual). + UINT64 completed_paint_submission = + paint_context_.paint_submission_tracker.GetCompletedSubmission(); + for (std::pair>& guest_output_resource_paint_ref : + paint_context_.guest_output_resource_paint_refs) { + if (!guest_output_resource_paint_ref.second || + guest_output_resource_paint_ref.second == guest_output_resource) { + continue; + } + if (completed_paint_submission >= guest_output_resource_paint_ref.first) { + guest_output_resource_paint_ref.second.Reset(); + } + } + + // If no guest output has been drawn, the transitioned of the back buffer to + // RTV hasn't been done yet, and it's needed to clear it, and optionally to + // draw the UI. + if (!back_buffer_acquired) { + D3D12_RESOURCE_BARRIER barrier_present_to_rtv; + barrier_present_to_rtv.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier_present_to_rtv.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier_present_to_rtv.Transition.pResource = back_buffer; + barrier_present_to_rtv.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + barrier_present_to_rtv.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT; + barrier_present_to_rtv.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; + command_list->ResourceBarrier(1, &barrier_present_to_rtv); + back_buffer_acquired = true; + } + + if (back_buffer_clear_needed) { + command_list->ClearRenderTargetView(back_buffer_rtv, kBackBufferClearColor, 0, nullptr); + back_buffer_clear_needed = false; + } + + if (execute_ui_drawers) { + // Draw the UI. + if (!back_buffer_bound) { + command_list->OMSetRenderTargets(1, &back_buffer_rtv, TRUE, nullptr); + back_buffer_bound = true; + } + D3D12UIDrawContext ui_draw_context(*this, paint_context_.swap_chain_width, + paint_context_.swap_chain_height, command_list, + ui_submission_tracker_.GetCurrentSubmission(), + ui_submission_tracker_.GetCompletedSubmission()); + ExecuteUIDrawersFromUIThread(ui_draw_context); + } + + // End drawing to the back buffer. + D3D12_RESOURCE_BARRIER barrier_rtv_to_present; + barrier_rtv_to_present.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier_rtv_to_present.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier_rtv_to_present.Transition.pResource = back_buffer; + barrier_rtv_to_present.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + barrier_rtv_to_present.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; + barrier_rtv_to_present.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT; + command_list->ResourceBarrier(1, &barrier_rtv_to_present); + + // Execute and present. + command_list->Close(); + ID3D12CommandList* execute_command_list = command_list; + provider_.GetDirectQueue()->ExecuteCommandLists(1, &execute_command_list); + if (execute_ui_drawers) { + ui_submission_tracker_.NextSubmission(); + } + paint_context_.paint_submission_tracker.NextSubmission(); + // Present as soon as possible, without waiting for vsync (the host refresh + // rate may be something like 144 Hz, which is not a multiple of the common + // 30 Hz or 60 Hz guest refresh rate), and allowing dropping outdated queued + // frames for lower latency. Also, if possible, allowing tearing to use + // variable refresh rate in borderless fullscreen (note that if DXGI + // fullscreen is ever used in, the allow tearing flag must not be passed in + // fullscreen, but DXGI fullscreen is largely unneeded with the flip + // presentation model used in Direct3D 12). + HRESULT present_result = paint_context_.swap_chain->Present( + 0, DXGI_PRESENT_RESTART | + (paint_context_.swap_chain_allows_tearing ? DXGI_PRESENT_ALLOW_TEARING : 0)); + // Even if presentation has failed, work might have been enqueued anyway + // internally before the failure according to Jesse Natalie from the DirectX + // Discord server. + paint_context_.present_submission_tracker.NextSubmission(); + switch (present_result) { + case DXGI_ERROR_DEVICE_REMOVED: + return PaintResult::kGpuLostExternally; + case DXGI_ERROR_DEVICE_RESET: + return PaintResult::kGpuLostResponsible; + default: + return SUCCEEDED(present_result) ? PaintResult::kPresented : PaintResult::kNotPresented; + } +} + +bool D3D12Presenter::InitializeSurfaceIndependent() { + // Check if DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING is supported. + { + Microsoft::WRL::ComPtr dxgi_factory_5; + if (SUCCEEDED(provider_.GetDXGIFactory()->QueryInterface(IID_PPV_ARGS(&dxgi_factory_5)))) { + BOOL tearing_feature_data; + dxgi_supports_tearing_ = SUCCEEDED(dxgi_factory_5->CheckFeatureSupport( + DXGI_FEATURE_PRESENT_ALLOW_TEARING, &tearing_feature_data, + sizeof(tearing_feature_data))) && + tearing_feature_data; + } + } + + ID3D12Device* device = provider_.GetDevice(); + + // Initialize static guest output painting objects. + + // Guest output painting root signatures. + // One (texture) for bilinear, two (texture and constants) for AMD FidelityFX + // CAS and FSR. + D3D12_ROOT_PARAMETER + guest_output_paint_root_parameters[UINT(GuestOutputPaintRootParameter::kCount)]; + // Source texture. + D3D12_DESCRIPTOR_RANGE guest_output_paint_root_descriptor_range_source; + guest_output_paint_root_descriptor_range_source.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + guest_output_paint_root_descriptor_range_source.NumDescriptors = 1; + guest_output_paint_root_descriptor_range_source.BaseShaderRegister = 0; + guest_output_paint_root_descriptor_range_source.RegisterSpace = 0; + guest_output_paint_root_descriptor_range_source.OffsetInDescriptorsFromTableStart = 0; + { + D3D12_ROOT_PARAMETER& guest_output_paint_root_parameter_source = + guest_output_paint_root_parameters[UINT(GuestOutputPaintRootParameter::kSource)]; + guest_output_paint_root_parameter_source.ParameterType = + D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + guest_output_paint_root_parameter_source.DescriptorTable.NumDescriptorRanges = 1; + guest_output_paint_root_parameter_source.DescriptorTable.pDescriptorRanges = + &guest_output_paint_root_descriptor_range_source; + guest_output_paint_root_parameter_source.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + } + // Rectangle. + { + D3D12_ROOT_PARAMETER& guest_output_paint_root_parameter_rect = + guest_output_paint_root_parameters[UINT(GuestOutputPaintRootParameter::kRectangle)]; + guest_output_paint_root_parameter_rect.ParameterType = + D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + guest_output_paint_root_parameter_rect.Constants.ShaderRegister = 0; + guest_output_paint_root_parameter_rect.Constants.RegisterSpace = 0; + guest_output_paint_root_parameter_rect.Constants.Num32BitValues = + sizeof(GuestOutputPaintRectangleConstants) / sizeof(uint32_t); + guest_output_paint_root_parameter_rect.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX; + } + // Pixel shader constants. + D3D12_ROOT_PARAMETER& guest_output_paint_root_parameter_effect_constants = + guest_output_paint_root_parameters[UINT(GuestOutputPaintRootParameter::kEffectConstants)]; + guest_output_paint_root_parameter_effect_constants.ParameterType = + D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + guest_output_paint_root_parameter_effect_constants.Constants.ShaderRegister = 0; + guest_output_paint_root_parameter_effect_constants.Constants.RegisterSpace = 0; + guest_output_paint_root_parameter_effect_constants.ShaderVisibility = + D3D12_SHADER_VISIBILITY_PIXEL; + // Bilinear sampler. + D3D12_STATIC_SAMPLER_DESC guest_output_paint_root_sampler; + guest_output_paint_root_sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; + guest_output_paint_root_sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + guest_output_paint_root_sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + guest_output_paint_root_sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + guest_output_paint_root_sampler.MipLODBias = 0.0f; + guest_output_paint_root_sampler.MaxAnisotropy = 1; + guest_output_paint_root_sampler.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER; + guest_output_paint_root_sampler.BorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK; + guest_output_paint_root_sampler.MinLOD = 0.0f; + guest_output_paint_root_sampler.MaxLOD = 0.0f; + guest_output_paint_root_sampler.ShaderRegister = 0; + guest_output_paint_root_sampler.RegisterSpace = 0; + guest_output_paint_root_sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + D3D12_ROOT_SIGNATURE_DESC guest_output_paint_root_signature_desc; + guest_output_paint_root_signature_desc.NumParameters = + UINT(GuestOutputPaintRootParameter::kCount); + guest_output_paint_root_signature_desc.pParameters = guest_output_paint_root_parameters; + guest_output_paint_root_signature_desc.NumStaticSamplers = 1; + guest_output_paint_root_signature_desc.pStaticSamplers = &guest_output_paint_root_sampler; + guest_output_paint_root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; + // Bilinear filtering (needs the sampler). + guest_output_paint_root_parameter_effect_constants.Constants.Num32BitValues = + sizeof(BilinearConstants) / sizeof(uint32_t); + { + ID3D12RootSignature* guest_output_paint_root_signature = + util::CreateRootSignature(provider_, guest_output_paint_root_signature_desc); + if (!guest_output_paint_root_signature) { + REXLOG_ERROR( + "D3D12Presenter: Failed to create the guest output bilinear " + "filtering presentation root signature"); + return false; + } + *(guest_output_paint_root_signatures_[kGuestOutputPaintRootSignatureIndexBilinear] + .ReleaseAndGetAddressOf()) = guest_output_paint_root_signature; + } +#if defined(REX_HAS_FIDELITYFX_SDK) + // EASU (needs the sampler). + guest_output_paint_root_parameter_effect_constants.Constants.Num32BitValues = + sizeof(FsrEasuConstants) / sizeof(uint32_t); + { + ID3D12RootSignature* guest_output_paint_root_signature = + util::CreateRootSignature(provider_, guest_output_paint_root_signature_desc); + if (!guest_output_paint_root_signature) { + REXLOG_ERROR( + "D3D12Presenter: Failed to create the guest output AMD FidelityFX " + "FSR EASU presentation root signature"); + return false; + } + *(guest_output_paint_root_signatures_[kGuestOutputPaintRootSignatureIndexFsrEasu] + .ReleaseAndGetAddressOf()) = guest_output_paint_root_signature; + } + // RCAS and CAS don't need the sampler. + guest_output_paint_root_signature_desc.NumStaticSamplers = 0; + // RCAS. + guest_output_paint_root_parameter_effect_constants.Constants.Num32BitValues = + sizeof(FsrRcasConstants) / sizeof(uint32_t); + { + ID3D12RootSignature* guest_output_paint_root_signature = + util::CreateRootSignature(provider_, guest_output_paint_root_signature_desc); + if (!guest_output_paint_root_signature) { + REXLOG_ERROR( + "D3D12Presenter: Failed to create the guest output AMD FidelityFX " + "FSR RCAS presentation root signature"); + return false; + } + *(guest_output_paint_root_signatures_[kGuestOutputPaintRootSignatureIndexFsrRcas] + .ReleaseAndGetAddressOf()) = guest_output_paint_root_signature; + } + // CAS, sharpening only. + guest_output_paint_root_parameter_effect_constants.Constants.Num32BitValues = + sizeof(CasSharpenConstants) / sizeof(uint32_t); + { + ID3D12RootSignature* guest_output_paint_root_signature = + util::CreateRootSignature(provider_, guest_output_paint_root_signature_desc); + if (!guest_output_paint_root_signature) { + REXLOG_ERROR( + "D3D12Presenter: Failed to create the guest output AMD FidelityFX " + "CAS presentation root signature"); + return false; + } + *(guest_output_paint_root_signatures_[kGuestOutputPaintRootSignatureIndexCasSharpen] + .ReleaseAndGetAddressOf()) = guest_output_paint_root_signature; + } + // CAS, resampling. + guest_output_paint_root_parameter_effect_constants.Constants.Num32BitValues = + sizeof(CasResampleConstants) / sizeof(uint32_t); + { + ID3D12RootSignature* guest_output_paint_root_signature = + util::CreateRootSignature(provider_, guest_output_paint_root_signature_desc); + if (!guest_output_paint_root_signature) { + REXLOG_ERROR( + "D3D12Presenter: Failed to create the guest output resampling AMD " + "FidelityFX CAS presentation root signature"); + return false; + } + *(guest_output_paint_root_signatures_[kGuestOutputPaintRootSignatureIndexCasResample] + .ReleaseAndGetAddressOf()) = guest_output_paint_root_signature; + } +#endif // defined(REX_HAS_FIDELITYFX_SDK) + + // Guest output painting pipelines. + D3D12_GRAPHICS_PIPELINE_STATE_DESC guest_output_paint_pipeline_desc = {}; + guest_output_paint_pipeline_desc.VS.pShaderBytecode = + shaders::guest_output_triangle_strip_rect_vs; + guest_output_paint_pipeline_desc.VS.BytecodeLength = + sizeof(shaders::guest_output_triangle_strip_rect_vs); + guest_output_paint_pipeline_desc.BlendState.RenderTarget[0].RenderTargetWriteMask = + D3D12_COLOR_WRITE_ENABLE_ALL; + guest_output_paint_pipeline_desc.SampleMask = UINT_MAX; + guest_output_paint_pipeline_desc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; + guest_output_paint_pipeline_desc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; + guest_output_paint_pipeline_desc.RasterizerState.DepthClipEnable = TRUE; + guest_output_paint_pipeline_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + guest_output_paint_pipeline_desc.NumRenderTargets = 1; + guest_output_paint_pipeline_desc.SampleDesc.Count = 1; + for (size_t i = 0; i < size_t(GuestOutputPaintEffect::kCount); ++i) { + GuestOutputPaintEffect guest_output_paint_effect = GuestOutputPaintEffect(i); + switch (guest_output_paint_effect) { + case GuestOutputPaintEffect::kBilinear: + guest_output_paint_pipeline_desc.PS.pShaderBytecode = shaders::guest_output_bilinear_ps; + guest_output_paint_pipeline_desc.PS.BytecodeLength = + sizeof(shaders::guest_output_bilinear_ps); + break; + case GuestOutputPaintEffect::kBilinearDither: + guest_output_paint_pipeline_desc.PS.pShaderBytecode = + shaders::guest_output_bilinear_dither_ps; + guest_output_paint_pipeline_desc.PS.BytecodeLength = + sizeof(shaders::guest_output_bilinear_dither_ps); + break; +#if defined(REX_HAS_FIDELITYFX_SDK) + case GuestOutputPaintEffect::kCasSharpen: + guest_output_paint_pipeline_desc.PS.pShaderBytecode = + shaders::guest_output_ffx_cas_sharpen_ps; + guest_output_paint_pipeline_desc.PS.BytecodeLength = + sizeof(shaders::guest_output_ffx_cas_sharpen_ps); + break; + case GuestOutputPaintEffect::kCasSharpenDither: + guest_output_paint_pipeline_desc.PS.pShaderBytecode = + shaders::guest_output_ffx_cas_sharpen_dither_ps; + guest_output_paint_pipeline_desc.PS.BytecodeLength = + sizeof(shaders::guest_output_ffx_cas_sharpen_dither_ps); + break; + case GuestOutputPaintEffect::kCasResample: + guest_output_paint_pipeline_desc.PS.pShaderBytecode = + shaders::guest_output_ffx_cas_resample_ps; + guest_output_paint_pipeline_desc.PS.BytecodeLength = + sizeof(shaders::guest_output_ffx_cas_resample_ps); + break; + case GuestOutputPaintEffect::kCasResampleDither: + guest_output_paint_pipeline_desc.PS.pShaderBytecode = + shaders::guest_output_ffx_cas_resample_dither_ps; + guest_output_paint_pipeline_desc.PS.BytecodeLength = + sizeof(shaders::guest_output_ffx_cas_resample_dither_ps); + break; + case GuestOutputPaintEffect::kFsrEasu: + guest_output_paint_pipeline_desc.PS.pShaderBytecode = shaders::guest_output_ffx_fsr_easu_ps; + guest_output_paint_pipeline_desc.PS.BytecodeLength = + sizeof(shaders::guest_output_ffx_fsr_easu_ps); + break; + case GuestOutputPaintEffect::kFsrRcas: + guest_output_paint_pipeline_desc.PS.pShaderBytecode = shaders::guest_output_ffx_fsr_rcas_ps; + guest_output_paint_pipeline_desc.PS.BytecodeLength = + sizeof(shaders::guest_output_ffx_fsr_rcas_ps); + break; + case GuestOutputPaintEffect::kFsrRcasDither: + guest_output_paint_pipeline_desc.PS.pShaderBytecode = + shaders::guest_output_ffx_fsr_rcas_dither_ps; + guest_output_paint_pipeline_desc.PS.BytecodeLength = + sizeof(shaders::guest_output_ffx_fsr_rcas_dither_ps); + break; +#endif + default: + // Not supported by this implementation. + continue; + } + guest_output_paint_pipeline_desc.pRootSignature = + guest_output_paint_root_signatures_[GetGuestOutputPaintRootSignatureIndex( + guest_output_paint_effect)] + .Get(); + if (CanGuestOutputPaintEffectBeIntermediate(guest_output_paint_effect)) { + guest_output_paint_pipeline_desc.RTVFormats[0] = kGuestOutputIntermediateFormat; + if (FAILED(device->CreateGraphicsPipelineState( + &guest_output_paint_pipeline_desc, + IID_PPV_ARGS(&guest_output_paint_intermediate_pipelines_[i])))) { + REXLOG_ERROR( + "D3D12Presenter: Failed to create the guest output painting " + "pipeline for effect {} writing to an intermediate texture", + i); + return false; + } + } + if (CanGuestOutputPaintEffectBeFinal(guest_output_paint_effect)) { + guest_output_paint_pipeline_desc.RTVFormats[0] = kSwapChainFormat; + if (FAILED(device->CreateGraphicsPipelineState( + &guest_output_paint_pipeline_desc, + IID_PPV_ARGS(&guest_output_paint_final_pipelines_[i])))) { + REXLOG_ERROR( + "D3D12Presenter: Failed to create the guest output painting " + "pipeline for effect {} writing to a swap chain buffer", + i); + return false; + } + } + } + + // Initialize connection-independent parts of the painting context. + + ID3D12CommandQueue* direct_queue = provider_.GetDirectQueue(); + + // Paint submission trackers. + if (!paint_context_.paint_submission_tracker.Initialize(device, direct_queue) || + !paint_context_.present_submission_tracker.Initialize(device, direct_queue)) { + return false; + } + + // Paint command allocators and command list. + for (Microsoft::WRL::ComPtr& paint_command_allocator_ref : + paint_context_.command_allocators) { + if (FAILED(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, + IID_PPV_ARGS(&paint_command_allocator_ref)))) { + REXLOG_ERROR( + "D3D12Presenter: Failed to create a command allocator for drawing to " + "a swap chain"); + return false; + } + } + if (FAILED(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, + paint_context_.command_allocators[0].Get(), nullptr, + IID_PPV_ARGS(&paint_context_.command_list)))) { + REXLOG_ERROR( + "D3D12Presenter: Failed to create the command list for drawing to a " + "swap chain"); + return false; + } + // Command lists are created in an open state. + paint_context_.command_list->Close(); + + // RTV descriptor heap. + D3D12_DESCRIPTOR_HEAP_DESC rtv_heap_desc; + rtv_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; + rtv_heap_desc.NumDescriptors = PaintContext::kRTVCount; + rtv_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + rtv_heap_desc.NodeMask = 0; + if (FAILED( + device->CreateDescriptorHeap(&rtv_heap_desc, IID_PPV_ARGS(&paint_context_.rtv_heap)))) { + REXLOG_ERROR( + "D3D12Presenter: Failed to create an RTV descriptor heap with {} " + "descriptors", + rtv_heap_desc.NumDescriptors); + return false; + } + + // CBV/SRV/UAV descriptor heap. + D3D12_DESCRIPTOR_HEAP_DESC view_heap_desc; + view_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + view_heap_desc.NumDescriptors = PaintContext::kViewCount; + view_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + view_heap_desc.NodeMask = 0; + if (FAILED( + device->CreateDescriptorHeap(&view_heap_desc, IID_PPV_ARGS(&paint_context_.view_heap)))) { + REXLOG_ERROR( + "D3D12Presenter: Failed to create a shader-visible CBV/SRV/UAV " + "descriptor heap with {} descriptors", + view_heap_desc.NumDescriptors); + return false; + } + + if (!guest_output_resource_refresher_submission_tracker_.Initialize(device, direct_queue)) { + return false; + } + + if (!ui_submission_tracker_.Initialize(device, direct_queue)) { + return false; + } + + return InitializeCommonSurfaceIndependent(); +} + +} // namespace rex::ui::d3d12 diff --git a/src/ui/d3d12/d3d12_provider.cpp b/src/ui/d3d12/d3d12_provider.cpp new file mode 100644 index 0000000..bf8252b --- /dev/null +++ b/src/ui/d3d12/d3d12_provider.cpp @@ -0,0 +1,479 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +REXCVAR_DEFINE_BOOL(d3d12_debug, false, "UI/D3D12", "Enable Direct3D 12 and DXGI debug layer") + .lifecycle(rex::cvar::Lifecycle::kInitOnly); + +REXCVAR_DEFINE_BOOL(d3d12_break_on_error, false, "UI/D3D12", + "Break on Direct3D 12 validation errors"); + +REXCVAR_DEFINE_BOOL(d3d12_break_on_warning, false, "UI/D3D12", + "Break on Direct3D 12 validation warnings"); + +REXCVAR_DEFINE_INT32(d3d12_adapter, -1, "UI/D3D12", + "Index of the DXGI adapter to use (-1 for any physical, -2 for WARP)") + .lifecycle(rex::cvar::Lifecycle::kInitOnly); + +REXCVAR_DEFINE_INT32(d3d12_queue_priority, 1, "UI/D3D12", + "Graphics command queue priority (0=normal, 1=high, 2=realtime)") + .range(0, 2); + +namespace rex::ui::d3d12 { + +bool D3D12Provider::IsD3D12APIAvailable() { + HMODULE library_d3d12 = LoadLibraryW(L"D3D12.dll"); + if (!library_d3d12) { + return false; + } + FreeLibrary(library_d3d12); + return true; +} + +std::unique_ptr D3D12Provider::Create() { + std::unique_ptr provider(new D3D12Provider); + if (!provider->Initialize()) { + rex::FatalError( + "Unable to initialize Direct3D 12 graphics subsystem.\n" + "\n" + "Ensure that you have the latest drivers for your GPU and it supports " + "Direct3D 12 with the feature level of at least 11_0.\n" + "\n" + "See https://xenia.jp/faq/ for more information and a list of " + "supported GPUs."); + return nullptr; + } + return provider; +} + +D3D12Provider::~D3D12Provider() { + if (graphics_analysis_ != nullptr) { + graphics_analysis_->Release(); + } + if (direct_queue_ != nullptr) { + direct_queue_->Release(); + } + if (device_ != nullptr) { + device_->Release(); + } + if (dxgi_factory_ != nullptr) { + dxgi_factory_->Release(); + } + + if (REXCVAR_GET(d3d12_debug) && pfn_dxgi_get_debug_interface1_) { + Microsoft::WRL::ComPtr dxgi_debug; + if (SUCCEEDED(pfn_dxgi_get_debug_interface1_(0, IID_PPV_ARGS(&dxgi_debug)))) { + dxgi_debug->ReportLiveObjects(DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_ALL); + } + } + + if (library_dxcompiler_ != nullptr) { + FreeLibrary(library_dxcompiler_); + } + if (library_dxilconv_ != nullptr) { + FreeLibrary(library_dxilconv_); + } + if (library_d3dcompiler_ != nullptr) { + FreeLibrary(library_d3dcompiler_); + } + if (library_d3d12_ != nullptr) { + FreeLibrary(library_d3d12_); + } + if (library_dxgi_ != nullptr) { + FreeLibrary(library_dxgi_); + } +} + +bool D3D12Provider::EnableIncreaseBasePriorityPrivilege() { + TOKEN_PRIVILEGES privileges; + privileges.PrivilegeCount = 1; + privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + if (!LookupPrivilegeValue(nullptr, SE_INC_BASE_PRIORITY_NAME, &privileges.Privileges[0].Luid)) { + return false; + } + HANDLE token; + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) { + return false; + } + bool enabled = + AdjustTokenPrivileges(token, FALSE, &privileges, sizeof(privileges), nullptr, nullptr) && + GetLastError() != ERROR_NOT_ALL_ASSIGNED; + CloseHandle(token); + return enabled; +} + +bool D3D12Provider::Initialize() { + // Load the core libraries. + library_dxgi_ = LoadLibraryW(L"dxgi.dll"); + library_d3d12_ = LoadLibraryW(L"D3D12.dll"); + if (!library_dxgi_ || !library_d3d12_) { + REXLOG_ERROR("Failed to load dxgi.dll or D3D12.dll"); + return false; + } + bool libraries_loaded = true; + libraries_loaded &= (pfn_create_dxgi_factory2_ = PFNCreateDXGIFactory2( + GetProcAddress(library_dxgi_, "CreateDXGIFactory2"))) != nullptr; + libraries_loaded &= (pfn_dxgi_get_debug_interface1_ = PFNDXGIGetDebugInterface1( + GetProcAddress(library_dxgi_, "DXGIGetDebugInterface1"))) != nullptr; + libraries_loaded &= (pfn_d3d12_get_debug_interface_ = PFN_D3D12_GET_DEBUG_INTERFACE( + GetProcAddress(library_d3d12_, "D3D12GetDebugInterface"))) != nullptr; + libraries_loaded &= (pfn_d3d12_create_device_ = PFN_D3D12_CREATE_DEVICE( + GetProcAddress(library_d3d12_, "D3D12CreateDevice"))) != nullptr; + libraries_loaded &= + (pfn_d3d12_serialize_root_signature_ = PFN_D3D12_SERIALIZE_ROOT_SIGNATURE( + GetProcAddress(library_d3d12_, "D3D12SerializeRootSignature"))) != nullptr; + if (!libraries_loaded) { + REXLOG_ERROR("Failed to get DXGI or Direct3D 12 functions"); + return false; + } + + // Load optional D3DCompiler_47.dll. + pfn_d3d_disassemble_ = nullptr; + library_d3dcompiler_ = LoadLibraryW(L"D3DCompiler_47.dll"); + if (library_d3dcompiler_) { + pfn_d3d_disassemble_ = pD3DDisassemble(GetProcAddress(library_d3dcompiler_, "D3DDisassemble")); + if (pfn_d3d_disassemble_ == nullptr) { + REXLOG_DEBUG( + "Failed to get D3DDisassemble from D3DCompiler_47.dll, DXBC " + "disassembly for debugging will be unavailable"); + } + } else { + REXLOG_DEBUG( + "Failed to load D3DCompiler_47.dll, DXBC disassembly for debugging " + "will be unavailable"); + } + + // Load optional dxilconv.dll. + pfn_dxilconv_dxc_create_instance_ = nullptr; + library_dxilconv_ = LoadLibraryW(L"dxilconv.dll"); + if (library_dxilconv_) { + pfn_dxilconv_dxc_create_instance_ = + DxcCreateInstanceProc(GetProcAddress(library_dxilconv_, "DxcCreateInstance")); + if (pfn_dxilconv_dxc_create_instance_ == nullptr) { + REXLOG_DEBUG( + "Failed to get DxcCreateInstance from dxilconv.dll, converted DXIL " + "disassembly for debugging will be unavailable"); + } + } else { + REXLOG_DEBUG( + "Failed to load dxilconv.dll, converted DXIL disassembly for debugging " + "will be unavailable - DXIL may be unsupported by your OS version"); + } + + // Load optional dxcompiler.dll. + pfn_dxcompiler_dxc_create_instance_ = nullptr; + library_dxcompiler_ = LoadLibraryW(L"dxcompiler.dll"); + if (library_dxcompiler_) { + pfn_dxcompiler_dxc_create_instance_ = + DxcCreateInstanceProc(GetProcAddress(library_dxcompiler_, "DxcCreateInstance")); + if (pfn_dxcompiler_dxc_create_instance_ == nullptr) { + REXLOG_DEBUG( + "Failed to get DxcCreateInstance from dxcompiler.dll, converted DXIL " + "disassembly for debugging will be unavailable"); + } + } else { + REXLOG_DEBUG( + "Failed to load dxcompiler.dll, converted DXIL disassembly for " + "debugging will be unavailable - if needed, download the DirectX " + "Shader Compiler from " + "https://github.com/microsoft/DirectXShaderCompiler/releases and place " + "the DLL in the Xenia directory"); + } + + // Configure the DXGI debug info queue. + if (REXCVAR_GET(d3d12_break_on_error) || REXCVAR_GET(d3d12_break_on_warning)) { + IDXGIInfoQueue* dxgi_info_queue; + if (SUCCEEDED(pfn_dxgi_get_debug_interface1_(0, IID_PPV_ARGS(&dxgi_info_queue)))) { + if (REXCVAR_GET(d3d12_break_on_error)) { + dxgi_info_queue->SetBreakOnSeverity(DXGI_DEBUG_ALL, + DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, TRUE); + dxgi_info_queue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, + TRUE); + } + if (REXCVAR_GET(d3d12_break_on_warning)) { + dxgi_info_queue->SetBreakOnSeverity(DXGI_DEBUG_ALL, + DXGI_INFO_QUEUE_MESSAGE_SEVERITY_WARNING, TRUE); + } + dxgi_info_queue->Release(); + } + } + + // Enable the debug layer. + bool debug = REXCVAR_GET(d3d12_debug); + if (debug) { + ID3D12Debug* debug_interface; + if (SUCCEEDED(pfn_d3d12_get_debug_interface_(IID_PPV_ARGS(&debug_interface)))) { + debug_interface->EnableDebugLayer(); + debug_interface->Release(); + } else { + REXLOG_WARN("Failed to enable the Direct3D 12 debug layer"); + debug = false; + } + + // Enable DRED (Device Removed Extended Data) for diagnosing GPU crashes. + { + Microsoft::WRL::ComPtr dred_settings; + if (SUCCEEDED(pfn_d3d12_get_debug_interface_(IID_PPV_ARGS(&dred_settings)))) { + dred_settings->SetAutoBreadcrumbsEnablement(D3D12_DRED_ENABLEMENT_FORCED_ON); + dred_settings->SetPageFaultEnablement(D3D12_DRED_ENABLEMENT_FORCED_ON); + REXLOG_INFO("DRED (Device Removed Extended Data) enabled"); + } else { + REXLOG_WARN( + "Failed to enable DRED - device removal diagnostics will be " + "limited"); + } + } + } + // Create the DXGI factory. + IDXGIFactory2* dxgi_factory; + if (FAILED(pfn_create_dxgi_factory2_(debug ? DXGI_CREATE_FACTORY_DEBUG : 0, + IID_PPV_ARGS(&dxgi_factory)))) { + REXLOG_ERROR("Failed to create a DXGI factory"); + return false; + } + + // Choose the adapter. + uint32_t adapter_index = 0; + IDXGIAdapter1* adapter = nullptr; + while (dxgi_factory->EnumAdapters1(adapter_index, &adapter) == S_OK) { + DXGI_ADAPTER_DESC1 adapter_desc; + if (SUCCEEDED(adapter->GetDesc1(&adapter_desc))) { + if (SUCCEEDED(pfn_d3d12_create_device_(adapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), + nullptr))) { + if (REXCVAR_GET(d3d12_adapter) >= 0) { + if (adapter_index == REXCVAR_GET(d3d12_adapter)) { + break; + } + } else if (REXCVAR_GET(d3d12_adapter) == -2) { + if (adapter_desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { + break; + } + } else { + if (!(adapter_desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)) { + break; + } + } + } + } + adapter->Release(); + adapter = nullptr; + ++adapter_index; + } + if (adapter == nullptr) { + REXLOG_ERROR( + "Failed to get an adapter supporting Direct3D 12 with the feature " + "level of at least 11_0"); + dxgi_factory->Release(); + return false; + } + DXGI_ADAPTER_DESC adapter_desc; + if (FAILED(adapter->GetDesc(&adapter_desc))) { + REXLOG_ERROR("Failed to get the DXGI adapter description"); + adapter->Release(); + dxgi_factory->Release(); + return false; + } + adapter_vendor_id_ = GpuVendorID(adapter_desc.VendorId); + int adapter_name_mb_size = + WideCharToMultiByte(CP_UTF8, 0, adapter_desc.Description, -1, nullptr, 0, nullptr, nullptr); + if (adapter_name_mb_size != 0) { + char* adapter_name_mb = reinterpret_cast(alloca(adapter_name_mb_size)); + if (WideCharToMultiByte(CP_UTF8, 0, adapter_desc.Description, -1, adapter_name_mb, + adapter_name_mb_size, nullptr, nullptr) != 0) { + REXGPU_INFO("DXGI adapter: {} (vendor 0x{:04X}, device 0x{:04X})", adapter_name_mb, + adapter_desc.VendorId, adapter_desc.DeviceId); + } + } + + // Create the Direct3D 12 device. + ID3D12Device* device; + if (FAILED(pfn_d3d12_create_device_(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&device)))) { + REXLOG_ERROR("Failed to create a Direct3D 12 feature level 11_0 device"); + adapter->Release(); + dxgi_factory->Release(); + return false; + } + adapter->Release(); + + // Configure the Direct3D 12 debug info queue. + ID3D12InfoQueue* d3d12_info_queue; + if (SUCCEEDED(device->QueryInterface(IID_PPV_ARGS(&d3d12_info_queue)))) { + D3D12_MESSAGE_SEVERITY d3d12_info_queue_denied_severities[] = { + D3D12_MESSAGE_SEVERITY_INFO, + }; + D3D12_MESSAGE_ID d3d12_info_queue_denied_messages[] = { + // Xbox 360 vertex fetch is explicit in shaders. + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_EMPTY_LAYOUT, + // Bug in the debug layer (fixed in some version of Windows) - gaps in + // render target bindings must be represented with a fully typed RTV + // descriptor and DXGI_FORMAT_UNKNOWN in the pipeline state, but older + // debug layer versions give a format mismatch error in this case. + D3D12_MESSAGE_ID_RENDER_TARGET_FORMAT_MISMATCH_PIPELINE_STATE, + // Render targets and shader exports don't have to match on the Xbox + // 360. + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_RENDERTARGETVIEW_NOT_SET, + // Arbitrary scissor can be specified by the guest, also it can be + // explicitly used to disable drawing. + D3D12_MESSAGE_ID_DRAW_EMPTY_SCISSOR_RECTANGLE, + // Arbitrary clear values can be specified by the guest. + D3D12_MESSAGE_ID_CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE, + D3D12_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_MISMATCHINGCLEARVALUE, + }; + D3D12_INFO_QUEUE_FILTER d3d12_info_queue_filter = {}; + d3d12_info_queue_filter.DenyList.NumSeverities = + UINT(rex::countof(d3d12_info_queue_denied_severities)); + d3d12_info_queue_filter.DenyList.pSeverityList = d3d12_info_queue_denied_severities; + d3d12_info_queue_filter.DenyList.NumIDs = UINT(rex::countof(d3d12_info_queue_denied_messages)); + d3d12_info_queue_filter.DenyList.pIDList = d3d12_info_queue_denied_messages; + d3d12_info_queue->PushStorageFilter(&d3d12_info_queue_filter); + if (REXCVAR_GET(d3d12_break_on_error)) { + d3d12_info_queue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE); + d3d12_info_queue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, TRUE); + } + if (REXCVAR_GET(d3d12_break_on_warning)) { + d3d12_info_queue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, TRUE); + } + d3d12_info_queue->Release(); + } + + // Create the command queue for graphics. + D3D12_COMMAND_QUEUE_DESC queue_desc; + queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + if (REXCVAR_GET(d3d12_queue_priority) >= 2) { + queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_GLOBAL_REALTIME; + if (!EnableIncreaseBasePriorityPrivilege()) { + REXLOG_WARN( + "Failed to enable SeIncreaseBasePriorityPrivilege for global " + "realtime Direct3D 12 command queue priority, falling back to high " + "priority, try launching Xenia as administrator"); + queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_HIGH; + } + } else if (REXCVAR_GET(d3d12_queue_priority) >= 1) { + queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_HIGH; + } else { + queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL; + } + queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + queue_desc.NodeMask = 0; + ID3D12CommandQueue* direct_queue; + if (FAILED(device->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&direct_queue)))) { + bool queue_created = false; + if (queue_desc.Priority == D3D12_COMMAND_QUEUE_PRIORITY_GLOBAL_REALTIME) { + REXLOG_WARN( + "Failed to create a Direct3D 12 direct command queue with global " + "realtime priority, falling back to high priority, try launching " + "Xenia as administrator"); + queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_HIGH; + queue_created = + SUCCEEDED(device->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&direct_queue))); + } + if (!queue_created) { + REXLOG_ERROR("Failed to create a Direct3D 12 direct command queue"); + device->Release(); + dxgi_factory->Release(); + return false; + } + } + + dxgi_factory_ = dxgi_factory; + device_ = device; + direct_queue_ = direct_queue; + + // Get descriptor sizes for each type. + for (uint32_t i = 0; i < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; ++i) { + descriptor_sizes_[i] = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE(i)); + } + + // Check if optional features are supported. + // D3D12_HEAP_FLAG_CREATE_NOT_ZEROED requires Windows 10 2004 (indicated by + // the availability of ID3D12Device8 or D3D12_FEATURE_D3D12_OPTIONS7). + heap_flag_create_not_zeroed_ = D3D12_HEAP_FLAG_NONE; + D3D12_FEATURE_DATA_D3D12_OPTIONS7 options7; + if (SUCCEEDED( + device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS7, &options7, sizeof(options7)))) { + heap_flag_create_not_zeroed_ = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; + } + ps_specified_stencil_reference_supported_ = false; + rasterizer_ordered_views_supported_ = false; + resource_binding_tier_ = D3D12_RESOURCE_BINDING_TIER_1; + tiled_resources_tier_ = D3D12_TILED_RESOURCES_TIER_NOT_SUPPORTED; + unaligned_block_textures_supported_ = false; + D3D12_FEATURE_DATA_D3D12_OPTIONS options; + if (SUCCEEDED( + device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options)))) { + ps_specified_stencil_reference_supported_ = bool(options.PSSpecifiedStencilRefSupported); + rasterizer_ordered_views_supported_ = bool(options.ROVsSupported); + resource_binding_tier_ = options.ResourceBindingTier; + tiled_resources_tier_ = options.TiledResourcesTier; + } + programmable_sample_positions_tier_ = D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_NOT_SUPPORTED; + D3D12_FEATURE_DATA_D3D12_OPTIONS2 options2; + if (SUCCEEDED( + device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS2, &options2, sizeof(options2)))) { + programmable_sample_positions_tier_ = options2.ProgrammableSamplePositionsTier; + } + D3D12_FEATURE_DATA_D3D12_OPTIONS8 options8; + if (SUCCEEDED( + device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS8, &options8, sizeof(options8)))) { + unaligned_block_textures_supported_ = bool(options8.UnalignedBlockTexturesSupported); + } + virtual_address_bits_per_resource_ = 0; + D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT virtual_address_support; + if (SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_GPU_VIRTUAL_ADDRESS_SUPPORT, + &virtual_address_support, + sizeof(virtual_address_support)))) { + virtual_address_bits_per_resource_ = + virtual_address_support.MaxGPUVirtualAddressBitsPerResource; + } + REXGPU_INFO( + "Direct3D 12 device and OS features:\n" + "* Max GPU virtual address bits per resource: {}\n" + "* Non-zeroed heap creation: {}\n" + "* Pixel-shader-specified stencil reference: {}\n" + "* Programmable sample positions: tier {}\n" + "* Rasterizer-ordered views: {}\n" + "* Resource binding: tier {}\n" + "* Tiled resources: tier {}\n" + "* Unaligned block-compressed textures: {}", + virtual_address_bits_per_resource_, + (heap_flag_create_not_zeroed_ & D3D12_HEAP_FLAG_CREATE_NOT_ZEROED) ? "yes" : "no", + ps_specified_stencil_reference_supported_ ? "yes" : "no", + uint32_t(programmable_sample_positions_tier_), + rasterizer_ordered_views_supported_ ? "yes" : "no", uint32_t(resource_binding_tier_), + uint32_t(tiled_resources_tier_), unaligned_block_textures_supported_ ? "yes" : "no"); + + // Get the graphics analysis interface, will silently fail if PIX is not + // attached. + pfn_dxgi_get_debug_interface1_(0, IID_PPV_ARGS(&graphics_analysis_)); + + return true; +} + +std::unique_ptr D3D12Provider::CreatePresenter( + Presenter::HostGpuLossCallback host_gpu_loss_callback) { + return D3D12Presenter::Create(host_gpu_loss_callback, *this); +} + +std::unique_ptr D3D12Provider::CreateImmediateDrawer() { + return D3D12ImmediateDrawer::Create(*this); +} + +} // namespace rex::ui::d3d12 diff --git a/src/ui/d3d12/d3d12_submission_tracker.cpp b/src/ui/d3d12/d3d12_submission_tracker.cpp new file mode 100644 index 0000000..50c721a --- /dev/null +++ b/src/ui/d3d12/d3d12_submission_tracker.cpp @@ -0,0 +1,118 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +namespace rex::ui::d3d12 { + +bool D3D12SubmissionTracker::Initialize(ID3D12Device* device, ID3D12CommandQueue* queue) { + Shutdown(); + fence_completion_event_ = CreateEvent(nullptr, FALSE, FALSE, nullptr); + if (!fence_completion_event_) { + REXLOG_ERROR("D3D12SubmissionTracker: Failed to create the fence completion event"); + Shutdown(); + return false; + } + // Continue where the tracker was left at the last shutdown. + if (FAILED(device->CreateFence(submission_current_ - 1, D3D12_FENCE_FLAG_NONE, + IID_PPV_ARGS(&fence_)))) { + REXLOG_ERROR("D3D12SubmissionTracker: Failed to create the fence"); + Shutdown(); + return false; + } + queue_ = queue; + submission_signal_queued_ = submission_current_ - 1; + return true; +} + +void D3D12SubmissionTracker::Shutdown() { + AwaitAllSubmissionsCompletion(); + queue_.Reset(); + fence_.Reset(); + if (fence_completion_event_) { + CloseHandle(fence_completion_event_); + fence_completion_event_ = nullptr; + } +} + +bool D3D12SubmissionTracker::AwaitSubmissionCompletion(UINT64 submission_index) { + if (!fence_ || !fence_completion_event_) { + // Not fully initialized yet or already shut down. + return false; + } + // The tracker itself can't give a submission index for a submission that + // hasn't even started being recorded yet, the client has provided a + // completely invalid value or has done overly optimistic math if such an + // index has been obtained somehow. + assert_true(submission_index <= submission_current_); + // Waiting for the current submission is fine if there was a refusal to + // submit, and the submission index wasn't incremented, but still need to + // release objects referenced in the dropped submission (while shutting down, + // for instance - in this case, waiting for the last successful submission, + // which could have also referenced the objects from the new submission - we + // can't know since the client has already overwritten its last usage index, + // would correctly ensure that GPU usage of the objects is not pending). + // Waiting for successful submissions, but failed signals, will result in a + // true race condition, however, but waiting for the closest successful signal + // is the best approximation - also retrying to signal in this case. + UINT64 fence_value = submission_index; + if (submission_index > submission_signal_queued_) { + TrySignalEnqueueing(); + fence_value = submission_signal_queued_; + } + if (fence_->GetCompletedValue() < fence_value) { + if (FAILED(fence_->SetEventOnCompletion(fence_value, fence_completion_event_))) { + return false; + } + if (WaitForSingleObject(fence_completion_event_, INFINITE) != WAIT_OBJECT_0) { + return false; + } + } + return fence_value == submission_index; +} + +void D3D12SubmissionTracker::SetQueue(ID3D12CommandQueue* new_queue) { + if (queue_.Get() == new_queue) { + return; + } + if (queue_) { + // Make sure the first signal on the new queue won't happen before the last + // signal, if pending, on the old one, as that would result first in too + // early submission completion indication, and then in rewinding. + AwaitAllSubmissionsCompletion(); + } + queue_ = new_queue; +} + +bool D3D12SubmissionTracker::NextSubmission() { + ++submission_current_; + assert_not_null(queue_); + assert_not_null(fence_); + return TrySignalEnqueueing(); +} + +bool D3D12SubmissionTracker::TrySignalEnqueueing() { + if (submission_signal_queued_ + 1 >= submission_current_) { + return true; + } + if (!queue_ || !fence_) { + return false; + } + if (FAILED(queue_->Signal(fence_.Get(), submission_current_ - 1))) { + return false; + } + submission_signal_queued_ = submission_current_ - 1; + return true; +} + +} // namespace rex::ui::d3d12 diff --git a/src/ui/d3d12/d3d12_upload_buffer_pool.cpp b/src/ui/d3d12/d3d12_upload_buffer_pool.cpp new file mode 100644 index 0000000..ade5dd2 --- /dev/null +++ b/src/ui/d3d12/d3d12_upload_buffer_pool.cpp @@ -0,0 +1,101 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +namespace rex::ui::d3d12 { + +// Align to D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT not to waste any space if +// it's smaller (the size of the heap backing the buffer will be aligned to +// D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT anyway). +D3D12UploadBufferPool::D3D12UploadBufferPool(const D3D12Provider& provider, size_t page_size) + : GraphicsUploadBufferPool( + rex::align(page_size, size_t(D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT))), + provider_(provider) {} + +uint8_t* D3D12UploadBufferPool::Request(uint64_t submission_index, size_t size, size_t alignment, + ID3D12Resource** buffer_out, size_t* offset_out, + D3D12_GPU_VIRTUAL_ADDRESS* gpu_address_out) { + size_t offset; + const D3D12Page* page = static_cast( + GraphicsUploadBufferPool::Request(submission_index, size, alignment, offset)); + if (!page) { + return nullptr; + } + if (buffer_out) { + *buffer_out = page->buffer_.Get(); + } + if (offset_out) { + *offset_out = offset; + } + if (gpu_address_out) { + *gpu_address_out = page->gpu_address_ + offset; + } + return reinterpret_cast(page->mapping_) + offset; +} + +uint8_t* D3D12UploadBufferPool::RequestPartial(uint64_t submission_index, size_t size, + size_t alignment, ID3D12Resource** buffer_out, + size_t* offset_out, size_t* size_out, + D3D12_GPU_VIRTUAL_ADDRESS* gpu_address_out) { + size_t offset, size_obtained; + const D3D12Page* page = static_cast(GraphicsUploadBufferPool::RequestPartial( + submission_index, size, alignment, offset, size_obtained)); + if (!page) { + return nullptr; + } + if (buffer_out) { + *buffer_out = page->buffer_.Get(); + } + if (offset_out) { + *offset_out = offset; + } + if (size_out) { + *size_out = size_obtained; + } + if (gpu_address_out) { + *gpu_address_out = page->gpu_address_ + offset; + } + return reinterpret_cast(page->mapping_) + offset; +} + +GraphicsUploadBufferPool::Page* D3D12UploadBufferPool::CreatePageImplementation() { + D3D12_RESOURCE_DESC buffer_desc; + util::FillBufferResourceDesc(buffer_desc, page_size_, D3D12_RESOURCE_FLAG_NONE); + Microsoft::WRL::ComPtr buffer; + if (FAILED(provider_.GetDevice()->CreateCommittedResource( + &util::kHeapPropertiesUpload, provider_.GetHeapFlagCreateNotZeroed(), &buffer_desc, + D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&buffer)))) { + REXLOG_ERROR("Failed to create a D3D upload buffer with {} bytes", page_size_); + return nullptr; + } + D3D12_RANGE read_range; + read_range.Begin = 0; + read_range.End = 0; + void* mapping; + if (FAILED(buffer->Map(0, &read_range, &mapping))) { + REXLOG_ERROR("Failed to map a D3D upload buffer with {} bytes", page_size_); + buffer->Release(); + return nullptr; + } + // Unmapping will be done implicitly when the resource is destroyed. + return new D3D12Page(buffer.Get(), mapping); +} + +D3D12UploadBufferPool::D3D12Page::D3D12Page(ID3D12Resource* buffer, void* mapping) + : buffer_(buffer), mapping_(mapping) { + gpu_address_ = buffer_->GetGPUVirtualAddress(); +} + +} // namespace rex::ui::d3d12 diff --git a/src/ui/d3d12/d3d12_util.cpp b/src/ui/d3d12/d3d12_util.cpp new file mode 100644 index 0000000..28b44a4 --- /dev/null +++ b/src/ui/d3d12/d3d12_util.cpp @@ -0,0 +1,117 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2018 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +namespace rex::ui::d3d12 { +namespace util { + +ID3D12RootSignature* CreateRootSignature(const D3D12Provider& provider, + const D3D12_ROOT_SIGNATURE_DESC& desc) { + ID3DBlob* blob; + ID3DBlob* error_blob = nullptr; + if (FAILED(provider.SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &blob, + &error_blob))) { + REXLOG_ERROR("Failed to serialize a root signature"); + if (error_blob != nullptr) { + REXLOG_ERROR("{}", reinterpret_cast(error_blob->GetBufferPointer())); + error_blob->Release(); + } + return nullptr; + } + if (error_blob != nullptr) { + error_blob->Release(); + } + ID3D12RootSignature* root_signature = nullptr; + provider.GetDevice()->CreateRootSignature(0, blob->GetBufferPointer(), blob->GetBufferSize(), + IID_PPV_ARGS(&root_signature)); + blob->Release(); + return root_signature; +} + +ID3D12PipelineState* CreateComputePipeline(ID3D12Device* device, const void* shader, + size_t shader_size, + ID3D12RootSignature* root_signature) { + D3D12_COMPUTE_PIPELINE_STATE_DESC desc; + desc.pRootSignature = root_signature; + desc.CS.pShaderBytecode = shader; + desc.CS.BytecodeLength = shader_size; + desc.NodeMask = 0; + desc.CachedPSO.pCachedBlob = nullptr; + desc.CachedPSO.CachedBlobSizeInBytes = 0; + desc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; + ID3D12PipelineState* pipeline = nullptr; + device->CreateComputePipelineState(&desc, IID_PPV_ARGS(&pipeline)); + return pipeline; +} + +void CreateBufferRawSRV(ID3D12Device* device, D3D12_CPU_DESCRIPTOR_HANDLE handle, + ID3D12Resource* buffer, uint32_t size, uint64_t offset) { + assert_false(size & (D3D12_RAW_UAV_SRV_BYTE_ALIGNMENT - 1)); + assert_false(offset & (D3D12_RAW_UAV_SRV_BYTE_ALIGNMENT - 1)); + D3D12_SHADER_RESOURCE_VIEW_DESC desc; + desc.Format = DXGI_FORMAT_R32_TYPELESS; + desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; + desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + desc.Buffer.FirstElement = offset >> 2; + desc.Buffer.NumElements = size >> 2; + desc.Buffer.StructureByteStride = 0; + desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW; + device->CreateShaderResourceView(buffer, &desc, handle); +} + +void CreateBufferRawUAV(ID3D12Device* device, D3D12_CPU_DESCRIPTOR_HANDLE handle, + ID3D12Resource* buffer, uint32_t size, uint64_t offset) { + assert_false(size & (D3D12_RAW_UAV_SRV_BYTE_ALIGNMENT - 1)); + assert_false(offset & (D3D12_RAW_UAV_SRV_BYTE_ALIGNMENT - 1)); + D3D12_UNORDERED_ACCESS_VIEW_DESC desc; + desc.Format = DXGI_FORMAT_R32_TYPELESS; + desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER; + desc.Buffer.FirstElement = offset >> 2; + desc.Buffer.NumElements = size >> 2; + desc.Buffer.StructureByteStride = 0; + desc.Buffer.CounterOffsetInBytes = 0; + desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW; + device->CreateUnorderedAccessView(buffer, nullptr, &desc, handle); +} + +void CreateBufferTypedSRV(ID3D12Device* device, D3D12_CPU_DESCRIPTOR_HANDLE handle, + ID3D12Resource* buffer, DXGI_FORMAT format, uint32_t num_elements, + uint64_t first_element) { + D3D12_SHADER_RESOURCE_VIEW_DESC desc; + desc.Format = format; + desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; + desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + desc.Buffer.FirstElement = first_element; + desc.Buffer.NumElements = num_elements; + desc.Buffer.StructureByteStride = 0; + desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE; + device->CreateShaderResourceView(buffer, &desc, handle); +} + +void CreateBufferTypedUAV(ID3D12Device* device, D3D12_CPU_DESCRIPTOR_HANDLE handle, + ID3D12Resource* buffer, DXGI_FORMAT format, uint32_t num_elements, + uint64_t first_element) { + D3D12_UNORDERED_ACCESS_VIEW_DESC desc; + desc.Format = format; + desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER; + desc.Buffer.FirstElement = first_element; + desc.Buffer.NumElements = num_elements; + desc.Buffer.StructureByteStride = 0; + desc.Buffer.CounterOffsetInBytes = 0; + desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE; + device->CreateUnorderedAccessView(buffer, nullptr, &desc, handle); +} + +} // namespace util +} // namespace rex::ui::d3d12 diff --git a/src/ui/graphics_upload_buffer_pool.cpp b/src/ui/graphics_upload_buffer_pool.cpp new file mode 100644 index 0000000..407498e --- /dev/null +++ b/src/ui/graphics_upload_buffer_pool.cpp @@ -0,0 +1,170 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include + +namespace rex { +namespace ui { + +GraphicsUploadBufferPool::~GraphicsUploadBufferPool() { + ClearCache(); +} + +void GraphicsUploadBufferPool::Reclaim(uint64_t completed_submission_index) { + while (submitted_first_) { + if (submitted_first_->last_submission_index_ > completed_submission_index) { + break; + } + if (writable_last_) { + writable_last_->next_ = submitted_first_; + } else { + writable_first_ = submitted_first_; + } + writable_last_ = submitted_first_; + submitted_first_ = submitted_first_->next_; + writable_last_->next_ = nullptr; + } + if (!submitted_first_) { + submitted_last_ = nullptr; + } +} + +void GraphicsUploadBufferPool::ChangeSubmissionTimeline() { + // Reclaim all submitted pages. + if (writable_last_) { + writable_last_->next_ = submitted_first_; + } else { + writable_first_ = submitted_first_; + } + writable_last_ = submitted_last_; + submitted_first_ = nullptr; + submitted_last_ = nullptr; + + // Mark all pages as never used yet in the new timeline. + Page* page = writable_first_; + while (page) { + page->last_submission_index_ = 0; + page = page->next_; + } +} + +void GraphicsUploadBufferPool::ClearCache() { + // Called from the destructor - must not call virtual functions here. + current_page_flushed_ = 0; + current_page_used_ = 0; + while (submitted_first_) { + Page* next_ = submitted_first_->next_; + delete submitted_first_; + submitted_first_ = next_; + } + submitted_last_ = nullptr; + while (writable_first_) { + Page* next_ = writable_first_->next_; + delete writable_first_; + writable_first_ = next_; + } + writable_last_ = nullptr; +} + +GraphicsUploadBufferPool::Page::~Page() {} + +void GraphicsUploadBufferPool::FlushWrites() { + if (current_page_flushed_ >= current_page_used_) { + return; + } + assert_not_null(writable_first_); + FlushPageWrites(writable_first_, current_page_flushed_, + current_page_used_ - current_page_flushed_); + current_page_flushed_ = current_page_used_; +} + +GraphicsUploadBufferPool::Page* GraphicsUploadBufferPool::Request(uint64_t submission_index, + size_t size, size_t alignment, + size_t& offset_out) { + alignment = std::max(alignment, size_t(1)); + assert_true(rex::is_pow2(alignment)); + size = rex::align(size, alignment); + assert_true(size <= page_size_); + if (size > page_size_) { + return nullptr; + } + assert_true(!current_page_used_ || submission_index >= writable_first_->last_submission_index_); + assert_true(!submitted_last_ || submission_index >= submitted_last_->last_submission_index_); + size_t current_page_used_aligned = rex::align(current_page_used_, alignment); + if (current_page_used_aligned + size > page_size_ || !writable_first_) { + // Start a new page if can't fit all the bytes or don't have an open page. + if (writable_first_) { + // Close the page that was current. + FlushWrites(); + if (submitted_last_) { + submitted_last_->next_ = writable_first_; + } else { + submitted_first_ = writable_first_; + } + submitted_last_ = writable_first_; + writable_first_ = writable_first_->next_; + submitted_last_->next_ = nullptr; + if (!writable_first_) { + writable_last_ = nullptr; + } + } + if (!writable_first_) { + // Create a new page if none available. + writable_first_ = CreatePageImplementation(); + if (!writable_first_) { + // Failed to create. + return nullptr; + } + writable_first_->last_submission_index_ = submission_index; + writable_first_->next_ = nullptr; + writable_last_ = writable_first_; + // After CreatePageImplementation (more specifically, the first successful + // call), page_size_ may grow - but this doesn't matter here. + } + current_page_used_ = 0; + current_page_used_aligned = 0; + current_page_flushed_ = 0; + } + writable_first_->last_submission_index_ = submission_index; + offset_out = current_page_used_aligned; + current_page_used_ = current_page_used_aligned + size; + return writable_first_; +} + +GraphicsUploadBufferPool::Page* GraphicsUploadBufferPool::RequestPartial(uint64_t submission_index, + size_t size, + size_t alignment, + size_t& offset_out, + size_t& size_out) { + alignment = std::max(alignment, size_t(1)); + assert_true(rex::is_pow2(alignment)); + size = rex::align(size, alignment); + size = std::min(size, page_size_); + size_t current_page_used_aligned = rex::align(current_page_used_, alignment); + if (current_page_used_aligned + alignment <= page_size_) { + size = std::min(size, (page_size_ - current_page_used_aligned) & ~(alignment - 1)); + } + Page* page = Request(submission_index, size, alignment, offset_out); + if (!page) { + return nullptr; + } + size_out = size; + return page; +} + +void GraphicsUploadBufferPool::FlushPageWrites(Page* page, size_t offset, size_t size) {} + +} // namespace ui +} // namespace rex diff --git a/src/ui/graphics_util.cpp b/src/ui/graphics_util.cpp new file mode 100644 index 0000000..793fcfa --- /dev/null +++ b/src/ui/graphics_util.cpp @@ -0,0 +1,65 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include + +namespace rex { +namespace ui { + +int32_t FloatToD3D11Fixed16p8(float f32) { + // https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#3.2.4.1%20FLOAT%20-%3E%20Fixed%20Point%20Integer + // Early exit tests. + // n == NaN || n.unbiasedExponent < -f-1 -> 0 . 0 + if (!(std::abs(f32) >= 1.0f / 512.0f)) { + return 0; + } + // n >= (2^(i-1)-2^-f) -> 2^(i-1)-1 . 2^f-1 + if (f32 >= 32768.0f - 1.0f / 256.0f) { + return (1 << 23) - 1; + } + // n <= -2^(i-1) -> -2^(i-1) . 0 + if (f32 <= -32768.0f) { + return -32768 * 256; + } + uint32_t f32_bits = *reinterpret_cast(&f32); + // Copy float32 mantissa bits [22:0] into corresponding bits [22:0] of a + // result buffer that has at least 24 bits total storage (before reaching + // rounding step further below). This includes one bit for the hidden 1. + // Set bit [23] (float32 hidden bit). + // Clear bits [31:24]. + union { + int32_t s; + uint32_t u; + } result; + result.u = (f32_bits & ((1 << 23) - 1)) | (1 << 23); + // If the sign bit is set in the float32 number (negative), then take the 2's + // component of the entire set of bits. + if ((f32_bits >> 31) != 0) { + result.s = -result.s; + } + // Final calculation: extraBits = (mantissa - f) - n.unbiasedExponent + // (guaranteed to be >= 0). + int32_t exponent = int32_t((f32_bits >> 23) & 255) - 127; + uint32_t extra_bits = uint32_t(15 - exponent); + if (extra_bits) { + // Round the 32-bit value to a decimal that is extraBits to the left of + // the LSB end, using nearest-even. + result.u += (1 << (extra_bits - 1)) - 1 + ((result.u >> extra_bits) & 1); + // Shift right by extraBits (sign extending). + result.s >>= extra_bits; + } + return result.s; +} + +} // namespace ui +} // namespace rex diff --git a/src/ui/imgui_dialog.cpp b/src/ui/imgui_dialog.cpp new file mode 100644 index 0000000..20cec48 --- /dev/null +++ b/src/ui/imgui_dialog.cpp @@ -0,0 +1,91 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include + +namespace rex { +namespace ui { + +ImGuiDialog::ImGuiDialog(ImGuiDrawer* imgui_drawer) : imgui_drawer_(imgui_drawer) { + imgui_drawer_->AddDialog(this); +} + +ImGuiDialog::~ImGuiDialog() { + imgui_drawer_->RemoveDialog(this); + for (auto fence : waiting_fences_) { + fence->Signal(); + } +} + +void ImGuiDialog::Then(rex::thread::Fence* fence) { + waiting_fences_.push_back(fence); +} + +void ImGuiDialog::Close() { + has_close_pending_ = true; +} + +ImGuiIO& ImGuiDialog::GetIO() { + return imgui_drawer()->GetIO(); +} + +void ImGuiDialog::Draw() { + // Draw UI. + OnDraw(GetIO()); + + // Check to see if the UI closed itself and needs to be deleted. + if (has_close_pending_) { + OnClose(); + delete this; + } +} + +class MessageBoxDialog final : public ImGuiDialog { + public: + MessageBoxDialog(ImGuiDrawer* imgui_drawer, std::string title, std::string body) + : ImGuiDialog(imgui_drawer), title_(std::move(title)), body_(std::move(body)) {} + + void OnDraw(ImGuiIO& io) override { + if (!has_opened_) { + ImGui::OpenPopup(title_.c_str()); + has_opened_ = true; + } + if (ImGui::BeginPopupModal(title_.c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { + char* text = const_cast(body_.c_str()); + ImGui::InputTextMultiline("##body", text, body_.size(), ImVec2(600, 0), + ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_ReadOnly); + if (ImGui::Button("OK")) { + ImGui::CloseCurrentPopup(); + Close(); + } + ImGui::EndPopup(); + } else { + Close(); + } + } + + private: + bool has_opened_ = false; + std::string title_; + std::string body_; +}; + +ImGuiDialog* ImGuiDialog::ShowMessageBox(ImGuiDrawer* imgui_drawer, std::string title, + std::string body) { + return new MessageBoxDialog(imgui_drawer, std::move(title), std::move(body)); +} + +} // namespace ui +} // namespace rex diff --git a/src/ui/imgui_drawer.cpp b/src/ui/imgui_drawer.cpp new file mode 100644 index 0000000..d9364b5 --- /dev/null +++ b/src/ui/imgui_drawer.cpp @@ -0,0 +1,653 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace rex { +namespace ui { + +// File: 'ProggyTiny.ttf' (35656 bytes) +// Exported using binary_to_compressed_c.cpp +const char kProggyTinyCompressedDataBase85[10950 + 1] = + R"(7])#######LJg=:'/###[),##/l:$#Q6>##5[n42>#/e>11NNV=Bv(*:.F?uu#(gRU.o0XGH`$vhLG1hxt9?W`#,5LsCm<]vf.r$<$u7k;hb';9C'mm?]XmKVeU2cD4Eo3R/[WB]b(MC;$jPfY.;h^`ItLw6Lh2TlS+f-s$o6Q#X14,MZ[Z##UE31#J&###Q-F%b>-nw'w++GM-]u)Nx0#,M[LH>#Zsvx+6O_^#l(FS7f`C_&E?g'&kcg-6Y,/;M#@2G`Bf%=(`5LF%fv$8#,+[0#veg>$EB&sQSSDgEKnIS7EM9>Z,KO_/78pQWqJE#$nt-4$F&###E`J&#uU'B#*9D6N;@;=-:U>hL&Y5<-%A9;-Y+Z&P^)9##._L&#awnk+ib*.-Z06X1>LcA#'rB#$o4ve6)fbA#kt72LN.72L=CG&#*iXZWt(F,>>#_03:)`(@2L@^x4Sj2B@PN#[xO8QkJNRR()N@#f.Mr#)t-L5FGMm8#&#/2TkLi3n##-/5##MwQ0#EB^1v&ols-)-mTMQ@-##qlQ08*lkA#aNRV7KRYML%4_s[kNa=_0Z%7Nd4[3#S@1g_/v`W#'`Fm#B$(Q#n$oqvc$&Svv$`,TM%,PS=%OeJE%s+]l%A=Fe%']K#&7aW5&O-Nd&q&>^&GZs1'w.bA'c>u>'B-1R'%gJ.(t1tx'_jH4(iNdc(GJ*X(l`uf(^Wqr(-=Jx(=[%5)')Gb)$1vV)57Vk),8n<*BYl/*qs%]*OI5R*Fkgb*H<+q*TQv(+Xak6+?C@H+5SaT+o2VhLKd)k+i$xl+4YW=,sJd,,C*oT,Eb:K,mSPgLsF8e,Z$=rJ[<5J`E:E&#k&bV7uVco]JfaJ2M'8L#xArJ27FJx?Zgt%uov/vZ@?Gj:Kl;,jo%*K;AL7L#7G'3/J(*t.5xO+/0r+N/%ipJ/Bq_k/A>4Y/^iwl/%K:K0[HW=04D'N0wQq_00Kjt0]NJ21?p?d1T:=Y1e*&i1HLr@28x*:29A[L2Mpd%3pFIp2igO+3aXRX3M#PN3uY$d37p2=4c,s54.3SI4v0iw4JqN65G$S*5rh<65ld7E5.IRt5.f-16A/U(6IoFR6Nj7I6Y3i[6>s#s6EF=P90>=W6-Mc##=(V$#MXI%#^3=&#nd0'#(?$(#8pm(#HJa)#X%T*#iUG+##1;,#3b.-#C#$i0B#'2[0#s6aW-AS*wp1W,/$-pZw'%]#AOC+[]O>X`=-9_cHMN8r&MsKH##77N/)8r_G3=^x]O].[]-/(pI$^=Kn<00k-$t`%/LDK5x76,G&#$or>I?v+sQ;koJM>,CS-14,dM,Hv<-cLH?01FQ*NGx0='H9V&#;Rov$8ooX_i7d;)]]>R*sVi.Lt3NM-$@dXM:uSGMDn%>-30[b's6Ct_.39I$3#bo7;FP&#YKh9&#d)KE$tok&L1tY-sTf2LP]K&s9L]u-c4Au9*A>-<'3UN-PZL-NIV+85p0eZ3:.Q8bj1S*(h)Z$lel,MX_CH-.Nck-(veHZwdJe$ej+_frio0cKB$HFtRZ>#DiaWqFq7Q84okA#tiUi'Qumo%<]Xl8As(?@iLT[%tDn8gsDGA#hDu-$+HM3X_?@_8:N+q7v3G&#a7>0H3=t-?ZKm.HK+U58E/.`AcQV,tUd+Z-$fQ-Haotl8Zx2Fn)&UQ8c6E&docd.%&^R]u)x:p.N*wIL8+fsrk+5###>jq:9%/v2;f`?J8fDrG%fmWw9gl'ENgjG:,EC%<-WW5x'6eaR86kf2`5alP&u]::.'a0i);c)3LN3wK#gZb19YvMa,?IggL3xoFMTK_P85.)0xLp7gw]m_oM++.`=JfLm)1#.gGKd4N^@N%M'Np7ZO:k)VTqt%EO`gurjj;-0r%;%I'M,W-(hdnXP4bA,%GLp75c`QUWh<_&.ZoDuWmLCVJ+7:P&#Wj7n$+8sb<:+R.Qx7m<-T`&0%3TK<-h.oN'eSYW-g7D^6mu7Rc;:cIH%5hWHX9uCq'RC/2'GZZ(=:.$ekS>k((WP_=-,8dT%;]DeHjNJ'HOsgj-vUa$UFQO68Ic+k2HwQ'(0Kgn8V=:'_5'r1GX`4;kNbkh&@-HCp[+c+Z68=Z9:BM#Jn$R+0Au6A)K:YXr1d^8ILE65V'#Y_%n8Mc`3r:>H9%PMhj9GVCh3F3wm81EG&#,`**<3AEYLN1pA#>q0p&(^?@'Bl+&>klY'vO%co7juS^d)a#9%=&m9.m`0i)rQNm8*GF]uI9+W-wmw5_L07xLC8qT;`9%90i^Gx'abQp7)>5wLq3n0#/U0V8+B^G3%3,0:3wR]4fJ(d%2N9Z-r_&7rjQS,sM;n9g#>ve^2SK)71JTRxD)o0@1wWA2#E;xov>0f^-QQQYVBeT+?-7kMD5d0B#QZAW0:ZjUK[OZi&61L&#>CCj;r]/RLH'(j>+$P-R9bF69`%f@[p-JZ*.hnp7;-ge$NSi?-qx8;-V]Z##,B?nrCn,)'(Q%a-sI^W&9'i&#SrRfL`Zwe%k.jA,xf:-%$+:t>-v^)'%of?pg=`N_*o'w)3(ip7XqF]uN-Fj9l=K/+sAH^*I=5qBCRt-,T163BO%ov7%,sb&T=XaZ$(#GM0#Qp%a]Cs7HNbxum=g@>wb%?7N:Fk'0PYRhUv-tLWr+P(lLM/:9N*H=KRZT'Pf2;.@2<)#pVl1MwLk0&;tUAuP3w.Le.]T/*Mc##O->>#9NCU.73rI3ZbA;%^xT3BS2L#$uLjf%53Kt-2SJMBFZ.m0cmcPS)aX%(c]Yg<^[G6;$W(8*2&$X->B+kk^$D'8E@P&#I-nT'u5pm8u;Be=AJ8F-T6po)A:&?-CPcd$rDtJjLUsv'7Hx_onecgHu78k:D#]4;tb)$-UHAm8h;2c>8J<@.(W=p&oVoY?&@+w7-)ri'bb=+X:#29.*DW/tNqT&QAl29xj+AuD:*+lnW]D,3l6<-PX9YYw)vX&=WuT8H=AbIs[`Am2xcW-jqbn*cZV%_t/Z&QpvGJ(i2.^==iWDurfn:Ml;-##/-U%)x$+1:lROdt*mpM=i4/)Zdr'H'P[N>-EKHl$hUvf:P'Q3`u*IM&uZA39^0F[pUB+n8hq+?I`L'-)2>Cq71g/6(?(oR&iBRiLr7w;-[HuL3u6e2&V:QjBJ:9iuF8.a##PHT<-.4r1&,qBE#LK,W-fIO4kX@%%#tUB#$57>uHN^KeX'-cD)d.s*#P2+c&#ok:/:3l(RsPD###2d#<-%,.t$5@HgL/mu<+PXhv[Bgb4)GO;eMZQMr?,tXvIIe;t-P2l?G2j1v^)3l$'mEa68K1l@7.`V[GG#)C]Y&f;]?OM>&x]i.L(/5##BO+k9Xp0B#NS9>#+7E<-d]nl$Yw6v9YK*6(sxGug]oko$_'l_-Ai%RMq<&_8o2@2L@@AS)c8(<-c&r]$J9oq7g?(m9LIS;H-)KfF@qVI*^ACO9fKc'&6k/q7RD&Fe&*l2LSQUV$vC#W-lwf&v:'n]%D4xVH4&(^#0jg<-@r'29EQT_6Gx)Q&':nKC>s6.6*;X^ZH.->#>atJC6`hJ>NjO?-^5l-8Tj72LFIRp7,:-.wruM;q0)(YHWp7@i('#'2,##8ZDKM9dvR3kYKd&#V(f+MR?xK#liDE<[/RM3M7-##1na_$+q)'%xheG*DsXbN^BxK#R90%'vrIfL.r&/LT*=(&A's2;O56>>/jsX_Z_+/(NSi.L>jEG']iNUR238^&?MR49neA>.M5N=h#=eq:T?k)/:;SF&#;k-gLXL0e,e6JdDNHj?@ihvi&wNT-;6`E.FAl):%3WK<-:EI+'^([:.+lQS%?_,c<8L[W&T7-##`QHXA=(xn&Yqbf(kge2-g)[OksHT*bm+Do5IM<_jILK4Pv'=u5a*E#Z^FHmn),Dheq.+Sl##04kWoAl[W]rYHI%+d@a-.dm<%#1[,MtRBt)O(35&>-f;-J=.g:(xp/)U]W]+RCwgCbE0#Aes-h%vr_BF0;=K34Yv',/GoEYQQ-U&5&Aw>]ewGt?k,l$1oR8VCkF<%+nTH4Z8f%/M&dQ/(2###S`%/L*cS5JX&V_$iac=(LG:;$ZcRPA.$+bHU7-###c7^O1[qS%)S#qT=lI(#=,o_Q.^r#(w1I<-+PK`&,o'^#GhsWQt6j(,]_##IN]p7i4mFuXih@-t=58.1&>uu$&h2`2H:%'T):wPGJuD%5DJTIUXbA#pvRdM=WcO-uhKj%0ej?Ppruu9k,h%cwfi'B.x`=Tg^d4%45GM@iZQ'YGHP9(MGGGvbG3jZJp7FAeEP&ePL'8k8k91/D?[-7(&(m@?q7kdH)cDfYN)@9TDSe;DG)uQh&#k+'p74N)^ohl=,'';[P9_kisBjgU,&g>Ok2=4'K%cl@Nii)3q-_.1U9,.QL/2&>uuF*^TVA7Bs&;W36AZ(j'muJG4M_CpO4)0kNeFKG2V?'jkgNvkK<&MQU+<[xKVaY>/T@&Jp'HtA$a&5U&R8bs:RWYiYeQu4k(NgxE$%X6V&#X+3O-u_dQ8/_-ldRf1W-2dpGe*E^r7d>S^JisoC%s`^68r*d;))C[p7W?[6OfId2P&;Hr7cpB#$X8-l93rg996Nb4):v0<-Y7`[eEdoW*l/xNN9<&v,%nra*-?078.F8o8aP+Au]ZX2L:1Bn*fuW1;N&&3M5U#x'-KA$ZAf0YS&_;AL;>g6pgV==5A6R.db1Wbs'MC9-)5u:ENe7-##H:O&=$^]712c&gL,%,cM+4(5SmwUF-x-*j0c-G(-9Y`N*$0_k2ece`*#JdQ8Fk=9W'&%kCjYeaHC@nL-$[d;B*<^#DuHQNYF#>Q8L*fW]8cJX/,CWR83+pVooXXk'1HCL:6I%T(`2VY(An&R8?uN]'WLJM'$/*JLXm@8JhS](6l0tv'x06oDXFC'%=7CP8fCKetbqp0%;=0iC/kRkrjK5x'qtD_Or/9x:VWF&#LW`<04=q0E8/c&hItt'a8J0)kY#Q8nnV78o=6UT`-1t%-FuN:xA1J[Oq`p77%72L9$2-'[qp)mH^*[eL]u/o(HF0iu.-vwoW_wn=O:[3NPcDh)Zn)ex[T%LaP-VC%f$36t1CvSw,X>^>Z4q=Z58]evqT5.xP33h839>So>InZb%=w=>F%$Mdm_FjSEEwGJMN3B,-(b@mHM;uFr$r&V@-Vp;m$bF6XJbM0-'-PgQJ=Z.lBE?=x>YBPX9N3?&+0)xm'wQsH$K]MP9cmv9glREr(>=n-k;/6t$r]2@-Ips&d-8oS@pb5r@lwcQ:aum))u=KkrVv[n>Lu,@RvlOE.^Puk;v4[+9.2A2LrPn'&]/?pg&.Rq$9-vc6BUpD*8[?:BmMq*9.HFt_QSl##O->>#b7278#r%34A$;M%+=hlTsVPp'X8N&Zu/To%mDh:.,umo%5VIl90wn5F9;_OFJ?=?JbjcX($^)Rj2vao7W9Udkr[F%8:@(4F@5W5_oHOG%M4Y@G:P+JGUsRA%UeO-;Tr+OOHi8i:F$aC=K@82L(__3:>H-g)S65e;B@:xnT_x0+x,2N:rmL4)VtH#)NF7WAs,Zx'uQpEU78_TX=?1s?cZYlBd'BugDAVB-vlc_fV5gc*s&Y9.;25##F7,W.P'OC&aTZ`*65m_&WRJM'vGl_&==(S*2)7`&27@U1G^4?-:_`=-+()t-c'ChLGF%q.0l:$#:T__&Pi68%0xi_&Zh+/(77j_&JWoF.V735&S)[R*:xFR*K5>>#`bW-?4Ne_&6Ne_&6Ne_&lM4;-xCJcM6X;uM6X;uM(.a..^2TkL%oR(#;u.T%eAr%4tJ8&><1=GHZ_+m9/#H1F^R#SC#*N=BA9(D?v[UiFk-c/>tBc/>`9IL2a)Ph#WL](#O:Jr1Btu+#TH4.#a5C/#vS3rL<1^NMowY.##t6qLw`5oL_R#.#2HwqLUwXrLp/w+#ALx>-1xRu-'*IqL@KCsLB@]qL]cYs-dpao7Om#K)l?1?%;LuDNH@H>#/X-TI(;P>#,Gc>#0Su>#4`1?#8lC?#xL$#B.`$#F:r$#JF.%#NR@%#R_R%#Vke%#Zww%#_-4TR-&Mglr-k'MS.o?.5/sWel/wpEM0%3'/1)K^f1-d>G21&v(35>V`39V7A4=onx4A1OY5EI0;6Ibgr6M$HS7Q<)58UT`l8Ym@M9^/x.:bGXf:f`9G;jxp((F+;?,_br?0wBS@49$5A8QZlAQ#]V-kw:8.o9ro.sQRP/wj320%-ki0)EKJ1-^,,21vcc258DD39P%&4=i[]4A+=>5ECtu5I[TV6Mt587Q6mo7tB'DW-fJcMxUq4S=Gj(N=eC]OkKu=Yc/;ip3#T(j:6s7R`?U+rH#5PSpL7]bIFtIqmW:YYdQqFrhod(WEH1VdDMSrZ>vViBn_t.CTp;JCbMMrdku.Sek+f4ft(XfCsOFlfOuo7[&+T.q6jHPA$HHPB*QHPC0ZHPD6dHPD3Q-P_aQL2RemoveInputListener(this); + if (internal_state_) { + ImGui::SetCurrentContext(internal_state_); + if (touch_pointer_id_ == TouchEvent::kPointerIDNone && ImGui::IsAnyMouseDown()) { + window_->ReleaseMouse(); + } + } + } + if (internal_state_) { + ImGui::DestroyContext(internal_state_); + internal_state_ = nullptr; + } +} + +void ImGuiDrawer::AddDialog(ImGuiDialog* dialog) { + assert_not_null(dialog); + // Check if already added. + if (std::find(dialogs_.cbegin(), dialogs_.cend(), dialog) != dialogs_.cend()) { + return; + } + if (dialogs_.empty() && !IsDrawingDialogs()) { + // First dialog added. !IsDrawingDialogs() is also checked because in a + // situation of removing the only dialog, then adding a dialog, from within + // a dialog's Draw function, re-registering the ImGuiDrawer may result in + // ImGui being drawn multiple times in the current frame. + window_->AddInputListener(this, z_order_); + if (presenter_) { + presenter_->AddUIDrawerFromUIThread(this, z_order_); + } + } + dialogs_.push_back(dialog); +} + +void ImGuiDrawer::RemoveDialog(ImGuiDialog* dialog) { + assert_not_null(dialog); + auto it = std::find(dialogs_.cbegin(), dialogs_.cend(), dialog); + if (it == dialogs_.cend()) { + return; + } + if (IsDrawingDialogs()) { + // Actualize the next dialog index after the erasure from the vector. + size_t existing_index = size_t(std::distance(dialogs_.cbegin(), it)); + if (dialog_loop_next_index_ > existing_index) { + --dialog_loop_next_index_; + } + } + dialogs_.erase(it); + DetachIfLastDialogRemoved(); +} + +void ImGuiDrawer::Initialize() { + // Setup ImGui internal state. + // This will give us state we can swap to the ImGui globals when in use. + internal_state_ = ImGui::CreateContext(); + ImGui::SetCurrentContext(internal_state_); + + auto& io = ImGui::GetIO(); + + // TODO(gibbed): disable imgui.ini saving for now, + // imgui assumes paths are char* so we can't throw a good path at it on + // Windows. + io.IniFilename = nullptr; + + // Setup the font glyphs. + ImFontConfig font_config; + font_config.OversampleH = font_config.OversampleV = 1; + font_config.PixelSnapH = true; + static const ImWchar font_glyph_ranges[] = { + 0x0020, + 0x00FF, // Basic Latin + Latin Supplement + 0, + }; + io.Fonts->AddFontFromMemoryCompressedBase85TTF(kProggyTinyCompressedDataBase85, 10.0f, + &font_config, font_glyph_ranges); + +#if REX_PLATFORM_WIN32 + // TODO(benvanik): jp font on other platforms? + // https://github.com/Koruri/kibitaki looks really good, but is 1.5MiB. + const char* jp_font_path = "C:\\Windows\\Fonts\\msgothic.ttc"; + if (std::filesystem::exists(jp_font_path)) { + ImFontConfig jp_font_config; + jp_font_config.MergeMode = true; + jp_font_config.OversampleH = jp_font_config.OversampleV = 1; + jp_font_config.PixelSnapH = true; + jp_font_config.FontNo = 0; + io.Fonts->AddFontFromFileTTF(jp_font_path, 12.0f, &jp_font_config, + io.Fonts->GetGlyphRangesJapanese()); + } else { + REXLOG_WARN("Unable to load Japanese font; JP characters will be boxes"); + } +#endif + + if (font_setup_) { + font_setup_(io.Fonts); + } + + auto& style = ImGui::GetStyle(); + style.ScrollbarRounding = 0; + style.WindowRounding = 0; + style.TabRounding = 0; + style.Colors[ImGuiCol_Text] = ImVec4(0.89f, 0.90f, 0.90f, 1.00f); + style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); + style.Colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.06f, 0.00f, 1.00f); + style.Colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + style.Colors[ImGuiCol_Border] = ImVec4(0.00f, 0.35f, 0.00f, 1.00f); + style.Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + style.Colors[ImGuiCol_FrameBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.30f); + style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.90f, 0.80f, 0.80f, 0.40f); + style.Colors[ImGuiCol_FrameBgActive] = ImVec4(0.90f, 0.65f, 0.65f, 0.45f); + style.Colors[ImGuiCol_TitleBg] = ImVec4(0.00f, 0.40f, 0.00f, 1.00f); + style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.33f, 0.00f, 1.00f); + style.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.16f, 0.65f, 0.00f, 1.00f); + style.Colors[ImGuiCol_MenuBarBg] = ImVec4(0.00f, 0.35f, 0.00f, 1.00f); + style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.00f, 0.40f, 0.11f, 0.59f); + style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.00f, 0.68f, 0.00f, 0.68f); + style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.00f, 1.00f, 0.15f, 0.62f); + style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.00f, 0.91f, 0.09f, 0.40f); + style.Colors[ImGuiCol_PopupBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.99f); + style.Colors[ImGuiCol_CheckMark] = ImVec4(0.74f, 0.90f, 0.72f, 0.50f); + style.Colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); + style.Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.34f, 0.75f, 0.11f, 1.00f); + style.Colors[ImGuiCol_Button] = ImVec4(0.15f, 0.56f, 0.11f, 0.60f); + style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.19f, 0.72f, 0.09f, 1.00f); + style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.19f, 0.60f, 0.09f, 1.00f); + style.Colors[ImGuiCol_Header] = ImVec4(0.00f, 0.40f, 0.00f, 0.71f); + style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.60f, 0.26f, 0.80f); + style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.00f, 0.75f, 0.00f, 0.80f); + style.Colors[ImGuiCol_Separator] = ImVec4(0.00f, 0.35f, 0.00f, 1.00f); + style.Colors[ImGuiCol_SeparatorHovered] = ImVec4(0.36f, 0.89f, 0.38f, 1.00f); + style.Colors[ImGuiCol_SeparatorActive] = ImVec4(0.13f, 0.50f, 0.11f, 1.00f); + style.Colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); + style.Colors[ImGuiCol_ResizeGripHovered] = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); + style.Colors[ImGuiCol_ResizeGripActive] = ImVec4(1.00f, 1.00f, 1.00f, 0.90f); + style.Colors[ImGuiCol_Tab] = style.Colors[ImGuiCol_Button]; + style.Colors[ImGuiCol_TabHovered] = style.Colors[ImGuiCol_ButtonHovered]; + style.Colors[ImGuiCol_TabActive] = style.Colors[ImGuiCol_ButtonActive]; + style.Colors[ImGuiCol_TabUnfocused] = style.Colors[ImGuiCol_FrameBg]; + style.Colors[ImGuiCol_TabUnfocusedActive] = style.Colors[ImGuiCol_FrameBgHovered]; + style.Colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + style.Colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + style.Colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + style.Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); + style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 1.00f, 0.00f, 0.21f); + style.Colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); + + frame_time_tick_frequency_ = double(rex::chrono::Clock::QueryHostTickFrequency()); + last_frame_time_ticks_ = rex::chrono::Clock::QueryHostTickCount(); + + touch_pointer_id_ = TouchEvent::kPointerIDNone; + reset_mouse_position_after_next_frame_ = false; +} + +std::optional ImGuiDrawer::VirtualKeyToImGuiKey(VirtualKey vkey) { + static const std::map map = { + // Navigation + {ui::VirtualKey::kTab, ImGuiKey_Tab}, + {ui::VirtualKey::kLeft, ImGuiKey_LeftArrow}, + {ui::VirtualKey::kRight, ImGuiKey_RightArrow}, + {ui::VirtualKey::kUp, ImGuiKey_UpArrow}, + {ui::VirtualKey::kDown, ImGuiKey_DownArrow}, + {ui::VirtualKey::kHome, ImGuiKey_Home}, + {ui::VirtualKey::kEnd, ImGuiKey_End}, + {ui::VirtualKey::kPrior, ImGuiKey_PageUp}, + {ui::VirtualKey::kNext, ImGuiKey_PageDown}, + {ui::VirtualKey::kInsert, ImGuiKey_Insert}, + {ui::VirtualKey::kDelete, ImGuiKey_Delete}, + {ui::VirtualKey::kBack, ImGuiKey_Backspace}, + {ui::VirtualKey::kReturn, ImGuiKey_Enter}, + {ui::VirtualKey::kEscape, ImGuiKey_Escape}, + {ui::VirtualKey::kSpace, ImGuiKey_Space}, + // Letters + {ui::VirtualKey::kA, ImGuiKey_A}, + {ui::VirtualKey::kB, ImGuiKey_B}, + {ui::VirtualKey::kC, ImGuiKey_C}, + {ui::VirtualKey::kD, ImGuiKey_D}, + {ui::VirtualKey::kE, ImGuiKey_E}, + {ui::VirtualKey::kF, ImGuiKey_F}, + {ui::VirtualKey::kG, ImGuiKey_G}, + {ui::VirtualKey::kH, ImGuiKey_H}, + {ui::VirtualKey::kI, ImGuiKey_I}, + {ui::VirtualKey::kJ, ImGuiKey_J}, + {ui::VirtualKey::kK, ImGuiKey_K}, + {ui::VirtualKey::kL, ImGuiKey_L}, + {ui::VirtualKey::kM, ImGuiKey_M}, + {ui::VirtualKey::kN, ImGuiKey_N}, + {ui::VirtualKey::kO, ImGuiKey_O}, + {ui::VirtualKey::kP, ImGuiKey_P}, + {ui::VirtualKey::kQ, ImGuiKey_Q}, + {ui::VirtualKey::kR, ImGuiKey_R}, + {ui::VirtualKey::kS, ImGuiKey_S}, + {ui::VirtualKey::kT, ImGuiKey_T}, + {ui::VirtualKey::kU, ImGuiKey_U}, + {ui::VirtualKey::kV, ImGuiKey_V}, + {ui::VirtualKey::kW, ImGuiKey_W}, + {ui::VirtualKey::kX, ImGuiKey_X}, + {ui::VirtualKey::kY, ImGuiKey_Y}, + {ui::VirtualKey::kZ, ImGuiKey_Z}, + // Digits + {ui::VirtualKey::k0, ImGuiKey_0}, + {ui::VirtualKey::k1, ImGuiKey_1}, + {ui::VirtualKey::k2, ImGuiKey_2}, + {ui::VirtualKey::k3, ImGuiKey_3}, + {ui::VirtualKey::k4, ImGuiKey_4}, + {ui::VirtualKey::k5, ImGuiKey_5}, + {ui::VirtualKey::k6, ImGuiKey_6}, + {ui::VirtualKey::k7, ImGuiKey_7}, + {ui::VirtualKey::k8, ImGuiKey_8}, + {ui::VirtualKey::k9, ImGuiKey_9}, + // Function keys + {ui::VirtualKey::kF1, ImGuiKey_F1}, + {ui::VirtualKey::kF2, ImGuiKey_F2}, + {ui::VirtualKey::kF3, ImGuiKey_F3}, + {ui::VirtualKey::kF4, ImGuiKey_F4}, + {ui::VirtualKey::kF5, ImGuiKey_F5}, + {ui::VirtualKey::kF6, ImGuiKey_F6}, + {ui::VirtualKey::kF7, ImGuiKey_F7}, + {ui::VirtualKey::kF8, ImGuiKey_F8}, + {ui::VirtualKey::kF9, ImGuiKey_F9}, + {ui::VirtualKey::kF10, ImGuiKey_F10}, + {ui::VirtualKey::kF11, ImGuiKey_F11}, + {ui::VirtualKey::kF12, ImGuiKey_F12}, + // Modifiers + {ui::VirtualKey::kShift, ImGuiKey_LeftShift}, + {ui::VirtualKey::kControl, ImGuiKey_LeftCtrl}, + {ui::VirtualKey::kMenu, ImGuiKey_LeftAlt}, + {ui::VirtualKey::kCapital, ImGuiKey_CapsLock}, + {ui::VirtualKey::kNumLock, ImGuiKey_NumLock}, + {ui::VirtualKey::kScroll, ImGuiKey_ScrollLock}, + {ui::VirtualKey::kSnapshot, ImGuiKey_PrintScreen}, + {ui::VirtualKey::kPause, ImGuiKey_Pause}, + // OEM keys + {ui::VirtualKey::kOem3, ImGuiKey_GraveAccent}, + {ui::VirtualKey::kOemMinus, ImGuiKey_Minus}, + {ui::VirtualKey::kOemPlus, ImGuiKey_Equal}, + {ui::VirtualKey::kOem4, ImGuiKey_LeftBracket}, + {ui::VirtualKey::kOem6, ImGuiKey_RightBracket}, + {ui::VirtualKey::kOem5, ImGuiKey_Backslash}, + {ui::VirtualKey::kOem1, ImGuiKey_Semicolon}, + {ui::VirtualKey::kOem7, ImGuiKey_Apostrophe}, + {ui::VirtualKey::kOemComma, ImGuiKey_Comma}, + {ui::VirtualKey::kOemPeriod, ImGuiKey_Period}, + {ui::VirtualKey::kOem2, ImGuiKey_Slash}, + // Numpad + {ui::VirtualKey::kNumpad0, ImGuiKey_Keypad0}, + {ui::VirtualKey::kNumpad1, ImGuiKey_Keypad1}, + {ui::VirtualKey::kNumpad2, ImGuiKey_Keypad2}, + {ui::VirtualKey::kNumpad3, ImGuiKey_Keypad3}, + {ui::VirtualKey::kNumpad4, ImGuiKey_Keypad4}, + {ui::VirtualKey::kNumpad5, ImGuiKey_Keypad5}, + {ui::VirtualKey::kNumpad6, ImGuiKey_Keypad6}, + {ui::VirtualKey::kNumpad7, ImGuiKey_Keypad7}, + {ui::VirtualKey::kNumpad8, ImGuiKey_Keypad8}, + {ui::VirtualKey::kNumpad9, ImGuiKey_Keypad9}, + {ui::VirtualKey::kAdd, ImGuiKey_KeypadAdd}, + {ui::VirtualKey::kSubtract, ImGuiKey_KeypadSubtract}, + {ui::VirtualKey::kMultiply, ImGuiKey_KeypadMultiply}, + {ui::VirtualKey::kDivide, ImGuiKey_KeypadDivide}, + {ui::VirtualKey::kDecimal, ImGuiKey_KeypadDecimal}, + }; + if (auto search = map.find(vkey); search != map.end()) { + return search->second; + } else { + return std::nullopt; + } +} + +void ImGuiDrawer::SetupFontTexture() { + if (font_texture_ || !immediate_drawer_) { + return; + } + ImGuiIO& io = GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + font_texture_ = immediate_drawer_->CreateTexture(width, height, ImmediateTextureFilter::kLinear, + true, reinterpret_cast(pixels)); + io.Fonts->TexID = reinterpret_cast(font_texture_.get()); +} + +void ImGuiDrawer::SetPresenter(Presenter* new_presenter) { + if (presenter_) { + if (presenter_ == new_presenter) { + return; + } + if (!dialogs_.empty()) { + presenter_->RemoveUIDrawerFromUIThread(this); + } + ImGuiIO& io = GetIO(); + } + presenter_ = new_presenter; + if (presenter_) { + if (!dialogs_.empty()) { + presenter_->AddUIDrawerFromUIThread(this, z_order_); + } + } +} + +void ImGuiDrawer::SetImmediateDrawer(ImmediateDrawer* new_immediate_drawer) { + if (immediate_drawer_ == new_immediate_drawer) { + return; + } + if (immediate_drawer_) { + GetIO().Fonts->TexID = ImTextureID{}; + font_texture_.reset(); + } + immediate_drawer_ = new_immediate_drawer; + if (immediate_drawer_) { + SetupFontTexture(); + } +} + +void ImGuiDrawer::Draw(UIDrawContext& ui_draw_context) { + // Drawing of anything is initiated by the presenter. + assert_not_null(presenter_); + if (!immediate_drawer_) { + // A presenter has been attached, but an immediate drawer hasn't been + // attached yet. + return; + } + + if (dialogs_.empty()) { + return; + } + + ImGui::SetCurrentContext(internal_state_); + + ImGuiIO& io = ImGui::GetIO(); + + uint64_t current_frame_time_ticks = rex::chrono::Clock::QueryHostTickCount(); + io.DeltaTime = + float(double(current_frame_time_ticks - last_frame_time_ticks_) / frame_time_tick_frequency_); + if (!(io.DeltaTime > 0.0f) || current_frame_time_ticks < last_frame_time_ticks_) { + // For safety as Dear ImGui doesn't allow non-positive DeltaTime. Using the + // same default value as in the official samples. + io.DeltaTime = 1.0f / 60.0f; + } + last_frame_time_ticks_ = current_frame_time_ticks; + + float physical_to_logical = float(window_->GetMediumDpi()) / float(window_->GetDpi()); + io.DisplaySize.x = window_->GetActualPhysicalWidth() * physical_to_logical; + io.DisplaySize.y = window_->GetActualPhysicalHeight() * physical_to_logical; + + ImGui::NewFrame(); + + assert_true(!IsDrawingDialogs()); + dialog_loop_next_index_ = 0; + while (dialog_loop_next_index_ < dialogs_.size()) { + dialogs_[dialog_loop_next_index_++]->Draw(); + } + dialog_loop_next_index_ = SIZE_MAX; + + ImGui::Render(); + ImDrawData* draw_data = ImGui::GetDrawData(); + if (draw_data) { + RenderDrawLists(draw_data, ui_draw_context); + } + + if (reset_mouse_position_after_next_frame_) { + reset_mouse_position_after_next_frame_ = false; + io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); + } + + // Detaching is deferred if the last dialog is removed during drawing, perform + // it now if needed. + DetachIfLastDialogRemoved(); + + if (!dialogs_.empty()) { + // Repaint (and handle input) continuously if still active. + presenter_->RequestUIPaintFromUIThread(); + } +} + +void ImGuiDrawer::RenderDrawLists(ImDrawData* data, UIDrawContext& ui_draw_context) { + ImGuiIO& io = ImGui::GetIO(); + + immediate_drawer_->Begin(ui_draw_context, io.DisplaySize.x, io.DisplaySize.y); + + for (int i = 0; i < data->CmdListsCount; ++i) { + const auto cmd_list = data->CmdLists[i]; + + ImmediateDrawBatch batch; + batch.vertices = reinterpret_cast(cmd_list->VtxBuffer.Data); + batch.vertex_count = cmd_list->VtxBuffer.size(); + batch.indices = cmd_list->IdxBuffer.Data; + batch.index_count = cmd_list->IdxBuffer.size(); + immediate_drawer_->BeginDrawBatch(batch); + + for (int j = 0; j < cmd_list->CmdBuffer.size(); ++j) { + const auto& cmd = cmd_list->CmdBuffer[j]; + + ImmediateDraw draw; + draw.primitive_type = ImmediatePrimitiveType::kTriangles; + draw.count = cmd.ElemCount; + draw.index_offset = cmd.IdxOffset; + draw.texture = reinterpret_cast(cmd.GetTexID()); + draw.scissor = true; + draw.scissor_left = cmd.ClipRect.x; + draw.scissor_top = cmd.ClipRect.y; + draw.scissor_right = cmd.ClipRect.z; + draw.scissor_bottom = cmd.ClipRect.w; + immediate_drawer_->Draw(draw); + } + + immediate_drawer_->EndDrawBatch(); + } + + immediate_drawer_->End(); +} + +ImGuiIO& ImGuiDrawer::GetIO() { + ImGui::SetCurrentContext(internal_state_); + return ImGui::GetIO(); +} + +void ImGuiDrawer::OnKeyDown(KeyEvent& e) { + OnKey(e, true); +} + +void ImGuiDrawer::OnKeyUp(KeyEvent& e) { + OnKey(e, false); +} + +void ImGuiDrawer::OnKeyChar(KeyEvent& e) { + auto& io = GetIO(); + // TODO(Triang3l): Accept the Unicode character. + unsigned int character = static_cast(e.virtual_key()); + if (character > 0 && character < 0x10000) { + io.AddInputCharacter(character); + e.set_handled(true); + } +} + +void ImGuiDrawer::OnMouseDown(MouseEvent& e) { + SwitchToPhysicalMouseAndUpdateMousePosition(e); + auto& io = GetIO(); + int button = -1; + switch (e.button()) { + case rex::ui::MouseEvent::Button::kLeft: { + button = 0; + break; + } + case rex::ui::MouseEvent::Button::kRight: { + button = 1; + break; + } + default: { + // Ignored. + break; + } + } + if (button >= 0 && button < std::size(io.MouseDown)) { + if (!io.MouseDown[button]) { + if (!ImGui::IsAnyMouseDown()) { + window_->CaptureMouse(); + } + io.MouseDown[button] = true; + } + } +} + +void ImGuiDrawer::OnMouseMove(MouseEvent& e) { + SwitchToPhysicalMouseAndUpdateMousePosition(e); +} + +void ImGuiDrawer::OnMouseUp(MouseEvent& e) { + SwitchToPhysicalMouseAndUpdateMousePosition(e); + auto& io = GetIO(); + int button = -1; + switch (e.button()) { + case rex::ui::MouseEvent::Button::kLeft: { + button = 0; + break; + } + case rex::ui::MouseEvent::Button::kRight: { + button = 1; + break; + } + default: { + // Ignored. + break; + } + } + if (button >= 0 && button < std::size(io.MouseDown)) { + if (io.MouseDown[button]) { + io.MouseDown[button] = false; + if (!ImGui::IsAnyMouseDown()) { + window_->ReleaseMouse(); + } + } + } +} + +void ImGuiDrawer::OnMouseWheel(MouseEvent& e) { + SwitchToPhysicalMouseAndUpdateMousePosition(e); + auto& io = GetIO(); + io.MouseWheel += float(e.scroll_y()) / float(MouseEvent::kScrollPerDetent); +} + +void ImGuiDrawer::OnTouchEvent(TouchEvent& e) { + auto& io = GetIO(); + TouchEvent::Action action = e.action(); + uint32_t pointer_id = e.pointer_id(); + if (action == TouchEvent::Action::kDown) { + // The latest pointer needs to be controlling the ImGui mouse. + if (touch_pointer_id_ == TouchEvent::kPointerIDNone) { + // Switching from the mouse to touch input. + if (ImGui::IsAnyMouseDown()) { + std::memset(io.MouseDown, 0, sizeof(io.MouseDown)); + window_->ReleaseMouse(); + } + } + touch_pointer_id_ = pointer_id; + } else { + if (pointer_id != touch_pointer_id_) { + return; + } + } + UpdateMousePosition(e.x(), e.y()); + if (action == TouchEvent::Action::kUp || action == TouchEvent::Action::kCancel) { + io.MouseDown[0] = false; + touch_pointer_id_ = TouchEvent::kPointerIDNone; + // Make sure that after a touch, the ImGui mouse isn't hovering over + // anything. + reset_mouse_position_after_next_frame_ = true; + } else { + io.MouseDown[0] = true; + reset_mouse_position_after_next_frame_ = false; + } +} + +void ImGuiDrawer::ClearInput() { + auto& io = GetIO(); + if (touch_pointer_id_ == TouchEvent::kPointerIDNone && ImGui::IsAnyMouseDown()) { + window_->ReleaseMouse(); + } + io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); + std::memset(io.MouseDown, 0, sizeof(io.MouseDown)); + io.ClearInputKeys(); + touch_pointer_id_ = TouchEvent::kPointerIDNone; + reset_mouse_position_after_next_frame_ = false; +} + +void ImGuiDrawer::OnKey(KeyEvent& e, bool is_down) { + auto& io = GetIO(); + const VirtualKey virtual_key = e.virtual_key(); + if (auto imGuiKey = VirtualKeyToImGuiKey(virtual_key); imGuiKey) { + io.AddKeyEvent(*imGuiKey, is_down); + } + switch (virtual_key) { + case VirtualKey::kShift: + io.KeyShift = is_down; + break; + case VirtualKey::kControl: + io.KeyCtrl = is_down; + break; + case VirtualKey::kMenu: + // FIXME(Triang3l): Doesn't work in xenia-ui-window-demo. + io.KeyAlt = is_down; + break; + case VirtualKey::kLWin: + io.KeySuper = is_down; + break; + default: + break; + } +} + +void ImGuiDrawer::UpdateMousePosition(float x, float y) { + auto& io = GetIO(); + float physical_to_logical = float(window_->GetMediumDpi()) / float(window_->GetDpi()); + io.MousePos.x = x * physical_to_logical; + io.MousePos.y = y * physical_to_logical; +} + +void ImGuiDrawer::SwitchToPhysicalMouseAndUpdateMousePosition(const MouseEvent& e) { + if (touch_pointer_id_ != TouchEvent::kPointerIDNone) { + touch_pointer_id_ = TouchEvent::kPointerIDNone; + auto& io = GetIO(); + std::memset(io.MouseDown, 0, sizeof(io.MouseDown)); + // Nothing needs to be done regarding CaptureMouse and ReleaseMouse - all + // buttons as well as mouse capture have been released when switching to + // touch input, the mouse is never captured during touch input, and now + // resetting to no buttons down (therefore not capturing). + } + reset_mouse_position_after_next_frame_ = false; + UpdateMousePosition(float(e.x()), float(e.y())); +} + +void ImGuiDrawer::DetachIfLastDialogRemoved() { + // IsDrawingDialogs() is also checked because in a situation of removing the + // only dialog, then adding a dialog, from within a dialog's Draw function, + // re-registering the ImGuiDrawer may result in ImGui being drawn multiple + // times in the current frame. + if (!dialogs_.empty() || IsDrawingDialogs()) { + return; + } + if (presenter_) { + presenter_->RemoveUIDrawerFromUIThread(this); + } + window_->RemoveInputListener(this); + // Clear all input since no input will be received anymore, and when the + // drawer becomes active again, it'd have an outdated input state otherwise + // which will be persistent until new events actualize individual input + // properties. + ClearInput(); +} + +} // namespace ui +} // namespace rex diff --git a/src/ui/immediate_drawer.cpp b/src/ui/immediate_drawer.cpp new file mode 100644 index 0000000..9d7581e --- /dev/null +++ b/src/ui/immediate_drawer.cpp @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include +#include + +namespace rex { +namespace ui { + +void ImmediateDrawer::SetPresenter(Presenter* new_presenter) { + if (presenter_ == new_presenter) { + return; + } + // Changing the presenter while drawing would make the state inconsistent. + assert_null(ui_draw_context_); + if (presenter_) { + OnLeavePresenter(); + } + presenter_ = new_presenter; + if (presenter_) { + OnEnterPresenter(); + } +} + +void ImmediateDrawer::Begin(UIDrawContext& ui_draw_context, float coordinate_space_width, + float coordinate_space_height) { + assert_true(&ui_draw_context.presenter() == presenter_); + ui_draw_context_ = &ui_draw_context; + // In case of non-positive values (or NaNs) - use render target coordinates + // according to the contract of the function, and also for safety because + // there will be division by the coordinate space size in several places. + if (!(coordinate_space_width > 0.0f) || !(coordinate_space_height > 0.0f)) { + coordinate_space_width = float(ui_draw_context.render_target_width()); + coordinate_space_height = float(ui_draw_context.render_target_height()); + } + coordinate_space_width_ = coordinate_space_width; + coordinate_space_height_ = coordinate_space_height; +} + +void ImmediateDrawer::End() { + ui_draw_context_ = nullptr; +} + +bool ImmediateDrawer::ScissorToRenderTarget(const ImmediateDraw& immediate_draw, uint32_t& out_left, + uint32_t& out_top, uint32_t& out_width, + uint32_t& out_height) { + uint32_t render_target_width = ui_draw_context()->render_target_width(); + uint32_t render_target_height = ui_draw_context()->render_target_height(); + if (!immediate_draw.scissor) { + out_left = 0; + out_top = 0; + out_width = render_target_width; + out_height = render_target_height; + return render_target_width && render_target_height; + } + float render_target_width_float = float(render_target_width); + float render_target_height_float = float(render_target_height); + // Scale to render target coordinates, drop NaNs, and clamp to the render + // target size, below which the values are representable as 16p8 fixed-point. + float scale_x = render_target_width / coordinate_space_width(); + float scale_y = render_target_height / coordinate_space_height(); + float x0_float = + rex::clamp_float(immediate_draw.scissor_left * scale_x, 0.0f, render_target_width_float); + float y0_float = + rex::clamp_float(immediate_draw.scissor_top * scale_y, 0.0f, render_target_height_float); + // Also make sure the size is non-negative. + float x1_float = + rex::clamp_float(immediate_draw.scissor_right * scale_x, x0_float, render_target_width_float); + float y1_float = rex::clamp_float(immediate_draw.scissor_bottom * scale_y, y0_float, + render_target_height_float); + // Top-left - include .5 (0.128 treated as 0 covered, 0.129 as 0 not covered). + int32_t x0 = (FloatToD3D11Fixed16p8(x0_float) + 127) >> 8; + int32_t y0 = (FloatToD3D11Fixed16p8(y0_float) + 127) >> 8; + // Bottom-right - exclude .5. + int32_t x1 = (FloatToD3D11Fixed16p8(x1_float) + 127) >> 8; + int32_t y1 = (FloatToD3D11Fixed16p8(y1_float) + 127) >> 8; + assert_true(x0 >= 0); + assert_true(y0 >= 0); + assert_true(x1 >= x0); + assert_true(y1 >= y0); + assert_true(x1 <= int32_t(render_target_width)); + assert_true(y1 <= int32_t(render_target_height)); + out_left = uint32_t(x0); + out_top = uint32_t(y0); + out_width = uint32_t(x1 - x0); + out_height = uint32_t(y1 - y0); + return x1 > x0 && y1 > y0; +} + +} // namespace ui +} // namespace rex diff --git a/src/ui/keybinds.cpp b/src/ui/keybinds.cpp new file mode 100644 index 0000000..9822f3b --- /dev/null +++ b/src/ui/keybinds.cpp @@ -0,0 +1,226 @@ +/** + * @file ui/keybinds.cpp + * @brief Key binding implementation. See keybinds.h for details. + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ +#include +#include +#include +#include +#include +#include + +namespace rex::ui { + +using rex::ui::VirtualKey; + +static const std::unordered_map kKeyNames = { + // Function keys + {"F1", VirtualKey::kF1}, + {"F2", VirtualKey::kF2}, + {"F3", VirtualKey::kF3}, + {"F4", VirtualKey::kF4}, + {"F5", VirtualKey::kF5}, + {"F6", VirtualKey::kF6}, + {"F7", VirtualKey::kF7}, + {"F8", VirtualKey::kF8}, + {"F9", VirtualKey::kF9}, + {"F10", VirtualKey::kF10}, + {"F11", VirtualKey::kF11}, + {"F12", VirtualKey::kF12}, + {"F13", VirtualKey::kF13}, + {"F14", VirtualKey::kF14}, + {"F15", VirtualKey::kF15}, + {"F16", VirtualKey::kF16}, + {"F17", VirtualKey::kF17}, + {"F18", VirtualKey::kF18}, + {"F19", VirtualKey::kF19}, + {"F20", VirtualKey::kF20}, + {"F21", VirtualKey::kF21}, + {"F22", VirtualKey::kF22}, + {"F23", VirtualKey::kF23}, + {"F24", VirtualKey::kF24}, + // Letters + {"A", VirtualKey::kA}, + {"B", VirtualKey::kB}, + {"C", VirtualKey::kC}, + {"D", VirtualKey::kD}, + {"E", VirtualKey::kE}, + {"F", VirtualKey::kF}, + {"G", VirtualKey::kG}, + {"H", VirtualKey::kH}, + {"I", VirtualKey::kI}, + {"J", VirtualKey::kJ}, + {"K", VirtualKey::kK}, + {"L", VirtualKey::kL}, + {"M", VirtualKey::kM}, + {"N", VirtualKey::kN}, + {"O", VirtualKey::kO}, + {"P", VirtualKey::kP}, + {"Q", VirtualKey::kQ}, + {"R", VirtualKey::kR}, + {"S", VirtualKey::kS}, + {"T", VirtualKey::kT}, + {"U", VirtualKey::kU}, + {"V", VirtualKey::kV}, + {"W", VirtualKey::kW}, + {"X", VirtualKey::kX}, + {"Y", VirtualKey::kY}, + {"Z", VirtualKey::kZ}, + // Digits + {"0", VirtualKey::k0}, + {"1", VirtualKey::k1}, + {"2", VirtualKey::k2}, + {"3", VirtualKey::k3}, + {"4", VirtualKey::k4}, + {"5", VirtualKey::k5}, + {"6", VirtualKey::k6}, + {"7", VirtualKey::k7}, + {"8", VirtualKey::k8}, + {"9", VirtualKey::k9}, + // OEM / special + {"Backtick", VirtualKey::kOem3}, + {"Minus", VirtualKey::kOemMinus}, + {"Plus", VirtualKey::kOemPlus}, + {"Comma", VirtualKey::kOemComma}, + {"Period", VirtualKey::kOemPeriod}, + {"Semicolon", VirtualKey::kOem1}, + {"Slash", VirtualKey::kOem2}, + {"Backslash", VirtualKey::kOem5}, + {"LBracket", VirtualKey::kOem4}, + {"RBracket", VirtualKey::kOem6}, + {"Quote", VirtualKey::kOem7}, + // Control + {"Escape", VirtualKey::kEscape}, + {"Return", VirtualKey::kReturn}, + {"Space", VirtualKey::kSpace}, + {"Tab", VirtualKey::kTab}, + {"Backspace", VirtualKey::kBack}, + {"Delete", VirtualKey::kDelete}, + {"Insert", VirtualKey::kInsert}, + {"Home", VirtualKey::kHome}, + {"End", VirtualKey::kEnd}, + {"PageUp", VirtualKey::kPrior}, + {"PageDown", VirtualKey::kNext}, + // Navigation + {"Left", VirtualKey::kLeft}, + {"Right", VirtualKey::kRight}, + {"Up", VirtualKey::kUp}, + {"Down", VirtualKey::kDown}, + // Modifier + {"Shift", VirtualKey::kShift}, + {"Control", VirtualKey::kControl}, + {"Alt", VirtualKey::kMenu}, + // Numpad + {"Numpad0", VirtualKey::kNumpad0}, + {"Numpad1", VirtualKey::kNumpad1}, + {"Numpad2", VirtualKey::kNumpad2}, + {"Numpad3", VirtualKey::kNumpad3}, + {"Numpad4", VirtualKey::kNumpad4}, + {"Numpad5", VirtualKey::kNumpad5}, + {"Numpad6", VirtualKey::kNumpad6}, + {"Numpad7", VirtualKey::kNumpad7}, + {"Numpad8", VirtualKey::kNumpad8}, + {"Numpad9", VirtualKey::kNumpad9}, + {"NumpadEnter", VirtualKey::kReturn}, + {"NumpadPlus", VirtualKey::kAdd}, + {"NumpadMinus", VirtualKey::kSubtract}, + {"NumpadStar", VirtualKey::kMultiply}, + {"NumpadSlash", VirtualKey::kDivide}, + {"PrintScreen", VirtualKey::kSnapshot}, + {"Pause", VirtualKey::kPause}, + {"CapsLock", VirtualKey::kCapital}, + {"NumLock", VirtualKey::kNumLock}, + {"ScrollLock", VirtualKey::kScroll}, + // Mouse buttons + {"LMB", VirtualKey::kLButton}, + {"RMB", VirtualKey::kRButton}, + {"MMB", VirtualKey::kMButton}, +}; + +VirtualKey ParseVirtualKey(std::string_view name) { + auto it = kKeyNames.find(std::string(name)); + return (it != kKeyNames.end()) ? it->second : VirtualKey::kNone; +} + +std::string VirtualKeyToString(VirtualKey vk) { + for (const auto& [name, key] : kKeyNames) { + if (key == vk) { + return name; + } + } + return {}; +} + +/* ---- Bind registry ---- */ + +struct BindEntry { + std::string name; + std::string current_key; + std::function callback; +}; + +static std::mutex g_binds_mutex; +static std::deque g_binds; + +void RegisterBind(std::string_view name, std::string_view default_key, std::string_view description, + std::function callback) { + std::lock_guard lock(g_binds_mutex); + + /* Store the bind entry (owns the key string that the CVAR references). */ + auto& entry = g_binds.emplace_back(); + entry.name = std::string(name); + entry.current_key = std::string(default_key); + entry.callback = std::move(callback); + + /* Capture a pointer to the entry's key string for the CVAR getter/setter. + The entry is stable because g_binds is never compacted while binds are + alive (UnregisterBind sets the callback to null rather than erasing). */ + std::string* key_ptr = &entry.current_key; + + rex::cvar::RegisterFlag({ + .name = std::string(name), + .type = rex::cvar::FlagType::String, + .category = "Input/Keybinds/System", + .description = std::string(description), + .setter = [key_ptr](std::string_view v) -> bool { + *key_ptr = std::string(v); + return true; + }, + .getter = [key_ptr]() -> std::string { return *key_ptr; }, + .lifecycle = rex::cvar::Lifecycle::kHotReload, + .default_value = std::string(default_key), + }); +} + +void UnregisterBind(std::string_view name) { + std::lock_guard lock(g_binds_mutex); + for (auto& entry : g_binds) { + if (entry.name == name) { + entry.callback = nullptr; + return; + } + } +} + +bool ProcessKeyEvent(KeyEvent& e) { + std::lock_guard lock(g_binds_mutex); + for (auto& entry : g_binds) { + if (!entry.callback) + continue; + VirtualKey vk = ParseVirtualKey(entry.current_key); + if (vk != VirtualKey::kNone && e.virtual_key() == vk) { + entry.callback(); + e.set_handled(true); + return true; + } + } + return false; +} + +} // namespace rex::ui diff --git a/src/ui/menu_item.cpp b/src/ui/menu_item.cpp new file mode 100644 index 0000000..b9aca05 --- /dev/null +++ b/src/ui/menu_item.cpp @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +namespace rex { +namespace ui { + +std::unique_ptr MenuItem::Create(Type type) { + return MenuItem::Create(type, "", "", nullptr); +} + +std::unique_ptr MenuItem::Create(Type type, const std::string& text) { + return MenuItem::Create(type, text, "", nullptr); +} + +std::unique_ptr MenuItem::Create(Type type, const std::string& text, + std::function callback) { + return MenuItem::Create(type, text, "", std::move(callback)); +} + +MenuItem::MenuItem(Type type, const std::string& text, const std::string& hotkey, + std::function callback) + : type_(type), + parent_item_(nullptr), + text_(text), + hotkey_(hotkey), + callback_(std::move(callback)) {} + +MenuItem::~MenuItem() = default; + +void MenuItem::AddChild(MenuItem* child_item) { + AddChild(MenuItemPtr(child_item, [](MenuItem* item) {})); +} + +void MenuItem::AddChild(std::unique_ptr child_item) { + AddChild(MenuItemPtr(child_item.release(), [](MenuItem* item) { delete item; })); +} + +void MenuItem::AddChild(MenuItemPtr child_item) { + auto child_item_ptr = child_item.get(); + children_.emplace_back(std::move(child_item)); + OnChildAdded(child_item_ptr); +} + +void MenuItem::RemoveChild(MenuItem* child_item) { + for (auto it = children_.begin(); it != children_.end(); ++it) { + if (it->get() == child_item) { + children_.erase(it); + OnChildRemoved(child_item); + break; + } + } +} + +MenuItem* MenuItem::child(size_t index) { + return children_[index].get(); +} + +void MenuItem::OnSelected() { + if (callback_) { + callback_(); + // Note that this MenuItem might have been destroyed by the callback. + // Must not do anything with *this in this function from now on. + } +} + +} // namespace ui +} // namespace rex diff --git a/src/ui/overlay/console_overlay.cpp b/src/ui/overlay/console_overlay.cpp new file mode 100644 index 0000000..df5915f --- /dev/null +++ b/src/ui/overlay/console_overlay.cpp @@ -0,0 +1,240 @@ +/** + * @file ui/overlay/console_overlay.cpp + * + * @brief Console overlay implementation. See console_overlay.h for details. + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ +#include +#include +#include +#include +#include + +namespace rex::ui { + +static ImVec4 LevelColor(spdlog::level::level_enum level) { + // todo(tomc): make these cvar driven + switch (level) { + case spdlog::level::trace: + return {0.5f, 0.5f, 0.5f, 1.0f}; // grey + case spdlog::level::debug: + return {0.4f, 0.9f, 0.9f, 1.0f}; // cyan + case spdlog::level::info: + return {1.0f, 1.0f, 1.0f, 1.0f}; // white + case spdlog::level::warn: + return {1.0f, 1.0f, 0.0f, 1.0f}; // yellow + case spdlog::level::err: + return {1.0f, 0.4f, 0.4f, 1.0f}; // red + case spdlog::level::critical: + return {1.0f, 0.0f, 0.0f, 1.0f}; // bright red + default: + return {1.0f, 1.0f, 1.0f, 1.0f}; + } +} + +ConsoleDialog::ConsoleDialog(ImGuiDrawer* imgui_drawer, std::shared_ptr sink) + : ImGuiDialog(imgui_drawer), sink_(std::move(sink)) {} + +ConsoleDialog::~ConsoleDialog() {} + +void ConsoleDialog::RefreshCategories() { + for (auto& entry : entries_) { + if (entry.category.empty() || entry.category == "console") + continue; + if (known_categories_.insert(entry.category).second) { + // New category discovered - enable by default. + category_filter_[entry.category] = true; + } + } +} + +int ConsoleDialog::InputTextCallback(ImGuiInputTextCallbackData* data) { + auto* self = static_cast(data->UserData); + if (data->EventFlag == ImGuiInputTextFlags_CallbackHistory) { + const int prev = self->history_pos_; + if (data->EventKey == ImGuiKey_UpArrow) { + if (self->history_pos_ == -1) { + self->history_pos_ = static_cast(self->history_.size()) - 1; + } else if (self->history_pos_ > 0) { + --self->history_pos_; + } + } else if (data->EventKey == ImGuiKey_DownArrow) { + if (self->history_pos_ != -1) { + if (++self->history_pos_ >= static_cast(self->history_.size())) { + self->history_pos_ = -1; + } + } + } + if (prev != self->history_pos_) { + const char* hist = + (self->history_pos_ >= 0) ? self->history_[self->history_pos_].c_str() : ""; + data->DeleteChars(0, data->BufTextLen); + data->InsertChars(0, hist); + } + } + return 0; +} + +void ConsoleDialog::ExecuteCommand(std::string_view cmd) { + // Trim whitespace. + while (!cmd.empty() && cmd.front() == ' ') + cmd.remove_prefix(1); + while (!cmd.empty() && cmd.back() == ' ') + cmd.remove_suffix(1); + if (cmd.empty()) + return; + + // Record in history. + if (history_.empty() || history_.back() != cmd) { + if (history_.size() >= kMaxHistory) + history_.pop_front(); + history_.push_back(std::string(cmd)); + } + history_pos_ = -1; + + if (cmd == "help" || cmd == "?") { + auto names = rex::cvar::ListFlags(); + std::sort(names.begin(), names.end()); + for (auto& n : names) { + const auto* info = rex::cvar::GetFlagInfo(n); + std::string line = " " + n; + if (info) + line += " = " + info->getter() + " (" + info->description + ")"; + local_entries_.push_back({spdlog::level::info, "console", line}); + } + return; + } + + // Split on first space: "name value" + auto sep = cmd.find(' '); + if (sep == std::string_view::npos) { + // No space: treat as "get" - show current value. + std::string val = rex::cvar::GetFlagByName(cmd); + if (val.empty() && !rex::cvar::GetFlagInfo(cmd)) { + local_entries_.push_back( + {spdlog::level::warn, "console", "[console] unknown cvar: " + std::string(cmd)}); + } else { + local_entries_.push_back( + {spdlog::level::info, "console", "[console] " + std::string(cmd) + " = " + val}); + } + return; + } + + std::string name(cmd.substr(0, sep)); + std::string value(cmd.substr(sep + 1)); + while (!value.empty() && value.front() == ' ') + value.erase(value.begin()); + + if (rex::cvar::SetFlagByName(name, value)) { + local_entries_.push_back({spdlog::level::info, "console", "[console] " + name + " = " + value}); + } else { + local_entries_.push_back({spdlog::level::warn, "console", "[console] unknown cvar: " + name}); + } + scroll_to_bottom_ = true; +} + +void ConsoleDialog::OnDraw(ImGuiIO& io) { + // Refresh entries if sink has new data. + if (sink_) { + uint64_t gen = sink_->generation(); + if (gen != last_generation_) { + sink_->CopyEntries(entries_); + // Re-append console-local entries (command feedback) that aren't in the sink. + entries_.insert(entries_.end(), local_entries_.begin(), local_entries_.end()); + last_generation_ = gen; + RefreshCategories(); + } + } + + const float window_height = io.DisplaySize.y * 0.45f; + ImGui::SetNextWindowPos(ImVec2(0, io.DisplaySize.y - window_height), ImGuiCond_Always); + ImGui::SetNextWindowSize(ImVec2(io.DisplaySize.x, window_height), ImGuiCond_Always); + ImGui::SetNextWindowBgAlpha(0.80f); + + ImGuiWindowFlags flags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | + ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar; + + if (!ImGui::Begin("Console##rex", nullptr, flags)) { + ImGui::End(); + return; + } + + // --- Filter bar --- + static const char* kLevelNames[] = {"trace", "debug", "info", "warn", "error", "critical"}; + ImGui::Text("Level:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(80.0f); + ImGui::Combo("##lvl", &min_level_, kLevelNames, 6); + ImGui::SameLine(); + ImGui::Text("Categories:"); + ImGui::SameLine(); + int cat_idx = 0; + for (auto& [cat_name, enabled] : category_filter_) { + ImGui::Checkbox(cat_name.c_str(), &enabled); + if (++cat_idx < static_cast(category_filter_.size())) + ImGui::SameLine(); + } + + // --- Log area --- + const float input_height = ImGui::GetFrameHeightWithSpacing() + 4.0f; + ImGui::BeginChild("##log", ImVec2(0, -input_height), false, ImGuiWindowFlags_HorizontalScrollbar); + + bool at_bottom = (ImGui::GetScrollY() >= ImGui::GetScrollMaxY() - 2.0f); + + for (auto& entry : entries_) { + // Level filter. + if (static_cast(entry.level) < min_level_) + continue; + // Category filter. + bool show_cat = false; + auto it = category_filter_.find(entry.category); + if (it != category_filter_.end()) { + show_cat = it->second; + } + // "console" pseudo-category always shown. + if (entry.category == "console") + show_cat = true; + if (!show_cat) + continue; + + ImGui::PushStyleColor(ImGuiCol_Text, LevelColor(entry.level)); + ImGui::TextUnformatted(entry.text.c_str()); + ImGui::PopStyleColor(); + } + + if (scroll_to_bottom_ || at_bottom) { + ImGui::SetScrollHereY(1.0f); + scroll_to_bottom_ = false; + } + ImGui::EndChild(); + + // --- Command input --- + ImGui::Separator(); + bool submit = false; + ImGuiInputTextFlags input_flags = + ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackHistory; + ImGui::SetNextItemWidth(-1.0f); + if (focus_input_next_frame_) { + ImGui::SetKeyboardFocusHere(); + focus_input_next_frame_ = false; + } + if (ImGui::InputText("##cmd", input_buf_, sizeof(input_buf_), input_flags, InputTextCallback, + this)) { + submit = true; + } + + if (submit && input_buf_[0] != '\0') { + ExecuteCommand(input_buf_); + input_buf_[0] = '\0'; + ImGui::SetKeyboardFocusHere(-1); + } + + ImGui::End(); +} + +} // namespace rex::ui diff --git a/src/ui/overlay/debug_overlay.cpp b/src/ui/overlay/debug_overlay.cpp new file mode 100644 index 0000000..8a97c2d --- /dev/null +++ b/src/ui/overlay/debug_overlay.cpp @@ -0,0 +1,108 @@ +/** + * @file ui/overlay/debug_overlay.cpp + * + * @brief Debug overlay implementation. See debug_overlay.h for details. + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ +#include +#include +#include +#ifdef REXGLUE_ENABLE_PERF_COUNTERS +#include +#include +#endif + +namespace rex::ui { + +DebugOverlayDialog::DebugOverlayDialog(ImGuiDrawer* imgui_drawer, FrameStatsProvider stats_provider) + : ImGuiDialog(imgui_drawer), stats_provider_(std::move(stats_provider)) {} + +DebugOverlayDialog::~DebugOverlayDialog() {} + +void DebugOverlayDialog::OnDraw(ImGuiIO& io) { + ImGui::SetNextWindowPos(ImVec2(10, 10), ImGuiCond_FirstUseEver); +#ifdef REXGLUE_ENABLE_PERF_COUNTERS + ImGui::SetNextWindowSize(ImVec2(280, 280), ImGuiCond_FirstUseEver); +#else + ImGui::SetNextWindowSize(ImVec2(220, 60), ImGuiCond_FirstUseEver); +#endif + ImGui::SetNextWindowBgAlpha(0.5f); + if (ImGui::Begin("Debug##overlay", nullptr, ImGuiWindowFlags_NoCollapse)) { + if (stats_provider_) { + auto stats = stats_provider_(); + if (stats.frame_count > 0) { + ImGui::Text("Guest: %.1f FPS (%.2f ms)", stats.fps, stats.frame_time_ms); + } + } +#ifdef REXGLUE_ENABLE_PERF_COUNTERS + ImGui::Separator(); + + // Frame time graph + auto ft_us = rex::perf::GetSnapshotCounter(rex::perf::CounterId::kFrameTimeUs); + float ft_ms = static_cast(ft_us) / 1000.0f; + frame_time_history_[frame_history_idx_] = ft_ms; + frame_history_idx_ = (frame_history_idx_ + 1) % kFrameHistorySize; + ImGui::PlotLines("##ft", frame_time_history_.data(), kFrameHistorySize, + static_cast(frame_history_idx_), "Frame (ms)", 0.0f, 50.0f, + ImVec2(200, 40)); + + // GPU + ImGui::Text("Draw: %" PRId64 " Stalls: %" PRId64 " Verts: %" PRId64, + rex::perf::GetSnapshotCounter(rex::perf::CounterId::kDrawCalls), + rex::perf::GetSnapshotCounter(rex::perf::CounterId::kCommandBufferStalls), + rex::perf::GetSnapshotCounter(rex::perf::CounterId::kVerticesProcessed)); + + // Audio + ImGui::Text("XMA: %" PRId64 " Lat: %.1fms BufQ: %" PRId64, + rex::perf::GetSnapshotCounter(rex::perf::CounterId::kXmaFramesDecoded), + static_cast( + rex::perf::GetSnapshotCounter(rex::perf::CounterId::kAudioFrameLatencyUs)) / + 1000.0f, + rex::perf::GetSnapshotCounter(rex::perf::CounterId::kBufferQueueDepth)); + + // Dispatch + ImGui::Text("Dispatch: %" PRId64 " IRQ: %" PRId64, + rex::perf::GetSnapshotCounter(rex::perf::CounterId::kFunctionsDispatched), + rex::perf::GetSnapshotCounter(rex::perf::CounterId::kInterruptDispatches)); + + // Threading + ImGui::Text("Threads: %" PRId64 " APC: %" PRId64 " Contention: %" PRId64, + rex::perf::GetSnapshotCounter(rex::perf::CounterId::kActiveThreads), + rex::perf::GetSnapshotCounter(rex::perf::CounterId::kApcQueueDepth), + rex::perf::GetSnapshotCounter(rex::perf::CounterId::kCriticalRegionContentions)); + + // Caches + auto tex_h = rex::perf::GetSnapshotCounter(rex::perf::CounterId::kTextureCacheHits); + auto tex_m = rex::perf::GetSnapshotCounter(rex::perf::CounterId::kTextureCacheMisses); + auto pip_h = rex::perf::GetSnapshotCounter(rex::perf::CounterId::kPipelineCacheHits); + auto pip_m = rex::perf::GetSnapshotCounter(rex::perf::CounterId::kPipelineCacheMisses); + ImGui::Text("TexCache: %" PRId64 "/%" PRId64 " PipeCache: %" PRId64 "/%" PRId64, tex_h, + tex_h + tex_m, pip_h, pip_h + pip_m); +#endif + } + ImGui::End(); + + // Build stamp watermark -- centered near bottom of screen + auto text_size = ImGui::CalcTextSize(REXGLUE_BUILD_STAMP); + float padding = ImGui::GetStyle().WindowPadding.x * 2.0f; + float bottom_offset = io.DisplaySize.y * 0.03f; + ImGui::SetNextWindowPos(ImVec2((io.DisplaySize.x - text_size.x - padding) * 0.5f, + io.DisplaySize.y - text_size.y - bottom_offset)); + ImGui::SetNextWindowSize(ImVec2(0, 0)); + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 0.5f)); + if (ImGui::Begin("##watermark", nullptr, + ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground | + ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoNav | + ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::TextUnformatted(REXGLUE_BUILD_STAMP); + } + ImGui::End(); + ImGui::PopStyleColor(); +} + +} // namespace rex::ui diff --git a/src/ui/overlay/settings_overlay.cpp b/src/ui/overlay/settings_overlay.cpp new file mode 100644 index 0000000..c530479 --- /dev/null +++ b/src/ui/overlay/settings_overlay.cpp @@ -0,0 +1,512 @@ +/** + * @file ui/overlay/settings_overlay.cpp + * + * @brief Settings overlay implementation. See settings_overlay.h for details. + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace rex::ui { + +SettingsDialog::SettingsDialog(ImGuiDrawer* imgui_drawer, std::filesystem::path config_path) + : ImGuiDialog(imgui_drawer), config_path_(std::move(config_path)) {} + +SettingsDialog::~SettingsDialog() {} + +static const char* LifecycleBadge(rex::cvar::Lifecycle lc) { + switch (lc) { + case rex::cvar::Lifecycle::kHotReload: + return " [live]"; + case rex::cvar::Lifecycle::kRequiresRestart: + return " [restart]"; + case rex::cvar::Lifecycle::kInitOnly: + return " [init-only]"; + } + return ""; +} + +static ImVec4 LifecycleColor(rex::cvar::Lifecycle lc) { + switch (lc) { + case rex::cvar::Lifecycle::kHotReload: + return {0.4f, 1.0f, 0.4f, 1.0f}; + case rex::cvar::Lifecycle::kRequiresRestart: + return {1.0f, 1.0f, 0.4f, 1.0f}; + case rex::cvar::Lifecycle::kInitOnly: + return {1.0f, 0.4f, 0.4f, 1.0f}; + } + return {1.0f, 1.0f, 1.0f, 1.0f}; +} + +static rex::ui::VirtualKey ImGuiKeyToVirtualKey(ImGuiKey key) { + using VK = rex::ui::VirtualKey; + if (key >= ImGuiKey_A && key <= ImGuiKey_Z) { + return static_cast(static_cast(VK::kA) + (key - ImGuiKey_A)); + } + if (key >= ImGuiKey_0 && key <= ImGuiKey_9) { + return static_cast(static_cast(VK::k0) + (key - ImGuiKey_0)); + } + if (key >= ImGuiKey_F1 && key <= ImGuiKey_F24) { + return static_cast(static_cast(VK::kF1) + (key - ImGuiKey_F1)); + } + if (key >= ImGuiKey_Keypad0 && key <= ImGuiKey_Keypad9) { + return static_cast(static_cast(VK::kNumpad0) + (key - ImGuiKey_Keypad0)); + } + switch (key) { + case ImGuiKey_Space: + return VK::kSpace; + case ImGuiKey_Enter: + return VK::kReturn; + case ImGuiKey_Escape: + return VK::kEscape; + case ImGuiKey_Tab: + return VK::kTab; + case ImGuiKey_Backspace: + return VK::kBack; + case ImGuiKey_Delete: + return VK::kDelete; + case ImGuiKey_Insert: + return VK::kInsert; + case ImGuiKey_Home: + return VK::kHome; + case ImGuiKey_End: + return VK::kEnd; + case ImGuiKey_PageUp: + return VK::kPrior; + case ImGuiKey_PageDown: + return VK::kNext; + case ImGuiKey_LeftArrow: + return VK::kLeft; + case ImGuiKey_RightArrow: + return VK::kRight; + case ImGuiKey_UpArrow: + return VK::kUp; + case ImGuiKey_DownArrow: + return VK::kDown; + case ImGuiKey_LeftShift: + case ImGuiKey_RightShift: + return VK::kShift; + case ImGuiKey_LeftCtrl: + case ImGuiKey_RightCtrl: + return VK::kControl; + case ImGuiKey_LeftAlt: + case ImGuiKey_RightAlt: + return VK::kMenu; + case ImGuiKey_CapsLock: + return VK::kCapital; + case ImGuiKey_NumLock: + return VK::kNumLock; + case ImGuiKey_ScrollLock: + return VK::kScroll; + case ImGuiKey_PrintScreen: + return VK::kSnapshot; + case ImGuiKey_Pause: + return VK::kPause; + case ImGuiKey_GraveAccent: + return VK::kOem3; + case ImGuiKey_Minus: + return VK::kOemMinus; + case ImGuiKey_Equal: + return VK::kOemPlus; + case ImGuiKey_LeftBracket: + return VK::kOem4; + case ImGuiKey_RightBracket: + return VK::kOem6; + case ImGuiKey_Backslash: + return VK::kOem5; + case ImGuiKey_Semicolon: + return VK::kOem1; + case ImGuiKey_Apostrophe: + return VK::kOem7; + case ImGuiKey_Comma: + return VK::kOemComma; + case ImGuiKey_Period: + return VK::kOemPeriod; + case ImGuiKey_Slash: + return VK::kOem2; + case ImGuiKey_KeypadDecimal: + return VK::kDecimal; + case ImGuiKey_KeypadDivide: + return VK::kDivide; + case ImGuiKey_KeypadMultiply: + return VK::kMultiply; + case ImGuiKey_KeypadSubtract: + return VK::kSubtract; + case ImGuiKey_KeypadAdd: + return VK::kAdd; + case ImGuiKey_KeypadEnter: + return VK::kReturn; + default: + return VK::kNone; + } +} + +void SettingsDialog::OnDraw(ImGuiIO& /*io*/) { + auto& registry = rex::cvar::GetRegistry(); + + // Collect sorted unique category paths. + std::set category_set; + for (auto& entry : registry) { + category_set.insert(entry.category); + } + + // Build tree: for each category path like "Input/Keybinds/Controller", + // also register the parent paths "Input" and "Input/Keybinds" as nodes. + struct CatNode { + std::string full_path; + std::string label; // leaf segment (e.g. "Controller") + std::map children; + bool has_direct_entries = false; + }; + std::map tree; + + for (auto& cat : category_set) { + std::map* level = &tree; + std::string path_so_far; + size_t start = 0; + while (start < cat.size()) { + size_t slash = cat.find('/', start); + std::string segment = + (slash == std::string::npos) ? cat.substr(start) : cat.substr(start, slash - start); + if (!path_so_far.empty()) + path_so_far += "/"; + path_so_far += segment; + auto& node = (*level)[segment]; + node.full_path = path_so_far; + node.label = segment; + if (path_so_far == cat) + node.has_direct_entries = true; + level = &node.children; + start = (slash == std::string::npos) ? cat.size() : slash + 1; + } + } + + const std::string search(search_buf_); + const bool searching = !search.empty(); + + ImGui::SetNextWindowSize(ImVec2(620, 480), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowBgAlpha(0.85f); + if (!ImGui::Begin("Settings##rex", nullptr, ImGuiWindowFlags_NoCollapse)) { + ImGui::End(); + return; + } + + // Search bar at the top (full width). + ImGui::SetNextItemWidth(-1.0f); + ImGui::InputText("##search", search_buf_, sizeof(search_buf_)); + ImGui::SameLine(0, 0); + ImGui::Dummy(ImVec2(0, 0)); + + ImGui::Separator(); + + const float panel_width = 160.0f; + ImGui::BeginChild("##cats", ImVec2(panel_width, -30.0f), true); + + // Recursive lambda to draw the category tree. + std::function&, int)> draw_tree; + draw_tree = [&](const std::map& nodes, int depth) { + for (auto& [key, node] : nodes) { + if (node.children.empty()) { + // Leaf node - selectable + bool selected = (selected_category_ == node.full_path); + if (depth > 0) + ImGui::Indent(8.0f); + if (ImGui::Selectable(node.label.c_str(), selected)) { + selected_category_ = node.full_path; + } + if (depth > 0) + ImGui::Unindent(8.0f); + } else { + // Parent node with children - use tree node + ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_OpenOnArrow; + if (node.has_direct_entries) { + // Can be selected as well as expanded + if (selected_category_ == node.full_path) + flags |= ImGuiTreeNodeFlags_Selected; + } + bool open = ImGui::TreeNodeEx(node.label.c_str(), flags); + if (ImGui::IsItemClicked() && node.has_direct_entries) { + selected_category_ = node.full_path; + } + if (open) { + draw_tree(node.children, depth + 1); + ImGui::TreePop(); + } + } + } + }; + // Root node named after the config file + std::string root_label = config_path_.stem().string(); + ImGuiTreeNodeFlags root_flags = ImGuiTreeNodeFlags_DefaultOpen; + if (selected_category_.empty()) + root_flags |= ImGuiTreeNodeFlags_Selected; + bool root_open = ImGui::TreeNodeEx(root_label.c_str(), root_flags); + if (ImGui::IsItemClicked()) { + selected_category_.clear(); + } + if (root_open) { + draw_tree(tree, 1); + ImGui::TreePop(); + } + + ImGui::EndChild(); + + ImGui::SameLine(); + + // Helper: check if a CVAR's category matches the selected category. + // Exact match or prefix match (e.g. selecting "Input" shows all "Input/*"). + auto category_matches = [&](const std::string& cat) -> bool { + if (selected_category_.empty()) + return true; // Root selected - show all + if (cat == selected_category_) + return true; + if (cat.size() > selected_category_.size() && + cat.compare(0, selected_category_.size(), selected_category_) == 0 && + cat[selected_category_.size()] == '/') { + return true; + } + return false; + }; + + // Helper: check if a category is a keybind category. + auto is_keybind_category = [](const std::string& cat) -> bool { + return cat == "Input/Keybinds" || + (cat.size() > 15 && cat.compare(0, 15, "Input/Keybinds/") == 0); + }; + + ImGui::BeginChild("##cvars", ImVec2(0, -30.0f), false); + for (auto& entry : registry) { + // Filter by category (unless searching). + if (!searching) { + if (!category_matches(entry.category)) { + continue; + } + } else { + // Search matches name or description (case-insensitive substring). + std::string name_lower = entry.name; + std::string search_lower = search; + auto to_lower = [](std::string& s) { + for (auto& c : s) + c = static_cast(std::tolower(c)); + }; + to_lower(name_lower); + to_lower(search_lower); + if (name_lower.find(search_lower) == std::string::npos && + entry.description.find(search_lower) == std::string::npos) { + continue; + } + } + + bool read_only = (entry.lifecycle == rex::cvar::Lifecycle::kInitOnly); + + ImGui::PushID(entry.name.c_str()); + + if (read_only) + ImGui::BeginDisabled(); + + std::string current_val = entry.getter(); + + // Use description as display label if available, otherwise CVAR name + const char* display_label = + (!entry.description.empty()) ? entry.description.c_str() : entry.name.c_str(); + + if (is_keybind_category(entry.category)) { + // Grey out controller keybinds when MnK mode is disabled + bool mnk_disabled = + (entry.category == "Input/Keybinds/Controller" && !REXCVAR_QUERY(bool, mnk_mode)); + if (mnk_disabled) + ImGui::BeginDisabled(); + + // Show description as label (e.g. "A button"), not the raw CVAR name + ImGui::Text("%-20s", entry.description.c_str()); + ImGui::SameLine(240.0f); + + bool is_capturing = (capturing_bind_name_ == entry.name); + + if (is_capturing) { + ImGui::Button("Press any key...##v", ImVec2(140.0f, 0)); + + if (ImGui::IsKeyPressed(ImGuiKey_Escape)) { + capturing_bind_name_.clear(); + } else { + for (int k = ImGuiKey_NamedKey_BEGIN; k < ImGuiKey_NamedKey_END; ++k) { + auto imgui_key = static_cast(k); + if (imgui_key == ImGuiKey_Escape) + continue; + if (ImGui::IsKeyPressed(imgui_key)) { + auto vk = ImGuiKeyToVirtualKey(imgui_key); + std::string name = rex::ui::VirtualKeyToString(vk); + if (!name.empty()) { + rex::cvar::SetFlagByName(entry.name, name); + } + capturing_bind_name_.clear(); + break; + } + } + for (int mb = 0; mb < 3; ++mb) { + if (ImGui::IsMouseClicked(mb)) { + const char* names[] = {"LMB", "RMB", "MMB"}; + rex::cvar::SetFlagByName(entry.name, names[mb]); + capturing_bind_name_.clear(); + break; + } + } + } + } else { + ImGui::SetNextItemWidth(80.0f); + ImGui::Text("%-10s", current_val.c_str()); + ImGui::SameLine(); + if (ImGui::SmallButton("Rebind##v")) { + capturing_bind_name_ = entry.name; + } + ImGui::SameLine(); + if (ImGui::SmallButton("Reset##v")) { + rex::cvar::SetFlagByName(entry.name, entry.default_value); + } + } + + // Conflict detection + if (!current_val.empty()) { + int conflict_count = 0; + for (auto& other : registry) { + if (is_keybind_category(other.category) && other.name != entry.name && + other.getter() == current_val) { + conflict_count++; + } + } + if (conflict_count > 0) { + ImGui::SameLine(); + ImGui::TextColored(ImVec4(1.0f, 0.8f, 0.2f, 1.0f), "(!)"); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Key '%s' is also bound to %d other action(s)", current_val.c_str(), + conflict_count); + } + } + } + + // Skip the generic name + lifecycle badge rendering for keybinds + if (mnk_disabled) + ImGui::EndDisabled(); + if (read_only) + ImGui::EndDisabled(); + ImGui::PopID(); + continue; + } else { + // Non-keybind CVARs: colored label on left, value widget on right + ImGui::TextColored(LifecycleColor(entry.lifecycle), "%-20s", entry.name.c_str()); + if (ImGui::IsItemHovered()) { + const char* lifecycle_label = ""; + switch (entry.lifecycle) { + case rex::cvar::Lifecycle::kHotReload: + lifecycle_label = "Live - changes apply immediately"; + break; + case rex::cvar::Lifecycle::kRequiresRestart: + lifecycle_label = "Requires restart to take effect"; + break; + case rex::cvar::Lifecycle::kInitOnly: + lifecycle_label = "Read-only - set at initialization only"; + break; + } + if (!entry.description.empty()) { + ImGui::SetTooltip("%s\n[%s]", entry.description.c_str(), lifecycle_label); + } else { + ImGui::SetTooltip("[%s]", lifecycle_label); + } + } + ImGui::SameLine(240.0f); + + ImGui::SetNextItemWidth(160.0f); + if (entry.type == rex::cvar::FlagType::Boolean) { + bool v = (current_val == "true"); + if (ImGui::Checkbox("##v", &v)) { + rex::cvar::SetFlagByName(entry.name, v ? "true" : "false"); + } + } else if (entry.type == rex::cvar::FlagType::String && + !entry.constraints.allowed_values.empty()) { + const auto& opts = entry.constraints.allowed_values; + int cur_idx = 0; + for (int i = 0; i < static_cast(opts.size()); ++i) { + if (opts[i] == current_val) { + cur_idx = i; + break; + } + } + if (ImGui::BeginCombo("##v", opts[cur_idx].c_str())) { + for (int i = 0; i < static_cast(opts.size()); ++i) { + bool sel = (i == cur_idx); + if (ImGui::Selectable(opts[i].c_str(), sel)) { + rex::cvar::SetFlagByName(entry.name, opts[i]); + } + if (sel) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + } else if (entry.type == rex::cvar::FlagType::Int32 || + entry.type == rex::cvar::FlagType::Int64 || + entry.type == rex::cvar::FlagType::Uint32 || + entry.type == rex::cvar::FlagType::Uint64) { + int v = std::atoi(current_val.c_str()); + int vmin = + entry.constraints.min.has_value() ? static_cast(*entry.constraints.min) : INT_MIN; + int vmax = + entry.constraints.max.has_value() ? static_cast(*entry.constraints.max) : INT_MAX; + if (ImGui::InputInt("##v", &v)) { + v = std::clamp(v, vmin, vmax); + rex::cvar::SetFlagByName(entry.name, std::to_string(v)); + } + } else if (entry.type == rex::cvar::FlagType::Double) { + double v = std::atof(current_val.c_str()); + if (ImGui::InputDouble("##v", &v, 0.0, 0.0, "%.4f")) { + if (entry.constraints.min) + v = std::max(v, *entry.constraints.min); + if (entry.constraints.max) + v = std::min(v, *entry.constraints.max); + rex::cvar::SetFlagByName(entry.name, std::to_string(v)); + } + } else if (entry.type == rex::cvar::FlagType::Command) { + if (ImGui::Button(std::string(entry.name + "##v").c_str())) { + entry.command_callback(); + } + } else { + char buf[256]; + std::strncpy(buf, current_val.c_str(), sizeof(buf) - 1); + buf[sizeof(buf) - 1] = '\0'; + if (ImGui::InputText("##v", buf, sizeof(buf), ImGuiInputTextFlags_EnterReturnsTrue)) { + rex::cvar::SetFlagByName(entry.name, buf); + } + } + } + + if (read_only) + ImGui::EndDisabled(); + + ImGui::PopID(); + } + ImGui::EndChild(); + + // Bottom bar: Save button. + ImGui::Separator(); + if (ImGui::Button("Save to config")) { + rex::cvar::SaveConfig(config_path_); + } + ImGui::SameLine(); + ImGui::TextDisabled("(%s)", config_path_.filename().string().c_str()); + + ImGui::End(); +} + +} // namespace rex::ui diff --git a/src/ui/presenter.cpp b/src/ui/presenter.cpp new file mode 100644 index 0000000..b6dc208 --- /dev/null +++ b/src/ui/presenter.cpp @@ -0,0 +1,1671 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME +#include +#include +#endif + +#if REX_PLATFORM_WIN32 +#include +#endif + +REXCVAR_DEFINE_BOOL(host_present_from_non_ui_thread, true, "UI/Presenter", + "Allow presentation from non-UI thread"); + +REXCVAR_DEFINE_BOOL(present_letterbox, true, "UI/Presenter", + "Enable letterboxing for non-native aspect ratios"); + +REXCVAR_DEFINE_INT32(present_safe_area_x, 90, "UI/Presenter", + "Horizontal safe area percentage (0-100)") + .range(0, 100); + +REXCVAR_DEFINE_INT32(present_safe_area_y, 90, "UI/Presenter", + "Vertical safe area percentage (0-100)") + .range(0, 100); + +#if defined(REX_HAS_FIDELITYFX_SDK) +REXCVAR_DEFINE_STRING(present_effect, "bilinear", "UI/Presenter", + "Guest output effect: bilinear, cas, fsr, fsr2, fsr3") + .allowed({"bilinear", "cas", "fsr", "fsr2", "fsr3"}) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_DOUBLE(present_cas_additional_sharpness, + rex::ui::Presenter::GuestOutputPaintConfig::kCasAdditionalSharpnessDefault, + "UI/Presenter", "Additional CAS sharpness in [0, 1]") + .range(rex::ui::Presenter::GuestOutputPaintConfig::kCasAdditionalSharpnessMin, + rex::ui::Presenter::GuestOutputPaintConfig::kCasAdditionalSharpnessMax) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_INT32(present_fsr_max_upsampling_passes, + rex::ui::Presenter::GuestOutputPaintConfig::kFsrMaxUpscalingPassesMax, + "UI/Presenter", "Maximum chained FSR EASU passes") + .range(1, int32_t(rex::ui::Presenter::GuestOutputPaintConfig::kFsrMaxUpscalingPassesMax)) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_DOUBLE(present_fsr_sharpness_reduction, + rex::ui::Presenter::GuestOutputPaintConfig::kFsrSharpnessReductionDefault, + "UI/Presenter", "FSR RCAS sharpness reduction in stops") + .range(rex::ui::Presenter::GuestOutputPaintConfig::kFsrSharpnessReductionMin, + rex::ui::Presenter::GuestOutputPaintConfig::kFsrSharpnessReductionMax) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_STRING( + present_fsr_quality_mode, "auto", "UI/Presenter", + "Temporal FSR quality mode: auto, nativeaa, quality, balanced, performance, ultra_performance") + .allowed({"auto", "nativeaa", "quality", "balanced", "performance", "ultra_performance"}) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); +#else +REXCVAR_DEFINE_STRING(present_effect, "bilinear", "UI/Presenter", "Guest output effect: bilinear") + .allowed({"bilinear"}) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); +#endif + +REXCVAR_DEFINE_BOOL(present_dither, false, "UI/Presenter", + "Enable output dithering in the final present pass") + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_BOOL(present_allow_overscan_cutoff, false, "UI/Presenter", + "Allow overscan cutoff based on safe area settings") + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +namespace { +using GuestOutputPaintConfig = rex::ui::Presenter::GuestOutputPaintConfig; + +GuestOutputPaintConfig::Effect ParsePresentEffect(const std::string& effect_name) { + std::string lowered = effect_name; + std::transform(lowered.begin(), lowered.end(), lowered.begin(), + [](unsigned char c) { return char(std::tolower(c)); }); +#if defined(REX_HAS_FIDELITYFX_SDK) + if (lowered == "cas") { + return GuestOutputPaintConfig::Effect::kCas; + } + if (lowered == "fsr") { + return GuestOutputPaintConfig::Effect::kFsr; + } + if (lowered == "fsr2") { + return GuestOutputPaintConfig::Effect::kFsr2; + } + if (lowered == "fsr3") { + return GuestOutputPaintConfig::Effect::kFsr3; + } +#endif + return GuestOutputPaintConfig::Effect::kBilinear; +} + +#if defined(REX_HAS_FIDELITYFX_SDK) +bool IsTemporalFsrCompatibilityEffect(GuestOutputPaintConfig::Effect effect) { + return effect == GuestOutputPaintConfig::Effect::kFsr2 || + effect == GuestOutputPaintConfig::Effect::kFsr3; +} + +GuestOutputPaintConfig::FsrQualityMode ParsePresentFsrQualityMode(const std::string& mode_name) { + std::string lowered = mode_name; + std::transform(lowered.begin(), lowered.end(), lowered.begin(), [](unsigned char c) { + c = static_cast(std::tolower(c)); + return c == '-' ? '_' : char(c); + }); + if (lowered == "nativeaa" || lowered == "native_aa" || lowered == "native") { + return GuestOutputPaintConfig::FsrQualityMode::kNativeAa; + } + if (lowered == "quality") { + return GuestOutputPaintConfig::FsrQualityMode::kQuality; + } + if (lowered == "balanced") { + return GuestOutputPaintConfig::FsrQualityMode::kBalanced; + } + if (lowered == "performance") { + return GuestOutputPaintConfig::FsrQualityMode::kPerformance; + } + if (lowered == "ultra_performance" || lowered == "ultra") { + return GuestOutputPaintConfig::FsrQualityMode::kUltraPerformance; + } + return GuestOutputPaintConfig::FsrQualityMode::kAuto; +} + +bool GetFsrQualityModeApiValue(GuestOutputPaintConfig::FsrQualityMode mode, + uint32_t& api_mode_out) { + switch (mode) { + case GuestOutputPaintConfig::FsrQualityMode::kAuto: + return false; + case GuestOutputPaintConfig::FsrQualityMode::kNativeAa: +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME + api_mode_out = FFX_UPSCALE_QUALITY_MODE_NATIVEAA; +#else + api_mode_out = 0; +#endif + return true; + case GuestOutputPaintConfig::FsrQualityMode::kQuality: +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME + api_mode_out = FFX_UPSCALE_QUALITY_MODE_QUALITY; +#else + api_mode_out = 1; +#endif + return true; + case GuestOutputPaintConfig::FsrQualityMode::kBalanced: +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME + api_mode_out = FFX_UPSCALE_QUALITY_MODE_BALANCED; +#else + api_mode_out = 2; +#endif + return true; + case GuestOutputPaintConfig::FsrQualityMode::kPerformance: +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME + api_mode_out = FFX_UPSCALE_QUALITY_MODE_PERFORMANCE; +#else + api_mode_out = 3; +#endif + return true; + case GuestOutputPaintConfig::FsrQualityMode::kUltraPerformance: +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME + api_mode_out = FFX_UPSCALE_QUALITY_MODE_ULTRA_PERFORMANCE; +#else + api_mode_out = 4; +#endif + return true; + } + return false; +} + +float GetFsrQualityModeRatioFallback(GuestOutputPaintConfig::FsrQualityMode mode) { + switch (mode) { + case GuestOutputPaintConfig::FsrQualityMode::kNativeAa: + return 1.0f; + case GuestOutputPaintConfig::FsrQualityMode::kQuality: + return 1.5f; + case GuestOutputPaintConfig::FsrQualityMode::kBalanced: + return 1.7f; + case GuestOutputPaintConfig::FsrQualityMode::kPerformance: + return 2.0f; + case GuestOutputPaintConfig::FsrQualityMode::kUltraPerformance: + return 3.0f; + case GuestOutputPaintConfig::FsrQualityMode::kAuto: + default: + return 1.0f; + } +} + +bool QueryTemporalFsrRenderResolutionFromQualityMode(uint32_t display_width, + uint32_t display_height, + GuestOutputPaintConfig::FsrQualityMode mode, + uint32_t& render_width_out, + uint32_t& render_height_out) { + uint32_t api_mode = 0; + if (!GetFsrQualityModeApiValue(mode, api_mode)) { + return false; + } + +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME + ffxQueryDescUpscaleGetRenderResolutionFromQualityMode query_desc = {}; + query_desc.header.type = FFX_API_QUERY_DESC_TYPE_UPSCALE_GETRENDERRESOLUTIONFROMQUALITYMODE; + query_desc.header.pNext = nullptr; + query_desc.displayWidth = display_width; + query_desc.displayHeight = display_height; + query_desc.qualityMode = api_mode; + query_desc.pOutRenderWidth = &render_width_out; + query_desc.pOutRenderHeight = &render_height_out; + if (ffxQuery(nullptr, &query_desc.header) == FFX_API_RETURN_OK && render_width_out && + render_height_out) { + return true; + } +#endif + + float ratio = GetFsrQualityModeRatioFallback(mode); + render_width_out = std::max(uint32_t(1), uint32_t(float(display_width) / ratio + 0.5f)); + render_height_out = std::max(uint32_t(1), uint32_t(float(display_height) / ratio + 0.5f)); + return true; +} + +void LogTemporalFsrCompatibilityPathOnce() { + static std::atomic temporal_fsr_compatibility_logged = false; + if (!temporal_fsr_compatibility_logged.exchange(true)) { + REXLOG_WARN( + "present_effect=fsr2/fsr3 uses an experimental temporal upscaler path " + "with synthesized depth/motion inputs and may fall back to spatial FSR"); + } +} + +void LogTemporalFsrQualityModeInputLimitOnce() { + static std::atomic temporal_fsr_quality_mode_input_limit_logged = false; + if (!temporal_fsr_quality_mode_input_limit_logged.exchange(true)) { + REXLOG_WARN( + "present_fsr_quality_mode requested a render size larger than the " + "guest output; using guest output size"); + } +} +#endif // defined(REX_HAS_FIDELITYFX_SDK) + +GuestOutputPaintConfig BuildGuestOutputPaintConfigFromCVar() { + GuestOutputPaintConfig config; + GuestOutputPaintConfig::Effect parsed_effect = ParsePresentEffect(REXCVAR_GET(present_effect)); +#if defined(REX_HAS_FIDELITYFX_SDK) + if (IsTemporalFsrCompatibilityEffect(parsed_effect)) { + LogTemporalFsrCompatibilityPathOnce(); + } +#endif + config.SetAllowOverscanCutoff(REXCVAR_GET(present_allow_overscan_cutoff)); + config.SetEffect(parsed_effect); +#if defined(REX_HAS_FIDELITYFX_SDK) + config.SetCasAdditionalSharpness(float(REXCVAR_GET(present_cas_additional_sharpness))); + config.SetFsrMaxUpsamplingPasses( + uint32_t(std::max(int32_t(1), REXCVAR_GET(present_fsr_max_upsampling_passes)))); + config.SetFsrSharpnessReduction(float(REXCVAR_GET(present_fsr_sharpness_reduction))); + config.SetFsrQualityMode(ParsePresentFsrQualityMode(REXCVAR_GET(present_fsr_quality_mode))); +#endif + config.SetDither(REXCVAR_GET(present_dither)); + return config; +} + +} // namespace + +namespace rex { +namespace ui { + +void Presenter::FatalErrorHostGpuLossCallback([[maybe_unused]] bool is_responsible, + [[maybe_unused]] bool statically_from_ui_thread) { + rex::FatalError("Graphics device lost (probably due to an internal error)"); +} + +Presenter::~Presenter() { + // No intrusive lifetime management must be performed from UI drawers - defer + // it if needed. + assert_false(is_executing_ui_drawers_); + +#if REX_PLATFORM_WIN32 + if (dxgi_ui_tick_thread_.joinable()) { + { + std::scoped_lock dxgi_ui_tick_lock(dxgi_ui_tick_mutex_); + dxgi_ui_tick_thread_shutdown_ = true; + } + dxgi_ui_tick_control_condition_.notify_all(); + dxgi_ui_tick_thread_.join(); + } +#endif // XE_PLATFORM + + if (window_) { + Window* old_window = window_; + // Null the pointer to prevent an infinite loop between SetPresenter and + // SetWindowSurfaceFromUIThread calling each other. + window_ = nullptr; + old_window->SetPresenter(nullptr); + } +} + +void Presenter::SetWindowSurfaceFromUIThread(Window* new_window, Surface* new_surface) { + // No intrusive lifetime management must be performed from UI drawers - defer + // it if needed. + assert_false(is_executing_ui_drawers_); + + // There can't be a valid surface pointer without a window, as a surface is + // created and owned by the window. + assert_false(new_surface && !new_window); + + if (window_ == new_window && (!window_ || surface_ == new_surface)) { + // Nothing has changed (or a recursive SetWindowSurfaceFromUIThread > + // SetPresenter > SetWindowSurfaceFromUIThread call). + return; + } + + // Disconnect from the current surface. + if (surface_) { + // Take ownership of painting, and also stop accepting paint requests from + // the guest output thread - the window (which is required for making them) + // may be going away, and there will be a forced paint when the connection + // becomes available. + SetPaintModeFromUIThread(PaintMode::kNone); + DisconnectPaintingFromSurfaceFromUIThread( + SurfacePaintConnectionState::kUnconnectedRetryAtStateChange); + surface_ = nullptr; + UpdateSurfaceMonitorFromUIThread(true); + } + + if (window_ != new_window) { + // The window pointer may be accessed by the guest output thread if painting + // is possible (or was possible, but the paint attempt has resulted in the + // implementation reporting that the connection has become outdated). + // However, a painting connection is currently not established at all, so + // it's safe to modify the window pointer here. + + // Detach from the old window if attaching to a different one or just + // detaching. SetPresenter for the new window might have been called without + // it having been called with nullptr for the old window. + if (window_) { + Window* old_window = window_; + // Null the pointer to prevent an infinite loop between SetPresenter and + // SetWindowSurfaceFromUIThread calling each other. + window_ = nullptr; + old_window->SetPresenter(nullptr); + } + + // Attach to the new one. + // This function is called from SetPresenter - don't need to notify the + // window of this, as it itself has triggered this. + window_ = new_window; + } + + if (new_surface) { + assert_true(paint_mode_ == PaintMode::kNone); + surface_ = new_surface; + UpdateSurfaceMonitorFromUIThread(true); + assert_true(surface_paint_connection_state_ == + SurfacePaintConnectionState::kUnconnectedRetryAtStateChange); + bool request_repaint; + UpdateSurfacePaintConnectionFromUIThread(&request_repaint, true); + // Request to paint as soon as possible in the UI thread if connected + // successfully. + if (request_repaint) { + RequestPaintOrConnectionRecoveryViaWindow(true); + } + } +} + +void Presenter::OnSurfaceMonitorUpdateFromUIThread(bool old_monitor_potentially_disconnected) { + // No intrusive lifetime management must be performed from UI drawers - defer + // it if needed. + assert_false(is_executing_ui_drawers_); + + if (!surface_) { + return; + } + + UpdateSurfaceMonitorFromUIThread(old_monitor_potentially_disconnected); +} + +void Presenter::OnSurfaceResizeFromUIThread() { + // No intrusive lifetime management must be performed from UI drawers - defer + // it if needed. + assert_false(is_executing_ui_drawers_); + + if (!surface_) { + return; + } + + // Let the UI thread take ownership of painting (so the connection can be + // updated) in a smooth way - downgrade to kUIThreadOnRequest rather than + // kNone, because a forced repaint may not be necessary if, for example, the + // size internally turns out to be the same after the update, and in this case + // the current image may be kept - but the new one must not be missed either + // if it becomes available during the resize. + if (paint_mode_ == PaintMode::kGuestOutputThreadImmediately) { + SetPaintModeFromUIThread(PaintMode::kUIThreadOnRequest); + } + + bool request_repaint; + UpdateSurfacePaintConnectionFromUIThread(&request_repaint, true); + + // Request to repaint as soon as possible in the UI thread if needed. + if (request_repaint) { + RequestPaintOrConnectionRecoveryViaWindow(true); + } +} + +void Presenter::PaintFromUIThread(bool force_paint) { + // If there is no surface, this will be a no-op, nothing outdated, nothing to + // paint. However, an explicit monitor check is needed because UI framerate + // limiting may be tied to signals from the OS for the monitor - but painting + // may still occur, for instance, if drawing to a composition surface in the + // OS (which will still be live even if the window goes outside any monitor). + // But a surface check still won't cause harm, for simplicity. + if (!InSurfaceOnMonitorFromUIThread()) { + return; + } + + // Defer changes to the paint mode as well as window paint requests, and do + // them in this function so they're consistent with the assumptions made here. + assert_false(is_in_ui_thread_paint_); + is_in_ui_thread_paint_ = true; + request_guest_output_paint_after_current_ui_thread_paint_ = false; + request_ui_paint_after_current_ui_thread_paint_ = false; + + // Actualize the connection if the UI needs to be drawn if there was some + // explicit paint request (the guest output has been refreshed, and the guest + // output thread was asked not to present directly due as the UI needs to be + // drawn, or some surface state change has happened so the guest output needs + // to be displayed as soon as possible without waiting for the guest to + // refresh it, or the guest output thread has been notified that the + // connection has become outdated and has requested the UI thread to + // reconnect). + bool draw_ui = !ui_drawers_.empty(); + bool do_paint = force_paint || draw_ui; + // Reset ui_thread_paint_requested_ unconditionally also, regardless of + // whether the UI needs to be drawn - the flag may be set to try reconnecting, + // for example. + if (ui_thread_paint_requested_.exchange(false, std::memory_order_relaxed)) { + do_paint = true; + } + PaintResult paint_result = PaintResult::kNotPresented; + bool request_repaint_at_tick = false; + bool request_repaint_immediately = false; + if (do_paint) { + // Take ownership of painting if it's currently owned by the guest output + // thread (downgrade from kGuestOutputThreadImmediately to + // kUIThreadOnRequest - not to kNone so if during this paint a new guest + // output frame is generated, the notification will still be sent to the UI + // thread rather than dropped, so the frame won't be skipped). This is + // needed to be able not only to paint, but also to try to recover from an + // outdated surface. + if (paint_mode_ == PaintMode::kGuestOutputThreadImmediately) { + SetPaintModeFromUIThread(PaintMode::kUIThreadOnRequest); + } + // Try to recover from the connection becoming outdated in the previous + // paint. + if (surface_paint_connection_state_ == SurfacePaintConnectionState::kConnectedOutdated) { + UpdateSurfacePaintConnectionFromUIThread(nullptr, false); + } + // If still paintable or recovered successfully, paint. + if (surface_paint_connection_state_ == SurfacePaintConnectionState::kConnectedPaintable) { + // The paint mode might have been set to kNone when the connection was + // marked as outdated last time. Or, if wasn't reconnecting, there was + // some other incorrect situation that caused the paint mode to be set to + // kNone for an active connection. Make sure that the current paint mode + // is consistent with painting from the UI thread. + SetPaintModeFromUIThread(PaintMode::kUIThreadOnRequest); + + // Limit the frame rate of the UI, usually to the monitor refresh rate, + // in a way so that the UI won't be stealing all the remaining GPU + // resources if it's repainted continuously, and the window system itself + // doesn't limit the frame rate. + WaitForUITickFromUIThread(); + + paint_result = PaintAndPresent(draw_ui); + if (surface_paint_connection_state_ == SurfacePaintConnectionState::kConnectedOutdated) { + // Request another PaintFromUIThread which will try to recover from the + // outdated connection in the next frame (not immediately, so the + // windowing system has some time to prepare what may be required to + // recover from it, such as to send a resize event). + request_repaint_immediately = true; + } + } + // If can't paint anymore, notify the paint mode refresh below (which is not + // guaranteed to have access to have ownership of painting as it's taken + // here only conditionally, thus can't know whether the connection is + // actually in a paintable state). + if (surface_paint_connection_state_ != SurfacePaintConnectionState::kConnectedPaintable) { + SetPaintModeFromUIThread(PaintMode::kNone); + } + } + + // Transfer the ownership of painting back to the guest output thread if it + // was taken or if needed for any reason (however, it's taken conditionally - + // no guarantees that the actual connection state is accessible here, so only + // checking whether the mode is not kNone currently, not the connection + // state), and overall synchronize the state taking into account both what has + // been done in this function and what could have been done by the UI drawer + // callbacks. + if (paint_mode_ != PaintMode::kNone) { + SetPaintModeFromUIThread(GetDesiredPaintModeFromUIThread(true)); + } + is_in_ui_thread_paint_ = false; + + // Check if the device has been lost. There's no point in requesting repaint + // if it has happened anyway, it won't be possible to satisfy such request + // with the current Presenter. + if (paint_result == PaintResult::kGpuLostExternally || + paint_result == PaintResult::kGpuLostResponsible) { + if (host_gpu_loss_callback_) { + host_gpu_loss_callback_(paint_result == PaintResult::kGpuLostResponsible, true); + } + // The loss callback might have destroyed the presenter, must not do + // anything with `this` anymore. + return; + } + + // Request refresh if needed. + // Can't check the exact paintability as the connection state may currently + // be owned by the guest output thread, so check conservatively via + // paint_mode_. + if (paint_mode_ != PaintMode::kNone) { + // Immediately paint the guest output if requested explicitly or if the UI + // has hidden itself. + if (request_guest_output_paint_after_current_ui_thread_paint_ || + (draw_ui && ui_drawers_.empty())) { + request_repaint_immediately = true; + } + if (request_ui_paint_after_current_ui_thread_paint_ && !ui_drawers_.empty()) { + request_repaint_at_tick = true; + } + } + if (request_repaint_at_tick || request_repaint_immediately) { + RequestPaintOrConnectionRecoveryViaWindow(request_repaint_immediately); + } +} + +bool Presenter::RefreshGuestOutput( + uint32_t frontbuffer_width, uint32_t frontbuffer_height, uint32_t display_aspect_ratio_x, + uint32_t display_aspect_ratio_y, + std::function refresher) { + GuestOutputProperties& writable_properties = + guest_output_properties_[guest_output_mailbox_writable_]; + writable_properties.frontbuffer_width = frontbuffer_width; + writable_properties.frontbuffer_height = frontbuffer_height; + writable_properties.display_aspect_ratio_x = display_aspect_ratio_x; + writable_properties.display_aspect_ratio_y = display_aspect_ratio_y; + writable_properties.is_8bpc = false; + bool is_active = writable_properties.IsActive(); + if (is_active) { + if (!RefreshGuestOutputImpl(guest_output_mailbox_writable_, frontbuffer_width, + frontbuffer_height, refresher, writable_properties.is_8bpc)) { + // If failed to refresh, don't send the currently writable image to the + // mailbox as it may be in an undefined state. Don't disable the guest + // output either though because the failure may be something transient. + return false; + } + guest_output_active_last_refresh_ = true; + } else { + // Request presenting a blank image if there was a true image previously, + // but not now. + if (!guest_output_active_last_refresh_) { + return false; + } + guest_output_active_last_refresh_ = false; + } + + // Make the new image the next to present on the host (the "ready" one), + // replacing the one already specified as the next (dropping it instead of + // enqueueing the new image after it) to achieve the lowest latency (also, + // after switching from UI thread painting to doing it in the guest output + // thread, will immediately recover to having the latest frame always sent to + // the host present call on the CPU and all frames reaching a present call). + uint32_t last_acquired_and_ready = + guest_output_mailbox_acquired_and_ready_.load(std::memory_order_relaxed); + // Desired acquired = current acquired (changed only by the consumers). + // Desired ready = current writable. + // memory_order_acq_rel to acquire the new writable image and to release the + // current one (to let the consumers take it, from ready to acquired). + while (!guest_output_mailbox_acquired_and_ready_.compare_exchange_weak( + last_acquired_and_ready, + (last_acquired_and_ready & 3) | (guest_output_mailbox_writable_ << 2), + std::memory_order_acq_rel, std::memory_order_relaxed)) {} + // Now, it's known that `ready == writable` on the host presentation side. + // Take the next `writable` with this assumption about its current value in + // mind. + uint32_t last_acquired = last_acquired_and_ready & 3; + if (last_acquired == guest_output_mailbox_writable_) { + // The new image has already been acquired by the time the compare-exchange + // loop has finished (acquired == ready == currently writable). + // It's a valid situation from the ownership perspective, and the semantics + // of the weak compare-exchange explicitly permit spurious `false` results. + // (3 - a - b) % 3 cannot be used here, as (3 - a - a) % 3 results in `a` - + // the same index. + // Take any free image. Preferably using + 1, not ^ 1, so if the guest needs + // to await any GPU work referencing the image, it will wait for the frame 3 + // frames ago, not 2, if this happens repeatedly. + guest_output_mailbox_writable_ = (guest_output_mailbox_writable_ + 1) % 3; + } else { + // Take the image other than the last acquired one and the new one, + // currently not accessible to the host presentation. + guest_output_mailbox_writable_ = (3 - last_acquired - guest_output_mailbox_writable_) % 3; + } + + // Trigger the presentation on the host. + PaintResult paint_result = PaintResult::kNotPresented; + { + std::lock_guard paint_mode_mutex_lock(paint_mode_mutex_); + switch (paint_mode_) { + case PaintMode::kNone: + // Neither painting nor window paint requesting is accessible. + break; + case PaintMode::kUIThreadOnRequest: + // Only window paint requesting is accessible. + RequestPaintOrConnectionRecoveryViaWindow(true); + break; + case PaintMode::kGuestOutputThreadImmediately: + // Both painting and window paint requesting are accessible. + if (surface_paint_connection_state_ == SurfacePaintConnectionState::kConnectedPaintable) { + paint_result = PaintAndPresent(false); + if (surface_paint_connection_state_ == SurfacePaintConnectionState::kConnectedOutdated) { + RequestPaintOrConnectionRecoveryViaWindow(true); + } + } + break; + } + } + // Handle GPU loss when not in the middle of the function anymore, and + // lifecycle management from the GPU loss callback is fine on the UI thread. + if (host_gpu_loss_callback_) { + if (paint_result == PaintResult::kGpuLostResponsible) { + host_gpu_loss_callback_(true, false); + } else if (paint_result == PaintResult::kGpuLostExternally) { + host_gpu_loss_callback_(false, false); + } + } + + return is_active; +} + +void Presenter::SetGuestOutputPaintConfigFromUIThread(const GuestOutputPaintConfig& new_config) { + // For simplicity, this may be called externally repeatedly. + // Lock the mutex only when something has been modified, and also don't + // request UI thread guest output redraws when not needed. + bool modified = false; + bool request_repaint = false; + if (guest_output_paint_config_.GetEffect() != new_config.GetEffect()) { + modified = true; + request_repaint = true; + } +#if defined(REX_HAS_FIDELITYFX_SDK) + if (guest_output_paint_config_.GetFsrSharpnessReduction() != + new_config.GetFsrSharpnessReduction()) { + modified = true; + if (new_config.GetEffect() == GuestOutputPaintConfig::Effect::kFsr || + new_config.GetEffect() == GuestOutputPaintConfig::Effect::kFsr2 || + new_config.GetEffect() == GuestOutputPaintConfig::Effect::kFsr3) { + request_repaint = true; + } + } + if (guest_output_paint_config_.GetCasAdditionalSharpness() != + new_config.GetCasAdditionalSharpness()) { + modified = true; + if (new_config.GetEffect() == GuestOutputPaintConfig::Effect::kCas || + new_config.GetEffect() == GuestOutputPaintConfig::Effect::kFsr || + new_config.GetEffect() == GuestOutputPaintConfig::Effect::kFsr2 || + new_config.GetEffect() == GuestOutputPaintConfig::Effect::kFsr3) { + request_repaint = true; + } + } +#endif + if (guest_output_paint_config_.GetDither() != new_config.GetDither()) { + modified = true; + request_repaint = true; + } +#if defined(REX_HAS_FIDELITYFX_SDK) + if (guest_output_paint_config_.GetFsrQualityMode() != new_config.GetFsrQualityMode()) { + modified = true; + if (new_config.GetEffect() == GuestOutputPaintConfig::Effect::kFsr2 || + new_config.GetEffect() == GuestOutputPaintConfig::Effect::kFsr3) { + request_repaint = true; + } + } +#endif + if (modified) { + { + std::unique_lock config_lock(guest_output_paint_config_mutex_); + guest_output_paint_config_ = new_config; + } + // Coarsely check the availability of painting and of the window (for + // calling RequestPaint) via paint_mode_ because the actual painting + // connection state may currently be owned not by the UI thread. + if (request_repaint && paint_mode_ != PaintMode::kNone) { + if (is_in_ui_thread_paint_) { + // Defer until the end of the current paint if called from, for + // instance, a UI drawer. + request_guest_output_paint_after_current_ui_thread_paint_ = true; + } else { + RequestPaintOrConnectionRecoveryViaWindow(true); + } + } + } +} + +void Presenter::AddUIDrawerFromUIThread(UIDrawer* drawer, size_t z_order) { + assert_not_null(drawer); + // Obtain whether the iterator list was empty before erasing in case of + // replacing with a new entry with a different Z order happens. + bool drawers_were_empty = ui_drawers_.empty(); + uint64_t drawer_last_draw = UINT64_MAX; + // Check if already added. + for (auto it_existing = ui_drawers_.begin(); it_existing != ui_drawers_.end(); ++it_existing) { + if (it_existing->second.drawer != drawer) { + continue; + } + if (it_existing->first == z_order) { + return; + } + // Keep the same last draw index to prevent the drawer from being executed + // twice if increasing its Z order during the drawer loop. + drawer_last_draw = it_existing->second.last_draw; + // If removing the drawer that is the next in the current drawer loop, skip + // it (in a multimap, only one element iterator is invalidated). + if (is_executing_ui_drawers_ && ui_draw_next_iterator_ == it_existing) { + ++ui_draw_next_iterator_; + } + ui_drawers_.erase(it_existing); + break; + } + auto it_new = ui_drawers_.emplace(z_order, UIDrawerReference(drawer, drawer_last_draw)); + // If adding to the Z layer currently being processed (for drawing, from the + // lowest to the highest), or to layers in between the current and the + // previously next, make sure the new drawer is executed too. + if (is_executing_ui_drawers_ && z_order >= ui_draw_current_z_order_ && + (ui_draw_next_iterator_ == ui_drawers_.end() || z_order < ui_draw_next_iterator_->first)) { + ui_draw_next_iterator_ = it_new; + } + HandleUIDrawersChangeFromUIThread(drawers_were_empty); +} + +void Presenter::RemoveUIDrawerFromUIThread(UIDrawer* drawer) { + assert_not_null(drawer); + for (auto it_existing = ui_drawers_.begin(); it_existing != ui_drawers_.end(); ++it_existing) { + if (it_existing->second.drawer != drawer) { + continue; + } + // If removing the drawer that is the next in the current drawer loop, skip + // it (in a multimap, only one element iterator is invalidated). + if (is_executing_ui_drawers_ && ui_draw_next_iterator_ == it_existing) { + ++ui_draw_next_iterator_; + } + ui_drawers_.erase(it_existing); + HandleUIDrawersChangeFromUIThread(false); + return; + } +} + +void Presenter::RequestUIPaintFromUIThread() { + if (is_in_ui_thread_paint_) { + // The paint request will be done once in the end of PaintFromUIThread + // according to the actual state at the moment that happens. It's common for + // drawers to call this (even every frame), and no need to do too many OS + // paint request calls. + request_ui_paint_after_current_ui_thread_paint_ = true; + return; + } + // The connection state may be owned by the guest output thread now rather + // than the UI thread, check whether it's not pointless to make the request + // coarsely via paint_mode_. + if (!ui_drawers_.empty() && paint_mode_ != PaintMode::kNone) { + // The window must be present, otherwise the conditions wouldn't have been + // met. + window_->RequestPaint(); + } +} + +bool Presenter::InitializeCommonSurfaceIndependent() { + { + std::lock_guard config_lock(guest_output_paint_config_mutex_); + guest_output_paint_config_ = BuildGuestOutputPaintConfigFromCVar(); + } + + // Initialize UI frame rate limiting. +#if REX_PLATFORM_WIN32 + dxgi_ui_tick_thread_ = std::thread(&Presenter::DXGIUITickThread, this); +#endif // XE_PLATFORM + + return true; +} + +std::unique_lock Presenter::ConsumeGuestOutput( + uint32_t& mailbox_index_or_max_if_inactive_out, GuestOutputProperties* properties_out, + GuestOutputPaintConfig* paint_config_out) { + if (paint_config_out) { + // Get the up-to-date guest output paint configuration settings set by the + // UI thread. + std::unique_lock config_lock(guest_output_paint_config_mutex_); + *paint_config_out = guest_output_paint_config_; + } + + // Lock the mutex to make sure the image that will be acquired now is owned + // exclusively by the calling thread for the time while this mutex is still + // locked (it needs to be held by the consumer while working with anything + // that depends on the image now being acquired or its index in the mailbox). + std::unique_lock consumer_lock(guest_output_mailbox_consumer_mutex_); + // Acquire the up-to-date ready guest image (may be new, in this case the last + // acquired one will be released, or still the same or no refresh has happened + // since the last consumption). + // memory_order_relaxed here because the ready index from this load will be + // used directly only if it's the same as during the last consumption - thus + // the image has already been acquired previously, no need for + // memory_order_acquire (if the image has been acquired by a different + // consumer though, the consumer mutex performs memory access ordering). + uint32_t old_acquired_and_ready = + guest_output_mailbox_acquired_and_ready_.load(std::memory_order_relaxed); + // Desired acquired = current ready. + // Desired ready = current ready (changed only by the producer). + uint32_t desired_acquired_and_ready = + (old_acquired_and_ready & ~uint32_t(3)) | (old_acquired_and_ready >> 2); + // Either the same image as during the last consumption, or a new one, is + // satisfying. However, if it's new, using memory_order_acq_rel to acquire the + // new ready image (to make it acquired) and to release the old acquired image + // (to let the producer take it as writable). + while (old_acquired_and_ready != desired_acquired_and_ready && + !guest_output_mailbox_acquired_and_ready_.compare_exchange_weak( + old_acquired_and_ready, desired_acquired_and_ready, std::memory_order_acq_rel, + std::memory_order_relaxed)) { + desired_acquired_and_ready = + (old_acquired_and_ready & ~uint32_t(3)) | (old_acquired_and_ready >> 2); + } + uint32_t mailbox_index = desired_acquired_and_ready & 3; + // Give the current acquired image to the caller, or UINT32_MAX if it's + // inactive. + const GuestOutputProperties& properties = guest_output_properties_[mailbox_index]; + mailbox_index_or_max_if_inactive_out = properties.IsActive() ? mailbox_index : UINT32_MAX; + if (properties_out) { + *properties_out = properties; + } + return std::move(consumer_lock); +} + +Presenter::GuestOutputPaintFlow Presenter::GetGuestOutputPaintFlow( + const GuestOutputProperties& properties, uint32_t host_rt_width, uint32_t host_rt_height, + uint32_t max_rt_width, uint32_t max_rt_height, const GuestOutputPaintConfig& config) const { + GuestOutputPaintFlow flow = {}; + + // FIXME(Triang3l): Configuration variables racing with per-game config + // loading. + + assert_not_zero(max_rt_width); + assert_not_zero(max_rt_height); + + // Initialize one clear rectangle for the case of drawing no guest output, for + // consistency with fewer state dependencies. + flow.letterbox_clear_rectangle_count = 1; + flow.letterbox_clear_rectangles[0].width = host_rt_width; + flow.letterbox_clear_rectangles[0].height = host_rt_height; + + // For safety such as division by zero prevention. + if (!properties.IsActive() || !host_rt_width || !host_rt_height || + !surface_width_in_paint_connection_ || !surface_height_in_paint_connection_) { + return flow; + } + + flow.properties = properties; + + // Multiplication-division rounding to the nearest. + auto rescale_unsigned = [](uint32_t value, uint32_t new_scale, uint32_t old_scale) -> uint32_t { + return uint32_t((uint64_t(value) * new_scale + (old_scale >> 1)) / old_scale); + }; + auto rescale_signed = [](int32_t value, uint32_t new_scale, uint32_t old_scale) -> int32_t { + // Plus old_scale / 2 for positive values, minus old_scale / 2 for + // negative values for consistent rounding for both positive and + // negative values (as the `/` operator rounds towards zero). + // Example: + // (-3 - 1) / 3 == -1 + // (-2 - 1) / 3 == -1 + // (-1 - 1) / 3 == 0 + // --- + // (0 + 1) / 3 == 0 + // (1 + 1) / 3 == 0 + // (2 + 1) / 3 == 1 + return int32_t((int64_t(value) * new_scale + int32_t(old_scale >> 1) * (value < 0 ? -1 : 1)) / + old_scale); + }; + + // Final output location and dimensions. + // All host location calculations are DPI-independent, conceptually depending + // only on the aspect ratios, not the absolute values. + uint32_t output_width, output_height; + if (uint64_t(surface_width_in_paint_connection_) * properties.display_aspect_ratio_y > + uint64_t(surface_height_in_paint_connection_) * properties.display_aspect_ratio_x) { + // The window is wider that the source - crop along Y to preserve the aspect + // ratio while stretching throughout the entire surface's width, then limit + // the Y cropping via letterboxing or stretching along X. + uint32_t present_safe_area; + if (config.GetAllowOverscanCutoff() && REXCVAR_GET(present_safe_area_y) > 0 && + REXCVAR_GET(present_safe_area_y) < 100) { + present_safe_area = uint32_t(REXCVAR_GET(present_safe_area_y)); + } else { + present_safe_area = 100; + } + // Scale the desired width by the H:W aspect ratio (inverse of W:H) to get + // the height. + output_height = + rescale_unsigned(surface_width_in_paint_connection_, properties.display_aspect_ratio_y, + properties.display_aspect_ratio_x); + bool letterbox = false; + if (output_height * present_safe_area > surface_height_in_paint_connection_ * 100) { + // Don't crop out more than the safe area margin - letterbox or stretch. + output_height = rescale_unsigned(surface_height_in_paint_connection_, 100, present_safe_area); + letterbox = true; + } + if (letterbox && REXCVAR_GET(present_letterbox)) { + output_width = rescale_unsigned(surface_height_in_paint_connection_ * 100, + properties.display_aspect_ratio_x, + properties.display_aspect_ratio_y * present_safe_area); + // output_width might have been rounded up already by rescale_unsigned, so + // rounding down in this division. + flow.output_x = (int32_t(surface_width_in_paint_connection_) - int32_t(output_width)) / 2; + } else { + output_width = surface_width_in_paint_connection_; + flow.output_x = 0; + } + // output_height might have been rounded up already by rescale_unsigned, so + // rounding down in this division. + flow.output_y = (int32_t(surface_height_in_paint_connection_) - int32_t(output_height)) / 2; + } else { + // The window is taller that the source - crop along X to preserve the + // aspect ratio while stretching throughout the entire surface's height, + // then limit the X cropping via letterboxing or stretching along Y. + uint32_t present_safe_area; + if (config.GetAllowOverscanCutoff() && REXCVAR_GET(present_safe_area_x) > 0 && + REXCVAR_GET(present_safe_area_x) < 100) { + present_safe_area = uint32_t(REXCVAR_GET(present_safe_area_x)); + } else { + present_safe_area = 100; + } + // Scale the desired height by the W:H aspect ratio to get the width. + output_width = + rescale_unsigned(surface_height_in_paint_connection_, properties.display_aspect_ratio_x, + properties.display_aspect_ratio_y); + bool letterbox = false; + if (output_width * present_safe_area > surface_width_in_paint_connection_ * 100) { + // Don't crop out more than the safe area margin - letterbox or stretch. + output_width = rescale_unsigned(surface_width_in_paint_connection_, 100, present_safe_area); + letterbox = true; + } + if (letterbox && REXCVAR_GET(present_letterbox)) { + output_height = rescale_unsigned(surface_width_in_paint_connection_ * 100, + properties.display_aspect_ratio_y, + properties.display_aspect_ratio_x * present_safe_area); + // output_height might have been rounded up already by rescale_unsigned, + // so rounding down in this division. + flow.output_y = (int32_t(surface_height_in_paint_connection_) - int32_t(output_height)) / 2; + } else { + output_height = surface_height_in_paint_connection_; + flow.output_y = 0; + } + // output_width might have been rounded up already by rescale_unsigned, so + // rounding down in this division. + flow.output_x = (int32_t(surface_width_in_paint_connection_) - int32_t(output_width)) / 2; + } + + // Convert the location from surface pixels (which have 1:1 aspect ratio + // relatively to the physical display) to render target pixels (the render + // target size may be arbitrary with any aspect ratio, but if it's different + // than the surface size, the OS is expected to stretch it to the surface + // boundaries), preserving the aspect ratio. + if (host_rt_width != surface_width_in_paint_connection_) { + flow.output_x = + rescale_signed(flow.output_x, host_rt_width, surface_width_in_paint_connection_); + output_width = + rescale_unsigned(output_width, host_rt_width, surface_width_in_paint_connection_); + } + if (host_rt_height != surface_height_in_paint_connection_) { + flow.output_y = + rescale_signed(flow.output_y, host_rt_height, surface_height_in_paint_connection_); + output_height = + rescale_unsigned(output_height, host_rt_height, surface_height_in_paint_connection_); + } + + // The out-of-bounds checks are needed for correct letterbox calculations. + // Though this normally shouldn't happen, but in case of rounding issues with + // extreme values. + int32_t output_right = flow.output_x + int32_t(output_width); + int32_t output_bottom = flow.output_y + int32_t(output_height); + // In rare cases (for example, when surface and render-target coordinate + // spaces diverge unexpectedly), the computed output may become anchored at + // the top-left and smaller than the host render target. This results in only + // a top-left region being presented with black right/bottom areas. + if (flow.output_x >= 0 && flow.output_y >= 0 && flow.output_x <= 1 && flow.output_y <= 1 && + output_width < host_rt_width && output_height < host_rt_height) { + static std::atomic logged_top_left_expand = false; + if (!logged_top_left_expand.exchange(true)) { + REXLOG_WARN( + "Presenter: expanding guest output from {}x{} to host render target " + "{}x{} to avoid top-left-only presentation", + output_width, output_height, host_rt_width, host_rt_height); + } + output_width = host_rt_width; + output_height = host_rt_height; + output_right = int32_t(output_width); + output_bottom = int32_t(output_height); + } + if (!output_width || !output_height || output_right <= 0 || output_bottom <= 0 || + flow.output_x >= int32_t(host_rt_width) || flow.output_y >= int32_t(host_rt_height)) { + return flow; + } + + // The output image may have a part of it outside the final render target (if + // using the overscan area to stretch the image to the entire surface while + // preserving the guest aspect ratio if it differs from the host one, for + // instance). While the final render target size is known to be within the + // host render target / image size limit, the intermediate images may be + // larger than that as they include the overscan area that will be outside the + // screen. Make sure the intermediate images can't be larger than the maximum + // render target size. + uint32_t output_width_clamped = std::min(output_width, max_rt_width); + uint32_t output_height_clamped = std::min(output_height, max_rt_height); + +#if defined(REX_HAS_FIDELITYFX_SDK) + if (config.GetEffect() == GuestOutputPaintConfig::Effect::kCas || + config.GetEffect() == GuestOutputPaintConfig::Effect::kFsr || + config.GetEffect() == GuestOutputPaintConfig::Effect::kFsr2 || + config.GetEffect() == GuestOutputPaintConfig::Effect::kFsr3) { + // FidelityFX Super Resolution and Contrast Adaptive Sharpening only work + // good for up to 2x2 upscaling due to the way they fetch texels. + // CAS is primarily a sharpening filter, not an upscaling one (its upscaling + // eliminates reduces blurriness, but doesn't preserve the shapes of edges, + // and executing it multiple times will only result in oversharpening. So, + // using it for scales only of up to 2x2, then simply stretching with + // bilinear filtering. + // EASU of FSR, however, preserves edges, it's not supposed to blur them or + // to make them jagged, so it can be executed multiple times - running + // multiple EASU passes for scale factors of over 2x2. + // Just one EASU pass rather than multiple for scaling to factors bigger + // than 2x2 (especially significantly bigger, such as 1152x640 to 3840x2160, + // or 3.333x3.375) results in blurry edges and an overall noisy look, + // multiple passes improve visual stability. + std::pair ffx_last_size; + if (flow.effect_count) { + ffx_last_size = flow.effect_output_sizes[flow.effect_count - 1]; + } else { + ffx_last_size.first = properties.frontbuffer_width; + ffx_last_size.second = properties.frontbuffer_height; + } + bool is_temporal_effect = config.GetEffect() == GuestOutputPaintConfig::Effect::kFsr2 || + config.GetEffect() == GuestOutputPaintConfig::Effect::kFsr3; + bool temporal_quality_mode_forced = + is_temporal_effect && + config.GetFsrQualityMode() != GuestOutputPaintConfig::FsrQualityMode::kAuto; + if ((config.GetEffect() == GuestOutputPaintConfig::Effect::kFsr || is_temporal_effect) && + ((ffx_last_size.first < output_width_clamped || + ffx_last_size.second < output_height_clamped) || + temporal_quality_mode_forced)) { + // AMD FidelityFX Super Resolution - upsample along at least one axis. + // Using the output size clamped to the maximum render target size here as + // EASU will always write to intermediate images, and RCAS supports only + // 1:1. + if (is_temporal_effect) { + uint32_t temporal_input_width = ffx_last_size.first; + uint32_t temporal_input_height = ffx_last_size.second; + uint32_t quality_mode_render_width = 0; + uint32_t quality_mode_render_height = 0; + if (QueryTemporalFsrRenderResolutionFromQualityMode( + output_width_clamped, output_height_clamped, config.GetFsrQualityMode(), + quality_mode_render_width, quality_mode_render_height)) { + quality_mode_render_width = + std::max(uint32_t(1), std::min(quality_mode_render_width, output_width_clamped)); + quality_mode_render_height = + std::max(uint32_t(1), std::min(quality_mode_render_height, output_height_clamped)); + if (quality_mode_render_width < temporal_input_width || + quality_mode_render_height < temporal_input_height) { + temporal_input_width = quality_mode_render_width; + temporal_input_height = quality_mode_render_height; + if (temporal_input_width != ffx_last_size.first || + temporal_input_height != ffx_last_size.second) { + assert_true(flow.effect_count < flow.effects.size()); + flow.effect_output_sizes[flow.effect_count] = + std::make_pair(temporal_input_width, temporal_input_height); + // Pre-temporal quality mode may request a lower render + // resolution. Use CAS resample since bilinear is not allowed in + // intermediate passes. + flow.effects[flow.effect_count++] = GuestOutputPaintEffect::kCasResample; + ffx_last_size.first = temporal_input_width; + ffx_last_size.second = temporal_input_height; + } + } else if (quality_mode_render_width > temporal_input_width || + quality_mode_render_height > temporal_input_height) { + LogTemporalFsrQualityModeInputLimitOnce(); + } + } + + // A single temporal upscaler dispatch can target the final clamped + // size directly, unlike the spatial multi-pass chain. + ffx_last_size.first = output_width_clamped; + ffx_last_size.second = output_height_clamped; + assert_true(flow.effect_count < flow.effects.size()); + flow.effect_output_sizes[flow.effect_count] = ffx_last_size; + flow.effects[flow.effect_count++] = GuestOutputPaintEffect::kFsrEasu; + } else { + uint32_t easu_max_passes = config.GetFsrMaxUpsamplingPasses(); + uint32_t easu_pass_count = 0; + while (easu_pass_count < easu_max_passes && + (ffx_last_size.first < output_width_clamped || + ffx_last_size.second < output_height_clamped)) { + ffx_last_size.first = std::min(ffx_last_size.first * uint32_t(2), output_width_clamped); + ffx_last_size.second = + std::min(ffx_last_size.second * uint32_t(2), output_height_clamped); + assert_true(flow.effect_count < flow.effects.size()); + flow.effect_output_sizes[flow.effect_count] = ffx_last_size; + flow.effects[flow.effect_count++] = GuestOutputPaintEffect::kFsrEasu; + ++easu_pass_count; + } + } + assert_true(flow.effect_count < flow.effects.size()); + flow.effect_output_sizes[flow.effect_count] = ffx_last_size; + flow.effects[flow.effect_count++] = GuestOutputPaintEffect::kFsrRcas; + } else { + // AMD FidelityFX Contrast Adaptive Sharpening - sharpen or downsample, or + // upsample up to 2x2 if CAS is specified to be used for upscaling too. + // Using the unclamped output size as CAS may be the last pass - if a + // bilinear pass is needed afterwards, and the CAS pass will be writing to + // an intermediate image, the CAS pass output size will be clamped while + // adding the bilinear stretch. + std::pair pre_cas_size = ffx_last_size; + ffx_last_size.first = std::min(ffx_last_size.first * uint32_t(2), output_width); + ffx_last_size.second = std::min(ffx_last_size.second * uint32_t(2), output_height); + assert_true(flow.effect_count < flow.effects.size()); + flow.effect_output_sizes[flow.effect_count] = ffx_last_size; + flow.effects[flow.effect_count++] = ffx_last_size == pre_cas_size + ? GuestOutputPaintEffect::kCasSharpen + : GuestOutputPaintEffect::kCasResample; + } + } +#endif // defined(REX_HAS_FIDELITYFX_SDK) + + std::pair* last_pre_bilinear_effect_size = + flow.effect_count ? &flow.effect_output_sizes[flow.effect_count - 1] : nullptr; + if (!last_pre_bilinear_effect_size || last_pre_bilinear_effect_size->first != output_width || + last_pre_bilinear_effect_size->second != output_height) { + // If not using FidelityFX, or it has reached its upscaling capabilities, + // but more is needed, stretch via bilinear filtering. + // Clamp the output size of the last effect to the maximum render target + // size because it will go to an intermediate image now. + if (last_pre_bilinear_effect_size) { +#if defined(REX_HAS_FIDELITYFX_SDK) + // RCAS only works for 1:1, clamping must be done explicitly for FSR. + assert_false(flow.effects[flow.effect_count - 1] == GuestOutputPaintEffect::kFsrRcas && + (last_pre_bilinear_effect_size->first > max_rt_width || + last_pre_bilinear_effect_size->second > max_rt_height)); +#endif + last_pre_bilinear_effect_size->first = + std::min(last_pre_bilinear_effect_size->first, max_rt_width); + last_pre_bilinear_effect_size->second = + std::min(last_pre_bilinear_effect_size->second, max_rt_height); + } + assert_true(flow.effect_count < flow.effects.size()); + flow.effect_output_sizes[flow.effect_count] = std::make_pair(output_width, output_height); + flow.effects[flow.effect_count++] = GuestOutputPaintEffect::kBilinear; + } + + assert_not_zero(flow.effect_count); + + if (config.GetDither()) { + // Dithering must be applied only to the final effect since resampling and + // sharpening filters may considering the dithering noise features and + // amplify it. + GuestOutputPaintEffect& last_effect = flow.effects[flow.effect_count - 1]; + switch (last_effect) { + case GuestOutputPaintEffect::kBilinear: + // Dithering has no effect for 1:1 copying of a 8bpc image. + if (!properties.is_8bpc || flow.effect_count > 1 || + output_width != properties.frontbuffer_width || + output_height != properties.frontbuffer_height) { + last_effect = GuestOutputPaintEffect::kBilinearDither; + } + break; +#if defined(REX_HAS_FIDELITYFX_SDK) + case GuestOutputPaintEffect::kCasSharpen: + last_effect = GuestOutputPaintEffect::kCasSharpenDither; + break; + case GuestOutputPaintEffect::kCasResample: + last_effect = GuestOutputPaintEffect::kCasResampleDither; + break; + case GuestOutputPaintEffect::kFsrRcas: + last_effect = GuestOutputPaintEffect::kFsrRcasDither; + break; +#endif + default: + break; + } + } + +#ifndef NDEBUG + for (size_t i = 0; i + 1 < flow.effect_count; ++i) { + assert_true(CanGuestOutputPaintEffectBeIntermediate(flow.effects[i])); + } + assert_true(CanGuestOutputPaintEffectBeFinal(flow.effects[flow.effect_count - 1])); +#endif + + // Calculate the letterbox geometry. + if (flow.effect_count) { + flow.letterbox_clear_rectangle_count = 0; + uint32_t letterbox_mid_top = uint32_t(std::max(flow.output_y, int32_t(0))); + // Top. + if (letterbox_mid_top) { + assert_true(flow.letterbox_clear_rectangle_count < flow.letterbox_clear_rectangles.size()); + GuestOutputPaintFlow::ClearRectangle& letterbox_clear_rectangle_top = + flow.letterbox_clear_rectangles[flow.letterbox_clear_rectangle_count++]; + letterbox_clear_rectangle_top.x = 0; + letterbox_clear_rectangle_top.y = 0; + letterbox_clear_rectangle_top.width = host_rt_width; + letterbox_clear_rectangle_top.height = letterbox_mid_top; + } + uint32_t letterbox_mid_bottom = std::min(uint32_t(output_bottom), host_rt_height); + uint32_t letterbox_mid_height = letterbox_mid_bottom - letterbox_mid_top; + // Middle-left. + if (flow.output_x > 0) { + assert_true(flow.letterbox_clear_rectangle_count < flow.letterbox_clear_rectangles.size()); + GuestOutputPaintFlow::ClearRectangle& letterbox_clear_rectangle_left = + flow.letterbox_clear_rectangles[flow.letterbox_clear_rectangle_count++]; + letterbox_clear_rectangle_left.x = 0; + letterbox_clear_rectangle_left.y = letterbox_mid_top; + letterbox_clear_rectangle_left.width = uint32_t(flow.output_x); + letterbox_clear_rectangle_left.height = letterbox_mid_height; + } + // Middle-right. + if (uint32_t(output_right) < host_rt_width) { + assert_true(flow.letterbox_clear_rectangle_count < flow.letterbox_clear_rectangles.size()); + GuestOutputPaintFlow::ClearRectangle& letterbox_clear_rectangle_right = + flow.letterbox_clear_rectangles[flow.letterbox_clear_rectangle_count++]; + letterbox_clear_rectangle_right.x = uint32_t(output_right); + letterbox_clear_rectangle_right.y = letterbox_mid_top; + letterbox_clear_rectangle_right.width = host_rt_width - uint32_t(output_right); + letterbox_clear_rectangle_right.height = letterbox_mid_height; + } + // Bottom. + if (letterbox_mid_bottom < host_rt_height) { + assert_true(flow.letterbox_clear_rectangle_count < flow.letterbox_clear_rectangles.size()); + GuestOutputPaintFlow::ClearRectangle& letterbox_clear_rectangle_top = + flow.letterbox_clear_rectangles[flow.letterbox_clear_rectangle_count++]; + letterbox_clear_rectangle_top.x = 0; + letterbox_clear_rectangle_top.y = letterbox_mid_bottom; + letterbox_clear_rectangle_top.width = host_rt_width; + letterbox_clear_rectangle_top.height = host_rt_height - letterbox_mid_bottom; + } + } + + return flow; +} + +void Presenter::ExecuteUIDrawersFromUIThread(UIDrawContext& ui_draw_context) { + // May be called by the implementations only when requested. + assert_true(is_in_ui_thread_paint_); + // Drawers can add or remove drawers (including themselves), need to ensure + // iterator validity in this case. + assert_false(is_executing_ui_drawers_); + ui_draw_next_iterator_ = ui_drawers_.begin(); + is_executing_ui_drawers_ = true; + while (ui_draw_next_iterator_ != ui_drawers_.end()) { + // The current iterator may be invalidated, and ui_draw_next_iterator_ may + // be changed, during the execution of the drawer if the list of the drawers + // is modified by it - don't assume that after the call + // ui_draw_next_iterator_ will be the same as + // std::next(ui_draw_next_iterator_) before it. + auto it_current = ui_draw_next_iterator_++; + // Don't draw twice if already drawn in this frame (may happen if the Z + // order of a drawer was increased from below the current one to above it by + // one of the drawers). + if (it_current->second.last_draw != ui_draw_current_) { + ui_draw_current_z_order_ = it_current->first; + it_current->second.last_draw = ui_draw_current_; + it_current->second.drawer->Draw(ui_draw_context); + } + } + is_executing_ui_drawers_ = false; + ++ui_draw_current_; +} + +void Presenter::SetPaintModeFromUIThread(PaintMode new_mode) { + // Can be modified only from the UI thread, so can skip locking if it's the + // same. + if (paint_mode_ == new_mode) { + return; + } + { + std::lock_guard lock(paint_mode_mutex_); + paint_mode_ = new_mode; + } + UpdateUITicksNeededFromUIThread(); +} + +Presenter::PaintMode Presenter::GetDesiredPaintModeFromUIThread(bool is_paintable) const { + if (!is_paintable) { + // The only case when kNone can be returned, for surface connection updates + // when it's known that the UI thread currently has access to the connection + // lifecycle. + return PaintMode::kNone; + } + if (!REXCVAR_GET(host_present_from_non_ui_thread)) { + return PaintMode::kUIThreadOnRequest; + } + if (surface_paint_connection_has_implicit_vsync_) { + // Don't be causing host vertical sync CPU waits in the thread generating + // the guest output. + return PaintMode::kUIThreadOnRequest; + } + if (!ui_drawers_.empty()) { + // The UI can be drawn only by the UI thread, and it needs to be drawn - + // paint in the UI thread. + return PaintMode::kUIThreadOnRequest; + } + // Only the guest output needs to be drawn - let the guest output thread + // present immediately for a lower latency. + return PaintMode::kGuestOutputThreadImmediately; +} + +void Presenter::DisconnectPaintingFromSurfaceFromUIThread(SurfacePaintConnectionState new_state) { + assert_false(IsConnectedSurfacePaintConnectionState(new_state)); + if (IsConnectedSurfacePaintConnectionState(surface_paint_connection_state_)) { + DisconnectPaintingFromSurfaceFromUIThreadImpl(); + } + surface_paint_connection_state_ = new_state; + surface_paint_connection_has_implicit_vsync_ = false; + surface_width_in_paint_connection_ = 0; + surface_height_in_paint_connection_ = 0; +} + +void Presenter::UpdateSurfacePaintConnectionFromUIThread(bool* repaint_needed_out, + bool update_paint_mode_to_desired) { + assert_not_null(surface_); + + // Validate that painting lifecycle is accessible by the UI thread currently, + // not given to the guest output thread. The mode can be modified only by + // the UI thread, so no need to lock the mutex. + assert_true(paint_mode_ != PaintMode::kGuestOutputThreadImmediately); + + // Initialize repaint_needed_out for failure cases. + if (repaint_needed_out) { + *repaint_needed_out = false; + } + + // If the connection state is kUnconnectedSurfaceReportedUnusable, the + // implementation has reported that the surface is not usable by the presenter + // at all, and it's pointless to retry connecting to it. + if (surface_paint_connection_state_ != + SurfacePaintConnectionState::kUnconnectedSurfaceReportedUnusable) { + uint32_t surface_width = 0, surface_height = 0; + bool surface_area_available = surface_->GetSize(surface_width, surface_height); + if (!surface_area_available) { + // The surface is currently zero-area (or has become zero-area), try again + // when it's resized. + DisconnectPaintingFromSurfaceFromUIThread( + SurfacePaintConnectionState::kUnconnectedRetryAtStateChange); + } else { + bool is_reconnect = IsConnectedSurfacePaintConnectionState(surface_paint_connection_state_); + bool is_vsync_implicit = false; + SurfacePaintConnectResult connect_result = ConnectOrReconnectPaintingToSurfaceFromUIThread( + *surface_, surface_width, surface_height, + surface_paint_connection_state_ == SurfacePaintConnectionState::kConnectedPaintable, + is_vsync_implicit); + switch (connect_result) { + case SurfacePaintConnectResult::kSuccess: + if (repaint_needed_out) { + *repaint_needed_out = true; + } + // Fallthrough to common success handling. + case SurfacePaintConnectResult::kSuccessUnchanged: + // Don't know yet what the first result was (success or suboptimal). + surface_paint_connection_was_optimal_at_successful_paint_ = false; + surface_paint_connection_state_ = SurfacePaintConnectionState::kConnectedPaintable; + surface_paint_connection_has_implicit_vsync_ = is_vsync_implicit; + surface_width_in_paint_connection_ = surface_width; + surface_height_in_paint_connection_ = surface_height; + if (!is_reconnect) { + *repaint_needed_out = true; + } + break; + case SurfacePaintConnectResult::kFailure: + surface_paint_connection_state_ = + SurfacePaintConnectionState::kUnconnectedRetryAtStateChange; + break; + case SurfacePaintConnectResult::kFailureSurfaceUnusable: + surface_paint_connection_state_ = + SurfacePaintConnectionState::kUnconnectedSurfaceReportedUnusable; + break; + } + } + } + + if (update_paint_mode_to_desired) { + SetPaintModeFromUIThread(GetDesiredPaintModeFromUIThread( + surface_paint_connection_state_ == SurfacePaintConnectionState::kConnectedPaintable)); + } +} + +bool Presenter::RequestPaintOrConnectionRecoveryViaWindow(bool force_ui_thread_paint_tick) { + // Can be called from any thread if an existing window_ is available in it, + // and it's known to have a Surface that will be the same throughout this + // call - not doing any checks whether this request can be satisfied + // theoretically. For safety, check whether the window exists unconditionally. + assert_not_null(window_); + assert_not_null(surface_); + if (ui_thread_paint_requested_.exchange(true, std::memory_order_relaxed)) { + // Invalidation pending already, no need to do it twice. + return false; + } + if (force_ui_thread_paint_tick) { + ForceUIThreadPaintTick(); + } + window_->RequestPaint(); + return true; +} + +void Presenter::UpdateSurfaceMonitorFromUIThread(bool old_monitor_potentially_disconnected) { + // For dropping the monitor when the window is closing and is losing its + // surface, the existence of `surface_` (which implies that `window_` exists + // too) must be the condition for a non-null monitor, not just the existence + // of `window_`. +#if REX_PLATFORM_WIN32 + HMONITOR surface_new_win32_monitor = nullptr; + if (surface_) { + HWND hwnd = static_cast(window_)->hwnd(); + // The HWND may be non-existent if the window has been closed and destroyed + // (the HWND, not the rex::ui::Window) already. + if (hwnd) { + surface_new_win32_monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL); + } + } + if (old_monitor_potentially_disconnected || surface_win32_monitor_ != surface_new_win32_monitor) { + surface_win32_monitor_ = surface_new_win32_monitor; + if (dxgi_ui_tick_factory_ && !dxgi_ui_tick_factory_->IsCurrent()) { + // If a monitor has been newly connected, it won't appear in the old + // factory, need to recreate it. + { + Microsoft::WRL::ComPtr old_factory_output_to_release; + { + std::scoped_lock dxgi_ui_tick_lock(dxgi_ui_tick_mutex_); + old_factory_output_to_release = std::move(dxgi_ui_tick_output_); + } + } + dxgi_ui_tick_factory_.Reset(); + } + if (!dxgi_ui_tick_factory_) { + if (FAILED(CreateDXGIFactory1(IID_PPV_ARGS(&dxgi_ui_tick_factory_)))) { + REXLOG_ERROR("Presenter: Failed to create a DXGI factory"); + } + } + Microsoft::WRL::ComPtr new_dxgi_output; + if (dxgi_ui_tick_factory_ && surface_new_win32_monitor) { + new_dxgi_output = + GetDXGIOutputForMonitor(dxgi_ui_tick_factory_.Get(), surface_new_win32_monitor); + } + // If the adapter was recreated, and the old output was released before its + // destruction, notifying is still required - the vertical blank wait thread + // might have entered the condition variable wait already as the output was + // null. + bool signal_dxgi_ui_tick_control; + { + std::unique_lock dxgi_ui_tick_lock(dxgi_ui_tick_mutex_); + bool dxgi_output_was_null = (dxgi_ui_tick_output_ == nullptr); + dxgi_ui_tick_output_ = new_dxgi_output; + signal_dxgi_ui_tick_control = + dxgi_output_was_null && AreDXGIUITicksWaitable(dxgi_ui_tick_lock); + } + if (signal_dxgi_ui_tick_control) { + dxgi_ui_tick_control_condition_.notify_all(); + } + } +#endif // XE_PLATFORM +} + +bool Presenter::InSurfaceOnMonitorFromUIThread() const { + if (!surface_) { + return false; + } +#if REX_PLATFORM_WIN32 + return surface_win32_monitor_ != nullptr; +#else + return true; +#endif // XE_PLATFORM +} + +Presenter::PaintResult Presenter::PaintAndPresent(bool execute_ui_drawers) { + assert_false(execute_ui_drawers && !is_in_ui_thread_paint_); + assert_true(surface_paint_connection_state_ == SurfacePaintConnectionState::kConnectedPaintable); + PaintResult result = PaintAndPresentImpl(execute_ui_drawers); + switch (result) { + case PaintResult::kPresented: + surface_paint_connection_was_optimal_at_successful_paint_ = true; + break; + case PaintResult::kPresentedSuboptimal: + // Make outdated if previously optimal, now suboptimal, but don't cause + // the connection to become outdated if it has been suboptimal from the + // very beginning. + if (surface_paint_connection_was_optimal_at_successful_paint_) { + surface_paint_connection_state_ = SurfacePaintConnectionState::kConnectedOutdated; + } + break; + case PaintResult::kNotPresentedConnectionOutdated: + surface_paint_connection_state_ = SurfacePaintConnectionState::kConnectedOutdated; + break; + default: + // Another issue not directly related to the surface connection. + break; + } + return result; +} + +void Presenter::HandleUIDrawersChangeFromUIThread(bool drawers_were_empty) { + if (is_in_ui_thread_paint_) { + // Defer the refresh so no dangerous lifecycle-related changes happen during + // drawing. + if (!ui_drawers_.empty()) { + request_ui_paint_after_current_ui_thread_paint_ = true; + } + return; + } + + if (paint_mode_ == PaintMode::kNone) { + // Not connected, no point in refreshing (checking a more conservative + // paint_mode_ because the actual connection state may currently be owned by + // the guest output thread instead) or in toggling the ownership (the rest + // of the function can assume it's not kNone). + return; + } + + if (ui_drawers_.empty() != drawers_were_empty) { + // Require the UI thread to paint if it needs the UI, or let the guest + // output thread paint immediately if not. + SetPaintModeFromUIThread(GetDesiredPaintModeFromUIThread(true)); + // Make sure the ticks for limiting the UI frame rate are sent. + UpdateUITicksNeededFromUIThread(); + } + + // Request painting so the changes to the UI drawer list are reflected as + // quickly as possible. + // RequestUIPaintFromUIThread is not enough, because a paint request is also + // needed if disabling the UI, to force paint a frame without the UI as soon + // as possible - it can't be dropped if ui_drawers_ is empty. + // The coarse painting availability (and thus the availability of `window_`, + // which is required for the paint mode to be anything else than kNone) has + // already been checked above. + ForceUIThreadPaintTick(); + window_->RequestPaint(); +} + +void Presenter::UpdateUITicksNeededFromUIThread() { +#if REX_PLATFORM_WIN32 + bool new_needed = AreUITicksNeededFromUIThread(); + if (dxgi_ui_ticks_needed_ == new_needed) { + return; + } + bool signal_dxgi_ui_tick_control; + { + std::unique_lock dxgi_ui_tick_lock(dxgi_ui_tick_mutex_); + dxgi_ui_ticks_needed_ = new_needed; + signal_dxgi_ui_tick_control = AreDXGIUITicksWaitable(dxgi_ui_tick_lock); + } + if (signal_dxgi_ui_tick_control) { + dxgi_ui_tick_control_condition_.notify_all(); + } +#endif +} + +void Presenter::WaitForUITickFromUIThread() { +#if REX_PLATFORM_WIN32 + if (!AreUITicksNeededFromUIThread()) { + return; + } + std::unique_lock dxgi_ui_tick_lock(dxgi_ui_tick_mutex_); + uint64_t last_vblank_before_wait = dxgi_ui_tick_last_vblank_; + while (true) { + // Guest output present requests should interrupt the wait as quickly as + // possible as they should be fulfilled as early as possible. + if (dxgi_ui_tick_force_requested_) { + dxgi_ui_tick_force_requested_ = false; + return; + } + if (!AreDXGIUITicksWaitable(dxgi_ui_tick_lock)) { + return; + } + if (dxgi_ui_tick_last_vblank_ > dxgi_ui_tick_last_draw_) { + // If there have been multiple vblanks during the wait for some reason, + // next time draw the UI immediately. + dxgi_ui_tick_last_draw_ = + std::min(last_vblank_before_wait + uint64_t(1), dxgi_ui_tick_last_vblank_); + return; + } + dxgi_ui_tick_signal_condition_.wait(dxgi_ui_tick_lock); + } +#endif // XE_PLATFORM +} + +void Presenter::ForceUIThreadPaintTick() { +#if REX_PLATFORM_WIN32 + std::scoped_lock dxgi_ui_tick_lock(dxgi_ui_tick_mutex_); + dxgi_ui_tick_force_requested_ = true; +#endif // XE_PLATFORM +} + +#if REX_PLATFORM_WIN32 +Microsoft::WRL::ComPtr Presenter::GetDXGIOutputForMonitor(IDXGIFactory1* factory, + HMONITOR monitor) { + Microsoft::WRL::ComPtr adapter; + for (UINT adapter_index = 0; + SUCCEEDED(factory->EnumAdapters(adapter_index, adapter.ReleaseAndGetAddressOf())); + ++adapter_index) { + Microsoft::WRL::ComPtr output; + for (UINT output_index = 0; SUCCEEDED(adapter->EnumOutputs(output_index, &output)); + ++output_index) { + DXGI_OUTPUT_DESC output_desc; + if (SUCCEEDED(output->GetDesc(&output_desc)) && output_desc.Monitor == monitor) { + return std::move(output); + } + } + } + return nullptr; +} + +void Presenter::DXGIUITickThread() { + std::unique_lock dxgi_ui_tick_lock(dxgi_ui_tick_mutex_); + while (true) { + if (dxgi_ui_tick_thread_shutdown_) { + return; + } + if (!AreDXGIUITicksWaitable(dxgi_ui_tick_lock)) { + dxgi_ui_tick_control_condition_.wait(dxgi_ui_tick_lock); + continue; + } + // Wait for vertical blank, with the mutex unlocked (holding a new reference + // to the current output while it's happening) so subscribers can still do + // early-out checks. + bool wait_succeeded; + { + Microsoft::WRL::ComPtr dxgi_output = dxgi_ui_tick_output_; + dxgi_ui_tick_lock.unlock(); + wait_succeeded = SUCCEEDED(dxgi_ui_tick_output_->WaitForVBlank()); + } + dxgi_ui_tick_lock.lock(); + if (wait_succeeded) { + ++dxgi_ui_tick_last_vblank_; + } else { + // Lost the ability to wait for a vertical blank on this output, notify + // the waiting threads, and wait for a new one. + dxgi_ui_tick_output_.Reset(); + } + dxgi_ui_tick_signal_condition_.notify_all(); + } +} +#endif // XE_PLATFORM + +} // namespace ui +} // namespace rex diff --git a/src/ui/renderdoc_api.cpp b/src/ui/renderdoc_api.cpp new file mode 100644 index 0000000..ce81e1b --- /dev/null +++ b/src/ui/renderdoc_api.cpp @@ -0,0 +1,48 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +namespace rex { +namespace ui { + +std::unique_ptr RenderDocAPI::CreateIfConnected() { + std::unique_ptr renderdoc_api(new RenderDocAPI()); + + pRENDERDOC_GetAPI get_api = nullptr; + + // Try to load the RenderDoc library. If RenderDoc is attached, the library + // should already be loaded into the process and this will increment the + // reference count. If not attached, the load will fail and we return nullptr. + if (!renderdoc_api->library_.Load(platform::lib_names::kRenderDoc)) { + return nullptr; + } + get_api = renderdoc_api->library_.GetSymbol("RENDERDOC_GetAPI"); + + // get_api will be null if RenderDoc is not connected, or the API isn't + // available on this platform, or there was an error. + if (!get_api || !get_api(eRENDERDOC_API_Version_1_0_0, (void**)&renderdoc_api->api_1_0_0_) || + !renderdoc_api->api_1_0_0_) { + return nullptr; + } + + REXLOG_INFO("RenderDoc API initialized"); + + return renderdoc_api; +} + +RenderDocAPI::~RenderDocAPI() { + library_.Close(); +} + +} // namespace ui +} // namespace rex diff --git a/src/ui/rex_app.cpp b/src/ui/rex_app.cpp new file mode 100644 index 0000000..8abe75e --- /dev/null +++ b/src/ui/rex_app.cpp @@ -0,0 +1,454 @@ +/** + * @file ui/rex_app.cpp + * @brief ReXApp implementation — compiled as part of the consumer executable + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if REX_HAS_VULKAN +#include +#endif +#if REX_HAS_D3D12 +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +namespace rex { + +// --- ReXApp --- + +ReXApp::~ReXApp() = default; + +ReXApp::ReXApp(ui::WindowedAppContext& ctx, std::string_view name, PPCImageInfo ppc_info, + std::string_view usage) + : WindowedApp(ctx, name, usage), ppc_info_(ppc_info) {} + +bool ReXApp::OnInitialize() { + if (!SetupEnvironment()) + return false; + if (!SetupPresentation()) + return false; + + auto paths = OnFinalizePaths(resolved_defaults_, MakeResumeCallback()); + if (!paths) { + // Async: consumer will invoke resume when ready. OnInitialize returns + // true so the event loop keeps pumping (wizard dialogs render). + return true; + } + + if (!ConstructRuntime(*paths)) + return false; + LaunchModule(); + return true; +} + +bool ReXApp::SetupEnvironment() { + auto exe_dir = rex::filesystem::GetExecutableFolder(); + + std::filesystem::path game_dir; + std::string game_data_cvar = REXCVAR_GET(game_data_root); + if (!game_data_cvar.empty()) { + game_dir = game_data_cvar; + } + + // User data: cvar override, or platform user directory + std::filesystem::path user_dir; + std::string user_data_cvar = REXCVAR_GET(user_data_root); + if (!user_data_cvar.empty()) { + user_dir = user_data_cvar; + } else { + user_dir = rex::filesystem::GetUserFolder() / GetName(); + } + + // Update data: cvar override, or empty (opt-in) + std::filesystem::path update_dir; + std::string update_data_cvar = REXCVAR_GET(update_data_root); + if (!update_data_cvar.empty()) { + update_dir = update_data_cvar; + } + + // Cache: cvar override, or user_dir/cache + std::filesystem::path cache_dir; + std::string cache_path_cvar = REXCVAR_GET(cache_path); + if (!cache_path_cvar.empty()) { + cache_dir = cache_path_cvar; + } else { + cache_dir = user_dir / "cache"; + } + + PathConfig path_config{game_dir, user_dir, update_dir, cache_dir, + exe_dir / (std::string(GetName()) + ".toml")}; + OnConfigurePaths(path_config); + game_data_root_ = path_config.game_data_root; + user_data_root_ = path_config.user_data_root; + update_data_root_ = path_config.update_data_root; + cache_root_ = path_config.cache_root; + config_path_ = path_config.config_path; + resolved_defaults_ = std::move(path_config); + + // Load config FIRST so log cvars have final values + if (std::filesystem::exists(config_path_)) + rex::cvar::LoadConfig(config_path_); + + // Late-phase logging + std::string log_file_cvar = REXCVAR_GET(log_file); + std::string log_level_str = REXCVAR_GET(log_level); + if (REXCVAR_GET(log_verbose) && log_level_str == "info") + log_level_str = "trace"; + + auto category_levels = rex::ParseCategoryLevelsFromConfig(config_path_); + auto log_config = rex::BuildLogConfig(log_file_cvar.empty() ? nullptr : log_file_cvar.c_str(), + log_level_str, category_levels); + if (log_file_cvar.empty()) { + log_config.app_name = std::string(GetName()); + log_config.log_dir = (exe_dir / "logs").string(); + } + + rex::InitLogging(log_config); + rex::RegisterLogLevelCallback(); + + log_sink_ = std::make_shared(); + rex::AddSink(log_sink_); + + OnPostInitLogging(); + + if (std::filesystem::exists(config_path_)) + REXLOG_INFO("Loaded config: {}", config_path_.filename().string()); + + REXLOG_INFO("{} starting", GetName()); + if (!game_data_root_.empty()) { + REXLOG_INFO(" Game directory: {}", game_data_root_.string()); + } + if (!user_data_root_.empty()) { + REXLOG_INFO(" User data: {}", user_data_root_.string()); + } + if (!update_data_root_.empty()) { + REXLOG_INFO(" Update data: {}", update_data_root_.string()); + } + REXLOG_INFO(" Cache root: {}", cache_root_.string()); + + return true; +} + +bool ReXApp::ConstructRuntime(const PathConfig& paths) { + if (paths.game_data_root.empty()) { + auto msg = std::string("--game_data_root was not provided."); + REXLOG_ERROR("{}", msg); + rex::ShowSimpleMessageBox(rex::SimpleMessageBoxType::Error, msg); + return false; + } + if (!std::filesystem::is_directory(paths.game_data_root)) { + auto msg = fmt::format("--game_data_root does not exist: {}", paths.game_data_root.string()); + REXLOG_ERROR("{}", msg); + rex::ShowSimpleMessageBox(rex::SimpleMessageBoxType::Error, msg); + return false; + } + + runtime_ = std::make_unique(paths.game_data_root, paths.user_data_root, + paths.update_data_root, paths.cache_root); + runtime_->set_app_context(&app_context()); + + // Window and ImGui drawer already exist from SetupPresentation; publish them + // to the runtime before Setup so hooks and native rendering see them. + if (window_) { + runtime_->set_display_window(window_.get()); + } + if (imgui_drawer_) { + runtime_->set_imgui_drawer(imgui_drawer_.get()); + } + + auto status = runtime_->Setup(ppc_info_, std::move(config_)); + if (XFAILED(status)) { + REXLOG_ERROR("Runtime setup failed: {:08X}", status); + return false; + } + + if (window_ && runtime_->input_system()) { + static_cast(runtime_->input_system())->AttachWindow(window_.get()); + } + + if (ppc_info_.register_modules) { + ppc_info_.register_modules(runtime_->kernel_state()); + } + + if (imgui_drawer_) { + auto* input_sys = static_cast(runtime_->input_system()); + if (input_sys) { + input_sys->SetActiveCallback([this]() { + if (!debug_overlay_ && !console_overlay_ && !settings_overlay_) + return true; + return !imgui_drawer_->GetIO().WantCaptureMouse; + }); + } + } + + std::string xex_image = "game:\\default.xex"; + OnLoadXexImage(xex_image); + + // Mirrors the game:\ / d:\ -> game_data_root mapping in Runtime::SetupVfs. + { + constexpr std::string_view kGameDevice = "game:\\"; + constexpr std::string_view kDDevice = "d:\\"; + std::string_view tail = xex_image; + if (tail.starts_with(kGameDevice)) { + tail.remove_prefix(kGameDevice.size()); + } else if (tail.starts_with(kDDevice)) { + tail.remove_prefix(kDDevice.size()); + } + std::string host_tail{tail}; + std::replace(host_tail.begin(), host_tail.end(), '\\', '/'); + auto xex_host = paths.game_data_root / host_tail; + if (!std::filesystem::is_regular_file(xex_host)) { + auto msg = fmt::format("Entrypoint XEX not found: {}", xex_host.string()); + REXLOG_ERROR("{}", msg); + rex::ShowSimpleMessageBox(rex::SimpleMessageBoxType::Error, msg); + return false; + } + } + + status = runtime_->LoadXexImage(xex_image); + if (XFAILED(status)) { + auto msg = fmt::format("Failed to load XEX ({}): {:08X}", xex_image, status); + REXLOG_ERROR("{}", msg); + rex::ShowSimpleMessageBox(rex::SimpleMessageBoxType::Error, msg); + return false; + } + + OnPostLoadXexImage(); + + if (ppc_info_.rexcrt_heap) { + if (!rex::kernel::crt::InitHeap(REXCVAR_GET(rexcrt_heap_size_mb), runtime_->memory())) { + REXLOG_ERROR("Failed to initialize rexcrt heap"); + return false; + } + } + + OnPostSetup(); + + return true; +} + +bool ReXApp::SetupPresentation() { +#if REX_HAS_D3D12 + config_.graphics = REX_GRAPHICS_BACKEND(rex::graphics::d3d12::D3D12GraphicsSystem); +#elif REX_HAS_VULKAN + config_.graphics = REX_GRAPHICS_BACKEND(rex::graphics::vulkan::VulkanGraphicsSystem); +#endif + config_.audio_factory = REX_AUDIO_BACKEND(rex::audio::sdl::SDLAudioSystem); + config_.input_factory = REX_INPUT_BACKEND(rex::input::CreateDefaultInputSystem); + config_.kernel_init = rex::kernel::InitializeKernel; + + OnPreSetup(config_); + + if (config_.graphics) { + X_STATUS status = config_.graphics->SetupPresentation(&app_context()); + if (XFAILED(status)) { + REXLOG_ERROR("Graphics presentation setup failed: {:08X}", status); + return false; + } + } + + // Create window + window_ = rex::ui::Window::Create(app_context(), GetName(), 1280, 720); + if (!window_) { + REXLOG_ERROR("Failed to create window"); + return false; + } + + // Set window title with SDK build stamp + std::string title = std::string(GetName()) + " " + REXGLUE_BUILD_TITLE; + window_->SetTitle(title); + + window_->AddListener(this); + window_->AddInputListener(this, 0); + + if (REXCVAR_GET(fullscreen)) { + window_->SetFullscreen(true); + } + window_->Open(); + + auto* graphics_system = static_cast(config_.graphics.get()); + if (graphics_system && graphics_system->presenter()) { + auto* presenter = graphics_system->presenter(); + auto* provider = graphics_system->provider(); + if (provider) { + immediate_drawer_ = provider->CreateImmediateDrawer(); + if (immediate_drawer_) { + immediate_drawer_->SetPresenter(presenter); + imgui_drawer_ = std::make_unique( + window_.get(), 64, [this](ImFontAtlas* atlas) { OnConfigureFonts(atlas); }); + imgui_drawer_->SetPresenterAndImmediateDrawer(presenter, immediate_drawer_.get()); + rex::ui::RegisterBind("bind_debug_overlay", "F3", "Toggle debug overlay", [this] { + if (debug_overlay_) { + debug_overlay_.reset(); + } else { + debug_overlay_ = std::make_unique(imgui_drawer_.get(), + frame_stats_provider_); + } + }); + rex::ui::RegisterBind("bind_console", "Backtick", "Toggle console overlay", [this] { + if (console_overlay_) { + console_overlay_.reset(); + } else { + console_overlay_ = std::make_unique(imgui_drawer_.get(), log_sink_); + } + }); + rex::ui::RegisterBind("bind_settings", "F4", "Toggle settings overlay", [this] { + if (settings_overlay_) { + settings_overlay_.reset(); + } else { + settings_overlay_ = + std::make_unique(imgui_drawer_.get(), config_path_); + } + }); + + OnCreateDialogs(imgui_drawer_.get()); + } + } + window_->SetPresenter(presenter); + } + + return true; +} + +void ReXApp::LaunchModule() { + app_context().CallInUIThreadDeferred([this]() { + OnPreLaunchModule(); + + auto main_thread = runtime_->PrepareModuleLaunch(); + if (!main_thread) { + REXLOG_ERROR("Failed to launch module"); + app_context().QuitFromUIThread(); + return; + } + + auto* graphics_system = + static_cast(runtime_->graphics_system()); + if (graphics_system && !runtime_->cache_root().empty()) { + uint32_t title_id = runtime_->kernel_state()->title_id(); + if (title_id != 0) { + REXLOG_INFO("Initializing shader storage for title {:08X}...", title_id); + graphics_system->InitializeShaderStorage(runtime_->cache_root(), title_id, true); + } + } + + OnPostLaunchModule(main_thread.get()); + main_thread->Resume(); + + module_thread_ = std::thread([this, main_thread = std::move(main_thread)]() mutable { + main_thread->Wait(0, 0, 0, nullptr); + OnGuestThreadExit(main_thread.get()); + REXLOG_INFO("Execution complete"); + if (!shutting_down_.load(std::memory_order_acquire)) { + app_context().CallInUIThread([this]() { app_context().QuitFromUIThread(); }); + } + }); + }); +} + +std::function ReXApp::MakeResumeCallback() { + return [this](PathConfig paths) { + if (shutting_down_.load(std::memory_order_acquire)) + return; + if (!ConstructRuntime(std::move(paths))) { + app_context().QuitFromUIThread(); + return; + } + LaunchModule(); + }; +} + +void ReXApp::OnKeyDown(ui::KeyEvent& e) { + rex::ui::ProcessKeyEvent(e); +} + +void ReXApp::OnClosing(ui::UIEvent& e) { + (void)e; + REXLOG_INFO("Window closing, shutting down..."); + shutting_down_.store(true, std::memory_order_release); + if (runtime_ && runtime_->kernel_state()) { + runtime_->kernel_state()->TerminateTitle(); + } + app_context().QuitFromUIThread(); +} + +void ReXApp::OnDestroy() { + // Notify subclass before cleanup + OnShutdown(); + + // Unregister overlay keybinds before destroying dialogs + rex::ui::UnregisterBind("bind_debug_overlay"); + rex::ui::UnregisterBind("bind_console"); + rex::ui::UnregisterBind("bind_settings"); + + // ImGui cleanup (reverse of setup) + settings_overlay_.reset(); + console_overlay_.reset(); + debug_overlay_.reset(); + if (imgui_drawer_) { + imgui_drawer_->SetPresenterAndImmediateDrawer(nullptr, nullptr); + imgui_drawer_.reset(); + } + if (immediate_drawer_) { + immediate_drawer_->SetPresenter(nullptr); + immediate_drawer_.reset(); + } + if (runtime_) { + runtime_->set_display_window(nullptr); + runtime_->set_imgui_drawer(nullptr); + } + // Window/runtime cleanup + if (window_) { + window_->SetPresenter(nullptr); + } + if (module_thread_.joinable()) { + module_thread_.join(); + } + if (window_) { + window_->RemoveInputListener(this); + window_->RemoveListener(this); + } + window_.reset(); + runtime_.reset(); +} + +void ReXApp::SetGuestFrameStats(ui::DebugOverlayDialog::FrameStatsProvider provider) { + frame_stats_provider_ = provider; + if (debug_overlay_) { + debug_overlay_->SetStatsProvider(provider); + } +} + +} // namespace rex diff --git a/src/ui/shaders/bytecode/d3d12_5_1/guest_output_bilinear_dither_ps.h b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_bilinear_dither_ps.h new file mode 100644 index 0000000..d6b03c5 --- /dev/null +++ b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_bilinear_dither_ps.h @@ -0,0 +1,604 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// int2 xe_bilinear_output_offset; // Offset: 0 Size: 8 +// float2 xe_bilinear_output_size_inv;// Offset: 8 Size: 8 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_bilinear_sampler sampler NA NA S0 s0 1 +// xe_bilinear_source texture float4 2d T0 t0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// +ps_5_1 +dcl_globalFlags refactoringAllowed +dcl_immediateConstantBuffer { { -0.001003, 0, 0, 0}, + { 0.000881, 0, 0, 0}, + { 0.001693, 0, 0, 0}, + { -0.001555, 0, 0, 0}, + { 0.001279, 0, 0, 0}, + { -0.000605, 0, 0, 0}, + { 0.001065, 0, 0, 0}, + { -0.001386, 0, 0, 0}, + { 0.001356, 0, 0, 0}, + { 0.000513, 0, 0, 0}, + { 0.001218, 0, 0, 0}, + { -0.001601, 0, 0, 0}, + { 0.000590, 0, 0, 0}, + { -0.000283, 0, 0, 0}, + { 0.001111, 0, 0, 0}, + { -0.001417, 0, 0, 0}, + { 0.001448, 0, 0, 0}, + { -0.000544, 0, 0, 0}, + { 0.000130, 0, 0, 0}, + { -0.001203, 0, 0, 0}, + { 0.000437, 0, 0, 0}, + { -0.001049, 0, 0, 0}, + { 0.000620, 0, 0, 0}, + { -0.000483, 0, 0, 0}, + { 0.001877, 0, 0, 0}, + { -0.001095, 0, 0, 0}, + { -0.000100, 0, 0, 0}, + { -0.000528, 0, 0, 0}, + { 0.001432, 0, 0, 0}, + { -0.001938, 0, 0, 0}, + { -0.000697, 0, 0, 0}, + { 0.000038, 0, 0, 0}, + { 0.000712, 0, 0, 0}, + { -0.001310, 0, 0, 0}, + { 0.001095, 0, 0, 0}, + { -0.000299, 0, 0, 0}, + { 0.001754, 0, 0, 0}, + { -0.001677, 0, 0, 0}, + { 0.001478, 0, 0, 0}, + { -0.000038, 0, 0, 0}, + { 0.000789, 0, 0, 0}, + { -0.001831, 0, 0, 0}, + { 0.000299, 0, 0, 0}, + { 0.000988, 0, 0, 0}, + { -0.001172, 0, 0, 0}, + { 0.000176, 0, 0, 0}, + { 0.001647, 0, 0, 0}, + { -0.001585, 0, 0, 0}, + { 0.000345, 0, 0, 0}, + { 0.001861, 0, 0, 0}, + { -0.001769, 0, 0, 0}, + { -0.000866, 0, 0, 0}, + { 0.000896, 0, 0, 0}, + { 0.000161, 0, 0, 0}, + { -0.000927, 0, 0, 0}, + { -0.001524, 0, 0, 0}, + { -0.000651, 0, 0, 0}, + { 0.001294, 0, 0, 0}, + { -0.000804, 0, 0, 0}, + { -0.001463, 0, 0, 0}, + { 0.001800, 0, 0, 0}, + { -0.000850, 0, 0, 0}, + { 0.000850, 0, 0, 0}, + { -0.000452, 0, 0, 0}, + { -0.001065, 0, 0, 0}, + { -0.000146, 0, 0, 0}, + { 0.000237, 0, 0, 0}, + { 0.001417, 0, 0, 0}, + { -0.000590, 0, 0, 0}, + { -0.000191, 0, 0, 0}, + { 0.001601, 0, 0, 0}, + { 0.001019, 0, 0, 0}, + { 0.000406, 0, 0, 0}, + { -0.000207, 0, 0, 0}, + { 0.001585, 0, 0, 0}, + { 0.000651, 0, 0, 0}, + { -0.000069, 0, 0, 0}, + { 0.000421, 0, 0, 0}, + { -0.001647, 0, 0, 0}, + { 0.001371, 0, 0, 0}, + { 0.000927, 0, 0, 0}, + { -0.000666, 0, 0, 0}, + { 0.001187, 0, 0, 0}, + { -0.001448, 0, 0, 0}, + { 0.000574, 0, 0, 0}, + { -0.001892, 0, 0, 0}, + { 0.000758, 0, 0, 0}, + { -0.001294, 0, 0, 0}, + { 0.001922, 0, 0, 0}, + { -0.001662, 0, 0, 0}, + { -0.001034, 0, 0, 0}, + { -0.000498, 0, 0, 0}, + { -0.001861, 0, 0, 0}, + { 0.001203, 0, 0, 0}, + { -0.000329, 0, 0, 0}, + { -0.001371, 0, 0, 0}, + { 0.001631, 0, 0, 0}, + { -0.001846, 0, 0, 0}, + { 0.000728, 0, 0, 0}, + { -0.000911, 0, 0, 0}, + { 0.001815, 0, 0, 0}, + { -0.001141, 0, 0, 0}, + { -0.000375, 0, 0, 0}, + { 0.000100, 0, 0, 0}, + { -0.000743, 0, 0, 0}, + { 0.001172, 0, 0, 0}, + { 0.000069, 0, 0, 0}, + { 0.001494, 0, 0, 0}, + { 0.000973, 0, 0, 0}, + { -0.000957, 0, 0, 0}, + { 0.001938, 0, 0, 0}, + { 0.000528, 0, 0, 0}, + { 0.000054, 0, 0, 0}, + { -0.001248, 0, 0, 0}, + { -0.000268, 0, 0, 0}, + { 0.001540, 0, 0, 0}, + { -0.000008, 0, 0, 0}, + { 0.000314, 0, 0, 0}, + { 0.001340, 0, 0, 0}, + { -0.001754, 0, 0, 0}, + { 0.000498, 0, 0, 0}, + { -0.001187, 0, 0, 0}, + { 0.000774, 0, 0, 0}, + { -0.001340, 0, 0, 0}, + { 0.000268, 0, 0, 0}, + { -0.001478, 0, 0, 0}, + { -0.000130, 0, 0, 0}, + { -0.000774, 0, 0, 0}, + { 0.001310, 0, 0, 0}, + { 0.000391, 0, 0, 0}, + { 0.000957, 0, 0, 0}, + { -0.000467, 0, 0, 0}, + { -0.001540, 0, 0, 0}, + { 0.001034, 0, 0, 0}, + { -0.000682, 0, 0, 0}, + { 0.001677, 0, 0, 0}, + { 0.001003, 0, 0, 0}, + { -0.000421, 0, 0, 0}, + { 0.001785, 0, 0, 0}, + { -0.000237, 0, 0, 0}, + { -0.000620, 0, 0, 0}, + { 0.001662, 0, 0, 0}, + { 0.000835, 0, 0, 0}, + { -0.001723, 0, 0, 0}, + { -0.001080, 0, 0, 0}, + { 0.001769, 0, 0, 0}, + { -0.000789, 0, 0, 0}, + { -0.001785, 0, 0, 0}, + { 0.000682, 0, 0, 0}, + { -0.000988, 0, 0, 0}, + { -0.001325, 0, 0, 0}, + { -0.000176, 0, 0, 0}, + { -0.001509, 0, 0, 0}, + { 0.000329, 0, 0, 0}, + { -0.001953, 0, 0, 0}, + { 0.000666, 0, 0, 0}, + { -0.001616, 0, 0, 0}, + { 0.001157, 0, 0, 0}, + { 0.000452, 0, 0, 0}, + { -0.000437, 0, 0, 0}, + { 0.000191, 0, 0, 0}, + { -0.001494, 0, 0, 0}, + { 0.001141, 0, 0, 0}, + { 0.000084, 0, 0, 0}, + { 0.001892, 0, 0, 0}, + { 0.001402, 0, 0, 0}, + { 0.000559, 0, 0, 0}, + { 0.000115, 0, 0, 0}, + { 0.001264, 0, 0, 0}, + { -0.000574, 0, 0, 0}, + { -0.000973, 0, 0, 0}, + { 0.001325, 0, 0, 0}, + { 0.000222, 0, 0, 0}, + { -0.000758, 0, 0, 0}, + { -0.001356, 0, 0, 0}, + { 0.001463, 0, 0, 0}, + { 0.000866, 0, 0, 0}, + { -0.000360, 0, 0, 0}, + { 0.000544, 0, 0, 0}, + { -0.001126, 0, 0, 0}, + { -0.000253, 0, 0, 0}, + { -0.000559, 0, 0, 0}, + { -0.001815, 0, 0, 0}, + { 0.001723, 0, 0, 0}, + { -0.001157, 0, 0, 0}, + { 0.000743, 0, 0, 0}, + { 0.001570, 0, 0, 0}, + { -0.000115, 0, 0, 0}, + { -0.001218, 0, 0, 0}, + { 0.001831, 0, 0, 0}, + { 0.000023, 0, 0, 0}, + { -0.001922, 0, 0, 0}, + { 0.001739, 0, 0, 0}, + { -0.000712, 0, 0, 0}, + { 0.001555, 0, 0, 0}, + { -0.001708, 0, 0, 0}, + { 0.001233, 0, 0, 0}, + { 0.000207, 0, 0, 0}, + { 0.001049, 0, 0, 0}, + { -0.000728, 0, 0, 0}, + { -0.001631, 0, 0, 0}, + { -0.000314, 0, 0, 0}, + { 0.000483, 0, 0, 0}, + { -0.001800, 0, 0, 0}, + { 0.000942, 0, 0, 0}, + { -0.000345, 0, 0, 0}, + { 0.000697, 0, 0, 0}, + { -0.001019, 0, 0, 0}, + { -0.001570, 0, 0, 0}, + { -0.000023, 0, 0, 0}, + { -0.001279, 0, 0, 0}, + { 0.000804, 0, 0, 0}, + { -0.000896, 0, 0, 0}, + { -0.001432, 0, 0, 0}, + { 0.000605, 0, 0, 0}, + { -0.000084, 0, 0, 0}, + { 0.000911, 0, 0, 0}, + { 0.001953, 0, 0, 0}, + { -0.001402, 0, 0, 0}, + { -0.000636, 0, 0, 0}, + { 0.001509, 0, 0, 0}, + { -0.000820, 0, 0, 0}, + { 0.001248, 0, 0, 0}, + { 0.000253, 0, 0, 0}, + { 0.001524, 0, 0, 0}, + { 0.001126, 0, 0, 0}, + { 0.000360, 0, 0, 0}, + { -0.000391, 0, 0, 0}, + { 0.001907, 0, 0, 0}, + { 0.001386, 0, 0, 0}, + { -0.001111, 0, 0, 0}, + { 0.001616, 0, 0, 0}, + { -0.000881, 0, 0, 0}, + { 0.000146, 0, 0, 0}, + { 0.001080, 0, 0, 0}, + { -0.000054, 0, 0, 0}, + { 0.000283, 0, 0, 0}, + { -0.001693, 0, 0, 0}, + { -0.001264, 0, 0, 0}, + { -0.000513, 0, 0, 0}, + { -0.000161, 0, 0, 0}, + { -0.001877, 0, 0, 0}, + { -0.000835, 0, 0, 0}, + { 0.000636, 0, 0, 0}, + { 0.000008, 0, 0, 0}, + { -0.001907, 0, 0, 0}, + { -0.000222, 0, 0, 0}, + { 0.000375, 0, 0, 0}, + { -0.001739, 0, 0, 0}, + { -0.000406, 0, 0, 0}, + { -0.001233, 0, 0, 0}, + { 0.001708, 0, 0, 0}, + { -0.000942, 0, 0, 0}, + { 0.000820, 0, 0, 0}, + { 0.001846, 0, 0, 0}, + { 0.000467, 0, 0, 0} } +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_sampler S0[0:0], mode_default, space=0 +dcl_resource_texture2d (float,float,float,float) T0[0:0], space=0 +dcl_input_ps_siv linear noperspective v0.xy, position +dcl_output o0.xyzw +dcl_temps 2 +ftoi r0.xy, v0.xyxx +iadd r0.xy, r0.xyxx, -CB0[0][0].xyxx +utof r0.zw, r0.xxxy +add r0.zw, r0.zzzw, l(0.000000, 0.000000, 0.500000, 0.500000) +mul r0.zw, r0.zzzw, CB0[0][0].zzzw +sample_l r1.xyz, r0.zwzz, T0[0].xyzw, S0[0], l(0.000000) +bfi r0.y, l(4), l(4), r0.y, l(0) +bfi r0.x, l(4), l(0), r0.x, r0.y +add_sat o0.xyz, r1.xyzx, icb[r0.x + 0].xxxx +mov o0.w, l(1.000000) +ret +// Approximately 11 instruction slots used +#endif + +const BYTE guest_output_bilinear_dither_ps[] = { + 68, 88, 66, 67, 156, 138, 216, 142, 148, 62, 121, 93, 254, 24, 231, 193, 50, 177, 115, + 65, 1, 0, 0, 0, 56, 21, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 2, + 0, 0, 120, 2, 0, 0, 172, 2, 0, 0, 156, 20, 0, 0, 82, 68, 69, 70, 8, + 2, 0, 0, 1, 0, 0, 0, 236, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 255, 255, 0, 5, 0, 0, 224, 1, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, + 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 219, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 98, 105, 108, 105, + 110, 101, 97, 114, 95, 115, 97, 109, 112, 108, 101, 114, 0, 120, 101, 95, 98, 105, 108, + 105, 110, 101, 97, 114, 95, 115, 111, 117, 114, 99, 101, 0, 112, 117, 115, 104, 95, 99, + 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 171, 219, 0, 0, 0, 2, 0, 0, 0, + 4, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 1, 0, + 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 116, 1, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 152, + 1, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 188, 1, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 120, 101, 95, 98, 105, 108, 105, 110, 101, 97, 114, 95, 111, 117, 116, 112, 117, 116, + 95, 111, 102, 102, 115, 101, 116, 0, 105, 110, 116, 50, 0, 171, 1, 0, 2, 0, 1, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 110, 1, 0, 0, 120, 101, 95, 98, 105, 108, 105, + 110, 101, 97, 114, 95, 111, 117, 116, 112, 117, 116, 95, 115, 105, 122, 101, 95, 105, 110, + 118, 0, 102, 108, 111, 97, 116, 50, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 180, 1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, 0, 1, + 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 15, 3, 0, 0, 83, 86, 95, 80, 111, 115, 105, + 116, 105, 111, 110, 0, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, + 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, + 83, 72, 69, 88, 232, 17, 0, 0, 81, 0, 0, 0, 122, 4, 0, 0, 106, 8, 0, + 1, 53, 24, 0, 0, 2, 4, 0, 0, 132, 131, 131, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 231, 230, 102, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 222, 221, 221, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 204, 203, 203, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 167, 167, + 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 159, 158, 30, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 139, 139, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 182, 181, 181, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 178, 177, 177, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 135, 134, 6, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 159, + 159, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 209, 209, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, 154, 26, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 149, 148, 148, 185, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 146, 145, 145, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 186, 185, 185, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 190, + 189, 189, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 142, 14, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137, 136, 8, 57, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 158, 157, 157, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 228, 228, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 138, 137, 137, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 163, 162, 34, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 252, 252, + 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 245, 245, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 143, 143, 186, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 209, 208, 208, 184, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 139, 138, 10, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 188, 187, 187, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 253, + 253, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 182, 54, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 161, 160, 32, 56, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 187, 186, 58, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 172, 171, 171, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 144, 143, 143, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157, + 156, 156, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 229, 229, 58, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 219, 219, 186, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 193, 193, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 161, 160, 32, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 207, 206, 78, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 240, 239, 239, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157, 156, 156, + 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, 129, 129, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 153, 153, 186, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 185, 184, 56, 57, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 215, 215, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 208, 207, 207, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181, 180, + 180, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 243, 243, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 231, 231, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 227, 226, 98, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 235, 234, 106, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 169, 168, 40, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, + 242, 114, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 199, 199, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 170, 42, 186, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 169, 169, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 211, 210, 82, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 192, 191, 191, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 236, 235, 235, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 222, 94, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 222, 94, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 236, 236, 185, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 140, 139, 139, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 153, 152, 24, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 249, 248, 120, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 185, + 185, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, 154, 26, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 200, 72, 185, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 210, 209, 209, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 134, 133, 133, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 213, 212, 212, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217, + 216, 88, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 208, 207, 207, 58, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 170, 42, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 144, 144, 184, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 221, 220, 220, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 216, 215, 215, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 180, 179, 179, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, 242, 114, + 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175, 174, 46, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 155, 155, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 190, 189, 189, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 151, 150, 22, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 248, 247, 247, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 199, 198, + 70, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 169, 169, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 251, 251, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 218, 217, 217, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 136, 135, 135, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 131, 130, 2, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, + 243, 243, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 158, 157, 157, 58, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, 172, 172, 185, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 179, 179, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 214, 213, 213, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 242, 241, 241, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 191, 190, 62, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, 238, 110, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, 237, 237, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 149, 149, 186, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 197, 196, 196, 185, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 209, 208, 208, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 195, 194, 66, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 153, + 153, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 144, 144, 56, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 195, 195, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 255, 254, 126, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 251, 250, 122, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 254, 253, 253, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, + 138, 10, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225, 224, 96, 56, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 163, 163, 186, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, 140, 140, 185, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 202, 201, 201, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 129, 128, 0, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 165, 164, 164, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176, 175, 175, + 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 229, 229, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 130, 2, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 156, 155, 155, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 203, 202, 74, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 176, 175, 175, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, 140, + 140, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 193, 193, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137, 136, 8, 185, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 202, 74, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 172, 171, 171, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 205, 204, 204, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 251, + 250, 122, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 244, 244, 185, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 201, 201, 186, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 135, 135, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 179, 178, 50, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 220, 219, 219, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 132, 131, 131, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 220, 220, + 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 233, 233, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 248, 120, 185, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 163, 162, 34, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 218, 217, 217, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 219, 218, 90, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, 225, + 225, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 141, 141, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 231, 231, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 207, 206, 78, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 234, 233, 233, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 179, 178, 50, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, + 129, 129, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 173, 173, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 185, 184, 56, 185, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 197, 197, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 173, 172, 172, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 175, 174, 46, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, 211, 211, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 152, 151, 151, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 236, 236, 57, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 229, 228, 228, 185, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 201, 200, 72, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 196, 195, 195, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 149, + 149, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 176, 176, 56, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 247, 247, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 184, 183, 183, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 147, 146, 18, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 241, 240, 240, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, + 165, 165, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151, 150, 22, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 254, 126, 186, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 173, 173, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 233, 232, 104, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 199, 198, 70, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 178, 177, 177, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 191, 191, + 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 227, 226, 98, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, 188, 188, 185, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 143, 142, 14, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 148, 147, 147, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 133, 132, 132, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, 146, + 18, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, 237, 237, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, 225, 225, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 152, 151, 151, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 195, 194, 66, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 206, 205, 205, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 241, + 240, 240, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 159, 159, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 239, 239, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 193, 192, 192, 55, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 252, 251, 251, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 228, 227, 227, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 187, 186, 58, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 203, 203, + 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 223, 223, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 161, 161, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 217, 216, 88, 57, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 138, 137, 137, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 191, 190, 62, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 213, + 213, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 164, 164, 185, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 252, 252, 57, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 236, 235, 235, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 247, 246, 118, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 181, 180, 180, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, + 182, 54, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 133, 133, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 205, 205, 186, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 193, 192, 192, 183, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 168, 167, 167, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 211, 210, 82, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 235, 234, 106, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188, 187, 187, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 159, 158, 30, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 176, 176, 184, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 239, 238, 110, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 184, 183, 183, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 167, 166, + 38, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 197, 197, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 215, 214, 86, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 164, 163, 163, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 133, 132, 132, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 200, 199, 199, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, + 147, 147, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, 188, 188, 57, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 205, 204, 204, 185, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 249, 249, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 182, 181, 181, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 146, 145, 145, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 212, 211, 211, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 231, 230, 102, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 152, 24, 57, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 141, 141, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 225, 224, 96, 184, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 149, 148, 148, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 222, 221, 221, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 165, + 165, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 134, 6, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 169, 168, 40, 185, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 246, 245, 245, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 219, 218, 90, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 167, 166, 38, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, + 128, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 249, 249, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 232, 104, 185, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 197, 196, 196, 57, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 228, 227, 227, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 213, 212, 212, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 162, 161, 161, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 223, 223, + 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 247, 246, 118, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 215, 214, 86, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 242, 241, 241, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 245, 244, 244, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 6, 70, 110, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 24, 0, 7, + 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 0, + 0, 0, 0, 0, 0, 100, 32, 0, 4, 50, 16, 16, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, + 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, + 0, 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 0, 0, 0, 0, 70, 128, 48, 128, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 194, 0, 16, 0, 0, 0, 0, 0, 6, + 4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, + 166, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 63, 56, 0, 0, 9, 194, 0, 16, 0, 0, 0, + 0, 0, 166, 14, 16, 0, 0, 0, 0, 0, 166, 142, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 13, 114, 0, 16, 0, 1, 0, 0, 0, + 230, 10, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 0, 32, 0, 8, 114, + 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 6, 144, 144, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, + 0, 0, 11, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/ui/shaders/bytecode/d3d12_5_1/guest_output_bilinear_ps.h b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_bilinear_ps.h new file mode 100644 index 0000000..41522a3 --- /dev/null +++ b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_bilinear_ps.h @@ -0,0 +1,125 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// int2 xe_bilinear_output_offset; // Offset: 0 Size: 8 +// float2 xe_bilinear_output_size_inv;// Offset: 8 Size: 8 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_bilinear_sampler sampler NA NA S0 s0 1 +// xe_bilinear_source texture float4 2d T0 t0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// +ps_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_sampler S0[0:0], mode_default, space=0 +dcl_resource_texture2d (float,float,float,float) T0[0:0], space=0 +dcl_input_ps_siv linear noperspective v0.xy, position +dcl_output o0.xyzw +dcl_temps 1 +ftoi r0.xy, v0.xyxx +iadd r0.xy, r0.xyxx, -CB0[0][0].xyxx +utof r0.xy, r0.xyxx +add r0.xy, r0.xyxx, l(0.500000, 0.500000, 0.000000, 0.000000) +mul r0.xy, r0.xyxx, CB0[0][0].zwzz +sample_l r0.xyz, r0.xyxx, T0[0].xyzw, S0[0], l(0.000000) +mov o0.xyz, r0.xyzx +mov o0.w, l(1.000000) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE guest_output_bilinear_ps[] = { + 68, 88, 66, 67, 235, 28, 93, 216, 171, 104, 177, 132, 67, 116, 72, 226, 224, 12, 60, + 100, 1, 0, 0, 0, 204, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 2, + 0, 0, 120, 2, 0, 0, 172, 2, 0, 0, 48, 4, 0, 0, 82, 68, 69, 70, 8, + 2, 0, 0, 1, 0, 0, 0, 236, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 255, 255, 0, 5, 0, 0, 224, 1, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, + 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 219, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 98, 105, 108, 105, + 110, 101, 97, 114, 95, 115, 97, 109, 112, 108, 101, 114, 0, 120, 101, 95, 98, 105, 108, + 105, 110, 101, 97, 114, 95, 115, 111, 117, 114, 99, 101, 0, 112, 117, 115, 104, 95, 99, + 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 171, 219, 0, 0, 0, 2, 0, 0, 0, + 4, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 1, 0, + 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 116, 1, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 152, + 1, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 188, 1, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 120, 101, 95, 98, 105, 108, 105, 110, 101, 97, 114, 95, 111, 117, 116, 112, 117, 116, + 95, 111, 102, 102, 115, 101, 116, 0, 105, 110, 116, 50, 0, 171, 1, 0, 2, 0, 1, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 110, 1, 0, 0, 120, 101, 95, 98, 105, 108, 105, + 110, 101, 97, 114, 95, 111, 117, 116, 112, 117, 116, 95, 115, 105, 122, 101, 95, 105, 110, + 118, 0, 102, 108, 111, 97, 116, 50, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 180, 1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, 0, 1, + 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 15, 3, 0, 0, 83, 86, 95, 80, 111, 115, 105, + 116, 105, 111, 110, 0, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, + 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, + 83, 72, 69, 88, 124, 1, 0, 0, 81, 0, 0, 0, 95, 0, 0, 0, 106, 8, 0, + 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 6, 70, 110, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 24, 0, 7, + 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 0, + 0, 0, 0, 0, 0, 100, 32, 0, 4, 50, 16, 16, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, + 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, + 0, 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 0, 0, 0, 0, 70, 128, 48, 128, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, + 63, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 9, 50, 0, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 230, 138, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 13, 114, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, + 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 9, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_cas_resample_dither_ps.h b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_cas_resample_dither_ps.h new file mode 100644 index 0000000..fc62404 --- /dev/null +++ b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_cas_resample_dither_ps.h @@ -0,0 +1,1032 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// int2 xe_cas_output_offset; // Offset: 0 Size: 8 +// float2 xe_cas_input_output_size_ratio;// Offset: 8 Size: 8 +// float xe_cas_sharpness_post_setup; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_cas_source texture float4 2d T0 t0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// +ps_5_1 +dcl_globalFlags refactoringAllowed +dcl_immediateConstantBuffer { { -0.001003, 0, 0, 0}, + { 0.000881, 0, 0, 0}, + { 0.001693, 0, 0, 0}, + { -0.001555, 0, 0, 0}, + { 0.001279, 0, 0, 0}, + { -0.000605, 0, 0, 0}, + { 0.001065, 0, 0, 0}, + { -0.001386, 0, 0, 0}, + { 0.001356, 0, 0, 0}, + { 0.000513, 0, 0, 0}, + { 0.001218, 0, 0, 0}, + { -0.001601, 0, 0, 0}, + { 0.000590, 0, 0, 0}, + { -0.000283, 0, 0, 0}, + { 0.001111, 0, 0, 0}, + { -0.001417, 0, 0, 0}, + { 0.001448, 0, 0, 0}, + { -0.000544, 0, 0, 0}, + { 0.000130, 0, 0, 0}, + { -0.001203, 0, 0, 0}, + { 0.000437, 0, 0, 0}, + { -0.001049, 0, 0, 0}, + { 0.000620, 0, 0, 0}, + { -0.000483, 0, 0, 0}, + { 0.001877, 0, 0, 0}, + { -0.001095, 0, 0, 0}, + { -0.000100, 0, 0, 0}, + { -0.000528, 0, 0, 0}, + { 0.001432, 0, 0, 0}, + { -0.001938, 0, 0, 0}, + { -0.000697, 0, 0, 0}, + { 0.000038, 0, 0, 0}, + { 0.000712, 0, 0, 0}, + { -0.001310, 0, 0, 0}, + { 0.001095, 0, 0, 0}, + { -0.000299, 0, 0, 0}, + { 0.001754, 0, 0, 0}, + { -0.001677, 0, 0, 0}, + { 0.001478, 0, 0, 0}, + { -0.000038, 0, 0, 0}, + { 0.000789, 0, 0, 0}, + { -0.001831, 0, 0, 0}, + { 0.000299, 0, 0, 0}, + { 0.000988, 0, 0, 0}, + { -0.001172, 0, 0, 0}, + { 0.000176, 0, 0, 0}, + { 0.001647, 0, 0, 0}, + { -0.001585, 0, 0, 0}, + { 0.000345, 0, 0, 0}, + { 0.001861, 0, 0, 0}, + { -0.001769, 0, 0, 0}, + { -0.000866, 0, 0, 0}, + { 0.000896, 0, 0, 0}, + { 0.000161, 0, 0, 0}, + { -0.000927, 0, 0, 0}, + { -0.001524, 0, 0, 0}, + { -0.000651, 0, 0, 0}, + { 0.001294, 0, 0, 0}, + { -0.000804, 0, 0, 0}, + { -0.001463, 0, 0, 0}, + { 0.001800, 0, 0, 0}, + { -0.000850, 0, 0, 0}, + { 0.000850, 0, 0, 0}, + { -0.000452, 0, 0, 0}, + { -0.001065, 0, 0, 0}, + { -0.000146, 0, 0, 0}, + { 0.000237, 0, 0, 0}, + { 0.001417, 0, 0, 0}, + { -0.000590, 0, 0, 0}, + { -0.000191, 0, 0, 0}, + { 0.001601, 0, 0, 0}, + { 0.001019, 0, 0, 0}, + { 0.000406, 0, 0, 0}, + { -0.000207, 0, 0, 0}, + { 0.001585, 0, 0, 0}, + { 0.000651, 0, 0, 0}, + { -0.000069, 0, 0, 0}, + { 0.000421, 0, 0, 0}, + { -0.001647, 0, 0, 0}, + { 0.001371, 0, 0, 0}, + { 0.000927, 0, 0, 0}, + { -0.000666, 0, 0, 0}, + { 0.001187, 0, 0, 0}, + { -0.001448, 0, 0, 0}, + { 0.000574, 0, 0, 0}, + { -0.001892, 0, 0, 0}, + { 0.000758, 0, 0, 0}, + { -0.001294, 0, 0, 0}, + { 0.001922, 0, 0, 0}, + { -0.001662, 0, 0, 0}, + { -0.001034, 0, 0, 0}, + { -0.000498, 0, 0, 0}, + { -0.001861, 0, 0, 0}, + { 0.001203, 0, 0, 0}, + { -0.000329, 0, 0, 0}, + { -0.001371, 0, 0, 0}, + { 0.001631, 0, 0, 0}, + { -0.001846, 0, 0, 0}, + { 0.000728, 0, 0, 0}, + { -0.000911, 0, 0, 0}, + { 0.001815, 0, 0, 0}, + { -0.001141, 0, 0, 0}, + { -0.000375, 0, 0, 0}, + { 0.000100, 0, 0, 0}, + { -0.000743, 0, 0, 0}, + { 0.001172, 0, 0, 0}, + { 0.000069, 0, 0, 0}, + { 0.001494, 0, 0, 0}, + { 0.000973, 0, 0, 0}, + { -0.000957, 0, 0, 0}, + { 0.001938, 0, 0, 0}, + { 0.000528, 0, 0, 0}, + { 0.000054, 0, 0, 0}, + { -0.001248, 0, 0, 0}, + { -0.000268, 0, 0, 0}, + { 0.001540, 0, 0, 0}, + { -0.000008, 0, 0, 0}, + { 0.000314, 0, 0, 0}, + { 0.001340, 0, 0, 0}, + { -0.001754, 0, 0, 0}, + { 0.000498, 0, 0, 0}, + { -0.001187, 0, 0, 0}, + { 0.000774, 0, 0, 0}, + { -0.001340, 0, 0, 0}, + { 0.000268, 0, 0, 0}, + { -0.001478, 0, 0, 0}, + { -0.000130, 0, 0, 0}, + { -0.000774, 0, 0, 0}, + { 0.001310, 0, 0, 0}, + { 0.000391, 0, 0, 0}, + { 0.000957, 0, 0, 0}, + { -0.000467, 0, 0, 0}, + { -0.001540, 0, 0, 0}, + { 0.001034, 0, 0, 0}, + { -0.000682, 0, 0, 0}, + { 0.001677, 0, 0, 0}, + { 0.001003, 0, 0, 0}, + { -0.000421, 0, 0, 0}, + { 0.001785, 0, 0, 0}, + { -0.000237, 0, 0, 0}, + { -0.000620, 0, 0, 0}, + { 0.001662, 0, 0, 0}, + { 0.000835, 0, 0, 0}, + { -0.001723, 0, 0, 0}, + { -0.001080, 0, 0, 0}, + { 0.001769, 0, 0, 0}, + { -0.000789, 0, 0, 0}, + { -0.001785, 0, 0, 0}, + { 0.000682, 0, 0, 0}, + { -0.000988, 0, 0, 0}, + { -0.001325, 0, 0, 0}, + { -0.000176, 0, 0, 0}, + { -0.001509, 0, 0, 0}, + { 0.000329, 0, 0, 0}, + { -0.001953, 0, 0, 0}, + { 0.000666, 0, 0, 0}, + { -0.001616, 0, 0, 0}, + { 0.001157, 0, 0, 0}, + { 0.000452, 0, 0, 0}, + { -0.000437, 0, 0, 0}, + { 0.000191, 0, 0, 0}, + { -0.001494, 0, 0, 0}, + { 0.001141, 0, 0, 0}, + { 0.000084, 0, 0, 0}, + { 0.001892, 0, 0, 0}, + { 0.001402, 0, 0, 0}, + { 0.000559, 0, 0, 0}, + { 0.000115, 0, 0, 0}, + { 0.001264, 0, 0, 0}, + { -0.000574, 0, 0, 0}, + { -0.000973, 0, 0, 0}, + { 0.001325, 0, 0, 0}, + { 0.000222, 0, 0, 0}, + { -0.000758, 0, 0, 0}, + { -0.001356, 0, 0, 0}, + { 0.001463, 0, 0, 0}, + { 0.000866, 0, 0, 0}, + { -0.000360, 0, 0, 0}, + { 0.000544, 0, 0, 0}, + { -0.001126, 0, 0, 0}, + { -0.000253, 0, 0, 0}, + { -0.000559, 0, 0, 0}, + { -0.001815, 0, 0, 0}, + { 0.001723, 0, 0, 0}, + { -0.001157, 0, 0, 0}, + { 0.000743, 0, 0, 0}, + { 0.001570, 0, 0, 0}, + { -0.000115, 0, 0, 0}, + { -0.001218, 0, 0, 0}, + { 0.001831, 0, 0, 0}, + { 0.000023, 0, 0, 0}, + { -0.001922, 0, 0, 0}, + { 0.001739, 0, 0, 0}, + { -0.000712, 0, 0, 0}, + { 0.001555, 0, 0, 0}, + { -0.001708, 0, 0, 0}, + { 0.001233, 0, 0, 0}, + { 0.000207, 0, 0, 0}, + { 0.001049, 0, 0, 0}, + { -0.000728, 0, 0, 0}, + { -0.001631, 0, 0, 0}, + { -0.000314, 0, 0, 0}, + { 0.000483, 0, 0, 0}, + { -0.001800, 0, 0, 0}, + { 0.000942, 0, 0, 0}, + { -0.000345, 0, 0, 0}, + { 0.000697, 0, 0, 0}, + { -0.001019, 0, 0, 0}, + { -0.001570, 0, 0, 0}, + { -0.000023, 0, 0, 0}, + { -0.001279, 0, 0, 0}, + { 0.000804, 0, 0, 0}, + { -0.000896, 0, 0, 0}, + { -0.001432, 0, 0, 0}, + { 0.000605, 0, 0, 0}, + { -0.000084, 0, 0, 0}, + { 0.000911, 0, 0, 0}, + { 0.001953, 0, 0, 0}, + { -0.001402, 0, 0, 0}, + { -0.000636, 0, 0, 0}, + { 0.001509, 0, 0, 0}, + { -0.000820, 0, 0, 0}, + { 0.001248, 0, 0, 0}, + { 0.000253, 0, 0, 0}, + { 0.001524, 0, 0, 0}, + { 0.001126, 0, 0, 0}, + { 0.000360, 0, 0, 0}, + { -0.000391, 0, 0, 0}, + { 0.001907, 0, 0, 0}, + { 0.001386, 0, 0, 0}, + { -0.001111, 0, 0, 0}, + { 0.001616, 0, 0, 0}, + { -0.000881, 0, 0, 0}, + { 0.000146, 0, 0, 0}, + { 0.001080, 0, 0, 0}, + { -0.000054, 0, 0, 0}, + { 0.000283, 0, 0, 0}, + { -0.001693, 0, 0, 0}, + { -0.001264, 0, 0, 0}, + { -0.000513, 0, 0, 0}, + { -0.000161, 0, 0, 0}, + { -0.001877, 0, 0, 0}, + { -0.000835, 0, 0, 0}, + { 0.000636, 0, 0, 0}, + { 0.000008, 0, 0, 0}, + { -0.001907, 0, 0, 0}, + { -0.000222, 0, 0, 0}, + { 0.000375, 0, 0, 0}, + { -0.001739, 0, 0, 0}, + { -0.000406, 0, 0, 0}, + { -0.001233, 0, 0, 0}, + { 0.001708, 0, 0, 0}, + { -0.000942, 0, 0, 0}, + { 0.000820, 0, 0, 0}, + { 0.001846, 0, 0, 0}, + { 0.000467, 0, 0, 0} } +dcl_constantbuffer CB0[0:0][2], immediateIndexed, space=0 +dcl_resource_texture2d (float,float,float,float) T0[0:0], space=0 +dcl_input_ps_siv linear noperspective v0.xy, position +dcl_output o0.xyzw +dcl_temps 14 +ftoi r0.xy, v0.xyxx +iadd r0.xy, r0.xyxx, -CB0[0][0].xyxx +mad r0.zw, CB0[0][0].zzzw, l(0.000000, 0.000000, 0.500000, 0.500000), l(0.000000, 0.000000, -0.500000, -0.500000) +utof r1.xy, r0.xyxx +mad r0.zw, r1.xxxy, CB0[0][0].zzzw, r0.zzzw +round_ni r1.xy, r0.zwzz +add r0.zw, r0.zzzw, -r1.xxxy +ftoi r1.xy, r1.xyxx +iadd r2.xyzw, r1.xyxy, l(-1, 0, 0, -1) +mov r3.xy, r2.zwzz +mov r3.zw, l(0,0,0,0) +ld r3.xyz, r3.xyzw, T0[0].xyzw +mov r2.zw, l(0,0,0,0) +ld r2.xyz, r2.xyzw, T0[0].xyzw +mov r1.zw, l(0,0,0,0) +ld r4.xyz, r1.xyzw, T0[0].xyzw +iadd r5.xyzw, r1.xyxy, l(1, 0, 1, -1) +mov r6.xy, r5.zwzz +mov r6.zw, l(0,0,0,0) +ld r6.xyz, r6.xyzw, T0[0].xyzw +mov r5.zw, l(0,0,0,0) +ld r5.xyz, r5.xyzw, T0[0].xyzw +iadd r7.xyzw, r1.xyxy, l(-1, 1, 2, 0) +mov r8.xy, r7.zwzz +mov r8.zw, l(0,0,0,0) +ld r8.xyz, r8.xyzw, T0[0].xyzw +mov r7.zw, l(0,0,0,0) +ld r7.xyz, r7.xyzw, T0[0].xyzw +iadd r9.xyzw, r1.xyxy, l(0, 2, 0, 1) +mov r10.xy, r9.zwzz +mov r10.zw, l(0,0,0,0) +ld r10.xyz, r10.xyzw, T0[0].xyzw +mov r9.zw, l(0,0,0,0) +ld r9.xyz, r9.xyzw, T0[0].xyzw +iadd r11.xyzw, r1.xyxy, l(2, 1, 1, 1) +mov r12.xy, r11.zwzz +mov r12.zw, l(0,0,0,0) +ld r12.xyz, r12.xyzw, T0[0].xyzw +mov r11.zw, l(0,0,0,0) +ld r11.xyz, r11.xyzw, T0[0].xyzw +iadd r1.xy, r1.xyxx, l(1, 2, 0, 0) +mov r1.zw, l(0,0,0,0) +ld r1.xyz, r1.xyzw, T0[0].xyzw +mul r3.xyz, r3.xyzx, r3.xyzx +mul r6.xyz, r6.xyzx, r6.xyzx +mul r2.xyz, r2.xyzx, r2.xyzx +mul r4.xyz, r4.xyzx, r4.xyzx +mul r5.xyz, r5.xyzx, r5.xyzx +mul r8.xyz, r8.xyzx, r8.xyzx +mul r7.xyz, r7.xyzx, r7.xyzx +mul r10.xyz, r10.xyzx, r10.xyzx +mul r12.xyz, r12.xyzx, r12.xyzx +mul r11.xyz, r11.xyzx, r11.xyzx +mul r9.xyz, r9.xyzx, r9.xyzx +mul r1.xyz, r1.xyzx, r1.xyzx +min r1.w, r2.y, r4.y +min r1.w, r1.w, r3.y +min r2.w, r5.y, r10.y +min r1.w, r1.w, r2.w +max r2.w, r2.y, r4.y +max r2.w, r2.w, r3.y +max r3.w, r5.y, r10.y +max r2.w, r2.w, r3.w +min r3.w, r4.y, r5.y +min r3.w, r3.w, r6.y +min r4.w, r8.y, r12.y +min r3.w, r3.w, r4.w +max r4.w, r4.y, r5.y +max r4.w, r4.w, r6.y +max r5.w, r8.y, r12.y +max r4.w, r4.w, r5.w +min r5.w, r7.y, r10.y +min r5.w, r4.y, r5.w +min r6.w, r9.y, r12.y +min r5.w, r5.w, r6.w +max r6.w, r7.y, r10.y +max r6.w, r4.y, r6.w +max r7.w, r9.y, r12.y +max r6.w, r6.w, r7.w +min r7.w, r10.y, r12.y +min r7.w, r5.y, r7.w +min r8.w, r1.y, r11.y +min r7.w, r7.w, r8.w +max r8.w, r10.y, r12.y +max r8.w, r5.y, r8.w +max r9.w, r1.y, r11.y +max r8.w, r8.w, r9.w +iadd r9.w, -r2.w, l(0x7ef07ebb) +iadd r10.w, -r4.w, l(0x7ef07ebb) +iadd r11.w, -r6.w, l(0x7ef07ebb) +iadd r12.w, -r8.w, l(0x7ef07ebb) +add r13.x, -r2.w, l(1.000000) +min r13.x, r1.w, r13.x +mul_sat r9.w, r9.w, r13.x +add r13.x, -r4.w, l(1.000000) +min r13.x, r3.w, r13.x +mul_sat r10.w, r10.w, r13.x +add r13.x, -r6.w, l(1.000000) +min r13.x, r5.w, r13.x +mul_sat r11.w, r11.w, r13.x +add r13.x, -r8.w, l(1.000000) +min r13.x, r7.w, r13.x +mul_sat r12.w, r12.w, r13.x +ushr r9.w, r9.w, l(1) +iadd r9.w, r9.w, l(0x1fbc4639) +ushr r10.w, r10.w, l(1) +iadd r10.w, r10.w, l(0x1fbc4639) +ushr r11.w, r11.w, l(1) +iadd r11.w, r11.w, l(0x1fbc4639) +ushr r12.w, r12.w, l(1) +iadd r12.w, r12.w, l(0x1fbc4639) +mul r9.w, r9.w, CB0[0][1].x +mul r10.w, r10.w, CB0[0][1].x +mul r11.w, r11.w, CB0[0][1].x +mul r12.w, r12.w, CB0[0][1].x +add r13.xy, -r0.wzww, l(1.000000, 1.000000, 0.000000, 0.000000) +mul r13.z, r13.x, r13.y +mul r13.xy, r0.zwzz, r13.xyxx +mul r0.z, r0.w, r0.z +add r0.w, -r1.w, r2.w +add r0.w, r0.w, l(0.031250) +iadd r0.w, -r0.w, l(0x7ef07ebb) +mul r1.w, r0.w, r13.z +add r2.w, -r3.w, r4.w +add r2.w, r2.w, l(0.031250) +iadd r2.w, -r2.w, l(0x7ef07ebb) +mul r3.w, r2.w, r13.x +add r4.w, -r5.w, r6.w +add r4.w, r4.w, l(0.031250) +iadd r4.w, -r4.w, l(0x7ef07ebb) +mul r5.w, r4.w, r13.y +add r6.w, -r7.w, r8.w +add r6.w, r6.w, l(0.031250) +iadd r6.w, -r6.w, l(0x7ef07ebb) +mul r7.w, r0.z, r6.w +mul r8.w, r1.w, r9.w +mul r13.w, r3.w, r10.w +mul r5.w, r5.w, r11.w +mad r3.w, r10.w, r3.w, r5.w +mad r0.w, r13.z, r0.w, r3.w +mul r7.w, r7.w, r12.w +mad r1.w, r9.w, r1.w, r7.w +mad r2.w, r13.x, r2.w, r1.w +mad r1.w, r13.y, r4.w, r1.w +mad r0.z, r0.z, r6.w, r3.w +add r3.w, r13.w, r13.w +mad r3.w, r8.w, l(2.000000), r3.w +mad r3.w, r5.w, l(2.000000), r3.w +mad r3.w, r7.w, l(2.000000), r3.w +add r3.w, r0.w, r3.w +add r3.w, r2.w, r3.w +add r3.w, r1.w, r3.w +add r3.w, r0.z, r3.w +iadd r4.w, -r3.w, l(0x7ef19fff) +mad r3.w, -r4.w, r3.w, l(2.000000) +mul r3.w, r3.w, r4.w +mul r2.xyz, r2.xyzx, r8.wwww +mad r2.xyz, r3.xyzx, r8.wwww, r2.xyzx +mad r2.xyz, r6.xyzx, r13.wwww, r2.xyzx +mad r2.xyz, r8.xyzx, r13.wwww, r2.xyzx +mad r2.xyz, r7.xyzx, r5.wwww, r2.xyzx +mad r2.xyz, r9.xyzx, r5.wwww, r2.xyzx +mad r2.xyz, r11.xyzx, r7.wwww, r2.xyzx +mad r1.xyz, r1.xyzx, r7.wwww, r2.xyzx +mad r1.xyz, r4.xyzx, r0.wwww, r1.xyzx +mad r1.xyz, r5.xyzx, r2.wwww, r1.xyzx +mad r1.xyz, r10.xyzx, r1.wwww, r1.xyzx +mad r1.xyz, r12.xyzx, r0.zzzz, r1.xyzx +mul_sat r1.xyz, r3.wwww, r1.xyzx +sqrt r1.xyz, r1.xyzx +bfi r0.y, l(4), l(4), r0.y, l(0) +bfi r0.x, l(4), l(0), r0.x, r0.y +add_sat o0.xyz, r1.xyzx, icb[r0.x + 0].xxxx +mov o0.w, l(1.000000) +ret +// Approximately 175 instruction slots used +#endif + +const BYTE guest_output_ffx_cas_resample_dither_ps[] = { + 68, 88, 66, 67, 0, 137, 156, 109, 124, 158, 247, 143, 56, 48, 248, 105, 125, 135, 166, + 115, 1, 0, 0, 0, 216, 40, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 116, 2, + 0, 0, 168, 2, 0, 0, 220, 2, 0, 0, 60, 40, 0, 0, 82, 68, 69, 70, 56, + 2, 0, 0, 1, 0, 0, 0, 172, 0, 0, 0, 2, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 255, 255, 0, 5, 0, 0, 16, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 99, 97, 115, 95, 115, 111, + 117, 114, 99, 101, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, + 0, 171, 171, 171, 154, 0, 0, 0, 3, 0, 0, 0, 196, 0, 0, 0, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 1, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 2, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 124, 1, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 2, 0, 0, 0, 164, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 200, 1, 0, 0, 16, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 236, 1, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, 99, + 97, 115, 95, 111, 117, 116, 112, 117, 116, 95, 111, 102, 102, 115, 101, 116, 0, 105, 110, + 116, 50, 0, 171, 171, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, + 1, 0, 0, 120, 101, 95, 99, 97, 115, 95, 105, 110, 112, 117, 116, 95, 111, 117, 116, + 112, 117, 116, 95, 115, 105, 122, 101, 95, 114, 97, 116, 105, 111, 0, 102, 108, 111, 97, + 116, 50, 0, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, + 1, 0, 0, 120, 101, 95, 99, 97, 115, 95, 115, 104, 97, 114, 112, 110, 101, 115, 115, + 95, 112, 111, 115, 116, 95, 115, 101, 116, 117, 112, 0, 102, 108, 111, 97, 116, 0, 171, + 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 1, 0, 0, 77, + 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, + 0, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, + 3, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, + 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 69, 88, 88, 37, 0, 0, 81, + 0, 0, 0, 86, 9, 0, 0, 106, 8, 0, 1, 53, 24, 0, 0, 2, 4, 0, 0, + 132, 131, 131, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 231, 230, 102, + 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, 221, 221, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 203, 203, 186, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 168, 167, 167, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 159, 158, 30, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 140, 139, 139, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, 181, + 181, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 178, 177, 177, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 134, 6, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 160, 159, 159, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 210, 209, 209, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 155, 154, 26, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 149, + 148, 148, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 145, 145, 58, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 185, 185, 186, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 190, 189, 189, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 143, 142, 14, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 137, 136, 8, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 158, 157, 157, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, 228, 228, + 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 137, 137, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 162, 34, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 253, 252, 252, 185, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 246, 245, 245, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 144, 143, 143, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 209, 208, + 208, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 138, 10, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188, 187, 187, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 254, 253, 253, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 183, 182, 54, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 161, 160, 32, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, + 186, 58, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 171, 171, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 143, 143, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 157, 156, 156, 185, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 230, 229, 229, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 220, 219, 219, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 194, 193, 193, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 161, 160, 32, + 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 207, 206, 78, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 239, 239, 186, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 157, 156, 156, 57, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 130, 129, 129, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 154, 153, 153, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 185, 184, + 56, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 216, 215, 215, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 208, 207, 207, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 181, 180, 180, 57, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 244, 243, 243, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 232, 231, 231, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 227, + 226, 98, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 235, 234, 106, 58, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 169, 168, 40, 57, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, 242, 114, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 200, 199, 199, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 171, 170, 42, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 170, 169, 169, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 211, 210, 82, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 191, 191, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 236, 235, 235, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 223, 222, 94, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 223, 222, 94, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 237, 236, 236, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 139, + 139, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 152, 24, 185, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 248, 120, 57, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 186, 185, 185, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 155, 154, 26, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 201, 200, 72, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, + 209, 209, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 133, 133, 58, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 212, 212, 57, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 217, 216, 88, 185, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 208, 207, 207, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 171, 170, 42, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 145, 144, 144, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 220, 220, + 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 216, 215, 215, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 179, 179, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 243, 242, 114, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 175, 174, 46, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 156, 155, 155, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 190, 189, + 189, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151, 150, 22, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 247, 247, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 199, 198, 70, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 170, 169, 169, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 252, 251, 251, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 218, + 217, 217, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 135, 135, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 130, 2, 186, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 243, 243, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 158, 157, 157, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 173, 172, 172, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 180, 179, 179, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 213, 213, + 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 242, 241, 241, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 190, 62, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 239, 238, 110, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 238, 237, 237, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 150, 149, 149, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 197, 196, + 196, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 209, 208, 208, 56, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 194, 66, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 154, 153, 153, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 145, 144, 144, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 196, 195, 195, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, + 254, 126, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 251, 250, 122, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 253, 253, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 138, 10, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 225, 224, 96, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 164, 163, 163, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 141, 140, 140, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 201, 201, + 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 128, 0, 183, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 164, 164, 57, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 176, 175, 175, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 230, 229, 229, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 131, 130, 2, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 155, + 155, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 203, 202, 74, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176, 175, 175, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 141, 140, 140, 57, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 194, 193, 193, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 137, 136, 8, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 203, + 202, 74, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 171, 171, 58, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 205, 204, 204, 57, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 251, 250, 122, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 245, 244, 244, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 202, 201, 201, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 136, 135, 135, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 179, 178, 50, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 219, 219, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132, 131, 131, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 221, 220, 220, 185, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 234, 233, 233, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 249, 248, 120, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 162, + 34, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 218, 217, 217, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 219, 218, 90, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 226, 225, 225, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 142, 141, 141, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 232, 231, 231, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 207, + 206, 78, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 233, 233, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 179, 178, 50, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, 129, 129, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 174, 173, 173, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 185, 184, 56, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 198, 197, 197, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, 172, 172, + 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175, 174, 46, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 212, 211, 211, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 151, 151, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 237, 236, 236, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, 228, + 228, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 200, 72, 57, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 195, 195, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 150, 149, 149, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 177, 176, 176, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 248, 247, 247, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 184, + 183, 183, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, 146, 18, 58, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 241, 240, 240, 56, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 165, 165, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 151, 150, 22, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 255, 254, 126, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 174, 173, 173, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 232, 104, + 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 199, 198, 70, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 178, 177, 177, 186, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 192, 191, 191, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 227, 226, 98, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 189, 188, 188, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 142, + 14, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 147, 147, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 132, 132, 185, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 147, 146, 18, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 238, 237, 237, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 226, 225, 225, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 152, + 151, 151, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 194, 66, 58, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 205, 205, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 241, 240, 240, 184, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 160, 159, 159, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 240, 239, 239, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 193, 192, 192, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 251, 251, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 227, 227, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, 186, 58, 186, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 204, 203, 203, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 224, 223, 223, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 162, 161, 161, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217, 216, + 88, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 137, 137, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 190, 62, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 214, 213, 213, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 165, 164, 164, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 253, 252, 252, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 236, + 235, 235, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 247, 246, 118, 58, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181, 180, 180, 185, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 182, 54, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 134, 133, 133, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 206, 205, 205, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 193, 192, 192, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 167, 167, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 211, 210, 82, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 235, 234, 106, 186, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 188, 187, 187, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 159, 158, 30, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 177, 176, 176, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, 238, + 110, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 184, 183, 183, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 167, 166, 38, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 198, 197, 197, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 215, 214, 86, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, + 163, 163, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 132, 132, 57, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 199, 199, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 147, 147, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 189, 188, 188, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 205, 204, 204, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 250, 249, 249, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, 181, 181, + 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 145, 145, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, 211, 211, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 231, 230, 102, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 153, 152, 24, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 142, 141, 141, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225, 224, + 96, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 149, 148, 148, 57, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, 221, 221, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 166, 165, 165, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 135, 134, 6, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 169, 168, 40, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, + 245, 245, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 219, 218, 90, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 167, 166, 38, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 128, 0, 55, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 250, 249, 249, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 233, 232, 104, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 197, 196, 196, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 227, 227, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 212, 212, 185, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 161, 161, 186, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 224, 223, 223, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 247, 246, 118, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 215, 214, 86, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 242, 241, + 241, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 244, 244, 57, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 7, 70, 142, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 88, 24, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 85, 85, 0, 0, 0, 0, 0, 0, 100, 32, 0, 4, 50, 16, 16, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, + 104, 0, 0, 2, 14, 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, + 0, 70, 16, 16, 0, 0, 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, 128, 48, 128, 65, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 17, 194, 0, 16, 0, + 0, 0, 0, 0, 166, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, + 0, 63, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 0, + 0, 0, 191, 86, 0, 0, 5, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 50, 0, 0, 11, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, + 0, 1, 0, 0, 0, 166, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 166, 14, 16, 0, 0, 0, 0, 0, 65, 0, 0, 5, 50, 0, 16, 0, 1, + 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 194, 0, 16, 0, + 0, 0, 0, 0, 166, 14, 16, 0, 0, 0, 0, 0, 6, 4, 16, 128, 65, 0, 0, + 0, 1, 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, + 16, 0, 1, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 54, 0, 0, 5, 50, 0, 16, 0, 3, 0, 0, + 0, 230, 10, 16, 0, 2, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, + 0, 8, 114, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, + 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, + 5, 0, 0, 0, 70, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 255, 255, 255, 255, 54, 0, 0, 5, 50, 0, + 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 54, 0, 0, 8, 194, + 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 6, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, + 114, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 126, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 7, 0, + 0, 0, 70, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 1, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, + 8, 0, 0, 0, 230, 10, 16, 0, 7, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 8, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, + 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, + 70, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 10, 0, + 0, 0, 230, 10, 16, 0, 9, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 4, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 12, 0, 0, 0, + 230, 10, 16, 0, 11, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, + 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, + 0, 0, 8, 114, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, + 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, + 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, + 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, + 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, + 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, + 0, 56, 0, 0, 7, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, + 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 5, + 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, + 56, 0, 0, 7, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, + 0, 70, 2, 16, 0, 8, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 7, 0, + 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 56, + 0, 0, 7, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, + 70, 2, 16, 0, 10, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 12, 0, 0, + 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 56, 0, + 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, + 2, 16, 0, 11, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, + 70, 2, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 56, 0, 0, + 7, 114, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 70, 2, + 16, 0, 1, 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, + 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 51, 0, 0, 7, + 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 3, 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, + 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 51, 0, 0, 7, 130, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, + 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 52, 0, 0, 7, 130, 0, + 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, + 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, + 5, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, + 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 4, + 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, + 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, + 0, 51, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 8, 0, + 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 3, + 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, + 52, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, + 0, 26, 0, 16, 0, 5, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 52, + 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, + 26, 0, 16, 0, 12, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, + 0, 58, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 51, 0, + 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, + 0, 16, 0, 10, 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, + 26, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 51, 0, 0, + 7, 130, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, + 16, 0, 12, 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, + 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 52, 0, 0, 7, + 130, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, + 0, 10, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 26, 0, + 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 52, 0, 0, 7, 130, + 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, + 12, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, + 0, 6, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 51, 0, 0, 7, 130, 0, + 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 12, + 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, + 5, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, + 0, 8, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 11, 0, + 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 7, + 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, + 8, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, + 0, 52, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 5, 0, + 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 9, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, + 52, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, + 0, 58, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 8, 130, 0, 16, 0, 9, 0, + 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 187, + 126, 240, 126, 30, 0, 0, 8, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 128, + 65, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 187, 126, 240, 126, 30, 0, 0, + 8, 130, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 6, 0, + 0, 0, 1, 64, 0, 0, 187, 126, 240, 126, 30, 0, 0, 8, 130, 0, 16, 0, 12, + 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 8, 0, 0, 0, 1, 64, 0, 0, + 187, 126, 240, 126, 0, 0, 0, 8, 18, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, + 128, 65, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 51, 0, + 0, 7, 18, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, + 0, 16, 0, 13, 0, 0, 0, 56, 32, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, + 58, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 0, 0, 0, + 8, 18, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 4, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 51, 0, 0, 7, 18, 0, 16, 0, 13, + 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, + 56, 32, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, + 0, 10, 0, 16, 0, 13, 0, 0, 0, 0, 0, 0, 8, 18, 0, 16, 0, 13, 0, + 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 128, 63, 51, 0, 0, 7, 18, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, + 5, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 56, 32, 0, 7, 130, 0, 16, + 0, 11, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 13, 0, + 0, 0, 0, 0, 0, 8, 18, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 128, 65, + 0, 0, 0, 8, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 51, 0, 0, 7, + 18, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, + 0, 13, 0, 0, 0, 56, 32, 0, 7, 130, 0, 16, 0, 12, 0, 0, 0, 58, 0, + 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 85, 0, 0, 7, 130, + 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, + 0, 9, 0, 0, 0, 1, 64, 0, 0, 57, 70, 188, 31, 85, 0, 0, 7, 130, 0, + 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, + 10, 0, 0, 0, 1, 64, 0, 0, 57, 70, 188, 31, 85, 0, 0, 7, 130, 0, 16, + 0, 11, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 11, + 0, 0, 0, 1, 64, 0, 0, 57, 70, 188, 31, 85, 0, 0, 7, 130, 0, 16, 0, + 12, 0, 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 30, 0, 0, 7, 130, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 12, 0, + 0, 0, 1, 64, 0, 0, 57, 70, 188, 31, 56, 0, 0, 9, 130, 0, 16, 0, 9, + 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 56, 0, 0, 9, 130, 0, 16, 0, 10, 0, 0, + 0, 58, 0, 16, 0, 10, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 56, 0, 0, 9, 130, 0, 16, 0, 11, 0, 0, 0, 58, + 0, 16, 0, 11, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 56, 0, 0, 9, 130, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, + 0, 12, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 11, 50, 0, 16, 0, 13, 0, 0, 0, 182, 15, 16, 128, 65, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 7, 66, 0, 16, 0, 13, 0, 0, + 0, 10, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 56, 0, + 0, 7, 50, 0, 16, 0, 13, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 70, + 0, 16, 0, 13, 0, 0, 0, 56, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 0, 0, 0, 7, 130, 0, 16, 0, 0, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 61, + 30, 0, 0, 8, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 187, 126, 240, 126, 56, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 13, + 0, 0, 0, 0, 0, 0, 8, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 128, + 65, 0, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 0, 0, 0, + 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 61, 30, 0, 0, 8, 130, 0, 16, 0, 2, 0, 0, 0, 58, + 0, 16, 128, 65, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 187, 126, 240, 126, + 56, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, + 0, 10, 0, 16, 0, 13, 0, 0, 0, 0, 0, 0, 8, 130, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 5, 0, 0, 0, 58, 0, 16, 0, 6, + 0, 0, 0, 0, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 61, 30, 0, 0, 8, 130, 0, 16, + 0, 4, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 187, 126, 240, 126, 56, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, + 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 0, 0, 0, 8, + 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 7, 0, 0, + 0, 58, 0, 16, 0, 8, 0, 0, 0, 0, 0, 0, 7, 130, 0, 16, 0, 6, 0, + 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 61, 30, + 0, 0, 8, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, + 6, 0, 0, 0, 1, 64, 0, 0, 187, 126, 240, 126, 56, 0, 0, 7, 130, 0, 16, + 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, + 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, + 13, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, + 0, 56, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, + 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 3, + 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 5, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, + 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, 50, 0, 0, 9, + 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 50, 0, 0, 9, 130, 0, + 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 2, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, + 1, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 66, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 58, + 0, 16, 0, 3, 0, 0, 0, 0, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 50, 0, 0, + 9, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 64, 58, 0, 16, 0, 3, 0, 0, 0, 50, 0, 0, 9, 130, + 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 64, 58, 0, 16, 0, 3, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, + 0, 3, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 64, 58, 0, 16, 0, 3, 0, 0, 0, 0, 0, 0, 7, 130, 0, 16, 0, 3, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, + 0, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, + 0, 58, 0, 16, 0, 3, 0, 0, 0, 0, 0, 0, 7, 130, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 0, + 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 8, 130, 0, 16, 0, 4, 0, 0, + 0, 58, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 255, 159, + 241, 126, 50, 0, 0, 10, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 128, 65, + 0, 0, 0, 4, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 64, 56, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, + 0, 3, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 56, 0, 0, 7, 114, 0, + 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 246, 15, 16, 0, 8, + 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, + 3, 0, 0, 0, 246, 15, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, + 0, 50, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 6, 0, + 0, 0, 246, 15, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 50, + 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, + 246, 15, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 50, 0, 0, + 9, 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 246, 15, + 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 50, 0, 0, 9, 114, + 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 246, 15, 16, 0, + 5, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, + 0, 2, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 246, 15, 16, 0, 7, 0, + 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 1, + 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 7, 0, 0, 0, + 70, 2, 16, 0, 2, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 1, 0, 0, + 0, 70, 2, 16, 0, 4, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 1, 0, 0, 0, 70, + 2, 16, 0, 5, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, + 1, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, + 0, 10, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 1, 0, + 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 12, + 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, + 56, 32, 0, 7, 114, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, + 0, 70, 2, 16, 0, 1, 0, 0, 0, 75, 0, 0, 5, 114, 0, 16, 0, 1, 0, + 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 140, 0, 0, + 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 0, 32, 0, 8, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, + 1, 0, 0, 0, 6, 144, 144, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, + 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 175, 0, 0, 0, 14, 0, 0, 0, 0, + 1, 0, 0, 2, 0, 0, 0, 115, 0, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0}; diff --git a/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_cas_resample_ps.h b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_cas_resample_ps.h new file mode 100644 index 0000000..69d9c3a --- /dev/null +++ b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_cas_resample_ps.h @@ -0,0 +1,550 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// int2 xe_cas_output_offset; // Offset: 0 Size: 8 +// float2 xe_cas_input_output_size_ratio;// Offset: 8 Size: 8 +// float xe_cas_sharpness_post_setup; // Offset: 16 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_cas_source texture float4 2d T0 t0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// +ps_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][2], immediateIndexed, space=0 +dcl_resource_texture2d (float,float,float,float) T0[0:0], space=0 +dcl_input_ps_siv linear noperspective v0.xy, position +dcl_output o0.xyzw +dcl_temps 14 +ftoi r0.xy, v0.xyxx +iadd r0.xy, r0.xyxx, -CB0[0][0].xyxx +mad r0.zw, CB0[0][0].zzzw, l(0.000000, 0.000000, 0.500000, 0.500000), l(0.000000, 0.000000, -0.500000, -0.500000) +utof r0.xy, r0.xyxx +mad r0.xy, r0.xyxx, CB0[0][0].zwzz, r0.zwzz +round_ni r0.zw, r0.xxxy +add r0.xy, -r0.zwzz, r0.xyxx +ftoi r1.xy, r0.zwzz +iadd r2.xyzw, r1.xyxy, l(-1, 0, 0, -1) +mov r3.xy, r2.zwzz +mov r3.zw, l(0,0,0,0) +ld r3.xyz, r3.xyzw, T0[0].xyzw +mov r2.zw, l(0,0,0,0) +ld r2.xyz, r2.xyzw, T0[0].xyzw +mov r1.zw, l(0,0,0,0) +ld r4.xyz, r1.xyzw, T0[0].xyzw +iadd r5.xyzw, r1.xyxy, l(1, 0, 1, -1) +mov r6.xy, r5.zwzz +mov r6.zw, l(0,0,0,0) +ld r6.xyz, r6.xyzw, T0[0].xyzw +mov r5.zw, l(0,0,0,0) +ld r5.xyz, r5.xyzw, T0[0].xyzw +iadd r7.xyzw, r1.xyxy, l(-1, 1, 2, 0) +mov r8.xy, r7.zwzz +mov r8.zw, l(0,0,0,0) +ld r8.xyz, r8.xyzw, T0[0].xyzw +mov r7.zw, l(0,0,0,0) +ld r7.xyz, r7.xyzw, T0[0].xyzw +iadd r9.xyzw, r1.xyxy, l(0, 2, 0, 1) +mov r10.xy, r9.zwzz +mov r10.zw, l(0,0,0,0) +ld r10.xyz, r10.xyzw, T0[0].xyzw +mov r9.zw, l(0,0,0,0) +ld r9.xyz, r9.xyzw, T0[0].xyzw +iadd r11.xyzw, r1.xyxy, l(2, 1, 1, 1) +mov r12.xy, r11.zwzz +mov r12.zw, l(0,0,0,0) +ld r12.xyz, r12.xyzw, T0[0].xyzw +mov r11.zw, l(0,0,0,0) +ld r11.xyz, r11.xyzw, T0[0].xyzw +iadd r1.xy, r1.xyxx, l(1, 2, 0, 0) +mov r1.zw, l(0,0,0,0) +ld r1.xyz, r1.xyzw, T0[0].xyzw +mul r3.xyz, r3.xyzx, r3.xyzx +mul r6.xyz, r6.xyzx, r6.xyzx +mul r2.xyz, r2.xyzx, r2.xyzx +mul r4.xyz, r4.xyzx, r4.xyzx +mul r5.xyz, r5.xyzx, r5.xyzx +mul r8.xyz, r8.xyzx, r8.xyzx +mul r7.xyz, r7.xyzx, r7.xyzx +mul r10.xyz, r10.xyzx, r10.xyzx +mul r12.xyz, r12.xyzx, r12.xyzx +mul r11.xyz, r11.xyzx, r11.xyzx +mul r9.xyz, r9.xyzx, r9.xyzx +mul r1.xyz, r1.xyzx, r1.xyzx +min r0.z, r2.y, r4.y +min r0.z, r0.z, r3.y +min r0.w, r5.y, r10.y +min r0.z, r0.w, r0.z +max r0.w, r2.y, r4.y +max r0.w, r0.w, r3.y +max r1.w, r5.y, r10.y +max r0.w, r0.w, r1.w +min r1.w, r4.y, r5.y +min r1.w, r1.w, r6.y +min r2.w, r8.y, r12.y +min r1.w, r1.w, r2.w +max r2.w, r4.y, r5.y +max r2.w, r2.w, r6.y +max r3.w, r8.y, r12.y +max r2.w, r2.w, r3.w +min r3.w, r7.y, r10.y +min r3.w, r3.w, r4.y +min r4.w, r9.y, r12.y +min r3.w, r3.w, r4.w +max r4.w, r7.y, r10.y +max r4.w, r4.w, r4.y +max r5.w, r9.y, r12.y +max r4.w, r4.w, r5.w +min r5.w, r10.y, r12.y +min r5.w, r5.w, r5.y +min r6.w, r1.y, r11.y +min r5.w, r5.w, r6.w +max r6.w, r10.y, r12.y +max r6.w, r5.y, r6.w +max r7.w, r1.y, r11.y +max r6.w, r6.w, r7.w +iadd r7.w, -r0.w, l(0x7ef07ebb) +iadd r8.w, -r2.w, l(0x7ef07ebb) +iadd r9.w, -r4.w, l(0x7ef07ebb) +iadd r10.w, -r6.w, l(0x7ef07ebb) +add r11.w, -r0.w, l(1.000000) +min r11.w, r0.z, r11.w +mul_sat r7.w, r7.w, r11.w +add r11.w, -r2.w, l(1.000000) +min r11.w, r1.w, r11.w +mul_sat r8.w, r8.w, r11.w +add r11.w, -r4.w, l(1.000000) +min r11.w, r3.w, r11.w +mul_sat r9.w, r9.w, r11.w +add r11.w, -r6.w, l(1.000000) +min r11.w, r5.w, r11.w +mul_sat r10.w, r10.w, r11.w +ushr r7.w, r7.w, l(1) +iadd r7.w, r7.w, l(0x1fbc4639) +ushr r8.w, r8.w, l(1) +iadd r8.w, r8.w, l(0x1fbc4639) +ushr r9.w, r9.w, l(1) +iadd r9.w, r9.w, l(0x1fbc4639) +ushr r10.w, r10.w, l(1) +iadd r10.w, r10.w, l(0x1fbc4639) +mul r7.w, r7.w, CB0[0][1].x +mul r8.w, r8.w, CB0[0][1].x +mul r9.w, r9.w, CB0[0][1].x +mul r10.w, r10.w, CB0[0][1].x +add r13.xy, -r0.yxyy, l(1.000000, 1.000000, 0.000000, 0.000000) +mul r11.w, r13.x, r13.y +mul r13.xy, r0.xyxx, r13.xyxx +mul r0.x, r0.y, r0.x +add r0.y, -r0.z, r0.w +add r0.y, r0.y, l(0.031250) +iadd r0.y, -r0.y, l(0x7ef07ebb) +mul r0.z, r0.y, r11.w +add r0.w, -r1.w, r2.w +add r0.w, r0.w, l(0.031250) +iadd r0.w, -r0.w, l(0x7ef07ebb) +mul r1.w, r0.w, r13.x +add r2.w, -r3.w, r4.w +add r2.w, r2.w, l(0.031250) +iadd r2.w, -r2.w, l(0x7ef07ebb) +mul r3.w, r2.w, r13.y +add r4.w, -r5.w, r6.w +add r4.w, r4.w, l(0.031250) +iadd r4.w, -r4.w, l(0x7ef07ebb) +mul r5.w, r0.x, r4.w +mul r6.w, r0.z, r7.w +mul r12.w, r1.w, r8.w +mul r3.w, r3.w, r9.w +mad r1.w, r8.w, r1.w, r3.w +mad r0.y, r11.w, r0.y, r1.w +mul r5.w, r5.w, r10.w +mad r0.z, r7.w, r0.z, r5.w +mad r0.w, r13.x, r0.w, r0.z +mad r0.z, r13.y, r2.w, r0.z +mad r0.x, r0.x, r4.w, r1.w +add r1.w, r12.w, r12.w +mad r1.w, r6.w, l(2.000000), r1.w +mad r1.w, r3.w, l(2.000000), r1.w +mad r1.w, r5.w, l(2.000000), r1.w +add r1.w, r0.y, r1.w +add r1.w, r0.w, r1.w +add r1.w, r0.z, r1.w +add r1.w, r0.x, r1.w +iadd r2.w, -r1.w, l(0x7ef19fff) +mad r1.w, -r2.w, r1.w, l(2.000000) +mul r1.w, r1.w, r2.w +mul r2.xyz, r2.xyzx, r6.wwww +mad r2.xyz, r3.xyzx, r6.wwww, r2.xyzx +mad r2.xyz, r6.xyzx, r12.wwww, r2.xyzx +mad r2.xyz, r8.xyzx, r12.wwww, r2.xyzx +mad r2.xyz, r7.xyzx, r3.wwww, r2.xyzx +mad r2.xyz, r9.xyzx, r3.wwww, r2.xyzx +mad r2.xyz, r11.xyzx, r5.wwww, r2.xyzx +mad r1.xyz, r1.xyzx, r5.wwww, r2.xyzx +mad r1.xyz, r4.xyzx, r0.yyyy, r1.xyzx +mad r1.xyz, r5.xyzx, r0.wwww, r1.xyzx +mad r0.yzw, r10.xxyz, r0.zzzz, r1.xxyz +mad r0.xyz, r12.xyzx, r0.xxxx, r0.yzwy +mul_sat r0.xyz, r1.wwww, r0.xyzx +sqrt o0.xyz, r0.xyzx +mov o0.w, l(1.000000) +ret +// Approximately 172 instruction slots used +#endif + +const BYTE guest_output_ffx_cas_resample_ps[] = { + 68, 88, 66, 67, 84, 78, 130, 0, 246, 156, 95, 10, 227, 64, 193, 189, 212, 26, 149, + 36, 1, 0, 0, 0, 88, 24, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 116, 2, + 0, 0, 168, 2, 0, 0, 220, 2, 0, 0, 188, 23, 0, 0, 82, 68, 69, 70, 56, + 2, 0, 0, 1, 0, 0, 0, 172, 0, 0, 0, 2, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 255, 255, 0, 5, 0, 0, 16, 2, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 99, 97, 115, 95, 115, 111, + 117, 114, 99, 101, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, + 0, 171, 171, 171, 154, 0, 0, 0, 3, 0, 0, 0, 196, 0, 0, 0, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 1, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 2, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 124, 1, 0, 0, 8, 0, 0, 0, + 8, 0, 0, 0, 2, 0, 0, 0, 164, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 200, 1, 0, 0, 16, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 236, 1, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, 99, + 97, 115, 95, 111, 117, 116, 112, 117, 116, 95, 111, 102, 102, 115, 101, 116, 0, 105, 110, + 116, 50, 0, 171, 171, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, + 1, 0, 0, 120, 101, 95, 99, 97, 115, 95, 105, 110, 112, 117, 116, 95, 111, 117, 116, + 112, 117, 116, 95, 115, 105, 122, 101, 95, 114, 97, 116, 105, 111, 0, 102, 108, 111, 97, + 116, 50, 0, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, + 1, 0, 0, 120, 101, 95, 99, 97, 115, 95, 115, 104, 97, 114, 112, 110, 101, 115, 115, + 95, 112, 111, 115, 116, 95, 115, 101, 116, 117, 112, 0, 102, 108, 111, 97, 116, 0, 171, + 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 1, 0, 0, 77, + 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, + 0, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, + 3, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, + 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 69, 88, 216, 20, 0, 0, 81, + 0, 0, 0, 54, 5, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 88, 24, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 85, 85, 0, 0, 0, 0, 0, 0, 100, 32, 0, 4, 50, 16, 16, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, + 104, 0, 0, 2, 14, 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, + 0, 70, 16, 16, 0, 0, 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, 128, 48, 128, 65, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 17, 194, 0, 16, 0, + 0, 0, 0, 0, 166, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, + 0, 63, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 0, + 0, 0, 191, 86, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 50, 0, 0, 11, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 0, 0, 0, 0, 230, 138, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 65, 0, 0, 5, 194, 0, 16, 0, 0, + 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 50, 0, 16, 0, + 0, 0, 0, 0, 230, 10, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 0, 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 1, 0, 0, 0, 230, 10, + 16, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, + 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 54, 0, 0, 5, 50, 0, 16, 0, 3, 0, 0, + 0, 230, 10, 16, 0, 2, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, + 3, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 2, + 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, + 0, 8, 114, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, + 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, + 5, 0, 0, 0, 70, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 255, 255, 255, 255, 54, 0, 0, 5, 50, 0, + 16, 0, 6, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 54, 0, 0, 8, 194, + 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 6, 0, 0, + 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, + 114, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 126, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 7, 0, + 0, 0, 70, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 1, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, + 8, 0, 0, 0, 230, 10, 16, 0, 7, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 8, 0, 0, 0, 70, + 14, 16, 0, 8, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, + 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, + 70, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 10, 0, + 0, 0, 230, 10, 16, 0, 9, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 10, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, + 0, 10, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, + 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 4, + 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 12, 0, 0, 0, + 230, 10, 16, 0, 11, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 12, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, + 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, + 194, 0, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, + 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, + 0, 0, 8, 114, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, + 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, + 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, + 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, + 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, + 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, + 0, 56, 0, 0, 7, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, + 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 5, + 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, + 56, 0, 0, 7, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, + 0, 70, 2, 16, 0, 8, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 7, 0, + 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 56, + 0, 0, 7, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, + 70, 2, 16, 0, 10, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 12, 0, 0, + 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 56, 0, + 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, + 2, 16, 0, 11, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, + 70, 2, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 56, 0, 0, + 7, 114, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 70, 2, + 16, 0, 1, 0, 0, 0, 51, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 51, 0, 0, 7, + 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 3, 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 51, 0, 0, 7, 66, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, + 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 52, 0, 0, 7, 130, 0, + 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, + 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, + 5, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 4, + 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, + 0, 51, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 8, 0, + 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, + 52, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, + 0, 26, 0, 16, 0, 5, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 52, + 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, + 26, 0, 16, 0, 12, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 51, 0, + 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, + 0, 16, 0, 10, 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 51, 0, 0, + 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, + 16, 0, 12, 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, + 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 52, 0, 0, 7, + 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, + 0, 10, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, + 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 52, 0, 0, 7, 130, + 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, + 12, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, + 0, 4, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 51, 0, 0, 7, 130, 0, + 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 12, + 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, + 5, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, + 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 11, 0, + 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, + 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, + 6, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, + 0, 52, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 5, 0, + 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 7, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, + 52, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, + 0, 58, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 8, 130, 0, 16, 0, 7, 0, + 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 187, + 126, 240, 126, 30, 0, 0, 8, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 128, + 65, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 187, 126, 240, 126, 30, 0, 0, + 8, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 4, 0, + 0, 0, 1, 64, 0, 0, 187, 126, 240, 126, 30, 0, 0, 8, 130, 0, 16, 0, 10, + 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, + 187, 126, 240, 126, 0, 0, 0, 8, 130, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, + 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 51, 0, + 0, 7, 130, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 11, 0, 0, 0, 56, 32, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, + 58, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 0, 0, 0, + 8, 130, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 2, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 51, 0, 0, 7, 130, 0, 16, 0, 11, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, + 56, 32, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, + 0, 58, 0, 16, 0, 11, 0, 0, 0, 0, 0, 0, 8, 130, 0, 16, 0, 11, 0, + 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 128, 63, 51, 0, 0, 7, 130, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 56, 32, 0, 7, 130, 0, 16, + 0, 9, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 11, 0, + 0, 0, 0, 0, 0, 8, 130, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 128, 65, + 0, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 51, 0, 0, 7, + 130, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, + 0, 11, 0, 0, 0, 56, 32, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, + 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 85, 0, 0, 7, 130, + 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, + 0, 7, 0, 0, 0, 1, 64, 0, 0, 57, 70, 188, 31, 85, 0, 0, 7, 130, 0, + 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, + 8, 0, 0, 0, 1, 64, 0, 0, 57, 70, 188, 31, 85, 0, 0, 7, 130, 0, 16, + 0, 9, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 1, 0, + 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 9, + 0, 0, 0, 1, 64, 0, 0, 57, 70, 188, 31, 85, 0, 0, 7, 130, 0, 16, 0, + 10, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, + 0, 30, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 10, 0, + 0, 0, 1, 64, 0, 0, 57, 70, 188, 31, 56, 0, 0, 9, 130, 0, 16, 0, 7, + 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 56, 0, 0, 9, 130, 0, 16, 0, 8, 0, 0, + 0, 58, 0, 16, 0, 8, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 56, 0, 0, 9, 130, 0, 16, 0, 9, 0, 0, 0, 58, + 0, 16, 0, 9, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 56, 0, 0, 9, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, + 0, 10, 0, 0, 0, 10, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 11, 50, 0, 16, 0, 13, 0, 0, 0, 22, 5, 16, 128, 65, + 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 11, 0, 0, + 0, 10, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 56, 0, + 0, 7, 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, + 0, 16, 0, 13, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 65, 0, 0, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 34, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 61, + 30, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 187, 126, 240, 126, 56, 0, 0, 7, 66, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 11, + 0, 0, 0, 0, 0, 0, 8, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 128, + 65, 0, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 0, 0, 0, + 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 61, 30, 0, 0, 8, 130, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 187, 126, 240, 126, + 56, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 13, 0, 0, 0, 0, 0, 0, 8, 130, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 4, + 0, 0, 0, 0, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 61, 30, 0, 0, 8, 130, 0, 16, + 0, 2, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 2, 0, 0, 0, 1, 64, + 0, 0, 187, 126, 240, 126, 56, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 0, 0, 0, 8, + 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 5, 0, 0, + 0, 58, 0, 16, 0, 6, 0, 0, 0, 0, 0, 0, 7, 130, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 61, 30, + 0, 0, 8, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, + 4, 0, 0, 0, 1, 64, 0, 0, 187, 126, 240, 126, 56, 0, 0, 7, 130, 0, 16, + 0, 5, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, + 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, + 12, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, + 0, 56, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 3, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, + 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 50, 0, 0, 9, + 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 50, 0, 0, 9, 130, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 66, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 58, + 0, 16, 0, 1, 0, 0, 0, 0, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, 50, 0, 0, + 9, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 64, 58, 0, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 130, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 64, 58, 0, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 64, 58, 0, 16, 0, 1, 0, 0, 0, 0, 0, 0, 7, 130, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 0, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 0, 0, 0, 7, 130, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 0, + 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 8, 130, 0, 16, 0, 2, 0, 0, + 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 255, 159, + 241, 126, 50, 0, 0, 10, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 128, 65, + 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 64, 56, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 56, 0, 0, 7, 114, 0, + 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 246, 15, 16, 0, 6, + 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, + 3, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, + 0, 50, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 6, 0, + 0, 0, 246, 15, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 50, + 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, + 246, 15, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 50, 0, 0, + 9, 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 246, 15, + 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 50, 0, 0, 9, 114, + 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 246, 15, 16, 0, + 3, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, + 0, 2, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 246, 15, 16, 0, 5, 0, + 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 1, + 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 5, 0, 0, 0, + 70, 2, 16, 0, 2, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 1, 0, 0, + 0, 70, 2, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 1, 0, 0, 0, 70, + 2, 16, 0, 5, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, + 1, 0, 0, 0, 50, 0, 0, 9, 226, 0, 16, 0, 0, 0, 0, 0, 6, 9, 16, + 0, 10, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 6, 9, 16, 0, 1, 0, + 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 12, + 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 150, 7, 16, 0, 0, 0, 0, 0, + 56, 32, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 75, 0, 0, 5, 114, 32, 16, 0, 0, 0, + 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, + 148, 0, 0, 0, 172, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 114, 0, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_cas_sharpen_dither_ps.h b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_cas_sharpen_dither_ps.h new file mode 100644 index 0000000..b402745 --- /dev/null +++ b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_cas_sharpen_dither_ps.h @@ -0,0 +1,703 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// int2 xe_cas_output_offset; // Offset: 0 Size: 8 +// float xe_cas_sharpness_post_setup; // Offset: 8 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_cas_source texture float4 2d T0 t0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// +ps_5_1 +dcl_globalFlags refactoringAllowed +dcl_immediateConstantBuffer { { -0.001003, 0, 0, 0}, + { 0.000881, 0, 0, 0}, + { 0.001693, 0, 0, 0}, + { -0.001555, 0, 0, 0}, + { 0.001279, 0, 0, 0}, + { -0.000605, 0, 0, 0}, + { 0.001065, 0, 0, 0}, + { -0.001386, 0, 0, 0}, + { 0.001356, 0, 0, 0}, + { 0.000513, 0, 0, 0}, + { 0.001218, 0, 0, 0}, + { -0.001601, 0, 0, 0}, + { 0.000590, 0, 0, 0}, + { -0.000283, 0, 0, 0}, + { 0.001111, 0, 0, 0}, + { -0.001417, 0, 0, 0}, + { 0.001448, 0, 0, 0}, + { -0.000544, 0, 0, 0}, + { 0.000130, 0, 0, 0}, + { -0.001203, 0, 0, 0}, + { 0.000437, 0, 0, 0}, + { -0.001049, 0, 0, 0}, + { 0.000620, 0, 0, 0}, + { -0.000483, 0, 0, 0}, + { 0.001877, 0, 0, 0}, + { -0.001095, 0, 0, 0}, + { -0.000100, 0, 0, 0}, + { -0.000528, 0, 0, 0}, + { 0.001432, 0, 0, 0}, + { -0.001938, 0, 0, 0}, + { -0.000697, 0, 0, 0}, + { 0.000038, 0, 0, 0}, + { 0.000712, 0, 0, 0}, + { -0.001310, 0, 0, 0}, + { 0.001095, 0, 0, 0}, + { -0.000299, 0, 0, 0}, + { 0.001754, 0, 0, 0}, + { -0.001677, 0, 0, 0}, + { 0.001478, 0, 0, 0}, + { -0.000038, 0, 0, 0}, + { 0.000789, 0, 0, 0}, + { -0.001831, 0, 0, 0}, + { 0.000299, 0, 0, 0}, + { 0.000988, 0, 0, 0}, + { -0.001172, 0, 0, 0}, + { 0.000176, 0, 0, 0}, + { 0.001647, 0, 0, 0}, + { -0.001585, 0, 0, 0}, + { 0.000345, 0, 0, 0}, + { 0.001861, 0, 0, 0}, + { -0.001769, 0, 0, 0}, + { -0.000866, 0, 0, 0}, + { 0.000896, 0, 0, 0}, + { 0.000161, 0, 0, 0}, + { -0.000927, 0, 0, 0}, + { -0.001524, 0, 0, 0}, + { -0.000651, 0, 0, 0}, + { 0.001294, 0, 0, 0}, + { -0.000804, 0, 0, 0}, + { -0.001463, 0, 0, 0}, + { 0.001800, 0, 0, 0}, + { -0.000850, 0, 0, 0}, + { 0.000850, 0, 0, 0}, + { -0.000452, 0, 0, 0}, + { -0.001065, 0, 0, 0}, + { -0.000146, 0, 0, 0}, + { 0.000237, 0, 0, 0}, + { 0.001417, 0, 0, 0}, + { -0.000590, 0, 0, 0}, + { -0.000191, 0, 0, 0}, + { 0.001601, 0, 0, 0}, + { 0.001019, 0, 0, 0}, + { 0.000406, 0, 0, 0}, + { -0.000207, 0, 0, 0}, + { 0.001585, 0, 0, 0}, + { 0.000651, 0, 0, 0}, + { -0.000069, 0, 0, 0}, + { 0.000421, 0, 0, 0}, + { -0.001647, 0, 0, 0}, + { 0.001371, 0, 0, 0}, + { 0.000927, 0, 0, 0}, + { -0.000666, 0, 0, 0}, + { 0.001187, 0, 0, 0}, + { -0.001448, 0, 0, 0}, + { 0.000574, 0, 0, 0}, + { -0.001892, 0, 0, 0}, + { 0.000758, 0, 0, 0}, + { -0.001294, 0, 0, 0}, + { 0.001922, 0, 0, 0}, + { -0.001662, 0, 0, 0}, + { -0.001034, 0, 0, 0}, + { -0.000498, 0, 0, 0}, + { -0.001861, 0, 0, 0}, + { 0.001203, 0, 0, 0}, + { -0.000329, 0, 0, 0}, + { -0.001371, 0, 0, 0}, + { 0.001631, 0, 0, 0}, + { -0.001846, 0, 0, 0}, + { 0.000728, 0, 0, 0}, + { -0.000911, 0, 0, 0}, + { 0.001815, 0, 0, 0}, + { -0.001141, 0, 0, 0}, + { -0.000375, 0, 0, 0}, + { 0.000100, 0, 0, 0}, + { -0.000743, 0, 0, 0}, + { 0.001172, 0, 0, 0}, + { 0.000069, 0, 0, 0}, + { 0.001494, 0, 0, 0}, + { 0.000973, 0, 0, 0}, + { -0.000957, 0, 0, 0}, + { 0.001938, 0, 0, 0}, + { 0.000528, 0, 0, 0}, + { 0.000054, 0, 0, 0}, + { -0.001248, 0, 0, 0}, + { -0.000268, 0, 0, 0}, + { 0.001540, 0, 0, 0}, + { -0.000008, 0, 0, 0}, + { 0.000314, 0, 0, 0}, + { 0.001340, 0, 0, 0}, + { -0.001754, 0, 0, 0}, + { 0.000498, 0, 0, 0}, + { -0.001187, 0, 0, 0}, + { 0.000774, 0, 0, 0}, + { -0.001340, 0, 0, 0}, + { 0.000268, 0, 0, 0}, + { -0.001478, 0, 0, 0}, + { -0.000130, 0, 0, 0}, + { -0.000774, 0, 0, 0}, + { 0.001310, 0, 0, 0}, + { 0.000391, 0, 0, 0}, + { 0.000957, 0, 0, 0}, + { -0.000467, 0, 0, 0}, + { -0.001540, 0, 0, 0}, + { 0.001034, 0, 0, 0}, + { -0.000682, 0, 0, 0}, + { 0.001677, 0, 0, 0}, + { 0.001003, 0, 0, 0}, + { -0.000421, 0, 0, 0}, + { 0.001785, 0, 0, 0}, + { -0.000237, 0, 0, 0}, + { -0.000620, 0, 0, 0}, + { 0.001662, 0, 0, 0}, + { 0.000835, 0, 0, 0}, + { -0.001723, 0, 0, 0}, + { -0.001080, 0, 0, 0}, + { 0.001769, 0, 0, 0}, + { -0.000789, 0, 0, 0}, + { -0.001785, 0, 0, 0}, + { 0.000682, 0, 0, 0}, + { -0.000988, 0, 0, 0}, + { -0.001325, 0, 0, 0}, + { -0.000176, 0, 0, 0}, + { -0.001509, 0, 0, 0}, + { 0.000329, 0, 0, 0}, + { -0.001953, 0, 0, 0}, + { 0.000666, 0, 0, 0}, + { -0.001616, 0, 0, 0}, + { 0.001157, 0, 0, 0}, + { 0.000452, 0, 0, 0}, + { -0.000437, 0, 0, 0}, + { 0.000191, 0, 0, 0}, + { -0.001494, 0, 0, 0}, + { 0.001141, 0, 0, 0}, + { 0.000084, 0, 0, 0}, + { 0.001892, 0, 0, 0}, + { 0.001402, 0, 0, 0}, + { 0.000559, 0, 0, 0}, + { 0.000115, 0, 0, 0}, + { 0.001264, 0, 0, 0}, + { -0.000574, 0, 0, 0}, + { -0.000973, 0, 0, 0}, + { 0.001325, 0, 0, 0}, + { 0.000222, 0, 0, 0}, + { -0.000758, 0, 0, 0}, + { -0.001356, 0, 0, 0}, + { 0.001463, 0, 0, 0}, + { 0.000866, 0, 0, 0}, + { -0.000360, 0, 0, 0}, + { 0.000544, 0, 0, 0}, + { -0.001126, 0, 0, 0}, + { -0.000253, 0, 0, 0}, + { -0.000559, 0, 0, 0}, + { -0.001815, 0, 0, 0}, + { 0.001723, 0, 0, 0}, + { -0.001157, 0, 0, 0}, + { 0.000743, 0, 0, 0}, + { 0.001570, 0, 0, 0}, + { -0.000115, 0, 0, 0}, + { -0.001218, 0, 0, 0}, + { 0.001831, 0, 0, 0}, + { 0.000023, 0, 0, 0}, + { -0.001922, 0, 0, 0}, + { 0.001739, 0, 0, 0}, + { -0.000712, 0, 0, 0}, + { 0.001555, 0, 0, 0}, + { -0.001708, 0, 0, 0}, + { 0.001233, 0, 0, 0}, + { 0.000207, 0, 0, 0}, + { 0.001049, 0, 0, 0}, + { -0.000728, 0, 0, 0}, + { -0.001631, 0, 0, 0}, + { -0.000314, 0, 0, 0}, + { 0.000483, 0, 0, 0}, + { -0.001800, 0, 0, 0}, + { 0.000942, 0, 0, 0}, + { -0.000345, 0, 0, 0}, + { 0.000697, 0, 0, 0}, + { -0.001019, 0, 0, 0}, + { -0.001570, 0, 0, 0}, + { -0.000023, 0, 0, 0}, + { -0.001279, 0, 0, 0}, + { 0.000804, 0, 0, 0}, + { -0.000896, 0, 0, 0}, + { -0.001432, 0, 0, 0}, + { 0.000605, 0, 0, 0}, + { -0.000084, 0, 0, 0}, + { 0.000911, 0, 0, 0}, + { 0.001953, 0, 0, 0}, + { -0.001402, 0, 0, 0}, + { -0.000636, 0, 0, 0}, + { 0.001509, 0, 0, 0}, + { -0.000820, 0, 0, 0}, + { 0.001248, 0, 0, 0}, + { 0.000253, 0, 0, 0}, + { 0.001524, 0, 0, 0}, + { 0.001126, 0, 0, 0}, + { 0.000360, 0, 0, 0}, + { -0.000391, 0, 0, 0}, + { 0.001907, 0, 0, 0}, + { 0.001386, 0, 0, 0}, + { -0.001111, 0, 0, 0}, + { 0.001616, 0, 0, 0}, + { -0.000881, 0, 0, 0}, + { 0.000146, 0, 0, 0}, + { 0.001080, 0, 0, 0}, + { -0.000054, 0, 0, 0}, + { 0.000283, 0, 0, 0}, + { -0.001693, 0, 0, 0}, + { -0.001264, 0, 0, 0}, + { -0.000513, 0, 0, 0}, + { -0.000161, 0, 0, 0}, + { -0.001877, 0, 0, 0}, + { -0.000835, 0, 0, 0}, + { 0.000636, 0, 0, 0}, + { 0.000008, 0, 0, 0}, + { -0.001907, 0, 0, 0}, + { -0.000222, 0, 0, 0}, + { 0.000375, 0, 0, 0}, + { -0.001739, 0, 0, 0}, + { -0.000406, 0, 0, 0}, + { -0.001233, 0, 0, 0}, + { 0.001708, 0, 0, 0}, + { -0.000942, 0, 0, 0}, + { 0.000820, 0, 0, 0}, + { 0.001846, 0, 0, 0}, + { 0.000467, 0, 0, 0} } +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_texture2d (float,float,float,float) T0[0:0], space=0 +dcl_input_ps_siv linear noperspective v0.xy, position +dcl_output o0.xyzw +dcl_temps 6 +ftoi r0.xy, v0.xyxx +iadd r0.xy, r0.xyxx, -CB0[0][0].xyxx +iadd r1.xyzw, r0.xyxy, l(-1, 0, 0, -1) +mov r2.xy, r1.zwzz +mov r2.zw, l(0,0,0,0) +ld r2.xyz, r2.xyzw, T0[0].xyzw +mov r1.zw, l(0,0,0,0) +ld r1.xyz, r1.xyzw, T0[0].xyzw +mov r0.zw, l(0,0,0,0) +ld r3.xyz, r0.xyzw, T0[0].xyzw +iadd r4.xyzw, r0.xyxy, l(0, 1, 1, 0) +mov r5.xy, r4.zwzz +mov r5.zw, l(0,0,0,0) +ld r5.xyz, r5.xyzw, T0[0].xyzw +mov r4.zw, l(0,0,0,0) +ld r4.xyz, r4.xyzw, T0[0].xyzw +mul r2.xyz, r2.xyzx, r2.xyzx +mul r1.xyz, r1.xyzx, r1.xyzx +mul r0.z, r3.y, r3.y +mul r5.xyz, r5.xyzx, r5.xyzx +mul r4.xyz, r4.xyzx, r4.xyzx +min r0.w, r0.z, r5.y +min r0.w, r0.w, r1.y +min r1.w, r2.y, r4.y +min r0.w, r0.w, r1.w +max r0.z, r0.z, r5.y +max r0.z, r0.z, r1.y +max r1.w, r2.y, r4.y +max r0.z, r0.z, r1.w +iadd r1.w, -r0.z, l(0x7ef07ebb) +add r0.z, -r0.z, l(1.000000) +min r0.z, r0.z, r0.w +mul_sat r0.z, r1.w, r0.z +ushr r0.z, r0.z, l(1) +iadd r0.z, r0.z, l(0x1fbc4639) +mul r0.z, r0.z, CB0[0][0].z +mad r0.w, r0.z, l(4.000000), l(1.000000) +iadd r1.w, -r0.w, l(0x7ef19fff) +mad r0.w, -r1.w, r0.w, l(2.000000) +mul r0.w, r0.w, r1.w +mul r1.xyz, r0.zzzz, r1.xyzx +mad r1.xyz, r2.xyzx, r0.zzzz, r1.xyzx +mad r1.xyz, r5.xyzx, r0.zzzz, r1.xyzx +mad r1.xyz, r4.xyzx, r0.zzzz, r1.xyzx +mad r1.xyz, r3.xyzx, r3.xyzx, r1.xyzx +mul_sat r1.xyz, r0.wwww, r1.xyzx +sqrt r1.xyz, r1.xyzx +bfi r0.y, l(4), l(4), r0.y, l(0) +bfi r0.x, l(4), l(0), r0.x, r0.y +add_sat o0.xyz, r1.xyzx, icb[r0.x + 0].xxxx +mov o0.w, l(1.000000) +ret +// Approximately 52 instruction slots used +#endif + +const BYTE guest_output_ffx_cas_sharpen_dither_ps[] = { + 68, 88, 66, 67, 255, 119, 136, 143, 9, 220, 108, 33, 44, 141, 124, 0, 167, 19, 114, + 121, 1, 0, 0, 0, 164, 25, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 0, 2, + 0, 0, 52, 2, 0, 0, 104, 2, 0, 0, 8, 25, 0, 0, 82, 68, 69, 70, 196, + 1, 0, 0, 1, 0, 0, 0, 172, 0, 0, 0, 2, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 255, 255, 0, 5, 0, 0, 156, 1, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 99, 97, 115, 95, 115, 111, + 117, 114, 99, 101, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, + 0, 171, 171, 171, 154, 0, 0, 0, 2, 0, 0, 0, 196, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 2, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 84, 1, 0, 0, 8, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, 99, 97, 115, + 95, 111, 117, 116, 112, 117, 116, 95, 111, 102, 102, 115, 101, 116, 0, 105, 110, 116, 50, + 0, 171, 171, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 1, 0, + 0, 120, 101, 95, 99, 97, 115, 95, 115, 104, 97, 114, 112, 110, 101, 115, 115, 95, 112, + 111, 115, 116, 95, 115, 101, 116, 117, 112, 0, 102, 108, 111, 97, 116, 0, 171, 171, 0, + 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 1, 0, 0, 77, 105, 99, + 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, + 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, + 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 3, 0, + 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 79, 83, 71, 78, 44, 0, + 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, + 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 69, 88, 152, 22, 0, 0, 81, 0, 0, + 0, 166, 5, 0, 0, 106, 8, 0, 1, 53, 24, 0, 0, 2, 4, 0, 0, 132, 131, + 131, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 231, 230, 102, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, 221, 221, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 204, 203, 203, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 168, 167, 167, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 159, 158, 30, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, + 139, 139, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, 181, 181, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 178, 177, 177, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 134, 6, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 160, 159, 159, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 210, 209, 209, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 155, 154, 26, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 149, 148, 148, + 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 145, 145, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 185, 185, 186, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 190, 189, 189, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 143, 142, 14, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 137, 136, 8, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 158, 157, + 157, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, 228, 228, 57, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 137, 137, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 163, 162, 34, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 253, 252, 252, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 246, 245, 245, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, + 143, 143, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 209, 208, 208, 184, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 138, 10, 186, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 188, 187, 187, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 254, 253, 253, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 183, 182, 54, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 161, 160, 32, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, 186, 58, + 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 171, 171, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 143, 143, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 157, 156, 156, 185, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 230, 229, 229, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 220, 219, 219, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 193, + 193, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 161, 160, 32, 184, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 207, 206, 78, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 240, 239, 239, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 157, 156, 156, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 130, 129, 129, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, + 153, 153, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 185, 184, 56, 57, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 216, 215, 215, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 208, 207, 207, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 181, 180, 180, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 244, 243, 243, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 232, 231, 231, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 227, 226, 98, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 235, 234, 106, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 169, 168, 40, 57, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 243, 242, 114, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 200, 199, 199, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 171, 170, 42, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 169, + 169, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 211, 210, 82, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 191, 191, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 236, 235, 235, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 223, 222, 94, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 223, 222, 94, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, + 236, 236, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 139, 139, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 152, 24, 185, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 248, 120, 57, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 186, 185, 185, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 155, 154, 26, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 201, 200, 72, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 209, 209, + 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 133, 133, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 212, 212, 57, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 217, 216, 88, 185, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 208, 207, 207, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 171, 170, 42, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 144, + 144, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 220, 220, 57, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 216, 215, 215, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 180, 179, 179, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 243, 242, 114, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 175, 174, 46, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, + 155, 155, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 190, 189, 189, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151, 150, 22, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 247, 247, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 199, 198, 70, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 170, 169, 169, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 252, 251, 251, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 218, 217, 217, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 135, 135, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 130, 2, 186, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 244, 243, 243, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 158, 157, 157, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 173, 172, 172, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 179, + 179, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 213, 213, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 242, 241, 241, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 191, 190, 62, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 239, 238, 110, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 238, 237, 237, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, + 149, 149, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 197, 196, 196, 185, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 209, 208, 208, 56, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 194, 66, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 154, 153, 153, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 145, 144, 144, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 196, 195, 195, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 254, 126, + 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 251, 250, 122, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 253, 253, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 139, 138, 10, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 225, 224, 96, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 164, 163, 163, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, 140, + 140, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 201, 201, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 128, 0, 183, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 165, 164, 164, 57, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 176, 175, 175, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 230, 229, 229, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, + 130, 2, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 155, 155, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 203, 202, 74, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 176, 175, 175, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 141, 140, 140, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 194, 193, 193, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 137, 136, 8, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 203, 202, 74, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 171, 171, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 205, 204, 204, 57, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 251, 250, 122, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 245, 244, 244, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 202, 201, 201, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 135, + 135, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 179, 178, 50, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 219, 219, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 132, 131, 131, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 221, 220, 220, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 234, 233, 233, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, + 248, 120, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 162, 34, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 218, 217, 217, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 219, 218, 90, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 226, 225, 225, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 142, 141, 141, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 232, 231, 231, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 207, 206, 78, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 233, 233, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 179, 178, 50, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 130, 129, 129, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 174, 173, 173, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 185, 184, 56, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 197, + 197, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, 172, 172, 57, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 175, 174, 46, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 212, 211, 211, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 152, 151, 151, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, + 236, 236, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, 228, 228, 185, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 200, 72, 57, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 195, 195, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 150, 149, 149, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 177, 176, 176, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 248, 247, 247, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 184, 183, 183, + 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, 146, 18, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 241, 240, 240, 56, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 166, 165, 165, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 151, 150, 22, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 255, 254, 126, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 173, + 173, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 232, 104, 57, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 199, 198, 70, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 178, 177, 177, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 192, 191, 191, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 227, 226, 98, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, + 188, 188, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 142, 14, 58, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 147, 147, 186, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 132, 132, 185, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 147, 146, 18, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 238, 237, 237, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 226, 225, 225, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 152, 151, 151, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 194, 66, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 205, 205, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 241, 240, 240, 184, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 160, 159, 159, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 240, 239, 239, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 193, 192, + 192, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 251, 251, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 227, 227, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 187, 186, 58, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 204, 203, 203, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 224, 223, 223, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, + 161, 161, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217, 216, 88, 57, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 137, 137, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 190, 62, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 214, 213, 213, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 165, 164, 164, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 253, 252, 252, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 236, 235, 235, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 247, 246, 118, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181, 180, 180, 185, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 183, 182, 54, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 134, 133, 133, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 206, 205, 205, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 193, 192, + 192, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 167, 167, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 211, 210, 82, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 235, 234, 106, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 188, 187, 187, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 159, 158, 30, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, + 176, 176, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, 238, 110, 58, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 184, 183, 183, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 167, 166, 38, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 198, 197, 197, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 215, 214, 86, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 163, 163, + 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 132, 132, 57, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 199, 199, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 148, 147, 147, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 189, 188, 188, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 205, 204, 204, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 249, + 249, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, 181, 181, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 145, 145, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 212, 211, 211, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 231, 230, 102, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 153, 152, 24, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, + 141, 141, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225, 224, 96, 184, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 149, 148, 148, 57, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, 221, 221, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 166, 165, 165, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 135, 134, 6, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 169, 168, 40, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 245, 245, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 219, 218, 90, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 167, 166, 38, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 129, 128, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 250, 249, 249, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 233, 232, 104, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 197, 196, + 196, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 227, 227, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 212, 212, 185, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 162, 161, 161, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 224, 223, 223, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 247, 246, 118, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 215, + 214, 86, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 242, 241, 241, 58, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 244, 244, 57, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 88, + 24, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 85, 0, 0, 0, 0, 0, 0, 100, 32, 0, 4, 50, 16, 16, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 6, 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, + 16, 16, 0, 0, 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, 0, 0, 70, 128, 48, 128, 65, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 1, 0, + 0, 0, 70, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 54, 0, 0, 5, 50, 0, 16, 0, + 2, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, + 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 45, 0, 0, 8, 114, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, + 0, 16, 0, 4, 0, 0, 0, 70, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 50, 0, 16, 0, 5, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, + 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 4, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, + 0, 0, 8, 114, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, + 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, + 0, 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, + 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 1, + 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, + 0, 56, 0, 0, 7, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, + 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 4, + 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, + 51, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 5, 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 51, + 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 4, 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 52, 0, + 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 5, 0, 0, 0, 52, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 52, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 26, 0, + 16, 0, 4, 0, 0, 0, 52, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 8, + 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 187, 126, 240, 126, 0, 0, 0, 8, 66, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 128, 63, 51, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 56, 32, 0, 7, 66, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 57, 70, 188, + 31, 56, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, + 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 128, 64, 1, 64, 0, 0, 0, 0, 128, 63, 30, 0, 0, + 8, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 255, 159, 241, 126, 50, 0, 0, 10, 130, 0, 16, 0, 0, + 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 56, 0, 0, 7, 130, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, + 1, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 1, 0, + 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 1, 0, 0, 0, + 70, 2, 16, 0, 4, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 2, 16, + 0, 1, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 1, 0, 0, 0, 70, 2, + 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 1, + 0, 0, 0, 56, 32, 0, 7, 114, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 75, 0, 0, 5, 114, 0, 16, + 0, 1, 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 140, 0, 0, 11, 34, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, 0, 32, 0, 8, 114, 32, 16, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 1, 0, 0, 0, 6, 144, 144, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, + 63, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 52, 0, 0, 0, 6, 0, + 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 6, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_cas_sharpen_ps.h b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_cas_sharpen_ps.h new file mode 100644 index 0000000..8440642 --- /dev/null +++ b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_cas_sharpen_ps.h @@ -0,0 +1,222 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// int2 xe_cas_output_offset; // Offset: 0 Size: 8 +// float xe_cas_sharpness_post_setup; // Offset: 8 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_cas_source texture float4 2d T0 t0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// +ps_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_texture2d (float,float,float,float) T0[0:0], space=0 +dcl_input_ps_siv linear noperspective v0.xy, position +dcl_output o0.xyzw +dcl_temps 5 +ftoi r0.xy, v0.xyxx +iadd r0.xy, r0.xyxx, -CB0[0][0].xyxx +iadd r1.xyzw, r0.xyxy, l(-1, 0, 0, -1) +mov r2.xy, r1.zwzz +mov r2.zw, l(0,0,0,0) +ld r2.xyz, r2.xyzw, T0[0].xyzw +mov r1.zw, l(0,0,0,0) +ld r1.xyz, r1.xyzw, T0[0].xyzw +mov r0.zw, l(0,0,0,0) +ld r3.xyz, r0.xyzw, T0[0].xyzw +iadd r0.xyzw, r0.xyxy, l(0, 1, 1, 0) +mov r4.xy, r0.zwzz +mov r4.zw, l(0,0,0,0) +ld r4.xyz, r4.xyzw, T0[0].xyzw +mov r0.zw, l(0,0,0,0) +ld r0.xyz, r0.xyzw, T0[0].xyzw +mul r2.xyz, r2.xyzx, r2.xyzx +mul r1.xyz, r1.xyzx, r1.xyzx +mul r0.w, r3.y, r3.y +mul r4.xyz, r4.xyzx, r4.xyzx +mul r0.xyz, r0.xyzx, r0.xyzx +min r1.w, r0.w, r4.y +min r1.w, r1.w, r1.y +min r2.w, r0.y, r2.y +min r1.w, r1.w, r2.w +max r0.w, r0.w, r4.y +max r0.w, r0.w, r1.y +max r2.w, r0.y, r2.y +max r0.w, r0.w, r2.w +iadd r2.w, -r0.w, l(0x7ef07ebb) +add r0.w, -r0.w, l(1.000000) +min r0.w, r0.w, r1.w +mul_sat r0.w, r2.w, r0.w +ushr r0.w, r0.w, l(1) +iadd r0.w, r0.w, l(0x1fbc4639) +mul r0.w, r0.w, CB0[0][0].z +mad r1.w, r0.w, l(4.000000), l(1.000000) +iadd r2.w, -r1.w, l(0x7ef19fff) +mad r1.w, -r2.w, r1.w, l(2.000000) +mul r1.w, r1.w, r2.w +mul r1.xyz, r0.wwww, r1.xyzx +mad r1.xyz, r2.xyzx, r0.wwww, r1.xyzx +mad r1.xyz, r4.xyzx, r0.wwww, r1.xyzx +mad r0.xyz, r0.xyzx, r0.wwww, r1.xyzx +mad r0.xyz, r3.xyzx, r3.xyzx, r0.xyzx +mul_sat r0.xyz, r1.wwww, r0.xyzx +sqrt o0.xyz, r0.xyzx +mov o0.w, l(1.000000) +ret +// Approximately 49 instruction slots used +#endif + +const BYTE guest_output_ffx_cas_sharpen_ps[] = { + 68, 88, 66, 67, 166, 66, 169, 116, 206, 31, 71, 185, 60, 220, 203, 253, 75, 208, 107, + 220, 1, 0, 0, 0, 36, 9, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 0, 2, + 0, 0, 52, 2, 0, 0, 104, 2, 0, 0, 136, 8, 0, 0, 82, 68, 69, 70, 196, + 1, 0, 0, 1, 0, 0, 0, 172, 0, 0, 0, 2, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 255, 255, 0, 5, 0, 0, 156, 1, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 99, 97, 115, 95, 115, 111, + 117, 114, 99, 101, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, 95, 120, 101, + 0, 171, 171, 171, 154, 0, 0, 0, 2, 0, 0, 0, 196, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 2, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 84, 1, 0, 0, 8, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 0, 0, 120, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, 99, 97, 115, + 95, 111, 117, 116, 112, 117, 116, 95, 111, 102, 102, 115, 101, 116, 0, 105, 110, 116, 50, + 0, 171, 171, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 1, 0, + 0, 120, 101, 95, 99, 97, 115, 95, 115, 104, 97, 114, 112, 110, 101, 115, 115, 95, 112, + 111, 115, 116, 95, 115, 101, 116, 117, 112, 0, 102, 108, 111, 97, 116, 0, 171, 171, 0, + 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 1, 0, 0, 77, 105, 99, + 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, + 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, + 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 3, 0, + 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 79, 83, 71, 78, 44, 0, + 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, + 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 69, 88, 24, 6, 0, 0, 81, 0, 0, + 0, 134, 1, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 88, + 24, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 85, 0, 0, 0, 0, 0, 0, 100, 32, 0, 4, 50, 16, 16, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, + 0, 2, 5, 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, + 16, 16, 0, 0, 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, 0, 0, 70, 128, 48, 128, 65, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 1, 0, + 0, 0, 70, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 0, + 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 54, 0, 0, 5, 50, 0, 16, 0, + 2, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 2, 0, 0, 0, 70, + 14, 16, 0, 2, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, + 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 45, 0, 0, 8, 114, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 0, 0, + 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, + 0, 16, 0, 0, 0, 0, 0, 70, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 50, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, + 0, 0, 8, 114, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, + 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, + 0, 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, + 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 1, + 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, + 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, + 0, 56, 0, 0, 7, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, + 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, + 51, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 4, 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 51, + 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 2, 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 52, 0, + 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, + 0, 16, 0, 4, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 52, 0, 0, + 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, + 16, 0, 2, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 8, + 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 187, 126, 240, 126, 0, 0, 0, 8, 130, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 128, 63, 51, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 56, 32, 0, 7, 130, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, + 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 57, 70, 188, + 31, 56, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, + 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, + 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, 128, 64, 1, 64, 0, 0, 0, 0, 128, 63, 30, 0, 0, + 8, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 255, 159, 241, 126, 50, 0, 0, 10, 130, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 56, 0, 0, 7, 130, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, + 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, + 1, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 1, 0, + 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, + 2, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, + 0, 1, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, + 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 0, + 0, 0, 0, 56, 32, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, + 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 75, 0, 0, 5, 114, 32, 16, + 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, + 84, 65, 84, 148, 0, 0, 0, 49, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 27, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0}; diff --git a/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_fsr_easu_ps.h b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_fsr_easu_ps.h new file mode 100644 index 0000000..48e64b0 --- /dev/null +++ b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_fsr_easu_ps.h @@ -0,0 +1,902 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// float2 xe_fsr_easu_input_output_size_ratio;// Offset: 0 Size: 8 +// float2 xe_fsr_easu_input_size_inv; // Offset: 8 Size: 8 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_fsr_easu_sampler sampler NA NA S0 s0 1 +// xe_fsr_easu_source texture float4 2d T0 t0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// +ps_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_sampler S0[0:0], mode_default, space=0 +dcl_resource_texture2d (float,float,float,float) T0[0:0], space=0 +dcl_input_ps_siv linear noperspective v0.xy, position +dcl_output o0.xyzw +dcl_temps 22 +mul r0.w, l(4.000000), CB0[0][0].w +mad r0.xy, CB0[0][0].xyxx, l(0.500000, 0.500000, 0.000000, 0.000000), l(-0.500000, -0.500000, 0.000000, 0.000000) +mul r1.xyz, l(1.000000, 1.000000, -1.000000, 0.000000), CB0[0][0].zwwz +ftou r2.xy, v0.xyxx +utof r2.xy, r2.xyxx +mad r0.xy, r2.xyxx, CB0[0][0].xyxx, r0.xyxx +round_ni r2.xy, r0.xyxx +add r0.xy, r0.xyxx, -r2.xyxx +mad r1.xy, r2.xyxx, r1.xyxx, r1.xzxx +mad r2.xyzw, CB0[0][0].zwzw, l(-1.000000, 2.000000, 1.000000, 2.000000), r1.xyxy +mov r0.z, l(0) +add r0.zw, r0.zzzw, r1.xxxy +gather4 r1.zw, r1.xyxx, T0[0].zwxy, S0[0].x +gather4 r3.xy, r1.xyxx, T0[0].xyzw, S0[0].y +gather4 r4.xz, r1.xyxx, T0[0].xzyw, S0[0].z +gather4 r5.xyzw, r2.xyxx, T0[0].xyzw, S0[0].x +gather4 r6.xyzw, r2.xyxx, T0[0].xyzw, S0[0].y +gather4 r7.xyzw, r2.xyxx, T0[0].yzxw, S0[0].z +gather4 r8.xyzw, r2.zwzz, T0[0].xyzw, S0[0].x +gather4 r9.xyzw, r2.zwzz, T0[0].xyzw, S0[0].y +gather4 r2.xyzw, r2.zwzz, T0[0].xyzw, S0[0].z +gather4 r1.xy, r0.zwzz, T0[0].zwxy, S0[0].x +gather4 r3.zw, r0.zwzz, T0[0].xyzw, S0[0].y +gather4 r10.zw, r0.zwzz, T0[0].xyzw, S0[0].z +mad r0.zw, r1.zzzw, l(0.000000, 0.000000, 0.500000, 0.500000), r3.xxxy +mad r0.zw, r4.xxxz, l(0.000000, 0.000000, 0.500000, 0.500000), r0.zzzw +mad r11.xyzw, r5.zwyx, l(0.500000, 0.500000, 0.500000, 0.500000), r6.zwyx +mad r11.xyzw, r7.ywxz, l(0.500000, 0.500000, 0.500000, 0.500000), r11.xyzw +mad r12.xyzw, r8.xyzw, l(0.500000, 0.500000, 0.500000, 0.500000), r9.xyzw +mad r12.xyzw, r2.xyzw, l(0.500000, 0.500000, 0.500000, 0.500000), r12.xyzw +mad r13.xy, r1.xyxx, l(0.500000, 0.500000, 0.000000, 0.000000), r3.zwzz +mad r13.xy, r10.zwzz, l(0.500000, 0.500000, 0.000000, 0.000000), r13.xyxx +add r14.xyzw, -r0.xyxy, l(1.000000, 1.000000, 0.000000, -1.000000) +mul r4.w, r14.y, r14.x +add r15.xyzw, -r11.xyxz, r12.wwzx +add r16.xyz, -r11.yxwy, r11.xzzx +max r13.zw, |r15.xxxw|, |r16.xxxz| +iadd r13.zw, -r13.zzzw, l(0, 0, 0x7ef07ebb, 0x7ef07ebb) +mul_sat r11.y, r13.z, |r15.y| +mul r11.y, r11.y, r11.y +add r16.xz, -r0.zzzz, r11.xxzx +max r0.z, |r16.x|, |r16.y| +iadd r0.z, -r0.z, l(0x7ef07ebb) +mul_sat r0.z, r0.z, |r16.z| +mul r0.z, r0.z, r0.z +mul r0.z, r4.w, r0.z +mad r0.z, r11.y, r4.w, r0.z +mul r14.xy, r0.xyxx, r14.yxyy +add r17.xyz, -r12.wwxw, r12.zxyz +max r15.xw, |r15.xxxw|, |r17.xxxz| +iadd r15.xw, -r15.xxxw, l(0x7ef07ebb, 0, 0, 0x7ef07ebb) +mul r11.y, r14.x, r15.z +mad r11.y, r15.y, r4.w, r11.y +mul_sat r12.z, r15.x, |r15.z| +mul r12.z, r12.z, r12.z +mad r0.z, r12.z, r14.x, r0.z +add r15.xy, -r0.wwww, r12.wxww +max r0.w, |r15.x|, |r17.y| +iadd r0.w, -r0.w, l(0x7ef07ebb) +mul r12.z, r14.x, r15.y +mad r4.w, r16.z, r4.w, r12.z +mul_sat r0.w, r0.w, |r15.y| +mul r0.w, r0.w, r0.w +mad r0.z, r0.w, r14.x, r0.z +add r12.yz, -r11.wwzw, r12.xxyx +mad r0.w, r12.y, r14.y, r11.y +mul_sat r11.y, r13.w, |r12.y| +mul r11.y, r11.y, r11.y +mad r0.z, r11.y, r14.y, r0.z +add r11.xy, -r11.zxzz, r13.yyyy +max r11.x, |r16.y|, |r11.x| +iadd r11.x, -r11.x, l(0x7ef07ebb) +mad r4.w, r11.y, r14.y, r4.w +mul_sat r11.x, r11.x, |r11.y| +mul r11.x, r11.x, r11.x +mad r0.z, r11.x, r14.y, r0.z +mul r11.x, r0.y, r0.x +mad r15.y, r12.z, r11.x, r0.w +mul_sat r0.w, r15.w, |r12.z| +mul r0.w, r0.w, r0.w +mad r0.z, r0.w, r11.x, r0.z +add r11.yz, -r12.xxwx, r13.xxxx +max r0.w, |r17.y|, |r11.y| +iadd r0.w, -r0.w, l(0x7ef07ebb) +mad r15.z, r11.z, r11.x, r4.w +mul_sat r0.w, r0.w, |r11.z| +mul r0.w, r0.w, r0.w +mad r0.z, r0.w, r11.x, r0.z +mul r11.xy, r15.yzyy, r15.yzyy +add r0.w, r11.y, r11.x +lt r4.w, r0.w, l(0.000031) +ushr r0.w, r0.w, l(1) +iadd r0.w, -r0.w, l(0x5f347d74) +movc r0.w, r4.w, l(1.000000), r0.w +movc r15.x, r4.w, l(1.000000), r15.y +mul r11.xy, r0.wwww, r15.xzxx +mul r0.z, r0.z, l(0.500000) +mul r0.z, r0.z, r0.z +dp2 r0.w, r11.xyxx, r11.xyxx +max r4.w, |r11.y|, |r11.x| +iadd r4.w, -r4.w, l(0x7ef07ebb) +mad r0.w, r0.w, r4.w, l(-1.000000) +mad r12.x, r0.w, r0.z, l(1.000000) +mad r12.yz, r0.zzzz, l(0.000000, -0.500000, -0.290000, 0.000000), l(0.000000, 1.000000, 0.500000, 0.000000) +iadd r0.z, -r12.z, l(0x7ef07ebb) +mov r13.x, r8.w +mov r13.y, r9.w +mov r13.z, r2.w +mov r15.x, r5.y +mov r15.y, r6.y +mov r15.z, r7.x +min r16.xyz, r13.xyzx, r15.xyzx +mov r17.x, r5.z +mov r17.y, r6.z +mov r17.z, r7.y +min r16.xyz, r16.xyzx, r17.xyzx +mov r18.x, r8.x +mov r18.y, r9.x +mov r18.z, r2.x +min r16.xyz, r16.xyzx, r18.xyzx +max r19.xyz, r13.xyzx, r15.xyzx +max r19.xyz, r17.xyzx, r19.xyzx +max r19.xyz, r18.xyzx, r19.xyzx +dp2 r14.x, r14.zwzz, r11.xyxx +mul r0.w, r11.x, r14.w +mad r14.y, r14.z, -r11.y, r0.w +mul r5.yz, r12.xxyx, r14.xxyx +dp2 r0.w, r5.yzyy, r5.yzyy +min r0.w, r0.z, r0.w +mad r2.w, r0.w, l(0.400000), l(-1.000000) +mad r0.w, r12.z, r0.w, l(-1.000000) +mul r2.w, r2.w, r2.w +mul r0.w, r0.w, r0.w +mad r2.w, r2.w, l(1.562500), l(-0.562500) +mul r4.w, r0.w, r2.w +mov r14.x, r1.z +mov r14.y, r3.x +mov r14.z, r4.x +add r20.xyzw, -r0.xyxy, l(1.000000, -1.000000, -1.000000, 1.000000) +dp2 r21.y, r20.xyxx, r11.xyxx +mul r5.yz, r11.xxxx, r20.yywy +mad r21.zw, r20.xxxz, -r11.yyyy, r5.yyyz +mul r5.yz, r12.xxyx, r21.yyzy +dp2 r1.z, r5.yzyy, r5.yzyy +min r1.z, r0.z, r1.z +mad r3.x, r1.z, l(0.400000), l(-1.000000) +mad r1.z, r12.z, r1.z, l(-1.000000) +mul r3.x, r3.x, r3.x +mul r1.z, r1.z, r1.z +mad r3.x, r3.x, l(1.562500), l(-0.562500) +mul r1.z, r1.z, r3.x +mov r4.x, r1.w +mov r4.y, r3.y +mul r4.xyz, r1.zzzz, r4.xyzx +mad r4.xyz, r14.xyzx, r4.wwww, r4.xyzx +mad r0.w, r2.w, r0.w, r1.z +dp2 r21.x, r20.zwzz, r11.xyxx +mul r1.zw, r12.xxxy, r21.xxxw +dp2 r1.z, r1.zwzz, r1.zwzz +min r1.z, r0.z, r1.z +mad r1.w, r1.z, l(0.400000), l(-1.000000) +mad r1.z, r12.z, r1.z, l(-1.000000) +mul r1.zw, r1.zzzw, r1.zzzw +mad r1.w, r1.w, l(1.562500), l(-0.562500) +mul r2.w, r1.z, r1.w +mov r7.x, r5.x +mov r7.y, r6.x +mad r4.xyz, r7.xyzx, r2.wwww, r4.xyzx +mad r0.w, r1.w, r1.z, r0.w +add r14.xyzw, -r0.xyxy, l(0.000000, 1.000000, -1.000000, 0.000000) +dp2 r20.y, r14.xyxx, r11.xyxx +mul r1.zw, r11.xxxx, r14.yyyw +mad r20.zw, r14.xxxz, -r11.yyyy, r1.zzzw +mul r1.zw, r12.xxxy, r20.yyyz +dp2 r1.z, r1.zwzz, r1.zwzz +min r1.z, r0.z, r1.z +mad r1.w, r1.z, l(0.400000), l(-1.000000) +mad r1.z, r12.z, r1.z, l(-1.000000) +mul r1.zw, r1.zzzw, r1.zzzw +mad r1.w, r1.w, l(1.562500), l(-0.562500) +mul r2.w, r1.z, r1.w +mad r4.xyz, r15.xyzx, r2.wwww, r4.xyzx +mad r0.w, r1.w, r1.z, r0.w +dp2 r3.x, -r0.xyxx, r11.xyxx +mul r1.z, -r0.y, r11.x +mad r3.y, r0.x, r11.y, r1.z +mul r1.zw, r12.xxxy, r3.xxxy +dp2 r1.z, r1.zwzz, r1.zwzz +min r1.z, r0.z, r1.z +mad r1.w, r1.z, l(0.400000), l(-1.000000) +mad r1.z, r12.z, r1.z, l(-1.000000) +mul r1.zw, r1.zzzw, r1.zzzw +mad r1.w, r1.w, l(1.562500), l(-0.562500) +mul r2.w, r1.z, r1.w +mad r4.xyz, r17.xyzx, r2.wwww, r4.xyzx +mad r0.w, r1.w, r1.z, r0.w +dp2 r20.x, r14.zwzz, r11.xyxx +mul r1.zw, r12.xxxy, r20.xxxw +dp2 r1.z, r1.zwzz, r1.zwzz +min r1.z, r0.z, r1.z +mad r1.w, r1.z, l(0.400000), l(-1.000000) +mad r1.z, r12.z, r1.z, l(-1.000000) +mul r1.zw, r1.zzzw, r1.zzzw +mad r1.w, r1.w, l(1.562500), l(-0.562500) +mul r2.w, r1.z, r1.w +mov r7.z, r5.w +mov r7.x, r6.w +mad r4.xyz, r7.zxwz, r2.wwww, r4.xyzx +mad r0.w, r1.w, r1.z, r0.w +add r5.xyzw, -r0.xyxy, l(1.000000, 1.000000, 2.000000, 1.000000) +dp2 r6.y, r5.xyxx, r11.xyxx +mul r1.zw, r11.xxxx, r5.yyyw +mad r6.zw, r5.xxxz, -r11.yyyy, r1.zzzw +mul r1.zw, r12.xxxy, r6.yyyz +dp2 r1.z, r1.zwzz, r1.zwzz +min r1.z, r0.z, r1.z +mad r1.w, r1.z, l(0.400000), l(-1.000000) +mad r1.z, r12.z, r1.z, l(-1.000000) +mul r1.zw, r1.zzzw, r1.zzzw +mad r1.w, r1.w, l(1.562500), l(-0.562500) +mul r2.w, r1.z, r1.w +mad r4.xyz, r18.xyzx, r2.wwww, r4.xyzx +mad r0.w, r1.w, r1.z, r0.w +dp2 r6.x, r5.zwzz, r11.xyxx +mul r1.zw, r12.xxxy, r6.xxxw +dp2 r1.z, r1.zwzz, r1.zwzz +min r1.z, r0.z, r1.z +mad r1.w, r1.z, l(0.400000), l(-1.000000) +mad r1.z, r12.z, r1.z, l(-1.000000) +mul r1.zw, r1.zzzw, r1.zzzw +mad r1.w, r1.w, l(1.562500), l(-0.562500) +mul r2.w, r1.z, r1.w +mov r5.x, r8.y +mov r5.y, r9.y +mov r5.z, r2.y +mad r4.xyz, r5.xyzx, r2.wwww, r4.xyzx +mad r0.w, r1.w, r1.z, r0.w +add r5.xyzw, -r0.xyxy, l(2.000000, 0.000000, 1.000000, 0.000000) +dp2 r6.y, r5.xyxx, r11.xyxx +mul r1.zw, r11.xxxx, r5.yyyw +mad r6.zw, r5.xxxz, -r11.yyyy, r1.zzzw +mul r1.zw, r12.xxxy, r6.yyyz +dp2 r1.z, r1.zwzz, r1.zwzz +min r1.z, r0.z, r1.z +mad r1.w, r1.z, l(0.400000), l(-1.000000) +mad r1.z, r12.z, r1.z, l(-1.000000) +mul r1.zw, r1.zzzw, r1.zzzw +mad r1.w, r1.w, l(1.562500), l(-0.562500) +mul r2.w, r1.z, r1.w +mov r2.x, r8.z +mov r2.y, r9.z +mad r2.xyz, r2.xyzx, r2.wwww, r4.xyzx +mad r0.w, r1.w, r1.z, r0.w +dp2 r6.x, r5.zwzz, r11.xyxx +mul r1.zw, r12.xxxy, r6.xxxw +dp2 r1.z, r1.zwzz, r1.zwzz +min r1.z, r0.z, r1.z +mad r1.w, r1.z, l(0.400000), l(-1.000000) +mad r1.z, r12.z, r1.z, l(-1.000000) +mul r1.zw, r1.zzzw, r1.zzzw +mad r1.w, r1.w, l(1.562500), l(-0.562500) +mul r2.w, r1.z, r1.w +mad r2.xyz, r13.xyzx, r2.wwww, r2.xyzx +mad r0.w, r1.w, r1.z, r0.w +add r4.xyzw, -r0.xyxy, l(1.000000, 2.000000, 0.000000, 2.000000) +dp2 r5.y, r4.xyxx, r11.xyxx +mul r0.xy, r11.xxxx, r4.ywyy +mad r5.zw, r4.xxxz, -r11.yyyy, r0.xxxy +mul r0.xy, r12.xyxx, r5.yzyy +dp2 r0.x, r0.xyxx, r0.xyxx +min r0.x, r0.z, r0.x +mad r0.y, r0.x, l(0.400000), l(-1.000000) +mad r0.x, r12.z, r0.x, l(-1.000000) +mul r0.xy, r0.xyxx, r0.xyxx +mad r0.y, r0.y, l(1.562500), l(-0.562500) +mul r1.z, r0.x, r0.y +mov r10.x, r1.x +mov r10.y, r3.z +mad r1.xzw, r10.xxyz, r1.zzzz, r2.xxyz +mad r0.x, r0.y, r0.x, r0.w +dp2 r5.x, r4.zwzz, r11.xyxx +mul r0.yw, r12.xxxy, r5.xxxw +dp2 r0.y, r0.ywyy, r0.ywyy +min r0.y, r0.z, r0.y +mad r0.z, r0.y, l(0.400000), l(-1.000000) +mad r0.y, r12.z, r0.y, l(-1.000000) +mul r0.yz, r0.yyzy, r0.yyzy +mad r0.z, r0.z, l(1.562500), l(-0.562500) +mul r0.w, r0.y, r0.z +mov r10.x, r1.y +mov r10.y, r3.w +mad r1.xyz, r10.xywx, r0.wwww, r1.xzwx +mad r0.x, r0.z, r0.y, r0.x +rcp r0.x, r0.x +mul r0.xyz, r0.xxxx, r1.xyzx +max r0.xyz, r0.xyzx, r16.xyzx +min o0.xyz, r0.xyzx, r19.xyzx +mov o0.w, l(1.000000) +ret +// Approximately 299 instruction slots used +#endif + +const BYTE guest_output_ffx_fsr_easu_ps[] = { + 68, 88, 66, 67, 104, 250, 195, 52, 200, 111, 243, 238, 6, 142, 244, 87, 56, 133, 88, + 21, 1, 0, 0, 0, 236, 40, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 36, 2, + 0, 0, 88, 2, 0, 0, 140, 2, 0, 0, 80, 40, 0, 0, 82, 68, 69, 70, 232, + 1, 0, 0, 1, 0, 0, 0, 236, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 255, 255, 0, 5, 0, 0, 191, 1, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, + 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 219, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 102, 115, 114, 95, + 101, 97, 115, 117, 95, 115, 97, 109, 112, 108, 101, 114, 0, 120, 101, 95, 102, 115, 114, + 95, 101, 97, 115, 117, 95, 115, 111, 117, 114, 99, 101, 0, 112, 117, 115, 104, 95, 99, + 111, 110, 115, 116, 115, 95, 120, 101, 0, 171, 171, 219, 0, 0, 0, 2, 0, 0, 0, + 4, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 1, 0, + 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 128, 1, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 164, + 1, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 128, 1, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, + 0, 120, 101, 95, 102, 115, 114, 95, 101, 97, 115, 117, 95, 105, 110, 112, 117, 116, 95, + 111, 117, 116, 112, 117, 116, 95, 115, 105, 122, 101, 95, 114, 97, 116, 105, 111, 0, 102, + 108, 111, 97, 116, 50, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 120, 1, 0, 0, 120, 101, 95, 102, 115, 114, 95, 101, 97, 115, 117, 95, 105, 110, + 112, 117, 116, 95, 115, 105, 122, 101, 95, 105, 110, 118, 0, 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 73, 83, 71, + 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 3, 0, 0, 83, + 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 79, 83, 71, 78, 44, 0, 0, 0, + 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, + 103, 101, 116, 0, 171, 171, 83, 72, 69, 88, 188, 37, 0, 0, 81, 0, 0, 0, 111, + 9, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, + 6, 70, 110, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 88, 24, 0, 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 85, 85, 0, 0, 0, 0, 0, 0, 100, 32, 0, 4, 50, 16, 16, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, + 0, 104, 0, 0, 2, 22, 0, 0, 0, 56, 0, 0, 9, 130, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 128, 64, 58, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 17, 50, 0, 16, 0, 0, 0, 0, 0, + 70, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 191, 0, 0, 0, 191, 0, 0, 0, 0, 0, 0, 0, 0, 56, + 0, 0, 12, 114, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, + 0, 0, 128, 63, 0, 0, 128, 191, 0, 0, 0, 0, 230, 139, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 5, 50, 0, 16, 0, 2, 0, + 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 86, 0, 0, 5, 50, 0, 16, 0, 2, + 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 50, 0, 0, 11, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, 128, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 65, 0, + 0, 5, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 8, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, + 70, 0, 16, 128, 65, 0, 0, 0, 2, 0, 0, 0, 50, 0, 0, 9, 50, 0, 16, + 0, 1, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 1, 0, + 0, 0, 134, 0, 16, 0, 1, 0, 0, 0, 50, 0, 0, 14, 242, 0, 16, 0, 2, + 0, 0, 0, 230, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 64, 0, 0, 128, 63, 0, 0, 0, + 64, 70, 4, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 194, 0, 16, 0, 0, + 0, 0, 0, 166, 14, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, + 109, 0, 0, 11, 194, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, + 0, 230, 116, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 96, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 109, 0, 0, 11, 50, 0, 16, 0, 3, 0, 0, 0, 70, + 0, 16, 0, 1, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 11, 82, 0, 16, + 0, 4, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 134, 125, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 42, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, + 0, 0, 11, 242, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, + 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 96, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 109, 0, 0, 11, 242, 0, 16, 0, 6, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 11, 242, 0, 16, 0, + 7, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 150, 124, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 42, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, + 0, 11, 242, 0, 16, 0, 8, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 70, + 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 96, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 109, 0, 0, 11, 242, 0, 16, 0, 9, 0, 0, 0, 230, 10, 16, + 0, 2, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 96, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 11, 242, 0, 16, 0, 2, + 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 42, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, + 11, 50, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 230, 116, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 96, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 109, 0, 0, 11, 194, 0, 16, 0, 3, 0, 0, 0, 230, 10, 16, 0, + 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 96, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 11, 194, 0, 16, 0, 10, 0, + 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 42, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 12, + 194, 0, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 6, 4, + 16, 0, 3, 0, 0, 0, 50, 0, 0, 12, 194, 0, 16, 0, 0, 0, 0, 0, 6, + 8, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 63, 0, 0, 0, 63, 166, 14, 16, 0, 0, 0, 0, 0, 50, 0, 0, + 12, 242, 0, 16, 0, 11, 0, 0, 0, 230, 1, 16, 0, 5, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 230, + 1, 16, 0, 6, 0, 0, 0, 50, 0, 0, 12, 242, 0, 16, 0, 11, 0, 0, 0, + 214, 8, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, + 63, 0, 0, 0, 63, 0, 0, 0, 63, 70, 14, 16, 0, 11, 0, 0, 0, 50, 0, + 0, 12, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, + 70, 14, 16, 0, 9, 0, 0, 0, 50, 0, 0, 12, 242, 0, 16, 0, 12, 0, 0, + 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, + 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 70, 14, 16, 0, 12, 0, 0, 0, 50, + 0, 0, 12, 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, + 0, 230, 10, 16, 0, 3, 0, 0, 0, 50, 0, 0, 12, 50, 0, 16, 0, 13, 0, + 0, 0, 230, 10, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 63, 0, + 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, + 0, 0, 0, 11, 242, 0, 16, 0, 14, 0, 0, 0, 70, 4, 16, 128, 65, 0, 0, + 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, + 0, 0, 0, 0, 128, 191, 56, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, + 0, 16, 0, 14, 0, 0, 0, 10, 0, 16, 0, 14, 0, 0, 0, 0, 0, 0, 8, + 242, 0, 16, 0, 15, 0, 0, 0, 70, 8, 16, 128, 65, 0, 0, 0, 11, 0, 0, + 0, 246, 2, 16, 0, 12, 0, 0, 0, 0, 0, 0, 8, 114, 0, 16, 0, 16, 0, + 0, 0, 22, 7, 16, 128, 65, 0, 0, 0, 11, 0, 0, 0, 134, 2, 16, 0, 11, + 0, 0, 0, 52, 0, 0, 9, 194, 0, 16, 0, 13, 0, 0, 0, 6, 12, 16, 128, + 129, 0, 0, 0, 15, 0, 0, 0, 6, 8, 16, 128, 129, 0, 0, 0, 16, 0, 0, + 0, 30, 0, 0, 11, 194, 0, 16, 0, 13, 0, 0, 0, 166, 14, 16, 128, 65, 0, + 0, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, + 126, 240, 126, 187, 126, 240, 126, 56, 32, 0, 8, 34, 0, 16, 0, 11, 0, 0, 0, + 42, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 128, 129, 0, 0, 0, 15, 0, 0, + 0, 56, 0, 0, 7, 34, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 11, 0, + 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 0, 0, 0, 8, 82, 0, 16, 0, 16, + 0, 0, 0, 166, 10, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 6, 2, 16, 0, + 11, 0, 0, 0, 52, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, + 128, 129, 0, 0, 0, 16, 0, 0, 0, 26, 0, 16, 128, 129, 0, 0, 0, 16, 0, + 0, 0, 30, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 65, + 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 187, 126, 240, 126, 56, 32, 0, 8, + 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 128, 129, 0, 0, 0, 16, 0, 0, 0, 56, 0, 0, 7, 66, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, + 0, 26, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 50, 0, 16, 0, 14, 0, 0, 0, 70, + 0, 16, 0, 0, 0, 0, 0, 22, 5, 16, 0, 14, 0, 0, 0, 0, 0, 0, 8, + 114, 0, 16, 0, 17, 0, 0, 0, 246, 12, 16, 128, 65, 0, 0, 0, 12, 0, 0, + 0, 38, 9, 16, 0, 12, 0, 0, 0, 52, 0, 0, 9, 146, 0, 16, 0, 15, 0, + 0, 0, 6, 12, 16, 128, 129, 0, 0, 0, 15, 0, 0, 0, 6, 8, 16, 128, 129, + 0, 0, 0, 17, 0, 0, 0, 30, 0, 0, 11, 146, 0, 16, 0, 15, 0, 0, 0, + 6, 12, 16, 128, 65, 0, 0, 0, 15, 0, 0, 0, 2, 64, 0, 0, 187, 126, 240, + 126, 0, 0, 0, 0, 0, 0, 0, 0, 187, 126, 240, 126, 56, 0, 0, 7, 34, 0, + 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 15, + 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, + 15, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, + 0, 56, 32, 0, 8, 66, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 15, 0, + 0, 0, 42, 0, 16, 128, 129, 0, 0, 0, 15, 0, 0, 0, 56, 0, 0, 7, 66, + 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, + 12, 0, 0, 0, 50, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 12, 0, 0, 0, 10, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 8, 50, 0, 16, 0, 15, 0, 0, 0, 246, 15, 16, 128, 65, + 0, 0, 0, 0, 0, 0, 0, 54, 15, 16, 0, 12, 0, 0, 0, 52, 0, 0, 9, + 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 128, 129, 0, 0, 0, 15, 0, 0, + 0, 26, 0, 16, 128, 129, 0, 0, 0, 17, 0, 0, 0, 30, 0, 0, 8, 130, 0, + 16, 0, 0, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 187, 126, 240, 126, 56, 0, 0, 7, 66, 0, 16, 0, 12, 0, 0, 0, + 10, 0, 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, 15, 0, 0, 0, 50, 0, 0, + 9, 130, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 16, 0, 0, 0, 58, 0, + 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 56, 32, 0, 8, 130, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 128, + 129, 0, 0, 0, 15, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, + 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 50, 0, + 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, + 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, + 98, 0, 16, 0, 12, 0, 0, 0, 246, 14, 16, 128, 65, 0, 0, 0, 11, 0, 0, + 0, 6, 1, 16, 0, 12, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 14, 0, 0, 0, 26, + 0, 16, 0, 11, 0, 0, 0, 56, 32, 0, 8, 34, 0, 16, 0, 11, 0, 0, 0, + 58, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 128, 129, 0, 0, 0, 12, 0, 0, + 0, 56, 0, 0, 7, 34, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 11, 0, + 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 50, 0, 0, 9, 66, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 14, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 50, 0, 16, 0, 11, 0, 0, + 0, 38, 10, 16, 128, 65, 0, 0, 0, 11, 0, 0, 0, 86, 5, 16, 0, 13, 0, + 0, 0, 52, 0, 0, 9, 18, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 128, 129, + 0, 0, 0, 16, 0, 0, 0, 10, 0, 16, 128, 129, 0, 0, 0, 11, 0, 0, 0, + 30, 0, 0, 8, 18, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, + 0, 11, 0, 0, 0, 1, 64, 0, 0, 187, 126, 240, 126, 50, 0, 0, 9, 130, 0, + 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 14, + 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 56, 32, 0, 8, 18, 0, 16, 0, + 11, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 128, 129, 0, 0, + 0, 11, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 11, 0, 0, 0, 10, 0, + 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 50, 0, 0, 9, 66, + 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, + 14, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, + 0, 11, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 12, + 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 56, 32, 0, 8, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, + 0, 42, 0, 16, 128, 129, 0, 0, 0, 12, 0, 0, 0, 56, 0, 0, 7, 130, 0, + 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 50, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 8, 98, 0, 16, 0, 11, 0, 0, 0, 6, 3, 16, 128, 65, 0, + 0, 0, 12, 0, 0, 0, 6, 0, 16, 0, 13, 0, 0, 0, 52, 0, 0, 9, 130, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 128, 129, 0, 0, 0, 17, 0, 0, 0, + 26, 0, 16, 128, 129, 0, 0, 0, 11, 0, 0, 0, 30, 0, 0, 8, 130, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 187, 126, 240, 126, 50, 0, 0, 9, 66, 0, 16, 0, 15, 0, 0, 0, 42, + 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 56, 32, 0, 8, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, + 0, 0, 0, 0, 0, 42, 0, 16, 128, 129, 0, 0, 0, 11, 0, 0, 0, 56, 0, + 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 56, 0, 0, 7, 50, 0, 16, 0, 11, 0, 0, 0, 150, 5, + 16, 0, 15, 0, 0, 0, 150, 5, 16, 0, 15, 0, 0, 0, 0, 0, 0, 7, 130, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, + 11, 0, 0, 0, 49, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 56, 85, 0, 0, 7, 130, 0, + 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, + 0, 0, 0, 30, 0, 0, 8, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 128, + 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 116, 125, 52, 95, 55, 0, 0, + 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 63, 58, 0, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 18, + 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 26, 0, 16, 0, 15, 0, 0, 0, 56, 0, 0, 7, 50, 0, 16, + 0, 11, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 134, 0, 16, 0, 15, 0, + 0, 0, 56, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 56, 0, 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 15, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 11, 0, + 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 52, 0, 0, 9, 130, 0, 16, 0, 4, + 0, 0, 0, 26, 0, 16, 128, 129, 0, 0, 0, 11, 0, 0, 0, 10, 0, 16, 128, + 129, 0, 0, 0, 11, 0, 0, 0, 30, 0, 0, 8, 130, 0, 16, 0, 4, 0, 0, + 0, 58, 0, 16, 128, 65, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 187, 126, + 240, 126, 50, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, + 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 191, + 50, 0, 0, 9, 18, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 50, 0, + 0, 15, 98, 0, 16, 0, 12, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 225, 122, 148, 190, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 63, 0, 0, 0, + 0, 30, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 65, 0, + 0, 0, 12, 0, 0, 0, 1, 64, 0, 0, 187, 126, 240, 126, 54, 0, 0, 5, 18, + 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 5, + 34, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 54, 0, 0, + 5, 66, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 54, + 0, 0, 5, 34, 0, 16, 0, 15, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, + 54, 0, 0, 5, 66, 0, 16, 0, 15, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, + 0, 51, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 13, 0, + 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 17, + 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, + 17, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, + 0, 17, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 51, 0, 0, 7, 114, 0, + 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 17, + 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 10, 0, 16, 0, + 8, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 18, 0, 0, 0, 10, 0, 16, + 0, 9, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 18, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, 51, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, 0, 70, + 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 52, 0, 0, 7, + 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, + 0, 15, 0, 0, 0, 52, 0, 0, 7, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, + 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 52, 0, 0, 7, 114, + 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, + 19, 0, 0, 0, 15, 0, 0, 7, 18, 0, 16, 0, 14, 0, 0, 0, 230, 10, 16, + 0, 14, 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 56, 0, 0, 7, 130, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 14, + 0, 0, 0, 50, 0, 0, 10, 34, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, + 14, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 11, 0, 0, 0, 58, 0, 16, + 0, 0, 0, 0, 0, 56, 0, 0, 7, 98, 0, 16, 0, 5, 0, 0, 0, 6, 1, + 16, 0, 12, 0, 0, 0, 6, 1, 16, 0, 14, 0, 0, 0, 15, 0, 0, 7, 130, + 0, 16, 0, 0, 0, 0, 0, 150, 5, 16, 0, 5, 0, 0, 0, 150, 5, 16, 0, + 5, 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 130, 0, + 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 205, + 204, 204, 62, 1, 64, 0, 0, 0, 0, 128, 191, 50, 0, 0, 9, 130, 0, 16, 0, + 0, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 128, 191, 56, 0, 0, 7, 130, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 56, + 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 2, 0, 0, + 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 200, 63, 1, 64, + 0, 0, 0, 0, 16, 191, 56, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, + 18, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, + 5, 34, 0, 16, 0, 14, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 54, 0, + 0, 5, 66, 0, 16, 0, 14, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 0, + 0, 0, 11, 242, 0, 16, 0, 20, 0, 0, 0, 70, 4, 16, 128, 65, 0, 0, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 191, 0, 0, 128, + 191, 0, 0, 128, 63, 15, 0, 0, 7, 34, 0, 16, 0, 21, 0, 0, 0, 70, 0, + 16, 0, 20, 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 56, 0, 0, 7, 98, + 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, 86, 7, 16, 0, + 20, 0, 0, 0, 50, 0, 0, 10, 194, 0, 16, 0, 21, 0, 0, 0, 6, 8, 16, + 0, 20, 0, 0, 0, 86, 5, 16, 128, 65, 0, 0, 0, 11, 0, 0, 0, 86, 9, + 16, 0, 5, 0, 0, 0, 56, 0, 0, 7, 98, 0, 16, 0, 5, 0, 0, 0, 6, + 1, 16, 0, 12, 0, 0, 0, 86, 6, 16, 0, 21, 0, 0, 0, 15, 0, 0, 7, + 66, 0, 16, 0, 1, 0, 0, 0, 150, 5, 16, 0, 5, 0, 0, 0, 150, 5, 16, + 0, 5, 0, 0, 0, 51, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 18, + 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 205, 204, 204, 62, 1, 64, 0, 0, 0, 0, 128, 191, 50, 0, 0, 9, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, 0, 0, 128, 191, 56, 0, 0, 7, 18, 0, 16, 0, 3, + 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, + 56, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 200, 63, 1, + 64, 0, 0, 0, 0, 16, 191, 56, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, + 5, 18, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 54, 0, + 0, 5, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 56, + 0, 0, 7, 114, 0, 16, 0, 4, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, + 70, 2, 16, 0, 4, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, + 0, 70, 2, 16, 0, 14, 0, 0, 0, 246, 15, 16, 0, 4, 0, 0, 0, 70, 2, + 16, 0, 4, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 15, 0, 0, 7, 18, 0, 16, 0, 21, 0, 0, 0, 230, 10, 16, + 0, 20, 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 56, 0, 0, 7, 194, 0, + 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 12, 0, 0, 0, 6, 12, 16, 0, 21, + 0, 0, 0, 15, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, + 1, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 51, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 205, 204, 204, 62, 1, 64, 0, 0, 0, 0, 128, 191, + 50, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 191, 56, 0, + 0, 7, 194, 0, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 166, + 14, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 200, 63, 1, 64, 0, + 0, 0, 0, 16, 191, 56, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 18, + 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, + 34, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 50, 0, 0, + 9, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 246, 15, + 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 50, 0, 0, 9, 130, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 11, 242, 0, 16, + 0, 14, 0, 0, 0, 70, 4, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 128, 191, 0, 0, 0, 0, 15, + 0, 0, 7, 34, 0, 16, 0, 20, 0, 0, 0, 70, 0, 16, 0, 14, 0, 0, 0, + 70, 0, 16, 0, 11, 0, 0, 0, 56, 0, 0, 7, 194, 0, 16, 0, 1, 0, 0, + 0, 6, 0, 16, 0, 11, 0, 0, 0, 86, 13, 16, 0, 14, 0, 0, 0, 50, 0, + 0, 10, 194, 0, 16, 0, 20, 0, 0, 0, 6, 8, 16, 0, 14, 0, 0, 0, 86, + 5, 16, 128, 65, 0, 0, 0, 11, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, + 56, 0, 0, 7, 194, 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 12, 0, 0, + 0, 86, 9, 16, 0, 20, 0, 0, 0, 15, 0, 0, 7, 66, 0, 16, 0, 1, 0, + 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 51, + 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 205, 204, 204, 62, 1, 64, + 0, 0, 0, 0, 128, 191, 50, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, + 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 128, 191, 56, 0, 0, 7, 194, 0, 16, 0, 1, 0, 0, 0, 166, 14, 16, + 0, 1, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 130, 0, + 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 200, 63, 1, 64, 0, 0, 0, 0, 16, 191, 56, 0, 0, 7, 130, 0, 16, 0, + 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, + 0, 50, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 15, 0, + 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 50, + 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 15, 0, 0, + 8, 18, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 128, 65, 0, 0, 0, 0, 0, + 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 56, 0, 0, 8, 66, 0, 16, 0, 1, + 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, + 11, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 1, 0, + 0, 0, 56, 0, 0, 7, 194, 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 12, + 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 15, 0, 0, 7, 66, 0, 16, 0, + 1, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, + 0, 51, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 1, + 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 205, 204, 204, 62, + 1, 64, 0, 0, 0, 0, 128, 191, 50, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 191, 56, 0, 0, 7, 194, 0, 16, 0, 1, 0, 0, 0, 166, + 14, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, + 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 200, 63, 1, 64, 0, 0, 0, 0, 16, 191, 56, 0, 0, 7, 130, 0, + 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, + 17, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, + 0, 50, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 15, + 0, 0, 7, 18, 0, 16, 0, 20, 0, 0, 0, 230, 10, 16, 0, 14, 0, 0, 0, + 70, 0, 16, 0, 11, 0, 0, 0, 56, 0, 0, 7, 194, 0, 16, 0, 1, 0, 0, + 0, 6, 4, 16, 0, 12, 0, 0, 0, 6, 12, 16, 0, 20, 0, 0, 0, 15, 0, + 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 230, + 10, 16, 0, 1, 0, 0, 0, 51, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 50, 0, 0, + 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 205, 204, 204, 62, 1, 64, 0, 0, 0, 0, 128, 191, 50, 0, 0, 9, 66, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 191, 56, 0, 0, 7, 194, 0, 16, + 0, 1, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 1, 0, + 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 200, 63, 1, 64, 0, 0, 0, 0, 16, 191, + 56, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 7, 0, + 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 7, + 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, + 4, 0, 0, 0, 38, 11, 16, 0, 7, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, + 0, 70, 2, 16, 0, 4, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 11, 242, 0, 16, 0, 5, 0, 0, 0, + 70, 4, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 63, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 128, 63, 15, 0, 0, 7, 34, 0, + 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 11, + 0, 0, 0, 56, 0, 0, 7, 194, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, + 11, 0, 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 50, 0, 0, 10, 194, 0, 16, + 0, 6, 0, 0, 0, 6, 8, 16, 0, 5, 0, 0, 0, 86, 5, 16, 128, 65, 0, + 0, 0, 11, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 194, + 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 12, 0, 0, 0, 86, 9, 16, 0, + 6, 0, 0, 0, 15, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, + 0, 1, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 51, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 205, 204, 204, 62, 1, 64, 0, 0, 0, 0, 128, + 191, 50, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 12, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 191, 56, + 0, 0, 7, 194, 0, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, + 166, 14, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 200, 63, 1, 64, + 0, 0, 0, 0, 16, 191, 56, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, + 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 246, 15, 16, + 0, 2, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 50, 0, 0, 9, 130, 0, + 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 15, 0, 0, 7, 18, 0, 16, 0, + 6, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, + 0, 56, 0, 0, 7, 194, 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 12, 0, + 0, 0, 6, 12, 16, 0, 6, 0, 0, 0, 15, 0, 0, 7, 66, 0, 16, 0, 1, + 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, + 51, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 205, 204, 204, 62, 1, + 64, 0, 0, 0, 0, 128, 191, 50, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 128, 191, 56, 0, 0, 7, 194, 0, 16, 0, 1, 0, 0, 0, 166, 14, + 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 130, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 200, 63, 1, 64, 0, 0, 0, 0, 16, 191, 56, 0, 0, 7, 130, 0, 16, + 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 8, + 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, + 9, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, + 0, 2, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, + 16, 0, 5, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 4, + 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 11, 242, 0, 16, 0, 5, 0, 0, 0, 70, 4, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, + 0, 128, 63, 0, 0, 0, 0, 15, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, + 70, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 56, 0, 0, + 7, 194, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, 86, 13, + 16, 0, 5, 0, 0, 0, 50, 0, 0, 10, 194, 0, 16, 0, 6, 0, 0, 0, 6, + 8, 16, 0, 5, 0, 0, 0, 86, 5, 16, 128, 65, 0, 0, 0, 11, 0, 0, 0, + 166, 14, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 194, 0, 16, 0, 1, 0, 0, + 0, 6, 4, 16, 0, 12, 0, 0, 0, 86, 9, 16, 0, 6, 0, 0, 0, 15, 0, + 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 230, + 10, 16, 0, 1, 0, 0, 0, 51, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 50, 0, 0, + 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, + 0, 0, 205, 204, 204, 62, 1, 64, 0, 0, 0, 0, 128, 191, 50, 0, 0, 9, 66, + 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 191, 56, 0, 0, 7, 194, 0, 16, + 0, 1, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 1, 0, + 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, + 0, 0, 0, 1, 64, 0, 0, 0, 0, 200, 63, 1, 64, 0, 0, 0, 0, 16, 191, + 56, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, + 0, 58, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 2, + 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, + 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, + 0, 70, 2, 16, 0, 4, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 15, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, + 230, 10, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 56, 0, 0, + 7, 194, 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 12, 0, 0, 0, 6, 12, + 16, 0, 6, 0, 0, 0, 15, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 230, + 10, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 1, 0, 0, 0, 51, 0, 0, 7, + 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 205, 204, 204, 62, 1, 64, 0, 0, 0, + 0, 128, 191, 50, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, + 12, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, + 191, 56, 0, 0, 7, 194, 0, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 1, 0, + 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 1, + 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 200, 63, + 1, 64, 0, 0, 0, 0, 16, 191, 56, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, + 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 50, 0, + 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 246, + 15, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 50, 0, 0, 9, + 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, + 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 11, 242, 0, + 16, 0, 4, 0, 0, 0, 70, 4, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 64, + 15, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, + 0, 70, 0, 16, 0, 11, 0, 0, 0, 56, 0, 0, 7, 50, 0, 16, 0, 0, 0, + 0, 0, 6, 0, 16, 0, 11, 0, 0, 0, 214, 5, 16, 0, 4, 0, 0, 0, 50, + 0, 0, 10, 194, 0, 16, 0, 5, 0, 0, 0, 6, 8, 16, 0, 4, 0, 0, 0, + 86, 5, 16, 128, 65, 0, 0, 0, 11, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, + 0, 56, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 12, 0, + 0, 0, 150, 5, 16, 0, 5, 0, 0, 0, 15, 0, 0, 7, 18, 0, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, + 51, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 205, 204, 204, 62, 1, + 64, 0, 0, 0, 0, 128, 191, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 128, 191, 56, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 34, + 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 200, 63, 1, 64, 0, 0, 0, 0, 16, 191, 56, 0, 0, 7, 66, 0, 16, + 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 1, + 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, + 3, 0, 0, 0, 50, 0, 0, 9, 210, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, + 0, 10, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 2, 0, + 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 15, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, + 0, 70, 0, 16, 0, 11, 0, 0, 0, 56, 0, 0, 7, 162, 0, 16, 0, 0, 0, + 0, 0, 6, 4, 16, 0, 12, 0, 0, 0, 6, 12, 16, 0, 5, 0, 0, 0, 15, + 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 214, 5, 16, 0, 0, 0, 0, 0, + 214, 5, 16, 0, 0, 0, 0, 0, 51, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, + 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 50, 0, + 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 205, 204, 204, 62, 1, 64, 0, 0, 0, 0, 128, 191, 50, 0, 0, 9, + 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 191, 56, 0, 0, 7, 98, 0, + 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, 0, + 0, 0, 0, 50, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 200, 63, 1, 64, 0, 0, 0, 0, 16, + 191, 56, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, + 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, + 10, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, + 0, 1, 0, 0, 0, 70, 3, 16, 0, 10, 0, 0, 0, 246, 15, 16, 0, 0, 0, + 0, 0, 134, 3, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, 0, 0, 129, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, + 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 52, + 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 16, 0, 0, 0, 51, 0, 0, 7, 114, 32, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 54, 0, + 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, + 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 43, 1, 0, 0, 22, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 239, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 2, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_fsr_rcas_dither_ps.h b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_fsr_rcas_dither_ps.h new file mode 100644 index 0000000..eb8e447 --- /dev/null +++ b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_fsr_rcas_dither_ps.h @@ -0,0 +1,704 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// int2 xe_fsr_rcas_output_offset; // Offset: 0 Size: 8 +// float xe_fsr_rcas_sharpness_post_setup;// Offset: 8 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_fsr_rcas_source texture float4 2d T0 t0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// +ps_5_1 +dcl_globalFlags refactoringAllowed +dcl_immediateConstantBuffer { { -0.001003, 0, 0, 0}, + { 0.000881, 0, 0, 0}, + { 0.001693, 0, 0, 0}, + { -0.001555, 0, 0, 0}, + { 0.001279, 0, 0, 0}, + { -0.000605, 0, 0, 0}, + { 0.001065, 0, 0, 0}, + { -0.001386, 0, 0, 0}, + { 0.001356, 0, 0, 0}, + { 0.000513, 0, 0, 0}, + { 0.001218, 0, 0, 0}, + { -0.001601, 0, 0, 0}, + { 0.000590, 0, 0, 0}, + { -0.000283, 0, 0, 0}, + { 0.001111, 0, 0, 0}, + { -0.001417, 0, 0, 0}, + { 0.001448, 0, 0, 0}, + { -0.000544, 0, 0, 0}, + { 0.000130, 0, 0, 0}, + { -0.001203, 0, 0, 0}, + { 0.000437, 0, 0, 0}, + { -0.001049, 0, 0, 0}, + { 0.000620, 0, 0, 0}, + { -0.000483, 0, 0, 0}, + { 0.001877, 0, 0, 0}, + { -0.001095, 0, 0, 0}, + { -0.000100, 0, 0, 0}, + { -0.000528, 0, 0, 0}, + { 0.001432, 0, 0, 0}, + { -0.001938, 0, 0, 0}, + { -0.000697, 0, 0, 0}, + { 0.000038, 0, 0, 0}, + { 0.000712, 0, 0, 0}, + { -0.001310, 0, 0, 0}, + { 0.001095, 0, 0, 0}, + { -0.000299, 0, 0, 0}, + { 0.001754, 0, 0, 0}, + { -0.001677, 0, 0, 0}, + { 0.001478, 0, 0, 0}, + { -0.000038, 0, 0, 0}, + { 0.000789, 0, 0, 0}, + { -0.001831, 0, 0, 0}, + { 0.000299, 0, 0, 0}, + { 0.000988, 0, 0, 0}, + { -0.001172, 0, 0, 0}, + { 0.000176, 0, 0, 0}, + { 0.001647, 0, 0, 0}, + { -0.001585, 0, 0, 0}, + { 0.000345, 0, 0, 0}, + { 0.001861, 0, 0, 0}, + { -0.001769, 0, 0, 0}, + { -0.000866, 0, 0, 0}, + { 0.000896, 0, 0, 0}, + { 0.000161, 0, 0, 0}, + { -0.000927, 0, 0, 0}, + { -0.001524, 0, 0, 0}, + { -0.000651, 0, 0, 0}, + { 0.001294, 0, 0, 0}, + { -0.000804, 0, 0, 0}, + { -0.001463, 0, 0, 0}, + { 0.001800, 0, 0, 0}, + { -0.000850, 0, 0, 0}, + { 0.000850, 0, 0, 0}, + { -0.000452, 0, 0, 0}, + { -0.001065, 0, 0, 0}, + { -0.000146, 0, 0, 0}, + { 0.000237, 0, 0, 0}, + { 0.001417, 0, 0, 0}, + { -0.000590, 0, 0, 0}, + { -0.000191, 0, 0, 0}, + { 0.001601, 0, 0, 0}, + { 0.001019, 0, 0, 0}, + { 0.000406, 0, 0, 0}, + { -0.000207, 0, 0, 0}, + { 0.001585, 0, 0, 0}, + { 0.000651, 0, 0, 0}, + { -0.000069, 0, 0, 0}, + { 0.000421, 0, 0, 0}, + { -0.001647, 0, 0, 0}, + { 0.001371, 0, 0, 0}, + { 0.000927, 0, 0, 0}, + { -0.000666, 0, 0, 0}, + { 0.001187, 0, 0, 0}, + { -0.001448, 0, 0, 0}, + { 0.000574, 0, 0, 0}, + { -0.001892, 0, 0, 0}, + { 0.000758, 0, 0, 0}, + { -0.001294, 0, 0, 0}, + { 0.001922, 0, 0, 0}, + { -0.001662, 0, 0, 0}, + { -0.001034, 0, 0, 0}, + { -0.000498, 0, 0, 0}, + { -0.001861, 0, 0, 0}, + { 0.001203, 0, 0, 0}, + { -0.000329, 0, 0, 0}, + { -0.001371, 0, 0, 0}, + { 0.001631, 0, 0, 0}, + { -0.001846, 0, 0, 0}, + { 0.000728, 0, 0, 0}, + { -0.000911, 0, 0, 0}, + { 0.001815, 0, 0, 0}, + { -0.001141, 0, 0, 0}, + { -0.000375, 0, 0, 0}, + { 0.000100, 0, 0, 0}, + { -0.000743, 0, 0, 0}, + { 0.001172, 0, 0, 0}, + { 0.000069, 0, 0, 0}, + { 0.001494, 0, 0, 0}, + { 0.000973, 0, 0, 0}, + { -0.000957, 0, 0, 0}, + { 0.001938, 0, 0, 0}, + { 0.000528, 0, 0, 0}, + { 0.000054, 0, 0, 0}, + { -0.001248, 0, 0, 0}, + { -0.000268, 0, 0, 0}, + { 0.001540, 0, 0, 0}, + { -0.000008, 0, 0, 0}, + { 0.000314, 0, 0, 0}, + { 0.001340, 0, 0, 0}, + { -0.001754, 0, 0, 0}, + { 0.000498, 0, 0, 0}, + { -0.001187, 0, 0, 0}, + { 0.000774, 0, 0, 0}, + { -0.001340, 0, 0, 0}, + { 0.000268, 0, 0, 0}, + { -0.001478, 0, 0, 0}, + { -0.000130, 0, 0, 0}, + { -0.000774, 0, 0, 0}, + { 0.001310, 0, 0, 0}, + { 0.000391, 0, 0, 0}, + { 0.000957, 0, 0, 0}, + { -0.000467, 0, 0, 0}, + { -0.001540, 0, 0, 0}, + { 0.001034, 0, 0, 0}, + { -0.000682, 0, 0, 0}, + { 0.001677, 0, 0, 0}, + { 0.001003, 0, 0, 0}, + { -0.000421, 0, 0, 0}, + { 0.001785, 0, 0, 0}, + { -0.000237, 0, 0, 0}, + { -0.000620, 0, 0, 0}, + { 0.001662, 0, 0, 0}, + { 0.000835, 0, 0, 0}, + { -0.001723, 0, 0, 0}, + { -0.001080, 0, 0, 0}, + { 0.001769, 0, 0, 0}, + { -0.000789, 0, 0, 0}, + { -0.001785, 0, 0, 0}, + { 0.000682, 0, 0, 0}, + { -0.000988, 0, 0, 0}, + { -0.001325, 0, 0, 0}, + { -0.000176, 0, 0, 0}, + { -0.001509, 0, 0, 0}, + { 0.000329, 0, 0, 0}, + { -0.001953, 0, 0, 0}, + { 0.000666, 0, 0, 0}, + { -0.001616, 0, 0, 0}, + { 0.001157, 0, 0, 0}, + { 0.000452, 0, 0, 0}, + { -0.000437, 0, 0, 0}, + { 0.000191, 0, 0, 0}, + { -0.001494, 0, 0, 0}, + { 0.001141, 0, 0, 0}, + { 0.000084, 0, 0, 0}, + { 0.001892, 0, 0, 0}, + { 0.001402, 0, 0, 0}, + { 0.000559, 0, 0, 0}, + { 0.000115, 0, 0, 0}, + { 0.001264, 0, 0, 0}, + { -0.000574, 0, 0, 0}, + { -0.000973, 0, 0, 0}, + { 0.001325, 0, 0, 0}, + { 0.000222, 0, 0, 0}, + { -0.000758, 0, 0, 0}, + { -0.001356, 0, 0, 0}, + { 0.001463, 0, 0, 0}, + { 0.000866, 0, 0, 0}, + { -0.000360, 0, 0, 0}, + { 0.000544, 0, 0, 0}, + { -0.001126, 0, 0, 0}, + { -0.000253, 0, 0, 0}, + { -0.000559, 0, 0, 0}, + { -0.001815, 0, 0, 0}, + { 0.001723, 0, 0, 0}, + { -0.001157, 0, 0, 0}, + { 0.000743, 0, 0, 0}, + { 0.001570, 0, 0, 0}, + { -0.000115, 0, 0, 0}, + { -0.001218, 0, 0, 0}, + { 0.001831, 0, 0, 0}, + { 0.000023, 0, 0, 0}, + { -0.001922, 0, 0, 0}, + { 0.001739, 0, 0, 0}, + { -0.000712, 0, 0, 0}, + { 0.001555, 0, 0, 0}, + { -0.001708, 0, 0, 0}, + { 0.001233, 0, 0, 0}, + { 0.000207, 0, 0, 0}, + { 0.001049, 0, 0, 0}, + { -0.000728, 0, 0, 0}, + { -0.001631, 0, 0, 0}, + { -0.000314, 0, 0, 0}, + { 0.000483, 0, 0, 0}, + { -0.001800, 0, 0, 0}, + { 0.000942, 0, 0, 0}, + { -0.000345, 0, 0, 0}, + { 0.000697, 0, 0, 0}, + { -0.001019, 0, 0, 0}, + { -0.001570, 0, 0, 0}, + { -0.000023, 0, 0, 0}, + { -0.001279, 0, 0, 0}, + { 0.000804, 0, 0, 0}, + { -0.000896, 0, 0, 0}, + { -0.001432, 0, 0, 0}, + { 0.000605, 0, 0, 0}, + { -0.000084, 0, 0, 0}, + { 0.000911, 0, 0, 0}, + { 0.001953, 0, 0, 0}, + { -0.001402, 0, 0, 0}, + { -0.000636, 0, 0, 0}, + { 0.001509, 0, 0, 0}, + { -0.000820, 0, 0, 0}, + { 0.001248, 0, 0, 0}, + { 0.000253, 0, 0, 0}, + { 0.001524, 0, 0, 0}, + { 0.001126, 0, 0, 0}, + { 0.000360, 0, 0, 0}, + { -0.000391, 0, 0, 0}, + { 0.001907, 0, 0, 0}, + { 0.001386, 0, 0, 0}, + { -0.001111, 0, 0, 0}, + { 0.001616, 0, 0, 0}, + { -0.000881, 0, 0, 0}, + { 0.000146, 0, 0, 0}, + { 0.001080, 0, 0, 0}, + { -0.000054, 0, 0, 0}, + { 0.000283, 0, 0, 0}, + { -0.001693, 0, 0, 0}, + { -0.001264, 0, 0, 0}, + { -0.000513, 0, 0, 0}, + { -0.000161, 0, 0, 0}, + { -0.001877, 0, 0, 0}, + { -0.000835, 0, 0, 0}, + { 0.000636, 0, 0, 0}, + { 0.000008, 0, 0, 0}, + { -0.001907, 0, 0, 0}, + { -0.000222, 0, 0, 0}, + { 0.000375, 0, 0, 0}, + { -0.001739, 0, 0, 0}, + { -0.000406, 0, 0, 0}, + { -0.001233, 0, 0, 0}, + { 0.001708, 0, 0, 0}, + { -0.000942, 0, 0, 0}, + { 0.000820, 0, 0, 0}, + { 0.001846, 0, 0, 0}, + { 0.000467, 0, 0, 0} } +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_texture2d (float,float,float,float) T0[0:0], space=0 +dcl_input_ps_siv linear noperspective v0.xy, position +dcl_output o0.xyzw +dcl_temps 10 +ftoi r0.xy, v0.xyxx +iadd r0.xy, r0.xyxx, -CB0[0][0].xyxx +iadd r1.xyzw, r0.xyxy, l(-1, 0, 0, -1) +mov r2.xy, r1.zwzz +mov r2.zw, l(0,0,0,0) +ld r2.xyz, r2.xyzw, T0[0].xyzw +mov r1.zw, l(0,0,0,0) +ld r1.xyz, r1.xyzw, T0[0].xyzw +mov r0.zw, l(0,0,0,0) +ld r3.xyz, r0.xyzw, T0[0].xyzw +iadd r4.xyzw, r0.xyxy, l(0, 1, 1, 0) +mov r5.xy, r4.zwzz +mov r5.zw, l(0,0,0,0) +ld r5.xyz, r5.xyzw, T0[0].xyzw +mov r4.zw, l(0,0,0,0) +ld r4.xyz, r4.xyzw, T0[0].xyzw +min r6.xyz, r1.xyzx, r5.xyzx +min r6.xyz, r2.xyzx, r6.xyzx +min r6.xyz, r4.xyzx, r6.xyzx +max r7.xyz, r1.xyzx, r5.xyzx +max r7.xyz, r2.xyzx, r7.xyzx +max r7.xyz, r4.xyzx, r7.xyzx +min r8.xyz, r3.xyzx, r6.xyzx +mul r9.xyz, r7.xyzx, l(4.000000, 4.000000, 4.000000, 0.000000) +rcp r9.xyz, r9.xyzx +mul r8.xyz, r8.xyzx, r9.xyzx +max r7.xyz, r3.xyzx, r7.xyzx +add r7.xyz, -r7.xyzx, l(1.000000, 1.000000, 1.000000, 0.000000) +mad r6.xyz, r6.xyzx, l(4.000000, 4.000000, 4.000000, 0.000000), l(-4.000000, -4.000000, -4.000000, 0.000000) +rcp r6.xyz, r6.xyzx +mul r6.xyz, r6.xyzx, r7.xyzx +max r6.xyz, r6.xyzx, -r8.xyzx +max r0.z, r6.z, r6.y +max r0.z, r0.z, r6.x +min r0.z, r0.z, l(0.000000) +max r0.z, r0.z, l(-0.187500) +mul r0.z, r0.z, CB0[0][0].z +mad r0.w, r0.z, l(4.000000), l(1.000000) +iadd r1.w, -r0.w, l(0x7ef19fff) +mad r0.w, -r1.w, r0.w, l(2.000000) +mul r0.w, r0.w, r1.w +mul r1.xyz, r1.xyzx, r0.zzzz +mad r1.xyz, r0.zzzz, r2.xyzx, r1.xyzx +mad r1.xyz, r0.zzzz, r4.xyzx, r1.xyzx +mad r1.xyz, r0.zzzz, r5.xyzx, r1.xyzx +add r1.xyz, r3.xyzx, r1.xyzx +bfi r0.y, l(4), l(4), r0.y, l(0) +bfi r0.x, l(4), l(0), r0.x, r0.y +mad_sat o0.xyz, r1.xyzx, r0.wwww, icb[r0.x + 0].xxxx +mov o0.w, l(1.000000) +ret +// Approximately 51 instruction slots used +#endif + +const BYTE guest_output_ffx_fsr_rcas_dither_ps[] = { + 68, 88, 66, 67, 189, 177, 225, 60, 179, 155, 192, 193, 156, 139, 161, 52, 112, 21, 82, + 56, 1, 0, 0, 0, 196, 25, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 12, 2, + 0, 0, 64, 2, 0, 0, 116, 2, 0, 0, 40, 25, 0, 0, 82, 68, 69, 70, 208, + 1, 0, 0, 1, 0, 0, 0, 176, 0, 0, 0, 2, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 255, 255, 0, 5, 0, 0, 168, 1, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 102, 115, 114, 95, 114, 99, + 97, 115, 95, 115, 111, 117, 114, 99, 101, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, + 116, 115, 95, 120, 101, 0, 171, 171, 159, 0, 0, 0, 2, 0, 0, 0, 200, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 1, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 56, 1, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 92, 1, 0, 0, + 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 132, 1, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 102, 115, 114, 95, 114, 99, 97, 115, 95, 111, 117, 116, 112, 117, 116, 95, 111, 102, + 102, 115, 101, 116, 0, 105, 110, 116, 50, 0, 171, 1, 0, 2, 0, 1, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 50, 1, 0, 0, 120, 101, 95, 102, 115, 114, 95, 114, 99, 97, + 115, 95, 115, 104, 97, 114, 112, 110, 101, 115, 115, 95, 112, 111, 115, 116, 95, 115, 101, + 116, 117, 112, 0, 102, 108, 111, 97, 116, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 125, 1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, + 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, 0, + 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 3, 0, 0, 83, 86, 95, 80, 111, 115, + 105, 116, 105, 111, 110, 0, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, + 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, + 171, 83, 72, 69, 88, 172, 22, 0, 0, 81, 0, 0, 0, 171, 5, 0, 0, 106, 8, + 0, 1, 53, 24, 0, 0, 2, 4, 0, 0, 132, 131, 131, 186, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 231, 230, 102, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 222, 221, 221, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 204, 203, 203, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 167, + 167, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 159, 158, 30, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 139, 139, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 182, 181, 181, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 178, 177, 177, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 135, 134, 6, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, + 159, 159, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 209, 209, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, 154, 26, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 149, 148, 148, 185, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 146, 145, 145, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 186, 185, 185, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 190, 189, 189, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 142, 14, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137, 136, 8, 57, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 158, 157, 157, 186, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 229, 228, 228, 57, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 138, 137, 137, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 163, 162, 34, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 252, + 252, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 245, 245, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 143, 143, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 209, 208, 208, 184, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 139, 138, 10, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 188, 187, 187, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, + 253, 253, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 182, 54, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 161, 160, 32, 56, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, 186, 58, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 172, 171, 171, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 144, 143, 143, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 157, 156, 156, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 229, 229, + 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 219, 219, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 193, 193, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 161, 160, 32, 184, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 207, 206, 78, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 240, 239, 239, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157, 156, + 156, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, 129, 129, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 153, 153, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 185, 184, 56, 57, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 216, 215, 215, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 208, 207, 207, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181, + 180, 180, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 243, 243, 58, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 231, 231, 186, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 227, 226, 98, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 235, 234, 106, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 169, 168, 40, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 243, 242, 114, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 199, 199, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 170, 42, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 169, 169, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 211, 210, 82, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 192, 191, 191, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 236, 235, 235, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 222, + 94, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 222, 94, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 236, 236, 185, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 140, 139, 139, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 153, 152, 24, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 249, 248, 120, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, + 185, 185, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, 154, 26, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 200, 72, 185, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 209, 209, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 134, 133, 133, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 213, 212, 212, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 217, 216, 88, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 208, 207, 207, + 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 170, 42, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 144, 144, 184, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 221, 220, 220, 57, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 216, 215, 215, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 180, 179, 179, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, 242, + 114, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175, 174, 46, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 155, 155, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 190, 189, 189, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 151, 150, 22, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 248, 247, 247, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 199, + 198, 70, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 169, 169, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 251, 251, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 218, 217, 217, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 136, 135, 135, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 131, 130, 2, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 244, 243, 243, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 158, 157, 157, + 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, 172, 172, 185, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 179, 179, 186, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 214, 213, 213, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 242, 241, 241, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 191, 190, 62, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, 238, + 110, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, 237, 237, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 149, 149, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 196, 196, 185, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 209, 208, 208, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 195, 194, 66, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, + 153, 153, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 144, 144, 56, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 195, 195, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 254, 126, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 251, 250, 122, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 254, 253, 253, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 139, 138, 10, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225, 224, 96, + 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 163, 163, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, 140, 140, 185, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 202, 201, 201, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 129, 128, 0, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 165, 164, 164, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176, 175, + 175, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 229, 229, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 130, 2, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 156, 155, 155, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 203, 202, 74, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 176, 175, 175, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, + 140, 140, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 193, 193, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137, 136, 8, 185, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 203, 202, 74, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 172, 171, 171, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 205, 204, 204, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 251, 250, 122, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 244, 244, + 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 201, 201, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 135, 135, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 179, 178, 50, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 220, 219, 219, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 132, 131, 131, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 220, + 220, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 233, 233, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 248, 120, 185, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 163, 162, 34, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 218, 217, 217, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 219, 218, 90, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, + 225, 225, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 141, 141, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 231, 231, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 207, 206, 78, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 234, 233, 233, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 179, 178, 50, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 130, 129, 129, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 173, 173, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 185, 184, 56, 185, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 197, 197, 186, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 173, 172, 172, 57, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 175, 174, 46, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, 211, + 211, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 152, 151, 151, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 236, 236, 57, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 229, 228, 228, 185, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 201, 200, 72, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 196, 195, 195, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, + 149, 149, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 176, 176, 56, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 247, 247, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 184, 183, 183, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 147, 146, 18, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 241, 240, 240, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 166, 165, 165, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151, 150, 22, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 254, 126, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 173, 173, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 233, 232, 104, 57, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 199, 198, 70, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 178, 177, 177, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 191, + 191, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 227, 226, 98, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, 188, 188, 185, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 143, 142, 14, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 148, 147, 147, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 133, 132, 132, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, + 146, 18, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, 237, 237, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, 225, 225, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 152, 151, 151, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 195, 194, 66, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 206, 205, 205, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 241, 240, 240, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 159, 159, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 239, 239, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 193, 192, 192, 55, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 252, 251, 251, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 228, 227, 227, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 187, 186, 58, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 203, + 203, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 223, 223, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 161, 161, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 217, 216, 88, 57, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 138, 137, 137, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 191, 190, 62, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, + 213, 213, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 164, 164, 185, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 252, 252, 57, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 236, 235, 235, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 247, 246, 118, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 181, 180, 180, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 183, 182, 54, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 133, 133, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 205, 205, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 193, 192, 192, 183, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 168, 167, 167, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 211, 210, 82, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 235, 234, 106, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188, 187, + 187, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 159, 158, 30, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 176, 176, 184, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 239, 238, 110, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 184, 183, 183, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 167, + 166, 38, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 197, 197, 58, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 215, 214, 86, 186, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 163, 163, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 133, 132, 132, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 200, 199, 199, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 148, 147, 147, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, 188, 188, + 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 205, 204, 204, 185, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 249, 249, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 182, 181, 181, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 146, 145, 145, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 212, 211, 211, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 231, 230, + 102, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 152, 24, 57, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 141, 141, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 225, 224, 96, 184, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 149, 148, 148, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 222, 221, 221, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, + 165, 165, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 134, 6, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 169, 168, 40, 185, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 245, 245, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 219, 218, 90, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 167, 166, 38, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 129, 128, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 249, 249, + 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 232, 104, 185, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 197, 196, 196, 57, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 228, 227, 227, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 213, 212, 212, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 162, 161, 161, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 223, + 223, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 247, 246, 118, 186, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 215, 214, 86, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 242, 241, 241, 58, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 245, 244, 244, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 88, 24, 0, 7, 70, 126, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 0, 0, 0, 0, 0, + 0, 100, 32, 0, 4, 50, 16, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 10, 0, 0, 0, 27, + 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, + 30, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, + 0, 70, 128, 48, 128, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 4, 16, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 54, 0, 0, 5, 50, 0, 16, 0, 2, 0, 0, 0, 230, 10, 16, + 0, 1, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, + 0, 0, 8, 114, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 1, 0, 0, 0, 70, + 14, 16, 0, 1, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, + 70, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 5, 0, + 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 5, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, + 0, 5, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, + 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 51, 0, 0, 7, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, + 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 51, 0, 0, 7, 114, + 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, + 6, 0, 0, 0, 51, 0, 0, 7, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, + 0, 4, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 52, 0, 0, 7, 114, 0, + 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 5, + 0, 0, 0, 52, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, + 2, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 52, 0, 0, 7, 114, 0, 16, + 0, 7, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 7, 0, + 0, 0, 51, 0, 0, 7, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 3, + 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, + 9, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 64, 0, 0, 128, 64, 0, 0, 128, 64, 0, 0, 0, 0, 129, 0, 0, 5, 114, 0, + 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 56, 0, 0, 7, 114, + 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, + 9, 0, 0, 0, 52, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, + 0, 3, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 0, 0, 0, 11, 114, 0, + 16, 0, 7, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 7, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 0, 0, + 50, 0, 0, 15, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 128, 64, 0, 0, 128, 64, 0, 0, 128, 64, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 128, 192, 0, 0, 128, 192, 0, 0, 128, 192, 0, + 0, 0, 0, 129, 0, 0, 5, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, + 6, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, + 0, 6, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 52, 0, 0, 8, 114, 0, + 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 70, 2, 16, 128, 65, + 0, 0, 0, 8, 0, 0, 0, 52, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 52, 0, 0, + 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 6, 0, 0, 0, 51, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 52, 0, 0, 7, + 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 64, 190, 56, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 64, 1, 64, 0, 0, 0, 0, 128, + 63, 30, 0, 0, 8, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 159, 241, 126, 50, 0, 0, 10, 130, + 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 56, 0, 0, + 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 1, 0, 0, 0, 70, + 2, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, + 114, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 2, 16, + 0, 2, 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 114, 0, + 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 4, + 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, + 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, + 0, 70, 2, 16, 0, 1, 0, 0, 0, 0, 0, 0, 7, 114, 0, 16, 0, 1, 0, + 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 140, + 0, 0, 11, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, + 1, 64, 0, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 140, 0, 0, 11, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, + 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 50, 32, 0, 10, 114, 32, 16, 0, + 0, 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, + 0, 6, 144, 144, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, + 84, 65, 84, 148, 0, 0, 0, 51, 0, 0, 0, 10, 0, 0, 0, 0, 1, 0, 0, + 2, 0, 0, 0, 28, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0}; diff --git a/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_fsr_rcas_ps.h b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_fsr_rcas_ps.h new file mode 100644 index 0000000..d4d5bc5 --- /dev/null +++ b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_ffx_fsr_rcas_ps.h @@ -0,0 +1,224 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// int2 xe_fsr_rcas_output_offset; // Offset: 0 Size: 8 +// float xe_fsr_rcas_sharpness_post_setup;// Offset: 8 Size: 4 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_fsr_rcas_source texture float4 2d T0 t0 1 +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// +ps_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_resource_texture2d (float,float,float,float) T0[0:0], space=0 +dcl_input_ps_siv linear noperspective v0.xy, position +dcl_output o0.xyzw +dcl_temps 9 +ftoi r0.xy, v0.xyxx +iadd r0.xy, r0.xyxx, -CB0[0][0].xyxx +iadd r1.xyzw, r0.xyxy, l(-1, 0, 0, -1) +mov r2.xy, r1.zwzz +mov r2.zw, l(0,0,0,0) +ld r2.xyz, r2.xyzw, T0[0].xyzw +mov r1.zw, l(0,0,0,0) +ld r1.xyz, r1.xyzw, T0[0].xyzw +mov r0.zw, l(0,0,0,0) +ld r3.xyz, r0.xyzw, T0[0].xyzw +iadd r0.xyzw, r0.xyxy, l(0, 1, 1, 0) +mov r4.xy, r0.zwzz +mov r4.zw, l(0,0,0,0) +ld r4.xyz, r4.xyzw, T0[0].xyzw +mov r0.zw, l(0,0,0,0) +ld r0.xyz, r0.xyzw, T0[0].xyzw +min r5.xyz, r1.xyzx, r4.xyzx +min r5.xyz, r2.xyzx, r5.xyzx +min r5.xyz, r0.xyzx, r5.xyzx +max r6.xyz, r1.xyzx, r4.xyzx +max r6.xyz, r2.xyzx, r6.xyzx +max r6.xyz, r0.xyzx, r6.xyzx +min r7.xyz, r3.xyzx, r5.xyzx +mul r8.xyz, r6.xyzx, l(4.000000, 4.000000, 4.000000, 0.000000) +rcp r8.xyz, r8.xyzx +mul r7.xyz, r7.xyzx, r8.xyzx +max r6.xyz, r3.xyzx, r6.xyzx +add r6.xyz, -r6.xyzx, l(1.000000, 1.000000, 1.000000, 0.000000) +mad r5.xyz, r5.xyzx, l(4.000000, 4.000000, 4.000000, 0.000000), l(-4.000000, -4.000000, -4.000000, 0.000000) +rcp r5.xyz, r5.xyzx +mul r5.xyz, r5.xyzx, r6.xyzx +max r5.xyz, r5.xyzx, -r7.xyzx +max r0.w, r5.z, r5.y +max r0.w, r0.w, r5.x +min r0.w, r0.w, l(0.000000) +max r0.w, r0.w, l(-0.187500) +mul r0.w, r0.w, CB0[0][0].z +mad r1.w, r0.w, l(4.000000), l(1.000000) +iadd r2.w, -r1.w, l(0x7ef19fff) +mad r1.w, -r2.w, r1.w, l(2.000000) +mul r1.w, r1.w, r2.w +mul r1.xyz, r1.xyzx, r0.wwww +mad r1.xyz, r0.wwww, r2.xyzx, r1.xyzx +mad r0.xyz, r0.wwww, r0.xyzx, r1.xyzx +mad r0.xyz, r0.wwww, r4.xyzx, r0.xyzx +add r0.xyz, r3.xyzx, r0.xyzx +mul o0.xyz, r1.wwww, r0.xyzx +mov o0.w, l(1.000000) +ret +// Approximately 49 instruction slots used +#endif + +const BYTE guest_output_ffx_fsr_rcas_ps[] = { + 68, 88, 66, 67, 67, 185, 127, 150, 159, 188, 61, 246, 239, 146, 24, 229, 183, 68, 131, + 230, 1, 0, 0, 0, 88, 9, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 12, 2, + 0, 0, 64, 2, 0, 0, 116, 2, 0, 0, 188, 8, 0, 0, 82, 68, 69, 70, 208, + 1, 0, 0, 1, 0, 0, 0, 176, 0, 0, 0, 2, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 255, 255, 0, 5, 0, 0, 168, 1, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 102, 115, 114, 95, 114, 99, + 97, 115, 95, 115, 111, 117, 114, 99, 101, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, + 116, 115, 95, 120, 101, 0, 171, 171, 159, 0, 0, 0, 2, 0, 0, 0, 200, 0, 0, + 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 1, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 56, 1, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 92, 1, 0, 0, + 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 132, 1, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, + 95, 102, 115, 114, 95, 114, 99, 97, 115, 95, 111, 117, 116, 112, 117, 116, 95, 111, 102, + 102, 115, 101, 116, 0, 105, 110, 116, 50, 0, 171, 1, 0, 2, 0, 1, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 50, 1, 0, 0, 120, 101, 95, 102, 115, 114, 95, 114, 99, 97, + 115, 95, 115, 104, 97, 114, 112, 110, 101, 115, 115, 95, 112, 111, 115, 116, 95, 115, 101, + 116, 117, 112, 0, 102, 108, 111, 97, 116, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 125, 1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, + 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, 0, + 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 3, 0, 0, 83, 86, 95, 80, 111, 115, + 105, 116, 105, 111, 110, 0, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, + 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, + 171, 83, 72, 69, 88, 64, 6, 0, 0, 81, 0, 0, 0, 144, 1, 0, 0, 106, 8, + 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 88, 24, 0, 7, 70, 126, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 0, 0, 0, 0, 0, + 0, 100, 32, 0, 4, 50, 16, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 9, 0, 0, 0, 27, + 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, + 30, 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, + 0, 70, 128, 48, 128, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 4, 16, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 54, 0, 0, 5, 50, 0, 16, 0, 2, 0, 0, 0, 230, 10, 16, + 0, 1, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, + 0, 0, 8, 114, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, + 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, + 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 1, 0, 0, 0, 70, + 14, 16, 0, 1, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, + 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, + 70, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 4, 0, + 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 4, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, + 0, 4, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 8, 114, 0, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 51, 0, 0, 7, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, + 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 51, 0, 0, 7, 114, + 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, + 5, 0, 0, 0, 51, 0, 0, 7, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, + 0, 0, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 52, 0, 0, 7, 114, 0, + 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 4, + 0, 0, 0, 52, 0, 0, 7, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, + 2, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 52, 0, 0, 7, 114, 0, 16, + 0, 6, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 6, 0, + 0, 0, 51, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 3, + 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, + 8, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, + 64, 0, 0, 128, 64, 0, 0, 128, 64, 0, 0, 0, 0, 129, 0, 0, 5, 114, 0, + 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 56, 0, 0, 7, 114, + 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, + 8, 0, 0, 0, 52, 0, 0, 7, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, + 0, 3, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 0, 0, 0, 11, 114, 0, + 16, 0, 6, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 6, 0, 0, 0, 2, + 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 0, 0, + 50, 0, 0, 15, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, + 0, 2, 64, 0, 0, 0, 0, 128, 64, 0, 0, 128, 64, 0, 0, 128, 64, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 128, 192, 0, 0, 128, 192, 0, 0, 128, 192, 0, + 0, 0, 0, 129, 0, 0, 5, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, + 5, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, + 0, 5, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 52, 0, 0, 8, 114, 0, + 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 70, 2, 16, 128, 65, + 0, 0, 0, 7, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 52, 0, 0, + 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 5, 0, 0, 0, 51, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, + 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 52, 0, 0, 7, + 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 64, 190, 56, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, 42, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 50, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 64, 1, 64, 0, 0, 0, 0, 128, + 63, 30, 0, 0, 8, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 128, 65, 0, + 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 255, 159, 241, 126, 50, 0, 0, 10, 130, + 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 56, 0, 0, + 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, + 16, 0, 2, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 1, 0, 0, 0, 70, + 2, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, + 114, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, + 0, 2, 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 114, 0, + 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, + 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 114, 0, 16, 0, + 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 114, 0, 16, 0, 0, 0, + 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 7, 114, 32, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, + 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, + 0, 0, 49, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/ui/shaders/bytecode/d3d12_5_1/guest_output_triangle_strip_rect_vs.h b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_triangle_strip_rect_vs.h new file mode 100644 index 0000000..49d793a --- /dev/null +++ b/src/ui/shaders/bytecode/d3d12_5_1/guest_output_triangle_strip_rect_vs.h @@ -0,0 +1,105 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// float2 xe_triangle_strip_rect_offset;// Offset: 0 Size: 8 +// float2 xe_triangle_strip_rect_size;// Offset: 8 Size: 8 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_VertexID 0 x 0 VERTID uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xyzw +// +vs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_input_sgv v0.x, vertex_id +dcl_output_siv o0.xyzw, position +dcl_temps 1 +ushr r0.y, v0.x, l(1) +mov r0.x, v0.x +and r0.xy, r0.xyxx, l(1, 1, 0, 0) +utof r0.xy, r0.xyxx +mad o0.xy, r0.xyxx, CB0[0][0].zwzz, CB0[0][0].xyxx +mov o0.zw, l(0,0,0,1.000000) +ret +// Approximately 7 instruction slots used +#endif + +const BYTE guest_output_triangle_strip_rect_vs[] = { + 68, 88, 66, 67, 50, 140, 173, 83, 164, 102, 25, 145, 174, 164, 206, 34, 69, 212, 161, + 224, 1, 0, 0, 0, 200, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 168, 1, + 0, 0, 220, 1, 0, 0, 16, 2, 0, 0, 44, 3, 0, 0, 82, 68, 69, 70, 108, + 1, 0, 0, 1, 0, 0, 0, 116, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 254, 255, 0, 5, 0, 0, 68, 1, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, + 95, 120, 101, 0, 171, 100, 0, 0, 0, 2, 0, 0, 0, 140, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 2, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 40, 1, 0, 0, 8, 0, 0, + 0, 8, 0, 0, 0, 2, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, 116, 114, + 105, 97, 110, 103, 108, 101, 95, 115, 116, 114, 105, 112, 95, 114, 101, 99, 116, 95, 111, + 102, 102, 115, 101, 116, 0, 102, 108, 111, 97, 116, 50, 0, 171, 171, 171, 1, 0, 3, + 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 120, 101, 95, 116, 114, + 105, 97, 110, 103, 108, 101, 95, 115, 116, 114, 105, 112, 95, 114, 101, 99, 116, 95, 115, + 105, 122, 101, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, + 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, + 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, 83, 86, 95, 86, 101, 114, 116, 101, 120, 73, 68, + 0, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, + 0, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 83, 72, 69, 88, + 20, 1, 0, 0, 81, 0, 1, 0, 69, 0, 0, 0, 106, 8, 0, 1, 89, 0, 0, + 7, 70, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 96, 0, 0, 4, 18, 16, 16, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 104, 0, 0, 2, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, + 0, 10, 16, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 0, 0, 0, 0, 1, + 0, 0, 10, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, + 0, 0, 50, 0, 0, 13, 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, + 0, 0, 0, 230, 138, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 70, 128, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 8, 194, 32, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 148, + 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/ui/shaders/bytecode/d3d12_5_1/immediate_ps.h b/src/ui/shaders/bytecode/d3d12_5_1/immediate_ps.h new file mode 100644 index 0000000..a043665 --- /dev/null +++ b/src/ui/shaders/bytecode/d3d12_5_1/immediate_ps.h @@ -0,0 +1,85 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_immediate_texture_xe_sampler sampler NA NA S0 s0 1 +// xe_immediate_texture texture float4 2d T0 t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// TEXCOORD 0 xy 0 NONE float xy +// COLOR 0 xyzw 1 NONE float xyzw +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// +ps_5_1 +dcl_globalFlags refactoringAllowed +dcl_sampler S0[0:0], mode_default, space=0 +dcl_resource_texture2d (float,float,float,float) T0[0:0], space=0 +dcl_input_ps linear v0.xy +dcl_input_ps linear v1.xyzw +dcl_output o0.xyzw +dcl_temps 1 +sample_l r0.xyzw, v0.xyxx, T0[0].xyzw, S0[0], l(0.000000) +mul o0.xyzw, r0.xyzw, v1.xyzw +ret +// Approximately 3 instruction slots used +#endif + +const BYTE immediate_ps[] = { + 68, 88, 66, 67, 107, 181, 28, 66, 229, 168, 59, 0, 81, 196, 220, 121, 194, 12, 76, + 233, 1, 0, 0, 0, 16, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 40, 1, + 0, 0, 120, 1, 0, 0, 172, 1, 0, 0, 116, 2, 0, 0, 82, 68, 69, 70, 236, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 255, 255, 0, 5, 0, 0, 193, 0, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 140, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, + 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 101, 95, 105, 109, 109, 101, 100, 105, + 97, 116, 101, 95, 116, 101, 120, 116, 117, 114, 101, 95, 120, 101, 95, 115, 97, 109, 112, + 108, 101, 114, 0, 120, 101, 95, 105, 109, 109, 101, 100, 105, 97, 116, 101, 95, 116, 101, + 120, 116, 117, 114, 101, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, + 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, + 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 72, 0, 0, 0, + 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 65, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, + 69, 88, 67, 79, 79, 82, 68, 0, 67, 79, 76, 79, 82, 0, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, + 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 69, 88, 192, 0, 0, 0, 81, + 0, 0, 0, 48, 0, 0, 0, 106, 8, 0, 1, 90, 0, 0, 6, 70, 110, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 24, 0, + 7, 70, 126, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, + 0, 0, 0, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, + 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, + 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 72, 0, 0, 13, 242, 0, 16, + 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 148, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0}; diff --git a/src/ui/shaders/bytecode/d3d12_5_1/immediate_vs.h b/src/ui/shaders/bytecode/d3d12_5_1/immediate_vs.h new file mode 100644 index 0000000..2636877 --- /dev/null +++ b/src/ui/shaders/bytecode/d3d12_5_1/immediate_vs.h @@ -0,0 +1,115 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer push_consts_xe +// { +// +// float2 xe_coordinate_space_size_inv;// Offset: 0 Size: 8 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// push_consts_xe cbuffer NA NA CB0 cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// POSITION 0 xy 0 NONE float xy +// TEXCOORD 0 xy 1 NONE float xy +// COLOR 0 xyzw 2 NONE float xyzw +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// TEXCOORD 0 xy 0 NONE float xy +// COLOR 0 xyzw 1 NONE float xyzw +// SV_Position 0 xyzw 2 POS float xyzw +// +vs_5_1 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][1], immediateIndexed, space=0 +dcl_input v0.xy +dcl_input v1.xy +dcl_input v2.xyzw +dcl_output o0.xy +dcl_output o1.xyzw +dcl_output_siv o2.xyzw, position +dcl_temps 1 +mul r0.xy, v0.xyxx, CB0[0][0].xyxx +mad o2.xy, r0.xyxx, l(2.000000, -2.000000, 0.000000, 0.000000), l(-1.000000, 1.000000, 0.000000, 0.000000) +mov o1.xyzw, v2.xyzw +mov o2.zw, l(0,0,0,1.000000) +mov o0.xy, v1.xyxx +ret +// Approximately 6 instruction slots used +#endif + +const BYTE immediate_vs[] = { + 68, 88, 66, 67, 150, 136, 152, 237, 155, 249, 84, 3, 80, 221, 206, 175, 204, 144, 211, + 193, 1, 0, 0, 0, 16, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 96, 1, + 0, 0, 208, 1, 0, 0, 68, 2, 0, 0, 116, 3, 0, 0, 82, 68, 69, 70, 36, + 1, 0, 0, 1, 0, 0, 0, 116, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 0, + 1, 5, 254, 255, 0, 5, 0, 0, 252, 0, 0, 0, 19, 19, 68, 37, 60, 0, 0, + 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 112, 117, 115, 104, 95, 99, 111, 110, 115, 116, 115, + 95, 120, 101, 0, 171, 100, 0, 0, 0, 1, 0, 0, 0, 140, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 2, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 120, 101, 95, 99, 111, 111, 114, + 100, 105, 110, 97, 116, 101, 95, 115, 112, 97, 99, 101, 95, 115, 105, 122, 101, 95, 105, + 110, 118, 0, 102, 108, 111, 97, 116, 50, 0, 1, 0, 3, 0, 1, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 209, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 104, 0, 0, 0, 3, + 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 89, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, 98, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, + 15, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, + 68, 0, 67, 79, 76, 79, 82, 0, 79, 83, 71, 78, 108, 0, 0, 0, 3, 0, 0, + 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 95, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, + 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 67, 79, 76, 79, 82, 0, 83, 86, 95, + 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 83, 72, 69, 88, 40, 1, 0, 0, 81, + 0, 1, 0, 74, 0, 0, 0, 106, 8, 0, 1, 89, 0, 0, 7, 70, 142, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 50, 16, + 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, + 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, + 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, 0, 0, 1, 0, 0, + 0, 104, 0, 0, 2, 1, 0, 0, 0, 56, 0, 0, 9, 50, 0, 16, 0, 0, 0, + 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 128, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 15, 50, 32, 16, 0, 2, 0, 0, 0, + 70, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 64, 0, 0, 0, + 192, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, + 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, + 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 54, 0, 0, 8, 194, 32, 16, 0, + 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 128, 63, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, + 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 148, 0, 0, 0, 6, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/ui/shaders/vulkan_spirv/guest_output_bilinear_dither_ps.h b/src/ui/shaders/vulkan_spirv/guest_output_bilinear_dither_ps.h new file mode 100644 index 0000000..a81a0be --- /dev/null +++ b/src/ui/shaders/vulkan_spirv/guest_output_bilinear_dither_ps.h @@ -0,0 +1,584 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25141 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %5663 "main" %gl_FragCoord %5312 + OpExecutionMode %5663 OriginUpperLeft + OpDecorate %gl_FragCoord BuiltIn FragCoord + OpDecorate %_struct_1028 Block + OpMemberDecorate %_struct_1028 0 Offset 16 + OpMemberDecorate %_struct_1028 1 Offset 24 + OpDecorate %4448 Binding 0 + OpDecorate %4448 DescriptorSet 0 + OpDecorate %4927 Binding 1 + OpDecorate %4927 DescriptorSet 0 + OpDecorate %5312 Location 0 + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %float = OpTypeFloat 32 +%_ptr_Function_float = OpTypePointer Function %float + %v3float = OpTypeVector %float 3 + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 + %uint_15 = OpConstant %uint 15 + %uint_256 = OpConstant %uint 256 +%_arr_float_uint_256 = OpTypeArray %float %uint_256 +%float_n0_00100337015 = OpConstant %float -0.00100337015 +%float_0_000880821084 = OpConstant %float 0.000880821084 +%float_0_00169270835 = OpConstant %float 0.00169270835 +%float_n0_00155484071 = OpConstant %float -0.00155484071 +%float_0_00127910543 = OpConstant %float 0.00127910543 +%float_n0_000605085806 = OpConstant %float -0.000605085806 +%float_0_00106464466 = OpConstant %float 0.00106464466 +%float_n0_00138633582 = OpConstant %float -0.00138633582 +%float_0_00135569857 = OpConstant %float 0.00135569857 +%float_0_000513174047 = OpConstant %float 0.000513174047 +%float_0_00121783093 = OpConstant %float 0.00121783093 +%float_n0_00160079659 = OpConstant %float -0.00160079659 +%float_0_00058976718 = OpConstant %float 0.00058976718 +%float_n0_00028339462 = OpConstant %float -0.00028339462 +%float_0_00111060054 = OpConstant %float 0.00111060054 +%float_n0_00141697307 = OpConstant %float -0.00141697307 +%float_0_00144761032 = OpConstant %float 0.00144761032 +%float_n0_0005438113 = OpConstant %float -0.0005438113 +%float_0_00013020834 = OpConstant %float 0.00013020834 +%float_n0_0012025123 = OpConstant %float -0.0012025123 +%float_0_000436580885 = OpConstant %float 0.000436580885 +%float_n0_00104932603 = OpConstant %float -0.00104932603 +%float_0_000620404433 = OpConstant %float 0.000620404433 +%float_n0_000482536765 = OpConstant %float -0.000482536765 +%float_0_00187653187 = OpConstant %float 0.00187653187 +%float_n0_00109528191 = OpConstant %float -0.00109528191 +%float_n9_95710798en05 = OpConstant %float -9.95710798e-05 +%float_n0_000528492674 = OpConstant %float -0.000528492674 +%float_0_0014322917 = OpConstant %float 0.0014322917 +%float_n0_00193780637 = OpConstant %float -0.00193780637 +%float_n0_000696997566 = OpConstant %float -0.000696997566 +%float_3_829657en05 = OpConstant %float 3.829657e-05 +%float_0_000712316192 = OpConstant %float 0.000712316192 +%float_n0_00130974269 = OpConstant %float -0.00130974269 +%float_0_00109528191 = OpConstant %float 0.00109528191 +%float_n0_000298713247 = OpConstant %float -0.000298713247 +%float_0_00175398286 = OpConstant %float 0.00175398286 +%float_n0_00167738972 = OpConstant %float -0.00167738972 +%float_0_00147824758 = OpConstant %float 0.00147824758 +%float_n3_829657en05 = OpConstant %float -3.829657e-05 +%float_0_000788909325 = OpConstant %float 0.000788909325 +%float_n0_00183057599 = OpConstant %float -0.00183057599 +%float_0_000298713247 = OpConstant %float 0.000298713247 +%float_0_000988051528 = OpConstant %float 0.000988051528 +%float_n0_00117187505 = OpConstant %float -0.00117187505 +%float_0_00017616422 = OpConstant %float 0.00017616422 +%float_0_00164675247 = OpConstant %float 0.00164675247 +%float_n0_00158547796 = OpConstant %float -0.00158547796 +%float_0_000344669126 = OpConstant %float 0.000344669126 +%float_0_00186121324 = OpConstant %float 0.00186121324 +%float_n0_00176930148 = OpConstant %float -0.00176930148 +%float_n0_000865502458 = OpConstant %float -0.000865502458 +%float_0_000896139711 = OpConstant %float 0.000896139711 +%float_0_000160845593 = OpConstant %float 0.000160845593 +%float_n0_000926776964 = OpConstant %float -0.000926776964 +%float_n0_00152420346 = OpConstant %float -0.00152420346 +%float_n0_000651041686 = OpConstant %float -0.000651041686 +%float_0_00129442406 = OpConstant %float 0.00129442406 +%float_n0_000804227951 = OpConstant %float -0.000804227951 +%float_n0_00146292895 = OpConstant %float -0.00146292895 +%float_0_00179993873 = OpConstant %float 0.00179993873 +%float_n0_000850183831 = OpConstant %float -0.000850183831 +%float_0_000850183831 = OpConstant %float 0.000850183831 +%float_n0_000451899512 = OpConstant %float -0.000451899512 +%float_n0_00106464466 = OpConstant %float -0.00106464466 +%float_n0_000145526967 = OpConstant %float -0.000145526967 +%float_0_000237438726 = OpConstant %float 0.000237438726 +%float_0_00141697307 = OpConstant %float 0.00141697307 +%float_n0_00058976718 = OpConstant %float -0.00058976718 +%float_n0_000191482846 = OpConstant %float -0.000191482846 +%float_0_00160079659 = OpConstant %float 0.00160079659 +%float_0_00101868878 = OpConstant %float 0.00101868878 +%float_0_000405943632 = OpConstant %float 0.000405943632 +%float_n0_000206801473 = OpConstant %float -0.000206801473 +%float_0_00158547796 = OpConstant %float 0.00158547796 +%float_0_000651041686 = OpConstant %float 0.000651041686 +%float_n6_89338267en05 = OpConstant %float -6.89338267e-05 +%float_0_000421262259 = OpConstant %float 0.000421262259 +%float_n0_00164675247 = OpConstant %float -0.00164675247 +%float_0_00137101719 = OpConstant %float 0.00137101719 +%float_0_000926776964 = OpConstant %float 0.000926776964 +%float_n0_000666360313 = OpConstant %float -0.000666360313 +%float_0_00118719367 = OpConstant %float 0.00118719367 +%float_n0_00144761032 = OpConstant %float -0.00144761032 +%float_0_000574448553 = OpConstant %float 0.000574448553 +%float_n0_00189185049 = OpConstant %float -0.00189185049 +%float_0_000758272072 = OpConstant %float 0.000758272072 +%float_n0_00129442406 = OpConstant %float -0.00129442406 +%float_0_00192248775 = OpConstant %float 0.00192248775 +%float_n0_0016620711 = OpConstant %float -0.0016620711 +%float_n0_00103400741 = OpConstant %float -0.00103400741 +%float_n0_000497855421 = OpConstant %float -0.000497855421 +%float_n0_00186121324 = OpConstant %float -0.00186121324 +%float_0_0012025123 = OpConstant %float 0.0012025123 +%float_n0_0003293505 = OpConstant %float -0.0003293505 +%float_n0_00137101719 = OpConstant %float -0.00137101719 +%float_0_00163143384 = OpConstant %float 0.00163143384 +%float_n0_00184589461 = OpConstant %float -0.00184589461 +%float_0_000727634819 = OpConstant %float 0.000727634819 +%float_n0_000911458337 = OpConstant %float -0.000911458337 +%float_0_00181525736 = OpConstant %float 0.00181525736 +%float_n0_00114123779 = OpConstant %float -0.00114123779 +%float_n0_000375306379 = OpConstant %float -0.000375306379 +%float_9_95710798en05 = OpConstant %float 9.95710798e-05 +%float_n0_000742953445 = OpConstant %float -0.000742953445 +%float_0_00117187505 = OpConstant %float 0.00117187505 +%float_6_89338267en05 = OpConstant %float 6.89338267e-05 +%float_0_0014935662 = OpConstant %float 0.0014935662 +%float_0_000972732843 = OpConstant %float 0.000972732843 +%float_n0_000957414217 = OpConstant %float -0.000957414217 +%float_0_00193780637 = OpConstant %float 0.00193780637 +%float_0_000528492674 = OpConstant %float 0.000528492674 +%float_5_36151965en05 = OpConstant %float 5.36151965e-05 +%float_n0_00124846818 = OpConstant %float -0.00124846818 +%float_n0_000268075994 = OpConstant %float -0.000268075994 +%float_0_00153952208 = OpConstant %float 0.00153952208 +%float_n7_65931418en06 = OpConstant %float -7.65931418e-06 +%float_0_000314031873 = OpConstant %float 0.000314031873 +%float_0_00134037994 = OpConstant %float 0.00134037994 +%float_n0_00175398286 = OpConstant %float -0.00175398286 +%float_0_000497855421 = OpConstant %float 0.000497855421 +%float_n0_00118719367 = OpConstant %float -0.00118719367 +%float_0_000773590698 = OpConstant %float 0.000773590698 +%float_n0_00134037994 = OpConstant %float -0.00134037994 +%float_0_000268075994 = OpConstant %float 0.000268075994 +%float_n0_00147824758 = OpConstant %float -0.00147824758 +%float_n0_00013020834 = OpConstant %float -0.00013020834 +%float_n0_000773590698 = OpConstant %float -0.000773590698 +%float_0_00130974269 = OpConstant %float 0.00130974269 +%float_0_000390625006 = OpConstant %float 0.000390625006 +%float_0_000957414217 = OpConstant %float 0.000957414217 +%float_n0_000467218139 = OpConstant %float -0.000467218139 +%float_n0_00153952208 = OpConstant %float -0.00153952208 +%float_0_00103400741 = OpConstant %float 0.00103400741 +%float_n0_000681678939 = OpConstant %float -0.000681678939 +%float_0_00167738972 = OpConstant %float 0.00167738972 +%float_0_00100337015 = OpConstant %float 0.00100337015 +%float_n0_000421262259 = OpConstant %float -0.000421262259 +%float_0_00178462011 = OpConstant %float 0.00178462011 +%float_n0_000237438726 = OpConstant %float -0.000237438726 +%float_n0_000620404433 = OpConstant %float -0.000620404433 +%float_0_0016620711 = OpConstant %float 0.0016620711 +%float_0_000834865205 = OpConstant %float 0.000834865205 +%float_n0_0017233456 = OpConstant %float -0.0017233456 +%float_n0_00107996329 = OpConstant %float -0.00107996329 +%float_0_00176930148 = OpConstant %float 0.00176930148 +%float_n0_000788909325 = OpConstant %float -0.000788909325 +%float_n0_00178462011 = OpConstant %float -0.00178462011 +%float_0_000681678939 = OpConstant %float 0.000681678939 +%float_n0_000988051528 = OpConstant %float -0.000988051528 +%float_n0_00132506131 = OpConstant %float -0.00132506131 +%float_n0_00017616422 = OpConstant %float -0.00017616422 +%float_n0_00150888483 = OpConstant %float -0.00150888483 +%float_0_0003293505 = OpConstant %float 0.0003293505 +%float_n0_001953125 = OpConstant %float -0.001953125 +%float_0_000666360313 = OpConstant %float 0.000666360313 +%float_n0_00161611522 = OpConstant %float -0.00161611522 +%float_0_00115655642 = OpConstant %float 0.00115655642 +%float_0_000451899512 = OpConstant %float 0.000451899512 +%float_n0_000436580885 = OpConstant %float -0.000436580885 +%float_0_000191482846 = OpConstant %float 0.000191482846 +%float_n0_0014935662 = OpConstant %float -0.0014935662 +%float_0_00114123779 = OpConstant %float 0.00114123779 +%float_8_42524532en05 = OpConstant %float 8.42524532e-05 +%float_0_00189185049 = OpConstant %float 0.00189185049 +%float_0_00140165444 = OpConstant %float 0.00140165444 +%float_0_000559129927 = OpConstant %float 0.000559129927 +%float_0_000114889706 = OpConstant %float 0.000114889706 +%float_0_00126378681 = OpConstant %float 0.00126378681 +%float_n0_000574448553 = OpConstant %float -0.000574448553 +%float_n0_000972732843 = OpConstant %float -0.000972732843 +%float_0_00132506131 = OpConstant %float 0.00132506131 +%float_0_000222120099 = OpConstant %float 0.000222120099 +%float_n0_000758272072 = OpConstant %float -0.000758272072 +%float_n0_00135569857 = OpConstant %float -0.00135569857 +%float_0_00146292895 = OpConstant %float 0.00146292895 +%float_0_000865502458 = OpConstant %float 0.000865502458 +%float_n0_000359987753 = OpConstant %float -0.000359987753 +%float_0_0005438113 = OpConstant %float 0.0005438113 +%float_n0_00112591917 = OpConstant %float -0.00112591917 +%float_n0_000252757367 = OpConstant %float -0.000252757367 +%float_n0_000559129927 = OpConstant %float -0.000559129927 +%float_n0_00181525736 = OpConstant %float -0.00181525736 +%float_0_0017233456 = OpConstant %float 0.0017233456 +%float_n0_00115655642 = OpConstant %float -0.00115655642 +%float_0_000742953445 = OpConstant %float 0.000742953445 +%float_0_00157015934 = OpConstant %float 0.00157015934 +%float_n0_000114889706 = OpConstant %float -0.000114889706 +%float_n0_00121783093 = OpConstant %float -0.00121783093 +%float_0_00183057599 = OpConstant %float 0.00183057599 +%float_2_29779416en05 = OpConstant %float 2.29779416e-05 +%float_n0_00192248775 = OpConstant %float -0.00192248775 +%float_0_00173866423 = OpConstant %float 0.00173866423 +%float_n0_000712316192 = OpConstant %float -0.000712316192 +%float_0_00155484071 = OpConstant %float 0.00155484071 +%float_n0_00170802698 = OpConstant %float -0.00170802698 +%float_0_00123314955 = OpConstant %float 0.00123314955 +%float_0_000206801473 = OpConstant %float 0.000206801473 +%float_0_00104932603 = OpConstant %float 0.00104932603 +%float_n0_000727634819 = OpConstant %float -0.000727634819 +%float_n0_00163143384 = OpConstant %float -0.00163143384 +%float_n0_000314031873 = OpConstant %float -0.000314031873 +%float_0_000482536765 = OpConstant %float 0.000482536765 +%float_n0_00179993873 = OpConstant %float -0.00179993873 +%float_0_00094209559 = OpConstant %float 0.00094209559 +%float_n0_000344669126 = OpConstant %float -0.000344669126 +%float_0_000696997566 = OpConstant %float 0.000696997566 +%float_n0_00101868878 = OpConstant %float -0.00101868878 +%float_n0_00157015934 = OpConstant %float -0.00157015934 +%float_n2_29779416en05 = OpConstant %float -2.29779416e-05 +%float_n0_00127910543 = OpConstant %float -0.00127910543 +%float_0_000804227951 = OpConstant %float 0.000804227951 +%float_n0_000896139711 = OpConstant %float -0.000896139711 +%float_n0_0014322917 = OpConstant %float -0.0014322917 +%float_0_000605085806 = OpConstant %float 0.000605085806 +%float_n8_42524532en05 = OpConstant %float -8.42524532e-05 +%float_0_000911458337 = OpConstant %float 0.000911458337 +%float_0_001953125 = OpConstant %float 0.001953125 +%float_n0_00140165444 = OpConstant %float -0.00140165444 +%float_n0_00063572306 = OpConstant %float -0.00063572306 +%float_0_00150888483 = OpConstant %float 0.00150888483 +%float_n0_000819546578 = OpConstant %float -0.000819546578 +%float_0_00124846818 = OpConstant %float 0.00124846818 +%float_0_000252757367 = OpConstant %float 0.000252757367 +%float_0_00152420346 = OpConstant %float 0.00152420346 +%float_0_00112591917 = OpConstant %float 0.00112591917 +%float_0_000359987753 = OpConstant %float 0.000359987753 +%float_n0_000390625006 = OpConstant %float -0.000390625006 +%float_0_00190716912 = OpConstant %float 0.00190716912 +%float_0_00138633582 = OpConstant %float 0.00138633582 +%float_n0_00111060054 = OpConstant %float -0.00111060054 +%float_0_00161611522 = OpConstant %float 0.00161611522 +%float_n0_000880821084 = OpConstant %float -0.000880821084 +%float_0_000145526967 = OpConstant %float 0.000145526967 +%float_0_00107996329 = OpConstant %float 0.00107996329 +%float_n5_36151965en05 = OpConstant %float -5.36151965e-05 +%float_0_00028339462 = OpConstant %float 0.00028339462 +%float_n0_00169270835 = OpConstant %float -0.00169270835 +%float_n0_00126378681 = OpConstant %float -0.00126378681 +%float_n0_000513174047 = OpConstant %float -0.000513174047 +%float_n0_000160845593 = OpConstant %float -0.000160845593 +%float_n0_00187653187 = OpConstant %float -0.00187653187 +%float_n0_000834865205 = OpConstant %float -0.000834865205 +%float_0_00063572306 = OpConstant %float 0.00063572306 +%float_7_65931418en06 = OpConstant %float 7.65931418e-06 +%float_n0_00190716912 = OpConstant %float -0.00190716912 +%float_n0_000222120099 = OpConstant %float -0.000222120099 +%float_0_000375306379 = OpConstant %float 0.000375306379 +%float_n0_00173866423 = OpConstant %float -0.00173866423 +%float_n0_000405943632 = OpConstant %float -0.000405943632 +%float_n0_00123314955 = OpConstant %float -0.00123314955 +%float_0_00170802698 = OpConstant %float 0.00170802698 +%float_n0_00094209559 = OpConstant %float -0.00094209559 +%float_0_000819546578 = OpConstant %float 0.000819546578 +%float_0_00184589461 = OpConstant %float 0.00184589461 +%float_0_000467218139 = OpConstant %float 0.000467218139 + %1947 = OpConstantComposite %_arr_float_uint_256 %float_n0_00100337015 %float_0_000880821084 %float_0_00169270835 %float_n0_00155484071 %float_0_00127910543 %float_n0_000605085806 %float_0_00106464466 %float_n0_00138633582 %float_0_00135569857 %float_0_000513174047 %float_0_00121783093 %float_n0_00160079659 %float_0_00058976718 %float_n0_00028339462 %float_0_00111060054 %float_n0_00141697307 %float_0_00144761032 %float_n0_0005438113 %float_0_00013020834 %float_n0_0012025123 %float_0_000436580885 %float_n0_00104932603 %float_0_000620404433 %float_n0_000482536765 %float_0_00187653187 %float_n0_00109528191 %float_n9_95710798en05 %float_n0_000528492674 %float_0_0014322917 %float_n0_00193780637 %float_n0_000696997566 %float_3_829657en05 %float_0_000712316192 %float_n0_00130974269 %float_0_00109528191 %float_n0_000298713247 %float_0_00175398286 %float_n0_00167738972 %float_0_00147824758 %float_n3_829657en05 %float_0_000788909325 %float_n0_00183057599 %float_0_000298713247 %float_0_000988051528 %float_n0_00117187505 %float_0_00017616422 %float_0_00164675247 %float_n0_00158547796 %float_0_000344669126 %float_0_00186121324 %float_n0_00176930148 %float_n0_000865502458 %float_0_000896139711 %float_0_000160845593 %float_n0_000926776964 %float_n0_00152420346 %float_n0_000651041686 %float_0_00129442406 %float_n0_000804227951 %float_n0_00146292895 %float_0_00179993873 %float_n0_000850183831 %float_0_000850183831 %float_n0_000451899512 %float_n0_00106464466 %float_n0_000145526967 %float_0_000237438726 %float_0_00141697307 %float_n0_00058976718 %float_n0_000191482846 %float_0_00160079659 %float_0_00101868878 %float_0_000405943632 %float_n0_000206801473 %float_0_00158547796 %float_0_000651041686 %float_n6_89338267en05 %float_0_000421262259 %float_n0_00164675247 %float_0_00137101719 %float_0_000926776964 %float_n0_000666360313 %float_0_00118719367 %float_n0_00144761032 %float_0_000574448553 %float_n0_00189185049 %float_0_000758272072 %float_n0_00129442406 %float_0_00192248775 %float_n0_0016620711 %float_n0_00103400741 %float_n0_000497855421 %float_n0_00186121324 %float_0_0012025123 %float_n0_0003293505 %float_n0_00137101719 %float_0_00163143384 %float_n0_00184589461 %float_0_000727634819 %float_n0_000911458337 %float_0_00181525736 %float_n0_00114123779 %float_n0_000375306379 %float_9_95710798en05 %float_n0_000742953445 %float_0_00117187505 %float_6_89338267en05 %float_0_0014935662 %float_0_000972732843 %float_n0_000957414217 %float_0_00193780637 %float_0_000528492674 %float_5_36151965en05 %float_n0_00124846818 %float_n0_000268075994 %float_0_00153952208 %float_n7_65931418en06 %float_0_000314031873 %float_0_00134037994 %float_n0_00175398286 %float_0_000497855421 %float_n0_00118719367 %float_0_000773590698 %float_n0_00134037994 %float_0_000268075994 %float_n0_00147824758 %float_n0_00013020834 %float_n0_000773590698 %float_0_00130974269 %float_0_000390625006 %float_0_000957414217 %float_n0_000467218139 %float_n0_00153952208 %float_0_00103400741 %float_n0_000681678939 %float_0_00167738972 %float_0_00100337015 %float_n0_000421262259 %float_0_00178462011 %float_n0_000237438726 %float_n0_000620404433 %float_0_0016620711 %float_0_000834865205 %float_n0_0017233456 %float_n0_00107996329 %float_0_00176930148 %float_n0_000788909325 %float_n0_00178462011 %float_0_000681678939 %float_n0_000988051528 %float_n0_00132506131 %float_n0_00017616422 %float_n0_00150888483 %float_0_0003293505 %float_n0_001953125 %float_0_000666360313 %float_n0_00161611522 %float_0_00115655642 %float_0_000451899512 %float_n0_000436580885 %float_0_000191482846 %float_n0_0014935662 %float_0_00114123779 %float_8_42524532en05 %float_0_00189185049 %float_0_00140165444 %float_0_000559129927 %float_0_000114889706 %float_0_00126378681 %float_n0_000574448553 %float_n0_000972732843 %float_0_00132506131 %float_0_000222120099 %float_n0_000758272072 %float_n0_00135569857 %float_0_00146292895 %float_0_000865502458 %float_n0_000359987753 %float_0_0005438113 %float_n0_00112591917 %float_n0_000252757367 %float_n0_000559129927 %float_n0_00181525736 %float_0_0017233456 %float_n0_00115655642 %float_0_000742953445 %float_0_00157015934 %float_n0_000114889706 %float_n0_00121783093 %float_0_00183057599 %float_2_29779416en05 %float_n0_00192248775 %float_0_00173866423 %float_n0_000712316192 %float_0_00155484071 %float_n0_00170802698 %float_0_00123314955 %float_0_000206801473 %float_0_00104932603 %float_n0_000727634819 %float_n0_00163143384 %float_n0_000314031873 %float_0_000482536765 %float_n0_00179993873 %float_0_00094209559 %float_n0_000344669126 %float_0_000696997566 %float_n0_00101868878 %float_n0_00157015934 %float_n2_29779416en05 %float_n0_00127910543 %float_0_000804227951 %float_n0_000896139711 %float_n0_0014322917 %float_0_000605085806 %float_n8_42524532en05 %float_0_000911458337 %float_0_001953125 %float_n0_00140165444 %float_n0_00063572306 %float_0_00150888483 %float_n0_000819546578 %float_0_00124846818 %float_0_000252757367 %float_0_00152420346 %float_0_00112591917 %float_0_000359987753 %float_n0_000390625006 %float_0_00190716912 %float_0_00138633582 %float_n0_00111060054 %float_0_00161611522 %float_n0_000880821084 %float_0_000145526967 %float_0_00107996329 %float_n5_36151965en05 %float_0_00028339462 %float_n0_00169270835 %float_n0_00126378681 %float_n0_000513174047 %float_n0_000160845593 %float_n0_00187653187 %float_n0_000834865205 %float_0_00063572306 %float_7_65931418en06 %float_n0_00190716912 %float_n0_000222120099 %float_0_000375306379 %float_n0_00173866423 %float_n0_000405943632 %float_n0_00123314955 %float_0_00170802698 %float_n0_00094209559 %float_0_000819546578 %float_0_00184589461 %float_0_000467218139 + %uint_16 = OpConstant %uint 16 +%_ptr_Function__arr_float_uint_256 = OpTypePointer Function %_arr_float_uint_256 + %v4float = OpTypeVector %float 4 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%gl_FragCoord = OpVariable %_ptr_Input_v4float Input + %v2float = OpTypeVector %float 2 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 +%_struct_1028 = OpTypeStruct %v2int %v2float +%_ptr_PushConstant__struct_1028 = OpTypePointer PushConstant %_struct_1028 + %3305 = OpVariable %_ptr_PushConstant__struct_1028 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_v2int = OpTypePointer PushConstant %v2int + %151 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_151 = OpTypePointer UniformConstant %151 + %4448 = OpVariable %_ptr_UniformConstant_151 UniformConstant + %508 = OpTypeSampler +%_ptr_UniformConstant_508 = OpTypePointer UniformConstant %508 + %4927 = OpVariable %_ptr_UniformConstant_508 UniformConstant + %510 = OpTypeSampledImage %151 + %float_0_5 = OpConstant %float 0.5 + %int_1 = OpConstant %int 1 +%_ptr_PushConstant_v2float = OpTypePointer PushConstant %v2float +%_ptr_Output_v4float = OpTypePointer Output %v4float + %5312 = OpVariable %_ptr_Output_v4float Output + %1566 = OpConstantComposite %v2float %float_0_5 %float_0_5 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %2604 = OpConstantComposite %v3float %float_0 %float_0 %float_0 + %2582 = OpConstantComposite %v3float %float_1 %float_1 %float_1 + %10264 = OpUndef %v4float + %5663 = OpFunction %void None %1282 + %24953 = OpLabel + %18411 = OpVariable %_ptr_Function__arr_float_uint_256 Function + %22087 = OpLoad %v4float %gl_FragCoord + %6562 = OpVectorShuffle %v2float %22087 %22087 0 1 + %17656 = OpConvertFToS %v2int %6562 + %19279 = OpAccessChain %_ptr_PushConstant_v2int %3305 %int_0 + %22822 = OpLoad %v2int %19279 + %23236 = OpISub %v2int %17656 %22822 + %10630 = OpBitcast %v2uint %23236 + %14905 = OpLoad %151 %4448 + %16965 = OpLoad %508 %4927 + %8907 = OpSampledImage %510 %14905 %16965 + %13759 = OpConvertUToF %v2float %10630 + %15917 = OpFAdd %v2float %13759 %1566 + %11863 = OpAccessChain %_ptr_PushConstant_v2float %3305 %int_1 + %20800 = OpLoad %v2float %11863 + %24336 = OpFMul %v2float %15917 %20800 + %9248 = OpImageSampleExplicitLod %v4float %8907 %24336 Lod %float_0 + %21554 = OpCompositeExtract %float %9248 0 + %14517 = OpCompositeInsert %v4float %21554 %10264 0 + %19852 = OpCompositeExtract %float %9248 1 + %16135 = OpCompositeInsert %v4float %19852 %14517 1 + %19814 = OpCompositeExtract %float %9248 2 + %18704 = OpCompositeInsert %v4float %19814 %16135 2 + %15997 = OpVectorShuffle %v3float %18704 %18704 0 1 2 + %12552 = OpBitwiseAnd %v2uint %10630 %2122 + %9741 = OpCompositeExtract %uint %12552 1 + %21498 = OpIMul %uint %9741 %uint_16 + %23411 = OpCompositeExtract %uint %12552 0 + %12610 = OpIAdd %uint %21498 %23411 + OpStore %18411 %1947 + %9958 = OpAccessChain %_ptr_Function_float %18411 %12610 + %25140 = OpLoad %float %9958 + %18028 = OpCompositeConstruct %v3float %25140 %25140 %25140 + %21458 = OpFAdd %v3float %15997 %18028 + %19525 = OpExtInst %v3float %1 FClamp %21458 %2604 %2582 + %16777 = OpCompositeExtract %float %19525 0 + %19708 = OpCompositeExtract %float %19525 1 + %7472 = OpCompositeExtract %float %19525 2 + %22408 = OpCompositeConstruct %v4float %16777 %19708 %7472 %float_1 + OpStore %5312 %22408 + OpReturn + OpFunctionEnd +#endif + +const uint32_t guest_output_bilinear_dither_ps[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006235, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0007000F, 0x00000004, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000C93, 0x000014C0, 0x00030010, + 0x0000161F, 0x00000007, 0x00040047, 0x00000C93, 0x0000000B, 0x0000000F, 0x00030047, 0x00000404, + 0x00000002, 0x00050048, 0x00000404, 0x00000000, 0x00000023, 0x00000010, 0x00050048, 0x00000404, + 0x00000001, 0x00000023, 0x00000018, 0x00040047, 0x00001160, 0x00000021, 0x00000000, 0x00040047, + 0x00001160, 0x00000022, 0x00000000, 0x00040047, 0x0000133F, 0x00000021, 0x00000001, 0x00040047, + 0x0000133F, 0x00000022, 0x00000000, 0x00040047, 0x000014C0, 0x0000001E, 0x00000000, 0x00020013, + 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00030016, 0x0000000D, 0x00000020, 0x00040020, + 0x0000028A, 0x00000007, 0x0000000D, 0x00040017, 0x00000018, 0x0000000D, 0x00000003, 0x00040015, + 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x0004002B, + 0x0000000D, 0x00000A0C, 0x00000000, 0x0004002B, 0x0000000D, 0x0000008A, 0x3F800000, 0x0004002B, + 0x0000000B, 0x00000A37, 0x0000000F, 0x0004002B, 0x0000000B, 0x00000147, 0x00000100, 0x0004001C, + 0x000002D4, 0x0000000D, 0x00000147, 0x0004002B, 0x0000000D, 0x0000010F, 0xBA838384, 0x0004002B, + 0x0000000D, 0x00000728, 0x3A66E6E7, 0x0004002B, 0x0000000D, 0x00000705, 0x3ADDDDDE, 0x0004002B, + 0x0000000D, 0x00000A5A, 0xBACBCBCC, 0x0004002B, 0x0000000D, 0x000008DF, 0x3AA7A7A8, 0x0004002B, + 0x0000000D, 0x00000094, 0xBA1E9E9F, 0x0004002B, 0x0000000D, 0x0000034C, 0x3A8B8B8C, 0x0004002B, + 0x0000000D, 0x0000087E, 0xBAB5B5B6, 0x0004002B, 0x0000000D, 0x0000034D, 0x3AB1B1B2, 0x0004002B, + 0x0000000D, 0x00000687, 0x3A068687, 0x0004002B, 0x0000000D, 0x000003EB, 0x3A9F9FA0, 0x0004002B, + 0x0000000D, 0x0000024E, 0xBAD1D1D2, 0x0004002B, 0x0000000D, 0x00000726, 0x3A1A9A9B, 0x0004002B, + 0x0000000D, 0x00000698, 0xB9949495, 0x0004002B, 0x0000000D, 0x00000703, 0x3A919192, 0x0004002B, + 0x0000000D, 0x00000AF8, 0xBAB9B9BA, 0x0004002B, 0x0000000D, 0x00000ABB, 0x3ABDBDBE, 0x0004002B, + 0x0000000D, 0x0000026F, 0xBA0E8E8F, 0x0004002B, 0x0000000D, 0x000008A8, 0x39088889, 0x0004002B, + 0x0000000D, 0x00000565, 0xBA9D9D9E, 0x0004002B, 0x0000000D, 0x0000065D, 0x39E4E4E5, 0x0004002B, + 0x0000000D, 0x000004C6, 0xBA89898A, 0x0004002B, 0x0000000D, 0x00000057, 0x3A22A2A3, 0x0004002B, + 0x0000000D, 0x0000006A, 0xB9FCFCFD, 0x0004002B, 0x0000000D, 0x00000A1E, 0x3AF5F5F6, 0x0004002B, + 0x0000000D, 0x0000087D, 0xBA8F8F90, 0x0004002B, 0x0000000D, 0x00000959, 0xB8D0D0D1, 0x0004002B, + 0x0000000D, 0x00000BB8, 0xBA0A8A8B, 0x0004002B, 0x0000000D, 0x0000097E, 0x3ABBBBBC, 0x0004002B, + 0x0000000D, 0x00000606, 0xBAFDFDFE, 0x0004002B, 0x0000000D, 0x000003AD, 0xBA36B6B7, 0x0004002B, + 0x0000000D, 0x000000E2, 0x3820A0A1, 0x0004002B, 0x0000000D, 0x00000370, 0x3A3ABABB, 0x0004002B, + 0x0000000D, 0x0000024D, 0xBAABABAC, 0x0004002B, 0x0000000D, 0x000005C6, 0x3A8F8F90, 0x0004002B, + 0x0000000D, 0x00000B8C, 0xB99C9C9D, 0x0004002B, 0x0000000D, 0x00000036, 0x3AE5E5E6, 0x0004002B, + 0x0000000D, 0x0000087F, 0xBADBDBDC, 0x0004002B, 0x0000000D, 0x00000172, 0x3AC1C1C2, 0x0004002B, + 0x0000000D, 0x00000399, 0xB820A0A1, 0x0004002B, 0x0000000D, 0x0000040F, 0x3A4ECECF, 0x0004002B, + 0x0000000D, 0x0000091E, 0xBAEFEFF0, 0x0004002B, 0x0000000D, 0x000008D5, 0x399C9C9D, 0x0004002B, + 0x0000000D, 0x000008DE, 0x3A818182, 0x0004002B, 0x0000000D, 0x000002EB, 0xBA99999A, 0x0004002B, + 0x0000000D, 0x00000317, 0x3938B8B9, 0x0004002B, 0x0000000D, 0x0000034E, 0x3AD7D7D8, 0x0004002B, + 0x0000000D, 0x00000111, 0xBACFCFD0, 0x0004002B, 0x0000000D, 0x0000002B, 0x39B4B4B5, 0x0004002B, + 0x0000000D, 0x000008E1, 0x3AF3F3F4, 0x0004002B, 0x0000000D, 0x0000042A, 0xBAE7E7E8, 0x0004002B, + 0x0000000D, 0x00000765, 0xBA62E2E3, 0x0004002B, 0x0000000D, 0x000009A2, 0x3A6AEAEB, 0x0004002B, + 0x0000000D, 0x000004F2, 0x3928A8A9, 0x0004002B, 0x0000000D, 0x0000058A, 0xBA72F2F3, 0x0004002B, + 0x0000000D, 0x000007E0, 0xBAC7C7C8, 0x0004002B, 0x0000000D, 0x00000802, 0xBA2AAAAB, 0x0004002B, + 0x0000000D, 0x00000A1C, 0x3AA9A9AA, 0x0004002B, 0x0000000D, 0x00000940, 0xBA52D2D3, 0x0004002B, + 0x0000000D, 0x000002EC, 0xBABFBFC0, 0x0004002B, 0x0000000D, 0x000003ED, 0x3AEBEBEC, 0x0004002B, + 0x0000000D, 0x000004EB, 0xBA5EDEDF, 0x0004002B, 0x0000000D, 0x00000234, 0x3A5EDEDF, 0x0004002B, + 0x0000000D, 0x00000245, 0xB9ECECED, 0x0004002B, 0x0000000D, 0x00000603, 0xBA8B8B8C, 0x0004002B, + 0x0000000D, 0x00000984, 0xB9189899, 0x0004002B, 0x0000000D, 0x0000076E, 0x3978F8F9, 0x0004002B, + 0x0000000D, 0x00000841, 0x3AB9B9BA, 0x0004002B, 0x0000000D, 0x000009DD, 0xBA1A9A9B, 0x0004002B, + 0x0000000D, 0x000003F3, 0xB948C8C9, 0x0004002B, 0x0000000D, 0x00000B5A, 0x3AD1D1D2, 0x0004002B, + 0x0000000D, 0x00000B58, 0x3A858586, 0x0004002B, 0x0000000D, 0x00000838, 0x39D4D4D5, 0x0004002B, + 0x0000000D, 0x00000218, 0xB958D8D9, 0x0004002B, 0x0000000D, 0x00000A1D, 0x3ACFCFD0, 0x0004002B, + 0x0000000D, 0x0000054B, 0x3A2AAAAB, 0x0004002B, 0x0000000D, 0x00000503, 0xB8909091, 0x0004002B, + 0x0000000D, 0x00000169, 0x39DCDCDD, 0x0004002B, 0x0000000D, 0x00000605, 0xBAD7D7D8, 0x0004002B, + 0x0000000D, 0x0000048A, 0x3AB3B3B4, 0x0004002B, 0x0000000D, 0x000002D3, 0x3A72F2F3, 0x0004002B, + 0x0000000D, 0x00000A7C, 0xBA2EAEAF, 0x0004002B, 0x0000000D, 0x00000171, 0x3A9B9B9C, 0x0004002B, + 0x0000000D, 0x000001AF, 0xBABDBDBE, 0x0004002B, 0x0000000D, 0x000004AC, 0x3A169697, 0x0004002B, + 0x0000000D, 0x0000024F, 0xBAF7F7F8, 0x0004002B, 0x0000000D, 0x00000ADE, 0x3A46C6C7, 0x0004002B, + 0x0000000D, 0x00000110, 0xBAA9A9AA, 0x0004002B, 0x0000000D, 0x00000212, 0x3AFBFBFC, 0x0004002B, + 0x0000000D, 0x00000742, 0xBAD9D9DA, 0x0004002B, 0x0000000D, 0x00000389, 0xBA878788, 0x0004002B, + 0x0000000D, 0x000006C4, 0xBA028283, 0x0004002B, 0x0000000D, 0x00000B98, 0xBAF3F3F4, 0x0004002B, + 0x0000000D, 0x000002AE, 0x3A9D9D9E, 0x0004002B, 0x0000000D, 0x000009B1, 0xB9ACACAD, 0x0004002B, + 0x0000000D, 0x00000741, 0xBAB3B3B4, 0x0004002B, 0x0000000D, 0x00000211, 0x3AD5D5D6, 0x0004002B, + 0x0000000D, 0x00000A5B, 0xBAF1F1F2, 0x0004002B, 0x0000000D, 0x000005EA, 0x3A3EBEBF, 0x0004002B, + 0x0000000D, 0x00000310, 0xBA6EEEEF, 0x0004002B, 0x0000000D, 0x0000052A, 0x3AEDEDEE, 0x0004002B, + 0x0000000D, 0x00000071, 0xBA959596, 0x0004002B, 0x0000000D, 0x00000107, 0xB9C4C4C5, 0x0004002B, + 0x0000000D, 0x000006A2, 0x38D0D0D1, 0x0004002B, 0x0000000D, 0x00000B1B, 0xBA42C2C3, 0x0004002B, + 0x0000000D, 0x00000034, 0x3A99999A, 0x0004002B, 0x0000000D, 0x0000024B, 0x38909091, 0x0004002B, + 0x0000000D, 0x000002AF, 0x3AC3C3C4, 0x0004002B, 0x0000000D, 0x00000A41, 0x3A7EFEFF, 0x0004002B, + 0x0000000D, 0x00000A7E, 0xBA7AFAFB, 0x0004002B, 0x0000000D, 0x0000034F, 0x3AFDFDFE, 0x0004002B, + 0x0000000D, 0x00000901, 0x3A0A8A8B, 0x0004002B, 0x0000000D, 0x00000539, 0x3860E0E1, 0x0004002B, + 0x0000000D, 0x0000091C, 0xBAA3A3A4, 0x0004002B, 0x0000000D, 0x000001A4, 0xB98C8C8D, 0x0004002B, + 0x0000000D, 0x00000666, 0x3AC9C9CA, 0x0004002B, 0x0000000D, 0x00000833, 0xB7008081, 0x0004002B, + 0x0000000D, 0x00000206, 0x39A4A4A5, 0x0004002B, 0x0000000D, 0x00000210, 0x3AAFAFB0, 0x0004002B, + 0x0000000D, 0x000002ED, 0xBAE5E5E6, 0x0004002B, 0x0000000D, 0x0000040D, 0x3A028283, 0x0004002B, + 0x0000000D, 0x00000428, 0xBA9B9B9C, 0x0004002B, 0x0000000D, 0x00000195, 0x3A4ACACB, 0x0004002B, + 0x0000000D, 0x000004C7, 0xBAAFAFB0, 0x0004002B, 0x0000000D, 0x00000AB0, 0x398C8C8D, 0x0004002B, + 0x0000000D, 0x00000429, 0xBAC1C1C2, 0x0004002B, 0x0000000D, 0x00000B5F, 0xB9088889, 0x0004002B, + 0x0000000D, 0x0000044C, 0xBA4ACACB, 0x0004002B, 0x0000000D, 0x00000B59, 0x3AABABAC, 0x0004002B, + 0x0000000D, 0x00000344, 0x39CCCCCD, 0x0004002B, 0x0000000D, 0x000007C7, 0x3A7AFAFB, 0x0004002B, + 0x0000000D, 0x00000739, 0xB9F4F4F5, 0x0004002B, 0x0000000D, 0x0000091D, 0xBAC9C9CA, 0x0004002B, + 0x0000000D, 0x000000D2, 0x3A878788, 0x0004002B, 0x0000000D, 0x00000133, 0xBA32B2B3, 0x0004002B, + 0x0000000D, 0x000005C8, 0x3ADBDBDC, 0x0004002B, 0x0000000D, 0x00000A1B, 0x3A838384, 0x0004002B, + 0x0000000D, 0x00000420, 0xB9DCDCDD, 0x0004002B, 0x0000000D, 0x000002B0, 0x3AE9E9EA, 0x0004002B, + 0x0000000D, 0x00000A25, 0xB978F8F9, 0x0004002B, 0x0000000D, 0x0000030E, 0xBA22A2A3, 0x0004002B, + 0x0000000D, 0x0000048B, 0x3AD9D9DA, 0x0004002B, 0x0000000D, 0x00000B7D, 0x3A5ADADB, 0x0004002B, + 0x0000000D, 0x00000073, 0xBAE1E1E2, 0x0004002B, 0x0000000D, 0x00000740, 0xBA8D8D8E, 0x0004002B, + 0x0000000D, 0x00000173, 0x3AE7E7E8, 0x0004002B, 0x0000000D, 0x000006C6, 0xBA4ECECF, 0x0004002B, + 0x0000000D, 0x00000567, 0xBAE9E9EA, 0x0004002B, 0x0000000D, 0x00000A3F, 0x3A32B2B3, 0x0004002B, + 0x0000000D, 0x00000B95, 0xBA818182, 0x0004002B, 0x0000000D, 0x0000038A, 0xBAADADAE, 0x0004002B, + 0x0000000D, 0x000005CE, 0xB938B8B9, 0x0004002B, 0x0000000D, 0x000006A3, 0xBAC5C5C6, 0x0004002B, + 0x0000000D, 0x000006FA, 0x39ACACAD, 0x0004002B, 0x0000000D, 0x00000743, 0xBB000000, 0x0004002B, + 0x0000000D, 0x000007C5, 0x3A2EAEAF, 0x0004002B, 0x0000000D, 0x0000038B, 0xBAD3D3D4, 0x0004002B, + 0x0000000D, 0x00000ABA, 0x3A979798, 0x0004002B, 0x0000000D, 0x00000B51, 0x39ECECED, 0x0004002B, + 0x0000000D, 0x00000914, 0xB9E4E4E5, 0x0004002B, 0x0000000D, 0x0000013C, 0x3948C8C9, 0x0004002B, + 0x0000000D, 0x00000566, 0xBAC3C3C4, 0x0004002B, 0x0000000D, 0x0000097D, 0x3A959596, 0x0004002B, + 0x0000000D, 0x00000A58, 0x38B0B0B1, 0x0004002B, 0x0000000D, 0x00000B5B, 0x3AF7F7F8, 0x0004002B, + 0x0000000D, 0x00000704, 0x3AB7B7B8, 0x0004002B, 0x0000000D, 0x00000232, 0x3A129293, 0x0004002B, + 0x0000000D, 0x000002EE, 0x38F0F0F1, 0x0004002B, 0x0000000D, 0x000007A2, 0x3AA5A5A6, 0x0004002B, + 0x0000000D, 0x00000763, 0xBA169697, 0x0004002B, 0x0000000D, 0x00000135, 0xBA7EFEFF, 0x0004002B, + 0x0000000D, 0x000000D3, 0x3AADADAE, 0x0004002B, 0x0000000D, 0x00000949, 0x3968E8E9, 0x0004002B, + 0x0000000D, 0x000001D2, 0xBA46C6C7, 0x0004002B, 0x0000000D, 0x00000604, 0xBAB1B1B2, 0x0004002B, + 0x0000000D, 0x00000035, 0x3ABFBFC0, 0x0004002B, 0x0000000D, 0x000004AE, 0x3A62E2E3, 0x0004002B, + 0x0000000D, 0x000007D6, 0xB9BCBCBD, 0x0004002B, 0x0000000D, 0x00000B7B, 0x3A0E8E8F, 0x0004002B, + 0x0000000D, 0x00000AF7, 0xBA939394, 0x0004002B, 0x0000000D, 0x00000873, 0xB9848485, 0x0004002B, + 0x0000000D, 0x000004E9, 0xBA129293, 0x0004002B, 0x0000000D, 0x000007E1, 0xBAEDEDEE, 0x0004002B, + 0x0000000D, 0x0000097F, 0x3AE1E1E2, 0x0004002B, 0x0000000D, 0x000001AE, 0xBA979798, 0x0004002B, + 0x0000000D, 0x00000864, 0x3A42C2C3, 0x0004002B, 0x0000000D, 0x000008E0, 0x3ACDCDCE, 0x0004002B, + 0x0000000D, 0x000005A3, 0xB8F0F0F1, 0x0004002B, 0x0000000D, 0x000006A4, 0xBA9F9FA0, 0x0004002B, + 0x0000000D, 0x00000667, 0x3AEFEFF0, 0x0004002B, 0x0000000D, 0x00000961, 0x37C0C0C1, 0x0004002B, + 0x0000000D, 0x000004C9, 0xBAFBFBFC, 0x0004002B, 0x0000000D, 0x00000ABC, 0x3AE3E3E4, 0x0004002B, + 0x0000000D, 0x00000627, 0xBA3ABABB, 0x0004002B, 0x0000000D, 0x000007A3, 0x3ACBCBCC, 0x0004002B, + 0x0000000D, 0x00000AF9, 0xBADFDFE0, 0x0004002B, 0x0000000D, 0x00000528, 0x3AA1A1A2, 0x0004002B, + 0x0000000D, 0x00000B24, 0x3958D8D9, 0x0004002B, 0x0000000D, 0x0000020F, 0x3A89898A, 0x0004002B, + 0x0000000D, 0x000008A1, 0xBA3EBEBF, 0x0004002B, 0x0000000D, 0x000004C8, 0xBAD5D5D6, 0x0004002B, + 0x0000000D, 0x000004BD, 0xB9A4A4A5, 0x0004002B, 0x0000000D, 0x00000976, 0x39FCFCFD, 0x0004002B, + 0x0000000D, 0x000006A5, 0xBAEBEBEC, 0x0004002B, 0x0000000D, 0x0000054D, 0x3A76F6F7, 0x0004002B, + 0x0000000D, 0x000002E2, 0xB9B4B4B5, 0x0004002B, 0x0000000D, 0x000000F6, 0x3A36B6B7, 0x0004002B, + 0x0000000D, 0x0000024C, 0xBA858586, 0x0004002B, 0x0000000D, 0x00000B97, 0xBACDCDCE, 0x0004002B, + 0x0000000D, 0x00000055, 0xB7C0C0C1, 0x0004002B, 0x0000000D, 0x00000B96, 0xBAA7A7A8, 0x0004002B, + 0x0000000D, 0x00000689, 0x3A52D2D3, 0x0004002B, 0x0000000D, 0x00000096, 0xBA6AEAEB, 0x0004002B, + 0x0000000D, 0x00000072, 0xBABBBBBC, 0x0004002B, 0x0000000D, 0x000009A0, 0x3A1E9E9F, 0x0004002B, + 0x0000000D, 0x0000014C, 0xB8B0B0B1, 0x0004002B, 0x0000000D, 0x00000059, 0x3A6EEEEF, 0x0004002B, + 0x0000000D, 0x0000048C, 0x3B000000, 0x0004002B, 0x0000000D, 0x000009BB, 0xBAB7B7B8, 0x0004002B, + 0x0000000D, 0x00000588, 0xBA26A6A7, 0x0004002B, 0x0000000D, 0x000003EC, 0x3AC5C5C6, 0x0004002B, + 0x0000000D, 0x00000BBA, 0xBA56D6D7, 0x0004002B, 0x0000000D, 0x00000665, 0x3AA3A3A4, 0x0004002B, + 0x0000000D, 0x000005BC, 0x39848485, 0x0004002B, 0x0000000D, 0x00000529, 0x3AC7C7C8, 0x0004002B, + 0x0000000D, 0x00000840, 0x3A939394, 0x0004002B, 0x0000000D, 0x0000051F, 0x39BCBCBD, 0x0004002B, + 0x0000000D, 0x000005FB, 0xB9CCCCCD, 0x0004002B, 0x0000000D, 0x000000D5, 0x3AF9F9FA, 0x0004002B, + 0x0000000D, 0x000005C7, 0x3AB5B5B6, 0x0004002B, 0x0000000D, 0x000009BA, 0xBA919192, 0x0004002B, + 0x0000000D, 0x000000D4, 0x3AD3D3D4, 0x0004002B, 0x0000000D, 0x000009DF, 0xBA66E6E7, 0x0004002B, + 0x0000000D, 0x000006CD, 0x39189899, 0x0004002B, 0x0000000D, 0x00000489, 0x3A8D8D8E, 0x0004002B, + 0x0000000D, 0x000007F0, 0xB860E0E1, 0x0004002B, 0x0000000D, 0x000003E1, 0x39949495, 0x0004002B, + 0x0000000D, 0x000009BC, 0xBADDDDDE, 0x0004002B, 0x0000000D, 0x00000A59, 0xBAA5A5A6, 0x0004002B, + 0x0000000D, 0x0000093E, 0xBA068687, 0x0004002B, 0x0000000D, 0x000007A9, 0xB928A8A9, 0x0004002B, + 0x0000000D, 0x00000112, 0xBAF5F5F6, 0x0004002B, 0x0000000D, 0x00000271, 0xBA5ADADB, 0x0004002B, + 0x0000000D, 0x000002D1, 0x3A26A6A7, 0x0004002B, 0x0000000D, 0x0000057C, 0x37008081, 0x0004002B, + 0x0000000D, 0x0000038C, 0xBAF9F9FA, 0x0004002B, 0x0000000D, 0x0000003D, 0xB968E8E9, 0x0004002B, + 0x0000000D, 0x00000A13, 0x39C4C4C5, 0x0004002B, 0x0000000D, 0x000001B0, 0xBAE3E3E4, 0x0004002B, + 0x0000000D, 0x00000AEF, 0xB9D4D4D5, 0x0004002B, 0x0000000D, 0x000007DF, 0xBAA1A1A2, 0x0004002B, + 0x0000000D, 0x00000842, 0x3ADFDFE0, 0x0004002B, 0x0000000D, 0x00000804, 0xBA76F6F7, 0x0004002B, + 0x0000000D, 0x00000903, 0x3A56D6D7, 0x0004002B, 0x0000000D, 0x000007A4, 0x3AF1F1F2, 0x0004002B, + 0x0000000D, 0x00000482, 0x39F4F4F5, 0x0103002C, 0x000002D4, 0x0000079B, 0x0000010F, 0x00000728, + 0x00000705, 0x00000A5A, 0x000008DF, 0x00000094, 0x0000034C, 0x0000087E, 0x0000034D, 0x00000687, + 0x000003EB, 0x0000024E, 0x00000726, 0x00000698, 0x00000703, 0x00000AF8, 0x00000ABB, 0x0000026F, + 0x000008A8, 0x00000565, 0x0000065D, 0x000004C6, 0x00000057, 0x0000006A, 0x00000A1E, 0x0000087D, + 0x00000959, 0x00000BB8, 0x0000097E, 0x00000606, 0x000003AD, 0x000000E2, 0x00000370, 0x0000024D, + 0x000005C6, 0x00000B8C, 0x00000036, 0x0000087F, 0x00000172, 0x00000399, 0x0000040F, 0x0000091E, + 0x000008D5, 0x000008DE, 0x000002EB, 0x00000317, 0x0000034E, 0x00000111, 0x0000002B, 0x000008E1, + 0x0000042A, 0x00000765, 0x000009A2, 0x000004F2, 0x0000058A, 0x000007E0, 0x00000802, 0x00000A1C, + 0x00000940, 0x000002EC, 0x000003ED, 0x000004EB, 0x00000234, 0x00000245, 0x00000603, 0x00000984, + 0x0000076E, 0x00000841, 0x000009DD, 0x000003F3, 0x00000B5A, 0x00000B58, 0x00000838, 0x00000218, + 0x00000A1D, 0x0000054B, 0x00000503, 0x00000169, 0x00000605, 0x0000048A, 0x000002D3, 0x00000A7C, + 0x00000171, 0x000001AF, 0x000004AC, 0x0000024F, 0x00000ADE, 0x00000110, 0x00000212, 0x00000742, + 0x00000389, 0x000006C4, 0x00000B98, 0x000002AE, 0x000009B1, 0x00000741, 0x00000211, 0x00000A5B, + 0x000005EA, 0x00000310, 0x0000052A, 0x00000071, 0x00000107, 0x000006A2, 0x00000B1B, 0x00000034, + 0x0000024B, 0x000002AF, 0x00000A41, 0x00000A7E, 0x0000034F, 0x00000901, 0x00000539, 0x0000091C, + 0x000001A4, 0x00000666, 0x00000833, 0x00000206, 0x00000210, 0x000002ED, 0x0000040D, 0x00000428, + 0x00000195, 0x000004C7, 0x00000AB0, 0x00000429, 0x00000B5F, 0x0000044C, 0x00000B59, 0x00000344, + 0x000007C7, 0x00000739, 0x0000091D, 0x000000D2, 0x00000133, 0x000005C8, 0x00000A1B, 0x00000420, + 0x000002B0, 0x00000A25, 0x0000030E, 0x0000048B, 0x00000B7D, 0x00000073, 0x00000740, 0x00000173, + 0x000006C6, 0x00000567, 0x00000A3F, 0x00000B95, 0x0000038A, 0x000005CE, 0x000006A3, 0x000006FA, + 0x00000743, 0x000007C5, 0x0000038B, 0x00000ABA, 0x00000B51, 0x00000914, 0x0000013C, 0x00000566, + 0x0000097D, 0x00000A58, 0x00000B5B, 0x00000704, 0x00000232, 0x000002EE, 0x000007A2, 0x00000763, + 0x00000135, 0x000000D3, 0x00000949, 0x000001D2, 0x00000604, 0x00000035, 0x000004AE, 0x000007D6, + 0x00000B7B, 0x00000AF7, 0x00000873, 0x000004E9, 0x000007E1, 0x0000097F, 0x000001AE, 0x00000864, + 0x000008E0, 0x000005A3, 0x000006A4, 0x00000667, 0x00000961, 0x000004C9, 0x00000ABC, 0x00000627, + 0x000007A3, 0x00000AF9, 0x00000528, 0x00000B24, 0x0000020F, 0x000008A1, 0x000004C8, 0x000004BD, + 0x00000976, 0x000006A5, 0x0000054D, 0x000002E2, 0x000000F6, 0x0000024C, 0x00000B97, 0x00000055, + 0x00000B96, 0x00000689, 0x00000096, 0x00000072, 0x000009A0, 0x0000014C, 0x00000059, 0x0000048C, + 0x000009BB, 0x00000588, 0x000003EC, 0x00000BBA, 0x00000665, 0x000005BC, 0x00000529, 0x00000840, + 0x0000051F, 0x000005FB, 0x000000D5, 0x000005C7, 0x000009BA, 0x000000D4, 0x000009DF, 0x000006CD, + 0x00000489, 0x000007F0, 0x000003E1, 0x000009BC, 0x00000A59, 0x0000093E, 0x000007A9, 0x00000112, + 0x00000271, 0x000002D1, 0x0000057C, 0x0000038C, 0x0000003D, 0x00000A13, 0x000001B0, 0x00000AEF, + 0x000007DF, 0x00000842, 0x00000804, 0x00000903, 0x000007A4, 0x00000482, 0x0004002B, 0x0000000B, + 0x00000A3A, 0x00000010, 0x00040020, 0x00000551, 0x00000007, 0x000002D4, 0x00040017, 0x0000001D, + 0x0000000D, 0x00000004, 0x00040020, 0x0000029A, 0x00000001, 0x0000001D, 0x0004003B, 0x0000029A, + 0x00000C93, 0x00000001, 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x00040015, 0x0000000C, + 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x0004001E, 0x00000404, + 0x00000012, 0x00000013, 0x00040020, 0x00000681, 0x00000009, 0x00000404, 0x0004003B, 0x00000681, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x0000028F, + 0x00000009, 0x00000012, 0x00090019, 0x00000097, 0x0000000D, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00040020, 0x00000313, 0x00000000, 0x00000097, 0x0004003B, + 0x00000313, 0x00001160, 0x00000000, 0x0002001A, 0x000001FC, 0x00040020, 0x00000479, 0x00000000, + 0x000001FC, 0x0004003B, 0x00000479, 0x0000133F, 0x00000000, 0x0003001B, 0x000001FE, 0x00000097, + 0x0004002B, 0x0000000D, 0x000000FC, 0x3F000000, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x00040020, 0x00000290, 0x00000009, 0x00000013, 0x00040020, 0x0000029B, 0x00000003, 0x0000001D, + 0x0004003B, 0x0000029B, 0x000014C0, 0x00000003, 0x0005002C, 0x00000013, 0x0000061E, 0x000000FC, + 0x000000FC, 0x0005002C, 0x00000011, 0x0000084A, 0x00000A37, 0x00000A37, 0x0006002C, 0x00000018, + 0x00000A2C, 0x00000A0C, 0x00000A0C, 0x00000A0C, 0x0006002C, 0x00000018, 0x00000A16, 0x0000008A, + 0x0000008A, 0x0000008A, 0x00030001, 0x0000001D, 0x00002818, 0x00050036, 0x00000008, 0x0000161F, + 0x00000000, 0x00000502, 0x000200F8, 0x00006179, 0x0004003B, 0x00000551, 0x000047EB, 0x00000007, + 0x0004003D, 0x0000001D, 0x00005647, 0x00000C93, 0x0007004F, 0x00000013, 0x000019A2, 0x00005647, + 0x00005647, 0x00000000, 0x00000001, 0x0004006E, 0x00000012, 0x000044F8, 0x000019A2, 0x00050041, + 0x0000028F, 0x00004B4F, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x00000012, 0x00005926, 0x00004B4F, + 0x00050082, 0x00000012, 0x00005AC4, 0x000044F8, 0x00005926, 0x0004007C, 0x00000011, 0x00002986, + 0x00005AC4, 0x0004003D, 0x00000097, 0x00003A39, 0x00001160, 0x0004003D, 0x000001FC, 0x00004245, + 0x0000133F, 0x00050056, 0x000001FE, 0x000022CB, 0x00003A39, 0x00004245, 0x00040070, 0x00000013, + 0x000035BF, 0x00002986, 0x00050081, 0x00000013, 0x00003E2D, 0x000035BF, 0x0000061E, 0x00050041, + 0x00000290, 0x00002E57, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x00000013, 0x00005140, 0x00002E57, + 0x00050085, 0x00000013, 0x00005F10, 0x00003E2D, 0x00005140, 0x00070058, 0x0000001D, 0x00002420, + 0x000022CB, 0x00005F10, 0x00000002, 0x00000A0C, 0x00050051, 0x0000000D, 0x00005432, 0x00002420, + 0x00000000, 0x00060052, 0x0000001D, 0x000038B5, 0x00005432, 0x00002818, 0x00000000, 0x00050051, + 0x0000000D, 0x00004D8C, 0x00002420, 0x00000001, 0x00060052, 0x0000001D, 0x00003F07, 0x00004D8C, + 0x000038B5, 0x00000001, 0x00050051, 0x0000000D, 0x00004D66, 0x00002420, 0x00000002, 0x00060052, + 0x0000001D, 0x00004910, 0x00004D66, 0x00003F07, 0x00000002, 0x0008004F, 0x00000018, 0x00003E7D, + 0x00004910, 0x00004910, 0x00000000, 0x00000001, 0x00000002, 0x000500C7, 0x00000011, 0x00003108, + 0x00002986, 0x0000084A, 0x00050051, 0x0000000B, 0x0000260D, 0x00003108, 0x00000001, 0x00050084, + 0x0000000B, 0x000053FA, 0x0000260D, 0x00000A3A, 0x00050051, 0x0000000B, 0x00005B73, 0x00003108, + 0x00000000, 0x00050080, 0x0000000B, 0x00003142, 0x000053FA, 0x00005B73, 0x0003003E, 0x000047EB, + 0x0000079B, 0x00050041, 0x0000028A, 0x000026E6, 0x000047EB, 0x00003142, 0x0004003D, 0x0000000D, + 0x00006234, 0x000026E6, 0x00060050, 0x00000018, 0x0000466C, 0x00006234, 0x00006234, 0x00006234, + 0x00050081, 0x00000018, 0x000053D2, 0x00003E7D, 0x0000466C, 0x0008000C, 0x00000018, 0x00004C45, + 0x00000001, 0x0000002B, 0x000053D2, 0x00000A2C, 0x00000A16, 0x00050051, 0x0000000D, 0x00004189, + 0x00004C45, 0x00000000, 0x00050051, 0x0000000D, 0x00004CFC, 0x00004C45, 0x00000001, 0x00050051, + 0x0000000D, 0x00001D30, 0x00004C45, 0x00000002, 0x00070050, 0x0000001D, 0x00005788, 0x00004189, + 0x00004CFC, 0x00001D30, 0x0000008A, 0x0003003E, 0x000014C0, 0x00005788, 0x000100FD, 0x00010038, +}; diff --git a/src/ui/shaders/vulkan_spirv/guest_output_bilinear_ps.h b/src/ui/shaders/vulkan_spirv/guest_output_bilinear_ps.h new file mode 100644 index 0000000..26f9d25 --- /dev/null +++ b/src/ui/shaders/vulkan_spirv/guest_output_bilinear_ps.h @@ -0,0 +1,118 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 24950 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %5663 "main" %gl_FragCoord %5312 + OpExecutionMode %5663 OriginUpperLeft + OpDecorate %gl_FragCoord BuiltIn FragCoord + OpDecorate %_struct_1028 Block + OpMemberDecorate %_struct_1028 0 Offset 16 + OpMemberDecorate %_struct_1028 1 Offset 24 + OpDecorate %4448 Binding 0 + OpDecorate %4448 DescriptorSet 0 + OpDecorate %4927 Binding 1 + OpDecorate %4927 DescriptorSet 0 + OpDecorate %5312 Location 0 + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%gl_FragCoord = OpVariable %_ptr_Input_v4float Input + %v2float = OpTypeVector %float 2 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 +%_struct_1028 = OpTypeStruct %v2int %v2float +%_ptr_PushConstant__struct_1028 = OpTypePointer PushConstant %_struct_1028 + %3305 = OpVariable %_ptr_PushConstant__struct_1028 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_v2int = OpTypePointer PushConstant %v2int + %150 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_150 = OpTypePointer UniformConstant %150 + %4448 = OpVariable %_ptr_UniformConstant_150 UniformConstant + %508 = OpTypeSampler +%_ptr_UniformConstant_508 = OpTypePointer UniformConstant %508 + %4927 = OpVariable %_ptr_UniformConstant_508 UniformConstant + %510 = OpTypeSampledImage %150 + %float_0_5 = OpConstant %float 0.5 + %int_1 = OpConstant %int 1 +%_ptr_PushConstant_v2float = OpTypePointer PushConstant %v2float + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %5312 = OpVariable %_ptr_Output_v4float Output + %1566 = OpConstantComposite %v2float %float_0_5 %float_0_5 + %5663 = OpFunction %void None %1282 + %24949 = OpLabel + %18571 = OpLoad %v4float %gl_FragCoord + %14008 = OpVectorShuffle %v2float %18571 %18571 0 1 + %17656 = OpConvertFToS %v2int %14008 + %19279 = OpAccessChain %_ptr_PushConstant_v2int %3305 %int_0 + %22822 = OpLoad %v2int %19279 + %23236 = OpISub %v2int %17656 %22822 + %10630 = OpBitcast %v2uint %23236 + %14905 = OpLoad %150 %4448 + %16965 = OpLoad %508 %4927 + %8907 = OpSampledImage %510 %14905 %16965 + %13759 = OpConvertUToF %v2float %10630 + %15917 = OpFAdd %v2float %13759 %1566 + %11863 = OpAccessChain %_ptr_PushConstant_v2float %3305 %int_1 + %20800 = OpLoad %v2float %11863 + %24336 = OpFMul %v2float %15917 %20800 + %9229 = OpImageSampleExplicitLod %v4float %8907 %24336 Lod %float_0 + %21727 = OpCompositeExtract %float %9229 0 + %22672 = OpCompositeExtract %float %9229 1 + %7472 = OpCompositeExtract %float %9229 2 + %22408 = OpCompositeConstruct %v4float %21727 %22672 %7472 %float_1 + OpStore %5312 %22408 + OpReturn + OpFunctionEnd +#endif + +const uint32_t guest_output_bilinear_ps[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006176, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0007000F, 0x00000004, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000C93, 0x000014C0, 0x00030010, + 0x0000161F, 0x00000007, 0x00040047, 0x00000C93, 0x0000000B, 0x0000000F, 0x00030047, 0x00000404, + 0x00000002, 0x00050048, 0x00000404, 0x00000000, 0x00000023, 0x00000010, 0x00050048, 0x00000404, + 0x00000001, 0x00000023, 0x00000018, 0x00040047, 0x00001160, 0x00000021, 0x00000000, 0x00040047, + 0x00001160, 0x00000022, 0x00000000, 0x00040047, 0x0000133F, 0x00000021, 0x00000001, 0x00040047, + 0x0000133F, 0x00000022, 0x00000000, 0x00040047, 0x000014C0, 0x0000001E, 0x00000000, 0x00020013, + 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00030016, 0x0000000D, 0x00000020, 0x00040017, + 0x0000001D, 0x0000000D, 0x00000004, 0x00040020, 0x0000029A, 0x00000001, 0x0000001D, 0x0004003B, + 0x0000029A, 0x00000C93, 0x00000001, 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x00040015, + 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x0004001E, + 0x00000404, 0x00000012, 0x00000013, 0x00040020, 0x00000681, 0x00000009, 0x00000404, 0x0004003B, + 0x00000681, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, + 0x0000028F, 0x00000009, 0x00000012, 0x00090019, 0x00000096, 0x0000000D, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00040020, 0x00000313, 0x00000000, 0x00000096, + 0x0004003B, 0x00000313, 0x00001160, 0x00000000, 0x0002001A, 0x000001FC, 0x00040020, 0x00000479, + 0x00000000, 0x000001FC, 0x0004003B, 0x00000479, 0x0000133F, 0x00000000, 0x0003001B, 0x000001FE, + 0x00000096, 0x0004002B, 0x0000000D, 0x000000FC, 0x3F000000, 0x0004002B, 0x0000000C, 0x00000A0E, + 0x00000001, 0x00040020, 0x00000290, 0x00000009, 0x00000013, 0x0004002B, 0x0000000D, 0x00000A0C, + 0x00000000, 0x0004002B, 0x0000000D, 0x0000008A, 0x3F800000, 0x00040020, 0x0000029B, 0x00000003, + 0x0000001D, 0x0004003B, 0x0000029B, 0x000014C0, 0x00000003, 0x0005002C, 0x00000013, 0x0000061E, + 0x000000FC, 0x000000FC, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, + 0x00006175, 0x0004003D, 0x0000001D, 0x0000488B, 0x00000C93, 0x0007004F, 0x00000013, 0x000036B8, + 0x0000488B, 0x0000488B, 0x00000000, 0x00000001, 0x0004006E, 0x00000012, 0x000044F8, 0x000036B8, + 0x00050041, 0x0000028F, 0x00004B4F, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x00000012, 0x00005926, + 0x00004B4F, 0x00050082, 0x00000012, 0x00005AC4, 0x000044F8, 0x00005926, 0x0004007C, 0x00000011, + 0x00002986, 0x00005AC4, 0x0004003D, 0x00000096, 0x00003A39, 0x00001160, 0x0004003D, 0x000001FC, + 0x00004245, 0x0000133F, 0x00050056, 0x000001FE, 0x000022CB, 0x00003A39, 0x00004245, 0x00040070, + 0x00000013, 0x000035BF, 0x00002986, 0x00050081, 0x00000013, 0x00003E2D, 0x000035BF, 0x0000061E, + 0x00050041, 0x00000290, 0x00002E57, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x00000013, 0x00005140, + 0x00002E57, 0x00050085, 0x00000013, 0x00005F10, 0x00003E2D, 0x00005140, 0x00070058, 0x0000001D, + 0x0000240D, 0x000022CB, 0x00005F10, 0x00000002, 0x00000A0C, 0x00050051, 0x0000000D, 0x000054DF, + 0x0000240D, 0x00000000, 0x00050051, 0x0000000D, 0x00005890, 0x0000240D, 0x00000001, 0x00050051, + 0x0000000D, 0x00001D30, 0x0000240D, 0x00000002, 0x00070050, 0x0000001D, 0x00005788, 0x000054DF, + 0x00005890, 0x00001D30, 0x0000008A, 0x0003003E, 0x000014C0, 0x00005788, 0x000100FD, 0x00010038, +}; diff --git a/src/ui/shaders/vulkan_spirv/guest_output_ffx_cas_resample_dither_ps.h b/src/ui/shaders/vulkan_spirv/guest_output_ffx_cas_resample_dither_ps.h new file mode 100644 index 0000000..05d894b --- /dev/null +++ b/src/ui/shaders/vulkan_spirv/guest_output_ffx_cas_resample_dither_ps.h @@ -0,0 +1,1169 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25213 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %5663 "main" %gl_FragCoord %5334 + OpExecutionMode %5663 OriginUpperLeft + OpDecorate %gl_FragCoord BuiltIn FragCoord + OpDecorate %_struct_1048 Block + OpMemberDecorate %_struct_1048 0 Offset 16 + OpMemberDecorate %_struct_1048 1 Offset 24 + OpMemberDecorate %_struct_1048 2 Offset 32 + OpDecorate %5334 Location 0 + OpDecorate %5163 Binding 0 + OpDecorate %5163 DescriptorSet 0 + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %float = OpTypeFloat 32 +%_ptr_Function_float = OpTypePointer Function %float + %v3float = OpTypeVector %float 3 + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v4uint = OpTypeVector %uint 4 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 + %uint_15 = OpConstant %uint 15 + %uint_256 = OpConstant %uint 256 +%_arr_float_uint_256 = OpTypeArray %float %uint_256 +%float_n0_00100337015 = OpConstant %float -0.00100337015 +%float_0_000880821084 = OpConstant %float 0.000880821084 +%float_0_00169270835 = OpConstant %float 0.00169270835 +%float_n0_00155484071 = OpConstant %float -0.00155484071 +%float_0_00127910543 = OpConstant %float 0.00127910543 +%float_n0_000605085806 = OpConstant %float -0.000605085806 +%float_0_00106464466 = OpConstant %float 0.00106464466 +%float_n0_00138633582 = OpConstant %float -0.00138633582 +%float_0_00135569857 = OpConstant %float 0.00135569857 +%float_0_000513174047 = OpConstant %float 0.000513174047 +%float_0_00121783093 = OpConstant %float 0.00121783093 +%float_n0_00160079659 = OpConstant %float -0.00160079659 +%float_0_00058976718 = OpConstant %float 0.00058976718 +%float_n0_00028339462 = OpConstant %float -0.00028339462 +%float_0_00111060054 = OpConstant %float 0.00111060054 +%float_n0_00141697307 = OpConstant %float -0.00141697307 +%float_0_00144761032 = OpConstant %float 0.00144761032 +%float_n0_0005438113 = OpConstant %float -0.0005438113 +%float_0_00013020834 = OpConstant %float 0.00013020834 +%float_n0_0012025123 = OpConstant %float -0.0012025123 +%float_0_000436580885 = OpConstant %float 0.000436580885 +%float_n0_00104932603 = OpConstant %float -0.00104932603 +%float_0_000620404433 = OpConstant %float 0.000620404433 +%float_n0_000482536765 = OpConstant %float -0.000482536765 +%float_0_00187653187 = OpConstant %float 0.00187653187 +%float_n0_00109528191 = OpConstant %float -0.00109528191 +%float_n9_95710798en05 = OpConstant %float -9.95710798e-05 +%float_n0_000528492674 = OpConstant %float -0.000528492674 +%float_0_0014322917 = OpConstant %float 0.0014322917 +%float_n0_00193780637 = OpConstant %float -0.00193780637 +%float_n0_000696997566 = OpConstant %float -0.000696997566 +%float_3_829657en05 = OpConstant %float 3.829657e-05 +%float_0_000712316192 = OpConstant %float 0.000712316192 +%float_n0_00130974269 = OpConstant %float -0.00130974269 +%float_0_00109528191 = OpConstant %float 0.00109528191 +%float_n0_000298713247 = OpConstant %float -0.000298713247 +%float_0_00175398286 = OpConstant %float 0.00175398286 +%float_n0_00167738972 = OpConstant %float -0.00167738972 +%float_0_00147824758 = OpConstant %float 0.00147824758 +%float_n3_829657en05 = OpConstant %float -3.829657e-05 +%float_0_000788909325 = OpConstant %float 0.000788909325 +%float_n0_00183057599 = OpConstant %float -0.00183057599 +%float_0_000298713247 = OpConstant %float 0.000298713247 +%float_0_000988051528 = OpConstant %float 0.000988051528 +%float_n0_00117187505 = OpConstant %float -0.00117187505 +%float_0_00017616422 = OpConstant %float 0.00017616422 +%float_0_00164675247 = OpConstant %float 0.00164675247 +%float_n0_00158547796 = OpConstant %float -0.00158547796 +%float_0_000344669126 = OpConstant %float 0.000344669126 +%float_0_00186121324 = OpConstant %float 0.00186121324 +%float_n0_00176930148 = OpConstant %float -0.00176930148 +%float_n0_000865502458 = OpConstant %float -0.000865502458 +%float_0_000896139711 = OpConstant %float 0.000896139711 +%float_0_000160845593 = OpConstant %float 0.000160845593 +%float_n0_000926776964 = OpConstant %float -0.000926776964 +%float_n0_00152420346 = OpConstant %float -0.00152420346 +%float_n0_000651041686 = OpConstant %float -0.000651041686 +%float_0_00129442406 = OpConstant %float 0.00129442406 +%float_n0_000804227951 = OpConstant %float -0.000804227951 +%float_n0_00146292895 = OpConstant %float -0.00146292895 +%float_0_00179993873 = OpConstant %float 0.00179993873 +%float_n0_000850183831 = OpConstant %float -0.000850183831 +%float_0_000850183831 = OpConstant %float 0.000850183831 +%float_n0_000451899512 = OpConstant %float -0.000451899512 +%float_n0_00106464466 = OpConstant %float -0.00106464466 +%float_n0_000145526967 = OpConstant %float -0.000145526967 +%float_0_000237438726 = OpConstant %float 0.000237438726 +%float_0_00141697307 = OpConstant %float 0.00141697307 +%float_n0_00058976718 = OpConstant %float -0.00058976718 +%float_n0_000191482846 = OpConstant %float -0.000191482846 +%float_0_00160079659 = OpConstant %float 0.00160079659 +%float_0_00101868878 = OpConstant %float 0.00101868878 +%float_0_000405943632 = OpConstant %float 0.000405943632 +%float_n0_000206801473 = OpConstant %float -0.000206801473 +%float_0_00158547796 = OpConstant %float 0.00158547796 +%float_0_000651041686 = OpConstant %float 0.000651041686 +%float_n6_89338267en05 = OpConstant %float -6.89338267e-05 +%float_0_000421262259 = OpConstant %float 0.000421262259 +%float_n0_00164675247 = OpConstant %float -0.00164675247 +%float_0_00137101719 = OpConstant %float 0.00137101719 +%float_0_000926776964 = OpConstant %float 0.000926776964 +%float_n0_000666360313 = OpConstant %float -0.000666360313 +%float_0_00118719367 = OpConstant %float 0.00118719367 +%float_n0_00144761032 = OpConstant %float -0.00144761032 +%float_0_000574448553 = OpConstant %float 0.000574448553 +%float_n0_00189185049 = OpConstant %float -0.00189185049 +%float_0_000758272072 = OpConstant %float 0.000758272072 +%float_n0_00129442406 = OpConstant %float -0.00129442406 +%float_0_00192248775 = OpConstant %float 0.00192248775 +%float_n0_0016620711 = OpConstant %float -0.0016620711 +%float_n0_00103400741 = OpConstant %float -0.00103400741 +%float_n0_000497855421 = OpConstant %float -0.000497855421 +%float_n0_00186121324 = OpConstant %float -0.00186121324 +%float_0_0012025123 = OpConstant %float 0.0012025123 +%float_n0_0003293505 = OpConstant %float -0.0003293505 +%float_n0_00137101719 = OpConstant %float -0.00137101719 +%float_0_00163143384 = OpConstant %float 0.00163143384 +%float_n0_00184589461 = OpConstant %float -0.00184589461 +%float_0_000727634819 = OpConstant %float 0.000727634819 +%float_n0_000911458337 = OpConstant %float -0.000911458337 +%float_0_00181525736 = OpConstant %float 0.00181525736 +%float_n0_00114123779 = OpConstant %float -0.00114123779 +%float_n0_000375306379 = OpConstant %float -0.000375306379 +%float_9_95710798en05 = OpConstant %float 9.95710798e-05 +%float_n0_000742953445 = OpConstant %float -0.000742953445 +%float_0_00117187505 = OpConstant %float 0.00117187505 +%float_6_89338267en05 = OpConstant %float 6.89338267e-05 +%float_0_0014935662 = OpConstant %float 0.0014935662 +%float_0_000972732843 = OpConstant %float 0.000972732843 +%float_n0_000957414217 = OpConstant %float -0.000957414217 +%float_0_00193780637 = OpConstant %float 0.00193780637 +%float_0_000528492674 = OpConstant %float 0.000528492674 +%float_5_36151965en05 = OpConstant %float 5.36151965e-05 +%float_n0_00124846818 = OpConstant %float -0.00124846818 +%float_n0_000268075994 = OpConstant %float -0.000268075994 +%float_0_00153952208 = OpConstant %float 0.00153952208 +%float_n7_65931418en06 = OpConstant %float -7.65931418e-06 +%float_0_000314031873 = OpConstant %float 0.000314031873 +%float_0_00134037994 = OpConstant %float 0.00134037994 +%float_n0_00175398286 = OpConstant %float -0.00175398286 +%float_0_000497855421 = OpConstant %float 0.000497855421 +%float_n0_00118719367 = OpConstant %float -0.00118719367 +%float_0_000773590698 = OpConstant %float 0.000773590698 +%float_n0_00134037994 = OpConstant %float -0.00134037994 +%float_0_000268075994 = OpConstant %float 0.000268075994 +%float_n0_00147824758 = OpConstant %float -0.00147824758 +%float_n0_00013020834 = OpConstant %float -0.00013020834 +%float_n0_000773590698 = OpConstant %float -0.000773590698 +%float_0_00130974269 = OpConstant %float 0.00130974269 +%float_0_000390625006 = OpConstant %float 0.000390625006 +%float_0_000957414217 = OpConstant %float 0.000957414217 +%float_n0_000467218139 = OpConstant %float -0.000467218139 +%float_n0_00153952208 = OpConstant %float -0.00153952208 +%float_0_00103400741 = OpConstant %float 0.00103400741 +%float_n0_000681678939 = OpConstant %float -0.000681678939 +%float_0_00167738972 = OpConstant %float 0.00167738972 +%float_0_00100337015 = OpConstant %float 0.00100337015 +%float_n0_000421262259 = OpConstant %float -0.000421262259 +%float_0_00178462011 = OpConstant %float 0.00178462011 +%float_n0_000237438726 = OpConstant %float -0.000237438726 +%float_n0_000620404433 = OpConstant %float -0.000620404433 +%float_0_0016620711 = OpConstant %float 0.0016620711 +%float_0_000834865205 = OpConstant %float 0.000834865205 +%float_n0_0017233456 = OpConstant %float -0.0017233456 +%float_n0_00107996329 = OpConstant %float -0.00107996329 +%float_0_00176930148 = OpConstant %float 0.00176930148 +%float_n0_000788909325 = OpConstant %float -0.000788909325 +%float_n0_00178462011 = OpConstant %float -0.00178462011 +%float_0_000681678939 = OpConstant %float 0.000681678939 +%float_n0_000988051528 = OpConstant %float -0.000988051528 +%float_n0_00132506131 = OpConstant %float -0.00132506131 +%float_n0_00017616422 = OpConstant %float -0.00017616422 +%float_n0_00150888483 = OpConstant %float -0.00150888483 +%float_0_0003293505 = OpConstant %float 0.0003293505 +%float_n0_001953125 = OpConstant %float -0.001953125 +%float_0_000666360313 = OpConstant %float 0.000666360313 +%float_n0_00161611522 = OpConstant %float -0.00161611522 +%float_0_00115655642 = OpConstant %float 0.00115655642 +%float_0_000451899512 = OpConstant %float 0.000451899512 +%float_n0_000436580885 = OpConstant %float -0.000436580885 +%float_0_000191482846 = OpConstant %float 0.000191482846 +%float_n0_0014935662 = OpConstant %float -0.0014935662 +%float_0_00114123779 = OpConstant %float 0.00114123779 +%float_8_42524532en05 = OpConstant %float 8.42524532e-05 +%float_0_00189185049 = OpConstant %float 0.00189185049 +%float_0_00140165444 = OpConstant %float 0.00140165444 +%float_0_000559129927 = OpConstant %float 0.000559129927 +%float_0_000114889706 = OpConstant %float 0.000114889706 +%float_0_00126378681 = OpConstant %float 0.00126378681 +%float_n0_000574448553 = OpConstant %float -0.000574448553 +%float_n0_000972732843 = OpConstant %float -0.000972732843 +%float_0_00132506131 = OpConstant %float 0.00132506131 +%float_0_000222120099 = OpConstant %float 0.000222120099 +%float_n0_000758272072 = OpConstant %float -0.000758272072 +%float_n0_00135569857 = OpConstant %float -0.00135569857 +%float_0_00146292895 = OpConstant %float 0.00146292895 +%float_0_000865502458 = OpConstant %float 0.000865502458 +%float_n0_000359987753 = OpConstant %float -0.000359987753 +%float_0_0005438113 = OpConstant %float 0.0005438113 +%float_n0_00112591917 = OpConstant %float -0.00112591917 +%float_n0_000252757367 = OpConstant %float -0.000252757367 +%float_n0_000559129927 = OpConstant %float -0.000559129927 +%float_n0_00181525736 = OpConstant %float -0.00181525736 +%float_0_0017233456 = OpConstant %float 0.0017233456 +%float_n0_00115655642 = OpConstant %float -0.00115655642 +%float_0_000742953445 = OpConstant %float 0.000742953445 +%float_0_00157015934 = OpConstant %float 0.00157015934 +%float_n0_000114889706 = OpConstant %float -0.000114889706 +%float_n0_00121783093 = OpConstant %float -0.00121783093 +%float_0_00183057599 = OpConstant %float 0.00183057599 +%float_2_29779416en05 = OpConstant %float 2.29779416e-05 +%float_n0_00192248775 = OpConstant %float -0.00192248775 +%float_0_00173866423 = OpConstant %float 0.00173866423 +%float_n0_000712316192 = OpConstant %float -0.000712316192 +%float_0_00155484071 = OpConstant %float 0.00155484071 +%float_n0_00170802698 = OpConstant %float -0.00170802698 +%float_0_00123314955 = OpConstant %float 0.00123314955 +%float_0_000206801473 = OpConstant %float 0.000206801473 +%float_0_00104932603 = OpConstant %float 0.00104932603 +%float_n0_000727634819 = OpConstant %float -0.000727634819 +%float_n0_00163143384 = OpConstant %float -0.00163143384 +%float_n0_000314031873 = OpConstant %float -0.000314031873 +%float_0_000482536765 = OpConstant %float 0.000482536765 +%float_n0_00179993873 = OpConstant %float -0.00179993873 +%float_0_00094209559 = OpConstant %float 0.00094209559 +%float_n0_000344669126 = OpConstant %float -0.000344669126 +%float_0_000696997566 = OpConstant %float 0.000696997566 +%float_n0_00101868878 = OpConstant %float -0.00101868878 +%float_n0_00157015934 = OpConstant %float -0.00157015934 +%float_n2_29779416en05 = OpConstant %float -2.29779416e-05 +%float_n0_00127910543 = OpConstant %float -0.00127910543 +%float_0_000804227951 = OpConstant %float 0.000804227951 +%float_n0_000896139711 = OpConstant %float -0.000896139711 +%float_n0_0014322917 = OpConstant %float -0.0014322917 +%float_0_000605085806 = OpConstant %float 0.000605085806 +%float_n8_42524532en05 = OpConstant %float -8.42524532e-05 +%float_0_000911458337 = OpConstant %float 0.000911458337 +%float_0_001953125 = OpConstant %float 0.001953125 +%float_n0_00140165444 = OpConstant %float -0.00140165444 +%float_n0_00063572306 = OpConstant %float -0.00063572306 +%float_0_00150888483 = OpConstant %float 0.00150888483 +%float_n0_000819546578 = OpConstant %float -0.000819546578 +%float_0_00124846818 = OpConstant %float 0.00124846818 +%float_0_000252757367 = OpConstant %float 0.000252757367 +%float_0_00152420346 = OpConstant %float 0.00152420346 +%float_0_00112591917 = OpConstant %float 0.00112591917 +%float_0_000359987753 = OpConstant %float 0.000359987753 +%float_n0_000390625006 = OpConstant %float -0.000390625006 +%float_0_00190716912 = OpConstant %float 0.00190716912 +%float_0_00138633582 = OpConstant %float 0.00138633582 +%float_n0_00111060054 = OpConstant %float -0.00111060054 +%float_0_00161611522 = OpConstant %float 0.00161611522 +%float_n0_000880821084 = OpConstant %float -0.000880821084 +%float_0_000145526967 = OpConstant %float 0.000145526967 +%float_0_00107996329 = OpConstant %float 0.00107996329 +%float_n5_36151965en05 = OpConstant %float -5.36151965e-05 +%float_0_00028339462 = OpConstant %float 0.00028339462 +%float_n0_00169270835 = OpConstant %float -0.00169270835 +%float_n0_00126378681 = OpConstant %float -0.00126378681 +%float_n0_000513174047 = OpConstant %float -0.000513174047 +%float_n0_000160845593 = OpConstant %float -0.000160845593 +%float_n0_00187653187 = OpConstant %float -0.00187653187 +%float_n0_000834865205 = OpConstant %float -0.000834865205 +%float_0_00063572306 = OpConstant %float 0.00063572306 +%float_7_65931418en06 = OpConstant %float 7.65931418e-06 +%float_n0_00190716912 = OpConstant %float -0.00190716912 +%float_n0_000222120099 = OpConstant %float -0.000222120099 +%float_0_000375306379 = OpConstant %float 0.000375306379 +%float_n0_00173866423 = OpConstant %float -0.00173866423 +%float_n0_000405943632 = OpConstant %float -0.000405943632 +%float_n0_00123314955 = OpConstant %float -0.00123314955 +%float_0_00170802698 = OpConstant %float 0.00170802698 +%float_n0_00094209559 = OpConstant %float -0.00094209559 +%float_0_000819546578 = OpConstant %float 0.000819546578 +%float_0_00184589461 = OpConstant %float 0.00184589461 +%float_0_000467218139 = OpConstant %float 0.000467218139 + %2242 = OpConstantComposite %_arr_float_uint_256 %float_n0_00100337015 %float_0_000880821084 %float_0_00169270835 %float_n0_00155484071 %float_0_00127910543 %float_n0_000605085806 %float_0_00106464466 %float_n0_00138633582 %float_0_00135569857 %float_0_000513174047 %float_0_00121783093 %float_n0_00160079659 %float_0_00058976718 %float_n0_00028339462 %float_0_00111060054 %float_n0_00141697307 %float_0_00144761032 %float_n0_0005438113 %float_0_00013020834 %float_n0_0012025123 %float_0_000436580885 %float_n0_00104932603 %float_0_000620404433 %float_n0_000482536765 %float_0_00187653187 %float_n0_00109528191 %float_n9_95710798en05 %float_n0_000528492674 %float_0_0014322917 %float_n0_00193780637 %float_n0_000696997566 %float_3_829657en05 %float_0_000712316192 %float_n0_00130974269 %float_0_00109528191 %float_n0_000298713247 %float_0_00175398286 %float_n0_00167738972 %float_0_00147824758 %float_n3_829657en05 %float_0_000788909325 %float_n0_00183057599 %float_0_000298713247 %float_0_000988051528 %float_n0_00117187505 %float_0_00017616422 %float_0_00164675247 %float_n0_00158547796 %float_0_000344669126 %float_0_00186121324 %float_n0_00176930148 %float_n0_000865502458 %float_0_000896139711 %float_0_000160845593 %float_n0_000926776964 %float_n0_00152420346 %float_n0_000651041686 %float_0_00129442406 %float_n0_000804227951 %float_n0_00146292895 %float_0_00179993873 %float_n0_000850183831 %float_0_000850183831 %float_n0_000451899512 %float_n0_00106464466 %float_n0_000145526967 %float_0_000237438726 %float_0_00141697307 %float_n0_00058976718 %float_n0_000191482846 %float_0_00160079659 %float_0_00101868878 %float_0_000405943632 %float_n0_000206801473 %float_0_00158547796 %float_0_000651041686 %float_n6_89338267en05 %float_0_000421262259 %float_n0_00164675247 %float_0_00137101719 %float_0_000926776964 %float_n0_000666360313 %float_0_00118719367 %float_n0_00144761032 %float_0_000574448553 %float_n0_00189185049 %float_0_000758272072 %float_n0_00129442406 %float_0_00192248775 %float_n0_0016620711 %float_n0_00103400741 %float_n0_000497855421 %float_n0_00186121324 %float_0_0012025123 %float_n0_0003293505 %float_n0_00137101719 %float_0_00163143384 %float_n0_00184589461 %float_0_000727634819 %float_n0_000911458337 %float_0_00181525736 %float_n0_00114123779 %float_n0_000375306379 %float_9_95710798en05 %float_n0_000742953445 %float_0_00117187505 %float_6_89338267en05 %float_0_0014935662 %float_0_000972732843 %float_n0_000957414217 %float_0_00193780637 %float_0_000528492674 %float_5_36151965en05 %float_n0_00124846818 %float_n0_000268075994 %float_0_00153952208 %float_n7_65931418en06 %float_0_000314031873 %float_0_00134037994 %float_n0_00175398286 %float_0_000497855421 %float_n0_00118719367 %float_0_000773590698 %float_n0_00134037994 %float_0_000268075994 %float_n0_00147824758 %float_n0_00013020834 %float_n0_000773590698 %float_0_00130974269 %float_0_000390625006 %float_0_000957414217 %float_n0_000467218139 %float_n0_00153952208 %float_0_00103400741 %float_n0_000681678939 %float_0_00167738972 %float_0_00100337015 %float_n0_000421262259 %float_0_00178462011 %float_n0_000237438726 %float_n0_000620404433 %float_0_0016620711 %float_0_000834865205 %float_n0_0017233456 %float_n0_00107996329 %float_0_00176930148 %float_n0_000788909325 %float_n0_00178462011 %float_0_000681678939 %float_n0_000988051528 %float_n0_00132506131 %float_n0_00017616422 %float_n0_00150888483 %float_0_0003293505 %float_n0_001953125 %float_0_000666360313 %float_n0_00161611522 %float_0_00115655642 %float_0_000451899512 %float_n0_000436580885 %float_0_000191482846 %float_n0_0014935662 %float_0_00114123779 %float_8_42524532en05 %float_0_00189185049 %float_0_00140165444 %float_0_000559129927 %float_0_000114889706 %float_0_00126378681 %float_n0_000574448553 %float_n0_000972732843 %float_0_00132506131 %float_0_000222120099 %float_n0_000758272072 %float_n0_00135569857 %float_0_00146292895 %float_0_000865502458 %float_n0_000359987753 %float_0_0005438113 %float_n0_00112591917 %float_n0_000252757367 %float_n0_000559129927 %float_n0_00181525736 %float_0_0017233456 %float_n0_00115655642 %float_0_000742953445 %float_0_00157015934 %float_n0_000114889706 %float_n0_00121783093 %float_0_00183057599 %float_2_29779416en05 %float_n0_00192248775 %float_0_00173866423 %float_n0_000712316192 %float_0_00155484071 %float_n0_00170802698 %float_0_00123314955 %float_0_000206801473 %float_0_00104932603 %float_n0_000727634819 %float_n0_00163143384 %float_n0_000314031873 %float_0_000482536765 %float_n0_00179993873 %float_0_00094209559 %float_n0_000344669126 %float_0_000696997566 %float_n0_00101868878 %float_n0_00157015934 %float_n2_29779416en05 %float_n0_00127910543 %float_0_000804227951 %float_n0_000896139711 %float_n0_0014322917 %float_0_000605085806 %float_n8_42524532en05 %float_0_000911458337 %float_0_001953125 %float_n0_00140165444 %float_n0_00063572306 %float_0_00150888483 %float_n0_000819546578 %float_0_00124846818 %float_0_000252757367 %float_0_00152420346 %float_0_00112591917 %float_0_000359987753 %float_n0_000390625006 %float_0_00190716912 %float_0_00138633582 %float_n0_00111060054 %float_0_00161611522 %float_n0_000880821084 %float_0_000145526967 %float_0_00107996329 %float_n5_36151965en05 %float_0_00028339462 %float_n0_00169270835 %float_n0_00126378681 %float_n0_000513174047 %float_n0_000160845593 %float_n0_00187653187 %float_n0_000834865205 %float_0_00063572306 %float_7_65931418en06 %float_n0_00190716912 %float_n0_000222120099 %float_0_000375306379 %float_n0_00173866423 %float_n0_000405943632 %float_n0_00123314955 %float_0_00170802698 %float_n0_00094209559 %float_0_000819546578 %float_0_00184589461 %float_0_000467218139 + %uint_1 = OpConstant %uint 1 + %uint_16 = OpConstant %uint 16 +%_ptr_Function__arr_float_uint_256 = OpTypePointer Function %_arr_float_uint_256 + %v4float = OpTypeVector %float 4 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%gl_FragCoord = OpVariable %_ptr_Input_v4float Input + %v2float = OpTypeVector %float 2 +%_struct_1048 = OpTypeStruct %v2int %v2float %float +%_ptr_PushConstant__struct_1048 = OpTypePointer PushConstant %_struct_1048 + %3305 = OpVariable %_ptr_PushConstant__struct_1048 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_v2int = OpTypePointer PushConstant %v2int + %int_1 = OpConstant %int 1 +%_ptr_PushConstant_v2float = OpTypePointer PushConstant %v2float + %float_0_5 = OpConstant %float 0.5 + %int_2 = OpConstant %int 2 +%_ptr_PushConstant_float = OpTypePointer PushConstant %float +%_ptr_Output_v4float = OpTypePointer Output %v4float + %5334 = OpVariable %_ptr_Output_v4float Output +%uint_532432441 = OpConstant %uint 532432441 +%uint_2129690299 = OpConstant %uint 2129690299 +%uint_2129764351 = OpConstant %uint 2129764351 + %float_2 = OpConstant %float 2 + %151 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_151 = OpTypePointer UniformConstant %151 + %5163 = OpVariable %_ptr_UniformConstant_151 UniformConstant + %int_n1 = OpConstant %int -1 + %1803 = OpConstantComposite %v2int %int_0 %int_n1 + %1812 = OpConstantComposite %v2int %int_1 %int_n1 + %1806 = OpConstantComposite %v2int %int_n1 %int_0 + %1824 = OpConstantComposite %v2int %int_1 %int_0 + %1818 = OpConstantComposite %v2int %int_n1 %int_1 + %1827 = OpConstantComposite %v2int %int_0 %int_1 + %1836 = OpConstantComposite %v2int %int_1 %int_1 + %1833 = OpConstantComposite %v2int %int_2 %int_0 + %1839 = OpConstantComposite %v2int %int_0 %int_2 + %1845 = OpConstantComposite %v2int %int_2 %int_1 + %1848 = OpConstantComposite %v2int %int_1 %int_2 +%float_0_03125 = OpConstant %float 0.03125 + %1566 = OpConstantComposite %v2float %float_0_5 %float_0_5 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %2604 = OpConstantComposite %v3float %float_0 %float_0 %float_0 + %2582 = OpConstantComposite %v3float %float_1 %float_1 %float_1 + %10264 = OpUndef %v4float + %5663 = OpFunction %void None %1282 + %24953 = OpLabel + %18411 = OpVariable %_ptr_Function__arr_float_uint_256 Function + %22087 = OpLoad %v4float %gl_FragCoord + %6562 = OpVectorShuffle %v2float %22087 %22087 0 1 + %17656 = OpConvertFToS %v2int %6562 + %19279 = OpAccessChain %_ptr_PushConstant_v2int %3305 %int_0 + %22822 = OpLoad %v2int %19279 + %23312 = OpISub %v2int %17656 %22822 + %9938 = OpBitcast %v2uint %23312 + %20997 = OpAccessChain %_ptr_PushConstant_v2float %3305 %int_1 + %22579 = OpLoad %v2float %20997 + %13397 = OpBitcast %v2uint %22579 + %12762 = OpVectorTimesScalar %v2float %22579 %float_0_5 + %24595 = OpFSub %v2float %12762 %1566 + %17743 = OpBitcast %v2uint %24595 + %16707 = OpCompositeExtract %uint %13397 0 + %13283 = OpCompositeExtract %uint %13397 1 + %7641 = OpCompositeExtract %uint %17743 0 + %7529 = OpCompositeExtract %uint %17743 1 + %18241 = OpCompositeConstruct %v4uint %16707 %13283 %7641 %7529 + %9777 = OpAccessChain %_ptr_PushConstant_float %3305 %int_2 + %18808 = OpLoad %float %9777 + %17599 = OpBitcast %uint %18808 + %19625 = OpConvertUToF %v2float %9938 + %8442 = OpVectorShuffle %v2uint %18241 %18241 0 1 + %11576 = OpBitcast %v2float %8442 + %20814 = OpFMul %v2float %19625 %11576 + %8994 = OpVectorShuffle %v2uint %18241 %18241 2 3 + %11797 = OpBitcast %v2float %8994 + %20069 = OpFAdd %v2float %20814 %11797 + %12719 = OpExtInst %v2float %1 Floor %20069 + %16290 = OpFSub %v2float %20069 %12719 + %17064 = OpConvertFToS %v2int %12719 + %20568 = OpIAdd %v2int %17064 %1803 + %18223 = OpLoad %151 %5163 + %19459 = OpImageFetch %v4float %18223 %20568 Lod %int_0 + %13347 = OpIAdd %v2int %17064 %1806 + %14538 = OpLoad %151 %5163 + %12625 = OpImageFetch %v4float %14538 %13347 Lod %int_0 + %10421 = OpLoad %151 %5163 + %15444 = OpImageFetch %v4float %10421 %17064 Lod %int_0 + %13348 = OpIAdd %v2int %17064 %1812 + %15811 = OpLoad %151 %5163 + %19460 = OpImageFetch %v4float %15811 %13348 Lod %int_0 + %13349 = OpIAdd %v2int %17064 %1824 + %15812 = OpLoad %151 %5163 + %19461 = OpImageFetch %v4float %15812 %13349 Lod %int_0 + %13350 = OpIAdd %v2int %17064 %1833 + %15813 = OpLoad %151 %5163 + %19462 = OpImageFetch %v4float %15813 %13350 Lod %int_0 + %13351 = OpIAdd %v2int %17064 %1818 + %15814 = OpLoad %151 %5163 + %19463 = OpImageFetch %v4float %15814 %13351 Lod %int_0 + %13352 = OpIAdd %v2int %17064 %1827 + %15815 = OpLoad %151 %5163 + %19464 = OpImageFetch %v4float %15815 %13352 Lod %int_0 + %13353 = OpIAdd %v2int %17064 %1839 + %15816 = OpLoad %151 %5163 + %19465 = OpImageFetch %v4float %15816 %13353 Lod %int_0 + %13354 = OpIAdd %v2int %17064 %1836 + %15817 = OpLoad %151 %5163 + %19466 = OpImageFetch %v4float %15817 %13354 Lod %int_0 + %13355 = OpIAdd %v2int %17064 %1845 + %15818 = OpLoad %151 %5163 + %19467 = OpImageFetch %v4float %15818 %13355 Lod %int_0 + %13356 = OpIAdd %v2int %17064 %1848 + %14918 = OpLoad %151 %5163 + %8899 = OpImageFetch %v4float %14918 %13356 Lod %int_0 + %19729 = OpCompositeExtract %float %19459 0 + %7025 = OpCompositeExtract %float %19459 1 + %18723 = OpCompositeExtract %float %19459 2 + %24863 = OpFMul %float %19729 %19729 + %16184 = OpFMul %float %7025 %7025 + %9305 = OpFMul %float %18723 %18723 + %22236 = OpCompositeExtract %float %19460 0 + %11844 = OpCompositeExtract %float %19460 1 + %18724 = OpCompositeExtract %float %19460 2 + %24864 = OpFMul %float %22236 %22236 + %16185 = OpFMul %float %11844 %11844 + %9306 = OpFMul %float %18724 %18724 + %22237 = OpCompositeExtract %float %12625 0 + %11845 = OpCompositeExtract %float %12625 1 + %18725 = OpCompositeExtract %float %12625 2 + %24865 = OpFMul %float %22237 %22237 + %16186 = OpFMul %float %11845 %11845 + %9307 = OpFMul %float %18725 %18725 + %22238 = OpCompositeExtract %float %15444 0 + %11846 = OpCompositeExtract %float %15444 1 + %18726 = OpCompositeExtract %float %15444 2 + %24866 = OpFMul %float %22238 %22238 + %16187 = OpFMul %float %11846 %11846 + %9308 = OpFMul %float %18726 %18726 + %22239 = OpCompositeExtract %float %19461 0 + %11847 = OpCompositeExtract %float %19461 1 + %18727 = OpCompositeExtract %float %19461 2 + %24867 = OpFMul %float %22239 %22239 + %16188 = OpFMul %float %11847 %11847 + %9309 = OpFMul %float %18727 %18727 + %22240 = OpCompositeExtract %float %19462 0 + %11848 = OpCompositeExtract %float %19462 1 + %18728 = OpCompositeExtract %float %19462 2 + %24868 = OpFMul %float %22240 %22240 + %16189 = OpFMul %float %11848 %11848 + %9310 = OpFMul %float %18728 %18728 + %22241 = OpCompositeExtract %float %19463 0 + %11849 = OpCompositeExtract %float %19463 1 + %18729 = OpCompositeExtract %float %19463 2 + %24869 = OpFMul %float %22241 %22241 + %16190 = OpFMul %float %11849 %11849 + %9311 = OpFMul %float %18729 %18729 + %22242 = OpCompositeExtract %float %19464 0 + %11850 = OpCompositeExtract %float %19464 1 + %18730 = OpCompositeExtract %float %19464 2 + %24870 = OpFMul %float %22242 %22242 + %16191 = OpFMul %float %11850 %11850 + %9312 = OpFMul %float %18730 %18730 + %22243 = OpCompositeExtract %float %19466 0 + %11851 = OpCompositeExtract %float %19466 1 + %18731 = OpCompositeExtract %float %19466 2 + %24871 = OpFMul %float %22243 %22243 + %16192 = OpFMul %float %11851 %11851 + %9313 = OpFMul %float %18731 %18731 + %22244 = OpCompositeExtract %float %19467 0 + %11852 = OpCompositeExtract %float %19467 1 + %18732 = OpCompositeExtract %float %19467 2 + %24872 = OpFMul %float %22244 %22244 + %16193 = OpFMul %float %11852 %11852 + %9314 = OpFMul %float %18732 %18732 + %22245 = OpCompositeExtract %float %19465 0 + %11853 = OpCompositeExtract %float %19465 1 + %18733 = OpCompositeExtract %float %19465 2 + %24873 = OpFMul %float %22245 %22245 + %16194 = OpFMul %float %11853 %11853 + %9315 = OpFMul %float %18733 %18733 + %22246 = OpCompositeExtract %float %8899 0 + %11854 = OpCompositeExtract %float %8899 1 + %18734 = OpCompositeExtract %float %8899 2 + %24874 = OpFMul %float %22246 %22246 + %14910 = OpFMul %float %11854 %11854 + %8590 = OpFMul %float %18734 %18734 + %10877 = OpExtInst %float %1 FMin %16186 %16187 + %9276 = OpExtInst %float %1 FMin %16184 %10877 + %15951 = OpExtInst %float %1 FMin %16188 %16191 + %10905 = OpExtInst %float %1 FMin %9276 %15951 + %24296 = OpExtInst %float %1 FMax %16186 %16187 + %17523 = OpExtInst %float %1 FMax %16184 %24296 + %21848 = OpExtInst %float %1 FMax %16188 %16191 + %7823 = OpExtInst %float %1 FMax %17523 %21848 + %13503 = OpExtInst %float %1 FMin %16187 %16188 + %13819 = OpExtInst %float %1 FMin %16185 %13503 + %15952 = OpExtInst %float %1 FMin %16189 %16192 + %10906 = OpExtInst %float %1 FMin %13819 %15952 + %24297 = OpExtInst %float %1 FMax %16187 %16188 + %17524 = OpExtInst %float %1 FMax %16185 %24297 + %21849 = OpExtInst %float %1 FMax %16189 %16192 + %7824 = OpExtInst %float %1 FMax %17524 %21849 + %13504 = OpExtInst %float %1 FMin %16190 %16191 + %13820 = OpExtInst %float %1 FMin %16187 %13504 + %15953 = OpExtInst %float %1 FMin %16192 %16194 + %10907 = OpExtInst %float %1 FMin %13820 %15953 + %24298 = OpExtInst %float %1 FMax %16190 %16191 + %17525 = OpExtInst %float %1 FMax %16187 %24298 + %21850 = OpExtInst %float %1 FMax %16192 %16194 + %7825 = OpExtInst %float %1 FMax %17525 %21850 + %13505 = OpExtInst %float %1 FMin %16191 %16192 + %13821 = OpExtInst %float %1 FMin %16188 %13505 + %15954 = OpExtInst %float %1 FMin %16193 %14910 + %10908 = OpExtInst %float %1 FMin %13821 %15954 + %24299 = OpExtInst %float %1 FMax %16191 %16192 + %17526 = OpExtInst %float %1 FMax %16188 %24299 + %23939 = OpExtInst %float %1 FMax %16193 %14910 + %21101 = OpExtInst %float %1 FMax %17526 %23939 + %8181 = OpBitcast %uint %7823 + %8818 = OpISub %uint %uint_2129690299 %8181 + %9881 = OpBitcast %float %8818 + %15062 = OpBitcast %uint %7824 + %6702 = OpISub %uint %uint_2129690299 %15062 + %9882 = OpBitcast %float %6702 + %15063 = OpBitcast %uint %7825 + %6703 = OpISub %uint %uint_2129690299 %15063 + %9883 = OpBitcast %float %6703 + %15064 = OpBitcast %uint %21101 + %6835 = OpISub %uint %uint_2129690299 %15064 + %6465 = OpBitcast %float %6835 + %24131 = OpFSub %float %float_1 %7823 + %23324 = OpExtInst %float %1 FMin %10905 %24131 + %23036 = OpFMul %float %23324 %9881 + %16051 = OpExtInst %float %1 FClamp %23036 %float_0 %float_1 + %25005 = OpFSub %float %float_1 %7824 + %10697 = OpExtInst %float %1 FMin %10906 %25005 + %23037 = OpFMul %float %10697 %9882 + %16052 = OpExtInst %float %1 FClamp %23037 %float_0 %float_1 + %25006 = OpFSub %float %float_1 %7825 + %10698 = OpExtInst %float %1 FMin %10907 %25006 + %23038 = OpFMul %float %10698 %9883 + %16053 = OpExtInst %float %1 FClamp %23038 %float_0 %float_1 + %25007 = OpFSub %float %float_1 %21101 + %10699 = OpExtInst %float %1 FMin %10908 %25007 + %22903 = OpFMul %float %10699 %6465 + %20683 = OpExtInst %float %1 FClamp %22903 %float_0 %float_1 + %24011 = OpBitcast %uint %16051 + %22090 = OpShiftRightLogical %uint %24011 %uint_1 + %23229 = OpIAdd %uint %22090 %uint_532432441 + %22851 = OpBitcast %float %23229 + %8910 = OpBitcast %uint %16052 + %9189 = OpShiftRightLogical %uint %8910 %uint_1 + %23230 = OpIAdd %uint %9189 %uint_532432441 + %22852 = OpBitcast %float %23230 + %8911 = OpBitcast %uint %16053 + %9190 = OpShiftRightLogical %uint %8911 %uint_1 + %23231 = OpIAdd %uint %9190 %uint_532432441 + %22853 = OpBitcast %float %23231 + %8912 = OpBitcast %uint %20683 + %9191 = OpShiftRightLogical %uint %8912 %uint_1 + %23232 = OpIAdd %uint %9191 %uint_532432441 + %21692 = OpBitcast %float %23232 + %19558 = OpBitcast %float %17599 + %18879 = OpFMul %float %22851 %19558 + %22795 = OpFMul %float %22852 %19558 + %19380 = OpFMul %float %22853 %19558 + %10255 = OpFMul %float %21692 %19558 + %13586 = OpCompositeExtract %float %16290 0 + %21718 = OpFSub %float %float_1 %13586 + %11876 = OpCompositeExtract %float %16290 1 + %11147 = OpFSub %float %float_1 %11876 + %17670 = OpFMul %float %21718 %11147 + %25212 = OpFMul %float %13586 %11147 + %20330 = OpFMul %float %21718 %11876 + %20638 = OpFMul %float %13586 %11876 + %18204 = OpFSub %float %7823 %10905 + %23453 = OpFAdd %float %float_0_03125 %18204 + %11395 = OpBitcast %uint %23453 + %7677 = OpISub %uint %uint_2129690299 %11395 + %8343 = OpBitcast %float %7677 + %17531 = OpFMul %float %17670 %8343 + %20631 = OpFSub %float %7824 %10906 + %23454 = OpFAdd %float %float_0_03125 %20631 + %11396 = OpBitcast %uint %23454 + %7678 = OpISub %uint %uint_2129690299 %11396 + %8344 = OpBitcast %float %7678 + %17532 = OpFMul %float %25212 %8344 + %20632 = OpFSub %float %7825 %10907 + %23455 = OpFAdd %float %float_0_03125 %20632 + %11397 = OpBitcast %uint %23455 + %7679 = OpISub %uint %uint_2129690299 %11397 + %8345 = OpBitcast %float %7679 + %17533 = OpFMul %float %20330 %8345 + %20633 = OpFSub %float %21101 %10908 + %23456 = OpFAdd %float %float_0_03125 %20633 + %11398 = OpBitcast %uint %23456 + %7680 = OpISub %uint %uint_2129690299 %11398 + %8381 = OpBitcast %float %7680 + %17261 = OpFMul %float %20638 %8381 + %22796 = OpFMul %float %18879 %17531 + %20292 = OpFMul %float %22795 %17532 + %20984 = OpFMul %float %19380 %17533 + %15690 = OpFAdd %float %20292 %20984 + %22375 = OpFAdd %float %15690 %17531 + %12597 = OpFMul %float %10255 %17261 + %18845 = OpFAdd %float %22796 %12597 + %23067 = OpFAdd %float %18845 %17532 + %7227 = OpFAdd %float %18845 %17533 + %7228 = OpFAdd %float %15690 %17261 + %7229 = OpFAdd %float %22796 %20292 + %7303 = OpFAdd %float %7229 %20984 + %6535 = OpFAdd %float %7303 %12597 + %12598 = OpFMul %float %float_2 %6535 + %18846 = OpFAdd %float %12598 %22375 + %23068 = OpFAdd %float %18846 %23067 + %7132 = OpFAdd %float %23068 %7227 + %8111 = OpFAdd %float %7132 %7228 + %9782 = OpBitcast %uint %8111 + %7563 = OpISub %uint %uint_2129764351 %9782 + %9419 = OpBitcast %float %7563 + %9130 = OpFNegate %float %9419 + %12367 = OpFMul %float %9130 %8111 + %16540 = OpFAdd %float %12367 %float_2 + %9442 = OpFMul %float %9419 %16540 + %18229 = OpFAdd %float %24863 %24865 + %8674 = OpFMul %float %22796 %18229 + %24291 = OpFMul %float %24864 %20292 + %14922 = OpFAdd %float %8674 %24291 + %9443 = OpFMul %float %24868 %20292 + %18153 = OpFAdd %float %14922 %9443 + %9444 = OpFMul %float %24869 %20984 + %18154 = OpFAdd %float %18153 %9444 + %9445 = OpFMul %float %24873 %20984 + %18155 = OpFAdd %float %18154 %9445 + %9446 = OpFMul %float %24872 %12597 + %18156 = OpFAdd %float %18155 %9446 + %9447 = OpFMul %float %24874 %12597 + %18157 = OpFAdd %float %18156 %9447 + %9448 = OpFMul %float %24866 %22375 + %18158 = OpFAdd %float %18157 %9448 + %9449 = OpFMul %float %24867 %23067 + %18159 = OpFAdd %float %18158 %9449 + %9450 = OpFMul %float %24870 %7227 + %18160 = OpFAdd %float %18159 %9450 + %9451 = OpFMul %float %24871 %7228 + %15973 = OpFAdd %float %18160 %9451 + %8137 = OpFMul %float %15973 %9442 + %15218 = OpExtInst %float %1 FClamp %8137 %float_0 %float_1 + %12765 = OpFAdd %float %16184 %16186 + %17545 = OpFMul %float %22796 %12765 + %24292 = OpFMul %float %16185 %20292 + %14923 = OpFAdd %float %17545 %24292 + %9452 = OpFMul %float %16189 %20292 + %18161 = OpFAdd %float %14923 %9452 + %9453 = OpFMul %float %16190 %20984 + %18162 = OpFAdd %float %18161 %9453 + %9454 = OpFMul %float %16194 %20984 + %18163 = OpFAdd %float %18162 %9454 + %9455 = OpFMul %float %16193 %12597 + %18164 = OpFAdd %float %18163 %9455 + %9456 = OpFMul %float %14910 %12597 + %18165 = OpFAdd %float %18164 %9456 + %9457 = OpFMul %float %16187 %22375 + %18166 = OpFAdd %float %18165 %9457 + %9458 = OpFMul %float %16188 %23067 + %18167 = OpFAdd %float %18166 %9458 + %9459 = OpFMul %float %16191 %7227 + %18168 = OpFAdd %float %18167 %9459 + %9460 = OpFMul %float %16192 %7228 + %15974 = OpFAdd %float %18168 %9460 + %8138 = OpFMul %float %15974 %9442 + %15219 = OpExtInst %float %1 FClamp %8138 %float_0 %float_1 + %12766 = OpFAdd %float %9305 %9307 + %17546 = OpFMul %float %22796 %12766 + %24293 = OpFMul %float %9306 %20292 + %14924 = OpFAdd %float %17546 %24293 + %9461 = OpFMul %float %9310 %20292 + %18169 = OpFAdd %float %14924 %9461 + %9462 = OpFMul %float %9311 %20984 + %18170 = OpFAdd %float %18169 %9462 + %9463 = OpFMul %float %9315 %20984 + %18171 = OpFAdd %float %18170 %9463 + %9464 = OpFMul %float %9314 %12597 + %18172 = OpFAdd %float %18171 %9464 + %9465 = OpFMul %float %8590 %12597 + %18173 = OpFAdd %float %18172 %9465 + %9466 = OpFMul %float %9308 %22375 + %18174 = OpFAdd %float %18173 %9466 + %9467 = OpFMul %float %9309 %23067 + %18175 = OpFAdd %float %18174 %9467 + %9468 = OpFMul %float %9312 %7227 + %18176 = OpFAdd %float %18175 %9468 + %9469 = OpFMul %float %9313 %7228 + %15975 = OpFAdd %float %18176 %9469 + %7244 = OpFMul %float %15975 %9442 + %22380 = OpExtInst %float %1 FClamp %7244 %float_0 %float_1 + %24270 = OpCompositeInsert %v4float %15218 %10264 0 + %11074 = OpCompositeInsert %v4float %15219 %24270 1 + %14933 = OpCompositeInsert %v4float %22380 %11074 2 + %12955 = OpVectorShuffle %v3float %14933 %14933 0 1 2 + %6471 = OpExtInst %v3float %1 Sqrt %12955 + %22742 = OpCompositeExtract %float %6471 0 + %19769 = OpCompositeInsert %v4float %22742 %10264 0 + %19852 = OpCompositeExtract %float %6471 1 + %16135 = OpCompositeInsert %v4float %19852 %19769 1 + %19814 = OpCompositeExtract %float %6471 2 + %18704 = OpCompositeInsert %v4float %19814 %16135 2 + %15997 = OpVectorShuffle %v3float %18704 %18704 0 1 2 + %12552 = OpBitwiseAnd %v2uint %9938 %2122 + %9741 = OpCompositeExtract %uint %12552 1 + %21498 = OpIMul %uint %9741 %uint_16 + %23411 = OpCompositeExtract %uint %12552 0 + %12610 = OpIAdd %uint %21498 %23411 + OpStore %18411 %2242 + %9958 = OpAccessChain %_ptr_Function_float %18411 %12610 + %25140 = OpLoad %float %9958 + %18028 = OpCompositeConstruct %v3float %25140 %25140 %25140 + %21458 = OpFAdd %v3float %15997 %18028 + %19525 = OpExtInst %v3float %1 FClamp %21458 %2604 %2582 + %16777 = OpCompositeExtract %float %19525 0 + %19708 = OpCompositeExtract %float %19525 1 + %7472 = OpCompositeExtract %float %19525 2 + %22408 = OpCompositeConstruct %v4float %16777 %19708 %7472 %float_1 + OpStore %5334 %22408 + OpReturn + OpFunctionEnd +#endif + +const uint32_t guest_output_ffx_cas_resample_dither_ps[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x0000627D, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0007000F, 0x00000004, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000C93, 0x000014D6, 0x00030010, + 0x0000161F, 0x00000007, 0x00040047, 0x00000C93, 0x0000000B, 0x0000000F, 0x00030047, 0x00000418, + 0x00000002, 0x00050048, 0x00000418, 0x00000000, 0x00000023, 0x00000010, 0x00050048, 0x00000418, + 0x00000001, 0x00000023, 0x00000018, 0x00050048, 0x00000418, 0x00000002, 0x00000023, 0x00000020, + 0x00040047, 0x000014D6, 0x0000001E, 0x00000000, 0x00040047, 0x0000142B, 0x00000021, 0x00000000, + 0x00040047, 0x0000142B, 0x00000022, 0x00000000, 0x00020013, 0x00000008, 0x00030021, 0x00000502, + 0x00000008, 0x00030016, 0x0000000D, 0x00000020, 0x00040020, 0x0000028A, 0x00000007, 0x0000000D, + 0x00040017, 0x00000018, 0x0000000D, 0x00000003, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, + 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, 0x00000004, + 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, 0x0004002B, 0x0000000D, 0x0000008A, 0x3F800000, + 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, 0x0004002B, 0x0000000B, 0x00000147, 0x00000100, + 0x0004001C, 0x000003FB, 0x0000000D, 0x00000147, 0x0004002B, 0x0000000D, 0x0000010F, 0xBA838384, + 0x0004002B, 0x0000000D, 0x00000728, 0x3A66E6E7, 0x0004002B, 0x0000000D, 0x00000705, 0x3ADDDDDE, + 0x0004002B, 0x0000000D, 0x00000A5A, 0xBACBCBCC, 0x0004002B, 0x0000000D, 0x000008DF, 0x3AA7A7A8, + 0x0004002B, 0x0000000D, 0x00000094, 0xBA1E9E9F, 0x0004002B, 0x0000000D, 0x0000034C, 0x3A8B8B8C, + 0x0004002B, 0x0000000D, 0x0000087E, 0xBAB5B5B6, 0x0004002B, 0x0000000D, 0x0000034D, 0x3AB1B1B2, + 0x0004002B, 0x0000000D, 0x00000687, 0x3A068687, 0x0004002B, 0x0000000D, 0x000003EB, 0x3A9F9FA0, + 0x0004002B, 0x0000000D, 0x0000024E, 0xBAD1D1D2, 0x0004002B, 0x0000000D, 0x00000726, 0x3A1A9A9B, + 0x0004002B, 0x0000000D, 0x00000698, 0xB9949495, 0x0004002B, 0x0000000D, 0x00000703, 0x3A919192, + 0x0004002B, 0x0000000D, 0x00000AF8, 0xBAB9B9BA, 0x0004002B, 0x0000000D, 0x00000ABB, 0x3ABDBDBE, + 0x0004002B, 0x0000000D, 0x0000026F, 0xBA0E8E8F, 0x0004002B, 0x0000000D, 0x000008A8, 0x39088889, + 0x0004002B, 0x0000000D, 0x00000565, 0xBA9D9D9E, 0x0004002B, 0x0000000D, 0x0000065D, 0x39E4E4E5, + 0x0004002B, 0x0000000D, 0x000004C6, 0xBA89898A, 0x0004002B, 0x0000000D, 0x00000057, 0x3A22A2A3, + 0x0004002B, 0x0000000D, 0x0000006A, 0xB9FCFCFD, 0x0004002B, 0x0000000D, 0x00000A1E, 0x3AF5F5F6, + 0x0004002B, 0x0000000D, 0x0000087D, 0xBA8F8F90, 0x0004002B, 0x0000000D, 0x00000959, 0xB8D0D0D1, + 0x0004002B, 0x0000000D, 0x00000BB8, 0xBA0A8A8B, 0x0004002B, 0x0000000D, 0x0000097E, 0x3ABBBBBC, + 0x0004002B, 0x0000000D, 0x00000606, 0xBAFDFDFE, 0x0004002B, 0x0000000D, 0x000003AD, 0xBA36B6B7, + 0x0004002B, 0x0000000D, 0x000000E2, 0x3820A0A1, 0x0004002B, 0x0000000D, 0x00000370, 0x3A3ABABB, + 0x0004002B, 0x0000000D, 0x0000024D, 0xBAABABAC, 0x0004002B, 0x0000000D, 0x000005C6, 0x3A8F8F90, + 0x0004002B, 0x0000000D, 0x00000B8C, 0xB99C9C9D, 0x0004002B, 0x0000000D, 0x00000036, 0x3AE5E5E6, + 0x0004002B, 0x0000000D, 0x0000087F, 0xBADBDBDC, 0x0004002B, 0x0000000D, 0x00000172, 0x3AC1C1C2, + 0x0004002B, 0x0000000D, 0x00000399, 0xB820A0A1, 0x0004002B, 0x0000000D, 0x0000040F, 0x3A4ECECF, + 0x0004002B, 0x0000000D, 0x0000091E, 0xBAEFEFF0, 0x0004002B, 0x0000000D, 0x000008D5, 0x399C9C9D, + 0x0004002B, 0x0000000D, 0x000008DE, 0x3A818182, 0x0004002B, 0x0000000D, 0x000002EB, 0xBA99999A, + 0x0004002B, 0x0000000D, 0x00000317, 0x3938B8B9, 0x0004002B, 0x0000000D, 0x0000034E, 0x3AD7D7D8, + 0x0004002B, 0x0000000D, 0x00000111, 0xBACFCFD0, 0x0004002B, 0x0000000D, 0x0000002B, 0x39B4B4B5, + 0x0004002B, 0x0000000D, 0x000008E1, 0x3AF3F3F4, 0x0004002B, 0x0000000D, 0x0000042A, 0xBAE7E7E8, + 0x0004002B, 0x0000000D, 0x00000765, 0xBA62E2E3, 0x0004002B, 0x0000000D, 0x000009A2, 0x3A6AEAEB, + 0x0004002B, 0x0000000D, 0x000004F2, 0x3928A8A9, 0x0004002B, 0x0000000D, 0x0000058A, 0xBA72F2F3, + 0x0004002B, 0x0000000D, 0x000007E0, 0xBAC7C7C8, 0x0004002B, 0x0000000D, 0x00000802, 0xBA2AAAAB, + 0x0004002B, 0x0000000D, 0x00000A1C, 0x3AA9A9AA, 0x0004002B, 0x0000000D, 0x00000940, 0xBA52D2D3, + 0x0004002B, 0x0000000D, 0x000002EC, 0xBABFBFC0, 0x0004002B, 0x0000000D, 0x000003ED, 0x3AEBEBEC, + 0x0004002B, 0x0000000D, 0x000004EB, 0xBA5EDEDF, 0x0004002B, 0x0000000D, 0x00000234, 0x3A5EDEDF, + 0x0004002B, 0x0000000D, 0x00000245, 0xB9ECECED, 0x0004002B, 0x0000000D, 0x00000603, 0xBA8B8B8C, + 0x0004002B, 0x0000000D, 0x00000984, 0xB9189899, 0x0004002B, 0x0000000D, 0x0000076E, 0x3978F8F9, + 0x0004002B, 0x0000000D, 0x00000841, 0x3AB9B9BA, 0x0004002B, 0x0000000D, 0x000009DD, 0xBA1A9A9B, + 0x0004002B, 0x0000000D, 0x000003F3, 0xB948C8C9, 0x0004002B, 0x0000000D, 0x00000B5A, 0x3AD1D1D2, + 0x0004002B, 0x0000000D, 0x00000B58, 0x3A858586, 0x0004002B, 0x0000000D, 0x00000838, 0x39D4D4D5, + 0x0004002B, 0x0000000D, 0x00000218, 0xB958D8D9, 0x0004002B, 0x0000000D, 0x00000A1D, 0x3ACFCFD0, + 0x0004002B, 0x0000000D, 0x0000054B, 0x3A2AAAAB, 0x0004002B, 0x0000000D, 0x00000503, 0xB8909091, + 0x0004002B, 0x0000000D, 0x00000169, 0x39DCDCDD, 0x0004002B, 0x0000000D, 0x00000605, 0xBAD7D7D8, + 0x0004002B, 0x0000000D, 0x0000048A, 0x3AB3B3B4, 0x0004002B, 0x0000000D, 0x000002D3, 0x3A72F2F3, + 0x0004002B, 0x0000000D, 0x00000A7C, 0xBA2EAEAF, 0x0004002B, 0x0000000D, 0x00000171, 0x3A9B9B9C, + 0x0004002B, 0x0000000D, 0x000001AF, 0xBABDBDBE, 0x0004002B, 0x0000000D, 0x000004AC, 0x3A169697, + 0x0004002B, 0x0000000D, 0x0000024F, 0xBAF7F7F8, 0x0004002B, 0x0000000D, 0x00000ADE, 0x3A46C6C7, + 0x0004002B, 0x0000000D, 0x00000110, 0xBAA9A9AA, 0x0004002B, 0x0000000D, 0x00000212, 0x3AFBFBFC, + 0x0004002B, 0x0000000D, 0x00000742, 0xBAD9D9DA, 0x0004002B, 0x0000000D, 0x00000389, 0xBA878788, + 0x0004002B, 0x0000000D, 0x000006C4, 0xBA028283, 0x0004002B, 0x0000000D, 0x00000B98, 0xBAF3F3F4, + 0x0004002B, 0x0000000D, 0x000002AE, 0x3A9D9D9E, 0x0004002B, 0x0000000D, 0x000009B1, 0xB9ACACAD, + 0x0004002B, 0x0000000D, 0x00000741, 0xBAB3B3B4, 0x0004002B, 0x0000000D, 0x00000211, 0x3AD5D5D6, + 0x0004002B, 0x0000000D, 0x00000A5B, 0xBAF1F1F2, 0x0004002B, 0x0000000D, 0x000005EA, 0x3A3EBEBF, + 0x0004002B, 0x0000000D, 0x00000310, 0xBA6EEEEF, 0x0004002B, 0x0000000D, 0x0000052A, 0x3AEDEDEE, + 0x0004002B, 0x0000000D, 0x00000071, 0xBA959596, 0x0004002B, 0x0000000D, 0x00000107, 0xB9C4C4C5, + 0x0004002B, 0x0000000D, 0x000006A2, 0x38D0D0D1, 0x0004002B, 0x0000000D, 0x00000B1B, 0xBA42C2C3, + 0x0004002B, 0x0000000D, 0x00000034, 0x3A99999A, 0x0004002B, 0x0000000D, 0x0000024B, 0x38909091, + 0x0004002B, 0x0000000D, 0x000002AF, 0x3AC3C3C4, 0x0004002B, 0x0000000D, 0x00000A41, 0x3A7EFEFF, + 0x0004002B, 0x0000000D, 0x00000A7E, 0xBA7AFAFB, 0x0004002B, 0x0000000D, 0x0000034F, 0x3AFDFDFE, + 0x0004002B, 0x0000000D, 0x00000901, 0x3A0A8A8B, 0x0004002B, 0x0000000D, 0x00000539, 0x3860E0E1, + 0x0004002B, 0x0000000D, 0x0000091C, 0xBAA3A3A4, 0x0004002B, 0x0000000D, 0x000001A4, 0xB98C8C8D, + 0x0004002B, 0x0000000D, 0x00000666, 0x3AC9C9CA, 0x0004002B, 0x0000000D, 0x00000833, 0xB7008081, + 0x0004002B, 0x0000000D, 0x00000206, 0x39A4A4A5, 0x0004002B, 0x0000000D, 0x00000210, 0x3AAFAFB0, + 0x0004002B, 0x0000000D, 0x000002ED, 0xBAE5E5E6, 0x0004002B, 0x0000000D, 0x0000040D, 0x3A028283, + 0x0004002B, 0x0000000D, 0x00000428, 0xBA9B9B9C, 0x0004002B, 0x0000000D, 0x00000195, 0x3A4ACACB, + 0x0004002B, 0x0000000D, 0x000004C7, 0xBAAFAFB0, 0x0004002B, 0x0000000D, 0x00000AB0, 0x398C8C8D, + 0x0004002B, 0x0000000D, 0x00000429, 0xBAC1C1C2, 0x0004002B, 0x0000000D, 0x00000B5F, 0xB9088889, + 0x0004002B, 0x0000000D, 0x0000044C, 0xBA4ACACB, 0x0004002B, 0x0000000D, 0x00000B59, 0x3AABABAC, + 0x0004002B, 0x0000000D, 0x00000344, 0x39CCCCCD, 0x0004002B, 0x0000000D, 0x000007C7, 0x3A7AFAFB, + 0x0004002B, 0x0000000D, 0x00000739, 0xB9F4F4F5, 0x0004002B, 0x0000000D, 0x0000091D, 0xBAC9C9CA, + 0x0004002B, 0x0000000D, 0x000000D2, 0x3A878788, 0x0004002B, 0x0000000D, 0x00000133, 0xBA32B2B3, + 0x0004002B, 0x0000000D, 0x000005C8, 0x3ADBDBDC, 0x0004002B, 0x0000000D, 0x00000A1B, 0x3A838384, + 0x0004002B, 0x0000000D, 0x00000420, 0xB9DCDCDD, 0x0004002B, 0x0000000D, 0x000002B0, 0x3AE9E9EA, + 0x0004002B, 0x0000000D, 0x00000A25, 0xB978F8F9, 0x0004002B, 0x0000000D, 0x0000030E, 0xBA22A2A3, + 0x0004002B, 0x0000000D, 0x0000048B, 0x3AD9D9DA, 0x0004002B, 0x0000000D, 0x00000B7D, 0x3A5ADADB, + 0x0004002B, 0x0000000D, 0x00000073, 0xBAE1E1E2, 0x0004002B, 0x0000000D, 0x00000740, 0xBA8D8D8E, + 0x0004002B, 0x0000000D, 0x00000173, 0x3AE7E7E8, 0x0004002B, 0x0000000D, 0x000006C6, 0xBA4ECECF, + 0x0004002B, 0x0000000D, 0x00000567, 0xBAE9E9EA, 0x0004002B, 0x0000000D, 0x00000A3F, 0x3A32B2B3, + 0x0004002B, 0x0000000D, 0x00000B95, 0xBA818182, 0x0004002B, 0x0000000D, 0x0000038A, 0xBAADADAE, + 0x0004002B, 0x0000000D, 0x000005CE, 0xB938B8B9, 0x0004002B, 0x0000000D, 0x000006A3, 0xBAC5C5C6, + 0x0004002B, 0x0000000D, 0x000006FA, 0x39ACACAD, 0x0004002B, 0x0000000D, 0x00000743, 0xBB000000, + 0x0004002B, 0x0000000D, 0x000007C5, 0x3A2EAEAF, 0x0004002B, 0x0000000D, 0x0000038B, 0xBAD3D3D4, + 0x0004002B, 0x0000000D, 0x00000ABA, 0x3A979798, 0x0004002B, 0x0000000D, 0x00000B51, 0x39ECECED, + 0x0004002B, 0x0000000D, 0x00000914, 0xB9E4E4E5, 0x0004002B, 0x0000000D, 0x0000013C, 0x3948C8C9, + 0x0004002B, 0x0000000D, 0x00000566, 0xBAC3C3C4, 0x0004002B, 0x0000000D, 0x0000097D, 0x3A959596, + 0x0004002B, 0x0000000D, 0x00000A58, 0x38B0B0B1, 0x0004002B, 0x0000000D, 0x00000B5B, 0x3AF7F7F8, + 0x0004002B, 0x0000000D, 0x00000704, 0x3AB7B7B8, 0x0004002B, 0x0000000D, 0x00000232, 0x3A129293, + 0x0004002B, 0x0000000D, 0x000002EE, 0x38F0F0F1, 0x0004002B, 0x0000000D, 0x000007A2, 0x3AA5A5A6, + 0x0004002B, 0x0000000D, 0x00000763, 0xBA169697, 0x0004002B, 0x0000000D, 0x00000135, 0xBA7EFEFF, + 0x0004002B, 0x0000000D, 0x000000D3, 0x3AADADAE, 0x0004002B, 0x0000000D, 0x00000949, 0x3968E8E9, + 0x0004002B, 0x0000000D, 0x000001D2, 0xBA46C6C7, 0x0004002B, 0x0000000D, 0x00000604, 0xBAB1B1B2, + 0x0004002B, 0x0000000D, 0x00000035, 0x3ABFBFC0, 0x0004002B, 0x0000000D, 0x000004AE, 0x3A62E2E3, + 0x0004002B, 0x0000000D, 0x000007D6, 0xB9BCBCBD, 0x0004002B, 0x0000000D, 0x00000B7B, 0x3A0E8E8F, + 0x0004002B, 0x0000000D, 0x00000AF7, 0xBA939394, 0x0004002B, 0x0000000D, 0x00000873, 0xB9848485, + 0x0004002B, 0x0000000D, 0x000004E9, 0xBA129293, 0x0004002B, 0x0000000D, 0x000007E1, 0xBAEDEDEE, + 0x0004002B, 0x0000000D, 0x0000097F, 0x3AE1E1E2, 0x0004002B, 0x0000000D, 0x000001AE, 0xBA979798, + 0x0004002B, 0x0000000D, 0x00000864, 0x3A42C2C3, 0x0004002B, 0x0000000D, 0x000008E0, 0x3ACDCDCE, + 0x0004002B, 0x0000000D, 0x000005A3, 0xB8F0F0F1, 0x0004002B, 0x0000000D, 0x000006A4, 0xBA9F9FA0, + 0x0004002B, 0x0000000D, 0x00000667, 0x3AEFEFF0, 0x0004002B, 0x0000000D, 0x00000961, 0x37C0C0C1, + 0x0004002B, 0x0000000D, 0x000004C9, 0xBAFBFBFC, 0x0004002B, 0x0000000D, 0x00000ABC, 0x3AE3E3E4, + 0x0004002B, 0x0000000D, 0x00000627, 0xBA3ABABB, 0x0004002B, 0x0000000D, 0x000007A3, 0x3ACBCBCC, + 0x0004002B, 0x0000000D, 0x00000AF9, 0xBADFDFE0, 0x0004002B, 0x0000000D, 0x00000528, 0x3AA1A1A2, + 0x0004002B, 0x0000000D, 0x00000B24, 0x3958D8D9, 0x0004002B, 0x0000000D, 0x0000020F, 0x3A89898A, + 0x0004002B, 0x0000000D, 0x000008A1, 0xBA3EBEBF, 0x0004002B, 0x0000000D, 0x000004C8, 0xBAD5D5D6, + 0x0004002B, 0x0000000D, 0x000004BD, 0xB9A4A4A5, 0x0004002B, 0x0000000D, 0x00000976, 0x39FCFCFD, + 0x0004002B, 0x0000000D, 0x000006A5, 0xBAEBEBEC, 0x0004002B, 0x0000000D, 0x0000054D, 0x3A76F6F7, + 0x0004002B, 0x0000000D, 0x000002E2, 0xB9B4B4B5, 0x0004002B, 0x0000000D, 0x000000F6, 0x3A36B6B7, + 0x0004002B, 0x0000000D, 0x0000024C, 0xBA858586, 0x0004002B, 0x0000000D, 0x00000B97, 0xBACDCDCE, + 0x0004002B, 0x0000000D, 0x00000055, 0xB7C0C0C1, 0x0004002B, 0x0000000D, 0x00000B96, 0xBAA7A7A8, + 0x0004002B, 0x0000000D, 0x00000689, 0x3A52D2D3, 0x0004002B, 0x0000000D, 0x00000096, 0xBA6AEAEB, + 0x0004002B, 0x0000000D, 0x00000072, 0xBABBBBBC, 0x0004002B, 0x0000000D, 0x000009A0, 0x3A1E9E9F, + 0x0004002B, 0x0000000D, 0x0000014C, 0xB8B0B0B1, 0x0004002B, 0x0000000D, 0x00000059, 0x3A6EEEEF, + 0x0004002B, 0x0000000D, 0x0000048C, 0x3B000000, 0x0004002B, 0x0000000D, 0x000009BB, 0xBAB7B7B8, + 0x0004002B, 0x0000000D, 0x00000588, 0xBA26A6A7, 0x0004002B, 0x0000000D, 0x000003EC, 0x3AC5C5C6, + 0x0004002B, 0x0000000D, 0x00000BBA, 0xBA56D6D7, 0x0004002B, 0x0000000D, 0x00000665, 0x3AA3A3A4, + 0x0004002B, 0x0000000D, 0x000005BC, 0x39848485, 0x0004002B, 0x0000000D, 0x00000529, 0x3AC7C7C8, + 0x0004002B, 0x0000000D, 0x00000840, 0x3A939394, 0x0004002B, 0x0000000D, 0x0000051F, 0x39BCBCBD, + 0x0004002B, 0x0000000D, 0x000005FB, 0xB9CCCCCD, 0x0004002B, 0x0000000D, 0x000000D5, 0x3AF9F9FA, + 0x0004002B, 0x0000000D, 0x000005C7, 0x3AB5B5B6, 0x0004002B, 0x0000000D, 0x000009BA, 0xBA919192, + 0x0004002B, 0x0000000D, 0x000000D4, 0x3AD3D3D4, 0x0004002B, 0x0000000D, 0x000009DF, 0xBA66E6E7, + 0x0004002B, 0x0000000D, 0x000006CD, 0x39189899, 0x0004002B, 0x0000000D, 0x00000489, 0x3A8D8D8E, + 0x0004002B, 0x0000000D, 0x000007F0, 0xB860E0E1, 0x0004002B, 0x0000000D, 0x000003E1, 0x39949495, + 0x0004002B, 0x0000000D, 0x000009BC, 0xBADDDDDE, 0x0004002B, 0x0000000D, 0x00000A59, 0xBAA5A5A6, + 0x0004002B, 0x0000000D, 0x0000093E, 0xBA068687, 0x0004002B, 0x0000000D, 0x000007A9, 0xB928A8A9, + 0x0004002B, 0x0000000D, 0x00000112, 0xBAF5F5F6, 0x0004002B, 0x0000000D, 0x00000271, 0xBA5ADADB, + 0x0004002B, 0x0000000D, 0x000002D1, 0x3A26A6A7, 0x0004002B, 0x0000000D, 0x0000057C, 0x37008081, + 0x0004002B, 0x0000000D, 0x0000038C, 0xBAF9F9FA, 0x0004002B, 0x0000000D, 0x0000003D, 0xB968E8E9, + 0x0004002B, 0x0000000D, 0x00000A13, 0x39C4C4C5, 0x0004002B, 0x0000000D, 0x000001B0, 0xBAE3E3E4, + 0x0004002B, 0x0000000D, 0x00000AEF, 0xB9D4D4D5, 0x0004002B, 0x0000000D, 0x000007DF, 0xBAA1A1A2, + 0x0004002B, 0x0000000D, 0x00000842, 0x3ADFDFE0, 0x0004002B, 0x0000000D, 0x00000804, 0xBA76F6F7, + 0x0004002B, 0x0000000D, 0x00000903, 0x3A56D6D7, 0x0004002B, 0x0000000D, 0x000007A4, 0x3AF1F1F2, + 0x0004002B, 0x0000000D, 0x00000482, 0x39F4F4F5, 0x0103002C, 0x000003FB, 0x000008C2, 0x0000010F, + 0x00000728, 0x00000705, 0x00000A5A, 0x000008DF, 0x00000094, 0x0000034C, 0x0000087E, 0x0000034D, + 0x00000687, 0x000003EB, 0x0000024E, 0x00000726, 0x00000698, 0x00000703, 0x00000AF8, 0x00000ABB, + 0x0000026F, 0x000008A8, 0x00000565, 0x0000065D, 0x000004C6, 0x00000057, 0x0000006A, 0x00000A1E, + 0x0000087D, 0x00000959, 0x00000BB8, 0x0000097E, 0x00000606, 0x000003AD, 0x000000E2, 0x00000370, + 0x0000024D, 0x000005C6, 0x00000B8C, 0x00000036, 0x0000087F, 0x00000172, 0x00000399, 0x0000040F, + 0x0000091E, 0x000008D5, 0x000008DE, 0x000002EB, 0x00000317, 0x0000034E, 0x00000111, 0x0000002B, + 0x000008E1, 0x0000042A, 0x00000765, 0x000009A2, 0x000004F2, 0x0000058A, 0x000007E0, 0x00000802, + 0x00000A1C, 0x00000940, 0x000002EC, 0x000003ED, 0x000004EB, 0x00000234, 0x00000245, 0x00000603, + 0x00000984, 0x0000076E, 0x00000841, 0x000009DD, 0x000003F3, 0x00000B5A, 0x00000B58, 0x00000838, + 0x00000218, 0x00000A1D, 0x0000054B, 0x00000503, 0x00000169, 0x00000605, 0x0000048A, 0x000002D3, + 0x00000A7C, 0x00000171, 0x000001AF, 0x000004AC, 0x0000024F, 0x00000ADE, 0x00000110, 0x00000212, + 0x00000742, 0x00000389, 0x000006C4, 0x00000B98, 0x000002AE, 0x000009B1, 0x00000741, 0x00000211, + 0x00000A5B, 0x000005EA, 0x00000310, 0x0000052A, 0x00000071, 0x00000107, 0x000006A2, 0x00000B1B, + 0x00000034, 0x0000024B, 0x000002AF, 0x00000A41, 0x00000A7E, 0x0000034F, 0x00000901, 0x00000539, + 0x0000091C, 0x000001A4, 0x00000666, 0x00000833, 0x00000206, 0x00000210, 0x000002ED, 0x0000040D, + 0x00000428, 0x00000195, 0x000004C7, 0x00000AB0, 0x00000429, 0x00000B5F, 0x0000044C, 0x00000B59, + 0x00000344, 0x000007C7, 0x00000739, 0x0000091D, 0x000000D2, 0x00000133, 0x000005C8, 0x00000A1B, + 0x00000420, 0x000002B0, 0x00000A25, 0x0000030E, 0x0000048B, 0x00000B7D, 0x00000073, 0x00000740, + 0x00000173, 0x000006C6, 0x00000567, 0x00000A3F, 0x00000B95, 0x0000038A, 0x000005CE, 0x000006A3, + 0x000006FA, 0x00000743, 0x000007C5, 0x0000038B, 0x00000ABA, 0x00000B51, 0x00000914, 0x0000013C, + 0x00000566, 0x0000097D, 0x00000A58, 0x00000B5B, 0x00000704, 0x00000232, 0x000002EE, 0x000007A2, + 0x00000763, 0x00000135, 0x000000D3, 0x00000949, 0x000001D2, 0x00000604, 0x00000035, 0x000004AE, + 0x000007D6, 0x00000B7B, 0x00000AF7, 0x00000873, 0x000004E9, 0x000007E1, 0x0000097F, 0x000001AE, + 0x00000864, 0x000008E0, 0x000005A3, 0x000006A4, 0x00000667, 0x00000961, 0x000004C9, 0x00000ABC, + 0x00000627, 0x000007A3, 0x00000AF9, 0x00000528, 0x00000B24, 0x0000020F, 0x000008A1, 0x000004C8, + 0x000004BD, 0x00000976, 0x000006A5, 0x0000054D, 0x000002E2, 0x000000F6, 0x0000024C, 0x00000B97, + 0x00000055, 0x00000B96, 0x00000689, 0x00000096, 0x00000072, 0x000009A0, 0x0000014C, 0x00000059, + 0x0000048C, 0x000009BB, 0x00000588, 0x000003EC, 0x00000BBA, 0x00000665, 0x000005BC, 0x00000529, + 0x00000840, 0x0000051F, 0x000005FB, 0x000000D5, 0x000005C7, 0x000009BA, 0x000000D4, 0x000009DF, + 0x000006CD, 0x00000489, 0x000007F0, 0x000003E1, 0x000009BC, 0x00000A59, 0x0000093E, 0x000007A9, + 0x00000112, 0x00000271, 0x000002D1, 0x0000057C, 0x0000038C, 0x0000003D, 0x00000A13, 0x000001B0, + 0x00000AEF, 0x000007DF, 0x00000842, 0x00000804, 0x00000903, 0x000007A4, 0x00000482, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x00040020, + 0x00000678, 0x00000007, 0x000003FB, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x00040020, + 0x0000029A, 0x00000001, 0x0000001D, 0x0004003B, 0x0000029A, 0x00000C93, 0x00000001, 0x00040017, + 0x00000013, 0x0000000D, 0x00000002, 0x0005001E, 0x00000418, 0x00000012, 0x00000013, 0x0000000D, + 0x00040020, 0x00000695, 0x00000009, 0x00000418, 0x0004003B, 0x00000695, 0x00000CE9, 0x00000009, + 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x0000028F, 0x00000009, 0x00000012, + 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x00040020, 0x00000290, 0x00000009, 0x00000013, + 0x0004002B, 0x0000000D, 0x000000FC, 0x3F000000, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, + 0x00040020, 0x0000028B, 0x00000009, 0x0000000D, 0x00040020, 0x0000029B, 0x00000003, 0x0000001D, + 0x0004003B, 0x0000029B, 0x000014D6, 0x00000003, 0x0004002B, 0x0000000B, 0x0000020D, 0x1FBC4639, + 0x0004002B, 0x0000000B, 0x00000345, 0x7EF07EBB, 0x0004002B, 0x0000000B, 0x000000B2, 0x7EF19FFF, + 0x0004002B, 0x0000000D, 0x00000019, 0x40000000, 0x00090019, 0x00000097, 0x0000000D, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00040020, 0x00000313, 0x00000000, + 0x00000097, 0x0004003B, 0x00000313, 0x0000142B, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A08, + 0xFFFFFFFF, 0x0005002C, 0x00000012, 0x0000070B, 0x00000A0B, 0x00000A08, 0x0005002C, 0x00000012, + 0x00000714, 0x00000A0E, 0x00000A08, 0x0005002C, 0x00000012, 0x0000070E, 0x00000A08, 0x00000A0B, + 0x0005002C, 0x00000012, 0x00000720, 0x00000A0E, 0x00000A0B, 0x0005002C, 0x00000012, 0x0000071A, + 0x00000A08, 0x00000A0E, 0x0005002C, 0x00000012, 0x00000723, 0x00000A0B, 0x00000A0E, 0x0005002C, + 0x00000012, 0x0000072C, 0x00000A0E, 0x00000A0E, 0x0005002C, 0x00000012, 0x00000729, 0x00000A11, + 0x00000A0B, 0x0005002C, 0x00000012, 0x0000072F, 0x00000A0B, 0x00000A11, 0x0005002C, 0x00000012, + 0x00000735, 0x00000A11, 0x00000A0E, 0x0005002C, 0x00000012, 0x00000738, 0x00000A0E, 0x00000A11, + 0x0004002B, 0x0000000D, 0x000002C4, 0x3D000000, 0x0005002C, 0x00000013, 0x0000061E, 0x000000FC, + 0x000000FC, 0x0005002C, 0x00000011, 0x0000084A, 0x00000A37, 0x00000A37, 0x0006002C, 0x00000018, + 0x00000A2C, 0x00000A0C, 0x00000A0C, 0x00000A0C, 0x0006002C, 0x00000018, 0x00000A16, 0x0000008A, + 0x0000008A, 0x0000008A, 0x00030001, 0x0000001D, 0x00002818, 0x00050036, 0x00000008, 0x0000161F, + 0x00000000, 0x00000502, 0x000200F8, 0x00006179, 0x0004003B, 0x00000678, 0x000047EB, 0x00000007, + 0x0004003D, 0x0000001D, 0x00005647, 0x00000C93, 0x0007004F, 0x00000013, 0x000019A2, 0x00005647, + 0x00005647, 0x00000000, 0x00000001, 0x0004006E, 0x00000012, 0x000044F8, 0x000019A2, 0x00050041, + 0x0000028F, 0x00004B4F, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x00000012, 0x00005926, 0x00004B4F, + 0x00050082, 0x00000012, 0x00005B10, 0x000044F8, 0x00005926, 0x0004007C, 0x00000011, 0x000026D2, + 0x00005B10, 0x00050041, 0x00000290, 0x00005205, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x00000013, + 0x00005833, 0x00005205, 0x0004007C, 0x00000011, 0x00003455, 0x00005833, 0x0005008E, 0x00000013, + 0x000031DA, 0x00005833, 0x000000FC, 0x00050083, 0x00000013, 0x00006013, 0x000031DA, 0x0000061E, + 0x0004007C, 0x00000011, 0x0000454F, 0x00006013, 0x00050051, 0x0000000B, 0x00004143, 0x00003455, + 0x00000000, 0x00050051, 0x0000000B, 0x000033E3, 0x00003455, 0x00000001, 0x00050051, 0x0000000B, + 0x00001DD9, 0x0000454F, 0x00000000, 0x00050051, 0x0000000B, 0x00001D69, 0x0000454F, 0x00000001, + 0x00070050, 0x00000017, 0x00004741, 0x00004143, 0x000033E3, 0x00001DD9, 0x00001D69, 0x00050041, + 0x0000028B, 0x00002631, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000D, 0x00004978, 0x00002631, + 0x0004007C, 0x0000000B, 0x000044BF, 0x00004978, 0x00040070, 0x00000013, 0x00004CA9, 0x000026D2, + 0x0007004F, 0x00000011, 0x000020FA, 0x00004741, 0x00004741, 0x00000000, 0x00000001, 0x0004007C, + 0x00000013, 0x00002D38, 0x000020FA, 0x00050085, 0x00000013, 0x0000514E, 0x00004CA9, 0x00002D38, + 0x0007004F, 0x00000011, 0x00002322, 0x00004741, 0x00004741, 0x00000002, 0x00000003, 0x0004007C, + 0x00000013, 0x00002E15, 0x00002322, 0x00050081, 0x00000013, 0x00004E65, 0x0000514E, 0x00002E15, + 0x0006000C, 0x00000013, 0x000031AF, 0x00000001, 0x00000008, 0x00004E65, 0x00050083, 0x00000013, + 0x00003FA2, 0x00004E65, 0x000031AF, 0x0004006E, 0x00000012, 0x000042A8, 0x000031AF, 0x00050080, + 0x00000012, 0x00005058, 0x000042A8, 0x0000070B, 0x0004003D, 0x00000097, 0x0000472F, 0x0000142B, + 0x0007005F, 0x0000001D, 0x00004C03, 0x0000472F, 0x00005058, 0x00000002, 0x00000A0B, 0x00050080, + 0x00000012, 0x00003423, 0x000042A8, 0x0000070E, 0x0004003D, 0x00000097, 0x000038CA, 0x0000142B, + 0x0007005F, 0x0000001D, 0x00003151, 0x000038CA, 0x00003423, 0x00000002, 0x00000A0B, 0x0004003D, + 0x00000097, 0x000028B5, 0x0000142B, 0x0007005F, 0x0000001D, 0x00003C54, 0x000028B5, 0x000042A8, + 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x00003424, 0x000042A8, 0x00000714, 0x0004003D, + 0x00000097, 0x00003DC3, 0x0000142B, 0x0007005F, 0x0000001D, 0x00004C04, 0x00003DC3, 0x00003424, + 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x00003425, 0x000042A8, 0x00000720, 0x0004003D, + 0x00000097, 0x00003DC4, 0x0000142B, 0x0007005F, 0x0000001D, 0x00004C05, 0x00003DC4, 0x00003425, + 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x00003426, 0x000042A8, 0x00000729, 0x0004003D, + 0x00000097, 0x00003DC5, 0x0000142B, 0x0007005F, 0x0000001D, 0x00004C06, 0x00003DC5, 0x00003426, + 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x00003427, 0x000042A8, 0x0000071A, 0x0004003D, + 0x00000097, 0x00003DC6, 0x0000142B, 0x0007005F, 0x0000001D, 0x00004C07, 0x00003DC6, 0x00003427, + 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x00003428, 0x000042A8, 0x00000723, 0x0004003D, + 0x00000097, 0x00003DC7, 0x0000142B, 0x0007005F, 0x0000001D, 0x00004C08, 0x00003DC7, 0x00003428, + 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x00003429, 0x000042A8, 0x0000072F, 0x0004003D, + 0x00000097, 0x00003DC8, 0x0000142B, 0x0007005F, 0x0000001D, 0x00004C09, 0x00003DC8, 0x00003429, + 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x0000342A, 0x000042A8, 0x0000072C, 0x0004003D, + 0x00000097, 0x00003DC9, 0x0000142B, 0x0007005F, 0x0000001D, 0x00004C0A, 0x00003DC9, 0x0000342A, + 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x0000342B, 0x000042A8, 0x00000735, 0x0004003D, + 0x00000097, 0x00003DCA, 0x0000142B, 0x0007005F, 0x0000001D, 0x00004C0B, 0x00003DCA, 0x0000342B, + 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x0000342C, 0x000042A8, 0x00000738, 0x0004003D, + 0x00000097, 0x00003A46, 0x0000142B, 0x0007005F, 0x0000001D, 0x000022C3, 0x00003A46, 0x0000342C, + 0x00000002, 0x00000A0B, 0x00050051, 0x0000000D, 0x00004D11, 0x00004C03, 0x00000000, 0x00050051, + 0x0000000D, 0x00001B71, 0x00004C03, 0x00000001, 0x00050051, 0x0000000D, 0x00004923, 0x00004C03, + 0x00000002, 0x00050085, 0x0000000D, 0x0000611F, 0x00004D11, 0x00004D11, 0x00050085, 0x0000000D, + 0x00003F38, 0x00001B71, 0x00001B71, 0x00050085, 0x0000000D, 0x00002459, 0x00004923, 0x00004923, + 0x00050051, 0x0000000D, 0x000056DC, 0x00004C04, 0x00000000, 0x00050051, 0x0000000D, 0x00002E44, + 0x00004C04, 0x00000001, 0x00050051, 0x0000000D, 0x00004924, 0x00004C04, 0x00000002, 0x00050085, + 0x0000000D, 0x00006120, 0x000056DC, 0x000056DC, 0x00050085, 0x0000000D, 0x00003F39, 0x00002E44, + 0x00002E44, 0x00050085, 0x0000000D, 0x0000245A, 0x00004924, 0x00004924, 0x00050051, 0x0000000D, + 0x000056DD, 0x00003151, 0x00000000, 0x00050051, 0x0000000D, 0x00002E45, 0x00003151, 0x00000001, + 0x00050051, 0x0000000D, 0x00004925, 0x00003151, 0x00000002, 0x00050085, 0x0000000D, 0x00006121, + 0x000056DD, 0x000056DD, 0x00050085, 0x0000000D, 0x00003F3A, 0x00002E45, 0x00002E45, 0x00050085, + 0x0000000D, 0x0000245B, 0x00004925, 0x00004925, 0x00050051, 0x0000000D, 0x000056DE, 0x00003C54, + 0x00000000, 0x00050051, 0x0000000D, 0x00002E46, 0x00003C54, 0x00000001, 0x00050051, 0x0000000D, + 0x00004926, 0x00003C54, 0x00000002, 0x00050085, 0x0000000D, 0x00006122, 0x000056DE, 0x000056DE, + 0x00050085, 0x0000000D, 0x00003F3B, 0x00002E46, 0x00002E46, 0x00050085, 0x0000000D, 0x0000245C, + 0x00004926, 0x00004926, 0x00050051, 0x0000000D, 0x000056DF, 0x00004C05, 0x00000000, 0x00050051, + 0x0000000D, 0x00002E47, 0x00004C05, 0x00000001, 0x00050051, 0x0000000D, 0x00004927, 0x00004C05, + 0x00000002, 0x00050085, 0x0000000D, 0x00006123, 0x000056DF, 0x000056DF, 0x00050085, 0x0000000D, + 0x00003F3C, 0x00002E47, 0x00002E47, 0x00050085, 0x0000000D, 0x0000245D, 0x00004927, 0x00004927, + 0x00050051, 0x0000000D, 0x000056E0, 0x00004C06, 0x00000000, 0x00050051, 0x0000000D, 0x00002E48, + 0x00004C06, 0x00000001, 0x00050051, 0x0000000D, 0x00004928, 0x00004C06, 0x00000002, 0x00050085, + 0x0000000D, 0x00006124, 0x000056E0, 0x000056E0, 0x00050085, 0x0000000D, 0x00003F3D, 0x00002E48, + 0x00002E48, 0x00050085, 0x0000000D, 0x0000245E, 0x00004928, 0x00004928, 0x00050051, 0x0000000D, + 0x000056E1, 0x00004C07, 0x00000000, 0x00050051, 0x0000000D, 0x00002E49, 0x00004C07, 0x00000001, + 0x00050051, 0x0000000D, 0x00004929, 0x00004C07, 0x00000002, 0x00050085, 0x0000000D, 0x00006125, + 0x000056E1, 0x000056E1, 0x00050085, 0x0000000D, 0x00003F3E, 0x00002E49, 0x00002E49, 0x00050085, + 0x0000000D, 0x0000245F, 0x00004929, 0x00004929, 0x00050051, 0x0000000D, 0x000056E2, 0x00004C08, + 0x00000000, 0x00050051, 0x0000000D, 0x00002E4A, 0x00004C08, 0x00000001, 0x00050051, 0x0000000D, + 0x0000492A, 0x00004C08, 0x00000002, 0x00050085, 0x0000000D, 0x00006126, 0x000056E2, 0x000056E2, + 0x00050085, 0x0000000D, 0x00003F3F, 0x00002E4A, 0x00002E4A, 0x00050085, 0x0000000D, 0x00002460, + 0x0000492A, 0x0000492A, 0x00050051, 0x0000000D, 0x000056E3, 0x00004C0A, 0x00000000, 0x00050051, + 0x0000000D, 0x00002E4B, 0x00004C0A, 0x00000001, 0x00050051, 0x0000000D, 0x0000492B, 0x00004C0A, + 0x00000002, 0x00050085, 0x0000000D, 0x00006127, 0x000056E3, 0x000056E3, 0x00050085, 0x0000000D, + 0x00003F40, 0x00002E4B, 0x00002E4B, 0x00050085, 0x0000000D, 0x00002461, 0x0000492B, 0x0000492B, + 0x00050051, 0x0000000D, 0x000056E4, 0x00004C0B, 0x00000000, 0x00050051, 0x0000000D, 0x00002E4C, + 0x00004C0B, 0x00000001, 0x00050051, 0x0000000D, 0x0000492C, 0x00004C0B, 0x00000002, 0x00050085, + 0x0000000D, 0x00006128, 0x000056E4, 0x000056E4, 0x00050085, 0x0000000D, 0x00003F41, 0x00002E4C, + 0x00002E4C, 0x00050085, 0x0000000D, 0x00002462, 0x0000492C, 0x0000492C, 0x00050051, 0x0000000D, + 0x000056E5, 0x00004C09, 0x00000000, 0x00050051, 0x0000000D, 0x00002E4D, 0x00004C09, 0x00000001, + 0x00050051, 0x0000000D, 0x0000492D, 0x00004C09, 0x00000002, 0x00050085, 0x0000000D, 0x00006129, + 0x000056E5, 0x000056E5, 0x00050085, 0x0000000D, 0x00003F42, 0x00002E4D, 0x00002E4D, 0x00050085, + 0x0000000D, 0x00002463, 0x0000492D, 0x0000492D, 0x00050051, 0x0000000D, 0x000056E6, 0x000022C3, + 0x00000000, 0x00050051, 0x0000000D, 0x00002E4E, 0x000022C3, 0x00000001, 0x00050051, 0x0000000D, + 0x0000492E, 0x000022C3, 0x00000002, 0x00050085, 0x0000000D, 0x0000612A, 0x000056E6, 0x000056E6, + 0x00050085, 0x0000000D, 0x00003A3E, 0x00002E4E, 0x00002E4E, 0x00050085, 0x0000000D, 0x0000218E, + 0x0000492E, 0x0000492E, 0x0007000C, 0x0000000D, 0x00002A7D, 0x00000001, 0x00000025, 0x00003F3A, + 0x00003F3B, 0x0007000C, 0x0000000D, 0x0000243C, 0x00000001, 0x00000025, 0x00003F38, 0x00002A7D, + 0x0007000C, 0x0000000D, 0x00003E4F, 0x00000001, 0x00000025, 0x00003F3C, 0x00003F3F, 0x0007000C, + 0x0000000D, 0x00002A99, 0x00000001, 0x00000025, 0x0000243C, 0x00003E4F, 0x0007000C, 0x0000000D, + 0x00005EE8, 0x00000001, 0x00000028, 0x00003F3A, 0x00003F3B, 0x0007000C, 0x0000000D, 0x00004473, + 0x00000001, 0x00000028, 0x00003F38, 0x00005EE8, 0x0007000C, 0x0000000D, 0x00005558, 0x00000001, + 0x00000028, 0x00003F3C, 0x00003F3F, 0x0007000C, 0x0000000D, 0x00001E8F, 0x00000001, 0x00000028, + 0x00004473, 0x00005558, 0x0007000C, 0x0000000D, 0x000034BF, 0x00000001, 0x00000025, 0x00003F3B, + 0x00003F3C, 0x0007000C, 0x0000000D, 0x000035FB, 0x00000001, 0x00000025, 0x00003F39, 0x000034BF, + 0x0007000C, 0x0000000D, 0x00003E50, 0x00000001, 0x00000025, 0x00003F3D, 0x00003F40, 0x0007000C, + 0x0000000D, 0x00002A9A, 0x00000001, 0x00000025, 0x000035FB, 0x00003E50, 0x0007000C, 0x0000000D, + 0x00005EE9, 0x00000001, 0x00000028, 0x00003F3B, 0x00003F3C, 0x0007000C, 0x0000000D, 0x00004474, + 0x00000001, 0x00000028, 0x00003F39, 0x00005EE9, 0x0007000C, 0x0000000D, 0x00005559, 0x00000001, + 0x00000028, 0x00003F3D, 0x00003F40, 0x0007000C, 0x0000000D, 0x00001E90, 0x00000001, 0x00000028, + 0x00004474, 0x00005559, 0x0007000C, 0x0000000D, 0x000034C0, 0x00000001, 0x00000025, 0x00003F3E, + 0x00003F3F, 0x0007000C, 0x0000000D, 0x000035FC, 0x00000001, 0x00000025, 0x00003F3B, 0x000034C0, + 0x0007000C, 0x0000000D, 0x00003E51, 0x00000001, 0x00000025, 0x00003F40, 0x00003F42, 0x0007000C, + 0x0000000D, 0x00002A9B, 0x00000001, 0x00000025, 0x000035FC, 0x00003E51, 0x0007000C, 0x0000000D, + 0x00005EEA, 0x00000001, 0x00000028, 0x00003F3E, 0x00003F3F, 0x0007000C, 0x0000000D, 0x00004475, + 0x00000001, 0x00000028, 0x00003F3B, 0x00005EEA, 0x0007000C, 0x0000000D, 0x0000555A, 0x00000001, + 0x00000028, 0x00003F40, 0x00003F42, 0x0007000C, 0x0000000D, 0x00001E91, 0x00000001, 0x00000028, + 0x00004475, 0x0000555A, 0x0007000C, 0x0000000D, 0x000034C1, 0x00000001, 0x00000025, 0x00003F3F, + 0x00003F40, 0x0007000C, 0x0000000D, 0x000035FD, 0x00000001, 0x00000025, 0x00003F3C, 0x000034C1, + 0x0007000C, 0x0000000D, 0x00003E52, 0x00000001, 0x00000025, 0x00003F41, 0x00003A3E, 0x0007000C, + 0x0000000D, 0x00002A9C, 0x00000001, 0x00000025, 0x000035FD, 0x00003E52, 0x0007000C, 0x0000000D, + 0x00005EEB, 0x00000001, 0x00000028, 0x00003F3F, 0x00003F40, 0x0007000C, 0x0000000D, 0x00004476, + 0x00000001, 0x00000028, 0x00003F3C, 0x00005EEB, 0x0007000C, 0x0000000D, 0x00005D83, 0x00000001, + 0x00000028, 0x00003F41, 0x00003A3E, 0x0007000C, 0x0000000D, 0x0000526D, 0x00000001, 0x00000028, + 0x00004476, 0x00005D83, 0x0004007C, 0x0000000B, 0x00001FF5, 0x00001E8F, 0x00050082, 0x0000000B, + 0x00002272, 0x00000345, 0x00001FF5, 0x0004007C, 0x0000000D, 0x00002699, 0x00002272, 0x0004007C, + 0x0000000B, 0x00003AD6, 0x00001E90, 0x00050082, 0x0000000B, 0x00001A2E, 0x00000345, 0x00003AD6, + 0x0004007C, 0x0000000D, 0x0000269A, 0x00001A2E, 0x0004007C, 0x0000000B, 0x00003AD7, 0x00001E91, + 0x00050082, 0x0000000B, 0x00001A2F, 0x00000345, 0x00003AD7, 0x0004007C, 0x0000000D, 0x0000269B, + 0x00001A2F, 0x0004007C, 0x0000000B, 0x00003AD8, 0x0000526D, 0x00050082, 0x0000000B, 0x00001AB3, + 0x00000345, 0x00003AD8, 0x0004007C, 0x0000000D, 0x00001941, 0x00001AB3, 0x00050083, 0x0000000D, + 0x00005E43, 0x0000008A, 0x00001E8F, 0x0007000C, 0x0000000D, 0x00005B1C, 0x00000001, 0x00000025, + 0x00002A99, 0x00005E43, 0x00050085, 0x0000000D, 0x000059FC, 0x00005B1C, 0x00002699, 0x0008000C, + 0x0000000D, 0x00003EB3, 0x00000001, 0x0000002B, 0x000059FC, 0x00000A0C, 0x0000008A, 0x00050083, + 0x0000000D, 0x000061AD, 0x0000008A, 0x00001E90, 0x0007000C, 0x0000000D, 0x000029C9, 0x00000001, + 0x00000025, 0x00002A9A, 0x000061AD, 0x00050085, 0x0000000D, 0x000059FD, 0x000029C9, 0x0000269A, + 0x0008000C, 0x0000000D, 0x00003EB4, 0x00000001, 0x0000002B, 0x000059FD, 0x00000A0C, 0x0000008A, + 0x00050083, 0x0000000D, 0x000061AE, 0x0000008A, 0x00001E91, 0x0007000C, 0x0000000D, 0x000029CA, + 0x00000001, 0x00000025, 0x00002A9B, 0x000061AE, 0x00050085, 0x0000000D, 0x000059FE, 0x000029CA, + 0x0000269B, 0x0008000C, 0x0000000D, 0x00003EB5, 0x00000001, 0x0000002B, 0x000059FE, 0x00000A0C, + 0x0000008A, 0x00050083, 0x0000000D, 0x000061AF, 0x0000008A, 0x0000526D, 0x0007000C, 0x0000000D, + 0x000029CB, 0x00000001, 0x00000025, 0x00002A9C, 0x000061AF, 0x00050085, 0x0000000D, 0x00005977, + 0x000029CB, 0x00001941, 0x0008000C, 0x0000000D, 0x000050CB, 0x00000001, 0x0000002B, 0x00005977, + 0x00000A0C, 0x0000008A, 0x0004007C, 0x0000000B, 0x00005DCB, 0x00003EB3, 0x000500C2, 0x0000000B, + 0x0000564A, 0x00005DCB, 0x00000A0D, 0x00050080, 0x0000000B, 0x00005ABD, 0x0000564A, 0x0000020D, + 0x0004007C, 0x0000000D, 0x00005943, 0x00005ABD, 0x0004007C, 0x0000000B, 0x000022CE, 0x00003EB4, + 0x000500C2, 0x0000000B, 0x000023E5, 0x000022CE, 0x00000A0D, 0x00050080, 0x0000000B, 0x00005ABE, + 0x000023E5, 0x0000020D, 0x0004007C, 0x0000000D, 0x00005944, 0x00005ABE, 0x0004007C, 0x0000000B, + 0x000022CF, 0x00003EB5, 0x000500C2, 0x0000000B, 0x000023E6, 0x000022CF, 0x00000A0D, 0x00050080, + 0x0000000B, 0x00005ABF, 0x000023E6, 0x0000020D, 0x0004007C, 0x0000000D, 0x00005945, 0x00005ABF, + 0x0004007C, 0x0000000B, 0x000022D0, 0x000050CB, 0x000500C2, 0x0000000B, 0x000023E7, 0x000022D0, + 0x00000A0D, 0x00050080, 0x0000000B, 0x00005AC0, 0x000023E7, 0x0000020D, 0x0004007C, 0x0000000D, + 0x000054BC, 0x00005AC0, 0x0004007C, 0x0000000D, 0x00004C66, 0x000044BF, 0x00050085, 0x0000000D, + 0x000049BF, 0x00005943, 0x00004C66, 0x00050085, 0x0000000D, 0x0000590B, 0x00005944, 0x00004C66, + 0x00050085, 0x0000000D, 0x00004BB4, 0x00005945, 0x00004C66, 0x00050085, 0x0000000D, 0x0000280F, + 0x000054BC, 0x00004C66, 0x00050051, 0x0000000D, 0x00003512, 0x00003FA2, 0x00000000, 0x00050083, + 0x0000000D, 0x000054D6, 0x0000008A, 0x00003512, 0x00050051, 0x0000000D, 0x00002E64, 0x00003FA2, + 0x00000001, 0x00050083, 0x0000000D, 0x00002B8B, 0x0000008A, 0x00002E64, 0x00050085, 0x0000000D, + 0x00004506, 0x000054D6, 0x00002B8B, 0x00050085, 0x0000000D, 0x0000627C, 0x00003512, 0x00002B8B, + 0x00050085, 0x0000000D, 0x00004F6A, 0x000054D6, 0x00002E64, 0x00050085, 0x0000000D, 0x0000509E, + 0x00003512, 0x00002E64, 0x00050083, 0x0000000D, 0x0000471C, 0x00001E8F, 0x00002A99, 0x00050081, + 0x0000000D, 0x00005B9D, 0x000002C4, 0x0000471C, 0x0004007C, 0x0000000B, 0x00002C83, 0x00005B9D, + 0x00050082, 0x0000000B, 0x00001DFD, 0x00000345, 0x00002C83, 0x0004007C, 0x0000000D, 0x00002097, + 0x00001DFD, 0x00050085, 0x0000000D, 0x0000447B, 0x00004506, 0x00002097, 0x00050083, 0x0000000D, + 0x00005097, 0x00001E90, 0x00002A9A, 0x00050081, 0x0000000D, 0x00005B9E, 0x000002C4, 0x00005097, + 0x0004007C, 0x0000000B, 0x00002C84, 0x00005B9E, 0x00050082, 0x0000000B, 0x00001DFE, 0x00000345, + 0x00002C84, 0x0004007C, 0x0000000D, 0x00002098, 0x00001DFE, 0x00050085, 0x0000000D, 0x0000447C, + 0x0000627C, 0x00002098, 0x00050083, 0x0000000D, 0x00005098, 0x00001E91, 0x00002A9B, 0x00050081, + 0x0000000D, 0x00005B9F, 0x000002C4, 0x00005098, 0x0004007C, 0x0000000B, 0x00002C85, 0x00005B9F, + 0x00050082, 0x0000000B, 0x00001DFF, 0x00000345, 0x00002C85, 0x0004007C, 0x0000000D, 0x00002099, + 0x00001DFF, 0x00050085, 0x0000000D, 0x0000447D, 0x00004F6A, 0x00002099, 0x00050083, 0x0000000D, + 0x00005099, 0x0000526D, 0x00002A9C, 0x00050081, 0x0000000D, 0x00005BA0, 0x000002C4, 0x00005099, + 0x0004007C, 0x0000000B, 0x00002C86, 0x00005BA0, 0x00050082, 0x0000000B, 0x00001E00, 0x00000345, + 0x00002C86, 0x0004007C, 0x0000000D, 0x000020BD, 0x00001E00, 0x00050085, 0x0000000D, 0x0000436D, + 0x0000509E, 0x000020BD, 0x00050085, 0x0000000D, 0x0000590C, 0x000049BF, 0x0000447B, 0x00050085, + 0x0000000D, 0x00004F44, 0x0000590B, 0x0000447C, 0x00050085, 0x0000000D, 0x000051F8, 0x00004BB4, + 0x0000447D, 0x00050081, 0x0000000D, 0x00003D4A, 0x00004F44, 0x000051F8, 0x00050081, 0x0000000D, + 0x00005767, 0x00003D4A, 0x0000447B, 0x00050085, 0x0000000D, 0x00003135, 0x0000280F, 0x0000436D, + 0x00050081, 0x0000000D, 0x0000499D, 0x0000590C, 0x00003135, 0x00050081, 0x0000000D, 0x00005A1B, + 0x0000499D, 0x0000447C, 0x00050081, 0x0000000D, 0x00001C3B, 0x0000499D, 0x0000447D, 0x00050081, + 0x0000000D, 0x00001C3C, 0x00003D4A, 0x0000436D, 0x00050081, 0x0000000D, 0x00001C3D, 0x0000590C, + 0x00004F44, 0x00050081, 0x0000000D, 0x00001C87, 0x00001C3D, 0x000051F8, 0x00050081, 0x0000000D, + 0x00001987, 0x00001C87, 0x00003135, 0x00050085, 0x0000000D, 0x00003136, 0x00000019, 0x00001987, + 0x00050081, 0x0000000D, 0x0000499E, 0x00003136, 0x00005767, 0x00050081, 0x0000000D, 0x00005A1C, + 0x0000499E, 0x00005A1B, 0x00050081, 0x0000000D, 0x00001BDC, 0x00005A1C, 0x00001C3B, 0x00050081, + 0x0000000D, 0x00001FAF, 0x00001BDC, 0x00001C3C, 0x0004007C, 0x0000000B, 0x00002636, 0x00001FAF, + 0x00050082, 0x0000000B, 0x00001D8B, 0x000000B2, 0x00002636, 0x0004007C, 0x0000000D, 0x000024CB, + 0x00001D8B, 0x0004007F, 0x0000000D, 0x000023AA, 0x000024CB, 0x00050085, 0x0000000D, 0x0000304F, + 0x000023AA, 0x00001FAF, 0x00050081, 0x0000000D, 0x0000409C, 0x0000304F, 0x00000019, 0x00050085, + 0x0000000D, 0x000024E2, 0x000024CB, 0x0000409C, 0x00050081, 0x0000000D, 0x00004735, 0x0000611F, + 0x00006121, 0x00050085, 0x0000000D, 0x000021E2, 0x0000590C, 0x00004735, 0x00050085, 0x0000000D, + 0x00005EE3, 0x00006120, 0x00004F44, 0x00050081, 0x0000000D, 0x00003A4A, 0x000021E2, 0x00005EE3, + 0x00050085, 0x0000000D, 0x000024E3, 0x00006124, 0x00004F44, 0x00050081, 0x0000000D, 0x000046E9, + 0x00003A4A, 0x000024E3, 0x00050085, 0x0000000D, 0x000024E4, 0x00006125, 0x000051F8, 0x00050081, + 0x0000000D, 0x000046EA, 0x000046E9, 0x000024E4, 0x00050085, 0x0000000D, 0x000024E5, 0x00006129, + 0x000051F8, 0x00050081, 0x0000000D, 0x000046EB, 0x000046EA, 0x000024E5, 0x00050085, 0x0000000D, + 0x000024E6, 0x00006128, 0x00003135, 0x00050081, 0x0000000D, 0x000046EC, 0x000046EB, 0x000024E6, + 0x00050085, 0x0000000D, 0x000024E7, 0x0000612A, 0x00003135, 0x00050081, 0x0000000D, 0x000046ED, + 0x000046EC, 0x000024E7, 0x00050085, 0x0000000D, 0x000024E8, 0x00006122, 0x00005767, 0x00050081, + 0x0000000D, 0x000046EE, 0x000046ED, 0x000024E8, 0x00050085, 0x0000000D, 0x000024E9, 0x00006123, + 0x00005A1B, 0x00050081, 0x0000000D, 0x000046EF, 0x000046EE, 0x000024E9, 0x00050085, 0x0000000D, + 0x000024EA, 0x00006126, 0x00001C3B, 0x00050081, 0x0000000D, 0x000046F0, 0x000046EF, 0x000024EA, + 0x00050085, 0x0000000D, 0x000024EB, 0x00006127, 0x00001C3C, 0x00050081, 0x0000000D, 0x00003E65, + 0x000046F0, 0x000024EB, 0x00050085, 0x0000000D, 0x00001FC9, 0x00003E65, 0x000024E2, 0x0008000C, + 0x0000000D, 0x00003B72, 0x00000001, 0x0000002B, 0x00001FC9, 0x00000A0C, 0x0000008A, 0x00050081, + 0x0000000D, 0x000031DD, 0x00003F38, 0x00003F3A, 0x00050085, 0x0000000D, 0x00004489, 0x0000590C, + 0x000031DD, 0x00050085, 0x0000000D, 0x00005EE4, 0x00003F39, 0x00004F44, 0x00050081, 0x0000000D, + 0x00003A4B, 0x00004489, 0x00005EE4, 0x00050085, 0x0000000D, 0x000024EC, 0x00003F3D, 0x00004F44, + 0x00050081, 0x0000000D, 0x000046F1, 0x00003A4B, 0x000024EC, 0x00050085, 0x0000000D, 0x000024ED, + 0x00003F3E, 0x000051F8, 0x00050081, 0x0000000D, 0x000046F2, 0x000046F1, 0x000024ED, 0x00050085, + 0x0000000D, 0x000024EE, 0x00003F42, 0x000051F8, 0x00050081, 0x0000000D, 0x000046F3, 0x000046F2, + 0x000024EE, 0x00050085, 0x0000000D, 0x000024EF, 0x00003F41, 0x00003135, 0x00050081, 0x0000000D, + 0x000046F4, 0x000046F3, 0x000024EF, 0x00050085, 0x0000000D, 0x000024F0, 0x00003A3E, 0x00003135, + 0x00050081, 0x0000000D, 0x000046F5, 0x000046F4, 0x000024F0, 0x00050085, 0x0000000D, 0x000024F1, + 0x00003F3B, 0x00005767, 0x00050081, 0x0000000D, 0x000046F6, 0x000046F5, 0x000024F1, 0x00050085, + 0x0000000D, 0x000024F2, 0x00003F3C, 0x00005A1B, 0x00050081, 0x0000000D, 0x000046F7, 0x000046F6, + 0x000024F2, 0x00050085, 0x0000000D, 0x000024F3, 0x00003F3F, 0x00001C3B, 0x00050081, 0x0000000D, + 0x000046F8, 0x000046F7, 0x000024F3, 0x00050085, 0x0000000D, 0x000024F4, 0x00003F40, 0x00001C3C, + 0x00050081, 0x0000000D, 0x00003E66, 0x000046F8, 0x000024F4, 0x00050085, 0x0000000D, 0x00001FCA, + 0x00003E66, 0x000024E2, 0x0008000C, 0x0000000D, 0x00003B73, 0x00000001, 0x0000002B, 0x00001FCA, + 0x00000A0C, 0x0000008A, 0x00050081, 0x0000000D, 0x000031DE, 0x00002459, 0x0000245B, 0x00050085, + 0x0000000D, 0x0000448A, 0x0000590C, 0x000031DE, 0x00050085, 0x0000000D, 0x00005EE5, 0x0000245A, + 0x00004F44, 0x00050081, 0x0000000D, 0x00003A4C, 0x0000448A, 0x00005EE5, 0x00050085, 0x0000000D, + 0x000024F5, 0x0000245E, 0x00004F44, 0x00050081, 0x0000000D, 0x000046F9, 0x00003A4C, 0x000024F5, + 0x00050085, 0x0000000D, 0x000024F6, 0x0000245F, 0x000051F8, 0x00050081, 0x0000000D, 0x000046FA, + 0x000046F9, 0x000024F6, 0x00050085, 0x0000000D, 0x000024F7, 0x00002463, 0x000051F8, 0x00050081, + 0x0000000D, 0x000046FB, 0x000046FA, 0x000024F7, 0x00050085, 0x0000000D, 0x000024F8, 0x00002462, + 0x00003135, 0x00050081, 0x0000000D, 0x000046FC, 0x000046FB, 0x000024F8, 0x00050085, 0x0000000D, + 0x000024F9, 0x0000218E, 0x00003135, 0x00050081, 0x0000000D, 0x000046FD, 0x000046FC, 0x000024F9, + 0x00050085, 0x0000000D, 0x000024FA, 0x0000245C, 0x00005767, 0x00050081, 0x0000000D, 0x000046FE, + 0x000046FD, 0x000024FA, 0x00050085, 0x0000000D, 0x000024FB, 0x0000245D, 0x00005A1B, 0x00050081, + 0x0000000D, 0x000046FF, 0x000046FE, 0x000024FB, 0x00050085, 0x0000000D, 0x000024FC, 0x00002460, + 0x00001C3B, 0x00050081, 0x0000000D, 0x00004700, 0x000046FF, 0x000024FC, 0x00050085, 0x0000000D, + 0x000024FD, 0x00002461, 0x00001C3C, 0x00050081, 0x0000000D, 0x00003E67, 0x00004700, 0x000024FD, + 0x00050085, 0x0000000D, 0x00001C4C, 0x00003E67, 0x000024E2, 0x0008000C, 0x0000000D, 0x0000576C, + 0x00000001, 0x0000002B, 0x00001C4C, 0x00000A0C, 0x0000008A, 0x00060052, 0x0000001D, 0x00005ECE, + 0x00003B72, 0x00002818, 0x00000000, 0x00060052, 0x0000001D, 0x00002B42, 0x00003B73, 0x00005ECE, + 0x00000001, 0x00060052, 0x0000001D, 0x00003A55, 0x0000576C, 0x00002B42, 0x00000002, 0x0008004F, + 0x00000018, 0x0000329B, 0x00003A55, 0x00003A55, 0x00000000, 0x00000001, 0x00000002, 0x0006000C, + 0x00000018, 0x00001947, 0x00000001, 0x0000001F, 0x0000329B, 0x00050051, 0x0000000D, 0x000058D6, + 0x00001947, 0x00000000, 0x00060052, 0x0000001D, 0x00004D39, 0x000058D6, 0x00002818, 0x00000000, + 0x00050051, 0x0000000D, 0x00004D8C, 0x00001947, 0x00000001, 0x00060052, 0x0000001D, 0x00003F07, + 0x00004D8C, 0x00004D39, 0x00000001, 0x00050051, 0x0000000D, 0x00004D66, 0x00001947, 0x00000002, + 0x00060052, 0x0000001D, 0x00004910, 0x00004D66, 0x00003F07, 0x00000002, 0x0008004F, 0x00000018, + 0x00003E7D, 0x00004910, 0x00004910, 0x00000000, 0x00000001, 0x00000002, 0x000500C7, 0x00000011, + 0x00003108, 0x000026D2, 0x0000084A, 0x00050051, 0x0000000B, 0x0000260D, 0x00003108, 0x00000001, + 0x00050084, 0x0000000B, 0x000053FA, 0x0000260D, 0x00000A3A, 0x00050051, 0x0000000B, 0x00005B73, + 0x00003108, 0x00000000, 0x00050080, 0x0000000B, 0x00003142, 0x000053FA, 0x00005B73, 0x0003003E, + 0x000047EB, 0x000008C2, 0x00050041, 0x0000028A, 0x000026E6, 0x000047EB, 0x00003142, 0x0004003D, + 0x0000000D, 0x00006234, 0x000026E6, 0x00060050, 0x00000018, 0x0000466C, 0x00006234, 0x00006234, + 0x00006234, 0x00050081, 0x00000018, 0x000053D2, 0x00003E7D, 0x0000466C, 0x0008000C, 0x00000018, + 0x00004C45, 0x00000001, 0x0000002B, 0x000053D2, 0x00000A2C, 0x00000A16, 0x00050051, 0x0000000D, + 0x00004189, 0x00004C45, 0x00000000, 0x00050051, 0x0000000D, 0x00004CFC, 0x00004C45, 0x00000001, + 0x00050051, 0x0000000D, 0x00001D30, 0x00004C45, 0x00000002, 0x00070050, 0x0000001D, 0x00005788, + 0x00004189, 0x00004CFC, 0x00001D30, 0x0000008A, 0x0003003E, 0x000014D6, 0x00005788, 0x000100FD, + 0x00010038, +}; diff --git a/src/ui/shaders/vulkan_spirv/guest_output_ffx_cas_resample_ps.h b/src/ui/shaders/vulkan_spirv/guest_output_ffx_cas_resample_ps.h new file mode 100644 index 0000000..138d7f4 --- /dev/null +++ b/src/ui/shaders/vulkan_spirv/guest_output_ffx_cas_resample_ps.h @@ -0,0 +1,705 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25213 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %5663 "main" %gl_FragCoord %5334 + OpExecutionMode %5663 OriginUpperLeft + OpDecorate %gl_FragCoord BuiltIn FragCoord + OpDecorate %_struct_1048 Block + OpMemberDecorate %_struct_1048 0 Offset 16 + OpMemberDecorate %_struct_1048 1 Offset 24 + OpMemberDecorate %_struct_1048 2 Offset 32 + OpDecorate %5334 Location 0 + OpDecorate %5163 Binding 0 + OpDecorate %5163 DescriptorSet 0 + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %float = OpTypeFloat 32 + %uint = OpTypeInt 32 0 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3float = OpTypeVector %float 3 + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 + %v4float = OpTypeVector %float 4 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%gl_FragCoord = OpVariable %_ptr_Input_v4float Input + %v2float = OpTypeVector %float 2 +%_struct_1048 = OpTypeStruct %v2int %v2float %float +%_ptr_PushConstant__struct_1048 = OpTypePointer PushConstant %_struct_1048 + %3305 = OpVariable %_ptr_PushConstant__struct_1048 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_v2int = OpTypePointer PushConstant %v2int + %int_1 = OpConstant %int 1 +%_ptr_PushConstant_v2float = OpTypePointer PushConstant %v2float + %float_0_5 = OpConstant %float 0.5 + %int_2 = OpConstant %int 2 +%_ptr_PushConstant_float = OpTypePointer PushConstant %float + %float_0 = OpConstant %float 0 + %uint_1 = OpConstant %uint 1 + %float_1 = OpConstant %float 1 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %5334 = OpVariable %_ptr_Output_v4float Output +%uint_532432441 = OpConstant %uint 532432441 +%uint_2129690299 = OpConstant %uint 2129690299 +%uint_2129764351 = OpConstant %uint 2129764351 + %float_2 = OpConstant %float 2 + %150 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_150 = OpTypePointer UniformConstant %150 + %5163 = OpVariable %_ptr_UniformConstant_150 UniformConstant + %int_n1 = OpConstant %int -1 + %1803 = OpConstantComposite %v2int %int_0 %int_n1 + %1812 = OpConstantComposite %v2int %int_1 %int_n1 + %1806 = OpConstantComposite %v2int %int_n1 %int_0 + %1824 = OpConstantComposite %v2int %int_1 %int_0 + %1818 = OpConstantComposite %v2int %int_n1 %int_1 + %1827 = OpConstantComposite %v2int %int_0 %int_1 + %1836 = OpConstantComposite %v2int %int_1 %int_1 + %1833 = OpConstantComposite %v2int %int_2 %int_0 + %1839 = OpConstantComposite %v2int %int_0 %int_2 + %1845 = OpConstantComposite %v2int %int_2 %int_1 + %1848 = OpConstantComposite %v2int %int_1 %int_2 +%float_0_03125 = OpConstant %float 0.03125 + %1566 = OpConstantComposite %v2float %float_0_5 %float_0_5 + %10264 = OpUndef %v4float + %5663 = OpFunction %void None %1282 + %24949 = OpLabel + %18571 = OpLoad %v4float %gl_FragCoord + %14008 = OpVectorShuffle %v2float %18571 %18571 0 1 + %17656 = OpConvertFToS %v2int %14008 + %19279 = OpAccessChain %_ptr_PushConstant_v2int %3305 %int_0 + %22822 = OpLoad %v2int %19279 + %23312 = OpISub %v2int %17656 %22822 + %9938 = OpBitcast %v2uint %23312 + %20997 = OpAccessChain %_ptr_PushConstant_v2float %3305 %int_1 + %22579 = OpLoad %v2float %20997 + %13397 = OpBitcast %v2uint %22579 + %12762 = OpVectorTimesScalar %v2float %22579 %float_0_5 + %24595 = OpFSub %v2float %12762 %1566 + %17743 = OpBitcast %v2uint %24595 + %16707 = OpCompositeExtract %uint %13397 0 + %13283 = OpCompositeExtract %uint %13397 1 + %7641 = OpCompositeExtract %uint %17743 0 + %7529 = OpCompositeExtract %uint %17743 1 + %18241 = OpCompositeConstruct %v4uint %16707 %13283 %7641 %7529 + %9777 = OpAccessChain %_ptr_PushConstant_float %3305 %int_2 + %18808 = OpLoad %float %9777 + %17599 = OpBitcast %uint %18808 + %19625 = OpConvertUToF %v2float %9938 + %8442 = OpVectorShuffle %v2uint %18241 %18241 0 1 + %11576 = OpBitcast %v2float %8442 + %20814 = OpFMul %v2float %19625 %11576 + %8994 = OpVectorShuffle %v2uint %18241 %18241 2 3 + %11797 = OpBitcast %v2float %8994 + %20069 = OpFAdd %v2float %20814 %11797 + %12719 = OpExtInst %v2float %1 Floor %20069 + %16290 = OpFSub %v2float %20069 %12719 + %17064 = OpConvertFToS %v2int %12719 + %20568 = OpIAdd %v2int %17064 %1803 + %18223 = OpLoad %150 %5163 + %19459 = OpImageFetch %v4float %18223 %20568 Lod %int_0 + %13347 = OpIAdd %v2int %17064 %1806 + %14538 = OpLoad %150 %5163 + %12625 = OpImageFetch %v4float %14538 %13347 Lod %int_0 + %10421 = OpLoad %150 %5163 + %15444 = OpImageFetch %v4float %10421 %17064 Lod %int_0 + %13348 = OpIAdd %v2int %17064 %1812 + %15811 = OpLoad %150 %5163 + %19460 = OpImageFetch %v4float %15811 %13348 Lod %int_0 + %13349 = OpIAdd %v2int %17064 %1824 + %15812 = OpLoad %150 %5163 + %19461 = OpImageFetch %v4float %15812 %13349 Lod %int_0 + %13350 = OpIAdd %v2int %17064 %1833 + %15813 = OpLoad %150 %5163 + %19462 = OpImageFetch %v4float %15813 %13350 Lod %int_0 + %13351 = OpIAdd %v2int %17064 %1818 + %15814 = OpLoad %150 %5163 + %19463 = OpImageFetch %v4float %15814 %13351 Lod %int_0 + %13352 = OpIAdd %v2int %17064 %1827 + %15815 = OpLoad %150 %5163 + %19464 = OpImageFetch %v4float %15815 %13352 Lod %int_0 + %13353 = OpIAdd %v2int %17064 %1839 + %15816 = OpLoad %150 %5163 + %19465 = OpImageFetch %v4float %15816 %13353 Lod %int_0 + %13354 = OpIAdd %v2int %17064 %1836 + %15817 = OpLoad %150 %5163 + %19466 = OpImageFetch %v4float %15817 %13354 Lod %int_0 + %13355 = OpIAdd %v2int %17064 %1845 + %15818 = OpLoad %150 %5163 + %19467 = OpImageFetch %v4float %15818 %13355 Lod %int_0 + %13356 = OpIAdd %v2int %17064 %1848 + %14918 = OpLoad %150 %5163 + %8899 = OpImageFetch %v4float %14918 %13356 Lod %int_0 + %19729 = OpCompositeExtract %float %19459 0 + %7025 = OpCompositeExtract %float %19459 1 + %18723 = OpCompositeExtract %float %19459 2 + %24863 = OpFMul %float %19729 %19729 + %16184 = OpFMul %float %7025 %7025 + %9305 = OpFMul %float %18723 %18723 + %22236 = OpCompositeExtract %float %19460 0 + %11844 = OpCompositeExtract %float %19460 1 + %18724 = OpCompositeExtract %float %19460 2 + %24864 = OpFMul %float %22236 %22236 + %16185 = OpFMul %float %11844 %11844 + %9306 = OpFMul %float %18724 %18724 + %22237 = OpCompositeExtract %float %12625 0 + %11845 = OpCompositeExtract %float %12625 1 + %18725 = OpCompositeExtract %float %12625 2 + %24865 = OpFMul %float %22237 %22237 + %16186 = OpFMul %float %11845 %11845 + %9307 = OpFMul %float %18725 %18725 + %22238 = OpCompositeExtract %float %15444 0 + %11846 = OpCompositeExtract %float %15444 1 + %18726 = OpCompositeExtract %float %15444 2 + %24866 = OpFMul %float %22238 %22238 + %16187 = OpFMul %float %11846 %11846 + %9308 = OpFMul %float %18726 %18726 + %22239 = OpCompositeExtract %float %19461 0 + %11847 = OpCompositeExtract %float %19461 1 + %18727 = OpCompositeExtract %float %19461 2 + %24867 = OpFMul %float %22239 %22239 + %16188 = OpFMul %float %11847 %11847 + %9309 = OpFMul %float %18727 %18727 + %22240 = OpCompositeExtract %float %19462 0 + %11848 = OpCompositeExtract %float %19462 1 + %18728 = OpCompositeExtract %float %19462 2 + %24868 = OpFMul %float %22240 %22240 + %16189 = OpFMul %float %11848 %11848 + %9310 = OpFMul %float %18728 %18728 + %22241 = OpCompositeExtract %float %19463 0 + %11849 = OpCompositeExtract %float %19463 1 + %18729 = OpCompositeExtract %float %19463 2 + %24869 = OpFMul %float %22241 %22241 + %16190 = OpFMul %float %11849 %11849 + %9311 = OpFMul %float %18729 %18729 + %22242 = OpCompositeExtract %float %19464 0 + %11850 = OpCompositeExtract %float %19464 1 + %18730 = OpCompositeExtract %float %19464 2 + %24870 = OpFMul %float %22242 %22242 + %16191 = OpFMul %float %11850 %11850 + %9312 = OpFMul %float %18730 %18730 + %22243 = OpCompositeExtract %float %19466 0 + %11851 = OpCompositeExtract %float %19466 1 + %18731 = OpCompositeExtract %float %19466 2 + %24871 = OpFMul %float %22243 %22243 + %16192 = OpFMul %float %11851 %11851 + %9313 = OpFMul %float %18731 %18731 + %22244 = OpCompositeExtract %float %19467 0 + %11852 = OpCompositeExtract %float %19467 1 + %18732 = OpCompositeExtract %float %19467 2 + %24872 = OpFMul %float %22244 %22244 + %16193 = OpFMul %float %11852 %11852 + %9314 = OpFMul %float %18732 %18732 + %22245 = OpCompositeExtract %float %19465 0 + %11853 = OpCompositeExtract %float %19465 1 + %18733 = OpCompositeExtract %float %19465 2 + %24873 = OpFMul %float %22245 %22245 + %16194 = OpFMul %float %11853 %11853 + %9315 = OpFMul %float %18733 %18733 + %22246 = OpCompositeExtract %float %8899 0 + %11854 = OpCompositeExtract %float %8899 1 + %18734 = OpCompositeExtract %float %8899 2 + %24874 = OpFMul %float %22246 %22246 + %14910 = OpFMul %float %11854 %11854 + %8590 = OpFMul %float %18734 %18734 + %10877 = OpExtInst %float %1 FMin %16186 %16187 + %9276 = OpExtInst %float %1 FMin %16184 %10877 + %15951 = OpExtInst %float %1 FMin %16188 %16191 + %10905 = OpExtInst %float %1 FMin %9276 %15951 + %24296 = OpExtInst %float %1 FMax %16186 %16187 + %17523 = OpExtInst %float %1 FMax %16184 %24296 + %21848 = OpExtInst %float %1 FMax %16188 %16191 + %7823 = OpExtInst %float %1 FMax %17523 %21848 + %13503 = OpExtInst %float %1 FMin %16187 %16188 + %13819 = OpExtInst %float %1 FMin %16185 %13503 + %15952 = OpExtInst %float %1 FMin %16189 %16192 + %10906 = OpExtInst %float %1 FMin %13819 %15952 + %24297 = OpExtInst %float %1 FMax %16187 %16188 + %17524 = OpExtInst %float %1 FMax %16185 %24297 + %21849 = OpExtInst %float %1 FMax %16189 %16192 + %7824 = OpExtInst %float %1 FMax %17524 %21849 + %13504 = OpExtInst %float %1 FMin %16190 %16191 + %13820 = OpExtInst %float %1 FMin %16187 %13504 + %15953 = OpExtInst %float %1 FMin %16192 %16194 + %10907 = OpExtInst %float %1 FMin %13820 %15953 + %24298 = OpExtInst %float %1 FMax %16190 %16191 + %17525 = OpExtInst %float %1 FMax %16187 %24298 + %21850 = OpExtInst %float %1 FMax %16192 %16194 + %7825 = OpExtInst %float %1 FMax %17525 %21850 + %13505 = OpExtInst %float %1 FMin %16191 %16192 + %13821 = OpExtInst %float %1 FMin %16188 %13505 + %15954 = OpExtInst %float %1 FMin %16193 %14910 + %10908 = OpExtInst %float %1 FMin %13821 %15954 + %24299 = OpExtInst %float %1 FMax %16191 %16192 + %17526 = OpExtInst %float %1 FMax %16188 %24299 + %23939 = OpExtInst %float %1 FMax %16193 %14910 + %21101 = OpExtInst %float %1 FMax %17526 %23939 + %8181 = OpBitcast %uint %7823 + %8818 = OpISub %uint %uint_2129690299 %8181 + %9881 = OpBitcast %float %8818 + %15062 = OpBitcast %uint %7824 + %6702 = OpISub %uint %uint_2129690299 %15062 + %9882 = OpBitcast %float %6702 + %15063 = OpBitcast %uint %7825 + %6703 = OpISub %uint %uint_2129690299 %15063 + %9883 = OpBitcast %float %6703 + %15064 = OpBitcast %uint %21101 + %6835 = OpISub %uint %uint_2129690299 %15064 + %6465 = OpBitcast %float %6835 + %24131 = OpFSub %float %float_1 %7823 + %23324 = OpExtInst %float %1 FMin %10905 %24131 + %23036 = OpFMul %float %23324 %9881 + %16051 = OpExtInst %float %1 FClamp %23036 %float_0 %float_1 + %25005 = OpFSub %float %float_1 %7824 + %10697 = OpExtInst %float %1 FMin %10906 %25005 + %23037 = OpFMul %float %10697 %9882 + %16052 = OpExtInst %float %1 FClamp %23037 %float_0 %float_1 + %25006 = OpFSub %float %float_1 %7825 + %10698 = OpExtInst %float %1 FMin %10907 %25006 + %23038 = OpFMul %float %10698 %9883 + %16053 = OpExtInst %float %1 FClamp %23038 %float_0 %float_1 + %25007 = OpFSub %float %float_1 %21101 + %10699 = OpExtInst %float %1 FMin %10908 %25007 + %22903 = OpFMul %float %10699 %6465 + %20683 = OpExtInst %float %1 FClamp %22903 %float_0 %float_1 + %24011 = OpBitcast %uint %16051 + %22090 = OpShiftRightLogical %uint %24011 %uint_1 + %23229 = OpIAdd %uint %22090 %uint_532432441 + %22851 = OpBitcast %float %23229 + %8910 = OpBitcast %uint %16052 + %9189 = OpShiftRightLogical %uint %8910 %uint_1 + %23230 = OpIAdd %uint %9189 %uint_532432441 + %22852 = OpBitcast %float %23230 + %8911 = OpBitcast %uint %16053 + %9190 = OpShiftRightLogical %uint %8911 %uint_1 + %23231 = OpIAdd %uint %9190 %uint_532432441 + %22853 = OpBitcast %float %23231 + %8912 = OpBitcast %uint %20683 + %9191 = OpShiftRightLogical %uint %8912 %uint_1 + %23232 = OpIAdd %uint %9191 %uint_532432441 + %21692 = OpBitcast %float %23232 + %19558 = OpBitcast %float %17599 + %18879 = OpFMul %float %22851 %19558 + %22795 = OpFMul %float %22852 %19558 + %19380 = OpFMul %float %22853 %19558 + %10255 = OpFMul %float %21692 %19558 + %13586 = OpCompositeExtract %float %16290 0 + %21718 = OpFSub %float %float_1 %13586 + %11876 = OpCompositeExtract %float %16290 1 + %11147 = OpFSub %float %float_1 %11876 + %17670 = OpFMul %float %21718 %11147 + %25212 = OpFMul %float %13586 %11147 + %20330 = OpFMul %float %21718 %11876 + %20638 = OpFMul %float %13586 %11876 + %18204 = OpFSub %float %7823 %10905 + %23453 = OpFAdd %float %float_0_03125 %18204 + %11395 = OpBitcast %uint %23453 + %7677 = OpISub %uint %uint_2129690299 %11395 + %8343 = OpBitcast %float %7677 + %17531 = OpFMul %float %17670 %8343 + %20631 = OpFSub %float %7824 %10906 + %23454 = OpFAdd %float %float_0_03125 %20631 + %11396 = OpBitcast %uint %23454 + %7678 = OpISub %uint %uint_2129690299 %11396 + %8344 = OpBitcast %float %7678 + %17532 = OpFMul %float %25212 %8344 + %20632 = OpFSub %float %7825 %10907 + %23455 = OpFAdd %float %float_0_03125 %20632 + %11397 = OpBitcast %uint %23455 + %7679 = OpISub %uint %uint_2129690299 %11397 + %8345 = OpBitcast %float %7679 + %17533 = OpFMul %float %20330 %8345 + %20633 = OpFSub %float %21101 %10908 + %23456 = OpFAdd %float %float_0_03125 %20633 + %11398 = OpBitcast %uint %23456 + %7680 = OpISub %uint %uint_2129690299 %11398 + %8381 = OpBitcast %float %7680 + %17261 = OpFMul %float %20638 %8381 + %22796 = OpFMul %float %18879 %17531 + %20292 = OpFMul %float %22795 %17532 + %20984 = OpFMul %float %19380 %17533 + %15690 = OpFAdd %float %20292 %20984 + %22375 = OpFAdd %float %15690 %17531 + %12597 = OpFMul %float %10255 %17261 + %18845 = OpFAdd %float %22796 %12597 + %23067 = OpFAdd %float %18845 %17532 + %7227 = OpFAdd %float %18845 %17533 + %7228 = OpFAdd %float %15690 %17261 + %7229 = OpFAdd %float %22796 %20292 + %7303 = OpFAdd %float %7229 %20984 + %6535 = OpFAdd %float %7303 %12597 + %12598 = OpFMul %float %float_2 %6535 + %18846 = OpFAdd %float %12598 %22375 + %23068 = OpFAdd %float %18846 %23067 + %7132 = OpFAdd %float %23068 %7227 + %8111 = OpFAdd %float %7132 %7228 + %9782 = OpBitcast %uint %8111 + %7563 = OpISub %uint %uint_2129764351 %9782 + %9419 = OpBitcast %float %7563 + %9130 = OpFNegate %float %9419 + %12367 = OpFMul %float %9130 %8111 + %16540 = OpFAdd %float %12367 %float_2 + %9442 = OpFMul %float %9419 %16540 + %18229 = OpFAdd %float %24863 %24865 + %8674 = OpFMul %float %22796 %18229 + %24291 = OpFMul %float %24864 %20292 + %14922 = OpFAdd %float %8674 %24291 + %9443 = OpFMul %float %24868 %20292 + %18153 = OpFAdd %float %14922 %9443 + %9444 = OpFMul %float %24869 %20984 + %18154 = OpFAdd %float %18153 %9444 + %9445 = OpFMul %float %24873 %20984 + %18155 = OpFAdd %float %18154 %9445 + %9446 = OpFMul %float %24872 %12597 + %18156 = OpFAdd %float %18155 %9446 + %9447 = OpFMul %float %24874 %12597 + %18157 = OpFAdd %float %18156 %9447 + %9448 = OpFMul %float %24866 %22375 + %18158 = OpFAdd %float %18157 %9448 + %9449 = OpFMul %float %24867 %23067 + %18159 = OpFAdd %float %18158 %9449 + %9450 = OpFMul %float %24870 %7227 + %18160 = OpFAdd %float %18159 %9450 + %9451 = OpFMul %float %24871 %7228 + %15973 = OpFAdd %float %18160 %9451 + %8137 = OpFMul %float %15973 %9442 + %15218 = OpExtInst %float %1 FClamp %8137 %float_0 %float_1 + %12765 = OpFAdd %float %16184 %16186 + %17545 = OpFMul %float %22796 %12765 + %24292 = OpFMul %float %16185 %20292 + %14923 = OpFAdd %float %17545 %24292 + %9452 = OpFMul %float %16189 %20292 + %18161 = OpFAdd %float %14923 %9452 + %9453 = OpFMul %float %16190 %20984 + %18162 = OpFAdd %float %18161 %9453 + %9454 = OpFMul %float %16194 %20984 + %18163 = OpFAdd %float %18162 %9454 + %9455 = OpFMul %float %16193 %12597 + %18164 = OpFAdd %float %18163 %9455 + %9456 = OpFMul %float %14910 %12597 + %18165 = OpFAdd %float %18164 %9456 + %9457 = OpFMul %float %16187 %22375 + %18166 = OpFAdd %float %18165 %9457 + %9458 = OpFMul %float %16188 %23067 + %18167 = OpFAdd %float %18166 %9458 + %9459 = OpFMul %float %16191 %7227 + %18168 = OpFAdd %float %18167 %9459 + %9460 = OpFMul %float %16192 %7228 + %15974 = OpFAdd %float %18168 %9460 + %8138 = OpFMul %float %15974 %9442 + %15219 = OpExtInst %float %1 FClamp %8138 %float_0 %float_1 + %12766 = OpFAdd %float %9305 %9307 + %17546 = OpFMul %float %22796 %12766 + %24293 = OpFMul %float %9306 %20292 + %14924 = OpFAdd %float %17546 %24293 + %9461 = OpFMul %float %9310 %20292 + %18169 = OpFAdd %float %14924 %9461 + %9462 = OpFMul %float %9311 %20984 + %18170 = OpFAdd %float %18169 %9462 + %9463 = OpFMul %float %9315 %20984 + %18171 = OpFAdd %float %18170 %9463 + %9464 = OpFMul %float %9314 %12597 + %18172 = OpFAdd %float %18171 %9464 + %9465 = OpFMul %float %8590 %12597 + %18173 = OpFAdd %float %18172 %9465 + %9466 = OpFMul %float %9308 %22375 + %18174 = OpFAdd %float %18173 %9466 + %9467 = OpFMul %float %9309 %23067 + %18175 = OpFAdd %float %18174 %9467 + %9468 = OpFMul %float %9312 %7227 + %18176 = OpFAdd %float %18175 %9468 + %9469 = OpFMul %float %9313 %7228 + %15975 = OpFAdd %float %18176 %9469 + %7244 = OpFMul %float %15975 %9442 + %22380 = OpExtInst %float %1 FClamp %7244 %float_0 %float_1 + %24270 = OpCompositeInsert %v4float %15218 %10264 0 + %11074 = OpCompositeInsert %v4float %15219 %24270 1 + %14933 = OpCompositeInsert %v4float %22380 %11074 2 + %12955 = OpVectorShuffle %v3float %14933 %14933 0 1 2 + %6452 = OpExtInst %v3float %1 Sqrt %12955 + %22915 = OpCompositeExtract %float %6452 0 + %8853 = OpCompositeExtract %float %6452 1 + %7472 = OpCompositeExtract %float %6452 2 + %22408 = OpCompositeConstruct %v4float %22915 %8853 %7472 %float_1 + OpStore %5334 %22408 + OpReturn + OpFunctionEnd +#endif + +const uint32_t guest_output_ffx_cas_resample_ps[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x0000627D, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0007000F, 0x00000004, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000C93, 0x000014D6, 0x00030010, + 0x0000161F, 0x00000007, 0x00040047, 0x00000C93, 0x0000000B, 0x0000000F, 0x00030047, 0x00000418, + 0x00000002, 0x00050048, 0x00000418, 0x00000000, 0x00000023, 0x00000010, 0x00050048, 0x00000418, + 0x00000001, 0x00000023, 0x00000018, 0x00050048, 0x00000418, 0x00000002, 0x00000023, 0x00000020, + 0x00040047, 0x000014D6, 0x0000001E, 0x00000000, 0x00040047, 0x0000142B, 0x00000021, 0x00000000, + 0x00040047, 0x0000142B, 0x00000022, 0x00000000, 0x00020013, 0x00000008, 0x00030021, 0x00000502, + 0x00000008, 0x00030016, 0x0000000D, 0x00000020, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, + 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, + 0x00040017, 0x00000018, 0x0000000D, 0x00000003, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, + 0x00040017, 0x00000017, 0x0000000B, 0x00000004, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, + 0x00040020, 0x0000029A, 0x00000001, 0x0000001D, 0x0004003B, 0x0000029A, 0x00000C93, 0x00000001, + 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x0005001E, 0x00000418, 0x00000012, 0x00000013, + 0x0000000D, 0x00040020, 0x00000695, 0x00000009, 0x00000418, 0x0004003B, 0x00000695, 0x00000CE9, + 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x0000028F, 0x00000009, + 0x00000012, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x00040020, 0x00000290, 0x00000009, + 0x00000013, 0x0004002B, 0x0000000D, 0x000000FC, 0x3F000000, 0x0004002B, 0x0000000C, 0x00000A11, + 0x00000002, 0x00040020, 0x0000028A, 0x00000009, 0x0000000D, 0x0004002B, 0x0000000D, 0x00000A0C, + 0x00000000, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000D, 0x0000008A, + 0x3F800000, 0x00040020, 0x0000029B, 0x00000003, 0x0000001D, 0x0004003B, 0x0000029B, 0x000014D6, + 0x00000003, 0x0004002B, 0x0000000B, 0x0000020D, 0x1FBC4639, 0x0004002B, 0x0000000B, 0x00000344, + 0x7EF07EBB, 0x0004002B, 0x0000000B, 0x000000B2, 0x7EF19FFF, 0x0004002B, 0x0000000D, 0x00000019, + 0x40000000, 0x00090019, 0x00000096, 0x0000000D, 0x00000001, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00040020, 0x00000313, 0x00000000, 0x00000096, 0x0004003B, 0x00000313, + 0x0000142B, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A08, 0xFFFFFFFF, 0x0005002C, 0x00000012, + 0x0000070B, 0x00000A0B, 0x00000A08, 0x0005002C, 0x00000012, 0x00000714, 0x00000A0E, 0x00000A08, + 0x0005002C, 0x00000012, 0x0000070E, 0x00000A08, 0x00000A0B, 0x0005002C, 0x00000012, 0x00000720, + 0x00000A0E, 0x00000A0B, 0x0005002C, 0x00000012, 0x0000071A, 0x00000A08, 0x00000A0E, 0x0005002C, + 0x00000012, 0x00000723, 0x00000A0B, 0x00000A0E, 0x0005002C, 0x00000012, 0x0000072C, 0x00000A0E, + 0x00000A0E, 0x0005002C, 0x00000012, 0x00000729, 0x00000A11, 0x00000A0B, 0x0005002C, 0x00000012, + 0x0000072F, 0x00000A0B, 0x00000A11, 0x0005002C, 0x00000012, 0x00000735, 0x00000A11, 0x00000A0E, + 0x0005002C, 0x00000012, 0x00000738, 0x00000A0E, 0x00000A11, 0x0004002B, 0x0000000D, 0x000002C4, + 0x3D000000, 0x0005002C, 0x00000013, 0x0000061E, 0x000000FC, 0x000000FC, 0x00030001, 0x0000001D, + 0x00002818, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00006175, + 0x0004003D, 0x0000001D, 0x0000488B, 0x00000C93, 0x0007004F, 0x00000013, 0x000036B8, 0x0000488B, + 0x0000488B, 0x00000000, 0x00000001, 0x0004006E, 0x00000012, 0x000044F8, 0x000036B8, 0x00050041, + 0x0000028F, 0x00004B4F, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x00000012, 0x00005926, 0x00004B4F, + 0x00050082, 0x00000012, 0x00005B10, 0x000044F8, 0x00005926, 0x0004007C, 0x00000011, 0x000026D2, + 0x00005B10, 0x00050041, 0x00000290, 0x00005205, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x00000013, + 0x00005833, 0x00005205, 0x0004007C, 0x00000011, 0x00003455, 0x00005833, 0x0005008E, 0x00000013, + 0x000031DA, 0x00005833, 0x000000FC, 0x00050083, 0x00000013, 0x00006013, 0x000031DA, 0x0000061E, + 0x0004007C, 0x00000011, 0x0000454F, 0x00006013, 0x00050051, 0x0000000B, 0x00004143, 0x00003455, + 0x00000000, 0x00050051, 0x0000000B, 0x000033E3, 0x00003455, 0x00000001, 0x00050051, 0x0000000B, + 0x00001DD9, 0x0000454F, 0x00000000, 0x00050051, 0x0000000B, 0x00001D69, 0x0000454F, 0x00000001, + 0x00070050, 0x00000017, 0x00004741, 0x00004143, 0x000033E3, 0x00001DD9, 0x00001D69, 0x00050041, + 0x0000028A, 0x00002631, 0x00000CE9, 0x00000A11, 0x0004003D, 0x0000000D, 0x00004978, 0x00002631, + 0x0004007C, 0x0000000B, 0x000044BF, 0x00004978, 0x00040070, 0x00000013, 0x00004CA9, 0x000026D2, + 0x0007004F, 0x00000011, 0x000020FA, 0x00004741, 0x00004741, 0x00000000, 0x00000001, 0x0004007C, + 0x00000013, 0x00002D38, 0x000020FA, 0x00050085, 0x00000013, 0x0000514E, 0x00004CA9, 0x00002D38, + 0x0007004F, 0x00000011, 0x00002322, 0x00004741, 0x00004741, 0x00000002, 0x00000003, 0x0004007C, + 0x00000013, 0x00002E15, 0x00002322, 0x00050081, 0x00000013, 0x00004E65, 0x0000514E, 0x00002E15, + 0x0006000C, 0x00000013, 0x000031AF, 0x00000001, 0x00000008, 0x00004E65, 0x00050083, 0x00000013, + 0x00003FA2, 0x00004E65, 0x000031AF, 0x0004006E, 0x00000012, 0x000042A8, 0x000031AF, 0x00050080, + 0x00000012, 0x00005058, 0x000042A8, 0x0000070B, 0x0004003D, 0x00000096, 0x0000472F, 0x0000142B, + 0x0007005F, 0x0000001D, 0x00004C03, 0x0000472F, 0x00005058, 0x00000002, 0x00000A0B, 0x00050080, + 0x00000012, 0x00003423, 0x000042A8, 0x0000070E, 0x0004003D, 0x00000096, 0x000038CA, 0x0000142B, + 0x0007005F, 0x0000001D, 0x00003151, 0x000038CA, 0x00003423, 0x00000002, 0x00000A0B, 0x0004003D, + 0x00000096, 0x000028B5, 0x0000142B, 0x0007005F, 0x0000001D, 0x00003C54, 0x000028B5, 0x000042A8, + 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x00003424, 0x000042A8, 0x00000714, 0x0004003D, + 0x00000096, 0x00003DC3, 0x0000142B, 0x0007005F, 0x0000001D, 0x00004C04, 0x00003DC3, 0x00003424, + 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x00003425, 0x000042A8, 0x00000720, 0x0004003D, + 0x00000096, 0x00003DC4, 0x0000142B, 0x0007005F, 0x0000001D, 0x00004C05, 0x00003DC4, 0x00003425, + 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x00003426, 0x000042A8, 0x00000729, 0x0004003D, + 0x00000096, 0x00003DC5, 0x0000142B, 0x0007005F, 0x0000001D, 0x00004C06, 0x00003DC5, 0x00003426, + 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x00003427, 0x000042A8, 0x0000071A, 0x0004003D, + 0x00000096, 0x00003DC6, 0x0000142B, 0x0007005F, 0x0000001D, 0x00004C07, 0x00003DC6, 0x00003427, + 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x00003428, 0x000042A8, 0x00000723, 0x0004003D, + 0x00000096, 0x00003DC7, 0x0000142B, 0x0007005F, 0x0000001D, 0x00004C08, 0x00003DC7, 0x00003428, + 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x00003429, 0x000042A8, 0x0000072F, 0x0004003D, + 0x00000096, 0x00003DC8, 0x0000142B, 0x0007005F, 0x0000001D, 0x00004C09, 0x00003DC8, 0x00003429, + 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x0000342A, 0x000042A8, 0x0000072C, 0x0004003D, + 0x00000096, 0x00003DC9, 0x0000142B, 0x0007005F, 0x0000001D, 0x00004C0A, 0x00003DC9, 0x0000342A, + 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x0000342B, 0x000042A8, 0x00000735, 0x0004003D, + 0x00000096, 0x00003DCA, 0x0000142B, 0x0007005F, 0x0000001D, 0x00004C0B, 0x00003DCA, 0x0000342B, + 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x0000342C, 0x000042A8, 0x00000738, 0x0004003D, + 0x00000096, 0x00003A46, 0x0000142B, 0x0007005F, 0x0000001D, 0x000022C3, 0x00003A46, 0x0000342C, + 0x00000002, 0x00000A0B, 0x00050051, 0x0000000D, 0x00004D11, 0x00004C03, 0x00000000, 0x00050051, + 0x0000000D, 0x00001B71, 0x00004C03, 0x00000001, 0x00050051, 0x0000000D, 0x00004923, 0x00004C03, + 0x00000002, 0x00050085, 0x0000000D, 0x0000611F, 0x00004D11, 0x00004D11, 0x00050085, 0x0000000D, + 0x00003F38, 0x00001B71, 0x00001B71, 0x00050085, 0x0000000D, 0x00002459, 0x00004923, 0x00004923, + 0x00050051, 0x0000000D, 0x000056DC, 0x00004C04, 0x00000000, 0x00050051, 0x0000000D, 0x00002E44, + 0x00004C04, 0x00000001, 0x00050051, 0x0000000D, 0x00004924, 0x00004C04, 0x00000002, 0x00050085, + 0x0000000D, 0x00006120, 0x000056DC, 0x000056DC, 0x00050085, 0x0000000D, 0x00003F39, 0x00002E44, + 0x00002E44, 0x00050085, 0x0000000D, 0x0000245A, 0x00004924, 0x00004924, 0x00050051, 0x0000000D, + 0x000056DD, 0x00003151, 0x00000000, 0x00050051, 0x0000000D, 0x00002E45, 0x00003151, 0x00000001, + 0x00050051, 0x0000000D, 0x00004925, 0x00003151, 0x00000002, 0x00050085, 0x0000000D, 0x00006121, + 0x000056DD, 0x000056DD, 0x00050085, 0x0000000D, 0x00003F3A, 0x00002E45, 0x00002E45, 0x00050085, + 0x0000000D, 0x0000245B, 0x00004925, 0x00004925, 0x00050051, 0x0000000D, 0x000056DE, 0x00003C54, + 0x00000000, 0x00050051, 0x0000000D, 0x00002E46, 0x00003C54, 0x00000001, 0x00050051, 0x0000000D, + 0x00004926, 0x00003C54, 0x00000002, 0x00050085, 0x0000000D, 0x00006122, 0x000056DE, 0x000056DE, + 0x00050085, 0x0000000D, 0x00003F3B, 0x00002E46, 0x00002E46, 0x00050085, 0x0000000D, 0x0000245C, + 0x00004926, 0x00004926, 0x00050051, 0x0000000D, 0x000056DF, 0x00004C05, 0x00000000, 0x00050051, + 0x0000000D, 0x00002E47, 0x00004C05, 0x00000001, 0x00050051, 0x0000000D, 0x00004927, 0x00004C05, + 0x00000002, 0x00050085, 0x0000000D, 0x00006123, 0x000056DF, 0x000056DF, 0x00050085, 0x0000000D, + 0x00003F3C, 0x00002E47, 0x00002E47, 0x00050085, 0x0000000D, 0x0000245D, 0x00004927, 0x00004927, + 0x00050051, 0x0000000D, 0x000056E0, 0x00004C06, 0x00000000, 0x00050051, 0x0000000D, 0x00002E48, + 0x00004C06, 0x00000001, 0x00050051, 0x0000000D, 0x00004928, 0x00004C06, 0x00000002, 0x00050085, + 0x0000000D, 0x00006124, 0x000056E0, 0x000056E0, 0x00050085, 0x0000000D, 0x00003F3D, 0x00002E48, + 0x00002E48, 0x00050085, 0x0000000D, 0x0000245E, 0x00004928, 0x00004928, 0x00050051, 0x0000000D, + 0x000056E1, 0x00004C07, 0x00000000, 0x00050051, 0x0000000D, 0x00002E49, 0x00004C07, 0x00000001, + 0x00050051, 0x0000000D, 0x00004929, 0x00004C07, 0x00000002, 0x00050085, 0x0000000D, 0x00006125, + 0x000056E1, 0x000056E1, 0x00050085, 0x0000000D, 0x00003F3E, 0x00002E49, 0x00002E49, 0x00050085, + 0x0000000D, 0x0000245F, 0x00004929, 0x00004929, 0x00050051, 0x0000000D, 0x000056E2, 0x00004C08, + 0x00000000, 0x00050051, 0x0000000D, 0x00002E4A, 0x00004C08, 0x00000001, 0x00050051, 0x0000000D, + 0x0000492A, 0x00004C08, 0x00000002, 0x00050085, 0x0000000D, 0x00006126, 0x000056E2, 0x000056E2, + 0x00050085, 0x0000000D, 0x00003F3F, 0x00002E4A, 0x00002E4A, 0x00050085, 0x0000000D, 0x00002460, + 0x0000492A, 0x0000492A, 0x00050051, 0x0000000D, 0x000056E3, 0x00004C0A, 0x00000000, 0x00050051, + 0x0000000D, 0x00002E4B, 0x00004C0A, 0x00000001, 0x00050051, 0x0000000D, 0x0000492B, 0x00004C0A, + 0x00000002, 0x00050085, 0x0000000D, 0x00006127, 0x000056E3, 0x000056E3, 0x00050085, 0x0000000D, + 0x00003F40, 0x00002E4B, 0x00002E4B, 0x00050085, 0x0000000D, 0x00002461, 0x0000492B, 0x0000492B, + 0x00050051, 0x0000000D, 0x000056E4, 0x00004C0B, 0x00000000, 0x00050051, 0x0000000D, 0x00002E4C, + 0x00004C0B, 0x00000001, 0x00050051, 0x0000000D, 0x0000492C, 0x00004C0B, 0x00000002, 0x00050085, + 0x0000000D, 0x00006128, 0x000056E4, 0x000056E4, 0x00050085, 0x0000000D, 0x00003F41, 0x00002E4C, + 0x00002E4C, 0x00050085, 0x0000000D, 0x00002462, 0x0000492C, 0x0000492C, 0x00050051, 0x0000000D, + 0x000056E5, 0x00004C09, 0x00000000, 0x00050051, 0x0000000D, 0x00002E4D, 0x00004C09, 0x00000001, + 0x00050051, 0x0000000D, 0x0000492D, 0x00004C09, 0x00000002, 0x00050085, 0x0000000D, 0x00006129, + 0x000056E5, 0x000056E5, 0x00050085, 0x0000000D, 0x00003F42, 0x00002E4D, 0x00002E4D, 0x00050085, + 0x0000000D, 0x00002463, 0x0000492D, 0x0000492D, 0x00050051, 0x0000000D, 0x000056E6, 0x000022C3, + 0x00000000, 0x00050051, 0x0000000D, 0x00002E4E, 0x000022C3, 0x00000001, 0x00050051, 0x0000000D, + 0x0000492E, 0x000022C3, 0x00000002, 0x00050085, 0x0000000D, 0x0000612A, 0x000056E6, 0x000056E6, + 0x00050085, 0x0000000D, 0x00003A3E, 0x00002E4E, 0x00002E4E, 0x00050085, 0x0000000D, 0x0000218E, + 0x0000492E, 0x0000492E, 0x0007000C, 0x0000000D, 0x00002A7D, 0x00000001, 0x00000025, 0x00003F3A, + 0x00003F3B, 0x0007000C, 0x0000000D, 0x0000243C, 0x00000001, 0x00000025, 0x00003F38, 0x00002A7D, + 0x0007000C, 0x0000000D, 0x00003E4F, 0x00000001, 0x00000025, 0x00003F3C, 0x00003F3F, 0x0007000C, + 0x0000000D, 0x00002A99, 0x00000001, 0x00000025, 0x0000243C, 0x00003E4F, 0x0007000C, 0x0000000D, + 0x00005EE8, 0x00000001, 0x00000028, 0x00003F3A, 0x00003F3B, 0x0007000C, 0x0000000D, 0x00004473, + 0x00000001, 0x00000028, 0x00003F38, 0x00005EE8, 0x0007000C, 0x0000000D, 0x00005558, 0x00000001, + 0x00000028, 0x00003F3C, 0x00003F3F, 0x0007000C, 0x0000000D, 0x00001E8F, 0x00000001, 0x00000028, + 0x00004473, 0x00005558, 0x0007000C, 0x0000000D, 0x000034BF, 0x00000001, 0x00000025, 0x00003F3B, + 0x00003F3C, 0x0007000C, 0x0000000D, 0x000035FB, 0x00000001, 0x00000025, 0x00003F39, 0x000034BF, + 0x0007000C, 0x0000000D, 0x00003E50, 0x00000001, 0x00000025, 0x00003F3D, 0x00003F40, 0x0007000C, + 0x0000000D, 0x00002A9A, 0x00000001, 0x00000025, 0x000035FB, 0x00003E50, 0x0007000C, 0x0000000D, + 0x00005EE9, 0x00000001, 0x00000028, 0x00003F3B, 0x00003F3C, 0x0007000C, 0x0000000D, 0x00004474, + 0x00000001, 0x00000028, 0x00003F39, 0x00005EE9, 0x0007000C, 0x0000000D, 0x00005559, 0x00000001, + 0x00000028, 0x00003F3D, 0x00003F40, 0x0007000C, 0x0000000D, 0x00001E90, 0x00000001, 0x00000028, + 0x00004474, 0x00005559, 0x0007000C, 0x0000000D, 0x000034C0, 0x00000001, 0x00000025, 0x00003F3E, + 0x00003F3F, 0x0007000C, 0x0000000D, 0x000035FC, 0x00000001, 0x00000025, 0x00003F3B, 0x000034C0, + 0x0007000C, 0x0000000D, 0x00003E51, 0x00000001, 0x00000025, 0x00003F40, 0x00003F42, 0x0007000C, + 0x0000000D, 0x00002A9B, 0x00000001, 0x00000025, 0x000035FC, 0x00003E51, 0x0007000C, 0x0000000D, + 0x00005EEA, 0x00000001, 0x00000028, 0x00003F3E, 0x00003F3F, 0x0007000C, 0x0000000D, 0x00004475, + 0x00000001, 0x00000028, 0x00003F3B, 0x00005EEA, 0x0007000C, 0x0000000D, 0x0000555A, 0x00000001, + 0x00000028, 0x00003F40, 0x00003F42, 0x0007000C, 0x0000000D, 0x00001E91, 0x00000001, 0x00000028, + 0x00004475, 0x0000555A, 0x0007000C, 0x0000000D, 0x000034C1, 0x00000001, 0x00000025, 0x00003F3F, + 0x00003F40, 0x0007000C, 0x0000000D, 0x000035FD, 0x00000001, 0x00000025, 0x00003F3C, 0x000034C1, + 0x0007000C, 0x0000000D, 0x00003E52, 0x00000001, 0x00000025, 0x00003F41, 0x00003A3E, 0x0007000C, + 0x0000000D, 0x00002A9C, 0x00000001, 0x00000025, 0x000035FD, 0x00003E52, 0x0007000C, 0x0000000D, + 0x00005EEB, 0x00000001, 0x00000028, 0x00003F3F, 0x00003F40, 0x0007000C, 0x0000000D, 0x00004476, + 0x00000001, 0x00000028, 0x00003F3C, 0x00005EEB, 0x0007000C, 0x0000000D, 0x00005D83, 0x00000001, + 0x00000028, 0x00003F41, 0x00003A3E, 0x0007000C, 0x0000000D, 0x0000526D, 0x00000001, 0x00000028, + 0x00004476, 0x00005D83, 0x0004007C, 0x0000000B, 0x00001FF5, 0x00001E8F, 0x00050082, 0x0000000B, + 0x00002272, 0x00000344, 0x00001FF5, 0x0004007C, 0x0000000D, 0x00002699, 0x00002272, 0x0004007C, + 0x0000000B, 0x00003AD6, 0x00001E90, 0x00050082, 0x0000000B, 0x00001A2E, 0x00000344, 0x00003AD6, + 0x0004007C, 0x0000000D, 0x0000269A, 0x00001A2E, 0x0004007C, 0x0000000B, 0x00003AD7, 0x00001E91, + 0x00050082, 0x0000000B, 0x00001A2F, 0x00000344, 0x00003AD7, 0x0004007C, 0x0000000D, 0x0000269B, + 0x00001A2F, 0x0004007C, 0x0000000B, 0x00003AD8, 0x0000526D, 0x00050082, 0x0000000B, 0x00001AB3, + 0x00000344, 0x00003AD8, 0x0004007C, 0x0000000D, 0x00001941, 0x00001AB3, 0x00050083, 0x0000000D, + 0x00005E43, 0x0000008A, 0x00001E8F, 0x0007000C, 0x0000000D, 0x00005B1C, 0x00000001, 0x00000025, + 0x00002A99, 0x00005E43, 0x00050085, 0x0000000D, 0x000059FC, 0x00005B1C, 0x00002699, 0x0008000C, + 0x0000000D, 0x00003EB3, 0x00000001, 0x0000002B, 0x000059FC, 0x00000A0C, 0x0000008A, 0x00050083, + 0x0000000D, 0x000061AD, 0x0000008A, 0x00001E90, 0x0007000C, 0x0000000D, 0x000029C9, 0x00000001, + 0x00000025, 0x00002A9A, 0x000061AD, 0x00050085, 0x0000000D, 0x000059FD, 0x000029C9, 0x0000269A, + 0x0008000C, 0x0000000D, 0x00003EB4, 0x00000001, 0x0000002B, 0x000059FD, 0x00000A0C, 0x0000008A, + 0x00050083, 0x0000000D, 0x000061AE, 0x0000008A, 0x00001E91, 0x0007000C, 0x0000000D, 0x000029CA, + 0x00000001, 0x00000025, 0x00002A9B, 0x000061AE, 0x00050085, 0x0000000D, 0x000059FE, 0x000029CA, + 0x0000269B, 0x0008000C, 0x0000000D, 0x00003EB5, 0x00000001, 0x0000002B, 0x000059FE, 0x00000A0C, + 0x0000008A, 0x00050083, 0x0000000D, 0x000061AF, 0x0000008A, 0x0000526D, 0x0007000C, 0x0000000D, + 0x000029CB, 0x00000001, 0x00000025, 0x00002A9C, 0x000061AF, 0x00050085, 0x0000000D, 0x00005977, + 0x000029CB, 0x00001941, 0x0008000C, 0x0000000D, 0x000050CB, 0x00000001, 0x0000002B, 0x00005977, + 0x00000A0C, 0x0000008A, 0x0004007C, 0x0000000B, 0x00005DCB, 0x00003EB3, 0x000500C2, 0x0000000B, + 0x0000564A, 0x00005DCB, 0x00000A0D, 0x00050080, 0x0000000B, 0x00005ABD, 0x0000564A, 0x0000020D, + 0x0004007C, 0x0000000D, 0x00005943, 0x00005ABD, 0x0004007C, 0x0000000B, 0x000022CE, 0x00003EB4, + 0x000500C2, 0x0000000B, 0x000023E5, 0x000022CE, 0x00000A0D, 0x00050080, 0x0000000B, 0x00005ABE, + 0x000023E5, 0x0000020D, 0x0004007C, 0x0000000D, 0x00005944, 0x00005ABE, 0x0004007C, 0x0000000B, + 0x000022CF, 0x00003EB5, 0x000500C2, 0x0000000B, 0x000023E6, 0x000022CF, 0x00000A0D, 0x00050080, + 0x0000000B, 0x00005ABF, 0x000023E6, 0x0000020D, 0x0004007C, 0x0000000D, 0x00005945, 0x00005ABF, + 0x0004007C, 0x0000000B, 0x000022D0, 0x000050CB, 0x000500C2, 0x0000000B, 0x000023E7, 0x000022D0, + 0x00000A0D, 0x00050080, 0x0000000B, 0x00005AC0, 0x000023E7, 0x0000020D, 0x0004007C, 0x0000000D, + 0x000054BC, 0x00005AC0, 0x0004007C, 0x0000000D, 0x00004C66, 0x000044BF, 0x00050085, 0x0000000D, + 0x000049BF, 0x00005943, 0x00004C66, 0x00050085, 0x0000000D, 0x0000590B, 0x00005944, 0x00004C66, + 0x00050085, 0x0000000D, 0x00004BB4, 0x00005945, 0x00004C66, 0x00050085, 0x0000000D, 0x0000280F, + 0x000054BC, 0x00004C66, 0x00050051, 0x0000000D, 0x00003512, 0x00003FA2, 0x00000000, 0x00050083, + 0x0000000D, 0x000054D6, 0x0000008A, 0x00003512, 0x00050051, 0x0000000D, 0x00002E64, 0x00003FA2, + 0x00000001, 0x00050083, 0x0000000D, 0x00002B8B, 0x0000008A, 0x00002E64, 0x00050085, 0x0000000D, + 0x00004506, 0x000054D6, 0x00002B8B, 0x00050085, 0x0000000D, 0x0000627C, 0x00003512, 0x00002B8B, + 0x00050085, 0x0000000D, 0x00004F6A, 0x000054D6, 0x00002E64, 0x00050085, 0x0000000D, 0x0000509E, + 0x00003512, 0x00002E64, 0x00050083, 0x0000000D, 0x0000471C, 0x00001E8F, 0x00002A99, 0x00050081, + 0x0000000D, 0x00005B9D, 0x000002C4, 0x0000471C, 0x0004007C, 0x0000000B, 0x00002C83, 0x00005B9D, + 0x00050082, 0x0000000B, 0x00001DFD, 0x00000344, 0x00002C83, 0x0004007C, 0x0000000D, 0x00002097, + 0x00001DFD, 0x00050085, 0x0000000D, 0x0000447B, 0x00004506, 0x00002097, 0x00050083, 0x0000000D, + 0x00005097, 0x00001E90, 0x00002A9A, 0x00050081, 0x0000000D, 0x00005B9E, 0x000002C4, 0x00005097, + 0x0004007C, 0x0000000B, 0x00002C84, 0x00005B9E, 0x00050082, 0x0000000B, 0x00001DFE, 0x00000344, + 0x00002C84, 0x0004007C, 0x0000000D, 0x00002098, 0x00001DFE, 0x00050085, 0x0000000D, 0x0000447C, + 0x0000627C, 0x00002098, 0x00050083, 0x0000000D, 0x00005098, 0x00001E91, 0x00002A9B, 0x00050081, + 0x0000000D, 0x00005B9F, 0x000002C4, 0x00005098, 0x0004007C, 0x0000000B, 0x00002C85, 0x00005B9F, + 0x00050082, 0x0000000B, 0x00001DFF, 0x00000344, 0x00002C85, 0x0004007C, 0x0000000D, 0x00002099, + 0x00001DFF, 0x00050085, 0x0000000D, 0x0000447D, 0x00004F6A, 0x00002099, 0x00050083, 0x0000000D, + 0x00005099, 0x0000526D, 0x00002A9C, 0x00050081, 0x0000000D, 0x00005BA0, 0x000002C4, 0x00005099, + 0x0004007C, 0x0000000B, 0x00002C86, 0x00005BA0, 0x00050082, 0x0000000B, 0x00001E00, 0x00000344, + 0x00002C86, 0x0004007C, 0x0000000D, 0x000020BD, 0x00001E00, 0x00050085, 0x0000000D, 0x0000436D, + 0x0000509E, 0x000020BD, 0x00050085, 0x0000000D, 0x0000590C, 0x000049BF, 0x0000447B, 0x00050085, + 0x0000000D, 0x00004F44, 0x0000590B, 0x0000447C, 0x00050085, 0x0000000D, 0x000051F8, 0x00004BB4, + 0x0000447D, 0x00050081, 0x0000000D, 0x00003D4A, 0x00004F44, 0x000051F8, 0x00050081, 0x0000000D, + 0x00005767, 0x00003D4A, 0x0000447B, 0x00050085, 0x0000000D, 0x00003135, 0x0000280F, 0x0000436D, + 0x00050081, 0x0000000D, 0x0000499D, 0x0000590C, 0x00003135, 0x00050081, 0x0000000D, 0x00005A1B, + 0x0000499D, 0x0000447C, 0x00050081, 0x0000000D, 0x00001C3B, 0x0000499D, 0x0000447D, 0x00050081, + 0x0000000D, 0x00001C3C, 0x00003D4A, 0x0000436D, 0x00050081, 0x0000000D, 0x00001C3D, 0x0000590C, + 0x00004F44, 0x00050081, 0x0000000D, 0x00001C87, 0x00001C3D, 0x000051F8, 0x00050081, 0x0000000D, + 0x00001987, 0x00001C87, 0x00003135, 0x00050085, 0x0000000D, 0x00003136, 0x00000019, 0x00001987, + 0x00050081, 0x0000000D, 0x0000499E, 0x00003136, 0x00005767, 0x00050081, 0x0000000D, 0x00005A1C, + 0x0000499E, 0x00005A1B, 0x00050081, 0x0000000D, 0x00001BDC, 0x00005A1C, 0x00001C3B, 0x00050081, + 0x0000000D, 0x00001FAF, 0x00001BDC, 0x00001C3C, 0x0004007C, 0x0000000B, 0x00002636, 0x00001FAF, + 0x00050082, 0x0000000B, 0x00001D8B, 0x000000B2, 0x00002636, 0x0004007C, 0x0000000D, 0x000024CB, + 0x00001D8B, 0x0004007F, 0x0000000D, 0x000023AA, 0x000024CB, 0x00050085, 0x0000000D, 0x0000304F, + 0x000023AA, 0x00001FAF, 0x00050081, 0x0000000D, 0x0000409C, 0x0000304F, 0x00000019, 0x00050085, + 0x0000000D, 0x000024E2, 0x000024CB, 0x0000409C, 0x00050081, 0x0000000D, 0x00004735, 0x0000611F, + 0x00006121, 0x00050085, 0x0000000D, 0x000021E2, 0x0000590C, 0x00004735, 0x00050085, 0x0000000D, + 0x00005EE3, 0x00006120, 0x00004F44, 0x00050081, 0x0000000D, 0x00003A4A, 0x000021E2, 0x00005EE3, + 0x00050085, 0x0000000D, 0x000024E3, 0x00006124, 0x00004F44, 0x00050081, 0x0000000D, 0x000046E9, + 0x00003A4A, 0x000024E3, 0x00050085, 0x0000000D, 0x000024E4, 0x00006125, 0x000051F8, 0x00050081, + 0x0000000D, 0x000046EA, 0x000046E9, 0x000024E4, 0x00050085, 0x0000000D, 0x000024E5, 0x00006129, + 0x000051F8, 0x00050081, 0x0000000D, 0x000046EB, 0x000046EA, 0x000024E5, 0x00050085, 0x0000000D, + 0x000024E6, 0x00006128, 0x00003135, 0x00050081, 0x0000000D, 0x000046EC, 0x000046EB, 0x000024E6, + 0x00050085, 0x0000000D, 0x000024E7, 0x0000612A, 0x00003135, 0x00050081, 0x0000000D, 0x000046ED, + 0x000046EC, 0x000024E7, 0x00050085, 0x0000000D, 0x000024E8, 0x00006122, 0x00005767, 0x00050081, + 0x0000000D, 0x000046EE, 0x000046ED, 0x000024E8, 0x00050085, 0x0000000D, 0x000024E9, 0x00006123, + 0x00005A1B, 0x00050081, 0x0000000D, 0x000046EF, 0x000046EE, 0x000024E9, 0x00050085, 0x0000000D, + 0x000024EA, 0x00006126, 0x00001C3B, 0x00050081, 0x0000000D, 0x000046F0, 0x000046EF, 0x000024EA, + 0x00050085, 0x0000000D, 0x000024EB, 0x00006127, 0x00001C3C, 0x00050081, 0x0000000D, 0x00003E65, + 0x000046F0, 0x000024EB, 0x00050085, 0x0000000D, 0x00001FC9, 0x00003E65, 0x000024E2, 0x0008000C, + 0x0000000D, 0x00003B72, 0x00000001, 0x0000002B, 0x00001FC9, 0x00000A0C, 0x0000008A, 0x00050081, + 0x0000000D, 0x000031DD, 0x00003F38, 0x00003F3A, 0x00050085, 0x0000000D, 0x00004489, 0x0000590C, + 0x000031DD, 0x00050085, 0x0000000D, 0x00005EE4, 0x00003F39, 0x00004F44, 0x00050081, 0x0000000D, + 0x00003A4B, 0x00004489, 0x00005EE4, 0x00050085, 0x0000000D, 0x000024EC, 0x00003F3D, 0x00004F44, + 0x00050081, 0x0000000D, 0x000046F1, 0x00003A4B, 0x000024EC, 0x00050085, 0x0000000D, 0x000024ED, + 0x00003F3E, 0x000051F8, 0x00050081, 0x0000000D, 0x000046F2, 0x000046F1, 0x000024ED, 0x00050085, + 0x0000000D, 0x000024EE, 0x00003F42, 0x000051F8, 0x00050081, 0x0000000D, 0x000046F3, 0x000046F2, + 0x000024EE, 0x00050085, 0x0000000D, 0x000024EF, 0x00003F41, 0x00003135, 0x00050081, 0x0000000D, + 0x000046F4, 0x000046F3, 0x000024EF, 0x00050085, 0x0000000D, 0x000024F0, 0x00003A3E, 0x00003135, + 0x00050081, 0x0000000D, 0x000046F5, 0x000046F4, 0x000024F0, 0x00050085, 0x0000000D, 0x000024F1, + 0x00003F3B, 0x00005767, 0x00050081, 0x0000000D, 0x000046F6, 0x000046F5, 0x000024F1, 0x00050085, + 0x0000000D, 0x000024F2, 0x00003F3C, 0x00005A1B, 0x00050081, 0x0000000D, 0x000046F7, 0x000046F6, + 0x000024F2, 0x00050085, 0x0000000D, 0x000024F3, 0x00003F3F, 0x00001C3B, 0x00050081, 0x0000000D, + 0x000046F8, 0x000046F7, 0x000024F3, 0x00050085, 0x0000000D, 0x000024F4, 0x00003F40, 0x00001C3C, + 0x00050081, 0x0000000D, 0x00003E66, 0x000046F8, 0x000024F4, 0x00050085, 0x0000000D, 0x00001FCA, + 0x00003E66, 0x000024E2, 0x0008000C, 0x0000000D, 0x00003B73, 0x00000001, 0x0000002B, 0x00001FCA, + 0x00000A0C, 0x0000008A, 0x00050081, 0x0000000D, 0x000031DE, 0x00002459, 0x0000245B, 0x00050085, + 0x0000000D, 0x0000448A, 0x0000590C, 0x000031DE, 0x00050085, 0x0000000D, 0x00005EE5, 0x0000245A, + 0x00004F44, 0x00050081, 0x0000000D, 0x00003A4C, 0x0000448A, 0x00005EE5, 0x00050085, 0x0000000D, + 0x000024F5, 0x0000245E, 0x00004F44, 0x00050081, 0x0000000D, 0x000046F9, 0x00003A4C, 0x000024F5, + 0x00050085, 0x0000000D, 0x000024F6, 0x0000245F, 0x000051F8, 0x00050081, 0x0000000D, 0x000046FA, + 0x000046F9, 0x000024F6, 0x00050085, 0x0000000D, 0x000024F7, 0x00002463, 0x000051F8, 0x00050081, + 0x0000000D, 0x000046FB, 0x000046FA, 0x000024F7, 0x00050085, 0x0000000D, 0x000024F8, 0x00002462, + 0x00003135, 0x00050081, 0x0000000D, 0x000046FC, 0x000046FB, 0x000024F8, 0x00050085, 0x0000000D, + 0x000024F9, 0x0000218E, 0x00003135, 0x00050081, 0x0000000D, 0x000046FD, 0x000046FC, 0x000024F9, + 0x00050085, 0x0000000D, 0x000024FA, 0x0000245C, 0x00005767, 0x00050081, 0x0000000D, 0x000046FE, + 0x000046FD, 0x000024FA, 0x00050085, 0x0000000D, 0x000024FB, 0x0000245D, 0x00005A1B, 0x00050081, + 0x0000000D, 0x000046FF, 0x000046FE, 0x000024FB, 0x00050085, 0x0000000D, 0x000024FC, 0x00002460, + 0x00001C3B, 0x00050081, 0x0000000D, 0x00004700, 0x000046FF, 0x000024FC, 0x00050085, 0x0000000D, + 0x000024FD, 0x00002461, 0x00001C3C, 0x00050081, 0x0000000D, 0x00003E67, 0x00004700, 0x000024FD, + 0x00050085, 0x0000000D, 0x00001C4C, 0x00003E67, 0x000024E2, 0x0008000C, 0x0000000D, 0x0000576C, + 0x00000001, 0x0000002B, 0x00001C4C, 0x00000A0C, 0x0000008A, 0x00060052, 0x0000001D, 0x00005ECE, + 0x00003B72, 0x00002818, 0x00000000, 0x00060052, 0x0000001D, 0x00002B42, 0x00003B73, 0x00005ECE, + 0x00000001, 0x00060052, 0x0000001D, 0x00003A55, 0x0000576C, 0x00002B42, 0x00000002, 0x0008004F, + 0x00000018, 0x0000329B, 0x00003A55, 0x00003A55, 0x00000000, 0x00000001, 0x00000002, 0x0006000C, + 0x00000018, 0x00001934, 0x00000001, 0x0000001F, 0x0000329B, 0x00050051, 0x0000000D, 0x00005983, + 0x00001934, 0x00000000, 0x00050051, 0x0000000D, 0x00002295, 0x00001934, 0x00000001, 0x00050051, + 0x0000000D, 0x00001D30, 0x00001934, 0x00000002, 0x00070050, 0x0000001D, 0x00005788, 0x00005983, + 0x00002295, 0x00001D30, 0x0000008A, 0x0003003E, 0x000014D6, 0x00005788, 0x000100FD, 0x00010038, +}; diff --git a/src/ui/shaders/vulkan_spirv/guest_output_ffx_cas_sharpen_dither_ps.h b/src/ui/shaders/vulkan_spirv/guest_output_ffx_cas_sharpen_dither_ps.h new file mode 100644 index 0000000..f0a1779 --- /dev/null +++ b/src/ui/shaders/vulkan_spirv/guest_output_ffx_cas_sharpen_dither_ps.h @@ -0,0 +1,748 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25141 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %5663 "main" %gl_FragCoord %5334 + OpExecutionMode %5663 OriginUpperLeft + OpDecorate %gl_FragCoord BuiltIn FragCoord + OpDecorate %_struct_1010 Block + OpMemberDecorate %_struct_1010 0 Offset 16 + OpMemberDecorate %_struct_1010 1 Offset 24 + OpDecorate %5334 Location 0 + OpDecorate %5163 Binding 0 + OpDecorate %5163 DescriptorSet 0 + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %float = OpTypeFloat 32 +%_ptr_Function_float = OpTypePointer Function %float + %v3float = OpTypeVector %float 3 + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 + %uint_15 = OpConstant %uint 15 + %uint_256 = OpConstant %uint 256 +%_arr_float_uint_256 = OpTypeArray %float %uint_256 +%float_n0_00100337015 = OpConstant %float -0.00100337015 +%float_0_000880821084 = OpConstant %float 0.000880821084 +%float_0_00169270835 = OpConstant %float 0.00169270835 +%float_n0_00155484071 = OpConstant %float -0.00155484071 +%float_0_00127910543 = OpConstant %float 0.00127910543 +%float_n0_000605085806 = OpConstant %float -0.000605085806 +%float_0_00106464466 = OpConstant %float 0.00106464466 +%float_n0_00138633582 = OpConstant %float -0.00138633582 +%float_0_00135569857 = OpConstant %float 0.00135569857 +%float_0_000513174047 = OpConstant %float 0.000513174047 +%float_0_00121783093 = OpConstant %float 0.00121783093 +%float_n0_00160079659 = OpConstant %float -0.00160079659 +%float_0_00058976718 = OpConstant %float 0.00058976718 +%float_n0_00028339462 = OpConstant %float -0.00028339462 +%float_0_00111060054 = OpConstant %float 0.00111060054 +%float_n0_00141697307 = OpConstant %float -0.00141697307 +%float_0_00144761032 = OpConstant %float 0.00144761032 +%float_n0_0005438113 = OpConstant %float -0.0005438113 +%float_0_00013020834 = OpConstant %float 0.00013020834 +%float_n0_0012025123 = OpConstant %float -0.0012025123 +%float_0_000436580885 = OpConstant %float 0.000436580885 +%float_n0_00104932603 = OpConstant %float -0.00104932603 +%float_0_000620404433 = OpConstant %float 0.000620404433 +%float_n0_000482536765 = OpConstant %float -0.000482536765 +%float_0_00187653187 = OpConstant %float 0.00187653187 +%float_n0_00109528191 = OpConstant %float -0.00109528191 +%float_n9_95710798en05 = OpConstant %float -9.95710798e-05 +%float_n0_000528492674 = OpConstant %float -0.000528492674 +%float_0_0014322917 = OpConstant %float 0.0014322917 +%float_n0_00193780637 = OpConstant %float -0.00193780637 +%float_n0_000696997566 = OpConstant %float -0.000696997566 +%float_3_829657en05 = OpConstant %float 3.829657e-05 +%float_0_000712316192 = OpConstant %float 0.000712316192 +%float_n0_00130974269 = OpConstant %float -0.00130974269 +%float_0_00109528191 = OpConstant %float 0.00109528191 +%float_n0_000298713247 = OpConstant %float -0.000298713247 +%float_0_00175398286 = OpConstant %float 0.00175398286 +%float_n0_00167738972 = OpConstant %float -0.00167738972 +%float_0_00147824758 = OpConstant %float 0.00147824758 +%float_n3_829657en05 = OpConstant %float -3.829657e-05 +%float_0_000788909325 = OpConstant %float 0.000788909325 +%float_n0_00183057599 = OpConstant %float -0.00183057599 +%float_0_000298713247 = OpConstant %float 0.000298713247 +%float_0_000988051528 = OpConstant %float 0.000988051528 +%float_n0_00117187505 = OpConstant %float -0.00117187505 +%float_0_00017616422 = OpConstant %float 0.00017616422 +%float_0_00164675247 = OpConstant %float 0.00164675247 +%float_n0_00158547796 = OpConstant %float -0.00158547796 +%float_0_000344669126 = OpConstant %float 0.000344669126 +%float_0_00186121324 = OpConstant %float 0.00186121324 +%float_n0_00176930148 = OpConstant %float -0.00176930148 +%float_n0_000865502458 = OpConstant %float -0.000865502458 +%float_0_000896139711 = OpConstant %float 0.000896139711 +%float_0_000160845593 = OpConstant %float 0.000160845593 +%float_n0_000926776964 = OpConstant %float -0.000926776964 +%float_n0_00152420346 = OpConstant %float -0.00152420346 +%float_n0_000651041686 = OpConstant %float -0.000651041686 +%float_0_00129442406 = OpConstant %float 0.00129442406 +%float_n0_000804227951 = OpConstant %float -0.000804227951 +%float_n0_00146292895 = OpConstant %float -0.00146292895 +%float_0_00179993873 = OpConstant %float 0.00179993873 +%float_n0_000850183831 = OpConstant %float -0.000850183831 +%float_0_000850183831 = OpConstant %float 0.000850183831 +%float_n0_000451899512 = OpConstant %float -0.000451899512 +%float_n0_00106464466 = OpConstant %float -0.00106464466 +%float_n0_000145526967 = OpConstant %float -0.000145526967 +%float_0_000237438726 = OpConstant %float 0.000237438726 +%float_0_00141697307 = OpConstant %float 0.00141697307 +%float_n0_00058976718 = OpConstant %float -0.00058976718 +%float_n0_000191482846 = OpConstant %float -0.000191482846 +%float_0_00160079659 = OpConstant %float 0.00160079659 +%float_0_00101868878 = OpConstant %float 0.00101868878 +%float_0_000405943632 = OpConstant %float 0.000405943632 +%float_n0_000206801473 = OpConstant %float -0.000206801473 +%float_0_00158547796 = OpConstant %float 0.00158547796 +%float_0_000651041686 = OpConstant %float 0.000651041686 +%float_n6_89338267en05 = OpConstant %float -6.89338267e-05 +%float_0_000421262259 = OpConstant %float 0.000421262259 +%float_n0_00164675247 = OpConstant %float -0.00164675247 +%float_0_00137101719 = OpConstant %float 0.00137101719 +%float_0_000926776964 = OpConstant %float 0.000926776964 +%float_n0_000666360313 = OpConstant %float -0.000666360313 +%float_0_00118719367 = OpConstant %float 0.00118719367 +%float_n0_00144761032 = OpConstant %float -0.00144761032 +%float_0_000574448553 = OpConstant %float 0.000574448553 +%float_n0_00189185049 = OpConstant %float -0.00189185049 +%float_0_000758272072 = OpConstant %float 0.000758272072 +%float_n0_00129442406 = OpConstant %float -0.00129442406 +%float_0_00192248775 = OpConstant %float 0.00192248775 +%float_n0_0016620711 = OpConstant %float -0.0016620711 +%float_n0_00103400741 = OpConstant %float -0.00103400741 +%float_n0_000497855421 = OpConstant %float -0.000497855421 +%float_n0_00186121324 = OpConstant %float -0.00186121324 +%float_0_0012025123 = OpConstant %float 0.0012025123 +%float_n0_0003293505 = OpConstant %float -0.0003293505 +%float_n0_00137101719 = OpConstant %float -0.00137101719 +%float_0_00163143384 = OpConstant %float 0.00163143384 +%float_n0_00184589461 = OpConstant %float -0.00184589461 +%float_0_000727634819 = OpConstant %float 0.000727634819 +%float_n0_000911458337 = OpConstant %float -0.000911458337 +%float_0_00181525736 = OpConstant %float 0.00181525736 +%float_n0_00114123779 = OpConstant %float -0.00114123779 +%float_n0_000375306379 = OpConstant %float -0.000375306379 +%float_9_95710798en05 = OpConstant %float 9.95710798e-05 +%float_n0_000742953445 = OpConstant %float -0.000742953445 +%float_0_00117187505 = OpConstant %float 0.00117187505 +%float_6_89338267en05 = OpConstant %float 6.89338267e-05 +%float_0_0014935662 = OpConstant %float 0.0014935662 +%float_0_000972732843 = OpConstant %float 0.000972732843 +%float_n0_000957414217 = OpConstant %float -0.000957414217 +%float_0_00193780637 = OpConstant %float 0.00193780637 +%float_0_000528492674 = OpConstant %float 0.000528492674 +%float_5_36151965en05 = OpConstant %float 5.36151965e-05 +%float_n0_00124846818 = OpConstant %float -0.00124846818 +%float_n0_000268075994 = OpConstant %float -0.000268075994 +%float_0_00153952208 = OpConstant %float 0.00153952208 +%float_n7_65931418en06 = OpConstant %float -7.65931418e-06 +%float_0_000314031873 = OpConstant %float 0.000314031873 +%float_0_00134037994 = OpConstant %float 0.00134037994 +%float_n0_00175398286 = OpConstant %float -0.00175398286 +%float_0_000497855421 = OpConstant %float 0.000497855421 +%float_n0_00118719367 = OpConstant %float -0.00118719367 +%float_0_000773590698 = OpConstant %float 0.000773590698 +%float_n0_00134037994 = OpConstant %float -0.00134037994 +%float_0_000268075994 = OpConstant %float 0.000268075994 +%float_n0_00147824758 = OpConstant %float -0.00147824758 +%float_n0_00013020834 = OpConstant %float -0.00013020834 +%float_n0_000773590698 = OpConstant %float -0.000773590698 +%float_0_00130974269 = OpConstant %float 0.00130974269 +%float_0_000390625006 = OpConstant %float 0.000390625006 +%float_0_000957414217 = OpConstant %float 0.000957414217 +%float_n0_000467218139 = OpConstant %float -0.000467218139 +%float_n0_00153952208 = OpConstant %float -0.00153952208 +%float_0_00103400741 = OpConstant %float 0.00103400741 +%float_n0_000681678939 = OpConstant %float -0.000681678939 +%float_0_00167738972 = OpConstant %float 0.00167738972 +%float_0_00100337015 = OpConstant %float 0.00100337015 +%float_n0_000421262259 = OpConstant %float -0.000421262259 +%float_0_00178462011 = OpConstant %float 0.00178462011 +%float_n0_000237438726 = OpConstant %float -0.000237438726 +%float_n0_000620404433 = OpConstant %float -0.000620404433 +%float_0_0016620711 = OpConstant %float 0.0016620711 +%float_0_000834865205 = OpConstant %float 0.000834865205 +%float_n0_0017233456 = OpConstant %float -0.0017233456 +%float_n0_00107996329 = OpConstant %float -0.00107996329 +%float_0_00176930148 = OpConstant %float 0.00176930148 +%float_n0_000788909325 = OpConstant %float -0.000788909325 +%float_n0_00178462011 = OpConstant %float -0.00178462011 +%float_0_000681678939 = OpConstant %float 0.000681678939 +%float_n0_000988051528 = OpConstant %float -0.000988051528 +%float_n0_00132506131 = OpConstant %float -0.00132506131 +%float_n0_00017616422 = OpConstant %float -0.00017616422 +%float_n0_00150888483 = OpConstant %float -0.00150888483 +%float_0_0003293505 = OpConstant %float 0.0003293505 +%float_n0_001953125 = OpConstant %float -0.001953125 +%float_0_000666360313 = OpConstant %float 0.000666360313 +%float_n0_00161611522 = OpConstant %float -0.00161611522 +%float_0_00115655642 = OpConstant %float 0.00115655642 +%float_0_000451899512 = OpConstant %float 0.000451899512 +%float_n0_000436580885 = OpConstant %float -0.000436580885 +%float_0_000191482846 = OpConstant %float 0.000191482846 +%float_n0_0014935662 = OpConstant %float -0.0014935662 +%float_0_00114123779 = OpConstant %float 0.00114123779 +%float_8_42524532en05 = OpConstant %float 8.42524532e-05 +%float_0_00189185049 = OpConstant %float 0.00189185049 +%float_0_00140165444 = OpConstant %float 0.00140165444 +%float_0_000559129927 = OpConstant %float 0.000559129927 +%float_0_000114889706 = OpConstant %float 0.000114889706 +%float_0_00126378681 = OpConstant %float 0.00126378681 +%float_n0_000574448553 = OpConstant %float -0.000574448553 +%float_n0_000972732843 = OpConstant %float -0.000972732843 +%float_0_00132506131 = OpConstant %float 0.00132506131 +%float_0_000222120099 = OpConstant %float 0.000222120099 +%float_n0_000758272072 = OpConstant %float -0.000758272072 +%float_n0_00135569857 = OpConstant %float -0.00135569857 +%float_0_00146292895 = OpConstant %float 0.00146292895 +%float_0_000865502458 = OpConstant %float 0.000865502458 +%float_n0_000359987753 = OpConstant %float -0.000359987753 +%float_0_0005438113 = OpConstant %float 0.0005438113 +%float_n0_00112591917 = OpConstant %float -0.00112591917 +%float_n0_000252757367 = OpConstant %float -0.000252757367 +%float_n0_000559129927 = OpConstant %float -0.000559129927 +%float_n0_00181525736 = OpConstant %float -0.00181525736 +%float_0_0017233456 = OpConstant %float 0.0017233456 +%float_n0_00115655642 = OpConstant %float -0.00115655642 +%float_0_000742953445 = OpConstant %float 0.000742953445 +%float_0_00157015934 = OpConstant %float 0.00157015934 +%float_n0_000114889706 = OpConstant %float -0.000114889706 +%float_n0_00121783093 = OpConstant %float -0.00121783093 +%float_0_00183057599 = OpConstant %float 0.00183057599 +%float_2_29779416en05 = OpConstant %float 2.29779416e-05 +%float_n0_00192248775 = OpConstant %float -0.00192248775 +%float_0_00173866423 = OpConstant %float 0.00173866423 +%float_n0_000712316192 = OpConstant %float -0.000712316192 +%float_0_00155484071 = OpConstant %float 0.00155484071 +%float_n0_00170802698 = OpConstant %float -0.00170802698 +%float_0_00123314955 = OpConstant %float 0.00123314955 +%float_0_000206801473 = OpConstant %float 0.000206801473 +%float_0_00104932603 = OpConstant %float 0.00104932603 +%float_n0_000727634819 = OpConstant %float -0.000727634819 +%float_n0_00163143384 = OpConstant %float -0.00163143384 +%float_n0_000314031873 = OpConstant %float -0.000314031873 +%float_0_000482536765 = OpConstant %float 0.000482536765 +%float_n0_00179993873 = OpConstant %float -0.00179993873 +%float_0_00094209559 = OpConstant %float 0.00094209559 +%float_n0_000344669126 = OpConstant %float -0.000344669126 +%float_0_000696997566 = OpConstant %float 0.000696997566 +%float_n0_00101868878 = OpConstant %float -0.00101868878 +%float_n0_00157015934 = OpConstant %float -0.00157015934 +%float_n2_29779416en05 = OpConstant %float -2.29779416e-05 +%float_n0_00127910543 = OpConstant %float -0.00127910543 +%float_0_000804227951 = OpConstant %float 0.000804227951 +%float_n0_000896139711 = OpConstant %float -0.000896139711 +%float_n0_0014322917 = OpConstant %float -0.0014322917 +%float_0_000605085806 = OpConstant %float 0.000605085806 +%float_n8_42524532en05 = OpConstant %float -8.42524532e-05 +%float_0_000911458337 = OpConstant %float 0.000911458337 +%float_0_001953125 = OpConstant %float 0.001953125 +%float_n0_00140165444 = OpConstant %float -0.00140165444 +%float_n0_00063572306 = OpConstant %float -0.00063572306 +%float_0_00150888483 = OpConstant %float 0.00150888483 +%float_n0_000819546578 = OpConstant %float -0.000819546578 +%float_0_00124846818 = OpConstant %float 0.00124846818 +%float_0_000252757367 = OpConstant %float 0.000252757367 +%float_0_00152420346 = OpConstant %float 0.00152420346 +%float_0_00112591917 = OpConstant %float 0.00112591917 +%float_0_000359987753 = OpConstant %float 0.000359987753 +%float_n0_000390625006 = OpConstant %float -0.000390625006 +%float_0_00190716912 = OpConstant %float 0.00190716912 +%float_0_00138633582 = OpConstant %float 0.00138633582 +%float_n0_00111060054 = OpConstant %float -0.00111060054 +%float_0_00161611522 = OpConstant %float 0.00161611522 +%float_n0_000880821084 = OpConstant %float -0.000880821084 +%float_0_000145526967 = OpConstant %float 0.000145526967 +%float_0_00107996329 = OpConstant %float 0.00107996329 +%float_n5_36151965en05 = OpConstant %float -5.36151965e-05 +%float_0_00028339462 = OpConstant %float 0.00028339462 +%float_n0_00169270835 = OpConstant %float -0.00169270835 +%float_n0_00126378681 = OpConstant %float -0.00126378681 +%float_n0_000513174047 = OpConstant %float -0.000513174047 +%float_n0_000160845593 = OpConstant %float -0.000160845593 +%float_n0_00187653187 = OpConstant %float -0.00187653187 +%float_n0_000834865205 = OpConstant %float -0.000834865205 +%float_0_00063572306 = OpConstant %float 0.00063572306 +%float_7_65931418en06 = OpConstant %float 7.65931418e-06 +%float_n0_00190716912 = OpConstant %float -0.00190716912 +%float_n0_000222120099 = OpConstant %float -0.000222120099 +%float_0_000375306379 = OpConstant %float 0.000375306379 +%float_n0_00173866423 = OpConstant %float -0.00173866423 +%float_n0_000405943632 = OpConstant %float -0.000405943632 +%float_n0_00123314955 = OpConstant %float -0.00123314955 +%float_0_00170802698 = OpConstant %float 0.00170802698 +%float_n0_00094209559 = OpConstant %float -0.00094209559 +%float_0_000819546578 = OpConstant %float 0.000819546578 +%float_0_00184589461 = OpConstant %float 0.00184589461 +%float_0_000467218139 = OpConstant %float 0.000467218139 + %2242 = OpConstantComposite %_arr_float_uint_256 %float_n0_00100337015 %float_0_000880821084 %float_0_00169270835 %float_n0_00155484071 %float_0_00127910543 %float_n0_000605085806 %float_0_00106464466 %float_n0_00138633582 %float_0_00135569857 %float_0_000513174047 %float_0_00121783093 %float_n0_00160079659 %float_0_00058976718 %float_n0_00028339462 %float_0_00111060054 %float_n0_00141697307 %float_0_00144761032 %float_n0_0005438113 %float_0_00013020834 %float_n0_0012025123 %float_0_000436580885 %float_n0_00104932603 %float_0_000620404433 %float_n0_000482536765 %float_0_00187653187 %float_n0_00109528191 %float_n9_95710798en05 %float_n0_000528492674 %float_0_0014322917 %float_n0_00193780637 %float_n0_000696997566 %float_3_829657en05 %float_0_000712316192 %float_n0_00130974269 %float_0_00109528191 %float_n0_000298713247 %float_0_00175398286 %float_n0_00167738972 %float_0_00147824758 %float_n3_829657en05 %float_0_000788909325 %float_n0_00183057599 %float_0_000298713247 %float_0_000988051528 %float_n0_00117187505 %float_0_00017616422 %float_0_00164675247 %float_n0_00158547796 %float_0_000344669126 %float_0_00186121324 %float_n0_00176930148 %float_n0_000865502458 %float_0_000896139711 %float_0_000160845593 %float_n0_000926776964 %float_n0_00152420346 %float_n0_000651041686 %float_0_00129442406 %float_n0_000804227951 %float_n0_00146292895 %float_0_00179993873 %float_n0_000850183831 %float_0_000850183831 %float_n0_000451899512 %float_n0_00106464466 %float_n0_000145526967 %float_0_000237438726 %float_0_00141697307 %float_n0_00058976718 %float_n0_000191482846 %float_0_00160079659 %float_0_00101868878 %float_0_000405943632 %float_n0_000206801473 %float_0_00158547796 %float_0_000651041686 %float_n6_89338267en05 %float_0_000421262259 %float_n0_00164675247 %float_0_00137101719 %float_0_000926776964 %float_n0_000666360313 %float_0_00118719367 %float_n0_00144761032 %float_0_000574448553 %float_n0_00189185049 %float_0_000758272072 %float_n0_00129442406 %float_0_00192248775 %float_n0_0016620711 %float_n0_00103400741 %float_n0_000497855421 %float_n0_00186121324 %float_0_0012025123 %float_n0_0003293505 %float_n0_00137101719 %float_0_00163143384 %float_n0_00184589461 %float_0_000727634819 %float_n0_000911458337 %float_0_00181525736 %float_n0_00114123779 %float_n0_000375306379 %float_9_95710798en05 %float_n0_000742953445 %float_0_00117187505 %float_6_89338267en05 %float_0_0014935662 %float_0_000972732843 %float_n0_000957414217 %float_0_00193780637 %float_0_000528492674 %float_5_36151965en05 %float_n0_00124846818 %float_n0_000268075994 %float_0_00153952208 %float_n7_65931418en06 %float_0_000314031873 %float_0_00134037994 %float_n0_00175398286 %float_0_000497855421 %float_n0_00118719367 %float_0_000773590698 %float_n0_00134037994 %float_0_000268075994 %float_n0_00147824758 %float_n0_00013020834 %float_n0_000773590698 %float_0_00130974269 %float_0_000390625006 %float_0_000957414217 %float_n0_000467218139 %float_n0_00153952208 %float_0_00103400741 %float_n0_000681678939 %float_0_00167738972 %float_0_00100337015 %float_n0_000421262259 %float_0_00178462011 %float_n0_000237438726 %float_n0_000620404433 %float_0_0016620711 %float_0_000834865205 %float_n0_0017233456 %float_n0_00107996329 %float_0_00176930148 %float_n0_000788909325 %float_n0_00178462011 %float_0_000681678939 %float_n0_000988051528 %float_n0_00132506131 %float_n0_00017616422 %float_n0_00150888483 %float_0_0003293505 %float_n0_001953125 %float_0_000666360313 %float_n0_00161611522 %float_0_00115655642 %float_0_000451899512 %float_n0_000436580885 %float_0_000191482846 %float_n0_0014935662 %float_0_00114123779 %float_8_42524532en05 %float_0_00189185049 %float_0_00140165444 %float_0_000559129927 %float_0_000114889706 %float_0_00126378681 %float_n0_000574448553 %float_n0_000972732843 %float_0_00132506131 %float_0_000222120099 %float_n0_000758272072 %float_n0_00135569857 %float_0_00146292895 %float_0_000865502458 %float_n0_000359987753 %float_0_0005438113 %float_n0_00112591917 %float_n0_000252757367 %float_n0_000559129927 %float_n0_00181525736 %float_0_0017233456 %float_n0_00115655642 %float_0_000742953445 %float_0_00157015934 %float_n0_000114889706 %float_n0_00121783093 %float_0_00183057599 %float_2_29779416en05 %float_n0_00192248775 %float_0_00173866423 %float_n0_000712316192 %float_0_00155484071 %float_n0_00170802698 %float_0_00123314955 %float_0_000206801473 %float_0_00104932603 %float_n0_000727634819 %float_n0_00163143384 %float_n0_000314031873 %float_0_000482536765 %float_n0_00179993873 %float_0_00094209559 %float_n0_000344669126 %float_0_000696997566 %float_n0_00101868878 %float_n0_00157015934 %float_n2_29779416en05 %float_n0_00127910543 %float_0_000804227951 %float_n0_000896139711 %float_n0_0014322917 %float_0_000605085806 %float_n8_42524532en05 %float_0_000911458337 %float_0_001953125 %float_n0_00140165444 %float_n0_00063572306 %float_0_00150888483 %float_n0_000819546578 %float_0_00124846818 %float_0_000252757367 %float_0_00152420346 %float_0_00112591917 %float_0_000359987753 %float_n0_000390625006 %float_0_00190716912 %float_0_00138633582 %float_n0_00111060054 %float_0_00161611522 %float_n0_000880821084 %float_0_000145526967 %float_0_00107996329 %float_n5_36151965en05 %float_0_00028339462 %float_n0_00169270835 %float_n0_00126378681 %float_n0_000513174047 %float_n0_000160845593 %float_n0_00187653187 %float_n0_000834865205 %float_0_00063572306 %float_7_65931418en06 %float_n0_00190716912 %float_n0_000222120099 %float_0_000375306379 %float_n0_00173866423 %float_n0_000405943632 %float_n0_00123314955 %float_0_00170802698 %float_n0_00094209559 %float_0_000819546578 %float_0_00184589461 %float_0_000467218139 + %uint_1 = OpConstant %uint 1 + %uint_16 = OpConstant %uint 16 +%_ptr_Function__arr_float_uint_256 = OpTypePointer Function %_arr_float_uint_256 + %v4float = OpTypeVector %float 4 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%gl_FragCoord = OpVariable %_ptr_Input_v4float Input + %v2float = OpTypeVector %float 2 +%_struct_1010 = OpTypeStruct %v2int %float +%_ptr_PushConstant__struct_1010 = OpTypePointer PushConstant %_struct_1010 + %3305 = OpVariable %_ptr_PushConstant__struct_1010 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_v2int = OpTypePointer PushConstant %v2int + %int_1 = OpConstant %int 1 +%_ptr_PushConstant_float = OpTypePointer PushConstant %float +%_ptr_Output_v4float = OpTypePointer Output %v4float + %5334 = OpVariable %_ptr_Output_v4float Output +%uint_532432441 = OpConstant %uint 532432441 +%uint_2129690299 = OpConstant %uint 2129690299 +%uint_2129764351 = OpConstant %uint 2129764351 + %float_2 = OpConstant %float 2 + %151 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_151 = OpTypePointer UniformConstant %151 + %5163 = OpVariable %_ptr_UniformConstant_151 UniformConstant + %int_n1 = OpConstant %int -1 + %1803 = OpConstantComposite %v2int %int_0 %int_n1 + %1806 = OpConstantComposite %v2int %int_n1 %int_0 + %1824 = OpConstantComposite %v2int %int_1 %int_0 + %1827 = OpConstantComposite %v2int %int_0 %int_1 + %float_4 = OpConstant %float 4 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %2604 = OpConstantComposite %v3float %float_0 %float_0 %float_0 + %2582 = OpConstantComposite %v3float %float_1 %float_1 %float_1 + %10264 = OpUndef %v4float + %5663 = OpFunction %void None %1282 + %24953 = OpLabel + %18411 = OpVariable %_ptr_Function__arr_float_uint_256 Function + %22087 = OpLoad %v4float %gl_FragCoord + %6562 = OpVectorShuffle %v2float %22087 %22087 0 1 + %17656 = OpConvertFToS %v2int %6562 + %19279 = OpAccessChain %_ptr_PushConstant_v2int %3305 %int_0 + %22822 = OpLoad %v2int %19279 + %23312 = OpISub %v2int %17656 %22822 + %9938 = OpBitcast %v2uint %23312 + %20997 = OpAccessChain %_ptr_PushConstant_float %3305 %int_1 + %22237 = OpLoad %float %20997 + %16454 = OpBitcast %uint %22237 + %6990 = OpBitcast %v2int %9938 + %14365 = OpIAdd %v2int %6990 %1803 + %23057 = OpLoad %151 %5163 + %19459 = OpImageFetch %v4float %23057 %14365 Lod %int_0 + %13347 = OpIAdd %v2int %6990 %1806 + %14538 = OpLoad %151 %5163 + %12625 = OpImageFetch %v4float %14538 %13347 Lod %int_0 + %10421 = OpLoad %151 %5163 + %15444 = OpImageFetch %v4float %10421 %6990 Lod %int_0 + %13348 = OpIAdd %v2int %6990 %1824 + %15811 = OpLoad %151 %5163 + %19460 = OpImageFetch %v4float %15811 %13348 Lod %int_0 + %13349 = OpIAdd %v2int %6990 %1827 + %14918 = OpLoad %151 %5163 + %8899 = OpImageFetch %v4float %14918 %13349 Lod %int_0 + %19729 = OpCompositeExtract %float %19459 0 + %7025 = OpCompositeExtract %float %19459 1 + %18723 = OpCompositeExtract %float %19459 2 + %24863 = OpFMul %float %19729 %19729 + %16184 = OpFMul %float %7025 %7025 + %9305 = OpFMul %float %18723 %18723 + %22236 = OpCompositeExtract %float %12625 0 + %11844 = OpCompositeExtract %float %12625 1 + %18724 = OpCompositeExtract %float %12625 2 + %24864 = OpFMul %float %22236 %22236 + %16185 = OpFMul %float %11844 %11844 + %9306 = OpFMul %float %18724 %18724 + %22238 = OpCompositeExtract %float %15444 0 + %11845 = OpCompositeExtract %float %15444 1 + %18725 = OpCompositeExtract %float %15444 2 + %24865 = OpFMul %float %22238 %22238 + %16186 = OpFMul %float %11845 %11845 + %9307 = OpFMul %float %18725 %18725 + %22239 = OpCompositeExtract %float %19460 0 + %11846 = OpCompositeExtract %float %19460 1 + %18726 = OpCompositeExtract %float %19460 2 + %24866 = OpFMul %float %22239 %22239 + %16187 = OpFMul %float %11846 %11846 + %9308 = OpFMul %float %18726 %18726 + %22240 = OpCompositeExtract %float %8899 0 + %11847 = OpCompositeExtract %float %8899 1 + %18727 = OpCompositeExtract %float %8899 2 + %24867 = OpFMul %float %22240 %22240 + %14910 = OpFMul %float %11847 %11847 + %8590 = OpFMul %float %18727 %18727 + %10877 = OpExtInst %float %1 FMin %16186 %16187 + %9276 = OpExtInst %float %1 FMin %16185 %10877 + %15951 = OpExtInst %float %1 FMin %16184 %14910 + %10905 = OpExtInst %float %1 FMin %9276 %15951 + %24296 = OpExtInst %float %1 FMax %16186 %16187 + %17523 = OpExtInst %float %1 FMax %16185 %24296 + %23939 = OpExtInst %float %1 FMax %16184 %14910 + %21101 = OpExtInst %float %1 FMax %17523 %23939 + %8181 = OpBitcast %uint %21101 + %8951 = OpISub %uint %uint_2129690299 %8181 + %6465 = OpBitcast %float %8951 + %24131 = OpFSub %float %float_1 %21101 + %23324 = OpExtInst %float %1 FMin %10905 %24131 + %22903 = OpFMul %float %23324 %6465 + %20683 = OpExtInst %float %1 FClamp %22903 %float_0 %float_1 + %24011 = OpBitcast %uint %20683 + %22090 = OpShiftRightLogical %uint %24011 %uint_1 + %23229 = OpIAdd %uint %22090 %uint_532432441 + %21692 = OpBitcast %float %23229 + %19558 = OpBitcast %float %16454 + %18803 = OpFMul %float %21692 %19558 + %23316 = OpFMul %float %float_4 %18803 + %16498 = OpFAdd %float %float_1 %23316 + %6551 = OpBitcast %uint %16498 + %7563 = OpISub %uint %uint_2129764351 %6551 + %9419 = OpBitcast %float %7563 + %9130 = OpFNegate %float %9419 + %12367 = OpFMul %float %9130 %16498 + %16540 = OpFAdd %float %12367 %float_2 + %9366 = OpFMul %float %9419 %16540 + %18845 = OpFAdd %float %24863 %24864 + %23143 = OpFAdd %float %18845 %24866 + %6535 = OpFAdd %float %23143 %24867 + %12673 = OpFMul %float %18803 %6535 + %15973 = OpFAdd %float %12673 %24865 + %8137 = OpFMul %float %15973 %9366 + %15142 = OpExtInst %float %1 FClamp %8137 %float_0 %float_1 + %13381 = OpFAdd %float %16184 %16185 + %12943 = OpFAdd %float %13381 %16187 + %6536 = OpFAdd %float %12943 %14910 + %12674 = OpFMul %float %18803 %6536 + %15974 = OpFAdd %float %12674 %16186 + %8138 = OpFMul %float %15974 %9366 + %15143 = OpExtInst %float %1 FClamp %8138 %float_0 %float_1 + %13382 = OpFAdd %float %9305 %9306 + %12944 = OpFAdd %float %13382 %9308 + %6537 = OpFAdd %float %12944 %8590 + %12675 = OpFMul %float %18803 %6537 + %15975 = OpFAdd %float %12675 %9307 + %7244 = OpFMul %float %15975 %9366 + %22380 = OpExtInst %float %1 FClamp %7244 %float_0 %float_1 + %24270 = OpCompositeInsert %v4float %15142 %10264 0 + %11074 = OpCompositeInsert %v4float %15143 %24270 1 + %14933 = OpCompositeInsert %v4float %22380 %11074 2 + %12955 = OpVectorShuffle %v3float %14933 %14933 0 1 2 + %6471 = OpExtInst %v3float %1 Sqrt %12955 + %22742 = OpCompositeExtract %float %6471 0 + %19769 = OpCompositeInsert %v4float %22742 %10264 0 + %19852 = OpCompositeExtract %float %6471 1 + %16135 = OpCompositeInsert %v4float %19852 %19769 1 + %19814 = OpCompositeExtract %float %6471 2 + %18704 = OpCompositeInsert %v4float %19814 %16135 2 + %15997 = OpVectorShuffle %v3float %18704 %18704 0 1 2 + %12552 = OpBitwiseAnd %v2uint %9938 %2122 + %9741 = OpCompositeExtract %uint %12552 1 + %21498 = OpIMul %uint %9741 %uint_16 + %23411 = OpCompositeExtract %uint %12552 0 + %12610 = OpIAdd %uint %21498 %23411 + OpStore %18411 %2242 + %9958 = OpAccessChain %_ptr_Function_float %18411 %12610 + %25140 = OpLoad %float %9958 + %18028 = OpCompositeConstruct %v3float %25140 %25140 %25140 + %21458 = OpFAdd %v3float %15997 %18028 + %19525 = OpExtInst %v3float %1 FClamp %21458 %2604 %2582 + %16777 = OpCompositeExtract %float %19525 0 + %19708 = OpCompositeExtract %float %19525 1 + %7472 = OpCompositeExtract %float %19525 2 + %22408 = OpCompositeConstruct %v4float %16777 %19708 %7472 %float_1 + OpStore %5334 %22408 + OpReturn + OpFunctionEnd +#endif + +const uint32_t guest_output_ffx_cas_sharpen_dither_ps[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006235, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0007000F, 0x00000004, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000C93, 0x000014D6, 0x00030010, + 0x0000161F, 0x00000007, 0x00040047, 0x00000C93, 0x0000000B, 0x0000000F, 0x00030047, 0x000003F2, + 0x00000002, 0x00050048, 0x000003F2, 0x00000000, 0x00000023, 0x00000010, 0x00050048, 0x000003F2, + 0x00000001, 0x00000023, 0x00000018, 0x00040047, 0x000014D6, 0x0000001E, 0x00000000, 0x00040047, + 0x0000142B, 0x00000021, 0x00000000, 0x00040047, 0x0000142B, 0x00000022, 0x00000000, 0x00020013, + 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00030016, 0x0000000D, 0x00000020, 0x00040020, + 0x0000028A, 0x00000007, 0x0000000D, 0x00040017, 0x00000018, 0x0000000D, 0x00000003, 0x00040015, + 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040015, + 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x0004002B, + 0x0000000D, 0x00000A0C, 0x00000000, 0x0004002B, 0x0000000D, 0x0000008A, 0x3F800000, 0x0004002B, + 0x0000000B, 0x00000A37, 0x0000000F, 0x0004002B, 0x0000000B, 0x00000147, 0x00000100, 0x0004001C, + 0x000003FB, 0x0000000D, 0x00000147, 0x0004002B, 0x0000000D, 0x0000010F, 0xBA838384, 0x0004002B, + 0x0000000D, 0x00000728, 0x3A66E6E7, 0x0004002B, 0x0000000D, 0x00000705, 0x3ADDDDDE, 0x0004002B, + 0x0000000D, 0x00000A5A, 0xBACBCBCC, 0x0004002B, 0x0000000D, 0x000008DF, 0x3AA7A7A8, 0x0004002B, + 0x0000000D, 0x00000094, 0xBA1E9E9F, 0x0004002B, 0x0000000D, 0x0000034C, 0x3A8B8B8C, 0x0004002B, + 0x0000000D, 0x0000087E, 0xBAB5B5B6, 0x0004002B, 0x0000000D, 0x0000034D, 0x3AB1B1B2, 0x0004002B, + 0x0000000D, 0x00000687, 0x3A068687, 0x0004002B, 0x0000000D, 0x000003EB, 0x3A9F9FA0, 0x0004002B, + 0x0000000D, 0x0000024E, 0xBAD1D1D2, 0x0004002B, 0x0000000D, 0x00000726, 0x3A1A9A9B, 0x0004002B, + 0x0000000D, 0x00000698, 0xB9949495, 0x0004002B, 0x0000000D, 0x00000703, 0x3A919192, 0x0004002B, + 0x0000000D, 0x00000AF8, 0xBAB9B9BA, 0x0004002B, 0x0000000D, 0x00000ABB, 0x3ABDBDBE, 0x0004002B, + 0x0000000D, 0x0000026F, 0xBA0E8E8F, 0x0004002B, 0x0000000D, 0x000008A8, 0x39088889, 0x0004002B, + 0x0000000D, 0x00000565, 0xBA9D9D9E, 0x0004002B, 0x0000000D, 0x0000065D, 0x39E4E4E5, 0x0004002B, + 0x0000000D, 0x000004C6, 0xBA89898A, 0x0004002B, 0x0000000D, 0x00000057, 0x3A22A2A3, 0x0004002B, + 0x0000000D, 0x0000006A, 0xB9FCFCFD, 0x0004002B, 0x0000000D, 0x00000A1E, 0x3AF5F5F6, 0x0004002B, + 0x0000000D, 0x0000087D, 0xBA8F8F90, 0x0004002B, 0x0000000D, 0x00000959, 0xB8D0D0D1, 0x0004002B, + 0x0000000D, 0x00000BB8, 0xBA0A8A8B, 0x0004002B, 0x0000000D, 0x0000097E, 0x3ABBBBBC, 0x0004002B, + 0x0000000D, 0x00000606, 0xBAFDFDFE, 0x0004002B, 0x0000000D, 0x000003AD, 0xBA36B6B7, 0x0004002B, + 0x0000000D, 0x000000E2, 0x3820A0A1, 0x0004002B, 0x0000000D, 0x00000370, 0x3A3ABABB, 0x0004002B, + 0x0000000D, 0x0000024D, 0xBAABABAC, 0x0004002B, 0x0000000D, 0x000005C6, 0x3A8F8F90, 0x0004002B, + 0x0000000D, 0x00000B8C, 0xB99C9C9D, 0x0004002B, 0x0000000D, 0x00000036, 0x3AE5E5E6, 0x0004002B, + 0x0000000D, 0x0000087F, 0xBADBDBDC, 0x0004002B, 0x0000000D, 0x00000172, 0x3AC1C1C2, 0x0004002B, + 0x0000000D, 0x00000399, 0xB820A0A1, 0x0004002B, 0x0000000D, 0x0000040F, 0x3A4ECECF, 0x0004002B, + 0x0000000D, 0x0000091E, 0xBAEFEFF0, 0x0004002B, 0x0000000D, 0x000008D5, 0x399C9C9D, 0x0004002B, + 0x0000000D, 0x000008DE, 0x3A818182, 0x0004002B, 0x0000000D, 0x000002EB, 0xBA99999A, 0x0004002B, + 0x0000000D, 0x00000317, 0x3938B8B9, 0x0004002B, 0x0000000D, 0x0000034E, 0x3AD7D7D8, 0x0004002B, + 0x0000000D, 0x00000111, 0xBACFCFD0, 0x0004002B, 0x0000000D, 0x0000002B, 0x39B4B4B5, 0x0004002B, + 0x0000000D, 0x000008E1, 0x3AF3F3F4, 0x0004002B, 0x0000000D, 0x0000042A, 0xBAE7E7E8, 0x0004002B, + 0x0000000D, 0x00000765, 0xBA62E2E3, 0x0004002B, 0x0000000D, 0x000009A2, 0x3A6AEAEB, 0x0004002B, + 0x0000000D, 0x000004F2, 0x3928A8A9, 0x0004002B, 0x0000000D, 0x0000058A, 0xBA72F2F3, 0x0004002B, + 0x0000000D, 0x000007E0, 0xBAC7C7C8, 0x0004002B, 0x0000000D, 0x00000802, 0xBA2AAAAB, 0x0004002B, + 0x0000000D, 0x00000A1C, 0x3AA9A9AA, 0x0004002B, 0x0000000D, 0x00000940, 0xBA52D2D3, 0x0004002B, + 0x0000000D, 0x000002EC, 0xBABFBFC0, 0x0004002B, 0x0000000D, 0x000003ED, 0x3AEBEBEC, 0x0004002B, + 0x0000000D, 0x000004EB, 0xBA5EDEDF, 0x0004002B, 0x0000000D, 0x00000234, 0x3A5EDEDF, 0x0004002B, + 0x0000000D, 0x00000245, 0xB9ECECED, 0x0004002B, 0x0000000D, 0x00000603, 0xBA8B8B8C, 0x0004002B, + 0x0000000D, 0x00000984, 0xB9189899, 0x0004002B, 0x0000000D, 0x0000076E, 0x3978F8F9, 0x0004002B, + 0x0000000D, 0x00000841, 0x3AB9B9BA, 0x0004002B, 0x0000000D, 0x000009DD, 0xBA1A9A9B, 0x0004002B, + 0x0000000D, 0x000003F3, 0xB948C8C9, 0x0004002B, 0x0000000D, 0x00000B5A, 0x3AD1D1D2, 0x0004002B, + 0x0000000D, 0x00000B58, 0x3A858586, 0x0004002B, 0x0000000D, 0x00000838, 0x39D4D4D5, 0x0004002B, + 0x0000000D, 0x00000218, 0xB958D8D9, 0x0004002B, 0x0000000D, 0x00000A1D, 0x3ACFCFD0, 0x0004002B, + 0x0000000D, 0x0000054B, 0x3A2AAAAB, 0x0004002B, 0x0000000D, 0x00000503, 0xB8909091, 0x0004002B, + 0x0000000D, 0x00000169, 0x39DCDCDD, 0x0004002B, 0x0000000D, 0x00000605, 0xBAD7D7D8, 0x0004002B, + 0x0000000D, 0x0000048A, 0x3AB3B3B4, 0x0004002B, 0x0000000D, 0x000002D3, 0x3A72F2F3, 0x0004002B, + 0x0000000D, 0x00000A7C, 0xBA2EAEAF, 0x0004002B, 0x0000000D, 0x00000171, 0x3A9B9B9C, 0x0004002B, + 0x0000000D, 0x000001AF, 0xBABDBDBE, 0x0004002B, 0x0000000D, 0x000004AC, 0x3A169697, 0x0004002B, + 0x0000000D, 0x0000024F, 0xBAF7F7F8, 0x0004002B, 0x0000000D, 0x00000ADE, 0x3A46C6C7, 0x0004002B, + 0x0000000D, 0x00000110, 0xBAA9A9AA, 0x0004002B, 0x0000000D, 0x00000212, 0x3AFBFBFC, 0x0004002B, + 0x0000000D, 0x00000742, 0xBAD9D9DA, 0x0004002B, 0x0000000D, 0x00000389, 0xBA878788, 0x0004002B, + 0x0000000D, 0x000006C4, 0xBA028283, 0x0004002B, 0x0000000D, 0x00000B98, 0xBAF3F3F4, 0x0004002B, + 0x0000000D, 0x000002AE, 0x3A9D9D9E, 0x0004002B, 0x0000000D, 0x000009B1, 0xB9ACACAD, 0x0004002B, + 0x0000000D, 0x00000741, 0xBAB3B3B4, 0x0004002B, 0x0000000D, 0x00000211, 0x3AD5D5D6, 0x0004002B, + 0x0000000D, 0x00000A5B, 0xBAF1F1F2, 0x0004002B, 0x0000000D, 0x000005EA, 0x3A3EBEBF, 0x0004002B, + 0x0000000D, 0x00000310, 0xBA6EEEEF, 0x0004002B, 0x0000000D, 0x0000052A, 0x3AEDEDEE, 0x0004002B, + 0x0000000D, 0x00000071, 0xBA959596, 0x0004002B, 0x0000000D, 0x00000107, 0xB9C4C4C5, 0x0004002B, + 0x0000000D, 0x000006A2, 0x38D0D0D1, 0x0004002B, 0x0000000D, 0x00000B1B, 0xBA42C2C3, 0x0004002B, + 0x0000000D, 0x00000034, 0x3A99999A, 0x0004002B, 0x0000000D, 0x0000024B, 0x38909091, 0x0004002B, + 0x0000000D, 0x000002AF, 0x3AC3C3C4, 0x0004002B, 0x0000000D, 0x00000A41, 0x3A7EFEFF, 0x0004002B, + 0x0000000D, 0x00000A7E, 0xBA7AFAFB, 0x0004002B, 0x0000000D, 0x0000034F, 0x3AFDFDFE, 0x0004002B, + 0x0000000D, 0x00000901, 0x3A0A8A8B, 0x0004002B, 0x0000000D, 0x00000539, 0x3860E0E1, 0x0004002B, + 0x0000000D, 0x0000091C, 0xBAA3A3A4, 0x0004002B, 0x0000000D, 0x000001A4, 0xB98C8C8D, 0x0004002B, + 0x0000000D, 0x00000666, 0x3AC9C9CA, 0x0004002B, 0x0000000D, 0x00000833, 0xB7008081, 0x0004002B, + 0x0000000D, 0x00000206, 0x39A4A4A5, 0x0004002B, 0x0000000D, 0x00000210, 0x3AAFAFB0, 0x0004002B, + 0x0000000D, 0x000002ED, 0xBAE5E5E6, 0x0004002B, 0x0000000D, 0x0000040D, 0x3A028283, 0x0004002B, + 0x0000000D, 0x00000428, 0xBA9B9B9C, 0x0004002B, 0x0000000D, 0x00000195, 0x3A4ACACB, 0x0004002B, + 0x0000000D, 0x000004C7, 0xBAAFAFB0, 0x0004002B, 0x0000000D, 0x00000AB0, 0x398C8C8D, 0x0004002B, + 0x0000000D, 0x00000429, 0xBAC1C1C2, 0x0004002B, 0x0000000D, 0x00000B5F, 0xB9088889, 0x0004002B, + 0x0000000D, 0x0000044C, 0xBA4ACACB, 0x0004002B, 0x0000000D, 0x00000B59, 0x3AABABAC, 0x0004002B, + 0x0000000D, 0x00000344, 0x39CCCCCD, 0x0004002B, 0x0000000D, 0x000007C7, 0x3A7AFAFB, 0x0004002B, + 0x0000000D, 0x00000739, 0xB9F4F4F5, 0x0004002B, 0x0000000D, 0x0000091D, 0xBAC9C9CA, 0x0004002B, + 0x0000000D, 0x000000D2, 0x3A878788, 0x0004002B, 0x0000000D, 0x00000133, 0xBA32B2B3, 0x0004002B, + 0x0000000D, 0x000005C8, 0x3ADBDBDC, 0x0004002B, 0x0000000D, 0x00000A1B, 0x3A838384, 0x0004002B, + 0x0000000D, 0x00000420, 0xB9DCDCDD, 0x0004002B, 0x0000000D, 0x000002B0, 0x3AE9E9EA, 0x0004002B, + 0x0000000D, 0x00000A25, 0xB978F8F9, 0x0004002B, 0x0000000D, 0x0000030E, 0xBA22A2A3, 0x0004002B, + 0x0000000D, 0x0000048B, 0x3AD9D9DA, 0x0004002B, 0x0000000D, 0x00000B7D, 0x3A5ADADB, 0x0004002B, + 0x0000000D, 0x00000073, 0xBAE1E1E2, 0x0004002B, 0x0000000D, 0x00000740, 0xBA8D8D8E, 0x0004002B, + 0x0000000D, 0x00000173, 0x3AE7E7E8, 0x0004002B, 0x0000000D, 0x000006C6, 0xBA4ECECF, 0x0004002B, + 0x0000000D, 0x00000567, 0xBAE9E9EA, 0x0004002B, 0x0000000D, 0x00000A3F, 0x3A32B2B3, 0x0004002B, + 0x0000000D, 0x00000B95, 0xBA818182, 0x0004002B, 0x0000000D, 0x0000038A, 0xBAADADAE, 0x0004002B, + 0x0000000D, 0x000005CE, 0xB938B8B9, 0x0004002B, 0x0000000D, 0x000006A3, 0xBAC5C5C6, 0x0004002B, + 0x0000000D, 0x000006FA, 0x39ACACAD, 0x0004002B, 0x0000000D, 0x00000743, 0xBB000000, 0x0004002B, + 0x0000000D, 0x000007C5, 0x3A2EAEAF, 0x0004002B, 0x0000000D, 0x0000038B, 0xBAD3D3D4, 0x0004002B, + 0x0000000D, 0x00000ABA, 0x3A979798, 0x0004002B, 0x0000000D, 0x00000B51, 0x39ECECED, 0x0004002B, + 0x0000000D, 0x00000914, 0xB9E4E4E5, 0x0004002B, 0x0000000D, 0x0000013C, 0x3948C8C9, 0x0004002B, + 0x0000000D, 0x00000566, 0xBAC3C3C4, 0x0004002B, 0x0000000D, 0x0000097D, 0x3A959596, 0x0004002B, + 0x0000000D, 0x00000A58, 0x38B0B0B1, 0x0004002B, 0x0000000D, 0x00000B5B, 0x3AF7F7F8, 0x0004002B, + 0x0000000D, 0x00000704, 0x3AB7B7B8, 0x0004002B, 0x0000000D, 0x00000232, 0x3A129293, 0x0004002B, + 0x0000000D, 0x000002EE, 0x38F0F0F1, 0x0004002B, 0x0000000D, 0x000007A2, 0x3AA5A5A6, 0x0004002B, + 0x0000000D, 0x00000763, 0xBA169697, 0x0004002B, 0x0000000D, 0x00000135, 0xBA7EFEFF, 0x0004002B, + 0x0000000D, 0x000000D3, 0x3AADADAE, 0x0004002B, 0x0000000D, 0x00000949, 0x3968E8E9, 0x0004002B, + 0x0000000D, 0x000001D2, 0xBA46C6C7, 0x0004002B, 0x0000000D, 0x00000604, 0xBAB1B1B2, 0x0004002B, + 0x0000000D, 0x00000035, 0x3ABFBFC0, 0x0004002B, 0x0000000D, 0x000004AE, 0x3A62E2E3, 0x0004002B, + 0x0000000D, 0x000007D6, 0xB9BCBCBD, 0x0004002B, 0x0000000D, 0x00000B7B, 0x3A0E8E8F, 0x0004002B, + 0x0000000D, 0x00000AF7, 0xBA939394, 0x0004002B, 0x0000000D, 0x00000873, 0xB9848485, 0x0004002B, + 0x0000000D, 0x000004E9, 0xBA129293, 0x0004002B, 0x0000000D, 0x000007E1, 0xBAEDEDEE, 0x0004002B, + 0x0000000D, 0x0000097F, 0x3AE1E1E2, 0x0004002B, 0x0000000D, 0x000001AE, 0xBA979798, 0x0004002B, + 0x0000000D, 0x00000864, 0x3A42C2C3, 0x0004002B, 0x0000000D, 0x000008E0, 0x3ACDCDCE, 0x0004002B, + 0x0000000D, 0x000005A3, 0xB8F0F0F1, 0x0004002B, 0x0000000D, 0x000006A4, 0xBA9F9FA0, 0x0004002B, + 0x0000000D, 0x00000667, 0x3AEFEFF0, 0x0004002B, 0x0000000D, 0x00000961, 0x37C0C0C1, 0x0004002B, + 0x0000000D, 0x000004C9, 0xBAFBFBFC, 0x0004002B, 0x0000000D, 0x00000ABC, 0x3AE3E3E4, 0x0004002B, + 0x0000000D, 0x00000627, 0xBA3ABABB, 0x0004002B, 0x0000000D, 0x000007A3, 0x3ACBCBCC, 0x0004002B, + 0x0000000D, 0x00000AF9, 0xBADFDFE0, 0x0004002B, 0x0000000D, 0x00000528, 0x3AA1A1A2, 0x0004002B, + 0x0000000D, 0x00000B24, 0x3958D8D9, 0x0004002B, 0x0000000D, 0x0000020F, 0x3A89898A, 0x0004002B, + 0x0000000D, 0x000008A1, 0xBA3EBEBF, 0x0004002B, 0x0000000D, 0x000004C8, 0xBAD5D5D6, 0x0004002B, + 0x0000000D, 0x000004BD, 0xB9A4A4A5, 0x0004002B, 0x0000000D, 0x00000976, 0x39FCFCFD, 0x0004002B, + 0x0000000D, 0x000006A5, 0xBAEBEBEC, 0x0004002B, 0x0000000D, 0x0000054D, 0x3A76F6F7, 0x0004002B, + 0x0000000D, 0x000002E2, 0xB9B4B4B5, 0x0004002B, 0x0000000D, 0x000000F6, 0x3A36B6B7, 0x0004002B, + 0x0000000D, 0x0000024C, 0xBA858586, 0x0004002B, 0x0000000D, 0x00000B97, 0xBACDCDCE, 0x0004002B, + 0x0000000D, 0x00000055, 0xB7C0C0C1, 0x0004002B, 0x0000000D, 0x00000B96, 0xBAA7A7A8, 0x0004002B, + 0x0000000D, 0x00000689, 0x3A52D2D3, 0x0004002B, 0x0000000D, 0x00000096, 0xBA6AEAEB, 0x0004002B, + 0x0000000D, 0x00000072, 0xBABBBBBC, 0x0004002B, 0x0000000D, 0x000009A0, 0x3A1E9E9F, 0x0004002B, + 0x0000000D, 0x0000014C, 0xB8B0B0B1, 0x0004002B, 0x0000000D, 0x00000059, 0x3A6EEEEF, 0x0004002B, + 0x0000000D, 0x0000048C, 0x3B000000, 0x0004002B, 0x0000000D, 0x000009BB, 0xBAB7B7B8, 0x0004002B, + 0x0000000D, 0x00000588, 0xBA26A6A7, 0x0004002B, 0x0000000D, 0x000003EC, 0x3AC5C5C6, 0x0004002B, + 0x0000000D, 0x00000BBA, 0xBA56D6D7, 0x0004002B, 0x0000000D, 0x00000665, 0x3AA3A3A4, 0x0004002B, + 0x0000000D, 0x000005BC, 0x39848485, 0x0004002B, 0x0000000D, 0x00000529, 0x3AC7C7C8, 0x0004002B, + 0x0000000D, 0x00000840, 0x3A939394, 0x0004002B, 0x0000000D, 0x0000051F, 0x39BCBCBD, 0x0004002B, + 0x0000000D, 0x000005FB, 0xB9CCCCCD, 0x0004002B, 0x0000000D, 0x000000D5, 0x3AF9F9FA, 0x0004002B, + 0x0000000D, 0x000005C7, 0x3AB5B5B6, 0x0004002B, 0x0000000D, 0x000009BA, 0xBA919192, 0x0004002B, + 0x0000000D, 0x000000D4, 0x3AD3D3D4, 0x0004002B, 0x0000000D, 0x000009DF, 0xBA66E6E7, 0x0004002B, + 0x0000000D, 0x000006CD, 0x39189899, 0x0004002B, 0x0000000D, 0x00000489, 0x3A8D8D8E, 0x0004002B, + 0x0000000D, 0x000007F0, 0xB860E0E1, 0x0004002B, 0x0000000D, 0x000003E1, 0x39949495, 0x0004002B, + 0x0000000D, 0x000009BC, 0xBADDDDDE, 0x0004002B, 0x0000000D, 0x00000A59, 0xBAA5A5A6, 0x0004002B, + 0x0000000D, 0x0000093E, 0xBA068687, 0x0004002B, 0x0000000D, 0x000007A9, 0xB928A8A9, 0x0004002B, + 0x0000000D, 0x00000112, 0xBAF5F5F6, 0x0004002B, 0x0000000D, 0x00000271, 0xBA5ADADB, 0x0004002B, + 0x0000000D, 0x000002D1, 0x3A26A6A7, 0x0004002B, 0x0000000D, 0x0000057C, 0x37008081, 0x0004002B, + 0x0000000D, 0x0000038C, 0xBAF9F9FA, 0x0004002B, 0x0000000D, 0x0000003D, 0xB968E8E9, 0x0004002B, + 0x0000000D, 0x00000A13, 0x39C4C4C5, 0x0004002B, 0x0000000D, 0x000001B0, 0xBAE3E3E4, 0x0004002B, + 0x0000000D, 0x00000AEF, 0xB9D4D4D5, 0x0004002B, 0x0000000D, 0x000007DF, 0xBAA1A1A2, 0x0004002B, + 0x0000000D, 0x00000842, 0x3ADFDFE0, 0x0004002B, 0x0000000D, 0x00000804, 0xBA76F6F7, 0x0004002B, + 0x0000000D, 0x00000903, 0x3A56D6D7, 0x0004002B, 0x0000000D, 0x000007A4, 0x3AF1F1F2, 0x0004002B, + 0x0000000D, 0x00000482, 0x39F4F4F5, 0x0103002C, 0x000003FB, 0x000008C2, 0x0000010F, 0x00000728, + 0x00000705, 0x00000A5A, 0x000008DF, 0x00000094, 0x0000034C, 0x0000087E, 0x0000034D, 0x00000687, + 0x000003EB, 0x0000024E, 0x00000726, 0x00000698, 0x00000703, 0x00000AF8, 0x00000ABB, 0x0000026F, + 0x000008A8, 0x00000565, 0x0000065D, 0x000004C6, 0x00000057, 0x0000006A, 0x00000A1E, 0x0000087D, + 0x00000959, 0x00000BB8, 0x0000097E, 0x00000606, 0x000003AD, 0x000000E2, 0x00000370, 0x0000024D, + 0x000005C6, 0x00000B8C, 0x00000036, 0x0000087F, 0x00000172, 0x00000399, 0x0000040F, 0x0000091E, + 0x000008D5, 0x000008DE, 0x000002EB, 0x00000317, 0x0000034E, 0x00000111, 0x0000002B, 0x000008E1, + 0x0000042A, 0x00000765, 0x000009A2, 0x000004F2, 0x0000058A, 0x000007E0, 0x00000802, 0x00000A1C, + 0x00000940, 0x000002EC, 0x000003ED, 0x000004EB, 0x00000234, 0x00000245, 0x00000603, 0x00000984, + 0x0000076E, 0x00000841, 0x000009DD, 0x000003F3, 0x00000B5A, 0x00000B58, 0x00000838, 0x00000218, + 0x00000A1D, 0x0000054B, 0x00000503, 0x00000169, 0x00000605, 0x0000048A, 0x000002D3, 0x00000A7C, + 0x00000171, 0x000001AF, 0x000004AC, 0x0000024F, 0x00000ADE, 0x00000110, 0x00000212, 0x00000742, + 0x00000389, 0x000006C4, 0x00000B98, 0x000002AE, 0x000009B1, 0x00000741, 0x00000211, 0x00000A5B, + 0x000005EA, 0x00000310, 0x0000052A, 0x00000071, 0x00000107, 0x000006A2, 0x00000B1B, 0x00000034, + 0x0000024B, 0x000002AF, 0x00000A41, 0x00000A7E, 0x0000034F, 0x00000901, 0x00000539, 0x0000091C, + 0x000001A4, 0x00000666, 0x00000833, 0x00000206, 0x00000210, 0x000002ED, 0x0000040D, 0x00000428, + 0x00000195, 0x000004C7, 0x00000AB0, 0x00000429, 0x00000B5F, 0x0000044C, 0x00000B59, 0x00000344, + 0x000007C7, 0x00000739, 0x0000091D, 0x000000D2, 0x00000133, 0x000005C8, 0x00000A1B, 0x00000420, + 0x000002B0, 0x00000A25, 0x0000030E, 0x0000048B, 0x00000B7D, 0x00000073, 0x00000740, 0x00000173, + 0x000006C6, 0x00000567, 0x00000A3F, 0x00000B95, 0x0000038A, 0x000005CE, 0x000006A3, 0x000006FA, + 0x00000743, 0x000007C5, 0x0000038B, 0x00000ABA, 0x00000B51, 0x00000914, 0x0000013C, 0x00000566, + 0x0000097D, 0x00000A58, 0x00000B5B, 0x00000704, 0x00000232, 0x000002EE, 0x000007A2, 0x00000763, + 0x00000135, 0x000000D3, 0x00000949, 0x000001D2, 0x00000604, 0x00000035, 0x000004AE, 0x000007D6, + 0x00000B7B, 0x00000AF7, 0x00000873, 0x000004E9, 0x000007E1, 0x0000097F, 0x000001AE, 0x00000864, + 0x000008E0, 0x000005A3, 0x000006A4, 0x00000667, 0x00000961, 0x000004C9, 0x00000ABC, 0x00000627, + 0x000007A3, 0x00000AF9, 0x00000528, 0x00000B24, 0x0000020F, 0x000008A1, 0x000004C8, 0x000004BD, + 0x00000976, 0x000006A5, 0x0000054D, 0x000002E2, 0x000000F6, 0x0000024C, 0x00000B97, 0x00000055, + 0x00000B96, 0x00000689, 0x00000096, 0x00000072, 0x000009A0, 0x0000014C, 0x00000059, 0x0000048C, + 0x000009BB, 0x00000588, 0x000003EC, 0x00000BBA, 0x00000665, 0x000005BC, 0x00000529, 0x00000840, + 0x0000051F, 0x000005FB, 0x000000D5, 0x000005C7, 0x000009BA, 0x000000D4, 0x000009DF, 0x000006CD, + 0x00000489, 0x000007F0, 0x000003E1, 0x000009BC, 0x00000A59, 0x0000093E, 0x000007A9, 0x00000112, + 0x00000271, 0x000002D1, 0x0000057C, 0x0000038C, 0x0000003D, 0x00000A13, 0x000001B0, 0x00000AEF, + 0x000007DF, 0x00000842, 0x00000804, 0x00000903, 0x000007A4, 0x00000482, 0x0004002B, 0x0000000B, + 0x00000A0D, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x00040020, 0x00000678, + 0x00000007, 0x000003FB, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x00040020, 0x0000029A, + 0x00000001, 0x0000001D, 0x0004003B, 0x0000029A, 0x00000C93, 0x00000001, 0x00040017, 0x00000013, + 0x0000000D, 0x00000002, 0x0004001E, 0x000003F2, 0x00000012, 0x0000000D, 0x00040020, 0x0000066F, + 0x00000009, 0x000003F2, 0x0004003B, 0x0000066F, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, + 0x00000A0B, 0x00000000, 0x00040020, 0x0000028F, 0x00000009, 0x00000012, 0x0004002B, 0x0000000C, + 0x00000A0E, 0x00000001, 0x00040020, 0x0000028B, 0x00000009, 0x0000000D, 0x00040020, 0x0000029B, + 0x00000003, 0x0000001D, 0x0004003B, 0x0000029B, 0x000014D6, 0x00000003, 0x0004002B, 0x0000000B, + 0x0000020D, 0x1FBC4639, 0x0004002B, 0x0000000B, 0x00000345, 0x7EF07EBB, 0x0004002B, 0x0000000B, + 0x000000B2, 0x7EF19FFF, 0x0004002B, 0x0000000D, 0x00000019, 0x40000000, 0x00090019, 0x00000097, + 0x0000000D, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00040020, + 0x00000313, 0x00000000, 0x00000097, 0x0004003B, 0x00000313, 0x0000142B, 0x00000000, 0x0004002B, + 0x0000000C, 0x00000A08, 0xFFFFFFFF, 0x0005002C, 0x00000012, 0x0000070B, 0x00000A0B, 0x00000A08, + 0x0005002C, 0x00000012, 0x0000070E, 0x00000A08, 0x00000A0B, 0x0005002C, 0x00000012, 0x00000720, + 0x00000A0E, 0x00000A0B, 0x0005002C, 0x00000012, 0x00000723, 0x00000A0B, 0x00000A0E, 0x0004002B, + 0x0000000D, 0x00000B69, 0x40800000, 0x0005002C, 0x00000011, 0x0000084A, 0x00000A37, 0x00000A37, + 0x0006002C, 0x00000018, 0x00000A2C, 0x00000A0C, 0x00000A0C, 0x00000A0C, 0x0006002C, 0x00000018, + 0x00000A16, 0x0000008A, 0x0000008A, 0x0000008A, 0x00030001, 0x0000001D, 0x00002818, 0x00050036, + 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00006179, 0x0004003B, 0x00000678, + 0x000047EB, 0x00000007, 0x0004003D, 0x0000001D, 0x00005647, 0x00000C93, 0x0007004F, 0x00000013, + 0x000019A2, 0x00005647, 0x00005647, 0x00000000, 0x00000001, 0x0004006E, 0x00000012, 0x000044F8, + 0x000019A2, 0x00050041, 0x0000028F, 0x00004B4F, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x00000012, + 0x00005926, 0x00004B4F, 0x00050082, 0x00000012, 0x00005B10, 0x000044F8, 0x00005926, 0x0004007C, + 0x00000011, 0x000026D2, 0x00005B10, 0x00050041, 0x0000028B, 0x00005205, 0x00000CE9, 0x00000A0E, + 0x0004003D, 0x0000000D, 0x000056DD, 0x00005205, 0x0004007C, 0x0000000B, 0x00004046, 0x000056DD, + 0x0004007C, 0x00000012, 0x00001B4E, 0x000026D2, 0x00050080, 0x00000012, 0x0000381D, 0x00001B4E, + 0x0000070B, 0x0004003D, 0x00000097, 0x00005A11, 0x0000142B, 0x0007005F, 0x0000001D, 0x00004C03, + 0x00005A11, 0x0000381D, 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x00003423, 0x00001B4E, + 0x0000070E, 0x0004003D, 0x00000097, 0x000038CA, 0x0000142B, 0x0007005F, 0x0000001D, 0x00003151, + 0x000038CA, 0x00003423, 0x00000002, 0x00000A0B, 0x0004003D, 0x00000097, 0x000028B5, 0x0000142B, + 0x0007005F, 0x0000001D, 0x00003C54, 0x000028B5, 0x00001B4E, 0x00000002, 0x00000A0B, 0x00050080, + 0x00000012, 0x00003424, 0x00001B4E, 0x00000720, 0x0004003D, 0x00000097, 0x00003DC3, 0x0000142B, + 0x0007005F, 0x0000001D, 0x00004C04, 0x00003DC3, 0x00003424, 0x00000002, 0x00000A0B, 0x00050080, + 0x00000012, 0x00003425, 0x00001B4E, 0x00000723, 0x0004003D, 0x00000097, 0x00003A46, 0x0000142B, + 0x0007005F, 0x0000001D, 0x000022C3, 0x00003A46, 0x00003425, 0x00000002, 0x00000A0B, 0x00050051, + 0x0000000D, 0x00004D11, 0x00004C03, 0x00000000, 0x00050051, 0x0000000D, 0x00001B71, 0x00004C03, + 0x00000001, 0x00050051, 0x0000000D, 0x00004923, 0x00004C03, 0x00000002, 0x00050085, 0x0000000D, + 0x0000611F, 0x00004D11, 0x00004D11, 0x00050085, 0x0000000D, 0x00003F38, 0x00001B71, 0x00001B71, + 0x00050085, 0x0000000D, 0x00002459, 0x00004923, 0x00004923, 0x00050051, 0x0000000D, 0x000056DC, + 0x00003151, 0x00000000, 0x00050051, 0x0000000D, 0x00002E44, 0x00003151, 0x00000001, 0x00050051, + 0x0000000D, 0x00004924, 0x00003151, 0x00000002, 0x00050085, 0x0000000D, 0x00006120, 0x000056DC, + 0x000056DC, 0x00050085, 0x0000000D, 0x00003F39, 0x00002E44, 0x00002E44, 0x00050085, 0x0000000D, + 0x0000245A, 0x00004924, 0x00004924, 0x00050051, 0x0000000D, 0x000056DE, 0x00003C54, 0x00000000, + 0x00050051, 0x0000000D, 0x00002E45, 0x00003C54, 0x00000001, 0x00050051, 0x0000000D, 0x00004925, + 0x00003C54, 0x00000002, 0x00050085, 0x0000000D, 0x00006121, 0x000056DE, 0x000056DE, 0x00050085, + 0x0000000D, 0x00003F3A, 0x00002E45, 0x00002E45, 0x00050085, 0x0000000D, 0x0000245B, 0x00004925, + 0x00004925, 0x00050051, 0x0000000D, 0x000056DF, 0x00004C04, 0x00000000, 0x00050051, 0x0000000D, + 0x00002E46, 0x00004C04, 0x00000001, 0x00050051, 0x0000000D, 0x00004926, 0x00004C04, 0x00000002, + 0x00050085, 0x0000000D, 0x00006122, 0x000056DF, 0x000056DF, 0x00050085, 0x0000000D, 0x00003F3B, + 0x00002E46, 0x00002E46, 0x00050085, 0x0000000D, 0x0000245C, 0x00004926, 0x00004926, 0x00050051, + 0x0000000D, 0x000056E0, 0x000022C3, 0x00000000, 0x00050051, 0x0000000D, 0x00002E47, 0x000022C3, + 0x00000001, 0x00050051, 0x0000000D, 0x00004927, 0x000022C3, 0x00000002, 0x00050085, 0x0000000D, + 0x00006123, 0x000056E0, 0x000056E0, 0x00050085, 0x0000000D, 0x00003A3E, 0x00002E47, 0x00002E47, + 0x00050085, 0x0000000D, 0x0000218E, 0x00004927, 0x00004927, 0x0007000C, 0x0000000D, 0x00002A7D, + 0x00000001, 0x00000025, 0x00003F3A, 0x00003F3B, 0x0007000C, 0x0000000D, 0x0000243C, 0x00000001, + 0x00000025, 0x00003F39, 0x00002A7D, 0x0007000C, 0x0000000D, 0x00003E4F, 0x00000001, 0x00000025, + 0x00003F38, 0x00003A3E, 0x0007000C, 0x0000000D, 0x00002A99, 0x00000001, 0x00000025, 0x0000243C, + 0x00003E4F, 0x0007000C, 0x0000000D, 0x00005EE8, 0x00000001, 0x00000028, 0x00003F3A, 0x00003F3B, + 0x0007000C, 0x0000000D, 0x00004473, 0x00000001, 0x00000028, 0x00003F39, 0x00005EE8, 0x0007000C, + 0x0000000D, 0x00005D83, 0x00000001, 0x00000028, 0x00003F38, 0x00003A3E, 0x0007000C, 0x0000000D, + 0x0000526D, 0x00000001, 0x00000028, 0x00004473, 0x00005D83, 0x0004007C, 0x0000000B, 0x00001FF5, + 0x0000526D, 0x00050082, 0x0000000B, 0x000022F7, 0x00000345, 0x00001FF5, 0x0004007C, 0x0000000D, + 0x00001941, 0x000022F7, 0x00050083, 0x0000000D, 0x00005E43, 0x0000008A, 0x0000526D, 0x0007000C, + 0x0000000D, 0x00005B1C, 0x00000001, 0x00000025, 0x00002A99, 0x00005E43, 0x00050085, 0x0000000D, + 0x00005977, 0x00005B1C, 0x00001941, 0x0008000C, 0x0000000D, 0x000050CB, 0x00000001, 0x0000002B, + 0x00005977, 0x00000A0C, 0x0000008A, 0x0004007C, 0x0000000B, 0x00005DCB, 0x000050CB, 0x000500C2, + 0x0000000B, 0x0000564A, 0x00005DCB, 0x00000A0D, 0x00050080, 0x0000000B, 0x00005ABD, 0x0000564A, + 0x0000020D, 0x0004007C, 0x0000000D, 0x000054BC, 0x00005ABD, 0x0004007C, 0x0000000D, 0x00004C66, + 0x00004046, 0x00050085, 0x0000000D, 0x00004973, 0x000054BC, 0x00004C66, 0x00050085, 0x0000000D, + 0x00005B14, 0x00000B69, 0x00004973, 0x00050081, 0x0000000D, 0x00004072, 0x0000008A, 0x00005B14, + 0x0004007C, 0x0000000B, 0x00001997, 0x00004072, 0x00050082, 0x0000000B, 0x00001D8B, 0x000000B2, + 0x00001997, 0x0004007C, 0x0000000D, 0x000024CB, 0x00001D8B, 0x0004007F, 0x0000000D, 0x000023AA, + 0x000024CB, 0x00050085, 0x0000000D, 0x0000304F, 0x000023AA, 0x00004072, 0x00050081, 0x0000000D, + 0x0000409C, 0x0000304F, 0x00000019, 0x00050085, 0x0000000D, 0x00002496, 0x000024CB, 0x0000409C, + 0x00050081, 0x0000000D, 0x0000499D, 0x0000611F, 0x00006120, 0x00050081, 0x0000000D, 0x00005A67, + 0x0000499D, 0x00006122, 0x00050081, 0x0000000D, 0x00001987, 0x00005A67, 0x00006123, 0x00050085, + 0x0000000D, 0x00003181, 0x00004973, 0x00001987, 0x00050081, 0x0000000D, 0x00003E65, 0x00003181, + 0x00006121, 0x00050085, 0x0000000D, 0x00001FC9, 0x00003E65, 0x00002496, 0x0008000C, 0x0000000D, + 0x00003B26, 0x00000001, 0x0000002B, 0x00001FC9, 0x00000A0C, 0x0000008A, 0x00050081, 0x0000000D, + 0x00003445, 0x00003F38, 0x00003F39, 0x00050081, 0x0000000D, 0x0000328F, 0x00003445, 0x00003F3B, + 0x00050081, 0x0000000D, 0x00001988, 0x0000328F, 0x00003A3E, 0x00050085, 0x0000000D, 0x00003182, + 0x00004973, 0x00001988, 0x00050081, 0x0000000D, 0x00003E66, 0x00003182, 0x00003F3A, 0x00050085, + 0x0000000D, 0x00001FCA, 0x00003E66, 0x00002496, 0x0008000C, 0x0000000D, 0x00003B27, 0x00000001, + 0x0000002B, 0x00001FCA, 0x00000A0C, 0x0000008A, 0x00050081, 0x0000000D, 0x00003446, 0x00002459, + 0x0000245A, 0x00050081, 0x0000000D, 0x00003290, 0x00003446, 0x0000245C, 0x00050081, 0x0000000D, + 0x00001989, 0x00003290, 0x0000218E, 0x00050085, 0x0000000D, 0x00003183, 0x00004973, 0x00001989, + 0x00050081, 0x0000000D, 0x00003E67, 0x00003183, 0x0000245B, 0x00050085, 0x0000000D, 0x00001C4C, + 0x00003E67, 0x00002496, 0x0008000C, 0x0000000D, 0x0000576C, 0x00000001, 0x0000002B, 0x00001C4C, + 0x00000A0C, 0x0000008A, 0x00060052, 0x0000001D, 0x00005ECE, 0x00003B26, 0x00002818, 0x00000000, + 0x00060052, 0x0000001D, 0x00002B42, 0x00003B27, 0x00005ECE, 0x00000001, 0x00060052, 0x0000001D, + 0x00003A55, 0x0000576C, 0x00002B42, 0x00000002, 0x0008004F, 0x00000018, 0x0000329B, 0x00003A55, + 0x00003A55, 0x00000000, 0x00000001, 0x00000002, 0x0006000C, 0x00000018, 0x00001947, 0x00000001, + 0x0000001F, 0x0000329B, 0x00050051, 0x0000000D, 0x000058D6, 0x00001947, 0x00000000, 0x00060052, + 0x0000001D, 0x00004D39, 0x000058D6, 0x00002818, 0x00000000, 0x00050051, 0x0000000D, 0x00004D8C, + 0x00001947, 0x00000001, 0x00060052, 0x0000001D, 0x00003F07, 0x00004D8C, 0x00004D39, 0x00000001, + 0x00050051, 0x0000000D, 0x00004D66, 0x00001947, 0x00000002, 0x00060052, 0x0000001D, 0x00004910, + 0x00004D66, 0x00003F07, 0x00000002, 0x0008004F, 0x00000018, 0x00003E7D, 0x00004910, 0x00004910, + 0x00000000, 0x00000001, 0x00000002, 0x000500C7, 0x00000011, 0x00003108, 0x000026D2, 0x0000084A, + 0x00050051, 0x0000000B, 0x0000260D, 0x00003108, 0x00000001, 0x00050084, 0x0000000B, 0x000053FA, + 0x0000260D, 0x00000A3A, 0x00050051, 0x0000000B, 0x00005B73, 0x00003108, 0x00000000, 0x00050080, + 0x0000000B, 0x00003142, 0x000053FA, 0x00005B73, 0x0003003E, 0x000047EB, 0x000008C2, 0x00050041, + 0x0000028A, 0x000026E6, 0x000047EB, 0x00003142, 0x0004003D, 0x0000000D, 0x00006234, 0x000026E6, + 0x00060050, 0x00000018, 0x0000466C, 0x00006234, 0x00006234, 0x00006234, 0x00050081, 0x00000018, + 0x000053D2, 0x00003E7D, 0x0000466C, 0x0008000C, 0x00000018, 0x00004C45, 0x00000001, 0x0000002B, + 0x000053D2, 0x00000A2C, 0x00000A16, 0x00050051, 0x0000000D, 0x00004189, 0x00004C45, 0x00000000, + 0x00050051, 0x0000000D, 0x00004CFC, 0x00004C45, 0x00000001, 0x00050051, 0x0000000D, 0x00001D30, + 0x00004C45, 0x00000002, 0x00070050, 0x0000001D, 0x00005788, 0x00004189, 0x00004CFC, 0x00001D30, + 0x0000008A, 0x0003003E, 0x000014D6, 0x00005788, 0x000100FD, 0x00010038, +}; diff --git a/src/ui/shaders/vulkan_spirv/guest_output_ffx_cas_sharpen_ps.h b/src/ui/shaders/vulkan_spirv/guest_output_ffx_cas_sharpen_ps.h new file mode 100644 index 0000000..5f3c8bf --- /dev/null +++ b/src/ui/shaders/vulkan_spirv/guest_output_ffx_cas_sharpen_ps.h @@ -0,0 +1,285 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 24950 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %5663 "main" %gl_FragCoord %5334 + OpExecutionMode %5663 OriginUpperLeft + OpDecorate %gl_FragCoord BuiltIn FragCoord + OpDecorate %_struct_1010 Block + OpMemberDecorate %_struct_1010 0 Offset 16 + OpMemberDecorate %_struct_1010 1 Offset 24 + OpDecorate %5334 Location 0 + OpDecorate %5163 Binding 0 + OpDecorate %5163 DescriptorSet 0 + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %float = OpTypeFloat 32 + %uint = OpTypeInt 32 0 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v3float = OpTypeVector %float 3 + %v2uint = OpTypeVector %uint 2 + %v4float = OpTypeVector %float 4 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%gl_FragCoord = OpVariable %_ptr_Input_v4float Input + %v2float = OpTypeVector %float 2 +%_struct_1010 = OpTypeStruct %v2int %float +%_ptr_PushConstant__struct_1010 = OpTypePointer PushConstant %_struct_1010 + %3305 = OpVariable %_ptr_PushConstant__struct_1010 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_v2int = OpTypePointer PushConstant %v2int + %float_1 = OpConstant %float 1 + %float_0 = OpConstant %float 0 + %int_1 = OpConstant %int 1 +%_ptr_PushConstant_float = OpTypePointer PushConstant %float + %uint_1 = OpConstant %uint 1 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %5334 = OpVariable %_ptr_Output_v4float Output +%uint_532432441 = OpConstant %uint 532432441 +%uint_2129690299 = OpConstant %uint 2129690299 +%uint_2129764351 = OpConstant %uint 2129764351 + %float_2 = OpConstant %float 2 + %150 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_150 = OpTypePointer UniformConstant %150 + %5163 = OpVariable %_ptr_UniformConstant_150 UniformConstant + %int_n1 = OpConstant %int -1 + %1803 = OpConstantComposite %v2int %int_0 %int_n1 + %1806 = OpConstantComposite %v2int %int_n1 %int_0 + %1824 = OpConstantComposite %v2int %int_1 %int_0 + %1827 = OpConstantComposite %v2int %int_0 %int_1 + %float_4 = OpConstant %float 4 + %10264 = OpUndef %v4float + %5663 = OpFunction %void None %1282 + %24949 = OpLabel + %18571 = OpLoad %v4float %gl_FragCoord + %14008 = OpVectorShuffle %v2float %18571 %18571 0 1 + %17656 = OpConvertFToS %v2int %14008 + %19279 = OpAccessChain %_ptr_PushConstant_v2int %3305 %int_0 + %22822 = OpLoad %v2int %19279 + %23312 = OpISub %v2int %17656 %22822 + %9938 = OpBitcast %v2uint %23312 + %20997 = OpAccessChain %_ptr_PushConstant_float %3305 %int_1 + %22237 = OpLoad %float %20997 + %16454 = OpBitcast %uint %22237 + %6990 = OpBitcast %v2int %9938 + %14365 = OpIAdd %v2int %6990 %1803 + %23057 = OpLoad %150 %5163 + %19459 = OpImageFetch %v4float %23057 %14365 Lod %int_0 + %13347 = OpIAdd %v2int %6990 %1806 + %14538 = OpLoad %150 %5163 + %12625 = OpImageFetch %v4float %14538 %13347 Lod %int_0 + %10421 = OpLoad %150 %5163 + %15444 = OpImageFetch %v4float %10421 %6990 Lod %int_0 + %13348 = OpIAdd %v2int %6990 %1824 + %15811 = OpLoad %150 %5163 + %19460 = OpImageFetch %v4float %15811 %13348 Lod %int_0 + %13349 = OpIAdd %v2int %6990 %1827 + %14918 = OpLoad %150 %5163 + %8899 = OpImageFetch %v4float %14918 %13349 Lod %int_0 + %19729 = OpCompositeExtract %float %19459 0 + %7025 = OpCompositeExtract %float %19459 1 + %18723 = OpCompositeExtract %float %19459 2 + %24863 = OpFMul %float %19729 %19729 + %16184 = OpFMul %float %7025 %7025 + %9305 = OpFMul %float %18723 %18723 + %22236 = OpCompositeExtract %float %12625 0 + %11844 = OpCompositeExtract %float %12625 1 + %18724 = OpCompositeExtract %float %12625 2 + %24864 = OpFMul %float %22236 %22236 + %16185 = OpFMul %float %11844 %11844 + %9306 = OpFMul %float %18724 %18724 + %22238 = OpCompositeExtract %float %15444 0 + %11845 = OpCompositeExtract %float %15444 1 + %18725 = OpCompositeExtract %float %15444 2 + %24865 = OpFMul %float %22238 %22238 + %16186 = OpFMul %float %11845 %11845 + %9307 = OpFMul %float %18725 %18725 + %22239 = OpCompositeExtract %float %19460 0 + %11846 = OpCompositeExtract %float %19460 1 + %18726 = OpCompositeExtract %float %19460 2 + %24866 = OpFMul %float %22239 %22239 + %16187 = OpFMul %float %11846 %11846 + %9308 = OpFMul %float %18726 %18726 + %22240 = OpCompositeExtract %float %8899 0 + %11847 = OpCompositeExtract %float %8899 1 + %18727 = OpCompositeExtract %float %8899 2 + %24867 = OpFMul %float %22240 %22240 + %14910 = OpFMul %float %11847 %11847 + %8590 = OpFMul %float %18727 %18727 + %10877 = OpExtInst %float %1 FMin %16186 %16187 + %9276 = OpExtInst %float %1 FMin %16185 %10877 + %15951 = OpExtInst %float %1 FMin %16184 %14910 + %10905 = OpExtInst %float %1 FMin %9276 %15951 + %24296 = OpExtInst %float %1 FMax %16186 %16187 + %17523 = OpExtInst %float %1 FMax %16185 %24296 + %23939 = OpExtInst %float %1 FMax %16184 %14910 + %21101 = OpExtInst %float %1 FMax %17523 %23939 + %8181 = OpBitcast %uint %21101 + %8951 = OpISub %uint %uint_2129690299 %8181 + %6465 = OpBitcast %float %8951 + %24131 = OpFSub %float %float_1 %21101 + %23324 = OpExtInst %float %1 FMin %10905 %24131 + %22903 = OpFMul %float %23324 %6465 + %20683 = OpExtInst %float %1 FClamp %22903 %float_0 %float_1 + %24011 = OpBitcast %uint %20683 + %22090 = OpShiftRightLogical %uint %24011 %uint_1 + %23229 = OpIAdd %uint %22090 %uint_532432441 + %21692 = OpBitcast %float %23229 + %19558 = OpBitcast %float %16454 + %18803 = OpFMul %float %21692 %19558 + %23316 = OpFMul %float %float_4 %18803 + %16498 = OpFAdd %float %float_1 %23316 + %6551 = OpBitcast %uint %16498 + %7563 = OpISub %uint %uint_2129764351 %6551 + %9419 = OpBitcast %float %7563 + %9130 = OpFNegate %float %9419 + %12367 = OpFMul %float %9130 %16498 + %16540 = OpFAdd %float %12367 %float_2 + %9366 = OpFMul %float %9419 %16540 + %18845 = OpFAdd %float %24863 %24864 + %23143 = OpFAdd %float %18845 %24866 + %6535 = OpFAdd %float %23143 %24867 + %12673 = OpFMul %float %18803 %6535 + %15973 = OpFAdd %float %12673 %24865 + %8137 = OpFMul %float %15973 %9366 + %15142 = OpExtInst %float %1 FClamp %8137 %float_0 %float_1 + %13381 = OpFAdd %float %16184 %16185 + %12943 = OpFAdd %float %13381 %16187 + %6536 = OpFAdd %float %12943 %14910 + %12674 = OpFMul %float %18803 %6536 + %15974 = OpFAdd %float %12674 %16186 + %8138 = OpFMul %float %15974 %9366 + %15143 = OpExtInst %float %1 FClamp %8138 %float_0 %float_1 + %13382 = OpFAdd %float %9305 %9306 + %12944 = OpFAdd %float %13382 %9308 + %6537 = OpFAdd %float %12944 %8590 + %12675 = OpFMul %float %18803 %6537 + %15975 = OpFAdd %float %12675 %9307 + %7244 = OpFMul %float %15975 %9366 + %22380 = OpExtInst %float %1 FClamp %7244 %float_0 %float_1 + %24270 = OpCompositeInsert %v4float %15142 %10264 0 + %11074 = OpCompositeInsert %v4float %15143 %24270 1 + %14933 = OpCompositeInsert %v4float %22380 %11074 2 + %12955 = OpVectorShuffle %v3float %14933 %14933 0 1 2 + %6452 = OpExtInst %v3float %1 Sqrt %12955 + %22915 = OpCompositeExtract %float %6452 0 + %8853 = OpCompositeExtract %float %6452 1 + %7472 = OpCompositeExtract %float %6452 2 + %22408 = OpCompositeConstruct %v4float %22915 %8853 %7472 %float_1 + OpStore %5334 %22408 + OpReturn + OpFunctionEnd +#endif + +const uint32_t guest_output_ffx_cas_sharpen_ps[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006176, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0007000F, 0x00000004, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000C93, 0x000014D6, 0x00030010, + 0x0000161F, 0x00000007, 0x00040047, 0x00000C93, 0x0000000B, 0x0000000F, 0x00030047, 0x000003F2, + 0x00000002, 0x00050048, 0x000003F2, 0x00000000, 0x00000023, 0x00000010, 0x00050048, 0x000003F2, + 0x00000001, 0x00000023, 0x00000018, 0x00040047, 0x000014D6, 0x0000001E, 0x00000000, 0x00040047, + 0x0000142B, 0x00000021, 0x00000000, 0x00040047, 0x0000142B, 0x00000022, 0x00000000, 0x00020013, + 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00030016, 0x0000000D, 0x00000020, 0x00040015, + 0x0000000B, 0x00000020, 0x00000000, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, + 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x00000018, 0x0000000D, 0x00000003, 0x00040017, + 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x00040020, + 0x0000029A, 0x00000001, 0x0000001D, 0x0004003B, 0x0000029A, 0x00000C93, 0x00000001, 0x00040017, + 0x00000013, 0x0000000D, 0x00000002, 0x0004001E, 0x000003F2, 0x00000012, 0x0000000D, 0x00040020, + 0x0000066F, 0x00000009, 0x000003F2, 0x0004003B, 0x0000066F, 0x00000CE9, 0x00000009, 0x0004002B, + 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x0000028F, 0x00000009, 0x00000012, 0x0004002B, + 0x0000000D, 0x0000008A, 0x3F800000, 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, 0x0004002B, + 0x0000000C, 0x00000A0E, 0x00000001, 0x00040020, 0x0000028A, 0x00000009, 0x0000000D, 0x0004002B, + 0x0000000B, 0x00000A0D, 0x00000001, 0x00040020, 0x0000029B, 0x00000003, 0x0000001D, 0x0004003B, + 0x0000029B, 0x000014D6, 0x00000003, 0x0004002B, 0x0000000B, 0x0000020D, 0x1FBC4639, 0x0004002B, + 0x0000000B, 0x00000344, 0x7EF07EBB, 0x0004002B, 0x0000000B, 0x000000B2, 0x7EF19FFF, 0x0004002B, + 0x0000000D, 0x00000019, 0x40000000, 0x00090019, 0x00000096, 0x0000000D, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00040020, 0x00000313, 0x00000000, 0x00000096, + 0x0004003B, 0x00000313, 0x0000142B, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A08, 0xFFFFFFFF, + 0x0005002C, 0x00000012, 0x0000070B, 0x00000A0B, 0x00000A08, 0x0005002C, 0x00000012, 0x0000070E, + 0x00000A08, 0x00000A0B, 0x0005002C, 0x00000012, 0x00000720, 0x00000A0E, 0x00000A0B, 0x0005002C, + 0x00000012, 0x00000723, 0x00000A0B, 0x00000A0E, 0x0004002B, 0x0000000D, 0x00000B69, 0x40800000, + 0x00030001, 0x0000001D, 0x00002818, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, + 0x000200F8, 0x00006175, 0x0004003D, 0x0000001D, 0x0000488B, 0x00000C93, 0x0007004F, 0x00000013, + 0x000036B8, 0x0000488B, 0x0000488B, 0x00000000, 0x00000001, 0x0004006E, 0x00000012, 0x000044F8, + 0x000036B8, 0x00050041, 0x0000028F, 0x00004B4F, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x00000012, + 0x00005926, 0x00004B4F, 0x00050082, 0x00000012, 0x00005B10, 0x000044F8, 0x00005926, 0x0004007C, + 0x00000011, 0x000026D2, 0x00005B10, 0x00050041, 0x0000028A, 0x00005205, 0x00000CE9, 0x00000A0E, + 0x0004003D, 0x0000000D, 0x000056DD, 0x00005205, 0x0004007C, 0x0000000B, 0x00004046, 0x000056DD, + 0x0004007C, 0x00000012, 0x00001B4E, 0x000026D2, 0x00050080, 0x00000012, 0x0000381D, 0x00001B4E, + 0x0000070B, 0x0004003D, 0x00000096, 0x00005A11, 0x0000142B, 0x0007005F, 0x0000001D, 0x00004C03, + 0x00005A11, 0x0000381D, 0x00000002, 0x00000A0B, 0x00050080, 0x00000012, 0x00003423, 0x00001B4E, + 0x0000070E, 0x0004003D, 0x00000096, 0x000038CA, 0x0000142B, 0x0007005F, 0x0000001D, 0x00003151, + 0x000038CA, 0x00003423, 0x00000002, 0x00000A0B, 0x0004003D, 0x00000096, 0x000028B5, 0x0000142B, + 0x0007005F, 0x0000001D, 0x00003C54, 0x000028B5, 0x00001B4E, 0x00000002, 0x00000A0B, 0x00050080, + 0x00000012, 0x00003424, 0x00001B4E, 0x00000720, 0x0004003D, 0x00000096, 0x00003DC3, 0x0000142B, + 0x0007005F, 0x0000001D, 0x00004C04, 0x00003DC3, 0x00003424, 0x00000002, 0x00000A0B, 0x00050080, + 0x00000012, 0x00003425, 0x00001B4E, 0x00000723, 0x0004003D, 0x00000096, 0x00003A46, 0x0000142B, + 0x0007005F, 0x0000001D, 0x000022C3, 0x00003A46, 0x00003425, 0x00000002, 0x00000A0B, 0x00050051, + 0x0000000D, 0x00004D11, 0x00004C03, 0x00000000, 0x00050051, 0x0000000D, 0x00001B71, 0x00004C03, + 0x00000001, 0x00050051, 0x0000000D, 0x00004923, 0x00004C03, 0x00000002, 0x00050085, 0x0000000D, + 0x0000611F, 0x00004D11, 0x00004D11, 0x00050085, 0x0000000D, 0x00003F38, 0x00001B71, 0x00001B71, + 0x00050085, 0x0000000D, 0x00002459, 0x00004923, 0x00004923, 0x00050051, 0x0000000D, 0x000056DC, + 0x00003151, 0x00000000, 0x00050051, 0x0000000D, 0x00002E44, 0x00003151, 0x00000001, 0x00050051, + 0x0000000D, 0x00004924, 0x00003151, 0x00000002, 0x00050085, 0x0000000D, 0x00006120, 0x000056DC, + 0x000056DC, 0x00050085, 0x0000000D, 0x00003F39, 0x00002E44, 0x00002E44, 0x00050085, 0x0000000D, + 0x0000245A, 0x00004924, 0x00004924, 0x00050051, 0x0000000D, 0x000056DE, 0x00003C54, 0x00000000, + 0x00050051, 0x0000000D, 0x00002E45, 0x00003C54, 0x00000001, 0x00050051, 0x0000000D, 0x00004925, + 0x00003C54, 0x00000002, 0x00050085, 0x0000000D, 0x00006121, 0x000056DE, 0x000056DE, 0x00050085, + 0x0000000D, 0x00003F3A, 0x00002E45, 0x00002E45, 0x00050085, 0x0000000D, 0x0000245B, 0x00004925, + 0x00004925, 0x00050051, 0x0000000D, 0x000056DF, 0x00004C04, 0x00000000, 0x00050051, 0x0000000D, + 0x00002E46, 0x00004C04, 0x00000001, 0x00050051, 0x0000000D, 0x00004926, 0x00004C04, 0x00000002, + 0x00050085, 0x0000000D, 0x00006122, 0x000056DF, 0x000056DF, 0x00050085, 0x0000000D, 0x00003F3B, + 0x00002E46, 0x00002E46, 0x00050085, 0x0000000D, 0x0000245C, 0x00004926, 0x00004926, 0x00050051, + 0x0000000D, 0x000056E0, 0x000022C3, 0x00000000, 0x00050051, 0x0000000D, 0x00002E47, 0x000022C3, + 0x00000001, 0x00050051, 0x0000000D, 0x00004927, 0x000022C3, 0x00000002, 0x00050085, 0x0000000D, + 0x00006123, 0x000056E0, 0x000056E0, 0x00050085, 0x0000000D, 0x00003A3E, 0x00002E47, 0x00002E47, + 0x00050085, 0x0000000D, 0x0000218E, 0x00004927, 0x00004927, 0x0007000C, 0x0000000D, 0x00002A7D, + 0x00000001, 0x00000025, 0x00003F3A, 0x00003F3B, 0x0007000C, 0x0000000D, 0x0000243C, 0x00000001, + 0x00000025, 0x00003F39, 0x00002A7D, 0x0007000C, 0x0000000D, 0x00003E4F, 0x00000001, 0x00000025, + 0x00003F38, 0x00003A3E, 0x0007000C, 0x0000000D, 0x00002A99, 0x00000001, 0x00000025, 0x0000243C, + 0x00003E4F, 0x0007000C, 0x0000000D, 0x00005EE8, 0x00000001, 0x00000028, 0x00003F3A, 0x00003F3B, + 0x0007000C, 0x0000000D, 0x00004473, 0x00000001, 0x00000028, 0x00003F39, 0x00005EE8, 0x0007000C, + 0x0000000D, 0x00005D83, 0x00000001, 0x00000028, 0x00003F38, 0x00003A3E, 0x0007000C, 0x0000000D, + 0x0000526D, 0x00000001, 0x00000028, 0x00004473, 0x00005D83, 0x0004007C, 0x0000000B, 0x00001FF5, + 0x0000526D, 0x00050082, 0x0000000B, 0x000022F7, 0x00000344, 0x00001FF5, 0x0004007C, 0x0000000D, + 0x00001941, 0x000022F7, 0x00050083, 0x0000000D, 0x00005E43, 0x0000008A, 0x0000526D, 0x0007000C, + 0x0000000D, 0x00005B1C, 0x00000001, 0x00000025, 0x00002A99, 0x00005E43, 0x00050085, 0x0000000D, + 0x00005977, 0x00005B1C, 0x00001941, 0x0008000C, 0x0000000D, 0x000050CB, 0x00000001, 0x0000002B, + 0x00005977, 0x00000A0C, 0x0000008A, 0x0004007C, 0x0000000B, 0x00005DCB, 0x000050CB, 0x000500C2, + 0x0000000B, 0x0000564A, 0x00005DCB, 0x00000A0D, 0x00050080, 0x0000000B, 0x00005ABD, 0x0000564A, + 0x0000020D, 0x0004007C, 0x0000000D, 0x000054BC, 0x00005ABD, 0x0004007C, 0x0000000D, 0x00004C66, + 0x00004046, 0x00050085, 0x0000000D, 0x00004973, 0x000054BC, 0x00004C66, 0x00050085, 0x0000000D, + 0x00005B14, 0x00000B69, 0x00004973, 0x00050081, 0x0000000D, 0x00004072, 0x0000008A, 0x00005B14, + 0x0004007C, 0x0000000B, 0x00001997, 0x00004072, 0x00050082, 0x0000000B, 0x00001D8B, 0x000000B2, + 0x00001997, 0x0004007C, 0x0000000D, 0x000024CB, 0x00001D8B, 0x0004007F, 0x0000000D, 0x000023AA, + 0x000024CB, 0x00050085, 0x0000000D, 0x0000304F, 0x000023AA, 0x00004072, 0x00050081, 0x0000000D, + 0x0000409C, 0x0000304F, 0x00000019, 0x00050085, 0x0000000D, 0x00002496, 0x000024CB, 0x0000409C, + 0x00050081, 0x0000000D, 0x0000499D, 0x0000611F, 0x00006120, 0x00050081, 0x0000000D, 0x00005A67, + 0x0000499D, 0x00006122, 0x00050081, 0x0000000D, 0x00001987, 0x00005A67, 0x00006123, 0x00050085, + 0x0000000D, 0x00003181, 0x00004973, 0x00001987, 0x00050081, 0x0000000D, 0x00003E65, 0x00003181, + 0x00006121, 0x00050085, 0x0000000D, 0x00001FC9, 0x00003E65, 0x00002496, 0x0008000C, 0x0000000D, + 0x00003B26, 0x00000001, 0x0000002B, 0x00001FC9, 0x00000A0C, 0x0000008A, 0x00050081, 0x0000000D, + 0x00003445, 0x00003F38, 0x00003F39, 0x00050081, 0x0000000D, 0x0000328F, 0x00003445, 0x00003F3B, + 0x00050081, 0x0000000D, 0x00001988, 0x0000328F, 0x00003A3E, 0x00050085, 0x0000000D, 0x00003182, + 0x00004973, 0x00001988, 0x00050081, 0x0000000D, 0x00003E66, 0x00003182, 0x00003F3A, 0x00050085, + 0x0000000D, 0x00001FCA, 0x00003E66, 0x00002496, 0x0008000C, 0x0000000D, 0x00003B27, 0x00000001, + 0x0000002B, 0x00001FCA, 0x00000A0C, 0x0000008A, 0x00050081, 0x0000000D, 0x00003446, 0x00002459, + 0x0000245A, 0x00050081, 0x0000000D, 0x00003290, 0x00003446, 0x0000245C, 0x00050081, 0x0000000D, + 0x00001989, 0x00003290, 0x0000218E, 0x00050085, 0x0000000D, 0x00003183, 0x00004973, 0x00001989, + 0x00050081, 0x0000000D, 0x00003E67, 0x00003183, 0x0000245B, 0x00050085, 0x0000000D, 0x00001C4C, + 0x00003E67, 0x00002496, 0x0008000C, 0x0000000D, 0x0000576C, 0x00000001, 0x0000002B, 0x00001C4C, + 0x00000A0C, 0x0000008A, 0x00060052, 0x0000001D, 0x00005ECE, 0x00003B26, 0x00002818, 0x00000000, + 0x00060052, 0x0000001D, 0x00002B42, 0x00003B27, 0x00005ECE, 0x00000001, 0x00060052, 0x0000001D, + 0x00003A55, 0x0000576C, 0x00002B42, 0x00000002, 0x0008004F, 0x00000018, 0x0000329B, 0x00003A55, + 0x00003A55, 0x00000000, 0x00000001, 0x00000002, 0x0006000C, 0x00000018, 0x00001934, 0x00000001, + 0x0000001F, 0x0000329B, 0x00050051, 0x0000000D, 0x00005983, 0x00001934, 0x00000000, 0x00050051, + 0x0000000D, 0x00002295, 0x00001934, 0x00000001, 0x00050051, 0x0000000D, 0x00001D30, 0x00001934, + 0x00000002, 0x00070050, 0x0000001D, 0x00005788, 0x00005983, 0x00002295, 0x00001D30, 0x0000008A, + 0x0003003E, 0x000014D6, 0x00005788, 0x000100FD, 0x00010038, +}; diff --git a/src/ui/shaders/vulkan_spirv/guest_output_ffx_fsr_easu_ps.h b/src/ui/shaders/vulkan_spirv/guest_output_ffx_fsr_easu_ps.h new file mode 100644 index 0000000..354c5f3 --- /dev/null +++ b/src/ui/shaders/vulkan_spirv/guest_output_ffx_fsr_easu_ps.h @@ -0,0 +1,1309 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25264 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %5663 "main" %5777 %gl_FragCoord + OpExecutionMode %5663 OriginUpperLeft + OpDecorate %_struct_1030 Block + OpMemberDecorate %_struct_1030 0 Offset 16 + OpMemberDecorate %_struct_1030 1 Offset 24 + OpDecorate %5777 Location 0 + OpDecorate %gl_FragCoord BuiltIn FragCoord + OpDecorate %5056 Binding 0 + OpDecorate %5056 DescriptorSet 0 + OpDecorate %4091 Binding 1 + OpDecorate %4091 DescriptorSet 0 + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 + %v3float = OpTypeVector %float 3 + %v4float = OpTypeVector %float 4 + %uint = OpTypeInt 32 0 + %bool = OpTypeBool + %v2uint = OpTypeVector %uint 2 + %v4uint = OpTypeVector %uint 4 +%_struct_1030 = OpTypeStruct %v2float %v2float +%_ptr_PushConstant__struct_1030 = OpTypePointer PushConstant %_struct_1030 + %3305 = OpVariable %_ptr_PushConstant__struct_1030 PushConstant + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_v2float = OpTypePointer PushConstant %v2float + %float_0_5 = OpConstant %float 0.5 + %float_1 = OpConstant %float 1 + %float_n1 = OpConstant %float -1 + %1284 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_n1 + %int_1 = OpConstant %int 1 + %float_2 = OpConstant %float 2 + %2460 = OpConstantComposite %v4float %float_n1 %float_2 %float_1 %float_2 + %float_0 = OpConstant %float 0 + %float_4 = OpConstant %float 4 + %uint_1 = OpConstant %uint 1 +%_ptr_PushConstant_float = OpTypePointer PushConstant %float + %uint_0 = OpConstant %uint 0 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %5777 = OpVariable %_ptr_Output_v4float Output +%_ptr_Input_v4float = OpTypePointer Input %v4float +%gl_FragCoord = OpVariable %_ptr_Input_v4float Input +%_ptr_Output_float = OpTypePointer Output %float + %uint_2 = OpConstant %uint 2 + %uint_3 = OpConstant %uint 3 +%uint_2129690299 = OpConstant %uint 2129690299 +%uint_1597275508 = OpConstant %uint 1597275508 + %150 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_150 = OpTypePointer UniformConstant %150 + %5056 = OpVariable %_ptr_UniformConstant_150 UniformConstant + %508 = OpTypeSampler +%_ptr_UniformConstant_508 = OpTypePointer UniformConstant %508 + %4091 = OpVariable %_ptr_UniformConstant_508 UniformConstant + %510 = OpTypeSampledImage %150 + %int_2 = OpConstant %int 2 +%float_0_400000006 = OpConstant %float 0.400000006 +%float_1_5625 = OpConstant %float 1.5625 +%float_n0_5625 = OpConstant %float -0.5625 +%float_3_05175781en05 = OpConstant %float 3.05175781e-05 + %float_n0_5 = OpConstant %float -0.5 +%float_n0_289999992 = OpConstant %float -0.289999992 + %889 = OpConstantComposite %v2float %float_0 %float_n1 + %768 = OpConstantComposite %v2float %float_1 %float_n1 + %73 = OpConstantComposite %v2float %float_n1 %float_1 + %890 = OpConstantComposite %v2float %float_0 %float_1 + %2628 = OpConstantComposite %v2float %float_n1 %float_0 + %769 = OpConstantComposite %v2float %float_1 %float_1 + %426 = OpConstantComposite %v2float %float_2 %float_1 + %2981 = OpConstantComposite %v2float %float_2 %float_0 + %312 = OpConstantComposite %v2float %float_1 %float_0 + %313 = OpConstantComposite %v2float %float_1 %float_2 + %1823 = OpConstantComposite %v2float %float_0 %float_2 + %1566 = OpConstantComposite %v2float %float_0_5 %float_0_5 + %325 = OpConstantComposite %v4float %float_0_5 %float_0_5 %float_0_5 %float_0_5 + %5663 = OpFunction %void None %1282 + %23915 = OpLabel + %8250 = OpAccessChain %_ptr_PushConstant_v2float %3305 %int_0 + %6959 = OpLoad %v2float %8250 + %13397 = OpBitcast %v2uint %6959 + %12762 = OpVectorTimesScalar %v2float %6959 %float_0_5 + %24595 = OpFSub %v2float %12762 %1566 + %17743 = OpBitcast %v2uint %24595 + %16707 = OpCompositeExtract %uint %13397 0 + %13283 = OpCompositeExtract %uint %13397 1 + %7641 = OpCompositeExtract %uint %17743 0 + %7529 = OpCompositeExtract %uint %17743 1 + %18241 = OpCompositeConstruct %v4uint %16707 %13283 %7641 %7529 + %8922 = OpAccessChain %_ptr_PushConstant_v2float %3305 %int_1 + %7921 = OpLoad %v2float %8922 + %8543 = OpVectorShuffle %v4float %7921 %7921 0 1 0 1 + %11088 = OpFMul %v4float %1284 %8543 + %12841 = OpBitcast %v4uint %11088 + %16717 = OpFMul %v4float %2460 %8543 + %11573 = OpBitcast %v4uint %16717 + %20359 = OpAccessChain %_ptr_PushConstant_float %3305 %int_1 %uint_1 + %20680 = OpLoad %float %20359 + %18089 = OpFMul %float %float_4 %20680 + %19210 = OpBitcast %uint %18089 + %10864 = OpCompositeConstruct %v4uint %uint_0 %19210 %uint_0 %uint_0 + %6631 = OpLoad %v4float %gl_FragCoord + %14879 = OpVectorShuffle %v2float %6631 %6631 0 1 + %18060 = OpConvertFToU %v2uint %14879 + %25263 = OpConvertUToF %v2float %18060 + %25101 = OpVectorShuffle %v2uint %18241 %18241 0 1 + %11576 = OpBitcast %v2float %25101 + %20814 = OpFMul %v2float %25263 %11576 + %8994 = OpVectorShuffle %v2uint %18241 %18241 2 3 + %11797 = OpBitcast %v2float %8994 + %20069 = OpFAdd %v2float %20814 %11797 + %12130 = OpExtInst %v2float %1 Floor %20069 + %21577 = OpFSub %v2float %20069 %12130 + %25184 = OpVectorShuffle %v2uint %12841 %12841 0 1 + %17214 = OpBitcast %v2float %25184 + %20815 = OpFMul %v2float %12130 %17214 + %8995 = OpVectorShuffle %v2uint %12841 %12841 2 3 + %13062 = OpBitcast %v2float %8995 + %15444 = OpFAdd %v2float %20815 %13062 + %16447 = OpVectorShuffle %v2uint %11573 %11573 0 1 + %16293 = OpBitcast %v2float %16447 + %15445 = OpFAdd %v2float %15444 %16293 + %16448 = OpVectorShuffle %v2uint %11573 %11573 2 3 + %16294 = OpBitcast %v2float %16448 + %15446 = OpFAdd %v2float %15444 %16294 + %16449 = OpVectorShuffle %v2uint %10864 %10864 0 1 + %15951 = OpBitcast %v2float %16449 + %17361 = OpFAdd %v2float %15444 %15951 + %21435 = OpLoad %150 %5056 + %17465 = OpLoad %508 %4091 + %10383 = OpSampledImage %510 %21435 %17465 + %10424 = OpImageGather %v4float %10383 %15444 %int_0 + %19276 = OpLoad %150 %5056 + %13450 = OpLoad %508 %4091 + %10384 = OpSampledImage %510 %19276 %13450 + %10425 = OpImageGather %v4float %10384 %15444 %int_1 + %19277 = OpLoad %150 %5056 + %13451 = OpLoad %508 %4091 + %10385 = OpSampledImage %510 %19277 %13451 + %10426 = OpImageGather %v4float %10385 %15444 %int_2 + %19278 = OpLoad %150 %5056 + %13452 = OpLoad %508 %4091 + %10386 = OpSampledImage %510 %19278 %13452 + %10427 = OpImageGather %v4float %10386 %15445 %int_0 + %19279 = OpLoad %150 %5056 + %13453 = OpLoad %508 %4091 + %10387 = OpSampledImage %510 %19279 %13453 + %10428 = OpImageGather %v4float %10387 %15445 %int_1 + %19280 = OpLoad %150 %5056 + %13454 = OpLoad %508 %4091 + %10388 = OpSampledImage %510 %19280 %13454 + %10429 = OpImageGather %v4float %10388 %15445 %int_2 + %19281 = OpLoad %150 %5056 + %13455 = OpLoad %508 %4091 + %10389 = OpSampledImage %510 %19281 %13455 + %10430 = OpImageGather %v4float %10389 %15446 %int_0 + %19282 = OpLoad %150 %5056 + %13456 = OpLoad %508 %4091 + %10390 = OpSampledImage %510 %19282 %13456 + %10431 = OpImageGather %v4float %10390 %15446 %int_1 + %19283 = OpLoad %150 %5056 + %13457 = OpLoad %508 %4091 + %10391 = OpSampledImage %510 %19283 %13457 + %10432 = OpImageGather %v4float %10391 %15446 %int_2 + %19284 = OpLoad %150 %5056 + %13458 = OpLoad %508 %4091 + %10392 = OpSampledImage %510 %19284 %13458 + %10433 = OpImageGather %v4float %10392 %17361 %int_0 + %19285 = OpLoad %150 %5056 + %13459 = OpLoad %508 %4091 + %10393 = OpSampledImage %510 %19285 %13459 + %10434 = OpImageGather %v4float %10393 %17361 %int_1 + %19286 = OpLoad %150 %5056 + %13460 = OpLoad %508 %4091 + %11751 = OpSampledImage %510 %19286 %13460 + %18407 = OpImageGather %v4float %11751 %17361 %int_2 + %21556 = OpFMul %v4float %10426 %325 + %20200 = OpFMul %v4float %10424 %325 + %15690 = OpFAdd %v4float %20200 %10425 + %22451 = OpFAdd %v4float %21556 %15690 + %11905 = OpFMul %v4float %10429 %325 + %24215 = OpFMul %v4float %10427 %325 + %15691 = OpFAdd %v4float %24215 %10428 + %22452 = OpFAdd %v4float %11905 %15691 + %11906 = OpFMul %v4float %10432 %325 + %24216 = OpFMul %v4float %10430 %325 + %15692 = OpFAdd %v4float %24216 %10431 + %22453 = OpFAdd %v4float %11906 %15692 + %11907 = OpFMul %v4float %18407 %325 + %24217 = OpFMul %v4float %10433 %325 + %14702 = OpFAdd %v4float %24217 %10434 + %11388 = OpFAdd %v4float %11907 %14702 + %7392 = OpCompositeExtract %float %22451 0 + %14087 = OpCompositeExtract %float %22451 1 + %7660 = OpCompositeExtract %float %22452 0 + %7661 = OpCompositeExtract %float %22452 1 + %7662 = OpCompositeExtract %float %22452 2 + %7663 = OpCompositeExtract %float %22452 3 + %7664 = OpCompositeExtract %float %22453 0 + %7665 = OpCompositeExtract %float %22453 1 + %7666 = OpCompositeExtract %float %22453 2 + %7667 = OpCompositeExtract %float %22453 3 + %7668 = OpCompositeExtract %float %11388 2 + %8610 = OpCompositeExtract %float %11388 3 + %18081 = OpCompositeExtract %float %21577 0 + %12065 = OpFSub %float %float_1 %18081 + %11876 = OpCompositeExtract %float %21577 1 + %11109 = OpFSub %float %float_1 %11876 + %17978 = OpFMul %float %12065 %11109 + %20578 = OpFSub %float %7667 %7662 + %11120 = OpFSub %float %7662 %7663 + %6568 = OpExtInst %float %1 FAbs %20578 + %13751 = OpExtInst %float %1 FAbs %11120 + %18456 = OpExtInst %float %1 FMax %6568 %13751 + %7301 = OpBitcast %uint %18456 + %8951 = OpISub %uint %uint_2129690299 %7301 + %8727 = OpBitcast %float %8951 + %12281 = OpFSub %float %7667 %7663 + %12070 = OpFMul %float %12281 %17978 + %17296 = OpExtInst %float %1 FAbs %12281 + %16149 = OpFMul %float %17296 %8727 + %21377 = OpExtInst %float %1 FClamp %16149 %float_0 %float_1 + %18443 = OpFMul %float %21377 %21377 + %24605 = OpFSub %float %7661 %7662 + %11121 = OpFSub %float %7662 %7392 + %6569 = OpExtInst %float %1 FAbs %24605 + %13752 = OpExtInst %float %1 FAbs %11121 + %18457 = OpExtInst %float %1 FMax %6569 %13752 + %7302 = OpBitcast %uint %18457 + %8952 = OpISub %uint %uint_2129690299 %7302 + %8728 = OpBitcast %float %8952 + %12282 = OpFSub %float %7661 %7392 + %12071 = OpFMul %float %12282 %17978 + %17297 = OpExtInst %float %1 FAbs %12282 + %16150 = OpFMul %float %17297 %8728 + %21339 = OpExtInst %float %1 FClamp %16150 %float_0 %float_1 + %18827 = OpFMul %float %21339 %21339 + %23869 = OpFAdd %float %18443 %18827 + %8712 = OpFMul %float %17978 %23869 + %21650 = OpFMul %float %18081 %11109 + %23272 = OpFSub %float %7666 %7667 + %6930 = OpExtInst %float %1 FAbs %23272 + %13180 = OpExtInst %float %1 FMax %6930 %6568 + %7303 = OpBitcast %uint %13180 + %8953 = OpISub %uint %uint_2129690299 %7303 + %8729 = OpBitcast %float %8953 + %14500 = OpFSub %float %7666 %7662 + %21690 = OpFMul %float %14500 %21650 + %8619 = OpFAdd %float %12070 %21690 + %7291 = OpExtInst %float %1 FAbs %14500 + %12923 = OpFMul %float %7291 %8729 + %21415 = OpExtInst %float %1 FClamp %12923 %float_0 %float_1 + %18059 = OpFMul %float %21415 %21415 + %10822 = OpFMul %float %18059 %21650 + %15306 = OpFAdd %float %8712 %10822 + %23187 = OpFSub %float %7664 %7667 + %7894 = OpFSub %float %7667 %14087 + %6570 = OpExtInst %float %1 FAbs %23187 + %13753 = OpExtInst %float %1 FAbs %7894 + %18458 = OpExtInst %float %1 FMax %6570 %13753 + %7304 = OpBitcast %uint %18458 + %8954 = OpISub %uint %uint_2129690299 %7304 + %8730 = OpBitcast %float %8954 + %14501 = OpFSub %float %7664 %14087 + %21691 = OpFMul %float %14501 %21650 + %8620 = OpFAdd %float %12071 %21691 + %7292 = OpExtInst %float %1 FAbs %14501 + %12924 = OpFMul %float %7292 %8730 + %21416 = OpExtInst %float %1 FClamp %12924 %float_0 %float_1 + %18061 = OpFMul %float %21416 %21416 + %10860 = OpFMul %float %18061 %21650 + %14960 = OpFAdd %float %15306 %10860 + %9058 = OpFMul %float %12065 %11876 + %18965 = OpFSub %float %7664 %7661 + %11122 = OpFSub %float %7661 %7660 + %6571 = OpExtInst %float %1 FAbs %18965 + %13754 = OpExtInst %float %1 FAbs %11122 + %18459 = OpExtInst %float %1 FMax %6571 %13754 + %7305 = OpBitcast %uint %18459 + %8955 = OpISub %uint %uint_2129690299 %7305 + %8731 = OpBitcast %float %8955 + %14502 = OpFSub %float %7664 %7660 + %21692 = OpFMul %float %14502 %9058 + %8621 = OpFAdd %float %8619 %21692 + %7293 = OpExtInst %float %1 FAbs %14502 + %12925 = OpFMul %float %7293 %8731 + %21417 = OpExtInst %float %1 FClamp %12925 %float_0 %float_1 + %18062 = OpFMul %float %21417 %21417 + %10823 = OpFMul %float %18062 %9058 + %13049 = OpFAdd %float %14960 %10823 + %11654 = OpFSub %float %8610 %7661 + %10161 = OpExtInst %float %1 FAbs %11654 + %13181 = OpExtInst %float %1 FMax %10161 %6569 + %7306 = OpBitcast %uint %13181 + %8956 = OpISub %uint %uint_2129690299 %7306 + %8732 = OpBitcast %float %8956 + %14503 = OpFSub %float %8610 %7662 + %21693 = OpFMul %float %14503 %9058 + %8622 = OpFAdd %float %8620 %21693 + %7294 = OpExtInst %float %1 FAbs %14503 + %12926 = OpFMul %float %7294 %8732 + %21418 = OpExtInst %float %1 FClamp %12926 %float_0 %float_1 + %18063 = OpFMul %float %21418 %21418 + %10861 = OpFMul %float %18063 %9058 + %14961 = OpFAdd %float %13049 %10861 + %6801 = OpFMul %float %18081 %11876 + %7432 = OpFSub %float %7665 %7664 + %6931 = OpExtInst %float %1 FAbs %7432 + %13182 = OpExtInst %float %1 FMax %6931 %6571 + %7307 = OpBitcast %uint %13182 + %8957 = OpISub %uint %uint_2129690299 %7307 + %8733 = OpBitcast %float %8957 + %14504 = OpFSub %float %7665 %7661 + %21694 = OpFMul %float %14504 %6801 + %8623 = OpFAdd %float %8621 %21694 + %7295 = OpExtInst %float %1 FAbs %14504 + %12927 = OpFMul %float %7295 %8733 + %21419 = OpExtInst %float %1 FClamp %12927 %float_0 %float_1 + %18064 = OpFMul %float %21419 %21419 + %10824 = OpFMul %float %18064 %6801 + %13050 = OpFAdd %float %14961 %10824 + %11655 = OpFSub %float %7668 %7664 + %10162 = OpExtInst %float %1 FAbs %11655 + %13183 = OpExtInst %float %1 FMax %10162 %6570 + %7308 = OpBitcast %uint %13183 + %8958 = OpISub %uint %uint_2129690299 %7308 + %8734 = OpBitcast %float %8958 + %14505 = OpFSub %float %7668 %7667 + %22978 = OpFMul %float %14505 %6801 + %7645 = OpFAdd %float %8622 %22978 + %18651 = OpCompositeConstruct %v2float %8623 %7645 + %11009 = OpExtInst %float %1 FAbs %14505 + %8918 = OpFMul %float %11009 %8734 + %21420 = OpExtInst %float %1 FClamp %8918 %float_0 %float_1 + %18065 = OpFMul %float %21420 %21420 + %10862 = OpFMul %float %18065 %6801 + %14010 = OpFAdd %float %13050 %10862 + %16758 = OpFMul %v2float %18651 %18651 + %19922 = OpCompositeExtract %float %16758 0 + %23580 = OpCompositeExtract %float %16758 1 + %10499 = OpFAdd %float %19922 %23580 + %22603 = OpFOrdLessThan %bool %10499 %float_3_05175781en05 + %22071 = OpBitcast %uint %10499 + %18491 = OpShiftRightLogical %uint %22071 %uint_1 + %20312 = OpISub %uint %uint_1597275508 %18491 + %7636 = OpBitcast %float %20312 + %20252 = OpSelect %float %22603 %float_1 %7636 + %18321 = OpSelect %float %22603 %float_1 %8623 + %15003 = OpCompositeInsert %v2float %18321 %18651 0 + %13998 = OpCompositeConstruct %v2float %20252 %20252 + %10076 = OpFMul %v2float %15003 %13998 + %12149 = OpFMul %float %14010 %float_0_5 + %10293 = OpFMul %float %12149 %12149 + %13240 = OpCompositeExtract %float %10076 0 + %24441 = OpFMul %float %13240 %13240 + %23570 = OpCompositeExtract %float %10076 1 + %13842 = OpFMul %float %23570 %23570 + %17355 = OpFAdd %float %24441 %13842 + %15136 = OpExtInst %float %1 FAbs %13240 + %18595 = OpExtInst %float %1 FAbs %23570 + %18460 = OpExtInst %float %1 FMax %15136 %18595 + %7309 = OpBitcast %uint %18460 + %8989 = OpISub %uint %uint_2129690299 %7309 + %8343 = OpBitcast %float %8989 + %17607 = OpFMul %float %17355 %8343 + %20034 = OpFSub %float %17607 %float_1 + %8944 = OpFMul %float %20034 %10293 + %19766 = OpFAdd %float %float_1 %8944 + %8435 = OpFMul %float %float_n0_5 %10293 + %8327 = OpFAdd %float %float_1 %8435 + %10727 = OpCompositeConstruct %v2float %19766 %8327 + %19446 = OpFMul %float %float_n0_289999992 %10293 + %9267 = OpFAdd %float %float_0_5 %19446 + %6551 = OpBitcast %uint %9267 + %6689 = OpISub %uint %uint_2129690299 %6551 + %16389 = OpBitcast %float %6689 + %19129 = OpCompositeExtract %float %10427 2 + %13264 = OpCompositeExtract %float %10428 2 + %7833 = OpCompositeExtract %float %10429 2 + %15853 = OpCompositeConstruct %v3float %19129 %13264 %7833 + %7909 = OpCompositeExtract %float %10430 3 + %22677 = OpCompositeExtract %float %10431 3 + %7834 = OpCompositeExtract %float %10432 3 + %15854 = OpCompositeConstruct %v3float %7909 %22677 %7834 + %7910 = OpCompositeExtract %float %10427 1 + %22678 = OpCompositeExtract %float %10428 1 + %6559 = OpCompositeExtract %float %10429 1 + %15138 = OpCompositeConstruct %v3float %7910 %22678 %6559 + %16895 = OpExtInst %v3float %1 FMin %15854 %15138 + %21831 = OpExtInst %v3float %1 FMin %15853 %16895 + %8236 = OpCompositeExtract %float %10430 0 + %11052 = OpCompositeExtract %float %10431 0 + %6560 = OpCompositeExtract %float %10432 0 + %15141 = OpCompositeConstruct %v3float %8236 %11052 %6560 + %10578 = OpExtInst %v3float %1 FMin %21831 %15141 + %16850 = OpExtInst %v3float %1 FMax %15854 %15138 + %19744 = OpExtInst %v3float %1 FMax %15853 %16850 + %18959 = OpExtInst %v3float %1 FMax %19744 %15141 + %15703 = OpFSub %v2float %889 %21577 + %8206 = OpCompositeExtract %float %10424 0 + %15681 = OpCompositeExtract %float %10425 0 + %7835 = OpCompositeExtract %float %10426 0 + %16841 = OpCompositeConstruct %v3float %8206 %15681 %7835 + %17984 = OpCompositeExtract %float %15703 0 + %17210 = OpFMul %float %17984 %13240 + %23571 = OpCompositeExtract %float %15703 1 + %16023 = OpFMul %float %23571 %23570 + %12840 = OpFAdd %float %17210 %16023 + %19767 = OpFNegate %float %23570 + %12403 = OpFMul %float %17984 %19767 + %21671 = OpFMul %float %23571 %13240 + %24167 = OpFAdd %float %12403 %21671 + %9815 = OpCompositeConstruct %v2float %12840 %24167 + %8850 = OpFMul %v2float %9815 %10727 + %25080 = OpCompositeExtract %float %8850 0 + %24442 = OpFMul %float %25080 %25080 + %23572 = OpCompositeExtract %float %8850 1 + %13875 = OpFMul %float %23572 %23572 + %21357 = OpFAdd %float %24442 %13875 + %10961 = OpExtInst %float %1 FMin %21357 %16389 + %10077 = OpFMul %float %float_0_400000006 %10961 + %21594 = OpFAdd %float %10077 %float_n1 + %9442 = OpFMul %float %9267 %10961 + %18229 = OpFAdd %float %9442 %float_n1 + %8750 = OpFMul %float %21594 %21594 + %23523 = OpFMul %float %18229 %18229 + %21060 = OpFMul %float %float_1_5625 %8750 + %15169 = OpFAdd %float %21060 %float_n0_5625 + %7155 = OpFMul %float %15169 %23523 + %6433 = OpVectorTimesScalar %v3float %16841 %7155 + %10536 = OpFSub %v2float %768 %21577 + %7693 = OpCompositeExtract %float %10424 1 + %15682 = OpCompositeExtract %float %10425 1 + %7836 = OpCompositeExtract %float %10426 1 + %16842 = OpCompositeConstruct %v3float %7693 %15682 %7836 + %17985 = OpCompositeExtract %float %10536 0 + %17211 = OpFMul %float %17985 %13240 + %23573 = OpCompositeExtract %float %10536 1 + %16137 = OpFMul %float %23573 %23570 + %11802 = OpFAdd %float %17211 %16137 + %8674 = OpFMul %float %17985 %19767 + %23284 = OpFMul %float %23573 %13240 + %24168 = OpFAdd %float %8674 %23284 + %9816 = OpCompositeConstruct %v2float %11802 %24168 + %8851 = OpFMul %v2float %9816 %10727 + %25081 = OpCompositeExtract %float %8851 0 + %24443 = OpFMul %float %25081 %25081 + %23574 = OpCompositeExtract %float %8851 1 + %13876 = OpFMul %float %23574 %23574 + %21358 = OpFAdd %float %24443 %13876 + %10962 = OpExtInst %float %1 FMin %21358 %16389 + %10078 = OpFMul %float %float_0_400000006 %10962 + %21595 = OpFAdd %float %10078 %float_n1 + %9443 = OpFMul %float %9267 %10962 + %18230 = OpFAdd %float %9443 %float_n1 + %8751 = OpFMul %float %21595 %21595 + %23524 = OpFMul %float %18230 %18230 + %21061 = OpFMul %float %float_1_5625 %8751 + %15170 = OpFAdd %float %21061 %float_n0_5625 + %7117 = OpFMul %float %15170 %23524 + %7691 = OpVectorTimesScalar %v3float %16842 %7117 + %6954 = OpFAdd %v3float %6433 %7691 + %6768 = OpFAdd %float %7155 %7117 + %17304 = OpFSub %v2float %73 %21577 + %6894 = OpCompositeExtract %float %10427 0 + %15683 = OpCompositeExtract %float %10428 0 + %7837 = OpCompositeExtract %float %10429 0 + %16843 = OpCompositeConstruct %v3float %6894 %15683 %7837 + %17986 = OpCompositeExtract %float %17304 0 + %17212 = OpFMul %float %17986 %13240 + %23575 = OpCompositeExtract %float %17304 1 + %16138 = OpFMul %float %23575 %23570 + %11803 = OpFAdd %float %17212 %16138 + %8675 = OpFMul %float %17986 %19767 + %23285 = OpFMul %float %23575 %13240 + %24169 = OpFAdd %float %8675 %23285 + %9817 = OpCompositeConstruct %v2float %11803 %24169 + %8852 = OpFMul %v2float %9817 %10727 + %25082 = OpCompositeExtract %float %8852 0 + %24444 = OpFMul %float %25082 %25082 + %23576 = OpCompositeExtract %float %8852 1 + %13877 = OpFMul %float %23576 %23576 + %21359 = OpFAdd %float %24444 %13877 + %10963 = OpExtInst %float %1 FMin %21359 %16389 + %10079 = OpFMul %float %float_0_400000006 %10963 + %21596 = OpFAdd %float %10079 %float_n1 + %9444 = OpFMul %float %9267 %10963 + %18231 = OpFAdd %float %9444 %float_n1 + %8752 = OpFMul %float %21596 %21596 + %23525 = OpFMul %float %18231 %18231 + %21062 = OpFMul %float %float_1_5625 %8752 + %15171 = OpFAdd %float %21062 %float_n0_5625 + %7118 = OpFMul %float %15171 %23525 + %7692 = OpVectorTimesScalar %v3float %16843 %7118 + %6955 = OpFAdd %v3float %6954 %7692 + %6769 = OpFAdd %float %6768 %7118 + %18292 = OpFSub %v2float %890 %21577 + %16969 = OpCompositeExtract %float %18292 0 + %22828 = OpFMul %float %16969 %13240 + %23577 = OpCompositeExtract %float %18292 1 + %16139 = OpFMul %float %23577 %23570 + %11804 = OpFAdd %float %22828 %16139 + %8676 = OpFMul %float %16969 %19767 + %23286 = OpFMul %float %23577 %13240 + %24170 = OpFAdd %float %8676 %23286 + %9818 = OpCompositeConstruct %v2float %11804 %24170 + %8853 = OpFMul %v2float %9818 %10727 + %25083 = OpCompositeExtract %float %8853 0 + %24445 = OpFMul %float %25083 %25083 + %23578 = OpCompositeExtract %float %8853 1 + %13878 = OpFMul %float %23578 %23578 + %21360 = OpFAdd %float %24445 %13878 + %10964 = OpExtInst %float %1 FMin %21360 %16389 + %10080 = OpFMul %float %float_0_400000006 %10964 + %21597 = OpFAdd %float %10080 %float_n1 + %9445 = OpFMul %float %9267 %10964 + %18232 = OpFAdd %float %9445 %float_n1 + %8753 = OpFMul %float %21597 %21597 + %23526 = OpFMul %float %18232 %18232 + %21063 = OpFMul %float %float_1_5625 %8753 + %15172 = OpFAdd %float %21063 %float_n0_5625 + %7119 = OpFMul %float %15172 %23526 + %7694 = OpVectorTimesScalar %v3float %15138 %7119 + %6878 = OpFAdd %v3float %6955 %7694 + %7460 = OpFAdd %float %6769 %7119 + %12922 = OpFNegate %v2float %21577 + %24422 = OpCompositeExtract %float %12922 0 + %6988 = OpFMul %float %24422 %13240 + %23579 = OpCompositeExtract %float %12922 1 + %16140 = OpFMul %float %23579 %23570 + %11805 = OpFAdd %float %6988 %16140 + %8677 = OpFMul %float %24422 %19767 + %23287 = OpFMul %float %23579 %13240 + %24171 = OpFAdd %float %8677 %23287 + %9819 = OpCompositeConstruct %v2float %11805 %24171 + %8854 = OpFMul %v2float %9819 %10727 + %25084 = OpCompositeExtract %float %8854 0 + %24446 = OpFMul %float %25084 %25084 + %23581 = OpCompositeExtract %float %8854 1 + %13879 = OpFMul %float %23581 %23581 + %21361 = OpFAdd %float %24446 %13879 + %10965 = OpExtInst %float %1 FMin %21361 %16389 + %10081 = OpFMul %float %float_0_400000006 %10965 + %21598 = OpFAdd %float %10081 %float_n1 + %9446 = OpFMul %float %9267 %10965 + %18233 = OpFAdd %float %9446 %float_n1 + %8754 = OpFMul %float %21598 %21598 + %23527 = OpFMul %float %18233 %18233 + %21064 = OpFMul %float %float_1_5625 %8754 + %15173 = OpFAdd %float %21064 %float_n0_5625 + %7120 = OpFMul %float %15173 %23527 + %7695 = OpVectorTimesScalar %v3float %15853 %7120 + %6956 = OpFAdd %v3float %6878 %7695 + %6770 = OpFAdd %float %7460 %7120 + %17305 = OpFSub %v2float %2628 %21577 + %6895 = OpCompositeExtract %float %10427 3 + %15684 = OpCompositeExtract %float %10428 3 + %7838 = OpCompositeExtract %float %10429 3 + %16844 = OpCompositeConstruct %v3float %6895 %15684 %7838 + %17987 = OpCompositeExtract %float %17305 0 + %17213 = OpFMul %float %17987 %13240 + %23582 = OpCompositeExtract %float %17305 1 + %16141 = OpFMul %float %23582 %23570 + %11806 = OpFAdd %float %17213 %16141 + %8678 = OpFMul %float %17987 %19767 + %23288 = OpFMul %float %23582 %13240 + %24172 = OpFAdd %float %8678 %23288 + %9820 = OpCompositeConstruct %v2float %11806 %24172 + %8855 = OpFMul %v2float %9820 %10727 + %25085 = OpCompositeExtract %float %8855 0 + %24447 = OpFMul %float %25085 %25085 + %23583 = OpCompositeExtract %float %8855 1 + %13880 = OpFMul %float %23583 %23583 + %21362 = OpFAdd %float %24447 %13880 + %10966 = OpExtInst %float %1 FMin %21362 %16389 + %10082 = OpFMul %float %float_0_400000006 %10966 + %21599 = OpFAdd %float %10082 %float_n1 + %9447 = OpFMul %float %9267 %10966 + %18234 = OpFAdd %float %9447 %float_n1 + %8755 = OpFMul %float %21599 %21599 + %23528 = OpFMul %float %18234 %18234 + %21065 = OpFMul %float %float_1_5625 %8755 + %15174 = OpFAdd %float %21065 %float_n0_5625 + %7121 = OpFMul %float %15174 %23528 + %7696 = OpVectorTimesScalar %v3float %16844 %7121 + %6957 = OpFAdd %v3float %6956 %7696 + %6771 = OpFAdd %float %6770 %7121 + %18293 = OpFSub %v2float %769 %21577 + %16970 = OpCompositeExtract %float %18293 0 + %22829 = OpFMul %float %16970 %13240 + %23584 = OpCompositeExtract %float %18293 1 + %16142 = OpFMul %float %23584 %23570 + %11807 = OpFAdd %float %22829 %16142 + %8679 = OpFMul %float %16970 %19767 + %23289 = OpFMul %float %23584 %13240 + %24173 = OpFAdd %float %8679 %23289 + %9821 = OpCompositeConstruct %v2float %11807 %24173 + %8856 = OpFMul %v2float %9821 %10727 + %25086 = OpCompositeExtract %float %8856 0 + %24448 = OpFMul %float %25086 %25086 + %23585 = OpCompositeExtract %float %8856 1 + %13881 = OpFMul %float %23585 %23585 + %21363 = OpFAdd %float %24448 %13881 + %10967 = OpExtInst %float %1 FMin %21363 %16389 + %10083 = OpFMul %float %float_0_400000006 %10967 + %21600 = OpFAdd %float %10083 %float_n1 + %9448 = OpFMul %float %9267 %10967 + %18235 = OpFAdd %float %9448 %float_n1 + %8756 = OpFMul %float %21600 %21600 + %23529 = OpFMul %float %18235 %18235 + %21066 = OpFMul %float %float_1_5625 %8756 + %15175 = OpFAdd %float %21066 %float_n0_5625 + %7122 = OpFMul %float %15175 %23529 + %7697 = OpVectorTimesScalar %v3float %15141 %7122 + %6958 = OpFAdd %v3float %6957 %7697 + %6772 = OpFAdd %float %6771 %7122 + %17306 = OpFSub %v2float %426 %21577 + %6896 = OpCompositeExtract %float %10430 1 + %15685 = OpCompositeExtract %float %10431 1 + %7839 = OpCompositeExtract %float %10432 1 + %16845 = OpCompositeConstruct %v3float %6896 %15685 %7839 + %17988 = OpCompositeExtract %float %17306 0 + %17215 = OpFMul %float %17988 %13240 + %23586 = OpCompositeExtract %float %17306 1 + %16143 = OpFMul %float %23586 %23570 + %11808 = OpFAdd %float %17215 %16143 + %8680 = OpFMul %float %17988 %19767 + %23290 = OpFMul %float %23586 %13240 + %24174 = OpFAdd %float %8680 %23290 + %9822 = OpCompositeConstruct %v2float %11808 %24174 + %8857 = OpFMul %v2float %9822 %10727 + %25087 = OpCompositeExtract %float %8857 0 + %24449 = OpFMul %float %25087 %25087 + %23587 = OpCompositeExtract %float %8857 1 + %13882 = OpFMul %float %23587 %23587 + %21364 = OpFAdd %float %24449 %13882 + %10968 = OpExtInst %float %1 FMin %21364 %16389 + %10084 = OpFMul %float %float_0_400000006 %10968 + %21601 = OpFAdd %float %10084 %float_n1 + %9449 = OpFMul %float %9267 %10968 + %18236 = OpFAdd %float %9449 %float_n1 + %8757 = OpFMul %float %21601 %21601 + %23530 = OpFMul %float %18236 %18236 + %21067 = OpFMul %float %float_1_5625 %8757 + %15176 = OpFAdd %float %21067 %float_n0_5625 + %7123 = OpFMul %float %15176 %23530 + %7698 = OpVectorTimesScalar %v3float %16845 %7123 + %6960 = OpFAdd %v3float %6958 %7698 + %6773 = OpFAdd %float %6772 %7123 + %17307 = OpFSub %v2float %2981 %21577 + %6897 = OpCompositeExtract %float %10430 2 + %15686 = OpCompositeExtract %float %10431 2 + %7840 = OpCompositeExtract %float %10432 2 + %16846 = OpCompositeConstruct %v3float %6897 %15686 %7840 + %17989 = OpCompositeExtract %float %17307 0 + %17216 = OpFMul %float %17989 %13240 + %23588 = OpCompositeExtract %float %17307 1 + %16144 = OpFMul %float %23588 %23570 + %11809 = OpFAdd %float %17216 %16144 + %8681 = OpFMul %float %17989 %19767 + %23291 = OpFMul %float %23588 %13240 + %24175 = OpFAdd %float %8681 %23291 + %9823 = OpCompositeConstruct %v2float %11809 %24175 + %8858 = OpFMul %v2float %9823 %10727 + %25088 = OpCompositeExtract %float %8858 0 + %24450 = OpFMul %float %25088 %25088 + %23589 = OpCompositeExtract %float %8858 1 + %13883 = OpFMul %float %23589 %23589 + %21365 = OpFAdd %float %24450 %13883 + %10969 = OpExtInst %float %1 FMin %21365 %16389 + %10085 = OpFMul %float %float_0_400000006 %10969 + %21602 = OpFAdd %float %10085 %float_n1 + %9450 = OpFMul %float %9267 %10969 + %18237 = OpFAdd %float %9450 %float_n1 + %8758 = OpFMul %float %21602 %21602 + %23531 = OpFMul %float %18237 %18237 + %21068 = OpFMul %float %float_1_5625 %8758 + %15177 = OpFAdd %float %21068 %float_n0_5625 + %7124 = OpFMul %float %15177 %23531 + %7699 = OpVectorTimesScalar %v3float %16846 %7124 + %6961 = OpFAdd %v3float %6960 %7699 + %6774 = OpFAdd %float %6773 %7124 + %18294 = OpFSub %v2float %312 %21577 + %16971 = OpCompositeExtract %float %18294 0 + %22830 = OpFMul %float %16971 %13240 + %23590 = OpCompositeExtract %float %18294 1 + %16145 = OpFMul %float %23590 %23570 + %11810 = OpFAdd %float %22830 %16145 + %8682 = OpFMul %float %16971 %19767 + %23292 = OpFMul %float %23590 %13240 + %24176 = OpFAdd %float %8682 %23292 + %9824 = OpCompositeConstruct %v2float %11810 %24176 + %8859 = OpFMul %v2float %9824 %10727 + %25089 = OpCompositeExtract %float %8859 0 + %24451 = OpFMul %float %25089 %25089 + %23591 = OpCompositeExtract %float %8859 1 + %13884 = OpFMul %float %23591 %23591 + %21366 = OpFAdd %float %24451 %13884 + %10970 = OpExtInst %float %1 FMin %21366 %16389 + %10086 = OpFMul %float %float_0_400000006 %10970 + %21603 = OpFAdd %float %10086 %float_n1 + %9451 = OpFMul %float %9267 %10970 + %18238 = OpFAdd %float %9451 %float_n1 + %8759 = OpFMul %float %21603 %21603 + %23532 = OpFMul %float %18238 %18238 + %21069 = OpFMul %float %float_1_5625 %8759 + %15178 = OpFAdd %float %21069 %float_n0_5625 + %7125 = OpFMul %float %15178 %23532 + %7700 = OpVectorTimesScalar %v3float %15854 %7125 + %6962 = OpFAdd %v3float %6961 %7700 + %6775 = OpFAdd %float %6774 %7125 + %17308 = OpFSub %v2float %313 %21577 + %6898 = OpCompositeExtract %float %10433 2 + %15687 = OpCompositeExtract %float %10434 2 + %7841 = OpCompositeExtract %float %18407 2 + %16847 = OpCompositeConstruct %v3float %6898 %15687 %7841 + %17990 = OpCompositeExtract %float %17308 0 + %17217 = OpFMul %float %17990 %13240 + %23592 = OpCompositeExtract %float %17308 1 + %16146 = OpFMul %float %23592 %23570 + %11811 = OpFAdd %float %17217 %16146 + %8683 = OpFMul %float %17990 %19767 + %23293 = OpFMul %float %23592 %13240 + %24177 = OpFAdd %float %8683 %23293 + %9825 = OpCompositeConstruct %v2float %11811 %24177 + %8860 = OpFMul %v2float %9825 %10727 + %25090 = OpCompositeExtract %float %8860 0 + %24452 = OpFMul %float %25090 %25090 + %23593 = OpCompositeExtract %float %8860 1 + %13885 = OpFMul %float %23593 %23593 + %21367 = OpFAdd %float %24452 %13885 + %10971 = OpExtInst %float %1 FMin %21367 %16389 + %10087 = OpFMul %float %float_0_400000006 %10971 + %21604 = OpFAdd %float %10087 %float_n1 + %9452 = OpFMul %float %9267 %10971 + %18239 = OpFAdd %float %9452 %float_n1 + %8760 = OpFMul %float %21604 %21604 + %23533 = OpFMul %float %18239 %18239 + %21070 = OpFMul %float %float_1_5625 %8760 + %15179 = OpFAdd %float %21070 %float_n0_5625 + %7126 = OpFMul %float %15179 %23533 + %7701 = OpVectorTimesScalar %v3float %16847 %7126 + %6963 = OpFAdd %v3float %6962 %7701 + %6776 = OpFAdd %float %6775 %7126 + %17309 = OpFSub %v2float %1823 %21577 + %6899 = OpCompositeExtract %float %10433 3 + %15688 = OpCompositeExtract %float %10434 3 + %7842 = OpCompositeExtract %float %18407 3 + %16848 = OpCompositeConstruct %v3float %6899 %15688 %7842 + %17991 = OpCompositeExtract %float %17309 0 + %17218 = OpFMul %float %17991 %13240 + %23594 = OpCompositeExtract %float %17309 1 + %16147 = OpFMul %float %23594 %23570 + %11812 = OpFAdd %float %17218 %16147 + %8684 = OpFMul %float %17991 %19767 + %23294 = OpFMul %float %23594 %13240 + %24178 = OpFAdd %float %8684 %23294 + %9826 = OpCompositeConstruct %v2float %11812 %24178 + %8861 = OpFMul %v2float %9826 %10727 + %25091 = OpCompositeExtract %float %8861 0 + %24453 = OpFMul %float %25091 %25091 + %23595 = OpCompositeExtract %float %8861 1 + %13886 = OpFMul %float %23595 %23595 + %21368 = OpFAdd %float %24453 %13886 + %10972 = OpExtInst %float %1 FMin %21368 %16389 + %10088 = OpFMul %float %float_0_400000006 %10972 + %21605 = OpFAdd %float %10088 %float_n1 + %9453 = OpFMul %float %9267 %10972 + %18240 = OpFAdd %float %9453 %float_n1 + %8761 = OpFMul %float %21605 %21605 + %23534 = OpFMul %float %18240 %18240 + %21071 = OpFMul %float %float_1_5625 %8761 + %15180 = OpFAdd %float %21071 %float_n0_5625 + %7127 = OpFMul %float %15180 %23534 + %7702 = OpVectorTimesScalar %v3float %16848 %7127 + %7049 = OpFAdd %v3float %6963 %7702 + %24955 = OpFAdd %float %6776 %7127 + %15642 = OpFDiv %float %float_1 %24955 + %16189 = OpCompositeConstruct %v3float %15642 %15642 %15642 + %17132 = OpFMul %v3float %7049 %16189 + %18007 = OpExtInst %v3float %1 FMax %10578 %17132 + %12443 = OpExtInst %v3float %1 FMin %18959 %18007 + %9794 = OpAccessChain %_ptr_Output_float %5777 %uint_0 + %24795 = OpCompositeExtract %float %12443 0 + OpStore %9794 %24795 + %16378 = OpAccessChain %_ptr_Output_float %5777 %uint_1 + %15746 = OpCompositeExtract %float %12443 1 + OpStore %16378 %15746 + %16379 = OpAccessChain %_ptr_Output_float %5777 %uint_2 + %15747 = OpCompositeExtract %float %12443 2 + OpStore %16379 %15747 + %23295 = OpAccessChain %_ptr_Output_float %5777 %uint_3 + OpStore %23295 %float_1 + OpReturn + OpFunctionEnd +#endif + +const uint32_t guest_output_ffx_fsr_easu_ps[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x000062B0, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0007000F, 0x00000004, 0x0000161F, 0x6E69616D, 0x00000000, 0x00001691, 0x00000C93, 0x00030010, + 0x0000161F, 0x00000007, 0x00030047, 0x00000406, 0x00000002, 0x00050048, 0x00000406, 0x00000000, + 0x00000023, 0x00000010, 0x00050048, 0x00000406, 0x00000001, 0x00000023, 0x00000018, 0x00040047, + 0x00001691, 0x0000001E, 0x00000000, 0x00040047, 0x00000C93, 0x0000000B, 0x0000000F, 0x00040047, + 0x000013C0, 0x00000021, 0x00000000, 0x00040047, 0x000013C0, 0x00000022, 0x00000000, 0x00040047, + 0x00000FFB, 0x00000021, 0x00000001, 0x00040047, 0x00000FFB, 0x00000022, 0x00000000, 0x00020013, + 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00030016, 0x0000000D, 0x00000020, 0x00040017, + 0x00000013, 0x0000000D, 0x00000002, 0x00040017, 0x00000018, 0x0000000D, 0x00000003, 0x00040017, + 0x0000001D, 0x0000000D, 0x00000004, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, 0x00020014, + 0x00000009, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040017, 0x00000017, 0x0000000B, + 0x00000004, 0x0004001E, 0x00000406, 0x00000013, 0x00000013, 0x00040020, 0x00000683, 0x00000009, + 0x00000406, 0x0004003B, 0x00000683, 0x00000CE9, 0x00000009, 0x00040015, 0x0000000C, 0x00000020, + 0x00000001, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x00000290, 0x00000009, + 0x00000013, 0x0004002B, 0x0000000D, 0x000000FC, 0x3F000000, 0x0004002B, 0x0000000D, 0x0000008A, + 0x3F800000, 0x0004002B, 0x0000000D, 0x00000341, 0xBF800000, 0x0007002C, 0x0000001D, 0x00000504, + 0x0000008A, 0x0000008A, 0x0000008A, 0x00000341, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, + 0x0004002B, 0x0000000D, 0x00000019, 0x40000000, 0x0007002C, 0x0000001D, 0x0000099C, 0x00000341, + 0x00000019, 0x0000008A, 0x00000019, 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, 0x0004002B, + 0x0000000D, 0x00000B69, 0x40800000, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x00040020, + 0x0000028A, 0x00000009, 0x0000000D, 0x0004002B, 0x0000000B, 0x00000A0A, 0x00000000, 0x00040020, + 0x0000029A, 0x00000003, 0x0000001D, 0x0004003B, 0x0000029A, 0x00001691, 0x00000003, 0x00040020, + 0x0000029B, 0x00000001, 0x0000001D, 0x0004003B, 0x0000029B, 0x00000C93, 0x00000001, 0x00040020, + 0x0000028B, 0x00000003, 0x0000000D, 0x0004002B, 0x0000000B, 0x00000A10, 0x00000002, 0x0004002B, + 0x0000000B, 0x00000A13, 0x00000003, 0x0004002B, 0x0000000B, 0x00000344, 0x7EF07EBB, 0x0004002B, + 0x0000000B, 0x00000661, 0x5F347D74, 0x00090019, 0x00000096, 0x0000000D, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00040020, 0x00000313, 0x00000000, 0x00000096, + 0x0004003B, 0x00000313, 0x000013C0, 0x00000000, 0x0002001A, 0x000001FC, 0x00040020, 0x00000479, + 0x00000000, 0x000001FC, 0x0004003B, 0x00000479, 0x00000FFB, 0x00000000, 0x0003001B, 0x000001FE, + 0x00000096, 0x0004002B, 0x0000000C, 0x00000A11, 0x00000002, 0x0004002B, 0x0000000D, 0x00000A93, + 0x3ECCCCCD, 0x0004002B, 0x0000000D, 0x000004B3, 0x3FC80000, 0x0004002B, 0x0000000D, 0x000000B4, + 0xBF100000, 0x0004002B, 0x0000000D, 0x00000738, 0x38000000, 0x0004002B, 0x0000000D, 0x000003B3, + 0xBF000000, 0x0004002B, 0x0000000D, 0x0000075D, 0xBE947AE1, 0x0005002C, 0x00000013, 0x00000379, + 0x00000A0C, 0x00000341, 0x0005002C, 0x00000013, 0x00000300, 0x0000008A, 0x00000341, 0x0005002C, + 0x00000013, 0x00000049, 0x00000341, 0x0000008A, 0x0005002C, 0x00000013, 0x0000037A, 0x00000A0C, + 0x0000008A, 0x0005002C, 0x00000013, 0x00000A44, 0x00000341, 0x00000A0C, 0x0005002C, 0x00000013, + 0x00000301, 0x0000008A, 0x0000008A, 0x0005002C, 0x00000013, 0x000001AA, 0x00000019, 0x0000008A, + 0x0005002C, 0x00000013, 0x00000BA5, 0x00000019, 0x00000A0C, 0x0005002C, 0x00000013, 0x00000138, + 0x0000008A, 0x00000A0C, 0x0005002C, 0x00000013, 0x00000139, 0x0000008A, 0x00000019, 0x0005002C, + 0x00000013, 0x0000071F, 0x00000A0C, 0x00000019, 0x0005002C, 0x00000013, 0x0000061E, 0x000000FC, + 0x000000FC, 0x0007002C, 0x0000001D, 0x00000145, 0x000000FC, 0x000000FC, 0x000000FC, 0x000000FC, + 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00005D6B, 0x00050041, + 0x00000290, 0x0000203A, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x00000013, 0x00001B2F, 0x0000203A, + 0x0004007C, 0x00000011, 0x00003455, 0x00001B2F, 0x0005008E, 0x00000013, 0x000031DA, 0x00001B2F, + 0x000000FC, 0x00050083, 0x00000013, 0x00006013, 0x000031DA, 0x0000061E, 0x0004007C, 0x00000011, + 0x0000454F, 0x00006013, 0x00050051, 0x0000000B, 0x00004143, 0x00003455, 0x00000000, 0x00050051, + 0x0000000B, 0x000033E3, 0x00003455, 0x00000001, 0x00050051, 0x0000000B, 0x00001DD9, 0x0000454F, + 0x00000000, 0x00050051, 0x0000000B, 0x00001D69, 0x0000454F, 0x00000001, 0x00070050, 0x00000017, + 0x00004741, 0x00004143, 0x000033E3, 0x00001DD9, 0x00001D69, 0x00050041, 0x00000290, 0x000022DA, + 0x00000CE9, 0x00000A0E, 0x0004003D, 0x00000013, 0x00001EF1, 0x000022DA, 0x0009004F, 0x0000001D, + 0x0000215F, 0x00001EF1, 0x00001EF1, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00050085, + 0x0000001D, 0x00002B50, 0x00000504, 0x0000215F, 0x0004007C, 0x00000017, 0x00003229, 0x00002B50, + 0x00050085, 0x0000001D, 0x0000414D, 0x0000099C, 0x0000215F, 0x0004007C, 0x00000017, 0x00002D35, + 0x0000414D, 0x00060041, 0x0000028A, 0x00004F87, 0x00000CE9, 0x00000A0E, 0x00000A0D, 0x0004003D, + 0x0000000D, 0x000050C8, 0x00004F87, 0x00050085, 0x0000000D, 0x000046A9, 0x00000B69, 0x000050C8, + 0x0004007C, 0x0000000B, 0x00004B0A, 0x000046A9, 0x00070050, 0x00000017, 0x00002A70, 0x00000A0A, + 0x00004B0A, 0x00000A0A, 0x00000A0A, 0x0004003D, 0x0000001D, 0x000019E7, 0x00000C93, 0x0007004F, + 0x00000013, 0x00003A1F, 0x000019E7, 0x000019E7, 0x00000000, 0x00000001, 0x0004006D, 0x00000011, + 0x0000468C, 0x00003A1F, 0x00040070, 0x00000013, 0x000062AF, 0x0000468C, 0x0007004F, 0x00000011, + 0x0000620D, 0x00004741, 0x00004741, 0x00000000, 0x00000001, 0x0004007C, 0x00000013, 0x00002D38, + 0x0000620D, 0x00050085, 0x00000013, 0x0000514E, 0x000062AF, 0x00002D38, 0x0007004F, 0x00000011, + 0x00002322, 0x00004741, 0x00004741, 0x00000002, 0x00000003, 0x0004007C, 0x00000013, 0x00002E15, + 0x00002322, 0x00050081, 0x00000013, 0x00004E65, 0x0000514E, 0x00002E15, 0x0006000C, 0x00000013, + 0x00002F62, 0x00000001, 0x00000008, 0x00004E65, 0x00050083, 0x00000013, 0x00005449, 0x00004E65, + 0x00002F62, 0x0007004F, 0x00000011, 0x00006260, 0x00003229, 0x00003229, 0x00000000, 0x00000001, + 0x0004007C, 0x00000013, 0x0000433E, 0x00006260, 0x00050085, 0x00000013, 0x0000514F, 0x00002F62, + 0x0000433E, 0x0007004F, 0x00000011, 0x00002323, 0x00003229, 0x00003229, 0x00000002, 0x00000003, + 0x0004007C, 0x00000013, 0x00003306, 0x00002323, 0x00050081, 0x00000013, 0x00003C54, 0x0000514F, + 0x00003306, 0x0007004F, 0x00000011, 0x0000403F, 0x00002D35, 0x00002D35, 0x00000000, 0x00000001, + 0x0004007C, 0x00000013, 0x00003FA5, 0x0000403F, 0x00050081, 0x00000013, 0x00003C55, 0x00003C54, + 0x00003FA5, 0x0007004F, 0x00000011, 0x00004040, 0x00002D35, 0x00002D35, 0x00000002, 0x00000003, + 0x0004007C, 0x00000013, 0x00003FA6, 0x00004040, 0x00050081, 0x00000013, 0x00003C56, 0x00003C54, + 0x00003FA6, 0x0007004F, 0x00000011, 0x00004041, 0x00002A70, 0x00002A70, 0x00000000, 0x00000001, + 0x0004007C, 0x00000013, 0x00003E4F, 0x00004041, 0x00050081, 0x00000013, 0x000043D1, 0x00003C54, + 0x00003E4F, 0x0004003D, 0x00000096, 0x000053BB, 0x000013C0, 0x0004003D, 0x000001FC, 0x00004439, + 0x00000FFB, 0x00050056, 0x000001FE, 0x0000288F, 0x000053BB, 0x00004439, 0x00060060, 0x0000001D, + 0x000028B8, 0x0000288F, 0x00003C54, 0x00000A0B, 0x0004003D, 0x00000096, 0x00004B4C, 0x000013C0, + 0x0004003D, 0x000001FC, 0x0000348A, 0x00000FFB, 0x00050056, 0x000001FE, 0x00002890, 0x00004B4C, + 0x0000348A, 0x00060060, 0x0000001D, 0x000028B9, 0x00002890, 0x00003C54, 0x00000A0E, 0x0004003D, + 0x00000096, 0x00004B4D, 0x000013C0, 0x0004003D, 0x000001FC, 0x0000348B, 0x00000FFB, 0x00050056, + 0x000001FE, 0x00002891, 0x00004B4D, 0x0000348B, 0x00060060, 0x0000001D, 0x000028BA, 0x00002891, + 0x00003C54, 0x00000A11, 0x0004003D, 0x00000096, 0x00004B4E, 0x000013C0, 0x0004003D, 0x000001FC, + 0x0000348C, 0x00000FFB, 0x00050056, 0x000001FE, 0x00002892, 0x00004B4E, 0x0000348C, 0x00060060, + 0x0000001D, 0x000028BB, 0x00002892, 0x00003C55, 0x00000A0B, 0x0004003D, 0x00000096, 0x00004B4F, + 0x000013C0, 0x0004003D, 0x000001FC, 0x0000348D, 0x00000FFB, 0x00050056, 0x000001FE, 0x00002893, + 0x00004B4F, 0x0000348D, 0x00060060, 0x0000001D, 0x000028BC, 0x00002893, 0x00003C55, 0x00000A0E, + 0x0004003D, 0x00000096, 0x00004B50, 0x000013C0, 0x0004003D, 0x000001FC, 0x0000348E, 0x00000FFB, + 0x00050056, 0x000001FE, 0x00002894, 0x00004B50, 0x0000348E, 0x00060060, 0x0000001D, 0x000028BD, + 0x00002894, 0x00003C55, 0x00000A11, 0x0004003D, 0x00000096, 0x00004B51, 0x000013C0, 0x0004003D, + 0x000001FC, 0x0000348F, 0x00000FFB, 0x00050056, 0x000001FE, 0x00002895, 0x00004B51, 0x0000348F, + 0x00060060, 0x0000001D, 0x000028BE, 0x00002895, 0x00003C56, 0x00000A0B, 0x0004003D, 0x00000096, + 0x00004B52, 0x000013C0, 0x0004003D, 0x000001FC, 0x00003490, 0x00000FFB, 0x00050056, 0x000001FE, + 0x00002896, 0x00004B52, 0x00003490, 0x00060060, 0x0000001D, 0x000028BF, 0x00002896, 0x00003C56, + 0x00000A0E, 0x0004003D, 0x00000096, 0x00004B53, 0x000013C0, 0x0004003D, 0x000001FC, 0x00003491, + 0x00000FFB, 0x00050056, 0x000001FE, 0x00002897, 0x00004B53, 0x00003491, 0x00060060, 0x0000001D, + 0x000028C0, 0x00002897, 0x00003C56, 0x00000A11, 0x0004003D, 0x00000096, 0x00004B54, 0x000013C0, + 0x0004003D, 0x000001FC, 0x00003492, 0x00000FFB, 0x00050056, 0x000001FE, 0x00002898, 0x00004B54, + 0x00003492, 0x00060060, 0x0000001D, 0x000028C1, 0x00002898, 0x000043D1, 0x00000A0B, 0x0004003D, + 0x00000096, 0x00004B55, 0x000013C0, 0x0004003D, 0x000001FC, 0x00003493, 0x00000FFB, 0x00050056, + 0x000001FE, 0x00002899, 0x00004B55, 0x00003493, 0x00060060, 0x0000001D, 0x000028C2, 0x00002899, + 0x000043D1, 0x00000A0E, 0x0004003D, 0x00000096, 0x00004B56, 0x000013C0, 0x0004003D, 0x000001FC, + 0x00003494, 0x00000FFB, 0x00050056, 0x000001FE, 0x00002DE7, 0x00004B56, 0x00003494, 0x00060060, + 0x0000001D, 0x000047E7, 0x00002DE7, 0x000043D1, 0x00000A11, 0x00050085, 0x0000001D, 0x00005434, + 0x000028BA, 0x00000145, 0x00050085, 0x0000001D, 0x00004EE8, 0x000028B8, 0x00000145, 0x00050081, + 0x0000001D, 0x00003D4A, 0x00004EE8, 0x000028B9, 0x00050081, 0x0000001D, 0x000057B3, 0x00005434, + 0x00003D4A, 0x00050085, 0x0000001D, 0x00002E81, 0x000028BD, 0x00000145, 0x00050085, 0x0000001D, + 0x00005E97, 0x000028BB, 0x00000145, 0x00050081, 0x0000001D, 0x00003D4B, 0x00005E97, 0x000028BC, + 0x00050081, 0x0000001D, 0x000057B4, 0x00002E81, 0x00003D4B, 0x00050085, 0x0000001D, 0x00002E82, + 0x000028C0, 0x00000145, 0x00050085, 0x0000001D, 0x00005E98, 0x000028BE, 0x00000145, 0x00050081, + 0x0000001D, 0x00003D4C, 0x00005E98, 0x000028BF, 0x00050081, 0x0000001D, 0x000057B5, 0x00002E82, + 0x00003D4C, 0x00050085, 0x0000001D, 0x00002E83, 0x000047E7, 0x00000145, 0x00050085, 0x0000001D, + 0x00005E99, 0x000028C1, 0x00000145, 0x00050081, 0x0000001D, 0x0000396E, 0x00005E99, 0x000028C2, + 0x00050081, 0x0000001D, 0x00002C7C, 0x00002E83, 0x0000396E, 0x00050051, 0x0000000D, 0x00001CE0, + 0x000057B3, 0x00000000, 0x00050051, 0x0000000D, 0x00003707, 0x000057B3, 0x00000001, 0x00050051, + 0x0000000D, 0x00001DEC, 0x000057B4, 0x00000000, 0x00050051, 0x0000000D, 0x00001DED, 0x000057B4, + 0x00000001, 0x00050051, 0x0000000D, 0x00001DEE, 0x000057B4, 0x00000002, 0x00050051, 0x0000000D, + 0x00001DEF, 0x000057B4, 0x00000003, 0x00050051, 0x0000000D, 0x00001DF0, 0x000057B5, 0x00000000, + 0x00050051, 0x0000000D, 0x00001DF1, 0x000057B5, 0x00000001, 0x00050051, 0x0000000D, 0x00001DF2, + 0x000057B5, 0x00000002, 0x00050051, 0x0000000D, 0x00001DF3, 0x000057B5, 0x00000003, 0x00050051, + 0x0000000D, 0x00001DF4, 0x00002C7C, 0x00000002, 0x00050051, 0x0000000D, 0x000021A2, 0x00002C7C, + 0x00000003, 0x00050051, 0x0000000D, 0x000046A1, 0x00005449, 0x00000000, 0x00050083, 0x0000000D, + 0x00002F21, 0x0000008A, 0x000046A1, 0x00050051, 0x0000000D, 0x00002E64, 0x00005449, 0x00000001, + 0x00050083, 0x0000000D, 0x00002B65, 0x0000008A, 0x00002E64, 0x00050085, 0x0000000D, 0x0000463A, + 0x00002F21, 0x00002B65, 0x00050083, 0x0000000D, 0x00005062, 0x00001DF3, 0x00001DEE, 0x00050083, + 0x0000000D, 0x00002B70, 0x00001DEE, 0x00001DEF, 0x0006000C, 0x0000000D, 0x000019A8, 0x00000001, + 0x00000004, 0x00005062, 0x0006000C, 0x0000000D, 0x000035B7, 0x00000001, 0x00000004, 0x00002B70, + 0x0007000C, 0x0000000D, 0x00004818, 0x00000001, 0x00000028, 0x000019A8, 0x000035B7, 0x0004007C, + 0x0000000B, 0x00001C85, 0x00004818, 0x00050082, 0x0000000B, 0x000022F7, 0x00000344, 0x00001C85, + 0x0004007C, 0x0000000D, 0x00002217, 0x000022F7, 0x00050083, 0x0000000D, 0x00002FF9, 0x00001DF3, + 0x00001DEF, 0x00050085, 0x0000000D, 0x00002F26, 0x00002FF9, 0x0000463A, 0x0006000C, 0x0000000D, + 0x00004390, 0x00000001, 0x00000004, 0x00002FF9, 0x00050085, 0x0000000D, 0x00003F15, 0x00004390, + 0x00002217, 0x0008000C, 0x0000000D, 0x00005381, 0x00000001, 0x0000002B, 0x00003F15, 0x00000A0C, + 0x0000008A, 0x00050085, 0x0000000D, 0x0000480B, 0x00005381, 0x00005381, 0x00050083, 0x0000000D, + 0x0000601D, 0x00001DED, 0x00001DEE, 0x00050083, 0x0000000D, 0x00002B71, 0x00001DEE, 0x00001CE0, + 0x0006000C, 0x0000000D, 0x000019A9, 0x00000001, 0x00000004, 0x0000601D, 0x0006000C, 0x0000000D, + 0x000035B8, 0x00000001, 0x00000004, 0x00002B71, 0x0007000C, 0x0000000D, 0x00004819, 0x00000001, + 0x00000028, 0x000019A9, 0x000035B8, 0x0004007C, 0x0000000B, 0x00001C86, 0x00004819, 0x00050082, + 0x0000000B, 0x000022F8, 0x00000344, 0x00001C86, 0x0004007C, 0x0000000D, 0x00002218, 0x000022F8, + 0x00050083, 0x0000000D, 0x00002FFA, 0x00001DED, 0x00001CE0, 0x00050085, 0x0000000D, 0x00002F27, + 0x00002FFA, 0x0000463A, 0x0006000C, 0x0000000D, 0x00004391, 0x00000001, 0x00000004, 0x00002FFA, + 0x00050085, 0x0000000D, 0x00003F16, 0x00004391, 0x00002218, 0x0008000C, 0x0000000D, 0x0000535B, + 0x00000001, 0x0000002B, 0x00003F16, 0x00000A0C, 0x0000008A, 0x00050085, 0x0000000D, 0x0000498B, + 0x0000535B, 0x0000535B, 0x00050081, 0x0000000D, 0x00005D3D, 0x0000480B, 0x0000498B, 0x00050085, + 0x0000000D, 0x00002208, 0x0000463A, 0x00005D3D, 0x00050085, 0x0000000D, 0x00005492, 0x000046A1, + 0x00002B65, 0x00050083, 0x0000000D, 0x00005AE8, 0x00001DF2, 0x00001DF3, 0x0006000C, 0x0000000D, + 0x00001B12, 0x00000001, 0x00000004, 0x00005AE8, 0x0007000C, 0x0000000D, 0x0000337C, 0x00000001, + 0x00000028, 0x00001B12, 0x000019A8, 0x0004007C, 0x0000000B, 0x00001C87, 0x0000337C, 0x00050082, + 0x0000000B, 0x000022F9, 0x00000344, 0x00001C87, 0x0004007C, 0x0000000D, 0x00002219, 0x000022F9, + 0x00050083, 0x0000000D, 0x000038A4, 0x00001DF2, 0x00001DEE, 0x00050085, 0x0000000D, 0x000054BA, + 0x000038A4, 0x00005492, 0x00050081, 0x0000000D, 0x000021AB, 0x00002F26, 0x000054BA, 0x0006000C, + 0x0000000D, 0x00001C7B, 0x00000001, 0x00000004, 0x000038A4, 0x00050085, 0x0000000D, 0x0000327B, + 0x00001C7B, 0x00002219, 0x0008000C, 0x0000000D, 0x000053A7, 0x00000001, 0x0000002B, 0x0000327B, + 0x00000A0C, 0x0000008A, 0x00050085, 0x0000000D, 0x0000468B, 0x000053A7, 0x000053A7, 0x00050085, + 0x0000000D, 0x00002A46, 0x0000468B, 0x00005492, 0x00050081, 0x0000000D, 0x00003BCA, 0x00002208, + 0x00002A46, 0x00050083, 0x0000000D, 0x00005A93, 0x00001DF0, 0x00001DF3, 0x00050083, 0x0000000D, + 0x00001ED6, 0x00001DF3, 0x00003707, 0x0006000C, 0x0000000D, 0x000019AA, 0x00000001, 0x00000004, + 0x00005A93, 0x0006000C, 0x0000000D, 0x000035B9, 0x00000001, 0x00000004, 0x00001ED6, 0x0007000C, + 0x0000000D, 0x0000481A, 0x00000001, 0x00000028, 0x000019AA, 0x000035B9, 0x0004007C, 0x0000000B, + 0x00001C88, 0x0000481A, 0x00050082, 0x0000000B, 0x000022FA, 0x00000344, 0x00001C88, 0x0004007C, + 0x0000000D, 0x0000221A, 0x000022FA, 0x00050083, 0x0000000D, 0x000038A5, 0x00001DF0, 0x00003707, + 0x00050085, 0x0000000D, 0x000054BB, 0x000038A5, 0x00005492, 0x00050081, 0x0000000D, 0x000021AC, + 0x00002F27, 0x000054BB, 0x0006000C, 0x0000000D, 0x00001C7C, 0x00000001, 0x00000004, 0x000038A5, + 0x00050085, 0x0000000D, 0x0000327C, 0x00001C7C, 0x0000221A, 0x0008000C, 0x0000000D, 0x000053A8, + 0x00000001, 0x0000002B, 0x0000327C, 0x00000A0C, 0x0000008A, 0x00050085, 0x0000000D, 0x0000468D, + 0x000053A8, 0x000053A8, 0x00050085, 0x0000000D, 0x00002A6C, 0x0000468D, 0x00005492, 0x00050081, + 0x0000000D, 0x00003A70, 0x00003BCA, 0x00002A6C, 0x00050085, 0x0000000D, 0x00002362, 0x00002F21, + 0x00002E64, 0x00050083, 0x0000000D, 0x00004A15, 0x00001DF0, 0x00001DED, 0x00050083, 0x0000000D, + 0x00002B72, 0x00001DED, 0x00001DEC, 0x0006000C, 0x0000000D, 0x000019AB, 0x00000001, 0x00000004, + 0x00004A15, 0x0006000C, 0x0000000D, 0x000035BA, 0x00000001, 0x00000004, 0x00002B72, 0x0007000C, + 0x0000000D, 0x0000481B, 0x00000001, 0x00000028, 0x000019AB, 0x000035BA, 0x0004007C, 0x0000000B, + 0x00001C89, 0x0000481B, 0x00050082, 0x0000000B, 0x000022FB, 0x00000344, 0x00001C89, 0x0004007C, + 0x0000000D, 0x0000221B, 0x000022FB, 0x00050083, 0x0000000D, 0x000038A6, 0x00001DF0, 0x00001DEC, + 0x00050085, 0x0000000D, 0x000054BC, 0x000038A6, 0x00002362, 0x00050081, 0x0000000D, 0x000021AD, + 0x000021AB, 0x000054BC, 0x0006000C, 0x0000000D, 0x00001C7D, 0x00000001, 0x00000004, 0x000038A6, + 0x00050085, 0x0000000D, 0x0000327D, 0x00001C7D, 0x0000221B, 0x0008000C, 0x0000000D, 0x000053A9, + 0x00000001, 0x0000002B, 0x0000327D, 0x00000A0C, 0x0000008A, 0x00050085, 0x0000000D, 0x0000468E, + 0x000053A9, 0x000053A9, 0x00050085, 0x0000000D, 0x00002A47, 0x0000468E, 0x00002362, 0x00050081, + 0x0000000D, 0x000032F9, 0x00003A70, 0x00002A47, 0x00050083, 0x0000000D, 0x00002D86, 0x000021A2, + 0x00001DED, 0x0006000C, 0x0000000D, 0x000027B1, 0x00000001, 0x00000004, 0x00002D86, 0x0007000C, + 0x0000000D, 0x0000337D, 0x00000001, 0x00000028, 0x000027B1, 0x000019A9, 0x0004007C, 0x0000000B, + 0x00001C8A, 0x0000337D, 0x00050082, 0x0000000B, 0x000022FC, 0x00000344, 0x00001C8A, 0x0004007C, + 0x0000000D, 0x0000221C, 0x000022FC, 0x00050083, 0x0000000D, 0x000038A7, 0x000021A2, 0x00001DEE, + 0x00050085, 0x0000000D, 0x000054BD, 0x000038A7, 0x00002362, 0x00050081, 0x0000000D, 0x000021AE, + 0x000021AC, 0x000054BD, 0x0006000C, 0x0000000D, 0x00001C7E, 0x00000001, 0x00000004, 0x000038A7, + 0x00050085, 0x0000000D, 0x0000327E, 0x00001C7E, 0x0000221C, 0x0008000C, 0x0000000D, 0x000053AA, + 0x00000001, 0x0000002B, 0x0000327E, 0x00000A0C, 0x0000008A, 0x00050085, 0x0000000D, 0x0000468F, + 0x000053AA, 0x000053AA, 0x00050085, 0x0000000D, 0x00002A6D, 0x0000468F, 0x00002362, 0x00050081, + 0x0000000D, 0x00003A71, 0x000032F9, 0x00002A6D, 0x00050085, 0x0000000D, 0x00001A91, 0x000046A1, + 0x00002E64, 0x00050083, 0x0000000D, 0x00001D08, 0x00001DF1, 0x00001DF0, 0x0006000C, 0x0000000D, + 0x00001B13, 0x00000001, 0x00000004, 0x00001D08, 0x0007000C, 0x0000000D, 0x0000337E, 0x00000001, + 0x00000028, 0x00001B13, 0x000019AB, 0x0004007C, 0x0000000B, 0x00001C8B, 0x0000337E, 0x00050082, + 0x0000000B, 0x000022FD, 0x00000344, 0x00001C8B, 0x0004007C, 0x0000000D, 0x0000221D, 0x000022FD, + 0x00050083, 0x0000000D, 0x000038A8, 0x00001DF1, 0x00001DED, 0x00050085, 0x0000000D, 0x000054BE, + 0x000038A8, 0x00001A91, 0x00050081, 0x0000000D, 0x000021AF, 0x000021AD, 0x000054BE, 0x0006000C, + 0x0000000D, 0x00001C7F, 0x00000001, 0x00000004, 0x000038A8, 0x00050085, 0x0000000D, 0x0000327F, + 0x00001C7F, 0x0000221D, 0x0008000C, 0x0000000D, 0x000053AB, 0x00000001, 0x0000002B, 0x0000327F, + 0x00000A0C, 0x0000008A, 0x00050085, 0x0000000D, 0x00004690, 0x000053AB, 0x000053AB, 0x00050085, + 0x0000000D, 0x00002A48, 0x00004690, 0x00001A91, 0x00050081, 0x0000000D, 0x000032FA, 0x00003A71, + 0x00002A48, 0x00050083, 0x0000000D, 0x00002D87, 0x00001DF4, 0x00001DF0, 0x0006000C, 0x0000000D, + 0x000027B2, 0x00000001, 0x00000004, 0x00002D87, 0x0007000C, 0x0000000D, 0x0000337F, 0x00000001, + 0x00000028, 0x000027B2, 0x000019AA, 0x0004007C, 0x0000000B, 0x00001C8C, 0x0000337F, 0x00050082, + 0x0000000B, 0x000022FE, 0x00000344, 0x00001C8C, 0x0004007C, 0x0000000D, 0x0000221E, 0x000022FE, + 0x00050083, 0x0000000D, 0x000038A9, 0x00001DF4, 0x00001DF3, 0x00050085, 0x0000000D, 0x000059C2, + 0x000038A9, 0x00001A91, 0x00050081, 0x0000000D, 0x00001DDD, 0x000021AE, 0x000059C2, 0x00050050, + 0x00000013, 0x000048DB, 0x000021AF, 0x00001DDD, 0x0006000C, 0x0000000D, 0x00002B01, 0x00000001, + 0x00000004, 0x000038A9, 0x00050085, 0x0000000D, 0x000022D6, 0x00002B01, 0x0000221E, 0x0008000C, + 0x0000000D, 0x000053AC, 0x00000001, 0x0000002B, 0x000022D6, 0x00000A0C, 0x0000008A, 0x00050085, + 0x0000000D, 0x00004691, 0x000053AC, 0x000053AC, 0x00050085, 0x0000000D, 0x00002A6E, 0x00004691, + 0x00001A91, 0x00050081, 0x0000000D, 0x000036BA, 0x000032FA, 0x00002A6E, 0x00050085, 0x00000013, + 0x00004176, 0x000048DB, 0x000048DB, 0x00050051, 0x0000000D, 0x00004DD2, 0x00004176, 0x00000000, + 0x00050051, 0x0000000D, 0x00005C1C, 0x00004176, 0x00000001, 0x00050081, 0x0000000D, 0x00002903, + 0x00004DD2, 0x00005C1C, 0x000500B8, 0x00000009, 0x0000584B, 0x00002903, 0x00000738, 0x0004007C, + 0x0000000B, 0x00005637, 0x00002903, 0x000500C2, 0x0000000B, 0x0000483B, 0x00005637, 0x00000A0D, + 0x00050082, 0x0000000B, 0x00004F58, 0x00000661, 0x0000483B, 0x0004007C, 0x0000000D, 0x00001DD4, + 0x00004F58, 0x000600A9, 0x0000000D, 0x00004F1C, 0x0000584B, 0x0000008A, 0x00001DD4, 0x000600A9, + 0x0000000D, 0x00004791, 0x0000584B, 0x0000008A, 0x000021AF, 0x00060052, 0x00000013, 0x00003A9B, + 0x00004791, 0x000048DB, 0x00000000, 0x00050050, 0x00000013, 0x000036AE, 0x00004F1C, 0x00004F1C, + 0x00050085, 0x00000013, 0x0000275C, 0x00003A9B, 0x000036AE, 0x00050085, 0x0000000D, 0x00002F75, + 0x000036BA, 0x000000FC, 0x00050085, 0x0000000D, 0x00002835, 0x00002F75, 0x00002F75, 0x00050051, + 0x0000000D, 0x000033B8, 0x0000275C, 0x00000000, 0x00050085, 0x0000000D, 0x00005F79, 0x000033B8, + 0x000033B8, 0x00050051, 0x0000000D, 0x00005C12, 0x0000275C, 0x00000001, 0x00050085, 0x0000000D, + 0x00003612, 0x00005C12, 0x00005C12, 0x00050081, 0x0000000D, 0x000043CB, 0x00005F79, 0x00003612, + 0x0006000C, 0x0000000D, 0x00003B20, 0x00000001, 0x00000004, 0x000033B8, 0x0006000C, 0x0000000D, + 0x000048A3, 0x00000001, 0x00000004, 0x00005C12, 0x0007000C, 0x0000000D, 0x0000481C, 0x00000001, + 0x00000028, 0x00003B20, 0x000048A3, 0x0004007C, 0x0000000B, 0x00001C8D, 0x0000481C, 0x00050082, + 0x0000000B, 0x0000231D, 0x00000344, 0x00001C8D, 0x0004007C, 0x0000000D, 0x00002097, 0x0000231D, + 0x00050085, 0x0000000D, 0x000044C7, 0x000043CB, 0x00002097, 0x00050083, 0x0000000D, 0x00004E42, + 0x000044C7, 0x0000008A, 0x00050085, 0x0000000D, 0x000022F0, 0x00004E42, 0x00002835, 0x00050081, + 0x0000000D, 0x00004D36, 0x0000008A, 0x000022F0, 0x00050085, 0x0000000D, 0x000020F3, 0x000003B3, + 0x00002835, 0x00050081, 0x0000000D, 0x00002087, 0x0000008A, 0x000020F3, 0x00050050, 0x00000013, + 0x000029E7, 0x00004D36, 0x00002087, 0x00050085, 0x0000000D, 0x00004BF6, 0x0000075D, 0x00002835, + 0x00050081, 0x0000000D, 0x00002433, 0x000000FC, 0x00004BF6, 0x0004007C, 0x0000000B, 0x00001997, + 0x00002433, 0x00050082, 0x0000000B, 0x00001A21, 0x00000344, 0x00001997, 0x0004007C, 0x0000000D, + 0x00004005, 0x00001A21, 0x00050051, 0x0000000D, 0x00004AB9, 0x000028BB, 0x00000002, 0x00050051, + 0x0000000D, 0x000033D0, 0x000028BC, 0x00000002, 0x00050051, 0x0000000D, 0x00001E99, 0x000028BD, + 0x00000002, 0x00060050, 0x00000018, 0x00003DED, 0x00004AB9, 0x000033D0, 0x00001E99, 0x00050051, + 0x0000000D, 0x00001EE5, 0x000028BE, 0x00000003, 0x00050051, 0x0000000D, 0x00005895, 0x000028BF, + 0x00000003, 0x00050051, 0x0000000D, 0x00001E9A, 0x000028C0, 0x00000003, 0x00060050, 0x00000018, + 0x00003DEE, 0x00001EE5, 0x00005895, 0x00001E9A, 0x00050051, 0x0000000D, 0x00001EE6, 0x000028BB, + 0x00000001, 0x00050051, 0x0000000D, 0x00005896, 0x000028BC, 0x00000001, 0x00050051, 0x0000000D, + 0x0000199F, 0x000028BD, 0x00000001, 0x00060050, 0x00000018, 0x00003B22, 0x00001EE6, 0x00005896, + 0x0000199F, 0x0007000C, 0x00000018, 0x000041FF, 0x00000001, 0x00000025, 0x00003DEE, 0x00003B22, + 0x0007000C, 0x00000018, 0x00005547, 0x00000001, 0x00000025, 0x00003DED, 0x000041FF, 0x00050051, + 0x0000000D, 0x0000202C, 0x000028BE, 0x00000000, 0x00050051, 0x0000000D, 0x00002B2C, 0x000028BF, + 0x00000000, 0x00050051, 0x0000000D, 0x000019A0, 0x000028C0, 0x00000000, 0x00060050, 0x00000018, + 0x00003B25, 0x0000202C, 0x00002B2C, 0x000019A0, 0x0007000C, 0x00000018, 0x00002952, 0x00000001, + 0x00000025, 0x00005547, 0x00003B25, 0x0007000C, 0x00000018, 0x000041D2, 0x00000001, 0x00000028, + 0x00003DEE, 0x00003B22, 0x0007000C, 0x00000018, 0x00004D20, 0x00000001, 0x00000028, 0x00003DED, + 0x000041D2, 0x0007000C, 0x00000018, 0x00004A0F, 0x00000001, 0x00000028, 0x00004D20, 0x00003B25, + 0x00050083, 0x00000013, 0x00003D57, 0x00000379, 0x00005449, 0x00050051, 0x0000000D, 0x0000200E, + 0x000028B8, 0x00000000, 0x00050051, 0x0000000D, 0x00003D41, 0x000028B9, 0x00000000, 0x00050051, + 0x0000000D, 0x00001E9B, 0x000028BA, 0x00000000, 0x00060050, 0x00000018, 0x000041C9, 0x0000200E, + 0x00003D41, 0x00001E9B, 0x00050051, 0x0000000D, 0x00004640, 0x00003D57, 0x00000000, 0x00050085, + 0x0000000D, 0x0000433A, 0x00004640, 0x000033B8, 0x00050051, 0x0000000D, 0x00005C13, 0x00003D57, + 0x00000001, 0x00050085, 0x0000000D, 0x00003E97, 0x00005C13, 0x00005C12, 0x00050081, 0x0000000D, + 0x00003228, 0x0000433A, 0x00003E97, 0x0004007F, 0x0000000D, 0x00004D37, 0x00005C12, 0x00050085, + 0x0000000D, 0x00003073, 0x00004640, 0x00004D37, 0x00050085, 0x0000000D, 0x000054A7, 0x00005C13, + 0x000033B8, 0x00050081, 0x0000000D, 0x00005E67, 0x00003073, 0x000054A7, 0x00050050, 0x00000013, + 0x00002657, 0x00003228, 0x00005E67, 0x00050085, 0x00000013, 0x00002292, 0x00002657, 0x000029E7, + 0x00050051, 0x0000000D, 0x000061F8, 0x00002292, 0x00000000, 0x00050085, 0x0000000D, 0x00005F7A, + 0x000061F8, 0x000061F8, 0x00050051, 0x0000000D, 0x00005C14, 0x00002292, 0x00000001, 0x00050085, + 0x0000000D, 0x00003633, 0x00005C14, 0x00005C14, 0x00050081, 0x0000000D, 0x0000536D, 0x00005F7A, + 0x00003633, 0x0007000C, 0x0000000D, 0x00002AD1, 0x00000001, 0x00000025, 0x0000536D, 0x00004005, + 0x00050085, 0x0000000D, 0x0000275D, 0x00000A93, 0x00002AD1, 0x00050081, 0x0000000D, 0x0000545A, + 0x0000275D, 0x00000341, 0x00050085, 0x0000000D, 0x000024E2, 0x00002433, 0x00002AD1, 0x00050081, + 0x0000000D, 0x00004735, 0x000024E2, 0x00000341, 0x00050085, 0x0000000D, 0x0000222E, 0x0000545A, + 0x0000545A, 0x00050085, 0x0000000D, 0x00005BE3, 0x00004735, 0x00004735, 0x00050085, 0x0000000D, + 0x00005244, 0x000004B3, 0x0000222E, 0x00050081, 0x0000000D, 0x00003B41, 0x00005244, 0x000000B4, + 0x00050085, 0x0000000D, 0x00001BF3, 0x00003B41, 0x00005BE3, 0x0005008E, 0x00000018, 0x00001921, + 0x000041C9, 0x00001BF3, 0x00050083, 0x00000013, 0x00002928, 0x00000300, 0x00005449, 0x00050051, + 0x0000000D, 0x00001E0D, 0x000028B8, 0x00000001, 0x00050051, 0x0000000D, 0x00003D42, 0x000028B9, + 0x00000001, 0x00050051, 0x0000000D, 0x00001E9C, 0x000028BA, 0x00000001, 0x00060050, 0x00000018, + 0x000041CA, 0x00001E0D, 0x00003D42, 0x00001E9C, 0x00050051, 0x0000000D, 0x00004641, 0x00002928, + 0x00000000, 0x00050085, 0x0000000D, 0x0000433B, 0x00004641, 0x000033B8, 0x00050051, 0x0000000D, + 0x00005C15, 0x00002928, 0x00000001, 0x00050085, 0x0000000D, 0x00003F09, 0x00005C15, 0x00005C12, + 0x00050081, 0x0000000D, 0x00002E1A, 0x0000433B, 0x00003F09, 0x00050085, 0x0000000D, 0x000021E2, + 0x00004641, 0x00004D37, 0x00050085, 0x0000000D, 0x00005AF4, 0x00005C15, 0x000033B8, 0x00050081, + 0x0000000D, 0x00005E68, 0x000021E2, 0x00005AF4, 0x00050050, 0x00000013, 0x00002658, 0x00002E1A, + 0x00005E68, 0x00050085, 0x00000013, 0x00002293, 0x00002658, 0x000029E7, 0x00050051, 0x0000000D, + 0x000061F9, 0x00002293, 0x00000000, 0x00050085, 0x0000000D, 0x00005F7B, 0x000061F9, 0x000061F9, + 0x00050051, 0x0000000D, 0x00005C16, 0x00002293, 0x00000001, 0x00050085, 0x0000000D, 0x00003634, + 0x00005C16, 0x00005C16, 0x00050081, 0x0000000D, 0x0000536E, 0x00005F7B, 0x00003634, 0x0007000C, + 0x0000000D, 0x00002AD2, 0x00000001, 0x00000025, 0x0000536E, 0x00004005, 0x00050085, 0x0000000D, + 0x0000275E, 0x00000A93, 0x00002AD2, 0x00050081, 0x0000000D, 0x0000545B, 0x0000275E, 0x00000341, + 0x00050085, 0x0000000D, 0x000024E3, 0x00002433, 0x00002AD2, 0x00050081, 0x0000000D, 0x00004736, + 0x000024E3, 0x00000341, 0x00050085, 0x0000000D, 0x0000222F, 0x0000545B, 0x0000545B, 0x00050085, + 0x0000000D, 0x00005BE4, 0x00004736, 0x00004736, 0x00050085, 0x0000000D, 0x00005245, 0x000004B3, + 0x0000222F, 0x00050081, 0x0000000D, 0x00003B42, 0x00005245, 0x000000B4, 0x00050085, 0x0000000D, + 0x00001BCD, 0x00003B42, 0x00005BE4, 0x0005008E, 0x00000018, 0x00001E0B, 0x000041CA, 0x00001BCD, + 0x00050081, 0x00000018, 0x00001B2A, 0x00001921, 0x00001E0B, 0x00050081, 0x0000000D, 0x00001A70, + 0x00001BF3, 0x00001BCD, 0x00050083, 0x00000013, 0x00004398, 0x00000049, 0x00005449, 0x00050051, + 0x0000000D, 0x00001AEE, 0x000028BB, 0x00000000, 0x00050051, 0x0000000D, 0x00003D43, 0x000028BC, + 0x00000000, 0x00050051, 0x0000000D, 0x00001E9D, 0x000028BD, 0x00000000, 0x00060050, 0x00000018, + 0x000041CB, 0x00001AEE, 0x00003D43, 0x00001E9D, 0x00050051, 0x0000000D, 0x00004642, 0x00004398, + 0x00000000, 0x00050085, 0x0000000D, 0x0000433C, 0x00004642, 0x000033B8, 0x00050051, 0x0000000D, + 0x00005C17, 0x00004398, 0x00000001, 0x00050085, 0x0000000D, 0x00003F0A, 0x00005C17, 0x00005C12, + 0x00050081, 0x0000000D, 0x00002E1B, 0x0000433C, 0x00003F0A, 0x00050085, 0x0000000D, 0x000021E3, + 0x00004642, 0x00004D37, 0x00050085, 0x0000000D, 0x00005AF5, 0x00005C17, 0x000033B8, 0x00050081, + 0x0000000D, 0x00005E69, 0x000021E3, 0x00005AF5, 0x00050050, 0x00000013, 0x00002659, 0x00002E1B, + 0x00005E69, 0x00050085, 0x00000013, 0x00002294, 0x00002659, 0x000029E7, 0x00050051, 0x0000000D, + 0x000061FA, 0x00002294, 0x00000000, 0x00050085, 0x0000000D, 0x00005F7C, 0x000061FA, 0x000061FA, + 0x00050051, 0x0000000D, 0x00005C18, 0x00002294, 0x00000001, 0x00050085, 0x0000000D, 0x00003635, + 0x00005C18, 0x00005C18, 0x00050081, 0x0000000D, 0x0000536F, 0x00005F7C, 0x00003635, 0x0007000C, + 0x0000000D, 0x00002AD3, 0x00000001, 0x00000025, 0x0000536F, 0x00004005, 0x00050085, 0x0000000D, + 0x0000275F, 0x00000A93, 0x00002AD3, 0x00050081, 0x0000000D, 0x0000545C, 0x0000275F, 0x00000341, + 0x00050085, 0x0000000D, 0x000024E4, 0x00002433, 0x00002AD3, 0x00050081, 0x0000000D, 0x00004737, + 0x000024E4, 0x00000341, 0x00050085, 0x0000000D, 0x00002230, 0x0000545C, 0x0000545C, 0x00050085, + 0x0000000D, 0x00005BE5, 0x00004737, 0x00004737, 0x00050085, 0x0000000D, 0x00005246, 0x000004B3, + 0x00002230, 0x00050081, 0x0000000D, 0x00003B43, 0x00005246, 0x000000B4, 0x00050085, 0x0000000D, + 0x00001BCE, 0x00003B43, 0x00005BE5, 0x0005008E, 0x00000018, 0x00001E0C, 0x000041CB, 0x00001BCE, + 0x00050081, 0x00000018, 0x00001B2B, 0x00001B2A, 0x00001E0C, 0x00050081, 0x0000000D, 0x00001A71, + 0x00001A70, 0x00001BCE, 0x00050083, 0x00000013, 0x00004774, 0x0000037A, 0x00005449, 0x00050051, + 0x0000000D, 0x00004249, 0x00004774, 0x00000000, 0x00050085, 0x0000000D, 0x0000592C, 0x00004249, + 0x000033B8, 0x00050051, 0x0000000D, 0x00005C19, 0x00004774, 0x00000001, 0x00050085, 0x0000000D, + 0x00003F0B, 0x00005C19, 0x00005C12, 0x00050081, 0x0000000D, 0x00002E1C, 0x0000592C, 0x00003F0B, + 0x00050085, 0x0000000D, 0x000021E4, 0x00004249, 0x00004D37, 0x00050085, 0x0000000D, 0x00005AF6, + 0x00005C19, 0x000033B8, 0x00050081, 0x0000000D, 0x00005E6A, 0x000021E4, 0x00005AF6, 0x00050050, + 0x00000013, 0x0000265A, 0x00002E1C, 0x00005E6A, 0x00050085, 0x00000013, 0x00002295, 0x0000265A, + 0x000029E7, 0x00050051, 0x0000000D, 0x000061FB, 0x00002295, 0x00000000, 0x00050085, 0x0000000D, + 0x00005F7D, 0x000061FB, 0x000061FB, 0x00050051, 0x0000000D, 0x00005C1A, 0x00002295, 0x00000001, + 0x00050085, 0x0000000D, 0x00003636, 0x00005C1A, 0x00005C1A, 0x00050081, 0x0000000D, 0x00005370, + 0x00005F7D, 0x00003636, 0x0007000C, 0x0000000D, 0x00002AD4, 0x00000001, 0x00000025, 0x00005370, + 0x00004005, 0x00050085, 0x0000000D, 0x00002760, 0x00000A93, 0x00002AD4, 0x00050081, 0x0000000D, + 0x0000545D, 0x00002760, 0x00000341, 0x00050085, 0x0000000D, 0x000024E5, 0x00002433, 0x00002AD4, + 0x00050081, 0x0000000D, 0x00004738, 0x000024E5, 0x00000341, 0x00050085, 0x0000000D, 0x00002231, + 0x0000545D, 0x0000545D, 0x00050085, 0x0000000D, 0x00005BE6, 0x00004738, 0x00004738, 0x00050085, + 0x0000000D, 0x00005247, 0x000004B3, 0x00002231, 0x00050081, 0x0000000D, 0x00003B44, 0x00005247, + 0x000000B4, 0x00050085, 0x0000000D, 0x00001BCF, 0x00003B44, 0x00005BE6, 0x0005008E, 0x00000018, + 0x00001E0E, 0x00003B22, 0x00001BCF, 0x00050081, 0x00000018, 0x00001ADE, 0x00001B2B, 0x00001E0E, + 0x00050081, 0x0000000D, 0x00001D24, 0x00001A71, 0x00001BCF, 0x0004007F, 0x00000013, 0x0000327A, + 0x00005449, 0x00050051, 0x0000000D, 0x00005F66, 0x0000327A, 0x00000000, 0x00050085, 0x0000000D, + 0x00001B4C, 0x00005F66, 0x000033B8, 0x00050051, 0x0000000D, 0x00005C1B, 0x0000327A, 0x00000001, + 0x00050085, 0x0000000D, 0x00003F0C, 0x00005C1B, 0x00005C12, 0x00050081, 0x0000000D, 0x00002E1D, + 0x00001B4C, 0x00003F0C, 0x00050085, 0x0000000D, 0x000021E5, 0x00005F66, 0x00004D37, 0x00050085, + 0x0000000D, 0x00005AF7, 0x00005C1B, 0x000033B8, 0x00050081, 0x0000000D, 0x00005E6B, 0x000021E5, + 0x00005AF7, 0x00050050, 0x00000013, 0x0000265B, 0x00002E1D, 0x00005E6B, 0x00050085, 0x00000013, + 0x00002296, 0x0000265B, 0x000029E7, 0x00050051, 0x0000000D, 0x000061FC, 0x00002296, 0x00000000, + 0x00050085, 0x0000000D, 0x00005F7E, 0x000061FC, 0x000061FC, 0x00050051, 0x0000000D, 0x00005C1D, + 0x00002296, 0x00000001, 0x00050085, 0x0000000D, 0x00003637, 0x00005C1D, 0x00005C1D, 0x00050081, + 0x0000000D, 0x00005371, 0x00005F7E, 0x00003637, 0x0007000C, 0x0000000D, 0x00002AD5, 0x00000001, + 0x00000025, 0x00005371, 0x00004005, 0x00050085, 0x0000000D, 0x00002761, 0x00000A93, 0x00002AD5, + 0x00050081, 0x0000000D, 0x0000545E, 0x00002761, 0x00000341, 0x00050085, 0x0000000D, 0x000024E6, + 0x00002433, 0x00002AD5, 0x00050081, 0x0000000D, 0x00004739, 0x000024E6, 0x00000341, 0x00050085, + 0x0000000D, 0x00002232, 0x0000545E, 0x0000545E, 0x00050085, 0x0000000D, 0x00005BE7, 0x00004739, + 0x00004739, 0x00050085, 0x0000000D, 0x00005248, 0x000004B3, 0x00002232, 0x00050081, 0x0000000D, + 0x00003B45, 0x00005248, 0x000000B4, 0x00050085, 0x0000000D, 0x00001BD0, 0x00003B45, 0x00005BE7, + 0x0005008E, 0x00000018, 0x00001E0F, 0x00003DED, 0x00001BD0, 0x00050081, 0x00000018, 0x00001B2C, + 0x00001ADE, 0x00001E0F, 0x00050081, 0x0000000D, 0x00001A72, 0x00001D24, 0x00001BD0, 0x00050083, + 0x00000013, 0x00004399, 0x00000A44, 0x00005449, 0x00050051, 0x0000000D, 0x00001AEF, 0x000028BB, + 0x00000003, 0x00050051, 0x0000000D, 0x00003D44, 0x000028BC, 0x00000003, 0x00050051, 0x0000000D, + 0x00001E9E, 0x000028BD, 0x00000003, 0x00060050, 0x00000018, 0x000041CC, 0x00001AEF, 0x00003D44, + 0x00001E9E, 0x00050051, 0x0000000D, 0x00004643, 0x00004399, 0x00000000, 0x00050085, 0x0000000D, + 0x0000433D, 0x00004643, 0x000033B8, 0x00050051, 0x0000000D, 0x00005C1E, 0x00004399, 0x00000001, + 0x00050085, 0x0000000D, 0x00003F0D, 0x00005C1E, 0x00005C12, 0x00050081, 0x0000000D, 0x00002E1E, + 0x0000433D, 0x00003F0D, 0x00050085, 0x0000000D, 0x000021E6, 0x00004643, 0x00004D37, 0x00050085, + 0x0000000D, 0x00005AF8, 0x00005C1E, 0x000033B8, 0x00050081, 0x0000000D, 0x00005E6C, 0x000021E6, + 0x00005AF8, 0x00050050, 0x00000013, 0x0000265C, 0x00002E1E, 0x00005E6C, 0x00050085, 0x00000013, + 0x00002297, 0x0000265C, 0x000029E7, 0x00050051, 0x0000000D, 0x000061FD, 0x00002297, 0x00000000, + 0x00050085, 0x0000000D, 0x00005F7F, 0x000061FD, 0x000061FD, 0x00050051, 0x0000000D, 0x00005C1F, + 0x00002297, 0x00000001, 0x00050085, 0x0000000D, 0x00003638, 0x00005C1F, 0x00005C1F, 0x00050081, + 0x0000000D, 0x00005372, 0x00005F7F, 0x00003638, 0x0007000C, 0x0000000D, 0x00002AD6, 0x00000001, + 0x00000025, 0x00005372, 0x00004005, 0x00050085, 0x0000000D, 0x00002762, 0x00000A93, 0x00002AD6, + 0x00050081, 0x0000000D, 0x0000545F, 0x00002762, 0x00000341, 0x00050085, 0x0000000D, 0x000024E7, + 0x00002433, 0x00002AD6, 0x00050081, 0x0000000D, 0x0000473A, 0x000024E7, 0x00000341, 0x00050085, + 0x0000000D, 0x00002233, 0x0000545F, 0x0000545F, 0x00050085, 0x0000000D, 0x00005BE8, 0x0000473A, + 0x0000473A, 0x00050085, 0x0000000D, 0x00005249, 0x000004B3, 0x00002233, 0x00050081, 0x0000000D, + 0x00003B46, 0x00005249, 0x000000B4, 0x00050085, 0x0000000D, 0x00001BD1, 0x00003B46, 0x00005BE8, + 0x0005008E, 0x00000018, 0x00001E10, 0x000041CC, 0x00001BD1, 0x00050081, 0x00000018, 0x00001B2D, + 0x00001B2C, 0x00001E10, 0x00050081, 0x0000000D, 0x00001A73, 0x00001A72, 0x00001BD1, 0x00050083, + 0x00000013, 0x00004775, 0x00000301, 0x00005449, 0x00050051, 0x0000000D, 0x0000424A, 0x00004775, + 0x00000000, 0x00050085, 0x0000000D, 0x0000592D, 0x0000424A, 0x000033B8, 0x00050051, 0x0000000D, + 0x00005C20, 0x00004775, 0x00000001, 0x00050085, 0x0000000D, 0x00003F0E, 0x00005C20, 0x00005C12, + 0x00050081, 0x0000000D, 0x00002E1F, 0x0000592D, 0x00003F0E, 0x00050085, 0x0000000D, 0x000021E7, + 0x0000424A, 0x00004D37, 0x00050085, 0x0000000D, 0x00005AF9, 0x00005C20, 0x000033B8, 0x00050081, + 0x0000000D, 0x00005E6D, 0x000021E7, 0x00005AF9, 0x00050050, 0x00000013, 0x0000265D, 0x00002E1F, + 0x00005E6D, 0x00050085, 0x00000013, 0x00002298, 0x0000265D, 0x000029E7, 0x00050051, 0x0000000D, + 0x000061FE, 0x00002298, 0x00000000, 0x00050085, 0x0000000D, 0x00005F80, 0x000061FE, 0x000061FE, + 0x00050051, 0x0000000D, 0x00005C21, 0x00002298, 0x00000001, 0x00050085, 0x0000000D, 0x00003639, + 0x00005C21, 0x00005C21, 0x00050081, 0x0000000D, 0x00005373, 0x00005F80, 0x00003639, 0x0007000C, + 0x0000000D, 0x00002AD7, 0x00000001, 0x00000025, 0x00005373, 0x00004005, 0x00050085, 0x0000000D, + 0x00002763, 0x00000A93, 0x00002AD7, 0x00050081, 0x0000000D, 0x00005460, 0x00002763, 0x00000341, + 0x00050085, 0x0000000D, 0x000024E8, 0x00002433, 0x00002AD7, 0x00050081, 0x0000000D, 0x0000473B, + 0x000024E8, 0x00000341, 0x00050085, 0x0000000D, 0x00002234, 0x00005460, 0x00005460, 0x00050085, + 0x0000000D, 0x00005BE9, 0x0000473B, 0x0000473B, 0x00050085, 0x0000000D, 0x0000524A, 0x000004B3, + 0x00002234, 0x00050081, 0x0000000D, 0x00003B47, 0x0000524A, 0x000000B4, 0x00050085, 0x0000000D, + 0x00001BD2, 0x00003B47, 0x00005BE9, 0x0005008E, 0x00000018, 0x00001E11, 0x00003B25, 0x00001BD2, + 0x00050081, 0x00000018, 0x00001B2E, 0x00001B2D, 0x00001E11, 0x00050081, 0x0000000D, 0x00001A74, + 0x00001A73, 0x00001BD2, 0x00050083, 0x00000013, 0x0000439A, 0x000001AA, 0x00005449, 0x00050051, + 0x0000000D, 0x00001AF0, 0x000028BE, 0x00000001, 0x00050051, 0x0000000D, 0x00003D45, 0x000028BF, + 0x00000001, 0x00050051, 0x0000000D, 0x00001E9F, 0x000028C0, 0x00000001, 0x00060050, 0x00000018, + 0x000041CD, 0x00001AF0, 0x00003D45, 0x00001E9F, 0x00050051, 0x0000000D, 0x00004644, 0x0000439A, + 0x00000000, 0x00050085, 0x0000000D, 0x0000433F, 0x00004644, 0x000033B8, 0x00050051, 0x0000000D, + 0x00005C22, 0x0000439A, 0x00000001, 0x00050085, 0x0000000D, 0x00003F0F, 0x00005C22, 0x00005C12, + 0x00050081, 0x0000000D, 0x00002E20, 0x0000433F, 0x00003F0F, 0x00050085, 0x0000000D, 0x000021E8, + 0x00004644, 0x00004D37, 0x00050085, 0x0000000D, 0x00005AFA, 0x00005C22, 0x000033B8, 0x00050081, + 0x0000000D, 0x00005E6E, 0x000021E8, 0x00005AFA, 0x00050050, 0x00000013, 0x0000265E, 0x00002E20, + 0x00005E6E, 0x00050085, 0x00000013, 0x00002299, 0x0000265E, 0x000029E7, 0x00050051, 0x0000000D, + 0x000061FF, 0x00002299, 0x00000000, 0x00050085, 0x0000000D, 0x00005F81, 0x000061FF, 0x000061FF, + 0x00050051, 0x0000000D, 0x00005C23, 0x00002299, 0x00000001, 0x00050085, 0x0000000D, 0x0000363A, + 0x00005C23, 0x00005C23, 0x00050081, 0x0000000D, 0x00005374, 0x00005F81, 0x0000363A, 0x0007000C, + 0x0000000D, 0x00002AD8, 0x00000001, 0x00000025, 0x00005374, 0x00004005, 0x00050085, 0x0000000D, + 0x00002764, 0x00000A93, 0x00002AD8, 0x00050081, 0x0000000D, 0x00005461, 0x00002764, 0x00000341, + 0x00050085, 0x0000000D, 0x000024E9, 0x00002433, 0x00002AD8, 0x00050081, 0x0000000D, 0x0000473C, + 0x000024E9, 0x00000341, 0x00050085, 0x0000000D, 0x00002235, 0x00005461, 0x00005461, 0x00050085, + 0x0000000D, 0x00005BEA, 0x0000473C, 0x0000473C, 0x00050085, 0x0000000D, 0x0000524B, 0x000004B3, + 0x00002235, 0x00050081, 0x0000000D, 0x00003B48, 0x0000524B, 0x000000B4, 0x00050085, 0x0000000D, + 0x00001BD3, 0x00003B48, 0x00005BEA, 0x0005008E, 0x00000018, 0x00001E12, 0x000041CD, 0x00001BD3, + 0x00050081, 0x00000018, 0x00001B30, 0x00001B2E, 0x00001E12, 0x00050081, 0x0000000D, 0x00001A75, + 0x00001A74, 0x00001BD3, 0x00050083, 0x00000013, 0x0000439B, 0x00000BA5, 0x00005449, 0x00050051, + 0x0000000D, 0x00001AF1, 0x000028BE, 0x00000002, 0x00050051, 0x0000000D, 0x00003D46, 0x000028BF, + 0x00000002, 0x00050051, 0x0000000D, 0x00001EA0, 0x000028C0, 0x00000002, 0x00060050, 0x00000018, + 0x000041CE, 0x00001AF1, 0x00003D46, 0x00001EA0, 0x00050051, 0x0000000D, 0x00004645, 0x0000439B, + 0x00000000, 0x00050085, 0x0000000D, 0x00004340, 0x00004645, 0x000033B8, 0x00050051, 0x0000000D, + 0x00005C24, 0x0000439B, 0x00000001, 0x00050085, 0x0000000D, 0x00003F10, 0x00005C24, 0x00005C12, + 0x00050081, 0x0000000D, 0x00002E21, 0x00004340, 0x00003F10, 0x00050085, 0x0000000D, 0x000021E9, + 0x00004645, 0x00004D37, 0x00050085, 0x0000000D, 0x00005AFB, 0x00005C24, 0x000033B8, 0x00050081, + 0x0000000D, 0x00005E6F, 0x000021E9, 0x00005AFB, 0x00050050, 0x00000013, 0x0000265F, 0x00002E21, + 0x00005E6F, 0x00050085, 0x00000013, 0x0000229A, 0x0000265F, 0x000029E7, 0x00050051, 0x0000000D, + 0x00006200, 0x0000229A, 0x00000000, 0x00050085, 0x0000000D, 0x00005F82, 0x00006200, 0x00006200, + 0x00050051, 0x0000000D, 0x00005C25, 0x0000229A, 0x00000001, 0x00050085, 0x0000000D, 0x0000363B, + 0x00005C25, 0x00005C25, 0x00050081, 0x0000000D, 0x00005375, 0x00005F82, 0x0000363B, 0x0007000C, + 0x0000000D, 0x00002AD9, 0x00000001, 0x00000025, 0x00005375, 0x00004005, 0x00050085, 0x0000000D, + 0x00002765, 0x00000A93, 0x00002AD9, 0x00050081, 0x0000000D, 0x00005462, 0x00002765, 0x00000341, + 0x00050085, 0x0000000D, 0x000024EA, 0x00002433, 0x00002AD9, 0x00050081, 0x0000000D, 0x0000473D, + 0x000024EA, 0x00000341, 0x00050085, 0x0000000D, 0x00002236, 0x00005462, 0x00005462, 0x00050085, + 0x0000000D, 0x00005BEB, 0x0000473D, 0x0000473D, 0x00050085, 0x0000000D, 0x0000524C, 0x000004B3, + 0x00002236, 0x00050081, 0x0000000D, 0x00003B49, 0x0000524C, 0x000000B4, 0x00050085, 0x0000000D, + 0x00001BD4, 0x00003B49, 0x00005BEB, 0x0005008E, 0x00000018, 0x00001E13, 0x000041CE, 0x00001BD4, + 0x00050081, 0x00000018, 0x00001B31, 0x00001B30, 0x00001E13, 0x00050081, 0x0000000D, 0x00001A76, + 0x00001A75, 0x00001BD4, 0x00050083, 0x00000013, 0x00004776, 0x00000138, 0x00005449, 0x00050051, + 0x0000000D, 0x0000424B, 0x00004776, 0x00000000, 0x00050085, 0x0000000D, 0x0000592E, 0x0000424B, + 0x000033B8, 0x00050051, 0x0000000D, 0x00005C26, 0x00004776, 0x00000001, 0x00050085, 0x0000000D, + 0x00003F11, 0x00005C26, 0x00005C12, 0x00050081, 0x0000000D, 0x00002E22, 0x0000592E, 0x00003F11, + 0x00050085, 0x0000000D, 0x000021EA, 0x0000424B, 0x00004D37, 0x00050085, 0x0000000D, 0x00005AFC, + 0x00005C26, 0x000033B8, 0x00050081, 0x0000000D, 0x00005E70, 0x000021EA, 0x00005AFC, 0x00050050, + 0x00000013, 0x00002660, 0x00002E22, 0x00005E70, 0x00050085, 0x00000013, 0x0000229B, 0x00002660, + 0x000029E7, 0x00050051, 0x0000000D, 0x00006201, 0x0000229B, 0x00000000, 0x00050085, 0x0000000D, + 0x00005F83, 0x00006201, 0x00006201, 0x00050051, 0x0000000D, 0x00005C27, 0x0000229B, 0x00000001, + 0x00050085, 0x0000000D, 0x0000363C, 0x00005C27, 0x00005C27, 0x00050081, 0x0000000D, 0x00005376, + 0x00005F83, 0x0000363C, 0x0007000C, 0x0000000D, 0x00002ADA, 0x00000001, 0x00000025, 0x00005376, + 0x00004005, 0x00050085, 0x0000000D, 0x00002766, 0x00000A93, 0x00002ADA, 0x00050081, 0x0000000D, + 0x00005463, 0x00002766, 0x00000341, 0x00050085, 0x0000000D, 0x000024EB, 0x00002433, 0x00002ADA, + 0x00050081, 0x0000000D, 0x0000473E, 0x000024EB, 0x00000341, 0x00050085, 0x0000000D, 0x00002237, + 0x00005463, 0x00005463, 0x00050085, 0x0000000D, 0x00005BEC, 0x0000473E, 0x0000473E, 0x00050085, + 0x0000000D, 0x0000524D, 0x000004B3, 0x00002237, 0x00050081, 0x0000000D, 0x00003B4A, 0x0000524D, + 0x000000B4, 0x00050085, 0x0000000D, 0x00001BD5, 0x00003B4A, 0x00005BEC, 0x0005008E, 0x00000018, + 0x00001E14, 0x00003DEE, 0x00001BD5, 0x00050081, 0x00000018, 0x00001B32, 0x00001B31, 0x00001E14, + 0x00050081, 0x0000000D, 0x00001A77, 0x00001A76, 0x00001BD5, 0x00050083, 0x00000013, 0x0000439C, + 0x00000139, 0x00005449, 0x00050051, 0x0000000D, 0x00001AF2, 0x000028C1, 0x00000002, 0x00050051, + 0x0000000D, 0x00003D47, 0x000028C2, 0x00000002, 0x00050051, 0x0000000D, 0x00001EA1, 0x000047E7, + 0x00000002, 0x00060050, 0x00000018, 0x000041CF, 0x00001AF2, 0x00003D47, 0x00001EA1, 0x00050051, + 0x0000000D, 0x00004646, 0x0000439C, 0x00000000, 0x00050085, 0x0000000D, 0x00004341, 0x00004646, + 0x000033B8, 0x00050051, 0x0000000D, 0x00005C28, 0x0000439C, 0x00000001, 0x00050085, 0x0000000D, + 0x00003F12, 0x00005C28, 0x00005C12, 0x00050081, 0x0000000D, 0x00002E23, 0x00004341, 0x00003F12, + 0x00050085, 0x0000000D, 0x000021EB, 0x00004646, 0x00004D37, 0x00050085, 0x0000000D, 0x00005AFD, + 0x00005C28, 0x000033B8, 0x00050081, 0x0000000D, 0x00005E71, 0x000021EB, 0x00005AFD, 0x00050050, + 0x00000013, 0x00002661, 0x00002E23, 0x00005E71, 0x00050085, 0x00000013, 0x0000229C, 0x00002661, + 0x000029E7, 0x00050051, 0x0000000D, 0x00006202, 0x0000229C, 0x00000000, 0x00050085, 0x0000000D, + 0x00005F84, 0x00006202, 0x00006202, 0x00050051, 0x0000000D, 0x00005C29, 0x0000229C, 0x00000001, + 0x00050085, 0x0000000D, 0x0000363D, 0x00005C29, 0x00005C29, 0x00050081, 0x0000000D, 0x00005377, + 0x00005F84, 0x0000363D, 0x0007000C, 0x0000000D, 0x00002ADB, 0x00000001, 0x00000025, 0x00005377, + 0x00004005, 0x00050085, 0x0000000D, 0x00002767, 0x00000A93, 0x00002ADB, 0x00050081, 0x0000000D, + 0x00005464, 0x00002767, 0x00000341, 0x00050085, 0x0000000D, 0x000024EC, 0x00002433, 0x00002ADB, + 0x00050081, 0x0000000D, 0x0000473F, 0x000024EC, 0x00000341, 0x00050085, 0x0000000D, 0x00002238, + 0x00005464, 0x00005464, 0x00050085, 0x0000000D, 0x00005BED, 0x0000473F, 0x0000473F, 0x00050085, + 0x0000000D, 0x0000524E, 0x000004B3, 0x00002238, 0x00050081, 0x0000000D, 0x00003B4B, 0x0000524E, + 0x000000B4, 0x00050085, 0x0000000D, 0x00001BD6, 0x00003B4B, 0x00005BED, 0x0005008E, 0x00000018, + 0x00001E15, 0x000041CF, 0x00001BD6, 0x00050081, 0x00000018, 0x00001B33, 0x00001B32, 0x00001E15, + 0x00050081, 0x0000000D, 0x00001A78, 0x00001A77, 0x00001BD6, 0x00050083, 0x00000013, 0x0000439D, + 0x0000071F, 0x00005449, 0x00050051, 0x0000000D, 0x00001AF3, 0x000028C1, 0x00000003, 0x00050051, + 0x0000000D, 0x00003D48, 0x000028C2, 0x00000003, 0x00050051, 0x0000000D, 0x00001EA2, 0x000047E7, + 0x00000003, 0x00060050, 0x00000018, 0x000041D0, 0x00001AF3, 0x00003D48, 0x00001EA2, 0x00050051, + 0x0000000D, 0x00004647, 0x0000439D, 0x00000000, 0x00050085, 0x0000000D, 0x00004342, 0x00004647, + 0x000033B8, 0x00050051, 0x0000000D, 0x00005C2A, 0x0000439D, 0x00000001, 0x00050085, 0x0000000D, + 0x00003F13, 0x00005C2A, 0x00005C12, 0x00050081, 0x0000000D, 0x00002E24, 0x00004342, 0x00003F13, + 0x00050085, 0x0000000D, 0x000021EC, 0x00004647, 0x00004D37, 0x00050085, 0x0000000D, 0x00005AFE, + 0x00005C2A, 0x000033B8, 0x00050081, 0x0000000D, 0x00005E72, 0x000021EC, 0x00005AFE, 0x00050050, + 0x00000013, 0x00002662, 0x00002E24, 0x00005E72, 0x00050085, 0x00000013, 0x0000229D, 0x00002662, + 0x000029E7, 0x00050051, 0x0000000D, 0x00006203, 0x0000229D, 0x00000000, 0x00050085, 0x0000000D, + 0x00005F85, 0x00006203, 0x00006203, 0x00050051, 0x0000000D, 0x00005C2B, 0x0000229D, 0x00000001, + 0x00050085, 0x0000000D, 0x0000363E, 0x00005C2B, 0x00005C2B, 0x00050081, 0x0000000D, 0x00005378, + 0x00005F85, 0x0000363E, 0x0007000C, 0x0000000D, 0x00002ADC, 0x00000001, 0x00000025, 0x00005378, + 0x00004005, 0x00050085, 0x0000000D, 0x00002768, 0x00000A93, 0x00002ADC, 0x00050081, 0x0000000D, + 0x00005465, 0x00002768, 0x00000341, 0x00050085, 0x0000000D, 0x000024ED, 0x00002433, 0x00002ADC, + 0x00050081, 0x0000000D, 0x00004740, 0x000024ED, 0x00000341, 0x00050085, 0x0000000D, 0x00002239, + 0x00005465, 0x00005465, 0x00050085, 0x0000000D, 0x00005BEE, 0x00004740, 0x00004740, 0x00050085, + 0x0000000D, 0x0000524F, 0x000004B3, 0x00002239, 0x00050081, 0x0000000D, 0x00003B4C, 0x0000524F, + 0x000000B4, 0x00050085, 0x0000000D, 0x00001BD7, 0x00003B4C, 0x00005BEE, 0x0005008E, 0x00000018, + 0x00001E16, 0x000041D0, 0x00001BD7, 0x00050081, 0x00000018, 0x00001B89, 0x00001B33, 0x00001E16, + 0x00050081, 0x0000000D, 0x0000617B, 0x00001A78, 0x00001BD7, 0x00050088, 0x0000000D, 0x00003D1A, + 0x0000008A, 0x0000617B, 0x00060050, 0x00000018, 0x00003F3D, 0x00003D1A, 0x00003D1A, 0x00003D1A, + 0x00050085, 0x00000018, 0x000042EC, 0x00001B89, 0x00003F3D, 0x0007000C, 0x00000018, 0x00004657, + 0x00000001, 0x00000028, 0x00002952, 0x000042EC, 0x0007000C, 0x00000018, 0x0000309B, 0x00000001, + 0x00000025, 0x00004A0F, 0x00004657, 0x00050041, 0x0000028B, 0x00002642, 0x00001691, 0x00000A0A, + 0x00050051, 0x0000000D, 0x000060DB, 0x0000309B, 0x00000000, 0x0003003E, 0x00002642, 0x000060DB, + 0x00050041, 0x0000028B, 0x00003FFA, 0x00001691, 0x00000A0D, 0x00050051, 0x0000000D, 0x00003D82, + 0x0000309B, 0x00000001, 0x0003003E, 0x00003FFA, 0x00003D82, 0x00050041, 0x0000028B, 0x00003FFB, + 0x00001691, 0x00000A10, 0x00050051, 0x0000000D, 0x00003D83, 0x0000309B, 0x00000002, 0x0003003E, + 0x00003FFB, 0x00003D83, 0x00050041, 0x0000028B, 0x00005AFF, 0x00001691, 0x00000A13, 0x0003003E, + 0x00005AFF, 0x0000008A, 0x000100FD, 0x00010038, +}; diff --git a/src/ui/shaders/vulkan_spirv/guest_output_ffx_fsr_rcas_dither_ps.h b/src/ui/shaders/vulkan_spirv/guest_output_ffx_fsr_rcas_dither_ps.h new file mode 100644 index 0000000..6875d31 --- /dev/null +++ b/src/ui/shaders/vulkan_spirv/guest_output_ffx_fsr_rcas_dither_ps.h @@ -0,0 +1,768 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25152 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %5663 "main" %gl_FragCoord %3253 + OpExecutionMode %5663 OriginUpperLeft + OpDecorate %gl_FragCoord BuiltIn FragCoord + OpDecorate %_struct_1010 Block + OpMemberDecorate %_struct_1010 0 Offset 16 + OpMemberDecorate %_struct_1010 1 Offset 24 + OpDecorate %3253 Location 0 + OpDecorate %3575 Binding 0 + OpDecorate %3575 DescriptorSet 0 + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %float = OpTypeFloat 32 +%_ptr_Function_float = OpTypePointer Function %float + %v3float = OpTypeVector %float 3 + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v4float = OpTypeVector %float 4 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 + %uint_15 = OpConstant %uint 15 + %uint_256 = OpConstant %uint 256 +%_arr_float_uint_256 = OpTypeArray %float %uint_256 +%float_n0_00100337015 = OpConstant %float -0.00100337015 +%float_0_000880821084 = OpConstant %float 0.000880821084 +%float_0_00169270835 = OpConstant %float 0.00169270835 +%float_n0_00155484071 = OpConstant %float -0.00155484071 +%float_0_00127910543 = OpConstant %float 0.00127910543 +%float_n0_000605085806 = OpConstant %float -0.000605085806 +%float_0_00106464466 = OpConstant %float 0.00106464466 +%float_n0_00138633582 = OpConstant %float -0.00138633582 +%float_0_00135569857 = OpConstant %float 0.00135569857 +%float_0_000513174047 = OpConstant %float 0.000513174047 +%float_0_00121783093 = OpConstant %float 0.00121783093 +%float_n0_00160079659 = OpConstant %float -0.00160079659 +%float_0_00058976718 = OpConstant %float 0.00058976718 +%float_n0_00028339462 = OpConstant %float -0.00028339462 +%float_0_00111060054 = OpConstant %float 0.00111060054 +%float_n0_00141697307 = OpConstant %float -0.00141697307 +%float_0_00144761032 = OpConstant %float 0.00144761032 +%float_n0_0005438113 = OpConstant %float -0.0005438113 +%float_0_00013020834 = OpConstant %float 0.00013020834 +%float_n0_0012025123 = OpConstant %float -0.0012025123 +%float_0_000436580885 = OpConstant %float 0.000436580885 +%float_n0_00104932603 = OpConstant %float -0.00104932603 +%float_0_000620404433 = OpConstant %float 0.000620404433 +%float_n0_000482536765 = OpConstant %float -0.000482536765 +%float_0_00187653187 = OpConstant %float 0.00187653187 +%float_n0_00109528191 = OpConstant %float -0.00109528191 +%float_n9_95710798en05 = OpConstant %float -9.95710798e-05 +%float_n0_000528492674 = OpConstant %float -0.000528492674 +%float_0_0014322917 = OpConstant %float 0.0014322917 +%float_n0_00193780637 = OpConstant %float -0.00193780637 +%float_n0_000696997566 = OpConstant %float -0.000696997566 +%float_3_829657en05 = OpConstant %float 3.829657e-05 +%float_0_000712316192 = OpConstant %float 0.000712316192 +%float_n0_00130974269 = OpConstant %float -0.00130974269 +%float_0_00109528191 = OpConstant %float 0.00109528191 +%float_n0_000298713247 = OpConstant %float -0.000298713247 +%float_0_00175398286 = OpConstant %float 0.00175398286 +%float_n0_00167738972 = OpConstant %float -0.00167738972 +%float_0_00147824758 = OpConstant %float 0.00147824758 +%float_n3_829657en05 = OpConstant %float -3.829657e-05 +%float_0_000788909325 = OpConstant %float 0.000788909325 +%float_n0_00183057599 = OpConstant %float -0.00183057599 +%float_0_000298713247 = OpConstant %float 0.000298713247 +%float_0_000988051528 = OpConstant %float 0.000988051528 +%float_n0_00117187505 = OpConstant %float -0.00117187505 +%float_0_00017616422 = OpConstant %float 0.00017616422 +%float_0_00164675247 = OpConstant %float 0.00164675247 +%float_n0_00158547796 = OpConstant %float -0.00158547796 +%float_0_000344669126 = OpConstant %float 0.000344669126 +%float_0_00186121324 = OpConstant %float 0.00186121324 +%float_n0_00176930148 = OpConstant %float -0.00176930148 +%float_n0_000865502458 = OpConstant %float -0.000865502458 +%float_0_000896139711 = OpConstant %float 0.000896139711 +%float_0_000160845593 = OpConstant %float 0.000160845593 +%float_n0_000926776964 = OpConstant %float -0.000926776964 +%float_n0_00152420346 = OpConstant %float -0.00152420346 +%float_n0_000651041686 = OpConstant %float -0.000651041686 +%float_0_00129442406 = OpConstant %float 0.00129442406 +%float_n0_000804227951 = OpConstant %float -0.000804227951 +%float_n0_00146292895 = OpConstant %float -0.00146292895 +%float_0_00179993873 = OpConstant %float 0.00179993873 +%float_n0_000850183831 = OpConstant %float -0.000850183831 +%float_0_000850183831 = OpConstant %float 0.000850183831 +%float_n0_000451899512 = OpConstant %float -0.000451899512 +%float_n0_00106464466 = OpConstant %float -0.00106464466 +%float_n0_000145526967 = OpConstant %float -0.000145526967 +%float_0_000237438726 = OpConstant %float 0.000237438726 +%float_0_00141697307 = OpConstant %float 0.00141697307 +%float_n0_00058976718 = OpConstant %float -0.00058976718 +%float_n0_000191482846 = OpConstant %float -0.000191482846 +%float_0_00160079659 = OpConstant %float 0.00160079659 +%float_0_00101868878 = OpConstant %float 0.00101868878 +%float_0_000405943632 = OpConstant %float 0.000405943632 +%float_n0_000206801473 = OpConstant %float -0.000206801473 +%float_0_00158547796 = OpConstant %float 0.00158547796 +%float_0_000651041686 = OpConstant %float 0.000651041686 +%float_n6_89338267en05 = OpConstant %float -6.89338267e-05 +%float_0_000421262259 = OpConstant %float 0.000421262259 +%float_n0_00164675247 = OpConstant %float -0.00164675247 +%float_0_00137101719 = OpConstant %float 0.00137101719 +%float_0_000926776964 = OpConstant %float 0.000926776964 +%float_n0_000666360313 = OpConstant %float -0.000666360313 +%float_0_00118719367 = OpConstant %float 0.00118719367 +%float_n0_00144761032 = OpConstant %float -0.00144761032 +%float_0_000574448553 = OpConstant %float 0.000574448553 +%float_n0_00189185049 = OpConstant %float -0.00189185049 +%float_0_000758272072 = OpConstant %float 0.000758272072 +%float_n0_00129442406 = OpConstant %float -0.00129442406 +%float_0_00192248775 = OpConstant %float 0.00192248775 +%float_n0_0016620711 = OpConstant %float -0.0016620711 +%float_n0_00103400741 = OpConstant %float -0.00103400741 +%float_n0_000497855421 = OpConstant %float -0.000497855421 +%float_n0_00186121324 = OpConstant %float -0.00186121324 +%float_0_0012025123 = OpConstant %float 0.0012025123 +%float_n0_0003293505 = OpConstant %float -0.0003293505 +%float_n0_00137101719 = OpConstant %float -0.00137101719 +%float_0_00163143384 = OpConstant %float 0.00163143384 +%float_n0_00184589461 = OpConstant %float -0.00184589461 +%float_0_000727634819 = OpConstant %float 0.000727634819 +%float_n0_000911458337 = OpConstant %float -0.000911458337 +%float_0_00181525736 = OpConstant %float 0.00181525736 +%float_n0_00114123779 = OpConstant %float -0.00114123779 +%float_n0_000375306379 = OpConstant %float -0.000375306379 +%float_9_95710798en05 = OpConstant %float 9.95710798e-05 +%float_n0_000742953445 = OpConstant %float -0.000742953445 +%float_0_00117187505 = OpConstant %float 0.00117187505 +%float_6_89338267en05 = OpConstant %float 6.89338267e-05 +%float_0_0014935662 = OpConstant %float 0.0014935662 +%float_0_000972732843 = OpConstant %float 0.000972732843 +%float_n0_000957414217 = OpConstant %float -0.000957414217 +%float_0_00193780637 = OpConstant %float 0.00193780637 +%float_0_000528492674 = OpConstant %float 0.000528492674 +%float_5_36151965en05 = OpConstant %float 5.36151965e-05 +%float_n0_00124846818 = OpConstant %float -0.00124846818 +%float_n0_000268075994 = OpConstant %float -0.000268075994 +%float_0_00153952208 = OpConstant %float 0.00153952208 +%float_n7_65931418en06 = OpConstant %float -7.65931418e-06 +%float_0_000314031873 = OpConstant %float 0.000314031873 +%float_0_00134037994 = OpConstant %float 0.00134037994 +%float_n0_00175398286 = OpConstant %float -0.00175398286 +%float_0_000497855421 = OpConstant %float 0.000497855421 +%float_n0_00118719367 = OpConstant %float -0.00118719367 +%float_0_000773590698 = OpConstant %float 0.000773590698 +%float_n0_00134037994 = OpConstant %float -0.00134037994 +%float_0_000268075994 = OpConstant %float 0.000268075994 +%float_n0_00147824758 = OpConstant %float -0.00147824758 +%float_n0_00013020834 = OpConstant %float -0.00013020834 +%float_n0_000773590698 = OpConstant %float -0.000773590698 +%float_0_00130974269 = OpConstant %float 0.00130974269 +%float_0_000390625006 = OpConstant %float 0.000390625006 +%float_0_000957414217 = OpConstant %float 0.000957414217 +%float_n0_000467218139 = OpConstant %float -0.000467218139 +%float_n0_00153952208 = OpConstant %float -0.00153952208 +%float_0_00103400741 = OpConstant %float 0.00103400741 +%float_n0_000681678939 = OpConstant %float -0.000681678939 +%float_0_00167738972 = OpConstant %float 0.00167738972 +%float_0_00100337015 = OpConstant %float 0.00100337015 +%float_n0_000421262259 = OpConstant %float -0.000421262259 +%float_0_00178462011 = OpConstant %float 0.00178462011 +%float_n0_000237438726 = OpConstant %float -0.000237438726 +%float_n0_000620404433 = OpConstant %float -0.000620404433 +%float_0_0016620711 = OpConstant %float 0.0016620711 +%float_0_000834865205 = OpConstant %float 0.000834865205 +%float_n0_0017233456 = OpConstant %float -0.0017233456 +%float_n0_00107996329 = OpConstant %float -0.00107996329 +%float_0_00176930148 = OpConstant %float 0.00176930148 +%float_n0_000788909325 = OpConstant %float -0.000788909325 +%float_n0_00178462011 = OpConstant %float -0.00178462011 +%float_0_000681678939 = OpConstant %float 0.000681678939 +%float_n0_000988051528 = OpConstant %float -0.000988051528 +%float_n0_00132506131 = OpConstant %float -0.00132506131 +%float_n0_00017616422 = OpConstant %float -0.00017616422 +%float_n0_00150888483 = OpConstant %float -0.00150888483 +%float_0_0003293505 = OpConstant %float 0.0003293505 +%float_n0_001953125 = OpConstant %float -0.001953125 +%float_0_000666360313 = OpConstant %float 0.000666360313 +%float_n0_00161611522 = OpConstant %float -0.00161611522 +%float_0_00115655642 = OpConstant %float 0.00115655642 +%float_0_000451899512 = OpConstant %float 0.000451899512 +%float_n0_000436580885 = OpConstant %float -0.000436580885 +%float_0_000191482846 = OpConstant %float 0.000191482846 +%float_n0_0014935662 = OpConstant %float -0.0014935662 +%float_0_00114123779 = OpConstant %float 0.00114123779 +%float_8_42524532en05 = OpConstant %float 8.42524532e-05 +%float_0_00189185049 = OpConstant %float 0.00189185049 +%float_0_00140165444 = OpConstant %float 0.00140165444 +%float_0_000559129927 = OpConstant %float 0.000559129927 +%float_0_000114889706 = OpConstant %float 0.000114889706 +%float_0_00126378681 = OpConstant %float 0.00126378681 +%float_n0_000574448553 = OpConstant %float -0.000574448553 +%float_n0_000972732843 = OpConstant %float -0.000972732843 +%float_0_00132506131 = OpConstant %float 0.00132506131 +%float_0_000222120099 = OpConstant %float 0.000222120099 +%float_n0_000758272072 = OpConstant %float -0.000758272072 +%float_n0_00135569857 = OpConstant %float -0.00135569857 +%float_0_00146292895 = OpConstant %float 0.00146292895 +%float_0_000865502458 = OpConstant %float 0.000865502458 +%float_n0_000359987753 = OpConstant %float -0.000359987753 +%float_0_0005438113 = OpConstant %float 0.0005438113 +%float_n0_00112591917 = OpConstant %float -0.00112591917 +%float_n0_000252757367 = OpConstant %float -0.000252757367 +%float_n0_000559129927 = OpConstant %float -0.000559129927 +%float_n0_00181525736 = OpConstant %float -0.00181525736 +%float_0_0017233456 = OpConstant %float 0.0017233456 +%float_n0_00115655642 = OpConstant %float -0.00115655642 +%float_0_000742953445 = OpConstant %float 0.000742953445 +%float_0_00157015934 = OpConstant %float 0.00157015934 +%float_n0_000114889706 = OpConstant %float -0.000114889706 +%float_n0_00121783093 = OpConstant %float -0.00121783093 +%float_0_00183057599 = OpConstant %float 0.00183057599 +%float_2_29779416en05 = OpConstant %float 2.29779416e-05 +%float_n0_00192248775 = OpConstant %float -0.00192248775 +%float_0_00173866423 = OpConstant %float 0.00173866423 +%float_n0_000712316192 = OpConstant %float -0.000712316192 +%float_0_00155484071 = OpConstant %float 0.00155484071 +%float_n0_00170802698 = OpConstant %float -0.00170802698 +%float_0_00123314955 = OpConstant %float 0.00123314955 +%float_0_000206801473 = OpConstant %float 0.000206801473 +%float_0_00104932603 = OpConstant %float 0.00104932603 +%float_n0_000727634819 = OpConstant %float -0.000727634819 +%float_n0_00163143384 = OpConstant %float -0.00163143384 +%float_n0_000314031873 = OpConstant %float -0.000314031873 +%float_0_000482536765 = OpConstant %float 0.000482536765 +%float_n0_00179993873 = OpConstant %float -0.00179993873 +%float_0_00094209559 = OpConstant %float 0.00094209559 +%float_n0_000344669126 = OpConstant %float -0.000344669126 +%float_0_000696997566 = OpConstant %float 0.000696997566 +%float_n0_00101868878 = OpConstant %float -0.00101868878 +%float_n0_00157015934 = OpConstant %float -0.00157015934 +%float_n2_29779416en05 = OpConstant %float -2.29779416e-05 +%float_n0_00127910543 = OpConstant %float -0.00127910543 +%float_0_000804227951 = OpConstant %float 0.000804227951 +%float_n0_000896139711 = OpConstant %float -0.000896139711 +%float_n0_0014322917 = OpConstant %float -0.0014322917 +%float_0_000605085806 = OpConstant %float 0.000605085806 +%float_n8_42524532en05 = OpConstant %float -8.42524532e-05 +%float_0_000911458337 = OpConstant %float 0.000911458337 +%float_0_001953125 = OpConstant %float 0.001953125 +%float_n0_00140165444 = OpConstant %float -0.00140165444 +%float_n0_00063572306 = OpConstant %float -0.00063572306 +%float_0_00150888483 = OpConstant %float 0.00150888483 +%float_n0_000819546578 = OpConstant %float -0.000819546578 +%float_0_00124846818 = OpConstant %float 0.00124846818 +%float_0_000252757367 = OpConstant %float 0.000252757367 +%float_0_00152420346 = OpConstant %float 0.00152420346 +%float_0_00112591917 = OpConstant %float 0.00112591917 +%float_0_000359987753 = OpConstant %float 0.000359987753 +%float_n0_000390625006 = OpConstant %float -0.000390625006 +%float_0_00190716912 = OpConstant %float 0.00190716912 +%float_0_00138633582 = OpConstant %float 0.00138633582 +%float_n0_00111060054 = OpConstant %float -0.00111060054 +%float_0_00161611522 = OpConstant %float 0.00161611522 +%float_n0_000880821084 = OpConstant %float -0.000880821084 +%float_0_000145526967 = OpConstant %float 0.000145526967 +%float_0_00107996329 = OpConstant %float 0.00107996329 +%float_n5_36151965en05 = OpConstant %float -5.36151965e-05 +%float_0_00028339462 = OpConstant %float 0.00028339462 +%float_n0_00169270835 = OpConstant %float -0.00169270835 +%float_n0_00126378681 = OpConstant %float -0.00126378681 +%float_n0_000513174047 = OpConstant %float -0.000513174047 +%float_n0_000160845593 = OpConstant %float -0.000160845593 +%float_n0_00187653187 = OpConstant %float -0.00187653187 +%float_n0_000834865205 = OpConstant %float -0.000834865205 +%float_0_00063572306 = OpConstant %float 0.00063572306 +%float_7_65931418en06 = OpConstant %float 7.65931418e-06 +%float_n0_00190716912 = OpConstant %float -0.00190716912 +%float_n0_000222120099 = OpConstant %float -0.000222120099 +%float_0_000375306379 = OpConstant %float 0.000375306379 +%float_n0_00173866423 = OpConstant %float -0.00173866423 +%float_n0_000405943632 = OpConstant %float -0.000405943632 +%float_n0_00123314955 = OpConstant %float -0.00123314955 +%float_0_00170802698 = OpConstant %float 0.00170802698 +%float_n0_00094209559 = OpConstant %float -0.00094209559 +%float_0_000819546578 = OpConstant %float 0.000819546578 +%float_0_00184589461 = OpConstant %float 0.00184589461 +%float_0_000467218139 = OpConstant %float 0.000467218139 + %2212 = OpConstantComposite %_arr_float_uint_256 %float_n0_00100337015 %float_0_000880821084 %float_0_00169270835 %float_n0_00155484071 %float_0_00127910543 %float_n0_000605085806 %float_0_00106464466 %float_n0_00138633582 %float_0_00135569857 %float_0_000513174047 %float_0_00121783093 %float_n0_00160079659 %float_0_00058976718 %float_n0_00028339462 %float_0_00111060054 %float_n0_00141697307 %float_0_00144761032 %float_n0_0005438113 %float_0_00013020834 %float_n0_0012025123 %float_0_000436580885 %float_n0_00104932603 %float_0_000620404433 %float_n0_000482536765 %float_0_00187653187 %float_n0_00109528191 %float_n9_95710798en05 %float_n0_000528492674 %float_0_0014322917 %float_n0_00193780637 %float_n0_000696997566 %float_3_829657en05 %float_0_000712316192 %float_n0_00130974269 %float_0_00109528191 %float_n0_000298713247 %float_0_00175398286 %float_n0_00167738972 %float_0_00147824758 %float_n3_829657en05 %float_0_000788909325 %float_n0_00183057599 %float_0_000298713247 %float_0_000988051528 %float_n0_00117187505 %float_0_00017616422 %float_0_00164675247 %float_n0_00158547796 %float_0_000344669126 %float_0_00186121324 %float_n0_00176930148 %float_n0_000865502458 %float_0_000896139711 %float_0_000160845593 %float_n0_000926776964 %float_n0_00152420346 %float_n0_000651041686 %float_0_00129442406 %float_n0_000804227951 %float_n0_00146292895 %float_0_00179993873 %float_n0_000850183831 %float_0_000850183831 %float_n0_000451899512 %float_n0_00106464466 %float_n0_000145526967 %float_0_000237438726 %float_0_00141697307 %float_n0_00058976718 %float_n0_000191482846 %float_0_00160079659 %float_0_00101868878 %float_0_000405943632 %float_n0_000206801473 %float_0_00158547796 %float_0_000651041686 %float_n6_89338267en05 %float_0_000421262259 %float_n0_00164675247 %float_0_00137101719 %float_0_000926776964 %float_n0_000666360313 %float_0_00118719367 %float_n0_00144761032 %float_0_000574448553 %float_n0_00189185049 %float_0_000758272072 %float_n0_00129442406 %float_0_00192248775 %float_n0_0016620711 %float_n0_00103400741 %float_n0_000497855421 %float_n0_00186121324 %float_0_0012025123 %float_n0_0003293505 %float_n0_00137101719 %float_0_00163143384 %float_n0_00184589461 %float_0_000727634819 %float_n0_000911458337 %float_0_00181525736 %float_n0_00114123779 %float_n0_000375306379 %float_9_95710798en05 %float_n0_000742953445 %float_0_00117187505 %float_6_89338267en05 %float_0_0014935662 %float_0_000972732843 %float_n0_000957414217 %float_0_00193780637 %float_0_000528492674 %float_5_36151965en05 %float_n0_00124846818 %float_n0_000268075994 %float_0_00153952208 %float_n7_65931418en06 %float_0_000314031873 %float_0_00134037994 %float_n0_00175398286 %float_0_000497855421 %float_n0_00118719367 %float_0_000773590698 %float_n0_00134037994 %float_0_000268075994 %float_n0_00147824758 %float_n0_00013020834 %float_n0_000773590698 %float_0_00130974269 %float_0_000390625006 %float_0_000957414217 %float_n0_000467218139 %float_n0_00153952208 %float_0_00103400741 %float_n0_000681678939 %float_0_00167738972 %float_0_00100337015 %float_n0_000421262259 %float_0_00178462011 %float_n0_000237438726 %float_n0_000620404433 %float_0_0016620711 %float_0_000834865205 %float_n0_0017233456 %float_n0_00107996329 %float_0_00176930148 %float_n0_000788909325 %float_n0_00178462011 %float_0_000681678939 %float_n0_000988051528 %float_n0_00132506131 %float_n0_00017616422 %float_n0_00150888483 %float_0_0003293505 %float_n0_001953125 %float_0_000666360313 %float_n0_00161611522 %float_0_00115655642 %float_0_000451899512 %float_n0_000436580885 %float_0_000191482846 %float_n0_0014935662 %float_0_00114123779 %float_8_42524532en05 %float_0_00189185049 %float_0_00140165444 %float_0_000559129927 %float_0_000114889706 %float_0_00126378681 %float_n0_000574448553 %float_n0_000972732843 %float_0_00132506131 %float_0_000222120099 %float_n0_000758272072 %float_n0_00135569857 %float_0_00146292895 %float_0_000865502458 %float_n0_000359987753 %float_0_0005438113 %float_n0_00112591917 %float_n0_000252757367 %float_n0_000559129927 %float_n0_00181525736 %float_0_0017233456 %float_n0_00115655642 %float_0_000742953445 %float_0_00157015934 %float_n0_000114889706 %float_n0_00121783093 %float_0_00183057599 %float_2_29779416en05 %float_n0_00192248775 %float_0_00173866423 %float_n0_000712316192 %float_0_00155484071 %float_n0_00170802698 %float_0_00123314955 %float_0_000206801473 %float_0_00104932603 %float_n0_000727634819 %float_n0_00163143384 %float_n0_000314031873 %float_0_000482536765 %float_n0_00179993873 %float_0_00094209559 %float_n0_000344669126 %float_0_000696997566 %float_n0_00101868878 %float_n0_00157015934 %float_n2_29779416en05 %float_n0_00127910543 %float_0_000804227951 %float_n0_000896139711 %float_n0_0014322917 %float_0_000605085806 %float_n8_42524532en05 %float_0_000911458337 %float_0_001953125 %float_n0_00140165444 %float_n0_00063572306 %float_0_00150888483 %float_n0_000819546578 %float_0_00124846818 %float_0_000252757367 %float_0_00152420346 %float_0_00112591917 %float_0_000359987753 %float_n0_000390625006 %float_0_00190716912 %float_0_00138633582 %float_n0_00111060054 %float_0_00161611522 %float_n0_000880821084 %float_0_000145526967 %float_0_00107996329 %float_n5_36151965en05 %float_0_00028339462 %float_n0_00169270835 %float_n0_00126378681 %float_n0_000513174047 %float_n0_000160845593 %float_n0_00187653187 %float_n0_000834865205 %float_0_00063572306 %float_7_65931418en06 %float_n0_00190716912 %float_n0_000222120099 %float_0_000375306379 %float_n0_00173866423 %float_n0_000405943632 %float_n0_00123314955 %float_0_00170802698 %float_n0_00094209559 %float_0_000819546578 %float_0_00184589461 %float_0_000467218139 + %uint_16 = OpConstant %uint 16 +%_ptr_Function__arr_float_uint_256 = OpTypePointer Function %_arr_float_uint_256 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%gl_FragCoord = OpVariable %_ptr_Input_v4float Input + %v2float = OpTypeVector %float 2 +%_struct_1010 = OpTypeStruct %v2int %float +%_ptr_PushConstant__struct_1010 = OpTypePointer PushConstant %_struct_1010 + %3305 = OpVariable %_ptr_PushConstant__struct_1010 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_v2int = OpTypePointer PushConstant %v2int + %int_1 = OpConstant %int 1 +%_ptr_PushConstant_float = OpTypePointer PushConstant %float +%_ptr_Output_v4float = OpTypePointer Output %v4float + %3253 = OpVariable %_ptr_Output_v4float Output +%uint_2129764351 = OpConstant %uint 2129764351 + %float_2 = OpConstant %float 2 + %151 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_151 = OpTypePointer UniformConstant %151 + %3575 = OpVariable %_ptr_UniformConstant_151 UniformConstant + %int_n1 = OpConstant %int -1 + %1803 = OpConstantComposite %v2int %int_0 %int_n1 + %1806 = OpConstantComposite %v2int %int_n1 %int_0 + %1824 = OpConstantComposite %v2int %int_1 %int_0 + %1827 = OpConstantComposite %v2int %int_0 %int_1 + %float_n4 = OpConstant %float -4 + %float_4 = OpConstant %float 4 +%float_n0_1875 = OpConstant %float -0.1875 + %2122 = OpConstantComposite %v2uint %uint_15 %uint_15 + %2604 = OpConstantComposite %v3float %float_0 %float_0 %float_0 + %2582 = OpConstantComposite %v3float %float_1 %float_1 %float_1 + %float_0_25 = OpConstant %float 0.25 + %10264 = OpUndef %v4float + %5663 = OpFunction %void None %1282 + %24953 = OpLabel + %18411 = OpVariable %_ptr_Function__arr_float_uint_256 Function + %22087 = OpLoad %v4float %gl_FragCoord + %6562 = OpVectorShuffle %v2float %22087 %22087 0 1 + %17656 = OpConvertFToS %v2int %6562 + %19279 = OpAccessChain %_ptr_PushConstant_v2int %3305 %int_0 + %22822 = OpLoad %v2int %19279 + %23312 = OpISub %v2int %17656 %22822 + %9938 = OpBitcast %v2uint %23312 + %20997 = OpAccessChain %_ptr_PushConstant_float %3305 %int_1 + %22237 = OpLoad %float %20997 + %16454 = OpBitcast %uint %22237 + %6990 = OpBitcast %v2int %9938 + %14365 = OpIAdd %v2int %6990 %1803 + %22164 = OpLoad %151 %3575 + %8899 = OpImageFetch %v4float %22164 %14365 Lod %int_0 + %19729 = OpCompositeExtract %float %8899 0 + %6930 = OpCompositeExtract %float %8899 1 + %18220 = OpCompositeExtract %float %8899 2 + %20349 = OpIAdd %v2int %6990 %1806 + %16541 = OpLoad %151 %3575 + %8900 = OpImageFetch %v4float %16541 %20349 Lod %int_0 + %19730 = OpCompositeExtract %float %8900 0 + %24728 = OpCompositeExtract %float %8900 1 + %11386 = OpCompositeExtract %float %8900 2 + %16530 = OpLoad %151 %3575 + %19121 = OpImageFetch %v4float %16530 %6990 Lod %int_0 + %19731 = OpCompositeExtract %float %19121 0 + %6931 = OpCompositeExtract %float %19121 1 + %18221 = OpCompositeExtract %float %19121 2 + %20350 = OpIAdd %v2int %6990 %1824 + %16542 = OpLoad %151 %3575 + %8901 = OpImageFetch %v4float %16542 %20350 Lod %int_0 + %19732 = OpCompositeExtract %float %8901 0 + %6932 = OpCompositeExtract %float %8901 1 + %18222 = OpCompositeExtract %float %8901 2 + %20351 = OpIAdd %v2int %6990 %1827 + %16543 = OpLoad %151 %3575 + %8902 = OpImageFetch %v4float %16543 %20351 Lod %int_0 + %19733 = OpCompositeExtract %float %8902 0 + %23834 = OpCompositeExtract %float %8902 1 + %6945 = OpCompositeExtract %float %8902 2 + %15372 = OpExtInst %float %1 FMin %19730 %19732 + %25151 = OpExtInst %float %1 FMin %19729 %15372 + %15948 = OpExtInst %float %1 FMin %25151 %19733 + %15949 = OpExtInst %float %1 FMin %24728 %6932 + %15950 = OpExtInst %float %1 FMin %6930 %15949 + %15951 = OpExtInst %float %1 FMin %15950 %23834 + %15952 = OpExtInst %float %1 FMin %11386 %18222 + %15953 = OpExtInst %float %1 FMin %18220 %15952 + %10905 = OpExtInst %float %1 FMin %15953 %6945 + %24296 = OpExtInst %float %1 FMax %19730 %19732 + %17523 = OpExtInst %float %1 FMax %19729 %24296 + %21851 = OpExtInst %float %1 FMax %17523 %19733 + %21852 = OpExtInst %float %1 FMax %24728 %6932 + %21853 = OpExtInst %float %1 FMax %6930 %21852 + %21854 = OpExtInst %float %1 FMax %21853 %23834 + %21855 = OpExtInst %float %1 FMax %11386 %18222 + %21848 = OpExtInst %float %1 FMax %18220 %21855 + %10142 = OpExtInst %float %1 FMax %21848 %6945 + %24762 = OpExtInst %float %1 FMin %15948 %19731 + %21997 = OpFDiv %float %float_0_25 %21851 + %10377 = OpFMul %float %24762 %21997 + %21327 = OpExtInst %float %1 FMin %15951 %6931 + %17454 = OpFDiv %float %float_0_25 %21854 + %10378 = OpFMul %float %21327 %17454 + %21328 = OpExtInst %float %1 FMin %10905 %18221 + %17457 = OpFDiv %float %float_0_25 %10142 + %24307 = OpFMul %float %21328 %17457 + %16512 = OpExtInst %float %1 FMax %21851 %19731 + %22147 = OpFSub %float %float_1 %16512 + %13544 = OpFMul %float %float_4 %15948 + %19323 = OpFAdd %float %13544 %float_n4 + %20054 = OpFDiv %float %float_1 %19323 + %20866 = OpFMul %float %22147 %20054 + %16513 = OpExtInst %float %1 FMax %21854 %6931 + %22148 = OpFSub %float %float_1 %16513 + %13545 = OpFMul %float %float_4 %15951 + %19324 = OpFAdd %float %13545 %float_n4 + %20055 = OpFDiv %float %float_1 %19324 + %20867 = OpFMul %float %22148 %20055 + %16514 = OpExtInst %float %1 FMax %10142 %18221 + %22149 = OpFSub %float %float_1 %16514 + %13546 = OpFMul %float %float_4 %10905 + %19325 = OpFAdd %float %13546 %float_n4 + %22199 = OpFDiv %float %float_1 %19325 + %15174 = OpFMul %float %22149 %22199 + %22356 = OpFNegate %float %10377 + %23705 = OpExtInst %float %1 FMax %22356 %20866 + %16409 = OpFNegate %float %10378 + %9177 = OpExtInst %float %1 FMax %16409 %20867 + %14264 = OpFNegate %float %24307 + %12648 = OpExtInst %float %1 FMax %14264 %15174 + %18923 = OpExtInst %float %1 FMax %9177 %12648 + %7826 = OpExtInst %float %1 FMax %23705 %18923 + %10548 = OpExtInst %float %1 FMin %7826 %float_0 + %8860 = OpExtInst %float %1 FMax %float_n0_1875 %10548 + %22576 = OpBitcast %float %16454 + %20919 = OpFMul %float %8860 %22576 + %23316 = OpFMul %float %float_4 %20919 + %16498 = OpFAdd %float %23316 %float_1 + %6551 = OpBitcast %uint %16498 + %7563 = OpISub %uint %uint_2129764351 %6551 + %9419 = OpBitcast %float %7563 + %9130 = OpFNegate %float %9419 + %12367 = OpFMul %float %9130 %16498 + %16540 = OpFAdd %float %12367 %float_2 + %9366 = OpFMul %float %9419 %16540 + %18845 = OpFAdd %float %19729 %19730 + %23143 = OpFAdd %float %18845 %19733 + %6535 = OpFAdd %float %23143 %19732 + %12673 = OpFMul %float %20919 %6535 + %18153 = OpFAdd %float %12673 %19731 + %9367 = OpFMul %float %18153 %9366 + %18846 = OpFAdd %float %6930 %24728 + %23144 = OpFAdd %float %18846 %23834 + %6536 = OpFAdd %float %23144 %6932 + %12674 = OpFMul %float %20919 %6536 + %18154 = OpFAdd %float %12674 %6931 + %9368 = OpFMul %float %18154 %9366 + %18847 = OpFAdd %float %18220 %11386 + %23145 = OpFAdd %float %18847 %6945 + %6537 = OpFAdd %float %23145 %18222 + %12675 = OpFMul %float %20919 %6537 + %17260 = OpFAdd %float %12675 %18221 + %16604 = OpFMul %float %17260 %9366 + %10663 = OpCompositeInsert %v4float %9367 %10264 0 + %21274 = OpCompositeInsert %v4float %9368 %10663 1 + %18455 = OpCompositeInsert %v4float %16604 %21274 2 + %20032 = OpVectorShuffle %v3float %18455 %18455 0 1 2 + %12552 = OpBitwiseAnd %v2uint %9938 %2122 + %9741 = OpCompositeExtract %uint %12552 1 + %21498 = OpIMul %uint %9741 %uint_16 + %23411 = OpCompositeExtract %uint %12552 0 + %12610 = OpIAdd %uint %21498 %23411 + OpStore %18411 %2212 + %9958 = OpAccessChain %_ptr_Function_float %18411 %12610 + %25140 = OpLoad %float %9958 + %18028 = OpCompositeConstruct %v3float %25140 %25140 %25140 + %21458 = OpFAdd %v3float %20032 %18028 + %19525 = OpExtInst %v3float %1 FClamp %21458 %2604 %2582 + %16777 = OpCompositeExtract %float %19525 0 + %19708 = OpCompositeExtract %float %19525 1 + %7472 = OpCompositeExtract %float %19525 2 + %22408 = OpCompositeConstruct %v4float %16777 %19708 %7472 %float_1 + OpStore %3253 %22408 + OpReturn + OpFunctionEnd +#endif + +const uint32_t guest_output_ffx_fsr_rcas_dither_ps[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006240, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0007000F, 0x00000004, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000C93, 0x00000CB5, 0x00030010, + 0x0000161F, 0x00000007, 0x00040047, 0x00000C93, 0x0000000B, 0x0000000F, 0x00030047, 0x000003F2, + 0x00000002, 0x00050048, 0x000003F2, 0x00000000, 0x00000023, 0x00000010, 0x00050048, 0x000003F2, + 0x00000001, 0x00000023, 0x00000018, 0x00040047, 0x00000CB5, 0x0000001E, 0x00000000, 0x00040047, + 0x00000DF7, 0x00000021, 0x00000000, 0x00040047, 0x00000DF7, 0x00000022, 0x00000000, 0x00020013, + 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00030016, 0x0000000D, 0x00000020, 0x00040020, + 0x0000028A, 0x00000007, 0x0000000D, 0x00040017, 0x00000018, 0x0000000D, 0x00000003, 0x00040015, + 0x0000000B, 0x00000020, 0x00000000, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00040015, + 0x0000000C, 0x00000020, 0x00000001, 0x00040017, 0x00000012, 0x0000000C, 0x00000002, 0x00040017, + 0x0000001D, 0x0000000D, 0x00000004, 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, 0x0004002B, + 0x0000000D, 0x0000008A, 0x3F800000, 0x0004002B, 0x0000000B, 0x00000A37, 0x0000000F, 0x0004002B, + 0x0000000B, 0x00000147, 0x00000100, 0x0004001C, 0x000003DD, 0x0000000D, 0x00000147, 0x0004002B, + 0x0000000D, 0x0000010F, 0xBA838384, 0x0004002B, 0x0000000D, 0x00000728, 0x3A66E6E7, 0x0004002B, + 0x0000000D, 0x00000705, 0x3ADDDDDE, 0x0004002B, 0x0000000D, 0x00000A5A, 0xBACBCBCC, 0x0004002B, + 0x0000000D, 0x000008DF, 0x3AA7A7A8, 0x0004002B, 0x0000000D, 0x00000094, 0xBA1E9E9F, 0x0004002B, + 0x0000000D, 0x0000034C, 0x3A8B8B8C, 0x0004002B, 0x0000000D, 0x0000087E, 0xBAB5B5B6, 0x0004002B, + 0x0000000D, 0x0000034D, 0x3AB1B1B2, 0x0004002B, 0x0000000D, 0x00000687, 0x3A068687, 0x0004002B, + 0x0000000D, 0x000003EB, 0x3A9F9FA0, 0x0004002B, 0x0000000D, 0x0000024E, 0xBAD1D1D2, 0x0004002B, + 0x0000000D, 0x00000726, 0x3A1A9A9B, 0x0004002B, 0x0000000D, 0x00000698, 0xB9949495, 0x0004002B, + 0x0000000D, 0x00000703, 0x3A919192, 0x0004002B, 0x0000000D, 0x00000AF8, 0xBAB9B9BA, 0x0004002B, + 0x0000000D, 0x00000ABB, 0x3ABDBDBE, 0x0004002B, 0x0000000D, 0x0000026F, 0xBA0E8E8F, 0x0004002B, + 0x0000000D, 0x000008A8, 0x39088889, 0x0004002B, 0x0000000D, 0x00000565, 0xBA9D9D9E, 0x0004002B, + 0x0000000D, 0x0000065D, 0x39E4E4E5, 0x0004002B, 0x0000000D, 0x000004C6, 0xBA89898A, 0x0004002B, + 0x0000000D, 0x00000057, 0x3A22A2A3, 0x0004002B, 0x0000000D, 0x0000006A, 0xB9FCFCFD, 0x0004002B, + 0x0000000D, 0x00000A1E, 0x3AF5F5F6, 0x0004002B, 0x0000000D, 0x0000087D, 0xBA8F8F90, 0x0004002B, + 0x0000000D, 0x00000959, 0xB8D0D0D1, 0x0004002B, 0x0000000D, 0x00000BB8, 0xBA0A8A8B, 0x0004002B, + 0x0000000D, 0x0000097E, 0x3ABBBBBC, 0x0004002B, 0x0000000D, 0x00000606, 0xBAFDFDFE, 0x0004002B, + 0x0000000D, 0x000003AD, 0xBA36B6B7, 0x0004002B, 0x0000000D, 0x000000E2, 0x3820A0A1, 0x0004002B, + 0x0000000D, 0x00000370, 0x3A3ABABB, 0x0004002B, 0x0000000D, 0x0000024D, 0xBAABABAC, 0x0004002B, + 0x0000000D, 0x000005C6, 0x3A8F8F90, 0x0004002B, 0x0000000D, 0x00000B8C, 0xB99C9C9D, 0x0004002B, + 0x0000000D, 0x00000036, 0x3AE5E5E6, 0x0004002B, 0x0000000D, 0x0000087F, 0xBADBDBDC, 0x0004002B, + 0x0000000D, 0x00000172, 0x3AC1C1C2, 0x0004002B, 0x0000000D, 0x00000399, 0xB820A0A1, 0x0004002B, + 0x0000000D, 0x0000040F, 0x3A4ECECF, 0x0004002B, 0x0000000D, 0x0000091E, 0xBAEFEFF0, 0x0004002B, + 0x0000000D, 0x000008D5, 0x399C9C9D, 0x0004002B, 0x0000000D, 0x000008DE, 0x3A818182, 0x0004002B, + 0x0000000D, 0x000002EB, 0xBA99999A, 0x0004002B, 0x0000000D, 0x00000317, 0x3938B8B9, 0x0004002B, + 0x0000000D, 0x0000034E, 0x3AD7D7D8, 0x0004002B, 0x0000000D, 0x00000111, 0xBACFCFD0, 0x0004002B, + 0x0000000D, 0x0000002B, 0x39B4B4B5, 0x0004002B, 0x0000000D, 0x000008E1, 0x3AF3F3F4, 0x0004002B, + 0x0000000D, 0x0000042A, 0xBAE7E7E8, 0x0004002B, 0x0000000D, 0x00000765, 0xBA62E2E3, 0x0004002B, + 0x0000000D, 0x000009A2, 0x3A6AEAEB, 0x0004002B, 0x0000000D, 0x000004F2, 0x3928A8A9, 0x0004002B, + 0x0000000D, 0x0000058A, 0xBA72F2F3, 0x0004002B, 0x0000000D, 0x000007E0, 0xBAC7C7C8, 0x0004002B, + 0x0000000D, 0x00000802, 0xBA2AAAAB, 0x0004002B, 0x0000000D, 0x00000A1C, 0x3AA9A9AA, 0x0004002B, + 0x0000000D, 0x00000940, 0xBA52D2D3, 0x0004002B, 0x0000000D, 0x000002EC, 0xBABFBFC0, 0x0004002B, + 0x0000000D, 0x000003ED, 0x3AEBEBEC, 0x0004002B, 0x0000000D, 0x000004EB, 0xBA5EDEDF, 0x0004002B, + 0x0000000D, 0x00000234, 0x3A5EDEDF, 0x0004002B, 0x0000000D, 0x00000245, 0xB9ECECED, 0x0004002B, + 0x0000000D, 0x00000603, 0xBA8B8B8C, 0x0004002B, 0x0000000D, 0x00000984, 0xB9189899, 0x0004002B, + 0x0000000D, 0x0000076E, 0x3978F8F9, 0x0004002B, 0x0000000D, 0x00000841, 0x3AB9B9BA, 0x0004002B, + 0x0000000D, 0x000009DD, 0xBA1A9A9B, 0x0004002B, 0x0000000D, 0x000003F3, 0xB948C8C9, 0x0004002B, + 0x0000000D, 0x00000B5A, 0x3AD1D1D2, 0x0004002B, 0x0000000D, 0x00000B58, 0x3A858586, 0x0004002B, + 0x0000000D, 0x00000838, 0x39D4D4D5, 0x0004002B, 0x0000000D, 0x00000218, 0xB958D8D9, 0x0004002B, + 0x0000000D, 0x00000A1D, 0x3ACFCFD0, 0x0004002B, 0x0000000D, 0x0000054B, 0x3A2AAAAB, 0x0004002B, + 0x0000000D, 0x00000503, 0xB8909091, 0x0004002B, 0x0000000D, 0x00000169, 0x39DCDCDD, 0x0004002B, + 0x0000000D, 0x00000605, 0xBAD7D7D8, 0x0004002B, 0x0000000D, 0x0000048A, 0x3AB3B3B4, 0x0004002B, + 0x0000000D, 0x000002D3, 0x3A72F2F3, 0x0004002B, 0x0000000D, 0x00000A7C, 0xBA2EAEAF, 0x0004002B, + 0x0000000D, 0x00000171, 0x3A9B9B9C, 0x0004002B, 0x0000000D, 0x000001AF, 0xBABDBDBE, 0x0004002B, + 0x0000000D, 0x000004AC, 0x3A169697, 0x0004002B, 0x0000000D, 0x0000024F, 0xBAF7F7F8, 0x0004002B, + 0x0000000D, 0x00000ADE, 0x3A46C6C7, 0x0004002B, 0x0000000D, 0x00000110, 0xBAA9A9AA, 0x0004002B, + 0x0000000D, 0x00000212, 0x3AFBFBFC, 0x0004002B, 0x0000000D, 0x00000742, 0xBAD9D9DA, 0x0004002B, + 0x0000000D, 0x00000389, 0xBA878788, 0x0004002B, 0x0000000D, 0x000006C4, 0xBA028283, 0x0004002B, + 0x0000000D, 0x00000B98, 0xBAF3F3F4, 0x0004002B, 0x0000000D, 0x000002AE, 0x3A9D9D9E, 0x0004002B, + 0x0000000D, 0x000009B1, 0xB9ACACAD, 0x0004002B, 0x0000000D, 0x00000741, 0xBAB3B3B4, 0x0004002B, + 0x0000000D, 0x00000211, 0x3AD5D5D6, 0x0004002B, 0x0000000D, 0x00000A5B, 0xBAF1F1F2, 0x0004002B, + 0x0000000D, 0x000005EA, 0x3A3EBEBF, 0x0004002B, 0x0000000D, 0x00000310, 0xBA6EEEEF, 0x0004002B, + 0x0000000D, 0x0000052A, 0x3AEDEDEE, 0x0004002B, 0x0000000D, 0x00000071, 0xBA959596, 0x0004002B, + 0x0000000D, 0x00000107, 0xB9C4C4C5, 0x0004002B, 0x0000000D, 0x000006A2, 0x38D0D0D1, 0x0004002B, + 0x0000000D, 0x00000B1B, 0xBA42C2C3, 0x0004002B, 0x0000000D, 0x00000034, 0x3A99999A, 0x0004002B, + 0x0000000D, 0x0000024B, 0x38909091, 0x0004002B, 0x0000000D, 0x000002AF, 0x3AC3C3C4, 0x0004002B, + 0x0000000D, 0x00000A41, 0x3A7EFEFF, 0x0004002B, 0x0000000D, 0x00000A7E, 0xBA7AFAFB, 0x0004002B, + 0x0000000D, 0x0000034F, 0x3AFDFDFE, 0x0004002B, 0x0000000D, 0x00000901, 0x3A0A8A8B, 0x0004002B, + 0x0000000D, 0x00000539, 0x3860E0E1, 0x0004002B, 0x0000000D, 0x0000091C, 0xBAA3A3A4, 0x0004002B, + 0x0000000D, 0x000001A4, 0xB98C8C8D, 0x0004002B, 0x0000000D, 0x00000666, 0x3AC9C9CA, 0x0004002B, + 0x0000000D, 0x00000833, 0xB7008081, 0x0004002B, 0x0000000D, 0x00000206, 0x39A4A4A5, 0x0004002B, + 0x0000000D, 0x00000210, 0x3AAFAFB0, 0x0004002B, 0x0000000D, 0x000002ED, 0xBAE5E5E6, 0x0004002B, + 0x0000000D, 0x0000040D, 0x3A028283, 0x0004002B, 0x0000000D, 0x00000428, 0xBA9B9B9C, 0x0004002B, + 0x0000000D, 0x00000195, 0x3A4ACACB, 0x0004002B, 0x0000000D, 0x000004C7, 0xBAAFAFB0, 0x0004002B, + 0x0000000D, 0x00000AB0, 0x398C8C8D, 0x0004002B, 0x0000000D, 0x00000429, 0xBAC1C1C2, 0x0004002B, + 0x0000000D, 0x00000B5F, 0xB9088889, 0x0004002B, 0x0000000D, 0x0000044C, 0xBA4ACACB, 0x0004002B, + 0x0000000D, 0x00000B59, 0x3AABABAC, 0x0004002B, 0x0000000D, 0x00000344, 0x39CCCCCD, 0x0004002B, + 0x0000000D, 0x000007C7, 0x3A7AFAFB, 0x0004002B, 0x0000000D, 0x00000739, 0xB9F4F4F5, 0x0004002B, + 0x0000000D, 0x0000091D, 0xBAC9C9CA, 0x0004002B, 0x0000000D, 0x000000D2, 0x3A878788, 0x0004002B, + 0x0000000D, 0x00000133, 0xBA32B2B3, 0x0004002B, 0x0000000D, 0x000005C8, 0x3ADBDBDC, 0x0004002B, + 0x0000000D, 0x00000A1B, 0x3A838384, 0x0004002B, 0x0000000D, 0x00000420, 0xB9DCDCDD, 0x0004002B, + 0x0000000D, 0x000002B0, 0x3AE9E9EA, 0x0004002B, 0x0000000D, 0x00000A25, 0xB978F8F9, 0x0004002B, + 0x0000000D, 0x0000030E, 0xBA22A2A3, 0x0004002B, 0x0000000D, 0x0000048B, 0x3AD9D9DA, 0x0004002B, + 0x0000000D, 0x00000B7D, 0x3A5ADADB, 0x0004002B, 0x0000000D, 0x00000073, 0xBAE1E1E2, 0x0004002B, + 0x0000000D, 0x00000740, 0xBA8D8D8E, 0x0004002B, 0x0000000D, 0x00000173, 0x3AE7E7E8, 0x0004002B, + 0x0000000D, 0x000006C6, 0xBA4ECECF, 0x0004002B, 0x0000000D, 0x00000567, 0xBAE9E9EA, 0x0004002B, + 0x0000000D, 0x00000A3F, 0x3A32B2B3, 0x0004002B, 0x0000000D, 0x00000B95, 0xBA818182, 0x0004002B, + 0x0000000D, 0x0000038A, 0xBAADADAE, 0x0004002B, 0x0000000D, 0x000005CE, 0xB938B8B9, 0x0004002B, + 0x0000000D, 0x000006A3, 0xBAC5C5C6, 0x0004002B, 0x0000000D, 0x000006FA, 0x39ACACAD, 0x0004002B, + 0x0000000D, 0x00000743, 0xBB000000, 0x0004002B, 0x0000000D, 0x000007C5, 0x3A2EAEAF, 0x0004002B, + 0x0000000D, 0x0000038B, 0xBAD3D3D4, 0x0004002B, 0x0000000D, 0x00000ABA, 0x3A979798, 0x0004002B, + 0x0000000D, 0x00000B51, 0x39ECECED, 0x0004002B, 0x0000000D, 0x00000914, 0xB9E4E4E5, 0x0004002B, + 0x0000000D, 0x0000013C, 0x3948C8C9, 0x0004002B, 0x0000000D, 0x00000566, 0xBAC3C3C4, 0x0004002B, + 0x0000000D, 0x0000097D, 0x3A959596, 0x0004002B, 0x0000000D, 0x00000A58, 0x38B0B0B1, 0x0004002B, + 0x0000000D, 0x00000B5B, 0x3AF7F7F8, 0x0004002B, 0x0000000D, 0x00000704, 0x3AB7B7B8, 0x0004002B, + 0x0000000D, 0x00000232, 0x3A129293, 0x0004002B, 0x0000000D, 0x000002EE, 0x38F0F0F1, 0x0004002B, + 0x0000000D, 0x000007A2, 0x3AA5A5A6, 0x0004002B, 0x0000000D, 0x00000763, 0xBA169697, 0x0004002B, + 0x0000000D, 0x00000135, 0xBA7EFEFF, 0x0004002B, 0x0000000D, 0x000000D3, 0x3AADADAE, 0x0004002B, + 0x0000000D, 0x00000949, 0x3968E8E9, 0x0004002B, 0x0000000D, 0x000001D2, 0xBA46C6C7, 0x0004002B, + 0x0000000D, 0x00000604, 0xBAB1B1B2, 0x0004002B, 0x0000000D, 0x00000035, 0x3ABFBFC0, 0x0004002B, + 0x0000000D, 0x000004AE, 0x3A62E2E3, 0x0004002B, 0x0000000D, 0x000007D6, 0xB9BCBCBD, 0x0004002B, + 0x0000000D, 0x00000B7B, 0x3A0E8E8F, 0x0004002B, 0x0000000D, 0x00000AF7, 0xBA939394, 0x0004002B, + 0x0000000D, 0x00000873, 0xB9848485, 0x0004002B, 0x0000000D, 0x000004E9, 0xBA129293, 0x0004002B, + 0x0000000D, 0x000007E1, 0xBAEDEDEE, 0x0004002B, 0x0000000D, 0x0000097F, 0x3AE1E1E2, 0x0004002B, + 0x0000000D, 0x000001AE, 0xBA979798, 0x0004002B, 0x0000000D, 0x00000864, 0x3A42C2C3, 0x0004002B, + 0x0000000D, 0x000008E0, 0x3ACDCDCE, 0x0004002B, 0x0000000D, 0x000005A3, 0xB8F0F0F1, 0x0004002B, + 0x0000000D, 0x000006A4, 0xBA9F9FA0, 0x0004002B, 0x0000000D, 0x00000667, 0x3AEFEFF0, 0x0004002B, + 0x0000000D, 0x00000961, 0x37C0C0C1, 0x0004002B, 0x0000000D, 0x000004C9, 0xBAFBFBFC, 0x0004002B, + 0x0000000D, 0x00000ABC, 0x3AE3E3E4, 0x0004002B, 0x0000000D, 0x00000627, 0xBA3ABABB, 0x0004002B, + 0x0000000D, 0x000007A3, 0x3ACBCBCC, 0x0004002B, 0x0000000D, 0x00000AF9, 0xBADFDFE0, 0x0004002B, + 0x0000000D, 0x00000528, 0x3AA1A1A2, 0x0004002B, 0x0000000D, 0x00000B24, 0x3958D8D9, 0x0004002B, + 0x0000000D, 0x0000020F, 0x3A89898A, 0x0004002B, 0x0000000D, 0x000008A1, 0xBA3EBEBF, 0x0004002B, + 0x0000000D, 0x000004C8, 0xBAD5D5D6, 0x0004002B, 0x0000000D, 0x000004BD, 0xB9A4A4A5, 0x0004002B, + 0x0000000D, 0x00000976, 0x39FCFCFD, 0x0004002B, 0x0000000D, 0x000006A5, 0xBAEBEBEC, 0x0004002B, + 0x0000000D, 0x0000054D, 0x3A76F6F7, 0x0004002B, 0x0000000D, 0x000002E2, 0xB9B4B4B5, 0x0004002B, + 0x0000000D, 0x000000F6, 0x3A36B6B7, 0x0004002B, 0x0000000D, 0x0000024C, 0xBA858586, 0x0004002B, + 0x0000000D, 0x00000B97, 0xBACDCDCE, 0x0004002B, 0x0000000D, 0x00000055, 0xB7C0C0C1, 0x0004002B, + 0x0000000D, 0x00000B96, 0xBAA7A7A8, 0x0004002B, 0x0000000D, 0x00000689, 0x3A52D2D3, 0x0004002B, + 0x0000000D, 0x00000096, 0xBA6AEAEB, 0x0004002B, 0x0000000D, 0x00000072, 0xBABBBBBC, 0x0004002B, + 0x0000000D, 0x000009A0, 0x3A1E9E9F, 0x0004002B, 0x0000000D, 0x0000014C, 0xB8B0B0B1, 0x0004002B, + 0x0000000D, 0x00000059, 0x3A6EEEEF, 0x0004002B, 0x0000000D, 0x0000048C, 0x3B000000, 0x0004002B, + 0x0000000D, 0x000009BB, 0xBAB7B7B8, 0x0004002B, 0x0000000D, 0x00000588, 0xBA26A6A7, 0x0004002B, + 0x0000000D, 0x000003EC, 0x3AC5C5C6, 0x0004002B, 0x0000000D, 0x00000BBA, 0xBA56D6D7, 0x0004002B, + 0x0000000D, 0x00000665, 0x3AA3A3A4, 0x0004002B, 0x0000000D, 0x000005BC, 0x39848485, 0x0004002B, + 0x0000000D, 0x00000529, 0x3AC7C7C8, 0x0004002B, 0x0000000D, 0x00000840, 0x3A939394, 0x0004002B, + 0x0000000D, 0x0000051F, 0x39BCBCBD, 0x0004002B, 0x0000000D, 0x000005FB, 0xB9CCCCCD, 0x0004002B, + 0x0000000D, 0x000000D5, 0x3AF9F9FA, 0x0004002B, 0x0000000D, 0x000005C7, 0x3AB5B5B6, 0x0004002B, + 0x0000000D, 0x000009BA, 0xBA919192, 0x0004002B, 0x0000000D, 0x000000D4, 0x3AD3D3D4, 0x0004002B, + 0x0000000D, 0x000009DF, 0xBA66E6E7, 0x0004002B, 0x0000000D, 0x000006CD, 0x39189899, 0x0004002B, + 0x0000000D, 0x00000489, 0x3A8D8D8E, 0x0004002B, 0x0000000D, 0x000007F0, 0xB860E0E1, 0x0004002B, + 0x0000000D, 0x000003E1, 0x39949495, 0x0004002B, 0x0000000D, 0x000009BC, 0xBADDDDDE, 0x0004002B, + 0x0000000D, 0x00000A59, 0xBAA5A5A6, 0x0004002B, 0x0000000D, 0x0000093E, 0xBA068687, 0x0004002B, + 0x0000000D, 0x000007A9, 0xB928A8A9, 0x0004002B, 0x0000000D, 0x00000112, 0xBAF5F5F6, 0x0004002B, + 0x0000000D, 0x00000271, 0xBA5ADADB, 0x0004002B, 0x0000000D, 0x000002D1, 0x3A26A6A7, 0x0004002B, + 0x0000000D, 0x0000057C, 0x37008081, 0x0004002B, 0x0000000D, 0x0000038C, 0xBAF9F9FA, 0x0004002B, + 0x0000000D, 0x0000003D, 0xB968E8E9, 0x0004002B, 0x0000000D, 0x00000A13, 0x39C4C4C5, 0x0004002B, + 0x0000000D, 0x000001B0, 0xBAE3E3E4, 0x0004002B, 0x0000000D, 0x00000AEF, 0xB9D4D4D5, 0x0004002B, + 0x0000000D, 0x000007DF, 0xBAA1A1A2, 0x0004002B, 0x0000000D, 0x00000842, 0x3ADFDFE0, 0x0004002B, + 0x0000000D, 0x00000804, 0xBA76F6F7, 0x0004002B, 0x0000000D, 0x00000903, 0x3A56D6D7, 0x0004002B, + 0x0000000D, 0x000007A4, 0x3AF1F1F2, 0x0004002B, 0x0000000D, 0x00000482, 0x39F4F4F5, 0x0103002C, + 0x000003DD, 0x000008A4, 0x0000010F, 0x00000728, 0x00000705, 0x00000A5A, 0x000008DF, 0x00000094, + 0x0000034C, 0x0000087E, 0x0000034D, 0x00000687, 0x000003EB, 0x0000024E, 0x00000726, 0x00000698, + 0x00000703, 0x00000AF8, 0x00000ABB, 0x0000026F, 0x000008A8, 0x00000565, 0x0000065D, 0x000004C6, + 0x00000057, 0x0000006A, 0x00000A1E, 0x0000087D, 0x00000959, 0x00000BB8, 0x0000097E, 0x00000606, + 0x000003AD, 0x000000E2, 0x00000370, 0x0000024D, 0x000005C6, 0x00000B8C, 0x00000036, 0x0000087F, + 0x00000172, 0x00000399, 0x0000040F, 0x0000091E, 0x000008D5, 0x000008DE, 0x000002EB, 0x00000317, + 0x0000034E, 0x00000111, 0x0000002B, 0x000008E1, 0x0000042A, 0x00000765, 0x000009A2, 0x000004F2, + 0x0000058A, 0x000007E0, 0x00000802, 0x00000A1C, 0x00000940, 0x000002EC, 0x000003ED, 0x000004EB, + 0x00000234, 0x00000245, 0x00000603, 0x00000984, 0x0000076E, 0x00000841, 0x000009DD, 0x000003F3, + 0x00000B5A, 0x00000B58, 0x00000838, 0x00000218, 0x00000A1D, 0x0000054B, 0x00000503, 0x00000169, + 0x00000605, 0x0000048A, 0x000002D3, 0x00000A7C, 0x00000171, 0x000001AF, 0x000004AC, 0x0000024F, + 0x00000ADE, 0x00000110, 0x00000212, 0x00000742, 0x00000389, 0x000006C4, 0x00000B98, 0x000002AE, + 0x000009B1, 0x00000741, 0x00000211, 0x00000A5B, 0x000005EA, 0x00000310, 0x0000052A, 0x00000071, + 0x00000107, 0x000006A2, 0x00000B1B, 0x00000034, 0x0000024B, 0x000002AF, 0x00000A41, 0x00000A7E, + 0x0000034F, 0x00000901, 0x00000539, 0x0000091C, 0x000001A4, 0x00000666, 0x00000833, 0x00000206, + 0x00000210, 0x000002ED, 0x0000040D, 0x00000428, 0x00000195, 0x000004C7, 0x00000AB0, 0x00000429, + 0x00000B5F, 0x0000044C, 0x00000B59, 0x00000344, 0x000007C7, 0x00000739, 0x0000091D, 0x000000D2, + 0x00000133, 0x000005C8, 0x00000A1B, 0x00000420, 0x000002B0, 0x00000A25, 0x0000030E, 0x0000048B, + 0x00000B7D, 0x00000073, 0x00000740, 0x00000173, 0x000006C6, 0x00000567, 0x00000A3F, 0x00000B95, + 0x0000038A, 0x000005CE, 0x000006A3, 0x000006FA, 0x00000743, 0x000007C5, 0x0000038B, 0x00000ABA, + 0x00000B51, 0x00000914, 0x0000013C, 0x00000566, 0x0000097D, 0x00000A58, 0x00000B5B, 0x00000704, + 0x00000232, 0x000002EE, 0x000007A2, 0x00000763, 0x00000135, 0x000000D3, 0x00000949, 0x000001D2, + 0x00000604, 0x00000035, 0x000004AE, 0x000007D6, 0x00000B7B, 0x00000AF7, 0x00000873, 0x000004E9, + 0x000007E1, 0x0000097F, 0x000001AE, 0x00000864, 0x000008E0, 0x000005A3, 0x000006A4, 0x00000667, + 0x00000961, 0x000004C9, 0x00000ABC, 0x00000627, 0x000007A3, 0x00000AF9, 0x00000528, 0x00000B24, + 0x0000020F, 0x000008A1, 0x000004C8, 0x000004BD, 0x00000976, 0x000006A5, 0x0000054D, 0x000002E2, + 0x000000F6, 0x0000024C, 0x00000B97, 0x00000055, 0x00000B96, 0x00000689, 0x00000096, 0x00000072, + 0x000009A0, 0x0000014C, 0x00000059, 0x0000048C, 0x000009BB, 0x00000588, 0x000003EC, 0x00000BBA, + 0x00000665, 0x000005BC, 0x00000529, 0x00000840, 0x0000051F, 0x000005FB, 0x000000D5, 0x000005C7, + 0x000009BA, 0x000000D4, 0x000009DF, 0x000006CD, 0x00000489, 0x000007F0, 0x000003E1, 0x000009BC, + 0x00000A59, 0x0000093E, 0x000007A9, 0x00000112, 0x00000271, 0x000002D1, 0x0000057C, 0x0000038C, + 0x0000003D, 0x00000A13, 0x000001B0, 0x00000AEF, 0x000007DF, 0x00000842, 0x00000804, 0x00000903, + 0x000007A4, 0x00000482, 0x0004002B, 0x0000000B, 0x00000A3A, 0x00000010, 0x00040020, 0x0000065A, + 0x00000007, 0x000003DD, 0x00040020, 0x0000029A, 0x00000001, 0x0000001D, 0x0004003B, 0x0000029A, + 0x00000C93, 0x00000001, 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x0004001E, 0x000003F2, + 0x00000012, 0x0000000D, 0x00040020, 0x0000066F, 0x00000009, 0x000003F2, 0x0004003B, 0x0000066F, + 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, 0x0000028F, + 0x00000009, 0x00000012, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x00040020, 0x0000028B, + 0x00000009, 0x0000000D, 0x00040020, 0x0000029B, 0x00000003, 0x0000001D, 0x0004003B, 0x0000029B, + 0x00000CB5, 0x00000003, 0x0004002B, 0x0000000B, 0x000000B2, 0x7EF19FFF, 0x0004002B, 0x0000000D, + 0x00000019, 0x40000000, 0x00090019, 0x00000097, 0x0000000D, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00040020, 0x00000313, 0x00000000, 0x00000097, 0x0004003B, + 0x00000313, 0x00000DF7, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A08, 0xFFFFFFFF, 0x0005002C, + 0x00000012, 0x0000070B, 0x00000A0B, 0x00000A08, 0x0005002C, 0x00000012, 0x0000070E, 0x00000A08, + 0x00000A0B, 0x0005002C, 0x00000012, 0x00000720, 0x00000A0E, 0x00000A0B, 0x0005002C, 0x00000012, + 0x00000723, 0x00000A0B, 0x00000A0E, 0x0004002B, 0x0000000D, 0x0000025D, 0xC0800000, 0x0004002B, + 0x0000000D, 0x00000B69, 0x40800000, 0x0004002B, 0x0000000D, 0x0000045E, 0xBE400000, 0x0005002C, + 0x00000011, 0x0000084A, 0x00000A37, 0x00000A37, 0x0006002C, 0x00000018, 0x00000A2C, 0x00000A0C, + 0x00000A0C, 0x00000A0C, 0x0006002C, 0x00000018, 0x00000A16, 0x0000008A, 0x0000008A, 0x0000008A, + 0x0004002B, 0x0000000D, 0x0000016E, 0x3E800000, 0x00030001, 0x0000001D, 0x00002818, 0x00050036, + 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00006179, 0x0004003B, 0x0000065A, + 0x000047EB, 0x00000007, 0x0004003D, 0x0000001D, 0x00005647, 0x00000C93, 0x0007004F, 0x00000013, + 0x000019A2, 0x00005647, 0x00005647, 0x00000000, 0x00000001, 0x0004006E, 0x00000012, 0x000044F8, + 0x000019A2, 0x00050041, 0x0000028F, 0x00004B4F, 0x00000CE9, 0x00000A0B, 0x0004003D, 0x00000012, + 0x00005926, 0x00004B4F, 0x00050082, 0x00000012, 0x00005B10, 0x000044F8, 0x00005926, 0x0004007C, + 0x00000011, 0x000026D2, 0x00005B10, 0x00050041, 0x0000028B, 0x00005205, 0x00000CE9, 0x00000A0E, + 0x0004003D, 0x0000000D, 0x000056DD, 0x00005205, 0x0004007C, 0x0000000B, 0x00004046, 0x000056DD, + 0x0004007C, 0x00000012, 0x00001B4E, 0x000026D2, 0x00050080, 0x00000012, 0x0000381D, 0x00001B4E, + 0x0000070B, 0x0004003D, 0x00000097, 0x00005694, 0x00000DF7, 0x0007005F, 0x0000001D, 0x000022C3, + 0x00005694, 0x0000381D, 0x00000002, 0x00000A0B, 0x00050051, 0x0000000D, 0x00004D11, 0x000022C3, + 0x00000000, 0x00050051, 0x0000000D, 0x00001B12, 0x000022C3, 0x00000001, 0x00050051, 0x0000000D, + 0x0000472C, 0x000022C3, 0x00000002, 0x00050080, 0x00000012, 0x00004F7D, 0x00001B4E, 0x0000070E, + 0x0004003D, 0x00000097, 0x0000409D, 0x00000DF7, 0x0007005F, 0x0000001D, 0x000022C4, 0x0000409D, + 0x00004F7D, 0x00000002, 0x00000A0B, 0x00050051, 0x0000000D, 0x00004D12, 0x000022C4, 0x00000000, + 0x00050051, 0x0000000D, 0x00006098, 0x000022C4, 0x00000001, 0x00050051, 0x0000000D, 0x00002C7A, + 0x000022C4, 0x00000002, 0x0004003D, 0x00000097, 0x00004092, 0x00000DF7, 0x0007005F, 0x0000001D, + 0x00004AB1, 0x00004092, 0x00001B4E, 0x00000002, 0x00000A0B, 0x00050051, 0x0000000D, 0x00004D13, + 0x00004AB1, 0x00000000, 0x00050051, 0x0000000D, 0x00001B13, 0x00004AB1, 0x00000001, 0x00050051, + 0x0000000D, 0x0000472D, 0x00004AB1, 0x00000002, 0x00050080, 0x00000012, 0x00004F7E, 0x00001B4E, + 0x00000720, 0x0004003D, 0x00000097, 0x0000409E, 0x00000DF7, 0x0007005F, 0x0000001D, 0x000022C5, + 0x0000409E, 0x00004F7E, 0x00000002, 0x00000A0B, 0x00050051, 0x0000000D, 0x00004D14, 0x000022C5, + 0x00000000, 0x00050051, 0x0000000D, 0x00001B14, 0x000022C5, 0x00000001, 0x00050051, 0x0000000D, + 0x0000472E, 0x000022C5, 0x00000002, 0x00050080, 0x00000012, 0x00004F7F, 0x00001B4E, 0x00000723, + 0x0004003D, 0x00000097, 0x0000409F, 0x00000DF7, 0x0007005F, 0x0000001D, 0x000022C6, 0x0000409F, + 0x00004F7F, 0x00000002, 0x00000A0B, 0x00050051, 0x0000000D, 0x00004D15, 0x000022C6, 0x00000000, + 0x00050051, 0x0000000D, 0x00005D1A, 0x000022C6, 0x00000001, 0x00050051, 0x0000000D, 0x00001B21, + 0x000022C6, 0x00000002, 0x0007000C, 0x0000000D, 0x00003C0C, 0x00000001, 0x00000025, 0x00004D12, + 0x00004D14, 0x0007000C, 0x0000000D, 0x0000623F, 0x00000001, 0x00000025, 0x00004D11, 0x00003C0C, + 0x0007000C, 0x0000000D, 0x00003E4C, 0x00000001, 0x00000025, 0x0000623F, 0x00004D15, 0x0007000C, + 0x0000000D, 0x00003E4D, 0x00000001, 0x00000025, 0x00006098, 0x00001B14, 0x0007000C, 0x0000000D, + 0x00003E4E, 0x00000001, 0x00000025, 0x00001B12, 0x00003E4D, 0x0007000C, 0x0000000D, 0x00003E4F, + 0x00000001, 0x00000025, 0x00003E4E, 0x00005D1A, 0x0007000C, 0x0000000D, 0x00003E50, 0x00000001, + 0x00000025, 0x00002C7A, 0x0000472E, 0x0007000C, 0x0000000D, 0x00003E51, 0x00000001, 0x00000025, + 0x0000472C, 0x00003E50, 0x0007000C, 0x0000000D, 0x00002A99, 0x00000001, 0x00000025, 0x00003E51, + 0x00001B21, 0x0007000C, 0x0000000D, 0x00005EE8, 0x00000001, 0x00000028, 0x00004D12, 0x00004D14, + 0x0007000C, 0x0000000D, 0x00004473, 0x00000001, 0x00000028, 0x00004D11, 0x00005EE8, 0x0007000C, + 0x0000000D, 0x0000555B, 0x00000001, 0x00000028, 0x00004473, 0x00004D15, 0x0007000C, 0x0000000D, + 0x0000555C, 0x00000001, 0x00000028, 0x00006098, 0x00001B14, 0x0007000C, 0x0000000D, 0x0000555D, + 0x00000001, 0x00000028, 0x00001B12, 0x0000555C, 0x0007000C, 0x0000000D, 0x0000555E, 0x00000001, + 0x00000028, 0x0000555D, 0x00005D1A, 0x0007000C, 0x0000000D, 0x0000555F, 0x00000001, 0x00000028, + 0x00002C7A, 0x0000472E, 0x0007000C, 0x0000000D, 0x00005558, 0x00000001, 0x00000028, 0x0000472C, + 0x0000555F, 0x0007000C, 0x0000000D, 0x0000279E, 0x00000001, 0x00000028, 0x00005558, 0x00001B21, + 0x0007000C, 0x0000000D, 0x000060BA, 0x00000001, 0x00000025, 0x00003E4C, 0x00004D13, 0x00050088, + 0x0000000D, 0x000055ED, 0x0000016E, 0x0000555B, 0x00050085, 0x0000000D, 0x00002889, 0x000060BA, + 0x000055ED, 0x0007000C, 0x0000000D, 0x0000534F, 0x00000001, 0x00000025, 0x00003E4F, 0x00001B13, + 0x00050088, 0x0000000D, 0x0000442E, 0x0000016E, 0x0000555E, 0x00050085, 0x0000000D, 0x0000288A, + 0x0000534F, 0x0000442E, 0x0007000C, 0x0000000D, 0x00005350, 0x00000001, 0x00000025, 0x00002A99, + 0x0000472D, 0x00050088, 0x0000000D, 0x00004431, 0x0000016E, 0x0000279E, 0x00050085, 0x0000000D, + 0x00005EF3, 0x00005350, 0x00004431, 0x0007000C, 0x0000000D, 0x00004080, 0x00000001, 0x00000028, + 0x0000555B, 0x00004D13, 0x00050083, 0x0000000D, 0x00005683, 0x0000008A, 0x00004080, 0x00050085, + 0x0000000D, 0x000034E8, 0x00000B69, 0x00003E4C, 0x00050081, 0x0000000D, 0x00004B7B, 0x000034E8, + 0x0000025D, 0x00050088, 0x0000000D, 0x00004E56, 0x0000008A, 0x00004B7B, 0x00050085, 0x0000000D, + 0x00005182, 0x00005683, 0x00004E56, 0x0007000C, 0x0000000D, 0x00004081, 0x00000001, 0x00000028, + 0x0000555E, 0x00001B13, 0x00050083, 0x0000000D, 0x00005684, 0x0000008A, 0x00004081, 0x00050085, + 0x0000000D, 0x000034E9, 0x00000B69, 0x00003E4F, 0x00050081, 0x0000000D, 0x00004B7C, 0x000034E9, + 0x0000025D, 0x00050088, 0x0000000D, 0x00004E57, 0x0000008A, 0x00004B7C, 0x00050085, 0x0000000D, + 0x00005183, 0x00005684, 0x00004E57, 0x0007000C, 0x0000000D, 0x00004082, 0x00000001, 0x00000028, + 0x0000279E, 0x0000472D, 0x00050083, 0x0000000D, 0x00005685, 0x0000008A, 0x00004082, 0x00050085, + 0x0000000D, 0x000034EA, 0x00000B69, 0x00002A99, 0x00050081, 0x0000000D, 0x00004B7D, 0x000034EA, + 0x0000025D, 0x00050088, 0x0000000D, 0x000056B7, 0x0000008A, 0x00004B7D, 0x00050085, 0x0000000D, + 0x00003B46, 0x00005685, 0x000056B7, 0x0004007F, 0x0000000D, 0x00005754, 0x00002889, 0x0007000C, + 0x0000000D, 0x00005C99, 0x00000001, 0x00000028, 0x00005754, 0x00005182, 0x0004007F, 0x0000000D, + 0x00004019, 0x0000288A, 0x0007000C, 0x0000000D, 0x000023D9, 0x00000001, 0x00000028, 0x00004019, + 0x00005183, 0x0004007F, 0x0000000D, 0x000037B8, 0x00005EF3, 0x0007000C, 0x0000000D, 0x00003168, + 0x00000001, 0x00000028, 0x000037B8, 0x00003B46, 0x0007000C, 0x0000000D, 0x000049EB, 0x00000001, + 0x00000028, 0x000023D9, 0x00003168, 0x0007000C, 0x0000000D, 0x00001E92, 0x00000001, 0x00000028, + 0x00005C99, 0x000049EB, 0x0007000C, 0x0000000D, 0x00002934, 0x00000001, 0x00000025, 0x00001E92, + 0x00000A0C, 0x0007000C, 0x0000000D, 0x0000229C, 0x00000001, 0x00000028, 0x0000045E, 0x00002934, + 0x0004007C, 0x0000000D, 0x00005830, 0x00004046, 0x00050085, 0x0000000D, 0x000051B7, 0x0000229C, + 0x00005830, 0x00050085, 0x0000000D, 0x00005B14, 0x00000B69, 0x000051B7, 0x00050081, 0x0000000D, + 0x00004072, 0x00005B14, 0x0000008A, 0x0004007C, 0x0000000B, 0x00001997, 0x00004072, 0x00050082, + 0x0000000B, 0x00001D8B, 0x000000B2, 0x00001997, 0x0004007C, 0x0000000D, 0x000024CB, 0x00001D8B, + 0x0004007F, 0x0000000D, 0x000023AA, 0x000024CB, 0x00050085, 0x0000000D, 0x0000304F, 0x000023AA, + 0x00004072, 0x00050081, 0x0000000D, 0x0000409C, 0x0000304F, 0x00000019, 0x00050085, 0x0000000D, + 0x00002496, 0x000024CB, 0x0000409C, 0x00050081, 0x0000000D, 0x0000499D, 0x00004D11, 0x00004D12, + 0x00050081, 0x0000000D, 0x00005A67, 0x0000499D, 0x00004D15, 0x00050081, 0x0000000D, 0x00001987, + 0x00005A67, 0x00004D14, 0x00050085, 0x0000000D, 0x00003181, 0x000051B7, 0x00001987, 0x00050081, + 0x0000000D, 0x000046E9, 0x00003181, 0x00004D13, 0x00050085, 0x0000000D, 0x00002497, 0x000046E9, + 0x00002496, 0x00050081, 0x0000000D, 0x0000499E, 0x00001B12, 0x00006098, 0x00050081, 0x0000000D, + 0x00005A68, 0x0000499E, 0x00005D1A, 0x00050081, 0x0000000D, 0x00001988, 0x00005A68, 0x00001B14, + 0x00050085, 0x0000000D, 0x00003182, 0x000051B7, 0x00001988, 0x00050081, 0x0000000D, 0x000046EA, + 0x00003182, 0x00001B13, 0x00050085, 0x0000000D, 0x00002498, 0x000046EA, 0x00002496, 0x00050081, + 0x0000000D, 0x0000499F, 0x0000472C, 0x00002C7A, 0x00050081, 0x0000000D, 0x00005A69, 0x0000499F, + 0x00001B21, 0x00050081, 0x0000000D, 0x00001989, 0x00005A69, 0x0000472E, 0x00050085, 0x0000000D, + 0x00003183, 0x000051B7, 0x00001989, 0x00050081, 0x0000000D, 0x0000436C, 0x00003183, 0x0000472D, + 0x00050085, 0x0000000D, 0x000040DC, 0x0000436C, 0x00002496, 0x00060052, 0x0000001D, 0x000029A7, + 0x00002497, 0x00002818, 0x00000000, 0x00060052, 0x0000001D, 0x0000531A, 0x00002498, 0x000029A7, + 0x00000001, 0x00060052, 0x0000001D, 0x00004817, 0x000040DC, 0x0000531A, 0x00000002, 0x0008004F, + 0x00000018, 0x00004E40, 0x00004817, 0x00004817, 0x00000000, 0x00000001, 0x00000002, 0x000500C7, + 0x00000011, 0x00003108, 0x000026D2, 0x0000084A, 0x00050051, 0x0000000B, 0x0000260D, 0x00003108, + 0x00000001, 0x00050084, 0x0000000B, 0x000053FA, 0x0000260D, 0x00000A3A, 0x00050051, 0x0000000B, + 0x00005B73, 0x00003108, 0x00000000, 0x00050080, 0x0000000B, 0x00003142, 0x000053FA, 0x00005B73, + 0x0003003E, 0x000047EB, 0x000008A4, 0x00050041, 0x0000028A, 0x000026E6, 0x000047EB, 0x00003142, + 0x0004003D, 0x0000000D, 0x00006234, 0x000026E6, 0x00060050, 0x00000018, 0x0000466C, 0x00006234, + 0x00006234, 0x00006234, 0x00050081, 0x00000018, 0x000053D2, 0x00004E40, 0x0000466C, 0x0008000C, + 0x00000018, 0x00004C45, 0x00000001, 0x0000002B, 0x000053D2, 0x00000A2C, 0x00000A16, 0x00050051, + 0x0000000D, 0x00004189, 0x00004C45, 0x00000000, 0x00050051, 0x0000000D, 0x00004CFC, 0x00004C45, + 0x00000001, 0x00050051, 0x0000000D, 0x00001D30, 0x00004C45, 0x00000002, 0x00070050, 0x0000001D, + 0x00005788, 0x00004189, 0x00004CFC, 0x00001D30, 0x0000008A, 0x0003003E, 0x00000CB5, 0x00005788, + 0x000100FD, 0x00010038, +}; diff --git a/src/ui/shaders/vulkan_spirv/guest_output_ffx_fsr_rcas_ps.h b/src/ui/shaders/vulkan_spirv/guest_output_ffx_fsr_rcas_ps.h new file mode 100644 index 0000000..21fe780 --- /dev/null +++ b/src/ui/shaders/vulkan_spirv/guest_output_ffx_fsr_rcas_ps.h @@ -0,0 +1,302 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 25152 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %5663 "main" %gl_FragCoord %3253 + OpExecutionMode %5663 OriginUpperLeft + OpDecorate %gl_FragCoord BuiltIn FragCoord + OpDecorate %_struct_1010 Block + OpMemberDecorate %_struct_1010 0 Offset 16 + OpMemberDecorate %_struct_1010 1 Offset 24 + OpDecorate %3253 Location 0 + OpDecorate %3575 Binding 0 + OpDecorate %3575 DescriptorSet 0 + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %float = OpTypeFloat 32 + %uint = OpTypeInt 32 0 + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %v4float = OpTypeVector %float 4 + %v2uint = OpTypeVector %uint 2 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%gl_FragCoord = OpVariable %_ptr_Input_v4float Input + %v2float = OpTypeVector %float 2 +%_struct_1010 = OpTypeStruct %v2int %float +%_ptr_PushConstant__struct_1010 = OpTypePointer PushConstant %_struct_1010 + %3305 = OpVariable %_ptr_PushConstant__struct_1010 PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_v2int = OpTypePointer PushConstant %v2int + %int_1 = OpConstant %int 1 +%_ptr_PushConstant_float = OpTypePointer PushConstant %float + %float_1 = OpConstant %float 1 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %3253 = OpVariable %_ptr_Output_v4float Output + %float_0 = OpConstant %float 0 +%uint_2129764351 = OpConstant %uint 2129764351 + %float_2 = OpConstant %float 2 + %150 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_150 = OpTypePointer UniformConstant %150 + %3575 = OpVariable %_ptr_UniformConstant_150 UniformConstant + %int_n1 = OpConstant %int -1 + %1803 = OpConstantComposite %v2int %int_0 %int_n1 + %1806 = OpConstantComposite %v2int %int_n1 %int_0 + %1824 = OpConstantComposite %v2int %int_1 %int_0 + %1827 = OpConstantComposite %v2int %int_0 %int_1 + %float_n4 = OpConstant %float -4 + %float_4 = OpConstant %float 4 +%float_n0_1875 = OpConstant %float -0.1875 + %float_0_25 = OpConstant %float 0.25 + %5663 = OpFunction %void None %1282 + %24949 = OpLabel + %18571 = OpLoad %v4float %gl_FragCoord + %14008 = OpVectorShuffle %v2float %18571 %18571 0 1 + %17656 = OpConvertFToS %v2int %14008 + %19279 = OpAccessChain %_ptr_PushConstant_v2int %3305 %int_0 + %22822 = OpLoad %v2int %19279 + %23312 = OpISub %v2int %17656 %22822 + %9938 = OpBitcast %v2uint %23312 + %20997 = OpAccessChain %_ptr_PushConstant_float %3305 %int_1 + %22237 = OpLoad %float %20997 + %16454 = OpBitcast %uint %22237 + %6990 = OpBitcast %v2int %9938 + %14365 = OpIAdd %v2int %6990 %1803 + %22164 = OpLoad %150 %3575 + %8899 = OpImageFetch %v4float %22164 %14365 Lod %int_0 + %19729 = OpCompositeExtract %float %8899 0 + %6930 = OpCompositeExtract %float %8899 1 + %18220 = OpCompositeExtract %float %8899 2 + %20349 = OpIAdd %v2int %6990 %1806 + %16541 = OpLoad %150 %3575 + %8900 = OpImageFetch %v4float %16541 %20349 Lod %int_0 + %19730 = OpCompositeExtract %float %8900 0 + %24728 = OpCompositeExtract %float %8900 1 + %11386 = OpCompositeExtract %float %8900 2 + %16530 = OpLoad %150 %3575 + %19121 = OpImageFetch %v4float %16530 %6990 Lod %int_0 + %19731 = OpCompositeExtract %float %19121 0 + %6931 = OpCompositeExtract %float %19121 1 + %18221 = OpCompositeExtract %float %19121 2 + %20350 = OpIAdd %v2int %6990 %1824 + %16542 = OpLoad %150 %3575 + %8901 = OpImageFetch %v4float %16542 %20350 Lod %int_0 + %19732 = OpCompositeExtract %float %8901 0 + %6932 = OpCompositeExtract %float %8901 1 + %18222 = OpCompositeExtract %float %8901 2 + %20351 = OpIAdd %v2int %6990 %1827 + %16543 = OpLoad %150 %3575 + %8902 = OpImageFetch %v4float %16543 %20351 Lod %int_0 + %19733 = OpCompositeExtract %float %8902 0 + %23834 = OpCompositeExtract %float %8902 1 + %6945 = OpCompositeExtract %float %8902 2 + %15372 = OpExtInst %float %1 FMin %19730 %19732 + %25151 = OpExtInst %float %1 FMin %19729 %15372 + %15948 = OpExtInst %float %1 FMin %25151 %19733 + %15949 = OpExtInst %float %1 FMin %24728 %6932 + %15950 = OpExtInst %float %1 FMin %6930 %15949 + %15951 = OpExtInst %float %1 FMin %15950 %23834 + %15952 = OpExtInst %float %1 FMin %11386 %18222 + %15953 = OpExtInst %float %1 FMin %18220 %15952 + %10905 = OpExtInst %float %1 FMin %15953 %6945 + %24296 = OpExtInst %float %1 FMax %19730 %19732 + %17523 = OpExtInst %float %1 FMax %19729 %24296 + %21851 = OpExtInst %float %1 FMax %17523 %19733 + %21852 = OpExtInst %float %1 FMax %24728 %6932 + %21853 = OpExtInst %float %1 FMax %6930 %21852 + %21854 = OpExtInst %float %1 FMax %21853 %23834 + %21855 = OpExtInst %float %1 FMax %11386 %18222 + %21848 = OpExtInst %float %1 FMax %18220 %21855 + %10142 = OpExtInst %float %1 FMax %21848 %6945 + %24762 = OpExtInst %float %1 FMin %15948 %19731 + %21997 = OpFDiv %float %float_0_25 %21851 + %10377 = OpFMul %float %24762 %21997 + %21327 = OpExtInst %float %1 FMin %15951 %6931 + %17454 = OpFDiv %float %float_0_25 %21854 + %10378 = OpFMul %float %21327 %17454 + %21328 = OpExtInst %float %1 FMin %10905 %18221 + %17457 = OpFDiv %float %float_0_25 %10142 + %24307 = OpFMul %float %21328 %17457 + %16512 = OpExtInst %float %1 FMax %21851 %19731 + %22147 = OpFSub %float %float_1 %16512 + %13544 = OpFMul %float %float_4 %15948 + %19323 = OpFAdd %float %13544 %float_n4 + %20054 = OpFDiv %float %float_1 %19323 + %20866 = OpFMul %float %22147 %20054 + %16513 = OpExtInst %float %1 FMax %21854 %6931 + %22148 = OpFSub %float %float_1 %16513 + %13545 = OpFMul %float %float_4 %15951 + %19324 = OpFAdd %float %13545 %float_n4 + %20055 = OpFDiv %float %float_1 %19324 + %20867 = OpFMul %float %22148 %20055 + %16514 = OpExtInst %float %1 FMax %10142 %18221 + %22149 = OpFSub %float %float_1 %16514 + %13546 = OpFMul %float %float_4 %10905 + %19325 = OpFAdd %float %13546 %float_n4 + %22199 = OpFDiv %float %float_1 %19325 + %15174 = OpFMul %float %22149 %22199 + %22356 = OpFNegate %float %10377 + %23705 = OpExtInst %float %1 FMax %22356 %20866 + %16409 = OpFNegate %float %10378 + %9177 = OpExtInst %float %1 FMax %16409 %20867 + %14264 = OpFNegate %float %24307 + %12648 = OpExtInst %float %1 FMax %14264 %15174 + %18923 = OpExtInst %float %1 FMax %9177 %12648 + %7826 = OpExtInst %float %1 FMax %23705 %18923 + %10548 = OpExtInst %float %1 FMin %7826 %float_0 + %8860 = OpExtInst %float %1 FMax %float_n0_1875 %10548 + %22576 = OpBitcast %float %16454 + %20919 = OpFMul %float %8860 %22576 + %23316 = OpFMul %float %float_4 %20919 + %16498 = OpFAdd %float %23316 %float_1 + %6551 = OpBitcast %uint %16498 + %7563 = OpISub %uint %uint_2129764351 %6551 + %9419 = OpBitcast %float %7563 + %9130 = OpFNegate %float %9419 + %12367 = OpFMul %float %9130 %16498 + %16540 = OpFAdd %float %12367 %float_2 + %9366 = OpFMul %float %9419 %16540 + %18845 = OpFAdd %float %19729 %19730 + %23143 = OpFAdd %float %18845 %19733 + %6535 = OpFAdd %float %23143 %19732 + %12673 = OpFMul %float %20919 %6535 + %18153 = OpFAdd %float %12673 %19731 + %9367 = OpFMul %float %18153 %9366 + %18846 = OpFAdd %float %6930 %24728 + %23144 = OpFAdd %float %18846 %23834 + %6536 = OpFAdd %float %23144 %6932 + %12674 = OpFMul %float %20919 %6536 + %18154 = OpFAdd %float %12674 %6931 + %9368 = OpFMul %float %18154 %9366 + %18847 = OpFAdd %float %18220 %11386 + %23145 = OpFAdd %float %18847 %6945 + %6537 = OpFAdd %float %23145 %18222 + %12675 = OpFMul %float %20919 %6537 + %17222 = OpFAdd %float %12675 %18221 + %16570 = OpFMul %float %17222 %9366 + %14687 = OpCompositeConstruct %v4float %9367 %9368 %16570 %float_1 + OpStore %3253 %14687 + OpReturn + OpFunctionEnd +#endif + +const uint32_t guest_output_ffx_fsr_rcas_ps[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006240, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0007000F, 0x00000004, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000C93, 0x00000CB5, 0x00030010, + 0x0000161F, 0x00000007, 0x00040047, 0x00000C93, 0x0000000B, 0x0000000F, 0x00030047, 0x000003F2, + 0x00000002, 0x00050048, 0x000003F2, 0x00000000, 0x00000023, 0x00000010, 0x00050048, 0x000003F2, + 0x00000001, 0x00000023, 0x00000018, 0x00040047, 0x00000CB5, 0x0000001E, 0x00000000, 0x00040047, + 0x00000DF7, 0x00000021, 0x00000000, 0x00040047, 0x00000DF7, 0x00000022, 0x00000000, 0x00020013, + 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00030016, 0x0000000D, 0x00000020, 0x00040015, + 0x0000000B, 0x00000020, 0x00000000, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x00040017, + 0x00000012, 0x0000000C, 0x00000002, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x00040017, + 0x00000011, 0x0000000B, 0x00000002, 0x00040020, 0x0000029A, 0x00000001, 0x0000001D, 0x0004003B, + 0x0000029A, 0x00000C93, 0x00000001, 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x0004001E, + 0x000003F2, 0x00000012, 0x0000000D, 0x00040020, 0x0000066F, 0x00000009, 0x000003F2, 0x0004003B, + 0x0000066F, 0x00000CE9, 0x00000009, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x00040020, + 0x0000028F, 0x00000009, 0x00000012, 0x0004002B, 0x0000000C, 0x00000A0E, 0x00000001, 0x00040020, + 0x0000028A, 0x00000009, 0x0000000D, 0x0004002B, 0x0000000D, 0x0000008A, 0x3F800000, 0x00040020, + 0x0000029B, 0x00000003, 0x0000001D, 0x0004003B, 0x0000029B, 0x00000CB5, 0x00000003, 0x0004002B, + 0x0000000D, 0x00000A0C, 0x00000000, 0x0004002B, 0x0000000B, 0x000000B2, 0x7EF19FFF, 0x0004002B, + 0x0000000D, 0x00000018, 0x40000000, 0x00090019, 0x00000096, 0x0000000D, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00040020, 0x00000313, 0x00000000, 0x00000096, + 0x0004003B, 0x00000313, 0x00000DF7, 0x00000000, 0x0004002B, 0x0000000C, 0x00000A08, 0xFFFFFFFF, + 0x0005002C, 0x00000012, 0x0000070B, 0x00000A0B, 0x00000A08, 0x0005002C, 0x00000012, 0x0000070E, + 0x00000A08, 0x00000A0B, 0x0005002C, 0x00000012, 0x00000720, 0x00000A0E, 0x00000A0B, 0x0005002C, + 0x00000012, 0x00000723, 0x00000A0B, 0x00000A0E, 0x0004002B, 0x0000000D, 0x0000025D, 0xC0800000, + 0x0004002B, 0x0000000D, 0x00000B69, 0x40800000, 0x0004002B, 0x0000000D, 0x0000045E, 0xBE400000, + 0x0004002B, 0x0000000D, 0x0000016E, 0x3E800000, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, + 0x00000502, 0x000200F8, 0x00006175, 0x0004003D, 0x0000001D, 0x0000488B, 0x00000C93, 0x0007004F, + 0x00000013, 0x000036B8, 0x0000488B, 0x0000488B, 0x00000000, 0x00000001, 0x0004006E, 0x00000012, + 0x000044F8, 0x000036B8, 0x00050041, 0x0000028F, 0x00004B4F, 0x00000CE9, 0x00000A0B, 0x0004003D, + 0x00000012, 0x00005926, 0x00004B4F, 0x00050082, 0x00000012, 0x00005B10, 0x000044F8, 0x00005926, + 0x0004007C, 0x00000011, 0x000026D2, 0x00005B10, 0x00050041, 0x0000028A, 0x00005205, 0x00000CE9, + 0x00000A0E, 0x0004003D, 0x0000000D, 0x000056DD, 0x00005205, 0x0004007C, 0x0000000B, 0x00004046, + 0x000056DD, 0x0004007C, 0x00000012, 0x00001B4E, 0x000026D2, 0x00050080, 0x00000012, 0x0000381D, + 0x00001B4E, 0x0000070B, 0x0004003D, 0x00000096, 0x00005694, 0x00000DF7, 0x0007005F, 0x0000001D, + 0x000022C3, 0x00005694, 0x0000381D, 0x00000002, 0x00000A0B, 0x00050051, 0x0000000D, 0x00004D11, + 0x000022C3, 0x00000000, 0x00050051, 0x0000000D, 0x00001B12, 0x000022C3, 0x00000001, 0x00050051, + 0x0000000D, 0x0000472C, 0x000022C3, 0x00000002, 0x00050080, 0x00000012, 0x00004F7D, 0x00001B4E, + 0x0000070E, 0x0004003D, 0x00000096, 0x0000409D, 0x00000DF7, 0x0007005F, 0x0000001D, 0x000022C4, + 0x0000409D, 0x00004F7D, 0x00000002, 0x00000A0B, 0x00050051, 0x0000000D, 0x00004D12, 0x000022C4, + 0x00000000, 0x00050051, 0x0000000D, 0x00006098, 0x000022C4, 0x00000001, 0x00050051, 0x0000000D, + 0x00002C7A, 0x000022C4, 0x00000002, 0x0004003D, 0x00000096, 0x00004092, 0x00000DF7, 0x0007005F, + 0x0000001D, 0x00004AB1, 0x00004092, 0x00001B4E, 0x00000002, 0x00000A0B, 0x00050051, 0x0000000D, + 0x00004D13, 0x00004AB1, 0x00000000, 0x00050051, 0x0000000D, 0x00001B13, 0x00004AB1, 0x00000001, + 0x00050051, 0x0000000D, 0x0000472D, 0x00004AB1, 0x00000002, 0x00050080, 0x00000012, 0x00004F7E, + 0x00001B4E, 0x00000720, 0x0004003D, 0x00000096, 0x0000409E, 0x00000DF7, 0x0007005F, 0x0000001D, + 0x000022C5, 0x0000409E, 0x00004F7E, 0x00000002, 0x00000A0B, 0x00050051, 0x0000000D, 0x00004D14, + 0x000022C5, 0x00000000, 0x00050051, 0x0000000D, 0x00001B14, 0x000022C5, 0x00000001, 0x00050051, + 0x0000000D, 0x0000472E, 0x000022C5, 0x00000002, 0x00050080, 0x00000012, 0x00004F7F, 0x00001B4E, + 0x00000723, 0x0004003D, 0x00000096, 0x0000409F, 0x00000DF7, 0x0007005F, 0x0000001D, 0x000022C6, + 0x0000409F, 0x00004F7F, 0x00000002, 0x00000A0B, 0x00050051, 0x0000000D, 0x00004D15, 0x000022C6, + 0x00000000, 0x00050051, 0x0000000D, 0x00005D1A, 0x000022C6, 0x00000001, 0x00050051, 0x0000000D, + 0x00001B21, 0x000022C6, 0x00000002, 0x0007000C, 0x0000000D, 0x00003C0C, 0x00000001, 0x00000025, + 0x00004D12, 0x00004D14, 0x0007000C, 0x0000000D, 0x0000623F, 0x00000001, 0x00000025, 0x00004D11, + 0x00003C0C, 0x0007000C, 0x0000000D, 0x00003E4C, 0x00000001, 0x00000025, 0x0000623F, 0x00004D15, + 0x0007000C, 0x0000000D, 0x00003E4D, 0x00000001, 0x00000025, 0x00006098, 0x00001B14, 0x0007000C, + 0x0000000D, 0x00003E4E, 0x00000001, 0x00000025, 0x00001B12, 0x00003E4D, 0x0007000C, 0x0000000D, + 0x00003E4F, 0x00000001, 0x00000025, 0x00003E4E, 0x00005D1A, 0x0007000C, 0x0000000D, 0x00003E50, + 0x00000001, 0x00000025, 0x00002C7A, 0x0000472E, 0x0007000C, 0x0000000D, 0x00003E51, 0x00000001, + 0x00000025, 0x0000472C, 0x00003E50, 0x0007000C, 0x0000000D, 0x00002A99, 0x00000001, 0x00000025, + 0x00003E51, 0x00001B21, 0x0007000C, 0x0000000D, 0x00005EE8, 0x00000001, 0x00000028, 0x00004D12, + 0x00004D14, 0x0007000C, 0x0000000D, 0x00004473, 0x00000001, 0x00000028, 0x00004D11, 0x00005EE8, + 0x0007000C, 0x0000000D, 0x0000555B, 0x00000001, 0x00000028, 0x00004473, 0x00004D15, 0x0007000C, + 0x0000000D, 0x0000555C, 0x00000001, 0x00000028, 0x00006098, 0x00001B14, 0x0007000C, 0x0000000D, + 0x0000555D, 0x00000001, 0x00000028, 0x00001B12, 0x0000555C, 0x0007000C, 0x0000000D, 0x0000555E, + 0x00000001, 0x00000028, 0x0000555D, 0x00005D1A, 0x0007000C, 0x0000000D, 0x0000555F, 0x00000001, + 0x00000028, 0x00002C7A, 0x0000472E, 0x0007000C, 0x0000000D, 0x00005558, 0x00000001, 0x00000028, + 0x0000472C, 0x0000555F, 0x0007000C, 0x0000000D, 0x0000279E, 0x00000001, 0x00000028, 0x00005558, + 0x00001B21, 0x0007000C, 0x0000000D, 0x000060BA, 0x00000001, 0x00000025, 0x00003E4C, 0x00004D13, + 0x00050088, 0x0000000D, 0x000055ED, 0x0000016E, 0x0000555B, 0x00050085, 0x0000000D, 0x00002889, + 0x000060BA, 0x000055ED, 0x0007000C, 0x0000000D, 0x0000534F, 0x00000001, 0x00000025, 0x00003E4F, + 0x00001B13, 0x00050088, 0x0000000D, 0x0000442E, 0x0000016E, 0x0000555E, 0x00050085, 0x0000000D, + 0x0000288A, 0x0000534F, 0x0000442E, 0x0007000C, 0x0000000D, 0x00005350, 0x00000001, 0x00000025, + 0x00002A99, 0x0000472D, 0x00050088, 0x0000000D, 0x00004431, 0x0000016E, 0x0000279E, 0x00050085, + 0x0000000D, 0x00005EF3, 0x00005350, 0x00004431, 0x0007000C, 0x0000000D, 0x00004080, 0x00000001, + 0x00000028, 0x0000555B, 0x00004D13, 0x00050083, 0x0000000D, 0x00005683, 0x0000008A, 0x00004080, + 0x00050085, 0x0000000D, 0x000034E8, 0x00000B69, 0x00003E4C, 0x00050081, 0x0000000D, 0x00004B7B, + 0x000034E8, 0x0000025D, 0x00050088, 0x0000000D, 0x00004E56, 0x0000008A, 0x00004B7B, 0x00050085, + 0x0000000D, 0x00005182, 0x00005683, 0x00004E56, 0x0007000C, 0x0000000D, 0x00004081, 0x00000001, + 0x00000028, 0x0000555E, 0x00001B13, 0x00050083, 0x0000000D, 0x00005684, 0x0000008A, 0x00004081, + 0x00050085, 0x0000000D, 0x000034E9, 0x00000B69, 0x00003E4F, 0x00050081, 0x0000000D, 0x00004B7C, + 0x000034E9, 0x0000025D, 0x00050088, 0x0000000D, 0x00004E57, 0x0000008A, 0x00004B7C, 0x00050085, + 0x0000000D, 0x00005183, 0x00005684, 0x00004E57, 0x0007000C, 0x0000000D, 0x00004082, 0x00000001, + 0x00000028, 0x0000279E, 0x0000472D, 0x00050083, 0x0000000D, 0x00005685, 0x0000008A, 0x00004082, + 0x00050085, 0x0000000D, 0x000034EA, 0x00000B69, 0x00002A99, 0x00050081, 0x0000000D, 0x00004B7D, + 0x000034EA, 0x0000025D, 0x00050088, 0x0000000D, 0x000056B7, 0x0000008A, 0x00004B7D, 0x00050085, + 0x0000000D, 0x00003B46, 0x00005685, 0x000056B7, 0x0004007F, 0x0000000D, 0x00005754, 0x00002889, + 0x0007000C, 0x0000000D, 0x00005C99, 0x00000001, 0x00000028, 0x00005754, 0x00005182, 0x0004007F, + 0x0000000D, 0x00004019, 0x0000288A, 0x0007000C, 0x0000000D, 0x000023D9, 0x00000001, 0x00000028, + 0x00004019, 0x00005183, 0x0004007F, 0x0000000D, 0x000037B8, 0x00005EF3, 0x0007000C, 0x0000000D, + 0x00003168, 0x00000001, 0x00000028, 0x000037B8, 0x00003B46, 0x0007000C, 0x0000000D, 0x000049EB, + 0x00000001, 0x00000028, 0x000023D9, 0x00003168, 0x0007000C, 0x0000000D, 0x00001E92, 0x00000001, + 0x00000028, 0x00005C99, 0x000049EB, 0x0007000C, 0x0000000D, 0x00002934, 0x00000001, 0x00000025, + 0x00001E92, 0x00000A0C, 0x0007000C, 0x0000000D, 0x0000229C, 0x00000001, 0x00000028, 0x0000045E, + 0x00002934, 0x0004007C, 0x0000000D, 0x00005830, 0x00004046, 0x00050085, 0x0000000D, 0x000051B7, + 0x0000229C, 0x00005830, 0x00050085, 0x0000000D, 0x00005B14, 0x00000B69, 0x000051B7, 0x00050081, + 0x0000000D, 0x00004072, 0x00005B14, 0x0000008A, 0x0004007C, 0x0000000B, 0x00001997, 0x00004072, + 0x00050082, 0x0000000B, 0x00001D8B, 0x000000B2, 0x00001997, 0x0004007C, 0x0000000D, 0x000024CB, + 0x00001D8B, 0x0004007F, 0x0000000D, 0x000023AA, 0x000024CB, 0x00050085, 0x0000000D, 0x0000304F, + 0x000023AA, 0x00004072, 0x00050081, 0x0000000D, 0x0000409C, 0x0000304F, 0x00000018, 0x00050085, + 0x0000000D, 0x00002496, 0x000024CB, 0x0000409C, 0x00050081, 0x0000000D, 0x0000499D, 0x00004D11, + 0x00004D12, 0x00050081, 0x0000000D, 0x00005A67, 0x0000499D, 0x00004D15, 0x00050081, 0x0000000D, + 0x00001987, 0x00005A67, 0x00004D14, 0x00050085, 0x0000000D, 0x00003181, 0x000051B7, 0x00001987, + 0x00050081, 0x0000000D, 0x000046E9, 0x00003181, 0x00004D13, 0x00050085, 0x0000000D, 0x00002497, + 0x000046E9, 0x00002496, 0x00050081, 0x0000000D, 0x0000499E, 0x00001B12, 0x00006098, 0x00050081, + 0x0000000D, 0x00005A68, 0x0000499E, 0x00005D1A, 0x00050081, 0x0000000D, 0x00001988, 0x00005A68, + 0x00001B14, 0x00050085, 0x0000000D, 0x00003182, 0x000051B7, 0x00001988, 0x00050081, 0x0000000D, + 0x000046EA, 0x00003182, 0x00001B13, 0x00050085, 0x0000000D, 0x00002498, 0x000046EA, 0x00002496, + 0x00050081, 0x0000000D, 0x0000499F, 0x0000472C, 0x00002C7A, 0x00050081, 0x0000000D, 0x00005A69, + 0x0000499F, 0x00001B21, 0x00050081, 0x0000000D, 0x00001989, 0x00005A69, 0x0000472E, 0x00050085, + 0x0000000D, 0x00003183, 0x000051B7, 0x00001989, 0x00050081, 0x0000000D, 0x00004346, 0x00003183, + 0x0000472D, 0x00050085, 0x0000000D, 0x000040BA, 0x00004346, 0x00002496, 0x00070050, 0x0000001D, + 0x0000395F, 0x00002497, 0x00002498, 0x000040BA, 0x0000008A, 0x0003003E, 0x00000CB5, 0x0000395F, + 0x000100FD, 0x00010038, +}; diff --git a/src/ui/shaders/vulkan_spirv/guest_output_triangle_strip_rect_vs.h b/src/ui/shaders/vulkan_spirv/guest_output_triangle_strip_rect_vs.h new file mode 100644 index 0000000..ce69dcd --- /dev/null +++ b/src/ui/shaders/vulkan_spirv/guest_output_triangle_strip_rect_vs.h @@ -0,0 +1,105 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 24012 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %5663 "main" %4930 %gl_VertexIndex + OpDecorate %_struct_374 Block + OpMemberDecorate %_struct_374 0 BuiltIn Position + OpMemberDecorate %_struct_374 1 BuiltIn PointSize + OpMemberDecorate %_struct_374 2 BuiltIn ClipDistance + OpMemberDecorate %_struct_374 3 BuiltIn CullDistance + OpDecorate %_struct_1030 Block + OpMemberDecorate %_struct_1030 0 Offset 0 + OpMemberDecorate %_struct_1030 1 Offset 8 + OpDecorate %gl_VertexIndex BuiltIn VertexIndex + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %uint_1 = OpConstant %uint 1 +%_arr_float_uint_1 = OpTypeArray %float %uint_1 +%_struct_374 = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 +%_ptr_Output__struct_374 = OpTypePointer Output %_struct_374 + %4930 = OpVariable %_ptr_Output__struct_374 Output + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 + %v2float = OpTypeVector %float 2 +%_struct_1030 = OpTypeStruct %v2float %v2float +%_ptr_PushConstant__struct_1030 = OpTypePointer PushConstant %_struct_1030 + %3305 = OpVariable %_ptr_PushConstant__struct_1030 PushConstant +%_ptr_PushConstant_v2float = OpTypePointer PushConstant %v2float +%_ptr_Input_int = OpTypePointer Input %int +%gl_VertexIndex = OpVariable %_ptr_Input_int Input + %uint_0 = OpConstant %uint 0 + %1819 = OpConstantComposite %v2uint %uint_0 %uint_1 + %int_1 = OpConstant %int 1 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %1828 = OpConstantComposite %v2uint %uint_1 %uint_1 + %5663 = OpFunction %void None %1282 + %23915 = OpLabel + %7053 = OpAccessChain %_ptr_PushConstant_v2float %3305 %int_0 + %17516 = OpLoad %v2float %7053 + %23241 = OpLoad %int %gl_VertexIndex + %9480 = OpBitcast %uint %23241 + %15408 = OpCompositeConstruct %v2uint %9480 %9480 + %14991 = OpShiftRightLogical %v2uint %15408 %1819 + %17567 = OpBitwiseAnd %v2uint %14991 %1828 + %7856 = OpConvertUToF %v2float %17567 + %12606 = OpAccessChain %_ptr_PushConstant_v2float %3305 %int_1 + %24011 = OpLoad %v2float %12606 + %17243 = OpFMul %v2float %7856 %24011 + %16594 = OpFAdd %v2float %17516 %17243 + %10599 = OpCompositeExtract %float %16594 0 + %13956 = OpCompositeExtract %float %16594 1 + %18260 = OpCompositeConstruct %v4float %10599 %13956 %float_0 %float_1 + %12055 = OpAccessChain %_ptr_Output_v4float %4930 %int_0 + OpStore %12055 %18260 + OpReturn + OpFunctionEnd +#endif + +const uint32_t guest_output_triangle_strip_rect_vs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00005DCC, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0007000F, 0x00000000, 0x0000161F, 0x6E69616D, 0x00000000, 0x00001342, 0x00001029, 0x00030047, + 0x00000176, 0x00000002, 0x00050048, 0x00000176, 0x00000000, 0x0000000B, 0x00000000, 0x00050048, + 0x00000176, 0x00000001, 0x0000000B, 0x00000001, 0x00050048, 0x00000176, 0x00000002, 0x0000000B, + 0x00000003, 0x00050048, 0x00000176, 0x00000003, 0x0000000B, 0x00000004, 0x00030047, 0x00000406, + 0x00000002, 0x00050048, 0x00000406, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000406, + 0x00000001, 0x00000023, 0x00000008, 0x00040047, 0x00001029, 0x0000000B, 0x0000002A, 0x00020013, + 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00040015, 0x0000000B, 0x00000020, 0x00000000, + 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x00030016, 0x0000000D, 0x00000020, 0x00040017, + 0x0000001D, 0x0000000D, 0x00000004, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004001C, + 0x0000025C, 0x0000000D, 0x00000A0D, 0x0006001E, 0x00000176, 0x0000001D, 0x0000000D, 0x0000025C, + 0x0000025C, 0x00040020, 0x000003F3, 0x00000003, 0x00000176, 0x0004003B, 0x000003F3, 0x00001342, + 0x00000003, 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A0B, + 0x00000000, 0x00040017, 0x00000013, 0x0000000D, 0x00000002, 0x0004001E, 0x00000406, 0x00000013, + 0x00000013, 0x00040020, 0x00000683, 0x00000009, 0x00000406, 0x0004003B, 0x00000683, 0x00000CE9, + 0x00000009, 0x00040020, 0x00000290, 0x00000009, 0x00000013, 0x00040020, 0x00000289, 0x00000001, + 0x0000000C, 0x0004003B, 0x00000289, 0x00001029, 0x00000001, 0x0004002B, 0x0000000B, 0x00000A0A, + 0x00000000, 0x0005002C, 0x00000011, 0x0000071B, 0x00000A0A, 0x00000A0D, 0x0004002B, 0x0000000C, + 0x00000A0E, 0x00000001, 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, 0x0004002B, 0x0000000D, + 0x0000008A, 0x3F800000, 0x00040020, 0x0000029A, 0x00000003, 0x0000001D, 0x0005002C, 0x00000011, + 0x00000724, 0x00000A0D, 0x00000A0D, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, + 0x000200F8, 0x00005D6B, 0x00050041, 0x00000290, 0x00001B8D, 0x00000CE9, 0x00000A0B, 0x0004003D, + 0x00000013, 0x0000446C, 0x00001B8D, 0x0004003D, 0x0000000C, 0x00005AC9, 0x00001029, 0x0004007C, + 0x0000000B, 0x00002508, 0x00005AC9, 0x00050050, 0x00000011, 0x00003C30, 0x00002508, 0x00002508, + 0x000500C2, 0x00000011, 0x00003A8F, 0x00003C30, 0x0000071B, 0x000500C7, 0x00000011, 0x0000449F, + 0x00003A8F, 0x00000724, 0x00040070, 0x00000013, 0x00001EB0, 0x0000449F, 0x00050041, 0x00000290, + 0x0000313E, 0x00000CE9, 0x00000A0E, 0x0004003D, 0x00000013, 0x00005DCB, 0x0000313E, 0x00050085, + 0x00000013, 0x0000435B, 0x00001EB0, 0x00005DCB, 0x00050081, 0x00000013, 0x000040D2, 0x0000446C, + 0x0000435B, 0x00050051, 0x0000000D, 0x00002967, 0x000040D2, 0x00000000, 0x00050051, 0x0000000D, + 0x00003684, 0x000040D2, 0x00000001, 0x00070050, 0x0000001D, 0x00004754, 0x00002967, 0x00003684, + 0x00000A0C, 0x0000008A, 0x00050041, 0x0000029A, 0x00002F17, 0x00001342, 0x00000A0B, 0x0003003E, + 0x00002F17, 0x00004754, 0x000100FD, 0x00010038, +}; diff --git a/src/ui/shaders/vulkan_spirv/immediate_ps.h b/src/ui/shaders/vulkan_spirv/immediate_ps.h new file mode 100644 index 0000000..bf6e9e3 --- /dev/null +++ b/src/ui/shaders/vulkan_spirv/immediate_ps.h @@ -0,0 +1,66 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 24608 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %5663 "main" %3080 %5914 %4693 + OpExecutionMode %5663 OriginUpperLeft + OpDecorate %3080 Location 0 + OpDecorate %5914 Location 1 + OpDecorate %5818 Binding 0 + OpDecorate %5818 DescriptorSet 0 + OpDecorate %4693 Location 0 + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %3080 = OpVariable %_ptr_Output_v4float Output +%_ptr_Input_v4float = OpTypePointer Input %v4float + %5914 = OpVariable %_ptr_Input_v4float Input + %150 = OpTypeImage %float 2D 0 0 0 1 Unknown + %510 = OpTypeSampledImage %150 +%_ptr_UniformConstant_510 = OpTypePointer UniformConstant %510 + %5818 = OpVariable %_ptr_UniformConstant_510 UniformConstant + %v2float = OpTypeVector %float 2 +%_ptr_Input_v2float = OpTypePointer Input %v2float + %4693 = OpVariable %_ptr_Input_v2float Input + %float_0 = OpConstant %float 0 + %5663 = OpFunction %void None %1282 + %24607 = OpLabel + %20754 = OpLoad %v4float %5914 + %24285 = OpLoad %510 %5818 + %8179 = OpLoad %v2float %4693 + %6686 = OpImageSampleExplicitLod %v4float %24285 %8179 Lod %float_0 + %8939 = OpFMul %v4float %20754 %6686 + OpStore %3080 %8939 + OpReturn + OpFunctionEnd +#endif + +const uint32_t immediate_ps[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006020, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x0008000F, 0x00000004, 0x0000161F, 0x6E69616D, 0x00000000, 0x00000C08, 0x0000171A, 0x00001255, + 0x00030010, 0x0000161F, 0x00000007, 0x00040047, 0x00000C08, 0x0000001E, 0x00000000, 0x00040047, + 0x0000171A, 0x0000001E, 0x00000001, 0x00040047, 0x000016BA, 0x00000021, 0x00000000, 0x00040047, + 0x000016BA, 0x00000022, 0x00000000, 0x00040047, 0x00001255, 0x0000001E, 0x00000000, 0x00020013, + 0x00000008, 0x00030021, 0x00000502, 0x00000008, 0x00030016, 0x0000000D, 0x00000020, 0x00040017, + 0x0000001D, 0x0000000D, 0x00000004, 0x00040020, 0x0000029A, 0x00000003, 0x0000001D, 0x0004003B, + 0x0000029A, 0x00000C08, 0x00000003, 0x00040020, 0x0000029B, 0x00000001, 0x0000001D, 0x0004003B, + 0x0000029B, 0x0000171A, 0x00000001, 0x00090019, 0x00000096, 0x0000000D, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x0003001B, 0x000001FE, 0x00000096, 0x00040020, + 0x0000047B, 0x00000000, 0x000001FE, 0x0004003B, 0x0000047B, 0x000016BA, 0x00000000, 0x00040017, + 0x00000013, 0x0000000D, 0x00000002, 0x00040020, 0x00000290, 0x00000001, 0x00000013, 0x0004003B, + 0x00000290, 0x00001255, 0x00000001, 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, 0x00050036, + 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x0000601F, 0x0004003D, 0x0000001D, + 0x00005112, 0x0000171A, 0x0004003D, 0x000001FE, 0x00005EDD, 0x000016BA, 0x0004003D, 0x00000013, + 0x00001FF3, 0x00001255, 0x00070058, 0x0000001D, 0x00001A1E, 0x00005EDD, 0x00001FF3, 0x00000002, + 0x00000A0C, 0x00050085, 0x0000001D, 0x000022EB, 0x00005112, 0x00001A1E, 0x0003003E, 0x00000C08, + 0x000022EB, 0x000100FD, 0x00010038, +}; diff --git a/src/ui/shaders/vulkan_spirv/immediate_vs.h b/src/ui/shaders/vulkan_spirv/immediate_vs.h new file mode 100644 index 0000000..141c4c4 --- /dev/null +++ b/src/ui/shaders/vulkan_spirv/immediate_vs.h @@ -0,0 +1,112 @@ +// Generated with `xb buildshaders`. +#if 0 +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 11 +; Bound: 24627 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %5663 "main" %4159 %4693 %3080 %5914 %4930 %5474 + OpDecorate %4159 Location 0 + OpDecorate %4693 Location 1 + OpDecorate %3080 Location 1 + OpDecorate %5914 Location 2 + OpDecorate %_struct_419 Block + OpMemberDecorate %_struct_419 0 BuiltIn Position + OpMemberDecorate %_struct_419 1 BuiltIn PointSize + OpMemberDecorate %_struct_419 2 BuiltIn ClipDistance + OpMemberDecorate %_struct_419 3 BuiltIn CullDistance + OpDecorate %5474 Location 0 + OpDecorate %_struct_997 Block + OpMemberDecorate %_struct_997 0 Offset 0 + %void = OpTypeVoid + %1282 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 +%_ptr_Output_v2float = OpTypePointer Output %v2float + %4159 = OpVariable %_ptr_Output_v2float Output +%_ptr_Input_v2float = OpTypePointer Input %v2float + %4693 = OpVariable %_ptr_Input_v2float Input + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %3080 = OpVariable %_ptr_Output_v4float Output +%_ptr_Input_v4float = OpTypePointer Input %v4float + %5914 = OpVariable %_ptr_Input_v4float Input + %uint = OpTypeInt 32 0 + %uint_1 = OpConstant %uint 1 +%_arr_float_uint_1 = OpTypeArray %float %uint_1 +%_struct_419 = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 +%_ptr_Output__struct_419 = OpTypePointer Output %_struct_419 + %4930 = OpVariable %_ptr_Output__struct_419 Output + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 + %5474 = OpVariable %_ptr_Input_v2float Input +%_struct_997 = OpTypeStruct %v2float +%_ptr_PushConstant__struct_997 = OpTypePointer PushConstant %_struct_997 + %3305 = OpVariable %_ptr_PushConstant__struct_997 PushConstant +%_ptr_PushConstant_v2float = OpTypePointer PushConstant %v2float + %float_2 = OpConstant %float 2 + %2981 = OpConstantComposite %v2float %float_2 %float_2 + %float_1 = OpConstant %float 1 + %768 = OpConstantComposite %v2float %float_1 %float_1 + %float_0 = OpConstant %float 0 + %5663 = OpFunction %void None %1282 + %24626 = OpLabel + %20581 = OpLoad %v2float %4693 + OpStore %4159 %20581 + %11060 = OpLoad %v4float %5914 + OpStore %3080 %11060 + %10541 = OpLoad %v2float %5474 + %22255 = OpAccessChain %_ptr_PushConstant_v2float %3305 %int_0 + %12012 = OpLoad %v2float %22255 + %17501 = OpFMul %v2float %10541 %12012 + %13314 = OpFMul %v2float %17501 %2981 + %6620 = OpFSub %v2float %13314 %768 + %22715 = OpCompositeExtract %float %6620 0 + %15569 = OpCompositeExtract %float %6620 1 + %18260 = OpCompositeConstruct %v4float %22715 %15569 %float_0 %float_1 + %12055 = OpAccessChain %_ptr_Output_v4float %4930 %int_0 + OpStore %12055 %18260 + OpReturn + OpFunctionEnd +#endif + +const uint32_t immediate_vs[] = { + 0x07230203, 0x00010000, 0x0008000B, 0x00006033, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, + 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, + 0x000B000F, 0x00000000, 0x0000161F, 0x6E69616D, 0x00000000, 0x0000103F, 0x00001255, 0x00000C08, + 0x0000171A, 0x00001342, 0x00001562, 0x00040047, 0x0000103F, 0x0000001E, 0x00000000, 0x00040047, + 0x00001255, 0x0000001E, 0x00000001, 0x00040047, 0x00000C08, 0x0000001E, 0x00000001, 0x00040047, + 0x0000171A, 0x0000001E, 0x00000002, 0x00030047, 0x000001A3, 0x00000002, 0x00050048, 0x000001A3, + 0x00000000, 0x0000000B, 0x00000000, 0x00050048, 0x000001A3, 0x00000001, 0x0000000B, 0x00000001, + 0x00050048, 0x000001A3, 0x00000002, 0x0000000B, 0x00000003, 0x00050048, 0x000001A3, 0x00000003, + 0x0000000B, 0x00000004, 0x00040047, 0x00001562, 0x0000001E, 0x00000000, 0x00030047, 0x000003E5, + 0x00000002, 0x00050048, 0x000003E5, 0x00000000, 0x00000023, 0x00000000, 0x00020013, 0x00000008, + 0x00030021, 0x00000502, 0x00000008, 0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x00000013, + 0x0000000D, 0x00000002, 0x00040020, 0x00000290, 0x00000003, 0x00000013, 0x0004003B, 0x00000290, + 0x0000103F, 0x00000003, 0x00040020, 0x00000291, 0x00000001, 0x00000013, 0x0004003B, 0x00000291, + 0x00001255, 0x00000001, 0x00040017, 0x0000001D, 0x0000000D, 0x00000004, 0x00040020, 0x0000029A, + 0x00000003, 0x0000001D, 0x0004003B, 0x0000029A, 0x00000C08, 0x00000003, 0x00040020, 0x0000029B, + 0x00000001, 0x0000001D, 0x0004003B, 0x0000029B, 0x0000171A, 0x00000001, 0x00040015, 0x0000000B, + 0x00000020, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A0D, 0x00000001, 0x0004001C, 0x00000261, + 0x0000000D, 0x00000A0D, 0x0006001E, 0x000001A3, 0x0000001D, 0x0000000D, 0x00000261, 0x00000261, + 0x00040020, 0x00000420, 0x00000003, 0x000001A3, 0x0004003B, 0x00000420, 0x00001342, 0x00000003, + 0x00040015, 0x0000000C, 0x00000020, 0x00000001, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, + 0x0004003B, 0x00000291, 0x00001562, 0x00000001, 0x0003001E, 0x000003E5, 0x00000013, 0x00040020, + 0x00000662, 0x00000009, 0x000003E5, 0x0004003B, 0x00000662, 0x00000CE9, 0x00000009, 0x00040020, + 0x00000292, 0x00000009, 0x00000013, 0x0004002B, 0x0000000D, 0x00000018, 0x40000000, 0x0005002C, + 0x00000013, 0x00000BA5, 0x00000018, 0x00000018, 0x0004002B, 0x0000000D, 0x0000008A, 0x3F800000, + 0x0005002C, 0x00000013, 0x00000300, 0x0000008A, 0x0000008A, 0x0004002B, 0x0000000D, 0x00000A0C, + 0x00000000, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x00006032, + 0x0004003D, 0x00000013, 0x00005065, 0x00001255, 0x0003003E, 0x0000103F, 0x00005065, 0x0004003D, + 0x0000001D, 0x00002B34, 0x0000171A, 0x0003003E, 0x00000C08, 0x00002B34, 0x0004003D, 0x00000013, + 0x0000292D, 0x00001562, 0x00050041, 0x00000292, 0x000056EF, 0x00000CE9, 0x00000A0B, 0x0004003D, + 0x00000013, 0x00002EEC, 0x000056EF, 0x00050085, 0x00000013, 0x0000445D, 0x0000292D, 0x00002EEC, + 0x00050085, 0x00000013, 0x00003402, 0x0000445D, 0x00000BA5, 0x00050083, 0x00000013, 0x000019DC, + 0x00003402, 0x00000300, 0x00050051, 0x0000000D, 0x000058BB, 0x000019DC, 0x00000000, 0x00050051, + 0x0000000D, 0x00003CD1, 0x000019DC, 0x00000001, 0x00070050, 0x0000001D, 0x00004754, 0x000058BB, + 0x00003CD1, 0x00000A0C, 0x0000008A, 0x00050041, 0x0000029A, 0x00002F17, 0x00001342, 0x00000A0B, + 0x0003003E, 0x00002F17, 0x00004754, 0x000100FD, 0x00010038, +}; diff --git a/src/ui/surface_gnulinux.cpp b/src/ui/surface_gnulinux.cpp new file mode 100644 index 0000000..a6ea800 --- /dev/null +++ b/src/ui/surface_gnulinux.cpp @@ -0,0 +1,32 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include + +namespace rex { +namespace ui { + +bool XcbWindowSurface::GetSizeImpl(uint32_t& width_out, uint32_t& height_out) const { + xcb_get_geometry_reply_t* reply = + xcb_get_geometry_reply(connection_, xcb_get_geometry(connection_, window_), nullptr); + if (!reply) { + return false; + } + width_out = reply->width; + height_out = reply->height; + std::free(reply); + return true; +} + +} // namespace ui +} // namespace rex diff --git a/src/ui/surface_win.cpp b/src/ui/surface_win.cpp new file mode 100644 index 0000000..8cd18a1 --- /dev/null +++ b/src/ui/surface_win.cpp @@ -0,0 +1,31 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +namespace rex { +namespace ui { + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_GAMES) +bool Win32HwndSurface::GetSizeImpl(uint32_t& width_out, uint32_t& height_out) const { + RECT client_rect; + if (!GetClientRect(hwnd(), &client_rect)) { + return false; + } + // GetClientRect returns a rectangle with 0 origin. + width_out = uint32_t(client_rect.right); + height_out = uint32_t(client_rect.bottom); + return true; +} +#endif + +} // namespace ui +} // namespace rex diff --git a/src/ui/vulkan/linked_type_descriptor_set_allocator.cpp b/src/ui/vulkan/linked_type_descriptor_set_allocator.cpp new file mode 100644 index 0000000..08a0833 --- /dev/null +++ b/src/ui/vulkan/linked_type_descriptor_set_allocator.cpp @@ -0,0 +1,384 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include +#include +#include + +namespace rex { +namespace ui { +namespace vulkan { + +void LinkedTypeDescriptorSetAllocator::Reset() { + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyDescriptorPool, device, + page_usable_latest_.pool); + page_usable_latest_.descriptors_remaining.reset(); + for (const std::pair& page_pair : pages_usable_) { + dfn.vkDestroyDescriptorPool(device, page_pair.second.pool, nullptr); + } + pages_usable_.clear(); + for (VkDescriptorPool pool : pages_full_) { + dfn.vkDestroyDescriptorPool(device, pool, nullptr); + } + pages_full_.clear(); +} + +VkDescriptorSet LinkedTypeDescriptorSetAllocator::Allocate( + VkDescriptorSetLayout descriptor_set_layout, const VkDescriptorPoolSize* descriptor_counts, + uint32_t descriptor_type_count) { + assert_not_zero(descriptor_type_count); +#ifndef NDEBUG + for (uint32_t i = 0; i < descriptor_type_count; ++i) { + const VkDescriptorPoolSize& descriptor_count_for_type = descriptor_counts[i]; + assert_not_zero(descriptor_count_for_type.descriptorCount); + for (uint32_t j = 0; j < i; ++j) { + assert_true(descriptor_counts[j].type != descriptor_count_for_type.type); + } + } +#endif + + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + VkDescriptorSetAllocateInfo descriptor_set_allocate_info; + descriptor_set_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + descriptor_set_allocate_info.pNext = nullptr; + descriptor_set_allocate_info.descriptorSetCount = 1; + descriptor_set_allocate_info.pSetLayouts = &descriptor_set_layout; + VkDescriptorSet descriptor_set; + + // Check if more descriptors have been requested than a page can hold, or + // descriptors of types not provided by this allocator, and if that's the + // case, create a dedicated pool for this allocation. + bool dedicated_descriptor_pool_needed = false; + for (uint32_t i = 0; i < descriptor_type_count; ++i) { + const VkDescriptorPoolSize& descriptor_count_for_type = descriptor_counts[i]; + // If the type is one that's not supported by the allocator, a dedicated + // pool is required. If it's supported, and the allocator has large enough + // pools to hold the requested number of descriptors, + // dedicated_descriptor_pool_needed will be set to false for this iteration, + // and the loop will continue. Otherwise, if that doesn't happen, a + // dedicated pool is required. + dedicated_descriptor_pool_needed = true; + for (uint32_t j = 0; j < descriptor_pool_size_count_; ++j) { + const VkDescriptorPoolSize& descriptor_pool_size = descriptor_pool_sizes_[j]; + if (descriptor_count_for_type.type != descriptor_pool_size.type) { + continue; + } + if (descriptor_count_for_type.descriptorCount <= descriptor_pool_size.descriptorCount) { + // For this type, pages can hold enough descriptors. + dedicated_descriptor_pool_needed = false; + } + break; + } + if (dedicated_descriptor_pool_needed) { + // For at least one requested type, pages can't hold enough descriptors. + break; + } + } + if (dedicated_descriptor_pool_needed) { + VkDescriptorPoolCreateInfo dedicated_descriptor_pool_create_info; + dedicated_descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + dedicated_descriptor_pool_create_info.pNext = nullptr; + dedicated_descriptor_pool_create_info.flags = 0; + dedicated_descriptor_pool_create_info.maxSets = 1; + dedicated_descriptor_pool_create_info.poolSizeCount = descriptor_type_count; + dedicated_descriptor_pool_create_info.pPoolSizes = descriptor_counts; + VkDescriptorPool dedicated_descriptor_pool; + if (dfn.vkCreateDescriptorPool(device, &dedicated_descriptor_pool_create_info, nullptr, + &dedicated_descriptor_pool) != VK_SUCCESS) { + REXLOG_ERROR( + "LinkedTypeDescriptorSetAllocator: Failed to create a dedicated " + "descriptor pool for a descriptor set that is too large for a pool " + "page"); + return VK_NULL_HANDLE; + } + descriptor_set_allocate_info.descriptorPool = dedicated_descriptor_pool; + if (dfn.vkAllocateDescriptorSets(device, &descriptor_set_allocate_info, &descriptor_set) != + VK_SUCCESS) { + REXLOG_ERROR( + "LinkedTypeDescriptorSetAllocator: Failed to allocate descriptors in " + "a dedicated pool"); + dfn.vkDestroyDescriptorPool(device, dedicated_descriptor_pool, nullptr); + return VK_NULL_HANDLE; + } + pages_full_.push_back(dedicated_descriptor_pool); + return descriptor_set; + } + + // Try allocating from the latest page an allocation has happened from, to + // avoid detaching from the map and re-attaching for every allocation. + if (page_usable_latest_.pool != VK_NULL_HANDLE) { + assert_not_zero(page_usable_latest_.descriptor_sets_remaining); + bool allocate_from_latest_page = true; + bool latest_page_becomes_full = page_usable_latest_.descriptor_sets_remaining == 1; + for (uint32_t i = 0; i < descriptor_type_count; ++i) { + const VkDescriptorPoolSize& descriptor_count_for_type = descriptor_counts[i]; + for (uint32_t j = 0; j < descriptor_pool_size_count_; ++j) { + const VkDescriptorPoolSize& descriptors_remaining_for_type = + page_usable_latest_.descriptors_remaining[j]; + if (descriptor_count_for_type.type != descriptors_remaining_for_type.type) { + continue; + } + if (descriptor_count_for_type.descriptorCount >= + descriptors_remaining_for_type.descriptorCount) { + if (descriptor_count_for_type.descriptorCount > + descriptors_remaining_for_type.descriptorCount) { + allocate_from_latest_page = false; + break; + } + latest_page_becomes_full = true; + } + } + if (!allocate_from_latest_page) { + break; + } + } + if (allocate_from_latest_page) { + descriptor_set_allocate_info.descriptorPool = page_usable_latest_.pool; + if (dfn.vkAllocateDescriptorSets(device, &descriptor_set_allocate_info, &descriptor_set) != + VK_SUCCESS) { + descriptor_set = VK_NULL_HANDLE; + // Failed to allocate internally even though there should be enough + // space, don't try to allocate from this pool again at all. + latest_page_becomes_full = true; + } + if (latest_page_becomes_full) { + pages_full_.push_back(page_usable_latest_.pool); + page_usable_latest_.pool = VK_NULL_HANDLE; + page_usable_latest_.descriptors_remaining.reset(); + } else { + --page_usable_latest_.descriptor_sets_remaining; + for (uint32_t i = 0; i < descriptor_type_count; ++i) { + const VkDescriptorPoolSize& descriptor_count_for_type = descriptor_counts[i]; + for (uint32_t j = 0; j < descriptor_pool_size_count_; ++j) { + VkDescriptorPoolSize& descriptors_remaining_for_type = + page_usable_latest_.descriptors_remaining[j]; + if (descriptor_count_for_type.type != descriptors_remaining_for_type.type) { + continue; + } + descriptors_remaining_for_type.descriptorCount -= + descriptor_count_for_type.descriptorCount; + } + } + } + if (descriptor_set != VK_NULL_HANDLE) { + return descriptor_set; + } + } + } + + // Count the maximum number of descriptors requested for any type to stop + // searching for pages once they can't satisfy this requirement. + uint32_t max_descriptors_per_type = descriptor_counts[0].descriptorCount; + for (uint32_t i = 1; i < descriptor_type_count; ++i) { + max_descriptors_per_type = + std::max(max_descriptors_per_type, descriptor_counts[i].descriptorCount); + } + + // If allocating from the latest pool wasn't possible, pick any that has + // enough free space. Prefer filling pages that have the most free space as + // they can more likely be used for more allocations later. + auto page_usable_it_next = pages_usable_.rbegin(); + while (page_usable_it_next != pages_usable_.rend()) { + auto page_usable_it = page_usable_it_next; + ++page_usable_it_next; + if (page_usable_it->first < max_descriptors_per_type) { + // All other pages_usable_ entries have smaller maximum number of free + // descriptor for any type (it's the map key). + break; + } + // Check if the page has enough free descriptors for all requested types, + // and whether allocating the requested number of descriptors in it will + // result in the page becoming full. + bool map_page_has_sufficient_space = true; + bool map_page_becomes_full = page_usable_it->second.descriptor_sets_remaining == 1; + for (uint32_t i = 0; i < descriptor_type_count; ++i) { + const VkDescriptorPoolSize& descriptor_count_for_type = descriptor_counts[i]; + for (uint32_t j = 0; j < descriptor_pool_size_count_; ++j) { + const VkDescriptorPoolSize& descriptors_remaining_for_type = + page_usable_it->second.descriptors_remaining[j]; + if (descriptor_count_for_type.type != descriptors_remaining_for_type.type) { + continue; + } + if (descriptor_count_for_type.descriptorCount >= + descriptors_remaining_for_type.descriptorCount) { + if (descriptor_count_for_type.descriptorCount > + descriptors_remaining_for_type.descriptorCount) { + map_page_has_sufficient_space = false; + break; + } + map_page_becomes_full = true; + } + } + if (!map_page_has_sufficient_space) { + break; + } + } + if (!map_page_has_sufficient_space) { + // Even though the coarse (maximum number of descriptors for any type) + // check has passed, for the exact types requested this page doesn't have + // sufficient space - try another one. + continue; + } + // Remove the page from the map unconditionally - in case of a successful + // allocation, it will have a different number of free descriptors for + // different types, thus potentially a new map key (but it will also become + // page_usable_latest_ instead even), or will become full, and in case of a + // failure to allocate internally even though there still should be enough + // space, it should never be allocated from again. + Page map_page = std::move(page_usable_it->second); + // Convert the reverse iterator to a forward iterator for erasing. + pages_usable_.erase(std::next(page_usable_it).base()); + descriptor_set_allocate_info.descriptorPool = map_page.pool; + if (dfn.vkAllocateDescriptorSets(device, &descriptor_set_allocate_info, &descriptor_set) != + VK_SUCCESS) { + descriptor_set = VK_NULL_HANDLE; + // Failed to allocate internally even though there should be enough space, + // don't try to allocate from this pool again at all. + map_page_becomes_full = true; + } + if (map_page_becomes_full) { + map_page.descriptors_remaining.reset(); + pages_full_.push_back(map_page.pool); + } else { + --map_page.descriptor_sets_remaining; + for (uint32_t i = 0; i < descriptor_type_count; ++i) { + const VkDescriptorPoolSize& descriptor_count_for_type = descriptor_counts[i]; + for (uint32_t j = 0; j < descriptor_pool_size_count_; ++j) { + VkDescriptorPoolSize& descriptors_remaining_for_type = map_page.descriptors_remaining[j]; + if (descriptor_count_for_type.type != descriptors_remaining_for_type.type) { + continue; + } + descriptors_remaining_for_type.descriptorCount -= + descriptor_count_for_type.descriptorCount; + } + } + // Move the latest page that allocation couldn't be done in to the usable + // pages to replace it with the new one. + if (page_usable_latest_.pool != VK_NULL_HANDLE) { + // Calculate the map key (the maximum number of remaining descriptors of + // any type). + uint32_t latest_page_max_descriptors_remaining = + page_usable_latest_.descriptors_remaining[0].descriptorCount; + for (uint32_t i = 1; i < descriptor_pool_size_count_; ++i) { + latest_page_max_descriptors_remaining = + std::max(latest_page_max_descriptors_remaining, + page_usable_latest_.descriptors_remaining[i].descriptorCount); + } + assert_not_zero(latest_page_max_descriptors_remaining); + pages_usable_.emplace(latest_page_max_descriptors_remaining, + std::move(page_usable_latest_)); + } + page_usable_latest_ = std::move(map_page); + } + if (descriptor_set != VK_NULL_HANDLE) { + return descriptor_set; + } + } + + // Try allocating from a new page. + // See if the new page has instantly become full. + bool new_page_becomes_full = descriptor_sets_per_page_ == 1; + for (uint32_t i = 0; !new_page_becomes_full && i < descriptor_type_count; ++i) { + const VkDescriptorPoolSize& descriptor_count_for_type = descriptor_counts[i]; + for (uint32_t j = 0; j < descriptor_pool_size_count_; ++j) { + const VkDescriptorPoolSize& descriptors_remaining_for_type = descriptor_pool_sizes_[j]; + if (descriptor_count_for_type.type != descriptors_remaining_for_type.type) { + continue; + } + assert_true(descriptor_count_for_type.descriptorCount <= + descriptors_remaining_for_type.descriptorCount); + if (descriptor_count_for_type.descriptorCount >= + descriptors_remaining_for_type.descriptorCount) { + new_page_becomes_full = true; + break; + } + } + } + // Allocate from a new page. However, if the new page becomes full + // immediately, create a dedicated pool instead for the exact number of + // descriptors not to leave any unused space in the pool. + VkDescriptorPoolCreateInfo new_descriptor_pool_create_info; + new_descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + new_descriptor_pool_create_info.pNext = nullptr; + new_descriptor_pool_create_info.flags = 0; + if (new_page_becomes_full) { + new_descriptor_pool_create_info.maxSets = 1; + new_descriptor_pool_create_info.poolSizeCount = descriptor_type_count; + new_descriptor_pool_create_info.pPoolSizes = descriptor_counts; + } else { + new_descriptor_pool_create_info.maxSets = descriptor_sets_per_page_; + new_descriptor_pool_create_info.poolSizeCount = descriptor_pool_size_count_; + new_descriptor_pool_create_info.pPoolSizes = descriptor_pool_sizes_.get(); + } + VkDescriptorPool new_descriptor_pool; + if (dfn.vkCreateDescriptorPool(device, &new_descriptor_pool_create_info, nullptr, + &new_descriptor_pool) != VK_SUCCESS) { + REXLOG_ERROR("LinkedTypeDescriptorSetAllocator: Failed to create a descriptor pool"); + return VK_NULL_HANDLE; + } + descriptor_set_allocate_info.descriptorPool = new_descriptor_pool; + if (dfn.vkAllocateDescriptorSets(device, &descriptor_set_allocate_info, &descriptor_set) != + VK_SUCCESS) { + REXLOG_ERROR("LinkedTypeDescriptorSetAllocator: Failed to allocate descriptors"); + dfn.vkDestroyDescriptorPool(device, new_descriptor_pool, nullptr); + return VK_NULL_HANDLE; + } + if (new_page_becomes_full) { + pages_full_.push_back(new_descriptor_pool); + } else { + // Move the latest page that allocation couldn't be done in to the usable + // pages to replace it with the new one. + if (page_usable_latest_.pool != VK_NULL_HANDLE) { + // Calculate the map key (the maximum number of remaining descriptors of + // any type). + uint32_t latest_page_max_descriptors_remaining = + page_usable_latest_.descriptors_remaining[0].descriptorCount; + for (uint32_t i = 1; i < descriptor_pool_size_count_; ++i) { + latest_page_max_descriptors_remaining = + std::max(latest_page_max_descriptors_remaining, + page_usable_latest_.descriptors_remaining[i].descriptorCount); + } + assert_not_zero(latest_page_max_descriptors_remaining); + pages_usable_.emplace(latest_page_max_descriptors_remaining, std::move(page_usable_latest_)); + } + page_usable_latest_.pool = new_descriptor_pool; + page_usable_latest_.descriptors_remaining = std::unique_ptr( + new VkDescriptorPoolSize[descriptor_pool_size_count_]); + for (uint32_t i = 0; i < descriptor_pool_size_count_; ++i) { + const VkDescriptorPoolSize& descriptor_pool_size_for_type = descriptor_pool_sizes_[i]; + page_usable_latest_.descriptors_remaining[i] = descriptor_pool_size_for_type; + for (uint32_t j = 0; j < descriptor_type_count; ++j) { + const VkDescriptorPoolSize& descriptor_count_for_type = descriptor_counts[j]; + if (descriptor_count_for_type.type != descriptor_pool_size_for_type.type) { + continue; + } + page_usable_latest_.descriptors_remaining[i].descriptorCount -= + descriptor_count_for_type.descriptorCount; + break; + } + } + page_usable_latest_.descriptor_sets_remaining = descriptor_sets_per_page_ - 1; + } + return descriptor_set; +} + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/src/ui/vulkan/single_layout_descriptor_set_pool.cpp b/src/ui/vulkan/single_layout_descriptor_set_pool.cpp new file mode 100644 index 0000000..ad54520 --- /dev/null +++ b/src/ui/vulkan/single_layout_descriptor_set_pool.cpp @@ -0,0 +1,115 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +namespace rex { +namespace ui { +namespace vulkan { + +SingleLayoutDescriptorSetPool::SingleLayoutDescriptorSetPool( + const VulkanDevice* const vulkan_device, const uint32_t pool_set_count, + const uint32_t set_layout_descriptor_counts_count, + const VkDescriptorPoolSize* const set_layout_descriptor_counts, + const VkDescriptorSetLayout set_layout) + : vulkan_device_(vulkan_device), pool_set_count_(pool_set_count), set_layout_(set_layout) { + assert_not_null(vulkan_device); + assert_not_zero(pool_set_count); + pool_descriptor_counts_.resize(set_layout_descriptor_counts_count); + for (uint32_t i = 0; i < set_layout_descriptor_counts_count; ++i) { + VkDescriptorPoolSize& pool_descriptor_type_count = pool_descriptor_counts_[i]; + const VkDescriptorPoolSize& set_layout_descriptor_type_count = set_layout_descriptor_counts[i]; + pool_descriptor_type_count.type = set_layout_descriptor_type_count.type; + pool_descriptor_type_count.descriptorCount = + set_layout_descriptor_type_count.descriptorCount * pool_set_count; + } +} + +SingleLayoutDescriptorSetPool::~SingleLayoutDescriptorSetPool() { + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + if (current_pool_ != VK_NULL_HANDLE) { + dfn.vkDestroyDescriptorPool(device, current_pool_, nullptr); + } + for (VkDescriptorPool pool : full_pools_) { + dfn.vkDestroyDescriptorPool(device, pool, nullptr); + } +} + +size_t SingleLayoutDescriptorSetPool::Allocate() { + if (!descriptor_sets_free_.empty()) { + size_t free_index = descriptor_sets_free_.back(); + descriptor_sets_free_.pop_back(); + return free_index; + } + + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + // Two iterations so if vkAllocateDescriptorSets fails even with a non-zero + // current_pool_sets_remaining_, another attempt will be made in a new pool. + for (uint32_t i = 0; i < 2; ++i) { + if (current_pool_ != VK_NULL_HANDLE && !current_pool_sets_remaining_) { + full_pools_.push_back(current_pool_); + current_pool_ = VK_NULL_HANDLE; + } + if (current_pool_ == VK_NULL_HANDLE) { + VkDescriptorPoolCreateInfo pool_create_info; + pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + pool_create_info.pNext = nullptr; + pool_create_info.flags = 0; + pool_create_info.maxSets = pool_set_count_; + pool_create_info.poolSizeCount = uint32_t(pool_descriptor_counts_.size()); + pool_create_info.pPoolSizes = pool_descriptor_counts_.data(); + if (dfn.vkCreateDescriptorPool(device, &pool_create_info, nullptr, ¤t_pool_) != + VK_SUCCESS) { + REXLOG_ERROR( + "SingleLayoutDescriptorSetPool: Failed to create a descriptor " + "pool"); + return SIZE_MAX; + } + current_pool_sets_remaining_ = pool_set_count_; + } + + VkDescriptorSetAllocateInfo descriptor_set_allocate_info; + descriptor_set_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + descriptor_set_allocate_info.pNext = nullptr; + descriptor_set_allocate_info.descriptorPool = current_pool_; + descriptor_set_allocate_info.descriptorSetCount = 1; + descriptor_set_allocate_info.pSetLayouts = &set_layout_; + VkDescriptorSet descriptor_set; + if (dfn.vkAllocateDescriptorSets(device, &descriptor_set_allocate_info, &descriptor_set) != + VK_SUCCESS) { + REXLOG_ERROR("SingleLayoutDescriptorSetPool: Failed to allocate a descriptor set"); + if (current_pool_sets_remaining_ >= pool_set_count_) { + // Failed to allocate in a new pool - something completely wrong, don't + // store empty pools as full. + dfn.vkDestroyDescriptorPool(device, current_pool_, nullptr); + current_pool_ = VK_NULL_HANDLE; + return SIZE_MAX; + } + full_pools_.push_back(current_pool_); + current_pool_ = VK_NULL_HANDLE; + } + --current_pool_sets_remaining_; + descriptor_sets_.push_back(descriptor_set); + return descriptor_sets_.size() - 1; + } + + // Both attempts have failed. + return SIZE_MAX; +} + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/src/ui/vulkan/spirv_tools_context.cpp b/src/ui/vulkan/spirv_tools_context.cpp new file mode 100644 index 0000000..f849450 --- /dev/null +++ b/src/ui/vulkan/spirv_tools_context.cpp @@ -0,0 +1,93 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +#include +#include + +namespace rex { +namespace ui { +namespace vulkan { + +bool SpirvToolsContext::Initialize(unsigned int spirv_version) { + const char* vulkan_sdk_env = std::getenv("VULKAN_SDK"); + if (!vulkan_sdk_env) { + REXLOG_ERROR("SPIRV-Tools: Failed to get the VULKAN_SDK environment variable"); + Shutdown(); + return false; + } + std::filesystem::path vulkan_sdk_path(vulkan_sdk_env); + auto library_path = vulkan_sdk_path / platform::lib_names::kSpirvToolsSdkPath; + if (!library_.Load(library_path)) { + REXLOG_ERROR("SPIRV-Tools: Failed to load {}", library_path.string()); + Shutdown(); + return false; + } + if (!LoadLibraryFunction(fn_spvContextCreate_, "spvContextCreate") || + !LoadLibraryFunction(fn_spvContextDestroy_, "spvContextDestroy") || + !LoadLibraryFunction(fn_spvValidateBinary_, "spvValidateBinary") || + !LoadLibraryFunction(fn_spvDiagnosticDestroy_, "spvDiagnosticDestroy")) { + REXLOG_ERROR("SPIRV-Tools: Failed to get library function pointers"); + Shutdown(); + return false; + } + spv_target_env target_env; + if (spirv_version >= 0x10500) { + target_env = SPV_ENV_VULKAN_1_2; + } else if (spirv_version >= 0x10400) { + target_env = SPV_ENV_VULKAN_1_1_SPIRV_1_4; + } else if (spirv_version >= 0x10300) { + target_env = SPV_ENV_VULKAN_1_1; + } else { + target_env = SPV_ENV_VULKAN_1_0; + } + context_ = fn_spvContextCreate_(target_env); + if (!context_) { + REXLOG_ERROR("SPIRV-Tools: Failed to create a Vulkan 1.0 context"); + Shutdown(); + return false; + } + return true; +} + +void SpirvToolsContext::Shutdown() { + if (context_) { + fn_spvContextDestroy_(context_); + context_ = nullptr; + } + library_.Close(); +} + +spv_result_t SpirvToolsContext::Validate(const uint32_t* words, size_t num_words, + std::string* error) const { + if (error) { + error->clear(); + } + if (!context_) { + return SPV_UNSUPPORTED; + } + spv_diagnostic diagnostic = nullptr; + spv_result_t result = fn_spvValidateBinary_(context_, words, num_words, &diagnostic); + if (diagnostic) { + if (error && diagnostic && diagnostic->error) { + *error = diagnostic->error; + } + fn_spvDiagnosticDestroy_(diagnostic); + } + return result; +} + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/src/ui/vulkan/ui_samplers.cpp b/src/ui/vulkan/ui_samplers.cpp new file mode 100644 index 0000000..f36051e --- /dev/null +++ b/src/ui/vulkan/ui_samplers.cpp @@ -0,0 +1,83 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include + +namespace rex { +namespace ui { +namespace vulkan { + +std::unique_ptr UISamplers::Create(const VulkanDevice* const vulkan_device) { + assert_not_null(vulkan_device); + + std::unique_ptr ui_samplers(new UISamplers(vulkan_device)); + + const VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + VkSamplerCreateInfo sampler_create_info = {VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO}; + + for (int sampler_index = 0; sampler_index < kSamplerCount; ++sampler_index) { + if (sampler_index == kSamplerIndexLinearRepeat || + sampler_index == kSamplerIndexLinearClampToEdge) { + sampler_create_info.magFilter = VK_FILTER_LINEAR; + sampler_create_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + } else { + sampler_create_info.magFilter = VK_FILTER_NEAREST; + sampler_create_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + } + sampler_create_info.minFilter = sampler_create_info.magFilter; + + if (sampler_index == kSamplerIndexNearestClampToEdge || + sampler_index == kSamplerIndexLinearClampToEdge) { + sampler_create_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + } else { + sampler_create_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; + } + sampler_create_info.addressModeV = sampler_create_info.addressModeU; + sampler_create_info.addressModeW = sampler_create_info.addressModeU; + + const VkResult sampler_create_result = dfn.vkCreateSampler( + device, &sampler_create_info, nullptr, &ui_samplers->samplers_[sampler_index]); + if (sampler_create_result != VK_SUCCESS) { + REXLOG_ERROR( + "Failed to create the Vulkan UI sampler with filter {}, addressing " + "mode {}: {}", + vk::to_string(vk::Filter(sampler_create_info.magFilter)), + vk::to_string(vk::SamplerAddressMode(sampler_create_info.addressModeU)), + vk::to_string(vk::Result(sampler_create_result))); + return nullptr; + } + } + + return ui_samplers; +} + +UISamplers::~UISamplers() { + for (const VkSampler sampler : samplers_) { + if (sampler == VK_NULL_HANDLE) { + continue; + } + vulkan_device_->functions().vkDestroySampler(vulkan_device_->device(), sampler, nullptr); + } +} + +UISamplers::UISamplers(const VulkanDevice* vulkan_device) : vulkan_device_(vulkan_device) { + assert_not_null(vulkan_device); + + samplers_.fill(VK_NULL_HANDLE); +} + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/src/ui/vulkan/vulkan_device.cpp b/src/ui/vulkan/vulkan_device.cpp new file mode 100644 index 0000000..c6f48fd --- /dev/null +++ b/src/ui/vulkan/vulkan_device.cpp @@ -0,0 +1,865 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(vulkan_require_fragment_stores_and_atomics, true, "UI/Vulkan", + "Deprecated and ignored for parity; fragmentStoresAndAtomics is always " + "required for Vulkan GPU emulation") + .lifecycle(rex::cvar::Lifecycle::kInitOnly); +REXCVAR_DEFINE_BOOL(vulkan_require_vertex_pipeline_stores_and_atomics, true, "UI/Vulkan", + "Deprecated and ignored for parity; vertexPipelineStoresAndAtomics is always " + "required for Vulkan GPU emulation") + .lifecycle(rex::cvar::Lifecycle::kInitOnly); +REXCVAR_DEFINE_BOOL(vulkan_require_geometry_shader, true, "UI/Vulkan", + "Require geometryShader support for Vulkan GPU emulation (disable to allow " + "fallback primitive emulation paths)") + .lifecycle(rex::cvar::Lifecycle::kInitOnly); +REXCVAR_DEFINE_BOOL(vulkan_require_fill_mode_non_solid, true, "UI/Vulkan", + "Require fillModeNonSolid support for Vulkan GPU emulation (disable to " + "allow fallback to solid fill for line/point polygon modes)") + .lifecycle(rex::cvar::Lifecycle::kInitOnly); + +namespace rex { +namespace ui { +namespace vulkan { + +template +struct VulkanFeatures { + Structure supported = {StructureType}; + Structure enabled = {StructureType}; + + void Link(VkPhysicalDeviceFeatures2& supported_features_2, + VkDeviceCreateInfo& device_create_info) { + supported.pNext = supported_features_2.pNext; + supported_features_2.pNext = &supported; + enabled.pNext = const_cast(device_create_info.pNext); + device_create_info.pNext = &enabled; + } +}; + +std::unique_ptr VulkanDevice::CreateIfSupported( + const VulkanInstance* const vulkan_instance, const VkPhysicalDevice physical_device, + const bool with_gpu_emulation, const bool with_swapchain) { + assert_not_null(vulkan_instance); + assert_not_null(physical_device); + + const VulkanInstance::Functions& ifn = vulkan_instance->functions(); + + // Get supported Vulkan 1.0 properties and features. + + VkPhysicalDeviceProperties properties = {}; + ifn.vkGetPhysicalDeviceProperties(physical_device, &properties); + + const uint32_t unclamped_api_version = properties.apiVersion; + if (vulkan_instance->api_version() < VK_MAKE_API_VERSION(0, 1, 1, 0)) { + // From the VkApplicationInfo specification: + // + // "The Khronos validation layers will treat apiVersion as the highest API + // version the application targets, and will validate API usage against the + // minimum of that version and the implementation version (instance or + // device, depending on context). If an application tries to use + // functionality from a greater version than this, a validation error will + // be triggered." + // + // "Vulkan 1.0 implementations were required to return + // VK_ERROR_INCOMPATIBLE_DRIVER if apiVersion was larger than 1.0." + properties.apiVersion = + VK_MAKE_API_VERSION(0, 1, 0, VK_API_VERSION_PATCH(properties.apiVersion)); + } + + VkPhysicalDeviceFeatures supported_features = {}; + ifn.vkGetPhysicalDeviceFeatures(physical_device, &supported_features); + + if (with_gpu_emulation) { + if (!supported_features.independentBlend) { + // Not trivial to work around: + // - Affects not only the blend equation, but also the color write mask. + // - Can't reuse the blend state of the first attachment for all because + // some attachments may have a format that doesn't support blending. + // - Not possible to split the draw into per-attachment draws because of + // depth / stencil. + // Not supported only on the proprietary driver for the Qualcomm + // Adreno 4xx, where the driver is largely experimental and doesn't expose + // a lot of the functionality available in the hardware. + REXLOG_WARN( + "Vulkan device '{}' doesn't support the independentBlend feature " + "required for GPU emulation", + properties.deviceName); + return nullptr; + } + if (!supported_features.fragmentStoresAndAtomics) { + REXLOG_WARN( + "Vulkan device '{}' doesn't support fragmentStoresAndAtomics, which " + "is required for Vulkan GPU emulation parity", + properties.deviceName); + return nullptr; + } + if (!supported_features.vertexPipelineStoresAndAtomics) { + REXLOG_WARN( + "Vulkan device '{}' doesn't support vertexPipelineStoresAndAtomics, which " + "is required for Vulkan GPU emulation parity", + properties.deviceName); + return nullptr; + } + if (REXCVAR_GET(vulkan_require_geometry_shader) && !supported_features.geometryShader) { + REXLOG_WARN( + "Vulkan device '{}' doesn't support geometryShader, but " + "vulkan_require_geometry_shader=true", + properties.deviceName); + return nullptr; + } + if (REXCVAR_GET(vulkan_require_fill_mode_non_solid) && !supported_features.fillModeNonSolid) { + REXLOG_WARN( + "Vulkan device '{}' doesn't support fillModeNonSolid, but " + "vulkan_require_fill_mode_non_solid=true", + properties.deviceName); + return nullptr; + } + } + + // Enable needed extensions. + + std::unique_ptr device(new VulkanDevice(vulkan_instance, physical_device)); + + const bool get_physical_device_properties2_supported = + vulkan_instance->extensions().ext_1_1_KHR_get_physical_device_properties2; + + // Name pointers from `requested_extensions` will be used in the enabled + // extensions vector. + std::unordered_map requested_extensions; + + const auto request_promoted_extension = [&](const char* const name, uint32_t const major, + uint32_t const minor, bool* const supported_ptr) { + assert_not_null(supported_ptr); + if (properties.apiVersion >= VK_MAKE_API_VERSION(0, major, minor, 0)) { + *supported_ptr = true; + } else { + requested_extensions.emplace(name, supported_ptr); + } + }; + +#define XE_UI_VULKAN_STRUCT_EXTENSION(name) \ + requested_extensions.emplace("VK_" #name, &device->extensions_.ext_##name); +#define XE_UI_VULKAN_LOCAL_EXTENSION(name) requested_extensions.emplace("VK_" #name, &ext_##name); +#define XE_UI_VULKAN_STRUCT_PROMOTED_EXTENSION(name, major, minor) \ + request_promoted_extension("VK_" #name, major, minor, \ + &device->extensions_.ext_##major##_##minor##_##name); +#define XE_UI_VULKAN_LOCAL_PROMOTED_EXTENSION(name, major, minor) \ + request_promoted_extension("VK_" #name, major, minor, &ext_##major##_##minor##_##name); + + bool ext_KHR_portability_subset = false; + bool ext_1_2_KHR_driver_properties = false; + if (get_physical_device_properties2_supported) { + // #164. Must be enabled according to the specification if the physical + // device is a portability subset one. + XE_UI_VULKAN_LOCAL_EXTENSION(KHR_portability_subset) + // #197 + XE_UI_VULKAN_LOCAL_PROMOTED_EXTENSION(KHR_driver_properties, 1, 2) + } + + // Used by the Vulkan Memory Allocator and potentially by Xenia. + // #128. + XE_UI_VULKAN_STRUCT_PROMOTED_EXTENSION(KHR_dedicated_allocation, 1, 1) + // #147. Also must be enabled for VK_KHR_dedicated_allocation and + // VK_KHR_sampler_ycbcr_conversion. + XE_UI_VULKAN_STRUCT_PROMOTED_EXTENSION(KHR_get_memory_requirements2, 1, 1) + // #158. Also must be enabled for VK_KHR_sampler_ycbcr_conversion. + XE_UI_VULKAN_STRUCT_PROMOTED_EXTENSION(KHR_bind_memory2, 1, 1) + if (get_physical_device_properties2_supported) { + // #238. + XE_UI_VULKAN_STRUCT_EXTENSION(EXT_memory_budget) + } + if (properties.apiVersion >= VK_MAKE_API_VERSION(0, 1, 1, 0)) { + // #414. + XE_UI_VULKAN_STRUCT_PROMOTED_EXTENSION(KHR_maintenance4, 1, 3) + // #55. + XE_UI_VULKAN_STRUCT_PROMOTED_EXTENSION(KHR_dynamic_rendering, 1, 3) + } + + if (with_swapchain) { + // #2. + XE_UI_VULKAN_STRUCT_EXTENSION(KHR_swapchain) + } + + bool ext_1_2_KHR_sampler_mirror_clamp_to_edge = false; + bool ext_1_1_KHR_maintenance1 = false; + bool ext_1_2_KHR_shader_float_controls = false; + bool ext_EXT_fragment_shader_interlock = false; + bool ext_1_3_EXT_shader_demote_to_helper_invocation = false; + bool ext_1_3_KHR_dynamic_rendering = false; + bool ext_EXT_non_seamless_cube_map = false; + if (with_gpu_emulation) { + // #15. + XE_UI_VULKAN_LOCAL_PROMOTED_EXTENSION(KHR_sampler_mirror_clamp_to_edge, 1, 2) + // #70. Must be enabled for VK_KHR_sampler_ycbcr_conversion. + XE_UI_VULKAN_LOCAL_PROMOTED_EXTENSION(KHR_maintenance1, 1, 1) + // #141. + XE_UI_VULKAN_STRUCT_EXTENSION(EXT_shader_stencil_export) + // #148. + XE_UI_VULKAN_STRUCT_PROMOTED_EXTENSION(KHR_image_format_list, 1, 2) + if (get_physical_device_properties2_supported) { + // #157. + XE_UI_VULKAN_STRUCT_PROMOTED_EXTENSION(KHR_sampler_ycbcr_conversion, 1, 1) + // #198. Also must be enabled for VK_KHR_spirv_1_4. + XE_UI_VULKAN_LOCAL_PROMOTED_EXTENSION(KHR_shader_float_controls, 1, 2) + // #252. + XE_UI_VULKAN_LOCAL_EXTENSION(EXT_fragment_shader_interlock) + // #55. + XE_UI_VULKAN_LOCAL_PROMOTED_EXTENSION(KHR_dynamic_rendering, 1, 3) + // #277. + XE_UI_VULKAN_LOCAL_PROMOTED_EXTENSION(EXT_shader_demote_to_helper_invocation, 1, 3) + // #423. + XE_UI_VULKAN_LOCAL_EXTENSION(EXT_non_seamless_cube_map) + // Required for non-black YCbCr border color parity with D3D12. + XE_UI_VULKAN_STRUCT_EXTENSION(EXT_custom_border_color) + // Required for true null descriptors in bindless texture bindings. + XE_UI_VULKAN_STRUCT_EXTENSION(EXT_robustness2) + } + if (properties.apiVersion >= VK_MAKE_API_VERSION(0, 1, 1, 0)) { + // #237. + XE_UI_VULKAN_STRUCT_PROMOTED_EXTENSION(KHR_spirv_1_4, 1, 2) + } + } + +#undef XE_UI_VULKAN_STRUCT_EXTENSION +#undef XE_UI_VULKAN_LOCAL_EXTENSION +#undef XE_UI_VULKAN_STRUCT_PROMOTED_EXTENSION +#undef XE_UI_VULKAN_LOCAL_PROMOTED_EXTENSION + + std::vector enabled_extensions; + { + uint32_t supported_extension_count = 0; + const VkResult get_supported_extension_count_result = ifn.vkEnumerateDeviceExtensionProperties( + physical_device, nullptr, &supported_extension_count, nullptr); + if (get_supported_extension_count_result != VK_SUCCESS && + get_supported_extension_count_result != VK_INCOMPLETE) { + REXLOG_WARN("Failed to get the Vulkan device '{}' extension count", properties.deviceName); + return nullptr; + } + if (supported_extension_count) { + std::vector supported_extensions(supported_extension_count); + if (ifn.vkEnumerateDeviceExtensionProperties(physical_device, nullptr, + &supported_extension_count, + supported_extensions.data()) != VK_SUCCESS) { + REXLOG_WARN("Failed to get the Vulkan device '{}' extensions", properties.deviceName); + return nullptr; + } + assert_true(supported_extension_count == supported_extensions.size()); + for (const VkExtensionProperties& supported_extension : supported_extensions) { + const auto requested_extension_it = + requested_extensions.find(supported_extension.extensionName); + if (requested_extension_it == requested_extensions.cend()) { + continue; + } + assert_not_null(requested_extension_it->second); + if (!*requested_extension_it->second) { + enabled_extensions.emplace_back(requested_extension_it->first.c_str()); + *requested_extension_it->second = true; + } + } + } + } + + if (with_swapchain && !device->extensions_.ext_KHR_swapchain) { + REXLOG_WARN("Vulkan device '{}' doesn't support swapchains", properties.deviceName); + return nullptr; + } + + VkDeviceCreateInfo device_create_info = {VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO}; + + device_create_info.enabledExtensionCount = uint32_t(enabled_extensions.size()); + device_create_info.ppEnabledExtensionNames = enabled_extensions.data(); + + // Get supported Vulkan 1.1+ and extension properties and features. + // + // The property and feature structures are initialized to zero or to the + // minimum / maximum requirements for the simplicity of handling unavailable + // VK_KHR_get_physical_device_properties2. + + VkPhysicalDeviceProperties2 properties_2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2}; + + VkPhysicalDeviceFeatures2 supported_features_2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2}; + + VulkanFeatures + features_1_2; + VulkanFeatures + features_1_3; + VulkanFeatures + features_KHR_portability_subset; + VkPhysicalDeviceDriverPropertiesKHR properties_1_2_KHR_driver_properties = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES}; + VkPhysicalDeviceFloatControlsProperties properties_1_2_KHR_shader_float_controls = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES}; + VulkanFeatures + features_EXT_fragment_shader_interlock; + VulkanFeatures + features_1_3_KHR_dynamic_rendering; + VulkanFeatures + features_1_3_EXT_shader_demote_to_helper_invocation; + VulkanFeatures + features_EXT_non_seamless_cube_map; + VulkanFeatures + features_EXT_custom_border_color; + VkPhysicalDeviceCustomBorderColorPropertiesEXT properties_EXT_custom_border_color = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT}; + VulkanFeatures + features_EXT_robustness2; + + if (get_physical_device_properties2_supported) { + if (properties.apiVersion >= VK_MAKE_API_VERSION(0, 1, 2, 0)) { + features_1_2.Link(supported_features_2, device_create_info); + } + if (properties.apiVersion >= VK_MAKE_API_VERSION(0, 1, 3, 0)) { + features_1_3.Link(supported_features_2, device_create_info); + } else { + if (ext_1_3_KHR_dynamic_rendering) { + features_1_3_KHR_dynamic_rendering.Link(supported_features_2, device_create_info); + } + if (ext_1_3_EXT_shader_demote_to_helper_invocation) { + features_1_3_EXT_shader_demote_to_helper_invocation.Link(supported_features_2, + device_create_info); + } + } + if (ext_KHR_portability_subset) { + features_KHR_portability_subset.Link(supported_features_2, device_create_info); + } + if (ext_1_2_KHR_driver_properties) { + properties_1_2_KHR_driver_properties.pNext = properties_2.pNext; + properties_2.pNext = &properties_1_2_KHR_driver_properties; + } + if (ext_1_2_KHR_shader_float_controls) { + properties_1_2_KHR_shader_float_controls.pNext = properties_2.pNext; + properties_2.pNext = &properties_1_2_KHR_shader_float_controls; + } + if (ext_EXT_fragment_shader_interlock) { + features_EXT_fragment_shader_interlock.Link(supported_features_2, device_create_info); + } + if (ext_EXT_non_seamless_cube_map) { + features_EXT_non_seamless_cube_map.Link(supported_features_2, device_create_info); + } + if (device->extensions_.ext_EXT_custom_border_color) { + features_EXT_custom_border_color.Link(supported_features_2, device_create_info); + properties_EXT_custom_border_color.pNext = properties_2.pNext; + properties_2.pNext = &properties_EXT_custom_border_color; + } + if (device->extensions_.ext_EXT_robustness2) { + features_EXT_robustness2.Link(supported_features_2, device_create_info); + } + ifn.vkGetPhysicalDeviceProperties2(physical_device, &properties_2); + ifn.vkGetPhysicalDeviceFeatures2(physical_device, &supported_features_2); + } + + uint32_t queue_family_count = 0; + ifn.vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, nullptr); + std::vector queue_families(queue_family_count); + ifn.vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, + queue_families.data()); + + device->queue_families_.resize(queue_family_count); + + uint32_t first_queue_family_graphics_compute_sparse_binding = UINT32_MAX; + uint32_t first_queue_family_graphics_compute = UINT32_MAX; + uint32_t first_queue_family_sparse_binding = UINT32_MAX; + bool has_presentation_queue_family = false; + + for (uint32_t queue_family_index = 0; queue_family_index < queue_family_count; + ++queue_family_index) { + QueueFamily& queue_family = device->queue_families_[queue_family_index]; + const VkQueueFamilyProperties& queue_family_properties = queue_families[queue_family_index]; + + const VkQueueFlags queue_unsupported_flags = ~queue_family_properties.queueFlags; + + if (!(queue_unsupported_flags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT))) { + first_queue_family_graphics_compute = + std::min(queue_family_index, first_queue_family_graphics_compute); + } + + if (with_gpu_emulation && supported_features.sparseBinding && + !(queue_unsupported_flags & VK_QUEUE_SPARSE_BINDING_BIT)) { + first_queue_family_sparse_binding = + std::min(queue_family_index, first_queue_family_sparse_binding); + if (!(queue_unsupported_flags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT))) { + first_queue_family_graphics_compute_sparse_binding = + std::min(queue_family_index, first_queue_family_graphics_compute_sparse_binding); + } + } + + if (with_swapchain) { +#if REX_PLATFORM_WIN32 + queue_family.may_support_presentation = + vulkan_instance->extensions().ext_KHR_win32_surface && + ifn.vkGetPhysicalDeviceWin32PresentationSupportKHR(physical_device, queue_family_index); +#else + queue_family.may_support_presentation = true; +#endif + if (queue_family.may_support_presentation) { + queue_family.queues.resize(std::max(size_t(1), queue_family.queues.size())); + has_presentation_queue_family = true; + } + } + } + + if (first_queue_family_graphics_compute == UINT32_MAX) { + // Not valid according to the Vulkan specification, but for safety. + REXLOG_WARN( + "Vulkan device '{}' doesn't provide a graphics and compute queue " + "family", + properties.deviceName); + return nullptr; + } + + if (with_swapchain && !has_presentation_queue_family) { + REXLOG_WARN( + "Vulkan device '{}' doesn't provide a queue family that supports " + "presentation", + properties.deviceName); + return nullptr; + } + + // Get the queues to create. + + if (first_queue_family_sparse_binding == UINT32_MAX) { + // Not valid not to provide a sparse binding queue if the sparseBinding + // feature is supported according to the Vulkan specification, but for + // safety and simplicity. + supported_features.sparseBinding = VK_FALSE; + } + if (!supported_features.sparseBinding) { + supported_features.sparseResidencyBuffer = VK_FALSE; + supported_features.sparseResidencyImage2D = VK_FALSE; + supported_features.sparseResidencyImage3D = VK_FALSE; + supported_features.sparseResidency2Samples = VK_FALSE; + supported_features.sparseResidency4Samples = VK_FALSE; + supported_features.sparseResidency8Samples = VK_FALSE; + supported_features.sparseResidency16Samples = VK_FALSE; + supported_features.sparseResidencyAliased = VK_FALSE; + } + + // Prefer using one queue for everything whenever possible for simplicity. + // TODO(Triang3l): Research if separate queues for purposes like composition, + // swapchain image presentation, and sparse binding, may be beneficial. + + if (first_queue_family_graphics_compute_sparse_binding != UINT32_MAX) { + device->queue_family_graphics_compute_ = first_queue_family_graphics_compute_sparse_binding; + device->queue_family_sparse_binding_ = first_queue_family_graphics_compute_sparse_binding; + } else { + device->queue_family_graphics_compute_ = first_queue_family_graphics_compute; + device->queue_family_sparse_binding_ = first_queue_family_sparse_binding; + } + + device->queue_families_[device->queue_family_graphics_compute_].queues.resize(std::max( + size_t(1), device->queue_families_[device->queue_family_graphics_compute_].queues.size())); + if (device->queue_family_sparse_binding_ != UINT32_MAX) { + device->queue_families_[device->queue_family_sparse_binding_].queues.resize(std::max( + size_t(1), device->queue_families_[device->queue_family_sparse_binding_].queues.size())); + } + + size_t max_enabled_queues_per_family = 0; + for (const QueueFamily& queue_family : device->queue_families_) { + max_enabled_queues_per_family = + std::max(queue_family.queues.size(), max_enabled_queues_per_family); + } + const std::vector queue_priorities(max_enabled_queues_per_family, 1.0f); + std::vector queue_create_infos; + for (size_t queue_family_index = 0; queue_family_index < device->queue_families_.size(); + ++queue_family_index) { + const QueueFamily& queue_family = device->queue_families_[queue_family_index]; + if (queue_family.queues.empty()) { + continue; + } + VkDeviceQueueCreateInfo& queue_create_info = queue_create_infos.emplace_back(); + queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_create_info.pNext = nullptr; + queue_create_info.flags = 0; + queue_create_info.queueFamilyIndex = uint32_t(queue_family_index); + queue_create_info.queueCount = uint32_t(queue_family.queues.size()); + queue_create_info.pQueuePriorities = queue_priorities.data(); + } + device_create_info.queueCreateInfoCount = uint32_t(queue_create_infos.size()); + device_create_info.pQueueCreateInfos = queue_create_infos.data(); + + // Enable needed features and copy the properties. + // + // Enabling only actually used features because drivers may take more optimal + // paths when certain features are disabled. Also, in VK_EXT_shader_object, + // the state that the application must set for the draw depends on which + // features are enabled. + + device->properties_.apiVersion = properties.apiVersion; + device->properties_.driverVersion = properties.driverVersion; + device->properties_.vendorID = properties.vendorID; + device->properties_.deviceID = properties.deviceID; + std::strcpy(device->properties_.deviceName, properties.deviceName); + + REXLOG_INFO( + "Vulkan device '{}': API {}.{}.{}, vendor 0x{:04X}, device 0x{:04X}, " + "driver version 0x{:X}", + properties.deviceName, VK_VERSION_MAJOR(properties.apiVersion), + VK_VERSION_MINOR(properties.apiVersion), VK_VERSION_PATCH(properties.apiVersion), + properties.vendorID, properties.deviceID, properties.driverVersion); + if (unclamped_api_version != properties.apiVersion) { + REXLOG_INFO( + "Device supports Vulkan API {}.{}.{}, but the used version is limited " + "by the instance", + VK_VERSION_MAJOR(unclamped_api_version), VK_VERSION_MINOR(unclamped_api_version), + VK_VERSION_PATCH(unclamped_api_version)); + } + + REXLOG_INFO("Enabled Vulkan device extensions:"); + for (uint32_t enabled_extension_index = 0; + enabled_extension_index < device_create_info.enabledExtensionCount; + ++enabled_extension_index) { + REXLOG_INFO("* {}", device_create_info.ppEnabledExtensionNames[enabled_extension_index]); + } + + REXLOG_INFO("Vulkan device properties and enabled features:"); + + VkPhysicalDeviceFeatures enabled_features = {}; + device_create_info.pEnabledFeatures = &enabled_features; + +#define XE_UI_VULKAN_LIMIT(name) \ + device->properties_.name = properties.limits.name; \ + REXLOG_INFO("* " #name ": {}", properties.limits.name); +#define XE_UI_VULKAN_ENUM_LIMIT(name, type) \ + device->properties_.name = properties.limits.name; \ + REXLOG_INFO("* " #name ": {}", vk::to_string(vk::type(properties.limits.name))); +#define XE_UI_VULKAN_FEATURE(name) \ + enabled_features.name = supported_features.name; \ + device->properties_.name = supported_features.name; \ + if (supported_features.name) { \ + REXLOG_INFO("* " #name); \ + } +#define XE_UI_VULKAN_PROPERTY_2(structure, name) \ + device->properties_.name = structure.name; \ + REXLOG_INFO("* " #name ": {}", structure.name); +#define XE_UI_VULKAN_ENUM_PROPERTY_2(structure, name, type) \ + device->properties_.name = structure.name; \ + REXLOG_INFO("* " #name ": {}", vk::to_string(vk::type(structure.name))); +#define XE_UI_VULKAN_FEATURE_2(structure, name) \ + structure.enabled.name = structure.supported.name; \ + device->properties_.name = structure.supported.name; \ + if (structure.supported.name) { \ + REXLOG_INFO("* " #name); \ + } +#define XE_UI_VULKAN_FEATURE_IMPLIED(name) \ + device->properties_.name = true; \ + REXLOG_INFO("* " #name); + + if (ext_1_2_KHR_driver_properties) { + XE_UI_VULKAN_ENUM_PROPERTY_2(properties_1_2_KHR_driver_properties, driverID, DriverId); + REXLOG_INFO("* driverName: {}", properties_1_2_KHR_driver_properties.driverName); + if (properties_1_2_KHR_driver_properties.driverInfo[0]) { + REXLOG_INFO("* driverInfo: {}", properties_1_2_KHR_driver_properties.driverInfo); + } + REXLOG_INFO("* conformanceVersion: {}.{}.{}.{}", + properties_1_2_KHR_driver_properties.conformanceVersion.major, + properties_1_2_KHR_driver_properties.conformanceVersion.minor, + properties_1_2_KHR_driver_properties.conformanceVersion.subminor, + properties_1_2_KHR_driver_properties.conformanceVersion.patch); + } + + XE_UI_VULKAN_LIMIT(maxImageDimension2D) + XE_UI_VULKAN_LIMIT(maxImageDimension3D) + XE_UI_VULKAN_LIMIT(maxImageDimensionCube) + XE_UI_VULKAN_LIMIT(maxImageArrayLayers) + XE_UI_VULKAN_LIMIT(maxStorageBufferRange) + XE_UI_VULKAN_LIMIT(maxSamplerAllocationCount) + XE_UI_VULKAN_LIMIT(maxPerStageDescriptorSamplers) + XE_UI_VULKAN_LIMIT(maxPerStageDescriptorStorageBuffers) + XE_UI_VULKAN_LIMIT(maxPerStageDescriptorSampledImages) + XE_UI_VULKAN_LIMIT(maxPerStageResources) + XE_UI_VULKAN_LIMIT(maxVertexOutputComponents) + XE_UI_VULKAN_LIMIT(maxTessellationEvaluationOutputComponents) + XE_UI_VULKAN_LIMIT(maxGeometryInputComponents) + XE_UI_VULKAN_LIMIT(maxGeometryOutputComponents) + XE_UI_VULKAN_LIMIT(maxFragmentInputComponents) + XE_UI_VULKAN_LIMIT(maxFragmentCombinedOutputResources) + XE_UI_VULKAN_LIMIT(maxSamplerAnisotropy) + XE_UI_VULKAN_LIMIT(maxViewportDimensions[0]) + XE_UI_VULKAN_LIMIT(maxViewportDimensions[1]) + XE_UI_VULKAN_LIMIT(minUniformBufferOffsetAlignment) + XE_UI_VULKAN_LIMIT(minStorageBufferOffsetAlignment) + XE_UI_VULKAN_LIMIT(maxFramebufferWidth) + XE_UI_VULKAN_LIMIT(maxFramebufferHeight) + XE_UI_VULKAN_ENUM_LIMIT(framebufferColorSampleCounts, SampleCountFlags) + XE_UI_VULKAN_ENUM_LIMIT(framebufferDepthSampleCounts, SampleCountFlags) + XE_UI_VULKAN_ENUM_LIMIT(framebufferStencilSampleCounts, SampleCountFlags) + XE_UI_VULKAN_ENUM_LIMIT(framebufferNoAttachmentsSampleCounts, SampleCountFlags) + XE_UI_VULKAN_ENUM_LIMIT(sampledImageColorSampleCounts, SampleCountFlags) + XE_UI_VULKAN_ENUM_LIMIT(sampledImageIntegerSampleCounts, SampleCountFlags) + XE_UI_VULKAN_ENUM_LIMIT(sampledImageDepthSampleCounts, SampleCountFlags) + XE_UI_VULKAN_ENUM_LIMIT(sampledImageStencilSampleCounts, SampleCountFlags) + XE_UI_VULKAN_LIMIT(standardSampleLocations) + XE_UI_VULKAN_LIMIT(optimalBufferCopyOffsetAlignment) + XE_UI_VULKAN_LIMIT(optimalBufferCopyRowPitchAlignment) + XE_UI_VULKAN_LIMIT(nonCoherentAtomSize) + + if (with_gpu_emulation) { + XE_UI_VULKAN_FEATURE(robustBufferAccess) + XE_UI_VULKAN_FEATURE(fullDrawIndexUint32) + XE_UI_VULKAN_FEATURE(independentBlend) + XE_UI_VULKAN_FEATURE(geometryShader) + XE_UI_VULKAN_FEATURE(tessellationShader) + XE_UI_VULKAN_FEATURE(sampleRateShading) + XE_UI_VULKAN_FEATURE(depthClamp) + XE_UI_VULKAN_FEATURE(fillModeNonSolid) + XE_UI_VULKAN_FEATURE(samplerAnisotropy) + XE_UI_VULKAN_FEATURE(occlusionQueryPrecise) + XE_UI_VULKAN_FEATURE(vertexPipelineStoresAndAtomics) + XE_UI_VULKAN_FEATURE(fragmentStoresAndAtomics) + XE_UI_VULKAN_FEATURE(shaderClipDistance) + XE_UI_VULKAN_FEATURE(shaderCullDistance) + XE_UI_VULKAN_FEATURE(sparseBinding) + XE_UI_VULKAN_FEATURE(sparseResidencyBuffer) + } + + if (properties.apiVersion >= VK_MAKE_API_VERSION(0, 1, 2, 0)) { + if (with_gpu_emulation) { + XE_UI_VULKAN_FEATURE_2(features_1_2, samplerMirrorClampToEdge); + XE_UI_VULKAN_FEATURE_2(features_1_2, uniformBufferStandardLayout); + XE_UI_VULKAN_FEATURE_2(features_1_2, scalarBlockLayout); + } + } else { + if (ext_1_2_KHR_sampler_mirror_clamp_to_edge) { + XE_UI_VULKAN_FEATURE_IMPLIED(samplerMirrorClampToEdge) + } + } + + if (properties.apiVersion >= VK_MAKE_API_VERSION(0, 1, 3, 0)) { + if (with_gpu_emulation) { + XE_UI_VULKAN_FEATURE_2(features_1_3, shaderDemoteToHelperInvocation); + XE_UI_VULKAN_FEATURE_2(features_1_3, dynamicRendering); + } + } else { + if (ext_1_3_KHR_dynamic_rendering) { + if (with_gpu_emulation) { + XE_UI_VULKAN_FEATURE_2(features_1_3_KHR_dynamic_rendering, dynamicRendering); + } + } + if (ext_1_3_EXT_shader_demote_to_helper_invocation) { + if (with_gpu_emulation) { + XE_UI_VULKAN_FEATURE_2(features_1_3_EXT_shader_demote_to_helper_invocation, + shaderDemoteToHelperInvocation); + } + } + } + + if (ext_KHR_portability_subset) { + if (with_gpu_emulation) { + XE_UI_VULKAN_FEATURE_2(features_KHR_portability_subset, constantAlphaColorBlendFactors) + XE_UI_VULKAN_FEATURE_2(features_KHR_portability_subset, imageViewFormatReinterpretation) + XE_UI_VULKAN_FEATURE_2(features_KHR_portability_subset, imageViewFormatSwizzle) + XE_UI_VULKAN_FEATURE_2(features_KHR_portability_subset, pointPolygons) + XE_UI_VULKAN_FEATURE_2(features_KHR_portability_subset, separateStencilMaskRef) + XE_UI_VULKAN_FEATURE_2(features_KHR_portability_subset, + shaderSampleRateInterpolationFunctions) + } + } else { + // Not a portability subset device. + XE_UI_VULKAN_FEATURE_IMPLIED(constantAlphaColorBlendFactors) + XE_UI_VULKAN_FEATURE_IMPLIED(imageViewFormatReinterpretation) + XE_UI_VULKAN_FEATURE_IMPLIED(imageViewFormatSwizzle) + XE_UI_VULKAN_FEATURE_IMPLIED(pointPolygons) + XE_UI_VULKAN_FEATURE_IMPLIED(separateStencilMaskRef) + XE_UI_VULKAN_FEATURE_IMPLIED(shaderSampleRateInterpolationFunctions) + } + + if (ext_1_2_KHR_shader_float_controls) { + XE_UI_VULKAN_PROPERTY_2(properties_1_2_KHR_shader_float_controls, + shaderSignedZeroInfNanPreserveFloat32); + XE_UI_VULKAN_PROPERTY_2(properties_1_2_KHR_shader_float_controls, + shaderDenormFlushToZeroFloat32); + XE_UI_VULKAN_PROPERTY_2(properties_1_2_KHR_shader_float_controls, shaderRoundingModeRTEFloat32); + } + + if (ext_EXT_fragment_shader_interlock) { + if (with_gpu_emulation) { + XE_UI_VULKAN_FEATURE_2(features_EXT_fragment_shader_interlock, fragmentShaderSampleInterlock) + XE_UI_VULKAN_FEATURE_2(features_EXT_fragment_shader_interlock, fragmentShaderPixelInterlock) + } + } + + if (ext_EXT_non_seamless_cube_map) { + if (with_gpu_emulation) { + XE_UI_VULKAN_FEATURE_2(features_EXT_non_seamless_cube_map, nonSeamlessCubeMap) + } + } + + if (device->extensions_.ext_EXT_custom_border_color) { + if (with_gpu_emulation) { + XE_UI_VULKAN_FEATURE_2(features_EXT_custom_border_color, customBorderColors) + XE_UI_VULKAN_FEATURE_2(features_EXT_custom_border_color, customBorderColorWithoutFormat) + } + XE_UI_VULKAN_PROPERTY_2(properties_EXT_custom_border_color, maxCustomBorderColorSamplers) + } + + if (device->extensions_.ext_EXT_robustness2) { + if (with_gpu_emulation) { + XE_UI_VULKAN_FEATURE_2(features_EXT_robustness2, nullDescriptor) + } + } + +#undef XE_UI_VULKAN_LIMIT +#undef XE_UI_VULKAN_ENUM_LIMIT +#undef XE_UI_VULKAN_FEATURE +#undef XE_UI_VULKAN_PROPERTY_2 +#undef XE_UI_VULKAN_ENUM_PROPERTY_2 +#undef XE_UI_VULKAN_FEATURE_2 + + // Create the device. + + const VkResult device_create_result = + ifn.vkCreateDevice(physical_device, &device_create_info, nullptr, &device->device_); + if (device_create_result != VK_SUCCESS) { + REXLOG_ERROR( + "Failed to create a Vulkan logical device from the physical device " + "'{}': {}", + properties.deviceName, vk::to_string(vk::Result(device_create_result))); + return nullptr; + } + + // Load device functions. + + bool functions_loaded = true; + + Functions& dfn = device->functions_; + +#define XE_UI_VULKAN_FUNCTION(name) \ + functions_loaded &= \ + (dfn.name = PFN_##name(ifn.vkGetDeviceProcAddr(device->device_, #name))) != nullptr; + + // Vulkan 1.0. +#include + + // Extensions promoted to a Vulkan version supported by the device. +#define XE_UI_VULKAN_FUNCTION_PROMOTED(extension_name, core_name) \ + functions_loaded &= \ + (dfn.core_name = PFN_##core_name(ifn.vkGetDeviceProcAddr(device->device_, #core_name))) != \ + nullptr; + if (properties.apiVersion >= VK_MAKE_API_VERSION(0, 1, 1, 0)) { +#include +#include + } + if (properties.apiVersion >= VK_MAKE_API_VERSION(0, 1, 3, 0)) { +#include +#include + } +#undef XE_UI_VULKAN_FUNCTION_PROMOTED + + // Non-promoted extensions, and extensions promoted to a Vulkan version not + // supported by the device. +#define XE_UI_VULKAN_FUNCTION_PROMOTED(extension_name, core_name) \ + functions_loaded &= (dfn.core_name = PFN_##core_name( \ + ifn.vkGetDeviceProcAddr(device->device_, #extension_name))) != nullptr; + if (properties.apiVersion < VK_MAKE_API_VERSION(0, 1, 1, 0)) { + if (device->extensions_.ext_1_1_KHR_get_memory_requirements2) { +#include + } + if (device->extensions_.ext_1_1_KHR_bind_memory2) { +#include + } + } + if (properties.apiVersion < VK_MAKE_API_VERSION(0, 1, 3, 0)) { + if (device->extensions_.ext_1_3_KHR_dynamic_rendering) { +#include + } + if (device->extensions_.ext_1_3_KHR_maintenance4) { +#include + } + } + if (device->extensions_.ext_KHR_swapchain) { +#include + } +#undef XE_UI_VULKAN_FUNCTION_PROMOTED + +#undef XE_UI_VULKAN_FUNCTION + + if (!functions_loaded) { + REXLOG_ERROR("Failed to get all Vulkan device function pointers for '{}'", + properties.deviceName); + return nullptr; + } + + // Get the queues. + + for (size_t queue_family_index = 0; queue_family_index < device->queue_families_.size(); + ++queue_family_index) { + QueueFamily& queue_family = device->queue_families_[queue_family_index]; + for (size_t queue_index = 0; queue_index < queue_family.queues.size(); ++queue_index) { + VkQueue queue; + dfn.vkGetDeviceQueue(device->device_, uint32_t(queue_family_index), uint32_t(queue_index), + &queue); + queue_family.queues[queue_index] = std::make_unique(queue); + } + } + + // Get the memory types. + + VkPhysicalDeviceMemoryProperties memory_properties; + ifn.vkGetPhysicalDeviceMemoryProperties(physical_device, &memory_properties); + for (uint32_t memory_type_index = 0; memory_type_index < memory_properties.memoryTypeCount; + ++memory_type_index) { + const uint32_t memory_type_bit = uint32_t(1) << memory_type_index; + const VkMemoryPropertyFlags memory_type_flags = + memory_properties.memoryTypes[memory_type_index].propertyFlags; + if (memory_type_flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) { + device->memory_types_.device_local |= memory_type_bit; + } + if (memory_type_flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { + device->memory_types_.host_visible |= memory_type_bit; + } + if (memory_type_flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) { + device->memory_types_.host_coherent |= memory_type_bit; + } + if (memory_type_flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) { + device->memory_types_.host_cached |= memory_type_bit; + } + } + + return device; +} + +VulkanDevice::~VulkanDevice() { + if (device_) { + vulkan_instance_->functions().vkDestroyDevice(device_, nullptr); + } +} + +VulkanDevice::VulkanDevice(const VulkanInstance* const vulkan_instance, + const VkPhysicalDevice physical_device) + : vulkan_instance_(vulkan_instance), physical_device_(physical_device) { + assert_not_null(vulkan_instance); + assert_not_null(physical_device); +} + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/src/ui/vulkan/vulkan_immediate_drawer.cpp b/src/ui/vulkan/vulkan_immediate_drawer.cpp new file mode 100644 index 0000000..fa574c4 --- /dev/null +++ b/src/ui/vulkan/vulkan_immediate_drawer.cpp @@ -0,0 +1,1019 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace rex { +namespace ui { +namespace vulkan { + +// Generated with `xb buildshaders`. +namespace shaders { +#include "../shaders/vulkan_spirv/immediate_ps.h" +#include "../shaders/vulkan_spirv/immediate_vs.h" +} // namespace shaders + +std::unique_ptr VulkanImmediateDrawer::Create( + const VulkanDevice* const vulkan_device, const UISamplers* const ui_samplers) { + assert_not_null(vulkan_device); + assert_not_null(ui_samplers); + + auto immediate_drawer = + std::unique_ptr(new VulkanImmediateDrawer(vulkan_device, ui_samplers)); + if (!immediate_drawer->Initialize()) { + return nullptr; + } + return immediate_drawer; +} + +VulkanImmediateDrawer::VulkanImmediateTexture::~VulkanImmediateTexture() { + if (immediate_drawer_) { + immediate_drawer_->OnImmediateTextureDestroyed(*this); + } +} + +VulkanImmediateDrawer::~VulkanImmediateDrawer() { + // Await GPU usage completion of all draws and texture uploads (which happen + // before draws). + auto vulkan_presenter = static_cast(presenter()); + if (vulkan_presenter) { + vulkan_presenter->AwaitUISubmissionCompletionFromUIThread(last_paint_submission_index_); + } + + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, pipeline_line_); + util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, pipeline_triangle_); + + util::DestroyAndNullHandle(dfn.vkDestroyPipelineLayout, device, pipeline_layout_); + + for (auto& deleted_texture : textures_deleted_) { + DestroyTextureResource(deleted_texture.first); + } + for (SubmittedTextureUploadBuffer& submitted_texture_upload_buffer : + texture_upload_buffers_submitted_) { + dfn.vkDestroyBuffer(device, submitted_texture_upload_buffer.buffer, nullptr); + dfn.vkFreeMemory(device, submitted_texture_upload_buffer.buffer_memory, nullptr); + } + for (PendingTextureUpload& pending_texture_upload : texture_uploads_pending_) { + dfn.vkDestroyBuffer(device, pending_texture_upload.buffer, nullptr); + dfn.vkFreeMemory(device, pending_texture_upload.buffer_memory, nullptr); + } + for (VulkanImmediateTexture* texture : textures_) { + if (texture->immediate_drawer_ != this) { + continue; + } + texture->immediate_drawer_ = nullptr; + DestroyTextureResource(texture->resource_); + } + if (white_texture_.image != VK_NULL_HANDLE) { + DestroyTextureResource(white_texture_); + } + + for (TextureDescriptorPool* pool : texture_descriptor_pools_) { + dfn.vkDestroyDescriptorPool(device, pool->pool, nullptr); + delete pool; + } + util::DestroyAndNullHandle(dfn.vkDestroyDescriptorSetLayout, device, + texture_descriptor_set_layout_); +} + +VulkanImmediateDrawer::VulkanImmediateDrawer(const VulkanDevice* const vulkan_device, + const UISamplers* const ui_samplers) + : vulkan_device_(vulkan_device), ui_samplers_(ui_samplers) { + assert_not_null(vulkan_device); + assert_not_null(ui_samplers); +} + +bool VulkanImmediateDrawer::Initialize() { + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + VkDescriptorSetLayoutBinding texture_descriptor_set_layout_binding; + texture_descriptor_set_layout_binding.binding = 0; + texture_descriptor_set_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + texture_descriptor_set_layout_binding.descriptorCount = 1; + texture_descriptor_set_layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + texture_descriptor_set_layout_binding.pImmutableSamplers = nullptr; + VkDescriptorSetLayoutCreateInfo texture_descriptor_set_layout_create_info; + texture_descriptor_set_layout_create_info.sType = + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + texture_descriptor_set_layout_create_info.pNext = nullptr; + texture_descriptor_set_layout_create_info.flags = 0; + texture_descriptor_set_layout_create_info.bindingCount = 1; + texture_descriptor_set_layout_create_info.pBindings = &texture_descriptor_set_layout_binding; + if (dfn.vkCreateDescriptorSetLayout(device, &texture_descriptor_set_layout_create_info, nullptr, + &texture_descriptor_set_layout_) != VK_SUCCESS) { + REXLOG_ERROR( + "VulkanImmediateDrawer: Failed to create the combined image sampler " + "descriptor set layout"); + return false; + } + + // Create the (1, 1, 1, 1) texture as a replacement when drawing without a + // real texture. + size_t white_texture_pending_upload_index; + if (!CreateTextureResource(1, 1, ImmediateTextureFilter::kNearest, false, nullptr, white_texture_, + white_texture_pending_upload_index)) { + REXLOG_ERROR("VulkanImmediateDrawer: Failed to create a blank texture"); + return false; + } + + vertex_buffer_pool_ = std::make_unique( + vulkan_device_, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); + + VkPushConstantRange push_constant_ranges[1]; + push_constant_ranges[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + push_constant_ranges[0].offset = offsetof(PushConstants, vertex); + push_constant_ranges[0].size = sizeof(PushConstants::Vertex); + VkPipelineLayoutCreateInfo pipeline_layout_create_info; + pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipeline_layout_create_info.pNext = nullptr; + pipeline_layout_create_info.flags = 0; + pipeline_layout_create_info.setLayoutCount = 1; + pipeline_layout_create_info.pSetLayouts = &texture_descriptor_set_layout_; + pipeline_layout_create_info.pushConstantRangeCount = uint32_t(rex::countof(push_constant_ranges)); + pipeline_layout_create_info.pPushConstantRanges = push_constant_ranges; + if (dfn.vkCreatePipelineLayout(device, &pipeline_layout_create_info, nullptr, + &pipeline_layout_) != VK_SUCCESS) { + REXLOG_ERROR("VulkanImmediateDrawer: Failed to create the pipeline layout"); + return false; + } + + // Reset the current state. + batch_open_ = false; + + return true; +} + +std::unique_ptr VulkanImmediateDrawer::CreateTexture( + uint32_t width, uint32_t height, ImmediateTextureFilter filter, bool is_repeated, + const uint8_t* data) { + assert_not_null(data); + auto texture = std::make_unique(width, height); + size_t pending_upload_index; + if (CreateTextureResource(width, height, filter, is_repeated, data, texture->resource_, + pending_upload_index)) { + // Manage by this immediate drawer. + texture->immediate_drawer_ = this; + texture->immediate_drawer_index_ = textures_.size(); + textures_.push_back(texture.get()); + texture->pending_upload_index_ = pending_upload_index; + texture_uploads_pending_[texture->pending_upload_index_].texture = texture.get(); + } + return std::move(texture); +} + +void VulkanImmediateDrawer::Begin(UIDrawContext& ui_draw_context, float coordinate_space_width, + float coordinate_space_height) { + ImmediateDrawer::Begin(ui_draw_context, coordinate_space_width, coordinate_space_height); + + assert_false(batch_open_); + + const VulkanUIDrawContext& vulkan_ui_draw_context = + static_cast(ui_draw_context); + + // Update the submission index to be used throughout the current immediate + // drawer paint. + last_paint_submission_index_ = vulkan_ui_draw_context.submission_index_current(); + last_completed_submission_index_ = vulkan_ui_draw_context.submission_index_completed(); + + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + // Destroy deleted textures. + for (auto it = textures_deleted_.begin(); it != textures_deleted_.end();) { + if (it->second > last_completed_submission_index_) { + ++it; + continue; + } + DestroyTextureResource(it->first); + if (std::next(it) != textures_deleted_.end()) { + *it = textures_deleted_.back(); + } + textures_deleted_.pop_back(); + } + + // Release upload buffers for completed texture uploads. + auto erase_texture_uploads_end = texture_upload_buffers_submitted_.begin(); + while (erase_texture_uploads_end != texture_upload_buffers_submitted_.end()) { + if (erase_texture_uploads_end->submission_index > last_completed_submission_index_) { + break; + } + dfn.vkDestroyBuffer(device, erase_texture_uploads_end->buffer, nullptr); + dfn.vkFreeMemory(device, erase_texture_uploads_end->buffer_memory, nullptr); + ++erase_texture_uploads_end; + } + texture_upload_buffers_submitted_.erase(texture_upload_buffers_submitted_.begin(), + erase_texture_uploads_end); + + vertex_buffer_pool_->Reclaim(last_completed_submission_index_); + + // Begin drawing. + + // Update the framebuffer attachment format in the pipelines - may await + // submission completion if changing. + if (!EnsurePipelinesCreatedForCurrentRenderPass()) { + // Failed to create the pipelines - don't draw anything. + return; + } + + VkCommandBuffer draw_command_buffer = vulkan_ui_draw_context.draw_command_buffer(); + + VkViewport viewport; + viewport.x = 0.0f; + viewport.y = 0.0f; + viewport.width = float(vulkan_ui_draw_context.render_target_width()); + viewport.height = float(vulkan_ui_draw_context.render_target_height()); + viewport.minDepth = 0.0f; + viewport.maxDepth = 1.0f; + dfn.vkCmdSetViewport(draw_command_buffer, 0, 1, &viewport); + PushConstants::Vertex push_constants_vertex; + push_constants_vertex.coordinate_space_size_inv[0] = 1.0f / coordinate_space_width; + push_constants_vertex.coordinate_space_size_inv[1] = 1.0f / coordinate_space_height; + dfn.vkCmdPushConstants(draw_command_buffer, pipeline_layout_, VK_SHADER_STAGE_VERTEX_BIT, + offsetof(PushConstants, vertex), sizeof(PushConstants::Vertex), + &push_constants_vertex); + current_scissor_.offset.x = 0; + current_scissor_.offset.y = 0; + current_scissor_.extent.width = 0; + current_scissor_.extent.height = 0; + + current_pipeline_ = VK_NULL_HANDLE; + current_texture_descriptor_index_ = UINT32_MAX; +} + +void VulkanImmediateDrawer::BeginDrawBatch(const ImmediateDrawBatch& batch) { + assert_false(batch_open_); + + const VulkanUIDrawContext& vulkan_ui_draw_context = + *static_cast(ui_draw_context()); + VkCommandBuffer draw_command_buffer = vulkan_ui_draw_context.draw_command_buffer(); + + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + + // Bind the vertices. + size_t vertex_buffer_size = sizeof(ImmediateVertex) * batch.vertex_count; + VkBuffer vertex_buffer; + VkDeviceSize vertex_buffer_offset; + void* vertex_buffer_mapping = + vertex_buffer_pool_->Request(last_paint_submission_index_, vertex_buffer_size, sizeof(float), + vertex_buffer, vertex_buffer_offset); + if (!vertex_buffer_mapping) { + REXLOG_ERROR("VulkanImmediateDrawer: Failed to get a buffer for {} vertices", + batch.vertex_count); + return; + } + std::memcpy(vertex_buffer_mapping, batch.vertices, vertex_buffer_size); + dfn.vkCmdBindVertexBuffers(draw_command_buffer, 0, 1, &vertex_buffer, &vertex_buffer_offset); + + // Bind the indices. + batch_has_index_buffer_ = batch.indices != nullptr; + if (batch_has_index_buffer_) { + size_t index_buffer_size = sizeof(uint16_t) * batch.index_count; + VkBuffer index_buffer; + VkDeviceSize index_buffer_offset; + void* index_buffer_mapping = + vertex_buffer_pool_->Request(last_paint_submission_index_, index_buffer_size, + sizeof(uint16_t), index_buffer, index_buffer_offset); + if (!index_buffer_mapping) { + REXLOG_ERROR("VulkanImmediateDrawer: Failed to get a buffer for {} indices", + batch.index_count); + return; + } + std::memcpy(index_buffer_mapping, batch.indices, index_buffer_size); + dfn.vkCmdBindIndexBuffer(draw_command_buffer, index_buffer, index_buffer_offset, + VK_INDEX_TYPE_UINT16); + } + + batch_open_ = true; +} + +void VulkanImmediateDrawer::Draw(const ImmediateDraw& draw) { + if (!batch_open_) { + // Could have been an error while obtaining the vertex and index buffers, + // for instance. + return; + } + + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VulkanUIDrawContext& vulkan_ui_draw_context = + *static_cast(ui_draw_context()); + VkCommandBuffer draw_command_buffer = vulkan_ui_draw_context.draw_command_buffer(); + + // Get the pipeline for the current primitive type. + VkPipeline pipeline; + switch (draw.primitive_type) { + case ImmediatePrimitiveType::kLines: + pipeline = pipeline_line_; + break; + case ImmediatePrimitiveType::kTriangles: + pipeline = pipeline_triangle_; + break; + default: + assert_unhandled_case(draw.primitive_type); + return; + } + if (pipeline == VK_NULL_HANDLE) { + // Failed to create the pipeline. + return; + } + + // Set the scissor rectangle if enabled. + VkRect2D scissor; + uint32_t scissor_left, scissor_top; + if (!ScissorToRenderTarget(draw, scissor_left, scissor_top, scissor.extent.width, + scissor.extent.height)) { + // Nothing is visible (zero area is used as the default current_scissor_ + // value also). + return; + } + scissor.offset.x = int32_t(scissor_left); + scissor.offset.y = int32_t(scissor_top); + if (current_scissor_.offset.x != scissor.offset.x || + current_scissor_.offset.y != scissor.offset.y || + current_scissor_.extent.width != scissor.extent.width || + current_scissor_.extent.height != scissor.extent.height) { + current_scissor_ = scissor; + dfn.vkCmdSetScissor(draw_command_buffer, 0, 1, &scissor); + } + + // Bind the pipeline for the primitive type if the scissor is not empty. + if (current_pipeline_ != pipeline) { + current_pipeline_ = pipeline; + dfn.vkCmdBindPipeline(draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + } + + // Bind the texture. + uint32_t texture_descriptor_index; + VulkanImmediateTexture* texture = static_cast(draw.texture); + if (texture && texture->immediate_drawer_ == this) { + texture_descriptor_index = texture->resource_.descriptor_index; + texture->last_usage_submission_ = last_paint_submission_index_; + } else { + texture_descriptor_index = white_texture_.descriptor_index; + } + if (current_texture_descriptor_index_ != texture_descriptor_index) { + current_texture_descriptor_index_ = texture_descriptor_index; + VkDescriptorSet texture_descriptor_set = GetTextureDescriptor(texture_descriptor_index); + dfn.vkCmdBindDescriptorSets(draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + pipeline_layout_, 0, 1, &texture_descriptor_set, 0, nullptr); + } + + // Draw. + if (batch_has_index_buffer_) { + dfn.vkCmdDrawIndexed(draw_command_buffer, draw.count, 1, draw.index_offset, draw.base_vertex, + 0); + } else { + dfn.vkCmdDraw(draw_command_buffer, draw.count, 1, draw.base_vertex, 0); + } +} + +void VulkanImmediateDrawer::EndDrawBatch() { + batch_open_ = false; +} + +void VulkanImmediateDrawer::End() { + assert_false(batch_open_); + + // Upload textures. + if (!texture_uploads_pending_.empty()) { + VulkanPresenter& vulkan_presenter = *static_cast(presenter()); + VkCommandBuffer setup_command_buffer = + vulkan_presenter.AcquireUISetupCommandBufferFromUIThread(); + if (setup_command_buffer != VK_NULL_HANDLE) { + size_t texture_uploads_pending_count = texture_uploads_pending_.size(); + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VulkanUIDrawContext& vulkan_ui_draw_context = + *static_cast(ui_draw_context()); + + // Transition to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL. + std::vector image_memory_barriers; + image_memory_barriers.reserve(texture_uploads_pending_count); + VkImageMemoryBarrier image_memory_barrier; + image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + image_memory_barrier.pNext = nullptr; + image_memory_barrier.srcAccessMask = 0; + image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.subresourceRange = util::InitializeSubresourceRange(); + for (const PendingTextureUpload& pending_texture_upload : texture_uploads_pending_) { + image_memory_barriers.emplace_back(image_memory_barrier).image = + pending_texture_upload.image; + } + dfn.vkCmdPipelineBarrier(setup_command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, + uint32_t(image_memory_barriers.size()), + image_memory_barriers.data()); + + // Do transfer operations and transition to + // VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, and also mark as used. + for (size_t i = 0; i < texture_uploads_pending_count; ++i) { + const PendingTextureUpload& pending_texture_upload = texture_uploads_pending_[i]; + if (pending_texture_upload.buffer != VK_NULL_HANDLE) { + // Copying. + VkBufferImageCopy copy_region; + copy_region.bufferOffset = 0; + copy_region.bufferRowLength = pending_texture_upload.width; + copy_region.bufferImageHeight = pending_texture_upload.height; + copy_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + copy_region.imageSubresource.mipLevel = 0; + copy_region.imageSubresource.baseArrayLayer = 0; + copy_region.imageSubresource.layerCount = 1; + copy_region.imageOffset.x = 0; + copy_region.imageOffset.y = 0; + copy_region.imageOffset.z = 0; + copy_region.imageExtent.width = pending_texture_upload.width; + copy_region.imageExtent.height = pending_texture_upload.height; + copy_region.imageExtent.depth = 1; + dfn.vkCmdCopyBufferToImage(setup_command_buffer, pending_texture_upload.buffer, + pending_texture_upload.image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©_region); + + SubmittedTextureUploadBuffer& submitted_texture_upload_buffer = + texture_upload_buffers_submitted_.emplace_back(); + submitted_texture_upload_buffer.buffer = pending_texture_upload.buffer; + submitted_texture_upload_buffer.buffer_memory = pending_texture_upload.buffer_memory; + submitted_texture_upload_buffer.submission_index = last_paint_submission_index_; + } else { + // Clearing (initializing the special empty image). + VkClearColorValue white_clear_value; + white_clear_value.float32[0] = 1.0f; + white_clear_value.float32[1] = 1.0f; + white_clear_value.float32[2] = 1.0f; + white_clear_value.float32[3] = 1.0f; + dfn.vkCmdClearColorImage(setup_command_buffer, pending_texture_upload.image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &white_clear_value, 1, + &image_memory_barrier.subresourceRange); + } + + VkImageMemoryBarrier& image_memory_barrier_current = image_memory_barriers[i]; + image_memory_barrier_current.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + image_memory_barrier_current.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + image_memory_barrier_current.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + image_memory_barrier_current.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + if (pending_texture_upload.texture) { + pending_texture_upload.texture->last_usage_submission_ = last_paint_submission_index_; + pending_texture_upload.texture->pending_upload_index_ = SIZE_MAX; + } + } + dfn.vkCmdPipelineBarrier(setup_command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, + uint32_t(image_memory_barriers.size()), + image_memory_barriers.data()); + + texture_uploads_pending_.clear(); + } + } + + vertex_buffer_pool_->FlushWrites(); + + ImmediateDrawer::End(); +} + +void VulkanImmediateDrawer::OnLeavePresenter() { + // Leaving the presenter's submission timeline - await GPU usage completion of + // all draws and texture uploads (which happen before draws) and reset + // submission indices. + VulkanPresenter& vulkan_presenter = *static_cast(presenter()); + vulkan_presenter.AwaitUISubmissionCompletionFromUIThread(last_paint_submission_index_); + + for (VulkanImmediateTexture* texture : textures_) { + texture->last_usage_submission_ = 0; + } + + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + for (SubmittedTextureUploadBuffer& submitted_texture_upload_buffer : + texture_upload_buffers_submitted_) { + dfn.vkDestroyBuffer(device, submitted_texture_upload_buffer.buffer, nullptr); + dfn.vkFreeMemory(device, submitted_texture_upload_buffer.buffer_memory, nullptr); + } + + vertex_buffer_pool_->ChangeSubmissionTimeline(); + + last_paint_submission_index_ = 0; + last_completed_submission_index_ = 0; +} + +bool VulkanImmediateDrawer::EnsurePipelinesCreatedForCurrentRenderPass() { + const VulkanUIDrawContext& vulkan_ui_draw_context = + *static_cast(ui_draw_context()); + VkFormat render_pass_format = vulkan_ui_draw_context.render_pass_format(); + + if (render_pass_format == pipeline_framebuffer_format_) { + // Either created, or failed to create once (don't try to create every + // frame). + return pipeline_triangle_ != VK_NULL_HANDLE && pipeline_line_ != VK_NULL_HANDLE; + } + + if (last_paint_submission_index_ && pipeline_triangle_ != VK_NULL_HANDLE && + pipeline_line_ != VK_NULL_HANDLE) { + // Make sure it's safe to delete the pipelines. + VulkanPresenter& vulkan_presenter = *static_cast(presenter()); + vulkan_presenter.AwaitUISubmissionCompletionFromUIThread(last_paint_submission_index_); + } + + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + // Safe to destroy the pipelines now - if the render pass was recreated, + // completion of its usage has already been awaited. + util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, pipeline_line_); + util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, pipeline_triangle_); + // If creation fails now, don't try to create every frame. + pipeline_framebuffer_format_ = render_pass_format; + + // Triangle pipeline. + + VkPipelineShaderStageCreateInfo stages[2] = {}; + stages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; + stages[0].module = util::CreateShaderModule(vulkan_device_, shaders::immediate_vs, + sizeof(shaders::immediate_vs)); + if (stages[0].module == VK_NULL_HANDLE) { + REXLOG_ERROR("VulkanImmediateDrawer: Failed to create the vertex shader module"); + return false; + } + stages[0].pName = "main"; + stages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; + stages[1].module = util::CreateShaderModule(vulkan_device_, shaders::immediate_ps, + sizeof(shaders::immediate_ps)); + if (stages[1].module == VK_NULL_HANDLE) { + REXLOG_ERROR("VulkanImmediateDrawer: Failed to create the fragment shader module"); + dfn.vkDestroyShaderModule(device, stages[0].module, nullptr); + return false; + } + stages[1].pName = "main"; + + VkVertexInputBindingDescription vertex_input_binding; + vertex_input_binding.binding = 0; + vertex_input_binding.stride = sizeof(ImmediateVertex); + vertex_input_binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; + VkVertexInputAttributeDescription vertex_input_attributes[3]; + vertex_input_attributes[0].location = 0; + vertex_input_attributes[0].binding = 0; + vertex_input_attributes[0].format = VK_FORMAT_R32G32_SFLOAT; + vertex_input_attributes[0].offset = offsetof(ImmediateVertex, x); + vertex_input_attributes[1].location = 1; + vertex_input_attributes[1].binding = 0; + vertex_input_attributes[1].format = VK_FORMAT_R32G32_SFLOAT; + vertex_input_attributes[1].offset = offsetof(ImmediateVertex, u); + vertex_input_attributes[2].location = 2; + vertex_input_attributes[2].binding = 0; + vertex_input_attributes[2].format = VK_FORMAT_R8G8B8A8_UNORM; + vertex_input_attributes[2].offset = offsetof(ImmediateVertex, color); + VkPipelineVertexInputStateCreateInfo vertex_input_state; + vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + vertex_input_state.pNext = nullptr; + vertex_input_state.flags = 0; + vertex_input_state.vertexBindingDescriptionCount = 1; + vertex_input_state.pVertexBindingDescriptions = &vertex_input_binding; + vertex_input_state.vertexAttributeDescriptionCount = + uint32_t(rex::countof(vertex_input_attributes)); + vertex_input_state.pVertexAttributeDescriptions = vertex_input_attributes; + + VkPipelineInputAssemblyStateCreateInfo input_assembly_state; + input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + input_assembly_state.pNext = nullptr; + input_assembly_state.flags = 0; + input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + input_assembly_state.primitiveRestartEnable = VK_FALSE; + + VkPipelineViewportStateCreateInfo viewport_state; + viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + viewport_state.pNext = nullptr; + viewport_state.flags = 0; + viewport_state.viewportCount = 1; + viewport_state.pViewports = nullptr; + viewport_state.scissorCount = 1; + viewport_state.pScissors = nullptr; + + VkPipelineRasterizationStateCreateInfo rasterization_state = {}; + rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rasterization_state.polygonMode = VK_POLYGON_MODE_FILL; + rasterization_state.cullMode = VK_CULL_MODE_NONE; + rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; + rasterization_state.lineWidth = 1.0f; + + VkPipelineMultisampleStateCreateInfo multisample_state = {}; + multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + + VkPipelineColorBlendAttachmentState color_blend_attachment_state; + color_blend_attachment_state.blendEnable = VK_TRUE; + color_blend_attachment_state.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; + color_blend_attachment_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + color_blend_attachment_state.colorBlendOp = VK_BLEND_OP_ADD; + color_blend_attachment_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; + color_blend_attachment_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE; + color_blend_attachment_state.alphaBlendOp = VK_BLEND_OP_ADD; + color_blend_attachment_state.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | + VK_COLOR_COMPONENT_G_BIT | + VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + VkPipelineColorBlendStateCreateInfo color_blend_state = {}; + color_blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + color_blend_state.attachmentCount = 1; + color_blend_state.pAttachments = &color_blend_attachment_state; + + static const VkDynamicState dynamic_states[] = { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, + }; + VkPipelineDynamicStateCreateInfo dynamic_state; + dynamic_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynamic_state.pNext = nullptr; + dynamic_state.flags = 0; + dynamic_state.dynamicStateCount = uint32_t(rex::countof(dynamic_states)); + dynamic_state.pDynamicStates = dynamic_states; + + VkGraphicsPipelineCreateInfo pipeline_create_info; + pipeline_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipeline_create_info.pNext = nullptr; + pipeline_create_info.flags = VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT; + pipeline_create_info.stageCount = uint32_t(rex::countof(stages)); + pipeline_create_info.pStages = stages; + pipeline_create_info.pVertexInputState = &vertex_input_state; + pipeline_create_info.pInputAssemblyState = &input_assembly_state; + pipeline_create_info.pTessellationState = nullptr; + pipeline_create_info.pViewportState = &viewport_state; + pipeline_create_info.pRasterizationState = &rasterization_state; + pipeline_create_info.pMultisampleState = &multisample_state; + pipeline_create_info.pDepthStencilState = nullptr; + pipeline_create_info.pColorBlendState = &color_blend_state; + pipeline_create_info.pDynamicState = &dynamic_state; + pipeline_create_info.layout = pipeline_layout_; + pipeline_create_info.renderPass = vulkan_ui_draw_context.render_pass(); + pipeline_create_info.subpass = 0; + pipeline_create_info.basePipelineHandle = VK_NULL_HANDLE; + pipeline_create_info.basePipelineIndex = -1; + if (dfn.vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipeline_create_info, nullptr, + &pipeline_triangle_) != VK_SUCCESS) { + REXLOG_ERROR("VulkanImmediateDrawer: Failed to create the triangle list pipeline"); + dfn.vkDestroyShaderModule(device, stages[1].module, nullptr); + dfn.vkDestroyShaderModule(device, stages[0].module, nullptr); + return false; + } + + // Line pipeline. + + input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST; + pipeline_create_info.flags = + (pipeline_create_info.flags & ~VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT) | + VK_PIPELINE_CREATE_DERIVATIVE_BIT; + pipeline_create_info.basePipelineHandle = pipeline_triangle_; + VkResult pipeline_line_create_result = dfn.vkCreateGraphicsPipelines( + device, VK_NULL_HANDLE, 1, &pipeline_create_info, nullptr, &pipeline_line_); + dfn.vkDestroyShaderModule(device, stages[1].module, nullptr); + dfn.vkDestroyShaderModule(device, stages[0].module, nullptr); + if (pipeline_line_create_result != VK_SUCCESS) { + REXLOG_ERROR("VulkanImmediateDrawer: Failed to create the line list pipeline"); + dfn.vkDestroyPipeline(device, pipeline_triangle_, nullptr); + pipeline_triangle_ = VK_NULL_HANDLE; + return false; + } + + return true; +} + +uint32_t VulkanImmediateDrawer::AllocateTextureDescriptor() { + // Try to reuse a recycled descriptor first. + if (texture_descriptor_pool_recycled_first_) { + TextureDescriptorPool* pool = texture_descriptor_pool_recycled_first_; + assert_not_zero(pool->recycled_bits); + uint32_t local_index; + rex::bit_scan_forward(pool->recycled_bits, &local_index); + pool->recycled_bits &= ~(uint64_t(1) << local_index); + if (!pool->recycled_bits) { + texture_descriptor_pool_recycled_first_ = pool->recycled_next; + } + return (pool->index << 6) | local_index; + } + + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + VkDescriptorSetAllocateInfo allocate_info; + allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + allocate_info.pNext = nullptr; + allocate_info.descriptorSetCount = 1; + allocate_info.pSetLayouts = &texture_descriptor_set_layout_; + + // If no recycled, try to create a new allocation within an existing pool with + // unallocated descriptors left. + while (texture_descriptor_pool_unallocated_first_) { + TextureDescriptorPool* pool = texture_descriptor_pool_unallocated_first_; + assert_not_zero(pool->unallocated_count); + allocate_info.descriptorPool = pool->pool; + uint32_t local_index = TextureDescriptorPool::kDescriptorCount - pool->unallocated_count; + VkResult allocate_result = + dfn.vkAllocateDescriptorSets(device, &allocate_info, &pool->sets[local_index]); + if (allocate_result == VK_SUCCESS) { + --pool->unallocated_count; + } else { + // Failed to allocate for some reason, don't try again for this pool. + pool->unallocated_count = 0; + } + if (!pool->unallocated_count) { + texture_descriptor_pool_unallocated_first_ = pool->unallocated_next; + } + if (allocate_result == VK_SUCCESS) { + return (pool->index << 6) | local_index; + } + } + + // Create a new pool and allocate the descriptor from it. + VkDescriptorPoolSize descriptor_pool_size; + descriptor_pool_size.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descriptor_pool_size.descriptorCount = TextureDescriptorPool::kDescriptorCount; + VkDescriptorPoolCreateInfo descriptor_pool_create_info; + descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + descriptor_pool_create_info.pNext = nullptr; + descriptor_pool_create_info.flags = 0; + descriptor_pool_create_info.maxSets = TextureDescriptorPool::kDescriptorCount; + descriptor_pool_create_info.poolSizeCount = 1; + descriptor_pool_create_info.pPoolSizes = &descriptor_pool_size; + VkDescriptorPool descriptor_pool; + if (dfn.vkCreateDescriptorPool(device, &descriptor_pool_create_info, nullptr, &descriptor_pool) != + VK_SUCCESS) { + REXLOG_ERROR( + "VulkanImmediateDrawer: Failed to create a combined image sampler " + "descriptor pool with {} descriptors", + TextureDescriptorPool::kDescriptorCount); + return UINT32_MAX; + } + allocate_info.descriptorPool = descriptor_pool; + VkDescriptorSet descriptor_set; + if (dfn.vkAllocateDescriptorSets(device, &allocate_info, &descriptor_set) != VK_SUCCESS) { + REXLOG_ERROR( + "VulkanImmediateDrawer: Failed to allocate a combined image sampler " + "descriptor"); + dfn.vkDestroyDescriptorPool(device, descriptor_pool, nullptr); + return UINT32_MAX; + } + TextureDescriptorPool* new_pool = new TextureDescriptorPool; + new_pool->pool = descriptor_pool; + new_pool->sets[0] = descriptor_set; + uint32_t new_pool_index = uint32_t(texture_descriptor_pools_.size()); + new_pool->index = new_pool_index; + new_pool->unallocated_count = TextureDescriptorPool::kDescriptorCount - 1; + new_pool->recycled_bits = 0; + new_pool->unallocated_next = texture_descriptor_pool_unallocated_first_; + texture_descriptor_pool_unallocated_first_ = new_pool; + new_pool->recycled_next = nullptr; + texture_descriptor_pools_.push_back(new_pool); + return new_pool_index << 6; +} + +VkDescriptorSet VulkanImmediateDrawer::GetTextureDescriptor(uint32_t descriptor_index) const { + uint32_t pool_index = descriptor_index >> 6; + assert_true(pool_index < texture_descriptor_pools_.size()); + const TextureDescriptorPool* pool = texture_descriptor_pools_[pool_index]; + uint32_t allocation_index = descriptor_index & 63; + assert_true(allocation_index < TextureDescriptorPool::kDescriptorCount - pool->unallocated_count); + return pool->sets[allocation_index]; +} + +void VulkanImmediateDrawer::FreeTextureDescriptor(uint32_t descriptor_index) { + uint32_t pool_index = descriptor_index >> 6; + assert_true(pool_index < texture_descriptor_pools_.size()); + TextureDescriptorPool* pool = texture_descriptor_pools_[pool_index]; + uint32_t allocation_index = descriptor_index & 63; + assert_true(allocation_index < TextureDescriptorPool::kDescriptorCount - pool->unallocated_count); + assert_zero(pool->recycled_bits & (uint64_t(1) << allocation_index)); + if (!pool->recycled_bits) { + // Add to the free list if not already in it. + pool->recycled_next = texture_descriptor_pool_recycled_first_; + texture_descriptor_pool_recycled_first_ = pool; + } + pool->recycled_bits |= uint64_t(1) << allocation_index; +} + +bool VulkanImmediateDrawer::CreateTextureResource(uint32_t width, uint32_t height, + ImmediateTextureFilter filter, bool is_repeated, + const uint8_t* data, + VulkanImmediateTexture::Resource& resource_out, + size_t& pending_upload_index_out) { + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + // Create the image and the descriptor. + + VkImageCreateInfo image_create_info; + image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + image_create_info.pNext = nullptr; + image_create_info.flags = 0; + image_create_info.imageType = VK_IMAGE_TYPE_2D; + image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM; + image_create_info.extent.width = width; + image_create_info.extent.height = height; + image_create_info.extent.depth = 1; + image_create_info.mipLevels = 1; + image_create_info.arrayLayers = 1; + image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; + image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; + image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + image_create_info.queueFamilyIndexCount = 0; + image_create_info.pQueueFamilyIndices = nullptr; + image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + VkImage image; + VkDeviceMemory image_memory; + if (!util::CreateDedicatedAllocationImage(vulkan_device_, image_create_info, + util::MemoryPurpose::kDeviceLocal, image, + image_memory)) { + REXLOG_ERROR( + "VulkanImmediateDrawer: Failed to create an image with dedicated " + "memory for a {}x{} texture", + width, height); + return false; + } + + VkImageViewCreateInfo image_view_create_info; + image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + image_view_create_info.pNext = nullptr; + image_view_create_info.flags = 0; + image_view_create_info.image = image; + image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; + image_view_create_info.format = VK_FORMAT_R8G8B8A8_UNORM; + // data == nullptr is a special case for (1, 1, 1, 1), though the image will + // be cleared to (1, 1, 1, 1) anyway, just a micro-optimization. + VkComponentSwizzle swizzle = (data || !vulkan_device_->properties().imageViewFormatSwizzle) + ? VK_COMPONENT_SWIZZLE_IDENTITY + : VK_COMPONENT_SWIZZLE_ONE; + image_view_create_info.components.r = swizzle; + image_view_create_info.components.g = swizzle; + image_view_create_info.components.b = swizzle; + image_view_create_info.components.a = swizzle; + image_view_create_info.subresourceRange = util::InitializeSubresourceRange(); + VkImageView image_view; + if (dfn.vkCreateImageView(device, &image_view_create_info, nullptr, &image_view) != VK_SUCCESS) { + REXLOG_ERROR( + "VulkanImmediateDrawer: Failed to create an image view for a {}x{} " + "image", + width, height); + dfn.vkDestroyImage(device, image, nullptr); + dfn.vkFreeMemory(device, image_memory, nullptr); + return false; + } + + uint32_t descriptor_index = AllocateTextureDescriptor(); + if (descriptor_index == UINT32_MAX) { + REXLOG_ERROR("VulkanImmediateDrawer: Failed to allocate a descriptor for an image"); + dfn.vkDestroyImageView(device, image_view, nullptr); + dfn.vkDestroyImage(device, image, nullptr); + dfn.vkFreeMemory(device, image_memory, nullptr); + return false; + } + VkDescriptorImageInfo descriptor_image_info; + UISamplers::SamplerIndex ui_sampler_index; + if (filter == ImmediateTextureFilter::kLinear) { + ui_sampler_index = is_repeated ? UISamplers::kSamplerIndexLinearRepeat + : UISamplers::kSamplerIndexLinearClampToEdge; + } else { + ui_sampler_index = is_repeated ? UISamplers::kSamplerIndexNearestRepeat + : UISamplers::kSamplerIndexNearestClampToEdge; + } + descriptor_image_info.sampler = ui_samplers_->samplers()[ui_sampler_index]; + descriptor_image_info.imageView = image_view; + descriptor_image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + VkWriteDescriptorSet descriptor_write; + descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptor_write.pNext = nullptr; + descriptor_write.dstSet = GetTextureDescriptor(descriptor_index); + descriptor_write.dstBinding = 0; + descriptor_write.dstArrayElement = 0; + descriptor_write.descriptorCount = 1; + descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descriptor_write.pImageInfo = &descriptor_image_info; + descriptor_write.pBufferInfo = nullptr; + descriptor_write.pTexelBufferView = nullptr; + dfn.vkUpdateDescriptorSets(device, 1, &descriptor_write, 0, nullptr); + + // Create and fill the upload buffer. + + // data == nullptr is a special case for (1, 1, 1, 1), clearing rather than + // uploading in this case. + VkBuffer upload_buffer = VK_NULL_HANDLE; + VkDeviceMemory upload_buffer_memory = VK_NULL_HANDLE; + if (data) { + size_t data_size = sizeof(uint32_t) * width * height; + uint32_t upload_buffer_memory_type; + if (!util::CreateDedicatedAllocationBuffer(vulkan_device_, VkDeviceSize(data_size), + VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + util::MemoryPurpose::kUpload, upload_buffer, + upload_buffer_memory, &upload_buffer_memory_type)) { + REXLOG_ERROR( + "VulkanImmediateDrawer: Failed to create an upload buffer for a " + "{}x{} image", + width, height); + FreeTextureDescriptor(descriptor_index); + dfn.vkDestroyImageView(device, image_view, nullptr); + dfn.vkDestroyImage(device, image, nullptr); + dfn.vkFreeMemory(device, image_memory, nullptr); + return false; + } + void* upload_buffer_mapping; + if (dfn.vkMapMemory(device, upload_buffer_memory, 0, VK_WHOLE_SIZE, 0, + &upload_buffer_mapping) != VK_SUCCESS) { + REXLOG_ERROR( + "VulkanImmediateDrawer: Failed to map upload buffer memory for a " + "{}x{} image", + width, height); + dfn.vkDestroyBuffer(device, upload_buffer, nullptr); + dfn.vkFreeMemory(device, upload_buffer_memory, nullptr); + FreeTextureDescriptor(descriptor_index); + dfn.vkDestroyImageView(device, image_view, nullptr); + dfn.vkDestroyImage(device, image, nullptr); + dfn.vkFreeMemory(device, image_memory, nullptr); + return false; + } + std::memcpy(upload_buffer_mapping, data, data_size); + util::FlushMappedMemoryRange(vulkan_device_, upload_buffer_memory, upload_buffer_memory_type); + dfn.vkUnmapMemory(device, upload_buffer_memory); + } + + resource_out.image = image; + resource_out.memory = image_memory; + resource_out.image_view = image_view; + resource_out.descriptor_index = descriptor_index; + + pending_upload_index_out = texture_uploads_pending_.size(); + PendingTextureUpload& pending_upload = texture_uploads_pending_.emplace_back(); + // The caller will set the ImmedateTexture pointer if needed. + pending_upload.texture = nullptr; + pending_upload.buffer = upload_buffer; + pending_upload.buffer_memory = upload_buffer_memory; + pending_upload.image = image; + pending_upload.width = width; + pending_upload.height = height; + + return true; +} + +void VulkanImmediateDrawer::DestroyTextureResource(VulkanImmediateTexture::Resource& resource) { + FreeTextureDescriptor(resource.descriptor_index); + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + dfn.vkDestroyImageView(device, resource.image_view, nullptr); + dfn.vkDestroyImage(device, resource.image, nullptr); + dfn.vkFreeMemory(device, resource.memory, nullptr); +} + +void VulkanImmediateDrawer::OnImmediateTextureDestroyed(VulkanImmediateTexture& texture) { + // Remove from the pending uploads. + size_t pending_upload_index = texture.pending_upload_index_; + if (pending_upload_index != SIZE_MAX) { + if (pending_upload_index + 1 < texture_uploads_pending_.size()) { + PendingTextureUpload& pending_upload = texture_uploads_pending_[pending_upload_index]; + pending_upload = texture_uploads_pending_.back(); + if (pending_upload.texture) { + pending_upload.texture->pending_upload_index_ = pending_upload_index; + } + } + texture_uploads_pending_.pop_back(); + } + + // Remove from the texture list. + VulkanImmediateTexture*& texture_at_index = textures_[texture.immediate_drawer_index_]; + texture_at_index = textures_.back(); + texture_at_index->immediate_drawer_index_ = texture.immediate_drawer_index_; + textures_.pop_back(); + + // Destroy immediately or queue for destruction if in use. + if (texture.last_usage_submission_ > last_completed_submission_index_) { + textures_deleted_.emplace_back( + std::make_pair(texture.resource_, texture.last_usage_submission_)); + } else { + DestroyTextureResource(texture.resource_); + } +} + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/src/ui/vulkan/vulkan_instance.cpp b/src/ui/vulkan/vulkan_instance.cpp new file mode 100644 index 0000000..0d2ded3 --- /dev/null +++ b/src/ui/vulkan/vulkan_instance.cpp @@ -0,0 +1,575 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(vulkan_log_debug_messages, true, "UI/Vulkan", "Log Vulkan debug messages"); + +namespace rex { +namespace ui { +namespace vulkan { + +std::unique_ptr VulkanInstance::Create(const bool with_surface, + const bool try_enable_validation) { + std::unique_ptr vulkan_instance(new VulkanInstance()); + + // Load the RenderDoc API if connected. + + vulkan_instance->renderdoc_api_ = RenderDocAPI::CreateIfConnected(); + + // Load the loader library. + + Functions& ifn = vulkan_instance->functions_; + + bool functions_loaded = true; + if (!vulkan_instance->loader_.Load(platform::lib_names::kVulkanLoader)) { + REXLOG_ERROR("Failed to load {}", platform::lib_names::kVulkanLoader); + return nullptr; + } +#define XE_VULKAN_LOAD_LOADER_FUNCTION(name) \ + functions_loaded &= (ifn.name = vulkan_instance->loader_.GetSymbol(#name)) != nullptr; + XE_VULKAN_LOAD_LOADER_FUNCTION(vkGetInstanceProcAddr); + XE_VULKAN_LOAD_LOADER_FUNCTION(vkDestroyInstance); +#undef XE_VULKAN_LOAD_LOADER_FUNCTION + if (!functions_loaded) { + REXLOG_ERROR("Failed to get Vulkan loader function pointers"); + return nullptr; + } + + // Load global functions. + + functions_loaded &= (ifn.vkCreateInstance = PFN_vkCreateInstance( + ifn.vkGetInstanceProcAddr(nullptr, "vkCreateInstance"))) != nullptr; + functions_loaded &= (ifn.vkEnumerateInstanceExtensionProperties = + PFN_vkEnumerateInstanceExtensionProperties(ifn.vkGetInstanceProcAddr( + nullptr, "vkEnumerateInstanceExtensionProperties"))) != nullptr; + functions_loaded &= + (ifn.vkEnumerateInstanceLayerProperties = PFN_vkEnumerateInstanceLayerProperties( + ifn.vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceLayerProperties"))) != nullptr; + if (!functions_loaded) { + REXLOG_ERROR( + "Failed to get Vulkan global function pointers via " + "vkGetInstanceProcAddr"); + return nullptr; + } + // Available since Vulkan 1.1. If this is nullptr, it's a Vulkan 1.0 instance. + ifn.vkEnumerateInstanceVersion = PFN_vkEnumerateInstanceVersion( + ifn.vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceVersion")); + + // Get the API version. + + if (ifn.vkEnumerateInstanceVersion) { + ifn.vkEnumerateInstanceVersion(&vulkan_instance->api_version_); + } + + // Enable extensions and layers. + + // Name pointers from `requested_extensions` will be used in the enabled + // extensions vector. + std::unordered_map requested_extensions; + if (vulkan_instance->api_version_ >= VK_MAKE_API_VERSION(0, 1, 1, 0)) { + vulkan_instance->extensions_.ext_1_1_KHR_get_physical_device_properties2 = true; + } else { + // #60. + requested_extensions.emplace( + "VK_KHR_get_physical_device_properties2", + &vulkan_instance->extensions_.ext_1_1_KHR_get_physical_device_properties2); + } + // #129. + requested_extensions.emplace("VK_EXT_debug_utils", + &vulkan_instance->extensions_.ext_EXT_debug_utils); + // #395. + requested_extensions.emplace("VK_KHR_portability_enumeration", + &vulkan_instance->extensions_.ext_KHR_portability_enumeration); + if (with_surface) { + // #1. + requested_extensions.emplace("VK_KHR_surface", &vulkan_instance->extensions_.ext_KHR_surface); +#ifdef VK_USE_PLATFORM_XCB_KHR + // #6. + requested_extensions.emplace("VK_KHR_xcb_surface", + &vulkan_instance->extensions_.ext_KHR_xcb_surface); +#endif +#ifdef VK_USE_PLATFORM_ANDROID_KHR + // #9. + requested_extensions.emplace("VK_KHR_android_surface", + &vulkan_instance->extensions_.ext_KHR_android_surface); +#endif +#ifdef VK_USE_PLATFORM_WIN32_KHR + // #10. + requested_extensions.emplace("VK_KHR_win32_surface", + &vulkan_instance->extensions_.ext_KHR_win32_surface); +#endif + } + + std::vector enabled_extensions; + + std::vector supported_implementation_extensions; + while (true) { + uint32_t supported_implementation_extension_count = 0; + const VkResult get_supported_implementation_extension_count_result = + ifn.vkEnumerateInstanceExtensionProperties( + nullptr, &supported_implementation_extension_count, nullptr); + if (get_supported_implementation_extension_count_result != VK_SUCCESS && + get_supported_implementation_extension_count_result != VK_INCOMPLETE) { + REXLOG_WARN("Failed to get the Vulkan instance extension count"); + return nullptr; + } + if (supported_implementation_extension_count) { + supported_implementation_extensions.resize(supported_implementation_extension_count); + const VkResult get_supported_implementation_extensions_result = + ifn.vkEnumerateInstanceExtensionProperties(nullptr, + &supported_implementation_extension_count, + supported_implementation_extensions.data()); + if (get_supported_implementation_extensions_result == VK_INCOMPLETE) { + continue; + } + if (get_supported_implementation_extensions_result != VK_SUCCESS) { + REXLOG_WARN("Failed to get the Vulkan instance extensions"); + return nullptr; + } + } + supported_implementation_extensions.resize(supported_implementation_extension_count); + break; + } + + for (const VkExtensionProperties& supported_extension : supported_implementation_extensions) { + const auto requested_extension_it = + requested_extensions.find(supported_extension.extensionName); + if (requested_extension_it == requested_extensions.cend()) { + continue; + } + assert_not_null(requested_extension_it->second); + if (!*requested_extension_it->second) { + enabled_extensions.emplace_back(requested_extension_it->first.c_str()); + *requested_extension_it->second = true; + } + } + + // If enabled layers are not present, will disable all extensions provided by + // the layers by truncating the enabled extension vector to this size. + const size_t enabled_implementation_extension_count = enabled_extensions.size(); + std::vector enabled_layer_extension_enablement_bools; + + // Name pointers from `requested_layers` will be used in the enabled layer + // vector. + std::unordered_map requested_layers; + bool layer_khronos_validation = false; + if (try_enable_validation) { + requested_layers.emplace("VK_LAYER_KHRONOS_validation", &layer_khronos_validation); + } + + std::vector enabled_layers; + + if (!requested_layers.empty()) { + std::vector available_layers; + // "The list of available layers may change at any time due to actions + // outside of the Vulkan implementation" + while (true) { + available_layers.clear(); + uint32_t available_layer_count = 0; + const VkResult get_available_layer_count_result = + ifn.vkEnumerateInstanceLayerProperties(&available_layer_count, nullptr); + if (get_available_layer_count_result != VK_SUCCESS && + get_available_layer_count_result != VK_INCOMPLETE) { + break; + } + if (available_layer_count) { + available_layers.resize(available_layer_count); + const VkResult get_available_layers_result = + ifn.vkEnumerateInstanceLayerProperties(&available_layer_count, available_layers.data()); + if (get_available_layers_result == VK_INCOMPLETE) { + // New layers were added. + continue; + } + if (get_available_layers_result != VK_SUCCESS) { + available_layers.clear(); + break; + } + // In case the second enumeration returned fewer layers. + available_layers.resize(available_layer_count); + } + break; + } + + if (!available_layers.empty()) { + std::vector supported_layer_extensions; + + for (const VkLayerProperties& available_layer : available_layers) { + auto requested_layer_it = requested_layers.find(available_layer.layerName); + if (requested_layer_it == requested_layers.cend()) { + continue; + } + + bool got_layer_extensions = true; + // "Because the list of available layers may change externally between + // calls to vkEnumerateInstanceExtensionProperties, two calls may + // retrieve different results if a pLayerName is available in one call + // but not in another." + while (true) { + uint32_t supported_layer_extension_count = 0; + const VkResult get_supported_layer_extension_count_result = + ifn.vkEnumerateInstanceExtensionProperties(nullptr, &supported_layer_extension_count, + nullptr); + if (get_supported_layer_extension_count_result != VK_SUCCESS && + get_supported_layer_extension_count_result != VK_INCOMPLETE) { + got_layer_extensions = false; + break; + } + if (supported_layer_extension_count) { + supported_layer_extensions.resize(supported_layer_extension_count); + const VkResult get_supported_layer_extensions_result = + ifn.vkEnumerateInstanceExtensionProperties(available_layer.layerName, + &supported_layer_extension_count, + supported_layer_extensions.data()); + if (get_supported_layer_extensions_result == VK_INCOMPLETE) { + continue; + } + if (get_supported_layer_extensions_result != VK_SUCCESS) { + got_layer_extensions = false; + break; + } + } + supported_layer_extensions.resize(supported_layer_extension_count); + break; + } + if (!got_layer_extensions) { + // The layer was possibly removed. + continue; + } + + for (const VkExtensionProperties& supported_extension : supported_layer_extensions) { + const auto requested_extension_it = + requested_extensions.find(supported_extension.extensionName); + if (requested_extension_it == requested_extensions.cend()) { + continue; + } + assert_not_null(requested_extension_it->second); + // Don't add the extension to the enabled vector multiple times if + // provided by the implementation itself or by another layer. + if (!*requested_extension_it->second) { + enabled_extensions.emplace_back(requested_extension_it->first.c_str()); + enabled_layer_extension_enablement_bools.push_back(requested_layer_it->second); + *requested_extension_it->second = true; + } + } + + assert_not_null(requested_layer_it->second); + if (!*requested_layer_it->second) { + enabled_layers.emplace_back(requested_layer_it->first.c_str()); + *requested_layer_it->second = true; + } + } + } + } + + // Create the instance. + + VkApplicationInfo application_info; + application_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + application_info.pNext = nullptr; + application_info.pApplicationName = "Xenia"; + application_info.applicationVersion = 1; + application_info.pEngineName = nullptr; + application_info.engineVersion = 0; + // "The patch version number specified in apiVersion is ignored when creating + // an instance object." + // "Vulkan 1.0 implementations were required to return + // VK_ERROR_INCOMPATIBLE_DRIVER if apiVersion was larger than 1.0." + application_info.apiVersion = vulkan_instance->api_version_ >= VK_MAKE_API_VERSION(0, 1, 1, 0) + ? VulkanDevice::kHighestUsedApiMinorVersion + : VK_MAKE_API_VERSION(0, 1, 0, 0); + + VkInstanceCreateInfo instance_create_info; + instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + instance_create_info.pNext = nullptr; + instance_create_info.flags = 0; + // VK_KHR_get_physical_device_properties2 is needed to get the portability + // subset features. + if (vulkan_instance->extensions_.ext_KHR_portability_enumeration && + vulkan_instance->extensions_.ext_1_1_KHR_get_physical_device_properties2) { + instance_create_info.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; + } + instance_create_info.pApplicationInfo = &application_info; + instance_create_info.enabledLayerCount = uint32_t(enabled_layers.size()); + instance_create_info.ppEnabledLayerNames = enabled_layers.data(); + instance_create_info.enabledExtensionCount = uint32_t(enabled_extensions.size()); + instance_create_info.ppEnabledExtensionNames = enabled_extensions.data(); + VkResult instance_create_result = + ifn.vkCreateInstance(&instance_create_info, nullptr, &vulkan_instance->instance_); + + if (instance_create_result == VK_ERROR_LAYER_NOT_PRESENT || + instance_create_result == VK_ERROR_EXTENSION_NOT_PRESENT) { + // A layer was possibly removed. Try without layers. + for (bool* const extension_enablement : enabled_layer_extension_enablement_bools) { + *extension_enablement = false; + } + for (const std::pair& requested_layer : requested_layers) { + *requested_layer.second = false; + } + instance_create_info.enabledLayerCount = 0; + instance_create_info.enabledExtensionCount = uint32_t(enabled_implementation_extension_count); + instance_create_result = + ifn.vkCreateInstance(&instance_create_info, nullptr, &vulkan_instance->instance_); + } + + if (instance_create_result != VK_SUCCESS) { + REXLOG_ERROR("Failed to create a Vulkan instance: {}", + vk::to_string(vk::Result(instance_create_result))); + return nullptr; + } + + // Load instance functions. + +#define XE_UI_VULKAN_FUNCTION(name) \ + functions_loaded &= \ + (ifn.name = PFN_##name(ifn.vkGetInstanceProcAddr(vulkan_instance->instance_, #name))) != \ + nullptr; + + // Vulkan 1.0. +#include + + // Extensions promoted to a Vulkan version supported by the instance. +#define XE_UI_VULKAN_FUNCTION_PROMOTED(extension_name, core_name) \ + functions_loaded &= (ifn.core_name = PFN_##core_name(ifn.vkGetInstanceProcAddr( \ + vulkan_instance->instance_, #core_name))) != nullptr; + if (vulkan_instance->api_version_ >= VK_MAKE_API_VERSION(0, 1, 1, 0)) { +#include + } +#undef XE_UI_VULKAN_FUNCTION_PROMOTED + + // Non-promoted extensions, and extensions promoted to a Vulkan version not + // supported by the instance. +#define XE_UI_VULKAN_FUNCTION_PROMOTED(extension_name, core_name) \ + functions_loaded &= (ifn.core_name = PFN_##core_name(ifn.vkGetInstanceProcAddr( \ + vulkan_instance->instance_, #extension_name))) != nullptr; + if (vulkan_instance->api_version_ < VK_MAKE_API_VERSION(0, 1, 1, 0)) { + if (vulkan_instance->extensions_.ext_1_1_KHR_get_physical_device_properties2) { +#include + } + } +#ifdef VK_USE_PLATFORM_XCB_KHR + if (vulkan_instance->extensions_.ext_KHR_xcb_surface) { +#include + } +#endif +#ifdef VK_USE_PLATFORM_ANDROID_KHR + if (vulkan_instance->extensions_.ext_KHR_android_surface) { +#include + } +#endif +#ifdef VK_USE_PLATFORM_WIN32_KHR + if (vulkan_instance->extensions_.ext_KHR_win32_surface) { +#include + } +#endif + if (vulkan_instance->extensions_.ext_KHR_surface) { +#include + } + if (vulkan_instance->extensions_.ext_EXT_debug_utils) { +#include + } +#undef XE_UI_VULKAN_FUNCTION_PROMOTED + +#undef XE_UI_VULKAN_FUNCTION + + if (!functions_loaded) { + REXLOG_ERROR("Failed to get all Vulkan instance function pointers"); + return nullptr; + } + + // Check whether a surface can be created. + + if (with_surface && + !VulkanPresenter::GetSurfaceTypesSupportedByInstance(vulkan_instance->extensions_)) { + REXLOG_ERROR("The Vulkan instance doesn't support surface types used by Xenia"); + return nullptr; + } + + // Log instance properties. + + REXLOG_INFO("Vulkan instance API version {}.{}.{}. Enabled layers and extensions:", + VK_VERSION_MAJOR(vulkan_instance->api_version_), + VK_VERSION_MINOR(vulkan_instance->api_version_), + VK_VERSION_PATCH(vulkan_instance->api_version_)); + for (uint32_t enabled_layer_index = 0; + enabled_layer_index < instance_create_info.enabledLayerCount; ++enabled_layer_index) { + REXLOG_INFO("* {}", instance_create_info.ppEnabledLayerNames[enabled_layer_index]); + } + for (uint32_t enabled_extension_index = 0; + enabled_extension_index < instance_create_info.enabledExtensionCount; + ++enabled_extension_index) { + REXLOG_INFO("* {}", instance_create_info.ppEnabledExtensionNames[enabled_extension_index]); + } + + // Create the debug messenger if requested and available. + + if (vulkan_instance->extensions_.ext_EXT_debug_utils && REXCVAR_GET(vulkan_log_debug_messages)) { + VkDebugUtilsMessengerCreateInfoEXT debug_utils_messenger_create_info = { + VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT}; + auto gpu_logger = rex::GetLogger(rex::log::gpu()); + if (gpu_logger) { + if (gpu_logger->should_log(spdlog::level::debug)) { + debug_utils_messenger_create_info.messageSeverity |= + VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT; + } + if (gpu_logger->should_log(spdlog::level::info)) { + debug_utils_messenger_create_info.messageSeverity |= + VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT; + } + if (gpu_logger->should_log(spdlog::level::warn)) { + debug_utils_messenger_create_info.messageSeverity |= + VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT; + } + if (gpu_logger->should_log(spdlog::level::err)) { + debug_utils_messenger_create_info.messageSeverity |= + VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + } + } + // VUID-VkDebugUtilsMessengerCreateInfoEXT-messageSeverity-requiredbitmask: + // "messageSeverity must not be 0" + if (debug_utils_messenger_create_info.messageSeverity) { + debug_utils_messenger_create_info.messageType = + VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; + debug_utils_messenger_create_info.pfnUserCallback = DebugUtilsMessengerCallback; + debug_utils_messenger_create_info.pUserData = vulkan_instance.get(); + const VkResult debug_utils_messenger_create_result = ifn.vkCreateDebugUtilsMessengerEXT( + vulkan_instance->instance_, &debug_utils_messenger_create_info, nullptr, + &vulkan_instance->debug_utils_messenger_); + if (debug_utils_messenger_create_result != VK_SUCCESS) { + REXLOG_WARN("Failed to create the Vulkan debug utils messenger: {}", + vk::to_string(vk::Result(debug_utils_messenger_create_result))); + } + } + } + + return vulkan_instance; +} + +VulkanInstance::~VulkanInstance() { + if (instance_) { + if (debug_utils_messenger_ != VK_NULL_HANDLE) { + functions_.vkDestroyDebugUtilsMessengerEXT(instance_, debug_utils_messenger_, nullptr); + } + + functions_.vkDestroyInstance(instance_, nullptr); + } + + loader_.Close(); +} + +void VulkanInstance::EnumeratePhysicalDevices( + std::vector& physical_devices_out) const { + physical_devices_out.clear(); + while (true) { + uint32_t physical_device_count = 0; + const VkResult get_physical_device_count_result = + functions_.vkEnumeratePhysicalDevices(instance_, &physical_device_count, nullptr); + if ((get_physical_device_count_result != VK_SUCCESS && + get_physical_device_count_result != VK_INCOMPLETE) || + !physical_device_count) { + return; + } + physical_devices_out.resize(physical_device_count); + const VkResult get_physical_devices_result = functions_.vkEnumeratePhysicalDevices( + instance_, &physical_device_count, physical_devices_out.data()); + if (get_physical_devices_result == VK_INCOMPLETE) { + continue; + } + physical_devices_out.resize(get_physical_devices_result == VK_SUCCESS ? physical_device_count + : 0); + return; + } +} + +VkBool32 VulkanInstance::DebugUtilsMessengerCallback( + VkDebugUtilsMessageSeverityFlagBitsEXT message_severity, + VkDebugUtilsMessageTypeFlagsEXT message_types, + const VkDebugUtilsMessengerCallbackDataEXT* callback_data, [[maybe_unused]] void* user_data) { + std::ostringstream log_str; + + log_str << "Vulkan " << vk::to_string(vk::DebugUtilsMessageSeverityFlagBitsEXT(message_severity)) + << " (" << vk::to_string(vk::DebugUtilsMessageTypeFlagsEXT(message_types)) << ", ID " + << callback_data->messageIdNumber; + if (callback_data->pMessageIdName) { + log_str << ": " << callback_data->pMessageIdName; + } + log_str << ')'; + + if (callback_data->pMessage) { + log_str << ": " << callback_data->pMessage; + } + + bool annotations_begun = false; + const auto begin_annotation = [&log_str, &annotations_begun]() { + log_str << (annotations_begun ? ", " : " ("); + annotations_begun = true; + }; + + for (uint32_t queue_label_index = 0; queue_label_index < callback_data->queueLabelCount; + ++queue_label_index) { + begin_annotation(); + log_str << "queue label " << queue_label_index << ": " + << callback_data->pQueueLabels[queue_label_index].pLabelName; + } + + for (uint32_t cmd_buf_label_index = 0; cmd_buf_label_index < callback_data->cmdBufLabelCount; + ++cmd_buf_label_index) { + begin_annotation(); + log_str << "command buffer label " << cmd_buf_label_index << ": " + << callback_data->pCmdBufLabels[cmd_buf_label_index].pLabelName; + } + + for (uint32_t object_index = 0; object_index < callback_data->objectCount; ++object_index) { + begin_annotation(); + const VkDebugUtilsObjectNameInfoEXT& object_info = callback_data->pObjects[object_index]; + // Lowercase hexadecimal digits in the handle to match the default Vulkan + // debug utils messenger. + log_str << "object " << object_index << ": " + << vk::to_string(vk::ObjectType(object_info.objectType)) << " 0x" << std::hex + << object_info.objectHandle << std::dec; + if (object_info.pObjectName) { + log_str << " '" << object_info.pObjectName << '\''; + } + } + + if (annotations_begun) { + log_str << ')'; + } + + auto msg = log_str.str(); + if (message_severity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { + REXGPU_ERROR("{}", msg); + } else if (message_severity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) { + REXGPU_WARN("{}", msg); + } else if (message_severity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) { + REXGPU_INFO("{}", msg); + } else { + REXGPU_DEBUG("{}", msg); + } + + return VK_FALSE; +} + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/src/ui/vulkan/vulkan_mem_alloc.cpp b/src/ui/vulkan/vulkan_mem_alloc.cpp new file mode 100644 index 0000000..9ffc2d1 --- /dev/null +++ b/src/ui/vulkan/vulkan_mem_alloc.cpp @@ -0,0 +1,98 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +// Implementing VMA in this translation unit. +#define VMA_IMPLEMENTATION +#include + +#include +#include + +namespace rex { +namespace ui { +namespace vulkan { + +VmaAllocator CreateVmaAllocator(const VulkanDevice* const vulkan_device, + const bool externally_synchronized) { + assert_not_null(vulkan_device); + + const VulkanInstance* const vulkan_instance = vulkan_device->vulkan_instance(); + const VulkanInstance::Functions& ifn = vulkan_instance->functions(); + const VulkanDevice::Functions& dfn = vulkan_device->functions(); + + VmaVulkanFunctions vma_vulkan_functions = {}; + VmaAllocatorCreateInfo allocator_create_info = {}; + + vma_vulkan_functions.vkGetInstanceProcAddr = ifn.vkGetInstanceProcAddr; + vma_vulkan_functions.vkGetDeviceProcAddr = ifn.vkGetDeviceProcAddr; + vma_vulkan_functions.vkGetPhysicalDeviceProperties = ifn.vkGetPhysicalDeviceProperties; + vma_vulkan_functions.vkGetPhysicalDeviceMemoryProperties = + ifn.vkGetPhysicalDeviceMemoryProperties; + vma_vulkan_functions.vkAllocateMemory = dfn.vkAllocateMemory; + vma_vulkan_functions.vkFreeMemory = dfn.vkFreeMemory; + vma_vulkan_functions.vkMapMemory = dfn.vkMapMemory; + vma_vulkan_functions.vkUnmapMemory = dfn.vkUnmapMemory; + vma_vulkan_functions.vkFlushMappedMemoryRanges = dfn.vkFlushMappedMemoryRanges; + vma_vulkan_functions.vkInvalidateMappedMemoryRanges = dfn.vkInvalidateMappedMemoryRanges; + vma_vulkan_functions.vkBindBufferMemory = dfn.vkBindBufferMemory; + vma_vulkan_functions.vkBindImageMemory = dfn.vkBindImageMemory; + vma_vulkan_functions.vkGetBufferMemoryRequirements = dfn.vkGetBufferMemoryRequirements; + vma_vulkan_functions.vkGetImageMemoryRequirements = dfn.vkGetImageMemoryRequirements; + vma_vulkan_functions.vkCreateBuffer = dfn.vkCreateBuffer; + vma_vulkan_functions.vkDestroyBuffer = dfn.vkDestroyBuffer; + vma_vulkan_functions.vkCreateImage = dfn.vkCreateImage; + vma_vulkan_functions.vkDestroyImage = dfn.vkDestroyImage; + vma_vulkan_functions.vkCmdCopyBuffer = dfn.vkCmdCopyBuffer; + if (vulkan_device->extensions().ext_1_1_KHR_get_memory_requirements2) { + vma_vulkan_functions.vkGetBufferMemoryRequirements2KHR = dfn.vkGetBufferMemoryRequirements2; + vma_vulkan_functions.vkGetImageMemoryRequirements2KHR = dfn.vkGetImageMemoryRequirements2; + if (vulkan_device->extensions().ext_1_1_KHR_dedicated_allocation) { + allocator_create_info.flags |= VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT; + } + } + if (vulkan_device->extensions().ext_1_1_KHR_bind_memory2) { + vma_vulkan_functions.vkBindBufferMemory2KHR = dfn.vkBindBufferMemory2; + vma_vulkan_functions.vkBindImageMemory2KHR = dfn.vkBindImageMemory2; + allocator_create_info.flags |= VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT; + } + if (vulkan_instance->extensions().ext_1_1_KHR_get_physical_device_properties2) { + vma_vulkan_functions.vkGetPhysicalDeviceMemoryProperties2KHR = + ifn.vkGetPhysicalDeviceMemoryProperties2; + if (vulkan_device->extensions().ext_EXT_memory_budget) { + allocator_create_info.flags |= VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT; + } + } + if (vulkan_device->extensions().ext_1_3_KHR_maintenance4) { + vma_vulkan_functions.vkGetDeviceBufferMemoryRequirements = + dfn.vkGetDeviceBufferMemoryRequirements; + vma_vulkan_functions.vkGetDeviceImageMemoryRequirements = + dfn.vkGetDeviceImageMemoryRequirements; + } + + if (externally_synchronized) { + allocator_create_info.flags |= VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT; + } + allocator_create_info.physicalDevice = vulkan_device->physical_device(); + allocator_create_info.device = vulkan_device->device(); + allocator_create_info.pVulkanFunctions = &vma_vulkan_functions; + allocator_create_info.instance = vulkan_instance->instance(); + allocator_create_info.vulkanApiVersion = vulkan_device->properties().apiVersion; + VmaAllocator allocator; + if (vmaCreateAllocator(&allocator_create_info, &allocator) != VK_SUCCESS) { + REXLOG_ERROR("Failed to create a Vulkan Memory Allocator instance"); + return VK_NULL_HANDLE; + } + return allocator; +} + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/src/ui/vulkan/vulkan_presenter.cpp b/src/ui/vulkan/vulkan_presenter.cpp new file mode 100644 index 0000000..30bafba --- /dev/null +++ b/src/ui/vulkan/vulkan_presenter.cpp @@ -0,0 +1,2632 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME +#include +#include +#include +#endif + +#if REX_PLATFORM_ANDROID +#include +#endif +#if REX_PLATFORM_GNU_LINUX +#include +#endif +#if REX_PLATFORM_WIN32 +#include +#endif + +REXCVAR_DEFINE_BOOL(present_render_pass_clear, true, "UI/Presenter", + "Clear render pass during presentation"); + +REXCVAR_DEFINE_BOOL(vulkan_allow_present_mode_immediate, true, "UI/Vulkan", + "Allow immediate present mode (no vsync)"); + +REXCVAR_DEFINE_BOOL(vulkan_allow_present_mode_mailbox, true, "UI/Vulkan", + "Allow mailbox present mode (triple buffering)"); + +REXCVAR_DEFINE_BOOL(vulkan_allow_present_mode_fifo_relaxed, true, "UI/Vulkan", + "Allow FIFO relaxed present mode"); + +namespace rex { +namespace ui { +namespace vulkan { + +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME +namespace { + +std::atomic g_ffx_vk_get_device_proc_addr{nullptr}; + +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL FfxVkGetDeviceProcAddrCompat(VkDevice device, + const char* p_name) { + if (!p_name) { + return nullptr; + } + + PFN_vkGetDeviceProcAddr get_device_proc_addr = + g_ffx_vk_get_device_proc_addr.load(std::memory_order_relaxed); + if (!get_device_proc_addr) { + return nullptr; + } + + PFN_vkVoidFunction proc = get_device_proc_addr(device, p_name); + if (proc) { + return proc; + } + + // Some drivers expose Vulkan 1.1+ core entry points, but not the legacy KHR + // aliases expected by parts of FidelityFX VK backend initialization. + if (!std::strcmp(p_name, "vkGetBufferMemoryRequirements2KHR")) { + return get_device_proc_addr(device, "vkGetBufferMemoryRequirements2"); + } + if (!std::strcmp(p_name, "vkGetImageMemoryRequirements2KHR")) { + return get_device_proc_addr(device, "vkGetImageMemoryRequirements2"); + } + if (!std::strcmp(p_name, "vkBindBufferMemory2KHR")) { + return get_device_proc_addr(device, "vkBindBufferMemory2"); + } + if (!std::strcmp(p_name, "vkBindImageMemory2KHR")) { + return get_device_proc_addr(device, "vkBindImageMemory2"); + } + + return nullptr; +} + +} // namespace +#endif // defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME + +// Generated with `xb buildshaders`. +namespace shaders { +#include "../shaders/vulkan_spirv/guest_output_bilinear_dither_ps.h" +#include "../shaders/vulkan_spirv/guest_output_bilinear_ps.h" +#if defined(REX_HAS_FIDELITYFX_SDK) +#include "../shaders/vulkan_spirv/guest_output_ffx_cas_resample_dither_ps.h" +#include "../shaders/vulkan_spirv/guest_output_ffx_cas_resample_ps.h" +#include "../shaders/vulkan_spirv/guest_output_ffx_cas_sharpen_dither_ps.h" +#include "../shaders/vulkan_spirv/guest_output_ffx_cas_sharpen_ps.h" +#include "../shaders/vulkan_spirv/guest_output_ffx_fsr_easu_ps.h" +#include "../shaders/vulkan_spirv/guest_output_ffx_fsr_rcas_dither_ps.h" +#include "../shaders/vulkan_spirv/guest_output_ffx_fsr_rcas_ps.h" +#endif +#include "../shaders/vulkan_spirv/guest_output_triangle_strip_rect_vs.h" +} // namespace shaders + +VulkanPresenter::PaintContext::Submission::~Submission() { + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + if (draw_command_pool_ != VK_NULL_HANDLE) { + dfn.vkDestroyCommandPool(device, draw_command_pool_, nullptr); + } + + if (present_semaphore_ != VK_NULL_HANDLE) { + dfn.vkDestroySemaphore(device, present_semaphore_, nullptr); + } + if (acquire_semaphore_ != VK_NULL_HANDLE) { + dfn.vkDestroySemaphore(device, acquire_semaphore_, nullptr); + } +} + +bool VulkanPresenter::PaintContext::Submission::Initialize() { + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + VkSemaphoreCreateInfo semaphore_create_info; + semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + semaphore_create_info.pNext = nullptr; + semaphore_create_info.flags = 0; + if (dfn.vkCreateSemaphore(device, &semaphore_create_info, nullptr, &acquire_semaphore_) != + VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to create a swapchain image acquisition " + "semaphore"); + return false; + } + if (dfn.vkCreateSemaphore(device, &semaphore_create_info, nullptr, &present_semaphore_) != + VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to create a swapchain image presentation " + "semaphore"); + return false; + } + + VkCommandPoolCreateInfo command_pool_create_info; + command_pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + command_pool_create_info.pNext = nullptr; + command_pool_create_info.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT; + command_pool_create_info.queueFamilyIndex = vulkan_device_->queue_family_graphics_compute(); + if (dfn.vkCreateCommandPool(device, &command_pool_create_info, nullptr, &draw_command_pool_) != + VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to create a command pool for drawing to a " + "swapchain"); + return false; + } + VkCommandBufferAllocateInfo command_buffer_allocate_info; + command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + command_buffer_allocate_info.pNext = nullptr; + command_buffer_allocate_info.commandPool = draw_command_pool_; + command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + command_buffer_allocate_info.commandBufferCount = 1; + if (dfn.vkAllocateCommandBuffers(device, &command_buffer_allocate_info, &draw_command_buffer_) != + VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to allocate a command buffer for drawing to a " + "swapchain"); + return false; + } + + return true; +} + +VulkanPresenter::~VulkanPresenter() { + // Destroy the swapchain after its images are not used for drawing anymore. + // This is a confusing part in Vulkan, as vkQueuePresentKHR doesn't signal a + // fence clearly indicating when it's safe to destroy a swapchain, so we + // assume that its lifetime is tracked internally in the WSI. This is also + // done before destroying the semaphore awaited by vkQueuePresentKHR, hoping + // that it will prevent the destruction during the semaphore wait in + // vkQueuePresentKHR execution (or between the vkQueueSubmit semaphore signal + // and the vkQueuePresentKHR semaphore wait). + // This will await completion of all paint submissions also. + paint_context_.DestroySwapchainAndVulkanSurface(); + + // Await completion of the usage of everything before destroying anything + // (paint submission completion already awaited). + // From most likely the latest to most likely the earliest to be signaled, so + // just one sleep will likely be needed. + ui_submission_tracker_.Shutdown(); + guest_output_image_refresher_submission_tracker_.Shutdown(); +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME + DestroyTemporalUpscalerContext(); +#endif + + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + if (paint_context_.swapchain_render_pass != VK_NULL_HANDLE) { + dfn.vkDestroyRenderPass(device, paint_context_.swapchain_render_pass, nullptr); + } + + for (const PaintContext::UISetupCommandBuffer& ui_setup_command_buffer : + paint_context_.ui_setup_command_buffers) { + dfn.vkDestroyCommandPool(device, ui_setup_command_buffer.command_pool, nullptr); + } + + for (VkFramebuffer& framebuffer : paint_context_.guest_output_intermediate_framebuffers) { + util::DestroyAndNullHandle(dfn.vkDestroyFramebuffer, device, framebuffer); + } + util::DestroyAndNullHandle(dfn.vkDestroyDescriptorPool, device, + paint_context_.guest_output_descriptor_pool); + for (PaintContext::GuestOutputPaintPipeline& guest_output_paint_pipeline : + paint_context_.guest_output_paint_pipelines) { + util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, + guest_output_paint_pipeline.swapchain_pipeline); + util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, + guest_output_paint_pipeline.intermediate_pipeline); + } + + util::DestroyAndNullHandle(dfn.vkDestroyRenderPass, device, + guest_output_intermediate_render_pass_); + for (VkShaderModule& shader_module : guest_output_paint_fs_) { + util::DestroyAndNullHandle(dfn.vkDestroyShaderModule, device, shader_module); + } + util::DestroyAndNullHandle(dfn.vkDestroyShaderModule, device, guest_output_paint_vs_); + for (VkPipelineLayout& pipeline_layout : guest_output_paint_pipeline_layouts_) { + util::DestroyAndNullHandle(dfn.vkDestroyPipelineLayout, device, pipeline_layout); + } + util::DestroyAndNullHandle(dfn.vkDestroyDescriptorSetLayout, device, + guest_output_paint_image_descriptor_set_layout_); +} + +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME +void VulkanPresenter::DestroyTemporalUpscalerContext() { + if (!temporal_upscaler_context_) { + return; + } + ffxContext* context = reinterpret_cast(&temporal_upscaler_context_); + ffxDestroyContext(context, nullptr); + temporal_upscaler_context_ = nullptr; + temporal_upscaler_max_render_width_ = 0; + temporal_upscaler_max_render_height_ = 0; + temporal_upscaler_max_output_width_ = 0; + temporal_upscaler_max_output_height_ = 0; +} + +bool VulkanPresenter::EnsureTemporalUpscalerContext(uint32_t render_width, uint32_t render_height, + uint32_t output_width, uint32_t output_height) { + if (!temporal_upscaler_context_ || temporal_upscaler_max_render_width_ != render_width || + temporal_upscaler_max_render_height_ != render_height || + temporal_upscaler_max_output_width_ != output_width || + temporal_upscaler_max_output_height_ != output_height) { + DestroyTemporalUpscalerContext(); + + ffxCreateContextDescUpscale create_desc = {}; + create_desc.header.type = FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE; + create_desc.header.pNext = nullptr; + create_desc.flags = FFX_UPSCALE_ENABLE_HIGH_DYNAMIC_RANGE | FFX_UPSCALE_ENABLE_AUTO_EXPOSURE; + create_desc.maxRenderSize.width = render_width; + create_desc.maxRenderSize.height = render_height; + create_desc.maxUpscaleSize.width = output_width; + create_desc.maxUpscaleSize.height = output_height; + create_desc.fpMessage = nullptr; + + ffxCreateBackendVKDesc backend_desc = {}; + backend_desc.header.type = FFX_API_CREATE_CONTEXT_DESC_TYPE_BACKEND_VK; + backend_desc.header.pNext = nullptr; + backend_desc.vkDevice = vulkan_device_->device(); + backend_desc.vkPhysicalDevice = vulkan_device_->physical_device(); + PFN_vkGetDeviceProcAddr vk_device_proc_addr = reinterpret_cast( + vulkan_device_->vulkan_instance()->functions().vkGetInstanceProcAddr( + vulkan_device_->vulkan_instance()->instance(), "vkGetDeviceProcAddr")); + if (!vk_device_proc_addr) { + REXLOG_WARN("VulkanPresenter: vkGetDeviceProcAddr is unavailable for FidelityFX"); + return false; + } + g_ffx_vk_get_device_proc_addr.store(vk_device_proc_addr, std::memory_order_relaxed); + backend_desc.vkDeviceProcAddr = FfxVkGetDeviceProcAddrCompat; + + create_desc.header.pNext = &backend_desc.header; + + ffxContext* context = reinterpret_cast(&temporal_upscaler_context_); + if (ffxCreateContext(context, &create_desc.header, nullptr) != FFX_API_RETURN_OK) { + REXLOG_WARN( + "VulkanPresenter: Failed to create FidelityFX temporal upscaler " + "context"); + temporal_upscaler_context_ = nullptr; + return false; + } + + temporal_upscaler_max_render_width_ = render_width; + temporal_upscaler_max_render_height_ = render_height; + temporal_upscaler_max_output_width_ = output_width; + temporal_upscaler_max_output_height_ = output_height; + temporal_upscaler_provider_logged_ = false; + } + + if (!temporal_upscaler_provider_logged_) { + ffxQueryGetProviderVersion provider_version = {}; + provider_version.header.type = FFX_API_QUERY_DESC_TYPE_GET_PROVIDER_VERSION; + provider_version.header.pNext = nullptr; + ffxContext* context = reinterpret_cast(&temporal_upscaler_context_); + if (ffxQuery(context, &provider_version.header) == FFX_API_RETURN_OK && + provider_version.versionName) { + REXLOG_INFO("VulkanPresenter: FidelityFX upscaler provider {}", provider_version.versionName); + } + temporal_upscaler_provider_logged_ = true; + } + + return temporal_upscaler_context_ != nullptr; +} + +bool VulkanPresenter::DispatchTemporalUpscaler(VkCommandBuffer command_buffer, VkImage input_image, + uint32_t input_width, uint32_t input_height, + VkImage output_image, uint32_t output_width, + uint32_t output_height, + const GuestOutputPaintConfig& config) { + if (command_buffer == VK_NULL_HANDLE || input_image == VK_NULL_HANDLE || + output_image == VK_NULL_HANDLE || !input_width || !input_height || !output_width || + !output_height) { + return false; + } + if (!EnsureTemporalUpscalerContext(input_width, input_height, output_width, output_height)) { + return false; + } + + VkImageCreateInfo source_image_create_info = {}; + source_image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + source_image_create_info.imageType = VK_IMAGE_TYPE_2D; + source_image_create_info.format = kGuestOutputFormat; + source_image_create_info.extent.width = input_width; + source_image_create_info.extent.height = input_height; + source_image_create_info.extent.depth = 1; + source_image_create_info.mipLevels = 1; + source_image_create_info.arrayLayers = 1; + source_image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; + source_image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; + source_image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT; + source_image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + source_image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + FfxApiResourceDescription source_desc = ffxApiGetImageResourceDescriptionVK( + input_image, source_image_create_info, FFX_API_RESOURCE_USAGE_READ_ONLY); + FfxApiResource source = ffxApiGetResourceVK(reinterpret_cast(input_image), source_desc, + FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ); + FfxApiResource depth = + ffxApiGetResourceVK(reinterpret_cast(input_image), + ffxApiGetImageResourceDescriptionVK(input_image, source_image_create_info, + FFX_API_RESOURCE_USAGE_DEPTHTARGET), + FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ); + FfxApiResource motion_vectors = source; + + VkImageCreateInfo output_image_create_info = source_image_create_info; + output_image_create_info.extent.width = output_width; + output_image_create_info.extent.height = output_height; + FfxApiResourceDescription output_desc = ffxApiGetImageResourceDescriptionVK( + output_image, output_image_create_info, + FFX_API_RESOURCE_USAGE_UAV | FFX_API_RESOURCE_USAGE_READ_ONLY); + FfxApiResource output = ffxApiGetResourceVK(reinterpret_cast(output_image), output_desc, + FFX_API_RESOURCE_STATE_UNORDERED_ACCESS); + + ffxDispatchDescUpscale dispatch_desc = {}; + dispatch_desc.header.type = FFX_API_DISPATCH_DESC_TYPE_UPSCALE; + dispatch_desc.header.pNext = nullptr; + dispatch_desc.commandList = command_buffer; + dispatch_desc.color = source; + dispatch_desc.depth = depth; + dispatch_desc.motionVectors = motion_vectors; + dispatch_desc.exposure = {}; + dispatch_desc.reactive = {}; + dispatch_desc.transparencyAndComposition = {}; + dispatch_desc.output = output; + dispatch_desc.jitterOffset.x = 0.0f; + dispatch_desc.jitterOffset.y = 0.0f; + dispatch_desc.motionVectorScale.x = float(input_width); + dispatch_desc.motionVectorScale.y = float(input_height); + dispatch_desc.renderSize.width = input_width; + dispatch_desc.renderSize.height = input_height; + dispatch_desc.upscaleSize.width = output_width; + dispatch_desc.upscaleSize.height = output_height; + dispatch_desc.enableSharpening = true; + dispatch_desc.sharpness = std::clamp(1.0f - config.GetFsrSharpnessReduction() * 0.5f, 0.0f, 1.0f); + dispatch_desc.reset = true; + dispatch_desc.frameTimeDelta = 16.666f; + dispatch_desc.preExposure = 1.0f; + dispatch_desc.cameraNear = 0.1f; + dispatch_desc.cameraFar = 1000.0f; + dispatch_desc.cameraFovAngleVertical = 1.0472f; + dispatch_desc.viewSpaceToMetersFactor = 1.0f; + dispatch_desc.flags = 0; + + ffxContext* context = reinterpret_cast(&temporal_upscaler_context_); + if (ffxDispatch(context, &dispatch_desc.header) != FFX_API_RETURN_OK) { + return false; + } + return true; +} +#endif + +Surface::TypeFlags VulkanPresenter::GetSurfaceTypesSupportedByInstance( + const VulkanInstance::Extensions& instance_extensions) { + if (!instance_extensions.ext_KHR_surface) { + return 0; + } + Surface::TypeFlags type_flags = 0; +#if REX_PLATFORM_ANDROID + if (instance_extensions.ext_KHR_android_surface) { + type_flags |= Surface::kTypeFlag_AndroidNativeWindow; + } +#endif +#if REX_PLATFORM_GNU_LINUX + if (instance_extensions.ext_KHR_xcb_surface) { + type_flags |= Surface::kTypeFlag_XcbWindow; + } +#endif +#if REX_PLATFORM_WIN32 + if (instance_extensions.ext_KHR_win32_surface) { + type_flags |= Surface::kTypeFlag_Win32Hwnd; + } +#endif + return type_flags; +} + +Surface::TypeFlags VulkanPresenter::GetSupportedSurfaceTypes() const { + if (!vulkan_device_->extensions().ext_KHR_swapchain) { + return 0; + } + return GetSurfaceTypesSupportedByInstance(vulkan_device_->vulkan_instance()->extensions()); +} + +bool VulkanPresenter::CaptureGuestOutput(RawImage& image_out) { + std::shared_ptr guest_output_image; + { + uint32_t guest_output_mailbox_index; + std::unique_lock guest_output_consumer_lock( + ConsumeGuestOutput(guest_output_mailbox_index, nullptr, nullptr)); + if (guest_output_mailbox_index != UINT32_MAX) { + assert_true(guest_output_images_[guest_output_mailbox_index].ever_successfully_refreshed); + guest_output_image = guest_output_images_[guest_output_mailbox_index].image; + } + // Incremented the reference count of the guest output image - safe to leave + // the consumer critical section now. + } + if (!guest_output_image) { + return false; + } + + VkExtent2D image_extent = guest_output_image->extent(); + size_t pixel_count = size_t(image_extent.width) * image_extent.height; + VkDeviceSize buffer_size = VkDeviceSize(sizeof(uint32_t) * pixel_count); + VkBuffer buffer; + VkDeviceMemory buffer_memory; + if (!util::CreateDedicatedAllocationBuffer( + vulkan_device_, buffer_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, + util::MemoryPurpose::kReadback, buffer, buffer_memory)) { + REXLOG_ERROR("VulkanPresenter: Failed to create the guest output capture buffer"); + return false; + } + + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + { + VkCommandPoolCreateInfo command_pool_create_info; + command_pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + command_pool_create_info.pNext = nullptr; + command_pool_create_info.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT; + command_pool_create_info.queueFamilyIndex = vulkan_device_->queue_family_graphics_compute(); + VkCommandPool command_pool; + if (dfn.vkCreateCommandPool(device, &command_pool_create_info, nullptr, &command_pool) != + VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to create the guest output capturing " + "command pool"); + dfn.vkDestroyBuffer(device, buffer, nullptr); + dfn.vkFreeMemory(device, buffer_memory, nullptr); + return false; + } + + VkCommandBufferAllocateInfo command_buffer_allocate_info; + command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + command_buffer_allocate_info.pNext = nullptr; + command_buffer_allocate_info.commandPool = command_pool; + command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + command_buffer_allocate_info.commandBufferCount = 1; + VkCommandBuffer command_buffer; + if (dfn.vkAllocateCommandBuffers(device, &command_buffer_allocate_info, &command_buffer) != + VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to allocate the guest output capturing " + "command buffer"); + dfn.vkDestroyCommandPool(device, command_pool, nullptr); + dfn.vkDestroyBuffer(device, buffer, nullptr); + dfn.vkFreeMemory(device, buffer_memory, nullptr); + return false; + } + + VkCommandBufferBeginInfo command_buffer_begin_info; + command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + command_buffer_begin_info.pNext = nullptr; + command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + command_buffer_begin_info.pInheritanceInfo = nullptr; + if (dfn.vkBeginCommandBuffer(command_buffer, &command_buffer_begin_info) != VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to begin recording the guest output " + "capturing command buffer"); + dfn.vkDestroyCommandPool(device, command_pool, nullptr); + dfn.vkDestroyBuffer(device, buffer, nullptr); + dfn.vkFreeMemory(device, buffer_memory, nullptr); + return false; + } + + VkImageMemoryBarrier image_memory_barrier; + image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + image_memory_barrier.pNext = nullptr; + image_memory_barrier.srcAccessMask = kGuestOutputInternalAccessMask; + image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + image_memory_barrier.oldLayout = kGuestOutputInternalLayout; + image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.image = guest_output_image->image(); + image_memory_barrier.subresourceRange = util::InitializeSubresourceRange(); + dfn.vkCmdPipelineBarrier(command_buffer, kGuestOutputInternalStageMask, + VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, + &image_memory_barrier); + + VkBufferImageCopy buffer_image_copy = {}; + buffer_image_copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + buffer_image_copy.imageSubresource.layerCount = 1; + buffer_image_copy.imageExtent.width = image_extent.width; + buffer_image_copy.imageExtent.height = image_extent.height; + buffer_image_copy.imageExtent.depth = 1; + dfn.vkCmdCopyImageToBuffer(command_buffer, guest_output_image->image(), + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, 1, &buffer_image_copy); + + // A fence doesn't guarantee host visibility and availability. + VkBufferMemoryBarrier buffer_memory_barrier; + buffer_memory_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; + buffer_memory_barrier.pNext = nullptr; + buffer_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + buffer_memory_barrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; + buffer_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + buffer_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + buffer_memory_barrier.buffer = buffer; + buffer_memory_barrier.offset = 0; + buffer_memory_barrier.size = VK_WHOLE_SIZE; + std::swap(image_memory_barrier.srcAccessMask, image_memory_barrier.dstAccessMask); + std::swap(image_memory_barrier.oldLayout, image_memory_barrier.newLayout); + dfn.vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_HOST_BIT | kGuestOutputInternalStageMask, 0, 0, + nullptr, 1, &buffer_memory_barrier, 1, &image_memory_barrier); + + if (dfn.vkEndCommandBuffer(command_buffer) != VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to end recording the guest output capturing " + "command buffer"); + dfn.vkDestroyCommandPool(device, command_pool, nullptr); + dfn.vkDestroyBuffer(device, buffer, nullptr); + dfn.vkFreeMemory(device, buffer_memory, nullptr); + return false; + } + + VkSubmitInfo submit_info = {}; + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = &command_buffer; + VulkanSubmissionTracker submission_tracker(vulkan_device_); + { + VulkanSubmissionTracker::FenceAcquisition fence_acqusition( + submission_tracker.AcquireFenceToAdvanceSubmission()); + if (!fence_acqusition.fence()) { + REXLOG_ERROR( + "VulkanPresenter: Failed to acquire a fence for guest output " + "capturing"); + fence_acqusition.SubmissionFailedOrDropped(); + dfn.vkDestroyCommandPool(device, command_pool, nullptr); + dfn.vkDestroyBuffer(device, buffer, nullptr); + dfn.vkFreeMemory(device, buffer_memory, nullptr); + return false; + } + VkResult submit_result; + { + const VulkanDevice::Queue::Acquisition queue_acquisition = + vulkan_device_->AcquireQueue(vulkan_device_->queue_family_graphics_compute(), 0); + submit_result = + dfn.vkQueueSubmit(queue_acquisition.queue(), 1, &submit_info, fence_acqusition.fence()); + } + if (submit_result != VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to submit the guest output capturing " + "command buffer"); + fence_acqusition.SubmissionFailedOrDropped(); + dfn.vkDestroyCommandPool(device, command_pool, nullptr); + dfn.vkDestroyBuffer(device, buffer, nullptr); + dfn.vkFreeMemory(device, buffer_memory, nullptr); + return false; + } + } + if (!submission_tracker.AwaitAllSubmissionsCompletion()) { + REXLOG_ERROR("VulkanPresenter: Failed to await the guest output capturing fence"); + dfn.vkDestroyCommandPool(device, command_pool, nullptr); + dfn.vkDestroyBuffer(device, buffer, nullptr); + dfn.vkFreeMemory(device, buffer_memory, nullptr); + return false; + } + + dfn.vkDestroyCommandPool(device, command_pool, nullptr); + } + + // Don't need the buffer anymore, just its memory. + dfn.vkDestroyBuffer(device, buffer, nullptr); + + void* mapping; + if (dfn.vkMapMemory(device, buffer_memory, 0, VK_WHOLE_SIZE, 0, &mapping) != VK_SUCCESS) { + REXLOG_ERROR("VulkanPresenter: Failed to map the guest output capture memory"); + dfn.vkFreeMemory(device, buffer_memory, nullptr); + return false; + } + + image_out.width = image_extent.width; + image_out.height = image_extent.height; + image_out.stride = sizeof(uint32_t) * image_extent.width; + image_out.data.resize(size_t(buffer_size)); + uint32_t* image_out_pixels = reinterpret_cast(image_out.data.data()); + for (size_t i = 0; i < pixel_count; ++i) { + image_out_pixels[i] = Packed10bpcRGBTo8bpcBytes(reinterpret_cast(mapping)[i]); + } + + // Unmapping will be done by freeing. + dfn.vkFreeMemory(device, buffer_memory, nullptr); + + return true; +} + +VkCommandBuffer VulkanPresenter::AcquireUISetupCommandBufferFromUIThread() { + if (paint_context_.ui_setup_command_buffer_current_index != SIZE_MAX) { + return paint_context_ + .ui_setup_command_buffers[paint_context_.ui_setup_command_buffer_current_index] + .command_buffer; + } + + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + VkCommandBufferBeginInfo command_buffer_begin_info; + command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + command_buffer_begin_info.pNext = nullptr; + command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + command_buffer_begin_info.pInheritanceInfo = nullptr; + + // Try to reuse an existing command buffer. + if (!paint_context_.ui_setup_command_buffers.empty()) { + uint64_t submission_index_completed = ui_submission_tracker_.UpdateAndGetCompletedSubmission(); + for (size_t i = 0; i < paint_context_.ui_setup_command_buffers.size(); ++i) { + PaintContext::UISetupCommandBuffer& ui_setup_command_buffer = + paint_context_.ui_setup_command_buffers[i]; + if (ui_setup_command_buffer.last_usage_submission_index > submission_index_completed) { + continue; + } + if (dfn.vkResetCommandPool(device, ui_setup_command_buffer.command_pool, 0) != VK_SUCCESS) { + REXLOG_ERROR("VulkanPresenter: Failed to reset a UI setup command pool"); + return VK_NULL_HANDLE; + } + if (dfn.vkBeginCommandBuffer(ui_setup_command_buffer.command_buffer, + &command_buffer_begin_info) != VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to begin UI setup command buffer " + "recording"); + return VK_NULL_HANDLE; + } + paint_context_.ui_setup_command_buffer_current_index = i; + ui_setup_command_buffer.last_usage_submission_index = + ui_submission_tracker_.GetCurrentSubmission(); + return ui_setup_command_buffer.command_buffer; + } + } + + // Create a new command buffer. + VkCommandPoolCreateInfo command_pool_create_info; + command_pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + command_pool_create_info.pNext = nullptr; + command_pool_create_info.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT; + command_pool_create_info.queueFamilyIndex = vulkan_device_->queue_family_graphics_compute(); + VkCommandPool new_command_pool; + if (dfn.vkCreateCommandPool(device, &command_pool_create_info, nullptr, &new_command_pool) != + VK_SUCCESS) { + REXLOG_ERROR("VulkanPresenter: Failed to create a UI setup command pool"); + return VK_NULL_HANDLE; + } + VkCommandBufferAllocateInfo command_buffer_allocate_info; + command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + command_buffer_allocate_info.pNext = nullptr; + command_buffer_allocate_info.commandPool = new_command_pool; + command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + command_buffer_allocate_info.commandBufferCount = 1; + VkCommandBuffer new_command_buffer; + if (dfn.vkAllocateCommandBuffers(device, &command_buffer_allocate_info, &new_command_buffer) != + VK_SUCCESS) { + REXLOG_ERROR("VulkanPresenter: Failed to allocate a UI setup command buffer"); + dfn.vkDestroyCommandPool(device, new_command_pool, nullptr); + return VK_NULL_HANDLE; + } + if (dfn.vkBeginCommandBuffer(new_command_buffer, &command_buffer_begin_info) != VK_SUCCESS) { + REXLOG_ERROR("VulkanPresenter: Failed to begin UI setup command buffer recording"); + dfn.vkDestroyCommandPool(device, new_command_pool, nullptr); + return VK_NULL_HANDLE; + } + paint_context_.ui_setup_command_buffer_current_index = + paint_context_.ui_setup_command_buffers.size(); + paint_context_.ui_setup_command_buffers.emplace_back( + new_command_pool, new_command_buffer, ui_submission_tracker_.GetCurrentSubmission()); + return new_command_buffer; +} + +Presenter::SurfacePaintConnectResult +VulkanPresenter::ConnectOrReconnectPaintingToSurfaceFromUIThread(Surface& new_surface, + uint32_t new_surface_width, + uint32_t new_surface_height, + bool was_paintable, + bool& is_vsync_implicit_out) { + const VulkanInstance* const vulkan_instance = vulkan_device_->vulkan_instance(); + const VulkanInstance::Functions& ifn = vulkan_instance->functions(); + const VkInstance instance = vulkan_instance->instance(); + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + VkFormat new_swapchain_format; + + // ConnectOrReconnectToSurfaceFromUIThread may be called only for the + // ui::Surface of the current swapchain or when the old swapchain and + // VkSurface have, if the ui::Surface is the same, try using the existing + // VkSurface and creating the swapchain smoothly from the existing one - if + // this doesn't succeed, start from scratch. + // The retirement or destruction of the swapchain here will also cause + // awaiting completion of the usage of the swapchain and the surface on the + // GPU. + if (paint_context_.vulkan_surface != VK_NULL_HANDLE) { + VkSwapchainKHR old_swapchain = paint_context_.PrepareForSwapchainRetirement(); + bool surface_unusable; + paint_context_.swapchain = PaintContext::CreateSwapchainForVulkanSurface( + vulkan_device_, paint_context_.vulkan_surface, new_surface_width, new_surface_height, + old_swapchain, paint_context_.present_queue_family, new_swapchain_format, + paint_context_.swapchain_extent, paint_context_.swapchain_is_fifo, surface_unusable); + // Destroy the old swapchain that may be retired now. + if (old_swapchain != VK_NULL_HANDLE) { + dfn.vkDestroySwapchainKHR(device, old_swapchain, nullptr); + } + if (paint_context_.swapchain == VK_NULL_HANDLE) { + // Couldn't create the swapchain for the existing surface - start over. + paint_context_.DestroySwapchainAndVulkanSurface(); + } + } + + // If failed to create the swapchain for the previous surface, recreate the + // surface and create the new swapchain. + if (paint_context_.swapchain == VK_NULL_HANDLE) { + // DestroySwapchainAndVulkanSurface should have been called previously. + assert_true(paint_context_.vulkan_surface == VK_NULL_HANDLE); + Surface::TypeIndex surface_type = new_surface.GetType(); + // Check if the surface type is supported according to the Vulkan + // extensions. + if (!(GetSupportedSurfaceTypes() & (Surface::TypeFlags(1) << surface_type))) { + REXLOG_ERROR( + "VulkanPresenter: Tried to create a Vulkan surface for an " + "unsupported Xenia surface type"); + return SurfacePaintConnectResult::kFailureSurfaceUnusable; + } + VkResult vulkan_surface_create_result = VK_ERROR_UNKNOWN; + switch (surface_type) { +#if REX_PLATFORM_ANDROID + case Surface::kTypeIndex_AndroidNativeWindow: { + auto& android_native_window_surface = + static_cast(new_surface); + VkAndroidSurfaceCreateInfoKHR surface_create_info; + surface_create_info.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; + surface_create_info.pNext = nullptr; + surface_create_info.flags = 0; + surface_create_info.window = android_native_window_surface.window(); + vulkan_surface_create_result = ifn.vkCreateAndroidSurfaceKHR( + instance, &surface_create_info, nullptr, &paint_context_.vulkan_surface); + } break; +#endif +#if REX_PLATFORM_GNU_LINUX + case Surface::kTypeIndex_XcbWindow: { + auto& xcb_window_surface = static_cast(new_surface); + VkXcbSurfaceCreateInfoKHR surface_create_info; + surface_create_info.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; + surface_create_info.pNext = nullptr; + surface_create_info.flags = 0; + surface_create_info.connection = xcb_window_surface.connection(); + surface_create_info.window = xcb_window_surface.window(); + vulkan_surface_create_result = ifn.vkCreateXcbSurfaceKHR( + instance, &surface_create_info, nullptr, &paint_context_.vulkan_surface); + } break; +#endif +#if REX_PLATFORM_WIN32 + case Surface::kTypeIndex_Win32Hwnd: { + auto& win32_hwnd_surface = static_cast(new_surface); + VkWin32SurfaceCreateInfoKHR surface_create_info; + surface_create_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + surface_create_info.pNext = nullptr; + surface_create_info.flags = 0; + surface_create_info.hinstance = win32_hwnd_surface.hinstance(); + surface_create_info.hwnd = win32_hwnd_surface.hwnd(); + vulkan_surface_create_result = ifn.vkCreateWin32SurfaceKHR( + instance, &surface_create_info, nullptr, &paint_context_.vulkan_surface); + } break; +#endif + default: + assert_unhandled_case(surface_type); + REXLOG_ERROR( + "VulkanPresenter: Tried to create a Vulkan surface for an " + "unknown Xenia surface type"); + return SurfacePaintConnectResult::kFailureSurfaceUnusable; + } + if (vulkan_surface_create_result != VK_SUCCESS) { + REXLOG_ERROR("VulkanPresenter: Failed to create a Vulkan surface"); + return SurfacePaintConnectResult::kFailure; + } + bool surface_unusable; + paint_context_.swapchain = PaintContext::CreateSwapchainForVulkanSurface( + vulkan_device_, paint_context_.vulkan_surface, new_surface_width, new_surface_height, + VK_NULL_HANDLE, paint_context_.present_queue_family, new_swapchain_format, + paint_context_.swapchain_extent, paint_context_.swapchain_is_fifo, surface_unusable); + if (paint_context_.swapchain == VK_NULL_HANDLE) { + // Failed to create the swapchain for the new Vulkan surface - destroy the + // Vulkan surface. + ifn.vkDestroySurfaceKHR(instance, paint_context_.vulkan_surface, nullptr); + paint_context_.vulkan_surface = VK_NULL_HANDLE; + return surface_unusable ? SurfacePaintConnectResult::kFailureSurfaceUnusable + : SurfacePaintConnectResult::kFailure; + } + // Successfully attached (at least for now). + } + + // From now on, in case of failure, + // paint_context_.DestroySwapchainAndVulkanSurface must be called before + // returning. + + // Update the render pass to the new format. + if (paint_context_.swapchain_render_pass_format != new_swapchain_format) { + util::DestroyAndNullHandle(dfn.vkDestroyRenderPass, device, + paint_context_.swapchain_render_pass); + paint_context_.swapchain_render_pass_format = new_swapchain_format; + } + if (paint_context_.swapchain_render_pass == VK_NULL_HANDLE) { + VkAttachmentDescription render_pass_attachment; + render_pass_attachment.flags = 0; + render_pass_attachment.format = new_swapchain_format; + render_pass_attachment.samples = VK_SAMPLE_COUNT_1_BIT; + render_pass_attachment.loadOp = REXCVAR_GET(present_render_pass_clear) + ? VK_ATTACHMENT_LOAD_OP_CLEAR + : VK_ATTACHMENT_LOAD_OP_DONT_CARE; + render_pass_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + render_pass_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + render_pass_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + render_pass_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + render_pass_attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + VkAttachmentReference render_pass_color_attachment; + render_pass_color_attachment.attachment = 0; + render_pass_color_attachment.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + VkSubpassDescription render_pass_subpass = {}; + render_pass_subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + render_pass_subpass.colorAttachmentCount = 1; + render_pass_subpass.pColorAttachments = &render_pass_color_attachment; + VkSubpassDependency render_pass_dependencies[2]; + render_pass_dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL; + render_pass_dependencies[0].dstSubpass = 0; + // srcStageMask is the semaphore wait stage. + render_pass_dependencies[0].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + render_pass_dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + render_pass_dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT; + // The main target can be used for UI drawing at any moment, which requires + // blending, so VK_ACCESS_COLOR_ATTACHMENT_READ_BIT is also included. + render_pass_dependencies[0].dstAccessMask = + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + render_pass_dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; + render_pass_dependencies[1].srcSubpass = 0; + render_pass_dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL; + render_pass_dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + // Semaphores are signaled at VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT. + render_pass_dependencies[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + render_pass_dependencies[1].srcAccessMask = + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + render_pass_dependencies[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; + render_pass_dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; + VkRenderPassCreateInfo render_pass_create_info; + render_pass_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + render_pass_create_info.pNext = nullptr; + render_pass_create_info.flags = 0; + render_pass_create_info.attachmentCount = 1; + render_pass_create_info.pAttachments = &render_pass_attachment; + render_pass_create_info.subpassCount = 1; + render_pass_create_info.pSubpasses = &render_pass_subpass; + render_pass_create_info.dependencyCount = uint32_t(rex::countof(render_pass_dependencies)); + render_pass_create_info.pDependencies = render_pass_dependencies; + VkRenderPass new_render_pass; + if (dfn.vkCreateRenderPass(device, &render_pass_create_info, nullptr, &new_render_pass) != + VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to create the render pass for drawing to " + "swapchain images"); + paint_context_.DestroySwapchainAndVulkanSurface(); + return SurfacePaintConnectResult::kFailure; + } + paint_context_.swapchain_render_pass = new_render_pass; + paint_context_.swapchain_render_pass_format = new_swapchain_format; + paint_context_.swapchain_render_pass_clear_load_op = + render_pass_attachment.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR; + } + + // Get the swapchain images. + paint_context_.swapchain_images.clear(); + VkResult swapchain_images_get_result; + for (;;) { + uint32_t swapchain_image_count = uint32_t(paint_context_.swapchain_images.size()); + bool swapchain_images_were_empty = !swapchain_image_count; + swapchain_images_get_result = dfn.vkGetSwapchainImagesKHR( + device, paint_context_.swapchain, &swapchain_image_count, + swapchain_images_were_empty ? nullptr : paint_context_.swapchain_images.data()); + // If the original swapchain image count was 0 (first call), SUCCESS is + // returned, not INCOMPLETE. + if (swapchain_images_get_result == VK_SUCCESS || swapchain_images_get_result == VK_INCOMPLETE) { + paint_context_.swapchain_images.resize(swapchain_image_count); + if (swapchain_images_get_result == VK_SUCCESS && + (!swapchain_images_were_empty || !swapchain_image_count)) { + break; + } + } else { + break; + } + } + if (swapchain_images_get_result != VK_SUCCESS) { + REXLOG_ERROR("VulkanPresenter: Failed to get swapchain images"); + paint_context_.DestroySwapchainAndVulkanSurface(); + return SurfacePaintConnectResult::kFailure; + } + + // Create the image views and the framebuffers. + assert_true(paint_context_.swapchain_framebuffers.empty()); + paint_context_.swapchain_framebuffers.reserve(paint_context_.swapchain_images.size()); + VkImageViewCreateInfo image_view_create_info; + image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + image_view_create_info.pNext = nullptr; + image_view_create_info.flags = 0; + image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; + image_view_create_info.format = new_swapchain_format; + image_view_create_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + image_view_create_info.subresourceRange.baseMipLevel = 0; + image_view_create_info.subresourceRange.levelCount = 1; + image_view_create_info.subresourceRange.baseArrayLayer = 0; + image_view_create_info.subresourceRange.layerCount = 1; + VkImageView image_view; + VkFramebufferCreateInfo framebuffer_create_info; + framebuffer_create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + framebuffer_create_info.pNext = nullptr; + framebuffer_create_info.flags = 0; + framebuffer_create_info.renderPass = paint_context_.swapchain_render_pass; + framebuffer_create_info.attachmentCount = 1; + framebuffer_create_info.pAttachments = &image_view; + framebuffer_create_info.width = paint_context_.swapchain_extent.width; + framebuffer_create_info.height = paint_context_.swapchain_extent.height; + framebuffer_create_info.layers = 1; + for (VkImage image : paint_context_.swapchain_images) { + image_view_create_info.image = image; + if (dfn.vkCreateImageView(device, &image_view_create_info, nullptr, &image_view) != + VK_SUCCESS) { + REXLOG_ERROR("VulkanPresenter: Failed to create a swapchain image view"); + paint_context_.DestroySwapchainAndVulkanSurface(); + return SurfacePaintConnectResult::kFailure; + } + VkFramebuffer framebuffer; + if (dfn.vkCreateFramebuffer(device, &framebuffer_create_info, nullptr, &framebuffer) != + VK_SUCCESS) { + REXLOG_ERROR("VulkanPresenter: Failed to create a swapchain framebuffer"); + dfn.vkDestroyImageView(device, image_view, nullptr); + paint_context_.DestroySwapchainAndVulkanSurface(); + return SurfacePaintConnectResult::kFailure; + } + paint_context_.swapchain_framebuffers.emplace_back(image_view, framebuffer); + } + + is_vsync_implicit_out = paint_context_.swapchain_is_fifo; + return SurfacePaintConnectResult::kSuccess; +} + +void VulkanPresenter::DisconnectPaintingFromSurfaceFromUIThreadImpl() { + paint_context_.DestroySwapchainAndVulkanSurface(); +} + +bool VulkanPresenter::RefreshGuestOutputImpl( + uint32_t mailbox_index, uint32_t frontbuffer_width, uint32_t frontbuffer_height, + std::function refresher, bool& is_8bpc_out_ref) { + assert_not_zero(frontbuffer_width); + assert_not_zero(frontbuffer_height); + VkExtent2D max_framebuffer_extent = util::GetMax2DFramebufferExtent(vulkan_device_->properties()); + if (frontbuffer_width > max_framebuffer_extent.width || + frontbuffer_height > max_framebuffer_extent.height) { + // Writing the guest output isn't supposed to rescale, and a guest texture + // exceeding the maximum size won't be loadable anyway. + return false; + } + + GuestOutputImageInstance& image_instance = guest_output_images_[mailbox_index]; + if (image_instance.image && (image_instance.image->extent().width != frontbuffer_width || + image_instance.image->extent().height != frontbuffer_height)) { + guest_output_image_refresher_submission_tracker_.AwaitSubmissionCompletion( + image_instance.last_refresher_submission); + image_instance.image.reset(); + } + if (!image_instance.image) { + std::unique_ptr new_image = + GuestOutputImage::Create(vulkan_device_, frontbuffer_width, frontbuffer_height); + if (!new_image) { + return false; + } + image_instance.SetToNewImage(std::move(new_image), guest_output_image_next_version_++); + } + + VulkanGuestOutputRefreshContext context(is_8bpc_out_ref, image_instance.image->image(), + image_instance.image->view(), image_instance.version, + image_instance.ever_successfully_refreshed); + bool refresher_succeeded = refresher(context); + if (refresher_succeeded) { + image_instance.ever_successfully_refreshed = true; + } + // Even if the refresher has returned false, it still might have submitted + // some commands referencing the image. It's better to put an excessive + // signal and wait slightly longer, for nothing important, while shutting down + // than to destroy the image while it's still in use. + image_instance.last_refresher_submission = + guest_output_image_refresher_submission_tracker_.GetCurrentSubmission(); + // No need to make the refresher signal the fence by itself - signal it here + // instead to have more control: + // "Fence signal operations that are defined by vkQueueSubmit additionally + // include in the first synchronization scope all commands that occur earlier + // in submission order." + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + { + VulkanSubmissionTracker::FenceAcquisition fence_acqusition( + guest_output_image_refresher_submission_tracker_.AcquireFenceToAdvanceSubmission()); + const VulkanDevice::Queue::Acquisition queue_acquisition = + vulkan_device_->AcquireQueue(vulkan_device_->queue_family_graphics_compute(), 0); + if (dfn.vkQueueSubmit(queue_acquisition.queue(), 0, nullptr, fence_acqusition.fence()) != + VK_SUCCESS) { + fence_acqusition.SubmissionSucceededSignalFailed(); + } + } + + return refresher_succeeded; +} + +VkSwapchainKHR VulkanPresenter::PaintContext::CreateSwapchainForVulkanSurface( + const VulkanDevice* vulkan_device, VkSurfaceKHR surface, uint32_t width, uint32_t height, + VkSwapchainKHR old_swapchain, uint32_t& present_queue_family_out, VkFormat& image_format_out, + VkExtent2D& image_extent_out, bool& is_fifo_out, bool& ui_surface_unusable_out) { + ui_surface_unusable_out = false; + + const VulkanInstance::Functions& ifn = vulkan_device->vulkan_instance()->functions(); + const VkPhysicalDevice physical_device = vulkan_device->physical_device(); + const VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + // Get surface capabilities. + VkSurfaceCapabilitiesKHR surface_capabilities; + if (ifn.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, surface, + &surface_capabilities) != VK_SUCCESS) { + REXLOG_ERROR("VulkanPresenter: Failed to get Vulkan surface capabilities"); + // Some strange error, try again later. + return VK_NULL_HANDLE; + } + + // First, check if the surface is not zero-area because in this case, the rest + // of the fields in theory may not be informative as the surface doesn't need + // to go to presentation anyway, thus there's no need to return real + // information, and ui_surface_unusable_out (from which it may not be possible + // to recover on certain platforms at all) may be set to true spuriously if + // any checks set it to true. VkSurfaceKHR may have zero-area bounds in some + // window state cases on Windows, for example. Also clamp the requested size + // to the maximum supported by the physical device as long as minImageExtent + // in the instance's WSI allows that (if not, there's no way to satisfy both + // requirements - the maximum 2D framebuffer size on the specific physical + // device, and the minimum swap chain size on the whole instance - fail to + // create until the surface becomes smaller). + VkExtent2D max_framebuffer_extent = util::GetMax2DFramebufferExtent(vulkan_device->properties()); + VkExtent2D image_extent; + image_extent.width = std::min(std::max(std::min(width, max_framebuffer_extent.width), + surface_capabilities.minImageExtent.width), + surface_capabilities.maxImageExtent.width); + image_extent.height = std::min(std::max(std::min(height, max_framebuffer_extent.height), + surface_capabilities.minImageExtent.height), + surface_capabilities.maxImageExtent.height); + if (!image_extent.width || !image_extent.height || + image_extent.width > max_framebuffer_extent.width || + image_extent.height > max_framebuffer_extent.height) { + return VK_NULL_HANDLE; + } + + // Get the queue family for presentation. + uint32_t queue_family_index_present = UINT32_MAX; + const std::vector& queue_families = vulkan_device->queue_families(); + VkBool32 queue_family_present_supported; + // First try the graphics and compute queue, prefer it to avoid the concurrent + // image sharing mode. + uint32_t queue_family_index_graphics_compute = vulkan_device->queue_family_graphics_compute(); + const VulkanDevice::QueueFamily& queue_family_graphics_compute = + queue_families[queue_family_index_graphics_compute]; + if (queue_family_graphics_compute.may_support_presentation && + !queue_family_graphics_compute.queues.empty() && + ifn.vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, queue_family_index_graphics_compute, + surface, + &queue_family_present_supported) == VK_SUCCESS && + queue_family_present_supported) { + queue_family_index_present = queue_family_index_graphics_compute; + } else { + for (uint32_t i = 0; i < uint32_t(queue_families.size()); ++i) { + const VulkanDevice::QueueFamily& queue_family = queue_families[i]; + if (!queue_family.queues.empty() && queue_family.may_support_presentation && + ifn.vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, i, surface, + &queue_family_present_supported) == VK_SUCCESS && + queue_family_present_supported) { + queue_family_index_present = i; + break; + } + } + } + if (queue_family_index_present == UINT32_MAX) { + // Not unusable though - may become presentable if the window (with the same + // surface) moved to a different display, for instance. + return VK_NULL_HANDLE; + } + + // TODO(Triang3l): Support transforms. + if (!(surface_capabilities.supportedTransforms & + (VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR | VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR))) { + REXLOG_ERROR( + "VulkanPresenter: The surface doesn't support identity or " + "window-system-controlled transform"); + return VK_NULL_HANDLE; + } + + // Get the surface format. + std::vector surface_formats; + VkResult surface_formats_get_result; + for (;;) { + uint32_t surface_format_count = uint32_t(surface_formats.size()); + bool surface_formats_were_empty = !surface_format_count; + surface_formats_get_result = ifn.vkGetPhysicalDeviceSurfaceFormatsKHR( + physical_device, surface, &surface_format_count, + surface_formats_were_empty ? nullptr : surface_formats.data()); + // If the original presentation mode count was 0 (first call), SUCCESS is + // returned, not INCOMPLETE. + if (surface_formats_get_result == VK_SUCCESS || surface_formats_get_result == VK_INCOMPLETE) { + surface_formats.resize(surface_format_count); + if (surface_formats_get_result == VK_SUCCESS && + (!surface_formats_were_empty || !surface_format_count)) { + break; + } + } else { + break; + } + } + if (surface_formats_get_result != VK_SUCCESS) { + // Assuming any format in case of an error (or as some fallback in case of + // specification violation). + surface_formats.clear(); + } +#if REX_PLATFORM_ANDROID + // Android uses R8G8B8A8. + static const VkFormat kFormat8888Primary = VK_FORMAT_R8G8B8A8_UNORM; + static const VkFormat kFormat8888Secondary = VK_FORMAT_B8G8R8A8_UNORM; +#else + // GNU/Linux X11 and Windows DWM use B8G8R8A8. + static const VkFormat kFormat8888Primary = VK_FORMAT_B8G8R8A8_UNORM; + static const VkFormat kFormat8888Secondary = VK_FORMAT_R8G8B8A8_UNORM; +#endif + VkSurfaceFormatKHR image_format; + if (surface_formats.empty() || + (surface_formats.size() == 1 || surface_formats[0].format == VK_FORMAT_UNDEFINED)) { + // Can choose any format if the implementation specifies only UNDEFINED. + image_format.format = kFormat8888Primary; + image_format.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; + } else { + // Pick the sRGB 8888 format preferred by the OS, fall back to any sRGB + // 8888, then to 8888 with an unknown color space, and then to the first + // sRGB available, and then to the first. + auto format_8888_primary_it = surface_formats.cend(); + auto format_8888_secondary_it = surface_formats.cend(); + auto any_non_8888_srgb_it = surface_formats.cend(); + for (auto it = surface_formats.cbegin(); it != surface_formats.cend(); ++it) { + if (it->format != kFormat8888Primary && it->format != kFormat8888Secondary) { + if (it->colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR && + any_non_8888_srgb_it == surface_formats.cend()) { + any_non_8888_srgb_it = it; + } + continue; + } + auto& preferred_8888_it = + it->format == kFormat8888Primary ? format_8888_primary_it : format_8888_secondary_it; + if (preferred_8888_it == surface_formats.cend()) { + // First primary or secondary 8888 encounter. + preferred_8888_it = it; + continue; + } + // Is this a better primary or secondary 8888, that is, this is sRGB, + // while the previous encounter was not? + if (it->colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR && + preferred_8888_it->colorSpace != VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { + preferred_8888_it = it; + } + } + if (format_8888_primary_it != surface_formats.cend() && + format_8888_secondary_it != surface_formats.cend()) { + // Both the primary and the secondary 8888 formats are available - prefer + // sRGB, if both are sRGB or not, prefer the primary format. + if (format_8888_primary_it->colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR || + format_8888_secondary_it->colorSpace != VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { + image_format = *format_8888_primary_it; + } else { + image_format = *format_8888_secondary_it; + } + } else if (format_8888_primary_it != surface_formats.cend()) { + // Only primary 8888. + image_format = *format_8888_primary_it; + } else if (format_8888_secondary_it != surface_formats.cend()) { + // Only secondary 8888. + image_format = *format_8888_secondary_it; + } else if (any_non_8888_srgb_it != surface_formats.cend()) { + // No 8888, but some sRGB format is available. + image_format = *any_non_8888_srgb_it; + } else { + // Just pick any format. + image_format = surface_formats.front(); + } + } + + // Get presentation modes. + std::vector present_modes; + VkResult present_modes_get_result; + for (;;) { + uint32_t present_mode_count = uint32_t(present_modes.size()); + bool present_modes_were_empty = !present_mode_count; + present_modes_get_result = ifn.vkGetPhysicalDeviceSurfacePresentModesKHR( + physical_device, surface, &present_mode_count, + present_modes_were_empty ? nullptr : present_modes.data()); + // If the original presentation mode count was 0 (first call), SUCCESS is + // returned, not INCOMPLETE. + if (present_modes_get_result == VK_SUCCESS || present_modes_get_result == VK_INCOMPLETE) { + present_modes.resize(present_mode_count); + if (present_modes_get_result == VK_SUCCESS && + (!present_modes_were_empty || !present_mode_count)) { + break; + } + } else { + break; + } + } + if (present_modes_get_result != VK_SUCCESS) { + // Assuming FIFO only (required everywhere) in case of an error. + present_modes.clear(); + } + + // Create the swapchain. + VkSwapchainCreateInfoKHR swapchain_create_info; + swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + swapchain_create_info.pNext = nullptr; + swapchain_create_info.flags = 0; + swapchain_create_info.surface = surface; + swapchain_create_info.minImageCount = + std::max(kSubmissionCount, surface_capabilities.minImageCount); + if (surface_capabilities.maxImageCount) { + swapchain_create_info.minImageCount = + std::min(swapchain_create_info.minImageCount, surface_capabilities.maxImageCount); + } + swapchain_create_info.imageFormat = image_format.format; + swapchain_create_info.imageColorSpace = image_format.colorSpace; + swapchain_create_info.imageExtent = image_extent; + swapchain_create_info.imageArrayLayers = 1; + swapchain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + uint32_t swapchain_queue_family_indices[2]; + if (queue_family_index_graphics_compute != queue_family_index_present) { + // Using concurrent sharing mode to avoid an explicit ownership transfer + // before presenting, which would require an additional command buffer + // submission with the acquire barrier and a semaphore between the graphics + // queue and the present queue. Different queues are an extremely rare case, + // and Xenia only uses the swapchain for the final guest output and the + // internal UI, so keeping framebuffer compression is not worth the + // additional submission complexity and possibly latency. + swapchain_queue_family_indices[0] = queue_family_index_graphics_compute; + swapchain_queue_family_indices[1] = queue_family_index_present; + swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT; + swapchain_create_info.queueFamilyIndexCount = 2; + swapchain_create_info.pQueueFamilyIndices = swapchain_queue_family_indices; + } else { + swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + swapchain_create_info.queueFamilyIndexCount = 0; + swapchain_create_info.pQueueFamilyIndices = nullptr; + } + swapchain_create_info.preTransform = + (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) + ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR + : VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR; + // Prefer opaque to avoid blending in the window system, or let that be + // specified via the window system if it can't be forced. As a last resort, + // just pick any - guest output will write alpha of 1 anyway. + if (surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) { + swapchain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + } else if (surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) { + swapchain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR; + } else { + uint32_t composite_alpha_shift; + if (!rex::bit_scan_forward(uint32_t(surface_capabilities.supportedCompositeAlpha), + &composite_alpha_shift)) { + // Against the Vulkan specification, but breaks the logic here. + REXLOG_ERROR( + "VulkanPresenter: The surface doesn't support any composite alpha " + "mode"); + return VK_NULL_HANDLE; + } + swapchain_create_info.compositeAlpha = + VkCompositeAlphaFlagBitsKHR(uint32_t(1) << composite_alpha_shift); + } + // As presentation is usually controlled by the GPU command processor, it's + // better to use modes that allow as quick acquisition as possible to avoid + // interfering with GPU command processing, and also to allow tearing so + // variable refresh rate may be used where it's available. + // Note: If the priorities here are changes, update the cvar descriptions. + if (REXCVAR_GET(vulkan_allow_present_mode_immediate) && + std::find(present_modes.cbegin(), present_modes.cend(), VK_PRESENT_MODE_IMMEDIATE_KHR) != + present_modes.cend()) { + // Allowing tearing to reduce latency, and possibly variable refresh rate + // (though on Windows with borderless fullscreen, GDI copying is used + // instead of independent flip, so it's not supported there). + swapchain_create_info.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; + } else if (REXCVAR_GET(vulkan_allow_present_mode_mailbox) && + std::find(present_modes.cbegin(), present_modes.cend(), VK_PRESENT_MODE_MAILBOX_KHR) != + present_modes.cend()) { + // Allowing dropping frames to reduce latency, but no tearing. + swapchain_create_info.presentMode = VK_PRESENT_MODE_MAILBOX_KHR; + } else if (REXCVAR_GET(vulkan_allow_present_mode_fifo_relaxed) && + std::find(present_modes.cbegin(), present_modes.cend(), + VK_PRESENT_MODE_FIFO_RELAXED_KHR) != present_modes.cend()) { + // Limiting the frame rate, but lets too long frames cause tearing not to + // make the latency even worse. + swapchain_create_info.presentMode = VK_PRESENT_MODE_FIFO_RELAXED_KHR; + } else { + // Highest latency (but always guaranteed to be available). + swapchain_create_info.presentMode = VK_PRESENT_MODE_FIFO_KHR; + } + swapchain_create_info.clipped = VK_TRUE; + swapchain_create_info.oldSwapchain = old_swapchain; + VkSwapchainKHR swapchain; + if (dfn.vkCreateSwapchainKHR(device, &swapchain_create_info, nullptr, &swapchain) != VK_SUCCESS) { + REXLOG_ERROR("VulkanPresenter: Failed to create a swapchain"); + return VK_NULL_HANDLE; + } + REXLOG_INFO( + "VulkanPresenter: Created {}x{} swapchain with format {}, color space " + "{}, presentation mode {}", + swapchain_create_info.imageExtent.width, swapchain_create_info.imageExtent.height, + uint32_t(swapchain_create_info.imageFormat), uint32_t(swapchain_create_info.imageColorSpace), + uint32_t(swapchain_create_info.presentMode)); + + present_queue_family_out = queue_family_index_present; + image_format_out = swapchain_create_info.imageFormat; + image_extent_out = swapchain_create_info.imageExtent; + is_fifo_out = swapchain_create_info.presentMode == VK_PRESENT_MODE_FIFO_KHR || + swapchain_create_info.presentMode == VK_PRESENT_MODE_FIFO_RELAXED_KHR; + return swapchain; +} + +VkSwapchainKHR VulkanPresenter::PaintContext::PrepareForSwapchainRetirement() { + if (swapchain != VK_NULL_HANDLE) { + submission_tracker.AwaitAllSubmissionsCompletion(); + } + const VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + for (const SwapchainFramebuffer& framebuffer : swapchain_framebuffers) { + dfn.vkDestroyFramebuffer(device, framebuffer.framebuffer, nullptr); + dfn.vkDestroyImageView(device, framebuffer.image_view, nullptr); + } + swapchain_framebuffers.clear(); + swapchain_images.clear(); + swapchain_extent.width = 0; + swapchain_extent.height = 0; + // The old swapchain must be destroyed externally. + VkSwapchainKHR old_swapchain = swapchain; + swapchain = nullptr; + return old_swapchain; +} + +void VulkanPresenter::PaintContext::DestroySwapchainAndVulkanSurface() { + VkSwapchainKHR old_swapchain = PrepareForSwapchainRetirement(); + if (old_swapchain != VK_NULL_HANDLE) { + vulkan_device->functions().vkDestroySwapchainKHR(vulkan_device->device(), old_swapchain, + nullptr); + } + present_queue_family = UINT32_MAX; + if (vulkan_surface != VK_NULL_HANDLE) { + const VulkanInstance* vulkan_instance = vulkan_device->vulkan_instance(); + vulkan_instance->functions().vkDestroySurfaceKHR(vulkan_instance->instance(), vulkan_surface, + nullptr); + vulkan_surface = VK_NULL_HANDLE; + } +} + +VulkanPresenter::GuestOutputImage::~GuestOutputImage() { + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + if (view_ != VK_NULL_HANDLE) { + dfn.vkDestroyImageView(device, view_, nullptr); + } + if (image_ != VK_NULL_HANDLE) { + dfn.vkDestroyImage(device, image_, nullptr); + } + if (memory_ != VK_NULL_HANDLE) { + dfn.vkFreeMemory(device, memory_, nullptr); + } +} + +bool VulkanPresenter::GuestOutputImage::Initialize() { + VkImageCreateInfo image_create_info; + image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + image_create_info.pNext = nullptr; + image_create_info.flags = 0; + image_create_info.imageType = VK_IMAGE_TYPE_2D; + image_create_info.format = kGuestOutputFormat; + image_create_info.extent.width = extent_.width; + image_create_info.extent.height = extent_.height; + image_create_info.extent.depth = 1; + image_create_info.mipLevels = 1; + image_create_info.arrayLayers = 1; + image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; + image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; + image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT; + image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + image_create_info.queueFamilyIndexCount = 0; + image_create_info.pQueueFamilyIndices = nullptr; + image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + if (!ui::vulkan::util::CreateDedicatedAllocationImage( + vulkan_device_, image_create_info, ui::vulkan::util::MemoryPurpose::kDeviceLocal, image_, + memory_)) { + REXLOG_ERROR("VulkanPresenter: Failed to create a guest output image"); + return false; + } + + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + VkImageViewCreateInfo image_view_create_info; + image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + image_view_create_info.pNext = nullptr; + image_view_create_info.flags = 0; + image_view_create_info.image = image_; + image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; + image_view_create_info.format = kGuestOutputFormat; + image_view_create_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + image_view_create_info.subresourceRange.baseMipLevel = 0; + image_view_create_info.subresourceRange.levelCount = 1; + image_view_create_info.subresourceRange.baseArrayLayer = 0; + image_view_create_info.subresourceRange.layerCount = 1; + if (dfn.vkCreateImageView(device, &image_view_create_info, nullptr, &view_) != VK_SUCCESS) { + REXLOG_ERROR("VulkanPresenter: Failed to create a guest output image view"); + return false; + } + + return true; +} + +Presenter::PaintResult VulkanPresenter::PaintAndPresentImpl(bool execute_ui_drawers) { + // Begin the submission in place of the one not currently potentially used on + // the GPU. + uint64_t current_paint_submission_index = + paint_context_.submission_tracker.GetCurrentSubmission(); + uint64_t paint_submission_count = uint64_t(paint_context_.submissions.size()); + if (current_paint_submission_index >= paint_submission_count) { + paint_context_.submission_tracker.AwaitSubmissionCompletion(current_paint_submission_index - + paint_submission_count); + } + const PaintContext::Submission& paint_submission = + *paint_context_.submissions[current_paint_submission_index % paint_submission_count]; + + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + VkCommandPool draw_command_pool = paint_submission.draw_command_pool(); + if (dfn.vkResetCommandPool(device, draw_command_pool, 0) != VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to reset a command buffer for drawing to the " + "swapchain"); + return PaintResult::kNotPresented; + } + + VkCommandBuffer draw_command_buffer = paint_submission.draw_command_buffer(); + VkCommandBufferBeginInfo command_buffer_begin_info; + command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + command_buffer_begin_info.pNext = nullptr; + command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + command_buffer_begin_info.pInheritanceInfo = nullptr; + if (dfn.vkBeginCommandBuffer(draw_command_buffer, &command_buffer_begin_info) != VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to being recording the command buffer for " + "drawing to the swapchain"); + return PaintResult::kNotPresented; + } + // vkResetCommandPool resets from both initial and recording states, still + // safe to return early from this function in case of an error. + + VkSemaphore acquire_semaphore = paint_submission.acquire_semaphore(); + uint32_t swapchain_image_index; + VkResult acquire_result = + dfn.vkAcquireNextImageKHR(device, paint_context_.swapchain, UINT64_MAX, acquire_semaphore, + VK_NULL_HANDLE, &swapchain_image_index); + switch (acquire_result) { + case VK_SUCCESS: + case VK_SUBOPTIMAL_KHR: + break; + case VK_ERROR_DEVICE_LOST: + REXLOG_ERROR( + "VulkanPresenter: Failed to acquire the swapchain image as the " + "device has been lost"); + return PaintResult::kGpuLostResponsible; + case VK_ERROR_OUT_OF_DATE_KHR: + case VK_ERROR_SURFACE_LOST_KHR: + case VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT: + // Not an error, reporting just as info (may normally occur while resizing + // on some platforms). + REXLOG_INFO( + "VulkanPresenter: Presentation to the swapchain image has been " + "dropped as the swapchain or the surface has become outdated"); + return PaintResult::kNotPresentedConnectionOutdated; + default: + REXLOG_ERROR("VulkanPresenter: Failed to acquire the swapchain image"); + return PaintResult::kNotPresented; + } + + // Non-zero extents needed for both the viewport (width must not be zero) and + // the guest output rectangle. + assert_not_zero(paint_context_.swapchain_extent.width); + assert_not_zero(paint_context_.swapchain_extent.height); + + bool swapchain_image_clear_needed = true; + VkClearAttachment swapchain_image_clear_attachment; + swapchain_image_clear_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + swapchain_image_clear_attachment.colorAttachment = 0; + swapchain_image_clear_attachment.clearValue.color.float32[0] = 0.0f; + swapchain_image_clear_attachment.clearValue.color.float32[1] = 0.0f; + swapchain_image_clear_attachment.clearValue.color.float32[2] = 0.0f; + swapchain_image_clear_attachment.clearValue.color.float32[3] = 1.0f; + + VkRenderPassBeginInfo swapchain_render_pass_begin_info; + swapchain_render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + swapchain_render_pass_begin_info.pNext = nullptr; + swapchain_render_pass_begin_info.renderPass = paint_context_.swapchain_render_pass; + swapchain_render_pass_begin_info.framebuffer = + paint_context_.swapchain_framebuffers[swapchain_image_index].framebuffer; + swapchain_render_pass_begin_info.renderArea.offset.x = 0; + swapchain_render_pass_begin_info.renderArea.offset.y = 0; + swapchain_render_pass_begin_info.renderArea.extent = paint_context_.swapchain_extent; + swapchain_render_pass_begin_info.clearValueCount = 0; + swapchain_render_pass_begin_info.pClearValues = nullptr; + if (paint_context_.swapchain_render_pass_clear_load_op) { + swapchain_render_pass_begin_info.clearValueCount = 1; + swapchain_render_pass_begin_info.pClearValues = &swapchain_image_clear_attachment.clearValue; + swapchain_image_clear_needed = false; + } + + bool swapchain_image_pass_begun = false; + + GuestOutputProperties guest_output_properties; + GuestOutputPaintConfig guest_output_paint_config; + std::shared_ptr guest_output_image; + { + uint32_t guest_output_mailbox_index; + std::unique_lock guest_output_consumer_lock(ConsumeGuestOutput( + guest_output_mailbox_index, &guest_output_properties, &guest_output_paint_config)); + if (guest_output_mailbox_index != UINT32_MAX) { + assert_true(guest_output_images_[guest_output_mailbox_index].ever_successfully_refreshed); + guest_output_image = guest_output_images_[guest_output_mailbox_index].image; + } + // Incremented the reference count of the guest output image - safe to leave + // the consumer critical section now as everything here either will be using + // the new reference or is exclusively owned by main target painting (and + // multiple threads can't paint the main target at the same time). + } + + if (guest_output_image) { + VkExtent2D max_framebuffer_extent = + util::GetMax2DFramebufferExtent(vulkan_device_->properties()); + GuestOutputPaintFlow guest_output_flow = GetGuestOutputPaintFlow( + guest_output_properties, paint_context_.swapchain_extent.width, + paint_context_.swapchain_extent.height, max_framebuffer_extent.width, + max_framebuffer_extent.height, guest_output_paint_config); + if (guest_output_flow.effect_count) { + // Store the main target reference to the guest output image so it's not + // destroyed while it's still potentially in use by main target painting + // queued on the GPU. + size_t guest_output_image_paint_ref_index = SIZE_MAX; + size_t guest_output_image_paint_ref_new_index = SIZE_MAX; + // Try to find the existing reference to the same image, or an already + // released (or a taken, but never actually used) slot. + for (size_t i = 0; i < paint_context_.guest_output_image_paint_refs.size(); ++i) { + const std::pair>& guest_output_image_paint_ref = + paint_context_.guest_output_image_paint_refs[i]; + if (guest_output_image_paint_ref.second == guest_output_image) { + guest_output_image_paint_ref_index = i; + break; + } + if (guest_output_image_paint_ref_new_index == SIZE_MAX && + (!guest_output_image_paint_ref.second || !guest_output_image_paint_ref.first)) { + guest_output_image_paint_ref_new_index = i; + } + } + if (guest_output_image_paint_ref_index == SIZE_MAX) { + // New image - store the reference and create the descriptors. + if (guest_output_image_paint_ref_new_index == SIZE_MAX) { + // Replace the earliest used reference. + guest_output_image_paint_ref_new_index = 0; + for (size_t i = 1; i < paint_context_.guest_output_image_paint_refs.size(); ++i) { + if (paint_context_.guest_output_image_paint_refs[i].first < + paint_context_.guest_output_image_paint_refs[guest_output_image_paint_ref_new_index] + .first) { + guest_output_image_paint_ref_new_index = i; + } + } + // Await the completion of the usage of the old guest output image and + // its descriptors. + paint_context_.submission_tracker.AwaitSubmissionCompletion( + paint_context_.guest_output_image_paint_refs[guest_output_image_paint_ref_new_index] + .first); + } + guest_output_image_paint_ref_index = guest_output_image_paint_ref_new_index; + // The actual submission index will be set if the image is actually + // used, not dropped due to some error. + paint_context_.guest_output_image_paint_refs[guest_output_image_paint_ref_index] = + std::make_pair(uint64_t(0), guest_output_image); + // Create the descriptors of the new image. + VkDescriptorImageInfo guest_output_image_descriptor_image_info; + guest_output_image_descriptor_image_info.sampler = VK_NULL_HANDLE; + guest_output_image_descriptor_image_info.imageView = guest_output_image->view(); + guest_output_image_descriptor_image_info.imageLayout = + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + VkWriteDescriptorSet guest_output_image_descriptor_write; + guest_output_image_descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + guest_output_image_descriptor_write.pNext = nullptr; + guest_output_image_descriptor_write.dstSet = + paint_context_.guest_output_descriptor_sets + [PaintContext::kGuestOutputDescriptorSetGuestOutput0Sampled + + guest_output_image_paint_ref_index]; + guest_output_image_descriptor_write.dstBinding = 0; + guest_output_image_descriptor_write.dstArrayElement = 0; + guest_output_image_descriptor_write.descriptorCount = 1; + guest_output_image_descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + guest_output_image_descriptor_write.pImageInfo = &guest_output_image_descriptor_image_info; + guest_output_image_descriptor_write.pBufferInfo = nullptr; + guest_output_image_descriptor_write.pTexelBufferView = nullptr; + dfn.vkUpdateDescriptorSets(device, 1, &guest_output_image_descriptor_write, 0, nullptr); + } + + // Make sure intermediate textures of the needed size are available, and + // unneeded intermediate textures are destroyed. + for (size_t i = 0; i < kMaxGuestOutputPaintEffects - 1; ++i) { + std::pair intermediate_needed_size(0, 0); + if (i + 1 < guest_output_flow.effect_count) { + intermediate_needed_size = guest_output_flow.effect_output_sizes[i]; + } + std::unique_ptr& intermediate_image_ptr_ref = + paint_context_.guest_output_intermediate_images[i]; + VkExtent2D intermediate_current_extent( + intermediate_image_ptr_ref ? intermediate_image_ptr_ref->extent() : VkExtent2D{}); + if (intermediate_current_extent.width != intermediate_needed_size.first || + intermediate_current_extent.height != intermediate_needed_size.second) { + if (intermediate_needed_size.first && intermediate_needed_size.second) { + // Need to replace immediately as a new image with the requested + // size is needed. + if (intermediate_image_ptr_ref) { + paint_context_.submission_tracker.AwaitSubmissionCompletion( + paint_context_.guest_output_intermediate_image_last_submission); + intermediate_image_ptr_ref.reset(); + util::DestroyAndNullHandle(dfn.vkDestroyFramebuffer, device, + paint_context_.guest_output_intermediate_framebuffers[i]); + } + // Image. + intermediate_image_ptr_ref = GuestOutputImage::Create( + vulkan_device_, intermediate_needed_size.first, intermediate_needed_size.second); + if (!intermediate_image_ptr_ref) { + // Don't display the guest output, and don't try to create more + // intermediate textures (only destroy them). + guest_output_flow.effect_count = 0; + continue; + } + // Framebuffer. + VkImageView intermediate_framebuffer_attachment = intermediate_image_ptr_ref->view(); + VkFramebufferCreateInfo intermediate_framebuffer_create_info; + intermediate_framebuffer_create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + intermediate_framebuffer_create_info.pNext = nullptr; + intermediate_framebuffer_create_info.flags = 0; + intermediate_framebuffer_create_info.renderPass = + guest_output_intermediate_render_pass_; + intermediate_framebuffer_create_info.attachmentCount = 1; + intermediate_framebuffer_create_info.pAttachments = + &intermediate_framebuffer_attachment; + intermediate_framebuffer_create_info.width = intermediate_needed_size.first; + intermediate_framebuffer_create_info.height = intermediate_needed_size.second; + intermediate_framebuffer_create_info.layers = 1; + if (dfn.vkCreateFramebuffer( + device, &intermediate_framebuffer_create_info, nullptr, + &paint_context_.guest_output_intermediate_framebuffers[i]) != VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to create a guest output " + "intermediate framebuffer"); + // Don't display the guest output, and don't try to create more + // intermediate textures (only destroy them). + guest_output_flow.effect_count = 0; + continue; + } + // Descriptors. + VkDescriptorImageInfo intermediate_descriptor_image_info; + intermediate_descriptor_image_info.sampler = VK_NULL_HANDLE; + intermediate_descriptor_image_info.imageView = intermediate_image_ptr_ref->view(); + intermediate_descriptor_image_info.imageLayout = + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + VkWriteDescriptorSet intermediate_descriptor_write; + intermediate_descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + intermediate_descriptor_write.pNext = nullptr; + intermediate_descriptor_write.dstSet = + paint_context_.guest_output_descriptor_sets + [PaintContext ::kGuestOutputDescriptorSetIntermediate0Sampled + i]; + intermediate_descriptor_write.dstBinding = 0; + intermediate_descriptor_write.dstArrayElement = 0; + intermediate_descriptor_write.descriptorCount = 1; + intermediate_descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + intermediate_descriptor_write.pImageInfo = &intermediate_descriptor_image_info; + intermediate_descriptor_write.pBufferInfo = nullptr; + intermediate_descriptor_write.pTexelBufferView = nullptr; + dfn.vkUpdateDescriptorSets(device, 1, &intermediate_descriptor_write, 0, nullptr); + } else { + // Was previously needed, but not anymore - destroy when possible. + if (intermediate_image_ptr_ref && + paint_context_.submission_tracker.UpdateAndGetCompletedSubmission() >= + paint_context_.guest_output_intermediate_image_last_submission) { + intermediate_image_ptr_ref.reset(); + util::DestroyAndNullHandle(dfn.vkDestroyFramebuffer, device, + paint_context_.guest_output_intermediate_framebuffers[i]); + } + } + } + } + + if (guest_output_flow.effect_count) { + // Check if all the intermediate effects are supported by the + // implementation. + for (size_t i = 0; i + 1 < guest_output_flow.effect_count; ++i) { + if (paint_context_.guest_output_paint_pipelines[size_t(guest_output_flow.effects[i])] + .intermediate_pipeline == VK_NULL_HANDLE) { + guest_output_flow.effect_count = 0; + break; + } + } + if (guest_output_flow.effect_count) { + // Ensure the pipeline exists for the final effect drawing to the + // swapchain, for the render pass with the up-to-date image format. + GuestOutputPaintEffect swapchain_effect = + guest_output_flow.effects[guest_output_flow.effect_count - 1]; + PaintContext::GuestOutputPaintPipeline& swapchain_effect_pipeline = + paint_context_.guest_output_paint_pipelines[size_t(swapchain_effect)]; + if (swapchain_effect_pipeline.swapchain_pipeline != VK_NULL_HANDLE && + swapchain_effect_pipeline.swapchain_format != + paint_context_.swapchain_render_pass_format) { + paint_context_.submission_tracker.AwaitSubmissionCompletion( + paint_context_.guest_output_image_paint_last_submission); + util::DestroyAndNullHandle(dfn.vkDestroyPipeline, device, + swapchain_effect_pipeline.swapchain_pipeline); + } + if (swapchain_effect_pipeline.swapchain_pipeline == VK_NULL_HANDLE) { + assert_true(CanGuestOutputPaintEffectBeFinal(swapchain_effect)); + assert_true(guest_output_paint_fs_[size_t(swapchain_effect)] != VK_NULL_HANDLE); + swapchain_effect_pipeline.swapchain_pipeline = CreateGuestOutputPaintPipeline( + swapchain_effect, paint_context_.swapchain_render_pass); + if (swapchain_effect_pipeline.swapchain_pipeline == VK_NULL_HANDLE) { + guest_output_flow.effect_count = 0; + } + } + } + } + + if (guest_output_flow.effect_count) { + // Actually draw the guest output. + paint_context_.guest_output_image_paint_refs[guest_output_image_paint_ref_index].first = + current_paint_submission_index; + paint_context_.guest_output_image_paint_last_submission = current_paint_submission_index; + VkViewport guest_output_viewport; + guest_output_viewport.x = 0.0f; + guest_output_viewport.y = 0.0f; + guest_output_viewport.minDepth = 0.0f; + guest_output_viewport.maxDepth = 1.0f; + VkRect2D guest_output_scissor; + guest_output_scissor.offset.x = 0; + guest_output_scissor.offset.y = 0; + if (guest_output_flow.effect_count > 1) { + paint_context_.guest_output_intermediate_image_last_submission = + current_paint_submission_index; + } + [[maybe_unused]] bool temporal_effect_selected = false; +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME + temporal_effect_selected = + guest_output_paint_config.GetEffect() == GuestOutputPaintConfig::Effect::kFsr2 || + guest_output_paint_config.GetEffect() == GuestOutputPaintConfig::Effect::kFsr3; +#endif + for (size_t i = 0; i < guest_output_flow.effect_count; ++i) { + bool is_final_effect = i + 1 >= guest_output_flow.effect_count; + GuestOutputPaintEffect effect = guest_output_flow.effects[i]; + + std::pair effect_rect_size = guest_output_flow.effect_output_sizes[i]; + if (is_final_effect && guest_output_flow.output_x == 0 && + guest_output_flow.output_y == 0 && + effect_rect_size.first < paint_context_.swapchain_extent.width && + effect_rect_size.second < paint_context_.swapchain_extent.height) { + static std::atomic logged_swapchain_expand = false; + if (!logged_swapchain_expand.exchange(true)) { + REXLOG_WARN( + "VulkanPresenter: expanding final guest output rect from " + "{}x{} to swapchain {}x{} to avoid top-left-only output", + effect_rect_size.first, effect_rect_size.second, + paint_context_.swapchain_extent.width, paint_context_.swapchain_extent.height); + } + effect_rect_size = std::make_pair(paint_context_.swapchain_extent.width, + paint_context_.swapchain_extent.height); + // Keep all final-pass data coherent - shader constants and + // letterbox clears are derived from guest_output_flow. + guest_output_flow.effect_output_sizes[i] = effect_rect_size; + guest_output_flow.output_x = 0; + guest_output_flow.output_y = 0; + guest_output_flow.letterbox_clear_rectangle_count = 0; + } +#if defined(REX_HAS_FIDELITYFX_RUNTIME) && REX_HAS_FIDELITYFX_RUNTIME + bool use_temporal_upscaler = + temporal_effect_selected && effect == GuestOutputPaintEffect::kFsrEasu; + if (use_temporal_upscaler && !is_final_effect) { + VkImage source_image = + i ? paint_context_.guest_output_intermediate_images[i - 1]->image() + : guest_output_image->image(); + VkImage output_image = paint_context_.guest_output_intermediate_images[i]->image(); + + VkImageMemoryBarrier barrier_to_uav = {}; + barrier_to_uav.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier_to_uav.srcAccessMask = 0; + barrier_to_uav.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + barrier_to_uav.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + barrier_to_uav.newLayout = VK_IMAGE_LAYOUT_GENERAL; + barrier_to_uav.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier_to_uav.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier_to_uav.image = output_image; + barrier_to_uav.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + barrier_to_uav.subresourceRange.baseMipLevel = 0; + barrier_to_uav.subresourceRange.levelCount = 1; + barrier_to_uav.subresourceRange.baseArrayLayer = 0; + barrier_to_uav.subresourceRange.layerCount = 1; + dfn.vkCmdPipelineBarrier(draw_command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, + nullptr, 1, &barrier_to_uav); + + uint32_t effect_input_width = 0, effect_input_height = 0; + guest_output_flow.GetEffectInputSize(i, effect_input_width, effect_input_height); + if (DispatchTemporalUpscaler(draw_command_buffer, source_image, effect_input_width, + effect_input_height, output_image, effect_rect_size.first, + effect_rect_size.second, guest_output_paint_config)) { + VkImageMemoryBarrier barrier_to_shader_read = {}; + barrier_to_shader_read.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier_to_shader_read.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + barrier_to_shader_read.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + barrier_to_shader_read.oldLayout = VK_IMAGE_LAYOUT_GENERAL; + barrier_to_shader_read.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + barrier_to_shader_read.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier_to_shader_read.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier_to_shader_read.image = output_image; + barrier_to_shader_read.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + barrier_to_shader_read.subresourceRange.baseMipLevel = 0; + barrier_to_shader_read.subresourceRange.levelCount = 1; + barrier_to_shader_read.subresourceRange.baseArrayLayer = 0; + barrier_to_shader_read.subresourceRange.layerCount = 1; + dfn.vkCmdPipelineBarrier( + draw_command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, + 0, nullptr, 0, nullptr, 1, &barrier_to_shader_read); + continue; + } + } +#endif + + int32_t effect_rect_x, effect_rect_y; + if (is_final_effect) { + effect_rect_x = guest_output_flow.output_x; + effect_rect_y = guest_output_flow.output_y; + dfn.vkCmdBeginRenderPass(draw_command_buffer, &swapchain_render_pass_begin_info, + VK_SUBPASS_CONTENTS_INLINE); + swapchain_image_pass_begun = true; + guest_output_viewport.width = float(paint_context_.swapchain_extent.width); + guest_output_viewport.height = float(paint_context_.swapchain_extent.height); + guest_output_scissor.extent.width = paint_context_.swapchain_extent.width; + guest_output_scissor.extent.height = paint_context_.swapchain_extent.height; + } else { + effect_rect_x = 0; + effect_rect_y = 0; + VkRenderPassBeginInfo intermediate_render_pass_begin_info; + intermediate_render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + intermediate_render_pass_begin_info.pNext = nullptr; + intermediate_render_pass_begin_info.renderPass = guest_output_intermediate_render_pass_; + intermediate_render_pass_begin_info.framebuffer = + paint_context_.guest_output_intermediate_framebuffers[i]; + intermediate_render_pass_begin_info.renderArea.offset.x = 0; + intermediate_render_pass_begin_info.renderArea.offset.y = 0; + intermediate_render_pass_begin_info.renderArea.extent.width = effect_rect_size.first; + intermediate_render_pass_begin_info.renderArea.extent.height = effect_rect_size.second; + intermediate_render_pass_begin_info.clearValueCount = 0; + intermediate_render_pass_begin_info.pClearValues = nullptr; + dfn.vkCmdBeginRenderPass(draw_command_buffer, &intermediate_render_pass_begin_info, + VK_SUBPASS_CONTENTS_INLINE); + guest_output_viewport.width = float(effect_rect_size.first); + guest_output_viewport.height = float(effect_rect_size.second); + guest_output_scissor.extent.width = effect_rect_size.first; + guest_output_scissor.extent.height = effect_rect_size.second; + } + dfn.vkCmdSetViewport(draw_command_buffer, 0, 1, &guest_output_viewport); + dfn.vkCmdSetScissor(draw_command_buffer, 0, 1, &guest_output_scissor); + + const PaintContext::GuestOutputPaintPipeline& effect_pipeline = + paint_context_.guest_output_paint_pipelines[size_t(effect)]; + VkPipeline effect_vulkan_pipeline = is_final_effect + ? effect_pipeline.swapchain_pipeline + : effect_pipeline.intermediate_pipeline; + assert_true(effect_vulkan_pipeline != VK_NULL_HANDLE); + dfn.vkCmdBindPipeline(draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + effect_vulkan_pipeline); + + GuestOutputPaintPipelineLayoutIndex guest_output_paint_pipeline_layout_index = + GetGuestOutputPaintPipelineLayoutIndex(effect); + VkPipelineLayout guest_output_paint_pipeline_layout = + guest_output_paint_pipeline_layouts_[guest_output_paint_pipeline_layout_index]; + + PaintContext::GuestOutputDescriptorSet effect_src_descriptor_set; + if (i) { + effect_src_descriptor_set = PaintContext::GuestOutputDescriptorSet( + PaintContext::kGuestOutputDescriptorSetIntermediate0Sampled + (i - 1)); + } else { + effect_src_descriptor_set = PaintContext::GuestOutputDescriptorSet( + PaintContext::kGuestOutputDescriptorSetGuestOutput0Sampled + + guest_output_image_paint_ref_index); + } + dfn.vkCmdBindDescriptorSets( + draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + guest_output_paint_pipeline_layout, 0, 1, + &paint_context_.guest_output_descriptor_sets[effect_src_descriptor_set], 0, nullptr); + + GuestOutputPaintRectangleConstants effect_rect_constants; + float effect_x_to_ndc = 2.0f / guest_output_viewport.width; + float effect_y_to_ndc = 2.0f / guest_output_viewport.height; + effect_rect_constants.x = -1.0f + float(effect_rect_x) * effect_x_to_ndc; + effect_rect_constants.y = -1.0f + float(effect_rect_y) * effect_y_to_ndc; + effect_rect_constants.width = float(effect_rect_size.first) * effect_x_to_ndc; + effect_rect_constants.height = float(effect_rect_size.second) * effect_y_to_ndc; + dfn.vkCmdPushConstants(draw_command_buffer, guest_output_paint_pipeline_layout, + VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(effect_rect_constants), + &effect_rect_constants); + + uint32_t effect_constants_size = 0; + union { + BilinearConstants bilinear; +#if defined(REX_HAS_FIDELITYFX_SDK) + CasSharpenConstants cas_sharpen; + CasResampleConstants cas_resample; + FsrEasuConstants fsr_easu; + FsrRcasConstants fsr_rcas; +#endif + } effect_constants; + switch (guest_output_paint_pipeline_layout_index) { + case kGuestOutputPaintPipelineLayoutIndexBilinear: { + effect_constants_size = sizeof(effect_constants.bilinear); + effect_constants.bilinear.Initialize(guest_output_flow, i); + } break; +#if defined(REX_HAS_FIDELITYFX_SDK) + case kGuestOutputPaintPipelineLayoutIndexCasSharpen: { + effect_constants_size = sizeof(effect_constants.cas_sharpen); + effect_constants.cas_sharpen.Initialize(guest_output_flow, i, + guest_output_paint_config); + } break; + case kGuestOutputPaintPipelineLayoutIndexCasResample: { + effect_constants_size = sizeof(effect_constants.cas_resample); + effect_constants.cas_resample.Initialize(guest_output_flow, i, + guest_output_paint_config); + } break; + case kGuestOutputPaintPipelineLayoutIndexFsrEasu: { + effect_constants_size = sizeof(effect_constants.fsr_easu); + effect_constants.fsr_easu.Initialize(guest_output_flow, i); + } break; + case kGuestOutputPaintPipelineLayoutIndexFsrRcas: { + effect_constants_size = sizeof(effect_constants.fsr_rcas); + effect_constants.fsr_rcas.Initialize(guest_output_flow, i, guest_output_paint_config); + } break; +#endif + default: + break; + } + if (effect_constants_size) { + dfn.vkCmdPushConstants(draw_command_buffer, guest_output_paint_pipeline_layout, + VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(effect_rect_constants), + effect_constants_size, &effect_constants); + } + + dfn.vkCmdDraw(draw_command_buffer, 4, 1, 0, 0); + + if (is_final_effect) { + // Clear the letterbox around the guest output if the guest output + // doesn't cover the entire swapchain image. + if (swapchain_image_clear_needed && guest_output_flow.letterbox_clear_rectangle_count) { + VkClearRect + letterbox_clear_vulkan_rectangles[GuestOutputPaintFlow::kMaxClearRectangles]; + for (size_t i = 0; i < guest_output_flow.letterbox_clear_rectangle_count; ++i) { + VkClearRect& letterbox_clear_vulkan_rectangle = + letterbox_clear_vulkan_rectangles[i]; + const GuestOutputPaintFlow::ClearRectangle& letterbox_clear_rectangle = + guest_output_flow.letterbox_clear_rectangles[i]; + letterbox_clear_vulkan_rectangle.rect.offset.x = + int32_t(letterbox_clear_rectangle.x); + letterbox_clear_vulkan_rectangle.rect.offset.y = + int32_t(letterbox_clear_rectangle.y); + letterbox_clear_vulkan_rectangle.rect.extent.width = + letterbox_clear_rectangle.width; + letterbox_clear_vulkan_rectangle.rect.extent.height = + letterbox_clear_rectangle.height; + letterbox_clear_vulkan_rectangle.baseArrayLayer = 0; + letterbox_clear_vulkan_rectangle.layerCount = 1; + } + dfn.vkCmdClearAttachments(draw_command_buffer, 1, &swapchain_image_clear_attachment, + uint32_t(guest_output_flow.letterbox_clear_rectangle_count), + letterbox_clear_vulkan_rectangles); + } + swapchain_image_clear_needed = false; + } else { + // Still need the swapchain pass to be open for UI drawing. + dfn.vkCmdEndRenderPass(draw_command_buffer); + } + } + } + } + } + + // Release main target guest output image references that aren't needed + // anymore (this is done after various potential guest-output-related main + // target submission tracker waits so the completed submission value is the + // most actual). + uint64_t completed_paint_submission = + paint_context_.submission_tracker.UpdateAndGetCompletedSubmission(); + for (std::pair>& guest_output_image_paint_ref : + paint_context_.guest_output_image_paint_refs) { + if (!guest_output_image_paint_ref.second || + guest_output_image_paint_ref.second == guest_output_image) { + continue; + } + if (completed_paint_submission >= guest_output_image_paint_ref.first) { + guest_output_image_paint_ref.second.reset(); + } + } + + // If hasn't presented the guest output, begin the pass to clear and, if + // needed, to draw the UI. + if (!swapchain_image_pass_begun) { + dfn.vkCmdBeginRenderPass(draw_command_buffer, &swapchain_render_pass_begin_info, + VK_SUBPASS_CONTENTS_INLINE); + } + if (swapchain_image_clear_needed) { + VkClearRect swapchain_image_clear_rectangle; + swapchain_image_clear_rectangle.rect.offset.x = 0; + swapchain_image_clear_rectangle.rect.offset.y = 0; + swapchain_image_clear_rectangle.rect.extent = paint_context_.swapchain_extent; + swapchain_image_clear_rectangle.baseArrayLayer = 0; + swapchain_image_clear_rectangle.layerCount = 1; + dfn.vkCmdClearAttachments(draw_command_buffer, 1, &swapchain_image_clear_attachment, 1, + &swapchain_image_clear_rectangle); + swapchain_image_clear_needed = false; + } + + if (execute_ui_drawers) { + // Draw the UI. + VulkanUIDrawContext ui_draw_context( + *this, paint_context_.swapchain_extent.width, paint_context_.swapchain_extent.height, + draw_command_buffer, ui_submission_tracker_.GetCurrentSubmission(), + ui_submission_tracker_.UpdateAndGetCompletedSubmission(), + paint_context_.swapchain_render_pass, paint_context_.swapchain_render_pass_format); + ExecuteUIDrawersFromUIThread(ui_draw_context); + } + + dfn.vkCmdEndRenderPass(draw_command_buffer); + + dfn.vkEndCommandBuffer(draw_command_buffer); + + VkPipelineStageFlags acquire_semaphore_wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + VkCommandBuffer command_buffers[2]; + uint32_t command_buffer_count = 0; + // UI setup command buffers must be accessed only if execute_ui_drawers is not + // null, to identify the UI thread. + size_t ui_setup_command_buffer_index = + execute_ui_drawers ? paint_context_.ui_setup_command_buffer_current_index : SIZE_MAX; + if (ui_setup_command_buffer_index != SIZE_MAX) { + PaintContext::UISetupCommandBuffer& ui_setup_command_buffer = + paint_context_.ui_setup_command_buffers[ui_setup_command_buffer_index]; + dfn.vkEndCommandBuffer(ui_setup_command_buffer.command_buffer); + command_buffers[command_buffer_count++] = ui_setup_command_buffer.command_buffer; + // Release the current UI setup command buffer regardless of submission + // result. Failed submissions (if the UI submission index wasn't incremented + // since the previous draw) should be handled by UI drawers themselves by + // retrying all the failed work if needed. + paint_context_.ui_setup_command_buffer_current_index = SIZE_MAX; + } + command_buffers[command_buffer_count++] = draw_command_buffer; + VkSemaphore present_semaphore = paint_submission.present_semaphore(); + VkSubmitInfo submit_info; + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.pNext = nullptr; + submit_info.waitSemaphoreCount = 1; + submit_info.pWaitSemaphores = &acquire_semaphore; + submit_info.pWaitDstStageMask = &acquire_semaphore_wait_stage; + submit_info.commandBufferCount = command_buffer_count; + submit_info.pCommandBuffers = command_buffers; + submit_info.signalSemaphoreCount = 1; + submit_info.pSignalSemaphores = &present_semaphore; + { + VulkanSubmissionTracker::FenceAcquisition fence_acqusition( + paint_context_.submission_tracker.AcquireFenceToAdvanceSubmission()); + // Also update the submission tracker giving submission indices to UI draw + // callbacks if submission is successful. + VulkanSubmissionTracker::FenceAcquisition ui_fence_acquisition; + if (execute_ui_drawers) { + ui_fence_acquisition = ui_submission_tracker_.AcquireFenceToAdvanceSubmission(); + } + VkResult submit_result; + { + const VulkanDevice::Queue::Acquisition queue_acquisition = + vulkan_device_->AcquireQueue(vulkan_device_->queue_family_graphics_compute(), 0); + submit_result = + dfn.vkQueueSubmit(queue_acquisition.queue(), 1, &submit_info, fence_acqusition.fence()); + if (ui_fence_acquisition.fence() != VK_NULL_HANDLE && submit_result == VK_SUCCESS) { + if (dfn.vkQueueSubmit(queue_acquisition.queue(), 0, nullptr, + ui_fence_acquisition.fence()) != VK_SUCCESS) { + ui_fence_acquisition.SubmissionSucceededSignalFailed(); + } + } + } + if (submit_result != VK_SUCCESS) { + REXLOG_ERROR("VulkanPresenter: Failed to submit command buffers"); + fence_acqusition.SubmissionFailedOrDropped(); + ui_fence_acquisition.SubmissionFailedOrDropped(); + if (ui_setup_command_buffer_index != SIZE_MAX) { + // If failed to submit, make the UI setup command buffer available for + // immediate reuse, as the completed submission index won't be updated + // to the current index, and failing submissions with setup command + // buffer over and over will result in never reusing the setup command + // buffers. + paint_context_.ui_setup_command_buffers[ui_setup_command_buffer_index] + .last_usage_submission_index = 0; + } + // The image is in an acquired state - but now, it will be in it forever. + // To avoid that, recreate the swapchain - don't return just + // kNotPresented. + return PaintResult::kNotPresentedConnectionOutdated; + } + } + + VkPresentInfoKHR present_info; + present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + present_info.pNext = nullptr; + present_info.waitSemaphoreCount = 1; + present_info.pWaitSemaphores = &present_semaphore; + present_info.swapchainCount = 1; + present_info.pSwapchains = &paint_context_.swapchain; + present_info.pImageIndices = &swapchain_image_index; + present_info.pResults = nullptr; + VkResult present_result; + { + const VulkanDevice::Queue::Acquisition queue_acquisition = + vulkan_device_->AcquireQueue(paint_context_.present_queue_family, 0); + present_result = dfn.vkQueuePresentKHR(queue_acquisition.queue(), &present_info); + } + switch (present_result) { + case VK_SUCCESS: + return PaintResult::kPresented; + case VK_SUBOPTIMAL_KHR: + return PaintResult::kPresentedSuboptimal; + case VK_ERROR_DEVICE_LOST: + REXLOG_ERROR( + "VulkanPresenter: Failed to present the swapchain image as the " + "device has been lost"); + return PaintResult::kGpuLostResponsible; + case VK_ERROR_OUT_OF_DATE_KHR: + case VK_ERROR_SURFACE_LOST_KHR: + case VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT: + // Not an error, reporting just as info (may normally occur while resizing + // on some platforms). + REXLOG_INFO( + "VulkanPresenter: Presentation to the swapchain image has been " + "dropped as the swapchain or the surface has become outdated"); + // Note that the semaphore wait (followed by reset) has been enqueued, + // however, this should have no effect on anything here likely. + return PaintResult::kNotPresentedConnectionOutdated; + default: + REXLOG_ERROR("VulkanPresenter: Failed to present the swapchain image"); + // The image is in an acquired state - but now, it will be in it forever. + // To avoid that, recreate the swapchain - don't return just + // kNotPresented. + return PaintResult::kNotPresentedConnectionOutdated; + } +} + +bool VulkanPresenter::InitializeSurfaceIndependent() { + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + VkDescriptorSetLayoutBinding guest_output_image_sampler_bindings[2]; + guest_output_image_sampler_bindings[0].binding = 0; + guest_output_image_sampler_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + guest_output_image_sampler_bindings[0].descriptorCount = 1; + guest_output_image_sampler_bindings[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + guest_output_image_sampler_bindings[0].pImmutableSamplers = nullptr; + const VkSampler sampler_linear_clamp = + ui_samplers_->samplers()[UISamplers::kSamplerIndexLinearClampToEdge]; + guest_output_image_sampler_bindings[1].binding = 1; + guest_output_image_sampler_bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; + guest_output_image_sampler_bindings[1].descriptorCount = 1; + guest_output_image_sampler_bindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + guest_output_image_sampler_bindings[1].pImmutableSamplers = &sampler_linear_clamp; + VkDescriptorSetLayoutCreateInfo guest_output_paint_image_descriptor_set_layout_create_info; + guest_output_paint_image_descriptor_set_layout_create_info.sType = + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + guest_output_paint_image_descriptor_set_layout_create_info.pNext = nullptr; + guest_output_paint_image_descriptor_set_layout_create_info.flags = 0; + guest_output_paint_image_descriptor_set_layout_create_info.bindingCount = + uint32_t(rex::countof(guest_output_image_sampler_bindings)); + guest_output_paint_image_descriptor_set_layout_create_info.pBindings = + guest_output_image_sampler_bindings; + if (dfn.vkCreateDescriptorSetLayout( + device, &guest_output_paint_image_descriptor_set_layout_create_info, nullptr, + &guest_output_paint_image_descriptor_set_layout_) != VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to create the guest output image descriptor " + "set layout"); + return false; + } + + VkPushConstantRange guest_output_paint_push_constant_ranges[2]; + VkPushConstantRange& guest_output_paint_push_constant_range_rect = + guest_output_paint_push_constant_ranges[0]; + guest_output_paint_push_constant_range_rect.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + guest_output_paint_push_constant_range_rect.offset = 0; + guest_output_paint_push_constant_range_rect.size = sizeof(GuestOutputPaintRectangleConstants); + VkPushConstantRange& guest_output_paint_push_constant_range_ffx = + guest_output_paint_push_constant_ranges[1]; + guest_output_paint_push_constant_range_ffx.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + guest_output_paint_push_constant_range_ffx.offset = + guest_output_paint_push_constant_ranges[0].offset + + guest_output_paint_push_constant_ranges[0].size; + VkPipelineLayoutCreateInfo guest_output_paint_pipeline_layout_create_info; + guest_output_paint_pipeline_layout_create_info.sType = + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + guest_output_paint_pipeline_layout_create_info.pNext = nullptr; + guest_output_paint_pipeline_layout_create_info.flags = 0; + guest_output_paint_pipeline_layout_create_info.setLayoutCount = 1; + guest_output_paint_pipeline_layout_create_info.pSetLayouts = + &guest_output_paint_image_descriptor_set_layout_; + guest_output_paint_pipeline_layout_create_info.pPushConstantRanges = + guest_output_paint_push_constant_ranges; + for (size_t i = 0; i < size_t(kGuestOutputPaintPipelineLayoutCount); ++i) { + switch (GuestOutputPaintPipelineLayoutIndex(i)) { + case kGuestOutputPaintPipelineLayoutIndexBilinear: + guest_output_paint_push_constant_range_ffx.size = sizeof(BilinearConstants); + break; +#if defined(REX_HAS_FIDELITYFX_SDK) + case kGuestOutputPaintPipelineLayoutIndexCasSharpen: + guest_output_paint_push_constant_range_ffx.size = sizeof(CasSharpenConstants); + break; + case kGuestOutputPaintPipelineLayoutIndexCasResample: + guest_output_paint_push_constant_range_ffx.size = sizeof(CasResampleConstants); + break; + case kGuestOutputPaintPipelineLayoutIndexFsrEasu: + guest_output_paint_push_constant_range_ffx.size = sizeof(FsrEasuConstants); + break; + case kGuestOutputPaintPipelineLayoutIndexFsrRcas: + guest_output_paint_push_constant_range_ffx.size = sizeof(FsrRcasConstants); + break; +#endif + default: + assert_unhandled_case(GuestOutputPaintPipelineLayoutIndex(i)); + continue; + } + guest_output_paint_pipeline_layout_create_info.pushConstantRangeCount = + 1 + uint32_t(guest_output_paint_push_constant_range_ffx.size != 0); + if (dfn.vkCreatePipelineLayout(device, &guest_output_paint_pipeline_layout_create_info, nullptr, + &guest_output_paint_pipeline_layouts_[i]) != VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to create a guest output presentation " + "pipeline layout with {} bytes of push constants", + guest_output_paint_push_constant_range_rect.size + + guest_output_paint_push_constant_range_ffx.size); + return false; + } + } + + VkShaderModuleCreateInfo shader_module_create_info; + shader_module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + shader_module_create_info.pNext = nullptr; + shader_module_create_info.flags = 0; + shader_module_create_info.codeSize = sizeof(shaders::guest_output_triangle_strip_rect_vs); + shader_module_create_info.pCode = shaders::guest_output_triangle_strip_rect_vs; + if (dfn.vkCreateShaderModule(device, &shader_module_create_info, nullptr, + &guest_output_paint_vs_) != VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to create the guest output presentation " + "vertex shader module"); + return false; + } + for (size_t i = 0; i < size_t(GuestOutputPaintEffect::kCount); ++i) { + GuestOutputPaintEffect guest_output_paint_effect = GuestOutputPaintEffect(i); + switch (guest_output_paint_effect) { + case GuestOutputPaintEffect::kBilinear: + shader_module_create_info.codeSize = sizeof(shaders::guest_output_bilinear_ps); + shader_module_create_info.pCode = shaders::guest_output_bilinear_ps; + break; + case GuestOutputPaintEffect::kBilinearDither: + shader_module_create_info.codeSize = sizeof(shaders::guest_output_bilinear_dither_ps); + shader_module_create_info.pCode = shaders::guest_output_bilinear_dither_ps; + break; +#if defined(REX_HAS_FIDELITYFX_SDK) + case GuestOutputPaintEffect::kCasSharpen: + shader_module_create_info.codeSize = sizeof(shaders::guest_output_ffx_cas_sharpen_ps); + shader_module_create_info.pCode = shaders::guest_output_ffx_cas_sharpen_ps; + break; + case GuestOutputPaintEffect::kCasSharpenDither: + shader_module_create_info.codeSize = + sizeof(shaders::guest_output_ffx_cas_sharpen_dither_ps); + shader_module_create_info.pCode = shaders::guest_output_ffx_cas_sharpen_dither_ps; + break; + case GuestOutputPaintEffect::kCasResample: + shader_module_create_info.codeSize = sizeof(shaders::guest_output_ffx_cas_resample_ps); + shader_module_create_info.pCode = shaders::guest_output_ffx_cas_resample_ps; + break; + case GuestOutputPaintEffect::kCasResampleDither: + shader_module_create_info.codeSize = + sizeof(shaders::guest_output_ffx_cas_resample_dither_ps); + shader_module_create_info.pCode = shaders::guest_output_ffx_cas_resample_dither_ps; + break; + case GuestOutputPaintEffect::kFsrEasu: + shader_module_create_info.codeSize = sizeof(shaders::guest_output_ffx_fsr_easu_ps); + shader_module_create_info.pCode = shaders::guest_output_ffx_fsr_easu_ps; + break; + case GuestOutputPaintEffect::kFsrRcas: + shader_module_create_info.codeSize = sizeof(shaders::guest_output_ffx_fsr_rcas_ps); + shader_module_create_info.pCode = shaders::guest_output_ffx_fsr_rcas_ps; + break; + case GuestOutputPaintEffect::kFsrRcasDither: + shader_module_create_info.codeSize = sizeof(shaders::guest_output_ffx_fsr_rcas_dither_ps); + shader_module_create_info.pCode = shaders::guest_output_ffx_fsr_rcas_dither_ps; + break; +#endif + default: + // Not supported by this implementation. + continue; + } + if (dfn.vkCreateShaderModule(device, &shader_module_create_info, nullptr, + &guest_output_paint_fs_[i]) != VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to create the guest output painting shader " + "module for effect {}", + i); + return false; + } + } + + VkAttachmentDescription intermediate_render_pass_attachment; + intermediate_render_pass_attachment.flags = 0; + intermediate_render_pass_attachment.format = kGuestOutputFormat; + intermediate_render_pass_attachment.samples = VK_SAMPLE_COUNT_1_BIT; + intermediate_render_pass_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + intermediate_render_pass_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + intermediate_render_pass_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + intermediate_render_pass_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + intermediate_render_pass_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + intermediate_render_pass_attachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + VkAttachmentReference intermediate_render_pass_color_attachment; + intermediate_render_pass_color_attachment.attachment = 0; + intermediate_render_pass_color_attachment.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + VkSubpassDescription intermediate_render_pass_subpass = {}; + intermediate_render_pass_subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + intermediate_render_pass_subpass.colorAttachmentCount = 1; + intermediate_render_pass_subpass.pColorAttachments = &intermediate_render_pass_color_attachment; + VkSubpassDependency intermediate_render_pass_dependencies[2]; + intermediate_render_pass_dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL; + intermediate_render_pass_dependencies[0].dstSubpass = 0; + intermediate_render_pass_dependencies[0].srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + intermediate_render_pass_dependencies[0].dstStageMask = + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + intermediate_render_pass_dependencies[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT; + intermediate_render_pass_dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + intermediate_render_pass_dependencies[0].dependencyFlags = 0; + intermediate_render_pass_dependencies[1].srcSubpass = 0; + intermediate_render_pass_dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL; + intermediate_render_pass_dependencies[1].srcStageMask = + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + intermediate_render_pass_dependencies[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + intermediate_render_pass_dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + intermediate_render_pass_dependencies[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + intermediate_render_pass_dependencies[1].dependencyFlags = 0; + VkRenderPassCreateInfo intermediate_render_pass_create_info; + intermediate_render_pass_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + intermediate_render_pass_create_info.pNext = nullptr; + intermediate_render_pass_create_info.flags = 0; + intermediate_render_pass_create_info.attachmentCount = 1; + intermediate_render_pass_create_info.pAttachments = &intermediate_render_pass_attachment; + intermediate_render_pass_create_info.subpassCount = 1; + intermediate_render_pass_create_info.pSubpasses = &intermediate_render_pass_subpass; + intermediate_render_pass_create_info.dependencyCount = + uint32_t(rex::countof(intermediate_render_pass_dependencies)); + intermediate_render_pass_create_info.pDependencies = intermediate_render_pass_dependencies; + if (dfn.vkCreateRenderPass(device, &intermediate_render_pass_create_info, nullptr, + &guest_output_intermediate_render_pass_) != VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to create the guest output intermediate image " + "render pass"); + return false; + } + + // Initialize connection-independent parts of the painting context. + + for (size_t i = 0; i < paint_context_.submissions.size(); ++i) { + paint_context_.submissions[i] = PaintContext::Submission::Create(vulkan_device_); + if (!paint_context_.submissions[i]) { + return false; + } + } + + // Guest output paint pipelines drawing to intermediate images, not depending + // on runtime state unlike ones drawing to the swapchain images as those + // depend on the swapchain format. + for (size_t i = 0; i < size_t(GuestOutputPaintEffect::kCount); ++i) { + if (!CanGuestOutputPaintEffectBeIntermediate(GuestOutputPaintEffect(i)) || + guest_output_paint_fs_[i] == VK_NULL_HANDLE) { + continue; + } + VkPipeline guest_output_paint_intermediate_pipeline = CreateGuestOutputPaintPipeline( + GuestOutputPaintEffect(i), guest_output_intermediate_render_pass_); + if (guest_output_paint_intermediate_pipeline == VK_NULL_HANDLE) { + return false; + } + paint_context_.guest_output_paint_pipelines[i].intermediate_pipeline = + guest_output_paint_intermediate_pipeline; + } + + // Guest output painting descriptor sets. + VkDescriptorPoolSize guest_output_paint_descriptor_pool_sizes[2]; + guest_output_paint_descriptor_pool_sizes[0].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + guest_output_paint_descriptor_pool_sizes[0].descriptorCount = + PaintContext::kGuestOutputDescriptorSetCount; + // Required even when using immutable samplers, otherwise failing to allocate + // descriptor sets (tested on AMD Software: Adrenalin Edition 22.3.2 on + // Windows 10 on AMD Radeon RX Vega 10 with Vulkan validation enabled). + guest_output_paint_descriptor_pool_sizes[1].type = VK_DESCRIPTOR_TYPE_SAMPLER; + guest_output_paint_descriptor_pool_sizes[1].descriptorCount = + PaintContext::kGuestOutputDescriptorSetCount; + VkDescriptorPoolCreateInfo guest_output_paint_descriptor_pool_create_info; + guest_output_paint_descriptor_pool_create_info.sType = + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + guest_output_paint_descriptor_pool_create_info.pNext = nullptr; + guest_output_paint_descriptor_pool_create_info.flags = 0; + guest_output_paint_descriptor_pool_create_info.maxSets = + PaintContext::kGuestOutputDescriptorSetCount; + guest_output_paint_descriptor_pool_create_info.poolSizeCount = + uint32_t(rex::countof(guest_output_paint_descriptor_pool_sizes)); + guest_output_paint_descriptor_pool_create_info.pPoolSizes = + guest_output_paint_descriptor_pool_sizes; + if (dfn.vkCreateDescriptorPool(device, &guest_output_paint_descriptor_pool_create_info, nullptr, + &paint_context_.guest_output_descriptor_pool) != VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to create the guest output painting " + "descriptor pool"); + return false; + } + VkDescriptorSetLayout + guest_output_paint_descriptor_set_layouts[PaintContext::kGuestOutputDescriptorSetCount]; + std::fill(guest_output_paint_descriptor_set_layouts, + guest_output_paint_descriptor_set_layouts + + rex::countof(guest_output_paint_descriptor_set_layouts), + guest_output_paint_image_descriptor_set_layout_); + VkDescriptorSetAllocateInfo guest_output_paint_descriptor_set_allocate_info; + guest_output_paint_descriptor_set_allocate_info.sType = + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + guest_output_paint_descriptor_set_allocate_info.pNext = nullptr; + guest_output_paint_descriptor_set_allocate_info.descriptorPool = + paint_context_.guest_output_descriptor_pool; + guest_output_paint_descriptor_set_allocate_info.descriptorSetCount = + PaintContext::kGuestOutputDescriptorSetCount; + guest_output_paint_descriptor_set_allocate_info.pSetLayouts = + guest_output_paint_descriptor_set_layouts; + if (dfn.vkAllocateDescriptorSets(device, &guest_output_paint_descriptor_set_allocate_info, + paint_context_.guest_output_descriptor_sets) != VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to allocate the guest output painting " + "descriptor sets"); + return false; + } + + return InitializeCommonSurfaceIndependent(); +} + +VkPipeline VulkanPresenter::CreateGuestOutputPaintPipeline(GuestOutputPaintEffect effect, + VkRenderPass render_pass) { + VkPipelineShaderStageCreateInfo stages[2] = {}; + for (uint32_t i = 0; i < 2; ++i) { + VkPipelineShaderStageCreateInfo& stage = stages[i]; + stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stage.stage = i ? VK_SHADER_STAGE_FRAGMENT_BIT : VK_SHADER_STAGE_VERTEX_BIT; + stage.pName = "main"; + } + stages[0].module = guest_output_paint_vs_; + stages[1].module = guest_output_paint_fs_[size_t(effect)]; + assert_true(stages[1].module != VK_NULL_HANDLE); + + VkPipelineVertexInputStateCreateInfo vertex_input_state = {}; + vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + + VkPipelineInputAssemblyStateCreateInfo input_assembly_state = {}; + input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; + + VkPipelineViewportStateCreateInfo viewport_state = {}; + viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + viewport_state.viewportCount = 1; + viewport_state.scissorCount = 1; + + VkPipelineRasterizationStateCreateInfo rasterization_state = {}; + rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rasterization_state.polygonMode = VK_POLYGON_MODE_FILL; + rasterization_state.cullMode = VK_CULL_MODE_NONE; + rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; + rasterization_state.lineWidth = 1.0f; + + VkPipelineMultisampleStateCreateInfo multisample_state = {}; + multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + + VkPipelineColorBlendAttachmentState color_blend_attachment_state = {}; + color_blend_attachment_state.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | + VK_COLOR_COMPONENT_G_BIT | + VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + VkPipelineColorBlendStateCreateInfo color_blend_state = {}; + color_blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + color_blend_state.attachmentCount = 1; + color_blend_state.pAttachments = &color_blend_attachment_state; + + static const VkDynamicState kPipelineDynamicStates[] = { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, + }; + VkPipelineDynamicStateCreateInfo dynamic_state = {}; + dynamic_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynamic_state.dynamicStateCount = uint32_t(rex::countof(kPipelineDynamicStates)); + dynamic_state.pDynamicStates = kPipelineDynamicStates; + + VkGraphicsPipelineCreateInfo pipeline_create_info; + pipeline_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipeline_create_info.pNext = nullptr; + pipeline_create_info.flags = 0; + pipeline_create_info.stageCount = uint32_t(rex::countof(stages)); + pipeline_create_info.pStages = stages; + pipeline_create_info.pVertexInputState = &vertex_input_state; + pipeline_create_info.pInputAssemblyState = &input_assembly_state; + pipeline_create_info.pTessellationState = nullptr; + pipeline_create_info.pViewportState = &viewport_state; + pipeline_create_info.pRasterizationState = &rasterization_state; + pipeline_create_info.pMultisampleState = &multisample_state; + pipeline_create_info.pDepthStencilState = nullptr; + pipeline_create_info.pColorBlendState = &color_blend_state; + pipeline_create_info.pDynamicState = &dynamic_state; + pipeline_create_info.layout = + guest_output_paint_pipeline_layouts_[GetGuestOutputPaintPipelineLayoutIndex(effect)]; + pipeline_create_info.renderPass = render_pass; + pipeline_create_info.subpass = 0; + pipeline_create_info.basePipelineHandle = VK_NULL_HANDLE; + pipeline_create_info.basePipelineIndex = -1; + + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + VkPipeline pipeline; + if (dfn.vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipeline_create_info, nullptr, + &pipeline) != VK_SUCCESS) { + REXLOG_ERROR( + "VulkanPresenter: Failed to create the guest output painting pipeline " + "for effect {}", + size_t(effect)); + return VK_NULL_HANDLE; + } + return pipeline; +} + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/src/ui/vulkan/vulkan_provider.cpp b/src/ui/vulkan/vulkan_provider.cpp new file mode 100644 index 0000000..9eeb902 --- /dev/null +++ b/src/ui/vulkan/vulkan_provider.cpp @@ -0,0 +1,170 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include +#include + +REXCVAR_DEFINE_BOOL(vulkan_validation_enabled, false, "UI/Vulkan", + "Enable Vulkan validation layers") + .lifecycle(rex::cvar::Lifecycle::kInitOnly); + +REXCVAR_DEFINE_INT32(vulkan_device, -1, "UI/Vulkan", "Vulkan device index (-1 for auto selection)") + .lifecycle(rex::cvar::Lifecycle::kInitOnly); + +REXCVAR_DEFINE_BOOL(vulkan_prefer_geometry_shader, true, "UI/Vulkan", + "Prefer physical devices supporting geometryShader when auto-selecting") + .lifecycle(rex::cvar::Lifecycle::kInitOnly); +REXCVAR_DEFINE_BOOL( + vulkan_prefer_fragment_stores_and_atomics, true, "UI/Vulkan", + "Prefer physical devices supporting fragmentStoresAndAtomics when auto-selecting") + .lifecycle(rex::cvar::Lifecycle::kInitOnly); +REXCVAR_DEFINE_BOOL(vulkan_prefer_vertex_pipeline_stores_and_atomics, true, "UI/Vulkan", + "Prefer physical devices supporting vertexPipelineStoresAndAtomics when " + "auto-selecting") + .lifecycle(rex::cvar::Lifecycle::kInitOnly); +REXCVAR_DEFINE_BOOL(vulkan_prefer_fill_mode_non_solid, true, "UI/Vulkan", + "Prefer physical devices supporting fillModeNonSolid when auto-selecting") + .lifecycle(rex::cvar::Lifecycle::kInitOnly); + +namespace rex { +namespace ui { +namespace vulkan { + +std::unique_ptr VulkanProvider::Create(const bool with_gpu_emulation, + const bool with_presentation) { + std::unique_ptr provider(new VulkanProvider()); + + provider->vulkan_instance_ = + VulkanInstance::Create(with_presentation, REXCVAR_GET(vulkan_validation_enabled)); + if (!provider->vulkan_instance_) { + return nullptr; + } + + std::vector physical_devices; + provider->vulkan_instance_->EnumeratePhysicalDevices(physical_devices); + + if (physical_devices.empty()) { + REXLOG_WARN("No Vulkan physical devices available"); + return nullptr; + } + + const VulkanInstance::Functions& ifn = provider->vulkan_instance_->functions(); + + REXLOG_WARN( + "Available Vulkan physical devices (use the 'vulkan_device' " + "configuration variable to force a specific device):"); + for (size_t physical_device_index = 0; physical_device_index < physical_devices.size(); + ++physical_device_index) { + VkPhysicalDeviceProperties physical_device_properties; + ifn.vkGetPhysicalDeviceProperties(physical_devices[physical_device_index], + &physical_device_properties); + REXLOG_WARN("* {}: {}", physical_device_index, physical_device_properties.deviceName); + } + + if (REXCVAR_GET(vulkan_device) >= 0 && + uint32_t(REXCVAR_GET(vulkan_device)) < physical_devices.size()) { + provider->vulkan_device_ = VulkanDevice::CreateIfSupported( + provider->vulkan_instance_.get(), physical_devices[REXCVAR_GET(vulkan_device)], + with_gpu_emulation, with_presentation); + } + + if (!provider->vulkan_device_) { + std::vector physical_devices_ordered = physical_devices; + bool prefer_geometry_shader = REXCVAR_GET(vulkan_prefer_geometry_shader); + bool prefer_fragment_stores = REXCVAR_GET(vulkan_prefer_fragment_stores_and_atomics); + bool prefer_vertex_stores = REXCVAR_GET(vulkan_prefer_vertex_pipeline_stores_and_atomics); + bool prefer_fill_mode_non_solid = REXCVAR_GET(vulkan_prefer_fill_mode_non_solid); + if (with_gpu_emulation && physical_devices.size() > 1 && + (prefer_geometry_shader || prefer_fragment_stores || prefer_vertex_stores || + prefer_fill_mode_non_solid)) { + struct PhysicalDeviceScore { + VkPhysicalDevice physical_device; + uint32_t score; + }; + std::vector scored_devices; + scored_devices.reserve(physical_devices.size()); + for (const VkPhysicalDevice physical_device : physical_devices) { + VkPhysicalDeviceFeatures supported_features = {}; + ifn.vkGetPhysicalDeviceFeatures(physical_device, &supported_features); + uint32_t score = 0; + if (prefer_geometry_shader && supported_features.geometryShader) { + ++score; + } + if (prefer_fragment_stores && supported_features.fragmentStoresAndAtomics) { + ++score; + } + if (prefer_vertex_stores && supported_features.vertexPipelineStoresAndAtomics) { + ++score; + } + if (prefer_fill_mode_non_solid && supported_features.fillModeNonSolid) { + ++score; + } + scored_devices.push_back({physical_device, score}); + } + + std::stable_sort(scored_devices.begin(), scored_devices.end(), + [](const PhysicalDeviceScore& a, const PhysicalDeviceScore& b) { + return a.score > b.score; + }); + + if (!scored_devices.empty() && scored_devices.front().score != scored_devices.back().score) { + physical_devices_ordered.clear(); + physical_devices_ordered.reserve(scored_devices.size()); + for (const PhysicalDeviceScore& scored_device : scored_devices) { + physical_devices_ordered.push_back(scored_device.physical_device); + } + } + } + + for (const VkPhysicalDevice physical_device : physical_devices_ordered) { + provider->vulkan_device_ = VulkanDevice::CreateIfSupported( + provider->vulkan_instance_.get(), physical_device, with_gpu_emulation, with_presentation); + if (provider->vulkan_device_) { + break; + } + } + + if (!provider->vulkan_device_) { + REXLOG_WARN( + "Couldn't choose a compatible Vulkan physical device or initialize a " + "Vulkan logical device"); + return nullptr; + } + } + + if (with_presentation) { + provider->ui_samplers_ = UISamplers::Create(provider->vulkan_device_.get()); + if (!provider->ui_samplers_) { + return nullptr; + } + } + + return provider; +} + +std::unique_ptr VulkanProvider::CreatePresenter( + Presenter::HostGpuLossCallback host_gpu_loss_callback) { + return VulkanPresenter::Create(host_gpu_loss_callback, vulkan_device(), ui_samplers()); +} + +std::unique_ptr VulkanProvider::CreateImmediateDrawer() { + return VulkanImmediateDrawer::Create(vulkan_device(), ui_samplers()); +} + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/src/ui/vulkan/vulkan_submission_tracker.cpp b/src/ui/vulkan/vulkan_submission_tracker.cpp new file mode 100644 index 0000000..07a07b2 --- /dev/null +++ b/src/ui/vulkan/vulkan_submission_tracker.cpp @@ -0,0 +1,172 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include + +namespace rex { +namespace ui { +namespace vulkan { + +VulkanSubmissionTracker::FenceAcquisition::~FenceAcquisition() { + if (!submission_tracker_) { + // Dropped submission or left after std::move. + return; + } + assert_true(submission_tracker_->fence_acquired_ == fence_); + if (fence_ != VK_NULL_HANDLE) { + if (signal_failed_) { + // Left in the unsignaled state. + submission_tracker_->fences_reclaimed_.push_back(fence_); + } else { + // Left in the pending state. + submission_tracker_->fences_pending_.emplace_back(submission_tracker_->submission_current_, + fence_); + } + submission_tracker_->fence_acquired_ = VK_NULL_HANDLE; + } + ++submission_tracker_->submission_current_; +} + +void VulkanSubmissionTracker::Shutdown() { + AwaitAllSubmissionsCompletion(); + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + for (VkFence fence : fences_reclaimed_) { + dfn.vkDestroyFence(device, fence, nullptr); + } + fences_reclaimed_.clear(); + for (const std::pair& fence_pair : fences_pending_) { + dfn.vkDestroyFence(device, fence_pair.second, nullptr); + } + fences_pending_.clear(); + assert_true(fence_acquired_ == VK_NULL_HANDLE); + util::DestroyAndNullHandle(dfn.vkDestroyFence, device, fence_acquired_); +} + +void VulkanSubmissionTracker::FenceAcquisition::SubmissionFailedOrDropped() { + if (!submission_tracker_) { + return; + } + assert_true(submission_tracker_->fence_acquired_ == fence_); + if (fence_ != VK_NULL_HANDLE) { + submission_tracker_->fences_reclaimed_.push_back(fence_); + } + submission_tracker_->fence_acquired_ = VK_NULL_HANDLE; + fence_ = VK_NULL_HANDLE; + // No submission acquisition from now on, don't increment the current + // submission index as well. + submission_tracker_ = VK_NULL_HANDLE; +} + +uint64_t VulkanSubmissionTracker::UpdateAndGetCompletedSubmission() { + if (!fences_pending_.empty()) { + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + while (!fences_pending_.empty()) { + const std::pair& pending_pair = fences_pending_.front(); + assert_true(pending_pair.first > submission_completed_on_gpu_); + if (dfn.vkGetFenceStatus(device, pending_pair.second) != VK_SUCCESS) { + break; + } + fences_reclaimed_.push_back(pending_pair.second); + submission_completed_on_gpu_ = pending_pair.first; + fences_pending_.pop_front(); + } + } + return submission_completed_on_gpu_; +} + +bool VulkanSubmissionTracker::AwaitSubmissionCompletion(uint64_t submission_index) { + // The tracker itself can't give a submission index for a submission that + // hasn't even started being recorded yet, the client has provided a + // completely invalid value or has done overly optimistic math if such an + // index has been obtained somehow. + assert_true(submission_index <= submission_current_); + // Waiting for the current submission is fine if there was a failure or a + // refusal to submit, and the submission index wasn't incremented, but still + // need to release objects referenced in the dropped submission (while + // shutting down, for instance - in this case, waiting for the last successful + // submission, which could have also referenced the objects from the new + // submission - we can't know since the client has already overwritten its + // last usage index, would correctly ensure that GPU usage of the objects is + // not pending). Waiting for successful submissions, but failed signals, will + // result in a true race condition, however, but waiting for the closest + // successful signal is the best approximation - also retrying to signal in + // this case. + // Go from the most recent to wait only for one fence, which includes all the + // preceding ones. + // "Fence signal operations that are defined by vkQueueSubmit additionally + // include in the first synchronization scope all commands that occur earlier + // in submission order." + size_t reclaim_end = fences_pending_.size(); + if (reclaim_end) { + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + while (reclaim_end) { + const std::pair& pending_pair = fences_pending_[reclaim_end - 1]; + assert_true(pending_pair.first > submission_completed_on_gpu_); + if (pending_pair.first <= submission_index) { + // Wait if requested. + if (dfn.vkWaitForFences(device, 1, &pending_pair.second, VK_TRUE, UINT64_MAX) == + VK_SUCCESS) { + break; + } + } + // Just refresh the completed submission. + if (dfn.vkGetFenceStatus(device, pending_pair.second) == VK_SUCCESS) { + break; + } + --reclaim_end; + } + if (reclaim_end) { + submission_completed_on_gpu_ = fences_pending_[reclaim_end - 1].first; + for (; reclaim_end; --reclaim_end) { + fences_reclaimed_.push_back(fences_pending_.front().second); + fences_pending_.pop_front(); + } + } + } + return submission_completed_on_gpu_ == submission_index; +} + +VulkanSubmissionTracker::FenceAcquisition +VulkanSubmissionTracker::AcquireFenceToAdvanceSubmission() { + assert_true(fence_acquired_ == VK_NULL_HANDLE); + // Reclaim fences if the client only gets the completed submission index or + // awaits in special cases such as shutdown. + UpdateAndGetCompletedSubmission(); + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + if (!fences_reclaimed_.empty()) { + VkFence reclaimed_fence = fences_reclaimed_.back(); + if (dfn.vkResetFences(device, 1, &reclaimed_fence) == VK_SUCCESS) { + fence_acquired_ = fences_reclaimed_.back(); + fences_reclaimed_.pop_back(); + } + } + if (fence_acquired_ == VK_NULL_HANDLE) { + VkFenceCreateInfo fence_create_info; + fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fence_create_info.pNext = nullptr; + fence_create_info.flags = 0; + // May fail, a null fence is handled in FenceAcquisition. + dfn.vkCreateFence(device, &fence_create_info, nullptr, &fence_acquired_); + } + return FenceAcquisition(*this, fence_acquired_); +} + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/src/ui/vulkan/vulkan_upload_buffer_pool.cpp b/src/ui/vulkan/vulkan_upload_buffer_pool.cpp new file mode 100644 index 0000000..771019a --- /dev/null +++ b/src/ui/vulkan/vulkan_upload_buffer_pool.cpp @@ -0,0 +1,185 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include + +namespace rex { +namespace ui { +namespace vulkan { + +// Host-visible memory sizes are likely to be internally rounded to +// nonCoherentAtomSize (it's the memory mapping granularity, though as the map +// or flush range must be clamped to the actual allocation size as a special +// case, but it's still unlikely that the allocation won't be aligned to it), so +// try not to waste that padding. +VulkanUploadBufferPool::VulkanUploadBufferPool(const VulkanDevice* const vulkan_device, + const VkBufferUsageFlags usage, + const size_t page_size) + : GraphicsUploadBufferPool(size_t( + rex::round_up(VkDeviceSize(page_size), vulkan_device->properties().nonCoherentAtomSize))), + vulkan_device_(vulkan_device), + usage_(usage) {} + +uint8_t* VulkanUploadBufferPool::Request(uint64_t submission_index, size_t size, size_t alignment, + VkBuffer& buffer_out, VkDeviceSize& offset_out) { + size_t offset; + const VulkanPage* page = static_cast( + GraphicsUploadBufferPool::Request(submission_index, size, alignment, offset)); + if (!page) { + return nullptr; + } + buffer_out = page->buffer_; + offset_out = VkDeviceSize(offset); + return reinterpret_cast(page->mapping_) + offset; +} + +uint8_t* VulkanUploadBufferPool::RequestPartial(uint64_t submission_index, size_t size, + size_t alignment, VkBuffer& buffer_out, + VkDeviceSize& offset_out, VkDeviceSize& size_out) { + size_t offset, size_obtained; + const VulkanPage* page = static_cast(GraphicsUploadBufferPool::RequestPartial( + submission_index, size, alignment, offset, size_obtained)); + if (!page) { + return nullptr; + } + buffer_out = page->buffer_; + offset_out = VkDeviceSize(offset); + size_out = VkDeviceSize(size_obtained); + return reinterpret_cast(page->mapping_) + offset; +} + +GraphicsUploadBufferPool::Page* VulkanUploadBufferPool::CreatePageImplementation() { + if (memory_type_ == kMemoryTypeUnavailable) { + // Don't try to create everything again and again if totally broken. + return nullptr; + } + + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + + VkBufferCreateInfo buffer_create_info; + buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + buffer_create_info.pNext = nullptr; + buffer_create_info.flags = 0; + buffer_create_info.size = VkDeviceSize(page_size_); + buffer_create_info.usage = usage_; + buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + buffer_create_info.queueFamilyIndexCount = 0; + buffer_create_info.pQueueFamilyIndices = nullptr; + VkBuffer buffer; + if (dfn.vkCreateBuffer(device, &buffer_create_info, nullptr, &buffer) != VK_SUCCESS) { + REXLOG_ERROR("Failed to create a Vulkan upload buffer with {} bytes", page_size_); + return nullptr; + } + + if (memory_type_ == kMemoryTypeUnknown) { + VkMemoryRequirements memory_requirements; + dfn.vkGetBufferMemoryRequirements(device, buffer, &memory_requirements); + memory_type_ = util::ChooseHostMemoryType(vulkan_device_->memory_types(), + memory_requirements.memoryTypeBits, false); + if (memory_type_ == UINT32_MAX) { + REXLOG_ERROR( + "No host-visible memory types can store an Vulkan upload buffer with " + "{} bytes", + page_size_); + memory_type_ = kMemoryTypeUnavailable; + dfn.vkDestroyBuffer(device, buffer, nullptr); + return nullptr; + } + allocation_size_ = memory_requirements.size; + if (allocation_size_ > page_size_) { + // Try to occupy the allocation padding. If that's going to require even + // more memory for some reason, don't. + buffer_create_info.size = allocation_size_; + VkBuffer buffer_expanded; + if (dfn.vkCreateBuffer(device, &buffer_create_info, nullptr, &buffer_expanded) == + VK_SUCCESS) { + VkMemoryRequirements memory_requirements_expanded; + dfn.vkGetBufferMemoryRequirements(device, buffer_expanded, &memory_requirements_expanded); + uint32_t memory_type_expanded = util::ChooseHostMemoryType( + vulkan_device_->memory_types(), memory_requirements.memoryTypeBits, false); + if (memory_requirements_expanded.size <= allocation_size_ && + memory_type_expanded != UINT32_MAX) { + page_size_ = size_t(allocation_size_); + allocation_size_ = memory_requirements_expanded.size; + memory_type_ = memory_type_expanded; + dfn.vkDestroyBuffer(device, buffer, nullptr); + buffer = buffer_expanded; + } else { + dfn.vkDestroyBuffer(device, buffer_expanded, nullptr); + } + } + } + } + + VkMemoryAllocateInfo memory_allocate_info; + VkMemoryAllocateInfo* memory_allocate_info_last = &memory_allocate_info; + memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + memory_allocate_info.pNext = nullptr; + memory_allocate_info.allocationSize = allocation_size_; + memory_allocate_info.memoryTypeIndex = memory_type_; + VkMemoryDedicatedAllocateInfo memory_dedicated_allocate_info; + if (vulkan_device_->extensions().ext_1_1_KHR_dedicated_allocation) { + memory_allocate_info_last->pNext = &memory_dedicated_allocate_info; + memory_allocate_info_last = + reinterpret_cast(&memory_dedicated_allocate_info); + memory_dedicated_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO; + memory_dedicated_allocate_info.pNext = nullptr; + memory_dedicated_allocate_info.image = VK_NULL_HANDLE; + memory_dedicated_allocate_info.buffer = buffer; + } + VkDeviceMemory memory; + if (dfn.vkAllocateMemory(device, &memory_allocate_info, nullptr, &memory) != VK_SUCCESS) { + REXLOG_ERROR("Failed to allocate {} bytes of Vulkan upload buffer memory", allocation_size_); + dfn.vkDestroyBuffer(device, buffer, nullptr); + return nullptr; + } + + if (dfn.vkBindBufferMemory(device, buffer, memory, 0) != VK_SUCCESS) { + REXLOG_ERROR("Failed to bind memory to a Vulkan upload buffer with {} bytes", page_size_); + dfn.vkDestroyBuffer(device, buffer, nullptr); + dfn.vkFreeMemory(device, memory, nullptr); + return nullptr; + } + + void* mapping; + if (dfn.vkMapMemory(device, memory, 0, VK_WHOLE_SIZE, 0, &mapping) != VK_SUCCESS) { + REXLOG_ERROR("Failed to map {} bytes of Vulkan upload buffer memory", allocation_size_); + dfn.vkDestroyBuffer(device, buffer, nullptr); + dfn.vkFreeMemory(device, memory, nullptr); + return nullptr; + } + + return new VulkanPage(vulkan_device_, buffer, memory, mapping); +} + +void VulkanUploadBufferPool::FlushPageWrites(Page* page, size_t offset, size_t size) { + util::FlushMappedMemoryRange(vulkan_device_, static_cast(page)->memory_, + memory_type_, VkDeviceSize(offset), allocation_size_, + VkDeviceSize(size)); +} + +VulkanUploadBufferPool::VulkanPage::~VulkanPage() { + const VulkanDevice::Functions& dfn = vulkan_device_->functions(); + const VkDevice device = vulkan_device_->device(); + dfn.vkDestroyBuffer(device, buffer_, nullptr); + // Unmapping is done implicitly when the memory is freed. + dfn.vkFreeMemory(device, memory_, nullptr); +} + +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/src/ui/vulkan/vulkan_util.cpp b/src/ui/vulkan/vulkan_util.cpp new file mode 100644 index 0000000..2106800 --- /dev/null +++ b/src/ui/vulkan/vulkan_util.cpp @@ -0,0 +1,220 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include +#include + +namespace rex { +namespace ui { +namespace vulkan { +namespace util { + +void FlushMappedMemoryRange(const VulkanDevice* const vulkan_device, const VkDeviceMemory memory, + const uint32_t memory_type, const VkDeviceSize offset, + const VkDeviceSize memory_size, const VkDeviceSize size) { + assert_false(size != VK_WHOLE_SIZE && memory_size == VK_WHOLE_SIZE); + assert_true(memory_size == VK_WHOLE_SIZE || offset <= memory_size); + assert_true(memory_size == VK_WHOLE_SIZE || size <= memory_size - offset); + if (!size || (vulkan_device->memory_types().host_coherent & (uint32_t(1) << memory_type))) { + return; + } + VkMappedMemoryRange range; + range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + range.pNext = nullptr; + range.memory = memory; + range.offset = offset; + range.size = size; + const VkDeviceSize non_coherent_atom_size = vulkan_device->properties().nonCoherentAtomSize; + range.offset = offset / non_coherent_atom_size * non_coherent_atom_size; + if (size != VK_WHOLE_SIZE) { + range.size = + std::min(rex::round_up(offset + size, non_coherent_atom_size), memory_size) - range.offset; + } + vulkan_device->functions().vkFlushMappedMemoryRanges(vulkan_device->device(), 1, &range); +} + +bool CreateDedicatedAllocationBuffer(const VulkanDevice* const vulkan_device, + const VkDeviceSize size, const VkBufferUsageFlags usage, + const MemoryPurpose memory_purpose, VkBuffer& buffer_out, + VkDeviceMemory& memory_out, uint32_t* const memory_type_out, + VkDeviceSize* const memory_size_out) { + const VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + VkBufferCreateInfo buffer_create_info; + buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + buffer_create_info.pNext = nullptr; + buffer_create_info.flags = 0; + buffer_create_info.size = size; + buffer_create_info.usage = usage; + buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + buffer_create_info.queueFamilyIndexCount = 0; + buffer_create_info.pQueueFamilyIndices = nullptr; + VkBuffer buffer; + if (dfn.vkCreateBuffer(device, &buffer_create_info, nullptr, &buffer) != VK_SUCCESS) { + return false; + } + + VkMemoryRequirements memory_requirements; + dfn.vkGetBufferMemoryRequirements(device, buffer, &memory_requirements); + uint32_t memory_type = ChooseMemoryType(vulkan_device->memory_types(), + memory_requirements.memoryTypeBits, memory_purpose); + if (memory_type == UINT32_MAX) { + dfn.vkDestroyBuffer(device, buffer, nullptr); + return false; + } + + VkMemoryAllocateInfo memory_allocate_info; + memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + memory_allocate_info.pNext = nullptr; + memory_allocate_info.allocationSize = memory_requirements.size; + memory_allocate_info.memoryTypeIndex = memory_type; + VkMemoryDedicatedAllocateInfo memory_dedicated_allocate_info; + if (vulkan_device->extensions().ext_1_1_KHR_dedicated_allocation) { + memory_dedicated_allocate_info.pNext = memory_allocate_info.pNext; + memory_allocate_info.pNext = &memory_dedicated_allocate_info; + memory_dedicated_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO; + memory_dedicated_allocate_info.pNext = nullptr; + memory_dedicated_allocate_info.image = VK_NULL_HANDLE; + memory_dedicated_allocate_info.buffer = buffer; + } + VkDeviceMemory memory; + if (dfn.vkAllocateMemory(device, &memory_allocate_info, nullptr, &memory) != VK_SUCCESS) { + dfn.vkDestroyBuffer(device, buffer, nullptr); + return false; + } + + if (dfn.vkBindBufferMemory(device, buffer, memory, 0) != VK_SUCCESS) { + dfn.vkDestroyBuffer(device, buffer, nullptr); + dfn.vkFreeMemory(device, memory, nullptr); + return false; + } + + buffer_out = buffer; + memory_out = memory; + if (memory_type_out) { + *memory_type_out = memory_type; + } + if (memory_size_out) { + *memory_size_out = memory_allocate_info.allocationSize; + } + return true; +} + +bool CreateDedicatedAllocationImage(const VulkanDevice* const vulkan_device, + const VkImageCreateInfo& create_info, + const MemoryPurpose memory_purpose, VkImage& image_out, + VkDeviceMemory& memory_out, uint32_t* const memory_type_out, + VkDeviceSize* const memory_size_out) { + const VulkanDevice::Functions& dfn = vulkan_device->functions(); + const VkDevice device = vulkan_device->device(); + + VkImage image; + if (dfn.vkCreateImage(device, &create_info, nullptr, &image) != VK_SUCCESS) { + return false; + } + + VkMemoryRequirements memory_requirements; + dfn.vkGetImageMemoryRequirements(device, image, &memory_requirements); + uint32_t memory_type = ChooseMemoryType(vulkan_device->memory_types(), + memory_requirements.memoryTypeBits, memory_purpose); + if (memory_type == UINT32_MAX) { + dfn.vkDestroyImage(device, image, nullptr); + return false; + } + + VkMemoryAllocateInfo memory_allocate_info; + memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + memory_allocate_info.pNext = nullptr; + memory_allocate_info.allocationSize = memory_requirements.size; + memory_allocate_info.memoryTypeIndex = memory_type; + VkMemoryDedicatedAllocateInfo memory_dedicated_allocate_info; + if (vulkan_device->extensions().ext_1_1_KHR_dedicated_allocation) { + memory_dedicated_allocate_info.pNext = memory_allocate_info.pNext; + memory_allocate_info.pNext = &memory_dedicated_allocate_info; + memory_dedicated_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO; + memory_dedicated_allocate_info.pNext = nullptr; + memory_dedicated_allocate_info.image = image; + memory_dedicated_allocate_info.buffer = VK_NULL_HANDLE; + } + VkDeviceMemory memory; + if (dfn.vkAllocateMemory(device, &memory_allocate_info, nullptr, &memory) != VK_SUCCESS) { + dfn.vkDestroyImage(device, image, nullptr); + return false; + } + + if (dfn.vkBindImageMemory(device, image, memory, 0) != VK_SUCCESS) { + dfn.vkDestroyImage(device, image, nullptr); + dfn.vkFreeMemory(device, memory, nullptr); + return false; + } + + image_out = image; + memory_out = memory; + if (memory_type_out) { + *memory_type_out = memory_type; + } + if (memory_size_out) { + *memory_size_out = memory_allocate_info.allocationSize; + } + return true; +} + +VkPipeline CreateComputePipeline(const VulkanDevice* const vulkan_device, + const VkPipelineLayout layout, const VkShaderModule shader, + const VkSpecializationInfo* const specialization_info, + const char* const entry_point) { + VkComputePipelineCreateInfo pipeline_create_info; + pipeline_create_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; + pipeline_create_info.pNext = nullptr; + pipeline_create_info.flags = 0; + pipeline_create_info.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + pipeline_create_info.stage.pNext = nullptr; + pipeline_create_info.stage.flags = 0; + pipeline_create_info.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT; + pipeline_create_info.stage.module = shader; + pipeline_create_info.stage.pName = entry_point; + pipeline_create_info.stage.pSpecializationInfo = specialization_info; + pipeline_create_info.layout = layout; + pipeline_create_info.basePipelineHandle = VK_NULL_HANDLE; + pipeline_create_info.basePipelineIndex = -1; + VkPipeline pipeline; + if (vulkan_device->functions().vkCreateComputePipelines(vulkan_device->device(), VK_NULL_HANDLE, + 1, &pipeline_create_info, nullptr, + &pipeline) != VK_SUCCESS) { + return VK_NULL_HANDLE; + } + return pipeline; +} + +VkPipeline CreateComputePipeline(const VulkanDevice* const vulkan_device, VkPipelineLayout layout, + const uint32_t* shader_code, size_t shader_code_size_bytes, + const VkSpecializationInfo* specialization_info, + const char* entry_point) { + const VkShaderModule shader = + CreateShaderModule(vulkan_device, shader_code, shader_code_size_bytes); + if (shader == VK_NULL_HANDLE) { + return VK_NULL_HANDLE; + } + const VkPipeline pipeline = + CreateComputePipeline(vulkan_device, layout, shader, specialization_info, entry_point); + vulkan_device->functions().vkDestroyShaderModule(vulkan_device->device(), shader, nullptr); + return pipeline; +} + +} // namespace util +} // namespace vulkan +} // namespace ui +} // namespace rex diff --git a/src/ui/window.cpp b/src/ui/window.cpp new file mode 100644 index 0000000..c813d09 --- /dev/null +++ b/src/ui/window.cpp @@ -0,0 +1,742 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +REXCVAR_DEFINE_INT32(window_width, 0, "UI/Window", + "Startup window width in logical pixels (0 = use app default)") + .range(0, 8192) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_INT32(window_height, 0, "UI/Window", + "Startup window height in logical pixels (0 = use app default)") + .range(0, 8192) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_BOOL(fullscreen, false, "UI/Window", "Start the window in fullscreen mode") + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_INT32(monitor, 0, "UI/Window", + "Monitor index to display on (0 = default, 1 = primary, 2 = " + "second monitor, etc.)") + .range(0, 16) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_INT32(video_mode_width, 1280, "GPU", "Guest video mode width in pixels") + .range(640, 0x0FFF) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_INT32(video_mode_height, 720, "GPU", "Guest video mode height in pixels") + .range(480, 0x0FFF) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_STRING(resolution, "", "GPU", + "Common resolution preset for both guest video mode and startup window (for " + "example: 720p, 1080p, 1440p, 4k, 1280x720)") + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +REXCVAR_DEFINE_DOUBLE(video_mode_refresh_rate, 60.0, "GPU", "Guest video mode refresh rate in Hz") + .range(24.0, 240.0) + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +namespace rex { +namespace ui { + +Window::Window(WindowedAppContext& app_context, const std::string_view title, + uint32_t desired_logical_width, uint32_t desired_logical_height) + : app_context_(app_context), + title_(title), + desired_logical_width_(desired_logical_width), + desired_logical_height_(desired_logical_height) {} + +Window::~Window() { + // In case the implementation didn't need to call EnterDestructor. Though + // that was likely a mistake, so placing an assertion. + assert_true(phase_ == Phase::kDeleting); + EnterDestructor(); + + if (presenter_) { + Presenter* old_presenter = presenter_; + // Null the pointer to prevent an infinite loop between + // SetWindowSurfaceFromUIThread and SetPresenter calling each other. + presenter_ = nullptr; + old_presenter->SetWindowSurfaceFromUIThread(nullptr, nullptr); + presenter_surface_.reset(); + } + + // Right before destruction has finished, after which no interaction with + // *this can be done, notify the destruction receivers that the window is + // being destroyed and that *this is not accessible anymore. + while (innermost_destruction_receiver_) { + innermost_destruction_receiver_->window_ = nullptr; + innermost_destruction_receiver_ = innermost_destruction_receiver_->outer_receiver_; + } +} + +void Window::AddListener(WindowListener* listener) { + assert_not_null(listener); + // Check if already added. + if (std::find(listeners_.cbegin(), listeners_.cend(), listener) != listeners_.cend()) { + return; + } + listeners_.push_back(listener); +} + +void Window::RemoveListener(WindowListener* listener) { + assert_not_null(listener); + auto it = std::find(listeners_.cbegin(), listeners_.cend(), listener); + if (it == listeners_.cend()) { + return; + } + // Actualize the next listener indices after the erasure from the vector. + ListenerIterationContext* iteration_context = innermost_listener_iteration_context_; + if (iteration_context) { + size_t existing_index = size_t(std::distance(listeners_.cbegin(), it)); + while (iteration_context) { + if (iteration_context->next_index > existing_index) { + --iteration_context->next_index; + } + iteration_context = iteration_context->outer_context; + } + } + listeners_.erase(it); +} + +void Window::AddInputListener(WindowInputListener* listener, size_t z_order) { + assert_not_null(listener); + // Check if already added. + for (auto it_existing = input_listeners_.rbegin(); it_existing != input_listeners_.rend(); + ++it_existing) { + if (it_existing->second != listener) { + continue; + } + if (it_existing->first == z_order) { + return; + } + // If removing the listener that is the next in a current listener loop, + // skip it (in a multimap, only one element iterator is invalidated). + InputListenerIterationContext* iteration_context = innermost_input_listener_iteration_context_; + while (iteration_context) { + if (iteration_context->next_iterator == it_existing) { + ++iteration_context->next_iterator; + } + iteration_context = iteration_context->outer_context; + } + input_listeners_.erase(std::prev(it_existing.base())); + // FIXME(Triang3l): Changing the Z order of an existing listener while + // already executing the listeners may cause listeners to be called twice if + // the Z order is lowered from one that has already been processed to one + // below the current one. Because nested listener calls are supported, a + // single last call index can't be associated with a listener to skip it if + // calling twice for the same event (a "not equal to" comparison of the call + // indices will result in the skipping being cancelled in the outer loop if + // an inner one is done, a "greater than" comparison will cause the inner + // loop to effectively terminate all outer ones). + } + auto it_new = std::prev(std::make_reverse_iterator(input_listeners_.emplace(z_order, listener))); + // If adding to layers in between the currently being processed ones (from + // highest to lowest) and the previously next, make sure the new listener is + // executed too. Execution within one layer, however, happens in the reverse + // order of addition, so if adding to the Z layer currently being processed, + // the new listener must not be executed within the loop. But, if adding to + // the next Z layer after the current one, it must be executed immediately. + { + InputListenerIterationContext* iteration_context = innermost_input_listener_iteration_context_; + while (iteration_context) { + if (z_order < iteration_context->current_z_order && + (iteration_context->next_iterator == input_listeners_.crend() || + z_order >= iteration_context->next_iterator->first)) { + iteration_context->next_iterator = it_new; + } + iteration_context = iteration_context->outer_context; + } + } +} + +void Window::RemoveInputListener(WindowInputListener* listener) { + assert_not_null(listener); + for (auto it_existing = input_listeners_.rbegin(); it_existing != input_listeners_.rend(); + ++it_existing) { + if (it_existing->second != listener) { + continue; + } + // If removing the listener that is the next in a current listener loop, + // skip it (in a multimap, only one element iterator is invalidated). + InputListenerIterationContext* iteration_context = innermost_input_listener_iteration_context_; + while (iteration_context) { + if (iteration_context->next_iterator == it_existing) { + ++iteration_context->next_iterator; + } + iteration_context = iteration_context->outer_context; + } + input_listeners_.erase(std::prev(it_existing.base())); + return; + } +} + +bool Window::Open() { + if (phase_ != Phase::kClosedOpenable) { + return true; + } + + // For consistency of the behavior of OpenImpl and the initial On*Update + // that should be called as a result of it, reset the actual state to its + // defaults for a closed window. + // Note that this is performed in Open, not after closing, because there's + // only one entry point for opening a window, while closing may be done + // different ways - by actually closing, by destroying, or by failing to call + // OpenImpl - instead of performing this reset in every possible close case, + // just returning these defaults from the actual state getters if + // HasActualState is false. + actual_physical_width_ = 0; + actual_physical_height_ = 0; + has_focus_ = false; + phase_ = Phase::kOpening; + bool platform_open_result = OpenImpl(); + if (!platform_open_result) { + phase_ = Phase::kClosedOpenable; + return false; + } + if (phase_ != Phase::kOpening) { + // The window was closed mid-opening. + return true; + } + phase_ = Phase::kOpen; + + // Call the listeners (OnOpened with all the new state so the listeners are + // aware that they can start interacting with the open Window, and after that, + // in case certain listeners don't handle OnOpened, but rather, only need the + // more granular callbacks, make sure those callbacks receive the new state + // too) for the actual state of the new window (that may be different than the + // desired, depending on how the platform has interpreted the desired state). + { + MonitorUpdateEvent e(this, true, true); + OnMonitorUpdate(e); + } + { + UISetupEvent e(this, true); + WindowDestructionReceiver destruction_receiver(this); + SendEventToListeners([&e](auto listener) { listener->OnOpened(e); }, destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrListenersUncallable()) { + return true; + } + SendEventToListeners([&e](auto listener) { listener->OnDpiChanged(e); }, destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrListenersUncallable()) { + return true; + } + SendEventToListeners([&e](auto listener) { listener->OnResize(e); }, destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrListenersUncallable()) { + return true; + } + if (HasFocus()) { + SendEventToListeners([&e](auto listener) { listener->OnGotFocus(e); }, destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrListenersUncallable()) { + return true; + } + } + } + + // May now try to create a valid surface (though the window may be in a + // minimized state without the possibility of creating a surface, but that + // will be resolved by the implementation), after OnDpiChanged and OnResize so + // nothing related to painting will be making wrong assumptions about the + // size. + OnSurfaceChanged(true); + + return true; +} + +void Window::SetFullscreen(bool new_fullscreen) { + if (fullscreen_ == new_fullscreen) { + return; + } + fullscreen_ = new_fullscreen; + if (!CanApplyState()) { + return; + } + WindowDestructionReceiver destruction_receiver(this); + ApplyNewFullscreen(); + if (destruction_receiver.IsWindowDestroyedOrStateInapplicable()) { + return; + } +} + +void Window::SetTitle(const std::string_view new_title) { + if (title_ == new_title) { + return; + } + title_ = new_title; + if (!CanApplyState()) { + return; + } + WindowDestructionReceiver destruction_receiver(this); + ApplyNewTitle(); + if (destruction_receiver.IsWindowDestroyedOrStateInapplicable()) { + return; + } +} + +void Window::SetIcon(const void* buffer, size_t size) { + bool reset = !buffer || !size; + WindowDestructionReceiver destruction_receiver(this); + LoadAndApplyIcon(reset ? nullptr : buffer, reset ? 0 : size, CanApplyState()); + if (destruction_receiver.IsWindowDestroyedOrStateInapplicable()) { + return; + } +} + +void Window::SetMainMenu(std::unique_ptr new_main_menu) { + // The primary reason for this comparison (of two unique pointers) is + // nullptr == nullptr. + if (main_menu_ == new_main_menu) { + return; + } + // Keep the old menu object existing while it's still being detached from + // the platform window. + std::unique_ptr old_main_menu = std::move(main_menu_); + main_menu_ = std::move(new_main_menu); + if (!CanApplyState()) { + return; + } + WindowDestructionReceiver destruction_receiver(this); + ApplyNewMainMenu(old_main_menu.get()); + if (destruction_receiver.IsWindowDestroyedOrStateInapplicable()) { + return; + } +} + +void Window::CompleteMainMenuItemsUpdate() { + if (!main_menu_ || !CanApplyState()) { + return; + } + WindowDestructionReceiver destruction_receiver(this); + CompleteMainMenuItemsUpdateImpl(); + if (destruction_receiver.IsWindowDestroyedOrStateInapplicable()) { + return; + } +} + +void Window::SetMainMenuEnabled(bool enabled) { + if (!main_menu_) { + return; + } + // Not comparing to the actual enabled state, it's a part of the MenuItem, not + // the Window. + // In case enabling (or even disabling) causes menu-related events (like + // pressing) that may execute callbacks potentially destroying the Window via + // the outer architecture. + WindowDestructionReceiver destruction_receiver(this); + main_menu_->SetEnabled(enabled); + if (destruction_receiver.IsWindowDestroyed()) { + return; + } + // Modifying the state of the items, notify the implementation so it makes the + // displaying of the main menu consistent. + CompleteMainMenuItemsUpdate(); + if (destruction_receiver.IsWindowDestroyed()) { + return; + } +} + +void Window::CaptureMouse() { + ++mouse_capture_request_count_; + if (!CanApplyState()) { + return; + } + WindowDestructionReceiver destruction_receiver(this); + // Call even if capturing while the mouse is already assumed to be captured, + // in case something has released it in the OS. + ApplyNewMouseCapture(); + if (destruction_receiver.IsWindowDestroyedOrStateInapplicable()) { + return; + } +} + +void Window::ReleaseMouse() { + assert_not_zero(mouse_capture_request_count_); + if (!mouse_capture_request_count_) { + return; + } + if (--mouse_capture_request_count_) { + return; + } + if (!CanApplyState()) { + return; + } + WindowDestructionReceiver destruction_receiver(this); + ApplyNewMouseRelease(); + if (destruction_receiver.IsWindowDestroyedOrStateInapplicable()) { + return; + } +} + +void Window::SetCursorVisibility(CursorVisibility new_cursor_visibility) { + if (cursor_visibility_ == new_cursor_visibility) { + return; + } + CursorVisibility old_cursor_visibility = cursor_visibility_; + cursor_visibility_ = new_cursor_visibility; + if (!CanApplyState()) { + return; + } + WindowDestructionReceiver destruction_receiver(this); + ApplyNewCursorVisibility(old_cursor_visibility); + if (destruction_receiver.IsWindowDestroyedOrStateInapplicable()) { + return; + } +} + +void Window::Focus() { + if (!CanApplyState() || has_focus_) { + return; + } + WindowDestructionReceiver destruction_receiver(this); + FocusImpl(); + if (destruction_receiver.IsWindowDestroyedOrStateInapplicable()) { + return; + } +} + +void Window::SetPresenter(Presenter* presenter) { + if (presenter_ == presenter) { + return; + } + if (presenter_) { + presenter_->SetWindowSurfaceFromUIThread(nullptr, nullptr); + presenter_surface_.reset(); + } + presenter_ = presenter; + if (presenter_) { + presenter_surface_ = CreateSurface(presenter_->GetSupportedSurfaceTypes()); + presenter_->SetWindowSurfaceFromUIThread(this, presenter_surface_.get()); + } +} + +void Window::OnSurfaceChanged(bool new_surface_potentially_exists) { + if (!presenter_) { + return; + } + + // Detach the presenter from the old surface before attaching to the new one. + if (presenter_surface_) { + presenter_->SetWindowSurfaceFromUIThread(this, nullptr); + presenter_surface_.reset(); + } + + if (!new_surface_potentially_exists) { + return; + } + + presenter_surface_ = CreateSurface(presenter_->GetSupportedSurfaceTypes()); + if (presenter_surface_) { + presenter_->SetWindowSurfaceFromUIThread(this, presenter_surface_.get()); + } +} + +void Window::OnBeforeClose(WindowDestructionReceiver& destruction_receiver) { + // Because events are not sent from closed windows, and to make sure the + // window isn't closed while its surface is still attached to the presenter, + // this must be called before doing what constitutes closing in the platform + // implementation, not after. + + bool was_open = phase_ == Phase::kOpen; + bool was_open_or_opening = was_open || phase_ == Phase::kOpening; + assert_true(was_open_or_opening); + if (!was_open_or_opening) { + return; + } + + if (was_open) { + phase_ = Phase::kOpenBeforeClosing; + + // If the window was focused, notify the listeners that focus is being lost + // because the window is being closed (the implementation usually wouldn't + // be sending any events to the listeners after OnClosing even if the OS + // actually sends the focus loss event as part of the closing process). + OnFocusUpdate(false, destruction_receiver); + if (destruction_receiver.IsWindowDestroyed()) { + return; + } + + { + UIEvent e(this); + SendEventToListeners([&e](auto listener) { listener->OnClosing(e); }, destruction_receiver); + if (destruction_receiver.IsWindowDestroyed()) { + return; + } + } + + // Disconnect from the surface without connecting to the new one (after the + // listeners so they don't try to reconnect afterwards). + OnSurfaceChanged(false); + } + + phase_ = Phase::kClosing; +} + +void Window::OnAfterClose() { + assert_true(phase_ == Phase::kClosing); + if (phase_ != Phase::kClosing) { + return; + } + phase_ = (innermost_listener_iteration_context_ || innermost_input_listener_iteration_context_) + ? Phase::kClosedLeavingListeners + : Phase::kClosedOpenable; +} + +void Window::OnDpiChanged(UISetupEvent& e, WindowDestructionReceiver& destruction_receiver) { + SendEventToListeners([&e](auto listener) { listener->OnDpiChanged(e); }, destruction_receiver); + if (destruction_receiver.IsWindowDestroyed()) { + return; + } +} + +void Window::OnMonitorUpdate(MonitorUpdateEvent& e) { + if (presenter_surface_) { + presenter_->OnSurfaceMonitorUpdateFromUIThread(e.old_monitor_potentially_disconnected()); + } +} + +bool Window::OnActualSizeUpdate(uint32_t new_physical_width, uint32_t new_physical_height, + WindowDestructionReceiver& destruction_receiver) { + if (actual_physical_width_ == new_physical_width && + actual_physical_height_ == new_physical_height) { + return false; + } + actual_physical_width_ = new_physical_width; + actual_physical_height_ = new_physical_height; + // The listeners may reference the presenter, update the presenter first. + if (presenter_surface_) { + presenter_->OnSurfaceResizeFromUIThread(); + } + UISetupEvent e(this); + SendEventToListeners([&e](auto listener) { listener->OnResize(e); }, destruction_receiver); + if (destruction_receiver.IsWindowDestroyed()) { + return true; + } + return true; +} + +void Window::OnFocusUpdate(bool new_has_focus, WindowDestructionReceiver& destruction_receiver) { + if (has_focus_ == new_has_focus) { + return; + } + has_focus_ = new_has_focus; + UISetupEvent e(this); + if (has_focus_) { + SendEventToListeners([&e](auto listener) { listener->OnGotFocus(e); }, destruction_receiver); + } else { + SendEventToListeners([&e](auto listener) { listener->OnLostFocus(e); }, destruction_receiver); + } + if (destruction_receiver.IsWindowDestroyed()) { + return; + } +} + +void Window::OnPaint(bool force_paint) { + if (is_painting_) { + return; + } + is_painting_ = true; + if (presenter_surface_) { + presenter_->PaintFromUIThread(force_paint); + } + is_painting_ = false; +} + +void Window::OnFileDrop(FileDropEvent& e, WindowDestructionReceiver& destruction_receiver) { + SendEventToListeners([&e](auto listener) { listener->OnFileDrop(e); }, destruction_receiver); + if (destruction_receiver.IsWindowDestroyed()) { + return; + } +} + +void Window::OnKeyDown(KeyEvent& e, WindowDestructionReceiver& destruction_receiver) { + PropagateEventThroughInputListeners( + [&e](auto listener) { + listener->OnKeyDown(e); + return e.is_handled(); + }, + destruction_receiver); + if (destruction_receiver.IsWindowDestroyed()) { + return; + } +} + +void Window::OnKeyUp(KeyEvent& e, WindowDestructionReceiver& destruction_receiver) { + PropagateEventThroughInputListeners( + [&e](auto listener) { + listener->OnKeyUp(e); + return e.is_handled(); + }, + destruction_receiver); + if (destruction_receiver.IsWindowDestroyed()) { + return; + } +} + +void Window::OnKeyChar(KeyEvent& e, WindowDestructionReceiver& destruction_receiver) { + PropagateEventThroughInputListeners( + [&e](auto listener) { + listener->OnKeyChar(e); + return e.is_handled(); + }, + destruction_receiver); + if (destruction_receiver.IsWindowDestroyed()) { + return; + } +} + +void Window::OnMouseDown(MouseEvent& e, WindowDestructionReceiver& destruction_receiver) { + PropagateEventThroughInputListeners( + [&e](auto listener) { + listener->OnMouseDown(e); + return e.is_handled(); + }, + destruction_receiver); + if (destruction_receiver.IsWindowDestroyed()) { + return; + } +} + +void Window::OnMouseMove(MouseEvent& e, WindowDestructionReceiver& destruction_receiver) { + PropagateEventThroughInputListeners( + [&e](auto listener) { + listener->OnMouseMove(e); + return e.is_handled(); + }, + destruction_receiver); + if (destruction_receiver.IsWindowDestroyed()) { + return; + } +} + +void Window::OnMouseUp(MouseEvent& e, WindowDestructionReceiver& destruction_receiver) { + PropagateEventThroughInputListeners( + [&e](auto listener) { + listener->OnMouseUp(e); + return e.is_handled(); + }, + destruction_receiver); + if (destruction_receiver.IsWindowDestroyed()) { + return; + } +} + +void Window::OnMouseWheel(MouseEvent& e, WindowDestructionReceiver& destruction_receiver) { + PropagateEventThroughInputListeners( + [&e](auto listener) { + listener->OnMouseWheel(e); + return e.is_handled(); + }, + destruction_receiver); + if (destruction_receiver.IsWindowDestroyed()) { + return; + } +} + +void Window::OnTouchEvent(TouchEvent& e, WindowDestructionReceiver& destruction_receiver) { + PropagateEventThroughInputListeners( + [&e](auto listener) { + listener->OnTouchEvent(e); + return e.is_handled(); + }, + destruction_receiver); + if (destruction_receiver.IsWindowDestroyed()) { + return; + } +} + +void Window::SendEventToListeners(std::function fn, + WindowDestructionReceiver& destruction_receiver) { + if (!CanSendEventsToListeners()) { + return; + } + ListenerIterationContext iteration_context(innermost_listener_iteration_context_); + innermost_listener_iteration_context_ = &iteration_context; + while (iteration_context.next_index < listeners_.size()) { + // iteration_context.next_index may be changed during the execution of the + // listener if the list of the listeners is modified by it - don't assume + // that after the call iteration_context.next_index will be the same as + // iteration_context.next_index + 1 before it. + fn(listeners_[iteration_context.next_index++]); + if (destruction_receiver.IsWindowDestroyed()) { + // The window was destroyed by the listener, can't access anything in + // *this anymore, including innermost_listener_iteration_context_ which + // has to be left in an indeterminate state. + return; + } + if (!CanSendEventsToListeners()) { + // The listener has put the window in a state in which the window can't + // send events anymore. + break; + } + } + assert_true(innermost_listener_iteration_context_ == &iteration_context); + innermost_listener_iteration_context_ = innermost_listener_iteration_context_->outer_context; + if (phase_ == Phase::kClosedLeavingListeners && !innermost_listener_iteration_context_ && + !innermost_input_listener_iteration_context_) { + phase_ = Phase::kClosedOpenable; + } +} + +void Window::PropagateEventThroughInputListeners(std::function fn, + WindowDestructionReceiver& destruction_receiver) { + if (!CanSendEventsToListeners()) { + return; + } + InputListenerIterationContext iteration_context(innermost_input_listener_iteration_context_, + input_listeners_.crbegin()); + innermost_input_listener_iteration_context_ = &iteration_context; + while (iteration_context.next_iterator != input_listeners_.crend()) { + // The current iterator may be invalidated, and + // iteration_context.next_iterator may be changed, during the execution of + // the listener if the list of the listeners is modified by it - don't + // assume that after the call iteration_context.next_iterator will be the + // same as std::next(iteration_context.next_iterator) before it. + iteration_context.current_z_order = iteration_context.next_iterator->first; + bool event_handled = fn((iteration_context.next_iterator++)->second); + if (destruction_receiver.IsWindowDestroyed()) { + // The window was destroyed by the listener, can't access anything in + // *this anymore, including innermost_listener_iteration_context_ which + // has to be left in an indeterminate state. + return; + } + if (event_handled) { + break; + } + if (!CanSendEventsToListeners()) { + // The listener has put the window in a state in which the window can't + // send events anymore. + break; + } + } + assert_true(innermost_input_listener_iteration_context_ == &iteration_context); + innermost_input_listener_iteration_context_ = + innermost_input_listener_iteration_context_->outer_context; + if (phase_ == Phase::kClosedLeavingListeners && !innermost_listener_iteration_context_ && + !innermost_input_listener_iteration_context_) { + phase_ = Phase::kClosedOpenable; + } +} + +} // namespace ui +} // namespace rex diff --git a/src/ui/window_gtk.cpp b/src/ui/window_gtk.cpp new file mode 100644 index 0000000..f729067 --- /dev/null +++ b/src/ui/window_gtk.cpp @@ -0,0 +1,963 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace { + +uint32_t ResolveWindowWidth(uint32_t requested_width) { + if (REXCVAR_GET(window_width) > 0) { + return uint32_t(REXCVAR_GET(window_width)); + } + if (!rex::cvar::HasNonDefaultValue("window_width")) { + if (rex::cvar::HasNonDefaultValue("video_mode_width") && REXCVAR_GET(video_mode_width) > 0) { + return uint32_t(std::clamp(REXCVAR_GET(video_mode_width), 1, 8192)); + } + int32_t preset_width = 0; + int32_t preset_height = 0; + if (rex::graphics::video_mode_util::TryGetResolutionPresetFromCVar(preset_width, + preset_height)) { + return uint32_t(std::clamp(preset_width, 1, 8192)); + } + } + return requested_width; +} + +uint32_t ResolveWindowHeight(uint32_t requested_height) { + if (REXCVAR_GET(window_height) > 0) { + return uint32_t(REXCVAR_GET(window_height)); + } + if (!rex::cvar::HasNonDefaultValue("window_height")) { + if (rex::cvar::HasNonDefaultValue("video_mode_height") && REXCVAR_GET(video_mode_height) > 0) { + return uint32_t(std::clamp(REXCVAR_GET(video_mode_height), 1, 8192)); + } + int32_t preset_width = 0; + int32_t preset_height = 0; + if (rex::graphics::video_mode_util::TryGetResolutionPresetFromCVar(preset_width, + preset_height)) { + return uint32_t(std::clamp(preset_height, 1, 8192)); + } + } + return requested_height; +} + +using rex::ui::VirtualKey; + +VirtualKey TranslateGdkKeyvalToVirtualKey(guint keyval) { + switch (keyval) { + // Function keys. + case GDK_KEY_F1: + return VirtualKey::kF1; + case GDK_KEY_F2: + return VirtualKey::kF2; + case GDK_KEY_F3: + return VirtualKey::kF3; + case GDK_KEY_F4: + return VirtualKey::kF4; + case GDK_KEY_F5: + return VirtualKey::kF5; + case GDK_KEY_F6: + return VirtualKey::kF6; + case GDK_KEY_F7: + return VirtualKey::kF7; + case GDK_KEY_F8: + return VirtualKey::kF8; + case GDK_KEY_F9: + return VirtualKey::kF9; + case GDK_KEY_F10: + return VirtualKey::kF10; + case GDK_KEY_F11: + return VirtualKey::kF11; + case GDK_KEY_F12: + return VirtualKey::kF12; + case GDK_KEY_F13: + return VirtualKey::kF13; + case GDK_KEY_F14: + return VirtualKey::kF14; + case GDK_KEY_F15: + return VirtualKey::kF15; + case GDK_KEY_F16: + return VirtualKey::kF16; + case GDK_KEY_F17: + return VirtualKey::kF17; + case GDK_KEY_F18: + return VirtualKey::kF18; + case GDK_KEY_F19: + return VirtualKey::kF19; + case GDK_KEY_F20: + return VirtualKey::kF20; + case GDK_KEY_F21: + return VirtualKey::kF21; + case GDK_KEY_F22: + return VirtualKey::kF22; + case GDK_KEY_F23: + return VirtualKey::kF23; + case GDK_KEY_F24: + return VirtualKey::kF24; + + // Control and navigation. + case GDK_KEY_Escape: + return VirtualKey::kEscape; + case GDK_KEY_Return: + case GDK_KEY_ISO_Enter: + case GDK_KEY_KP_Enter: + return VirtualKey::kReturn; + case GDK_KEY_space: + case GDK_KEY_KP_Space: + return VirtualKey::kSpace; + case GDK_KEY_Tab: + case GDK_KEY_ISO_Left_Tab: + return VirtualKey::kTab; + case GDK_KEY_BackSpace: + return VirtualKey::kBack; + case GDK_KEY_Delete: + case GDK_KEY_KP_Delete: + return VirtualKey::kDelete; + case GDK_KEY_Insert: + case GDK_KEY_KP_Insert: + return VirtualKey::kInsert; + case GDK_KEY_Home: + case GDK_KEY_KP_Home: + return VirtualKey::kHome; + case GDK_KEY_End: + case GDK_KEY_KP_End: + return VirtualKey::kEnd; + case GDK_KEY_Page_Up: + case GDK_KEY_KP_Page_Up: + return VirtualKey::kPrior; + case GDK_KEY_Page_Down: + case GDK_KEY_KP_Page_Down: + return VirtualKey::kNext; + case GDK_KEY_Left: + case GDK_KEY_KP_Left: + return VirtualKey::kLeft; + case GDK_KEY_Right: + case GDK_KEY_KP_Right: + return VirtualKey::kRight; + case GDK_KEY_Up: + case GDK_KEY_KP_Up: + return VirtualKey::kUp; + case GDK_KEY_Down: + case GDK_KEY_KP_Down: + return VirtualKey::kDown; + + // Modifiers and lock keys. + case GDK_KEY_Shift_L: + case GDK_KEY_Shift_R: + return VirtualKey::kShift; + case GDK_KEY_Control_L: + case GDK_KEY_Control_R: + return VirtualKey::kControl; + case GDK_KEY_Alt_L: + case GDK_KEY_Alt_R: + case GDK_KEY_Meta_L: + case GDK_KEY_Meta_R: + return VirtualKey::kMenu; + case GDK_KEY_Super_L: + return VirtualKey::kLWin; + case GDK_KEY_Super_R: + return VirtualKey::kRWin; + case GDK_KEY_Menu: + return VirtualKey::kApps; + case GDK_KEY_Caps_Lock: + return VirtualKey::kCapital; + case GDK_KEY_Num_Lock: + return VirtualKey::kNumLock; + case GDK_KEY_Scroll_Lock: + return VirtualKey::kScroll; + case GDK_KEY_Print: + return VirtualKey::kSnapshot; + case GDK_KEY_Pause: + return VirtualKey::kPause; + + // Numeric row. + case GDK_KEY_0: + return VirtualKey::k0; + case GDK_KEY_1: + return VirtualKey::k1; + case GDK_KEY_2: + return VirtualKey::k2; + case GDK_KEY_3: + return VirtualKey::k3; + case GDK_KEY_4: + return VirtualKey::k4; + case GDK_KEY_5: + return VirtualKey::k5; + case GDK_KEY_6: + return VirtualKey::k6; + case GDK_KEY_7: + return VirtualKey::k7; + case GDK_KEY_8: + return VirtualKey::k8; + case GDK_KEY_9: + return VirtualKey::k9; + + // Numpad. + case GDK_KEY_KP_0: + return VirtualKey::kNumpad0; + case GDK_KEY_KP_1: + return VirtualKey::kNumpad1; + case GDK_KEY_KP_2: + return VirtualKey::kNumpad2; + case GDK_KEY_KP_3: + return VirtualKey::kNumpad3; + case GDK_KEY_KP_4: + return VirtualKey::kNumpad4; + case GDK_KEY_KP_5: + return VirtualKey::kNumpad5; + case GDK_KEY_KP_6: + return VirtualKey::kNumpad6; + case GDK_KEY_KP_7: + return VirtualKey::kNumpad7; + case GDK_KEY_KP_8: + return VirtualKey::kNumpad8; + case GDK_KEY_KP_9: + return VirtualKey::kNumpad9; + case GDK_KEY_KP_Add: + return VirtualKey::kAdd; + case GDK_KEY_KP_Subtract: + return VirtualKey::kSubtract; + case GDK_KEY_KP_Multiply: + return VirtualKey::kMultiply; + case GDK_KEY_KP_Divide: + return VirtualKey::kDivide; + case GDK_KEY_KP_Decimal: + return VirtualKey::kDecimal; + + // Punctuation. + case GDK_KEY_grave: + case GDK_KEY_asciitilde: + return VirtualKey::kOem3; + case GDK_KEY_minus: + case GDK_KEY_underscore: + return VirtualKey::kOemMinus; + case GDK_KEY_equal: + case GDK_KEY_plus: + return VirtualKey::kOemPlus; + case GDK_KEY_comma: + case GDK_KEY_less: + return VirtualKey::kOemComma; + case GDK_KEY_period: + case GDK_KEY_greater: + return VirtualKey::kOemPeriod; + case GDK_KEY_semicolon: + case GDK_KEY_colon: + return VirtualKey::kOem1; + case GDK_KEY_slash: + case GDK_KEY_question: + return VirtualKey::kOem2; + case GDK_KEY_backslash: + case GDK_KEY_bar: + return VirtualKey::kOem5; + case GDK_KEY_bracketleft: + case GDK_KEY_braceleft: + return VirtualKey::kOem4; + case GDK_KEY_bracketright: + case GDK_KEY_braceright: + return VirtualKey::kOem6; + case GDK_KEY_apostrophe: + case GDK_KEY_quotedbl: + return VirtualKey::kOem7; + + default: + break; + } + + if (keyval >= GDK_KEY_a && keyval <= GDK_KEY_z) { + return VirtualKey(uint16_t(VirtualKey::kA) + uint16_t(keyval - GDK_KEY_a)); + } + if (keyval >= GDK_KEY_A && keyval <= GDK_KEY_Z) { + return VirtualKey(uint16_t(VirtualKey::kA) + uint16_t(keyval - GDK_KEY_A)); + } + + return VirtualKey::kNone; +} + +} // namespace + +namespace rex { +namespace ui { + +std::unique_ptr Window::Create(WindowedAppContext& app_context, + const std::string_view title, uint32_t desired_logical_width, + uint32_t desired_logical_height) { + desired_logical_width = ResolveWindowWidth(desired_logical_width); + desired_logical_height = ResolveWindowHeight(desired_logical_height); + return std::make_unique(app_context, title, desired_logical_width, + desired_logical_height); +} + +GTKWindow::GTKWindow(WindowedAppContext& app_context, const std::string_view title, + uint32_t desired_logical_width, uint32_t desired_logical_height) + : Window(app_context, title, desired_logical_width, desired_logical_height) {} + +GTKWindow::~GTKWindow() { + EnterDestructor(); + if (window_) { + // Set window_ to null to ignore events from now on since this ui::GTKWindow + // is entering an indeterminate state. + GtkWidget* window = window_; + window_ = nullptr; + // Destroying the top-level window also destroys its children. + drawing_area_ = nullptr; + box_ = nullptr; + gtk_widget_destroy(window); + } +} + +bool GTKWindow::OpenImpl() { + window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL); + + gtk_window_set_title(GTK_WINDOW(window_), GetTitle().c_str()); + + // Create the vertical box container for the main menu and the drawing area. + box_ = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_container_add(GTK_CONTAINER(window_), box_); + + // Add the main menu (even if fullscreen was requested, for the initial layout + // calculation). + const GTKMenuItem* main_menu = static_cast(GetMainMenu()); + GtkWidget* main_menu_widget = main_menu ? main_menu->handle() : nullptr; + if (main_menu_widget) { + gtk_box_pack_start(GTK_BOX(box_), main_menu_widget, FALSE, FALSE, 0); + } + + // Create the drawing area for creating the surface for, which will be the + // client area of the window occupying all the window space not taken by the + // main menu. + drawing_area_ = gtk_drawing_area_new(); + gtk_box_pack_end(GTK_BOX(box_), drawing_area_, TRUE, TRUE, 0); + // The desired size is the client (drawing) area size. Let GTK auto-size the + // entire window around it (as well as the width of the menu actually if it + // happens to be bigger - the desired size in the Window will be updated later + // to reflect that). + gtk_widget_set_size_request(drawing_area_, GetDesiredLogicalWidth(), GetDesiredLogicalHeight()); + + // Attach the event handlers. + // Keyboard events are processed by the window, mouse events are processed + // within, and by, the drawing (client) area. + gtk_widget_set_events(window_, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_FOCUS_CHANGE_MASK); + gtk_widget_set_events(drawing_area_, GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK | + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | + GDK_SCROLL_MASK); + g_signal_connect(G_OBJECT(window_), "event", G_CALLBACK(WindowEventHandlerThunk), + reinterpret_cast(this)); + g_signal_connect(G_OBJECT(drawing_area_), "event", G_CALLBACK(DrawingAreaEventHandlerThunk), + reinterpret_cast(this)); + g_signal_connect(G_OBJECT(drawing_area_), "draw", G_CALLBACK(DrawHandler), + reinterpret_cast(this)); + + // Finally show all the widgets in the window, including the main menu. + gtk_widget_show_all(window_); + + // Remove the size request after finishing the initial layout because it makes + // it impossible to make the window smaller. + gtk_widget_set_size_request(drawing_area_, -1, -1); + + // Move the window to the requested monitor before entering fullscreen. + if (int32_t monitor_index = REXCVAR_GET(monitor); monitor_index > 0) { + GdkDisplay* display = gtk_widget_get_display(window_); + GdkScreen* screen = gdk_display_get_default_screen(display); + int n_monitors = gdk_screen_get_n_monitors(screen); + if (monitor_index <= n_monitors) { + GdkRectangle geom; + gdk_screen_get_monitor_geometry(screen, monitor_index - 1, &geom); + gtk_window_move(GTK_WINDOW(window_), geom.x + (geom.width - GetDesiredLogicalWidth()) / 2, + geom.y + (geom.height - GetDesiredLogicalHeight()) / 2); + } + } + + // After setting up the initial layout for non-fullscreen, enter fullscreen if + // requested. + if (IsFullscreen()) { + if (main_menu_widget) { + gtk_container_remove(GTK_CONTAINER(box_), main_menu_widget); + } + gtk_window_fullscreen(GTK_WINDOW(window_)); + } + + // Make sure the initial state after opening is reported to the common Window + // class no matter how GTK sends the events. + { + WindowDestructionReceiver destruction_receiver(this); + + // TODO(Triang3l): Report the desired client area size. + + GtkAllocation drawing_area_allocation; + gtk_widget_get_allocation(drawing_area_, &drawing_area_allocation); + OnActualSizeUpdate(uint32_t(drawing_area_allocation.width), + uint32_t(drawing_area_allocation.height), destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + return true; + } + + if (gtk_window_has_toplevel_focus(GTK_WINDOW(window_))) { + OnFocusUpdate(true, destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + return true; + } + } + } + + return true; +} + +void GTKWindow::RequestCloseImpl() { + gtk_window_close(GTK_WINDOW(window_)); +} + +void GTKWindow::ApplyNewFullscreen() { + // Various functions here may trigger events that may result in the listeners + // being invoked, and potentially cause the destruction of the window or + // fullscreen being toggled from inside this function. + WindowDestructionReceiver destruction_receiver(this); + + const GTKMenuItem* main_menu = static_cast(GetMainMenu()); + GtkWidget* main_menu_widget = main_menu ? main_menu->handle() : nullptr; + + // Changing the menu and the fullscreen state may change the size of the + // drawing area too, don't handle the resize multiple times (also potentially + // with the listeners changing the desired fullscreen if called from the + // handling of some event like GDK_CONFIGURE). + BeginBatchedSizeUpdate(); + + if (IsFullscreen()) { + if (main_menu_widget) { + gtk_container_remove(GTK_CONTAINER(box_), main_menu_widget); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + if (!destruction_receiver.IsWindowDestroyed()) { + EndBatchedSizeUpdate(destruction_receiver); + } + return; + } + } + gtk_window_fullscreen(GTK_WINDOW(window_)); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + if (!destruction_receiver.IsWindowDestroyed()) { + EndBatchedSizeUpdate(destruction_receiver); + } + return; + } + } else { + gtk_window_unfullscreen(GTK_WINDOW(window_)); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + if (!destruction_receiver.IsWindowDestroyed()) { + EndBatchedSizeUpdate(destruction_receiver); + } + return; + } + if (main_menu_widget) { + gtk_box_pack_start(GTK_BOX(box_), main_menu_widget, FALSE, FALSE, 0); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + if (!destruction_receiver.IsWindowDestroyed()) { + EndBatchedSizeUpdate(destruction_receiver); + } + return; + } + // If the new menu is used for the first time, it will be in the hidden + // state initially. The menu might have been changed while in fullscreen + // without having shown it. + gtk_widget_show_all(main_menu_widget); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + if (!destruction_receiver.IsWindowDestroyed()) { + EndBatchedSizeUpdate(destruction_receiver); + } + return; + } + } + } + + EndBatchedSizeUpdate(destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + return; + } +} + +void GTKWindow::ApplyNewTitle() { + gtk_window_set_title(GTK_WINDOW(window_), GetTitle().c_str()); +} + +void GTKWindow::ApplyNewMainMenu(MenuItem* old_main_menu) { + if (IsFullscreen()) { + // The menu will be set when exiting fullscreen. + return; + } + // The fullscreen state may have been changed by some callback invoked, such + // as the configure (resize) one, recheck it after making changes also. + + WindowDestructionReceiver destruction_receiver(this); + + // Changing the menu may change the size of the drawing area too, and here the + // menu may be changed twice (to detach the old one and to attach the new), + // don't handle the resize multiple times. + BeginBatchedSizeUpdate(); + + if (old_main_menu) { + const GTKMenuItem& old_gtk_main_menu = *static_cast(old_main_menu); + gtk_container_remove(GTK_CONTAINER(box_), old_gtk_main_menu.handle()); + if (destruction_receiver.IsWindowDestroyedOrClosed() || IsFullscreen()) { + if (!destruction_receiver.IsWindowDestroyed()) { + EndBatchedSizeUpdate(destruction_receiver); + } + return; + } + } + + const GTKMenuItem* new_main_menu = static_cast(GetMainMenu()); + if (!new_main_menu) { + EndBatchedSizeUpdate(destruction_receiver); + return; + } + GtkWidget* new_main_menu_widget = new_main_menu->handle(); + gtk_box_pack_start(GTK_BOX(box_), new_main_menu_widget, FALSE, FALSE, 0); + if (destruction_receiver.IsWindowDestroyedOrClosed() || IsFullscreen()) { + if (!destruction_receiver.IsWindowDestroyed()) { + EndBatchedSizeUpdate(destruction_receiver); + } + return; + } + // If the new menu is used for the first time, it will be in the hidden state + // initially. + gtk_widget_show_all(new_main_menu_widget); + if (destruction_receiver.IsWindowDestroyedOrClosed() || IsFullscreen()) { + if (!destruction_receiver.IsWindowDestroyed()) { + EndBatchedSizeUpdate(destruction_receiver); + } + return; + } + + EndBatchedSizeUpdate(destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + return; + } +} + +void GTKWindow::FocusImpl() { + gtk_window_activate_focus(GTK_WINDOW(window_)); +} + +std::unique_ptr GTKWindow::CreateSurfaceImpl(Surface::TypeFlags allowed_types) { + GdkDisplay* display = gtk_widget_get_display(window_); + GdkWindow* drawing_area_window = gtk_widget_get_window(drawing_area_); + bool type_known = false; + bool type_supported_by_display = false; + if (allowed_types & Surface::kTypeFlag_XcbWindow) { + type_known = true; + if (GDK_IS_X11_DISPLAY(display)) { + type_supported_by_display = true; + return std::make_unique( + XGetXCBConnection(gdk_x11_display_get_xdisplay(display)), + gdk_x11_window_get_xid(drawing_area_window)); + } + } + // TODO(Triang3l): Wayland surface. + if (type_known && !type_supported_by_display) { + REXLOG_ERROR( + "GTKWindow: The window system of the GTK window is not supported by " + "Xenia"); + } + return nullptr; +} + +void GTKWindow::RequestPaintImpl() { + gtk_widget_queue_draw(drawing_area_); +} + +void GTKWindow::HandleSizeUpdate(WindowDestructionReceiver& destruction_receiver) { + if (!drawing_area_) { + // Batched size update ended when the window has already been closed, for + // instance. + return; + } + + // TODO(Triang3l): Report the desired client area size. + + GtkAllocation drawing_area_allocation; + gtk_widget_get_allocation(drawing_area_, &drawing_area_allocation); + OnActualSizeUpdate(uint32_t(drawing_area_allocation.width), + uint32_t(drawing_area_allocation.height), destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + return; + } +} + +void GTKWindow::BeginBatchedSizeUpdate() { + // It's okay if batched_size_update_contained_* are not false when beginning + // a batched update, in case the new batched update was started by a window + // listener called from within EndBatchedSizeUpdate. + ++batched_size_update_depth_; +} + +void GTKWindow::EndBatchedSizeUpdate(WindowDestructionReceiver& destruction_receiver) { + assert_not_zero(batched_size_update_depth_); + if (--batched_size_update_depth_) { + return; + } + // Resetting batched_size_update_contained_* in closing, not opening, because + // a listener may start a new batch, and finish it, and there won't be need to + // handle the deferred messages twice. + if (batched_size_update_contained_configure_) { + batched_size_update_contained_configure_ = false; + HandleSizeUpdate(destruction_receiver); + if (destruction_receiver.IsWindowDestroyed()) { + return; + } + } + if (batched_size_update_contained_draw_) { + batched_size_update_contained_draw_ = false; + RequestPaint(); + } +} + +bool GTKWindow::HandleMouse(GdkEvent* event, WindowDestructionReceiver& destruction_receiver) { + MouseEvent::Button button = MouseEvent::Button::kNone; + int32_t x = 0; + int32_t y = 0; + int32_t scroll_x = 0; + int32_t scroll_y = 0; + switch (event->type) { + case GDK_MOTION_NOTIFY: { + auto motion_event = reinterpret_cast(event); + x = motion_event->x; + y = motion_event->y; + } break; + case GDK_BUTTON_PRESS: + case GDK_BUTTON_RELEASE: { + auto button_event = reinterpret_cast(event); + switch (button_event->button) { + case 1: + button = MouseEvent::Button::kLeft; + break; + case 2: + button = MouseEvent::Button::kMiddle; + break; + case 3: + button = MouseEvent::Button::kRight; + break; + case 4: + button = MouseEvent::Button::kX1; + break; + case 5: + button = MouseEvent::Button::kX2; + break; + default: + // Still handle the movement. + break; + } + x = button_event->x; + y = button_event->y; + } break; + case GDK_SCROLL: { + auto scroll_event = reinterpret_cast(event); + x = scroll_event->x; + y = scroll_event->y; + scroll_x = scroll_event->delta_x * MouseEvent::kScrollPerDetent; + // In GDK, positive is towards the bottom of the screen, not forward from + // the user. + scroll_y = -scroll_event->delta_y * MouseEvent::kScrollPerDetent; + } break; + default: + return false; + } + + MouseEvent e(this, button, x, y, scroll_x, scroll_y); + switch (event->type) { + case GDK_MOTION_NOTIFY: + OnMouseMove(e, destruction_receiver); + break; + case GDK_BUTTON_PRESS: + OnMouseDown(e, destruction_receiver); + break; + case GDK_BUTTON_RELEASE: + OnMouseUp(e, destruction_receiver); + break; + case GDK_SCROLL: + OnMouseWheel(e, destruction_receiver); + break; + default: + break; + } + // Returning immediately anyway - no need to check + // destruction_receiver.IsWindowDestroyed(). + return e.is_handled(); +} + +bool GTKWindow::HandleKeyboard(GdkEventKey* event, + WindowDestructionReceiver& destruction_receiver) { + unsigned int modifiers = event->state; + bool shift_pressed = modifiers & GDK_SHIFT_MASK; + bool ctrl_pressed = modifiers & GDK_CONTROL_MASK; + bool alt_pressed = modifiers & (GDK_MOD1_MASK | GDK_META_MASK); + bool super_pressed = modifiers & GDK_SUPER_MASK; + uint32_t key_char = gdk_keyval_to_unicode(event->keyval); + KeyEvent e(this, TranslateGdkKeyvalToVirtualKey(event->keyval), 1, event->type == GDK_KEY_RELEASE, + shift_pressed, ctrl_pressed, alt_pressed, super_pressed); + switch (event->type) { + case GDK_KEY_PRESS: + OnKeyDown(e, destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + return e.is_handled(); + } + if (key_char > 0) { + KeyEvent char_event(this, VirtualKey(key_char), 1, false, shift_pressed, ctrl_pressed, + alt_pressed, super_pressed); + OnKeyChar(char_event, destruction_receiver); + if (char_event.is_handled()) { + e.set_handled(true); + } + } + break; + case GDK_KEY_RELEASE: + OnKeyUp(e, destruction_receiver); + break; + default: + break; + } + // Returning immediately anyway - no need to check + // destruction_receiver.IsWindowDestroyed(). + return e.is_handled(); +} + +gboolean GTKWindow::WindowEventHandler(GdkEvent* event) { + switch (event->type) { + case GDK_DELETE: + // In case the widget was somehow forcibly destroyed without GDK_DELETE. + case GDK_DESTROY: { + WindowDestructionReceiver destruction_receiver(this); + OnBeforeClose(destruction_receiver); + if (destruction_receiver.IsWindowDestroyed()) { + break; + } + // Set window_ to null to ignore events from now on since this + // ui::GTKWindow is entering an indeterminate state - this should be done + // at some point in closing anyway. + GtkWidget* window = window_; + window_ = nullptr; + // Destroying the top-level window also destroys its children. + drawing_area_ = nullptr; + box_ = nullptr; + if (event->type != GDK_DESTROY) { + gtk_widget_destroy(window); + } + OnAfterClose(); + } break; + + case GDK_FOCUS_CHANGE: { + auto focus_event = reinterpret_cast(event); + WindowDestructionReceiver destruction_receiver(this); + OnFocusUpdate(bool(focus_event->in), destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + break; + } + } break; + + case GDK_KEY_PRESS: + case GDK_KEY_RELEASE: { + WindowDestructionReceiver destruction_receiver(this); + HandleKeyboard(reinterpret_cast(event), destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + break; + } + } break; + + default: + break; + } + + // The window might have been destroyed by the handlers, don't interact with + // *this in this function from now on. + + return GDK_EVENT_PROPAGATE; +} + +gboolean GTKWindow::WindowEventHandlerThunk(GtkWidget* widget, GdkEvent* event, + gpointer user_data) { + GTKWindow* window = reinterpret_cast(user_data); + if (!window || widget != window->window_ || + reinterpret_cast(event)->window != + gtk_widget_get_window(window->window_)) { + return GDK_EVENT_PROPAGATE; + } + return window->WindowEventHandler(event); +} + +gboolean GTKWindow::DrawingAreaEventHandler(GdkEvent* event) { + switch (event->type) { + case GDK_MOTION_NOTIFY: + case GDK_BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + case GDK_SCROLL: { + WindowDestructionReceiver destruction_receiver(this); + HandleMouse(event, destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + break; + } + } break; + + case GDK_CONFIGURE: { + if (batched_size_update_depth_) { + batched_size_update_contained_configure_ = true; + } else { + WindowDestructionReceiver destruction_receiver(this); + HandleSizeUpdate(destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + break; + } + } + } break; + default: + break; + } + + // The window might have been destroyed by the handlers, don't interact with + // *this in this function from now on. + + return GDK_EVENT_PROPAGATE; +} + +gboolean GTKWindow::DrawingAreaEventHandlerThunk(GtkWidget* widget, GdkEvent* event, + gpointer user_data) { + GTKWindow* window = reinterpret_cast(user_data); + if (!window || widget != window->drawing_area_ || + reinterpret_cast(event)->window != + gtk_widget_get_window(window->drawing_area_)) { + return GDK_EVENT_PROPAGATE; + } + return window->DrawingAreaEventHandler(event); +} + +gboolean GTKWindow::DrawHandler(GtkWidget* widget, cairo_t* cr, gpointer user_data) { + GTKWindow* window = reinterpret_cast(user_data); + if (!window || widget != window->drawing_area_) { + return FALSE; + } + if (window->batched_size_update_depth_) { + window->batched_size_update_contained_draw_ = true; + } else { + window->OnPaint(); + } + return TRUE; +} + +std::unique_ptr MenuItem::Create(Type type, const std::string& text, + const std::string& hotkey, + std::function callback) { + return std::make_unique(type, text, hotkey, callback); +} + +void GTKMenuItem::ActivateHandler(GtkWidget* menu_item, gpointer user_data) { + static_cast(user_data)->OnSelected(); + // The menu item might have been destroyed by its OnSelected, don't do + // anything with it here from now on. +} + +GTKMenuItem::GTKMenuItem(Type type, const std::string& text, const std::string& hotkey, + std::function callback) + : MenuItem(type, text, hotkey, std::move(callback)) { + std::string label = text; + // TODO(dougvj) Would we ever need to escape underscores? + // Replace & with _ for gtk to see the memonic + std::replace(label.begin(), label.end(), '&', '_'); + const gchar* gtk_label = reinterpret_cast(label.c_str()); + switch (type) { + case MenuItem::Type::kNormal: + default: + menu_ = gtk_menu_bar_new(); + break; + case MenuItem::Type::kPopup: + menu_ = gtk_menu_item_new_with_mnemonic(gtk_label); + break; + case MenuItem::Type::kSeparator: + menu_ = gtk_separator_menu_item_new(); + break; + case MenuItem::Type::kString: + auto full_name = text; + if (!hotkey.empty()) { + full_name += "\t" + hotkey; + } + menu_ = gtk_menu_item_new_with_mnemonic(gtk_label); + break; + } + if (menu_) { + // Own the object because it may be detached from and re-attached to a + // Window. + g_object_ref_sink(menu_); + if (GTK_IS_MENU_ITEM(menu_)) { + g_signal_connect(menu_, "activate", G_CALLBACK(ActivateHandler), + reinterpret_cast(this)); + } + } +} + +GTKMenuItem::~GTKMenuItem() { + if (menu_) { + g_object_unref(menu_); + } +} + +void GTKMenuItem::OnChildAdded(MenuItem* generic_child_item) { + auto child_item = static_cast(generic_child_item); + GtkWidget* submenu = nullptr; + switch (child_item->type()) { + case MenuItem::Type::kNormal: + // Nothing special. + break; + case MenuItem::Type::kPopup: + if (GTK_IS_MENU_ITEM(menu_)) { + submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu_)); + // Get sub menu and if it doesn't exist create it + if (submenu == nullptr) { + submenu = gtk_menu_new(); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_), submenu); + } + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), child_item->handle()); + } else { + gtk_menu_shell_append(GTK_MENU_SHELL(menu_), child_item->handle()); + } + break; + case MenuItem::Type::kSeparator: + case MenuItem::Type::kString: + assert(GTK_IS_MENU_ITEM(menu_)); + // Get sub menu and if it doesn't exist create it + submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu_)); + if (submenu == nullptr) { + submenu = gtk_menu_new(); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_), submenu); + } + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), child_item->handle()); + break; + } +} + +// TODO(dougvj) +void GTKMenuItem::OnChildRemoved(MenuItem* generic_child_item) { + assert_always(); +} + +} // namespace ui + +} // namespace rex diff --git a/src/ui/window_win.cpp b/src/ui/window_win.cpp new file mode 100644 index 0000000..09c44a3 --- /dev/null +++ b/src/ui/window_win.cpp @@ -0,0 +1,1395 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Must be included before Windows headers for things like NOMINMAX. +#include + +#include +#include +#include + +#include +#include +#include +#include + +namespace { + +uint32_t ResolveWindowWidth(uint32_t requested_width) { + if (REXCVAR_GET(window_width) > 0) { + return uint32_t(REXCVAR_GET(window_width)); + } + if (!rex::cvar::HasNonDefaultValue("window_width")) { + if (rex::cvar::HasNonDefaultValue("video_mode_width") && REXCVAR_GET(video_mode_width) > 0) { + return uint32_t(std::clamp(REXCVAR_GET(video_mode_width), 1, 8192)); + } + int32_t preset_width = 0; + int32_t preset_height = 0; + if (rex::graphics::video_mode_util::TryGetResolutionPresetFromCVar(preset_width, + preset_height)) { + return uint32_t(std::clamp(preset_width, 1, 8192)); + } + } + return requested_width; +} + +uint32_t ResolveWindowHeight(uint32_t requested_height) { + if (REXCVAR_GET(window_height) > 0) { + return uint32_t(REXCVAR_GET(window_height)); + } + if (!rex::cvar::HasNonDefaultValue("window_height")) { + if (rex::cvar::HasNonDefaultValue("video_mode_height") && REXCVAR_GET(video_mode_height) > 0) { + return uint32_t(std::clamp(REXCVAR_GET(video_mode_height), 1, 8192)); + } + int32_t preset_width = 0; + int32_t preset_height = 0; + if (rex::graphics::video_mode_util::TryGetResolutionPresetFromCVar(preset_width, + preset_height)) { + return uint32_t(std::clamp(preset_height, 1, 8192)); + } + } + return requested_height; +} + +BOOL CALLBACK EnumMonitorsCallback(HMONITOR monitor, HDC, LPRECT, LPARAM data) { + auto* monitors = reinterpret_cast*>(data); + monitors->push_back(monitor); + return TRUE; +} + +HMONITOR GetMonitorByIndex(int32_t index) { + if (index <= 0) { + return nullptr; + } + std::vector monitors; + EnumDisplayMonitors(nullptr, nullptr, EnumMonitorsCallback, reinterpret_cast(&monitors)); + if (index <= static_cast(monitors.size())) { + return monitors[index - 1]; + } + return nullptr; +} + +} // namespace + +namespace rex { +namespace ui { + +std::unique_ptr Window::Create(WindowedAppContext& app_context, + const std::string_view title, uint32_t desired_logical_width, + uint32_t desired_logical_height) { + desired_logical_width = ResolveWindowWidth(desired_logical_width); + desired_logical_height = ResolveWindowHeight(desired_logical_height); + return std::make_unique(app_context, title, desired_logical_width, + desired_logical_height); +} + +Win32Window::Win32Window(WindowedAppContext& app_context, const std::string_view title, + uint32_t desired_logical_width, uint32_t desired_logical_height) + : Window(app_context, title, desired_logical_width, desired_logical_height), + arrow_cursor_(LoadCursor(nullptr, IDC_ARROW)) { + dpi_ = GetCurrentSystemDpi(); +} + +Win32Window::~Win32Window() { + EnterDestructor(); + if (cursor_auto_hide_timer_) { + DeleteTimerQueueTimer(nullptr, cursor_auto_hide_timer_, nullptr); + cursor_auto_hide_timer_ = nullptr; + } + if (hwnd_) { + // Set hwnd_ to null to ignore events from now on since this Win32Window is + // entering an indeterminate state. + HWND hwnd = hwnd_; + hwnd_ = nullptr; + SetWindowLongPtr(hwnd, GWLP_USERDATA, 0); + DestroyWindow(hwnd); + } + if (icon_) { + DestroyIcon(icon_); + } +} + +uint32_t Win32Window::GetMediumDpi() const { + return USER_DEFAULT_SCREEN_DPI; +} + +bool Win32Window::OpenImpl() { + const Win32WindowedAppContext& win32_app_context = + static_cast(app_context()); + HINSTANCE hinstance = win32_app_context.hinstance(); + + static bool has_registered_class = false; + if (!has_registered_class) { + WNDCLASSEXW wcex; + wcex.cbSize = sizeof(wcex); + wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wcex.lpfnWndProc = Win32Window::WndProcThunk; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hinstance; + wcex.hIcon = LoadIconW(hinstance, L"MAINICON"); + wcex.hIconSm = nullptr; // LoadIconW(hinstance, L"MAINICON"); + wcex.hCursor = arrow_cursor_; + // Matches the black background color of the presenter's painting. + wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wcex.lpszMenuName = nullptr; + wcex.lpszClassName = L"RexWindowClass"; + if (!RegisterClassExW(&wcex)) { + REXLOG_ERROR("RegisterClassEx failed"); + return false; + } + has_registered_class = true; + } + + const Win32MenuItem* main_menu = static_cast(GetMainMenu()); + + // Setup the initial size for the non-fullscreen window. With per-monitor DPI, + // this is also done to be able to obtain the initial window rectangle (with + // CW_USEDEFAULT) to get the monitor for the window position, and then to + // adjust the normal window size to the new DPI. + // Save the initial desired size since it may be modified by the handler of + // the WM_SIZE sent during window creation - it's needed for the initial + // per-monitor DPI scaling. + uint32_t initial_desired_logical_width = GetDesiredLogicalWidth(); + uint32_t initial_desired_logical_height = GetDesiredLogicalHeight(); + const Win32WindowedAppContext::PerMonitorDpiV2Api* per_monitor_dpi_v2_api = + win32_app_context.per_monitor_dpi_v2_api(); + const Win32WindowedAppContext::PerMonitorDpiV1Api* per_monitor_dpi_v1_api = + win32_app_context.per_monitor_dpi_v1_api(); + // Even with per-monitor DPI, take the closest approximation (system DPI) to + // potentially more accurately determine the initial monitor. + dpi_ = GetCurrentSystemDpi(); + DWORD window_style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + DWORD window_ex_style = WS_EX_APPWINDOW | WS_EX_CONTROLPARENT; + RECT window_size_rect; + window_size_rect.left = 0; + window_size_rect.top = 0; + window_size_rect.right = + LONG(ConvertSizeDpi(initial_desired_logical_width, dpi_, USER_DEFAULT_SCREEN_DPI)); + window_size_rect.bottom = + LONG(ConvertSizeDpi(initial_desired_logical_height, dpi_, USER_DEFAULT_SCREEN_DPI)); + AdjustWindowRectangle(window_size_rect, window_style, BOOL(main_menu != nullptr), window_ex_style, + dpi_); + // Create the window. Though WM_NCCREATE will assign to `hwnd_` too, still do + // the assignment here to handle the case of a failure after WM_NCCREATE, for + // instance. + auto wide_title = rex::string::to_utf16(GetTitle()); + hwnd_ = CreateWindowExW( + window_ex_style, L"RexWindowClass", reinterpret_cast(wide_title.c_str()), + window_style, CW_USEDEFAULT, CW_USEDEFAULT, window_size_rect.right - window_size_rect.left, + window_size_rect.bottom - window_size_rect.top, nullptr, nullptr, hinstance, this); + if (!hwnd_) { + REXLOG_ERROR("CreateWindowExW failed"); + return false; + } + // For per-monitor DPI, obtain the DPI of the monitor the window was created + // on, and adjust the initial normal size for it. If as a result of this + // resizing, the window is moved to a different monitor, the WM_DPICHANGED + // handler will do the needed correction. + uint32_t initial_monitor_dpi = dpi_; + if (per_monitor_dpi_v2_api) { + initial_monitor_dpi = per_monitor_dpi_v2_api->get_dpi_for_window(hwnd_); + } else if (per_monitor_dpi_v1_api) { + HMONITOR monitor = MonitorFromWindow(hwnd_, MONITOR_DEFAULTTONEAREST); + UINT monitor_dpi_x, monitor_dpi_y; + if (monitor && SUCCEEDED(per_monitor_dpi_v1_api->get_dpi_for_monitor( + monitor, MDT_DEFAULT, &monitor_dpi_x, &monitor_dpi_y))) { + initial_monitor_dpi = monitor_dpi_x; + } + } + if (dpi_ != initial_monitor_dpi) { + dpi_ = initial_monitor_dpi; + WINDOWPLACEMENT initial_dpi_placement; + // Note that WINDOWPLACEMENT contains workspace coordinates, which are + // adjusted to exclude toolbars such as the taskbar - the positions and + // rectangle origins there can't be mixed with origins of rectangles in + // virtual screen coordinates such as those involved in functions like + // GetWindowRect. + initial_dpi_placement.length = sizeof(initial_dpi_placement); + if (GetWindowPlacement(hwnd_, &initial_dpi_placement)) { + window_size_rect.left = 0; + window_size_rect.top = 0; + window_size_rect.right = + LONG(ConvertSizeDpi(initial_desired_logical_width, dpi_, USER_DEFAULT_SCREEN_DPI)); + window_size_rect.bottom = + LONG(ConvertSizeDpi(initial_desired_logical_height, dpi_, USER_DEFAULT_SCREEN_DPI)); + AdjustWindowRectangle(window_size_rect, window_style, BOOL(main_menu != nullptr), + window_ex_style, dpi_); + initial_dpi_placement.rcNormalPosition.right = + initial_dpi_placement.rcNormalPosition.left + + (window_size_rect.right - window_size_rect.left); + initial_dpi_placement.rcNormalPosition.bottom = + initial_dpi_placement.rcNormalPosition.top + + (window_size_rect.bottom - window_size_rect.top); + SetWindowPlacement(hwnd_, &initial_dpi_placement); + } + } + + // Disable rounded corners starting with Windows 11 (or silently receive and + // ignore E_INVALIDARG on Windows versions before 10.0.22000.0), primarily to + // preserve all pixels of the guest output. + DWM_WINDOW_CORNER_PREFERENCE window_corner_preference = DWMWCP_DONOTROUND; + DwmSetWindowAttribute(hwnd_, DWMWA_WINDOW_CORNER_PREFERENCE, &window_corner_preference, + sizeof(window_corner_preference)); + + // Disable flicks. + ATOM atom = GlobalAddAtomW(L"MicrosoftTabletPenServiceProperty"); + const DWORD_PTR dwHwndTabletProperty = + TABLET_DISABLE_PRESSANDHOLD | // disables press and hold (right-click) + // gesture + TABLET_DISABLE_PENTAPFEEDBACK | // disables UI feedback on pen up (waves) + TABLET_DISABLE_PENBARRELFEEDBACK | // disables UI feedback on pen button + // down (circle) + TABLET_DISABLE_FLICKS | // disables pen flicks (back, forward, drag down, + // drag up) + TABLET_DISABLE_TOUCHSWITCH | TABLET_DISABLE_SMOOTHSCROLLING | TABLET_DISABLE_TOUCHUIFORCEON | + TABLET_ENABLE_MULTITOUCHDATA; + SetPropW(hwnd_, L"MicrosoftTabletPenServiceProperty", + reinterpret_cast(dwHwndTabletProperty)); + GlobalDeleteAtom(atom); + + // Enable file dragging from external sources + DragAcceptFiles(hwnd_, true); + + // Apply the initial state from the Window that the window shouldn't be + // visibly transitioned to. + + if (icon_) { + SendMessageW(hwnd_, WM_SETICON, ICON_BIG, reinterpret_cast(icon_)); + SendMessageW(hwnd_, WM_SETICON, ICON_SMALL, reinterpret_cast(icon_)); + } + + // Move the window to the requested monitor before entering fullscreen so + // that MonitorFromWindow picks the correct display. + if (int32_t monitor_index = REXCVAR_GET(monitor); monitor_index > 0) { + HMONITOR target = GetMonitorByIndex(monitor_index); + if (target) { + MONITORINFO mi; + mi.cbSize = sizeof(mi); + if (GetMonitorInfo(target, &mi)) { + RECT wr; + GetWindowRect(hwnd_, &wr); + int w = wr.right - wr.left; + int h = wr.bottom - wr.top; + int x = mi.rcWork.left + (mi.rcWork.right - mi.rcWork.left - w) / 2; + int y = mi.rcWork.top + (mi.rcWork.bottom - mi.rcWork.top - h) / 2; + SetWindowPos(hwnd_, nullptr, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); + } + } + } + + if (IsFullscreen()) { + // Go fullscreen after setting up everything related to the placement of the + // non-fullscreen window. + WindowDestructionReceiver destruction_receiver(this); + ApplyFullscreenEntry(destruction_receiver); + if (destruction_receiver.IsWindowDestroyed()) { + return true; + } + } else { + if (main_menu) { + SetMenu(hwnd_, main_menu->handle()); + } + } + + // Finally show the window. + ShowWindow(hwnd_, SW_SHOWNORMAL); + + // Report the initial actual state after opening, messages for which might + // have missed if they were processed during CreateWindowExW when the HWND was + // not yet attached to the Win32Window. + { + WindowDestructionReceiver destruction_receiver(this); + + // Report the desired logical size of the client area in the non-maximized + // state after the initial layout setup in Windows. + WINDOWPLACEMENT shown_placement; + shown_placement.length = sizeof(shown_placement); + if (GetWindowPlacement(hwnd_, &shown_placement)) { + // Get the size of the non-client area to subtract it from the size of the + // entire window in its non-maximized state, to get the client area. For + // safety, in case the window is somehow smaller than its non-client area + // (AdjustWindowRect is not exact in various cases also, such as when the + // menu becomes multiline), clamp to 0. + RECT non_client_area_rect = {}; + AdjustWindowRectangle(non_client_area_rect); + OnDesiredLogicalSizeUpdate( + SizeToLogical(uint32_t(std::max( + (shown_placement.rcNormalPosition.right - shown_placement.rcNormalPosition.left) - + (non_client_area_rect.right - non_client_area_rect.left), + LONG(0)))), + SizeToLogical(uint32_t(std::max( + (shown_placement.rcNormalPosition.bottom - shown_placement.rcNormalPosition.top) - + (non_client_area_rect.bottom - non_client_area_rect.top), + LONG(0))))); + } + + // Report the actual physical size in the current state. + // GetClientRect returns a rectangle with 0 origin. + RECT shown_client_rect; + if (GetClientRect(hwnd_, &shown_client_rect)) { + OnActualSizeUpdate(uint32_t(shown_client_rect.right), uint32_t(shown_client_rect.bottom), + destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + return true; + } + } + + OnFocusUpdate(GetFocus() == hwnd_, destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + return true; + } + } + + // Apply the initial state from the Window that involves interaction with the + // user. + + if (IsMouseCaptureRequested()) { + SetCapture(hwnd_); + } + + cursor_currently_auto_hidden_ = false; + CursorVisibility cursor_visibility = GetCursorVisibility(); + if (cursor_visibility != CursorVisibility::kVisible) { + if (cursor_visibility == CursorVisibility::kAutoHidden) { + if (!GetCursorPos(&cursor_auto_hide_last_screen_pos_)) { + cursor_auto_hide_last_screen_pos_.x = LONG_MAX; + cursor_auto_hide_last_screen_pos_.y = LONG_MAX; + } + cursor_currently_auto_hidden_ = true; + } + // OnFocusUpdate needs to be done before this. + SetCursorIfFocusedOnClientArea(nullptr); + } + + return true; +} + +void Win32Window::RequestCloseImpl() { + // Note that CloseWindow doesn't close the window, rather, it only minimizes + // it - need to send WM_CLOSE to let the Win32Window WndProc perform all the + // shutdown. + SendMessageW(hwnd_, WM_CLOSE, 0, 0); + // The window might have been deleted by the close handler, don't do anything + // with *this anymore (if that's needed, use a WindowDestructionReceiver). +} + +uint32_t Win32Window::GetLatestDpiImpl() const { + // hwnd_ may be null in this function, but the latest DPI is stored in a + // variable anyway. + return dpi_; +} + +void Win32Window::ApplyNewFullscreen() { + // Various functions here may send messages that may result in the + // listeners being invoked, and potentially cause the destruction of the + // window or fullscreen being toggled from inside this function. + WindowDestructionReceiver destruction_receiver(this); + if (IsFullscreen()) { + ApplyFullscreenEntry(destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + return; + } + } else { + // Changing the style and the menu may change the size too, don't handle + // the resize multiple times (also potentially with the listeners changing + // the desired fullscreen if called from the handling of some message like + // WM_SIZE). + BeginBatchedSizeUpdate(); + + // Reinstate the non-client area. + SetWindowLong(hwnd_, GWL_STYLE, GetWindowLong(hwnd_, GWL_STYLE) | WS_OVERLAPPEDWINDOW); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + if (!destruction_receiver.IsWindowDestroyed()) { + EndBatchedSizeUpdate(destruction_receiver); + } + return; + } + const Win32MenuItem* main_menu = static_cast(GetMainMenu()); + if (main_menu) { + SetMenu(hwnd_, main_menu->handle()); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + if (!destruction_receiver.IsWindowDestroyed()) { + EndBatchedSizeUpdate(destruction_receiver); + } + return; + } + } + + // For some reason, WM_DPICHANGED is not sent when the window is borderless + // fullscreen with per-monitor DPI awareness v1 (on Windows versions since + // Windows 8.1 before Windows 10 1703) - refresh the current DPI explicitly. + dpi_ = GetCurrentDpi(); + if (dpi_ != pre_fullscreen_dpi_) { + // Rescale the pre-fullscreen non-maximized window size to the new DPI as + // WM_DPICHANGED with the new rectangle was received for the fullscreen + // window size, not the windowed one. Simulating the behavior of the + // automatic resizing when changing the scale in the Windows settings (as + // of Windows 11 21H2 at least), which keeps the physical top-left origin + // of the entire window including the non-client area, but rescales the + // size. + // Note that WINDOWPLACEMENT contains workspace coordinates, which are + // adjusted to exclude toolbars such as the taskbar - the positions and + // rectangle origins there can't be mixed with origins of rectangles in + // virtual screen coordinates such as those involved in functions like + // GetWindowRect. + RECT new_dpi_rect; + new_dpi_rect.left = 0; + new_dpi_rect.top = 0; + new_dpi_rect.right = + LONG(ConvertSizeDpi(pre_fullscreen_normal_client_width_, dpi_, pre_fullscreen_dpi_)); + new_dpi_rect.bottom = + LONG(ConvertSizeDpi(pre_fullscreen_normal_client_height_, dpi_, pre_fullscreen_dpi_)); + AdjustWindowRectangle(new_dpi_rect); + pre_fullscreen_placement_.rcNormalPosition.right = + pre_fullscreen_placement_.rcNormalPosition.left + + (new_dpi_rect.right - new_dpi_rect.left); + pre_fullscreen_placement_.rcNormalPosition.bottom = + pre_fullscreen_placement_.rcNormalPosition.top + (new_dpi_rect.bottom - new_dpi_rect.top); + } + SetWindowPlacement(hwnd_, &pre_fullscreen_placement_); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + if (!destruction_receiver.IsWindowDestroyed()) { + EndBatchedSizeUpdate(destruction_receiver); + } + return; + } + + // https://devblogs.microsoft.com/oldnewthing/20131017-00/?p=2903 + SetWindowPos(hwnd_, nullptr, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + if (!destruction_receiver.IsWindowDestroyed()) { + EndBatchedSizeUpdate(destruction_receiver); + } + return; + } + + EndBatchedSizeUpdate(destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + return; + } + } +} + +void Win32Window::ApplyNewTitle() { + auto wide_title = rex::string::to_utf16(GetTitle()); + SetWindowTextW(hwnd_, reinterpret_cast(wide_title.c_str())); +} + +void Win32Window::LoadAndApplyIcon(const void* buffer, size_t size, + bool can_apply_state_in_current_phase) { + bool reset = !buffer || !size; + + HICON new_icon, new_icon_small; + if (reset) { + if (!icon_) { + // The icon is already the default one. + return; + } + if (!hwnd_) { + // Don't need to get the actual icon from the class if there's nothing to + // set it for yet (and there's no HWND to get it from, and the class may + // have not been registered yet also). + DestroyIcon(icon_); + icon_ = nullptr; + return; + } + new_icon = reinterpret_cast(GetClassLongPtrW(hwnd_, GCLP_HICON)); + new_icon_small = reinterpret_cast(GetClassLongPtrW(hwnd_, GCLP_HICONSM)); + // Not caring if it's null in the class, accepting anything the class + // specifies. + } else { + new_icon = CreateIconFromResourceEx(static_cast(const_cast(buffer)), DWORD(size), + TRUE, 0x00030000, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE); + if (!new_icon) { + return; + } + new_icon_small = new_icon; + } + + if (hwnd_) { + SendMessageW(hwnd_, WM_SETICON, ICON_BIG, reinterpret_cast(new_icon)); + SendMessageW(hwnd_, WM_SETICON, ICON_SMALL, reinterpret_cast(new_icon_small)); + } + + // The old icon is not in use anymore, safe to destroy it now. + if (icon_) { + DestroyIcon(icon_); + icon_ = nullptr; + } + + if (!reset) { + assert_true(new_icon_small == new_icon); + icon_ = new_icon; + } +} + +void Win32Window::ApplyNewMainMenu(MenuItem* old_main_menu) { + if (IsFullscreen()) { + // The menu will be set when exiting fullscreen. + return; + } + const Win32MenuItem* main_menu = static_cast(GetMainMenu()); + WindowDestructionReceiver destruction_receiver(this); + SetMenu(hwnd_, main_menu ? main_menu->handle() : nullptr); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + return; + } +} + +void Win32Window::CompleteMainMenuItemsUpdateImpl() { + if (IsFullscreen()) { + return; + } + DrawMenuBar(hwnd_); +} + +void Win32Window::ApplyNewMouseCapture() { + WindowDestructionReceiver destruction_receiver(this); + SetCapture(hwnd_); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + return; + } +} + +void Win32Window::ApplyNewMouseRelease() { + if (GetCapture() != hwnd_) { + return; + } + WindowDestructionReceiver destruction_receiver(this); + ReleaseCapture(); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + return; + } +} + +void Win32Window::ApplyNewCursorVisibility(CursorVisibility old_cursor_visibility) { + CursorVisibility new_cursor_visibility = GetCursorVisibility(); + cursor_currently_auto_hidden_ = false; + if (new_cursor_visibility == CursorVisibility::kAutoHidden) { + if (!GetCursorPos(&cursor_auto_hide_last_screen_pos_)) { + cursor_auto_hide_last_screen_pos_.x = LONG_MAX; + cursor_auto_hide_last_screen_pos_.y = LONG_MAX; + } + cursor_currently_auto_hidden_ = true; + } else if (old_cursor_visibility == CursorVisibility::kAutoHidden) { + if (cursor_auto_hide_timer_) { + DeleteTimerQueueTimer(nullptr, cursor_auto_hide_timer_, nullptr); + cursor_auto_hide_timer_ = nullptr; + } + } + SetCursorIfFocusedOnClientArea(new_cursor_visibility == CursorVisibility::kVisible ? arrow_cursor_ + : nullptr); +} + +void Win32Window::FocusImpl() { + SetFocus(hwnd_); +} + +std::unique_ptr Win32Window::CreateSurfaceImpl(Surface::TypeFlags allowed_types) { + HINSTANCE hInstance = static_cast(app_context()).hinstance(); + if (allowed_types & Surface::kTypeFlag_Win32Hwnd) { + return std::make_unique(hInstance, hwnd_); + } + return nullptr; +} + +void Win32Window::RequestPaintImpl() { + InvalidateRect(hwnd_, nullptr, FALSE); +} + +BOOL Win32Window::AdjustWindowRectangle(RECT& rect, DWORD style, BOOL menu, DWORD ex_style, + UINT dpi) const { + const Win32WindowedAppContext& win32_app_context = + static_cast(app_context()); + const Win32WindowedAppContext::PerMonitorDpiV2Api* per_monitor_dpi_v2_api = + win32_app_context.per_monitor_dpi_v2_api(); + if (per_monitor_dpi_v2_api) { + return per_monitor_dpi_v2_api->adjust_window_rect_ex_for_dpi(&rect, style, menu, ex_style, dpi); + } + // Before per-monitor DPI v2, there was no rescaling of the non-client + // area at runtime at all, so throughout the execution of the process it will + // behave the same regardless of the DPI. + return AdjustWindowRectEx(&rect, style, menu, ex_style); +} + +BOOL Win32Window::AdjustWindowRectangle(RECT& rect) const { + if (!hwnd_) { + return FALSE; + } + return AdjustWindowRectangle(rect, GetWindowLong(hwnd_, GWL_STYLE), + BOOL(GetMainMenu() != nullptr), GetWindowLong(hwnd_, GWL_EXSTYLE), + dpi_); +} + +uint32_t Win32Window::GetCurrentSystemDpi() const { + const Win32WindowedAppContext& win32_app_context = + static_cast(app_context()); + const Win32WindowedAppContext::PerMonitorDpiV2Api* per_monitor_dpi_v2_api = + win32_app_context.per_monitor_dpi_v2_api(); + if (per_monitor_dpi_v2_api) { + return per_monitor_dpi_v2_api->get_dpi_for_system(); + } + + HDC screen_hdc = GetDC(nullptr); + if (!screen_hdc) { + return USER_DEFAULT_SCREEN_DPI; + } + // According to MSDN, x and y are identical. + int logical_pixels_x = GetDeviceCaps(screen_hdc, LOGPIXELSX); + ReleaseDC(nullptr, screen_hdc); + return uint32_t(logical_pixels_x); +} + +uint32_t Win32Window::GetCurrentDpi() const { + if (hwnd_) { + const Win32WindowedAppContext& win32_app_context = + static_cast(app_context()); + + const Win32WindowedAppContext::PerMonitorDpiV2Api* per_monitor_dpi_v2_api = + win32_app_context.per_monitor_dpi_v2_api(); + if (per_monitor_dpi_v2_api) { + return per_monitor_dpi_v2_api->get_dpi_for_window(hwnd_); + } + + const Win32WindowedAppContext::PerMonitorDpiV1Api* per_monitor_dpi_v1_api = + win32_app_context.per_monitor_dpi_v1_api(); + if (per_monitor_dpi_v1_api) { + HMONITOR monitor = MonitorFromWindow(hwnd_, MONITOR_DEFAULTTONEAREST); + UINT monitor_dpi_x, monitor_dpi_y; + if (monitor && SUCCEEDED(per_monitor_dpi_v1_api->get_dpi_for_monitor( + monitor, MDT_DEFAULT, &monitor_dpi_x, &monitor_dpi_y))) { + // According to MSDN, x and y are identical. + return monitor_dpi_x; + } + } + } + + return GetCurrentSystemDpi(); +} + +void Win32Window::ApplyFullscreenEntry(WindowDestructionReceiver& destruction_receiver) { + if (!IsFullscreen()) { + return; + } + + // https://blogs.msdn.com/b/oldnewthing/archive/2010/04/12/9994016.aspx + // No reason to use MONITOR_DEFAULTTOPRIMARY instead of + // MONITOR_DEFAULTTONEAREST, however. + pre_fullscreen_dpi_ = dpi_; + pre_fullscreen_placement_.length = sizeof(pre_fullscreen_placement_); + HMONITOR monitor; + MONITORINFO monitor_info; + monitor_info.cbSize = sizeof(monitor_info); + if (!GetWindowPlacement(hwnd_, &pre_fullscreen_placement_) || + !(monitor = MonitorFromWindow(hwnd_, MONITOR_DEFAULTTONEAREST)) || + !GetMonitorInfo(monitor, &monitor_info)) { + OnDesiredFullscreenUpdate(false); + return; + } + // Preserve values for DPI rescaling of the window in the non-maximized state + // if DPI is changed mid-fullscreen. + // Get the size of the non-client area to subtract it from the size of the + // entire window in its non-maximized state, to get the client area. For + // safety, in case the window is somehow smaller than its non-client area + // (AdjustWindowRect is not exact in various cases also, such as when the menu + // becomes multiline), clamp to 0. + RECT non_client_area_rect = {}; + AdjustWindowRectangle(non_client_area_rect); + pre_fullscreen_normal_client_width_ = + uint32_t(std::max((pre_fullscreen_placement_.rcNormalPosition.right - + pre_fullscreen_placement_.rcNormalPosition.left) - + (non_client_area_rect.right - non_client_area_rect.left), + LONG(0))); + pre_fullscreen_normal_client_height_ = + uint32_t(std::max((pre_fullscreen_placement_.rcNormalPosition.bottom - + pre_fullscreen_placement_.rcNormalPosition.top) - + (non_client_area_rect.bottom - non_client_area_rect.top), + LONG(0))); + + // Changing the style and the menu may change the size too, don't handle the + // resize multiple times (also potentially with the listeners changing the + // desired fullscreen if called from the handling of some message like + // WM_SIZE). + BeginBatchedSizeUpdate(); + + // Remove the non-client area. + if (GetMainMenu()) { + SetMenu(hwnd_, nullptr); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + if (!destruction_receiver.IsWindowDestroyed()) { + EndBatchedSizeUpdate(destruction_receiver); + } + return; + } + } + SetWindowLong(hwnd_, GWL_STYLE, GetWindowLong(hwnd_, GWL_STYLE) & ~DWORD(WS_OVERLAPPEDWINDOW)); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + if (!destruction_receiver.IsWindowDestroyed()) { + EndBatchedSizeUpdate(destruction_receiver); + } + return; + } + + // Resize the window to fullscreen. It is important that this is done _after_ + // disabling the decorations and the menu, to make sure that composition will + // not have to be done for the new size of the window at all, so independent, + // low-latency presentation is possible immediately - if the window was + // involved in composition, it may stay composed persistently until some other + // state change that sometimes helps, sometimes doesn't, even if it becomes + // borderless fullscreen again - this occurs sometimes at least on Windows 11 + // 21H2 on Nvidia GeForce GTX 1070 on driver version 472.12. + SetWindowPos(hwnd_, HWND_TOP, monitor_info.rcMonitor.left, monitor_info.rcMonitor.top, + monitor_info.rcMonitor.right - monitor_info.rcMonitor.left, + monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top, + SWP_NOOWNERZORDER | SWP_FRAMECHANGED); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + if (!destruction_receiver.IsWindowDestroyed()) { + EndBatchedSizeUpdate(destruction_receiver); + } + return; + } + + EndBatchedSizeUpdate(destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + return; + } +} + +void Win32Window::HandleSizeUpdate(WindowDestructionReceiver& destruction_receiver) { + if (!hwnd_) { + // Batched size update ended when the window has already been closed, for + // instance. + return; + } + + { + MonitorUpdateEvent e(this, false); + OnMonitorUpdate(e); + } + + // For the desired size in the normal, not maximized and not fullscreen state. + if (!IsFullscreen()) { + WINDOWPLACEMENT window_placement; + window_placement.length = sizeof(window_placement); + if (GetWindowPlacement(hwnd_, &window_placement)) { + // window_placement.rcNormalPosition is the entire window's rectangle, not + // only the client area - convert to client. + // https://devblogs.microsoft.com/oldnewthing/20131017-00/?p=2903 + // For safety, in case the window is somehow smaller than its non-client + // area (AdjustWindowRect is not exact in various cases also, such as when + // the menu becomes multiline), clamp to 0. + RECT non_client_area_rect = {}; + if (AdjustWindowRectangle(non_client_area_rect)) { + OnDesiredLogicalSizeUpdate( + SizeToLogical(uint32_t(std::max( + (window_placement.rcNormalPosition.right - window_placement.rcNormalPosition.left) - + (non_client_area_rect.right - non_client_area_rect.left), + LONG(0)))), + SizeToLogical(uint32_t(std::max( + (window_placement.rcNormalPosition.bottom - window_placement.rcNormalPosition.top) - + (non_client_area_rect.bottom - non_client_area_rect.top), + LONG(0))))); + } + } + } + + // For the actual state. + // GetClientRect returns a rectangle with 0 origin. + RECT client_rect; + if (GetClientRect(hwnd_, &client_rect)) { + OnActualSizeUpdate(uint32_t(client_rect.right), uint32_t(client_rect.bottom), + destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + return; + } + } +} + +void Win32Window::BeginBatchedSizeUpdate() { + // It's okay if batched_size_update_contained_* are not false when beginning + // a batched update, in case the new batched update was started by a window + // listener called from within EndBatchedSizeUpdate. + ++batched_size_update_depth_; +} + +void Win32Window::EndBatchedSizeUpdate(WindowDestructionReceiver& destruction_receiver) { + assert_not_zero(batched_size_update_depth_); + if (--batched_size_update_depth_) { + return; + } + // Resetting batched_size_update_contained_* in closing, not opening, because + // a listener may start a new batch, and finish it, and there won't be need to + // handle the deferred messages twice. + if (batched_size_update_contained_wm_size_) { + batched_size_update_contained_wm_size_ = false; + HandleSizeUpdate(destruction_receiver); + if (destruction_receiver.IsWindowDestroyed()) { + return; + } + } + if (batched_size_update_contained_wm_paint_) { + batched_size_update_contained_wm_paint_ = false; + RequestPaint(); + } +} + +bool Win32Window::HandleMouse(UINT message, WPARAM wParam, LPARAM lParam, + WindowDestructionReceiver& destruction_receiver) { + // Mouse messages usually contain the position in the client area in lParam, + // but WM_MOUSEWHEEL is an exception, it passes the screen position. + int32_t message_x = GET_X_LPARAM(lParam); + int32_t message_y = GET_Y_LPARAM(lParam); + bool message_pos_is_screen = message == WM_MOUSEWHEEL; + + POINT client_pos = {message_x, message_y}; + if (message_pos_is_screen) { + ScreenToClient(hwnd_, &client_pos); + } + + if (GetCursorVisibility() == CursorVisibility::kAutoHidden) { + POINT screen_pos = {message_x, message_y}; + if (message_pos_is_screen || ClientToScreen(hwnd_, &screen_pos)) { + if (screen_pos.x != cursor_auto_hide_last_screen_pos_.x || + screen_pos.y != cursor_auto_hide_last_screen_pos_.y) { + // WM_MOUSEMOVE messages followed by WM_SETCURSOR may be sent for + // reasons not always involving actual mouse movement performed by the + // user. They're sent when the position of the cursor relative to the + // client area has been changed, as well as other events related to + // window management (including when creating the window), even when not + // interacting with the OS. These should not be revealing the cursor. + // Only revealing it if the mouse has actually been moved. + cursor_currently_auto_hidden_ = false; + SetCursorAutoHideTimer(); + // There's no need to SetCursor here, mouse messages relevant to the + // cursor within the window are always followed by WM_SETCURSOR. + cursor_auto_hide_last_screen_pos_ = screen_pos; + } + } + } + + MouseEvent::Button button = MouseEvent::Button::kNone; + int32_t scroll_y = 0; + switch (message) { + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + button = MouseEvent::Button::kLeft; + break; + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + button = MouseEvent::Button::kRight; + break; + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + button = MouseEvent::Button::kMiddle; + break; + case WM_XBUTTONDOWN: + case WM_XBUTTONUP: + switch (GET_XBUTTON_WPARAM(wParam)) { + case XBUTTON1: + button = MouseEvent::Button::kX1; + break; + case XBUTTON2: + button = MouseEvent::Button::kX2; + break; + default: + // Still handle the movement. + break; + } + break; + case WM_MOUSEMOVE: + button = MouseEvent::Button::kNone; + break; + case WM_MOUSEWHEEL: + button = MouseEvent::Button::kNone; + static_assert(MouseEvent::kScrollPerDetent == WHEEL_DELTA, + "Assuming the Windows scroll amount can be passed directly to " + "MouseEvent"); + scroll_y = GET_WHEEL_DELTA_WPARAM(wParam); + break; + default: + return false; + } + + MouseEvent e(this, button, client_pos.x, client_pos.y, 0, scroll_y); + switch (message) { + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_XBUTTONDOWN: + OnMouseDown(e, destruction_receiver); + break; + case WM_LBUTTONUP: + case WM_RBUTTONUP: + case WM_MBUTTONUP: + case WM_XBUTTONUP: + OnMouseUp(e, destruction_receiver); + break; + case WM_MOUSEMOVE: + OnMouseMove(e, destruction_receiver); + break; + case WM_MOUSEWHEEL: + OnMouseWheel(e, destruction_receiver); + break; + default: + break; + } + // Returning immediately anyway - no need to check + // destruction_receiver.IsWindowDestroyed(). + return e.is_handled(); +} + +bool Win32Window::HandleKeyboard(UINT message, WPARAM wParam, LPARAM lParam, + WindowDestructionReceiver& destruction_receiver) { + KeyEvent e(this, VirtualKey(wParam), lParam & 0xFFFF, !!(lParam & (LPARAM(1) << 30)), + !!(GetKeyState(VK_SHIFT) & 0x80), !!(GetKeyState(VK_CONTROL) & 0x80), + !!(GetKeyState(VK_MENU) & 0x80), !!(GetKeyState(VK_LWIN) & 0x80)); + switch (message) { + case WM_KEYDOWN: + OnKeyDown(e, destruction_receiver); + break; + case WM_KEYUP: + OnKeyUp(e, destruction_receiver); + break; + case WM_CHAR: + OnKeyChar(e, destruction_receiver); + break; + default: + break; + } + // Returning immediately anyway - no need to check + // destruction_receiver.IsWindowDestroyed(). + return e.is_handled(); +} + +void Win32Window::SetCursorIfFocusedOnClientArea(HCURSOR cursor) const { + if (!HasFocus()) { + return; + } + POINT cursor_pos; + if (!GetCursorPos(&cursor_pos)) { + return; + } + if (WindowFromPoint(cursor_pos) == hwnd_ && + SendMessage(hwnd_, WM_NCHITTEST, 0, MAKELONG(cursor_pos.x, cursor_pos.y)) == HTCLIENT) { + SetCursor(cursor); + } +} + +void Win32Window::SetCursorAutoHideTimer() { + // Reset the timer by deleting the old timer and creating the new one. + // ChangeTimerQueueTimer doesn't work if the timer has already expired. + if (cursor_auto_hide_timer_) { + DeleteTimerQueueTimer(nullptr, cursor_auto_hide_timer_, nullptr); + cursor_auto_hide_timer_ = nullptr; + } + // After making sure that the callback is not callable anymore + // (DeleteTimerQueueTimer waits for the completion of the callback if it has + // been called already, or cancels it if it's hasn't), update the most recent + // message revision. + last_cursor_auto_hide_queued = last_cursor_auto_hide_signaled + 1; + CreateTimerQueueTimer(&cursor_auto_hide_timer_, nullptr, AutoHideCursorTimerCallback, this, + kDefaultCursorAutoHideMilliseconds, 0, + WT_EXECUTEINTIMERTHREAD | WT_EXECUTEONLYONCE); +} + +void Win32Window::AutoHideCursorTimerCallback(void* parameter, BOOLEAN timer_or_wait_fired) { + if (!timer_or_wait_fired) { + // Not a timer callback. + return; + } + Win32Window& window = *static_cast(parameter); + window.last_cursor_auto_hide_signaled = window.last_cursor_auto_hide_queued; + SendMessage(window.hwnd_, kUserMessageAutoHideCursor, window.last_cursor_auto_hide_signaled, 0); +} + +LRESULT Win32Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { + if (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST) { + WindowDestructionReceiver destruction_receiver(this); + // Returning immediately anyway - no need to check + // destruction_receiver.IsWindowDestroyed() afterwards. + return HandleMouse(message, wParam, lParam, destruction_receiver) + ? 0 + : DefWindowProcW(hWnd, message, wParam, lParam); + } + if (message >= WM_KEYFIRST && message <= WM_KEYLAST) { + WindowDestructionReceiver destruction_receiver(this); + // Returning immediately anyway - no need to check + // destruction_receiver.IsWindowDestroyed() afterwards. + return HandleKeyboard(message, wParam, lParam, destruction_receiver) + ? 0 + : DefWindowProcW(hWnd, message, wParam, lParam); + } + + switch (message) { + case WM_CLOSE: + // In case the Windows window was somehow forcibly destroyed without + // WM_CLOSE. + case WM_DESTROY: { + if (cursor_auto_hide_timer_) { + DeleteTimerQueueTimer(nullptr, cursor_auto_hide_timer_, nullptr); + cursor_auto_hide_timer_ = nullptr; + } + { + WindowDestructionReceiver destruction_receiver(this); + OnBeforeClose(destruction_receiver); + if (destruction_receiver.IsWindowDestroyed()) { + break; + } + } + // Set hwnd_ to null to ignore events from now on since this Win32Window + // is entering an indeterminate state - this should be done at some point + // in closing anyway. + hwnd_ = nullptr; + SetWindowLongPtr(hWnd, GWLP_USERDATA, 0); + if (message != WM_DESTROY) { + DestroyWindow(hWnd); + } + OnAfterClose(); + } break; + + case WM_DROPFILES: { + HDROP drop_handle = reinterpret_cast(wParam); + auto drop_count = DragQueryFileW(drop_handle, 0xFFFFFFFFu, nullptr, 0); + if (drop_count > 0) { + // Get required buffer size + UINT path_size = DragQueryFileW(drop_handle, 0, nullptr, 0); + if (path_size > 0 && path_size < 0xFFFFFFFFu) { + std::u16string path; + ++path_size; // Ensure space for the null terminator + path.resize(path_size); // Reserve space + // Only getting first file dropped (other files ignored) + path_size = DragQueryFileW(drop_handle, 0, (LPWSTR)&path[0], path_size); + if (path_size > 0) { + path.resize(path_size); // Will drop the null terminator + FileDropEvent e(this, rex::to_path(path)); + WindowDestructionReceiver destruction_receiver(this); + OnFileDrop(e, destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + DragFinish(drop_handle); + break; + } + } + } + } + DragFinish(drop_handle); + } break; + + case WM_MOVE: { + MonitorUpdateEvent e(this, false); + OnMonitorUpdate(e); + } break; + + case WM_SIZE: { + if (batched_size_update_depth_) { + batched_size_update_contained_wm_size_ = true; + } else { + WindowDestructionReceiver destruction_receiver(this); + HandleSizeUpdate(destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + break; + } + } + } break; + + case WM_PAINT: { + if (batched_size_update_depth_) { + // Avoid painting an outdated surface during a batched size update when + // WM_SIZE handling is deferred. + batched_size_update_contained_wm_paint_ = true; + } else { + ValidateRect(hwnd_, nullptr); + OnPaint(); + } + // Custom painting via OnPaint - don't pass to DefWindowProc. + return 0; + } break; + + case WM_ERASEBKGND: { + if (HasSurface()) { + // Don't erase between paints because painting may be dropped if nothing + // has changed since the last one. + return 0; + } + } break; + + case WM_DISPLAYCHANGE: { + MonitorUpdateEvent e(this, true); + OnMonitorUpdate(e); + } break; + + case WM_DPICHANGED: { + // Note that for some reason, WM_DPICHANGED is not sent when the window is + // borderless fullscreen with per-monitor DPI awareness v1. + + dpi_ = GetCurrentDpi(); + + WindowDestructionReceiver destruction_receiver(this); + + { + UISetupEvent e(this); + OnDpiChanged(e, destruction_receiver); + // The window might have been closed by the handler, check hwnd_ too + // since it's needed below. + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + break; + } + } + + auto rect = reinterpret_cast(lParam); + if (rect) { + // SetWindowPos arguments according to WM_DPICHANGED MSDN documentation. + // https://docs.microsoft.com/en-us/windows/win32/hidpi/wm-dpichanged + // There's no need to handle the maximized state any special way (by + // updating the window placement instead of the window position in this + // case, for instance), as Windows (by design) restores the window when + // changing the DPI to a new one. + SetWindowPos(hwnd_, nullptr, int(rect->left), int(rect->top), int(rect->right - rect->left), + int(rect->bottom - rect->top), SWP_NOZORDER | SWP_NOACTIVATE); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + break; + } + } + } break; + + case WM_KILLFOCUS: { + WindowDestructionReceiver destruction_receiver(this); + OnFocusUpdate(false, destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + break; + } + } break; + + case WM_SETFOCUS: { + WindowDestructionReceiver destruction_receiver(this); + OnFocusUpdate(true, destruction_receiver); + if (destruction_receiver.IsWindowDestroyedOrClosed()) { + break; + } + } break; + + case WM_SETCURSOR: { + if (reinterpret_cast(wParam) == hwnd_ && HasFocus() && LOWORD(lParam) == HTCLIENT) { + switch (GetCursorVisibility()) { + case CursorVisibility::kAutoHidden: { + // Always revealing the cursor in case of events like clicking, but + // WM_MOUSEMOVE messages may be sent for reasons not always + // involving actual mouse movement performed by the user. Revealing + // the cursor in case of movement is done in HandleMouse instead. + if (HIWORD(lParam) != WM_MOUSEMOVE) { + cursor_currently_auto_hidden_ = false; + SetCursorAutoHideTimer(); + } + if (cursor_currently_auto_hidden_) { + SetCursor(nullptr); + return TRUE; + } + } break; + case CursorVisibility::kHidden: + SetCursor(nullptr); + return TRUE; + default: + break; + } + } + // For the non-client area, and for visible cursor, letting normal + // processing happen, setting the cursor to an arrow or to something + // specific to non-client parts of the window. + } break; + + case kUserMessageAutoHideCursor: { + // Recheck the cursor visibility - the callback might have been called + // before or while the timer is deleted. Also ignore messages from + // outdated mouse interactions. + if (GetCursorVisibility() == CursorVisibility::kAutoHidden && + wParam == last_cursor_auto_hide_queued) { + // The timer object is not needed anymore. + if (cursor_auto_hide_timer_) { + DeleteTimerQueueTimer(nullptr, cursor_auto_hide_timer_, nullptr); + cursor_auto_hide_timer_ = nullptr; + } + cursor_currently_auto_hidden_ = true; + SetCursorIfFocusedOnClientArea(nullptr); + } + return 0; + } break; + + case WM_TABLET_QUERYSYSTEMGESTURESTATUS: + return + // disables press and hold (right-click) gesture + TABLET_DISABLE_PRESSANDHOLD | + // disables UI feedback on pen up (waves) + TABLET_DISABLE_PENTAPFEEDBACK | + // disables UI feedback on pen button down (circle) + TABLET_DISABLE_PENBARRELFEEDBACK | + // disables pen flicks (back, forward, drag down, drag up) + TABLET_DISABLE_FLICKS | TABLET_DISABLE_TOUCHSWITCH | TABLET_DISABLE_SMOOTHSCROLLING | + TABLET_DISABLE_TOUCHUIFORCEON | TABLET_ENABLE_MULTITOUCHDATA; + + case WM_MENUCOMMAND: { + MENUINFO menu_info = {}; + menu_info.cbSize = sizeof(menu_info); + menu_info.fMask = MIM_MENUDATA; + GetMenuInfo(HMENU(lParam), &menu_info); + auto parent_item = reinterpret_cast(menu_info.dwMenuData); + auto child_item = reinterpret_cast(parent_item->child(wParam)); + assert_not_null(child_item); + WindowDestructionReceiver destruction_receiver(this); + child_item->OnSelected(); + if (destruction_receiver.IsWindowDestroyed()) { + break; + } + // The menu item might have been destroyed by its OnSelected, don't do + // anything with it here from now on. + } break; + } + + // The window might have been destroyed by the handlers, don't interact with + // *this in this function from now on. + + // Passing the original hWnd argument rather than hwnd_ as the window might + // have been closed or destroyed by a handler, making hwnd_ null even though + // DefWindowProc still needs to be called to propagate the closing-related + // messages needed by Windows, or inaccessible (due to use-after-free) at all. + return DefWindowProcW(hWnd, message, wParam, lParam); +} + +LRESULT CALLBACK Win32Window::WndProcThunk(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { + if (hWnd) { + Win32Window* window = nullptr; + if (message == WM_NCCREATE) { + auto create_struct = reinterpret_cast(lParam); + window = reinterpret_cast(create_struct->lpCreateParams); + SetWindowLongPtr(hWnd, GWLP_USERDATA, (__int3264)(LONG_PTR)window); + // Don't miss any messages (as they may have effect on the actual state + // stored in Win32Window) sent before the completion of CreateWindowExW + // dropped because `window->hwnd_ != hWnd`, when the result of + // CreateWindowExW still hasn't been assigned to `hwnd_` (however, don't + // reattach this window to a closed window if WM_NCCREATE was somehow sent + // to a window being closed). + if (window->phase() == Phase::kOpening) { + assert_true(!window->hwnd_ || window->hwnd_ == hWnd); + window->hwnd_ = hWnd; + } + // Enable non-client area DPI scaling for AdjustWindowRectExForDpi to work + // correctly between Windows 10 1607 (when AdjustWindowRectExForDpi and + // EnableNonClientDpiScaling were added) and 1703 (when per-monitor + // awareness version 2 was added with automatically enabled non-client + // area DPI scaling). + const Win32WindowedAppContext& win32_app_context = + static_cast(window->app_context()); + const Win32WindowedAppContext::PerMonitorDpiV2Api* per_monitor_dpi_v2_api = + win32_app_context.per_monitor_dpi_v2_api(); + if (per_monitor_dpi_v2_api) { + per_monitor_dpi_v2_api->enable_non_client_dpi_scaling(hWnd); + } + // Already fully handled, no need to call Win32Window::WndProc. + } else { + window = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); + if (window && window->hwnd_ == hWnd) { + return window->WndProc(hWnd, message, wParam, lParam); + } + } + } + return DefWindowProcW(hWnd, message, wParam, lParam); +} + +std::unique_ptr MenuItem::Create(Type type, const std::string& text, + const std::string& hotkey, + std::function callback) { + return std::make_unique(type, text, hotkey, callback); +} + +Win32MenuItem::Win32MenuItem(Type type, const std::string& text, const std::string& hotkey, + std::function callback) + : MenuItem(type, text, hotkey, std::move(callback)) { + switch (type) { + case MenuItem::Type::kNormal: + handle_ = CreateMenu(); + break; + case MenuItem::Type::kPopup: + handle_ = CreatePopupMenu(); + break; + default: + // May just be a placeholder. + break; + } + if (handle_) { + MENUINFO menu_info = {}; + menu_info.cbSize = sizeof(menu_info); + menu_info.fMask = MIM_MENUDATA | MIM_STYLE; + menu_info.dwMenuData = ULONG_PTR(this); + menu_info.dwStyle = MNS_NOTIFYBYPOS; + SetMenuInfo(handle_, &menu_info); + } +} + +Win32MenuItem::~Win32MenuItem() { + if (handle_) { + DestroyMenu(handle_); + } +} + +void Win32MenuItem::SetEnabled(bool enabled) { + UINT enable_flags = MF_BYPOSITION | (enabled ? MF_ENABLED : MF_GRAYED); + UINT i = 0; + for (auto iter = children_.begin(); iter != children_.end(); ++iter, ++i) { + EnableMenuItem(handle_, i, enable_flags); + } +} + +void Win32MenuItem::OnChildAdded(MenuItem* generic_child_item) { + auto child_item = static_cast(generic_child_item); + + switch (child_item->type()) { + case MenuItem::Type::kNormal: + // Nothing special. + break; + case MenuItem::Type::kPopup: { + auto wide_text = rex::string::to_utf16(child_item->text()); + AppendMenuW(handle_, MF_POPUP, reinterpret_cast(child_item->handle()), + reinterpret_cast(wide_text.c_str())); + } break; + case MenuItem::Type::kSeparator: + AppendMenuW(handle_, MF_SEPARATOR, UINT_PTR(child_item->handle_), 0); + break; + case MenuItem::Type::kString: + auto full_name = child_item->text(); + if (!child_item->hotkey().empty()) { + full_name += "\t" + child_item->hotkey(); + } + auto wide_name = rex::string::to_utf16(full_name); + AppendMenuW(handle_, MF_STRING, UINT_PTR(child_item->handle_), + reinterpret_cast(wide_name.c_str())); + break; + } +} + +void Win32MenuItem::OnChildRemoved(MenuItem* generic_child_item) {} + +} // namespace ui +} // namespace rex diff --git a/src/ui/windowed_app.cpp b/src/ui/windowed_app.cpp new file mode 100644 index 0000000..ab9950e --- /dev/null +++ b/src/ui/windowed_app.cpp @@ -0,0 +1,27 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include + +#include + +namespace rex { +namespace ui { + +#if XE_UI_WINDOWED_APPS_IN_LIBRARY +// A zero-initialized pointer to remove dependence on the initialization order +// of the map relatively to the app creator proxies. +std::unordered_map* WindowedApp::creators_; +#endif // XE_UI_WINDOWED_APPS_IN_LIBRARY + +} // namespace ui +} // namespace rex diff --git a/src/ui/windowed_app_context.cpp b/src/ui/windowed_app_context.cpp new file mode 100644 index 0000000..2a25838 --- /dev/null +++ b/src/ui/windowed_app_context.cpp @@ -0,0 +1,178 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include + +namespace rex { +namespace ui { + +WindowedAppContext::~WindowedAppContext() { + // The UI thread is responsible for managing the lifetime of the context. + assert_true(IsInUIThread()); + + // It's okay to destroy the context from a platform's internal UI loop + // callback, primarily on platforms where the loop is run by the OS itself, + // and the context can't be created and destroyed in a RAII way, rather, it's + // created in an initialization handler and destroyed in a shutdown handler + // called by the OS. However, destruction must not be done from within the + // queued functions - as in this case, the pending function container, the + // mutex, will be accessed after having been destroyed already. + + // Make sure CallInUIThreadDeferred doesn't call + // NotifyUILoopOfPendingFunctions, which is virtual. + is_in_destructor_ = true; + // Make sure the final ExecutePendingFunctionsFromUIThread doesn't call + // PlatformQuitFromUIThread, which is virtual. + has_quit_ = true; + + // Platform-specific quit is expected to be performed by the subclass (the + // order of it vs. the final ExecutePendingFunctionsFromUIThread shouldn't + // matter anymore, the implementation may assume that no pending functions + // will be requested for execution specifically via the platform-specific + // loop, as there should be no more references to the context in other + // threads), can't call the virtual PlatformQuitFromUIThread anymore. + ExecutePendingFunctionsFromUIThread(true); +} + +bool WindowedAppContext::CallInUIThreadDeferred(std::function function) { + { + std::unique_lock pending_functions_lock(pending_functions_mutex_); + if (!pending_functions_accepted_) { + // Will not be called as the loop will not be executed anymore. + return false; + } + pending_functions_.emplace_back(std::move(function)); + } + // Notify unconditionally, even if currently running pending functions. It's + // possible for pending functions themselves to run inner platform message + // loops, such as when displaying dialogs - in this case, the notification is + // needed to run the new function from such an inner loop. A modal loop can be + // started even in leftovers happening during the quit, where there's still + // opportunity for enqueueing and executing new pending functions - so only + // checking if called in the destructor (it's safe to check this without + // locking a mutex as it's assumed that if the object is already being + // destroyed, no other threads can have references to it - any access would + // result in a race condition anyway) as the subclass has already been + // destroyed. Having pending_functions_mutex_ unlocked also means that + // NotifyUILoopOfPendingFunctions may be done while the UI thread is calling + // or has already called PlatformQuitFromUIThread - but it's better than + // keeping pending_functions_mutex_ locked as NotifyUILoopOfPendingFunctions + // may be implemented as pushing to a fixed-size pipe, in which case it will + // have to wait until free space is available, but if the UI thread tries to + // lock the mutex afterwards to execute pending functions (and encouters + // contention), nothing will be able to receive from the pipe anymore and thus + // free the space, causing a deadlock. + if (!is_in_destructor_) { + NotifyUILoopOfPendingFunctions(); + } + return true; +} + +bool WindowedAppContext::CallInUIThread(std::function function) { + if (IsInUIThread()) { + // The intention is just to make sure the code is executed in the UI thread, + // don't defer execution if no need to. + function(); + return true; + } + return CallInUIThreadDeferred(std::move(function)); +} + +bool WindowedAppContext::CallInUIThreadSynchronous(std::function function) { + if (IsInUIThread()) { + // Prevent deadlock if called from the UI thread. + function(); + return true; + } + rex::thread::Fence fence; + if (!CallInUIThreadDeferred([&function, &fence]() { + function(); + fence.Signal(); + })) { + return false; + } + fence.Wait(); + return true; +} + +void WindowedAppContext::QuitFromUIThread() { + assert_true(IsInUIThread()); + bool has_quit_previously = has_quit_; + // Make sure PlatformQuitFromUIThread is called only once, not from nested + // pending function execution during the quit - otherwise it will be called + // when it's still possible to add new pending functions. This isn't as wrong + // as calling PlatformQuitFromUIThread from the destructor, but still a part + // of the contract for simplicity. + has_quit_ = true; + // Executing pending function unconditionally because it's the contract of + // this method that functions are executed immediately. + ExecutePendingFunctionsFromUIThread(true); + if (has_quit_previously) { + // Potentially calling QuitFromUIThread from inside a pending function (in + // the worst and dangerous case, from a pending function executed in the + // destructor - and PlatformQuitFromUIThread is virtual). + return; + } + // Call the platform-specific shutdown while letting it assume that no new + // functions will be queued anymore (but NotifyUILoopOfPendingFunctions may + // still be called after PlatformQuitFromUIThread as the two are not + // interlocked). This is different than the order in the destruction, but + // there this assumption is ensured by the expectation that there should be no + // more references to the context in other threads that would allow queueing + // new functions with calling NotifyUILoopOfPendingFunctions. + PlatformQuitFromUIThread(); +} + +void WindowedAppContext::ExecutePendingFunctionsFromUIThread(bool is_final) { + assert_true(IsInUIThread()); + std::unique_lock pending_functions_lock(pending_functions_mutex_); + while (!pending_functions_.empty()) { + // Removing the function from the queue before executing it, as the function + // itself may call ExecutePendingFunctionsFromUIThread - if it's kept, the + // inner loop will try to execute it again, resulting in potentially endless + // recursion, and even if it's terminated, each level will be trying to + // remove the same function from the queue - instead, actually removing + // other functions, or even beyond the end of the queue. + std::function function = std::move(pending_functions_.front()); + pending_functions_.pop_front(); + // Call the function with the lock released as it may take an indefinitely + // long time to execute if it opens some dialog (possibly with its own + // platform message loop), and in that case, without unlocking, no other + // thread would be able to add new pending functions (which would result in + // unintended waits for user input). This also allows using std::mutex + // instead of std::recursive_mutex. + pending_functions_lock.unlock(); + function(); + pending_functions_lock.lock(); + } + if (is_final) { + // Atomically with completion of the pending functions loop, disallow adding + // new functions after executing the existing ones - it was possible to + // enqueue new functions from the leftover ones as there still was + // opportunity to call them, so it wasn't necessary to disallow adding + // before executing, but now new functions will potentially never be + // executed. This is done even if this is just an inner pending functions + // execution and there's still potential possibility of adding and executing + // new functions in the outer loops - for simplicity and consistency (so + // QuitFromUIThread's behavior doesn't depend as much on the location of the + // call - inside a pending function or from some system callback of the + // window), assuming after a PlatformQuitFromUIThread call, it's not + // possible to add new pending functions anymore. + pending_functions_accepted_ = false; + } +} + +} // namespace ui +} // namespace rex diff --git a/src/ui/windowed_app_context_gtk.cpp b/src/ui/windowed_app_context_gtk.cpp new file mode 100644 index 0000000..4e86138 --- /dev/null +++ b/src/ui/windowed_app_context_gtk.cpp @@ -0,0 +1,106 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include +#include + +namespace rex { +namespace ui { + +GTKWindowedAppContext::~GTKWindowedAppContext() { + // Remove the idle sources as their data pointer (to this context) is now + // outdated. + if (quit_idle_pending_) { + g_source_remove(quit_idle_pending_); + } + if (pending_functions_idle_pending_) { + g_source_remove(pending_functions_idle_pending_); + } +} + +void GTKWindowedAppContext::NotifyUILoopOfPendingFunctions() { + std::lock_guard pending_functions_idle_pending_lock( + pending_functions_idle_pending_mutex_); + if (!pending_functions_idle_pending_) { + pending_functions_idle_pending_ = gdk_threads_add_idle(PendingFunctionsSourceFunc, this); + } +} + +void GTKWindowedAppContext::PlatformQuitFromUIThread() { + if (quit_idle_pending_ || !gtk_main_level()) { + return; + } + gtk_main_quit(); + // Quit from all loops in the context, current inner, upcoming inner (this is + // why the idle function is added even at the main level of 1), until we can + // return to the tail of RunMainGTKLoop. + quit_idle_pending_ = gdk_threads_add_idle(QuitSourceFunc, this); +} + +void GTKWindowedAppContext::RunMainGTKLoop() { + // For safety, in case the quit request somehow happened before the loop. + if (HasQuitFromUIThread()) { + return; + } + assert_zero(gtk_main_level()); + gtk_main(); + // Something else - not QuitFromUIThread - might have done gtk_main_quit for + // the outer loop. If it has exited for some reason, let the context know, so + // pending function won't be added pointlessly. + QuitFromUIThread(); + // Don't interfere with main loops of other contexts that will possibly be + // executed in this thread later (if this is not the only app that will be + // executed in this process, for example, or if some WindowedAppContext-less + // dialog is opened after the windowed app has quit) - cancel the scheduled + // quit chain as we have quit already. + if (quit_idle_pending_) { + g_source_remove(quit_idle_pending_); + quit_idle_pending_ = 0; + } +} + +gboolean GTKWindowedAppContext::PendingFunctionsSourceFunc(gpointer data) { + auto& app_context = *static_cast(data); + // Allow new pending function notifications to be made, and stop tracking the + // lifetime of the idle source that is already being executed and thus + // removed. This must be done before executing the functions (if done after, + // notifications may be missed if they happen between the execution of the + // functions and the reset of pending_functions_idle_pending_). + { + std::lock_guard pending_functions_idle_pending_lock( + app_context.pending_functions_idle_pending_mutex_); + app_context.pending_functions_idle_pending_ = 0; + } + app_context.ExecutePendingFunctionsFromUIThread(); + return G_SOURCE_REMOVE; +} + +gboolean GTKWindowedAppContext::QuitSourceFunc(gpointer data) { + auto app_context = static_cast(data); + guint main_level = gtk_main_level(); + assert_not_zero(main_level); + if (!main_level) { + app_context->quit_idle_pending_ = 0; + return G_SOURCE_REMOVE; + } + gtk_main_quit(); + // Quit from all loops in the context, current inner, upcoming inner (this is + // why the idle function is added even at the main level of 1), until we can + // return to the tail of RunMainGTKLoop. + app_context->quit_idle_pending_ = gdk_threads_add_idle(QuitSourceFunc, app_context); + return G_SOURCE_REMOVE; +} + +} // namespace ui +} // namespace rex diff --git a/src/ui/windowed_app_context_win.cpp b/src/ui/windowed_app_context_win.cpp new file mode 100644 index 0000000..d18820d --- /dev/null +++ b/src/ui/windowed_app_context_win.cpp @@ -0,0 +1,158 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include + +#include +#include + +namespace rex { +namespace ui { + +bool Win32WindowedAppContext::pending_functions_window_class_registered_; + +Win32WindowedAppContext::~Win32WindowedAppContext() { + if (pending_functions_hwnd_) { + DestroyWindow(pending_functions_hwnd_); + } + if (user32_module_) { + FreeLibrary(user32_module_); + } + if (shcore_module_) { + FreeLibrary(shcore_module_); + } +} + +bool Win32WindowedAppContext::Initialize() { + // Logging possibly not initialized in this function yet. + + // Obtain function pointers that may be used for windows if available. + shcore_module_ = LoadLibraryW(L"SHCore.dll"); + if (shcore_module_) { + per_monitor_dpi_v1_api_available_ = true; + per_monitor_dpi_v1_api_available_ &= + (*reinterpret_cast(&per_monitor_dpi_v1_api_.get_dpi_for_monitor) = + GetProcAddress(shcore_module_, "GetDpiForMonitor")) != nullptr; + } + user32_module_ = LoadLibraryW(L"user32.dll"); + if (user32_module_) { + per_monitor_dpi_v2_api_available_ = true; + per_monitor_dpi_v2_api_available_ &= + (*reinterpret_cast(&per_monitor_dpi_v2_api_.adjust_window_rect_ex_for_dpi) = + GetProcAddress(user32_module_, "AdjustWindowRectExForDpi")) != nullptr; + per_monitor_dpi_v2_api_available_ &= + (*reinterpret_cast(&per_monitor_dpi_v2_api_.enable_non_client_dpi_scaling) = + GetProcAddress(user32_module_, "EnableNonClientDpiScaling")) != nullptr; + per_monitor_dpi_v2_api_available_ &= + (*reinterpret_cast(&per_monitor_dpi_v2_api_.get_dpi_for_system) = + GetProcAddress(user32_module_, "GetDpiForSystem")) != nullptr; + per_monitor_dpi_v2_api_available_ &= + (*reinterpret_cast(&per_monitor_dpi_v2_api_.get_dpi_for_window) = + GetProcAddress(user32_module_, "GetDpiForWindow")) != nullptr; + } + + // Create the message-only window for executing pending functions - using a + // window instead of executing them between iterations so non-main message + // loops, such as Windows modals, can execute pending functions too. + static const WCHAR kPendingFunctionsWindowClassName[] = L"RexPendingFunctionsWindowClass"; + if (!pending_functions_window_class_registered_) { + WNDCLASSEXW pending_functions_window_class = {}; + pending_functions_window_class.cbSize = sizeof(pending_functions_window_class); + pending_functions_window_class.lpfnWndProc = PendingFunctionsWndProc; + pending_functions_window_class.hInstance = hinstance_; + pending_functions_window_class.lpszClassName = kPendingFunctionsWindowClassName; + if (!RegisterClassExW(&pending_functions_window_class)) { + return false; + } + pending_functions_window_class_registered_ = true; + } + pending_functions_hwnd_ = CreateWindowExW( + 0, kPendingFunctionsWindowClassName, L"Rex Pending Functions", WS_OVERLAPPED, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_MESSAGE, nullptr, hinstance_, this); + if (!pending_functions_hwnd_) { + return false; + } + + return true; +} + +void Win32WindowedAppContext::NotifyUILoopOfPendingFunctions() { + while (!PostMessageW(pending_functions_hwnd_, kPendingFunctionsWindowClassMessageExecute, 0, 0)) { + Sleep(1); + } +} + +void Win32WindowedAppContext::PlatformQuitFromUIThread() { + // Send WM_QUIT to whichever loop happens to process it - may be the loop of a + // built-in modal window, which is unaware of HasQuitFromUIThread, don't let + // it delay quitting indefinitely. + PostQuitMessage(EXIT_SUCCESS); +} + +int Win32WindowedAppContext::RunMainMessageLoop() { + int result = EXIT_SUCCESS; + MSG message; + // The HasQuitFromUIThread check is not absolutely required, but for + // additional safety in case WM_QUIT is not received for any reason. + while (!HasQuitFromUIThread()) { + BOOL message_result = GetMessageW(&message, nullptr, 0, 0); + if (message_result == 0 || message_result == -1) { + // WM_QUIT (0 - this is the primary message loop, no need to resend, also + // contains the result from PostQuitMessage in wParam) or an error + // (-1). Quitting the context will run the pending functions. Getting + // WM_QUIT doesn't imply that QuitFromUIThread has been called already, it + // may originate in some place other than PlatformQuitFromUIThread as + // well - call it to finish everything including the pending functions. + QuitFromUIThread(); + result = message_result ? EXIT_FAILURE : int(message.wParam); + break; + } + TranslateMessage(&message); + DispatchMessageW(&message); + } + return result; +} + +LRESULT CALLBACK Win32WindowedAppContext::PendingFunctionsWndProc(HWND hwnd, UINT message, + WPARAM wparam, LPARAM lparam) { + if (message == WM_CLOSE) { + // Need the window for the entire context's lifetime, don't allow anything + // to close it. + return 0; + } + if (message == WM_NCCREATE) { + SetWindowLongPtrW( + hwnd, GWLP_USERDATA, + reinterpret_cast(reinterpret_cast(lparam)->lpCreateParams)); + } else { + auto app_context = + reinterpret_cast(GetWindowLongPtrW(hwnd, GWLP_USERDATA)); + if (app_context) { + switch (message) { + case WM_DESTROY: + // The message-only window owned by the context is being destroyed, + // thus the context won't be able to execute pending functions + // anymore - can't continue functioning normally. + app_context->QuitFromUIThread(); + break; + case kPendingFunctionsWindowClassMessageExecute: + app_context->ExecutePendingFunctionsFromUIThread(); + return 0; + default: + break; + } + } + } + return DefWindowProcW(hwnd, message, wparam, lparam); +} + +} // namespace ui +} // namespace rex diff --git a/src/ui/windowed_app_main_posix.cpp b/src/ui/windowed_app_main_posix.cpp new file mode 100644 index 0000000..ebabe7f --- /dev/null +++ b/src/ui/windowed_app_main_posix.cpp @@ -0,0 +1,79 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern "C" int main(int argc_pre_gtk, char** argv_pre_gtk) { + // Before touching anything GTK+, make sure that when running on Wayland, + // we'll still get an X11 (Xwayland) window + setenv("GDK_BACKEND", "x11", 1); + + // Initialize GTK+, which will handle and remove its own arguments from argv. + // Both GTK+ and Xenia use --option=value argument format (see man + // gtk-options), however, it's meaningless to try to parse the same argument + // both as a GTK+ one and as a cvar. Make GTK+ options take precedence in case + // of a name collision, as there's an alternative way of setting Xenia options + // (the config). + int argc_post_gtk = argc_pre_gtk; + char** argv_post_gtk = argv_pre_gtk; + if (!gtk_init_check(&argc_post_gtk, &argv_post_gtk)) { + // Logging has not been initialized yet. + std::fputs("Failed to initialize GTK+\n", stderr); + return EXIT_FAILURE; + } + + auto remaining = rex::cvar::Init(argc_post_gtk, argv_post_gtk); + rex::cvar::ApplyEnvironment(); + rex::InitLoggingEarly(); + + int result; + + { + rex::ui::GTKWindowedAppContext app_context; + + std::unique_ptr app = rex::ui::GetWindowedAppCreator()(app_context); + + // Match remaining positional args to app's expected options + const auto& option_names = app->GetPositionalOptions(); + std::map parsed; + size_t count = std::min(remaining.size(), option_names.size()); + for (size_t i = 0; i < count; ++i) { + parsed[option_names[i]] = remaining[i]; + } + app->SetParsedArguments(std::move(parsed)); + + if (app->OnInitialize()) { + app_context.RunMainGTKLoop(); + result = EXIT_SUCCESS; + } else { + result = EXIT_FAILURE; + } + + app->InvokeOnDestroy(); + } + + // Logging may still be needed in the destructors. + rex::ShutdownLogging(); + + return result; +} diff --git a/src/ui/windowed_app_main_win.cpp b/src/ui/windowed_app_main_win.cpp new file mode 100644 index 0000000..69bc5e6 --- /dev/null +++ b/src/ui/windowed_app_main_win.cpp @@ -0,0 +1,111 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2021 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + * + * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace { + +// Convert wide argv from CommandLineToArgvW to UTF-8 argc/argv for cvar::Init +std::vector WideArgsToUtf8(int argc, wchar_t** wargv) { + std::vector args; + args.reserve(static_cast(argc)); + for (int i = 0; i < argc; ++i) { + std::wstring wide(wargv[i]); + if (wide.empty()) { + args.emplace_back(); + continue; + } + int size = WideCharToMultiByte(CP_UTF8, 0, wide.data(), static_cast(wide.size()), nullptr, + 0, nullptr, nullptr); + std::string utf8(static_cast(size), '\0'); + WideCharToMultiByte(CP_UTF8, 0, wide.data(), static_cast(wide.size()), utf8.data(), size, + nullptr, nullptr); + args.push_back(std::move(utf8)); + } + return args; +} + +} // namespace + +int WINAPI wWinMain(HINSTANCE hinstance, HINSTANCE hinstance_prev, LPWSTR command_line, + int show_cmd) { + (void)hinstance_prev; + (void)command_line; + + // Convert wide command line to UTF-8 argc/argv and parse CVARs + int wargc = 0; + wchar_t** wargv = CommandLineToArgvW(GetCommandLineW(), &wargc); + auto utf8_args = WideArgsToUtf8(wargc, wargv); + LocalFree(wargv); + + // Build char* argv for cvar::Init + std::vector argv_ptrs; + argv_ptrs.reserve(utf8_args.size()); + for (auto& s : utf8_args) { + argv_ptrs.push_back(s.data()); + } + auto remaining = rex::cvar::Init(static_cast(argv_ptrs.size()), argv_ptrs.data()); + rex::cvar::ApplyEnvironment(); + rex::InitLoggingEarly(); + + int result; + + { + rex::ui::Win32WindowedAppContext app_context(hinstance, show_cmd); + // TODO(Triang3l): Initialize creates a window. Set DPI awareness via the + // manifest. + if (!app_context.Initialize()) { + return EXIT_FAILURE; + } + + std::unique_ptr app = rex::ui::GetWindowedAppCreator()(app_context); + + // Match remaining positional args to app's expected options + const auto& option_names = app->GetPositionalOptions(); + std::map parsed; + size_t count = std::min(remaining.size(), option_names.size()); + for (size_t i = 0; i < count; ++i) { + parsed[option_names[i]] = remaining[i]; + } + app->SetParsedArguments(std::move(parsed)); + + // Initialize COM on the UI thread with the apartment-threaded concurrency + // model, so dialogs can be used. + if (FAILED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED))) { + return EXIT_FAILURE; + } + + // TODO: Port InitializeWin32App from Xenia + // rex::InitializeWin32App(app->GetName()); + + result = app->OnInitialize() ? app_context.RunMainMessageLoop() : EXIT_FAILURE; + + app->InvokeOnDestroy(); + } + + // TODO: Port ShutdownWin32App from Xenia + // Logging may still be needed in the destructors. + // rex::ShutdownWin32App(); + + CoUninitialize(); + + return result; +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..3e67044 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,8 @@ +# ReXGlue Tests +# Test infrastructure for PPC instruction validation and unit tests + +# Unit tests for core components +add_subdirectory(unit) + +# PPC instruction tests (requires PPC toolchain) +add_subdirectory(ppc) diff --git a/tests/ppc/CMakeLists.txt b/tests/ppc/CMakeLists.txt new file mode 100644 index 0000000..00acefa --- /dev/null +++ b/tests/ppc/CMakeLists.txt @@ -0,0 +1,111 @@ +# PowerPC Instruction Test Suite +# Compiles PPC assembly tests and generates Catch2 test cases + +include(ppc_test_pipeline) + +# Output directories +set(PPC_OBJ_DIR ${CMAKE_BINARY_DIR}/tests/ppc/obj) +set(PPC_BIN_DIR ${CMAKE_BINARY_DIR}/tests/ppc/bin) +set(PPC_GEN_DIR ${CMAKE_BINARY_DIR}/tests/ppc/generated) + +file(MAKE_DIRECTORY ${PPC_OBJ_DIR}) +file(MAKE_DIRECTORY ${PPC_BIN_DIR}) +file(MAKE_DIRECTORY ${PPC_GEN_DIR}) + +# Collect and build all assembly test files +file(GLOB ASM_FILES ${CMAKE_CURRENT_SOURCE_DIR}/asm/*.s) +list(LENGTH ASM_FILES NUM_TESTS) + +if(NUM_TESTS EQUAL 0) + message(WARNING "No test files found in ${CMAKE_CURRENT_SOURCE_DIR}/asm/") + return() +endif() + +message(STATUS "Found ${NUM_TESTS} PPC instruction test files") + +foreach(ASM_FILE ${ASM_FILES}) + ppc_add_test_binary(${ASM_FILE} ${PPC_OBJ_DIR} ${PPC_BIN_DIR}) +endforeach() + +get_property(TEST_BINS GLOBAL PROPERTY PPC_TEST_BINS) +get_property(TEST_MAPS GLOBAL PROPERTY PPC_TEST_MAPS) + +# Generate Catch2 test code from recompiled binaries +add_custom_command( + OUTPUT ${PPC_GEN_DIR}/ppc_test_functions.cpp + ${PPC_GEN_DIR}/ppc_test_cases.cpp + ${PPC_GEN_DIR}/ppc_test_decls.h + COMMAND $ recompile-tests + --output=${PPC_GEN_DIR} + --bin_dir=${PPC_BIN_DIR} + --asm_dir=${CMAKE_CURRENT_SOURCE_DIR}/asm + DEPENDS ${TEST_BINS} ${TEST_MAPS} ${ASM_FILES} rexglue + COMMENT "Generating Catch2 test code with rexglue" + VERBATIM +) + +add_executable(ppc_tests + ${PPC_GEN_DIR}/ppc_test_functions.cpp + ${PPC_GEN_DIR}/ppc_test_cases.cpp +) + +set_source_files_properties( + ${PPC_GEN_DIR}/ppc_test_functions.cpp + ${PPC_GEN_DIR}/ppc_test_cases.cpp + ${PPC_GEN_DIR}/ppc_test_decls.h + PROPERTIES GENERATED TRUE +) + +target_include_directories(ppc_tests PRIVATE + ${PROJECT_SOURCE_DIR}/include + ${PPC_GEN_DIR} +) + +target_link_libraries(ppc_tests PRIVATE + simde + rexruntime + rexcore + fmt::fmt + Catch2::Catch2WithMain +) + +# Delay-load FidelityFX DLLs so ppc_tests can run without them. +if(WIN32) + if(TARGET amd_fidelityfx_vk) + target_link_options(ppc_tests PRIVATE + "LINKER:/DELAYLOAD:$") + endif() + if(TARGET amd_fidelityfx_dx12) + target_link_options(ppc_tests PRIVATE + "LINKER:/DELAYLOAD:$") + endif() + if(TARGET amd_fidelityfx_vk OR TARGET amd_fidelityfx_dx12) + target_link_libraries(ppc_tests PRIVATE delayimp) + endif() +endif() + +set_target_properties(ppc_tests PROPERTIES + RUNTIME_OUTPUT_DIRECTORY $ +) +if(UNIX AND NOT APPLE) + set_target_properties(ppc_tests PROPERTIES + INSTALL_RPATH "$ORIGIN" + BUILD_WITH_INSTALL_RPATH ON + ) +endif() + +target_compile_options(ppc_tests PRIVATE + -UTRACY_ENABLE -UREXGLUE_ENABLE_PROFILING + -UREXGLUE_ENABLE_PERF_COUNTERS -UREXGLUE_PROFILE_GUEST_FUNCTIONS + -msse4.1 -mssse3 +) + +include(Catch) +catch_discover_tests(ppc_tests + TEST_PREFIX "ppc." + PROPERTIES + LABELS "ppc;instructions" + TIMEOUT 60 +) + +message(STATUS "Configured PPC test suite with ${NUM_TESTS} test files") diff --git a/tests/ppc/asm/instr_add.s b/tests/ppc/asm/instr_add.s new file mode 100644 index 0000000..5595c78 --- /dev/null +++ b/tests/ppc/asm/instr_add.s @@ -0,0 +1,178 @@ +test_add_1: + #_ REGISTER_IN r5 0x00100000 + #_ REGISTER_IN r25 0x0000FFFF + + add r11, r5, r25 + + blr + #_ REGISTER_OUT r5 0x00100000 + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x0010FFFF + +test_add_1_constant: + lis r5, 0x10 + li r25, -1 + clrldi r25, r25, 48 + + add r11, r5, r25 + + blr + #_ REGISTER_OUT r5 0x00100000 + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x0010FFFF + +test_add_2: + #_ REGISTER_IN r0 0x00100000 + #_ REGISTER_IN r25 0x0000FFFF + + add r11, r0, r25 + + blr + #_ REGISTER_OUT r0 0x00100000 + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x0010FFFF + +test_add_2_constant: + lis r0, 0x10 + li r25, -1 + clrldi r25, r25, 48 + + add r11, r0, r25 + + blr + #_ REGISTER_OUT r0 0x00100000 + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x0010FFFF + +test_add_cr_1: + #_ REGISTER_IN r5 0x00100000 + #_ REGISTER_IN r25 0x0000FFFF + + add. r11, r5, r25 + mfcr r12 + + blr + #_ REGISTER_OUT r5 0x00100000 + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x0010FFFF + #_ REGISTER_OUT r12 0x40000000 + +test_add_cr_1_constant: + lis r5, 0x10 + li r25, -1 + clrldi r25, r25, 48 + + add. r11, r5, r25 + mfcr r12 + + blr + #_ REGISTER_OUT r5 0x00100000 + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x0010FFFF + #_ REGISTER_OUT r12 0x40000000 + +test_add_cr_2: + #_ REGISTER_IN r0 0x00100000 + #_ REGISTER_IN r25 0x0000FFFF + + add. r11, r0, r25 + mfcr r12 + + blr + #_ REGISTER_OUT r0 0x00100000 + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x0010FFFF + #_ REGISTER_OUT r12 0x40000000 + +test_add_cr_2_constant: + lis r0, 0x10 + li r25, -1 + clrldi r25, r25, 48 + + add. r11, r0, r25 + mfcr r12 + + blr + #_ REGISTER_OUT r0 0x00100000 + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x0010FFFF + #_ REGISTER_OUT r12 0x40000000 + +test_add_cr_3: + #_ REGISTER_IN r0 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r25 0x000000000000FFFF + + add. r11, r0, r25 + mfcr r12 + + blr + #_ REGISTER_OUT r0 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0x000000000000FFFF + #_ REGISTER_OUT r11 0x000000000000FFFE + #_ REGISTER_OUT r12 0x40000000 + +test_add_cr_3_constant: + li r0, -1 + li r25, -1 + clrldi r25, r25, 48 + + add. r11, r0, r25 + mfcr r12 + + blr + #_ REGISTER_OUT r0 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0x000000000000FFFF + #_ REGISTER_OUT r11 0x000000000000FFFE + #_ REGISTER_OUT r12 0x40000000 + +test_add_cr_4: + #_ REGISTER_IN r0 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r25 0x0000000000000001 + + add. r11, r0, r25 + mfcr r12 + + blr + #_ REGISTER_OUT r0 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0x0000000000000001 + #_ REGISTER_OUT r11 0x0000000000000000 + #_ REGISTER_OUT r12 0x20000000 + +test_add_cr_4_constant: + li r0, -1 + li r25, 1 + + add. r11, r0, r25 + mfcr r12 + + blr + #_ REGISTER_OUT r0 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0x0000000000000001 + #_ REGISTER_OUT r11 0x0000000000000000 + #_ REGISTER_OUT r12 0x20000000 + +test_add_cr_5: + #_ REGISTER_IN r0 -50 + #_ REGISTER_IN r25 -25 + + add. r11, r0, r25 + mfcr r12 + + blr + #_ REGISTER_OUT r0 -50 + #_ REGISTER_OUT r25 -25 + #_ REGISTER_OUT r11 -75 + #_ REGISTER_OUT r12 0x80000000 + +test_add_cr_5_constant: + li r0, -50 + li r25, -25 + + add. r11, r0, r25 + mfcr r12 + + blr + #_ REGISTER_OUT r0 -50 + #_ REGISTER_OUT r25 -25 + #_ REGISTER_OUT r11 -75 + #_ REGISTER_OUT r12 0x80000000 diff --git a/tests/ppc/asm/instr_addc.s b/tests/ppc/asm/instr_addc.s new file mode 100644 index 0000000..7c0b64b --- /dev/null +++ b/tests/ppc/asm/instr_addc.s @@ -0,0 +1,266 @@ +test_addc_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 2 + addc r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 3 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + #_ REGISTER_OUT r6 0 + +test_addc_1_constant: + li r4, 1 + li r5, 2 + addc r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 3 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + #_ REGISTER_OUT r6 0 + +test_addc_2: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0 + addc r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 0 + +test_addc_2_constant: + li r4, -1 + li r5, 0 + addc r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 0 + +test_addc_3: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + addc r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 1 + +test_addc_3_constant: + li r4, -1 + li r5, 1 + addc r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 1 + +test_addc_4: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 123 + addc r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0x000000000000007A + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 123 + #_ REGISTER_OUT r6 1 + +test_addc_4_constant: + li r4, -1 + li r5, 123 + addc r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0x000000000000007A + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 123 + #_ REGISTER_OUT r6 1 + +test_addc_5: + #_ REGISTER_IN r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + addc r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_addc_5_constant: + li r5, -1 + srdi r4, r5, 1 + addc r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_addc_cr_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 2 + addc. r3, r4, r5 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 3 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x40000000 + +test_addc_cr_1_constant: + li r4, 1 + li r5, 2 + addc. r3, r4, r5 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 3 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x40000000 + +test_addc_cr_2: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0 + addc. r3, r4, r5 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x80000000 + +test_addc_cr_2_constant: + li r4, -1 + li r5, 0 + addc. r3, r4, r5 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x80000000 + +test_addc_cr_3: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + addc. r3, r4, r5 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x20000000 + +test_addc_cr_3_constant: + li r4, -1 + li r5, 1 + addc. r3, r4, r5 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x20000000 + +test_addc_cr_4: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 123 + addc. r3, r4, r5 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x000000000000007A + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 123 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x40000000 + +test_addc_cr_4_constant: + li r4, -1 + li r5, 123 + addc. r3, r4, r5 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x000000000000007A + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 123 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x40000000 + +test_addc_cr_5: + #_ REGISTER_IN r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + addc. r3, r4, r5 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x80000000 + +test_addc_cr_5_constant: + li r5, -1 + srdi r4, r5, 1 + addc. r3, r4, r5 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x80000000 + +test_addc_cr_6: + #_ REGISTER_IN r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_IN r5 2 + addc. r3, r4, r5 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x8000000000000001 + #_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 2 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x40000000 + +test_addc_cr_6_constant: + li r4, -1 + srdi r4, r4, 1 + li r5, 2 + addc. r3, r4, r5 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x8000000000000001 + #_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 2 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x40000000 diff --git a/tests/ppc/asm/instr_adde.s b/tests/ppc/asm/instr_adde.s new file mode 100644 index 0000000..c81cb1a --- /dev/null +++ b/tests/ppc/asm/instr_adde.s @@ -0,0 +1,579 @@ +test_adde_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 2 + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 3 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + #_ REGISTER_OUT r6 0 + +test_adde_1_constant: + li r4, 1 + li r5, 2 + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 3 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + #_ REGISTER_OUT r6 0 + +test_adde_2: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 2 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 4 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + #_ REGISTER_OUT r6 0 + +test_adde_2_constant: + li r4, 1 + li r5, 2 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 4 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + #_ REGISTER_OUT r6 0 + +test_adde_3: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0 + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 0 + +test_adde_3_constant: + li r4, -1 + li r5, 0 + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 0 + +test_adde_4: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 1 + +test_adde_4_constant: + li r4, -1 + li r5, 0 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 1 + +test_adde_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 1 + +test_adde_5_constant: + li r4, -1 + li r5, 1 + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 1 + +test_adde_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 1 + +test_adde_6_constant: + li r4, -1 + li r5, 1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 1 + +test_adde_7: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 123 + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0x000000000000007A + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 123 + #_ REGISTER_OUT r6 1 + +test_adde_7_constant: + li r4, -1 + li r5, 123 + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0x000000000000007A + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 123 + #_ REGISTER_OUT r6 1 + +test_adde_8: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 123 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0x000000000000007B + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 123 + #_ REGISTER_OUT r6 1 + +test_adde_8_constant: + li r4, -1 + li r5, 123 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0x000000000000007B + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 123 + #_ REGISTER_OUT r6 1 + +test_adde_9: + #_ REGISTER_IN r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_adde_9_constant: + li r5, -1 + srdi r4, r5, 1 + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_adde_10: + #_ REGISTER_IN r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_adde_10_constant: + li r5, -1 + srdi r4, r5, 1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_adde_cr_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 2 + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 3 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r11 0x40000000 + #_ REGISTER_OUT r12 0x20000000 + +test_adde_cr_1_constant: + li r4, 1 + li r5, 2 + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 3 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r11 0x40000000 + #_ REGISTER_OUT r12 0x20000000 + +test_adde_cr_2: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 2 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 4 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r11 0x40000000 + #_ REGISTER_OUT r12 0x20000000 + +test_adde_cr_2_constant: + li r4, 1 + li r5, 2 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 4 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r11 0x40000000 + #_ REGISTER_OUT r12 0x20000000 + +test_adde_cr_3: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0 + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r11 0x80000000 + #_ REGISTER_OUT r12 0x20000000 + +test_adde_cr_3_constant: + li r4, -1 + li r5, 0 + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r11 0x80000000 + #_ REGISTER_OUT r12 0x20000000 + +test_adde_cr_4: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r11 0x20000000 + #_ REGISTER_OUT r12 0x40000000 + +test_adde_cr_4_constant: + li r4, -1 + li r5, 0 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r11 0x20000000 + #_ REGISTER_OUT r12 0x40000000 + +test_adde_cr_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r11 0x20000000 + #_ REGISTER_OUT r12 0x40000000 + +test_adde_cr_5_constant: + li r4, -1 + li r5, 1 + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r11 0x20000000 + #_ REGISTER_OUT r12 0x40000000 + +test_adde_cr_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r11 0x40000000 + #_ REGISTER_OUT r12 0x40000000 + +test_adde_cr_6_constant: + li r4, -1 + li r5, 1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r11 0x40000000 + #_ REGISTER_OUT r12 0x40000000 + +test_adde_cr_7: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 123 + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x000000000000007A + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 123 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r11 0x40000000 + #_ REGISTER_OUT r12 0x40000000 + +test_adde_cr_7_constant: + li r4, -1 + li r5, 123 + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x000000000000007A + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 123 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r11 0x40000000 + #_ REGISTER_OUT r12 0x40000000 + +test_adde_cr_8: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 123 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x000000000000007B + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 123 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r11 0x40000000 + #_ REGISTER_OUT r12 0x40000000 + +test_adde_cr_8_constant: + li r4, -1 + li r5, 123 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x000000000000007B + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 123 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r11 0x40000000 + #_ REGISTER_OUT r12 0x40000000 + +test_adde_cr_9: + #_ REGISTER_IN r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r11 0x80000000 + #_ REGISTER_OUT r12 0x40000000 + +test_adde_cr_9_constant: + li r5, -1 + srdi r4, r5, 1 + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r11 0x80000000 + #_ REGISTER_OUT r12 0x40000000 + +test_adde_cr_10: + #_ REGISTER_IN r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r11 0x80000000 + #_ REGISTER_OUT r12 0x40000000 + +test_adde_cr_10_constant: + li r5, -1 + srdi r4, r5, 1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + adde. r3, r4, r5 + mfcr r11 + adde. r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r11 0x80000000 + #_ REGISTER_OUT r12 0x40000000 diff --git a/tests/ppc/asm/instr_addic.s b/tests/ppc/asm/instr_addic.s new file mode 100644 index 0000000..835e182 --- /dev/null +++ b/tests/ppc/asm/instr_addic.s @@ -0,0 +1,88 @@ +test_addic_1: + #_ REGISTER_IN r4 1 + addic r4, r4, 1 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r6 0 + +test_addic_1_constant: + li r4, 1 + addic r4, r4, 1 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r6 0 + +test_addic_2: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + addic r4, r4, 1 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 1 + +test_addic_2_constant: + li r4, -1 + addic r4, r4, 1 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 1 + +test_addic_3: + #_ REGISTER_IN r4 0xFFFFFFFF + addic r4, r4, 1 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r4 0x0000000100000000 + #_ REGISTER_OUT r6 1 + +test_addic_3_constant: + li r4, 0xFFFFFFFF + srwi r4, r4, 0 + addic r4, r4, 1 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r4 0x0000000100000000 + #_ REGISTER_OUT r6 1 + +test_addic_cr_1: + #_ REGISTER_IN r4 1 + addic. r4, r4, 1 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x40000000 + +test_addic_cr_1_constant: + li r4, 1 + addic. r4, r4, 1 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x40000000 + +test_addic_cr_2: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + addic. r4, r4, 1 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x20000000 + +test_addic_cr_2_constant: + li r4, -1 + addic. r4, r4, 1 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x20000000 diff --git a/tests/ppc/asm/instr_addis.s b/tests/ppc/asm/instr_addis.s new file mode 100644 index 0000000..bb5219b --- /dev/null +++ b/tests/ppc/asm/instr_addis.s @@ -0,0 +1,77 @@ +test_addis_1: + #_ REGISTER_IN r0 1234 + #_ REGISTER_IN r4 1 + addis r3, r0, 1 + blr + #_ REGISTER_OUT r0 1234 + #_ REGISTER_OUT r3 0x10000 + #_ REGISTER_OUT r4 1 + +test_addis_1_constant: + li r0, 1234 + li r4, 1 + addis r3, r0, 1 + blr + #_ REGISTER_OUT r0 1234 + #_ REGISTER_OUT r3 0x10000 + #_ REGISTER_OUT r4 1 + +test_addis_2: + #_ REGISTER_IN r4 1234 + #_ REGISTER_IN r5 1 + addis r3, r4, 1 + blr + #_ REGISTER_OUT r3 0x104D2 + #_ REGISTER_OUT r4 1234 + +test_addis_2_constant: + li r4, 1234 + li r5, 1 + addis r3, r4, 1 + blr + #_ REGISTER_OUT r3 0x104D2 + #_ REGISTER_OUT r4 1234 + +test_lis_1: + #_ REGISTER_IN r0 1234 + lis r3, 1 + blr + #_ REGISTER_OUT r0 1234 + #_ REGISTER_OUT r3 0x10000 + +test_lis_1_constant: + li r0, 1234 + lis r3, 1 + blr + #_ REGISTER_OUT r0 1234 + #_ REGISTER_OUT r3 0x10000 + +test_lis_2: + #_ REGISTER_IN r0 1234 + lis r3, -1 + blr + #_ REGISTER_OUT r0 1234 + #_ REGISTER_OUT r3 0xFFFFFFFFFFFF0000 + +test_lis_2_constant: + li r0, 1234 + lis r3, -1 + blr + #_ REGISTER_OUT r0 1234 + #_ REGISTER_OUT r3 0xFFFFFFFFFFFF0000 + +test_subis_1: + #_ REGISTER_IN r4 1234 + #_ REGISTER_IN r5 1 + subis r3, r4, 1 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFF04D2 + #_ REGISTER_OUT r4 1234 + +test_subis_1_constant: + li r4, 1234 + li r5, 1 + subis r3, r4, 1 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFF04D2 + #_ REGISTER_OUT r4 1234 diff --git a/tests/ppc/asm/instr_addme.s b/tests/ppc/asm/instr_addme.s new file mode 100644 index 0000000..5ab6d58 --- /dev/null +++ b/tests/ppc/asm/instr_addme.s @@ -0,0 +1,367 @@ +test_addme_1: + #_ REGISTER_IN r4 1 + addme r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 1 + +test_addme_1_constant: + li r4, 1 + addme r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 1 + +test_addme_2: + #_ REGISTER_IN r4 1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addme r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 1 + +test_addme_2_constant: + li r4, 1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addme r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 1 + +test_addme_3: + #_ REGISTER_IN r4 12 + addme r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 11 + #_ REGISTER_OUT r4 12 + #_ REGISTER_OUT r6 1 + +test_addme_3_constant: + li r4, 12 + addme r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 11 + #_ REGISTER_OUT r4 12 + #_ REGISTER_OUT r6 1 + +test_addme_4: + #_ REGISTER_IN r4 12 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addme r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 12 + #_ REGISTER_OUT r4 12 + #_ REGISTER_OUT r6 1 + +test_addme_4_constant: + li r4, 12 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addme r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 12 + #_ REGISTER_OUT r4 12 + #_ REGISTER_OUT r6 1 + +test_addme_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + addme r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_addme_5_constant: + li r4, -1 + addme r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_addme_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addme r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_addme_6_constant: + li r4, -1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addme r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_addme_7: + #_ REGISTER_IN r4 0 + addme r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 0 + +test_addme_7_constant: + li r4, 0 + addme r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 0 + +test_addme_8: + #_ REGISTER_IN r4 0 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addme r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 1 + +test_addme_8_constant: + li r4, 0 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addme r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 1 + +test_addme_cr_1: + #_ REGISTER_IN r4 1 + addme. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x20000000 + +test_addme_cr_1_constant: + li r4, 1 + addme. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x20000000 + +test_addme_cr_2: + #_ REGISTER_IN r4 1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addme. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x40000000 + +test_addme_cr_2_constant: + li r4, 1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addme. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x40000000 + +test_addme_cr_3: + #_ REGISTER_IN r4 12 + addme. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 11 + #_ REGISTER_OUT r4 12 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x40000000 + +test_addme_cr_3_constant: + li r4, 12 + addme. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 11 + #_ REGISTER_OUT r4 12 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x40000000 + +test_addme_cr_4: + #_ REGISTER_IN r4 12 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addme. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 12 + #_ REGISTER_OUT r4 12 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x40000000 + +test_addme_cr_4_constant: + li r4, 12 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addme. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 12 + #_ REGISTER_OUT r4 12 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x40000000 + +test_addme_cr_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + addme. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x80000000 + +test_addme_cr_5_constant: + li r4, -1 + addme. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x80000000 + +test_addme_cr_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addme. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x80000000 + +test_addme_cr_6_constant: + li r4, -1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addme. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x80000000 + +test_addme_cr_7: + #_ REGISTER_IN r4 0 + addme. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x80000000 + +test_addme_cr_7_constant: + li r4, 0 + addme. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x80000000 + +test_addme_cr_8: + #_ REGISTER_IN r4 0 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addme. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x20000000 + +test_addme_cr_8_constant: + li r4, 0 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addme. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x20000000 diff --git a/tests/ppc/asm/instr_addze.s b/tests/ppc/asm/instr_addze.s new file mode 100644 index 0000000..15c93ed --- /dev/null +++ b/tests/ppc/asm/instr_addze.s @@ -0,0 +1,367 @@ +test_addze_1: + #_ REGISTER_IN r4 1 + addze r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 0 + +test_addze_1_constant: + li r4, 1 + addze r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 0 + +test_addze_2: + #_ REGISTER_IN r4 1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addze r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 0 + +test_addze_2_constant: + li r4, 1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addze r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 0 + +test_addze_3: + #_ REGISTER_IN r4 12 + addze r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 12 + #_ REGISTER_OUT r4 12 + #_ REGISTER_OUT r6 0 + +test_addze_3_constant: + li r4, 12 + addze r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 12 + #_ REGISTER_OUT r4 12 + #_ REGISTER_OUT r6 0 + +test_addze_4: + #_ REGISTER_IN r4 12 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addze r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 13 + #_ REGISTER_OUT r4 12 + #_ REGISTER_OUT r6 0 + +test_addze_4_constant: + li r4, 12 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addze r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 13 + #_ REGISTER_OUT r4 12 + #_ REGISTER_OUT r6 0 + +test_addze_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + addze r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 0 + +test_addze_5_constant: + li r4, -1 + addze r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 0 + +test_addze_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addze r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_addze_6_constant: + li r4, -1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addze r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_addze_7: + #_ REGISTER_IN r4 0 + addze r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 0 + +test_addze_7_constant: + li r4, 0 + addze r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 0 + +test_addze_8: + #_ REGISTER_IN r4 0 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addze r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 0 + +test_addze_8_constant: + li r4, 0 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addze r3, r4 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 0 + +test_addze_cr_1: + #_ REGISTER_IN r4 1 + addze. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x40000000 + +test_addze_cr_1_constant: + li r4, 1 + addze. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x40000000 + +test_addze_cr_2: + #_ REGISTER_IN r4 1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addze. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x40000000 + +test_addze_cr_2_constant: + li r4, 1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addze. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x40000000 + +test_addze_cr_3: + #_ REGISTER_IN r4 12 + addze. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 12 + #_ REGISTER_OUT r4 12 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x40000000 + +test_addze_cr_3_constant: + li r4, 12 + addze. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 12 + #_ REGISTER_OUT r4 12 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x40000000 + +test_addze_cr_4: + #_ REGISTER_IN r4 12 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addze. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 13 + #_ REGISTER_OUT r4 12 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x40000000 + +test_addze_cr_4_constant: + li r4, 12 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addze. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 13 + #_ REGISTER_OUT r4 12 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x40000000 + +test_addze_cr_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + addze. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x80000000 + +test_addze_cr_5_constant: + li r4, -1 + addze. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x80000000 + +test_addze_cr_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addze. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x20000000 + +test_addze_cr_6_constant: + li r4, -1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addze. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + #_ REGISTER_OUT r12 0x20000000 + +test_addze_cr_7: + #_ REGISTER_IN r4 0 + addze. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x20000000 + +test_addze_cr_7_constant: + li r4, 0 + addze. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x20000000 + +test_addze_cr_8: + #_ REGISTER_IN r4 0 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addze. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x40000000 + +test_addze_cr_8_constant: + li r4, 0 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 # CA=1 + addze. r3, r4 + adde r6, r0, r0 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 0 + #_ REGISTER_OUT r12 0x40000000 diff --git a/tests/ppc/asm/instr_and.s b/tests/ppc/asm/instr_and.s new file mode 100644 index 0000000..34555c4 --- /dev/null +++ b/tests/ppc/asm/instr_and.s @@ -0,0 +1,205 @@ +test_and_1: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r25 0xFFFFFFFFFFFFFFFF + and r11, r5, r25 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF + +test_and_1_constant: + li r5, -1 + li r25, -1 + and r11, r5, r25 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF + +test_and_2: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r25 0 + and r11, r5, r25 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0 + #_ REGISTER_OUT r11 0 + +test_and_2_constant: + li r5, -1 + li r25, 0 + and r11, r5, r25 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0 + #_ REGISTER_OUT r11 0 + +test_and_3: + #_ REGISTER_IN r5 0 + #_ REGISTER_IN r25 0xFFFFFFFFFFFFFFFF + and r11, r5, r25 + blr + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0 + +test_and_3_constant: + li r5, 0 + li r25, -1 + and r11, r5, r25 + blr + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0 + +test_and_4: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r25 0x0000FFFF + and r11, r5, r25 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x0000FFFF + +test_and_4_constant: + li r5, -1 + li r25, -1 + clrldi r25, r25, 48 + and r11, r5, r25 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x0000FFFF + +test_and_5: + #_ REGISTER_IN r0 0x100000FF + #_ REGISTER_IN r25 0x0000FFFF + and r11, r0, r25 + blr + #_ REGISTER_OUT r0 0x100000FF + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x000000FF + +test_and_5_constant: + lis r0, 0x1000 + ori r0, r0, 0xFF + li r25, -1 + clrldi r25, r25, 48 + and r11, r0, r25 + blr + #_ REGISTER_OUT r0 0x100000FF + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x000000FF + +test_and_cr_1: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r25 0xFFFFFFFFFFFFFFFF + and. r11, r5, r25 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r12 0x80000000 + +test_and_cr_1_constant: + li r5, -1 + li r25, -1 + and. r11, r5, r25 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r12 0x80000000 + +test_and_cr_2: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r25 0 + and. r11, r5, r25 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0 + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r12 0x20000000 + +test_and_cr_2_constant: + li r5, -1 + li r25, 0 + and. r11, r5, r25 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0 + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r12 0x20000000 + +test_and_cr_3: + #_ REGISTER_IN r5 0 + #_ REGISTER_IN r25 0xFFFFFFFFFFFFFFFF + and. r11, r5, r25 + mfcr r12 + blr + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r12 0x20000000 + +test_and_cr_3_constant: + li r5, 0 + li r25, -1 + and. r11, r5, r25 + mfcr r12 + blr + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r12 0x20000000 + +test_and_cr_4: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r25 0x0000FFFF + and. r11, r5, r25 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x0000FFFF + #_ REGISTER_OUT r12 0x40000000 + +test_and_cr_4_constant: + li r5, -1 + li r25, -1 + clrldi r25, r25, 48 + and. r11, r5, r25 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x0000FFFF + #_ REGISTER_OUT r12 0x40000000 + +test_and_cr_5: + #_ REGISTER_IN r0 0x100000FF + #_ REGISTER_IN r25 0x0000FFFF + and. r11, r0, r25 + mfcr r12 + blr + #_ REGISTER_OUT r0 0x100000FF + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x000000FF + #_ REGISTER_OUT r12 0x40000000 + +test_and_cr_5_constant: + lis r0, 0x1000 + ori r0, r0, 0xFF + li r25, -1 + clrldi r25, r25, 48 + and. r11, r0, r25 + mfcr r12 + blr + #_ REGISTER_OUT r0 0x100000FF + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x000000FF + #_ REGISTER_OUT r12 0x40000000 diff --git a/tests/ppc/asm/instr_andc.s b/tests/ppc/asm/instr_andc.s new file mode 100644 index 0000000..b437717 --- /dev/null +++ b/tests/ppc/asm/instr_andc.s @@ -0,0 +1,205 @@ +test_andc_1: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r25 0xFFFFFFFFFFFFFFFF + andc r11, r5, r25 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0 + +test_andc_1_constant: + li r5, -1 + li r25, -1 + andc r11, r5, r25 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0 + +test_andc_2: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r25 0 + andc r11, r5, r25 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0 + #_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF + +test_andc_2_constant: + li r5, -1 + li r25, 0 + andc r11, r5, r25 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0 + #_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF + +test_andc_3: + #_ REGISTER_IN r5 0 + #_ REGISTER_IN r25 0xFFFFFFFFFFFFFFFF + andc r11, r5, r25 + blr + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0 + +test_andc_3_constant: + li r5, 0 + li r25, -1 + andc r11, r5, r25 + blr + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0 + +test_andc_4: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r25 0x0000FFFF + andc r11, r5, r25 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0xFFFFFFFFFFFF0000 + +test_andc_4_constant: + li r5, -1 + li r25, -1 + clrldi r25, r25, 48 + andc r11, r5, r25 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0xFFFFFFFFFFFF0000 + +test_andc_5: + #_ REGISTER_IN r0 0x100000FF + #_ REGISTER_IN r25 0x0000FFFF + andc r11, r0, r25 + blr + #_ REGISTER_OUT r0 0x100000FF + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x10000000 + +test_andc_5_constant: + lis r0, 0x1000 + ori r0, r0, 0xFF + li r25, -1 + clrldi r25, r25, 48 + andc r11, r0, r25 + blr + #_ REGISTER_OUT r0 0x100000FF + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x10000000 + +test_andc_cr_1: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r25 0xFFFFFFFFFFFFFFFF + andc. r11, r5, r25 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r12 0x20000000 + +test_andc_cr_1_constant: + li r5, -1 + li r25, -1 + andc. r11, r5, r25 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r12 0x20000000 + +test_andc_cr_2: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r25 0 + andc. r11, r5, r25 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0 + #_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r12 0x80000000 + +test_andc_cr_2_constant: + li r5, -1 + li r25, 0 + andc. r11, r5, r25 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0 + #_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r12 0x80000000 + +test_andc_cr_3: + #_ REGISTER_IN r5 0 + #_ REGISTER_IN r25 0xFFFFFFFFFFFFFFFF + andc. r11, r5, r25 + mfcr r12 + blr + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r12 0x20000000 + +test_andc_cr_3_constant: + li r5, 0 + li r25, -1 + andc. r11, r5, r25 + mfcr r12 + blr + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r12 0x20000000 + +test_andc_cr_4: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r25 0x0000FFFF + andc. r11, r5, r25 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0xFFFFFFFFFFFF0000 + #_ REGISTER_OUT r12 0x80000000 + +test_andc_cr_4_constant: + li r5, -1 + li r25, -1 + clrldi r25, r25, 48 + andc. r11, r5, r25 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0xFFFFFFFFFFFF0000 + #_ REGISTER_OUT r12 0x80000000 + +test_andc_cr_5: + #_ REGISTER_IN r0 0x100000FF + #_ REGISTER_IN r25 0x0000FFFF + andc. r11, r0, r25 + mfcr r12 + blr + #_ REGISTER_OUT r0 0x100000FF + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x10000000 + #_ REGISTER_OUT r12 0x40000000 + +test_andc_cr_5_constant: + lis r0, 0x1000 + ori r0, r0, 0xFF + li r25, -1 + clrldi r25, r25, 48 + andc. r11, r0, r25 + mfcr r12 + blr + #_ REGISTER_OUT r0 0x100000FF + #_ REGISTER_OUT r25 0x0000FFFF + #_ REGISTER_OUT r11 0x10000000 + #_ REGISTER_OUT r12 0x40000000 diff --git a/tests/ppc/asm/instr_andi.s b/tests/ppc/asm/instr_andi.s new file mode 100644 index 0000000..8644bc0 --- /dev/null +++ b/tests/ppc/asm/instr_andi.s @@ -0,0 +1,90 @@ +test_andi_cr_1: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + andi. r11, r5, 0xCAFE + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0x0000CAFE + #_ REGISTER_OUT r12 0x40000000 + +test_andi_cr_1_constant: + li r5, -1 + andi. r11, r5, 0xCAFE + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0x0000CAFE + #_ REGISTER_OUT r12 0x40000000 + +test_andi_cr_2: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + andi. r11, r5, 0 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r12 0x20000000 + +test_andi_cr_2_constant: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + andi. r11, r5, 0 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r12 0x20000000 + +test_andi_cr_3: + #_ REGISTER_IN r5 0 + andi. r11, r5, 0xFFFF + mfcr r12 + blr + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r12 0x20000000 + +test_andi_cr_3_constant: + li r5, 0 + andi. r11, r5, 0xFFFF + mfcr r12 + blr + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r12 0x20000000 + +test_andi_cr_4: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + andi. r11, r5, 0xCAFE + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0x0000CAFE + #_ REGISTER_OUT r12 0x40000000 + +test_andi_cr_4_constant: + li r5, -1 + andi. r11, r5, 0xCAFE + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0x0000CAFE + #_ REGISTER_OUT r12 0x40000000 + +test_andi_cr_5: + #_ REGISTER_IN r0 0x100000FF + andi. r11, r0, 0xFFFF + mfcr r12 + blr + #_ REGISTER_OUT r0 0x100000FF + #_ REGISTER_OUT r11 0x000000FF + #_ REGISTER_OUT r12 0x40000000 + +test_andi_cr_5_constant: + lis r0, 0x1000 + ori r0, r0, 0xFF + andi. r11, r0, 0xFFFF + mfcr r12 + blr + #_ REGISTER_OUT r0 0x100000FF + #_ REGISTER_OUT r11 0x000000FF + #_ REGISTER_OUT r12 0x40000000 diff --git a/tests/ppc/asm/instr_andis.s b/tests/ppc/asm/instr_andis.s new file mode 100644 index 0000000..425f72d --- /dev/null +++ b/tests/ppc/asm/instr_andis.s @@ -0,0 +1,90 @@ +test_andis_cr_1: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + andis. r11, r5, 0xCAFE + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0xCAFE0000 + #_ REGISTER_OUT r12 0x80000000 + +test_andis_cr_1_constant: + li r5, -1 + andis. r11, r5, 0xCAFE + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0xCAFE0000 + #_ REGISTER_OUT r12 0x80000000 + +test_andis_cr_2: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + andis. r11, r5, 0 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r12 0x20000000 + +test_andis_cr_2_constant: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + andis. r11, r5, 0 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r12 0x20000000 + +test_andis_cr_3: + #_ REGISTER_IN r5 0 + andis. r11, r5, 0xFFFF + mfcr r12 + blr + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r12 0x20000000 + +test_andis_cr_3_constant: + li r5, 0 + andis. r11, r5, 0xFFFF + mfcr r12 + blr + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r12 0x20000000 + +test_andis_cr_4: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + andis. r11, r5, 0xCAFE + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0xCAFE0000 + #_ REGISTER_OUT r12 0x80000000 + +test_andis_cr_4_constant: + li r5, -1 + andis. r11, r5, 0xCAFE + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0xCAFE0000 + #_ REGISTER_OUT r12 0x80000000 + +test_andis_cr_5: + #_ REGISTER_IN r0 0x100000FF + andis. r11, r0, 0xFFFF + mfcr r12 + blr + #_ REGISTER_OUT r0 0x100000FF + #_ REGISTER_OUT r11 0x10000000 + #_ REGISTER_OUT r12 0x40000000 + +test_andis_cr_5_constant: + lis r0, 0x1000 + ori r0, r0, 0xFF + andis. r11, r0, 0xFFFF + mfcr r12 + blr + #_ REGISTER_OUT r0 0x100000FF + #_ REGISTER_OUT r11 0x10000000 + #_ REGISTER_OUT r12 0x40000000 diff --git a/tests/ppc/asm/instr_cmp.s b/tests/ppc/asm/instr_cmp.s new file mode 100644 index 0000000..36fd709 --- /dev/null +++ b/tests/ppc/asm/instr_cmp.s @@ -0,0 +1,186 @@ +test_cmpd_1: + #_ REGISTER_IN r3 0x0000000100000000 + #_ REGISTER_IN r4 0x0000000200000000 + cmpd r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000000 + #_ REGISTER_OUT r4 0x0000000200000000 + #_ REGISTER_OUT r12 0x80000000 + +test_cmpd_1_constant: + li r3, 1 + sldi r3, r3, 32 + sldi r4, r3, 1 + cmpd r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000000 + #_ REGISTER_OUT r4 0x0000000200000000 + #_ REGISTER_OUT r12 0x80000000 + +test_cmpd_2: + #_ REGISTER_IN r3 0x0000000200000000 + #_ REGISTER_IN r4 0x0000000100000000 + cmpd r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000200000000 + #_ REGISTER_OUT r4 0x0000000100000000 + #_ REGISTER_OUT r12 0x40000000 + +test_cmpd_2_constant: + li r4, 1 + sldi r4, r4, 32 + sldi r3, r4, 1 + cmpd r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000200000000 + #_ REGISTER_OUT r4 0x0000000100000000 + #_ REGISTER_OUT r12 0x40000000 + +test_cmpw_1: + #_ REGISTER_IN r3 0x0000000100000000 + #_ REGISTER_IN r4 0x0000000200000000 + cmpw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000000 + #_ REGISTER_OUT r4 0x0000000200000000 + #_ REGISTER_OUT r12 0x20000000 + +test_cmpw_1_constant: + li r3, 1 + sldi r3, r3, 32 + sldi r4, r3, 1 + cmpw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000000 + #_ REGISTER_OUT r4 0x0000000200000000 + #_ REGISTER_OUT r12 0x20000000 + +test_cmpw_2: + #_ REGISTER_IN r3 0x0000000200000000 + #_ REGISTER_IN r4 0x0000000100000000 + cmpw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000200000000 + #_ REGISTER_OUT r4 0x0000000100000000 + #_ REGISTER_OUT r12 0x20000000 + +test_cmpw_2_constant: + li r4, 1 + sldi r4, r4, 32 + sldi r3, r4, 1 + cmpw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000200000000 + #_ REGISTER_OUT r4 0x0000000100000000 + #_ REGISTER_OUT r12 0x20000000 + +test_cmpw_3: + #_ REGISTER_IN r3 1 + #_ REGISTER_IN r4 2 + cmpw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r12 0x80000000 + +test_cmpw_3_constant: + li r3, 1 + li r4, 2 + cmpw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r12 0x80000000 + +test_cmpw_4: + #_ REGISTER_IN r3 2 + #_ REGISTER_IN r4 1 + cmpw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r12 0x40000000 + +test_cmpw_4_constant: + li r3, 2 + li r4, 1 + cmpw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r12 0x40000000 + +test_cmpw_5: + #_ REGISTER_IN r3 0x0000000100000002 + #_ REGISTER_IN r4 0x0000000200000001 + cmpw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000002 + #_ REGISTER_OUT r4 0x0000000200000001 + #_ REGISTER_OUT r12 0x40000000 + +test_cmpw_5_constant: + li r3, 1 + sldi r3, r3, 32 + sldi r4, r3, 1 + addi r3, r3, 2 + addi r4, r4, 1 + cmpw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000002 + #_ REGISTER_OUT r4 0x0000000200000001 + #_ REGISTER_OUT r12 0x40000000 + +test_cmp_1: + #_ REGISTER_IN r3 1 + #_ REGISTER_IN r4 2 + cmp 5, 0, r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r12 0x00000800 + +test_cmp_1_constant: + li r3, 1 + li r4, 2 + cmp 5, 0, r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r12 0x00000800 + +test_cmp_2: + #_ REGISTER_IN r3 2 + #_ REGISTER_IN r4 1 + cmp 3, 0, r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r12 0x00040000 + +test_cmp_2_constant: + li r3, 2 + li r4, 1 + cmp 3, 0, r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r12 0x00040000 diff --git a/tests/ppc/asm/instr_cmpi.s b/tests/ppc/asm/instr_cmpi.s new file mode 100644 index 0000000..19f94af --- /dev/null +++ b/tests/ppc/asm/instr_cmpi.s @@ -0,0 +1,116 @@ +test_cmpdi_1: + #_ REGISTER_IN r3 0x0000000100000000 + cmpdi r3, 2 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000000 + #_ REGISTER_OUT r12 0x40000000 + +test_cmpdi_1_constant: + li r3, 1 + sldi r3, r3, 32 + cmpdi r3, 2 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000000 + #_ REGISTER_OUT r12 0x40000000 + +test_cmpdi_2: + #_ REGISTER_IN r3 1 + cmpdi r3, 2 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r12 0x80000000 + +test_cmpdi_2_constant: + li r3, 1 + cmpdi r3, 2 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r12 0x80000000 + +test_cmpwi_1: + #_ REGISTER_IN r3 0x0000000100000000 + cmpwi r3, 2 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000000 + #_ REGISTER_OUT r12 0x80000000 + +test_cmpwi_1_constant: + li r3, 1 + sldi r3, r3, 32 + cmpwi r3, 2 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000000 + #_ REGISTER_OUT r12 0x80000000 + +test_cmpwi_2: + #_ REGISTER_IN r3 2 + cmpwi r3, 1 + mfcr r12 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r12 0x40000000 + +test_cmpwi_2_constant: + li r3, 2 + cmpwi r3, 1 + mfcr r12 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r12 0x40000000 + +test_cmpwi_5: + #_ REGISTER_IN r3 0x0000000100000002 + cmpwi r3, 1 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000002 + #_ REGISTER_OUT r12 0x40000000 + +test_cmpwi_5_constant: + li r3, 1 + sldi r3, r3, 32 + sldi r4, r3, 1 + addi r3, r3, 2 + cmpwi r3, 1 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000002 + #_ REGISTER_OUT r12 0x40000000 + +test_cmpi_1: + #_ REGISTER_IN r3 1 + cmpi 5, 0, r3, 2 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r12 0x00000800 + +test_cmpi_1_constant: + li r3, 1 + cmpi 5, 0, r3, 2 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r12 0x00000800 + +test_cmpi_2: + #_ REGISTER_IN r3 2 + cmpi 3, 0, r3, 1 + mfcr r12 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r12 0x00040000 + +test_cmpi_2_constant: + li r3, 2 + cmpi 3, 0, r3, 1 + mfcr r12 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r12 0x00040000 diff --git a/tests/ppc/asm/instr_cmpl.s b/tests/ppc/asm/instr_cmpl.s new file mode 100644 index 0000000..0a5742e --- /dev/null +++ b/tests/ppc/asm/instr_cmpl.s @@ -0,0 +1,209 @@ +test_cmpld_1: + #_ REGISTER_IN r3 0x0000000100000000 + #_ REGISTER_IN r4 0x0000000200000000 + cmpld r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000000 + #_ REGISTER_OUT r4 0x0000000200000000 + #_ REGISTER_OUT r12 0x80000000 + +test_cmpld_1_constant: + li r3, 1 + sldi r3, r3, 32 + sldi r4, r3, 1 + cmpld r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000000 + #_ REGISTER_OUT r4 0x0000000200000000 + #_ REGISTER_OUT r12 0x80000000 + +test_cmpld_2: + #_ REGISTER_IN r3 0x0000000200000000 + #_ REGISTER_IN r4 0x0000000100000000 + cmpld r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000200000000 + #_ REGISTER_OUT r4 0x0000000100000000 + #_ REGISTER_OUT r12 0x40000000 + +test_cmpld_2_constant: + li r4, 1 + sldi r4, r4, 32 + sldi r3, r4, 1 + cmpld r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000200000000 + #_ REGISTER_OUT r4 0x0000000100000000 + #_ REGISTER_OUT r12 0x40000000 + +test_cmplw_1: + #_ REGISTER_IN r3 0x0000000100000000 + #_ REGISTER_IN r4 0x0000000200000000 + cmplw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000000 + #_ REGISTER_OUT r4 0x0000000200000000 + #_ REGISTER_OUT r12 0x20000000 + +test_cmplw_1_constant: + li r3, 1 + sldi r3, r3, 32 + sldi r4, r3, 1 + cmplw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000000 + #_ REGISTER_OUT r4 0x0000000200000000 + #_ REGISTER_OUT r12 0x20000000 + +test_cmplw_2: + #_ REGISTER_IN r3 0x0000000200000000 + #_ REGISTER_IN r4 0x0000000100000000 + cmplw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000200000000 + #_ REGISTER_OUT r4 0x0000000100000000 + #_ REGISTER_OUT r12 0x20000000 + +test_cmplw_2_constant: + li r4, 1 + sldi r4, r4, 32 + sldi r3, r4, 1 + cmplw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000200000000 + #_ REGISTER_OUT r4 0x0000000100000000 + #_ REGISTER_OUT r12 0x20000000 + +test_cmplw_3: + #_ REGISTER_IN r3 1 + #_ REGISTER_IN r4 2 + cmplw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r12 0x80000000 + +test_cmplw_3_constant: + li r3, 1 + li r4, 2 + cmplw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r12 0x80000000 + +test_cmplw_4: + #_ REGISTER_IN r3 2 + #_ REGISTER_IN r4 1 + cmplw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r12 0x40000000 + +test_cmplw_4_constant: + li r3, 2 + li r4, 1 + cmplw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r12 0x40000000 + +test_cmplw_5: + #_ REGISTER_IN r3 0x0000000100000002 + #_ REGISTER_IN r4 0x0000000200000001 + cmplw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000002 + #_ REGISTER_OUT r4 0x0000000200000001 + #_ REGISTER_OUT r12 0x40000000 + +test_cmplw_5_constant: + li r3, 1 + sldi r3, r3, 32 + sldi r4, r3, 1 + addi r3, r3, 2 + addi r4, r4, 1 + cmplw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000002 + #_ REGISTER_OUT r4 0x0000000200000001 + #_ REGISTER_OUT r12 0x40000000 + +test_cmplw_6: + #_ REGISTER_IN r3 0xFFFFFFFF80000000 + #_ REGISTER_IN r4 0x0000000080000000 + cmplw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFF80000000 + #_ REGISTER_OUT r4 0x0000000080000000 + #_ REGISTER_OUT r12 0x20000000 + +test_cmplw_6_constant: + lis r3, 0x7FFF + ori r3, r3, 0xFFFF + not r3, r3 + li r4, 1 + sldi r4, r4, 31 + cmplw r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFF80000000 + #_ REGISTER_OUT r4 0x0000000080000000 + #_ REGISTER_OUT r12 0x20000000 + +test_cmpl_1: + #_ REGISTER_IN r3 1 + #_ REGISTER_IN r4 2 + cmpl 5, 0, r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r12 0x00000800 + +test_cmpl_1_constant: + li r3, 1 + li r4, 2 + cmpl 5, 0, r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r12 0x00000800 + +test_cmpl_2: + #_ REGISTER_IN r3 2 + #_ REGISTER_IN r4 1 + cmpl 3, 0, r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r12 0x00040000 + +test_cmpl_2_constant: + li r3, 2 + li r4, 1 + cmpl 3, 0, r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r12 0x00040000 diff --git a/tests/ppc/asm/instr_cmpli.s b/tests/ppc/asm/instr_cmpli.s new file mode 100644 index 0000000..44a8df8 --- /dev/null +++ b/tests/ppc/asm/instr_cmpli.s @@ -0,0 +1,116 @@ +test_cmpldi_1: + #_ REGISTER_IN r3 0x0000000100000000 + cmpldi r3, 2 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000000 + #_ REGISTER_OUT r12 0x40000000 + +test_cmpldi_1_constant: + li r3, 1 + sldi r3, r3, 32 + cmpldi r3, 2 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000000 + #_ REGISTER_OUT r12 0x40000000 + +test_cmpldi_2: + #_ REGISTER_IN r3 1 + cmpldi r3, 2 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r12 0x80000000 + +test_cmpldi_2_constant: + li r3, 1 + cmpldi r3, 2 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r12 0x80000000 + +test_cmplwi_1: + #_ REGISTER_IN r3 0x0000000100000000 + cmplwi r3, 2 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000000 + #_ REGISTER_OUT r12 0x80000000 + +test_cmplwi_1_constant: + li r3, 1 + sldi r3, r3, 32 + cmplwi r3, 2 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000000 + #_ REGISTER_OUT r12 0x80000000 + +test_cmplwi_2: + #_ REGISTER_IN r3 2 + cmplwi r3, 1 + mfcr r12 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r12 0x40000000 + +test_cmplwi_2_constant: + li r3, 2 + cmplwi r3, 1 + mfcr r12 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r12 0x40000000 + +test_cmplwi_5: + #_ REGISTER_IN r3 0x0000000100000002 + cmplwi r3, 1 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000002 + #_ REGISTER_OUT r12 0x40000000 + +test_cmplwi_5_constant: + li r3, 1 + sldi r3, r3, 32 + sldi r4, r3, 1 + addi r3, r3, 2 + cmplwi r3, 1 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0000000100000002 + #_ REGISTER_OUT r12 0x40000000 + +test_cmpli_1: + #_ REGISTER_IN r3 1 + cmpli 5, 0, r3, 2 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r12 0x00000800 + +test_cmpli_1_constant: + li r3, 1 + cmpli 5, 0, r3, 2 + mfcr r12 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r12 0x00000800 + +test_cmpli_2: + #_ REGISTER_IN r3 2 + cmpli 3, 0, r3, 1 + mfcr r12 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r12 0x00040000 + +test_cmpli_2_constant: + li r3, 2 + cmpli 3, 0, r3, 1 + mfcr r12 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r12 0x00040000 diff --git a/tests/ppc/asm/instr_cntlzd.s b/tests/ppc/asm/instr_cntlzd.s new file mode 100644 index 0000000..f59264f --- /dev/null +++ b/tests/ppc/asm/instr_cntlzd.s @@ -0,0 +1,56 @@ +test_cntlzd_1: + #_ REGISTER_IN r5 0 + cntlzd r6, r5 + blr + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 64 + +test_cntlzd_1_constant: + li r5, 0 + cntlzd r6, r5 + blr + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 64 + +test_cntlzd_2: + #_ REGISTER_IN r5 1 + cntlzd r6, r5 + blr + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 63 + +test_cntlzd_2_constant: + li r5, 1 + cntlzd r6, r5 + blr + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 63 + +test_cntlzd_3: + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + cntlzd r6, r5 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 0 + +test_cntlzd_3_constant: + li r5, -1 + cntlzd r6, r5 + blr + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 0 + +test_cntlzd_4: + #_ REGISTER_IN r5 0x7FFFFFFFFFFFFFFF + cntlzd r6, r5 + blr + #_ REGISTER_OUT r5 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_cntlzd_4_constant: + li r5, -1 + srdi r5, r5, 1 + cntlzd r6, r5 + blr + #_ REGISTER_OUT r5 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 diff --git a/tests/ppc/asm/instr_cntlzw.s b/tests/ppc/asm/instr_cntlzw.s new file mode 100644 index 0000000..b786f8a --- /dev/null +++ b/tests/ppc/asm/instr_cntlzw.s @@ -0,0 +1,73 @@ +test_cntlzw_1: + #_ REGISTER_IN r5 0 + cntlzw r6, r5 + blr + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 32 + +test_cntlzw_1_constant: + li r5, 0 + cntlzw r6, r5 + blr + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 32 + +test_cntlzw_2: + #_ REGISTER_IN r5 1 + cntlzw r6, r5 + blr + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 31 + +test_cntlzw_2_constant: + li r5, 1 + cntlzw r6, r5 + blr + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 31 + +test_cntlzw_3: + #_ REGISTER_IN r5 0xFFFFFFFF + cntlzw r6, r5 + blr + #_ REGISTER_OUT r5 0xFFFFFFFF + #_ REGISTER_OUT r6 0 + +test_cntlzw_3_constant: + li r5, -1 + srwi r5, r5, 0 + cntlzw r6, r5 + blr + #_ REGISTER_OUT r5 0xFFFFFFFF + #_ REGISTER_OUT r6 0 + +test_cntlzw_4: + #_ REGISTER_IN r5 0x7FFFFFFF + cntlzw r6, r5 + blr + #_ REGISTER_OUT r5 0x7FFFFFFF + #_ REGISTER_OUT r6 1 + +test_cntlzw_4_constant: + li r5, -1 + srwi r5, r5, 1 + cntlzw r6, r5 + blr + #_ REGISTER_OUT r5 0x7FFFFFFF + #_ REGISTER_OUT r6 1 + +test_cntlzw_5: + #_ REGISTER_IN r5 0xFFFFFFFF00000001 + cntlzw r6, r5 + blr + #_ REGISTER_OUT r5 0xFFFFFFFF00000001 + #_ REGISTER_OUT r6 31 + +test_cntlzw_5_constant: + li r5, -1 + sldi r5, r5, 32 + addi r5, r5, 1 + cntlzw r6, r5 + blr + #_ REGISTER_OUT r5 0xFFFFFFFF00000001 + #_ REGISTER_OUT r6 31 diff --git a/tests/ppc/asm/instr_divd.s b/tests/ppc/asm/instr_divd.s new file mode 100644 index 0000000..cafc90a --- /dev/null +++ b/tests/ppc/asm/instr_divd.s @@ -0,0 +1,166 @@ +test_divd_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 2 + divd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + +test_divd_1_constant: + li r4, 1 + li r5, 2 + divd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + +# TODO(benvanik): x64 ignore divide by zero (=0) +#test_divd_2: +# #_ REGISTER_IN r4 1 +# #_ REGISTER_IN r5 0 +# divd r3, r4, r5 +# blr +# #_ REGISTER_OUT r3 0 +# #_ REGISTER_OUT r4 1 +# #_ REGISTER_OUT r5 0 + +# TODO(benvanik): x64 ignore divide by zero (=0) +#test_divd_2_constant: +# li r4, 1 +# li r5, 0 +# divd r3, r4, r5 +# blr +# #_ REGISTER_OUT r3 0 +# #_ REGISTER_OUT r4 1 +# #_ REGISTER_OUT r5 0 + +test_divd_3: + #_ REGISTER_IN r4 2 + #_ REGISTER_IN r5 1 + divd r3, r4, r5 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r5 1 + +test_divd_3_constant: + li r4, 2 + li r5, 1 + divd r3, r4, r5 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r5 1 + +test_divd_4: + #_ REGISTER_IN r4 35 + #_ REGISTER_IN r5 7 + divd r3, r4, r5 + blr + #_ REGISTER_OUT r3 5 + #_ REGISTER_OUT r4 35 + #_ REGISTER_OUT r5 7 + +test_divd_4_constant: + li r4, 35 + li r5, 7 + divd r3, r4, r5 + blr + #_ REGISTER_OUT r3 5 + #_ REGISTER_OUT r4 35 + #_ REGISTER_OUT r5 7 + +test_divd_5: + #_ REGISTER_IN r4 0 + #_ REGISTER_IN r5 1 + divd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r5 1 + +test_divd_5_constant: + li r4, 0 + li r5, 1 + divd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r5 1 + +test_divd_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + divd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_divd_6_constant: + li r4, -1 + li r5, 1 + divd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_divd_7: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + divd r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_divd_7_constant: + li r4, -1 + li r5, -1 + divd r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_divd_8: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + divd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_divd_8_constant: + li r4, 1 + li r5, -1 + divd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +# TODO(benvanik): integer overflow (=0) +#test_divd_9: +# #_ REGISTER_IN r4 0x8000000000000000 +# #_ REGISTER_IN r5 -1 +# divd r3, r4, r5 +# blr +# #_ REGISTER_OUT r3 0 +# #_ REGISTER_OUT r4 0x8000000000000000 +# #_ REGISTER_OUT r5 -1 + +# TODO(benvanik): integer overflow (=0) +#test_divd_9_constant: +# li r4, 1 +# sldi r4, r4, 63 +# li r5, -1 +# divd r3, r4, r5 +# blr +# #_ REGISTER_OUT r3 0 +# #_ REGISTER_OUT r4 0x8000000000000000 +# #_ REGISTER_OUT r5 -1 diff --git a/tests/ppc/asm/instr_divdu.s b/tests/ppc/asm/instr_divdu.s new file mode 100644 index 0000000..0829c63 --- /dev/null +++ b/tests/ppc/asm/instr_divdu.s @@ -0,0 +1,183 @@ +test_divdu_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 2 + divdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + +test_divdu_1_constant: + li r4, 1 + li r5, 2 + divdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + +# TODO(benvanik): x64 ignore divide by zero (=0) +#test_divdu_2: +# #_ REGISTER_IN r4 1 +# #_ REGISTER_IN r5 0 +# divdu r3, r4, r5 +# blr +# #_ REGISTER_OUT r3 0 +# #_ REGISTER_OUT r4 1 +# #_ REGISTER_OUT r5 0 + +# TODO(benvanik): x64 ignore divide by zero (=0) +#test_divdu_2_constant: +# li r4, 1 +# li r5, 0 +# divdu r3, r4, r5 +# blr +# #_ REGISTER_OUT r3 0 +# #_ REGISTER_OUT r4 1 +# #_ REGISTER_OUT r5 0 + +test_divdu_3: + #_ REGISTER_IN r4 2 + #_ REGISTER_IN r5 1 + divdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r5 1 + +test_divdu_3_constant: + li r4, 2 + li r5, 1 + divdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r5 1 + +test_divdu_4: + #_ REGISTER_IN r4 35 + #_ REGISTER_IN r5 7 + divdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 5 + #_ REGISTER_OUT r4 35 + #_ REGISTER_OUT r5 7 + +test_divdu_4_constant: + li r4, 35 + li r5, 7 + divdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 5 + #_ REGISTER_OUT r4 35 + #_ REGISTER_OUT r5 7 + +test_divdu_5: + #_ REGISTER_IN r4 0 + #_ REGISTER_IN r5 1 + divdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r5 1 + +test_divdu_5_constant: + li r4, 0 + li r5, 1 + divdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r5 1 + +test_divdu_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + divdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_divdu_6_constant: + li r4, -1 + li r5, 1 + divdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_divdu_7: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + divdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_divdu_7_constant: + li r4, -1 + li r5, -1 + divdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_divdu_8: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + divdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_divdu_8_constant: + li r4, 1 + li r5, -1 + divdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_divdu_9: + #_ REGISTER_IN r4 0x8000000000000000 + #_ REGISTER_IN r5 -1 + divdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0x8000000000000000 + #_ REGISTER_OUT r5 -1 + +# TODO(benvanik): integer overflow (=0) +test_divdu_9_constant: + li r4, 1 + sldi r4, r4, 63 + li r5, -1 + divdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0x8000000000000000 + #_ REGISTER_OUT r5 -1 + +test_divdu_10: + #_ REGISTER_IN r0 0x1 + #_ REGISTER_IN r3 0xFFFFFFFF + divdu. r0, r3, r0 + blr + #_ REGISTER_OUT r0 0xFFFFFFFF + #_ REGISTER_OUT r3 0xFFFFFFFF + #_ REGISTER_OUT cr 0x0000000080000000 + +test_divdu_11: + #_ REGISTER_IN r0 0 + #_ REGISTER_IN r3 0xFFFFFFFF + divdu. r0, r0, r3 + blr + #_ REGISTER_OUT r0 0 + #_ REGISTER_OUT r3 0xFFFFFFFF + #_ REGISTER_OUT cr 0x0000000020000000 diff --git a/tests/ppc/asm/instr_divw.s b/tests/ppc/asm/instr_divw.s new file mode 100644 index 0000000..ff01b8b --- /dev/null +++ b/tests/ppc/asm/instr_divw.s @@ -0,0 +1,223 @@ +test_divw_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 2 + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + +test_divw_1_constant: + li r4, 1 + li r5, 2 + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + +# TODO(benvanik): x64 ignore divide by zero (=0) +#test_divw_2: +# #_ REGISTER_IN r4 1 +# #_ REGISTER_IN r5 0 +# divw r3, r4, r5 +# blr +# #_ REGISTER_OUT r3 0 +# #_ REGISTER_OUT r4 1 +# #_ REGISTER_OUT r5 0 + +# TODO(benvanik): x64 ignore divide by zero (=0) +#test_divw_2_constant: +# li r4, 1 +# li r5, 0 +# divw r3, r4, r5 +# blr +# #_ REGISTER_OUT r3 0 +# #_ REGISTER_OUT r4 1 +# #_ REGISTER_OUT r5 0 + +test_divw_3: + #_ REGISTER_IN r4 2 + #_ REGISTER_IN r5 1 + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r5 1 + +test_divw_3_constant: + li r4, 2 + li r5, 1 + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r5 1 + +test_divw_4: + #_ REGISTER_IN r4 35 + #_ REGISTER_IN r5 7 + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 5 + #_ REGISTER_OUT r4 35 + #_ REGISTER_OUT r5 7 + +test_divw_4_constant: + li r4, 35 + li r5, 7 + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 5 + #_ REGISTER_OUT r4 35 + #_ REGISTER_OUT r5 7 + +test_divw_5: + #_ REGISTER_IN r4 0 + #_ REGISTER_IN r5 1 + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r5 1 + +test_divw_5_constant: + li r4, 0 + li r5, 1 + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r5 1 + +test_divw_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000FFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_divw_6_constant: + li r4, -1 + li r5, 1 + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000FFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_divw_7: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_divw_7_constant: + li r4, -1 + li r5, -1 + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_divw_8: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000FFFFFFFF + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_divw_8_constant: + li r4, 1 + li r5, -1 + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000FFFFFFFF + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_divw_9: + #_ REGISTER_IN r4 0x000000007FFFFFFF + #_ REGISTER_IN r5 1 + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x000000007FFFFFFF + #_ REGISTER_OUT r4 0x000000007FFFFFFF + #_ REGISTER_OUT r5 1 + +test_divw_9_constant: + li r4, -1 + clrldi r4, r4, 33 + li r5, 1 + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x000000007FFFFFFF + #_ REGISTER_OUT r4 0x000000007FFFFFFF + #_ REGISTER_OUT r5 1 + +test_divw_10: + #_ REGISTER_IN r4 0x000000007FFFFFFF + #_ REGISTER_IN r5 0x000000007FFFFFFF + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0x000000007FFFFFFF + #_ REGISTER_OUT r5 0x000000007FFFFFFF + +test_divw_10_constant: + li r4, -1 + clrldi r4, r4, 33 + mr r5, r4 + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0x000000007FFFFFFF + #_ REGISTER_OUT r5 0x000000007FFFFFFF + +test_divw_11: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0x000000007FFFFFFF + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0x000000007FFFFFFF + +test_divw_11_constant: + li r4, 1 + li r5, -1 + clrldi r5, r5, 33 + divw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0x000000007FFFFFFF + +# TODO(benvanik): integer overflow (=0) +#test_divw_12: +# #_ REGISTER_IN r4 0x80000000 +# #_ REGISTER_IN r5 -1 +# divw r3, r4, r5 +# blr +# #_ REGISTER_OUT r3 0 +# #_ REGISTER_OUT r4 0x80000000 +# #_ REGISTER_OUT r5 -1 + +# TODO(benvanik): integer overflow (=0) +#test_divw_12_constant: +# li r4, 1 +# srdi r4, 31 +# li r5, -1 +# divw r3, r4, r5 +# blr +# #_ REGISTER_OUT r3 0 +# #_ REGISTER_OUT r4 0x80000000 +# #_ REGISTER_OUT r5 -1 diff --git a/tests/ppc/asm/instr_divwu.s b/tests/ppc/asm/instr_divwu.s new file mode 100644 index 0000000..a3e1b12 --- /dev/null +++ b/tests/ppc/asm/instr_divwu.s @@ -0,0 +1,239 @@ +test_divwu_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 2 + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + +test_divwu_1_constant: + li r4, 1 + li r5, 2 + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 2 + +# TODO(benvanik): x64 ignore divide by zero (=0) +#test_divwu_2: +# #_ REGISTER_IN r4 1 +# #_ REGISTER_IN r5 0 +# divwu r3, r4, r5 +# blr +# #_ REGISTER_OUT r3 0 +# #_ REGISTER_OUT r4 1 +# #_ REGISTER_OUT r5 0 + +# TODO(benvanik): x64 ignore divide by zero (=0) +#test_divwu_2_constant: +# li r4, 1 +# li r5, 0 +# divwu r3, r4, r5 +# blr +# #_ REGISTER_OUT r3 0 +# #_ REGISTER_OUT r4 1 +# #_ REGISTER_OUT r5 0 + +test_divwu_3: + #_ REGISTER_IN r4 2 + #_ REGISTER_IN r5 1 + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r5 1 + +test_divwu_3_constant: + li r4, 2 + li r5, 1 + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 2 + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r5 1 + +test_divwu_4: + #_ REGISTER_IN r4 35 + #_ REGISTER_IN r5 7 + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 5 + #_ REGISTER_OUT r4 35 + #_ REGISTER_OUT r5 7 + +test_divwu_4_constant: + li r4, 35 + li r5, 7 + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 5 + #_ REGISTER_OUT r4 35 + #_ REGISTER_OUT r5 7 + +test_divwu_5: + #_ REGISTER_IN r4 0 + #_ REGISTER_IN r5 1 + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r5 1 + +test_divwu_5_constant: + li r4, 0 + li r5, 1 + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r5 1 + +test_divwu_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000FFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_divwu_6_constant: + li r4, -1 + li r5, 1 + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000FFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_divwu_7: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_divwu_7_constant: + li r4, -1 + li r5, -1 + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_divwu_8: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_divwu_8_constant: + li r4, 1 + li r5, -1 + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_divwu_9: + #_ REGISTER_IN r4 0x000000007FFFFFFF + #_ REGISTER_IN r5 1 + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x000000007FFFFFFF + #_ REGISTER_OUT r4 0x000000007FFFFFFF + #_ REGISTER_OUT r5 1 + +test_divwu_9_constant: + li r4, -1 + clrldi r4, r4, 33 + li r5, 1 + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x000000007FFFFFFF + #_ REGISTER_OUT r4 0x000000007FFFFFFF + #_ REGISTER_OUT r5 1 + +test_divwu_10: + #_ REGISTER_IN r4 0x000000007FFFFFFF + #_ REGISTER_IN r5 0x000000007FFFFFFF + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0x000000007FFFFFFF + #_ REGISTER_OUT r5 0x000000007FFFFFFF + +test_divwu_10_constant: + li r4, -1 + clrldi r4, r4, 33 + mr r5, r4 + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0x000000007FFFFFFF + #_ REGISTER_OUT r5 0x000000007FFFFFFF + +test_divwu_11: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0x000000007FFFFFFF + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0x000000007FFFFFFF + +test_divwu_11_constant: + li r4, 1 + li r5, -1 + clrldi r5, r5, 33 + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0x000000007FFFFFFF + +test_divwu_12: + #_ REGISTER_IN r4 0x80000000 + #_ REGISTER_IN r5 -1 + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0x80000000 + #_ REGISTER_OUT r5 -1 + +test_divwu_12_constant: + li r4, 1 + sldi r4, r4, 31 + li r5, -1 + divwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0x80000000 + #_ REGISTER_OUT r5 -1 + +test_divwu_13: + #_ REGISTER_IN r0 0x1 + #_ REGISTER_IN r3 0xFFFFFFFF + divwu. r0, r3, r0 + blr + #_ REGISTER_OUT r0 0xFFFFFFFF + #_ REGISTER_OUT r3 0xFFFFFFFF + #_ REGISTER_OUT cr 0x0000000080000000 + +test_divwu_14: + #_ REGISTER_IN r0 0x1 + #_ REGISTER_IN r3 0xFFFFFFFF + divwu. r0, r0, r3 + blr + #_ REGISTER_OUT r0 0 + #_ REGISTER_OUT r3 0xFFFFFFFF + #_ REGISTER_OUT cr 0x0000000020000000 diff --git a/tests/ppc/asm/instr_eqv.s b/tests/ppc/asm/instr_eqv.s new file mode 100644 index 0000000..249a306 --- /dev/null +++ b/tests/ppc/asm/instr_eqv.s @@ -0,0 +1,119 @@ +test_eqv_1: + #_ REGISTER_IN r4 0 + #_ REGISTER_IN r5 1 + eqv r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xfffffffffffffffe + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r5 1 + +test_eqv_1_constant: + li r4, 0 + li r5, 1 + eqv r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xfffffffffffffffe + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r5 1 + +test_eqv_2: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0 + eqv r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + +test_eqv_2_constant: + li r4, -1 + li r5, 0 + eqv r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + +test_eqv_3: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + eqv r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_eqv_3_constant: + li r4, -1 + li r5, -1 + eqv r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_eqv_4: + #_ REGISTER_IN r4 0xDEADBEEFDEADBEEF + #_ REGISTER_IN r5 0xDEADBEEFDEADBEEF + eqv r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xDEADBEEFDEADBEEF + #_ REGISTER_OUT r5 0xDEADBEEFDEADBEEF + +test_eqv_4_constant: + lis r4, 0xDEAD + ori r4, r4, 0xBEEF + sldi r5, r4, 32 + clrldi r4, r4, 32 + or r4, r5, r4 + mr r5, r4 + eqv r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xDEADBEEFDEADBEEF + #_ REGISTER_OUT r5 0xDEADBEEFDEADBEEF + +test_eqv_5: + #_ REGISTER_IN r4 0xDEADBEEFDEADBEEF + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + eqv r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xDEADBEEFDEADBEEF + #_ REGISTER_OUT r4 0xDEADBEEFDEADBEEF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_eqv_5_constant: + lis r4, 0xDEAD + ori r4, r4, 0xBEEF + sldi r5, r4, 32 + clrldi r4, r4, 32 + or r4, r5, r4 + li r5, -1 + eqv r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xDEADBEEFDEADBEEF + #_ REGISTER_OUT r4 0xDEADBEEFDEADBEEF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_eqv_6: + #_ REGISTER_IN r4 0xDEADBEEFDEADBEEF + #_ REGISTER_IN r5 0 + eqv r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x2152411021524110 + #_ REGISTER_OUT r4 0xDEADBEEFDEADBEEF + #_ REGISTER_OUT r5 0 + +test_eqv_6_constant: + lis r4, 0xDEAD + ori r4, r4, 0xBEEF + sldi r5, r4, 32 + clrldi r4, r4, 32 + or r4, r5, r4 + li r5, 0 + eqv r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x2152411021524110 + #_ REGISTER_OUT r4 0xDEADBEEFDEADBEEF + #_ REGISTER_OUT r5 0 diff --git a/tests/ppc/asm/instr_extsb.s b/tests/ppc/asm/instr_extsb.s new file mode 100644 index 0000000..c377c4a --- /dev/null +++ b/tests/ppc/asm/instr_extsb.s @@ -0,0 +1,129 @@ +test_extsb_1: + #_ REGISTER_IN r4 0x0F + extsb r3, r4 + blr + #_ REGISTER_OUT r3 0x0F + #_ REGISTER_OUT r4 0x0F + +test_extsb_1_constant: + li r4, 0x0F + extsb r3, r4 + blr + #_ REGISTER_OUT r3 0x0F + #_ REGISTER_OUT r4 0x0F + +test_extsb_2: + #_ REGISTER_IN r4 0x7F + extsb r3, r4 + blr + #_ REGISTER_OUT r3 0x7F + #_ REGISTER_OUT r4 0x7F + +test_extsb_2_constant: + li r4, 0x7F + extsb r3, r4 + blr + #_ REGISTER_OUT r3 0x7F + #_ REGISTER_OUT r4 0x7F + +test_extsb_3: + #_ REGISTER_IN r4 0x80 + extsb r3, r4 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFF80 + #_ REGISTER_OUT r4 0x80 + +test_extsb_3_constant: + li r4, 0x80 + extsb r3, r4 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFF80 + #_ REGISTER_OUT r4 0x80 + +test_extsb_4: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFF080 + extsb r3, r4 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFF80 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFF080 + +test_extsb_4_constant: + li r4, 0xF7F + not r4, r4 + extsb r3, r4 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFF80 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFF080 + +test_extsb_cr_1: + #_ REGISTER_IN r4 0x0F + extsb. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0F + #_ REGISTER_OUT r4 0x0F + #_ REGISTER_OUT r12 0x40000000 + +test_extsb_cr_1_constant: + li r4, 0x0F + extsb. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0F + #_ REGISTER_OUT r4 0x0F + #_ REGISTER_OUT r12 0x40000000 + +test_extsb_cr_2: + #_ REGISTER_IN r4 0x7F + extsb. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x7F + #_ REGISTER_OUT r4 0x7F + #_ REGISTER_OUT r12 0x40000000 + +test_extsb_cr_2_constant: + li r4, 0x7F + extsb. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x7F + #_ REGISTER_OUT r4 0x7F + #_ REGISTER_OUT r12 0x40000000 + +test_extsb_cr_3: + #_ REGISTER_IN r4 0x80 + extsb. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFF80 + #_ REGISTER_OUT r4 0x80 + #_ REGISTER_OUT r12 0x80000000 + +test_extsb_cr_3_constant: + li r4, 0x80 + extsb. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFF80 + #_ REGISTER_OUT r4 0x80 + #_ REGISTER_OUT r12 0x80000000 + +test_extsb_cr_4: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFF080 + extsb. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFF80 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFF080 + #_ REGISTER_OUT r12 0x80000000 + +test_extsb_cr_4_constant: + li r4, 0xF7F + not r4, r4 + extsb. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFF80 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFF080 + #_ REGISTER_OUT r12 0x80000000 diff --git a/tests/ppc/asm/instr_extsh.s b/tests/ppc/asm/instr_extsh.s new file mode 100644 index 0000000..956c372 --- /dev/null +++ b/tests/ppc/asm/instr_extsh.s @@ -0,0 +1,133 @@ +test_extsh_1: + #_ REGISTER_IN r4 0x0F + extsh r3, r4 + blr + #_ REGISTER_OUT r3 0x0F + #_ REGISTER_OUT r4 0x0F + +test_extsh_1_constant: + li r4, 0x0F + extsh r3, r4 + blr + #_ REGISTER_OUT r3 0x0F + #_ REGISTER_OUT r4 0x0F + +test_extsh_2: + #_ REGISTER_IN r4 0x7FFF + extsh r3, r4 + blr + #_ REGISTER_OUT r3 0x7FFF + #_ REGISTER_OUT r4 0x7FFF + +test_extsh_2_constant: + li r4, 0x7FFF + extsh r3, r4 + blr + #_ REGISTER_OUT r3 0x7FFF + #_ REGISTER_OUT r4 0x7FFF + +test_extsh_3: + #_ REGISTER_IN r4 0x8000 + extsh r3, r4 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFF8000 + #_ REGISTER_OUT r4 0x8000 + +test_extsh_3_constant: + li r4, 0x80 + sldi r4, r4, 8 + extsh r3, r4 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFF8000 + #_ REGISTER_OUT r4 0x8000 + +test_extsh_4: + #_ REGISTER_IN r4 0xFFFFFFFFFFF08000 + extsh r3, r4 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFF8000 + #_ REGISTER_OUT r4 0xFFFFFFFFFFF08000 + +test_extsh_4_constant: + li r4, 0xF7F + not r4, r4 + sldi r4, r4, 8 + extsh r3, r4 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFF8000 + #_ REGISTER_OUT r4 0xFFFFFFFFFFF08000 + +test_extsh_cr_1: + #_ REGISTER_IN r4 0x0F + extsh. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0F + #_ REGISTER_OUT r4 0x0F + #_ REGISTER_OUT r12 0x40000000 + +test_extsh_cr_1_constant: + li r4, 0x0F + extsh. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0F + #_ REGISTER_OUT r4 0x0F + #_ REGISTER_OUT r12 0x40000000 + +test_extsh_cr_2: + #_ REGISTER_IN r4 0x7FFF + extsh. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x7FFF + #_ REGISTER_OUT r4 0x7FFF + #_ REGISTER_OUT r12 0x40000000 + +test_extsh_cr_2_constant: + li r4, 0x7FFF + extsh. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x7FFF + #_ REGISTER_OUT r4 0x7FFF + #_ REGISTER_OUT r12 0x40000000 + +test_extsh_cr_3: + #_ REGISTER_IN r4 0x8000 + extsh. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFF8000 + #_ REGISTER_OUT r4 0x8000 + #_ REGISTER_OUT r12 0x80000000 + +test_extsh_cr_3_constant: + li r4, 0x80 + sldi r4, r4, 8 + extsh. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFF8000 + #_ REGISTER_OUT r4 0x8000 + #_ REGISTER_OUT r12 0x80000000 + +test_extsh_cr_4: + #_ REGISTER_IN r4 0xFFFFFFFFFFF08000 + extsh. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFF8000 + #_ REGISTER_OUT r4 0xFFFFFFFFFFF08000 + #_ REGISTER_OUT r12 0x80000000 + +test_extsh_cr_4_constant: + li r4, 0xF7F + not r4, r4 + sldi r4, r4, 8 + extsh. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFF8000 + #_ REGISTER_OUT r4 0xFFFFFFFFFFF08000 + #_ REGISTER_OUT r12 0x80000000 diff --git a/tests/ppc/asm/instr_extsw.s b/tests/ppc/asm/instr_extsw.s new file mode 100644 index 0000000..c7df978 --- /dev/null +++ b/tests/ppc/asm/instr_extsw.s @@ -0,0 +1,135 @@ +test_extsw_1: + #_ REGISTER_IN r4 0x0F + extsw r3, r4 + blr + #_ REGISTER_OUT r3 0x0F + #_ REGISTER_OUT r4 0x0F + +test_extsw_1_constant: + li r4, 0x0F + extsw r3, r4 + blr + #_ REGISTER_OUT r3 0x0F + #_ REGISTER_OUT r4 0x0F + +test_extsw_2: + #_ REGISTER_IN r4 0x7FFFFFFF + extsw r3, r4 + blr + #_ REGISTER_OUT r3 0x7FFFFFFF + #_ REGISTER_OUT r4 0x7FFFFFFF + +test_extsw_2_constant: + lis r4, 0x7FFF + ori r4, r4, 0xFFFF + extsw r3, r4 + blr + #_ REGISTER_OUT r3 0x7FFFFFFF + #_ REGISTER_OUT r4 0x7FFFFFFF + +test_extsw_3: + #_ REGISTER_IN r4 0x80000000 + extsw r3, r4 + blr + #_ REGISTER_OUT r3 0xFFFFFFFF80000000 + #_ REGISTER_OUT r4 0x80000000 + +test_extsw_3_constant: + li r4, 0x80 + sldi r4, r4, 24 + extsw r3, r4 + blr + #_ REGISTER_OUT r3 0xFFFFFFFF80000000 + #_ REGISTER_OUT r4 0x80000000 + +test_extsw_4: + #_ REGISTER_IN r4 0xFFFFFFF080000000 + extsw r3, r4 + blr + #_ REGISTER_OUT r3 0xFFFFFFFF80000000 + #_ REGISTER_OUT r4 0xFFFFFFF080000000 + +test_extsw_4_constant: + li r4, 0xF7F + not r4, r4 + sldi r4, r4, 24 + extsw r3, r4 + blr + #_ REGISTER_OUT r3 0xFFFFFFFF80000000 + #_ REGISTER_OUT r4 0xFFFFFFF080000000 + +test_extsw_cr_1: + #_ REGISTER_IN r4 0x0F + extsw. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0F + #_ REGISTER_OUT r4 0x0F + #_ REGISTER_OUT r12 0x40000000 + +test_extsw_cr_1_constant: + li r4, 0x0F + extsw. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x0F + #_ REGISTER_OUT r4 0x0F + #_ REGISTER_OUT r12 0x40000000 + +test_extsw_cr_2: + #_ REGISTER_IN r4 0x7FFFFFFF + extsw. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x7FFFFFFF + #_ REGISTER_OUT r4 0x7FFFFFFF + #_ REGISTER_OUT r12 0x40000000 + +test_extsw_cr_2_constant: + lis r4, 0x7FFF + ori r4, r4, 0xFFFF + extsw. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0x7FFFFFFF + #_ REGISTER_OUT r4 0x7FFFFFFF + #_ REGISTER_OUT r12 0x40000000 + +test_extsw_cr_3: + #_ REGISTER_IN r4 0x80000000 + extsw. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFF80000000 + #_ REGISTER_OUT r4 0x80000000 + #_ REGISTER_OUT r12 0x80000000 + +test_extsw_cr_3_constant: + li r4, 0x80 + sldi r4, r4, 24 + extsw. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFF80000000 + #_ REGISTER_OUT r4 0x80000000 + #_ REGISTER_OUT r12 0x80000000 + +test_extsw_cr_4: + #_ REGISTER_IN r4 0xFFFFFFF080000000 + extsw. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFF80000000 + #_ REGISTER_OUT r4 0xFFFFFFF080000000 + #_ REGISTER_OUT r12 0x80000000 + +test_extsw_cr_4_constant: + li r4, 0xF7F + not r4, r4 + sldi r4, r4, 24 + extsw. r3, r4 + mfcr r12 + blr + #_ REGISTER_OUT r3 0xFFFFFFFF80000000 + #_ REGISTER_OUT r4 0xFFFFFFF080000000 + #_ REGISTER_OUT r12 0x80000000 diff --git a/tests/ppc/asm/instr_fabs.s b/tests/ppc/asm/instr_fabs.s new file mode 100644 index 0000000..60fc684 --- /dev/null +++ b/tests/ppc/asm/instr_fabs.s @@ -0,0 +1,41 @@ +test_fabs_1: + #_ REGISTER_IN f1 1.0 + fabs f1, f1 + blr + #_ REGISTER_OUT f1 1.0 + +test_fabs_2: + #_ REGISTER_IN f1 -1.0 + fabs f1, f1 + blr + #_ REGISTER_OUT f1 1.0 + +test_fabs_3: + #_ REGISTER_IN f1 -1234.0 + fabs f1, f1 + blr + #_ REGISTER_OUT f1 1234.0 + +#test_fabs_cr_1: +# #_ REGISTER_IN f1 1.0 +# fabs. f1, f1 +# mfcr r12 +# blr +# #_ REGISTER_OUT f1 1.0 +# #_ REGISTER_OUT r12 0x04000000 + +#test_fabs_cr_2: +# #_ REGISTER_IN f1 -1.0 +# fabs. f1, f1 +# mfcr r12 +# blr +# #_ REGISTER_OUT f1 1.0 +# #_ REGISTER_OUT r12 0x08000000 + +#test_fabs_cr_3: +# #_ REGISTER_IN f1 -1234.0 +# fabs. f1, f1 +# mfcr r12 +# blr +# #_ REGISTER_OUT f1 1234.0 +# #_ REGISTER_OUT r12 0x08000000 diff --git a/tests/ppc/asm/instr_fadd.s b/tests/ppc/asm/instr_fadd.s new file mode 100644 index 0000000..71e116e --- /dev/null +++ b/tests/ppc/asm/instr_fadd.s @@ -0,0 +1,20 @@ +test_fadd_1: + #_ REGISTER_IN f1 1.0 + #_ REGISTER_IN f2 2.0 + fadd f3, f1, f2 + blr + #_ REGISTER_OUT f3 3.0 + +test_fadd_2: + #_ REGISTER_IN f1 0.0 + #_ REGISTER_IN f2 0.0 + fadd f3, f1, f2 + blr + #_ REGISTER_OUT f3 0.0 + +test_fadd_3: + #_ REGISTER_IN f1 -200.0 + #_ REGISTER_IN f2 200.0 + fadd f3, f1, f2 + blr + #_ REGISTER_OUT f3 0.0 diff --git a/tests/ppc/asm/instr_fctixz.s b/tests/ppc/asm/instr_fctixz.s new file mode 100644 index 0000000..4f132a6 --- /dev/null +++ b/tests/ppc/asm/instr_fctixz.s @@ -0,0 +1,194 @@ +# Credits: These tests stolen from https://github.com/dolphin-emu/hwtests +# +0 +test_fctiwz_1: + #_ REGISTER_IN f0 0x0000000000000000 + fctiwz f1, f0 + blr + #_ REGISTER_OUT f0 0x0000000000000000 + #_ REGISTER_OUT f1 0x0000000000000000 + +# -0 +test_fctiwz_2: + #_ REGISTER_IN f0 0x8000000000000000 + fctiwz f1, f0 + blr + #_ REGISTER_OUT f0 0x8000000000000000 + #_ REGISTER_OUT f1 0x0000000000000000 + +# smallest positive subnormal +test_fctiwz_3: + #_ REGISTER_IN f0 0x0000000000000001 + fctiwz f1, f0 + blr + #_ REGISTER_OUT f0 0x0000000000000001 + #_ REGISTER_OUT f1 0x0000000000000000 + +# largest subnormal +test_fctiwz_4: + #_ REGISTER_IN f0 0x000fffffffffffff + fctiwz f1, f0 + blr + #_ REGISTER_OUT f0 0x000fffffffffffff + #_ REGISTER_OUT f1 0x0000000000000000 + +# +1 +test_fctiwz_5: + #_ REGISTER_IN f0 0x3ff0000000000000 + fctiwz f1, f0 + blr + #_ REGISTER_OUT f0 0x3ff0000000000000 + #_ REGISTER_OUT f1 0x0000000000000001 + +# -1 +test_fctiwz_6: + #_ REGISTER_IN f0 0xbff0000000000000 + fctiwz f1, f0 + blr + #_ REGISTER_OUT f0 0xbff0000000000000 + #_ REGISTER_OUT f1 0xffffffffffffffff + +# -(2^31) +test_fctiwz_7: + #_ REGISTER_IN f0 0xc1e0000000000000 + fctiwz f1, f0 + blr + #_ REGISTER_OUT f0 0xc1e0000000000000 + #_ REGISTER_OUT f1 0xFFFFFFFF80000000 + +# 2^31 - 1 +test_fctiwz_8: + #_ REGISTER_IN f0 0x41dfffffffc00000 + fctiwz f1, f0 + blr + #_ REGISTER_OUT f0 0x41dfffffffc00000 + #_ REGISTER_OUT f1 0x000000007fffffff + +# +infinity +test_fctiwz_9: + #_ REGISTER_IN f0 0x7ff0000000000000 + fctiwz f1, f0 + blr + #_ REGISTER_OUT f0 0x7ff0000000000000 + #_ REGISTER_OUT f1 0x000000007fffffff + +# -infinity +test_fctiwz_10: + #_ REGISTER_IN f0 0xfff0000000000000 + fctiwz f1, f0 + blr + #_ REGISTER_OUT f0 0xfff0000000000000 + #_ REGISTER_OUT f1 0xFFFFFFFF80000000 + +# TODO(DrChat): Xenia doesn't handle NaNs yet. +# # QNaN +# test_fctiwz_11: +# #_ REGISTER_IN f0 0xfff8000000000000 +# fctiwz f1, f0 +# blr +# #_ REGISTER_OUT f0 0xfff8000000000000 +# #_ REGISTER_OUT f1 0xFFFFFFFF80000000 +# +# # SNaN +# test_fctiwz_12: +# #_ REGISTER_IN f0 0xfff4000000000000 +# fctiwz f1, f0 +# blr +# #_ REGISTER_OUT f0 0xfff4000000000000 +# #_ REGISTER_OUT f1 0xFFFFFFFF80000000 + +# +0 +test_fctidz_1: + #_ REGISTER_IN f0 0x0000000000000000 + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0x0000000000000000 + #_ REGISTER_OUT f1 0x0000000000000000 + +# -0 +test_fctidz_2: + #_ REGISTER_IN f0 0x8000000000000000 + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0x8000000000000000 + #_ REGISTER_OUT f1 0x0000000000000000 + +# smallest positive subnormal +test_fctidz_3: + #_ REGISTER_IN f0 0x0000000000000001 + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0x0000000000000001 + #_ REGISTER_OUT f1 0x0000000000000000 + +# largest subnormal +test_fctidz_4: + #_ REGISTER_IN f0 0x000fffffffffffff + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0x000fffffffffffff + #_ REGISTER_OUT f1 0x0000000000000000 + +# +1 +test_fctidz_5: + #_ REGISTER_IN f0 0x3ff0000000000000 + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0x3ff0000000000000 + #_ REGISTER_OUT f1 0x0000000000000001 + +# -1 +test_fctidz_6: + #_ REGISTER_IN f0 0xbff0000000000000 + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0xbff0000000000000 + #_ REGISTER_OUT f1 0xffffffffffffffff + +# -(2^31) +test_fctidz_7: + #_ REGISTER_IN f0 0xc1e0000000000000 + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0xc1e0000000000000 + #_ REGISTER_OUT f1 0xffffffff80000000 + +# 2^31 - 1 +test_fctidz_8: + #_ REGISTER_IN f0 0x41dfffffffc00000 + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0x41dfffffffc00000 + #_ REGISTER_OUT f1 0x000000007fffffff + +# +infinity +test_fctidz_9: + #_ REGISTER_IN f0 0x7ff0000000000000 + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0x7ff0000000000000 + #_ REGISTER_OUT f1 0x7fffffffffffffff + +# -infinity +test_fctidz_10: + #_ REGISTER_IN f0 0xfff0000000000000 + fctidz f1, f0 + blr + #_ REGISTER_OUT f0 0xfff0000000000000 + #_ REGISTER_OUT f1 0x8000000000000000 + +# TODO(DrChat): Xenia doesn't handle NaNs yet. +# # QNaN +# test_fctidz_11: +# #_ REGISTER_IN f0 0xfff8000000000000 +# fctidz f1, f0 +# blr +# #_ REGISTER_OUT f0 0xfff8000000000000 +# #_ REGISTER_OUT f1 0x8000000000000000 +# +# # SNaN +# test_fctidz_12: +# #_ REGISTER_IN f0 0xfff4000000000000 +# fctidz f1, f0 +# blr +# #_ REGISTER_OUT f0 0xfff4000000000000 +# #_ REGISTER_OUT f1 0x8000000000000000 diff --git a/tests/ppc/asm/instr_fmadd.s b/tests/ppc/asm/instr_fmadd.s new file mode 100644 index 0000000..eaa5fbb --- /dev/null +++ b/tests/ppc/asm/instr_fmadd.s @@ -0,0 +1,47 @@ +test_fmadd_1: + #_ REGISTER_IN f1 0.0 + #_ REGISTER_IN f2 5.0 + #_ REGISTER_IN f3 5.0 + #_ REGISTER_IN f4 0.0 + fmadd f1, f2, f3, f4 + blr + #_ REGISTER_OUT f1 25.0 + #_ REGISTER_OUT f2 5.0 + #_ REGISTER_OUT f3 5.0 + #_ REGISTER_OUT f4 0.0 + +test_fmadd_2: + #_ REGISTER_IN f1 0.0 + #_ REGISTER_IN f2 5.0 + #_ REGISTER_IN f3 0.0 + #_ REGISTER_IN f4 15.0 + fmadd f1, f2, f3, f4 + blr + #_ REGISTER_OUT f1 15.0 + #_ REGISTER_OUT f2 5.0 + #_ REGISTER_OUT f3 0.0 + #_ REGISTER_OUT f4 15.0 + +test_fmadd_3: + #_ REGISTER_IN f1 0.0 + #_ REGISTER_IN f2 5.0 + #_ REGISTER_IN f3 5.0 + #_ REGISTER_IN f4 15.0 + fmadd f1, f2, f3, f4 + blr + #_ REGISTER_OUT f1 40.0 + #_ REGISTER_OUT f2 5.0 + #_ REGISTER_OUT f3 5.0 + #_ REGISTER_OUT f4 15.0 + +test_fmadd_4: + #_ REGISTER_IN f1 0.0 + #_ REGISTER_IN f2 9999.99 + #_ REGISTER_IN f3 9999.99 + #_ REGISTER_IN f4 9999.99 + fmadd f1, f2, f3, f4 + blr + #_ REGISTER_OUT f1 100009799.9901 + #_ REGISTER_OUT f2 9999.99 + #_ REGISTER_OUT f3 9999.99 + #_ REGISTER_OUT f4 9999.99 diff --git a/tests/ppc/asm/instr_fmadds.s b/tests/ppc/asm/instr_fmadds.s new file mode 100644 index 0000000..c4e05fb --- /dev/null +++ b/tests/ppc/asm/instr_fmadds.s @@ -0,0 +1,47 @@ +test_fmadds_1: + #_ REGISTER_IN f1 0.0 + #_ REGISTER_IN f2 5.0 + #_ REGISTER_IN f3 5.0 + #_ REGISTER_IN f4 0.0 + fmadds f1, f2, f3, f4 + blr + #_ REGISTER_OUT f1 25.0 + #_ REGISTER_OUT f2 5.0 + #_ REGISTER_OUT f3 5.0 + #_ REGISTER_OUT f4 0.0 + +test_fmadds_2: + #_ REGISTER_IN f1 0.0 + #_ REGISTER_IN f2 5.0 + #_ REGISTER_IN f3 0.0 + #_ REGISTER_IN f4 15.0 + fmadds f1, f2, f3, f4 + blr + #_ REGISTER_OUT f1 15.0 + #_ REGISTER_OUT f2 5.0 + #_ REGISTER_OUT f3 0.0 + #_ REGISTER_OUT f4 15.0 + +test_fmadds_3: + #_ REGISTER_IN f1 0.0 + #_ REGISTER_IN f2 5.0 + #_ REGISTER_IN f3 5.0 + #_ REGISTER_IN f4 15.0 + fmadds f1, f2, f3, f4 + blr + #_ REGISTER_OUT f1 40.0 + #_ REGISTER_OUT f2 5.0 + #_ REGISTER_OUT f3 5.0 + #_ REGISTER_OUT f4 15.0 + +test_fmadds_4: + #_ REGISTER_IN f1 0.0 + #_ REGISTER_IN f2 9999.99 + #_ REGISTER_IN f3 9999.99 + #_ REGISTER_IN f4 9999.99 + fmadds f1, f2, f3, f4 + blr + #_ REGISTER_OUT f1 100009800.0 + #_ REGISTER_OUT f2 9999.99 + #_ REGISTER_OUT f3 9999.99 + #_ REGISTER_OUT f4 9999.99 diff --git a/tests/ppc/asm/instr_fmul.s b/tests/ppc/asm/instr_fmul.s new file mode 100644 index 0000000..69a6bf1 --- /dev/null +++ b/tests/ppc/asm/instr_fmul.s @@ -0,0 +1,20 @@ +test_fmul_1: + #_ REGISTER_IN f1 5.0 + #_ REGISTER_IN f2 5.0 + fmul f3, f1, f2 + blr + #_ REGISTER_OUT f3 25.0 + +test_fmul_2: + #_ REGISTER_IN f1 5.0 + #_ REGISTER_IN f2 0.0 + fmul f3, f1, f2 + blr + #_ REGISTER_OUT f3 0.0 + +test_fmul_3: + #_ REGISTER_IN f1 -2.0 + #_ REGISTER_IN f2 2.0 + fmul f3, f1, f2 + blr + #_ REGISTER_OUT f3 -4.0 diff --git a/tests/ppc/asm/instr_fnabs.s b/tests/ppc/asm/instr_fnabs.s new file mode 100644 index 0000000..73e2f70 --- /dev/null +++ b/tests/ppc/asm/instr_fnabs.s @@ -0,0 +1,5 @@ +test_fnabs_1: + #_ REGISTER_IN f1 0x400C000000000000 + fnabs f2, f1 + blr + #_ REGISTER_OUT f2 0xC00C000000000000 diff --git a/tests/ppc/asm/instr_frsqrte.s b/tests/ppc/asm/instr_frsqrte.s new file mode 100644 index 0000000..e4f5fc0 --- /dev/null +++ b/tests/ppc/asm/instr_frsqrte.s @@ -0,0 +1,19 @@ +test_frsqrte_1: + # _ REGISTER_IN f1 1.0 + frsqrte f1, f1 + blr + # _ REGISTER_OUT f1 0.99975585937500000 + # want: 0.97 + +test_frsqrte_2: + # _ REGISTER_IN f1 64.0 + frsqrte f1, f1 + blr + # _ REGISTER_OUT f1 0.12496948242187500 + +test_frsqrte_3: + # _ REGISTER_IN f1 0.5 + frsqrte f1, f1 + blr + # _ REGISTER_OUT f1 1.41381835937500000 + # want: 1.375 diff --git a/tests/ppc/asm/instr_fsel.s b/tests/ppc/asm/instr_fsel.s new file mode 100644 index 0000000..ca9e52b --- /dev/null +++ b/tests/ppc/asm/instr_fsel.s @@ -0,0 +1,32 @@ +test_fsel_1: + #_ REGISTER_IN f2 2.0 + #_ REGISTER_IN f3 3.0 + #_ REGISTER_IN f4 4.0 + fsel f1, f2, f3, f4 + blr + #_ REGISTER_OUT f1 3.0 + #_ REGISTER_OUT f2 2.0 + #_ REGISTER_OUT f3 3.0 + #_ REGISTER_OUT f4 4.0 + +test_fsel_2: + #_ REGISTER_IN f2 -2.0 + #_ REGISTER_IN f3 3.0 + #_ REGISTER_IN f4 4.0 + fsel f1, f2, f3, f4 + blr + #_ REGISTER_OUT f1 4.0 + #_ REGISTER_OUT f2 -2.0 + #_ REGISTER_OUT f3 3.0 + #_ REGISTER_OUT f4 4.0 + +test_fsel_3: + #_ REGISTER_IN f2 0.0 + #_ REGISTER_IN f3 3.0 + #_ REGISTER_IN f4 4.0 + fsel f1, f2, f3, f4 + blr + #_ REGISTER_OUT f1 3.0 + #_ REGISTER_OUT f2 0.0 + #_ REGISTER_OUT f3 3.0 + #_ REGISTER_OUT f4 4.0 diff --git a/tests/ppc/asm/instr_fsqrt.s b/tests/ppc/asm/instr_fsqrt.s new file mode 100644 index 0000000..792cf3f --- /dev/null +++ b/tests/ppc/asm/instr_fsqrt.s @@ -0,0 +1,17 @@ +test_fsqrt_1: + #_ REGISTER_IN f1 1.0 + fsqrt f1, f1 + blr + #_ REGISTER_OUT f1 1.0000000000000000 + +test_fsqrt_2: + #_ REGISTER_IN f1 64.0 + fsqrt f1, f1 + blr + #_ REGISTER_OUT f1 8.0000000000000000 + +test_fsqrt_3: + #_ REGISTER_IN f1 0.5 + fsqrt f1, f1 + blr + #_ REGISTER_OUT f1 0.70710678118654757 diff --git a/tests/ppc/asm/instr_lvexx.s b/tests/ppc/asm/instr_lvexx.s new file mode 100644 index 0000000..efac04b --- /dev/null +++ b/tests/ppc/asm/instr_lvexx.s @@ -0,0 +1,135 @@ +test_lvebx_1: + #_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f + #_ REGISTER_IN r4 0x10001000 + lvebx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001000 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_lvebx_1_constant: + #_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f + lis r4, 0x1000 + ori r4, r4, 0x1000 + lvebx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001000 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_lvebx_2: + #_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f + #_ REGISTER_IN r4 0x10001004 + lvebx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001004 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_lvebx_2_constant: + #_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f + lis r4, 0x1000 + ori r4, r4, 0x1004 + lvebx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001004 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_lvehx_1: + #_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f + #_ REGISTER_IN r4 0x10001000 + lvehx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001000 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_lvehx_1_constant: + #_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f + lis r4, 0x1000 + ori r4, r4, 0x1000 + lvehx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001000 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_lvehx_2: + #_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f + #_ REGISTER_IN r4 0x10001004 + lvehx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001004 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_lvehx_2_constant: + #_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f + lis r4, 0x1000 + ori r4, r4, 0x1004 + lvehx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001004 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_lvewx_1: + #_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f + #_ REGISTER_IN r4 0x10001000 + lvewx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001000 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_lvewx_1_constant: + #_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f + lis r4, 0x1000 + ori r4, r4, 0x1000 + lvewx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001000 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_lvewx_2: + #_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f + #_ REGISTER_IN r4 0x10001004 + lvewx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001004 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_lvewx_2_constant: + #_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f + lis r4, 0x1000 + ori r4, r4, 0x1004 + lvewx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001004 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_lvewx128_1: + #_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f + #_ REGISTER_IN r4 0x10001000 + lvewx128 v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001000 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_lvewx128_1_constant: + #_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f + lis r4, 0x1000 + ori r4, r4, 0x1000 + lvewx128 v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001000 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_lvewx128_2: + #_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f + #_ REGISTER_IN r4 0x10001004 + lvewx128 v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001004 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_lvewx128_2_constant: + #_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f + lis r4, 0x1000 + ori r4, r4, 0x1004 + lvewx128 v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001004 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] diff --git a/tests/ppc/asm/instr_lvl.s b/tests/ppc/asm/instr_lvl.s new file mode 100644 index 0000000..c2a7ff7 --- /dev/null +++ b/tests/ppc/asm/instr_lvl.s @@ -0,0 +1,16 @@ +test_lvl_1: + #_ MEMORY_IN 10001077 0a 0b 0c 0d 0e 0f 10 13 0c 0d 0e 10 11 12 13 14 ff ff ff ff ff ff + #_ REGISTER_IN r4 0x10001077 + lvlx v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x10001077 + #_ REGISTER_OUT v3 [0A0B0C0D, 0E0F1013, 0C000000, 00000000] + +test_lvl_1_constant: + #_ MEMORY_IN 10001077 0a 0b 0c 0d 0e 0f 10 13 0c 0d 0e 10 11 12 13 14 ff ff ff ff ff ff + lis r4, 0x1000 + ori r4, r4, 0x1077 + lvlx v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x10001077 + #_ REGISTER_OUT v3 [0A0B0C0D, 0E0F1013, 0C000000, 00000000] diff --git a/tests/ppc/asm/instr_lvr.s b/tests/ppc/asm/instr_lvr.s new file mode 100644 index 0000000..706a08a --- /dev/null +++ b/tests/ppc/asm/instr_lvr.s @@ -0,0 +1,40 @@ +test_lvr_1: + #_ MEMORY_IN 100010B0 090A0A0B 0C0F120A 0B0C0D0E 0F10130C 0D0E1011 121314FF FFFFFFFF + #_ REGISTER_IN r4 0x100010B7 + #_ REGISTER_IN r5 0x10 + lvrx v3, r4, r5 + blr + #_ REGISTER_OUT r4 0x100010B7 + #_ REGISTER_OUT r5 0x10 + #_ REGISTER_OUT v3 [00000000, 00000000, 000D0E10, 11121314] + +test_lvr_1_constant: + #_ MEMORY_IN 100010B0 090A0A0B 0C0F120A 0B0C0D0E 0F10130C 0D0E1011 121314FF FFFFFFFF + lis r4, 0x1000 + ori r4, r4, 0x10B7 + li r5, 0x10 + lvrx v3, r4, r5 + blr + #_ REGISTER_OUT r4 0x100010B7 + #_ REGISTER_OUT r5 0x10 + #_ REGISTER_OUT v3 [00000000, 00000000, 000D0E10, 11121314] + +test_lvr_2: + #_ REGISTER_IN r4 0x20000000 + #_ REGISTER_IN r5 0x10 + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + lvrx v3, r4, r5 + blr + #_ REGISTER_OUT r4 0x20000000 + #_ REGISTER_OUT r5 0x10 + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + +test_lvr_2_constant: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + lis r4, 0x2000 + li r5, 0x10 + lvrx v3, r4, r5 + blr + #_ REGISTER_OUT r4 0x20000000 + #_ REGISTER_OUT r5 0x10 + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] diff --git a/tests/ppc/asm/instr_lvsl.s b/tests/ppc/asm/instr_lvsl.s new file mode 100644 index 0000000..493f57a --- /dev/null +++ b/tests/ppc/asm/instr_lvsl.s @@ -0,0 +1,41 @@ +test_lvsl_1: + #_ REGISTER_IN r4 0x1070 + lvsl v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x1070 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_lvsl_1_constant: + li r4, 0x1070 + lvsl v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x1070 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_lvsl_2: + #_ REGISTER_IN r4 0x1071 + lvsl v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x1071 + #_ REGISTER_OUT v3 [01020304, 05060708, 090A0B0C, 0D0E0F10] + +test_lvsl_2_constant: + li r4, 0x1071 + lvsl v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x1071 + #_ REGISTER_OUT v3 [01020304, 05060708, 090A0B0C, 0D0E0F10] + +test_lvsl_3: + #_ REGISTER_IN r4 0x107F + lvsl v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x107F + #_ REGISTER_OUT v3 [0F101112, 13141516, 1718191A, 1B1C1D1E] + +test_lvsl_3_constant: + li r4, 0x107F + lvsl v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x107F + #_ REGISTER_OUT v3 [0F101112, 13141516, 1718191A, 1B1C1D1E] diff --git a/tests/ppc/asm/instr_lvsr.s b/tests/ppc/asm/instr_lvsr.s new file mode 100644 index 0000000..4976236 --- /dev/null +++ b/tests/ppc/asm/instr_lvsr.s @@ -0,0 +1,41 @@ +test_lvsr_1: + #_ REGISTER_IN r4 0x1070 + lvsr v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x1070 + #_ REGISTER_OUT v3 [10111213, 14151617, 18191A1B, 1C1D1E1F] + +test_lvsr_1_constant: + li r4, 0x1070 + lvsr v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x1070 + #_ REGISTER_OUT v3 [10111213, 14151617, 18191A1B, 1C1D1E1F] + +test_lvsr_2: + #_ REGISTER_IN r4 0x1071 + lvsr v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x1071 + #_ REGISTER_OUT v3 [0F101112, 13141516, 1718191A, 1B1C1D1E] + +test_lvsr_2_constant: + li r4, 0x1071 + lvsr v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x1071 + #_ REGISTER_OUT v3 [0F101112, 13141516, 1718191A, 1B1C1D1E] + +test_lvsr_3: + #_ REGISTER_IN r4 0x107F + lvsr v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x107F + #_ REGISTER_OUT v3 [01020304, 05060708, 090A0B0C, 0D0E0F10] + +test_lvsr_3_constant: + li r4, 0x107F + lvsr v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x107F + #_ REGISTER_OUT v3 [01020304, 05060708, 090A0B0C, 0D0E0F10] diff --git a/tests/ppc/asm/instr_mulhd.s b/tests/ppc/asm/instr_mulhd.s new file mode 100644 index 0000000..819a01c --- /dev/null +++ b/tests/ppc/asm/instr_mulhd.s @@ -0,0 +1,89 @@ +test_mulhd_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0 + mulhd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_mulhd_1_constant: + li r4, 1 + li r5, 0 + mulhd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_mulhd_2: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + mulhd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhd_2_constant: + li r4, -1 + li r5, 1 + mulhd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhd_3: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 2 + mulhd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 2 + +test_mulhd_3_constant: + li r4, -1 + li r5, 2 + mulhd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 2 + +test_mulhd_4: + #_ REGISTER_IN r4 0x8000000000000000 + #_ REGISTER_IN r5 1 + mulhd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0x8000000000000000 + #_ REGISTER_OUT r5 1 + +test_mulhd_4_constant: + li r5, 1 + sldi r4, r5, 63 + mulhd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0x8000000000000000 + #_ REGISTER_OUT r5 1 + +test_mulhd_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + mulhd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_mulhd_5_constant: + li r4, -1 + li r5, -1 + mulhd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF diff --git a/tests/ppc/asm/instr_mulhdu.s b/tests/ppc/asm/instr_mulhdu.s new file mode 100644 index 0000000..06e062c --- /dev/null +++ b/tests/ppc/asm/instr_mulhdu.s @@ -0,0 +1,89 @@ +test_mulhdu_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0 + mulhdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_mulhdu_1_constant: + li r4, 1 + li r5, 0 + mulhdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_mulhdu_2: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + mulhdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhdu_2_constant: + li r4, -1 + li r5, 1 + mulhdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhdu_3: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 2 + mulhdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 2 + +test_mulhdu_3_constant: + li r4, -1 + li r5, 2 + mulhdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 2 + +test_mulhdu_4: + #_ REGISTER_IN r4 0x8000000000000000 + #_ REGISTER_IN r5 1 + mulhdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0x8000000000000000 + #_ REGISTER_OUT r5 1 + +test_mulhdu_4_constant: + li r5, 1 + sldi r4, r5, 63 + mulhdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0x8000000000000000 + #_ REGISTER_OUT r5 1 + +test_mulhdu_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + mulhdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_mulhdu_5_constant: + li r4, -1 + li r5, -1 + mulhdu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF diff --git a/tests/ppc/asm/instr_mulhw.s b/tests/ppc/asm/instr_mulhw.s new file mode 100644 index 0000000..e435cb5 --- /dev/null +++ b/tests/ppc/asm/instr_mulhw.s @@ -0,0 +1,113 @@ +test_mulhw_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0 + mulhw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_mulhw_1_constant: + li r4, 1 + li r5, 0 + mulhw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_mulhw_2: + #_ REGISTER_IN r4 0x00000000FFFFFFFF + #_ REGISTER_IN r5 1 + mulhw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0x00000000FFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhw_2_constant: + li r4, -1 + clrldi r4, r4, 32 + li r5, 1 + mulhw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0x00000000FFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhw_3: + #_ REGISTER_IN r4 0x00000001FFFFFFFF + #_ REGISTER_IN r5 1 + mulhw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0x00000001FFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhw_3_constant: + li r4, -1 + clrldi r4, r4, 31 + li r5, 1 + mulhw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0x00000001FFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhw_4: + #_ REGISTER_IN r4 0x800000007FFFFFFF + #_ REGISTER_IN r5 1 + mulhw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0x800000007FFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhw_4_constant: + li r4, -1 + clrldi r4, r4, 33 + li r5, 1 + sldi r5, r5, 63 + or r4, r4, r5 + li r5, 1 + mulhw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0x800000007FFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhw_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + mulhw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhw_5_constant: + li r4, -1 + li r5, 1 + mulhw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhw_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + mulhw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_mulhw_6_constant: + li r4, -1 + li r5, -1 + mulhw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF diff --git a/tests/ppc/asm/instr_mulhwu.s b/tests/ppc/asm/instr_mulhwu.s new file mode 100644 index 0000000..5f5fdd6 --- /dev/null +++ b/tests/ppc/asm/instr_mulhwu.s @@ -0,0 +1,131 @@ +test_mulhwu_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0 + mulhwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_mulhwu_1_constant: + li r4, 1 + li r5, 0 + mulhwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_mulhwu_2: + #_ REGISTER_IN r4 0x00000000FFFFFFFF + #_ REGISTER_IN r5 1 + mulhwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0x00000000FFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhwu_2_constant: + li r4, -1 + clrldi r4, r4, 32 + li r5, 1 + mulhwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0x00000000FFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhwu_3: + #_ REGISTER_IN r4 0x00000001FFFFFFFF + #_ REGISTER_IN r5 1 + mulhwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0x00000001FFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhwu_3_constant: + li r4, -1 + clrldi r4, r4, 31 + li r5, 1 + mulhwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0x00000001FFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhwu_4: + #_ REGISTER_IN r4 0x800000007FFFFFFF + #_ REGISTER_IN r5 1 + mulhwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0x800000007FFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhwu_4_constant: + li r4, -1 + clrldi r4, r4, 33 + li r5, 1 + sldi r5, r5, 63 + or r4, r4, r5 + li r5, 1 + mulhwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0x800000007FFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhwu_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + mulhwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhwu_5_constant: + li r4, -1 + li r5, 1 + mulhwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulhwu_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF + mulhwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000FFFFFFFE + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_mulhwu_6_constant: + li r4, -1 + li r5, -1 + mulhwu r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000FFFFFFFE + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF + +test_mulhwu_7: + #_ REGISTER_IN r0 0x1 + #_ REGISTER_IN r3 0xFFFFFFFF + mulhwu. r0, r3, r0 + blr + #_ REGISTER_OUT r0 0 + #_ REGISTER_OUT r3 0xFFFFFFFF + #_ REGISTER_OUT cr 0x0000000020000000 + +test_mulhwu_8: + #_ REGISTER_IN r0 0x1 + #_ REGISTER_IN r3 0x1FFFFFFFF + mulhwu. r0, r3, r0 + blr + #_ REGISTER_OUT r0 0 + #_ REGISTER_OUT r3 0x1FFFFFFFF + #_ REGISTER_OUT cr 0x0000000020000000 diff --git a/tests/ppc/asm/instr_mulld.s b/tests/ppc/asm/instr_mulld.s new file mode 100644 index 0000000..4cfed15 --- /dev/null +++ b/tests/ppc/asm/instr_mulld.s @@ -0,0 +1,143 @@ +test_mulld_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0 + mulld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_mulld_1_constant: + li r4, 1 + li r5, 0 + mulld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_mulld_2: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 1 + mulld r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 1 + +test_mulld_2_constant: + li r4, 1 + li r5, 1 + mulld r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 1 + +test_mulld_3: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 -1 + mulld r3, r4, r5 + blr + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 -1 + +test_mulld_3_constant: + li r4, 1 + li r5, -1 + mulld r3, r4, r5 + blr + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 -1 + +test_mulld_4: + #_ REGISTER_IN r4 123 + #_ REGISTER_IN r5 -1 + mulld r3, r4, r5 + blr + #_ REGISTER_OUT r3 -123 + #_ REGISTER_OUT r4 123 + #_ REGISTER_OUT r5 -1 + +test_mulld_4_constant: + li r4, 123 + li r5, -1 + mulld r3, r4, r5 + blr + #_ REGISTER_OUT r3 -123 + #_ REGISTER_OUT r4 123 + #_ REGISTER_OUT r5 -1 + +test_mulld_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + mulld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulld_5_constant: + li r4, -1 + li r5, 1 + mulld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mulld_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 2 + mulld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 2 + +test_mulld_6_constant: + li r4, -1 + li r5, 2 + mulld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 2 + +test_mulld_7: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 -1 + mulld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 -1 + +test_mulld_7_constant: + li r4, 1 + li r5, -1 + mulld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 -1 + +test_mulld_8: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 -1 + mulld r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 -1 + +test_mulld_8_constant: + li r4, -1 + li r5, -1 + mulld r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 -1 diff --git a/tests/ppc/asm/instr_mulli.s b/tests/ppc/asm/instr_mulli.s new file mode 100644 index 0000000..2e8a9e4 --- /dev/null +++ b/tests/ppc/asm/instr_mulli.s @@ -0,0 +1,111 @@ +test_mulli_1: + #_ REGISTER_IN r4 1 + mulli r3, r4, 0 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + +test_mulli_1_constant: + li r4, 1 + mulli r3, r4, 0 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + +test_mulli_2: + #_ REGISTER_IN r4 1 + mulli r3, r4, 1 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + +test_mulli_2_constant: + li r4, 1 + mulli r3, r4, 1 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + +test_mulli_3: + #_ REGISTER_IN r4 1 + mulli r3, r4, -1 + blr + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 1 + +test_mulli_3_constant: + li r4, 1 + mulli r3, r4, -1 + blr + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 1 + +test_mulli_4: + #_ REGISTER_IN r4 123 + mulli r3, r4, -1 + blr + #_ REGISTER_OUT r3 -123 + #_ REGISTER_OUT r4 123 + +test_mulli_4_constant: + li r4, 123 + mulli r3, r4, -1 + blr + #_ REGISTER_OUT r3 -123 + #_ REGISTER_OUT r4 123 + +test_mulli_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + mulli r3, r4, 1 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + +test_mulli_5_constant: + li r4, -1 + mulli r3, r4, 1 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + +test_mulli_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + mulli r3, r4, 2 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + +test_mulli_6_constant: + li r4, -1 + mulli r3, r4, 2 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + +test_mulli_7: + #_ REGISTER_IN r4 1 + mulli r3, r4, -1 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 1 + +test_mulli_7_constant: + li r4, 1 + mulli r3, r4, -1 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 1 + +test_mulli_8: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + mulli r3, r4, -1 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + +test_mulli_8_constant: + li r4, -1 + mulli r3, r4, -1 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF diff --git a/tests/ppc/asm/instr_mullw.s b/tests/ppc/asm/instr_mullw.s new file mode 100644 index 0000000..7b4637b --- /dev/null +++ b/tests/ppc/asm/instr_mullw.s @@ -0,0 +1,209 @@ +test_mullw_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_mullw_1_constant: + li r4, 1 + li r5, 0 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_mullw_2: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 1 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 1 + +test_mullw_2_constant: + li r4, 1 + li r5, 1 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 1 + +test_mullw_3: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 -1 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 -1 + +test_mullw_3_constant: + li r4, 1 + li r5, -1 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 -1 + +test_mullw_4: + #_ REGISTER_IN r4 123 + #_ REGISTER_IN r5 -1 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 -123 + #_ REGISTER_OUT r4 123 + #_ REGISTER_OUT r5 -1 + +test_mullw_4_constant: + li r4, 123 + li r5, -1 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 -123 + #_ REGISTER_OUT r4 123 + #_ REGISTER_OUT r5 -1 + +test_mullw_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mullw_5_constant: + li r4, -1 + li r5, 1 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_mullw_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 2 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 2 + +test_mullw_6_constant: + li r4, -1 + li r5, 2 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 2 + +test_mullw_7: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 -1 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 -1 + +test_mullw_7_constant: + li r4, 1 + li r5, -1 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 -1 + +test_mullw_8: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 -1 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 -1 + +test_mullw_8_constant: + li r4, -1 + li r5, -1 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 -1 + +test_mullw_9: + #_ REGISTER_IN r4 0xFFFFFFFF00000000 + #_ REGISTER_IN r5 1 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFF00000000 + #_ REGISTER_OUT r5 1 + +test_mullw_9_constant: + li r4, -1 + sldi r4, r4, 32 + li r5, 1 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFF00000000 + #_ REGISTER_OUT r5 1 + +test_mullw_10: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0xFFFFFFFF00000000 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0xFFFFFFFF00000000 + +test_mullw_10_constant: + li r4, 1 + li r5, -1 + sldi r5, r5, 32 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0xFFFFFFFF00000000 + +test_mullw_11: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0x000000007FFFFFFF + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x000000007FFFFFFF + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0x000000007FFFFFFF + +test_mullw_11_constant: + li r4, 1 + li r5, -1 + clrldi r5, r5, 33 + mullw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x000000007FFFFFFF + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0x000000007FFFFFFF + +test_mullw_12: + #_ REGISTER_IN r0 0x1 + #_ REGISTER_IN r8 0x0123456789ABCDEF + mullw r0, r8, r8 + blr + #_ REGISTER_OUT r0 0x36B1B9D890F2A521 + #_ REGISTER_OUT r8 0x0123456789ABCDEF + blr diff --git a/tests/ppc/asm/instr_neg.s b/tests/ppc/asm/instr_neg.s new file mode 100644 index 0000000..c642605 --- /dev/null +++ b/tests/ppc/asm/instr_neg.s @@ -0,0 +1,37 @@ +test_neg_1: + #_ REGISTER_IN r3 0x0000000080000000 + neg r3, r3 + blr + #_ REGISTER_OUT r3 0xFFFFFFFF80000000 + +test_neg_1_constant: + li r3, 1 + sldi r3, r3, 31 + neg r3, r3 + blr + #_ REGISTER_OUT r3 0xFFFFFFFF80000000 + +test_neg_2: + #_ REGISTER_IN r3 0x8000000000000000 + neg r3, r3 + blr + #_ REGISTER_OUT r3 0x8000000000000000 + +test_neg_2_constant: + li r3, 1 + sldi r3, r3, 63 + neg r3, r3 + blr + #_ REGISTER_OUT r3 0x8000000000000000 + +test_neg_3: + #_ REGISTER_IN r3 0x0000000000000005 + neg r3, r3 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFB + +test_neg_3_constant: + li r3, 5 + neg r3, r3 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFB diff --git a/tests/ppc/asm/instr_nor.s b/tests/ppc/asm/instr_nor.s new file mode 100644 index 0000000..cf593f2 --- /dev/null +++ b/tests/ppc/asm/instr_nor.s @@ -0,0 +1,20 @@ +test_nor_cr_1: + #_ REGISTER_IN r3 0x00000000FFFFFFFF + nor. r3, r3, r3 + li r3, 0 + bne nor_cr_1_ne + li r3, 1 +nor_cr_1_ne: + blr + #_ REGISTER_OUT r3 1 + +test_nor_cr_1_constant: + li r3, -1 + clrldi r3, r3, 32 + nor. r3, r3, r3 + li r3, 0 + bne nor_cr_1_constant_ne + li r3, 1 +nor_cr_1_constant_ne: + blr + #_ REGISTER_OUT r3 1 diff --git a/tests/ppc/asm/instr_ori.s b/tests/ppc/asm/instr_ori.s new file mode 100644 index 0000000..9dc8430 --- /dev/null +++ b/tests/ppc/asm/instr_ori.s @@ -0,0 +1,42 @@ +.macro make_test_constant dest + lis \dest, 0xDEAD + ori \dest, \dest, 0xBEEF + sldi \dest, \dest, 32 +.endm + +test_ori_1: + #_ REGISTER_IN r4 0xDEADBEEF00000000 + + ori r3, r4, 0xFEDC + + blr + #_ REGISTER_OUT r3 0xDEADBEEF0000FEDC + #_ REGISTER_OUT r4 0xDEADBEEF00000000 + +test_ori_1_constant: + make_test_constant r4 + ori r3, r4, 0xFEDC + + blr + #_ REGISTER_OUT r3 0xDEADBEEF0000FEDC + #_ REGISTER_OUT r4 0xDEADBEEF00000000 + +test_ori_2: + #_ REGISTER_IN r4 0xDEADBEEF10000000 + + ori r3, r4, 0xFEDC + + blr + #_ REGISTER_OUT r3 0xDEADBEEF1000FEDC + #_ REGISTER_OUT r4 0xDEADBEEF10000000 + +test_ori_2_constant: + make_test_constant r4 + lis r3, 0x1000 + or r4, r4, r3 + + ori r3, r4, 0xFEDC + + blr + #_ REGISTER_OUT r3 0xDEADBEEF1000FEDC + #_ REGISTER_OUT r4 0xDEADBEEF10000000 diff --git a/tests/ppc/asm/instr_rldicl.s b/tests/ppc/asm/instr_rldicl.s new file mode 100644 index 0000000..321d4eb --- /dev/null +++ b/tests/ppc/asm/instr_rldicl.s @@ -0,0 +1,221 @@ +.macro make_full_test_constant dest, a, b, c, d + lis \dest, \a + ori \dest, \dest, \b + sldi \dest, \dest, 32 + lis r3, \c + ori r3, r3, \d + clrldi r3, r3, 32 + or \dest, \dest, r3 +.endm + +test_rldicl_1: + #_ REGISTER_IN r4 0x0123456789ABCDEF + rldicl r3, r4, 24, 0 + blr + #_ REGISTER_OUT r3 0x6789abcdef012345 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicl_1_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + rldicl r3, r4, 24, 0 + blr + #_ REGISTER_OUT r3 0x6789abcdef012345 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicl_2: + #_ REGISTER_IN r4 0x0123456789ABCDEF + rldicl r3, r4, 24, 8 + blr + #_ REGISTER_OUT r3 0x0089abcdef012345 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicl_2_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + rldicl r3, r4, 24, 8 + blr + #_ REGISTER_OUT r3 0x0089abcdef012345 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicl_3: + #_ REGISTER_IN r4 0x0123456789ABCDEF + rldicl r3, r4, 24, 63 + blr + #_ REGISTER_OUT r3 0x0000000000000001 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicl_3_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + rldicl r3, r4, 24, 63 + blr + #_ REGISTER_OUT r3 0x0000000000000001 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicl_4: + #_ REGISTER_IN r4 0x0123456789ABCDEF + rldicl r3, r4, 0, 0 + blr + #_ REGISTER_OUT r3 0x0123456789abcdef + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicl_4_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + rldicl r3, r4, 0, 0 + blr + #_ REGISTER_OUT r3 0x0123456789abcdef + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicl_5: + #_ REGISTER_IN r4 0x0123456789ABCDEF + rldicl r3, r4, 0, 63 + blr + #_ REGISTER_OUT r3 0x0000000000000001 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicl_5_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + rldicl r3, r4, 0, 63 + blr + #_ REGISTER_OUT r3 0x0000000000000001 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicl_6: + #_ REGISTER_IN r4 0x0123456789ABCDEF + rldicl r3, r4, 0, 8 + blr + #_ REGISTER_OUT r3 0x0023456789abcdef + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicl_6_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + rldicl r3, r4, 0, 8 + blr + #_ REGISTER_OUT r3 0x0023456789abcdef + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicl_7: + #_ REGISTER_IN r4 0x0123456789ABCDEF + rldicl r3, r4, 63, 0 + blr + #_ REGISTER_OUT r3 0x8091a2b3c4d5e6f7 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicl_7_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + rldicl r3, r4, 63, 0 + blr + #_ REGISTER_OUT r3 0x8091a2b3c4d5e6f7 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicl_8: + #_ REGISTER_IN r4 0x0123456789ABCDEF + rldicl r3, r4, 63, 63 + blr + #_ REGISTER_OUT r3 0x0000000000000001 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicl_8_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + rldicl r3, r4, 63, 63 + blr + #_ REGISTER_OUT r3 0x0000000000000001 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicl_9: + #_ REGISTER_IN r4 0x0123456789ABCDEF + rldicl r3, r4, 31, 0 + blr + #_ REGISTER_OUT r3 0xc4d5e6f78091a2b3 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicl_9_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + rldicl r3, r4, 31, 0 + blr + #_ REGISTER_OUT r3 0xc4d5e6f78091a2b3 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicl_10: + #_ REGISTER_IN r4 0x16300000 + rldicl r3, r4, 58, 6 + blr + #_ REGISTER_OUT r3 0x58C000 + #_ REGISTER_OUT r4 0x16300000 + +test_rldicl_10_constant: + lis r4, 0x1630 + rldicl r3, r4, 58, 6 + blr + #_ REGISTER_OUT r3 0x58C000 + #_ REGISTER_OUT r4 0x16300000 + +test_srdi_1: + #_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r4 0x0123456789ABCDEF + srdi r3, r3, 0 + srdi r4, r4, 0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_srdi_1_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + li r3, -1 + srdi r3, r3, 0 + srdi r4, r4, 0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_srdi_2: + #_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r4 0x0123456789ABCDEF + srdi r3, r3, 1 + srdi r4, r4, 1 + blr + #_ REGISTER_OUT r3 0x7fffffffffffffff + #_ REGISTER_OUT r4 0x0091a2b3c4d5e6f7 + +test_srdi_2_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + li r3, -1 + srdi r3, r3, 1 + srdi r4, r4, 1 + blr + #_ REGISTER_OUT r3 0x7fffffffffffffff + #_ REGISTER_OUT r4 0x0091a2b3c4d5e6f7 + +test_srdi_3: + #_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r4 0x0123456789ABCDEF + srdi r3, r3, 32 + srdi r4, r4, 32 + blr + #_ REGISTER_OUT r3 0x00000000ffffffff + #_ REGISTER_OUT r4 0x0000000001234567 + +test_srdi_3_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + li r3, -1 + srdi r3, r3, 32 + srdi r4, r4, 32 + blr + #_ REGISTER_OUT r3 0x00000000ffffffff + #_ REGISTER_OUT r4 0x0000000001234567 + +test_srdi_4: + #_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r4 0x0123456789ABCDEF + srdi r3, r3, 63 + srdi r4, r4, 63 + blr + #_ REGISTER_OUT r3 0x0000000000000001 + #_ REGISTER_OUT r4 0x0000000000000000 + +test_srdi_4_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + li r3, -1 + srdi r3, r3, 63 + srdi r4, r4, 63 + blr + #_ REGISTER_OUT r3 0x0000000000000001 + #_ REGISTER_OUT r4 0x0000000000000000 diff --git a/tests/ppc/asm/instr_rldicr.s b/tests/ppc/asm/instr_rldicr.s new file mode 100644 index 0000000..ab68ba1 --- /dev/null +++ b/tests/ppc/asm/instr_rldicr.s @@ -0,0 +1,207 @@ +.macro make_full_test_constant dest, a, b, c, d + lis \dest, \a + ori \dest, \dest, \b + sldi \dest, \dest, 32 + lis r3, \c + ori r3, r3, \d + clrldi r3, r3, 32 + or \dest, \dest, r3 +.endm + +test_rldicr_1: + #_ REGISTER_IN r4 0x0123456789ABCDEF + rldicr r3, r4, 24, 0 + blr + #_ REGISTER_OUT r3 0x0000000000000000 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicr_1_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + rldicr r3, r4, 24, 0 + blr + #_ REGISTER_OUT r3 0x0000000000000000 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicr_2: + #_ REGISTER_IN r4 0x0123456789ABCDEF + rldicr r3, r4, 24, 8 + blr + #_ REGISTER_OUT r3 0x6780000000000000 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicr_2_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + rldicr r3, r4, 24, 8 + blr + #_ REGISTER_OUT r3 0x6780000000000000 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicr_3: + #_ REGISTER_IN r4 0x0123456789ABCDEF + rldicr r3, r4, 24, 63 + blr + #_ REGISTER_OUT r3 0x6789abcdef012345 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicr_3_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + rldicr r3, r4, 24, 63 + blr + #_ REGISTER_OUT r3 0x6789abcdef012345 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicr_4: + #_ REGISTER_IN r4 0x0123456789ABCDEF + rldicr r3, r4, 0, 0 + blr + #_ REGISTER_OUT r3 0x0000000000000000 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicr_4_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + rldicr r3, r4, 0, 0 + blr + #_ REGISTER_OUT r3 0x0000000000000000 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicr_5: + #_ REGISTER_IN r4 0x0123456789ABCDEF + rldicr r3, r4, 0, 63 + blr + #_ REGISTER_OUT r3 0x0123456789abcdef + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicr_5_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + rldicr r3, r4, 0, 63 + blr + #_ REGISTER_OUT r3 0x0123456789abcdef + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicr_6: + #_ REGISTER_IN r4 0x0123456789ABCDEF + rldicr r3, r4, 0, 8 + blr + #_ REGISTER_OUT r3 0x0100000000000000 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicr_6_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + rldicr r3, r4, 0, 8 + blr + #_ REGISTER_OUT r3 0x0100000000000000 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicr_7: + #_ REGISTER_IN r4 0x0123456789ABCDEF + rldicr r3, r4, 63, 0 + blr + #_ REGISTER_OUT r3 0x8000000000000000 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicr_7_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + rldicr r3, r4, 63, 0 + blr + #_ REGISTER_OUT r3 0x8000000000000000 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicr_8: + #_ REGISTER_IN r4 0x0123456789ABCDEF + rldicr r3, r4, 63, 63 + blr + #_ REGISTER_OUT r3 0x8091a2b3c4d5e6f7 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicr_8_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + rldicr r3, r4, 63, 63 + blr + #_ REGISTER_OUT r3 0x8091a2b3c4d5e6f7 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicr_9: + #_ REGISTER_IN r4 0x0123456789ABCDEF + rldicr r3, r4, 31, 0 + blr + #_ REGISTER_OUT r3 0x8000000000000000 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_rldicr_9_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + rldicr r3, r4, 31, 0 + blr + #_ REGISTER_OUT r3 0x8000000000000000 + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_sldi_1: + #_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r4 0x0123456789ABCDEF + sldi r3, r3, 0 + sldi r4, r4, 0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_sldi_1_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + li r3, -1 + sldi r3, r3, 0 + sldi r4, r4, 0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_sldi_2: + #_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r4 0x0123456789ABCDEF + sldi r3, r3, 1 + sldi r4, r4, 1 + blr + #_ REGISTER_OUT r3 0xfffffffffffffffe + #_ REGISTER_OUT r4 0x02468acf13579bde + +test_sldi_2_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + li r3, -1 + sldi r3, r3, 1 + sldi r4, r4, 1 + blr + #_ REGISTER_OUT r3 0xfffffffffffffffe + #_ REGISTER_OUT r4 0x02468acf13579bde + +test_sldi_3: + #_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r4 0x0123456789ABCDEF + sldi r3, r3, 32 + sldi r4, r4, 32 + blr + #_ REGISTER_OUT r3 0xffffffff00000000 + #_ REGISTER_OUT r4 0x89abcdef00000000 + +test_sldi_3_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + li r3, -1 + sldi r3, r3, 32 + sldi r4, r4, 32 + blr + #_ REGISTER_OUT r3 0xffffffff00000000 + #_ REGISTER_OUT r4 0x89abcdef00000000 + +test_sldi_4: + #_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r4 0x0123456789ABCDEF + sldi r3, r3, 63 + sldi r4, r4, 63 + blr + #_ REGISTER_OUT r3 0x8000000000000000 + #_ REGISTER_OUT r4 0x8000000000000000 + +test_sldi_4_constant: + make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF + li r3, -1 + sldi r3, r3, 63 + sldi r4, r4, 63 + blr + #_ REGISTER_OUT r3 0x8000000000000000 + #_ REGISTER_OUT r4 0x8000000000000000 diff --git a/tests/ppc/asm/instr_rlwimi.s b/tests/ppc/asm/instr_rlwimi.s new file mode 100644 index 0000000..c1e4136 --- /dev/null +++ b/tests/ppc/asm/instr_rlwimi.s @@ -0,0 +1,25 @@ +.macro make_full_test_constant dest, a, b, c, d + lis \dest, \a + ori \dest, \dest, \b + sldi \dest, \dest, 32 + lis r3, \c + ori r3, r3, \d + clrldi r3, r3, 32 + or \dest, \dest, r3 +.endm + +test_rlwimi: + #_ REGISTER_IN r4 0xCAFEBABE90003000 + #_ REGISTER_IN r6 0xDEADBEEF00000003 + rlwimi r6, r4, 2, 0, 0x1D + blr + #_ REGISTER_OUT r4 0xCAFEBABE90003000 + #_ REGISTER_OUT r6 0xDEADBEEF4000C003 + +test_rlwimi_constant: + make_full_test_constant r4, 0xCAFE, 0xBABE, 0x9000, 0x3000 + make_full_test_constant r6, 0xDEAD, 0xBEEF, 0x0000, 0x0003 + rlwimi r6, r4, 2, 0, 0x1D + blr + #_ REGISTER_OUT r4 0xCAFEBABE90003000 + #_ REGISTER_OUT r6 0xDEADBEEF4000C003 diff --git a/tests/ppc/asm/instr_rlwinm.s b/tests/ppc/asm/instr_rlwinm.s new file mode 100644 index 0000000..b1376b1 --- /dev/null +++ b/tests/ppc/asm/instr_rlwinm.s @@ -0,0 +1,263 @@ +test_rlwinm_1: + #_ REGISTER_IN r4 0x12345678 + rlwinm r3, r4, 24, 8, 15 + blr + #_ REGISTER_OUT r3 0x00120000 + #_ REGISTER_OUT r4 0x12345678 + +test_rlwinm_1_constant: + lis r4, 0x1234 + ori r4, r4, 0x5678 + rlwinm r3, r4, 24, 8, 15 + blr + #_ REGISTER_OUT r3 0x00120000 + #_ REGISTER_OUT r4 0x12345678 + +test_rlwinm_2: + #_ REGISTER_IN r4 0x12345678 + rlwinm r3, r4, 4, 0, 27 + blr + #_ REGISTER_OUT r3 0x23456780 + #_ REGISTER_OUT r4 0x12345678 + +test_rlwinm_2_constant: + lis r4, 0x1234 + ori r4, r4, 0x5678 + rlwinm r3, r4, 4, 0, 27 + blr + #_ REGISTER_OUT r3 0x23456780 + #_ REGISTER_OUT r4 0x12345678 + +test_rlwinm_3: + #_ REGISTER_IN r4 0x90003000 + rlwinm r3, r4, 2, 0, 0x1D + blr + #_ REGISTER_OUT r3 0x4000C000 + #_ REGISTER_OUT r4 0x90003000 + +test_rlwinm_3_constant: + lis r4, 0x9000 + ori r4, r4, 0x3000 + clrldi r4, r4, 32 + rlwinm r3, r4, 2, 0, 0x1D + blr + #_ REGISTER_OUT r3 0x4000C000 + #_ REGISTER_OUT r4 0x90003000 + +test_rlwinm_4: + #_ REGISTER_IN r4 0xB0043000 + rlwinm. r3, r4, 2, 0, 0x1D + blr + #_ REGISTER_OUT r3 0xC010C000 + #_ REGISTER_OUT r4 0xB0043000 + # CRF = 0x8 + +test_rlwinm_4_constant: + lis r4, 0xB004 + ori r4, r4, 0x3000 + clrldi r4, r4, 32 + rlwinm. r3, r4, 2, 0, 0x1D + blr + #_ REGISTER_OUT r3 0xC010C000 + #_ REGISTER_OUT r4 0xB0043000 + # CRF = 0x8 + +test_rlwinm_5: + #_ REGISTER_IN r4 0x12345678 + rlwinm r3, r4, 0, 5, 0x1D + blr + #_ REGISTER_OUT r3 0x02345678 + #_ REGISTER_OUT r4 0x12345678 + +test_rlwinm_5_constant: + lis r4, 0x1234 + ori r4, r4, 0x5678 + rlwinm r3, r4, 0, 5, 0x1D + blr + #_ REGISTER_OUT r3 0x02345678 + #_ REGISTER_OUT r4 0x12345678 + +test_rlwinm_6: + #_ REGISTER_IN r4 0x12345678 + rlwinm r3, r4, 0, 0, 31 + blr + #_ REGISTER_OUT r3 0x12345678 + #_ REGISTER_OUT r4 0x12345678 + +test_rlwinm_6_constant: + lis r4, 0x1234 + ori r4, r4, 0x5678 + rlwinm r3, r4, 0, 0, 31 + blr + #_ REGISTER_OUT r3 0x12345678 + #_ REGISTER_OUT r4 0x12345678 + +test_rlwinm_7: + #_ REGISTER_IN r4 0x12345678 + rlwinm r3, r4, 0, 0, 16 + blr + #_ REGISTER_OUT r3 0x12340000 + #_ REGISTER_OUT r4 0x12345678 + +test_rlwinm_7_constant: + lis r4, 0x1234 + ori r4, r4, 0x5678 + rlwinm r3, r4, 0, 0, 16 + blr + #_ REGISTER_OUT r3 0x12340000 + #_ REGISTER_OUT r4 0x12345678 + +test_rlwinm_8: + #_ REGISTER_IN r4 0x12345678 + rlwinm r3, r4, 0, 16, 31 + blr + #_ REGISTER_OUT r3 0x00005678 + #_ REGISTER_OUT r4 0x12345678 + +test_rlwinm_8_constant: + lis r4, 0x1234 + ori r4, r4, 0x5678 + rlwinm r3, r4, 0, 16, 31 + blr + #_ REGISTER_OUT r3 0x00005678 + #_ REGISTER_OUT r4 0x12345678 + +test_rlwinm_9: + #_ REGISTER_IN r4 0x12345678 + rlwinm r3, r4, 16, 16, 31 + blr + #_ REGISTER_OUT r3 0x00001234 + #_ REGISTER_OUT r4 0x12345678 + +test_rlwinm_9_constant: + lis r4, 0x1234 + ori r4, r4, 0x5678 + rlwinm r3, r4, 16, 16, 31 + blr + #_ REGISTER_OUT r3 0x00001234 + #_ REGISTER_OUT r4 0x12345678 + +# Extract and right justify immediate +# extrwi RA, RS, n, b +# rlwinm RA, RS, b+n, 32-n, 31 +test_extrwi_1: + # extrwi ra,rs,n,b (n > 0) == rlwinm ra,rs,b+n,32-n,31 + #_ REGISTER_IN r5 0x30 + rlwinm r7, r5, 29, 28, 31 + #extrwi r7, r5, 4, 25 + blr + #_ REGISTER_OUT r5 0x30 + #_ REGISTER_OUT r7 0x06 + +test_extrwi_1_constant: + # extrwi ra,rs,n,b (n > 0) == rlwinm ra,rs,b+n,32-n,31 + li r5, 0x30 + rlwinm r7, r5, 29, 28, 31 + #extrwi r7, r5, 4, 25 + blr + #_ REGISTER_OUT r5 0x30 + #_ REGISTER_OUT r7 0x06 + +test_extrwi_2: + #_ REGISTER_IN r5 0xFFFFFFFF01234567 + rlwinm r7, r5, 26, 16, 31 + #extrwi r7, r5, 16, 10 + blr + #_ REGISTER_OUT r5 0xFFFFFFFF01234567 + #_ REGISTER_OUT r7 0x0000000000008D15 + +test_extrwi_2_constant: + li r5, -1 + sldi r5, r5, 32 + oris r5, r5, 0x0123 + ori r5, r5, 0x4567 + rlwinm r7, r5, 26, 16, 31 + #extrwi r7, r5, 16, 10 + blr + #_ REGISTER_OUT r5 0xFFFFFFFF01234567 + #_ REGISTER_OUT r7 0x0000000000008D15 + +test_extrwi_cr_1: + #_ REGISTER_IN r5 0x30 + rlwinm. r7, r5, 29, 28, 31 + #extrwi. r7, r5, 4, 25 + mfcr r12 + blr + #_ REGISTER_OUT r5 0x30 + #_ REGISTER_OUT r7 0x06 + #_ REGISTER_OUT r12 0x40000000 + +test_extrwi_cr_1_constant: + li r5, 0x30 + rlwinm. r7, r5, 29, 28, 31 + #extrwi. r7, r5, 4, 25 + mfcr r12 + blr + #_ REGISTER_OUT r5 0x30 + #_ REGISTER_OUT r7 0x06 + #_ REGISTER_OUT r12 0x40000000 + +test_extrwi_cr_2: + #_ REGISTER_IN r5 0xFFFFFFFF01234567 + rlwinm. r7, r5, 26, 16, 31 + #extrwi. r7, r5, 16, 10 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFF01234567 + #_ REGISTER_OUT r7 0x0000000000008D15 + #_ REGISTER_OUT r12 0x40000000 + +test_extrwi_cr_2_constant: + li r5, -1 + sldi r5, r5, 32 + oris r5, r5, 0x0123 + ori r5, r5, 0x4567 + rlwinm. r7, r5, 26, 16, 31 + #extrwi. r7, r5, 16, 10 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFF01234567 + #_ REGISTER_OUT r7 0x0000000000008D15 + #_ REGISTER_OUT r12 0x40000000 + +test_extrwi_cr_3: + #_ REGISTER_IN r5 0xFFFFFFFF00000000 + rlwinm. r7, r5, 26, 16, 31 + #extrwi. r7, r5, 16, 10 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFF00000000 + #_ REGISTER_OUT r7 0x0000000000000000 + #_ REGISTER_OUT r12 0x20000000 + +test_extrwi_cr_3_constant: + li r5, -1 + sldi r5, r5, 32 + rlwinm. r7, r5, 26, 16, 31 + #extrwi. r7, r5, 16, 10 + mfcr r12 + blr + #_ REGISTER_OUT r5 0xFFFFFFFF00000000 + #_ REGISTER_OUT r7 0x0000000000000000 + #_ REGISTER_OUT r12 0x20000000 + +test_rlwinm_10: + #_ REGISTER_IN r7 0x01234567 + rlwinm r6, r7, 31, 31, 1 + blr + #_ REGISTER_OUT r6 0x8091A2B380000001 + #_ REGISTER_OUT r7 0x01234567 + +test_rlwinm_11: + #_ REGISTER_IN r8 0x0123456789ABCDEF + rlwinm r6, r8, 8, 2, 0 + blr + #_ REGISTER_OUT r6 0xABCDEF89ABCDEF89 + #_ REGISTER_OUT r8 0x0123456789ABCDEF + +test_rlwinm_12: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + rlwinm r7, r4, 31, 30, 1 + blr + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r7 0xFFFFFFFFC0000003 diff --git a/tests/ppc/asm/instr_rlwnm.s b/tests/ppc/asm/instr_rlwnm.s new file mode 100644 index 0000000..f41c78d --- /dev/null +++ b/tests/ppc/asm/instr_rlwnm.s @@ -0,0 +1,215 @@ +test_rlwnm_1: + #_ REGISTER_IN r4 0x12345678 + #_ REGISTER_IN r5 24 + rlwnm r3, r4, r5, 8, 15 + blr + #_ REGISTER_OUT r3 0x00120000 + #_ REGISTER_OUT r4 0x12345678 + #_ REGISTER_OUT r5 24 + +test_rlwnm_1_constant: + lis r4, 0x1234 + ori r4, r4, 0x5678 + li r5, 24 + rlwnm r3, r4, r5, 8, 15 + blr + #_ REGISTER_OUT r3 0x00120000 + #_ REGISTER_OUT r4 0x12345678 + #_ REGISTER_OUT r5 24 + +test_rlwnm_2: + #_ REGISTER_IN r4 0x12345678 + #_ REGISTER_IN r5 4 + rlwnm r3, r4, r5, 0, 27 + blr + #_ REGISTER_OUT r3 0x23456780 + #_ REGISTER_OUT r4 0x12345678 + #_ REGISTER_OUT r5 4 + +test_rlwnm_2_constant: + lis r4, 0x1234 + ori r4, r4, 0x5678 + li r5, 4 + rlwnm r3, r4, r5, 0, 27 + blr + #_ REGISTER_OUT r3 0x23456780 + #_ REGISTER_OUT r4 0x12345678 + #_ REGISTER_OUT r5 4 + +test_rlwnm_3: + #_ REGISTER_IN r4 0x90003000 + #_ REGISTER_IN r5 2 + rlwnm r3, r4, r5, 0, 0x1D + blr + #_ REGISTER_OUT r3 0x4000C000 + #_ REGISTER_OUT r4 0x90003000 + #_ REGISTER_OUT r5 2 + +test_rlwnm_3_constant: + lis r4, 0x9000 + ori r4, r4, 0x3000 + clrldi r4, r4, 32 + li r5, 2 + rlwnm r3, r4, r5, 0, 0x1D + blr + #_ REGISTER_OUT r3 0x4000C000 + #_ REGISTER_OUT r4 0x90003000 + #_ REGISTER_OUT r5 2 + +test_rlwnm_4: + #_ REGISTER_IN r4 0xB0043000 + #_ REGISTER_IN r5 2 + rlwnm. r3, r4, r5, 0, 0x1D + blr + #_ REGISTER_OUT r3 0xC010C000 + #_ REGISTER_OUT r4 0xB0043000 + #_ REGISTER_OUT r5 2 + # CRF = 0x8 + +test_rlwnm_4_constant: + lis r4, 0xB004 + ori r4, r4, 0x3000 + clrldi r4, r4, 32 + li r5, 2 + rlwnm. r3, r4, r5, 0, 0x1D + blr + #_ REGISTER_OUT r3 0xC010C000 + #_ REGISTER_OUT r4 0xB0043000 + #_ REGISTER_OUT r5 2 + # CRF = 0x8 + +test_rlwnm_5: + #_ REGISTER_IN r4 0x12345678 + #_ REGISTER_IN r5 0 + rlwnm r3, r4, r5, 5, 0x1D + blr + #_ REGISTER_OUT r3 0x02345678 + #_ REGISTER_OUT r4 0x12345678 + #_ REGISTER_OUT r5 0 + +test_rlwnm_5_constant: + lis r4, 0x1234 + ori r4, r4, 0x5678 + li r5, 0 + rlwnm r3, r4, r5, 5, 0x1D + blr + #_ REGISTER_OUT r3 0x02345678 + #_ REGISTER_OUT r4 0x12345678 + #_ REGISTER_OUT r5 0 + +test_rlwnm_6: + #_ REGISTER_IN r4 0x12345678 + #_ REGISTER_IN r5 0 + rlwnm r3, r4, r5, 0, 31 + blr + #_ REGISTER_OUT r3 0x12345678 + #_ REGISTER_OUT r4 0x12345678 + #_ REGISTER_OUT r5 0 + +test_rlwnm_6_constant: + lis r4, 0x1234 + ori r4, r4, 0x5678 + li r5, 0 + rlwnm r3, r4, r5, 0, 31 + blr + #_ REGISTER_OUT r3 0x12345678 + #_ REGISTER_OUT r4 0x12345678 + #_ REGISTER_OUT r5 0 + +test_rlwnm_7: + #_ REGISTER_IN r4 0x12345678 + #_ REGISTER_IN r5 0 + rlwnm r3, r4, r5, 0, 16 + blr + #_ REGISTER_OUT r3 0x12340000 + #_ REGISTER_OUT r4 0x12345678 + #_ REGISTER_OUT r5 0 + +test_rlwnm_7_constant: + lis r4, 0x1234 + ori r4, r4, 0x5678 + li r5, 0 + rlwnm r3, r4, r5, 0, 16 + blr + #_ REGISTER_OUT r3 0x12340000 + #_ REGISTER_OUT r4 0x12345678 + #_ REGISTER_OUT r5 0 + +test_rlwnm_8: + #_ REGISTER_IN r4 0x12345678 + #_ REGISTER_IN r5 0 + rlwnm r3, r4, r5, 16, 31 + blr + #_ REGISTER_OUT r3 0x00005678 + #_ REGISTER_OUT r4 0x12345678 + #_ REGISTER_OUT r5 0 + +test_rlwnm_8_constant: + lis r4, 0x1234 + ori r4, r4, 0x5678 + li r5, 0 + rlwnm r3, r4, r5, 16, 31 + blr + #_ REGISTER_OUT r3 0x00005678 + #_ REGISTER_OUT r4 0x12345678 + #_ REGISTER_OUT r5 0 + +test_rlwnm_9: + #_ REGISTER_IN r4 0x12345678 + #_ REGISTER_IN r5 16 + rlwnm r3, r4, r5, 16, 31 + blr + #_ REGISTER_OUT r3 0x00001234 + #_ REGISTER_OUT r4 0x12345678 + #_ REGISTER_OUT r5 16 + +test_rlwnm_9_constant: + lis r4, 0x1234 + ori r4, r4, 0x5678 + li r5, 16 + rlwnm r3, r4, r5, 16, 31 + blr + #_ REGISTER_OUT r3 0x00001234 + #_ REGISTER_OUT r4 0x12345678 + #_ REGISTER_OUT r5 16 + +test_rlwnm_10: + #_ REGISTER_IN r4 0x12345678 + #_ REGISTER_IN r5 32 + rlwnm r3, r4, r5, 0, 31 + blr + #_ REGISTER_OUT r3 0x12345678 + #_ REGISTER_OUT r4 0x12345678 + #_ REGISTER_OUT r5 32 + +test_rlwnm_10_constant: + lis r4, 0x1234 + ori r4, r4, 0x5678 + li r5, 32 + rlwnm r3, r4, r5, 0, 31 + blr + #_ REGISTER_OUT r3 0x12345678 + #_ REGISTER_OUT r4 0x12345678 + #_ REGISTER_OUT r5 32 + +test_rlwnm_11: + #_ REGISTER_IN r0 0x1 + rlwnm r0, r0, r0, 1, 0 + blr + #_ REGISTER_OUT r0 0x0000000200000002 + +test_rlwnm_12: + #_ REGISTER_IN r3 0xFFFFFFFF + rlwnm r0, r3, r3, 30, 1 + blr + #_ REGISTER_OUT r0 0xFFFFFFFFC0000003 + #_ REGISTER_OUT r3 0xFFFFFFFF + +test_rlwnm_13: + #_ REGISTER_IN r7 0x01234567 + #_ REGISTER_IN r8 0x0123456789ABCDEFull + rlwnm r6, r8, r7, 31, 30 + blr + #_ REGISTER_OUT r6 0xD5E6F7C4D5E6F7C4 + #_ REGISTER_OUT r7 0x01234567 + #_ REGISTER_OUT r8 0x0123456789ABCDEFull diff --git a/tests/ppc/asm/instr_sld.s b/tests/ppc/asm/instr_sld.s new file mode 100644 index 0000000..0ed67d1 --- /dev/null +++ b/tests/ppc/asm/instr_sld.s @@ -0,0 +1,125 @@ +test_sld_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0 + sld r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_sld_1_constant: + li r4, 1 + li r5, 0 + sld r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_sld_2: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0 + sld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + +test_sld_2_constant: + li r4, -1 + li r5, 0 + sld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + +test_sld_3: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + sld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_sld_3_constant: + li r4, -1 + li r5, 1 + sld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_sld_4: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 62 + sld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xc000000000000000 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 62 + +test_sld_4_constant: + li r4, -1 + li r5, 62 + sld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xc000000000000000 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 62 + +test_sld_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 63 + sld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x8000000000000000 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 63 + +test_sld_5_constant: + li r4, -1 + li r5, 63 + sld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x8000000000000000 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 63 + +test_sld_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 64 + sld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 64 + +test_sld_6_constant: + li r4, -1 + li r5, 64 + sld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 64 + +test_sld_7: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 100 + sld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 100 + +test_sld_7_constant: + li r4, -1 + li r5, 100 + sld r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 100 diff --git a/tests/ppc/asm/instr_slw.s b/tests/ppc/asm/instr_slw.s new file mode 100644 index 0000000..e654876 --- /dev/null +++ b/tests/ppc/asm/instr_slw.s @@ -0,0 +1,202 @@ +test_slw_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_slw_1_constant: + li r4, 1 + li r5, 0 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_slw_2: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000FFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + +test_slw_2_constant: + li r4, -1 + li r5, 0 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000FFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + +test_slw_3: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000FFFFFFFE + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_slw_3_constant: + li r4, -1 + li r5, 1 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000FFFFFFFE + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_slw_4: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 63 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 63 + +test_slw_4_constant: + li r4, -1 + li r5, 63 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 63 + +test_slw_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 64 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000FFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 64 + +test_slw_5_constant: + li r4, -1 + li r5, 64 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000FFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 64 + +test_slw_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 100 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 100 + +test_slw_6_constant: + li r4, -1 + li r5, 100 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 100 + +test_slw_7: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 30 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000c0000000 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 30 + +test_slw_7_constant: + li r4, -1 + li r5, 30 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000c0000000 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 30 + +test_slw_8: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 31 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x0000000080000000 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 31 + +test_slw_8_constant: + li r4, -1 + li r5, 31 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x0000000080000000 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 31 + +test_slw_9: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 32 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 32 + +test_slw_9_constant: + li r4, -1 + li r5, 32 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 32 + +test_slw_10: + #_ REGISTER_IN r4 99 + #_ REGISTER_IN r5 1 + cntlzw r5, r5 + subi r5, r5, 28 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 792 + #_ REGISTER_OUT r4 99 + #_ REGISTER_OUT r5 3 + +test_slw_10_constant: + #_ REGISTER_IN r4 99 + li r5, 1 + cntlzw r5, r5 + subi r5, r5, 28 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 792 + #_ REGISTER_OUT r4 99 + #_ REGISTER_OUT r5 3 + +test_slw_11: + #_ REGISTER_IN r4 99 + #_ REGISTER_IN r5 3 + li r5, 3 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 792 + #_ REGISTER_OUT r4 99 + #_ REGISTER_OUT r5 3 + +test_slw_11_constant: + #_ REGISTER_IN r4 99 + li r5, 3 + slw r3, r4, r5 + blr + #_ REGISTER_OUT r3 792 + #_ REGISTER_OUT r4 99 + #_ REGISTER_OUT r5 3 diff --git a/tests/ppc/asm/instr_srad.s b/tests/ppc/asm/instr_srad.s new file mode 100644 index 0000000..9afff4a --- /dev/null +++ b/tests/ppc/asm/instr_srad.s @@ -0,0 +1,153 @@ +test_srad_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0 + srad r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 0 + +test_srad_1_constant: + li r4, 1 + li r5, 0 + srad r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 0 + +test_srad_2: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0 + srad r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 0 + +test_srad_2_constant: + li r4, -1 + li r5, 0 + srad r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 0 + +test_srad_3: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + srad r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 1 + +test_srad_3_constant: + li r4, -1 + li r5, 1 + srad r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 1 + +test_srad_4: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 62 + srad r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 62 + #_ REGISTER_OUT r6 1 + +test_srad_4_constant: + li r4, -1 + li r5, 62 + srad r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 62 + #_ REGISTER_OUT r6 1 + +test_srad_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 63 + srad r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 63 + #_ REGISTER_OUT r6 1 + +test_srad_5_constant: + li r4, -1 + li r5, 63 + srad r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 63 + #_ REGISTER_OUT r6 1 + +test_srad_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 64 + srad r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 64 + #_ REGISTER_OUT r6 1 + +test_srad_6_constant: + li r4, -1 + li r5, 64 + srad r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 64 + #_ REGISTER_OUT r6 1 + +test_srad_7: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 100 + srad r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 100 + #_ REGISTER_OUT r6 1 + +test_srad_7_constant: + li r4, -1 + li r5, 100 + srad r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 100 + #_ REGISTER_OUT r6 1 diff --git a/tests/ppc/asm/instr_sradi.s b/tests/ppc/asm/instr_sradi.s new file mode 100644 index 0000000..20a7dd9 --- /dev/null +++ b/tests/ppc/asm/instr_sradi.s @@ -0,0 +1,89 @@ +test_sradi_1: + #_ REGISTER_IN r4 1 + sradi r3, r4, 0 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 0 + +test_sradi_1_constant: + li r4, 1 + sradi r3, r4, 0 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 0 + +test_sradi_2: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + sradi r3, r4, 0 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 0 + +test_sradi_2_constant: + li r4, -1 + sradi r3, r4, 0 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 0 + +test_sradi_3: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + sradi r3, r4, 1 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_sradi_3_constant: + li r4, -1 + sradi r3, r4, 1 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_sradi_4: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + sradi r3, r4, 62 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_sradi_4_constant: + li r4, -1 + sradi r3, r4, 62 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_sradi_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + sradi r3, r4, 63 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_sradi_5_constant: + li r4, -1 + sradi r3, r4, 63 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 diff --git a/tests/ppc/asm/instr_sraw.s b/tests/ppc/asm/instr_sraw.s new file mode 100644 index 0000000..8b9b803 --- /dev/null +++ b/tests/ppc/asm/instr_sraw.s @@ -0,0 +1,197 @@ +test_sraw_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0 + sraw r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 0 + +test_sraw_1_constant: + li r4, 1 + li r5, 0 + sraw r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 0 + +test_sraw_2: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0 + sraw r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 0 + +test_sraw_2_constant: + li r4, -1 + li r5, 0 + sraw r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + #_ REGISTER_OUT r6 0 + +test_sraw_3: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + sraw r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 1 + +test_sraw_3_constant: + li r4, -1 + li r5, 1 + sraw r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + #_ REGISTER_OUT r6 1 + +test_sraw_4: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 63 + sraw r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 63 + #_ REGISTER_OUT r6 1 + +test_sraw_4_constant: + li r4, -1 + li r5, 63 + sraw r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 63 + #_ REGISTER_OUT r6 1 + +test_sraw_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 64 + sraw r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 64 + #_ REGISTER_OUT r6 0 + +test_sraw_5_constant: + li r4, -1 + li r5, 64 + sraw r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 64 + #_ REGISTER_OUT r6 0 + +test_sraw_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 100 + sraw r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 100 + #_ REGISTER_OUT r6 1 + +test_sraw_6_constant: + li r4, -1 + li r5, 100 + sraw r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 100 + #_ REGISTER_OUT r6 1 + +test_sraw_7: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 30 + sraw r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 30 + #_ REGISTER_OUT r6 1 + +test_sraw_7_constant: + li r4, -1 + li r5, 30 + sraw r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 30 + #_ REGISTER_OUT r6 1 + +test_sraw_8: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 31 + sraw r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 31 + #_ REGISTER_OUT r6 1 + +test_sraw_8_constant: + li r4, -1 + li r5, 31 + sraw r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 31 + #_ REGISTER_OUT r6 1 + +test_sraw_9: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 32 + sraw r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 32 + #_ REGISTER_OUT r6 1 + +test_sraw_9_constant: + li r4, -1 + li r5, 32 + sraw r3, r4, r5 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 32 + #_ REGISTER_OUT r6 1 diff --git a/tests/ppc/asm/instr_srawi.s b/tests/ppc/asm/instr_srawi.s new file mode 100644 index 0000000..d1477d4 --- /dev/null +++ b/tests/ppc/asm/instr_srawi.s @@ -0,0 +1,89 @@ +test_srawi_1: + #_ REGISTER_IN r4 1 + srawi r3, r4, 0 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 0 + +test_srawi_1_constant: + li r4, 1 + srawi r3, r4, 0 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r6 0 + +test_srawi_2: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + srawi r3, r4, 0 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 0 + +test_srawi_2_constant: + li r4, -1 + srawi r3, r4, 0 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 0 + +test_srawi_3: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + srawi r3, r4, 1 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_srawi_3_constant: + li r4, -1 + srawi r3, r4, 1 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_srawi_4: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + srawi r3, r4, 30 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_srawi_4_constant: + li r4, -1 + srawi r3, r4, 30 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_srawi_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + srawi r3, r4, 31 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 + +test_srawi_5_constant: + li r4, -1 + srawi r3, r4, 31 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r6 1 diff --git a/tests/ppc/asm/instr_srd.s b/tests/ppc/asm/instr_srd.s new file mode 100644 index 0000000..ca330a9 --- /dev/null +++ b/tests/ppc/asm/instr_srd.s @@ -0,0 +1,125 @@ +test_srd_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0 + srd r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_srd_1_constant: + li r4, 1 + li r5, 0 + srd r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_srd_2: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0 + srd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + +test_srd_2_constant: + li r4, -1 + li r5, 0 + srd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + +test_srd_3: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + srd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_srd_3_constant: + li r4, -1 + li r5, 1 + srd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_srd_4: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 62 + srd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x0000000000000003 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 62 + +test_srd_4_constant: + li r4, -1 + li r5, 62 + srd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x0000000000000003 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 62 + +test_srd_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 63 + srd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x0000000000000001 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 63 + +test_srd_5_constant: + li r4, -1 + li r5, 63 + srd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x0000000000000001 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 63 + +test_srd_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 64 + srd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 64 + +test_srd_6_constant: + li r4, -1 + li r5, 64 + srd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 64 + +test_srd_7: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 100 + srd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 100 + +test_srd_7_constant: + li r4, -1 + li r5, 100 + srd r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 100 diff --git a/tests/ppc/asm/instr_srw.s b/tests/ppc/asm/instr_srw.s new file mode 100644 index 0000000..ca9d9a7 --- /dev/null +++ b/tests/ppc/asm/instr_srw.s @@ -0,0 +1,199 @@ +test_srw_1: + #_ REGISTER_IN r4 1 + #_ REGISTER_IN r5 0 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_srw_1_constant: + li r4, 1 + li r5, 0 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + #_ REGISTER_OUT r5 0 + +test_srw_2: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 0 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000FFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + +test_srw_2_constant: + li r4, -1 + li r5, 0 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000FFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 0 + +test_srw_3: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 1 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x000000007FFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_srw_3_constant: + li r4, -1 + li r5, 1 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x000000007FFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 1 + +test_srw_4: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 63 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 63 + +test_srw_4_constant: + li r4, -1 + li r5, 63 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 63 + +test_srw_5: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 64 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000FFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 64 + +test_srw_5_constant: + li r4, -1 + li r5, 64 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x00000000FFFFFFFF + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 64 + +test_srw_6: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 100 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 100 + +test_srw_6_constant: + li r4, -1 + li r5, 100 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 100 + +test_srw_7: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 30 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x0000000000000003 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 30 + +test_srw_7_constant: + li r4, -1 + li r5, 30 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x0000000000000003 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 30 + +test_srw_8: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 31 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x0000000000000001 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 31 + +test_srw_8_constant: + li r4, -1 + li r5, 31 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x0000000000000001 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 31 + +test_srw_9: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r5 32 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 32 + +test_srw_9_constant: + li r4, -1 + li r5, 32 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r5 32 + +test_srw_10: + #_ REGISTER_IN r4 0x0000000090003000 + #_ REGISTER_IN r5 36 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0x0000000090003000 + #_ REGISTER_OUT r5 36 + +test_srw_10_constant: + lis r4, 0x9000 + ori r4, r4, 0x3000 + li r5, 36 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0xFFFFFFFF90003000 + #_ REGISTER_OUT r5 36 + +test_srw_11: + #_ REGISTER_IN r4 0x00000000B0043001 + #_ REGISTER_IN r5 4 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x000000000B004300 + #_ REGISTER_OUT r4 0x00000000B0043001 + #_ REGISTER_OUT r5 4 + +test_srw_11_constant: + lis r4, 0xB004 + ori r4, r4, 0x3001 + li r5, 4 + srw r3, r4, r5 + blr + #_ REGISTER_OUT r3 0x000000000B004300 + #_ REGISTER_OUT r4 0xFFFFFFFFB0043001 + #_ REGISTER_OUT r5 4 diff --git a/tests/ppc/asm/instr_stvew.s b/tests/ppc/asm/instr_stvew.s new file mode 100644 index 0000000..ba83de9 --- /dev/null +++ b/tests/ppc/asm/instr_stvew.s @@ -0,0 +1,83 @@ +test_stvew_1: + #_ MEMORY_IN 10001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC + #_ REGISTER_IN r4 0x10001050 + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + stvewx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001050 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ MEMORY_OUT 10001050 00010203 CCCCCCCC CCCCCCCC CCCCCCCC + +test_stvew_1_constant: + #_ MEMORY_IN 10001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC + lis r4, 0x1000 + ori r4, r4, 0x1050 + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + stvewx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001050 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ MEMORY_OUT 10001050 00010203 CCCCCCCC CCCCCCCC CCCCCCCC + +test_stvew_2: + #_ MEMORY_IN 10001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC + #_ REGISTER_IN r4 0x10001054 + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + stvewx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001054 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ MEMORY_OUT 10001050 CCCCCCCC 04050607 CCCCCCCC CCCCCCCC + +test_stvew_2_constant: + #_ MEMORY_IN 10001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC + lis r4, 0x1000 + ori r4, r4, 0x1054 + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + stvewx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001054 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ MEMORY_OUT 10001050 CCCCCCCC 04050607 CCCCCCCC CCCCCCCC + +test_stvew_3: + #_ MEMORY_IN 10001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC + #_ REGISTER_IN r4 0x10001058 + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + stvewx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001058 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ MEMORY_OUT 10001050 CCCCCCCC CCCCCCCC 08090A0B CCCCCCCC + +test_stvew_3_constant: + #_ MEMORY_IN 10001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC + lis r4, 0x1000 + ori r4, r4, 0x1058 + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + stvewx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x10001058 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ MEMORY_OUT 10001050 CCCCCCCC CCCCCCCC 08090A0B CCCCCCCC + +test_stvew_4: + #_ MEMORY_IN 10001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC + #_ REGISTER_IN r4 0x1000105C + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + stvewx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x1000105C + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ MEMORY_OUT 10001050 CCCCCCCC CCCCCCCC CCCCCCCC 0C0D0E0F + +test_stvew_4_constant: + #_ MEMORY_IN 10001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC + lis r4, 0x1000 + ori r4, r4, 0x105C + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + stvewx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x1000105C + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ MEMORY_OUT 10001050 CCCCCCCC CCCCCCCC CCCCCCCC 0C0D0E0F diff --git a/tests/ppc/asm/instr_stvl.s b/tests/ppc/asm/instr_stvl.s new file mode 100644 index 0000000..ddcf0af --- /dev/null +++ b/tests/ppc/asm/instr_stvl.s @@ -0,0 +1,41 @@ +test_stvlx_1: + #_ MEMORY_IN 10001040 00000000 00000000 00000000 3F800000 + #_ REGISTER_IN r4 0x10001040 + #_ REGISTER_IN v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F] + stvlx v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x10001040 + #_ REGISTER_OUT v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F] + #_ MEMORY_OUT 10001040 BE74FCBD BD912ABA BF317BBB BF2D135F + +test_stvlx_1_constant: + #_ MEMORY_IN 10001040 00000000 00000000 00000000 3F800000 + lis r4, 0x1000 + ori r4, r4, 0x1040 + #_ REGISTER_IN v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F] + stvlx v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x10001040 + #_ REGISTER_OUT v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F] + #_ MEMORY_OUT 10001040 BE74FCBD BD912ABA BF317BBB BF2D135F + +test_stvlx_2: + #_ MEMORY_IN 10001040 00010203 04050607 08090A0B 0C0D0E0F + #_ REGISTER_IN r4 0x10001044 + #_ REGISTER_IN v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF] + stvlx v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x10001044 + #_ REGISTER_OUT v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF] + #_ MEMORY_OUT 10001040 00010203 F0F1F2F3 F4F5F6F7 F8F9FAFB + +test_stvlx_2_constant: + #_ MEMORY_IN 10001040 00010203 04050607 08090A0B 0C0D0E0F + lis r4, 0x1000 + ori r4, r4, 0x1044 + #_ REGISTER_IN v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF] + stvlx v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x10001044 + #_ REGISTER_OUT v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF] + #_ MEMORY_OUT 10001040 00010203 F0F1F2F3 F4F5F6F7 F8F9FAFB diff --git a/tests/ppc/asm/instr_stvr.s b/tests/ppc/asm/instr_stvr.s new file mode 100644 index 0000000..cc5bc22 --- /dev/null +++ b/tests/ppc/asm/instr_stvr.s @@ -0,0 +1,67 @@ +test_stvr_1: + #_ MEMORY_IN 10001040 BE74FCBD BD912ABA BF317BBB BF2D135F + #_ MEMORY_IN 10001050 00000000 00000000 00000000 00000000 + #_ REGISTER_IN r4 0x10001040 + #_ REGISTER_IN r5 0x10 + #_ REGISTER_IN v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F] + stvrx v3, r4, r5 + blr + #_ REGISTER_OUT r4 0x10001040 + #_ REGISTER_OUT r5 0x10 + #_ REGISTER_OUT v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F] + #_ MEMORY_OUT 10001040 BE74FCBD BD912ABA BF317BBB BF2D135F + #_ MEMORY_OUT 10001050 00000000 00000000 00000000 00000000 + +test_stvr_1_constant: + #_ MEMORY_IN 10001040 BE74FCBD BD912ABA BF317BBB BF2D135F + #_ MEMORY_IN 10001050 00000000 00000000 00000000 00000000 + lis r4, 0x1000 + ori r4, r4, 0x1040 + li r5, 0x10 + #_ REGISTER_IN v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F] + stvrx v3, r4, r5 + blr + #_ REGISTER_OUT r4 0x10001040 + #_ REGISTER_OUT r5 0x10 + #_ REGISTER_OUT v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F] + #_ MEMORY_OUT 10001040 BE74FCBD BD912ABA BF317BBB BF2D135F + #_ MEMORY_OUT 10001050 00000000 00000000 00000000 00000000 + +test_stvr_2: + #_ MEMORY_IN 10001040 00010203 04050607 08090A0B 0C0D0E0F + #_ REGISTER_IN r4 0x10001044 + #_ REGISTER_IN v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF] + stvrx v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x10001044 + #_ REGISTER_OUT v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF] + #_ MEMORY_OUT 10001040 FCFDFEFF 04050607 08090A0B 0C0D0E0F + +test_stvr_2_constant: + #_ MEMORY_IN 10001040 00010203 04050607 08090A0B 0C0D0E0F + lis r4, 0x1000 + ori r4, r4, 0x1044 + #_ REGISTER_IN v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF] + stvrx v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x10001044 + #_ REGISTER_OUT v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF] + #_ MEMORY_OUT 10001040 FCFDFEFF 04050607 08090A0B 0C0D0E0F + +test_stvr_3: + #_ REGISTER_IN r4 0x10010000 + #_ REGISTER_IN r5 0x0 + #_ REGISTER_IN v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F] + stvrx v3, r4, r5 + blr + #_ REGISTER_OUT r4 0x10010000 + #_ REGISTER_OUT r5 0x0 + #_ REGISTER_OUT v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F] + +test_stvr_3_constant: + #_ REGISTER_IN v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F] + lis r4, 0x1001 + stvrx v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x10010000 + #_ REGISTER_OUT v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F] diff --git a/tests/ppc/asm/instr_subf.s b/tests/ppc/asm/instr_subf.s new file mode 100644 index 0000000..3ad052a --- /dev/null +++ b/tests/ppc/asm/instr_subf.s @@ -0,0 +1,91 @@ +test_subf_1: + #_ REGISTER_IN r10 0x00000000000103BF + #_ REGISTER_IN r11 0x00000000000103C0 + subf r3, r10, r11 + blr + #_ REGISTER_OUT r10 0x00000000000103BF + #_ REGISTER_OUT r11 0x00000000000103C0 + #_ REGISTER_OUT r3 0x1 + +test_subf_1_constant: + lis r10, 1 + ori r10, r10, 0x03BF + lis r11, 1 + ori r11, r11, 0x03C0 + subf r3, r10, r11 + blr + #_ REGISTER_OUT r10 0x00000000000103BF + #_ REGISTER_OUT r11 0x00000000000103C0 + #_ REGISTER_OUT r3 0x1 + +test_subf_2: + #_ REGISTER_IN r10 0 + #_ REGISTER_IN r11 0 + subf r3, r10, r11 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r3 0 + +test_subf_2_constant: + li r10, 0 + li r11, 0 + subf r3, r10, r11 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r3 0 + +test_subf_3: + #_ REGISTER_IN r10 1 + #_ REGISTER_IN r11 0 + subf r3, r10, r11 + blr + #_ REGISTER_OUT r10 1 + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r3 -1 + +test_subf_3_constant: + li r10, 1 + li r11, 0 + subf r3, r10, r11 + blr + #_ REGISTER_OUT r10 1 + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r3 -1 + +test_subf_4: + #_ REGISTER_IN r10 0 + #_ REGISTER_IN r11 1 + subf r3, r10, r11 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r11 1 + #_ REGISTER_OUT r3 1 + +test_subf_4_constant: + li r10, 0 + li r11, 1 + subf r3, r10, r11 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r11 1 + #_ REGISTER_OUT r3 1 + +test_subf_5: + #_ REGISTER_IN r10 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r11 0xFFFFFFFFFFFFFFFF + subf r3, r10, r11 + blr + #_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r3 0x0 + +test_subf_5_constant: + li r10, -1 + li r11, -1 + subf r3, r10, r11 + blr + #_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r3 0x0 diff --git a/tests/ppc/asm/instr_subfc.s b/tests/ppc/asm/instr_subfc.s new file mode 100644 index 0000000..84dc25d --- /dev/null +++ b/tests/ppc/asm/instr_subfc.s @@ -0,0 +1,111 @@ +test_subfc_1: + #_ REGISTER_IN r10 0x00000000000103BF + #_ REGISTER_IN r11 0x00000000000103C0 + subfc r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0x00000000000103BF + #_ REGISTER_OUT r11 0x00000000000103C0 + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + +test_subfc_1_constant: + lis r10, 1 + ori r10, r10, 0x03BF + lis r11, 1 + ori r11, r11, 0x03C0 + subfc r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0x00000000000103BF + #_ REGISTER_OUT r11 0x00000000000103C0 + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + +test_subfc_2: + #_ REGISTER_IN r10 0 + #_ REGISTER_IN r11 0 + subfc r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + +test_subfc_2_constant: + li r10, 0 + li r11, 0 + subfc r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + +test_subfc_3: + #_ REGISTER_IN r10 1 + #_ REGISTER_IN r11 0 + subfc r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 1 + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 0 + +test_subfc_3_constant: + li r10, 1 + li r11, 0 + subfc r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 1 + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 0 + +test_subfc_4: + #_ REGISTER_IN r10 0 + #_ REGISTER_IN r11 1 + subfc r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r11 1 + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + +test_subfc_4_constant: + li r10, 0 + li r11, 1 + subfc r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r11 1 + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + +test_subfc_5: + #_ REGISTER_IN r10 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r11 0xFFFFFFFFFFFFFFFF + subfc r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + +test_subfc_5_constant: + li r10, -1 + li r11, -1 + subfc r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 diff --git a/tests/ppc/asm/instr_subfe.s b/tests/ppc/asm/instr_subfe.s new file mode 100644 index 0000000..25b4891 --- /dev/null +++ b/tests/ppc/asm/instr_subfe.s @@ -0,0 +1,111 @@ +test_subfe_1: + #_ REGISTER_IN r10 0x00000000000103BF + #_ REGISTER_IN r11 0x00000000000103C0 + subfe r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0x00000000000103BF + #_ REGISTER_OUT r11 0x00000000000103C0 + #_ REGISTER_OUT r3 0x0 + #_ REGISTER_OUT r4 1 + +test_subfe_1_constant: + lis r10, 1 + ori r10, r10, 0x03BF + lis r11, 1 + ori r11, r11, 0x03C0 + subfe r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0x00000000000103BF + #_ REGISTER_OUT r11 0x00000000000103C0 + #_ REGISTER_OUT r3 0x0 + #_ REGISTER_OUT r4 1 + +test_subfe_2: + #_ REGISTER_IN r10 0 + #_ REGISTER_IN r11 0 + subfe r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0 + +test_subfe_2_constant: + li r10, 0 + li r11, 0 + subfe r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0 + +test_subfe_3: + #_ REGISTER_IN r10 1 + #_ REGISTER_IN r11 0 + subfe r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 1 + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r3 0xfffffffffffffffe + #_ REGISTER_OUT r4 0 + +test_subfe_3_constant: + li r10, 1 + li r11, 0 + subfe r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 1 + #_ REGISTER_OUT r11 0 + #_ REGISTER_OUT r3 0xfffffffffffffffe + #_ REGISTER_OUT r4 0 + +test_subfe_4: + #_ REGISTER_IN r10 0 + #_ REGISTER_IN r11 1 + subfe r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r11 1 + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + +test_subfe_4_constant: + li r10, 0 + li r11, 1 + subfe r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r11 1 + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + +test_subfe_5: + #_ REGISTER_IN r10 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r11 0xFFFFFFFFFFFFFFFF + subfe r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0 + +test_subfe_5_constant: + li r10, -1 + li r11, -1 + subfe r3, r10, r11 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0 diff --git a/tests/ppc/asm/instr_subfic.s b/tests/ppc/asm/instr_subfic.s new file mode 100644 index 0000000..3a958eb --- /dev/null +++ b/tests/ppc/asm/instr_subfic.s @@ -0,0 +1,109 @@ +test_subfic_1: + #_ REGISTER_IN r10 0x00000000000103BF + subfic r3, r10, 0x3C0 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0x00000000000103BF + #_ REGISTER_OUT r3 0xffffffffffff0001 + #_ REGISTER_OUT r4 0 + +test_subfic_1_constant: + lis r10, 1 + ori r10, r10, 0x03BF + subfic r3, r10, 0x3C0 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0x00000000000103BF + #_ REGISTER_OUT r3 0xffffffffffff0001 + #_ REGISTER_OUT r4 0 + +test_subfic_2: + #_ REGISTER_IN r10 0x00000000000103BF + subfic r3, r10, -234 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0x00000000000103BF + #_ REGISTER_OUT r3 0xfffffffffffefb57 + #_ REGISTER_OUT r4 1 + +test_subfic_2_constant: + lis r10, 1 + ori r10, r10, 0x03BF + subfic r3, r10, -234 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0x00000000000103BF + #_ REGISTER_OUT r3 0xfffffffffffefb57 + #_ REGISTER_OUT r4 1 + +test_subfic_3: + #_ REGISTER_IN r10 0 + subfic r3, r10, 0 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + +test_subfic_3_constant: + li r10, 0 + subfic r3, r10, 0 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + +test_subfic_4: + #_ REGISTER_IN r10 1 + subfic r3, r10, 0 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 1 + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 0 + +test_subfic_4_constant: + li r10, 1 + subfic r3, r10, 0 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 1 + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 0 + +test_subfic_5: + #_ REGISTER_IN r10 0 + subfic r3, r10, 1 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + +test_subfic_5_constant: + li r10, 0 + subfic r3, r10, 1 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r3 1 + #_ REGISTER_OUT r4 1 + +test_subfic_6: + #_ REGISTER_IN r10 0xFFFFFFFFFFFFFFFF + subfic r3, r10, -1 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + +test_subfic_6_constant: + li r10, -1 + subfic r3, r10, -1 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 diff --git a/tests/ppc/asm/instr_subfme.s b/tests/ppc/asm/instr_subfme.s new file mode 100644 index 0000000..9366b7e --- /dev/null +++ b/tests/ppc/asm/instr_subfme.s @@ -0,0 +1,185 @@ +test_subfme_one_ca_1: + #_ REGISTER_IN r10 0x00000000000103BF + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 + subfme r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0x00000000000103BF + #_ REGISTER_OUT r3 0xfffffffffffefc40 + #_ REGISTER_OUT r4 1 + +test_subfme_one_ca_1_constant: + lis r10, 1 + ori r10, r10, 0x03BF + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 + subfme r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0x00000000000103BF + #_ REGISTER_OUT r3 0xfffffffffffefc40 + #_ REGISTER_OUT r4 1 + +test_subfme_one_ca_2: + #_ REGISTER_IN r10 0 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 + subfme r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 1 + +test_subfme_one_ca_2_constant: + li r10, 0 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 + subfme r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 1 + +test_subfme_one_ca_3: + #_ REGISTER_IN r10 1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 + subfme r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 1 + #_ REGISTER_OUT r3 0xfffffffffffffffe + #_ REGISTER_OUT r4 1 + +test_subfme_one_ca_3_constant: + li r10, 1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 + subfme r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 1 + #_ REGISTER_OUT r3 0xfffffffffffffffe + #_ REGISTER_OUT r4 1 + +test_subfme_one_ca_4: + #_ REGISTER_IN r10 0xFFFFFFFFFFFFFFFF + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 + subfme r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + +test_subfme_one_ca_4_constant: + li r10, -1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 + subfme r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + +test_subfme_zero_ca_1: + #_ REGISTER_IN r10 0x00000000000103BF + xor r3, r3, r3 + addic r3, r3, 1 + subfme r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0x00000000000103BF + #_ REGISTER_OUT r3 0xfffffffffffefc3f + #_ REGISTER_OUT r4 1 + +test_subfme_zero_ca_1_constant: + lis r10, 1 + ori r10, r10, 0x03BF + xor r3, r3, r3 + addic r3, r3, 1 + subfme r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0x00000000000103BF + #_ REGISTER_OUT r3 0xfffffffffffefc3f + #_ REGISTER_OUT r4 1 + +test_subfme_zero_ca_2: + #_ REGISTER_IN r10 0 + xor r3, r3, r3 + addic r3, r3, 1 + subfme r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r3 0xfffffffffffffffe + #_ REGISTER_OUT r4 1 + +test_subfme_zero_ca_2_constant: + li r10, 0 + xor r3, r3, r3 + addic r3, r3, 1 + subfme r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r3 0xfffffffffffffffe + #_ REGISTER_OUT r4 1 + +test_subfme_zero_ca_3: + #_ REGISTER_IN r10 1 + xor r3, r3, r3 + addic r3, r3, 1 + subfme r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 1 + #_ REGISTER_OUT r3 0xfffffffffffffffd + #_ REGISTER_OUT r4 1 + +test_subfme_zero_ca_3_constant: + li r10, 1 + xor r3, r3, r3 + addic r3, r3, 1 + subfme r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 1 + #_ REGISTER_OUT r3 0xfffffffffffffffd + #_ REGISTER_OUT r4 1 + +test_subfme_zero_ca_4: + #_ REGISTER_IN r10 0xFFFFFFFFFFFFFFFF + xor r3, r3, r3 + addic r3, r3, 1 + subfme r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0 + +test_subfme_zero_ca_4_constant: + li r10, -1 + xor r3, r3, r3 + addic r3, r3, 1 + subfme r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0 diff --git a/tests/ppc/asm/instr_subfze.s b/tests/ppc/asm/instr_subfze.s new file mode 100644 index 0000000..d050dce --- /dev/null +++ b/tests/ppc/asm/instr_subfze.s @@ -0,0 +1,185 @@ +test_subfze_one_ca_1: + #_ REGISTER_IN r10 0x00000000000103BF + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 + subfze r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0x00000000000103BF + #_ REGISTER_OUT r3 0xfffffffffffefc41 + #_ REGISTER_OUT r4 0 + +test_subfze_one_ca_1_constant: + lis r10, 1 + ori r10, r10, 0x03BF + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 + subfze r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0x00000000000103BF + #_ REGISTER_OUT r3 0xfffffffffffefc41 + #_ REGISTER_OUT r4 0 + +test_subfze_one_ca_2: + #_ REGISTER_IN r10 0 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 + subfze r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + +test_subfze_one_ca_2_constant: + li r10, 0 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 + subfze r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 1 + +test_subfze_one_ca_3: + #_ REGISTER_IN r10 1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 + subfze r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 1 + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 0 + +test_subfze_one_ca_3_constant: + li r10, 1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 + subfze r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 1 + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 0 + +test_subfze_one_ca_4: + #_ REGISTER_IN r10 0xFFFFFFFFFFFFFFFF + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 + subfze r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r3 0x1 + #_ REGISTER_OUT r4 0 + +test_subfze_one_ca_4_constant: + li r10, -1 + xor r3, r3, r3 + not r3, r3 + addic r3, r3, 1 + subfze r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r3 0x1 + #_ REGISTER_OUT r4 0 + +test_subfze_zero_ca_1: + #_ REGISTER_IN r10 0x00000000000103BF + xor r3, r3, r3 + addic r3, r3, 1 + subfze r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0x00000000000103BF + #_ REGISTER_OUT r3 0xfffffffffffefc40 + #_ REGISTER_OUT r4 0 + +test_subfze_zero_ca_1_constant: + lis r10, 1 + ori r10, r10, 0x03BF + xor r3, r3, r3 + addic r3, r3, 1 + subfze r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0x00000000000103BF + #_ REGISTER_OUT r3 0xfffffffffffefc40 + #_ REGISTER_OUT r4 0 + +test_subfze_zero_ca_2: + #_ REGISTER_IN r10 0 + xor r3, r3, r3 + addic r3, r3, 1 + subfze r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0 + +test_subfze_zero_ca_2_constant: + li r10, 0 + xor r3, r3, r3 + addic r3, r3, 1 + subfze r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0 + #_ REGISTER_OUT r3 0xffffffffffffffff + #_ REGISTER_OUT r4 0 + +test_subfze_zero_ca_3: + #_ REGISTER_IN r10 1 + xor r3, r3, r3 + addic r3, r3, 1 + subfze r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 1 + #_ REGISTER_OUT r3 0xfffffffffffffffe + #_ REGISTER_OUT r4 0 + +test_subfze_zero_ca_3_constant: + li r10, 1 + xor r3, r3, r3 + addic r3, r3, 1 + subfze r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 1 + #_ REGISTER_OUT r3 0xfffffffffffffffe + #_ REGISTER_OUT r4 0 + +test_subfze_zero_ca_4: + #_ REGISTER_IN r10 0xFFFFFFFFFFFFFFFF + xor r3, r3, r3 + addic r3, r3, 1 + subfze r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + +test_subfze_zero_ca_4_constant: + li r10, -1 + xor r3, r3, r3 + addic r3, r3, 1 + subfze r3, r10 + adde r4, r0, r0 + blr + #_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 diff --git a/tests/ppc/asm/instr_td.s b/tests/ppc/asm/instr_td.s new file mode 100644 index 0000000..7cc07ed --- /dev/null +++ b/tests/ppc/asm/instr_td.s @@ -0,0 +1,511 @@ +test_tdlt_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 16 + tdlt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_tdlt_1_constant: + li r3, 24 + li r4, 16 + tdlt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_tdlt_2: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 0 + tdlt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_tdlt_2_constant: + li r3, 24 + li r4, 0 + tdlt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_tdle_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 16 + tdle r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_tdle_1_constant: + li r3, 24 + li r4, 16 + tdle r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_tdle_2: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 0 + tdle r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_tdle_2_constant: + li r3, 24 + li r4, 0 + tdle r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_tdeq_1: + #_ REGISTER_IN r3 0 + #_ REGISTER_IN r4 24 + tdeq r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 24 + +test_tdeq_1_constant: + li r3, 0 + li r4, 24 + tdeq r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 24 + +test_tdeq_2: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 0 + tdeq r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_tdeq_2_constant: + li r3, 24 + li r4, 0 + tdeq r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_tdge_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 48 + tdge r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_tdge_1_constant: + li r3, 24 + li r4, 48 + tdge r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_tdge_2: + #_ REGISTER_IN r3 0 + #_ REGISTER_IN r4 48 + tdge r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_tdge_2_constant: + li r3, 0 + li r4, 48 + tdge r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_tdge_3: + #_ REGISTER_IN r3 -1 + #_ REGISTER_IN r4 0 + tdge r3, r4 + blr + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 0 + +test_tdge_3_constant: + li r3, -1 + li r4, 0 + tdge r3, r4 + blr + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 0 + +test_tdgt_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 48 + tdgt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_tdgt_1_constant: + li r3, 24 + li r4, 48 + tdgt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_tdgt_2: + #_ REGISTER_IN r3 0 + #_ REGISTER_IN r4 48 + tdgt r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_tdgt_2_constant: + li r3, 0 + li r4, 48 + tdgt r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_tdgt_3: + #_ REGISTER_IN r3 -1 + #_ REGISTER_IN r4 0 + tdgt r3, r4 + blr + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 0 + +test_tdgt_3_constant: + li r3, -1 + li r4, 0 + tdgt r3, r4 + blr + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 0 + +test_tdnl_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 48 + tdnl r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_tdnl_1_constant: + li r3, 24 + li r4, 48 + tdnl r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_tdnl_2: + #_ REGISTER_IN r3 0 + #_ REGISTER_IN r4 48 + tdnl r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_tdnl_2_constant: + li r3, 0 + li r4, 48 + tdnl r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_tdnl_3: + #_ REGISTER_IN r3 -1 + #_ REGISTER_IN r4 0 + tdnl r3, r4 + blr + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 0 + +test_tdnl_3_constant: + li r3, -1 + li r4, 0 + tdnl r3, r4 + blr + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 0 + +test_tdne_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 24 + tdne r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 24 + +test_tdne_1_constant: + li r3, 24 + li r4, 24 + tdne r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 24 + +test_tdne_2: + #_ REGISTER_IN r3 0 + #_ REGISTER_IN r4 0 + tdne r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + +test_tdne_2_constant: + li r3, 0 + li r4, 0 + tdne r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + +test_tdng_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 16 + tdng r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_tdng_1_constant: + li r3, 24 + li r4, 16 + tdng r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_tdng_2: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 0 + tdng r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_tdng_2_constant: + li r3, 24 + li r4, 0 + tdng r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_tdng_3: + #_ REGISTER_IN r3 0 + #_ REGISTER_IN r4 -1 + tdng r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 -1 + +test_tdng_3_constant: + li r3, 0 + li r4, -1 + tdng r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 -1 + +test_tdllt_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 16 + tdllt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_tdllt_1_constant: + li r3, 24 + li r4, 16 + tdllt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_tdllt_2: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 0 + tdllt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_tdllt_2_constant: + li r3, 24 + li r4, 0 + tdllt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_tdlle_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 16 + tdlle r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_tdlle_1_constant: + li r3, 24 + li r4, 16 + tdlle r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_tdlle_2: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 0 + tdlle r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_tdlle_2_constant: + li r3, 24 + li r4, 0 + tdlle r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_tdlge_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 48 + tdlge r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_tdlge_1_constant: + li r3, 24 + li r4, 48 + tdlge r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_tdlge_2: + #_ REGISTER_IN r3 0 + #_ REGISTER_IN r4 48 + tdlge r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_tdlge_2_constant: + li r3, 0 + li r4, 48 + tdlge r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_tdlgt_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 48 + tdlgt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_tdlgt_1_constant: + li r3, 24 + li r4, 48 + tdlgt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_tdlgt_2: + #_ REGISTER_IN r3 0 + #_ REGISTER_IN r4 48 + tdlgt r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_tdlgt_2_constant: + li r3, 0 + li r4, 48 + tdlgt r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_tdlnl_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 48 + tdlnl r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_tdlnl_1_constant: + li r3, 24 + li r4, 48 + tdlnl r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_tdlnl_2: + #_ REGISTER_IN r3 0 + #_ REGISTER_IN r4 48 + tdlnl r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_tdlnl_2_constant: + li r3, 0 + li r4, 48 + tdlnl r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_tdlng_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 16 + tdlng r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_tdlng_1_constant: + li r3, 24 + li r4, 16 + tdlng r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_tdlng_2: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 0 + tdlng r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_tdlng_2_constant: + li r3, 24 + li r4, 0 + tdlng r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 diff --git a/tests/ppc/asm/instr_tdi.s b/tests/ppc/asm/instr_tdi.s new file mode 100644 index 0000000..df2a20e --- /dev/null +++ b/tests/ppc/asm/instr_tdi.s @@ -0,0 +1,383 @@ +test_tdlti_1: + #_ REGISTER_IN r3 24 + tdlti r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_tdlti_1_constant: + li r3, 24 + tdlti r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_tdlti_2: + #_ REGISTER_IN r3 24 + tdlti r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_tdlti_2_constant: + li r3, 24 + tdlti r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_tdlei_1: + #_ REGISTER_IN r3 24 + tdlei r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_tdlei_1_constant: + li r3, 24 + tdlei r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_tdlei_2: + #_ REGISTER_IN r3 24 + tdlei r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_tdlei_2_constant: + li r3, 24 + tdlei r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_tdeqi_1: + #_ REGISTER_IN r3 0 + tdeqi r3, 24 + blr + #_ REGISTER_OUT r3 0 + +test_tdeqi_1_constant: + li r3, 0 + tdeqi r3, 24 + blr + #_ REGISTER_OUT r3 0 + +test_tdeqi_2: + #_ REGISTER_IN r3 24 + tdeqi r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_tdeqi_2_constant: + li r3, 24 + tdeqi r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_tdgei_1: + #_ REGISTER_IN r3 24 + tdgei r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_tdgei_1_constant: + li r3, 24 + tdgei r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_tdgei_2: + #_ REGISTER_IN r3 0 + tdgei r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_tdgei_2_constant: + li r3, 0 + tdgei r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_tdgei_3: + #_ REGISTER_IN r3 -1 + tdgei r3, 0 + blr + #_ REGISTER_OUT r3 -1 + +test_tdgei_3_constant: + li r3, -1 + tdgei r3, 0 + blr + #_ REGISTER_OUT r3 -1 + +test_tdgti_1: + #_ REGISTER_IN r3 24 + tdgti r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_tdgti_1_constant: + li r3, 24 + tdgti r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_tdgti_2: + #_ REGISTER_IN r3 0 + tdgti r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_tdgti_2_constant: + li r3, 0 + tdgti r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_tdgti_3: + #_ REGISTER_IN r3 -1 + tdgti r3, 0 + blr + #_ REGISTER_OUT r3 -1 + +test_tdgti_3_constant: + li r3, -1 + tdgti r3, 0 + blr + #_ REGISTER_OUT r3 -1 + +test_tdnli_1: + #_ REGISTER_IN r3 24 + tdnli r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_tdnli_1_constant: + li r3, 24 + tdnli r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_tdnli_2: + #_ REGISTER_IN r3 0 + tdnli r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_tdnli_2_constant: + li r3, 0 + tdnli r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_tdnli_3: + #_ REGISTER_IN r3 -1 + tdnli r3, 0 + blr + #_ REGISTER_OUT r3 -1 + +test_tdnli_3_constant: + li r3, -1 + tdnli r3, 0 + blr + #_ REGISTER_OUT r3 -1 + +test_tdnei_1: + #_ REGISTER_IN r3 24 + tdnei r3, 24 + blr + #_ REGISTER_OUT r3 24 + +test_tdnei_1_constant: + li r3, 24 + tdnei r3, 24 + blr + #_ REGISTER_OUT r3 24 + +test_tdnei_2: + #_ REGISTER_IN r3 0 + tdnei r3, 0 + blr + #_ REGISTER_OUT r3 0 + +test_tdnei_2_constant: + li r3, 0 + tdnei r3, 0 + blr + #_ REGISTER_OUT r3 0 + +test_tdngi_1: + #_ REGISTER_IN r3 24 + tdngi r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_tdngi_1_constant: + li r3, 24 + tdngi r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_tdngi_2: + #_ REGISTER_IN r3 24 + tdngi r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_tdngi_2_constant: + li r3, 24 + tdngi r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_tdngi_3: + #_ REGISTER_IN r3 0 + tdngi r3, -1 + blr + #_ REGISTER_OUT r3 0 + +test_tdngi_3_constant: + li r3, 0 + tdngi r3, -1 + blr + #_ REGISTER_OUT r3 0 + +test_tdllti_1: + #_ REGISTER_IN r3 24 + tdllti r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_tdllti_1_constant: + li r3, 24 + tdllti r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_tdllti_2: + #_ REGISTER_IN r3 24 + tdllti r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_tdllti_2_constant: + li r3, 24 + tdllti r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_tdllei_1: + #_ REGISTER_IN r3 24 + tdllei r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_tdllei_1_constant: + li r3, 24 + tdllei r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_tdllei_2: + #_ REGISTER_IN r3 24 + tdllei r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_tdllei_2_constant: + li r3, 24 + tdllei r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_tdlgei_1: + #_ REGISTER_IN r3 24 + tdlgei r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_tdlgei_1_constant: + li r3, 24 + tdlgei r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_tdlgei_2: + #_ REGISTER_IN r3 0 + tdlgei r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_tdlgei_2_constant: + li r3, 0 + tdlgei r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_tdlgti_1: + #_ REGISTER_IN r3 24 + tdlgti r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_tdlgti_1_constant: + li r3, 24 + tdlgti r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_tdlgti_2: + #_ REGISTER_IN r3 0 + tdlgti r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_tdlgti_2_constant: + li r3, 0 + tdlgti r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_tdlnli_1: + #_ REGISTER_IN r3 24 + tdlnli r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_tdlnli_1_constant: + li r3, 24 + tdlnli r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_tdlnli_2: + #_ REGISTER_IN r3 0 + tdlnli r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_tdlnli_2_constant: + li r3, 0 + tdlnli r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_tdlngi_1: + #_ REGISTER_IN r3 24 + tdlngi r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_tdlngi_1_constant: + li r3, 24 + tdlngi r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_tdlngi_2: + #_ REGISTER_IN r3 24 + tdlngi r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_tdlngi_2_constant: + li r3, 24 + tdlngi r3, 0 + blr + #_ REGISTER_OUT r3 24 diff --git a/tests/ppc/asm/instr_tw.s b/tests/ppc/asm/instr_tw.s new file mode 100644 index 0000000..5742794 --- /dev/null +++ b/tests/ppc/asm/instr_tw.s @@ -0,0 +1,511 @@ +test_twlt_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 16 + twlt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_twlt_1_constant: + li r3, 24 + li r4, 16 + twlt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_twlt_2: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 0 + twlt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_twlt_2_constant: + li r3, 24 + li r4, 0 + twlt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_twle_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 16 + twle r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_twle_1_constant: + li r3, 24 + li r4, 16 + twle r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_twle_2: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 0 + twle r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_twle_2_constant: + li r3, 24 + li r4, 0 + twle r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_tweq_1: + #_ REGISTER_IN r3 0 + #_ REGISTER_IN r4 24 + tweq r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 24 + +test_tweq_1_constant: + li r3, 0 + li r4, 24 + tweq r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 24 + +test_tweq_2: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 0 + tweq r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_tweq_2_constant: + li r3, 24 + li r4, 0 + tweq r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_twge_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 48 + twge r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_twge_1_constant: + li r3, 24 + li r4, 48 + twge r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_twge_2: + #_ REGISTER_IN r3 0 + #_ REGISTER_IN r4 48 + twge r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_twge_2_constant: + li r3, 0 + li r4, 48 + twge r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_twge_3: + #_ REGISTER_IN r3 -1 + #_ REGISTER_IN r4 0 + twge r3, r4 + blr + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 0 + +test_twge_3_constant: + li r3, -1 + li r4, 0 + twge r3, r4 + blr + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 0 + +test_twgt_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 48 + twgt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_twgt_1_constant: + li r3, 24 + li r4, 48 + twgt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_twgt_2: + #_ REGISTER_IN r3 0 + #_ REGISTER_IN r4 48 + twgt r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_twgt_2_constant: + li r3, 0 + li r4, 48 + twgt r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_twgt_3: + #_ REGISTER_IN r3 -1 + #_ REGISTER_IN r4 0 + twgt r3, r4 + blr + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 0 + +test_twgt_3_constant: + li r3, -1 + li r4, 0 + twgt r3, r4 + blr + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 0 + +test_twnl_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 48 + twnl r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_twnl_1_constant: + li r3, 24 + li r4, 48 + twnl r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_twnl_2: + #_ REGISTER_IN r3 0 + #_ REGISTER_IN r4 48 + twnl r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_twnl_2_constant: + li r3, 0 + li r4, 48 + twnl r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_twnl_3: + #_ REGISTER_IN r3 -1 + #_ REGISTER_IN r4 0 + twnl r3, r4 + blr + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 0 + +test_twnl_3_constant: + li r3, -1 + li r4, 0 + twnl r3, r4 + blr + #_ REGISTER_OUT r3 -1 + #_ REGISTER_OUT r4 0 + +test_twne_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 24 + twne r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 24 + +test_twne_1_constant: + li r3, 24 + li r4, 24 + twne r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 24 + +test_twne_2: + #_ REGISTER_IN r3 0 + #_ REGISTER_IN r4 0 + twne r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + +test_twne_2_constant: + li r3, 0 + li r4, 0 + twne r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 0 + +test_twng_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 16 + twng r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_twng_1_constant: + li r3, 24 + li r4, 16 + twng r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_twng_2: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 0 + twng r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_twng_2_constant: + li r3, 24 + li r4, 0 + twng r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_twng_3: + #_ REGISTER_IN r3 0 + #_ REGISTER_IN r4 -1 + twng r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 -1 + +test_twng_3_constant: + li r3, 0 + li r4, -1 + twng r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 -1 + +test_twllt_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 16 + twllt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_twllt_1_constant: + li r3, 24 + li r4, 16 + twllt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_twllt_2: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 0 + twllt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_twllt_2_constant: + li r3, 24 + li r4, 0 + twllt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_twlle_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 16 + twlle r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_twlle_1_constant: + li r3, 24 + li r4, 16 + twlle r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_twlle_2: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 0 + twlle r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_twlle_2_constant: + li r3, 24 + li r4, 0 + twlle r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_twlge_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 48 + twlge r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_twlge_1_constant: + li r3, 24 + li r4, 48 + twlge r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_twlge_2: + #_ REGISTER_IN r3 0 + #_ REGISTER_IN r4 48 + twlge r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_twlge_2_constant: + li r3, 0 + li r4, 48 + twlge r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_twlgt_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 48 + twlgt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_twlgt_1_constant: + li r3, 24 + li r4, 48 + twlgt r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_twlgt_2: + #_ REGISTER_IN r3 0 + #_ REGISTER_IN r4 48 + twlgt r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_twlgt_2_constant: + li r3, 0 + li r4, 48 + twlgt r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_twlnl_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 48 + twlnl r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_twlnl_1_constant: + li r3, 24 + li r4, 48 + twlnl r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 48 + +test_twlnl_2: + #_ REGISTER_IN r3 0 + #_ REGISTER_IN r4 48 + twlnl r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_twlnl_2_constant: + li r3, 0 + li r4, 48 + twlnl r3, r4 + blr + #_ REGISTER_OUT r3 0 + #_ REGISTER_OUT r4 48 + +test_twlng_1: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 16 + twlng r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_twlng_1_constant: + li r3, 24 + li r4, 16 + twlng r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 16 + +test_twlng_2: + #_ REGISTER_IN r3 24 + #_ REGISTER_IN r4 0 + twlng r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 + +test_twlng_2_constant: + li r3, 24 + li r4, 0 + twlng r3, r4 + blr + #_ REGISTER_OUT r3 24 + #_ REGISTER_OUT r4 0 diff --git a/tests/ppc/asm/instr_twi.s b/tests/ppc/asm/instr_twi.s new file mode 100644 index 0000000..3650ccc --- /dev/null +++ b/tests/ppc/asm/instr_twi.s @@ -0,0 +1,383 @@ +test_twlti_1: + #_ REGISTER_IN r3 24 + twlti r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_twlti_1_constant: + li r3, 24 + twlti r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_twlti_2: + #_ REGISTER_IN r3 24 + twlti r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_twlti_2_constant: + li r3, 24 + twlti r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_twlei_1: + #_ REGISTER_IN r3 24 + twlei r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_twlei_1_constant: + li r3, 24 + twlei r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_twlei_2: + #_ REGISTER_IN r3 24 + twlei r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_twlei_2_constant: + li r3, 24 + twlei r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_tweqi_1: + #_ REGISTER_IN r3 0 + tweqi r3, 24 + blr + #_ REGISTER_OUT r3 0 + +test_tweqi_1_constant: + li r3, 0 + tweqi r3, 24 + blr + #_ REGISTER_OUT r3 0 + +test_tweqi_2: + #_ REGISTER_IN r3 24 + tweqi r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_tweqi_2_constant: + li r3, 24 + tweqi r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_twgei_1: + #_ REGISTER_IN r3 24 + twgei r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_twgei_1_constant: + li r3, 24 + twgei r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_twgei_2: + #_ REGISTER_IN r3 0 + twgei r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_twgei_2_constant: + li r3, 0 + twgei r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_twgei_3: + #_ REGISTER_IN r3 -1 + twgei r3, 0 + blr + #_ REGISTER_OUT r3 -1 + +test_twgei_3_constant: + li r3, -1 + twgei r3, 0 + blr + #_ REGISTER_OUT r3 -1 + +test_twgti_1: + #_ REGISTER_IN r3 24 + twgti r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_twgti_1_constant: + li r3, 24 + twgti r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_twgti_2: + #_ REGISTER_IN r3 0 + twgti r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_twgti_2_constant: + li r3, 0 + twgti r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_twgti_3: + #_ REGISTER_IN r3 -1 + twgti r3, 0 + blr + #_ REGISTER_OUT r3 -1 + +test_twgti_3_constant: + li r3, -1 + twgti r3, 0 + blr + #_ REGISTER_OUT r3 -1 + +test_twnli_1: + #_ REGISTER_IN r3 24 + twnli r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_twnli_1_constant: + li r3, 24 + twnli r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_twnli_2: + #_ REGISTER_IN r3 0 + twnli r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_twnli_2_constant: + li r3, 0 + twnli r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_twnli_3: + #_ REGISTER_IN r3 -1 + twnli r3, 0 + blr + #_ REGISTER_OUT r3 -1 + +test_twnli_3_constant: + li r3, -1 + twnli r3, 0 + blr + #_ REGISTER_OUT r3 -1 + +test_twnei_1: + #_ REGISTER_IN r3 24 + twnei r3, 24 + blr + #_ REGISTER_OUT r3 24 + +test_twnei_1_constant: + li r3, 24 + twnei r3, 24 + blr + #_ REGISTER_OUT r3 24 + +test_twnei_2: + #_ REGISTER_IN r3 0 + twnei r3, 0 + blr + #_ REGISTER_OUT r3 0 + +test_twnei_2_constant: + li r3, 0 + twnei r3, 0 + blr + #_ REGISTER_OUT r3 0 + +test_twngi_1: + #_ REGISTER_IN r3 24 + twngi r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_twngi_1_constant: + li r3, 24 + twngi r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_twngi_2: + #_ REGISTER_IN r3 24 + twngi r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_twngi_2_constant: + li r3, 24 + twngi r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_twngi_3: + #_ REGISTER_IN r3 0 + twngi r3, -1 + blr + #_ REGISTER_OUT r3 0 + +test_twngi_3_constant: + li r3, 0 + twngi r3, -1 + blr + #_ REGISTER_OUT r3 0 + +test_twllti_1: + #_ REGISTER_IN r3 24 + twllti r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_twllti_1_constant: + li r3, 24 + twllti r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_twllti_2: + #_ REGISTER_IN r3 24 + twllti r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_twllti_2_constant: + li r3, 24 + twllti r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_twllei_1: + #_ REGISTER_IN r3 24 + twllei r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_twllei_1_constant: + li r3, 24 + twllei r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_twllei_2: + #_ REGISTER_IN r3 24 + twllei r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_twllei_2_constant: + li r3, 24 + twllei r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_twlgei_1: + #_ REGISTER_IN r3 24 + twlgei r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_twlgei_1_constant: + li r3, 24 + twlgei r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_twlgei_2: + #_ REGISTER_IN r3 0 + twlgei r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_twlgei_2_constant: + li r3, 0 + twlgei r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_twlgti_1: + #_ REGISTER_IN r3 24 + twlgti r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_twlgti_1_constant: + li r3, 24 + twlgti r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_twlgti_2: + #_ REGISTER_IN r3 0 + twlgti r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_twlgti_2_constant: + li r3, 0 + twlgti r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_twlnli_1: + #_ REGISTER_IN r3 24 + twlnli r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_twlnli_1_constant: + li r3, 24 + twlnli r3, 48 + blr + #_ REGISTER_OUT r3 24 + +test_twlnli_2: + #_ REGISTER_IN r3 0 + twlnli r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_twlnli_2_constant: + li r3, 0 + twlnli r3, 48 + blr + #_ REGISTER_OUT r3 0 + +test_twlngi_1: + #_ REGISTER_IN r3 24 + twlngi r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_twlngi_1_constant: + li r3, 24 + twlngi r3, 16 + blr + #_ REGISTER_OUT r3 24 + +test_twlngi_2: + #_ REGISTER_IN r3 24 + twlngi r3, 0 + blr + #_ REGISTER_OUT r3 24 + +test_twlngi_2_constant: + li r3, 24 + twlngi r3, 0 + blr + #_ REGISTER_OUT r3 24 diff --git a/tests/ppc/asm/instr_vaddfp.s b/tests/ppc/asm/instr_vaddfp.s new file mode 100644 index 0000000..d7cfdca --- /dev/null +++ b/tests/ppc/asm/instr_vaddfp.s @@ -0,0 +1,9 @@ +test_vaddfp_1: + # v3 = [10.0, -10.0, 15.0, -15.0] + # v4 = [-10.0, 20.0, -20.0, 30.0] + #_ REGISTER_IN v3 [41200000, C1200000, 41700000, C1700000] + #_ REGISTER_IN v4 [C1200000, 41A00000, C1A00000, 41F00000] + vaddfp v3, v3, v4 + blr + #_ REGISTER_OUT v3 [00000000, 41200000, C0A00000, 41700000] + #_ REGISTER_OUT v4 [C1200000, 41A00000, C1A00000, 41F00000] diff --git a/tests/ppc/asm/instr_vaddfp128.s b/tests/ppc/asm/instr_vaddfp128.s new file mode 100644 index 0000000..9972760 --- /dev/null +++ b/tests/ppc/asm/instr_vaddfp128.s @@ -0,0 +1,10 @@ +test_vaddfp128_1: + # v3 = [10.0, -10.0, 15.0, -15.0] + # v4 = [-10.0, 20.0, -20.0, 30.0] + #_ REGISTER_IN v3 [41200000, C1200000, 41700000, C1700000] + #_ REGISTER_IN v4 [C1200000, 41A00000, C1A00000, 41F00000] + vaddfp128 v0, v3, v4 + blr + #_ REGISTER_OUT v0 [00000000, 41200000, C0A00000, 41700000] + #_ REGISTER_OUT v3 [41200000, C1200000, 41700000, C1700000] + #_ REGISTER_OUT v4 [C1200000, 41A00000, C1A00000, 41F00000] diff --git a/tests/ppc/asm/instr_vaddshs.s b/tests/ppc/asm/instr_vaddshs.s new file mode 100644 index 0000000..033b9cf --- /dev/null +++ b/tests/ppc/asm/instr_vaddshs.s @@ -0,0 +1,7 @@ +test_vaddshs_1: + #_ REGISTER_IN v3 [7FFF8001, 7FFF8003, 7FFF8005, 80068007] + #_ REGISTER_IN v4 [00018001, 10000000, 42568124, 00000000] + vaddshs v3, v3, v4 + blr + #_ REGISTER_OUT v3 [7fff8000, 7fff8003, 7fff8000, 80068007] + #_ REGISTER_OUT v4 [00018001, 10000000, 42568124, 00000000] diff --git a/tests/ppc/asm/instr_vadduhm.s b/tests/ppc/asm/instr_vadduhm.s new file mode 100644 index 0000000..2d7126d --- /dev/null +++ b/tests/ppc/asm/instr_vadduhm.s @@ -0,0 +1,7 @@ +test_vadduhm_1: + #_ REGISTER_IN v3 [7FFF8001, 7FFF8003, 7FFF8005, 80068007] + #_ REGISTER_IN v4 [00018001, 10000000, 42568124, 00000000] + vadduhm v3, v3, v4 + blr + #_ REGISTER_OUT v3 [80000002, 8fff8003, c2550129, 80068007] + #_ REGISTER_OUT v4 [00018001, 10000000, 42568124, 00000000] diff --git a/tests/ppc/asm/instr_vand.s b/tests/ppc/asm/instr_vand.s new file mode 100644 index 0000000..0780dae --- /dev/null +++ b/tests/ppc/asm/instr_vand.s @@ -0,0 +1,8 @@ +test_vand_1: + #_ REGISTER_IN v3 [FFFF0101, 7070FFFF, 7FFFFFFF, 00000000] + #_ REGISTER_IN v4 [80081010, 808F0020, 7FFFFFF0, 8FFFFFFF] + vand v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFF0101, 7070FFFF, 7FFFFFFF, 00000000] + #_ REGISTER_OUT v4 [80081010, 808F0020, 7FFFFFF0, 8FFFFFFF] + #_ REGISTER_OUT v5 [80080000, 00000020, 7FFFFFF0, 00000000] diff --git a/tests/ppc/asm/instr_vand128.s b/tests/ppc/asm/instr_vand128.s new file mode 100644 index 0000000..5e37574 --- /dev/null +++ b/tests/ppc/asm/instr_vand128.s @@ -0,0 +1,8 @@ +test_vand128_1: + #_ REGISTER_IN v3 [FFFF0101, 7070FFFF, 7FFFFFFF, 00000000] + #_ REGISTER_IN v4 [80081010, 808F0020, 7FFFFFF0, 8FFFFFFF] + vand128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFF0101, 7070FFFF, 7FFFFFFF, 00000000] + #_ REGISTER_OUT v4 [80081010, 808F0020, 7FFFFFF0, 8FFFFFFF] + #_ REGISTER_OUT v5 [80080000, 00000020, 7FFFFFF0, 00000000] diff --git a/tests/ppc/asm/instr_vandc.s b/tests/ppc/asm/instr_vandc.s new file mode 100644 index 0000000..17c7ebd --- /dev/null +++ b/tests/ppc/asm/instr_vandc.s @@ -0,0 +1,8 @@ +test_vandc_1: + #_ REGISTER_IN v3 [FFFF0101, 7070FFFF, 7FFFFFFF, 00000000] + #_ REGISTER_IN v4 [80081010, 808F0020, 7FFFFFF0, 8FFFFFFF] + vandc v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFF0101, 7070FFFF, 7FFFFFFF, 00000000] + #_ REGISTER_OUT v4 [80081010, 808F0020, 7FFFFFF0, 8FFFFFFF] + #_ REGISTER_OUT v5 [7FF70101, 7070FFDF, 0000000F, 00000000] diff --git a/tests/ppc/asm/instr_vandc128.s b/tests/ppc/asm/instr_vandc128.s new file mode 100644 index 0000000..1ee5cca --- /dev/null +++ b/tests/ppc/asm/instr_vandc128.s @@ -0,0 +1,8 @@ +test_vandc128_1: + #_ REGISTER_IN v3 [FFFF0101, 7070FFFF, 7FFFFFFF, 00000000] + #_ REGISTER_IN v4 [80081010, 808F0020, 7FFFFFF0, 8FFFFFFF] + vandc128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFF0101, 7070FFFF, 7FFFFFFF, 00000000] + #_ REGISTER_OUT v4 [80081010, 808F0020, 7FFFFFF0, 8FFFFFFF] + #_ REGISTER_OUT v5 [7FF70101, 7070FFDF, 0000000F, 00000000] diff --git a/tests/ppc/asm/instr_vavgsh.s b/tests/ppc/asm/instr_vavgsh.s new file mode 100644 index 0000000..93a8697 --- /dev/null +++ b/tests/ppc/asm/instr_vavgsh.s @@ -0,0 +1,8 @@ +test_vavgsh_1: + #_ REGISTER_IN v3 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_IN v4 [00080009, 000A000B, 000C000D, 000E000F] + vavgsh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_OUT v4 [00080009, 000A000B, 000C000D, 000E000F] + #_ REGISTER_OUT v5 [00040005, 00060007, 00080009, 000A000B] diff --git a/tests/ppc/asm/instr_vavguh.s b/tests/ppc/asm/instr_vavguh.s new file mode 100644 index 0000000..196c343 --- /dev/null +++ b/tests/ppc/asm/instr_vavguh.s @@ -0,0 +1,8 @@ +test_vavguh_1: + #_ REGISTER_IN v3 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_IN v4 [00080009, 000A000B, 000C000D, 000E000F] + vavguh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_OUT v4 [00080009, 000A000B, 000C000D, 000E000F] + #_ REGISTER_OUT v5 [00040005, 00060007, 00080009, 000A000B] diff --git a/tests/ppc/asm/instr_vcfsx.s b/tests/ppc/asm/instr_vcfsx.s new file mode 100644 index 0000000..86986f3 --- /dev/null +++ b/tests/ppc/asm/instr_vcfsx.s @@ -0,0 +1,20 @@ +test_vcfsx_1: + #_ REGISTER_IN v3 [3f800000, 3fc00000, 3f8ccccd, 3ff33333] + # 1.0, 1.5, 1.1, 1.9 + vcfsx v3, v3, 0 + blr + #_ REGISTER_OUT v3 [4e7e0000, 4e7f0000, 4e7e3333, 4e7fcccd] + +test_vcfsx_2: + #_ REGISTER_IN v3 [3f800000, 3fc00000, 3f8ccccd, 3ff33333] + # 1.0, 1.5, 1.1, 1.9 + vcfsx v3, v3, 1 + blr + #_ REGISTER_OUT v3 [4dfe0000, 4dff0000, 4dfe3333, 4dffcccd] + +test_vcfsx_3: + #_ REGISTER_IN v3 [3f800000, 3fc00000, 3f8ccccd, 3ff33333] + # 1.0, 1.5, 1.1, 1.9 + vcfsx v3, v3, 10 + blr + #_ REGISTER_OUT v3 [497e0000, 497f0000, 497e3333, 497fcccd] diff --git a/tests/ppc/asm/instr_vcmpxxfp.s b/tests/ppc/asm/instr_vcmpxxfp.s new file mode 100644 index 0000000..ceaf3fb --- /dev/null +++ b/tests/ppc/asm/instr_vcmpxxfp.s @@ -0,0 +1,68 @@ +test_vcmpxxfp_1: + #_ REGISTER_IN v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_IN v5 [3f800000, 3f800000, 3f800000, 3f800000] + vcmpeqfp. v3, v4, v5 + mfocrf r3, 2 # cr6 + blr + #_ REGISTER_OUT v3 [ffffffff, ffffffff, ffffffff, ffffffff] + #_ REGISTER_OUT v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_OUT v5 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_OUT r3 0x00000080 + +test_vcmpxxfp_2: + #_ REGISTER_IN v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_IN v5 [3f800001, 3f800000, 3f800000, 3f800000] + vcmpeqfp. v3, v4, v5 + mfocrf r3, 2 # cr6 + blr + #_ REGISTER_OUT v3 [00000000, ffffffff, ffffffff, ffffffff] + #_ REGISTER_OUT v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_OUT v5 [3f800001, 3f800000, 3f800000, 3f800000] + #_ REGISTER_OUT r3 0x00000000 + +test_vcmpxxfp_3: + #_ REGISTER_IN v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_IN v5 [3f800001, 3f800001, 3f800001, 3f800001] + vcmpeqfp. v3, v4, v5 + mfocrf r3, 2 # cr6 + blr + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_OUT v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_OUT v5 [3f800001, 3f800001, 3f800001, 3f800001] + #_ REGISTER_OUT r3 0x00000020 + +test_vcmpbfp_1: + # [5.0, 5.0, 5.0, 5.0] + #_ REGISTER_IN v4 [40A00000, 40A00000, 40A00000, 40A00000] + #_ REGISTER_IN v5 [40A00000, 40A00000, 40A00000, 40A00000] + vcmpbfp. v3, v4, v5 + mfocrf r3, 2 # cr6 + blr + #_ REGISTER_OUT v4 [40A00000, 40A00000, 40A00000, 40A00000] + #_ REGISTER_OUT v5 [40A00000, 40A00000, 40A00000, 40A00000] + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_OUT r3 0x00000020 + +test_vcmpbfp_2: + # [-5.0, -5.0, -5.0, -5.0] + #_ REGISTER_IN v4 [C0A00000, C0A00000, C0A00000, C0A00000] + #_ REGISTER_IN v5 [40A00000, 40A00000, 40A00000, 40A00000] + vcmpbfp. v3, v4, v5 + mfocrf r3, 2 # cr6 + blr + #_ REGISTER_OUT v4 [C0A00000, C0A00000, C0A00000, C0A00000] + #_ REGISTER_OUT v5 [40A00000, 40A00000, 40A00000, 40A00000] + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_OUT r3 0x00000020 + +test_vcmpbfp_3: + # [7.0, -7.0, 5.0, 5.0] + #_ REGISTER_IN v4 [40E00000, C0E00000, 40A00000, 40A00000] + #_ REGISTER_IN v5 [40A00000, 40A00000, 40A00000, 40A00000] + vcmpbfp. v3, v4, v5 + mfocrf r3, 2 # cr6 + blr + #_ REGISTER_OUT v4 [40E00000, C0E00000, 40A00000, 40A00000] + #_ REGISTER_OUT v5 [40A00000, 40A00000, 40A00000, 40A00000] + #_ REGISTER_OUT v3 [80000000, 40000000, 00000000, 00000000] + #_ REGISTER_OUT r3 0x00000000 diff --git a/tests/ppc/asm/instr_vcmpxxfp128.s b/tests/ppc/asm/instr_vcmpxxfp128.s new file mode 100644 index 0000000..472757a --- /dev/null +++ b/tests/ppc/asm/instr_vcmpxxfp128.s @@ -0,0 +1,68 @@ +test_vcmpxxfp128_1: + #_ REGISTER_IN v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_IN v5 [3f800000, 3f800000, 3f800000, 3f800000] + vcmpeqfp128. v3, v4, v5 + mfocrf r3, 2 # cr6 + blr + #_ REGISTER_OUT v3 [ffffffff, ffffffff, ffffffff, ffffffff] + #_ REGISTER_OUT v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_OUT v5 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_OUT r3 0x00000080 + +test_vcmpxxfp128_2: + #_ REGISTER_IN v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_IN v5 [3f800001, 3f800000, 3f800000, 3f800000] + vcmpeqfp128. v3, v4, v5 + mfocrf r3, 2 # cr6 + blr + #_ REGISTER_OUT v3 [00000000, ffffffff, ffffffff, ffffffff] + #_ REGISTER_OUT v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_OUT v5 [3f800001, 3f800000, 3f800000, 3f800000] + #_ REGISTER_OUT r3 0x00000000 + +test_vcmpxxfp128_3: + #_ REGISTER_IN v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_IN v5 [3f800001, 3f800001, 3f800001, 3f800001] + vcmpeqfp128. v3, v4, v5 + mfocrf r3, 2 # cr6 + blr + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_OUT v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_OUT v5 [3f800001, 3f800001, 3f800001, 3f800001] + #_ REGISTER_OUT r3 0x00000020 + +test_vcmpbfp128_1: + # [5.0, 5.0, 5.0, 5.0] + #_ REGISTER_IN v4 [40A00000, 40A00000, 40A00000, 40A00000] + #_ REGISTER_IN v5 [40A00000, 40A00000, 40A00000, 40A00000] + vcmpbfp128. v3, v4, v5 + mfocrf r3, 2 # cr6 + blr + #_ REGISTER_OUT v4 [40A00000, 40A00000, 40A00000, 40A00000] + #_ REGISTER_OUT v5 [40A00000, 40A00000, 40A00000, 40A00000] + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_OUT r3 0x00000020 + +test_vcmpbfp128_2: + # [-5.0, -5.0, -5.0, -5.0] + #_ REGISTER_IN v4 [C0A00000, C0A00000, C0A00000, C0A00000] + #_ REGISTER_IN v5 [40A00000, 40A00000, 40A00000, 40A00000] + vcmpbfp128. v3, v4, v5 + mfocrf r3, 2 # cr6 + blr + #_ REGISTER_OUT v4 [C0A00000, C0A00000, C0A00000, C0A00000] + #_ REGISTER_OUT v5 [40A00000, 40A00000, 40A00000, 40A00000] + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_OUT r3 0x00000020 + +test_vcmpbfp128_3: + # [7.0, -7.0, 5.0, 5.0] + #_ REGISTER_IN v4 [40E00000, C0E00000, 40A00000, 40A00000] + #_ REGISTER_IN v5 [40A00000, 40A00000, 40A00000, 40A00000] + vcmpbfp128. v3, v4, v5 + mfocrf r3, 2 # cr6 + blr + #_ REGISTER_OUT v4 [40E00000, C0E00000, 40A00000, 40A00000] + #_ REGISTER_OUT v5 [40A00000, 40A00000, 40A00000, 40A00000] + #_ REGISTER_OUT v3 [80000000, 40000000, 00000000, 00000000] + #_ REGISTER_OUT r3 0x00000000 diff --git a/tests/ppc/asm/instr_vctsxs.s b/tests/ppc/asm/instr_vctsxs.s new file mode 100644 index 0000000..1738de9 --- /dev/null +++ b/tests/ppc/asm/instr_vctsxs.s @@ -0,0 +1,71 @@ +# 0 * 2^31 +test_vctsxs_1: + #_ REGISTER_IN v0 [00000000, 00000000, 00000000, 00000000] + vctsxs v3, v0, 31 + blr + #_ REGISTER_OUT v0 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + +# -0 ^ 2^31 +test_vctsxs_2: + #_ REGISTER_IN v0 [80000000, 80000000, 80000000, 80000000] + vctsxs v3, v0, 31 + blr + #_ REGISTER_OUT v0 [80000000, 80000000, 80000000, 80000000] + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + +# smallest positive subnormal * 2^31 +test_vctsxs_3: + #_ REGISTER_IN v0 [00000001, 00000001, 00000001, 00000001] + vctsxs v3, v0, 31 + blr + #_ REGISTER_OUT v0 [00000001, 00000001, 00000001, 00000001] + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + +# largest subnormal * 2^31 +test_vctsxs_4: + #_ REGISTER_IN v0 [007FFFFF, 007FFFFF, 007FFFFF, 007FFFFF] + vctsxs v3, v0, 31 + blr + #_ REGISTER_OUT v0 [007FFFFF, 007FFFFF, 007FFFFF, 007FFFFF] + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + +# +1 * 2^0 +test_vctsxs_5: + #_ REGISTER_IN v0 [3F800000, 3F800000, 3F800000, 3F800000] + vctsxs v3, v0, 0 + blr + #_ REGISTER_OUT v0 [3F800000, 3F800000, 3F800000, 3F800000] + #_ REGISTER_OUT v3 [00000001, 00000001, 00000001, 00000001] + +# -1 * 2^0 +test_vctsxs_6: + #_ REGISTER_IN v0 [BF800000, BF800000, BF800000, BF800000] + vctsxs v3, v0, 0 + blr + #_ REGISTER_OUT v0 [BF800000, BF800000, BF800000, BF800000] + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + +# 2^31 * 2^0 +test_vctsxs_7: + #_ REGISTER_IN v0 [4F000000, 4F000000, 4F000000, 4F000000] + vctsxs v3, v0, 0 + blr + #_ REGISTER_OUT v0 [4F000000, 4F000000, 4F000000, 4F000000] + #_ REGISTER_OUT v3 [7FFFFFFF, 7FFFFFFF, 7FFFFFFF, 7FFFFFFF] + +# +infinity * 2^0 +test_vctsxs_8: + #_ REGISTER_IN v0 [7F800000, 7F800000, 7F800000, 7F800000] + vctsxs v3, v0, 0 + blr + #_ REGISTER_OUT v0 [7F800000, 7F800000, 7F800000, 7F800000] + #_ REGISTER_OUT v3 [7FFFFFFF, 7FFFFFFF, 7FFFFFFF, 7FFFFFFF] + +# -infinity * 2^0 +test_vctsxs_9: + #_ REGISTER_IN v0 [FF800000, FF800000, FF800000, FF800000] + vctsxs v3, v0, 0 + blr + #_ REGISTER_OUT v0 [FF800000, FF800000, FF800000, FF800000] + #_ REGISTER_OUT v3 [80000000, 80000000, 80000000, 80000000] diff --git a/tests/ppc/asm/instr_vctuxs.s b/tests/ppc/asm/instr_vctuxs.s new file mode 100644 index 0000000..f3f6e66 --- /dev/null +++ b/tests/ppc/asm/instr_vctuxs.s @@ -0,0 +1,87 @@ +# 0 * 2^31 +test_vctuxs_1: + #_ REGISTER_IN v0 [00000000, 00000000, 00000000, 00000000] + vctuxs v3, v0, 31 + blr + #_ REGISTER_OUT v0 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + +# -0 ^ 2^31 +test_vctuxs_2: + #_ REGISTER_IN v0 [80000000, 80000000, 80000000, 80000000] + vctuxs v3, v0, 31 + blr + #_ REGISTER_OUT v0 [80000000, 80000000, 80000000, 80000000] + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + +# smallest positive subnormal * 2^31 +test_vctuxs_3: + #_ REGISTER_IN v0 [00000001, 00000001, 00000001, 00000001] + vctuxs v3, v0, 31 + blr + #_ REGISTER_OUT v0 [00000001, 00000001, 00000001, 00000001] + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + +# largest subnormal * 2^31 +test_vctuxs_4: + #_ REGISTER_IN v0 [007FFFFF, 007FFFFF, 007FFFFF, 007FFFFF] + vctuxs v3, v0, 31 + blr + #_ REGISTER_OUT v0 [007FFFFF, 007FFFFF, 007FFFFF, 007FFFFF] + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + +# +1 * 2^0 +test_vctuxs_5: + #_ REGISTER_IN v0 [3F800000, 3F800000, 3F800000, 3F800000] + vctuxs v3, v0, 0 + blr + #_ REGISTER_OUT v0 [3F800000, 3F800000, 3F800000, 3F800000] + #_ REGISTER_OUT v3 [00000001, 00000001, 00000001, 00000001] + +# -1 * 2^0 +test_vctuxs_6: + #_ REGISTER_IN v0 [BF800000, BF800000, BF800000, BF800000] + vctuxs v3, v0, 0 + blr + #_ REGISTER_OUT v0 [BF800000, BF800000, BF800000, BF800000] + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + +# 2^31 * 2^0 +test_vctuxs_7: + #_ REGISTER_IN v0 [4F000000, 4F000000, 4F000000, 4F000000] + vctuxs v3, v0, 0 + blr + #_ REGISTER_OUT v0 [4F000000, 4F000000, 4F000000, 4F000000] + #_ REGISTER_OUT v3 [80000000, 80000000, 80000000, 80000000] + +# 2^31 * 1.5 * 2^0 +test_vctuxs_8: + #_ REGISTER_IN v0 [4F400000, 4F400000, 4F400000, 4F400000] + vctuxs v3, v0, 0 + blr + #_ REGISTER_OUT v0 [4F400000, 4F400000, 4F400000, 4F400000] + #_ REGISTER_OUT v3 [C0000000, C0000000, C0000000, C0000000] + +# 2^32 * 2^0 +test_vctuxs_9: + #_ REGISTER_IN v0 [4F800000, 4F800000, 4F800000, 4F800000] + vctuxs v3, v0, 0 + blr + #_ REGISTER_OUT v0 [4F800000, 4F800000, 4F800000, 4F800000] + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + +# +infinity * 2^0 +test_vctuxs_10: + #_ REGISTER_IN v0 [7F800000, 7F800000, 7F800000, 7F800000] + vctuxs v3, v0, 0 + blr + #_ REGISTER_OUT v0 [7F800000, 7F800000, 7F800000, 7F800000] + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + +# -infinity * 2^0 +test_vctuxs_11: + #_ REGISTER_IN v0 [FF800000, FF800000, FF800000, FF800000] + vctuxs v3, v0, 0 + blr + #_ REGISTER_OUT v0 [FF800000, FF800000, FF800000, FF800000] + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] diff --git a/tests/ppc/asm/instr_vexptefp.s b/tests/ppc/asm/instr_vexptefp.s new file mode 100644 index 0000000..ae85683 --- /dev/null +++ b/tests/ppc/asm/instr_vexptefp.s @@ -0,0 +1,6 @@ +test_vexptefp_1: + #_ REGISTER_IN v3 [40000000, 40400000, 40800000, 40A00000] + vexptefp v4, v3 + blr + #_ REGISTER_OUT v3 [40000000, 40400000, 40800000, 40A00000] + #_ REGISTER_OUT v4 [40800000, 41000000, 41800000, 42000000] diff --git a/tests/ppc/asm/instr_vmaddfp.s b/tests/ppc/asm/instr_vmaddfp.s new file mode 100644 index 0000000..74005af --- /dev/null +++ b/tests/ppc/asm/instr_vmaddfp.s @@ -0,0 +1,39 @@ +test_vmaddfp_1: + #_ REGISTER_IN v4 [3f800000, 3fc00000, 3f8ccccd, 3ff33333] + # 1.0, 1.5, 1.1, 1.9 + vmaddfp v3, v4, v4, v4 + blr + #_ REGISTER_OUT v3 [40000000, 40700000, 4013d70a, 40b051eb] + #_ REGISTER_OUT v4 [3f800000, 3fc00000, 3f8ccccd, 3ff33333] + # 2.0, 3.75, 2.31, 5.51 + # 40b051eb is actually 5.50999975, not 5.51? + # 40b051ec is 5.51 + +test_vmaddfp_2: + #_ REGISTER_IN v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_IN v5 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_IN v6 [3f800000, 3f800000, 3f800000, 3f800000] + # 1.0, 1.5, 1.1, 1.9 + vmaddfp v3, v4, v5, v6 + blr + #_ REGISTER_OUT v3 [40000000, 40000000, 40000000, 40000000] + #_ REGISTER_OUT v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_OUT v5 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_OUT v6 [3f800000, 3f800000, 3f800000, 3f800000] + +test_vmaddfp_3: + # v4 = 5, 5, 1, 1 + # v5 = 5, 5, 1, 1 + # v6 = 1, 1, 1, 1 + #_ REGISTER_IN v4 [40a00000, 40a00000, 3f800000, 3f800000] + #_ REGISTER_IN v5 [40a00000, 40a00000, 3f800000, 3f800000] + #_ REGISTER_IN v6 [3f800000, 3f800000, 3f800000, 3f800000] + # 1.0, 1.5, 1.1, 1.9 + vmaddfp v3, v4, v5, v6 + blr + # v3 = 26.0, 26.0, 2.0, 2.0 + #_ REGISTER_OUT v3 [41d00000, 41d00000, 40000000, 40000000] + #_ REGISTER_OUT v4 [40a00000, 40a00000, 3f800000, 3f800000] + #_ REGISTER_OUT v5 [40a00000, 40a00000, 3f800000, 3f800000] + #_ REGISTER_OUT v6 [3f800000, 3f800000, 3f800000, 3f800000] + \ No newline at end of file diff --git a/tests/ppc/asm/instr_vmaxfp.s b/tests/ppc/asm/instr_vmaxfp.s new file mode 100644 index 0000000..2da29fd --- /dev/null +++ b/tests/ppc/asm/instr_vmaxfp.s @@ -0,0 +1,10 @@ +test_vmaxfp_1: + # v3 = [10.0, -10.0, 15.0, -15.0] + # v4 = [-10.0, 20.0, -20.0, 30.0] + #_ REGISTER_IN v3 [41200000, C1200000, 41700000, C1700000] + #_ REGISTER_IN v4 [C1200000, 41A00000, C1A00000, 41F00000] + vmaxfp v0, v3, v4 + blr + #_ REGISTER_OUT v0 [41200000, 41A00000, 41700000, 41F00000] + #_ REGISTER_OUT v3 [41200000, C1200000, 41700000, C1700000] + #_ REGISTER_OUT v4 [C1200000, 41A00000, C1A00000, 41F00000] diff --git a/tests/ppc/asm/instr_vmaxfp128.s b/tests/ppc/asm/instr_vmaxfp128.s new file mode 100644 index 0000000..fa86a87 --- /dev/null +++ b/tests/ppc/asm/instr_vmaxfp128.s @@ -0,0 +1,10 @@ +test_vmaxfp128_1: + # v3 = [10.0, -10.0, 15.0, -15.0] + # v4 = [-10.0, 20.0, -20.0, 30.0] + #_ REGISTER_IN v3 [41200000, C1200000, 41700000, C1700000] + #_ REGISTER_IN v4 [C1200000, 41A00000, C1A00000, 41F00000] + vmaxfp128 v0, v3, v4 + blr + #_ REGISTER_OUT v0 [41200000, 41A00000, 41700000, 41F00000] + #_ REGISTER_OUT v3 [41200000, C1200000, 41700000, C1700000] + #_ REGISTER_OUT v4 [C1200000, 41A00000, C1A00000, 41F00000] diff --git a/tests/ppc/asm/instr_vmaxsh.s b/tests/ppc/asm/instr_vmaxsh.s new file mode 100644 index 0000000..80f47c5 --- /dev/null +++ b/tests/ppc/asm/instr_vmaxsh.s @@ -0,0 +1,17 @@ +test_vmaxsh_1: + #_ REGISTER_IN v3 [00000001, 00020003, 00040005, 80060007] + #_ REGISTER_IN v4 [00080009, 000A000B, 000C000D, 000E000F] + vmaxsh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000001, 00020003, 00040005, 80060007] + #_ REGISTER_OUT v4 [00080009, 000A000B, 000C000D, 000E000F] + #_ REGISTER_OUT v5 [00080009, 000A000B, 000C000D, 000E000F] + +test_vmaxsh_2: + #_ REGISTER_IN v3 [00000009, 0002000B, 0004000D, 0006000F] + #_ REGISTER_IN v4 [00080001, 000A0003, 000C0005, 000E0007] + vmaxsh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000009, 0002000B, 0004000D, 0006000F] + #_ REGISTER_OUT v4 [00080001, 000A0003, 000C0005, 000E0007] + #_ REGISTER_OUT v5 [00080009, 000A000B, 000C000D, 000E000F] diff --git a/tests/ppc/asm/instr_vmaxuh.s b/tests/ppc/asm/instr_vmaxuh.s new file mode 100644 index 0000000..a12d26f --- /dev/null +++ b/tests/ppc/asm/instr_vmaxuh.s @@ -0,0 +1,17 @@ +test_vmaxuh_1: + #_ REGISTER_IN v3 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_IN v4 [00080009, 000A000B, 000C000D, 800E000F] + vmaxuh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_OUT v4 [00080009, 000A000B, 000C000D, 800E000F] + #_ REGISTER_OUT v5 [00080009, 000A000B, 000C000D, 800E000F] + +test_vmaxuh_2: + #_ REGISTER_IN v3 [00000009, 0002000B, 0004000D, 0006000F] + #_ REGISTER_IN v4 [00080001, 000A0003, 000C0005, 000E0007] + vmaxuh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000009, 0002000B, 0004000D, 0006000F] + #_ REGISTER_OUT v4 [00080001, 000A0003, 000C0005, 000E0007] + #_ REGISTER_OUT v5 [00080009, 000A000B, 000C000D, 000E000F] diff --git a/tests/ppc/asm/instr_vminfp.s b/tests/ppc/asm/instr_vminfp.s new file mode 100644 index 0000000..149859c --- /dev/null +++ b/tests/ppc/asm/instr_vminfp.s @@ -0,0 +1,10 @@ +test_vminfp_1: + # v3 = [10.0, -10.0, 15.0, -15.0] + # v4 = [-10.0, 20.0, -20.0, 30.0] + #_ REGISTER_IN v3 [41200000, C1200000, 41700000, C1700000] + #_ REGISTER_IN v4 [C1200000, 41A00000, C1A00000, 41F00000] + vminfp v0, v3, v4 + blr + #_ REGISTER_OUT v0 [C1200000, C1200000, C1A00000, C1700000] + #_ REGISTER_OUT v3 [41200000, C1200000, 41700000, C1700000] + #_ REGISTER_OUT v4 [C1200000, 41A00000, C1A00000, 41F00000] diff --git a/tests/ppc/asm/instr_vminfp128.s b/tests/ppc/asm/instr_vminfp128.s new file mode 100644 index 0000000..566dbff --- /dev/null +++ b/tests/ppc/asm/instr_vminfp128.s @@ -0,0 +1,10 @@ +test_vminfp128_1: + # v3 = [10.0, -10.0, 15.0, -15.0] + # v4 = [-10.0, 20.0, -20.0, 30.0] + #_ REGISTER_IN v3 [41200000, C1200000, 41700000, C1700000] + #_ REGISTER_IN v4 [C1200000, 41A00000, C1A00000, 41F00000] + vminfp128 v0, v3, v4 + blr + #_ REGISTER_OUT v0 [C1200000, C1200000, C1A00000, C1700000] + #_ REGISTER_OUT v3 [41200000, C1200000, 41700000, C1700000] + #_ REGISTER_OUT v4 [C1200000, 41A00000, C1A00000, 41F00000] diff --git a/tests/ppc/asm/instr_vminsh.s b/tests/ppc/asm/instr_vminsh.s new file mode 100644 index 0000000..3f69e0d --- /dev/null +++ b/tests/ppc/asm/instr_vminsh.s @@ -0,0 +1,17 @@ +test_vminsh_1: + #_ REGISTER_IN v3 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_IN v4 [00080009, 000A000B, 000C000D, 000E000F] + vminsh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_OUT v4 [00080009, 000A000B, 000C000D, 000E000F] + #_ REGISTER_OUT v5 [00000001, 00020003, 00040005, 00060007] + +test_vminsh_2: + #_ REGISTER_IN v3 [00000009, 0002000B, 0004000D, 0006000F] + #_ REGISTER_IN v4 [00080001, 000A0003, 000C0005, 000E0007] + vminsh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000009, 0002000B, 0004000D, 0006000F] + #_ REGISTER_OUT v4 [00080001, 000A0003, 000C0005, 000E0007] + #_ REGISTER_OUT v5 [00000001, 00020003, 00040005, 00060007] diff --git a/tests/ppc/asm/instr_vminuh.s b/tests/ppc/asm/instr_vminuh.s new file mode 100644 index 0000000..aaac242 --- /dev/null +++ b/tests/ppc/asm/instr_vminuh.s @@ -0,0 +1,17 @@ +test_vminuh_1: + #_ REGISTER_IN v3 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_IN v4 [00080009, 000A000B, 000C000D, 000E000F] + vminuh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_OUT v4 [00080009, 000A000B, 000C000D, 000E000F] + #_ REGISTER_OUT v5 [00000001, 00020003, 00040005, 00060007] + +test_vminuh_2: + #_ REGISTER_IN v3 [00000009, 0002000B, 0004000D, 0006000F] + #_ REGISTER_IN v4 [00080001, 000A0003, 000C0005, 000E0007] + vminuh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000009, 0002000B, 0004000D, 0006000F] + #_ REGISTER_OUT v4 [00080001, 000A0003, 000C0005, 000E0007] + #_ REGISTER_OUT v5 [00000001, 00020003, 00040005, 00060007] diff --git a/tests/ppc/asm/instr_vmrghb.s b/tests/ppc/asm/instr_vmrghb.s new file mode 100644 index 0000000..2918143 --- /dev/null +++ b/tests/ppc/asm/instr_vmrghb.s @@ -0,0 +1,17 @@ +test_vmrghb_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + vmrghb v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [00100111, 02120313, 04140515, 06160717] + +test_vmrghb_2: + #_ REGISTER_IN v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF] + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vmrghb v5, v3, v4 + blr + #_ REGISTER_OUT v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v5 [F000F101, F202F303, F404F505, F606F707] diff --git a/tests/ppc/asm/instr_vmrghh.s b/tests/ppc/asm/instr_vmrghh.s new file mode 100644 index 0000000..fd0fe16 --- /dev/null +++ b/tests/ppc/asm/instr_vmrghh.s @@ -0,0 +1,26 @@ +test_vmrghh_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + vmrghh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [00011011, 02031213, 04051415, 06071617] + +test_vmrghh_2: + #_ REGISTER_IN v3 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_IN v4 [00080009, 000A000B, 000C000D, 000E000F] + vmrghh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_OUT v4 [00080009, 000A000B, 000C000D, 000E000F] + #_ REGISTER_OUT v5 [00000008, 00010009, 0002000A, 0003000B] + +test_vmrghh_3: + #_ REGISTER_IN v3 [FFF8FFF9, FFFAFFFB, FFFCFFFD, FFFEFFFF] + #_ REGISTER_IN v4 [00000001, 00020003, 00040005, 00060007] + vmrghh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFF8FFF9, FFFAFFFB, FFFCFFFD, FFFEFFFF] + #_ REGISTER_OUT v4 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_OUT v5 [FFF80000, FFF90001, FFFA0002, FFFB0003] diff --git a/tests/ppc/asm/instr_vmrghw.s b/tests/ppc/asm/instr_vmrghw.s new file mode 100644 index 0000000..c22b74c --- /dev/null +++ b/tests/ppc/asm/instr_vmrghw.s @@ -0,0 +1,35 @@ +test_vmrghw_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + vmrghw v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [00010203, 10111213, 04050607, 14151617] + +test_vmrghw_2: + #_ REGISTER_IN v3 [00000000, 00000001, 00000002, 00000003] + #_ REGISTER_IN v4 [00000004, 00000005, 00000006, 00000007] + vmrghw v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000000, 00000001, 00000002, 00000003] + #_ REGISTER_OUT v4 [00000004, 00000005, 00000006, 00000007] + #_ REGISTER_OUT v5 [00000000, 00000004, 00000001, 00000005] + +test_vmrghw_3: + #_ REGISTER_IN v3 [C0800000, C0400000, C0000000, BF800000] + #_ REGISTER_IN v4 [00000000, 3F800000, 40000000, 40400000] + vmrghw v5, v3, v4 + blr + #_ REGISTER_OUT v3 [C0800000, C0400000, C0000000, BF800000] + #_ REGISTER_OUT v4 [00000000, 3F800000, 40000000, 40400000] + #_ REGISTER_OUT v5 [C0800000, 00000000, C0400000, 3F800000] + +test_vmrghw_4: + #_ REGISTER_IN v3 [FFFFFFFC, FFFFFFFD, FFFFFFFE, FFFFFFFF] + #_ REGISTER_IN v4 [00000000, 00000001, 00000002, 00000003] + vmrghw v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFC, FFFFFFFD, FFFFFFFE, FFFFFFFF] + #_ REGISTER_OUT v4 [00000000, 00000001, 00000002, 00000003] + #_ REGISTER_OUT v5 [FFFFFFFC, 00000000, FFFFFFFD, 00000001] diff --git a/tests/ppc/asm/instr_vmrglb.s b/tests/ppc/asm/instr_vmrglb.s new file mode 100644 index 0000000..35c6801 --- /dev/null +++ b/tests/ppc/asm/instr_vmrglb.s @@ -0,0 +1,17 @@ +test_vmrglb_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + vmrglb v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [08180919, 0a1a0b1b, 0c1c0d1d, 0e1e0f1f] + +test_vmrglb_2: + #_ REGISTER_IN v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF] + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vmrglb v5, v3, v4 + blr + #_ REGISTER_OUT v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v5 [F808F909, FA0AFB0B, FC0CFD0D, FE0EFF0F] diff --git a/tests/ppc/asm/instr_vmrglh.s b/tests/ppc/asm/instr_vmrglh.s new file mode 100644 index 0000000..d598485 --- /dev/null +++ b/tests/ppc/asm/instr_vmrglh.s @@ -0,0 +1,26 @@ +test_vmrglh_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + vmrglh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [08091819, 0a0b1a1b, 0c0d1c1d, 0e0f1e1f] + +test_vmrglh_2: + #_ REGISTER_IN v3 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_IN v4 [00080009, 000A000B, 000C000D, 000E000F] + vmrglh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_OUT v4 [00080009, 000A000B, 000C000D, 000E000F] + #_ REGISTER_OUT v5 [0004000C, 0005000D, 0006000E, 0007000F] + +test_vmrglh_3: + #_ REGISTER_IN v3 [FFF8FFF9, FFFAFFFB, FFFCFFFD, FFFEFFFF] + #_ REGISTER_IN v4 [00000001, 00020003, 00040005, 00060007] + vmrglh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFF8FFF9, FFFAFFFB, FFFCFFFD, FFFEFFFF] + #_ REGISTER_OUT v4 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_OUT v5 [FFFC0004, FFFD0005, FFFE0006, FFFF0007] diff --git a/tests/ppc/asm/instr_vmrglw.s b/tests/ppc/asm/instr_vmrglw.s new file mode 100644 index 0000000..6ecfda7 --- /dev/null +++ b/tests/ppc/asm/instr_vmrglw.s @@ -0,0 +1,35 @@ +test_vmrglw_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + vmrglw v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [08090a0b, 18191a1b, 0c0d0e0f, 1c1d1e1f] + +test_vmrglw_2: + #_ REGISTER_IN v3 [00000000, 00000001, 00000002, 00000003] + #_ REGISTER_IN v4 [00000004, 00000005, 00000006, 00000007] + vmrglw v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000000, 00000001, 00000002, 00000003] + #_ REGISTER_OUT v4 [00000004, 00000005, 00000006, 00000007] + #_ REGISTER_OUT v5 [00000002, 00000006, 00000003, 00000007] + +test_vmrglw_3: + #_ REGISTER_IN v3 [C0800000, C0400000, C0000000, BF800000] + #_ REGISTER_IN v4 [00000000, 3F800000, 40000000, 40400000] + vmrglw v5, v3, v4 + blr + #_ REGISTER_OUT v3 [C0800000, C0400000, C0000000, BF800000] + #_ REGISTER_OUT v4 [00000000, 3F800000, 40000000, 40400000] + #_ REGISTER_OUT v5 [C0000000, 40000000, BF800000, 40400000] + +test_vmrglw_4: + #_ REGISTER_IN v3 [FFFFFFFC, FFFFFFFD, FFFFFFFE, FFFFFFFF] + #_ REGISTER_IN v4 [00000000, 00000001, 00000002, 00000003] + vmrglw v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFC, FFFFFFFD, FFFFFFFE, FFFFFFFF] + #_ REGISTER_OUT v4 [00000000, 00000001, 00000002, 00000003] + #_ REGISTER_OUT v5 [FFFFFFFE, 00000002, FFFFFFFF, 00000003] diff --git a/tests/ppc/asm/instr_vmsum3fp128.s b/tests/ppc/asm/instr_vmsum3fp128.s new file mode 100644 index 0000000..f88cf8a --- /dev/null +++ b/tests/ppc/asm/instr_vmsum3fp128.s @@ -0,0 +1,10 @@ +test_vmsum3fp128_1: + # v3 = [1.0, 1.5, 1.1, 0.0] + # v4 = [2.0, 3.75, 2.31, 0.0] + #_ REGISTER_IN v3 [3f800000, 3fc00000, 3f8ccccd, 01020304] + #_ REGISTER_IN v4 [40000000, 40700000, 4013d70a, 01020304] + vmsum3fp128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [3f800000, 3fc00000, 3f8ccccd, 01020304] + #_ REGISTER_OUT v4 [40000000, 40700000, 4013d70a, 01020304] + #_ REGISTER_OUT v5 [4122A7F0, 4122A7F0, 4122A7F0, 4122A7F0] diff --git a/tests/ppc/asm/instr_vmsum4fp128.s b/tests/ppc/asm/instr_vmsum4fp128.s new file mode 100644 index 0000000..4243dd0 --- /dev/null +++ b/tests/ppc/asm/instr_vmsum4fp128.s @@ -0,0 +1,8 @@ +test_vmsum4fp128_1: + #_ REGISTER_IN v3 [3f800000, 3fc00000, 3f8ccccd, 3ff33333] + #_ REGISTER_IN v4 [40000000, 40700000, 4013d70a, 40b051eb] + vmsum4fp128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [3f800000, 3fc00000, 3f8ccccd, 3ff33333] + #_ REGISTER_OUT v4 [40000000, 40700000, 4013d70a, 40b051eb] + #_ REGISTER_OUT v5 [41A5147B, 41A5147B, 41A5147B, 41A5147B] diff --git a/tests/ppc/asm/instr_vor.s b/tests/ppc/asm/instr_vor.s new file mode 100644 index 0000000..466b09d --- /dev/null +++ b/tests/ppc/asm/instr_vor.s @@ -0,0 +1,8 @@ +test_vor_1: + #_ REGISTER_IN v3 [FFFF0101, 7070FFFF, FFFFFFFF, 00000000] + #_ REGISTER_IN v4 [80081010, 808F0000, 00000000, 8FFFFFFF] + vor v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFF0101, 7070FFFF, FFFFFFFF, 00000000] + #_ REGISTER_OUT v4 [80081010, 808F0000, 00000000, 8FFFFFFF] + #_ REGISTER_OUT v5 [FFFF1111, F0FFFFFF, FFFFFFFF, 8FFFFFFF] diff --git a/tests/ppc/asm/instr_vor128.s b/tests/ppc/asm/instr_vor128.s new file mode 100644 index 0000000..cb978ea --- /dev/null +++ b/tests/ppc/asm/instr_vor128.s @@ -0,0 +1,8 @@ +test_vor128_1: + #_ REGISTER_IN v3 [FFFF0101, 7070FFFF, FFFFFFFF, 00000000] + #_ REGISTER_IN v4 [80081010, 808F0000, 00000000, 8FFFFFFF] + vor128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFF0101, 7070FFFF, FFFFFFFF, 00000000] + #_ REGISTER_OUT v4 [80081010, 808F0000, 00000000, 8FFFFFFF] + #_ REGISTER_OUT v5 [FFFF1111, F0FFFFFF, FFFFFFFF, 8FFFFFFF] diff --git a/tests/ppc/asm/instr_vperm.s b/tests/ppc/asm/instr_vperm.s new file mode 100644 index 0000000..c8d7f32 --- /dev/null +++ b/tests/ppc/asm/instr_vperm.s @@ -0,0 +1,56 @@ +test_vperm_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [00000000, 00000000, 00000000, 00000000] + vperm v6, v3, v4, v5 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_OUT v6 [00000000, 00000000, 00000000, 00000000] + +test_vperm_2: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [01010101, 01010101, 01010101, 01010101] + vperm v6, v3, v4, v5 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [01010101, 01010101, 01010101, 01010101] + #_ REGISTER_OUT v6 [01010101, 01010101, 01010101, 01010101] + +test_vperm_3: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [11111111, 11111111, 11111111, 11111111] + vperm v6, v3, v4, v5 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [11111111, 11111111, 11111111, 11111111] + #_ REGISTER_OUT v6 [11111111, 11111111, 11111111, 11111111] + +test_vperm_4: + # try with > 32b values (should mod) + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [21212121, 21212121, 21212121, 21212121] + vperm v6, v3, v4, v5 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [21212121, 21212121, 21212121, 21212121] + #_ REGISTER_OUT v6 [01010101, 01010101, 01010101, 01010101] + +test_vperm_5: + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v5 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v6 [01020003, 14150001, 1F1C1D1E, 00141518] + vperm v3, v4, v5, v6 + blr + #_ REGISTER_OUT v3 [01020003, 14150001, 1F1C1D1E, 00141518] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v5 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v6 [01020003, 14150001, 1F1C1D1E, 00141518] + \ No newline at end of file diff --git a/tests/ppc/asm/instr_vpermwi128.s b/tests/ppc/asm/instr_vpermwi128.s new file mode 100644 index 0000000..158a0e6 --- /dev/null +++ b/tests/ppc/asm/instr_vpermwi128.s @@ -0,0 +1,35 @@ +test_vpermwi128_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + # to 0,1,2,3 + # vpermwi128 v4, v3, 0x1B + .long 0x189B1A10 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vpermwi128_2: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + # to 3,2,1,0 + # vpermwi128 v4, v3, 0xE4 + .long 0x18841BD0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [0C0D0E0F, 08090A0B, 04050607, 00010203] + +test_vpermwi128_3: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + # to 0,0,0,0 + # vpermwi128 v4, v3, 0 + .long 0x18801A10 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [00010203, 00010203, 00010203, 00010203] + +test_vpermwi128_4: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + # to 3,3,3,3 + # vpermwi128 v4, v3, 0xFF + .long 0x189F1BD0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [0C0D0E0F, 0C0D0E0F, 0C0D0E0F, 0C0D0E0F] diff --git a/tests/ppc/asm/instr_vpkd3d128.s b/tests/ppc/asm/instr_vpkd3d128.s new file mode 100644 index 0000000..e4acd59 --- /dev/null +++ b/tests/ppc/asm/instr_vpkd3d128.s @@ -0,0 +1,258 @@ +# vpkd3d128 dest, src, type, mask, shift +# type: +# 0 = PACK_TYPE_D3DCOLOR +# 1 = PACK_TYPE_SHORT_2 +# 2 = PACK_TYPE_2_10_10_10 +# 3 = PACK_TYPE_FLOAT16_2 +# 4 = PACK_TYPE_SHORT_4 +# 5 = PACK_TYPE_FLOAT16_4 +# mask: +# must not be zero +# 1 = 00000000 00000000 00000000 FFFFFFFF +# 2 = 00000000 00000000 FFFFFFFF FFFFFFFF +# 3 = same as 2? except mask3/shift3 +# shift: +# 0 = no shift +# 1 = shift left by one word +# 2 ... +# 3 ... +# special case: mask3/shift3 = 00000000 00000000 00000000 FFFFFFFF + +# vpkd3d128 is broken in binutils, so these are hand coded + +test_vpkd3d128_d3dcolor_invalid_0: + #_ REGISTER_IN v3 [00000001, 00000002, 00000003, 00000004] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 0, 1, 0 + .long 0x18811E10 + blr + #_ REGISTER_OUT v3 [00000001, 00000002, 00000003, 00000004] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 00000000] +test_vpkd3d128_d3dcolor_invalid_1: + #_ REGISTER_IN v3 [40800000, 40000000, C2F60000, 4B3BDF83] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 0, 1, 0 + .long 0x18811E10 + blr + #_ REGISTER_OUT v3 [40800000, 40000000, C2F60000, 4B3BDF83] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, FFFF0000] +test_vpkd3d128_d3dcolor_invalid_2: + #_ REGISTER_IN v3 [40800000, 40000000, C2F60000, FFFFFFFF] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 0, 1, 0 + .long 0x18811E10 + blr + #_ REGISTER_OUT v3 [40800000, 40000000, C2F60000, FFFFFFFF] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 00FF0000] + +test_vpkd3d128_d3dcolor_1_0: + #_ REGISTER_IN v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 0, 1, 0 + .long 0x18811E10 + blr + #_ REGISTER_OUT v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 04010203] +test_vpkd3d128_d3dcolor_1_1: + #_ REGISTER_IN v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 0, 1, 1 + .long 0x18811E50 + blr + #_ REGISTER_OUT v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, 04010203, CDCDCDCD] +test_vpkd3d128_d3dcolor_1_2: + #_ REGISTER_IN v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 0, 1, 2 + .long 0x18811E90 + blr + #_ REGISTER_OUT v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_OUT v4 [CDCDCDCD, 04010203, CDCDCDCD, CDCDCDCD] +test_vpkd3d128_d3dcolor_1_3: + #_ REGISTER_IN v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 0, 1, 3 + .long 0x18811ED0 + blr + #_ REGISTER_OUT v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_OUT v4 [04010203, CDCDCDCD, CDCDCDCD, CDCDCDCD] + +test_vpkd3d128_d3dcolor_2_0: + #_ REGISTER_IN v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 0, 2, 0 + .long 0x18821E10 + blr + #_ REGISTER_OUT v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, 00000000, 04010203] +test_vpkd3d128_d3dcolor_2_1: + #_ REGISTER_IN v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 0, 2, 1 + .long 0x18821E50 + blr + #_ REGISTER_OUT v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_OUT v4 [CDCDCDCD, 00000000, 04010203, CDCDCDCD] +test_vpkd3d128_d3dcolor_2_2: + #_ REGISTER_IN v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 0, 2, 2 + .long 0x18821E90 + blr + #_ REGISTER_OUT v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_OUT v4 [00000000, 04010203, CDCDCDCD, CDCDCDCD] +test_vpkd3d128_d3dcolor_2_3: + #_ REGISTER_IN v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 0, 2, 3 + .long 0x18821ED0 + blr + #_ REGISTER_OUT v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_OUT v4 [04010203, CDCDCDCD, CDCDCDCD, CDCDCDCD] + +test_vpkd3d128_d3dcolor_3_0: + #_ REGISTER_IN v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 0, 3, 0 + .long 0x18831E10 + blr + #_ REGISTER_OUT v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, 00000000, 04010203] +test_vpkd3d128_d3dcolor_3_1: + #_ REGISTER_IN v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 0, 3, 1 + .long 0x18831E50 + blr + #_ REGISTER_OUT v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_OUT v4 [CDCDCDCD, 00000000, 04010203, CDCDCDCD] +test_vpkd3d128_d3dcolor_3_2: + #_ REGISTER_IN v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 0, 3, 2 + .long 0x18831E90 + blr + #_ REGISTER_OUT v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_OUT v4 [00000000, 04010203, CDCDCDCD, CDCDCDCD] +test_vpkd3d128_d3dcolor_3_3: + #_ REGISTER_IN v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 0, 3, 3 + .long 0x18831ED0 + blr + #_ REGISTER_OUT v3 [40400001, 40400002, 40400003, 40400004] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 00000000] + + +test_vpkd3d128_short2_invalid_0: + #_ REGISTER_IN v3 [43817E00, C37CFC00, 42A23EC8, 403DB757] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 1, 1, 0 + .long 0x18851E10 + blr + #_ REGISTER_OUT v3 [43817E00, C37CFC00, 42A23EC8, 403DB757] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 7FFF8001] +test_vpkd3d128_short2_invalid_1: + #_ REGISTER_IN v3 [412FDF00, C09FBE00, 42A23EC8, 403DB757] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 1, 1, 0 + .long 0x18851E10 + blr + #_ REGISTER_OUT v3 [412FDF00, C09FBE00, 42A23EC8, 403DB757] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 7FFF8001] + +test_vpkd3d128_short2_0: + #_ REGISTER_IN v3 [40407FFF, 403F8001, 00000000, 00000000] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 1, 1, 0 + .long 0x18851E10 + blr + #_ REGISTER_OUT v3 [40407FFF, 403F8001, 00000000, 00000000] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 7FFF8001] +test_vpkd3d128_short2_1: + #_ REGISTER_IN v3 [40404000, 403FC000, 40400003, 403F8001] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 1, 1, 0 + .long 0x18851E10 + blr + #_ REGISTER_OUT v3 [40404000, 403FC000, 40400003, 403F8001] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 4000C000] +test_vpkd3d128_short2_2: + #_ REGISTER_IN v3 [4040FFFE, 403FF333, 42A23EC8, 403DB757] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 1, 1, 0 + .long 0x18851E10 + blr + #_ REGISTER_OUT v3 [4040FFFE, 403FF333, 42A23EC8, 403DB757] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 7FFFF333] + +test_vpkd3d128_short4_0: + # v3 = [1.5, -1.5, 1.5, -1.5] + #_ REGISTER_IN v3 [403F8001, 403FFFF8, 4040007F, 40400000] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 4, 2, 0 + .long 0x18921E10 + blr + #_ REGISTER_OUT v3 [403F8001, 403FFFF8, 4040007F, 40400000] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, 8001FFF8, 007F0000] + +test_vpkd3d128_uint_2101010_0: + #_ REGISTER_IN v3 [B8FF8000, B8FF8000, C04001FF, 4E9A5A5A] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 2, 1, 0 + .long 0x18891E10 + blr + #_ REGISTER_OUT v3 [B8FF8000, B8FF8000, C04001FF, 4E9A5A5A] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, E0180601] +test_vpkd3d128_uint_2101010_1: + #_ REGISTER_IN v3 [42C80000, C2C80000, 40400000, 3F800000] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 2, 1, 0 + .long 0x18891E10 + blr + #_ REGISTER_OUT v3 [42C80000, C2C80000, 40400000, 3F800000] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 000805FF] +test_vpkd3d128_uint_2101010_2: + #_ REGISTER_IN v3 [3F000000, BF000000, 3F800000, 00000000] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 2, 1, 0 + .long 0x18891E10 + blr + #_ REGISTER_OUT v3 [3F000000, BF000000, 3F800000, 00000000] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 20180601] + + +test_vpkd3d128_float16_2_invalid_0: + #_ REGISTER_IN v3 [3FC00000, BFC00000, 42A23EC8, 403DB757] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 3, 1, 0 + .long 0x188D1E10 + blr + #_ REGISTER_OUT v3 [3FC00000, BFC00000, 42A23EC8, 403DB757] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 3E00BE00] +test_vpkd3d128_float16_2_0: + #_ REGISTER_IN v3 [3F000000, BF000000, 00000000, 00000000] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 3, 1, 0 + .long 0x188D1E10 + blr + #_ REGISTER_OUT v3 [3F000000, BF000000, 00000000, 00000000] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 3800B800] + +test_vpkd3d128_float16_4_invalid_0: + #_ REGISTER_IN v3 [3FC00000, BFC00000, 3FC00000, BFC00000] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 5, 2, 0 + .long 0x18961E10 + blr + #_ REGISTER_OUT v3 [3FC00000, BFC00000, 3FC00000, BFC00000] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, 3E00BE00, 3E00BE00] +test_vpkd3d128_float16_4_0: + #_ REGISTER_IN v3 [3F000000, BF000000, 3F800000, BF800000] + #_ REGISTER_IN v4 [CDCDCDCD, CDCDCDCD, CDCDCDCD, CDCDCDCD] + # vpkd3d128 v4, v3, 5, 2, 0 + .long 0x18961E10 + blr + #_ REGISTER_OUT v3 [3F000000, BF000000, 3F800000, BF800000] + #_ REGISTER_OUT v4 [CDCDCDCD, CDCDCDCD, 3800B800, 3C00BC00] diff --git a/tests/ppc/asm/instr_vpkpx.s b/tests/ppc/asm/instr_vpkpx.s new file mode 100644 index 0000000..9775799 --- /dev/null +++ b/tests/ppc/asm/instr_vpkpx.s @@ -0,0 +1,9 @@ +#vpkpx isn't implemented yet +#test_vpkpx_1: +# #_ REGISTER_IN v3 [00101820, 01283038, 00404850, 01586068] +# #_ REGISTER_IN v4 [01707880, 00889098, 01A0A8B0, 00B8C0C8] +# vpkpx v5, v3, v4 +# blr +# #_ REGISTER_OUT v3 [00101820, 01283038, 00404850, 01586068] +# #_ REGISTER_OUT v4 [01707880, 00889098, 01A0A8B0, 00B8C0C8] +# #_ REGISTER_OUT v5 [086494C7, 212AAD8D, B9F04653, D2B65F19] diff --git a/tests/ppc/asm/instr_vpkshss.s b/tests/ppc/asm/instr_vpkshss.s new file mode 100644 index 0000000..385cc1d --- /dev/null +++ b/tests/ppc/asm/instr_vpkshss.s @@ -0,0 +1,30 @@ +test_vpkshss_1: + #_ REGISTER_IN v3 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_IN v4 [00080009, 000A000B, 000C000D, 000E000F] + vpkshss v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_OUT v4 [00080009, 000A000B, 000C000D, 000E000F] + #_ REGISTER_OUT v5 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vpkshss_2: + #_ REGISTER_IN v3 [7FFF8000, 00020003, 00040005, 00060007] + #_ REGISTER_IN v4 [7FFF8000, 000A000B, 000C000D, 000E000F] + vpkshss v5, v3, v4 + blr + #_ REGISTER_OUT v3 [7FFF8000, 00020003, 00040005, 00060007] + #_ REGISTER_OUT v4 [7FFF8000, 000A000B, 000C000D, 000E000F] + #_ REGISTER_OUT v5 [7F800203, 04050607, 7F800A0B, 0C0D0E0F] + +test_vpkshss_3: + # {-1, -128, 0, 127, -2, -129, 1, 128} + #_ REGISTER_IN v3 [FFFFFF80, 0000007F, FFFEFF7F, 00010080] + # {-3, -130, 2, 129, -4, -131, 3, 130} + #_ REGISTER_IN v4 [FFFDFF7E, 00020081, FFFCFF7D, 00030082] + vpkshss v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFF80, 0000007F, FFFEFF7F, 00010080] + #_ REGISTER_OUT v4 [FFFDFF7E, 00020081, FFFCFF7D, 00030082] + # {-1, -128, 0, 127, -2, -128, 1, 127, + # -3, -128, 2, 127, -4, -128, 3, 127} + #_ REGISTER_OUT v5 [FF80007F, FE80017F, FD80027F, FC80037F] diff --git a/tests/ppc/asm/instr_vpkshss128.s b/tests/ppc/asm/instr_vpkshss128.s new file mode 100644 index 0000000..6fbe6e5 --- /dev/null +++ b/tests/ppc/asm/instr_vpkshss128.s @@ -0,0 +1,30 @@ +test_vpkshss128_1: + #_ REGISTER_IN v3 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_IN v4 [00080009, 000A000B, 000C000D, 000E000F] + vpkshss128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_OUT v4 [00080009, 000A000B, 000C000D, 000E000F] + #_ REGISTER_OUT v5 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vpkshss128_2: + #_ REGISTER_IN v3 [7FFF8000, 00020003, 00040005, 00060007] + #_ REGISTER_IN v4 [7FFF8000, 000A000B, 000C000D, 000E000F] + vpkshss128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [7FFF8000, 00020003, 00040005, 00060007] + #_ REGISTER_OUT v4 [7FFF8000, 000A000B, 000C000D, 000E000F] + #_ REGISTER_OUT v5 [7F800203, 04050607, 7F800A0B, 0C0D0E0F] + +test_vpkshss128_3: + # {-1, -128, 0, 127, -2, -129, 1, 128} + #_ REGISTER_IN v3 [FFFFFF80, 0000007F, FFFEFF7F, 00010080] + # {-3, -130, 2, 129, -4, -131, 3, 130} + #_ REGISTER_IN v4 [FFFDFF7E, 00020081, FFFCFF7D, 00030082] + vpkshss128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFF80, 0000007F, FFFEFF7F, 00010080] + #_ REGISTER_OUT v4 [FFFDFF7E, 00020081, FFFCFF7D, 00030082] + # {-1, -128, 0, 127, -2, -128, 1, 127, + # -3, -128, 2, 127, -4, -128, 3, 127} + #_ REGISTER_OUT v5 [FF80007F, FE80017F, FD80027F, FC80037F] diff --git a/tests/ppc/asm/instr_vpkshus.s b/tests/ppc/asm/instr_vpkshus.s new file mode 100644 index 0000000..8e8a6c7 --- /dev/null +++ b/tests/ppc/asm/instr_vpkshus.s @@ -0,0 +1,11 @@ +test_vpkshus_1: + # {-1, -128, 0, 127, -2, -129, 1, 128} + #_ REGISTER_IN v3 [FFFFFF80, 0000007F, FFFEFF7F, 00010080] + # {-3, -130, 2, 129, -4, -131, 3, 130} + #_ REGISTER_IN v4 [FFFDFF7E, 00020081, FFFCFF7D, 00030082] + vpkshus v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFF80, 0000007F, FFFEFF7F, 00010080] + #_ REGISTER_OUT v4 [FFFDFF7E, 00020081, FFFCFF7D, 00030082] + # {0, 0, 0, 127, 0, 0, 1, 128, 0, 0, 2, 129, 0, 0, 3, 130} + #_ REGISTER_OUT v5 [0000007F, 00000180, 00000281, 00000382] diff --git a/tests/ppc/asm/instr_vpkshus128.s b/tests/ppc/asm/instr_vpkshus128.s new file mode 100644 index 0000000..12cca20 --- /dev/null +++ b/tests/ppc/asm/instr_vpkshus128.s @@ -0,0 +1,11 @@ +test_vpkshus128_1: + # {-1, -128, 0, 127, -2, -129, 1, 128} + #_ REGISTER_IN v3 [FFFFFF80, 0000007F, FFFEFF7F, 00010080] + # {-3, -130, 2, 129, -4, -131, 3, 130} + #_ REGISTER_IN v4 [FFFDFF7E, 00020081, FFFCFF7D, 00030082] + vpkshus128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFF80, 0000007F, FFFEFF7F, 00010080] + #_ REGISTER_OUT v4 [FFFDFF7E, 00020081, FFFCFF7D, 00030082] + # {0, 0, 0, 127, 0, 0, 1, 128, 0, 0, 2, 129, 0, 0, 3, 130} + #_ REGISTER_OUT v5 [0000007F, 00000180, 00000281, 00000382] diff --git a/tests/ppc/asm/instr_vpkswss.s b/tests/ppc/asm/instr_vpkswss.s new file mode 100644 index 0000000..6820e5b --- /dev/null +++ b/tests/ppc/asm/instr_vpkswss.s @@ -0,0 +1,29 @@ +test_vpkswss_1: + #_ REGISTER_IN v3 [00000001, 00000002, 00000003, 00000004] + #_ REGISTER_IN v4 [00000005, 00000006, 00000007, 00000008] + vpkswss v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000001, 00000002, 00000003, 00000004] + #_ REGISTER_OUT v4 [00000005, 00000006, 00000007, 00000008] + #_ REGISTER_OUT v5 [00010002, 00030004, 00050006, 00070008] + +test_vpkswss_2: + #_ REGISTER_IN v3 [7FFFFFFF, 80000000, 00000000, 00000004] + #_ REGISTER_IN v4 [7FFFFFFF, 80000000, 00000000, 00000008] + vpkswss v5, v3, v4 + blr + #_ REGISTER_OUT v3 [7FFFFFFF, 80000000, 00000000, 00000004] + #_ REGISTER_OUT v4 [7FFFFFFF, 80000000, 00000000, 00000008] + #_ REGISTER_OUT v5 [7FFF8000, 00000004, 7FFF8000, 00000008] + +test_vpkswss_3: + # {-1, -32768, 0, 32767} + #_ REGISTER_IN v3 [FFFFFFFF, FFFF8000, 00000000, 00007FFF] + # {-2, -32769, 1, 32768} + #_ REGISTER_IN v4 [FFFFFFFE, FFFF7FFF, 00000001, 00008000] + vpkswss v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFF8000, 00000000, 00007FFF] + #_ REGISTER_OUT v4 [FFFFFFFE, FFFF7FFF, 00000001, 00008000] + # {-1, -32768, 0, 32767, -2, -32768, 1, 32767} + #_ REGISTER_OUT v5 [FFFF8000, 00007FFF, FFFE8000, 00017FFF] diff --git a/tests/ppc/asm/instr_vpkswss128.s b/tests/ppc/asm/instr_vpkswss128.s new file mode 100644 index 0000000..82fdbd4 --- /dev/null +++ b/tests/ppc/asm/instr_vpkswss128.s @@ -0,0 +1,29 @@ +test_vpkswss128_1: + #_ REGISTER_IN v3 [00000001, 00000002, 00000003, 00000004] + #_ REGISTER_IN v4 [00000005, 00000006, 00000007, 00000008] + vpkswss128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000001, 00000002, 00000003, 00000004] + #_ REGISTER_OUT v4 [00000005, 00000006, 00000007, 00000008] + #_ REGISTER_OUT v5 [00010002, 00030004, 00050006, 00070008] + +test_vpkswss128_2: + #_ REGISTER_IN v3 [7FFFFFFF, 80000000, 00000000, 00000004] + #_ REGISTER_IN v4 [7FFFFFFF, 80000000, 00000000, 00000008] + vpkswss128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [7FFFFFFF, 80000000, 00000000, 00000004] + #_ REGISTER_OUT v4 [7FFFFFFF, 80000000, 00000000, 00000008] + #_ REGISTER_OUT v5 [7FFF8000, 00000004, 7FFF8000, 00000008] + +test_vpkswss128_3: + # {-1, -32768, 0, 32767} + #_ REGISTER_IN v3 [FFFFFFFF, FFFF8000, 00000000, 00007FFF] + # {-2, -32769, 1, 32768} + #_ REGISTER_IN v4 [FFFFFFFE, FFFF7FFF, 00000001, 00008000] + vpkswss128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFF8000, 00000000, 00007FFF] + #_ REGISTER_OUT v4 [FFFFFFFE, FFFF7FFF, 00000001, 00008000] + # {-1, -32768, 0, 32767, -2, -32768, 1, 32767} + #_ REGISTER_OUT v5 [FFFF8000, 00007FFF, FFFE8000, 00017FFF] diff --git a/tests/ppc/asm/instr_vpkswus.s b/tests/ppc/asm/instr_vpkswus.s new file mode 100644 index 0000000..26fd724 --- /dev/null +++ b/tests/ppc/asm/instr_vpkswus.s @@ -0,0 +1,11 @@ +test_vpkswus_1: + # {-1, -32768, 0, 32767} + #_ REGISTER_IN v3 [FFFFFFFF, FFFF8000, 00000000, 00007FFF] + # {-2, -32769, 1, 32768} + #_ REGISTER_IN v4 [FFFFFFFE, FFFF7FFF, 00000001, 00008000] + vpkswus v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFF8000, 00000000, 00007FFF] + #_ REGISTER_OUT v4 [FFFFFFFE, FFFF7FFF, 00000001, 00008000] + # {0, 0, 0, 32767, 0, 0, 1, 32768} + #_ REGISTER_OUT v5 [00000000, 00007FFF, 00000000, 00018000] diff --git a/tests/ppc/asm/instr_vpkswus128.s b/tests/ppc/asm/instr_vpkswus128.s new file mode 100644 index 0000000..d1c43c3 --- /dev/null +++ b/tests/ppc/asm/instr_vpkswus128.s @@ -0,0 +1,11 @@ +test_vpkswus128_1: + # {-1, -32768, 0, 32767} + #_ REGISTER_IN v3 [FFFFFFFF, FFFF8000, 00000000, 00007FFF] + # {-2, -32769, 1, 32768} + #_ REGISTER_IN v4 [FFFFFFFE, FFFF7FFF, 00000001, 00008000] + vpkswus128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFF8000, 00000000, 00007FFF] + #_ REGISTER_OUT v4 [FFFFFFFE, FFFF7FFF, 00000001, 00008000] + # {0, 0, 0, 32767, 0, 0, 1, 32768} + #_ REGISTER_OUT v5 [00000000, 00007FFF, 00000000, 00018000] diff --git a/tests/ppc/asm/instr_vpkuhum.s b/tests/ppc/asm/instr_vpkuhum.s new file mode 100644 index 0000000..d81dbaf --- /dev/null +++ b/tests/ppc/asm/instr_vpkuhum.s @@ -0,0 +1,35 @@ +test_vpkuhum_1: + # {0, 1, 2, 3, 4, 5, 6, 7} + #_ REGISTER_IN v3 [00000001, 00020003, 00040005, 00060007] + # {8, 9, 10, 11, 12, 13, 14, 15} + #_ REGISTER_IN v4 [00080009, 000A000B, 000C000D, 000E000F] + vpkuhum v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000001, 00020003, 00040005, 00060007] + #_ REGISTER_OUT v4 [00080009, 000A000B, 000C000D, 000E000F] + # {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} + #_ REGISTER_OUT v5 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vpkuhum_2: + # {-8, -7, -6, -5, -4, -3, -2, -1} + #_ REGISTER_IN v3 [FFF8FFF9, FFFAFFFB, FFFCFFFD, FFFEFFFF] + # {0, 1, 2, 3, 4, 5, 6, 7} + #_ REGISTER_IN v4 [00000001, 00020003, 00040005, 00060007] + vpkuhum v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFF8FFF9, FFFAFFFB, FFFCFFFD, FFFEFFFF] + #_ REGISTER_OUT v4 [00000001, 00020003, 00040005, 00060007] + # {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7} + #_ REGISTER_OUT v5 [F8F9FAFB, FCFDFEFF, 00010203, 04050607] + +test_vpkuhum_3: + # {0, 65535, 65535, 0, 0, 0, 65535, 0} + #_ REGISTER_IN v3 [0000FFFF, FFFF0000, 00000000, FFFF0000] + # {65535, 0, 0, 65535, 65535, 65535, 0, 65535} + #_ REGISTER_IN v4 [FFFF0000, 0000FFFF, FFFFFFFF, 0000FFFF] + vpkuhum v5, v3, v4 + blr + #_ REGISTER_OUT v3 [0000FFFF, FFFF0000, 00000000, FFFF0000] + #_ REGISTER_OUT v4 [FFFF0000, 0000FFFF, FFFFFFFF, 0000FFFF] + # {0, 255, 255, 0, 0, 0, 255, 0, 255, 0, 0, 255, 255, 255, 0, 255} + #_ REGISTER_OUT v5 [00FFFF00, 0000FF00, FF0000FF, FFFF00FF] diff --git a/tests/ppc/asm/instr_vpkuhum128.s b/tests/ppc/asm/instr_vpkuhum128.s new file mode 100644 index 0000000..2834ede --- /dev/null +++ b/tests/ppc/asm/instr_vpkuhum128.s @@ -0,0 +1,39 @@ +#vpkuhum128 isn't implemented yet +#test_vpkuhum128_1: +# # {0, 1, 2, 3, 4, 5, 6, 7} +# #_ REGISTER_IN v3 [00000001, 00020003, 00040005, 00060007] +# # {8, 9, 10, 11, 12, 13, 14, 15} +# #_ REGISTER_IN v4 [00080009, 000A000B, 000C000D, 000E000F] +# vpkuhum128 v5, v3, v4 +# blr +# #_ REGISTER_OUT v3 [00000001, 00020003, 00040005, 00060007] +# #_ REGISTER_OUT v4 [00080009, 000A000B, 000C000D, 000E000F] +# # {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} +# #_ REGISTER_OUT v5 [00010203, 04050607, 08090A0B, 0C0D0E0F] +# blr + +#test_vpkuhum128_2: +# # {-8, -7, -6, -5, -4, -3, -2, -1} +# #_ REGISTER_IN v3 [FFF8FFF9, FFFAFFFB, FFFCFFFD, FFFEFFFF] +# # {0, 1, 2, 3, 4, 5, 6, 7} +# #_ REGISTER_IN v4 [00000001, 00020003, 00040005, 00060007] +# vpkuhum128 v5, v3, v4 +# blr +# #_ REGISTER_OUT v3 [FFF8FFF9, FFFAFFFB, FFFCFFFD, FFFEFFFF] +# #_ REGISTER_OUT v4 [00000001, 00020003, 00040005, 00060007] +# # {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7} +# #_ REGISTER_OUT v5 [F8F9FAFB, FCFDFEFF, 00010203, 04050607] +# blr + +#test_vpkuhum128_3: +# # {0, 65535, 65535, 0, 0, 0, 65535, 0} +# #_ REGISTER_IN v3 [0000FFFF, FFFF0000, 00000000, FFFF0000] +# # {65535, 0, 0, 65535, 65535, 65535, 0, 65535} +# #_ REGISTER_IN v4 [FFFF0000, 0000FFFF, FFFFFFFF, 0000FFFF] +# vpkuhum128 v5, v3, v4 +# blr +# #_ REGISTER_OUT v3 [0000FFFF, FFFF0000, 00000000, FFFF0000] +# #_ REGISTER_OUT v4 [FFFF0000, 0000FFFF, FFFFFFFF, 0000FFFF] +# # {0, 255, 255, 0, 0, 0, 255, 0, 255, 0, 0, 255, 255, 255, 0, 255} +# #_ REGISTER_OUT v5 [00FFFF00, 0000FF00, FF0000FF, FFFF00FF] +# blr diff --git a/tests/ppc/asm/instr_vpkuhus.s b/tests/ppc/asm/instr_vpkuhus.s new file mode 100644 index 0000000..7b4c2a3 --- /dev/null +++ b/tests/ppc/asm/instr_vpkuhus.s @@ -0,0 +1,11 @@ +test_vpkuhus_1: + # {0, 256, 1, 257, 2, 258, 3, 259} + #_ REGISTER_IN v3 [00000100, 00010101, 00020102, 00030103] + # {4, 260, 5, 261, 6, 262, 7, 263} + #_ REGISTER_IN v4 [00040104, 00050105, 00060106, 00070107] + vpkuhus v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000100, 00010101, 00020102, 00030103] + #_ REGISTER_OUT v4 [00040104, 00050105, 00060106, 00070107] + # {0, 255, 1, 255, 2, 255, 3, 255, 4, 255, 5, 255, 6, 255, 7, 255} + #_ REGISTER_OUT v5 [00FF01FF, 02FF03FF, 04FF05FF, 06FF07FF] diff --git a/tests/ppc/asm/instr_vpkuhus128.s b/tests/ppc/asm/instr_vpkuhus128.s new file mode 100644 index 0000000..dc2135d --- /dev/null +++ b/tests/ppc/asm/instr_vpkuhus128.s @@ -0,0 +1,11 @@ +test_vpkuhus128_1: + # {0, 256, 1, 257, 2, 258, 3, 259} + #_ REGISTER_IN v3 [00000100, 00010101, 00020102, 00030103] + # {4, 260, 5, 261, 6, 262, 7, 263} + #_ REGISTER_IN v4 [00040104, 00050105, 00060106, 00070107] + vpkuhus128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000100, 00010101, 00020102, 00030103] + #_ REGISTER_OUT v4 [00040104, 00050105, 00060106, 00070107] + # {0, 255, 1, 255, 2, 255, 3, 255, 4, 255, 5, 255, 6, 255, 7, 255} + #_ REGISTER_OUT v5 [00FF01FF, 02FF03FF, 04FF05FF, 06FF07FF] diff --git a/tests/ppc/asm/instr_vpkuwum.s b/tests/ppc/asm/instr_vpkuwum.s new file mode 100644 index 0000000..66116f7 --- /dev/null +++ b/tests/ppc/asm/instr_vpkuwum.s @@ -0,0 +1,35 @@ +test_vpkuwum_1: + # {0, 1, 2, 3} + #_ REGISTER_IN v3 [00000000, 00000001, 00000002, 00000003] + # {4, 5, 6, 7} + #_ REGISTER_IN v4 [00000004, 00000005, 00000006, 00000007] + vpkuwum v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000000, 00000001, 00000002, 00000003] + #_ REGISTER_OUT v4 [00000004, 00000005, 00000006, 00000007] + # {0, 1, 2, 3, 4, 5, 6, 7} + #_ REGISTER_OUT v5 [00000001, 00020003, 00040005, 00060007] + +test_vpkuwum_2: + # {-4, -3, -2, -1} + #_ REGISTER_IN v3 [FFFFFFFC, FFFFFFFD, FFFFFFFE, FFFFFFFF] + # {0, 1, 2, 3} + #_ REGISTER_IN v4 [00000000, 00000001, 00000002, 00000003] + vpkuwum v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFC, FFFFFFFD, FFFFFFFE, FFFFFFFF] + #_ REGISTER_OUT v4 [00000000, 00000001, 00000002, 00000003] + # {-4, -3, -2, -1, 0, 1, 2, 3} + #_ REGISTER_OUT v5 [FFFCFFFD, FFFEFFFF, 00000001, 00020003] + +test_vpkuwum_3: + # {0, 4294967295, 4294967295, 4294967295} + #_ REGISTER_IN v3 [00000000, FFFFFFFF, FFFFFFFF, FFFFFFFF] + # {4294967295, 0, 0, 0} + #_ REGISTER_IN v4 [FFFFFFFF, 00000000, 00000000, 00000000] + vpkuwum v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000000, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_OUT v4 [FFFFFFFF, 00000000, 00000000, 00000000] + # {0, 65535, 65535, 65535, 65535, 0, 0, 0} + #_ REGISTER_OUT v5 [0000FFFF, FFFFFFFF, FFFF0000, 00000000] diff --git a/tests/ppc/asm/instr_vpkuwum128.s b/tests/ppc/asm/instr_vpkuwum128.s new file mode 100644 index 0000000..b7149c0 --- /dev/null +++ b/tests/ppc/asm/instr_vpkuwum128.s @@ -0,0 +1,35 @@ +test_vpkuwum128_1: + # {0, 1, 2, 3} + #_ REGISTER_IN v3 [00000000, 00000001, 00000002, 00000003] + # {4, 5, 6, 7} + #_ REGISTER_IN v4 [00000004, 00000005, 00000006, 00000007] + vpkuwum128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000000, 00000001, 00000002, 00000003] + #_ REGISTER_OUT v4 [00000004, 00000005, 00000006, 00000007] + # {0, 1, 2, 3, 4, 5, 6, 7} + #_ REGISTER_OUT v5 [00000001, 00020003, 00040005, 00060007] + +test_vpkuwum128_2: + # {-4, -3, -2, -1} + #_ REGISTER_IN v3 [FFFFFFFC, FFFFFFFD, FFFFFFFE, FFFFFFFF] + # {0, 1, 2, 3} + #_ REGISTER_IN v4 [00000000, 00000001, 00000002, 00000003] + vpkuwum128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFC, FFFFFFFD, FFFFFFFE, FFFFFFFF] + #_ REGISTER_OUT v4 [00000000, 00000001, 00000002, 00000003] + # {-4, -3, -2, -1, 0, 1, 2, 3} + #_ REGISTER_OUT v5 [FFFCFFFD, FFFEFFFF, 00000001, 00020003] + +test_vpkuwum128_3: + # {0, 4294967295, 4294967295, 4294967295} + #_ REGISTER_IN v3 [00000000, FFFFFFFF, FFFFFFFF, FFFFFFFF] + # {4294967295, 0, 0, 0} + #_ REGISTER_IN v4 [FFFFFFFF, 00000000, 00000000, 00000000] + vpkuwum128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000000, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_OUT v4 [FFFFFFFF, 00000000, 00000000, 00000000] + # {0, 65535, 65535, 65535, 65535, 0, 0, 0} + #_ REGISTER_OUT v5 [0000FFFF, FFFFFFFF, FFFF0000, 00000000] diff --git a/tests/ppc/asm/instr_vpkuwus.s b/tests/ppc/asm/instr_vpkuwus.s new file mode 100644 index 0000000..7f117c1 --- /dev/null +++ b/tests/ppc/asm/instr_vpkuwus.s @@ -0,0 +1,23 @@ +test_vpkuwus_1: + # {0, 65536, 1, 65537} + #_ REGISTER_IN v3 [00000000, 00010000, 00000001, 00010001] + # {2, 65538, 3, 65539} + #_ REGISTER_IN v4 [00000002, 00010002, 00000003, 00010003] + vpkuwus v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000000, 00010000, 00000001, 00010001] + #_ REGISTER_OUT v4 [00000002, 00010002, 00000003, 00010003] + # {0, 65535, 1, 65535, 2, 65535, 3, 65535} + #_ REGISTER_OUT v5 [0000FFFF, 0001FFFF, 0002FFFF, 0003FFFF] + +test_vpkuwus_2: + # {2147483648, 2147483647, 2, 3} + #_ REGISTER_IN v3 [80000000, 7FFFFFFF, 00000002, 00000003] + # {4294967295, 65538, 4294967294, 16} + #_ REGISTER_IN v4 [FFFFFFFF, 00010002, FFFFFFFE, 00000010] + vpkuwus v5, v3, v4 + blr + #_ REGISTER_OUT v3 [80000000, 7FFFFFFF, 00000002, 00000003] + #_ REGISTER_OUT v4 [FFFFFFFF, 00010002, FFFFFFFE, 00000010] + # {65535, 65535, 2, 3, 65535, 65535, 65535, 16} + #_ REGISTER_OUT v5 [FFFFFFFF, 00020003, FFFFFFFF, FFFF0010] diff --git a/tests/ppc/asm/instr_vpkuwus128.s b/tests/ppc/asm/instr_vpkuwus128.s new file mode 100644 index 0000000..3313589 --- /dev/null +++ b/tests/ppc/asm/instr_vpkuwus128.s @@ -0,0 +1,23 @@ +test_vpkuwus128_1: + # {0, 65536, 1, 65537} + #_ REGISTER_IN v3 [00000000, 00010000, 00000001, 00010001] + # {2, 65538, 3, 65539} + #_ REGISTER_IN v4 [00000002, 00010002, 00000003, 00010003] + vpkuwus128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00000000, 00010000, 00000001, 00010001] + #_ REGISTER_OUT v4 [00000002, 00010002, 00000003, 00010003] + # {0, 65535, 1, 65535, 2, 65535, 3, 65535} + #_ REGISTER_OUT v5 [0000FFFF, 0001FFFF, 0002FFFF, 0003FFFF] + +test_vpkuwus128_2: + # {2147483648, 2147483647, 2, 3} + #_ REGISTER_IN v3 [80000000, 7FFFFFFF, 00000002, 00000003] + # {4294967295, 65538, 4294967294, 16} + #_ REGISTER_IN v4 [FFFFFFFF, 00010002, FFFFFFFE, 00000010] + vpkuwus128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [80000000, 7FFFFFFF, 00000002, 00000003] + #_ REGISTER_OUT v4 [FFFFFFFF, 00010002, FFFFFFFE, 00000010] + # {65535, 65535, 2, 3, 65535, 65535, 65535, 16} + #_ REGISTER_OUT v5 [FFFFFFFF, 00020003, FFFFFFFF, FFFF0010] diff --git a/tests/ppc/asm/instr_vrfin.s b/tests/ppc/asm/instr_vrfin.s new file mode 100644 index 0000000..cf31be5 --- /dev/null +++ b/tests/ppc/asm/instr_vrfin.s @@ -0,0 +1,13 @@ +test_vrfin_1: + #_ REGISTER_IN v3 [3f800000, 3fc00000, 3f8ccccd, 3ff33333] + # 1.0, 1.5, 1.1, 1.9 -> 1.0, 2.0, 1.0, 2.0 + vrfin v3, v3 + blr + #_ REGISTER_OUT v3 [3f800000, 40000000, 3f800000, 40000000] + +test_vrfin_2: + #_ REGISTER_IN v3 [bf800000, bfc00000, bf8ccccd, bff33333] + # -1.0, -1.5, -1.1, -1.9 -> -1.0, -2.0, -1.0, -2.0 + vrfin v3, v3 + blr + #_ REGISTER_OUT v3 [bf800000, c0000000, bf800000, c0000000] diff --git a/tests/ppc/asm/instr_vrlh.s b/tests/ppc/asm/instr_vrlh.s new file mode 100644 index 0000000..1ea7f62 --- /dev/null +++ b/tests/ppc/asm/instr_vrlh.s @@ -0,0 +1,8 @@ +test_vrlh_1: + #_ REGISTER_IN v3 [12345678, 87654321, 11223344, 55667788] + #_ REGISTER_IN v4 [000D000D, 000D000D, 000D000D, 000D000D] + vrlh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [12345678, 87654321, 11223344, 55667788] + #_ REGISTER_OUT v4 [000D000D, 000D000D, 000D000D, 000D000D] + #_ REGISTER_OUT v5 [82460ACF, B0EC2864, 42248668, CAAC0EF1] diff --git a/tests/ppc/asm/instr_vrlimi128.s b/tests/ppc/asm/instr_vrlimi128.s new file mode 100644 index 0000000..55a128d --- /dev/null +++ b/tests/ppc/asm/instr_vrlimi128.s @@ -0,0 +1,75 @@ +test_vrlimi128_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + vrlimi128 v4, v3, 0, 0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + +test_vrlimi128_2: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + vrlimi128 v4, v3, 0xF, 0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vrlimi128_3: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + # assember is busted here: + # vrlimi128 v4, v3, 0xF, 1 + .long 0x188f1f50 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [04050607, 08090A0B, 0C0D0E0F, 00010203] + +test_vrlimi128_4: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + vrlimi128 v4, v3, 0xF, 2 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [08090A0B, 0C0D0E0F, 00010203, 04050607] + +test_vrlimi128_5: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + # assember is busted here: + # vrlimi128 v4, v3, 0xF, 3 + .long 0x188f1fd0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [0C0D0E0F, 00010203, 04050607, 08090A0B] + +test_vrlimi128_6: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + vrlimi128 v4, v3, 0x8, 0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [00010203, CCCCCCCC, CCCCCCCC, CCCCCCCC] + +test_vrlimi128_7: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + vrlimi128 v4, v3, 0x4, 0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [CCCCCCCC, 04050607, CCCCCCCC, CCCCCCCC] + +test_vrlimi128_8: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + vrlimi128 v4, v3, 0x2, 0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [CCCCCCCC, CCCCCCCC, 08090A0B, CCCCCCCC] + +test_vrlimi128_9: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + vrlimi128 v4, v3, 0x1, 0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, 0C0D0E0F] diff --git a/tests/ppc/asm/instr_vsel.s b/tests/ppc/asm/instr_vsel.s new file mode 100644 index 0000000..e9fe43d --- /dev/null +++ b/tests/ppc/asm/instr_vsel.s @@ -0,0 +1,49 @@ +test_vsel_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [00000000, 00000000, 00000000, 00000000] + vsel v5, v3, v4, v5 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vsel_2: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + vsel v5, v3, v4, v5 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [10111213, 14151617, 18191A1B, 1C1D1E1F] + +test_vsel_3: + #_ REGISTER_IN v3 [0C010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [1D111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [10101010, 10101010, 10101010, 10101010] + vsel v5, v3, v4, v5 + blr + #_ REGISTER_OUT v3 [0C010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [1D111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [1C111213, 14151617, 18191A1B, 1C1D1E1F] + +test_vsel_4: + #_ REGISTER_IN v3 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_IN v4 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v5 [01234567, 89ABCDEF, FEDCBA98, 76543210] + vsel v5, v3, v4, v5 + blr + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_OUT v4 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_OUT v5 [01234567, 89ABCDEF, FEDCBA98, 76543210] + +test_vsel_5: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_IN v5 [01234567, 89ABCDEF, FEDCBA98, 76543210] + vsel v5, v3, v4, v5 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_OUT v4 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_OUT v5 [FEDCBA98, 76543210, 01234567, 89ABCDEF] diff --git a/tests/ppc/asm/instr_vsl.s b/tests/ppc/asm/instr_vsl.s new file mode 100644 index 0000000..48d847a --- /dev/null +++ b/tests/ppc/asm/instr_vsl.s @@ -0,0 +1,31 @@ +test_vsl_1: + #_ REGISTER_IN v3 [FEFEFEFE, FEFEFEFE, FEFEFEFE, FEFEFEFE] + #_ REGISTER_IN v4 [04040404, 04040404, 04040404, 04040404] + vsl v3, v3, v4 + blr + #_ REGISTER_OUT v3 [EFEFEFEF, EFEFEFEF, EFEFEFEF, EFEFEFE0] + #_ REGISTER_OUT v4 [04040404, 04040404, 04040404, 04040404] + +test_vsl_2: + #_ REGISTER_IN v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_IN v4 [04040404, 04040404, 04040404, 04040404] + vsl v3, v3, v4 + blr + #_ REGISTER_OUT v3 [01122334, 45566778, 899AABBC, CDDEEFF0] + #_ REGISTER_OUT v4 [04040404, 04040404, 04040404, 04040404] + +test_vsl_3: + #_ REGISTER_IN v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_IN v4 [07070707, 07070707, 07070707, 07070707] + vsl v3, v3, v4 + blr + #_ REGISTER_OUT v3 [089119A2, 2AB33BC4, 4CD55DE6, 6EF77F80] + #_ REGISTER_OUT v4 [07070707, 07070707, 07070707, 07070707] + +test_vsl_4: + #_ REGISTER_IN v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_IN v4 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + vsl v3, v3, v4 + blr + #_ REGISTER_OUT v3 [089119A2, 2AB33BC4, 4CD55DE6, 6EF77F80] + #_ REGISTER_OUT v4 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] diff --git a/tests/ppc/asm/instr_vslb.s b/tests/ppc/asm/instr_vslb.s new file mode 100644 index 0000000..818f1d2 --- /dev/null +++ b/tests/ppc/asm/instr_vslb.s @@ -0,0 +1,39 @@ +test_vslb_1: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00000000, 00000000, 00000000, 00000000] + vslb v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_OUT v4 [00000000, 00000000, 00000000, 00000000] + +test_vslb_2: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [01010101, 01010101, 01010101, 01010101] + vslb v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FEFEFEFE, FEFEFEFE, FEFEFEFE, FEFEFEFE] + #_ REGISTER_OUT v4 [01010101, 01010101, 01010101, 01010101] + +test_vslb_3: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [07070707, 07070707, 07070707, 07070707] + vslb v3, v3, v4 + blr + #_ REGISTER_OUT v3 [80808080, 80808080, 80808080, 80808080] + #_ REGISTER_OUT v4 [07070707, 07070707, 07070707, 07070707] + +test_vslb_4: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [08080808, 08080808, 08080808, 08080808] + vslb v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_OUT v4 [08080808, 08080808, 08080808, 08080808] + +test_vslb_5: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [09090909, 09090909, 09090909, 09090909] + vslb v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FEFEFEFE, FEFEFEFE, FEFEFEFE, FEFEFEFE] + #_ REGISTER_OUT v4 [09090909, 09090909, 09090909, 09090909] diff --git a/tests/ppc/asm/instr_vsldoi.s b/tests/ppc/asm/instr_vsldoi.s new file mode 100644 index 0000000..7ab577c --- /dev/null +++ b/tests/ppc/asm/instr_vsldoi.s @@ -0,0 +1,29 @@ +test_vsldoi_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [00000000, 00000000, 00000000, 00000000] + vsldoi v5, v3, v4, 0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vsldoi_2: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [00000000, 00000000, 00000000, 00000000] + vsldoi v5, v3, v4, 1 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [01020304, 05060708, 090A0B0C, 0D0E0F10] + +test_vsldoi_3: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [00000000, 00000000, 00000000, 00000000] + vsldoi v5, v3, v4, 0xF + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [0F101112, 13141516, 1718191A, 1B1C1D1E] diff --git a/tests/ppc/asm/instr_vslh.s b/tests/ppc/asm/instr_vslh.s new file mode 100644 index 0000000..d29d666 --- /dev/null +++ b/tests/ppc/asm/instr_vslh.s @@ -0,0 +1,47 @@ +test_vslh_1: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00000000, 00000000, 00000000, 00000000] + vslh v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_OUT v4 [00000000, 00000000, 00000000, 00000000] + +test_vslh_2: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00010001, 00010001, 00010001, 00010001] + vslh v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFEFFFE, FFFEFFFE, FFFEFFFE, FFFEFFFE] + #_ REGISTER_OUT v4 [00010001, 00010001, 00010001, 00010001] + +test_vslh_3: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [000F000F, 000F000F, 000F000F, 000F000F] + vslh v3, v3, v4 + blr + #_ REGISTER_OUT v3 [80008000, 80008000, 80008000, 80008000] + #_ REGISTER_OUT v4 [000F000F, 000F000F, 000F000F, 000F000F] + +test_vslh_4: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00100010, 00100010, 00100010, 00100010] + vslh v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_OUT v4 [00100010, 00100010, 00100010, 00100010] + +test_vslh_5: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00090009, 00090009, 00090009, 00090009] + vslh v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FE00FE00, FE00FE00, FE00FE00, FE00FE00] + #_ REGISTER_OUT v4 [00090009, 00090009, 00090009, 00090009] + +test_vslh_6: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00110011, 00110011, 00110011, 00110011] + vslh v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFEFFFE, FFFEFFFE, FFFEFFFE, FFFEFFFE] + #_ REGISTER_OUT v4 [00110011, 00110011, 00110011, 00110011] diff --git a/tests/ppc/asm/instr_vslo.s b/tests/ppc/asm/instr_vslo.s new file mode 100644 index 0000000..34dc03b --- /dev/null +++ b/tests/ppc/asm/instr_vslo.s @@ -0,0 +1,39 @@ +test_vslo_1: + #_ REGISTER_IN v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_IN v4 [04040404, 04040404, 04040404, 04040404] + vslo v3, v3, v4 + blr + #_ REGISTER_OUT v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_OUT v4 [04040404, 04040404, 04040404, 04040404] + +test_vslo_2: + #_ REGISTER_IN v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_IN v4 [08080808, 08080808, 08080808, 08080808] + vslo v3, v3, v4 + blr + #_ REGISTER_OUT v3 [11223344, 55667788, 99AABBCC, DDEEFF00] + #_ REGISTER_OUT v4 [08080808, 08080808, 08080808, 08080808] + +test_vslo_3: + #_ REGISTER_IN v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_IN v4 [12121212, 12121212, 12121212, 12121212] + vslo v3, v3, v4 + blr + #_ REGISTER_OUT v3 [22334455, 66778899, AABBCCDD, EEFF0000] + #_ REGISTER_OUT v4 [12121212, 12121212, 12121212, 12121212] + +test_vslo_4: + #_ REGISTER_IN v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_IN v4 [80808080, 80808080, 80808080, 80808080] + vslo v3, v3, v4 + blr + #_ REGISTER_OUT v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_OUT v4 [80808080, 80808080, 80808080, 80808080] + +test_vslo_5: + #_ REGISTER_IN v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_IN v4 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + vslo v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FF000000, 00000000, 00000000, 00000000] + #_ REGISTER_OUT v4 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] diff --git a/tests/ppc/asm/instr_vslw.s b/tests/ppc/asm/instr_vslw.s new file mode 100644 index 0000000..89013ee --- /dev/null +++ b/tests/ppc/asm/instr_vslw.s @@ -0,0 +1,47 @@ +test_vslw_1: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00000000, 00000000, 00000000, 00000000] + vslw v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_OUT v4 [00000000, 00000000, 00000000, 00000000] + +test_vslw_2: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00000001, 00000001, 00000001, 00000001] + vslw v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFE, FFFFFFFE, FFFFFFFE, FFFFFFFE] + #_ REGISTER_OUT v4 [00000001, 00000001, 00000001, 00000001] + +test_vslw_3: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [0000001F, 0000001F, 0000001F, 0000001F] + vslw v3, v3, v4 + blr + #_ REGISTER_OUT v3 [80000000, 80000000, 80000000, 80000000] + #_ REGISTER_OUT v4 [0000001F, 0000001F, 0000001F, 0000001F] + +test_vslw_4: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00000020, 00000020, 00000020, 00000020] + vslw v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_OUT v4 [00000020, 00000020, 00000020, 00000020] + +test_vslw_5: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00000009, 00000009, 00000009, 00000009] + vslw v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFE00, FFFFFE00, FFFFFE00, FFFFFE00] + #_ REGISTER_OUT v4 [00000009, 00000009, 00000009, 00000009] + +test_vslw_6: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00000021, 00000021, 00000021, 00000021] + vslw v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFE, FFFFFFFE, FFFFFFFE, FFFFFFFE] + #_ REGISTER_OUT v4 [00000021, 00000021, 00000021, 00000021] diff --git a/tests/ppc/asm/instr_vspltb.s b/tests/ppc/asm/instr_vspltb.s new file mode 100644 index 0000000..71d2197 --- /dev/null +++ b/tests/ppc/asm/instr_vspltb.s @@ -0,0 +1,20 @@ +test_vspltb_1: + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vspltb v3, v4, 0 + blr + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vspltb_2: + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vspltb v3, v4, 1 + blr + #_ REGISTER_OUT v3 [01010101, 01010101, 01010101, 01010101] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vspltb_3: + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vspltb v3, v4, 0xF + blr + #_ REGISTER_OUT v3 [0F0F0F0F, 0F0F0F0F, 0F0F0F0F, 0F0F0F0F] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] diff --git a/tests/ppc/asm/instr_vsplth.s b/tests/ppc/asm/instr_vsplth.s new file mode 100644 index 0000000..a6a382d --- /dev/null +++ b/tests/ppc/asm/instr_vsplth.s @@ -0,0 +1,20 @@ +test_vsplth_1: + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vsplth v3, v4, 0 + blr + #_ REGISTER_OUT v3 [00010001, 00010001, 00010001, 00010001] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vsplth_2: + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vsplth v3, v4, 1 + blr + #_ REGISTER_OUT v3 [02030203, 02030203, 02030203, 02030203] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vsplth_3: + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vsplth v3, v4, 7 + blr + #_ REGISTER_OUT v3 [0E0F0E0F, 0E0F0E0F, 0E0F0E0F, 0E0F0E0F] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] diff --git a/tests/ppc/asm/instr_vspltisb.s b/tests/ppc/asm/instr_vspltisb.s new file mode 100644 index 0000000..83e48c0 --- /dev/null +++ b/tests/ppc/asm/instr_vspltisb.s @@ -0,0 +1,19 @@ +test_vspltisb_1: + vspltisb v3, 0 + blr + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + +test_vspltisb_2: + vspltisb v3, 1 + blr + #_ REGISTER_OUT v3 [01010101, 01010101, 01010101, 01010101] + +test_vspltisb_3: + vspltisb v3, -1 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + +test_vspltisb_4: + vspltisb v3, -2 + blr + #_ REGISTER_OUT v3 [FEFEFEFE, FEFEFEFE, FEFEFEFE, FEFEFEFE] diff --git a/tests/ppc/asm/instr_vspltish.s b/tests/ppc/asm/instr_vspltish.s new file mode 100644 index 0000000..40ae3d6 --- /dev/null +++ b/tests/ppc/asm/instr_vspltish.s @@ -0,0 +1,19 @@ +test_vspltish_1: + vspltish v3, 0 + blr + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + +test_vspltish_2: + vspltish v3, 1 + blr + #_ REGISTER_OUT v3 [00010001, 00010001, 00010001, 00010001] + +test_vspltish_3: + vspltish v3, -1 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + +test_vspltish_4: + vspltish v3, -2 + blr + #_ REGISTER_OUT v3 [FFFEFFFE, FFFEFFFE, FFFEFFFE, FFFEFFFE] diff --git a/tests/ppc/asm/instr_vspltisw.s b/tests/ppc/asm/instr_vspltisw.s new file mode 100644 index 0000000..696544c --- /dev/null +++ b/tests/ppc/asm/instr_vspltisw.s @@ -0,0 +1,19 @@ +test_vspltisw_1: + vspltisw v3, 0 + blr + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + +test_vspltisw_2: + vspltisw v3, 1 + blr + #_ REGISTER_OUT v3 [00000001, 00000001, 00000001, 00000001] + +test_vspltisw_3: + vspltisw v3, -1 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + +test_vspltisw_4: + vspltisw v3, -2 + blr + #_ REGISTER_OUT v3 [FFFFFFFE, FFFFFFFE, FFFFFFFE, FFFFFFFE] diff --git a/tests/ppc/asm/instr_vspltw.s b/tests/ppc/asm/instr_vspltw.s new file mode 100644 index 0000000..d9f30e1 --- /dev/null +++ b/tests/ppc/asm/instr_vspltw.s @@ -0,0 +1,20 @@ +test_vspltw_1: + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vspltw v3, v4, 0 + blr + #_ REGISTER_OUT v3 [00010203, 00010203, 00010203, 00010203] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vspltw_2: + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vspltw v3, v4, 1 + blr + #_ REGISTER_OUT v3 [04050607, 04050607, 04050607, 04050607] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vspltw_3: + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vspltw v3, v4, 3 + blr + #_ REGISTER_OUT v3 [0C0D0E0F, 0C0D0E0F, 0C0D0E0F, 0C0D0E0F] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] diff --git a/tests/ppc/asm/instr_vsr.s b/tests/ppc/asm/instr_vsr.s new file mode 100644 index 0000000..d6c6a8d --- /dev/null +++ b/tests/ppc/asm/instr_vsr.s @@ -0,0 +1,31 @@ +test_vsr_1: + #_ REGISTER_IN v3 [FEFEFEFE, FEFEFEFE, FEFEFEFE, FEFEFEFE] + #_ REGISTER_IN v4 [04040404, 04040404, 04040404, 04040404] + vsr v3, v3, v4 + blr + #_ REGISTER_OUT v3 [0FEFEFEF, EFEFEFEF, EFEFEFEF, EFEFEFEF] + #_ REGISTER_OUT v4 [04040404, 04040404, 04040404, 04040404] + +test_vsr_2: + #_ REGISTER_IN v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_IN v4 [04040404, 04040404, 04040404, 04040404] + vsr v3, v3, v4 + blr + #_ REGISTER_OUT v3 [00011223, 34455667, 78899AAB, BCCDDEEF] + #_ REGISTER_OUT v4 [04040404, 04040404, 04040404, 04040404] + +test_vsr_3: + #_ REGISTER_IN v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_IN v4 [07070707, 07070707, 07070707, 07070707] + vsr v3, v3, v4 + blr + #_ REGISTER_OUT v3 [00002244, 6688AACC, EF113355, 7799BBDD] + #_ REGISTER_OUT v4 [07070707, 07070707, 07070707, 07070707] + +test_vsr_4: + #_ REGISTER_IN v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_IN v4 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + vsr v3, v3, v4 + blr + #_ REGISTER_OUT v3 [00002244, 6688AACC, EF113355, 7799BBDD] + #_ REGISTER_OUT v4 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] diff --git a/tests/ppc/asm/instr_vsrah.s b/tests/ppc/asm/instr_vsrah.s new file mode 100644 index 0000000..beb4290 --- /dev/null +++ b/tests/ppc/asm/instr_vsrah.s @@ -0,0 +1,8 @@ +test_vsrah_1: + #_ REGISTER_IN v3 [12345678, 87654321, 11223344, 55667788] + #_ REGISTER_IN v4 [000D000D, 000D000D, 000D000D, 000D000D] + vsrah v5, v3, v4 + blr + #_ REGISTER_OUT v3 [12345678, 87654321, 11223344, 55667788] + #_ REGISTER_OUT v4 [000D000D, 000D000D, 000D000D, 000D000D] + #_ REGISTER_OUT v5 [00000002, FFFC0002, 00000001, 00020003] diff --git a/tests/ppc/asm/instr_vsrh.s b/tests/ppc/asm/instr_vsrh.s new file mode 100644 index 0000000..33210f8 --- /dev/null +++ b/tests/ppc/asm/instr_vsrh.s @@ -0,0 +1,8 @@ +test_vsrh_1: + #_ REGISTER_IN v3 [12345678, 87654321, 11223344, 55667788] + #_ REGISTER_IN v4 [000D000D, 000D000D, 000D000D, 000D000D] + vsrh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [12345678, 87654321, 11223344, 55667788] + #_ REGISTER_OUT v4 [000D000D, 000D000D, 000D000D, 000D000D] + #_ REGISTER_OUT v5 [00000002, 00040002, 00000001, 00020003] diff --git a/tests/ppc/asm/instr_vsro.s b/tests/ppc/asm/instr_vsro.s new file mode 100644 index 0000000..4cc52ca --- /dev/null +++ b/tests/ppc/asm/instr_vsro.s @@ -0,0 +1,39 @@ +test_vsro_1: + #_ REGISTER_IN v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_IN v4 [04040404, 04040404, 04040404, 04040404] + vsro v3, v3, v4 + blr + #_ REGISTER_OUT v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_OUT v4 [04040404, 04040404, 04040404, 04040404] + +test_vsro_2: + #_ REGISTER_IN v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_IN v4 [08080808, 08080808, 08080808, 08080808] + vsro v3, v3, v4 + blr + #_ REGISTER_OUT v3 [00001122, 33445566, 778899AA, BBCCDDEE] + #_ REGISTER_OUT v4 [08080808, 08080808, 08080808, 08080808] + +test_vsro_3: + #_ REGISTER_IN v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_IN v4 [12121212, 12121212, 12121212, 12121212] + vsro v3, v3, v4 + blr + #_ REGISTER_OUT v3 [00000011, 22334455, 66778899, AABBCCDD] + #_ REGISTER_OUT v4 [12121212, 12121212, 12121212, 12121212] + +test_vsro_4: + #_ REGISTER_IN v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_IN v4 [80808080, 80808080, 80808080, 80808080] + vsro v3, v3, v4 + blr + #_ REGISTER_OUT v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_OUT v4 [80808080, 80808080, 80808080, 80808080] + +test_vsro_5: + #_ REGISTER_IN v3 [00112233, 44556677, 8899AABB, CCDDEEFF] + #_ REGISTER_IN v4 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + vsro v3, v3, v4 + blr + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_OUT v4 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] diff --git a/tests/ppc/asm/instr_vsubfp.s b/tests/ppc/asm/instr_vsubfp.s new file mode 100644 index 0000000..0aadf5c --- /dev/null +++ b/tests/ppc/asm/instr_vsubfp.s @@ -0,0 +1,9 @@ +test_vsubfp_1: + # v3 = [10.0, -10.0, 15.0, -15.0] + # v4 = [-10.0, 20.0, -20.0, 30.0] + #_ REGISTER_IN v3 [41200000, C1200000, 41700000, C1700000] + #_ REGISTER_IN v4 [C1200000, 41A00000, C1A00000, 41F00000] + vsubfp v3, v3, v4 + blr + #_ REGISTER_OUT v3 [41A00000, C1F00000, 420C0000, C2340000] + #_ REGISTER_OUT v4 [C1200000, 41A00000, C1A00000, 41F00000] diff --git a/tests/ppc/asm/instr_vsubfp128.s b/tests/ppc/asm/instr_vsubfp128.s new file mode 100644 index 0000000..33c01ed --- /dev/null +++ b/tests/ppc/asm/instr_vsubfp128.s @@ -0,0 +1,10 @@ +test_vsubfp128_1: + # v3 = [10.0, -10.0, 15.0, -15.0] + # v4 = [-10.0, 20.0, -20.0, 30.0] + #_ REGISTER_IN v3 [41200000, C1200000, 41700000, C1700000] + #_ REGISTER_IN v4 [C1200000, 41A00000, C1A00000, 41F00000] + vsubfp128 v0, v3, v4 + blr + #_ REGISTER_OUT v0 [41A00000, C1F00000, 420C0000, C2340000] + #_ REGISTER_OUT v3 [41200000, C1200000, 41700000, C1700000] + #_ REGISTER_OUT v4 [C1200000, 41A00000, C1A00000, 41F00000] diff --git a/tests/ppc/asm/instr_vsubshs.s b/tests/ppc/asm/instr_vsubshs.s new file mode 100644 index 0000000..d781757 --- /dev/null +++ b/tests/ppc/asm/instr_vsubshs.s @@ -0,0 +1,15 @@ +test_vsubshs_1: + #_ REGISTER_IN v3 [7FFF8001, 7FFF8003, 7FFF8005, 80068007] + #_ REGISTER_IN v4 [00018001, 10000000, 42568124, 00000000] + vsubshs v3, v3, v4 + blr + #_ REGISTER_OUT v3 [7ffe0000, 6fff8003, 3da9fee1, 80068007] + #_ REGISTER_OUT v4 [00018001, 10000000, 42568124, 00000000] + +test_vsubshs_2: + #_ REGISTER_IN v3 [7FFF8002, 7FFF8003, 7FFF8005, 80068007] + #_ REGISTER_IN v4 [FFFF0005, 10000000, 42568124, 00000000] + vsubshs v3, v3, v4 + blr + #_ REGISTER_OUT v3 [7FFF8000, 6FFF8003, 3DA9FEE1, 80068007] + #_ REGISTER_OUT v4 [FFFF0005, 10000000, 42568124, 00000000] diff --git a/tests/ppc/asm/instr_vsubuhm.s b/tests/ppc/asm/instr_vsubuhm.s new file mode 100644 index 0000000..7eb9b8a --- /dev/null +++ b/tests/ppc/asm/instr_vsubuhm.s @@ -0,0 +1,7 @@ +test_vsubuhm_1: + #_ REGISTER_IN v3 [7FFF8001, 7FFF8003, 7FFF8005, 80068007] + #_ REGISTER_IN v4 [00018001, 10000000, 42568124, 00000000] + vsubuhm v3, v3, v4 + blr + #_ REGISTER_OUT v3 [7ffe0000, 6fff8003, 3da9fee1, 80068007] + #_ REGISTER_OUT v4 [00018001, 10000000, 42568124, 00000000] diff --git a/tests/ppc/asm/instr_vupkd3d128.s b/tests/ppc/asm/instr_vupkd3d128.s new file mode 100644 index 0000000..b16b299 --- /dev/null +++ b/tests/ppc/asm/instr_vupkd3d128.s @@ -0,0 +1,80 @@ +# vupkd3d128 dest, src, type +# type: +# 0 = PACK_TYPE_D3DCOLOR +# 1 = PACK_TYPE_SHORT_2 +# 3 = PACK_TYPE_FLOAT16_2 +# 5 = PACK_TYPE_FLOAT16_4 + +# vupkd3d128 is broken in binutils, so these are hand coded + +test_vupkd3d128_d3dcolor: + #_ REGISTER_IN v3 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 04010203] + # vupkd3d128 v3, v3, 0 + .long 0x18601FF0 + blr + #_ REGISTER_OUT v3 [3f800001, 3f800002, 3f800003, 3f800004] + +test_vupkd3d128_short2_0: + #_ REGISTER_IN v3 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 7FFF8001] + # vupkd3d128 v3, v3, 1 + .long 0x18641FF0 + blr + #_ REGISTER_OUT v3 [40407fff, 403f8001, 00000000, 3f800000] +test_vupkd3d128_short2_1: + #_ REGISTER_IN v3 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 4000C000] + # vupkd3d128 v3, v3, 1 + .long 0x18641FF0 + blr + #_ REGISTER_OUT v3 [40404000, 403FC000, 00000000, 3f800000] +test_vupkd3d128_short2_2: + #_ REGISTER_IN v3 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 7FFFF333] + # vupkd3d128 v3, v3, 1 + .long 0x18641FF0 + blr + #_ REGISTER_OUT v3 [40407FFF, 403FF333, 00000000, 3f800000] +test_vupkd3d128_short2_3: + #_ REGISTER_IN v3 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 00008000] + # vupkd3d128 v3, v3, 1 + .long 0x18641FF0 + blr + #_ REGISTER_OUT v3 [40400000, 7FC00000, 00000000, 3f800000] + +test_vupkd3d128_short4_0: + #_ REGISTER_IN v3 [CDCDCDCD, CDCDCDCD, 7FFFFFFF, 007FFFF8] + # vupkd3d128 v3, v3, 4 + .long 0x18701FF0 + blr + #_ REGISTER_OUT v3 [40407FFF, 403FFFFF, 4040007F, 403FFFF8] + +test_vupkd3d128_float16_2_0: + #_ REGISTER_IN v3 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 3800B800] + # vupkd3d128 v3, v3, 3 + .long 0x186C1FF0 + blr + #_ REGISTER_OUT v3 [3F000000, BF000000, 00000000, 3f800000] + +test_vupkd3d128_float16_4_0: + #_ REGISTER_IN v3 [CDCDCDCD, CDCDCDCD, 3800B801, 3802B803] + # vupkd3d128 v3, v3, 5 + .long 0x18741FF0 + blr + #_ REGISTER_OUT v3 [3F000000, bf002000, 3f004000, bf006000] + +test_vupkd3d128_uint_2101010_0: + #_ REGISTER_IN v3 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 400001FF] + # vupkd3d128 v3, v3, 2 + .long 0x18681FF0 + blr + #_ REGISTER_OUT v3 [404001FF, 40400000, 40400000, 3F800001] +test_vupkd3d128_uint_2101010_1: + #_ REGISTER_IN v3 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 40000201] + # vupkd3d128 v3, v3, 2 + .long 0x18681FF0 + blr + #_ REGISTER_OUT v3 [403FFE01, 40400000, 40400000, 3F800001] +test_vupkd3d128_uint_2101010_2: + #_ REGISTER_IN v3 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 40000200] + # vupkd3d128 v3, v3, 2 + .long 0x18681FF0 + blr + #_ REGISTER_OUT v3 [7FC00000, 40400000, 40400000, 3F800001] diff --git a/tests/ppc/asm/instr_vupkhsb.s b/tests/ppc/asm/instr_vupkhsb.s new file mode 100644 index 0000000..e9dad4e --- /dev/null +++ b/tests/ppc/asm/instr_vupkhsb.s @@ -0,0 +1,15 @@ +test_vupkhsb_1: + # {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7} + #_ REGISTER_IN v3 [F8F9FAFB, FCFDFEFF, 00010203, 04050607] + vupkhsb v3, v3 + blr + # {-8, -7, -6, -5, -4, -3, -2, -1} + #_ REGISTER_OUT v3 [FFF8FFF9, FFFAFFFB, FFFCFFFD, FFFEFFFF] + +test_vupkhsb_2: + # {0, 255, 255, 0, 0, 0, 255, 0, 255, 0, 0, 255, 255, 255, 0, 255} + #_ REGISTER_IN v3 [00FFFF00, 0000FF00, FF0000FF, FFFF00FF] + vupkhsb v3, v3 + blr + # {0, 65535, 65535, 0, 0, 0, 65535, 0} + #_ REGISTER_OUT v3 [0000FFFF, FFFF0000, 00000000, FFFF0000] diff --git a/tests/ppc/asm/instr_vupkhsb128.s b/tests/ppc/asm/instr_vupkhsb128.s new file mode 100644 index 0000000..67ff265 --- /dev/null +++ b/tests/ppc/asm/instr_vupkhsb128.s @@ -0,0 +1,15 @@ +test_vupkhsb128_1: + # {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7} + #_ REGISTER_IN v3 [F8F9FAFB, FCFDFEFF, 00010203, 04050607] + vupkhsb128 v3, v3 + blr + # {-8, -7, -6, -5, -4, -3, -2, -1} + #_ REGISTER_OUT v3 [FFF8FFF9, FFFAFFFB, FFFCFFFD, FFFEFFFF] + +test_vupkhsb128_2: + # {0, 255, 255, 0, 0, 0, 255, 0, 255, 0, 0, 255, 255, 255, 0, 255} + #_ REGISTER_IN v3 [00FFFF00, 0000FF00, FF0000FF, FFFF00FF] + vupkhsb128 v3, v3 + blr + # {0, 65535, 65535, 0, 0, 0, 65535, 0} + #_ REGISTER_OUT v3 [0000FFFF, FFFF0000, 00000000, FFFF0000] diff --git a/tests/ppc/asm/instr_vupkhsh.s b/tests/ppc/asm/instr_vupkhsh.s new file mode 100644 index 0000000..866bc77 --- /dev/null +++ b/tests/ppc/asm/instr_vupkhsh.s @@ -0,0 +1,27 @@ +test_vupkhsh_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vupkhsh v3, v3 + blr + #_ REGISTER_OUT v3 [00000001, 00000203, 00000405, 00000607] + +test_vupkhsh_2: + #_ REGISTER_IN v3 [7F800203, 04050607, 7F800A0B, 0C0D0E0F] + vupkhsh v3, v3 + blr + #_ REGISTER_OUT v3 [00007f80, 00000203, 00000405, 00000607] + +test_vupkhsh_3: + # {0, 65535, 65535, 0, 0, 0, 65535, 0} + #_ REGISTER_IN v3 [0000FFFF, FFFF0000, 00000000, FFFF0000] + vupkhsh v3, v3 + blr + # {0, 4294967295, 4294967295, 0} + #_ REGISTER_OUT v3 [00000000, FFFFFFFF, FFFFFFFF, 00000000] + +test_vupkhsh_4: + # {-4, -3, -2, -1, 0, 1, 2, 3} + #_ REGISTER_IN v3 [FFFCFFFD, FFFEFFFF, 00000001, 00020003] + vupkhsh v3, v3 + blr + # {-4, -3, -2, -1} + #_ REGISTER_OUT v3 [FFFFFFFC, FFFFFFFD, FFFFFFFE, FFFFFFFF] diff --git a/tests/ppc/asm/instr_vupklsb.s b/tests/ppc/asm/instr_vupklsb.s new file mode 100644 index 0000000..00b212c --- /dev/null +++ b/tests/ppc/asm/instr_vupklsb.s @@ -0,0 +1,15 @@ +test_vupklsb_1: + # {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7} + #_ REGISTER_IN v3 [F8F9FAFB, FCFDFEFF, 00010203, 04050607] + vupklsb v3, v3 + blr + # {0, 1, 2, 3, 4, 5, 6, 7} + #_ REGISTER_OUT v3 [00000001, 00020003, 00040005, 00060007] + +test_vupklsb_2: + # {0, 255, 255, 0, 0, 0, 255, 0, 255, 0, 0, 255, 255, 255, 0, 255} + #_ REGISTER_IN v3 [00FFFF00, 0000FF00, FF0000FF, FFFF00FF] + vupklsb v3, v3 + blr + # {65535, 0, 0, 65535, 65535, 65535, 0, 65535} + #_ REGISTER_OUT v3 [FFFF0000, 0000FFFF, FFFFFFFF, 0000FFFF] diff --git a/tests/ppc/asm/instr_vupklsb128.s b/tests/ppc/asm/instr_vupklsb128.s new file mode 100644 index 0000000..f9e8b88 --- /dev/null +++ b/tests/ppc/asm/instr_vupklsb128.s @@ -0,0 +1,15 @@ +test_vupklsb128_1: + # {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7} + #_ REGISTER_IN v3 [F8F9FAFB, FCFDFEFF, 00010203, 04050607] + vupklsb128 v3, v3 + blr + # {0, 1, 2, 3, 4, 5, 6, 7} + #_ REGISTER_OUT v3 [00000001, 00020003, 00040005, 00060007] + +test_vupklsb128_2: + # {0, 255, 255, 0, 0, 0, 255, 0, 255, 0, 0, 255, 255, 255, 0, 255} + #_ REGISTER_IN v3 [00FFFF00, 0000FF00, FF0000FF, FFFF00FF] + vupklsb128 v3, v3 + blr + # {65535, 0, 0, 65535, 65535, 65535, 0, 65535} + #_ REGISTER_OUT v3 [FFFF0000, 0000FFFF, FFFFFFFF, 0000FFFF] diff --git a/tests/ppc/asm/instr_vupklsh.s b/tests/ppc/asm/instr_vupklsh.s new file mode 100644 index 0000000..008e96e --- /dev/null +++ b/tests/ppc/asm/instr_vupklsh.s @@ -0,0 +1,27 @@ +test_vupklsh_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vupklsh v3, v3 + blr + #_ REGISTER_OUT v3 [00000809, 00000a0b, 00000c0d, 00000e0f] + +test_vupklsh_2: + #_ REGISTER_IN v3 [7F800203, 04050607, 7F800A0B, 0C0D0E0F] + vupklsh v3, v3 + blr + #_ REGISTER_OUT v3 [00007f80, 00000a0b, 00000c0d, 00000e0f] + +test_vupklsh_3: + # {-4, -3, -2, -1, 0, 1, 2, 3} + #_ REGISTER_IN v3 [FFFCFFFD, FFFEFFFF, 00000001, 00020003] + vupklsh v3, v3 + blr + # {-4, -3, -2, -1} + #_ REGISTER_OUT v3 [00000000, 00000001, 00000002, 00000003] + +test_vupklsh_4: + # {0, 65535, 65535, 0, 0, 0, 65535, 0} + #_ REGISTER_IN v3 [0000FFFF, FFFF0000, 00000000, FFFF0000] + vupklsh v3, v3 + blr + # {0, 0, 4294967295, 0} + #_ REGISTER_OUT v3 [00000000, 00000000, FFFFFFFF, 00000000] diff --git a/tests/ppc/asm/instr_vxor.s b/tests/ppc/asm/instr_vxor.s new file mode 100644 index 0000000..51d9d53 --- /dev/null +++ b/tests/ppc/asm/instr_vxor.s @@ -0,0 +1,8 @@ +test_vxor_1: + #_ REGISTER_IN v3 [FFFF0101, 7070FFFF, FFFFFFFF, 00000000] + #_ REGISTER_IN v4 [80081010, 808F0000, 7FFFFFFF, 8FFFFFFF] + vxor v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFF0101, 7070FFFF, FFFFFFFF, 00000000] + #_ REGISTER_OUT v4 [80081010, 808F0000, 7FFFFFFF, 8FFFFFFF] + #_ REGISTER_OUT v5 [7FF71111, F0FFFFFF, 80000000, 8FFFFFFF] diff --git a/tests/ppc/asm/instr_vxor128.s b/tests/ppc/asm/instr_vxor128.s new file mode 100644 index 0000000..bfc808a --- /dev/null +++ b/tests/ppc/asm/instr_vxor128.s @@ -0,0 +1,8 @@ +test_vxor128_1: + #_ REGISTER_IN v3 [FFFF0101, 7070FFFF, FFFFFFFF, 00000000] + #_ REGISTER_IN v4 [80081010, 808F0000, 7FFFFFFF, 8FFFFFFF] + vxor128 v5, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFF0101, 7070FFFF, FFFFFFFF, 00000000] + #_ REGISTER_OUT v4 [80081010, 808F0000, 7FFFFFFF, 8FFFFFFF] + #_ REGISTER_OUT v5 [7FF71111, F0FFFFFF, 80000000, 8FFFFFFF] diff --git a/tests/ppc/asm/seq_branch_carry.s b/tests/ppc/asm/seq_branch_carry.s new file mode 100644 index 0000000..7dbe276 --- /dev/null +++ b/tests/ppc/asm/seq_branch_carry.s @@ -0,0 +1,41 @@ +test_equiv_1: + #_ REGISTER_IN r11 0x9E2A83C1 + lis r9, -0x61D6 # 0x9E2A83C1 + ori r30, r9, 0x83C1 # 0x9E2A83C1 + subf r8, r11, r30 + addic r7, r8, -1 + subfe. r29, r7, r8 + beq equiv_1_good + li r12, 0 + blr +equiv_1_good: + li r12, 1 + blr + #_ REGISTER_OUT r7 0xfffffffeffffffff + #_ REGISTER_OUT r8 0xffffffff00000000 + #_ REGISTER_OUT r9 0xffffffff9e2a0000 + #_ REGISTER_OUT r30 0xffffffff9e2a83c1 + #_ REGISTER_OUT r29 0 + #_ REGISTER_OUT r11 0x000000009e2a83c1 + #_ REGISTER_OUT r12 1 + +test_equiv_2: + #_ REGISTER_IN r11 0xffffffff9e2a83c1 + lis r9, -0x61D6 # 0x9E2A83C1 + ori r30, r9, 0x83C1 # 0x9E2A83C1 + subf r8, r11, r30 + addic r7, r8, -1 + subfe. r29, r7, r8 + beq equiv_2_good + li r12, 0 + blr +equiv_2_good: + li r12, 1 + blr + #_ REGISTER_OUT r7 0xffffffffffffffff + #_ REGISTER_OUT r8 0 + #_ REGISTER_OUT r9 0xffffffff9e2a0000 + #_ REGISTER_OUT r30 0xffffffff9e2a83c1 + #_ REGISTER_OUT r29 0 + #_ REGISTER_OUT r11 0xffffffff9e2a83c1 + #_ REGISTER_OUT r12 1 diff --git a/tests/ppc/asm/seq_jumptable_constants.s b/tests/ppc/asm/seq_jumptable_constants.s new file mode 100644 index 0000000..0d4f5e5 --- /dev/null +++ b/tests/ppc/asm/seq_jumptable_constants.s @@ -0,0 +1,47 @@ +test_jumptable: + cmpwi cr6, r3, 3 + bgt cr6, .case_3 + lis r11, .the_table@h + addi r11, r11, .the_table@l + slwi r3, r3, 2 + lwzx r3, r11, r3 + mtspr ctr, r3 + bctr +.the_table: + .long .case_0 + .long .case_1 + .long .case_2 + .long .case_3 +.case_0: + li r11, 8 + b .the_divide +.case_1: + li r11, 16 + b .the_divide +.case_2: + li r11, 24 + b .the_divide +.case_3: + li r11, 32 +.the_divide: + extsw r11, r11 + tdllei r11, 0 + divdu r4, r4, r11 + blr + +test_jumptable_constants: + mfspr r12, lr + li r3, 0 + li r4, 1024 + bl test_jumptable + li r3, 1 + li r4, 1024 + bl test_jumptable + li r3, 2 + li r4, 1024 + bl test_jumptable + li r3, 3 + li r4, 1024 + bl test_jumptable + mtspr lr, r12 + blr diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt new file mode 100644 index 0000000..65d5944 --- /dev/null +++ b/tests/unit/CMakeLists.txt @@ -0,0 +1,64 @@ +# Unit Tests for ReXGlue core components + +add_executable(unit_tests + memory/heap_allocation_test.cpp + kernel/object_table_test.cpp + core/cvar_test.cpp + core/fiber_test.cpp + core/sha256_test.cpp + core/stream_test.cpp + core/byte_order_test.cpp + core/chrono_test.cpp + codegen/config_test.cpp + codegen/template_registry_test.cpp + ppc/import_function_test.cpp + ppc/stack_test.cpp + system/guest_path_test.cpp + system/function_dispatcher_test.cpp + codegen/manifest_test.cpp + rexglue/migration_scan_test.cpp + rexglue/ui_test.cpp +) + +target_sources(unit_tests PRIVATE + ${PROJECT_SOURCE_DIR}/src/rexglue/commands/migration_scan.cpp + ${PROJECT_SOURCE_DIR}/src/rexglue/ui/ui.cpp + ${PROJECT_SOURCE_DIR}/src/rexglue/ui/progress.cpp +) + +target_include_directories(unit_tests PRIVATE + ${PROJECT_SOURCE_DIR}/include + ${PROJECT_SOURCE_DIR}/src +) + +target_link_libraries(unit_tests PRIVATE + rexcore + rexcodegen + rexruntime + Catch2::Catch2WithMain +) + +# Strip Tracy/profiling instrumentation from test targets +target_compile_options(unit_tests PRIVATE + -UTRACY_ENABLE -UREXGLUE_ENABLE_PROFILING + -UREXGLUE_ENABLE_PERF_COUNTERS -UREXGLUE_PROFILE_GUEST_FUNCTIONS +) + +set_target_properties(unit_tests PROPERTIES + RUNTIME_OUTPUT_DIRECTORY $ +) +if(UNIX AND NOT APPLE) + set_target_properties(unit_tests PROPERTIES + INSTALL_RPATH "$ORIGIN" + BUILD_WITH_INSTALL_RPATH ON + ) +endif() + +# Discover tests +include(Catch) +catch_discover_tests(unit_tests + TEST_PREFIX "unit." + PROPERTIES + LABELS "unit" + TIMEOUT 60 +) diff --git a/tests/unit/codegen/config_test.cpp b/tests/unit/codegen/config_test.cpp new file mode 100644 index 0000000..9595b35 --- /dev/null +++ b/tests/unit/codegen/config_test.cpp @@ -0,0 +1,349 @@ +/** + * @file tests/unit/codegen/config_test.cpp + * @brief Unit tests for RecompilerConfig include-based config layering + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include +#include + +#include +#include +#include + +namespace fs = std::filesystem; + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +static fs::path WriteTempToml(const fs::path& dir, const std::string& name, + const std::string& content) { + auto path = dir / name; + fs::create_directories(path.parent_path()); + std::ofstream(path) << content; + return path; +} + +// Produce a chain of N TOML files where each file includes the next. +// Returns the path to the first file in the chain (depth 0). +static fs::path WriteIncludeChain(const fs::path& dir, uint32_t length) { + // Write the leaf (no includes), then work backwards. + for (uint32_t i = length - 1; i > 0; --i) { + std::string next = "chain_" + std::to_string(i) + ".toml"; + std::string content = "includes = [\"" + next + + "\"]\n" + "file_path = \"dummy.xex\"\n"; + WriteTempToml(dir, "chain_" + std::to_string(i - 1) + ".toml", content); + } + // Leaf file + WriteTempToml(dir, "chain_" + std::to_string(length - 1) + ".toml", + "file_path = \"dummy.xex\"\n"); + return dir / "chain_0.toml"; +} + +// --------------------------------------------------------------------------- +// Test 1: Scalar override -- last (top-level) wins +// --------------------------------------------------------------------------- + +TEST_CASE("Config scalar override - last wins", "[codegen][config]") { + auto tmp = fs::temp_directory_path() / "rex_cfg_scalar"; + fs::remove_all(tmp); + fs::create_directories(tmp); + + // base.toml sets project_name and file_path + WriteTempToml(tmp, "base.toml", + "project_name = \"base_project\"\n" + "file_path = \"base.xex\"\n" + "skip_lr = false\n"); + + // top.toml includes base, then overrides project_name and skip_lr + WriteTempToml(tmp, "top.toml", + "includes = [\"base.toml\"]\n" + "project_name = \"top_project\"\n" + "file_path = \"base.xex\"\n" + "skip_lr = true\n"); + + rex::codegen::RecompilerConfig cfg; + REQUIRE(cfg.Load((tmp / "top.toml").string())); + + // Top-level values must win + CHECK(cfg.projectName == "top_project"); + CHECK(cfg.skipLr == true); + // file_path from base is not re-overridden by top (top also sets it) + CHECK(cfg.filePath == "base.xex"); + + fs::remove_all(tmp); +} + +// --------------------------------------------------------------------------- +// Test 2: Collection merge -- additive +// --------------------------------------------------------------------------- + +TEST_CASE("Config collection merge - additive", "[codegen][config]") { + auto tmp = fs::temp_directory_path() / "rex_cfg_additive"; + fs::remove_all(tmp); + fs::create_directories(tmp); + + // base.toml defines one function + WriteTempToml(tmp, "base.toml", + "file_path = \"game.xex\"\n" + "\n" + "[functions.\"82200000\"]\n" + "size = 0x100\n" + "name = \"BaseFunc\"\n"); + + // top.toml includes base and adds a second distinct function + WriteTempToml(tmp, "top.toml", + "includes = [\"base.toml\"]\n" + "file_path = \"game.xex\"\n" + "\n" + "[functions.\"82200200\"]\n" + "size = 0x80\n" + "name = \"TopFunc\"\n"); + + rex::codegen::RecompilerConfig cfg; + REQUIRE(cfg.Load((tmp / "top.toml").string())); + + // Both functions must be present + REQUIRE(cfg.functions.count(0x82200000u) == 1); + REQUIRE(cfg.functions.count(0x82200200u) == 1); + CHECK(cfg.functions.at(0x82200000u).name == "BaseFunc"); + CHECK(cfg.functions.at(0x82200200u).name == "TopFunc"); + + fs::remove_all(tmp); +} + +// --------------------------------------------------------------------------- +// Test 3: Keyed conflict -- last wins +// --------------------------------------------------------------------------- + +TEST_CASE("Config keyed conflict - last wins", "[codegen][config]") { + auto tmp = fs::temp_directory_path() / "rex_cfg_conflict"; + fs::remove_all(tmp); + fs::create_directories(tmp); + + // included.toml defines a function at address 0x82210000 + WriteTempToml(tmp, "included.toml", + "file_path = \"game.xex\"\n" + "\n" + "[functions.\"82210000\"]\n" + "size = 0x200\n" + "name = \"OldName\"\n"); + + // top.toml includes the above, then redefines the SAME address + WriteTempToml(tmp, "top.toml", + "includes = [\"included.toml\"]\n" + "file_path = \"game.xex\"\n" + "\n" + "[functions.\"82210000\"]\n" + "size = 0x400\n" + "name = \"NewName\"\n"); + + rex::codegen::RecompilerConfig cfg; + REQUIRE(cfg.Load((tmp / "top.toml").string())); + + // Only one entry for the address; top-level definition wins + REQUIRE(cfg.functions.count(0x82210000u) == 1); + CHECK(cfg.functions.at(0x82210000u).name == "NewName"); + CHECK(cfg.functions.at(0x82210000u).size == 0x400u); + + fs::remove_all(tmp); +} + +// --------------------------------------------------------------------------- +// Test 4: Array-of-table dedup -- same address, last wins +// --------------------------------------------------------------------------- + +TEST_CASE("Config switch_tables dedup - last wins", "[codegen][config]") { + auto tmp = fs::temp_directory_path() / "rex_cfg_switchtable"; + fs::remove_all(tmp); + fs::create_directories(tmp); + + // first.toml defines a switch_table at bctrAddress 0x82220000 with 2 labels + WriteTempToml(tmp, "first.toml", + "file_path = \"game.xex\"\n" + "\n" + "[[switch_tables]]\n" + "address = 0x82220000\n" + "register = 3\n" + "labels = [0x82220100, 0x82220200]\n"); + + // top.toml includes first, then redefines the SAME bctrAddress with 3 labels + WriteTempToml(tmp, "top.toml", + "includes = [\"first.toml\"]\n" + "file_path = \"game.xex\"\n" + "\n" + "[[switch_tables]]\n" + "address = 0x82220000\n" + "register = 4\n" + "labels = [0x82220100, 0x82220200, 0x82220300]\n"); + + rex::codegen::RecompilerConfig cfg; + REQUIRE(cfg.Load((tmp / "top.toml").string())); + + // One entry at the address; top-level definition wins + REQUIRE(cfg.switchTables.count(0x82220000u) == 1); + const auto& jt = cfg.switchTables.at(0x82220000u); + CHECK(jt.indexRegister == 4); + REQUIRE(jt.targets.size() == 3); + CHECK(jt.targets[2] == 0x82220300u); + + fs::remove_all(tmp); +} + +// --------------------------------------------------------------------------- +// Test 5: Circular include detection -> Load() returns false +// --------------------------------------------------------------------------- + +TEST_CASE("Config circular include detection", "[codegen][config]") { + auto tmp = fs::temp_directory_path() / "rex_cfg_circular"; + fs::remove_all(tmp); + fs::create_directories(tmp); + + // a.toml includes b.toml + WriteTempToml(tmp, "a.toml", + "file_path = \"game.xex\"\n" + "includes = [\"b.toml\"]\n"); + + // b.toml includes a.toml (cycle) + WriteTempToml(tmp, "b.toml", + "file_path = \"game.xex\"\n" + "includes = [\"a.toml\"]\n"); + + rex::codegen::RecompilerConfig cfg; + CHECK_FALSE(cfg.Load((tmp / "a.toml").string())); + + fs::remove_all(tmp); +} + +// --------------------------------------------------------------------------- +// Test 6: Max depth enforcement (chain of 33 non-cyclic files -> false) +// --------------------------------------------------------------------------- + +TEST_CASE("Config max include depth enforcement", "[codegen][config]") { + // kMaxIncludeDepth == 32; a chain of 34 files has depth 33 at the leaf. + constexpr uint32_t kChainLength = 34; + + auto tmp = fs::temp_directory_path() / "rex_cfg_maxdepth"; + fs::remove_all(tmp); + fs::create_directories(tmp); + + fs::path root = WriteIncludeChain(tmp, kChainLength); + + rex::codegen::RecompilerConfig cfg; + CHECK_FALSE(cfg.Load(root.string())); + + fs::remove_all(tmp); +} + +// --------------------------------------------------------------------------- +// Test 7: Recursive includes happy path +// --------------------------------------------------------------------------- + +TEST_CASE("Config recursive includes happy path", "[codegen][config]") { + auto tmp = fs::temp_directory_path() / "rex_cfg_recursive"; + fs::remove_all(tmp); + fs::create_directories(tmp); + + // leaf.toml: lowest-level config + WriteTempToml(tmp, "leaf.toml", + "file_path = \"game.xex\"\n" + "project_name = \"leaf_project\"\n" + "\n" + "[functions.\"82230000\"]\n" + "size = 0x80\n" + "name = \"LeafFunc\"\n"); + + // mid.toml: includes leaf, adds another function + WriteTempToml(tmp, "mid.toml", + "includes = [\"leaf.toml\"]\n" + "file_path = \"game.xex\"\n" + "\n" + "[functions.\"82230100\"]\n" + "size = 0x80\n" + "name = \"MidFunc\"\n"); + + // top.toml: includes mid, adds yet another function and overrides project_name + WriteTempToml(tmp, "top.toml", + "includes = [\"mid.toml\"]\n" + "file_path = \"game.xex\"\n" + "project_name = \"top_project\"\n" + "\n" + "[functions.\"82230200\"]\n" + "size = 0x80\n" + "name = \"TopFunc\"\n"); + + rex::codegen::RecompilerConfig cfg; + REQUIRE(cfg.Load((tmp / "top.toml").string())); + + // All three functions must be present + CHECK(cfg.functions.count(0x82230000u) == 1); + CHECK(cfg.functions.count(0x82230100u) == 1); + CHECK(cfg.functions.count(0x82230200u) == 1); + + // Top-level project_name overrides leaf's value + CHECK(cfg.projectName == "top_project"); + + fs::remove_all(tmp); +} + +// --------------------------------------------------------------------------- +// Test 8: Relative path resolution +// --------------------------------------------------------------------------- + +TEST_CASE("Config relative path resolution from subdirectory", "[codegen][config]") { + auto tmp = fs::temp_directory_path() / "rex_cfg_relpath"; + fs::remove_all(tmp); + fs::create_directories(tmp / "sub"); + + // sub/leaf.toml: lives in a subdirectory + WriteTempToml(tmp, "sub/leaf.toml", + "file_path = \"game.xex\"\n" + "\n" + "[functions.\"82240000\"]\n" + "size = 0xC0\n" + "name = \"SubFunc\"\n"); + + // top.toml: includes sub/leaf.toml using a relative path + WriteTempToml(tmp, "top.toml", + "includes = [\"sub/leaf.toml\"]\n" + "file_path = \"game.xex\"\n"); + + rex::codegen::RecompilerConfig cfg; + REQUIRE(cfg.Load((tmp / "top.toml").string())); + + REQUIRE(cfg.functions.count(0x82240000u) == 1); + CHECK(cfg.functions.at(0x82240000u).name == "SubFunc"); + + // Now test that an included file resolves its OWN includes relative to itself. + // Create: top2.toml -> subdir/mid.toml -> ../leaf2.toml (back up to tmp root) + WriteTempToml(tmp, "leaf2.toml", + "file_path = \"game.xex\"\n" + "\n" + "[functions.\"82240100\"]\n" + "size = 0xC0\n" + "name = \"Leaf2Func\"\n"); + + // sub/mid.toml includes the parent directory's leaf2.toml + WriteTempToml(tmp, "sub/mid.toml", + "includes = [\"../leaf2.toml\"]\n" + "file_path = \"game.xex\"\n"); + + WriteTempToml(tmp, "top2.toml", + "includes = [\"sub/mid.toml\"]\n" + "file_path = \"game.xex\"\n"); + + rex::codegen::RecompilerConfig cfg2; + REQUIRE(cfg2.Load((tmp / "top2.toml").string())); + + REQUIRE(cfg2.functions.count(0x82240100u) == 1); + CHECK(cfg2.functions.at(0x82240100u).name == "Leaf2Func"); + + fs::remove_all(tmp); +} diff --git a/tests/unit/codegen/manifest_test.cpp b/tests/unit/codegen/manifest_test.cpp new file mode 100644 index 0000000..0fd737a --- /dev/null +++ b/tests/unit/codegen/manifest_test.cpp @@ -0,0 +1,231 @@ +/** + * @file tests/unit/codegen/manifest_test.cpp + * @brief Unit tests for manifest TOML parser + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include +#include + +#include +#include + +namespace fs = std::filesystem; + +namespace { + +struct TempDir { + fs::path path; + TempDir() : path(fs::temp_directory_path() / "manifest_test") { + fs::remove_all(path); + fs::create_directories(path); + } + ~TempDir() { fs::remove_all(path); } + void writeFile(const std::string& name, const std::string& content) const { + std::ofstream f(path / name); + f << content; + } +}; + +} // namespace + +TEST_CASE("Manifest: parse manifest with inline entrypoint", "[codegen][manifest]") { + TempDir tmp; + + tmp.writeFile("manifest.toml", R"( +[project] +name = "mygame" + +[entrypoint] +file_path = "assets/default.xex" +out_directory_path = "generated/default" +includes = [] + )"); + + auto result = rex::codegen::ManifestConfig::Load(tmp.path / "manifest.toml"); + REQUIRE(result.has_value()); + CHECK(result->projectName == "mygame"); + CHECK(result->entrypoint.recompiler.filePath == "assets/default.xex"); + CHECK(result->entrypoint.recompiler.outDirectoryPath == "generated/default"); + CHECK(result->entrypoint.guestPath.empty()); + CHECK(result->modules.empty()); +} + +TEST_CASE("Manifest: IsManifest detection", "[codegen][manifest]") { + TempDir tmp; + tmp.writeFile("manifest.toml", + "[project]\nname = \"test\"\n[entrypoint]\nfile_path = \"x.xex\"\n"); + tmp.writeFile("config.toml", "project_name = \"test\"\nfile_path = \"test.xex\""); + + CHECK(rex::codegen::ManifestConfig::IsManifest(tmp.path / "manifest.toml")); + CHECK_FALSE(rex::codegen::ManifestConfig::IsManifest(tmp.path / "config.toml")); +} + +TEST_CASE("Manifest: parse manifest with inline modules", "[codegen][manifest]") { + TempDir tmp; + tmp.writeFile("manifest.toml", R"( +[project] +name = "mygame" + +[entrypoint] +file_path = "assets/default.xex" +out_directory_path = "generated/default" + +[[modules]] +guest_path = "bin/lib_a.dll" +file_path = "assets/lib_a.dll" +out_directory_path = "generated/lib_a" + +[[modules]] +guest_path = "bin/lib_b.dll" +file_path = "assets/lib_b.dll" +out_directory_path = "generated/lib_b" + )"); + + auto result = rex::codegen::ManifestConfig::Load(tmp.path / "manifest.toml"); + REQUIRE(result.has_value()); + REQUIRE(result->modules.size() == 2u); + CHECK(result->modules[0].guestPath == "bin/lib_a.dll"); + CHECK(result->modules[0].recompiler.filePath == "assets/lib_a.dll"); + CHECK(result->modules[1].guestPath == "bin/lib_b.dll"); + CHECK(result->modules[1].recompiler.filePath == "assets/lib_b.dll"); +} + +TEST_CASE("Manifest: missing project section fails", "[codegen][manifest]") { + TempDir tmp; + tmp.writeFile("manifest.toml", "[entrypoint]\nfile_path = \"x.xex\"\n"); + auto result = rex::codegen::ManifestConfig::Load(tmp.path / "manifest.toml"); + CHECK_FALSE(result.has_value()); +} + +TEST_CASE("Manifest: missing entrypoint section fails", "[codegen][manifest]") { + TempDir tmp; + tmp.writeFile("manifest.toml", "[project]\nname = \"mygame\"\n"); + auto result = rex::codegen::ManifestConfig::Load(tmp.path / "manifest.toml"); + CHECK_FALSE(result.has_value()); +} + +TEST_CASE("Manifest: missing project name fails", "[codegen][manifest]") { + TempDir tmp; + tmp.writeFile("manifest.toml", + "[project]\n[entrypoint]\nfile_path = \"x.xex\"\nout_directory_path = \"o\"\n"); + auto result = rex::codegen::ManifestConfig::Load(tmp.path / "manifest.toml"); + CHECK_FALSE(result.has_value()); +} + +TEST_CASE("Manifest: parses sdk_version when present", "[codegen][manifest]") { + TempDir tmp; + tmp.writeFile("manifest.toml", R"( +[project] +name = "mygame" +sdk_version = "0.7.8.48" + +[entrypoint] +file_path = "assets/default.xex" +out_directory_path = "generated/default" + )"); + auto result = rex::codegen::ManifestConfig::Load(tmp.path / "manifest.toml"); + REQUIRE(result.has_value()); + REQUIRE(result->sdkVersion.has_value()); + CHECK(*result->sdkVersion == "0.7.8.48"); +} + +TEST_CASE("Manifest: sdk_version is nullopt when absent", "[codegen][manifest]") { + TempDir tmp; + tmp.writeFile("manifest.toml", R"( +[project] +name = "mygame" + +[entrypoint] +file_path = "assets/default.xex" +out_directory_path = "generated/default" + )"); + auto result = rex::codegen::ManifestConfig::Load(tmp.path / "manifest.toml"); + REQUIRE(result.has_value()); + CHECK_FALSE(result->sdkVersion.has_value()); +} + +TEST_CASE("Manifest: WriteSdkVersionStamp inserts when missing", "[codegen][manifest]") { + TempDir tmp; + tmp.writeFile("manifest.toml", R"([project] +name = "mygame" + +[entrypoint] +file_path = "assets/default.xex" +out_directory_path = "generated/default" +)"); + + auto path = tmp.path / "manifest.toml"; + CHECK(rex::codegen::ManifestConfig::WriteSdkVersionStamp(path, "0.8.0")); + + auto result = rex::codegen::ManifestConfig::Load(path); + REQUIRE(result.has_value()); + REQUIRE(result->sdkVersion.has_value()); + CHECK(*result->sdkVersion == "0.8.0"); + CHECK(result->projectName == "mygame"); +} + +TEST_CASE("Manifest: WriteSdkVersionStamp overwrites existing", "[codegen][manifest]") { + TempDir tmp; + tmp.writeFile("manifest.toml", R"([project] +name = "mygame" +sdk_version = "0.7.0" + +[entrypoint] +file_path = "assets/default.xex" +out_directory_path = "generated/default" +)"); + + auto path = tmp.path / "manifest.toml"; + CHECK(rex::codegen::ManifestConfig::WriteSdkVersionStamp(path, "0.8.0")); + + auto result = rex::codegen::ManifestConfig::Load(path); + REQUIRE(result.has_value()); + REQUIRE(result->sdkVersion.has_value()); + CHECK(*result->sdkVersion == "0.8.0"); +} + +TEST_CASE("CanonicalizeModuleGuestPath: device prefix", "[codegen][manifest][canonicalize]") { + using rex::codegen::CanonicalizeModuleGuestPath; + CHECK(CanonicalizeModuleGuestPath("game:\\bin\\foo.dll") == "bin/foo.dll"); + CHECK(CanonicalizeModuleGuestPath("game:/bin/foo.dll") == "bin/foo.dll"); + CHECK(CanonicalizeModuleGuestPath("d:\\bin\\foo.dll") == "bin/foo.dll"); +} + +TEST_CASE("CanonicalizeModuleGuestPath: case + slashes", "[codegen][canonicalize]") { + using rex::codegen::CanonicalizeModuleGuestPath; + CHECK(CanonicalizeModuleGuestPath("BIN\\Foo.DLL") == "bin/foo.dll"); + CHECK(CanonicalizeModuleGuestPath("bin\\sub\\Foo.dll") == "bin/sub/foo.dll"); +} + +TEST_CASE("CanonicalizeModuleGuestPath: leading slashes", "[codegen][canonicalize]") { + using rex::codegen::CanonicalizeModuleGuestPath; + CHECK(CanonicalizeModuleGuestPath("/bin/foo.dll") == "bin/foo.dll"); + CHECK(CanonicalizeModuleGuestPath("//bin/foo.dll") == "bin/foo.dll"); +} + +TEST_CASE("CanonicalizeModuleGuestPath: bare assets prefix preserved without project", + "[codegen][canonicalize]") { + using rex::codegen::CanonicalizeModuleGuestPath; + CHECK(CanonicalizeModuleGuestPath("assets/bin/foo.dll") == "assets/bin/foo.dll"); + CHECK(CanonicalizeModuleGuestPath("Assets/Bin/Foo.DLL") == "assets/bin/foo.dll"); +} + +TEST_CASE("CanonicalizeModuleGuestPath: project assets prefix stripped", + "[codegen][canonicalize]") { + using rex::codegen::CanonicalizeModuleGuestPath; + CHECK(CanonicalizeModuleGuestPath("mygame/assets/bin/foo.dll", "mygame") == "bin/foo.dll"); + CHECK(CanonicalizeModuleGuestPath("MyGame/Assets/Bin/Foo.DLL", "mygame") == "bin/foo.dll"); +} + +TEST_CASE("CanonicalizeModuleGuestPath: project mismatch keeps prefix", "[codegen][canonicalize]") { + using rex::codegen::CanonicalizeModuleGuestPath; + CHECK(CanonicalizeModuleGuestPath("othergame/assets/bin/foo.dll", "mygame") == + "othergame/assets/bin/foo.dll"); + CHECK(CanonicalizeModuleGuestPath("assets/foo.dll", "mygame") == "assets/foo.dll"); +} diff --git a/tests/unit/codegen/template_registry_test.cpp b/tests/unit/codegen/template_registry_test.cpp new file mode 100644 index 0000000..d4d2ce3 --- /dev/null +++ b/tests/unit/codegen/template_registry_test.cpp @@ -0,0 +1,207 @@ +/** + * @file tests/unit/codegen/template_registry_test.cpp + * @brief Unit tests for TemplateRegistry + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include +#include + +#include +#include +#include + +namespace fs = std::filesystem; + +// Helper to create a temp directory for test overrides +static fs::path CreateTempDir() { + auto tmp = fs::temp_directory_path() / "rex_template_test"; + fs::create_directories(tmp); + return tmp; +} + +static void CleanupTempDir(const fs::path& dir) { + fs::remove_all(dir); +} + +static void WriteTempFile(const fs::path& path, const std::string& content) { + fs::create_directories(path.parent_path()); + std::ofstream f(path); + f << content; +} + +TEST_CASE("TemplateRegistry: registeredIds returns all template IDs", "[TemplateRegistry]") { + rex::codegen::TemplateRegistry registry; + auto ids = registry.registeredIds(); + + REQUIRE(ids.size() == 17); + + auto has = [&](const std::string& id) { + return std::find(ids.begin(), ids.end(), id) != ids.end(); + }; + CHECK(has("init/cmakelists")); + CHECK(has("init/cmake_presets")); + CHECK(has("init/main_cpp")); + CHECK(has("init/app_header")); + CHECK(has("init/manifest_toml")); + CHECK(has("init/rexglue_cmake")); + CHECK(has("codegen/init_h")); + CHECK(has("codegen/init_cpp")); + CHECK(has("codegen/sources_cmake")); + CHECK(has("codegen/_indirect_call")); + CHECK(has("codegen/dll_targets_cmake")); + CHECK(has("codegen/module_registry_cpp")); + CHECK(has("codegen/register_cpp")); + CHECK(has("test/ppc_config_h")); + CHECK(has("test/ppc_test_cases_cpp")); + CHECK(has("test/ppc_test_decls_h")); + CHECK(has("test/ppc_test_functions_cpp")); +} + +TEST_CASE("TemplateRegistry: render with simple CLI data", "[TemplateRegistry]") { + rex::codegen::TemplateRegistry registry; + std::string json = R"({ + "names": {"snake_case": "test_app"}, + "sdk_version": "1.0.0", + "include_stamp": false, + "xex_path": "assets/default.xex", + "out_directory_path": "generated/default" + })"; + std::string result = registry.render("init/manifest_toml", json); + + CHECK(result.find("name = \"test_app\"") != std::string::npos); + CHECK(result.find("[entrypoint]") != std::string::npos); + CHECK(result.find("file_path = \"assets/default.xex\"") != std::string::npos); +} + +TEST_CASE("TemplateRegistry: render with codegen data", "[TemplateRegistry]") { + rex::codegen::TemplateRegistry registry; + std::string json = R"({ + "project": "test_proj", + "image_base": "0x82000000", + "image_size": "0x1000000", + "code_base": "0x82010000", + "code_size": "0x100000", + "rexcrt_heap": 1, + "config_flags": {}, + "functions": [], + "imports": [] + })"; + + std::string result = registry.render("codegen/init_cpp", json); + CHECK(result.find("PPCImageConfig") != std::string::npos); + CHECK(result.find("test_proj") != std::string::npos); +} + +TEST_CASE("TemplateRegistry: render unknown ID throws TemplateError", "[TemplateRegistry]") { + rex::codegen::TemplateRegistry registry; + REQUIRE_THROWS_AS(registry.render("nonexistent/template_id", "{}"), rex::codegen::TemplateError); +} + +TEST_CASE("TemplateRegistry: init_h includes shared indirect-call partial", "[TemplateRegistry]") { + rex::codegen::TemplateRegistry registry; + std::string json = R"({ + "config_flags": { + "skip_lr": false, + "ctr_as_local": false, + "xer_as_local": false, + "reserved_as_local": false, + "skip_msr": false, + "cr_as_local": false, + "non_argument_as_local": false, + "non_volatile_as_local": false + }, + "image_base": "0x82000000", + "image_size": "0x1000000", + "code_base": "0x82010000", + "code_size": "0x100000", + "thunk_reserve_size": "0x1000", + "rexcrt_heap": false, + "functions": [], + "imports": [] + })"; + std::string result = registry.render("codegen/init_h", json); + CHECK(result.find("REX_LOOKUP_FUNC") != std::string::npos); + CHECK(result.find("ResolveIndirectFunction") != std::string::npos); + CHECK(result.find("last_indirect_target") != std::string::npos); + CHECK(result.find("REX_THUNK_RESERVE_SIZE") != std::string::npos); + CHECK(result.find("[[likely]]") != std::string::npos); + CHECK(result.find("[[unlikely]]") != std::string::npos); +} + +TEST_CASE("TemplateRegistry: ppc_config_h includes shared indirect-call partial", + "[TemplateRegistry]") { + rex::codegen::TemplateRegistry registry; + std::string json = R"({ + "image_base": "0x82000000", + "image_size": "0x1000000", + "code_base": "0x82010000", + "code_size": "0x100000", + "thunk_reserve_size": "0x1000" + })"; + std::string result = registry.render("test/ppc_config_h", json); + CHECK(result.find("ResolveIndirectFunction") != std::string::npos); + CHECK(result.find("last_indirect_target") != std::string::npos); + CHECK(result.find("[[likely]]") != std::string::npos); +} + +TEST_CASE("TemplateRegistry: cmake_var callback works", "[TemplateRegistry]") { + rex::codegen::TemplateRegistry registry; + std::string result = registry.renderString("{{ cmake_var(\"FOO\") }}", "{}"); + CHECK(result == "${FOO}"); +} + +TEST_CASE("TemplateRegistry: loadOverrides with valid override", "[TemplateRegistry]") { + auto tmpDir = CreateTempDir(); + + // Write a custom init/manifest_toml.inja override + WriteTempFile(tmpDir / "init" / "manifest_toml.inja", "custom_override = true\n"); + + rex::codegen::TemplateRegistry registry; + registry.loadOverrides(tmpDir); + + std::string result = registry.render("init/manifest_toml", "{}"); + CHECK(result.find("custom_override = true") != std::string::npos); + // Should NOT contain the default template content + CHECK(result.find("[entrypoint]") == std::string::npos); + + CleanupTempDir(tmpDir); +} + +TEST_CASE("TemplateRegistry: loadOverrides ignores unknown IDs", "[TemplateRegistry]") { + auto tmpDir = CreateTempDir(); + + // Write a file with unrecognized canonical ID + WriteTempFile(tmpDir / "unknown" / "template.inja", "should be ignored\n"); + + rex::codegen::TemplateRegistry registry; + // Should not throw + REQUIRE_NOTHROW(registry.loadOverrides(tmpDir)); + + // Unknown template should still not be renderable + REQUIRE_THROWS_AS(registry.render("unknown/template", "{}"), rex::codegen::TemplateError); + + CleanupTempDir(tmpDir); +} + +TEST_CASE("Template: manifest_toml emits sdk_version when include_stamp is true", + "[TemplateRegistry][manifest]") { + rex::codegen::TemplateRegistry registry; + std::string json = + R"({"names": {"snake_case": "mygame", "pascal_case": "Mygame", "upper_case": "MYGAME"}, "sdk_version": "0.8.0", "include_stamp": true})"; + std::string out = registry.render("init/manifest_toml", json); + CHECK(out.find("sdk_version = \"0.8.0\"") != std::string::npos); + CHECK(out.find("name = \"mygame\"") != std::string::npos); +} + +TEST_CASE("Template: manifest_toml omits sdk_version when include_stamp is false", + "[TemplateRegistry][manifest]") { + rex::codegen::TemplateRegistry registry; + std::string json = + R"({"names": {"snake_case": "mygame", "pascal_case": "Mygame", "upper_case": "MYGAME"}, "sdk_version": "0.8.0", "include_stamp": false})"; + std::string out = registry.render("init/manifest_toml", json); + CHECK(out.find("sdk_version") == std::string::npos); + CHECK(out.find("name = \"mygame\"") != std::string::npos); +} diff --git a/tests/unit/core/byte_order_test.cpp b/tests/unit/core/byte_order_test.cpp new file mode 100644 index 0000000..ee0fd5f --- /dev/null +++ b/tests/unit/core/byte_order_test.cpp @@ -0,0 +1,124 @@ +/** + * Unit tests for byte order utilities (byte_swap, endian_store) + * + * Tests endianness conversion and byte swapping operations. + */ + +#include + +#include + +#include + +using namespace rex; + +// ============================================================================= +// byte_swap Tests +// ============================================================================= + +TEST_CASE("byte_swap 1-byte is identity", "[byte_order]") { + CHECK(byte_swap(uint8_t{0x12}) == 0x12); + CHECK(byte_swap(uint8_t{0x00}) == 0x00); + CHECK(byte_swap(uint8_t{0xFF}) == 0xFF); +} + +TEST_CASE("byte_swap 2-byte swaps correctly", "[byte_order]") { + CHECK(byte_swap(uint16_t{0x1234}) == 0x3412); + CHECK(byte_swap(uint16_t{0x0000}) == 0x0000); + CHECK(byte_swap(uint16_t{0xFFFF}) == 0xFFFF); + CHECK(byte_swap(uint16_t{0xFF00}) == 0x00FF); +} + +TEST_CASE("byte_swap 4-byte swaps correctly", "[byte_order]") { + CHECK(byte_swap(uint32_t{0x12345678}) == 0x78563412); + CHECK(byte_swap(uint32_t{0x00000000}) == 0x00000000); + CHECK(byte_swap(uint32_t{0xFFFFFFFF}) == 0xFFFFFFFF); + CHECK(byte_swap(uint32_t{0xFF000000}) == 0x000000FF); +} + +TEST_CASE("byte_swap 8-byte swaps correctly", "[byte_order]") { + CHECK(byte_swap(uint64_t{0x123456789ABCDEF0}) == 0xF0DEBC9A78563412); + CHECK(byte_swap(uint64_t{0x0000000000000000}) == 0x0000000000000000); + CHECK(byte_swap(uint64_t{0xFFFFFFFFFFFFFFFF}) == 0xFFFFFFFFFFFFFFFF); +} + +TEST_CASE("byte_swap is self-inverse", "[byte_order]") { + uint16_t val16 = 0x1234; + CHECK(byte_swap(byte_swap(val16)) == val16); + + uint32_t val32 = 0x12345678; + CHECK(byte_swap(byte_swap(val32)) == val32); + + uint64_t val64 = 0x123456789ABCDEF0; + CHECK(byte_swap(byte_swap(val64)) == val64); +} + +// ============================================================================= +// endian_store Tests +// ============================================================================= + +TEST_CASE("endian_store be stores big-endian", "[byte_order]") { + be val; + val.set(0x12345678); + + // On little-endian machine, stored bytes should be swapped + if constexpr (std::endian::native == std::endian::little) { + CHECK(val.value == 0x78563412); + } else { + CHECK(val.value == 0x12345678); + } + + CHECK(val.get() == 0x12345678); +} + +TEST_CASE("endian_store le stores little-endian", "[byte_order]") { + le val; + val.set(0x12345678); + + // On little-endian machine, stored bytes should be native + if constexpr (std::endian::native == std::endian::little) { + CHECK(val.value == 0x12345678); + } else { + CHECK(val.value == 0x78563412); + } + + CHECK(val.get() == 0x12345678); +} + +TEST_CASE("endian_store implicit conversion works", "[byte_order]") { + be be_val(0x12345678); + uint32_t native = be_val; // Implicit conversion via operator T() + CHECK(native == 0x12345678); +} + +TEST_CASE("endian_store assignment from value", "[byte_order]") { + be val; + val = be(0xABCD); + CHECK(val.get() == 0xABCD); +} + +TEST_CASE("endian_store increment operators", "[byte_order]") { + be val(10); + + ++val; + CHECK(val.get() == 11); + + val++; + CHECK(val.get() == 12); + + --val; + CHECK(val.get() == 11); + + val--; + CHECK(val.get() == 10); +} + +TEST_CASE("endian_store compound assignment", "[byte_order]") { + be val(100); + + val += 50; + CHECK(val.get() == 150); + + val -= 30; + CHECK(val.get() == 120); +} diff --git a/tests/unit/core/chrono_test.cpp b/tests/unit/core/chrono_test.cpp new file mode 100644 index 0000000..dbd4caa --- /dev/null +++ b/tests/unit/core/chrono_test.cpp @@ -0,0 +1,317 @@ +/** + * @file tests/unit/core/chrono_test.cpp + * @brief Unit tests for rex::chrono types (NtSystemClock, WinSystemClock) + * and the date:: calendar API surface used in xboxkrnl_rtl.cpp. + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include +#include + +#include + +#include + +using rex::chrono::WinSystemClock; + +// ============================================================================= +// Known FILETIME constants +// ============================================================================= + +// All values are 100-nanosecond intervals since 1601-01-01 00:00:00 UTC. +static constexpr uint64_t kFtNtEpoch = 0; // 1601-01-01 +static constexpr uint64_t kFtUnixEpoch = 116444736000000000; // 1970-01-01 +static constexpr uint64_t kFtY2k = 125911584000000000; // 2000-01-01 +static constexpr uint64_t kFtLeapDay = 125962560000000000; // 2000-02-29 +static constexpr uint64_t kFtSubDay = 132538032123450000; // 2020-12-30 12:00:12.345 +static constexpr uint64_t kFt2021 = 132539328000000000; // 2021-01-01 + +// ============================================================================= +// Section 1: Epoch Constant Validation +// ============================================================================= + +TEST_CASE("unix_epoch_delta computes correct 1601-to-1970 offset", "[chrono]") { + // 369 years from 1601 to 1970, with 89 leap days + constexpr int64_t expected_seconds = (369LL * 365 + 89) * 86400LL; + + // unix_epoch_delta() computes dynamically from date types + // The delta should be negative (1601 is before 1970) + CHECK(WinSystemClock::unix_epoch_delta().count() == -expected_seconds); + CHECK(WinSystemClock::unix_epoch_delta().count() < 0); +} + +// ============================================================================= +// Section 2: FILETIME Round-Trip +// ============================================================================= + +TEST_CASE("from_file_time and to_file_time are exact inverses", "[chrono]") { + SECTION("zero (NT epoch)") { + auto tp = WinSystemClock::from_file_time(kFtNtEpoch); + CHECK(WinSystemClock::to_file_time(tp) == kFtNtEpoch); + } + SECTION("Unix epoch") { + auto tp = WinSystemClock::from_file_time(kFtUnixEpoch); + CHECK(WinSystemClock::to_file_time(tp) == kFtUnixEpoch); + } + SECTION("large value") { + constexpr uint64_t large = 2650467743990000000ULL; // ~year 9999 + auto tp = WinSystemClock::from_file_time(large); + CHECK(WinSystemClock::to_file_time(tp) == large); + } +} + +TEST_CASE("to_file_time then from_file_time round-trips", "[chrono]") { + auto tp = WinSystemClock::from_file_time(kFtSubDay); + auto ft = WinSystemClock::to_file_time(tp); + auto tp2 = WinSystemClock::from_file_time(ft); + CHECK(tp == tp2); +} + +// ============================================================================= +// Section 3: to_sys / from_sys with Known Values +// ============================================================================= + +TEST_CASE("to_sys converts known FILETIMEs to correct system_clock values", "[chrono]") { + using namespace std::chrono; + + SECTION("Unix epoch FILETIME -> system_clock epoch") { + auto tp = WinSystemClock::to_sys(WinSystemClock::from_file_time(kFtUnixEpoch)); + // system_clock epoch is 1970-01-01, so time_since_epoch should be zero + auto since_epoch = tp.time_since_epoch(); + CHECK(duration_cast(since_epoch).count() == 0); + } + SECTION("Y2K FILETIME -> 30 years after Unix epoch") { + auto tp = WinSystemClock::to_sys(WinSystemClock::from_file_time(kFtY2k)); + auto since_epoch = tp.time_since_epoch(); + // 2000-01-01 is 10957 days after 1970-01-01 (including leap days) + CHECK(duration_cast(since_epoch).count() == 10957LL * 86400); + } + SECTION("2021 FILETIME -> known seconds since Unix epoch") { + auto tp = WinSystemClock::to_sys(WinSystemClock::from_file_time(kFt2021)); + auto since_epoch = tp.time_since_epoch(); + // 2021-01-01 is 18628 days after 1970-01-01 + CHECK(duration_cast(since_epoch).count() == 18628LL * 86400); + } +} + +TEST_CASE("from_sys then to_sys round-trips for whole-second values", "[chrono]") { + // Use values aligned to system_clock precision (whole seconds) + for (uint64_t ft : {kFtNtEpoch, kFtUnixEpoch, kFtY2k, kFt2021}) { + auto nt_tp = WinSystemClock::from_file_time(ft); + auto sys_tp = WinSystemClock::to_sys(nt_tp); + auto nt_tp2 = WinSystemClock::from_sys(sys_tp); + auto ft2 = WinSystemClock::to_file_time(nt_tp2); + CHECK(ft2 == ft); + } +} + +// ============================================================================= +// Section 4: Calendar Decomposition (mirrors RtlTimeToTimeFields) +// ============================================================================= + +// Helper struct matching the fields extracted in RtlTimeToTimeFields_entry +struct TimeFields { + int year; + unsigned month; + unsigned day; + unsigned weekday; // c_encoding: 0=Sun..6=Sat + int hours; + int minutes; + int seconds; + int milliseconds; +}; + +// Decompose a FILETIME exactly as RtlTimeToTimeFields_entry does +static TimeFields decompose(uint64_t filetime) { + auto tp = WinSystemClock::to_sys(WinSystemClock::from_file_time(filetime)); + auto dp = std::chrono::floor(tp); + auto ymd = std::chrono::year_month_day{dp}; + auto wd = std::chrono::weekday{dp}; + auto time = std::chrono::hh_mm_ss{std::chrono::floor(tp - dp)}; + return { + static_cast(ymd.year()), + static_cast(ymd.month()), + static_cast(ymd.day()), + wd.c_encoding(), + static_cast(time.hours().count()), + static_cast(time.minutes().count()), + static_cast(time.seconds().count()), + static_cast(time.subseconds().count()), + }; +} + +TEST_CASE("calendar decomposition: NT epoch (1601-01-01)", "[chrono]") { + auto tf = decompose(kFtNtEpoch); + CHECK(tf.year == 1601); + CHECK(tf.month == 1); + CHECK(tf.day == 1); + CHECK(tf.weekday == 1); // Monday + CHECK(tf.hours == 0); + CHECK(tf.minutes == 0); + CHECK(tf.seconds == 0); + CHECK(tf.milliseconds == 0); +} + +TEST_CASE("calendar decomposition: Unix epoch (1970-01-01)", "[chrono]") { + auto tf = decompose(kFtUnixEpoch); + CHECK(tf.year == 1970); + CHECK(tf.month == 1); + CHECK(tf.day == 1); + CHECK(tf.weekday == 4); // Thursday + CHECK(tf.hours == 0); + CHECK(tf.minutes == 0); + CHECK(tf.seconds == 0); + CHECK(tf.milliseconds == 0); +} + +TEST_CASE("calendar decomposition: Y2K (2000-01-01)", "[chrono]") { + auto tf = decompose(kFtY2k); + CHECK(tf.year == 2000); + CHECK(tf.month == 1); + CHECK(tf.day == 1); + CHECK(tf.weekday == 6); // Saturday + CHECK(tf.hours == 0); + CHECK(tf.minutes == 0); + CHECK(tf.seconds == 0); + CHECK(tf.milliseconds == 0); +} + +TEST_CASE("calendar decomposition: leap day (2000-02-29)", "[chrono]") { + auto tf = decompose(kFtLeapDay); + CHECK(tf.year == 2000); + CHECK(tf.month == 2); + CHECK(tf.day == 29); + CHECK(tf.weekday == 2); // Tuesday + CHECK(tf.hours == 0); + CHECK(tf.minutes == 0); + CHECK(tf.seconds == 0); + CHECK(tf.milliseconds == 0); +} + +TEST_CASE("calendar decomposition: sub-day (2020-12-30 12:00:12.345)", "[chrono]") { + auto tf = decompose(kFtSubDay); + CHECK(tf.year == 2020); + CHECK(tf.month == 12); + CHECK(tf.day == 30); + CHECK(tf.weekday == 3); // Wednesday + CHECK(tf.hours == 12); + CHECK(tf.minutes == 0); + CHECK(tf.seconds == 12); + CHECK(tf.milliseconds == 345); +} + +TEST_CASE("calendar decomposition: 2021-01-01", "[chrono]") { + auto tf = decompose(kFt2021); + CHECK(tf.year == 2021); + CHECK(tf.month == 1); + CHECK(tf.day == 1); + CHECK(tf.weekday == 5); // Friday + CHECK(tf.hours == 0); + CHECK(tf.minutes == 0); + CHECK(tf.seconds == 0); + CHECK(tf.milliseconds == 0); +} + +// ============================================================================= +// Section 5: Calendar Recomposition (mirrors RtlTimeFieldsToTime) +// ============================================================================= + +// Recompose fields to FILETIME exactly as RtlTimeFieldsToTime_entry does +static uint64_t recompose(int y, unsigned m, unsigned d, int hour, int min, int sec, int ms) { + auto ymd = + std::chrono::year_month_day{std::chrono::year{y}, std::chrono::month{m}, std::chrono::day{d}}; + if (!ymd.ok()) + return 0; + auto dp = static_cast(ymd); + std::chrono::system_clock::time_point time = dp; + time += std::chrono::hours{hour}; + time += std::chrono::minutes{min}; + time += std::chrono::seconds{sec}; + time += std::chrono::milliseconds{ms}; + return WinSystemClock::to_file_time(WinSystemClock::from_sys(time)); +} + +TEST_CASE("calendar recomposition: known dates produce correct FILETIMEs", "[chrono]") { + CHECK(recompose(1601, 1, 1, 0, 0, 0, 0) == kFtNtEpoch); + CHECK(recompose(1970, 1, 1, 0, 0, 0, 0) == kFtUnixEpoch); + CHECK(recompose(2000, 1, 1, 0, 0, 0, 0) == kFtY2k); + CHECK(recompose(2000, 2, 29, 0, 0, 0, 0) == kFtLeapDay); + CHECK(recompose(2020, 12, 30, 12, 0, 12, 345) == kFtSubDay); + CHECK(recompose(2021, 1, 1, 0, 0, 0, 0) == kFt2021); +} + +TEST_CASE("calendar recomposition: decompose then recompose round-trips", "[chrono]") { + for (uint64_t ft : {kFtNtEpoch, kFtUnixEpoch, kFtY2k, kFtLeapDay, kFtSubDay, kFt2021}) { + auto tf = decompose(ft); + auto result = + recompose(tf.year, tf.month, tf.day, tf.hours, tf.minutes, tf.seconds, tf.milliseconds); + CHECK(result == ft); + } +} + +TEST_CASE("year_month_day::ok rejects invalid dates", "[chrono]") { + // Feb 30 - never valid + CHECK_FALSE(std::chrono::year_month_day{std::chrono::year{2000}, std::chrono::month{2}, + std::chrono::day{30}} + .ok()); + // Month 13 - invalid month + CHECK_FALSE(std::chrono::year_month_day{std::chrono::year{2000}, std::chrono::month{13}, + std::chrono::day{1}} + .ok()); + // Day 0 - invalid day + CHECK_FALSE(std::chrono::year_month_day{std::chrono::year{2000}, std::chrono::month{1}, + std::chrono::day{0}} + .ok()); + // Feb 29 in non-leap year + CHECK_FALSE(std::chrono::year_month_day{std::chrono::year{2001}, std::chrono::month{2}, + std::chrono::day{29}} + .ok()); + // Feb 29 in leap year - valid + CHECK(std::chrono::year_month_day{std::chrono::year{2000}, std::chrono::month{2}, + std::chrono::day{29}} + .ok()); + // Century non-leap: 1900 is not a leap year + CHECK_FALSE(std::chrono::year_month_day{std::chrono::year{1900}, std::chrono::month{2}, + std::chrono::day{29}} + .ok()); + // 400-year leap: 2000 is a leap year (already checked above, but explicit) + CHECK(std::chrono::year_month_day{std::chrono::year{2000}, std::chrono::month{2}, + std::chrono::day{29}} + .ok()); +} + +TEST_CASE("recompose returns 0 for invalid dates", "[chrono]") { + CHECK(recompose(2000, 2, 30, 0, 0, 0, 0) == 0); + CHECK(recompose(2001, 2, 29, 0, 0, 0, 0) == 0); + CHECK(recompose(2000, 13, 1, 0, 0, 0, 0) == 0); + CHECK(recompose(2000, 1, 0, 0, 0, 0, 0) == 0); +} + +// ============================================================================= +// Section 6: Weekday c_encoding Edge Cases +// ============================================================================= + +TEST_CASE("weekday c_encoding returns 0=Sunday through 6=Saturday", "[chrono]") { + using namespace std::chrono; + + // Verify the full range of c_encoding values using known days + // 2000-01-02 is Sunday (0) + CHECK(weekday{sys_days{year{2000} / month{1} / day{2}}}.c_encoding() == 0); + // 1601-01-01 is Monday (1) + CHECK(weekday{sys_days{year{1601} / month{1} / day{1}}}.c_encoding() == 1); + // 2000-02-29 is Tuesday (2) + CHECK(weekday{sys_days{year{2000} / month{2} / day{29}}}.c_encoding() == 2); + // 2020-12-30 is Wednesday (3) + CHECK(weekday{sys_days{year{2020} / month{12} / day{30}}}.c_encoding() == 3); + // 1970-01-01 is Thursday (4) + CHECK(weekday{sys_days{year{1970} / month{1} / day{1}}}.c_encoding() == 4); + // 2021-01-01 is Friday (5) + CHECK(weekday{sys_days{year{2021} / month{1} / day{1}}}.c_encoding() == 5); + // 2000-01-01 is Saturday (6) + CHECK(weekday{sys_days{year{2000} / month{1} / day{1}}}.c_encoding() == 6); +} diff --git a/tests/unit/core/cvar_test.cpp b/tests/unit/core/cvar_test.cpp new file mode 100644 index 0000000..0726566 --- /dev/null +++ b/tests/unit/core/cvar_test.cpp @@ -0,0 +1,548 @@ +/** + * @file cvar_test.cpp + * @brief Unit tests for the cvar system + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include +#include + +#include +#include + +#include + +// Test cvars +REXCVAR_DEFINE_BOOL(test_bool_flag, false, "Test", "Test boolean flag"); +REXCVAR_DEFINE_INT32(test_int32_flag, 42, "Test", "Test int32 flag"); +REXCVAR_DEFINE_STRING(test_string_flag, "default", "Test", "Test string flag"); +REXCVAR_DEFINE_DOUBLE(test_double_flag, 3.14, "Test", "Test double flag"); +REXCVAR_DEFINE_INT32(test_ranged_flag, 5, "Test", "Test ranged flag").range(1, 10); +REXCVAR_DEFINE_STRING(test_enum_flag, "low", "Test", "Test enum-like flag") + .allowed({"low", "medium", "high"}); +REXCVAR_DEFINE_STRING(test_init_only_flag, "initial", "Test", "Init-only flag") + .lifecycle(rex::cvar::Lifecycle::kInitOnly); +REXCVAR_DEFINE_BOOL(test_restart_flag, false, "Test", "Requires restart") + .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); + +TEST_CASE("cvar registry stores flag metadata", "[cvar]") { + auto flags = rex::cvar::ListFlags(); + + SECTION("Flags are registered") { + REQUIRE(flags.size() > 0); + + bool found_bool = false; + bool found_int32 = false; + bool found_string = false; + + for (const auto& name : flags) { + if (name == "test_bool_flag") + found_bool = true; + if (name == "test_int32_flag") + found_int32 = true; + if (name == "test_string_flag") + found_string = true; + } + + CHECK(found_bool); + CHECK(found_int32); + CHECK(found_string); + } +} + +TEST_CASE("cvar REXCVAR_SET and REXCVAR_GET macros", "[cvar]") { + SECTION("Set and get boolean flag") { + REXCVAR_SET(test_bool_flag, true); + CHECK(REXCVAR_GET(test_bool_flag) == true); + + REXCVAR_SET(test_bool_flag, false); + CHECK(REXCVAR_GET(test_bool_flag) == false); + } + + SECTION("Set and get int32 flag") { + REXCVAR_SET(test_int32_flag, 123); + CHECK(REXCVAR_GET(test_int32_flag) == 123); + } + + SECTION("Set and get string flag") { + REXCVAR_SET(test_string_flag, "hello world"); + CHECK(REXCVAR_GET(test_string_flag) == "hello world"); + } + + SECTION("Set and get double flag") { + REXCVAR_SET(test_double_flag, 2.718); + CHECK(REXCVAR_GET(test_double_flag) == Catch::Approx(2.718)); + } +} + +TEST_CASE("cvar SetFlagByName and GetFlagByName string API", "[cvar]") { + SECTION("Set and get by name with string conversion") { + REQUIRE(rex::cvar::SetFlagByName("test_bool_flag", "true")); + CHECK(rex::cvar::GetFlagByName("test_bool_flag") == "true"); + + REQUIRE(rex::cvar::SetFlagByName("test_int32_flag", "456")); + CHECK(rex::cvar::GetFlagByName("test_int32_flag") == "456"); + + REQUIRE(rex::cvar::SetFlagByName("test_string_flag", "test value")); + CHECK(rex::cvar::GetFlagByName("test_string_flag") == "test value"); + } + + SECTION("Unknown flag returns false") { + CHECK_FALSE(rex::cvar::SetFlagByName("nonexistent_flag", "value")); + CHECK(rex::cvar::GetFlagByName("nonexistent_flag").empty()); + } +} + +TEST_CASE("cvar boolean parsing accepts multiple formats", "[cvar]") { + // This test specifically tests the string-based SetFlagByName API + // which parses string representations into native types + SECTION("true values") { + rex::cvar::SetFlagByName("test_bool_flag", "true"); + CHECK(REXCVAR_GET(test_bool_flag) == true); + + rex::cvar::SetFlagByName("test_bool_flag", "1"); + CHECK(REXCVAR_GET(test_bool_flag) == true); + + rex::cvar::SetFlagByName("test_bool_flag", "yes"); + CHECK(REXCVAR_GET(test_bool_flag) == true); + } + + SECTION("false values") { + rex::cvar::SetFlagByName("test_bool_flag", "false"); + CHECK(REXCVAR_GET(test_bool_flag) == false); + + rex::cvar::SetFlagByName("test_bool_flag", "0"); + CHECK(REXCVAR_GET(test_bool_flag) == false); + + rex::cvar::SetFlagByName("test_bool_flag", "no"); + CHECK(REXCVAR_GET(test_bool_flag) == false); + } +} + +TEST_CASE("cvar ListFlagsByCategory", "[cvar]") { + auto test_flags = rex::cvar::ListFlagsByCategory("Test"); + + CHECK(test_flags.size() >= 4); + + bool found = false; + for (const auto& name : test_flags) { + if (name == "test_bool_flag") { + found = true; + break; + } + } + CHECK(found); +} + +TEST_CASE("cvar GetFlagInfo returns metadata", "[cvar]") { + auto* info = rex::cvar::GetFlagInfo("test_int32_flag"); + + REQUIRE(info != nullptr); + CHECK(info->name == "test_int32_flag"); + CHECK(info->type == rex::cvar::FlagType::Int32); + CHECK(info->category == "Test"); + CHECK(info->default_value == "42"); + CHECK(info->lifecycle == rex::cvar::Lifecycle::kHotReload); + + SECTION("Unknown flag returns nullptr") { + CHECK(rex::cvar::GetFlagInfo("nonexistent") == nullptr); + } +} + +TEST_CASE("cvar TOML config loading", "[cvar]") { + auto temp_dir = std::filesystem::temp_directory_path(); + auto config_path = temp_dir / "test_config.toml"; + + SECTION("Load flat config") { + std::ofstream file(config_path); + file << "test_bool_flag = true\n"; + file << "test_int32_flag = 999\n"; + file << "test_string_flag = \"from config\"\n"; + file.close(); + + // Set initial values using REXCVAR_SET + REXCVAR_SET(test_bool_flag, false); + REXCVAR_SET(test_int32_flag, 0); + REXCVAR_SET(test_string_flag, ""); + + rex::cvar::LoadConfig(config_path); + + CHECK(REXCVAR_GET(test_bool_flag) == true); + CHECK(REXCVAR_GET(test_int32_flag) == 999); + CHECK(REXCVAR_GET(test_string_flag) == "from config"); + + std::filesystem::remove(config_path); + } + + SECTION("Nonexistent config is handled gracefully") { + auto missing = temp_dir / "nonexistent.toml"; + rex::cvar::LoadConfig(missing); + } +} + +TEST_CASE("cvar range validation", "[cvar]") { + SECTION("Value within range succeeds") { + REQUIRE(rex::cvar::SetFlagByName("test_ranged_flag", "5")); + CHECK(REXCVAR_GET(test_ranged_flag) == 5); + + REQUIRE(rex::cvar::SetFlagByName("test_ranged_flag", "1")); + CHECK(REXCVAR_GET(test_ranged_flag) == 1); + + REQUIRE(rex::cvar::SetFlagByName("test_ranged_flag", "10")); + CHECK(REXCVAR_GET(test_ranged_flag) == 10); + } + + SECTION("Value outside range fails") { + REXCVAR_SET(test_ranged_flag, 5); // Reset to known value + + CHECK_FALSE(rex::cvar::SetFlagByName("test_ranged_flag", "0")); + CHECK(REXCVAR_GET(test_ranged_flag) == 5); // Unchanged + + CHECK_FALSE(rex::cvar::SetFlagByName("test_ranged_flag", "11")); + CHECK(REXCVAR_GET(test_ranged_flag) == 5); // Unchanged + } +} + +TEST_CASE("cvar allowed values validation", "[cvar]") { + SECTION("Allowed value succeeds") { + REQUIRE(rex::cvar::SetFlagByName("test_enum_flag", "low")); + CHECK(REXCVAR_GET(test_enum_flag) == "low"); + + REQUIRE(rex::cvar::SetFlagByName("test_enum_flag", "medium")); + CHECK(REXCVAR_GET(test_enum_flag) == "medium"); + + REQUIRE(rex::cvar::SetFlagByName("test_enum_flag", "high")); + CHECK(REXCVAR_GET(test_enum_flag) == "high"); + } + + SECTION("Disallowed value fails") { + REXCVAR_SET(test_enum_flag, "low"); // Reset + + CHECK_FALSE(rex::cvar::SetFlagByName("test_enum_flag", "ultra")); + CHECK(REXCVAR_GET(test_enum_flag) == "low"); // Unchanged + } +} + +TEST_CASE("cvar lifecycle enforcement", "[cvar]") { + // Note: This test must run before FinalizeInit is called elsewhere, + // or use testing utilities to reset state + + SECTION("InitOnly flag can be set before finalization") { + // Assuming not finalized yet in test context + if (!rex::cvar::IsFinalized()) { + REQUIRE(rex::cvar::SetFlagByName("test_init_only_flag", "modified")); + CHECK(REXCVAR_GET(test_init_only_flag) == "modified"); + } + } +} + +TEST_CASE("cvar restart tracking", "[cvar]") { + // Clear any existing pending flags + rex::cvar::ClearPendingRestartFlags(); + + SECTION("Changing RequiresRestart flag tracks it") { + auto pending = rex::cvar::GetPendingRestartFlags(); + CHECK(pending.empty()); + + REQUIRE(rex::cvar::SetFlagByName("test_restart_flag", "true")); + + pending = rex::cvar::GetPendingRestartFlags(); + REQUIRE(pending.size() == 1); + CHECK(pending[0] == "test_restart_flag"); + } + + SECTION("ClearPendingRestartFlags clears the list") { + rex::cvar::SetFlagByName("test_restart_flag", "true"); + CHECK_FALSE(rex::cvar::GetPendingRestartFlags().empty()); + + rex::cvar::ClearPendingRestartFlags(); + CHECK(rex::cvar::GetPendingRestartFlags().empty()); + } +} + +TEST_CASE("cvar ListFlagsByLifecycle", "[cvar]") { + auto init_only = rex::cvar::ListFlagsByLifecycle(rex::cvar::Lifecycle::kInitOnly); + auto restart = rex::cvar::ListFlagsByLifecycle(rex::cvar::Lifecycle::kRequiresRestart); + + bool found_init = + std::find(init_only.begin(), init_only.end(), "test_init_only_flag") != init_only.end(); + bool found_restart = + std::find(restart.begin(), restart.end(), "test_restart_flag") != restart.end(); + + CHECK(found_init); + CHECK(found_restart); +} + +TEST_CASE("cvar reset and diff utilities", "[cvar]") { + SECTION("HasNonDefaultValue detects changes") { + REXCVAR_SET(test_int32_flag, 42); // Reset to default + CHECK_FALSE(rex::cvar::HasNonDefaultValue("test_int32_flag")); + + REXCVAR_SET(test_int32_flag, 100); + CHECK(rex::cvar::HasNonDefaultValue("test_int32_flag")); + } + + SECTION("ResetToDefault restores default value") { + REXCVAR_SET(test_int32_flag, 100); + CHECK(REXCVAR_GET(test_int32_flag) == 100); + + rex::cvar::ResetToDefault("test_int32_flag"); + CHECK(REXCVAR_GET(test_int32_flag) == 42); + } + + SECTION("ListModifiedFlags returns changed flags") { + REXCVAR_SET(test_int32_flag, 42); // Default + REXCVAR_SET(test_bool_flag, false); // Default + + auto modified = rex::cvar::ListModifiedFlags(); + bool found_int = + std::find(modified.begin(), modified.end(), "test_int32_flag") != modified.end(); + CHECK_FALSE(found_int); + + REXCVAR_SET(test_int32_flag, 999); + modified = rex::cvar::ListModifiedFlags(); + found_int = std::find(modified.begin(), modified.end(), "test_int32_flag") != modified.end(); + CHECK(found_int); + } +} + +TEST_CASE("cvar testing utilities", "[cvar]") { + SECTION("ResetAllForTesting resets state") { + REXCVAR_SET(test_int32_flag, 999); + rex::cvar::testing::ResetAllForTesting(); + CHECK(REXCVAR_GET(test_int32_flag) == 42); // Back to default + } +} + +TEST_CASE("cvar TOML serialization", "[cvar]") { + rex::cvar::testing::ResetAllForTesting(); + + REXCVAR_SET(test_int32_flag, 999); + REXCVAR_SET(test_string_flag, "custom"); + + auto toml = rex::cvar::SerializeToTOML(); + + // Should contain modified flags + CHECK(toml.find("test_int32_flag = 999") != std::string::npos); + CHECK(toml.find("test_string_flag = \"custom\"") != std::string::npos); + + // Should not contain flags at default + CHECK(toml.find("test_bool_flag") == std::string::npos); +} + +TEST_CASE("cvar metadata integration test", "[cvar][integration]") { + rex::cvar::testing::ResetAllForTesting(); + + SECTION("Full metadata workflow") { + // 1. Verify metadata is queryable + auto* info = rex::cvar::GetFlagInfo("test_ranged_flag"); + REQUIRE(info != nullptr); + CHECK(info->constraints.min.value_or(0) == 1); + CHECK(info->constraints.max.value_or(0) == 10); + + // 2. Verify validation works (set to valid non-default value, then invalid) + CHECK(rex::cvar::SetFlagByName("test_ranged_flag", "7")); + CHECK_FALSE(rex::cvar::SetFlagByName("test_ranged_flag", "100")); + + // 3. Verify change tracking (value 7 is different from default 5) + CHECK(rex::cvar::HasNonDefaultValue("test_ranged_flag")); + + // 4. Verify reset works + rex::cvar::ResetToDefault("test_ranged_flag"); + CHECK_FALSE(rex::cvar::HasNonDefaultValue("test_ranged_flag")); + } +} + +// Additional test cvars for extended coverage +REXCVAR_DEFINE_INT64(test_int64_flag, 1000000000LL, "Test", "Test int64 flag"); +REXCVAR_DEFINE_UINT32(test_uint32_flag, 42u, "Test", "Test uint32 flag"); +REXCVAR_DEFINE_UINT64(test_uint64_flag, 999999999999ULL, "Test", "Test uint64 flag"); +REXCVAR_DEFINE_STRING(test_validated_flag, "valid", "Test", "Custom validated flag") + .validator([](std::string_view v) { return v.size() >= 3; }); +REXCVAR_DEFINE_BOOL(test_debug_flag, false, "Test", "Debug-only flag").debug_only(); +REXCVAR_DEFINE_STRING(test_category_flag, "value", "TestCategory", "For category filter test"); + +TEST_CASE("cvar INT64/UINT32/UINT64 types", "[cvar]") { + SECTION("INT64 get/set") { + REXCVAR_SET(test_int64_flag, 9876543210LL); + CHECK(REXCVAR_GET(test_int64_flag) == 9876543210LL); + + REQUIRE(rex::cvar::SetFlagByName("test_int64_flag", "-123456789")); + CHECK(REXCVAR_GET(test_int64_flag) == -123456789LL); + } + + SECTION("UINT32 get/set") { + REXCVAR_SET(test_uint32_flag, 4000000000u); + CHECK(REXCVAR_GET(test_uint32_flag) == 4000000000u); + + REQUIRE(rex::cvar::SetFlagByName("test_uint32_flag", "123")); + CHECK(REXCVAR_GET(test_uint32_flag) == 123u); + } + + SECTION("UINT64 get/set") { + REXCVAR_SET(test_uint64_flag, 18446744073709551000ULL); + CHECK(REXCVAR_GET(test_uint64_flag) == 18446744073709551000ULL); + + REQUIRE(rex::cvar::SetFlagByName("test_uint64_flag", "999")); + CHECK(REXCVAR_GET(test_uint64_flag) == 999ULL); + } +} + +TEST_CASE("cvar custom validator", "[cvar]") { + SECTION("Valid value passes") { + REQUIRE(rex::cvar::SetFlagByName("test_validated_flag", "abc")); + CHECK(REXCVAR_GET(test_validated_flag) == "abc"); + + REQUIRE(rex::cvar::SetFlagByName("test_validated_flag", "long_string")); + CHECK(REXCVAR_GET(test_validated_flag) == "long_string"); + } + + SECTION("Invalid value fails") { + REXCVAR_SET(test_validated_flag, "valid"); + + // Too short (less than 3 chars) + CHECK_FALSE(rex::cvar::SetFlagByName("test_validated_flag", "ab")); + CHECK(REXCVAR_GET(test_validated_flag) == "valid"); // Unchanged + + CHECK_FALSE(rex::cvar::SetFlagByName("test_validated_flag", "x")); + CHECK(REXCVAR_GET(test_validated_flag) == "valid"); // Unchanged + } +} + +TEST_CASE("cvar debug_only flag", "[cvar]") { + auto* info = rex::cvar::GetFlagInfo("test_debug_flag"); + REQUIRE(info != nullptr); + CHECK(info->is_debug_only == true); + + // Non-debug flag should have is_debug_only = false + auto* non_debug = rex::cvar::GetFlagInfo("test_bool_flag"); + REQUIRE(non_debug != nullptr); + CHECK(non_debug->is_debug_only == false); +} + +TEST_CASE("cvar ScopedLifecycleOverride", "[cvar]") { + rex::cvar::testing::ResetAllForTesting(); + + // Finalize to lock init-only flags + rex::cvar::FinalizeInit(); + CHECK(rex::cvar::IsFinalized()); + + SECTION("Init-only blocked after finalization") { + CHECK_FALSE(rex::cvar::SetFlagByName("test_init_only_flag", "blocked")); + } + + SECTION("ScopedLifecycleOverride allows modification") { + { + rex::cvar::testing::ScopedLifecycleOverride override; + REQUIRE(rex::cvar::SetFlagByName("test_init_only_flag", "overridden")); + CHECK(REXCVAR_GET(test_init_only_flag) == "overridden"); + } + // After scope, should be blocked again + CHECK_FALSE(rex::cvar::SetFlagByName("test_init_only_flag", "blocked_again")); + } + + rex::cvar::testing::ResetAllForTesting(); +} + +TEST_CASE("cvar ResetAllToDefaults", "[cvar]") { + // Modify several flags + REXCVAR_SET(test_bool_flag, true); + REXCVAR_SET(test_int32_flag, 999); + REXCVAR_SET(test_string_flag, "modified"); + + CHECK(REXCVAR_GET(test_bool_flag) == true); + CHECK(REXCVAR_GET(test_int32_flag) == 999); + CHECK(REXCVAR_GET(test_string_flag) == "modified"); + + rex::cvar::ResetAllToDefaults(); + + CHECK(REXCVAR_GET(test_bool_flag) == false); + CHECK(REXCVAR_GET(test_int32_flag) == 42); + CHECK(REXCVAR_GET(test_string_flag) == "default"); +} + +TEST_CASE("cvar SerializeToTOML with category filter", "[cvar]") { + rex::cvar::testing::ResetAllForTesting(); + + // Modify flags in different categories + REXCVAR_SET(test_int32_flag, 123); // Category: Test + REXCVAR_SET(test_category_flag, "changed"); // Category: TestCategory + + SECTION("Filter by category returns only that category") { + auto test_toml = rex::cvar::SerializeToTOML("Test"); + auto category_toml = rex::cvar::SerializeToTOML("TestCategory"); + + CHECK(test_toml.find("test_int32_flag") != std::string::npos); + CHECK(test_toml.find("test_category_flag") == std::string::npos); + + CHECK(category_toml.find("test_category_flag") != std::string::npos); + CHECK(category_toml.find("test_int32_flag") == std::string::npos); + } +} + +TEST_CASE("cvar SaveConfig", "[cvar]") { + rex::cvar::testing::ResetAllForTesting(); + + auto temp_dir = std::filesystem::temp_directory_path(); + auto save_path = temp_dir / "test_save_config.toml"; + + // Clean up any existing file + std::filesystem::remove(save_path); + + SECTION("SaveConfig writes modified flags to file") { + REXCVAR_SET(test_int32_flag, 777); + REXCVAR_SET(test_string_flag, "saved_value"); + + rex::cvar::SaveConfig(save_path); + + // Verify file exists and contains expected content + REQUIRE(std::filesystem::exists(save_path)); + + std::string content; + { + std::ifstream file(save_path); + content = + std::string((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + } + + CHECK(content.find("test_int32_flag = 777") != std::string::npos); + CHECK(content.find("test_string_flag = \"saved_value\"") != std::string::npos); + + std::filesystem::remove(save_path); + } + + SECTION("SaveConfig with no modifications creates no file or empty") { + rex::cvar::testing::ResetAllForTesting(); + rex::cvar::SaveConfig(save_path); + // Either file doesn't exist or is minimal (just header comment) + } +} + +TEST_CASE("cvar ApplyEnvironment", "[cvar]") { + rex::cvar::testing::ResetAllForTesting(); + + // Note: This test modifies the environment, which may affect other tests + // In practice, environment application happens once at startup + + SECTION("Environment variables are applied with REX_ prefix") { +// Set environment variable +#ifdef _WIN32 + _putenv_s("REX_TEST_INT32_FLAG", "12345"); +#else + setenv("REX_TEST_INT32_FLAG", "12345", 1); +#endif + + rex::cvar::ApplyEnvironment(); + + CHECK(REXCVAR_GET(test_int32_flag) == 12345); + +// Clean up +#ifdef _WIN32 + _putenv_s("REX_TEST_INT32_FLAG", ""); +#else + unsetenv("REX_TEST_INT32_FLAG"); +#endif + } +} diff --git a/tests/unit/core/fiber_test.cpp b/tests/unit/core/fiber_test.cpp new file mode 100644 index 0000000..eed5618 --- /dev/null +++ b/tests/unit/core/fiber_test.cpp @@ -0,0 +1,45 @@ +/** + * @file tests/unit/core/fiber_test.cpp + * @brief Unit tests for rex::thread::Fiber + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include +#include + +using rex::thread::Fiber; + +// Globals - fiber entry functions cannot capture closures. +static Fiber* s_main = nullptr; +static int s_count = 0; + +static void counting_fiber(void*) { + ++s_count; // first resume + Fiber::SwitchTo(s_main); + ++s_count; // second resume + Fiber::SwitchTo(s_main); +} + +TEST_CASE("rex::thread::Fiber - basic context switch", "[fiber]") { + s_count = 0; + s_main = Fiber::ConvertCurrentThread(); + auto* f = Fiber::Create(256 * 1024, counting_fiber, nullptr); + + REQUIRE(s_count == 0); + Fiber::SwitchTo(f); + REQUIRE(s_count == 1); // fiber ran, switched back + Fiber::SwitchTo(f); + REQUIRE(s_count == 2); // fiber resumed, ran again, switched back + + // NOTE: Cleanup is not exception-safe. If a REQUIRE above fires, Catch2 + // throws and these Destroy() calls are skipped, leaking the host fiber + // handles. Acceptable for a test-only scenario; fix if spurious failures occur. + f->Destroy(); + s_main->Destroy(); + s_main = nullptr; +} diff --git a/tests/unit/core/sha256_test.cpp b/tests/unit/core/sha256_test.cpp new file mode 100644 index 0000000..2d22a30 --- /dev/null +++ b/tests/unit/core/sha256_test.cpp @@ -0,0 +1,25 @@ +/** + * Unit tests for SHA256 hashing utilities + * + * Tests SHA256 computation for strings and files. + */ + +#include + +#include + +TEST_CASE("sha256 empty string", "[sha256]") { + auto hash = rex::crypto::sha256(""); + CHECK(hash == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); +} + +TEST_CASE("sha256 hello world", "[sha256]") { + auto hash = rex::crypto::sha256("hello world"); + CHECK(hash == "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"); +} + +TEST_CASE("sha256 file content", "[sha256]") { + std::string content = "project_name = \"test\"\nxex_path = \"test.xex\"\n"; + auto hash = rex::crypto::sha256(content); + CHECK(hash.size() == 64); +} diff --git a/tests/unit/core/stream_test.cpp b/tests/unit/core/stream_test.cpp new file mode 100644 index 0000000..9929507 --- /dev/null +++ b/tests/unit/core/stream_test.cpp @@ -0,0 +1,382 @@ +/** + * Unit tests for stream utilities (BitStream, ByteStream) + * + * Tests bit-level and byte-level stream operations. + */ + +#include +#include +#include + +#include + +#include + +using namespace rex::stream; + +// ============================================================================= +// ByteStream Basic Tests +// ============================================================================= + +TEST_CASE("ByteStream construction and initial state", "[stream][bytestream]") { + std::array buffer{}; + ByteStream stream(buffer.data(), buffer.size()); + + CHECK(stream.data() == buffer.data()); + CHECK(stream.data_length() == 16); + CHECK(stream.offset() == 0); +} + +TEST_CASE("ByteStream construction with offset", "[stream][bytestream]") { + std::array buffer{}; + ByteStream stream(buffer.data(), buffer.size(), 8); + + CHECK(stream.offset() == 8); +} + +TEST_CASE("ByteStream Advance moves offset", "[stream][bytestream]") { + std::array buffer{}; + ByteStream stream(buffer.data(), buffer.size()); + + stream.Advance(4); + CHECK(stream.offset() == 4); + + stream.Advance(8); + CHECK(stream.offset() == 12); +} + +TEST_CASE("ByteStream set_offset works", "[stream][bytestream]") { + std::array buffer{}; + ByteStream stream(buffer.data(), buffer.size()); + + stream.set_offset(10); + CHECK(stream.offset() == 10); + + stream.set_offset(0); + CHECK(stream.offset() == 0); +} + +// ============================================================================= +// ByteStream Read/Write Tests +// ============================================================================= + +TEST_CASE("ByteStream Write and Read span", "[stream][bytestream]") { + std::array buffer{}; + ByteStream stream(buffer.data(), buffer.size()); + + std::array write_data = {0x11, 0x22, 0x33, 0x44}; + stream.Write(write_data.data(), write_data.size()); + + CHECK(stream.offset() == 4); + CHECK(buffer[0] == 0x11); + CHECK(buffer[1] == 0x22); + CHECK(buffer[2] == 0x33); + CHECK(buffer[3] == 0x44); + + // Read it back + stream.set_offset(0); + std::array read_data{}; + stream.Read(read_data.data(), read_data.size()); + + CHECK(read_data == write_data); + CHECK(stream.offset() == 4); +} + +TEST_CASE("ByteStream Write and Read template primitives", "[stream][bytestream]") { + std::array buffer{}; + ByteStream stream(buffer.data(), buffer.size()); + + // Write various types + stream.Write(0x12); + stream.Write(0x3456); + stream.Write(0x789ABCDE); + stream.Write(0xFEDCBA9876543210); + + CHECK(stream.offset() == 1 + 2 + 4 + 8); + + // Read them back + stream.set_offset(0); + CHECK(stream.Read() == 0x12); + CHECK(stream.Read() == 0x3456); + CHECK(stream.Read() == 0x789ABCDE); + CHECK(stream.Read() == 0xFEDCBA9876543210); +} + +TEST_CASE("ByteStream Write and Read void* overloads", "[stream][bytestream]") { + std::array buffer{}; + ByteStream stream(buffer.data(), buffer.size()); + + const char* msg = "test"; + stream.Write(msg, 4); + + stream.set_offset(0); + char read_buf[5] = {}; + stream.Read(read_buf, 4); + + CHECK(std::memcmp(read_buf, msg, 4) == 0); +} + +TEST_CASE("ByteStream Write and Read std::string", "[stream][bytestream]") { + std::array buffer{}; + ByteStream stream(buffer.data(), buffer.size()); + + std::string original = "Hello, World!"; + stream.Write(std::string_view(original)); + + stream.set_offset(0); + std::string result = stream.Read(); + + CHECK(result == original); +} + +TEST_CASE("ByteStream Write and Read std::u16string", "[stream][bytestream]") { + std::array buffer{}; + ByteStream stream(buffer.data(), buffer.size()); + + std::u16string original = u"Unicode\u00AE"; + stream.Write(std::u16string_view(original)); + + stream.set_offset(0); + std::u16string result = stream.Read(); + + CHECK(result == original); +} + +TEST_CASE("ByteStream empty string round-trip", "[stream][bytestream]") { + std::array buffer{}; + ByteStream stream(buffer.data(), buffer.size()); + + stream.Write(std::string_view("")); + + stream.set_offset(0); + std::string result = stream.Read(); + + CHECK(result.empty()); +} + +// ============================================================================= +// BitStream Basic Tests +// ============================================================================= + +TEST_CASE("BitStream construction and initial state", "[stream][bitstream]") { + std::array buffer{}; + BitStream stream(buffer.data(), buffer.size() * 8); + + CHECK(stream.buffer() == buffer.data()); + CHECK(stream.size_bits() == 128); + CHECK(stream.offset_bits() == 0); + CHECK(stream.BitsRemaining() == 128); +} + +TEST_CASE("BitStream SetOffset works", "[stream][bitstream]") { + std::array buffer{}; + BitStream stream(buffer.data(), buffer.size() * 8); + + stream.SetOffset(32); + CHECK(stream.offset_bits() == 32); + CHECK(stream.BitsRemaining() == 96); +} + +TEST_CASE("BitStream Advance works", "[stream][bitstream]") { + std::array buffer{}; + BitStream stream(buffer.data(), buffer.size() * 8); + + stream.Advance(10); + CHECK(stream.offset_bits() == 10); + + stream.Advance(5); + CHECK(stream.offset_bits() == 15); +} + +// ============================================================================= +// BitStream Peek/Read Tests +// ============================================================================= + +TEST_CASE("BitStream Peek reads without advancing", "[stream][bitstream]") { + // Buffer with known pattern: 0xAB = 10101011 + std::array buffer = {0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x9A}; + BitStream stream(buffer.data(), buffer.size() * 8); + + uint64_t val1 = stream.Peek(8); + CHECK(stream.offset_bits() == 0); // No advance + + uint64_t val2 = stream.Peek(8); + CHECK(val1 == val2); // Same value +} + +TEST_CASE("BitStream Read advances offset", "[stream][bitstream]") { + std::array buffer = {0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x9A}; + BitStream stream(buffer.data(), buffer.size() * 8); + + stream.Read(8); + CHECK(stream.offset_bits() == 8); + + stream.Read(16); + CHECK(stream.offset_bits() == 24); +} + +TEST_CASE("BitStream Read byte-aligned values", "[stream][bitstream]") { + // Big-endian data: reading first byte should give 0xAB + std::array buffer = {0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x9A}; + BitStream stream(buffer.data(), buffer.size() * 8); + + CHECK(stream.Read(8) == 0xAB); + CHECK(stream.Read(8) == 0xCD); + CHECK(stream.Read(8) == 0xEF); +} + +TEST_CASE("BitStream Read 16-bit aligned", "[stream][bitstream]") { + std::array buffer = {0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x9A}; + BitStream stream(buffer.data(), buffer.size() * 8); + + // Reading 16 bits from big-endian: 0xABCD + CHECK(stream.Read(16) == 0xABCD); + CHECK(stream.Read(16) == 0xEF12); +} + +TEST_CASE("BitStream Read 32-bit aligned", "[stream][bitstream]") { + std::array buffer = {0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x9A}; + BitStream stream(buffer.data(), buffer.size() * 8); + + CHECK(stream.Read(32) == 0xABCDEF12); +} + +TEST_CASE("BitStream Read non-byte-aligned", "[stream][bitstream]") { + // 0xAB = 10101011, 0xCD = 11001101 + std::array buffer = {0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x9A}; + BitStream stream(buffer.data(), buffer.size() * 8); + + // Read 4 bits: should be 1010 = 0xA + CHECK(stream.Read(4) == 0xA); + + // Read 4 bits: should be 1011 = 0xB + CHECK(stream.Read(4) == 0xB); + + // Read 8 bits: should be 0xCD + CHECK(stream.Read(8) == 0xCD); +} + +TEST_CASE("BitStream Read single bits", "[stream][bitstream]") { + // 0xAB = 10101011 + std::array buffer = {0xAB, 0xCD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + BitStream stream(buffer.data(), buffer.size() * 8); + + // Read bits one at a time from MSB + CHECK(stream.Read(1) == 1); // 1 + CHECK(stream.Read(1) == 0); // 0 + CHECK(stream.Read(1) == 1); // 1 + CHECK(stream.Read(1) == 0); // 0 + CHECK(stream.Read(1) == 1); // 1 + CHECK(stream.Read(1) == 0); // 0 + CHECK(stream.Read(1) == 1); // 1 + CHECK(stream.Read(1) == 1); // 1 +} + +TEST_CASE("BitStream Read crossing byte boundary", "[stream][bitstream]") { + // Read bits that span byte boundaries + std::array buffer = {0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + BitStream stream(buffer.data(), buffer.size() * 8); + + stream.Advance(4); // Now at bit 4 + + // Read 8 bits crossing the boundary: last 4 of 0xFF + first 4 of 0x00 + // 0xFF = 11111111, last 4 = 1111 + // 0x00 = 00000000, first 4 = 0000 + // Combined: 11110000 = 0xF0 + CHECK(stream.Read(8) == 0xF0); +} + +// ============================================================================= +// BitStream Write Tests +// NOTE: BitStream::Write is marked "TODO: This is totally not tested!" in source. +// It has a bug: doesn't byte-swap when storing, but Read expects big-endian. +// These tests are skipped until Write is fixed. +// ============================================================================= + +TEST_CASE("BitStream Write byte-aligned", "[stream][bitstream][!mayfail]") { + SKIP("BitStream::Write is broken - doesn't byte-swap on store"); + + std::array buffer{}; + BitStream stream(buffer.data(), buffer.size() * 8); + + stream.Write(0xAB, 8); + CHECK(stream.offset_bits() == 8); + + stream.SetOffset(0); + CHECK(stream.Read(8) == 0xAB); +} + +TEST_CASE("BitStream Write 16-bit value", "[stream][bitstream][!mayfail]") { + SKIP("BitStream::Write is broken - doesn't byte-swap on store"); + + std::array buffer{}; + BitStream stream(buffer.data(), buffer.size() * 8); + + stream.Write(0x1234, 16); + + stream.SetOffset(0); + CHECK(stream.Read(16) == 0x1234); +} + +TEST_CASE("BitStream Write non-byte-aligned", "[stream][bitstream][!mayfail]") { + SKIP("BitStream::Write is broken - doesn't byte-swap on store"); + + std::array buffer{}; + BitStream stream(buffer.data(), buffer.size() * 8); + + // Write 4 bits, then 4 more + stream.Write(0xA, 4); // 1010 + stream.Write(0xB, 4); // 1011 + + stream.SetOffset(0); + CHECK(stream.Read(8) == 0xAB); +} + +TEST_CASE("BitStream Write preserves surrounding bits", "[stream][bitstream][!mayfail]") { + SKIP("BitStream::Write is broken - doesn't byte-swap on store"); + + std::array buffer = {0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + BitStream stream(buffer.data(), buffer.size() * 8); + + stream.Advance(4); + stream.Write(0x0, 4); // Clear middle 4 bits + + stream.SetOffset(0); + // First 4 bits should still be 1111, next 4 should be 0000 + CHECK(stream.Read(4) == 0xF); + CHECK(stream.Read(4) == 0x0); +} + +// ============================================================================= +// BitStream Edge Cases +// ============================================================================= + +TEST_CASE("BitStream Read zero bits returns zero", "[stream][bitstream]") { + std::array buffer = {0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + BitStream stream(buffer.data(), buffer.size() * 8); + + CHECK(stream.Read(0) == 0); + CHECK(stream.offset_bits() == 0); // No advance +} + +TEST_CASE("BitStream maximum bits (57)", "[stream][bitstream]") { + std::array buffer = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + BitStream stream(buffer.data(), buffer.size() * 8); + + // 57 bits of all 1s = 0x1FFFFFFFFFFFFFF + uint64_t expected = (1ULL << 57) - 1; + CHECK(stream.Read(57) == expected); +} + +TEST_CASE("BitStream BitsRemaining decreases", "[stream][bitstream]") { + std::array buffer{}; + BitStream stream(buffer.data(), 64); // 64 bits = 8 bytes + + CHECK(stream.BitsRemaining() == 64); + + stream.Read(16); + CHECK(stream.BitsRemaining() == 48); + + stream.Read(32); + CHECK(stream.BitsRemaining() == 16); +} diff --git a/tests/unit/kernel/object_table_test.cpp b/tests/unit/kernel/object_table_test.cpp new file mode 100644 index 0000000..9c51153 --- /dev/null +++ b/tests/unit/kernel/object_table_test.cpp @@ -0,0 +1,581 @@ +/** + * Unit tests for kernel object system (XObject and ObjectTable) + * + * Tests handle management, reference counting, and name mapping. + */ + +#include + +#include +#include +#include + +using namespace rex; +using namespace rex::system; +using namespace rex::system::util; + +// ============================================================================= +// Test Fixtures and Helpers +// ============================================================================= + +// Minimal XObject subclass for testing +class TestObject : public XObject { + public: + static constexpr Type kObjectType = Type::Undefined; + + TestObject() : XObject(Type::Undefined) {} + + // Track destructor calls for leak detection + static int destructor_count; + ~TestObject() override { destructor_count++; } +}; + +int TestObject::destructor_count = 0; + +// Reset destructor count before each test +struct DestructorCountReset { + DestructorCountReset() { TestObject::destructor_count = 0; } +}; + +// Initialize logging once +void InitTestLogging() { + static bool initialized = false; + if (!initialized) { + rex::InitLogging(); + initialized = true; + } +} + +// ============================================================================= +// object_ref Smart Pointer Tests +// ============================================================================= + +TEST_CASE("object_ref default construction is null", "[kernel][object_ref]") { + InitTestLogging(); + object_ref ref; + + CHECK(ref.get() == nullptr); + CHECK(!ref); + CHECK(ref == nullptr); +} + +TEST_CASE("object_ref construction from raw pointer", "[kernel][object_ref]") { + InitTestLogging(); + DestructorCountReset reset; + + auto* obj = new TestObject(); + // Object starts with ref count of 1 from constructor + + { + object_ref ref(obj); + CHECK(ref.get() == obj); + CHECK(ref); + CHECK(ref != nullptr); + } + // Destructor should release, destroying object + CHECK(TestObject::destructor_count == 1); +} + +TEST_CASE("object_ref copy construction retains", "[kernel][object_ref]") { + InitTestLogging(); + DestructorCountReset reset; + + auto* obj = new TestObject(); + + { + object_ref ref1(obj); + { + object_ref ref2(ref1); // Copy - should retain + CHECK(ref1.get() == ref2.get()); + CHECK(TestObject::destructor_count == 0); // Still alive + } + // ref2 destroyed, but ref1 still holds + CHECK(TestObject::destructor_count == 0); + } + // Both refs destroyed + CHECK(TestObject::destructor_count == 1); +} + +TEST_CASE("object_ref move construction transfers ownership", "[kernel][object_ref]") { + InitTestLogging(); + DestructorCountReset reset; + + auto* obj = new TestObject(); + + { + object_ref ref1(obj); + object_ref ref2(std::move(ref1)); + + CHECK(ref1.get() == nullptr); // Moved from + CHECK(ref2.get() == obj); + CHECK(TestObject::destructor_count == 0); + } + CHECK(TestObject::destructor_count == 1); +} + +TEST_CASE("object_ref copy assignment retains", "[kernel][object_ref]") { + InitTestLogging(); + DestructorCountReset reset; + + auto* obj = new TestObject(); + + { + object_ref ref1(obj); + object_ref ref2; + + ref2 = ref1; // Copy assign + CHECK(ref1.get() == ref2.get()); + CHECK(TestObject::destructor_count == 0); + } + CHECK(TestObject::destructor_count == 1); +} + +TEST_CASE("object_ref move assignment transfers ownership", "[kernel][object_ref]") { + InitTestLogging(); + DestructorCountReset reset; + + auto* obj = new TestObject(); + + { + object_ref ref1(obj); + object_ref ref2; + + ref2 = std::move(ref1); + CHECK(ref1.get() == nullptr); + CHECK(ref2.get() == obj); + } + CHECK(TestObject::destructor_count == 1); +} + +TEST_CASE("object_ref reset releases reference", "[kernel][object_ref]") { + InitTestLogging(); + DestructorCountReset reset; + + auto* obj = new TestObject(); + + object_ref ref(obj); + CHECK(TestObject::destructor_count == 0); + + ref.reset(); + CHECK(ref.get() == nullptr); + CHECK(TestObject::destructor_count == 1); +} + +TEST_CASE("object_ref release returns pointer without destroying", "[kernel][object_ref]") { + InitTestLogging(); + DestructorCountReset reset; + + auto* obj = new TestObject(); + + object_ref ref(obj); + auto* released = ref.release(); + + CHECK(released == obj); + CHECK(ref.get() == nullptr); + CHECK(TestObject::destructor_count == 0); // Not destroyed + + // Clean up manually + released->Release(); + CHECK(TestObject::destructor_count == 1); +} + +TEST_CASE("object_ref arrow operator works", "[kernel][object_ref]") { + InitTestLogging(); + + auto* obj = new TestObject(); + object_ref ref(obj); + + CHECK(ref->type() == XObject::Type::Undefined); +} + +TEST_CASE("object_ref dereference operator works", "[kernel][object_ref]") { + InitTestLogging(); + + auto* obj = new TestObject(); + object_ref ref(obj); + + TestObject& deref = *ref; + CHECK(&deref == obj); +} + +TEST_CASE("retain_object helper retains and wraps", "[kernel][object_ref]") { + InitTestLogging(); + DestructorCountReset reset; + + auto* obj = new TestObject(); + // obj has ref count 1 + + { + auto ref = retain_object(obj); // Should retain, ref count now 2 + CHECK(ref.get() == obj); + } + // ref destroyed, ref count back to 1 + CHECK(TestObject::destructor_count == 0); + + obj->Release(); // Final release + CHECK(TestObject::destructor_count == 1); +} + +// ============================================================================= +// ObjectTable Handle Allocation Tests +// ============================================================================= + +TEST_CASE("ObjectTable AddHandle allocates valid handle", "[kernel][object_table]") { + InitTestLogging(); + DestructorCountReset reset; + + ObjectTable table; + auto* obj = new TestObject(); + + X_HANDLE handle = 0; + X_STATUS status = table.AddHandle(obj, &handle); + + CHECK(status == X_STATUS_SUCCESS); + CHECK(handle != 0); + CHECK(handle >= XObject::kHandleBase); // 0xF8000000 + + // Handle should be in object's handle list + CHECK(obj->handles().size() == 1); + CHECK(obj->handles()[0] == handle); + + table.Reset(); +} + +TEST_CASE("ObjectTable first handle is slot 1 not 0", "[kernel][object_table]") { + InitTestLogging(); + + ObjectTable table; + auto* obj = new TestObject(); + + X_HANDLE handle = 0; + table.AddHandle(obj, &handle); + + // First handle should be slot 1: kHandleBase + (1 << 2) = 0xF8000004 + CHECK(handle == XObject::kHandleBase + 4); + + table.Reset(); +} + +TEST_CASE("ObjectTable multiple objects get unique handles", "[kernel][object_table]") { + InitTestLogging(); + + ObjectTable table; + auto* obj1 = new TestObject(); + auto* obj2 = new TestObject(); + auto* obj3 = new TestObject(); + + X_HANDLE h1 = 0, h2 = 0, h3 = 0; + table.AddHandle(obj1, &h1); + table.AddHandle(obj2, &h2); + table.AddHandle(obj3, &h3); + + CHECK(h1 != h2); + CHECK(h2 != h3); + CHECK(h1 != h3); + + // Handles increment by 4 (slot << 2) + CHECK(h2 == h1 + 4); + CHECK(h3 == h2 + 4); + + table.Reset(); +} + +// ============================================================================= +// ObjectTable Handle Lookup Tests +// ============================================================================= + +TEST_CASE("ObjectTable LookupObject finds object by handle", "[kernel][object_table]") { + InitTestLogging(); + + ObjectTable table; + auto* obj = new TestObject(); + + X_HANDLE handle = 0; + table.AddHandle(obj, &handle); + + auto found = table.LookupObject(handle); + CHECK(found.get() == obj); + + table.Reset(); +} + +TEST_CASE("ObjectTable LookupObject returns null for invalid handle", "[kernel][object_table]") { + InitTestLogging(); + + ObjectTable table; + + auto found = table.LookupObject(0xF8001234); + CHECK(found.get() == nullptr); +} + +TEST_CASE("ObjectTable LookupObject returns null for handle 0", "[kernel][object_table]") { + InitTestLogging(); + + ObjectTable table; + + auto found = table.LookupObject(0); + CHECK(found.get() == nullptr); +} + +// ============================================================================= +// ObjectTable Handle Reference Counting Tests +// ============================================================================= + +TEST_CASE("ObjectTable RetainHandle increments ref count", "[kernel][object_table]") { + InitTestLogging(); + + ObjectTable table; + auto* obj = new TestObject(); + + X_HANDLE handle = 0; + table.AddHandle(obj, &handle); + + X_STATUS status = table.RetainHandle(handle); + CHECK(status == X_STATUS_SUCCESS); + + // Need two releases to remove + table.ReleaseHandle(handle); + auto still_there = table.LookupObject(handle); + CHECK(still_there.get() == obj); + + table.ReleaseHandle(handle); // This should remove it + + table.Reset(); +} + +TEST_CASE("ObjectTable ReleaseHandle removes at zero refs", "[kernel][object_table]") { + InitTestLogging(); + DestructorCountReset reset; + + ObjectTable table; + auto* obj = new TestObject(); + + X_HANDLE handle = 0; + table.AddHandle(obj, &handle); + + X_STATUS status = table.ReleaseHandle(handle); + CHECK(status == X_STATUS_SUCCESS); + + // Handle should be gone + auto found = table.LookupObject(handle); + CHECK(found.get() == nullptr); + + table.Reset(); +} + +TEST_CASE("ObjectTable ReleaseHandle on invalid handle returns error", "[kernel][object_table]") { + InitTestLogging(); + + ObjectTable table; + + X_STATUS status = table.ReleaseHandle(0xF8001234); + CHECK(status == X_STATUS_INVALID_HANDLE); +} + +TEST_CASE("ObjectTable DuplicateHandle creates new handle for same object", + "[kernel][object_table]") { + InitTestLogging(); + + ObjectTable table; + auto* obj = new TestObject(); + + X_HANDLE h1 = 0, h2 = 0; + table.AddHandle(obj, &h1); + table.DuplicateHandle(h1, &h2); + + CHECK(h1 != h2); + + // Both handles refer to same object + auto found1 = table.LookupObject(h1); + auto found2 = table.LookupObject(h2); + CHECK(found1.get() == obj); + CHECK(found2.get() == obj); + + // Object should have both handles + CHECK(obj->handles().size() == 2); + + table.Reset(); +} + +// ============================================================================= +// ObjectTable Handle Release Tests +// ============================================================================= + +TEST_CASE("ObjectTable ReleaseHandle removes handle from table", "[kernel][object_table]") { + InitTestLogging(); + + ObjectTable table; + auto* obj = new TestObject(); + + X_HANDLE handle = 0; + table.AddHandle(obj, &handle); + + // ReleaseHandle decrements ref count; at 0 it removes the handle + X_STATUS status = table.ReleaseHandle(handle); + CHECK(status == X_STATUS_SUCCESS); + + auto found = table.LookupObject(handle); + CHECK(found.get() == nullptr); + + table.Reset(); +} + +TEST_CASE("ObjectTable ReleaseHandle updates object's handle list", "[kernel][object_table]") { + InitTestLogging(); + + ObjectTable table; + auto* obj = new TestObject(); + obj->Retain(); // Keep alive after table releases + + X_HANDLE handle = 0; + table.AddHandle(obj, &handle); + CHECK(obj->handles().size() == 1); + + table.ReleaseHandle(handle); + CHECK(obj->handles().empty()); + + obj->Release(); + table.Reset(); +} + +// ============================================================================= +// ObjectTable Name Mapping Tests +// ============================================================================= + +TEST_CASE("ObjectTable AddNameMapping registers name", "[kernel][object_table]") { + InitTestLogging(); + + ObjectTable table; + auto* obj = new TestObject(); + + X_HANDLE handle = 0; + table.AddHandle(obj, &handle); + + X_STATUS status = table.AddNameMapping("TestName", handle); + CHECK(status == X_STATUS_SUCCESS); + + table.Reset(); +} + +TEST_CASE("ObjectTable duplicate name returns collision", "[kernel][object_table]") { + InitTestLogging(); + + ObjectTable table; + auto* obj1 = new TestObject(); + auto* obj2 = new TestObject(); + + X_HANDLE h1 = 0, h2 = 0; + table.AddHandle(obj1, &h1); + table.AddHandle(obj2, &h2); + + CHECK(table.AddNameMapping("SharedName", h1) == X_STATUS_SUCCESS); + CHECK(table.AddNameMapping("SharedName", h2) == X_STATUS_OBJECT_NAME_COLLISION); + + table.Reset(); +} + +TEST_CASE("ObjectTable name collision is case-insensitive", "[kernel][object_table]") { + InitTestLogging(); + + ObjectTable table; + auto* obj1 = new TestObject(); + auto* obj2 = new TestObject(); + + X_HANDLE h1 = 0, h2 = 0; + table.AddHandle(obj1, &h1); + table.AddHandle(obj2, &h2); + + CHECK(table.AddNameMapping("TestName", h1) == X_STATUS_SUCCESS); + // Different case should still collide + CHECK(table.AddNameMapping("testname", h2) == X_STATUS_OBJECT_NAME_COLLISION); + CHECK(table.AddNameMapping("TESTNAME", h2) == X_STATUS_OBJECT_NAME_COLLISION); + + table.Reset(); +} + +TEST_CASE("ObjectTable GetObjectByName returns not found for missing name", + "[kernel][object_table]") { + InitTestLogging(); + + ObjectTable table; + + X_HANDLE found = 0; + X_STATUS status = table.GetObjectByName("DoesNotExist", &found); + CHECK(status == X_STATUS_OBJECT_NAME_NOT_FOUND); + CHECK(found == X_INVALID_HANDLE_VALUE); +} + +TEST_CASE("ObjectTable RemoveNameMapping clears name", "[kernel][object_table]") { + InitTestLogging(); + + ObjectTable table; + auto* obj = new TestObject(); + + X_HANDLE handle = 0; + table.AddHandle(obj, &handle); + table.AddNameMapping("TempName", handle); + + table.RemoveNameMapping("TempName"); + + X_HANDLE found = 0; + CHECK(table.GetObjectByName("TempName", &found) == X_STATUS_OBJECT_NAME_NOT_FOUND); + + table.Reset(); +} + +// ============================================================================= +// ObjectTable Reset and Bulk Operations +// ============================================================================= + +TEST_CASE("ObjectTable Reset releases all objects", "[kernel][object_table]") { + InitTestLogging(); + DestructorCountReset reset; + + ObjectTable table; + auto* obj1 = new TestObject(); + auto* obj2 = new TestObject(); + auto* obj3 = new TestObject(); + + table.AddHandle(obj1, nullptr); + table.AddHandle(obj2, nullptr); + table.AddHandle(obj3, nullptr); + + // Objects have ref count 2: 1 from new, 1 from AddHandle's Retain + // Release our initial ref so table owns them exclusively + obj1->Release(); + obj2->Release(); + obj3->Release(); + + CHECK(TestObject::destructor_count == 0); + + table.Reset(); + + // Now Reset's Release brings ref count from 1 to 0, destroying them + CHECK(TestObject::destructor_count == 3); +} + +TEST_CASE("ObjectTable GetAllObjects returns all objects", "[kernel][object_table]") { + InitTestLogging(); + + ObjectTable table; + auto* obj1 = new TestObject(); + auto* obj2 = new TestObject(); + + table.AddHandle(obj1, nullptr); + table.AddHandle(obj2, nullptr); + + auto all = table.GetAllObjects(); + CHECK(all.size() == 2); + + table.Reset(); +} + +// ============================================================================= +// TODO: Tests requiring kernel integration +// ============================================================================= + +// TODO: Test handle 0xFFFFFFFF (CurrentProcess) - requires full KernelState +// TODO: Test handle 0xFFFFFFFE (CurrentThread) - requires XThread integration +// TODO: Test GetObjectsByType() with real typed objects +// TODO: Test GetObjectByName with existing object - requires kernel_state for RetainHandle +// TODO: Test case-insensitive name lookup via GetObjectByName diff --git a/tests/unit/memory/heap_allocation_test.cpp b/tests/unit/memory/heap_allocation_test.cpp new file mode 100644 index 0000000..7a83256 --- /dev/null +++ b/tests/unit/memory/heap_allocation_test.cpp @@ -0,0 +1,763 @@ +/** + * @file heap_allocation_test.cpp + * @brief Unit tests for memory heap allocation behavior + * + * These tests validate the BaseHeap allocation, protection, and query + * operations based on observed runtime behavior. + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include + +#include +#include +#include + +namespace { + +// Shared memory instance - expensive to create, reuse across tests +rex::memory::Memory& GetTestMemory() { + static rex::memory::Memory memory; + static bool initialized = false; + if (!initialized) { + rex::InitLogging(); + bool result = memory.Initialize(); + REQUIRE(result); + initialized = true; + } + return memory; +} + +// Helper to cast away const for heap operations +rex::memory::BaseHeap* MutableHeap(const rex::memory::BaseHeap* heap) { + return const_cast(heap); +} + +} // namespace + +// ============================================================================= +// Size and Alignment Rounding Tests +// ============================================================================= + +TEST_CASE("Heap allocation rounds size up to page size", "[memory][heap]") { + auto& memory = GetTestMemory(); + auto* heap = MutableHeap(memory.LookupHeap(0x10000000)); // v00000000, 4KB pages + REQUIRE(heap != nullptr); + + SECTION("Size smaller than page size rounds to page size") { + uint32_t addr = 0; + bool result = heap->Alloc( + 100, // Requested size + 4096, // Alignment + rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, false, &addr); + REQUIRE(result); + REQUIRE(addr != 0); + + // Query to verify actual allocated size + rex::memory::HeapAllocationInfo info{}; + REQUIRE(heap->QueryRegionInfo(addr, &info)); + CHECK(info.allocation_size == 4096); // Rounded up from 100 + + heap->Release(addr, nullptr); + } + + SECTION("Size of 4 bytes rounds to 4096") { + uint32_t addr = 0; + bool result = heap->Alloc( + 4, 4096, rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, false, &addr); + REQUIRE(result); + + rex::memory::HeapAllocationInfo info{}; + REQUIRE(heap->QueryRegionInfo(addr, &info)); + CHECK(info.allocation_size == 4096); + + heap->Release(addr, nullptr); + } + + SECTION("Size exactly page size stays unchanged") { + uint32_t addr = 0; + bool result = heap->Alloc( + 4096, 4096, rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, false, &addr); + REQUIRE(result); + + rex::memory::HeapAllocationInfo info{}; + REQUIRE(heap->QueryRegionInfo(addr, &info)); + CHECK(info.allocation_size == 4096); + + heap->Release(addr, nullptr); + } + + SECTION("Multi-page allocation") { + uint32_t addr = 0; + bool result = heap->Alloc( + 4096 * 4, 4096, // 4 pages + rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, false, &addr); + REQUIRE(result); + + rex::memory::HeapAllocationInfo info{}; + REQUIRE(heap->QueryRegionInfo(addr, &info)); + CHECK(info.allocation_size == 4096 * 4); + + heap->Release(addr, nullptr); + } +} + +TEST_CASE("Heap allocation rounds alignment up to page size", "[memory][heap]") { + auto& memory = GetTestMemory(); + auto* heap = MutableHeap(memory.LookupHeap(0x10000000)); + REQUIRE(heap != nullptr); + + SECTION("Small alignment rounds to page size") { + uint32_t addr = 0; + bool result = heap->Alloc( + 4096, 32, // 32-byte alignment requested + rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, false, &addr); + REQUIRE(result); + + // Address should be page-aligned (4096), not just 32-byte aligned + CHECK((addr % 4096) == 0); + + heap->Release(addr, nullptr); + } + + SECTION("Large alignment is respected") { + uint32_t addr = 0; + bool result = heap->Alloc( + 4096, 65536, // 64KB alignment + rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, false, &addr); + REQUIRE(result); + + CHECK((addr % 65536) == 0); + + heap->Release(addr, nullptr); + } +} + +// ============================================================================= +// Allocation Direction Tests +// ============================================================================= + +TEST_CASE("Bottom-up allocation starts after reserved first 64KB", "[memory][heap]") { + auto& memory = GetTestMemory(); + auto* heap = MutableHeap(memory.LookupHeap(0x10000000)); + REQUIRE(heap != nullptr); + + uint32_t addr = 0; + bool result = heap->Alloc( + 4096, 4096, rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, + false, // bottom-up + &addr); + REQUIRE(result); + + // First 64KB (0x10000) is reserved, allocations start at 0x10000 or later + CHECK(addr >= 0x10000); + + heap->Release(addr, nullptr); +} + +TEST_CASE("Top-down allocation returns high addresses", "[memory][heap]") { + auto& memory = GetTestMemory(); + auto* heap = MutableHeap(memory.LookupHeap(0x10000000)); + REQUIRE(heap != nullptr); + + uint32_t addr_bottom = 0; + uint32_t addr_top = 0; + + // Allocate bottom-up first + heap->Alloc( + 4096, 4096, rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, false, &addr_bottom); + + // Allocate top-down + heap->Alloc(4096, 4096, + rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, + true, // top-down + &addr_top); + + // Top-down should be significantly higher + CHECK(addr_top > addr_bottom); + // Top-down should be near top of heap (heap ends at ~0x40000000) + CHECK(addr_top > 0x1F000000); + + heap->Release(addr_bottom, nullptr); + heap->Release(addr_top, nullptr); +} + +// ============================================================================= +// AllocFixed Tests +// ============================================================================= + +TEST_CASE("AllocFixed allocates at exact address", "[memory][heap]") { + auto& memory = GetTestMemory(); + auto* heap = MutableHeap(memory.LookupHeap(0x10000000)); + REQUIRE(heap != nullptr); + + // Choose an address that should be free + uint32_t target = 0x20000000; + + bool result = + heap->AllocFixed(target, 4096, 4096, + rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite); + REQUIRE(result); + + // Verify allocation is at exact address + rex::memory::HeapAllocationInfo info{}; + REQUIRE(heap->QueryRegionInfo(target, &info)); + CHECK(info.base_address == target); + CHECK(info.state != 0); // Should be allocated + + heap->Release(target, nullptr); +} + +TEST_CASE("AllocFixed reserve-only fails on already-reserved region", "[memory][heap]") { + auto& memory = GetTestMemory(); + auto* heap = MutableHeap(memory.LookupHeap(0x10000000)); + REQUIRE(heap != nullptr); + + uint32_t target = 0x21000000; + + // First allocation: reserve only + bool first = heap->AllocFixed(target, 4096, 4096, + rex::memory::kMemoryAllocationReserve, // Reserve only + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite); + REQUIRE(first); + + // Second reserve at same address should FAIL + bool second = + heap->AllocFixed(target, 4096, 4096, + rex::memory::kMemoryAllocationReserve, // Reserve only - should fail + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite); + CHECK_FALSE(second); + + heap->Release(target, nullptr); +} + +TEST_CASE("AllocFixed commit on reserved region succeeds", "[memory][heap]") { + auto& memory = GetTestMemory(); + auto* heap = MutableHeap(memory.LookupHeap(0x10000000)); + REQUIRE(heap != nullptr); + + uint32_t target = 0x21100000; + + // First: reserve only + bool reserve = + heap->AllocFixed(target, 4096, 4096, rex::memory::kMemoryAllocationReserve, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite); + REQUIRE(reserve); + + // Second: commit on already-reserved region should SUCCEED + bool commit = + heap->AllocFixed(target, 4096, 4096, + rex::memory::kMemoryAllocationCommit, // Commit only + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite); + CHECK(commit); + + heap->Release(target, nullptr); +} + +// ============================================================================= +// Protection Tests +// ============================================================================= + +TEST_CASE("Protect changes page protection and returns old value", "[memory][heap]") { + auto& memory = GetTestMemory(); + auto* heap = MutableHeap(memory.LookupHeap(0x10000000)); + REQUIRE(heap != nullptr); + + uint32_t addr = 0; + bool result = heap->Alloc( + 4096, 4096, rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, // Initial: RW + false, &addr); + REQUIRE(result); + + SECTION("Change to read-only") { + uint32_t old_protect = 0; + bool protect_result = heap->Protect(addr, 4096, + rex::memory::kMemoryProtectRead, // New: Read only + &old_protect); + REQUIRE(protect_result); + + // Old protection should have been RW (3) + CHECK(old_protect == (rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite)); + + // Query to verify new protection + rex::memory::HeapAllocationInfo info{}; + REQUIRE(heap->QueryRegionInfo(addr, &info)); + CHECK(info.protect == rex::memory::kMemoryProtectRead); + } + + heap->Release(addr, nullptr); +} + +// ============================================================================= +// QueryRegionInfo Tests +// ============================================================================= + +TEST_CASE("QueryRegionInfo returns correct allocation info", "[memory][heap]") { + auto& memory = GetTestMemory(); + auto* heap = MutableHeap(memory.LookupHeap(0x10000000)); + REQUIRE(heap != nullptr); + + uint32_t addr = 0; + bool result = + heap->Alloc(4096 * 4, 4096, // 4 pages + rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, false, &addr); + REQUIRE(result); + + SECTION("Query at allocation base") { + rex::memory::HeapAllocationInfo info{}; + REQUIRE(heap->QueryRegionInfo(addr, &info)); + + CHECK(info.base_address == addr); + CHECK(info.allocation_size == 4096 * 4); + CHECK(info.region_size == 4096 * 4); + CHECK(info.protect == (rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite)); + CHECK(info.state != 0); // Allocated + } + + SECTION("Query in middle of allocation") { + uint32_t mid = addr + 4096 * 2; // Third page + rex::memory::HeapAllocationInfo info{}; + REQUIRE(heap->QueryRegionInfo(mid, &info)); + + // base_address is the queried address + CHECK(info.base_address == mid); + // allocation_size should still be full allocation + CHECK(info.allocation_size == 4096 * 4); + // region_size is remaining size from query point + CHECK(info.region_size == 4096 * 2); // 2 pages left + } + + heap->Release(addr, nullptr); +} + +// ============================================================================= +// Release Tests +// ============================================================================= + +TEST_CASE("Release frees memory for reallocation", "[memory][heap]") { + auto& memory = GetTestMemory(); + auto* heap = MutableHeap(memory.LookupHeap(0x22000000)); // Use a different region + REQUIRE(heap != nullptr); + + uint32_t target = 0x22000000; + + // Allocate + bool alloc1 = + heap->AllocFixed(target, 4096, 4096, + rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite); + REQUIRE(alloc1); + + // Release + uint32_t released_size = 0; + bool release = heap->Release(target, &released_size); + REQUIRE(release); + CHECK(released_size == 4096); + + // Should be able to allocate at same address again + bool alloc2 = + heap->AllocFixed(target, 4096, 4096, + rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite); + CHECK(alloc2); + + heap->Release(target, nullptr); +} + +// ============================================================================= +// Heap Selection Tests (LookupHeap) +// ============================================================================= + +TEST_CASE("LookupHeap returns correct heap for address", "[memory][heap]") { + auto& memory = GetTestMemory(); + + SECTION("Address in v00000000 range") { + auto* heap = memory.LookupHeap(0x10000000); + REQUIRE(heap != nullptr); + // This is the 4KB page heap + } + + SECTION("Address in v40000000 range") { + auto* heap = memory.LookupHeap(0x50000000); + REQUIRE(heap != nullptr); + // This is the 64KB page heap + } + + SECTION("Address in v80000000 range (XEX)") { + auto* heap = memory.LookupHeap(0x82000000); + REQUIRE(heap != nullptr); + } + + SECTION("Address in stack range returns nullptr") { + auto* heap = memory.LookupHeap(0x7F000000); + CHECK(heap == nullptr); + } +} + +// ============================================================================= +// 64KB Page Heap Tests (v40000000) +// ============================================================================= + +TEST_CASE("64KB page heap rounds to 64KB boundaries", "[memory][heap]") { + auto& memory = GetTestMemory(); + auto* heap = MutableHeap(memory.LookupHeap(0x50000000)); // v40000000 heap + REQUIRE(heap != nullptr); + + SECTION("Small size rounds to 64KB") { + uint32_t addr = 0; + bool result = heap->Alloc( + 4096, 4096, // Request only 4KB + rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, false, &addr); + REQUIRE(result); + + rex::memory::HeapAllocationInfo info{}; + REQUIRE(heap->QueryRegionInfo(addr, &info)); + // Size should be rounded to 64KB page size + CHECK(info.allocation_size == 65536); + + // Address should be 64KB aligned + CHECK((addr % 65536) == 0); + + heap->Release(addr, nullptr); + } +} + +// ============================================================================= +// Decommit Tests +// ============================================================================= + +TEST_CASE("Decommit removes commit flag but keeps reservation", "[memory][heap]") { + auto& memory = GetTestMemory(); + auto* heap = MutableHeap(memory.LookupHeap(0x10000000)); + REQUIRE(heap != nullptr); + + uint32_t addr = 0; + bool result = heap->Alloc( + 4096, 4096, rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, false, &addr); + REQUIRE(result); + + // Verify initial state is committed + rex::memory::HeapAllocationInfo info_before{}; + REQUIRE(heap->QueryRegionInfo(addr, &info_before)); + CHECK((info_before.state & rex::memory::kMemoryAllocationCommit) != 0); + CHECK((info_before.state & rex::memory::kMemoryAllocationReserve) != 0); + + // Decommit + bool decommit = heap->Decommit(addr, 4096); + REQUIRE(decommit); + + // Verify commit flag is removed but reserve remains + rex::memory::HeapAllocationInfo info_after{}; + REQUIRE(heap->QueryRegionInfo(addr, &info_after)); + CHECK((info_after.state & rex::memory::kMemoryAllocationCommit) == 0); + CHECK((info_after.state & rex::memory::kMemoryAllocationReserve) != 0); + + heap->Release(addr, nullptr); +} + +TEST_CASE("Decommit partial region", "[memory][heap]") { + auto& memory = GetTestMemory(); + auto* heap = MutableHeap(memory.LookupHeap(0x10000000)); + REQUIRE(heap != nullptr); + + uint32_t addr = 0; + bool result = + heap->Alloc(4096 * 4, 4096, // 4 pages + rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, false, &addr); + REQUIRE(result); + + // Decommit only middle 2 pages + bool decommit = heap->Decommit(addr + 4096, 4096 * 2); + REQUIRE(decommit); + + // First page should still be committed + rex::memory::HeapAllocationInfo info_first{}; + REQUIRE(heap->QueryRegionInfo(addr, &info_first)); + CHECK((info_first.state & rex::memory::kMemoryAllocationCommit) != 0); + + // Middle page should be decommitted + rex::memory::HeapAllocationInfo info_mid{}; + REQUIRE(heap->QueryRegionInfo(addr + 4096, &info_mid)); + CHECK((info_mid.state & rex::memory::kMemoryAllocationCommit) == 0); + + // Last page should still be committed + rex::memory::HeapAllocationInfo info_last{}; + REQUIRE(heap->QueryRegionInfo(addr + 4096 * 3, &info_last)); + CHECK((info_last.state & rex::memory::kMemoryAllocationCommit) != 0); + + heap->Release(addr, nullptr); +} + +TEST_CASE("Decommit-recommit cycle on 64KB heap (real usage pattern)", "[memory][heap]") { + // This pattern observed in real app: NtFreeVirtualMemory(MEM_DECOMMIT) + // followed by NtAllocateVirtualMemory at same address + auto& memory = GetTestMemory(); + auto* heap = MutableHeap(memory.LookupHeap(0x50000000)); // v40000000 heap, 64KB pages + REQUIRE(heap != nullptr); + + // Allocate on 64KB heap + uint32_t addr = 0; + bool result = heap->Alloc( + 65536, 65536, rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, false, &addr); + REQUIRE(result); + + // Decommit (like NtFreeVirtualMemory with type=0x4000) + bool decommit = heap->Decommit(addr, 65536); + REQUIRE(decommit); + + // After decommit, state should be Reserve only (state=1) + rex::memory::HeapAllocationInfo info{}; + REQUIRE(heap->QueryRegionInfo(addr, &info)); + CHECK(info.state == rex::memory::kMemoryAllocationReserve); // Exactly 1 + + // Recommit at same address (like NtAllocateVirtualMemory with type=0x60001000) + bool recommit = + heap->AllocFixed(addr, 65536, 65536, + rex::memory::kMemoryAllocationCommit, // Commit only + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite); + REQUIRE(recommit); + + // State should now include commit again + rex::memory::HeapAllocationInfo info_after{}; + REQUIRE(heap->QueryRegionInfo(addr, &info_after)); + CHECK((info_after.state & rex::memory::kMemoryAllocationCommit) != 0); + + heap->Release(addr, nullptr); +} + +TEST_CASE("Repeated decommit of same page succeeds (idempotent)", "[memory][heap]") { + // Real app decommits same address multiple times in sequence + auto& memory = GetTestMemory(); + auto* heap = MutableHeap(memory.LookupHeap(0x50000000)); // v40000000 heap + REQUIRE(heap != nullptr); + + uint32_t addr = 0; + bool result = heap->Alloc( + 65536, 65536, rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, false, &addr); + REQUIRE(result); + + // First decommit + bool decommit1 = heap->Decommit(addr, 65536); + REQUIRE(decommit1); + + // Second decommit of same already-decommitted page should still succeed + bool decommit2 = heap->Decommit(addr, 65536); + CHECK(decommit2); + + // Third decommit + bool decommit3 = heap->Decommit(addr, 65536); + CHECK(decommit3); + + heap->Release(addr, nullptr); +} + +TEST_CASE("Decommit on 64KB heap uses 64KB granularity", "[memory][heap]") { + // On v40000000 heap, even small decommit requests affect whole 64KB page + auto& memory = GetTestMemory(); + auto* heap = MutableHeap(memory.LookupHeap(0x50000000)); + REQUIRE(heap != nullptr); + + uint32_t addr = 0; + bool result = heap->Alloc( + 65536, 65536, rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, false, &addr); + REQUIRE(result); + + // Decommit with small size - should still affect the page + bool decommit = heap->Decommit(addr, 4096); // Request only 4KB + REQUIRE(decommit); + + // The 64KB page should still be affected (implementation detail: + // size gets rounded to page_size internally via get_page_count) + rex::memory::HeapAllocationInfo info{}; + REQUIRE(heap->QueryRegionInfo(addr, &info)); + // State should show decommitted + CHECK((info.state & rex::memory::kMemoryAllocationCommit) == 0); + + heap->Release(addr, nullptr); +} + +// ============================================================================= +// Address Translation Tests +// ============================================================================= + +TEST_CASE("TranslateVirtual returns valid host pointer", "[memory][translation]") { + auto& memory = GetTestMemory(); + + // Allocate some memory first + auto* heap = MutableHeap(memory.LookupHeap(0x10000000)); + REQUIRE(heap != nullptr); + + uint32_t guest_addr = 0; + bool result = heap->Alloc( + 4096, 4096, rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, false, &guest_addr); + REQUIRE(result); + + // Translate to host + uint8_t* host_ptr = memory.TranslateVirtual(guest_addr); + REQUIRE(host_ptr != nullptr); + + // Should be able to read/write + host_ptr[0] = 0xAB; + CHECK(host_ptr[0] == 0xAB); + + heap->Release(guest_addr, nullptr); +} + +TEST_CASE("HostToGuestVirtual roundtrip", "[memory][translation]") { + auto& memory = GetTestMemory(); + + auto* heap = MutableHeap(memory.LookupHeap(0x10000000)); + REQUIRE(heap != nullptr); + + uint32_t original_guest = 0; + bool result = heap->Alloc( + 4096, 4096, rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, false, &original_guest); + REQUIRE(result); + + // Guest -> Host -> Guest roundtrip + uint8_t* host_ptr = memory.TranslateVirtual(original_guest); + uint32_t back_to_guest = memory.HostToGuestVirtual(host_ptr); + + CHECK(back_to_guest == original_guest); + + heap->Release(original_guest, nullptr); +} + +TEST_CASE("TranslatePhysical masks to 29 bits", "[memory][translation]") { + auto& memory = GetTestMemory(); + + // Physical addresses are masked with 0x1FFFFFFF (29 bits) + // So 0xA0000000 and 0x00000000 should map to same physical offset + uint8_t* ptr_low = memory.TranslatePhysical(0x00001000); + uint8_t* ptr_high = memory.TranslatePhysical(0xA0001000); + + // Both should resolve to same offset in physical memory + // (0xA0001000 & 0x1FFFFFFF) == 0x00001000 + CHECK(ptr_low == ptr_high); +} + +// ============================================================================= +// Physical Heap Tests +// ============================================================================= + +TEST_CASE("Physical heap vA0000000 (64KB pages, cached)", "[memory][physical]") { + auto& memory = GetTestMemory(); + auto* heap = MutableHeap(memory.LookupHeap(0xA0000000)); + REQUIRE(heap != nullptr); + + // vA0000000 heap: base=0xA0000000, 64KB pages + uint32_t addr = 0; + bool result = heap->Alloc( + 4096, 4096, rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, false, &addr); + REQUIRE(result); + + // Address should be in 0xA0000000-0xBFFFFFFF range + CHECK(addr >= 0xA0000000); + CHECK(addr < 0xC0000000); + + // Should be 64KB aligned + CHECK((addr % 65536) == 0); + + heap->Release(addr, nullptr); +} + +TEST_CASE("Physical heap vC0000000 (16MB pages, uncached)", "[memory][physical]") { + auto& memory = GetTestMemory(); + auto* heap = MutableHeap(memory.LookupHeap(0xC0000000)); + REQUIRE(heap != nullptr); + + // vC0000000 heap: base=0xC0000000, 16MB pages + // Note: First 16MB is pre-allocated for GPU writeback + + uint32_t addr = 0; + bool result = + heap->Alloc(16 * 1024 * 1024, 16 * 1024 * 1024, // 16MB + rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, false, &addr); + REQUIRE(result); + + // Address should be in 0xC0000000-0xDFFFFFFF range + CHECK(addr >= 0xC0000000); + CHECK(addr < 0xE0000000); + + heap->Release(addr, nullptr); +} + +TEST_CASE("Physical heap vE0000000 (4KB pages, write-combine)", "[memory][physical]") { + auto& memory = GetTestMemory(); + auto* heap = MutableHeap(memory.LookupHeap(0xE0000000)); + REQUIRE(heap != nullptr); + + // vE0000000 heap: base=0xE0000000, 4KB pages + uint32_t addr = 0; + bool result = heap->Alloc( + 4096, 4096, rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit, + rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite, false, &addr); + REQUIRE(result); + + // Address should be in 0xE0000000-0xFFCFFFFF range + CHECK(addr >= 0xE0000000); + CHECK(addr < 0xFFD00000); + + // Should be 4KB aligned + CHECK((addr % 4096) == 0); + + heap->Release(addr, nullptr); +} + +TEST_CASE("LookupHeapByType selects correct heap", "[memory][heap]") { + auto& memory = GetTestMemory(); + + SECTION("Virtual heap with 4KB pages") { + auto* heap = memory.LookupHeapByType(false, 4096); + REQUIRE(heap != nullptr); + // Should be v00000000 heap + } + + SECTION("Virtual heap with 64KB pages") { + auto* heap = memory.LookupHeapByType(false, 65536); + REQUIRE(heap != nullptr); + // Should be v40000000 heap + } + + SECTION("Physical heap with 4KB pages") { + auto* heap = memory.LookupHeapByType(true, 4096); + REQUIRE(heap != nullptr); + // Should be vE0000000 heap + } + + SECTION("Physical heap with 64KB pages") { + auto* heap = memory.LookupHeapByType(true, 65536); + REQUIRE(heap != nullptr); + // Should be vA0000000 heap + } + + SECTION("Physical heap with 16MB pages") { + auto* heap = memory.LookupHeapByType(true, 16 * 1024 * 1024); + REQUIRE(heap != nullptr); + // Should be vC0000000 heap + } +} diff --git a/tests/unit/ppc/import_function_test.cpp b/tests/unit/ppc/import_function_test.cpp new file mode 100644 index 0000000..c0bf0b1 --- /dev/null +++ b/tests/unit/ppc/import_function_test.cpp @@ -0,0 +1,49 @@ +/** + * Tests for ArgTranslator stack argument support and ImportFunction isolation. + */ + +#include +#include + +#include + +#include +#include + +using namespace rex::ppc; + +// Fake 64KB guest memory block for tests +alignas(64) static uint8_t g_test_mem[0x10000] = {}; + +TEST_CASE("SetIntegerArgumentValue writes stack args for index > 7", "[ppc][arg_translator]") { + PPCContext ctx{}; + ctx.r1.u32 = 0x8000; + + ArgTranslator::SetIntegerArgumentValue(ctx, g_test_mem, 8, 0xDEADBEEF); + + uint64_t readback = ArgTranslator::GetIntegerArgumentValue(ctx, g_test_mem, 8); + CHECK(readback == 0xDEADBEEF); +} + +TEST_CASE("SetIntegerArgumentValue writes multiple stack args at correct offsets", + "[ppc][arg_translator]") { + PPCContext ctx{}; + ctx.r1.u32 = 0x8000; + std::memset(g_test_mem + 0x8000, 0, 0x100); + + ArgTranslator::SetIntegerArgumentValue(ctx, g_test_mem, 8, 0x11111111); + ArgTranslator::SetIntegerArgumentValue(ctx, g_test_mem, 9, 0x22222222); + ArgTranslator::SetIntegerArgumentValue(ctx, g_test_mem, 10, 0x33333333); + + CHECK(ArgTranslator::GetIntegerArgumentValue(ctx, g_test_mem, 8) == 0x11111111); + CHECK(ArgTranslator::GetIntegerArgumentValue(ctx, g_test_mem, 9) == 0x22222222); + CHECK(ArgTranslator::GetIntegerArgumentValue(ctx, g_test_mem, 10) == 0x33333333); +} + +TEST_CASE("SetIntegerArgumentValue still works for register args 0-7", "[ppc][arg_translator]") { + PPCContext ctx{}; + ArgTranslator::SetIntegerArgumentValue(ctx, g_test_mem, 0, 0xAAAA); + ArgTranslator::SetIntegerArgumentValue(ctx, g_test_mem, 7, 0xBBBB); + CHECK(ctx.r3.u64 == 0xAAAA); + CHECK(ctx.r10.u64 == 0xBBBB); +} diff --git a/tests/unit/ppc/stack_test.cpp b/tests/unit/ppc/stack_test.cpp new file mode 100644 index 0000000..0617741 --- /dev/null +++ b/tests/unit/ppc/stack_test.cpp @@ -0,0 +1,144 @@ +/** + * Tests for rex::ppc stack push/pop/guard operations. + */ + +#include +#include + +#include + +#include +#include + +// 64KB test memory, aligned +alignas(64) static uint8_t g_mem[0x10000] = {}; + +TEST_CASE("stack_push scalar decrements r1 and writes byte-swapped value", "[ppc][stack]") { + PPCContext ctx{}; + ctx.r1.u32 = 0x8000; + + uint32_t addr = rex::ppc::stack_push(ctx, g_mem, uint32_t{0x12345678}); + + CHECK(ctx.r1.u32 == 0x8000 - 8); + CHECK(addr == ctx.r1.u32); + uint32_t raw; + std::memcpy(&raw, g_mem + addr, 4); + CHECK(raw == __builtin_bswap32(0x12345678)); +} + +TEST_CASE("stack_push float writes byte-swapped float", "[ppc][stack]") { + PPCContext ctx{}; + ctx.r1.u32 = 0x8000; + + float val = 3.14f; + uint32_t addr = rex::ppc::stack_push(ctx, g_mem, val); + + CHECK(ctx.r1.u32 == 0x8000 - 8); + uint32_t raw; + std::memcpy(&raw, g_mem + addr, 4); + uint32_t val_bits; + std::memcpy(&val_bits, &val, 4); + CHECK(raw == __builtin_bswap32(val_bits)); +} + +TEST_CASE("stack_push_string writes NUL-terminated string", "[ppc][stack]") { + PPCContext ctx{}; + ctx.r1.u32 = 0x8000; + std::memset(g_mem + 0x7F00, 0, 0x100); + + uint32_t addr = rex::ppc::stack_push_string(ctx, g_mem, "hello"); + + CHECK(ctx.r1.u32 == 0x8000 - 8); + CHECK(addr == ctx.r1.u32); + CHECK(std::strcmp(reinterpret_cast(g_mem + addr), "hello") == 0); +} + +TEST_CASE("stack_push_string aligns to 8 bytes", "[ppc][stack]") { + PPCContext ctx{}; + ctx.r1.u32 = 0x8000; + + uint32_t addr = rex::ppc::stack_push_string(ctx, g_mem, "longstring1"); + CHECK(ctx.r1.u32 == 0x8000 - 16); + CHECK(addr == ctx.r1.u32); +} + +TEST_CASE("stack_push raw bytes", "[ppc][stack]") { + PPCContext ctx{}; + ctx.r1.u32 = 0x8000; + + uint8_t data[] = {0xAA, 0xBB, 0xCC}; + uint32_t addr = rex::ppc::stack_push(ctx, g_mem, data, 3); + + CHECK(ctx.r1.u32 == 0x8000 - 8); + CHECK(g_mem[addr] == 0xAA); + CHECK(g_mem[addr + 1] == 0xBB); + CHECK(g_mem[addr + 2] == 0xCC); +} + +TEST_CASE("stack_pop restores r1", "[ppc][stack]") { + PPCContext ctx{}; + ctx.r1.u32 = 0x8000; + + rex::ppc::stack_push(ctx, g_mem, uint32_t{42}); + CHECK(ctx.r1.u32 == 0x8000 - 8); + + rex::ppc::stack_pop(ctx, 8); + CHECK(ctx.r1.u32 == 0x8000); +} + +TEST_CASE("multiple pushes return stable addresses", "[ppc][stack]") { + PPCContext ctx{}; + ctx.r1.u32 = 0x8000; + + uint32_t addr1 = rex::ppc::stack_push_string(ctx, g_mem, "first"); + uint32_t addr2 = rex::ppc::stack_push_string(ctx, g_mem, "second"); + + CHECK(addr1 != addr2); + CHECK(std::strcmp(reinterpret_cast(g_mem + addr1), "first") == 0); + CHECK(std::strcmp(reinterpret_cast(g_mem + addr2), "second") == 0); +} + +TEST_CASE("stack_guard restores r1 on scope exit", "[ppc][stack]") { + PPCContext ctx{}; + ctx.r1.u32 = 0x8000; + + { + rex::ppc::stack_guard guard(ctx); + rex::ppc::stack_push_string(ctx, g_mem, "temporary"); + CHECK(ctx.r1.u32 < 0x8000); + } + + CHECK(ctx.r1.u32 == 0x8000); +} + +TEST_CASE("stack_guard restores after multiple pushes", "[ppc][stack]") { + PPCContext ctx{}; + ctx.r1.u32 = 0x8000; + + { + rex::ppc::stack_guard guard(ctx); + rex::ppc::stack_push(ctx, g_mem, uint32_t{1}); + rex::ppc::stack_push(ctx, g_mem, uint32_t{2}); + rex::ppc::stack_push_string(ctx, g_mem, "three"); + CHECK(ctx.r1.u32 == 0x8000 - 8 - 8 - 8); + } + + CHECK(ctx.r1.u32 == 0x8000); +} + +TEST_CASE("nested stack_guards restore correctly", "[ppc][stack]") { + PPCContext ctx{}; + ctx.r1.u32 = 0x8000; + + { + rex::ppc::stack_guard outer(ctx); + rex::ppc::stack_push_string(ctx, g_mem, "outer"); + + { + rex::ppc::stack_guard inner(ctx); + rex::ppc::stack_push_string(ctx, g_mem, "inner"); + } + CHECK(ctx.r1.u32 == 0x8000 - 8); + } + CHECK(ctx.r1.u32 == 0x8000); +} diff --git a/tests/unit/rexglue/migration_scan_test.cpp b/tests/unit/rexglue/migration_scan_test.cpp new file mode 100644 index 0000000..fae1526 --- /dev/null +++ b/tests/unit/rexglue/migration_scan_test.cpp @@ -0,0 +1,516 @@ +/** + * @file tests/unit/rexglue/migration_scan_test.cpp + * @brief Tests for project-tree migration scanners + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include "rexglue/commands/migration_scan.h" + +#include + +#include +#include +#include +#include +#include + +namespace fs = std::filesystem; + +namespace { + +struct TempProject { + fs::path root; + explicit TempProject(const std::string& tag = "migration_scan_test") + : root(fs::temp_directory_path() / tag) { + fs::remove_all(root); + fs::create_directories(root / "generated"); + } + ~TempProject() { fs::remove_all(root); } + + void writeRexglueCmake(const std::string& content) const { + std::ofstream f(root / "generated" / "rexglue.cmake"); + f << content; + } + + void writeFile(const fs::path& rel, const std::string& content) const { + fs::create_directories((root / rel).parent_path()); + std::ofstream f(root / rel); + f << content; + } +}; + +} // namespace + +// --------------------------------------------------------------------------- +// SDK template drift +// --------------------------------------------------------------------------- + +TEST_CASE("MigrationScan: empty plan when rexglue.cmake matches template", + "[rexglue][migration_scan]") { + TempProject tp; + std::string rendered = rexglue::cli::RenderRexglueCmake("mygame", "0.8.0", "generated/default"); + tp.writeRexglueCmake(rendered); + + auto plan = rexglue::cli::ScanSdkTemplateDrift(tp.root, "mygame", "0.8.0", "generated/default"); + CHECK(plan.empty()); +} + +TEST_CASE("MigrationScan: drift entry is silent (lives inside generated/)", + "[rexglue][migration_scan]") { + TempProject tp; + tp.writeRexglueCmake("# obviously stale content\n"); + + auto plan = rexglue::cli::ScanSdkTemplateDrift(tp.root, "mygame", "0.8.0", "generated/default"); + REQUIRE(plan.size() == 1u); + CHECK(plan[0].path.filename() == "rexglue.cmake"); + CHECK(plan[0].silent); + CHECK(plan[0].action == rexglue::cli::OverwriteAction::Write); + CHECK(plan[0].rendered_content.find("rex::runtime") != std::string::npos); + CHECK(plan[0].rendered_content.find("generated/default/sources.cmake") != std::string::npos); +} + +TEST_CASE("MigrationScan: drift entry is silent when the file is missing", + "[rexglue][migration_scan]") { + TempProject tp; // generated/rexglue.cmake never written + + auto plan = rexglue::cli::ScanSdkTemplateDrift(tp.root, "mygame", "0.8.0", "generated/default"); + REQUIRE(plan.size() == 1u); + CHECK(plan[0].silent); + CHECK(plan[0].path == tp.root / "generated" / "rexglue.cmake"); +} + +// --------------------------------------------------------------------------- +// CMake reference rewrites +// --------------------------------------------------------------------------- + +TEST_CASE("MigrationScan: ScanCmakeReferences rewrites legacy config refs", + "[rexglue][migration_scan]") { + TempProject tp; + tp.writeFile("CMakeLists.txt", + "add_custom_target(mygame_codegen\n" + " COMMAND rexglue codegen ${CMAKE_CURRENT_SOURCE_DIR}/mygame_config.toml\n" + ")\n"); + tp.writeFile("cmake/extra.cmake", "# nothing to do here\n"); + + auto entries = + rexglue::cli::ScanCmakeReferences(tp.root, "mygame_config.toml", "mygame_manifest.toml"); + REQUIRE(entries.size() == 1u); + CHECK(entries[0].path == tp.root / "CMakeLists.txt"); + CHECK_FALSE(entries[0].silent); + CHECK(entries[0].rendered_content.find("mygame_manifest.toml") != std::string::npos); + CHECK(entries[0].rendered_content.find("mygame_config.toml") == std::string::npos); +} + +TEST_CASE("MigrationScan: ScanCmakeReferences leaves embedded substrings alone", + "[rexglue][migration_scan]") { + TempProject tp; + tp.writeFile("CMakeLists.txt", + "# legacy file: mygame_config.toml.bak retained for reference\n" + "add_custom_target(mygame_codegen\n" + " COMMAND rexglue codegen mygame_config.toml\n" + ")\n"); + auto entries = + rexglue::cli::ScanCmakeReferences(tp.root, "mygame_config.toml", "mygame_manifest.toml"); + REQUIRE(entries.size() == 1u); + CHECK(entries[0].rendered_content.find("mygame_config.toml.bak") != std::string::npos); + CHECK(entries[0].rendered_content.find("rexglue codegen mygame_manifest.toml") != + std::string::npos); +} + +TEST_CASE("MigrationScan: ScanCmakeReferences skips files inside generated/", + "[rexglue][migration_scan]") { + TempProject tp; + tp.writeFile("generated/rexglue.cmake", + "add_custom_target(mygame_codegen\n" + " COMMAND rexglue codegen mygame_config.toml\n" + ")\n"); + + auto entries = + rexglue::cli::ScanCmakeReferences(tp.root, "mygame_config.toml", "mygame_manifest.toml"); + CHECK(entries.empty()); +} + +TEST_CASE("MigrationScan: ScanCmakeReferences ignores irrelevant files", + "[rexglue][migration_scan]") { + TempProject tp; + tp.writeFile("README.md", "mygame_config.toml is the legacy config\n"); + tp.writeFile("src/main.cpp", "// references mygame_config.toml in a comment\n"); + + auto entries = + rexglue::cli::ScanCmakeReferences(tp.root, "mygame_config.toml", "mygame_manifest.toml"); + CHECK(entries.empty()); +} + +// --------------------------------------------------------------------------- +// Source #include rewrites +// --------------------------------------------------------------------------- + +TEST_CASE("MigrationScan: ScanSourceIncludeRewrites renames _config.h to _init.h", + "[rexglue][migration_scan]") { + TempProject tp; + tp.writeFile("src/main.cpp", + "#include \"generated/mygame_config.h\"\n" + "int main() { return 0; }\n"); + + auto entries = rexglue::cli::ScanSourceIncludeRewrites(tp.root, "mygame"); + REQUIRE(entries.size() == 1u); + CHECK(entries[0].path == tp.root / "src" / "main.cpp"); + CHECK_FALSE(entries[0].silent); + CHECK(entries[0].action == rexglue::cli::OverwriteAction::Write); + CHECK(entries[0].rendered_content.find("generated/mygame_init.h") != std::string::npos); + CHECK(entries[0].rendered_content.find("mygame_config.h") == std::string::npos); + CHECK(entries[0].rendered_content.find("int main()") != std::string::npos); +} + +TEST_CASE("MigrationScan: ScanSourceIncludeRewrites drops duplicate when _init.h already present", + "[rexglue][migration_scan]") { + TempProject tp; + tp.writeFile("src/main.cpp", + "#include \"generated/mygame_config.h\"\n" + "#include \"generated/mygame_init.h\"\n" + "int main() { return 0; }\n"); + + auto entries = rexglue::cli::ScanSourceIncludeRewrites(tp.root, "mygame"); + REQUIRE(entries.size() == 1u); + CHECK(entries[0].rendered_content.find("mygame_config.h") == std::string::npos); + std::size_t init_count = 0; + for (std::size_t pos = 0; + (pos = entries[0].rendered_content.find("mygame_init.h", pos)) != std::string::npos; + pos += 1) { + ++init_count; + } + CHECK(init_count == 1u); + CHECK(entries[0].rendered_content.find("int main()") != std::string::npos); +} + +TEST_CASE("MigrationScan: ScanSourceIncludeRewrites no-op when no _config.h reference", + "[rexglue][migration_scan]") { + TempProject tp; + tp.writeFile("src/main.cpp", + "#include \"generated/mygame_init.h\"\n" + "int main() { return 0; }\n"); + + auto entries = rexglue::cli::ScanSourceIncludeRewrites(tp.root, "mygame"); + CHECK(entries.empty()); +} + +TEST_CASE("MigrationScan: ScanSourceIncludeRewrites skips files inside generated/", + "[rexglue][migration_scan]") { + TempProject tp; + tp.writeFile("generated/mygame_register.cpp", "#include \"mygame_config.h\"\n"); + + auto entries = rexglue::cli::ScanSourceIncludeRewrites(tp.root, "mygame"); + CHECK(entries.empty()); +} + +TEST_CASE("MigrationScan: ScanSourceIncludeRewrites only matches the project's own header", + "[rexglue][migration_scan]") { + TempProject tp; + tp.writeFile("src/main.cpp", "#include \"otherproj_config.h\"\n"); + + auto entries = rexglue::cli::ScanSourceIncludeRewrites(tp.root, "mygame"); + CHECK(entries.empty()); +} + +TEST_CASE("MigrationScan: ScanSourceIncludeRewrites is case-insensitive on basename", + "[rexglue][migration_scan]") { + TempProject tp; + tp.writeFile("src/main.cpp", "#include \"MyGame_Config.H\"\n"); + + auto entries = rexglue::cli::ScanSourceIncludeRewrites(tp.root, "mygame"); + REQUIRE(entries.size() == 1u); + CHECK(entries[0].rendered_content.find("mygame_init.h") != std::string::npos); +} + +// --------------------------------------------------------------------------- +// Stale include warnings +// --------------------------------------------------------------------------- + +TEST_CASE("MigrationScan: ScanStaleIncludes matches quoted #include with stale basename", + "[rexglue][migration_scan]") { + TempProject tp("migration_stale_includes"); + tp.writeFile("main.cpp", + R"(#include "generated/foo_config.h" +int main() { return 0; } +)"); + std::unordered_set removed{"foo_config.h"}; + + auto results = rexglue::cli::ScanStaleIncludes(tp.root, removed); + REQUIRE(results.size() == 1u); + CHECK(results[0].file == tp.root / "main.cpp"); + CHECK(results[0].line_number == 1u); + CHECK(results[0].detail.find("generated/foo_config.h") != std::string::npos); + CHECK(results[0].hint.find("no longer emitted") != std::string::npos); +} + +TEST_CASE("MigrationScan: ScanStaleIncludes ignores unrelated #include directives", + "[rexglue][migration_scan]") { + TempProject tp("migration_stale_includes_unrelated"); + tp.writeFile("a.cpp", + R"(#include +#include "bar.h" +)"); + std::unordered_set removed{"foo_config.h"}; + + auto results = rexglue::cli::ScanStaleIncludes(tp.root, removed); + CHECK(results.empty()); +} + +TEST_CASE("MigrationScan: ScanStaleIncludes walks subdirectories and supports common extensions", + "[rexglue][migration_scan]") { + TempProject tp("migration_stale_includes_walk"); + tp.writeFile("a.cpp", "#include \"foo_config.h\"\n"); + tp.writeFile("sub/b.h", "#include \"foo_config.h\"\n"); + tp.writeFile("sub/c.hpp", "#include \n"); + tp.writeFile("sub/d.inl", "#include \"foo_config.h\"\n"); + tp.writeFile("sub/e.txt", "#include \"foo_config.h\"\n"); + std::unordered_set removed{"foo_config.h"}; + + auto results = rexglue::cli::ScanStaleIncludes(tp.root, removed); + CHECK(results.size() == 4u); +} + +TEST_CASE("MigrationScan: ScanStaleIncludes returns empty when src dir does not exist", + "[rexglue][migration_scan]") { + fs::path nonexistent = fs::temp_directory_path() / "migration_stale_includes_missing"; + fs::remove_all(nonexistent); + std::unordered_set removed{"foo.h"}; + auto results = rexglue::cli::ScanStaleIncludes(nonexistent, removed); + CHECK(results.empty()); +} + +TEST_CASE("MigrationScan: ScanStaleIncludes matches case-insensitively on basename", + "[rexglue][migration_scan]") { + TempProject tp("migration_stale_includes_case"); + tp.writeFile("a.cpp", "#include \"Foo_Config.H\"\n"); + std::unordered_set removed{"foo_config.h"}; + + auto results = rexglue::cli::ScanStaleIncludes(tp.root, removed); + REQUIRE(results.size() == 1u); + CHECK(results[0].detail.find("Foo_Config.H") != std::string::npos); +} + +// --------------------------------------------------------------------------- +// Legacy identifier scanner +// --------------------------------------------------------------------------- + +TEST_CASE("MigrationScan: ScanLegacyIdentifiers rewrites whole-token PPC_FUNC to REX_FUNC", + "[rexglue][migration_scan]") { + TempProject tp("migration_legacy_idents"); + tp.writeFile("src/foo.cpp", + "#include \n" + "PPC_FUNC(sub_1234) {\n" + " PPC_LOAD_U32(ctx.r3.u32);\n" + "}\n"); + + auto findings = rexglue::cli::ScanLegacyIdentifiers(tp.root); + REQUIRE(findings.rewrites.size() == 1u); + CHECK(findings.warnings.empty()); + const auto& entry = findings.rewrites[0]; + CHECK(entry.path == tp.root / "src" / "foo.cpp"); + CHECK_FALSE(entry.silent); + CHECK(entry.rendered_content.find("REX_FUNC(sub_1234)") != std::string::npos); + CHECK(entry.rendered_content.find("REX_LOAD_U32") != std::string::npos); + CHECK(entry.rendered_content.find("PPC_FUNC") == std::string::npos); + CHECK(entry.rendered_content.find("PPC_LOAD_U32") == std::string::npos); +} + +TEST_CASE("MigrationScan: ScanLegacyIdentifiers leaves non-matching prefixes alone", + "[rexglue][migration_scan]") { + TempProject tp("migration_legacy_idents_prefix"); + // Real binutils tokens that happen to start with PPC_ but are NOT in the + // breaking-change rule list - they must not be rewritten. + tp.writeFile("src/disasm.cpp", + "#include \n" + "uint32_t op = PPC_OP(insn);\n" + "if (op == PPC_INST_BL) { /* ... */ }\n"); + + auto findings = rexglue::cli::ScanLegacyIdentifiers(tp.root); + CHECK(findings.rewrites.empty()); + CHECK(findings.warnings.empty()); +} + +TEST_CASE("MigrationScan: ScanLegacyIdentifiers warns on tokens with no replacement", + "[rexglue][migration_scan]") { + TempProject tp("migration_legacy_idents_warn"); + tp.writeFile("src/decls.h", "PPC_EXTERN_FUNC(some_helper);\n"); + + auto findings = rexglue::cli::ScanLegacyIdentifiers(tp.root); + CHECK(findings.rewrites.empty()); + REQUIRE(findings.warnings.size() == 1u); + CHECK(findings.warnings[0].file == tp.root / "src" / "decls.h"); + CHECK(findings.warnings[0].line_number == 1u); + CHECK(findings.warnings[0].detail.find("PPC_EXTERN_FUNC") != std::string::npos); + CHECK(findings.warnings[0].hint.find("extern REX_FUNC") != std::string::npos); +} + +TEST_CASE("MigrationScan: ScanLegacyIdentifiers respects identifier boundaries", + "[rexglue][migration_scan]") { + TempProject tp("migration_legacy_idents_boundary"); + // PPC_FUNC_PROLOGUE is a known token; PPC_FUNC_THINGAMAJIG is not. The token + // matcher must prefer the longest run of identifier characters and only + // rewrite when the full identifier is in the rule table. + tp.writeFile("src/bar.cpp", + "PPC_FUNC_PROLOGUE();\n" + "PPC_FUNC_THINGAMAJIG();\n"); + + auto findings = rexglue::cli::ScanLegacyIdentifiers(tp.root); + REQUIRE(findings.rewrites.size() == 1u); + CHECK(findings.rewrites[0].rendered_content.find("REX_FUNC_PROLOGUE();") != std::string::npos); + CHECK(findings.rewrites[0].rendered_content.find("PPC_FUNC_THINGAMAJIG();") != std::string::npos); +} + +TEST_CASE("MigrationScan: ScanLegacyIdentifiers skips files inside generated/", + "[rexglue][migration_scan]") { + TempProject tp("migration_legacy_idents_gen"); + tp.writeFile("generated/foo.cpp", "PPC_FUNC(sub_1) {}\n"); + + auto findings = rexglue::cli::ScanLegacyIdentifiers(tp.root); + CHECK(findings.rewrites.empty()); + CHECK(findings.warnings.empty()); +} + +TEST_CASE("MigrationScan: ScanLegacyIdentifiers accepts a custom rule list", + "[rexglue][migration_scan]") { + TempProject tp("migration_legacy_idents_custom"); + tp.writeFile("src/custom.cpp", "OLD_THING x = NEW_THING;\nUSE_ONCE();\n"); + + std::array rules = {{ + {"OLD_THING", "NEW_THING_V2", "renamed: OLD_THING -> NEW_THING_V2"}, + {"USE_ONCE", "", "removed; manual fix required"}, + }}; + auto findings = rexglue::cli::ScanLegacyIdentifiers(tp.root, rules); + REQUIRE(findings.rewrites.size() == 1u); + CHECK(findings.rewrites[0].rendered_content.find("NEW_THING_V2 x = NEW_THING;") != + std::string::npos); + REQUIRE(findings.warnings.size() == 1u); + CHECK(findings.warnings[0].detail.find("USE_ONCE") != std::string::npos); +} + +// --------------------------------------------------------------------------- +// Call-site pattern scanner +// --------------------------------------------------------------------------- + +TEST_CASE("MigrationScan: ScanCallSitePatterns flags removed game_directory positional", + "[rexglue][migration_scan]") { + TempProject tp("migration_callsite_gamedir"); + tp.writeFile("src/app.cpp", + "#include \n" + "void f() {\n" + " if (GetArgument(\"game_directory\").has_value()) {}\n" + "}\n"); + + auto warnings = rexglue::cli::ScanCallSitePatterns(tp.root); + REQUIRE(warnings.size() == 1u); + CHECK(warnings[0].file == tp.root / "src" / "app.cpp"); + CHECK(warnings[0].line_number == 3u); + CHECK(warnings[0].detail.find("game_directory") != std::string::npos); +} + +TEST_CASE("MigrationScan: ScanCallSitePatterns leaves unrelated GetArgument calls alone", + "[rexglue][migration_scan]") { + TempProject tp("migration_callsite_gamedir_other"); + tp.writeFile("src/app.cpp", " GetArgument(\"verbose\");\n"); + + auto warnings = rexglue::cli::ScanCallSitePatterns(tp.root); + CHECK(warnings.empty()); +} + +TEST_CASE("MigrationScan: ScanCallSitePatterns flags one-arg AllocateThunk", + "[rexglue][migration_scan]") { + TempProject tp("migration_callsite_thunk_one"); + tp.writeFile("src/d.cpp", + "auto* d = dispatcher();\n" + "uint32_t a = d->AllocateThunk(&Helper);\n"); + + auto warnings = rexglue::cli::ScanCallSitePatterns(tp.root); + REQUIRE(warnings.size() == 1u); + CHECK(warnings[0].line_number == 2u); + CHECK(warnings[0].detail.find("AllocateThunk") != std::string::npos); + CHECK(warnings[0].hint.find("caller_address") != std::string::npos); +} + +TEST_CASE("MigrationScan: ScanCallSitePatterns ignores two-arg AllocateThunk", + "[rexglue][migration_scan]") { + TempProject tp("migration_callsite_thunk_two"); + tp.writeFile("src/d.cpp", "uint32_t a = d->AllocateThunk(s_trampolines[i], ctx.lr);\n"); + + auto warnings = rexglue::cli::ScanCallSitePatterns(tp.root); + CHECK(warnings.empty()); +} + +TEST_CASE("MigrationScan: ScanCallSitePatterns handles single arg with nested parens", + "[rexglue][migration_scan]") { + TempProject tp("migration_callsite_thunk_nested"); + tp.writeFile("src/d.cpp", "auto a = d->AllocateThunk(MakeHelper(env));\n"); + + auto warnings = rexglue::cli::ScanCallSitePatterns(tp.root); + REQUIRE(warnings.size() == 1u); + CHECK(warnings[0].detail.find("AllocateThunk") != std::string::npos); +} + +TEST_CASE("MigrationScan: ScanCallSitePatterns ignores zero-arg AllocateThunk", + "[rexglue][migration_scan]") { + TempProject tp("migration_callsite_thunk_zero"); + tp.writeFile("src/d.cpp", "auto a = d->AllocateThunk();\n"); + + auto warnings = rexglue::cli::ScanCallSitePatterns(tp.root); + CHECK(warnings.empty()); +} + +TEST_CASE("MigrationScan: ScanCallSitePatterns skips files inside generated/", + "[rexglue][migration_scan]") { + TempProject tp("migration_callsite_gen"); + tp.writeFile("generated/foo.cpp", " d->AllocateThunk(&Fn);\n"); + + auto warnings = rexglue::cli::ScanCallSitePatterns(tp.root); + CHECK(warnings.empty()); +} + +TEST_CASE("MigrationScan: ScanCallSitePatterns accepts a custom rule list", + "[rexglue][migration_scan]") { + TempProject tp("migration_callsite_custom"); + tp.writeFile("src/x.cpp", " legacy_api(42);\n"); + + std::array rules = {{ + {"legacy_api(", "uses removed legacy_api()", "switch to modern_api() (drop-in)", nullptr}, + }}; + auto warnings = rexglue::cli::ScanCallSitePatterns(tp.root, rules); + REQUIRE(warnings.size() == 1u); + CHECK(warnings[0].detail.find("legacy_api") != std::string::npos); + CHECK(warnings[0].hint.find("modern_api") != std::string::npos); +} + +TEST_CASE("MigrationScan: DefaultCallSiteRules covers known manual fixes", + "[rexglue][migration_scan]") { + auto rules = rexglue::cli::DefaultCallSiteRules(); + REQUIRE(!rules.empty()); + bool saw_gamedir = false; + bool saw_thunk = false; + for (const auto& r : rules) { + if (r.pattern.find("game_directory") != std::string_view::npos) + saw_gamedir = true; + if (r.pattern == "AllocateThunk(") + saw_thunk = true; + } + CHECK(saw_gamedir); + CHECK(saw_thunk); +} + +TEST_CASE("MigrationScan: DefaultBreakingChangeRules covers PPC_ legacy macros", + "[rexglue][migration_scan]") { + auto rules = rexglue::cli::DefaultBreakingChangeRules(); + REQUIRE(!rules.empty()); + bool saw_ppc_func = false; + bool saw_ppc_round_nearest = false; + for (const auto& r : rules) { + if (r.legacy_token == "PPC_FUNC") + saw_ppc_func = (r.replacement == "REX_FUNC"); + if (r.legacy_token == "PPC_ROUND_NEAREST") + saw_ppc_round_nearest = (r.replacement == "rex::ppc::kRoundNearest"); + } + CHECK(saw_ppc_func); + CHECK(saw_ppc_round_nearest); +} diff --git a/tests/unit/rexglue/ui_test.cpp b/tests/unit/rexglue/ui_test.cpp new file mode 100644 index 0000000..7346dbc --- /dev/null +++ b/tests/unit/rexglue/ui_test.cpp @@ -0,0 +1,175 @@ +/** + * @file tests/unit/rexglue/ui_test.cpp + * @brief Unit tests for the rexglue presentation layer + * + * @copyright Copyright (c) 2026 Tom Clay + * @license BSD 3-Clause License + */ + +#include "rexglue/ui/progress.h" +#include "rexglue/ui/ui.h" + +#include +#include +#include +#include +#include + +#include +#include + +namespace { + +// Test helper: build a logger that writes through the sink under test. +struct LoggerHarness { + std::ostringstream out; + std::shared_ptr sink; + std::shared_ptr logger; + + explicit LoggerHarness(bool tty = false, bool color = false) + : sink(std::make_shared(out, tty, color)), + logger(std::make_shared("test", sink)) { + logger->set_level(spdlog::level::trace); + } +}; + +// For block-writer tests we need ui:: free functions to find a global sink. +struct UiBlockHarness { + std::ostringstream out; + UiBlockHarness() { + rexglue::ui::Shutdown(); + rexglue::ui::detail::SetGlobalSinkForTesting( + std::make_unique(out, /*tty=*/false, + /*color=*/false)); + } + ~UiBlockHarness() { rexglue::ui::Shutdown(); } +}; + +} // namespace + +TEST_CASE("PresentationSink routes spdlog messages to the injected stream", "[ui][sink]") { + LoggerHarness h; + h.logger->info("hello world"); + h.logger->flush(); + REQUIRE(h.out.str().find("hello world") != std::string::npos); +} + +TEST_CASE("ui::Banner writes title followed by blank line", "[ui][block]") { + UiBlockHarness h; + rexglue::ui::Banner("ReXGlue 0.8.0.26"); + REQUIRE(h.out.str() == "ReXGlue 0.8.0.26\n\n"); +} + +TEST_CASE("ui::KeyValueBlock aligns keys and emits header", "[ui][block]") { + UiBlockHarness h; + std::array rows = {{ + {"Manifest", "/abs/manifest.toml"}, + {"Project", "reblue (entrypoint + 2 DLLs)"}, + }}; + rexglue::ui::KeyValueBlock("", rows); + auto s = h.out.str(); + REQUIRE(s.find(" Manifest: /abs/manifest.toml\n") != std::string::npos); + REQUIRE(s.find(" Project: reblue (entrypoint + 2 DLLs)\n") != std::string::npos); +} + +TEST_CASE("ui::PlanTable formats rows with action label and reason", "[ui][block]") { + UiBlockHarness h; + std::array rows = {{ + {"write ", "/a/b.toml", "upgrade format"}, + {"delete", "/a/c.toml", "absorbed"}, + }}; + rexglue::ui::PlanTable("Migration: 2 file(s) will be rewritten.", rows); + auto s = h.out.str(); + REQUIRE(s.find("Migration: 2 file(s) will be rewritten.\n") != std::string::npos); + REQUIRE(s.find(" [write ] /a/b.toml") != std::string::npos); + REQUIRE(s.find("upgrade format") != std::string::npos); + REQUIRE(s.find(" [delete] /a/c.toml") != std::string::npos); + REQUIRE(s.find("absorbed") != std::string::npos); +} + +TEST_CASE("ui::ManualReviewList nests detail and optional hint", "[ui][block]") { + UiBlockHarness h; + std::array rows = {{ + {"f.cpp:329", "single-arg call", "pass ctx.lr instead"}, + {"g.cpp:43", "removed positional argument", ""}, + }}; + rexglue::ui::ManualReviewList("Migration: 2 site(s) need manual review:", rows); + auto s = h.out.str(); + REQUIRE(s.find("Migration: 2 site(s) need manual review:\n") != std::string::npos); + REQUIRE(s.find(" f.cpp:329 single-arg call\n") != std::string::npos); + REQUIRE(s.find(" pass ctx.lr instead\n") != std::string::npos); + REQUIRE(s.find(" g.cpp:43 removed positional argument\n") != std::string::npos); + REQUIRE(s.find(" \n") == std::string::npos); +} + +TEST_CASE("ui::Confirm returns false on non-TTY without consuming input", "[ui][confirm]") { + UiBlockHarness h; + std::istringstream input("y\n"); + bool result = rexglue::ui::detail::ConfirmWithStream("Apply?", input, /*tty=*/false); + REQUIRE(result == false); + REQUIRE(input.tellg() == 0); + REQUIRE(h.out.str().find("Apply? [y/N]: ") != std::string::npos); +} + +TEST_CASE("ui::Confirm returns true for 'y' on TTY", "[ui][confirm]") { + UiBlockHarness h; + std::istringstream input("y\n"); + REQUIRE(rexglue::ui::detail::ConfirmWithStream("Apply?", input, + /*tty=*/true) == true); +} + +TEST_CASE("ui::Confirm returns true for 'YES' (case-insensitive)", "[ui][confirm]") { + UiBlockHarness h; + std::istringstream input("YES\n"); + REQUIRE(rexglue::ui::detail::ConfirmWithStream("Apply?", input, + /*tty=*/true) == true); +} + +TEST_CASE("ui::Confirm returns false for 'n', empty, and EOF", "[ui][confirm]") { + for (const std::string& answer : {std::string{"n\n"}, std::string{"\n"}, std::string{}}) { + UiBlockHarness h; + std::istringstream input(answer); + REQUIRE(rexglue::ui::detail::ConfirmWithStream("Apply?", input, + /*tty=*/true) == false); + } +} + +TEST_CASE("ProgressView non-TTY emits one line per event in order", "[ui][progress]") { + UiBlockHarness h; + { + rexglue::ui::ProgressView pv("Recompiling reblue (entrypoint + 1 DLL)"); + pv.moduleStarted("reblue", 0, 2); + pv.phaseChanged("Register"); + pv.phaseChanged("Discover"); + pv.moduleFinished(std::chrono::milliseconds{1234}); + pv.moduleStarted("bdengine", 1, 2); + pv.phaseChanged("Register"); + pv.moduleFinished(std::chrono::milliseconds{2345}); + } + auto s = h.out.str(); + REQUIRE(s.find("Recompiling reblue (entrypoint + 1 DLL)\n") == 0); + auto pos1 = s.find(" start reblue"); + auto pos2 = s.find(" phase reblue: Register"); + auto pos3 = s.find(" phase reblue: Discover"); + auto pos4 = s.find(" done reblue (1.2s)"); + auto pos5 = s.find(" start bdengine"); + auto pos6 = s.find(" done bdengine (2.3s)"); + REQUIRE(pos1 != std::string::npos); + REQUIRE(pos1 < pos2); + REQUIRE(pos2 < pos3); + REQUIRE(pos3 < pos4); + REQUIRE(pos4 < pos5); + REQUIRE(pos5 < pos6); +} + +TEST_CASE("ui::DoneSummary writes single Done line", "[ui][summary]") { + UiBlockHarness h; + rexglue::ui::DoneSummary(std::chrono::milliseconds{8400}); + REQUIRE(h.out.str() == "Done in 8.4s.\n"); +} + +TEST_CASE("ui::FailureSummary writes Failed line with reason and duration", "[ui][summary]") { + UiBlockHarness h; + rexglue::ui::FailureSummary("manifest not found", std::chrono::milliseconds{2500}); + REQUIRE(h.out.str() == "Failed: manifest not found (after 2.5s)\n"); +} diff --git a/tests/unit/system/function_dispatcher_test.cpp b/tests/unit/system/function_dispatcher_test.cpp new file mode 100644 index 0000000..967cccf --- /dev/null +++ b/tests/unit/system/function_dispatcher_test.cpp @@ -0,0 +1,165 @@ +/** + * @file tests/unit/system/function_dispatcher_test.cpp + * @brief Unit tests for caller-aware thunk allocation and unregister cleanup + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include + +#include +#include +#include +#include +#include + +namespace { + +rex::memory::Memory& GetTestMemory() { + static rex::memory::Memory memory; + static bool initialized = false; + if (!initialized) { + rex::InitLogging(); + REQUIRE(memory.Initialize()); + initialized = true; + } + return memory; +} + +void DummyFn(PPCContext&, uint8_t*) {} + +} // namespace + +TEST_CASE("FunctionDispatcher: caller_address routes thunk to caller's module pool", + "[runtime][dispatcher]") { + auto& memory = GetTestMemory(); + rex::runtime::ExportResolver resolver; + rex::runtime::FunctionDispatcher dispatcher(&memory, &resolver); + + constexpr uint32_t kModA = 0x82000000u; + constexpr uint32_t kCodeSize = 0x10000u; + constexpr uint32_t kImageSize = 0x100000u; + + REQUIRE(dispatcher.InitializeFunctionTable(kModA, kCodeSize, kModA, kImageSize)); + + constexpr uint32_t kModB = 0x83000000u; + REQUIRE(dispatcher.InitializeFunctionTable(kModB, kCodeSize, kModB, kImageSize)); + + uint32_t thunk_a = dispatcher.AllocateThunk(&DummyFn, kModA + 0x100); + uint32_t thunk_b = dispatcher.AllocateThunk(&DummyFn, kModB + 0x100); + + CHECK(thunk_a >= kModA + kCodeSize); + CHECK(thunk_a < kModA + kCodeSize + rex::runtime::FunctionDispatcher::kThunkReserveSize); + CHECK(thunk_b >= kModB + kCodeSize); + CHECK(thunk_b < kModB + kCodeSize + rex::runtime::FunctionDispatcher::kThunkReserveSize); + + CHECK(dispatcher.GetFunction(thunk_a) == &DummyFn); + CHECK(dispatcher.GetFunction(thunk_b) == &DummyFn); +} + +TEST_CASE("FunctionDispatcher: AllocateThunk(0) uses the entrypoint pool only when explicit", + "[runtime][dispatcher]") { + // caller_address=0 is reserved for host-initiated allocations that have no + // guest caller (the entrypoint wiring its own __imp__* exports during + // setup). It must land in the entrypoint module's pool. + auto& memory = GetTestMemory(); + rex::runtime::ExportResolver resolver; + rex::runtime::FunctionDispatcher dispatcher(&memory, &resolver); + + constexpr uint32_t kModA = 0x84000000u; + constexpr uint32_t kCodeSize = 0x10000u; + constexpr uint32_t kImageSize = 0x100000u; + + REQUIRE(dispatcher.InitializeFunctionTable(kModA, kCodeSize, kModA, kImageSize, + /*is_entrypoint=*/true)); + + uint32_t thunk = dispatcher.AllocateThunk(&DummyFn, 0); + CHECK(thunk >= kModA + kCodeSize); + CHECK(thunk < kModA + kCodeSize + rex::runtime::FunctionDispatcher::kThunkReserveSize); +} + +TEST_CASE("FunctionDispatcher: AllocateThunk(0) rejects when no entrypoint registered", + "[runtime][dispatcher]") { + auto& memory = GetTestMemory(); + rex::runtime::ExportResolver resolver; + rex::runtime::FunctionDispatcher dispatcher(&memory, &resolver); + + constexpr uint32_t kModA = 0x88000000u; + constexpr uint32_t kCodeSize = 0x10000u; + constexpr uint32_t kImageSize = 0x100000u; + + REQUIRE(dispatcher.InitializeFunctionTable(kModA, kCodeSize, kModA, kImageSize)); + + CHECK(dispatcher.AllocateThunk(&DummyFn, 0) == 0); +} + +TEST_CASE("FunctionDispatcher: AllocateThunk rejects caller_address outside any module", + "[runtime][dispatcher]") { + auto& memory = GetTestMemory(); + rex::runtime::ExportResolver resolver; + rex::runtime::FunctionDispatcher dispatcher(&memory, &resolver); + + constexpr uint32_t kModA = 0x86000000u; + constexpr uint32_t kCodeSize = 0x10000u; + constexpr uint32_t kImageSize = 0x100000u; + + REQUIRE(dispatcher.InitializeFunctionTable(kModA, kCodeSize, kModA, kImageSize)); + + // A non-zero caller_address that doesn't fall inside any module is a bug + // in the caller: the right answer is to refuse, not to silently route the + // thunk to the entrypoint pool. + uint32_t thunk = dispatcher.AllocateThunk(&DummyFn, 0xDEADBEEFu); + CHECK(thunk == 0); +} + +namespace { +constexpr uint32_t kRegisterModBase = 0x85000000u; +void RegisterOne(rex::runtime::IModuleRegistrar* registrar) { + registrar->SetFunction(kRegisterModBase + 0x10, &DummyFn); +} +} // namespace + +TEST_CASE("FunctionDispatcher: UnregisterModule clears pool and slots", "[runtime][dispatcher]") { + auto& memory = GetTestMemory(); + rex::runtime::ExportResolver resolver; + rex::runtime::FunctionDispatcher dispatcher(&memory, &resolver); + + constexpr uint32_t kCodeSize = 0x10000u; + constexpr uint32_t kImageSize = 0x100000u; + + REQUIRE(dispatcher.InitializeFunctionTable(kRegisterModBase, kCodeSize, kRegisterModBase, + kImageSize)); + + dispatcher.RegisterModule("modA", kRegisterModBase, &RegisterOne); + + uint32_t thunk = dispatcher.AllocateThunk(&DummyFn, kRegisterModBase + 0x100); + REQUIRE(thunk != 0); + REQUIRE(dispatcher.GetFunction(kRegisterModBase + 0x10) == &DummyFn); + REQUIRE(dispatcher.GetFunction(thunk) == &DummyFn); + + auto cleared = dispatcher.UnregisterModule("modA"); + REQUIRE(cleared.has_value()); + CHECK(cleared->first == kRegisterModBase + kCodeSize); + CHECK(cleared->second == thunk + 4); + CHECK(dispatcher.GetFunction(kRegisterModBase + 0x10) == nullptr); + CHECK(dispatcher.GetFunction(thunk) == nullptr); + + // Re-init must succeed: UnregisterModule destroys the per-module table so the + // same code range can be reloaded without tripping the overlap check. + REQUIRE(dispatcher.InitializeFunctionTable(kRegisterModBase, kCodeSize, kRegisterModBase, + kImageSize)); + uint32_t thunk_after = dispatcher.AllocateThunk(&DummyFn, kRegisterModBase + 0x100); + CHECK(thunk_after == thunk); +} + +TEST_CASE("FunctionDispatcher: UnregisterModule on unknown id returns nullopt", + "[runtime][dispatcher]") { + auto& memory = GetTestMemory(); + rex::runtime::ExportResolver resolver; + rex::runtime::FunctionDispatcher dispatcher(&memory, &resolver); + CHECK_FALSE(dispatcher.UnregisterModule("nope").has_value()); +} diff --git a/tests/unit/system/guest_path_test.cpp b/tests/unit/system/guest_path_test.cpp new file mode 100644 index 0000000..cd6d9e2 --- /dev/null +++ b/tests/unit/system/guest_path_test.cpp @@ -0,0 +1,33 @@ +/** + * @file tests/unit/system/guest_path_test.cpp + * @brief Unit tests for guest path normalization + * + * @copyright Copyright (c) 2026 Tom Clay + * All rights reserved. + * + * @license BSD 3-Clause License + * See LICENSE file in the project root for full license text. + */ + +#include +#include + +using rex::system::NormalizeGuestPath; + +TEST_CASE("Guest path normalization: strip device prefix", "[system][path]") { + CHECK(NormalizeGuestPath("game:\\bin\\somelib.dll") == "bin/somelib.dll"); + CHECK(NormalizeGuestPath("GAME:\\BIN\\SomeLib.DLL") == "bin/somelib.dll"); + CHECK(NormalizeGuestPath("d:\\content\\modules\\test.dll") == "content/modules/test.dll"); +} + +TEST_CASE("Guest path normalization: already normalized", "[system][path]") { + CHECK(NormalizeGuestPath("bin/somelib.dll") == "bin/somelib.dll"); +} + +TEST_CASE("Guest path normalization: backslash to forward slash", "[system][path]") { + CHECK(NormalizeGuestPath("data\\libs\\foo.dll") == "data/libs/foo.dll"); +} + +TEST_CASE("Guest path normalization: case folding", "[system][path]") { + CHECK(NormalizeGuestPath("BIN/SomeLib.DLL") == "bin/somelib.dll"); +} diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt new file mode 100644 index 0000000..af6607f --- /dev/null +++ b/thirdparty/CMakeLists.txt @@ -0,0 +1,672 @@ +# Third-party vendored dependencies for ReXGlue + +set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) + +#============================================================================= +# Architecture detection +#============================================================================= +if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64)$") + set(IS_ARM64 FALSE) + set(IS_X86_64 TRUE) +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|ARM64)$") + set(IS_ARM64 TRUE) + set(IS_X86_64 FALSE) +else() + set(IS_ARM64 FALSE) + set(IS_X86_64 FALSE) +endif() + +#============================================================================= +# Verify git submodules are initialized (only vendored ones) +#============================================================================= +set(REQUIRED_SUBMODULES + cli11 + libmspack + FFmpeg + tomlplusplus + simde + xxHash + spdlog + fmt + snappy + utfcpp + imgui + sdl3 +) + +if(REXGLUE_USE_VULKAN) + list(APPEND REQUIRED_SUBMODULES + volk vulkan-headers vulkan-memory-allocator + spirv-headers spirv-tools glslang + ) +endif() + + +if(REXGLUE_ENABLE_TRACY) + list(APPEND REQUIRED_SUBMODULES tracy) +endif() + +if(REXGLUE_BUILD_TESTS) + list(APPEND REQUIRED_SUBMODULES catch2) +endif() + +foreach(submodule ${REQUIRED_SUBMODULES}) + if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${submodule}/.git") + message(FATAL_ERROR + "Git submodule '${submodule}' is not initialized.\n" + "Please run: git submodule update --init --recursive\n" + "from the repository root directory." + ) + endif() +endforeach() + +#============================================================================= +# Header-only libraries (vendored, not in vcpkg) +#============================================================================= + +# disruptorplus - lock-free queue (header-only) +add_library(disruptorplus INTERFACE) +target_include_directories(disruptorplus INTERFACE + $ + $) + +# renderdoc - RenderDoc API header (header-only) +add_library(renderdoc INTERFACE) +target_include_directories(renderdoc INTERFACE + $ + $) + +# tomlplusplus - TOML config file parser (header-only) +add_library(tomlplusplus INTERFACE) +target_include_directories(tomlplusplus SYSTEM INTERFACE + $ + $) + +# simde - SIMD Everywhere (header-only, git submodule) +add_library(simde INTERFACE) +target_include_directories(simde INTERFACE + $ + $ + $) + +#============================================================================= +# Compiled libraries (vendored sources) +#============================================================================= + +# tiny-AES-c - AES encryption (used for XEX decryption) +add_library(tiny-aes STATIC + tiny-aes-c/aes.c +) +target_include_directories(tiny-aes PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/tiny-aes-c) +target_compile_definitions(tiny-aes PUBLIC AES128=1 CBC=1) + +# aes_128 - AES-128 encryption/decryption (used by kernel crypt routines) +# From: https://github.com/openluopworld/aes_128 +add_library(aes128 STATIC + aes_128/aes.c +) +target_include_directories(aes128 PUBLIC + $ + $) +# Suppress warnings in third-party C code +target_compile_options(aes128 PRIVATE -w) + +# libmspack - LZX decompression (only lzxd.c needed for XEX decompression). +# Use the real source directory instead of cabextract's symlink mirror so +# Windows checkouts without symlink support compile correctly. +set(MSPACK_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libmspack/libmspack/mspack") +add_library(mspack STATIC + ${MSPACK_DIR}/lzxd.c +) +target_include_directories(mspack PUBLIC + $ + $) +# Suppress warnings in third-party C code +target_compile_options(mspack PRIVATE -w) + +# o1heap - O(1) heap allocator for real-time systems (used by rexcrt heap) +# NOTE: o1heap.c auto-detects CLZ via __builtin_clzl when __clang__/__GNUC__ +# are defined, but on Windows unsigned long is 32-bit even on x64. We inject +# a config header that provides a correct 64-bit CLZ +add_library(o1heap STATIC + o1heap/o1heap/o1heap.c +) +target_include_directories(o1heap PUBLIC + $ + $) +target_compile_definitions(o1heap PRIVATE + "O1HEAP_CONFIG_HEADER=\"${CMAKE_CURRENT_SOURCE_DIR}/../include/rex/o1heap_config.h\"") +target_compile_options(o1heap PRIVATE -w) + +# xxHash - extremely fast non-cryptographic hash (git submodule) +set(XXHASH_BUILD_XXHSUM OFF CACHE BOOL "" FORCE) +add_subdirectory(xxHash/cmake_unofficial) +target_compile_options(xxhash PRIVATE -w) + +# disasm - PowerPC disassembler (existing local library) +add_subdirectory(disasm) +# Suppress warnings in disasm +target_compile_options(disasm PRIVATE -w) + +#============================================================================= +# fmt - Formatting library (must come before spdlog) +#============================================================================= +set(FMT_DOC OFF CACHE BOOL "" FORCE) +set(FMT_TEST OFF CACHE BOOL "" FORCE) +set(FMT_INSTALL ON CACHE BOOL "" FORCE) +add_subdirectory(fmt) +target_compile_options(fmt PRIVATE -w) + +#============================================================================= +# spdlog - Logging library +#============================================================================= +set(SPDLOG_FMT_EXTERNAL ON CACHE BOOL "" FORCE) +set(SPDLOG_BUILD_EXAMPLE OFF CACHE BOOL "" FORCE) +set(SPDLOG_BUILD_TESTS OFF CACHE BOOL "" FORCE) +set(SPDLOG_BUILD_BENCH OFF CACHE BOOL "" FORCE) +set(SPDLOG_INSTALL ON CACHE BOOL "" FORCE) +add_subdirectory(spdlog) +target_compile_options(spdlog PRIVATE -w) + +#============================================================================= +# snappy - Fast compression/decompression (GPU traces) +#============================================================================= +set(SNAPPY_BUILD_TESTS OFF CACHE BOOL "" FORCE) +set(SNAPPY_BUILD_BENCHMARKS OFF CACHE BOOL "" FORCE) +set(SNAPPY_INSTALL ON CACHE BOOL "" FORCE) +add_subdirectory(snappy) +target_compile_options(snappy PRIVATE -w) + +#============================================================================= +# utfcpp - UTF-8 string library (header-only) +#============================================================================= +add_subdirectory(utfcpp) + +#============================================================================= +# Vulkan dependencies (only when Vulkan backend is enabled) +#============================================================================= +if(REXGLUE_USE_VULKAN) + # Vulkan-Headers + set(VULKAN_HEADERS_ENABLE_TESTS OFF CACHE BOOL "" FORCE) + set(VULKAN_HEADERS_ENABLE_INSTALL ON CACHE BOOL "" FORCE) + set(VULKAN_HEADERS_ENABLE_MODULE OFF CACHE BOOL "" FORCE) + add_subdirectory(vulkan-headers) + + # VulkanMemoryAllocator + set(VMA_ENABLE_INSTALL ON CACHE BOOL "" FORCE) + add_subdirectory(vulkan-memory-allocator) + + # volk + set(VOLK_INSTALL ON CACHE BOOL "" FORCE) + set(VOLK_PULL_IN_VULKAN OFF CACHE BOOL "" FORCE) + add_subdirectory(volk) + target_link_libraries(volk PUBLIC Vulkan::Headers) + target_link_libraries(volk_headers INTERFACE Vulkan::Headers) + target_compile_options(volk PRIVATE -w) +endif() + +#============================================================================= +# FidelityFX (optional, fetched on demand) +#============================================================================= +include(${PROJECT_SOURCE_DIR}/cmake/rexglue_fidelityfx.cmake) + +#============================================================================= +# imgui - Immediate mode GUI (no CMakeLists.txt, manual target) +#============================================================================= +set(IMGUI_DIR "${CMAKE_CURRENT_SOURCE_DIR}/imgui") +add_library(imgui OBJECT + ${IMGUI_DIR}/imgui.cpp + ${IMGUI_DIR}/imgui_demo.cpp + ${IMGUI_DIR}/imgui_draw.cpp + ${IMGUI_DIR}/imgui_tables.cpp + ${IMGUI_DIR}/imgui_widgets.cpp +) +add_library(imgui::imgui ALIAS imgui) +target_include_directories(imgui PUBLIC + $ + $) +target_compile_options(imgui PRIVATE -w) + +#============================================================================= +# SDL3 - Cross-platform media layer +#============================================================================= +set(SDL_INSTALL ON CACHE BOOL "" FORCE) +set(SDL_SHARED OFF CACHE BOOL "" FORCE) +set(SDL_STATIC ON CACHE BOOL "" FORCE) +set(SDL_TEST OFF CACHE BOOL "" FORCE) +set(SDL_UNIX_CONSOLE_BUILD ON CACHE BOOL "" FORCE) + +# Disable unused subsystems +set(SDL_VIDEO OFF CACHE BOOL "" FORCE) +set(SDL_RENDER OFF CACHE BOOL "" FORCE) +set(SDL_HAPTIC OFF CACHE BOOL "" FORCE) +set(SDL_SENSOR OFF CACHE BOOL "" FORCE) +set(SDL_POWER OFF CACHE BOOL "" FORCE) +set(SDL_FILESYSTEM OFF CACHE BOOL "" FORCE) +set(SDL_LOCALE OFF CACHE BOOL "" FORCE) +set(SDL_FILE OFF CACHE BOOL "" FORCE) +set(SDL_MISC OFF CACHE BOOL "" FORCE) +set(SDL_DIALOG OFF CACHE BOOL "" FORCE) +set(SDL_TRAY OFF CACHE BOOL "" FORCE) +set(SDL_CAMERA OFF CACHE BOOL "" FORCE) + +# Disable graphics APIs (unused without video) +set(SDL_OPENGL OFF CACHE BOOL "" FORCE) +set(SDL_OPENGLES OFF CACHE BOOL "" FORCE) +set(SDL_VULKAN OFF CACHE BOOL "" FORCE) +set(SDL_METAL OFF CACHE BOOL "" FORCE) + +# Disable dummy drivers +set(SDL_DISKAUDIO OFF CACHE BOOL "" FORCE) +set(SDL_DUMMYAUDIO OFF CACHE BOOL "" FORCE) +set(SDL_DUMMYVIDEO OFF CACHE BOOL "" FORCE) + +# Linux audio backends +if(UNIX AND NOT APPLE) + set(SDL_ALSA ON CACHE BOOL "" FORCE) + set(SDL_ALSA_SHARED ON CACHE BOOL "" FORCE) + set(SDL_PULSEAUDIO ON CACHE BOOL "" FORCE) + set(SDL_PULSEAUDIO_SHARED ON CACHE BOOL "" FORCE) + set(SDL_PIPEWIRE ON CACHE BOOL "" FORCE) + set(SDL_PIPEWIRE_SHARED ON CACHE BOOL "" FORCE) +endif() + +add_subdirectory(sdl3) + +#============================================================================= +# DXC API headers (vendored from DirectXShaderCompiler, runtime-loaded) +#============================================================================= +if(REXGLUE_USE_D3D12) + add_library(dxc-headers INTERFACE) + target_include_directories(dxc-headers INTERFACE + $ + $) +endif() + +#============================================================================= +# SPIR-V toolchain (only when Vulkan backend is enabled) +#============================================================================= +if(REXGLUE_USE_VULKAN) + # SPIRV-Headers + set(SPIRV_HEADERS_ENABLE_TESTS OFF CACHE BOOL "" FORCE) + set(SPIRV_HEADERS_ENABLE_INSTALL OFF CACHE BOOL "" FORCE) + add_subdirectory(spirv-headers) + + # SPIRV-Tools + set(SPIRV_SKIP_EXECUTABLES ON CACHE BOOL "" FORCE) + set(SPIRV_SKIP_TESTS ON CACHE BOOL "" FORCE) + set(SPIRV_WERROR OFF CACHE BOOL "" FORCE) + set(SKIP_SPIRV_TOOLS_INSTALL ON CACHE BOOL "" FORCE) + add_subdirectory(spirv-tools) + target_compile_options(SPIRV-Tools-static PRIVATE -w) + + # glslang/SPIRV - SPIR-V code generation for shader translation + set(ENABLE_GLSLANG_BINARIES OFF CACHE BOOL "" FORCE) + set(ENABLE_SPVREMAPPER OFF CACHE BOOL "" FORCE) + set(ENABLE_HLSL OFF CACHE BOOL "" FORCE) + set(ENABLE_OPT OFF CACHE BOOL "" FORCE) + set(BUILD_TESTING OFF CACHE BOOL "" FORCE) + set(SKIP_GLSLANG_INSTALL ON CACHE BOOL "" FORCE) + # Enable RTTI for spv::Builder inheritance in SpirvBuilder + set(ENABLE_RTTI ON CACHE BOOL "" FORCE) + + # Set policy minimum for older glslang versions with outdated cmake_minimum_required + set(CMAKE_POLICY_VERSION_MINIMUM 3.5 CACHE STRING "" FORCE) + add_subdirectory(glslang) + # Create alias for older glslang versions that don't provide it + if(NOT TARGET glslang::SPIRV) + add_library(glslang::SPIRV ALIAS SPIRV) + endif() +endif() + +#============================================================================= +# Catch2 - Test framework (only when tests are enabled, not part of SDK install) +#============================================================================= +if(REXGLUE_BUILD_TESTS) + add_subdirectory(catch2) +endif() + +#============================================================================= +# Tracy Profiler (optional) +#============================================================================= +if(REXGLUE_ENABLE_TRACY) + set(TRACY_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/tracy) + set(TRACY_PUBLIC_DIR ${TRACY_ROOT}/public) + + find_package(Threads REQUIRED) + + add_library(TracyClient SHARED ${TRACY_PUBLIC_DIR}/TracyClient.cpp) + add_library(Tracy::TracyClient ALIAS TracyClient) + + target_compile_features(TracyClient PUBLIC cxx_std_11) + + target_include_directories(TracyClient SYSTEM PUBLIC + $ + $ + ) + + target_link_libraries(TracyClient PUBLIC Threads::Threads ${CMAKE_DL_LIBS}) + + if(WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + target_link_libraries(TracyClient PUBLIC ws2_32 dbghelp) + endif() + + target_compile_definitions(TracyClient + PRIVATE + TRACY_EXPORTS + PUBLIC + TRACY_IMPORTS + TRACY_ENABLE + TRACY_ON_DEMAND + TRACY_DELAYED_INIT + TRACY_MANUAL_LIFETIME + TRACY_FIBERS + ) + + target_compile_options(TracyClient PRIVATE -w) + + install(DIRECTORY ${TRACY_PUBLIC_DIR}/tracy + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/tracy + FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h" PATTERN "*.hmm") + install(DIRECTORY ${TRACY_PUBLIC_DIR}/client + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/tracy + FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h") + install(DIRECTORY ${TRACY_PUBLIC_DIR}/common + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/tracy + FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h") +endif() + +#============================================================================= +# FFmpeg - Audio/video codec library (for XMA decoding) +# Only builds libavutil and libavcodec needed for WMA Pro decoding +#============================================================================= + +set(FFMPEG_DIR "${CMAKE_CURRENT_SOURCE_DIR}/FFmpeg") + +# Overlay generated FFmpeg list files +set(FFMPEG_OVERLAY_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ffmpeg-overlay") +set(FFMPEG_OVERLAY_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/ffmpeg-overlay") +file(MAKE_DIRECTORY "${FFMPEG_OVERLAY_BUILD_DIR}/libavcodec") +configure_file( + "${FFMPEG_OVERLAY_SRC_DIR}/codec_list.c" "${FFMPEG_OVERLAY_BUILD_DIR}/libavcodec/codec_list.c" + COPYONLY +) +configure_file( + "${FFMPEG_OVERLAY_SRC_DIR}/parser_list.c" "${FFMPEG_OVERLAY_BUILD_DIR}/libavcodec/parser_list.c" + COPYONLY +) +configure_file( + "${FFMPEG_OVERLAY_SRC_DIR}/bsf_list.c" "${FFMPEG_OVERLAY_BUILD_DIR}/libavcodec/bsf_list.c" + COPYONLY +) + +# Common defines for both libraries +set(FFMPEG_COMMON_DEFINES + HAVE_AV_CONFIG_H + _USE_MATH_DEFINES # For M_PI/etc +) + +# Platform-specific include paths for atomics +if(WIN32) + set(FFMPEG_ATOMICS_INCLUDE "${FFMPEG_DIR}/compat/atomics/win32") +else() + set(FFMPEG_ATOMICS_INCLUDE "${FFMPEG_DIR}/compat/atomics/gcc") +endif() + +#============================================================================= +# ARM64 setup for FFmpeg (NEON optimizations) +#============================================================================= +if(IS_ARM64) + enable_language(ASM) + set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -march=armv8-a") +endif() + +# libavutil - FFmpeg utility library (must build first) +add_library(libavutil STATIC + ${FFMPEG_DIR}/libavutil/adler32.c + ${FFMPEG_DIR}/libavutil/aes.c + ${FFMPEG_DIR}/libavutil/aes_ctr.c + ${FFMPEG_DIR}/libavutil/audio_fifo.c + ${FFMPEG_DIR}/libavutil/avstring.c + ${FFMPEG_DIR}/libavutil/avsscanf.c + ${FFMPEG_DIR}/libavutil/base64.c + ${FFMPEG_DIR}/libavutil/blowfish.c + ${FFMPEG_DIR}/libavutil/bprint.c + ${FFMPEG_DIR}/libavutil/buffer.c + ${FFMPEG_DIR}/libavutil/cast5.c + ${FFMPEG_DIR}/libavutil/camellia.c + ${FFMPEG_DIR}/libavutil/channel_layout.c + ${FFMPEG_DIR}/libavutil/color_utils.c + ${FFMPEG_DIR}/libavutil/cpu.c + ${FFMPEG_DIR}/libavutil/crc.c + ${FFMPEG_DIR}/libavutil/des.c + ${FFMPEG_DIR}/libavutil/dict.c + ${FFMPEG_DIR}/libavutil/display.c + ${FFMPEG_DIR}/libavutil/dovi_meta.c + ${FFMPEG_DIR}/libavutil/downmix_info.c + ${FFMPEG_DIR}/libavutil/encryption_info.c + ${FFMPEG_DIR}/libavutil/error.c + ${FFMPEG_DIR}/libavutil/eval.c + ${FFMPEG_DIR}/libavutil/fifo.c + ${FFMPEG_DIR}/libavutil/file.c + ${FFMPEG_DIR}/libavutil/file_open.c + ${FFMPEG_DIR}/libavutil/float_dsp.c + ${FFMPEG_DIR}/libavutil/fixed_dsp.c + ${FFMPEG_DIR}/libavutil/frame.c + ${FFMPEG_DIR}/libavutil/hash.c + ${FFMPEG_DIR}/libavutil/hdr_dynamic_metadata.c + ${FFMPEG_DIR}/libavutil/hmac.c + ${FFMPEG_DIR}/libavutil/hwcontext.c + ${FFMPEG_DIR}/libavutil/imgutils.c + ${FFMPEG_DIR}/libavutil/integer.c + ${FFMPEG_DIR}/libavutil/intmath.c + ${FFMPEG_DIR}/libavutil/lfg.c + ${FFMPEG_DIR}/libavutil/lls.c + ${FFMPEG_DIR}/libavutil/log.c + ${FFMPEG_DIR}/libavutil/log2_tab.c + ${FFMPEG_DIR}/libavutil/mathematics.c + ${FFMPEG_DIR}/libavutil/mastering_display_metadata.c + ${FFMPEG_DIR}/libavutil/md5.c + ${FFMPEG_DIR}/libavutil/mem.c + ${FFMPEG_DIR}/libavutil/murmur3.c + ${FFMPEG_DIR}/libavutil/opt.c + ${FFMPEG_DIR}/libavutil/parseutils.c + ${FFMPEG_DIR}/libavutil/pixdesc.c + ${FFMPEG_DIR}/libavutil/pixelutils.c + ${FFMPEG_DIR}/libavutil/random_seed.c + ${FFMPEG_DIR}/libavutil/rational.c + ${FFMPEG_DIR}/libavutil/reverse.c + ${FFMPEG_DIR}/libavutil/rc4.c + ${FFMPEG_DIR}/libavutil/ripemd.c + ${FFMPEG_DIR}/libavutil/samplefmt.c + ${FFMPEG_DIR}/libavutil/sha.c + ${FFMPEG_DIR}/libavutil/sha512.c + ${FFMPEG_DIR}/libavutil/slicethread.c + ${FFMPEG_DIR}/libavutil/spherical.c + ${FFMPEG_DIR}/libavutil/stereo3d.c + ${FFMPEG_DIR}/libavutil/threadmessage.c + ${FFMPEG_DIR}/libavutil/time.c + ${FFMPEG_DIR}/libavutil/timecode.c + ${FFMPEG_DIR}/libavutil/tree.c + ${FFMPEG_DIR}/libavutil/twofish.c + ${FFMPEG_DIR}/libavutil/utils.c + ${FFMPEG_DIR}/libavutil/xga_font_data.c + ${FFMPEG_DIR}/libavutil/xtea.c + ${FFMPEG_DIR}/libavutil/tea.c + ${FFMPEG_DIR}/libavutil/tx.c + ${FFMPEG_DIR}/libavutil/tx_float.c + ${FFMPEG_DIR}/libavutil/tx_double.c + ${FFMPEG_DIR}/libavutil/tx_int32.c + ${FFMPEG_DIR}/libavutil/video_enc_params.c + ${FFMPEG_DIR}/libavutil/film_grain_params.c +) + +# Add x86 optimizations +if(IS_X86_64) + target_sources(libavutil PRIVATE + ${FFMPEG_DIR}/libavutil/x86/cpu.c + ${FFMPEG_DIR}/libavutil/x86/fixed_dsp_init.c + ${FFMPEG_DIR}/libavutil/x86/float_dsp_init.c + ${FFMPEG_DIR}/libavutil/x86/imgutils_init.c + ${FFMPEG_DIR}/libavutil/x86/lls_init.c + ) +endif() + +# ARM64 optimizations for libavutil +if(IS_ARM64) + target_sources(libavutil PRIVATE + ${FFMPEG_DIR}/libavutil/aarch64/cpu.c + ${FFMPEG_DIR}/libavutil/aarch64/float_dsp_init.c + ${FFMPEG_DIR}/libavutil/aarch64/float_dsp_neon.S + ) + target_compile_definitions(libavutil PRIVATE + HAVE_NEON=1 + HAVE_ARMV8=1 + HAVE_INLINE_ASM=1 + ) +endif() + +target_include_directories(libavutil + PUBLIC + $ + $ + PRIVATE ${FFMPEG_ATOMICS_INCLUDE} +) +target_compile_definitions(libavutil PRIVATE ${FFMPEG_COMMON_DEFINES}) +target_compile_options(libavutil PRIVATE -w) # Suppress warnings in third-party code +if(WIN32) + target_link_libraries(libavutil PRIVATE bcrypt) +endif() + +# libavcodec - FFmpeg codec library (depends on libavutil) +add_library(libavcodec STATIC + ${FFMPEG_DIR}/libavcodec/ac3_parser.c + ${FFMPEG_DIR}/libavcodec/adts_parser.c + ${FFMPEG_DIR}/libavcodec/allcodecs.c + ${FFMPEG_DIR}/libavcodec/avcodec.c + ${FFMPEG_DIR}/libavcodec/avdct.c + ${FFMPEG_DIR}/libavcodec/avpacket.c + ${FFMPEG_DIR}/libavcodec/avpicture.c + ${FFMPEG_DIR}/libavcodec/bitstream.c + ${FFMPEG_DIR}/libavcodec/bitstream_filter.c + ${FFMPEG_DIR}/libavcodec/bitstream_filters.c + ${FFMPEG_DIR}/libavcodec/bsf.c + ${FFMPEG_DIR}/libavcodec/codec_desc.c + ${FFMPEG_DIR}/libavcodec/codec_par.c + ${FFMPEG_DIR}/libavcodec/d3d11va.c + ${FFMPEG_DIR}/libavcodec/decode.c + ${FFMPEG_DIR}/libavcodec/dirac.c + ${FFMPEG_DIR}/libavcodec/dv_profile.c + ${FFMPEG_DIR}/libavcodec/encode.c + ${FFMPEG_DIR}/libavcodec/imgconvert.c + ${FFMPEG_DIR}/libavcodec/jni.c + ${FFMPEG_DIR}/libavcodec/mathtables.c + ${FFMPEG_DIR}/libavcodec/mediacodec.c + ${FFMPEG_DIR}/libavcodec/mpeg12framerate.c + ${FFMPEG_DIR}/libavcodec/options.c + ${FFMPEG_DIR}/libavcodec/parser.c + ${FFMPEG_DIR}/libavcodec/parsers.c + ${FFMPEG_DIR}/libavcodec/profiles.c + ${FFMPEG_DIR}/libavcodec/qsv_api.c + ${FFMPEG_DIR}/libavcodec/raw.c + ${FFMPEG_DIR}/libavcodec/utils.c + ${FFMPEG_DIR}/libavcodec/vorbis_parser.c + ${FFMPEG_DIR}/libavcodec/xiph.c + ${FFMPEG_DIR}/libavcodec/faandct.c + ${FFMPEG_DIR}/libavcodec/faanidct.c + ${FFMPEG_DIR}/libavcodec/fdctdsp.c + ${FFMPEG_DIR}/libavcodec/jfdctfst.c + ${FFMPEG_DIR}/libavcodec/jfdctint.c + ${FFMPEG_DIR}/libavcodec/idctdsp.c + ${FFMPEG_DIR}/libavcodec/simple_idct.c + ${FFMPEG_DIR}/libavcodec/jrevdct.c + ${FFMPEG_DIR}/libavcodec/mdct_float.c + ${FFMPEG_DIR}/libavcodec/mdct_fixed_32.c + ${FFMPEG_DIR}/libavcodec/sinewin.c + ${FFMPEG_DIR}/libavcodec/wma_freqs.c + ${FFMPEG_DIR}/libavcodec/wmaprodec.c + ${FFMPEG_DIR}/libavcodec/wmadec.c + ${FFMPEG_DIR}/libavcodec/wma.c + ${FFMPEG_DIR}/libavcodec/wma_common.c + ${FFMPEG_DIR}/libavcodec/mpegaudio.c + ${FFMPEG_DIR}/libavcodec/mpegaudiodata.c + ${FFMPEG_DIR}/libavcodec/mpegaudiodecheader.c + ${FFMPEG_DIR}/libavcodec/mpegaudiodec_common.c + ${FFMPEG_DIR}/libavcodec/mpegaudiodec_float.c + ${FFMPEG_DIR}/libavcodec/mpegaudiodec_fixed.c + ${FFMPEG_DIR}/libavcodec/mpegaudiodsp.c + ${FFMPEG_DIR}/libavcodec/mpegaudiodsp_data.c + ${FFMPEG_DIR}/libavcodec/mpegaudiodsp_float.c + ${FFMPEG_DIR}/libavcodec/mpegaudiodsp_fixed.c + ${FFMPEG_DIR}/libavcodec/mpegaudio_parser.c + ${FFMPEG_DIR}/libavcodec/dct.c + ${FFMPEG_DIR}/libavcodec/dct32_float.c + ${FFMPEG_DIR}/libavcodec/dct32_fixed.c + ${FFMPEG_DIR}/libavcodec/rdft.c + ${FFMPEG_DIR}/libavcodec/aactab.c + ${FFMPEG_DIR}/libavcodec/null_bsf.c + ${FFMPEG_DIR}/libavcodec/pthread.c + ${FFMPEG_DIR}/libavcodec/pthread_slice.c + ${FFMPEG_DIR}/libavcodec/pthread_frame.c + ${FFMPEG_DIR}/libavcodec/avfft.c + ${FFMPEG_DIR}/libavcodec/fft_float.c + ${FFMPEG_DIR}/libavcodec/fft_fixed_32.c + ${FFMPEG_DIR}/libavcodec/fft_init_table.c +) + +# Windows-specific source +if(WIN32) + target_sources(libavcodec PRIVATE + ${FFMPEG_DIR}/libavcodec/file_open.c + ) +endif() + +# Add x86 optimizations +if(IS_X86_64) + target_sources(libavcodec PRIVATE + ${FFMPEG_DIR}/libavcodec/x86/constants.c + ${FFMPEG_DIR}/libavcodec/x86/fdctdsp_init.c + ${FFMPEG_DIR}/libavcodec/x86/fft_init.c + ${FFMPEG_DIR}/libavcodec/x86/idctdsp_init.c + ${FFMPEG_DIR}/libavcodec/x86/fdct.c + ${FFMPEG_DIR}/libavcodec/x86/mpegaudiodsp.c + ${FFMPEG_DIR}/libavcodec/x86/dct_init.c + ) +endif() + +# ARM64 optimizations for libavcodec +if(IS_ARM64) + target_sources(libavcodec PRIVATE + ${FFMPEG_DIR}/libavcodec/aarch64/fft_init_aarch64.c + ${FFMPEG_DIR}/libavcodec/aarch64/fft_neon.S + ${FFMPEG_DIR}/libavcodec/aarch64/mdct_neon.S + ${FFMPEG_DIR}/libavcodec/aarch64/simple_idct_neon.S + ${FFMPEG_DIR}/libavcodec/aarch64/videodsp.S + ${FFMPEG_DIR}/libavcodec/aarch64/neon.S + ${FFMPEG_DIR}/libavcodec/aarch64/mpegaudiodsp_init.c + ${FFMPEG_DIR}/libavcodec/aarch64/mpegaudiodsp_neon.S + ) + target_compile_definitions(libavcodec PRIVATE + HAVE_NEON=1 + HAVE_ARMV8=1 + HAVE_INLINE_ASM=1 + ) +endif() + +target_include_directories(libavcodec BEFORE PRIVATE "${FFMPEG_OVERLAY_BUILD_DIR}") + +target_include_directories(libavcodec + PUBLIC + $ + $ + PRIVATE ${FFMPEG_ATOMICS_INCLUDE} +) +target_compile_definitions(libavcodec PRIVATE ${FFMPEG_COMMON_DEFINES}) +target_compile_options(libavcodec PRIVATE -w) # Suppress warnings in third-party code +target_link_libraries(libavcodec PUBLIC libavutil) +if(WIN32) + target_link_libraries(libavcodec PRIVATE bcrypt) +endif() + +# IDE folder organization +set_target_properties(libavutil libavcodec PROPERTIES FOLDER "FFmpeg") diff --git a/thirdparty/FFmpeg b/thirdparty/FFmpeg new file mode 160000 index 0000000..0604b46 --- /dev/null +++ b/thirdparty/FFmpeg @@ -0,0 +1 @@ +Subproject commit 0604b464c7cb4ebc94940cf1f324a3b26b87717c diff --git a/thirdparty/aes_128/LICENSE b/thirdparty/aes_128/LICENSE new file mode 100644 index 0000000..e0903c4 --- /dev/null +++ b/thirdparty/aes_128/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 LuoPeng + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/thirdparty/aes_128/README.md b/thirdparty/aes_128/README.md new file mode 100644 index 0000000..5ac104e --- /dev/null +++ b/thirdparty/aes_128/README.md @@ -0,0 +1,99 @@ +# AES-128 + +[![Build Status](https://travis-ci.org/openluopworld/aes_128.svg?branch=master)](https://travis-ci.org/openluopworld/aes_128) [![Coverity Scan Build Status](https://img.shields.io/coverity/scan/11502.svg)](https://scan.coverity.com/projects/openluopworld-aes_128) + +C implementation of AES-128. No modes are given. This code has been tested with GCC 4.8.4 and Valgrind-3.11.0 on Intel-i5-3230. + +## How to read + +Reading of the paper [AES Proposal: Rijndael](https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf#page=3) first is recommended. If you care more about the implementation, Chapter 4 is enough. + ++ Reference implementation: ./aes.c + - This should be read first. Since it is the reference implementation. ++ Full unroll implementation: ./unroll/aes.c + - The full unroll impelementation is easy to understand if you have read the reference one. ++ Look up table implementation: ./lut/aes.c + - Lut may be something difficult. But it is widely used in softwares. + - gen_dec_key_table.c, gen_enc_table.c and gen_dec_table.c are utils. + - This code suppose the mechine is little-endian. ++ If you still have interest, the advanced implementations with SIMD instructions or hardware instructions can be found in some famous projects. + +## Usage + +### Interface + +```C +/** + * @purpose: Key schedule for AES-128 + * @par[in]key: 16 bytes of master keys + * @par[out]roundkeys: 176 bytes of round keys + */ +void aes_key_schedule_128(const uint8_t *key, uint8_t *roundkeys); + +/** + * @purpose: Encryption. The length of plain and cipher should be one block (16 bytes). + * The plaintext and ciphertext may point to the same memory + * @par[in]roundkeys: round keys + * @par[in]plaintext: plain text + * @par[out]ciphertext: cipher text + */ +void aes_encrypt_128(const uint8_t *roundkeys, const uint8_t *plaintext, uint8_t *ciphertext); + +/** + * @purpose: Decryption. The length of plain and cipher should be one block (16 bytes). + * The ciphertext and plaintext may point to the same memory + * @par[in]roundkeys: round keys + * @par[in]ciphertext: cipher text + * @par[out]plaintext: plain text + */ +void aes_decrypt_128(const uint8_t *roundkeys, const uint8_t *ciphertext, uint8_t *plaintext); +``` + +### Compile +```sh +make +``` + +## Dependencies + ++ The code is written in standard C ++ No dependencies of other libraries + +## Contributing + +If there is anything wrong or if you have any question, just make an issue or email me. + +## Todo +'Todo' may always be 'To do', so I do not like this word, but... + +* Implementation + + SIMD implementation, include SSE and AVX + + [AES NEON](http://www.luopeng.site/2018/aes-neon.html) +* Modes + + ECB, CBC, CTR and XTS +* Add speed test +* Understand White-box Cryptography + + [White-Box Cryptography and an AES Implementation](http://link.springer.com/chapter/10.1007%2F3-540-36492-7_17?LI=true) + + [A Tutorial on White-Box AES](https://eprint.iacr.org/2013/104.pdf). May be better to understand. + +## License + +> Copyright (c) 2017 LuoPeng +> +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in all +> copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +> SOFTWARE. diff --git a/thirdparty/aes_128/_config.yml b/thirdparty/aes_128/_config.yml new file mode 100644 index 0000000..c419263 --- /dev/null +++ b/thirdparty/aes_128/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-cayman \ No newline at end of file diff --git a/thirdparty/aes_128/aes.c b/thirdparty/aes_128/aes.c new file mode 100644 index 0000000..417db4a --- /dev/null +++ b/thirdparty/aes_128/aes.c @@ -0,0 +1,296 @@ +/* + * + * Chinese Academy of Sciences + * State Key Laboratory of Information Security + * Institute of Information Engineering + * + * Copyright (C) 2016 Chinese Academy of Sciences + * + * LuoPeng, luopeng@iie.ac.cn + * Updated in Oct 2016 + * Updated in Jan 2017, update muliple function on GF(2^8). + * + */ +#include +#include + +#include "aes.h" + +/* + * round constants + */ +static uint8_t RC[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; + +/* + * Sbox + */ +static uint8_t SBOX[256] = { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; + +/* + * Inverse Sboxs + */ +static uint8_t INV_SBOX[256] = { + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d}; + +/** + * https://en.wikipedia.org/wiki/Finite_field_arithmetic + * Multiply two numbers in the GF(2^8) finite field defined + * by the polynomial x^8 + x^4 + x^3 + x + 1 = 0 + * We do use mul2(int8_t a) but not mul(uint8_t a, uint8_t b) + * just in order to get a higher speed. + */ +static inline uint8_t mul2(uint8_t a) { + return (a&0x80) ? ((a<<1)^0x1b) : (a<<1); +} + +/** + * @purpose: ShiftRows + * @descrption: + * Row0: s0 s4 s8 s12 <<< 0 byte + * Row1: s1 s5 s9 s13 <<< 1 byte + * Row2: s2 s6 s10 s14 <<< 2 bytes + * Row3: s3 s7 s11 s15 <<< 3 bytes + */ +static void shift_rows(uint8_t *state) { + uint8_t temp; + // row1 + temp = *(state+1); + *(state+1) = *(state+5); + *(state+5) = *(state+9); + *(state+9) = *(state+13); + *(state+13) = temp; + // row2 + temp = *(state+2); + *(state+2) = *(state+10); + *(state+10) = temp; + temp = *(state+6); + *(state+6) = *(state+14); + *(state+14) = temp; + // row3 + temp = *(state+15); + *(state+15) = *(state+11); + *(state+11) = *(state+7); + *(state+7) = *(state+3); + *(state+3) = temp; +} + +/** + * @purpose: Inverse ShiftRows + * @description + * Row0: s0 s4 s8 s12 >>> 0 byte + * Row1: s1 s5 s9 s13 >>> 1 byte + * Row2: s2 s6 s10 s14 >>> 2 bytes + * Row3: s3 s7 s11 s15 >>> 3 bytes + */ +static void inv_shift_rows(uint8_t *state) { + uint8_t temp; + // row1 + temp = *(state+13); + *(state+13) = *(state+9); + *(state+9) = *(state+5); + *(state+5) = *(state+1); + *(state+1) = temp; + // row2 + temp = *(state+14); + *(state+14) = *(state+6); + *(state+6) = temp; + temp = *(state+10); + *(state+10) = *(state+2); + *(state+2) = temp; + // row3 + temp = *(state+3); + *(state+3) = *(state+7); + *(state+7) = *(state+11); + *(state+11) = *(state+15); + *(state+15) = temp; +} + +void aes_key_schedule_128(const uint8_t *key, uint8_t *roundkeys) { + + uint8_t temp[4]; + uint8_t *last4bytes; // point to the last 4 bytes of one round + uint8_t *lastround; + uint8_t i; + + for (i = 0; i < 16; ++i) { + *roundkeys++ = *key++; + } + + last4bytes = roundkeys-4; + for (i = 0; i < AES_ROUNDS; ++i) { + // k0-k3 for next round + temp[3] = SBOX[*last4bytes++]; + temp[0] = SBOX[*last4bytes++]; + temp[1] = SBOX[*last4bytes++]; + temp[2] = SBOX[*last4bytes++]; + temp[0] ^= RC[i]; + lastround = roundkeys-16; + *roundkeys++ = temp[0] ^ *lastround++; + *roundkeys++ = temp[1] ^ *lastround++; + *roundkeys++ = temp[2] ^ *lastround++; + *roundkeys++ = temp[3] ^ *lastround++; + // k4-k7 for next round + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + // k8-k11 for next round + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + // k12-k15 for next round + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + } +} + +void aes_encrypt_128(const uint8_t *roundkeys, const uint8_t *plaintext, uint8_t *ciphertext) { + + uint8_t tmp[16], t; + uint8_t i, j; + + // first AddRoundKey + for ( i = 0; i < AES_BLOCK_SIZE; ++i ) { + *(ciphertext+i) = *(plaintext+i) ^ *roundkeys++; + } + + // 9 rounds + for (j = 1; j < AES_ROUNDS; ++j) { + + // SubBytes + for (i = 0; i < AES_BLOCK_SIZE; ++i) { + *(tmp+i) = SBOX[*(ciphertext+i)]; + } + shift_rows(tmp); + /* + * MixColumns + * [02 03 01 01] [s0 s4 s8 s12] + * [01 02 03 01] . [s1 s5 s9 s13] + * [01 01 02 03] [s2 s6 s10 s14] + * [03 01 01 02] [s3 s7 s11 s15] + */ + for (i = 0; i < AES_BLOCK_SIZE; i+=4) { + t = tmp[i] ^ tmp[i+1] ^ tmp[i+2] ^ tmp[i+3]; + ciphertext[i] = mul2(tmp[i] ^ tmp[i+1]) ^ tmp[i] ^ t; + ciphertext[i+1] = mul2(tmp[i+1] ^ tmp[i+2]) ^ tmp[i+1] ^ t; + ciphertext[i+2] = mul2(tmp[i+2] ^ tmp[i+3]) ^ tmp[i+2] ^ t; + ciphertext[i+3] = mul2(tmp[i+3] ^ tmp[i] ) ^ tmp[i+3] ^ t; + } + + // AddRoundKey + for ( i = 0; i < AES_BLOCK_SIZE; ++i ) { + *(ciphertext+i) ^= *roundkeys++; + } + + } + + // last round + for (i = 0; i < AES_BLOCK_SIZE; ++i) { + *(ciphertext+i) = SBOX[*(ciphertext+i)]; + } + shift_rows(ciphertext); + for ( i = 0; i < AES_BLOCK_SIZE; ++i ) { + *(ciphertext+i) ^= *roundkeys++; + } + +} + +void aes_decrypt_128(const uint8_t *roundkeys, const uint8_t *ciphertext, uint8_t *plaintext) { + + uint8_t tmp[16]; + uint8_t t, u, v; + uint8_t i, j; + + roundkeys += 160; + + // first round + for ( i = 0; i < AES_BLOCK_SIZE; ++i ) { + *(plaintext+i) = *(ciphertext+i) ^ *(roundkeys+i); + } + roundkeys -= 16; + inv_shift_rows(plaintext); + for (i = 0; i < AES_BLOCK_SIZE; ++i) { + *(plaintext+i) = INV_SBOX[*(plaintext+i)]; + } + + for (j = 1; j < AES_ROUNDS; ++j) { + + // Inverse AddRoundKey + for ( i = 0; i < AES_BLOCK_SIZE; ++i ) { + *(tmp+i) = *(plaintext+i) ^ *(roundkeys+i); + } + + /* + * Inverse MixColumns + * [0e 0b 0d 09] [s0 s4 s8 s12] + * [09 0e 0b 0d] . [s1 s5 s9 s13] + * [0d 09 0e 0b] [s2 s6 s10 s14] + * [0b 0d 09 0e] [s3 s7 s11 s15] + */ + for (i = 0; i < AES_BLOCK_SIZE; i+=4) { + t = tmp[i] ^ tmp[i+1] ^ tmp[i+2] ^ tmp[i+3]; + plaintext[i] = t ^ tmp[i] ^ mul2(tmp[i] ^ tmp[i+1]); + plaintext[i+1] = t ^ tmp[i+1] ^ mul2(tmp[i+1] ^ tmp[i+2]); + plaintext[i+2] = t ^ tmp[i+2] ^ mul2(tmp[i+2] ^ tmp[i+3]); + plaintext[i+3] = t ^ tmp[i+3] ^ mul2(tmp[i+3] ^ tmp[i]); + u = mul2(mul2(tmp[i] ^ tmp[i+2])); + v = mul2(mul2(tmp[i+1] ^ tmp[i+3])); + t = mul2(u ^ v); + plaintext[i] ^= t ^ u; + plaintext[i+1] ^= t ^ v; + plaintext[i+2] ^= t ^ u; + plaintext[i+3] ^= t ^ v; + } + + // Inverse ShiftRows + inv_shift_rows(plaintext); + + // Inverse SubBytes + for (i = 0; i < AES_BLOCK_SIZE; ++i) { + *(plaintext+i) = INV_SBOX[*(plaintext+i)]; + } + + roundkeys -= 16; + + } + + // last AddRoundKey + for ( i = 0; i < AES_BLOCK_SIZE; ++i ) { + *(plaintext+i) ^= *(roundkeys+i); + } + +} \ No newline at end of file diff --git a/thirdparty/aes_128/aes.h b/thirdparty/aes_128/aes.h new file mode 100644 index 0000000..2dc0cd0 --- /dev/null +++ b/thirdparty/aes_128/aes.h @@ -0,0 +1,48 @@ +/* + * + * Chinese Academy of Sciences + * State Key Laboratory of Information Security + * Institute of Information Engineering + * + * Copyright (C) 2016 Chinese Academy of Sciences + * + * LuoPeng, luopeng@iie.ac.cn + * Updated in May 2016 + * + */ +#ifndef AES_128_H +#define AES_128_H + +#include +#include + +#define AES_BLOCK_SIZE 16 +#define AES_ROUNDS 10 // 12, 14 +#define AES_ROUND_KEY_SIZE 176 // AES-128 has 10 rounds, and there is a AddRoundKey before first round. (10+1)x16=176. + +/** + * @purpose: Key schedule for AES-128 + * @par[in]key: 16 bytes of master keys + * @par[out]roundkeys: 176 bytes of round keys + */ +void aes_key_schedule_128(const uint8_t *key, uint8_t *roundkeys); + +/** + * @purpose: Encryption. The length of plain and cipher should be one block (16 bytes). + * The plaintext and ciphertext may point to the same memory + * @par[in]roundkeys: round keys + * @par[in]plaintext: plain text + * @par[out]ciphertext: cipher text + */ +void aes_encrypt_128(const uint8_t *roundkeys, const uint8_t *plaintext, uint8_t *ciphertext); + +/** + * @purpose: Decryption. The length of plain and cipher should be one block (16 bytes). + * The ciphertext and plaintext may point to the same memory + * @par[in]roundkeys: round keys + * @par[in]ciphertext: cipher text + * @par[out]plaintext: plain text + */ +void aes_decrypt_128(const uint8_t *roundkeys, const uint8_t *ciphertext, uint8_t *plaintext); + +#endif diff --git a/thirdparty/aes_128/lut/aes.c b/thirdparty/aes_128/lut/aes.c new file mode 100644 index 0000000..ec6983a --- /dev/null +++ b/thirdparty/aes_128/lut/aes.c @@ -0,0 +1,852 @@ +/* + * Look up table implementation of AES-128. + * Suppose the mechine is little-endian. + + * LuoPeng (luopengxq@gmail.com) + * 2017.8.5 + * Modified 2017.8.31. Add the decryption LUT implementation. + */ + +#include +#include + +#include "aes.h" + +/* + * Four encryption tables + */ +static const uint32_t T0[256] = { + 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, + 0xdf2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, + 0x50303060, 0x3010102, 0xa96767ce, 0x7d2b2b56, + 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, + 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, + 0x15fafaef, 0xeb5959b2, 0xc947478e, 0xbf0f0fb, + 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, + 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, + 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, + 0x5a36366c, 0x413f3f7e, 0x2f7f7f5, 0x4fcccc83, + 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x8f1f1f9, + 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, + 0xc040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, + 0x28181830, 0xa1969637, 0xf05050a, 0xb59a9a2f, + 0x907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, + 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, + 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, + 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, + 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, + 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, + 0xf55353a6, 0x68d1d1b9, 0x0, 0x2cededc1, + 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, + 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, + 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, + 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, + 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, + 0xcf45458a, 0x10f9f9e9, 0x6020204, 0x817f7ffe, + 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, + 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, + 0xad92923f, 0xbc9d9d21, 0x48383870, 0x4f5f5f1, + 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, + 0x30101020, 0x1affffe5, 0xef3f3fd, 0x6dd2d2bf, + 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, + 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, + 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, + 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, + 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, + 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, + 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, + 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, + 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, + 0xdb494992, 0xa06060c, 0x6c242448, 0xe45c5cb8, + 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, + 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, + 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, + 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, + 0xb46c6cd8, 0xfa5656ac, 0x7f4f4f3, 0x25eaeacf, + 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, + 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, + 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, + 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, + 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, + 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, + 0xd8484890, 0x5030306, 0x1f6f6f7, 0x120e0e1c, + 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, + 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, + 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, + 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, + 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, + 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, + 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, + 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, + 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, + 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c, }; + +static const uint32_t T1[256] = { + 0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, + 0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, + 0x30306050, 0x1010203, 0x6767cea9, 0x2b2b567d, + 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, + 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, + 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, + 0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, + 0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, + 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, + 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, + 0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, + 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, + 0x404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, + 0x18183028, 0x969637a1, 0x5050a0f, 0x9a9a2fb5, + 0x7070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, + 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, + 0x909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, + 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, + 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, + 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, + 0x5353a6f5, 0xd1d1b968, 0x0, 0xededc12c, + 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, + 0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, + 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, + 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, + 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, + 0x45458acf, 0xf9f9e910, 0x2020406, 0x7f7ffe81, + 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, + 0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, + 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, + 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, + 0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, + 0xcdcd814c, 0xc0c1814, 0x13132635, 0xececc32f, + 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, + 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, + 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, + 0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, + 0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83, + 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, + 0xdedea779, 0x5e5ebce2, 0xb0b161d, 0xdbdbad76, + 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0xa0a141e, + 0x494992db, 0x6060c0a, 0x2424486c, 0x5c5cb8e4, + 0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, + 0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, + 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, + 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, + 0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, + 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x8081018, + 0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, + 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, + 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, + 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, + 0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, + 0x484890d8, 0x3030605, 0xf6f6f701, 0xe0e1c12, + 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, + 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, + 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, + 0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, + 0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, + 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, + 0x8c8c038f, 0xa1a159f8, 0x89890980, 0xd0d1a17, + 0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, + 0x414182c3, 0x999929b0, 0x2d2d5a77, 0xf0f1e11, + 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a, }; + +static const uint32_t T2[256] = { + 0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, + 0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, + 0x30605030, 0x1020301, 0x67cea967, 0x2b567d2b, + 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, + 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, + 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, + 0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, + 0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, + 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, + 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, + 0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, + 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, + 0x4080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, + 0x18302818, 0x9637a196, 0x50a0f05, 0x9a2fb59a, + 0x70e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, + 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, + 0x9121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, + 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, + 0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, + 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, + 0x53a6f553, 0xd1b968d1, 0x0, 0xedc12ced, + 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, + 0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, + 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, + 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, + 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, + 0x458acf45, 0xf9e910f9, 0x2040602, 0x7ffe817f, + 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, + 0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, + 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, + 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, + 0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, + 0xcd814ccd, 0xc18140c, 0x13263513, 0xecc32fec, + 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, + 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, + 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, + 0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, + 0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388, + 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, + 0xdea779de, 0x5ebce25e, 0xb161d0b, 0xdbad76db, + 0xe0db3be0, 0x32645632, 0x3a744e3a, 0xa141e0a, + 0x4992db49, 0x60c0a06, 0x24486c24, 0x5cb8e45c, + 0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, + 0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, + 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, + 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, + 0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, + 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x8101808, + 0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, + 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, + 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, + 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, + 0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, + 0x4890d848, 0x3060503, 0xf6f701f6, 0xe1c120e, + 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, + 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, + 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, + 0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, + 0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, + 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, + 0x8c038f8c, 0xa159f8a1, 0x89098089, 0xd1a170d, + 0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, + 0x4182c341, 0x9929b099, 0x2d5a772d, 0xf1e110f, + 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16, }; + +static const uint32_t T3[256] = { + 0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, + 0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, + 0x60503030, 0x2030101, 0xcea96767, 0x567d2b2b, + 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, + 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, + 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, + 0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, + 0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, + 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, + 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, + 0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, + 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, + 0x80c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, + 0x30281818, 0x37a19696, 0xa0f0505, 0x2fb59a9a, + 0xe090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, + 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, + 0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, + 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, + 0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, + 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, + 0xa6f55353, 0xb968d1d1, 0x0, 0xc12ceded, + 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, + 0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, + 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, + 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, + 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, + 0x8acf4545, 0xe910f9f9, 0x4060202, 0xfe817f7f, + 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, + 0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x58a8f8f, + 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, + 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, + 0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, + 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, + 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, + 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, + 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, + 0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, + 0x44662222, 0x547e2a2a, 0x3bab9090, 0xb838888, + 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, + 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, + 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, + 0x92db4949, 0xc0a0606, 0x486c2424, 0xb8e45c5c, + 0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, + 0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, + 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, + 0x18c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, + 0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, + 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, + 0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, + 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, + 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, + 0x96dd4b4b, 0x61dcbdbd, 0xd868b8b, 0xf858a8a, + 0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, + 0x90d84848, 0x6050303, 0xf701f6f6, 0x1c120e0e, + 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, + 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, + 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, + 0xd2bb6969, 0xa970d9d9, 0x7898e8e, 0x33a79494, + 0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, + 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, + 0x38f8c8c, 0x59f8a1a1, 0x9808989, 0x1a170d0d, + 0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, + 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, + 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616, }; + +/* + * Sbox + */ +static uint8_t SBOX[256] = { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; + +/* + * Decryption tables + */ +static const uint32_t D0[256] = { + 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, + 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b, + 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, + 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, + 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, + 0x2752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, + 0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, + 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e, + 0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, + 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, + 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, + 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, + 0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, + 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566, + 0x728ebb2, 0x3c2b52f, 0x9a7bc586, 0xa50837d3, + 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, + 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, + 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4, + 0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, + 0x39ec830b, 0xaaef6040, 0x69f715e, 0x51106ebd, + 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, + 0xb58d5491, 0x55dc471, 0x6fd40604, 0xff155060, + 0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, + 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879, + 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x0, + 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, + 0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, + 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624, + 0xb1670a0c, 0xfe75793, 0xd296eeb4, 0x9e919b1b, + 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, + 0xaba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, + 0xb0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, + 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, + 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, + 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, + 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, + 0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, + 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177, + 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, + 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, + 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, + 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, + 0xe49d3a2c, 0xd927850, 0x9bcc5f6a, 0x62467e54, + 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382, + 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, + 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, + 0x97826cd, 0xf418596e, 0x1b79aec, 0xa89a4f83, + 0x656e95e6, 0x7ee6ffaa, 0x8cfbc21, 0xe6e815ef, + 0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, + 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, + 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, + 0x4a9804f1, 0xf7daec41, 0xe50cd7f, 0x2ff69117, + 0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, + 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546, + 0x4ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, + 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, + 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, + 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a, + 0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, + 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, + 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, + 0x72c31d16, 0xc25e2bc, 0x8b493c28, 0x41950dff, + 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, + 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0, }; + +static const uint32_t D1[256] = { + 0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96, + 0x6bab3bcb, 0x459d1ff1, 0x58faacab, 0x3e34b93, + 0xfa302055, 0x6d76adf6, 0x76cc8891, 0x4c02f525, + 0xd7e54ffc, 0xcb2ac5d7, 0x44352680, 0xa362b58f, + 0x5ab1de49, 0x1bba2567, 0xeea4598, 0xc0fe5de1, + 0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6, + 0x5f8f03e7, 0x9c921595, 0x7a6dbfeb, 0x595295da, + 0x83bed42d, 0x217458d3, 0x69e04929, 0xc8c98e44, + 0x89c2756a, 0x798ef478, 0x3e58996b, 0x71b927dd, + 0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4, + 0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245, + 0x7764b1e0, 0xae6bbb84, 0xa081fe1c, 0x2b08f994, + 0x68487058, 0xfd458f19, 0x6cde9487, 0xf87b52b7, + 0xd373ab23, 0x24b72e2, 0x8f1fe357, 0xab55662a, + 0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x837d3a5, + 0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c, + 0x1ccf8a2b, 0xb479a792, 0xf207f3f0, 0xe2694ea1, + 0xf4da65cd, 0xbe0506d5, 0x6234d11f, 0xfea6c48a, + 0x532e349d, 0x55f3a2a0, 0xe18a0532, 0xebf6a475, + 0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51, + 0x8a213ef9, 0x6dd963d, 0x53eddae, 0xbde64d46, + 0x8d5491b5, 0x5dc47105, 0xd406046f, 0x155060ff, + 0xfb981924, 0xe9bdd697, 0x434089cc, 0x9ed96777, + 0x42e8b0bd, 0x8b890788, 0x5b19e738, 0xeec879db, + 0xa7ca147, 0xf427ce9, 0x1e84f8c9, 0x0, + 0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e, + 0xff0efdfb, 0x38850f56, 0xd5ae3d1e, 0x392d3627, + 0xd90f0a64, 0xa65c6821, 0x545b9bd1, 0x2e36243a, + 0x670a0cb1, 0xe757930f, 0x96eeb4d2, 0x919b1b9e, + 0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16, + 0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d, + 0xd090e0b, 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8, + 0x19f15785, 0x775af4c, 0xdd99eebb, 0x607fa3fd, + 0x2601f79f, 0xf5725cbc, 0x3b6644c5, 0x7efb5b34, + 0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863, + 0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420, + 0x244a857d, 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d, + 0x2f9e1d4b, 0x30b2dcf3, 0x52860dec, 0xe3c177d0, + 0x16b32b6c, 0xb970a999, 0x489411fa, 0x64e94722, + 0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef, + 0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0xbd49836, + 0x81f5a6cf, 0xde7aa528, 0x8eb7da26, 0xbfad3fa4, + 0x9d3a2ce4, 0x9278500d, 0xcc5f6a9b, 0x467e5462, + 0x138df6c2, 0xb8d890e8, 0xf7392e5e, 0xafc382f5, + 0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3, + 0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b, + 0x7826cd09, 0x18596ef4, 0xb79aec01, 0x9a4f83a8, + 0x6e95e665, 0xe6ffaa7e, 0xcfbc2108, 0xe815efe6, + 0x9be7bad9, 0x366f4ace, 0x99fead4, 0x7cb029d6, + 0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0, + 0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315, + 0x9804f14a, 0xdaec41f7, 0x50cd7f0e, 0xf691172f, + 0xd64d768d, 0xb0ef434d, 0x4daacc54, 0x496e4df, + 0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, 0x5165467f, + 0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e, + 0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13, + 0x61d79a8c, 0xca1377a, 0x14f8598e, 0x3c13eb89, + 0x27a9ceee, 0xc961b735, 0xe51ce1ed, 0xb1477a3c, + 0xdfd29c59, 0x73f2553f, 0xce141879, 0x37c773bf, + 0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886, + 0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f, + 0xc31d1672, 0x25e2bc0c, 0x493c288b, 0x950dff41, + 0x1a83971, 0xb30c08de, 0xe4b4d89c, 0xc1566490, + 0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042, }; + +static const uint32_t D2[256] = { + 0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e, + 0xab3bcb6b, 0x9d1ff145, 0xfaacab58, 0xe34b9303, + 0x302055fa, 0x76adf66d, 0xcc889176, 0x2f5254c, + 0xe54ffcd7, 0x2ac5d7cb, 0x35268044, 0x62b58fa3, + 0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0, + 0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9, + 0x8f03e75f, 0x9215959c, 0x6dbfeb7a, 0x5295da59, + 0xbed42d83, 0x7458d321, 0xe0492969, 0xc98e44c8, + 0xc2756a89, 0x8ef47879, 0x58996b3e, 0xb927dd71, + 0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a, + 0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f, + 0x64b1e077, 0x6bbb84ae, 0x81fe1ca0, 0x8f9942b, + 0x48705868, 0x458f19fd, 0xde94876c, 0x7b52b7f8, + 0x73ab23d3, 0x4b72e202, 0x1fe3578f, 0x55662aab, + 0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508, + 0x2830f287, 0xbf23b2a5, 0x302ba6a, 0x16ed5c82, + 0xcf8a2b1c, 0x79a792b4, 0x7f3f0f2, 0x694ea1e2, + 0xda65cdf4, 0x506d5be, 0x34d11f62, 0xa6c48afe, + 0x2e349d53, 0xf3a2a055, 0x8a0532e1, 0xf6a475eb, + 0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110, + 0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd, + 0x5491b58d, 0xc471055d, 0x6046fd4, 0x5060ff15, + 0x981924fb, 0xbdd697e9, 0x4089cc43, 0xd967779e, + 0xe8b0bd42, 0x8907888b, 0x19e7385b, 0xc879dbee, + 0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x0, + 0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72, + 0xefdfbff, 0x850f5638, 0xae3d1ed5, 0x2d362739, + 0xf0a64d9, 0x5c6821a6, 0x5b9bd154, 0x36243a2e, + 0xa0cb167, 0x57930fe7, 0xeeb4d296, 0x9b1b9e91, + 0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a, + 0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17, + 0x90e0b0d, 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9, + 0xf1578519, 0x75af4c07, 0x99eebbdd, 0x7fa3fd60, + 0x1f79f26, 0x725cbcf5, 0x6644c53b, 0xfb5b347e, + 0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1, + 0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011, + 0x4a857d24, 0xbbd2f83d, 0xf9ae1132, 0x29c76da1, + 0x9e1d4b2f, 0xb2dcf330, 0x860dec52, 0xc177d0e3, + 0xb32b6c16, 0x70a999b9, 0x9411fa48, 0xe9472264, + 0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90, + 0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b, + 0xf5a6cf81, 0x7aa528de, 0xb7da268e, 0xad3fa4bf, + 0x3a2ce49d, 0x78500d92, 0x5f6a9bcc, 0x7e546246, + 0x8df6c213, 0xd890e8b8, 0x392e5ef7, 0xc382f5af, + 0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312, + 0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb, + 0x26cd0978, 0x596ef418, 0x9aec01b7, 0x4f83a89a, + 0x95e6656e, 0xffaa7ee6, 0xbc2108cf, 0x15efe6e8, + 0xe7bad99b, 0x6f4ace36, 0x9fead409, 0xb029d67c, + 0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066, + 0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8, + 0x4f14a98, 0xec41f7da, 0xcd7f0e50, 0x91172ff6, + 0x4d768dd6, 0xef434db0, 0xaacc544d, 0x96e4df04, + 0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, 0x65467f51, + 0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0xbfb2e41, + 0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347, + 0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c, + 0xa9ceee27, 0x61b735c9, 0x1ce1ede5, 0x477a3cb1, + 0xd29c59df, 0xf2553f73, 0x141879ce, 0xc773bf37, + 0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db, + 0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40, + 0x1d1672c3, 0xe2bc0c25, 0x3c288b49, 0xdff4195, + 0xa8397101, 0xc08deb3, 0xb4d89ce4, 0x566490c1, + 0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257, }; + +static const uint32_t D3[256] = { + 0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, + 0x3bcb6bab, 0x1ff1459d, 0xacab58fa, 0x4b9303e3, + 0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02, + 0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362, + 0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe, + 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3, + 0x3e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952, + 0xd42d83be, 0x58d32174, 0x492969e0, 0x8e44c8c9, + 0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9, + 0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace, + 0x63184adf, 0xe582311a, 0x97603351, 0x62457f53, + 0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08, + 0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b, + 0xab23d373, 0x72e2024b, 0xe3578f1f, 0x662aab55, + 0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837, + 0x30f28728, 0x23b2a5bf, 0x2ba6a03, 0xed5c8216, + 0x8a2b1ccf, 0xa792b479, 0xf3f0f207, 0x4ea1e269, + 0x65cdf4da, 0x6d5be05, 0xd11f6234, 0xc48afea6, + 0x349d532e, 0xa2a055f3, 0x532e18a, 0xa475ebf6, + 0xb39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e, + 0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6, + 0x91b58d54, 0x71055dc4, 0x46fd406, 0x60ff1550, + 0x1924fb98, 0xd697e9bd, 0x89cc4340, 0x67779ed9, + 0xb0bd42e8, 0x7888b89, 0xe7385b19, 0x79dbeec8, + 0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x0, + 0x9838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a, + 0xfdfbff0e, 0xf563885, 0x3d1ed5ae, 0x3627392d, + 0xa64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36, + 0xcb1670a, 0x930fe757, 0xb4d296ee, 0x1b9e919b, + 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12, + 0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, + 0xe0b0d09, 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e, + 0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f, + 0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb, + 0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4, + 0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6, + 0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129, + 0x1d4b2f9e, 0xdcf330b2, 0xdec5286, 0x77d0e3c1, + 0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9, + 0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033, + 0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4, + 0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad, + 0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e, + 0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, 0x82f5afc3, + 0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225, + 0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, + 0xcd097826, 0x6ef41859, 0xec01b79a, 0x83a89a4f, + 0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815, + 0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0, + 0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2, + 0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7, + 0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691, + 0x768dd64d, 0x434db0ef, 0xcc544daa, 0xe4df0496, + 0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165, + 0x9d04ea5e, 0x15d358c, 0xfa737487, 0xfb2e410b, + 0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6, + 0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13, + 0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147, + 0x9c59dfd2, 0x553f73f2, 0x1879ce14, 0x73bf37c7, + 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44, + 0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, + 0x1672c31d, 0xbc0c25e2, 0x288b493c, 0xff41950d, + 0x397101a8, 0x8deb30c, 0xd89ce4b4, 0x6490c156, + 0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8, }; + +/* + * This is for the Inverse MixColumns of round keys. + * + * The values is [0x0b, 0x0d, 0x09, 0x0e].x + * where x belongs to [0, 255] + */ +static const uint32_t IK0[256] = { + 0x0, 0xb0d090e, 0x161a121c, 0x1d171b12, + 0x2c342438, 0x27392d36, 0x3a2e3624, 0x31233f2a, + 0x58684870, 0x5365417e, 0x4e725a6c, 0x457f5362, + 0x745c6c48, 0x7f516546, 0x62467e54, 0x694b775a, + 0xb0d090e0, 0xbbdd99ee, 0xa6ca82fc, 0xadc78bf2, + 0x9ce4b4d8, 0x97e9bdd6, 0x8afea6c4, 0x81f3afca, + 0xe8b8d890, 0xe3b5d19e, 0xfea2ca8c, 0xf5afc382, + 0xc48cfca8, 0xcf81f5a6, 0xd296eeb4, 0xd99be7ba, + 0x7bbb3bdb, 0x70b632d5, 0x6da129c7, 0x66ac20c9, + 0x578f1fe3, 0x5c8216ed, 0x41950dff, 0x4a9804f1, + 0x23d373ab, 0x28de7aa5, 0x35c961b7, 0x3ec468b9, + 0xfe75793, 0x4ea5e9d, 0x19fd458f, 0x12f04c81, + 0xcb6bab3b, 0xc066a235, 0xdd71b927, 0xd67cb029, + 0xe75f8f03, 0xec52860d, 0xf1459d1f, 0xfa489411, + 0x9303e34b, 0x980eea45, 0x8519f157, 0x8e14f859, + 0xbf37c773, 0xb43ace7d, 0xa92dd56f, 0xa220dc61, + 0xf66d76ad, 0xfd607fa3, 0xe07764b1, 0xeb7a6dbf, + 0xda595295, 0xd1545b9b, 0xcc434089, 0xc74e4987, + 0xae053edd, 0xa50837d3, 0xb81f2cc1, 0xb31225cf, + 0x82311ae5, 0x893c13eb, 0x942b08f9, 0x9f2601f7, + 0x46bde64d, 0x4db0ef43, 0x50a7f451, 0x5baafd5f, + 0x6a89c275, 0x6184cb7b, 0x7c93d069, 0x779ed967, + 0x1ed5ae3d, 0x15d8a733, 0x8cfbc21, 0x3c2b52f, + 0x32e18a05, 0x39ec830b, 0x24fb9819, 0x2ff69117, + 0x8dd64d76, 0x86db4478, 0x9bcc5f6a, 0x90c15664, + 0xa1e2694e, 0xaaef6040, 0xb7f87b52, 0xbcf5725c, + 0xd5be0506, 0xdeb30c08, 0xc3a4171a, 0xc8a91e14, + 0xf98a213e, 0xf2872830, 0xef903322, 0xe49d3a2c, + 0x3d06dd96, 0x360bd498, 0x2b1ccf8a, 0x2011c684, + 0x1132f9ae, 0x1a3ff0a0, 0x728ebb2, 0xc25e2bc, + 0x656e95e6, 0x6e639ce8, 0x737487fa, 0x78798ef4, + 0x495ab1de, 0x4257b8d0, 0x5f40a3c2, 0x544daacc, + 0xf7daec41, 0xfcd7e54f, 0xe1c0fe5d, 0xeacdf753, + 0xdbeec879, 0xd0e3c177, 0xcdf4da65, 0xc6f9d36b, + 0xafb2a431, 0xa4bfad3f, 0xb9a8b62d, 0xb2a5bf23, + 0x83868009, 0x888b8907, 0x959c9215, 0x9e919b1b, + 0x470a7ca1, 0x4c0775af, 0x51106ebd, 0x5a1d67b3, + 0x6b3e5899, 0x60335197, 0x7d244a85, 0x7629438b, + 0x1f6234d1, 0x146f3ddf, 0x97826cd, 0x2752fc3, + 0x335610e9, 0x385b19e7, 0x254c02f5, 0x2e410bfb, + 0x8c61d79a, 0x876cde94, 0x9a7bc586, 0x9176cc88, + 0xa055f3a2, 0xab58faac, 0xb64fe1be, 0xbd42e8b0, + 0xd4099fea, 0xdf0496e4, 0xc2138df6, 0xc91e84f8, + 0xf83dbbd2, 0xf330b2dc, 0xee27a9ce, 0xe52aa0c0, + 0x3cb1477a, 0x37bc4e74, 0x2aab5566, 0x21a65c68, + 0x10856342, 0x1b886a4c, 0x69f715e, 0xd927850, + 0x64d90f0a, 0x6fd40604, 0x72c31d16, 0x79ce1418, + 0x48ed2b32, 0x43e0223c, 0x5ef7392e, 0x55fa3020, + 0x1b79aec, 0xaba93e2, 0x17ad88f0, 0x1ca081fe, + 0x2d83bed4, 0x268eb7da, 0x3b99acc8, 0x3094a5c6, + 0x59dfd29c, 0x52d2db92, 0x4fc5c080, 0x44c8c98e, + 0x75ebf6a4, 0x7ee6ffaa, 0x63f1e4b8, 0x68fcedb6, + 0xb1670a0c, 0xba6a0302, 0xa77d1810, 0xac70111e, + 0x9d532e34, 0x965e273a, 0x8b493c28, 0x80443526, + 0xe90f427c, 0xe2024b72, 0xff155060, 0xf418596e, + 0xc53b6644, 0xce366f4a, 0xd3217458, 0xd82c7d56, + 0x7a0ca137, 0x7101a839, 0x6c16b32b, 0x671bba25, + 0x5638850f, 0x5d358c01, 0x40229713, 0x4b2f9e1d, + 0x2264e947, 0x2969e049, 0x347efb5b, 0x3f73f255, + 0xe50cd7f, 0x55dc471, 0x184adf63, 0x1347d66d, + 0xcadc31d7, 0xc1d138d9, 0xdcc623cb, 0xd7cb2ac5, + 0xe6e815ef, 0xede51ce1, 0xf0f207f3, 0xfbff0efd, + 0x92b479a7, 0x99b970a9, 0x84ae6bbb, 0x8fa362b5, + 0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d, +}; + +/* + * Inverse Sboxs + */ +static uint8_t INV_SBOX[256] = { + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d}; + +/* + * Round constants + */ +static uint8_t RC[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; + +void aes_key_schedule_128(const uint8_t *key, uint8_t *roundkeys) { + + uint8_t temp[4]; + uint8_t *last4bytes; // point to the last 4 bytes of one round + uint8_t *lastround; + uint8_t i; + + for (i = 0; i < 16; ++i) { + *roundkeys++ = *key++; + } + + last4bytes = roundkeys-4; + for (i = 0; i < AES_ROUNDS; ++i) { + // k0-k3 for next round + temp[3] = SBOX[*last4bytes++]; + temp[0] = SBOX[*last4bytes++]; + temp[1] = SBOX[*last4bytes++]; + temp[2] = SBOX[*last4bytes++]; + temp[0] ^= RC[i]; + lastround = roundkeys-16; + *roundkeys++ = temp[0] ^ *lastround++; + *roundkeys++ = temp[1] ^ *lastround++; + *roundkeys++ = temp[2] ^ *lastround++; + *roundkeys++ = temp[3] ^ *lastround++; + // k4-k7 for next round + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + // k8-k11 for next round + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + // k12-k15 for next round + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + } +} + +void aes_encrypt_128(const uint8_t *roundkeys, const uint8_t *plaintext, uint8_t *ciphertext) { + + int i; + + const uint32_t * rks = (uint32_t*)roundkeys; + const uint32_t * pt = (uint32_t*)plaintext; + uint32_t t0, t1, t2, t3, u0, u1, u2, u3; + + t0 = pt[0] ^ *rks++; + t1 = pt[1] ^ *rks++; + t2 = pt[2] ^ *rks++; + t3 = pt[3] ^ *rks++; + + // 9 rounds + for (i = 1; i < AES_ROUNDS; ++i) { + u0 = T0[(uint8_t)t0] ^ T1[(uint8_t)(t1>>8)] ^ T2[(uint8_t)(t2>>16)] ^ T3[t3>>24]; + u1 = T0[(uint8_t)t1] ^ T1[(uint8_t)(t2>>8)] ^ T2[(uint8_t)(t3>>16)] ^ T3[t0>>24]; + u2 = T0[(uint8_t)t2] ^ T1[(uint8_t)(t3>>8)] ^ T2[(uint8_t)(t0>>16)] ^ T3[t1>>24]; + u3 = T0[(uint8_t)t3] ^ T1[(uint8_t)(t0>>8)] ^ T2[(uint8_t)(t1>>16)] ^ T3[t2>>24]; + + t0 = u0 ^ *rks++; + t1 = u1 ^ *rks++; + t2 = u2 ^ *rks++; + t3 = u3 ^ *rks++; + } + + roundkeys += 160; + ciphertext[0] = SBOX[(uint8_t)t0] ^ *roundkeys++; + ciphertext[1] = SBOX[(uint8_t)(t1>>8)] ^ *roundkeys++; + ciphertext[2] = SBOX[(uint8_t)(t2>>16)] ^ *roundkeys++; + ciphertext[3] = SBOX[t3>>24] ^ *roundkeys++; + ciphertext[4] = SBOX[(uint8_t)t1] ^ *roundkeys++; + ciphertext[5] = SBOX[(uint8_t)(t2>>8)] ^ *roundkeys++; + ciphertext[6] = SBOX[(uint8_t)(t3>>16)] ^ *roundkeys++; + ciphertext[7] = SBOX[t0>>24] ^ *roundkeys++; + ciphertext[8] = SBOX[(uint8_t)t2] ^ *roundkeys++; + ciphertext[9] = SBOX[(uint8_t)(t3>>8)] ^ *roundkeys++; + ciphertext[10] = SBOX[(uint8_t)(t0>>16)] ^ *roundkeys++; + ciphertext[11] = SBOX[t1>>24] ^ *roundkeys++; + ciphertext[12] = SBOX[(uint8_t)t3] ^ *roundkeys++; + ciphertext[13] = SBOX[(uint8_t)(t0>>8)] ^ *roundkeys++; + ciphertext[14] = SBOX[(uint8_t)(t1>>16)] ^ *roundkeys++; + ciphertext[15] = SBOX[t2>>24] ^ *roundkeys++; + +} + + +/* + * Decryption steps + * + * Suppose: + * IAdd -- Inverse AddRoundKey + * IShf -- Inverse ShiftRows + * ISub -- Inverse SubBytes + * IMix -- Inverse MixColumns + * + * ----------------------------------------------------- + * + * IAdd IAdd IAdd IAdd + * IShf -------- -------- -------- + * ISub | IShf | | ISub | | ISub | + * -------- | ISub | | IShf | | IShf | + * | IAdd | | IAdd | | IAdd | | IAdd | + * | IMix | 1 | IMix | 2 | IMix | 3 | IMix | + * | IShf | ----> -------- ----> -------- ----> -------- + * | ISub | IShf IShf IShf + * -------- ISub ISub ISub + * IAdd IAdd IAdd IAdd + * + * Step 2 change the order of IShf and ISub. This can be done directly. + * Step 3 change the order of IAdd and IMix. Therefore, we add the table + * TK0 for the round keys to do IMix. You can also use 4 tables + * (util/dec_key_table.c can get the tables). + * ----------------------------------------------------- + * + */ + +void aes_decrypt_128(const uint8_t *roundkeys, const uint8_t *ciphertext, uint8_t *plaintext) { + + int i; + + const uint32_t * ct = (uint32_t*)ciphertext; + uint32_t t0, t1, t2, t3, u0, u1, u2, u3; + + // first Inverse AddRoundKey + + t0 = ct[0] ^ *( ((uint32_t*)roundkeys) + 40); + t1 = ct[1] ^ *( ((uint32_t*)roundkeys) + 41); + t2 = ct[2] ^ *( ((uint32_t*)roundkeys) + 42); + t3 = ct[3] ^ *( ((uint32_t*)roundkeys) + 43); + + /* + * 9 rounds of decryction + */ + roundkeys += 144; + for (i = 1; i < AES_ROUNDS; ++i) { + u0 = D0[(uint8_t)t0] ^ D1[(uint8_t)(t3>>8)] ^ D2[(uint8_t)(t2>>16)] ^ D3[t1>>24] + ^ IK0[roundkeys[0]] + ^ ((IK0[roundkeys[1]]<<8) ^ (IK0[roundkeys[1]]>>24)) + ^ ((IK0[roundkeys[2]]<<16) ^ (IK0[roundkeys[2]]>>16)) + ^ ((IK0[roundkeys[3]]<<24) ^ (IK0[roundkeys[3]]>>8)); + u1 = D0[(uint8_t)t1] ^ D1[(uint8_t)(t0>>8)] ^ D2[(uint8_t)(t3>>16)] ^ D3[t2>>24] + ^ IK0[roundkeys[4]] + ^ ((IK0[roundkeys[5]]<<8) ^ (IK0[roundkeys[5]]>>24)) + ^ ((IK0[roundkeys[6]]<<16) ^ (IK0[roundkeys[6]]>>16)) + ^ ((IK0[roundkeys[7]]<<24) ^ (IK0[roundkeys[7]]>>8)); + u2 = D0[(uint8_t)t2] ^ D1[(uint8_t)(t1>>8)] ^ D2[(uint8_t)(t0>>16)] ^ D3[t3>>24] + ^ IK0[roundkeys[8]] + ^ ((IK0[roundkeys[9]]<<8) ^ (IK0[roundkeys[9]]>>24)) + ^ ((IK0[roundkeys[10]]<<16) ^ (IK0[roundkeys[10]]>>16)) + ^ ((IK0[roundkeys[11]]<<24) ^ (IK0[roundkeys[11]]>>8)); + u3 = D0[(uint8_t)t3] ^ D1[(uint8_t)(t2>>8)] ^ D2[(uint8_t)(t1>>16)] ^ D3[t0>>24] + ^ IK0[roundkeys[12]] + ^ ((IK0[roundkeys[13]]<<8) ^ (IK0[roundkeys[13]]>>24)) + ^ ((IK0[roundkeys[14]]<<16) ^ (IK0[roundkeys[14]]>>16)) + ^ ((IK0[roundkeys[15]]<<24) ^ (IK0[roundkeys[15]]>>8)); + t0 = u0; + t1 = u1; + t2 = u2; + t3 = u3; + roundkeys -= 16; + } + + // last round: Inverse ShiftRows, Inverse SubBytes and Inverse AddRoundKey + plaintext[0] = INV_SBOX[(uint8_t)t0] ^ *roundkeys++; + plaintext[1] = INV_SBOX[(uint8_t)(t3>>8)] ^ *roundkeys++; + plaintext[2] = INV_SBOX[(uint8_t)(t2>>16)] ^ *roundkeys++; + plaintext[3] = INV_SBOX[t1>>24] ^ *roundkeys++; + plaintext[4] = INV_SBOX[(uint8_t)t1] ^ *roundkeys++; + plaintext[5] = INV_SBOX[(uint8_t)(t0>>8)] ^ *roundkeys++; + plaintext[6] = INV_SBOX[(uint8_t)(t3>>16)] ^ *roundkeys++; + plaintext[7] = INV_SBOX[t2>>24] ^ *roundkeys++; + plaintext[8] = INV_SBOX[(uint8_t)t2] ^ *roundkeys++; + plaintext[9] = INV_SBOX[(uint8_t)(t1>>8)] ^ *roundkeys++; + plaintext[10] = INV_SBOX[(uint8_t)(t0>>16)] ^ *roundkeys++; + plaintext[11] = INV_SBOX[t3>>24] ^ *roundkeys++; + plaintext[12] = INV_SBOX[(uint8_t)t3] ^ *roundkeys++; + plaintext[13] = INV_SBOX[(uint8_t)(t2>>8)] ^ *roundkeys++; + plaintext[14] = INV_SBOX[(uint8_t)(t1>>16)] ^ *roundkeys++; + plaintext[15] = INV_SBOX[t0>>24] ^ *roundkeys++; + +} diff --git a/thirdparty/aes_128/lut/gen_dec_key_table.c b/thirdparty/aes_128/lut/gen_dec_key_table.c new file mode 100644 index 0000000..3a71b00 --- /dev/null +++ b/thirdparty/aes_128/lut/gen_dec_key_table.c @@ -0,0 +1,102 @@ + +#include +#include + +static uint8_t Ie[256]; +static uint8_t I9[256]; +static uint8_t Ib[256]; +static uint8_t Id[256]; + +static const uint8_t CONX = 0X1B; + +// tables + +static uint32_t IK0[256]; +static uint32_t IK1[256]; +static uint32_t IK2[256]; +static uint32_t IK3[256]; + +void generate_mix(); +void generate_tables(); +void print_tables(); + +int main () { + + generate_mix(); + generate_tables(); + print_tables(); + + return 0; +} + + +void generate_mix() { + int i; + uint8_t base, base2, base4, base8; + for ( i = 0, base = 0; i < 256; ++i, ++base) { + base2 = (base&0x80) ? ((base<<1)^CONX) : (base<<1); + base4 = (base2&0x80) ? ((base2<<1)^CONX) : (base2<<1); + base8 = (base4&0x80) ? ((base4<<1)^CONX) : (base4<<1); + + I9[i] = base8 ^ base; + Ib[i] = I9[i] ^ base2; + Id[i] = I9[i] ^ base4; + Ie[i] = Id[i] ^ base2 ^ base; + } +} + +void print_tables() { + + int i; + printf("IK0:\n"); + for ( i = 0; i < 256; ++i ) { + printf("0x%8x, ", IK0[i]); + if ( i % 4 == 3 ) { + printf("\n"); + } + } + printf("\n\n"); + + printf("IK1:\n"); + for ( i = 0; i < 256; ++i ) { + printf("0x%8x, ", IK1[i]); + if ( i % 4 == 3 ) { + printf("\n"); + } + } + printf("\n\n"); + + printf("IK2:\n"); + for ( i = 0; i < 256; ++i) { + printf("0x%8x, ", IK2[i]); + if ( i % 4 == 3 ) { + printf("\n"); + } + } + printf("\n\n"); + + printf("IK3:\n"); + for ( i = 0; i < 256; ++i ) { + printf("0x%8x, ", IK3[i]); + if ( i % 4 == 3 ) { + printf("\n"); + } + } + +} + +void generate_tables() { + + int i; + for (i = 0; i < 256; ++i ) { + IK0[i] = ((uint32_t)Ib[i]<<24) ^ ((uint32_t)Id[i]<<16) + ^ ((uint32_t)I9[i]<<8) ^ ((uint32_t)Ie[i]); + IK1[i] = ((uint32_t)Id[i]<<24) ^ ((uint32_t)I9[i]<<16) + ^ ((uint32_t)Ie[i]<<8)^ ((uint32_t)Ib[i]); + IK2[i] = ((uint32_t)I9[i]<<24) ^ ((uint32_t)Ie[i]<<16) + ^ ((uint32_t)Ib[i]<<8)^ ((uint32_t)Id[i]); + IK3[i] = ((uint32_t)Ie[i]<<24) ^ ((uint32_t)Ib[i]<<16) + ^ ((uint32_t)Id[i]<<8) ^ ((uint32_t)I9[i]); + } + +} diff --git a/thirdparty/aes_128/lut/gen_dec_table.c b/thirdparty/aes_128/lut/gen_dec_table.c new file mode 100644 index 0000000..9870961 --- /dev/null +++ b/thirdparty/aes_128/lut/gen_dec_table.c @@ -0,0 +1,123 @@ + +#include +#include + +/* + * Inverse Sboxs + */ +static uint8_t INV_SBOX[256] = { + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d}; + +static uint8_t Ie[256]; +static uint8_t I9[256]; +static uint8_t Ib[256]; +static uint8_t Id[256]; + +static const uint8_t CONX = 0X1B; + +// tables + +static uint32_t D0[256]; +static uint32_t D1[256]; +static uint32_t D2[256]; +static uint32_t D3[256]; + +void generate_mix(); +void generate_tables(); +void print_tables(); + +int main () { + + generate_mix(); + generate_tables(); + print_tables(); + + return 0; +} + + +void generate_mix() { + int i; + uint8_t base2, base4, base8; + for ( i = 0; i < 256; ++i) { + base2 = (INV_SBOX[i]&0x80) ? ((INV_SBOX[i]<<1)^CONX) : (INV_SBOX[i]<<1); + base4 = (base2&0x80) ? ((base2<<1)^CONX) : (base2<<1); + base8 = (base4&0x80) ? ((base4<<1)^CONX) : (base4<<1); + + I9[i] = base8 ^ INV_SBOX[i]; + Ib[i] = I9[i] ^ base2; + Id[i] = I9[i] ^ base4; + Ie[i] = Id[i] ^ base2 ^ INV_SBOX[i]; + } +} + +void print_tables() { + + int i; + printf("D0:\n"); + for ( i = 0; i < 256; ++i ) { + printf("0x%8x, ", D0[i]); + if ( i % 4 == 3 ) { + printf("\n"); + } + } + printf("\n\n"); + + printf("D1:\n"); + for ( i = 0; i < 256; ++i ) { + printf("0x%8x, ", D1[i]); + if ( i % 4 == 3 ) { + printf("\n"); + } + } + printf("\n\n"); + + printf("D2:\n"); + for ( i = 0; i < 256; ++i) { + printf("0x%8x, ", D2[i]); + if ( i % 4 == 3 ) { + printf("\n"); + } + } + printf("\n\n"); + + printf("D3:\n"); + for ( i = 0; i < 256; ++i ) { + printf("0x%8x, ", D3[i]); + if ( i % 4 == 3 ) { + printf("\n"); + } + } + +} + +void generate_tables() { + + int i; + for (i = 0; i < 256; ++i ) { + D0[i] = ((uint32_t)Ib[i]<<24) ^ ((uint32_t)Id[i]<<16) + ^ ((uint32_t)I9[i]<<8) ^ ((uint32_t)Ie[i]); + D1[i] = ((uint32_t)Id[i]<<24) ^ ((uint32_t)I9[i]<<16) + ^ ((uint32_t)Ie[i]<<8)^ ((uint32_t)Ib[i]); + D2[i] = ((uint32_t)I9[i]<<24) ^ ((uint32_t)Ie[i]<<16) + ^ ((uint32_t)Ib[i]<<8)^ ((uint32_t)Id[i]); + D3[i] = ((uint32_t)Ie[i]<<24) ^ ((uint32_t)Ib[i]<<16) + ^ ((uint32_t)Id[i]<<8) ^ ((uint32_t)I9[i]); + } + +} diff --git a/thirdparty/aes_128/lut/gen_enc_table.c b/thirdparty/aes_128/lut/gen_enc_table.c new file mode 100644 index 0000000..49d1b55 --- /dev/null +++ b/thirdparty/aes_128/lut/gen_enc_table.c @@ -0,0 +1,116 @@ + +#include +#include + +/* + * Sbox + */ +static uint8_t SBOX[256] = { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; + +static uint8_t SBOX2[256]; +static uint8_t SBOX3[256]; + +static const uint8_t CONX = 0X1B; + +// tables + +static uint32_t T1[256]; +static uint32_t T2[256]; +static uint32_t T3[256]; +static uint32_t T4[256]; + +void generate_tables(); +void print_tables(); + +int main () { + + int i; + for ( i = 0; i < 256; ++i ) { + + SBOX2[i] = SBOX[i] << 1; + + if ( SBOX[i] >= 128 ) { + SBOX2[i] ^= CONX; + } + + SBOX3[i] = SBOX2[i] ^ SBOX[i]; + + } + + generate_tables(); + print_tables(); + + return 0; +} + +void print_tables() { + + int i; + printf("T1:\n"); + for ( i = 0; i < 256; ++i ) { + printf("0x%8x, ", T1[i]); + if ( i % 4 == 3 ) { + printf("\n"); + } + } + printf("\n\n"); + + printf("T2:\n"); + for ( i = 0; i < 256; ++i ) { + printf("0x%8x, ", T2[i]); + if ( i % 4 == 3 ) { + printf("\n"); + } + } + printf("\n\n"); + + printf("T3:\n"); + for ( i = 0; i < 256; ++i) { + printf("0x%8x, ", T3[i]); + if ( i % 4 == 3 ) { + printf("\n"); + } + } + printf("\n\n"); + + printf("T4:\n"); + for ( i = 0; i < 256; ++i ) { + printf("0x%8x, ", T4[i]); + if ( i % 4 == 3 ) { + printf("\n"); + } + } + +} + +void generate_tables() { + + int i; + for (i = 0; i < 256; ++i ) { + T1[i] = ((uint32_t)SBOX3[i]<<24) ^ ((uint32_t)SBOX[i]<<16) + ^ ((uint32_t)SBOX[i]<<8) ^ ((uint32_t)SBOX2[i]); + T2[i] = ((uint32_t)SBOX[i]<<24) ^ ((uint32_t)SBOX[i]<<16) + ^ ((uint32_t)SBOX2[i]<<8)^ ((uint32_t)SBOX3[i]); + T3[i] = ((uint32_t)SBOX[i]<<24) ^ ((uint32_t)SBOX2[i]<<16) + ^ ((uint32_t)SBOX3[i]<<8)^ ((uint32_t)SBOX[i]); + T4[i] = ((uint32_t)SBOX2[i]<<24) ^ ((uint32_t)SBOX3[i]<<16) + ^ ((uint32_t)SBOX[i]<<8) ^ ((uint32_t)SBOX[i]); + } + +} diff --git a/thirdparty/aes_128/main.c b/thirdparty/aes_128/main.c new file mode 100644 index 0000000..f2813d9 --- /dev/null +++ b/thirdparty/aes_128/main.c @@ -0,0 +1,95 @@ +/* + * + * Chinese Academy of Sciences + * State Key Laboratory of Information Security + * Institute of Information Engineering + * + * Copyright (C) 2016 Chinese Academy of Sciences + * + * LuoPeng, luopeng@iie.ac.cn + * Updated in May 2016 + * + */ + +#include + +#include "aes.h" + +int main(int argc, char *argv[]) { + + uint8_t i, r; + + /* 128 bit key */ + uint8_t key[] = { + //0x0f, 0x15, 0x71, 0xc9, 0x47, 0xd9, 0xe8, 0x59, + //0x0c, 0xb7, 0xad, 0xd6, 0xaf, 0x7f, 0x67, 0x98, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + + }; + + uint8_t plaintext[] = { + //0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + //0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + }; + + + uint8_t ciphertext[AES_BLOCK_SIZE]; + + const uint8_t const_cipher[AES_BLOCK_SIZE] = { + //0xff, 0x0b, 0x84, 0x4a, 0x08, 0x53, 0xbf, 0x7c, + //0x69, 0x34, 0xab, 0x43, 0x64, 0x14, 0x8f, 0xb9, + 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, + 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a, + }; + + uint8_t roundkeys[AES_ROUND_KEY_SIZE]; + + printf("\n--------------------------------------------------------\n"); + printf("Plain text:\n"); + for (i = 0; i < AES_BLOCK_SIZE; i++) { + printf("%2x ", plaintext[i]); + } + printf("\n\n"); + + // key schedule + aes_key_schedule_128(key, roundkeys); + printf("Round Keys:\n"); + for ( r = 0; r <= AES_ROUNDS; r++ ) { + for (i = 0; i < AES_BLOCK_SIZE; i++) { + printf("%2x ", roundkeys[r*AES_BLOCK_SIZE+i]); + } + printf("\n"); + } + printf("\n"); + + // encryption + aes_encrypt_128(roundkeys, plaintext, ciphertext); + printf("Cipher text:\n"); + for (i = 0; i < AES_BLOCK_SIZE; i++) { + printf("%2x ", ciphertext[i]); + } + for (i = 0; i < AES_BLOCK_SIZE; i++) { + if ( ciphertext[i] != const_cipher[i] ) { break; } + } + if ( AES_BLOCK_SIZE != i ) { printf("\nENCRYPT WRONG\n\n"); } + else { printf("\nENCRYPT CORRECT\n\n"); } + + + // decryption + aes_decrypt_128(roundkeys, ciphertext, ciphertext); + printf("Plain text:\n"); + for (i = 0; i < AES_BLOCK_SIZE; i++) { + printf("%2x ", ciphertext[i]); + } + for (i = 0; i < AES_BLOCK_SIZE; i++) { + if ( ciphertext[i] != plaintext[i] ) { break; } + } + if ( AES_BLOCK_SIZE != i ) { printf("\nDECRYPT WRONG\n\n"); } + else { printf("\nDECRYPT CORRECT\n\n"); } + + return 0; + +} diff --git a/thirdparty/aes_128/makefile b/thirdparty/aes_128/makefile new file mode 100644 index 0000000..13923de --- /dev/null +++ b/thirdparty/aes_128/makefile @@ -0,0 +1,13 @@ +CC=gcc +CFLAGS=-Wall -O2 + +aes.out: aes.o main.o + $(CC) -o $@ $^ $(CFLAGS) + make clean + +clean: + rm -f *.o + +cleanall: + rm -f aes.out + rm -f *.o \ No newline at end of file diff --git a/thirdparty/aes_128/unroll/aes.c b/thirdparty/aes_128/unroll/aes.c new file mode 100644 index 0000000..e5d044c --- /dev/null +++ b/thirdparty/aes_128/unroll/aes.c @@ -0,0 +1,261 @@ +/* + * Full unroll implementation of aes-128 + * + * Author: LuoPeng (luopengxq@gmail.com) + * Time: 2017.08.02 + */ +#include +#include + +#include "aes.h" + +/* + * round constants + */ +static uint8_t RC[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; + +/* + * Sbox + */ +static uint8_t SBOX[256] = { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; + +/* + * Inverse Sboxs + */ +static uint8_t INV_SBOX[256] = { + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d}; + +/** + * https://en.wikipedia.org/wiki/Finite_field_arithmetic + * Multiply two numbers in the GF(2^8) finite field defined + * by the polynomial x^8 + x^4 + x^3 + x + 1 = 0 + * We do use mul2(int8_t a) but not mul(uint8_t a, uint8_t b) + * just in order to get a higher speed. + */ +static inline uint8_t mul2(uint8_t a) { + return (a&0x80) ? ((a<<1)^0x1b) : (a<<1); +} + +void aes_key_schedule_128(const uint8_t *key, uint8_t *roundkeys) { + + uint8_t temp[4]; + uint8_t *last4bytes; // point to the last 4 bytes of one round + uint8_t *lastround; + uint8_t i; + + for (i = 0; i < 16; ++i) { + *roundkeys++ = *key++; + } + + last4bytes = roundkeys-4; + for (i = 0; i < AES_ROUNDS; ++i) { + // k0-k3 for next round + temp[3] = SBOX[*last4bytes++]; + temp[0] = SBOX[*last4bytes++]; + temp[1] = SBOX[*last4bytes++]; + temp[2] = SBOX[*last4bytes++]; + temp[0] ^= RC[i]; + lastround = roundkeys-16; + *roundkeys++ = temp[0] ^ *lastround++; + *roundkeys++ = temp[1] ^ *lastround++; + *roundkeys++ = temp[2] ^ *lastround++; + *roundkeys++ = temp[3] ^ *lastround++; + // k4-k7 for next round + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + // k8-k11 for next round + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + // k12-k15 for next round + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + *roundkeys++ = *last4bytes++ ^ *lastround++; + } +} + +// encryption + +#define sub_bytes(ct, tmp) \ + *tmp = SBOX[*ct], *(tmp+1) = SBOX[*(ct+1)], *(tmp+2) = SBOX[*(ct+2)], *(tmp+3) = SBOX[*(ct+3)]; \ + *(tmp+4) = SBOX[*(ct+4)], *(tmp+5) = SBOX[*(ct+5)], *(tmp+6) = SBOX[*(ct+6)], *(tmp+7) = SBOX[*(ct+7)]; \ + *(tmp+8) = SBOX[*(ct+8)], *(tmp+9) = SBOX[*(ct+9)], *(tmp+10) = SBOX[*(ct+10)], *(tmp+11) = SBOX[*(ct+11)]; \ + *(tmp+12) = SBOX[*(ct+12)], *(tmp+13) = SBOX[*(ct+13)], *(tmp+14) = SBOX[*(ct+14)], *(tmp+15) = SBOX[*(ct+15)]; + +#define shift_rows(tmp, t) \ + t = *(tmp+1), *(tmp+1) = *(tmp+5), *(tmp+5) = *(tmp+9), *(tmp+9) = *(tmp+13), *(tmp+13) = t; \ + t = *(tmp+2), *(tmp+2) = *(tmp+10), *(tmp+10) = t; \ + t = *(tmp+6), *(tmp+6) = *(tmp+14), *(tmp+14) = t; \ + t = *(tmp+15), *(tmp+15) = *(tmp+11), *(tmp+11) = *(tmp+7), *(tmp+7) = *(tmp+3), *(tmp+3) = t; + +#define mix_columns(ct, tmp, t) \ + t = tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3]; \ + ct[0] = mul2(tmp[0] ^ tmp[1]) ^ tmp[0] ^ t; \ + ct[1] = mul2(tmp[1] ^ tmp[2]) ^ tmp[1] ^ t; \ + ct[2] = mul2(tmp[2] ^ tmp[3]) ^ tmp[2] ^ t; \ + ct[3] = mul2(tmp[3] ^ tmp[0]) ^ tmp[3] ^ t; \ + t = tmp[4] ^ tmp[5] ^ tmp[6] ^ tmp[7]; \ + ct[4] = mul2(tmp[4] ^ tmp[5]) ^ tmp[4] ^ t; \ + ct[5] = mul2(tmp[5] ^ tmp[6]) ^ tmp[5] ^ t; \ + ct[6] = mul2(tmp[6] ^ tmp[7]) ^ tmp[6] ^ t; \ + ct[7] = mul2(tmp[7] ^ tmp[4]) ^ tmp[7] ^ t; \ + t = tmp[8] ^ tmp[9] ^ tmp[10] ^ tmp[11]; \ + ct[8] = mul2(tmp[8] ^ tmp[9]) ^ tmp[8] ^ t; \ + ct[9] = mul2(tmp[9] ^ tmp[10]) ^ tmp[9] ^ t; \ + ct[10] = mul2(tmp[10] ^ tmp[11]) ^ tmp[10] ^ t; \ + ct[11] = mul2(tmp[11] ^ tmp[8]) ^ tmp[11] ^ t; \ + t = tmp[12] ^ tmp[13] ^ tmp[14] ^ tmp[15]; \ + ct[12] = mul2(tmp[12] ^ tmp[13]) ^ tmp[12] ^ t; \ + ct[13] = mul2(tmp[13] ^ tmp[14]) ^ tmp[13] ^ t; \ + ct[14] = mul2(tmp[14] ^ tmp[15]) ^ tmp[14] ^ t; \ + ct[15] = mul2(tmp[15] ^ tmp[12]) ^ tmp[15] ^ t; + +#define add_round_key(in, out, rks) \ + *out = *in ^ *rks++, *(out+1) = *(in+1) ^ *rks++, *(out+2) = *(in+2) ^ *rks++, *(out+3) = *(in+3) ^ *rks++; \ + *(out+4) = *(in+4) ^ *rks++, *(out+5) = *(in+5) ^ *rks++, *(out+6) = *(in+6) ^ *rks++, *(out+7) = *(in+7) ^ *rks++; \ + *(out+8) = *(in+8) ^ *rks++, *(out+9) = *(in+9) ^ *rks++, *(out+10) = *(in+10) ^ *rks++, *(out+11) = *(in+11) ^ *rks++; \ + *(out+12) = *(in+12) ^ *rks++, *(out+13) = *(in+13) ^ *rks++, *(out+14) = *(in+14) ^ *rks++, *(out+15) = *(in+15) ^ *rks++; + +#define enc_one_round(ct, rks, tmp, t) \ + sub_bytes(ct, tmp); \ + shift_rows(tmp, t); \ + mix_columns(ct, tmp, t); \ + add_round_key(ct, ct, rks); + +#define enc_last_round(ct, rks, t) \ + sub_bytes(ct, ct); \ + shift_rows(ct, t); \ + add_round_key(ct, ct, rks); + +void aes_encrypt_128(const uint8_t *roundkeys, const uint8_t *plaintext, uint8_t *ciphertext) { + + uint8_t tmp[16], t; + + add_round_key(plaintext, ciphertext, roundkeys); + + enc_one_round(ciphertext, roundkeys, tmp, t); + enc_one_round(ciphertext, roundkeys, tmp, t); + enc_one_round(ciphertext, roundkeys, tmp, t); + enc_one_round(ciphertext, roundkeys, tmp, t); + enc_one_round(ciphertext, roundkeys, tmp, t); + enc_one_round(ciphertext, roundkeys, tmp, t); + enc_one_round(ciphertext, roundkeys, tmp, t); + enc_one_round(ciphertext, roundkeys, tmp, t); + enc_one_round(ciphertext, roundkeys, tmp, t); + + enc_last_round(ciphertext, roundkeys, t); + +} + + +// decryption + +#define inv_add_round_key(in, out, rks) \ + *out = *in ^ *rks, *(out+1) = *(in+1) ^ *(rks+1), *(out+2) = *(in+2) ^ *(rks+2), *(out+3) = *(in+3) ^ *(rks+3); \ + *(out+4) = *(in+4) ^ *(rks+4), *(out+5) = *(in+5) ^ *(rks+5), *(out+6) = *(in+6) ^ *(rks+6), *(out+7) = *(in+7) ^ *(rks+7); \ + *(out+8) = *(in+8) ^ *(rks+8), *(out+9) = *(in+9) ^ *(rks+9), *(out+10) = *(in+10) ^ *(rks+10), *(out+11) = *(in+11) ^ *(rks+11); \ + *(out+12) = *(in+12) ^ *(rks+12), *(out+13) = *(in+13) ^ *(rks+13), *(out+14) = *(in+14) ^ *(rks+14), *(out+15) = *(in+15) ^ *(rks+15); + +#define inv_shift_rows(pt, t) \ + t = *(pt+13); *(pt+13) = *(pt+9); *(pt+9) = *(pt+5); *(pt+5) = *(pt+1); *(pt+1) = t; \ + t = *(pt+14); *(pt+14) = *(pt+6); *(pt+6) = t; \ + t = *(pt+10); *(pt+10) = *(pt+2); *(pt+2) = t; \ + t = *(pt+3); *(pt+3) = *(pt+7); *(pt+7) = *(pt+11); *(pt+11) = *(pt+15); *(pt+15) = t; + +#define inv_sub_bytes(pt) \ + *pt = INV_SBOX[*pt], *(pt+1) = INV_SBOX[*(pt+1)], *(pt+2) = INV_SBOX[*(pt+2)], *(pt+3) = INV_SBOX[*(pt+3)]; \ + *(pt+4) = INV_SBOX[*(pt+4)], *(pt+5) = INV_SBOX[*(pt+5)], *(pt+6) = INV_SBOX[*(pt+6)], *(pt+7) = INV_SBOX[*(pt+7)]; \ + *(pt+8) = INV_SBOX[*(pt+8)], *(pt+9) = INV_SBOX[*(pt+9)], *(pt+10) = INV_SBOX[*(pt+10)], *(pt+11) = INV_SBOX[*(pt+11)]; \ + *(pt+12) = INV_SBOX[*(pt+12)], *(pt+13) = INV_SBOX[*(pt+13)], *(pt+14) = INV_SBOX[*(pt+14)], *(pt+15) = INV_SBOX[*(pt+15)]; + +#define inv_mix_columns(pt, tmp, t, u, v) \ + t = tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3]; \ + pt[0] = t ^ tmp[0] ^ mul2(tmp[0] ^ tmp[1]), pt[1] = t ^ tmp[1] ^ mul2(tmp[1] ^ tmp[2]); \ + pt[2] = t ^ tmp[2] ^ mul2(tmp[2] ^ tmp[3]), pt[3] = t ^ tmp[3] ^ mul2(tmp[3] ^ tmp[0]); \ + u = mul2(mul2(tmp[0] ^ tmp[2])), v = mul2(mul2(tmp[1] ^ tmp[3])), t = mul2(u ^ v); \ + pt[0] ^= t ^ u, pt[1] ^= t ^ v, pt[2] ^= t ^ u, pt[3] ^= t ^ v; \ + t = tmp[4] ^ tmp[5] ^ tmp[6] ^ tmp[7]; \ + pt[4] = t ^ tmp[4] ^ mul2(tmp[4] ^ tmp[5]), pt[5] = t ^ tmp[5] ^ mul2(tmp[5] ^ tmp[6]); \ + pt[6] = t ^ tmp[6] ^ mul2(tmp[6] ^ tmp[7]), pt[7] = t ^ tmp[7] ^ mul2(tmp[7] ^ tmp[4]); \ + u = mul2(mul2(tmp[4] ^ tmp[6])), v = mul2(mul2(tmp[5] ^ tmp[7])), t = mul2(u ^ v); \ + pt[4] ^= t ^ u, pt[5] ^= t ^ v, pt[6] ^= t ^ u, pt[7] ^= t ^ v; \ + t = tmp[8] ^ tmp[9] ^ tmp[10] ^ tmp[11]; \ + pt[8] = t ^ tmp[8] ^ mul2(tmp[8] ^ tmp[9]), pt[9] = t ^ tmp[9] ^ mul2(tmp[9] ^ tmp[10]); \ + pt[10] = t ^ tmp[10] ^ mul2(tmp[10] ^ tmp[11]), pt[11] = t ^ tmp[11] ^ mul2(tmp[11] ^ tmp[8]); \ + u = mul2(mul2(tmp[8] ^ tmp[10])), v = mul2(mul2(tmp[9] ^ tmp[11])), t = mul2(u ^ v); \ + pt[8] ^= t ^ u, pt[9] ^= t ^ v, pt[10] ^= t ^ u, pt[11] ^= t ^ v; \ + t = tmp[12] ^ tmp[13] ^ tmp[14] ^ tmp[15]; \ + pt[12] = t ^ tmp[12] ^ mul2(tmp[12] ^ tmp[13]), pt[13] = t ^ tmp[13] ^ mul2(tmp[13] ^ tmp[14]); \ + pt[14] = t ^ tmp[14] ^ mul2(tmp[14] ^ tmp[15]), pt[15] = t ^ tmp[15] ^ mul2(tmp[15] ^ tmp[12]); \ + u = mul2(mul2(tmp[12] ^ tmp[14])), v = mul2(mul2(tmp[13] ^ tmp[15])), t = mul2(u ^ v); \ + pt[12] ^= t ^ u, pt[13] ^= t ^ v, pt[14] ^= t ^ u, pt[15] ^= t ^ v; + +#define dec_first_round(ct, pt, rks, t) \ + inv_add_round_key(ct, pt, rks); \ + rks -= 16; \ + inv_shift_rows(pt, t); \ + inv_sub_bytes(pt); + +#define dec_one_round(pt, rks, tmp, t, u, v) \ + inv_add_round_key(pt, tmp, rks); \ + roundkeys -= 16; \ + inv_mix_columns(pt, tmp, t, u, v); \ + inv_shift_rows(pt, t); \ + inv_sub_bytes(pt); + +void aes_decrypt_128(const uint8_t *roundkeys, const uint8_t *ciphertext, uint8_t *plaintext) { + + uint8_t tmp[16]; + uint8_t t, u, v; + + roundkeys += 160; + dec_first_round(ciphertext, plaintext, roundkeys, t); + + dec_one_round(plaintext, roundkeys, tmp, t, u, v); + dec_one_round(plaintext, roundkeys, tmp, t, u, v); + dec_one_round(plaintext, roundkeys, tmp, t, u, v); + dec_one_round(plaintext, roundkeys, tmp, t, u, v); + dec_one_round(plaintext, roundkeys, tmp, t, u, v); + dec_one_round(plaintext, roundkeys, tmp, t, u, v); + dec_one_round(plaintext, roundkeys, tmp, t, u, v); + dec_one_round(plaintext, roundkeys, tmp, t, u, v); + dec_one_round(plaintext, roundkeys, tmp, t, u, v); + + inv_add_round_key(plaintext, plaintext, roundkeys); + +} \ No newline at end of file diff --git a/thirdparty/catch2 b/thirdparty/catch2 new file mode 160000 index 0000000..88abf9b --- /dev/null +++ b/thirdparty/catch2 @@ -0,0 +1 @@ +Subproject commit 88abf9bf325c798c33f54f6b9220ef885b267f4f diff --git a/thirdparty/cli11 b/thirdparty/cli11 new file mode 160000 index 0000000..bfffd37 --- /dev/null +++ b/thirdparty/cli11 @@ -0,0 +1 @@ +Subproject commit bfffd37e1f804ca4fae1caae106935791696b6a9 diff --git a/thirdparty/crypto/TinySHA1.hpp b/thirdparty/crypto/TinySHA1.hpp new file mode 100644 index 0000000..2493e88 --- /dev/null +++ b/thirdparty/crypto/TinySHA1.hpp @@ -0,0 +1,223 @@ +/* + * + * TinySHA1 - a header only implementation of the SHA1 algorithm in C++. Based + * on the implementation in boost::uuid::details. + * + * SHA1 Wikipedia Page: http://en.wikipedia.org/wiki/SHA-1 + * + * Copyright (c) 2012-22 SAURAV MOHAPATRA + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Taken from https://github.com/mohaps/TinySHA1 + * Modified for use by Xenia + */ +#ifndef _TINY_SHA1_HPP_ +#define _TINY_SHA1_HPP_ + +#include +#include +#include +#include + +namespace sha1 { +class SHA1 { + public: + typedef uint32_t digest32_t[5]; + typedef uint8_t digest8_t[20]; + inline static uint32_t LeftRotate(uint32_t value, size_t count) { + return (value << count) ^ (value >> (32 - count)); + } + SHA1() { reset(); } + virtual ~SHA1() {} + SHA1(const SHA1& s) { *this = s; } + const SHA1& operator=(const SHA1& s) { + memcpy(m_digest, s.m_digest, 5 * sizeof(uint32_t)); + memcpy(m_block, s.m_block, 64); + m_blockByteIndex = s.m_blockByteIndex; + m_byteCount = s.m_byteCount; + + return *this; + } + + SHA1& init(const uint32_t digest[5], const uint8_t block[64], + uint32_t count) { + std::memcpy(m_digest, digest, 20); + std::memcpy(m_block, block, count % 64); + m_byteCount = count; + m_blockByteIndex = count % 64; + + return *this; + } + + const uint32_t* getDigest() const { return m_digest; } + const uint8_t* getBlock() const { return m_block; } + size_t getBlockByteIndex() const { return m_blockByteIndex; } + size_t getByteCount() const { return m_byteCount; } + + SHA1& reset() { + m_digest[0] = 0x67452301; + m_digest[1] = 0xEFCDAB89; + m_digest[2] = 0x98BADCFE; + m_digest[3] = 0x10325476; + m_digest[4] = 0xC3D2E1F0; + m_blockByteIndex = 0; + m_byteCount = 0; + return *this; + } + + SHA1& processByte(uint8_t octet) { + this->m_block[this->m_blockByteIndex++] = octet; + ++this->m_byteCount; + if (m_blockByteIndex == 64) { + this->m_blockByteIndex = 0; + processBlock(); + } + + return *this; + } + + SHA1& processBlock(const void* const start, const void* const end) { + const uint8_t* begin = static_cast(start); + const uint8_t* finish = static_cast(end); + while (begin != finish) { + processByte(*begin); + begin++; + } + return *this; + } + + SHA1& processBytes(const void* const data, size_t len) { + const uint8_t* block = static_cast(data); + processBlock(block, block + len); + return *this; + } + + const uint32_t* finalize(digest32_t digest) { + size_t bitCount = this->m_byteCount * 8; + processByte(0x80); + if (this->m_blockByteIndex > 56) { + while (m_blockByteIndex != 0) { + processByte(0); + } + while (m_blockByteIndex < 56) { + processByte(0); + } + } else { + while (m_blockByteIndex < 56) { + processByte(0); + } + } + processByte(0); + processByte(0); + processByte(0); + processByte(0); + processByte(static_cast((bitCount >> 24) & 0xFF)); + processByte(static_cast((bitCount >> 16) & 0xFF)); + processByte(static_cast((bitCount >> 8) & 0xFF)); + processByte(static_cast((bitCount)&0xFF)); + + memcpy(digest, m_digest, 5 * sizeof(uint32_t)); + return digest; + } + + const uint8_t* finalize(digest8_t digest) { + digest32_t d32; + finalize(d32); + size_t di = 0; + digest[di++] = ((d32[0] >> 24) & 0xFF); + digest[di++] = ((d32[0] >> 16) & 0xFF); + digest[di++] = ((d32[0] >> 8) & 0xFF); + digest[di++] = ((d32[0]) & 0xFF); + + digest[di++] = ((d32[1] >> 24) & 0xFF); + digest[di++] = ((d32[1] >> 16) & 0xFF); + digest[di++] = ((d32[1] >> 8) & 0xFF); + digest[di++] = ((d32[1]) & 0xFF); + + digest[di++] = ((d32[2] >> 24) & 0xFF); + digest[di++] = ((d32[2] >> 16) & 0xFF); + digest[di++] = ((d32[2] >> 8) & 0xFF); + digest[di++] = ((d32[2]) & 0xFF); + + digest[di++] = ((d32[3] >> 24) & 0xFF); + digest[di++] = ((d32[3] >> 16) & 0xFF); + digest[di++] = ((d32[3] >> 8) & 0xFF); + digest[di++] = ((d32[3]) & 0xFF); + + digest[di++] = ((d32[4] >> 24) & 0xFF); + digest[di++] = ((d32[4] >> 16) & 0xFF); + digest[di++] = ((d32[4] >> 8) & 0xFF); + digest[di++] = ((d32[4]) & 0xFF); + return digest; + } + + protected: + void processBlock() { + uint32_t w[80]; + for (size_t i = 0; i < 16; i++) { + w[i] = (m_block[i * 4 + 0] << 24); + w[i] |= (m_block[i * 4 + 1] << 16); + w[i] |= (m_block[i * 4 + 2] << 8); + w[i] |= (m_block[i * 4 + 3]); + } + for (size_t i = 16; i < 80; i++) { + w[i] = LeftRotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1); + } + + uint32_t a = m_digest[0]; + uint32_t b = m_digest[1]; + uint32_t c = m_digest[2]; + uint32_t d = m_digest[3]; + uint32_t e = m_digest[4]; + + for (std::size_t i = 0; i < 80; ++i) { + uint32_t f = 0; + uint32_t k = 0; + + if (i < 20) { + f = (b & c) | (~b & d); + k = 0x5A827999; + } else if (i < 40) { + f = b ^ c ^ d; + k = 0x6ED9EBA1; + } else if (i < 60) { + f = (b & c) | (b & d) | (c & d); + k = 0x8F1BBCDC; + } else { + f = b ^ c ^ d; + k = 0xCA62C1D6; + } + uint32_t temp = LeftRotate(a, 5) + f + e + k + w[i]; + e = d; + d = c; + c = LeftRotate(b, 30); + b = a; + a = temp; + } + + m_digest[0] += a; + m_digest[1] += b; + m_digest[2] += c; + m_digest[3] += d; + m_digest[4] += e; + } + + private: + digest32_t m_digest; + uint8_t m_block[64]; + size_t m_blockByteIndex; + size_t m_byteCount; +}; +} +#endif diff --git a/thirdparty/crypto/des/LICENSE b/thirdparty/crypto/des/LICENSE new file mode 100644 index 0000000..45e37f5 --- /dev/null +++ b/thirdparty/crypto/des/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014 Faraz Fallahi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/thirdparty/crypto/des/README.md b/thirdparty/crypto/des/README.md new file mode 100644 index 0000000..c904a28 --- /dev/null +++ b/thirdparty/crypto/des/README.md @@ -0,0 +1,6 @@ +cppDES +====== + +Taken from [this repository](https://github.com/fffaraz/cppDES) + +Modified for use by Xenia. \ No newline at end of file diff --git a/thirdparty/crypto/des/des.cpp b/thirdparty/crypto/des/des.cpp new file mode 100644 index 0000000..d4ad544 --- /dev/null +++ b/thirdparty/crypto/des/des.cpp @@ -0,0 +1,177 @@ +#include "des.h" +#include "des_key.h" +#include "des_data.h" +#include "des_lookup.h" + +#include + +//#pragma GCC push_options +#ifndef _MSC_VER +#pragma GCC optimize ("unroll-loops") +#endif + +DES::DES(ui64 key) +{ + keygen(key); +} + +DES::DES(ui64* sub_key) +{ + set_sub_key(sub_key); +} + +void DES::set_sub_key(ui64 *sub_key) +{ + std::memcpy(this->sub_key, sub_key, 128); +} + +ui64 DES::encrypt(ui64 block) +{ + return des(block, false); +} + +ui64 DES::decrypt(ui64 block) +{ + return des(block, true); +} + +ui64 DES::encrypt(ui64 block, ui64 key) +{ + DES des(key); + return des.des(block, false); +} + +ui64 DES::decrypt(ui64 block, ui64 key) +{ + DES des(key); + return des.des(block, true); +} + +void DES::keygen(ui64 key) +{ + // initial key schedule calculation + ui64 permuted_choice_1 = 0; // 56 bits + for (ui8 i = 0; i < 56; i++) + { + permuted_choice_1 <<= 1; + permuted_choice_1 |= (key >> (64-PC1[i])) & LB64_MASK; + } + + // 28 bits + ui32 C = (ui32) ((permuted_choice_1 >> 28) & 0x000000000fffffff); + ui32 D = (ui32) (permuted_choice_1 & 0x000000000fffffff); + + // Calculation of the 16 keys + for (ui8 i = 0; i < 16; i++) + { + // key schedule, shifting Ci and Di + for (ui8 j = 0; j < ITERATION_SHIFT[i]; j++) + { + C = (0x0fffffff & (C << 1)) | (0x00000001 & (C >> 27)); + D = (0x0fffffff & (D << 1)) | (0x00000001 & (D >> 27)); + } + + ui64 permuted_choice_2 = (((ui64) C) << 28) | (ui64) D; + + sub_key[i] = 0; // 48 bits (2*24) + for (ui8 j = 0; j < 48; j++) + { + sub_key[i] <<= 1; + sub_key[i] |= (permuted_choice_2 >> (56-PC2[j])) & LB64_MASK; + } + } +} + +ui64 DES::des(ui64 block, bool mode) +{ + // applying initial permutation + block = ip(block); + + // dividing T' into two 32-bit parts + ui32 L = (ui32) (block >> 32) & L64_MASK; + ui32 R = (ui32) (block & L64_MASK); + + // 16 rounds + for (ui8 i = 0; i < 16; i++) + { + ui32 F = mode ? f(R, sub_key[15-i]) : f(R, sub_key[i]); + feistel(L, R, F); + } + + // swapping the two parts + block = (((ui64) R) << 32) | (ui64) L; + // applying final permutation + return fp(block); +} + +ui64 DES::ip(ui64 block) +{ + // initial permutation + ui64 result = 0; + for (ui8 i = 0; i < 64; i++) + { + result <<= 1; + result |= (block >> (64-IP[i])) & LB64_MASK; + } + return result; +} + +ui64 DES::fp(ui64 block) +{ + // inverse initial permutation + ui64 result = 0; + for (ui8 i = 0; i < 64; i++) + { + result <<= 1; + result |= (block >> (64-FP[i])) & LB64_MASK; + } + return result; +} + +void DES::feistel(ui32 &L, ui32 &R, ui32 F) +{ + ui32 temp = R; + R = L ^ F; + L = temp; +} + +ui32 DES::f(ui32 R, ui64 k) // f(R,k) function +{ + // applying expansion permutation and returning 48-bit data + ui64 s_input = 0; + for (ui8 i = 0; i < 48; i++) + { + s_input <<= 1; + s_input |= (ui64) ((R >> (32-EXPANSION[i])) & LB32_MASK); + } + + // XORing expanded Ri with Ki, the round key + s_input = s_input ^ k; + + // applying S-Boxes function and returning 32-bit data + ui32 s_output = 0; + for (ui8 i = 0; i < 8; i++) + { + // Outer bits + char row = (char) ((s_input & (0x0000840000000000 >> 6*i)) >> (42-6*i)); + row = (row >> 4) | (row & 0x01); + + // Middle 4 bits of input + char column = (char) ((s_input & (0x0000780000000000 >> 6*i)) >> (43-6*i)); + + s_output <<= 4; + s_output |= (ui32) (SBOX[i][16*row + column] & 0x0f); + } + + // applying the round permutation + ui32 f_result = 0; + for (ui8 i = 0; i < 32; i++) + { + f_result <<= 1; + f_result |= (s_output >> (32 - PBOX[i])) & LB32_MASK; + } + + return f_result; +} + +//#pragma GCC pop_options diff --git a/thirdparty/crypto/des/des.h b/thirdparty/crypto/des/des.h new file mode 100644 index 0000000..5425417 --- /dev/null +++ b/thirdparty/crypto/des/des.h @@ -0,0 +1,51 @@ +#ifndef DES_H +#define DES_H + +#include + +typedef uint64_t ui64; +typedef uint32_t ui32; +typedef uint8_t ui8; + +class DES +{ +public: + DES(ui64 key); + DES(ui64 *sub_key); + ui64 des(ui64 block, bool mode); + + ui64 encrypt(ui64 block); + ui64 decrypt(ui64 block); + + static ui64 encrypt(ui64 block, ui64 key); + static ui64 decrypt(ui64 block, ui64 key); + + static void set_parity(ui8 *key, int length, ui8 *out) { + for (int i = 0; i < length; i++) { + ui8 parity = key[i]; + + parity ^= parity >> 4; + parity ^= parity >> 2; + parity ^= parity >> 1; + + out[i] = (key[i] & 0xFE) | (~parity & 1); + } + } + + const ui64 *get_sub_key() const { return sub_key; } + void set_sub_key(ui64 *key); + +protected: + void keygen(ui64 key); + + ui64 ip(ui64 block); + ui64 fp(ui64 block); + + void feistel(ui32 &L, ui32 &R, ui32 F); + ui32 f(ui32 R, ui64 k); + +private: + ui64 sub_key[16]; // 48 bits each +}; + +#endif // DES_H diff --git a/thirdparty/crypto/des/des3.h b/thirdparty/crypto/des/des3.h new file mode 100644 index 0000000..4b32772 --- /dev/null +++ b/thirdparty/crypto/des/des3.h @@ -0,0 +1,40 @@ +#ifndef DES3_H +#define DES3_H + +#include "des.h" + +class DES3 +{ +public: + DES3(ui64 k1, ui64 k2, ui64 k3) : des{ DES(k1), DES(k2), DES(k3) } {} + DES3(ui64* sk1, ui64* sk2, ui64* sk3) : des{ DES(sk1), DES(sk2), DES(sk3) } {} + + inline ui64 encrypt(ui64 block) + { + return des[2].encrypt(des[1].decrypt(des[0].encrypt(block))); + } + + inline ui64 decrypt(ui64 block) + { + return des[0].decrypt(des[1].encrypt(des[2].decrypt(block))); + } + + inline ui64 crypt(ui64 block, bool bEncrypt) + { + if (bEncrypt) + { + return encrypt(block); + } + else + { + return decrypt(block); + } + } + + inline DES* getDES() { return des; } + +private: + DES des[3]; +}; + +#endif // DES3_H diff --git a/thirdparty/crypto/des/des_data.h b/thirdparty/crypto/des/des_data.h new file mode 100644 index 0000000..5bda75a --- /dev/null +++ b/thirdparty/crypto/des/des_data.h @@ -0,0 +1,121 @@ +#ifndef DES_DATA_H +#define DES_DATA_H + +#define LB32_MASK 0x00000001 +#define LB64_MASK 0x0000000000000001 +#define L64_MASK 0x00000000ffffffff + +// Initial Permutation Table [8*8] +static const char IP[] = +{ + 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7 +}; + +// Inverse Initial Permutation Table [8*8] +static const char FP[] = +{ + 40, 8, 48, 16, 56, 24, 64, 32, + 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25 +}; + +// Expansion table [6*8] +static const char EXPANSION[] = +{ + 32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1 +}; + +// The S-Box tables [8*16*4] +static const char SBOX[8][64] = +{ + { + // S1 + 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 + }, + { + // S2 + 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 + }, + { + // S3 + 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 + }, + { + // S4 + 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 + }, + { + // S5 + 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 + }, + { + // S6 + 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 + }, + { + // S7 + 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 + }, + { + // S8 + 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 + } +}; + +// Post S-Box permutation [4*8] +static const char PBOX[] = +{ + 16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25 +}; + +#endif // DES_DATA_H diff --git a/thirdparty/crypto/des/des_key.h b/thirdparty/crypto/des/des_key.h new file mode 100644 index 0000000..ea52a5b --- /dev/null +++ b/thirdparty/crypto/des/des_key.h @@ -0,0 +1,38 @@ +#ifndef DES_KEY_H +#define DES_KEY_H + +// Permuted Choice 1 Table [7*8] +static const char PC1[] = +{ + 57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4 +}; + +// Permuted Choice 2 Table [6*8] +static const char PC2[] = +{ + 14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32 +}; + +// Iteration Shift Array +static const char ITERATION_SHIFT[] = +{ +// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 +}; + +#endif // DES_KEY_H diff --git a/thirdparty/crypto/des/des_lookup.h b/thirdparty/crypto/des/des_lookup.h new file mode 100644 index 0000000..25e7862 --- /dev/null +++ b/thirdparty/crypto/des/des_lookup.h @@ -0,0 +1,4 @@ +#ifndef DES_LOOKUP_H +#define DES_LOOKUP_H + +#endif // DES_LOOKUP_H diff --git a/thirdparty/crypto/des/descbc.h b/thirdparty/crypto/des/descbc.h new file mode 100644 index 0000000..30a0fa7 --- /dev/null +++ b/thirdparty/crypto/des/descbc.h @@ -0,0 +1,34 @@ +#ifndef DESCBC_H +#define DESCBC_H + +#include "des.h" + +class DESCBC +{ +public: + DESCBC(ui64 key, ui64 iv) : des(key), iv(iv), last_block(iv) {} + inline ui64 encrypt(ui64 block) + { + last_block = des.encrypt(block ^ last_block); + return last_block; + } + + inline ui64 decrypt(ui64 block) + { + ui64 result = des.decrypt(block) ^ last_block; + last_block = block; + return result; + } + + inline void reset() + { + last_block = iv; + } + +private: + DES des; + ui64 iv; + ui64 last_block; +}; + +#endif // DESCBC_H diff --git a/thirdparty/crypto/rc4.c b/thirdparty/crypto/rc4.c new file mode 100644 index 0000000..c98b0b1 --- /dev/null +++ b/thirdparty/crypto/rc4.c @@ -0,0 +1,90 @@ +/* +* rc4.c +* +* Copyright (c) 1996-2000 Whistle Communications, Inc. +* All rights reserved. +* +* Subject to the following obligations and disclaimer of warranty, use and +* redistribution of this software, in source or object code forms, with or +* without modifications are expressly permitted by Whistle Communications; +* provided, however, that: +* 1. Any and all reproductions of the source or object code must include the +* copyright notice above and the following disclaimer of warranties; and +* 2. No rights are granted, in any manner or form, to use Whistle +* Communications, Inc. trademarks, including the mark "WHISTLE +* COMMUNICATIONS" on advertising, endorsements, or otherwise except as +* such appears in the above copyright notice or in the software. +* +* THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND +* TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO +* REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, +* INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. +* WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY +* REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS +* SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. +* IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES +* RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING +* WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +* PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY +* OF SUCH DAMAGE. +*/ + +#include "rc4.h" + +static __inline void swap_bytes(uint8_t *a, uint8_t *b) { + uint8_t temp; + + temp = *a; + *a = *b; + *b = temp; +} + +/* +* Initialize an RC4 state buffer using the supplied key, +* which can have arbitrary length. +*/ +void rc4_init(struct rc4_state *const state, const uint8_t *key, int keylen) { + uint8_t j; + int i; + + /* Initialize state with identity permutation */ + for (i = 0; i < 256; i++) state->perm[i] = (uint8_t)i; + state->index1 = 0; + state->index2 = 0; + + /* Randomize the permutation using key data */ + for (j = i = 0; i < 256; i++) { + j += state->perm[i] + key[i % keylen]; + swap_bytes(&state->perm[i], &state->perm[j]); + } +} + +/* +* Encrypt some data using the supplied RC4 state buffer. +* The input and output buffers may be the same buffer. +* Since RC4 is a stream cypher, this function is used +* for both encryption and decryption. +*/ +void rc4_crypt(struct rc4_state *const state, const uint8_t *inbuf, + uint8_t *outbuf, int buflen) { + int i; + uint8_t j; + + for (i = 0; i < buflen; i++) { + /* Update modification indicies */ + state->index1++; + state->index2 += state->perm[state->index1]; + + /* Modify permutation */ + swap_bytes(&state->perm[state->index1], &state->perm[state->index2]); + + /* Encrypt/decrypt next byte */ + j = state->perm[state->index1] + state->perm[state->index2]; + outbuf[i] = inbuf[i] ^ state->perm[j]; + } +} diff --git a/thirdparty/crypto/rc4.h b/thirdparty/crypto/rc4.h new file mode 100644 index 0000000..6328074 --- /dev/null +++ b/thirdparty/crypto/rc4.h @@ -0,0 +1,50 @@ +/* +* rc4.h +* +* Copyright (c) 1996-2000 Whistle Communications, Inc. +* All rights reserved. +* +* Subject to the following obligations and disclaimer of warranty, use and +* redistribution of this software, in source or object code forms, with or +* without modifications are expressly permitted by Whistle Communications; +* provided, however, that: +* 1. Any and all reproductions of the source or object code must include the +* copyright notice above and the following disclaimer of warranties; and +* 2. No rights are granted, in any manner or form, to use Whistle +* Communications, Inc. trademarks, including the mark "WHISTLE +* COMMUNICATIONS" on advertising, endorsements, or otherwise except as +* such appears in the above copyright notice or in the software. +* +* THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND +* TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO +* REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, +* INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. +* WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY +* REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS +* SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. +* IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES +* RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING +* WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +* PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY +* OF SUCH DAMAGE. +*/ + +#ifndef _SYS_CRYPTO_RC4_RC4_H_ +#define _SYS_CRYPTO_RC4_RC4_H_ + +struct rc4_state { + uint8_t perm[256]; + uint8_t index1; + uint8_t index2; +}; + +void rc4_init(struct rc4_state *state, const uint8_t *key, int keylen); +void rc4_crypt(struct rc4_state *state, const uint8_t *inbuf, uint8_t *outbuf, + int buflen); + +#endif diff --git a/thirdparty/crypto/rijndael-alg-fst.c b/thirdparty/crypto/rijndael-alg-fst.c new file mode 100644 index 0000000..99102f4 --- /dev/null +++ b/thirdparty/crypto/rijndael-alg-fst.c @@ -0,0 +1,1400 @@ +/** + * rijndael-alg-fst.c + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include + +#include "rijndael-alg-fst.h" + +/* +Te0[x] = S [x].[02, 01, 01, 03]; +Te1[x] = S [x].[03, 02, 01, 01]; +Te2[x] = S [x].[01, 03, 02, 01]; +Te3[x] = S [x].[01, 01, 03, 02]; +Te4[x] = S [x].[01, 01, 01, 01]; + +Td0[x] = Si[x].[0e, 09, 0d, 0b]; +Td1[x] = Si[x].[0b, 0e, 09, 0d]; +Td2[x] = Si[x].[0d, 0b, 0e, 09]; +Td3[x] = Si[x].[09, 0d, 0b, 0e]; +Td4[x] = Si[x].[01, 01, 01, 01]; +*/ + +static const u32 Te0[256] = { + 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, + 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, + 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, + 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, + 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, + 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, + 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, + 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, + 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, + 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, + 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, + 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, + 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, + 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, + 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, + 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, + 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, + 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, + 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, + 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, + 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, + 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, + 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, + 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, + 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, + 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, + 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, + 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, + 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, + 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, + 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, + 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, + 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, + 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, + 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, + 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, + 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, + 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, + 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, + 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, + 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, + 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, + 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, + 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, + 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, + 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, + 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, + 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, + 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, + 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, + 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, + 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, + 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, + 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, + 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, + 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, + 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, + 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, + 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, + 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, + 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, + 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, + 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, + 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, +}; +static const u32 Te1[256] = { + 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, + 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, + 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, + 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, + 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, + 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, + 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, + 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, + 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, + 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, + 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, + 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, + 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, + 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, + 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, + 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, + 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, + 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, + 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, + 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, + 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, + 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, + 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, + 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, + 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, + 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, + 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, + 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, + 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, + 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, + 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, + 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, + 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, + 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, + 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, + 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, + 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, + 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, + 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, + 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, + 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, + 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, + 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, + 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, + 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, + 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, + 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, + 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, + 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, + 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, + 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, + 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, + 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, + 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, + 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, + 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, + 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, + 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, + 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, + 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, + 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, + 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, + 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, + 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, +}; +static const u32 Te2[256] = { + 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, + 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, + 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, + 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, + 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, + 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, + 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, + 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, + 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, + 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, + 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, + 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, + 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, + 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, + 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, + 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, + 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, + 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, + 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, + 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, + 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, + 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, + 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, + 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, + 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, + 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, + 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, + 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, + 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, + 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, + 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, + 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, + 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, + 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, + 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, + 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, + 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, + 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, + 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, + 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, + 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, + 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, + 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, + 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, + 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, + 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, + 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, + 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, + 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, + 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, + 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, + 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, + 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, + 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, + 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, + 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, + 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, + 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, + 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, + 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, + 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, + 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, + 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, + 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, +}; +static const u32 Te3[256] = { + + 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, + 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, + 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, + 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, + 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, + 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, + 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, + 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, + 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, + 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, + 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, + 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, + 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, + 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, + 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, + 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, + 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, + 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, + 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, + 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, + 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, + 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, + 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, + 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, + 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, + 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, + 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, + 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, + 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, + 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, + 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, + 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, + 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, + 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, + 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, + 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, + 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, + 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, + 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, + 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, + 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, + 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, + 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, + 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, + 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, + 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, + 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, + 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, + 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, + 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, + 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, + 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, + 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, + 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, + 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, + 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, + 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, + 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, + 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, + 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, + 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, + 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, + 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, + 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, +}; +static const u32 Te4[256] = { + 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, + 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, + 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, + 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, + 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, + 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, + 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, + 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, + 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, + 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, + 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, + 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, + 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, + 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, + 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, + 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, + 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, + 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, + 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, + 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, + 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, + 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, + 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, + 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, + 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, + 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, + 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, + 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, + 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, + 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, + 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, + 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, + 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, + 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, + 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, + 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, + 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, + 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, + 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, + 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, + 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, + 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, + 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, + 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, + 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, + 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, + 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, + 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, + 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, + 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, + 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, + 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, + 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, + 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, + 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, + 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, + 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, + 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, + 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, + 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, + 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, + 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, + 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, + 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, +}; +static const u32 Td0[256] = { + 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, + 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, + 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, + 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, + 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, + 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, + 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, + 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, + 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, + 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, + 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, + 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, + 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, + 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, + 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, + 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, + 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, + 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, + 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, + 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, + 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, + 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, + 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, + 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, + 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, + 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, + 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, + 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, + 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, + 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, + 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, + 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, + 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, + 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, + 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, + 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, + 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, + 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, + 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, + 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, + 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, + 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, + 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, + 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, + 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, + 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, + 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, + 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, + 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, + 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, + 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, + 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, + 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, + 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, + 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, + 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, + 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, + 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, + 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, + 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, + 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, + 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, + 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, + 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, +}; +static const u32 Td1[256] = { + 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, + 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, + 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, + 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, + 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, + 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, + 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, + 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, + 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, + 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, + 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, + 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, + 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, + 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, + 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, + 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, + 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, + 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, + 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, + 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, + 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, + 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, + 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, + 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, + 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, + 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, + 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, + 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, + 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, + 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, + 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, + 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, + 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, + 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, + 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, + 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, + 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, + 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, + 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, + 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, + 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, + 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, + 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, + 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, + 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, + 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, + 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, + 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, + 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, + 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, + 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, + 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, + 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, + 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, + 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, + 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, + 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, + 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, + 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, + 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, + 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, + 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, + 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, + 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, +}; +static const u32 Td2[256] = { + 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, + 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, + 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, + 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, + 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, + 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, + 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, + 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, + 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, + 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, + 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, + 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, + 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, + 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, + 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, + 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, + 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, + 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, + 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, + 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, + + 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, + 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, + 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, + 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, + 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, + 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, + 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, + 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, + 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, + 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, + 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, + 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, + 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, + 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, + 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, + 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, + 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, + 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, + 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, + 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, + 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, + 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, + 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, + 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, + 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, + 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, + 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, + 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, + 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, + 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, + 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, + 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, + 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, + 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, + 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, + 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, + 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, + 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, + 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, + 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, + 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, + 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, + 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, + 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, +}; +static const u32 Td3[256] = { + 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, + 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, + 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, + 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, + 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, + 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, + 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, + 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, + 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, + 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, + 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, + 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, + 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, + 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, + 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, + 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, + 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, + 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, + 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, + 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, + 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, + 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, + 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, + 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, + 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, + 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, + 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, + 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, + 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, + 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, + 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, + 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, + 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, + 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, + 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, + 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, + 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, + 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, + 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, + 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, + 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, + 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, + 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, + 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, + 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, + 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, + 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, + 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, + 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, + 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, + 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, + 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, + 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, + 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, + 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, + 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, + 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, + 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, + 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, + 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, + 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, + 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, + 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, + 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, +}; +static const u32 Td4[256] = { + 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, + 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, + 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, + 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, + 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, + 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, + 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, + 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, + 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, + 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, + 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, + 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, + 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, + 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, + 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, + 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, + 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, + 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, + 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, + 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, + 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, + 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, + 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, + 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, + 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, + 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, + 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, + 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, + 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, + 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, + 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, + 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, + 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, + 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, + 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, + 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, + 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, + 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, + 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, + 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, + 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, + 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, + 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, + 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, + 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, + 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, + 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, + 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, + 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, + 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, + 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, + 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, + 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, + 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, + 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, + 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, + 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, + 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, + 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, + 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, + 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, + 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, + 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, + 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, +}; +static const u32 rcon[] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; + +#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) + +#ifdef _MSC_VER +#define GETU32(p) SWAP(*((u32 *)(p))) +#define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } +#else +#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) +#define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } +#endif + +/** + * Expand the cipher key into the encryption key schedule. + * + * @return the number of rounds for the given cipher key size. + */ +int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) { + int i = 0; + u32 temp; + + rk[0] = GETU32(cipherKey ); + rk[1] = GETU32(cipherKey + 4); + rk[2] = GETU32(cipherKey + 8); + rk[3] = GETU32(cipherKey + 12); + if (keyBits == 128) { + for (;;) { + temp = rk[3]; + rk[4] = rk[0] ^ + (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te4[(temp ) & 0xff] & 0x0000ff00) ^ + (Te4[(temp >> 24) ] & 0x000000ff) ^ + rcon[i]; + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + if (++i == 10) { + return 10; + } + rk += 4; + } + } + rk[4] = GETU32(cipherKey + 16); + rk[5] = GETU32(cipherKey + 20); + if (keyBits == 192) { + for (;;) { + temp = rk[ 5]; + rk[ 6] = rk[ 0] ^ + (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te4[(temp ) & 0xff] & 0x0000ff00) ^ + (Te4[(temp >> 24) ] & 0x000000ff) ^ + rcon[i]; + rk[ 7] = rk[ 1] ^ rk[ 6]; + rk[ 8] = rk[ 2] ^ rk[ 7]; + rk[ 9] = rk[ 3] ^ rk[ 8]; + if (++i == 8) { + return 12; + } + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + rk += 6; + } + } + rk[6] = GETU32(cipherKey + 24); + rk[7] = GETU32(cipherKey + 28); + if (keyBits == 256) { + for (;;) { + temp = rk[ 7]; + rk[ 8] = rk[ 0] ^ + (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te4[(temp ) & 0xff] & 0x0000ff00) ^ + (Te4[(temp >> 24) ] & 0x000000ff) ^ + rcon[i]; + rk[ 9] = rk[ 1] ^ rk[ 8]; + rk[10] = rk[ 2] ^ rk[ 9]; + rk[11] = rk[ 3] ^ rk[10]; + if (++i == 7) { + return 14; + } + temp = rk[11]; + rk[12] = rk[ 4] ^ + (Te4[(temp >> 24) ] & 0xff000000) ^ + (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(temp ) & 0xff] & 0x000000ff); + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + + rk += 8; + } + } + return 0; +} + +/** + * Expand the cipher key into the decryption key schedule. + * + * @return the number of rounds for the given cipher key size. + */ +int rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) { + int Nr, i, j; + u32 temp; + + /* expand the cipher key: */ + Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits); + /* invert the order of the round keys: */ + for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) { + temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; + temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; + temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; + temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; + } + /* apply the inverse MixColumn transform to all round keys but the first and the last: */ + for (i = 1; i < Nr; i++) { + rk += 4; + rk[0] = + Td0[Te4[(rk[0] >> 24) ] & 0xff] ^ + Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[0] ) & 0xff] & 0xff]; + rk[1] = + Td0[Te4[(rk[1] >> 24) ] & 0xff] ^ + Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[1] ) & 0xff] & 0xff]; + rk[2] = + Td0[Te4[(rk[2] >> 24) ] & 0xff] ^ + Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[2] ) & 0xff] & 0xff]; + rk[3] = + Td0[Te4[(rk[3] >> 24) ] & 0xff] ^ + Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[3] ) & 0xff] & 0xff]; + } + return Nr; +} + +void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]) { + u32 s0, s1, s2, s3, t0, t1, t2, t3; +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(pt ) ^ rk[0]; + s1 = GETU32(pt + 4) ^ rk[1]; + s2 = GETU32(pt + 8) ^ rk[2]; + s3 = GETU32(pt + 12) ^ rk[3]; +#ifdef FULL_UNROLL + /* round 1: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7]; + /* round 2: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11]; + /* round 3: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15]; + /* round 4: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19]; + /* round 5: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23]; + /* round 6: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27]; + /* round 7: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31]; + /* round 8: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35]; + /* round 9: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39]; + if (Nr > 10) { + /* round 10: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43]; + /* round 11: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47]; + if (Nr > 12) { + /* round 12: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51]; + /* round 13: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55]; + } + } + rk += Nr << 2; +#else /* !FULL_UNROLL */ + /* + * Nr - 1 full rounds: + */ + r = Nr >> 1; + for (;;) { + t0 = + Te0[(s0 >> 24) ] ^ + Te1[(s1 >> 16) & 0xff] ^ + Te2[(s2 >> 8) & 0xff] ^ + Te3[(s3 ) & 0xff] ^ + rk[4]; + t1 = + Te0[(s1 >> 24) ] ^ + Te1[(s2 >> 16) & 0xff] ^ + Te2[(s3 >> 8) & 0xff] ^ + Te3[(s0 ) & 0xff] ^ + rk[5]; + t2 = + Te0[(s2 >> 24) ] ^ + Te1[(s3 >> 16) & 0xff] ^ + Te2[(s0 >> 8) & 0xff] ^ + Te3[(s1 ) & 0xff] ^ + rk[6]; + t3 = + Te0[(s3 >> 24) ] ^ + Te1[(s0 >> 16) & 0xff] ^ + Te2[(s1 >> 8) & 0xff] ^ + Te3[(s2 ) & 0xff] ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + Te0[(t0 >> 24) ] ^ + Te1[(t1 >> 16) & 0xff] ^ + Te2[(t2 >> 8) & 0xff] ^ + Te3[(t3 ) & 0xff] ^ + rk[0]; + s1 = + Te0[(t1 >> 24) ] ^ + Te1[(t2 >> 16) & 0xff] ^ + Te2[(t3 >> 8) & 0xff] ^ + Te3[(t0 ) & 0xff] ^ + rk[1]; + s2 = + Te0[(t2 >> 24) ] ^ + Te1[(t3 >> 16) & 0xff] ^ + Te2[(t0 >> 8) & 0xff] ^ + Te3[(t1 ) & 0xff] ^ + rk[2]; + s3 = + Te0[(t3 >> 24) ] ^ + Te1[(t0 >> 16) & 0xff] ^ + Te2[(t1 >> 8) & 0xff] ^ + Te3[(t2 ) & 0xff] ^ + rk[3]; + } +#endif /* ?FULL_UNROLL */ + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (Te4[(t0 >> 24) ] & 0xff000000) ^ + (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t3 ) & 0xff] & 0x000000ff) ^ + rk[0]; + PUTU32(ct , s0); + s1 = + (Te4[(t1 >> 24) ] & 0xff000000) ^ + (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t0 ) & 0xff] & 0x000000ff) ^ + rk[1]; + PUTU32(ct + 4, s1); + s2 = + (Te4[(t2 >> 24) ] & 0xff000000) ^ + (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t1 ) & 0xff] & 0x000000ff) ^ + rk[2]; + PUTU32(ct + 8, s2); + s3 = + (Te4[(t3 >> 24) ] & 0xff000000) ^ + (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t2 ) & 0xff] & 0x000000ff) ^ + rk[3]; + PUTU32(ct + 12, s3); +} + +void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], u8 pt[16]) { + u32 s0, s1, s2, s3, t0, t1, t2, t3; +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(ct ) ^ rk[0]; + s1 = GETU32(ct + 4) ^ rk[1]; + s2 = GETU32(ct + 8) ^ rk[2]; + s3 = GETU32(ct + 12) ^ rk[3]; +#ifdef FULL_UNROLL + /* round 1: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7]; + /* round 2: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11]; + /* round 3: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15]; + /* round 4: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19]; + /* round 5: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23]; + /* round 6: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27]; + /* round 7: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31]; + /* round 8: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35]; + /* round 9: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39]; + if (Nr > 10) { + /* round 10: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43]; + /* round 11: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47]; + if (Nr > 12) { + /* round 12: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51]; + /* round 13: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55]; + } + } + rk += Nr << 2; +#else /* !FULL_UNROLL */ + /* + * Nr - 1 full rounds: + */ + r = Nr >> 1; + for (;;) { + t0 = + Td0[(s0 >> 24) ] ^ + Td1[(s3 >> 16) & 0xff] ^ + Td2[(s2 >> 8) & 0xff] ^ + Td3[(s1 ) & 0xff] ^ + rk[4]; + t1 = + Td0[(s1 >> 24) ] ^ + Td1[(s0 >> 16) & 0xff] ^ + Td2[(s3 >> 8) & 0xff] ^ + Td3[(s2 ) & 0xff] ^ + rk[5]; + t2 = + Td0[(s2 >> 24) ] ^ + Td1[(s1 >> 16) & 0xff] ^ + Td2[(s0 >> 8) & 0xff] ^ + Td3[(s3 ) & 0xff] ^ + rk[6]; + t3 = + Td0[(s3 >> 24) ] ^ + Td1[(s2 >> 16) & 0xff] ^ + Td2[(s1 >> 8) & 0xff] ^ + Td3[(s0 ) & 0xff] ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + Td0[(t0 >> 24) ] ^ + Td1[(t3 >> 16) & 0xff] ^ + Td2[(t2 >> 8) & 0xff] ^ + Td3[(t1 ) & 0xff] ^ + rk[0]; + s1 = + Td0[(t1 >> 24) ] ^ + Td1[(t0 >> 16) & 0xff] ^ + Td2[(t3 >> 8) & 0xff] ^ + Td3[(t2 ) & 0xff] ^ + rk[1]; + s2 = + Td0[(t2 >> 24) ] ^ + Td1[(t1 >> 16) & 0xff] ^ + Td2[(t0 >> 8) & 0xff] ^ + Td3[(t3 ) & 0xff] ^ + rk[2]; + s3 = + Td0[(t3 >> 24) ] ^ + Td1[(t2 >> 16) & 0xff] ^ + Td2[(t1 >> 8) & 0xff] ^ + Td3[(t0 ) & 0xff] ^ + rk[3]; + } +#endif /* ?FULL_UNROLL */ + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (Td4[(t0 >> 24) ] & 0xff000000) ^ + (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t1 ) & 0xff] & 0x000000ff) ^ + rk[0]; + PUTU32(pt , s0); + s1 = + (Td4[(t1 >> 24) ] & 0xff000000) ^ + (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t2 ) & 0xff] & 0x000000ff) ^ + rk[1]; + PUTU32(pt + 4, s1); + s2 = + (Td4[(t2 >> 24) ] & 0xff000000) ^ + (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t3 ) & 0xff] & 0x000000ff) ^ + rk[2]; + PUTU32(pt + 8, s2); + s3 = + (Td4[(t3 >> 24) ] & 0xff000000) ^ + (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t0 ) & 0xff] & 0x000000ff) ^ + rk[3]; + PUTU32(pt + 12, s3); +} + +#ifdef INTERMEDIATE_VALUE_KAT + +void rijndaelEncryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds) { + int r; + u32 s0, s1, s2, s3, t0, t1, t2, t3; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(block ) ^ rk[0]; + s1 = GETU32(block + 4) ^ rk[1]; + s2 = GETU32(block + 8) ^ rk[2]; + s3 = GETU32(block + 12) ^ rk[3]; + rk += 4; + + /* + * Nr - 1 full rounds: + */ + for (r = (rounds < Nr ? rounds : Nr - 1); r > 0; r--) { + t0 = + Te0[(s0 >> 24) ] ^ + Te1[(s1 >> 16) & 0xff] ^ + Te2[(s2 >> 8) & 0xff] ^ + Te3[(s3 ) & 0xff] ^ + rk[0]; + t1 = + Te0[(s1 >> 24) ] ^ + Te1[(s2 >> 16) & 0xff] ^ + Te2[(s3 >> 8) & 0xff] ^ + Te3[(s0 ) & 0xff] ^ + rk[1]; + t2 = + Te0[(s2 >> 24) ] ^ + Te1[(s3 >> 16) & 0xff] ^ + Te2[(s0 >> 8) & 0xff] ^ + Te3[(s1 ) & 0xff] ^ + rk[2]; + t3 = + Te0[(s3 >> 24) ] ^ + Te1[(s0 >> 16) & 0xff] ^ + Te2[(s1 >> 8) & 0xff] ^ + Te3[(s2 ) & 0xff] ^ + rk[3]; + + s0 = t0; + s1 = t1; + s2 = t2; + s3 = t3; + rk += 4; + + } + + /* + * apply last round and + * map cipher state to byte array block: + */ + if (rounds == Nr) { + t0 = + (Te4[(s0 >> 24) ] & 0xff000000) ^ + (Te4[(s1 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(s2 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(s3 ) & 0xff] & 0x000000ff) ^ + rk[0]; + t1 = + (Te4[(s1 >> 24) ] & 0xff000000) ^ + (Te4[(s2 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(s3 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(s0 ) & 0xff] & 0x000000ff) ^ + rk[1]; + t2 = + (Te4[(s2 >> 24) ] & 0xff000000) ^ + (Te4[(s3 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(s0 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(s1 ) & 0xff] & 0x000000ff) ^ + rk[2]; + t3 = + (Te4[(s3 >> 24) ] & 0xff000000) ^ + (Te4[(s0 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(s1 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(s2 ) & 0xff] & 0x000000ff) ^ + rk[3]; + + s0 = t0; + s1 = t1; + s2 = t2; + s3 = t3; + } + + PUTU32(block , s0); + PUTU32(block + 4, s1); + PUTU32(block + 8, s2); + PUTU32(block + 12, s3); +} + +void rijndaelDecryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds) { + int r; + u32 s0, s1, s2, s3, t0, t1, t2, t3; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(block ) ^ rk[0]; + s1 = GETU32(block + 4) ^ rk[1]; + s2 = GETU32(block + 8) ^ rk[2]; + s3 = GETU32(block + 12) ^ rk[3]; + rk += 4; + + /* + * Nr - 1 full rounds: + */ + for (r = (rounds < Nr ? rounds : Nr) - 1; r > 0; r--) { + t0 = + Td0[(s0 >> 24) ] ^ + Td1[(s3 >> 16) & 0xff] ^ + Td2[(s2 >> 8) & 0xff] ^ + Td3[(s1 ) & 0xff] ^ + rk[0]; + t1 = + Td0[(s1 >> 24) ] ^ + Td1[(s0 >> 16) & 0xff] ^ + Td2[(s3 >> 8) & 0xff] ^ + Td3[(s2 ) & 0xff] ^ + rk[1]; + t2 = + Td0[(s2 >> 24) ] ^ + Td1[(s1 >> 16) & 0xff] ^ + Td2[(s0 >> 8) & 0xff] ^ + Td3[(s3 ) & 0xff] ^ + rk[2]; + t3 = + Td0[(s3 >> 24) ] ^ + Td1[(s2 >> 16) & 0xff] ^ + Td2[(s1 >> 8) & 0xff] ^ + Td3[(s0 ) & 0xff] ^ + rk[3]; + + s0 = t0; + s1 = t1; + s2 = t2; + s3 = t3; + rk += 4; + + } + + /* + * complete the last round and + * map cipher state to byte array block: + */ + t0 = + (Td4[(s0 >> 24) ] & 0xff000000) ^ + (Td4[(s3 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(s2 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(s1 ) & 0xff] & 0x000000ff); + t1 = + (Td4[(s1 >> 24) ] & 0xff000000) ^ + (Td4[(s0 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(s3 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(s2 ) & 0xff] & 0x000000ff); + t2 = + (Td4[(s2 >> 24) ] & 0xff000000) ^ + (Td4[(s1 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(s0 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(s3 ) & 0xff] & 0x000000ff); + t3 = + (Td4[(s3 >> 24) ] & 0xff000000) ^ + (Td4[(s2 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(s1 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(s0 ) & 0xff] & 0x000000ff); + + if (rounds == Nr) { + t0 ^= rk[0]; + t1 ^= rk[1]; + t2 ^= rk[2]; + t3 ^= rk[3]; + } + + PUTU32(block , t0); + PUTU32(block + 4, t1); + PUTU32(block + 8, t2); + PUTU32(block + 12, t3); +} + +#endif /* INTERMEDIATE_VALUE_KAT */ diff --git a/thirdparty/crypto/rijndael-alg-fst.h b/thirdparty/crypto/rijndael-alg-fst.h new file mode 100644 index 0000000..f093e5b --- /dev/null +++ b/thirdparty/crypto/rijndael-alg-fst.h @@ -0,0 +1,47 @@ +/** + * rijndael-alg-fst.h + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __RIJNDAEL_ALG_FST_H +#define __RIJNDAEL_ALG_FST_H + +#define MAXKC (256/32) +#define MAXKB (256/8) +#define MAXNR 14 + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; + +int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits); +int rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits); +void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]); +void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], u8 pt[16]); + +#ifdef INTERMEDIATE_VALUE_KAT +void rijndaelEncryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds); +void rijndaelDecryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds); +#endif /* INTERMEDIATE_VALUE_KAT */ + +#endif /* __RIJNDAEL_ALG_FST_H */ diff --git a/thirdparty/crypto/sha256.cpp b/thirdparty/crypto/sha256.cpp new file mode 100644 index 0000000..f63fb2a --- /dev/null +++ b/thirdparty/crypto/sha256.cpp @@ -0,0 +1,576 @@ +// ////////////////////////////////////////////////////////// +// sha256.cpp +// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. +// see http://create.stephan-brumme.com/disclaimer.html +// +// Altered for use in Xenia. Licensed under zlib license when acquired. + +#include "sha256.h" + +// big endian architectures need #define __BYTE_ORDER __BIG_ENDIAN +#ifndef _MSC_VER +#include +#endif + +namespace sha256 { + +/// same as reset() +SHA256::SHA256() { reset(); } + +/// restart +void SHA256::reset() { + m_numBytes = 0; + m_bufferSize = 0; + + // according to RFC 1321 + m_hash[0] = 0x6a09e667; + m_hash[1] = 0xbb67ae85; + m_hash[2] = 0x3c6ef372; + m_hash[3] = 0xa54ff53a; + m_hash[4] = 0x510e527f; + m_hash[5] = 0x9b05688c; + m_hash[6] = 0x1f83d9ab; + m_hash[7] = 0x5be0cd19; +} + +namespace { +inline uint32_t rotate(uint32_t a, uint32_t c) { + return (a >> c) | (a << (32 - c)); +} + +inline uint32_t swap(uint32_t x) { +#if defined(__GNUC__) || defined(__clang__) + return __builtin_bswap32(x); +#endif +#ifdef MSC_VER + return _byteswap_ulong(x); +#endif + + return (x >> 24) | ((x >> 8) & 0x0000FF00) | ((x << 8) & 0x00FF0000) | + (x << 24); +} + +// mix functions for processBlock() +inline uint32_t f1(uint32_t e, uint32_t f, uint32_t g) { + uint32_t term1 = rotate(e, 6) ^ rotate(e, 11) ^ rotate(e, 25); + uint32_t term2 = (e & f) ^ (~e & g); //(g ^ (e & (f ^ g))) + return term1 + term2; +} + +inline uint32_t f2(uint32_t a, uint32_t b, uint32_t c) { + uint32_t term1 = rotate(a, 2) ^ rotate(a, 13) ^ rotate(a, 22); + uint32_t term2 = ((a | b) & c) | (a & b); //(a & (b ^ c)) ^ (b & c); + return term1 + term2; +} +} + +/// process 64 bytes +void SHA256::processBlock(const void* data) { + // get last hash + uint32_t a = m_hash[0]; + uint32_t b = m_hash[1]; + uint32_t c = m_hash[2]; + uint32_t d = m_hash[3]; + uint32_t e = m_hash[4]; + uint32_t f = m_hash[5]; + uint32_t g = m_hash[6]; + uint32_t h = m_hash[7]; + + // data represented as 16x 32-bit words + const uint32_t* input = (uint32_t*)data; + // convert to big endian + uint32_t words[64]; + int i; + for (i = 0; i < 16; i++) +#if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && \ + (__BYTE_ORDER == __BIG_ENDIAN) + words[i] = input[i]; +#else + words[i] = swap(input[i]); +#endif + + uint32_t x, y; // temporaries + + // first round + x = h + f1(e, f, g) + 0x428a2f98 + words[0]; + y = f2(a, b, c); + d += x; + h = x + y; + x = g + f1(d, e, f) + 0x71374491 + words[1]; + y = f2(h, a, b); + c += x; + g = x + y; + x = f + f1(c, d, e) + 0xb5c0fbcf + words[2]; + y = f2(g, h, a); + b += x; + f = x + y; + x = e + f1(b, c, d) + 0xe9b5dba5 + words[3]; + y = f2(f, g, h); + a += x; + e = x + y; + x = d + f1(a, b, c) + 0x3956c25b + words[4]; + y = f2(e, f, g); + h += x; + d = x + y; + x = c + f1(h, a, b) + 0x59f111f1 + words[5]; + y = f2(d, e, f); + g += x; + c = x + y; + x = b + f1(g, h, a) + 0x923f82a4 + words[6]; + y = f2(c, d, e); + f += x; + b = x + y; + x = a + f1(f, g, h) + 0xab1c5ed5 + words[7]; + y = f2(b, c, d); + e += x; + a = x + y; + + // secound round + x = h + f1(e, f, g) + 0xd807aa98 + words[8]; + y = f2(a, b, c); + d += x; + h = x + y; + x = g + f1(d, e, f) + 0x12835b01 + words[9]; + y = f2(h, a, b); + c += x; + g = x + y; + x = f + f1(c, d, e) + 0x243185be + words[10]; + y = f2(g, h, a); + b += x; + f = x + y; + x = e + f1(b, c, d) + 0x550c7dc3 + words[11]; + y = f2(f, g, h); + a += x; + e = x + y; + x = d + f1(a, b, c) + 0x72be5d74 + words[12]; + y = f2(e, f, g); + h += x; + d = x + y; + x = c + f1(h, a, b) + 0x80deb1fe + words[13]; + y = f2(d, e, f); + g += x; + c = x + y; + x = b + f1(g, h, a) + 0x9bdc06a7 + words[14]; + y = f2(c, d, e); + f += x; + b = x + y; + x = a + f1(f, g, h) + 0xc19bf174 + words[15]; + y = f2(b, c, d); + e += x; + a = x + y; + + // extend to 24 words + for (; i < 24; i++) + words[i] = words[i - 16] + + (rotate(words[i - 15], 7) ^ rotate(words[i - 15], 18) ^ + (words[i - 15] >> 3)) + + words[i - 7] + (rotate(words[i - 2], 17) ^ + rotate(words[i - 2], 19) ^ (words[i - 2] >> 10)); + + // third round + x = h + f1(e, f, g) + 0xe49b69c1 + words[16]; + y = f2(a, b, c); + d += x; + h = x + y; + x = g + f1(d, e, f) + 0xefbe4786 + words[17]; + y = f2(h, a, b); + c += x; + g = x + y; + x = f + f1(c, d, e) + 0x0fc19dc6 + words[18]; + y = f2(g, h, a); + b += x; + f = x + y; + x = e + f1(b, c, d) + 0x240ca1cc + words[19]; + y = f2(f, g, h); + a += x; + e = x + y; + x = d + f1(a, b, c) + 0x2de92c6f + words[20]; + y = f2(e, f, g); + h += x; + d = x + y; + x = c + f1(h, a, b) + 0x4a7484aa + words[21]; + y = f2(d, e, f); + g += x; + c = x + y; + x = b + f1(g, h, a) + 0x5cb0a9dc + words[22]; + y = f2(c, d, e); + f += x; + b = x + y; + x = a + f1(f, g, h) + 0x76f988da + words[23]; + y = f2(b, c, d); + e += x; + a = x + y; + + // extend to 32 words + for (; i < 32; i++) + words[i] = words[i - 16] + + (rotate(words[i - 15], 7) ^ rotate(words[i - 15], 18) ^ + (words[i - 15] >> 3)) + + words[i - 7] + (rotate(words[i - 2], 17) ^ + rotate(words[i - 2], 19) ^ (words[i - 2] >> 10)); + + // fourth round + x = h + f1(e, f, g) + 0x983e5152 + words[24]; + y = f2(a, b, c); + d += x; + h = x + y; + x = g + f1(d, e, f) + 0xa831c66d + words[25]; + y = f2(h, a, b); + c += x; + g = x + y; + x = f + f1(c, d, e) + 0xb00327c8 + words[26]; + y = f2(g, h, a); + b += x; + f = x + y; + x = e + f1(b, c, d) + 0xbf597fc7 + words[27]; + y = f2(f, g, h); + a += x; + e = x + y; + x = d + f1(a, b, c) + 0xc6e00bf3 + words[28]; + y = f2(e, f, g); + h += x; + d = x + y; + x = c + f1(h, a, b) + 0xd5a79147 + words[29]; + y = f2(d, e, f); + g += x; + c = x + y; + x = b + f1(g, h, a) + 0x06ca6351 + words[30]; + y = f2(c, d, e); + f += x; + b = x + y; + x = a + f1(f, g, h) + 0x14292967 + words[31]; + y = f2(b, c, d); + e += x; + a = x + y; + + // extend to 40 words + for (; i < 40; i++) + words[i] = words[i - 16] + + (rotate(words[i - 15], 7) ^ rotate(words[i - 15], 18) ^ + (words[i - 15] >> 3)) + + words[i - 7] + (rotate(words[i - 2], 17) ^ + rotate(words[i - 2], 19) ^ (words[i - 2] >> 10)); + + // fifth round + x = h + f1(e, f, g) + 0x27b70a85 + words[32]; + y = f2(a, b, c); + d += x; + h = x + y; + x = g + f1(d, e, f) + 0x2e1b2138 + words[33]; + y = f2(h, a, b); + c += x; + g = x + y; + x = f + f1(c, d, e) + 0x4d2c6dfc + words[34]; + y = f2(g, h, a); + b += x; + f = x + y; + x = e + f1(b, c, d) + 0x53380d13 + words[35]; + y = f2(f, g, h); + a += x; + e = x + y; + x = d + f1(a, b, c) + 0x650a7354 + words[36]; + y = f2(e, f, g); + h += x; + d = x + y; + x = c + f1(h, a, b) + 0x766a0abb + words[37]; + y = f2(d, e, f); + g += x; + c = x + y; + x = b + f1(g, h, a) + 0x81c2c92e + words[38]; + y = f2(c, d, e); + f += x; + b = x + y; + x = a + f1(f, g, h) + 0x92722c85 + words[39]; + y = f2(b, c, d); + e += x; + a = x + y; + + // extend to 48 words + for (; i < 48; i++) + words[i] = words[i - 16] + + (rotate(words[i - 15], 7) ^ rotate(words[i - 15], 18) ^ + (words[i - 15] >> 3)) + + words[i - 7] + (rotate(words[i - 2], 17) ^ + rotate(words[i - 2], 19) ^ (words[i - 2] >> 10)); + + // sixth round + x = h + f1(e, f, g) + 0xa2bfe8a1 + words[40]; + y = f2(a, b, c); + d += x; + h = x + y; + x = g + f1(d, e, f) + 0xa81a664b + words[41]; + y = f2(h, a, b); + c += x; + g = x + y; + x = f + f1(c, d, e) + 0xc24b8b70 + words[42]; + y = f2(g, h, a); + b += x; + f = x + y; + x = e + f1(b, c, d) + 0xc76c51a3 + words[43]; + y = f2(f, g, h); + a += x; + e = x + y; + x = d + f1(a, b, c) + 0xd192e819 + words[44]; + y = f2(e, f, g); + h += x; + d = x + y; + x = c + f1(h, a, b) + 0xd6990624 + words[45]; + y = f2(d, e, f); + g += x; + c = x + y; + x = b + f1(g, h, a) + 0xf40e3585 + words[46]; + y = f2(c, d, e); + f += x; + b = x + y; + x = a + f1(f, g, h) + 0x106aa070 + words[47]; + y = f2(b, c, d); + e += x; + a = x + y; + + // extend to 56 words + for (; i < 56; i++) + words[i] = words[i - 16] + + (rotate(words[i - 15], 7) ^ rotate(words[i - 15], 18) ^ + (words[i - 15] >> 3)) + + words[i - 7] + (rotate(words[i - 2], 17) ^ + rotate(words[i - 2], 19) ^ (words[i - 2] >> 10)); + + // seventh round + x = h + f1(e, f, g) + 0x19a4c116 + words[48]; + y = f2(a, b, c); + d += x; + h = x + y; + x = g + f1(d, e, f) + 0x1e376c08 + words[49]; + y = f2(h, a, b); + c += x; + g = x + y; + x = f + f1(c, d, e) + 0x2748774c + words[50]; + y = f2(g, h, a); + b += x; + f = x + y; + x = e + f1(b, c, d) + 0x34b0bcb5 + words[51]; + y = f2(f, g, h); + a += x; + e = x + y; + x = d + f1(a, b, c) + 0x391c0cb3 + words[52]; + y = f2(e, f, g); + h += x; + d = x + y; + x = c + f1(h, a, b) + 0x4ed8aa4a + words[53]; + y = f2(d, e, f); + g += x; + c = x + y; + x = b + f1(g, h, a) + 0x5b9cca4f + words[54]; + y = f2(c, d, e); + f += x; + b = x + y; + x = a + f1(f, g, h) + 0x682e6ff3 + words[55]; + y = f2(b, c, d); + e += x; + a = x + y; + + // extend to 64 words + for (; i < 64; i++) + words[i] = words[i - 16] + + (rotate(words[i - 15], 7) ^ rotate(words[i - 15], 18) ^ + (words[i - 15] >> 3)) + + words[i - 7] + (rotate(words[i - 2], 17) ^ + rotate(words[i - 2], 19) ^ (words[i - 2] >> 10)); + + // eigth round + x = h + f1(e, f, g) + 0x748f82ee + words[56]; + y = f2(a, b, c); + d += x; + h = x + y; + x = g + f1(d, e, f) + 0x78a5636f + words[57]; + y = f2(h, a, b); + c += x; + g = x + y; + x = f + f1(c, d, e) + 0x84c87814 + words[58]; + y = f2(g, h, a); + b += x; + f = x + y; + x = e + f1(b, c, d) + 0x8cc70208 + words[59]; + y = f2(f, g, h); + a += x; + e = x + y; + x = d + f1(a, b, c) + 0x90befffa + words[60]; + y = f2(e, f, g); + h += x; + d = x + y; + x = c + f1(h, a, b) + 0xa4506ceb + words[61]; + y = f2(d, e, f); + g += x; + c = x + y; + x = b + f1(g, h, a) + 0xbef9a3f7 + words[62]; + y = f2(c, d, e); + f += x; + b = x + y; + x = a + f1(f, g, h) + 0xc67178f2 + words[63]; + y = f2(b, c, d); + e += x; + a = x + y; + + // update hash + m_hash[0] += a; + m_hash[1] += b; + m_hash[2] += c; + m_hash[3] += d; + m_hash[4] += e; + m_hash[5] += f; + m_hash[6] += g; + m_hash[7] += h; +} + +/// add arbitrary number of bytes +void SHA256::add(const void* data, size_t numBytes) { + const uint8_t* current = (const uint8_t*)data; + + if (m_bufferSize > 0) { + while (numBytes > 0 && m_bufferSize < BlockSize) { + m_buffer[m_bufferSize++] = *current++; + numBytes--; + } + } + + // full buffer + if (m_bufferSize == BlockSize) { + processBlock(m_buffer); + m_numBytes += BlockSize; + m_bufferSize = 0; + } + + // no more data ? + if (numBytes == 0) return; + + // process full blocks + while (numBytes >= BlockSize) { + processBlock(current); + current += BlockSize; + m_numBytes += BlockSize; + numBytes -= BlockSize; + } + + // keep remaining bytes in buffer + while (numBytes > 0) { + m_buffer[m_bufferSize++] = *current++; + numBytes--; + } +} + +/// process final block, less than 64 bytes +void SHA256::processBuffer() { + // the input bytes are considered as bits strings, where the first bit is the + // most significant bit of the byte + + // - append "1" bit to message + // - append "0" bits until message length in bit mod 512 is 448 + // - append length as 64 bit integer + + // number of bits + size_t paddedLength = m_bufferSize * 8; + + // plus one bit set to 1 (always appended) + paddedLength++; + + // number of bits must be (numBits % 512) = 448 + size_t lower11Bits = paddedLength & 511; + if (lower11Bits <= 448) + paddedLength += 448 - lower11Bits; + else + paddedLength += 512 + 448 - lower11Bits; + // convert from bits to bytes + paddedLength /= 8; + + // only needed if additional data flows over into a second block + unsigned char extra[BlockSize]; + + // append a "1" bit, 128 => binary 10000000 + if (m_bufferSize < BlockSize) + m_buffer[m_bufferSize] = 128; + else + extra[0] = 128; + + size_t i; + for (i = m_bufferSize + 1; i < BlockSize; i++) m_buffer[i] = 0; + for (; i < paddedLength; i++) extra[i - BlockSize] = 0; + + // add message length in bits as 64 bit number + uint64_t msgBits = 8 * (m_numBytes + m_bufferSize); + // find right position + unsigned char* addLength; + if (paddedLength < BlockSize) + addLength = m_buffer + paddedLength; + else + addLength = extra + paddedLength - BlockSize; + + // must be big endian + *addLength++ = (unsigned char)((msgBits >> 56) & 0xFF); + *addLength++ = (unsigned char)((msgBits >> 48) & 0xFF); + *addLength++ = (unsigned char)((msgBits >> 40) & 0xFF); + *addLength++ = (unsigned char)((msgBits >> 32) & 0xFF); + *addLength++ = (unsigned char)((msgBits >> 24) & 0xFF); + *addLength++ = (unsigned char)((msgBits >> 16) & 0xFF); + *addLength++ = (unsigned char)((msgBits >> 8) & 0xFF); + *addLength = (unsigned char)(msgBits & 0xFF); + + // process blocks + processBlock(m_buffer); + // flowed over into a second block ? + if (paddedLength > BlockSize) processBlock(extra); +} + +/// return latest hash as 64 hex characters +std::string SHA256::getHash() { + // compute hash (as raw bytes) + unsigned char rawHash[HashBytes]; + getHash(rawHash); + + // convert to hex string + std::string result; + result.reserve(2 * HashBytes); + for (int i = 0; i < HashBytes; i++) { + static const char dec2hex[16 + 1] = "0123456789abcdef"; + result += dec2hex[(rawHash[i] >> 4) & 15]; + result += dec2hex[rawHash[i] & 15]; + } + + return result; +} + +/// return latest hash as bytes +void SHA256::getHash(unsigned char buffer[SHA256::HashBytes]) { + // save old hash if buffer is partially filled + uint32_t oldHash[HashValues]; + for (int i = 0; i < HashValues; i++) oldHash[i] = m_hash[i]; + + // process remaining bytes + processBuffer(); + + unsigned char* current = buffer; + for (int i = 0; i < HashValues; i++) { + *current++ = (m_hash[i] >> 24) & 0xFF; + *current++ = (m_hash[i] >> 16) & 0xFF; + *current++ = (m_hash[i] >> 8) & 0xFF; + *current++ = m_hash[i] & 0xFF; + + // restore old hash + m_hash[i] = oldHash[i]; + } +} + +/// compute SHA256 of a memory block +std::string SHA256::operator()(const void* data, size_t numBytes) { + reset(); + add(data, numBytes); + return getHash(); +} + +/// compute SHA256 of a string, excluding final zero +std::string SHA256::operator()(const std::string& text) { + reset(); + add(text.c_str(), text.size()); + return getHash(); +} + +} \ No newline at end of file diff --git a/thirdparty/crypto/sha256.h b/thirdparty/crypto/sha256.h new file mode 100644 index 0000000..e8aeae2 --- /dev/null +++ b/thirdparty/crypto/sha256.h @@ -0,0 +1,79 @@ +// ////////////////////////////////////////////////////////// +// sha256.h +// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. +// see http://create.stephan-brumme.com/disclaimer.html +// +// Altered for use in Xenia. Licensed under zlib license when acquired. + +#pragma once + +#include +#include + +namespace sha256 { + +/// compute SHA256 hash +/** Usage: + SHA256 sha256; + std::string myHash = sha256("Hello World"); // std::string + std::string myHash2 = sha256("How are you", 11); // arbitrary data, 11 bytes + + // or in a streaming fashion: + + SHA256 sha256; + while (more data available) + sha256.add(pointer to fresh data, number of new bytes); + std::string myHash3 = sha256.getHash(); + */ +class SHA256 { + public: + /// split into 64 byte blocks (=> 512 bits), hash is 32 bytes long + enum { BlockSize = 512 / 8, HashBytes = 32 }; + + /// same as reset() + SHA256(); + + /// compute SHA256 of a memory block + std::string operator()(const void* data, size_t numBytes); + /// compute SHA256 of a string, excluding final zero + std::string operator()(const std::string& text); + + /// add arbitrary number of bytes + void add(const void* data, size_t numBytes); + + /// return latest hash as 64 hex characters + std::string getHash(); + /// return latest hash as bytes + void getHash(unsigned char buffer[HashBytes]); + + uint8_t* getBuffer() { return m_buffer; } + uint32_t* getHashValues() { return m_hash; } + + size_t getTotalSize() const { return m_numBytes + m_bufferSize; } + void setTotalSize(size_t size) { + m_bufferSize = size & (BlockSize - 1); + m_numBytes = size & ~(BlockSize - 1); + } + + /// restart + void reset(); + + private: + /// process 64 bytes + void processBlock(const void* data); + /// process everything left in the internal buffer + void processBuffer(); + + /// size of processed data in bytes + uint64_t m_numBytes; + /// valid bytes in m_buffer + size_t m_bufferSize; + /// bytes not processed yet + uint8_t m_buffer[BlockSize]; + + enum { HashValues = HashBytes / 4 }; + /// hash, stored as integers + uint32_t m_hash[HashValues]; +}; + +}; // namespace sha256 \ No newline at end of file diff --git a/thirdparty/disasm/CMakeLists.txt b/thirdparty/disasm/CMakeLists.txt new file mode 100644 index 0000000..ed5ef17 --- /dev/null +++ b/thirdparty/disasm/CMakeLists.txt @@ -0,0 +1,6 @@ +project("disasm") + +add_library(disasm "ppc-dis.c" "disasm.c" "ppc.h") +target_include_directories(disasm PUBLIC + $ + $) diff --git a/thirdparty/disasm/dis-asm.h b/thirdparty/disasm/dis-asm.h new file mode 100644 index 0000000..f9705ff --- /dev/null +++ b/thirdparty/disasm/dis-asm.h @@ -0,0 +1,550 @@ +/* Interface between the opcode library and its callers. + Written by Cygnus Support, 1993. + + The opcode library (libopcodes.a) provides instruction decoders for + a large variety of instruction sets, callable with an identical + interface, for making instruction-processing programs more independent + of the instruction set being processed. */ + +#ifndef DIS_ASM_H +#define DIS_ASM_H + +#if defined __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + +#if defined __GNUC__ +# if (__GNUC__ < 4) || \ + defined(__GNUC_MINOR__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 4) + /* gcc versions before 4.4.x don't support gnu_printf, so use printf. */ +# define GCC_ATTR __attribute__((__unused__, format(printf, 1, 2))) +# define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m))) +# else + /* Use gnu_printf when supported (qemu uses standard format strings). */ +# define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2))) +# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m))) +# endif +#else +#define GCC_ATTR /**/ +#define GCC_FMT_ATTR(n, m) +#endif + +typedef int (*fprintf_function)(FILE* f, const char* fmt, ...) GCC_FMT_ATTR(2, 3); + +typedef void *PTR; +typedef uint64_t bfd_vma; +typedef int64_t bfd_signed_vma; +typedef uint8_t bfd_byte; +#define sprintf_vma(s,x) sprintf (s, "%0" PRIx64, x) +#define snprintf_vma(s,ss,x) snprintf (s, ss, "%0" PRIx64, x) + +#define BFD64 + +enum bfd_flavour { + bfd_target_unknown_flavour, + bfd_target_aout_flavour, + bfd_target_coff_flavour, + bfd_target_ecoff_flavour, + bfd_target_elf_flavour, + bfd_target_ieee_flavour, + bfd_target_nlm_flavour, + bfd_target_oasys_flavour, + bfd_target_tekhex_flavour, + bfd_target_srec_flavour, + bfd_target_ihex_flavour, + bfd_target_som_flavour, + bfd_target_os9k_flavour, + bfd_target_versados_flavour, + bfd_target_msdos_flavour, + bfd_target_evax_flavour +}; + +enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN }; + +enum bfd_architecture +{ + bfd_arch_unknown, /* File arch not known */ + bfd_arch_obscure, /* Arch known, not one of these */ + bfd_arch_m68k, /* Motorola 68xxx */ +#define bfd_mach_m68000 1 +#define bfd_mach_m68008 2 +#define bfd_mach_m68010 3 +#define bfd_mach_m68020 4 +#define bfd_mach_m68030 5 +#define bfd_mach_m68040 6 +#define bfd_mach_m68060 7 +#define bfd_mach_cpu32 8 +#define bfd_mach_mcf5200 9 +#define bfd_mach_mcf5206e 10 +#define bfd_mach_mcf5307 11 +#define bfd_mach_mcf5407 12 +#define bfd_mach_mcf528x 13 +#define bfd_mach_mcfv4e 14 +#define bfd_mach_mcf521x 15 +#define bfd_mach_mcf5249 16 +#define bfd_mach_mcf547x 17 +#define bfd_mach_mcf548x 18 + bfd_arch_vax, /* DEC Vax */ + bfd_arch_i960, /* Intel 960 */ + /* The order of the following is important. + lower number indicates a machine type that + only accepts a subset of the instructions + available to machines with higher numbers. + The exception is the "ca", which is + incompatible with all other machines except + "core". */ + +#define bfd_mach_i960_core 1 +#define bfd_mach_i960_ka_sa 2 +#define bfd_mach_i960_kb_sb 3 +#define bfd_mach_i960_mc 4 +#define bfd_mach_i960_xa 5 +#define bfd_mach_i960_ca 6 +#define bfd_mach_i960_jx 7 +#define bfd_mach_i960_hx 8 + + bfd_arch_a29k, /* AMD 29000 */ + bfd_arch_sparc, /* SPARC */ +#define bfd_mach_sparc 1 +/* The difference between v8plus and v9 is that v9 is a true 64 bit env. */ +#define bfd_mach_sparc_sparclet 2 +#define bfd_mach_sparc_sparclite 3 +#define bfd_mach_sparc_v8plus 4 +#define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns. */ +#define bfd_mach_sparc_sparclite_le 6 +#define bfd_mach_sparc_v9 7 +#define bfd_mach_sparc_v9a 8 /* with ultrasparc add'ns. */ +#define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */ +#define bfd_mach_sparc_v9b 10 /* with cheetah add'ns. */ +/* Nonzero if MACH has the v9 instruction set. */ +#define bfd_mach_sparc_v9_p(mach) \ + ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9b \ + && (mach) != bfd_mach_sparc_sparclite_le) + bfd_arch_mips, /* MIPS Rxxxx */ +#define bfd_mach_mips3000 3000 +#define bfd_mach_mips3900 3900 +#define bfd_mach_mips4000 4000 +#define bfd_mach_mips4010 4010 +#define bfd_mach_mips4100 4100 +#define bfd_mach_mips4300 4300 +#define bfd_mach_mips4400 4400 +#define bfd_mach_mips4600 4600 +#define bfd_mach_mips4650 4650 +#define bfd_mach_mips5000 5000 +#define bfd_mach_mips6000 6000 +#define bfd_mach_mips8000 8000 +#define bfd_mach_mips10000 10000 +#define bfd_mach_mips16 16 + bfd_arch_i386, /* Intel 386 */ +#define bfd_mach_i386_i386 0 +#define bfd_mach_i386_i8086 1 +#define bfd_mach_i386_i386_intel_syntax 2 +#define bfd_mach_x86_64 3 +#define bfd_mach_x86_64_intel_syntax 4 + bfd_arch_we32k, /* AT&T WE32xxx */ + bfd_arch_tahoe, /* CCI/Harris Tahoe */ + bfd_arch_i860, /* Intel 860 */ + bfd_arch_romp, /* IBM ROMP PC/RT */ + bfd_arch_alliant, /* Alliant */ + bfd_arch_convex, /* Convex */ + bfd_arch_m88k, /* Motorola 88xxx */ + bfd_arch_pyramid, /* Pyramid Technology */ + bfd_arch_h8300, /* Hitachi H8/300 */ +#define bfd_mach_h8300 1 +#define bfd_mach_h8300h 2 +#define bfd_mach_h8300s 3 + bfd_arch_powerpc, /* PowerPC */ +#define bfd_mach_ppc 0 +#define bfd_mach_ppc64 1 +#define bfd_mach_ppc_403 403 +#define bfd_mach_ppc_403gc 4030 +#define bfd_mach_ppc_e500 500 +#define bfd_mach_ppc_505 505 +#define bfd_mach_ppc_601 601 +#define bfd_mach_ppc_602 602 +#define bfd_mach_ppc_603 603 +#define bfd_mach_ppc_ec603e 6031 +#define bfd_mach_ppc_604 604 +#define bfd_mach_ppc_620 620 +#define bfd_mach_ppc_630 630 +#define bfd_mach_ppc_750 750 +#define bfd_mach_ppc_860 860 +#define bfd_mach_ppc_a35 35 +#define bfd_mach_ppc_rs64ii 642 +#define bfd_mach_ppc_rs64iii 643 +#define bfd_mach_ppc_7400 7400 + bfd_arch_rs6000, /* IBM RS/6000 */ + bfd_arch_hppa, /* HP PA RISC */ +#define bfd_mach_hppa10 10 +#define bfd_mach_hppa11 11 +#define bfd_mach_hppa20 20 +#define bfd_mach_hppa20w 25 + bfd_arch_d10v, /* Mitsubishi D10V */ + bfd_arch_z8k, /* Zilog Z8000 */ +#define bfd_mach_z8001 1 +#define bfd_mach_z8002 2 + bfd_arch_h8500, /* Hitachi H8/500 */ + bfd_arch_sh, /* Hitachi SH */ +#define bfd_mach_sh 1 +#define bfd_mach_sh2 0x20 +#define bfd_mach_sh_dsp 0x2d +#define bfd_mach_sh2a 0x2a +#define bfd_mach_sh2a_nofpu 0x2b +#define bfd_mach_sh2e 0x2e +#define bfd_mach_sh3 0x30 +#define bfd_mach_sh3_nommu 0x31 +#define bfd_mach_sh3_dsp 0x3d +#define bfd_mach_sh3e 0x3e +#define bfd_mach_sh4 0x40 +#define bfd_mach_sh4_nofpu 0x41 +#define bfd_mach_sh4_nommu_nofpu 0x42 +#define bfd_mach_sh4a 0x4a +#define bfd_mach_sh4a_nofpu 0x4b +#define bfd_mach_sh4al_dsp 0x4d +#define bfd_mach_sh5 0x50 + bfd_arch_alpha, /* Dec Alpha */ +#define bfd_mach_alpha 1 +#define bfd_mach_alpha_ev4 0x10 +#define bfd_mach_alpha_ev5 0x20 +#define bfd_mach_alpha_ev6 0x30 + bfd_arch_arm, /* Advanced Risc Machines ARM */ +#define bfd_mach_arm_unknown 0 +#define bfd_mach_arm_2 1 +#define bfd_mach_arm_2a 2 +#define bfd_mach_arm_3 3 +#define bfd_mach_arm_3M 4 +#define bfd_mach_arm_4 5 +#define bfd_mach_arm_4T 6 +#define bfd_mach_arm_5 7 +#define bfd_mach_arm_5T 8 +#define bfd_mach_arm_5TE 9 +#define bfd_mach_arm_XScale 10 +#define bfd_mach_arm_ep9312 11 +#define bfd_mach_arm_iWMMXt 12 +#define bfd_mach_arm_iWMMXt2 13 + bfd_arch_ns32k, /* National Semiconductors ns32000 */ + bfd_arch_w65, /* WDC 65816 */ + bfd_arch_tic30, /* Texas Instruments TMS320C30 */ + bfd_arch_v850, /* NEC V850 */ +#define bfd_mach_v850 0 + bfd_arch_arc, /* Argonaut RISC Core */ +#define bfd_mach_arc_base 0 + bfd_arch_m32r, /* Mitsubishi M32R/D */ +#define bfd_mach_m32r 0 /* backwards compatibility */ + bfd_arch_mn10200, /* Matsushita MN10200 */ + bfd_arch_mn10300, /* Matsushita MN10300 */ + bfd_arch_cris, /* Axis CRIS */ +#define bfd_mach_cris_v0_v10 255 +#define bfd_mach_cris_v32 32 +#define bfd_mach_cris_v10_v32 1032 + bfd_arch_microblaze, /* Xilinx MicroBlaze. */ + bfd_arch_ia64, /* HP/Intel ia64 */ +#define bfd_mach_ia64_elf64 64 +#define bfd_mach_ia64_elf32 32 + bfd_arch_last + }; +#define bfd_mach_s390_31 31 +#define bfd_mach_s390_64 64 + +typedef struct symbol_cache_entry +{ + const char *name; + union + { + PTR p; + bfd_vma i; + } udata; +} asymbol; + +enum dis_insn_type { + dis_noninsn, /* Not a valid instruction */ + dis_nonbranch, /* Not a branch instruction */ + dis_branch, /* Unconditional branch */ + dis_condbranch, /* Conditional branch */ + dis_jsr, /* Jump to subroutine */ + dis_condjsr, /* Conditional jump to subroutine */ + dis_dref, /* Data reference instruction */ + dis_dref2 /* Two data references in instruction */ +}; + +/* This struct is passed into the instruction decoding routine, + and is passed back out into each callback. The various fields are used + for conveying information from your main routine into your callbacks, + for passing information into the instruction decoders (such as the + addresses of the callback functions), or for passing information + back from the instruction decoders to their callers. + + It must be initialized before it is first passed; this can be done + by hand, or using one of the initialization macros below. */ + +typedef struct disassemble_info { + fprintf_function fprintf_func; + FILE *stream; + PTR application_data; + + /* Target description. We could replace this with a pointer to the bfd, + but that would require one. There currently isn't any such requirement + so to avoid introducing one we record these explicitly. */ + /* The bfd_flavour. This can be bfd_target_unknown_flavour. */ + enum bfd_flavour flavour; + /* The bfd_arch value. */ + enum bfd_architecture arch; + /* The bfd_mach value. */ + unsigned long mach; + /* Endianness (for bi-endian cpus). Mono-endian cpus can ignore this. */ + enum bfd_endian endian; + + /* An array of pointers to symbols either at the location being disassembled + or at the start of the function being disassembled. The array is sorted + so that the first symbol is intended to be the one used. The others are + present for any misc. purposes. This is not set reliably, but if it is + not NULL, it is correct. */ + asymbol **symbols; + /* Number of symbols in array. */ + int num_symbols; + + /* For use by the disassembler. + The top 16 bits are reserved for public use (and are documented here). + The bottom 16 bits are for the internal use of the disassembler. */ + unsigned long flags; +#define INSN_HAS_RELOC 0x80000000 + PTR private_data; + + /* Function used to get bytes to disassemble. MEMADDR is the + address of the stuff to be disassembled, MYADDR is the address to + put the bytes in, and LENGTH is the number of bytes to read. + INFO is a pointer to this struct. + Returns an errno value or 0 for success. */ + int (*read_memory_func) + (bfd_vma memaddr, bfd_byte *myaddr, int length, + struct disassemble_info *info); + + /* Function which should be called if we get an error that we can't + recover from. STATUS is the errno value from read_memory_func and + MEMADDR is the address that we were trying to read. INFO is a + pointer to this struct. */ + void (*memory_error_func) + (int status, bfd_vma memaddr, struct disassemble_info *info); + + /* Function called to print ADDR. */ + void (*print_address_func) + (bfd_vma addr, struct disassemble_info *info); + + /* Function called to determine if there is a symbol at the given ADDR. + If there is, the function returns 1, otherwise it returns 0. + This is used by ports which support an overlay manager where + the overlay number is held in the top part of an address. In + some circumstances we want to include the overlay number in the + address, (normally because there is a symbol associated with + that address), but sometimes we want to mask out the overlay bits. */ + int (* symbol_at_address_func) + (bfd_vma addr, struct disassemble_info * info); + + /* These are for buffer_read_memory. */ + const bfd_byte *buffer; + bfd_vma buffer_vma; + int buffer_length; + + /* This variable may be set by the instruction decoder. It suggests + the number of bytes objdump should display on a single line. If + the instruction decoder sets this, it should always set it to + the same value in order to get reasonable looking output. */ + int bytes_per_line; + + /* the next two variables control the way objdump displays the raw data */ + /* For example, if bytes_per_line is 8 and bytes_per_chunk is 4, the */ + /* output will look like this: + 00: 00000000 00000000 + with the chunks displayed according to "display_endian". */ + int bytes_per_chunk; + enum bfd_endian display_endian; + + /* Results from instruction decoders. Not all decoders yet support + this information. This info is set each time an instruction is + decoded, and is only valid for the last such instruction. + + To determine whether this decoder supports this information, set + insn_info_valid to 0, decode an instruction, then check it. */ + + char insn_info_valid; /* Branch info has been set. */ + char branch_delay_insns; /* How many sequential insn's will run before + a branch takes effect. (0 = normal) */ + char data_size; /* Size of data reference in insn, in bytes */ + enum dis_insn_type insn_type; /* Type of instruction */ + bfd_vma target; /* Target address of branch or dref, if known; + zero if unknown. */ + bfd_vma target2; /* Second target address for dref2 */ + + /* Command line options specific to the target disassembler. */ + const char * disassembler_options; + +} disassemble_info; + +typedef struct powerpc_opcode +{ + /* The opcode name. */ + const char* name; + + /* The opcode itself. Those bits which will be filled in with + operands are zeroes. */ + unsigned long opcode; + + /* The opcode mask. This is used by the disassembler. This is a + mask containing ones indicating those bits which must match the + opcode field, and zeroes indicating those bits which need not + match (and are presumably filled in by operands). */ + unsigned long mask; + + /* One bit flags for the opcode. These are used to indicate which + specific processors support the instructions. The defined values + are listed below. */ + unsigned long flags; + + /* An array of operand codes. Each code is an index into the + operand table. They appear in the order which the operands must + appear in assembly code, and are terminated by a zero. */ + unsigned char operands[8]; + + /* The opcode ID. */ + int id; +} powerpc_opcode; + +typedef struct ppc_insn +{ + const powerpc_opcode* opcode; + uint32_t instruction; + uint32_t operands[8]; + char op_str[160]; +} ppc_insn; + +/* Standard disassemblers. Disassemble one instruction at the given + target address. Return number of bytes processed. */ +typedef int (*disassembler_ftype) (bfd_vma, disassemble_info *); + +int print_insn_big_mips (bfd_vma, disassemble_info*); +int print_insn_little_mips (bfd_vma, disassemble_info*); +int print_insn_i386 (bfd_vma, disassemble_info*); +int print_insn_m68k (bfd_vma, disassemble_info*); +int print_insn_z8001 (bfd_vma, disassemble_info*); +int print_insn_z8002 (bfd_vma, disassemble_info*); +int print_insn_h8300 (bfd_vma, disassemble_info*); +int print_insn_h8300h (bfd_vma, disassemble_info*); +int print_insn_h8300s (bfd_vma, disassemble_info*); +int print_insn_h8500 (bfd_vma, disassemble_info*); +int print_insn_alpha (bfd_vma, disassemble_info*); +disassembler_ftype arc_get_disassembler (int, int); +int print_insn_arm (bfd_vma, disassemble_info*); +int print_insn_sparc (bfd_vma, disassemble_info*); +int print_insn_big_a29k (bfd_vma, disassemble_info*); +int print_insn_little_a29k (bfd_vma, disassemble_info*); +int print_insn_i960 (bfd_vma, disassemble_info*); +int print_insn_sh (bfd_vma, disassemble_info*); +int print_insn_shl (bfd_vma, disassemble_info*); +int print_insn_hppa (bfd_vma, disassemble_info*); +int print_insn_m32r (bfd_vma, disassemble_info*); +int print_insn_m88k (bfd_vma, disassemble_info*); +int print_insn_mn10200 (bfd_vma, disassemble_info*); +int print_insn_mn10300 (bfd_vma, disassemble_info*); +int print_insn_ns32k (bfd_vma, disassemble_info*); +int print_insn_big_powerpc (bfd_vma, disassemble_info*); +int print_insn_little_powerpc (bfd_vma, disassemble_info*); +int print_insn_rs6000 (bfd_vma, disassemble_info*); +int print_insn_w65 (bfd_vma, disassemble_info*); +int print_insn_d10v (bfd_vma, disassemble_info*); +int print_insn_v850 (bfd_vma, disassemble_info*); +int print_insn_tic30 (bfd_vma, disassemble_info*); +int print_insn_ppc (bfd_vma, disassemble_info*); +int print_insn_s390 (bfd_vma, disassemble_info*); +int print_insn_crisv32 (bfd_vma, disassemble_info*); +int print_insn_crisv10 (bfd_vma, disassemble_info*); +int print_insn_microblaze (bfd_vma, disassemble_info*); +int print_insn_ia64 (bfd_vma, disassemble_info*); + +int decode_insn_ppc(bfd_vma, disassemble_info*, ppc_insn*); + +#if 0 +/* Fetch the disassembler for a given BFD, if that support is available. */ +disassembler_ftype disassembler(bfd *); +#endif + +/* This block of definitions is for particular callers who read instructions + into a buffer before calling the instruction decoder. */ + +/* Here is a function which callers may wish to use for read_memory_func. + It gets bytes from a buffer. */ +int buffer_read_memory(bfd_vma, bfd_byte *, int, struct disassemble_info *); + +/* This function goes with buffer_read_memory. + It prints a message using info->fprintf_func and info->stream. */ +void perror_memory(int, bfd_vma, struct disassemble_info *); + + +/* Just print the address in hex. This is included for completeness even + though both GDB and objdump provide their own (to print symbolic + addresses). */ +void generic_print_address(bfd_vma, struct disassemble_info *); + +/* Always true. */ +int generic_symbol_at_address(bfd_vma, struct disassemble_info *); + +/* Macro to initialize a disassemble_info struct. This should be called + by all applications creating such a struct. */ +#define INIT_DISASSEMBLE_INFO(INFO, STREAM, FPRINTF_FUNC) \ + (INFO).flavour = bfd_target_unknown_flavour, \ + (INFO).arch = bfd_arch_unknown, \ + (INFO).mach = 0, \ + (INFO).endian = BFD_ENDIAN_UNKNOWN, \ + INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC) + +/* Call this macro to initialize only the internal variables for the + disassembler. Architecture dependent things such as byte order, or machine + variant are not touched by this macro. This makes things much easier for + GDB which must initialize these things separately. */ + +#define INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC) \ + (INFO).fprintf_func = (FPRINTF_FUNC), \ + (INFO).stream = (STREAM), \ + (INFO).symbols = NULL, \ + (INFO).num_symbols = 0, \ + (INFO).private_data = NULL, \ + (INFO).buffer = NULL, \ + (INFO).buffer_vma = 0, \ + (INFO).buffer_length = 0, \ + (INFO).read_memory_func = buffer_read_memory, \ + (INFO).memory_error_func = perror_memory, \ + (INFO).print_address_func = generic_print_address, \ + (INFO).symbol_at_address_func = generic_symbol_at_address, \ + (INFO).flags = 0, \ + (INFO).bytes_per_line = 0, \ + (INFO).bytes_per_chunk = 0, \ + (INFO).display_endian = BFD_ENDIAN_UNKNOWN, \ + (INFO).disassembler_options = NULL, \ + (INFO).insn_info_valid = 0 + +#define _(x) x + +#if defined __GNUC__ +#define ATTRIBUTE_UNUSED __attribute__((unused)) +#else +#define ATTRIBUTE_UNUSED +#endif +/* from libbfd */ + +bfd_vma bfd_getl64 (const bfd_byte *addr); +bfd_vma bfd_getl32 (const bfd_byte *addr); +bfd_vma bfd_getb32 (const bfd_byte *addr); +bfd_vma bfd_getl16 (const bfd_byte *addr); +bfd_vma bfd_getb16 (const bfd_byte *addr); +typedef bool bfd_boolean; + +#if defined __cplusplus +} +#endif + +#endif /* ! defined (DIS_ASM_H) */ diff --git a/thirdparty/disasm/disasm.c b/thirdparty/disasm/disasm.c new file mode 100644 index 0000000..fa7977d --- /dev/null +++ b/thirdparty/disasm/disasm.c @@ -0,0 +1,110 @@ +#include "dis-asm.h" + +#ifndef EIO +#define EIO 5 +#endif + +/* Get LENGTH bytes from info's buffer, at target address memaddr. + Transfer them to myaddr. */ +int +buffer_read_memory(bfd_vma memaddr, bfd_byte* myaddr, int length, + struct disassemble_info* info) +{ + if (memaddr < info->buffer_vma + || memaddr + length > info->buffer_vma + info->buffer_length) + /* Out of bounds. Use EIO because GDB uses it. */ + return EIO; + memcpy(myaddr, info->buffer + (memaddr - info->buffer_vma), length); + return 0; +} + +/* Print an error message. We can assume that this is in response to + an error return from buffer_read_memory. */ +void +perror_memory(int status, bfd_vma memaddr, struct disassemble_info* info) +{ + if (status != EIO) + /* Can't happen. */ + (*info->fprintf_func) (info->stream, "Unknown error %d\n", status); + else + /* Actually, address between memaddr and memaddr + len was + out of bounds. */ + (*info->fprintf_func) (info->stream, + "Address 0x%" PRIx64 " is out of bounds.\n", memaddr); +} + +/* This could be in a separate file, to save miniscule amounts of space + in statically linked executables. */ + + /* Just print the address is hex. This is included for completeness even + though both GDB and objdump provide their own (to print symbolic + addresses). */ + +void +generic_print_address(bfd_vma addr, struct disassemble_info* info) +{ + (*info->fprintf_func) (info->stream, "0x%" PRIx64, addr); +} + +/* Just return the given address. */ + +int +generic_symbol_at_address(bfd_vma addr, struct disassemble_info* info) +{ + return 1; +} + +bfd_vma bfd_getl64(const bfd_byte* addr) +{ + unsigned long long v; + + v = (unsigned long long) addr[0]; + v |= (unsigned long long) addr[1] << 8; + v |= (unsigned long long) addr[2] << 16; + v |= (unsigned long long) addr[3] << 24; + v |= (unsigned long long) addr[4] << 32; + v |= (unsigned long long) addr[5] << 40; + v |= (unsigned long long) addr[6] << 48; + v |= (unsigned long long) addr[7] << 56; + return (bfd_vma)v; +} + +bfd_vma bfd_getl32(const bfd_byte* addr) +{ + unsigned long v; + + v = (unsigned long)addr[0]; + v |= (unsigned long)addr[1] << 8; + v |= (unsigned long)addr[2] << 16; + v |= (unsigned long)addr[3] << 24; + return (bfd_vma)v; +} + +bfd_vma bfd_getb32(const bfd_byte* addr) +{ + unsigned long v; + + v = (unsigned long)addr[0] << 24; + v |= (unsigned long)addr[1] << 16; + v |= (unsigned long)addr[2] << 8; + v |= (unsigned long)addr[3]; + return (bfd_vma)v; +} + +bfd_vma bfd_getl16(const bfd_byte* addr) +{ + unsigned long v; + + v = (unsigned long)addr[0]; + v |= (unsigned long)addr[1] << 8; + return (bfd_vma)v; +} + +bfd_vma bfd_getb16(const bfd_byte* addr) +{ + unsigned long v; + + v = (unsigned long)addr[0] << 24; + v |= (unsigned long)addr[1] << 16; + return (bfd_vma)v; +} diff --git a/thirdparty/disasm/ppc-dis.c b/thirdparty/disasm/ppc-dis.c new file mode 100644 index 0000000..3e224b4 --- /dev/null +++ b/thirdparty/disasm/ppc-dis.c @@ -0,0 +1,5822 @@ +/* ppc-dis.c -- Disassemble PowerPC instructions + Copyright 1994, 1995, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. + Written by Ian Lance Taylor, Cygnus Support + +This file is part of GDB, GAS, and the GNU binutils. + +GDB, GAS, and the GNU binutils are free software; you can redistribute +them and/or modify them under the terms of the GNU General Public +License as published by the Free Software Foundation; either version +2, or (at your option) any later version. + +GDB, GAS, and the GNU binutils are distributed in the hope that they +will be useful, but WITHOUT ANY WARRANTY; without even the implied +warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this file; see the file COPYING. If not, +see . */ +#include "dis-asm.h" +#include "ppc.h" + +#define BFD_DEFAULT_TARGET_SIZE 64 + +/* ppc.h -- Header file for PowerPC opcode table + Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2007 Free Software Foundation, Inc. + Written by Ian Lance Taylor, Cygnus Support + +This file is part of GDB, GAS, and the GNU binutils. + +GDB, GAS, and the GNU binutils are free software; you can redistribute +them and/or modify them under the terms of the GNU General Public +License as published by the Free Software Foundation; either version +1, or (at your option) any later version. + +GDB, GAS, and the GNU binutils are distributed in the hope that they +will be useful, but WITHOUT ANY WARRANTY; without even the implied +warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this file; see the file COPYING. If not, +see . */ + +/* The opcode table is an array of struct powerpc_opcode. */ + +/* The table itself is sorted by major opcode number, and is otherwise + in the order in which the disassembler should consider + instructions. */ +extern const struct powerpc_opcode powerpc_opcodes[]; +extern const int powerpc_num_opcodes; + +/* Values defined for the flags field of a struct powerpc_opcode. */ + +/* Opcode is defined for the PowerPC architecture. */ +#define PPC_OPCODE_PPC 1 + +/* Opcode is defined for the POWER (RS/6000) architecture. */ +#define PPC_OPCODE_POWER 2 + +/* Opcode is defined for the POWER2 (Rios 2) architecture. */ +#define PPC_OPCODE_POWER2 4 + +/* Opcode is only defined on 32 bit architectures. */ +#define PPC_OPCODE_32 8 + +/* Opcode is only defined on 64 bit architectures. */ +#define PPC_OPCODE_64 0x10 + +/* Opcode is supported by the Motorola PowerPC 601 processor. The 601 + is assumed to support all PowerPC (PPC_OPCODE_PPC) instructions, + but it also supports many additional POWER instructions. */ +#define PPC_OPCODE_601 0x20 + + /* Opcode is supported in both the Power and PowerPC architectures + (ie, compiler's -mcpu=common or assembler's -mcom). */ +#define PPC_OPCODE_COMMON 0x40 + + /* Opcode is supported for any Power or PowerPC platform (this is + for the assembler's -many option, and it eliminates duplicates). */ +#define PPC_OPCODE_ANY 0x80 + + /* Opcode is supported as part of the 64-bit bridge. */ +#define PPC_OPCODE_64_BRIDGE 0x100 + +/* Opcode is supported by Altivec Vector Unit */ +#define PPC_OPCODE_ALTIVEC 0x200 + +/* Opcode is supported by VMX128 Vector Extension */ +#define PPC_OPCODE_VMX_128 0x1000000 + +/* Opcode is supported by PowerPC 403 processor. */ +#define PPC_OPCODE_403 0x400 + +/* Opcode is supported by PowerPC BookE processor. */ +#define PPC_OPCODE_BOOKE 0x800 + +/* Opcode is only supported by 64-bit PowerPC BookE processor. */ +#define PPC_OPCODE_BOOKE64 0x1000 + +/* Opcode is supported by PowerPC 440 processor. */ +#define PPC_OPCODE_440 0x2000 + +/* Opcode is only supported by Power4 architecture. */ +#define PPC_OPCODE_POWER4 0x4000 + +/* Opcode isn't supported by Power4 architecture. */ +#define PPC_OPCODE_NOPOWER4 0x8000 + +/* Opcode is only supported by POWERPC Classic architecture. */ +#define PPC_OPCODE_CLASSIC 0x10000 + +/* Opcode is only supported by e500x2 Core. */ +#define PPC_OPCODE_SPE 0x20000 + +/* Opcode is supported by e500x2 Integer select APU. */ +#define PPC_OPCODE_ISEL 0x40000 + +/* Opcode is an e500 SPE floating point instruction. */ +#define PPC_OPCODE_EFS 0x80000 + +/* Opcode is supported by branch locking APU. */ +#define PPC_OPCODE_BRLOCK 0x100000 + +/* Opcode is supported by performance monitor APU. */ +#define PPC_OPCODE_PMR 0x200000 + +/* Opcode is supported by cache locking APU. */ +#define PPC_OPCODE_CACHELCK 0x400000 + +/* Opcode is supported by machine check APU. */ +#define PPC_OPCODE_RFMCI 0x800000 + +/* Opcode is only supported by Power5 architecture. */ +#define PPC_OPCODE_POWER5 0x1000000 + +/* Opcode is supported by PowerPC e300 family. */ +#define PPC_OPCODE_E300 0x2000000 + +/* Opcode is only supported by Power6 architecture. */ +#define PPC_OPCODE_POWER6 0x4000000 + +/* Opcode is only supported by PowerPC Cell family. */ +#define PPC_OPCODE_CELL 0x8000000 + +/* The operands table is an array of struct powerpc_operand. */ + +struct powerpc_operand +{ + /* A bitmask of bits in the operand. */ + unsigned int bitm; + + /* How far the operand is left shifted in the instruction. + -1 to indicate that BITM and SHIFT cannot be used to determine + where the operand goes in the insn. */ + int shift; + + /* Insertion function. This is used by the assembler. To insert an + operand value into an instruction, check this field. + + If it is NULL, execute + i |= (op & o->bitm) << o->shift; + (i is the instruction which we are filling in, o is a pointer to + this structure, and op is the operand value). + + If this field is not NULL, then simply call it with the + instruction and the operand value. It will return the new value + of the instruction. If the ERRMSG argument is not NULL, then if + the operand value is illegal, *ERRMSG will be set to a warning + string (the operand will be inserted in any case). If the + operand value is legal, *ERRMSG will be unchanged (most operands + can accept any value). */ + unsigned long (*insert) + (unsigned long instruction, long op, int dialect, const char** errmsg); + + /* Extraction function. This is used by the disassembler. To + extract this operand type from an instruction, check this field. + + If it is NULL, compute + op = (i >> o->shift) & o->bitm; + if ((o->flags & PPC_OPERAND_SIGNED) != 0) + sign_extend (op); + (i is the instruction, o is a pointer to this structure, and op + is the result). + + If this field is not NULL, then simply call it with the + instruction value. It will return the value of the operand. If + the INVALID argument is not NULL, *INVALID will be set to + non-zero if this operand type can not actually be extracted from + this operand (i.e., the instruction does not match). If the + operand is valid, *INVALID will not be changed. */ + long (*extract) (unsigned long instruction, int dialect, int* invalid); + + /* One bit syntax flags. */ + unsigned long flags; +}; + +/* Elements in the table are retrieved by indexing with values from + the operands field of the powerpc_opcodes table. */ + +extern const struct powerpc_operand powerpc_operands[]; +extern const unsigned int num_powerpc_operands; + +/* Values defined for the flags field of a struct powerpc_operand. */ + +/* This operand takes signed values. */ +#define PPC_OPERAND_SIGNED (0x1) + +/* This operand takes signed values, but also accepts a full positive + range of values when running in 32 bit mode. That is, if bits is + 16, it takes any value from -0x8000 to 0xffff. In 64 bit mode, + this flag is ignored. */ +#define PPC_OPERAND_SIGNOPT (0x2) + + /* This operand does not actually exist in the assembler input. This + is used to support extended mnemonics such as mr, for which two + operands fields are identical. The assembler should call the + insert function with any op value. The disassembler should call + the extract function, ignore the return value, and check the value + placed in the valid argument. */ +#define PPC_OPERAND_FAKE (0x4) + + /* The next operand should be wrapped in parentheses rather than + separated from this one by a comma. This is used for the load and + store instructions which want their operands to look like + reg,displacement(reg) + */ +#define PPC_OPERAND_PARENS (0x8) + + /* This operand may use the symbolic names for the CR fields, which + are + lt 0 gt 1 eq 2 so 3 un 3 + cr0 0 cr1 1 cr2 2 cr3 3 + cr4 4 cr5 5 cr6 6 cr7 7 + These may be combined arithmetically, as in cr2*4+gt. These are + only supported on the PowerPC, not the POWER. */ +#define PPC_OPERAND_CR (0x10) + + /* This operand names a register. The disassembler uses this to print + register names with a leading 'r'. */ +#define PPC_OPERAND_GPR (0x20) + + /* Like PPC_OPERAND_GPR, but don't print a leading 'r' for r0. */ +#define PPC_OPERAND_GPR_0 (0x40) + +/* This operand names a floating point register. The disassembler + prints these with a leading 'f'. */ +#define PPC_OPERAND_FPR (0x80) + + /* This operand is a relative branch displacement. The disassembler + prints these symbolically if possible. */ +#define PPC_OPERAND_RELATIVE (0x100) + + /* This operand is an absolute branch address. The disassembler + prints these symbolically if possible. */ +#define PPC_OPERAND_ABSOLUTE (0x200) + + /* This operand is optional, and is zero if omitted. This is used for + example, in the optional BF field in the comparison instructions. The + assembler must count the number of operands remaining on the line, + and the number of operands remaining for the opcode, and decide + whether this operand is present or not. The disassembler should + print this operand out only if it is not zero. */ +#define PPC_OPERAND_OPTIONAL (0x400) + + /* This flag is only used with PPC_OPERAND_OPTIONAL. If this operand + is omitted, then for the next operand use this operand value plus + 1, ignoring the next operand field for the opcode. This wretched + hack is needed because the Power rotate instructions can take + either 4 or 5 operands. The disassembler should print this operand + out regardless of the PPC_OPERAND_OPTIONAL field. */ +#define PPC_OPERAND_NEXT (0x800) + + /* This operand should be regarded as a negative number for the + purposes of overflow checking (i.e., the normal most negative + number is disallowed and one more than the normal most positive + number is allowed). This flag will only be set for a signed + operand. */ +#define PPC_OPERAND_NEGATIVE (0x1000) + + /* This operand names a vector unit register. The disassembler + prints these with a leading 'v'. */ +#define PPC_OPERAND_VR (0x2000) + + /* This operand is for the DS field in a DS form instruction. */ +#define PPC_OPERAND_DS (0x4000) + +/* This operand is for the DQ field in a DQ form instruction. */ +#define PPC_OPERAND_DQ (0x8000) + +/* Valid range of operand is 0..n rather than 0..n-1. */ +#define PPC_OPERAND_PLUS1 (0x10000) + +/* The POWER and PowerPC assemblers use a few macros. We keep them + with the operands table for simplicity. The macro table is an + array of struct powerpc_macro. */ + +struct powerpc_macro +{ + /* The macro name. */ + const char* name; + + /* The number of operands the macro takes. */ + unsigned int operands; + + /* One bit flags for the opcode. These are used to indicate which + specific processors support the instructions. The values are the + same as those for the struct powerpc_opcode flags field. */ + unsigned long flags; + + /* A format string to turn the macro into a normal instruction. + Each %N in the string is replaced with operand number N (zero + based). */ + const char* format; +}; + +extern const struct powerpc_macro powerpc_macros[]; +extern const int powerpc_num_macros; + +/* ppc-opc.c -- PowerPC opcode list + Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, + 2005, 2006, 2007 Free Software Foundation, Inc. + Written by Ian Lance Taylor, Cygnus Support + + This file is part of GDB, GAS, and the GNU binutils. + + GDB, GAS, and the GNU binutils are free software; you can redistribute + them and/or modify them under the terms of the GNU General Public + License as published by the Free Software Foundation; either version + 2, or (at your option) any later version. + + GDB, GAS, and the GNU binutils are distributed in the hope that they + will be useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this file; see the file COPYING. + If not, see . */ + + /* This file holds the PowerPC opcode table. The opcode table + includes almost all of the extended instruction mnemonics. This + permits the disassembler to use them, and simplifies the assembler + logic, at the cost of increasing the table size. The table is + strictly constant data, so the compiler should be able to put it in + the .text section. + + This file also holds the operand table. All knowledge about + inserting operands into instructions and vice-versa is kept in this + file. */ + + /* Local insertion and extraction functions. */ + +static unsigned long insert_bat(unsigned long, long, int, const char**); +static long extract_bat(unsigned long, int, int*); +static unsigned long insert_bba(unsigned long, long, int, const char**); +static long extract_bba(unsigned long, int, int*); +static unsigned long insert_bdm(unsigned long, long, int, const char**); +static long extract_bdm(unsigned long, int, int*); +static unsigned long insert_bdp(unsigned long, long, int, const char**); +static long extract_bdp(unsigned long, int, int*); +static unsigned long insert_bo(unsigned long, long, int, const char**); +static long extract_bo(unsigned long, int, int*); +static unsigned long insert_boe(unsigned long, long, int, const char**); +static long extract_boe(unsigned long, int, int*); +static unsigned long insert_fxm(unsigned long, long, int, const char**); +static long extract_fxm(unsigned long, int, int*); +static unsigned long insert_mbe(unsigned long, long, int, const char**); +static long extract_mbe(unsigned long, int, int*); +static unsigned long insert_mb6(unsigned long, long, int, const char**); +static long extract_mb6(unsigned long, int, int*); +static long extract_nb(unsigned long, int, int*); +static unsigned long insert_nsi(unsigned long, long, int, const char**); +static long extract_nsi(unsigned long, int, int*); +static unsigned long insert_ral(unsigned long, long, int, const char**); +static unsigned long insert_ram(unsigned long, long, int, const char**); +static unsigned long insert_raq(unsigned long, long, int, const char**); +static unsigned long insert_ras(unsigned long, long, int, const char**); +static unsigned long insert_rbs(unsigned long, long, int, const char**); +static long extract_rbs(unsigned long, int, int*); +static unsigned long insert_sh6(unsigned long, long, int, const char**); +static long extract_sh6(unsigned long, int, int*); +static unsigned long insert_spr(unsigned long, long, int, const char**); +static long extract_spr(unsigned long, int, int*); +static unsigned long insert_sprg(unsigned long, long, int, const char**); +static long extract_sprg(unsigned long, int, int*); +static unsigned long insert_tbr(unsigned long, long, int, const char**); +static long extract_tbr(unsigned long, int, int*); +static unsigned long insert_vds128(unsigned long, long, int, const char**); +static long extract_vds128(unsigned long, int, int*); +static unsigned long insert_va128(unsigned long, long, int, const char**); +static long extract_va128(unsigned long, int, int*); +static unsigned long insert_vb128(unsigned long, long, int, const char**); +static long extract_vb128(unsigned long, int, int*); +static unsigned long insert_vperm(unsigned long, long, int, const char**); +static long extract_vperm(unsigned long, int, int*); + +/* The operands table. + + The fields are bitm, shift, insert, extract, flags. + + We used to put parens around the various additions, like the one + for BA just below. However, that caused trouble with feeble + compilers with a limit on depth of a parenthesized expression, like + (reportedly) the compiler in Microsoft Developer Studio 5. So we + omit the parens, since the macros are never used in a context where + the addition will be ambiguous. */ + +const struct powerpc_operand powerpc_operands[] = +{ + /* The zero index is used to indicate the end of the list of + operands. */ + #define UNUSED 0 + { 0, 0, NULL, NULL, 0 }, + + /* The BA field in an XL form instruction. */ + #define BA UNUSED + 1 + /* The BI field in a B form or XL form instruction. */ + #define BI BA + #define BI_MASK (0x1f << 16) + { 0x1f, 16, NULL, NULL, PPC_OPERAND_CR }, + + /* The BA field in an XL form instruction when it must be the same + as the BT field in the same instruction. */ + #define BAT BA + 1 + { 0x1f, 16, insert_bat, extract_bat, PPC_OPERAND_FAKE }, + + /* The BB field in an XL form instruction. */ + #define BB BAT + 1 + #define BB_MASK (0x1f << 11) + { 0x1f, 11, NULL, NULL, PPC_OPERAND_CR }, + + /* The BB field in an XL form instruction when it must be the same + as the BA field in the same instruction. */ + #define BBA BB + 1 + { 0x1f, 11, insert_bba, extract_bba, PPC_OPERAND_FAKE }, + + /* The BD field in a B form instruction. The lower two bits are + forced to zero. */ + #define BD BBA + 1 + { 0xfffc, 0, NULL, NULL, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED }, + + /* The BD field in a B form instruction when absolute addressing is + used. */ + #define BDA BD + 1 + { 0xfffc, 0, NULL, NULL, PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED }, + + /* The BD field in a B form instruction when the - modifier is used. + This sets the y bit of the BO field appropriately. */ + #define BDM BDA + 1 + { 0xfffc, 0, insert_bdm, extract_bdm, + PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED }, + + /* The BD field in a B form instruction when the - modifier is used + and absolute address is used. */ + #define BDMA BDM + 1 + { 0xfffc, 0, insert_bdm, extract_bdm, + PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED }, + + /* The BD field in a B form instruction when the + modifier is used. + This sets the y bit of the BO field appropriately. */ + #define BDP BDMA + 1 + { 0xfffc, 0, insert_bdp, extract_bdp, + PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED }, + + /* The BD field in a B form instruction when the + modifier is used + and absolute addressing is used. */ + #define BDPA BDP + 1 + { 0xfffc, 0, insert_bdp, extract_bdp, + PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED }, + + /* The BF field in an X or XL form instruction. */ + #define BF BDPA + 1 + /* The CRFD field in an X form instruction. */ + #define CRFD BF + { 0x7, 23, NULL, NULL, PPC_OPERAND_CR }, + + /* The BF field in an X or XL form instruction. */ + #define BFF BF + 1 + { 0x7, 23, NULL, NULL, 0 }, + + /* An optional BF field. This is used for comparison instructions, + in which an omitted BF field is taken as zero. */ + #define OBF BFF + 1 + { 0x7, 23, NULL, NULL, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL }, + + /* The BFA field in an X or XL form instruction. */ + #define BFA OBF + 1 + { 0x7, 18, NULL, NULL, PPC_OPERAND_CR }, + + /* The BO field in a B form instruction. Certain values are + illegal. */ + #define BO BFA + 1 + #define BO_MASK (0x1f << 21) + { 0x1f, 21, insert_bo, extract_bo, 0 }, + + /* The BO field in a B form instruction when the + or - modifier is + used. This is like the BO field, but it must be even. */ + #define BOE BO + 1 + { 0x1e, 21, insert_boe, extract_boe, 0 }, + + #define BH BOE + 1 + { 0x3, 11, NULL, NULL, PPC_OPERAND_OPTIONAL }, + + /* The BT field in an X or XL form instruction. */ + #define BT BH + 1 + { 0x1f, 21, NULL, NULL, PPC_OPERAND_CR }, + + /* The condition register number portion of the BI field in a B form + or XL form instruction. This is used for the extended + conditional branch mnemonics, which set the lower two bits of the + BI field. This field is optional. */ + #define CR BT + 1 + { 0x7, 18, NULL, NULL, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL }, + + /* The CRB field in an X form instruction. */ + #define CRB CR + 1 + /* The MB field in an M form instruction. */ + #define MB CRB + #define MB_MASK (0x1f << 6) + { 0x1f, 6, NULL, NULL, 0 }, + + /* The CRFS field in an X form instruction. */ + #define CRFS CRB + 1 + { 0x7, 0, NULL, NULL, PPC_OPERAND_CR }, + + /* The CT field in an X form instruction. */ + #define CT CRFS + 1 + /* The MO field in an mbar instruction. */ + #define MO CT + { 0x1f, 21, NULL, NULL, PPC_OPERAND_OPTIONAL }, + + /* The D field in a D form instruction. This is a displacement off + a register, and implies that the next operand is a register in + parentheses. */ + #define D CT + 1 + { 0xffff, 0, NULL, NULL, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED }, + + /* The DE field in a DE form instruction. This is like D, but is 12 + bits only. */ + #define DE D + 1 + { 0xfff, 4, NULL, NULL, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED }, + + /* The DES field in a DES form instruction. This is like DS, but is 14 + bits only (12 stored.) */ + #define DES DE + 1 + { 0x3ffc, 2, NULL, NULL, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED }, + + /* The DQ field in a DQ form instruction. This is like D, but the + lower four bits are forced to zero. */ + #define DQ DES + 1 + { 0xfff0, 0, NULL, NULL, + PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED | PPC_OPERAND_DQ }, + + /* The DS field in a DS form instruction. This is like D, but the + lower two bits are forced to zero. */ + #undef DS + #define DS DQ + 1 + { 0xfffc, 0, NULL, NULL, + PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED | PPC_OPERAND_DS }, + + /* The E field in a wrteei instruction. */ + #define E DS + 1 + { 0x1, 15, NULL, NULL, 0 }, + + /* The FL1 field in a POWER SC form instruction. */ + #define FL1 E + 1 + /* The U field in an X form instruction. */ + #define U FL1 + { 0xf, 12, NULL, NULL, 0 }, + + /* The FL2 field in a POWER SC form instruction. */ + #define FL2 FL1 + 1 + { 0x7, 2, NULL, NULL, 0 }, + + /* The FLM field in an XFL form instruction. */ + #define FLM FL2 + 1 + { 0xff, 17, NULL, NULL, 0 }, + + /* The FRA field in an X or A form instruction. */ + #define FRA FLM + 1 + #define FRA_MASK (0x1f << 16) + { 0x1f, 16, NULL, NULL, PPC_OPERAND_FPR }, + + /* The FRB field in an X or A form instruction. */ + #define FRB FRA + 1 + #define FRB_MASK (0x1f << 11) + { 0x1f, 11, NULL, NULL, PPC_OPERAND_FPR }, + + /* The FRC field in an A form instruction. */ + #define FRC FRB + 1 + #define FRC_MASK (0x1f << 6) + { 0x1f, 6, NULL, NULL, PPC_OPERAND_FPR }, + + /* The FRS field in an X form instruction or the FRT field in a D, X + or A form instruction. */ + #define FRS FRC + 1 + #define FRT FRS + { 0x1f, 21, NULL, NULL, PPC_OPERAND_FPR }, + + /* The FXM field in an XFX instruction. */ + #define FXM FRS + 1 + { 0xff, 12, insert_fxm, extract_fxm, 0 }, + + /* Power4 version for mfcr. */ + #define FXM4 FXM + 1 + { 0xff, 12, insert_fxm, extract_fxm, PPC_OPERAND_OPTIONAL }, + + /* The L field in a D or X form instruction. */ + #define L FXM4 + 1 + { 0x1, 21, NULL, NULL, PPC_OPERAND_OPTIONAL }, + + /* The LEV field in a POWER SVC form instruction. */ + #define SVC_LEV L + 1 + { 0x7f, 5, NULL, NULL, 0 }, + + /* The LEV field in an SC form instruction. */ + #define LEV SVC_LEV + 1 + { 0x7f, 5, NULL, NULL, PPC_OPERAND_OPTIONAL }, + + /* The LI field in an I form instruction. The lower two bits are + forced to zero. */ + #define LI LEV + 1 + { 0x3fffffc, 0, NULL, NULL, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED }, + + /* The LI field in an I form instruction when used as an absolute + address. */ + #define LIA LI + 1 + { 0x3fffffc, 0, NULL, NULL, PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED }, + + /* The LS field in an X (sync) form instruction. */ + #define LS LIA + 1 + { 0x3, 21, NULL, NULL, PPC_OPERAND_OPTIONAL }, + + /* The ME field in an M form instruction. */ + #define ME LS + 1 + #define ME_MASK (0x1f << 1) + { 0x1f, 1, NULL, NULL, 0 }, + + /* The MB and ME fields in an M form instruction expressed a single + operand which is a bitmask indicating which bits to select. This + is a two operand form using PPC_OPERAND_NEXT. See the + description in opcode/ppc.h for what this means. */ + #define MBE ME + 1 + { 0x1f, 6, NULL, NULL, PPC_OPERAND_OPTIONAL | PPC_OPERAND_NEXT }, + { -1, 0, insert_mbe, extract_mbe, 0 }, + + /* The MB or ME field in an MD or MDS form instruction. The high + bit is wrapped to the low end. */ + #define MB6 MBE + 2 + #define ME6 MB6 + #define MB6_MASK (0x3f << 5) + { 0x3f, 5, insert_mb6, extract_mb6, 0 }, + + /* The NB field in an X form instruction. The value 32 is stored as + 0. */ + #define NB MB6 + 1 + { 0x1f, 11, NULL, extract_nb, PPC_OPERAND_PLUS1 }, + + /* The NSI field in a D form instruction. This is the same as the + SI field, only negated. */ + #define NSI NB + 1 + { 0xffff, 0, insert_nsi, extract_nsi, + PPC_OPERAND_NEGATIVE | PPC_OPERAND_SIGNED }, + + /* The RA field in an D, DS, DQ, X, XO, M, or MDS form instruction. */ + #define RA NSI + 1 + #define RA_MASK (0x1f << 16) + { 0x1f, 16, NULL, NULL, PPC_OPERAND_GPR }, + + /* As above, but 0 in the RA field means zero, not r0. */ + #define RA0 RA + 1 + { 0x1f, 16, NULL, NULL, PPC_OPERAND_GPR_0 }, + + /* The RA field in the DQ form lq instruction, which has special + value restrictions. */ + #define RAQ RA0 + 1 + { 0x1f, 16, insert_raq, NULL, PPC_OPERAND_GPR_0 }, + + /* The RA field in a D or X form instruction which is an updating + load, which means that the RA field may not be zero and may not + equal the RT field. */ + #define RAL RAQ + 1 + { 0x1f, 16, insert_ral, NULL, PPC_OPERAND_GPR_0 }, + + /* The RA field in an lmw instruction, which has special value + restrictions. */ + #define RAM RAL + 1 + { 0x1f, 16, insert_ram, NULL, PPC_OPERAND_GPR_0 }, + + /* The RA field in a D or X form instruction which is an updating + store or an updating floating point load, which means that the RA + field may not be zero. */ + #define RAS RAM + 1 + { 0x1f, 16, insert_ras, NULL, PPC_OPERAND_GPR_0 }, + + /* The RA field of the tlbwe instruction, which is optional. */ + #define RAOPT RAS + 1 + { 0x1f, 16, NULL, NULL, PPC_OPERAND_GPR | PPC_OPERAND_OPTIONAL }, + + /* The RB field in an X, XO, M, or MDS form instruction. */ + #define RB RAOPT + 1 + #define RB_MASK (0x1f << 11) + { 0x1f, 11, NULL, NULL, PPC_OPERAND_GPR }, + + /* The RB field in an X form instruction when it must be the same as + the RS field in the instruction. This is used for extended + mnemonics like mr. */ + #define RBS RB + 1 + { 0x1f, 11, insert_rbs, extract_rbs, PPC_OPERAND_FAKE }, + + /* The RS field in a D, DS, X, XFX, XS, M, MD or MDS form + instruction or the RT field in a D, DS, X, XFX or XO form + instruction. */ + #define RS RBS + 1 + #define RT RS + #define RT_MASK (0x1f << 21) + { 0x1f, 21, NULL, NULL, PPC_OPERAND_GPR }, + + /* The RS and RT fields of the DS form stq instruction, which have + special value restrictions. */ + #define RSQ RS + 1 + #define RTQ RSQ + { 0x1e, 21, NULL, NULL, PPC_OPERAND_GPR_0 }, + + /* The RS field of the tlbwe instruction, which is optional. */ + #define RSO RSQ + 1 + #define RTO RSO + { 0x1f, 21, NULL, NULL, PPC_OPERAND_GPR | PPC_OPERAND_OPTIONAL }, + + /* The SH field in an X or M form instruction. */ + #define SH RSO + 1 + #define SH_MASK (0x1f << 11) + /* The other UIMM field in a EVX form instruction. */ + #define EVUIMM SH + { 0x1f, 11, NULL, NULL, 0 }, + + /* The SH field in an MD form instruction. This is split. */ + #define SH6 SH + 1 + #define SH6_MASK ((0x1f << 11) | (1 << 1)) + { 0x3f, -1, insert_sh6, extract_sh6, 0 }, + + /* The SH field of the tlbwe instruction, which is optional. */ + #define SHO SH6 + 1 + { 0x1f, 11, NULL, NULL, PPC_OPERAND_OPTIONAL }, + + /* The SI field in a D form instruction. */ + #define SI SHO + 1 + { 0xffff, 0, NULL, NULL, PPC_OPERAND_SIGNED }, + + /* The SI field in a D form instruction when we accept a wide range + of positive values. */ + #define SISIGNOPT SI + 1 + { 0xffff, 0, NULL, NULL, PPC_OPERAND_SIGNED | PPC_OPERAND_SIGNOPT }, + + /* The SPR field in an XFX form instruction. This is flipped--the + lower 5 bits are stored in the upper 5 and vice- versa. */ + #define SPR SISIGNOPT + 1 + #define PMR SPR + #define SPR_MASK (0x3ff << 11) + { 0x3ff, 11, insert_spr, extract_spr, 0 }, + + /* The BAT index number in an XFX form m[ft]ibat[lu] instruction. */ + #define SPRBAT SPR + 1 + #define SPRBAT_MASK (0x3 << 17) + { 0x3, 17, NULL, NULL, 0 }, + + /* The SPRG register number in an XFX form m[ft]sprg instruction. */ + #define SPRG SPRBAT + 1 + { 0x1f, 16, insert_sprg, extract_sprg, 0 }, + + /* The SR field in an X form instruction. */ + #define SR SPRG + 1 + { 0xf, 16, NULL, NULL, 0 }, + + /* The STRM field in an X AltiVec form instruction. */ + #define STRM SR + 1 + { 0x3, 21, NULL, NULL, 0 }, + + /* The SV field in a POWER SC form instruction. */ + #define SV STRM + 1 + { 0x3fff, 2, NULL, NULL, 0 }, + + /* The TBR field in an XFX form instruction. This is like the SPR + field, but it is optional. */ + #define TBR SV + 1 + { 0x3ff, 11, insert_tbr, extract_tbr, PPC_OPERAND_OPTIONAL }, + + /* The TO field in a D or X form instruction. */ + #define TO TBR + 1 + #define TO_MASK (0x1f << 21) + { 0x1f, 21, NULL, NULL, 0 }, + + /* The UI field in a D form instruction. */ + #define UI TO + 1 + { 0xffff, 0, NULL, NULL, 0 }, + + /* The VA field in a VA, VX or VXR form instruction. */ + #define VA UI + 1 + { 0x1f, 16, NULL, NULL, PPC_OPERAND_VR }, + + /* The VB field in a VA, VX or VXR form instruction. */ + #define VB VA + 1 + { 0x1f, 11, NULL, NULL, PPC_OPERAND_VR }, + + /* The VC field in a VA form instruction. */ + #define VC VB + 1 + { 0x1f, 6, NULL, NULL, PPC_OPERAND_VR }, + + /* The VD or VS field in a VA, VX, VXR or X form instruction. */ + #define VD VC + 1 + #define VS VD + { 0x1f, 21, NULL, NULL, PPC_OPERAND_VR }, + + #define VD128 VD + 1 + #define VS128 VD128 + #define VD128_MASK (0x1f << 21) + { 7, 0, insert_vds128, extract_vds128, PPC_OPERAND_VR }, + + /* The VA128 field in a VA, VX, VXR or X form instruction. */ + #define VA128 VD128 + 1 + #define VA128_MASK (0x1f << 21) + { 7, 0, insert_va128, extract_va128, PPC_OPERAND_VR }, + + /* The VB128 field in a VA, VX, VXR or X form instruction. */ + #define VB128 VA128 + 1 + #define VB128_MASK (0x1f << 21) + { 7, 0, insert_vb128, extract_vb128, PPC_OPERAND_VR }, + + /* The VC128 field in a VA, VX, VXR or X form instruction. */ + #define VC128 VB128 + 1 + #define VC128_MASK (0x1f << 21) + { 7, 6, NULL, NULL, PPC_OPERAND_VR }, + + /* The VPERM field in a VPERM128 form instruction. */ + #define VPERM128 VC128 + 1 + #define VPERM_MASK (0x1f << 21) + { 8, 0, insert_vperm, extract_vperm, 0 }, + + #define VD3D0 VPERM128 + 1 + { 7, 18, NULL, NULL, 0 }, + + #define VD3D1 VD3D0 + 1 + { 3, 16, NULL, NULL, 0 }, + + #define VD3D2 VD3D1 + 1 + { 3, 6, NULL, NULL, 0 }, + + /* The SIMM field in a VX form instruction. */ + #define SIMM VD3D2 + 1 + { 0x1f, 16, NULL, NULL, PPC_OPERAND_SIGNED}, + + /* The UIMM field in a VX form instruction, and TE in Z form. */ + #define UIMM SIMM + 1 + #define TE UIMM + { 0x1f, 16, NULL, NULL, 0 }, + + /* The SHB field in a VA form instruction. */ + #define SHB UIMM + 1 + { 0xf, 6, NULL, NULL, 0 }, + + /* The other UIMM field in a half word EVX form instruction. */ + #define EVUIMM_2 SHB + 1 + { 0x3e, 10, NULL, NULL, PPC_OPERAND_PARENS }, + + /* The other UIMM field in a word EVX form instruction. */ + #define EVUIMM_4 EVUIMM_2 + 1 + { 0x7c, 9, NULL, NULL, PPC_OPERAND_PARENS }, + + /* The other UIMM field in a double EVX form instruction. */ + #define EVUIMM_8 EVUIMM_4 + 1 + { 0xf8, 8, NULL, NULL, PPC_OPERAND_PARENS }, + + /* The WS field. */ + #define WS EVUIMM_8 + 1 + { 0x7, 11, NULL, NULL, 0 }, + + /* The L field in an mtmsrd or A form instruction or W in an X form. */ + #define A_L WS + 1 + #define W A_L + { 0x1, 16, NULL, NULL, PPC_OPERAND_OPTIONAL }, + + #define RMC A_L + 1 + { 0x3, 9, NULL, NULL, 0 }, + + #define R RMC + 1 + { 0x1, 16, NULL, NULL, 0 }, + + #define SP R + 1 + { 0x3, 19, NULL, NULL, 0 }, + + #define S SP + 1 + { 0x1, 20, NULL, NULL, 0 }, + + /* SH field starting at bit position 16. */ + #define SH16 S + 1 + /* The DCM and DGM fields in a Z form instruction. */ + #define DCM SH16 + #define DGM DCM + { 0x3f, 10, NULL, NULL, 0 }, + + /* The EH field in larx instruction. */ + #define EH SH16 + 1 + { 0x1, 0, NULL, NULL, PPC_OPERAND_OPTIONAL }, + + /* The L field in an mtfsf or XFL form instruction. */ + #define XFL_L EH + 1 + { 0x1, 25, NULL, NULL, PPC_OPERAND_OPTIONAL}, +}; + +const unsigned int num_powerpc_operands = (sizeof(powerpc_operands) + / sizeof(powerpc_operands[0])); + +/* The functions used to insert and extract complicated operands. */ + +/* The BA field in an XL form instruction when it must be the same as + the BT field in the same instruction. This operand is marked FAKE. + The insertion function just copies the BT field into the BA field, + and the extraction function just checks that the fields are the + same. */ + +static unsigned long +insert_bat(unsigned long insn, + long value ATTRIBUTE_UNUSED, + int dialect ATTRIBUTE_UNUSED, + const char** errmsg ATTRIBUTE_UNUSED) +{ + return insn | (((insn >> 21) & 0x1f) << 16); +} + +static long +extract_bat(unsigned long insn, + int dialect ATTRIBUTE_UNUSED, + int* invalid) +{ + if (((insn >> 21) & 0x1f) != ((insn >> 16) & 0x1f)) + *invalid = 1; + return 0; +} + +/* The BB field in an XL form instruction when it must be the same as + the BA field in the same instruction. This operand is marked FAKE. + The insertion function just copies the BA field into the BB field, + and the extraction function just checks that the fields are the + same. */ + +static unsigned long +insert_bba(unsigned long insn, + long value ATTRIBUTE_UNUSED, + int dialect ATTRIBUTE_UNUSED, + const char** errmsg ATTRIBUTE_UNUSED) +{ + return insn | (((insn >> 16) & 0x1f) << 11); +} + +static long +extract_bba(unsigned long insn, + int dialect ATTRIBUTE_UNUSED, + int* invalid) +{ + if (((insn >> 16) & 0x1f) != ((insn >> 11) & 0x1f)) + *invalid = 1; + return 0; +} + +/* The BD field in a B form instruction when the - modifier is used. + This modifier means that the branch is not expected to be taken. + For chips built to versions of the architecture prior to version 2 + (ie. not Power4 compatible), we set the y bit of the BO field to 1 + if the offset is negative. When extracting, we require that the y + bit be 1 and that the offset be positive, since if the y bit is 0 + we just want to print the normal form of the instruction. + Power4 compatible targets use two bits, "a", and "t", instead of + the "y" bit. "at" == 00 => no hint, "at" == 01 => unpredictable, + "at" == 10 => not taken, "at" == 11 => taken. The "t" bit is 00001 + in BO field, the "a" bit is 00010 for branch on CR(BI) and 01000 + for branch on CTR. We only handle the taken/not-taken hint here. + Note that we don't relax the conditions tested here when + disassembling with -Many because insns using extract_bdm and + extract_bdp always occur in pairs. One or the other will always + be valid. */ + +static unsigned long +insert_bdm(unsigned long insn, + long value, + int dialect, + const char** errmsg ATTRIBUTE_UNUSED) +{ + if ((dialect & PPC_OPCODE_POWER4) == 0) + { + if ((value & 0x8000) != 0) + insn |= 1 << 21; + } + else + { + if ((insn & (0x14 << 21)) == (0x04 << 21)) + insn |= 0x02 << 21; + else if ((insn & (0x14 << 21)) == (0x10 << 21)) + insn |= 0x08 << 21; + } + return insn | (value & 0xfffc); +} + +static long +extract_bdm(unsigned long insn, + int dialect, + int* invalid) +{ + if ((dialect & PPC_OPCODE_POWER4) == 0) + { + if (((insn & (1 << 21)) == 0) != ((insn & (1 << 15)) == 0)) + *invalid = 1; + } + else + { + if ((insn & (0x17 << 21)) != (0x06 << 21) + && (insn & (0x1d << 21)) != (0x18 << 21)) + *invalid = 1; + } + + return ((insn & 0xfffc) ^ 0x8000) - 0x8000; +} + +/* The BD field in a B form instruction when the + modifier is used. + This is like BDM, above, except that the branch is expected to be + taken. */ + +static unsigned long +insert_bdp(unsigned long insn, + long value, + int dialect, + const char** errmsg ATTRIBUTE_UNUSED) +{ + if ((dialect & PPC_OPCODE_POWER4) == 0) + { + if ((value & 0x8000) == 0) + insn |= 1 << 21; + } + else + { + if ((insn & (0x14 << 21)) == (0x04 << 21)) + insn |= 0x03 << 21; + else if ((insn & (0x14 << 21)) == (0x10 << 21)) + insn |= 0x09 << 21; + } + return insn | (value & 0xfffc); +} + +static long +extract_bdp(unsigned long insn, + int dialect, + int* invalid) +{ + if ((dialect & PPC_OPCODE_POWER4) == 0) + { + if (((insn & (1 << 21)) == 0) == ((insn & (1 << 15)) == 0)) + *invalid = 1; + } + else + { + if ((insn & (0x17 << 21)) != (0x07 << 21) + && (insn & (0x1d << 21)) != (0x19 << 21)) + *invalid = 1; + } + + return ((insn & 0xfffc) ^ 0x8000) - 0x8000; +} + +/* Check for legal values of a BO field. */ + +static int +valid_bo(long value, int dialect, int extract) +{ + if ((dialect & PPC_OPCODE_POWER4) == 0) + { + int valid; + /* Certain encodings have bits that are required to be zero. + These are (z must be zero, y may be anything): + 001zy + 011zy + 1z00y + 1z01y + 1z1zz + */ + switch (value & 0x14) + { + default: + case 0: + valid = 1; + break; + case 0x4: + valid = (value & 0x2) == 0; + break; + case 0x10: + valid = (value & 0x8) == 0; + break; + case 0x14: + valid = value == 0x14; + break; + } + /* When disassembling with -Many, accept power4 encodings too. */ + if (valid + || (dialect & PPC_OPCODE_ANY) == 0 + || !extract) + return valid; + } + + /* Certain encodings have bits that are required to be zero. + These are (z must be zero, a & t may be anything): + 0000z + 0001z + 0100z + 0101z + 001at + 011at + 1a00t + 1a01t + 1z1zz + */ + if ((value & 0x14) == 0) + return (value & 0x1) == 0; + else if ((value & 0x14) == 0x14) + return value == 0x14; + else + return 1; +} + +/* The BO field in a B form instruction. Warn about attempts to set + the field to an illegal value. */ + +static unsigned long +insert_bo(unsigned long insn, + long value, + int dialect, + const char** errmsg) +{ + if (!valid_bo(value, dialect, 0)) + *errmsg = _("invalid conditional option"); + return insn | ((value & 0x1f) << 21); +} + +static long +extract_bo(unsigned long insn, + int dialect, + int* invalid) +{ + long value; + + value = (insn >> 21) & 0x1f; + if (!valid_bo(value, dialect, 1)) + *invalid = 1; + return value; +} + +/* The BO field in a B form instruction when the + or - modifier is + used. This is like the BO field, but it must be even. When + extracting it, we force it to be even. */ + +static unsigned long +insert_boe(unsigned long insn, + long value, + int dialect, + const char** errmsg) +{ + if (!valid_bo(value, dialect, 0)) + *errmsg = _("invalid conditional option"); + else if ((value & 1) != 0) + *errmsg = _("attempt to set y bit when using + or - modifier"); + + return insn | ((value & 0x1f) << 21); +} + +static long +extract_boe(unsigned long insn, + int dialect, + int* invalid) +{ + long value; + + value = (insn >> 21) & 0x1f; + if (!valid_bo(value, dialect, 1)) + *invalid = 1; + return value & 0x1e; +} + +/* FXM mask in mfcr and mtcrf instructions. */ + +static unsigned long +insert_fxm(unsigned long insn, + long value, + int dialect, + const char** errmsg) +{ + /* If we're handling the mfocrf and mtocrf insns ensure that exactly + one bit of the mask field is set. */ + if ((insn & (1 << 20)) != 0) + { + if (value == 0 || (value & -value) != value) + { + *errmsg = _("invalid mask field"); + value = 0; + } + } + + /* If the optional field on mfcr is missing that means we want to use + the old form of the instruction that moves the whole cr. In that + case we'll have VALUE zero. There doesn't seem to be a way to + distinguish this from the case where someone writes mfcr %r3,0. */ + else if (value == 0) + ; + + /* If only one bit of the FXM field is set, we can use the new form + of the instruction, which is faster. Unlike the Power4 branch hint + encoding, this is not backward compatible. Do not generate the + new form unless -mpower4 has been given, or -many and the two + operand form of mfcr was used. */ + else if ((value & -value) == value + && ((dialect & PPC_OPCODE_POWER4) != 0 + || ((dialect & PPC_OPCODE_ANY) != 0 + && (insn & (0x3ff << 1)) == 19 << 1))) + insn |= 1 << 20; + + /* Any other value on mfcr is an error. */ + else if ((insn & (0x3ff << 1)) == 19 << 1) + { + *errmsg = _("ignoring invalid mfcr mask"); + value = 0; + } + + return insn | ((value & 0xff) << 12); +} + +static long +extract_fxm(unsigned long insn, + int dialect ATTRIBUTE_UNUSED, + int* invalid) +{ + long mask = (insn >> 12) & 0xff; + + /* Is this a Power4 insn? */ + if ((insn & (1 << 20)) != 0) + { + /* Exactly one bit of MASK should be set. */ + if (mask == 0 || (mask & -mask) != mask) + *invalid = 1; + } + + /* Check that non-power4 form of mfcr has a zero MASK. */ + else if ((insn & (0x3ff << 1)) == 19 << 1) + { + if (mask != 0) + *invalid = 1; + } + + return mask; +} + +/* The MB and ME fields in an M form instruction expressed as a single + operand which is itself a bitmask. The extraction function always + marks it as invalid, since we never want to recognize an + instruction which uses a field of this type. */ + +static unsigned long +insert_mbe(unsigned long insn, + long value, + int dialect ATTRIBUTE_UNUSED, + const char** errmsg) +{ + unsigned long uval, mask; + int mb, me, mx, count, last; + + uval = value; + + if (uval == 0) + { + *errmsg = _("illegal bitmask"); + return insn; + } + + mb = 0; + me = 32; + if ((uval & 1) != 0) + last = 1; + else + last = 0; + count = 0; + + /* mb: location of last 0->1 transition */ + /* me: location of last 1->0 transition */ + /* count: # transitions */ + + for (mx = 0, mask = 1L << 31; mx < 32; ++mx, mask >>= 1) + { + if ((uval & mask) && !last) + { + ++count; + mb = mx; + last = 1; + } + else if (!(uval & mask) && last) + { + ++count; + me = mx; + last = 0; + } + } + if (me == 0) + me = 32; + + if (count != 2 && (count != 0 || !last)) + *errmsg = _("illegal bitmask"); + + return insn | (mb << 6) | ((me - 1) << 1); +} + +static long +extract_mbe(unsigned long insn, + int dialect ATTRIBUTE_UNUSED, + int* invalid) +{ + long ret; + int mb, me; + int i; + + *invalid = 1; + + mb = (insn >> 6) & 0x1f; + me = (insn >> 1) & 0x1f; + if (mb < me + 1) + { + ret = 0; + for (i = mb; i <= me; i++) + ret |= 1L << (31 - i); + } + else if (mb == me + 1) + ret = ~0; + else /* (mb > me + 1) */ + { + ret = ~0; + for (i = me + 1; i < mb; i++) + ret &= ~(1L << (31 - i)); + } + return ret; +} + +/* The MB or ME field in an MD or MDS form instruction. The high bit + is wrapped to the low end. */ + +static unsigned long +insert_mb6(unsigned long insn, + long value, + int dialect ATTRIBUTE_UNUSED, + const char** errmsg ATTRIBUTE_UNUSED) +{ + return insn | ((value & 0x1f) << 6) | (value & 0x20); +} + +static long +extract_mb6(unsigned long insn, + int dialect ATTRIBUTE_UNUSED, + int* invalid ATTRIBUTE_UNUSED) +{ + return ((insn >> 6) & 0x1f) | (insn & 0x20); +} + +/* The NB field in an X form instruction. The value 32 is stored as + 0. */ + +static long +extract_nb(unsigned long insn, + int dialect ATTRIBUTE_UNUSED, + int* invalid ATTRIBUTE_UNUSED) +{ + long ret; + + ret = (insn >> 11) & 0x1f; + if (ret == 0) + ret = 32; + return ret; +} + +/* The NSI field in a D form instruction. This is the same as the SI + field, only negated. The extraction function always marks it as + invalid, since we never want to recognize an instruction which uses + a field of this type. */ + +static unsigned long +insert_nsi(unsigned long insn, + long value, + int dialect ATTRIBUTE_UNUSED, + const char** errmsg ATTRIBUTE_UNUSED) +{ + return insn | (-value & 0xffff); +} + +static long +extract_nsi(unsigned long insn, + int dialect ATTRIBUTE_UNUSED, + int* invalid) +{ + *invalid = 1; + return -(((insn & 0xffff) ^ 0x8000) - 0x8000); +} + +/* The RA field in a D or X form instruction which is an updating + load, which means that the RA field may not be zero and may not + equal the RT field. */ + +static unsigned long +insert_ral(unsigned long insn, + long value, + int dialect ATTRIBUTE_UNUSED, + const char** errmsg) +{ + if (value == 0 + || (unsigned long)value == ((insn >> 21) & 0x1f)) + *errmsg = "invalid register operand when updating"; + return insn | ((value & 0x1f) << 16); +} + +/* The RA field in an lmw instruction, which has special value + restrictions. */ + +static unsigned long +insert_ram(unsigned long insn, + long value, + int dialect ATTRIBUTE_UNUSED, + const char** errmsg) +{ + if ((unsigned long)value >= ((insn >> 21) & 0x1f)) + *errmsg = _("index register in load range"); + return insn | ((value & 0x1f) << 16); +} + +/* The RA field in the DQ form lq instruction, which has special + value restrictions. */ + +static unsigned long +insert_raq(unsigned long insn, + long value, + int dialect ATTRIBUTE_UNUSED, + const char** errmsg) +{ + long rtvalue = (insn & RT_MASK) >> 21; + + if (value == rtvalue) + *errmsg = _("source and target register operands must be different"); + return insn | ((value & 0x1f) << 16); +} + +/* The RA field in a D or X form instruction which is an updating + store or an updating floating point load, which means that the RA + field may not be zero. */ + +static unsigned long +insert_ras(unsigned long insn, + long value, + int dialect ATTRIBUTE_UNUSED, + const char** errmsg) +{ + if (value == 0) + *errmsg = _("invalid register operand when updating"); + return insn | ((value & 0x1f) << 16); +} + +/* The RB field in an X form instruction when it must be the same as + the RS field in the instruction. This is used for extended + mnemonics like mr. This operand is marked FAKE. The insertion + function just copies the BT field into the BA field, and the + extraction function just checks that the fields are the same. */ + +static unsigned long +insert_rbs(unsigned long insn, + long value ATTRIBUTE_UNUSED, + int dialect ATTRIBUTE_UNUSED, + const char** errmsg ATTRIBUTE_UNUSED) +{ + return insn | (((insn >> 21) & 0x1f) << 11); +} + +static long +extract_rbs(unsigned long insn, + int dialect ATTRIBUTE_UNUSED, + int* invalid) +{ + if (((insn >> 21) & 0x1f) != ((insn >> 11) & 0x1f)) + *invalid = 1; + return 0; +} + +/* The SH field in an MD form instruction. This is split. */ + +static unsigned long +insert_sh6(unsigned long insn, + long value, + int dialect ATTRIBUTE_UNUSED, + const char** errmsg ATTRIBUTE_UNUSED) +{ + return insn | ((value & 0x1f) << 11) | ((value & 0x20) >> 4); +} + +static long +extract_sh6(unsigned long insn, + int dialect ATTRIBUTE_UNUSED, + int* invalid ATTRIBUTE_UNUSED) +{ + return ((insn >> 11) & 0x1f) | ((insn << 4) & 0x20); +} + +/* The SPR field in an XFX form instruction. This is flipped--the + lower 5 bits are stored in the upper 5 and vice- versa. */ + +static unsigned long +insert_spr(unsigned long insn, + long value, + int dialect ATTRIBUTE_UNUSED, + const char** errmsg ATTRIBUTE_UNUSED) +{ + return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6); +} + +static long +extract_spr(unsigned long insn, + int dialect ATTRIBUTE_UNUSED, + int* invalid ATTRIBUTE_UNUSED) +{ + return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0); +} + +/* Some dialects have 8 SPRG registers instead of the standard 4. */ + +static unsigned long +insert_sprg(unsigned long insn, + long value, + int dialect, + const char** errmsg) +{ + /* This check uses PPC_OPCODE_403 because PPC405 is later defined + as a synonym. If ever a 405 specific dialect is added this + check should use that instead. */ + if (value > 7 + || (value > 3 + && (dialect & (PPC_OPCODE_BOOKE | PPC_OPCODE_403)) == 0)) + *errmsg = _("invalid sprg number"); + + /* If this is mfsprg4..7 then use spr 260..263 which can be read in + user mode. Anything else must use spr 272..279. */ + if (value <= 3 || (insn & 0x100) != 0) + value |= 0x10; + + return insn | ((value & 0x17) << 16); +} + +static long +extract_sprg(unsigned long insn, + int dialect, + int* invalid) +{ + unsigned long val = (insn >> 16) & 0x1f; + + /* mfsprg can use 260..263 and 272..279. mtsprg only uses spr 272..279 + If not BOOKE or 405, then both use only 272..275. */ + if (val <= 3 + || (val < 0x10 && (insn & 0x100) != 0) + || (val - 0x10 > 3 + && (dialect & (PPC_OPCODE_BOOKE | PPC_OPCODE_403)) == 0)) + *invalid = 1; + return val & 7; +} + +/* The TBR field in an XFX instruction. This is just like SPR, but it + is optional. When TBR is omitted, it must be inserted as 268 (the + magic number of the TB register). These functions treat 0 + (indicating an omitted optional operand) as 268. This means that + ``mftb 4,0'' is not handled correctly. This does not matter very + much, since the architecture manual does not define mftb as + accepting any values other than 268 or 269. */ + +#define TB (268) + +static unsigned long +insert_tbr(unsigned long insn, + long value, + int dialect ATTRIBUTE_UNUSED, + const char** errmsg ATTRIBUTE_UNUSED) +{ + if (value == 0) + value = TB; + return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6); +} + +static long +extract_tbr(unsigned long insn, + int dialect ATTRIBUTE_UNUSED, + int* invalid ATTRIBUTE_UNUSED) +{ + long ret; + + ret = ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0); + if (ret == TB) + ret = 0; + return ret; +} + +/* The VD128 or VS128 field in an VX128 form instruction. This is split. */ + +static unsigned long +insert_vds128 (unsigned long insn, + long value, + int dialect ATTRIBUTE_UNUSED, + const char **errmsg ATTRIBUTE_UNUSED) +{ + + return insn | ((value & 0x60) >> 3) | ((value & 0x1f) << 21); +} + +static long +extract_vds128 (unsigned long insn, + int dialect ATTRIBUTE_UNUSED, + int *invalid ATTRIBUTE_UNUSED) +{ + return ((insn << 3) & 0x60) | ((insn >> 21) & 0x1f); +} + +/* The VA128 field in an VX128 form instruction. This is split. */ + +static unsigned long +insert_va128 (unsigned long insn, + long value, + int dialect ATTRIBUTE_UNUSED, + const char **errmsg ATTRIBUTE_UNUSED) +{ + return insn | ((value & 0x40) << 4) | (value & 0x20) + | ((value & 0x1f) << 16); +} + +static long +extract_va128 (unsigned long insn, + int dialect ATTRIBUTE_UNUSED, + int *invalid ATTRIBUTE_UNUSED) +{ + return ((insn >> 4) & 0x40) | (insn & 0x20) | ((insn >> 16) & 0x1f); +} + +/* The VB128 field in an VX128 form instruction. This is split. */ + +static unsigned long +insert_vb128 (unsigned long insn, + long value, + int dialect ATTRIBUTE_UNUSED, + const char **errmsg ATTRIBUTE_UNUSED) +{ + return insn | ((value & 0x60) >> 5) | ((value & 0x1f) << 11); +} + +static long +extract_vb128 (unsigned long insn, + int dialect ATTRIBUTE_UNUSED, + int *invalid ATTRIBUTE_UNUSED) +{ + return ((insn << 5) & 0x60) | ((insn >> 11) & 0x1f); +} + +/* The VPERM field in an VX128 form instruction. This is split. */ + +static unsigned long +insert_vperm (unsigned long insn, + long value, + int dialect ATTRIBUTE_UNUSED, + const char **errmsg ATTRIBUTE_UNUSED) +{ + return insn | ((value & 0xe0) << 1) | ((value & 0x1f) << 16); +} + +static long +extract_vperm (unsigned long insn, + int dialect ATTRIBUTE_UNUSED, + int *invalid ATTRIBUTE_UNUSED) +{ + return ((insn >> 1) & 0xe0) | ((insn >> 16) & 0x1f); +} + + +/* Macros used to form opcodes. */ + +/* The main opcode. */ +#define OP(x) ((((unsigned long)(x)) & 0x3f) << 26) +#define OP_MASK OP (0x3f) + +/* The main opcode combined with a trap code in the TO field of a D + form instruction. Used for extended mnemonics for the trap + instructions. */ +#define OPTO(x,to) (OP (x) | ((((unsigned long)(to)) & 0x1f) << 21)) +#define OPTO_MASK (OP_MASK | TO_MASK) + + /* The main opcode combined with a comparison size bit in the L field + of a D form or X form instruction. Used for extended mnemonics for + the comparison instructions. */ +#define OPL(x,l) (OP (x) | ((((unsigned long)(l)) & 1) << 21)) +#define OPL_MASK OPL (0x3f,1) + + /* An A form instruction. */ +#define A(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x1f) << 1) | (((unsigned long)(rc)) & 1)) +#define A_MASK A (0x3f, 0x1f, 1) + +/* An A_MASK with the FRB field fixed. */ +#define AFRB_MASK (A_MASK | FRB_MASK) + +/* An A_MASK with the FRC field fixed. */ +#define AFRC_MASK (A_MASK | FRC_MASK) + +/* An A_MASK with the FRA and FRC fields fixed. */ +#define AFRAFRC_MASK (A_MASK | FRA_MASK | FRC_MASK) + +/* An AFRAFRC_MASK, but with L bit clear. */ +#define AFRALFRC_MASK (AFRAFRC_MASK & ~((unsigned long) 1 << 16)) + +/* A B form instruction. */ +#define B(op, aa, lk) (OP (op) | ((((unsigned long)(aa)) & 1) << 1) | ((lk) & 1)) +#define B_MASK B (0x3f, 1, 1) + +/* A B form instruction setting the BO field. */ +#define BBO(op, bo, aa, lk) (B ((op), (aa), (lk)) | ((((unsigned long)(bo)) & 0x1f) << 21)) +#define BBO_MASK BBO (0x3f, 0x1f, 1, 1) + +/* A BBO_MASK with the y bit of the BO field removed. This permits + matching a conditional branch regardless of the setting of the y + bit. Similarly for the 'at' bits used for power4 branch hints. */ +#define Y_MASK (((unsigned long) 1) << 21) +#define AT1_MASK (((unsigned long) 3) << 21) +#define AT2_MASK (((unsigned long) 9) << 21) +#define BBOY_MASK (BBO_MASK &~ Y_MASK) +#define BBOAT_MASK (BBO_MASK &~ AT1_MASK) + + /* A B form instruction setting the BO field and the condition bits of + the BI field. */ +#define BBOCB(op, bo, cb, aa, lk) \ + (BBO ((op), (bo), (aa), (lk)) | ((((unsigned long)(cb)) & 0x3) << 16)) +#define BBOCB_MASK BBOCB (0x3f, 0x1f, 0x3, 1, 1) + + /* A BBOCB_MASK with the y bit of the BO field removed. */ +#define BBOYCB_MASK (BBOCB_MASK &~ Y_MASK) +#define BBOATCB_MASK (BBOCB_MASK &~ AT1_MASK) +#define BBOAT2CB_MASK (BBOCB_MASK &~ AT2_MASK) + +/* A BBOYCB_MASK in which the BI field is fixed. */ +#define BBOYBI_MASK (BBOYCB_MASK | BI_MASK) +#define BBOATBI_MASK (BBOAT2CB_MASK | BI_MASK) + +/* An Context form instruction. */ +#define CTX(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x7)) +#define CTX_MASK CTX(0x3f, 0x7) + +/* An User Context form instruction. */ +#define UCTX(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x1f)) +#define UCTX_MASK UCTX(0x3f, 0x1f) + +/* The main opcode mask with the RA field clear. */ +#define DRA_MASK (OP_MASK | RA_MASK) + +/* A DS form instruction. */ +#define DSO(op, xop) (OP (op) | ((xop) & 0x3)) +#define DS_MASK DSO (0x3f, 3) + +/* A DE form instruction. */ +#define DEO(op, xop) (OP (op) | ((xop) & 0xf)) +#define DE_MASK DEO (0x3e, 0xf) + +/* An EVSEL form instruction. */ +#define EVSEL(op, xop) (OP (op) | (((unsigned long)(xop)) & 0xff) << 3) +#define EVSEL_MASK EVSEL(0x3f, 0xff) + +/* An M form instruction. */ +#define M(op, rc) (OP (op) | ((rc) & 1)) +#define M_MASK M (0x3f, 1) + +/* An M form instruction with the ME field specified. */ +#define MME(op, me, rc) (M ((op), (rc)) | ((((unsigned long)(me)) & 0x1f) << 1)) + +/* An M_MASK with the MB and ME fields fixed. */ +#define MMBME_MASK (M_MASK | MB_MASK | ME_MASK) + +/* An M_MASK with the SH and ME fields fixed. */ +#define MSHME_MASK (M_MASK | SH_MASK | ME_MASK) + +/* An MD form instruction. */ +#define MD(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x7) << 2) | ((rc) & 1)) +#define MD_MASK MD (0x3f, 0x7, 1) + +/* An MD_MASK with the MB field fixed. */ +#define MDMB_MASK (MD_MASK | MB6_MASK) + +/* An MD_MASK with the SH field fixed. */ +#define MDSH_MASK (MD_MASK | SH6_MASK) + +/* An MDS form instruction. */ +#define MDS(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0xf) << 1) | ((rc) & 1)) +#define MDS_MASK MDS (0x3f, 0xf, 1) + +/* An MDS_MASK with the MB field fixed. */ +#define MDSMB_MASK (MDS_MASK | MB6_MASK) + +/* An SC form instruction. */ +#define SC(op, sa, lk) (OP (op) | ((((unsigned long)(sa)) & 1) << 1) | ((lk) & 1)) +#define SC_MASK (OP_MASK | (((unsigned long)0x3ff) << 16) | (((unsigned long)1) << 1) | 1) + +/* An VX form instruction. */ +#define VX(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x7ff)) + +/* The mask for an VX form instruction. */ +#define VX_MASK VX(0x3f, 0x7ff) + +/* An VA form instruction. */ +#define VXA(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x03f)) + +/* The mask for an VA form instruction. */ +#define VXA_MASK VXA(0x3f, 0x3f) + +/* An VXR form instruction. */ +#define VXR(op, xop, rc) (OP (op) | (((rc) & 1) << 10) | (((unsigned long)(xop)) & 0x3ff)) + +/* The mask for a VXR form instruction. */ +#define VXR_MASK VXR(0x3f, 0x3ff, 1) + +/* An VX128 form instruction. */ +#define VX128(op, xop) (OP(op) | (((unsigned long)(xop)) & 0x3d0)) + +/* The mask for an VX form instruction. */ +#define VX128_MASK VX(0x3f, 0x3d0) + +/* An VX128 form instruction. */ +#define VX128_1(op, xop) (OP(op) | (((unsigned long)(xop)) & 0x7f3)) + +/* The mask for an VX form instruction. */ +#define VX128_1_MASK VX(0x3f, 0x7f3) + +/* An VX128 form instruction. */ +#define VX128_2(op, xop) (OP(op) | (((unsigned long)(xop)) & 0x210)) + +/* The mask for an VX form instruction. */ +#define VX128_2_MASK VX(0x3f, 0x210) + +/* An VX128 form instruction. */ +#define VX128_3(op, xop) (OP(op) | (((unsigned long)(xop)) & 0x7f0)) + +/* The mask for an VX form instruction. */ +#define VX128_3_MASK VX(0x3f, 0x7f0) + +#define VX128_P(op, xop) (OP(op) | (((unsigned long)(xop)) & 0x630)) +#define VX128_P_MASK VX(0x3f, 0x630) + +#define VX128_4(op, xop) (OP(op) | (((unsigned long)(xop)) & 0x730)) +#define VX128_4_MASK VX(0x3f, 0x730) + +#define VX128_5(op, xop) (OP(op) | (((unsigned long)(xop)) & 0x10)) +#define VX128_5_MASK VX(0x3f, 0x10) + +/* An X form instruction. */ +#define X(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1)) + +/* A Z form instruction. */ +#define Z(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 1)) + +/* An X form instruction with the RC bit specified. */ +#define XRC(op, xop, rc) (X ((op), (xop)) | ((rc) & 1)) + +/* A Z form instruction with the RC bit specified. */ +#define ZRC(op, xop, rc) (Z ((op), (xop)) | ((rc) & 1)) + +/* The mask for an X form instruction. */ +#define X_MASK XRC (0x3f, 0x3ff, 1) + +/* The mask for a Z form instruction. */ +#define Z_MASK ZRC (0x3f, 0x1ff, 1) +#define Z2_MASK ZRC (0x3f, 0xff, 1) + +/* An X_MASK with the RA field fixed. */ +#define XRA_MASK (X_MASK | RA_MASK) + +/* An XRA_MASK with the W field clear. */ +#define XWRA_MASK (XRA_MASK & ~((unsigned long) 1 << 16)) + +/* An X_MASK with the RB field fixed. */ +#define XRB_MASK (X_MASK | RB_MASK) + +/* An X_MASK with the RT field fixed. */ +#define XRT_MASK (X_MASK | RT_MASK) + +/* An XRT_MASK mask with the L bits clear. */ +#define XLRT_MASK (XRT_MASK & ~((unsigned long) 0x3 << 21)) + +/* An X_MASK with the RA and RB fields fixed. */ +#define XRARB_MASK (X_MASK | RA_MASK | RB_MASK) + +/* An XRARB_MASK, but with the L bit clear. */ +#define XRLARB_MASK (XRARB_MASK & ~((unsigned long) 1 << 16)) + +/* An X_MASK with the RT and RA fields fixed. */ +#define XRTRA_MASK (X_MASK | RT_MASK | RA_MASK) + +/* An XRTRA_MASK, but with L bit clear. */ +#define XRTLRA_MASK (XRTRA_MASK & ~((unsigned long) 1 << 21)) + +/* An X form instruction with the L bit specified. */ +#define XOPL(op, xop, l) (X ((op), (xop)) | ((((unsigned long)(l)) & 1) << 21)) + +/* The mask for an X form comparison instruction. */ +#define XCMP_MASK (X_MASK | (((unsigned long)1) << 22)) + +/* The mask for an X form comparison instruction with the L field + fixed. */ +#define XCMPL_MASK (XCMP_MASK | (((unsigned long)1) << 21)) + + /* An X form trap instruction with the TO field specified. */ +#define XTO(op, xop, to) (X ((op), (xop)) | ((((unsigned long)(to)) & 0x1f) << 21)) +#define XTO_MASK (X_MASK | TO_MASK) + +/* An X form tlb instruction with the SH field specified. */ +#define XTLB(op, xop, sh) (X ((op), (xop)) | ((((unsigned long)(sh)) & 0x1f) << 11)) +#define XTLB_MASK (X_MASK | SH_MASK) + +/* An X form sync instruction. */ +#define XSYNC(op, xop, l) (X ((op), (xop)) | ((((unsigned long)(l)) & 3) << 21)) + +/* An X form sync instruction with everything filled in except the LS field. */ +#define XSYNC_MASK (0xff9fffff) + +/* An X_MASK, but with the EH bit clear. */ +#define XEH_MASK (X_MASK & ~((unsigned long )1)) + +/* An X form AltiVec dss instruction. */ +#define XDSS(op, xop, a) (X ((op), (xop)) | ((((unsigned long)(a)) & 1) << 25)) +#define XDSS_MASK XDSS(0x3f, 0x3ff, 1) + +/* An XFL form instruction. */ +#define XFL(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1) | (((unsigned long)(rc)) & 1)) +#define XFL_MASK XFL (0x3f, 0x3ff, 1) + +/* An X form isel instruction. */ +#define XISEL(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x1f) << 1)) +#define XISEL_MASK XISEL(0x3f, 0x1f) + +/* An XL form instruction with the LK field set to 0. */ +#define XL(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1)) + +/* An XL form instruction which uses the LK field. */ +#define XLLK(op, xop, lk) (XL ((op), (xop)) | ((lk) & 1)) + +/* The mask for an XL form instruction. */ +#define XL_MASK XLLK (0x3f, 0x3ff, 1) + +/* An XL form instruction which explicitly sets the BO field. */ +#define XLO(op, bo, xop, lk) \ + (XLLK ((op), (xop), (lk)) | ((((unsigned long)(bo)) & 0x1f) << 21)) +#define XLO_MASK (XL_MASK | BO_MASK) + +/* An XL form instruction which explicitly sets the y bit of the BO + field. */ +#define XLYLK(op, xop, y, lk) (XLLK ((op), (xop), (lk)) | ((((unsigned long)(y)) & 1) << 21)) +#define XLYLK_MASK (XL_MASK | Y_MASK) + + /* An XL form instruction which sets the BO field and the condition + bits of the BI field. */ +#define XLOCB(op, bo, cb, xop, lk) \ + (XLO ((op), (bo), (xop), (lk)) | ((((unsigned long)(cb)) & 3) << 16)) +#define XLOCB_MASK XLOCB (0x3f, 0x1f, 0x3, 0x3ff, 1) + + /* An XL_MASK or XLYLK_MASK or XLOCB_MASK with the BB field fixed. */ +#define XLBB_MASK (XL_MASK | BB_MASK) +#define XLYBB_MASK (XLYLK_MASK | BB_MASK) +#define XLBOCBBB_MASK (XLOCB_MASK | BB_MASK) + +/* A mask for branch instructions using the BH field. */ +#define XLBH_MASK (XL_MASK | (0x1c << 11)) + +/* An XL_MASK with the BO and BB fields fixed. */ +#define XLBOBB_MASK (XL_MASK | BO_MASK | BB_MASK) + +/* An XL_MASK with the BO, BI and BB fields fixed. */ +#define XLBOBIBB_MASK (XL_MASK | BO_MASK | BI_MASK | BB_MASK) + +/* An XO form instruction. */ +#define XO(op, xop, oe, rc) \ + (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 1) | ((((unsigned long)(oe)) & 1) << 10) | (((unsigned long)(rc)) & 1)) +#define XO_MASK XO (0x3f, 0x1ff, 1, 1) + +/* An XO_MASK with the RB field fixed. */ +#define XORB_MASK (XO_MASK | RB_MASK) + +/* An XS form instruction. */ +#define XS(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 2) | (((unsigned long)(rc)) & 1)) +#define XS_MASK XS (0x3f, 0x1ff, 1) + +/* A mask for the FXM version of an XFX form instruction. */ +#define XFXFXM_MASK (X_MASK | (1 << 11) | (1 << 20)) + +/* An XFX form instruction with the FXM field filled in. */ +#define XFXM(op, xop, fxm, p4) \ + (X ((op), (xop)) | ((((unsigned long)(fxm)) & 0xff) << 12) \ + | ((unsigned long)(p4) << 20)) + +/* An XFX form instruction with the SPR field filled in. */ +#define XSPR(op, xop, spr) \ + (X ((op), (xop)) | ((((unsigned long)(spr)) & 0x1f) << 16) | ((((unsigned long)(spr)) & 0x3e0) << 6)) +#define XSPR_MASK (X_MASK | SPR_MASK) + +/* An XFX form instruction with the SPR field filled in except for the + SPRBAT field. */ +#define XSPRBAT_MASK (XSPR_MASK &~ SPRBAT_MASK) + + /* An XFX form instruction with the SPR field filled in except for the + SPRG field. */ +#define XSPRG_MASK (XSPR_MASK & ~(0x1f << 16)) + + /* An X form instruction with everything filled in except the E field. */ +#define XE_MASK (0xffff7fff) + +/* An X form user context instruction. */ +#define XUC(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x1f)) +#define XUC_MASK XUC(0x3f, 0x1f) + +/* The BO encodings used in extended conditional branch mnemonics. */ +#define BODNZF (0x0) +#define BODNZFP (0x1) +#define BODZF (0x2) +#define BODZFP (0x3) +#define BODNZT (0x8) +#define BODNZTP (0x9) +#define BODZT (0xa) +#define BODZTP (0xb) + +#define BOF (0x4) +#define BOFP (0x5) +#define BOFM4 (0x6) +#define BOFP4 (0x7) +#define BOT (0xc) +#define BOTP (0xd) +#define BOTM4 (0xe) +#define BOTP4 (0xf) + +#define BODNZ (0x10) +#define BODNZP (0x11) +#define BODZ (0x12) +#define BODZP (0x13) +#define BODNZM4 (0x18) +#define BODNZP4 (0x19) +#define BODZM4 (0x1a) +#define BODZP4 (0x1b) + +#define BOU (0x14) + +/* The BI condition bit encodings used in extended conditional branch + mnemonics. */ +#define CBLT (0) +#define CBGT (1) +#define CBEQ (2) +#define CBSO (3) + + /* The TO encodings used in extended trap mnemonics. */ +#define TOLGT (0x1) +#define TOLLT (0x2) +#define TOEQ (0x4) +#define TOLGE (0x5) +#define TOLNL (0x5) +#define TOLLE (0x6) +#define TOLNG (0x6) +#define TOGT (0x8) +#define TOGE (0xc) +#define TONL (0xc) +#define TOLT (0x10) +#define TOLE (0x14) +#define TONG (0x14) +#define TONE (0x18) +#define TOU (0x1f) + +/* Smaller names for the flags so each entry in the opcodes table will + fit on a single line. */ +#undef PPC +#define PPC PPC_OPCODE_PPC +#define PPCCOM PPC_OPCODE_PPC | PPC_OPCODE_COMMON +#define NOPOWER4 PPC_OPCODE_NOPOWER4 | PPCCOM +#define POWER4 PPC_OPCODE_POWER4 +#define POWER5 PPC_OPCODE_POWER5 +#define POWER6 PPC_OPCODE_POWER6 +#define CELL PPC_OPCODE_CELL +#define PPC32 PPC_OPCODE_32 | PPC_OPCODE_PPC +#define PPC64 PPC_OPCODE_64 | PPC_OPCODE_PPC +#define PPC403 PPC_OPCODE_403 +#define PPC405 PPC403 +#define PPC440 PPC_OPCODE_440 +#define PPC750 PPC +#define PPC860 PPC +#define PPCVEC PPC_OPCODE_ALTIVEC +#define PPCVEC128 PPC_OPCODE_VMX_128 +#define POWER PPC_OPCODE_POWER +#define POWER2 PPC_OPCODE_POWER | PPC_OPCODE_POWER2 +#define PPCPWR2 PPC_OPCODE_PPC | PPC_OPCODE_POWER | PPC_OPCODE_POWER2 +#define POWER32 PPC_OPCODE_POWER | PPC_OPCODE_32 +#define COM PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON +#define COM32 PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_32 +#define M601 PPC_OPCODE_POWER | PPC_OPCODE_601 +#define PWRCOM PPC_OPCODE_POWER | PPC_OPCODE_601 | PPC_OPCODE_COMMON +#define MFDEC1 PPC_OPCODE_POWER +#define MFDEC2 PPC_OPCODE_PPC | PPC_OPCODE_601 | PPC_OPCODE_BOOKE +#define BOOKE PPC_OPCODE_BOOKE +#define BOOKE64 PPC_OPCODE_BOOKE64 +#define CLASSIC PPC_OPCODE_CLASSIC +#define PPCE300 PPC_OPCODE_E300 +#define PPCSPE PPC_OPCODE_SPE +#define PPCISEL PPC_OPCODE_ISEL +#define PPCEFS PPC_OPCODE_EFS +#define PPCBRLK PPC_OPCODE_BRLOCK +#define PPCPMR PPC_OPCODE_PMR +#define PPCCHLK PPC_OPCODE_CACHELCK +#define PPCCHLK64 PPC_OPCODE_CACHELCK | PPC_OPCODE_BOOKE64 +#define PPCRFMCI PPC_OPCODE_RFMCI + + /* The opcode table. + + The format of the opcode table is: + + NAME OPCODE MASK FLAGS { OPERANDS } + + NAME is the name of the instruction. + OPCODE is the instruction opcode. + MASK is the opcode mask; this is used to tell the disassembler + which bits in the actual opcode must match OPCODE. + FLAGS are flags indicated what processors support the instruction. + OPERANDS is the list of operands. + + The disassembler reads the table in order and prints the first + instruction which matches, so this table is sorted to put more + specific instructions before more general instructions. It is also + sorted by major opcode. */ + +const struct powerpc_opcode powerpc_opcodes[] = { +{ "attn", X(0,256), X_MASK, POWER4, { 0 }, PPC_INST_ATTN }, +{ "tdlgti", OPTO(2,TOLGT), OPTO_MASK, PPC64, { RA, SI }, PPC_INST_TDLGTI }, +{ "tdllti", OPTO(2,TOLLT), OPTO_MASK, PPC64, { RA, SI }, PPC_INST_TDLLTI }, +{ "tdeqi", OPTO(2,TOEQ), OPTO_MASK, PPC64, { RA, SI }, PPC_INST_TDEQI }, +{ "tdlgei", OPTO(2,TOLGE), OPTO_MASK, PPC64, { RA, SI }, PPC_INST_TDLGEI }, +{ "tdlnli", OPTO(2,TOLNL), OPTO_MASK, PPC64, { RA, SI }, PPC_INST_TDLNLI }, +{ "tdllei", OPTO(2,TOLLE), OPTO_MASK, PPC64, { RA, SI }, PPC_INST_TDLLEI }, +{ "tdlngi", OPTO(2,TOLNG), OPTO_MASK, PPC64, { RA, SI }, PPC_INST_TDLNGI }, +{ "tdgti", OPTO(2,TOGT), OPTO_MASK, PPC64, { RA, SI }, PPC_INST_TDGTI }, +{ "tdgei", OPTO(2,TOGE), OPTO_MASK, PPC64, { RA, SI }, PPC_INST_TDGEI }, +{ "tdnli", OPTO(2,TONL), OPTO_MASK, PPC64, { RA, SI }, PPC_INST_TDNLI }, +{ "tdlti", OPTO(2,TOLT), OPTO_MASK, PPC64, { RA, SI }, PPC_INST_TDLTI }, +{ "tdlei", OPTO(2,TOLE), OPTO_MASK, PPC64, { RA, SI }, PPC_INST_TDLEI }, +{ "tdngi", OPTO(2,TONG), OPTO_MASK, PPC64, { RA, SI }, PPC_INST_TDNGI }, +{ "tdnei", OPTO(2,TONE), OPTO_MASK, PPC64, { RA, SI }, PPC_INST_TDNEI }, +{ "tdi", OP(2), OP_MASK, PPC64, { TO, RA, SI }, PPC_INST_TDI }, + +{ "twlgti", OPTO(3,TOLGT), OPTO_MASK, PPCCOM, { RA, SI }, PPC_INST_TWLGTI }, +{ "tlgti", OPTO(3,TOLGT), OPTO_MASK, PWRCOM, { RA, SI }, PPC_INST_TLGTI }, +{ "twllti", OPTO(3,TOLLT), OPTO_MASK, PPCCOM, { RA, SI }, PPC_INST_TWLLTI }, +{ "tllti", OPTO(3,TOLLT), OPTO_MASK, PWRCOM, { RA, SI }, PPC_INST_TLLTI }, +{ "tweqi", OPTO(3,TOEQ), OPTO_MASK, PPCCOM, { RA, SI }, PPC_INST_TWEQI }, +{ "teqi", OPTO(3,TOEQ), OPTO_MASK, PWRCOM, { RA, SI }, PPC_INST_TEQI }, +{ "twlgei", OPTO(3,TOLGE), OPTO_MASK, PPCCOM, { RA, SI }, PPC_INST_TWLGEI }, +{ "tlgei", OPTO(3,TOLGE), OPTO_MASK, PWRCOM, { RA, SI }, PPC_INST_TLGEI }, +{ "twlnli", OPTO(3,TOLNL), OPTO_MASK, PPCCOM, { RA, SI }, PPC_INST_TWLNLI }, +{ "tlnli", OPTO(3,TOLNL), OPTO_MASK, PWRCOM, { RA, SI }, PPC_INST_TLNLI }, +{ "twllei", OPTO(3,TOLLE), OPTO_MASK, PPCCOM, { RA, SI }, PPC_INST_TWLLEI }, +{ "tllei", OPTO(3,TOLLE), OPTO_MASK, PWRCOM, { RA, SI }, PPC_INST_TLLEI }, +{ "twlngi", OPTO(3,TOLNG), OPTO_MASK, PPCCOM, { RA, SI }, PPC_INST_TWLNGI }, +{ "tlngi", OPTO(3,TOLNG), OPTO_MASK, PWRCOM, { RA, SI }, PPC_INST_TLNGI }, +{ "twgti", OPTO(3,TOGT), OPTO_MASK, PPCCOM, { RA, SI }, PPC_INST_TWGTI }, +{ "tgti", OPTO(3,TOGT), OPTO_MASK, PWRCOM, { RA, SI }, PPC_INST_TGTI }, +{ "twgei", OPTO(3,TOGE), OPTO_MASK, PPCCOM, { RA, SI }, PPC_INST_TWGEI }, +{ "tgei", OPTO(3,TOGE), OPTO_MASK, PWRCOM, { RA, SI }, PPC_INST_TGEI }, +{ "twnli", OPTO(3,TONL), OPTO_MASK, PPCCOM, { RA, SI }, PPC_INST_TWNLI }, +{ "tnli", OPTO(3,TONL), OPTO_MASK, PWRCOM, { RA, SI }, PPC_INST_TNLI }, +{ "twlti", OPTO(3,TOLT), OPTO_MASK, PPCCOM, { RA, SI }, PPC_INST_TWLTI }, +{ "tlti", OPTO(3,TOLT), OPTO_MASK, PWRCOM, { RA, SI }, PPC_INST_TLTI }, +{ "twlei", OPTO(3,TOLE), OPTO_MASK, PPCCOM, { RA, SI }, PPC_INST_TWLEI }, +{ "tlei", OPTO(3,TOLE), OPTO_MASK, PWRCOM, { RA, SI }, PPC_INST_TLEI }, +{ "twngi", OPTO(3,TONG), OPTO_MASK, PPCCOM, { RA, SI }, PPC_INST_TWNGI }, +{ "tngi", OPTO(3,TONG), OPTO_MASK, PWRCOM, { RA, SI }, PPC_INST_TNGI }, +{ "twnei", OPTO(3,TONE), OPTO_MASK, PPCCOM, { RA, SI }, PPC_INST_TWNEI }, +{ "tnei", OPTO(3,TONE), OPTO_MASK, PWRCOM, { RA, SI }, PPC_INST_TNEI }, +{ "twi", OP(3), OP_MASK, PPCCOM, { TO, RA, SI }, PPC_INST_TWI }, +{ "ti", OP(3), OP_MASK, PWRCOM, { TO, RA, SI }, PPC_INST_TI }, + +{ "macchw", XO(4,172,0,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACCHW }, +{ "macchw.", XO(4,172,0,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACCHW }, +{ "macchwo", XO(4,172,1,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACCHWO }, +{ "macchwo.", XO(4,172,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACCHWO }, +{ "macchws", XO(4,236,0,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACCHWS }, +{ "macchws.", XO(4,236,0,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACCHWS }, +{ "macchwso", XO(4,236,1,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACCHWSO }, +{ "macchwso.", XO(4,236,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACCHWSO }, +{ "macchwsu", XO(4,204,0,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACCHWSU }, +{ "macchwsu.", XO(4,204,0,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACCHWSU }, +{ "macchwsuo", XO(4,204,1,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACCHWSUO }, +{ "macchwsuo.", XO(4,204,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACCHWSUO }, +{ "macchwu", XO(4,140,0,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACCHWU }, +{ "macchwu.", XO(4,140,0,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACCHWU }, +{ "macchwuo", XO(4,140,1,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACCHWUO }, +{ "macchwuo.", XO(4,140,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACCHWUO }, +{ "machhw", XO(4,44,0,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACHHW }, +{ "machhw.", XO(4,44,0,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACHHW }, +{ "machhwo", XO(4,44,1,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACHHWO }, +{ "machhwo.", XO(4,44,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACHHWO }, +{ "machhws", XO(4,108,0,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACHHWS }, +{ "machhws.", XO(4,108,0,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACHHWS }, +{ "machhwso", XO(4,108,1,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACHHWSO }, +{ "machhwso.", XO(4,108,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACHHWSO }, +{ "machhwsu", XO(4,76,0,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACHHWSU }, +{ "machhwsu.", XO(4,76,0,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACHHWSU }, +{ "machhwsuo", XO(4,76,1,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACHHWSUO }, +{ "machhwsuo.", XO(4,76,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACHHWSUO }, +{ "machhwu", XO(4,12,0,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACHHWU }, +{ "machhwu.", XO(4,12,0,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACHHWU }, +{ "machhwuo", XO(4,12,1,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACHHWUO }, +{ "machhwuo.", XO(4,12,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACHHWUO }, +{ "maclhw", XO(4,428,0,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACLHW }, +{ "maclhw.", XO(4,428,0,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACLHW }, +{ "maclhwo", XO(4,428,1,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACLHWO }, +{ "maclhwo.", XO(4,428,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACLHWO }, +{ "maclhws", XO(4,492,0,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACLHWS }, +{ "maclhws.", XO(4,492,0,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACLHWS }, +{ "maclhwso", XO(4,492,1,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACLHWSO }, +{ "maclhwso.", XO(4,492,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACLHWSO }, +{ "maclhwsu", XO(4,460,0,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACLHWSU }, +{ "maclhwsu.", XO(4,460,0,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACLHWSU }, +{ "maclhwsuo", XO(4,460,1,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACLHWSUO }, +{ "maclhwsuo.", XO(4,460,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACLHWSUO }, +{ "maclhwu", XO(4,396,0,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACLHWU }, +{ "maclhwu.", XO(4,396,0,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACLHWU }, +{ "maclhwuo", XO(4,396,1,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACLHWUO }, +{ "maclhwuo.", XO(4,396,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACLHWUO }, +{ "mulchw", XRC(4,168,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULCHW }, +{ "mulchw.", XRC(4,168,1), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULCHW }, +//{ "mulchwu", XRC(4,136,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULCHWU }, +//{ "mulchwu.", XRC(4,136,1), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULCHWU }, +//{ "mulhhw", XRC(4,40,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULHHW }, +//{ "mulhhw.", XRC(4,40,1), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULHHW }, +{ "mulhhwu", XRC(4,8,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULHHWU }, +{ "mulhhwu.", XRC(4,8,1), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULHHWU }, +{ "mullhw", XRC(4,424,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULLHW }, +{ "mullhw.", XRC(4,424,1), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULLHW }, +{ "mullhwu", XRC(4,392,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULLHWU }, +{ "mullhwu.", XRC(4,392,1), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULLHWU }, +{ "nmacchw", XO(4,174,0,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACCHW }, +{ "nmacchw.", XO(4,174,0,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACCHW }, +{ "nmacchwo", XO(4,174,1,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACCHWO }, +{ "nmacchwo.", XO(4,174,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACCHWO }, +{ "nmacchws", XO(4,238,0,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACCHWS }, +{ "nmacchws.", XO(4,238,0,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACCHWS }, +{ "nmacchwso", XO(4,238,1,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACCHWSO }, +{ "nmacchwso.", XO(4,238,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACCHWSO }, +{ "nmachhw", XO(4,46,0,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACHHW }, +{ "nmachhw.", XO(4,46,0,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACHHW }, +{ "nmachhwo", XO(4,46,1,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACHHWO }, +{ "nmachhwo.", XO(4,46,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACHHWO }, +{ "nmachhws", XO(4,110,0,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACHHWS }, +{ "nmachhws.", XO(4,110,0,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACHHWS }, +{ "nmachhwso", XO(4,110,1,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACHHWSO }, +{ "nmachhwso.", XO(4,110,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACHHWSO }, +{ "nmaclhw", XO(4,430,0,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACLHW }, +{ "nmaclhw.", XO(4,430,0,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACLHW }, +{ "nmaclhwo", XO(4,430,1,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACLHWO }, +{ "nmaclhwo.", XO(4,430,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACLHWO }, +{ "nmaclhws", XO(4,494,0,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACLHWS }, +{ "nmaclhws.", XO(4,494,0,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACLHWS }, +{ "nmaclhwso", XO(4,494,1,0), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACLHWSO }, +{ "nmaclhwso.", XO(4,494,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_NMACLHWSO }, +{ "mfvscr", VX(4, 1540), VX_MASK, PPCVEC, { VD }, PPC_INST_MFVSCR }, +{ "mtvscr", VX(4, 1604), VX_MASK, PPCVEC, { VB }, PPC_INST_MTVSCR }, + +/* Double-precision opcodes. */ +/* Some of these conflict with AltiVec, so move them before, since + PPCVEC includes the PPC_OPCODE_PPC set. */ +{ "efscfd", VX(4, 719), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFSCFD }, +{ "efdabs", VX(4, 740), VX_MASK, PPCEFS, { RS, RA }, PPC_INST_EFDABS }, +{ "efdnabs", VX(4, 741), VX_MASK, PPCEFS, { RS, RA }, PPC_INST_EFDNABS }, +{ "efdneg", VX(4, 742), VX_MASK, PPCEFS, { RS, RA }, PPC_INST_EFDNEG }, +{ "efdadd", VX(4, 736), VX_MASK, PPCEFS, { RS, RA, RB }, PPC_INST_EFDADD }, +{ "efdsub", VX(4, 737), VX_MASK, PPCEFS, { RS, RA, RB }, PPC_INST_EFDSUB }, +{ "efdmul", VX(4, 744), VX_MASK, PPCEFS, { RS, RA, RB }, PPC_INST_EFDMUL }, +{ "efddiv", VX(4, 745), VX_MASK, PPCEFS, { RS, RA, RB }, PPC_INST_EFDDIV }, +{ "efdcmpgt", VX(4, 748), VX_MASK, PPCEFS, { CRFD, RA, RB }, PPC_INST_EFDCMPGT }, +{ "efdcmplt", VX(4, 749), VX_MASK, PPCEFS, { CRFD, RA, RB }, PPC_INST_EFDCMPLT }, +{ "efdcmpeq", VX(4, 750), VX_MASK, PPCEFS, { CRFD, RA, RB }, PPC_INST_EFDCMPEQ }, +{ "efdtstgt", VX(4, 764), VX_MASK, PPCEFS, { CRFD, RA, RB }, PPC_INST_EFDTSTGT }, +{ "efdtstlt", VX(4, 765), VX_MASK, PPCEFS, { CRFD, RA, RB }, PPC_INST_EFDTSTLT }, +{ "efdtsteq", VX(4, 766), VX_MASK, PPCEFS, { CRFD, RA, RB }, PPC_INST_EFDTSTEQ }, +{ "efdcfsi", VX(4, 753), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFDCFSI }, +{ "efdcfsid", VX(4, 739), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFDCFSID }, +{ "efdcfui", VX(4, 752), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFDCFUI }, +{ "efdcfuid", VX(4, 738), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFDCFUID }, +{ "efdcfsf", VX(4, 755), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFDCFSF }, +{ "efdcfuf", VX(4, 754), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFDCFUF }, +{ "efdctsi", VX(4, 757), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFDCTSI }, +{ "efdctsidz",VX(4, 747), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFDCTSIDZ }, +{ "efdctsiz", VX(4, 762), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFDCTSIZ }, +{ "efdctui", VX(4, 756), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFDCTUI }, +{ "efdctuidz",VX(4, 746), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFDCTUIDZ }, +{ "efdctuiz", VX(4, 760), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFDCTUIZ }, +{ "efdctsf", VX(4, 759), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFDCTSF }, +{ "efdctuf", VX(4, 758), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFDCTUF }, +{ "efdcfs", VX(4, 751), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFDCFS }, +/* End of double-precision opcodes. */ + +{ "vaddcuw", VX(4, 384), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VADDCUW }, +{ "vaddfp", VX(4, 10), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VADDFP }, +{ "vaddsbs", VX(4, 768), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VADDSBS }, +{ "vaddshs", VX(4, 832), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VADDSHS }, +{ "vaddsws", VX(4, 896), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VADDSWS }, +{ "vaddubm", VX(4, 0), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VADDUBM }, +{ "vaddubs", VX(4, 512), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VADDUBS }, +{ "vadduhm", VX(4, 64), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VADDUHM }, +{ "vadduhs", VX(4, 576), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VADDUHS }, +{ "vadduwm", VX(4, 128), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VADDUWM }, +{ "vadduws", VX(4, 640), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VADDUWS }, +{ "vand", VX(4, 1028), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VAND }, +{ "vandc", VX(4, 1092), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VANDC }, +{ "vavgsb", VX(4, 1282), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VAVGSB }, +{ "vavgsh", VX(4, 1346), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VAVGSH }, +{ "vavgsw", VX(4, 1410), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VAVGSW }, +{ "vavgub", VX(4, 1026), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VAVGUB }, +{ "vavguh", VX(4, 1090), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VAVGUH }, +{ "vavguw", VX(4, 1154), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VAVGUW }, +{ "vcfsx", VX(4, 842), VX_MASK, PPCVEC, { VD, VB, UIMM }, PPC_INST_VCFSX }, +{ "vcfux", VX(4, 778), VX_MASK, PPCVEC, { VD, VB, UIMM }, PPC_INST_VCFUX }, +{ "vcmpbfp", VXR(4, 966, 0), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPBFP }, +{ "vcmpbfp.", VXR(4, 966, 1), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPBFP }, +{ "vcmpeqfp", VXR(4, 198, 0), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPEQFP }, +{ "vcmpeqfp.", VXR(4, 198, 1), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPEQFP }, +{ "vcmpequb", VXR(4, 6, 0), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPEQUB }, +{ "vcmpequb.", VXR(4, 6, 1), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPEQUB }, +{ "vcmpequh", VXR(4, 70, 0), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPEQUH }, +{ "vcmpequh.", VXR(4, 70, 1), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPEQUH }, +{ "vcmpequw", VXR(4, 134, 0), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPEQUW }, +{ "vcmpequw.", VXR(4, 134, 1), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPEQUW }, +{ "vcmpgefp", VXR(4, 454, 0), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPGEFP }, +{ "vcmpgefp.", VXR(4, 454, 1), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPGEFP }, +{ "vcmpgtfp", VXR(4, 710, 0), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPGTFP }, +{ "vcmpgtfp.", VXR(4, 710, 1), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPGTFP }, +{ "vcmpgtsb", VXR(4, 774, 0), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPGTSB }, +{ "vcmpgtsb.", VXR(4, 774, 1), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPGTSB }, +{ "vcmpgtsh", VXR(4, 838, 0), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPGTSH }, +{ "vcmpgtsh.", VXR(4, 838, 1), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPGTSH }, +{ "vcmpgtsw", VXR(4, 902, 0), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPGTSW }, +{ "vcmpgtsw.", VXR(4, 902, 1), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPGTSW }, +{ "vcmpgtub", VXR(4, 518, 0), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPGTUB }, +{ "vcmpgtub.", VXR(4, 518, 1), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPGTUB }, +{ "vcmpgtuh", VXR(4, 582, 0), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPGTUH }, +{ "vcmpgtuh.", VXR(4, 582, 1), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPGTUH }, +{ "vcmpgtuw", VXR(4, 646, 0), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPGTUW }, +{ "vcmpgtuw.", VXR(4, 646, 1), VXR_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VCMPGTUW }, +{ "vctsxs", VX(4, 970), VX_MASK, PPCVEC, { VD, VB, UIMM }, PPC_INST_VCTSXS }, +{ "vctuxs", VX(4, 906), VX_MASK, PPCVEC, { VD, VB, UIMM }, PPC_INST_VCTUXS }, +{ "vexptefp", VX(4, 394), VX_MASK, PPCVEC, { VD, VB }, PPC_INST_VEXPTEFP }, +{ "vlogefp", VX(4, 458), VX_MASK, PPCVEC, { VD, VB }, PPC_INST_VLOGEFP }, +{ "vmaddfp", VXA(4, 46), VXA_MASK, PPCVEC, { VD, VA, VC, VB }, PPC_INST_VMADDFP }, +{ "vmaxfp", VX(4, 1034), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMAXFP }, +{ "vmaxsb", VX(4, 258), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMAXSB }, +{ "vmaxsh", VX(4, 322), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMAXSH }, +{ "vmaxsw", VX(4, 386), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMAXSW }, +{ "vmaxub", VX(4, 2), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMAXUB }, +{ "vmaxuh", VX(4, 66), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMAXUH }, +{ "vmaxuw", VX(4, 130), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMAXUW }, +{ "vmhaddshs", VXA(4, 32), VXA_MASK, PPCVEC, { VD, VA, VB, VC }, PPC_INST_VMHADDSHS }, +{ "vmhraddshs", VXA(4, 33), VXA_MASK, PPCVEC, { VD, VA, VB, VC }, PPC_INST_VMHRADDSHS }, +{ "vminfp", VX(4, 1098), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMINFP }, +{ "vminsb", VX(4, 770), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMINSB }, +{ "vminsh", VX(4, 834), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMINSH }, +{ "vminsw", VX(4, 898), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMINSW }, +{ "vminub", VX(4, 514), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMINUB }, +{ "vminuh", VX(4, 578), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMINUH }, +{ "vminuw", VX(4, 642), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMINUW }, +{ "vmladduhm", VXA(4, 34), VXA_MASK, PPCVEC, { VD, VA, VB, VC }, PPC_INST_VMLADDUHM }, +{ "vmrghb", VX(4, 12), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMRGHB }, +{ "vmrghh", VX(4, 76), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMRGHH }, +{ "vmrghw", VX(4, 140), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMRGHW }, +{ "vmrglb", VX(4, 268), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMRGLB }, +{ "vmrglh", VX(4, 332), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMRGLH }, +{ "vmrglw", VX(4, 396), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMRGLW }, +{ "vmsummbm", VXA(4, 37), VXA_MASK, PPCVEC, { VD, VA, VB, VC }, PPC_INST_VMSUMMBM }, +{ "vmsumshm", VXA(4, 40), VXA_MASK, PPCVEC, { VD, VA, VB, VC }, PPC_INST_VMSUMSHM }, +{ "vmsumshs", VXA(4, 41), VXA_MASK, PPCVEC, { VD, VA, VB, VC }, PPC_INST_VMSUMSHS }, +{ "vmsumubm", VXA(4, 36), VXA_MASK, PPCVEC, { VD, VA, VB, VC }, PPC_INST_VMSUMUBM }, +{ "vmsumuhm", VXA(4, 38), VXA_MASK, PPCVEC, { VD, VA, VB, VC }, PPC_INST_VMSUMUHM }, +{ "vmsumuhs", VXA(4, 39), VXA_MASK, PPCVEC, { VD, VA, VB, VC }, PPC_INST_VMSUMUHS }, +{ "vmulesb", VX(4, 776), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMULESB }, +{ "vmulesh", VX(4, 840), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMULESH }, +{ "vmuleub", VX(4, 520), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMULEUB }, +{ "vmuleuh", VX(4, 584), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMULEUH }, +{ "vmulosb", VX(4, 264), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMULOSB }, +{ "vmulosh", VX(4, 328), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMULOSH }, +{ "vmuloub", VX(4, 8), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMULOUB }, +{ "vmulouh", VX(4, 72), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VMULOUH }, +{ "vnmsubfp", VXA(4, 47), VXA_MASK, PPCVEC, { VD, VA, VC, VB }, PPC_INST_VNMSUBFP }, +{ "vnor", VX(4, 1284), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VNOR }, +{ "vor", VX(4, 1156), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VOR }, +{ "vperm", VXA(4, 43), VXA_MASK, PPCVEC, { VD, VA, VB, VC }, PPC_INST_VPERM }, +{ "vpkpx", VX(4, 782), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VPKPX }, +{ "vpkshss", VX(4, 398), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VPKSHSS }, +{ "vpkshus", VX(4, 270), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VPKSHUS }, +{ "vpkswss", VX(4, 462), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VPKSWSS }, +{ "vpkswus", VX(4, 334), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VPKSWUS }, +{ "vpkuhum", VX(4, 14), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VPKUHUM }, +{ "vpkuhus", VX(4, 142), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VPKUHUS }, +{ "vpkuwum", VX(4, 78), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VPKUWUM }, +{ "vpkuwus", VX(4, 206), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VPKUWUS }, +{ "vrefp", VX(4, 266), VX_MASK, PPCVEC, { VD, VB }, PPC_INST_VREFP }, +{ "vrfim", VX(4, 714), VX_MASK, PPCVEC, { VD, VB }, PPC_INST_VRFIM }, +{ "vrfin", VX(4, 522), VX_MASK, PPCVEC, { VD, VB }, PPC_INST_VRFIN }, +{ "vrfip", VX(4, 650), VX_MASK, PPCVEC, { VD, VB }, PPC_INST_VRFIP }, +{ "vrfiz", VX(4, 586), VX_MASK, PPCVEC, { VD, VB }, PPC_INST_VRFIZ }, +{ "vrlb", VX(4, 4), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VRLB }, +{ "vrlh", VX(4, 68), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VRLH }, +{ "vrlw", VX(4, 132), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VRLW }, +{ "vrsqrtefp", VX(4, 330), VX_MASK, PPCVEC, { VD, VB }, PPC_INST_VRSQRTEFP }, +{ "vsel", VXA(4, 42), VXA_MASK, PPCVEC, { VD, VA, VB, VC }, PPC_INST_VSEL }, +{ "vsl", VX(4, 452), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSL }, +{ "vslb", VX(4, 260), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSLB }, +{ "vsldoi", VXA(4, 44), VXA_MASK, PPCVEC, { VD, VA, VB, SHB }, PPC_INST_VSLDOI }, +{ "vslh", VX(4, 324), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSLH }, +{ "vslo", VX(4, 1036), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSLO }, +{ "vslw", VX(4, 388), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSLW }, +{ "vspltb", VX(4, 524), VX_MASK, PPCVEC, { VD, VB, UIMM }, PPC_INST_VSPLTB }, +{ "vsplth", VX(4, 588), VX_MASK, PPCVEC, { VD, VB, UIMM }, PPC_INST_VSPLTH }, +{ "vspltisb", VX(4, 780), VX_MASK, PPCVEC, { VD, SIMM }, PPC_INST_VSPLTISB }, +{ "vspltish", VX(4, 844), VX_MASK, PPCVEC, { VD, SIMM }, PPC_INST_VSPLTISH }, +{ "vspltisw", VX(4, 908), VX_MASK, PPCVEC, { VD, SIMM }, PPC_INST_VSPLTISW }, +{ "vspltw", VX(4, 652), VX_MASK, PPCVEC, { VD, VB, UIMM }, PPC_INST_VSPLTW }, +{ "vsr", VX(4, 708), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSR }, +{ "vsrab", VX(4, 772), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSRAB }, +{ "vsrah", VX(4, 836), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSRAH }, +{ "vsraw", VX(4, 900), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSRAW }, +{ "vsrb", VX(4, 516), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSRB }, +{ "vsrh", VX(4, 580), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSRH }, +{ "vsro", VX(4, 1100), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSRO }, +{ "vsrw", VX(4, 644), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSRW }, +{ "vsubcuw", VX(4, 1408), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSUBCUW }, +{ "vsubfp", VX(4, 74), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSUBFP }, +{ "vsubsbs", VX(4, 1792), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSUBSBS }, +{ "vsubshs", VX(4, 1856), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSUBSHS }, +{ "vsubsws", VX(4, 1920), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSUBSWS }, +{ "vsububm", VX(4, 1024), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSUBUBM }, +{ "vsububs", VX(4, 1536), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSUBUBS }, +{ "vsubuhm", VX(4, 1088), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSUBUHM }, +{ "vsubuhs", VX(4, 1600), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSUBUHS }, +{ "vsubuwm", VX(4, 1152), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSUBUWM }, +{ "vsubuws", VX(4, 1664), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSUBUWS }, +{ "vsumsws", VX(4, 1928), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSUMSWS }, +{ "vsum2sws", VX(4, 1672), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSUM2SWS }, +{ "vsum4sbs", VX(4, 1800), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSUM4SBS }, +{ "vsum4shs", VX(4, 1608), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSUM4SHS }, +{ "vsum4ubs", VX(4, 1544), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VSUM4UBS }, +{ "vupkhpx", VX(4, 846), VX_MASK, PPCVEC, { VD, VB }, PPC_INST_VUPKHPX }, +{ "vupkhsb", VX(4, 526), VX_MASK, PPCVEC, { VD, VB }, PPC_INST_VUPKHSB }, +{ "vupkhsh", VX(4, 590), VX_MASK, PPCVEC, { VD, VB }, PPC_INST_VUPKHSH }, +{ "vupklpx", VX(4, 974), VX_MASK, PPCVEC, { VD, VB }, PPC_INST_VUPKLPX }, +{ "vupklsb", VX(4, 654), VX_MASK, PPCVEC, { VD, VB }, PPC_INST_VUPKLSB }, +{ "vupklsh", VX(4, 718), VX_MASK, PPCVEC, { VD, VB }, PPC_INST_VUPKLSH }, +{ "vxor", VX(4, 1220), VX_MASK, PPCVEC, { VD, VA, VB }, PPC_INST_VXOR }, + +{ "vsldoi128", VX128_5(4, 16), VX128_5_MASK, PPCVEC128, { VD128, VA128, VB128, SHB }, PPC_INST_VSLDOI128 }, +{ "lvsl128", VX128_1(4, 3), VX128_1_MASK, PPCVEC128, { VD128, RA, RB }, PPC_INST_LVSL128 }, +{ "lvsr128", VX128_1(4, 67), VX128_1_MASK, PPCVEC128, { VD128, RA, RB }, PPC_INST_LVSR128 }, +{ "lvewx128", VX128_1(4, 131), VX128_1_MASK, PPCVEC128, { VD128, RA, RB }, PPC_INST_LVEWX128 }, +{ "lvx128", VX128_1(4, 195), VX128_1_MASK, PPCVEC128, { VD128, RA, RB }, PPC_INST_LVX128 }, +{ "stvewx128", VX128_1(4, 387), VX128_1_MASK, PPCVEC128, { VS128, RA, RB }, PPC_INST_STVEWX128 }, +{ "stvx128", VX128_1(4, 451), VX128_1_MASK, PPCVEC128, { VS128, RA, RB }, PPC_INST_STVX128 }, +{ "lvxl128", VX128_1(4, 707), VX128_1_MASK, PPCVEC128, { VD128, RA, RB }, PPC_INST_LVXL128 }, +{ "stvxl128", VX128_1(4, 963), VX128_1_MASK, PPCVEC128, { VS128, RA, RB }, PPC_INST_STVXL128 }, +{ "lvlx128", VX128_1(4, 1027), VX128_1_MASK, PPCVEC128, { VD128, RA, RB }, PPC_INST_LVLX128 }, +{ "lvrx128", VX128_1(4, 1091), VX128_1_MASK, PPCVEC128, { VD128, RA, RB }, PPC_INST_LVRX128 }, +{ "stvlx128", VX128_1(4, 1283), VX128_1_MASK, PPCVEC128, { VS128, RA, RB }, PPC_INST_STVLX128 }, +{ "stvrx128", VX128_1(4, 1347), VX128_1_MASK, PPCVEC128, { VS128, RA, RB }, PPC_INST_STVRX128 }, +{ "lvlxl128", VX128_1(4, 1539), VX128_1_MASK, PPCVEC128, { VD128, RA, RB }, PPC_INST_LVLXL128 }, +{ "lvrxl128", VX128_1(4, 1603), VX128_1_MASK, PPCVEC128, { VD128, RA, RB }, PPC_INST_LVRXL128 }, +{ "stvlxl128", VX128_1(4, 1795), VX128_1_MASK, PPCVEC128, { VS128, RA, RB }, PPC_INST_STVLXL128 }, +{ "stvrxl128", VX128_1(4, 1859), VX128_1_MASK, PPCVEC128, { VS128, RA, RB }, PPC_INST_STVRXL128 }, + +{ "vperm128", VX128_2(5, 0), VX128_2_MASK, PPCVEC128, { VD128, VA128, VB128, VC128 }, PPC_INST_VPERM128 }, +{ "vaddfp128", VX128(5, 16), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VADDFP128 }, +{ "vsubfp128", VX128(5, 80), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VSUBFP128 }, +{ "vmulfp128", VX128(5, 144), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VMULFP128 }, +{ "vmaddfp128", VX128(5, 208), VX128_MASK, PPCVEC128, { VD128, VA128, VB128, VS128 }, PPC_INST_VMADDFP128 }, +{ "vmaddcfp128", VX128(5, 272), VX128_MASK, PPCVEC128, { VD128, VA128, VS128, VB128 }, PPC_INST_VMADDCFP128 }, +{ "vnmsubfp128", VX128(5, 336), VX128_MASK, PPCVEC128, { VD128, VA128, VB128, VS128 }, PPC_INST_VNMSUBFP128 }, +{ "vmsum3fp128", VX128(5, 400), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VMSUM3FP128 }, +{ "vmsum4fp128", VX128(5, 464), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VMSUM4FP128 }, +{ "vpkshss128", VX128(5, 512), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VPKSHSS128 }, +{ "vand128", VX128(5, 528), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VAND128 }, +{ "vpkshus128", VX128(5, 576), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VPKSHUS128 }, +{ "vandc128", VX128(5, 592), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VANDC128 }, +{ "vpkswss128", VX128(5, 640), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VPKSWSS128 }, +{ "vnor128", VX128(5, 656), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VNOR128 }, +{ "vpkswus128", VX128(5, 704), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VPKSWUS128 }, +{ "vor128", VX128(5, 720), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VOR128 }, +{ "vpkuhum128", VX128(5, 768), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VPKUHUM128 }, +{ "vxor128", VX128(5, 784), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VXOR128 }, +{ "vpkuhus128", VX128(5, 832), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VPKUHUS128 }, +{ "vsel128", VX128(5, 848), VX128_MASK, PPCVEC128, { VD128, VA128, VB128, VS128 }, PPC_INST_VSEL128 }, +{ "vpkuwum128", VX128(5, 896), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VPKUWUM128 }, +{ "vslo128", VX128(5, 912), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VSLO128 }, +{ "vpkuwus128", VX128(5, 960), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VPKUWUS128 }, +{ "vsro128", VX128(5, 976), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VSRO128 }, + +{ "vpermwi128", VX128_P(6, 528), VX128_P_MASK, PPCVEC128, { VD128, VB128, VPERM128 }, PPC_INST_VPERMWI128 }, +{ "vcfpsxws128", VX128_3(6, 560), VX128_3_MASK, PPCVEC128, { VD128, VB128, UIMM }, PPC_INST_VCFPSXWS128 }, +{ "vcfpuxws128", VX128_3(6, 624), VX128_3_MASK, PPCVEC128, { VD128, VB128, UIMM }, PPC_INST_VCFPUXWS128 }, +{ "vcsxwfp128", VX128_3(6, 688), VX128_3_MASK, PPCVEC128, { VD128, VB128, UIMM }, PPC_INST_VCSXWFP128 }, +{ "vcuxwfp128", VX128_3(6, 752), VX128_3_MASK, PPCVEC128, { VD128, VB128, UIMM }, PPC_INST_VCUXWFP128 }, +{ "vrfim128", VX128_3(6, 816), VX128_3_MASK, PPCVEC128, { VD128, VB128 }, PPC_INST_VRFIM128 }, +{ "vrfin128", VX128_3(6, 880), VX128_3_MASK, PPCVEC128, { VD128, VB128 }, PPC_INST_VRFIN128 }, +{ "vrfip128", VX128_3(6, 944), VX128_3_MASK, PPCVEC128, { VD128, VB128 }, PPC_INST_VRFIP128 }, +{ "vrfiz128", VX128_3(6, 1008), VX128_3_MASK, PPCVEC128, { VD128, VB128 }, PPC_INST_VRFIZ128 }, +{ "vpkd3d128", VX128_4(6, 1552), VX128_4_MASK, PPCVEC128, { VD128, VB128, VD3D0, VD3D1, VD3D2 }, PPC_INST_VPKD3D128 }, +{ "vrefp128", VX128_3(6, 1584), VX128_3_MASK, PPCVEC128, { VD128, VB128 }, PPC_INST_VREFP128 }, +{ "vrsqrtefp128", VX128_3(6, 1648), VX128_3_MASK, PPCVEC128, { VD128, VB128 }, PPC_INST_VRSQRTEFP128 }, +{ "vexptefp128", VX128_3(6, 1712), VX128_3_MASK, PPCVEC128, { VD128, VB128 }, PPC_INST_VEXPTEFP128 }, +{ "vlogefp128", VX128_3(6, 1776), VX128_3_MASK, PPCVEC128, { VD128, VB128 }, PPC_INST_VLOGEFP128 }, +{ "vrlimi128", VX128_4(6, 1808), VX128_4_MASK, PPCVEC128, { VD128, VB128, UIMM, VD3D2 }, PPC_INST_VRLIMI128 }, +{ "vspltw128", VX128_3(6, 1840), VX128_3_MASK, PPCVEC128, { VD128, VB128, UIMM }, PPC_INST_VSPLTW128 }, +{ "vspltisw128", VX128_3(6, 1904), VX128_3_MASK, PPCVEC128, { VD128, SIMM }, PPC_INST_VSPLTISW128 }, +{ "vupkd3d128", VX128_3(6, 2032), VX128_3_MASK, PPCVEC128, { VD128, VB128, UIMM }, PPC_INST_VUPKD3D128 }, +{ "vcmpeqfp128", VX128(6, 0), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VCMPEQFP128 }, +{ "vcmpeqfp128.", VX128(6, 64), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VCMPEQFP128 }, +{ "vrlw128", VX128(6, 80), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VRLW128 }, +{ "vcmpgefp128", VX128(6, 128), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VCMPGEFP128 }, +{ "vcmpgefp128.", VX128(6, 192), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VCMPGEFP128 }, +{ "vslw128", VX128(6, 208), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VSLW128 }, +{ "vcmpgtfp128", VX128(6, 256), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VCMPGTFP128 }, +{ "vcmpgtfp128.", VX128(6, 320), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VCMPGTFP128 }, +{ "vsraw128", VX128(6, 336), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VSRAW128 }, +{ "vcmpbfp128", VX128(6, 384), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VCMPBFP128 }, +{ "vcmpbfp128.", VX128(6, 448), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VCMPBFP128 }, +{ "vsrw128", VX128(6, 464), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VSRW128 }, +{ "vcmpequw128", VX128(6, 512), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VCMPEQUW128 }, +{ "vcmpequw128.", VX128(6, 576), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VCMPEQUW128 }, +{ "vmaxfp128", VX128(6, 640), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VMAXFP128 }, +{ "vminfp128", VX128(6, 704), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VMINFP128 }, +{ "vmrghw128", VX128(6, 768), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VMRGHW128 }, +{ "vmrglw128", VX128(6, 832), VX128_MASK, PPCVEC128, { VD128, VA128, VB128 }, PPC_INST_VMRGLW128 }, +{ "vupkhsb128", VX128(6, 896), VX128_MASK, PPCVEC128, { VD128, VB128, VA128 }, PPC_INST_VUPKHSB128 }, +{ "vupklsb128", VX128(6, 960), VX128_MASK, PPCVEC128, { VD128, VB128, VA128 }, PPC_INST_VUPKLSB128 }, +//{ "vupkhsh128", VX128(6, 1952), VX128_MASK, PPCVEC128, { VD128, VB128 }, PPC_INST_VUPKHSH128 }, +//{ "vupklsh128", VX128(6, 2016), VX128_MASK, PPCVEC128, { VD128, VB128 }, PPC_INST_VUPKLSH128 }, + +{ "evaddw", VX(4, 512), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVADDW }, +{ "evaddiw", VX(4, 514), VX_MASK, PPCSPE, { RS, RB, UIMM }, PPC_INST_EVADDIW }, +{ "evsubfw", VX(4, 516), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVSUBFW }, +{ "evsubw", VX(4, 516), VX_MASK, PPCSPE, { RS, RB, RA }, PPC_INST_EVSUBW }, +{ "evsubifw", VX(4, 518), VX_MASK, PPCSPE, { RS, UIMM, RB }, PPC_INST_EVSUBIFW }, +{ "evsubiw", VX(4, 518), VX_MASK, PPCSPE, { RS, RB, UIMM }, PPC_INST_EVSUBIW }, +{ "evabs", VX(4, 520), VX_MASK, PPCSPE, { RS, RA }, PPC_INST_EVABS }, +{ "evneg", VX(4, 521), VX_MASK, PPCSPE, { RS, RA }, PPC_INST_EVNEG }, +{ "evextsb", VX(4, 522), VX_MASK, PPCSPE, { RS, RA }, PPC_INST_EVEXTSB }, +{ "evextsh", VX(4, 523), VX_MASK, PPCSPE, { RS, RA }, PPC_INST_EVEXTSH }, +{ "evrndw", VX(4, 524), VX_MASK, PPCSPE, { RS, RA }, PPC_INST_EVRNDW }, +{ "evcntlzw", VX(4, 525), VX_MASK, PPCSPE, { RS, RA }, PPC_INST_EVCNTLZW }, +{ "evcntlsw", VX(4, 526), VX_MASK, PPCSPE, { RS, RA }, PPC_INST_EVCNTLSW }, + +{ "brinc", VX(4, 527), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_BRINC }, + +{ "evand", VX(4, 529), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVAND }, +{ "evandc", VX(4, 530), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVANDC }, +{ "evmr", VX(4, 535), VX_MASK, PPCSPE, { RS, RA, BBA }, PPC_INST_EVMR }, +{ "evor", VX(4, 535), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVOR }, +{ "evorc", VX(4, 539), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVORC }, +{ "evxor", VX(4, 534), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVXOR }, +{ "eveqv", VX(4, 537), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVEQV }, +{ "evnand", VX(4, 542), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVNAND }, +{ "evnot", VX(4, 536), VX_MASK, PPCSPE, { RS, RA, BBA }, PPC_INST_EVNOT }, +{ "evnor", VX(4, 536), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVNOR }, + +{ "evrlw", VX(4, 552), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVRLW }, +{ "evrlwi", VX(4, 554), VX_MASK, PPCSPE, { RS, RA, EVUIMM }, PPC_INST_EVRLWI }, +{ "evslw", VX(4, 548), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVSLW }, +{ "evslwi", VX(4, 550), VX_MASK, PPCSPE, { RS, RA, EVUIMM }, PPC_INST_EVSLWI }, +{ "evsrws", VX(4, 545), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVSRWS }, +{ "evsrwu", VX(4, 544), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVSRWU }, +{ "evsrwis", VX(4, 547), VX_MASK, PPCSPE, { RS, RA, EVUIMM }, PPC_INST_EVSRWIS }, +{ "evsrwiu", VX(4, 546), VX_MASK, PPCSPE, { RS, RA, EVUIMM }, PPC_INST_EVSRWIU }, +{ "evsplati", VX(4, 553), VX_MASK, PPCSPE, { RS, SIMM }, PPC_INST_EVSPLATI }, +{ "evsplatfi", VX(4, 555), VX_MASK, PPCSPE, { RS, SIMM }, PPC_INST_EVSPLATFI }, +{ "evmergehi", VX(4, 556), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMERGEHI }, +{ "evmergelo", VX(4, 557), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMERGELO }, +{ "evmergehilo",VX(4,558), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMERGEHILO }, +{ "evmergelohi",VX(4,559), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMERGELOHI }, + +{ "evcmpgts", VX(4, 561), VX_MASK, PPCSPE, { CRFD, RA, RB }, PPC_INST_EVCMPGTS }, +{ "evcmpgtu", VX(4, 560), VX_MASK, PPCSPE, { CRFD, RA, RB }, PPC_INST_EVCMPGTU }, +{ "evcmplts", VX(4, 563), VX_MASK, PPCSPE, { CRFD, RA, RB }, PPC_INST_EVCMPLTS }, +{ "evcmpltu", VX(4, 562), VX_MASK, PPCSPE, { CRFD, RA, RB }, PPC_INST_EVCMPLTU }, +{ "evcmpeq", VX(4, 564), VX_MASK, PPCSPE, { CRFD, RA, RB }, PPC_INST_EVCMPEQ }, +{ "evsel", EVSEL(4,79),EVSEL_MASK, PPCSPE, { RS, RA, RB, CRFS }, PPC_INST_EVSEL }, + +{ "evldd", VX(4, 769), VX_MASK, PPCSPE, { RS, EVUIMM_8, RA }, PPC_INST_EVLDD }, +{ "evlddx", VX(4, 768), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVLDDX }, +{ "evldw", VX(4, 771), VX_MASK, PPCSPE, { RS, EVUIMM_8, RA }, PPC_INST_EVLDW }, +{ "evldwx", VX(4, 770), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVLDWX }, +{ "evldh", VX(4, 773), VX_MASK, PPCSPE, { RS, EVUIMM_8, RA }, PPC_INST_EVLDH }, +{ "evldhx", VX(4, 772), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVLDHX }, +{ "evlwhe", VX(4, 785), VX_MASK, PPCSPE, { RS, EVUIMM_4, RA }, PPC_INST_EVLWHE }, +{ "evlwhex", VX(4, 784), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVLWHEX }, +{ "evlwhou", VX(4, 789), VX_MASK, PPCSPE, { RS, EVUIMM_4, RA }, PPC_INST_EVLWHOU }, +{ "evlwhoux", VX(4, 788), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVLWHOUX }, +{ "evlwhos", VX(4, 791), VX_MASK, PPCSPE, { RS, EVUIMM_4, RA }, PPC_INST_EVLWHOS }, +{ "evlwhosx", VX(4, 790), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVLWHOSX }, +{ "evlwwsplat",VX(4, 793), VX_MASK, PPCSPE, { RS, EVUIMM_4, RA }, PPC_INST_EVLWWSPLAT }, +{ "evlwwsplatx",VX(4, 792), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVLWWSPLATX }, +{ "evlwhsplat",VX(4, 797), VX_MASK, PPCSPE, { RS, EVUIMM_4, RA }, PPC_INST_EVLWHSPLAT }, +{ "evlwhsplatx",VX(4, 796), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVLWHSPLATX }, +{ "evlhhesplat",VX(4, 777), VX_MASK, PPCSPE, { RS, EVUIMM_2, RA }, PPC_INST_EVLHHESPLAT }, +{ "evlhhesplatx",VX(4, 776), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVLHHESPLATX }, +{ "evlhhousplat",VX(4, 781), VX_MASK, PPCSPE, { RS, EVUIMM_2, RA }, PPC_INST_EVLHHOUSPLAT }, +{ "evlhhousplatx",VX(4, 780), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVLHHOUSPLATX }, +{ "evlhhossplat",VX(4, 783), VX_MASK, PPCSPE, { RS, EVUIMM_2, RA }, PPC_INST_EVLHHOSSPLAT }, +{ "evlhhossplatx",VX(4, 782), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVLHHOSSPLATX }, + +{ "evstdd", VX(4, 801), VX_MASK, PPCSPE, { RS, EVUIMM_8, RA }, PPC_INST_EVSTDD }, +{ "evstddx", VX(4, 800), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVSTDDX }, +{ "evstdw", VX(4, 803), VX_MASK, PPCSPE, { RS, EVUIMM_8, RA }, PPC_INST_EVSTDW }, +{ "evstdwx", VX(4, 802), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVSTDWX }, +{ "evstdh", VX(4, 805), VX_MASK, PPCSPE, { RS, EVUIMM_8, RA }, PPC_INST_EVSTDH }, +{ "evstdhx", VX(4, 804), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVSTDHX }, +{ "evstwwe", VX(4, 825), VX_MASK, PPCSPE, { RS, EVUIMM_4, RA }, PPC_INST_EVSTWWE }, +{ "evstwwex", VX(4, 824), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVSTWWEX }, +{ "evstwwo", VX(4, 829), VX_MASK, PPCSPE, { RS, EVUIMM_4, RA }, PPC_INST_EVSTWWO }, +{ "evstwwox", VX(4, 828), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVSTWWOX }, +{ "evstwhe", VX(4, 817), VX_MASK, PPCSPE, { RS, EVUIMM_4, RA }, PPC_INST_EVSTWHE }, +{ "evstwhex", VX(4, 816), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVSTWHEX }, +{ "evstwho", VX(4, 821), VX_MASK, PPCSPE, { RS, EVUIMM_4, RA }, PPC_INST_EVSTWHO }, +{ "evstwhox", VX(4, 820), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVSTWHOX }, + +{ "evfsabs", VX(4, 644), VX_MASK, PPCSPE, { RS, RA }, PPC_INST_EVFSABS }, +{ "evfsnabs", VX(4, 645), VX_MASK, PPCSPE, { RS, RA }, PPC_INST_EVFSNABS }, +{ "evfsneg", VX(4, 646), VX_MASK, PPCSPE, { RS, RA }, PPC_INST_EVFSNEG }, +{ "evfsadd", VX(4, 640), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVFSADD }, +{ "evfssub", VX(4, 641), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVFSSUB }, +{ "evfsmul", VX(4, 648), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVFSMUL }, +{ "evfsdiv", VX(4, 649), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVFSDIV }, +{ "evfscmpgt", VX(4, 652), VX_MASK, PPCSPE, { CRFD, RA, RB }, PPC_INST_EVFSCMPGT }, +{ "evfscmplt", VX(4, 653), VX_MASK, PPCSPE, { CRFD, RA, RB }, PPC_INST_EVFSCMPLT }, +{ "evfscmpeq", VX(4, 654), VX_MASK, PPCSPE, { CRFD, RA, RB }, PPC_INST_EVFSCMPEQ }, +{ "evfststgt", VX(4, 668), VX_MASK, PPCSPE, { CRFD, RA, RB }, PPC_INST_EVFSTSTGT }, +{ "evfststlt", VX(4, 669), VX_MASK, PPCSPE, { CRFD, RA, RB }, PPC_INST_EVFSTSTLT }, +{ "evfststeq", VX(4, 670), VX_MASK, PPCSPE, { CRFD, RA, RB }, PPC_INST_EVFSTSTEQ }, +{ "evfscfui", VX(4, 656), VX_MASK, PPCSPE, { RS, RB }, PPC_INST_EVFSCFUI }, +{ "evfsctuiz", VX(4, 664), VX_MASK, PPCSPE, { RS, RB }, PPC_INST_EVFSCTUIZ }, +{ "evfscfsi", VX(4, 657), VX_MASK, PPCSPE, { RS, RB }, PPC_INST_EVFSCFSI }, +{ "evfscfuf", VX(4, 658), VX_MASK, PPCSPE, { RS, RB }, PPC_INST_EVFSCFUF }, +{ "evfscfsf", VX(4, 659), VX_MASK, PPCSPE, { RS, RB }, PPC_INST_EVFSCFSF }, +{ "evfsctui", VX(4, 660), VX_MASK, PPCSPE, { RS, RB }, PPC_INST_EVFSCTUI }, +{ "evfsctsi", VX(4, 661), VX_MASK, PPCSPE, { RS, RB }, PPC_INST_EVFSCTSI }, +{ "evfsctsiz", VX(4, 666), VX_MASK, PPCSPE, { RS, RB }, PPC_INST_EVFSCTSIZ }, +{ "evfsctuf", VX(4, 662), VX_MASK, PPCSPE, { RS, RB }, PPC_INST_EVFSCTUF }, +{ "evfsctsf", VX(4, 663), VX_MASK, PPCSPE, { RS, RB }, PPC_INST_EVFSCTSF }, + +{ "efsabs", VX(4, 708), VX_MASK, PPCEFS, { RS, RA }, PPC_INST_EFSABS }, +{ "efsnabs", VX(4, 709), VX_MASK, PPCEFS, { RS, RA }, PPC_INST_EFSNABS }, +{ "efsneg", VX(4, 710), VX_MASK, PPCEFS, { RS, RA }, PPC_INST_EFSNEG }, +{ "efsadd", VX(4, 704), VX_MASK, PPCEFS, { RS, RA, RB }, PPC_INST_EFSADD }, +{ "efssub", VX(4, 705), VX_MASK, PPCEFS, { RS, RA, RB }, PPC_INST_EFSSUB }, +{ "efsmul", VX(4, 712), VX_MASK, PPCEFS, { RS, RA, RB }, PPC_INST_EFSMUL }, +{ "efsdiv", VX(4, 713), VX_MASK, PPCEFS, { RS, RA, RB }, PPC_INST_EFSDIV }, +{ "efscmpgt", VX(4, 716), VX_MASK, PPCEFS, { CRFD, RA, RB }, PPC_INST_EFSCMPGT }, +{ "efscmplt", VX(4, 717), VX_MASK, PPCEFS, { CRFD, RA, RB }, PPC_INST_EFSCMPLT }, +{ "efscmpeq", VX(4, 718), VX_MASK, PPCEFS, { CRFD, RA, RB }, PPC_INST_EFSCMPEQ }, +{ "efststgt", VX(4, 732), VX_MASK, PPCEFS, { CRFD, RA, RB }, PPC_INST_EFSTSTGT }, +{ "efststlt", VX(4, 733), VX_MASK, PPCEFS, { CRFD, RA, RB }, PPC_INST_EFSTSTLT }, +{ "efststeq", VX(4, 734), VX_MASK, PPCEFS, { CRFD, RA, RB }, PPC_INST_EFSTSTEQ }, +{ "efscfui", VX(4, 720), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFSCFUI }, +{ "efsctuiz", VX(4, 728), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFSCTUIZ }, +{ "efscfsi", VX(4, 721), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFSCFSI }, +{ "efscfuf", VX(4, 722), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFSCFUF }, +{ "efscfsf", VX(4, 723), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFSCFSF }, +{ "efsctui", VX(4, 724), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFSCTUI }, +{ "efsctsi", VX(4, 725), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFSCTSI }, +{ "efsctsiz", VX(4, 730), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFSCTSIZ }, +{ "efsctuf", VX(4, 726), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFSCTUF }, +{ "efsctsf", VX(4, 727), VX_MASK, PPCEFS, { RS, RB }, PPC_INST_EFSCTSF }, + +{ "evmhossf", VX(4, 1031), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOSSF }, +{ "evmhossfa", VX(4, 1063), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOSSFA }, +{ "evmhosmf", VX(4, 1039), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOSMF }, +{ "evmhosmfa", VX(4, 1071), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOSMFA }, +{ "evmhosmi", VX(4, 1037), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOSMI }, +{ "evmhosmia", VX(4, 1069), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOSMIA }, +{ "evmhoumi", VX(4, 1036), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOUMI }, +{ "evmhoumia", VX(4, 1068), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOUMIA }, +{ "evmhessf", VX(4, 1027), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHESSF }, +{ "evmhessfa", VX(4, 1059), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHESSFA }, +{ "evmhesmf", VX(4, 1035), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHESMF }, +{ "evmhesmfa", VX(4, 1067), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHESMFA }, +{ "evmhesmi", VX(4, 1033), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHESMI }, +{ "evmhesmia", VX(4, 1065), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHESMIA }, +{ "evmheumi", VX(4, 1032), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHEUMI }, +{ "evmheumia", VX(4, 1064), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHEUMIA }, + +{ "evmhossfaaw",VX(4, 1287), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOSSFAAW }, +{ "evmhossiaaw",VX(4, 1285), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOSSIAAW }, +{ "evmhosmfaaw",VX(4, 1295), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOSMFAAW }, +{ "evmhosmiaaw",VX(4, 1293), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOSMIAAW }, +{ "evmhousiaaw",VX(4, 1284), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOUSIAAW }, +{ "evmhoumiaaw",VX(4, 1292), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOUMIAAW }, +{ "evmhessfaaw",VX(4, 1283), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHESSFAAW }, +{ "evmhessiaaw",VX(4, 1281), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHESSIAAW }, +{ "evmhesmfaaw",VX(4, 1291), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHESMFAAW }, +{ "evmhesmiaaw",VX(4, 1289), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHESMIAAW }, +{ "evmheusiaaw",VX(4, 1280), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHEUSIAAW }, +{ "evmheumiaaw",VX(4, 1288), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHEUMIAAW }, + +{ "evmhossfanw",VX(4, 1415), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOSSFANW }, +{ "evmhossianw",VX(4, 1413), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOSSIANW }, +{ "evmhosmfanw",VX(4, 1423), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOSMFANW }, +{ "evmhosmianw",VX(4, 1421), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOSMIANW }, +{ "evmhousianw",VX(4, 1412), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOUSIANW }, +{ "evmhoumianw",VX(4, 1420), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOUMIANW }, +{ "evmhessfanw",VX(4, 1411), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHESSFANW }, +{ "evmhessianw",VX(4, 1409), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHESSIANW }, +{ "evmhesmfanw",VX(4, 1419), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHESMFANW }, +{ "evmhesmianw",VX(4, 1417), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHESMIANW }, +{ "evmheusianw",VX(4, 1408), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHEUSIANW }, +{ "evmheumianw",VX(4, 1416), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHEUMIANW }, + +{ "evmhogsmfaa",VX(4, 1327), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOGSMFAA }, +{ "evmhogsmiaa",VX(4, 1325), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOGSMIAA }, +{ "evmhogumiaa",VX(4, 1324), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOGUMIAA }, +{ "evmhegsmfaa",VX(4, 1323), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHEGSMFAA }, +{ "evmhegsmiaa",VX(4, 1321), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHEGSMIAA }, +{ "evmhegumiaa",VX(4, 1320), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHEGUMIAA }, + +{ "evmhogsmfan",VX(4, 1455), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOGSMFAN }, +{ "evmhogsmian",VX(4, 1453), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOGSMIAN }, +{ "evmhogumian",VX(4, 1452), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHOGUMIAN }, +{ "evmhegsmfan",VX(4, 1451), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHEGSMFAN }, +{ "evmhegsmian",VX(4, 1449), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHEGSMIAN }, +{ "evmhegumian",VX(4, 1448), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMHEGUMIAN }, + +{ "evmwhssf", VX(4, 1095), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWHSSF }, +{ "evmwhssfa", VX(4, 1127), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWHSSFA }, +{ "evmwhsmf", VX(4, 1103), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWHSMF }, +{ "evmwhsmfa", VX(4, 1135), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWHSMFA }, +{ "evmwhsmi", VX(4, 1101), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWHSMI }, +{ "evmwhsmia", VX(4, 1133), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWHSMIA }, +{ "evmwhumi", VX(4, 1100), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWHUMI }, +{ "evmwhumia", VX(4, 1132), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWHUMIA }, + +{ "evmwlumi", VX(4, 1096), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWLUMI }, +{ "evmwlumia", VX(4, 1128), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWLUMIA }, + +{ "evmwlssiaaw",VX(4, 1345), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWLSSIAAW }, +{ "evmwlsmiaaw",VX(4, 1353), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWLSMIAAW }, +{ "evmwlusiaaw",VX(4, 1344), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWLUSIAAW }, +{ "evmwlumiaaw",VX(4, 1352), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWLUMIAAW }, + +{ "evmwlssianw",VX(4, 1473), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWLSSIANW }, +{ "evmwlsmianw",VX(4, 1481), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWLSMIANW }, +{ "evmwlusianw",VX(4, 1472), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWLUSIANW }, +{ "evmwlumianw",VX(4, 1480), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWLUMIANW }, + +{ "evmwssf", VX(4, 1107), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWSSF }, +{ "evmwssfa", VX(4, 1139), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWSSFA }, +{ "evmwsmf", VX(4, 1115), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWSMF }, +{ "evmwsmfa", VX(4, 1147), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWSMFA }, +{ "evmwsmi", VX(4, 1113), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWSMI }, +{ "evmwsmia", VX(4, 1145), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWSMIA }, +{ "evmwumi", VX(4, 1112), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWUMI }, +{ "evmwumia", VX(4, 1144), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWUMIA }, + +{ "evmwssfaa", VX(4, 1363), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWSSFAA }, +{ "evmwsmfaa", VX(4, 1371), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWSMFAA }, +{ "evmwsmiaa", VX(4, 1369), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWSMIAA }, +{ "evmwumiaa", VX(4, 1368), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWUMIAA }, + +{ "evmwssfan", VX(4, 1491), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWSSFAN }, +{ "evmwsmfan", VX(4, 1499), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWSMFAN }, +{ "evmwsmian", VX(4, 1497), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWSMIAN }, +{ "evmwumian", VX(4, 1496), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVMWUMIAN }, + +{ "evaddssiaaw",VX(4, 1217), VX_MASK, PPCSPE, { RS, RA }, PPC_INST_EVADDSSIAAW }, +{ "evaddsmiaaw",VX(4, 1225), VX_MASK, PPCSPE, { RS, RA }, PPC_INST_EVADDSMIAAW }, +{ "evaddusiaaw",VX(4, 1216), VX_MASK, PPCSPE, { RS, RA }, PPC_INST_EVADDUSIAAW }, +{ "evaddumiaaw",VX(4, 1224), VX_MASK, PPCSPE, { RS, RA }, PPC_INST_EVADDUMIAAW }, + +{ "evsubfssiaaw",VX(4, 1219), VX_MASK, PPCSPE, { RS, RA }, PPC_INST_EVSUBFSSIAAW }, +{ "evsubfsmiaaw",VX(4, 1227), VX_MASK, PPCSPE, { RS, RA }, PPC_INST_EVSUBFSMIAAW }, +{ "evsubfusiaaw",VX(4, 1218), VX_MASK, PPCSPE, { RS, RA }, PPC_INST_EVSUBFUSIAAW }, +{ "evsubfumiaaw",VX(4, 1226), VX_MASK, PPCSPE, { RS, RA }, PPC_INST_EVSUBFUMIAAW }, + +{ "evmra", VX(4, 1220), VX_MASK, PPCSPE, { RS, RA }, PPC_INST_EVMRA }, + +{ "evdivws", VX(4, 1222), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVDIVWS }, +{ "evdivwu", VX(4, 1223), VX_MASK, PPCSPE, { RS, RA, RB }, PPC_INST_EVDIVWU }, + +{ "mulli", OP(7), OP_MASK, PPCCOM, { RT, RA, SI }, PPC_INST_MULLI }, +{ "muli", OP(7), OP_MASK, PWRCOM, { RT, RA, SI }, PPC_INST_MULI }, + +{ "subfic", OP(8), OP_MASK, PPCCOM, { RT, RA, SI }, PPC_INST_SUBFIC }, +{ "sfi", OP(8), OP_MASK, PWRCOM, { RT, RA, SI }, PPC_INST_SFI }, + +{ "dozi", OP(9), OP_MASK, M601, { RT, RA, SI }, PPC_INST_DOZI }, + +{ "bce", B(9,0,0), B_MASK, BOOKE64, { BO, BI, BD }, PPC_INST_BCE }, +{ "bcel", B(9,0,1), B_MASK, BOOKE64, { BO, BI, BD }, PPC_INST_BCEL }, +{ "bcea", B(9,1,0), B_MASK, BOOKE64, { BO, BI, BDA }, PPC_INST_BCEA }, +{ "bcela", B(9,1,1), B_MASK, BOOKE64, { BO, BI, BDA }, PPC_INST_BCELA }, + +{ "cmplwi", OPL(10,0), OPL_MASK, PPCCOM, { OBF, RA, UI }, PPC_INST_CMPLWI }, +{ "cmpldi", OPL(10,1), OPL_MASK, PPC64, { OBF, RA, UI }, PPC_INST_CMPLDI }, +{ "cmpli", OP(10), OP_MASK, PPC, { BF, L, RA, UI }, PPC_INST_CMPLI }, +{ "cmpli", OP(10), OP_MASK, PWRCOM, { BF, RA, UI }, PPC_INST_CMPLI }, + +{ "cmpwi", OPL(11,0), OPL_MASK, PPCCOM, { OBF, RA, SI }, PPC_INST_CMPWI }, +{ "cmpdi", OPL(11,1), OPL_MASK, PPC64, { OBF, RA, SI }, PPC_INST_CMPDI }, +{ "cmpi", OP(11), OP_MASK, PPC, { BF, L, RA, SI }, PPC_INST_CMPI }, +{ "cmpi", OP(11), OP_MASK, PWRCOM, { BF, RA, SI }, PPC_INST_CMPI }, + +{ "addic", OP(12), OP_MASK, PPCCOM, { RT, RA, SI }, PPC_INST_ADDIC }, +{ "ai", OP(12), OP_MASK, PWRCOM, { RT, RA, SI }, PPC_INST_AI }, +{ "subic", OP(12), OP_MASK, PPCCOM, { RT, RA, NSI }, PPC_INST_SUBIC }, + +{ "addic.", OP(13), OP_MASK, PPCCOM, { RT, RA, SI }, PPC_INST_ADDIC }, +{ "ai.", OP(13), OP_MASK, PWRCOM, { RT, RA, SI }, PPC_INST_AI }, +{ "subic.", OP(13), OP_MASK, PPCCOM, { RT, RA, NSI }, PPC_INST_SUBIC }, + +{ "li", OP(14), DRA_MASK, PPCCOM, { RT, SI }, PPC_INST_LI }, +{ "lil", OP(14), DRA_MASK, PWRCOM, { RT, SI }, PPC_INST_LIL }, +{ "addi", OP(14), OP_MASK, PPCCOM, { RT, RA0, SI }, PPC_INST_ADDI }, +{ "cal", OP(14), OP_MASK, PWRCOM, { RT, D, RA0 }, PPC_INST_CAL }, +{ "subi", OP(14), OP_MASK, PPCCOM, { RT, RA0, NSI }, PPC_INST_SUBI }, +{ "la", OP(14), OP_MASK, PPCCOM, { RT, D, RA0 }, PPC_INST_LA }, + +{ "lis", OP(15), DRA_MASK, PPCCOM, { RT, SISIGNOPT }, PPC_INST_LIS }, +{ "liu", OP(15), DRA_MASK, PWRCOM, { RT, SISIGNOPT }, PPC_INST_LIU }, +{ "addis", OP(15), OP_MASK, PPCCOM, { RT,RA0,SISIGNOPT }, PPC_INST_ADDIS }, +{ "cau", OP(15), OP_MASK, PWRCOM, { RT,RA0,SISIGNOPT }, PPC_INST_CAU }, +{ "subis", OP(15), OP_MASK, PPCCOM, { RT, RA0, NSI }, PPC_INST_SUBIS }, + +{ "bdnz-", BBO(16,BODNZ,0,0), BBOATBI_MASK, PPCCOM, { BDM }, PPC_INST_BDNZ }, +{ "bdnz+", BBO(16,BODNZ,0,0), BBOATBI_MASK, PPCCOM, { BDP }, PPC_INST_BDNZ }, +{ "bdnz", BBO(16,BODNZ,0,0), BBOATBI_MASK, PPCCOM, { BD }, PPC_INST_BDNZ }, +{ "bdn", BBO(16,BODNZ,0,0), BBOATBI_MASK, PWRCOM, { BD }, PPC_INST_BDN }, +{ "bdnzl-", BBO(16,BODNZ,0,1), BBOATBI_MASK, PPCCOM, { BDM }, PPC_INST_BDNZL }, +{ "bdnzl+", BBO(16,BODNZ,0,1), BBOATBI_MASK, PPCCOM, { BDP }, PPC_INST_BDNZL }, +{ "bdnzl", BBO(16,BODNZ,0,1), BBOATBI_MASK, PPCCOM, { BD }, PPC_INST_BDNZL }, +{ "bdnl", BBO(16,BODNZ,0,1), BBOATBI_MASK, PWRCOM, { BD }, PPC_INST_BDNL }, +{ "bdnza-", BBO(16,BODNZ,1,0), BBOATBI_MASK, PPCCOM, { BDMA }, PPC_INST_BDNZA }, +{ "bdnza+", BBO(16,BODNZ,1,0), BBOATBI_MASK, PPCCOM, { BDPA }, PPC_INST_BDNZA }, +{ "bdnza", BBO(16,BODNZ,1,0), BBOATBI_MASK, PPCCOM, { BDA }, PPC_INST_BDNZA }, +{ "bdna", BBO(16,BODNZ,1,0), BBOATBI_MASK, PWRCOM, { BDA }, PPC_INST_BDNA }, +{ "bdnzla-", BBO(16,BODNZ,1,1), BBOATBI_MASK, PPCCOM, { BDMA }, PPC_INST_BDNZLA }, +{ "bdnzla+", BBO(16,BODNZ,1,1), BBOATBI_MASK, PPCCOM, { BDPA }, PPC_INST_BDNZLA }, +{ "bdnzla", BBO(16,BODNZ,1,1), BBOATBI_MASK, PPCCOM, { BDA }, PPC_INST_BDNZLA }, +{ "bdnla", BBO(16,BODNZ,1,1), BBOATBI_MASK, PWRCOM, { BDA }, PPC_INST_BDNLA }, +{ "bdz-", BBO(16,BODZ,0,0), BBOATBI_MASK, PPCCOM, { BDM }, PPC_INST_BDZ }, +{ "bdz+", BBO(16,BODZ,0,0), BBOATBI_MASK, PPCCOM, { BDP }, PPC_INST_BDZ }, +{ "bdz", BBO(16,BODZ,0,0), BBOATBI_MASK, COM, { BD }, PPC_INST_BDZ }, +{ "bdzl-", BBO(16,BODZ,0,1), BBOATBI_MASK, PPCCOM, { BDM }, PPC_INST_BDZL }, +{ "bdzl+", BBO(16,BODZ,0,1), BBOATBI_MASK, PPCCOM, { BDP }, PPC_INST_BDZL }, +{ "bdzl", BBO(16,BODZ,0,1), BBOATBI_MASK, COM, { BD }, PPC_INST_BDZL }, +{ "bdza-", BBO(16,BODZ,1,0), BBOATBI_MASK, PPCCOM, { BDMA }, PPC_INST_BDZA }, +{ "bdza+", BBO(16,BODZ,1,0), BBOATBI_MASK, PPCCOM, { BDPA }, PPC_INST_BDZA }, +{ "bdza", BBO(16,BODZ,1,0), BBOATBI_MASK, COM, { BDA }, PPC_INST_BDZA }, +{ "bdzla-", BBO(16,BODZ,1,1), BBOATBI_MASK, PPCCOM, { BDMA }, PPC_INST_BDZLA }, +{ "bdzla+", BBO(16,BODZ,1,1), BBOATBI_MASK, PPCCOM, { BDPA }, PPC_INST_BDZLA }, +{ "bdzla", BBO(16,BODZ,1,1), BBOATBI_MASK, COM, { BDA }, PPC_INST_BDZLA }, +{ "blt-", BBOCB(16,BOT,CBLT,0,0), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BLT }, +{ "blt+", BBOCB(16,BOT,CBLT,0,0), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BLT }, +{ "blt", BBOCB(16,BOT,CBLT,0,0), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BLT }, +{ "bltl-", BBOCB(16,BOT,CBLT,0,1), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BLTL }, +{ "bltl+", BBOCB(16,BOT,CBLT,0,1), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BLTL }, +{ "bltl", BBOCB(16,BOT,CBLT,0,1), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BLTL }, +{ "blta-", BBOCB(16,BOT,CBLT,1,0), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BLTA }, +{ "blta+", BBOCB(16,BOT,CBLT,1,0), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BLTA }, +{ "blta", BBOCB(16,BOT,CBLT,1,0), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BLTA }, +{ "bltla-", BBOCB(16,BOT,CBLT,1,1), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BLTLA }, +{ "bltla+", BBOCB(16,BOT,CBLT,1,1), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BLTLA }, +{ "bltla", BBOCB(16,BOT,CBLT,1,1), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BLTLA }, +{ "bgt-", BBOCB(16,BOT,CBGT,0,0), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BGT }, +{ "bgt+", BBOCB(16,BOT,CBGT,0,0), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BGT }, +{ "bgt", BBOCB(16,BOT,CBGT,0,0), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BGT }, +{ "bgtl-", BBOCB(16,BOT,CBGT,0,1), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BGTL }, +{ "bgtl+", BBOCB(16,BOT,CBGT,0,1), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BGTL }, +{ "bgtl", BBOCB(16,BOT,CBGT,0,1), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BGTL }, +{ "bgta-", BBOCB(16,BOT,CBGT,1,0), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BGTA }, +{ "bgta+", BBOCB(16,BOT,CBGT,1,0), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BGTA }, +{ "bgta", BBOCB(16,BOT,CBGT,1,0), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BGTA }, +{ "bgtla-", BBOCB(16,BOT,CBGT,1,1), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BGTLA }, +{ "bgtla+", BBOCB(16,BOT,CBGT,1,1), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BGTLA }, +{ "bgtla", BBOCB(16,BOT,CBGT,1,1), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BGTLA }, +{ "beq-", BBOCB(16,BOT,CBEQ,0,0), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BEQ }, +{ "beq+", BBOCB(16,BOT,CBEQ,0,0), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BEQ }, +{ "beq", BBOCB(16,BOT,CBEQ,0,0), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BEQ }, +{ "beql-", BBOCB(16,BOT,CBEQ,0,1), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BEQL }, +{ "beql+", BBOCB(16,BOT,CBEQ,0,1), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BEQL }, +{ "beql", BBOCB(16,BOT,CBEQ,0,1), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BEQL }, +{ "beqa-", BBOCB(16,BOT,CBEQ,1,0), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BEQA }, +{ "beqa+", BBOCB(16,BOT,CBEQ,1,0), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BEQA }, +{ "beqa", BBOCB(16,BOT,CBEQ,1,0), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BEQA }, +{ "beqla-", BBOCB(16,BOT,CBEQ,1,1), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BEQLA }, +{ "beqla+", BBOCB(16,BOT,CBEQ,1,1), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BEQLA }, +{ "beqla", BBOCB(16,BOT,CBEQ,1,1), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BEQLA }, +{ "bso-", BBOCB(16,BOT,CBSO,0,0), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BSO }, +{ "bso+", BBOCB(16,BOT,CBSO,0,0), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BSO }, +{ "bso", BBOCB(16,BOT,CBSO,0,0), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BSO }, +{ "bsol-", BBOCB(16,BOT,CBSO,0,1), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BSOL }, +{ "bsol+", BBOCB(16,BOT,CBSO,0,1), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BSOL }, +{ "bsol", BBOCB(16,BOT,CBSO,0,1), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BSOL }, +{ "bsoa-", BBOCB(16,BOT,CBSO,1,0), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BSOA }, +{ "bsoa+", BBOCB(16,BOT,CBSO,1,0), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BSOA }, +{ "bsoa", BBOCB(16,BOT,CBSO,1,0), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BSOA }, +{ "bsola-", BBOCB(16,BOT,CBSO,1,1), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BSOLA }, +{ "bsola+", BBOCB(16,BOT,CBSO,1,1), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BSOLA }, +{ "bsola", BBOCB(16,BOT,CBSO,1,1), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BSOLA }, +{ "bun-", BBOCB(16,BOT,CBSO,0,0), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BUN }, +{ "bun+", BBOCB(16,BOT,CBSO,0,0), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BUN }, +{ "bun", BBOCB(16,BOT,CBSO,0,0), BBOATCB_MASK, PPCCOM, { CR, BD }, PPC_INST_BUN }, +{ "bunl-", BBOCB(16,BOT,CBSO,0,1), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BUNL }, +{ "bunl+", BBOCB(16,BOT,CBSO,0,1), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BUNL }, +{ "bunl", BBOCB(16,BOT,CBSO,0,1), BBOATCB_MASK, PPCCOM, { CR, BD }, PPC_INST_BUNL }, +{ "buna-", BBOCB(16,BOT,CBSO,1,0), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BUNA }, +{ "buna+", BBOCB(16,BOT,CBSO,1,0), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BUNA }, +{ "buna", BBOCB(16,BOT,CBSO,1,0), BBOATCB_MASK, PPCCOM, { CR, BDA }, PPC_INST_BUNA }, +{ "bunla-", BBOCB(16,BOT,CBSO,1,1), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BUNLA }, +{ "bunla+", BBOCB(16,BOT,CBSO,1,1), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BUNLA }, +{ "bunla", BBOCB(16,BOT,CBSO,1,1), BBOATCB_MASK, PPCCOM, { CR, BDA }, PPC_INST_BUNLA }, +{ "bge-", BBOCB(16,BOF,CBLT,0,0), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BGE }, +{ "bge+", BBOCB(16,BOF,CBLT,0,0), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BGE }, +{ "bge", BBOCB(16,BOF,CBLT,0,0), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BGE }, +{ "bgel-", BBOCB(16,BOF,CBLT,0,1), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BGEL }, +{ "bgel+", BBOCB(16,BOF,CBLT,0,1), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BGEL }, +{ "bgel", BBOCB(16,BOF,CBLT,0,1), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BGEL }, +{ "bgea-", BBOCB(16,BOF,CBLT,1,0), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BGEA }, +{ "bgea+", BBOCB(16,BOF,CBLT,1,0), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BGEA }, +{ "bgea", BBOCB(16,BOF,CBLT,1,0), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BGEA }, +{ "bgela-", BBOCB(16,BOF,CBLT,1,1), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BGELA }, +{ "bgela+", BBOCB(16,BOF,CBLT,1,1), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BGELA }, +{ "bgela", BBOCB(16,BOF,CBLT,1,1), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BGELA }, +{ "bnl-", BBOCB(16,BOF,CBLT,0,0), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BNL }, +{ "bnl+", BBOCB(16,BOF,CBLT,0,0), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BNL }, +{ "bnl", BBOCB(16,BOF,CBLT,0,0), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BNL }, +{ "bnll-", BBOCB(16,BOF,CBLT,0,1), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BNLL }, +{ "bnll+", BBOCB(16,BOF,CBLT,0,1), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BNLL }, +{ "bnll", BBOCB(16,BOF,CBLT,0,1), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BNLL }, +{ "bnla-", BBOCB(16,BOF,CBLT,1,0), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BNLA }, +{ "bnla+", BBOCB(16,BOF,CBLT,1,0), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BNLA }, +{ "bnla", BBOCB(16,BOF,CBLT,1,0), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BNLA }, +{ "bnlla-", BBOCB(16,BOF,CBLT,1,1), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BNLLA }, +{ "bnlla+", BBOCB(16,BOF,CBLT,1,1), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BNLLA }, +{ "bnlla", BBOCB(16,BOF,CBLT,1,1), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BNLLA }, +{ "ble-", BBOCB(16,BOF,CBGT,0,0), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BLE }, +{ "ble+", BBOCB(16,BOF,CBGT,0,0), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BLE }, +{ "ble", BBOCB(16,BOF,CBGT,0,0), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BLE }, +{ "blel-", BBOCB(16,BOF,CBGT,0,1), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BLEL }, +{ "blel+", BBOCB(16,BOF,CBGT,0,1), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BLEL }, +{ "blel", BBOCB(16,BOF,CBGT,0,1), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BLEL }, +{ "blea-", BBOCB(16,BOF,CBGT,1,0), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BLEA }, +{ "blea+", BBOCB(16,BOF,CBGT,1,0), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BLEA }, +{ "blea", BBOCB(16,BOF,CBGT,1,0), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BLEA }, +{ "blela-", BBOCB(16,BOF,CBGT,1,1), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BLELA }, +{ "blela+", BBOCB(16,BOF,CBGT,1,1), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BLELA }, +{ "blela", BBOCB(16,BOF,CBGT,1,1), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BLELA }, +{ "bng-", BBOCB(16,BOF,CBGT,0,0), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BNG }, +{ "bng+", BBOCB(16,BOF,CBGT,0,0), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BNG }, +{ "bng", BBOCB(16,BOF,CBGT,0,0), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BNG }, +{ "bngl-", BBOCB(16,BOF,CBGT,0,1), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BNGL }, +{ "bngl+", BBOCB(16,BOF,CBGT,0,1), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BNGL }, +{ "bngl", BBOCB(16,BOF,CBGT,0,1), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BNGL }, +{ "bnga-", BBOCB(16,BOF,CBGT,1,0), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BNGA }, +{ "bnga+", BBOCB(16,BOF,CBGT,1,0), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BNGA }, +{ "bnga", BBOCB(16,BOF,CBGT,1,0), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BNGA }, +{ "bngla-", BBOCB(16,BOF,CBGT,1,1), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BNGLA }, +{ "bngla+", BBOCB(16,BOF,CBGT,1,1), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BNGLA }, +{ "bngla", BBOCB(16,BOF,CBGT,1,1), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BNGLA }, +{ "bne-", BBOCB(16,BOF,CBEQ,0,0), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BNE }, +{ "bne+", BBOCB(16,BOF,CBEQ,0,0), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BNE }, +{ "bne", BBOCB(16,BOF,CBEQ,0,0), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BNE }, +{ "bnel-", BBOCB(16,BOF,CBEQ,0,1), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BNEL }, +{ "bnel+", BBOCB(16,BOF,CBEQ,0,1), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BNEL }, +{ "bnel", BBOCB(16,BOF,CBEQ,0,1), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BNEL }, +{ "bnea-", BBOCB(16,BOF,CBEQ,1,0), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BNEA }, +{ "bnea+", BBOCB(16,BOF,CBEQ,1,0), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BNEA }, +{ "bnea", BBOCB(16,BOF,CBEQ,1,0), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BNEA }, +{ "bnela-", BBOCB(16,BOF,CBEQ,1,1), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BNELA }, +{ "bnela+", BBOCB(16,BOF,CBEQ,1,1), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BNELA }, +{ "bnela", BBOCB(16,BOF,CBEQ,1,1), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BNELA }, +{ "bns-", BBOCB(16,BOF,CBSO,0,0), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BNS }, +{ "bns+", BBOCB(16,BOF,CBSO,0,0), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BNS }, +{ "bns", BBOCB(16,BOF,CBSO,0,0), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BNS }, +{ "bnsl-", BBOCB(16,BOF,CBSO,0,1), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BNSL }, +{ "bnsl+", BBOCB(16,BOF,CBSO,0,1), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BNSL }, +{ "bnsl", BBOCB(16,BOF,CBSO,0,1), BBOATCB_MASK, COM, { CR, BD }, PPC_INST_BNSL }, +{ "bnsa-", BBOCB(16,BOF,CBSO,1,0), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BNSA }, +{ "bnsa+", BBOCB(16,BOF,CBSO,1,0), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BNSA }, +{ "bnsa", BBOCB(16,BOF,CBSO,1,0), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BNSA }, +{ "bnsla-", BBOCB(16,BOF,CBSO,1,1), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BNSLA }, +{ "bnsla+", BBOCB(16,BOF,CBSO,1,1), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BNSLA }, +{ "bnsla", BBOCB(16,BOF,CBSO,1,1), BBOATCB_MASK, COM, { CR, BDA }, PPC_INST_BNSLA }, +{ "bnu-", BBOCB(16,BOF,CBSO,0,0), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BNU }, +{ "bnu+", BBOCB(16,BOF,CBSO,0,0), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BNU }, +{ "bnu", BBOCB(16,BOF,CBSO,0,0), BBOATCB_MASK, PPCCOM, { CR, BD }, PPC_INST_BNU }, +{ "bnul-", BBOCB(16,BOF,CBSO,0,1), BBOATCB_MASK, PPCCOM, { CR, BDM }, PPC_INST_BNUL }, +{ "bnul+", BBOCB(16,BOF,CBSO,0,1), BBOATCB_MASK, PPCCOM, { CR, BDP }, PPC_INST_BNUL }, +{ "bnul", BBOCB(16,BOF,CBSO,0,1), BBOATCB_MASK, PPCCOM, { CR, BD }, PPC_INST_BNUL }, +{ "bnua-", BBOCB(16,BOF,CBSO,1,0), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BNUA }, +{ "bnua+", BBOCB(16,BOF,CBSO,1,0), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BNUA }, +{ "bnua", BBOCB(16,BOF,CBSO,1,0), BBOATCB_MASK, PPCCOM, { CR, BDA }, PPC_INST_BNUA }, +{ "bnula-", BBOCB(16,BOF,CBSO,1,1), BBOATCB_MASK, PPCCOM, { CR, BDMA }, PPC_INST_BNULA }, +{ "bnula+", BBOCB(16,BOF,CBSO,1,1), BBOATCB_MASK, PPCCOM, { CR, BDPA }, PPC_INST_BNULA }, +{ "bnula", BBOCB(16,BOF,CBSO,1,1), BBOATCB_MASK, PPCCOM, { CR, BDA }, PPC_INST_BNULA }, +{ "bdnzt-", BBO(16,BODNZT,0,0), BBOY_MASK, NOPOWER4, { BI, BDM }, PPC_INST_BDNZT }, +{ "bdnzt+", BBO(16,BODNZT,0,0), BBOY_MASK, NOPOWER4, { BI, BDP }, PPC_INST_BDNZT }, +{ "bdnzt", BBO(16,BODNZT,0,0), BBOY_MASK, PPCCOM, { BI, BD }, PPC_INST_BDNZT }, +{ "bdnztl-", BBO(16,BODNZT,0,1), BBOY_MASK, NOPOWER4, { BI, BDM }, PPC_INST_BDNZTL }, +{ "bdnztl+", BBO(16,BODNZT,0,1), BBOY_MASK, NOPOWER4, { BI, BDP }, PPC_INST_BDNZTL }, +{ "bdnztl", BBO(16,BODNZT,0,1), BBOY_MASK, PPCCOM, { BI, BD }, PPC_INST_BDNZTL }, +{ "bdnzta-", BBO(16,BODNZT,1,0), BBOY_MASK, NOPOWER4, { BI, BDMA }, PPC_INST_BDNZTA }, +{ "bdnzta+", BBO(16,BODNZT,1,0), BBOY_MASK, NOPOWER4, { BI, BDPA }, PPC_INST_BDNZTA }, +{ "bdnzta", BBO(16,BODNZT,1,0), BBOY_MASK, PPCCOM, { BI, BDA }, PPC_INST_BDNZTA }, +{ "bdnztla-",BBO(16,BODNZT,1,1), BBOY_MASK, NOPOWER4, { BI, BDMA }, PPC_INST_BDNZTLA }, +{ "bdnztla+",BBO(16,BODNZT,1,1), BBOY_MASK, NOPOWER4, { BI, BDPA }, PPC_INST_BDNZTLA }, +{ "bdnztla", BBO(16,BODNZT,1,1), BBOY_MASK, PPCCOM, { BI, BDA }, PPC_INST_BDNZTLA }, +{ "bdnzf-", BBO(16,BODNZF,0,0), BBOY_MASK, NOPOWER4, { BI, BDM }, PPC_INST_BDNZF }, +{ "bdnzf+", BBO(16,BODNZF,0,0), BBOY_MASK, NOPOWER4, { BI, BDP }, PPC_INST_BDNZF }, +{ "bdnzf", BBO(16,BODNZF,0,0), BBOY_MASK, PPCCOM, { BI, BD }, PPC_INST_BDNZF }, +{ "bdnzfl-", BBO(16,BODNZF,0,1), BBOY_MASK, NOPOWER4, { BI, BDM }, PPC_INST_BDNZFL }, +{ "bdnzfl+", BBO(16,BODNZF,0,1), BBOY_MASK, NOPOWER4, { BI, BDP }, PPC_INST_BDNZFL }, +{ "bdnzfl", BBO(16,BODNZF,0,1), BBOY_MASK, PPCCOM, { BI, BD }, PPC_INST_BDNZFL }, +{ "bdnzfa-", BBO(16,BODNZF,1,0), BBOY_MASK, NOPOWER4, { BI, BDMA }, PPC_INST_BDNZFA }, +{ "bdnzfa+", BBO(16,BODNZF,1,0), BBOY_MASK, NOPOWER4, { BI, BDPA }, PPC_INST_BDNZFA }, +{ "bdnzfa", BBO(16,BODNZF,1,0), BBOY_MASK, PPCCOM, { BI, BDA }, PPC_INST_BDNZFA }, +{ "bdnzfla-",BBO(16,BODNZF,1,1), BBOY_MASK, NOPOWER4, { BI, BDMA }, PPC_INST_BDNZFLA }, +{ "bdnzfla+",BBO(16,BODNZF,1,1), BBOY_MASK, NOPOWER4, { BI, BDPA }, PPC_INST_BDNZFLA }, +{ "bdnzfla", BBO(16,BODNZF,1,1), BBOY_MASK, PPCCOM, { BI, BDA }, PPC_INST_BDNZFLA }, +{ "bt-", BBO(16,BOT,0,0), BBOAT_MASK, PPCCOM, { BI, BDM }, PPC_INST_BT }, +{ "bt+", BBO(16,BOT,0,0), BBOAT_MASK, PPCCOM, { BI, BDP }, PPC_INST_BT }, +{ "bt", BBO(16,BOT,0,0), BBOAT_MASK, PPCCOM, { BI, BD }, PPC_INST_BT }, +{ "bbt", BBO(16,BOT,0,0), BBOAT_MASK, PWRCOM, { BI, BD }, PPC_INST_BBT }, +{ "btl-", BBO(16,BOT,0,1), BBOAT_MASK, PPCCOM, { BI, BDM }, PPC_INST_BTL }, +{ "btl+", BBO(16,BOT,0,1), BBOAT_MASK, PPCCOM, { BI, BDP }, PPC_INST_BTL }, +{ "btl", BBO(16,BOT,0,1), BBOAT_MASK, PPCCOM, { BI, BD }, PPC_INST_BTL }, +{ "bbtl", BBO(16,BOT,0,1), BBOAT_MASK, PWRCOM, { BI, BD }, PPC_INST_BBTL }, +{ "bta-", BBO(16,BOT,1,0), BBOAT_MASK, PPCCOM, { BI, BDMA }, PPC_INST_BTA }, +{ "bta+", BBO(16,BOT,1,0), BBOAT_MASK, PPCCOM, { BI, BDPA }, PPC_INST_BTA }, +{ "bta", BBO(16,BOT,1,0), BBOAT_MASK, PPCCOM, { BI, BDA }, PPC_INST_BTA }, +{ "bbta", BBO(16,BOT,1,0), BBOAT_MASK, PWRCOM, { BI, BDA }, PPC_INST_BBTA }, +{ "btla-", BBO(16,BOT,1,1), BBOAT_MASK, PPCCOM, { BI, BDMA }, PPC_INST_BTLA }, +{ "btla+", BBO(16,BOT,1,1), BBOAT_MASK, PPCCOM, { BI, BDPA }, PPC_INST_BTLA }, +{ "btla", BBO(16,BOT,1,1), BBOAT_MASK, PPCCOM, { BI, BDA }, PPC_INST_BTLA }, +{ "bbtla", BBO(16,BOT,1,1), BBOAT_MASK, PWRCOM, { BI, BDA }, PPC_INST_BBTLA }, +{ "bf-", BBO(16,BOF,0,0), BBOAT_MASK, PPCCOM, { BI, BDM }, PPC_INST_BF }, +{ "bf+", BBO(16,BOF,0,0), BBOAT_MASK, PPCCOM, { BI, BDP }, PPC_INST_BF }, +{ "bf", BBO(16,BOF,0,0), BBOAT_MASK, PPCCOM, { BI, BD }, PPC_INST_BF }, +{ "bbf", BBO(16,BOF,0,0), BBOAT_MASK, PWRCOM, { BI, BD }, PPC_INST_BBF }, +{ "bfl-", BBO(16,BOF,0,1), BBOAT_MASK, PPCCOM, { BI, BDM }, PPC_INST_BFL }, +{ "bfl+", BBO(16,BOF,0,1), BBOAT_MASK, PPCCOM, { BI, BDP }, PPC_INST_BFL }, +{ "bfl", BBO(16,BOF,0,1), BBOAT_MASK, PPCCOM, { BI, BD }, PPC_INST_BFL }, +{ "bbfl", BBO(16,BOF,0,1), BBOAT_MASK, PWRCOM, { BI, BD }, PPC_INST_BBFL }, +{ "bfa-", BBO(16,BOF,1,0), BBOAT_MASK, PPCCOM, { BI, BDMA }, PPC_INST_BFA }, +{ "bfa+", BBO(16,BOF,1,0), BBOAT_MASK, PPCCOM, { BI, BDPA }, PPC_INST_BFA }, +{ "bfa", BBO(16,BOF,1,0), BBOAT_MASK, PPCCOM, { BI, BDA }, PPC_INST_BFA }, +{ "bbfa", BBO(16,BOF,1,0), BBOAT_MASK, PWRCOM, { BI, BDA }, PPC_INST_BBFA }, +{ "bfla-", BBO(16,BOF,1,1), BBOAT_MASK, PPCCOM, { BI, BDMA }, PPC_INST_BFLA }, +{ "bfla+", BBO(16,BOF,1,1), BBOAT_MASK, PPCCOM, { BI, BDPA }, PPC_INST_BFLA }, +{ "bfla", BBO(16,BOF,1,1), BBOAT_MASK, PPCCOM, { BI, BDA }, PPC_INST_BFLA }, +{ "bbfla", BBO(16,BOF,1,1), BBOAT_MASK, PWRCOM, { BI, BDA }, PPC_INST_BBFLA }, +{ "bdzt-", BBO(16,BODZT,0,0), BBOY_MASK, NOPOWER4, { BI, BDM }, PPC_INST_BDZT }, +{ "bdzt+", BBO(16,BODZT,0,0), BBOY_MASK, NOPOWER4, { BI, BDP }, PPC_INST_BDZT }, +{ "bdzt", BBO(16,BODZT,0,0), BBOY_MASK, PPCCOM, { BI, BD }, PPC_INST_BDZT }, +{ "bdztl-", BBO(16,BODZT,0,1), BBOY_MASK, NOPOWER4, { BI, BDM }, PPC_INST_BDZTL }, +{ "bdztl+", BBO(16,BODZT,0,1), BBOY_MASK, NOPOWER4, { BI, BDP }, PPC_INST_BDZTL }, +{ "bdztl", BBO(16,BODZT,0,1), BBOY_MASK, PPCCOM, { BI, BD }, PPC_INST_BDZTL }, +{ "bdzta-", BBO(16,BODZT,1,0), BBOY_MASK, NOPOWER4, { BI, BDMA }, PPC_INST_BDZTA }, +{ "bdzta+", BBO(16,BODZT,1,0), BBOY_MASK, NOPOWER4, { BI, BDPA }, PPC_INST_BDZTA }, +{ "bdzta", BBO(16,BODZT,1,0), BBOY_MASK, PPCCOM, { BI, BDA }, PPC_INST_BDZTA }, +{ "bdztla-", BBO(16,BODZT,1,1), BBOY_MASK, NOPOWER4, { BI, BDMA }, PPC_INST_BDZTLA }, +{ "bdztla+", BBO(16,BODZT,1,1), BBOY_MASK, NOPOWER4, { BI, BDPA }, PPC_INST_BDZTLA }, +{ "bdztla", BBO(16,BODZT,1,1), BBOY_MASK, PPCCOM, { BI, BDA }, PPC_INST_BDZTLA }, +{ "bdzf-", BBO(16,BODZF,0,0), BBOY_MASK, NOPOWER4, { BI, BDM }, PPC_INST_BDZF }, +{ "bdzf+", BBO(16,BODZF,0,0), BBOY_MASK, NOPOWER4, { BI, BDP }, PPC_INST_BDZF }, +{ "bdzf", BBO(16,BODZF,0,0), BBOY_MASK, PPCCOM, { BI, BD }, PPC_INST_BDZF }, +{ "bdzfl-", BBO(16,BODZF,0,1), BBOY_MASK, NOPOWER4, { BI, BDM }, PPC_INST_BDZFL }, +{ "bdzfl+", BBO(16,BODZF,0,1), BBOY_MASK, NOPOWER4, { BI, BDP }, PPC_INST_BDZFL }, +{ "bdzfl", BBO(16,BODZF,0,1), BBOY_MASK, PPCCOM, { BI, BD }, PPC_INST_BDZFL }, +{ "bdzfa-", BBO(16,BODZF,1,0), BBOY_MASK, NOPOWER4, { BI, BDMA }, PPC_INST_BDZFA }, +{ "bdzfa+", BBO(16,BODZF,1,0), BBOY_MASK, NOPOWER4, { BI, BDPA }, PPC_INST_BDZFA }, +{ "bdzfa", BBO(16,BODZF,1,0), BBOY_MASK, PPCCOM, { BI, BDA }, PPC_INST_BDZFA }, +{ "bdzfla-", BBO(16,BODZF,1,1), BBOY_MASK, NOPOWER4, { BI, BDMA }, PPC_INST_BDZFLA }, +{ "bdzfla+", BBO(16,BODZF,1,1), BBOY_MASK, NOPOWER4, { BI, BDPA }, PPC_INST_BDZFLA }, +{ "bdzfla", BBO(16,BODZF,1,1), BBOY_MASK, PPCCOM, { BI, BDA }, PPC_INST_BDZFLA }, +{ "bc-", B(16,0,0), B_MASK, PPCCOM, { BOE, BI, BDM }, PPC_INST_BC }, +{ "bc+", B(16,0,0), B_MASK, PPCCOM, { BOE, BI, BDP }, PPC_INST_BC }, +{ "bc", B(16,0,0), B_MASK, COM, { BO, BI, BD }, PPC_INST_BC }, +{ "bcl-", B(16,0,1), B_MASK, PPCCOM, { BOE, BI, BDM }, PPC_INST_BCL }, +{ "bcl+", B(16,0,1), B_MASK, PPCCOM, { BOE, BI, BDP }, PPC_INST_BCL }, +{ "bcl", B(16,0,1), B_MASK, COM, { BO, BI, BD }, PPC_INST_BCL }, +{ "bca-", B(16,1,0), B_MASK, PPCCOM, { BOE, BI, BDMA }, PPC_INST_BCA }, +{ "bca+", B(16,1,0), B_MASK, PPCCOM, { BOE, BI, BDPA }, PPC_INST_BCA }, +{ "bca", B(16,1,0), B_MASK, COM, { BO, BI, BDA }, PPC_INST_BCA }, +{ "bcla-", B(16,1,1), B_MASK, PPCCOM, { BOE, BI, BDMA }, PPC_INST_BCLA }, +{ "bcla+", B(16,1,1), B_MASK, PPCCOM, { BOE, BI, BDPA }, PPC_INST_BCLA }, +{ "bcla", B(16,1,1), B_MASK, COM, { BO, BI, BDA }, PPC_INST_BCLA }, + +{ "sc", SC(17,1,0), SC_MASK, PPC, { LEV }, PPC_INST_SC }, +{ "svc", SC(17,0,0), SC_MASK, POWER, { SVC_LEV, FL1, FL2 }, PPC_INST_SVC }, +{ "svcl", SC(17,0,1), SC_MASK, POWER, { SVC_LEV, FL1, FL2 }, PPC_INST_SVCL }, +{ "svca", SC(17,1,0), SC_MASK, PWRCOM, { SV }, PPC_INST_SVCA }, +{ "svcla", SC(17,1,1), SC_MASK, POWER, { SV }, PPC_INST_SVCLA }, + +{ "b", B(18,0,0), B_MASK, COM, { LI }, PPC_INST_B }, +{ "bl", B(18,0,1), B_MASK, COM, { LI }, PPC_INST_BL }, +{ "ba", B(18,1,0), B_MASK, COM, { LIA }, PPC_INST_BA }, +{ "bla", B(18,1,1), B_MASK, COM, { LIA }, PPC_INST_BLA }, + +{ "mcrf", XL(19,0), XLBB_MASK | (3 << 21) | (3 << 16), COM, { BF, BFA }, PPC_INST_MCRF }, + +{ "blr", XLO(19,BOU,16,0), XLBOBIBB_MASK, PPCCOM, { 0 }, PPC_INST_BLR }, +{ "br", XLO(19,BOU,16,0), XLBOBIBB_MASK, PWRCOM, { 0 }, PPC_INST_BR }, +{ "blrl", XLO(19,BOU,16,1), XLBOBIBB_MASK, PPCCOM, { 0 }, PPC_INST_BLRL }, +{ "brl", XLO(19,BOU,16,1), XLBOBIBB_MASK, PWRCOM, { 0 }, PPC_INST_BRL }, +{ "bdnzlr", XLO(19,BODNZ,16,0), XLBOBIBB_MASK, PPCCOM, { 0 }, PPC_INST_BDNZLR }, +{ "bdnzlr-", XLO(19,BODNZ,16,0), XLBOBIBB_MASK, NOPOWER4, { 0 }, PPC_INST_BDNZLR }, +{ "bdnzlr-", XLO(19,BODNZM4,16,0), XLBOBIBB_MASK, POWER4, { 0 }, PPC_INST_BDNZLR }, +{ "bdnzlr+", XLO(19,BODNZP,16,0), XLBOBIBB_MASK, NOPOWER4, { 0 }, PPC_INST_BDNZLR }, +{ "bdnzlr+", XLO(19,BODNZP4,16,0), XLBOBIBB_MASK, POWER4, { 0 }, PPC_INST_BDNZLR }, +{ "bdnzlrl", XLO(19,BODNZ,16,1), XLBOBIBB_MASK, PPCCOM, { 0 }, PPC_INST_BDNZLRL }, +{ "bdnzlrl-",XLO(19,BODNZ,16,1), XLBOBIBB_MASK, NOPOWER4, { 0 }, PPC_INST_BDNZLRL }, +{ "bdnzlrl-",XLO(19,BODNZM4,16,1), XLBOBIBB_MASK, POWER4, { 0 }, PPC_INST_BDNZLRL }, +{ "bdnzlrl+",XLO(19,BODNZP,16,1), XLBOBIBB_MASK, NOPOWER4, { 0 }, PPC_INST_BDNZLRL }, +{ "bdnzlrl+",XLO(19,BODNZP4,16,1), XLBOBIBB_MASK, POWER4, { 0 }, PPC_INST_BDNZLRL }, +{ "bdzlr", XLO(19,BODZ,16,0), XLBOBIBB_MASK, PPCCOM, { 0 }, PPC_INST_BDZLR }, +{ "bdzlr-", XLO(19,BODZ,16,0), XLBOBIBB_MASK, NOPOWER4, { 0 }, PPC_INST_BDZLR }, +{ "bdzlr-", XLO(19,BODZM4,16,0), XLBOBIBB_MASK, POWER4, { 0 }, PPC_INST_BDZLR }, +{ "bdzlr+", XLO(19,BODZP,16,0), XLBOBIBB_MASK, NOPOWER4, { 0 }, PPC_INST_BDZLR }, +{ "bdzlr+", XLO(19,BODZP4,16,0), XLBOBIBB_MASK, POWER4, { 0 }, PPC_INST_BDZLR }, +{ "bdzlrl", XLO(19,BODZ,16,1), XLBOBIBB_MASK, PPCCOM, { 0 }, PPC_INST_BDZLRL }, +{ "bdzlrl-", XLO(19,BODZ,16,1), XLBOBIBB_MASK, NOPOWER4, { 0 }, PPC_INST_BDZLRL }, +{ "bdzlrl-", XLO(19,BODZM4,16,1), XLBOBIBB_MASK, POWER4, { 0 }, PPC_INST_BDZLRL }, +{ "bdzlrl+", XLO(19,BODZP,16,1), XLBOBIBB_MASK, NOPOWER4, { 0 }, PPC_INST_BDZLRL }, +{ "bdzlrl+", XLO(19,BODZP4,16,1), XLBOBIBB_MASK, POWER4, { 0 }, PPC_INST_BDZLRL }, +{ "bltlr", XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BLTLR }, +{ "bltlr-", XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BLTLR }, +{ "bltlr-", XLOCB(19,BOTM4,CBLT,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BLTLR }, +{ "bltlr+", XLOCB(19,BOTP,CBLT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BLTLR }, +{ "bltlr+", XLOCB(19,BOTP4,CBLT,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BLTLR }, +{ "bltr", XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BLTR }, +{ "bltlrl", XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BLTLRL }, +{ "bltlrl-", XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BLTLRL }, +{ "bltlrl-", XLOCB(19,BOTM4,CBLT,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BLTLRL }, +{ "bltlrl+", XLOCB(19,BOTP,CBLT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BLTLRL }, +{ "bltlrl+", XLOCB(19,BOTP4,CBLT,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BLTLRL }, +{ "bltrl", XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BLTRL }, +{ "bgtlr", XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BGTLR }, +{ "bgtlr-", XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BGTLR }, +{ "bgtlr-", XLOCB(19,BOTM4,CBGT,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BGTLR }, +{ "bgtlr+", XLOCB(19,BOTP,CBGT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BGTLR }, +{ "bgtlr+", XLOCB(19,BOTP4,CBGT,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BGTLR }, +{ "bgtr", XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BGTR }, +{ "bgtlrl", XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BGTLRL }, +{ "bgtlrl-", XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BGTLRL }, +{ "bgtlrl-", XLOCB(19,BOTM4,CBGT,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BGTLRL }, +{ "bgtlrl+", XLOCB(19,BOTP,CBGT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BGTLRL }, +{ "bgtlrl+", XLOCB(19,BOTP4,CBGT,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BGTLRL }, +{ "bgtrl", XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BGTRL }, +{ "beqlr", XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BEQLR }, +{ "beqlr-", XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BEQLR }, +{ "beqlr-", XLOCB(19,BOTM4,CBEQ,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BEQLR }, +{ "beqlr+", XLOCB(19,BOTP,CBEQ,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BEQLR }, +{ "beqlr+", XLOCB(19,BOTP4,CBEQ,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BEQLR }, +{ "beqr", XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BEQR }, +{ "beqlrl", XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BEQLRL }, +{ "beqlrl-", XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BEQLRL }, +{ "beqlrl-", XLOCB(19,BOTM4,CBEQ,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BEQLRL }, +{ "beqlrl+", XLOCB(19,BOTP,CBEQ,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BEQLRL }, +{ "beqlrl+", XLOCB(19,BOTP4,CBEQ,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BEQLRL }, +{ "beqrl", XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BEQRL }, +{ "bsolr", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BSOLR }, +{ "bsolr-", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BSOLR }, +{ "bsolr-", XLOCB(19,BOTM4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BSOLR }, +{ "bsolr+", XLOCB(19,BOTP,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BSOLR }, +{ "bsolr+", XLOCB(19,BOTP4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BSOLR }, +{ "bsor", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BSOR }, +{ "bsolrl", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BSOLRL }, +{ "bsolrl-", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BSOLRL }, +{ "bsolrl-", XLOCB(19,BOTM4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BSOLRL }, +{ "bsolrl+", XLOCB(19,BOTP,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BSOLRL }, +{ "bsolrl+", XLOCB(19,BOTP4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BSOLRL }, +{ "bsorl", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BSORL }, +{ "bunlr", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BUNLR }, +{ "bunlr-", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BUNLR }, +{ "bunlr-", XLOCB(19,BOTM4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BUNLR }, +{ "bunlr+", XLOCB(19,BOTP,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BUNLR }, +{ "bunlr+", XLOCB(19,BOTP4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BUNLR }, +{ "bunlrl", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BUNLRL }, +{ "bunlrl-", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BUNLRL }, +{ "bunlrl-", XLOCB(19,BOTM4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BUNLRL }, +{ "bunlrl+", XLOCB(19,BOTP,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BUNLRL }, +{ "bunlrl+", XLOCB(19,BOTP4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BUNLRL }, +{ "bgelr", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BGELR }, +{ "bgelr-", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BGELR }, +{ "bgelr-", XLOCB(19,BOFM4,CBLT,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BGELR }, +{ "bgelr+", XLOCB(19,BOFP,CBLT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BGELR }, +{ "bgelr+", XLOCB(19,BOFP4,CBLT,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BGELR }, +{ "bger", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BGER }, +{ "bgelrl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BGELRL }, +{ "bgelrl-", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BGELRL }, +{ "bgelrl-", XLOCB(19,BOFM4,CBLT,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BGELRL }, +{ "bgelrl+", XLOCB(19,BOFP,CBLT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BGELRL }, +{ "bgelrl+", XLOCB(19,BOFP4,CBLT,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BGELRL }, +{ "bgerl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BGERL }, +{ "bnllr", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNLLR }, +{ "bnllr-", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNLLR }, +{ "bnllr-", XLOCB(19,BOFM4,CBLT,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNLLR }, +{ "bnllr+", XLOCB(19,BOFP,CBLT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNLLR }, +{ "bnllr+", XLOCB(19,BOFP4,CBLT,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNLLR }, +{ "bnlr", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BNLR }, +{ "bnllrl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNLLRL }, +{ "bnllrl-", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNLLRL }, +{ "bnllrl-", XLOCB(19,BOFM4,CBLT,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNLLRL }, +{ "bnllrl+", XLOCB(19,BOFP,CBLT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNLLRL }, +{ "bnllrl+", XLOCB(19,BOFP4,CBLT,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNLLRL }, +{ "bnlrl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BNLRL }, +{ "blelr", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BLELR }, +{ "blelr-", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BLELR }, +{ "blelr-", XLOCB(19,BOFM4,CBGT,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BLELR }, +{ "blelr+", XLOCB(19,BOFP,CBGT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BLELR }, +{ "blelr+", XLOCB(19,BOFP4,CBGT,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BLELR }, +{ "bler", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BLER }, +{ "blelrl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BLELRL }, +{ "blelrl-", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BLELRL }, +{ "blelrl-", XLOCB(19,BOFM4,CBGT,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BLELRL }, +{ "blelrl+", XLOCB(19,BOFP,CBGT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BLELRL }, +{ "blelrl+", XLOCB(19,BOFP4,CBGT,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BLELRL }, +{ "blerl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BLERL }, +{ "bnglr", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNGLR }, +{ "bnglr-", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNGLR }, +{ "bnglr-", XLOCB(19,BOFM4,CBGT,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNGLR }, +{ "bnglr+", XLOCB(19,BOFP,CBGT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNGLR }, +{ "bnglr+", XLOCB(19,BOFP4,CBGT,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNGLR }, +{ "bngr", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BNGR }, +{ "bnglrl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNGLRL }, +{ "bnglrl-", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNGLRL }, +{ "bnglrl-", XLOCB(19,BOFM4,CBGT,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNGLRL }, +{ "bnglrl+", XLOCB(19,BOFP,CBGT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNGLRL }, +{ "bnglrl+", XLOCB(19,BOFP4,CBGT,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNGLRL }, +{ "bngrl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BNGRL }, +{ "bnelr", XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNELR }, +{ "bnelr-", XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNELR }, +{ "bnelr-", XLOCB(19,BOFM4,CBEQ,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNELR }, +{ "bnelr+", XLOCB(19,BOFP,CBEQ,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNELR }, +{ "bnelr+", XLOCB(19,BOFP4,CBEQ,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNELR }, +{ "bner", XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BNER }, +{ "bnelrl", XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNELRL }, +{ "bnelrl-", XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNELRL }, +{ "bnelrl-", XLOCB(19,BOFM4,CBEQ,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNELRL }, +{ "bnelrl+", XLOCB(19,BOFP,CBEQ,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNELRL }, +{ "bnelrl+", XLOCB(19,BOFP4,CBEQ,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNELRL }, +{ "bnerl", XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BNERL }, +{ "bnslr", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNSLR }, +{ "bnslr-", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNSLR }, +{ "bnslr-", XLOCB(19,BOFM4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNSLR }, +{ "bnslr+", XLOCB(19,BOFP,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNSLR }, +{ "bnslr+", XLOCB(19,BOFP4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNSLR }, +{ "bnsr", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BNSR }, +{ "bnslrl", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNSLRL }, +{ "bnslrl-", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNSLRL }, +{ "bnslrl-", XLOCB(19,BOFM4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNSLRL }, +{ "bnslrl+", XLOCB(19,BOFP,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNSLRL }, +{ "bnslrl+", XLOCB(19,BOFP4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNSLRL }, +{ "bnsrl", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PWRCOM, { CR }, PPC_INST_BNSRL }, +{ "bnulr", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNULR }, +{ "bnulr-", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNULR }, +{ "bnulr-", XLOCB(19,BOFM4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNULR }, +{ "bnulr+", XLOCB(19,BOFP,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNULR }, +{ "bnulr+", XLOCB(19,BOFP4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNULR }, +{ "bnulrl", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNULRL }, +{ "bnulrl-", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNULRL }, +{ "bnulrl-", XLOCB(19,BOFM4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNULRL }, +{ "bnulrl+", XLOCB(19,BOFP,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNULRL }, +{ "bnulrl+", XLOCB(19,BOFP4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNULRL }, +{ "btlr", XLO(19,BOT,16,0), XLBOBB_MASK, PPCCOM, { BI }, PPC_INST_BTLR }, +{ "btlr-", XLO(19,BOT,16,0), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BTLR }, +{ "btlr-", XLO(19,BOTM4,16,0), XLBOBB_MASK, POWER4, { BI }, PPC_INST_BTLR }, +{ "btlr+", XLO(19,BOTP,16,0), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BTLR }, +{ "btlr+", XLO(19,BOTP4,16,0), XLBOBB_MASK, POWER4, { BI }, PPC_INST_BTLR }, +{ "bbtr", XLO(19,BOT,16,0), XLBOBB_MASK, PWRCOM, { BI }, PPC_INST_BBTR }, +{ "btlrl", XLO(19,BOT,16,1), XLBOBB_MASK, PPCCOM, { BI }, PPC_INST_BTLRL }, +{ "btlrl-", XLO(19,BOT,16,1), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BTLRL }, +{ "btlrl-", XLO(19,BOTM4,16,1), XLBOBB_MASK, POWER4, { BI }, PPC_INST_BTLRL }, +{ "btlrl+", XLO(19,BOTP,16,1), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BTLRL }, +{ "btlrl+", XLO(19,BOTP4,16,1), XLBOBB_MASK, POWER4, { BI }, PPC_INST_BTLRL }, +{ "bbtrl", XLO(19,BOT,16,1), XLBOBB_MASK, PWRCOM, { BI }, PPC_INST_BBTRL }, +{ "bflr", XLO(19,BOF,16,0), XLBOBB_MASK, PPCCOM, { BI }, PPC_INST_BFLR }, +{ "bflr-", XLO(19,BOF,16,0), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BFLR }, +{ "bflr-", XLO(19,BOFM4,16,0), XLBOBB_MASK, POWER4, { BI }, PPC_INST_BFLR }, +{ "bflr+", XLO(19,BOFP,16,0), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BFLR }, +{ "bflr+", XLO(19,BOFP4,16,0), XLBOBB_MASK, POWER4, { BI }, PPC_INST_BFLR }, +{ "bbfr", XLO(19,BOF,16,0), XLBOBB_MASK, PWRCOM, { BI }, PPC_INST_BBFR }, +{ "bflrl", XLO(19,BOF,16,1), XLBOBB_MASK, PPCCOM, { BI }, PPC_INST_BFLRL }, +{ "bflrl-", XLO(19,BOF,16,1), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BFLRL }, +{ "bflrl-", XLO(19,BOFM4,16,1), XLBOBB_MASK, POWER4, { BI }, PPC_INST_BFLRL }, +{ "bflrl+", XLO(19,BOFP,16,1), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BFLRL }, +{ "bflrl+", XLO(19,BOFP4,16,1), XLBOBB_MASK, POWER4, { BI }, PPC_INST_BFLRL }, +{ "bbfrl", XLO(19,BOF,16,1), XLBOBB_MASK, PWRCOM, { BI }, PPC_INST_BBFRL }, +{ "bdnztlr", XLO(19,BODNZT,16,0), XLBOBB_MASK, PPCCOM, { BI }, PPC_INST_BDNZTLR }, +{ "bdnztlr-",XLO(19,BODNZT,16,0), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BDNZTLR }, +{ "bdnztlr+",XLO(19,BODNZTP,16,0), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BDNZTLR }, +{ "bdnztlrl",XLO(19,BODNZT,16,1), XLBOBB_MASK, PPCCOM, { BI }, PPC_INST_BDNZTLRL }, +{ "bdnztlrl-",XLO(19,BODNZT,16,1), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BDNZTLRL }, +{ "bdnztlrl+",XLO(19,BODNZTP,16,1), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BDNZTLRL }, +{ "bdnzflr", XLO(19,BODNZF,16,0), XLBOBB_MASK, PPCCOM, { BI }, PPC_INST_BDNZFLR }, +{ "bdnzflr-",XLO(19,BODNZF,16,0), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BDNZFLR }, +{ "bdnzflr+",XLO(19,BODNZFP,16,0), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BDNZFLR }, +{ "bdnzflrl",XLO(19,BODNZF,16,1), XLBOBB_MASK, PPCCOM, { BI }, PPC_INST_BDNZFLRL }, +{ "bdnzflrl-",XLO(19,BODNZF,16,1), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BDNZFLRL }, +{ "bdnzflrl+",XLO(19,BODNZFP,16,1), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BDNZFLRL }, +{ "bdztlr", XLO(19,BODZT,16,0), XLBOBB_MASK, PPCCOM, { BI }, PPC_INST_BDZTLR }, +{ "bdztlr-", XLO(19,BODZT,16,0), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BDZTLR }, +{ "bdztlr+", XLO(19,BODZTP,16,0), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BDZTLR }, +{ "bdztlrl", XLO(19,BODZT,16,1), XLBOBB_MASK, PPCCOM, { BI }, PPC_INST_BDZTLRL }, +{ "bdztlrl-",XLO(19,BODZT,16,1), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BDZTLRL }, +{ "bdztlrl+",XLO(19,BODZTP,16,1), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BDZTLRL }, +{ "bdzflr", XLO(19,BODZF,16,0), XLBOBB_MASK, PPCCOM, { BI }, PPC_INST_BDZFLR }, +{ "bdzflr-", XLO(19,BODZF,16,0), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BDZFLR }, +{ "bdzflr+", XLO(19,BODZFP,16,0), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BDZFLR }, +{ "bdzflrl", XLO(19,BODZF,16,1), XLBOBB_MASK, PPCCOM, { BI }, PPC_INST_BDZFLRL }, +{ "bdzflrl-",XLO(19,BODZF,16,1), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BDZFLRL }, +{ "bdzflrl+",XLO(19,BODZFP,16,1), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BDZFLRL }, +{ "bclr+", XLYLK(19,16,1,0), XLYBB_MASK, PPCCOM, { BOE, BI }, PPC_INST_BCLR }, +{ "bclrl+", XLYLK(19,16,1,1), XLYBB_MASK, PPCCOM, { BOE, BI }, PPC_INST_BCLRL }, +{ "bclr-", XLYLK(19,16,0,0), XLYBB_MASK, PPCCOM, { BOE, BI }, PPC_INST_BCLR }, +{ "bclrl-", XLYLK(19,16,0,1), XLYBB_MASK, PPCCOM, { BOE, BI }, PPC_INST_BCLRL }, +{ "bclr", XLLK(19,16,0), XLBH_MASK, PPCCOM, { BO, BI, BH }, PPC_INST_BCLR }, +{ "bclrl", XLLK(19,16,1), XLBH_MASK, PPCCOM, { BO, BI, BH }, PPC_INST_BCLRL }, +{ "bcr", XLLK(19,16,0), XLBB_MASK, PWRCOM, { BO, BI }, PPC_INST_BCR }, +{ "bcrl", XLLK(19,16,1), XLBB_MASK, PWRCOM, { BO, BI }, PPC_INST_BCRL }, +{ "bclre", XLLK(19,17,0), XLBB_MASK, BOOKE64, { BO, BI }, PPC_INST_BCLRE }, +{ "bclrel", XLLK(19,17,1), XLBB_MASK, BOOKE64, { BO, BI }, PPC_INST_BCLREL }, + +{ "rfid", XL(19,18), 0xffffffff, PPC64, { 0 }, PPC_INST_RFID }, + +{ "crnot", XL(19,33), XL_MASK, PPCCOM, { BT, BA, BBA }, PPC_INST_CRNOT }, +{ "crnor", XL(19,33), XL_MASK, COM, { BT, BA, BB }, PPC_INST_CRNOR }, +{ "rfmci", X(19,38), 0xffffffff, PPCRFMCI, { 0 }, PPC_INST_RFMCI }, + +{ "rfi", XL(19,50), 0xffffffff, COM, { 0 }, PPC_INST_RFI }, +{ "rfci", XL(19,51), 0xffffffff, PPC403 | BOOKE, { 0 }, PPC_INST_RFCI }, + +{ "rfsvc", XL(19,82), 0xffffffff, POWER, { 0 }, PPC_INST_RFSVC }, + +{ "crandc", XL(19,129), XL_MASK, COM, { BT, BA, BB }, PPC_INST_CRANDC }, + +{ "isync", XL(19,150), 0xffffffff, PPCCOM, { 0 }, PPC_INST_ISYNC }, +{ "ics", XL(19,150), 0xffffffff, PWRCOM, { 0 }, PPC_INST_ICS }, + +{ "crclr", XL(19,193), XL_MASK, PPCCOM, { BT, BAT, BBA }, PPC_INST_CRCLR }, +{ "crxor", XL(19,193), XL_MASK, COM, { BT, BA, BB }, PPC_INST_CRXOR }, + +{ "crnand", XL(19,225), XL_MASK, COM, { BT, BA, BB }, PPC_INST_CRNAND }, + +{ "crand", XL(19,257), XL_MASK, COM, { BT, BA, BB }, PPC_INST_CRAND }, + +{ "hrfid", XL(19,274), 0xffffffff, POWER5 | CELL, { 0 }, PPC_INST_HRFID }, + +{ "crset", XL(19,289), XL_MASK, PPCCOM, { BT, BAT, BBA }, PPC_INST_CRSET }, +{ "creqv", XL(19,289), XL_MASK, COM, { BT, BA, BB }, PPC_INST_CREQV }, + +{ "doze", XL(19,402), 0xffffffff, POWER6, { 0 }, PPC_INST_DOZE }, + +{ "crorc", XL(19,417), XL_MASK, COM, { BT, BA, BB }, PPC_INST_CRORC }, + +{ "nap", XL(19,434), 0xffffffff, POWER6, { 0 }, PPC_INST_NAP }, + +{ "crmove", XL(19,449), XL_MASK, PPCCOM, { BT, BA, BBA }, PPC_INST_CRMOVE }, +{ "cror", XL(19,449), XL_MASK, COM, { BT, BA, BB }, PPC_INST_CROR }, + +{ "sleep", XL(19,466), 0xffffffff, POWER6, { 0 }, PPC_INST_SLEEP }, +{ "rvwinkle", XL(19,498), 0xffffffff, POWER6, { 0 }, PPC_INST_RVWINKLE }, + +{ "bctr", XLO(19,BOU,528,0), XLBOBIBB_MASK, COM, { 0 }, PPC_INST_BCTR }, +{ "bctrl", XLO(19,BOU,528,1), XLBOBIBB_MASK, COM, { 0 }, PPC_INST_BCTRL }, +{ "bltctr", XLOCB(19,BOT,CBLT,528,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BLTCTR }, +{ "bltctr-", XLOCB(19,BOT,CBLT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BLTCTR }, +{ "bltctr-", XLOCB(19,BOTM4,CBLT,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BLTCTR }, +{ "bltctr+", XLOCB(19,BOTP,CBLT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BLTCTR }, +{ "bltctr+", XLOCB(19,BOTP4,CBLT,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BLTCTR }, +{ "bltctrl", XLOCB(19,BOT,CBLT,528,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BLTCTRL }, +{ "bltctrl-",XLOCB(19,BOT,CBLT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BLTCTRL }, +{ "bltctrl-",XLOCB(19,BOTM4,CBLT,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BLTCTRL }, +{ "bltctrl+",XLOCB(19,BOTP,CBLT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BLTCTRL }, +{ "bltctrl+",XLOCB(19,BOTP4,CBLT,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BLTCTRL }, +{ "bgtctr", XLOCB(19,BOT,CBGT,528,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BGTCTR }, +{ "bgtctr-", XLOCB(19,BOT,CBGT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BGTCTR }, +{ "bgtctr-", XLOCB(19,BOTM4,CBGT,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BGTCTR }, +{ "bgtctr+", XLOCB(19,BOTP,CBGT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BGTCTR }, +{ "bgtctr+", XLOCB(19,BOTP4,CBGT,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BGTCTR }, +{ "bgtctrl", XLOCB(19,BOT,CBGT,528,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BGTCTRL }, +{ "bgtctrl-",XLOCB(19,BOT,CBGT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BGTCTRL }, +{ "bgtctrl-",XLOCB(19,BOTM4,CBGT,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BGTCTRL }, +{ "bgtctrl+",XLOCB(19,BOTP,CBGT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BGTCTRL }, +{ "bgtctrl+",XLOCB(19,BOTP4,CBGT,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BGTCTRL }, +{ "beqctr", XLOCB(19,BOT,CBEQ,528,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BEQCTR }, +{ "beqctr-", XLOCB(19,BOT,CBEQ,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BEQCTR }, +{ "beqctr-", XLOCB(19,BOTM4,CBEQ,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BEQCTR }, +{ "beqctr+", XLOCB(19,BOTP,CBEQ,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BEQCTR }, +{ "beqctr+", XLOCB(19,BOTP4,CBEQ,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BEQCTR }, +{ "beqctrl", XLOCB(19,BOT,CBEQ,528,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BEQCTRL }, +{ "beqctrl-",XLOCB(19,BOT,CBEQ,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BEQCTRL }, +{ "beqctrl-",XLOCB(19,BOTM4,CBEQ,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BEQCTRL }, +{ "beqctrl+",XLOCB(19,BOTP,CBEQ,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BEQCTRL }, +{ "beqctrl+",XLOCB(19,BOTP4,CBEQ,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BEQCTRL }, +{ "bsoctr", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BSOCTR }, +{ "bsoctr-", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BSOCTR }, +{ "bsoctr-", XLOCB(19,BOTM4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BSOCTR }, +{ "bsoctr+", XLOCB(19,BOTP,CBSO,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BSOCTR }, +{ "bsoctr+", XLOCB(19,BOTP4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BSOCTR }, +{ "bsoctrl", XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BSOCTRL }, +{ "bsoctrl-",XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BSOCTRL }, +{ "bsoctrl-",XLOCB(19,BOTM4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BSOCTRL }, +{ "bsoctrl+",XLOCB(19,BOTP,CBSO,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BSOCTRL }, +{ "bsoctrl+",XLOCB(19,BOTP4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BSOCTRL }, +{ "bunctr", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BUNCTR }, +{ "bunctr-", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BUNCTR }, +{ "bunctr-", XLOCB(19,BOTM4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BUNCTR }, +{ "bunctr+", XLOCB(19,BOTP,CBSO,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BUNCTR }, +{ "bunctr+", XLOCB(19,BOTP4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BUNCTR }, +{ "bunctrl", XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BUNCTRL }, +{ "bunctrl-",XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BUNCTRL }, +{ "bunctrl-",XLOCB(19,BOTM4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BUNCTRL }, +{ "bunctrl+",XLOCB(19,BOTP,CBSO,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BUNCTRL }, +{ "bunctrl+",XLOCB(19,BOTP4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BUNCTRL }, +{ "bgectr", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BGECTR }, +{ "bgectr-", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BGECTR }, +{ "bgectr-", XLOCB(19,BOFM4,CBLT,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BGECTR }, +{ "bgectr+", XLOCB(19,BOFP,CBLT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BGECTR }, +{ "bgectr+", XLOCB(19,BOFP4,CBLT,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BGECTR }, +{ "bgectrl", XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BGECTRL }, +{ "bgectrl-",XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BGECTRL }, +{ "bgectrl-",XLOCB(19,BOFM4,CBLT,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BGECTRL }, +{ "bgectrl+",XLOCB(19,BOFP,CBLT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BGECTRL }, +{ "bgectrl+",XLOCB(19,BOFP4,CBLT,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BGECTRL }, +{ "bnlctr", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNLCTR }, +{ "bnlctr-", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNLCTR }, +{ "bnlctr-", XLOCB(19,BOFM4,CBLT,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNLCTR }, +{ "bnlctr+", XLOCB(19,BOFP,CBLT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNLCTR }, +{ "bnlctr+", XLOCB(19,BOFP4,CBLT,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNLCTR }, +{ "bnlctrl", XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNLCTRL }, +{ "bnlctrl-",XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNLCTRL }, +{ "bnlctrl-",XLOCB(19,BOFM4,CBLT,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNLCTRL }, +{ "bnlctrl+",XLOCB(19,BOFP,CBLT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNLCTRL }, +{ "bnlctrl+",XLOCB(19,BOFP4,CBLT,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNLCTRL }, +{ "blectr", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BLECTR }, +{ "blectr-", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BLECTR }, +{ "blectr-", XLOCB(19,BOFM4,CBGT,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BLECTR }, +{ "blectr+", XLOCB(19,BOFP,CBGT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BLECTR }, +{ "blectr+", XLOCB(19,BOFP4,CBGT,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BLECTR }, +{ "blectrl", XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BLECTRL }, +{ "blectrl-",XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BLECTRL }, +{ "blectrl-",XLOCB(19,BOFM4,CBGT,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BLECTRL }, +{ "blectrl+",XLOCB(19,BOFP,CBGT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BLECTRL }, +{ "blectrl+",XLOCB(19,BOFP4,CBGT,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BLECTRL }, +{ "bngctr", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNGCTR }, +{ "bngctr-", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNGCTR }, +{ "bngctr-", XLOCB(19,BOFM4,CBGT,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNGCTR }, +{ "bngctr+", XLOCB(19,BOFP,CBGT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNGCTR }, +{ "bngctr+", XLOCB(19,BOFP4,CBGT,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNGCTR }, +{ "bngctrl", XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNGCTRL }, +{ "bngctrl-",XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNGCTRL }, +{ "bngctrl-",XLOCB(19,BOFM4,CBGT,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNGCTRL }, +{ "bngctrl+",XLOCB(19,BOFP,CBGT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNGCTRL }, +{ "bngctrl+",XLOCB(19,BOFP4,CBGT,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNGCTRL }, +{ "bnectr", XLOCB(19,BOF,CBEQ,528,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNECTR }, +{ "bnectr-", XLOCB(19,BOF,CBEQ,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNECTR }, +{ "bnectr-", XLOCB(19,BOFM4,CBEQ,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNECTR }, +{ "bnectr+", XLOCB(19,BOFP,CBEQ,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNECTR }, +{ "bnectr+", XLOCB(19,BOFP4,CBEQ,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNECTR }, +{ "bnectrl", XLOCB(19,BOF,CBEQ,528,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNECTRL }, +{ "bnectrl-",XLOCB(19,BOF,CBEQ,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNECTRL }, +{ "bnectrl-",XLOCB(19,BOFM4,CBEQ,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNECTRL }, +{ "bnectrl+",XLOCB(19,BOFP,CBEQ,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNECTRL }, +{ "bnectrl+",XLOCB(19,BOFP4,CBEQ,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNECTRL }, +{ "bnsctr", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNSCTR }, +{ "bnsctr-", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNSCTR }, +{ "bnsctr-", XLOCB(19,BOFM4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNSCTR }, +{ "bnsctr+", XLOCB(19,BOFP,CBSO,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNSCTR }, +{ "bnsctr+", XLOCB(19,BOFP4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNSCTR }, +{ "bnsctrl", XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNSCTRL }, +{ "bnsctrl-",XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNSCTRL }, +{ "bnsctrl-",XLOCB(19,BOFM4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNSCTRL }, +{ "bnsctrl+",XLOCB(19,BOFP,CBSO,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNSCTRL }, +{ "bnsctrl+",XLOCB(19,BOFP4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNSCTRL }, +{ "bnuctr", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNUCTR }, +{ "bnuctr-", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNUCTR }, +{ "bnuctr-", XLOCB(19,BOFM4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNUCTR }, +{ "bnuctr+", XLOCB(19,BOFP,CBSO,528,0), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNUCTR }, +{ "bnuctr+", XLOCB(19,BOFP4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNUCTR }, +{ "bnuctrl", XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPCCOM, { CR }, PPC_INST_BNUCTRL }, +{ "bnuctrl-",XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNUCTRL }, +{ "bnuctrl-",XLOCB(19,BOFM4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNUCTRL }, +{ "bnuctrl+",XLOCB(19,BOFP,CBSO,528,1), XLBOCBBB_MASK, NOPOWER4, { CR }, PPC_INST_BNUCTRL }, +{ "bnuctrl+",XLOCB(19,BOFP4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR }, PPC_INST_BNUCTRL }, +{ "btctr", XLO(19,BOT,528,0), XLBOBB_MASK, PPCCOM, { BI }, PPC_INST_BTCTR }, +{ "btctr-", XLO(19,BOT,528,0), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BTCTR }, +{ "btctr-", XLO(19,BOTM4,528,0), XLBOBB_MASK, POWER4, { BI }, PPC_INST_BTCTR }, +{ "btctr+", XLO(19,BOTP,528,0), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BTCTR }, +{ "btctr+", XLO(19,BOTP4,528,0), XLBOBB_MASK, POWER4, { BI }, PPC_INST_BTCTR }, +{ "btctrl", XLO(19,BOT,528,1), XLBOBB_MASK, PPCCOM, { BI }, PPC_INST_BTCTRL }, +{ "btctrl-", XLO(19,BOT,528,1), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BTCTRL }, +{ "btctrl-", XLO(19,BOTM4,528,1), XLBOBB_MASK, POWER4, { BI }, PPC_INST_BTCTRL }, +{ "btctrl+", XLO(19,BOTP,528,1), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BTCTRL }, +{ "btctrl+", XLO(19,BOTP4,528,1), XLBOBB_MASK, POWER4, { BI }, PPC_INST_BTCTRL }, +{ "bfctr", XLO(19,BOF,528,0), XLBOBB_MASK, PPCCOM, { BI }, PPC_INST_BFCTR }, +{ "bfctr-", XLO(19,BOF,528,0), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BFCTR }, +{ "bfctr-", XLO(19,BOFM4,528,0), XLBOBB_MASK, POWER4, { BI }, PPC_INST_BFCTR }, +{ "bfctr+", XLO(19,BOFP,528,0), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BFCTR }, +{ "bfctr+", XLO(19,BOFP4,528,0), XLBOBB_MASK, POWER4, { BI }, PPC_INST_BFCTR }, +{ "bfctrl", XLO(19,BOF,528,1), XLBOBB_MASK, PPCCOM, { BI }, PPC_INST_BFCTRL }, +{ "bfctrl-", XLO(19,BOF,528,1), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BFCTRL }, +{ "bfctrl-", XLO(19,BOFM4,528,1), XLBOBB_MASK, POWER4, { BI }, PPC_INST_BFCTRL }, +{ "bfctrl+", XLO(19,BOFP,528,1), XLBOBB_MASK, NOPOWER4, { BI }, PPC_INST_BFCTRL }, +{ "bfctrl+", XLO(19,BOFP4,528,1), XLBOBB_MASK, POWER4, { BI }, PPC_INST_BFCTRL }, +{ "bcctr-", XLYLK(19,528,0,0), XLYBB_MASK, PPCCOM, { BOE, BI }, PPC_INST_BCCTR }, +{ "bcctr+", XLYLK(19,528,1,0), XLYBB_MASK, PPCCOM, { BOE, BI }, PPC_INST_BCCTR }, +{ "bcctrl-", XLYLK(19,528,0,1), XLYBB_MASK, PPCCOM, { BOE, BI }, PPC_INST_BCCTRL }, +{ "bcctrl+", XLYLK(19,528,1,1), XLYBB_MASK, PPCCOM, { BOE, BI }, PPC_INST_BCCTRL }, +{ "bcctr", XLLK(19,528,0), XLBH_MASK, PPCCOM, { BO, BI, BH }, PPC_INST_BCCTR }, +{ "bcctrl", XLLK(19,528,1), XLBH_MASK, PPCCOM, { BO, BI, BH }, PPC_INST_BCCTRL }, +{ "bcc", XLLK(19,528,0), XLBB_MASK, PWRCOM, { BO, BI }, PPC_INST_BCC }, +{ "bccl", XLLK(19,528,1), XLBB_MASK, PWRCOM, { BO, BI }, PPC_INST_BCCL }, +{ "bcctre", XLLK(19,529,0), XLBB_MASK, BOOKE64, { BO, BI }, PPC_INST_BCCTRE }, +{ "bcctrel", XLLK(19,529,1), XLBB_MASK, BOOKE64, { BO, BI }, PPC_INST_BCCTREL }, + +{ "rlwimi", M(20,0), M_MASK, PPCCOM, { RA,RS,SH,MBE,ME }, PPC_INST_RLWIMI }, +{ "rlimi", M(20,0), M_MASK, PWRCOM, { RA,RS,SH,MBE,ME }, PPC_INST_RLIMI }, + +{ "rlwimi.", M(20,1), M_MASK, PPCCOM, { RA,RS,SH,MBE,ME }, PPC_INST_RLWIMI }, +{ "rlimi.", M(20,1), M_MASK, PWRCOM, { RA,RS,SH,MBE,ME }, PPC_INST_RLIMI }, + +{ "rotlwi", MME(21,31,0), MMBME_MASK, PPCCOM, { RA, RS, SH }, PPC_INST_ROTLWI }, +{ "clrlwi", MME(21,31,0), MSHME_MASK, PPCCOM, { RA, RS, MB }, PPC_INST_CLRLWI }, +{ "rlwinm", M(21,0), M_MASK, PPCCOM, { RA,RS,SH,MBE,ME }, PPC_INST_RLWINM }, +{ "rlinm", M(21,0), M_MASK, PWRCOM, { RA,RS,SH,MBE,ME }, PPC_INST_RLINM }, +{ "rotlwi.", MME(21,31,1), MMBME_MASK, PPCCOM, { RA,RS,SH }, PPC_INST_ROTLWI }, +{ "clrlwi.", MME(21,31,1), MSHME_MASK, PPCCOM, { RA, RS, MB }, PPC_INST_CLRLWI }, +{ "rlwinm.", M(21,1), M_MASK, PPCCOM, { RA,RS,SH,MBE,ME }, PPC_INST_RLWINM }, +{ "rlinm.", M(21,1), M_MASK, PWRCOM, { RA,RS,SH,MBE,ME }, PPC_INST_RLINM }, + +{ "rlmi", M(22,0), M_MASK, M601, { RA,RS,RB,MBE,ME }, PPC_INST_RLMI }, +{ "rlmi.", M(22,1), M_MASK, M601, { RA,RS,RB,MBE,ME }, PPC_INST_RLMI }, + +{ "be", B(22,0,0), B_MASK, BOOKE64, { LI }, PPC_INST_BE }, +{ "bel", B(22,0,1), B_MASK, BOOKE64, { LI }, PPC_INST_BEL }, +{ "bea", B(22,1,0), B_MASK, BOOKE64, { LIA }, PPC_INST_BEA }, +{ "bela", B(22,1,1), B_MASK, BOOKE64, { LIA }, PPC_INST_BELA }, + +{ "rotlw", MME(23,31,0), MMBME_MASK, PPCCOM, { RA, RS, RB }, PPC_INST_ROTLW }, +{ "rlwnm", M(23,0), M_MASK, PPCCOM, { RA,RS,RB,MBE,ME }, PPC_INST_RLWNM }, +{ "rlnm", M(23,0), M_MASK, PWRCOM, { RA,RS,RB,MBE,ME }, PPC_INST_RLNM }, +{ "rotlw.", MME(23,31,1), MMBME_MASK, PPCCOM, { RA, RS, RB }, PPC_INST_ROTLW }, +{ "rlwnm.", M(23,1), M_MASK, PPCCOM, { RA,RS,RB,MBE,ME }, PPC_INST_RLWNM }, +{ "rlnm.", M(23,1), M_MASK, PWRCOM, { RA,RS,RB,MBE,ME }, PPC_INST_RLNM }, + +{ "nop", OP(24), 0xffffffff, PPCCOM, { 0 }, PPC_INST_NOP }, +{ "ori", OP(24), OP_MASK, PPCCOM, { RA, RS, UI }, PPC_INST_ORI }, +{ "oril", OP(24), OP_MASK, PWRCOM, { RA, RS, UI }, PPC_INST_ORIL }, + +{ "oris", OP(25), OP_MASK, PPCCOM, { RA, RS, UI }, PPC_INST_ORIS }, +{ "oriu", OP(25), OP_MASK, PWRCOM, { RA, RS, UI }, PPC_INST_ORIU }, + +{ "xori", OP(26), OP_MASK, PPCCOM, { RA, RS, UI }, PPC_INST_XORI }, +{ "xoril", OP(26), OP_MASK, PWRCOM, { RA, RS, UI }, PPC_INST_XORIL }, + +{ "xoris", OP(27), OP_MASK, PPCCOM, { RA, RS, UI }, PPC_INST_XORIS }, +{ "xoriu", OP(27), OP_MASK, PWRCOM, { RA, RS, UI }, PPC_INST_XORIU }, + +{ "andi.", OP(28), OP_MASK, PPCCOM, { RA, RS, UI }, PPC_INST_ANDI }, +{ "andil.", OP(28), OP_MASK, PWRCOM, { RA, RS, UI }, PPC_INST_ANDIL }, + +{ "andis.", OP(29), OP_MASK, PPCCOM, { RA, RS, UI }, PPC_INST_ANDIS }, +{ "andiu.", OP(29), OP_MASK, PWRCOM, { RA, RS, UI }, PPC_INST_ANDIU }, + +{ "rotldi", MD(30,0,0), MDMB_MASK, PPC64, { RA, RS, SH6 }, PPC_INST_ROTLDI }, +{ "clrldi", MD(30,0,0), MDSH_MASK, PPC64, { RA, RS, MB6 }, PPC_INST_CLRLDI }, +{ "rldicl", MD(30,0,0), MD_MASK, PPC64, { RA, RS, SH6, MB6 }, PPC_INST_RLDICL }, +{ "rotldi.", MD(30,0,1), MDMB_MASK, PPC64, { RA, RS, SH6 }, PPC_INST_ROTLDI }, +{ "clrldi.", MD(30,0,1), MDSH_MASK, PPC64, { RA, RS, MB6 }, PPC_INST_CLRLDI }, +{ "rldicl.", MD(30,0,1), MD_MASK, PPC64, { RA, RS, SH6, MB6 }, PPC_INST_RLDICL }, + +{ "rldicr", MD(30,1,0), MD_MASK, PPC64, { RA, RS, SH6, ME6 }, PPC_INST_RLDICR }, +{ "rldicr.", MD(30,1,1), MD_MASK, PPC64, { RA, RS, SH6, ME6 }, PPC_INST_RLDICR }, + +{ "rldic", MD(30,2,0), MD_MASK, PPC64, { RA, RS, SH6, MB6 }, PPC_INST_RLDIC }, +{ "rldic.", MD(30,2,1), MD_MASK, PPC64, { RA, RS, SH6, MB6 }, PPC_INST_RLDIC }, + +{ "rldimi", MD(30,3,0), MD_MASK, PPC64, { RA, RS, SH6, MB6 }, PPC_INST_RLDIMI }, +{ "rldimi.", MD(30,3,1), MD_MASK, PPC64, { RA, RS, SH6, MB6 }, PPC_INST_RLDIMI }, + +{ "rotld", MDS(30,8,0), MDSMB_MASK, PPC64, { RA, RS, RB }, PPC_INST_ROTLD }, +{ "rldcl", MDS(30,8,0), MDS_MASK, PPC64, { RA, RS, RB, MB6 }, PPC_INST_RLDCL }, +{ "rotld.", MDS(30,8,1), MDSMB_MASK, PPC64, { RA, RS, RB }, PPC_INST_ROTLD }, +{ "rldcl.", MDS(30,8,1), MDS_MASK, PPC64, { RA, RS, RB, MB6 }, PPC_INST_RLDCL }, + +{ "rldcr", MDS(30,9,0), MDS_MASK, PPC64, { RA, RS, RB, ME6 }, PPC_INST_RLDCR }, +{ "rldcr.", MDS(30,9,1), MDS_MASK, PPC64, { RA, RS, RB, ME6 }, PPC_INST_RLDCR }, + +{ "cmpw", XOPL(31,0,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB }, PPC_INST_CMPW }, +{ "cmpd", XOPL(31,0,1), XCMPL_MASK, PPC64, { OBF, RA, RB }, PPC_INST_CMPD }, +{ "cmp", X(31,0), XCMP_MASK, PPC, { BF, L, RA, RB }, PPC_INST_CMP }, +{ "cmp", X(31,0), XCMPL_MASK, PWRCOM, { BF, RA, RB }, PPC_INST_CMP }, + +{ "twlgt", XTO(31,4,TOLGT), XTO_MASK, PPCCOM, { RA, RB }, PPC_INST_TWLGT }, +{ "tlgt", XTO(31,4,TOLGT), XTO_MASK, PWRCOM, { RA, RB }, PPC_INST_TLGT }, +{ "twllt", XTO(31,4,TOLLT), XTO_MASK, PPCCOM, { RA, RB }, PPC_INST_TWLLT }, +{ "tllt", XTO(31,4,TOLLT), XTO_MASK, PWRCOM, { RA, RB }, PPC_INST_TLLT }, +{ "tweq", XTO(31,4,TOEQ), XTO_MASK, PPCCOM, { RA, RB }, PPC_INST_TWEQ }, +{ "teq", XTO(31,4,TOEQ), XTO_MASK, PWRCOM, { RA, RB }, PPC_INST_TEQ }, +{ "twlge", XTO(31,4,TOLGE), XTO_MASK, PPCCOM, { RA, RB }, PPC_INST_TWLGE }, +{ "tlge", XTO(31,4,TOLGE), XTO_MASK, PWRCOM, { RA, RB }, PPC_INST_TLGE }, +{ "twlnl", XTO(31,4,TOLNL), XTO_MASK, PPCCOM, { RA, RB }, PPC_INST_TWLNL }, +{ "tlnl", XTO(31,4,TOLNL), XTO_MASK, PWRCOM, { RA, RB }, PPC_INST_TLNL }, +{ "twlle", XTO(31,4,TOLLE), XTO_MASK, PPCCOM, { RA, RB }, PPC_INST_TWLLE }, +{ "tlle", XTO(31,4,TOLLE), XTO_MASK, PWRCOM, { RA, RB }, PPC_INST_TLLE }, +{ "twlng", XTO(31,4,TOLNG), XTO_MASK, PPCCOM, { RA, RB }, PPC_INST_TWLNG }, +{ "tlng", XTO(31,4,TOLNG), XTO_MASK, PWRCOM, { RA, RB }, PPC_INST_TLNG }, +{ "twgt", XTO(31,4,TOGT), XTO_MASK, PPCCOM, { RA, RB }, PPC_INST_TWGT }, +{ "tgt", XTO(31,4,TOGT), XTO_MASK, PWRCOM, { RA, RB }, PPC_INST_TGT }, +{ "twge", XTO(31,4,TOGE), XTO_MASK, PPCCOM, { RA, RB }, PPC_INST_TWGE }, +{ "tge", XTO(31,4,TOGE), XTO_MASK, PWRCOM, { RA, RB }, PPC_INST_TGE }, +{ "twnl", XTO(31,4,TONL), XTO_MASK, PPCCOM, { RA, RB }, PPC_INST_TWNL }, +{ "tnl", XTO(31,4,TONL), XTO_MASK, PWRCOM, { RA, RB }, PPC_INST_TNL }, +{ "twlt", XTO(31,4,TOLT), XTO_MASK, PPCCOM, { RA, RB }, PPC_INST_TWLT }, +{ "tlt", XTO(31,4,TOLT), XTO_MASK, PWRCOM, { RA, RB }, PPC_INST_TLT }, +{ "twle", XTO(31,4,TOLE), XTO_MASK, PPCCOM, { RA, RB }, PPC_INST_TWLE }, +{ "tle", XTO(31,4,TOLE), XTO_MASK, PWRCOM, { RA, RB }, PPC_INST_TLE }, +{ "twng", XTO(31,4,TONG), XTO_MASK, PPCCOM, { RA, RB }, PPC_INST_TWNG }, +{ "tng", XTO(31,4,TONG), XTO_MASK, PWRCOM, { RA, RB }, PPC_INST_TNG }, +{ "twne", XTO(31,4,TONE), XTO_MASK, PPCCOM, { RA, RB }, PPC_INST_TWNE }, +{ "tne", XTO(31,4,TONE), XTO_MASK, PWRCOM, { RA, RB }, PPC_INST_TNE }, +{ "trap", XTO(31,4,TOU), 0xffffffff, PPCCOM, { 0 }, PPC_INST_TRAP }, +{ "tw", X(31,4), X_MASK, PPCCOM, { TO, RA, RB }, PPC_INST_TW }, +{ "t", X(31,4), X_MASK, PWRCOM, { TO, RA, RB }, PPC_INST_T }, + +{ "subfc", XO(31,8,0,0), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_SUBFC }, +{ "sf", XO(31,8,0,0), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_SF }, +{ "subc", XO(31,8,0,0), XO_MASK, PPC, { RT, RB, RA }, PPC_INST_SUBC }, +{ "subfc.", XO(31,8,0,1), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_SUBFC }, +{ "sf.", XO(31,8,0,1), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_SF }, +{ "subc.", XO(31,8,0,1), XO_MASK, PPCCOM, { RT, RB, RA }, PPC_INST_SUBC }, +{ "subfco", XO(31,8,1,0), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_SUBFCO }, +{ "sfo", XO(31,8,1,0), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_SFO }, +{ "subco", XO(31,8,1,0), XO_MASK, PPC, { RT, RB, RA }, PPC_INST_SUBCO }, +{ "subfco.", XO(31,8,1,1), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_SUBFCO }, +{ "sfo.", XO(31,8,1,1), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_SFO }, +{ "subco.", XO(31,8,1,1), XO_MASK, PPC, { RT, RB, RA }, PPC_INST_SUBCO }, + +{ "mulhdu", XO(31,9,0,0), XO_MASK, PPC64, { RT, RA, RB }, PPC_INST_MULHDU }, +{ "mulhdu.", XO(31,9,0,1), XO_MASK, PPC64, { RT, RA, RB }, PPC_INST_MULHDU }, + +{ "addc", XO(31,10,0,0), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_ADDC }, +{ "a", XO(31,10,0,0), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_A }, +{ "addc.", XO(31,10,0,1), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_ADDC }, +{ "a.", XO(31,10,0,1), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_A }, +{ "addco", XO(31,10,1,0), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_ADDCO }, +{ "ao", XO(31,10,1,0), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_AO }, +{ "addco.", XO(31,10,1,1), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_ADDCO }, +{ "ao.", XO(31,10,1,1), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_AO }, + +{ "mulhwu", XO(31,11,0,0), XO_MASK, PPC, { RT, RA, RB }, PPC_INST_MULHWU }, +{ "mulhwu.", XO(31,11,0,1), XO_MASK, PPC, { RT, RA, RB }, PPC_INST_MULHWU }, + +{ "isellt", X(31,15), X_MASK, PPCISEL, { RT, RA, RB }, PPC_INST_ISELLT }, +{ "iselgt", X(31,47), X_MASK, PPCISEL, { RT, RA, RB }, PPC_INST_ISELGT }, +{ "iseleq", X(31,79), X_MASK, PPCISEL, { RT, RA, RB }, PPC_INST_ISELEQ }, +{ "isel", XISEL(31,15), XISEL_MASK, PPCISEL, { RT, RA, RB, CRB }, PPC_INST_ISEL }, + +{ "mfocrf", XFXM(31,19,0,1), XFXFXM_MASK, COM, { RT, FXM }, PPC_INST_MFOCRF }, +{ "mfcr", X(31,19), XRARB_MASK, NOPOWER4 | COM, { RT }, PPC_INST_MFCR }, +{ "mfcr", X(31,19), XFXFXM_MASK, POWER4, { RT, FXM4 }, PPC_INST_MFCR }, + +{ "lwarx", X(31,20), XEH_MASK, PPC, { RT, RA0, RB, EH }, PPC_INST_LWARX }, + +{ "ldx", X(31,21), X_MASK, PPC64, { RT, RA0, RB }, PPC_INST_LDX }, + +{ "icbt", X(31,22), X_MASK, BOOKE | PPCE300, { CT, RA, RB }, PPC_INST_ICBT }, +{ "icbt", X(31,262), XRT_MASK, PPC403, { RA, RB }, PPC_INST_ICBT }, + +{ "lwzx", X(31,23), X_MASK, PPCCOM, { RT, RA0, RB }, PPC_INST_LWZX }, +{ "lx", X(31,23), X_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_LX }, + +{ "slw", XRC(31,24,0), X_MASK, PPCCOM, { RA, RS, RB }, PPC_INST_SLW }, +{ "sl", XRC(31,24,0), X_MASK, PWRCOM, { RA, RS, RB }, PPC_INST_SL }, +{ "slw.", XRC(31,24,1), X_MASK, PPCCOM, { RA, RS, RB }, PPC_INST_SLW }, +{ "sl.", XRC(31,24,1), X_MASK, PWRCOM, { RA, RS, RB }, PPC_INST_SL }, + +{ "cntlzw", XRC(31,26,0), XRB_MASK, PPCCOM, { RA, RS }, PPC_INST_CNTLZW }, +{ "cntlz", XRC(31,26,0), XRB_MASK, PWRCOM, { RA, RS }, PPC_INST_CNTLZ }, +{ "cntlzw.", XRC(31,26,1), XRB_MASK, PPCCOM, { RA, RS }, PPC_INST_CNTLZW }, +{ "cntlz.", XRC(31,26,1), XRB_MASK, PWRCOM, { RA, RS }, PPC_INST_CNTLZ }, + +{ "sld", XRC(31,27,0), X_MASK, PPC64, { RA, RS, RB }, PPC_INST_SLD }, +{ "sld.", XRC(31,27,1), X_MASK, PPC64, { RA, RS, RB }, PPC_INST_SLD }, + +{ "and", XRC(31,28,0), X_MASK, COM, { RA, RS, RB }, PPC_INST_AND }, +{ "and.", XRC(31,28,1), X_MASK, COM, { RA, RS, RB }, PPC_INST_AND }, + +{ "maskg", XRC(31,29,0), X_MASK, M601, { RA, RS, RB }, PPC_INST_MASKG }, +{ "maskg.", XRC(31,29,1), X_MASK, M601, { RA, RS, RB }, PPC_INST_MASKG }, + +{ "icbte", X(31,30), X_MASK, BOOKE64, { CT, RA, RB }, PPC_INST_ICBTE }, + +{ "lwzxe", X(31,31), X_MASK, BOOKE64, { RT, RA0, RB }, PPC_INST_LWZXE }, + +{ "cmplw", XOPL(31,32,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB }, PPC_INST_CMPLW }, +{ "cmpld", XOPL(31,32,1), XCMPL_MASK, PPC64, { OBF, RA, RB }, PPC_INST_CMPLD }, +{ "cmpl", X(31,32), XCMP_MASK, PPC, { BF, L, RA, RB }, PPC_INST_CMPL }, +{ "cmpl", X(31,32), XCMPL_MASK, PWRCOM, { BF, RA, RB }, PPC_INST_CMPL }, + +{ "subf", XO(31,40,0,0), XO_MASK, PPC, { RT, RA, RB }, PPC_INST_SUBF }, +{ "sub", XO(31,40,0,0), XO_MASK, PPC, { RT, RB, RA }, PPC_INST_SUB }, +{ "subf.", XO(31,40,0,1), XO_MASK, PPC, { RT, RA, RB }, PPC_INST_SUBF }, +{ "sub.", XO(31,40,0,1), XO_MASK, PPC, { RT, RB, RA }, PPC_INST_SUB }, +{ "subfo", XO(31,40,1,0), XO_MASK, PPC, { RT, RA, RB }, PPC_INST_SUBFO }, +{ "subo", XO(31,40,1,0), XO_MASK, PPC, { RT, RB, RA }, PPC_INST_SUBO }, +{ "subfo.", XO(31,40,1,1), XO_MASK, PPC, { RT, RA, RB }, PPC_INST_SUBFO }, +{ "subo.", XO(31,40,1,1), XO_MASK, PPC, { RT, RB, RA }, PPC_INST_SUBO }, + +{ "ldux", X(31,53), X_MASK, PPC64, { RT, RAL, RB }, PPC_INST_LDUX }, + +{ "dcbst", X(31,54), XRT_MASK, PPC, { RA, RB }, PPC_INST_DCBST }, + +{ "lwzux", X(31,55), X_MASK, PPCCOM, { RT, RAL, RB }, PPC_INST_LWZUX }, +{ "lux", X(31,55), X_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_LUX }, + +{ "dcbste", X(31,62), XRT_MASK, BOOKE64, { RA, RB }, PPC_INST_DCBSTE }, + +{ "lwzuxe", X(31,63), X_MASK, BOOKE64, { RT, RAL, RB }, PPC_INST_LWZUXE }, + +{ "cntlzd", XRC(31,58,0), XRB_MASK, PPC64, { RA, RS }, PPC_INST_CNTLZD }, +{ "cntlzd.", XRC(31,58,1), XRB_MASK, PPC64, { RA, RS }, PPC_INST_CNTLZD }, + +{ "andc", XRC(31,60,0), X_MASK, COM, { RA, RS, RB }, PPC_INST_ANDC }, +{ "andc.", XRC(31,60,1), X_MASK, COM, { RA, RS, RB }, PPC_INST_ANDC }, + +{ "tdlgt", XTO(31,68,TOLGT), XTO_MASK, PPC64, { RA, RB }, PPC_INST_TDLGT }, +{ "tdllt", XTO(31,68,TOLLT), XTO_MASK, PPC64, { RA, RB }, PPC_INST_TDLLT }, +{ "tdeq", XTO(31,68,TOEQ), XTO_MASK, PPC64, { RA, RB }, PPC_INST_TDEQ }, +{ "tdlge", XTO(31,68,TOLGE), XTO_MASK, PPC64, { RA, RB }, PPC_INST_TDLGE }, +{ "tdlnl", XTO(31,68,TOLNL), XTO_MASK, PPC64, { RA, RB }, PPC_INST_TDLNL }, +{ "tdlle", XTO(31,68,TOLLE), XTO_MASK, PPC64, { RA, RB }, PPC_INST_TDLLE }, +{ "tdlng", XTO(31,68,TOLNG), XTO_MASK, PPC64, { RA, RB }, PPC_INST_TDLNG }, +{ "tdgt", XTO(31,68,TOGT), XTO_MASK, PPC64, { RA, RB }, PPC_INST_TDGT }, +{ "tdge", XTO(31,68,TOGE), XTO_MASK, PPC64, { RA, RB }, PPC_INST_TDGE }, +{ "tdnl", XTO(31,68,TONL), XTO_MASK, PPC64, { RA, RB }, PPC_INST_TDNL }, +{ "tdlt", XTO(31,68,TOLT), XTO_MASK, PPC64, { RA, RB }, PPC_INST_TDLT }, +{ "tdle", XTO(31,68,TOLE), XTO_MASK, PPC64, { RA, RB }, PPC_INST_TDLE }, +{ "tdng", XTO(31,68,TONG), XTO_MASK, PPC64, { RA, RB }, PPC_INST_TDNG }, +{ "tdne", XTO(31,68,TONE), XTO_MASK, PPC64, { RA, RB }, PPC_INST_TDNE }, +{ "td", X(31,68), X_MASK, PPC64, { TO, RA, RB }, PPC_INST_TD }, + +{ "mulhd", XO(31,73,0,0), XO_MASK, PPC64, { RT, RA, RB }, PPC_INST_MULHD }, +{ "mulhd.", XO(31,73,0,1), XO_MASK, PPC64, { RT, RA, RB }, PPC_INST_MULHD }, + +{ "mulhw", XO(31,75,0,0), XO_MASK, PPC, { RT, RA, RB }, PPC_INST_MULHW }, +{ "mulhw.", XO(31,75,0,1), XO_MASK, PPC, { RT, RA, RB }, PPC_INST_MULHW }, + +{ "dlmzb", XRC(31,78,0), X_MASK, PPC403 | PPC440, { RA, RS, RB }, PPC_INST_DLMZB }, +{ "dlmzb.", XRC(31,78,1), X_MASK, PPC403 | PPC440, { RA, RS, RB }, PPC_INST_DLMZB }, + +{ "mtsrd", X(31,82), XRB_MASK | (1 << 20), PPC64, { SR, RS }, PPC_INST_MTSRD }, + +{ "mfmsr", X(31,83), XRARB_MASK, COM, { RT }, PPC_INST_MFMSR }, + +{ "ldarx", X(31,84), XEH_MASK, PPC64, { RT, RA0, RB, EH }, PPC_INST_LDARX }, + +{ "dcbfl", XOPL(31,86,1), XRT_MASK, POWER5, { RA, RB }, PPC_INST_DCBFL }, +{ "dcbf", X(31,86), XLRT_MASK, PPC, { RA, RB, L }, PPC_INST_DCBF }, + +{ "lbzx", X(31,87), X_MASK, COM, { RT, RA0, RB }, PPC_INST_LBZX }, + +{ "dcbfe", X(31,94), XRT_MASK, BOOKE64, { RA, RB }, PPC_INST_DCBFE }, + +{ "lbzxe", X(31,95), X_MASK, BOOKE64, { RT, RA0, RB }, PPC_INST_LBZXE }, + +{ "neg", XO(31,104,0,0), XORB_MASK, COM, { RT, RA }, PPC_INST_NEG }, +{ "neg.", XO(31,104,0,1), XORB_MASK, COM, { RT, RA }, PPC_INST_NEG }, +{ "nego", XO(31,104,1,0), XORB_MASK, COM, { RT, RA }, PPC_INST_NEGO }, +{ "nego.", XO(31,104,1,1), XORB_MASK, COM, { RT, RA }, PPC_INST_NEGO }, + +{ "mul", XO(31,107,0,0), XO_MASK, M601, { RT, RA, RB }, PPC_INST_MUL }, +{ "mul.", XO(31,107,0,1), XO_MASK, M601, { RT, RA, RB }, PPC_INST_MUL }, +{ "mulo", XO(31,107,1,0), XO_MASK, M601, { RT, RA, RB }, PPC_INST_MULO }, +{ "mulo.", XO(31,107,1,1), XO_MASK, M601, { RT, RA, RB }, PPC_INST_MULO }, + +{ "mtsrdin", X(31,114), XRA_MASK, PPC64, { RS, RB }, PPC_INST_MTSRDIN }, + +{ "clf", X(31,118), XTO_MASK, POWER, { RA, RB }, PPC_INST_CLF }, + +{ "lbzux", X(31,119), X_MASK, COM, { RT, RAL, RB }, PPC_INST_LBZUX }, + +{ "popcntb", X(31,122), XRB_MASK, POWER5, { RA, RS }, PPC_INST_POPCNTB }, + +{ "not", XRC(31,124,0), X_MASK, COM, { RA, RS, RBS }, PPC_INST_NOT }, +{ "nor", XRC(31,124,0), X_MASK, COM, { RA, RS, RB }, PPC_INST_NOR }, +{ "not.", XRC(31,124,1), X_MASK, COM, { RA, RS, RBS }, PPC_INST_NOT }, +{ "nor.", XRC(31,124,1), X_MASK, COM, { RA, RS, RB }, PPC_INST_NOR }, + +{ "lwarxe", X(31,126), X_MASK, BOOKE64, { RT, RA0, RB }, PPC_INST_LWARXE }, + +{ "lbzuxe", X(31,127), X_MASK, BOOKE64, { RT, RAL, RB }, PPC_INST_LBZUXE }, + +{ "wrtee", X(31,131), XRARB_MASK, PPC403 | BOOKE, { RS }, PPC_INST_WRTEE }, + +{ "dcbtstls",X(31,134), X_MASK, PPCCHLK, { CT, RA, RB }, PPC_INST_DCBTSTLS }, + +{ "subfe", XO(31,136,0,0), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_SUBFE }, +{ "sfe", XO(31,136,0,0), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_SFE }, +{ "subfe.", XO(31,136,0,1), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_SUBFE }, +{ "sfe.", XO(31,136,0,1), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_SFE }, +{ "subfeo", XO(31,136,1,0), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_SUBFEO }, +{ "sfeo", XO(31,136,1,0), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_SFEO }, +{ "subfeo.", XO(31,136,1,1), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_SUBFEO }, +{ "sfeo.", XO(31,136,1,1), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_SFEO }, + +{ "adde", XO(31,138,0,0), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_ADDE }, +{ "ae", XO(31,138,0,0), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_AE }, +{ "adde.", XO(31,138,0,1), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_ADDE }, +{ "ae.", XO(31,138,0,1), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_AE }, +{ "addeo", XO(31,138,1,0), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_ADDEO }, +{ "aeo", XO(31,138,1,0), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_AEO }, +{ "addeo.", XO(31,138,1,1), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_ADDEO }, +{ "aeo.", XO(31,138,1,1), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_AEO }, + +{ "dcbtstlse",X(31,142),X_MASK, PPCCHLK64, { CT, RA, RB }, PPC_INST_DCBTSTLSE }, + +{ "mtocrf", XFXM(31,144,0,1), XFXFXM_MASK, COM, { FXM, RS }, PPC_INST_MTOCRF }, +{ "mtcr", XFXM(31,144,0xff,0), XRARB_MASK, COM, { RS }, PPC_INST_MTCR }, +{ "mtcrf", X(31,144), XFXFXM_MASK, COM, { FXM, RS }, PPC_INST_MTCRF }, + +{ "mtmsr", X(31,146), XRARB_MASK, COM, { RS }, PPC_INST_MTMSR }, + +{ "stdx", X(31,149), X_MASK, PPC64, { RS, RA0, RB }, PPC_INST_STDX }, + +{ "stwcx.", XRC(31,150,1), X_MASK, PPC, { RS, RA0, RB }, PPC_INST_STWCX }, + +{ "stwx", X(31,151), X_MASK, PPCCOM, { RS, RA0, RB }, PPC_INST_STWX }, +{ "stx", X(31,151), X_MASK, PWRCOM, { RS, RA, RB }, PPC_INST_STX }, + +{ "stwcxe.", XRC(31,158,1), X_MASK, BOOKE64, { RS, RA0, RB }, PPC_INST_STWCXE }, + +{ "stwxe", X(31,159), X_MASK, BOOKE64, { RS, RA0, RB }, PPC_INST_STWXE }, + +{ "slq", XRC(31,152,0), X_MASK, M601, { RA, RS, RB }, PPC_INST_SLQ }, +{ "slq.", XRC(31,152,1), X_MASK, M601, { RA, RS, RB }, PPC_INST_SLQ }, + +{ "sle", XRC(31,153,0), X_MASK, M601, { RA, RS, RB }, PPC_INST_SLE }, +{ "sle.", XRC(31,153,1), X_MASK, M601, { RA, RS, RB }, PPC_INST_SLE }, + +{ "prtyw", X(31,154), XRB_MASK, POWER6, { RA, RS }, PPC_INST_PRTYW }, + +{ "wrteei", X(31,163), XE_MASK, PPC403 | BOOKE, { E }, PPC_INST_WRTEEI }, + +{ "dcbtls", X(31,166), X_MASK, PPCCHLK, { CT, RA, RB }, PPC_INST_DCBTLS }, +{ "dcbtlse", X(31,174), X_MASK, PPCCHLK64, { CT, RA, RB }, PPC_INST_DCBTLSE }, + +{ "mtmsrd", X(31,178), XRLARB_MASK, PPC64, { RS, A_L }, PPC_INST_MTMSRD }, + +{ "stdux", X(31,181), X_MASK, PPC64, { RS, RAS, RB }, PPC_INST_STDUX }, + +{ "stwux", X(31,183), X_MASK, PPCCOM, { RS, RAS, RB }, PPC_INST_STWUX }, +{ "stux", X(31,183), X_MASK, PWRCOM, { RS, RA0, RB }, PPC_INST_STUX }, + +{ "sliq", XRC(31,184,0), X_MASK, M601, { RA, RS, SH }, PPC_INST_SLIQ }, +{ "sliq.", XRC(31,184,1), X_MASK, M601, { RA, RS, SH }, PPC_INST_SLIQ }, + +{ "prtyd", X(31,186), XRB_MASK, POWER6, { RA, RS }, PPC_INST_PRTYD }, + +{ "stwuxe", X(31,191), X_MASK, BOOKE64, { RS, RAS, RB }, PPC_INST_STWUXE }, + +{ "subfze", XO(31,200,0,0), XORB_MASK, PPCCOM, { RT, RA }, PPC_INST_SUBFZE }, +{ "sfze", XO(31,200,0,0), XORB_MASK, PWRCOM, { RT, RA }, PPC_INST_SFZE }, +{ "subfze.", XO(31,200,0,1), XORB_MASK, PPCCOM, { RT, RA }, PPC_INST_SUBFZE }, +{ "sfze.", XO(31,200,0,1), XORB_MASK, PWRCOM, { RT, RA }, PPC_INST_SFZE }, +{ "subfzeo", XO(31,200,1,0), XORB_MASK, PPCCOM, { RT, RA }, PPC_INST_SUBFZEO }, +{ "sfzeo", XO(31,200,1,0), XORB_MASK, PWRCOM, { RT, RA }, PPC_INST_SFZEO }, +{ "subfzeo.",XO(31,200,1,1), XORB_MASK, PPCCOM, { RT, RA }, PPC_INST_SUBFZEO }, +{ "sfzeo.", XO(31,200,1,1), XORB_MASK, PWRCOM, { RT, RA }, PPC_INST_SFZEO }, + +{ "addze", XO(31,202,0,0), XORB_MASK, PPCCOM, { RT, RA }, PPC_INST_ADDZE }, +{ "aze", XO(31,202,0,0), XORB_MASK, PWRCOM, { RT, RA }, PPC_INST_AZE }, +{ "addze.", XO(31,202,0,1), XORB_MASK, PPCCOM, { RT, RA }, PPC_INST_ADDZE }, +{ "aze.", XO(31,202,0,1), XORB_MASK, PWRCOM, { RT, RA }, PPC_INST_AZE }, +{ "addzeo", XO(31,202,1,0), XORB_MASK, PPCCOM, { RT, RA }, PPC_INST_ADDZEO }, +{ "azeo", XO(31,202,1,0), XORB_MASK, PWRCOM, { RT, RA }, PPC_INST_AZEO }, +{ "addzeo.", XO(31,202,1,1), XORB_MASK, PPCCOM, { RT, RA }, PPC_INST_ADDZEO }, +{ "azeo.", XO(31,202,1,1), XORB_MASK, PWRCOM, { RT, RA }, PPC_INST_AZEO }, + +{ "mtsr", X(31,210), XRB_MASK | (1 << 20), COM32, { SR, RS }, PPC_INST_MTSR }, + +{ "stdcx.", XRC(31,214,1), X_MASK, PPC64, { RS, RA0, RB }, PPC_INST_STDCX }, + +{ "stbx", X(31,215), X_MASK, COM, { RS, RA0, RB }, PPC_INST_STBX }, + +{ "sllq", XRC(31,216,0), X_MASK, M601, { RA, RS, RB }, PPC_INST_SLLQ }, +{ "sllq.", XRC(31,216,1), X_MASK, M601, { RA, RS, RB }, PPC_INST_SLLQ }, + +{ "sleq", XRC(31,217,0), X_MASK, M601, { RA, RS, RB }, PPC_INST_SLEQ }, +{ "sleq.", XRC(31,217,1), X_MASK, M601, { RA, RS, RB }, PPC_INST_SLEQ }, + +{ "stbxe", X(31,223), X_MASK, BOOKE64, { RS, RA0, RB }, PPC_INST_STBXE }, + +{ "icblc", X(31,230), X_MASK, PPCCHLK, { CT, RA, RB }, PPC_INST_ICBLC }, + +{ "subfme", XO(31,232,0,0), XORB_MASK, PPCCOM, { RT, RA }, PPC_INST_SUBFME }, +{ "sfme", XO(31,232,0,0), XORB_MASK, PWRCOM, { RT, RA }, PPC_INST_SFME }, +{ "subfme.", XO(31,232,0,1), XORB_MASK, PPCCOM, { RT, RA }, PPC_INST_SUBFME }, +{ "sfme.", XO(31,232,0,1), XORB_MASK, PWRCOM, { RT, RA }, PPC_INST_SFME }, +{ "subfmeo", XO(31,232,1,0), XORB_MASK, PPCCOM, { RT, RA }, PPC_INST_SUBFMEO }, +{ "sfmeo", XO(31,232,1,0), XORB_MASK, PWRCOM, { RT, RA }, PPC_INST_SFMEO }, +{ "subfmeo.",XO(31,232,1,1), XORB_MASK, PPCCOM, { RT, RA }, PPC_INST_SUBFMEO }, +{ "sfmeo.", XO(31,232,1,1), XORB_MASK, PWRCOM, { RT, RA }, PPC_INST_SFMEO }, + +{ "mulld", XO(31,233,0,0), XO_MASK, PPC64, { RT, RA, RB }, PPC_INST_MULLD }, +{ "mulld.", XO(31,233,0,1), XO_MASK, PPC64, { RT, RA, RB }, PPC_INST_MULLD }, +{ "mulldo", XO(31,233,1,0), XO_MASK, PPC64, { RT, RA, RB }, PPC_INST_MULLDO }, +{ "mulldo.", XO(31,233,1,1), XO_MASK, PPC64, { RT, RA, RB }, PPC_INST_MULLDO }, + +{ "addme", XO(31,234,0,0), XORB_MASK, PPCCOM, { RT, RA }, PPC_INST_ADDME }, +{ "ame", XO(31,234,0,0), XORB_MASK, PWRCOM, { RT, RA }, PPC_INST_AME }, +{ "addme.", XO(31,234,0,1), XORB_MASK, PPCCOM, { RT, RA }, PPC_INST_ADDME }, +{ "ame.", XO(31,234,0,1), XORB_MASK, PWRCOM, { RT, RA }, PPC_INST_AME }, +{ "addmeo", XO(31,234,1,0), XORB_MASK, PPCCOM, { RT, RA }, PPC_INST_ADDMEO }, +{ "ameo", XO(31,234,1,0), XORB_MASK, PWRCOM, { RT, RA }, PPC_INST_AMEO }, +{ "addmeo.", XO(31,234,1,1), XORB_MASK, PPCCOM, { RT, RA }, PPC_INST_ADDMEO }, +{ "ameo.", XO(31,234,1,1), XORB_MASK, PWRCOM, { RT, RA }, PPC_INST_AMEO }, + +{ "mullw", XO(31,235,0,0), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_MULLW }, +{ "muls", XO(31,235,0,0), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_MULS }, +{ "mullw.", XO(31,235,0,1), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_MULLW }, +{ "muls.", XO(31,235,0,1), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_MULS }, +{ "mullwo", XO(31,235,1,0), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_MULLWO }, +{ "mulso", XO(31,235,1,0), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_MULSO }, +{ "mullwo.", XO(31,235,1,1), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_MULLWO }, +{ "mulso.", XO(31,235,1,1), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_MULSO }, + +{ "icblce", X(31,238), X_MASK, PPCCHLK64, { CT, RA, RB }, PPC_INST_ICBLCE }, +{ "mtsrin", X(31,242), XRA_MASK, PPC32, { RS, RB }, PPC_INST_MTSRIN }, +{ "mtsri", X(31,242), XRA_MASK, POWER32, { RS, RB }, PPC_INST_MTSRI }, + +{ "dcbtst", X(31,246), X_MASK, PPC, { CT, RA, RB }, PPC_INST_DCBTST }, + +{ "stbux", X(31,247), X_MASK, COM, { RS, RAS, RB }, PPC_INST_STBUX }, + +{ "slliq", XRC(31,248,0), X_MASK, M601, { RA, RS, SH }, PPC_INST_SLLIQ }, +{ "slliq.", XRC(31,248,1), X_MASK, M601, { RA, RS, SH }, PPC_INST_SLLIQ }, + +{ "dcbtste", X(31,253), X_MASK, BOOKE64, { CT, RA, RB }, PPC_INST_DCBTSTE }, + +{ "stbuxe", X(31,255), X_MASK, BOOKE64, { RS, RAS, RB }, PPC_INST_STBUXE }, + +{ "mfdcrx", X(31,259), X_MASK, BOOKE, { RS, RA }, PPC_INST_MFDCRX }, + +{ "doz", XO(31,264,0,0), XO_MASK, M601, { RT, RA, RB }, PPC_INST_DOZ }, +{ "doz.", XO(31,264,0,1), XO_MASK, M601, { RT, RA, RB }, PPC_INST_DOZ }, +{ "dozo", XO(31,264,1,0), XO_MASK, M601, { RT, RA, RB }, PPC_INST_DOZO }, +{ "dozo.", XO(31,264,1,1), XO_MASK, M601, { RT, RA, RB }, PPC_INST_DOZO }, + +{ "add", XO(31,266,0,0), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_ADD }, +{ "cax", XO(31,266,0,0), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_CAX }, +{ "add.", XO(31,266,0,1), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_ADD }, +{ "cax.", XO(31,266,0,1), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_CAX }, +{ "addo", XO(31,266,1,0), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_ADDO }, +{ "caxo", XO(31,266,1,0), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_CAXO }, +{ "addo.", XO(31,266,1,1), XO_MASK, PPCCOM, { RT, RA, RB }, PPC_INST_ADDO }, +{ "caxo.", XO(31,266,1,1), XO_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_CAXO }, + +{ "tlbiel", X(31,274), XRTLRA_MASK, POWER4, { RB, L }, PPC_INST_TLBIEL }, + +{ "mfapidi", X(31,275), X_MASK, BOOKE, { RT, RA }, PPC_INST_MFAPIDI }, + +{ "lscbx", XRC(31,277,0), X_MASK, M601, { RT, RA, RB }, PPC_INST_LSCBX }, +{ "lscbx.", XRC(31,277,1), X_MASK, M601, { RT, RA, RB }, PPC_INST_LSCBX }, + +{ "dcbt", X(31,278), X_MASK, PPC, { CT, RA, RB }, PPC_INST_DCBT }, + +{ "lhzx", X(31,279), X_MASK, COM, { RT, RA0, RB }, PPC_INST_LHZX }, + +{ "eqv", XRC(31,284,0), X_MASK, COM, { RA, RS, RB }, PPC_INST_EQV }, +{ "eqv.", XRC(31,284,1), X_MASK, COM, { RA, RS, RB }, PPC_INST_EQV }, + +{ "dcbte", X(31,286), X_MASK, BOOKE64, { CT, RA, RB }, PPC_INST_DCBTE }, + +{ "lhzxe", X(31,287), X_MASK, BOOKE64, { RT, RA0, RB }, PPC_INST_LHZXE }, + +{ "tlbie", X(31,306), XRTLRA_MASK, PPC, { RB, L }, PPC_INST_TLBIE }, +{ "tlbi", X(31,306), XRT_MASK, POWER, { RA0, RB }, PPC_INST_TLBI }, + +{ "eciwx", X(31,310), X_MASK, PPC, { RT, RA, RB }, PPC_INST_ECIWX }, + +{ "lhzux", X(31,311), X_MASK, COM, { RT, RAL, RB }, PPC_INST_LHZUX }, + +{ "xor", XRC(31,316,0), X_MASK, COM, { RA, RS, RB }, PPC_INST_XOR }, +{ "xor.", XRC(31,316,1), X_MASK, COM, { RA, RS, RB }, PPC_INST_XOR }, + +{ "lhzuxe", X(31,319), X_MASK, BOOKE64, { RT, RAL, RB }, PPC_INST_LHZUXE }, + +{ "mfexisr", XSPR(31,323,64), XSPR_MASK, PPC403, { RT }, PPC_INST_MFEXISR }, +{ "mfexier", XSPR(31,323,66), XSPR_MASK, PPC403, { RT }, PPC_INST_MFEXIER }, +{ "mfbr0", XSPR(31,323,128), XSPR_MASK, PPC403, { RT }, PPC_INST_MFBR0 }, +{ "mfbr1", XSPR(31,323,129), XSPR_MASK, PPC403, { RT }, PPC_INST_MFBR1 }, +{ "mfbr2", XSPR(31,323,130), XSPR_MASK, PPC403, { RT }, PPC_INST_MFBR2 }, +{ "mfbr3", XSPR(31,323,131), XSPR_MASK, PPC403, { RT }, PPC_INST_MFBR3 }, +{ "mfbr4", XSPR(31,323,132), XSPR_MASK, PPC403, { RT }, PPC_INST_MFBR4 }, +{ "mfbr5", XSPR(31,323,133), XSPR_MASK, PPC403, { RT }, PPC_INST_MFBR5 }, +{ "mfbr6", XSPR(31,323,134), XSPR_MASK, PPC403, { RT }, PPC_INST_MFBR6 }, +{ "mfbr7", XSPR(31,323,135), XSPR_MASK, PPC403, { RT }, PPC_INST_MFBR7 }, +{ "mfbear", XSPR(31,323,144), XSPR_MASK, PPC403, { RT }, PPC_INST_MFBEAR }, +{ "mfbesr", XSPR(31,323,145), XSPR_MASK, PPC403, { RT }, PPC_INST_MFBESR }, +{ "mfiocr", XSPR(31,323,160), XSPR_MASK, PPC403, { RT }, PPC_INST_MFIOCR }, +{ "mfdmacr0", XSPR(31,323,192), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMACR0 }, +{ "mfdmact0", XSPR(31,323,193), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMACT0 }, +{ "mfdmada0", XSPR(31,323,194), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMADA0 }, +{ "mfdmasa0", XSPR(31,323,195), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMASA0 }, +{ "mfdmacc0", XSPR(31,323,196), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMACC0 }, +{ "mfdmacr1", XSPR(31,323,200), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMACR1 }, +{ "mfdmact1", XSPR(31,323,201), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMACT1 }, +{ "mfdmada1", XSPR(31,323,202), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMADA1 }, +{ "mfdmasa1", XSPR(31,323,203), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMASA1 }, +{ "mfdmacc1", XSPR(31,323,204), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMACC1 }, +{ "mfdmacr2", XSPR(31,323,208), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMACR2 }, +{ "mfdmact2", XSPR(31,323,209), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMACT2 }, +{ "mfdmada2", XSPR(31,323,210), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMADA2 }, +{ "mfdmasa2", XSPR(31,323,211), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMASA2 }, +{ "mfdmacc2", XSPR(31,323,212), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMACC2 }, +{ "mfdmacr3", XSPR(31,323,216), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMACR3 }, +{ "mfdmact3", XSPR(31,323,217), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMACT3 }, +{ "mfdmada3", XSPR(31,323,218), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMADA3 }, +{ "mfdmasa3", XSPR(31,323,219), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMASA3 }, +{ "mfdmacc3", XSPR(31,323,220), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMACC3 }, +{ "mfdmasr", XSPR(31,323,224), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDMASR }, +{ "mfdcr", X(31,323), X_MASK, PPC403 | BOOKE, { RT, SPR }, PPC_INST_MFDCR }, + +{ "div", XO(31,331,0,0), XO_MASK, M601, { RT, RA, RB }, PPC_INST_DIV }, +{ "div.", XO(31,331,0,1), XO_MASK, M601, { RT, RA, RB }, PPC_INST_DIV }, +{ "divo", XO(31,331,1,0), XO_MASK, M601, { RT, RA, RB }, PPC_INST_DIVO }, +{ "divo.", XO(31,331,1,1), XO_MASK, M601, { RT, RA, RB }, PPC_INST_DIVO }, + +{ "mfpmr", X(31,334), X_MASK, PPCPMR, { RT, PMR }, PPC_INST_MFPMR }, + +{ "mfmq", XSPR(31,339,0), XSPR_MASK, M601, { RT }, PPC_INST_MFMQ }, +{ "mfxer", XSPR(31,339,1), XSPR_MASK, COM, { RT }, PPC_INST_MFXER }, +{ "mfrtcu", XSPR(31,339,4), XSPR_MASK, COM, { RT }, PPC_INST_MFRTCU }, +{ "mfrtcl", XSPR(31,339,5), XSPR_MASK, COM, { RT }, PPC_INST_MFRTCL }, +{ "mfdec", XSPR(31,339,6), XSPR_MASK, MFDEC1, { RT }, PPC_INST_MFDEC }, +{ "mfdec", XSPR(31,339,22), XSPR_MASK, MFDEC2, { RT }, PPC_INST_MFDEC }, +{ "mflr", XSPR(31,339,8), XSPR_MASK, COM, { RT }, PPC_INST_MFLR }, +{ "mfctr", XSPR(31,339,9), XSPR_MASK, COM, { RT }, PPC_INST_MFCTR }, +{ "mftid", XSPR(31,339,17), XSPR_MASK, POWER, { RT }, PPC_INST_MFTID }, +{ "mfdsisr", XSPR(31,339,18), XSPR_MASK, COM, { RT }, PPC_INST_MFDSISR }, +{ "mfdar", XSPR(31,339,19), XSPR_MASK, COM, { RT }, PPC_INST_MFDAR }, +{ "mfsdr0", XSPR(31,339,24), XSPR_MASK, POWER, { RT }, PPC_INST_MFSDR0 }, +{ "mfsdr1", XSPR(31,339,25), XSPR_MASK, COM, { RT }, PPC_INST_MFSDR1 }, +{ "mfsrr0", XSPR(31,339,26), XSPR_MASK, COM, { RT }, PPC_INST_MFSRR0 }, +{ "mfsrr1", XSPR(31,339,27), XSPR_MASK, COM, { RT }, PPC_INST_MFSRR1 }, +{ "mfcfar", XSPR(31,339,28), XSPR_MASK, POWER6, { RT }, PPC_INST_MFCFAR }, +{ "mfpid", XSPR(31,339,48), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFPID }, +{ "mfpid", XSPR(31,339,945), XSPR_MASK, PPC403, { RT }, PPC_INST_MFPID }, +{ "mfcsrr0", XSPR(31,339,58), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFCSRR0 }, +{ "mfcsrr1", XSPR(31,339,59), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFCSRR1 }, +{ "mfdear", XSPR(31,339,61), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFDEAR }, +{ "mfdear", XSPR(31,339,981), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDEAR }, +{ "mfesr", XSPR(31,339,62), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFESR }, +{ "mfesr", XSPR(31,339,980), XSPR_MASK, PPC403, { RT }, PPC_INST_MFESR }, +{ "mfivpr", XSPR(31,339,63), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIVPR }, +{ "mfcmpa", XSPR(31,339,144), XSPR_MASK, PPC860, { RT }, PPC_INST_MFCMPA }, +{ "mfcmpb", XSPR(31,339,145), XSPR_MASK, PPC860, { RT }, PPC_INST_MFCMPB }, +{ "mfcmpc", XSPR(31,339,146), XSPR_MASK, PPC860, { RT }, PPC_INST_MFCMPC }, +{ "mfcmpd", XSPR(31,339,147), XSPR_MASK, PPC860, { RT }, PPC_INST_MFCMPD }, +{ "mficr", XSPR(31,339,148), XSPR_MASK, PPC860, { RT }, PPC_INST_MFICR }, +{ "mfder", XSPR(31,339,149), XSPR_MASK, PPC860, { RT }, PPC_INST_MFDER }, +{ "mfcounta", XSPR(31,339,150), XSPR_MASK, PPC860, { RT }, PPC_INST_MFCOUNTA }, +{ "mfcountb", XSPR(31,339,151), XSPR_MASK, PPC860, { RT }, PPC_INST_MFCOUNTB }, +{ "mfcmpe", XSPR(31,339,152), XSPR_MASK, PPC860, { RT }, PPC_INST_MFCMPE }, +{ "mfcmpf", XSPR(31,339,153), XSPR_MASK, PPC860, { RT }, PPC_INST_MFCMPF }, +{ "mfcmpg", XSPR(31,339,154), XSPR_MASK, PPC860, { RT }, PPC_INST_MFCMPG }, +{ "mfcmph", XSPR(31,339,155), XSPR_MASK, PPC860, { RT }, PPC_INST_MFCMPH }, +{ "mflctrl1", XSPR(31,339,156), XSPR_MASK, PPC860, { RT }, PPC_INST_MFLCTRL1 }, +{ "mflctrl2", XSPR(31,339,157), XSPR_MASK, PPC860, { RT }, PPC_INST_MFLCTRL2 }, +{ "mfictrl", XSPR(31,339,158), XSPR_MASK, PPC860, { RT }, PPC_INST_MFICTRL }, +{ "mfbar", XSPR(31,339,159), XSPR_MASK, PPC860, { RT }, PPC_INST_MFBAR }, +{ "mfvrsave", XSPR(31,339,256), XSPR_MASK, PPCVEC, { RT }, PPC_INST_MFVRSAVE }, +{ "mfusprg0", XSPR(31,339,256), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFUSPRG0 }, +{ "mftb", X(31,371), X_MASK, CLASSIC, { RT, TBR }, PPC_INST_MFTB }, +{ "mftb", XSPR(31,339,268), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFTB }, +{ "mftbl", XSPR(31,371,268), XSPR_MASK, CLASSIC, { RT }, PPC_INST_MFTBL }, +{ "mftbl", XSPR(31,339,268), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFTBL }, +{ "mftbu", XSPR(31,371,269), XSPR_MASK, CLASSIC, { RT }, PPC_INST_MFTBU }, +{ "mftbu", XSPR(31,339,269), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFTBU }, +{ "mfsprg", XSPR(31,339,256), XSPRG_MASK, PPC, { RT, SPRG }, PPC_INST_MFSPRG }, +{ "mfsprg0", XSPR(31,339,272), XSPR_MASK, PPC, { RT }, PPC_INST_MFSPRG0 }, +{ "mfsprg1", XSPR(31,339,273), XSPR_MASK, PPC, { RT }, PPC_INST_MFSPRG1 }, +{ "mfsprg2", XSPR(31,339,274), XSPR_MASK, PPC, { RT }, PPC_INST_MFSPRG2 }, +{ "mfsprg3", XSPR(31,339,275), XSPR_MASK, PPC, { RT }, PPC_INST_MFSPRG3 }, +{ "mfsprg4", XSPR(31,339,260), XSPR_MASK, PPC405 | BOOKE, { RT }, PPC_INST_MFSPRG4 }, +{ "mfsprg5", XSPR(31,339,261), XSPR_MASK, PPC405 | BOOKE, { RT }, PPC_INST_MFSPRG5 }, +{ "mfsprg6", XSPR(31,339,262), XSPR_MASK, PPC405 | BOOKE, { RT }, PPC_INST_MFSPRG6 }, +{ "mfsprg7", XSPR(31,339,263), XSPR_MASK, PPC405 | BOOKE, { RT }, PPC_INST_MFSPRG7 }, +{ "mfasr", XSPR(31,339,280), XSPR_MASK, PPC64, { RT }, PPC_INST_MFASR }, +{ "mfear", XSPR(31,339,282), XSPR_MASK, PPC, { RT }, PPC_INST_MFEAR }, +{ "mfpir", XSPR(31,339,286), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFPIR }, +{ "mfpvr", XSPR(31,339,287), XSPR_MASK, PPC, { RT }, PPC_INST_MFPVR }, +{ "mfdbsr", XSPR(31,339,304), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFDBSR }, +{ "mfdbsr", XSPR(31,339,1008), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDBSR }, +{ "mfdbcr0", XSPR(31,339,308), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFDBCR0 }, +{ "mfdbcr0", XSPR(31,339,1010), XSPR_MASK, PPC405, { RT }, PPC_INST_MFDBCR0 }, +{ "mfdbcr1", XSPR(31,339,309), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFDBCR1 }, +{ "mfdbcr1", XSPR(31,339,957), XSPR_MASK, PPC405, { RT }, PPC_INST_MFDBCR1 }, +{ "mfdbcr2", XSPR(31,339,310), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFDBCR2 }, +{ "mfiac1", XSPR(31,339,312), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIAC1 }, +{ "mfiac1", XSPR(31,339,1012), XSPR_MASK, PPC403, { RT }, PPC_INST_MFIAC1 }, +{ "mfiac2", XSPR(31,339,313), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIAC2 }, +{ "mfiac2", XSPR(31,339,1013), XSPR_MASK, PPC403, { RT }, PPC_INST_MFIAC2 }, +{ "mfiac3", XSPR(31,339,314), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIAC3 }, +{ "mfiac3", XSPR(31,339,948), XSPR_MASK, PPC405, { RT }, PPC_INST_MFIAC3 }, +{ "mfiac4", XSPR(31,339,315), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIAC4 }, +{ "mfiac4", XSPR(31,339,949), XSPR_MASK, PPC405, { RT }, PPC_INST_MFIAC4 }, +{ "mfdac1", XSPR(31,339,316), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFDAC1 }, +{ "mfdac1", XSPR(31,339,1014), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDAC1 }, +{ "mfdac2", XSPR(31,339,317), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFDAC2 }, +{ "mfdac2", XSPR(31,339,1015), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDAC2 }, +{ "mfdvc1", XSPR(31,339,318), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFDVC1 }, +{ "mfdvc1", XSPR(31,339,950), XSPR_MASK, PPC405, { RT }, PPC_INST_MFDVC1 }, +{ "mfdvc2", XSPR(31,339,319), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFDVC2 }, +{ "mfdvc2", XSPR(31,339,951), XSPR_MASK, PPC405, { RT }, PPC_INST_MFDVC2 }, +{ "mftsr", XSPR(31,339,336), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFTSR }, +{ "mftsr", XSPR(31,339,984), XSPR_MASK, PPC403, { RT }, PPC_INST_MFTSR }, +{ "mftcr", XSPR(31,339,340), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFTCR }, +{ "mftcr", XSPR(31,339,986), XSPR_MASK, PPC403, { RT }, PPC_INST_MFTCR }, +{ "mfivor0", XSPR(31,339,400), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIVOR0 }, +{ "mfivor1", XSPR(31,339,401), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIVOR1 }, +{ "mfivor2", XSPR(31,339,402), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIVOR2 }, +{ "mfivor3", XSPR(31,339,403), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIVOR3 }, +{ "mfivor4", XSPR(31,339,404), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIVOR4 }, +{ "mfivor5", XSPR(31,339,405), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIVOR5 }, +{ "mfivor6", XSPR(31,339,406), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIVOR6 }, +{ "mfivor7", XSPR(31,339,407), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIVOR7 }, +{ "mfivor8", XSPR(31,339,408), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIVOR8 }, +{ "mfivor9", XSPR(31,339,409), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIVOR9 }, +{ "mfivor10", XSPR(31,339,410), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIVOR10 }, +{ "mfivor11", XSPR(31,339,411), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIVOR11 }, +{ "mfivor12", XSPR(31,339,412), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIVOR12 }, +{ "mfivor13", XSPR(31,339,413), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIVOR13 }, +{ "mfivor14", XSPR(31,339,414), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIVOR14 }, +{ "mfivor15", XSPR(31,339,415), XSPR_MASK, BOOKE, { RT }, PPC_INST_MFIVOR15 }, +{ "mfspefscr", XSPR(31,339,512), XSPR_MASK, PPCSPE, { RT }, PPC_INST_MFSPEFSCR }, +{ "mfbbear", XSPR(31,339,513), XSPR_MASK, PPCBRLK, { RT }, PPC_INST_MFBBEAR }, +{ "mfbbtar", XSPR(31,339,514), XSPR_MASK, PPCBRLK, { RT }, PPC_INST_MFBBTAR }, +{ "mfivor32", XSPR(31,339,528), XSPR_MASK, PPCSPE, { RT }, PPC_INST_MFIVOR32 }, +{ "mfivor33", XSPR(31,339,529), XSPR_MASK, PPCSPE, { RT }, PPC_INST_MFIVOR33 }, +{ "mfivor34", XSPR(31,339,530), XSPR_MASK, PPCSPE, { RT }, PPC_INST_MFIVOR34 }, +{ "mfivor35", XSPR(31,339,531), XSPR_MASK, PPCPMR, { RT }, PPC_INST_MFIVOR35 }, +{ "mfibatu", XSPR(31,339,528), XSPRBAT_MASK, PPC, { RT, SPRBAT }, PPC_INST_MFIBATU }, +{ "mfibatl", XSPR(31,339,529), XSPRBAT_MASK, PPC, { RT, SPRBAT }, PPC_INST_MFIBATL }, +{ "mfdbatu", XSPR(31,339,536), XSPRBAT_MASK, PPC, { RT, SPRBAT }, PPC_INST_MFDBATU }, +{ "mfdbatl", XSPR(31,339,537), XSPRBAT_MASK, PPC, { RT, SPRBAT }, PPC_INST_MFDBATL }, +{ "mfic_cst", XSPR(31,339,560), XSPR_MASK, PPC860, { RT }, PPC_INST_MFIC_CST }, +{ "mfic_adr", XSPR(31,339,561), XSPR_MASK, PPC860, { RT }, PPC_INST_MFIC_ADR }, +{ "mfic_dat", XSPR(31,339,562), XSPR_MASK, PPC860, { RT }, PPC_INST_MFIC_DAT }, +{ "mfdc_cst", XSPR(31,339,568), XSPR_MASK, PPC860, { RT }, PPC_INST_MFDC_CST }, +{ "mfdc_adr", XSPR(31,339,569), XSPR_MASK, PPC860, { RT }, PPC_INST_MFDC_ADR }, +{ "mfmcsrr0", XSPR(31,339,570), XSPR_MASK, PPCRFMCI, { RT }, PPC_INST_MFMCSRR0 }, +{ "mfdc_dat", XSPR(31,339,570), XSPR_MASK, PPC860, { RT }, PPC_INST_MFDC_DAT }, +{ "mfmcsrr1", XSPR(31,339,571), XSPR_MASK, PPCRFMCI, { RT }, PPC_INST_MFMCSRR1 }, +{ "mfmcsr", XSPR(31,339,572), XSPR_MASK, PPCRFMCI, { RT }, PPC_INST_MFMCSR }, +{ "mfmcar", XSPR(31,339,573), XSPR_MASK, PPCRFMCI, { RT }, PPC_INST_MFMCAR }, +{ "mfdpdr", XSPR(31,339,630), XSPR_MASK, PPC860, { RT }, PPC_INST_MFDPDR }, +{ "mfdpir", XSPR(31,339,631), XSPR_MASK, PPC860, { RT }, PPC_INST_MFDPIR }, +{ "mfimmr", XSPR(31,339,638), XSPR_MASK, PPC860, { RT }, PPC_INST_MFIMMR }, +{ "mfmi_ctr", XSPR(31,339,784), XSPR_MASK, PPC860, { RT }, PPC_INST_MFMI_CTR }, +{ "mfmi_ap", XSPR(31,339,786), XSPR_MASK, PPC860, { RT }, PPC_INST_MFMI_AP }, +{ "mfmi_epn", XSPR(31,339,787), XSPR_MASK, PPC860, { RT }, PPC_INST_MFMI_EPN }, +{ "mfmi_twc", XSPR(31,339,789), XSPR_MASK, PPC860, { RT }, PPC_INST_MFMI_TWC }, +{ "mfmi_rpn", XSPR(31,339,790), XSPR_MASK, PPC860, { RT }, PPC_INST_MFMI_RPN }, +{ "mfmd_ctr", XSPR(31,339,792), XSPR_MASK, PPC860, { RT }, PPC_INST_MFMD_CTR }, +{ "mfm_casid", XSPR(31,339,793), XSPR_MASK, PPC860, { RT }, PPC_INST_MFM_CASID }, +{ "mfmd_ap", XSPR(31,339,794), XSPR_MASK, PPC860, { RT }, PPC_INST_MFMD_AP }, +{ "mfmd_epn", XSPR(31,339,795), XSPR_MASK, PPC860, { RT }, PPC_INST_MFMD_EPN }, +{ "mfmd_twb", XSPR(31,339,796), XSPR_MASK, PPC860, { RT }, PPC_INST_MFMD_TWB }, +{ "mfmd_twc", XSPR(31,339,797), XSPR_MASK, PPC860, { RT }, PPC_INST_MFMD_TWC }, +{ "mfmd_rpn", XSPR(31,339,798), XSPR_MASK, PPC860, { RT }, PPC_INST_MFMD_RPN }, +{ "mfm_tw", XSPR(31,339,799), XSPR_MASK, PPC860, { RT }, PPC_INST_MFM_TW }, +{ "mfmi_dbcam", XSPR(31,339,816), XSPR_MASK, PPC860, { RT }, PPC_INST_MFMI_DBCAM }, +{ "mfmi_dbram0",XSPR(31,339,817), XSPR_MASK, PPC860, { RT }, PPC_INST_MFMI_DBRAM0 }, +{ "mfmi_dbram1",XSPR(31,339,818), XSPR_MASK, PPC860, { RT }, PPC_INST_MFMI_DBRAM1 }, +{ "mfmd_dbcam", XSPR(31,339,824), XSPR_MASK, PPC860, { RT }, PPC_INST_MFMD_DBCAM }, +{ "mfmd_dbram0",XSPR(31,339,825), XSPR_MASK, PPC860, { RT }, PPC_INST_MFMD_DBRAM0 }, +{ "mfmd_dbram1",XSPR(31,339,826), XSPR_MASK, PPC860, { RT }, PPC_INST_MFMD_DBRAM1 }, +{ "mfummcr0", XSPR(31,339,936), XSPR_MASK, PPC750, { RT }, PPC_INST_MFUMMCR0 }, +{ "mfupmc1", XSPR(31,339,937), XSPR_MASK, PPC750, { RT }, PPC_INST_MFUPMC1 }, +{ "mfupmc2", XSPR(31,339,938), XSPR_MASK, PPC750, { RT }, PPC_INST_MFUPMC2 }, +{ "mfusia", XSPR(31,339,939), XSPR_MASK, PPC750, { RT }, PPC_INST_MFUSIA }, +{ "mfummcr1", XSPR(31,339,940), XSPR_MASK, PPC750, { RT }, PPC_INST_MFUMMCR1 }, +{ "mfupmc3", XSPR(31,339,941), XSPR_MASK, PPC750, { RT }, PPC_INST_MFUPMC3 }, +{ "mfupmc4", XSPR(31,339,942), XSPR_MASK, PPC750, { RT }, PPC_INST_MFUPMC4 }, +{ "mfzpr", XSPR(31,339,944), XSPR_MASK, PPC403, { RT }, PPC_INST_MFZPR }, +{ "mfccr0", XSPR(31,339,947), XSPR_MASK, PPC405, { RT }, PPC_INST_MFCCR0 }, +{ "mfmmcr0", XSPR(31,339,952), XSPR_MASK, PPC750, { RT }, PPC_INST_MFMMCR0 }, +{ "mfpmc1", XSPR(31,339,953), XSPR_MASK, PPC750, { RT }, PPC_INST_MFPMC1 }, +{ "mfsgr", XSPR(31,339,953), XSPR_MASK, PPC403, { RT }, PPC_INST_MFSGR }, +{ "mfpmc2", XSPR(31,339,954), XSPR_MASK, PPC750, { RT }, PPC_INST_MFPMC2 }, +{ "mfdcwr", XSPR(31,339,954), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDCWR }, +{ "mfsia", XSPR(31,339,955), XSPR_MASK, PPC750, { RT }, PPC_INST_MFSIA }, +{ "mfsler", XSPR(31,339,955), XSPR_MASK, PPC405, { RT }, PPC_INST_MFSLER }, +{ "mfmmcr1", XSPR(31,339,956), XSPR_MASK, PPC750, { RT }, PPC_INST_MFMMCR1 }, +{ "mfsu0r", XSPR(31,339,956), XSPR_MASK, PPC405, { RT }, PPC_INST_MFSU0R }, +{ "mfpmc3", XSPR(31,339,957), XSPR_MASK, PPC750, { RT }, PPC_INST_MFPMC3 }, +{ "mfpmc4", XSPR(31,339,958), XSPR_MASK, PPC750, { RT }, PPC_INST_MFPMC4 }, +{ "mficdbdr", XSPR(31,339,979), XSPR_MASK, PPC403, { RT }, PPC_INST_MFICDBDR }, +{ "mfevpr", XSPR(31,339,982), XSPR_MASK, PPC403, { RT }, PPC_INST_MFEVPR }, +{ "mfcdbcr", XSPR(31,339,983), XSPR_MASK, PPC403, { RT }, PPC_INST_MFCDBCR }, +{ "mfpit", XSPR(31,339,987), XSPR_MASK, PPC403, { RT }, PPC_INST_MFPIT }, +{ "mftbhi", XSPR(31,339,988), XSPR_MASK, PPC403, { RT }, PPC_INST_MFTBHI }, +{ "mftblo", XSPR(31,339,989), XSPR_MASK, PPC403, { RT }, PPC_INST_MFTBLO }, +{ "mfsrr2", XSPR(31,339,990), XSPR_MASK, PPC403, { RT }, PPC_INST_MFSRR2 }, +{ "mfsrr3", XSPR(31,339,991), XSPR_MASK, PPC403, { RT }, PPC_INST_MFSRR3 }, +{ "mfl2cr", XSPR(31,339,1017), XSPR_MASK, PPC750, { RT }, PPC_INST_MFL2CR }, +{ "mfdccr", XSPR(31,339,1018), XSPR_MASK, PPC403, { RT }, PPC_INST_MFDCCR }, +{ "mficcr", XSPR(31,339,1019), XSPR_MASK, PPC403, { RT }, PPC_INST_MFICCR }, +{ "mfictc", XSPR(31,339,1019), XSPR_MASK, PPC750, { RT }, PPC_INST_MFICTC }, +{ "mfpbl1", XSPR(31,339,1020), XSPR_MASK, PPC403, { RT }, PPC_INST_MFPBL1 }, +{ "mfthrm1", XSPR(31,339,1020), XSPR_MASK, PPC750, { RT }, PPC_INST_MFTHRM1 }, +{ "mfpbu1", XSPR(31,339,1021), XSPR_MASK, PPC403, { RT }, PPC_INST_MFPBU1 }, +{ "mfthrm2", XSPR(31,339,1021), XSPR_MASK, PPC750, { RT }, PPC_INST_MFTHRM2 }, +{ "mfpbl2", XSPR(31,339,1022), XSPR_MASK, PPC403, { RT }, PPC_INST_MFPBL2 }, +{ "mfthrm3", XSPR(31,339,1022), XSPR_MASK, PPC750, { RT }, PPC_INST_MFTHRM3 }, +{ "mfpbu2", XSPR(31,339,1023), XSPR_MASK, PPC403, { RT }, PPC_INST_MFPBU2 }, +{ "mfspr", X(31,339), X_MASK, COM, { RT, SPR }, PPC_INST_MFSPR }, + +{ "lwax", X(31,341), X_MASK, PPC64, { RT, RA0, RB }, PPC_INST_LWAX }, + +{ "dst", XDSS(31,342,0), XDSS_MASK, PPCVEC, { RA, RB, STRM }, PPC_INST_DST }, +{ "dstt", XDSS(31,342,1), XDSS_MASK, PPCVEC, { RA, RB, STRM }, PPC_INST_DSTT }, + +{ "lhax", X(31,343), X_MASK, COM, { RT, RA0, RB }, PPC_INST_LHAX }, + +{ "lhaxe", X(31,351), X_MASK, BOOKE64, { RT, RA0, RB }, PPC_INST_LHAXE }, + +{ "dstst", XDSS(31,374,0), XDSS_MASK, PPCVEC, { RA, RB, STRM }, PPC_INST_DSTST }, +{ "dststt", XDSS(31,374,1), XDSS_MASK, PPCVEC, { RA, RB, STRM }, PPC_INST_DSTSTT }, + +{ "dccci", X(31,454), XRT_MASK, PPC403 | PPC440, { RA, RB }, PPC_INST_DCCCI }, + +{ "abs", XO(31,360,0,0), XORB_MASK, M601, { RT, RA }, PPC_INST_ABS }, +{ "abs.", XO(31,360,0,1), XORB_MASK, M601, { RT, RA }, PPC_INST_ABS }, +{ "abso", XO(31,360,1,0), XORB_MASK, M601, { RT, RA }, PPC_INST_ABSO }, +{ "abso.", XO(31,360,1,1), XORB_MASK, M601, { RT, RA }, PPC_INST_ABSO }, + +{ "divs", XO(31,363,0,0), XO_MASK, M601, { RT, RA, RB }, PPC_INST_DIVS }, +{ "divs.", XO(31,363,0,1), XO_MASK, M601, { RT, RA, RB }, PPC_INST_DIVS }, +{ "divso", XO(31,363,1,0), XO_MASK, M601, { RT, RA, RB }, PPC_INST_DIVSO }, +{ "divso.", XO(31,363,1,1), XO_MASK, M601, { RT, RA, RB }, PPC_INST_DIVSO }, + +{ "tlbia", X(31,370), 0xffffffff, PPC, { 0 }, PPC_INST_TLBIA }, + +{ "lwaux", X(31,373), X_MASK, PPC64, { RT, RAL, RB }, PPC_INST_LWAUX }, + +{ "lhaux", X(31,375), X_MASK, COM, { RT, RAL, RB }, PPC_INST_LHAUX }, + +{ "lhauxe", X(31,383), X_MASK, BOOKE64, { RT, RAL, RB }, PPC_INST_LHAUXE }, + +{ "mtdcrx", X(31,387), X_MASK, BOOKE, { RA, RS }, PPC_INST_MTDCRX }, + +{ "dcblc", X(31,390), X_MASK, PPCCHLK, { CT, RA, RB }, PPC_INST_DCBLC }, + +{ "subfe64", XO(31,392,0,0), XO_MASK, BOOKE64, { RT, RA, RB }, PPC_INST_SUBFE64 }, +{ "subfe64o",XO(31,392,1,0), XO_MASK, BOOKE64, { RT, RA, RB }, PPC_INST_SUBFE64O }, + +{ "adde64", XO(31,394,0,0), XO_MASK, BOOKE64, { RT, RA, RB }, PPC_INST_ADDE64 }, +{ "adde64o", XO(31,394,1,0), XO_MASK, BOOKE64, { RT, RA, RB }, PPC_INST_ADDE64O }, + +{ "dcblce", X(31,398), X_MASK, PPCCHLK64, { CT, RA, RB }, PPC_INST_DCBLCE }, + +{ "slbmte", X(31,402), XRA_MASK, PPC64, { RS, RB }, PPC_INST_SLBMTE }, + +{ "sthx", X(31,407), X_MASK, COM, { RS, RA0, RB }, PPC_INST_STHX }, + +{ "cmpb", X(31,508), X_MASK, POWER6, { RA, RS, RB }, PPC_INST_CMPB }, + +{ "lfqx", X(31,791), X_MASK, POWER2, { FRT, RA, RB }, PPC_INST_LFQX }, + +{ "lfdpx", X(31,791), X_MASK, POWER6, { FRT, RA, RB }, PPC_INST_LFDPX }, + +{ "lfqux", X(31,823), X_MASK, POWER2, { FRT, RA, RB }, PPC_INST_LFQUX }, + +{ "stfqx", X(31,919), X_MASK, POWER2, { FRS, RA, RB }, PPC_INST_STFQX }, + +{ "stfdpx", X(31,919), X_MASK, POWER6, { FRS, RA, RB }, PPC_INST_STFDPX }, + +{ "stfqux", X(31,951), X_MASK, POWER2, { FRS, RA, RB }, PPC_INST_STFQUX }, + +{ "orc", XRC(31,412,0), X_MASK, COM, { RA, RS, RB }, PPC_INST_ORC }, +{ "orc.", XRC(31,412,1), X_MASK, COM, { RA, RS, RB }, PPC_INST_ORC }, + +{ "sradi", XS(31,413,0), XS_MASK, PPC64, { RA, RS, SH6 }, PPC_INST_SRADI }, +{ "sradi.", XS(31,413,1), XS_MASK, PPC64, { RA, RS, SH6 }, PPC_INST_SRADI }, + +{ "sthxe", X(31,415), X_MASK, BOOKE64, { RS, RA0, RB }, PPC_INST_STHXE }, + +{ "slbie", X(31,434), XRTRA_MASK, PPC64, { RB }, PPC_INST_SLBIE }, + +{ "ecowx", X(31,438), X_MASK, PPC, { RT, RA, RB }, PPC_INST_ECOWX }, + +{ "sthux", X(31,439), X_MASK, COM, { RS, RAS, RB }, PPC_INST_STHUX }, + +{ "sthuxe", X(31,447), X_MASK, BOOKE64, { RS, RAS, RB }, PPC_INST_STHUXE }, + +{ "cctpl", 0x7c210b78, 0xffffffff, CELL, { 0 }, PPC_INST_CCTPL }, +{ "cctpm", 0x7c421378, 0xffffffff, CELL, { 0 }, PPC_INST_CCTPM }, +{ "cctph", 0x7c631b78, 0xffffffff, CELL, { 0 }, PPC_INST_CCTPH }, +{ "db8cyc", 0x7f9ce378, 0xffffffff, CELL, { 0 }, PPC_INST_DB8CYC }, +{ "db10cyc", 0x7fbdeb78, 0xffffffff, CELL, { 0 }, PPC_INST_DB10CYC }, +{ "db12cyc", 0x7fdef378, 0xffffffff, CELL, { 0 }, PPC_INST_DB12CYC }, +{ "db16cyc", 0x7ffffb78, 0xffffffff, CELL, { 0 }, PPC_INST_DB16CYC }, +{ "mr", XRC(31,444,0), X_MASK, COM, { RA, RS, RBS }, PPC_INST_MR }, +{ "or", XRC(31,444,0), X_MASK, COM, { RA, RS, RB }, PPC_INST_OR }, +{ "mr.", XRC(31,444,1), X_MASK, COM, { RA, RS, RBS }, PPC_INST_MR }, +{ "or.", XRC(31,444,1), X_MASK, COM, { RA, RS, RB }, PPC_INST_OR }, + +{ "mtexisr", XSPR(31,451,64), XSPR_MASK, PPC403, { RS }, PPC_INST_MTEXISR }, +{ "mtexier", XSPR(31,451,66), XSPR_MASK, PPC403, { RS }, PPC_INST_MTEXIER }, +{ "mtbr0", XSPR(31,451,128), XSPR_MASK, PPC403, { RS }, PPC_INST_MTBR0 }, +{ "mtbr1", XSPR(31,451,129), XSPR_MASK, PPC403, { RS }, PPC_INST_MTBR1 }, +{ "mtbr2", XSPR(31,451,130), XSPR_MASK, PPC403, { RS }, PPC_INST_MTBR2 }, +{ "mtbr3", XSPR(31,451,131), XSPR_MASK, PPC403, { RS }, PPC_INST_MTBR3 }, +{ "mtbr4", XSPR(31,451,132), XSPR_MASK, PPC403, { RS }, PPC_INST_MTBR4 }, +{ "mtbr5", XSPR(31,451,133), XSPR_MASK, PPC403, { RS }, PPC_INST_MTBR5 }, +{ "mtbr6", XSPR(31,451,134), XSPR_MASK, PPC403, { RS }, PPC_INST_MTBR6 }, +{ "mtbr7", XSPR(31,451,135), XSPR_MASK, PPC403, { RS }, PPC_INST_MTBR7 }, +{ "mtbear", XSPR(31,451,144), XSPR_MASK, PPC403, { RS }, PPC_INST_MTBEAR }, +{ "mtbesr", XSPR(31,451,145), XSPR_MASK, PPC403, { RS }, PPC_INST_MTBESR }, +{ "mtiocr", XSPR(31,451,160), XSPR_MASK, PPC403, { RS }, PPC_INST_MTIOCR }, +{ "mtdmacr0", XSPR(31,451,192), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMACR0 }, +{ "mtdmact0", XSPR(31,451,193), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMACT0 }, +{ "mtdmada0", XSPR(31,451,194), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMADA0 }, +{ "mtdmasa0", XSPR(31,451,195), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMASA0 }, +{ "mtdmacc0", XSPR(31,451,196), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMACC0 }, +{ "mtdmacr1", XSPR(31,451,200), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMACR1 }, +{ "mtdmact1", XSPR(31,451,201), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMACT1 }, +{ "mtdmada1", XSPR(31,451,202), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMADA1 }, +{ "mtdmasa1", XSPR(31,451,203), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMASA1 }, +{ "mtdmacc1", XSPR(31,451,204), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMACC1 }, +{ "mtdmacr2", XSPR(31,451,208), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMACR2 }, +{ "mtdmact2", XSPR(31,451,209), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMACT2 }, +{ "mtdmada2", XSPR(31,451,210), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMADA2 }, +{ "mtdmasa2", XSPR(31,451,211), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMASA2 }, +{ "mtdmacc2", XSPR(31,451,212), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMACC2 }, +{ "mtdmacr3", XSPR(31,451,216), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMACR3 }, +{ "mtdmact3", XSPR(31,451,217), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMACT3 }, +{ "mtdmada3", XSPR(31,451,218), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMADA3 }, +{ "mtdmasa3", XSPR(31,451,219), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMASA3 }, +{ "mtdmacc3", XSPR(31,451,220), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMACC3 }, +{ "mtdmasr", XSPR(31,451,224), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDMASR }, +{ "mtdcr", X(31,451), X_MASK, PPC403 | BOOKE, { SPR, RS }, PPC_INST_MTDCR }, + +{ "subfze64",XO(31,456,0,0), XORB_MASK, BOOKE64, { RT, RA }, PPC_INST_SUBFZE64 }, +{ "subfze64o",XO(31,456,1,0), XORB_MASK, BOOKE64, { RT, RA }, PPC_INST_SUBFZE64O }, + +{ "divdu", XO(31,457,0,0), XO_MASK, PPC64, { RT, RA, RB }, PPC_INST_DIVDU }, +{ "divdu.", XO(31,457,0,1), XO_MASK, PPC64, { RT, RA, RB }, PPC_INST_DIVDU }, +{ "divduo", XO(31,457,1,0), XO_MASK, PPC64, { RT, RA, RB }, PPC_INST_DIVDUO }, +{ "divduo.", XO(31,457,1,1), XO_MASK, PPC64, { RT, RA, RB }, PPC_INST_DIVDUO }, + +{ "addze64", XO(31,458,0,0), XORB_MASK, BOOKE64, { RT, RA }, PPC_INST_ADDZE64 }, +{ "addze64o",XO(31,458,1,0), XORB_MASK, BOOKE64, { RT, RA }, PPC_INST_ADDZE64O }, + +{ "divwu", XO(31,459,0,0), XO_MASK, PPC, { RT, RA, RB }, PPC_INST_DIVWU }, +{ "divwu.", XO(31,459,0,1), XO_MASK, PPC, { RT, RA, RB }, PPC_INST_DIVWU }, +{ "divwuo", XO(31,459,1,0), XO_MASK, PPC, { RT, RA, RB }, PPC_INST_DIVWUO }, +{ "divwuo.", XO(31,459,1,1), XO_MASK, PPC, { RT, RA, RB }, PPC_INST_DIVWUO }, + +{ "mtmq", XSPR(31,467,0), XSPR_MASK, M601, { RS }, PPC_INST_MTMQ }, +{ "mtxer", XSPR(31,467,1), XSPR_MASK, COM, { RS }, PPC_INST_MTXER }, +{ "mtlr", XSPR(31,467,8), XSPR_MASK, COM, { RS }, PPC_INST_MTLR }, +{ "mtctr", XSPR(31,467,9), XSPR_MASK, COM, { RS }, PPC_INST_MTCTR }, +{ "mttid", XSPR(31,467,17), XSPR_MASK, POWER, { RS }, PPC_INST_MTTID }, +{ "mtdsisr", XSPR(31,467,18), XSPR_MASK, COM, { RS }, PPC_INST_MTDSISR }, +{ "mtdar", XSPR(31,467,19), XSPR_MASK, COM, { RS }, PPC_INST_MTDAR }, +{ "mtrtcu", XSPR(31,467,20), XSPR_MASK, COM, { RS }, PPC_INST_MTRTCU }, +{ "mtrtcl", XSPR(31,467,21), XSPR_MASK, COM, { RS }, PPC_INST_MTRTCL }, +{ "mtdec", XSPR(31,467,22), XSPR_MASK, COM, { RS }, PPC_INST_MTDEC }, +{ "mtsdr0", XSPR(31,467,24), XSPR_MASK, POWER, { RS }, PPC_INST_MTSDR0 }, +{ "mtsdr1", XSPR(31,467,25), XSPR_MASK, COM, { RS }, PPC_INST_MTSDR1 }, +{ "mtsrr0", XSPR(31,467,26), XSPR_MASK, COM, { RS }, PPC_INST_MTSRR0 }, +{ "mtsrr1", XSPR(31,467,27), XSPR_MASK, COM, { RS }, PPC_INST_MTSRR1 }, +{ "mtcfar", XSPR(31,467,28), XSPR_MASK, POWER6, { RS }, PPC_INST_MTCFAR }, +{ "mtpid", XSPR(31,467,48), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTPID }, +{ "mtpid", XSPR(31,467,945), XSPR_MASK, PPC403, { RS }, PPC_INST_MTPID }, +{ "mtdecar", XSPR(31,467,54), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTDECAR }, +{ "mtcsrr0", XSPR(31,467,58), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTCSRR0 }, +{ "mtcsrr1", XSPR(31,467,59), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTCSRR1 }, +{ "mtdear", XSPR(31,467,61), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTDEAR }, +{ "mtdear", XSPR(31,467,981), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDEAR }, +{ "mtesr", XSPR(31,467,62), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTESR }, +{ "mtesr", XSPR(31,467,980), XSPR_MASK, PPC403, { RS }, PPC_INST_MTESR }, +{ "mtivpr", XSPR(31,467,63), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIVPR }, +{ "mtcmpa", XSPR(31,467,144), XSPR_MASK, PPC860, { RS }, PPC_INST_MTCMPA }, +{ "mtcmpb", XSPR(31,467,145), XSPR_MASK, PPC860, { RS }, PPC_INST_MTCMPB }, +{ "mtcmpc", XSPR(31,467,146), XSPR_MASK, PPC860, { RS }, PPC_INST_MTCMPC }, +{ "mtcmpd", XSPR(31,467,147), XSPR_MASK, PPC860, { RS }, PPC_INST_MTCMPD }, +{ "mticr", XSPR(31,467,148), XSPR_MASK, PPC860, { RS }, PPC_INST_MTICR }, +{ "mtder", XSPR(31,467,149), XSPR_MASK, PPC860, { RS }, PPC_INST_MTDER }, +{ "mtcounta", XSPR(31,467,150), XSPR_MASK, PPC860, { RS }, PPC_INST_MTCOUNTA }, +{ "mtcountb", XSPR(31,467,151), XSPR_MASK, PPC860, { RS }, PPC_INST_MTCOUNTB }, +{ "mtcmpe", XSPR(31,467,152), XSPR_MASK, PPC860, { RS }, PPC_INST_MTCMPE }, +{ "mtcmpf", XSPR(31,467,153), XSPR_MASK, PPC860, { RS }, PPC_INST_MTCMPF }, +{ "mtcmpg", XSPR(31,467,154), XSPR_MASK, PPC860, { RS }, PPC_INST_MTCMPG }, +{ "mtcmph", XSPR(31,467,155), XSPR_MASK, PPC860, { RS }, PPC_INST_MTCMPH }, +{ "mtlctrl1", XSPR(31,467,156), XSPR_MASK, PPC860, { RS }, PPC_INST_MTLCTRL1 }, +{ "mtlctrl2", XSPR(31,467,157), XSPR_MASK, PPC860, { RS }, PPC_INST_MTLCTRL2 }, +{ "mtictrl", XSPR(31,467,158), XSPR_MASK, PPC860, { RS }, PPC_INST_MTICTRL }, +{ "mtbar", XSPR(31,467,159), XSPR_MASK, PPC860, { RS }, PPC_INST_MTBAR }, +{ "mtvrsave", XSPR(31,467,256), XSPR_MASK, PPCVEC, { RS }, PPC_INST_MTVRSAVE }, +{ "mtusprg0", XSPR(31,467,256), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTUSPRG0 }, +{ "mtsprg", XSPR(31,467,256), XSPRG_MASK,PPC, { SPRG, RS }, PPC_INST_MTSPRG }, +{ "mtsprg0", XSPR(31,467,272), XSPR_MASK, PPC, { RS }, PPC_INST_MTSPRG0 }, +{ "mtsprg1", XSPR(31,467,273), XSPR_MASK, PPC, { RS }, PPC_INST_MTSPRG1 }, +{ "mtsprg2", XSPR(31,467,274), XSPR_MASK, PPC, { RS }, PPC_INST_MTSPRG2 }, +{ "mtsprg3", XSPR(31,467,275), XSPR_MASK, PPC, { RS }, PPC_INST_MTSPRG3 }, +{ "mtsprg4", XSPR(31,467,276), XSPR_MASK, PPC405 | BOOKE, { RS }, PPC_INST_MTSPRG4 }, +{ "mtsprg5", XSPR(31,467,277), XSPR_MASK, PPC405 | BOOKE, { RS }, PPC_INST_MTSPRG5 }, +{ "mtsprg6", XSPR(31,467,278), XSPR_MASK, PPC405 | BOOKE, { RS }, PPC_INST_MTSPRG6 }, +{ "mtsprg7", XSPR(31,467,279), XSPR_MASK, PPC405 | BOOKE, { RS }, PPC_INST_MTSPRG7 }, +{ "mtasr", XSPR(31,467,280), XSPR_MASK, PPC64, { RS }, PPC_INST_MTASR }, +{ "mtear", XSPR(31,467,282), XSPR_MASK, PPC, { RS }, PPC_INST_MTEAR }, +{ "mttbl", XSPR(31,467,284), XSPR_MASK, PPC, { RS }, PPC_INST_MTTBL }, +{ "mttbu", XSPR(31,467,285), XSPR_MASK, PPC, { RS }, PPC_INST_MTTBU }, +{ "mtdbsr", XSPR(31,467,304), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTDBSR }, +{ "mtdbsr", XSPR(31,467,1008), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDBSR }, +{ "mtdbcr0", XSPR(31,467,308), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTDBCR0 }, +{ "mtdbcr0", XSPR(31,467,1010), XSPR_MASK, PPC405, { RS }, PPC_INST_MTDBCR0 }, +{ "mtdbcr1", XSPR(31,467,309), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTDBCR1 }, +{ "mtdbcr1", XSPR(31,467,957), XSPR_MASK, PPC405, { RS }, PPC_INST_MTDBCR1 }, +{ "mtdbcr2", XSPR(31,467,310), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTDBCR2 }, +{ "mtiac1", XSPR(31,467,312), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIAC1 }, +{ "mtiac1", XSPR(31,467,1012), XSPR_MASK, PPC403, { RS }, PPC_INST_MTIAC1 }, +{ "mtiac2", XSPR(31,467,313), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIAC2 }, +{ "mtiac2", XSPR(31,467,1013), XSPR_MASK, PPC403, { RS }, PPC_INST_MTIAC2 }, +{ "mtiac3", XSPR(31,467,314), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIAC3 }, +{ "mtiac3", XSPR(31,467,948), XSPR_MASK, PPC405, { RS }, PPC_INST_MTIAC3 }, +{ "mtiac4", XSPR(31,467,315), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIAC4 }, +{ "mtiac4", XSPR(31,467,949), XSPR_MASK, PPC405, { RS }, PPC_INST_MTIAC4 }, +{ "mtdac1", XSPR(31,467,316), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTDAC1 }, +{ "mtdac1", XSPR(31,467,1014), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDAC1 }, +{ "mtdac2", XSPR(31,467,317), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTDAC2 }, +{ "mtdac2", XSPR(31,467,1015), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDAC2 }, +{ "mtdvc1", XSPR(31,467,318), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTDVC1 }, +{ "mtdvc1", XSPR(31,467,950), XSPR_MASK, PPC405, { RS }, PPC_INST_MTDVC1 }, +{ "mtdvc2", XSPR(31,467,319), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTDVC2 }, +{ "mtdvc2", XSPR(31,467,951), XSPR_MASK, PPC405, { RS }, PPC_INST_MTDVC2 }, +{ "mttsr", XSPR(31,467,336), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTTSR }, +{ "mttsr", XSPR(31,467,984), XSPR_MASK, PPC403, { RS }, PPC_INST_MTTSR }, +{ "mttcr", XSPR(31,467,340), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTTCR }, +{ "mttcr", XSPR(31,467,986), XSPR_MASK, PPC403, { RS }, PPC_INST_MTTCR }, +{ "mtivor0", XSPR(31,467,400), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIVOR0 }, +{ "mtivor1", XSPR(31,467,401), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIVOR1 }, +{ "mtivor2", XSPR(31,467,402), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIVOR2 }, +{ "mtivor3", XSPR(31,467,403), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIVOR3 }, +{ "mtivor4", XSPR(31,467,404), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIVOR4 }, +{ "mtivor5", XSPR(31,467,405), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIVOR5 }, +{ "mtivor6", XSPR(31,467,406), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIVOR6 }, +{ "mtivor7", XSPR(31,467,407), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIVOR7 }, +{ "mtivor8", XSPR(31,467,408), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIVOR8 }, +{ "mtivor9", XSPR(31,467,409), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIVOR9 }, +{ "mtivor10", XSPR(31,467,410), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIVOR10 }, +{ "mtivor11", XSPR(31,467,411), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIVOR11 }, +{ "mtivor12", XSPR(31,467,412), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIVOR12 }, +{ "mtivor13", XSPR(31,467,413), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIVOR13 }, +{ "mtivor14", XSPR(31,467,414), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIVOR14 }, +{ "mtivor15", XSPR(31,467,415), XSPR_MASK, BOOKE, { RS }, PPC_INST_MTIVOR15 }, +{ "mtspefscr", XSPR(31,467,512), XSPR_MASK, PPCSPE, { RS }, PPC_INST_MTSPEFSCR }, +{ "mtbbear", XSPR(31,467,513), XSPR_MASK, PPCBRLK, { RS }, PPC_INST_MTBBEAR }, +{ "mtbbtar", XSPR(31,467,514), XSPR_MASK, PPCBRLK, { RS }, PPC_INST_MTBBTAR }, +{ "mtivor32", XSPR(31,467,528), XSPR_MASK, PPCSPE, { RS }, PPC_INST_MTIVOR32 }, +{ "mtivor33", XSPR(31,467,529), XSPR_MASK, PPCSPE, { RS }, PPC_INST_MTIVOR33 }, +{ "mtivor34", XSPR(31,467,530), XSPR_MASK, PPCSPE, { RS }, PPC_INST_MTIVOR34 }, +{ "mtivor35", XSPR(31,467,531), XSPR_MASK, PPCPMR, { RS }, PPC_INST_MTIVOR35 }, +{ "mtibatu", XSPR(31,467,528), XSPRBAT_MASK, PPC, { SPRBAT, RS }, PPC_INST_MTIBATU }, +{ "mtibatl", XSPR(31,467,529), XSPRBAT_MASK, PPC, { SPRBAT, RS }, PPC_INST_MTIBATL }, +{ "mtdbatu", XSPR(31,467,536), XSPRBAT_MASK, PPC, { SPRBAT, RS }, PPC_INST_MTDBATU }, +{ "mtdbatl", XSPR(31,467,537), XSPRBAT_MASK, PPC, { SPRBAT, RS }, PPC_INST_MTDBATL }, +{ "mtmcsrr0", XSPR(31,467,570), XSPR_MASK, PPCRFMCI, { RS }, PPC_INST_MTMCSRR0 }, +{ "mtmcsrr1", XSPR(31,467,571), XSPR_MASK, PPCRFMCI, { RS }, PPC_INST_MTMCSRR1 }, +{ "mtmcsr", XSPR(31,467,572), XSPR_MASK, PPCRFMCI, { RS }, PPC_INST_MTMCSR }, +{ "mtummcr0", XSPR(31,467,936), XSPR_MASK, PPC750, { RS }, PPC_INST_MTUMMCR0 }, +{ "mtupmc1", XSPR(31,467,937), XSPR_MASK, PPC750, { RS }, PPC_INST_MTUPMC1 }, +{ "mtupmc2", XSPR(31,467,938), XSPR_MASK, PPC750, { RS }, PPC_INST_MTUPMC2 }, +{ "mtusia", XSPR(31,467,939), XSPR_MASK, PPC750, { RS }, PPC_INST_MTUSIA }, +{ "mtummcr1", XSPR(31,467,940), XSPR_MASK, PPC750, { RS }, PPC_INST_MTUMMCR1 }, +{ "mtupmc3", XSPR(31,467,941), XSPR_MASK, PPC750, { RS }, PPC_INST_MTUPMC3 }, +{ "mtupmc4", XSPR(31,467,942), XSPR_MASK, PPC750, { RS }, PPC_INST_MTUPMC4 }, +{ "mtzpr", XSPR(31,467,944), XSPR_MASK, PPC403, { RS }, PPC_INST_MTZPR }, +{ "mtccr0", XSPR(31,467,947), XSPR_MASK, PPC405, { RS }, PPC_INST_MTCCR0 }, +{ "mtmmcr0", XSPR(31,467,952), XSPR_MASK, PPC750, { RS }, PPC_INST_MTMMCR0 }, +{ "mtsgr", XSPR(31,467,953), XSPR_MASK, PPC403, { RS }, PPC_INST_MTSGR }, +{ "mtpmc1", XSPR(31,467,953), XSPR_MASK, PPC750, { RS }, PPC_INST_MTPMC1 }, +{ "mtdcwr", XSPR(31,467,954), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDCWR }, +{ "mtpmc2", XSPR(31,467,954), XSPR_MASK, PPC750, { RS }, PPC_INST_MTPMC2 }, +{ "mtsler", XSPR(31,467,955), XSPR_MASK, PPC405, { RS }, PPC_INST_MTSLER }, +{ "mtsia", XSPR(31,467,955), XSPR_MASK, PPC750, { RS }, PPC_INST_MTSIA }, +{ "mtsu0r", XSPR(31,467,956), XSPR_MASK, PPC405, { RS }, PPC_INST_MTSU0R }, +{ "mtmmcr1", XSPR(31,467,956), XSPR_MASK, PPC750, { RS }, PPC_INST_MTMMCR1 }, +{ "mtpmc3", XSPR(31,467,957), XSPR_MASK, PPC750, { RS }, PPC_INST_MTPMC3 }, +{ "mtpmc4", XSPR(31,467,958), XSPR_MASK, PPC750, { RS }, PPC_INST_MTPMC4 }, +{ "mticdbdr", XSPR(31,467,979), XSPR_MASK, PPC403, { RS }, PPC_INST_MTICDBDR }, +{ "mtevpr", XSPR(31,467,982), XSPR_MASK, PPC403, { RS }, PPC_INST_MTEVPR }, +{ "mtcdbcr", XSPR(31,467,983), XSPR_MASK, PPC403, { RS }, PPC_INST_MTCDBCR }, +{ "mtpit", XSPR(31,467,987), XSPR_MASK, PPC403, { RS }, PPC_INST_MTPIT }, +{ "mttbhi", XSPR(31,467,988), XSPR_MASK, PPC403, { RS }, PPC_INST_MTTBHI }, +{ "mttblo", XSPR(31,467,989), XSPR_MASK, PPC403, { RS }, PPC_INST_MTTBLO }, +{ "mtsrr2", XSPR(31,467,990), XSPR_MASK, PPC403, { RS }, PPC_INST_MTSRR2 }, +{ "mtsrr3", XSPR(31,467,991), XSPR_MASK, PPC403, { RS }, PPC_INST_MTSRR3 }, +{ "mtl2cr", XSPR(31,467,1017), XSPR_MASK, PPC750, { RS }, PPC_INST_MTL2CR }, +{ "mtdccr", XSPR(31,467,1018), XSPR_MASK, PPC403, { RS }, PPC_INST_MTDCCR }, +{ "mticcr", XSPR(31,467,1019), XSPR_MASK, PPC403, { RS }, PPC_INST_MTICCR }, +{ "mtictc", XSPR(31,467,1019), XSPR_MASK, PPC750, { RS }, PPC_INST_MTICTC }, +{ "mtpbl1", XSPR(31,467,1020), XSPR_MASK, PPC403, { RS }, PPC_INST_MTPBL1 }, +{ "mtthrm1", XSPR(31,467,1020), XSPR_MASK, PPC750, { RS }, PPC_INST_MTTHRM1 }, +{ "mtpbu1", XSPR(31,467,1021), XSPR_MASK, PPC403, { RS }, PPC_INST_MTPBU1 }, +{ "mtthrm2", XSPR(31,467,1021), XSPR_MASK, PPC750, { RS }, PPC_INST_MTTHRM2 }, +{ "mtpbl2", XSPR(31,467,1022), XSPR_MASK, PPC403, { RS }, PPC_INST_MTPBL2 }, +{ "mtthrm3", XSPR(31,467,1022), XSPR_MASK, PPC750, { RS }, PPC_INST_MTTHRM3 }, +{ "mtpbu2", XSPR(31,467,1023), XSPR_MASK, PPC403, { RS }, PPC_INST_MTPBU2 }, +{ "mtspr", X(31,467), X_MASK, COM, { SPR, RS }, PPC_INST_MTSPR }, + +{ "dcbi", X(31,470), XRT_MASK, PPC, { RA, RB }, PPC_INST_DCBI }, + +{ "nand", XRC(31,476,0), X_MASK, COM, { RA, RS, RB }, PPC_INST_NAND }, +{ "nand.", XRC(31,476,1), X_MASK, COM, { RA, RS, RB }, PPC_INST_NAND }, + +{ "dcbie", X(31,478), XRT_MASK, BOOKE64, { RA, RB }, PPC_INST_DCBIE }, + +{ "dcread", X(31,486), X_MASK, PPC403 | PPC440, { RT, RA, RB }, PPC_INST_DCREAD }, + +{ "mtpmr", X(31,462), X_MASK, PPCPMR, { PMR, RS }, PPC_INST_MTPMR }, + +{ "icbtls", X(31,486), X_MASK, PPCCHLK, { CT, RA, RB }, PPC_INST_ICBTLS }, + +{ "nabs", XO(31,488,0,0), XORB_MASK, M601, { RT, RA }, PPC_INST_NABS }, +{ "subfme64",XO(31,488,0,0), XORB_MASK, BOOKE64, { RT, RA }, PPC_INST_SUBFME64 }, +{ "nabs.", XO(31,488,0,1), XORB_MASK, M601, { RT, RA }, PPC_INST_NABS }, +{ "nabso", XO(31,488,1,0), XORB_MASK, M601, { RT, RA }, PPC_INST_NABSO }, +{ "subfme64o",XO(31,488,1,0), XORB_MASK, BOOKE64, { RT, RA }, PPC_INST_SUBFME64O }, +{ "nabso.", XO(31,488,1,1), XORB_MASK, M601, { RT, RA }, PPC_INST_NABSO }, + +{ "divd", XO(31,489,0,0), XO_MASK, PPC64, { RT, RA, RB }, PPC_INST_DIVD }, +{ "divd.", XO(31,489,0,1), XO_MASK, PPC64, { RT, RA, RB }, PPC_INST_DIVD }, +{ "divdo", XO(31,489,1,0), XO_MASK, PPC64, { RT, RA, RB }, PPC_INST_DIVDO }, +{ "divdo.", XO(31,489,1,1), XO_MASK, PPC64, { RT, RA, RB }, PPC_INST_DIVDO }, + +{ "addme64", XO(31,490,0,0), XORB_MASK, BOOKE64, { RT, RA }, PPC_INST_ADDME64 }, +{ "addme64o",XO(31,490,1,0), XORB_MASK, BOOKE64, { RT, RA }, PPC_INST_ADDME64O }, + +{ "divw", XO(31,491,0,0), XO_MASK, PPC, { RT, RA, RB }, PPC_INST_DIVW }, +{ "divw.", XO(31,491,0,1), XO_MASK, PPC, { RT, RA, RB }, PPC_INST_DIVW }, +{ "divwo", XO(31,491,1,0), XO_MASK, PPC, { RT, RA, RB }, PPC_INST_DIVWO }, +{ "divwo.", XO(31,491,1,1), XO_MASK, PPC, { RT, RA, RB }, PPC_INST_DIVWO }, + +{ "icbtlse", X(31,494), X_MASK, PPCCHLK64, { CT, RA, RB }, PPC_INST_ICBTLSE }, + +{ "slbia", X(31,498), 0xffffffff, PPC64, { 0 }, PPC_INST_SLBIA }, + +{ "cli", X(31,502), XRB_MASK, POWER, { RT, RA }, PPC_INST_CLI }, + +{ "stdcxe.", XRC(31,511,1), X_MASK, BOOKE64, { RS, RA, RB }, PPC_INST_STDCXE }, + +{ "mcrxr", X(31,512), XRARB_MASK | (3 << 21), COM, { BF }, PPC_INST_MCRXR }, + +{ "bblels", X(31,518), X_MASK, PPCBRLK, { 0 }, PPC_INST_BBLELS }, +{ "mcrxr64", X(31,544), XRARB_MASK | (3 << 21), BOOKE64, { BF }, PPC_INST_MCRXR64 }, + +{ "clcs", X(31,531), XRB_MASK, M601, { RT, RA }, PPC_INST_CLCS }, + +{ "ldbrx", X(31,532), X_MASK, CELL, { RT, RA0, RB }, PPC_INST_LDBRX }, + +{ "lswx", X(31,533), X_MASK, PPCCOM, { RT, RA0, RB }, PPC_INST_LSWX }, +{ "lsx", X(31,533), X_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_LSX }, + +{ "lwbrx", X(31,534), X_MASK, PPCCOM, { RT, RA0, RB }, PPC_INST_LWBRX }, +{ "lbrx", X(31,534), X_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_LBRX }, + +{ "lfsx", X(31,535), X_MASK, COM, { FRT, RA0, RB }, PPC_INST_LFSX }, + +{ "srw", XRC(31,536,0), X_MASK, PPCCOM, { RA, RS, RB }, PPC_INST_SRW }, +{ "sr", XRC(31,536,0), X_MASK, PWRCOM, { RA, RS, RB }, PPC_INST_SR }, +{ "srw.", XRC(31,536,1), X_MASK, PPCCOM, { RA, RS, RB }, PPC_INST_SRW }, +{ "sr.", XRC(31,536,1), X_MASK, PWRCOM, { RA, RS, RB }, PPC_INST_SR }, + +{ "rrib", XRC(31,537,0), X_MASK, M601, { RA, RS, RB }, PPC_INST_RRIB }, +{ "rrib.", XRC(31,537,1), X_MASK, M601, { RA, RS, RB }, PPC_INST_RRIB }, + +{ "srd", XRC(31,539,0), X_MASK, PPC64, { RA, RS, RB }, PPC_INST_SRD }, +{ "srd.", XRC(31,539,1), X_MASK, PPC64, { RA, RS, RB }, PPC_INST_SRD }, + +{ "maskir", XRC(31,541,0), X_MASK, M601, { RA, RS, RB }, PPC_INST_MASKIR }, +{ "maskir.", XRC(31,541,1), X_MASK, M601, { RA, RS, RB }, PPC_INST_MASKIR }, + +{ "lwbrxe", X(31,542), X_MASK, BOOKE64, { RT, RA0, RB }, PPC_INST_LWBRXE }, + +{ "lfsxe", X(31,543), X_MASK, BOOKE64, { FRT, RA0, RB }, PPC_INST_LFSXE }, + +{ "bbelr", X(31,550), X_MASK, PPCBRLK, { 0 }, PPC_INST_BBELR }, + +{ "tlbsync", X(31,566), 0xffffffff, PPC, { 0 }, PPC_INST_TLBSYNC }, + +{ "lfsux", X(31,567), X_MASK, COM, { FRT, RAS, RB }, PPC_INST_LFSUX }, + +{ "lfsuxe", X(31,575), X_MASK, BOOKE64, { FRT, RAS, RB }, PPC_INST_LFSUXE }, + +{ "mfsr", X(31,595), XRB_MASK | (1 << 20), COM32, { RT, SR }, PPC_INST_MFSR }, + +{ "lswi", X(31,597), X_MASK, PPCCOM, { RT, RA0, NB }, PPC_INST_LSWI }, +{ "lsi", X(31,597), X_MASK, PWRCOM, { RT, RA0, NB }, PPC_INST_LSI }, + +{ "lwsync", XSYNC(31,598,1), 0xffffffff, PPC, { 0 }, PPC_INST_LWSYNC }, +{ "ptesync", XSYNC(31,598,2), 0xffffffff, PPC64, { 0 }, PPC_INST_PTESYNC }, +{ "msync", X(31,598), 0xffffffff, BOOKE, { 0 }, PPC_INST_MSYNC }, +{ "sync", X(31,598), XSYNC_MASK, PPCCOM, { LS }, PPC_INST_SYNC }, +{ "dcs", X(31,598), 0xffffffff, PWRCOM, { 0 }, PPC_INST_DCS }, + +{ "lfdx", X(31,599), X_MASK, COM, { FRT, RA0, RB }, PPC_INST_LFDX }, + +{ "lfdxe", X(31,607), X_MASK, BOOKE64, { FRT, RA0, RB }, PPC_INST_LFDXE }, + +{ "mffgpr", XRC(31,607,0), XRA_MASK, POWER6, { FRT, RB }, PPC_INST_MFFGPR }, + +{ "mfsri", X(31,627), X_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_MFSRI }, + +{ "dclst", X(31,630), XRB_MASK, PWRCOM, { RS, RA }, PPC_INST_DCLST }, + +{ "lfdux", X(31,631), X_MASK, COM, { FRT, RAS, RB }, PPC_INST_LFDUX }, + +{ "lfduxe", X(31,639), X_MASK, BOOKE64, { FRT, RAS, RB }, PPC_INST_LFDUXE }, + +{ "mfsrin", X(31,659), XRA_MASK, PPC32, { RT, RB }, PPC_INST_MFSRIN }, + +{ "stdbrx", X(31,660), X_MASK, CELL, { RS, RA0, RB }, PPC_INST_STDBRX }, + +{ "stswx", X(31,661), X_MASK, PPCCOM, { RS, RA0, RB }, PPC_INST_STSWX }, +{ "stsx", X(31,661), X_MASK, PWRCOM, { RS, RA0, RB }, PPC_INST_STSX }, + +{ "stwbrx", X(31,662), X_MASK, PPCCOM, { RS, RA0, RB }, PPC_INST_STWBRX }, +{ "stbrx", X(31,662), X_MASK, PWRCOM, { RS, RA0, RB }, PPC_INST_STBRX }, + +{ "stfsx", X(31,663), X_MASK, COM, { FRS, RA0, RB }, PPC_INST_STFSX }, + +{ "srq", XRC(31,664,0), X_MASK, M601, { RA, RS, RB }, PPC_INST_SRQ }, +{ "srq.", XRC(31,664,1), X_MASK, M601, { RA, RS, RB }, PPC_INST_SRQ }, + +{ "sre", XRC(31,665,0), X_MASK, M601, { RA, RS, RB }, PPC_INST_SRE }, +{ "sre.", XRC(31,665,1), X_MASK, M601, { RA, RS, RB }, PPC_INST_SRE }, + +{ "stwbrxe", X(31,670), X_MASK, BOOKE64, { RS, RA0, RB }, PPC_INST_STWBRXE }, + +{ "stfsxe", X(31,671), X_MASK, BOOKE64, { FRS, RA0, RB }, PPC_INST_STFSXE }, + +{ "stfsux", X(31,695), X_MASK, COM, { FRS, RAS, RB }, PPC_INST_STFSUX }, + +{ "sriq", XRC(31,696,0), X_MASK, M601, { RA, RS, SH }, PPC_INST_SRIQ }, +{ "sriq.", XRC(31,696,1), X_MASK, M601, { RA, RS, SH }, PPC_INST_SRIQ }, + +{ "stfsuxe", X(31,703), X_MASK, BOOKE64, { FRS, RAS, RB }, PPC_INST_STFSUXE }, + +{ "stswi", X(31,725), X_MASK, PPCCOM, { RS, RA0, NB }, PPC_INST_STSWI }, +{ "stsi", X(31,725), X_MASK, PWRCOM, { RS, RA0, NB }, PPC_INST_STSI }, + +{ "stfdx", X(31,727), X_MASK, COM, { FRS, RA0, RB }, PPC_INST_STFDX }, + +{ "srlq", XRC(31,728,0), X_MASK, M601, { RA, RS, RB }, PPC_INST_SRLQ }, +{ "srlq.", XRC(31,728,1), X_MASK, M601, { RA, RS, RB }, PPC_INST_SRLQ }, + +{ "sreq", XRC(31,729,0), X_MASK, M601, { RA, RS, RB }, PPC_INST_SREQ }, +{ "sreq.", XRC(31,729,1), X_MASK, M601, { RA, RS, RB }, PPC_INST_SREQ }, + +{ "stfdxe", X(31,735), X_MASK, BOOKE64, { FRS, RA0, RB }, PPC_INST_STFDXE }, + +{ "mftgpr", XRC(31,735,0), XRA_MASK, POWER6, { RT, FRB }, PPC_INST_MFTGPR }, + +{ "dcba", X(31,758), XRT_MASK, PPC405 | BOOKE, { RA, RB }, PPC_INST_DCBA }, + +{ "stfdux", X(31,759), X_MASK, COM, { FRS, RAS, RB }, PPC_INST_STFDUX }, + +{ "srliq", XRC(31,760,0), X_MASK, M601, { RA, RS, SH }, PPC_INST_SRLIQ }, +{ "srliq.", XRC(31,760,1), X_MASK, M601, { RA, RS, SH }, PPC_INST_SRLIQ }, + +{ "dcbae", X(31,766), XRT_MASK, BOOKE64, { RA, RB }, PPC_INST_DCBAE }, + +{ "stfduxe", X(31,767), X_MASK, BOOKE64, { FRS, RAS, RB }, PPC_INST_STFDUXE }, + +{ "tlbivax", X(31,786), XRT_MASK, BOOKE, { RA, RB }, PPC_INST_TLBIVAX }, +{ "tlbivaxe",X(31,787), XRT_MASK, BOOKE64, { RA, RB }, PPC_INST_TLBIVAXE }, + +{ "lwzcix", X(31,789), X_MASK, POWER6, { RT, RA0, RB }, PPC_INST_LWZCIX }, + +{ "lhbrx", X(31,790), X_MASK, COM, { RT, RA0, RB }, PPC_INST_LHBRX }, + +{ "sraw", XRC(31,792,0), X_MASK, PPCCOM, { RA, RS, RB }, PPC_INST_SRAW }, +{ "sra", XRC(31,792,0), X_MASK, PWRCOM, { RA, RS, RB }, PPC_INST_SRA }, +{ "sraw.", XRC(31,792,1), X_MASK, PPCCOM, { RA, RS, RB }, PPC_INST_SRAW }, +{ "sra.", XRC(31,792,1), X_MASK, PWRCOM, { RA, RS, RB }, PPC_INST_SRA }, + +{ "srad", XRC(31,794,0), X_MASK, PPC64, { RA, RS, RB }, PPC_INST_SRAD }, +{ "srad.", XRC(31,794,1), X_MASK, PPC64, { RA, RS, RB }, PPC_INST_SRAD }, + +{ "lhbrxe", X(31,798), X_MASK, BOOKE64, { RT, RA0, RB }, PPC_INST_LHBRXE }, + +{ "ldxe", X(31,799), X_MASK, BOOKE64, { RT, RA0, RB }, PPC_INST_LDXE }, +{ "lduxe", X(31,831), X_MASK, BOOKE64, { RT, RA0, RB }, PPC_INST_LDUXE }, + +{ "rac", X(31,818), X_MASK, PWRCOM, { RT, RA, RB }, PPC_INST_RAC }, + +{ "lhzcix", X(31,821), X_MASK, POWER6, { RT, RA0, RB }, PPC_INST_LHZCIX }, + +{ "dss", XDSS(31,822,0), XDSS_MASK, PPCVEC, { STRM }, PPC_INST_DSS }, +{ "dssall", XDSS(31,822,1), XDSS_MASK, PPCVEC, { 0 }, PPC_INST_DSSALL }, + +{ "srawi", XRC(31,824,0), X_MASK, PPCCOM, { RA, RS, SH }, PPC_INST_SRAWI }, +{ "srai", XRC(31,824,0), X_MASK, PWRCOM, { RA, RS, SH }, PPC_INST_SRAI }, +{ "srawi.", XRC(31,824,1), X_MASK, PPCCOM, { RA, RS, SH }, PPC_INST_SRAWI }, +{ "srai.", XRC(31,824,1), X_MASK, PWRCOM, { RA, RS, SH }, PPC_INST_SRAI }, + +{ "slbmfev", X(31,851), XRA_MASK, PPC64, { RT, RB }, PPC_INST_SLBMFEV }, + +{ "lbzcix", X(31,853), X_MASK, POWER6, { RT, RA0, RB }, PPC_INST_LBZCIX }, + +{ "mbar", X(31,854), X_MASK, BOOKE, { MO }, PPC_INST_MBAR }, +{ "eieio", X(31,854), 0xffffffff, PPC, { 0 }, PPC_INST_EIEIO }, + +{ "lfiwax", X(31,855), X_MASK, POWER6, { FRT, RA0, RB }, PPC_INST_LFIWAX }, + +{ "ldcix", X(31,885), X_MASK, POWER6, { RT, RA0, RB }, PPC_INST_LDCIX }, + +{ "tlbsx", XRC(31,914,0), X_MASK, PPC403 | BOOKE, { RTO, RA, RB }, PPC_INST_TLBSX }, +{ "tlbsx.", XRC(31,914,1), X_MASK, PPC403 | BOOKE, { RTO, RA, RB }, PPC_INST_TLBSX }, +{ "tlbsxe", XRC(31,915,0), X_MASK, BOOKE64, { RTO, RA, RB }, PPC_INST_TLBSXE }, +{ "tlbsxe.", XRC(31,915,1), X_MASK, BOOKE64, { RTO, RA, RB }, PPC_INST_TLBSXE }, + +{ "slbmfee", X(31,915), XRA_MASK, PPC64, { RT, RB }, PPC_INST_SLBMFEE }, + +{ "stwcix", X(31,917), X_MASK, POWER6, { RS, RA0, RB }, PPC_INST_STWCIX }, + +{ "sthbrx", X(31,918), X_MASK, COM, { RS, RA0, RB }, PPC_INST_STHBRX }, + +{ "sraq", XRC(31,920,0), X_MASK, M601, { RA, RS, RB }, PPC_INST_SRAQ }, +{ "sraq.", XRC(31,920,1), X_MASK, M601, { RA, RS, RB }, PPC_INST_SRAQ }, + +{ "srea", XRC(31,921,0), X_MASK, M601, { RA, RS, RB }, PPC_INST_SREA }, +{ "srea.", XRC(31,921,1), X_MASK, M601, { RA, RS, RB }, PPC_INST_SREA }, + +{ "extsh", XRC(31,922,0), XRB_MASK, PPCCOM, { RA, RS }, PPC_INST_EXTSH }, +{ "exts", XRC(31,922,0), XRB_MASK, PWRCOM, { RA, RS }, PPC_INST_EXTS }, +{ "extsh.", XRC(31,922,1), XRB_MASK, PPCCOM, { RA, RS }, PPC_INST_EXTSH }, +{ "exts.", XRC(31,922,1), XRB_MASK, PWRCOM, { RA, RS }, PPC_INST_EXTS }, + +{ "sthbrxe", X(31,926), X_MASK, BOOKE64, { RS, RA0, RB }, PPC_INST_STHBRXE }, + +{ "stdxe", X(31,927), X_MASK, BOOKE64, { RS, RA0, RB }, PPC_INST_STDXE }, + +{ "tlbrehi", XTLB(31,946,0), XTLB_MASK, PPC403, { RT, RA }, PPC_INST_TLBREHI }, +{ "tlbrelo", XTLB(31,946,1), XTLB_MASK, PPC403, { RT, RA }, PPC_INST_TLBRELO }, +{ "tlbre", X(31,946), X_MASK, PPC403 | BOOKE, { RSO, RAOPT, SHO }, PPC_INST_TLBRE }, + +{ "sthcix", X(31,949), X_MASK, POWER6, { RS, RA0, RB }, PPC_INST_STHCIX }, + +{ "sraiq", XRC(31,952,0), X_MASK, M601, { RA, RS, SH }, PPC_INST_SRAIQ }, +{ "sraiq.", XRC(31,952,1), X_MASK, M601, { RA, RS, SH }, PPC_INST_SRAIQ }, + +{ "extsb", XRC(31,954,0), XRB_MASK, PPC, { RA, RS}, PPC_INST_EXTSB }, +{ "extsb.", XRC(31,954,1), XRB_MASK, PPC, { RA, RS}, PPC_INST_EXTSB }, + +{ "stduxe", X(31,959), X_MASK, BOOKE64, { RS, RAS, RB }, PPC_INST_STDUXE }, + +{ "iccci", X(31,966), XRT_MASK, PPC403 | PPC440, { RA, RB }, PPC_INST_ICCCI }, + +{ "tlbwehi", XTLB(31,978,0), XTLB_MASK, PPC403, { RT, RA }, PPC_INST_TLBWEHI }, +{ "tlbwelo", XTLB(31,978,1), XTLB_MASK, PPC403, { RT, RA }, PPC_INST_TLBWELO }, +{ "tlbwe", X(31,978), X_MASK, PPC403 | BOOKE, { RSO, RAOPT, SHO }, PPC_INST_TLBWE }, +{ "tlbld", X(31,978), XRTRA_MASK, PPC, { RB }, PPC_INST_TLBLD }, + +{ "stbcix", X(31,981), X_MASK, POWER6, { RS, RA0, RB }, PPC_INST_STBCIX }, + +{ "icbi", X(31,982), XRT_MASK, PPC, { RA, RB }, PPC_INST_ICBI }, + +{ "stfiwx", X(31,983), X_MASK, PPC, { FRS, RA0, RB }, PPC_INST_STFIWX }, + +{ "extsw", XRC(31,986,0), XRB_MASK, PPC64 | BOOKE64,{ RA, RS }, PPC_INST_EXTSW }, +{ "extsw.", XRC(31,986,1), XRB_MASK, PPC64, { RA, RS }, PPC_INST_EXTSW }, + +{ "icread", X(31,998), XRT_MASK, PPC403 | PPC440, { RA, RB }, PPC_INST_ICREAD }, + +{ "icbie", X(31,990), XRT_MASK, BOOKE64, { RA, RB }, PPC_INST_ICBIE }, +{ "stfiwxe", X(31,991), X_MASK, BOOKE64, { FRS, RA0, RB }, PPC_INST_STFIWXE }, + +{ "tlbli", X(31,1010), XRTRA_MASK, PPC, { RB }, PPC_INST_TLBLI }, + +{ "stdcix", X(31,1013), X_MASK, POWER6, { RS, RA0, RB }, PPC_INST_STDCIX }, + +{ "dcbzl", XOPL(31,1014,1), XRT_MASK,POWER4, { RA, RB }, PPC_INST_DCBZL }, +{ "dcbz", X(31,1014), XRT_MASK, PPC, { RA, RB }, PPC_INST_DCBZ }, +{ "dclz", X(31,1014), XRT_MASK, PPC, { RA, RB }, PPC_INST_DCLZ }, + +{ "dcbze", X(31,1022), XRT_MASK, BOOKE64, { RA, RB }, PPC_INST_DCBZE }, + +{ "lvebx", X(31, 7), X_MASK, PPCVEC, { VD, RA, RB }, PPC_INST_LVEBX }, +{ "lvehx", X(31, 39), X_MASK, PPCVEC, { VD, RA, RB }, PPC_INST_LVEHX }, +{ "lvewx", X(31, 71), X_MASK, PPCVEC, { VD, RA, RB }, PPC_INST_LVEWX }, +{ "lvsl", X(31, 6), X_MASK, PPCVEC, { VD, RA, RB }, PPC_INST_LVSL }, +{ "lvsr", X(31, 38), X_MASK, PPCVEC, { VD, RA, RB }, PPC_INST_LVSR }, +{ "lvx", X(31, 103), X_MASK, PPCVEC, { VD, RA, RB }, PPC_INST_LVX }, +{ "lvxl", X(31, 359), X_MASK, PPCVEC, { VD, RA, RB }, PPC_INST_LVXL }, +{ "stvebx", X(31, 135), X_MASK, PPCVEC, { VS, RA, RB }, PPC_INST_STVEBX }, +{ "stvehx", X(31, 167), X_MASK, PPCVEC, { VS, RA, RB }, PPC_INST_STVEHX }, +{ "stvewx", X(31, 199), X_MASK, PPCVEC, { VS, RA, RB }, PPC_INST_STVEWX }, +{ "stvx", X(31, 231), X_MASK, PPCVEC, { VS, RA, RB }, PPC_INST_STVX }, +{ "stvxl", X(31, 487), X_MASK, PPCVEC, { VS, RA, RB }, PPC_INST_STVXL }, + +/* New load/store left/right index vector instructions that are in the Cell only. */ +{ "lvlx", X(31, 519), X_MASK, CELL | PPCVEC128, { VD, RA0, RB }, PPC_INST_LVLX }, +{ "lvlxl", X(31, 775), X_MASK, CELL | PPCVEC128, { VD, RA0, RB }, PPC_INST_LVLXL }, +{ "lvrx", X(31, 551), X_MASK, CELL | PPCVEC128, { VD, RA0, RB }, PPC_INST_LVRX }, +{ "lvrxl", X(31, 807), X_MASK, CELL | PPCVEC128, { VD, RA0, RB }, PPC_INST_LVRXL }, +{ "stvlx", X(31, 647), X_MASK, CELL | PPCVEC128, { VS, RA0, RB }, PPC_INST_STVLX }, +{ "stvlxl", X(31, 903), X_MASK, CELL | PPCVEC128, { VS, RA0, RB }, PPC_INST_STVLXL }, +{ "stvrx", X(31, 679), X_MASK, CELL | PPCVEC128, { VS, RA0, RB }, PPC_INST_STVRX }, +{ "stvrxl", X(31, 935), X_MASK, CELL | PPCVEC128, { VS, RA0, RB }, PPC_INST_STVRXL }, + +{ "lwz", OP(32), OP_MASK, PPCCOM, { RT, D, RA0 }, PPC_INST_LWZ }, +{ "l", OP(32), OP_MASK, PWRCOM, { RT, D, RA0 }, PPC_INST_L }, + +{ "lwzu", OP(33), OP_MASK, PPCCOM, { RT, D, RAL }, PPC_INST_LWZU }, +{ "lu", OP(33), OP_MASK, PWRCOM, { RT, D, RA0 }, PPC_INST_LU }, + +{ "lbz", OP(34), OP_MASK, COM, { RT, D, RA0 }, PPC_INST_LBZ }, + +{ "lbzu", OP(35), OP_MASK, COM, { RT, D, RAL }, PPC_INST_LBZU }, + +{ "stw", OP(36), OP_MASK, PPCCOM, { RS, D, RA0 }, PPC_INST_STW }, +{ "st", OP(36), OP_MASK, PWRCOM, { RS, D, RA0 }, PPC_INST_ST }, + +{ "stwu", OP(37), OP_MASK, PPCCOM, { RS, D, RAS }, PPC_INST_STWU }, +{ "stu", OP(37), OP_MASK, PWRCOM, { RS, D, RA0 }, PPC_INST_STU }, + +{ "stb", OP(38), OP_MASK, COM, { RS, D, RA0 }, PPC_INST_STB }, + +{ "stbu", OP(39), OP_MASK, COM, { RS, D, RAS }, PPC_INST_STBU }, + +{ "lhz", OP(40), OP_MASK, COM, { RT, D, RA0 }, PPC_INST_LHZ }, + +{ "lhzu", OP(41), OP_MASK, COM, { RT, D, RAL }, PPC_INST_LHZU }, + +{ "lha", OP(42), OP_MASK, COM, { RT, D, RA0 }, PPC_INST_LHA }, + +{ "lhau", OP(43), OP_MASK, COM, { RT, D, RAL }, PPC_INST_LHAU }, + +{ "sth", OP(44), OP_MASK, COM, { RS, D, RA0 }, PPC_INST_STH }, + +{ "sthu", OP(45), OP_MASK, COM, { RS, D, RAS }, PPC_INST_STHU }, + +{ "lmw", OP(46), OP_MASK, PPCCOM, { RT, D, RAM }, PPC_INST_LMW }, +{ "lm", OP(46), OP_MASK, PWRCOM, { RT, D, RA0 }, PPC_INST_LM }, + +{ "stmw", OP(47), OP_MASK, PPCCOM, { RS, D, RA0 }, PPC_INST_STMW }, +{ "stm", OP(47), OP_MASK, PWRCOM, { RS, D, RA0 }, PPC_INST_STM }, + +{ "lfs", OP(48), OP_MASK, COM, { FRT, D, RA0 }, PPC_INST_LFS }, + +{ "lfsu", OP(49), OP_MASK, COM, { FRT, D, RAS }, PPC_INST_LFSU }, + +{ "lfd", OP(50), OP_MASK, COM, { FRT, D, RA0 }, PPC_INST_LFD }, + +{ "lfdu", OP(51), OP_MASK, COM, { FRT, D, RAS }, PPC_INST_LFDU }, + +{ "stfs", OP(52), OP_MASK, COM, { FRS, D, RA0 }, PPC_INST_STFS }, + +{ "stfsu", OP(53), OP_MASK, COM, { FRS, D, RAS }, PPC_INST_STFSU }, + +{ "stfd", OP(54), OP_MASK, COM, { FRS, D, RA0 }, PPC_INST_STFD }, + +{ "stfdu", OP(55), OP_MASK, COM, { FRS, D, RAS }, PPC_INST_STFDU }, + +{ "lq", OP(56), OP_MASK, POWER4, { RTQ, DQ, RAQ }, PPC_INST_LQ }, + +{ "lfq", OP(56), OP_MASK, POWER2, { FRT, D, RA0 }, PPC_INST_LFQ }, + +{ "lfqu", OP(57), OP_MASK, POWER2, { FRT, D, RA0 }, PPC_INST_LFQU }, + +{ "lfdp", OP(57), OP_MASK, POWER6, { FRT, D, RA0 }, PPC_INST_LFDP }, + +{ "lbze", DEO(58,0), DE_MASK, BOOKE64, { RT, DE, RA0 }, PPC_INST_LBZE }, +{ "lbzue", DEO(58,1), DE_MASK, BOOKE64, { RT, DE, RAL }, PPC_INST_LBZUE }, +{ "lhze", DEO(58,2), DE_MASK, BOOKE64, { RT, DE, RA0 }, PPC_INST_LHZE }, +{ "lhzue", DEO(58,3), DE_MASK, BOOKE64, { RT, DE, RAL }, PPC_INST_LHZUE }, +{ "lhae", DEO(58,4), DE_MASK, BOOKE64, { RT, DE, RA0 }, PPC_INST_LHAE }, +{ "lhaue", DEO(58,5), DE_MASK, BOOKE64, { RT, DE, RAL }, PPC_INST_LHAUE }, +{ "lwze", DEO(58,6), DE_MASK, BOOKE64, { RT, DE, RA0 }, PPC_INST_LWZE }, +{ "lwzue", DEO(58,7), DE_MASK, BOOKE64, { RT, DE, RAL }, PPC_INST_LWZUE }, +{ "stbe", DEO(58,8), DE_MASK, BOOKE64, { RS, DE, RA0 }, PPC_INST_STBE }, +{ "stbue", DEO(58,9), DE_MASK, BOOKE64, { RS, DE, RAS }, PPC_INST_STBUE }, +{ "sthe", DEO(58,10), DE_MASK, BOOKE64, { RS, DE, RA0 }, PPC_INST_STHE }, +{ "sthue", DEO(58,11), DE_MASK, BOOKE64, { RS, DE, RAS }, PPC_INST_STHUE }, +{ "stwe", DEO(58,14), DE_MASK, BOOKE64, { RS, DE, RA0 }, PPC_INST_STWE }, +{ "stwue", DEO(58,15), DE_MASK, BOOKE64, { RS, DE, RAS }, PPC_INST_STWUE }, + +{ "ld", DSO(58,0), DS_MASK, PPC64, { RT, DS, RA0 }, PPC_INST_LD }, + +{ "ldu", DSO(58,1), DS_MASK, PPC64, { RT, DS, RAL }, PPC_INST_LDU }, + +{ "lwa", DSO(58,2), DS_MASK, PPC64, { RT, DS, RA0 }, PPC_INST_LWA }, + +{ "dadd", XRC(59,2,0), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DADD }, +{ "dadd.", XRC(59,2,1), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DADD }, + +{ "dqua", ZRC(59,3,0), Z2_MASK, POWER6, { FRT, FRA, FRB, RMC }, PPC_INST_DQUA }, +{ "dqua.", ZRC(59,3,1), Z2_MASK, POWER6, { FRT, FRA, FRB, RMC }, PPC_INST_DQUA }, + +{ "fdivs", A(59,18,0), AFRC_MASK, PPC, { FRT, FRA, FRB }, PPC_INST_FDIVS }, +{ "fdivs.", A(59,18,1), AFRC_MASK, PPC, { FRT, FRA, FRB }, PPC_INST_FDIVS }, + +{ "fsubs", A(59,20,0), AFRC_MASK, PPC, { FRT, FRA, FRB }, PPC_INST_FSUBS }, +{ "fsubs.", A(59,20,1), AFRC_MASK, PPC, { FRT, FRA, FRB }, PPC_INST_FSUBS }, + +{ "fadds", A(59,21,0), AFRC_MASK, PPC, { FRT, FRA, FRB }, PPC_INST_FADDS }, +{ "fadds.", A(59,21,1), AFRC_MASK, PPC, { FRT, FRA, FRB }, PPC_INST_FADDS }, + +{ "fsqrts", A(59,22,0), AFRAFRC_MASK, PPC, { FRT, FRB }, PPC_INST_FSQRTS }, +{ "fsqrts.", A(59,22,1), AFRAFRC_MASK, PPC, { FRT, FRB }, PPC_INST_FSQRTS }, + +{ "fres", A(59,24,0), AFRALFRC_MASK, PPC, { FRT, FRB, A_L }, PPC_INST_FRES }, +{ "fres.", A(59,24,1), AFRALFRC_MASK, PPC, { FRT, FRB, A_L }, PPC_INST_FRES }, + +{ "fmuls", A(59,25,0), AFRB_MASK, PPC, { FRT, FRA, FRC }, PPC_INST_FMULS }, +{ "fmuls.", A(59,25,1), AFRB_MASK, PPC, { FRT, FRA, FRC }, PPC_INST_FMULS }, + +{ "frsqrtes", A(59,26,0), AFRALFRC_MASK,POWER5, { FRT, FRB, A_L }, PPC_INST_FRSQRTES }, +{ "frsqrtes.",A(59,26,1), AFRALFRC_MASK,POWER5, { FRT, FRB, A_L }, PPC_INST_FRSQRTES }, + +{ "fmsubs", A(59,28,0), A_MASK, PPC, { FRT,FRA,FRC,FRB }, PPC_INST_FMSUBS }, +{ "fmsubs.", A(59,28,1), A_MASK, PPC, { FRT,FRA,FRC,FRB }, PPC_INST_FMSUBS }, + +{ "fmadds", A(59,29,0), A_MASK, PPC, { FRT,FRA,FRC,FRB }, PPC_INST_FMADDS }, +{ "fmadds.", A(59,29,1), A_MASK, PPC, { FRT,FRA,FRC,FRB }, PPC_INST_FMADDS }, + +{ "fnmsubs", A(59,30,0), A_MASK, PPC, { FRT,FRA,FRC,FRB }, PPC_INST_FNMSUBS }, +{ "fnmsubs.",A(59,30,1), A_MASK, PPC, { FRT,FRA,FRC,FRB }, PPC_INST_FNMSUBS }, + +{ "fnmadds", A(59,31,0), A_MASK, PPC, { FRT,FRA,FRC,FRB }, PPC_INST_FNMADDS }, +{ "fnmadds.",A(59,31,1), A_MASK, PPC, { FRT,FRA,FRC,FRB }, PPC_INST_FNMADDS }, + +{ "dmul", XRC(59,34,0), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DMUL }, +{ "dmul.", XRC(59,34,1), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DMUL }, + +{ "drrnd", ZRC(59,35,0), Z2_MASK, POWER6, { FRT, FRA, FRB, RMC }, PPC_INST_DRRND }, +{ "drrnd.", ZRC(59,35,1), Z2_MASK, POWER6, { FRT, FRA, FRB, RMC }, PPC_INST_DRRND }, + +{ "dscli", ZRC(59,66,0), Z_MASK, POWER6, { FRT, FRA, SH16 }, PPC_INST_DSCLI }, +{ "dscli.", ZRC(59,66,1), Z_MASK, POWER6, { FRT, FRA, SH16 }, PPC_INST_DSCLI }, + +{ "dquai", ZRC(59,67,0), Z2_MASK, POWER6, { TE, FRT, FRB, RMC }, PPC_INST_DQUAI }, +{ "dquai.", ZRC(59,67,1), Z2_MASK, POWER6, { TE, FRT, FRB, RMC }, PPC_INST_DQUAI }, + +{ "dscri", ZRC(59,98,0), Z_MASK, POWER6, { FRT, FRA, SH16 }, PPC_INST_DSCRI }, +{ "dscri.", ZRC(59,98,1), Z_MASK, POWER6, { FRT, FRA, SH16 }, PPC_INST_DSCRI }, + +{ "drintx", ZRC(59,99,0), Z2_MASK, POWER6, { R, FRT, FRB, RMC }, PPC_INST_DRINTX }, +{ "drintx.", ZRC(59,99,1), Z2_MASK, POWER6, { R, FRT, FRB, RMC }, PPC_INST_DRINTX }, + +{ "dcmpo", X(59,130), X_MASK, POWER6, { BF, FRA, FRB }, PPC_INST_DCMPO }, + +{ "dtstex", X(59,162), X_MASK, POWER6, { BF, FRA, FRB }, PPC_INST_DTSTEX }, +{ "dtstdc", Z(59,194), Z_MASK, POWER6, { BF, FRA, DCM }, PPC_INST_DTSTDC }, +{ "dtstdg", Z(59,226), Z_MASK, POWER6, { BF, FRA, DGM }, PPC_INST_DTSTDG }, + +{ "drintn", ZRC(59,227,0), Z2_MASK, POWER6, { R, FRT, FRB, RMC }, PPC_INST_DRINTN }, +{ "drintn.", ZRC(59,227,1), Z2_MASK, POWER6, { R, FRT, FRB, RMC }, PPC_INST_DRINTN }, + +{ "dctdp", XRC(59,258,0), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DCTDP }, +{ "dctdp.", XRC(59,258,1), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DCTDP }, + +{ "dctfix", XRC(59,290,0), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DCTFIX }, +{ "dctfix.", XRC(59,290,1), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DCTFIX }, + +{ "ddedpd", XRC(59,322,0), X_MASK, POWER6, { SP, FRT, FRB }, PPC_INST_DDEDPD }, +{ "ddedpd.", XRC(59,322,1), X_MASK, POWER6, { SP, FRT, FRB }, PPC_INST_DDEDPD }, + +{ "dxex", XRC(59,354,0), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DXEX }, +{ "dxex.", XRC(59,354,1), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DXEX }, + +{ "dsub", XRC(59,514,0), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DSUB }, +{ "dsub.", XRC(59,514,1), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DSUB }, + +{ "ddiv", XRC(59,546,0), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DDIV }, +{ "ddiv.", XRC(59,546,1), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DDIV }, + +{ "dcmpu", X(59,642), X_MASK, POWER6, { BF, FRA, FRB }, PPC_INST_DCMPU }, + +{ "dtstsf", X(59,674), X_MASK, POWER6, { BF, FRA, FRB }, PPC_INST_DTSTSF }, + +{ "drsp", XRC(59,770,0), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DRSP }, +{ "drsp.", XRC(59,770,1), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DRSP }, + +{ "dcffix", XRC(59,802,0), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DCFFIX }, +{ "dcffix.", XRC(59,802,1), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DCFFIX }, + +{ "denbcd", XRC(59,834,0), X_MASK, POWER6, { S, FRT, FRB }, PPC_INST_DENBCD }, +{ "denbcd.", XRC(59,834,1), X_MASK, POWER6, { S, FRT, FRB }, PPC_INST_DENBCD }, + +{ "diex", XRC(59,866,0), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DIEX }, +{ "diex.", XRC(59,866,1), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DIEX }, + +{ "stfq", OP(60), OP_MASK, POWER2, { FRS, D, RA }, PPC_INST_STFQ }, + +{ "stfqu", OP(61), OP_MASK, POWER2, { FRS, D, RA }, PPC_INST_STFQU }, + +{ "stfdp", OP(61), OP_MASK, POWER6, { FRT, D, RA0 }, PPC_INST_STFDP }, + +{ "lde", DEO(62,0), DE_MASK, BOOKE64, { RT, DES, RA0 }, PPC_INST_LDE }, +{ "ldue", DEO(62,1), DE_MASK, BOOKE64, { RT, DES, RA0 }, PPC_INST_LDUE }, +{ "lfse", DEO(62,4), DE_MASK, BOOKE64, { FRT, DES, RA0 }, PPC_INST_LFSE }, +{ "lfsue", DEO(62,5), DE_MASK, BOOKE64, { FRT, DES, RAS }, PPC_INST_LFSUE }, +{ "lfde", DEO(62,6), DE_MASK, BOOKE64, { FRT, DES, RA0 }, PPC_INST_LFDE }, +{ "lfdue", DEO(62,7), DE_MASK, BOOKE64, { FRT, DES, RAS }, PPC_INST_LFDUE }, +{ "stde", DEO(62,8), DE_MASK, BOOKE64, { RS, DES, RA0 }, PPC_INST_STDE }, +{ "stdue", DEO(62,9), DE_MASK, BOOKE64, { RS, DES, RAS }, PPC_INST_STDUE }, +{ "stfse", DEO(62,12), DE_MASK, BOOKE64, { FRS, DES, RA0 }, PPC_INST_STFSE }, +{ "stfsue", DEO(62,13), DE_MASK, BOOKE64, { FRS, DES, RAS }, PPC_INST_STFSUE }, +{ "stfde", DEO(62,14), DE_MASK, BOOKE64, { FRS, DES, RA0 }, PPC_INST_STFDE }, +{ "stfdue", DEO(62,15), DE_MASK, BOOKE64, { FRS, DES, RAS }, PPC_INST_STFDUE }, + +{ "std", DSO(62,0), DS_MASK, PPC64, { RS, DS, RA0 }, PPC_INST_STD }, + +{ "stdu", DSO(62,1), DS_MASK, PPC64, { RS, DS, RAS }, PPC_INST_STDU }, + +{ "stq", DSO(62,2), DS_MASK, POWER4, { RSQ, DS, RA0 }, PPC_INST_STQ }, + +{ "fcmpu", X(63,0), X_MASK | (3 << 21), COM, { BF, FRA, FRB }, PPC_INST_FCMPU }, + +{ "daddq", XRC(63,2,0), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DADDQ }, +{ "daddq.", XRC(63,2,1), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DADDQ }, + +{ "dquaq", ZRC(63,3,0), Z2_MASK, POWER6, { FRT, FRA, FRB, RMC }, PPC_INST_DQUAQ }, +{ "dquaq.", ZRC(63,3,1), Z2_MASK, POWER6, { FRT, FRA, FRB, RMC }, PPC_INST_DQUAQ }, + +{ "fcpsgn", XRC(63,8,0), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_FCPSGN }, +{ "fcpsgn.", XRC(63,8,1), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_FCPSGN }, + +{ "frsp", XRC(63,12,0), XRA_MASK, COM, { FRT, FRB }, PPC_INST_FRSP }, +{ "frsp.", XRC(63,12,1), XRA_MASK, COM, { FRT, FRB }, PPC_INST_FRSP }, + +{ "fctiw", XRC(63,14,0), XRA_MASK, PPCCOM, { FRT, FRB }, PPC_INST_FCTIW }, +{ "fcir", XRC(63,14,0), XRA_MASK, POWER2, { FRT, FRB }, PPC_INST_FCIR }, +{ "fctiw.", XRC(63,14,1), XRA_MASK, PPCCOM, { FRT, FRB }, PPC_INST_FCTIW }, +{ "fcir.", XRC(63,14,1), XRA_MASK, POWER2, { FRT, FRB }, PPC_INST_FCIR }, + +{ "fctiwz", XRC(63,15,0), XRA_MASK, PPCCOM, { FRT, FRB }, PPC_INST_FCTIWZ }, +{ "fcirz", XRC(63,15,0), XRA_MASK, POWER2, { FRT, FRB }, PPC_INST_FCIRZ }, +{ "fctiwz.", XRC(63,15,1), XRA_MASK, PPCCOM, { FRT, FRB }, PPC_INST_FCTIWZ }, +{ "fcirz.", XRC(63,15,1), XRA_MASK, POWER2, { FRT, FRB }, PPC_INST_FCIRZ }, + +{ "fdiv", A(63,18,0), AFRC_MASK, PPCCOM, { FRT, FRA, FRB }, PPC_INST_FDIV }, +{ "fd", A(63,18,0), AFRC_MASK, PWRCOM, { FRT, FRA, FRB }, PPC_INST_FD }, +{ "fdiv.", A(63,18,1), AFRC_MASK, PPCCOM, { FRT, FRA, FRB }, PPC_INST_FDIV }, +{ "fd.", A(63,18,1), AFRC_MASK, PWRCOM, { FRT, FRA, FRB }, PPC_INST_FD }, + +{ "fsub", A(63,20,0), AFRC_MASK, PPCCOM, { FRT, FRA, FRB }, PPC_INST_FSUB }, +{ "fs", A(63,20,0), AFRC_MASK, PWRCOM, { FRT, FRA, FRB }, PPC_INST_FS }, +{ "fsub.", A(63,20,1), AFRC_MASK, PPCCOM, { FRT, FRA, FRB }, PPC_INST_FSUB }, +{ "fs.", A(63,20,1), AFRC_MASK, PWRCOM, { FRT, FRA, FRB }, PPC_INST_FS }, + +{ "fadd", A(63,21,0), AFRC_MASK, PPCCOM, { FRT, FRA, FRB }, PPC_INST_FADD }, +{ "fa", A(63,21,0), AFRC_MASK, PWRCOM, { FRT, FRA, FRB }, PPC_INST_FA }, +{ "fadd.", A(63,21,1), AFRC_MASK, PPCCOM, { FRT, FRA, FRB }, PPC_INST_FADD }, +{ "fa.", A(63,21,1), AFRC_MASK, PWRCOM, { FRT, FRA, FRB }, PPC_INST_FA }, + +{ "fsqrt", A(63,22,0), AFRAFRC_MASK, PPCPWR2, { FRT, FRB }, PPC_INST_FSQRT }, +{ "fsqrt.", A(63,22,1), AFRAFRC_MASK, PPCPWR2, { FRT, FRB }, PPC_INST_FSQRT }, + +{ "fsel", A(63,23,0), A_MASK, PPC, { FRT,FRA,FRC,FRB }, PPC_INST_FSEL }, +{ "fsel.", A(63,23,1), A_MASK, PPC, { FRT,FRA,FRC,FRB }, PPC_INST_FSEL }, + +{ "fre", A(63,24,0), AFRALFRC_MASK, POWER5, { FRT, FRB, A_L }, PPC_INST_FRE }, +{ "fre.", A(63,24,1), AFRALFRC_MASK, POWER5, { FRT, FRB, A_L }, PPC_INST_FRE }, + +{ "fmul", A(63,25,0), AFRB_MASK, PPCCOM, { FRT, FRA, FRC }, PPC_INST_FMUL }, +{ "fm", A(63,25,0), AFRB_MASK, PWRCOM, { FRT, FRA, FRC }, PPC_INST_FM }, +{ "fmul.", A(63,25,1), AFRB_MASK, PPCCOM, { FRT, FRA, FRC }, PPC_INST_FMUL }, +{ "fm.", A(63,25,1), AFRB_MASK, PWRCOM, { FRT, FRA, FRC }, PPC_INST_FM }, + +{ "frsqrte", A(63,26,0), AFRALFRC_MASK, PPC, { FRT, FRB, A_L }, PPC_INST_FRSQRTE }, +{ "frsqrte.",A(63,26,1), AFRALFRC_MASK, PPC, { FRT, FRB, A_L }, PPC_INST_FRSQRTE }, + +{ "fmsub", A(63,28,0), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB }, PPC_INST_FMSUB }, +{ "fms", A(63,28,0), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB }, PPC_INST_FMS }, +{ "fmsub.", A(63,28,1), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB }, PPC_INST_FMSUB }, +{ "fms.", A(63,28,1), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB }, PPC_INST_FMS }, + +{ "fmadd", A(63,29,0), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB }, PPC_INST_FMADD }, +{ "fma", A(63,29,0), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB }, PPC_INST_FMA }, +{ "fmadd.", A(63,29,1), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB }, PPC_INST_FMADD }, +{ "fma.", A(63,29,1), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB }, PPC_INST_FMA }, + +{ "fnmsub", A(63,30,0), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB }, PPC_INST_FNMSUB }, +{ "fnms", A(63,30,0), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB }, PPC_INST_FNMS }, +{ "fnmsub.", A(63,30,1), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB }, PPC_INST_FNMSUB }, +{ "fnms.", A(63,30,1), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB }, PPC_INST_FNMS }, + +{ "fnmadd", A(63,31,0), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB }, PPC_INST_FNMADD }, +{ "fnma", A(63,31,0), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB }, PPC_INST_FNMA }, +{ "fnmadd.", A(63,31,1), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB }, PPC_INST_FNMADD }, +{ "fnma.", A(63,31,1), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB }, PPC_INST_FNMA }, + +{ "fcmpo", X(63,32), X_MASK | (3 << 21), COM, { BF, FRA, FRB }, PPC_INST_FCMPO }, + +{ "dmulq", XRC(63,34,0), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DMULQ }, +{ "dmulq.", XRC(63,34,1), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DMULQ }, + +{ "drrndq", ZRC(63,35,0), Z2_MASK, POWER6, { FRT, FRA, FRB, RMC }, PPC_INST_DRRNDQ }, +{ "drrndq.", ZRC(63,35,1), Z2_MASK, POWER6, { FRT, FRA, FRB, RMC }, PPC_INST_DRRNDQ }, + +{ "mtfsb1", XRC(63,38,0), XRARB_MASK, COM, { BT }, PPC_INST_MTFSB1 }, +{ "mtfsb1.", XRC(63,38,1), XRARB_MASK, COM, { BT }, PPC_INST_MTFSB1 }, + +{ "fneg", XRC(63,40,0), XRA_MASK, COM, { FRT, FRB }, PPC_INST_FNEG }, +{ "fneg.", XRC(63,40,1), XRA_MASK, COM, { FRT, FRB }, PPC_INST_FNEG }, + +{ "mcrfs", X(63,64), XRB_MASK | (3 << 21) | (3 << 16), COM, { BF, BFA }, PPC_INST_MCRFS }, + +{ "dscliq", ZRC(63,66,0), Z_MASK, POWER6, { FRT, FRA, SH16 }, PPC_INST_DSCLIQ }, +{ "dscliq.", ZRC(63,66,1), Z_MASK, POWER6, { FRT, FRA, SH16 }, PPC_INST_DSCLIQ }, + +{ "dquaiq", ZRC(63,67,0), Z2_MASK, POWER6, { TE, FRT, FRB, RMC }, PPC_INST_DQUAIQ }, +{ "dquaiq.", ZRC(63,67,1), Z2_MASK, POWER6, { FRT, FRA, FRB, RMC }, PPC_INST_DQUAIQ }, + +{ "mtfsb0", XRC(63,70,0), XRARB_MASK, COM, { BT }, PPC_INST_MTFSB0 }, +{ "mtfsb0.", XRC(63,70,1), XRARB_MASK, COM, { BT }, PPC_INST_MTFSB0 }, + +{ "fmr", XRC(63,72,0), XRA_MASK, COM, { FRT, FRB }, PPC_INST_FMR }, +{ "fmr.", XRC(63,72,1), XRA_MASK, COM, { FRT, FRB }, PPC_INST_FMR }, + +{ "dscriq", ZRC(63,98,0), Z_MASK, POWER6, { FRT, FRA, SH16 }, PPC_INST_DSCRIQ }, +{ "dscriq.", ZRC(63,98,1), Z_MASK, POWER6, { FRT, FRA, SH16 }, PPC_INST_DSCRIQ }, + +{ "drintxq", ZRC(63,99,0), Z2_MASK, POWER6, { R, FRT, FRB, RMC }, PPC_INST_DRINTXQ }, +{ "drintxq.",ZRC(63,99,1), Z2_MASK, POWER6, { R, FRT, FRB, RMC }, PPC_INST_DRINTXQ }, + +{ "dcmpoq", X(63,130), X_MASK, POWER6, { BF, FRA, FRB }, PPC_INST_DCMPOQ }, + +{ "mtfsfi", XRC(63,134,0), XWRA_MASK | (3 << 21) | (1 << 11), COM, { BFF, U, W }, PPC_INST_MTFSFI }, +{ "mtfsfi.", XRC(63,134,1), XWRA_MASK | (3 << 21) | (1 << 11), COM, { BFF, U, W }, PPC_INST_MTFSFI }, + +{ "fnabs", XRC(63,136,0), XRA_MASK, COM, { FRT, FRB }, PPC_INST_FNABS }, +{ "fnabs.", XRC(63,136,1), XRA_MASK, COM, { FRT, FRB }, PPC_INST_FNABS }, + +{ "dtstexq", X(63,162), X_MASK, POWER6, { BF, FRA, FRB }, PPC_INST_DTSTEXQ }, +{ "dtstdcq", Z(63,194), Z_MASK, POWER6, { BF, FRA, DCM }, PPC_INST_DTSTDCQ }, +{ "dtstdgq", Z(63,226), Z_MASK, POWER6, { BF, FRA, DGM }, PPC_INST_DTSTDGQ }, + +{ "drintnq", ZRC(63,227,0), Z2_MASK, POWER6, { R, FRT, FRB, RMC }, PPC_INST_DRINTNQ }, +{ "drintnq.",ZRC(63,227,1), Z2_MASK, POWER6, { R, FRT, FRB, RMC }, PPC_INST_DRINTNQ }, + +{ "dctqpq", XRC(63,258,0), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DCTQPQ }, +{ "dctqpq.", XRC(63,258,1), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DCTQPQ }, + +{ "fabs", XRC(63,264,0), XRA_MASK, COM, { FRT, FRB }, PPC_INST_FABS }, +{ "fabs.", XRC(63,264,1), XRA_MASK, COM, { FRT, FRB }, PPC_INST_FABS }, + +{ "dctfixq", XRC(63,290,0), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DCTFIXQ }, +{ "dctfixq.",XRC(63,290,1), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DCTFIXQ }, + +{ "ddedpdq", XRC(63,322,0), X_MASK, POWER6, { SP, FRT, FRB }, PPC_INST_DDEDPDQ }, +{ "ddedpdq.",XRC(63,322,1), X_MASK, POWER6, { SP, FRT, FRB }, PPC_INST_DDEDPDQ }, + +{ "dxexq", XRC(63,354,0), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DXEXQ }, +{ "dxexq.", XRC(63,354,1), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DXEXQ }, + +{ "frin", XRC(63,392,0), XRA_MASK, POWER5, { FRT, FRB }, PPC_INST_FRIN }, +{ "frin.", XRC(63,392,1), XRA_MASK, POWER5, { FRT, FRB }, PPC_INST_FRIN }, +{ "friz", XRC(63,424,0), XRA_MASK, POWER5, { FRT, FRB }, PPC_INST_FRIZ }, +{ "friz.", XRC(63,424,1), XRA_MASK, POWER5, { FRT, FRB }, PPC_INST_FRIZ }, +{ "frip", XRC(63,456,0), XRA_MASK, POWER5, { FRT, FRB }, PPC_INST_FRIP }, +{ "frip.", XRC(63,456,1), XRA_MASK, POWER5, { FRT, FRB }, PPC_INST_FRIP }, +{ "frim", XRC(63,488,0), XRA_MASK, POWER5, { FRT, FRB }, PPC_INST_FRIM }, +{ "frim.", XRC(63,488,1), XRA_MASK, POWER5, { FRT, FRB }, PPC_INST_FRIM }, + +{ "dsubq", XRC(63,514,0), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DSUBQ }, +{ "dsubq.", XRC(63,514,1), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DSUBQ }, + +{ "ddivq", XRC(63,546,0), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DDIVQ }, +{ "ddivq.", XRC(63,546,1), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DDIVQ }, + +{ "mffs", XRC(63,583,0), XRARB_MASK, COM, { FRT }, PPC_INST_MFFS }, +{ "mffs.", XRC(63,583,1), XRARB_MASK, COM, { FRT }, PPC_INST_MFFS }, + +{ "dcmpuq", X(63,642), X_MASK, POWER6, { BF, FRA, FRB }, PPC_INST_DCMPUQ }, + +{ "dtstsfq", X(63,674), X_MASK, POWER6, { BF, FRA, FRB }, PPC_INST_DTSTSFQ }, + +{ "mtfsf", XFL(63,711,0), XFL_MASK, COM, { FLM, FRB, XFL_L, W }, PPC_INST_MTFSF }, +{ "mtfsf.", XFL(63,711,1), XFL_MASK, COM, { FLM, FRB, XFL_L, W }, PPC_INST_MTFSF }, + +{ "drdpq", XRC(63,770,0), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DRDPQ }, +{ "drdpq.", XRC(63,770,1), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DRDPQ }, + +{ "dcffixq", XRC(63,802,0), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DCFFIXQ }, +{ "dcffixq.",XRC(63,802,1), X_MASK, POWER6, { FRT, FRB }, PPC_INST_DCFFIXQ }, + +{ "fctid", XRC(63,814,0), XRA_MASK, PPC64, { FRT, FRB }, PPC_INST_FCTID }, +{ "fctid.", XRC(63,814,1), XRA_MASK, PPC64, { FRT, FRB }, PPC_INST_FCTID }, + +{ "fctidz", XRC(63,815,0), XRA_MASK, PPC64, { FRT, FRB }, PPC_INST_FCTIDZ }, +{ "fctidz.", XRC(63,815,1), XRA_MASK, PPC64, { FRT, FRB }, PPC_INST_FCTIDZ }, + +{ "denbcdq", XRC(63,834,0), X_MASK, POWER6, { S, FRT, FRB }, PPC_INST_DENBCDQ }, +{ "denbcdq.",XRC(63,834,1), X_MASK, POWER6, { S, FRT, FRB }, PPC_INST_DENBCDQ }, + +{ "fcfid", XRC(63,846,0), XRA_MASK, PPC64, { FRT, FRB }, PPC_INST_FCFID }, +{ "fcfid.", XRC(63,846,1), XRA_MASK, PPC64, { FRT, FRB }, PPC_INST_FCFID }, + +{ "diexq", XRC(63,866,0), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DIEXQ }, +{ "diexq.", XRC(63,866,1), X_MASK, POWER6, { FRT, FRA, FRB }, PPC_INST_DIEXQ }, + +}; + +// (.+?")(.+)?(".+?)(\},) +// $1$2$3, POWERPC_INSTRUCTION_\U$2 $4 + +const int powerpc_num_opcodes = +sizeof(powerpc_opcodes) / sizeof(powerpc_opcodes[0]); + +/* The macro table. This is only used by the assembler. */ + +/* The expressions of the form (-x ! 31) & (x | 31) have the value 0 + when x=0; 32-x when x is between 1 and 31; are negative if x is + negative; and are 32 or more otherwise. This is what you want + when, for instance, you are emulating a right shift by a + rotate-left-and-mask, because the underlying instructions support + shifts of size 0 but not shifts of size 32. By comparison, when + extracting x bits from some word you want to use just 32-x, because + the underlying instructions don't support extracting 0 bits but do + support extracting the whole word (32 bits in this case). */ + +const struct powerpc_macro powerpc_macros[] = { +{ "extldi", 4, PPC64, "rldicr %0,%1,%3,(%2)-1" }, +{ "extldi.", 4, PPC64, "rldicr. %0,%1,%3,(%2)-1" }, +{ "extrdi", 4, PPC64, "rldicl %0,%1,(%2)+(%3),64-(%2)" }, +{ "extrdi.", 4, PPC64, "rldicl. %0,%1,(%2)+(%3),64-(%2)" }, +{ "insrdi", 4, PPC64, "rldimi %0,%1,64-((%2)+(%3)),%3" }, +{ "insrdi.", 4, PPC64, "rldimi. %0,%1,64-((%2)+(%3)),%3" }, +{ "rotrdi", 3, PPC64, "rldicl %0,%1,(-(%2)!63)&((%2)|63),0" }, +{ "rotrdi.", 3, PPC64, "rldicl. %0,%1,(-(%2)!63)&((%2)|63),0" }, +{ "sldi", 3, PPC64, "rldicr %0,%1,%2,63-(%2)" }, +{ "sldi.", 3, PPC64, "rldicr. %0,%1,%2,63-(%2)" }, +{ "srdi", 3, PPC64, "rldicl %0,%1,(-(%2)!63)&((%2)|63),%2" }, +{ "srdi.", 3, PPC64, "rldicl. %0,%1,(-(%2)!63)&((%2)|63),%2" }, +{ "clrrdi", 3, PPC64, "rldicr %0,%1,0,63-(%2)" }, +{ "clrrdi.", 3, PPC64, "rldicr. %0,%1,0,63-(%2)" }, +{ "clrlsldi",4, PPC64, "rldic %0,%1,%3,(%2)-(%3)" }, +{ "clrlsldi.",4, PPC64, "rldic. %0,%1,%3,(%2)-(%3)" }, + +{ "extlwi", 4, PPCCOM, "rlwinm %0,%1,%3,0,(%2)-1" }, +{ "extlwi.", 4, PPCCOM, "rlwinm. %0,%1,%3,0,(%2)-1" }, +{ "extrwi", 4, PPCCOM, "rlwinm %0,%1,((%2)+(%3))&((%2)+(%3)<>32),32-(%2),31" }, +{ "extrwi.", 4, PPCCOM, "rlwinm. %0,%1,((%2)+(%3))&((%2)+(%3)<>32),32-(%2),31" }, +{ "inslwi", 4, PPCCOM, "rlwimi %0,%1,(-(%3)!31)&((%3)|31),%3,(%2)+(%3)-1" }, +{ "inslwi.", 4, PPCCOM, "rlwimi. %0,%1,(-(%3)!31)&((%3)|31),%3,(%2)+(%3)-1"}, +{ "insrwi", 4, PPCCOM, "rlwimi %0,%1,32-((%2)+(%3)),%3,(%2)+(%3)-1" }, +{ "insrwi.", 4, PPCCOM, "rlwimi. %0,%1,32-((%2)+(%3)),%3,(%2)+(%3)-1"}, +{ "rotrwi", 3, PPCCOM, "rlwinm %0,%1,(-(%2)!31)&((%2)|31),0,31" }, +{ "rotrwi.", 3, PPCCOM, "rlwinm. %0,%1,(-(%2)!31)&((%2)|31),0,31" }, +{ "slwi", 3, PPCCOM, "rlwinm %0,%1,%2,0,31-(%2)" }, +{ "sli", 3, PWRCOM, "rlinm %0,%1,%2,0,31-(%2)" }, +{ "slwi.", 3, PPCCOM, "rlwinm. %0,%1,%2,0,31-(%2)" }, +{ "sli.", 3, PWRCOM, "rlinm. %0,%1,%2,0,31-(%2)" }, +{ "srwi", 3, PPCCOM, "rlwinm %0,%1,(-(%2)!31)&((%2)|31),%2,31" }, +{ "sri", 3, PWRCOM, "rlinm %0,%1,(-(%2)!31)&((%2)|31),%2,31" }, +{ "srwi.", 3, PPCCOM, "rlwinm. %0,%1,(-(%2)!31)&((%2)|31),%2,31" }, +{ "sri.", 3, PWRCOM, "rlinm. %0,%1,(-(%2)!31)&((%2)|31),%2,31" }, +{ "clrrwi", 3, PPCCOM, "rlwinm %0,%1,0,0,31-(%2)" }, +{ "clrrwi.", 3, PPCCOM, "rlwinm. %0,%1,0,0,31-(%2)" }, +{ "clrlslwi",4, PPCCOM, "rlwinm %0,%1,%3,(%2)-(%3),31-(%3)" }, +{ "clrlslwi.",4, PPCCOM, "rlwinm. %0,%1,%3,(%2)-(%3),31-(%3)" }, +}; + +const int powerpc_num_macros = +sizeof(powerpc_macros) / sizeof(powerpc_macros[0]); + + +/* This file provides several disassembler functions, all of which use + the disassembler interface defined in dis-asm.h. Several functions + are provided because this file handles disassembly for the PowerPC + in both big and little endian mode and also for the POWER (RS/6000) + chip. */ + +static int print_insn_powerpc(bfd_vma, struct disassemble_info*, int, int); +static int decode_insn_powerpc(bfd_vma memaddr, disassemble_info* info, int bigendian, int dialect, ppc_insn* oinsn); + +/* Determine which set of machines to disassemble for. PPC403/601 or + BookE. For convenience, also disassemble instructions supported + by the AltiVec vector unit. */ + +static int +powerpc_dialect(struct disassemble_info* info) +{ + int dialect = PPC_OPCODE_PPC; + + if (BFD_DEFAULT_TARGET_SIZE == 64) + dialect |= PPC_OPCODE_64; + + if (info->disassembler_options + && strstr(info->disassembler_options, "booke") != NULL) + dialect |= PPC_OPCODE_BOOKE | PPC_OPCODE_BOOKE64; + else if ((info->mach == bfd_mach_ppc_e500) + || (info->disassembler_options + && strstr(info->disassembler_options, "e500") != NULL)) + dialect |= (PPC_OPCODE_BOOKE + | PPC_OPCODE_SPE | PPC_OPCODE_ISEL + | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK + | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK + | PPC_OPCODE_RFMCI); + else if (info->disassembler_options + && strstr(info->disassembler_options, "efs") != NULL) + dialect |= PPC_OPCODE_EFS; + else if (info->disassembler_options + && strstr(info->disassembler_options, "e300") != NULL) + dialect |= PPC_OPCODE_E300 | PPC_OPCODE_CLASSIC | PPC_OPCODE_COMMON; + else if (info->disassembler_options + && strstr(info->disassembler_options, "440") != NULL) + dialect |= PPC_OPCODE_BOOKE | PPC_OPCODE_32 + | PPC_OPCODE_440 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI; + else + dialect |= (PPC_OPCODE_403 | PPC_OPCODE_601 | PPC_OPCODE_CLASSIC + | PPC_OPCODE_COMMON | PPC_OPCODE_ALTIVEC); + + if (info->disassembler_options + && strstr(info->disassembler_options, "power4") != NULL) + dialect |= PPC_OPCODE_POWER4; + + if (info->disassembler_options + && strstr(info->disassembler_options, "power5") != NULL) + dialect |= PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5; + + if (info->disassembler_options + && strstr(info->disassembler_options, "cell") != NULL) + dialect |= PPC_OPCODE_POWER4 | PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VMX_128; + + if (info->disassembler_options + && strstr(info->disassembler_options, "power6") != NULL) + dialect |= PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC; + + if (info->disassembler_options + && strstr(info->disassembler_options, "any") != NULL) + dialect |= PPC_OPCODE_ANY; + + if (info->disassembler_options) + { + if (strstr(info->disassembler_options, "32") != NULL) + dialect &= ~PPC_OPCODE_64; + else if (strstr(info->disassembler_options, "64") != NULL) + dialect |= PPC_OPCODE_64; + } + + info->private_data = (char*)0 + dialect; + return dialect; +} + +int decode_insn_ppc(bfd_vma memaddr, disassemble_info* info, ppc_insn* oinsn) +{ + int dialect = (char*)info->private_data - (char*)0; + return decode_insn_powerpc(memaddr, info, 1, dialect, oinsn); +} + +/* Qemu default */ +int +print_insn_ppc(bfd_vma memaddr, struct disassemble_info* info) +{ + int dialect = (char*)info->private_data - (char*)0; + return print_insn_powerpc(memaddr, info, 1, dialect); +} + +/* Print a big endian PowerPC instruction. */ + +int +print_insn_big_powerpc(bfd_vma memaddr, struct disassemble_info* info) +{ + int dialect = (char*)info->private_data - (char*)0; + return print_insn_powerpc(memaddr, info, 1, dialect); +} + +/* Print a little endian PowerPC instruction. */ + +int +print_insn_little_powerpc(bfd_vma memaddr, struct disassemble_info* info) +{ + int dialect = (char*)info->private_data - (char*)0; + return print_insn_powerpc(memaddr, info, 0, dialect); +} + +/* Print a POWER (RS/6000) instruction. */ + +int +print_insn_rs6000(bfd_vma memaddr, struct disassemble_info* info) +{ + return print_insn_powerpc(memaddr, info, 1, PPC_OPCODE_POWER); +} + +/* Extract the operand value from the PowerPC or POWER instruction. */ + +static long +operand_value_powerpc(const struct powerpc_operand* operand, + unsigned long insn, int dialect) +{ + long value; + int invalid; + /* Extract the value from the instruction. */ + if (operand->extract) + value = (*operand->extract) (insn, dialect, &invalid); + else + { + value = (insn >> operand->shift) & operand->bitm; + if ((operand->flags & PPC_OPERAND_SIGNED) != 0) + { + /* BITM is always some number of zeros followed by some + number of ones, followed by some numer of zeros. */ + unsigned long top = operand->bitm; + /* top & -top gives the rightmost 1 bit, so this + fills in any trailing zeros. */ + top |= (top & -top) - 1; + top &= ~(top >> 1); + value = (value ^ top) - top; + } + } + + return value; +} + +/* Determine whether the optional operand(s) should be printed. */ + +static int +skip_optional_operands(const unsigned char* opindex, + unsigned long insn, int dialect) +{ + const struct powerpc_operand* operand; + + for (; *opindex != 0; opindex++) + { + operand = &powerpc_operands[*opindex]; + if ((operand->flags & PPC_OPERAND_NEXT) != 0 + || ((operand->flags & PPC_OPERAND_OPTIONAL) != 0 + && operand_value_powerpc(operand, insn, dialect) != 0)) + return 0; + } + + return 1; +} + +/* Print a PowerPC or POWER instruction. */ + +static int +print_insn_powerpc(bfd_vma memaddr, + struct disassemble_info* info, + int bigendian, + int dialect) +{ + bfd_byte buffer[4]; + int status; + unsigned long insn; + const struct powerpc_opcode* opcode; + const struct powerpc_opcode* opcode_end; + unsigned long op; + + if (dialect == 0) + dialect = powerpc_dialect(info); + + status = (*info->read_memory_func) (memaddr, buffer, 4, info); + if (status != 0) + { + (*info->memory_error_func) (status, memaddr, info); + return -1; + } + + if (bigendian) + insn = bfd_getb32(buffer); + else + insn = bfd_getl32(buffer); + + /* Get the major opcode of the instruction. */ + op = PPC_OP(insn); + + /* Find the first match in the opcode table. We could speed this up + a bit by doing a binary search on the major opcode. */ + opcode_end = powerpc_opcodes + powerpc_num_opcodes; +again: + for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++) + { + unsigned long table_op; + const unsigned char* opindex; + const struct powerpc_operand* operand; + int invalid; + int need_comma; + int need_paren; + int skip_optional; + + table_op = PPC_OP(opcode->opcode); + if (op < table_op) + break; + if (op > table_op) + continue; + + if ((insn & opcode->mask) != opcode->opcode + || (opcode->flags & dialect) == 0) + continue; + + /* Make two passes over the operands. First see if any of them + have extraction functions, and, if they do, make sure the + instruction is valid. */ + invalid = 0; + for (opindex = opcode->operands; *opindex != 0; opindex++) + { + operand = powerpc_operands + *opindex; + if (operand->extract) + (*operand->extract) (insn, dialect, &invalid); + } + if (invalid) + continue; + + /* The instruction is valid. */ + if (opcode->operands[0] != 0) + (*info->fprintf_func) (info->stream, "%-7s ", opcode->name); + else + (*info->fprintf_func) (info->stream, "%s", opcode->name); + + /* Now extract and print the operands. */ + need_comma = 0; + need_paren = 0; + skip_optional = -1; + for (opindex = opcode->operands; *opindex != 0; opindex++) + { + long value; + + operand = powerpc_operands + *opindex; + + /* Operands that are marked FAKE are simply ignored. We + already made sure that the extract function considered + the instruction to be valid. */ + if ((operand->flags & PPC_OPERAND_FAKE) != 0) + continue; + + /* If all of the optional operands have the value zero, + then don't print any of them. */ + if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0) + { + if (skip_optional < 0) + skip_optional = skip_optional_operands(opindex, insn, + dialect); + if (skip_optional) + continue; + } + + value = operand_value_powerpc(operand, insn, dialect); + + if (need_comma) + { + (*info->fprintf_func) (info->stream, ","); + need_comma = 0; + } + + /* Print the operand as directed by the flags. */ + if ((operand->flags & PPC_OPERAND_GPR) != 0 + || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0)) + (*info->fprintf_func) (info->stream, "r%ld", value); + else if ((operand->flags & PPC_OPERAND_FPR) != 0) + (*info->fprintf_func) (info->stream, "f%ld", value); + else if ((operand->flags & PPC_OPERAND_VR) != 0) + (*info->fprintf_func) (info->stream, "v%ld", value); + else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0) + (*info->print_address_func) (memaddr + value, info); + else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0) + (*info->print_address_func) ((bfd_vma)value & 0xffffffff, info); + else if ((operand->flags & PPC_OPERAND_CR) == 0 + || (dialect & PPC_OPCODE_PPC) == 0) + (*info->fprintf_func) (info->stream, "%ld", value); + else + { + if (operand->bitm == 7) + (*info->fprintf_func) (info->stream, "cr%ld", value); + else + { + static const char* cbnames[4] = { "lt", "gt", "eq", "so" }; + int cr; + int cc; + + cr = value >> 2; + if (cr != 0) + (*info->fprintf_func) (info->stream, "4*cr%d+", cr); + cc = value & 3; + (*info->fprintf_func) (info->stream, "%s", cbnames[cc]); + } + } + + if (need_paren) + { + (*info->fprintf_func) (info->stream, ")"); + need_paren = 0; + } + + if ((operand->flags & PPC_OPERAND_PARENS) == 0) + need_comma = 1; + else + { + (*info->fprintf_func) (info->stream, "("); + need_paren = 1; + } + } + + /* We have found and printed an instruction; return. */ + return 4; + } + + if ((dialect & PPC_OPCODE_ANY) != 0) + { + dialect = ~PPC_OPCODE_ANY; + goto again; + } + + /* We could not find a match. */ + (*info->fprintf_func) (info->stream, ".long 0x%lx", insn); + + return 4; +} + +static int decode_insn_powerpc(bfd_vma memaddr, disassemble_info* info, int bigendian, int dialect, ppc_insn* oinsn) +{ + bfd_byte buffer[4]; + int status; + unsigned long insn; + const struct powerpc_opcode* opcode; + const struct powerpc_opcode* opcode_end; + unsigned long op; + char* stream = oinsn->op_str; + + if (dialect == 0) + dialect = powerpc_dialect(info); + + oinsn->op_str[0] = 0; + status = (*info->read_memory_func) (memaddr, buffer, 4, info); + if (status != 0) + { + (*info->memory_error_func) (status, memaddr, info); + return -1; + } + + if (bigendian) + insn = bfd_getb32(buffer); + else + insn = bfd_getl32(buffer); + + oinsn->instruction = insn; + memset(oinsn->operands, 0, sizeof(oinsn->operands)); + + /* Get the major opcode of the instruction. */ + op = PPC_OP(insn); + + /* Find the first match in the opcode table. We could speed this up + a bit by doing a binary search on the major opcode. */ + opcode_end = powerpc_opcodes + powerpc_num_opcodes; +again: + for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++) + { + unsigned long table_op; + unsigned long i_op; + const unsigned char* opindex; + const struct powerpc_operand* operand; + int invalid; + int need_comma; + int need_paren; + int skip_optional; + + table_op = PPC_OP(opcode->opcode); + if (op < table_op) + break; + if (op > table_op) + continue; + + if ((insn & opcode->mask) != opcode->opcode + || (opcode->flags & dialect) == 0) + continue; + + /* Make two passes over the operands. First see if any of them + have extraction functions, and, if they do, make sure the + instruction is valid. */ + invalid = 0; + for (opindex = opcode->operands; *opindex != 0; opindex++) + { + operand = powerpc_operands + *opindex; + if (operand->extract) + (*operand->extract) (insn, dialect, &invalid); + } + if (invalid) + continue; + + /* The instruction is valid. */ + oinsn->opcode = opcode; + + /* Now extract and print the operands. */ + need_comma = 0; + need_paren = 0; + skip_optional = -1; + i_op = 0; + for (opindex = opcode->operands; *opindex != 0; opindex++, i_op++) + { + long value; + + operand = powerpc_operands + *opindex; + + /* Operands that are marked FAKE are simply ignored. We + already made sure that the extract function considered + the instruction to be valid. */ + if ((operand->flags & PPC_OPERAND_FAKE) != 0) + continue; + + /* If all of the optional operands have the value zero, + then don't print any of them. */ + if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0) + { + if (skip_optional < 0) + skip_optional = skip_optional_operands(opindex, insn, + dialect); + if (skip_optional) + continue; + } + + value = operand_value_powerpc(operand, insn, dialect); + oinsn->operands[i_op] = value; + + if (operand->flags & PPC_OPERAND_RELATIVE) + { + oinsn->operands[i_op] += memaddr; + } + else if (operand->flags & PPC_OPERAND_ABSOLUTE) + { + oinsn->operands[i_op] &= 0xffffffff; + } + + if (need_comma) + { + stream = stream + sprintf(stream, ","); + need_comma = 0; + } + + /* Print the operand as directed by the flags. */ + if ((operand->flags & PPC_OPERAND_GPR) != 0 + || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0)) + stream = stream + sprintf(stream, "r%ld", value); + else if ((operand->flags & PPC_OPERAND_FPR) != 0) + stream = stream + sprintf(stream, "f%ld", value); + else if ((operand->flags & PPC_OPERAND_VR) != 0) + stream = stream + sprintf(stream, "v%ld", value); + else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0) + stream = stream + sprintf(stream, "0x%llx", memaddr + value); + else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0) + stream = stream + sprintf(stream, "0x%llx", (bfd_vma)value & 0xffffffff); + else if ((operand->flags & PPC_OPERAND_CR) == 0 + || (dialect & PPC_OPCODE_PPC) == 0) + stream = stream + sprintf(stream, "%ld", value); + else + { + if (operand->bitm == 7) + stream = stream + sprintf(stream, "cr%ld", value); + else + { + static const char* cbnames[4] = { "lt", "gt", "eq", "so" }; + int cr; + int cc; + + cr = value >> 2; + if (cr != 0) + stream = stream + sprintf(stream, "4*cr%d+", cr); + cc = value & 3; + stream = stream + sprintf(stream, "%s", cbnames[cc]); + } + } + + if (need_paren) + { + stream = stream + sprintf(stream, ")"); + need_paren = 0; + } + + if ((operand->flags & PPC_OPERAND_PARENS) == 0) + need_comma = 1; + else + { + stream = stream + sprintf(stream, "("); + need_paren = 1; + } + } + + /* We have found and printed an instruction; return. */ + return 4; + } + + if ((dialect & PPC_OPCODE_ANY) != 0) + { + dialect = ~PPC_OPCODE_ANY; + goto again; + } + + /* We could not find a match. */ + stream = stream + sprintf(stream, ".long 0x%lx", insn); + oinsn->opcode = 0; + + return 4; +} diff --git a/thirdparty/disasm/ppc-inst.h b/thirdparty/disasm/ppc-inst.h new file mode 100644 index 0000000..89df9ee --- /dev/null +++ b/thirdparty/disasm/ppc-inst.h @@ -0,0 +1,1848 @@ +#pragma once + +#define PPC_INST_ATTN 1 +#define PPC_INST_TDLGTI 2 +#define PPC_INST_TDLLTI 3 +#define PPC_INST_TDEQI 4 +#define PPC_INST_TDLGEI 5 +#define PPC_INST_TDLNLI 6 +#define PPC_INST_TDLLEI 7 +#define PPC_INST_TDLNGI 8 +#define PPC_INST_TDGTI 9 +#define PPC_INST_TDGEI 10 +#define PPC_INST_TDNLI 11 +#define PPC_INST_TDLTI 12 +#define PPC_INST_TDLEI 13 +#define PPC_INST_TDNGI 14 +#define PPC_INST_TDNEI 15 +#define PPC_INST_TDI 16 +#define PPC_INST_TWLGTI 17 +#define PPC_INST_TLGTI 18 +#define PPC_INST_TWLLTI 19 +#define PPC_INST_TLLTI 20 +#define PPC_INST_TWEQI 21 +#define PPC_INST_TEQI 22 +#define PPC_INST_TWLGEI 23 +#define PPC_INST_TLGEI 24 +#define PPC_INST_TWLNLI 25 +#define PPC_INST_TLNLI 26 +#define PPC_INST_TWLLEI 27 +#define PPC_INST_TLLEI 28 +#define PPC_INST_TWLNGI 29 +#define PPC_INST_TLNGI 30 +#define PPC_INST_TWGTI 31 +#define PPC_INST_TGTI 32 +#define PPC_INST_TWGEI 33 +#define PPC_INST_TGEI 34 +#define PPC_INST_TWNLI 35 +#define PPC_INST_TNLI 36 +#define PPC_INST_TWLTI 37 +#define PPC_INST_TLTI 38 +#define PPC_INST_TWLEI 39 +#define PPC_INST_TLEI 40 +#define PPC_INST_TWNGI 41 +#define PPC_INST_TNGI 42 +#define PPC_INST_TWNEI 43 +#define PPC_INST_TNEI 44 +#define PPC_INST_TWI 45 +#define PPC_INST_TI 46 +#define PPC_INST_MACCHW 47 +#define PPC_INST_MACCHWO 48 +#define PPC_INST_MACCHWS 49 +#define PPC_INST_MACCHWSO 50 +#define PPC_INST_MACCHWSU 51 +#define PPC_INST_MACCHWSUO 52 +#define PPC_INST_MACCHWU 53 +#define PPC_INST_MACCHWUO 54 +#define PPC_INST_MACHHW 55 +#define PPC_INST_MACHHWO 56 +#define PPC_INST_MACHHWS 57 +#define PPC_INST_MACHHWSO 58 +#define PPC_INST_MACHHWSU 59 +#define PPC_INST_MACHHWSUO 60 +#define PPC_INST_MACHHWU 61 +#define PPC_INST_MACHHWUO 62 +#define PPC_INST_MACLHW 63 +#define PPC_INST_MACLHWO 64 +#define PPC_INST_MACLHWS 65 +#define PPC_INST_MACLHWSO 66 +#define PPC_INST_MACLHWSU 67 +#define PPC_INST_MACLHWSUO 68 +#define PPC_INST_MACLHWU 69 +#define PPC_INST_MACLHWUO 70 +#define PPC_INST_MULCHW 71 +#define PPC_INST_MULCHWU 72 +#define PPC_INST_MULHHW 73 +#define PPC_INST_MULHHWU 74 +#define PPC_INST_MULLHW 75 +#define PPC_INST_MULLHWU 76 +#define PPC_INST_NMACCHW 77 +#define PPC_INST_NMACCHWO 78 +#define PPC_INST_NMACCHWS 79 +#define PPC_INST_NMACCHWSO 80 +#define PPC_INST_NMACHHW 81 +#define PPC_INST_NMACHHWO 82 +#define PPC_INST_NMACHHWS 83 +#define PPC_INST_NMACHHWSO 84 +#define PPC_INST_NMACLHW 85 +#define PPC_INST_NMACLHWO 86 +#define PPC_INST_NMACLHWS 87 +#define PPC_INST_NMACLHWSO 88 +#define PPC_INST_MFVSCR 89 +#define PPC_INST_MTVSCR 90 +#define PPC_INST_EFSCFD 91 +#define PPC_INST_EFDABS 92 +#define PPC_INST_EFDNABS 93 +#define PPC_INST_EFDNEG 94 +#define PPC_INST_EFDADD 95 +#define PPC_INST_EFDSUB 96 +#define PPC_INST_EFDMUL 97 +#define PPC_INST_EFDDIV 98 +#define PPC_INST_EFDCMPGT 99 +#define PPC_INST_EFDCMPLT 100 +#define PPC_INST_EFDCMPEQ 101 +#define PPC_INST_EFDTSTGT 102 +#define PPC_INST_EFDTSTLT 103 +#define PPC_INST_EFDTSTEQ 104 +#define PPC_INST_EFDCFSI 105 +#define PPC_INST_EFDCFSID 106 +#define PPC_INST_EFDCFUI 107 +#define PPC_INST_EFDCFUID 108 +#define PPC_INST_EFDCFSF 109 +#define PPC_INST_EFDCFUF 110 +#define PPC_INST_EFDCTSI 111 +#define PPC_INST_EFDCTSIDZ 112 +#define PPC_INST_EFDCTSIZ 113 +#define PPC_INST_EFDCTUI 114 +#define PPC_INST_EFDCTUIDZ 115 +#define PPC_INST_EFDCTUIZ 116 +#define PPC_INST_EFDCTSF 117 +#define PPC_INST_EFDCTUF 118 +#define PPC_INST_EFDCFS 119 +#define PPC_INST_VADDCUW 120 +#define PPC_INST_VADDFP 121 +#define PPC_INST_VADDSBS 122 +#define PPC_INST_VADDSHS 123 +#define PPC_INST_VADDSWS 124 +#define PPC_INST_VADDUBM 125 +#define PPC_INST_VADDUBS 126 +#define PPC_INST_VADDUHM 127 +#define PPC_INST_VADDUHS 128 +#define PPC_INST_VADDUWM 129 +#define PPC_INST_VADDUWS 130 +#define PPC_INST_VAND 131 +#define PPC_INST_VANDC 132 +#define PPC_INST_VAVGSB 133 +#define PPC_INST_VAVGSH 134 +#define PPC_INST_VAVGSW 135 +#define PPC_INST_VAVGUB 136 +#define PPC_INST_VAVGUH 137 +#define PPC_INST_VAVGUW 138 +#define PPC_INST_VCFSX 139 +#define PPC_INST_VCFUX 140 +#define PPC_INST_VCMPBFP 141 +#define PPC_INST_VCMPEQFP 142 +#define PPC_INST_VCMPEQUB 143 +#define PPC_INST_VCMPEQUH 144 +#define PPC_INST_VCMPEQUW 145 +#define PPC_INST_VCMPGEFP 146 +#define PPC_INST_VCMPGTFP 147 +#define PPC_INST_VCMPGTSB 148 +#define PPC_INST_VCMPGTSH 149 +#define PPC_INST_VCMPGTSW 150 +#define PPC_INST_VCMPGTUB 151 +#define PPC_INST_VCMPGTUH 152 +#define PPC_INST_VCMPGTUW 153 +#define PPC_INST_VCTSXS 154 +#define PPC_INST_VCTUXS 155 +#define PPC_INST_VEXPTEFP 156 +#define PPC_INST_VLOGEFP 157 +#define PPC_INST_VMADDFP 158 +#define PPC_INST_VMAXFP 159 +#define PPC_INST_VMAXSB 160 +#define PPC_INST_VMAXSH 161 +#define PPC_INST_VMAXSW 162 +#define PPC_INST_VMAXUB 163 +#define PPC_INST_VMAXUH 164 +#define PPC_INST_VMAXUW 165 +#define PPC_INST_VMHADDSHS 166 +#define PPC_INST_VMHRADDSHS 167 +#define PPC_INST_VMINFP 168 +#define PPC_INST_VMINSB 169 +#define PPC_INST_VMINSH 170 +#define PPC_INST_VMINSW 171 +#define PPC_INST_VMINUB 172 +#define PPC_INST_VMINUH 173 +#define PPC_INST_VMINUW 174 +#define PPC_INST_VMLADDUHM 175 +#define PPC_INST_VMRGHB 176 +#define PPC_INST_VMRGHH 177 +#define PPC_INST_VMRGHW 178 +#define PPC_INST_VMRGLB 179 +#define PPC_INST_VMRGLH 180 +#define PPC_INST_VMRGLW 181 +#define PPC_INST_VMSUMMBM 182 +#define PPC_INST_VMSUMSHM 183 +#define PPC_INST_VMSUMSHS 184 +#define PPC_INST_VMSUMUBM 185 +#define PPC_INST_VMSUMUHM 186 +#define PPC_INST_VMSUMUHS 187 +#define PPC_INST_VMULESB 188 +#define PPC_INST_VMULESH 189 +#define PPC_INST_VMULEUB 190 +#define PPC_INST_VMULEUH 191 +#define PPC_INST_VMULOSB 192 +#define PPC_INST_VMULOSH 193 +#define PPC_INST_VMULOUB 194 +#define PPC_INST_VMULOUH 195 +#define PPC_INST_VNMSUBFP 196 +#define PPC_INST_VNOR 197 +#define PPC_INST_VOR 198 +#define PPC_INST_VPERM 199 +#define PPC_INST_VPKPX 200 +#define PPC_INST_VPKSHSS 201 +#define PPC_INST_VPKSHUS 202 +#define PPC_INST_VPKSWSS 203 +#define PPC_INST_VPKSWUS 204 +#define PPC_INST_VPKUHUM 205 +#define PPC_INST_VPKUHUS 206 +#define PPC_INST_VPKUWUM 207 +#define PPC_INST_VPKUWUS 208 +#define PPC_INST_VREFP 209 +#define PPC_INST_VRFIM 210 +#define PPC_INST_VRFIN 211 +#define PPC_INST_VRFIP 212 +#define PPC_INST_VRFIZ 213 +#define PPC_INST_VRLB 214 +#define PPC_INST_VRLH 215 +#define PPC_INST_VRLW 216 +#define PPC_INST_VRSQRTEFP 217 +#define PPC_INST_VSEL 218 +#define PPC_INST_VSL 219 +#define PPC_INST_VSLB 220 +#define PPC_INST_VSLDOI 221 +#define PPC_INST_VSLH 222 +#define PPC_INST_VSLO 223 +#define PPC_INST_VSLW 224 +#define PPC_INST_VSPLTB 225 +#define PPC_INST_VSPLTH 226 +#define PPC_INST_VSPLTISB 227 +#define PPC_INST_VSPLTISH 228 +#define PPC_INST_VSPLTISW 229 +#define PPC_INST_VSPLTW 230 +#define PPC_INST_VSR 231 +#define PPC_INST_VSRAB 232 +#define PPC_INST_VSRAH 233 +#define PPC_INST_VSRAW 234 +#define PPC_INST_VSRB 235 +#define PPC_INST_VSRH 236 +#define PPC_INST_VSRO 237 +#define PPC_INST_VSRW 238 +#define PPC_INST_VSUBCUW 239 +#define PPC_INST_VSUBFP 240 +#define PPC_INST_VSUBSBS 241 +#define PPC_INST_VSUBSHS 242 +#define PPC_INST_VSUBSWS 243 +#define PPC_INST_VSUBUBM 244 +#define PPC_INST_VSUBUBS 245 +#define PPC_INST_VSUBUHM 246 +#define PPC_INST_VSUBUHS 247 +#define PPC_INST_VSUBUWM 248 +#define PPC_INST_VSUBUWS 249 +#define PPC_INST_VSUMSWS 250 +#define PPC_INST_VSUM2SWS 251 +#define PPC_INST_VSUM4SBS 252 +#define PPC_INST_VSUM4SHS 253 +#define PPC_INST_VSUM4UBS 254 +#define PPC_INST_VUPKHPX 255 +#define PPC_INST_VUPKHSB 256 +#define PPC_INST_VUPKHSH 257 +#define PPC_INST_VUPKLPX 258 +#define PPC_INST_VUPKLSB 259 +#define PPC_INST_VUPKLSH 260 +#define PPC_INST_VXOR 261 +#define PPC_INST_VSLDOI128 262 +#define PPC_INST_LVSL128 263 +#define PPC_INST_LVSR128 264 +#define PPC_INST_LVEWX128 265 +#define PPC_INST_LVX128 266 +#define PPC_INST_STVEWX128 267 +#define PPC_INST_STVX128 268 +#define PPC_INST_LVXL128 269 +#define PPC_INST_STVXL128 270 +#define PPC_INST_LVLX128 271 +#define PPC_INST_LVRX128 272 +#define PPC_INST_STVLX128 273 +#define PPC_INST_STVRX128 274 +#define PPC_INST_LVLXL128 275 +#define PPC_INST_LVRXL128 276 +#define PPC_INST_STVLXL128 277 +#define PPC_INST_STVRXL128 278 +#define PPC_INST_VPERM128 279 +#define PPC_INST_VADDFP128 280 +#define PPC_INST_VSUBFP128 281 +#define PPC_INST_VMULFP128 282 +#define PPC_INST_VMADDFP128 283 +#define PPC_INST_VMADDCFP128 284 +#define PPC_INST_VNMSUBFP128 285 +#define PPC_INST_VMSUM3FP128 286 +#define PPC_INST_VMSUM4FP128 287 +#define PPC_INST_VPKSHSS128 288 +#define PPC_INST_VAND128 289 +#define PPC_INST_VPKSHUS128 290 +#define PPC_INST_VANDC128 291 +#define PPC_INST_VPKSWSS128 292 +#define PPC_INST_VNOR128 293 +#define PPC_INST_VPKSWUS128 294 +#define PPC_INST_VOR128 295 +#define PPC_INST_VPKUHUM128 296 +#define PPC_INST_VXOR128 297 +#define PPC_INST_VPKUHUS128 298 +#define PPC_INST_VSEL128 299 +#define PPC_INST_VPKUWUM128 300 +#define PPC_INST_VSLO128 301 +#define PPC_INST_VPKUWUS128 302 +#define PPC_INST_VSRO128 303 +#define PPC_INST_VPERMWI128 304 +#define PPC_INST_VCFPSXWS128 305 +#define PPC_INST_VCFPUXWS128 306 +#define PPC_INST_VCSXWFP128 307 +#define PPC_INST_VCUXWFP128 308 +#define PPC_INST_VRFIM128 309 +#define PPC_INST_VRFIN128 310 +#define PPC_INST_VRFIP128 311 +#define PPC_INST_VRFIZ128 312 +#define PPC_INST_VPKD3D128 313 +#define PPC_INST_VREFP128 314 +#define PPC_INST_VRSQRTEFP128 315 +#define PPC_INST_VEXPTEFP128 316 +#define PPC_INST_VLOGEFP128 317 +#define PPC_INST_VRLIMI128 318 +#define PPC_INST_VSPLTW128 319 +#define PPC_INST_VSPLTISW128 320 +#define PPC_INST_VUPKD3D128 321 +#define PPC_INST_VCMPEQFP128 322 +#define PPC_INST_VRLW128 323 +#define PPC_INST_VCMPGEFP128 324 +#define PPC_INST_VSLW128 325 +#define PPC_INST_VCMPGTFP128 326 +#define PPC_INST_VSRAW128 327 +#define PPC_INST_VCMPBFP128 328 +#define PPC_INST_VSRW128 329 +#define PPC_INST_VCMPEQUW128 330 +#define PPC_INST_VMAXFP128 331 +#define PPC_INST_VMINFP128 332 +#define PPC_INST_VMRGHW128 333 +#define PPC_INST_VMRGLW128 334 +#define PPC_INST_VUPKHSB128 335 +#define PPC_INST_VUPKLSB128 336 +#define PPC_INST_EVADDW 337 +#define PPC_INST_EVADDIW 338 +#define PPC_INST_EVSUBFW 339 +#define PPC_INST_EVSUBW 340 +#define PPC_INST_EVSUBIFW 341 +#define PPC_INST_EVSUBIW 342 +#define PPC_INST_EVABS 343 +#define PPC_INST_EVNEG 344 +#define PPC_INST_EVEXTSB 345 +#define PPC_INST_EVEXTSH 346 +#define PPC_INST_EVRNDW 347 +#define PPC_INST_EVCNTLZW 348 +#define PPC_INST_EVCNTLSW 349 +#define PPC_INST_BRINC 350 +#define PPC_INST_EVAND 351 +#define PPC_INST_EVANDC 352 +#define PPC_INST_EVMR 353 +#define PPC_INST_EVOR 354 +#define PPC_INST_EVORC 355 +#define PPC_INST_EVXOR 356 +#define PPC_INST_EVEQV 357 +#define PPC_INST_EVNAND 358 +#define PPC_INST_EVNOT 359 +#define PPC_INST_EVNOR 360 +#define PPC_INST_EVRLW 361 +#define PPC_INST_EVRLWI 362 +#define PPC_INST_EVSLW 363 +#define PPC_INST_EVSLWI 364 +#define PPC_INST_EVSRWS 365 +#define PPC_INST_EVSRWU 366 +#define PPC_INST_EVSRWIS 367 +#define PPC_INST_EVSRWIU 368 +#define PPC_INST_EVSPLATI 369 +#define PPC_INST_EVSPLATFI 370 +#define PPC_INST_EVMERGEHI 371 +#define PPC_INST_EVMERGELO 372 +#define PPC_INST_EVMERGEHILO 373 +#define PPC_INST_EVMERGELOHI 374 +#define PPC_INST_EVCMPGTS 375 +#define PPC_INST_EVCMPGTU 376 +#define PPC_INST_EVCMPLTS 377 +#define PPC_INST_EVCMPLTU 378 +#define PPC_INST_EVCMPEQ 379 +#define PPC_INST_EVSEL 380 +#define PPC_INST_EVLDD 381 +#define PPC_INST_EVLDDX 382 +#define PPC_INST_EVLDW 383 +#define PPC_INST_EVLDWX 384 +#define PPC_INST_EVLDH 385 +#define PPC_INST_EVLDHX 386 +#define PPC_INST_EVLWHE 387 +#define PPC_INST_EVLWHEX 388 +#define PPC_INST_EVLWHOU 389 +#define PPC_INST_EVLWHOUX 390 +#define PPC_INST_EVLWHOS 391 +#define PPC_INST_EVLWHOSX 392 +#define PPC_INST_EVLWWSPLAT 393 +#define PPC_INST_EVLWWSPLATX 394 +#define PPC_INST_EVLWHSPLAT 395 +#define PPC_INST_EVLWHSPLATX 396 +#define PPC_INST_EVLHHESPLAT 397 +#define PPC_INST_EVLHHESPLATX 398 +#define PPC_INST_EVLHHOUSPLAT 399 +#define PPC_INST_EVLHHOUSPLATX 400 +#define PPC_INST_EVLHHOSSPLAT 401 +#define PPC_INST_EVLHHOSSPLATX 402 +#define PPC_INST_EVSTDD 403 +#define PPC_INST_EVSTDDX 404 +#define PPC_INST_EVSTDW 405 +#define PPC_INST_EVSTDWX 406 +#define PPC_INST_EVSTDH 407 +#define PPC_INST_EVSTDHX 408 +#define PPC_INST_EVSTWWE 409 +#define PPC_INST_EVSTWWEX 410 +#define PPC_INST_EVSTWWO 411 +#define PPC_INST_EVSTWWOX 412 +#define PPC_INST_EVSTWHE 413 +#define PPC_INST_EVSTWHEX 414 +#define PPC_INST_EVSTWHO 415 +#define PPC_INST_EVSTWHOX 416 +#define PPC_INST_EVFSABS 417 +#define PPC_INST_EVFSNABS 418 +#define PPC_INST_EVFSNEG 419 +#define PPC_INST_EVFSADD 420 +#define PPC_INST_EVFSSUB 421 +#define PPC_INST_EVFSMUL 422 +#define PPC_INST_EVFSDIV 423 +#define PPC_INST_EVFSCMPGT 424 +#define PPC_INST_EVFSCMPLT 425 +#define PPC_INST_EVFSCMPEQ 426 +#define PPC_INST_EVFSTSTGT 427 +#define PPC_INST_EVFSTSTLT 428 +#define PPC_INST_EVFSTSTEQ 429 +#define PPC_INST_EVFSCFUI 430 +#define PPC_INST_EVFSCTUIZ 431 +#define PPC_INST_EVFSCFSI 432 +#define PPC_INST_EVFSCFUF 433 +#define PPC_INST_EVFSCFSF 434 +#define PPC_INST_EVFSCTUI 435 +#define PPC_INST_EVFSCTSI 436 +#define PPC_INST_EVFSCTSIZ 437 +#define PPC_INST_EVFSCTUF 438 +#define PPC_INST_EVFSCTSF 439 +#define PPC_INST_EFSABS 440 +#define PPC_INST_EFSNABS 441 +#define PPC_INST_EFSNEG 442 +#define PPC_INST_EFSADD 443 +#define PPC_INST_EFSSUB 444 +#define PPC_INST_EFSMUL 445 +#define PPC_INST_EFSDIV 446 +#define PPC_INST_EFSCMPGT 447 +#define PPC_INST_EFSCMPLT 448 +#define PPC_INST_EFSCMPEQ 449 +#define PPC_INST_EFSTSTGT 450 +#define PPC_INST_EFSTSTLT 451 +#define PPC_INST_EFSTSTEQ 452 +#define PPC_INST_EFSCFUI 453 +#define PPC_INST_EFSCTUIZ 454 +#define PPC_INST_EFSCFSI 455 +#define PPC_INST_EFSCFUF 456 +#define PPC_INST_EFSCFSF 457 +#define PPC_INST_EFSCTUI 458 +#define PPC_INST_EFSCTSI 459 +#define PPC_INST_EFSCTSIZ 460 +#define PPC_INST_EFSCTUF 461 +#define PPC_INST_EFSCTSF 462 +#define PPC_INST_EVMHOSSF 463 +#define PPC_INST_EVMHOSSFA 464 +#define PPC_INST_EVMHOSMF 465 +#define PPC_INST_EVMHOSMFA 466 +#define PPC_INST_EVMHOSMI 467 +#define PPC_INST_EVMHOSMIA 468 +#define PPC_INST_EVMHOUMI 469 +#define PPC_INST_EVMHOUMIA 470 +#define PPC_INST_EVMHESSF 471 +#define PPC_INST_EVMHESSFA 472 +#define PPC_INST_EVMHESMF 473 +#define PPC_INST_EVMHESMFA 474 +#define PPC_INST_EVMHESMI 475 +#define PPC_INST_EVMHESMIA 476 +#define PPC_INST_EVMHEUMI 477 +#define PPC_INST_EVMHEUMIA 478 +#define PPC_INST_EVMHOSSFAAW 479 +#define PPC_INST_EVMHOSSIAAW 480 +#define PPC_INST_EVMHOSMFAAW 481 +#define PPC_INST_EVMHOSMIAAW 482 +#define PPC_INST_EVMHOUSIAAW 483 +#define PPC_INST_EVMHOUMIAAW 484 +#define PPC_INST_EVMHESSFAAW 485 +#define PPC_INST_EVMHESSIAAW 486 +#define PPC_INST_EVMHESMFAAW 487 +#define PPC_INST_EVMHESMIAAW 488 +#define PPC_INST_EVMHEUSIAAW 489 +#define PPC_INST_EVMHEUMIAAW 490 +#define PPC_INST_EVMHOSSFANW 491 +#define PPC_INST_EVMHOSSIANW 492 +#define PPC_INST_EVMHOSMFANW 493 +#define PPC_INST_EVMHOSMIANW 494 +#define PPC_INST_EVMHOUSIANW 495 +#define PPC_INST_EVMHOUMIANW 496 +#define PPC_INST_EVMHESSFANW 497 +#define PPC_INST_EVMHESSIANW 498 +#define PPC_INST_EVMHESMFANW 499 +#define PPC_INST_EVMHESMIANW 500 +#define PPC_INST_EVMHEUSIANW 501 +#define PPC_INST_EVMHEUMIANW 502 +#define PPC_INST_EVMHOGSMFAA 503 +#define PPC_INST_EVMHOGSMIAA 504 +#define PPC_INST_EVMHOGUMIAA 505 +#define PPC_INST_EVMHEGSMFAA 506 +#define PPC_INST_EVMHEGSMIAA 507 +#define PPC_INST_EVMHEGUMIAA 508 +#define PPC_INST_EVMHOGSMFAN 509 +#define PPC_INST_EVMHOGSMIAN 510 +#define PPC_INST_EVMHOGUMIAN 511 +#define PPC_INST_EVMHEGSMFAN 512 +#define PPC_INST_EVMHEGSMIAN 513 +#define PPC_INST_EVMHEGUMIAN 514 +#define PPC_INST_EVMWHSSF 515 +#define PPC_INST_EVMWHSSFA 516 +#define PPC_INST_EVMWHSMF 517 +#define PPC_INST_EVMWHSMFA 518 +#define PPC_INST_EVMWHSMI 519 +#define PPC_INST_EVMWHSMIA 520 +#define PPC_INST_EVMWHUMI 521 +#define PPC_INST_EVMWHUMIA 522 +#define PPC_INST_EVMWLUMI 523 +#define PPC_INST_EVMWLUMIA 524 +#define PPC_INST_EVMWLSSIAAW 525 +#define PPC_INST_EVMWLSMIAAW 526 +#define PPC_INST_EVMWLUSIAAW 527 +#define PPC_INST_EVMWLUMIAAW 528 +#define PPC_INST_EVMWLSSIANW 529 +#define PPC_INST_EVMWLSMIANW 530 +#define PPC_INST_EVMWLUSIANW 531 +#define PPC_INST_EVMWLUMIANW 532 +#define PPC_INST_EVMWSSF 533 +#define PPC_INST_EVMWSSFA 534 +#define PPC_INST_EVMWSMF 535 +#define PPC_INST_EVMWSMFA 536 +#define PPC_INST_EVMWSMI 537 +#define PPC_INST_EVMWSMIA 538 +#define PPC_INST_EVMWUMI 539 +#define PPC_INST_EVMWUMIA 540 +#define PPC_INST_EVMWSSFAA 541 +#define PPC_INST_EVMWSMFAA 542 +#define PPC_INST_EVMWSMIAA 543 +#define PPC_INST_EVMWUMIAA 544 +#define PPC_INST_EVMWSSFAN 545 +#define PPC_INST_EVMWSMFAN 546 +#define PPC_INST_EVMWSMIAN 547 +#define PPC_INST_EVMWUMIAN 548 +#define PPC_INST_EVADDSSIAAW 549 +#define PPC_INST_EVADDSMIAAW 550 +#define PPC_INST_EVADDUSIAAW 551 +#define PPC_INST_EVADDUMIAAW 552 +#define PPC_INST_EVSUBFSSIAAW 553 +#define PPC_INST_EVSUBFSMIAAW 554 +#define PPC_INST_EVSUBFUSIAAW 555 +#define PPC_INST_EVSUBFUMIAAW 556 +#define PPC_INST_EVMRA 557 +#define PPC_INST_EVDIVWS 558 +#define PPC_INST_EVDIVWU 559 +#define PPC_INST_MULLI 560 +#define PPC_INST_MULI 561 +#define PPC_INST_SUBFIC 562 +#define PPC_INST_SFI 563 +#define PPC_INST_DOZI 564 +#define PPC_INST_BCE 565 +#define PPC_INST_BCEL 566 +#define PPC_INST_BCEA 567 +#define PPC_INST_BCELA 568 +#define PPC_INST_CMPLWI 569 +#define PPC_INST_CMPLDI 570 +#define PPC_INST_CMPLI 571 +#define PPC_INST_CMPWI 572 +#define PPC_INST_CMPDI 573 +#define PPC_INST_CMPI 574 +#define PPC_INST_ADDIC 575 +#define PPC_INST_AI 576 +#define PPC_INST_SUBIC 577 +#define PPC_INST_LI 578 +#define PPC_INST_LIL 579 +#define PPC_INST_ADDI 580 +#define PPC_INST_CAL 581 +#define PPC_INST_SUBI 582 +#define PPC_INST_LA 583 +#define PPC_INST_LIS 584 +#define PPC_INST_LIU 585 +#define PPC_INST_ADDIS 586 +#define PPC_INST_CAU 587 +#define PPC_INST_SUBIS 588 +#define PPC_INST_BDNZ 589 +#define PPC_INST_BDN 590 +#define PPC_INST_BDNZL 591 +#define PPC_INST_BDNL 592 +#define PPC_INST_BDNZA 593 +#define PPC_INST_BDNA 594 +#define PPC_INST_BDNZLA 595 +#define PPC_INST_BDNLA 596 +#define PPC_INST_BDZ 597 +#define PPC_INST_BDZL 598 +#define PPC_INST_BDZA 599 +#define PPC_INST_BDZLA 600 +#define PPC_INST_BLT 601 +#define PPC_INST_BLTL 602 +#define PPC_INST_BLTA 603 +#define PPC_INST_BLTLA 604 +#define PPC_INST_BGT 605 +#define PPC_INST_BGTL 606 +#define PPC_INST_BGTA 607 +#define PPC_INST_BGTLA 608 +#define PPC_INST_BEQ 609 +#define PPC_INST_BEQL 610 +#define PPC_INST_BEQA 611 +#define PPC_INST_BEQLA 612 +#define PPC_INST_BSO 613 +#define PPC_INST_BSOL 614 +#define PPC_INST_BSOA 615 +#define PPC_INST_BSOLA 616 +#define PPC_INST_BUN 617 +#define PPC_INST_BUNL 618 +#define PPC_INST_BUNA 619 +#define PPC_INST_BUNLA 620 +#define PPC_INST_BGE 621 +#define PPC_INST_BGEL 622 +#define PPC_INST_BGEA 623 +#define PPC_INST_BGELA 624 +#define PPC_INST_BNL 625 +#define PPC_INST_BNLL 626 +#define PPC_INST_BNLA 627 +#define PPC_INST_BNLLA 628 +#define PPC_INST_BLE 629 +#define PPC_INST_BLEL 630 +#define PPC_INST_BLEA 631 +#define PPC_INST_BLELA 632 +#define PPC_INST_BNG 633 +#define PPC_INST_BNGL 634 +#define PPC_INST_BNGA 635 +#define PPC_INST_BNGLA 636 +#define PPC_INST_BNE 637 +#define PPC_INST_BNEL 638 +#define PPC_INST_BNEA 639 +#define PPC_INST_BNELA 640 +#define PPC_INST_BNS 641 +#define PPC_INST_BNSL 642 +#define PPC_INST_BNSA 643 +#define PPC_INST_BNSLA 644 +#define PPC_INST_BNU 645 +#define PPC_INST_BNUL 646 +#define PPC_INST_BNUA 647 +#define PPC_INST_BNULA 648 +#define PPC_INST_BDNZT 649 +#define PPC_INST_BDNZTL 650 +#define PPC_INST_BDNZTA 651 +#define PPC_INST_BDNZTLA 652 +#define PPC_INST_BDNZF 653 +#define PPC_INST_BDNZFL 654 +#define PPC_INST_BDNZFA 655 +#define PPC_INST_BDNZFLA 656 +#define PPC_INST_BT 657 +#define PPC_INST_BBT 658 +#define PPC_INST_BTL 659 +#define PPC_INST_BBTL 660 +#define PPC_INST_BTA 661 +#define PPC_INST_BBTA 662 +#define PPC_INST_BTLA 663 +#define PPC_INST_BBTLA 664 +#define PPC_INST_BF 665 +#define PPC_INST_BBF 666 +#define PPC_INST_BFL 667 +#define PPC_INST_BBFL 668 +#define PPC_INST_BFA 669 +#define PPC_INST_BBFA 670 +#define PPC_INST_BFLA 671 +#define PPC_INST_BBFLA 672 +#define PPC_INST_BDZT 673 +#define PPC_INST_BDZTL 674 +#define PPC_INST_BDZTA 675 +#define PPC_INST_BDZTLA 676 +#define PPC_INST_BDZF 677 +#define PPC_INST_BDZFL 678 +#define PPC_INST_BDZFA 679 +#define PPC_INST_BDZFLA 680 +#define PPC_INST_BC 681 +#define PPC_INST_BCL 682 +#define PPC_INST_BCA 683 +#define PPC_INST_BCLA 684 +#define PPC_INST_SC 685 +#define PPC_INST_SVC 686 +#define PPC_INST_SVCL 687 +#define PPC_INST_SVCA 688 +#define PPC_INST_SVCLA 689 +#define PPC_INST_B 690 +#define PPC_INST_BL 691 +#define PPC_INST_BA 692 +#define PPC_INST_BLA 693 +#define PPC_INST_MCRF 694 +#define PPC_INST_BLR 695 +#define PPC_INST_BR 696 +#define PPC_INST_BLRL 697 +#define PPC_INST_BRL 698 +#define PPC_INST_BDNZLR 699 +#define PPC_INST_BDNZLRL 700 +#define PPC_INST_BDZLR 701 +#define PPC_INST_BDZLRL 702 +#define PPC_INST_BLTLR 703 +#define PPC_INST_BLTR 704 +#define PPC_INST_BLTLRL 705 +#define PPC_INST_BLTRL 706 +#define PPC_INST_BGTLR 707 +#define PPC_INST_BGTR 708 +#define PPC_INST_BGTLRL 709 +#define PPC_INST_BGTRL 710 +#define PPC_INST_BEQLR 711 +#define PPC_INST_BEQR 712 +#define PPC_INST_BEQLRL 713 +#define PPC_INST_BEQRL 714 +#define PPC_INST_BSOLR 715 +#define PPC_INST_BSOR 716 +#define PPC_INST_BSOLRL 717 +#define PPC_INST_BSORL 718 +#define PPC_INST_BUNLR 719 +#define PPC_INST_BUNLRL 720 +#define PPC_INST_BGELR 721 +#define PPC_INST_BGER 722 +#define PPC_INST_BGELRL 723 +#define PPC_INST_BGERL 724 +#define PPC_INST_BNLLR 725 +#define PPC_INST_BNLR 726 +#define PPC_INST_BNLLRL 727 +#define PPC_INST_BNLRL 728 +#define PPC_INST_BLELR 729 +#define PPC_INST_BLER 730 +#define PPC_INST_BLELRL 731 +#define PPC_INST_BLERL 732 +#define PPC_INST_BNGLR 733 +#define PPC_INST_BNGR 734 +#define PPC_INST_BNGLRL 735 +#define PPC_INST_BNGRL 736 +#define PPC_INST_BNELR 737 +#define PPC_INST_BNER 738 +#define PPC_INST_BNELRL 739 +#define PPC_INST_BNERL 740 +#define PPC_INST_BNSLR 741 +#define PPC_INST_BNSR 742 +#define PPC_INST_BNSLRL 743 +#define PPC_INST_BNSRL 744 +#define PPC_INST_BNULR 745 +#define PPC_INST_BNULRL 746 +#define PPC_INST_BTLR 747 +#define PPC_INST_BBTR 748 +#define PPC_INST_BTLRL 749 +#define PPC_INST_BBTRL 750 +#define PPC_INST_BFLR 751 +#define PPC_INST_BBFR 752 +#define PPC_INST_BFLRL 753 +#define PPC_INST_BBFRL 754 +#define PPC_INST_BDNZTLR 755 +#define PPC_INST_BDNZTLRL 756 +#define PPC_INST_BDNZFLR 757 +#define PPC_INST_BDNZFLRL 758 +#define PPC_INST_BDZTLR 759 +#define PPC_INST_BDZTLRL 760 +#define PPC_INST_BDZFLR 761 +#define PPC_INST_BDZFLRL 762 +#define PPC_INST_BCLR 763 +#define PPC_INST_BCLRL 764 +#define PPC_INST_BCR 765 +#define PPC_INST_BCRL 766 +#define PPC_INST_BCLRE 767 +#define PPC_INST_BCLREL 768 +#define PPC_INST_RFID 769 +#define PPC_INST_CRNOT 770 +#define PPC_INST_CRNOR 771 +#define PPC_INST_RFMCI 772 +#define PPC_INST_RFI 773 +#define PPC_INST_RFCI 774 +#define PPC_INST_RFSVC 775 +#define PPC_INST_CRANDC 776 +#define PPC_INST_ISYNC 777 +#define PPC_INST_ICS 778 +#define PPC_INST_CRCLR 779 +#define PPC_INST_CRXOR 780 +#define PPC_INST_CRNAND 781 +#define PPC_INST_CRAND 782 +#define PPC_INST_HRFID 783 +#define PPC_INST_CRSET 784 +#define PPC_INST_CREQV 785 +#define PPC_INST_DOZE 786 +#define PPC_INST_CRORC 787 +#define PPC_INST_NAP 788 +#define PPC_INST_CRMOVE 789 +#define PPC_INST_CROR 790 +#define PPC_INST_SLEEP 791 +#define PPC_INST_RVWINKLE 792 +#define PPC_INST_BCTR 793 +#define PPC_INST_BCTRL 794 +#define PPC_INST_BLTCTR 795 +#define PPC_INST_BLTCTRL 796 +#define PPC_INST_BGTCTR 797 +#define PPC_INST_BGTCTRL 798 +#define PPC_INST_BEQCTR 799 +#define PPC_INST_BEQCTRL 800 +#define PPC_INST_BSOCTR 801 +#define PPC_INST_BSOCTRL 802 +#define PPC_INST_BUNCTR 803 +#define PPC_INST_BUNCTRL 804 +#define PPC_INST_BGECTR 805 +#define PPC_INST_BGECTRL 806 +#define PPC_INST_BNLCTR 807 +#define PPC_INST_BNLCTRL 808 +#define PPC_INST_BLECTR 809 +#define PPC_INST_BLECTRL 810 +#define PPC_INST_BNGCTR 811 +#define PPC_INST_BNGCTRL 812 +#define PPC_INST_BNECTR 813 +#define PPC_INST_BNECTRL 814 +#define PPC_INST_BNSCTR 815 +#define PPC_INST_BNSCTRL 816 +#define PPC_INST_BNUCTR 817 +#define PPC_INST_BNUCTRL 818 +#define PPC_INST_BTCTR 819 +#define PPC_INST_BTCTRL 820 +#define PPC_INST_BFCTR 821 +#define PPC_INST_BFCTRL 822 +#define PPC_INST_BCCTR 823 +#define PPC_INST_BCCTRL 824 +#define PPC_INST_BCC 825 +#define PPC_INST_BCCL 826 +#define PPC_INST_BCCTRE 827 +#define PPC_INST_BCCTREL 828 +#define PPC_INST_RLWIMI 829 +#define PPC_INST_RLIMI 830 +#define PPC_INST_ROTLWI 831 +#define PPC_INST_CLRLWI 832 +#define PPC_INST_RLWINM 833 +#define PPC_INST_RLINM 834 +#define PPC_INST_RLMI 835 +#define PPC_INST_BE 836 +#define PPC_INST_BEL 837 +#define PPC_INST_BEA 838 +#define PPC_INST_BELA 839 +#define PPC_INST_ROTLW 840 +#define PPC_INST_RLWNM 841 +#define PPC_INST_RLNM 842 +#define PPC_INST_NOP 843 +#define PPC_INST_ORI 844 +#define PPC_INST_ORIL 845 +#define PPC_INST_ORIS 846 +#define PPC_INST_ORIU 847 +#define PPC_INST_XORI 848 +#define PPC_INST_XORIL 849 +#define PPC_INST_XORIS 850 +#define PPC_INST_XORIU 851 +#define PPC_INST_ANDI 852 +#define PPC_INST_ANDIL 853 +#define PPC_INST_ANDIS 854 +#define PPC_INST_ANDIU 855 +#define PPC_INST_ROTLDI 856 +#define PPC_INST_CLRLDI 857 +#define PPC_INST_RLDICL 858 +#define PPC_INST_RLDICR 859 +#define PPC_INST_RLDIC 860 +#define PPC_INST_RLDIMI 861 +#define PPC_INST_ROTLD 862 +#define PPC_INST_RLDCL 863 +#define PPC_INST_RLDCR 864 +#define PPC_INST_CMPW 865 +#define PPC_INST_CMPD 866 +#define PPC_INST_CMP 867 +#define PPC_INST_TWLGT 868 +#define PPC_INST_TLGT 869 +#define PPC_INST_TWLLT 870 +#define PPC_INST_TLLT 871 +#define PPC_INST_TWEQ 872 +#define PPC_INST_TEQ 873 +#define PPC_INST_TWLGE 874 +#define PPC_INST_TLGE 875 +#define PPC_INST_TWLNL 876 +#define PPC_INST_TLNL 877 +#define PPC_INST_TWLLE 878 +#define PPC_INST_TLLE 879 +#define PPC_INST_TWLNG 880 +#define PPC_INST_TLNG 881 +#define PPC_INST_TWGT 882 +#define PPC_INST_TGT 883 +#define PPC_INST_TWGE 884 +#define PPC_INST_TGE 885 +#define PPC_INST_TWNL 886 +#define PPC_INST_TNL 887 +#define PPC_INST_TWLT 888 +#define PPC_INST_TLT 889 +#define PPC_INST_TWLE 890 +#define PPC_INST_TLE 891 +#define PPC_INST_TWNG 892 +#define PPC_INST_TNG 893 +#define PPC_INST_TWNE 894 +#define PPC_INST_TNE 895 +#define PPC_INST_TRAP 896 +#define PPC_INST_TW 897 +#define PPC_INST_T 898 +#define PPC_INST_SUBFC 899 +#define PPC_INST_SF 900 +#define PPC_INST_SUBC 901 +#define PPC_INST_SUBFCO 902 +#define PPC_INST_SFO 903 +#define PPC_INST_SUBCO 904 +#define PPC_INST_MULHDU 905 +#define PPC_INST_ADDC 906 +#define PPC_INST_A 907 +#define PPC_INST_ADDCO 908 +#define PPC_INST_AO 909 +#define PPC_INST_MULHWU 910 +#define PPC_INST_ISELLT 911 +#define PPC_INST_ISELGT 912 +#define PPC_INST_ISELEQ 913 +#define PPC_INST_ISEL 914 +#define PPC_INST_MFOCRF 915 +#define PPC_INST_MFCR 916 +#define PPC_INST_LWARX 917 +#define PPC_INST_LDX 918 +#define PPC_INST_ICBT 919 +#define PPC_INST_LWZX 920 +#define PPC_INST_LX 921 +#define PPC_INST_SLW 922 +#define PPC_INST_SL 923 +#define PPC_INST_CNTLZW 924 +#define PPC_INST_CNTLZ 925 +#define PPC_INST_SLD 926 +#define PPC_INST_AND 927 +#define PPC_INST_MASKG 928 +#define PPC_INST_ICBTE 929 +#define PPC_INST_LWZXE 930 +#define PPC_INST_CMPLW 931 +#define PPC_INST_CMPLD 932 +#define PPC_INST_CMPL 933 +#define PPC_INST_SUBF 934 +#define PPC_INST_SUB 935 +#define PPC_INST_SUBFO 936 +#define PPC_INST_SUBO 937 +#define PPC_INST_LDUX 938 +#define PPC_INST_DCBST 939 +#define PPC_INST_LWZUX 940 +#define PPC_INST_LUX 941 +#define PPC_INST_DCBSTE 942 +#define PPC_INST_LWZUXE 943 +#define PPC_INST_CNTLZD 944 +#define PPC_INST_ANDC 945 +#define PPC_INST_TDLGT 946 +#define PPC_INST_TDLLT 947 +#define PPC_INST_TDEQ 948 +#define PPC_INST_TDLGE 949 +#define PPC_INST_TDLNL 950 +#define PPC_INST_TDLLE 951 +#define PPC_INST_TDLNG 952 +#define PPC_INST_TDGT 953 +#define PPC_INST_TDGE 954 +#define PPC_INST_TDNL 955 +#define PPC_INST_TDLT 956 +#define PPC_INST_TDLE 957 +#define PPC_INST_TDNG 958 +#define PPC_INST_TDNE 959 +#define PPC_INST_TD 960 +#define PPC_INST_MULHD 961 +#define PPC_INST_MULHW 962 +#define PPC_INST_DLMZB 963 +#define PPC_INST_MTSRD 964 +#define PPC_INST_MFMSR 965 +#define PPC_INST_LDARX 966 +#define PPC_INST_DCBFL 967 +#define PPC_INST_DCBF 968 +#define PPC_INST_LBZX 969 +#define PPC_INST_DCBFE 970 +#define PPC_INST_LBZXE 971 +#define PPC_INST_NEG 972 +#define PPC_INST_NEGO 973 +#define PPC_INST_MUL 974 +#define PPC_INST_MULO 975 +#define PPC_INST_MTSRDIN 976 +#define PPC_INST_CLF 977 +#define PPC_INST_LBZUX 978 +#define PPC_INST_POPCNTB 979 +#define PPC_INST_NOT 980 +#define PPC_INST_NOR 981 +#define PPC_INST_LWARXE 982 +#define PPC_INST_LBZUXE 983 +#define PPC_INST_WRTEE 984 +#define PPC_INST_DCBTSTLS 985 +#define PPC_INST_SUBFE 986 +#define PPC_INST_SFE 987 +#define PPC_INST_SUBFEO 988 +#define PPC_INST_SFEO 989 +#define PPC_INST_ADDE 990 +#define PPC_INST_AE 991 +#define PPC_INST_ADDEO 992 +#define PPC_INST_AEO 993 +#define PPC_INST_DCBTSTLSE 994 +#define PPC_INST_MTOCRF 995 +#define PPC_INST_MTCR 996 +#define PPC_INST_MTCRF 997 +#define PPC_INST_MTMSR 998 +#define PPC_INST_STDX 999 +#define PPC_INST_STWCX 1000 +#define PPC_INST_STWX 1001 +#define PPC_INST_STX 1002 +#define PPC_INST_STWCXE 1003 +#define PPC_INST_STWXE 1004 +#define PPC_INST_SLQ 1005 +#define PPC_INST_SLE 1006 +#define PPC_INST_PRTYW 1007 +#define PPC_INST_WRTEEI 1008 +#define PPC_INST_DCBTLS 1009 +#define PPC_INST_DCBTLSE 1010 +#define PPC_INST_MTMSRD 1011 +#define PPC_INST_STDUX 1012 +#define PPC_INST_STWUX 1013 +#define PPC_INST_STUX 1014 +#define PPC_INST_SLIQ 1015 +#define PPC_INST_PRTYD 1016 +#define PPC_INST_STWUXE 1017 +#define PPC_INST_SUBFZE 1018 +#define PPC_INST_SFZE 1019 +#define PPC_INST_SUBFZEO 1020 +#define PPC_INST_SFZEO 1021 +#define PPC_INST_ADDZE 1022 +#define PPC_INST_AZE 1023 +#define PPC_INST_ADDZEO 1024 +#define PPC_INST_AZEO 1025 +#define PPC_INST_MTSR 1026 +#define PPC_INST_STDCX 1027 +#define PPC_INST_STBX 1028 +#define PPC_INST_SLLQ 1029 +#define PPC_INST_SLEQ 1030 +#define PPC_INST_STBXE 1031 +#define PPC_INST_ICBLC 1032 +#define PPC_INST_SUBFME 1033 +#define PPC_INST_SFME 1034 +#define PPC_INST_SUBFMEO 1035 +#define PPC_INST_SFMEO 1036 +#define PPC_INST_MULLD 1037 +#define PPC_INST_MULLDO 1038 +#define PPC_INST_ADDME 1039 +#define PPC_INST_AME 1040 +#define PPC_INST_ADDMEO 1041 +#define PPC_INST_AMEO 1042 +#define PPC_INST_MULLW 1043 +#define PPC_INST_MULS 1044 +#define PPC_INST_MULLWO 1045 +#define PPC_INST_MULSO 1046 +#define PPC_INST_ICBLCE 1047 +#define PPC_INST_MTSRIN 1048 +#define PPC_INST_MTSRI 1049 +#define PPC_INST_DCBTST 1050 +#define PPC_INST_STBUX 1051 +#define PPC_INST_SLLIQ 1052 +#define PPC_INST_DCBTSTE 1053 +#define PPC_INST_STBUXE 1054 +#define PPC_INST_MFDCRX 1055 +#define PPC_INST_DOZ 1056 +#define PPC_INST_DOZO 1057 +#define PPC_INST_ADD 1058 +#define PPC_INST_CAX 1059 +#define PPC_INST_ADDO 1060 +#define PPC_INST_CAXO 1061 +#define PPC_INST_TLBIEL 1062 +#define PPC_INST_MFAPIDI 1063 +#define PPC_INST_LSCBX 1064 +#define PPC_INST_DCBT 1065 +#define PPC_INST_LHZX 1066 +#define PPC_INST_EQV 1067 +#define PPC_INST_DCBTE 1068 +#define PPC_INST_LHZXE 1069 +#define PPC_INST_TLBIE 1070 +#define PPC_INST_TLBI 1071 +#define PPC_INST_ECIWX 1072 +#define PPC_INST_LHZUX 1073 +#define PPC_INST_XOR 1074 +#define PPC_INST_LHZUXE 1075 +#define PPC_INST_MFEXISR 1076 +#define PPC_INST_MFEXIER 1077 +#define PPC_INST_MFBR0 1078 +#define PPC_INST_MFBR1 1079 +#define PPC_INST_MFBR2 1080 +#define PPC_INST_MFBR3 1081 +#define PPC_INST_MFBR4 1082 +#define PPC_INST_MFBR5 1083 +#define PPC_INST_MFBR6 1084 +#define PPC_INST_MFBR7 1085 +#define PPC_INST_MFBEAR 1086 +#define PPC_INST_MFBESR 1087 +#define PPC_INST_MFIOCR 1088 +#define PPC_INST_MFDMACR0 1089 +#define PPC_INST_MFDMACT0 1090 +#define PPC_INST_MFDMADA0 1091 +#define PPC_INST_MFDMASA0 1092 +#define PPC_INST_MFDMACC0 1093 +#define PPC_INST_MFDMACR1 1094 +#define PPC_INST_MFDMACT1 1095 +#define PPC_INST_MFDMADA1 1096 +#define PPC_INST_MFDMASA1 1097 +#define PPC_INST_MFDMACC1 1098 +#define PPC_INST_MFDMACR2 1099 +#define PPC_INST_MFDMACT2 1100 +#define PPC_INST_MFDMADA2 1101 +#define PPC_INST_MFDMASA2 1102 +#define PPC_INST_MFDMACC2 1103 +#define PPC_INST_MFDMACR3 1104 +#define PPC_INST_MFDMACT3 1105 +#define PPC_INST_MFDMADA3 1106 +#define PPC_INST_MFDMASA3 1107 +#define PPC_INST_MFDMACC3 1108 +#define PPC_INST_MFDMASR 1109 +#define PPC_INST_MFDCR 1110 +#define PPC_INST_DIV 1111 +#define PPC_INST_DIVO 1112 +#define PPC_INST_MFPMR 1113 +#define PPC_INST_MFMQ 1114 +#define PPC_INST_MFXER 1115 +#define PPC_INST_MFRTCU 1116 +#define PPC_INST_MFRTCL 1117 +#define PPC_INST_MFDEC 1118 +#define PPC_INST_MFLR 1119 +#define PPC_INST_MFCTR 1120 +#define PPC_INST_MFTID 1121 +#define PPC_INST_MFDSISR 1122 +#define PPC_INST_MFDAR 1123 +#define PPC_INST_MFSDR0 1124 +#define PPC_INST_MFSDR1 1125 +#define PPC_INST_MFSRR0 1126 +#define PPC_INST_MFSRR1 1127 +#define PPC_INST_MFCFAR 1128 +#define PPC_INST_MFPID 1129 +#define PPC_INST_MFCSRR0 1130 +#define PPC_INST_MFCSRR1 1131 +#define PPC_INST_MFDEAR 1132 +#define PPC_INST_MFESR 1133 +#define PPC_INST_MFIVPR 1134 +#define PPC_INST_MFCMPA 1135 +#define PPC_INST_MFCMPB 1136 +#define PPC_INST_MFCMPC 1137 +#define PPC_INST_MFCMPD 1138 +#define PPC_INST_MFICR 1139 +#define PPC_INST_MFDER 1140 +#define PPC_INST_MFCOUNTA 1141 +#define PPC_INST_MFCOUNTB 1142 +#define PPC_INST_MFCMPE 1143 +#define PPC_INST_MFCMPF 1144 +#define PPC_INST_MFCMPG 1145 +#define PPC_INST_MFCMPH 1146 +#define PPC_INST_MFLCTRL1 1147 +#define PPC_INST_MFLCTRL2 1148 +#define PPC_INST_MFICTRL 1149 +#define PPC_INST_MFBAR 1150 +#define PPC_INST_MFVRSAVE 1151 +#define PPC_INST_MFUSPRG0 1152 +#define PPC_INST_MFTB 1153 +#define PPC_INST_MFTBL 1154 +#define PPC_INST_MFTBU 1155 +#define PPC_INST_MFSPRG 1156 +#define PPC_INST_MFSPRG0 1157 +#define PPC_INST_MFSPRG1 1158 +#define PPC_INST_MFSPRG2 1159 +#define PPC_INST_MFSPRG3 1160 +#define PPC_INST_MFSPRG4 1161 +#define PPC_INST_MFSPRG5 1162 +#define PPC_INST_MFSPRG6 1163 +#define PPC_INST_MFSPRG7 1164 +#define PPC_INST_MFASR 1165 +#define PPC_INST_MFEAR 1166 +#define PPC_INST_MFPIR 1167 +#define PPC_INST_MFPVR 1168 +#define PPC_INST_MFDBSR 1169 +#define PPC_INST_MFDBCR0 1170 +#define PPC_INST_MFDBCR1 1171 +#define PPC_INST_MFDBCR2 1172 +#define PPC_INST_MFIAC1 1173 +#define PPC_INST_MFIAC2 1174 +#define PPC_INST_MFIAC3 1175 +#define PPC_INST_MFIAC4 1176 +#define PPC_INST_MFDAC1 1177 +#define PPC_INST_MFDAC2 1178 +#define PPC_INST_MFDVC1 1179 +#define PPC_INST_MFDVC2 1180 +#define PPC_INST_MFTSR 1181 +#define PPC_INST_MFTCR 1182 +#define PPC_INST_MFIVOR0 1183 +#define PPC_INST_MFIVOR1 1184 +#define PPC_INST_MFIVOR2 1185 +#define PPC_INST_MFIVOR3 1186 +#define PPC_INST_MFIVOR4 1187 +#define PPC_INST_MFIVOR5 1188 +#define PPC_INST_MFIVOR6 1189 +#define PPC_INST_MFIVOR7 1190 +#define PPC_INST_MFIVOR8 1191 +#define PPC_INST_MFIVOR9 1192 +#define PPC_INST_MFIVOR10 1193 +#define PPC_INST_MFIVOR11 1194 +#define PPC_INST_MFIVOR12 1195 +#define PPC_INST_MFIVOR13 1196 +#define PPC_INST_MFIVOR14 1197 +#define PPC_INST_MFIVOR15 1198 +#define PPC_INST_MFSPEFSCR 1199 +#define PPC_INST_MFBBEAR 1200 +#define PPC_INST_MFBBTAR 1201 +#define PPC_INST_MFIVOR32 1202 +#define PPC_INST_MFIVOR33 1203 +#define PPC_INST_MFIVOR34 1204 +#define PPC_INST_MFIVOR35 1205 +#define PPC_INST_MFIBATU 1206 +#define PPC_INST_MFIBATL 1207 +#define PPC_INST_MFDBATU 1208 +#define PPC_INST_MFDBATL 1209 +#define PPC_INST_MFIC_CST 1210 +#define PPC_INST_MFIC_ADR 1211 +#define PPC_INST_MFIC_DAT 1212 +#define PPC_INST_MFDC_CST 1213 +#define PPC_INST_MFDC_ADR 1214 +#define PPC_INST_MFMCSRR0 1215 +#define PPC_INST_MFDC_DAT 1216 +#define PPC_INST_MFMCSRR1 1217 +#define PPC_INST_MFMCSR 1218 +#define PPC_INST_MFMCAR 1219 +#define PPC_INST_MFDPDR 1220 +#define PPC_INST_MFDPIR 1221 +#define PPC_INST_MFIMMR 1222 +#define PPC_INST_MFMI_CTR 1223 +#define PPC_INST_MFMI_AP 1224 +#define PPC_INST_MFMI_EPN 1225 +#define PPC_INST_MFMI_TWC 1226 +#define PPC_INST_MFMI_RPN 1227 +#define PPC_INST_MFMD_CTR 1228 +#define PPC_INST_MFM_CASID 1229 +#define PPC_INST_MFMD_AP 1230 +#define PPC_INST_MFMD_EPN 1231 +#define PPC_INST_MFMD_TWB 1232 +#define PPC_INST_MFMD_TWC 1233 +#define PPC_INST_MFMD_RPN 1234 +#define PPC_INST_MFM_TW 1235 +#define PPC_INST_MFMI_DBCAM 1236 +#define PPC_INST_MFMI_DBRAM0 1237 +#define PPC_INST_MFMI_DBRAM1 1238 +#define PPC_INST_MFMD_DBCAM 1239 +#define PPC_INST_MFMD_DBRAM0 1240 +#define PPC_INST_MFMD_DBRAM1 1241 +#define PPC_INST_MFUMMCR0 1242 +#define PPC_INST_MFUPMC1 1243 +#define PPC_INST_MFUPMC2 1244 +#define PPC_INST_MFUSIA 1245 +#define PPC_INST_MFUMMCR1 1246 +#define PPC_INST_MFUPMC3 1247 +#define PPC_INST_MFUPMC4 1248 +#define PPC_INST_MFZPR 1249 +#define PPC_INST_MFCCR0 1250 +#define PPC_INST_MFMMCR0 1251 +#define PPC_INST_MFPMC1 1252 +#define PPC_INST_MFSGR 1253 +#define PPC_INST_MFPMC2 1254 +#define PPC_INST_MFDCWR 1255 +#define PPC_INST_MFSIA 1256 +#define PPC_INST_MFSLER 1257 +#define PPC_INST_MFMMCR1 1258 +#define PPC_INST_MFSU0R 1259 +#define PPC_INST_MFPMC3 1260 +#define PPC_INST_MFPMC4 1261 +#define PPC_INST_MFICDBDR 1262 +#define PPC_INST_MFEVPR 1263 +#define PPC_INST_MFCDBCR 1264 +#define PPC_INST_MFPIT 1265 +#define PPC_INST_MFTBHI 1266 +#define PPC_INST_MFTBLO 1267 +#define PPC_INST_MFSRR2 1268 +#define PPC_INST_MFSRR3 1269 +#define PPC_INST_MFL2CR 1270 +#define PPC_INST_MFDCCR 1271 +#define PPC_INST_MFICCR 1272 +#define PPC_INST_MFICTC 1273 +#define PPC_INST_MFPBL1 1274 +#define PPC_INST_MFTHRM1 1275 +#define PPC_INST_MFPBU1 1276 +#define PPC_INST_MFTHRM2 1277 +#define PPC_INST_MFPBL2 1278 +#define PPC_INST_MFTHRM3 1279 +#define PPC_INST_MFPBU2 1280 +#define PPC_INST_MFSPR 1281 +#define PPC_INST_LWAX 1282 +#define PPC_INST_DST 1283 +#define PPC_INST_DSTT 1284 +#define PPC_INST_LHAX 1285 +#define PPC_INST_LHAXE 1286 +#define PPC_INST_DSTST 1287 +#define PPC_INST_DSTSTT 1288 +#define PPC_INST_DCCCI 1289 +#define PPC_INST_ABS 1290 +#define PPC_INST_ABSO 1291 +#define PPC_INST_DIVS 1292 +#define PPC_INST_DIVSO 1293 +#define PPC_INST_TLBIA 1294 +#define PPC_INST_LWAUX 1295 +#define PPC_INST_LHAUX 1296 +#define PPC_INST_LHAUXE 1297 +#define PPC_INST_MTDCRX 1298 +#define PPC_INST_DCBLC 1299 +#define PPC_INST_SUBFE64 1300 +#define PPC_INST_SUBFE64O 1301 +#define PPC_INST_ADDE64 1302 +#define PPC_INST_ADDE64O 1303 +#define PPC_INST_DCBLCE 1304 +#define PPC_INST_SLBMTE 1305 +#define PPC_INST_STHX 1306 +#define PPC_INST_CMPB 1307 +#define PPC_INST_LFQX 1308 +#define PPC_INST_LFDPX 1309 +#define PPC_INST_LFQUX 1310 +#define PPC_INST_STFQX 1311 +#define PPC_INST_STFDPX 1312 +#define PPC_INST_STFQUX 1313 +#define PPC_INST_ORC 1314 +#define PPC_INST_SRADI 1315 +#define PPC_INST_STHXE 1316 +#define PPC_INST_SLBIE 1317 +#define PPC_INST_ECOWX 1318 +#define PPC_INST_STHUX 1319 +#define PPC_INST_STHUXE 1320 +#define PPC_INST_CCTPL 1321 +#define PPC_INST_CCTPM 1322 +#define PPC_INST_CCTPH 1323 +#define PPC_INST_DB8CYC 1324 +#define PPC_INST_DB10CYC 1325 +#define PPC_INST_DB12CYC 1326 +#define PPC_INST_DB16CYC 1327 +#define PPC_INST_MR 1328 +#define PPC_INST_OR 1329 +#define PPC_INST_MTEXISR 1330 +#define PPC_INST_MTEXIER 1331 +#define PPC_INST_MTBR0 1332 +#define PPC_INST_MTBR1 1333 +#define PPC_INST_MTBR2 1334 +#define PPC_INST_MTBR3 1335 +#define PPC_INST_MTBR4 1336 +#define PPC_INST_MTBR5 1337 +#define PPC_INST_MTBR6 1338 +#define PPC_INST_MTBR7 1339 +#define PPC_INST_MTBEAR 1340 +#define PPC_INST_MTBESR 1341 +#define PPC_INST_MTIOCR 1342 +#define PPC_INST_MTDMACR0 1343 +#define PPC_INST_MTDMACT0 1344 +#define PPC_INST_MTDMADA0 1345 +#define PPC_INST_MTDMASA0 1346 +#define PPC_INST_MTDMACC0 1347 +#define PPC_INST_MTDMACR1 1348 +#define PPC_INST_MTDMACT1 1349 +#define PPC_INST_MTDMADA1 1350 +#define PPC_INST_MTDMASA1 1351 +#define PPC_INST_MTDMACC1 1352 +#define PPC_INST_MTDMACR2 1353 +#define PPC_INST_MTDMACT2 1354 +#define PPC_INST_MTDMADA2 1355 +#define PPC_INST_MTDMASA2 1356 +#define PPC_INST_MTDMACC2 1357 +#define PPC_INST_MTDMACR3 1358 +#define PPC_INST_MTDMACT3 1359 +#define PPC_INST_MTDMADA3 1360 +#define PPC_INST_MTDMASA3 1361 +#define PPC_INST_MTDMACC3 1362 +#define PPC_INST_MTDMASR 1363 +#define PPC_INST_MTDCR 1364 +#define PPC_INST_SUBFZE64 1365 +#define PPC_INST_SUBFZE64O 1366 +#define PPC_INST_DIVDU 1367 +#define PPC_INST_DIVDUO 1368 +#define PPC_INST_ADDZE64 1369 +#define PPC_INST_ADDZE64O 1370 +#define PPC_INST_DIVWU 1371 +#define PPC_INST_DIVWUO 1372 +#define PPC_INST_MTMQ 1373 +#define PPC_INST_MTXER 1374 +#define PPC_INST_MTLR 1375 +#define PPC_INST_MTCTR 1376 +#define PPC_INST_MTTID 1377 +#define PPC_INST_MTDSISR 1378 +#define PPC_INST_MTDAR 1379 +#define PPC_INST_MTRTCU 1380 +#define PPC_INST_MTRTCL 1381 +#define PPC_INST_MTDEC 1382 +#define PPC_INST_MTSDR0 1383 +#define PPC_INST_MTSDR1 1384 +#define PPC_INST_MTSRR0 1385 +#define PPC_INST_MTSRR1 1386 +#define PPC_INST_MTCFAR 1387 +#define PPC_INST_MTPID 1388 +#define PPC_INST_MTDECAR 1389 +#define PPC_INST_MTCSRR0 1390 +#define PPC_INST_MTCSRR1 1391 +#define PPC_INST_MTDEAR 1392 +#define PPC_INST_MTESR 1393 +#define PPC_INST_MTIVPR 1394 +#define PPC_INST_MTCMPA 1395 +#define PPC_INST_MTCMPB 1396 +#define PPC_INST_MTCMPC 1397 +#define PPC_INST_MTCMPD 1398 +#define PPC_INST_MTICR 1399 +#define PPC_INST_MTDER 1400 +#define PPC_INST_MTCOUNTA 1401 +#define PPC_INST_MTCOUNTB 1402 +#define PPC_INST_MTCMPE 1403 +#define PPC_INST_MTCMPF 1404 +#define PPC_INST_MTCMPG 1405 +#define PPC_INST_MTCMPH 1406 +#define PPC_INST_MTLCTRL1 1407 +#define PPC_INST_MTLCTRL2 1408 +#define PPC_INST_MTICTRL 1409 +#define PPC_INST_MTBAR 1410 +#define PPC_INST_MTVRSAVE 1411 +#define PPC_INST_MTUSPRG0 1412 +#define PPC_INST_MTSPRG 1413 +#define PPC_INST_MTSPRG0 1414 +#define PPC_INST_MTSPRG1 1415 +#define PPC_INST_MTSPRG2 1416 +#define PPC_INST_MTSPRG3 1417 +#define PPC_INST_MTSPRG4 1418 +#define PPC_INST_MTSPRG5 1419 +#define PPC_INST_MTSPRG6 1420 +#define PPC_INST_MTSPRG7 1421 +#define PPC_INST_MTASR 1422 +#define PPC_INST_MTEAR 1423 +#define PPC_INST_MTTBL 1424 +#define PPC_INST_MTTBU 1425 +#define PPC_INST_MTDBSR 1426 +#define PPC_INST_MTDBCR0 1427 +#define PPC_INST_MTDBCR1 1428 +#define PPC_INST_MTDBCR2 1429 +#define PPC_INST_MTIAC1 1430 +#define PPC_INST_MTIAC2 1431 +#define PPC_INST_MTIAC3 1432 +#define PPC_INST_MTIAC4 1433 +#define PPC_INST_MTDAC1 1434 +#define PPC_INST_MTDAC2 1435 +#define PPC_INST_MTDVC1 1436 +#define PPC_INST_MTDVC2 1437 +#define PPC_INST_MTTSR 1438 +#define PPC_INST_MTTCR 1439 +#define PPC_INST_MTIVOR0 1440 +#define PPC_INST_MTIVOR1 1441 +#define PPC_INST_MTIVOR2 1442 +#define PPC_INST_MTIVOR3 1443 +#define PPC_INST_MTIVOR4 1444 +#define PPC_INST_MTIVOR5 1445 +#define PPC_INST_MTIVOR6 1446 +#define PPC_INST_MTIVOR7 1447 +#define PPC_INST_MTIVOR8 1448 +#define PPC_INST_MTIVOR9 1449 +#define PPC_INST_MTIVOR10 1450 +#define PPC_INST_MTIVOR11 1451 +#define PPC_INST_MTIVOR12 1452 +#define PPC_INST_MTIVOR13 1453 +#define PPC_INST_MTIVOR14 1454 +#define PPC_INST_MTIVOR15 1455 +#define PPC_INST_MTSPEFSCR 1456 +#define PPC_INST_MTBBEAR 1457 +#define PPC_INST_MTBBTAR 1458 +#define PPC_INST_MTIVOR32 1459 +#define PPC_INST_MTIVOR33 1460 +#define PPC_INST_MTIVOR34 1461 +#define PPC_INST_MTIVOR35 1462 +#define PPC_INST_MTIBATU 1463 +#define PPC_INST_MTIBATL 1464 +#define PPC_INST_MTDBATU 1465 +#define PPC_INST_MTDBATL 1466 +#define PPC_INST_MTMCSRR0 1467 +#define PPC_INST_MTMCSRR1 1468 +#define PPC_INST_MTMCSR 1469 +#define PPC_INST_MTUMMCR0 1470 +#define PPC_INST_MTUPMC1 1471 +#define PPC_INST_MTUPMC2 1472 +#define PPC_INST_MTUSIA 1473 +#define PPC_INST_MTUMMCR1 1474 +#define PPC_INST_MTUPMC3 1475 +#define PPC_INST_MTUPMC4 1476 +#define PPC_INST_MTZPR 1477 +#define PPC_INST_MTCCR0 1478 +#define PPC_INST_MTMMCR0 1479 +#define PPC_INST_MTSGR 1480 +#define PPC_INST_MTPMC1 1481 +#define PPC_INST_MTDCWR 1482 +#define PPC_INST_MTPMC2 1483 +#define PPC_INST_MTSLER 1484 +#define PPC_INST_MTSIA 1485 +#define PPC_INST_MTSU0R 1486 +#define PPC_INST_MTMMCR1 1487 +#define PPC_INST_MTPMC3 1488 +#define PPC_INST_MTPMC4 1489 +#define PPC_INST_MTICDBDR 1490 +#define PPC_INST_MTEVPR 1491 +#define PPC_INST_MTCDBCR 1492 +#define PPC_INST_MTPIT 1493 +#define PPC_INST_MTTBHI 1494 +#define PPC_INST_MTTBLO 1495 +#define PPC_INST_MTSRR2 1496 +#define PPC_INST_MTSRR3 1497 +#define PPC_INST_MTL2CR 1498 +#define PPC_INST_MTDCCR 1499 +#define PPC_INST_MTICCR 1500 +#define PPC_INST_MTICTC 1501 +#define PPC_INST_MTPBL1 1502 +#define PPC_INST_MTTHRM1 1503 +#define PPC_INST_MTPBU1 1504 +#define PPC_INST_MTTHRM2 1505 +#define PPC_INST_MTPBL2 1506 +#define PPC_INST_MTTHRM3 1507 +#define PPC_INST_MTPBU2 1508 +#define PPC_INST_MTSPR 1509 +#define PPC_INST_DCBI 1510 +#define PPC_INST_NAND 1511 +#define PPC_INST_DCBIE 1512 +#define PPC_INST_DCREAD 1513 +#define PPC_INST_MTPMR 1514 +#define PPC_INST_ICBTLS 1515 +#define PPC_INST_NABS 1516 +#define PPC_INST_SUBFME64 1517 +#define PPC_INST_NABSO 1518 +#define PPC_INST_SUBFME64O 1519 +#define PPC_INST_DIVD 1520 +#define PPC_INST_DIVDO 1521 +#define PPC_INST_ADDME64 1522 +#define PPC_INST_ADDME64O 1523 +#define PPC_INST_DIVW 1524 +#define PPC_INST_DIVWO 1525 +#define PPC_INST_ICBTLSE 1526 +#define PPC_INST_SLBIA 1527 +#define PPC_INST_CLI 1528 +#define PPC_INST_STDCXE 1529 +#define PPC_INST_MCRXR 1530 +#define PPC_INST_BBLELS 1531 +#define PPC_INST_MCRXR64 1532 +#define PPC_INST_CLCS 1533 +#define PPC_INST_LDBRX 1534 +#define PPC_INST_LSWX 1535 +#define PPC_INST_LSX 1536 +#define PPC_INST_LWBRX 1537 +#define PPC_INST_LBRX 1538 +#define PPC_INST_LFSX 1539 +#define PPC_INST_SRW 1540 +#define PPC_INST_SR 1541 +#define PPC_INST_RRIB 1542 +#define PPC_INST_SRD 1543 +#define PPC_INST_MASKIR 1544 +#define PPC_INST_LWBRXE 1545 +#define PPC_INST_LFSXE 1546 +#define PPC_INST_BBELR 1547 +#define PPC_INST_TLBSYNC 1548 +#define PPC_INST_LFSUX 1549 +#define PPC_INST_LFSUXE 1550 +#define PPC_INST_MFSR 1551 +#define PPC_INST_LSWI 1552 +#define PPC_INST_LSI 1553 +#define PPC_INST_LWSYNC 1554 +#define PPC_INST_PTESYNC 1555 +#define PPC_INST_MSYNC 1556 +#define PPC_INST_SYNC 1557 +#define PPC_INST_DCS 1558 +#define PPC_INST_LFDX 1559 +#define PPC_INST_LFDXE 1560 +#define PPC_INST_MFFGPR 1561 +#define PPC_INST_MFSRI 1562 +#define PPC_INST_DCLST 1563 +#define PPC_INST_LFDUX 1564 +#define PPC_INST_LFDUXE 1565 +#define PPC_INST_MFSRIN 1566 +#define PPC_INST_STDBRX 1567 +#define PPC_INST_STSWX 1568 +#define PPC_INST_STSX 1569 +#define PPC_INST_STWBRX 1570 +#define PPC_INST_STBRX 1571 +#define PPC_INST_STFSX 1572 +#define PPC_INST_SRQ 1573 +#define PPC_INST_SRE 1574 +#define PPC_INST_STWBRXE 1575 +#define PPC_INST_STFSXE 1576 +#define PPC_INST_STFSUX 1577 +#define PPC_INST_SRIQ 1578 +#define PPC_INST_STFSUXE 1579 +#define PPC_INST_STSWI 1580 +#define PPC_INST_STSI 1581 +#define PPC_INST_STFDX 1582 +#define PPC_INST_SRLQ 1583 +#define PPC_INST_SREQ 1584 +#define PPC_INST_STFDXE 1585 +#define PPC_INST_MFTGPR 1586 +#define PPC_INST_DCBA 1587 +#define PPC_INST_STFDUX 1588 +#define PPC_INST_SRLIQ 1589 +#define PPC_INST_DCBAE 1590 +#define PPC_INST_STFDUXE 1591 +#define PPC_INST_TLBIVAX 1592 +#define PPC_INST_TLBIVAXE 1593 +#define PPC_INST_LWZCIX 1594 +#define PPC_INST_LHBRX 1595 +#define PPC_INST_SRAW 1596 +#define PPC_INST_SRA 1597 +#define PPC_INST_SRAD 1598 +#define PPC_INST_LHBRXE 1599 +#define PPC_INST_LDXE 1600 +#define PPC_INST_LDUXE 1601 +#define PPC_INST_RAC 1602 +#define PPC_INST_LHZCIX 1603 +#define PPC_INST_DSS 1604 +#define PPC_INST_DSSALL 1605 +#define PPC_INST_SRAWI 1606 +#define PPC_INST_SRAI 1607 +#define PPC_INST_SLBMFEV 1608 +#define PPC_INST_LBZCIX 1609 +#define PPC_INST_MBAR 1610 +#define PPC_INST_EIEIO 1611 +#define PPC_INST_LFIWAX 1612 +#define PPC_INST_LDCIX 1613 +#define PPC_INST_TLBSX 1614 +#define PPC_INST_TLBSXE 1615 +#define PPC_INST_SLBMFEE 1616 +#define PPC_INST_STWCIX 1617 +#define PPC_INST_STHBRX 1618 +#define PPC_INST_SRAQ 1619 +#define PPC_INST_SREA 1620 +#define PPC_INST_EXTSH 1621 +#define PPC_INST_EXTS 1622 +#define PPC_INST_STHBRXE 1623 +#define PPC_INST_STDXE 1624 +#define PPC_INST_TLBREHI 1625 +#define PPC_INST_TLBRELO 1626 +#define PPC_INST_TLBRE 1627 +#define PPC_INST_STHCIX 1628 +#define PPC_INST_SRAIQ 1629 +#define PPC_INST_EXTSB 1630 +#define PPC_INST_STDUXE 1631 +#define PPC_INST_ICCCI 1632 +#define PPC_INST_TLBWEHI 1633 +#define PPC_INST_TLBWELO 1634 +#define PPC_INST_TLBWE 1635 +#define PPC_INST_TLBLD 1636 +#define PPC_INST_STBCIX 1637 +#define PPC_INST_ICBI 1638 +#define PPC_INST_STFIWX 1639 +#define PPC_INST_EXTSW 1640 +#define PPC_INST_ICREAD 1641 +#define PPC_INST_ICBIE 1642 +#define PPC_INST_STFIWXE 1643 +#define PPC_INST_TLBLI 1644 +#define PPC_INST_STDCIX 1645 +#define PPC_INST_DCBZL 1646 +#define PPC_INST_DCBZ 1647 +#define PPC_INST_DCLZ 1648 +#define PPC_INST_DCBZE 1649 +#define PPC_INST_LVEBX 1650 +#define PPC_INST_LVEHX 1651 +#define PPC_INST_LVEWX 1652 +#define PPC_INST_LVSL 1653 +#define PPC_INST_LVSR 1654 +#define PPC_INST_LVX 1655 +#define PPC_INST_LVXL 1656 +#define PPC_INST_STVEBX 1657 +#define PPC_INST_STVEHX 1658 +#define PPC_INST_STVEWX 1659 +#define PPC_INST_STVX 1660 +#define PPC_INST_STVXL 1661 +#define PPC_INST_LVLX 1662 +#define PPC_INST_LVLXL 1663 +#define PPC_INST_LVRX 1664 +#define PPC_INST_LVRXL 1665 +#define PPC_INST_STVLX 1666 +#define PPC_INST_STVLXL 1667 +#define PPC_INST_STVRX 1668 +#define PPC_INST_STVRXL 1669 +#define PPC_INST_LWZ 1670 +#define PPC_INST_L 1671 +#define PPC_INST_LWZU 1672 +#define PPC_INST_LU 1673 +#define PPC_INST_LBZ 1674 +#define PPC_INST_LBZU 1675 +#define PPC_INST_STW 1676 +#define PPC_INST_ST 1677 +#define PPC_INST_STWU 1678 +#define PPC_INST_STU 1679 +#define PPC_INST_STB 1680 +#define PPC_INST_STBU 1681 +#define PPC_INST_LHZ 1682 +#define PPC_INST_LHZU 1683 +#define PPC_INST_LHA 1684 +#define PPC_INST_LHAU 1685 +#define PPC_INST_STH 1686 +#define PPC_INST_STHU 1687 +#define PPC_INST_LMW 1688 +#define PPC_INST_LM 1689 +#define PPC_INST_STMW 1690 +#define PPC_INST_STM 1691 +#define PPC_INST_LFS 1692 +#define PPC_INST_LFSU 1693 +#define PPC_INST_LFD 1694 +#define PPC_INST_LFDU 1695 +#define PPC_INST_STFS 1696 +#define PPC_INST_STFSU 1697 +#define PPC_INST_STFD 1698 +#define PPC_INST_STFDU 1699 +#define PPC_INST_LQ 1700 +#define PPC_INST_LFQ 1701 +#define PPC_INST_LFQU 1702 +#define PPC_INST_LFDP 1703 +#define PPC_INST_LBZE 1704 +#define PPC_INST_LBZUE 1705 +#define PPC_INST_LHZE 1706 +#define PPC_INST_LHZUE 1707 +#define PPC_INST_LHAE 1708 +#define PPC_INST_LHAUE 1709 +#define PPC_INST_LWZE 1710 +#define PPC_INST_LWZUE 1711 +#define PPC_INST_STBE 1712 +#define PPC_INST_STBUE 1713 +#define PPC_INST_STHE 1714 +#define PPC_INST_STHUE 1715 +#define PPC_INST_STWE 1716 +#define PPC_INST_STWUE 1717 +#define PPC_INST_LD 1718 +#define PPC_INST_LDU 1719 +#define PPC_INST_LWA 1720 +#define PPC_INST_DADD 1721 +#define PPC_INST_DQUA 1722 +#define PPC_INST_FDIVS 1723 +#define PPC_INST_FSUBS 1724 +#define PPC_INST_FADDS 1725 +#define PPC_INST_FSQRTS 1726 +#define PPC_INST_FRES 1727 +#define PPC_INST_FMULS 1728 +#define PPC_INST_FRSQRTES 1729 +#define PPC_INST_FMSUBS 1730 +#define PPC_INST_FMADDS 1731 +#define PPC_INST_FNMSUBS 1732 +#define PPC_INST_FNMADDS 1733 +#define PPC_INST_DMUL 1734 +#define PPC_INST_DRRND 1735 +#define PPC_INST_DSCLI 1736 +#define PPC_INST_DQUAI 1737 +#define PPC_INST_DSCRI 1738 +#define PPC_INST_DRINTX 1739 +#define PPC_INST_DCMPO 1740 +#define PPC_INST_DTSTEX 1741 +#define PPC_INST_DTSTDC 1742 +#define PPC_INST_DTSTDG 1743 +#define PPC_INST_DRINTN 1744 +#define PPC_INST_DCTDP 1745 +#define PPC_INST_DCTFIX 1746 +#define PPC_INST_DDEDPD 1747 +#define PPC_INST_DXEX 1748 +#define PPC_INST_DSUB 1749 +#define PPC_INST_DDIV 1750 +#define PPC_INST_DCMPU 1751 +#define PPC_INST_DTSTSF 1752 +#define PPC_INST_DRSP 1753 +#define PPC_INST_DCFFIX 1754 +#define PPC_INST_DENBCD 1755 +#define PPC_INST_DIEX 1756 +#define PPC_INST_STFQ 1757 +#define PPC_INST_STFQU 1758 +#define PPC_INST_STFDP 1759 +#define PPC_INST_LDE 1760 +#define PPC_INST_LDUE 1761 +#define PPC_INST_LFSE 1762 +#define PPC_INST_LFSUE 1763 +#define PPC_INST_LFDE 1764 +#define PPC_INST_LFDUE 1765 +#define PPC_INST_STDE 1766 +#define PPC_INST_STDUE 1767 +#define PPC_INST_STFSE 1768 +#define PPC_INST_STFSUE 1769 +#define PPC_INST_STFDE 1770 +#define PPC_INST_STFDUE 1771 +#define PPC_INST_STD 1772 +#define PPC_INST_STDU 1773 +#define PPC_INST_STQ 1774 +#define PPC_INST_FCMPU 1775 +#define PPC_INST_DADDQ 1776 +#define PPC_INST_DQUAQ 1777 +#define PPC_INST_FCPSGN 1778 +#define PPC_INST_FRSP 1779 +#define PPC_INST_FCTIW 1780 +#define PPC_INST_FCIR 1781 +#define PPC_INST_FCTIWZ 1782 +#define PPC_INST_FCIRZ 1783 +#define PPC_INST_FDIV 1784 +#define PPC_INST_FD 1785 +#define PPC_INST_FSUB 1786 +#define PPC_INST_FS 1787 +#define PPC_INST_FADD 1788 +#define PPC_INST_FA 1789 +#define PPC_INST_FSQRT 1790 +#define PPC_INST_FSEL 1791 +#define PPC_INST_FRE 1792 +#define PPC_INST_FMUL 1793 +#define PPC_INST_FM 1794 +#define PPC_INST_FRSQRTE 1795 +#define PPC_INST_FMSUB 1796 +#define PPC_INST_FMS 1797 +#define PPC_INST_FMADD 1798 +#define PPC_INST_FMA 1799 +#define PPC_INST_FNMSUB 1800 +#define PPC_INST_FNMS 1801 +#define PPC_INST_FNMADD 1802 +#define PPC_INST_FNMA 1803 +#define PPC_INST_FCMPO 1804 +#define PPC_INST_DMULQ 1805 +#define PPC_INST_DRRNDQ 1806 +#define PPC_INST_MTFSB1 1807 +#define PPC_INST_FNEG 1808 +#define PPC_INST_MCRFS 1809 +#define PPC_INST_DSCLIQ 1810 +#define PPC_INST_DQUAIQ 1811 +#define PPC_INST_MTFSB0 1812 +#define PPC_INST_FMR 1813 +#define PPC_INST_DSCRIQ 1814 +#define PPC_INST_DRINTXQ 1815 +#define PPC_INST_DCMPOQ 1816 +#define PPC_INST_MTFSFI 1817 +#define PPC_INST_FNABS 1818 +#define PPC_INST_DTSTEXQ 1819 +#define PPC_INST_DTSTDCQ 1820 +#define PPC_INST_DTSTDGQ 1821 +#define PPC_INST_DRINTNQ 1822 +#define PPC_INST_DCTQPQ 1823 +#define PPC_INST_FABS 1824 +#define PPC_INST_DCTFIXQ 1825 +#define PPC_INST_DDEDPDQ 1826 +#define PPC_INST_DXEXQ 1827 +#define PPC_INST_FRIN 1828 +#define PPC_INST_FRIZ 1829 +#define PPC_INST_FRIP 1830 +#define PPC_INST_FRIM 1831 +#define PPC_INST_DSUBQ 1832 +#define PPC_INST_DDIVQ 1833 +#define PPC_INST_MFFS 1834 +#define PPC_INST_DCMPUQ 1835 +#define PPC_INST_DTSTSFQ 1836 +#define PPC_INST_MTFSF 1837 +#define PPC_INST_DRDPQ 1838 +#define PPC_INST_DCFFIXQ 1839 +#define PPC_INST_FCTID 1840 +#define PPC_INST_FCTIDZ 1841 +#define PPC_INST_DENBCDQ 1842 +#define PPC_INST_FCFID 1843 +#define PPC_INST_DIEXQ 1844 +#define PPC_INST_VUPKHSH128 1845 +#define PPC_INST_VUPKLSH128 1846 diff --git a/thirdparty/disasm/ppc.h b/thirdparty/disasm/ppc.h new file mode 100644 index 0000000..a425c98 --- /dev/null +++ b/thirdparty/disasm/ppc.h @@ -0,0 +1,38 @@ +#pragma once +#include "ppc-inst.h" + +/* A macro to extract the major opcode from an instruction. */ +#define PPC_OP(i) (((i) >> 26) & 0x3f) + +/* A macro to extract the extended opcode from an instruction. */ +#define PPC_XOP(i) (((i) >> 1) & 0x3ff) + +/* A macro to extract the branch destination from a conditional instruction. */ +#define PPC_BD(i) ((signed int)((((i) & 0xFFFC) ^ 0x8000) - 0x8000)) + +/* A macro to extract the branch destination from an immediate instruction. */ +#define PPC_BI(i) ((signed int)((((i) & 0x3FFFFFC) ^ 0x2000000) - 0x2000000)) + +/* A macro to extract whether the branch is absolute. */ +#define PPC_BA(i) (!!((i) & 2)) + +/* A macro to extract whether the branch is a link. */ +#define PPC_BL(i) (!!((i) & 1)) + +/* A macro to extract the branch operation of an instruction. */ +#define PPC_BO(i) (((i) >> 21) & 0x1F) + +#define PPC_OP_TDI 2 +#define PPC_OP_TWI 3 +#define PPC_OP_MULLI 7 +#define PPC_OP_SUBFIC 8 +#define PPC_OP_CMPLI 0xA +#define PPC_OP_CMPI 0xB +#define PPC_OP_ADDIC 0xC // addic +#define PPC_OP_ADDICR 0xD // addic. +#define PPC_OP_ADDI 0xE +#define PPC_OP_ADDIS 0xF +#define PPC_OP_BC 0x10 +#define PPC_OP_SC 0x11 +#define PPC_OP_B 0x12 +#define PPC_OP_CTR 0x13 diff --git a/thirdparty/disruptorplus/include/disruptorplus/blocking_wait_strategy.hpp b/thirdparty/disruptorplus/include/disruptorplus/blocking_wait_strategy.hpp new file mode 100644 index 0000000..32d427d --- /dev/null +++ b/thirdparty/disruptorplus/include/disruptorplus/blocking_wait_strategy.hpp @@ -0,0 +1,205 @@ +#ifndef DISRUPTORPLUS_BLOCKING_WAIT_STRATEGY_HPP_INCLUDED +#define DISRUPTORPLUS_BLOCKING_WAIT_STRATEGY_HPP_INCLUDED + +#include "sequence.hpp" + +#include +#include +#include +#include +#include + +namespace disruptorplus +{ + /// \brief + /// A wait_strategy that blocks waiting threads using a until the respective + /// sequence barriers have reached the desired sequence number using a + /// condition-variable. + /// + /// All currently blocked threads will be woken when any sequence + /// barrier publishes a new sequence regardless of whether those + /// threads are currently waiting on that sequence barrier or not. + /// + /// This strategy is CPU efficient for cases where there may + /// be long periods of inactivity when either producer or consumer + /// threads are starved, but has the downside of using kernel + /// calls which can introduce uncertainty in processing latency. + class blocking_wait_strategy + { + public: + + /// \brief + /// Initialise the synchronisation resources used by the wait strategy. + /// + /// \throw std::system_error + /// If unable to initialise the resources. + blocking_wait_strategy() + {} + + /// \brief + /// Wait unconditionally until all of the specified sequences + /// have at least published the specified sequence value. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \param count + /// The number of elements in \p sequences. + /// Must be greater than zero. + /// + /// \param sequences + /// An array of \p count pointers to sequence values. + /// The call will not return until all of these values have advanced + /// beyond the specified \p sequence. + /// + /// \return + /// The value of the least-advanced sequence. + /// This value is guaranteed to be at least \p sequence. + /// + /// \throw std::system_error + /// If the system does not have enough resources to perform this operation. + sequence_t wait_until_published( + sequence_t sequence, + size_t count, + const std::atomic* const sequences[]) + { + assert(count > 0); + sequence_t result; + { + std::unique_lock lock(m_mutex); + m_cv.wait(lock, [&]() -> bool { + result = minimum_sequence_after(sequence, count, sequences); + return difference(result, sequence) >= 0; + }); + } + return result; + } + + /// \brief + /// Wait until either all of the specified sequences have at least + /// published the specified sequence value or a timeout is reached. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \param count + /// The number of elements in \p sequences. + /// Must be greater than zero. + /// + /// \param sequences + /// An array of \p count pointers to sequence values. + /// The call will wait until all of these sequence values have + /// published a sequence number at or after the specified + /// \p sequence number. + /// + /// \param timeout + /// The maximum amount of time to wait for the \p sequences + /// numbers to advance to \p sequence. + /// + /// \return + /// If the operation timed out then returns some number such + /// that difference(result, sequence) < 0, otherwise + /// returns the least-advanced of all the sequence values read + /// from \p sequences, which is guaranteed to satisfy + /// difference(result, sequence) >= 0. + /// + /// \throw std::system_error + /// If the system does not have enough resources to perform this operation. + template + sequence_t wait_until_published( + sequence_t sequence, + size_t count, + const std::atomic* const sequences[], + const std::chrono::duration& timeout) + { + assert(count > 0); + sequence_t result; + { + std::unique_lock lock(m_mutex); + m_cv.wait_for( + lock, + [&]() -> bool { + result = minimum_sequence_after(sequence, count, sequences); + return difference(result, sequence) >= 0; + }, + timeout); + } + return result; + } + + /// \brief + /// Wait until either all of the specified sequences have at least + /// published the specified sequence value or a timeout time is reached. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \param count + /// The number of elements in \p sequences. + /// Must be greater than zero. + /// + /// \param sequences + /// An array of \p count pointers to sequence values. + /// The call will wait until all of these sequence values have + /// published a sequence number at or after the specified + /// \p sequence number. + /// + /// \param timeoutTime + /// The time to wait until for the \p sequences numbers to + /// advance to \p sequence. The operation will timeout after + /// this point in time. + /// + /// \return + /// If the operation timed out then returns some number such + /// that difference(result, sequence) < 0, otherwise + /// returns the least-advanced of all the sequence values read + /// from \p sequences, which is guaranteed to satisfy + /// difference(result, sequence) >= 0. + /// + /// \throw std::system_error + /// If the system does not have enough resources to perform this operation. + template + sequence_t wait_until_published( + sequence_t sequence, + size_t count, + const std::atomic* const sequences[], + const std::chrono::time_point& timeoutTime) + { + assert(count > 0); + sequence_t result; + { + std::unique_lock lock(m_mutex); + m_cv.wait_until( + lock, + [&]() -> bool { + result = minimum_sequence_after(sequence, count, sequences); + return difference(result, sequence) >= 0; + }, + timeoutTime); + } + return result; + } + + /// \brief + /// Notify any waiting threads that one of the sequence values has changed. + /// + /// Wakes all waiting threads so they can re-check whether their target + /// sequence numbers are now satisfied. + void signal_all_when_blocking() + { + // Take out a lock here because we don't want to notify other threads + // if they are between checking the sequence values and waiting on + // the condition-variable. + std::unique_lock lock(m_mutex); + m_cv.notify_all(); + } + + private: + + std::mutex m_mutex; + std::condition_variable m_cv; + + }; +} + +#endif diff --git a/thirdparty/disruptorplus/include/disruptorplus/config.hpp b/thirdparty/disruptorplus/include/disruptorplus/config.hpp new file mode 100644 index 0000000..3d4cf02 --- /dev/null +++ b/thirdparty/disruptorplus/include/disruptorplus/config.hpp @@ -0,0 +1,19 @@ +#ifndef DISRUPTORPLUS_CONFIG_HPP_INCLUDED +#define DISRUPTORPLUS_CONFIG_HPP_INCLUDED + +#include + +namespace disruptorplus +{ + /// \brief + /// The expected size of a cache-line in bytes. + /// + /// Some data structures are padded according to this value to + /// ensure certain data members do not share a cache line with + /// other data in order to reduce the problem of false-sharing. + /// + /// The value of 64 bytes is typical for x86/x64 architectures. + const size_t CacheLineSize = 64; +} + +#endif diff --git a/thirdparty/disruptorplus/include/disruptorplus/multi_threaded_claim_strategy.hpp b/thirdparty/disruptorplus/include/disruptorplus/multi_threaded_claim_strategy.hpp new file mode 100644 index 0000000..ae540ea --- /dev/null +++ b/thirdparty/disruptorplus/include/disruptorplus/multi_threaded_claim_strategy.hpp @@ -0,0 +1,572 @@ +#ifndef DISRUPTORPLUS_MULTI_THREADED_CLAIM_STRATEGY_HPP_INCLUDED +#define DISRUPTORPLUS_MULTI_THREADED_CLAIM_STRATEGY_HPP_INCLUDED + +#include "config.hpp" +#include "sequence_barrier.hpp" +#include "sequence_barrier_group.hpp" +#include "sequence_range.hpp" + +#include +#include +#include + +namespace disruptorplus +{ + /// \brief + /// A claim strategy for slots in a ring buffer where there are multiple + /// producer threads all concurrently trying to write items to the ring + /// buffer. + /// + /// When a writer wants to write to a slot in the queue it first atomically + /// increments a counter by the number of slots it wishes to allocate. + /// It then waits until all of those slots have become available and then + /// returns the range of sequence numbers allocated back to the caller. + /// The caller then writes to those slots and when done publishes them + /// by writing the sequence numbers published to each of the slots to + /// the corresponding element of an array of equal size to the ring buffer. + /// When a reader wants to check if the next sequence number is available + /// it them simply needs to read from the corresponding slot in this array + /// to check if the value stored there is equal to the sequence number it + /// is wanting to read. + /// + /// This means concurrent writers are wait-free when there is space available + /// in the ring buffer, requiring a single atomic fetch-add operation as the + /// only contended write operation. All other writes are to memory locations + /// owned by a particular writer. Concurrent writers can publish items + /// out-of-order so that one writer does not hold up other writers until the + /// ring buffer fills up. + /// + /// \tparam WaitStrategy + /// The type of wait-strategy object to use to block threads when waiting + /// for sequence numbers to be published. + /// + /// \see single_threaded_claim_strategy + /// For an alternative implementation of a claim strategy where only one + /// thread is publishing items to the ring buffer. + template + class multi_threaded_claim_strategy + { + public: + + /// \brief + /// Initialise a new claim strategy. + /// + /// \param bufferSize + /// The number of elements in the ring buffer. + /// Must be a power of two. + /// + /// \param waitStrategy + /// The wait strategy to use when waiting for sequence numbers to + /// be published. + multi_threaded_claim_strategy( + size_t bufferSize, + WaitStrategy& waitStrategy) + : m_indexMask(bufferSize - 1) + , m_bufferSize(bufferSize) + , m_waitStrategy(waitStrategy) + , m_claimBarrier(waitStrategy) + , m_published(new std::atomic[bufferSize]) + , m_nextClaimable(0) + { + // bufferSize must be power-of-two + assert(m_bufferSize > 0 && (m_bufferSize & (m_bufferSize - 1)) == 0); + + // Initialise the buffer such that sequences before 0 have already + // been published. + for (sequence_t i = 0; i < bufferSize; ++i) + { + m_published[i].store(static_cast(i - bufferSize), std::memory_order_relaxed); + } + } + + /// \brief + /// The number of elements in the ring-buffer. + /// + /// This will always be a power-of-two. + size_t buffer_size() const { return m_bufferSize; } + + /// \brief + /// Add a sequence barrier for claiming slots in the ring buffer. + /// + /// Add a sequence barrier that prevents elements of the ring buffer from + /// being claimed by writers until the reader has indicated the slot is + /// available by publishing the sequence number they have finished reading. + /// Claimed slots will never advance more than buffer_size() ahead + /// of any of the registered claim barriers. + /// + /// \param barrier + /// The sequence barrier to add. + /// A reference to the sequence barrier is held by the claim strategy + /// so the caller must ensure the lifetime of the sequence barrier + /// exceeds that of the cliam strategy. + /// This barrier must have been constructed with the same wait strategy object + /// as the claim strategy was constructed with. + /// \note + /// This operation is not thread-safe and the caller must ensure that no other + /// threads are accessing the claim strategy concurrently with this call. + void add_claim_barrier(sequence_barrier& barrier) + { + m_claimBarrier.add(barrier); + } + + /// \brief + /// Add a sequence barrier group for claiming slots in the ring buffer. + /// + /// Adds sequence barriers that prevent elements of the ring buffer from + /// being claimed by writers until the readers have indicated the slot is + /// available by publishing the sequence number they have finished reading. + /// Claimed slots will never advance more than buffer_size() ahead + /// of any of the registered claim barriers. + /// + /// \param barrier + /// The sequence barriers to add. + /// A reference to each sequence barrier in the group is held by the claim + /// strategy, so the caller must ensure the lifetime of the sequence barriers + /// exceed that of the cliam strategy. + /// This barrier must have been constructed with the same wait strategy object + /// as the claim strategy was constructed with. + /// + /// \note + /// This operation is not thread-safe and the caller must ensure that no other + /// threads are accessing the claim strategy concurrently with this call. + void add_claim_barrier(sequence_barrier_group& barrier) + { + m_claimBarrier.add(barrier); + } + + /// \brief + /// Claim a single slot in the ring buffer for writing to. + /// + /// Blocks the caller until a slot is available. + /// + /// The caller must call \ref publish(sequence_t) once it has + /// finished writing to the slot to publish the item to readers. + /// + /// \return + /// The sequence number of the slot claimed. + sequence_t claim_one() + { + sequence_t sequence = m_nextClaimable.fetch_add(1, std::memory_order_relaxed); + m_claimBarrier.wait_until_published( + static_cast(sequence - m_bufferSize)); + return sequence; + } + + /// \brief + /// Claim up to \p count consecutive slots in the ring buffer. + /// + /// Blocks the caller until items are available. + /// Will allocate at most \ref buffer_size() slots in the ring buffer. + /// + /// This operation has 'acquire' memory semantics. + /// + /// \param count + /// The maximum number of slots to claim. + /// + /// \return + /// A sequence range indicating the sequence numbers that were claimed. + /// This sequence range may contain less items than requested but will + /// contain at least one slot if \p count is non-zero. + sequence_range claim(size_t count) + { + count = std::min(count, m_bufferSize); + sequence_t sequence = m_nextClaimable.fetch_add(count, std::memory_order_relaxed); + sequence_range range(sequence, count); + m_claimBarrier.wait_until_published( + static_cast(range.last() - m_bufferSize)); + return range; + } + + /// \brief + /// Attempt to claim up to \p count slots in the ring buffer without blocking. + /// + /// This operation has 'acquire' memory semantics. + /// + /// \param count + /// The maximum number of slots to claim. + /// + /// \param range [out] + /// If any slots were claimed then this variable is populated with the + /// range of sequence numbers that were claimed. If no slots were claimed + /// then the value is left unchanged. + /// + /// \return + /// Returns \c true if any elements were claimed in which case the range of + /// slots claimed is written to the \p range out-parameter. May claim less + /// slots than requested if fewer slots were available. + /// Returns \c false if no elements were claimed. The \p range out-parameter is + /// not modified in this case. + bool try_claim(size_t count, sequence_range& range) + { + sequence_t published = + static_cast(m_claimBarrier.last_published() + m_bufferSize); + + sequence_t sequence = m_nextClaimable.load(std::memory_order_relaxed); + do + { + sequence_diff_t diff = difference(published, sequence); + if (diff < 0) + { + return false; + } + count = std::min(count, static_cast(diff + 1)); + } while (!m_nextClaimable.compare_exchange_weak( + sequence, + static_cast(sequence + count), + std::memory_order_relaxed, + std::memory_order_relaxed)); + + range = sequence_range(sequence, count); + return true; + } + + /// \brief + /// Attempt to claim up to \p count slots in the ring buffer. + /// + /// Blocks the caller until either at least one slot was claimed or until + /// the specified timeout period has elapsed, whichever comes first. + /// + /// This operation has 'acquire' memory semantics. + /// + /// \param count + /// The maximum number of slots to claim. + /// + /// \param range [out] + /// Receives the range of sequence numbers claimed if the operation succeeds. + /// Value is left unchanged if no slots were claimed. + /// + /// \param timeout + /// The maximum time to wait for claiming any slots. + /// + /// \return + /// Returns \c true if any slots were claimed in which case the range + /// of slots claimed is written to the \p range out-parameter. + /// Returns \c false if the timeout duration was exceeded without + /// claiming any slots. + /// + /// \throw std::exception + /// May throw any exception thrown by WaitStrategy::wait_until_published(). + template + bool try_claim_for( + size_t count, + sequence_range& range, + const std::chrono::duration& timeout) + { + return try_claim_until( + count, + range, + std::chrono::high_resolution_clock::now() + timeout); + } + + /// \brief + /// Attempt to claim up to \p count slots in the ring buffer. + /// + /// Blocks the caller until either at least one slot was claimed or until + /// the specified timeout period has elapsed, whichever comes first. + /// + /// This operation has 'acquire' memory semantics. + /// + /// \param count + /// The maximum number of slots to claim. + /// + /// \param range [out] + /// Receives the range of sequence numbers claimed if the operation succeeds. + /// Value is left unchanged if no slots were claimed. + /// + /// \param timeoutTime + /// The time after which the call should stop waiting for available slots. + /// + /// \return + /// Returns \c true if any slots were claimed in which case the range + /// of slots claimed is written to the \p range out-parameter. + /// Returns \c false if the timeout duration was exceeded without + /// claiming any slots. + /// + /// \throw std::exception + /// May throw any exception thrown by \c Clock::now() or + /// \c WaitStrategy::wait_until_published(). + template + bool try_claim_until( + size_t count, + sequence_range& range, + const std::chrono::time_point& timeoutTime) + { + sequence_t published = + static_cast(m_claimBarrier.last_published() + m_bufferSize); + + sequence_t sequence = m_nextClaimable.load(std::memory_order_relaxed); + size_t reducedCount; + do + { + sequence_diff_t diff = difference(published, sequence); + if (diff < 0) + { + published = static_cast( + m_claimBarrier.wait_until_published( + static_cast(sequence - m_bufferSize), + timeoutTime) + m_bufferSize); + diff = difference(published, sequence); + if (diff < 0) + { + // Timeout + return false; + } + } + reducedCount = std::min(count, static_cast(diff + 1)); + } while (!m_nextClaimable.compare_exchange_weak( + sequence, + static_cast(sequence + reducedCount), + std::memory_order_relaxed, + std::memory_order_relaxed)); + + range = sequence_range(sequence, reducedCount); + + return true; + } + + /// \brief + /// Publish an element written to a slot in the ring buffer, + /// signalling that the element is available to be accessed by + /// reader threads. + /// + /// A reader will not be notified that this element is available + /// until all other sequences prior to this element have also + /// been published. + /// + /// A writer must call this method when they have finished + /// writing data to the ring-buffer element they previously + /// claimed by calling one of the 'claim' methods above. + /// + /// This operation has 'release' memory semantics. + /// + /// \note + /// The meaning of this method is slightly different from that + /// of the \ref single_threaded_claim_strategy::publish(sequence_t) method. + /// As multiple threads may publish elements out of order, every + /// sequence number must be published, whereas for the single-threaded + /// claim strategy it is assumed that all prior sequences have already + /// been published when publishing the next sequence. + /// + /// \param sequence + /// The sequence number of the element being published. + /// + /// \throw std::exception + /// Throws any exception thrown by WaitStrategy::signal_all_when_blocking(). + void publish(sequence_t sequence) + { + set_published(sequence); + m_waitStrategy.signal_all_when_blocking(); + } + + /// \brief + /// Publish a sequence of elements written to slots in the ring buffer, + /// signalling that the elements are available to be accessed by + /// reader threads. + /// + /// A reader will not be notified that these elements are available + /// until all other sequences prior to these elements have also + /// been published. + /// + /// A writer must call this method when they have finished + /// writing data to the ring-buffer elements they previously + /// claimed by calling one of the 'claim' methods above. + /// + /// This operation has 'release' memory semantics. + /// + /// \param range + /// The range of sequence numbers to publish. + /// + /// \throw std::exception + /// Throws any exception thrown by WaitStrategy::signal_all_when_blocking(). + void publish(const sequence_range& range) + { + for (size_t i = 0, j = range.size(); i < j; ++i) + { + set_published(range[i]); + } + m_waitStrategy.signal_all_when_blocking(); + } + + /// \brief + /// Return the highest sequence number published after the specified + /// last-known published sequence. + /// + /// \param lastKnownPublished + /// This sequence number is assumed to have already been published. + /// The initial value passed in here on first call should be sequence_t(-1). + /// + /// \return + /// The last-published sequence number. + /// This will be equal to \p lastKnownPublished if no additional sequences + /// have been published. + sequence_t last_published_after(sequence_t lastKnownPublished) const + { + sequence_t seq = lastKnownPublished + 1; + while (is_published(seq)) + { + lastKnownPublished = seq; + ++seq; + } + return lastKnownPublished; + } + + /// \brief + /// Block the caller until the specified sequence number has been + /// published. + /// + /// This method is called by reader threads waiting to consume + /// items written to the ring buffer. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \param lastKnownPublished + /// This sequence number is assumed to have already been published. + /// The initial value passed in here on first call should be sequence_t(-1). + /// + /// \return + /// Returns the sequence number of the latest available published + /// sequence, guaranteed to be equal to or later than the specified + /// \p sequence parameter. + /// + /// \throw std::exception + /// Throws any exception thrown by \c WaitStrategy::wait_until_published(). + sequence_t wait_until_published( + sequence_t sequence, + sequence_t lastKnownPublished) const + { + assert(difference(sequence, lastKnownPublished) > 0); + + for (sequence_t seq = lastKnownPublished + 1; + difference(seq, sequence) <= 0; + ++seq) + { + if (!is_published(seq)) + { + const std::atomic* const sequences[1] = + { &m_published[seq & m_indexMask] }; + m_waitStrategy.wait_until_published(seq, 1, sequences); + } + } + return last_published_after(sequence); + } + + /// \brief + /// Block the caller until the specified sequence number has been + /// published or until a specified timeout has elapsed. + /// + /// This method is called by reader threads waiting to consume + /// items written to the ring buffer. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \param lastKnownPublished + /// This sequence number is assumed to have already been published. + /// The initial value passed in here on first call should be sequence_t(-1). + /// + /// \param timeout + /// The maximum time to wait for the sequence number to be published. + /// + /// \return + /// Returns the sequence number of the latest available published + /// element. If this value is prior to the requested \p sequence + /// number then the operation timed-out before the sequence + /// was published. + template + sequence_t wait_until_published( + sequence_t sequence, + sequence_t lastKnownPublished, + const std::chrono::duration& timeout) const + { + return wait_until_published( + sequence, + lastKnownPublished, + std::chrono::high_resolution_clock::now() + timeout); + } + + /// \brief + /// Block the caller until the specified sequence number has been + /// published or until a specified timeout has elapsed. + /// + /// This method is called by reader threads waiting to consume + /// items written to the ring buffer. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \param lastKnownPublished + /// This sequence number is assumed to have already been published. + /// The initial value passed in here on first call should be sequence_t(-1). + /// + /// \param timeoutTime + /// The time after which the operation should cease blocking the caller + /// if the sequence number has not yet been published. + /// + /// \return + /// Returns the sequence number of the latest available published + /// element. If this value is prior to the requested \p sequence + /// number then the operation timed-out before the sequence + /// was published. + template + sequence_t wait_until_published( + sequence_t sequence, + sequence_t lastKnownPublished, + const std::chrono::time_point& timeoutTime) const + { + assert(difference(sequence, lastKnownPublished) > 0); + + for (sequence_t seq = lastKnownPublished + 1; + difference(seq, sequence) <= 0; + ++seq) + { + if (!is_published(seq)) + { + const std::atomic* const sequences[1] = + { &m_published[seq & m_indexMask] }; + sequence_t result = + m_waitStrategy.wait_until_published(seq, 1, sequences, timeoutTime); + if (difference(result, seq) < 0) + { + // Timeout. seq is the first non-published sequence + return seq - 1; + } + } + } + return last_published_after(sequence); + } + + private: + + bool is_published(sequence_t sequence) const + { + return m_published[sequence & m_indexMask].load(std::memory_order_acquire) == sequence; + } + + void set_published(sequence_t sequence) + { + auto& entry = m_published[sequence & m_indexMask]; + assert(entry.load(std::memory_order_relaxed) == static_cast(sequence - m_bufferSize)); + entry.store(sequence, std::memory_order_release); + } + + const sequence_t m_indexMask; + const size_t m_bufferSize; + + WaitStrategy& m_waitStrategy; + + sequence_barrier_group m_claimBarrier; + + const std::unique_ptr[]> m_published; + + // Since this m_nextClaimable is going to be written to by multiple + // threads, we don't want false sharing with m_published or other + // variables that occur after it in the heap/stack. + uint8_t m_pad0[CacheLineSize - sizeof(sequence_t)]; + std::atomic m_nextClaimable; + uint8_t m_pad1[CacheLineSize - sizeof(sequence_t)]; + + }; +} + +#endif diff --git a/thirdparty/disruptorplus/include/disruptorplus/ring_buffer.hpp b/thirdparty/disruptorplus/include/disruptorplus/ring_buffer.hpp new file mode 100644 index 0000000..e6d82c0 --- /dev/null +++ b/thirdparty/disruptorplus/include/disruptorplus/ring_buffer.hpp @@ -0,0 +1,104 @@ +#ifndef DISRUPTORPLUS_RING_BUFFER_HPP_INCLUDED +#define DISRUPTORPLUS_RING_BUFFER_HPP_INCLUDED + +#include "sequence.hpp" + +#include +#include + +namespace disruptorplus +{ + /// \brief + /// A ring buffer is a buffer of size power-of-two that can + /// be indexed using a sequence number. + /// + /// A given slot, \c i, in the ring buffer is addressed by any sequence + /// number that has the form n * size() + i for some \c n. + /// + /// A ring buffer is typically used in conjunction with a claim-strategy + /// for writers to claim a slot in the ring buffer, and one or more + /// sequence-barriers for readers to indicate where in the ring buffer + /// they have processed up to. + /// + /// \tparam T + /// The type of elements the ring buffer. + /// This type must be default-constructible. + template + class ring_buffer + { + public: + + /// \brief + /// The type of elements in the ring buffer. + typedef T value_type; + + /// \brief + /// A type that is a reference to a ring buffer element. + typedef T& reference; + + /// \brief + /// A type that is a const-reference to a ring buffer element. + typedef const T& const_reference; + + /// \brief + /// Constructs a ring buffer of a specified size. + /// + /// Allocates the buffer on the heap and default-constructs all + /// elements of the buffer. + /// + /// \param size + /// The desired size of the ring buffer. + /// Must be a power of two, eg. 16384. + /// + /// \throws std::bad_alloc + /// If there was insufficient memory to allocate the buffer. + ring_buffer(size_t size) + : m_size(size) + , m_mask(size - 1) + , m_data(new T[size]) + { + // Check that size was a power-of-two. + assert(m_size > 0 && (m_size & m_mask) == 0); + } + + /// \brief + /// The number of elements in the ring buffer. + /// + /// This will always be a power-of-two. + size_t size() const + { + return m_size; + } + + /// \brief + /// Obtain a reference to the ring buffer element corresponding to the specified + /// sequence number. + /// + /// \param seq + /// The sequence number of the item in the ring buffer. + /// The slot in the ring buffer is calculated as the sequence number + /// modulo \ref size(). + reference operator[](sequence_t seq) + { + return m_data[static_cast(seq) & m_mask]; + } + + /// \copydoc ring_buffer::operator[](sequence_t) + const_reference operator[](sequence_t seq) const + { + return m_data[static_cast(seq) & m_mask]; + } + + private: + + // Disable copy-construction + ring_buffer(const ring_buffer&); + + const size_t m_size; + const size_t m_mask; + std::unique_ptr m_data; + + }; +} + +#endif diff --git a/thirdparty/disruptorplus/include/disruptorplus/sequence.hpp b/thirdparty/disruptorplus/include/disruptorplus/sequence.hpp new file mode 100644 index 0000000..b8cfa4a --- /dev/null +++ b/thirdparty/disruptorplus/include/disruptorplus/sequence.hpp @@ -0,0 +1,140 @@ +#ifndef DISRUPTORPLUS_SEQUENCE_HPP_INCLUDED +#define DISRUPTORPLUS_SEQUENCE_HPP_INCLUDED + +#include +#include +#include +#include + +/// \file +/// \brief +/// Defines typedefs and utility functions relating to sequence numbers. +/// +/// Sequence numbers are a central concept in Disruptor++ as sequence numbers +/// are used to indicate the order that items were added to a ring buffer +/// and hence their location in the ring buffer. +/// +/// Sequence numbers can overflow back to zero so all comparisons of sequence +/// numbers need to take this into account by calling the +/// \ref disruptorplus::difference(sequence_t,sequence_t) function. + +/// \brief +/// The \ref disruptorplus namespace provides abstractions that implement the +/// Disruptor data structure for multi-threaded producer/consumer queues. +namespace disruptorplus +{ + /// \brief + /// Integer type used to represent sequence number of an item + /// added to a ring buffer. + /// + /// The first item added to a ring buffer always has a sequence number + /// of zero, with the second item having a sequence number of 1, etc. + /// Sequence numbers wrap around back to zero when they overflow. + typedef uint64_t sequence_t; + + /// \typedef sequence_diff_t + /// \brief + /// Integer type used to represent the difference between two + /// \ref sequence_t values. + typedef int64_t sequence_diff_t; + + /// \brief + /// Calculate the difference between two sequence numbers. + /// + /// Use this function to determine the relative order of two sequence + /// numbers rather than just using \p a < \p b to handle the case where + /// sequence numbers overflow back to zero. + /// + /// \param a The first sequence number. + /// \param b The second sequence number. + /// \return + /// The difference between \p a and \p b. ie. (a - b). + /// This value will be <0 if \p a precedes \p b, 0 if \p a == \p b, + /// >0 if \p b precedes \p a. + inline sequence_diff_t difference(sequence_t a, sequence_t b) + { + return static_cast(a - b); + } + + /// \brief + /// Calculate the minimum sequence number of an array of sequences. + /// + /// Calculates the minimum sequence number of the array of sequences + /// taking into account any overflowed sequence numbers by using the + /// first sequence as the zero-point. + /// + /// This assumes no two active sequence values will be more than + /// (1 << (sizeof(sequence_t) * 8 - 2)) - 1 different from each other. + /// + /// This operation implies acquire memory semantics on each of the sequences. + /// + /// \param count + /// The number of elements in \p sequences. + /// Must be greater than zero. + /// + /// \param sequences + /// An array of pointers to sequence_t values containing the sequence + /// numbers to read. + /// + /// \return + /// The minimum sequence number read from \p sequences. + /// ie. the sequence number, \c s, such that difference(s, sequences[i]) >= 0 + /// for all \c i in \[0, count)\[. + inline sequence_t minimum_sequence( + size_t count, + const std::atomic* const sequences[]) + { + assert(count > 0); + sequence_t minimum = sequences[0]->load(std::memory_order_acquire); + for (size_t i = 1; i < count; ++i) + { + sequence_t seq = sequences[i]->load(std::memory_order_acquire); + if (difference(seq, minimum) < 0) + { + minimum = seq; + } + } + return minimum; + } + + /// \brief + /// Calculate the minimum sequence number of an array of sequences, + /// short-circuiting if any of them precede a specified sequence number. + /// + /// Calculates the minimum sequence number of the array of sequences + /// taking into account any overflowed sequence numbers by using the + /// first sequence as the zero-point. + /// + /// This assumes no two active sequence values will be more than + /// (1 << (sizeof(sequence_t) * 8 - 2)) - 1 different from each other. + /// + /// If the returned sequence number does not precede the specified + /// sequence number then this operation implies acquire memory semantics + /// on each of the sequences, otherwise the memory semantics are undefined + /// and this operation should not be used for synchronisation. + /// + /// \param minimum The minimum desired sequence number. + /// \param count The number of elements in \p sequences. + /// \param sequences An array of \p count pointers to sequence_t values to read. + /// \return + /// If no sequence numbers in \p sequences precede the \p minimum sequence + /// number then the return value is the minimum of the sequence numbers. + /// If any sequence numbers precede \p minimum then the return value is + /// one of the sequence numbers that precedes \p minimum. + inline sequence_t minimum_sequence_after( + sequence_t minimum, + size_t count, + const std::atomic* const sequences[]) + { + assert(count > 0); + sequence_diff_t minDelta = difference(sequences[0]->load(std::memory_order_acquire), minimum); + for (size_t i = 1; i < count && minDelta >= 0; ++i) + { + sequence_t seq = sequences[i]->load(std::memory_order_acquire); + minDelta = std::min(minDelta, difference(seq, minimum)); + } + return static_cast(minDelta + minimum); + } +} + +#endif diff --git a/thirdparty/disruptorplus/include/disruptorplus/sequence_barrier.hpp b/thirdparty/disruptorplus/include/disruptorplus/sequence_barrier.hpp new file mode 100644 index 0000000..61d971d --- /dev/null +++ b/thirdparty/disruptorplus/include/disruptorplus/sequence_barrier.hpp @@ -0,0 +1,211 @@ +#ifndef DISRUPTORPLUS_SEQUENCE_BARRIER_HPP_INCLUDED +#define DISRUPTORPLUS_SEQUENCE_BARRIER_HPP_INCLUDED + +#include "config.hpp" +#include "sequence.hpp" + +#include +#include + +namespace disruptorplus +{ + template + class sequence_barrier_group; + + /// \brief + /// A sequence barrier holds a sequence number that can be used to + /// publish which item has finished processing and is now available. + /// + /// The assumption is that when a sequence number is published in a + /// sequence barrier that the specified sequence number and all prior + /// sequence numbers are available for down-stream threads to consume. + /// + /// While it is only safe for a single thread to publish sequence numbers, + /// an arbitrary number of threads can wait for a sequence barrier to + /// reach a desired sequence number. + /// + /// \tparam WaitStrategy + /// A class that defines the strategy to use for blocking threads while + /// waiting for a given sequence number to be published. + /// Must implement the wait_strategy model. + template + class sequence_barrier + { + public: + + /// \brief + /// Initialise the sequence barrier. + /// + /// The sequence barrier's initial published sequence number is the + /// number immediately preceding zero. ie. the next sequence number + /// to be published is zero. + /// + /// \param waitStrategy + /// The wait strategy to use for threads waiting on this sequence barrier. + /// The constructed sequence barrier will hold a reference to this object + /// so callers must ensure the lifetime of the wait strategy exceeds that + /// of the sequence barrier. + sequence_barrier(WaitStrategy& waitStrategy) + : m_waitStrategy(waitStrategy) + , m_lastPublished(static_cast(-1)) + {} + + /// \brief + /// Query the sequence number last published to this sequence barrier. + /// + /// This operation synchronises with the corresponding call to publish() + /// and has 'acquire' memory semantics. + /// + /// \return + /// The last-published sequence number. + sequence_t last_published() const + { + return m_lastPublished.load(std::memory_order_acquire); + } + + /// \brief + /// Block the calling thread until the specified sequence number is published. + /// + /// This operation synchronises with the corresponding call to publish() + /// that publishes the returned sequence number and has 'acquire' memory + /// semantics. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \return + /// The last-published sequence number. + /// This sequence number is guaranteed to be equal to or after + /// the specified \p sequence. + /// + /// \throws std::exception + /// May throw any exception thrown by the WaitStrategy::wait_until_published() + /// function. + sequence_t wait_until_published(sequence_t sequence) const + { + sequence_t current = last_published(); + sequence_diff_t diff = difference(current, sequence); + if (diff >= 0) + { + return current; + } + const std::atomic* const sequences[] = { &m_lastPublished }; + return m_waitStrategy.wait_until_published(sequence, 1, sequences); + } + + /// \brief + /// Block the calling thread until either the specified sequence number is + /// published or a timeout has been exceeded. + /// + /// This operation synchronises with the corresponding call to publish() + /// that publishes the returned sequence number and has 'acquire' memory + /// semantics. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \param timeout + /// The maximum amount of time to wait for the sequence number to + /// be published. + /// + /// \return + /// The last-published sequence number. + /// If difference(result, sequence) >= 0 then the operation has + /// completed successfully and the requested sequence number has been + /// published. Otherwise if difference(result, sequence) < 0 then + /// the operation has timed out. + /// + /// \throws std::exception + /// May throw any exception thrown by the WaitStrategy::wait_until_published() + /// function. + template + sequence_t wait_until_published( + sequence_t sequence, + const std::chrono::duration& timeout) const + { + sequence_t current = last_published(); + sequence_diff_t diff = difference(current, sequence); + if (diff >= 0) + { + return current; + } + const std::atomic* const sequences[] = { &m_lastPublished }; + return m_waitStrategy.wait_until_published(sequence, 1, sequences, timeout); + } + + /// \brief + /// Block the calling thread until either the specified sequence number is + /// published or a timeout time has been exceeded. + /// + /// This operation synchronises with the corresponding call to publish() + /// that publishes the returned sequence number and has 'acquire' memory + /// semantics. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \param timeoutTime + /// Wait only until this point in time. + /// + /// \return + /// The last-published sequence number. + /// If difference(result, sequence) >= 0 then the operation has + /// completed successfully and the requested sequence number has been + /// published. Otherwise if difference(result, sequence) < 0 then + /// the operation has timed out. + /// + /// \throws std::exception + /// May throw any exception thrown by the WaitStrategy::wait_until_published() + /// function. + template + sequence_t wait_until_published( + sequence_t sequence, + const std::chrono::time_point& timeoutTime) const + { + sequence_t current = last_published(); + sequence_diff_t diff = difference(current, sequence); + if (diff >= 0) + { + return current; + } + const std::atomic* const sequences[] = { &m_lastPublished }; + return m_waitStrategy.wait_until_published(sequence, 1, sequences, timeoutTime); + } + + /// \brief + /// Publish the specified sequence number. + /// + /// This indicates that all sequence numbers up to and including this + /// sequence number are available for use by down-stream operations. + /// + /// This operation synchronises with calls to any of the wait_until_published() + /// overloads that wait on the specified \p sequence. This operation has + /// 'release' memory semantics. + /// + /// \param sequence + /// The sequence number to publish. + /// + /// \throws std::exception + /// May throw any exception thrown by the WaitStrategy::signal_all_when_blocking() + /// method. + void publish(sequence_t sequence) + { + m_lastPublished.store(sequence, std::memory_order_release); + m_waitStrategy.signal_all_when_blocking(); + } + + private: + + friend class sequence_barrier_group; + + WaitStrategy& m_waitStrategy; + + // Pad before/after to prevent false-sharing + uint8_t m_pad1[CacheLineSize - sizeof(sequence_t)]; + std::atomic m_lastPublished; + uint8_t m_pad2[CacheLineSize - sizeof(sequence_t)]; + + }; +} + +#endif diff --git a/thirdparty/disruptorplus/include/disruptorplus/sequence_barrier_group.hpp b/thirdparty/disruptorplus/include/disruptorplus/sequence_barrier_group.hpp new file mode 100644 index 0000000..c4b770c --- /dev/null +++ b/thirdparty/disruptorplus/include/disruptorplus/sequence_barrier_group.hpp @@ -0,0 +1,223 @@ +#ifndef DISRUPTORPLUS_SEQUENCE_BARRIER_GROUP_HPP_INCLUDED +#define DISRUPTORPLUS_SEQUENCE_BARRIER_GROUP_HPP_INCLUDED + +#include "sequence.hpp" +#include "sequence_barrier.hpp" + +#include +#include +#include + +namespace disruptorplus +{ + /// \brief + /// A sequence barrier group holds a collection of sequence barriers + /// that can be used to wait until all of the sequence barriers have + /// published a given sequence number. + /// + /// This can be used when one consumer in the processing pipeline must + /// wait until multiple prior consumers in the processing pipeline have + /// completed processing an item before starting to process that item. + /// + /// \tparam WaitStrategy + /// A class that defines the strategy to use for blocking threads while + /// waiting for a given sequence number to be published. + /// Must implement the wait_strategy model. + template + class sequence_barrier_group + { + public: + + /// \brief + /// Initialise the sequence barrier group to the empty set of sequence barriers. + /// + /// \note + /// You must add some \ref sequence_barrier items to this + /// sequence barrier group before you can wait on it. + /// + /// \param waitStrategy + /// The wait strategy to use for threads waiting on this sequence barrier group. + /// The constructed sequence barrier will hold a reference to this object + /// so callers must ensure the lifetime of the wait strategy exceeds that + /// of the sequence barrier group. + sequence_barrier_group(WaitStrategy& waitStrategy) + : m_waitStrategy(waitStrategy) + {} + + /// \brief + /// Add a sequence barrier to the group. + /// + /// This operation is not thread-safe and must be called prior + /// to sharing this object for use on multiple threads. + /// + /// The sequence barrier group holds onto a reference to the sequence + /// barrier, so the passed barrier's lifetime must exceed that of the + /// sequence barrier. + /// + /// \param barrier + /// The sequence barrier to add to the group. + /// This barrier must have been constructed with the same wait strategy + /// object that this sequence barrier group was constructed with. + /// + /// \throw std::bad_alloc + /// If there was insufficient memory to add the sequence barriers to + /// the group. + void add(const sequence_barrier& barrier) + { + assert(&barrier.m_waitStrategy == &m_waitStrategy); + m_sequences.push_back(&barrier.m_lastPublished); + } + + /// \brief + /// Add all sequence barriers in another group to this group. + /// + /// This operation is not thread-safe and must be called prior + /// to sharing this object for use on multiple threads. + /// + /// The sequence barrier group holds onto a reference to all + /// sequence barriers added to it, so the passed sequence barriers' + /// lifetimes must exceed that of the sequence barrier. + /// + /// \param barrierGroup + /// The sequence barrier group to add to the group. + /// All sequence barriers added to the specified group at the time + /// this call is made are added to this group. + /// + /// \throw std::bad_alloc + /// If there was insufficient memory to add the sequence barriers to + /// the group. + void add(const sequence_barrier_group& barrierGroup) + { + m_sequences.insert( + m_sequences.end(), + barrierGroup.m_sequences.begin(), + barrierGroup.m_sequences.end()); + } + + /// \brief + /// Query the sequence number of the least-advanced sequence barrier + /// in the group. + sequence_t last_published() const + { + assert(!m_sequences.empty()); + return minimum_sequence(m_sequences.size(), m_sequences.data()); + } + + /// \brief + /// Block the calling thread until all sequence barriers in the group + /// have advanced to at least the specified sequence. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \return + /// The sequence number of the least-advanced sequence in the group. + /// This is guaranteed to satisfy difference(result, sequence) >= 0. + /// + /// \throw std::exception + /// Can throw any exception thrown by the associated + /// \c WaitStrategy::wait_until_published() method. + sequence_t wait_until_published(sequence_t sequence) const + { + assert(!m_sequences.empty()); + + size_t count = m_sequences.size(); + + sequence_t current = minimum_sequence_after(sequence, count, m_sequences.data()); + if (difference(current, sequence) >= 0) + { + return current; + } + + return m_waitStrategy.wait_until_published(sequence, count, m_sequences.data()); + } + + /// \brief + /// Block the calling thread until either all sequence barriers in + /// the group had advanced to at least the specified sequence or + /// a timeout has elapsed. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \param timeout + /// The maximum time to block the thread for. + /// Note the thread may be blocked for slightly more or less than + /// this time depending on operating system thread scheduling. + /// + /// \return + /// If the requested \p sequence number was published by all barriers + /// then returns the sequence number of the least-advanced of the + /// sequence barriers in the group. Otherwise, if the operation timed + /// out then returns some sequence number prior to \p sequence. + /// + /// \throw std::exception + /// Can throw any exception thrown by the associated + /// \c WaitStrategy::wait_until_published() method. + template + sequence_t wait_until_published( + sequence_t sequence, + const std::chrono::duration& timeout) const + { + assert(!m_sequences.empty()); + + size_t count = m_sequences.size(); + + sequence_t current = minimum_sequence_after(sequence, count, m_sequences.data()); + if (difference(current, sequence) >= 0) + { + return current; + } + + return m_waitStrategy.wait_until_published(sequence, count, m_sequences.data(), timeout); + } + + /// \brief + /// Block the calling thread until either all sequence barriers in + /// the group had advanced to at least the specified sequence or + /// a timeout time has passed. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \param timeoutTime + /// The time after which this operation times out. + /// Note the thread may be blocked for slightly more or less than + /// this time depending on operating system thread scheduling. + /// + /// \return + /// If the requested \p sequence number was published by all barriers + /// then returns the sequence number of the least-advanced of the + /// sequence barriers in the group. Otherwise, if the operation timed + /// out then returns some sequence number prior to \p sequence. + /// + /// \throw std::exception + /// Can throw any exception thrown by the associated + /// \c WaitStrategy::wait_until_published() method. + template + sequence_t wait_until_published( + sequence_t sequence, + const std::chrono::time_point& timeoutTime) const + { + assert(!m_sequences.empty()); + + size_t count = m_sequences.size(); + + sequence_t current = minimum_sequence_after(sequence, count, m_sequences.data()); + if (difference(current, sequence) >= 0) + { + return current; + } + + return m_waitStrategy.wait_until_published(sequence, count, m_sequences.data(), timeoutTime); + } + + private: + + WaitStrategy& m_waitStrategy; + std::vector*> m_sequences; + + }; +} + +#endif diff --git a/thirdparty/disruptorplus/include/disruptorplus/sequence_range.hpp b/thirdparty/disruptorplus/include/disruptorplus/sequence_range.hpp new file mode 100644 index 0000000..91ab0d7 --- /dev/null +++ b/thirdparty/disruptorplus/include/disruptorplus/sequence_range.hpp @@ -0,0 +1,76 @@ +#ifndef DISRUPTORPLUS_SEQUENCE_RANGE_HPP_INCLUDED +#define DISRUPTORPLUS_SEQUENCE_RANGE_HPP_INCLUDED + +#include "sequence.hpp" + +namespace disruptorplus +{ + /// \brief + /// A sequence range represents a contiguous range of sequence numbers. + /// + /// A range has a \ref first() sequence number and a \ref size() which + /// indicates the number of sequence numbers in the range. + /// + /// The range of sequence numbers may overflow the underlying integer + /// storage type in which case the values wrap back around to zero. + class sequence_range + { + public: + + /// \brief + /// Construct to the empty range. + sequence_range() + : m_first(0) + , m_size(0) + {} + + /// \brief + /// Construct to a range of \p size sequence numbers starting at \p first. + /// + /// \param first + /// The first sequence number in the range. + /// + /// \param size + /// The number of sequence numbers in the range. + sequence_range(sequence_t first, size_t size) + : m_first(first) + , m_size(size) + {} + + /// \brief + /// Number of sequence numbers in this range. + size_t size() const { return m_size; } + + /// \brief + /// The first sequence number in the range. + sequence_t first() const { return m_first; } + + /// \brief + /// The last sequence number in the range. + sequence_t last() const { return end() - 1; } + + /// \brief + /// One-past the last sequence number in the range. + sequence_t end() const { return static_cast(m_first + m_size); } + + /// \brief + /// Lookup the nth sequence number in the range. + /// + /// \param index + /// The index of the nth sequence number in the range. + /// Must be in range [0, size()). + /// + /// \return + /// The nth sequence number in the range. + /// Equivalent to this->first() + index. + sequence_t operator[](size_t index) const { return static_cast(m_first + index); } + + private: + + sequence_t m_first; + size_t m_size; + + }; +} + +#endif diff --git a/thirdparty/disruptorplus/include/disruptorplus/single_threaded_claim_strategy.hpp b/thirdparty/disruptorplus/include/disruptorplus/single_threaded_claim_strategy.hpp new file mode 100644 index 0000000..999aa1e --- /dev/null +++ b/thirdparty/disruptorplus/include/disruptorplus/single_threaded_claim_strategy.hpp @@ -0,0 +1,520 @@ +#ifndef DISRUPTORPLUS_SINGLE_THREADED_CLAIM_STRATEGY_HPP_INCLUDED +#define DISRUPTORPLUS_SINGLE_THREADED_CLAIM_STRATEGY_HPP_INCLUDED + +#include "sequence_range.hpp" +#include "sequence_barrier.hpp" +#include "sequence_barrier_group.hpp" + +#include +#include +#include +#include + +namespace disruptorplus +{ + /// \brief + /// A claim strategy for use where only a single thread will be publishing + /// items to a ring buffer. + /// + /// This strategy avoids the overhead required to synchronise multiple + /// threads trying to claim slots in the ring buffer. + /// + /// A writer thread starts by first claiming one or more slots in the ring buffer + /// by calling one of the 'claim' methods. The writer then writes to the slots + /// and indicates to readers it has finished writing to the slots by calling + /// publish(). + /// + /// Reader threads can wait until a writer thread has published an element + /// to the ring buffer by calling one of the wait_until_published() methods. + /// + /// Readers indicate they are finished reading from a slot in the ring buffer + /// by publishing the sequence number of the latest item they are finished + /// with in the 'claim barrier'. This frees the slot up for writers to + /// subsequently claim it for future writes. + /// + /// \tparam WaitStrategy + /// The strategy to use to block threads waiting for sequence numbers to be published. + template + class single_threaded_claim_strategy + { + public: + + /// \brief + /// Initialise the claim strategy. + /// + /// \param bufferSize + /// The size of the ring buffer in which elements are allocated. + /// Must be a power-of-two. + /// + /// \param waitStrategy + /// The wait strategy object to use for blocking threads waiting for + /// a particular sequence number to be published. + /// This must be the same object that sequence barriers used by readers + /// are constructed with. + single_threaded_claim_strategy( + size_t bufferSize, + WaitStrategy& waitStrategy) + : m_bufferSize(bufferSize) + , m_nextSequenceToClaim(0) + , m_claimBarrier(waitStrategy) + , m_readBarrier(waitStrategy) + { + assert(bufferSize > 0 && (bufferSize & (bufferSize - 1)) == 0); + } + + /// \brief + /// The number of elements in the ring buffer. + /// + /// This will always be a power-of-two + size_t buffer_size() const + { + return m_bufferSize; + } + + /// \brief + /// Add a sequence barrier for claiming slots in the ring buffer. + /// + /// Add a sequence barrier that prevents elements of the ring buffer from + /// being claimed by writers until the reader has indicated the slot is + /// available by publishing the sequence number they have finished reading. + /// Claimed slots will never advance more than buffer_size() ahead + /// of any of the registered claim barriers. + /// + /// \param barrier + /// The sequence barrier to add. + /// A reference to the sequence barrier is held by the claim strategy + /// so the caller must ensure the lifetime of the sequence barrier + /// exceeds that of the cliam strategy. + /// This barrier must have been constructed with the same wait strategy object + /// as the claim strategy was constructed with. + /// \note + /// This operation is not thread-safe and the caller must ensure that no other + /// threads are accessing the claim strategy concurrently with this call. + void add_claim_barrier(sequence_barrier& barrier) + { + m_claimBarrier.add(barrier); + } + + /// \brief + /// Add a sequence barrier group for claiming slots in the ring buffer. + /// + /// Adds sequence barriers that prevent elements of the ring buffer from + /// being claimed by writers until the readers have indicated the slot is + /// available by publishing the sequence number they have finished reading. + /// Claimed slots will never advance more than buffer_size() ahead + /// of any of the registered claim barriers. + /// + /// \param barrier + /// The sequence barriers to add. + /// A reference to each sequence barrier in the group is held by the claim + /// strategy, so the caller must ensure the lifetime of the sequence barriers + /// exceed that of the cliam strategy. + /// This barrier must have been constructed with the same wait strategy object + /// as the claim strategy was constructed with. + /// + /// \note + /// This operation is not thread-safe and the caller must ensure that no other + /// threads are accessing the claim strategy concurrently with this call. + void add_claim_barrier(sequence_barrier_group& barrier) + { + m_claimBarrier.add(barrier); + } + + /// \brief + /// Claim a single slot in the ring buffer for writing to. + /// + /// Blocks the caller until a slot is available. + /// + /// The caller must call \ref publish(sequence_t) once it has + /// finished writing to the slot to publish the item to readers. + /// + /// \return + /// The sequence number of the slot claimed. + sequence_t claim_one() + { + m_claimBarrier.wait_until_published( + static_cast(m_nextSequenceToClaim - m_bufferSize)); + return m_nextSequenceToClaim++; + } + + /// Claim up to \p count consecutive slots in the ring buffer. + /// + /// Blocks the caller until at least one slot is available to claim. + /// + /// This operation has 'acquire' memory semantics. + /// + /// \param count + /// The maximum number of slots to claim. + /// + /// \return + /// A sequence range indicating the sequence numbers that were claimed. + /// This sequence range may contain less items than requested if fewer + /// were available but will contain at least one slot if \p count is non-zero. + sequence_range claim(size_t count) + { + sequence_t claimable = static_cast( + m_claimBarrier.wait_until_published( + static_cast(m_nextSequenceToClaim - m_bufferSize)) + + m_bufferSize); + + sequence_diff_t diff = difference(claimable, m_nextSequenceToClaim); + assert(diff >= 0); + + size_t available = static_cast(diff + 1); + count = std::min(count, available); + sequence_range result(m_nextSequenceToClaim, count); + m_nextSequenceToClaim += count; + + return result; + } + + /// \brief + /// Attempt to claim up to \p count slots in the ring buffer without blocking. + /// + /// This operation has 'acquire' memory semantics. + /// + /// \param count + /// The maximum number of slots to claim. + /// + /// \param range [out] + /// If any slots were claimed then this variable is populated with the + /// range of sequence numbers that were claimed. If no slots were claimed + /// then the value is left unchanged. + /// + /// \return + /// Returns \c true if any elements were claimed in which case the range of + /// slots claimed is written to the \p range out-parameter. May claim less + /// slots than requested if fewer slots were available. + /// Returns \c false if no elements were claimed. The \p range out-parameter is + /// not modified in this case. + bool try_claim(size_t count, sequence_range& range) + { + sequence_t seq = static_cast(m_claimBarrier.last_published() + m_bufferSize); + sequence_diff_t diff = difference(seq, m_nextSequenceToClaim); + if (diff < 0) + { + return false; + } + assert(diff >= 0); + size_t available = static_cast(diff + 1); + count = std::min(count, available); + range = sequence_range(m_nextSequenceToClaim, count); + m_nextSequenceToClaim += count; + return true; + } + + /// \brief + /// Attempt to claim up to \p count slots in the ring buffer. + /// + /// Blocks the caller until either at least one slot was claimed or until + /// the specified timeout period has elapsed, whichever comes first. + /// + /// This operation has 'acquire' memory semantics. + /// + /// \param count + /// The maximum number of slots to claim. + /// + /// \param range [out] + /// Receives the range of sequence numbers claimed if the operation succeeds. + /// Value is left unchanged if no slots were claimed. + /// + /// \param timeout + /// The maximum time to wait for claiming any slots. + /// + /// \return + /// Returns \c true if any slots were claimed in which case the range + /// of slots claimed is written to the \p range out-parameter. + /// Returns \c false if the timeout duration was exceeded without + /// claiming any slots. + /// + /// \throw std::exception + /// May throw any exception thrown by WaitStrategy::wait_until_published(). + template + bool try_claim_for( + size_t count, + sequence_range& range, + const std::chrono::duration& timeout) + { + if (try_claim(count, range)) + { + return true; + } + + sequence_t claimable = + static_cast( + m_claimBarrier.wait_until_published( + static_cast(m_nextSequenceToClaim - m_bufferSize), + timeout) + m_bufferSize); + sequence_diff_t diff = difference(claimable, m_nextSequenceToClaim); + if (diff < 0) + { + // Timeout + return false; + } + + size_t available = static_cast(diff + 1); + count = std::min(count, available); + range = sequence_range(m_nextSequenceToClaim, count); + m_nextSequenceToClaim += count; + + return true; + } + + /// \brief + /// Attempt to claim up to \p count slots in the ring buffer. + /// + /// Blocks the caller until either at least one slot was claimed or until + /// the specified timeout period has elapsed, whichever comes first. + /// + /// This operation has 'acquire' memory semantics. + /// + /// \param count + /// The maximum number of slots to claim. + /// + /// \param range [out] + /// Receives the range of sequence numbers claimed if the operation succeeds. + /// Value is left unchanged if no slots were claimed. + /// + /// \param timeoutTime + /// The time after which the call should stop waiting for available slots. + /// + /// \return + /// Returns \c true if any slots were claimed in which case the range + /// of slots claimed is written to the \p range out-parameter. + /// Returns \c false if the timeout duration was exceeded without + /// claiming any slots. + /// + /// \throw std::exception + /// May throw any exception thrown by \c Clock::now() or + /// \c WaitStrategy::wait_until_published(). + template + bool try_claim_until( + size_t count, + sequence_range& range, + const std::chrono::time_point& timeoutTime) + { + if (try_claim(count, range)) + { + return true; + } + + sequence_t claimable = + static_cast( + m_claimBarrier.wait_until_published( + static_cast(m_nextSequenceToClaim - m_bufferSize), + timeoutTime) + m_bufferSize); + sequence_diff_t diff = difference(claimable, m_nextSequenceToClaim); + if (diff < 0) + { + // Timeout + return false; + } + + size_t available = static_cast(diff + 1); + count = std::min(count, available); + range = sequence_range(m_nextSequenceToClaim, count); + m_nextSequenceToClaim += count; + + return true; + } + + /// \brief + /// Publishes all sequences up to and including \p sequence. + /// + /// Notifies reader threads that these items are now available + /// to be read. + /// + /// This operation has 'release' memory semantics. + /// + /// \param sequence + /// The sequence number to publish to readers. + void publish(sequence_t sequence) + { + m_readBarrier.publish(sequence); + } + + /// \brief + /// Query the last sequence that was published. + /// + /// All sequences up to and including returned sequence value + /// have been published and are available for readers to access. + /// + /// This operation has 'acquire' memory semantics. + sequence_t last_published() const + { + return m_readBarrier.last_published(); + } + + /// \brief + /// Block the caller until the specified \p sequence has been + /// published by the writer thread. + /// + /// This operation has 'acquire' memory semantics. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \return + /// Returns the value of \ref last_published() which may be in + /// advance of the requested sequence. + sequence_t wait_until_published(sequence_t sequence) const + { + return m_readBarrier.wait_until_published(sequence); + } + + /// \brief + /// Block the caller until the specified \p sequence has been + /// published by the writer thread. + /// + /// This operation has 'acquire' memory semantics. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \param lastKnownPublished + /// This sequence number is assumed to have already been published. + /// The initial value passed in here on first call should be sequence_t(-1). + /// + /// \return + /// Returns the value of \ref last_published() which may be in + /// advance of the requested sequence. + sequence_t wait_until_published(sequence_t sequence, sequence_t lastKnownPublished) const + { + return wait_until_published(sequence); + } + + /// \brief + /// Block the caller until either the specified sequence has been + /// published by the writer thread or until the specified timeout + /// has elapsed. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \param timeout + /// The maximum amount of time to wait for the sequence number to + /// be published. + /// + /// \return + /// Returns the value of \ref last_published() which may be prior to + /// the specified sequence in the case of a timeout or equal to + /// or after the specified sequence in the case of that item being + /// published. + template + sequence_t wait_until_published( + sequence_t sequence, + const std::chrono::duration& timeout) const + { + return m_readBarrier.wait_until_published(sequence, timeout); + } + + /// \brief + /// Block the caller until either the specified sequence has been + /// published by the writer thread or until the specified timeout + /// has elapsed. + /// + /// This operation has 'acquire' memory semantics. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \param lastKnownPublished + /// This sequence number is assumed to have already been published. + /// The initial value passed in here on first call should be sequence_t(-1). + /// + /// \param timeout + /// The maximum amount of time to wait for the sequence number to + /// be published. + /// + /// \return + /// Returns the value of \ref last_published() which may be prior to + /// the specified sequence in the case of a timeout or equal to + /// or after the specified sequence in the case of that item being + /// published. + template + sequence_t wait_until_published( + sequence_t sequence, + sequence_t lastKnownPublished, + const std::chrono::duration& timeout) const + { + return wait_until_published(sequence, timeout); + } + + /// \brief + /// Block the caller until either the specified sequence has been + /// published by the writer thread or until the specified timeout + /// time has passed. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \param timeoutTime + /// The time after which the call should return in failure if + /// the specified \p sequence has not yet been published. + /// + /// \return + /// Returns the value of \ref last_published() which may be prior to + /// the specified sequence in the case of a timeout or equal to + /// or after the specified sequence in the case of that item being + /// published. + template + sequence_t wait_until_published( + sequence_t sequence, + const std::chrono::time_point& timeoutTime) const + { + return m_readBarrier.wait_until_published(sequence, timeoutTime); + } + + /// \brief + /// Block the caller until either the specified sequence has been + /// published by the writer thread or until the specified timeout + /// has elapsed. + /// + /// This operation has 'acquire' memory semantics. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \param lastKnownPublished + /// This sequence number is assumed to have already been published. + /// The initial value passed in here on first call should be sequence_t(-1). + /// + /// \param timeoutTime + /// The time after which the call should return in failure if + /// the specified \p sequence has not yet been published. + /// + /// \return + /// Returns the value of \ref last_published() which may be prior to + /// the specified sequence in the case of a timeout or equal to + /// or after the specified sequence in the case of that item being + /// published. + template + sequence_t wait_until_published( + sequence_t sequence, + sequence_t lastKnownPublished, + const std::chrono::time_point& timeoutTime) const + { + return wait_until_published(sequence, timeoutTime); + } + + private: + + const size_t m_bufferSize; + + // The next sequence to be claimed (may not yet be available). + sequence_t m_nextSequenceToClaim; + + // A cache of the last-known available sequence value + // queried using m_claimBarrier. + sequence_t m_lastKnownClaimableSequence; + + sequence_barrier_group m_claimBarrier; + + // Barrier used to publish items to the + sequence_barrier m_readBarrier; + + }; + +} + +#endif diff --git a/thirdparty/disruptorplus/include/disruptorplus/spin_wait.hpp b/thirdparty/disruptorplus/include/disruptorplus/spin_wait.hpp new file mode 100644 index 0000000..2d8a95a --- /dev/null +++ b/thirdparty/disruptorplus/include/disruptorplus/spin_wait.hpp @@ -0,0 +1,135 @@ +#ifndef DISRUPTORPLUS_SPIN_WAIT_HPP_INCLUDED +#define DISRUPTORPLUS_SPIN_WAIT_HPP_INCLUDED + +#include + +#if defined(_M_IX86) || defined(_M_AMD64) || defined(__i386__) || defined(__amd64__) +# define DISRUPTORPLUS_ARCH_X86 +# include +#endif + +#if defined(_M_ARM) || defined(_M_ARM64) || defined(__arm__) || defined(__aarch64__) +# define DISRUPTORPLUS_ARCH_ARM +# ifdef _MSC_VER +# include +# endif +#endif + +namespace disruptorplus +{ + /// \brief + /// A helper class for implementing spin-wait loops. + /// + /// Call \ref spin_once() each time through the loop + /// to wait for a short time. Initially just trying to + /// put the CPU into an idle mode (eg. to allow other + /// hyper-threads on same core to run) and eventually + /// yielding the rest of the thread's time-slice or + /// putting the thread to sleep for a short time. + /// + /// For example: + /// \code + /// std::atomic& flag = someSharedFlag; + /// disruptorplus::spin_wait spinner; + /// while (!flag.load()) + /// { + /// spinner.spin_once(); + /// } + /// \endcode + /// + /// \note + /// On single-core machines this will not with the CPU + /// idling phase and will proceed straight to yielding + /// the remainder of the thread time-slice. + class spin_wait + { + public: + + spin_wait() + { + reset(); + } + + /// \brief + /// Reset the spin_wait back to its original state. + void reset() + { + m_value = std::thread::hardware_concurrency() > 1 ? 0 : 10; + } + + /// \brief + /// Wait for a short period of time. + /// + /// Call this method each time through a spin-wait loop. + void spin_once() + { + // Exponentially longer sequences of busy-waits each + // time we're called for first 10 calls, then graduating + // to yielding our time slice with every 20th call then + // putting the thread to sleep for a short while. + if (next_spin_will_yield()) + { + uint32_t count = m_value - 10; + if (count % 20 == 19) + { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + else + { + std::this_thread::yield(); + } + } + else + { + uint32_t count = 4 << m_value; + while (count-- != 0) + { + yield_processor(); + } + } + m_value = (m_value == 0xFFFFFFFF) ? 10 : m_value + 1; + } + + /// \brief + /// Query whether the next call to \ref spin_once() will yield the + /// remainder of the thread's time slice. + /// + /// Call this if you want to perform some alternative logic prior + /// to the thread being rescheduled. + /// + /// \return + /// \c true if the next call to \ref spin_once() will yield the + /// remainder of the thread's time slice, \c false otherwise. + bool next_spin_will_yield() const + { + return m_value >= 10; + } + + private: + + /// \brief + /// Indicate to the CPU that the current thread is waiting and + /// so should be put in an idle mode. + /// + /// eg. On Intel processors with HyperThreading this may signal + /// to allow the other thread running on this core to execute. + static void yield_processor() + { + // Ideally we want to put this processor into idle mode for a few cycles. +#if defined(DISRUPTORPLUS_ARCH_X86) + _mm_pause(); +#elif defined(DISRUPTORPLUS_ARCH_ARM) +# if defined(_MSC_VER) + __yield(); +# else + __asm__ volatile("yield" ::: "memory"); +# endif +#endif + } + + uint32_t m_value; + + }; +} + +#endif diff --git a/thirdparty/disruptorplus/include/disruptorplus/spin_wait_strategy.hpp b/thirdparty/disruptorplus/include/disruptorplus/spin_wait_strategy.hpp new file mode 100644 index 0000000..9a8f199 --- /dev/null +++ b/thirdparty/disruptorplus/include/disruptorplus/spin_wait_strategy.hpp @@ -0,0 +1,177 @@ +#ifndef DISRUPTORPLUS_SPIN_WAIT_STRATEGY_HPP_INCLUDED +#define DISRUPTORPLUS_SPIN_WAIT_STRATEGY_HPP_INCLUDED + +#include "spin_wait.hpp" +#include "sequence.hpp" + +#include +#include +#include + +namespace disruptorplus +{ + /// \brief + /// This wait-strategy busy-waits when waiting for sequences to be + /// published. + /// + /// The busy wait used is a phased wait which backs off incrementally, + /// initially actively busy waiting, falling back to yielding the + /// thread's remaining time-slice and sleeping occasionally. + /// This attempts to balance low-latency throughput during busy periods + /// with low CPU usage during the quiet periods. + /// + /// \see disruptorplus::spin_wait + /// \see disruptorplus::blocking_wait_strategy + class spin_wait_strategy + { + public: + + /// \brief + /// Wait unconditionally until all of the specified sequences + /// have at least published the specified sequence value. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \param count + /// The number of elements in \p sequences. + /// Must be greater than zero. + /// + /// \param sequences + /// An array of \p count pointers to sequence values. + /// The call will not return until all of these values have advanced + /// beyond the specified \p sequence. + /// + /// \return + /// The value of the least-advanced sequence. + /// This value is guaranteed to be at least \p sequence. + /// + /// \throw std::system_error + /// If the system does not have enough resources to perform this operation. + sequence_t wait_until_published( + sequence_t sequence, + size_t count, + const std::atomic* const sequences[]) + { + assert(count > 0); + spin_wait spinner; + sequence_t result = minimum_sequence_after(sequence, count, sequences); + while (difference(result, sequence) < 0) + { + spinner.spin_once(); + result = minimum_sequence_after(sequence, count, sequences); + } + return result; + } + + /// \brief + /// Wait until either all of the specified sequences have at least + /// published the specified sequence value or a timeout is reached. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \param count + /// The number of elements in \p sequences. + /// Must be greater than zero. + /// + /// \param sequences + /// An array of \p count pointers to sequence values. + /// The call will wait until all of these sequence values have + /// published a sequence number at or after the specified + /// \p sequence number. + /// + /// \param timeout + /// The maximum amount of time to wait for the \p sequences + /// numbers to advance to \p sequence. + /// + /// \return + /// If the operation timed out then returns some number such + /// that difference(result, sequence) < 0, otherwise + /// returns the least-advanced of all the sequence values read + /// from \p sequences, which is guaranteed to satisfy + /// difference(result, sequence) >= 0. + /// + /// \throw std::system_error + /// If the system does not have enough resources to perform this operation. + template + sequence_t wait_until_published( + sequence_t sequence, + size_t count, + const std::atomic* const sequences[], + const std::chrono::duration& timeout) + { + return wait_until_published( + sequence, + count, + sequences, + std::chrono::high_resolution_clock::now() + timeout); + } + + /// \brief + /// Wait until either all of the specified sequences have at least + /// published the specified sequence value or a timeout time is reached. + /// + /// \param sequence + /// The sequence number to wait for. + /// + /// \param count + /// The number of elements in \p sequences. + /// Must be greater than zero. + /// + /// \param sequences + /// An array of \p count pointers to sequence values. + /// The call will wait until all of these sequence values have + /// published a sequence number at or after the specified + /// \p sequence number. + /// + /// \param timeoutTime + /// The time to wait until for the \p sequences numbers to + /// advance to \p sequence. The operation will timeout after + /// this point in time. + /// + /// \return + /// If the operation timed out then returns some number such + /// that difference(result, sequence) < 0, otherwise + /// returns the least-advanced of all the sequence values read + /// from \p sequences, which is guaranteed to satisfy + /// difference(result, sequence) >= 0. + /// + /// \throw std::system_error + /// If the system does not have enough resources to perform this operation. + template + sequence_t wait_until_published( + sequence_t sequence, + size_t count, + const std::atomic* const sequences[], + const std::chrono::time_point& timeoutTime) + { + assert(count > 0); + spin_wait spinner; + sequence_t result = minimum_sequence_after(sequence, count, sequences); + while (difference(result, sequence) < 0) + { + if (spinner.next_spin_will_yield() && timeoutTime < Clock::now()) + { + // Out of time. + return result; + } + spinner.spin_once(); + result = minimum_sequence_after(sequence, count, sequences); + } + return result; + } + + /// \brief + /// Notify any waiting threads that one of the sequence values has changed. + void signal_all_when_blocking() + { + // This is requred as part of the wait_strategy interface but does nothing + // for the spin_wait_strategy since all waiting threads are continuously + // checking the sequence values in a spin-wait loop. + } + + }; +} + +#endif diff --git a/thirdparty/dxbc/DXBCChecksum.cpp b/thirdparty/dxbc/DXBCChecksum.cpp new file mode 100644 index 0000000..635fc9c --- /dev/null +++ b/thirdparty/dxbc/DXBCChecksum.cpp @@ -0,0 +1,389 @@ +// Xenia: removed Windows.h dependency. + +//===================================================================== +// Copyright 2008-2016 (c), Advanced Micro Devices, Inc. All rights reserved. +// +/// \author AMD Developer Tools Team +/// \file DXBCChecksum.cpp +/// +//===================================================================== + +//===================================================================== +// $Id: //devtools/main/Common/Src/ShaderUtils/DX10/DXBCChecksum.cpp#4 $ +// +// Last checkin: $DateTime: 2016/04/18 06:01:26 $ +// Last edited by: $Author: AMD Developer Tools Team +//===================================================================== +// Free for all implementation of the MD5 hash algorithm + +/* +********************************************************************** +** DXBCChecksum.cpp ** +** ** +** - Modified by Seth Sowerby, November 2007 ** +** Modified to match DXBC checksum algorithm used by Microsoft ** +** ** +********************************************************************** +*/ + +/* +********************************************************************** +** MD5.cpp ** +** ** +** - Style modified by Tony Ray, January 2001 ** +** Added support for randomizing initialization constants ** +** - Style modified by Dominik Reichl, April 2003 ** +** Optimized code ** +** ** +********************************************************************** +*/ + +/* + ********************************************************************** + ** MD5.c ** + ** RSA Data Security, Inc. MD5 Message Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version ** + ********************************************************************** + */ + +/* + ********************************************************************** + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + ** ** + ** License to copy and use this software is granted provided that ** + ** it is identified as the "RSA Data Security, Inc. MD5 Message ** + ** Digest Algorithm" in all material mentioning or referencing this ** + ** software or this function. ** + ** ** + ** License is also granted to make and use derivative works ** + ** provided that such works are identified as "derived from the RSA ** + ** Data Security, Inc. MD5 Message Digest Algorithm" in all ** + ** material mentioning or referencing the derived work. ** + ** ** + ** RSA Data Security, Inc. makes no representations concerning ** + ** either the merchantability of this software or the suitability ** + ** of this software for any particular purpose. It is provided "as ** + ** is" without express or implied warranty of any kind. ** + ** ** + ** These notices must be retained in any copies of any part of this ** + ** documentation and/or software. ** + ********************************************************************** + */ + +#include +#include +#include +#include "DXBCChecksum.h" + +/* Padding */ +static unsigned char MD5_PADDING[64] = +{ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* MD5_F, MD5_G and MD5_H are basic MD5 functions: selection, majority, parity */ +#define MD5_F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define MD5_G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define MD5_H(x, y, z) ((x) ^ (y) ^ (z)) +#define MD5_I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits */ +#ifndef ROTATE_LEFT + #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) +#endif + +/* MD5_FF, MD5_GG, MD5_HH, and MD5_II transformations for rounds 1, 2, 3, and 4 */ +/* Rotation is separate from addition to prevent recomputation */ +#define MD5_FF(a, b, c, d, x, s, ac) {(a) += MD5_F ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } +#define MD5_GG(a, b, c, d, x, s, ac) {(a) += MD5_G ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } +#define MD5_HH(a, b, c, d, x, s, ac) {(a) += MD5_H ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } +#define MD5_II(a, b, c, d, x, s, ac) {(a) += MD5_I ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } + +/* Constants for transformation */ +#define MD5_S11 7 /* Round 1 */ +#define MD5_S12 12 +#define MD5_S13 17 +#define MD5_S14 22 +#define MD5_S21 5 /* Round 2 */ +#define MD5_S22 9 +#define MD5_S23 14 +#define MD5_S24 20 +#define MD5_S31 4 /* Round 3 */ +#define MD5_S32 11 +#define MD5_S33 16 +#define MD5_S34 23 +#define MD5_S41 6 /* Round 4 */ +#define MD5_S42 10 +#define MD5_S43 15 +#define MD5_S44 21 + +/* Typedef a 32 bit type */ +#ifndef UINT4 + typedef unsigned int UINT4; +#endif + +/* Data structure for MD5 (Message Digest) computation */ +typedef struct +{ + UINT4 i[2]; /* Number of _bits_ handled mod 2^64 */ + UINT4 buf[4]; /* Scratch buffer */ + unsigned char in[64]; /* Input buffer */ + unsigned char digest[16]; /* Actual digest after MD5Final call */ +} MD5_CTX; + +static void MD5_Transform(UINT4* buf, UINT4* in); + +void MD5Init(MD5_CTX* mdContext, unsigned long pseudoRandomNumber = 0); +void MD5Update(MD5_CTX* mdContext, unsigned char* inBuf, unsigned int inLen); +void MD5Final(MD5_CTX* mdContext); + +/* Basic MD5 step. MD5_Transform buf based on in */ +static void MD5_Transform(UINT4* buf, UINT4* in) +{ + UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + + /* Round 1 */ + MD5_FF(a, b, c, d, in[ 0], MD5_S11, (UINT4) 3614090360u); /* 1 */ + MD5_FF(d, a, b, c, in[ 1], MD5_S12, (UINT4) 3905402710u); /* 2 */ + MD5_FF(c, d, a, b, in[ 2], MD5_S13, (UINT4) 606105819u); /* 3 */ + MD5_FF(b, c, d, a, in[ 3], MD5_S14, (UINT4) 3250441966u); /* 4 */ + MD5_FF(a, b, c, d, in[ 4], MD5_S11, (UINT4) 4118548399u); /* 5 */ + MD5_FF(d, a, b, c, in[ 5], MD5_S12, (UINT4) 1200080426u); /* 6 */ + MD5_FF(c, d, a, b, in[ 6], MD5_S13, (UINT4) 2821735955u); /* 7 */ + MD5_FF(b, c, d, a, in[ 7], MD5_S14, (UINT4) 4249261313u); /* 8 */ + MD5_FF(a, b, c, d, in[ 8], MD5_S11, (UINT4) 1770035416u); /* 9 */ + MD5_FF(d, a, b, c, in[ 9], MD5_S12, (UINT4) 2336552879u); /* 10 */ + MD5_FF(c, d, a, b, in[10], MD5_S13, (UINT4) 4294925233u); /* 11 */ + MD5_FF(b, c, d, a, in[11], MD5_S14, (UINT4) 2304563134u); /* 12 */ + MD5_FF(a, b, c, d, in[12], MD5_S11, (UINT4) 1804603682u); /* 13 */ + MD5_FF(d, a, b, c, in[13], MD5_S12, (UINT4) 4254626195u); /* 14 */ + MD5_FF(c, d, a, b, in[14], MD5_S13, (UINT4) 2792965006u); /* 15 */ + MD5_FF(b, c, d, a, in[15], MD5_S14, (UINT4) 1236535329u); /* 16 */ + + /* Round 2 */ + MD5_GG(a, b, c, d, in[ 1], MD5_S21, (UINT4) 4129170786u); /* 17 */ + MD5_GG(d, a, b, c, in[ 6], MD5_S22, (UINT4) 3225465664u); /* 18 */ + MD5_GG(c, d, a, b, in[11], MD5_S23, (UINT4) 643717713u); /* 19 */ + MD5_GG(b, c, d, a, in[ 0], MD5_S24, (UINT4) 3921069994u); /* 20 */ + MD5_GG(a, b, c, d, in[ 5], MD5_S21, (UINT4) 3593408605u); /* 21 */ + MD5_GG(d, a, b, c, in[10], MD5_S22, (UINT4) 38016083u); /* 22 */ + MD5_GG(c, d, a, b, in[15], MD5_S23, (UINT4) 3634488961u); /* 23 */ + MD5_GG(b, c, d, a, in[ 4], MD5_S24, (UINT4) 3889429448u); /* 24 */ + MD5_GG(a, b, c, d, in[ 9], MD5_S21, (UINT4) 568446438u); /* 25 */ + MD5_GG(d, a, b, c, in[14], MD5_S22, (UINT4) 3275163606u); /* 26 */ + MD5_GG(c, d, a, b, in[ 3], MD5_S23, (UINT4) 4107603335u); /* 27 */ + MD5_GG(b, c, d, a, in[ 8], MD5_S24, (UINT4) 1163531501u); /* 28 */ + MD5_GG(a, b, c, d, in[13], MD5_S21, (UINT4) 2850285829u); /* 29 */ + MD5_GG(d, a, b, c, in[ 2], MD5_S22, (UINT4) 4243563512u); /* 30 */ + MD5_GG(c, d, a, b, in[ 7], MD5_S23, (UINT4) 1735328473u); /* 31 */ + MD5_GG(b, c, d, a, in[12], MD5_S24, (UINT4) 2368359562u); /* 32 */ + + /* Round 3 */ + MD5_HH(a, b, c, d, in[ 5], MD5_S31, (UINT4) 4294588738u); /* 33 */ + MD5_HH(d, a, b, c, in[ 8], MD5_S32, (UINT4) 2272392833u); /* 34 */ + MD5_HH(c, d, a, b, in[11], MD5_S33, (UINT4) 1839030562u); /* 35 */ + MD5_HH(b, c, d, a, in[14], MD5_S34, (UINT4) 4259657740u); /* 36 */ + MD5_HH(a, b, c, d, in[ 1], MD5_S31, (UINT4) 2763975236u); /* 37 */ + MD5_HH(d, a, b, c, in[ 4], MD5_S32, (UINT4) 1272893353u); /* 38 */ + MD5_HH(c, d, a, b, in[ 7], MD5_S33, (UINT4) 4139469664u); /* 39 */ + MD5_HH(b, c, d, a, in[10], MD5_S34, (UINT4) 3200236656u); /* 40 */ + MD5_HH(a, b, c, d, in[13], MD5_S31, (UINT4) 681279174u); /* 41 */ + MD5_HH(d, a, b, c, in[ 0], MD5_S32, (UINT4) 3936430074u); /* 42 */ + MD5_HH(c, d, a, b, in[ 3], MD5_S33, (UINT4) 3572445317u); /* 43 */ + MD5_HH(b, c, d, a, in[ 6], MD5_S34, (UINT4) 76029189u); /* 44 */ + MD5_HH(a, b, c, d, in[ 9], MD5_S31, (UINT4) 3654602809u); /* 45 */ + MD5_HH(d, a, b, c, in[12], MD5_S32, (UINT4) 3873151461u); /* 46 */ + MD5_HH(c, d, a, b, in[15], MD5_S33, (UINT4) 530742520u); /* 47 */ + MD5_HH(b, c, d, a, in[ 2], MD5_S34, (UINT4) 3299628645u); /* 48 */ + + /* Round 4 */ + MD5_II(a, b, c, d, in[ 0], MD5_S41, (UINT4) 4096336452u); /* 49 */ + MD5_II(d, a, b, c, in[ 7], MD5_S42, (UINT4) 1126891415u); /* 50 */ + MD5_II(c, d, a, b, in[14], MD5_S43, (UINT4) 2878612391u); /* 51 */ + MD5_II(b, c, d, a, in[ 5], MD5_S44, (UINT4) 4237533241u); /* 52 */ + MD5_II(a, b, c, d, in[12], MD5_S41, (UINT4) 1700485571u); /* 53 */ + MD5_II(d, a, b, c, in[ 3], MD5_S42, (UINT4) 2399980690u); /* 54 */ + MD5_II(c, d, a, b, in[10], MD5_S43, (UINT4) 4293915773u); /* 55 */ + MD5_II(b, c, d, a, in[ 1], MD5_S44, (UINT4) 2240044497u); /* 56 */ + MD5_II(a, b, c, d, in[ 8], MD5_S41, (UINT4) 1873313359u); /* 57 */ + MD5_II(d, a, b, c, in[15], MD5_S42, (UINT4) 4264355552u); /* 58 */ + MD5_II(c, d, a, b, in[ 6], MD5_S43, (UINT4) 2734768916u); /* 59 */ + MD5_II(b, c, d, a, in[13], MD5_S44, (UINT4) 1309151649u); /* 60 */ + MD5_II(a, b, c, d, in[ 4], MD5_S41, (UINT4) 4149444226u); /* 61 */ + MD5_II(d, a, b, c, in[11], MD5_S42, (UINT4) 3174756917u); /* 62 */ + MD5_II(c, d, a, b, in[ 2], MD5_S43, (UINT4) 718787259u); /* 63 */ + MD5_II(b, c, d, a, in[ 9], MD5_S44, (UINT4) 3951481745u); /* 64 */ + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +// Set pseudoRandomNumber to zero for RFC MD5 implementation +void MD5Init(MD5_CTX* mdContext, unsigned long pseudoRandomNumber) +{ + mdContext->i[0] = mdContext->i[1] = (UINT4)0; + + /* Load magic initialization constants */ + mdContext->buf[0] = (UINT4)0x67452301 + (pseudoRandomNumber * 11); + mdContext->buf[1] = (UINT4)0xefcdab89 + (pseudoRandomNumber * 71); + mdContext->buf[2] = (UINT4)0x98badcfe + (pseudoRandomNumber * 37); + mdContext->buf[3] = (UINT4)0x10325476 + (pseudoRandomNumber * 97); +} + +void MD5Update(MD5_CTX* mdContext, unsigned char* inBuf, unsigned int inLen) +{ + UINT4 in[16]; + int mdi = 0; + unsigned int i = 0, ii = 0; + + /* Compute number of bytes mod 64 */ + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + /* Update number of bits */ + if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0]) + { + mdContext->i[1]++; + } + + mdContext->i[0] += ((UINT4)inLen << 3); + mdContext->i[1] += ((UINT4)inLen >> 29); + + while (inLen--) + { + /* Add new character to buffer, increment mdi */ + mdContext->in[mdi++] = *inBuf++; + + /* Transform if necessary */ + if (mdi == 0x40) + { + for (i = 0, ii = 0; i < 16; i++, ii += 4) + in[i] = (((UINT4)mdContext->in[ii + 3]) << 24) | + (((UINT4)mdContext->in[ii + 2]) << 16) | + (((UINT4)mdContext->in[ii + 1]) << 8) | + ((UINT4)mdContext->in[ii]); + + MD5_Transform(mdContext->buf, in); + mdi = 0; + } + } +} + +void MD5Final(MD5_CTX* mdContext) +{ + UINT4 in[16]; + int mdi = 0; + unsigned int i = 0, ii = 0, padLen = 0; + + /* Save number of bits */ + unsigned int numberOfBits = mdContext->i[0]; + + /* Pad out to 56 mod 64 */ + padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); + + MD5Update(mdContext, (unsigned char*) &numberOfBits, 4); + + /* Compute number of bytes mod 64 */ + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + /* Pad out to 56 mod 64 */ + padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); + MD5Update(mdContext, MD5_PADDING, padLen); + + ((UINT4*)mdContext->in)[15] = (numberOfBits >> 2) | 1; + // MD5Update (mdContext, (unsigned char*) terminator, 8); + + memcpy(in, mdContext->in, 64); + /* Append length in bits and transform */ + /* + for (i = 0, ii = 0; i < 14; i++, ii += 4) + in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | + (((UINT4)mdContext->in[ii+2]) << 16) | + (((UINT4)mdContext->in[ii+1]) << 8) | + ((UINT4)mdContext->in[ii]); + */ + MD5_Transform(mdContext->buf, in); + + /* Store buffer in digest */ + for (i = 0, ii = 0; i < 4; i++, ii += 4) + { + mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); + mdContext->digest[ii + 1] = (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); + mdContext->digest[ii + 2] = (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); + mdContext->digest[ii + 3] = (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); + } +} + +static const unsigned int dwHashOffset = 0x14; + +void CalculateDXBCChecksum(unsigned char* pData, unsigned int dwSize, unsigned int dwHash[4]) +{ + MD5_CTX md5Ctx; + MD5Init(&md5Ctx, 0); + + // Skip the start of the shader header + dwSize -= dwHashOffset; + pData += dwHashOffset; + + unsigned int dwNumberOfBits = dwSize * 8; + + // First we hash all the full chunks available + unsigned int dwFullChunksSize = dwSize & 0xffffffc0; + MD5Update(&md5Ctx, pData, dwFullChunksSize); + + unsigned int dwLastChunkSize = dwSize - dwFullChunksSize; + unsigned int dwPaddingSize = 64 - dwLastChunkSize; + unsigned char* pLastChunkData = pData + dwFullChunksSize; + + if (dwLastChunkSize >= 56) + { + MD5Update(&md5Ctx, pLastChunkData, dwLastChunkSize); + + /* Pad out to 56 mod 64 */ + MD5Update(&md5Ctx, MD5_PADDING, dwPaddingSize); + + // Pass in the number of bits + UINT4 in[16]; + memset(in, 0, sizeof(in)); + in[0] = dwNumberOfBits; + in[15] = (dwNumberOfBits >> 2) | 1; + + MD5_Transform(md5Ctx.buf, in); + } + else + { + // Pass in the number of bits + MD5Update(&md5Ctx, (unsigned char*) &dwNumberOfBits, 4); + + if (dwLastChunkSize) + { + MD5Update(&md5Ctx, pLastChunkData, dwLastChunkSize); + } + + + // Adjust for the space used for dwNumberOfBits + dwLastChunkSize += sizeof(unsigned int); + dwPaddingSize -= sizeof(unsigned int); + + /* Pad out to 56 mod 64 */ + memcpy(&md5Ctx.in[dwLastChunkSize], MD5_PADDING, dwPaddingSize); + + ((UINT4*)md5Ctx.in)[15] = (dwNumberOfBits >> 2) | 1; + + UINT4 in[16]; + memcpy(in, md5Ctx.in, 64); + + MD5_Transform(md5Ctx.buf, in); + } + + memcpy(dwHash, md5Ctx.buf, 4 * sizeof(unsigned int)); +} \ No newline at end of file diff --git a/thirdparty/dxbc/DXBCChecksum.h b/thirdparty/dxbc/DXBCChecksum.h new file mode 100644 index 0000000..f9407a0 --- /dev/null +++ b/thirdparty/dxbc/DXBCChecksum.h @@ -0,0 +1,79 @@ +// Xenia: removed Windows.h dependency. + +//===================================================================== +// Copyright 2008-2016 (c), Advanced Micro Devices, Inc. All rights reserved. +// +/// \author AMD Developer Tools Team +/// \file DXBCChecksum.h +/// +//===================================================================== + +//===================================================================== +// $Id: //devtools/main/Common/Src/ShaderUtils/DX10/DXBCChecksum.h#4 $ +// +// Last checkin: $DateTime: 2016/04/18 06:01:26 $ +// Last edited by: $Author: AMD Developer Tools Team +//===================================================================== + +#pragma once +#ifndef DXBCCHECKSUM_H +#define DXBCCHECKSUM_H + +/* + ********************************************************************** + ** MD5.h ** + ** ** + ** - Style modified by Tony Ray, January 2001 ** + ** Added support for randomizing initialization constants ** + ** - Style modified by Dominik Reichl, September 2002 ** + ** Optimized code ** + ** ** + ********************************************************************** + */ + +/* + ********************************************************************** + ** MD5.h -- Header file for implementation of MD5 ** + ** RSA Data Security, Inc. MD5 Message Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** + ** Revised (for MD5): RLR 4/27/91 ** + ** -- G modified to have y&~z instead of y&z ** + ** -- FF, GG, HH modified to add in last register done ** + ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** + ** -- distinct additive constant for each step ** + ** -- round 4 added, working mod 7 ** + ********************************************************************** + */ + +/* + ********************************************************************** + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + ** ** + ** License to copy and use this software is granted provided that ** + ** it is identified as the "RSA Data Security, Inc. MD5 Message ** + ** Digest Algorithm" in all material mentioning or referencing this ** + ** software or this function. ** + ** ** + ** License is also granted to make and use derivative works ** + ** provided that such works are identified as "derived from the RSA ** + ** Data Security, Inc. MD5 Message Digest Algorithm" in all ** + ** material mentioning or referencing the derived work. ** + ** ** + ** RSA Data Security, Inc. makes no representations concerning ** + ** either the merchantability of this software or the suitability ** + ** of this software for any particular purpose. It is provided "as ** + ** is" without express or implied warranty of any kind. ** + ** ** + ** These notices must be retained in any copies of any part of this ** + ** documentation and/or software. ** + ********************************************************************** + */ + +/// Calculate the DXBC checksum for the provided chunk of memory. +/// \param[in] pData A pointer to the memory to checksum. +/// \param[in] dwSize The size of the memory to checksum. +/// \param[out] dwHash A DWORD array to copy the calculated check sum into. +void CalculateDXBCChecksum(unsigned char* pData, unsigned int dwSize, unsigned int dwHash[4]); + +#endif // DXBCCHECKSUM_H diff --git a/thirdparty/dxc/README.md b/thirdparty/dxc/README.md new file mode 100644 index 0000000..b994055 --- /dev/null +++ b/thirdparty/dxc/README.md @@ -0,0 +1,15 @@ +# DXC API Headers (Vendored) + +Headers vendored from [microsoft/DirectXShaderCompiler](https://github.com/microsoft/DirectXShaderCompiler). + +## Source + +- **Commit:** `6b6f40200bea5ed99367513f53f6a28e52fd3d0e` +- **Files:** + - `include/dxcapi.h` — from `include/dxc/dxcapi.h` + - `include/DxbcConverter.h` — from `projects/dxilconv/include/DxbcConverter.h` + +## License + +University of Illinois/NCSA Open Source License. See the +[DirectXShaderCompiler LICENSE](https://github.com/microsoft/DirectXShaderCompiler/blob/main/LICENSE.TXT). diff --git a/thirdparty/dxc/include/DxbcConverter.h b/thirdparty/dxc/include/DxbcConverter.h new file mode 100644 index 0000000..5d98337 --- /dev/null +++ b/thirdparty/dxc/include/DxbcConverter.h @@ -0,0 +1,68 @@ +/////////////////////////////////////////////////////////////////////////////// +// // +// DxbcConverter.h // +// Copyright (C) Microsoft. All rights reserved. // +// This file is distributed under the University of Illinois Open Source // +// License. See LICENSE.TXT for details. // +// // +// Provides declarations for the DirectX DXBC to DXIL converter component. // +// // +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __DXBC_CONVERTER__H__ +#define __DXBC_CONVERTER__H__ + +#ifndef _MSC_VER +extern "C" +#endif +DXC_API_IMPORT HRESULT __stdcall DxcCreateInstance( + _In_ REFCLSID rclsid, + _In_ REFIID riid, + _Out_ LPVOID* ppv +); + +#ifndef _MSC_VER +extern "C" +#endif +DXC_API_IMPORT HRESULT __stdcall DxcCreateInstance2( + _In_ IMalloc *pMalloc, + _In_ REFCLSID rclsid, + _In_ REFIID riid, + _Out_ LPVOID* ppv +); + +struct __declspec(uuid("5F956ED5-78D1-4B15-8247-F7187614A041")) +IDxbcConverter : public IUnknown { + /// Create DXIL container out of DXBC shader blob. + virtual HRESULT STDMETHODCALLTYPE Convert( + _In_reads_bytes_(DxbcSize) LPCVOID pDxbc, + _In_ UINT32 DxbcSize, + _In_opt_z_ LPCWSTR pExtraOptions, + _Outptr_result_bytebuffer_maybenull_(*pDxilSize) LPVOID *ppDxil, + _Out_ UINT32 *pDxilSize, + _Outptr_result_maybenull_z_ LPWSTR *ppDiag) = 0; + + /// Create DXIL LLVM module out of DXBC bytecode and DDI I/O signatures. + /// This is for driver consumption only. + virtual HRESULT STDMETHODCALLTYPE ConvertInDriver( + _In_reads_bytes_(pBytecode[1]) const UINT32 *pBytecode, + _In_opt_z_ LPCVOID pInputSignature, + _In_ UINT32 NumInputSignatureElements, + _In_opt_z_ LPCVOID pOutputSignature, + _In_ UINT32 NumOutputSignatureElements, + _In_opt_z_ LPCVOID pPatchConstantSignature, + _In_ UINT32 NumPatchConstantSignatureElements, + _In_opt_z_ LPCWSTR pExtraOptions, + _Out_ IDxcBlob **ppDxilModule, + _Outptr_result_maybenull_z_ LPWSTR *ppDiag) = 0; +}; + +__declspec(selectany) +extern const CLSID CLSID_DxbcConverter = { /* 4900391E-B752-4EDD-A885-6FB76E25ADDB */ + 0x4900391e, + 0xb752, + 0x4edd, + { 0xa8, 0x85, 0x6f, 0xb7, 0x6e, 0x25, 0xad, 0xdb } +}; + +#endif diff --git a/thirdparty/dxc/include/dxcapi.h b/thirdparty/dxc/include/dxcapi.h new file mode 100644 index 0000000..98f9b42 --- /dev/null +++ b/thirdparty/dxc/include/dxcapi.h @@ -0,0 +1,693 @@ + +/////////////////////////////////////////////////////////////////////////////// +// // +// dxcapi.h // +// Copyright (C) Microsoft Corporation. All rights reserved. // +// This file is distributed under the University of Illinois Open Source // +// License. See LICENSE.TXT for details. // +// // +// Provides declarations for the DirectX Compiler API entry point. // +// // +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __DXC_API__ +#define __DXC_API__ + +#ifdef _WIN32 +#ifndef DXC_API_IMPORT +#define DXC_API_IMPORT __declspec(dllimport) +#endif +#else +#ifndef DXC_API_IMPORT +#define DXC_API_IMPORT __attribute__ ((visibility ("default"))) +#endif +#endif + +#ifdef _WIN32 +#define DECLARE_CROSS_PLATFORM_UUIDOF(T) +#define DEFINE_CROSS_PLATFORM_UUIDOF(T) +#else +#include +#include "dxc/Support/WinAdapter.h" +#endif + +struct IMalloc; + +struct IDxcIncludeHandler; + +typedef HRESULT (__stdcall *DxcCreateInstanceProc)( + _In_ REFCLSID rclsid, + _In_ REFIID riid, + _Out_ LPVOID* ppv +); + +typedef HRESULT(__stdcall *DxcCreateInstance2Proc)( + _In_ IMalloc *pMalloc, + _In_ REFCLSID rclsid, + _In_ REFIID riid, + _Out_ LPVOID* ppv + ); + +/// +/// Creates a single uninitialized object of the class associated with a specified CLSID. +/// +/// +/// The CLSID associated with the data and code that will be used to create the object. +/// +/// +/// A reference to the identifier of the interface to be used to communicate +/// with the object. +/// +/// +/// Address of pointer variable that receives the interface pointer requested +/// in riid. Upon successful return, *ppv contains the requested interface +/// pointer. Upon failure, *ppv contains NULL. +/// +/// While this function is similar to CoCreateInstance, there is no COM involvement. +/// + +extern "C" +DXC_API_IMPORT HRESULT __stdcall DxcCreateInstance( + _In_ REFCLSID rclsid, + _In_ REFIID riid, + _Out_ LPVOID* ppv + ); + +extern "C" +DXC_API_IMPORT HRESULT __stdcall DxcCreateInstance2( + _In_ IMalloc *pMalloc, + _In_ REFCLSID rclsid, + _In_ REFIID riid, + _Out_ LPVOID* ppv +); + +// For convenience, equivalent definitions to CP_UTF8 and CP_UTF16. +#define DXC_CP_UTF8 65001 +#define DXC_CP_UTF16 1200 +// Use DXC_CP_ACP for: Binary; ANSI Text; Autodetect UTF with BOM +#define DXC_CP_ACP 0 + +// This flag indicates that the shader hash was computed taking into account source information (-Zss) +#define DXC_HASHFLAG_INCLUDES_SOURCE 1 + +// Hash digest type for ShaderHash +typedef struct DxcShaderHash { + UINT32 Flags; // DXC_HASHFLAG_* + BYTE HashDigest[16]; +} DxcShaderHash; + +#define DXC_FOURCC(ch0, ch1, ch2, ch3) ( \ + (UINT32)(UINT8)(ch0) | (UINT32)(UINT8)(ch1) << 8 | \ + (UINT32)(UINT8)(ch2) << 16 | (UINT32)(UINT8)(ch3) << 24 \ + ) +#define DXC_PART_PDB DXC_FOURCC('I', 'L', 'D', 'B') +#define DXC_PART_PDB_NAME DXC_FOURCC('I', 'L', 'D', 'N') +#define DXC_PART_PRIVATE_DATA DXC_FOURCC('P', 'R', 'I', 'V') +#define DXC_PART_ROOT_SIGNATURE DXC_FOURCC('R', 'T', 'S', '0') +#define DXC_PART_DXIL DXC_FOURCC('D', 'X', 'I', 'L') +#define DXC_PART_REFLECTION_DATA DXC_FOURCC('S', 'T', 'A', 'T') +#define DXC_PART_SHADER_HASH DXC_FOURCC('H', 'A', 'S', 'H') +#define DXC_PART_INPUT_SIGNATURE DXC_FOURCC('I', 'S', 'G', '1') +#define DXC_PART_OUTPUT_SIGNATURE DXC_FOURCC('O', 'S', 'G', '1') +#define DXC_PART_PATCH_CONSTANT_SIGNATURE DXC_FOURCC('P', 'S', 'G', '1') + +// Some option arguments are defined here for continuity with D3DCompile interface +#define DXC_ARG_DEBUG L"-Zi" +#define DXC_ARG_SKIP_VALIDATION L"-Vd" +#define DXC_ARG_SKIP_OPTIMIZATIONS L"-Od" +#define DXC_ARG_PACK_MATRIX_ROW_MAJOR L"-Zpr" +#define DXC_ARG_PACK_MATRIX_COLUMN_MAJOR L"-Zpc" +#define DXC_ARG_AVOID_FLOW_CONTROL L"-Gfa" +#define DXC_ARG_PREFER_FLOW_CONTROL L"-Gfp" +#define DXC_ARG_ENABLE_STRICTNESS L"-Ges" +#define DXC_ARG_ENABLE_BACKWARDS_COMPATIBILITY L"-Gec" +#define DXC_ARG_IEEE_STRICTNESS L"-Gis" +#define DXC_ARG_OPTIMIZATION_LEVEL0 L"-O0" +#define DXC_ARG_OPTIMIZATION_LEVEL1 L"-O1" +#define DXC_ARG_OPTIMIZATION_LEVEL2 L"-O2" +#define DXC_ARG_OPTIMIZATION_LEVEL3 L"-O3" +#define DXC_ARG_WARNINGS_ARE_ERRORS L"-WX" +#define DXC_ARG_RESOURCES_MAY_ALIAS L"-res_may_alias" +#define DXC_ARG_ALL_RESOURCES_BOUND L"-all_resources_bound" +#define DXC_ARG_DEBUG_NAME_FOR_SOURCE L"-Zss" +#define DXC_ARG_DEBUG_NAME_FOR_BINARY L"-Zsb" + +// IDxcBlob is an alias of ID3D10Blob and ID3DBlob +struct __declspec(uuid("8BA5FB08-5195-40e2-AC58-0D989C3A0102")) +IDxcBlob : public IUnknown { +public: + virtual LPVOID STDMETHODCALLTYPE GetBufferPointer(void) = 0; + virtual SIZE_T STDMETHODCALLTYPE GetBufferSize(void) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcBlob) +}; + +struct __declspec(uuid("7241d424-2646-4191-97c0-98e96e42fc68")) +IDxcBlobEncoding : public IDxcBlob { +public: + virtual HRESULT STDMETHODCALLTYPE GetEncoding(_Out_ BOOL *pKnown, + _Out_ UINT32 *pCodePage) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcBlobEncoding) +}; + +// Notes on IDxcBlobUtf16 and IDxcBlobUtf8 +// These guarantee null-terminated text and the stated encoding. +// GetBufferSize() will return the size in bytes, including null-terminator +// GetStringLength() will return the length in characters, excluding the null-terminator +// Name strings will use IDxcBlobUtf16, while other string output blobs, +// such as errors/warnings, preprocessed HLSL, or other text will be based +// on the -encoding option. + +// The API will use this interface for output name strings +struct __declspec(uuid("A3F84EAB-0FAA-497E-A39C-EE6ED60B2D84")) +IDxcBlobUtf16 : public IDxcBlobEncoding { +public: + virtual LPCWSTR STDMETHODCALLTYPE GetStringPointer(void) = 0; + virtual SIZE_T STDMETHODCALLTYPE GetStringLength(void) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcBlobUtf16) +}; +struct __declspec(uuid("3DA636C9-BA71-4024-A301-30CBF125305B")) +IDxcBlobUtf8 : public IDxcBlobEncoding { +public: + virtual LPCSTR STDMETHODCALLTYPE GetStringPointer(void) = 0; + virtual SIZE_T STDMETHODCALLTYPE GetStringLength(void) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcBlobUtf8) +}; + +struct __declspec(uuid("7f61fc7d-950d-467f-b3e3-3c02fb49187c")) +IDxcIncludeHandler : public IUnknown { + virtual HRESULT STDMETHODCALLTYPE LoadSource( + _In_z_ LPCWSTR pFilename, // Candidate filename. + _COM_Outptr_result_maybenull_ IDxcBlob **ppIncludeSource // Resultant source object for included file, nullptr if not found. + ) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcIncludeHandler) +}; + +// Structure for supplying bytes or text input to Dxc APIs. +// Use Encoding = 0 for non-text bytes, ANSI text, or unknown with BOM. +typedef struct DxcBuffer { + LPCVOID Ptr; + SIZE_T Size; + UINT Encoding; +} DxcText; + +struct DxcDefine { + LPCWSTR Name; + _Maybenull_ LPCWSTR Value; +}; + +struct __declspec(uuid("73EFFE2A-70DC-45F8-9690-EFF64C02429D")) +IDxcCompilerArgs : public IUnknown { + // Pass GetArguments() and GetCount() to Compile + virtual LPCWSTR* STDMETHODCALLTYPE GetArguments() = 0; + virtual UINT32 STDMETHODCALLTYPE GetCount() = 0; + + // Add additional arguments or defines here, if desired. + virtual HRESULT STDMETHODCALLTYPE AddArguments( + _In_opt_count_(argCount) LPCWSTR *pArguments, // Array of pointers to arguments to add + _In_ UINT32 argCount // Number of arguments to add + ) = 0; + virtual HRESULT STDMETHODCALLTYPE AddArgumentsUTF8( + _In_opt_count_(argCount)LPCSTR *pArguments, // Array of pointers to UTF-8 arguments to add + _In_ UINT32 argCount // Number of arguments to add + ) = 0; + virtual HRESULT STDMETHODCALLTYPE AddDefines( + _In_count_(defineCount) const DxcDefine *pDefines, // Array of defines + _In_ UINT32 defineCount // Number of defines + ) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcCompilerArgs) +}; + +////////////////////////// +// Legacy Interfaces +///////////////////////// + +// NOTE: IDxcUtils replaces IDxcLibrary +struct __declspec(uuid("e5204dc7-d18c-4c3c-bdfb-851673980fe7")) +IDxcLibrary : public IUnknown { + virtual HRESULT STDMETHODCALLTYPE SetMalloc(_In_opt_ IMalloc *pMalloc) = 0; + virtual HRESULT STDMETHODCALLTYPE CreateBlobFromBlob( + _In_ IDxcBlob *pBlob, UINT32 offset, UINT32 length, _COM_Outptr_ IDxcBlob **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE CreateBlobFromFile( + _In_z_ LPCWSTR pFileName, _In_opt_ UINT32* codePage, + _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0; + virtual HRESULT STDMETHODCALLTYPE CreateBlobWithEncodingFromPinned( + _In_bytecount_(size) LPCVOID pText, UINT32 size, UINT32 codePage, + _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0; + virtual HRESULT STDMETHODCALLTYPE CreateBlobWithEncodingOnHeapCopy( + _In_bytecount_(size) LPCVOID pText, UINT32 size, UINT32 codePage, + _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0; + virtual HRESULT STDMETHODCALLTYPE CreateBlobWithEncodingOnMalloc( + _In_bytecount_(size) LPCVOID pText, IMalloc *pIMalloc, UINT32 size, UINT32 codePage, + _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0; + virtual HRESULT STDMETHODCALLTYPE CreateIncludeHandler( + _COM_Outptr_ IDxcIncludeHandler **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE CreateStreamFromBlobReadOnly( + _In_ IDxcBlob *pBlob, _COM_Outptr_ IStream **ppStream) = 0; + virtual HRESULT STDMETHODCALLTYPE GetBlobAsUtf8( + _In_ IDxcBlob *pBlob, _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0; + virtual HRESULT STDMETHODCALLTYPE GetBlobAsUtf16( + _In_ IDxcBlob *pBlob, _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcLibrary) +}; + +// NOTE: IDxcResult replaces IDxcOperationResult +struct __declspec(uuid("CEDB484A-D4E9-445A-B991-CA21CA157DC2")) +IDxcOperationResult : public IUnknown { + virtual HRESULT STDMETHODCALLTYPE GetStatus(_Out_ HRESULT *pStatus) = 0; + + // GetResult returns the main result of the operation. + // This corresponds to: + // DXC_OUT_OBJECT - Compile() with shader or library target + // DXC_OUT_DISASSEMBLY - Disassemble() + // DXC_OUT_HLSL - Compile() with -P + // DXC_OUT_ROOT_SIGNATURE - Compile() with rootsig_* target + virtual HRESULT STDMETHODCALLTYPE GetResult(_COM_Outptr_result_maybenull_ IDxcBlob **ppResult) = 0; + + // GetErrorBuffer Corresponds to DXC_OUT_ERRORS. + virtual HRESULT STDMETHODCALLTYPE GetErrorBuffer(_COM_Outptr_result_maybenull_ IDxcBlobEncoding **ppErrors) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcOperationResult) +}; + +// NOTE: IDxcCompiler3 replaces IDxcCompiler and IDxcCompiler2 +struct __declspec(uuid("8c210bf3-011f-4422-8d70-6f9acb8db617")) +IDxcCompiler : public IUnknown { + // Compile a single entry point to the target shader model + virtual HRESULT STDMETHODCALLTYPE Compile( + _In_ IDxcBlob *pSource, // Source text to compile + _In_opt_z_ LPCWSTR pSourceName, // Optional file name for pSource. Used in errors and include handlers. + _In_opt_z_ LPCWSTR pEntryPoint, // entry point name + _In_z_ LPCWSTR pTargetProfile, // shader profile to compile + _In_opt_count_(argCount) LPCWSTR *pArguments, // Array of pointers to arguments + _In_ UINT32 argCount, // Number of arguments + _In_count_(defineCount) + const DxcDefine *pDefines, // Array of defines + _In_ UINT32 defineCount, // Number of defines + _In_opt_ IDxcIncludeHandler *pIncludeHandler, // user-provided interface to handle #include directives (optional) + _COM_Outptr_ IDxcOperationResult **ppResult // Compiler output status, buffer, and errors + ) = 0; + + // Preprocess source text + virtual HRESULT STDMETHODCALLTYPE Preprocess( + _In_ IDxcBlob *pSource, // Source text to preprocess + _In_opt_z_ LPCWSTR pSourceName, // Optional file name for pSource. Used in errors and include handlers. + _In_opt_count_(argCount) LPCWSTR *pArguments, // Array of pointers to arguments + _In_ UINT32 argCount, // Number of arguments + _In_count_(defineCount) + const DxcDefine *pDefines, // Array of defines + _In_ UINT32 defineCount, // Number of defines + _In_opt_ IDxcIncludeHandler *pIncludeHandler, // user-provided interface to handle #include directives (optional) + _COM_Outptr_ IDxcOperationResult **ppResult // Preprocessor output status, buffer, and errors + ) = 0; + + // Disassemble a program. + virtual HRESULT STDMETHODCALLTYPE Disassemble( + _In_ IDxcBlob *pSource, // Program to disassemble. + _COM_Outptr_ IDxcBlobEncoding **ppDisassembly // Disassembly text. + ) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcCompiler) +}; + +// NOTE: IDxcCompiler3 replaces IDxcCompiler and IDxcCompiler2 +struct __declspec(uuid("A005A9D9-B8BB-4594-B5C9-0E633BEC4D37")) +IDxcCompiler2 : public IDxcCompiler { + // Compile a single entry point to the target shader model with debug information. + virtual HRESULT STDMETHODCALLTYPE CompileWithDebug( + _In_ IDxcBlob *pSource, // Source text to compile + _In_opt_z_ LPCWSTR pSourceName, // Optional file name for pSource. Used in errors and include handlers. + _In_opt_z_ LPCWSTR pEntryPoint, // Entry point name + _In_z_ LPCWSTR pTargetProfile, // Shader profile to compile + _In_opt_count_(argCount) LPCWSTR *pArguments, // Array of pointers to arguments + _In_ UINT32 argCount, // Number of arguments + _In_count_(defineCount) + const DxcDefine *pDefines, // Array of defines + _In_ UINT32 defineCount, // Number of defines + _In_opt_ IDxcIncludeHandler *pIncludeHandler, // user-provided interface to handle #include directives (optional) + _COM_Outptr_ IDxcOperationResult **ppResult, // Compiler output status, buffer, and errors + _Outptr_opt_result_z_ LPWSTR *ppDebugBlobName,// Suggested file name for debug blob. (Must be HeapFree()'d!) + _COM_Outptr_opt_ IDxcBlob **ppDebugBlob // Debug blob + ) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcCompiler2) +}; + +struct __declspec(uuid("F1B5BE2A-62DD-4327-A1C2-42AC1E1E78E6")) +IDxcLinker : public IUnknown { +public: + // Register a library with name to ref it later. + virtual HRESULT RegisterLibrary( + _In_opt_ LPCWSTR pLibName, // Name of the library. + _In_ IDxcBlob *pLib // Library blob. + ) = 0; + + // Links the shader and produces a shader blob that the Direct3D runtime can + // use. + virtual HRESULT STDMETHODCALLTYPE Link( + _In_opt_ LPCWSTR pEntryName, // Entry point name + _In_ LPCWSTR pTargetProfile, // shader profile to link + _In_count_(libCount) + const LPCWSTR *pLibNames, // Array of library names to link + _In_ UINT32 libCount, // Number of libraries to link + _In_opt_count_(argCount) const LPCWSTR *pArguments, // Array of pointers to arguments + _In_ UINT32 argCount, // Number of arguments + _COM_Outptr_ + IDxcOperationResult **ppResult // Linker output status, buffer, and errors + ) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcLinker) +}; + +///////////////////////// +// Latest interfaces. Please use these +//////////////////////// + +// NOTE: IDxcUtils replaces IDxcLibrary +struct __declspec(uuid("4605C4CB-2019-492A-ADA4-65F20BB7D67F")) +IDxcUtils : public IUnknown { + // Create a sub-blob that holds a reference to the outer blob and points to its memory. + virtual HRESULT STDMETHODCALLTYPE CreateBlobFromBlob( + _In_ IDxcBlob *pBlob, UINT32 offset, UINT32 length, _COM_Outptr_ IDxcBlob **ppResult) = 0; + + // For codePage, use 0 (or DXC_CP_ACP) for raw binary or ANSI code page + + // Creates a blob referencing existing memory, with no copy. + // User must manage the memory lifetime separately. + // (was: CreateBlobWithEncodingFromPinned) + virtual HRESULT STDMETHODCALLTYPE CreateBlobFromPinned( + _In_bytecount_(size) LPCVOID pData, UINT32 size, UINT32 codePage, + _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0; + + // Create blob, taking ownership of memory allocated with supplied allocator. + // (was: CreateBlobWithEncodingOnMalloc) + virtual HRESULT STDMETHODCALLTYPE MoveToBlob( + _In_bytecount_(size) LPCVOID pData, IMalloc *pIMalloc, UINT32 size, UINT32 codePage, + _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0; + + //// + // New blobs and copied contents are allocated with the current allocator + + // Copy blob contents to memory owned by the new blob. + // (was: CreateBlobWithEncodingOnHeapCopy) + virtual HRESULT STDMETHODCALLTYPE CreateBlob( + _In_bytecount_(size) LPCVOID pData, UINT32 size, UINT32 codePage, + _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0; + + // (was: CreateBlobFromFile) + virtual HRESULT STDMETHODCALLTYPE LoadFile( + _In_z_ LPCWSTR pFileName, _In_opt_ UINT32* pCodePage, + _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateReadOnlyStreamFromBlob( + _In_ IDxcBlob *pBlob, _COM_Outptr_ IStream **ppStream) = 0; + + // Create default file-based include handler + virtual HRESULT STDMETHODCALLTYPE CreateDefaultIncludeHandler( + _COM_Outptr_ IDxcIncludeHandler **ppResult) = 0; + + // Convert or return matching encoded text blobs + virtual HRESULT STDMETHODCALLTYPE GetBlobAsUtf8( + _In_ IDxcBlob *pBlob, _COM_Outptr_ IDxcBlobUtf8 **pBlobEncoding) = 0; + virtual HRESULT STDMETHODCALLTYPE GetBlobAsUtf16( + _In_ IDxcBlob *pBlob, _COM_Outptr_ IDxcBlobUtf16 **pBlobEncoding) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDxilContainerPart( + _In_ const DxcBuffer *pShader, + _In_ UINT32 DxcPart, + _Outptr_result_nullonfailure_ void **ppPartData, + _Out_ UINT32 *pPartSizeInBytes) = 0; + + // Create reflection interface from serialized Dxil container, or DXC_PART_REFLECTION_DATA. + // TBD: Require part header for RDAT? (leaning towards yes) + virtual HRESULT STDMETHODCALLTYPE CreateReflection( + _In_ const DxcBuffer *pData, REFIID iid, void **ppvReflection) = 0; + + virtual HRESULT STDMETHODCALLTYPE BuildArguments( + _In_opt_z_ LPCWSTR pSourceName, // Optional file name for pSource. Used in errors and include handlers. + _In_opt_z_ LPCWSTR pEntryPoint, // Entry point name. (-E) + _In_z_ LPCWSTR pTargetProfile, // Shader profile to compile. (-T) + _In_opt_count_(argCount) LPCWSTR *pArguments, // Array of pointers to arguments + _In_ UINT32 argCount, // Number of arguments + _In_count_(defineCount) + const DxcDefine *pDefines, // Array of defines + _In_ UINT32 defineCount, // Number of defines + _COM_Outptr_ IDxcCompilerArgs **ppArgs // Arguments you can use with Compile() method + ) = 0; + + // Takes the shader PDB and returns the hash and the container inside it + virtual HRESULT STDMETHODCALLTYPE GetPDBContents( + _In_ IDxcBlob *pPDBBlob, _COM_Outptr_ IDxcBlob **ppHash, _COM_Outptr_ IDxcBlob **ppContainer) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcUtils) +}; + +// For use with IDxcResult::[Has|Get]Output dxcOutKind argument +// Note: text outputs returned from version 2 APIs are UTF-8 or UTF-16 based on -encoding option +typedef enum DXC_OUT_KIND { + DXC_OUT_NONE = 0, + DXC_OUT_OBJECT = 1, // IDxcBlob - Shader or library object + DXC_OUT_ERRORS = 2, // IDxcBlobUtf8 or IDxcBlobUtf16 + DXC_OUT_PDB = 3, // IDxcBlob + DXC_OUT_SHADER_HASH = 4, // IDxcBlob - DxcShaderHash of shader or shader with source info (-Zsb/-Zss) + DXC_OUT_DISASSEMBLY = 5, // IDxcBlobUtf8 or IDxcBlobUtf16 - from Disassemble + DXC_OUT_HLSL = 6, // IDxcBlobUtf8 or IDxcBlobUtf16 - from Preprocessor or Rewriter + DXC_OUT_TEXT = 7, // IDxcBlobUtf8 or IDxcBlobUtf16 - other text, such as -ast-dump or -Odump + DXC_OUT_REFLECTION = 8, // IDxcBlob - RDAT part with reflection data + DXC_OUT_ROOT_SIGNATURE = 9, // IDxcBlob - Serialized root signature output + DXC_OUT_EXTRA_OUTPUTS = 10,// IDxcExtraResults - Extra outputs + + DXC_OUT_FORCE_DWORD = 0xFFFFFFFF +} DXC_OUT_KIND; + +struct __declspec(uuid("58346CDA-DDE7-4497-9461-6F87AF5E0659")) +IDxcResult : public IDxcOperationResult { + virtual BOOL STDMETHODCALLTYPE HasOutput(_In_ DXC_OUT_KIND dxcOutKind) = 0; + virtual HRESULT STDMETHODCALLTYPE GetOutput(_In_ DXC_OUT_KIND dxcOutKind, + _In_ REFIID iid, _COM_Outptr_opt_result_maybenull_ void **ppvObject, + _COM_Outptr_ IDxcBlobUtf16 **ppOutputName) = 0; + + virtual UINT32 GetNumOutputs() = 0; + virtual DXC_OUT_KIND GetOutputByIndex(UINT32 Index) = 0; + virtual DXC_OUT_KIND PrimaryOutput() = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcResult) +}; + +// Special names for extra output that should get written to specific streams +#define DXC_EXTRA_OUTPUT_NAME_STDOUT L"*stdout*" +#define DXC_EXTRA_OUTPUT_NAME_STDERR L"*stderr*" + +struct __declspec(uuid("319b37a2-a5c2-494a-a5de-4801b2faf989")) +IDxcExtraOutputs : public IUnknown { + + virtual UINT32 STDMETHODCALLTYPE GetOutputCount() = 0; + virtual HRESULT STDMETHODCALLTYPE GetOutput(_In_ UINT32 uIndex, + _In_ REFIID iid, _COM_Outptr_opt_result_maybenull_ void **ppvObject, + _COM_Outptr_opt_result_maybenull_ IDxcBlobUtf16 **ppOutputType, + _COM_Outptr_opt_result_maybenull_ IDxcBlobUtf16 **ppOutputName) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcExtraOutputs) +}; + +struct __declspec(uuid("228B4687-5A6A-4730-900C-9702B2203F54")) +IDxcCompiler3 : public IUnknown { + // Compile a single entry point to the target shader model, + // Compile a library to a library target (-T lib_*), + // Compile a root signature (-T rootsig_*), or + // Preprocess HLSL source (-P) + virtual HRESULT STDMETHODCALLTYPE Compile( + _In_ const DxcBuffer *pSource, // Source text to compile + _In_opt_count_(argCount) LPCWSTR *pArguments, // Array of pointers to arguments + _In_ UINT32 argCount, // Number of arguments + _In_opt_ IDxcIncludeHandler *pIncludeHandler, // user-provided interface to handle #include directives (optional) + _In_ REFIID riid, _Out_ LPVOID *ppResult // IDxcResult: status, buffer, and errors + ) = 0; + + // Disassemble a program. + virtual HRESULT STDMETHODCALLTYPE Disassemble( + _In_ const DxcBuffer *pObject, // Program to disassemble: dxil container or bitcode. + _In_ REFIID riid, _Out_ LPVOID *ppResult // IDxcResult: status, disassembly text, and errors + ) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcCompiler3) +}; + +static const UINT32 DxcValidatorFlags_Default = 0; +static const UINT32 DxcValidatorFlags_InPlaceEdit = 1; // Validator is allowed to update shader blob in-place. +static const UINT32 DxcValidatorFlags_RootSignatureOnly = 2; +static const UINT32 DxcValidatorFlags_ModuleOnly = 4; +static const UINT32 DxcValidatorFlags_ValidMask = 0x7; + +struct __declspec(uuid("A6E82BD2-1FD7-4826-9811-2857E797F49A")) +IDxcValidator : public IUnknown { + // Validate a shader. + virtual HRESULT STDMETHODCALLTYPE Validate( + _In_ IDxcBlob *pShader, // Shader to validate. + _In_ UINT32 Flags, // Validation flags. + _COM_Outptr_ IDxcOperationResult **ppResult // Validation output status, buffer, and errors + ) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcValidator) +}; + +struct __declspec(uuid("334b1f50-2292-4b35-99a1-25588d8c17fe")) +IDxcContainerBuilder : public IUnknown { + virtual HRESULT STDMETHODCALLTYPE Load(_In_ IDxcBlob *pDxilContainerHeader) = 0; // Loads DxilContainer to the builder + virtual HRESULT STDMETHODCALLTYPE AddPart(_In_ UINT32 fourCC, _In_ IDxcBlob *pSource) = 0; // Part to add to the container + virtual HRESULT STDMETHODCALLTYPE RemovePart(_In_ UINT32 fourCC) = 0; // Remove the part with fourCC + virtual HRESULT STDMETHODCALLTYPE SerializeContainer(_Out_ IDxcOperationResult **ppResult) = 0; // Builds a container of the given container builder state + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcContainerBuilder) +}; + +struct __declspec(uuid("091f7a26-1c1f-4948-904b-e6e3a8a771d5")) +IDxcAssembler : public IUnknown { + // Assemble dxil in ll or llvm bitcode to DXIL container. + virtual HRESULT STDMETHODCALLTYPE AssembleToContainer( + _In_ IDxcBlob *pShader, // Shader to assemble. + _COM_Outptr_ IDxcOperationResult **ppResult // Assembly output status, buffer, and errors + ) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcAssembler) +}; + +struct __declspec(uuid("d2c21b26-8350-4bdc-976a-331ce6f4c54c")) +IDxcContainerReflection : public IUnknown { + virtual HRESULT STDMETHODCALLTYPE Load(_In_ IDxcBlob *pContainer) = 0; // Container to load. + virtual HRESULT STDMETHODCALLTYPE GetPartCount(_Out_ UINT32 *pResult) = 0; + virtual HRESULT STDMETHODCALLTYPE GetPartKind(UINT32 idx, _Out_ UINT32 *pResult) = 0; + virtual HRESULT STDMETHODCALLTYPE GetPartContent(UINT32 idx, _COM_Outptr_ IDxcBlob **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE FindFirstPartKind(UINT32 kind, _Out_ UINT32 *pResult) = 0; + virtual HRESULT STDMETHODCALLTYPE GetPartReflection(UINT32 idx, REFIID iid, void **ppvObject) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcContainerReflection) +}; + +struct __declspec(uuid("AE2CD79F-CC22-453F-9B6B-B124E7A5204C")) +IDxcOptimizerPass : public IUnknown { + virtual HRESULT STDMETHODCALLTYPE GetOptionName(_COM_Outptr_ LPWSTR *ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE GetDescription(_COM_Outptr_ LPWSTR *ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE GetOptionArgCount(_Out_ UINT32 *pCount) = 0; + virtual HRESULT STDMETHODCALLTYPE GetOptionArgName(UINT32 argIndex, _COM_Outptr_ LPWSTR *ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE GetOptionArgDescription(UINT32 argIndex, _COM_Outptr_ LPWSTR *ppResult) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcOptimizerPass) +}; + +struct __declspec(uuid("25740E2E-9CBA-401B-9119-4FB42F39F270")) +IDxcOptimizer : public IUnknown { + virtual HRESULT STDMETHODCALLTYPE GetAvailablePassCount(_Out_ UINT32 *pCount) = 0; + virtual HRESULT STDMETHODCALLTYPE GetAvailablePass(UINT32 index, _COM_Outptr_ IDxcOptimizerPass** ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE RunOptimizer(IDxcBlob *pBlob, + _In_count_(optionCount) LPCWSTR *ppOptions, UINT32 optionCount, + _COM_Outptr_ IDxcBlob **pOutputModule, + _COM_Outptr_opt_ IDxcBlobEncoding **ppOutputText) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcOptimizer) +}; + +static const UINT32 DxcVersionInfoFlags_None = 0; +static const UINT32 DxcVersionInfoFlags_Debug = 1; // Matches VS_FF_DEBUG +static const UINT32 DxcVersionInfoFlags_Internal = 2; // Internal Validator (non-signing) + +struct __declspec(uuid("b04f5b50-2059-4f12-a8ff-a1e0cde1cc7e")) +IDxcVersionInfo : public IUnknown { + virtual HRESULT STDMETHODCALLTYPE GetVersion(_Out_ UINT32 *pMajor, _Out_ UINT32 *pMinor) = 0; + virtual HRESULT STDMETHODCALLTYPE GetFlags(_Out_ UINT32 *pFlags) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcVersionInfo) +}; + +struct __declspec(uuid("fb6904c4-42f0-4b62-9c46-983af7da7c83")) +IDxcVersionInfo2 : public IDxcVersionInfo { + virtual HRESULT STDMETHODCALLTYPE GetCommitInfo(_Out_ UINT32 *pCommitCount, _Out_ char **pCommitHash) = 0; + + DECLARE_CROSS_PLATFORM_UUIDOF(IDxcVersionInfo2) +}; + +// Note: __declspec(selectany) requires 'extern' +// On Linux __declspec(selectany) is removed and using 'extern' results in link error. +#ifdef _MSC_VER +#define CLSID_SCOPE __declspec(selectany) extern +#else +#define CLSID_SCOPE +#endif + +CLSID_SCOPE const CLSID CLSID_DxcCompiler = { + 0x73e22d93, + 0xe6ce, + 0x47f3, + {0xb5, 0xbf, 0xf0, 0x66, 0x4f, 0x39, 0xc1, 0xb0}}; + +// {EF6A8087-B0EA-4D56-9E45-D07E1A8B7806} +CLSID_SCOPE const GUID CLSID_DxcLinker = { + 0xef6a8087, + 0xb0ea, + 0x4d56, + {0x9e, 0x45, 0xd0, 0x7e, 0x1a, 0x8b, 0x78, 0x6}}; + +// {CD1F6B73-2AB0-484D-8EDC-EBE7A43CA09F} +CLSID_SCOPE const CLSID CLSID_DxcDiaDataSource = { + 0xcd1f6b73, + 0x2ab0, + 0x484d, + {0x8e, 0xdc, 0xeb, 0xe7, 0xa4, 0x3c, 0xa0, 0x9f}}; + +// {3E56AE82-224D-470F-A1A1-FE3016EE9F9D} +CLSID_SCOPE const CLSID CLSID_DxcCompilerArgs = { + 0x3e56ae82, + 0x224d, + 0x470f, + {0xa1, 0xa1, 0xfe, 0x30, 0x16, 0xee, 0x9f, 0x9d}}; + +// {6245D6AF-66E0-48FD-80B4-4D271796748C} +CLSID_SCOPE const GUID CLSID_DxcLibrary = { + 0x6245d6af, + 0x66e0, + 0x48fd, + {0x80, 0xb4, 0x4d, 0x27, 0x17, 0x96, 0x74, 0x8c}}; + +CLSID_SCOPE const GUID CLSID_DxcUtils = CLSID_DxcLibrary; + +// {8CA3E215-F728-4CF3-8CDD-88AF917587A1} +CLSID_SCOPE const GUID CLSID_DxcValidator = { + 0x8ca3e215, + 0xf728, + 0x4cf3, + {0x8c, 0xdd, 0x88, 0xaf, 0x91, 0x75, 0x87, 0xa1}}; + +// {D728DB68-F903-4F80-94CD-DCCF76EC7151} +CLSID_SCOPE const GUID CLSID_DxcAssembler = { + 0xd728db68, + 0xf903, + 0x4f80, + {0x94, 0xcd, 0xdc, 0xcf, 0x76, 0xec, 0x71, 0x51}}; + +// {b9f54489-55b8-400c-ba3a-1675e4728b91} +CLSID_SCOPE const GUID CLSID_DxcContainerReflection = { + 0xb9f54489, + 0x55b8, + 0x400c, + {0xba, 0x3a, 0x16, 0x75, 0xe4, 0x72, 0x8b, 0x91}}; + +// {AE2CD79F-CC22-453F-9B6B-B124E7A5204C} +CLSID_SCOPE const GUID CLSID_DxcOptimizer = { + 0xae2cd79f, + 0xcc22, + 0x453f, + {0x9b, 0x6b, 0xb1, 0x24, 0xe7, 0xa5, 0x20, 0x4c}}; + +// {94134294-411f-4574-b4d0-8741e25240d2} +CLSID_SCOPE const GUID CLSID_DxcContainerBuilder = { + 0x94134294, + 0x411f, + 0x4574, + {0xb4, 0xd0, 0x87, 0x41, 0xe2, 0x52, 0x40, 0xd2}}; +#endif diff --git a/thirdparty/ffmpeg-overlay/bsf_list.c b/thirdparty/ffmpeg-overlay/bsf_list.c new file mode 100644 index 0000000..2ae103b --- /dev/null +++ b/thirdparty/ffmpeg-overlay/bsf_list.c @@ -0,0 +1,5 @@ +static const AVBitStreamFilter* const bitstream_filters[] = { +#if CONFIG_NULL_BSF + &ff_null_bsf, +#endif + NULL}; diff --git a/thirdparty/ffmpeg-overlay/codec_list.c b/thirdparty/ffmpeg-overlay/codec_list.c new file mode 100644 index 0000000..8f32113 --- /dev/null +++ b/thirdparty/ffmpeg-overlay/codec_list.c @@ -0,0 +1,17 @@ +static const AVCodec* const codec_list[] = { +#if CONFIG_MP3FLOAT_DECODER + &ff_mp3float_decoder, +#endif +#if CONFIG_MP3_DECODER + &ff_mp3_decoder, +#endif +#if CONFIG_WMAPRO_DECODER + &ff_wmapro_decoder, +#endif +#if CONFIG_WMAV2_DECODER + &ff_wmav2_decoder, +#endif +#if CONFIG_XMAFRAMES_DECODER + &ff_xmaframes_decoder, +#endif + NULL}; diff --git a/thirdparty/ffmpeg-overlay/parser_list.c b/thirdparty/ffmpeg-overlay/parser_list.c new file mode 100644 index 0000000..3eb1220 --- /dev/null +++ b/thirdparty/ffmpeg-overlay/parser_list.c @@ -0,0 +1,5 @@ +static const AVCodecParser* const parser_list[] = { +#if CONFIG_MPEGAUDIO_PARSER + &ff_mpegaudio_parser, +#endif + NULL}; diff --git a/thirdparty/fmt b/thirdparty/fmt new file mode 160000 index 0000000..407c905 --- /dev/null +++ b/thirdparty/fmt @@ -0,0 +1 @@ +Subproject commit 407c905e45ad75fc29bf0f9bb7c5c2fd3475976f diff --git a/thirdparty/glslang b/thirdparty/glslang new file mode 160000 index 0000000..f4f1d8a --- /dev/null +++ b/thirdparty/glslang @@ -0,0 +1 @@ +Subproject commit f4f1d8a352ca1908943aea2ad8c54b39b4879080 diff --git a/thirdparty/imgui b/thirdparty/imgui new file mode 160000 index 0000000..6d910d5 --- /dev/null +++ b/thirdparty/imgui @@ -0,0 +1 @@ +Subproject commit 6d910d5487d11ca567b61c7824b0c78c569d62f0 diff --git a/thirdparty/inja b/thirdparty/inja new file mode 160000 index 0000000..7d1b460 --- /dev/null +++ b/thirdparty/inja @@ -0,0 +1 @@ +Subproject commit 7d1b4600b68595085a949743331c2e5673f511ea diff --git a/thirdparty/libmspack b/thirdparty/libmspack new file mode 160000 index 0000000..3059077 --- /dev/null +++ b/thirdparty/libmspack @@ -0,0 +1 @@ +Subproject commit 305907723a4e7ab2018e58040059ffb5e77db837 diff --git a/thirdparty/o1heap b/thirdparty/o1heap new file mode 160000 index 0000000..388a73f --- /dev/null +++ b/thirdparty/o1heap @@ -0,0 +1 @@ +Subproject commit 388a73fd9007300e5130c5fe352d9ce3288b6dde diff --git a/thirdparty/pe/pe_image.h b/thirdparty/pe/pe_image.h new file mode 100644 index 0000000..e2e694b --- /dev/null +++ b/thirdparty/pe/pe_image.h @@ -0,0 +1,1022 @@ +/* Xenia: minor tweaks to bring up to date with winnt.h */ + +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* NT image format (to be used when the Win32 SDK version of WINNT.H cannot) */ + +#ifndef UNALIGNED +/* BUGBUG fixme */ +#define UNALIGNED +#endif + +#ifdef _MSC_VER +#pragma pack (1) +#endif + +// MODIFIED: on Windows a few definitions aren't in WINNT +#ifdef IMAGE_NT_SIGNATURE +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224 +#define IMAGE_FILE_MACHINE_POWERPCBE 0x01F2 // IBM PowerPC Big-Endian +#endif + +/* Skip if WINNT.H already included. We check IMAGE_NT_SIGNATURE instead of _WINNT_, + * because WinCE's version of WINNT.H defines _WINNT_ but it doesn't include everything here + */ +#ifndef IMAGE_NT_SIGNATURE + +#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */ +#define IMAGE_OS2_SIGNATURE 0x454E /* NE */ +#define IMAGE_OS2_SIGNATURE_LE 0x454C /* LE */ +#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */ + +typedef struct _IMAGE_DOS_HEADER { /* DOS .EXE header */ + uint16_t e_magic; /* Magic number */ + uint16_t e_cblp; /* Bytes on last page of file */ + uint16_t e_cp; /* Pages in file */ + uint16_t e_crlc; /* Relocations */ + uint16_t e_cparhdr; /* Size of header in paragraphs */ + uint16_t e_minalloc; /* Minimum extra paragraphs needed */ + uint16_t e_maxalloc; /* Maximum extra paragraphs needed */ + uint16_t e_ss; /* Initial (relative) SS value */ + uint16_t e_sp; /* Initial SP value */ + uint16_t e_csum; /* Checksum */ + uint16_t e_ip; /* Initial IP value */ + uint16_t e_cs; /* Initial (relative) CS value */ + uint16_t e_lfarlc; /* File address of relocation table */ + uint16_t e_ovno; /* Overlay number */ + uint16_t e_res[4]; /* Reserved words */ + uint16_t e_oemid; /* OEM identifier (for e_oeminfo) */ + uint16_t e_oeminfo; /* OEM information; e_oemid specific */ + uint16_t e_res2[10]; /* Reserved words */ + int32_t e_lfanew; /* File address of new exe header */ + } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; + +typedef struct _IMAGE_OS2_HEADER { /* OS/2 .EXE header */ + uint16_t ne_magic; /* Magic number */ + int8_t ne_ver; /* Version number */ + int8_t ne_rev; /* Revision number */ + uint16_t ne_enttab; /* Offset of Entry Table */ + uint16_t ne_cbenttab; /* Number of bytes in Entry Table */ + int32_t ne_crc; /* Checksum of whole file */ + uint16_t ne_flags; /* Flag word */ + uint16_t ne_autodata; /* Automatic data segment number */ + uint16_t ne_heap; /* Initial heap allocation */ + uint16_t ne_stack; /* Initial stack allocation */ + int32_t ne_csip; /* Initial CS:IP setting */ + int32_t ne_sssp; /* Initial SS:SP setting */ + uint16_t ne_cseg; /* Count of file segments */ + uint16_t ne_cmod; /* Entries in Module Reference Table */ + uint16_t ne_cbnrestab; /* Size of non-resident name table */ + uint16_t ne_segtab; /* Offset of Segment Table */ + uint16_t ne_rsrctab; /* Offset of Resource Table */ + uint16_t ne_restab; /* Offset of resident name table */ + uint16_t ne_modtab; /* Offset of Module Reference Table */ + uint16_t ne_imptab; /* Offset of Imported Names Table */ + int32_t ne_nrestab; /* Offset of Non-resident Names Table */ + uint16_t ne_cmovent; /* Count of movable entries */ + uint16_t ne_align; /* Segment alignment shift count */ + uint16_t ne_cres; /* Count of resource segments */ + uint8_t ne_exetyp; /* Target Operating system */ + uint8_t ne_flagsothers; /* Other .EXE flags */ + uint16_t ne_pretthunks; /* offset to return thunks */ + uint16_t ne_psegrefbytes; /* offset to segment ref. bytes */ + uint16_t ne_swaparea; /* Minimum code swap area size */ + uint16_t ne_expver; /* Expected Windows version number */ + } IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER; + +/* + * File header format. + */ + +typedef struct _IMAGE_FILE_HEADER { + uint16_t Machine; + uint16_t NumberOfSections; + uint32_t TimeDateStamp; + uint32_t PointerToSymbolTable; + uint32_t NumberOfSymbols; + uint16_t SizeOfOptionalHeader; + uint16_t Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + +#define IMAGE_SIZEOF_FILE_HEADER 20 + +#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 /* Relocation info stripped from file. */ +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 /* File is executable (i.e. no unresolved externel references). */ +#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 /* Line nunbers stripped from file. */ +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 /* Local symbols stripped from file. */ +#define IMAGE_FILE_MINIMAL_OBJECT 0x0010 /* Reserved. */ +#define IMAGE_FILE_UPDATE_OBJECT 0x0020 /* Reserved. */ +#define IMAGE_FILE_16BIT_MACHINE 0x0040 /* 16 bit word machine. */ +#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 /* Bytes of machine word are reversed. */ +#define IMAGE_FILE_32BIT_MACHINE 0x0100 /* 32 bit word machine. */ +#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 /* Debugging info stripped from file in .DBG file */ +#define IMAGE_FILE_PATCH 0x0400 /* Reserved. */ +#define IMAGE_FILE_SYSTEM 0x1000 /* System File. */ +#define IMAGE_FILE_DLL 0x2000 /* File is a DLL. */ +#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 /* Bytes of machine word are reversed. */ + +#define IMAGE_FILE_MACHINE_UNKNOWN 0 +#define IMAGE_FILE_MACHINE_I860 0x14d /* Intel 860. */ +#define IMAGE_FILE_MACHINE_I386 0x14c /* Intel 386. */ +#define IMAGE_FILE_MACHINE_R3000 0x162 /* MIPS little-endian, 0540 big-endian */ +#define IMAGE_FILE_MACHINE_R4000 0x166 /* MIPS little-endian */ +#define IMAGE_FILE_MACHINE_R10000 0x0168 // MIPS little-endian +#define IMAGE_FILE_MACHINE_ALPHA 0x184 /* Alpha_AXP */ +#define IMAGE_FILE_MACHINE_POWERPC 0x01F0 // IBM PowerPC Little-Endian +#define IMAGE_FILE_MACHINE_POWERPCBE 0x01F2 // IBM PowerPC Big-Endian +#define IMAGE_FILE_MACHINE_SH3 0x01a2 // SH3 little-endian +#define IMAGE_FILE_MACHINE_SH3E 0x01a4 // SH3E little-endian +#define IMAGE_FILE_MACHINE_SH4 0x01a6 // SH4 little-endian +#define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian +#define IMAGE_FILE_MACHINE_THUMB 0x01c2 +#define IMAGE_FILE_MACHINE_IA64 0x0200 // Intel 64 +#define IMAGE_FILE_MACHINE_MIPS16 0x0266 // MIPS +#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 // MIPS +#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 // MIPS +#define IMAGE_FILE_MACHINE_ALPHA64 0x0284 // ALPHA64 +#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64 +#define IMAGE_FILE_MACHINE_CEF 0xC0EF + +/* + * Directory format. + */ + +typedef struct _IMAGE_DATA_DIRECTORY { + uint32_t VirtualAddress; + uint32_t Size; +} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + +/* + * Optional header format. + */ + +typedef struct _IMAGE_OPTIONAL_HEADER { + /* + * Standard fields. + */ + + uint16_t Magic; + uint8_t MajorLinkerVersion; + uint8_t MinorLinkerVersion; + uint32_t SizeOfCode; + uint32_t SizeOfInitializedData; + uint32_t SizeOfUninitializedData; + uint32_t AddressOfEntryPoint; + uint32_t BaseOfCode; + uint32_t BaseOfData; + + /* + * NT additional fields. + */ + + uint32_t ImageBase; + uint32_t SectionAlignment; + uint32_t FileAlignment; + uint16_t MajorOperatingSystemVersion; + uint16_t MinorOperatingSystemVersion; + uint16_t MajorImageVersion; + uint16_t MinorImageVersion; + uint16_t MajorSubsystemVersion; + uint16_t MinorSubsystemVersion; + uint32_t Reserved1; + uint32_t SizeOfImage; + uint32_t SizeOfHeaders; + uint32_t CheckSum; + uint16_t Subsystem; + uint16_t DllCharacteristics; + uint32_t SizeOfStackReserve; + uint32_t SizeOfStackCommit; + uint32_t SizeOfHeapReserve; + uint32_t SizeOfHeapCommit; + uint32_t LoaderFlags; + uint32_t NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER; + +typedef IMAGE_OPTIONAL_HEADER IMAGE_OPTIONAL_HEADER32; + +#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28 +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224 + +#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b + +#ifdef _WIN64 +#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR64_MAGIC +#else +#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR32_MAGIC +#endif + +typedef struct _IMAGE_NT_HEADERS { + uint32_t Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER OptionalHeader; +} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS; + +typedef IMAGE_NT_HEADERS IMAGE_NT_HEADERS32; + +#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \ + ((uint8_t*)ntheader + \ + offsetof( IMAGE_NT_HEADERS, OptionalHeader ) + \ + ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader \ + )) + + +/* Subsystem Values */ + +#define IMAGE_SUBSYSTEM_UNKNOWN 0 /* Unknown subsystem. */ +#define IMAGE_SUBSYSTEM_NATIVE 1 /* Image doesn't require a subsystem. */ +#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 /* Image runs in the Windows GUI subsystem. */ +#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 /* Image runs in the Windows character subsystem. */ +#define IMAGE_SUBSYSTEM_OS2_CUI 5 /* image runs in the OS/2 character subsystem. */ +#define IMAGE_SUBSYSTEM_POSIX_CUI 7 /* image run in the Posix character subsystem. */ +#define IMAGE_SUBSYSTEM_XBOX 14 + +/* Dll Characteristics */ + +#define IMAGE_LIBRARY_PROCESS_INIT 1 /* Dll has a process initialization routine. */ +#define IMAGE_LIBRARY_PROCESS_TERM 2 /* Dll has a thread termination routine. */ +#define IMAGE_LIBRARY_THREAD_INIT 4 /* Dll has a thread initialization routine. */ +#define IMAGE_LIBRARY_THREAD_TERM 8 /* Dll has a thread termination routine. */ + +/* + * Loader Flags + */ + +#define IMAGE_LOADER_FLAGS_BREAK_ON_LOAD 0x00000001 +#define IMAGE_LOADER_FLAGS_DEBUG_ON_LOAD 0x00000002 + + +/* Directory Entries */ + +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 /* Export Directory */ +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 /* Import Directory */ +#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 /* Resource Directory */ +#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 /* Exception Directory */ +#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 /* Security Directory */ +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 /* Base Relocation Table */ +#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 /* Debug Directory */ +#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 /* Description String */ +#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 /* Machine Value (MIPS GP) */ +#define IMAGE_DIRECTORY_ENTRY_TLS 9 /* TLS Directory */ +#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 /* Load Configuration Directory */ + +#ifdef USES_COMPLUS20 +#define IMAGE_DIRECTORY_ENTRY_COMHEADER 14 /* COM+ data */ +#endif + + +/* + * Section header format. + */ + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +typedef struct _IMAGE_SECTION_HEADER { + uint8_t Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + uint32_t PhysicalAddress; + uint32_t VirtualSize; + } Misc; + uint32_t VirtualAddress; + uint32_t SizeOfRawData; + uint32_t PointerToRawData; + uint32_t PointerToRelocations; + uint32_t PointerToLinenumbers; + uint16_t NumberOfRelocations; + uint16_t NumberOfLinenumbers; + uint32_t Characteristics; +} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; + +#define IMAGE_SIZEOF_SECTION_HEADER 40 + +#define IMAGE_SCN_TYPE_REGULAR 0x00000000 /* +#define IMAGE_SCN_TYPE_DUMMY 0x00000001 // Reserved. */ +#define IMAGE_SCN_TYPE_NO_LOAD 0x00000002 /* Reserved. */ +#define IMAGE_SCN_TYPE_GROUPED 0x00000004 /* Used for 16-bit offset code. */ +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* Reserved. */ +#define IMAGE_SCN_TYPE_COPY 0x00000010 /* Reserved. */ + +#define IMAGE_SCN_CNT_CODE 0x00000020 /* Section contains code. */ +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* Section contains initialized data. */ +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* Section contains uninitialized data. */ + +#define IMAGE_SCN_LNK_OTHER 0x00000100 /* Reserved. */ +#define IMAGE_SCN_LNK_INFO 0x00000200 /* Section contains comments or some other type of information. */ +#define IMAGE_SCN_LNK_OVERLAY 0x00000400 /* Section contains an overlay. */ +#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* Section contents will not become part of image. */ +#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* Section contents comdat. */ + +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default alignment if no others are specified. */ +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 + +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 /* Section can be discarded. */ +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* Section is not cachable. */ +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* Section is not pageable. */ +#define IMAGE_SCN_MEM_SHARED 0x10000000 /* Section is shareable. */ +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 /* Section is executable. */ +#define IMAGE_SCN_MEM_READ 0x40000000 /* Section is readable. */ +#define IMAGE_SCN_MEM_WRITE 0x80000000 /* Section is writeable. */ + +/* + * Symbol format. + */ + +typedef struct _IMAGE_SYMBOL { + union { + uint8_t ShortName[8]; + struct { + uint32_t Short; /* if 0, use LongName */ + uint32_t Long; /* offset into string table */ + } Name; + uint8_t* LongName[2]; + } N; + uint32_t Value; + int16_t SectionNumber; + uint16_t Type; + uint8_t StorageClass; + uint8_t NumberOfAuxSymbols; +} IMAGE_SYMBOL; +typedef IMAGE_SYMBOL UNALIGNED *PIMAGE_SYMBOL; + +#define IMAGE_SIZEOF_SYMBOL 18 + +/* + * Section values. + * + * Symbols have a section number of the section in which they are + * defined. Otherwise, section numbers have the following meanings: + */ + +#define IMAGE_SYM_UNDEFINED (int16 )0 /* Symbol is undefined or is common. */ +#define IMAGE_SYM_ABSOLUTE (int16 )-1 /* Symbol is an absolute value. */ +#define IMAGE_SYM_DEBUG (int16 )-2 /* Symbol is a special debug item. */ + +/* + * Type (fundamental) values. + */ + +#define IMAGE_SYM_TYPE_NULL 0 /* no type. */ +#define IMAGE_SYM_TYPE_VOID 1 +#define IMAGE_SYM_TYPE_CHAR 2 /* type character. */ +#define IMAGE_SYM_TYPE_SHORT 3 /* type short integer. */ +#define IMAGE_SYM_TYPE_INT 4 +#define IMAGE_SYM_TYPE_LONG 5 +#define IMAGE_SYM_TYPE_FLOAT 6 +#define IMAGE_SYM_TYPE_DOUBLE 7 +#define IMAGE_SYM_TYPE_STRUCT 8 +#define IMAGE_SYM_TYPE_UNION 9 +#define IMAGE_SYM_TYPE_ENUM 10 /* enumeration. */ +#define IMAGE_SYM_TYPE_MOE 11 /* member of enumeration. */ +#define IMAGE_SYM_TYPE_UCHAR 12 +#define IMAGE_SYM_TYPE_USHORT 13 +#define IMAGE_SYM_TYPE_UINT 14 +#define IMAGE_SYM_TYPE_ULONG 15 + +/* + * Type (derived) values. + */ + +#define IMAGE_SYM_DTYPE_NULL 0 /* no derived type. */ +#define IMAGE_SYM_DTYPE_POINTER 1 /* pointer. */ +#define IMAGE_SYM_DTYPE_FUNCTION 2 /* function. */ +#define IMAGE_SYM_DTYPE_ARRAY 3 /* array. */ + +/* + * Storage classes. + */ + +#define IMAGE_SYM_CLASS_END_OF_FUNCTION (uint8_t )-1 +#define IMAGE_SYM_CLASS_NULL 0 +#define IMAGE_SYM_CLASS_AUTOMATIC 1 +#define IMAGE_SYM_CLASS_EXTERNAL 2 +#define IMAGE_SYM_CLASS_STATIC 3 +#define IMAGE_SYM_CLASS_REGISTER 4 +#define IMAGE_SYM_CLASS_EXTERNAL_DEF 5 +#define IMAGE_SYM_CLASS_LABEL 6 +#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7 +#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8 +#define IMAGE_SYM_CLASS_ARGUMENT 9 +#define IMAGE_SYM_CLASS_STRUCT_TAG 10 +#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 11 +#define IMAGE_SYM_CLASS_UNION_TAG 12 +#define IMAGE_SYM_CLASS_TYPE_DEFINITION 13 +#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 14 +#define IMAGE_SYM_CLASS_ENUM_TAG 15 +#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16 +#define IMAGE_SYM_CLASS_REGISTER_PARAM 17 +#define IMAGE_SYM_CLASS_BIT_FIELD 18 +#define IMAGE_SYM_CLASS_BLOCK 100 +#define IMAGE_SYM_CLASS_FUNCTION 101 +#define IMAGE_SYM_CLASS_END_OF_STRUCT 102 +#define IMAGE_SYM_CLASS_FILE 103 +#define IMAGE_SYM_CLASS_SECTION 104 +#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105 + +/* type packing constants */ + +#define N_BTMASK 017 +#define N_TMASK 060 +#define N_TMASK1 0300 +#define N_TMASK2 0360 +#define N_BTSHFT 4 +#define N_TSHIFT 2 + +/* MACROS */ + +/* Basic Type of x */ +#define BTYPE(x) ((x) & N_BTMASK) + +/* Is x a pointer? */ +#ifndef ISPTR +#define ISPTR(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_POINTER << N_BTSHFT)) +#endif + +/* Is x a function? */ +#ifndef ISFCN +#define ISFCN(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_FUNCTION << N_BTSHFT)) +#endif + +/* Is x an array? */ + +#ifndef ISARY +#define ISARY(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_ARRAY << N_BTSHFT)) +#endif + +/* Is x a structure, union, or enumeration TAG? */ +#ifndef ISTAG +#define ISTAG(x) ((x)==IMAGE_SYM_CLASS_STRUCT_TAG || (x)==IMAGE_SYM_CLASS_UNION_TAG || (x)==IMAGE_SYM_CLASS_ENUM_TAG) +#endif + +#ifndef INCREF +#define INCREF(x) ((((x)&~N_BTMASK)<>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK)) +#endif + +/* + * Auxiliary entry format. + */ + +typedef union _IMAGE_AUX_SYMBOL { + struct { + uint32_t TagIndex; /* struct, union, or enum tag index */ + union { + struct { + uint16_t Linenumber; /* declaration line number */ + uint16_t Size; /* size of struct, union, or enum */ + } LnSz; + uint32_t TotalSize; + } Misc; + union { + struct { /* if ISFCN, tag, or .bb */ + uint32_t PointerToLinenumber; + uint32_t PointerToNextFunction; + } Function; + struct { /* if ISARY, up to 4 dimen. */ + uint16_t Dimension[4]; + } Array; + } FcnAry; + uint16_t TvIndex; /* tv index */ + } Sym; + struct { + uint8_t Name[IMAGE_SIZEOF_SYMBOL]; + } File; + struct { + uint32_t Length; /* section length */ + uint16_t NumberOfRelocations; /* number of relocation entries */ + uint16_t NumberOfLinenumbers; /* number of line numbers */ + uint32_t CheckSum; /* checksum for communal */ + int16_t Number; /* section number to associate with */ + uint8_t Selection; /* communal selection type */ + } Section; +} IMAGE_AUX_SYMBOL; +typedef IMAGE_AUX_SYMBOL UNALIGNED *PIMAGE_AUX_SYMBOL; + +#define IMAGE_SIZEOF_AUX_SYMBOL 18 + +/* + * Communal selection types. + */ + +#define IMAGE_COMDAT_SELECT_UNKNOWN 0 +#define IMAGE_COMDAT_SELECT_NODUPLICATES 1 +#define IMAGE_COMDAT_SELECT_ANY 2 +#define IMAGE_COMDAT_SELECT_SAME_SIZE 3 +#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4 +#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 + +#define IMAGE_WEAK_EXTERN_SEARCH_UNKNOWN 0 +#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 +#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 + + +/* + * Relocation format. + */ + +typedef struct _IMAGE_RELOCATION { + uint32_t VirtualAddress; + uint32_t SymbolTableIndex; + uint16_t Type; +} IMAGE_RELOCATION; +typedef IMAGE_RELOCATION UNALIGNED *PIMAGE_RELOCATION; + +#define IMAGE_SIZEOF_RELOCATION 10 + +/* + * I860 relocation types. + */ + +#define IMAGE_REL_I860_ABSOLUTE 0 /* Reference is absolute, no relocation is necessary */ +#define IMAGE_REL_I860_DIR32 06 /* Direct 32-bit reference to the symbols virtual address */ +#define IMAGE_REL_I860_DIR32NB 07 +#define IMAGE_REL_I860_SECTION 012 +#define IMAGE_REL_I860_SECREL 013 +#define IMAGE_REL_I860_PAIR 034 +#define IMAGE_REL_I860_HIGH 036 +#define IMAGE_REL_I860_LOW0 037 +#define IMAGE_REL_I860_LOW1 040 +#define IMAGE_REL_I860_LOW2 041 +#define IMAGE_REL_I860_LOW3 042 +#define IMAGE_REL_I860_LOW4 043 +#define IMAGE_REL_I860_SPLIT0 044 +#define IMAGE_REL_I860_SPLIT1 045 +#define IMAGE_REL_I860_SPLIT2 046 +#define IMAGE_REL_I860_HIGHADJ 047 +#define IMAGE_REL_I860_BRADDR 050 + +/* + * I386 relocation types. + */ + +#define IMAGE_REL_I386_ABSOLUTE 0 /* Reference is absolute, no relocation is necessary */ +#define IMAGE_REL_I386_DIR16 01 /* Direct 16-bit reference to the symbols virtual address */ +#define IMAGE_REL_I386_REL16 02 /* PC-relative 16-bit reference to the symbols virtual address */ +#define IMAGE_REL_I386_DIR32 06 /* Direct 32-bit reference to the symbols virtual address */ +#define IMAGE_REL_I386_DIR32NB 07 /* Direct 32-bit reference to the symbols virtual address, base not included */ +#define IMAGE_REL_I386_SEG12 011 /* Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address */ +#define IMAGE_REL_I386_SECTION 012 +#define IMAGE_REL_I386_SECREL 013 +#define IMAGE_REL_I386_REL32 024 /* PC-relative 32-bit reference to the symbols virtual address */ + +/* + * MIPS relocation types. + */ + +#define IMAGE_REL_MIPS_ABSOLUTE 0 /* Reference is absolute, no relocation is necessary */ +#define IMAGE_REL_MIPS_REFHALF 01 +#define IMAGE_REL_MIPS_REFWORD 02 +#define IMAGE_REL_MIPS_JMPADDR 03 +#define IMAGE_REL_MIPS_REFHI 04 +#define IMAGE_REL_MIPS_REFLO 05 +#define IMAGE_REL_MIPS_GPREL 06 +#define IMAGE_REL_MIPS_LITERAL 07 +#define IMAGE_REL_MIPS_SECTION 012 +#define IMAGE_REL_MIPS_SECREL 013 +#define IMAGE_REL_MIPS_REFWORDNB 042 +#define IMAGE_REL_MIPS_PAIR 045 + +/* + * Alpha Relocation types. + */ + +#define IMAGE_REL_ALPHA_ABSOLUTE 0x0 +#define IMAGE_REL_ALPHA_REFLONG 0x1 +#define IMAGE_REL_ALPHA_REFQUAD 0x2 +#define IMAGE_REL_ALPHA_GPREL32 0x3 +#define IMAGE_REL_ALPHA_LITERAL 0x4 +#define IMAGE_REL_ALPHA_LITUSE 0x5 +#define IMAGE_REL_ALPHA_GPDISP 0x6 +#define IMAGE_REL_ALPHA_BRADDR 0x7 +#define IMAGE_REL_ALPHA_HINT 0x8 +#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x9 +#define IMAGE_REL_ALPHA_REFHI 0xA +#define IMAGE_REL_ALPHA_REFLO 0xB +#define IMAGE_REL_ALPHA_PAIR 0xC +#define IMAGE_REL_ALPHA_MATCH 0xD +#define IMAGE_REL_ALPHA_SECTION 0xE +#define IMAGE_REL_ALPHA_SECREL 0xF +#define IMAGE_REL_ALPHA_REFLONGNB 0x10 + +/* + * Based relocation format. + */ + +typedef struct _IMAGE_BASE_RELOCATION { + uint32_t VirtualAddress; + uint32_t SizeOfBlock; +/* uint16_t TypeOffset[1]; */ +} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION; + +#define IMAGE_SIZEOF_BASE_RELOCATION 8 + +/* + * Based relocation types. + */ + +#define IMAGE_REL_BASED_ABSOLUTE 0 +#define IMAGE_REL_BASED_HIGH 1 +#define IMAGE_REL_BASED_LOW 2 +#define IMAGE_REL_BASED_HIGHLOW 3 +#define IMAGE_REL_BASED_HIGHADJ 4 +#define IMAGE_REL_BASED_MIPS_JMPADDR 5 +#define IMAGE_REL_BASED_I860_BRADDR 6 +#define IMAGE_REL_BASED_I860_SPLIT 7 + +/* + * Line number format. + */ + +typedef struct _IMAGE_LINENUMBER { + union { + uint32_t SymbolTableIndex; /* Symbol table index of function name if Linenumber is 0. */ + uint32_t VirtualAddress; /* Virtual address of line number. */ + } Type; + uint16_t Linenumber; /* Line number. */ +} IMAGE_LINENUMBER; +typedef IMAGE_LINENUMBER UNALIGNED *PIMAGE_LINENUMBER; + +#define IMAGE_SIZEOF_LINENUMBER 6 + +/* + * Archive format. + */ + +#define IMAGE_ARCHIVE_START_SIZE 8 +#define IMAGE_ARCHIVE_START "!\n" +#define IMAGE_ARCHIVE_END "`\n" +#define IMAGE_ARCHIVE_PAD "\n" +#define IMAGE_ARCHIVE_LINKER_MEMBER "/ " +#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " + +typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER { + uint8_t Name[16]; /* File member name - `/' terminated. */ + uint8_t Date[12]; /* File member date - decimal. */ + uint8_t UserID[6]; /* File member user id - decimal. */ + uint8_t GroupID[6]; /* File member group id - decimal. */ + uint8_t Mode[8]; /* File member mode - octal. */ + uint8_t Size[10]; /* File member size - decimal. */ + uint8_t EndHeader[2]; /* String to end header. */ +} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER; + +#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 + +/* + * DLL support. + */ + +/* + * Export Format + */ + +typedef struct _IMAGE_EXPORT_DIRECTORY { + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t Name; + uint32_t Base; + uint32_t NumberOfFunctions; + uint32_t NumberOfNames; + uint32_t **AddressOfFunctions; + uint32_t **AddressOfNames; + uint16_t **AddressOfNameOrdinals; +} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; + +/* + * Import Format + */ + +typedef struct _IMAGE_IMPORT_BY_NAME { + uint16_t Hint; + uint8_t Name[1]; +} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; + +typedef struct _IMAGE_THUNK_DATA { + union { + uint32_t *Function; + uint32_t Ordinal; + PIMAGE_IMPORT_BY_NAME AddressOfData; + } u1; +} IMAGE_THUNK_DATA, *PIMAGE_THUNK_DATA; + +#define IMAGE_ORDINAL_FLAG 0x80000000 +#define IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG) != 0) +#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) + +typedef struct _IMAGE_IMPORT_DESCRIPTOR { + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint32_t ForwarderChain; + uint32_t Name; + PIMAGE_THUNK_DATA FirstThunk; +} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR; + +/* + * Thread Local Storage + */ + +typedef void (*PIMAGE_TLS_CALLBACK) ( + void* DllHandle, + uint32_t Reason, + void* Reserved + ); + +typedef struct _IMAGE_TLS_DIRECTORY { + uint32_t StartAddressOfRawData; + uint32_t EndAddressOfRawData; + uint32_t *AddressOfIndex; + PIMAGE_TLS_CALLBACK *AddressOfCallBacks; + uint32_t SizeOfZeroFill; + uint32_t Characteristics; +} IMAGE_TLS_DIRECTORY, *PIMAGE_TLS_DIRECTORY; + + +/* + * Resource Format. + */ + +/* + * Resource directory consists of two counts, following by a variable length + * array of directory entries. The first count is the number of entries at + * beginning of the array that have actual names associated with each entry. + * The entries are in ascending order, case insensitive strings. The second + * count is the number of entries that immediately follow the named entries. + * This second count identifies the number of entries that have 31-bit integer + * Ids as their name. These entries are also sorted in ascending order. + * + * This structure allows fast lookup by either name or number, but for any + * given resource entry only one form of lookup is supported, not both. + * This is consistant with the syntax of the .RC file and the .RES file. + */ + +typedef struct _IMAGE_RESOURCE_DIRECTORY { + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint16_t NumberOfNamedEntries; + uint16_t NumberOfIdEntries; +/* IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[]; */ +} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY; + +#define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000 +#define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000 + +/* + * Each directory contains the 32-bit Name of the entry and an offset, + * relative to the beginning of the resource directory of the data associated + * with this directory entry. If the name of the entry is an actual text + * string instead of an integer Id, then the high order bit of the name field + * is set to one and the low order 31-bits are an offset, relative to the + * beginning of the resource directory of the string, which is of type + * IMAGE_RESOURCE_DIRECTORY_STRING. Otherwise the high bit is clear and the + * low-order 31-bits are the integer Id that identify this resource directory + * entry. If the directory entry is yet another resource directory (i.e. a + * subdirectory), then the high order bit of the offset field will be + * set to indicate this. Otherwise the high bit is clear and the offset + * field points to a resource data entry. + */ + +typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY { + uint32_t Name; + uint32_t OffsetToData; +} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY; + +/* + * For resource directory entries that have actual string names, the Name + * field of the directory entry points to an object of the following type. + * All of these string objects are stored together after the last resource + * directory entry and before the first resource data object. This minimizes + * the impact of these variable length objects on the alignment of the fixed + * size directory entry objects. + */ + +typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING { + uint16_t Length; + char NameString[ 1 ]; +} IMAGE_RESOURCE_DIRECTORY_STRING, *PIMAGE_RESOURCE_DIRECTORY_STRING; + + +typedef struct _IMAGE_RESOURCE_DIR_STRING_U { + uint16_t Length; + wchar_t NameString[ 1 ]; +} IMAGE_RESOURCE_DIR_STRING_U, *PIMAGE_RESOURCE_DIR_STRING_U; + +/* + * Each resource data entry describes a leaf node in the resource directory + * tree. It contains an offset, relative to the beginning of the resource + * directory of the data for the resource, a size field that gives the number + * of bytes of data at that offset, a CodePage that should be used when + * decoding code point values within the resource data. Typically for new + * applications the code page would be the unicode code page. + */ + +typedef struct _IMAGE_RESOURCE_DATA_ENTRY { + uint32_t OffsetToData; + uint32_t Size; + uint32_t CodePage; + uint32_t Reserved; +} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY; + +/* + * Load Configuration Directory Entry + */ + +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY { + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t GlobalFlagsClear; + uint32_t GlobalFlagsSet; + uint32_t CriticalSectionDefaultTimeout; + uint32_t DeCommitFreeBlockThreshold; + uint32_t DeCommitTotalFreeThreshold; + uint32_t Reserved[ 8 ]; +} IMAGE_LOAD_CONFIG_DIRECTORY, *PIMAGE_LOAD_CONFIG_DIRECTORY; + + +/* + * Function table entry format for MIPS/ALPHA images. Function table is + * pointed to by the IMAGE_DIRECTORY_ENTRY_EXCEPTION directory entry. + * This definition duplicates ones in ntmips.h and ntalpha.h for use + * by portable image file mungers. + */ + +typedef struct _IMAGE_RUNTIME_FUNCTION_ENTRY { + uint32_t BeginAddress; + uint32_t EndAddress; + void* ExceptionHandler; + void* HandlerData; + uint32_t PrologEndAddress; +} IMAGE_RUNTIME_FUNCTION_ENTRY, *PIMAGE_RUNTIME_FUNCTION_ENTRY; + +/* + * Debug Format + */ + +typedef struct _IMAGE_DEBUG_DIRECTORY { + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t Type; + uint32_t SizeOfData; + uint32_t AddressOfRawData; + uint32_t PointerToRawData; +} IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY; + +#define IMAGE_DEBUG_TYPE_UNKNOWN 0 +#define IMAGE_DEBUG_TYPE_COFF 1 +#define IMAGE_DEBUG_TYPE_CODEVIEW 2 +#define IMAGE_DEBUG_TYPE_FPO 3 +#define IMAGE_DEBUG_TYPE_MISC 4 +#define IMAGE_DEBUG_TYPE_EXCEPTION 5 +#define IMAGE_DEBUG_TYPE_FIXUP 6 +#define IMAGE_DEBUG_TYPE_RESERVED6 7 +#define IMAGE_DEBUG_TYPE_RESERVED7 8 + +typedef struct _IMAGE_COFF_SYMBOLS_HEADER { + uint32_t NumberOfSymbols; + uint32_t LvaToFirstSymbol; + uint32_t NumberOfLinenumbers; + uint32_t LvaToFirstLinenumber; + uint32_t RvaToFirstByteOfCode; + uint32_t RvaToLastByteOfCode; + uint32_t RvaToFirstByteOfData; + uint32_t RvaToLastByteOfData; +} IMAGE_COFF_SYMBOLS_HEADER, *PIMAGE_COFF_SYMBOLS_HEADER; + +#define FRAME_FPO 0 +#define FRAME_TRAP 1 +#define FRAME_TSS 2 + +#ifdef _MSC_VER +#pragma warning(disable:4214) +#endif +typedef struct _FPO_DATA { + uint32_t ulOffStart; /* offset 1st byte of function code */ + uint32_t cbProcSize; /* # bytes in function */ + uint32_t cdwLocals; /* # bytes in locals/4 */ + uint16_t cdwParams; /* # bytes in params/4 */ + uint16_t cbProlog : 8; /* # bytes in prolog */ + uint16_t cbRegs : 3; /* # regs saved */ + uint16_t fHasSEH : 1; /* TRUE if SEH in func */ + uint16_t fUseBP : 1; /* TRUE if EBP has been allocated */ + uint16_t reserved : 1; /* reserved for future use */ + uint16_t cbFrame : 2; /* frame type */ +} FPO_DATA, *PFPO_DATA; +#define SIZEOF_RFPO_DATA 16 +#ifdef _MSC_VER +#pragma warning(default:4214) +#endif + +#define IMAGE_DEBUG_MISC_EXENAME 1 + +typedef struct _IMAGE_DEBUG_MISC { + uint32_t DataType; /* type of misc data, see defines */ + uint32_t Length; /* total length of record, rounded to four */ + /* byte multiple. */ + uint8_t Unicode; /* TRUE if data is unicode string */ + uint8_t Reserved[ 3 ]; + uint8_t Data[ 1 ]; /* Actual data */ +} IMAGE_DEBUG_MISC, *PIMAGE_DEBUG_MISC; + + +/* + * Debugging information can be stripped from an image file and placed + * in a separate .DBG file, whose file name part is the same as the + * image file name part (e.g. symbols for CMD.EXE could be stripped + * and placed in CMD.DBG). This is indicated by the IMAGE_FILE_DEBUG_STRIPPED + * flag in the Characteristics field of the file header. The beginning of + * the .DBG file contains the following structure which captures certain + * information from the image file. This allows a debug to proceed even if + * the original image file is not accessable. This header is followed by + * zero of more IMAGE_SECTION_HEADER structures, followed by zero or more + * IMAGE_DEBUG_DIRECTORY structures. The latter structures and those in + * the image file contain file offsets relative to the beginning of the + * .DBG file. + * + * If symbols have been stripped from an image, the IMAGE_DEBUG_MISC structure + * is left in the image file, but not mapped. This allows a debugger to + * compute the name of the .DBG file, from the name of the image in the + * IMAGE_DEBUG_MISC structure. + */ + +typedef struct _IMAGE_SEPARATE_DEBUG_HEADER { + uint16_t Signature; + uint16_t Flags; + uint16_t Machine; + uint16_t Characteristics; + uint32_t TimeDateStamp; + uint32_t CheckSum; + uint32_t ImageBase; + uint32_t SizeOfImage; + uint32_t NumberOfSections; + uint32_t ExportedNamesSize; + uint32_t DebugDirectorySize; + uint32_t Reserved[ 3 ]; +} IMAGE_SEPARATE_DEBUG_HEADER, *PIMAGE_SEPARATE_DEBUG_HEADER; + +#define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944 + +#endif /* IMAGE_NT_SIGNATURE */ + + +#ifdef USES_COMPLUS20 +/* + * COM+ 2.0 header structure. + */ +typedef struct IMAGE_COR20_HEADER +{ + /* Header versioning */ + uint32_t cb; + uint16_t MajorRuntimeVersion; + uint16_t MinorRuntimeVersion; + + /* Symbol table and startup information */ + IMAGE_DATA_DIRECTORY MetaData; + uint32_t Flags; + uint32_t EntryPointToken; + + /* Binding information */ + IMAGE_DATA_DIRECTORY Resources; + IMAGE_DATA_DIRECTORY StrongNameSignature; + + /* Regular fixup and binding information */ + IMAGE_DATA_DIRECTORY CodeManagerTable; + IMAGE_DATA_DIRECTORY VTableFixups; + IMAGE_DATA_DIRECTORY ExportAddressTableJumps; + + /* Managed Native Code */ + IMAGE_DATA_DIRECTORY EEInfoTable; + IMAGE_DATA_DIRECTORY HelperTable; + IMAGE_DATA_DIRECTORY DynamicInfo; + IMAGE_DATA_DIRECTORY DelayLoadInfo; + IMAGE_DATA_DIRECTORY ModuleImage; + IMAGE_DATA_DIRECTORY ExternalFixups; + IMAGE_DATA_DIRECTORY RidMap; + IMAGE_DATA_DIRECTORY DebugMap; + + /*@Todo: this is obsolete, being replaced by pdata in the PE header.*/ + IMAGE_DATA_DIRECTORY IPMap; + +} IMAGE_COR20_HEADER; + +#endif /* USES_COMPLUS20 */ + +#ifdef _MSC_VER +#pragma pack () +#endif + +/* + * End Image Format + */ diff --git a/thirdparty/picosha2/picosha2.h b/thirdparty/picosha2/picosha2.h new file mode 100644 index 0000000..ef965e6 --- /dev/null +++ b/thirdparty/picosha2/picosha2.h @@ -0,0 +1,388 @@ +/* +The MIT License (MIT) + +Copyright (C) 2017 okdshin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +#ifndef PICOSHA2_H +#define PICOSHA2_H +// picosha2:20140213 + +#ifndef PICOSHA2_BUFFER_SIZE_FOR_INPUT_ITERATOR +#define PICOSHA2_BUFFER_SIZE_FOR_INPUT_ITERATOR \ + 1048576 //=1024*1024: default is 1MB memory +#endif + +#include +#include +#include +#include +#include +#include +namespace picosha2 { +typedef unsigned long word_t; +typedef unsigned char byte_t; + +static const size_t k_digest_size = 32; + +namespace detail { +inline byte_t mask_8bit(byte_t x) { return x & 0xff; } + +inline word_t mask_32bit(word_t x) { return x & 0xffffffff; } + +const word_t add_constant[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, + 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, + 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, + 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, + 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, + 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2}; + +const word_t initial_message_digest[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, + 0xa54ff53a, 0x510e527f, 0x9b05688c, + 0x1f83d9ab, 0x5be0cd19}; + +inline word_t ch(word_t x, word_t y, word_t z) { return (x & y) ^ ((~x) & z); } + +inline word_t maj(word_t x, word_t y, word_t z) { + return (x & y) ^ (x & z) ^ (y & z); +} + +inline word_t rotr(word_t x, std::size_t n) { + assert(n < 32); + return mask_32bit((x >> n) | (x << (32 - n))); +} + +inline word_t bsig0(word_t x) { return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22); } + +inline word_t bsig1(word_t x) { return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25); } + +inline word_t shr(word_t x, std::size_t n) { + assert(n < 32); + return x >> n; +} + +inline word_t ssig0(word_t x) { return rotr(x, 7) ^ rotr(x, 18) ^ shr(x, 3); } + +inline word_t ssig1(word_t x) { return rotr(x, 17) ^ rotr(x, 19) ^ shr(x, 10); } + +template +void hash256_block(RaIter1 message_digest, RaIter2 first, RaIter2 last) { + assert(first + 64 == last); + static_cast(last); // for avoiding unused-variable warning + word_t w[64]; + std::fill(w, w + 64, word_t(0)); + for (std::size_t i = 0; i < 16; ++i) { + w[i] = (static_cast(mask_8bit(*(first + i * 4))) << 24) | + (static_cast(mask_8bit(*(first + i * 4 + 1))) << 16) | + (static_cast(mask_8bit(*(first + i * 4 + 2))) << 8) | + (static_cast(mask_8bit(*(first + i * 4 + 3)))); + } + for (std::size_t i = 16; i < 64; ++i) { + w[i] = mask_32bit(ssig1(w[i - 2]) + w[i - 7] + ssig0(w[i - 15]) + + w[i - 16]); + } + + word_t a = *message_digest; + word_t b = *(message_digest + 1); + word_t c = *(message_digest + 2); + word_t d = *(message_digest + 3); + word_t e = *(message_digest + 4); + word_t f = *(message_digest + 5); + word_t g = *(message_digest + 6); + word_t h = *(message_digest + 7); + + for (std::size_t i = 0; i < 64; ++i) { + word_t temp1 = h + bsig1(e) + ch(e, f, g) + add_constant[i] + w[i]; + word_t temp2 = bsig0(a) + maj(a, b, c); + h = g; + g = f; + f = e; + e = mask_32bit(d + temp1); + d = c; + c = b; + b = a; + a = mask_32bit(temp1 + temp2); + } + *message_digest += a; + *(message_digest + 1) += b; + *(message_digest + 2) += c; + *(message_digest + 3) += d; + *(message_digest + 4) += e; + *(message_digest + 5) += f; + *(message_digest + 6) += g; + *(message_digest + 7) += h; + for (std::size_t i = 0; i < 8; ++i) { + *(message_digest + i) = mask_32bit(*(message_digest + i)); + } +} + +} // namespace detail + +template +void output_hex(InIter first, InIter last, std::ostream& os) { + os.setf(std::ios::hex, std::ios::basefield); + while (first != last) { + os.width(2); + os.fill('0'); + os << static_cast(*first); + ++first; + } + os.setf(std::ios::dec, std::ios::basefield); +} + +template +void bytes_to_hex_string(InIter first, InIter last, std::string& hex_str) { + std::ostringstream oss; + output_hex(first, last, oss); + hex_str.assign(oss.str()); +} + +template +void bytes_to_hex_string(const InContainer& bytes, std::string& hex_str) { + bytes_to_hex_string(bytes.begin(), bytes.end(), hex_str); +} + +template +std::string bytes_to_hex_string(InIter first, InIter last) { + std::string hex_str; + bytes_to_hex_string(first, last, hex_str); + return hex_str; +} + +template +std::string bytes_to_hex_string(const InContainer& bytes) { + std::string hex_str; + bytes_to_hex_string(bytes, hex_str); + return hex_str; +} + +class hash256_one_by_one { + public: + hash256_one_by_one() { init(); } + + void init() { + buffer_.clear(); + std::fill(data_length_digits_, data_length_digits_ + 4, word_t(0)); + std::copy(detail::initial_message_digest, + detail::initial_message_digest + 8, h_); + } + + template + void process(RaIter first, RaIter last) { + add_to_data_length(static_cast(std::distance(first, last))); + std::copy(first, last, std::back_inserter(buffer_)); + std::size_t i = 0; + for (; i + 64 <= buffer_.size(); i += 64) { + detail::hash256_block(h_, buffer_.begin() + i, + buffer_.begin() + i + 64); + } + buffer_.erase(buffer_.begin(), buffer_.begin() + i); + } + + void finish() { + byte_t temp[64]; + std::fill(temp, temp + 64, byte_t(0)); + std::size_t remains = buffer_.size(); + std::copy(buffer_.begin(), buffer_.end(), temp); + assert(remains < 64); + + // This branch is not executed actually (`remains` is always lower than 64), + // but needed to avoid g++ false-positive warning. + // See https://github.com/okdshin/PicoSHA2/issues/25 + // vvvvvvvvvvvvvvvv + if(remains >= 64) { + remains = 63; + } + // ^^^^^^^^^^^^^^^^ + + temp[remains] = 0x80; + + if (remains > 55) { + std::fill(temp + remains + 1, temp + 64, byte_t(0)); + detail::hash256_block(h_, temp, temp + 64); + std::fill(temp, temp + 64 - 4, byte_t(0)); + } else { + std::fill(temp + remains + 1, temp + 64 - 4, byte_t(0)); + } + + write_data_bit_length(&(temp[56])); + detail::hash256_block(h_, temp, temp + 64); + } + + template + void get_hash_bytes(OutIter first, OutIter last) const { + for (const word_t* iter = h_; iter != h_ + 8; ++iter) { + for (std::size_t i = 0; i < 4 && first != last; ++i) { + *(first++) = detail::mask_8bit( + static_cast((*iter >> (24 - 8 * i)))); + } + } + } + + private: + void add_to_data_length(word_t n) { + word_t carry = 0; + data_length_digits_[0] += n; + for (std::size_t i = 0; i < 4; ++i) { + data_length_digits_[i] += carry; + if (data_length_digits_[i] >= 65536u) { + carry = data_length_digits_[i] >> 16; + data_length_digits_[i] &= 65535u; + } else { + break; + } + } + } + void write_data_bit_length(byte_t* begin) { + word_t data_bit_length_digits[4]; + std::copy(data_length_digits_, data_length_digits_ + 4, + data_bit_length_digits); + + // convert byte length to bit length (multiply 8 or shift 3 times left) + word_t carry = 0; + for (std::size_t i = 0; i < 4; ++i) { + word_t before_val = data_bit_length_digits[i]; + data_bit_length_digits[i] <<= 3; + data_bit_length_digits[i] |= carry; + data_bit_length_digits[i] &= 65535u; + carry = (before_val >> (16 - 3)) & 65535u; + } + + // write data_bit_length + for (int i = 3; i >= 0; --i) { + (*begin++) = static_cast(data_bit_length_digits[i] >> 8); + (*begin++) = static_cast(data_bit_length_digits[i]); + } + } + std::vector buffer_; + word_t data_length_digits_[4]; // as 64bit integer (16bit x 4 integer) + word_t h_[8]; +}; + +inline void get_hash_hex_string(const hash256_one_by_one& hasher, + std::string& hex_str) { + byte_t hash[k_digest_size]; + hasher.get_hash_bytes(hash, hash + k_digest_size); + return bytes_to_hex_string(hash, hash + k_digest_size, hex_str); +} + +inline std::string get_hash_hex_string(const hash256_one_by_one& hasher) { + std::string hex_str; + get_hash_hex_string(hasher, hex_str); + return hex_str; +} + +namespace impl { +template +void hash256_impl(RaIter first, RaIter last, OutIter first2, OutIter last2, int, + std::random_access_iterator_tag) { + hash256_one_by_one hasher; + // hasher.init(); + hasher.process(first, last); + hasher.finish(); + hasher.get_hash_bytes(first2, last2); +} + +template +void hash256_impl(InputIter first, InputIter last, OutIter first2, + OutIter last2, int buffer_size, std::input_iterator_tag) { + std::vector buffer(buffer_size); + hash256_one_by_one hasher; + // hasher.init(); + while (first != last) { + int size = buffer_size; + for (int i = 0; i != buffer_size; ++i, ++first) { + if (first == last) { + size = i; + break; + } + buffer[i] = *first; + } + hasher.process(buffer.begin(), buffer.begin() + size); + } + hasher.finish(); + hasher.get_hash_bytes(first2, last2); +} +} + +template +void hash256(InIter first, InIter last, OutIter first2, OutIter last2, + int buffer_size = PICOSHA2_BUFFER_SIZE_FOR_INPUT_ITERATOR) { + picosha2::impl::hash256_impl( + first, last, first2, last2, buffer_size, + typename std::iterator_traits::iterator_category()); +} + +template +void hash256(InIter first, InIter last, OutContainer& dst) { + hash256(first, last, dst.begin(), dst.end()); +} + +template +void hash256(const InContainer& src, OutIter first, OutIter last) { + hash256(src.begin(), src.end(), first, last); +} + +template +void hash256(const InContainer& src, OutContainer& dst) { + hash256(src.begin(), src.end(), dst.begin(), dst.end()); +} + +template +void hash256_hex_string(InIter first, InIter last, std::string& hex_str) { + byte_t hashed[k_digest_size]; + hash256(first, last, hashed, hashed + k_digest_size); + std::ostringstream oss; + output_hex(hashed, hashed + k_digest_size, oss); + hex_str.assign(oss.str()); +} + +template +std::string hash256_hex_string(InIter first, InIter last) { + std::string hex_str; + hash256_hex_string(first, last, hex_str); + return hex_str; +} + +inline void hash256_hex_string(const std::string& src, std::string& hex_str) { + hash256_hex_string(src.begin(), src.end(), hex_str); +} + +template +void hash256_hex_string(const InContainer& src, std::string& hex_str) { + hash256_hex_string(src.begin(), src.end(), hex_str); +} + +template +std::string hash256_hex_string(const InContainer& src) { + return hash256_hex_string(src.begin(), src.end()); +} +templatevoid hash256(std::ifstream& f, OutIter first, OutIter last){ + hash256(std::istreambuf_iterator(f), std::istreambuf_iterator(), first,last); + +} +}// namespace picosha2 +#endif // PICOSHA2_H diff --git a/thirdparty/renderdoc/renderdoc_app.h b/thirdparty/renderdoc/renderdoc_app.h new file mode 100644 index 0000000..da323e9 --- /dev/null +++ b/thirdparty/renderdoc/renderdoc_app.h @@ -0,0 +1,524 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2015-2016 Baldur Karlsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#pragma once + +#if !defined(RENDERDOC_NO_STDINT) +#include +#endif + +#if defined(WIN32) || defined(_WIN32) + #define RENDERDOC_CC __cdecl +#elif defined(__linux__) + #define RENDERDOC_CC +#else + #error "Unknown platform" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +////////////////////////////////////////////////////////////////////////////////////////////////// +// RenderDoc capture options +// + +typedef enum +{ + // Allow the application to enable vsync + // + // Default - enabled + // + // 1 - The application can enable or disable vsync at will + // 0 - vsync is force disabled + eRENDERDOC_Option_AllowVSync = 0, + + // Allow the application to enable fullscreen + // + // Default - enabled + // + // 1 - The application can enable or disable fullscreen at will + // 0 - fullscreen is force disabled + eRENDERDOC_Option_AllowFullscreen = 1, + + // Record API debugging events and messages + // + // Default - disabled + // + // 1 - Enable built-in API debugging features and records the results into + // the capture logfile, which is matched up with events on replay + // 0 - no API debugging is forcibly enabled + eRENDERDOC_Option_DebugDeviceMode = 2, + + // Capture CPU callstacks for API events + // + // Default - disabled + // + // 1 - Enables capturing of callstacks + // 0 - no callstacks are captured + eRENDERDOC_Option_CaptureCallstacks = 3, + + // When capturing CPU callstacks, only capture them from drawcalls. + // This option does nothing without the above option being enabled + // + // Default - disabled + // + // 1 - Only captures callstacks for drawcall type API events. + // Ignored if CaptureCallstacks is disabled + // 0 - Callstacks, if enabled, are captured for every event. + eRENDERDOC_Option_CaptureCallstacksOnlyDraws = 4, + + // Specify a delay in seconds to wait for a debugger to attach, after + // creating or injecting into a process, before continuing to allow it to run. + // + // 0 indicates no delay, and the process will run immediately after injection + // + // Default - 0 seconds + // + eRENDERDOC_Option_DelayForDebugger = 5, + + // Verify any writes to mapped buffers, by checking the memory after the + // bounds of the returned pointer to detect any modification. + // + // Default - disabled + // + // 1 - Verify any writes to mapped buffers + // 0 - No verification is performed, and overwriting bounds may cause + // crashes or corruption in RenderDoc + eRENDERDOC_Option_VerifyMapWrites = 6, + + // Hooks any system API calls that create child processes, and injects + // RenderDoc into them recursively with the same options. + // + // Default - disabled + // + // 1 - Hooks into spawned child processes + // 0 - Child processes are not hooked by RenderDoc + eRENDERDOC_Option_HookIntoChildren = 7, + + // By default RenderDoc only includes resources in the final logfile necessary + // for that frame, this allows you to override that behaviour. + // + // Default - disabled + // + // 1 - all live resources at the time of capture are included in the log + // and available for inspection + // 0 - only the resources referenced by the captured frame are included + eRENDERDOC_Option_RefAllResources = 8, + + // By default RenderDoc skips saving initial states for resources where the + // previous contents don't appear to be used, assuming that writes before + // reads indicate previous contents aren't used. + // + // Default - disabled + // + // 1 - initial contents at the start of each captured frame are saved, even if + // they are later overwritten or cleared before being used. + // 0 - unless a read is detected, initial contents will not be saved and will + // appear as black or empty data. + eRENDERDOC_Option_SaveAllInitials = 9, + + // In APIs that allow for the recording of command lists to be replayed later, + // RenderDoc may choose to not capture command lists before a frame capture is + // triggered, to reduce overheads. This means any command lists recorded once + // and replayed many times will not be available and may cause a failure to + // capture. + // + // Note this is only true for APIs where multithreading is difficult or + // discouraged. Newer APIs like Vulkan and D3D12 will ignore this option + // and always capture all command lists since the API is heavily oriented + // around it and the overheads have been reduced by API design. + // + // 1 - All command lists are captured from the start of the application + // 0 - Command lists are only captured if their recording begins during + // the period when a frame capture is in progress. + eRENDERDOC_Option_CaptureAllCmdLists = 10, + + // Mute API debugging output when the debug device mode option is enabled + // + // Default - enabled + // + // 1 - Mute any API debug messages from being displayed or passed through + // 0 - API debugging is displayed as normal + eRENDERDOC_Option_DebugOutputMute = 11, + +} RENDERDOC_CaptureOption; + +// Sets an option that controls how RenderDoc behaves on capture. +// +// Returns 1 if the option and value are valid +// Returns 0 if either is invalid and the option is unchanged +typedef int (RENDERDOC_CC *pRENDERDOC_SetCaptureOptionU32)(RENDERDOC_CaptureOption opt, uint32_t val); +typedef int (RENDERDOC_CC *pRENDERDOC_SetCaptureOptionF32)(RENDERDOC_CaptureOption opt, float val); + +// Gets the current value of an option as a uint32_t +// +// If the option is invalid, 0xffffffff is returned +typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetCaptureOptionU32)(RENDERDOC_CaptureOption opt); + +// Gets the current value of an option as a float +// +// If the option is invalid, -FLT_MAX is returned +typedef float (RENDERDOC_CC *pRENDERDOC_GetCaptureOptionF32)(RENDERDOC_CaptureOption opt); + +typedef enum +{ + // '0' - '9' matches ASCII values + eRENDERDOC_Key_0 = 0x30, + eRENDERDOC_Key_1 = 0x31, + eRENDERDOC_Key_2 = 0x32, + eRENDERDOC_Key_3 = 0x33, + eRENDERDOC_Key_4 = 0x34, + eRENDERDOC_Key_5 = 0x35, + eRENDERDOC_Key_6 = 0x36, + eRENDERDOC_Key_7 = 0x37, + eRENDERDOC_Key_8 = 0x38, + eRENDERDOC_Key_9 = 0x39, + + // 'A' - 'Z' matches ASCII values + eRENDERDOC_Key_A = 0x41, + eRENDERDOC_Key_B = 0x42, + eRENDERDOC_Key_C = 0x43, + eRENDERDOC_Key_D = 0x44, + eRENDERDOC_Key_E = 0x45, + eRENDERDOC_Key_F = 0x46, + eRENDERDOC_Key_G = 0x47, + eRENDERDOC_Key_H = 0x48, + eRENDERDOC_Key_I = 0x49, + eRENDERDOC_Key_J = 0x4A, + eRENDERDOC_Key_K = 0x4B, + eRENDERDOC_Key_L = 0x4C, + eRENDERDOC_Key_M = 0x4D, + eRENDERDOC_Key_N = 0x4E, + eRENDERDOC_Key_O = 0x4F, + eRENDERDOC_Key_P = 0x50, + eRENDERDOC_Key_Q = 0x51, + eRENDERDOC_Key_R = 0x52, + eRENDERDOC_Key_S = 0x53, + eRENDERDOC_Key_T = 0x54, + eRENDERDOC_Key_U = 0x55, + eRENDERDOC_Key_V = 0x56, + eRENDERDOC_Key_W = 0x57, + eRENDERDOC_Key_X = 0x58, + eRENDERDOC_Key_Y = 0x59, + eRENDERDOC_Key_Z = 0x5A, + + // leave the rest of the ASCII range free + // in case we want to use it later + eRENDERDOC_Key_NonPrintable = 0x100, + + eRENDERDOC_Key_Divide, + eRENDERDOC_Key_Multiply, + eRENDERDOC_Key_Subtract, + eRENDERDOC_Key_Plus, + + eRENDERDOC_Key_F1, + eRENDERDOC_Key_F2, + eRENDERDOC_Key_F3, + eRENDERDOC_Key_F4, + eRENDERDOC_Key_F5, + eRENDERDOC_Key_F6, + eRENDERDOC_Key_F7, + eRENDERDOC_Key_F8, + eRENDERDOC_Key_F9, + eRENDERDOC_Key_F10, + eRENDERDOC_Key_F11, + eRENDERDOC_Key_F12, + + eRENDERDOC_Key_Home, + eRENDERDOC_Key_End, + eRENDERDOC_Key_Insert, + eRENDERDOC_Key_Delete, + eRENDERDOC_Key_PageUp, + eRENDERDOC_Key_PageDn, + + eRENDERDOC_Key_Backspace, + eRENDERDOC_Key_Tab, + eRENDERDOC_Key_PrtScrn, + eRENDERDOC_Key_Pause, + + eRENDERDOC_Key_Max, +} RENDERDOC_InputButton; + +// Sets which key or keys can be used to toggle focus between multiple windows +// +// If keys is NULL or num is 0, toggle keys will be disabled +typedef void (RENDERDOC_CC *pRENDERDOC_SetFocusToggleKeys)(RENDERDOC_InputButton *keys, int num); + +// Sets which key or keys can be used to capture the next frame +// +// If keys is NULL or num is 0, captures keys will be disabled +typedef void (RENDERDOC_CC *pRENDERDOC_SetCaptureKeys)(RENDERDOC_InputButton *keys, int num); + +typedef enum +{ + // This single bit controls whether the overlay is enabled or disabled globally + eRENDERDOC_Overlay_Enabled = 0x1, + + // Show the average framerate over several seconds as well as min/max + eRENDERDOC_Overlay_FrameRate = 0x2, + + // Show the current frame number + eRENDERDOC_Overlay_FrameNumber = 0x4, + + // Show a list of recent captures, and how many captures have been made + eRENDERDOC_Overlay_CaptureList = 0x8, + + // Default values for the overlay mask + eRENDERDOC_Overlay_Default = + (eRENDERDOC_Overlay_Enabled| + eRENDERDOC_Overlay_FrameRate| + eRENDERDOC_Overlay_FrameNumber| + eRENDERDOC_Overlay_CaptureList), + + // Enable all bits + eRENDERDOC_Overlay_All = ~0U, + + // Disable all bits + eRENDERDOC_Overlay_None = 0, +} RENDERDOC_OverlayBits; + +// returns the overlay bits that have been set +typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetOverlayBits)(); +// sets the overlay bits with an and & or mask +typedef void (RENDERDOC_CC *pRENDERDOC_MaskOverlayBits)(uint32_t And, uint32_t Or); + +// this function will attempt to shut down RenderDoc. +// +// Note: that this will only work correctly if done immediately after +// the dll is loaded, before any API work happens. RenderDoc will remove its +// injected hooks and shut down. Behaviour is undefined if this is called +// after any API functions have been called. +typedef void (RENDERDOC_CC *pRENDERDOC_Shutdown)(); + +// This function will unload RenderDoc's crash handler. +// +// If you use your own crash handler and don't want RenderDoc's handler to +// intercede, you can call this function to unload it and any unhandled +// exceptions will pass to the next handler. +typedef void (RENDERDOC_CC *pRENDERDOC_UnloadCrashHandler)(); + +// Sets the logfile path template +// +// logfile is a UTF-8 string that gives a template for how captures will be named +// and where they will be saved. +// +// Any extension is stripped off the path, and captures are saved in the directory +// specified, and named with the filename and the frame number appended. If the +// directory does not exist it will be created, including any parent directories. +// +// If pathtemplate is NULL, the template will remain unchanged +// +// Example: +// +// SetLogFilePathTemplate("my_captures/example"); +// +// Capture #1 -> my_captures/example_frame123.rdc +// Capture #2 -> my_captures/example_frame456.rdc +typedef void (RENDERDOC_CC *pRENDERDOC_SetLogFilePathTemplate)(const char *pathtemplate); + +// returns the current logfile template, see SetLogFileTemplate above, as a UTF-8 string +typedef const char* (RENDERDOC_CC *pRENDERDOC_GetLogFilePathTemplate)(); + +// returns the number of captures that have been made +typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetNumCaptures)(); + +// This function returns the details of a capture, by index. New captures are added +// to the end of the list. +// +// logfile will be filled with the absolute path to the capture file, as a UTF-8 string +// pathlength will be written with the length in bytes of the logfile string +// timestamp will be written with the time of the capture, in seconds since the Unix epoch +// +// Any of the parameters can be NULL and they'll be skipped. +// +// The function will return 1 if the capture index is valid, or 0 if the index is invalid +// If the index is invalid, the values will be unchanged +// +// Note: when captures are deleted in the UI they will remain in this list, so the +// logfile path may not exist anymore. +typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetCapture)(uint32_t idx, char *logfile, uint32_t *pathlength, uint64_t *timestamp); + +// capture the next frame on whichever window and API is currently considered active +typedef void (RENDERDOC_CC *pRENDERDOC_TriggerCapture)(); + +// returns 1 if the RenderDoc UI is connected to this application, 0 otherwise +typedef uint32_t (RENDERDOC_CC *pRENDERDOC_IsRemoteAccessConnected)(); + +// This function will launch the Replay UI associated with the RenderDoc library injected +// into the running application. +// +// if connectRemoteAccess is 1, the Replay UI will be launched with a command line parameter +// to connect to this application +// cmdline is the rest of the command line, as a UTF-8 string. E.g. a captures to open +// if cmdline is NULL, the command line will be empty. +// +// returns the PID of the replay UI if successful, 0 if not successful. +typedef uint32_t (RENDERDOC_CC *pRENDERDOC_LaunchReplayUI)(uint32_t connectRemoteAccess, const char *cmdline); + +// RenderDoc can return a higher version than requested if it's backwards compatible, +// this function returns the actual version returned. If a parameter is NULL, it will be +// ignored and the others will be filled out. +typedef void (RENDERDOC_CC *pRENDERDOC_GetAPIVersion)(int *major, int *minor, int *patch); + +////////////////////////////////////////////////////////////////////////// +// Capturing functions +// + +// A device pointer is a pointer to the API's root handle. +// +// This would be an ID3D11Device, HGLRC/GLXContext, ID3D12Device, etc +typedef void* RENDERDOC_DevicePointer; + +// A window handle is the OS's native window handle +// +// This would be an HWND, GLXDrawable, etc +typedef void* RENDERDOC_WindowHandle; + +// This sets the RenderDoc in-app overlay in the API/window pair as 'active' and it will +// respond to keypresses. Neither parameter can be NULL +typedef void (RENDERDOC_CC *pRENDERDOC_SetActiveWindow)(RENDERDOC_DevicePointer device, RENDERDOC_WindowHandle wndHandle); + +// When choosing either a device pointer or a window handle to capture, you can pass NULL. +// Passing NULL specifies a 'wildcard' match against anything. This allows you to specify +// any API rendering to a specific window, or a specific API instance rendering to any window, +// or in the simplest case of one window and one API, you can just pass NULL for both. +// +// In either case, if there are two or more possible matching (device,window) pairs it +// is undefined which one will be captured. +// +// Note: for headless rendering you can pass NULL for the window handle and either specify +// a device pointer or leave it NULL as above. + +// Immediately starts capturing API calls on the specified device pointer and window handle. +// +// If there is no matching thing to capture (e.g. no supported API has been initialised), +// this will do nothing. +// +// The results are undefined (including crashes) if two captures are started overlapping, +// even on separate devices and/oror windows. +typedef void (RENDERDOC_CC *pRENDERDOC_StartFrameCapture)(RENDERDOC_DevicePointer device, RENDERDOC_WindowHandle wndHandle); + +// Returns whether or not a frame capture is currently ongoing anywhere. +// +// This will return 1 if a capture is ongoing, and 0 if there is no capture running +typedef uint32_t (RENDERDOC_CC *pRENDERDOC_IsFrameCapturing)(); + +// Ends capturing immediately. +// +// This will return 1 if the capture succeeded, and 0 if there was an error capturing. +typedef uint32_t (RENDERDOC_CC *pRENDERDOC_EndFrameCapture)(RENDERDOC_DevicePointer device, RENDERDOC_WindowHandle wndHandle); + +////////////////////////////////////////////////////////////////////////////////////////////////// +// RenderDoc API versions +// + +// RenderDoc uses semantic versioning (http://semver.org/). +// +// MAJOR version is incremented when incompatible API changes happen. +// MINOR version is incremented when functionality is added in a backwards-compatible manner. +// PATCH version is incremented when backwards-compatible bug fixes happen. +// +// Note that this means the API returned can be higher than the one you might have requested. +// e.g. if you are running against a newer RenderDoc that supports 1.0.1, it will be returned +// instead of 1.0.0. You can check this with the GetAPIVersion entry point +typedef enum +{ + eRENDERDOC_API_Version_1_0_0 = 10000, // RENDERDOC_API_1_0_0 = 1 00 00 + eRENDERDOC_API_Version_1_0_1 = 10001, // RENDERDOC_API_1_0_1 = 1 00 01 +} RENDERDOC_Version; + +// API version changelog: +// +// 1.0.0 - initial release +// 1.0.1 - Bugfix: IsFrameCapturing() was returning false for captures that were triggered +// by keypress or TriggerCapture, instead of Start/EndFrameCapture. + +// eRENDERDOC_API_Version_1_0_1 +typedef struct +{ + pRENDERDOC_GetAPIVersion GetAPIVersion; + + pRENDERDOC_SetCaptureOptionU32 SetCaptureOptionU32; + pRENDERDOC_SetCaptureOptionF32 SetCaptureOptionF32; + + pRENDERDOC_GetCaptureOptionU32 GetCaptureOptionU32; + pRENDERDOC_GetCaptureOptionF32 GetCaptureOptionF32; + + pRENDERDOC_SetFocusToggleKeys SetFocusToggleKeys; + pRENDERDOC_SetCaptureKeys SetCaptureKeys; + + pRENDERDOC_GetOverlayBits GetOverlayBits; + pRENDERDOC_MaskOverlayBits MaskOverlayBits; + + pRENDERDOC_Shutdown Shutdown; + pRENDERDOC_UnloadCrashHandler UnloadCrashHandler; + + pRENDERDOC_SetLogFilePathTemplate SetLogFilePathTemplate; + pRENDERDOC_GetLogFilePathTemplate GetLogFilePathTemplate; + + pRENDERDOC_GetNumCaptures GetNumCaptures; + pRENDERDOC_GetCapture GetCapture; + + pRENDERDOC_TriggerCapture TriggerCapture; + + pRENDERDOC_IsRemoteAccessConnected IsRemoteAccessConnected; + pRENDERDOC_LaunchReplayUI LaunchReplayUI; + + pRENDERDOC_SetActiveWindow SetActiveWindow; + + pRENDERDOC_StartFrameCapture StartFrameCapture; + pRENDERDOC_IsFrameCapturing IsFrameCapturing; + pRENDERDOC_EndFrameCapture EndFrameCapture; +} RENDERDOC_API_1_0_1; + +typedef RENDERDOC_API_1_0_1 RENDERDOC_API_1_0_0; + +////////////////////////////////////////////////////////////////////////////////////////////////// +// RenderDoc API entry point +// +// This entry point can be obtained via GetProcAddress/dlsym if RenderDoc is available. +// +// The name is the same as the typedef - "RENDERDOC_GetAPI" +// +// This function is not thread safe, and should not be called on multiple threads at once. +// Ideally, call this once as early as possible in your application's startup, before doing +// any API work, since some configuration functionality etc has to be done also before +// initialising any APIs. +// +// Parameters: +// version is a single value from the RENDERDOC_Version above. +// +// outAPIPointers will be filled out with a pointer to the corresponding struct of function +// pointers. +// +// Returns: +// 1 - if the outAPIPointers has been filled with a pointer to the API struct requested +// 0 - if the requested version is not supported or the arguments are invalid. +// +typedef int (RENDERDOC_CC *pRENDERDOC_GetAPI)(RENDERDOC_Version version, void **outAPIPointers); + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/thirdparty/sdl3 b/thirdparty/sdl3 new file mode 160000 index 0000000..8bf3b72 --- /dev/null +++ b/thirdparty/sdl3 @@ -0,0 +1 @@ +Subproject commit 8bf3b7215ad9fc3deb583c6a3a37c6c67f2e24e4 diff --git a/thirdparty/simde b/thirdparty/simde new file mode 160000 index 0000000..71fd833 --- /dev/null +++ b/thirdparty/simde @@ -0,0 +1 @@ +Subproject commit 71fd833d9666141edcd1d3c109a80e228303d8d7 diff --git a/thirdparty/snappy b/thirdparty/snappy new file mode 160000 index 0000000..6af9287 --- /dev/null +++ b/thirdparty/snappy @@ -0,0 +1 @@ +Subproject commit 6af9287fbdb913f0794d0148c6aa43b58e63c8e3 diff --git a/thirdparty/spdlog b/thirdparty/spdlog new file mode 160000 index 0000000..79524dd --- /dev/null +++ b/thirdparty/spdlog @@ -0,0 +1 @@ +Subproject commit 79524ddd08a4ec981b7fea76afd08ee05f83755d diff --git a/thirdparty/spirv-headers b/thirdparty/spirv-headers new file mode 160000 index 0000000..04f10f6 --- /dev/null +++ b/thirdparty/spirv-headers @@ -0,0 +1 @@ +Subproject commit 04f10f650d514df88b76d25e83db360142c7b174 diff --git a/thirdparty/spirv-tools b/thirdparty/spirv-tools new file mode 160000 index 0000000..04d0b16 --- /dev/null +++ b/thirdparty/spirv-tools @@ -0,0 +1 @@ +Subproject commit 04d0b166dcd62e29509bf2aac3ca0c5ccdcb6929 diff --git a/thirdparty/tiny-aes-c/aes.c b/thirdparty/tiny-aes-c/aes.c new file mode 100644 index 0000000..4481f7b --- /dev/null +++ b/thirdparty/tiny-aes-c/aes.c @@ -0,0 +1,572 @@ +/* + +This is an implementation of the AES algorithm, specifically ECB, CTR and CBC mode. +Block size can be chosen in aes.h - available choices are AES128, AES192, AES256. + +The implementation is verified against the test vectors in: + National Institute of Standards and Technology Special Publication 800-38A 2001 ED + +ECB-AES128 +---------- + + plain-text: + 6bc1bee22e409f96e93d7e117393172a + ae2d8a571e03ac9c9eb76fac45af8e51 + 30c81c46a35ce411e5fbc1191a0a52ef + f69f2445df4f9b17ad2b417be66c3710 + + key: + 2b7e151628aed2a6abf7158809cf4f3c + + resulting cipher + 3ad77bb40d7a3660a89ecaf32466ef97 + f5d3d58503b9699de785895a96fdbaaf + 43b1cd7f598ece23881b00e3ed030688 + 7b0c785e27e8ad3f8223207104725dd4 + + +NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0) + You should pad the end of the string with zeros if this is not the case. + For AES192/256 the key size is proportionally larger. + +*/ + + +/*****************************************************************************/ +/* Includes: */ +/*****************************************************************************/ +#include // CBC mode, for memset +#include "aes.h" + +/*****************************************************************************/ +/* Defines: */ +/*****************************************************************************/ +// The number of columns comprising a state in AES. This is a constant in AES. Value=4 +#define Nb 4 + +#if defined(AES256) && (AES256 == 1) + #define Nk 8 + #define Nr 14 +#elif defined(AES192) && (AES192 == 1) + #define Nk 6 + #define Nr 12 +#else + #define Nk 4 // The number of 32 bit words in a key. + #define Nr 10 // The number of rounds in AES Cipher. +#endif + +// jcallan@github points out that declaring Multiply as a function +// reduces code size considerably with the Keil ARM compiler. +// See this link for more information: https://github.com/kokke/tiny-AES-C/pull/3 +#ifndef MULTIPLY_AS_A_FUNCTION + #define MULTIPLY_AS_A_FUNCTION 0 +#endif + + + + +/*****************************************************************************/ +/* Private variables: */ +/*****************************************************************************/ +// state - array holding the intermediate results during decryption. +typedef uint8_t state_t[4][4]; + + + +// The lookup-tables are marked const so they can be placed in read-only storage instead of RAM +// The numbers below can be computed dynamically trading ROM for RAM - +// This can be useful in (embedded) bootloader applications, where ROM is often limited. +static const uint8_t sbox[256] = { + //0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; + +#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1) +static const uint8_t rsbox[256] = { + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }; +#endif + +// The round constant word array, Rcon[i], contains the values given by +// x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8) +static const uint8_t Rcon[11] = { + 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; + +/* + * Jordan Goulder points out in PR #12 (https://github.com/kokke/tiny-AES-C/pull/12), + * that you can remove most of the elements in the Rcon array, because they are unused. + * + * From Wikipedia's article on the Rijndael key schedule @ https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon + * + * "Only the first some of these constants are actually used – up to rcon[10] for AES-128 (as 11 round keys are needed), + * up to rcon[8] for AES-192, up to rcon[7] for AES-256. rcon[0] is not used in AES algorithm." + */ + + +/*****************************************************************************/ +/* Private functions: */ +/*****************************************************************************/ +/* +static uint8_t getSBoxValue(uint8_t num) +{ + return sbox[num]; +} +*/ +#define getSBoxValue(num) (sbox[(num)]) + +// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states. +static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key) +{ + unsigned i, j, k; + uint8_t tempa[4]; // Used for the column/row operations + + // The first round key is the key itself. + for (i = 0; i < Nk; ++i) + { + RoundKey[(i * 4) + 0] = Key[(i * 4) + 0]; + RoundKey[(i * 4) + 1] = Key[(i * 4) + 1]; + RoundKey[(i * 4) + 2] = Key[(i * 4) + 2]; + RoundKey[(i * 4) + 3] = Key[(i * 4) + 3]; + } + + // All other round keys are found from the previous round keys. + for (i = Nk; i < Nb * (Nr + 1); ++i) + { + { + k = (i - 1) * 4; + tempa[0]=RoundKey[k + 0]; + tempa[1]=RoundKey[k + 1]; + tempa[2]=RoundKey[k + 2]; + tempa[3]=RoundKey[k + 3]; + + } + + if (i % Nk == 0) + { + // This function shifts the 4 bytes in a word to the left once. + // [a0,a1,a2,a3] becomes [a1,a2,a3,a0] + + // Function RotWord() + { + const uint8_t u8tmp = tempa[0]; + tempa[0] = tempa[1]; + tempa[1] = tempa[2]; + tempa[2] = tempa[3]; + tempa[3] = u8tmp; + } + + // SubWord() is a function that takes a four-byte input word and + // applies the S-box to each of the four bytes to produce an output word. + + // Function Subword() + { + tempa[0] = getSBoxValue(tempa[0]); + tempa[1] = getSBoxValue(tempa[1]); + tempa[2] = getSBoxValue(tempa[2]); + tempa[3] = getSBoxValue(tempa[3]); + } + + tempa[0] = tempa[0] ^ Rcon[i/Nk]; + } +#if defined(AES256) && (AES256 == 1) + if (i % Nk == 4) + { + // Function Subword() + { + tempa[0] = getSBoxValue(tempa[0]); + tempa[1] = getSBoxValue(tempa[1]); + tempa[2] = getSBoxValue(tempa[2]); + tempa[3] = getSBoxValue(tempa[3]); + } + } +#endif + j = i * 4; k=(i - Nk) * 4; + RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0]; + RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1]; + RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2]; + RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3]; + } +} + +void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key) +{ + KeyExpansion(ctx->RoundKey, key); +} +#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1)) +void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv) +{ + KeyExpansion(ctx->RoundKey, key); + memcpy (ctx->Iv, iv, AES_BLOCKLEN); +} +void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv) +{ + memcpy (ctx->Iv, iv, AES_BLOCKLEN); +} +#endif + +// This function adds the round key to state. +// The round key is added to the state by an XOR function. +static void AddRoundKey(uint8_t round, state_t* state, const uint8_t* RoundKey) +{ + uint8_t i,j; + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 4; ++j) + { + (*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j]; + } + } +} + +// The SubBytes Function Substitutes the values in the +// state matrix with values in an S-box. +static void SubBytes(state_t* state) +{ + uint8_t i, j; + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 4; ++j) + { + (*state)[j][i] = getSBoxValue((*state)[j][i]); + } + } +} + +// The ShiftRows() function shifts the rows in the state to the left. +// Each row is shifted with different offset. +// Offset = Row number. So the first row is not shifted. +static void ShiftRows(state_t* state) +{ + uint8_t temp; + + // Rotate first row 1 columns to left + temp = (*state)[0][1]; + (*state)[0][1] = (*state)[1][1]; + (*state)[1][1] = (*state)[2][1]; + (*state)[2][1] = (*state)[3][1]; + (*state)[3][1] = temp; + + // Rotate second row 2 columns to left + temp = (*state)[0][2]; + (*state)[0][2] = (*state)[2][2]; + (*state)[2][2] = temp; + + temp = (*state)[1][2]; + (*state)[1][2] = (*state)[3][2]; + (*state)[3][2] = temp; + + // Rotate third row 3 columns to left + temp = (*state)[0][3]; + (*state)[0][3] = (*state)[3][3]; + (*state)[3][3] = (*state)[2][3]; + (*state)[2][3] = (*state)[1][3]; + (*state)[1][3] = temp; +} + +static uint8_t xtime(uint8_t x) +{ + return ((x<<1) ^ (((x>>7) & 1) * 0x1b)); +} + +// MixColumns function mixes the columns of the state matrix +static void MixColumns(state_t* state) +{ + uint8_t i; + uint8_t Tmp, Tm, t; + for (i = 0; i < 4; ++i) + { + t = (*state)[i][0]; + Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ; + Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ; + Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ; + Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ; + Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ; + } +} + +// Multiply is used to multiply numbers in the field GF(2^8) +// Note: The last call to xtime() is unneeded, but often ends up generating a smaller binary +// The compiler seems to be able to vectorize the operation better this way. +// See https://github.com/kokke/tiny-AES-c/pull/34 +#if MULTIPLY_AS_A_FUNCTION +static uint8_t Multiply(uint8_t x, uint8_t y) +{ + return (((y & 1) * x) ^ + ((y>>1 & 1) * xtime(x)) ^ + ((y>>2 & 1) * xtime(xtime(x))) ^ + ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ + ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))); /* this last call to xtime() can be omitted */ + } +#else +#define Multiply(x, y) \ + ( ((y & 1) * x) ^ \ + ((y>>1 & 1) * xtime(x)) ^ \ + ((y>>2 & 1) * xtime(xtime(x))) ^ \ + ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \ + ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \ + +#endif + +#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1) +/* +static uint8_t getSBoxInvert(uint8_t num) +{ + return rsbox[num]; +} +*/ +#define getSBoxInvert(num) (rsbox[(num)]) + +// MixColumns function mixes the columns of the state matrix. +// The method used to multiply may be difficult to understand for the inexperienced. +// Please use the references to gain more information. +static void InvMixColumns(state_t* state) +{ + int i; + uint8_t a, b, c, d; + for (i = 0; i < 4; ++i) + { + a = (*state)[i][0]; + b = (*state)[i][1]; + c = (*state)[i][2]; + d = (*state)[i][3]; + + (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09); + (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d); + (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b); + (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e); + } +} + + +// The SubBytes Function Substitutes the values in the +// state matrix with values in an S-box. +static void InvSubBytes(state_t* state) +{ + uint8_t i, j; + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 4; ++j) + { + (*state)[j][i] = getSBoxInvert((*state)[j][i]); + } + } +} + +static void InvShiftRows(state_t* state) +{ + uint8_t temp; + + // Rotate first row 1 columns to right + temp = (*state)[3][1]; + (*state)[3][1] = (*state)[2][1]; + (*state)[2][1] = (*state)[1][1]; + (*state)[1][1] = (*state)[0][1]; + (*state)[0][1] = temp; + + // Rotate second row 2 columns to right + temp = (*state)[0][2]; + (*state)[0][2] = (*state)[2][2]; + (*state)[2][2] = temp; + + temp = (*state)[1][2]; + (*state)[1][2] = (*state)[3][2]; + (*state)[3][2] = temp; + + // Rotate third row 3 columns to right + temp = (*state)[0][3]; + (*state)[0][3] = (*state)[1][3]; + (*state)[1][3] = (*state)[2][3]; + (*state)[2][3] = (*state)[3][3]; + (*state)[3][3] = temp; +} +#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1) + +// Cipher is the main function that encrypts the PlainText. +static void Cipher(state_t* state, const uint8_t* RoundKey) +{ + uint8_t round = 0; + + // Add the First round key to the state before starting the rounds. + AddRoundKey(0, state, RoundKey); + + // There will be Nr rounds. + // The first Nr-1 rounds are identical. + // These Nr rounds are executed in the loop below. + // Last one without MixColumns() + for (round = 1; ; ++round) + { + SubBytes(state); + ShiftRows(state); + if (round == Nr) { + break; + } + MixColumns(state); + AddRoundKey(round, state, RoundKey); + } + // Add round key to last round + AddRoundKey(Nr, state, RoundKey); +} + +#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1) +static void InvCipher(state_t* state, const uint8_t* RoundKey) +{ + uint8_t round = 0; + + // Add the First round key to the state before starting the rounds. + AddRoundKey(Nr, state, RoundKey); + + // There will be Nr rounds. + // The first Nr-1 rounds are identical. + // These Nr rounds are executed in the loop below. + // Last one without InvMixColumn() + for (round = (Nr - 1); ; --round) + { + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(round, state, RoundKey); + if (round == 0) { + break; + } + InvMixColumns(state); + } + +} +#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1) + +/*****************************************************************************/ +/* Public functions: */ +/*****************************************************************************/ +#if defined(ECB) && (ECB == 1) + + +void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf) +{ + // The next function call encrypts the PlainText with the Key using AES algorithm. + Cipher((state_t*)buf, ctx->RoundKey); +} + +void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf) +{ + // The next function call decrypts the PlainText with the Key using AES algorithm. + InvCipher((state_t*)buf, ctx->RoundKey); +} + + +#endif // #if defined(ECB) && (ECB == 1) + + + + + +#if defined(CBC) && (CBC == 1) + + +static void XorWithIv(uint8_t* buf, const uint8_t* Iv) +{ + uint8_t i; + for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size + { + buf[i] ^= Iv[i]; + } +} + +void AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t* buf, size_t length) +{ + size_t i; + uint8_t *Iv = ctx->Iv; + for (i = 0; i < length; i += AES_BLOCKLEN) + { + XorWithIv(buf, Iv); + Cipher((state_t*)buf, ctx->RoundKey); + Iv = buf; + buf += AES_BLOCKLEN; + } + /* store Iv in ctx for next call */ + memcpy(ctx->Iv, Iv, AES_BLOCKLEN); +} + +void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length) +{ + size_t i; + uint8_t storeNextIv[AES_BLOCKLEN]; + for (i = 0; i < length; i += AES_BLOCKLEN) + { + memcpy(storeNextIv, buf, AES_BLOCKLEN); + InvCipher((state_t*)buf, ctx->RoundKey); + XorWithIv(buf, ctx->Iv); + memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN); + buf += AES_BLOCKLEN; + } + +} + +#endif // #if defined(CBC) && (CBC == 1) + + + +#if defined(CTR) && (CTR == 1) + +/* Symmetrical operation: same function for encrypting as for decrypting. Note any IV/nonce should never be reused with the same key */ +void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length) +{ + uint8_t buffer[AES_BLOCKLEN]; + + size_t i; + int bi; + for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi) + { + if (bi == AES_BLOCKLEN) /* we need to regen xor compliment in buffer */ + { + + memcpy(buffer, ctx->Iv, AES_BLOCKLEN); + Cipher((state_t*)buffer,ctx->RoundKey); + + /* Increment Iv and handle overflow */ + for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi) + { + /* inc will overflow */ + if (ctx->Iv[bi] == 255) + { + ctx->Iv[bi] = 0; + continue; + } + ctx->Iv[bi] += 1; + break; + } + bi = 0; + } + + buf[i] = (buf[i] ^ buffer[bi]); + } +} + +#endif // #if defined(CTR) && (CTR == 1) + diff --git a/thirdparty/tiny-aes-c/aes.h b/thirdparty/tiny-aes-c/aes.h new file mode 100644 index 0000000..b29b668 --- /dev/null +++ b/thirdparty/tiny-aes-c/aes.h @@ -0,0 +1,91 @@ +#ifndef _AES_H_ +#define _AES_H_ + +#include +#include + +// #define the macros below to 1/0 to enable/disable the mode of operation. +// +// CBC enables AES encryption in CBC-mode of operation. +// CTR enables encryption in counter-mode. +// ECB enables the basic ECB 16-byte block algorithm. All can be enabled simultaneously. + +// The #ifndef-guard allows it to be configured before #include'ing or at compile time. +#ifndef CBC + #define CBC 1 +#endif + +#ifndef ECB + #define ECB 1 +#endif + +#ifndef CTR + #define CTR 1 +#endif + + +#define AES128 1 +//#define AES192 1 +//#define AES256 1 + +#define AES_BLOCKLEN 16 // Block length in bytes - AES is 128b block only + +#if defined(AES256) && (AES256 == 1) + #define AES_KEYLEN 32 + #define AES_keyExpSize 240 +#elif defined(AES192) && (AES192 == 1) + #define AES_KEYLEN 24 + #define AES_keyExpSize 208 +#else + #define AES_KEYLEN 16 // Key length in bytes + #define AES_keyExpSize 176 +#endif + +struct AES_ctx +{ + uint8_t RoundKey[AES_keyExpSize]; +#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1)) + uint8_t Iv[AES_BLOCKLEN]; +#endif +}; + +void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key); +#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1)) +void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv); +void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv); +#endif + +#if defined(ECB) && (ECB == 1) +// buffer size is exactly AES_BLOCKLEN bytes; +// you need only AES_init_ctx as IV is not used in ECB +// NB: ECB is considered insecure for most uses +void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf); +void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf); + +#endif // #if defined(ECB) && (ECB == !) + + +#if defined(CBC) && (CBC == 1) +// buffer size MUST be mutile of AES_BLOCKLEN; +// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme +// NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv() +// no IV should ever be reused with the same key +void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length); +void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length); + +#endif // #if defined(CBC) && (CBC == 1) + + +#if defined(CTR) && (CTR == 1) + +// Same function for encrypting as for decrypting. +// IV is incremented for every block, and used after encryption as XOR-compliment for output +// Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme +// NOTES: you need to set IV in ctx with AES_init_ctx_iv() or AES_ctx_set_iv() +// no IV should ever be reused with the same key +void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length); + +#endif // #if defined(CTR) && (CTR == 1) + + +#endif // _AES_H_ diff --git a/thirdparty/tiny-aes-c/aes.hpp b/thirdparty/tiny-aes-c/aes.hpp new file mode 100644 index 0000000..ade1642 --- /dev/null +++ b/thirdparty/tiny-aes-c/aes.hpp @@ -0,0 +1,12 @@ +#ifndef _AES_HPP_ +#define _AES_HPP_ + +#ifndef __cplusplus +#error Do not include the hpp header in a c project! +#endif //__cplusplus + +extern "C" { +#include "aes.h" +} + +#endif //_AES_HPP_ diff --git a/thirdparty/tomlplusplus b/thirdparty/tomlplusplus new file mode 160000 index 0000000..3017243 --- /dev/null +++ b/thirdparty/tomlplusplus @@ -0,0 +1 @@ +Subproject commit 30172438cee64926dc41fdd9c11fb3ba5b2ba9de diff --git a/thirdparty/tracy b/thirdparty/tracy new file mode 160000 index 0000000..05cceee --- /dev/null +++ b/thirdparty/tracy @@ -0,0 +1 @@ +Subproject commit 05cceee0df3b8d7c6fa87e9638af311dbabc63cb diff --git a/thirdparty/utfcpp b/thirdparty/utfcpp new file mode 160000 index 0000000..63d64de --- /dev/null +++ b/thirdparty/utfcpp @@ -0,0 +1 @@ +Subproject commit 63d64de49fd6b829f7c8694df5ab2ee625cb7134 diff --git a/thirdparty/volk b/thirdparty/volk new file mode 160000 index 0000000..0b17a76 --- /dev/null +++ b/thirdparty/volk @@ -0,0 +1 @@ +Subproject commit 0b17a763ba5643e32da1b2152f8140461b3b7345 diff --git a/thirdparty/vulkan-headers b/thirdparty/vulkan-headers new file mode 160000 index 0000000..49f1a38 --- /dev/null +++ b/thirdparty/vulkan-headers @@ -0,0 +1 @@ +Subproject commit 49f1a381e2aec33ef32adf4a377b5a39ec016ec4 diff --git a/thirdparty/vulkan-memory-allocator b/thirdparty/vulkan-memory-allocator new file mode 160000 index 0000000..1d8f600 --- /dev/null +++ b/thirdparty/vulkan-memory-allocator @@ -0,0 +1 @@ +Subproject commit 1d8f600fd424278486eade7ed3e877c99f0846b1 diff --git a/thirdparty/xxHash b/thirdparty/xxHash new file mode 160000 index 0000000..e626a72 --- /dev/null +++ b/thirdparty/xxHash @@ -0,0 +1 @@ +Subproject commit e626a72bc2321cd320e953a0ccf1584cad60f363 diff --git a/tools/binutils/LICENSE b/tools/binutils/LICENSE new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/tools/binutils/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/tools/binutils/cygiconv-2.dll b/tools/binutils/cygiconv-2.dll new file mode 100644 index 0000000..b7f49ea Binary files /dev/null and b/tools/binutils/cygiconv-2.dll differ diff --git a/tools/binutils/cygintl-8.dll b/tools/binutils/cygintl-8.dll new file mode 100644 index 0000000..f8e5745 Binary files /dev/null and b/tools/binutils/cygintl-8.dll differ diff --git a/tools/binutils/cygwin1.dll b/tools/binutils/cygwin1.dll new file mode 100644 index 0000000..7831069 Binary files /dev/null and b/tools/binutils/cygwin1.dll differ diff --git a/tools/binutils/powerpc-none-elf-addr2line b/tools/binutils/powerpc-none-elf-addr2line new file mode 100755 index 0000000..d6afa5e Binary files /dev/null and b/tools/binutils/powerpc-none-elf-addr2line differ diff --git a/tools/binutils/powerpc-none-elf-addr2line.exe b/tools/binutils/powerpc-none-elf-addr2line.exe new file mode 100644 index 0000000..944382c Binary files /dev/null and b/tools/binutils/powerpc-none-elf-addr2line.exe differ diff --git a/tools/binutils/powerpc-none-elf-ar b/tools/binutils/powerpc-none-elf-ar new file mode 100755 index 0000000..34b4881 Binary files /dev/null and b/tools/binutils/powerpc-none-elf-ar differ diff --git a/tools/binutils/powerpc-none-elf-ar.exe b/tools/binutils/powerpc-none-elf-ar.exe new file mode 100644 index 0000000..96fbb64 Binary files /dev/null and b/tools/binutils/powerpc-none-elf-ar.exe differ diff --git a/tools/binutils/powerpc-none-elf-as b/tools/binutils/powerpc-none-elf-as new file mode 100755 index 0000000..f7a55af Binary files /dev/null and b/tools/binutils/powerpc-none-elf-as differ diff --git a/tools/binutils/powerpc-none-elf-as.exe b/tools/binutils/powerpc-none-elf-as.exe new file mode 100644 index 0000000..4ee4c6d Binary files /dev/null and b/tools/binutils/powerpc-none-elf-as.exe differ diff --git a/tools/binutils/powerpc-none-elf-c++filt b/tools/binutils/powerpc-none-elf-c++filt new file mode 100755 index 0000000..d295a68 Binary files /dev/null and b/tools/binutils/powerpc-none-elf-c++filt differ diff --git a/tools/binutils/powerpc-none-elf-c++filt.exe b/tools/binutils/powerpc-none-elf-c++filt.exe new file mode 100644 index 0000000..1706b34 Binary files /dev/null and b/tools/binutils/powerpc-none-elf-c++filt.exe differ diff --git a/tools/binutils/powerpc-none-elf-elfedit b/tools/binutils/powerpc-none-elf-elfedit new file mode 100755 index 0000000..2b20c9f Binary files /dev/null and b/tools/binutils/powerpc-none-elf-elfedit differ diff --git a/tools/binutils/powerpc-none-elf-elfedit.exe b/tools/binutils/powerpc-none-elf-elfedit.exe new file mode 100644 index 0000000..d781cbe Binary files /dev/null and b/tools/binutils/powerpc-none-elf-elfedit.exe differ diff --git a/tools/binutils/powerpc-none-elf-embedspu b/tools/binutils/powerpc-none-elf-embedspu new file mode 100755 index 0000000..9e2261b --- /dev/null +++ b/tools/binutils/powerpc-none-elf-embedspu @@ -0,0 +1,260 @@ +#! /bin/sh +# Embed an SPU ELF executable into a PowerPC object file. +# +# Copyright 2006, 2007, 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Binutils. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. + +usage () +{ + echo "Usage: embedspu [flags] symbol_name input_filename output_filename" + echo + echo " input_filename: SPU ELF executable to be embedded" + echo " output_filename: Resulting PowerPC object file" + echo " symbol_name: Name of program handle struct to be defined" + echo " flags: GCC flags defining PowerPC object file format" + echo " (e.g. -m32 or -m64)" + exit 1 +} + +program_transform_name="s&^&powerpc-none-elf-&" +mydir=`dirname "$0"` + +find_prog () +{ + prog=`echo $1 | sed "$program_transform_name"` + prog="$mydir/$prog" + test -x "$prog" && return 0 + prog="$mydir/$1" + test -x "$prog" && return 0 + prog=`echo $1 | sed "$program_transform_name"` + which $prog > /dev/null 2> /dev/null && return 0 + return 1 +} + +SYMBOL= +INFILE= +OUTFILE= +FLAGS= + +parse_args () +{ + while test -n "$1"; do + case "$1" in + -*) FLAGS="${FLAGS} $1" ;; + *) if test -z "$SYMBOL"; then + SYMBOL="$1" + elif test -z "$INFILE"; then + INFILE="$1" + elif test -z "$OUTFILE"; then + OUTFILE="$1" + else + echo "Too many arguments!" + usage + fi ;; + esac + shift + done + if test -z "$OUTFILE"; then + usage + fi + if test ! -r "$INFILE"; then + echo "${INFILE}: File not found" + usage + fi +} + +main () +{ + parse_args "$@" + + # Find a powerpc gcc. Support running from a combined tree build. + if test -x "$mydir/../gcc/xgcc"; then + CC="$mydir/../gcc/xgcc -B$mydir/../gcc/" + else + find_prog gcc + if test $? -ne 0; then + echo "Cannot find $prog" + exit 1 + fi + CC="$prog" + fi + + # Find readelf. Any old readelf should do. + find_prog readelf + if test $? -ne 0; then + if which readelf > /dev/null 2> /dev/null; then + prog=readelf + else + echo "Cannot find $prog" + exit 1 + fi + fi + READELF="$prog" + + # Sanity check the input file + if ! ${READELF} -h ${INFILE} | grep 'Class:.*ELF32' >/dev/null 2>/dev/null \ + || ! ${READELF} -h ${INFILE} | grep 'Type:.*EXEC' >/dev/null 2>/dev/null \ + || ! ${READELF} -h ${INFILE} | egrep 'Machine:.*(SPU|17)' >/dev/null 2>/dev/null + then + echo "${INFILE}: Does not appear to be an SPU executable" + exit 1 + fi + + toe=`${READELF} -S ${INFILE} | sed -n -e 's, *\[ *\([0-9]*\)\] *\.toe *[PROGN]*BITS *\([0-9a-f]*\).*,\1 \2,p'` + toe_addr=`echo $toe | sed -n -e 's,.* ,,p'` + toe=`echo $toe | sed -n -e 's, .*,,p'` + has_ea=`${READELF} -S ${INFILE} | sed -n -e 's, *\[ *\([0-9]*\)\] *\._ea *PROGBITS.*,\1,p'` + # For loaded sections, pick off section number, address, and file offset + sections=`${READELF} -S ${INFILE} | sed -n -e 's, *\[ *\([0-9]*\)\] *[^ ]* *PROGBITS *\([0-9a-f]*\) *\([0-9a-f]*\).*,\1 \2 \3,p'` + sections=`echo ${sections}` + # For relocation sections, pick off file offset and info (points to + # section where relocs apply) + relas=`${READELF} -S ${INFILE} | sed -n -e 's, *\[ *[0-9]*\] *[^ ]* *RELA *[0-9a-f]* *0*\([0-9a-f][0-9a-f]*\).* \([0-9a-f][0-9a-f]*\) *[0-9a-f][0-9a-f]*$,\1 \2,p'` + relas=`echo ${relas}` + + # Build embedded SPU image. + # 1. The whole SPU ELF file is written to .rodata.speelf + # 2. Symbols starting with the string "_EAR_" in the SPU ELF image are + # special. They allow an SPU program to access corresponding symbols + # (ie. minus the _EAR_ prefix), in the PowerPC program. _EAR_ without + # a suffix is used to refer to the addrress of the SPU image in + # PowerPC address space. _EAR_* symbols must all be defined in .toe + # at 16 byte intervals, or they must be defined in other non-bss + # sections. + # Find all _EAR_ symbols in .toe using readelf, sort by address, and + # write the address of the corresponding PowerPC symbol in a table + # built in .data.spetoe. For _EAR_ symbols not in .toe, create + # .reloc commands to relocate their location directly. + # 3. Look for R_SPU_PPU32 and R_SPU_PPU64 relocations in the SPU ELF image + # and create .reloc commands for them. + # 4. Write a struct spe_program_handle to .data. + # 5. Write a table of _SPUEAR_ symbols. + ${CC} ${FLAGS} -x assembler-with-cpp -nostartfiles -nostdlib \ + -Wa,-mbig -Wa,-noexecstack -Wl,-r -Wl,-x -o ${OUTFILE} - <